[
  {
    "path": ".cvsignore",
    "content": "*.bak\n*.orig\n*.rej\n*.sav\n*~\n.*.list\n.*.time\n.ccmalloc\n.ppack\n.ext\n.git\n.svn\n.pc\nCOPYING.LIB\nChangeLog.pre-alpha\nChangeLog.pre1_1\nMakefile\nREADME.fat-patch\nREADME.v6\nREADME.atheos\narchive\nautom4te*.cache\nautomake\nbeos\nconfig.cache\nconfig.h\nconfig.h.in\nconfig.log\nconfig.status\nconfigure\nlibruby.so.*\nminiruby\nnewdate.rb\nnewver.rb\nparse.c\npatches\nppack\npreview\nrbconfig.rb\nrepack\nriscos\nrubicon\nruby\nruby-man.rd.gz\ntmp\nweb\ny.output\ny.tab.c\n"
  },
  {
    "path": ".document",
    "content": "# This file determines which files in the\n# Ruby hierarchy will be processed by the RDoc\n# tool when it is given the top-level directory\n# as an argument\n\n# Process all the C source files\n*.c\n\n# the lib/ directory (which has its own .document file)\n\nlib\n\n\n# and some of the ext/ directory (which has its own .document file)\n\next\n"
  },
  {
    "path": ".gitignore",
    "content": ".ext\n.installed.list\n*.o\n*.so\n*.bundle\n*.dSYM\nautom4te.cache\nconfdefs.h\nconfig.h\nconfig.log\nconfig.status\nconfig.status.lineno\n/configure\nconftest.c\nconftest.er1\nmkmf.log\nMakefile\nlargefile.h\n.rbconfig.time\nenc.mk\nencdb.h\ninsns.inc\ninsns_info.inc\nlex.c\nlib/doc\nlibruby-static.a\nminiprelude.c\nminiruby\nnode_name.inc\nopt_sc.inc\noptinsn.inc\noptunifs.inc\nparse.c\nprelude.c\nrbconfig.rb\nrevision.h\n/ruby\ntransdb.h\nvm.inc\nvmtc.inc\nyasmdata.rb\next/dl/call.func\next/dl/callback.func\next/dl/cbtable.func\next/dl/dlconfig.h\next/dl/dlconfig.rb\next/openssl/extconf.h\next/win32ole/.document\ndistro/version.txt\ndistro/documentation.html\n/ruby-enterprise-*\ndistro/rubygems*.tgz\nruby-enterprise-*.tar.gz\nfakeroot\n!distro/runtime/*/ruby\n"
  },
  {
    "path": "COPYING",
    "content": "Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.\nYou can redistribute it and/or modify it under either the terms of the GPL\nversion 2 (see the file GPL), or the conditions below:\n\n  1. You may make and give away verbatim copies of the source form of the\n     software without restriction, provided that you duplicate all of the\n     original copyright notices and associated disclaimers.\n\n  2. You may modify your copy of the software in any way, provided that\n     you do at least ONE of the following:\n\n       a) place your modifications in the Public Domain or otherwise\n          make them Freely Available, such as by posting said\n\t  modifications to Usenet or an equivalent medium, or by allowing\n\t  the author to include your modifications in the software.\n\n       b) use the modified software only within your corporation or\n          organization.\n\n       c) give non-standard binaries non-standard names, with\n          instructions on where to get the original software distribution.\n\n       d) make other distribution arrangements with the author.\n\n  3. You may distribute the software in object code or binary form,\n     provided that you do at least ONE of the following:\n\n       a) distribute the binaries and library files of the software,\n\t  together with instructions (in the manual page or equivalent)\n\t  on where to get the original distribution.\n\n       b) accompany the distribution with the machine-readable source of\n\t  the software.\n\n       c) give non-standard binaries non-standard names, with\n          instructions on where to get the original software distribution.\n\n       d) make other distribution arrangements with the author.\n\n  4. You may modify and include the part of the software into any other\n     software (possibly commercial).  But some files in the distribution\n     are not written by the author, so that they are not under these terms.\n\n     For the list of those files and their copying conditions, see the\n     file LEGAL.\n\n  5. The scripts and library files supplied as input to or produced as \n     output from the software do not automatically fall under the\n     copyright of the software, but belong to whomever generated them, \n     and may be sold commercially, and may be aggregated with this\n     software.\n\n  6. THIS SOFTWARE IS PROVIDED \"AS IS\" AND WITHOUT ANY EXPRESS OR\n     IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\n     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n     PURPOSE.\n"
  },
  {
    "path": "COPYING.ja",
    "content": "\u001b$BK\\%W%m%0%i%`$O%U%j!<%=%U%H%&%'%\"$G$9!%\u001b(BGPL(the GNU General\nPublic License)\u001b$B$^$?$O0J2<$K<($9>r7o$GK\\%W%m%0%i%`$r:FG[I[$G\u001b(B\n\u001b$B$-$^$9!%\u001b(BGPL\u001b$B$K$D$$$F$O\u001b(BGPL\u001b$B%U%!%$%k$r;2>H$7$F2<$5$$!%\u001b(B\n\n  1. \u001b$BJ#@=$O@)8B$J$/<+M3$G$9!%\u001b(B\n\n  2. \u001b$B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\\%W%m%0%i%`$N%=!<%9$r\u001b(B\n     \u001b$B<+M3$KJQ99$G$-$^$9!%\u001b(B\n\n     (a) \u001b$B%M%C%H%K%e!<%:$K%]%9%H$7$?$j!$:n<T$KJQ99$rAwIU$9$k\u001b(B\n         \u001b$B$J$I$NJ}K!$G!$JQ99$r8x3+$9$k!%\u001b(B\n\n     (b) \u001b$BJQ99$7$?K\\%W%m%0%i%`$r<+J,$N=jB0$9$kAH?%FbIt$@$1$G\u001b(B\n         \u001b$B;H$&!%\u001b(B\n\n     (c) \u001b$BJQ99E@$rL@<($7$?$&$(!$%=%U%H%&%'%\"$NL>A0$rJQ99$9$k!%\u001b(B\n         \u001b$B$=$N%=%U%H%&%'%\"$rG[I[$9$k;~$K$OJQ99A0$NK\\%W%m%0%i\u001b(B\n         \u001b$B%`$bF1;~$KG[I[$9$k!%$^$?$OJQ99A0$NK\\%W%m%0%i%`$N%=!<\u001b(B\n         \u001b$B%9$NF~<jK!$rL@<($9$k!%\u001b(B\n\n     (d) \u001b$B$=$NB>$NJQ99>r7o$r:n<T$H9g0U$9$k!%\u001b(B\n\n  3. \u001b$B0J2<$N>r7o$N$$$:$l$+$rK~$?$9;~$KK\\%W%m%0%i%`$r%3%s%Q%$\u001b(B\n     \u001b$B%k$7$?%*%V%8%'%/%H%3!<%I$d<B9T7A<0$G$bG[I[$G$-$^$9!%\u001b(B\n\n     (a) \u001b$B%P%$%J%j$r<u$1<h$C$??M$,%=!<%9$rF~<j$G$-$k$h$&$K!$\u001b(B\n         \u001b$B%=!<%9$NF~<jK!$rL@<($9$k!%\u001b(B\n\n     (b) \u001b$B5!3#2DFI$J%=!<%9%3!<%I$rE:IU$9$k!%\u001b(B\n\n     (c) \u001b$BJQ99$r9T$C$?%P%$%J%j$OL>A0$rJQ99$7$?$&$(!$%*%j%8%J\u001b(B\n         \u001b$B%k$N%=!<%9%3!<%I$NF~<jK!$rL@<($9$k!%\u001b(B\n\n     (d) \u001b$B$=$NB>$NG[I[>r7o$r:n<T$H9g0U$9$k!%\u001b(B\n\n  4. \u001b$BB>$N%W%m%0%i%`$X$N0zMQ$O$$$+$J$kL\\E*$G$\"$l<+M3$G$9!%$?\u001b(B\n     \u001b$B$@$7!$K\\%W%m%0%i%`$K4^$^$l$kB>$N:n<T$K$h$k%3!<%I$O!$$=\u001b(B\n     \u001b$B$l$>$l$N:n<T$N0U8~$K$h$k@)8B$,2C$($i$l$k>l9g$,$\"$j$^$9!%\u001b(B\n\n     \u001b$B$=$l$i%U%!%$%k$N0lMw$H$=$l$>$l$NG[I[>r7o$J$I$KIU$$$F$O\u001b(B\n     LEGAL\u001b$B%U%!%$%k$r;2>H$7$F$/$@$5$$!%\u001b(B\n\n  5. \u001b$BK\\%W%m%0%i%`$X$NF~NO$H$J$k%9%/%j%W%H$*$h$S!$K\\%W%m%0%i\u001b(B\n     \u001b$B%`$+$i$N=PNO$N8\"Mx$OK\\%W%m%0%i%`$N:n<T$G$O$J$/!$$=$l$>\u001b(B\n     \u001b$B$l$NF~=PNO$r@8@.$7$??M$KB0$7$^$9!%$^$?!$K\\%W%m%0%i%`$K\u001b(B\n     \u001b$BAH$_9~$^$l$k$?$a$N3HD%%i%$%V%i%j$K$D$$$F$bF1MM$G$9!%\u001b(B\n\n  6. \u001b$BK\\%W%m%0%i%`$OL5J]>Z$G$9!%:n<T$OK\\%W%m%0%i%`$r%5%]!<%H\u001b(B\n     \u001b$B$9$k0U;V$O$\"$j$^$9$,!$%W%m%0%i%`<+?H$N%P%0$\"$k$$$OK\\%W\u001b(B\n     \u001b$B%m%0%i%`$N<B9T$J$I$+$iH/@8$9$k$$$+$J$kB;32$KBP$7$F$b@U\u001b(B\n     \u001b$BG$$r;}$A$^$;$s!%\u001b(B\n"
  },
  {
    "path": "ChangeLog",
    "content": "Mon May 16 00:00:00 2011, Kiji 0.11\n\n        * Longlife heap optimizations; only newly allocated longlived objects\n          are scanned for additions to remembered set.\n\n        * Heap allocation strategy now governed by RUBY_GC_HEAP_SIZE,\n          RUBY_GC_EDEN_HEAPS, and RUBY_GC_LONGLIFE_LAZINESS environment\n          variables.\n\n        * Added memory summary and object allocation tracing to GC_DEBUG\n          builds, governed by RUBY_GC_DEBUG_SUMMARY, RUBY_GC_DEBUG_DUMP, and\n          RUBY_GC_DUMP_FILE_PATTERN environment variables.\n\n\t* Exposed ObjectSpace.allocated_objects.\n\n\t* Exposed Object.moved? and Object.longlived? APIs.\n\n\t* Added support for BSD-style register naming conventions on\n\t  ucontext_t structures on x86_64 architecture, thereby allowing\n\t  signal handling to work properly on BSD/x86_64 platform.\n\nFri Mar  4 00:00:00 2011, Kiji 0.9\n\n        * Introduced longlife heap\n\nFri Feb  5 23:09:01 2010  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/rational/rational.c: Added to provide a fast implementation\n\t  of Fixnum#gcd (and maybe some others in the future) in C.  The\n\t  base code was submitted by Kurt Stephens. [Feature #2561]\n\n\t* ext/rational/lib/rational.rb: Moved from lib/rational.rb.  Make\n\t  overall code optimization; submitted by Kurt Stephens.\n\t  [Feature #2561]\n\n\t* test/rational/test_rational.rb, test/rational/test_rational2.rb:\n\t  Add tests for Rational, ported from trunk.\n\n\t* test/rational/test_fixnum_gcd.rb: Add a test for Integer#gcd.\n\t  Case values are only provided for i386 and amd64 at the moment;\n\t  submitted by Kurt Stephens. [Feature #2561]\n\nWed Feb  3 21:14:59 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/net/http.rb (Net::HTTP#request): close @socket only after\n\t  started.  [ruby-core:28028]\n\nSat May 22 19:36:38 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_invoke): reverted r25975.  [ruby-dev:39931]\n\t  [ruby-dev:40059]\n\n\t* eval.c (rb_mod_define_method): return original block but not\n\t  bound block.  [ruby-core:26984]\n\nThu May 20 16:28:17 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/webrick/httpservlet/filehandler.rb (make_partial_content):\n\t  add bytes-unit.  [ruby-dev:40030]\n\nThu May 20 16:17:37 2010  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* ext/zlib/zlib.c: backport r18029 and r21861 from trunk.\n\t  * r18029 ext/zlib/zlib.c (rb_deflate_params): flush before\n\t    deflateParams. [ruby-core:17675] (by mame)\n\t  * r21861 ext/zlib/zlib.c (zstream_run): desperately guard the\n\t    variable.  [ruby-core:20576] (by usa)\n\n\t* test/zlib/test_zlib.rb: backport deflate tests from trunk.\n\nThu May 20 15:59:14 2010  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/maker/base.rb, test/rss/test_maker_0.9.rb:\n\taccept any time format in maker. [ruby-core:26923]\n\nThu May 20 15:54:08 2010  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (recursive_push): Taint internal hash to prevent\n\t  unexpected SecurityError; fixes #1864.\n\nThu May 20 15:39:26 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_fwrite): preserve errno.  [ruby-core:27425]\n\nTue Apr 20 08:04:37 2010  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (rb_io_s_read): close the IO if an exception is raised on\n\t  seeking. [ruby-core:27429]\n\nMon Apr 19 22:43:28 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t * ruby.h (RB_GC_GUARD_PTR): workaround for gcc optimization.\n\t   [ruby-core:27402]\n\nTue Apr 20 06:40:53 2010  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* lib/uri/generic.rb (URI::Generic::eql): Check the class of the\n\t  compared object. Based on a patch by Peter McLain [ruby-core:27019]\n\nFri Apr  2 03:27:22 2010  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/net/http.rb (HTTPGenericRequest#send_request_with_body_stream):\n\t  increased encoding chunk size for POST request with body_stream\n\t  (1K -> 16K). patched by Brian Candler. #1284.\n\n\t* test/net/http/test_post_io.rb: added for the patch. It's good if a\n\t  patch comes with a test.\n\nThu Apr  1 05:32:17 2010  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* string.c (rb_str_inspect): wrong result of UTF-8 inspect because of\n\t  the mistake of calculation.  reported by eban via IRC.\n\nSun Jan 10 19:00:31 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/webrick/accesslog.rb : Escape needed.\n\n\t* lib/webrick/httpstatus.rb : ditto.\n\n\t* lib/webrick/httprequest.rb : ditto.\n\n\t* lib/webrick/httputils.rb : ditto.\n\nFri Jan  8 18:51:11 2010  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_fwrite): preserve errno.  [ruby-core:27425]\n\nThu Dec 24 18:04:27 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: default ac_cv_prog_CC to CC.\n\nThu Dec 24 17:56:32 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: MINIRUBY is given via make-flag.\n\nThu Dec 24 17:56:32 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (EXTMK_ARGS): needs MINIRUBY for cross-compile.\n\t  [ruby-core:20131]\n\nThu Dec 24 17:56:32 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* common.mk (EXTMK_ARGS): shouldn't use ``\\\"'' because cmd.exe eat\n\t  ''\\'' in such quotes.\n\nThu Dec 24 17:56:32 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (EXTMK_ARGS): needs MINIRUBY for cross-compile.\n\t  [ruby-core:20131]\n\nThu Dec 24 17:56:32 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* mkconfig.rb (patchlevel): config.status may not contain\n\t  PATCHLEVEL even if other version numbers exist.\n\nThu Dec 24 17:50:35 2009  Yusuke Endoh  <mame@tsg.ne.jp>\n\n\t* ext/stringio/stringio.c (strio_init): rewind when reopened.\n\nThu Dec 24 17:06:13 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (run_final): runs finalizers with the object terminated.\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): ObjectSpace::finalizers needs\n\t  to scan whole object space, although deprecated.\n\nThu Dec 24 17:06:13 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (chain_finalized_object): deletes finalizers to be invoked from\n\t  finalizer_table.\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): warns when could not invoke\n\t  finalizers.\n\nMon Dec 21 16:09:09 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (LD_SHARED1): typo.\n\nWed Dec 16 20:17:40 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (CreateChild): allocate temporary buffer and use it\n\t  instead of directly modify the passed string.  [ruby-dev:39635]\n\nWed Dec 16 19:49:47 2009  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* instruby.rb (with_destdir): revert. [ruby-dev:39885]\n\nMon Dec 14 13:28:48 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit.rb (Test::Unit.run=, Test::Unit.run?): fixed rdoc.\n\t  [ruby-core:25034]\n\nMon Dec 14 13:21:32 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/open3.rb (Open3#popen3): fixed and improved rdoc.  [ruby-core:25658]\n\nMon Dec 14 13:09:01 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (LIBPATHFLAG): use numbered specifier if RPATHFLAG\n\t  is set.  [ruby-talk:322136]\n\nMon Dec 14 12:53:56 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* lib/bigdecimal.rb: fix comparison operators [ruby-core:26646]\n\nMon Dec 14 12:40:10 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* object.c (rb_Float): Allow results of to_f to be NaN\n\t  [ruby-core:26733]\n\nMon Dec 14 12:35:21 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_invoke): unbound block created by define_method\n\t  cannot call super.  [ruby-core:26984]\n\nMon Dec 14 12:06:39 2009  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/digest.c (rb_digest_instance_method_unimpl): Do not\n\t  call rb_inspect() on an object that does not implement necessary\n\t  methods; reported by NaHi.\n\nMon Dec 14 11:47:31 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_method_missing): adjusted format and argument number.\n\n\t* eval.c (rb_call): fixed for super in cached method.\n\t  [ruby-dev:39757]\n\nMon Dec 14 11:40:35 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (ruby_setenv): get rid of crash in Solaris 8 and 10.\n\t  [ruby-core:26668]\n\nMon Dec 14 11:31:58 2009  Takeyuki FUJIOKA  <xibbar@ruby-lang.org>\n\n\t* lib/cgi.rb: fix command-line option of\n\t  non-interactive terminal. [ruby-core:23016]\n\nMon Dec 14 03:36:20 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* eval.c (method_inspect, method_name, mnew): Bug fix when\n\t  method created from an alias.\n\t  Based on a patch by Peter Vanbroekhoven [ruby-core:22040]\n\nMon Dec 14 02:27:32 2009  Yusuke Endoh  <mame@tsg.ne.jp>\n\n\t* hash.c (rb_hash): always return a fixnum value because a return\n\t  value of rb_hash may be used as a hash value itself and bignums have\n\t  no unique VALUE.\n\n\t* test/ruby/test_hash.rb: add a test for above.\n\nMon Dec 14 00:42:55 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_inspect): get rid of adding garbage to shor\n\t  UTF-8 string.  [ruby-dev:39550]\n\nSun Dec 13 23:54:22 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (marshal_load): should set taintness.  [ruby-dev:39723]\n\nSun Dec 13 23:54:22 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (struct {dump,load}_arg): manage with dfree, instead\n\t  of using local variable which may be moved by context switch.\n\t  [ruby-dev:39425]\n\nWed Nov 25 17:42:33 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_fwrite): adjust stdio file position after direct write on\n\t  BSDish platforms.   [ruby-core:26300]\n\nWed Nov 25 17:39:28 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/ostruct/test_ostruct.rb (test_frozen): added assertions.\n\nWed Nov 25 16:43:24 2009  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/monitor.rb (MonitorMixin.mon_release): ensure the scheduled\n\t  thread to be alive when a thread is releasing a monitor. #2240\n\nWed Nov 25 16:28:11 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* lib/rexml/element.rb (text=): false should be converted to string.\n\t  A patch by Teruo Oshida [ruby-dev:38351]\n\nWed Nov 25 16:18:37 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_clear_cache_for_undef): clear entries for inherited\n\t  methods.  [ruby-core:26074]\n\nTue Nov 24 16:15:18 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_create): cannot retry with given block.\n\t  [ruby-dev:39487]\n\nTue Nov 24 16:12:33 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (resp_text_code): accepts response codes without\n\t  text.  backported from trunk.  [ruby-core:24194]\n\nTue Nov 24 16:09:41 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (getaddress): rescue exceptions.  [ruby-dev:39451]\n\nTue Nov 24 15:51:07 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* ext/curses/curses.c: Many functions of module Curses could cause a\n\t  crash if the ncurses library was not properly initialized.\n\t  Fix pointed out by Alexander Beisig [ruby-core:22592]\n\t  Functions fixed: attroff, attron, attrset, bkgd, bkgdset,\n\t  can_change_color, close_screen, closed, color_content, curs_set,\n\t  def_prog_mode, delch, deleteln, getmouse, getstr, has_colors,\n\t  init_color, init_pair, insertln, keyname, mouseinterval, mousemask,\n\t  pair_content, pair_number, reset_prog_mode, resizeterm, scrl,\n\t  setscrreg, standend, standout, start_color, timeout, ungetmouse\n\nFri Nov 20 15:49:59 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/resolv.rb (Resolv::DNS.bind_random_port): bind to \"::\" for IPv6.\n\t  (Resolv::DNS::ConnectedUDP#initialize): specify is_ipv6 argument of\n\t  bind_random_port.\n\t  [ruby-core:25970]\n\nThu Nov 19 18:03:31 2009  Takeyuki FUJIOKA  <xibbar@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI.unescapeHTML): fix for hex values 80-FF,\n\t  single-byte hex entity encodings from 80-FF are valid HTML.\n\t\t[ruby-core:25702]\n\nThu Nov 19 15:34:40 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fptr_finalize): free fptr to avoid memory leaks.\n\t  fixed: #2009   [ruby-core:25173] [ruby-dev:39410]\n\nThu Nov 19 15:27:17 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* lib/net/http.rb (transport_request): Handle timeout error by\n\t  closing socket if exception raised. [ruby-core:20976]\n\nWed Nov 18 14:14:38 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* ext/openssl/ossl_config.c (ossl_config_add_value_m,\n\t  ossl_config_set_section): Check if frozen (or untainted for $SECURE >=\n\t  4) [ruby-core:18377]\n\nWed Nov 18 14:13:14 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* instruby.rb: win32/win32.h exists in srcdir.\n\t  reported by arton ( http://www.artonx.org/diary/20090919.html#p01 )\n\nWed Nov 18 14:13:14 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (subtract): if the parameters are same value, should\n\t  return zero.\n\nWed Nov 18 14:13:14 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_select): of course, need to initialize rest.\n\nWed Nov 18 14:13:14 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_select): wait specified time on select.\n\nWed Nov 18 14:13:14 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_select): on 1.8, we don't need to poll sockets,\n\t  because our select is never called from multiple threads.\n\nTue Nov 17 16:22:22 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0, rb_thread_start_1): should call star\n\t  timer after added new thread to thread list.  [ruby-core:25613]\n\nTue Nov 17 16:22:22 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_timer): start to catch SIGVTALRM together\n\t  with timer thread.   [ruby-core:25606]\n\n\t* eval.c (rb_thread_atfork): stop timer thread.\n\nTue Nov 17 16:04:02 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* lib/cgi/cookie.rb (value): Keep CGI::Cookie#value in sync with the\n\t  cookie itself. A patch by Arthur Schreiber [ruby-core:17634]\n\nTue Nov 17 15:49:00 2009  Marc-Andre Lafortune  <ruby-core@marc-andre.ca>\n\n\t* lib/irb/ext/multi-irb.rb: Fix arguments handling for shell commands\n\t  in irb; a patch by Yusuke Endoh [ruby-dev:35075]\n\nTue Nov 17 15:32:27 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_binmode): check if closed regardless platforms.\n\t  [ruby-core:25363]\n\nTue Nov 17 15:31:09 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (round): added declaration.  [ruby-dev:39222]\n\nMon Nov 16 19:58:02 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (gc_sweep): makes new room if object space is full of\n\t  finalized objects and has no free objects.  [ruby-dev:39201]\n\nMon Nov 16 19:45:27 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* util.c: suppress strict-aliasing warning with gcc-4.4.0 -O2 to fix\n\t  infinite loop by ruby -e \"1.402e-45\" .\n\nMon Nov 16 19:28:23 2009  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_to_i): revert a part of\n\t  r23645, which was not a bug fix. [ruby-dev:39474]\n\nFri Sep 11 11:56:53 2009  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* class.c (rb_singleton_class_clone): Qnil must be used for a null\n\t  class reference when we use NIL_P() to check class reference\n\t  validity.  The bug was exposed by the spec test of Sequel.\n\n\t* eval.c (ruby_init): Use NEW_CREF().\n\nThu Sep 10 10:53:03 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (rb_sysopen): workaround for MSVCRT's bug.\n\t  [ruby-core:24838]\n\nMon Sep  7 19:52:44 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (rb_thread_schedule): need select for WAIT_SELECT, even if\n\t  already timeout.  [ruby-dev:38971]\n\t  (WAIT_DONE): defined for mark threads which can be runnable.\n\nMon Sep  7 19:52:44 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (rb_thread_schedule): refine previous change.\n\nMon Sep  7 19:52:44 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (rb_thread_schedule): fix condition for making thread\n\t  runnable.  [ruby-core:23515]\n\nSun Sep  6 19:47:10 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_exc_raise, rb_exc_fatal): require exception object.\n\t  [ruby-core:24767]\n\nSun Sep  6 01:34:03 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_connect): return value was broken when some\n\t  error occurred.\n\t  [ruby-core:24234]\n\nFri Sep  4 10:03:22 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (argf_eof): go to the next file if called after ARGF.close\n\t  or ARGF.skip.  a patch from Mike Kasick at [ruby-core:24561].\n\nSun Aug  9 17:43:44 2009  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/irb.rb, lib/irb/init.rb, lib/irb/ext/save-history.rb: add\n\t  IRB::irb_at_exit. no use finalizer saving history. [ruby-dev-38563]\n\nWed Aug  5 15:29:54 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (rb_io_flush): fsync() after buffer is flushed on win32.\n\t  backported from trunk.  [ruby-core:20043]\n\n\nTue Aug  4 11:00:30 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* re.h (RMATCH_REGS): added for compatibility.\n\nMon Aug  3 14:46:53 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/complex.rb (Numeric#arg): should return NaN for NaN.\n\t  [ruby-core:24116]\n\nThu Jul 30 09:27:44 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (big_lshift, big_rshift): return Bignum always withou\n\t  normalization.  [ruby-dev:38680]\n\nWed Jul 29 11:19:47 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_close): always call #close method.  [ruby-core:23853]\n\n\t* io.c (argf_skip): should close only when current_file is available.\n\nSat Jul 25 21:26:18 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (first_i): Enumerator#first should consume only what is\n\t  needed.   a patch from Marc-Andre Lafortune.  [ruby-core:23661]\n\n\t* enum.c (take_i): ditto.\n\n\t* enum.c (enum_first): call to_int once for an argument.  a patch\n\t  from Marc-Andre Lafortune.\n\nFri Jul 24 17:19:40 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (HTTP_STATUS): typo fixed.   [ruby-dev:38538]\n\nWed Jul 22 23:39:34 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rexml/text.rb (REXML::Text.normalize): call to_s for input.\n\t  [ruby-talk:337069]\n\nTue Jul 21 18:21:47 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (SRC_EXT): should be flat.\n\t  http://twitter.com/_tad_/status/1825862632\n\nSat Jul 18 00:44:43 2009  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): finalizer_table can be NULL.\n\t  [ruby-core:24395]\n\nThu Jul 16 09:35:06 2009  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/delegate.rb (Delegator#method_missing)\n\t  (DelegateClass()#method_missing): Properly pass a given block\n\t  through. [ruby-dev:38390]\n\nWed Jul 15 11:40:34 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_join): recursive array has no meaning as path\n\t  name.  [ruby-core:23329]\n\nTue Jul 14 19:57:28 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (get_ts): use readtime clock.  [ruby-dev:38354]\n\n\t* eval.c (rb_thread_stop_timer): clear thread_init while locking.\n\nTue Jul 14 19:57:28 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_timer): guard condition was inverted.\n\t  [ruby-dev:38319]\n\nTue Jul 14 19:57:28 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (safe_mutex_lock): pthread_cleanup_push() must not be\n\t  inside parens.\n\nMon Jul 13 01:36:54 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_timeval): rounds subsecond toward zero.\n\nMon Jul 13 01:36:54 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_timeval): check out-of-range.  [ruby-core:23282]\n\t  [Bug #1396]\n\nThu Jul  9 17:58:03 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_invoke): shares dmethod scope local variables.\n\t  a patch from coderrr at [ruby-core:23050]\n\n\t* gc.c (obj_free): do not free cloned scope local variables.\n\nWed Jul  8 19:28:03 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_remove): stops timer thread unless other\n\t  threads exist.  [ruby-core:18444]\n\nMon Jul  6 16:01:38 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): checks for interrupt, stack and finalizers too.\n\t  [ruby-dev:38208], [Bug #1329]\n\n\t* eval.c (eval): replaces the message if frozen.\n\nSun Jul  5 03:50:52 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit.rb: use Kernel.exit to get rid of using\n\t  IRB::ExtendCommandBundle#exit.  a patch from Dmitry Vazhov by\n\t  [ruby-core:22986].\n\nFri Jul  3 09:05:38 2009  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (open_server_inaddr_any): fixed multiple network\n\t  families problem. a patch from Charl Matthee at [ruby-core:21033].\n\nWed Jul  1 15:46:30 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/pathname.rb (Pathname#sub): set $~ in block.binding.\n\t  [ruby-dev:38173]\n\nMon Jun 29 13:18:42 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/fileutils.rb (FileUtils#fu_get_gid): stringify group\n\t  argument before making regexp match.  [ruby-dev:38155]\n\nFri Jun 12 16:36:44 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (VpToString): fixed a bug introduced\n\t  in r23613.  [ruby-talk:338957]\n\nMon Jun  8 10:58:41 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): mswin32 doesn't have F_GETFD, so check\n\t  with another method.\n\nMon Jun  8 08:15:36 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (VpAlloc): avoid ALLOCA_N() to avoid\n\t  segmentation fault caused by (insanely) long decimal values.\n\t  backported from 1.9. CVE-2009-1904\n \n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_dump, BigDecimal_to_i,\n\t  BigDecimal_to_f, BigDecimal_to_s, BigDecimal_split,\n\t  BigDecimal_inspect): ditto.\n\nMon Jun  8 08:15:36 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_to_f): returns Inf if\n\t  exp is bigger than DBL_MANT_DIG.\n\nWed Jun  3 21:16:30 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* file.c: include fcntl.h for O_RDONLY on Solaris.\n\nWed Jun  3 21:09:56 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.c (rv_strdup): macro to duplicate nul-terminated string.\n\t  [ruby-core:22852]\n\n\t* util.c (ruby_dtoa): allocates one more byte to get rid of buffer\n\t  overrun.  a patch from Charlie Savage at [ruby-core:22604].\n\nWed Jun  3 21:09:56 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.c (ruby_dtoa): allocates one more byte to get rid of buffer\n\t  overrun.  a patch from Charlie Savage at [ruby-core:22604].\n\nWed Jun  3 21:05:44 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (gfDebug): uncommented out.\n\t  [ruby-core:22600]\n\nWed Jun  3 20:54:23 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): needs to guard intermediate string objects.\n\t  based on a patch from Brent Roman <brent AT mbari.org> a\n\t  [ruby-core:22584].\n\nTue May 26 21:24:01 2009  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* Makefile.in (update-rubyspec, test-rubyspec): Catch up to\n\t  rubyspec merge.  A patch by Brian Ford at [ruby-core:21032]\n\nTue May 26 21:21:49 2009  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/soap/mimemessage.rb (MIMEMessage#to_s): Fix a fatal\n\t  method name typo. [Bug #1173]\n\nTue May 26 21:16:55 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_extname): fix for spaces before extention.\n\t  [ruby-dev:38044]\n\nTue May 26 21:09:21 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (_CrtDbgReportW): prevent from false positive\n\t  assertions in msvcrtd.  [ruby-core:22116]\n\nTue May 26 21:02:13 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/ostruct.rb (OpenStruct#new_ostruct_member): checks if frozen.\n\t  [ruby-talk:328195], [ruby-core:22142]\n\nTue May 26 21:00:08 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/ostruct.rb (OpenStruct#inspect): fixed the recursion check.\n\t  Patch by Kornelius Kalnbach.  [ruby-core:20992].\n\n\t* test/ostruct/test_ostruct.rb: test for inspect.\n\t  Patch by Kornelius Kalnbach.  [ruby-core:20992].\n\nTue May 26 20:50:32 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (rb_thread_schedule): handle EBADF of select as well.\n\t  [ruby-core:21264]\n\nWed Apr  8 18:59:52 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (subtruct): check tv_sec.\n\nThu Apr  2 16:06:17 2009  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* test/rss/test_atom.rb (RSS::TestAtomCore::assert_atom_content_inline_other_base64_to_s):\n\t  ditto. [ruby-dev:38248]\n\nThu Apr  2 15:43:46 2009  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* test/rss/rss-assertions.rb (RSS::Assertions::assert_atom_content_inline_other_text):\n\t  newlines are valid for Base64 data. [ruby-dev:38248]\n\nThu Apr  2 14:17:09 2009  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* test/openssl/test_ssl.rb (OpenSSL#test_client_session):\n\t  Debian's openssl 0.9.8g-13 failed at assert(ssl.session_reused?),\n\t  when use default SSLContext. [ruby-dev:36167]\n\t  backported r19268 from trunk. [ruby-core:22843]\n\nThu Mar 31 18:18:18 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (mkintpath): new function which converts native path\n\t  to format acceptable in Makefile.\n\n\t* lib/mkmf.rb (configuration): leaves PATH_SEPARATOR unchanged.\n\n\t* lib/mkmf.rb (configuration): convers srcdir, topdir and hdrdir.\n\t  a patch by Alexey Borzenkov <snaury AT gmail.com> at\n\t  [ruby-core:21448].\n\nFri Mar 27 19:22:02 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (run_final): frees zombies only.  [ruby-dev:38171]\n\nFri Mar 27 19:22:02 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): leave Thread objects\n\t  unfinalized.  [ruby-dev:38168]\n\nFri Mar 27 19:22:02 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (run_final): calls free function.  [ruby-core:22578]\n\nMon Mar 23 19:17:06 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/thread/thread.c (rb_queue_pop, rb_queue_push): should not lock\n\t  mutex if got an exception while waiting, and should ensure unlocked\n\t  after signaled.  [ruby-dev:37545]\n\nMon Mar 23 18:26:57 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_value): missed to change at r17874.  [ruby-core:17595]\n\nMon Mar 23 18:26:57 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_join): new API.\n\n\t* ext/thread/thread.c (wait_mutex, lock_mutex): wait until the locking\n\t  thread exits.  [ruby-dev:34856]\n\nMon Mar 23 17:41:49 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (file_load_ok): checks if regular file, except for the\n\t  platform disallows to open directories, e.g. dosish.\n\t  [ruby-dev:38097], [Bug #1221]\n\nMon Mar  9 20:59:24 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/openssl/ossl_ocsp.c (ossl_ocspbres_verify): OCSP_basic_verify\n\t  returns positive value on success, not non-zero.  [ruby-core:21762]\n\t  backported r22440 from trunk.\n\nMon Mar  9 10:02:15 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (match_check): check if MatchData is initialized.\n\t  [ruby-core:18749]\n\nMon Mar  9 09:56:34 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/rexml/rexml.rb: incremented Ruby::VERSION.  Thanks, Jeremy\n\t  Kemper.  [ruby-core:20113]\n\nMon Mar  9 09:52:53 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* io.c (io_getpartial): fflush after read for updating pos in FILE.\n\t  not portable, I guess.  [ruby-core:21561]\n\nMon Mar  9 09:04:39 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (define_final): cannot define finalizer for immediate\n\t  values.  [ruby-core:21500]\n\n\t* gc.c (define_final): freezes or hides internal values.\n\nMon Mar  9 08:54:47 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (IS_BEG): EXPR_CLASS should be treated like EXPR_BEG.\n\t  [ruby-core:21453]\n\nWed Feb 25 15:15:52 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* node.h (rb_thread_raised_clear): should not clear flags other than\n\t  raised flags.  a patch by Tomoyuki Chikanaga <chikanag AT\n\t  nippon-control-system.co.jp> at [ruby-dev:37794].  [ruby-dev:37776]\n\nWed Feb 25 15:05:48 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/extconf.rb (gai_strerror): checks if available and if\n\t  returns const pointer.\n\n\t* ext/socket/getaddrinfo.c (gai_strerror): defines only if non\n\t  available.  [ruby-core:21328]\n\nWed Feb 25 14:57:18 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (open_dir_handle): extracted from rb_w32_opendir.\n\n\t* win32/win32.c (winnt_stat): gets rid of strange behavior of\n\t  GetFileAttributes().  [ruby-core:21269]\n\nTue Feb 24 02:44:39 2009  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb (PercentScanner): remove PercentScanner. fixed % after\n\t  %> bug. [ruby-dev:37751] [Bug #997] \n\n\t* test/erb/test_erb.rb: ditto\n\nTue Feb 24 02:35:29 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (rb_hash_s_create): set nil as the value if assoc length\n\t  is not enough.  [ruby-core:21249]\n\nSun Feb 22 22:08:45 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (stack_extend): streamlined rb_thread_restore_context()\n\t  to ensure O(1) time.  based on a patch by Brent Roman <brent AT\n\t  mbari.org>.\n\nSun Feb 22 22:03:40 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (cc_mark): frees the continuation's stack if its thread\n\t  is dead to avoid recursive gc that segfaults.  [ruby-core:13889]\n\t  a patch by Brent Roman <brent AT mbari.org>.\n\n\t* eval.c (rb_cont_check): checks for valid continuation instance.\n\n\t* eval.c (rb_callcc): assigns th->thread before scope_dup() to\n\t  avoid segfaults if this scope_dup() triggers a gc pass.\n\t  a patch by Brent Roman <brent AT mbari.org>.\n\nSun Feb 22 21:43:34 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (ruby_float_step): extracted from num_step().\n\n\t* range.c (range_step): uses ruby_float_step() for float range.\n\t  [ruby-dev:37691]\n\nSun Feb 22 00:49:36 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): does not use both of makefile.rb and\n\t  extconf.rb at the same time.\n\n\t* lib/mkmf.rb (DLLIB): depends on Makefile.  [ruby-core:21096]\n\nSun Feb 22 00:19:05 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (rb_thread_schedule): Don't change status of threads which\n\t  don't run next even if select notify readability/writability.\n\t  [ruby-core:20446]\n\nFri Feb 20 20:43:13 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::List#summarize): gives priority\n\t  to latter switches.  [ruby-dev:36692]\n\n\t* lib/optparse.rb (OptionParser#summarize): do not append\n\t  unnecessary line terminator.\n\nFri Feb 20 19:35:08 2009  Takeyuki FUJIOKA  <xibbar@ruby-lang.org>\n\n\t* lib/cgi/session.rb: ignore session_id options fixed.[Bug #605]\n\nFri Feb 20 18:06:40 2009  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 20854 from trunk.\n\n\t* lib/xmlrpc/server.rb:  Restricting method inspection to show only\n\t  non-inherited public methods.  [ruby-core:20603]\n\n\t* lib/xmlrpc/server.rb:  Fixing method inspection so it doesn't \n\t  trigger XMLRPC::FaultException when used.  [ruby-core:20604]\n\nFri Feb 20 01:41:08 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/sync.rb (Sync_m#sync_try_lock): wrong variable name fixed.\n\t  a patch from [ruby-core:20561]\n\n\t* lib/sync.rb (Sync_m::Err.Fail): turn off Thread.critical before\n\t  exit.\n\nThu Feb 19 18:02:10 2009  Yuki Sonoda (Yugui)  <yugui@yugui.jp>\n\n\t* pack.c (pack_pack): fixed odd act of 'm*', 'M*', and 'P*'.\n\t  just ignores '*' in these cases.\n\t  [ruby-dev:37289]\n\nThu Feb 19 17:26:11 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* pack.c (pack_pack): fixed length for odd length string.\n\t  [ruby-dev:37283]\n\nThu Feb 19 17:13:13 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): Qundef means no argument.  [ruby-Bugs-22525]\n\nWed Feb 18 22:28:00 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_isatty): check whether fd is valid.\n\nWed Feb 18 22:24:23 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (waitpid): fix bug of checking child slot.\n\n\t* win32/win32.c (FindChildSlotByHandle): new.\n\nWed Feb 18 22:17:04 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): propagate taint status from format string to\n\t  result string.\n\nWed Feb 18 22:07:44 2009  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* ext/gdbm/gdbm.c: do not set members of RSTRING(str) directly.\n\t  [ruby-dev:37182]\n\n\t* ext/gdbm/gdbm.c (rb_gdbm_nextkey): fix memory leak.\n\nTue Feb 17 11:58:58 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (str_independent): no independent string points null_str.\n\t  [ruby-core:20082]\n\nMon Feb 16 23:30:24 2009  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/blt.rb, ext/tk/lib/tkextlib/blt/vector.rb: \n\t  fix NameError bug.\n\nMon Feb 16 23:08:22 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_s_alloc, rb_str_replace): use null_str as well as\n\t  rb_string_value so that extension libraries do not segfault.\n\t  [ruby-core:19971]\n\n\t* string.c (rb_str_replace): reduced unnecessary malloc and copy.\n\nMon Feb 16 22:45:41 2009  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/rinda/test_rinda.rb: fixed fails occasionally [ruby-dev:37119].\n\t  thanks, shinichiro.h.\n\nMon Feb 16 22:36:37 2009  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRbConn::alive?): fixed NoMethodError problem\n\t  from NaHi [ruby-dev:37110].\n\nSun Feb 15 04:21:42 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/net/ftp.rb (Net::FTP#open_socket): SOCKSsocket is obsolete.\n\t  a patch from Alan Johnson <alan.wayne.johnson at gmail.com> in \n\t  [ruby-core:19982].\n\nFri Feb 13 19:18:42 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/logger.rb (ProgName): fixed for svn, based on a patch from\n\t  Nobuhiro IMAI at [ruby-dev:37108].\n\nSun Feb 15 04:17:40 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/webrick/httprequest.rb (WEBrick::HTTPRequest#read_request_line):\n\t  use non-greedy match for path retrieval to avoid huge recursion\n\t  for insanely long path.\n\nFri Feb 13 19:04:54 2009  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* shell/command-processor.rb: undefined method `top_level_test' in\n  \t  Shell#test. [ruby-list:45634]\n\nTue Feb 10 20:00:52 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (load_lock): makes circular require deadlock.\n\t  [ruby-core:19821]\n\nTue Feb 10 19:40:58 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_feature_p): returns found feature name if loading.\n\t  [ruby-core:19798]\n\n\t* eval.c (search_required): ditto.\n\nWed Feb 11 23:37:35 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (VpMidRound): Round method bug\n\t  pointed by Ryan Platte fixed(Patch to the patch from \"NATORI\n\t  Shin\").  [ruby-talk:273360]\n\t  back ported from 1.9. fix [ruby-core:19791]\n\nMon Feb  9 17:35:38 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_accept): secure fd before accept because if\n\t  error causes in securing, cannot restore the state of accepted\n\t  socket.\n\t  fixed [ruby-core:19728]\n\nMon Feb  9 13:42:15 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (ifs_open_socket): should retry without proto_buffer\n\t  if cannot find the suitable protocol. a patch from Heesob Park.\n\t  fixed [ruby-core:19713]\n\nMon Feb  9 13:40:21 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_ungetc): should allow ungetc at\n\t  the top of the buffer.  ref #701\n\nThu Feb  5 09:38:48 2009  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c (h_conv): can't guess UTF-8 input in\n\t  conversion. [ruby-list:45609]\n\nThu Feb  5 09:03:21 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/rexml/entity.rb (unnormalized): do not call\n\t  document.record_entity_expansion if document is nil.\n\t  see <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=502535>.\n\t  Thanks, Naohisa Goto.  backported from trunk.\n\n\t* test/rexml/test_document.rb: ditto.\n\nThu Feb  5 08:55:24 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (rb_ary_join): do not repeat self in a recursive array.\n\t  [ruby-dev:37019]\n\nWed Feb  4 14:26:58 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_globs): need taint check.  reported by steve\n\t  <oksteev at gmail.com>\n\nTue Feb  3 14:35:26 2009  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/net/pop.rb: check for invalid APOP timestamp. (CVE-2007-1558)\n\t  [ruby-dev:36631]\n\n\t* test/net/pop/test_pop.rb: ditto.\n\nMon Feb  2 20:03:58 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_mdump, time_mload): preserves GMT status.\n\t  [ruby-core:19252]\n\nMon Feb  2 11:34:51 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* variable.c (autoload_delete, autoload_file): should not delete\n\t  autoload table, since it may be shared with duplicated modules.\n\t  [ruby-core:19181]\n\nThu Jan 29 11:54:22 2009  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb (today,now): should produce own instances.\n\t  [ruby-talk:317020]\n\nWed Jan 28 22:51:55 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_mod_modfunc): method undefined in included module\n\t  may not have nd_body.  [ruby-core:18738]\n\nWed Jan 28 20:53:27 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (marshal_dump): fixed for check_dump_arg.\n\nTue Jan 27 17:30:11 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (marshal_dump): initializes dump_arg before any funcall.\n\t  [ruby-dev:36648]\n\nTue Jan 27 15:17:35 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/socket.c (host_str): numeric address should be unsigned.\n\t  [ruby-core:18971]\n\nMon Jan 26 11:12:03 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/tmpdir.rb: setup buffer with nul characters instead of spaces.\n\t  fixed [ruby-dev:36493]\n\nSun Jan 25 00:07:23 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rexml/formatters/pretty.rb (REXML::Formatters::Pretty#wrap):\n\t  abandon wrapping if the line contains no space.  [ruby-dev:36045]\n\t  fix: #342\n\nSun Jan 25 00:02:23 2009  Yuki Sonoda (Yugui)  <yugui@yugui.jp>\n\n\t* lib/matrix.rb (Vector#eql?): typo of the method name as \"eqn?\".\n\t  (Vector#eqn?): removed. Defined by mistake.\n\t  Fixes [ruby-dev:36294]. Reported by weda <weda AT\n\t  issp.u-tokyo.ac.jp> and an anonymous user.\n\n\t* test/matrix/test_matrix.rb: added.\n\n\t* test/matrix/test_vector.rb: added.\n\nFri Jan 23 11:49:45 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* NEWS: added an entry for REXML.\n\n\t* lib/rexml/document.rb: fixed typo.\n\nFri Jan 23 11:49:45 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/rexml/document.rb: limit entity expansion.  Thanks, Luka\n\t  Treiber, Mitja Kolsek, and Michael Koziarski.  backported from\n\t  trunk r19033, r19317, r19318.\n\n\t* lib/rexml/entity.rb: ditto.\n\n\t* test/rexml/test_document.rb: ditto.\n\nThu Jan 22 15:19:39 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (marshal_load): arg.data is no longer a VALUE but a\n\t  st_table, and freed in load_ensure.  pointed out by pegacorn.\n\t  [ruby-dev:37008]\n\nThu Jan 22 15:19:39 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (rb_mark_set): new function to mark keys.\n\n\t* marshal.c (struct dump_arg, struct load_arg): added wrappers to mark\n\t  data entries.  backport from trunk r13527,r13528,r13961,r16533.\n\t  [ruby-dev:36082]\n\nWed Jan 21 11:12:55 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (filetime_to_timeval): new function, split from\n\t  gettimeofday().\n\n\t* win32/win32.c (gettimeofday): use above function.\n\n\t* win32/win32.c (filetime_to_unixtime): ditto. [ruby-dev:36135]\n\nWed Jan 21 11:12:55 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (gettimeofday): tv_usec is usec, not msec.\n\t  [ruby-dev:36094]\n\nWed Jan 21 11:12:55 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (gettimeofday): calc tv_sec and tv_usec from system\n\t  time by myself. [ruby-dev:36084]\n\nWed Jan 21 11:12:55 2009  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (gettimeofday): shouldn't use mktime(2) because it's\n\t  buggy about handling summer time.\n\t  reported by Yoshikawa <yoshixool AT gmail.com> at [ruby-dev:36071]\n\nTue Jan 20 12:23:38 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/scanf.rb (Scanf::FormatSpecifier#initialize): %i should accept\n\t  single digit decimal.  [ruby-core:18355]\n\nMon Jan 19 18:25:28 2009  Tanaka Akira  <akr@fsij.org>\n\n\t* configure.in (rb_cv_broken_glibc_ia64_erfc): renamed from\n\t  rb_broken_glibc_ia64_erfc.\n\t  [ruby-core:18228]\n\nSat Jan 17 12:16:10 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* random.c (Init_Random): always initialize seed.\n\nFri Jan 16 10:59:31 2009  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (clone_method): should copy cbase in cref as well.\n\t  [ruby-dev:35116]\n\n\t* node.h (NEW_CREF): new NEW_ macro.\n\n\t* eval.c (PUSH_CREF): use NEW_CREF().\n\nThu Jan 15 14:34:32 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (STACK_LEVEL_MAX, ruby_stack_length): returns size_t.\n\t  [ruby-core:18207]\nWed Jan 14 10:39:56 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* stable/ext/socket/socket.c (NI_MAXHOST, NI_MAXSERV): fixed invalid\n\t  preprocessor directives.  a patch from Peter Bowen at\n\t  [ruby-core:18211].\n\nTue Jan 13 04:40:30 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (login): raise FTPReplyError if passwd or acct\n\t  is not supplied.  backported from trunk.  fixed [ruby-core:18058].\n\nMon Jan 12 00:23:37 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (gc_sweep, obj_free, run_final): defer finalizers of IO and\n\t  Data.  [ruby-dev:35578]\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): self-referencing finalizers\n\t  cannot be invoked.  [ruby-dev:35681]\n\nSun Jan 11 11:33:27 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (chdir): handle 5xx errors correctly.\n\t  backported from trunk.  fixed [ruby-core:18057].\n\nFri Jan  9 19:25:25 2009  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (disconnect): do not refer SSL::SSLSocket for\n\t  environments without OpenSSL.  backported from trunk.\n\t  fixed [ruby-dev:35755].\n\nThu Jan  8 13:24:23 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (deferred_nodes, compstmt, arg, fixup_nodes, range_op): fix\n\t  up fixnum range literal in conditional as automagical line number\n\t  comparison.  [ruby-core:12124], [ruby-dev:35731]\n\nWed Jan  7 10:09:46 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (timeofday): use monotonic clock.  based on a patch\n\t  from zimbatm <zimbatm@oree.ch> in [ruby-core:16627].\n\nTue Jan  6 09:03:35 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (yylex): 8 and 9 in octal integer should cause compile\n\t  error.  [ruby-dev:35729]\n\nMon Jan  5 11:14:39 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): runs deferred finalizers.\n\n\t* gc.c (gc_sweep): sets rb_thread_pending to run deferred finalizers.\n\n\t* rubysig.h (CHECK_INTS): now checks rb_thread_pending even on\n\t  platforms where setitimer is not available.  [ruby-core:18045]\n\nMon Jan  5 11:14:39 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* rubysig.h (CHECK_INTS): gives the chance to perform to deferred\n\t  finalizers before explicit GC.start or the process termination.\n\t  [ruby-core:18045]\n\nSun Jan  4 04:49:01 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_telldir): just returns loc.\n\n\t* win32/win32.c (rb_w32_rewinddir): needs to intialize loc.\n\t  [ruby-core:18041]\n\nSun Jan  4 04:45:26 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_select): recalc the rest of timeout for each\n\t  iterations.  [ruby-core:18015]\n\nFri Jan  2 03:08:47 2009  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* test/rss/: use PNG instead of zlib as binary data. [ruby-dev:35666]\n\nTue Nov 11 01:07:32 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* configure.in: fix SEGV on Mac OS X 10.5.3 with --enable-pthread.\n\t  a patch from Wataru Kimura in Bug #193 [ruby-core:17333].\n\nMon Aug 11 09:37:17 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dl/dl.c (rb_str_to_ptr): should propagate taint to dlptr.\n\n\t* ext/dl/dl.c (rb_ary_to_ptr): ditto.\n\n\t* ext/dl/sym.c (rb_dlsym_call): should check taint of DLPtrData as\n\t  well.\n\nFri Aug  8 10:53:52 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/resolv.rb: randomize source port and transaction id.\n\t  CVE-2008-1447.\n\n\t* lib/resolv-replace.rb (UDPSocket#bind): don't resolv host if host is\n\t  \"\".\n\nMon Aug  4 14:49:35 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* lib/net/smtp.rb (Net::SMTP::rcptto): fix a typo. a patch from\n\t  Masao Takaku <masao at nii.ac.jp>\n\t  fix [ruby-dev:35489].\n\nMon Aug  4 14:13:15 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* regex.c (xmalloc, xrealloc, xfree): not to use ruby managed memory.\n\n\t* regex.c (DOUBLE_STACK, re_compile_fastmap0, re_adjust_startpos),\n\t  (re_search, re_match_exec): check if failed to allocate memory.\n\nMon Aug  4 13:53:42 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big2str0, bigsqr): made interruptible.  [ruby-Bugs-20622]\n\nMon Aug  4 13:31:41 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* numeric.c (check_uint, rb_num2uint, rb_fix2uint): fixed wrong check\n\t  about 64bit positive value.\nMon Aug  4 13:31:41 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* numeric.c (check_uint, rb_num2uint, rb_fix2uint): strict check.\n\t  fixed [ruby-dev:33683]\n\nThu Jul 17 21:42:07 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* lib/net/smtp.rb (Net::SMTP::start): revert to avoid RFC2821\n\t  violation. [ruby-dev:35487]\n\nThu Jul 17 21:32:49 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* string.c (rb_str_format_m): make tmp volatile to avoid possible GC\n\t  problem.\n\nThu Jul 17 21:30:55 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser#environment): requires shellwords.\n\t  [ruby-dev:35466]\n\nThu Jul 17 02:05:10 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/xmlrpc/client.rb (XMLRPC::Client#do_rpc): requires\n\t  webrick/cookie.  [ ruby-Bugs-21139 ]\n\nThu Jul 17 01:38:31 2008  Yusuke Endoh  <mame@tsg.ne.jp>\n\n\t* ext/zlib/zlib.c (rb_gzfile_set_mtime): fix typo.  [ruby-core:17713]\n\nSun Jul 13 00:08:16 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/ipaddr.rb (IPAddr#initialize): get rid of ArgumentError in\n\t  IPAddr#to_range.  a patch from okkez <okkez000 AT gmail.com> in\n\t  [ruby-dev:35091].\n\nSun Jul 13 00:04:38 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* configure.in (erfc): erfc of glibc comes with Debian GNU/Linux Etch\n\t  on IA64 is broken.  erfc(10000.0) aborts.\n\t  use missing/erf.c instead.\n\t  http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html\n\nThu Jul 10 18:50:48 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* common.mk (SPEC_GIT_BASE): update RubySpec GIT URL.\n\nThu Jul 10 18:46:28 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_extname): fix for file name with spaces.\n\t  [ruby-talk:307404]\n\nThu Jul 10 18:42:37 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb (PercentScanner#scan): fix %% line bug. [ruby-core:17491]\n\n\t* test/erb/test_erb.rb (test_percent): ditto.\n\nThu Jul 10 18:40:22 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/net/ftp.rb (Net::FTP#sendport): use divmod.  [ruby-core:17557]\n\nThu Jul 10 18:36:53 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* ruby.c: Mac OS X needs origargc times of '\\0' in\n\t  origargv. [ruby-dev:35308]\n\nThu Jul 10 13:53:08 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* include/ruby/ruby.h (POSFIXABLE): use FIXNUM_MAX+1 instead of\n\t  FIXNUM_MAX to make it possible to convert to double accurately.\n\t  It assumes FLT_RADIX is 2.\n\t  fix RubyForge bug #14102.\n\t  backported from 1.9.\n\nMon Jul  7 16:21:38 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/net/smtp.rb (Net::SMTP::start): use 'localhost' instead of\n\t  'localhost.localdomain'.  [ruby-dev:35333]\n\n\t* lib/net/smtp.rb (Net::SMTP::SMTP.start): ditto.\n\nMon Jul  7 15:02:13 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_longjmp): duplicate the thrown exception to set backtrace\n\t  if it was frozen.  clear all raised flags.\n\n\t* eval.c (stack_check): leave clearing flag to rb_longjmp.\n\n\t* eval.c (rb_thread_set_raised, rb_thread_reset_raised): use generic\n\t  flags.\n\n\t* eval.c (Init_Proc), gc.c (Init_GC): freeze preallocated special exceptions.\n\n\t* gc.c (rb_memerror): use thread raised flag instead of static flag,\n\t  and raise nomem_error without backtrace if failed to make backtrace.\n\t  [ruby-dev:34724]\n\n\t* gc.c (ruby_xmalloc): increase malloc_increase only if malloc\n\t  succeeds.  failed malloc size can be huge.  it may increase\n\t  malloc_limit too big which cause less GC and memory full.\n\t  (ruby_xrealloc): ditto.\n\nMon Jul  7 12:23:05 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c: avoid creating Ruby object during\n\t  GC. thanks to arton <artonx AT yahoo.co.jp>. [ruby-dev:35313]\n\n\t* ext/win32ole/tests: add test_win32ole_event.rb, remove\n\t  testOLEEVENT.rb\n\n\t* ext/win32ole/tests/testWIN32OLE.rb(test_convert_bignum):\n\t  fix test.\n\nMon Jul  7 12:23:05 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* gc.c: add rb_during_gc(). based on a patch from arton <artonx AT\n\t  yahoo.co.jp> at [ruby-dev:35313].   \n\n\t* intern.h: ditto.\n\nThu Jul  3 20:13:20 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (w_object, marshal_dump, r_object0, marshal_load): search\n\t  public methods only.  [ruby-core:17283]\n\n\t* object.c (convert_type): ditto.\n\n\t* lib/singleton.rb (Singleton#_dump): conversion method should be\n\t  public.\n\nWed Jul  2 19:06:43 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension.read_multipart): blanks inside\n\t  double quotes are allowed.  [ruby-list:45140]\n\nWed Jul  2 19:03:37 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* numeric.c (num_coerce): call rb_Float(x) first.  don't depend on\n\t  evaluation order of function arguments.\n\nWed Jul  2 18:57:19 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syslog/syslog.c (syslog_write): syslog operations should be\n\t  protected from $SAFE level 4.  a patch from Keita Yamaguchi\n\t  <keita.yamaguchi at gmail.com>.\n\n\t* ext/syslog/syslog.c (mSyslog_close): ditto.\n\n\t* ext/syslog/syslog.c (mSyslog_set_mask): ditto.\n\nWed Jul  2 18:26:20 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* math.c (domain_check): fix preprocess condition.\n\nWed Jul  2 18:22:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/tmpdir.rb (@@systmpdir): prior LOCAL_APPDATA if possible, and\n\t  should be clean.  based on a patch from arton <artonx AT\n\t  yahoo.co.jp> at [ruby-dev:35269]\n\nWed Jul  2 18:16:19 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (date2time_str): fix the overflow in\n\t  some situation. [ruby-bugs-20793]\n\nTue Jul  1 15:11:14 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (rb_ary_fill): check if beg is too big.\n\nMon Jun 30 20:35:32 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (str_buf_cat): check for self concatenation.\n\nSun Jun 29 21:39:54 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (rb_obj_respond_to): use RTEST to test the result of\n\t  respond_to? method.\n\nSun Jun 29 21:20:17 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* array.c (rb_ary_fill): (compatibility) do not raise\n\t  ArgumentError on negative length.  This behaviour shall change\n\t  in a future release.\n\nSun Jun 29 20:08:11 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* time.c (time_timeval): fix rounding negative float.\n\nSun Jun 29 19:19:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/inlinetest.rb (InlineTest.in_progname): workaround for frozen\n\t  $0.  [ruby-dev:35261]\n\n\t* lib/test/unit/ui/console/testrunner.rb (TestRunner#finished): ditto.\n\nSun Jun 29 19:19:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ruby.c (set_arg0, ruby_prog_init): freeze $0.  a patch from Keita\n\t  Yamaguchi <keita.yamaguchi at gmail.com>.\n\nSun Jun 29 18:33:33 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* process.c: include sys/resource.h if HAVE_SYS_RESOURCE_H is defined.\n\t  pointed by TOYOFUKU Chikanobu.  [ruby-dev:35258]\n\nSun Jun 29 18:26:01 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_f_trace_var): should not be allowed at safe level 4.  \n\t  a patch from Keita Yamaguchi <keita.yamaguchi at gmail.com>.\n\n\t* eval.c (rb_call0): wrong condition to check insecure method.\n\t  a patch from Keita Yamaguchi <keita.yamaguchi at gmail.com>.\n\nSun Jun 29 18:22:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (rb_ary_fill): not depend on unspecified behavior at integer\n\t  overflow.  reported by Vincenzo Iozzo <snagg AT openssl.it>.\n\nSun Jun 29 18:22:06 2008  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c(ole_invoke): fix memory leak.\n\t  [ruby-bugs-20792]\n\nSun Jun 29 18:19:11 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (PUSH_FRAME, PUSH_CLASS): Add volatile to avoid a\n\t  possible optimization bug on OS X/PPC.  This at least makes\n\t  build with gcc -O1 and `make test' pass.\n\nSun Jun 29 17:24:43 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc#collect_first_comment): skip\n\t  magic comment.\n\nSun Jun 29 17:22:09 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_each, strio_readlines): IO#each and\n\t  IO#readlines do not affect $_.  [ruby-core:17277]\n\nSun Jun 29 17:19:59 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_readline, strio_each)\n\t  (strio_readlines): set lastline.  [ruby-core:17257]\n\nSun Jun 29 17:15:49 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/openssl/ossl.h: include winsock.h if USE_WINSOCK2 is not defined.\n\t  a patch from arton <artonx at yahoo.co.jp> in [ruby-dev:35078]\n\nSun Jun 29 17:09:48 2008  wanabe  <s.wanabe@gmail.com>\n\n\t* util.c (ruby_strtod): ruby_strtod don't allow a trailing\n\t  decimal point like \"7.\". [ruby-dev:34835] [ruby-dev:35009]\n\nSat Jun 28 19:23:40 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* class.c (clone_method): use rb_copy_node_scope.\n\t  fixed [ruby-list:45102]\n\t  fixed [ruby-core:17393]\n\nSat Jun 28 18:49:50 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* class.c: revert to r15855.\n\nFri Jun 20 18:25:18 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_buf_append): should infect.\n\nFri Jun 20 16:33:09 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (rb_ary_store, rb_ary_splice): not depend on unspecified\n\t  behavior at integer overflow.\n\n\t* string.c (str_buf_cat): ditto.\n\nWed Jun 18 22:24:46 2008  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* array.c (ary_new, rb_ary_initialize, rb_ary_store,\n\t  rb_ary_aplice, rb_ary_times): integer overflows should be\n\t  checked. based on patches from Drew Yao <ayao at apple.com>\n\t  fixed CVE-2008-2726\n\n\t* string.c (rb_str_buf_append): fixed unsafe use of alloca,\n\t  which led memory corruption. based on a patch from Drew Yao\n\t  <ayao at apple.com> fixed CVE-2008-2726\n\n\t* sprintf.c (rb_str_format): backported from trunk.\n\n\t* intern.h: ditto.\n\nTue Jun 17 15:09:46 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (file_expand_path): no need to expand root path which has no\n\t  short file name.  [ruby-dev:35095]\n\nSun Jun 15 19:27:40 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in: Fix $LOAD_PATH.  Properly expand vendor_ruby\n\t  directories; submitted by Takahiro Kambe <taca at\n\t  back-street.net> in [ruby-dev:35099].\n\nMon Jun  9 17:56:30 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb (Set#delete_if): Call to_a.\n\t  (SortedSet#delete_if, TC_SortedSet#test_sortedset): Use super to\n\t  yield elements in sorted order; [ruby-core:17144] by Arthur\n\t  Schreiber.\n\t  (SortedSet#each, SortedSet#each, TC_Set#test_each)\n\t  (TC_SortedSet#test_sortedset): Return self; [ruby-dev:35002] by\n\t  Arthur Schreiber.\n\nMon Jun  9 03:28:05 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/zlib/zlib.c (rb_deflate_initialize, Init_zlib): Fix up\n\t  initialize_copy; [ruby-list:45016], [ruby-list:45018].\n\nMon Jun  9 03:26:03 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* NEWS: Mention new constants.\n\nMon Jun  9 03:24:18 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* hash.c (hash_i): make Hash#hash order insensitive.\n\nMon Jun  9 03:22:43 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (VENDOR_DIR): use LIBDIR instead of PREFIX as well as\n\t  SITE_DIR.  a patch from Richard Brown <rbrown AT exherbo.org> in\n\t  [ruby-core:17129].\n\nMon Jun  9 03:21:20 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* gc.c (os_obj_of): assure to not free the scanning heap.\n\nMon Jun  9 03:20:12 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (rb_open_file, rb_io_s_sysopen): fmode should be unsigned int.\n\t  fixed [ruby-dev:34979]\n\nFri Jun  6 21:16:55 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (COMMON_HEADERS): include ws2tcpip.h.\n\n\t* ext/socket/addrinfo.h (addrinfo, getaddrinfo, getnameinfo,\n\t  freehostent, freeaddrinfo): undef before define because these are\n\t  macros in some versions of Windows SDK.\n\n\t* win32/setup.mak: maybe commit miss.\n\nFri Jun  6 19:34:22 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* mkconfig.rb: hide build path from rbconfig.rb.\n\n\t* util.c (ruby_strtod, dtoa): initialize more variables for error\n\t  handling.\n\n\t* io.c (rscheck), marshal.c (w_nbyte, w_bytes, w_unique),\n\t  (path2class, path2module): constified.\n\n\t* pack.c (pack_unpack), process.c (rb_syswait): suppress warnings.\n\n\t* suppress warnings on cygwin, mingw and mswin.\n\nFri Jun  6 19:23:53 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (file_expand_path): fix for non-existent files and SFN of\n\t  symlinks.  [ruby-talk:303736]\n\nFri Jun  6 18:25:43 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/iconv: Tests fixed.\n\nFri Jun  6 17:04:56 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* win32/win32.h: include ws2tcpip.h. fixed [ruby-Bugs-20528]\n\n\t* lib/time.rb (Time.xmlschema): don't use float.  fix\n\t  http://rubyforge.org/tracker/index.php?func=detail&group_id=426&atid=1698&aid=20504\n\n\t* object.c (rb_obj_alloc): RDoc updated.  a patch from Gaston\n\t  Ramos <ramos.gaston at gmail.com> in [ruby-core:17073].\n\n\t* lib/rdoc.rb: massive spelling correction patch from Evan Farrar\n\t  <evanfarrar at gmail.com> in [ruby-doc:1382] applied.\n\n\t* ext/openssl/ossl_ssl_session.c (ossl_ssl_session_initialize):\n\t  Add a null check for ssl; submitted by akira yamada\n\t  in [ruby-dev:34950].\n\n\t* ext/openssl/ossl_ssl.c (Init_ossl_ssl): Define OP_NO_TICKET if\n\t  SSL_OP_NO_TICKET is present; submitted by akira yamada\n\t  in [ruby-dev:34944].\n\n\t* test/openssl/test_ssl.rb (OpenSSL#test_server_session): Add a\n\t  workaround for the case where OpenSSL is configured with\n\t  --enable-tlsext; submitted by akira yamada in [ruby-dev:34944].\n\nFri Jun  6 16:58:23 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_iconv): fix for length argument and now\n\t  allows range.  [ruby-core:17092] [ruby-core:17115]\n\nWed Jun  4 17:22:30 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Fix typos and move misplaced entries.\n\t  NEWS: Somehow optflags and warnflags were not actually included\n\t  in this release.\n\nTue Jun  3 19:33:22 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c (enumerator_init_copy): Take care of\n\t  initialize_copy as well as initialize.\n\n\t* test/ruby/test_enumerator.rb: Pull in the test suite for\n\t  enumerator from trunk.\n\nTue Jun  3 12:51:57 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c (enumerator_allocate, enumerator_ptr): Properly\n\t  detect if the object is initialized and raise error when\n\t  appropriate.\n\t  (enumerator_initialize): Fix a typo in rdoc. [ruby-core:17052]\n\nTue Jun  3 10:16:40 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/erb.rb (ERB::Compiler::TrimScanner#scan_line): Fix a bug\n\t  where tokens are not yilelded one by one.\n\t  (ERB::Compiler::TrimScanner#explicit_trim_line): Fix without-\n\t  strscan problems. [ruby_core:17028].\n\n\t* test/erb/test_erb.rb (TestERBCore#_test_01)\n\t  (TestERBCore#test_02_safe_04): The expected value should come\n\t  first for assert_equal().\n\t  (TestERBCoreWOStrScan): Add test class for without-strscan.\n\nMon Jun  2 19:47:16 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/delegate.rb (DelegateClass, Delegator#respond_to?):\n\t  respond_to? must take optional second argument.  This was a\n\t  latent bug exposed by a recent internal change of marshal.c to\n\t  call respond_to? with a second argument; submitted by Jeremy\n\t  Kemper <jeremy at bitsweat.net> in [ruby-core:17045].\n\nSat May 31 23:53:35 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* .: Release as Ruby 1.8.7.\n\nSat May 31 23:33:34 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* README, README.ja: Add a note about default C flags.\n\nSat May 31 22:11:15 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* version.c (ruby_description, ruby_copyright): backported from\n\t  1.9. bug#19002, [ruby-dev:34883]\n\n\t* error.c (report_bug): uses ruby_description.\n\nSat May 31 20:56:04 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_delete_if): should return enumerator if no block\n\t  is given.  [ruby-dev:34901]\n\nSat May 31 18:28:17 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* suppress warnings with -Wwrite-string.\n\nSat May 31 15:58:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, configure.in (warnflags): defaulted to -Wall\n\t  -Wno-parentheses with gcc.  [ruby-dev:34810]\n\nFri May 30 05:28:18 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* enum.c (count_i, count_iter_i, count_all_i): add prototypes for VC.\n\nFri May 30 04:32:07 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c (count_i, count_iter_i): Sync with trunk.\n\t  enum.c (enum_count, count_all_i, Init_Enumerable),\n\t  array.c (rb_ary_count): Sync with trunk.  If no argument or\n\t  block is given, count the number of all elements.\n\nFri May 30 03:12:18 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/openssl/ossl_bn.c (ossl_bn_s_rand, ossl_bn_s_pseudo_rand):\n\t  Int should be enough here.\n\nFri May 30 02:35:00 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/openssl/ossl_bn.c (ossl_bn_s_rand, ossl_bn_s_pseudo_rand),\n\t  ext/openssl/ossl_pkey_dh.c (ossl_dh_s_generate)\n\t  (ossl_dh_initialize),\n\t  ext/openssl/ossl_pkey_dsa.c (ossl_dsa_s_generate),\n\t  ext/openssl/ossl_rand.c (ossl_rand_bytes)\n\t  (ossl_rand_pseudo_bytes, ossl_rand_egd_bytes),\n\t  ext/openssl/ossl_x509store.c (ossl_x509stctx_set_error): Do not\n\t  use FIX2INT() without checking the value type.  Use NUM2INT()\n\t  instead; found by akr in [ruby-dev:34890].\n\nThu May 29 20:07:45 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in, win32/Makefile.sub, mkconfig.rb, instruby.rb,\n\t  ruby.c, lib/mkmf.rb, README.EXT, README.EXT.ja: Backport the\n\t  vendor_ruby directory support.\n\nThu May 29 17:52:31 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/zlib/extconf.rb: search zlib1, and regard mswin32 later than VC6\n\t  as WIN32.  [ruby-core:16984]\n\nWed May 28 17:54:29 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (rb_str_start_with): Remove an unused variable.\n\t  (rb_str_upto_m): Fix a prototype.\n\nWed May 28 17:48:28 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* range.c (range_step): Fix brokenness when a non-integer numeric\n\t  value is specified as step. [rubyspec]\n\t  (range_step): Make use of String#step internally if a string (or\n\t  string-alike) range is given.\n\n\t* string.c (rb_str_upto_m, Init_String): Add an optional second\n\t  argument to specify if the last value should be included.\n\nWed May 28 16:53:39 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_slice_bang): Call rb_ary_modify_check() at the\n\t  beginning. [rubyspec]\n\nWed May 28 16:12:44 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/webrick/httpservlet/cgihandler.rb (WEBrick::HTTPServlet::CGIHandler#do_GET):\n\t  Set the HTTP status code to 302 if a Location header field is\n\t  present and the status code is not valid as a client\n\t  redirection.  cf. RFC 3875 6.2.3, 6.2.4.\n\nWed May 28 15:18:16 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/singleton.rb (SingletonClassMethods): _load should be public.\n\nWed May 28 12:52:41 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (w_object, marshal_dump, r_object0, marshal_load): search\n\t  private methods too.  [ruby-dev:34671]\n\n\t* object.c (convert_type): ditto.\n\nTue May 27 23:26:49 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_bug): description from rb_bug() should include\n\t  patchlevel.  [ruby-dev:34826]\n\nTue May 27 20:19:22 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_slice_bang): Return an empty array instead of\n\t  nil when pos is valid and len is adjusted from a valid value to\n\t  zero; caught by RubySpec.\n\nTue May 27 19:45:20 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* numeric.c (flo_divmod): Revert the behavior change; do not\n\t  suppress an exception when div is NaN or Inf. [ruby-dev:34857]\n\nTue May 27 19:24:40 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c (enum_to_a): Pass arguments through to #each().\n\t  (enum_sort): Follow the enum_to_a signature change.\n\t  (enum_reverse_each): Add #reverse_each().\n\nTue May 27 18:54:02 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/stringio/stringio.c (strio_each_char, Init_stringio): Add\n\t  StringIO#{each_char,chars}.\n\nTue May 27 17:59:34 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/stringio/stringio.c (strio_each): Return an enumerator if no\n\t  block is given.\n\t  (strio_each_byte): Return an enumerator if no block is given,\n\t  and return self if one is given as the rdoc says.\n\n\t* io.c (rb_io_each_byte): Fix rdoc.  IO#each_byte returns self,\n\t  not nil.\n\nTue May 27 16:02:58 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_mod_module_exec, Init_eval): Add\n\t  Module#{module_exec,class_exec}.\n\nTue May 27 15:36:37 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* io.c (rb_io_each_char, argf_each_char, Init_IO):\n\t  Add {IO#,ARGF.}{each_char,chars}.\n\nTue May 27 13:46:52 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/stringio/stringio.c (Init_stringio): Define\n\t  StringIO#{getbyte,readbyte}.\n\nTue May 27 13:38:51 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* io.c (Init_IO): Define {IO#,ARGF.}{getbyte,readbyte}.\n\nTue May 27 13:26:15 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/stringio/stringio.c (Init_stringio): Define #bytes and\n\t  #lines.\n\nTue May 27 13:20:35 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* io.c: (rb_io_lines, rb_io_bytes, Init_IO): Define\n\t  IO#{lines,bytes} and ARGF.{lines,bytes}.\n\nTue May 27 12:13:17 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (BUFCHECK): wrong condition. [ruby-core:16921]\n\n\t* file.c (file_expand_buf): shouldn't use buflen for length of string.\n\nMon May 26 18:24:48 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (BUFCHECK): no resize if enough room.\n\n\t* file.c (file_expand_path): use BUFCHECK.\n\nMon May 26 16:46:19 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (ntfs_tail): filename which starts with '.' is valid.\n\n\t* file.c (file_expand_path): cygwin symlink support.\n\nMon May 26 12:16:43 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* .: Release as Ruby 1.8.7-preview4.\n\nMon May 26 12:12:26 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* marshal.c (dump_ensure, load_ensure): should return values.\n\n\t* eval.c (yield_under, yield_under_i, yield_args_under_i)\n\t  (specific_eval, rb_obj_instance_exec, Init_eval): Implement\n\t  Object#instance_exec(), a 1.9 feature.\n\nMon May 26 11:53:21 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_yield_0, proc_invoke, proc_arity): allow passing a\n\t  block to a Proc.  [ruby-dev:23533]; by nobu; backported from\n\t  1.9.  This implementation in current shape is known to be\n\t  buggy/broken, especially with nested block invocation.  Take\n\t  this as an experimental feature.\n\n\t* parse.y (block_par, block_var): ditto.\n\nMon May 26 08:00:52 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* marshal.c (r_object0, Init_marshal): Fix the garbled s_call\n\t  definition; fixes [ruby-dev:34843].\n\nMon May 26 03:16:20 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* hash.c (rb_hash_default): Fix rdoc.\n\t  (rb_hash_each, env_each_value, env_each_pair): Return an\n\t  enumerator if no block is given.\n\t  (rb_hash_update): Update rdoc.\n\t  (envix): Conditionalize the definition itself.\n\t  (rb_f_getenv, env_fetch, env_keys, env_values, env_values_at)\n\t  (env_select, env_inspect, env_to_a, env_empty_p, env_has_key)\n\t  (env_has_value, env_index, env_indexes, env_to_hash, env_shift)\n\t  (env_update): Require secure level 4.\n\t  (env_each_value, env_each_i): Delay variable initialization.\n\t  (env_each_key, env_each_value, env_reject_bang)\n\t  (env_clear, env_replace): Omit duplicated secure level check.\n\t  (env_has_value): Do to_str conversion.\n\nSun May 25 19:48:12 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* hash.c (env_delete_if): Return an enumerator if no block is\n\t  given.\n\t  (env_each_key): Delay a variable initialization after\n\t  RETURN_ENUMERATOR().\n\nSun May 25 05:07:19 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_slice_bang): Be consistent with Array#slice()\n\t  and String#slice!().  Just return nil when a negative length or\n\t  out of boundary index is given instead of raising an exception\n\t  via internal functions.\n\t  (rb_ary_slice_bang): should not use rb_ary_subseq() which shares\n\t  internal pointer.  splice modifies the receiver right after\n\t  subseq.  [ruby-dev:34005]\n\t  (rb_ary_slice_bang): should adjust length before making\n\t  sub-array.\n\n\t* enumerator.c (Init_Enumerator): Override\n\t  Enumerable::Enumerator#each_with_index with #with_index.\n\nSun May 25 03:13:09 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (Init_Thread): Initialize recursive_key.\n\nSun May 25 02:45:49 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* error.c (syserr_eqq): Use en.\n\nSat May 24 22:32:49 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_cstr_to_dbl): should clear errno before calling\n\t  strtod(3).  [ruby-dev:34834]\n\nSat May 24 22:27:44 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (marshal_load): should initialize arg.data used for\n\t  reentrant check.  [ruby-dev:34837]\n\nSat May 24 00:34:59 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/rational.rb (Rational#to_i): fix rdoc.  Rational(-7,4).to_i\n\t  should be -1.\n\nFri May 23 20:22:44 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (reentrant_check): check reentrance via callcc.\n\t  [ruby-dev:34802]\n\nFri May 23 16:46:28 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c (proc_call): Remove an unused static function.\n\nFri May 23 13:46:09 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (cflags): commit miss.\n\nFri May 23 09:52:21 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (MINIRUBY), common.mk (RUBYOPT): add purelib.rb.\n\t  [ruby-core:16642]\n\n\t* ext/extmk.rb: load purelib.rb only when not cross compiling.\n\nFri May 23 08:47:02 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (syserr_eqq): === should be able to handle delegated\n\t  objects as well.\n\nFri May 23 04:22:19 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c, ext/tk/tkutil/tkutil.c: fix memory leak.\n\n\t* ext/tk/lib/tk.rb: avoid trouble when finalize TclTkIp.\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tk/*: help to fix troubles when\n\t  use Ttk widgets on old Tk scripts.\n\n\t* ext/tk/sample/*: update and add demo scripts. some of them are\n\t  introduction about new features of Tcl/Tk8.5.\n\nFri May 23 03:48:10 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* class.c (clone_method): Just use ruby_cref as cref.\n\nFri May 23 01:03:23 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* class.c (rb_singleton_class_clone): Pass Qnil, not 0.\n\nFri May 23 00:51:48 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* class.c (clone_method): Totally revamp the previous fix which\n\t  was incorrect.\n\t  (rb_mod_init_copy): Ditto.\n\t  (singleton_class_clone_int): Ditto.\n\nFri May 23 00:48:10 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_copy_node_scope), node.h: Rename from copy_node_scope\n\t  and export.\n\nThu May 22 21:24:15 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (top_local_setup): fixed memory leak bug based on a\n\t  patch from Roger Pack <rogerpack2005 at gmail.com> in\n\t  [ruby-core:16610].\n\nThu May 22 14:20:54 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (flatten): check if reentered.  [ruby-dev:34798]\n\nThu May 22 08:28:49 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (flatten): free memo hash table before raising exception.\n\t  [ruby-dev:34789]\n\nThu May 22 06:30:10 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* array.c (flatten): fix memory leak.\n\nThu May 22 05:45:30 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* proc.c (proc_dup): should copy safe_level from src proc\n\t  properly.  a patch from Keita Yamaguchi\n\t  <keita.yamaguchi at gmail.com>\n\nWed May 21 23:31:44 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_get_method_body, rb_alias, rb_eval): should not cache\n\t  uninitialized value, since search_method doesn't set origin if the\n\t  method wasn't found.\n\n\t* eval.c (search_method, remove_method, error_print, rb_alias)\n\t  (rb_eval, rb_rescue2, search_required, Init_eval, rb_thread_create),\n\t  gc.c (rb_source_filename, Init_stack), io.c (rb_io_getline),\n\t  parse.y (rb_id2name, rb_parser_free): suppress warnings.\n\nWed May 21 12:34:51 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (rb_hash_delete): rdoc fix based on a patch from Gaston Ramos\n\t  <ramos.gaston AT gmail.com>.  [ruby-core:16825]\n\nTue May 20 13:15:46 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* file.c (lchmod_internal): Remove a compiler warning.\n\nMon May 19 18:22:35 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/openssl/ossl_pkcs5.c (ossl_pkcs5_pbkdf2_hmac): Fix the type\n\t  of md; pointed out by Takahiro Kambe <taca at back-street.net>\n\t  in [ruby-dev:34748].\n\nMon May 19 14:20:13 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): fixed SEGV on win32 with \"% 0e\" % 1.0/0.0.\n\nMon May 19 13:29:58 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* process.c (rb_f_system): set last_status when status == -1 because\n\t  there is no path to set it on win32. this patch is derived from\n\t  [ruby-core:16787], submitted by Luis Lavena <luislavena at gmail.com>\n\nMon May 19 13:01:05 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk ({MSPEC,RUBYSPEC}_GIT_URL): moved from Makefine.in.\n\n\t* {win32,bcc32}/Makefile.sub (update-rubyspec): added.\n\nMon May 19 11:53:45 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/openssl/openssl_missing.c (HMAC_CTX_copy): adopted\n\t  prototype change in openssl bundled with newer OpenBSD.\n\t  a patch from Takahiro Kambe <taca at back-street.net> in\n\t  [ruby-dev:34691].\n\nMon May 19 06:36:37 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* .: Release as Ruby 1.8.7-preview3.\n\nSun May 18 22:26:51 2008  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpservlet/filehandler.rb: should normalize path\n\t  name in path_info to prevent script disclosure vulnerability on\n\t  DOSISH filesystems. (fix: CVE-2008-1891)\n\t  Note: NTFS/FAT filesystem should not be published by the platforms\n\t  other than Windows. Pathname interpretation (including short\n\t  filename) is less than perfect.\n\n\t* lib/webrick/httpservlet/abstract.rb\n\t  (WEBrick::HTTPServlet::AbstracServlet#redirect_to_directory_uri):\n\t  should escape the value of Location: header.\n\n\t* lib/webrick/httpservlet/cgi_runner.rb: accept interpreter\n\t  command line arguments.\n\nSat May 17 23:53:57 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (file_expand_path): fix for short file name on Cygwin.\n\nSat May 17 11:29:11 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_extname): first dot is not an extension name.\n\nSat May 17 10:18:44 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_search): need to free allocated buffer in re_register.\n\nFri May 16 17:01:44 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (test-rubyspec): added.\n\nFri May 16 16:22:40 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c: sometimes freeze when receive Interrupt signal.\n\nFri May 16 14:54:56 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* Makefile.in (update-rubyspec): move rubyspec to srcdir. \n\t  (test-rubyspec): ditto.\n\nFri May 16 14:25:22 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* Makefile.in (test-rubyspec): use RUNRUBY.  suggested by nobu.\n\nFri May 16 13:01:43 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* Makefile.in (update-rubyspec): new target to download rubyspec.\n\t  (test-rubyspec): new target to run rubyspec.  this doesn't work\n\t  before install.\n\nFri May 16 08:15:52 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: fix memory (object) leak bug.\n\n\t* ext/tk/sample/demos-jp/aniwave.rb, ext/tk/sample/demos-en/aniwave.rb:\n\t  bug fix.\n\nThu May 15 17:00:22 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (Init_String): Define #bytesize as an alias for #size\n\t  for compatibility with 1.9.\n\nThu May 15 15:33:59 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (file_expand_path): support for alternative data stream\n\t  and ignored trailing garbages of NTFS.\n\n\t* file.c (rb_file_s_basename): ditto.\n\n\t* file.c (rb_file_s_extname): ditto.\n\nWed May 14 19:24:59 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_count): Override Enumerable#count for better\n\t  performance.\n\t  (rb_ary_nitems): Undo the backport.  Use #count {} instead.\n\n\t* enumerator.c (enumerator_iter_i): Remove an unused function.\n\t  (enumerator_with_index, enumerator_each): Remove unused\n\t  variables.\n\nWed May 14 17:15:11 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/tk/tkutil/extronf.rb: check stdndup() because it's not standard\n\t  function of C.\n\n\t* ext/tk/tkutil/tkutil.c (cbsubst_table_setup): use malloc() and\n\t  strncpy() instead of strndup() if not available.\n\nWed May 14 09:52:02 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil/tkutil.c: improve handling callback-subst-keys. \n\t  Now, support longnam-keys (e.g. '%CTT' on tkdnd-2.0; however, still\n\t  not support tkdnd-2.0 on tkextlib), and symbols of parameters (e.g. \n\t  :widget=>'%W', :keycode=>'%k', '%x'=>:x, '%X'=>:root_x, and so on; \n\t  those are attributes of event object). It means that Ruby/Tk accepts\n\t  not only \"widget.bind(ev, '%W', '%k', ...){|w, k, ...| ... }\", but \n\t  also \"widget.bind(ev, :widget, :keycode, ...){|w, k, ...| ... }\". \n\t  It is potentially incompatible, when user passes symbols to the\n\t  arguments of the callback block (the block receives the symbols as\n\t  strings). I think that is very rare case (probably, used by Ruby/Tk\n\t  experts only). When causes such trouble, please give strings instead\n\t  of such symbol parameters (e.g. call Symbol#to_s method).\n\n\t* ext/tk/lib/tk/event.rb, ext/tk/lib/tk/validation.rb, \n\t  ext/tk/lib/tkextlib/blt/treeview.rb, \n\t  ext/tk/lib/tkextlib/winico/winico.rb: ditto.\n\n\t* ext/tk/tkutil/tkutil.c: strings are available on subst_tables on \n\t  TkUtil::CallbackSubst class (it is useful on Ruby 1.9). \n\n\t* ext/tk/lib/tk/spinbox.rb, ext/tk/lib/tkextlib/iwidgets/hierarchy.rb, \n\t  ext/tk/lib/tkextlib/iwidgets/spinner.rb, \n\t  ext/tk/lib/tkextlib/iwidgets/entryfield.rb, \n\t  ext/tk/lib/tkextlib/iwidgets/calendar.rb, \n\t  ext/tk/lib/tkextlib/blt/dragdrop.rb, \n\t  ext/tk/lib/tkextlib/tkDND/tkdnd.rb, \n\t  ext/tk/lib/tkextlib/treectrl/tktreectrl.rb, \n\t  ext/tk/lib/tkextlib/tktable/tktable.rb: disable code piece became \n\t  unnecessary by reason of the changes of ext/tk/tkutil/tkutil.c.\n\nTue May 13 15:10:50 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c: Update rdoc.\n\t  (enumerator_initialize): Discourage the use.\n\t  (enum_each_slice, enum_each_cons, enumerator_each)\n\t  (enumerator_with_index): Add a note about a call without a block.\n\n\t* NEWS: Intentionally omit enum_slice and enum_cons, which are\n\t  removed in 1.9.\n\nTue May 13 07:56:36 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cat): fixed buffer overrun reported by\n\t  Christopher Thompson <cthompson at nexopia.com> in [ruby-core:16746]\n\nMon May 12 13:57:19 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): add NODE_OP_ASGN_{OR,AND}.  \"defined?(a||=1)\"\n\t  should not operate assignment.  [ruby-dev:34645]\n\nMon May 12 12:59:23 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/wm.rb: Wm#overrideredirect overwrites arguemnt to\n\t  an invalid value.\n\n\t* ext/tk/sample/ttk_wrapper.rb: support \"if __FILE__ == $0\" idiom.\n\nMon May 12 12:36:55 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_select): backport from trunk.\n\t  [ruby-talk:300743]\n\nMon May 12 12:33:21 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (RUBYLIB, RUBYOPT): clear.\n\nMon May 12 10:41:10 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/delegate.rb (SimpleDelegator::dup): removed needless argument.\n\t  [ruby-list:44910]\n\n\t* lib/delegate.rb (clone, dup): keep relationship with the target\n\t  object.\n\nSun May 11 23:19:39 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (all_iter_i, any_iter_i): reduced duplicated code.\n\nSun May 11 17:57:36 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (MINIRUBY): should not include extension library path.\n\nSun May 11 10:36:10 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* eval.c (method_name, method_owner): New methods; backported\n\t  from 1.9. (UnboundMethod#name, UnboundMethod#owner)\n\nSun May 11 02:48:13 2008    <nagai@orca16.orcabay.ddo.jp>\n\n\t* ext/tk/lib/tk/pack.rb, ext/tk/lib/tk/grid.rb: fail to do pack/grid \n\t  without options.\n\n\t* ext/tk/lib/tk.rb: add TkWindow#grid_anchor, grid_column, grid_row.\n\nSat May 10 18:19:16 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_each_line): RDoc updated.  [ruby-dev:34586]\n\nSat May 10 13:17:56 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/pack.rb, ext/tk/lib/tk/grid.rb: increase supported\n\t  parameter patterns of configure method.\n\nSat May 10 09:16:13 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): backported from 1.9.  a patch from Satoshi\n\t  Nakagawa <psychs at limechat.net> in [ruby-dev:34625]. \n\t  fixed: [ruby-dev:34623]\n\nFri May  9 23:33:25 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/wm.rb: methods of Tk::Wm_for_General module cannot\n\t  pass the given block to methods of Tk::Wm module.\n\n\t* ext/tk/lib/tk/grid.rb: lack of module-method definitions.\n\n\t* ext/tk/lib/tkextlib/tile.rb: lack of autoload definitions.\n\n\t* ext/tk/lib/tkextlib/tile/tnotebook.rb: cannot use kanji (not UTF-8) \n\t  characters for headings.\n\n\t* ext/tk/tcltklib.c: maybe a little more stable about @encoding value \n\t  of TclTkIp object.\n\nWed May  7 08:46:44 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (rb_struct_s_def): to_str should be called only once.\n\t  [ruby-core:16647]\n\nWed May  7 00:54:25 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (gzreader_gets): may cause infinite loop.\n\t  a patch from Kouya <kouyataifu4 at gmail.com> in\n\t  [ruby-reference-manual:762].\n\nSun May  4 09:35:51 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* sample/erb/erb4html.rb (ERB4Html) : add example of ERB#set_eoutvar.\n\t  ERB4Html is an auto-quote ERB.\n\nSat May  3 22:52:48 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/tile.rb, ext/tk/lib/tkextlib/tile/style.rb, \n\t  ext/tk/sample/ttk_wrapper.rb: improve treating and control themes. \n\t  add Tk::Tile.themes and Tk::Tile.set_theme(theme).\n\nFri May  2 14:52:33 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el: move fontifying code from hook.  a patch from\n\t  Phil Hagelberg <phil at hagelb.org> in [ruby-core:16636].\n\nFri May  2 13:47:51 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (match_select): restore previous behavior of MatchData#select.\n\t  RDoc updated as well, mentioning the plan to remove this method\n\t  in the future.  [ruby-dev:34556]\n\nFri May  2 13:04:04 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dbm/dbm.c (Init_dbm): defines DBM::VERSION even when\n\t  DB_VERSION_STRING is not available.  [ruby-dev:34569]\n\nThu May  1 23:57:06 2008  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 16257 from trunk.\n\n\t* lib/net/telnet.rb:  This patch from Brian Candler adds a FailEOF mode which\n\t  can be activated to have net/telnet raise EOFError exceptions when the \n\t  remote connection is closed.  The default behavior remains unchanged though.\n\nThu May  1 23:43:21 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* range.c (range_step): check if step can be converted to an integer.\n\t  [ruby-dev:34558]\n\n\t* range.c (range_step): allow float step bigger than zero but less\n\t  than one.  [ruby-dev:34557]\n\nWed Apr 30 20:22:40 2008  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 16241 from trunk.\n\n\t* lib/net/telnet.rb:  Fixing a bug where line endings would not be properly\n\t  escaped when the two character ending was broken up into separate TCP\n\t  packets.  Issue reported and patched by Brian Candler.\n\nWed Apr 30 17:47:21 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* re.c (rb_reg_search): use local variable.  a patch from wanabe\n\t  <s.wanabe AT gmail.com> in [ruby-dev:34537].  [ruby-dev:34492]\n\nSat Apr 26 19:40:34 2008  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* class.c (struct clone_method_data): Add cref.\n\t  (clone_method): Properly handle NODE_BMETHOD and NODE_DMETHOD.\n\t  (rb_singleton_class_clone, singleton_class_clone_int): Set a\n\t  proper value to klass and propagate cref. [ruby-core:16238]\n\n\t* eval.c (rb_block_dup, rb_method_dup), intern.h: Add duplicator\n\t  methods for use from class.c#clone_method().\n\nFri Apr 25 15:46:37 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tk/scrollbar.rb, ext/tk/lib/tk/scale.rb:\n\t  improve unknonw-option check when create a widget. \n\n\t* ext/tk/lib/tkextlib/blt/unix_dnd.rb, ext/tk/lib/tkextlib/blt/ted.rb,\n\t  ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix on 'cget'.\n\n\t* ext/tk/lib/tk/menuspec.rb: option check will fail when \n\t  TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ is true.\n\n\t* ext/tk/lib/tk/palette.rb: bug fix.\n\nFri Apr 25 12:37:54 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (flatten): returns an instance of same class.\n\t  [ruby-core:16554]\n\nThu Apr 24 23:47:50 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/net/pop.rb: backported from 1.9. bug#19003\n\n\t* ext/openssl/lib/openssl/ssl.rb: set_params; backported from 1.9.\n\t  bug#19552, [ruby-dev:34402]\n\n\t* ext/openssl/ossl_ssl.c: ditto.\n\n\t* test/openssl/test_ssl.rb: ditto.\n\nThu Apr 24 17:06:34 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (THREAD_SAVE_CONTEXT): remove unnecessary\n\t  FLUSH_REGISTER_WINDOWS before calling setjmp().  [ruby-core:16285]\n\nThu Apr 24 14:15:11 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dln.c (dln_find_1): prior files with extensions to files sans\n\t  extensions.  [ruby-core:16517]\n\nWed Apr 23 15:39:31 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (bind_eval): Add Binding#eval, a shorthand method for\n\t  eval(str, binding, ..); backported from 1.9.\n\nWed Apr 23 15:28:52 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* test/gdbm/test_gdbm.rb (TestGDBM#test_s_open_no_create): failed\n\t  notice moved from comment to assertion message. [ruby-dev:29127]\n\nWed Apr 23 14:00:05 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb (create_makefile): Add a missing dependency on the\n\t  target directory for each .rb file.  This will hopefully fix\n\t  parallel make (-jN).  Tested on FreeBSD.\n\nWed Apr 23 11:49:54 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb (Set#each, SortedSet#each, TC_Set#test_each): Return\n\t  an enumerator if no block is given.\n\nWed Apr 23 00:42:49 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* eval.c (error_print): show full stack grace except SystemStackError.\n\t  backport from 1.9.  [ruby-dev:31014]\n\nWed Apr 23 00:18:45 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* test/ruby/test_symbol.rb (TestSymbol#test_to_proc): Improve\n\t  tests of Symbol#to_proc.\n\nTue Apr 22 22:43:05 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_proc_new, YIELD_FUNC_LAMBDA): Add a new nd_state\n\t  YIELD_FUNC_LAMBDA which avoids automatic `avalue' conversion for\n\t  arguments.  This fixes a bug where [1,[2,3]].map(&:object_id)\n\t  fails.\n\n\t* intern.h, object.c: Hide rb_proc_new() from intern.h.  It should\n\t  not be considered an official API function yet.\n\nTue Apr 22 21:24:32 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_proc_new): Turn the BLOCK_LAMBDA flag on.\n\n\t* object.c (sym_to_proc), test/ruby/test_symbol.rb: Add back\n\t  Symbol#to_proc, now that it passes the tests.\n\nTue Apr 22 19:35:03 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c (enumerator_initialize): Remove an undocumented\n\t  feature (passing a block to the constructor) that's broken.\n\t  This is not what I intended.\n\nTue Apr 22 17:49:46 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): should protect temporary string from\n\t  GC.   [ruby-dev:34480]\n\nTue Apr 22 17:12:05 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_search): string might be NULL.  [ruby-core:16478]\n\nTue Apr 22 16:44:00 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* object.c (rb_obj_tap): Correct documentation; pointed out by\n\t  okkez in [ruby-dev:34472].\n\nTue Apr 22 10:05:51 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (eaccess): workaround for recent msvcrt's behavior.\n\t  [ruby-core:16460]\n\nMon Apr 21 16:06:47 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enumerator.c (enumerator_init): preserve the method name in ID.\n\n\t* enumerator.c (enumerator_each): need not to call rb_to_id().\n\n\t* enumerator.c (enumerator_with_index): ditto.\n\nMon Apr 21 17:19:52 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_f_method_name): New gloval function: __method__;\n\t  backported from matzruby / 1.9.\n\n\t* eval.c (rb_frame_this_func), intern.h: New internal function.\n\n\t* intern.h (RETURN_ENUMERATOR): Use rb_frame_this_func() instead\n\t  of rb_frame_last_func(), to accommodate the behavior to that of\n\t  1.9.\n\nMon Apr 21 15:54:48 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tempfile.rb (Tempfile::_close): check @data before modifying\n\t  it; backported from 1.9.  [ruby-dev:34094]\n\n\t* lib/tempfile.rb (Tempfile::close): clear @data and @tmpname.\n\nMon Apr 21 10:17:17 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* time.c: should include <errno.h> to refer errno.\n\nMon Apr 21 10:02:43 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* hash.c (recursive_hash): prototype.\n\nMon Apr 21 10:00:51 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* time.c (rb_strftime): check errno to detect strftime(3)'s error.\n\t  this is workaround for recent version of MSVCRT.\n\t  [ruby-dev:34456]\n\nSun Apr 20 21:10:04 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* .: Release as Ruby 1.8.7-preview2.\n\nSun Apr 20 21:02:06 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c: Resolve the method every time an enumeration\n\t  method is run, not once when the enumerator is initialized as it\n\t  was before, so that method_missing() and method (re)definition\n\t  afterwards are both in effect; pointed out in: [ruby-core:16441]\n\nSun Apr 20 17:59:25 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* object.c, NEWS, test/ruby/test_symbol.rb: Revert Symbol#to_proc\n\t  since it does not pass the tests.\n\nSun Apr 20 14:29:35 2008  Technorama Ltd.  <oss-ruby@technorama.net>\n\n\t* ext/openssl/ossl_ssl.c: initialize session class.\n\nSat Apr 19 20:54:42 2008  akira yamada  <akira@arika.org>\n\n\t* lib/uri/ftp.rb, lib/uri/generic.rb, test/uri/test_common.rb,\n\t  test/uri/test_ftp.rb, test/uri/test_generic.rb: backported from 1.9.\n\t  [ruby-dev:31318]\n\nSat Apr 19 20:35:02 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/yaml/baseemitter.rb, lib/yaml/encoding.rb: performance\n\t  tuning around String#gsub.\n\n\t* lib/yaml/tag.rb: Replace nodoc with stopdoc so Module methods get\n\t  documented.\n\n\t* lib/yaml/store.rb (YAML::load): modified to support empty\n\t  database.\n\n\t* lib/yaml/store.rb (YAML::Store::marshal_dump_supports_canonical_option?):\n\t  add a method to support faster PStore.\n\nSat Apr 19 20:16:52 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/yaml/types.rb: Likewise, pass self to YAML::quick_emit;\n\t  merged from 1.9.\n\n\t* lib/yaml.rb (quick_emit): use combination of object_id and hash to\n\t  identify repeated object references, since GC will reuse memory of\n\t  objects during output of YAML. [ruby-Bugs-8548] [ruby-Bugs-3698];\n\t  merged from 1.9.\n\nSat Apr 19 20:05:39 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_equal, rb_ary_eql, rb_ary_hash, rb_ary_cmp):\n\t  Make Array#eql?, #hash, #== and #<=> use rb_exec_recursive() and\n\t  handle recursive data properly.\n\n\t* hash.c (hash_equal, rb_hash_hash): Make Hash#eql?, #hash and #==\n\t  use rb_exec_recursive() and handle recursive data properly.\n\nSat Apr 19 19:26:09 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* intern.h, eval.c (rb_exec_recursive): New internal function to\n\t  help perform recursive operation; backported from 1.9.\n\nSat Apr 19 18:42:04 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* intern.h, hash.c (rb_hash_lookup): New internal function to\n\t  check if a key exists in a hash, ignoring #default; backported\n\t  from 1.9.\n\nFri Apr 18 18:56:57 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syck/rubyext.c (syck_genericresolver_node_import): should\n\t  not set instance variable \"@kind\" before initializing it.\n\t  [ruby-dev:32677]\n\n\t* ext/syck/rubyext.c (syck_resolver_initialize,\n\t  syck_resolver_detect_implicit, syck_emitter_emit): remove unused\n\t  variables.\n\nFri Apr 18 18:54:57 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syck/rubyext.c: Node#value defined twice.\n\n\t* lib/yaml/: several method redefinitions causing warnings.\n\nFri Apr 18 16:36:16 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/rexml/node.rb (REXML::Node::indent): should initialize rv\n\t  variable.  a patch from Tadayoshi Funaba <tadf AT dotrb.org> in \n\t  [ruby-dev:32783].\n\nFri Apr 18 16:01:37 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/rexml: Merge fixes since 1.8.6 made solely on the ruby_1_8_6\n\t  branch.\n\nWed Apr 16 06:11:49 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* test/ruby/test_settracefunc.rb (TestSetTraceFunc#test_event):\n\t  Fix tests to reflect the following changes: r15833, r15759.\n\nWed Apr 16 05:03:48 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* .: Release as Ruby 1.8.7-preview1.\n\nWed Apr 16 02:09:14 2008  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/xmlrpc/client.rb: fix cookie handling. [ruby-dev:34403]\n\n\t* test/xmlrpc/test_cookie.rb: add a test for the above fix.\n\nTue Apr 15 23:48:28 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* version.h: Branch off ruby_1_8_7 from ruby_1_8 in preparation\n\t  for the forthcoming 1.8.7 release.\n\nTue Apr 15 23:40:39 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syck/rubyext.c (rb_syck_mktime): Avoid buffer overflow.\n\nTue Apr 15 20:32:03 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* re.c (match_inspect): backported from 1.9.\n\nTue Apr 15 19:03:28 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* eval.c (method_receiver, method_name, method_owner): New\n\t  methods; backported from 1.9. bug#19007\n\nTue Apr 15 18:39:14 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/uri.rb, lib/uri/ldaps.rb: added LDAPS\n\t  scheme; backported from 1.9. bug#19015, [ruby-dev:31896]\n\nTue Apr 15 17:45:43 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/net/smtp.rb: backported from 1.9. bug#19003\n\nTue Apr 15 17:06:12 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* test/ruby/test_symbol.rb (TestSymbol#test_to_proc): add tests.\n\nTue Apr 15 16:58:55 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/menuspec.rb: option check will fail when \n\t  TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ is true.\n\n\t* ext/tk/lib/tk/palette.rb: bug fix.\n\nTue Apr 15 16:47:48 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* signal.c, gc.c: New methods: GC.stress, GC.stress=;\n\t  backported from 1.9. a patch from Tadashi Saito\n\t  in [ruby-dev:34394] and bug#19000\n\nTue Apr 15 12:35:44 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* rubyio.h (rb_io_t): renamed from OpenFile.\n\n\t* ruby.h (struct RHash), file.c, gc.c, io.c, ext/dl/dl.c,\n\t  ext/io/wait/wait.c, ext/pty/pty.c, ext/readline/readline.c,\n\t  ext/socket/socket.c: ditto.\n\n\t* win32/win32.h: removed workaround for OpenFile.\n\nTue Apr 15 00:15:29 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/text.rb: typo. call a wrong method.\n\n\t* ext/tk/lib/tk/itemconfig.rb: ditto.\n\n\t* ext/tk/sample/ttk_wrapper.rb: bug fix.\n\n\t* ext/tk/sample/tktextio.rb: add binding for 'Ctrl-u' at console mode.\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tk/itemfont.rb, ext/tk/lib/font.rb: \n\t  support __IGNORE_UNKNOWN_CONFIGURE_OPTION__ about font options.\n\n\t* ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb, \n\t  ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb, \n\t  ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb: bug fix. \n\n\t* ext/tk/lib/tkextlib/tile/tpaned.rb: improve TPaned#add.\n\n\t* ext/tk/lib/tk/timer.rb: add TkTimer#at_end(proc) to register the \n\t  procedure which called at end of the timer.\n\nMon Apr 14 19:54:21 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_flatten, rb_ary_flatten_bang): Take an optional\n\t  argument that determines the level of recursion to flatten;\n\t  backported from 1.9.\n\n\t* array.c (rb_ary_shuffle_bang, rb_ary_shuffle, rb_ary_choice,\n\t  rb_ary_cycle, rb_ary_permutation, rb_ary_combination,\n\t  rb_ary_product, rb_ary_take, rb_ary_take_while, rb_ary_drop,\n\t  rb_ary_drop_while): New methods: Array#shuffle, #shuffle!,\n\t  #choice, #cycle, #permutation, #combination, #product, #take,\n\t  #take_while, #drop, #drop_while; backported from 1.9.\n\nMon Apr 14 19:52:35 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.h: New macro: RB_GC_GUARD().\n\nMon Apr 14 19:49:35 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* random.c (rb_genrand_int32, rb_genrand_real), intern.h: Export.\n\n\t* string.c (rb_str_tmp_new), intern.h: New function.\n\nMon Apr 14 19:18:55 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* enum.c (inject_i, inject_op_i): prototype.\n\nMon Apr 14 19:10:47 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c New methods: Enumerable#take, #take_while, #drop and\n\t  #drop_while; backported from 1.9.\n\nMon Apr 14 18:50:15 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c: New methods: Enumerable#one?, #none?, #minmax, #min_by,\n\t  #max_by, #minmax_by and #cycle; backported from 1.9.\n\n\t* enum.c (enum_find_index): Add support for find_index(obj);\n\t  [ruby-dev:34313]; backported from 1.9.\n\n\t* enum.c (enum_inject): Add support for Enumerable#inject(:binop);\n\t  backported from 1.9.\n\n\t* enum.c: Alias Enumerable#reject to #inject; backported from 1.9.\n\nMon Apr 14 18:14:19 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c (enum_find, enum_reject): Return an enumerator if no\n\t  block is given; backported from 1.9.\n\n\t* io.c (rb_io_each_line, rb_io_each_byte, rb_io_s_foreach,\n\t  argf_each_line, argf_each_byte): Ditto.\n\n\t* string.c (str_gsub): Ditto.\n\nMon Apr 14 18:10:05 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* enum.c (find_index_i, find_index_iter_i): add prototype for VC.\n\nMon Apr 14 17:55:30 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_collect_bang, rb_ary_select): Return an\n\t  enumerator if no block is given; backported from 1.9.\n\n\t* dir.c (dir_each, dir_foreach): Ditto.\n\n\t* enum.c (enum_partition, enum_sort_by): Ditto.\n\n\t* gc.c (os_each_obj): Ditto.\n\n\t* hash.c (rb_hash_delete_if, rb_hash_reject_bang, rb_hash_select,\n\t  rb_hash_each_value, rb_hash_each_key, rb_hash_each_pair,\n\t  env_each_key, env_each_value, env_each, env_each_pair,\n\t  env_reject_bang, env_delete_if, env_select): Ditto.\n\n\t* numeric.c (num_step, int_upto, int_downto, int_dotimes): Ditto.\n\nMon Apr 14 16:42:53 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.h (rb_block_call_func): Fix prototype.\n\n\t* enumerator.c (enumerator_iter_i, enumerator_each_i): Ditto.\n\nMon Apr 14 15:49:05 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c (enum_count, enum_find_index): New methods:\n\t  Enumerable#count and #find_index; backported from 1.9.\n\nMon Apr 14 14:16:08 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* enumerator.c (enumerator_mark, enumerator_iter_i, enumerator_each_i,\n\t  enumerator_allocate): add prototype.\n\n\t* enumerator.c (enumerator_each_i): declare unused two arguments.\n\nMon Apr 14 13:58:32 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (rb_str_each_char): New methods: String#chars and\n\t  #each_char; backported from 1.9.\n\nMon Apr 14 13:42:20 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (rb_str_each_line, rb_str_each_byte): Reflect\n\t  enumerator integration.  #lines and #bytes are now aliases to\n\t  #each_line and #each_byte, respectively.\n\nMon Apr 14 13:19:36 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* range.c (range_each, range_step): Return an enumerator if no\n\t  block is given; backported from 1.9.\n\n\t* struct.c (rb_struct_each, rb_struct_each_pair): Ditto.\n\nMon Apr 14 13:07:59 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (rb_str_partition, rb_str_rpartition,\n\t  rb_str_start_with, rb_str_end_with): New methods:\n\t  String#partition, #rpartition, #start_with? and #end_with?;\n\t  backported from 1.9.  These methods are $KCODE aware unlike\n\t  #index, #rindex and #include?.\n\nSun Apr 13 15:55:52 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* object.c (sym_to_proc): new method Symbol#to_proc; backported\n\t  from 1.9. bug#19012\n\nFri Apr 11 19:14:30 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* object.c (rb_obj_tap): new method Object#tap; backported from\n\t  1.9. bug#19008\n\nFri Apr 11 18:58:09 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* process.c: new method Process.exec; backported from 1.9. bug#19006\n\nFri Apr 11 12:43:56 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/tile.rb, ext/tk/lib/tkextlib/tile/style.rb, \n\t  ext/tk/sample/tkextlib/tile/demo.rb: previous patch is not complete.\n\nFri Apr 11 10:22:54 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/tile.rb:\n\t  __define_LoadImages_proc_for_compatibility__! do nothing when the \n\t  Tcl command exists.\n\n\t* ext/tk/lib/tkextlib/tile/style.rb:\n\t  __define_wrapper_proc_for_compatibility__! do nothing when the Tcl\n\t  command exists.\n\n\t* ext/tk/sample/tkextlib/tile/demo.rb: don't create 'step' theme if \n\t  it already exists.\n\nFri Apr 11 08:05:12 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): add volatile to avoid potential GC bug.  a\n\t  patch from Tomoyuki Chikanaga <chikanag at nippon-control-system.co.jp>\n\t  in [ruby-dev:34311].\n\nThu Apr 10 20:29:13 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* misc/rdebug.el, misc/README: Remove rdebug.el as per request\n\t  from the maintainer and mention the ruby-debug project at\n\t  RubyForge in README; bug#19043.\n\nThu Apr 10 20:08:37 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enum.c (enum_first, enum_group_by): New methods:\n\t  Enumerable#first and #group_by; backported from 1.9.\n\nThu Apr 10 19:49:10 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c (rb_eStopIteration), eval.c (rb_f_loop), ruby.h:\n\t  Add a new exception class StopIteration, which breaks Kernel#loop\n\t  iteration when raised; backported from 1.9.\n\n\t* enumerator.c (enumerator_next, enumerator_rewind): Implement\n\t  #next and #rewind using the \"generator\" library.\n\n\t* lib/generator.rb: Implement Enumerable::Enumerator#next and\n\t  #rewind.\n\nThu Apr 10 19:29:48 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_first, rb_ary_last): Return a shared array when\n\t  possible.\n\n\t* array.c (rb_ary_pop, rb_ary_pop_m, rb_ary_shift, rb_ary_shift_m):\n\t  Array#pop and Array#shift can take an optional argument\n\t  specifying the number of elements to remove and return;\n\t  backported from 1.9.\n\nThu Apr 10 14:00:44 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/resolv.rb (Resolv::DNS#each_address): backport from 1.9 for\n\t  CNAME.  [ruby-dev:34200]\n\nThu Apr 10 01:42:25 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* enum.c (iterate_method): add prototype to avoid warning on VC++.\n\nWed Apr  9 23:12:41 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c: SEGV when tcltk-stubs is enabled.\n\n\t* ext/tk/tcltklib.c: avoid error on a shared object.\n\n\t* ext/tk/extconf.rb: support --with-tcltkversion\n\n\t* ext/tk/README.tcltklib: add document about --with-tcltkversion\n\n\t* ext/tk/sample/demos-jp/widget, ext/tk/sample/demos-en/widget, \n\t  ext/tk/sample/demos-jp/style.rb, ext/tk/sample/demos-en/style.rb, \n\t  ext/tk/sample/demos-jp/bind.rb, ext/tk/sample/demos-en/bind.rb: \n\t  bug fix.\n\nWed Apr  9 21:54:45 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_pop): Do not reallocate too often; backported\n\t  from 1.9.\n\nWed Apr  9 21:13:05 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_each, rb_ary_each_index, rb_ary_reverse_each,\n\t  rb_ary_reject, rb_ary_reject_bang): Array#each, #each_index,\n\t  #reverse_each, #reject, #reject! and #delete_if return an\n\t  enumerator if no block is given; backported from 1.9.\n\nWed Apr  9 20:47:16 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_index, rb_ary_index): Array#index and #rindex\n\t  can take a block instead of an argument; backported from 1.9.\n\nWed Apr  9 19:58:31 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* enumerator.c, inits.c (rb_call_inits), ruby.h, intern.h,\n\t  ext/enumerator, common.mk (OBJS, enumerator.$(OBJEXT)): Make the\n\t  enumerator module built-in.\n\n\t* enumerator.c: New method: Enumerable::Enumerator#with_index.\n\n\t* enum.c (enum_each_with_index): Enumerable#each_with_index now\n\t  returns an enumerator instead of raising an exception if no\n\t  block is given.  Enumerable#enum_with_index, formerly defined in\n\t  the enumerator module, is kept as an alias to each_with_index\n\t  for backward compatibility.\n\nWed Apr  9 19:43:51 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_obj_method, rb_proc_call), intern.h: Export.\n\nTue Apr  8 11:11:28 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (EXEC_TAG): remove unnecessary FLUSH_REGISTER_WINDOWS for\n\t  better performance on SPARC.  [ruby-core:16159]\n\nTue Apr  8 10:49:54 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_quote): should always copy the quoting string.\n\t  [ruby-core:16235]\n\nMon Apr  7 21:35:08 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_nitems): Backport Array#nitems with a block;\n\t  suggested by Bertram Scharpf <lists@bertram-scharpf.de> in\n\t  [ruby-talk:134083].\n\nSun Apr  6 09:45:00 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (dir_tell): check if closed.  [ruby-core:16223]\n\nSat Apr  5 10:05:00 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (rb_check_to_integer): backported for range_step.\n\nFri Apr  4 05:57:11 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/net/pop.rb (Net::POP3::do_finish): clear @n_mails and\n\t  @n_bytes as well.  [ruby-core:16144]\n\nFri Apr  4 02:17:06 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_step): should not round step into integer if\n\t  begin and end are numeric.  [ruby-core:15990]\n\nTue Apr  1 14:43:38 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: get rid of empty expansion.\n\n\t* {bcc,win}32/Makefile (config.h): need to define RUBY_SETJMP, etc.\n\nTue Apr  1 11:36:19 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: _setjmp is available but _longjmp is not on mingw.\n\nTue Apr  1 03:20:40 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_SETJMP, RUBY_LONGJMP, RUBY_JMP_BUF): prefers\n\t  _setjmp over setjmp and sigsetjmp.  [ruby-core:16023]\n\t  __builtin_setjmp cannot handle a variable.\n\n\t* configure.in (--with-setjmp-type): new option to override the\n\t  default rule in the above.\n\n\t* eval_intern.h (ruby_setjmp, ruby_longjmp), gc.c (rb_setjmp),\n\t  vm_core.h (rb_jmpbuf_t): use RUBY_SETJMP, RUBY_LONGJMP and\n\t  RUBY_JMP_BUF.\n\nTue Apr  1 01:55:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/resolv.rb (Resolv::Config.default_config_hash): requires\n\t  win32/resolv to use Win32::Resolv.  [ruby-dev:34138]\n\nMon Mar 31 14:51:11 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_div): Bignum#div should return integer for\n\t  floating number operand.\n\nSun Mar 30 07:00:32 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/tk/tcltklib.c: rb_hash_lookup has not been backported yet.\n\nSat Mar 29 14:18:41 2008  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/*: full update Ruby/Tk to support Ruby(1.9|1.8) and Tc/Tk8.5.\n\n\t* ext/tk/lib/tkextlib/tile.rb: [incompatible] remove TileWidgets' \n\t  instate/state/identify method to avoid the conflict with standard\n\t  widget options. Those methods are renamed to ttk_instate/ttk_state/\n\t  ttk_identify (tile_instate/tile_state/tile_identify are available \n\t  too). Although I don't recommend, if you realy need old methods, \n\t  please define \"Tk::USE_OBSOLETE_TILE_STATE_METHOD = true\" before \n\t  \"require 'tkextlib/tile'\".\n\n\t* ext/tk/lib/tkextlib/tile.rb: \"Tk::Tile::__Import_Tile_Widgets__!\"\n\t  is obsolete. It outputs warning. To control default widget set, \n\t  use \"Tk.default_widget_set = :Ttk\".\n\n\t* ext/tk/lib/tk.rb: __IGNORE_UNKNOWN_CONFIGURE_OPTION__ method and \n\t  __set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) method are defind \n\t  as module methods of TkConfigMethod. It may help users to wrap old \n\t  Ruby/Tk scripts (use standard widgets) to force to use Ttk widgets.\n\t  Ttk widgets don't have some options of standard widgets which are \n\t  control the view of widgets. When set ignore-mode true, configure \n\t  method tries to ignoure such unknown options with no exception. \n\t  Of course, it may raise other troubles on the GUI design. \n\t  So, those are a little danger methods. \n\n\t* ext/tk/lib/tk/itemconfig.rb: __IGNORE_UNKNOWN_CONFIGURE_OPTION__ \n\t  method and __set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) method \n\t  are defind as module methods of TkItemConfigMethod as the same \n\t  purpose as TkConfigMethod's ones.\n\n\t* ext/tk/sample/ttk_wrapper.rb: A new example. This is a tool for \n\t  wrapping old Ruby/Tk scripts (which use standard widgets) to use \n\t  Ttk (Tile) widgets as default.\n\n\t* ext/tk/sample/tkextlib/tile/demo.rb: use ttk_instate/ttk_state \n\t  method instead of instate/state method.\n\n\t* ext/tk/lib/tk/root, ext/tk/lib/tk/namespace.rb,\n\t  ext/tk/lib/tk/text.rb, ext/tk/lib/tkextlib/*: some 'instance_eval's  \n\t  are replaced to \"instance_exec(self)\".\n\n\t* ext/tk/lib/tk/event.rb: bug fix on KEY_TBL and PROC_TBL (?x is not \n\t  a character code on Ruby1.9).\n\n\t* ext/tk/lib/tk/variable.rb: support new style of operation argument \n\t  on Tcl/Tk's 'trace' command for variables. \n\n\t* ext/tk/sample/demos-jp/widget, ext/tk/sample/demos-en/widget: bug fix\n\n\t* ext/tk/sammple/demos-jp/textpeer.rb, \n\t  ext/tk/sammple/demos-en/textpeer.rb: new widget demo.\n\n\t* ext/tk/tcltklib.c: decrase SEGV troubles (probably)\n\n\t* ext/tk/lib/tk.rb: remove Thread.critical access if Ruby1.9\n\n\t* ext/tk/lib/tk/multi-tk.rb: support Ruby1.9 (probably)\n\n\t* ext/tk/lib/tkextlib/tile.rb: add method to define Tcl/Tk command \n\t  to make Tcl/Tk theme sources (based on different version of Tile \n\t  extension) available. \n\t  (Tk::Tile::__define_LoadImages_proc_for_comaptibility__)\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tk/wm.rb: support dockable frames\n\t  (Tcl/Tk8.5 feature). 'wm' command can treat many kinds of widgets \n\t  as toplevel widgets.\n\n\t* ext/tk/lib/tkextlib/tile/style.rb: ditto.\n\t  (Tk::Tile::Style.__define_wrapper_proc_for_compatibility__)\n\n\t* ext/tk/lib/tk/font.rb: add actual_hash and metrics_hash to get \n\t  properties as a hash. metrics_hash method returns a boolean value \n\t  for 'fixed' option. But metrics method returns numeric value \n\t  (0 or 1) for 'fixed' option, because of backward compatibility. \n\n\t* ext/tk/lib/tk/timer.rb: somtimes fail to set callback procedure.\n\n\t* ext/tk/lib/tk.rb: add Tk.sleep and Tk.wakeup method. Tk.sleep \n\t  doesn't block the eventloop. It will be better to use the method \n\t  in event callbacks.\n\n\t* ext/tk/sample/tksleep_sample.rb: sample script about Tk.sleep.\n\nSat Mar 29 04:08:59 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (clone_method): should copy cref as well.\n\t  [ruby-core:15833]\n\nMon Mar 24 20:07:42 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (rb_eval): Call trace hook for if expression after the\n\t  condition has been evaluated, not before; submitted by Rocky\n\t  Bernstein in #18722.\n\nMon Mar 24 19:44:53 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* parse.y (yycompile): Always prepare a new array for each file's\n\t  SCRIPT_LINES__ storage, instead of appending source lines every\n\t  time a file is re-loaded; submitted by Rocky Bernstein in\n\t  #18517.\n\nMon Mar 24 10:25:54 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: sitearch should use target_cpu.  [ruby-core:15986]\n\nMon Mar 24 01:24:24 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb (result): use proc instead of Thread. [ruby-dev:33692]\n\nFri Mar 21 21:26:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/resolv.rb (Resolv::Hosts): should not use win32/resolv on cygwin.\n\t  [ruby-dev:29945], [ruby-dev:34095]\n\n\t* lib/win32/registry.rb (Win32::Registry.expand_environ): try upcased\n\t  name too for cygwin.  [ruby-dev:29945]\n\n\t* lib/win32/resolv.rb (Win32::Resolv.get_hosts_path): use expand_path.\n\nFri Mar 21 21:10:00 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/ipaddr.rb: Say that I am the current maintainer.\n\n\t* lib/set.rb: Ditto.\n\n\t* lib/shellwords.rb: Ditto.\n\n\t* ext/syslog/syslog.txt: Ditto.\n\nFri Mar 21 09:24:28 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* instruby.rb (open_for_install): write block result and rewrite only\n\t  if changed from existing file.\n\nWed Mar 19 21:01:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (dir_inspect, dir_path, dir_tell): check for frozen and closed\n\t  is not needed.  [ruby-dev:32640]\n\nWed Mar 19 20:25:40 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (Init_Dir): define inspect method.  [ruby-core:15960]\n\nWed Mar 19 14:59:12 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-style.el (ruby-style-{case,label}-indent): fix for labels\n\t  inside blocks in switch and function top level.\n\nWed Mar 19 14:36:40 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_cstr_to_inum): treat successive underscores as\n\t  nondigit.  [ruby-dev:34089]\n\nWed Mar 19 00:01:23 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb (ERB::Compiler): Make some minor code optimization.\n\nMon Mar 17 17:11:13 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-mode): should use `run-mode-hooks' instead\n\t  of calling `run-hooks' directly to run the mode hook.  patch from\n\t  Chiyuan Zhang <pluskid AT gmail.com> in [ruby-core:15915]\n\nMon Mar 17 16:41:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: unset GREP_OPTIONS.  [ruby-core:15918]\n\nFri Mar 14 16:59:23 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_LIB_PREFIX): fix for prefix.\n\nFri Mar 14 16:35:11 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::Cookie::initialize): performance patch from\n\t  Makoto Kuwata <kwa@kuwata-lab.com> in [ruby-dev:34048].\n\nFri Mar 14 15:49:05 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_LIB_PREFIX): use libdir.\n\nFri Mar 14 10:12:29 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_CHECK_VARTYPE): should not indent preprocessor\n\t  directives.\n\nThu Mar 13 00:37:20 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_call0): yields the last executed node line number at\n\t  return event.  [ruby-core:15855]\n\nWed Mar 12 02:12:20 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/delegate.rb: check $@ to avoid NoMethodError.\n\nTue Mar 11 19:48:09 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (fix_coerce): try conversion before type check.\n\t  [ruby-core:15838]\n\nTue Mar 11 17:03:23 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/delegate.rb (Delegator#initialize, DelegateClass): skip correct\n\t  backtrace.  [ruby-dev:34019]\n\nTue Mar 11 16:43:53 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_cmdvector): terminate shrunken command line.\n\nTue Mar 11 12:39:03 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (clean-local): removes MINOBJS.\n\nSat Mar  8 18:50:57 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (isdirsep): backslash is valid path separator on cygwin too.\n\nFri Mar  7 19:56:10 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb: rdoc added.  [ruby-Patches-9762]\n\nThu Mar  6 15:10:21 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32}/Makefile.sub (RUNRUBY): use $(PROGRAM) instead of\n\t  ruby$(EXEEXT).\n\t  suggested by KIMURA Koichi <kimura.koichi at canon.co.jp>.\n\t  [ruby-dev:34000]\n\nThu Mar  6 12:15:06 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (opt_block_param): command can start just after block param\n\t  definition.  [ruby-list:44479]\n\nThu Mar  6 00:34:11 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb: update RDoc. Thanks Makoto Kuwata [ruby-dev:33702]\n\nMon Mar  3 23:28:34 2008  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpservlet/filehandler.rb: should normalize path\n\t  separators in path_info to prevent directory traversal attacks\n\t  on DOSISH platforms.\n\t  reported by Digital Security Research Group [DSECRG-08-026].\n\n\t* lib/webrick/httpservlet/filehandler.rb: pathnames which have\n\t  not to be published should be checked case-insensitively.\n\nMon Mar  3 16:14:24 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (rb_any_hash): shrinks all results in Fixnum range.\n\t  [ruby-core:15713]\n\nSat Mar  1 02:35:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (big2str_find_n1): check integer overflow.\n\nTue Feb 26 16:06:00 2008  Technorama Ltd.  <oss-ruby@technorama.net>\n\n\t* ext/openssl/ossl_pkey_{ec,dh,dsa,rsa}.c: Remove useless warnings.\n\n\t* ext/openssl/ossl_asn1.c: Simplify code.\n\n\t* ext/openssl/ossl_ssl_session.c Fix compiler warnings.\n\t  Undefine #id if SSL_SESSION_get_id is not supported.\n\nTue Feb 26 15:43:42 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* parse.y (tokadd_escape): refactored.  [ruby-core:15657]\n\nMon Feb 25 17:30:29 2008  Technorama Ltd.  <oss-ruby@technorama.net>\n\n\t* ext/openssl/digest.c ext/openssl/lib/openssl/digest.rb:\n\t  Commit patch #9280 from Akinori MUSHA.\n\t  Simplify the OpenSSL::Digest class and make use of the\n\t  existing Digest framework.\n\t  Enhance performance.\n\nMon Feb 25 13:40:03 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* process.c (Init_process): share bignum objects for RLIM_INFINITY,\n\t  RLIM_SAVED_MAX and RLIM_SAVED_CUR if they are equal.\n\nSun Feb 24 23:29:48 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk, {bcc,win}32/Makefile.sub (clean-local): remove\n\t  intermediate files.\n\nSun Feb 24 03:52:58 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.c (valid_filename): use O_EXCL to get rid of clobbering\n\t  existing files in race conditions.\n\nFri Feb 22 19:50:19 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (BIGZEROP): fix for longer Bignum zeros.  [ruby-Bugs-17454]\n\nFri Feb 22 16:09:53 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_lshift, rb_big_rshift, rb_big_aref): removed excess\n\t  arguments.\n\nThu Feb 21 00:01:34 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RPATHFLAG): -R option of HP-UX ld is not for runtime\n\t  load path.  [ruby-list:44600]\n\nWed Feb 20 23:55:19 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_map_errno): exported.\n\nWed Feb 20 13:08:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* instruby.rb (parse_args): added --dir-mode, --script-mode and\n\t  --cmd-type options.  [ruby-dev:33816]\n\n\t* instruby.rb (parse_args): added bin-arch and bin-comm to install\n\t  type, for compiled files and script files.\n\n\t* instruby.rb (parse_args): deal with make style command line macros,\n\t  and count as long syle options if prefixed with INSTALL_.\n\n\t* instruby.rb (makedirs): use $dir_mode.  [ruby-dev:33805]\n\n\t* instruby.rb (open_for_install): set file mode, which is now\n\t  permission mode instead of access mode.\n\n\t* instruby.rb (bin-comm): installs scripts with replacing shebang\n\t  lines.\n\nTue Feb 19 18:34:32 2008  Tanaka Akira  <akr@fsij.org>\n\n\t* gc.c (STACK_LENGTH) [SPARC] : 0x80 offset removed.  [ruby-dev:33857]\n\nTue Feb 19 14:27:32 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/readline/readline.c (readline_event): prevent polling.  based on\n\t  a patch from error errorsson in [ruby-Bugs-17675].\n\nTue Feb 19 12:08:29 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (yycompile): clear ruby_eval_tree_begin if parse failed.\n\nMon Feb 18 16:23:45 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (yycompile): clear ruby_eval_tree_begin too before parse.\n\nMon Feb 18 10:17:42 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/pty/lib/expect.rb (IO#expect): check if peer is closed.\n\t  [ruby-Bugs-17940]\n\nFri Feb 15 20:37:06 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/rational.rb (floor, ceil, truncate, round): do not use\n\t  definitions of Numeric.\n\n\t* lib/rational.rb (to_i): should returns truncated self.\n\n\t* lib/complex.rb (numerator): requires\n\t  Integer#{numerator,denominator}.\n\n\t* lib/complex.rb (quo): do not use definition of Numeric.\n\n\t* lib/complex.rb (div, divmod, floor, ceil, truncate, round):\n\t  undef'ed.\n\nFri Feb 15 15:23:12 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_convert): check upper bound.  a patch from\n\t  Daniel Luz at [ruby-Bugs-17910].\n\nFri Feb 15 02:42:25 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (ftruncate): check if available.\n\n\t* file.c (rb_file_truncate): check if ftruncate instead of truncate.\n\nFri Feb 15 02:40:54 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (sigsetmask): check when signal semantics is not POSIX.\n\n\t* signal.c (USE_TRAP_MASK): set true if sigprocmask or sigsetmask is\n\t  available.\n\nThu Feb 14 17:44:32 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dl/ptr.c (dlmem_each_i): typo fixed.  a patch from IKOMA\n\t  Yoshiki <ikoma AT mb.i-chubu.ne.jp> in [ruby-dev:33776].\n\nThu Feb 14 16:02:51 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_utime): inhibits with secure level 2 or higher.\n\nThu Feb 14 01:43:16 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/timeout.rb (Timeout::timeout): made sensitive to location on the\n\t  stack.  [ruby-core:15458]\n\nThu Feb 14 00:49:53 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (INSTRUBY_ARGS): pass mode to install.  [ruby-dev:33766]\n\n\t* instruby.rb (parse_args): added --data-mode and --prog-mode options.\n\nTue Feb 12 11:33:26 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/erb/test_erb.rb(TestERBCore): import from erb-2.0.4.\n\n\t* test/erb/hello.erb: ditto\n\nMon Feb 11 17:25:21 2008  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (RSS::VERSION), test/rss/test_version.rb, NEWS:\n\t  0.2.3 -> 0.2.4.\n\n\t* lib/rss/maker.rb, lib/rss/maker/, test/rss/test_maker_2.0.rb:\n\t  fixed a bug that RSS::Maker.make(\"0.9\")'s item doesn't make some\n\t  elements if description is missed.\n\t  Reported by Michael Auzenne. Thanks!!!\n\n\t* lib/rss/maker/0.9.rb, test/rss/test_maker_0.9.rb:\n\t  RSS::Maker.make(\"0.9\") generates RSS 0.92 not RSS 0.91.\n\nMon Feb 11 16:57:00 2008  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* ChangeLog: format-time-string under C locale. [ruby-dev:33261]\n\nMon Feb 11 16:31:47 2008  URABE Shyouhei  <shyouhei@ice.uec.ac.jp>\n\n\t* gc.c (rb_newobj): prohibit call of rb_newobj() during gc.\n\t  Submitted by Sylvain Joyeux [ruby-core:12099].\n\n\t* ext/dl/ptr.c: do not use LONG2NUM() inside dlptr_free().\n\t  Slightly modified fix bassed on a patch by Sylvain Joyeux\n\t  [ruby-core:12099] [ ruby-bugs-11859 ] [ ruby-bugs-11882 ]\n\t  [ ruby-patches-13151 ].\n\nMon Feb 11 00:22:55 2008  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* lib/benchmark.rb (Job::Benchmark#item): fix typo.\n\nSat Feb  9 23:22:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/bigdecimal/extconf.rb: simplified the condition.\n\nSat Feb  9 17:51:24 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_to_f): use strtod() for more\n\t  precision.  [ruby-talk:290296]\n\n\t* ext/bigdecimal/bigdecimal.c (BASE_FIG): made constant.\n\n\t* ext/bigdecimal/extconf.rb: ditto.  [ruby-dev:33658]\n\nSat Feb  9 00:44:52 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/irb.rb (IRB::Irb::eval_input): rescues Interrupt and other than\n\t  SystemExit and SignalException.  [ruby-core:15359]\n\nFri Feb  8 15:09:21 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (xsystem): expand macros like as make.\n\nTue Feb  5 11:14:11 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (INSTALL_DIRS, install_dirs): added BINDIR.\n\n\t* lib/mkmf.rb (install_files): rejects files matching to\n\t  $NONINSTALLFILES.\n\n\t* lib/mkmf.rb (init_mkmf): defaults $NONINSTALLFILES to backup and\n\t  temporary filse.\n\nMon Feb  4 16:44:24 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (darwin): NSIG is not defined if _XOPEN_SOURCE > 500L.\n\t  [ruby-dev:33584]\n\nSat Feb  2 20:06:42 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/benchmark.rb (Benchmark::realtime): make Benchmark#realtime\n\t  a bit faster.  a patch from Alexander Dymo <dymo AT ukrpost.ua> in\n\t  [ruby-core:15337].\n\nSat Feb  2 09:53:39 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (darwin): disabled fat-binary support which confuses\n\t  configure much, since ``universal'' implies hidden cross-compiling.\n\t  TODO: ruby and libruby.bundle might be possible to bound with `lipo'\n\t  after builds for each archs.  Anyway, config.h and rbconfig.rb must\n\t  be separated definitely at least.\n\nFri Feb  1 21:42:37 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (darwin): _XOPEN_SOURCE is necessary to make ucontext_t\n\t  consistent with the library implementation of MacOS X 10.5.\n\t  [ruby-dev:33461]\n\n\t* configure.in (darwin): ucontext on PowerPC MacOS X 10.5 is broken.\n\nThu Jan 31 08:31:19 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (ext/extmk.rb, instruby.rb): inlined $(MAKE) so that can\n\t  be executed even with -n.\n\nThu Jan 31 07:00:19 2008  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (bin_for_find): should find a symbol by\n\t  Symbol class.\n\n\t* test/rinda/test_rinda.rb (test_symbol_tuple): ditto.\n\nWed Jan 30 22:07:58 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb: refined deprecated methods.\n\nWed Jan 30 22:06:54 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* bignum.c (rb_cstr_to_inum): '0_2' is a valid representation.\n\nTue Jan 29 22:40:12 2008  Yusuke Endoh  <mame@tsg.ne.jp>\n\n\t* range.c (step_i): rb_funcall receives VALUE as an argument.\n\nTue Jan 29 11:53:05 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: rm largefile.h.\n\nMon Jan 28 01:21:15 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_open_file): should check NUL in path.\n\t  <http://www.rubyist.net/~matz/20080125.html#c01>.\n\n\t* io.c (rb_io_s_popen): ditto.\n\n\t* io.c (rb_io_reopen): ditto.\n\n\t* io.c (next_argv): ditto.\n\n\t* io.c (rb_io_s_foreach): ditto.\n\n\t* io.c (rb_io_s_readlines): ditto.\n\n\t* io.c (rb_io_s_read): ditto.\n\nFri Jan 25 22:33:38 2008  Yusuke Endoh  <mame@tsg.ne.jp>\n\n\t* math.c: fix comment.  [ruby-dev:33276]\n\nFri Jan 25 10:31:58 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* */*.bat: set svn:mime-type to text/batch.\n\nThu Jan 24 19:36:22 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic::inspect): use Kernel#to_s instead\n\t  object_id with printf.  [ruby-dev:33347]\n\nTue Jan 22 11:22:47 2008  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/setup.mak ($(ARCH)): if a macro is appended by $(APPEND),\n\t  a space will be inserted on the top of the line.\n\n\t* win32/Makefile.sub (MKFILES): stop make process if Makefile is\n\t  updated.\n\nMon Jan 21 17:34:41 2008  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* io.c (rb_io_mode_flags, rb_io_mode_modenum): Ignore encoding\n\t  options for forward compatibility.\n\nMon Jan 21 12:50:02 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c, gc.c (setjmp): sigsetjmp is a macro on cygwin.\n\nSat Jan 19 11:21:53 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (sigsetjmp): check if available.\n\n\t* eval.c, gc.c (setjmp): do not use _setjmp if sigsetjmp is available.\n\nSat Jan 19 11:10:11 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: Remove wrong assumptions about Cygwin.  a patch from\n\t  Corinna Vinschen in [ruby-Bugs-17018].\n\nThu Jan 17 21:06:01 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb (Date::Infinity#<=>): didn't work.  A patch from\n\t  Dirkjan Bussink <d.bussink AT gmail.com> [ruby-core:15098].\n\t  This is a bug obviously.  However it didn't affect the library's\n\t  functions.\n\n\t* lib/date.rb, lib/date/format.rb: some trivial changes.\n\nTue Jan 15 15:09:28 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/setup.mak: strip out empty lines from CPP output.\n\nTue Jan 15 03:41:42 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (eval): check if backtrace is empty.  [ruby-core:15040]\n\nTue Jan 15 01:28:47 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk: simplified dummy objects dependencies.\n\nMon Jan 14 16:12:58 2008  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/shellwords.rb: scape should be an alias to shellescape.  a\n\t  patch from Masahiro Kawato <m-kawato AT mwb.biglobe.ne.jp> in\n\t  [ruby-dev:33060].\n\nMon Jan 14 09:32:40 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/time.rb: do not reference Time directly from the inside of\n\t  definitions. [ruby-dev:33059]\n\nSat Jan 12 18:27:41 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_define_alloc_func, rb_undef_alloc_func): should\n\t  define/undef on a signleton class.  [ruby-core:09959]\n\nSat Jan 12 12:04:14 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: tuning for performance.\n\nFri Jan 11 12:35:56 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: moved broken syscall checks from process.c etc.\n\n\t* defines.h (WORDS_BIGENDIAN): honor __BIG_ENDIAN__ than the result of\n\t  configure.\n\n\t* dln.c: use dlopen on Mac OS X 10.3 or later.  backport from trunk.\n\n\t* lib/rdoc/options.rb (check_diagram): more precise check, darwin\n\t  is not Windows but minwg is on it.\n\nThu Jan 10 10:53:50 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_open_osfhandle): reverted to old definition.\n\t  [ ruby-Bugs-16948 ]\n\nTue Jan  8 20:02:08 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win{32,ce}/Makefile.sub: merged.\n\nSun Jan  6 09:39:02 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: introduced some constants\n\t  (for internal use).\n\n\t* sample/cal.rb: trivial adjustments.\n\nFri Jan  4 23:08:48 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_arg): use converted object.  [ruby-core:14759]\n\nFri Jan  4 01:20:21 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32.h: only VC6 needs extern \"C++\" for math.h.  [ruby-talk:285660]\n\nThu Jan  3 11:28:58 2008  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (fptr_finalize): clear errno first.  [ruby-talk:284492]\n\nWed Jan  2 10:18:56 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* sample/time.rb: use Process.times instead of Time.times.\n\nWed Jan  2 09:18:11 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* sample/goodfriday.rb: examples for date are enough.  retired.\n\nWed Jan  2 09:06:55 2008  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* sample/cal.rb: just updated with the newest version.\n\nMon Dec 31 06:50:38 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* trunk/common.mk: not use -I$(srcdir)/lib with $(MINIRUBY) for cross\n\t  compiling.\n\n\t* configure.in, {win,bcc}32/Makefile.sub (MINIRUBY): -I$(srcdir)/lib\n\t  moved.\n\nSun Dec 30 22:48:37 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb (_valid_time?): I'm not sure to recommend such an\n\t  expression.  but anyway it is acceptable now.  [ruby-core:14580]\n\nFri Dec 28 16:36:33 2007  NARUSE, Yui  <naruse@airemix.com>\n\n       * lib/resolv.rb (Resolv::DNS#each_address): now returns IPv6 address.\n\nFri Dec 28 13:21:32 2007  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb, test/rss/test_version.rb, NEWS: 0.2.2 -> 0.2.3.\n\n\t* lib/rss/parser.rb, test/rss/test_parser.rb: supported \"-\" in tag name.\n\t  Reported by Ray Chen. Thanks.\n\nThu Dec 27 23:56:01 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* mkconfig.rb: should not use the libraries under the source directory\n\t  at cross compiling.\n\nThu Dec 27 11:02:45 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* intern.h, string.c (rb_str_set_len): added for upgrading path from\n\t  1.8 to 1.9. [ruby-dev:32807]\n\n\t* string.c (rb_str_lines, rb_str_bytes): ditto.\n\nThu Dec 27 10:47:32 2007  Technorama Ltd.  <oss-ruby@technorama.net>\n\n\t* ext/openssl/ossl_ssl.c: Only show a warning if the default\n\t  DH callback is actually used.\n\n\t* ext/openssl/ossl_rand.c: New method: random_add().\n\nWed Dec 26 22:27:45 2007  NARUSE, Yui <naruse@ruby-lang.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Name.==): fix for other is array of\n\t  Resolv::DNS::Label::Str.\n\n\t* lib/resolv.rb (Resolv::DNS::MessageEncoder#put_label): String#string\n\t  is not defined, so replace to_s.\n\n\t* lib/resolv.rb (Resolv::IPv6#to_name): ip6.int is obsoleted by\n\t  int.arpa.\n\nMon Dec 24 16:18:57 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/ri/ri_options.rb:  Fix ri --help listing of gem ri paths.\n\t  Merge of r14567 and r14569 from trunk.\n\n\t* lib/rdoc/ri/ri_paths.rb:  Fix duplication of ri data for multiple\n\t  gems.  Merge of r14567 from trunk\n\nMon Dec 24 12:35:03 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win{32,ce}/Makefile.sub (MFLAGS): defaulted to -l.\n\nMon Dec 24 11:56:31 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* {bcc32,win{32,ce}}/Makefile.sub (SET_MAKE): set MFLAGS which is not\n\t  set by default, to get rid of chaotic situation of MFLAGS/MAKEFLAGS.\n\nSat Dec 22 14:49:46 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb: don't freeze nil even if 1.8 will not be aware of\n\t  the issue. [ruby-dev:32677]\n\nWed Dec 19 13:57:43 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (TIMEZONE_VOID): check whether timezone requires zero\n\t  arguments.  [ruby-dev:32631]\n\nWed Dec 19 12:01:42 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (f_rest_arg): check if duplicated.  [ruby-core:14140]\n\nWed Dec 19 10:52:29 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_cstr_to_inum): an underscore succeeding after octal\n\t  prefix is allowed.  [ruby-core:14139]\n\nMon Dec 17 13:43:15 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* gc.c (stack_end_address): use local variable address instead of\n\t  __builtin_frame_address(0) to avoid SEGV on SunOS 5.11 on x86 with\n\t  gcc (GCC) 3.4.3 (csl-sol210-3_4-20050802).\n\t  stack_end_address returned a frame address of garbage_collect\n\t  since stack_end_address doesn't create its own frame.\n\t  So a VALUE stored in a callee saved register, %edi, pushed into\n\t  the stack at the beginning of garbage_collect was not marked.\n\nMon Dec 17 12:21:25 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in (RUNRUBY): added RUNRUBYOPT.\n\nFri Dec 14 12:36:35 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_CHECK_VARTYPE): check if a variable is defined\n\t  and its type.\n\n\t* configure.in (timezone, altzone): check for recent cygwin.\n\n\t* missing/strftime.c (strftime): fix for timezone.  [ruby-dev:32536]\n\n\t* lib/mkmf.rb (try_var): should fail for functions.\n\n\t* ext/readline/extconf.rb: should use have_func for functions instead\n\t  of have_var.\n\nTue Dec 11 00:04:05 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_slice_bang): If an invalid negative index (<\n\t  -size) is given, do not raise an exception but return nil just\n\t  like slice() does.\n\n\t* test/ruby/test_array.rb (TestArray::test_slice,\n\t  TestArray::test_slice!): Pull in test cases from trunk.\n\nMon Dec 10 21:47:53 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* transcode.c (str_transcode): allow non-registered encodings.\n\t  [ruby-dev:32520]\n\nMon Dec 10 21:00:30 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_slice_bang): should return nil if position out\n\t  of range.  a patch from Akinori MUSHA <knu AT iDaemons.org>.\n\t  [ruby-dev:32518]\n\nMon Dec 10 18:28:06 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/uri/common.rb (URI::REGEXP::PATTERN): typo in REG_NAME\n\t  regular expression.  a patch from Ueda Satoshi\n\t  <s-ueda AT livedoor.jp>.  [ruby-dev:32514]\n\nSun Dec  9 12:39:01 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/cgi.rb (read_multipart): exclude blanks from header values.\n\t  [ruby-list:44327]\n\nWed Dec  5 23:38:50 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* range.c (range_each): followed step_i change.\n\nWed Dec  5 18:08:45 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* numeric.c (int_odd_p): new method Integer#odd?.\n\t  (int_even_p): new method Integer#even?.\n\t  (int_pred): new method Integer#pred.\n\t  (fix_odd_p): new method Fixnum#odd?.\n\t  (fix_even_p): new method Fixnum#even?.\n\nWed Dec  5 15:15:21 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* range.c (step_i, range_step): support non-fixnum steps.\n\t  [ruby-talk:282100]\n\nTue Dec  4 11:23:50 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_cstr_to_inum): trailing spaces may exist at sqeezing\n\t  preceeding 0s.  [ruby-core:13873]\n\nSun Dec  2 22:43:45 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (error_print): put newline unless multiple line message ends\n\t  with a newline.  [ruby-dev:32429]\n\nSun Dec  2 15:49:20 2007  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb, test/rss/test_version.rb, NEWS: 0.2.1 -> 0.2.2.\n\n\t* lib/rss/maker/itunes.rb: fixed new_itunes_category.\n\t* lib/rss/maker/taxonomy.rb: new_taxo_topic -> new_topic because\n\t  of consistency.\n\n\t* test/rss/test_maker_itunes.rb, test/rss/test_itunes.rb: removed\n\t  needless UTF-8 characters.\n\nSun Dec  2 01:12:15 2007  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 14070 from trunk.\n\n\t* lib/xmlrpc/server.rb (XMLRPC::Server#server): Improve signal handling so\n\t  pressing control-c in the controlling terminal or sending SIGTERM stops\n\t  the XML-RPC server.\n\nSat Dec  1 15:13:33 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/resolv.rb: documentation update.  backported from 1.9.\n\t  [ruby-core:13273]\n\nSat Dec  1 03:30:47 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (newline_node): set line from outermost node before removing\n\t  NODE_BEGIN.  [ruby-dev:32406]\n\nFri Nov 30 21:53:28 2007  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb, test/rss/test_version.rb: 0.2.0 -> 0.2.1.\n\n\t* lib/rss/content.rb, lib/rss/content/1.0.rb,\n\t  lib/rss/content/2.0.rb, lib/rss/maker/content.rb,\n\t  test/rss/rss-testcase.rb, test/rss/test_content.rb,\n\t  test/rss/test_maker_content.rb: supported content:encoded with RSS\n\t  2.0.\n\t  Suggested by Sam Lown. Thanks.\n\n\t* NEWS: added the above changes.\n\nThu Nov 29 16:59:10 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (stmt): remove unnecessary NODE_BEGIN.  [ruby-core:13814]\n\nWed Nov 28 14:43:14 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extract_makefile): use dldflags instead of DLDFLAGS to\n\t  get rid of mixing $LDFLAGS and $ARCH_FLAG.\n\n\t* lib/mkmf.rb (configuration): ditto.\n\n\t* lib/mkmf.rb (create_makefile): support for extensions which has no\n\t  shared object.\n\nWed Nov 28 09:51:42 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big2str0): do not clobber space for sign.\n\n\t* sprintf.c (remove_sign_bits): extends sign bit first.\n\nWed Nov 21 01:04:12 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (nil_plus): remove unused function.  [ruby-core:13737]\n\nSun Nov 18 14:03:44 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_alias): do not call hook functions until initialization\n\t  finishes.  [ruby-talk:279538]\n\nSun Nov 18 09:09:48 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (String#tr_cpp): make preprocessor identifiers.\n\nSat Nov 17 13:58:11 2007  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_invoke): bug fix. [ruby-talk:279100]\n\nFri Nov 16 17:41:34 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (Document-class): moved the simplest example to\n\t  the top.\n\n\t* ext/iconv/iconv.c (iconv_s_iconv): Document-method: needs class\n\t  prefix for class method.  [ruby-core:13542]\n\n\t* ext/iconv/iconv.c (iconv_iconv): also instance method needs to be\n\t  qualified.\n\nFri Nov 16 11:16:41 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb (String#is_binary_data?): use Integer#fdiv.\n\nThu Nov 15 19:50:46 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/curses/extconf.rb: check macro if cannot find func.\n\t  [ruby-list:44224]\n\nThu Nov 15 12:19:14 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::FileStore::restore): use\n\t  lockfile for exclusive locks.  a patch from <tommy AT tmtm.org>.\n\t  [ruby-dev:32296]\n\nWed Nov 14 01:52:59 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* missing/isinf.c (isinf): don't define if the macro is defined.\n\nWed Nov 14 01:34:42 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (round): fallback definition.\n\n\t* numeric.c (flo_divmod, flo_round): use round() always.\n\t  [ruby-dev:32269]\n\nTue Nov 13 22:02:23 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: remove Thread.exclusive.\n\n\t* lib/drb/extservm.rb: ditto.\n\nTue Nov 13 16:33:07 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (flodivmod): work around for infinity.\n\n\t* numeric.c (flo_divmod): work around for platforms have no round().\n\t  [ruby-dev:32247]\n\nTue Nov 13 13:58:51 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* numeric.c (numeric.c): Integer#ord implemented.  [ruby-dev:32206]\n\nTue Nov 13 02:57:04 2007  URABE Shyouhei  <shyouhei@ice.uec.ac.jp>\n\n\t* numeric.c (flo_divmod): round to the nearest integer.\n\t  [ ruby-Bugs-14540 ]\n\nMon Nov 12 16:52:29 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): rdoc about srcprefix.  a patch from\n\t  Daniel Berger <djberg96 AT gmail.com> in [ruby-core:13378].\n\nMon Nov 12 13:53:06 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-parse-partial): handle stringified\n\t  symbols properly using ruby-forward-string.\n\nMon Nov 12 12:38:31 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* Makefile.in (lex.c): don't remove lex.c at first.\n\nFri Nov  9 07:26:04 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* random.c: update MT URL.[ruby-core:13305].\n\nWed Nov  7 03:32:38 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rexml/encodings/SHIFT-JIS.rb (REXML::Encoding): place -x for\n\t  nkf conversion.  a patch from <moonwolf AT moonwolf.com>.\n\t  [ruby-dev:32183]\n\nMon Nov  5 05:17:04 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Switch::summarize): fix for long form\n\t  option with very long argument.  a patch from Kobayashi Noritada\n\t  <nori1 AT dolphin.c.u-tokyo.ac.jp> in [ruby-list:44179].\n\nMon Nov  5 01:20:33 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (call_args): remove \"parenthesize argument(s) for future\n\t  version\" warning.  when I added this warning, I had a plan to\n\t  reimplement the parser that is simpler than the current one.\n\t  since we abandoned the plan, warning no longer required.\n\nFri Nov  2 00:13:51 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_assoc): check and convert inner arrays (assocs)\n\t  using #to_ary.\n\n\t* hash.c (rb_hash_s_create): check and convert argument hash\n\t  using #to_hash.\n\n\t* hash.c (rb_hash_s_create): Hash#[] now takes assocs as source of\n\t  hash conversion.\n\nThu Nov  1 23:47:43 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRbTCPSocket): Improving with multiple network\n\t  interface.\n\n\t* test/drb/drbtest.rb: ditto.\n\nFri Oct 26 17:14:14 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (fix_pow): returns 1.0 for 0**0.0.\n\n\t* numeric.c (fix_pow): returns infinity for 0**-1.  [ruby-dev:32084]\n\nWed Oct 25 07:18:09 2007  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 13781 from trunk.\n\n\t* lib/net/telnet.rb (Net::Telnet#login): Allowing \"passphrase\" in\n\t  addition to \"password\" for Telnet login prompts. [ruby-Bugs-10746]\n\nWed Oct 25 06:46:21 2007  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 13779 from trunk.\n\n\t* lib/net/telnet.rb (Net::Telnet#login): Making the password prompt\n\t  pattern case insensitive. [ruby-Bugs-10746]\n\nThu Oct 25 14:19:33 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_tell, rb_io_seek): check errno too.  [ruby-dev:32093]\n\nWed Oct 25 08:03:53 2007  James Edward Gray II  <jeg2@ruby-lang.org>\n\n\tMerged 13767, 13768, 13769, and 13770 from trunk.\n\n\t* lib/xmlrpc/parser.rb (XMLRPC::Convert::dateTime): Fixing a bug that\n\t  caused time zone conversion to fail for some ISO 8601 date formats.\n\t  [ruby-Bugs-12677]\n\n\t* lib/xmlrpc/client.rb (XMLRPC::Client#do_rpc): Explicitly start\n\t  the HTTP connection to support keepalive requests. [ruby-Bugs-9353]\n\n\t* lib/xmlrpc/client.rb (XMLRPC::Client#do_rpc): Improving the error\n\t  message for Content-Type check failures. [ruby-core:12163]\n\n\t* lib/xmlrpc/utils.rb (XMLRPC::ParseContentType#parse_content_type):\n\t  Making Content-Type checks case insensitive. [ruby-Bugs-3367]\n\nSun Oct 21 21:16:43 2007  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss.rb, lib/rss/, test/rss/, sample/rss/: merged from trunk.\n\t- 0.1.6 -> 2.0.0.\n\t- fixed image module URI. Thanks to Dmitry Borodaenko.\n\t- supported Atom.\n\t- supported ITunes module.\n\t- supported Slash module.\n\n\t* NEWS: added an entry for RSS Parser.\n\nThu Oct 18 10:57:06 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* ruby.h (RCLASS_IV_TBL): defined.\n\t  (RCLASS_M_TBL): ditto.\n\t  (RCLASS_SUPER): ditto.\n\t  (RMODULE_IV_TBL): ditto.\n\t  (RMODULE_M_TBL): ditto.\n\t  (RMODULE_SUPER): ditto.\n\nMon Oct 15 22:08:55 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Merge some of the sub-sections, as the differences were\n\t  unclear.\n\nMon Oct 15 21:57:07 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Mention ipaddr enhancements.\n\n\t* lib/ipaddr.rb (in_addr, in6_addr, addr_mask): Make some minor\n\t  code optimization.\n\n\t* lib/ipaddr.rb (<=>): Implement IPAddr#<=> and make IPAddr\n\t  comparable.\n\n\t* lib/ipaddr.rb (succ): Implement IPAddr#succ.  You can now create\n\t  a range between two IPAddr's, which (Range) object is\n\t  enumerable.\n\n\t* lib/ipaddr.rb (to_range): A new method to create a Range object\n\t  for the (network) address.\n\n\t* lib/ipaddr.rb (coerce_other): Support type coercion and make &,\n\t  |, == and include? accept a string or an integer instead of an\n\t  IPAddr object as the argument.\n\n\t* lib/ipaddr.rb (initialize): Give better error messages.\n\n\t* lib/ipaddr.rb: Improve documentation.\n\nMon Oct 15 21:24:25 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Mention shellwords and tempfile enhancements.\n\n\t* NEWS: Move the entry about Tk::X_Scrollable to a better section.\n\nMon Oct 15 17:28:20 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/openssl/lib/openssl/buffering.rb (read, readpartial): revert\n\t  r12496. handling EOF is a little differnt in ruby 1.8 and ruby 1.9.\n\t  [ruby-dev:31979]\n\nMon Oct 15 11:45:12 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (r_bytes0): refined length check.  [ruby-dev:32059]\n\nMon Oct 15 09:58:07 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (r_bytes0): check if source has enough data.\n\t  [ruby-dev:32054]\n\nMon Oct 15 01:15:09 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* ext/socket/socket.c (s_accept_nonblock): make accepted fd\n\t  nonblocking.  [ruby-talk:274079]\n\nSun Oct 14 04:08:34 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (AC_SYS_LARGEFILE): keep results also in command\n\t  options, to vail out of mismatch.  [ruby-list:44114]\n\n\t* mkconfig.rb, lib/mkmf.rb (configuration): add DEFS.\n\nSun Oct 14 03:55:52 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/mkexports.rb: deal with __fastcall name decorations.\n\t  [ruby-list:44111]\n\nSat Oct 13 09:02:16 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* {bcc,win}32/mkexports.rb: explicit data.  [ruby-list:44108]\n\nSat Oct 13 00:35:03 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rexml/source.rb (REXML::SourceFactory::SourceFactory): typo\n\t  fixed.  [ruby-list:44099]\n\nFri Oct 12 11:22:15 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (match_values_at): make #select to be alias to #values_at\n\t  to adapt RDoc description.  [ruby-core:12588]\n\nThu Oct 11 14:32:46 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32}/Makefile.sub (COMMON_MACROS): workaround for old SDK's\n\t  bug. [ruby-core:12584]\n\nWed Oct 10 23:34:45 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/securerandom.rb: new file.  [ruby-dev:31928]\n\n\t* lib/cgi/session.rb (create_new_id): use securerandom if available.\n\nTue Oct  9 01:01:55 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* re.c (rb_reg_s_union_m): Regexp.union accepts single\n\t  argument which is an array of patterns.  [ruby-list:44084]\n\nMon Oct  8 20:06:23 2007  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/net/http.rb, lib/open-uri.rb: remove\n\t  Net::HTTP#enable_post_connection_check.  [ruby-dev:31960]\n\n\t* lib/net/imap.rb: hostname should be verified against server's\n\t  indentity as persented in the server's certificate. [ruby-dev:31960]\n\n\t* ext/openssl/lib/net/telnets.rb, ext/openssl/lib/net/ftptls.rb: ditto.\n\nSat Oct  6 23:14:54 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_to_i): update RDoc since base can be any value\n\t  between 2 and 36.  [ruby-talk:272879]\n\nFri Oct  5 15:44:50 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/shellwords.rb: Add shellescape() and shelljoin().\n\n\t* lib/shellwords.rb: Rename shellwords() to shellsplit() and make\n\t  the former an alias to the latter.\n\n\t* lib/shellwords.rb: Add escape(), split(), join() as class\n\t  methods, which are aliases to their respective long names\n\t  prefixed with `shell'.\n\n\t* lib/shellwords.rb: Add String#shellescape(), String#shellsplit()\n\t  and Array#shelljoin() for convenience.\n\nFri Oct  5 15:40:04 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/tempfile.rb (Tempfile::make_tmpname): Allow to specify a\n\t  suffix for a temporary file name.\n\n\t* lib/tempfile.rb (Tempfile::make_tmpname): Make temporary file\n\t  names less predictable by including a random string.\n\t  [inspired by: akr]\n\nTue Oct  2 21:20:14 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (make_cmdvector): adjust escaped successive\n\t  double-quote handling. (merge from trunk)\n\nTue Oct  2 20:35:24 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (init_env): initialize HOME and USER environment\n\t  variables unless set. [ruby-core:12328] (merge from trunk)\n\n\t* win32/win32.c (NtInitialize, getlogin): ditto.\n\n\t* configure.in, win32/Makefile.sub (LIBS): need to link shell32\n\t  library for SH* functions on mswin32 and mingw32.\n\nMon Oct  1 12:50:59 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (id2ref): valid id should not refer T_VALUE nor T_ICLASS.\n\t  [ruby-dev:31911]\n\nWed Sep 26 23:54:37 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake), lib/mkmf.rb (configuration): top_srcdir\n\t  should not prefixed with DESTDIR.\n\nWed Sep 26 08:36:31 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in (ext/extinit.o): use $(OUTFLAG) as well as other\n\t  objects.  [ruby-Bugs-14228]\n\nWed Sep 26 05:12:17 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (yyerror): limit error message length.  [ruby-dev:31848]\n\n\t* regex.c (re_mbc_startpos): separated from re_adjust_startpos.\n\nTue Sep 25 13:47:38 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (remove_method): should not remove undef place holder.\n\t  [ruby-dev:31817]\n\nMon Sep 24 16:52:11 2007  Urabe Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* lib/net/http.rb: fix typo.\n\nSun Sep 23 21:57:25 2007  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/net/http.rb: an SSL verification (the server hostname should\n\t  be matched with its certificate's commonName) is added.\n\t  this verification can be skipped by\n\t  \"Net::HTTP#enable_post_connection_check=(false)\".\n\t  suggested by Chris Clark <cclark at isecpartners.com>\n\n\t* lib/net/open-uri.rb: use Net::HTTP#enable_post_connection_check to\n\t  perform SSL post connection check.\n\n\t* ext/openssl/lib/openssl/ssl.c\n\t  (OpenSSL::SSL::SSLSocket#post_connection_check): refine error message.\n\nSun Sep 23 09:05:05 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (os_obj_of, os_each_obj): hide objects to be finalized.\n\t  [ruby-dev:31810]\n\nSun Sep 23 08:58:01 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval_method.ci (rb_attr): should not use alloca for unknowen size\n\t  input.  [ruby-dev:31816]\n\n\t* parse.y (rb_intern_str): prevent str from optimization.\n\nSun Sep 23 05:42:35 2007  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* lib/rdoc/options.rb (Options::check_diagram): dot -V output\n\t  changed. [ ruby-Bugs-11978 ], Thanks Florian Frank.\n\nSat Sep 22 06:02:11 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::List::summarize): use each_line if\n\t  defined rather than each.  [ruby-Patches-14096]\n\nSat Sep 22 05:19:49 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_init): separate from strio_initialize\n\t  to share with strio_reopen properly.  [ruby-Bugs-13919]\n\nFri Sep 21 15:46:20 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (struct rb_exec_arg): proc should be a VALUE.\n\n\t* process.c (rb_f_exec): suppress a warning.\n\nFri Sep 21 03:05:35 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c, intern.h, ext/thread/thread.c: should not free queue while\n\t  any live threads are waiting.  [ruby-dev:30653]\n\nThu Sep 20 17:24:59 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (rb_detach_process): cast for the platforms where size of\n\t  pointer differs from size of int.\n\n\t* process.c (rb_f_exec, rb_f_system): should not exceptions after\n\t  fork.  [ruby-core:08262]\n\nFri Sep 14 00:34:25 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/extservm.rb (invoke_service): use Thread.exclusive instead of\n\t  Thread.critical\n\nWed Sep 12 23:12:22 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (proc_options): -W should be allowed in RUBYOPT\n\t  environment variable.  [ruby-core:12118]\n\nMon Sep 10 01:05:25 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_step): fixed integer overflow.  [ruby-dev:31763]\n\nSun Sep  9 09:14:45 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (_strptime): now also attaches an element\n\t  which denotes leftover substring if exists.\n\nSat Sep  8 10:22:20 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (rb_struct_s_members): should raise TypeError instead\n\t  of call rb_bug().  [ruby-dev:31709]\n\n\t* marshal.c (r_object0): no nil check require any more.\n\nSat Sep  8 09:38:19 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (str[fp]time): now check specifications more\n\t  strictly.\n\nFri Sep  7 05:36:19 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/rinda/test_rinda.rb (MockClock): correct synchronous problems\n\t  of the MultiThreading. [ruby-dev:31692]\n\nWed Sep  5 22:02:27 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_subseq): need integer overflow check.\n\t  [ruby-dev:31736]\n\n\t* array.c (rb_ary_splice): ditto.  [ruby-dev:31737]\n\n\t* array.c (rb_ary_fill): ditto.  [ruby-dev:31738]\n\n\t* string.c (rb_str_splice): integer overflow for length.\n\t  [ruby-dev:31739]\n\nSun Sep  2 00:48:15 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (_parse): improved parsing of ordinal dates.\n\n\t* lib/date/format.rb (_parse): use named character classes in some\n\t  regular expressions.\n\nSat Sep  1 08:13:36 2007  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c: add WIN32OLE#ole_activex_initialize.\n\nThu Aug 30 13:13:13 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (try_const, have_const): check for a const is defined.\n\t  [ruby-core:04422]\n\nThu Aug 30 13:10:57 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (group_member): check if presents.\n\n\t* configure.in (XCFLAGS): add _GNU_SOURCE on linux.\n\n\t* file.c (group_member): use system routine if available.\n\nThu Aug 30 08:24:18 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* ruby.h (RHASH_TBL): defined for compatibility to 1.9.\n\t* (RHASH_ITER_LEV): ditto.\n\t* (RHASH_IFNONE): ditto.\n\t* (RHASH_SIZE): ditto.\n\t* (RHASH_EMPTY_P): ditto.\n\nWed Aug 29 13:05:59 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* include/ruby/defines.h (flush_register_windows): call \"ta 0x03\"\n\t  even on Linux/Sparc.  [ruby-dev:31674]\n\nTue Aug 28 23:26:12 2007  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_type_progid, reg_enum_key,\n\t  reg_get_val, ole_wc2mb): fix the bug. Thanks, arton.\n\t  [ruby-dev:31576]\n\nMon Aug 27 19:10:50 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/etc/etc.c (etc_getlogin): update documentation to note\n\t  security issue.  [ruby-Bugs-11821]\n\nTue Aug 21 21:09:48 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/tmpdir.rb (Dir.mktmpdir): make directory suffix specifiable.\n\nTue Aug 21 13:57:04 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (st_foreach_func, rb_foreach_func): typedefed.\n\nMon Aug 20 17:25:33 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (mnew): should preserve noex as safe_level.\n\n\t* eval.c (rb_call0): tighten security check condition..\n\nSat Aug 18 21:32:20 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/tmpdir.rb (Dir.mktmpdir): new method.\n\t  [ruby-dev:31462]\n\nSat Aug 18 17:44:42 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/tk/tcltklib.c (Init_tcltklib): use rb_set_end_proc().\n\nSat Aug 18 15:59:52 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (detach_process_watcher): should not pass the pointer\n\t  to an auto variable to the thread to be created.  pointed and\n\t  fix by KUBO Takehiro <kubo at jiubao.org>  [ruby-dev:30618]\n\nSat Aug 18 12:24:30 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sample/test.rb, test/ruby/test_system.rb(valid_syntax?): keep\n\t  comment lines first.\n\nThu Aug 16 20:40:50 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bigtrunc): RBIGNUM(x)->len may be zero.  out of bound\n\t  access.  [ruby-dev:31404]\n\nThu Aug 16 16:46:07 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (aix): enable shared by default.\n\n\t* configure.in (aix): for 64bit-mode AIX.  [ruby-dev:31401]\n\t  + use CC for LDSHARED if non-gcc,\n\t  + moved -G option from *LDFLAGS to LDSHARED,\n\t  + set -brtl only in XLDFLAGS.\n\nThu Aug 16 13:06:08 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* bignum.c (big_lshift): make shift offset long type.\n\t  (big_rshift): ditto.\n\t  (rb_big_lshift): ditto.\n\t  (big_rshift): ditto.\n\t  [ruby-dev:31434]\n\nThu Aug 16 04:09:19 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (Rinda::TupleSpace#start_keeper): improve\n\t  keeper thread.\n\nWed Aug 15 13:50:10 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (rb_hash_delete_key): delete the entry without calling block.\n\n\t* hash.c (rb_hash_shift): should consider iter_lev too.\n\n\t* hash.c (delete_if_i): use rb_hash_delete_key() so that the block\n\t  isn't called twice.  [ruby-core:11556]\n\nSun Arg 12 03:56:30 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb: fix Rinda::TupleSpace keeper thread bug.\n\t  the thread is started too early. [ruby-talk:264062]\n\n\t* test/rinda/test_rinda.rb: ditto.\n\nSat Aug 11 07:34:10 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: reverted some wrongly erased \"o\" options\n\t  (pointed out by nobu).\n\nTue Aug  7 14:58:39 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/pty/pty.c (establishShell): handshaking before close slave\n\t  device.  [ruby-talk:263410]\n\n\t* ext/pty/pty.c (MasterDevice, SlaveDevice, deviceNo): constified.\n\n\t* ext/pty/pty.c (SlaveName): removed static buffer.\n\n\t* ext/pty/expect_sample.rb: support for autologin.\n\nTue Aug  7 12:45:13 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (ac_cv_func_isinf): set yes also on OpenSolaris.\n\t  [ruby-Bugs-12859]\n\nMon Aug  6 17:36:29 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rexml/encodings/{ISO-8859-15,CP-1252}.rb: fixed invalid syntax.\n\nFri Aug  3 11:05:54 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): save all CONFIG values.\n\n\t* ext/extmk.rb (extmake): remove mkmf.log at clean, and extconf.h at\n\t  distclean, respectively.\n\n\t* ext/extmk.rb: remove rdoc at clean, and installed list file at\n\t  distclean, respectively.\n\nFri Aug  3 07:09:05 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb: more verbose message.  [ruby-Bugs-12766]\n\n\t* lib/mkmf.rb (have_type): suppress a warning with -Wall.\n\n\t* lib/mkmf.rb (find_type): new method.\n\nThu Aug  2 13:46:39 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): should not check positional number as\n\t  width.  [ruby-core:11838]\n\nMon Jul 30 11:16:40 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_aref): check for Bignum index range.\n\t  [ruby-dev:31271]\n\nSat Jul 28 09:35:41 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/digest/lib/digest.rb (Digest::self.const_missing): avoid\n\t  infinite recursive const_missing call.  [ruby-talk:262193]\n\nThu Jul 26 13:57:45 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dln.c (load_1, dln_find_1): constified.\n\n\t* dln.c (conv_to_posix_path): removed.\n\n\t* ruby.c (usage): constified.\n\n\t* ruby.c (rubylib_mangled_path, rubylib_mangled_path2): return\n\t  VALUE instead of a pointer to static buffer.\n\n\t* ruby.c (push_include_cygwin): fixed buffer overflow.\n\t  [ruby-dev:31297]\n\n\t* ruby.c (ruby_init_loadpath): not convert built-in paths.\n\nSun Jul 22 16:07:12 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* intern.h (is_ruby_native_thread): removed since declared as an int\n\t  function in ruby.h already.\n\nSun Jul 22 14:33:40 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_rename): deleted code to get rid of a bug of\n\t  old Cygwin.\n\n\t* file.c (rb_file_truncate): added prototype of GetLastError()\n\t  on cygwin.  [ruby-dev:31239]\n\n\t* intern.h (is_ruby_native_thread): prototype.\n\n\t* missing/strftime.c (strftime): fix printf format and actual\n\t  arguments.\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): ditto.\n\n\t* ext/tk/tcltklib.c (ip_finalize): ditto.\n\n\t* ext/dl/ptr.c (rb_dlptr_inspect): ditto.  [ruby-dev:31268]\n\n\t* ext/dl/sym.c (rb_dlsym_inspect): ditto.\n\n\t* ext/socket/getnameinfo.c: include stdio.h always.\n\n\t* ext/win32ole/win32ole.c (ole_hresult2msg, folevariable_name,\n\t  folevariable_ole_type, folevariable_ole_type_detail,\n\t  folevariable_value, folemethod_visible): missing return value.\n\nSat Jul 21 17:48:26 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): make OBJS depend on RUBY_EXTCONF_H\n\t  only if extconf.h is created.\n\n\t* bcc32/{Makefile.sub,configure.bat,setup.mak: configure_args\n\t  support.\n\n\t* bcc32/setup.mak: check runtime version.\n\n\t* win32/win32.c (rb_w32_open_osfhandle): prototype has changed\n\t  in bcc 5.82.\n\n\t* {win32,wince,bcc32}/setup.mak (-version-): no RUBY_EXTERN magic.\n\n\t* win32/resource.rb: include patchlevel number.\n\nSat Jul 21 12:06:48 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (init_mkmf): should remove mkmf.log too.\n\nSat Jul 21 01:53:17 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (Date._parse): completes calendar week based year.\n\n\t* lib/date/format.rb (Date._parse): detects year of ordinal date in\n\t  extended format.\n\nFri Jul 20 15:22:51 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/openssl/ossl_config.c (ossl_config_set_section): do not\n\t  initialize aggregations with dynamic values.  [ruby-talk:259306]\n\nThu Jul 19 19:24:14 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (get_backtrace): check the result more.\n\t  [ruby-dev:31261] [ruby-bugs-12398]\n\nThu Jul 19 14:38:45 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_lshift, rb_big_rshift): separated functions\n\t  to get rid of infinite recursion.  fixed calculation in edge\n\t  cases.  [ruby-dev:31244]\n\n\t* numeric.c (rb_fix_lshift, rb_fix_rshift): ditto.\n\nWed Jul 18 16:57:41 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_pow): refine overflow check.  [ruby-dev:31242]\n\nWed Jul 18 08:47:09 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_succ): Time#succ should return a time object in the\n\t  same timezone mode to the original.  [ruby-talk:260256]\n\nTue Jul 17 00:50:53 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_pow): integer power calculation: 0**n => 0,\n\t  1**n => 1, -1**n => 1 (n: even) / -1 (n: odd).\n\n\t* test/ruby/test_fixnum.rb (TestFixnum::test_pow): update test\n\t  suite.  pow(-3, 2^64) gives NaN when pow(3, 2^64) gives Inf.\n\nMon Jul 16 23:07:51 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/base64.rb (Base64::b64encode): should not specify /o option\n\t  for regular expression.  [ruby-dev:31221]\n\nMon Jul 16 18:29:33 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_rindex_m): accept string-like object convertible\n\t  with #to_str method, as well as rb_str_index_m.  [ruby-core:11692]\n\nMon Jul 16 05:45:53 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): more checks for format argument.\n\t  [ruby-core:11569], [ruby-core:11570], [ruby-core:11571],\n\t  [ruby-core:11573]\n\nMon Jul 16 00:26:10 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_pow): removed invariant variable.  [ruby-dev:31236]\n\nSun Jul 15 23:59:57 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_neg): SIGNED_VALUE isn't in 1.8.\n\nSun Jul 15 22:24:49 2007  pegacorn  <subscriber.jp AT gmail.com>\n\n\t* ext/digest/digest.c (rb_digest_instance_update,\n\t  rb_digest_instance_finish, rb_digest_instance_reset,\n\t  rb_digest_instance_block_length): %s in rb_raise() expects char*.\n\t  [ruby-dev:31222]\n\n\t* ext/openssl/ossl.h: include ossl_pkcs5.h.  [ruby-dev:31231]\n\n\t* ext/openssl/ossl_pkcs5.h: new file for PKCS5.  [ruby-dev:31231]\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_to_s): use ossl_raise()\n\t  instead of rb_raise().  [ruby-dev:31222]\n\n\t* ext/sdbm/_sdbm.c: DOSISH platforms need io.h.  [ruby-dev:31232]\n\n\t* ext/syck/syck.h: include stdlib.h for malloc() and free().\n\t  [ruby-dev:31232]\n\n\t* ext/syck/syck.h (syck_parser_set_input_type): prototype added.\n\t  [ruby-dev:31231]\n\n\t* win32/win32.c: include mbstring.h for _mbspbrk().  [ruby-dev:31232]\n\n\t* win32.h (rb_w32_getcwd): prototype added.  [ruby-dev:31232]\n\nSun Jul 15 21:07:43 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (bigtrunc): do not empty Bignum.  [ruby-dev:31229]\n\nSun Jul 15 19:05:28 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_cstr_to_inum): check leading non-digits.\n\t  [ruby-core:11691]\n\nSun Jul 15 04:42:20 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (get2comp): do nothing for empty Bignum.  [ruby-dev:31225]\n\nSat Jul 14 14:04:06 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (sort_by_cmp): check if reentered.  [ruby-dev:24291]\n\nSat Jul 14 12:44:14 2007  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/openssl/test_pkcs7.rb: reverted the previous patch.  it should\n\t  be as it was to check interface compatibility.  sorry for bothering\n\t  with this.\n\nSat Jul 14 12:16:17 2007  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/openssl/test_pkcs7.rb: follow the library change.  applied a\n\t  patch from <zn at mbf.nifty.com> [ruby-dev:31214].\n\t  NOTE: r12496 imports the latest openssl libs from trunk to ruby_1_8\n\t  though its's not ChangeLog-ed.  maintainer should aware that.\n\nSat Jul 14 02:51:52 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_pow): 0**2 should not raise floating point\n\t  exception.  [ruby-dev:31216]\n\nSat Jul 14 02:25:48 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (int_pow): wrong overflow detection.  [ruby-dev:31213]\n\n\t* numeric.c (int_pow): wrong overflow detection.  [ruby-dev:31215]\n\nFri Jul 13 16:10:00 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): use ENV.to_hash to access\n\t  http_proxy environment variable to avoid case insensitive\n\t  environment search.\n\nFri Jul 13 15:02:15 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (CreateChild): enclose command line except for\n\t  command.com which can not handle quotes.  [ruby-talk:258939]\n\nFri Jul 13 10:10:46 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (link_command, cc_command, cpp_command): do not expand\n\t  ::CONFIG which is an alias of MAKEFILE_CONFIG.\n\nThu Jul 12 17:03:15 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* struct.c (rb_struct_init_copy): disallow changing the size.\n\t  [ruby-dev:31168]\n\nWed Jul 11 23:38:14 2007  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* random.c: documentation fix.  srand(0) initializes PRNG with '0',\n\t  not with random_seed.\n\nTue Jul 10 14:50:01 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bcc32/{Makefile.sub,setup.mak}: remove surplus slash from srcdir.\n\nFri Jul  6 15:22:58 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_interrupt): suppress a gcc's officious warning.\n\nThu Jul  5 16:44:28 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* numeric.c (int_pow): fix previous nubu's commit.\n\n\t* test/ruby/test_fixnum.rb: new test.\n\nThu Jul  5 15:56:06 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (int_pow): even number multiplication never be negative.\n\nMon Jul  2 14:34:43 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): sign bit extension should not be done\n\t  if FPLUS flag is specified.  [ruby-list:39224]\n\nSat Jun 30 16:05:41 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_initialize): should call rb_ary_modify() first.\n\t  [ruby-core:11562]\n\nSat Jun 30 00:17:00 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (yylex): return non-valid token for an invalid\n\t  instance/class variable name.  a patch from Yusuke ENDOH\n\t  <mame AT tsg.ne.jp>.  [ruby-dev:31095]\n\nFri Jun 29 11:23:09 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (dsym): return non-null NODE even if yyerror().  based on a\n\t  patch from Yusuke ENDOH <mame AT tsg.ne.jp>.  [ruby-dev:31085]\n\nTue Jun 26 16:35:21 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (ruby_setreuid, ruby_setregid): rename to get rid of name\n\t  clash.\n\n\t* process.c (proc_exec_v, rb_proc_exec): preserve errno.\n\nSat Jun 23 00:37:46 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_select): remove unnecessary varargs for\n\t  rb_hash_select.  a patch from Daniel Berger\n\t  <Daniel.Berger at qwest.com>.   [ruby-core:11527]\n\n\t* hash.c: ditto.\n\nMon Jun 18 08:47:54 2007  Technorama Ltd.  <oss-ruby@technorama.net>\n\n\t* ext/openssl/{extconf.rb,ossl_ssl_session.c}:\n\t  Fix ruby-Bugs-11513.\n\n\t* ext/openssl/ossl_pkey_ec.c\n\t  New methods EC::Point.[eql,make_affine!,invert!,on_curve?,infinity?]\n\t  By default output the same key form as the openssl command.\n\n\t* ext/openssl/ossl_rand.c\n\t  New method Random.status?\n\nMon Jun 18 13:54:36 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): return EXIT_FAILURE if any exceptions occured\n\t  in at_exit blocks.  [ruby-core:11263]\n\nMon Jun 18 01:14:10 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* variable.c (rb_path2class): get rid of dangling pointer caused by\n\t  optimized out value.\n\n\t* variable.c (rb_global_entry, rb_f_untrace_var, rb_alias_variable,\n\t  rb_generic_ivar_table, generic_ivar_get, generic_ivar_set,\n\t  generic_ivar_defined, generic_ivar_remove, rb_mark_generic_ivar,\n\t  rb_free_generic_ivar, rb_copy_generic_ivar,\n\t  rb_obj_instance_variables): suppress warnings.\n\nFri Jun 15 22:33:29 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (realclean): separate local and ext.\n\n\t* ext/extmk.rb: not remove unrelated directories.\n\nFri Jun 15 17:01:20 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/dl/lib/dl/win32.rb: seems that dl doesn't accept void argument.\n\t  fixed [ruby-bugs:PR#5489].\n\nThu Jun 14 17:09:48 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser): handle more\n\t  extensions.  [ruby-dev:30972]\n\nWed Jun 13 06:05:12 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (darwin): prohibit loading extension libraries to\n\t  miniruby.\n\nWed Jun 13 05:47:58 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_kill_thread): renamed in order to get rid of conflict\n\t  with a BeOS system function.  [ruby-core:10830]\n\nTue Jun 12 14:53:51 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (Logging.quiet, Logging.message): added quiet flag and\n\t  use it.  [ruby-core:10909]\n\n\t* lib/mkmf.rb (find_header): use header names in the message.\n\nSun Jun 10 13:47:36 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/ruby/test_beginendblock.rb (test_should_propagate_signaled):\n\t  get rid of invoking shell.  [ruby-dev:30942]\n\nThu Jun  7 19:02:48 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* lib/pp.rb: call original \"method\" method instead of redefined one.\n\nMon Jun  4 11:11:12 2007  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (ResponseParser#next_token): fixed\n\t  error message. (backported from HEAD)\n\n\t* lib/net/imap.rb (ResponseParser#parse_error): fixed\n\t  the condition not to refer @token.symbol unexpectedly.\n\t  Thanks, Dick Monahan. (backported from HEAD)\n\nThu May 31 17:27:53 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/benchmark.rb (Benchmark::Job::item): avoid modifying the\n\t  argument unintentionally.  [ruby-talk:253676]\n\nThu May 31 02:12:32 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (Rinda::TupleBag): create index on tuple bag\n\t  by first column.\n\nWed May 30 13:27:40 2007  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (Net::FTP#transfercmd): skip 2XX\n\t  responses for some FTP servers. (backported from HEAD)\n\nWed May 30 05:17:55 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): get rid of SEGV at ZSUPER in a block\n\t  [ruby-dev:30836]\n\nWed May 30 04:29:43 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (thread_timer): timer thread should not receive any\n\t  signals.  submitted by Sylvain Joyeux.  [ruby-core:08546]\n\nWed May 30 04:18:37 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval_cmd): just return if no exceptions.\n\t  [ruby-dev:30820]\n\nTue May 29 11:01:06 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_opendir): store attributes of the second\n\t  entries or later too.\n\n\t* win32/win32.c (rb_w32_opendir, rb_w32_readdir): eliminate magic\n\t  numbers.\n\nMon May 28 02:54:05 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (Rinda::TupleBag#delete): use rindex and\n\t  delete_at instead of delete for little improvement.\n\nSat May 26 00:05:22 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/ruby/test_beginendblock.rb (test_should_propagate_signaled):\n\t  skip tests for exitstatus and termsig on the platforms where\n\t  signals not supported.\n\nWed May 23 06:51:46 2007  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI#[]): get rid of exceptions being raised.\n\t  [ruby-dev:30740], Thanks Kentaro KAWAMOTO.\n\nWed May 23 05:49:49 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb, ext/purelib.rb, lib/mkmf.rb, runruby.rb: clear default\n\t  load path to get rid of load pre-installed extensions/libraries.\n\t  [ruby-core:11017]\n\nSat May 19 10:29:18 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (Date._parse): detects some OFX dates\n\t  (Of course not fully).\n\nFri May 18 23:07:33 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_first): call rb_ary_subseq() instead of pushing\n\t  values by itself.  [ruby-talk:252062]\n\n\t* array.c (rb_ary_first): add negative length check.\n\nFri May 18 17:10:31 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (move_to_next_entry): loc also must move forward.\n\t  [ruby-talk:251987]\n\nFri May 18 03:02:40 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/mkexports.rb: preserve prefixed underscores for WINAPI\n\t  symbols.\n\n\t* wince/mkconfig_wce.rb, wince/mkexports.rb: obsolete.\n\nThu May 17 17:03:11 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-style.el (ruby-style-label-indent): for yacc rules.\n\nTue May 15 14:54:07 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (init_stdhandle): stderr should be without buffering,\n\t  but mswin32 use buffering when stderr is not connected to tty.\n\nMon May 14 13:28:03 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/thread/thread.c (wait_list): supress a warning.\n\nThu May 10 15:21:51 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_s_conv): rdoc fix.\n\nThu May 10 10:14:14 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_priority): rdoc fix; the initial value is\n\t  inherited from the creating thread.  [ruby-core:10607]\n\nWed May  9 12:28:57 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (Init_Bignum), numeric.c (Init_Numeric): added fdiv as\n\t  aliases of quo.  [ruby-dev:30771]\n\nWed May  9 11:55:15 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_quo): now calculate in integer.  [ruby-dev:30753]\n\nWed May  9 11:51:06 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big_pow): reduce multiplying for even number.\n\n\t* bignum.c (rb_big_pow): truncate all zero BDIGITs. [ruby-dev:30733]\n\n\t* bignum.c (rb_big_pow): improvement by calculating from MSB and using\n\t  factorization.  <http://yowaken.dip.jp/tdiary/20070426.html#p01>\n\n\t* numeric.c (int_pow): calculate power in Fixnum as possible.\n\t  [ruby-dev:30726]\n\nTue May  8 23:42:51 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (Date._parse): revised treatment of\n\t  hyphened/separatorless dates.\n\n\t* lib/date/format.rb: some trivial adjustments.\n\nTue May  8 20:25:05 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: reverted.\n\nSat May  5 16:26:33 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/date/format.rb (Format::Bag#method_missing): get rid of\n\t  modifying orginal argument.  [ruby-core:11090]\n\nMon Apr 30 01:17:51 2007  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (TupleSpace#create_entry, TupleBag#push,\n\t  delete): extract method, and rename parameter.\n\nFri Apr 27 02:00:17 2007  Ryan Davis  <ryand-ruby@zenspider.com>\n\n\t* signal.c: Fixed backwards compatibility for 'raise Interrupt'.\n\n\t* lib/yaml/tag.rb: Running rdoc over the 1.8.6 tree skips\n\t  Module. Patch from James Britt\n\nThu Apr 26 13:54:51 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-style.el: new file.  C/C++ style for ruby source code.\n\nWed Apr 25 19:49:16 2007  Tanaka Akira  <akr@fsij.org>\n\n\t* ext/socket/socket.c (unix_send_io, unix_recv_io): use CMSG_DATA to\n\t  align file descriptor appropriately.\n\nTue Apr 24 09:33:57 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (do_stat, do_lstat, do_opendir): should not warn ENOTDIR.\n\t  [ruby-talk:248288]\n\nMon Apr 23 22:14:42 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb ($ruby): add extout directory to include path.\n\t  [ruby-core:11003]\n\n\t* lib/mkmf.rb (libpathflag): not to append RPATHFLAG to current\n\t  directory.\n\n\t* lib/mkmf.rb (init_mkmf): add current directory to default\n\t  library path with highest priority.  [ruby-core:10960]\n\n\t* lib/mkmf.rb (LINK_SO): LIBPATH to be placed before DLDFLAGS.\n\nFri Apr 20 16:05:22 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (LIBPATHFLAG, RPATHFLAG): no needs to be quoted,\n\t  it is done by libpathflag in mkmf.rb.\n\nFri Apr 20 12:27:04 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb: fix to override conv proc.\n\nFri Apr 20 12:17:05 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): inversed the order of errinfos.\n\nThu Apr 19 14:53:32 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/monitor.rb (ConditionVariable#wait, mon_enter, mon_exit_for_cond):\n\t  ensures Thread.critical to be false.  [ruby-talk:248300]\n\nWed Apr 18 10:41:21 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.c (ruby_strtod): exponent is radix 10.  [ruby-talk:248272]\n\nWed Apr 18 02:30:24 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (LDFLAGS): prepend -L. instead appending it to\n\t  XLDFLAGS.  [ruby-core:10933]\n\n\t* configure.in (Makefile): remove $U for automake from MISSING.\n\t  [ruby-talk:248171]\n\nTue Apr 17 16:46:46 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): should not clear state on TAG_NEXT when\n\t  it's invoked from within lambda body.  [ruby-talk:248136]\n\n\t* eval.c (proc_invoke): handle TAG_NEXT which would be caused by\n\t  next in the lambda body as well.\n\nMon Apr 16 22:56:01 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/pty/expect_sample.rb: avoid symbolic link representation for\n\t  expect.  a patch from Kazuhiro NISHIYAMA <zn at mbf.nifty.com>.\n\t  [ruby-dev:30714]\n\nMon Apr 16 22:51:11 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sample: replace TRUE, FALSE with true, false respectively.\n\t  a patch from Kazuhiro NISHIYAMA <zn at mbf.nifty.com>.\n\t  [ruby-dev:30713]\n\nMon Apr 16 17:08:02 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (make_switch): do not clobber converter if pattern\n\t  has no convert method.  reported by sheepman in [ruby-dev:30709].\n\nMon Apr 16 16:49:32 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_seek): consistent behavior with\n\t  IO#seek.  patch by sheepman in [ruby-dev:30710].\n\nMon Apr 16 16:34:08 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (parser_yylex): should set command_start after block\n\t  starting \"do\"s and braces.  [ruby-core:10916]\n\nSun Apr 15 09:19:57 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: added some zone names.\n\n\t* lib/date/format.rb (_parse): now interprets doted numerical\n\t  dates as a big endian (except dd.mm.yyyy).\n\nTue Apr 10 17:37:36 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_fclose, rb_w32_close): need to save errno\n\t  before calling original fclose()/close().\n\nMon Apr  9 09:30:44 2007  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (disconnect): call shutdown for\n\t  SSLSocket. Thanks, Technorama Ltd.\n\nThu Apr  5 00:42:48 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* error.c (rb_notimplement), io.c (pipe_open): removed definite\n\t  articles and UNIX manual section from messages.  [ruby-dev:30690]\n\nWed Apr  4 17:09:17 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (pipe_open): refined the message of NotImplementedError.\n\t  [ruby-dev:30685]\n\nWed Apr  4 10:18:04 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (pipe_open): raise NotImplementedError for command \"-\" on\n\t  platforms where fork(2) is not available.  [ruby-dev:30681]\n\nTue Apr  3 15:45:41 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (s_recv, s_recvfrom): some systems (such as\n\t  windows) doesn't set fromlen if the socket is connection-oriented.\n\t  reported by Bram Whillock in [ruby-core:10512] [ruby-Bugs#9061]\n\nSat Mar 24 23:40:29 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* node.h (struct rb_thread.locals): explicit as struct.\n\t  [ruby-core:10585]\n\n\t* eval.c, node.h (enum rb_thread_status, struct rb_thread,\n\t  rb_curr_thread, rb_main_thread): prefixed.  [ruby-core:10586]\n\n\t* file.c (chompdirsep): made an unprefixed name static.\n\n\t* io.c (io_fread): ditto.\n\nSat Mar 24 01:54:03 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): exit by SystemExit and SignalException in END\n\t  block.  [ruby-core:10609]\n\n\t* test/ruby/test_beginendblock.rb (test_should_propagate_exit_code):\n\t  test for exit in END block.  [ruby-core:10760]\n\n\t* test/ruby/test_beginendblock.rb (test_should_propagate_signaled):\n\t  test for signal in END block.\n\nThu Mar 22 23:13:17 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_provided): check for extension library if SOEXT is\n\t  explicitly given.  [ruby-dev:30657]\n\nThu Mar 22 10:29:25 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/ruby/test_bignum.rb (test_to_s): add tests for Bignum#to_s.\n\nWed Mar 21 17:04:30 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bignum.c (rb_big2str0): round up for the most significant digit.\n\t  [ruby-core:10686]\n\nWed Mar 21 07:21:24 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c (remove_one): Preserve List invariants;\n\t  submitted by: MenTaLguY <mental AT rydia.net>\n\t  in [ruby-core:10598] and [ruby-bugs:PR#9388].\n\nTue Mar 20 22:54:50 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_extended): erroneous check condition when dump\n\t  method is defined.  [ruby-core:10646]\n\nTue Mar 20 15:37:24 2007  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* distruby.rb: Add zip generation.\n\nTue Mar 20 11:28:41 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/matrix.rb (Matrix::inverse_from): adding partial pivoting to\n\t  the Gauss-Jordan algorithm, making it stable.  a patch from\n\t  Peter Vanbroekhoven.  [ruby-core:10641]\n\nMon Mar 19 11:39:29 2007  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb (rbuf_read): extend buffer size for speed.\n\nSun Mar 18 04:23:52 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Add a note about the new `date' library defining\n\t  Time#to_date and Time#to_datetime private methods.\n\n\t* NEWS: Inform that the old `thread' library is considered to be\n\t  stable.\n\n\t* NEWS: Sort library entries in alphabetical order.\n\nFri Mar 16 21:48:11 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dl/dl.c (rb_ary2cary): Fix a bug in type validation;\n\t  submitted by sheepman <sheepman AT sheepman.sakura.ne.jp>\n\t  in [ruby-dev:30554].\n\nFri Mar 16 18:28:06 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/etc/etc.c (etc_getgrgid): Fix a bug in Etc::getgrgid()\n\t  always returning the (real) group entry of the running process;\n\t  reported by: UEDA Hiroyuki <ueda AT netforest.ad.jp>\n\t  in [ruby-dev:30586].\n\nFri Mar 16 16:33:58 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c (unlock_mutex_inner): Make sure that the\n\t  given mutex is actually owned by the caller; submitted by:\n\t  Sylvain Joyeux <sylvain.joyeux AT m4x.org> in [ruby-core:10598].\n\nFri Mar 16 16:21:35 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c (wait_condvar, lock_mutex): Fix a problem in\n\t  ConditionVariable#wait that occurs when two threads that are\n\t  trying to access the condition variable are also in concurrence\n\t  for the given mutex; submitted by: Sylvain Joyeux\n\t  <sylvain.joyeux AT m4x.org> and MenTaLguY <mental AT rydia.net>\n\t  in [ruby-core:10598].\n\nFri Mar 16 16:17:27 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* test/thread/test_thread.rb: Add a test script for the `thread'\n\t  library.  This should result in failure as of now with\n\t  ext/thread; submitted by: Sylvain Joyeux <sylvain.joyeux AT\n\t  m4x.org> in [ruby-core:10598].\n\nWed Mar 14 12:30:00 2007  Shigeo Kobayashi  <shigeo@tinyforest.jp>\n\n\t* ext/bigdecimal/bigdecimal.c: BigDecimal(\"-.31\") is now\n\t  treated as (\"-0.31\") not as (\"0.31\").\n\nTue Mar 13 09:25:10 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (clear-installed-list): separated from install-prereq.\n\nTue Mar 13 06:38:43 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Reword and improve entries.\n\nTue Mar 13 06:03:46 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* stable version 1.8.6 released from the ruby_1_8_6 branch.\n\nTue Mar 13 03:24:07 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* runruby.rb: added --pure (turned on by default) and --debugger\n\t  options.\n\nTue Mar 13 02:50:28 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/cgi.rb (CGI::header): IIS >= 5.0 does not need the nph\n\t  assumption any more; submitted by MIYASAKA Masaru <alkaid AT\n\t  coral.ocn.ne.jp> in [ruby-dev:30537].\n\nMon Mar 12 11:07:44 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/openssl/ossl_asn1.c (Init_ossl_asn1): Let rdoc know about\n\t  externally defined modules; submitted by Technorama\n\t  Ltd. <oss-ruby AT technorama.net> in [ruby-bugs:PR#4704].\n\n\t* ext/openssl/ossl_bn.c (Init_ossl_bn): Ditto.\n\n\t* ext/openssl/ossl_cipher.c (Init_ossl_cipher): Ditto.\n\n\t* ext/openssl/ossl_digest.c (Init_ossl_digest): Ditto.\n\n\t* ext/openssl/ossl_hmac.c (Init_ossl_hmac): Ditto.\n\n\t* ext/openssl/ossl_pkey.c (Init_ossl_pkey): Ditto.\n\n\t* ext/openssl/ossl_pkey_dh.c (Init_ossl_dh): Ditto.\n\n\t* ext/openssl/ossl_pkey_dsa.c (Init_ossl_dsa): Ditto.\n\n\t* ext/openssl/ossl_pkey_rsa.c (Init_ossl_rsa): Ditto.\n\n\t* ext/openssl/ossl_rand.c (Init_ossl_rand): Ditto.\n\n\t* ext/openssl/ossl_ssl.c (Init_ossl_ssl): Ditto.\n\nMon Mar 12 01:05:17 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dl/sym.c (rb_dlsym_inspect): Use \"0x%x\" rather for pointers.\n\t  This might not be very right but it is commonly used in other\n\t  parts of the code; submitted by sheepman <sheepman AT\n\t  sheepman.sakura.ne.jp> in [ruby-dev:30532].\n\n\t* ext/dl/ptr.c (rb_dlptr_inspect): Ditto.\n\nMon Mar 12 00:59:19 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dl/lib/dl/import.rb (DL::Importable::Internal::import,\n\t  DL::Importable::Internal::callback): Avoid race condition for an\n\t  instance variable; submitted by sheepman <sheepman AT\n\t  sheepman.sakura.ne.jp> in [ruby-dev:30530].\n\nSun Mar 11 18:57:50 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* misc/README: Add a note about ruby-electric.el.\n\n\t* misc/ruby-mode.el (ruby-non-block-do-re): Fix\n\t  ruby-non-block-do-re. [ruby-core:03719]\n\n\t* misc/inf-ruby.el: Synchronize the comment section with trunk.\n\n\t* misc/README, misc/rdebug.el: Add rdebug.el, Emacs ruby-debug\n\t  interface based on rubydb3x.el; submitted by Martin Nordholts\n\t  <enselic AT gmail.com> in [ruby-bugs:PR#9023].\n\nSun Mar 11 17:45:51 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dl/mkcallback.rb (mkfunc): Make sure that a callback\n\t  function is found in the function table before trying to call\n\t  it; submitted by sheepman <sheepman AT sheepman.sakura.ne.jp>\n\t  in [ruby-dev:30524].\n\nSun Mar 11 12:09:37 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (error_handle): no message when exiting by signal.\n\n\t* eval.c (ruby_cleanup): re-send signal.  [ruby-dev:30516]\n\n\t* eval.c (rb_thread_interrupt): instantiate SignalException.\n\n\t* eval.c (rb_thread_signal_raise): now takes signal number instead\n\t  of signal name.\n\n\t* intern.h (rb_thread_signal_raise, ruby_default_signal): prototypes.\n\n\t* signal.c (esignal_init): takes a signal number and an optional\n\t  signal name.\n\n\t* signal.c (interrupt_init): pass SIGINT always.\n\n\t* signal.c (ruby_default_signal): invoke system default signal\n\t  handler.\n\n\t* signal.c (rb_signal_exec, trap): handle SIGTERM.  [ruby-dev:30505]\n\nTue Mar  6 19:08:46 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/lib/md5.rb (MD5::new, MD5::md5): Do not modify\n\t  Digest::MD5.\n\n\t* ext/digest/lib/sha1.rb (SHA1::new, SHA1::sha1): Ditto.\n\nTue Mar  6 18:58:37 2007  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/shell/process-controller.rb: fix thread synchronization\n\t  problem for [ruby-dev:30477].\n\nTue Mar  6 18:44:26 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/lib/md5.rb (MD5::new, MD5::md5): Catch up with\n\t  Digest's API changes; noted by: Kazuhiro Yoshida <moriq AT\n\t  moriq.com> in [ruby-dev:30500].\n\n\t* ext/digest/lib/sha1.rb (SHA1::new, SHA1::sha1): Ditto.\n\nTue Mar  6 18:24:19 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* time.c (time_to_s): Back out the format changes; discussed\n\t  in [ruby-dev:30495].\n\nTue Mar  6 11:53:25 2007  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/irbtkw.rbw: fails to exit process.\n\nMon Mar  5 20:14:49 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* time.c (time_to_s): Correct the wrong format which did not\n\t  really conform to RFC 2822; pointed out by: OHARA Shigeki <os at\n\t  iij.ad.jp> in [ruby-dev:30487].\n\nSun Mar  4 23:38:07 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_stat_s_utime): fixed a commit miss for the platforms\n\t  where utimes() does not exist.\n\n\t* lib/fileutils.rb (touch): ditto.\n\nSun Mar  4 14:46:56 2007  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* util.c (push_element): should return a int value.\n\nSun Mar  4 01:05:57 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb (Set#^, Set#&): Correct documentation.  Those methods\n\t  return sets, not arrays; noted by Oliver Frank Wittich <nietz AT\n\t  mangabrain.de>.\n\nSat Mar  3 23:01:07 2007  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mv): could not move a directory between\n\t  different filesystems. [ruby-dev:30411]\n\nSat Mar  3 22:57:11 2007  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (touch): last commit causes error if :mtime\n\t  option was not given.\n\nSat Mar  3 22:37:02 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_utime): allow nil to set the current time.\n\n\t* lib/fileutils.rb (touch): ditto, and added :mtime and :nocreate\n\t  options.  fixed: [ruby-talk:219037]\n\nSat Mar  3 21:17:35 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c (stack_check): Unset inline to fix build with GCC 3.4.6;\n\t  submitted by: NISHIMATSU Takeshi <t_nissie AT yahoo.co.jp> in\n\t  [ruby-list:43218].\n\t  cf. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24556\n\nSat Mar  3 19:05:31 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c (push_list): Use ALLOC().\n\n\t* ext/thread/thread.c (rb_mutex_alloc): Ditto.\n\n\t* ext/thread/thread.c (rb_condvar_alloc): Ditto.\n\nSat Mar  3 18:53:11 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Add a note for String#intern.\n\nSat Mar  3 16:23:13 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* env.h (SCOPE_CLONE): Introduce a new scope flag to prevent a\n\t  local_tbl region from getting freed many times; submitted by\n\t  Chikanaga Tomoyuki <chikanag AT nippon-control-system.co.jp> in\n\t  [ruby-dev:30460].\n\n\t* eval.c (proc_invoke): Ditto.\n\n\t* gc.c (obj_free): Ditto.\n\n\t* parse.y (top_local_setup_gen): Ditto.\n\nSat Mar  3 16:07:02 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* object.c (rb_obj_ivar_set): RDoc updated according to a\n\t  suggestion from Brian Candler <B.Candler AT pobox.com>.\n\t  [ruby-core:10469]\n\nThu Mar  1 21:38:07 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (stmt, arg): should not omit lhs of OP_ASGN1 even if\n\t  empty.  [ruby-dev:30455]\n\nThu Mar  1 08:55:38 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_feature_p): check loading_tbl if the given ext is\n\t  empty.  [ruby-dev:30452]\n\n\t* eval.c (rb_feature_p): fix possible buffer overrun.\n\nThu Mar  1 03:30:21 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/digest.c (get_digest_base_metadata): Allow inheriting\n\t  Digest::Base subclasses, which was unintentionally made\n\t  impossible while restructuring Digest classes.\n\nThu Mar  1 02:05:17 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* mkconfig.rb (patchlevel): read from version.h.\n\nThu Mar  1 00:09:39 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_provided): return true only for features loaded from\n\t  .rb files, and not search actual library type.  [ruby-dev:30414]\n\nWed Feb 28 21:15:00 2007  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (ac_cv_func_fcntl): fcntl support for MinGW.\n\n\t* missing/flock.c: workaround for MinGW.\n\nWed Feb 28 20:51:32 2007  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* pack.c (pack_unpack): properly ignore non-base64 octets such as\n\t  UTF-8 encoded BOMs; submitted by SOUMA Yutaka <holon@radastery.jp>\n\t  to fix [ruby-core:10437]\n\nWed Feb 28 18:59:57 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* NEWS: Add NEWS, a document file to keep user visible feature\n\t  changes between releases.\n\nWed Feb 28 18:35:50 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/openssl/extconf.rb: no need to check unistd.h and sys/time.h.\n\t  they are already checked at configure.\n\t  reported by KOBAYASHI Yasuhiro [ruby-list:43225]\n\nWed Feb 28 18:34:48 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb ($DEFLIBPATH): default library paths ($(topdir), etc)\n\t  should be the first elements of library paths list.\n\t  reported by KOBAYASHI Yasuhiro [ruby-list:43225]\n\nWed Feb 28 18:31:32 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* doc/NEWS-1.8.0: Rename NEWS to NEWS-1.8.0.  This is way too old\n\t  NEWS.\n\nWed Feb 28 01:22:58 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/{dbm,gdbm}/test_{dbm,gdbm}.rb: shouldn't use host_os. use\n\t  target_os instead. reported by KOBAYASHI Yasuhiro [ruby-list:43225]\n\nWed Feb 28 00:08:11 2007  URABE Shyouhei  <shyouhei@ice.uec.ac.jp>\n\n\t* mkconfig.rb (RbConfig): add CONFIG['PATCHLEVEL']\n\n\t* common.mk: new target dist\n\n\t* distruby.rb: new file\n\nTue Feb 27 22:18:45 2007  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (--enable-auto-image-base): avoid the neccessity to\n\t  rebase the shared libs as much as possible;\n\t  submitted by Corinna Vinschen <spam at vinschen.de> in\n\t  [ruby-talk:240964].\n\nTue Feb 27 21:36:47 2007  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* util.c (__crt0_glob_function): use ruby_glob() instead of rb_globi().\n\nTue Feb 27 21:33:04 2007  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (ac_cv_func_setrlimit): workaround for djgpp.\n\nTue Feb 27 19:38:52 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/base64.rb (Base64::b64encode): Fix documentation; submitted\n\t  by David Symonds <dsymonds@gmail.com> in [ruby-core:10432].\n\nTue Feb 27 19:36:57 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* regex.c (calculate_must_string, slow_search, re_search): Silence\n\t  warnings regarding char * vs. unsigned char * mismatch;\n\t  submitted by Lyle Johnson <lyle.johnson@gmail.com>\n\t  in [ruby-core:10416].\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_load): Ditto.\n\n\t* ext/digest/sha1/sha1ossl.c (SHA1_Finish): Ditto.\n\n\t* ext/digest/rmd160/rmd160ossl.c (RMD160_Finish): Ditto.\n\n\t* ext/digest/digest.c (rb_digest_base_finish,\n\t  rb_digest_base_update): Ditto.\n\n\t* ext/nkf/nkf.c (rb_str_resize, rb_nkf_kconv, rb_nkf_guess1,\n\t  rb_nkf_guess2): Ditto.\n\nTue Feb 27 03:40:09 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c (wait_list_cleanup, rb_mutex_try_lock):\n\t  Eliminate rb_thread_critical switching where unnecessary;\n\t  implied by shugo in [ruby-dev:30412].\n\n\t* ext/thread/thread.c (set_critical): Merge in\n\t  thread_exclusive_ensure().\n\n\t* ext/thread/thread.c: Consistently use 0 and 1 for\n\t  rb_thread_critical values.\n\nMon Feb 26 15:18:23 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c: Use xmalloc()/xfree() instead of\n\t  malloc()/free(); pointed out by shugo in [ruby-dev:30412].\n\nSun Feb 25 23:02:55 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner::initialize):\n\t  Initialize @workdir properly to silence a warning under -w.\n\t  Submitted by <tommy at tmtm.org> in [ruby-dev:30400].\n\nSun Feb 25 02:47:43 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* defines.h: Pull the RUBY_MBCHAR_MAXSIZE definition from trunk,\n\t  which is necessary for dir.c to compile on djgpp and emx.\n\nSat Feb 24 10:42:01 2007  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/racc/cparse/cparse.c (cparse_params_mark): remove useless\n\t  rb_gc_mark.  Thanks Tomoyuki Chikanaga. [ruby-dev:30405]\n\nFri Feb 23 15:10:46 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (set_pioinfo_extra): new function for VC++8 SP1\n\t  workaround. [ruby-core:10259]\n\n\t* win32/win32.c (NtInitialize): call above function.\n\nFri Feb 23 14:19:40 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* signal.c (sighandler): need to tell to be interrupted to main\n\t  context when handler is installed.\n\n\t* win32/win32.[ch] (rb_win32_interrupted): new function to listen\n\t  interrupt.\n\nFri Feb 23 13:02:17 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* numeric.c (fix_cmp, fix_equal): Remove FIX2LONG() to optimize.\n\t  suggested in\n\t  http://t-a-w.blogspot.com/2007/02/making-ruby-faster.html.\n\t  [ruby-talk:240223]\n\nFri Feb 23 12:43:17 2007  James Edward Gray II  <james@grayproductions.net>\n\n\t* lib/xmlrpc/client.rb (XMLRPC::Client::do_rpc): Make the\n\t  Content-Length parameter optional for responses in\n\t  xmlrpc/client.rb; suggested by Daniel Berger\n\t  <Daniel.Berger@qwest.com> and approved by the maintainer.\n\n\t* lib/xmlrpc/create.rb (XMLRPC::Create::conv2value): Add DateTime\n\t  support to xmlrpc; approved by the maintainer.\n\nMon Feb 19 18:22:52 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in, defines.h, eval.c (rb_feature_p, rb_provided,\n\t  load_wait, search_required, rb_require_safe), ext/extmk.rb: Fix\n\t  a bug where a statically linked extension cannot be autoloaded.\n\t  [ruby-dev:30023] / [ruby-dev:30239]\n\nMon Feb 19 17:14:28 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (unix_peeraddr): wrong syscall name in error\n\t  message for #peeraddr. a patch from Sam Roberts\n\t  <sroberts at uniserve.com>.  [ruby-core:10366]\n\nSun Feb 18 19:35:21 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: updated based on date2 4.0.3.\n\nFri Feb 16 11:18:21 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/.document: Apply patch for irb, e2mmap and README by Hugh Sasse\n\t  <hgs at dmu.ac.uk> from [ruby-core:10135]\n\n\t* lib/prettyprint.rb: Suppress RDoc for PrettyPrint test suite.\n\nThu Feb 15 20:26:30 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/uri/ftp.rb: Revert the previous change pending discussion.\n\nThu Feb 15 18:08:17 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* dir.c (glob_helper): Fix the function declaration.\n\nThu Feb 15 17:13:32 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* version.h: Welcome to the post-1.8.6 world.  Radical changes are\n\t  inhibited in the ruby_1_8 branch until the 1.8.6 final release\n\t  goes out of the door.\n\nThu Feb 15 16:44:14 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/uri/generic.rb (URI::Generic::userinfo): Considering how\n\t  `scheme://user:@...', `scheme://:password@...' and\n\t  `scheme://:@...' are parsed, an empty user name or password\n\t  should be allowed and represented as it is.\n\nThu Feb 15 11:46:05 2007  KIMURA Koichi  <hogemuta@gmail.com>\n\n\t* dir.c, win32/win32.c, win32/dir.h, ruby.h, intern.h: Bring\n\t  encoding aware globbing support in from trunk.  Dir.[] and\n\t  Dir.glob() can now take many patterns in an array.  Minor fixes\n\t  will follow.\n\nThu Feb 15 11:00:26 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/uri/generic.rb (URI::Generic::userinfo): should support\n\t  empty password.  [ruby-core:10290]\n\n\t* lib/uri/generic.rb (URI::Generic::set_password): password can be\n\t  cleared by nil.  [ruby-core:10290]\n\n\t* lib/uri/common.rb (escape): regard second string argument as a\n\t  character set properly. [ruby-dev:27692]\n\n\t* lib/uri/ftp.rb: Attempt to conform to RFC 1738 with regard to\n\t  relative/absolute paths.\n\n\t* lib/uri: Lovely RDOC patches from mathew (metaATpoboxDOTcom).\n\nThu Feb 15 10:57:38 2007  Tietew  <tietew@tietew.net>>\n\n\t* lib/cgi.rb (CGI::unescapeHTML): invalid decoding for single\n\t  unescaped ampersand.  a patch from Tietew\n\t  <tietew+ruby-dev at tietew.net> in [ruby-dev:30292].\n\t  fixed: [ruby-dev:30289]\n\nThu Feb 15 10:48:40 2007  MenTaLguY  <mental@rydia.net>\n\n\t* ext/thread/thread.c: Handle interrupted waits correctly.\n\t  [ruby-bugs:PR#8663]\n\nWed Feb 14 19:22:15 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/lib/digest.rb (Digest::self.const_missing): Drop\n\t  autoloads for sha2 classes in favor of handling in\n\t  const_missing(), to work around a problem exposed on OS X.\n\nTue Feb 13 02:21:12 2007  Sam Roberts  <sroberts@uniserve.com>\n\n\t* io.c (rb_f_syscall): Fix buffer overflow with syscall\n\t  arguments.  [ruby-bugs:PR#8541]\n\nSun Feb 11 07:46:45 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::read_multipart): Properly parse\n\t  a quoted-string in a Content-Disposition value.\n\nSun Feb 11 06:27:54 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in, ext/thread/extconf.rb, lib/thread.rb: Add a\n\t  configure option `--disable-fastthread', to choose the original,\n\t  pure ruby version of the \"thread\" library instead of the new,\n\t  much faster implementation in ext/thread.\n\nSun Feb 11 06:22:20 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Setup: Add thread except for platforms without threads\n\t  support.\n\nSun Feb 11 06:15:16 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/lib/thread.rb: Add a replacement of thread.rb that\n\t  loads this extension.\n\nSun Feb 11 05:39:47 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/thread.rb: Remove an ineffective part of the code.\n\nSun Feb 11 05:32:54 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c (rb_thread_exclusive): Implement\n\t  Thread.exclusive.\n\nSun Feb 11 05:26:51 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread/thread.c: Get rid of use of a dummy function.\n\nSun Feb 11 01:45:31 2007  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/thread/thread.c (Init_thread): Define missing aliases:\n\t  Queue#enq and SizedQueue#enq.\n\nSat Feb 10 09:27:35 2007  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_variant2val): fix compile error\n\t  on VC++.\n\nSat Feb 10 07:41:52 2007  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_variant2val): fix the bug when\n\t  SAFEARRAY pointer is NULL.\n\nSat Feb 10 00:13:11 2007  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: fix typo (TkConfigMethod::__confinfo_cmd,\n\t  __conv_keyonly_opts).\n\nFri Feb  9 20:44:53 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread: Make style fixes (mostly de-K&R'ism) to match the\n\t  rest of the source code.\n\n\t* ext/thread: Make USE_MEM_POOLS an extconf option.\n\nFri Feb  9 20:43:01 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/thread: Import the \"fastthread\" implementation by MenTaLguY\n\t  in the original form.  This module is not hooked into the build\n\t  yet since it needs some style fixes and adjustments.\n\nFri Feb  9 15:46:09 2007  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/bigdecimal: Synchronize with trunk.  Better function\n\t  prototypes, removal of a useless method `!=', and document\n\t  updates.\n\nTue Feb 06 22:06:45 2007  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/{nkf.c,utf8tbl.c}:\n\t  imported nkf 2007-01-28.\n\t  * Fixed: can't decode MIME encode JIS string.\n\t  * Fixed: Fullwitdh-halfwidth conversion.\n\t  * Support DoCoMo's and Softbank's EMOJI\n\t  * Support CP932, CP5022x, eucJP-ms UDC\n\t  * Support UTF-32 encoding\n\t  * Support beyond BMP\n\t  [ruby-dev:29700] [ruby-dev:29922] [ruby-dev:30144]\n\nWed Jan 31 14:52:09 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_iterate): need to PUSH_ITER in proper order.\n\t  [ruby-core:10125]\n\n\t* test/ruby/test_iterator.rb (TestIterator::test_block_given_within_iterator):\n\t  add new test.  [ruby-core:10125]\n\nTue Jan 30 14:58:51 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* string.c (rb_str_sub_bang): calling rb_str_modify() should be just\n\t  before actually modifying the string.\n\t  fixed: [ruby-dev:30211] (originally reported by zunda)\n\nTue Jan 30 12:05:35 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* mkconfig.rb: autoconf 2.61 support.  [ruby-core:10016]\n\nSat Jan 27 15:20:11 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (dyna_var_lookup): should not alter dvar->val not to\n\t  destroy living value.  [ruby-core:10076]\n\n\t* parse.y (dyna_init): ditto.\n\nFri Jan 26 12:03:39 2007  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb (TkConfigMethod#__confinfo_cmd,\n\t  __conv_keyonly_optkeys): make them private [ruby-dev:30074].\n\n\t* ext/tk/lib/tk/txtwin_abst.rb: fix typo [ruby-dev:30073].\n\n\t* ext/tk/lib/tk/canvas.rb (TkCanvas#scan_dragto): lack of an argument.\n\n\t* ext/tk/lib/tk/canvas.rb: clarify the including module name\n\t  [ruby-dev:30080].\n\n\t* ext/tk/lib/tk/scrollable.rb: change primary name of modules\n\t  [ruby-dev:30080].\n\nWed Jan 24 18:05:39 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-font-lock-syntactic-keywords): fix\n\t  regexp font-lock bug.  [ruby-talk:235758]\n\nTue Jan 23 11:02:33 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/webrick/httprequest.rb (WEBrick::HTTPRequest::read_line):\n\nTue Jan 23 18:26:12 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::read_multipart): use == instead\n\t  of ===.  [ruby-dev:30176]\n\nTue Jan 23 10:48:17 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c: added documentation for Hash about how it uses eql? and\n\t  hash methods for the keys.  [ruby-core:09995]\n\nMon Jan 22 14:57:25 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c: fix errors in socket sample code.\n\t  [ruby-core:09992]\n\nSat Jan 13 23:54:48 2007  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_free, ole_type_free,\n\t  olemethod_free, olevariable_free, oleparam_free,\n\t  ole_event_free): fix memory leak.  [ruby-core:09846]\n\nFri Jan 12 11:13:55 2007  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/etc/etc.c (etc_getpwuid, etc_getgrgid): fix to correctly\n\t  convert uid/gid from VALUE. (backport of r11521)\n\nWed Jan 10 18:57:57 2007  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c (strscan_do_scan): should set kcode option\n\t  before match. [ruby-dev:29914]\n\n\t* test/strscan/test_stringscanner.rb: test it.\n\n\t* re.c: export kcode_set_option and kcode_reset_option (with \"rb_\"\n\t  prefix).\n\n\t* intern.h: ditto.\n\nTue Jan  9 17:45:17 2007  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (rb_find_file): should not call fpath_check() with NULL.\n\t  fixed: [ruby-core:09867]\n\nTue Jan  9 03:54:38 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_upto): String#upto from empty string makes\n\t  inifinite loop.  [ruby-core:09864]\n\nSun Jan  7 12:13:26 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#find_class_comment):\n\t  Look for class and module comments above rb_define_class and\n\t  rb_define_module.  Patch by Daniel Berger <djberg96 at gmail.com>\n\nSun Jan  7 10:32:12 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#handle_constants):\n\t  Properly handle escaping of : in comments.\n\t* test/rdoc/parsers/test_parse_c.rb:\n\t  Test RDoc::C_Parser#do_classes and Rdoc::C_Parser#find_class_comment.\n\nSun Jan  7 09:33:02 2007  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: updated based on date2 4.0.1.\n\nWed Jan  3 11:36:51 2007  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (ruby_dup): start GC on ENOMEM as well.\n\nMon Jan  1 06:13:11 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/c_parser.rb: Make Rdoc accessible.  Update constant\n\t  value information.\n\nMon Jan  1 06:13:11 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* ext/bigdecimal/bigdecimal.c: Update constant comments to provide\n\t  values for RDoc.\n\nMon Jan  1 06:05:55 2007  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#handle_constansts):\n\t  Allow RDoc comment to give friendly value for rb_define_const.  Patch\n\t  by Daniel Berger <djberg96 at gmail.com>, [ruby-patches-7499].\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#handle_constansts): Fix\n\t  whitespace handling in constant comments.\n\nSun Dec 31 00:31:16 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 4.0.\n\nThu Dec 14 18:29:13 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/readline/readline.c: NetBSD editline does not have\n\t  rl_username_completion_function() and rl_completion_matches().\n\t  a patch from Takahiro Kambe <taca at back-street.net>.\n\t  [ruby-dev:30008]\n\nThu Dec 14 18:20:43 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/locale.rb (IRB::Locale::puts): typo fixed.  a patch from\n\t  NAKAMURA Usaku <usa@ruby-lang.org>.  [ruby-dev:30012]\n\nMon Dec 11 11:58:36 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/sha2/lib/sha2.rb: Moved one level up from under\n\t  the superfluous subdirectory digest/.\n\nMon Dec 11 11:46:18 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_define_const): typo fixed.\n\nMon Dec 11 09:36:29 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_aset): index double decode problem.\n\t  [ruby-core:09695]\n\nSat Dec  9 21:39:24 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): keep the exception till after END blocks.\n\t  [ruby-core:09675]\n\nSat Dec  9 11:22:00 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/locale.rb (IRB::Locale::search_file): ues File.exist?\n\t  instead of File.exists?.  a patch from Yutaka Kanemoto\n\t  <kinpoco at gmail.com> in [ruby-dev:30000].\n\nThu Dec  7 09:29:02 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/weakref.rb (WeakRef::__setobj__): should support\n\t  marshaling.  [ruby-talk:228508]\n\n\t* lib/delegate.rb (Delegator::marshal_load): need to call\n\t  __setobj__.\n\nWed Dec  6 23:56:14 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, common.mk (NULLCMD): moved for platforms that empty\n\t  command does not run.  fixed: [ruby-dev:29994]\n\nWed Dec  6 17:17:26 2006  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (SITE_DIR): fixed to emtpy RUBY_SITE_LIB in config.h on\n\t  NetBSD.  fixed: [ruby-dev:29358]\n\nTue Dec  5 00:59:05 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-parse-partial): need to parse \"/=\" as\n\t  self assignment operator, not regex.  [ruby-talk:227324]\n\nMon Dec  4 10:48:03 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h (OFFT2NUM): use LONG2NUM() if sizeof(long) equals to\n\t  sizeof(off_t).\n\nMon Dec  4 10:43:46 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (dyna_init_gen): dvar initialization only if dvar is\n\t  assigned inner block.  [ruby-talk:227402]\n\nMon Dec  4 08:32:49 2006  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::read_multipart): should quote\n\t  boundary. JVN#84798830\n\nSat Dec  2 07:09:04 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ocsp.c: OpenSSL::OCSP::OSCPError should be\n\t  subclass of OpenSSL::OpenSSLError. [ruby-dev:29980]\n\nFri Dec  1 17:01:49 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* gc.c (ruby_init_stack): decrease \"stack level too deep\" in Windows.\n\t  merge from trunk.\n\nFri Dec  1 16:31:53 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c: shouldn't run the killed thread at callback.\n\t  [ruby-talk: 227408]\n\nMon Nov 27 17:18:27 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): need not to truncate string if no\n\t  width specifier given for %s.  [ruby-dev:29952]\n\nSun Nov 26 16:36:46 2006  URABE Shyouhei  <shyouhei@ruby-lang.org>\n\n\t* version.h: addition of RUBY_PATCHLEVEL.\n\t* version.c: ditto.\n\nFri Nov 24 10:17:51 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bignorm): avoid segmentation.  a patch from Hiroyuki\n\t  Ito <ZXB01226@nifty.com>.  [ruby-list:43012]\n\nThu Nov 23 10:38:40 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_define_method): set implicit visibility only when\n\t  it's called for the target class (ruby_cbase).\n\nWed Nov 22 16:00:49 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/extconf.rb: support --with-X11/--without-X11 option.\n\n\t* ext/tk/README.tcltklib: add description about --with-X11-* option\n\t  [ruby-talk:225166] and --with-X11/--without-X11 option.\n\n\t* ext/tk/tkutil/extconf.rb: able to be called manually\n\t  [ruby-talk:225950].\n\nWed Nov 15 23:22:54 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (test_grpowned, rb_stat_grpowned): should honor\n\t  supplementary group IDs.  [ruby-core:09546]\n\nThu Nov  9 03:15:22 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (BEGIN_CALLARGS): ruby_block may be NULL even when\n\t  ITER_PRE.\n\nTue Nov  7 18:34:34 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/lib/digest/hmac.rb: Keep this out of the 1.8 tree\n\t  until we reach a consensus that HMAC should be put under Digest.\n\nTue Nov  7 18:05:01 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/itemconfig.rb: minor bug fix.\n\nMon Nov  6 20:11:20 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/0.9.rb (RSS::Rss): removed needless include.\n\nMon Nov  6 15:41:55 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/itemconfig.rb: ext/tk/lib/tk/itemconfig.rb: bug\n\t  fix on 'itemconfiginfo' method, and modify to make it easy to\n\t  override 'itemconfiginfo' method.\n\n\t* ext/tk/lib/tkextlib/tile/treeview.rb : support Tile 0.7.8.\n\n\t* ext/tk/lib/tkextlib/version.rb : [new] add Tk::Tkextlib_RELEASE_DATE\n\t  to get the information from scripts.\n\n\t* ext/tk/lib/tk.rb: load 'tkextlib/version.rb', and update RELEASE_DATE\n\n\t* ext/tk/lib/tkextlib/SUPPORT_STATUS: update.\n\n\t* ext/tk/sample/editable_listbox.rb: [new] the listbox with editable\n\t  items. It's one of the example about usage of Place geometry manager.\n\n\t* ext/tk/sample/tktextio.rb: improve the functions of TkTextIO class.\n\t  Those are required by 'irbtkw.rbw'.\n\n\t* ext/tk/sample/irbtkw.rbw: [new] IRB on Ruby/Tk. It doesn't need any\n\t  real console. IRB works on a text widget without I/O blocking. That\n\t  is, thread switching on IRB will work properly, even if on Windows.\n\nSun Nov  5 19:53:49 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb: updated based on date2 3.9.7.\n\nSat Nov  4 13:13:57 2006  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: accept NOMODSEQ. [ruby-core:9002]\n\t  (backported from HEAD)\n\nFri Nov  3 00:16:37 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_getnameinfo__aix): AF_INET6 workaround\n\t  for AIX.  a patch from Yutaka Kanemoto <kinpoco AT gmail.com>.\n\t  [ruby-dev:29744]\n\nThu Nov  2 15:43:39 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* parse.y (primary): should set NODE even when compstmt is NULL.\n\t  merge from trunk. fixed: [ruby-dev:29732]\n\nThu Nov  2 14:48:30 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb (Set#^): Fix XOR operation against a container that\n\t  holds duplicate values. [issue: #6444]\n\nWed Nov  1 02:41:38 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/lib/digest/hmac.rb (Digest::HMAC::update): Minor\n\t  optimization.\n\n\t* ext/digest/digest.c (rb_digest_instance_equal): Allow comparing\n\t  a digest instance with another of a different class.\n\nWed Nov  1 01:05:13 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (rb_call0): fixed bug of zsuper with both of opt and rest.\n\t  fixed: [ruby-list:42928]\n\n\t* test/ruby/test_super.rb: add tests to check above bug.\n\nTue Oct 31 17:03:21 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_dup): duplicate the class of original time.\n\t  [ruby-core:09357]\n\n\t* lib/time.rb (Time::make_time, Time::rfc2822, Time::httpdate):\n\t  should respect subclasses.  [ruby-core:09357]\n\nMon Oct 30 23:40:52 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in (miniruby): add XLDFLAGS.\n\n\t* configure.in (aix): use -bE option for miniruby.  [ruby-dev:29698]\n\n\t* dir.c (glob_helper): get rid of possible memory leak.\n\n\t* win32/win32.c (cmdglob, rb_w32_cmdvector, rb_w32_opendir,\n\t  rb_w32_get_environ): not to use GC before initialization.\n\nMon Oct 30 19:29:20 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* bignum.c (rb_big2str0): use better approximation.\n\nMon Oct 30 18:35:33 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big2str0): wrong allocation length.  a patch from\n\t  U.Nakamura <usa at garbagecollect.jp> [ruby-dev:29710]\n\nMon Oct 30 12:34:02 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): fix commit miss.  [ruby-dev:29707]\n\nMon Oct 30 12:20:58 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big2str0): a bug in length adjustment.\n\nMon Oct 30 11:15:40 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_str_format): should preserve leading zero\n\t  information for negative %b and %x.  [ruby-talk:221347]\n\nThu Oct 26 21:05:58 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_pkcs7.c (ossl_pkcs7_verify): should clear error.\n\t  (fix http://bugs.debian.org/394336)\n\n\t* ext/openssl/ossl_ns_spki.c (ossl_spki_initialize): ditto.\n\nThu Oct 26 15:21:10 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/digest/digest.c (Init_digest): typo.\n\nWed Oct 25 17:23:28 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest, test/digest/test_digest.rb: Merge from trunk:\n\t  - Introduce versioning in Digest::Base API, and prefix C\n\t    constants with RUBY_ and C type names with rb_ to avoid name\n\t    clash in writing extensions.\n\t  - Introduce Digest::Class and Digest::Instance for ease of\n\t    implementing subclasses and add-ons.\n\t  - Digest::Instance module requires and assumes that any instance\n\t    be resettable and clonable.  An instance method #new() is\n\t    added so digest instances work just like digest classes.\n\t  - The constructor does no longer take an initial string to feed;\n\t    digest() and hexdigest() now do, instead.  This allows digest\n\t    classes to take their own hashing parameters.\n\t  - Make some changes to digest() and hexdigest() class methods,\n\t    which now take extra arguments, which are passed through to\n\t    the constructor in an internal call.\n\t  - Add #digest_length/size/length() and #block_length(),\n\t  - Add the Digest::SHA2 class to wrap up SHA2 variants: SHA256,\n\t    SHA384 and SHA512, hoping this module would make a decent\n\t    example of a digest subclass written in Ruby.\n\t  - Rip BubbleBabble support out of the base class and have a\n\t    separate module named digest/bubblebabble.\n\t  - Remove RD documents in favor of newly written and embedded\n\t    RDoc documentation.\n\nWed Oct 25 08:03:23 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: updated based on date2 3.9.6.\n\t  [ruby-core:09323]\n\nSun Oct 22 14:48:31 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* signal.c (ruby_signal): don't set SA_RESTART.  a backport from\n\t  the HEAD.  [ruby-talk:220937]  [ruby-talk:147220]\n\n\t* signal.c (Init_signal): avoid duplicated installation of SIGCHLD\n\t  handler.\n\nSun Oct 22 16:47:56 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_substr): should be infected with only original\n\t  string, but not the shared string.  fixed: [ruby-core:09152]\n\n\t* string.c (rb_str_new4): keep shared string untainted when orignal\n\t  string is tainted.  fixed: [ruby-dev:29672]\n\nSun Oct 22 05:20:34 2006  URABE Shyouhei  <shyouhei@ice.uec.ac.jp>\n\n\t* configure.in: alloca is broken; use C_ALLOCA instead.\n\t  [ruby-dev:29416]\n\nFri Oct 20 10:47:43 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb: fixed the bug of handling COMMON_MACROS.\n\nFri Oct 20 08:42:38 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (NULLCMD): dummy command.\n\n\t* bcc32/Makefile.sub (post-install-*): Borland make cannot ignore\n\t  command-less double-colon rules.  [ruby-dev:29676]\n\nFri Oct 20 00:37:07 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bcc32/Makefile.sub ($(LIBRUBY_SO)): execute pre-link hook.\n\n\t* ext/extmk.rb: workaround for Borland make.\n\nWed Oct 18 23:02:40 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (rb_ary_shift): shorten copy size.  fixed: [ruby-list:42907]\n\n\t* signal.c (Init_signal): handle SIGTERM.  fixed: [ruby-list:42895]\n\n\t* win32/win32.c (rb_w32_utime): allow NULL to set the current time.\n\t  [ruby-talk:219248]\n\nWed Oct 18 00:55:33 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (parser_yylex): use particular enums.  [ruby-core:09221]\n\nMon Oct 16 08:30:43 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* mkconfig.rb: *OBJS are not needed for extension libraries.\n\n\t* {bcc32,wince,win32}/Makefile.sub (config.status): fixed typo,\n\t  missing comma.\n\nSun Oct 15 01:03:08 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/collector/dir.rb (Collector::Dir#collect): append base\n\t  directory but not prepend.\n\n\t* lib/test/unit/collector/dir.rb (Collector::Dir#collect_file): do not\n\t  join with dot.  fixed: [ruby-core:09179]\n\nSat Oct 14 23:39:50 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (singleton): no need to re-create NODE_SELF() again.\n\t  [ruby-core:09177]\n\nSat Oct 14 23:25:31 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (parser_warning, parser_warn): some error message may\n\t  contain format specifiers.  a patch from Akinori MUSHA <knu at\n\t  iDaemons.org>.  [ruby-dev:29657]\n\n\t* ext/bigdecimal/bigdecimal.c (VpException): ditto.\n\n\t* ext/dl/handle.c (rb_dlhandle_initialize): ditto.\n\n\t* ext/gdbm/gdbm.c (rb_gdbm_fatal): ditto.\n\nSat Oct 14 08:24:45 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/lib/digest/hmac: Back out the addition of digest/hmac\n\t  for now because the API is too premature for a stable branch.\n\nSat Oct 14 00:55:08 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bcc32/Makefile.sub (post-install-ext): no longer needed.\n\n\t* bcc32/configure.bat: get rid of a quirk of Borland make, which\n\t  sets empty macro in command line to \"1\".\n\nFri Oct 13 22:50:43 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb: updated based on date2 3.9.5.\n\nFri Oct 13 22:33:28 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (FileUtils.cp_r): dereference_root=true is\n\t  default in Ruby 1.8.  This line is wrongly removed in last commit.\n\nFri Oct 13 18:19:31 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c: Class#inherited RDoc added.  a patch from Daniel\n\t  Berger <djberg96 at gmail.com>  [ruby-core:08942]\n\nFri Oct 13 02:30:12 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/collector/dir.rb (Collector::Dir#collect): prepend\n\t  base directory to load path.\n\n\t* lib/test/unit/collector/dir.rb (Collector::Dir#collect_file): should\n\t  use the given File-like interface, but not File directly.\n\n\t* test/testunit/collector/test_dir.rb (TestDir::FileSystem): implement\n\t  File-like methods correctly.\n\nFri Oct 13 01:48:42 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/date.rb (Date::self.complete_hash): need to check if g is\n\t  nil before dereference.  [ruby-core:09116]\n\nFri Oct 13 00:34:26 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_cvar_defined): wrong id check.  a patch from\n\t  Mauricio Fernandez <mfp at acm.org>.  [ruby-core:09158]\n\n\t* object.c (rb_mod_cvar_get): typo fixed.  [ruby-core:09168]\n\n\t* object.c (rb_mod_cvar_set): ditto.\n\nWed Oct 11 22:21:41 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest: Merge from trunk; metadata location changed,\n\t  Digest::Base#reset() added, Digest::Base#equal() changed, and\n\t  digest/hmac added with some modifications made for ruby 1.8.\n\nTue Oct 10 17:24:12 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/Makefile.sub (config.status): shouldn't use\n\t  copy command instead of install. use -run install.\n\nTue Oct 10 16:49:16 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/digest.c (hexdigest_str_new, bubblebabble_str_new):\n\t  Perform StringValue() checks properly.\n\n\t* ext/digest/digest.c: Use RSTRING_{PTR,LEN} macros.\n\nTue Oct 10 13:49:53 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest: Merge from trunk; apply all changes since the\n\t  initial import, except for the removal of compatibility stub\n\t  libraries (md5.rb and sha1.rb).\n\nMon Oct  9 23:46:29 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/parsedate.rb: documentation patch from Konrad Meyer\n\t  <konrad.meyer@gmail.com>.  [ruby-doc:1238]\n\n\t* lib/open3.rb, lib/ping.rb: ditto.\n\nMon Oct  9 22:56:12 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rexml/encoding.rb (REXML::Encoding::check_encoding): spaces\n\t  are allowed around equal sign.  [ruby-core:09032]\n\n\t* lib/rexml/parsers/baseparser.rb (REXML::Parsers::BaseParser): ditto.\n\nSat Oct  7 23:53:08 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_scan): small documentation fix.\n\t  [ruby-core:09007]\n\nSat Oct  7 23:44:33 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_rshift): a bug in right shift of negative\n\t  bignums.  [ruby-core:09020]\n\nSat Oct  7 00:27:58 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_include_module): remove unnecessary check.\n\t  [ruby-talk:218402]\n\nFri Oct  6 04:30:30 2006  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* sample/openssl/c_rehash.rb: Use digest/md5 instead of obsolete md5.\n\nWed Oct  4 18:47:25 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/*: bugfix and update\n\t  (see ext/tk/ChangeLog.tkextlib).\n\nWed Oct  4 17:25:14 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call): check protected visibility based on real self,\n\t  not ruby_frame->self.  [ruby-talk:217822]\n\nWed Oct  4 08:52:30 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/optparse/test_getopts.rb: changed the class name of test case\n\t  to get rid of conflict with test_optparse.rb.\n\nTue Oct  3 23:32:27 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/testcase.rb (Test::Unit::TestCase.suite): test name\n\t  must be string.  fixed: [ruby-core:08978]\n\nMon Oct  2 23:47:55 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner::COLLECTORS):\n\t  base directory should be lower precedence.  fixed: [ruby-dev:29622]\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner#options): typo.\n\n\t* lib/test/unit/collector/dir.rb (Test::Unit::Collector::Dir#collect_file):\n\t  load expanded path.  fixed: [ruby-dev:29621]\n\nMon Oct  2 15:49:19 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* instruby.rb: batfile should be CRLF'ed.\n\nMon Oct  2 01:24:26 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (test-all): separate directory where running test cases\n\t  from source tree.\n\n\t* lib/test/unit/autorunner.rb (options): added --basedir, --workdir\n\t  and --load-path options.\n\n\t* lib/test/unit/collector/dir.rb (recursive_collect, collect_file):\n\t  base directory support.\n\nSun Oct  1 23:56:52 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, common.mk, ext/extmk.rb, win{32,ce}/Makefile.in: keep\n\t  LIBRUBY_SO unless need to be removed.\n\nSun Oct  1 23:12:19 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser#make_switch): pass arguments directly.\n\nSat Sep 30 15:12:25 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 3.9.4.\n\nFri Sep 29 12:11:04 2006  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* jcode.rb (succ!): call original succ! if $KCODE == 'n'.\n\t  fixed: [ruby-talk:216845]\n\nFri Sep 29 11:43:40 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (try_func): revert fallback checking undeclared function.\n\t  fixed: [ruby-core:08949]\n\nFri Sep 29 09:56:56 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: extout is needed for also clean.\n\t  fixed: [ruby-core:08944]\n\n\t* lib/optparse.rb (OptionParser::Switch#conv_arg): unsplat by\n\t  Proc#call if no conversion is given.\n\nThu Sep 28 23:59:31 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* node.h (struct thread): declare win32_exception_list on cygwin and\n\t  win32 regardless if it is implemented.  Provisional fix for\n\t  [ruby-core:08917].\n\nThu Sep 28 20:53:16 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/tmpdir.rb: use return value of getdir.call for length.\n\nWed Sep 27 01:04:49 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (try_func): check function pointer first and macro next.\n\n\t* lib/mkmf.rb (have_type): simplified with typedef and sizeof.\n\nTue Sep 26 23:57:03 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser#getopts): use strings as key.\n\t  fixed: [ruby-dev:29614]\n\nTue Sep 26 15:31:26 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {win32,wince}/Makefile.sub (CPP): check predefined value.\n\nTue Sep 26 07:55:16 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_shift): should not move memory region if array\n\t  body is shared.  a patch from Kent Sibilev <ksruby at gmail.com>.\n\t  [ruby-core:08922]\n\nMon Sep 25 22:26:26 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_path_end): skip root directory.  fixed: [ruby-core:08913]\n\n\t* lib/mkmf.rb (init_mkmf): set default $LDFLAGS.  Patch by Michal\n\t  Suchanek <hramrach at centrum.cz>.  [ruby-talk:216256]\n\nMon Sep 25 08:14:43 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_shift): should clear shifting top element.\n\t  [ruby-talk:216055]\n\n\t* array.c (rb_ary_shift): avoid creating shared object if array\n\t  size is small.\n\nMon Sep 25 08:11:35 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* random.c (rb_f_rand): RDoc typo fix.  a patch from Frederick\n\t  Cheung <fred at 82ask.com>.  [ruby-talk:216047]\n\nSun Sep 24 22:28:20 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* runruby.rb: extension library scripts moved into common directory.\n\nSun Sep 24 14:59:50 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* node.h (struct thread): ia64 support is broken by sandbox patch.\n\nSun Sep 24 12:11:16 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 3.9.3.\n\nSat Sep 23 23:24:57 2006  why the lucky stiff  <why@ruby-lang.org>\n\n\t* eval.c (rb_thread_save_context, rb_thread_restore_context):\n\t  sandbox hook to save and restore sandbox state.\n\n\t* eval.c (thread_no_ensure): added THREAD_NO_ENSURE thread flag.\n\n\t* eval.c (rb_thread_kill_bang): Thread#kill! uses the above flag\n\t  to circumvent ensure, in order to prevent endless loops.\n\t  [ruby-core:08768]\n\n\t* eval.c (rb_thread_kill): fix Thread#kill docs, which returns\n\t  the thread object in all cases.\n\n\t* node.h: expose the rb_jmpbuf_t and rb_thread_t structs, along\n\t  with the thread flags.  used by the sandbox extension.\n\n\t* ruby.h: extern rb_eThreadError, so sandbox can swap it.\n\nSat Sep 23 21:34:15 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::read_multipart): CGI content\n\t  may be empty.  a patch from Jamis Buck <jamis at 37signals.com>.\n\nSat Sep 23 08:35:53 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rdoc/ri/ri_options.rb: prevent NameError.  [ruby-dev:29597]\n\nSat Sep 23 01:04:20 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 3.9.2.\n\nFri Sep 22 02:06:26 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* .cvsignore: ignore timestamp files and installed list file.\n\nFri Sep 22 01:36:34 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* instruby.rb: include FileUtils unconditionally.\n\nThu Sep 21 22:56:20 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (no-install): not install rdoc actually.\n\n\t* common.mk (install-doc, no-install-doc): use instruby.rb.\n\n\t* instruby.rb: rdoc installation.\n\n\t* ext/extmk.rb: expand ruby executable names.\n\nThu Sep 21 13:55:07 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/etc/etc.c (etc_getpwuid): uid integer should be wraped in\n\t  uid_t value.  [ruby-core:08897]\n\n\t* ext/etc/etc.c (etc_getpwuid): uid_t may be bigger than plain\n\t  'int' type.\n\nWed Sep 20 23:17:41 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (pre-install-doc): create data directory before install.\n\n\t* lib/mkmf.rb (dir_re): fixed typo.\n\n\t* lib/mkmf.rb (install_dirs): remove extra slash.\n\nWed Sep 20 09:53:38 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/Makefile.sub (INSTALLED_LIST): need to define\n\t  this macro to install.\n\nWed Sep 20 09:43:10 2006  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: allow extra spaces in responses.\n\t  Thanks, Tom Soderlund. (backported from HEAD)\n\nWed Sep 20 09:25:39 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/gdbm/gdbm.c: add RDoc documentation. a patch from Peter\n\t  Adolphs <futzilogik at users dot sourceforge dot net>.\n\t  [ruby-doc:1223]\n\nTue Sep 19 01:28:00 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: backport from HEAD (rev 1.71).\n\n\t* lib/fileutils.rb (FileUtils.cp_r): new option\n\t  :remove_destination.\n\nTue Sep 19 00:42:15 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (rb_obj_ivar_defined, rb_mod_cvar_defined): new methods,\n\t  Kernel#instance_variable_defined? and Module#class_variable_defined?.\n\t  [ruby-dev:29587]\n\n\t* lib/date/format.rb (Date::Bag#method_missing): use new method,\n\t  instance_variable_defined? to check if an instance variable is\n\t  defined.  fixed: [ruby-dev:29554]\n\t  -- This didn't fix anything.\n\nSun Sep 17 23:44:58 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rdoc/rdoc.rb (RDoc::RDoc#document): scan only files modified\n\t  after the previous generation.\n\nSun Sep 17 17:42:13 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (install-doc): reverted.\n\n\t* instruby.rb: stores file name list without destdir prefix.\n\n\t* lib/rdoc/generators/ri_generator.rb: do not chdir twice.\n\nSat Sep 16 23:14:29 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/pty/pty.c (establishShell): remove remaining unused line.\n\nSat Sep 16 16:40:44 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, common.in, instruby.rb, ext/extmk.rb, lib/mkmf.rb:\n\t  use instruby.rb to install extensions instead of ext/extmk.rb.\n\n\t* instruby.rb: store installed list into the file.\n\n\t* ext/dbm/extconf.rb: allow multiple candidates for dbm-type.\n\n\t* ext/io/wait/extconf.rb: suspicious checking_for.\n\n\t* ext/pty/pty.c (establishShell): parent pid is not used.\n\n\t* ext/pty/pty.c (freeDevice): not used.\n\n\t* ext/pty/pty.c (get_device_once): removed garbage right brace.\n\n\t* lib/mkmf.rb (checking_for): improved the messages.\n\nThu Sep 14 16:11:15 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_intern): raise SecurityError only when $SAFE\n\t  level is greater than zero.  [ruby-core:08862]\n\n\t* parse.y (rb_interned_p): new function to check if a string is\n\t  already interned.\n\n\t* object.c (str_to_id): use rb_str_intern().\n\nWed Sep 13 18:43:05 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* README.EXT: English adjustment.  [ruby-core:08851] and\n\t  [ruby-core:08852]\n\nWed Sep 13 18:25:18 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-parse-partial): better here-doc support.\n\t  a patch from Marshall T. Vandegrift <llasram at gmail.com>.\n\t  [ruby-core:08804]\n\nWed Sep 13 16:43:36 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_intern): prohibit interning tainted string.\n\nWed Sep 13 01:14:21 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser#getopts): works with pre-registered\n\t  options.  [ruby-core:08826]\n\nSun Sep 10 20:27:13 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 3.9.1.\n\nTue Jan 10 09:18:03 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (stack_extend): fixed prototype.\n\n\t* eval.c (rb_require_safe): prevent extension from loading twice.\n\t  fixed: [ruby-dev:29523]\n\nSat Sep  9 23:50:38 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_mul0): bignum multiplication without\n\t  normalization.\n\n\t* bignum.c (rb_big_pow): use rb_big_mul0().  [ruby-dev:29547]\n\nSat Sep  9 14:08:38 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/test/unit/testcase.rb (Test::Unit::TestCase#run): Rescue\n\t  Exception in Test::Unit::TestCase#run.  [ruby-core:08783]\n\nSat Sep  9 04:55:59 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/pstore.rb: open all in binary mode, and get rid of the quirk of\n\t  msvcrt.  fixed: [ruby-dev:29518]\n\nSat Sep  9 04:54:42 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, win32/Makefile.sub (MINIRUBY): append MINIRUBYOPT.\n\n\t* mkconfig.rb, ext/extmk.rb, lib/mkmf.rb, win32/mkexports.rb: suppress\n\t  warnings with $VERBOSE.\n\n\t* ext/extmk.rb: Proc#call does not pass the block in 1.8.\n\n\t* win32/resource.rb: add more info.\n\nFri Sep  8 10:03:59 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cookie.rb (WEBrick::Cookie.parse_set_cookies): new\n\t  method to parse multiple cookies per Set-Cookie header.\n\t  Thanks to Aaron Patterson <aaron_patterson at speakeasy.net>.\n\t  [ruby-core:08802]\n\nFri Sep  8 08:59:30 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/Makefile.sub, win32/configure.bat win32/setup.mak: program\n\t  name transform.\n\nFri Sep  8 01:33:08 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h (RSTRING_PTR): add migration macro.\n\n\t* ruby.h (RARRAY_PTR): ditto.\n\nThu Sep  7 23:27:05 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (path_check_0, fpath_check): disable path check on cygwin.\n\t  [ruby-talk:213074]\n\nWed Sep 06 12:05:19 2006  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/lib/kconv.rb (Kconv::RegexpEucjp): fix regexp for euc-jp\n\t  [ruby-dev:29344]\n\n\t* ext/nkf/lib/kconv.rb (Kconv::toeuc): remove -m0 [ruby-dev:29505]\n\nTue Sep  5 06:47:22 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_to_s): variable declaration after an execution\n\t  statement.\n\nTue Sep  5 05:56:51 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* numeric.c (flo_hash): improve collision.  fixed: [ruby-dev:29352]\n\nTue Sep  5 05:49:41 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (path_check_0): check if sticky bit is set on parent\n\t  directories for executable path.  fixed: [ruby-dev:29415]\n\nTue Sep  5 05:03:46 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_plus): addition in Fixnum will never overflow\n\t  long.  a patch from Ondrej Bilka <neleai at seznam.cz>.\n\t  [ruby-core:08794]\n\n\t* numeric.c (fix_minus): ditto.\n\n\t* bignum.c (rb_big_pow): eagerly truncate resulting bignum.\n\t  [ruby-core:08794]\n\nMon Sep  4 23:15:34 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_to_s): make it conform to RFC2822 date format.\n\t  [ruby-dev:29467]\n\nMon Sep  4 21:43:57 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb: create makefile according to the result of check\n\t  for dbm header.  fixed: [ruby-dev:29445]\n\nMon Sep  4 21:42:35 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 3.9.\n\nMon Sep  4 21:14:20 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_strftime): include nul character.  fixed: [ruby-dev:29422]\n\nMon Sep  4 16:29:33 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::out): specify -m0 -x option for nkf.\n\t  [ruby-dev:29284]\n\nMon Sep  4 16:13:23 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (pipe_open): command name should not contain null bytes.\n\t  [ruby-dev:29421]\n\n\t* process.c (proc_spawn): ditto.\n\n\t* process.c (proc_spawn_n): ditto.\n\n\t* process.c (rb_f_system): ditto.\n\nSun Sep  3 15:32:44 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb: get rid of nil.to_s.\n\nSun Sep  3 06:24:38 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* ext/socket/socket.c (ruby_connect): sockerrlen should be socklen_t.\n\nSun Sep  3 04:40:42 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* ext/socket/extconf.rb: check arpa/inet.h for ntohs.\n\n\t* ext/socket/socket.c: include arpa/inet.h if available.\n\nSun Sep  3 02:34:55 2006  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/unix.rb (DRbUNIXSocket#close): don't get path if client mode.\n\t  [ruby-dev:29417]\n\nSun Sep  3 01:45:17 2006  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/acl.rb (ACLEntry#initialize): examine whether '*' is\n\t  included before IPAddr.new. [ruby-dev:29406]\n\nSat Sep  2 13:23:01 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* common.mk (ia64.o): use the compiler driver to assemble ia64.s\n\t  to use appropriate ABI.\n\nSat Sep  2 03:36:22 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* common.mk, configure.in, defines.h, eval.c, gc.c, main.c,\n\t  numeric.c, ruby.h, ia64.s: backport IA64 HP-UX support.\n\nFri Sep  1 13:52:57 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/font.rb: TkFont#current_configinfo() doesn't work\n\t  on Tcl/Tk8.x.\n\nThu Aug 31 12:46:55 2006  why the lucky stiff  <why@ruby-lang.org>\n\n\t* eval.c (ruby_init): rename top_cref to ruby_top_cref and export,\n\t  along with ruby_cref, for use by the sandbox. [ruby-core:08762]\n\n\t* node.h: ditto.\n\nTue Aug 29 19:10:10 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (rb_hash_s_create): fixed memory leak, based on the patch\n\t  by Kent Sibilev <ksruby at gmail.com>.  fixed: [ruby-talk:211233]\n\nMon Aug 28 11:36:02 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_rb.rb: Fix typo.  Submitted by\n\t  <calamitas at gmail.com>.  [ruby-core:08724]\n\nMon Aug 28 07:53:44 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/ri/ri_formatter.rb: Don't unescape HTML in HtmlFormatter.\n\t  Submitted by Kent Sibilev <ksruby at gmail.com>.  [ruby-core:08392].\n\nMon Aug 28 07:25:45 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* file.c (File#size?): Fix documentation submitted by Rick Ohnemus.\n\t  ruby-Bugs-5529.  [ruby-core:08725]\n\nSat Aug 26 08:07:13 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: updated based on date2 3.8.2.\n\nFri Aug 25 22:32:04 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rexml/source.rb (REXML::IOSource#initialize): encoding have to\n\t  be set with the accessor.  fixed: [ruby-list:42737]\n\nFri Aug 25 17:15:17 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.8.5 released.\n\nFri Aug 25 17:02:06 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_sweep): typo fixed.\n\nTue Aug 22 18:47:51 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::handle_method):\n\t  rdoc documents C module methods as instance methods. a patch in\n\t  [ruby-core:08536].\n\nSat Aug 19 14:15:02 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (config.status): include winsock2.h instead of\n\t  winsock.h when --with-winsock2 is specified.\n\t  fixed: [ruby-dev:29296]\n\nSat Aug 19 11:28:08 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_rename): use errno if set properly.\n\t  fixed: [ruby-dev:29293]\n\nSat Aug 19 11:09:23 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (then): remove semicolon warning.  [ruby-dev:29299]\n\nThu Aug 17 19:15:16 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_stat_[rRwWxX]): check for super user.\n\t  fixed: [ruby-core:08616]\n\nThu Aug 17 14:47:06 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb: added rdoc by Daniel Berger.  [ruby-core:08177]\n\nThu Aug 17 00:39:05 2006  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/ring.rb (do_reply): Fix for RingServer fails to find a\n\t  TupleSpace when TupleSpace resides in the same ruby process with\n\t  RingServer. a patch from Kent Sibilev. [ruby-core:08453]\n\nWed Aug 16 11:45:36 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (proc_setuid, proc_setgid, proc_seteuid, proc_setegid):\n\t  get rid of bogus implementations on Mac OS X.\n\nTue Aug 15 19:10:18 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#find_class_comment): Fix\n\t  broken class-level documentation.\n\nWed Aug 16 11:09:26 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ruby.c (set_arg0): fill argv other than the first with an empty\n\t  string instead of NULL.\n\nWed Aug 16 11:08:00 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.h: removed an excess macro.  fixed: [ruby-dev:29258]\n\nTue Aug  8 23:49:06 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/extend-command.rb (IRB::ExtendCommandBundle): pacify\n\t  RDoc.  a patch from Eric Hodel <drbrain at segment7.net>.\n\t  [ruby-core:08522]\n\nTue Aug  8 11:32:54 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* Makefile.in, common.mk, configure.in: fix for platforms without\n\t  rm. patches from Yutaka kanemoto <kinpoco at gmail.com>.\n\t  [ruby-dev:29215]\n\nMon Aug  7 17:56:59 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c, ext/digest/rmd160/rmd160ossl.c,\n\t  ext/digest/sha1/sha1ossl.c, ext/readline/readline.c: move\n\t  incluion of config.h to pacify AIX.  a patch from Yutaka\n\t  Kanemoto <kinpoco at gmail.com>.  [ruby-dev:29197]\n\nMon Aug  7 15:55:08 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syck/syck.c (syck_move_tokens): should avoid negative\n\t  memmove.  [ruby-list:42625]\n\nMon Aug  7 14:37:48 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in, common.mk: AIX link issue.  a patch from Yutaka\n\t  Kanemoto <kinpoco at gmail.com>.  [ruby-dev:29190]\n\n\t* ext/socket/socket.c: AIX socket support.  [ruby-dev:29190]\n\nMon Aug  7 12:05:28 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dln.c, eval.c, gc.c, regex.c, ruby.h: shut up AIX alloca\n\t  warning.  a patch from Yutaka Kanemoto <kinpoco at gmail.com>.\n\t  [ruby-dev:29191]\n\nSun Aug  6 20:40:41 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (str[fp]time): %[EO]U didn't denote %U.\n\nSat Aug  5 17:07:43 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (top_local_setup): local_vars[-1] should point\n\t  ruby_scope itself to protect local_tbl from garbage collection.\n\t  [ruby-dev:29049]\n\nSat Aug  5 13:54:03 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb (str[fp]time): \"%\\n\" means \"\\n\".\n\nFri Aug  4 15:21:00 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib: Merge RDoc and .document from HEAD.\n\t* lib/drb/ssl.rb: Close socket on SSLError [ruby-core:7197]\n\nFri Aug  4 19:13:41 2006  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/irb/{init.rb,ruby-lex.rb,slex.rb}: can't input '\\c' for\n\t  [ruby-core: 7122].\n\nFri Aug  4 14:02:14 2006  James Edward Gray II  <james@grayproductions.net>\n\n\t* lib/date/format.rb (__strptime, strftime): allow multi-line patterns\n\t  in Date#strftime the same as Time#strftime accepts.\n\t  fixed: [ruby-core:08466]\n\nFri Aug  4 13:56:51 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* pack.c (pack_pack): check argument overrun for 'P'.  based on a\n\t  patch by rucila <rucila at yahoo.cojp>.  fixed: [ruby-dev:29182]\n\nTue Aug  1 17:44:03 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (init_stdhandle): assign standard file handles.\n\nTue Aug  1 12:24:58 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (Init_Binding): fix old commit miss.\n\nMon Jul 31 17:08:20 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (exit_handler): new function; release winsock and\n\t  environment work area.\n\n\t* win32/win32.c (NTInitialize): setup exit_handler.\n\n\t* win32/win32.c (StartSockets): use exit_handler.\n\n\t* win32/win32.c (rb_w32_getenv): use GetEnvironmentStrings() instead\n\t  of GetEnvironmentVariable(), because the latter cannot distinguish\n\t  wheather a null environment variable exists or not.\n\t  fixed: [ruby-talk:205123]\n\nMon Jul 31 16:15:13 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* test/ruby/test_process.rb (TestProcess#test_rlimit_nofile):\n\t  setrlimit may fail with EINVAL.\n\t  reported by MIYAMUKO Katsuyuki.  [ruby-dev:29174]\n\nMon Jul 31 13:38:22 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httprequest.rb (WEBrick::HTTPReuqest#parse_uri): improve\n\t  for the value of IPv6 address in the Host: header field.\n\nMon Jul 31 09:22:12 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h: use ifdef (or defined) for macro constants that may or\n\t  may not be defined to shut up gcc's -Wundef warnings.\n\t  [ruby-core:08447]\n\nSun Jul 30 23:26:22 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_call0): trace call/return of method defined from block.\n\t  fixed: [ruby-core:08329]\n\n\t* eval.c (rb_trap_eval): make the current thread runnable to deal with\n\t  exceptions which occurred within the trap.  fixed: [ruby-dev:27729]\n\n\t* lib/cgi/session.rb, lib/cgi/session/pstore.rb: suppress warnings.\n\t  fixed: [ruby-talk:204896]\n\nSat Jul 29 06:12:06 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: freeze ip_name for security reason.\n\nSat Jul 29 01:23:52 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/logger.rb: improves the amount of documentation that Rdoc\n\t  picks up when processing logger.rb by moving the require\n\t  statement back before the comment block.  a patch from Hugh\n\t  Sasse <hgs at dmu.ac.uk>.  [ruby-core:08422]\n\nThu Jul 27 22:21:52 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (time_to_s): fixed format mismatch.\n\nThu Jul 27 21:19:54 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* math.c (domain_check): a new function to check domain error\n\t  explicitly for systems that return NaN like FreeBSD.\n\t  [ruby-core:07019]\n\n\t* math.c (math_acos, math_asin, math_acosh, math_atanh, math_log,\n\t  math_log10, math_sqrt): use domain_check().\n\n\t* math.c (math_sqrt): fix documentation flaw.\n\nThu Jul 27 18:12:12 2006  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* time.c: need to declare time_utc_offset.\n\nThu Jul 27 17:01:01 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_close): always calls \"close\" method of the receiver.\n\t  [ruby-core:6911] [ruby-core:8112]\n\nThu Jul 27 16:49:01 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_to_s): use +0900 style timezone string for local time.\n\t  [ruby-dev:29143]\n\nThu Jul 27 16:41:15 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/openssl/ossl.h: move <ruby.h> inclusion point to shut up\n\t  Solaris compiler.  [ruby-core:08114]\n\nWed Jul 26 22:20:59 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: add support for as and ASFLAGS.  [ruby-dev:29138]\n\nWed Jul 26 22:13:45 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: sync with HEAD (rev 1.132).\n\n\t* lib/net/http.rb (Net::HTTP#post, request_post, request): should\n\t  set Content-Type: x-www-form-urlencoded by default.\n\n\t* lib/net/http.rb (Net::HTTPHeader#content_type): should return\n\t  nil when there's no Content-Type.\n\n\t* lib/net/http.rb (Net::HTTPHeader#sub_type): should return nil\n\t  when there's no sub Content-Type (e.g. \"Content-Type: text\").\n\n\t* lib/net/http.rb (Net::HTTPHeader#type_params): wrongly failed\n\t  when there's no Content-Type.\n\nWed Jul 26 18:35:38 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: sync with HEAD (rev 1.25).\n\n\t* ext/strscan/strscan.c (strscan_do_scan):\n\t  StringScanner.new(\"\").scan(//) should return \"\". [ruby-Bugs:4361]\n\nWed Jul 26 18:14:19 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/pty/pty.c (getDevice): retry once after GC on failure.\n\t  [ruby-core:08282]\n\nWed Jul 26 17:28:16 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): prepend \"..\" to %u for negative bignum,\n\t  but not \"-\".  fixed: [ruby-core:08167]\n\nWed Jul 26 16:39:07 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_scan): add string modification check.\n\t  [ruby-core:7216]\n\nWed Jul 26 16:06:03 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::read_multipart): check\n\t  multipart boundary end.  a patch from Fujioka <fuj at rabbix.jp>\n\t  [ruby-dev:28470]\n\nWed Jul 26 01:02:59 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: suppress warnings by automake 1.8 or later.\n\nTue Jul 25 00:30:06 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/prettyprint.rb: RD to RDoc conversion by Hugh Sasse.\n\nTue Jul 25 14:49:51 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb (configuration): typo.\n\nTue Jul 25 13:14:32 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_proc_times): rename hz to hertz to avoid name\n\t  crash on AIX.  [ruby-dev:29126]\n\nMon Jul 24 22:03:40 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (backtrace): skip frames successive on node and method name.\n\nMon Jul 24 17:55:55 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_f_system): add security check.  [ruby-talk:202947]\n\n\t* process.c (rb_f_system): move signal right before fork to avoid\n\t  signal handler intervention.\n\nMon Jul 24 15:51:52 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* ext/readline/readline.c (readline_readline): rl_deprep_term_function\n\t  may be NULL with libedit.  reported by Ryan Davis.  [ruby-dev:29070]\n\nMon Jul 24 15:19:55 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): revert last change.  [ruby-dev:29112]\n\t  [ruby-core:08374]\n\nSun Jul 23 22:59:49 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* test/socket/test_unix.rb: disabled on cygwin.\n\t  reported by Kouhei Yanagita.  [ruby-dev:29080]\n\nFri Jul 21 21:21:08 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_call0): include funcalled methods in caller list.\n\t  fixed: [ruby-core:08290]\n\nFri Jul 21 12:11:00 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb, lib/mkmf.rb (with_destdir): remove drive letter before\n\t  prepending destdir on DOSISH.\n\nThu Jul 20 15:07:14 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h: export classes/modules to implement sandbox.\n\t  [ruby-core:08283]\n\nThu Jul 20 00:06:29 2006  Keiju Ishitsuka  <keiju@ishitsuka.com>\n\n\t* lib/irb/completion.rb: support for completion of numeric\n\t  number. [ruby-dev: 29038]\n\nWed Jul 19 23:53:05 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/parser.rb, lib/rss/utils.rb: added documents.\n\nTue Jul 18 22:10:13 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_f_system): block SIGCHLD during the process\n\t  execution, like glibc system(3) does.  [ruby-talk:202361]\n\nTue Jul 18 23:12:14 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (open_ifs_socket): should not use plain malloc.\n\n\t* win32/win32.c (rb_w32_opendir): should not use plain realloc.\n\nTue Jul 18 18:05:49 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* test/ruby/test_float.rb (TestFloat::test_strtod): update test to\n\t  conform strtod change.\n\nTue Jul 18 15:49:42 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_unpack): propagate association array to copied\n\t  string.  [ruby-core:08223]\n\n\t* pack.c (pack_unpack): return referenced string itself if it has\n\t  same length as specified.  a patch from <nobu at ruby-lang.org>\n\t  in [ruby-core:08225].\n\n\t* pack.c (pack_pack): taint 'p' packed strings.\n\nTue Jul 18 14:03:02 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/webrick/httpserver.rb (WEBrick::HTTPServer::unmount): remove\n\t  inpect argument from sprintf.  [ruby-dev:29039]\n\nTue Jul 18 10:53:37 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (rb_cstr_to_dbl): limit out-of-range message.\n\n\t* util.c (ruby_strtod): return end pointer even if ERANGE occurred.\n\t  fixed: [ruby-dev:29041]\n\nMon Jul 18 00:43:05 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.c (ruby_strtod): stop at dot not followed by digits.\n\t  fixed: [ruby-dev:29035]\n\nTue Jul 18 00:01:27 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: remove LIBRUBY_SO if static linked extensions exist.\n\nMon Jul 17 23:30:46 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (rb_cv_msvcrt): defaulted to msvcrt.  Workaround for a\n\t  bug of cygwin 1.5.20.\n\nMon Jul 17 13:43:05 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (define_swapx): should not use plain malloc.\n\nMon Jul 17 12:58:41 2006  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: should use ac_cv_lib_dl_dlopen=no on MinGW.\n\nSat Jul 15 23:50:12 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_require_safe): wait for another thread requiring the same\n\t  feature.  fixed: [ruby-core:08229]\n\nSat Jul 15 01:27:13 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (has_magic): glob names contain alphabets to enable case fold\n\t  search also for directories.  fixed: [ruby-talk:201917]\n\nSat Jul 15 01:09:22 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.c (malloc): use xmalloc/xcalloc instead of plain\n\t  malloc/calloc, to detect memory allocation failure.  see\n\t  <http://www.nongnu.org/failmalloc/>.\n\n\t* gc.c (rb_memerror): should not raise empty nomem_error.\n\nFri Jul 14 13:08:13 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add methods for new features of latest Tcl/Tk8.5.\n\n\t* ext/tk/lib/tk/namespace.rb: ditto.\n\nFri Jul 14 02:30:12 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/monitor.rb: document patch from Hugh Sasse <hgs at dmu.ac.uk>.\n\t  [ruby-core:08205]\n\nFri Jul 14 01:09:46 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (then): error in warning action.\n\nFri Jul 14 00:10:15 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_pop): may cause realloc oscillation.  a patch\n\t  from MORITA Naoyuki <mlgetter at kidou.sakura.ne.jp>.\n\t  [ruby-dev:29028]\n\nThu Jul 13 22:23:56 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/composite.rb: improve handling of the classname on the\n\t  option database for the widget class which includes TkComposite.\n\nThu Jul 13 20:32:19 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/parser.rb: updated documents by a patch from\n\t  Hugh Sasse <hgs at dmu.ac.uk>. [ruby-core:8194]\n\nWed Jul 12 13:54:09 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (then): we'd like to reserve colon here for the future.\n\t  warning added.\n\nTue Jul 11 20:58:18 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h: export rb_cMethod.  [ruby-talk:201259]\n\nTue Jul 11 19:13:33 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: remove restriction on the class of\n\t  pseudo-toplevel.\n\nTue Jul 11 18:00:57 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: security fix.\n\nTue Jul 11 17:33:39 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* string.c (rb_str_dump): need to extend len for \\b.\n\nMon Jul 10 22:00:00 2006  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c: Allows '_' to appear within\n\t  digits.  [ruby-dev:28872]\n\n\t* ext/bigdecimal/lib/bigdecimal/util.rb: Bug in to_r reported by\n\t  [ruby-list:42533] fixed.\n\nMon Jul 10 19:22:19 2006  Tanaka Akira  <akr@fsij.org>\n\n\t* gc.c (gc_sweep): expand heap earlier.\n\t  reported by MORITA Naoyuki.  [ruby-dev:28960]\n\nMon Jul 10 18:59:34 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/font.rb: sorry. mistaken to patch.\n\nMon Jul 10 18:46:52 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c: make SEGV risk lower at exit.\n\n\t* ext/tk/lib/tk.rb: ditto.\n\n\t* ext/tk/lib/multi-tk.rb: fail to call function-style methods on slave\n\t  interpreters. The strategy (MultiTkIp_PseudoToplevel_Evaluable) to\n\t  fix the problem is a little tricky. You may have to take care of\n\t  conflicting with it.\n\n\t* ext/tk/lib/tk.rb: a little change for the pseudo-toplevel strategy.\n\n\t* ext/tk/lib/tk/font.rb: ditto.\n\n\t* ext/tk/lib/tk/msgcat.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/itk/incr_tk.rb: ditto.\n\n\t* ext/tk/sample/demos-en/widget: fail to call function-style methods\n\t  on sample scripts. To fix it, a strategy which similar to the way\n\t  on MultiTiIp is used. Please take care when re-write and re-run a\n\t  demo script on the Widget-Demo code viewer.\n\n\t* ext/tk/sample/demos-jp/widget: ditto.\n\nMon Jul 10 13:58:40 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* signal.c (ruby_nativethread_signal, posix_nativethread_signal,\n\t  sigsend_to_ruby_thread, install_nativethread_sighandler):\n\t  nativethread-support on signal handler. RE-backport from 1.9.\n\n\t* ruby.h (HAVE_NATIVETHREAD_KILL): ditto.\n\n\t* eval.c (ruby_native_thread_kill): ditto.\n\nMon Jul 10 10:54:14 2006  Ryan Davis  <ryand@zenspider.com>\n\n\t* lib/rdoc/parsers/parse_f95.rb: massive overhaul from Yasuhiro\n\t  Morikawa including new file suffixes, function support, public\n\t  variables and constants, derived-types, defined operators and\n\t  assignments, namelists, and subroutine and function\n\t  arguments. Truly massive.\n\n\t* lib/rdoc/diagram.rb: diagrams are now cached.\n\n\t* lib/irb/completion.rb: fixed a crasher when completing against\n\t  an unnamed class/module.\n\n\t* lib/rdoc/parsers/parse_c.rb: private comment (--/++) support in\n\t  C-file rdoc.\n\n\t* lib/debug.rb: minor clarification in help.\n\n\t* lib/pp.rb: minor clarification on exception.\n\nMon Jul 10 09:29:12 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_clear_cache_for_undef): clear entries for included\n\t  module.  fixed: [ruby-core:08180]\n\nMon Jul 10 01:48:38 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.h (st_data_t): use pointer sized integer for st_data_t.\n\t  [ruby-dev:28988]\n\nSun Jul  9 18:06:47 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (try_constant): fix for value 1 at cross compiling.\n\n\t* lib/mkmf.rb (create_makefile): prevent substitution of macro\n\t  definition.  fixed: http://www.yotabanana.com/lab/20060624.html#p02\n\nSun Jul  9 00:54:34 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (next_jump): deal with destination of next.\n\t  fixed: [ruby-core:08169]\n\nFri Jul  7 00:38:49 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_default): should not call default procedure if\n\t  no key is given.  [ruby-list:42541]\n\nFri Jul  7 00:29:10 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_mload): a patch from Daniel Berger\n\t  <Daniel.Berger at qwest.com>.  [ruby-core:08128]\n\nThu Jul  6 22:21:57 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (rb_proc_times): use sysconf(_SC_CLK_TCK) value prior to\n\t  HZ and CLK_TCK.  fixed: [ruby-talk:200293]\n\nThu Jul  6 22:17:21 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/racc/cparse/cparse.c: sync with original code, rev 1.8.\n\n\t* ext/racc/cparse/cparse.c: should mark CparseParams objects.\n\n\t* lib/racc/parser.rb: sync with original code, rev 1.8.\n\n\t* lib/racc/parser.rb: update coding style.\n\nMon Jul  3 19:04:38 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c (ip_make_menu_embeddable): help to make a menu\n\t  widget embeddable (pack, grid, and so on) like as a general widget.\n\t  However, an embeddable menu may require to be definied some event\n\t  bindings for general use.\n\n\t* ext/tk/lib/tk/event.rb: [bug fix] Tk.callback_break and\n\t  Tk.callback_continue don't work on MultiTkIp.\n\n\t* ext/tk/lib/multi-tk.rb: ditto.\n\n\t* ext/tk/lib/tk.rb: lack of Tk.callback_return.\n\n\t* ext/tk/lib/tk/menu.rb: improve creating clone menus.\n\nMon Jul  3 14:42:06 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/etc/extconf.rb (PW_UID2VAL, PW_GID2VAL): defaulted to conversion\n\t  from int, and sys/types.h needs to be included before grp.h.\n\t  fixed: [ruby-dev:28938]\n\nMon Jul  3 01:14:15 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_inspect): encode \\b (\\010) for escape.\n\t  [ruby-dev:28927]\n\n\t* string.c (rb_str_dump): ditto.\n\nSun Jul  2 19:17:56 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/racc/cparse/cparse.c: sync with original code (rev 1.7).\n\n\t* ext/racc/cparse/cparse.c: use rb_catch instead of rb_iterate.\n\t  Giving a block to a Ruby-level method by rb_iterate is obsolete on\n\t  Ruby 1.9.  Note that current cparse.c still includes one\n\t  rb_iterate call on Ruby 1.8, but it is not a problem (at least\n\t  just now).\n\nSat Jul  1 15:15:49 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* test/socket/test_nonblock.rb: add timeout to send/receive\n\t  an empty UDP packet.\n\t  [ruby-dev:28820]\n\nFri Jun 30 23:46:23 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: should test isinf for Solaris with GCC compiler.\n\t  a patch from <ville.mattila at stonesoft.com>.  [ruby-core:07791]\n\n\t* configure.in: -shared patch from Andrew Morrow\n\t  <andrew.c.morrow at gmail.com>.  [ruby-core:08100]\n\nThu Jun 29 18:58:51 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_version): fix patch\n\t  failure.\n\nThu Jun 29 18:00:51 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c: add RDoc document.  a patch from\n\t  mathew <meta at pobox.com>.   [ruby-core:07050]\n\nWed Jun 28 15:47:14 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/optparse.rb: RDoc patch from Robin Stocker <robin@nibor.org>\n\t  [ruby-core:08087]\n\nWed Jun 28 19:04:34 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* test/socket/test_unix.rb: test_seqpacket_pair removed.\n\t  [ruby-dev:28846]\n\nTue Jun 27 23:03:49 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c: RDoc update for =~ method.  a patch from Alex Young\n\t  <alex at blackkettle.org>.  [ruby-core:08068]\n\nTue Jun 27 22:47:18 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c: forgot to update TCLTKLIB_RELEASE_DATE.\n\n\t* ext/tk/lib/tk.rb (tk_tcl2ruby): [bug fix] sometimes fail to convert\n\t  a tcl string to a ruby object if the tcl string includes \"\\n\".\n\nTue Jun 27 16:04:05 2006  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.h: define isascii on MinGW for msvcrt compatibility.\n\n\t* configure.in: set ac_cv_header_sys_time_h=no on MinGW\n\t  for msvcrt compatibility.\n\nTue Jun 27 11:36:02 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/etc/etc.c (setup_passwd, setup_group): allow bignum uid, gid and\n\t  so on.  [ruby-talk:199102]\n\nMon Jun 26 13:37:27 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc: Merge from HEAD.\n\t  Add options to limit the ri search path.\n\nTue Jun 27 00:54:08 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.c (powersOf10): constified.\n\nMon Jun 26 18:37:44 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c (ip_delete): fix SEGV when a slave-ip is\n\t  deleted on callback.\n\nMon Jun 26 10:47:42 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (pipe_open): avoid closing uninitialized file descriptors.\n\t  a patch from <tommy at tmtm.org> [ruby-dev:28600]\n\nMon Jun 26 09:56:22 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.[ch] (rb_w32_send, rb_w32_sendto): constified.\n\nSun Jun 25 23:02:12 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, mkconfig.rb: catch-up for latest autoconf.\n\nSat Jun 24 06:35:00 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* signal.c: revert last change.\n\n\t* ruby.h: ditto.\n\n\t* eval.c: ditto.\n\nThu Jun 22 11:52:02 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/net/http.rb (Net::HTTPResponse): duplicated error 501;\n\t  HTTPInternalServerError should be error 500.  [ruby-core:08037]\n\nThu Jun 22 05:15:58 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c (sock_s_socketpair): try GC only once.\n\t  [ruby-dev:28778]\n\nWed Jun 21 21:28:32 2006  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb (jd_to_commercial): now works fine even if in\n\t  mathn-ized context.\n\nWed Jun 21 17:32:31 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* signal.c (ruby_nativethread_signal, posix_nativethread_signal,\n\t  sigsend_to_ruby_thread, install_nativethread_sighandler):\n\t  nativethread-support on signal handler (backport from 1.9).\n\n\t* ruby.h (HAVE_NATIVETHREAD_KILL): ditto.\n\n\t* eval.c (ruby_native_thread_kill): ditto.\n\nWed Jun 21 08:39:54 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/xmlrpc/create.rb (XMLRPC::Create::conv2value): merge Date\n\t  and Time processing.  [ruby-core:08033]\n\nWed Jun 21 01:40:25 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (yylex, reswords): modifier token is no longer returned in\n\t  fname state.  [ruby-dev:28775]\n\nWed Jun 21 01:12:46 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: RSS::Element.def_corresponded_attr_writer\n\t  supported date type.\n\nTue Jun 20 22:08:36 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* test/rss/test_parser.rb: split parser tests into ...\n\t* test/rss/test_parser_1.0.rb: ... RSS 1.0 parsing tests and ...\n\t* test/rss/test_parser_2.0.rb: ... RSS 2.0 parsing tests.\n\nTue Jun 20 21:19:06 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: provided default RSS::Element#children.\n\n\t* lib/rss/0.9.rb: used default RSS::Element#children.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\nTue Jun 20 21:04:33 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: provided default RSS::Element#_tags.\n\n\t* lib/rss/0.9.rb: used default RSS::Element#_tags.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\nTue Jun 20 20:47:07 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: hide RSS::Element.install_model.\n\t  (RSS::Element.install_have_child_element,\n\t   RSS::Element.install_have_children_element,\n\t   RSS::Element.install_text_element,\n\t   RSS::Element.install_date_element): call\n\t  RSS::Element.install_model internally.\n\n\t* lib/rss/0.9.rb: followed new API.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/content.rb: ditto.\n\t* lib/rss/dublincore.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/syndication.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\nTue Jun 20 20:18:05 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: add check for OBJ_NAME_do_all_sorted.\n\n\t* ext/openssl/ossl_cipher.c (ossl_s_ciphers): new method\n\t  OpenSSL::Cipher.ciphers. it returns all the cipher names.\n\n\t* ext/openssl/lib/openssl/cipher.rb:\n\t  - add constants AES128, AES192, AES256. [ruby-dev:28610]\n\t  - reimplement without eval()\n\n\t* ext/openssl/lib/openssl/digest.rb: reimplement without eval().\n\n\t* test/openssl/test_cipher.rb, test_digest: fix about reimplemented\n\t  features.\n\n\t* sample/openssl/cipher.rb: rewrite all.\n\nSat Jun 19 11:21:46 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/test/unit/assertions.rb: Merge RDoc from HEAD.\n\nTue Jun 20 01:06:57 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb:\n\t  - cleanup validation mechanism. Now, #XXX_validation is\n\t    needless.\n\t  - changed internal variable name RSS::Element::MODEL to\n\t    RSS::Element::MODELS.\n\t  - RSS::Element.install_model requires uri.\n\n\t* lib/rss/0.9.rb: followed new validation API.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/content.rb: ditto.\n\t* lib/rss/dublincore.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/syndication.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\nMon Jun 19 23:40:59 2006  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/lib/kconv.rb: remove default -m0 and fix document.\n\n\t* ext/nkf/nkf-8/{nkf.c, config.h, utf8tbl.c, utf8tbl.h}:\n\t  imported nkf 2.0.7.\n\nMon Jun 19 22:31:59 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb:\n\t  - provided default #to_s as RSS::Element#to_s.\n\t  - removed RSS::Element#other_element.\n\t  - RSS::Element#tag requires attributes as Hash instead of Array.\n\n\t* lib/rss/0.9.rb: removed #to_s to use RSS::Element#to_s.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\n\t* lib/rss/2.0.rb: removed #other_element.\n\nMon Jun 19 22:09:16 2006  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c(ole_invoke): support some kind of\n\t  method of word. [ruby-Bugs#3237]\n\n\t* ext/win32ole/tests/test_word.rb: ditto.\n\n\t* ext/win32ole/tests/testall.rb: ditto.\n\nMon Jun 19 00:02:17 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: automatically detected attributes.\n\n\t* lib/rss/0.9.rb: removed #_attrs.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\n\t* lib/rss/parser.rb: followed new internal API.\n\nMon Jun 19 00:00:17 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: fix bug: initialize improper tables.\n\nSun Jun 18 22:36:13 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: RSS::Element#initialize accepts initial\n\t  attributes.\n\t* lib/rss/0.9.rb: ditto.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/dublincore.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\n\t* lib/rss/utils.rb: added Utils.element_initialize_arguments? to\n\t  detect backward compatibility initial arguments.\n\n\t* lib/rss/parser.rb: user initial attributes to initialize\n\t  RSS::Element.\n\nSun Jun 18 18:24:42 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/converter.rb: use NKF for Uconv fallback.\n\nSun Jun 18 18:22:04 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* test/rss/test_image.rb: shared name space configuration.\n\nSun Jun 18 18:13:25 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: improved ignore_unknown_element\n\t  handling. RSS::NotExpectedTagError provides tag URI.\n\t* lib/rss/parser.rb: ditto.\n\t* lib/rss/0.9.rb: ditto.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/content.rb: ditto.\n\t* lib/rss/dublincore.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/syndication.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\n\t* test/rss/rss-assertions.rb: checked URI of not expected tag too.\n\t* test/rss/test_parser.rb: ditto.\n\nSun Jun 18 18:08:36 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: changed empty namespace URI representation to \"\"\n\t  from nil.\n\t* lib/rss/parser.rb: ditto.\n\t* lib/rss/0.9.rb: ditto.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\nSun Jun 18 18:03:50 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/parser.rb: removed a guard for requiring open-uri.\n\nSun Jun 18 18:01:26 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: fixed typo: except -> expect\n\t* lib/rss/parser.rb: ditto.\n\t* test/rss/rss-assertions.rb: ditto.\n\t* test/rss/test_parser.rb: ditto.\n\nSun Jun 18 17:52:39 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: RSS::Element#calc_indent became to be deprecated.\n\t* lib/rss/0.9.rb: ditto.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* lib/rss/trackback.rb: ditto.\n\n\t* test/rss/test_1.0.rb: removed RSS::Element.indent_size tests.\n\t* test/rss/test_2.0.rb: ditto.\n\nSun Jun 18 00:49:11 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c (bsock_recv_nonblock): new method\n\t  BasicSocket#recv_nonblock.\n\t  (udp_recvfrom_nonblock): renamed from ip_recvfrom_nonblock.\n\t  IPSocket#recvfrom_nonblock is moved to UDPSocket#recvfrom_nonblock.\n\t  (unix_recvfrom_nonblock): removed.\n\t  UNIXSocket#recvfrom_nonblock is removed.\n\nSat Jun 17 22:17:17 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/mathn.rb (Integer::prime_division): raise ZeroDivisionError\n\t  on zeros.  [ruby-dev:28739]\n\nSat Jun 17 14:53:32 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb: backport from 1.9.\n\t  (Kernel#Pathname): new method.\n\nSat Jun 17 10:30:41 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (Hash#merge, Enumerable#sort_by): removed.\n\n\t* lib/rss/rss.rb (RSS::RootElementMixin#to_xml): added.\n\t  [ruby-talk:197284]\n\n\t  We can convert RSS version easily like the following:\n\t    rss10 = RSS::Parser.parse(File.read(\"1.0.rdf\"))\n\t    File.open(\"2.0.rss\", \"w\") {|f| f.print(rss10.to_xml(\"2.0\"))}\n\n\t* test/rss/test_1.0.rb: added #to_xml test.\n\t* test/rss/test_2.0.rb: ditto.\n\n\t* test/rss/rss-testcase.rb: added some helper methods that\n\t  generates sample RSS 2.0.\n\n\t* sample/rss/convert.rb: added a sample script to convert RSS format.\n\nSat Jun 17 10:23:22 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (Kernel#funcall): removed.\n\t* lib/rss/parser.rb (Kernel.URI): removed.\n\n\t* lib/rss/maker/: supported\n\t    xxx.new_yyy do |yyy|\n\t      yyy.zzz = zzz\n\t      ...\n\t    end\n\t  style and this style became the style of the recommendation.\n\n\t  Old style\n\t    yyy = xxx.new_yyy\n\t    yyy.zzz = zzz\n\t    ...\n\t  is supported too but this style isn't recommended.\n\t  [ruby-talk:197284]\n\n\t* test/rss/test_*maker*.rb: used new recommended style.\n\nSat Jun 17 09:03:47 2006  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss, test/rss: backported from trunk. (2005-11-16 - now)\n\n\t* lib/rss/rss.rb (RSS::VERSION): 0.1.5 -> 0.1.6.\n\t* test/rss/test_version.rb (RSS::TestVersion#test_version): ditto.\n\n\t* lib/rss/trackback.rb: added TrackBack prefix.\n\t* lib/rss/maker/trackback.rb: ditto.\n\n\t* lib/rss/rss.rb : removed needless argument 'prefix'.\n\t* lib/rss/parser.rb: ditto.\n\n\t* lib/rss/1.0.rb: added rdf:Bag.\n\n\t* lib/rss/taxonomy.rb: implemented taxonomy module.\n\t* test/rss/test_taxonomy.rb: added tests for taxonomy support.\n\n\t* lib/rss/1.0.rb: added convenience method 'resources'.\n\t* lib/rss/taxonomy.rb: ditto.\n\t* test/rss/rss-assertions.rb: added test for 'resources'.\n\t* test/rss/test_taxonomy.rb: ditto.\n\n\t* lib/rss/rss.rb: fixed a indentation bug.\n\t* lib/rss/taxonomy.rb: fixed <taxo:topic> #to_s bug.\n\t* test/rss/test_taxonomy.rb: added a #to_s test.\n\n\t* lib/rss/maker/taxonomy.rb: implemented taxonomy module for RSS\n\t  Maker.\n\t* lib/rss/taxonomy.rb: supported RSS Maker.\n\t* lib/rss/maker.rb: added taxonomy module support.\n\n\t* lib/rss/rss.rb: adjusted to other element API.\n\t* lib/rss/1.0.rb: adjusted to other element API but backward\n\t  compatibility is reserved.\n\t* lib/rss/0.9.rb: ditto.\n\n\t* test/rss/test_maker_taxo.rb: added test case for taxonomy module\n\t  for RSS Maker.\n\t* test/rss/test_setup_maker_1.0.rb: added tests for taxo:topic.\n\n\t* test/rss/test_setup_maker_1.0.rb: added backward compatibility\n\t  test.\n\t* test/rss/test_setup_maker_0.9.rb: ditto.\n\t* test/rss/test_setup_maker_2.0.rb: ditto.\n\n\t* test/rss/rss-testcase.rb: added convenience method for setting\n\t  up taxo:topic.\n\t* test/rss/rss-assertions.rb: added assertion for taxo:topic.\n\n\t* sample/rss/blend.rb: followed new API.\n\n\t* lib/rss/taxonomy.rb: changed class or module prefix to\n\t  Taxonomy from Taxo.\n\t* lib/rss/maker/taxonomy.rb: ditto.\n\n\t* test/rss/test_taxonomy.rb: use #reject directory.\n\n\t* lib/rss/: use #__send__ instead of #send.\n\t* test/rss/: ditto.\n\n\t* lib/rss/parser.rb: added entity handling type predicate.\n\t* lib/rss/rexmlparser.rb: ditto.\n\t* lib/rss/xmlparser.rb: ditto.\n\t* lib/rss/xmlscanner.rb: ditto.\n\n\t* lib/rss/xmlscanner.rb: more robust entity handling.\n\n\t* test/rss/test_parser.rb: added an entity handling test.\n\n\t* test/rss/test_2.0.rb: added RSS 2.0 tests.\n\t* test/rss/rss-assertions.rb: extended XML stylesheet assertion.\n\t* lib/rss/0.9.rb: added initialize method.\n\t* test/rss/test_1.0.rb: cleanup.\n\n\t* lib/rss/image.rb: added Image prefix.\n\t* lib/rss/maker/image.rb: ditto.\n\n\t* lib/rss/rss.rb: improved type conversion.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/0.9.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/syndication.rb: ditto.\n\n\t* test/rss/test_2.0.rb: added type conversion tests.\n\t* test/rss/test_accessor.rb: ditto.\n\t* test/rss/test_to_s.rb: ditto.\n\t* test/rss/test_syndication.rb: ditto.\n\t* test/rss/test_setup_maker_2.0.rb: ditto.\n\t* test/rss/test_setup_maker_1.0.rb: ditto.\n\t* test/rss/test_setup_maker_0.9.rb: ditto.\n\t* test/rss/test_maker_sy.rb: ditto.\n\t* test/rss/test_maker_image.rb: ditto.\n\t* test/rss/test_maker_2.0.rb: ditto.\n\t* test/rss/test_maker_0.9.rb: ditto.\n\t* test/rss/test_image.rb: ditto.\n\n\t* test/rss/test_maker_1.0.rb: use assert instead of assert_equal.\n\n\t* test/rss/rss-assertions.rb: improved type conversion assertions.\n\n\t* lib/rss/rss.rb: added backward compatibility codes.\n\t* lib/rss/parser.rb: ditto.\n\t* test/rss/test_parser.rb: ditto.\n\t* test/rss/test_2.0.rb: ditto.\n\nSat Jun 17 02:01:00 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (Kernel#pretty_inspect): defined for pretty printed\n\t  string.\n\nSat Jun 17 00:23:58 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (reswords): kDO_BLOCK was missing.  fixed: [ruby-core:7995]\n\nSat Jun 17 00:02:15 2006  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_propertyput): support\n\t  PROPERTYPUTREF. [ruby-talk:183042]\n\n\t* ext/win32ole/tests/test_propertyputref.rb: ditto.\n\nThu Jun 15 23:02:47 2006  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (fole_methods): The return value\n\t  of WIN32OLE#ole_methods should include PROPERTYPUTREF methods.\n\n\t* ext/win32ole/win32ole.c (fole_put_methods): The return value\n\t  of WIN32OLE#ole_put_methods should include PROPERTYPUTREF methods.\n\n\t* ext/win32ole/tests/test_ole_methods.rb: ditto.\n\n\t* ext/win32ole/tests/testall.rb : ditto.\n\nWed Jun 14 18:23:28 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* enum.c (enum_any): Documentation typo.\n\nWed Jun 14 15:01:09 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser#warn): Don't print\n\t  warnings when -q is set.\n\nWed Jun 14 23:03:53 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* configure.in: check sizeof(rlim_t).\n\t  check setrlimit.\n\n\t* process.c (proc_getrlimit): new method Process.getrlimit.\n\t  (proc_setrlimit): new method Process.setrlimit.\n\n\t* ruby.h (NUM2ULL): new macro.\n\nMon Jun 12 22:25:09 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): adjust precision length to prevent\n\t  splitting multi-byte characters.  [ruby-list:42389]\n\nSun Jun 11 23:20:07 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Arguable#getopts): pass self to the\n\t  parser.\n\nSun Jun 11 10:00:57 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.h (write): not need to define on bcc.\n\nSun Jun 11 08:30:33 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser#getopts): new methods.\n\nSat Jun 10 18:02:40 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/bigdecimal/lib/bigdecimal/newton.rb (Newton::nlsolve): typo\n\t  fixed: raize -> raise.  [ruby-talk:196608]\n\nThu Jun  8 14:19:17 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.[ch] (rb_w32_read, rb_w32_write): new functions.\n\t  use recv() and send() when fd is socket. fixed: [ruby-dev:28694]\n\nWed Jun  7 16:22:51 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tempfile.rb (Tempfile::make_tmpname): put dot between\n\t  basename and pid.  [ruby-talk:196272]\n\nWed Jun  7 14:53:04 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (errmap): add some winsock errors.\n\nWed Jun  7 11:34:38 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* configure.in: add new configure option `--with-winsock2' for mingw.\n\n\t* win32/Makefile.sub (config.h): define USE_WINSOCK2 in config.h\n\t  instead of in CPPFLAGS.\n\n\t* ext/socket/extconf.rb: determine whether to use winsock2 or not\n\t  by using with_config.\n\nWed Jun  7 10:45:10 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/{configure.bat, setup.mak, Makefile.sub, win32.h}: add\n\t  new configure option `--with-winsock2'.\n\n\t* win32/win32.c (StartSockets): ditto.\n\n\t* ext/socket/extconf.rb: ditto.\n\n\t* win32/win32.c (open_ifs_socket): new function.\n\n\t* win32/win32.c (StartSockets, rb_w32_socket): use open_ifs_socket()\n\t  instead of socket().\n\t  ifs socket support is backported from trunk.\n\nWed Jun  7 09:14:44 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): binding for the return event hook should have\n\t  consistent scope.  [ruby-core:07928]\n\n\t* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from\n\t  event_hooks.\tno guarantee for arbitrary hook deletion.\n\t  [ruby-dev:28632]\n\nMon Jun  5 18:12:12 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c (sock_s_unpack_sockaddr_in): reject\n\t  non-AF_INET/AF_INET6 sockaddr.\n\t  (sock_s_unpack_sockaddr_un): reject non-AF_UNIX sockaddr.\n\t  [ruby-dev:28691]\n\nSun Jun  4 20:40:19 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c: fix sockaddr_un handling.\n\t  [ruby-dev:28677]\n\nFri Jun  2 22:08:17 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/forwardable.rb: RDoc typo fix from Jan Svitok\n\t  <jan.svitok at gmail.com>.  [ruby-core:07943]\n\nFri Jun  2 19:02:09 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: use create_header.\n\n\t* ext/openssl/ossl.h, ext/openssl/openssl_missing.h:\n\t  include RUBY_EXTCONF_H.\n\nFri Jun  2 17:16:52 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (CLEANINGS): remove extconf.h by distclean if created.\n\nFri Jun  2 00:11:19 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c (s_recvfrom): alen may be zero with UNIXSocket\n\t  too.  (tested on NetBSD 3.0)\n\t  (s_recvfrom_nonblock): extracted from sock_recvfrom_nonblock.\n\t  (sock_recvfrom_nonblock): use s_recvfrom_nonblock.\n\t  (ip_recvfrom_nonblock): new method: IPSocket#recvfrom_nonblock\n\t  (unix_recvfrom_nonblock): new method: UNIXSocket#recvfrom_nonblock\n\t  (s_accept_nonblock): extracted from sock_accept_nonblock.\n\t  (sock_accept_nonblock): use s_accept_nonblock.\n\t  (tcp_accept_nonblock): new method: TCPServer#accept_nonblock\n\t  (unix_accept_nonblock): new method: UNIXServer#accept_nonblock\n\nThu Jun  1 19:12:37 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_cmdvector): backslashes inside single-quotes\n\t  no longer has special meanings.  fixed: [ruby-list:42311]\n\nThu Jun  1 16:14:41 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_getcwd): runtime's getcwd() will not success\n\t  if the length of the cwd is longer than MAX_PATH.\n\t  fixed [ruby-list:42335]\n\nThu Jun  1 11:29:14 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_getcwd): set errno if not set.\n\t  fixed [ruby-list:42346]\n\nSat May 27 11:29:46 2006  nobuyoshi nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): remove extinit files if no statically linked\n\t  extensions.\n\nFri May 26 09:05:11 2006  nobuyoshi nakada  <nobu@ruby-lang.org>\n\n\t* ruby.h, lib/mkmf.rb (create_header): clear command line options for\n\t  macros moved to extconf.h.\n\n\t* ext/extmk.rb (extract_makefile, extmk): made RUBY_EXTCONF_H and\n\t  EXTSTATIC permanent.\n\n\t* ext/{dbm,digest/*,socket,zlib}/extconf.rb: used $defs and $INCFLAGS.\n\n\t* {bcc32,win32,wince}/Makefile.sub (COMPILE_C, COMPILE_CXX): added\n\t  $(INCFLAGS).\n\n\t* lib/mkmf.rb (configuration): add $defs unless extconf.h was created.\n\nThu May 25 01:52:07 2006  nobuyoshi nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (pkg_config): particular config commands support.\n\n\t* ext/extmk.rb: deal with $static set in extconf.rb.\n\n\t* mkconfig.rb: merge multiple entries to an entry with multiple lines.\n\n\t* lib/mkmf.rb: allow a series of commands to link.\n\n\t* win32/Makefile.sub: embed manifests.\n\n\t* win32/setup.mak: suffix OS name by runtime version.\n\nWed May 24 23:52:11 2006  nobuyoshi nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (ac_install_sh): ignore dummy install-sh.\n\t  [ruby-talk:193876]\n\nWed May 24 03:10:48 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/ssl.rb\n\t  (OpenSSL::SSL::SocketForwarder#setsockopt,getsockopt): typo fixed.\n\nMon May 22 17:54:12 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_recvfrom_nonblock): use rb_read_pending\n\t  instead of rb_io_read_pending.\n\t  [ruby-dev:28663]\n\nMon May 22 17:30:04 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* rubyio.h (rb_io_set_nonblock): declared.\n\n\t* io.c (rb_io_set_nonblock): new function.\n\t  (io_getpartial): nonblocking read support.\n\t  (io_read_nonblock): new method: IO#read_nonblock.\n\t  (io_write_nonblock): new method: IO#write_nonblock.\n\n\t* ext/socket/socket.c\n\t  (sock_connect_nonblock): new method: Socket#connect_nonblock.\n\t  (sock_accept_nonblock): new method: Socket#accept_nonblock.\n\t  (sock_recvfrom_nonblock): new method: Socket#recvfrom_nonblock.\n\n\t  [ruby-core:7917]\n\nMon May 22 15:57:39 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (umethod_bind): should not update original class.\n\t  [ruby-dev:28636]\n\nMon May 22 13:38:57 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ev_const_get): should support constant access from\n\t  within instance_eval().  [ruby-dev:28327]\n\nThu May 18 17:51:32 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_timeval): should round for usec floating\n\t  number.  [ruby-core:07896]\n\n\t* time.c (time_add): ditto.\n\nThu May 18 17:11:45 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::out): support utf-8.  a patch from Fujioka\n\t  <fuj at rabbix.jp>.  [ruby-dev:28649]\n\nThu May 18 00:42:12 2006  nobuyoshi nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb, lib/mkmf.rb: use BUILD_FILE_SEPARATOR in Makefiles.\n\nWed May 17 17:55:26 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (sys_warning): should not call a vararg function\n\t  rb_sys_warning() indirectly.  [ruby-core:07886]\n\nWed May 17 08:17:15 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): try to reduce errors using powersOf10\n\t  table.  [ruby-dev:28644]\n\nTue May 16 15:34:18 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_initialize): should not allow modifying literal\n\t  regexps.  frozen check moved from rb_reg_initialize_m as well.\n\nTue May 16 09:20:16 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_initialize): should not modify untainted objects in\n\t  safe levels higher than 3.\n\n\t* re.c (rb_memcmp): type change from char* to const void*.\n\n\t* dir.c (dir_close): should not close untainted dir stream.\n\n\t* dir.c (GetDIR): add tainted/frozen check for each dir operation.\n\nMon May 15 17:42:39 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):\n\t  typo fixed.  a patch from Florian Gross <florg at florg.net>.\n\nSat May 13 16:14:05 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (PP.mcall): new method.\n\t  (Struct#pretty_print): call Kernel#class and Struct#members even if\n\t  overridden.\n\t  (Struct#pretty_print_cycle): ditto.\n\t  [ruby-core:7865]\n\nThu May 11 19:57:00 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): differ addition to minimize error.\n\t  [ruby-dev:28619]\n\nFri Aug 11 15:39:25 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/yaml/tag.rb: Replace nodoc with stopdoc so Module methods get\n\t  documented.\n\nThu May 11 18:10:43 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): should not raise ERANGE when the input\n\t  string does not have any digits.  [ruby-dev:28629]\n\nSun May  7 03:09:51 2006  Stephan Maka  <stephan@spaceboyz.net>\n\n\t* lib/resolv.rb (Resolv::DNS::Requester::ConnectedUDP#initialize):\n\t  Use AF_INET6 for nameservers containing colons.\n\nSat May  6 00:38:42 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* signal.c (trap): sig should be less then NSIG.  Coverity found\n\t  this bug.  a patch from Kevin Tew <tewk at tewk.com>.\n\t  [ruby-core:07823]\n\nThu May  4 02:24:16 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syck/emitter.c (syck_scan_scalar): avoid accessing\n\t  uninitialized array element.  a patch from Pat Eyler\n\t  <rubypate at gmail.com>.  [ruby-core:07809]\n\n\t* array.c (rb_ary_fill): initialize local variables first.  a\n\t  patch from Pat Eyler <rubypate at gmail.com>.  [ruby-core:07810]\n\n\t* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free\n\t  type_tag.  a patch from Pat Eyler <rubypate at gmail.com>.\n\t  [ruby-core:07808]\n\nWed May  3 02:12:07 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (make_hostent_internal): accept ai_family\n\t  check from Sam Roberts <sroberts at uniserve.com>.\n\t  [ruby-core:07691]\n\nMon May  1 12:23:19 2006    <sinara@blade.nagaokaut.ac.jp>\n\n\t* numeric.c (num_div): use floor rather than rb_Integer().\n\t  [ruby-dev:28589]\n\n\t* numeric.c (flo_divmod): the first element of Float#divmod should\n\t  be an integer. [ruby-dev:28589]\n\n\t* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.\n\nSat Apr 29 22:42:08 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_decode0): should initialize\n\t  flag. [ruby-core:07785]\n\nFri Apr 28 10:53:16 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): should not cut off 18 digits for no\n\t  reason.  [ruby-core:07796]\n\n\t* util.c (ruby_strtod): fixed wrong conversion.\n\nThu Apr 27 01:38:10 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_fill): internalize local variable \"beg\" to\n\t  pacify Coverity.  [ruby-core:07770]\n\nWed Apr 26 16:59:24 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_unpack): now supports CRLF newlines.  a patch from\n\t  <tommy at tmtm.org>.  [ruby-dev:28601]\n\nTue Apr 25 18:00:05 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c (delete_slaves): maybe increment the reference\n\t  count of a NULL Tcl_Obj [ruby-core:07759].\n\nTue Apr 25 07:55:31 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/jcode.rb (String::tr_s): should have translated non\n\t  squeezing character sequence (i.e. a character) as well.  thanks\n\t  to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]\n\nTue Apr 25 00:08:24 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): should check if c is not a\n\t  multibyte character.  a patch from KIMURA Koichi\n\t  <kimura.koichi at canon.co.jp>.  [ruby-dev:28598]\n\nFri Apr 21 15:19:13 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c (lib_eventloop_ensure): refer freed pointer\n\t  [ruby-core:07744] and memory leak.\n\nFri Apr 21 12:14:52 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c: document update patch from Sam Roberts\n\t  <sroberts at uniserve.com>.  [ruby-core:07701]\n\nWed Apr 19 13:55:27 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): too much NEW_LIST()\n\n\t* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.\n\nWed Apr 19 11:57:04 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.\n\t  [ruby-dev:28585]\n\n\t* parse.y (list_concat): revert last change.\n\n\t* parse.y (arg): use NODE_ARGSCAT for placeholder.\n\nWed Apr 19 11:13:17 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from\n\t  mathew <meta at pobox.com>.  [ruby-core:07738]\n\nWed Apr 19 10:13:27 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_const_set): raise error when no target klass is\n\t  supplied.  [ruby-dev:28582]\n\nWed Apr 19 09:49:36 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (list_concat): should not modify nodes other than\n\t  NODE_ARRAY.  [ruby-dev:28583]\n\nTue Apr 18 17:40:37 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: add a binding to a container for a slave IP.\n\n\t* ext/tk/lib/tk.rb: update RELEASE_DATE.\n\n\t* ext/tk/tcltklib.c: forget to reset a Tcl interpreter.\n\n\t* ext/tk/stubs.c: fix potential bugs about handling rb_argv0.\n\nTue Apr 18 00:11:21 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c: block_unique should be 1, not frame_unique.\n\t  [ruby-dev:28577]\n\nFri Aug 11 15:39:25 2006  Eric Hodel  <drbrain@segment7.net>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#find_body): Make RDoc\n\t  ignore C function prototypes.  Patch by Tilman Sauerbeck\n\t  <tilman at code-monkey.de>.  [ruby-core:8574]\n\t* lib/yaml/tag.rb: Replace nodoc with stopdoc so Module methods get\n\t  documented.\n\nMon Apr 10 01:03:10 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* prec.c (prec_prec_f): documentation patch from\n\t  <gerardo.santana at gmail.com>.  [ruby-core:07689]\n\nSat Apr  8 02:34:34 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_pow): second operand may be too big even if\n\t  it's a Fixnum.  [ruby-talk:187984]\n\nSat Apr  8 02:12:38 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* README.EXT: update symbol description.  [ruby-talk:188104]\n\nThu Apr  6 23:28:47 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* COPYING: explicitly note GPLv2.  [ruby-talk:187922]\n\nThu Apr  6 11:18:37 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/panedwindow.rb: lack of arguments. [ruby-core:7681]\n\nThu Apr  6 01:04:47 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tcltklib.c: fix SEGV when embedding to an application.\n\t  [ruby-core:7600]\n\n\t* ext/tk/tcltklib.c: fix SEGV at exit. [ruby-talk:186489]\n\n\t* ext/tk/tkutil/tkutil.c: follow to changing specification of\n\t  instance_eval on ruby-1.9.x.\n\n\t* ext/tk/lib/tk.rb: ditto.\n\n\t* ext/tk/lib/multi-tk.rb: ditto.\n\n\t* ext/tk/lib/tk.rb: remove warning about redefinition of methods.\n\n\t* ext/tk/lib/tk/variable.rb: remove warning about unseting Tcl\n\t  variables.\n\nWed Mar 29 20:54:44 2006  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (fole_getproperty): WIN32OLE#[] should accept\n\t  multi arguments.\n\n\t* ext/win32ole/tests/testWIN32OLE.rb (test_setproperty_bracket): ditto.\n\nWed Mar 29 10:07:44 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c (nkf_each_char_to_hex, encode_fallback_subchar,\n\t  e2w_conv): support C90 compiler.\n\nWed Mar 29 06:48:40 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (backtrace): reports aliased method names in a generated\n\t  backtrace.  a patch from \"U.Nakamura\" <usa at garbagecollect.jp>.\n\t  [ruby-dev:28471]\n\nMon Mar 27 22:19:09 2006  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/{nkf.c, utf8tbl.c, config.h}: imported nkf 2.0.6.\n\t  * Add --ic / --oc option and mapping tables.\n\t  * Add fallback option.\n\t  * Add --no-best-fit-chars option.\n\t  * Fix some bugs.\n\n\t* ext/nkf/nkf.c (nkf_split_options): added for parse option string.\n\n\t* ext/nkf/lib/kconv.rb (Kconv.to*): add -m0.\n\t  Note that Kconv.to* still imply -X.\n\nMon Mar 27 03:17:21 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): insecure calling should be checked for non\n\t  NODE_SCOPE method invocations too.\n\n\t* eval.c (rb_alias): should preserve the current safe level as\n\t  well as method definition.\n\nFri Mar 24 23:14:30 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (yield_under_i): pass self again for instance_eval().\n\t  [ruby-dev:28466]\n\nFri Mar 24 17:20:03 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_f_sleep): remove description about SIGALRM which\n\t  is not valid on the current implementation.  [ruby-dev:28464]\n\nThu Mar 23 10:47:03 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (method_missing): should support argument splat in\n\t  super.  [ruby-talk:185438]\n\nMon Mar 20 12:05:18 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: Solaris SunPro compiler -rapth patch from\n\t  <kuwa at labs.fujitsu.com>.  [ruby-dev:28443]\n\nMon Mar 20 09:40:23 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: remove enable_rpath=no for Solaris.\n\t  [ruby-dev:28440]\n\nFri Mar 17 19:08:49 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c, ext/openssl/ossl_nsspki.c: fix typo.\n\t  [ruby-core:07571]\n\nWed Mar 15 16:54:21 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): support libraries without *.so.\n\nWed Mar 15 16:35:43 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c, ext/openssl/ossl_nsspki.c: should use\n\t  \"rb_str_new(0, 0)\" to make empty string.\n\nSat Mar 11 14:24:06 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::TextFormatter::wrap): removed\n\t  space before argument parenthesis.  [ruby-talk:183630]\n\n\t* ruby.1: a clarification patch from David Lutterkort\n\t  <dlutter at redhat.com>.  [ruby-core:7508]\n\nSat Mar  4 15:26:40 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* gc.c (id2ref): fix symbol test.\n\nSat Mar  4 01:08:07 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems\n\t  directories.  a patch from Eric Hodel <drbrain at segment7.net>.\n\t  [ruby-core:07423]\n\nThu Mar  2 19:44:18 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* gc.c: align VALUE with sizeof(RVALUE) globally.\n\t  (is_pointer_to_heap): check alignment out of loop.\n\t  (id2ref): avoid collision between symbols and objects.\n\t  (rb_obj_id): ditto.  moved from object.c.\n\t  [ruby-talk:178364] [ruby-core:7305]\n\nThu Mar  2 18:58:18 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_fd_writable): should not re-schedule output\n\t  from KILLED thread (must be error printing).\n\nThu Mar  2 17:57:49 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* gc.c: commited magic for reducing RVALUE size on windows. (24->20byte)\n\t  [ruby-core:7474]\n\nThu Mar  2 12:59:14 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (filetime_to_unixtime): should set tm_isdst to -1.\n\t  stat() didn't treat daylight saving time property on WinNT.\n\t  [ruby-talk:182100]\n\nThu Mar  2 08:02:42 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (add_heap): heap_slots may overflow.  a patch from Stefan\n\t  Weil <weil at mail.berlios.de>.\n\nWed Mar  1 00:24:31 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/rdoc/parsers/parse_rb.rb (read_escape): could not handle /\\^/.\n\t  merged Mr. Ishizuka's lib/irb/ruby-lex.rb 's patch rev 1.29.\n\t  [ruby-talk:181631] [ruby-dev:28404]\n\nTue Feb 28 09:32:17 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/drb/extservm.rb (invoke_service_command): cannot invoke command\n\t  if command name is quoted on mswin32. [ruby-dev:28400]\n\nMon Feb 27 00:19:16 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h (SYM2ID): should not cast to signed long.\n\t  [ruby-core:07414]\n\nFri Feb 24 20:07:23 2006  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/drb/drbtest.rb (add_service_command): quote pathnames in the\n\t  server's command line for space contained directory names.\n\t  Thanks, arton. [ruby-dev:28386]\n\nFri Feb 24 12:11:08 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* instruby.rb: install *.exe.manifest and *.dll.manifest if exist.\n\t  It's for VC++8.\n\nFri Feb 24 11:33:52 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub (HAVE_HYPOT): bcc32 has hypot().\n\nFri Feb 24 11:19:58 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* time.c (time_new_internal): add prototype to tell the compiler\n\t  arugments types.\n\n\t* win32/win32.c (NtInitialize): need to set a handler for VC++8.\n\nFri Feb 24 08:19:16 2006  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* test.rb: Removed.  Obsolete by test/nkf.\n\n\t* ext/.document: enabled documents in nkf and kconv\n\n\t* ext/nkf/nkf.c ext/nkf/lib/kconv.rb: Add rdoc.\n\nThu Feb 23 22:39:59 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: use borlndmm.dll if possible. bcc32's RTL internal\n\t  memory manager cannot handle large memory block properly.\n\t  ex: 10000.times { \"\" << \".\" * 529671; GC.start } # crash\n\t  [ruby-dev:28230]\n\nThu Feb 23 13:20:28 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* eval.c (SETUP_ARGS0): fixed memory corruption. [ruby-dev:28360]\n\nTue Feb 21 02:18:46 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* configure.in (mingw): have link.  [ruby-list:41838]\n\n\t* win32/Makefile.sub (config.h): ditto.\n\nTue Feb 21 02:07:39 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (f_arglist): should set command_start = Qtrue for\n\t  command body.  [ruby-talk:180648]\n\nMon Feb 20 17:37:26 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* mkconfig.rb: alias RbConfig for Config.\n\nMon Feb 20 12:27:53 2006  Kent Sibilev  <ksruby@gmail.com>\n\n\t* lib/rational.rb (Integer::gcd): small typo fix.\n\t  [ruby-core:07395]\n\nMon Feb 20 01:05:27 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rational.rb (Integer::gcd): replaced by gcd4 in\n\t  [ruby-core:07390].  [ruby-core:07377]\n\nMon Feb 20 00:57:02 2006  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.h (OSSL_Debug): should not use __func__.\n\t  [ruby-dev:28339]\n\nSun Feb 19 04:46:29 2006  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* eval.c: initial value for block_unique must be 1.\n\t  [ruby-talk:180420]\n\nSat Feb 18 23:58:26 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tracer.rb (Tracer::Tracer.add_filter): turn on tracer mode\n\t  only when caller() level size is one.  [ruby-core:07389]\n\n\t* lib/rdoc/parsers/parse_rb.rb: need not to require \"tracer\".\n\t  [ruby-core:07389]\n\n\t* sample/rtags.rb: ditto.\n\nSat Feb 18 12:18:26 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/fileutils.rb (FileUtils::fu_world_writable): make it\n\t  private.  [ruby-core:07383]\n\nSat Feb 18 00:22:39 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tracer.rb: merged a minor clarification patch from Daniel\n\t  Berger <Daniel.Berger at qwest.com>.  [ruby-core:07376]\n\nFri Feb 17 11:18:42 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* util.c (ruby_strtod): Float(\"1e\") should fail. [ruby-core:7330]\n\n\t* pack.c (EXTEND32): unpack(\"l\") did not work where sizeof(long) != 4.\n\t  [ruby-talk:180024]\n\n\t* pack.c (pack_unpack): fixed integer overflow on template \"w\".\n\t  [ruby-talk:180126]\n\nFri Feb 17 09:39:29 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_wait_for): sleep should always sleep for\n\t  specified amount of time.  [ruby-talk:180067]\n\nThu Feb 16 01:10:48 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (backtrace): frame->orig_func may not be initialized.\n\t  [ruby-core:07367]\n\nWed Feb 15 16:52:52 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): NODE_OP_ASGN1 should allow splat in its\n\t  argument list.  [ruby-core:07366]\n\n\t* parse.y (arg): avoid unnecessary extra argument.\n\t  [ruby-core:07366]\n\n\t* eval.c (rb_eval): honor visibility on OP_ASGN1 and\n\t  OP_ASGN2. [ruby-core:07366]\n\nWed Feb 15 10:09:51 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (yield_under_i): should not pass self as an argument to\n\t  the block for instance_eval.  [ruby-core:07364]\n\nWed Feb 15 09:20:35 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_obj_instance_eval): should be no singleton classes for\n\t  true, false, and nil.  [ruby-dev:28186]\n\nTue Feb 14 18:48:33 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (DMETHOD_P): accessing wrong frame.  [ruby-dev:28181]\n\n\t* eval.c (proc_invoke): preserve FRAME_DMETH flag.\n\nTue Feb 14 15:13:51 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/zlib/zlib.c: supress warning on test/zlib. [ruby-dev:28323]\n\nTue Feb 14 14:01:17 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* time.c (search_time_t): support non 32bit time_t environments.\n\n\t* win32/Makefile.sub (config.h): VC++8 has ``long long'' type.\n\n\t* win32/Makefile.sub (config.h): VC++8's time_t is 64bit value.\n\n\t* win32/win32.c (rb_w32_utime): drop read-only attribute before\n\t  changing file time.\n\n\t  all changes are backported from CVS HEAD.\n\nTue Feb 14 11:21:38 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_forward): should not use frame->argv.\n\t  [ruby-core:07358]\n\nMon Feb 13 18:08:12 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): argument update propagation.  [ruby-dev:28044]\n\n\t* env.h: remove argv member from struct FRAME.\n\nMon Feb 13 13:27:00 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): should push class from binding if supplied.\n\t  [ruby-core:07347]\n\nMon Feb 13 00:04:00 2006  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb (ERB::Compiler): add instance variable @insert_cmd to\n\t  change <%='s behavior. (backported 1.15 - 1.16)\n\nSat Feb 11 02:04:11 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): no need to push ruby_class.  [ruby-dev:28176]\n\nSat Feb 11 01:57:44 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_autoload): check if ruby_cbase is nil (during\n\t  instance_eval for objects cannot have singleton classes,\n\t  e.g. fixnums and symbols).  [ruby-dev:28178]\n\nTue Feb  7 23:03:24 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/zlib/zlib.c: should not access ruby objects in finalizer.\n\t  [ruby-dev:28286]\n\nMon Feb  6 16:02:51 2006  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (rb_thread_flock): ERROR_NOT_LOCKED is not an error on Cygwin.\n\t  In such situation, flock() should return 0.\n\nMon Feb  6 00:41:08 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* ruby.h (RSTRUCT_LEN, RSTRUCT_PTR): defined for source level\n\t  compatibility with ruby 1.9.\n\nSun Feb  5 21:05:34 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* numeric.c (fix_to_s): removed workaround for radix 2. Historically,\n\t  rb_fix2str could only handle radix 8, 10, 16. (Rev1.37) But for now,\n\t  it can handle radix 2..36. [ruby-Bugs#3438] [ruby-core:7300]\n\nSun Feb  5 18:55:08 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: imported from trunk, rev 1.129\n\n\t* lib/net/http.rb (add_field, get_fields): keep 1.8.2 backward\n\t  compatibility.\n\n\t* lib/net/https.rb: imported from trunk, rev 1.3.\n\n\t* lib/net/https.rb: #use_ssl? definition moved from net/http.rb.\n\nSun Feb  5 14:22:15 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/pstore.rb: should return default value if name is not found.\n\t  [ruby-core:7304]\n\n\t* lib/pstore.rb: should raise PStore::Error if not in transaction.\n\nSat Feb  4 22:51:43 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c: apply the FreeBSD getcontext/setcontext workaround\n\t  only before FreeBSD 7-CURRENT.\n\nSat Feb  4 21:19:23 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (LK_ERR): ERROR_NOT_LOCKED is not an error.\n\t  In such situation, flock() should return 0.\n\nSat Feb  4 15:56:37 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* numeric.c (fix_to_s): (2**32).to_s(2) fails with exception where\n\t  sizeof(int) == 4 < sizeof(long). [ruby-core:7300]\n\nFri Feb  3 15:06:50 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/syck.c (syck_move_tokens): should reset p->cursor or etc\n\t  even if skip == 0. This causes buffer overrun.\n\t  (ex: YAML.load('--- \"..' + '\\x82\\xA0' * 511 + '\"'))\n\nThu Feb  2 23:51:18 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/emitter.c (syck_emitter_write): should not set '\\0' on\n\t  emitter's marker. if marker points to the end of buffer, this causes\n\t  buffer overrun. (ex: YAML.dump(\".\" * 12288))\n\nThu Feb  2 16:01:24 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): need not to protect $SAFE value.\n\t  [ruby-core:07177]\n\nThu Feb  2 14:45:53 2006  Ville Mattila  <ville.mattila@stonesoft.com>\n\n\t* configure.in: The isinf is not regognized by autoconf\n\t  library guesser on solaris 10. [ruby-core:7138]\n\nWed Feb  1 22:01:47 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* configure.in, hash.c (ruby_setenv): use setenv(3) and unsetenv(3)\n\t  where they are supported. modifing environ variable seems to\n\t  segfault solaris 10. [ruby-core:7276] [ruby-dev:28270]\n\n\t* ruby.c (set_arg0): if use setenv(3), environ space cannot be used\n\t  for altering argv[0].\n\nTue Jan 31 14:46:28 2006  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (rb_struct_select): update RDoc description.\n\t  [ruby-core:7254]\n\nTue Jan 31 11:58:51 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: add MultiTkIp#eval and bg_eval.\n\n\t* ext/tk/lib/tk/namespace.rb: TkNamespace#eval was enbugged at the\n\t  last commit. Now it will return a proper object.\n\nTue Jan 31 00:10:26 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/rubyext.c (syck_resolver_transfer): workaround for SEGV.\n\t  ex: ruby -ryaml -e 'YAML.load(\"!map:B {}\")' [ruby-core:7217]\n\nSat Jan 28 07:56:57 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/rdoc/usage.rb: support \"a:0:33\" style caller[-1]. In this case\n\t  file name is \"a:0\". I don't know this really happens though...\n\t  [ruby-Bugs:3344]\n\nWed Jan 25 22:29:04 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in, dln.c, file.c, intern.h, missing.h (eaccess): use\n\t  system routine if provided.  fixed: [ruby-core:07195]\n\nSun Jan 22 23:27:13 2006  Go Noguchi  <gonoguti@yahoo.co.jp>\n\n\t* lib/test/unit/autorunner.rb (process_args): ignore arguments after\n\t  '--' so that test scripts can handle them.  fixed: [ruby-dev:28258]\n\nSun Jan 22 22:09:52 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (POST_GETCONTEXT): define separately from PRE_GETCONTEXT on\n\t  IA64 to avoid reusing variable address.\n\nSun Jan 22 20:03:35 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (ruby_setjmp): define PRE_GETCONTEXT and POST_GETCONTEXT\n\t  instead of FUNCTION_CALL_MAY_RETURN_TWICE.\n\t  define PRE_GETCONTEXT to clear carry flag for workaround of\n\t  FreeBSD/i386 getcontext/setcontext bug.\n\t  [ruby-dev:28263]\n\nSat Jan 21 00:36:47 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (FUNCTION_CALL_MAY_RETURN_TWICE): use only on SPARC and IA64\n\t  before gcc 4.0.3.\n\t  [ruby-dev:28247]\n\nThu Jan 19 22:21:23 2006  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mv): should remove file after copying.\n\t  [ruby-dev:28223]\n\nWed Jan 18 23:37:06 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (FUNCTION_CALL_MAY_RETURN_TWICE): don't clobber %l7 of SPARC\n\t  if enable-shared.\n\t  (ruby_setjmp): call FUNCTION_CALL_MAY_RETURN_TWICE after getcontext\n\t  too.\n\t  reported by Pav Lucistnik and Marius Strobl.\n\t  http://lists.freebsd.org/pipermail/freebsd-sparc64/2006-January/003739.html\n\nTue Jan 17 11:32:46 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/setup.mak (MAKE): workaround for nmake 8.\n\nTue Jan 17 11:10:21 2006  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/{Makefile.sub,setup.mak}: invoke .bat via shell. workaround\n\t  for nmake 8.\n\nMon Jan 16 10:26:23 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/emitter.c (syck_emit_seq, syck_emit_map, syck_emit_item):\n\t  should output complex key mark even if map's key is empty seq/map.\n\t  [ruby-core:7129]\n\nSat Jan 14 05:37:06 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (READ_DATA_PENDING, READ_DATA_PENDING_COUNT): defined\n\t  for DragonFly BSD 1.4.0.\n\nSat Jan 14 03:43:24 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* file.c (rb_file_s_chmod): avoid warning where sizeof(int) !=\n\t  sizeof(void*).\n\nFri Jan 13 19:14:56 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/rdoc/diagram.rb:\n\t    - properly quote bare element attributes\n\t    - terminates dangling elements (e.g. <img>, <br>, <link>, etc)\n\t    - converts \"CVS\" to the more HTML-friendly acronym element\n\t    - adds missing type attributes to style elements\n\n\t  based on Paul Duncan's patch <pabs@pablotron.org> [ruby-core:7028]\n\n\t* lib/rdoc/generators/html_generator.rb: ditto.\n\t* lib/rdoc/generators/template/html/hefss.rb: ditto.\n\t* lib/rdoc/generators/template/html/html.rb: ditto.\n\t* lib/rdoc/generators/template/html/kilmer.rb: ditto.\n\nThu Jan 12 11:53:08 2006  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tkballoonhelp.rb: [bug fix] couldn't add to a widget\n\t  which is constructed with TkComposite module.\n\t  [new feature] support 'command' option which is called just before\n\t  popping up the balloon help.\n\nWed Jan 11 15:00:00 2006  Ville Mattila  <mulperi@iki.fi>\n\n\t* io.c (READ_PENDING*): Support solaris 64-bit environments.\n\t  Solaris defines a opaque FILE struct when compiling 64 bit\n\t  binaries. This means that we dont have access to _ptr etc.\n\t  members anymore. The solution by Steven Lumos is to define\n\t  FILE64 that has needed members available. I've modified\n\t  the origanal patch a bit so that it compiles both with gcc\n\t  and now free sun studio 11 compiler and both amd64 and sparc.\n\t  NOTE! We have to 64 bit solaris FILE structure time to time\n\t  otherwise we'll get breakage.\n\t  [ruby-core:7106]\n\nTue Jan 10 19:42:33 2006  Tanaka Akira  <akr@m17n.org>\n\n\t* gc.c (garbage_collect): mark ruby_current_node.\n\t  if an exception is raised in a finalizer called written in C by\n\t  rb_gc_call_finalizer_at_exit, ruby_set_current_source may use\n\t  collected ruby_current_node and mark_source_filename may corrupt\n\t  memory.\n\nTue Jan 10 13:30:34 2006  akira yamada  <akira@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_resolver_transfer): should be able to load\n\t  !ruby/object:Bignum syntax 1.8.3 dumped. [ruby-core:6159]\n\nTue Jan 10 12:47:41 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/yaml/rubytypes.rb (Fixnum): Bignum could not be loaded in\n\t  ruby 1.8.3/1.8.4. [ruby-core:6115]\n\n\t* lib/yaml/rubytypes.rb (Numeric): Subclass of Numeric could not\n\t  be dumped properly. [ruby-core:7047]\n\nTue Jan 10 12:00:48 2006  Aaron Schrab  <aaron @nospam@ schrab.com>\n\n\t* lib/yaml/rubytypes.rb (Symbol#yaml_new): YAML loading of quoted\n\t  Symbols broken. [ruby-Bugs:2535]\n\nMon Jan  9 19:54:35 2006  arton  <artonx@yahoo.co.jp>\n\n\t* ext/zlib/extconf.rb: zlib compiled DLL version 1.2.3 distributed by\n\t  http://www.zlib.net/ has zdll.lib. [ruby-dev:28209]\n\nMon Jan  9 14:17:12 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/Makefile.sub (OPTFLAGS): I have experienced trouble on y- flag,\n\t  (VisualC++6) so use -O2b2xg- if  $(MSC_VER) < 1400. [ruby-core:7040]\n\nMon Jan  9 14:17:12 2006  Kero van Gelder  <rubyforge @nospam@ kero.tmfweb.nl>\n\n\t* lib/webrick/httpservlet/filehandler.rb: fixed typo. [ruby-core:7075]\n\nSat Jan  7 15:40:07 2006  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (singleton): get rid of segfault on syntax error.\n\t  fixed: [ruby-core:07070]\n\nFri Jan  6 10:16:20 2006  Steven Lumos  <steven@lumos.us>\n\n\t* io.c (READ_DATA_PENDING): defined for 64bit Solaris on SPARC.\n\t  [ruby-core:7057]\n\t  (READ_DATA_PENDING_COUNT): ditto.\n\t  (READ_DATA_PENDING_PTR): ditto.\n\nSun Jan  1 17:07:59 2006  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (rb_w32_seekdir): should not segfault even if passed\n\t  the location which rb_w32_telldir didn't return. [ruby-core:7035]\n\t  (I think HEAD implementation is better. but binary compatibility)\n\n\t* test/ruby/test_dir.rb: added.\n\nSat Dec 31 22:57:00 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_save_context): should not recycle scope object used\n\t  in a thread.  fixed: [ruby-dev:28177]\n\nFri Dec 30 18:22:42 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (garbage_collect): mark objects refered from aborting threads.\n\t  [ruby-dev:28190]\n\n\t* win32/Makefile.sub: VC++8 support.\n\nFri Dec 30 14:24:53 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dir.c (glob_helper): do not use TRUE for djgpp.\n\nFri Dec 30 04:54:40 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (eaccess): workaround for VC++8 runtime.\n\n\t* win32/win32.c (ioinfo): VC++8 support.\n\nThu Dec 29 23:59:37 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_gc_mark_threads): leave unmarked threads which won't wake\n\t  up alone, and mark threads in the loading table.  [ruby-dev:28154]\n\n\t* eval.c (rb_gc_abort_threads), gc.c (gc_sweep): kill unmarked\n\t  threads.  [ruby-dev:28172]\n\nThu Dec 29 17:02:07 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* test/ruby/envutil.rb (EnvUtil.rubybin): search \"ruby\" instead of\n\t  \"miniruby\".  [ruby-dev:28140]\n\nTue Dec 27 16:59:52 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* test/drb/drbtest.rb (DRbService::self.ext_service): increase\n\t  timeout limit.  a patch from Kazuhiro NISHIYAMA\n\t  <zn at mbf.nifty.com>. [ruby-dev:28132]\n\nTue Dec 27 08:29:18 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/ssl.rb (OpenSSL::SSL::SSLSocket#post_connection_chech):\n\t  treat wildcard character in commonName. [ruby-dev:28121]\n\nMon Dec 26 22:32:47 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval), gc.c (gc_mark_children), node.h (NEW_ALIAS,\n\t  NEW_VALIAS), parse.y (fitem): allow dynamic symbols to\n\t  NODE_UNDEF and NODE_ALIAS.\n\t  backported from trunk.  fixed: [ruby-dev:28105]\n\nMon Dec 26 08:50:36 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ev_const_get): fixed a bug in constant reference during\n\t  instance_eval.  [yarv-dev:707]\n\n\t* eval.c (ev_const_defined): ditto.\n\n\t* lib/yaml.rb (YAML::add_domain_type): typo fixed.  a patch from\n\t  Joel VanderWerf <vjoel at path.berkeley.edu>.\n\t  [ruby-talk:165285] [ruby-core:6995]\n\nSat Dec 24 18:58:14 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.8.4 released.\n\nFri Dec 23 10:30:23 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/digest/sha2/sha2.c (ULL): support AIX C.  a patch from\n\t  Kailden <kailden at gmail.com>.  [ruby-core:06984]\n\nWed Dec 21 16:53:06 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* file.c (w32_io_info): should return handle because FileIndex is\n\t  valid only while file is open. [ruby-dev:28088]\n\nWed Dec 21 14:53:26 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (test_kernel_open): use File.identical?.\n\t  [ruby-talk:171804]\n\nTue Dec 20 22:41:17 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (eval_under_i): evaluate source in caller's frame.\n\t  [ruby-dev:28076]\n\n\t* eval.c (rb_call_super): use original method name on exception.\n\t  [ruby-dev:28078]\n\nTue Dec 20 13:11:59 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/rubyext.c: fixed GC problem (backported HEAD 1.55 - 1.62)\n\t  [ruby-dev:27839]\n\n\t* ext/syck/syck.h (S_FREE): small hack. no need to check if pointer is\n\t  NULL or not before S_FREE.\n\n\t* st.c: uses malloc instead of xmalloc to avoid GC. syck uses st_insert\n\t  in gram.c to insert node from rb_syck_bad_anchor_handler into\n\t  SyckParser's hash table. if GC occurs in st_insert, it's not under\n\t  SyckParser's mark system yet. so RString can be released wrongly.\n\t  [ruby-dev:28057]\n\nTue Dec 20 12:53:23 2005  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_emitter_reset): to ensure compatibility\n\t  with previous Ruby versions, documents are no longer headless.\n\nTue Dec 20 01:46:48 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_f_backquote): fix a GC problem on\n\t  IA64 with gcc 4.0.3 20051216 (prerelease) -O3.\n\nMon Dec 19 23:32:39 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (rb_symname_p): fixed wrong validation.  [ruby-dev:28047]\n\nSat Dec 17 03:57:01 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* bignum.c (rb_big_rshift): fix a GC problem on\n\t  IA64 with gcc 4.0.3 20051216 (prerelease).\n\nSat Dec 17 03:30:23 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (bmcall): fix a GC problem by tail call on\n\t  IA64 with gcc 4.0.3 20051216 (prerelease).\n\nFri Dec 16 00:54:06 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* signal.c (Init_signal): revert C++ style comment.\n\t  [ruby-dev:28041]\n\nThu Dec 15 12:35:14 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tmpdir.rb: merged RDoc patch from Eric Hodel <drbrain at\n\t  segment7.net>.  [ruby-core:06894]\n\nThu Dec 15 01:33:31 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/zlib/zlib.c (zstream_run): fix a GC problem by tail call on\n\t  x86_64 with gcc 4.0.3 20051111 (prerelease) (Debian 4.0.2-4)\n\nWed Dec 14 12:11:46 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* test/gdbm/test_gdbm.rb: specify pid for the argument of\n\t  Process.wait.  workaround for Cygwin.\n\nWed Dec 14 12:01:26 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* marshal.c (r_object0): fix a GC problem for reading a bignum on\n\t  IA64 with gcc 3.3.5 (Debian 1:3.3.5-13).\n\nTue Dec 13 12:23:47 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* re.c (rb_reg_regcomp): fix a GC problem on x86_64 with\n\t  gcc 3.3.5 (Debian 1:3.3.5-13).\n\nTue Dec 13 01:44:16 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* array.c (rb_ary_diff): fix a GC problem on IA64 with\n\t  gcc 3.3.5 (Debian 1:3.3.5-13).\n\t  When rb_ary_push is called, there was no register which contains\n\t  `hash' but `&RHASH(hash)->tbl' instead.\n\nTue Dec 13 00:08:09 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* sprintf.c (rb_str_format): fix a GC problem.\n\t  [ruby-dev:28001]\n\nMon Dec 12 15:54:56 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* test/openssl/test_ssl.rb (test_parallel): call GC.start to close\n\t  unused files. [ruby-dev:27981]\n\nMon Dec 12 00:33:56 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/digest/digest.c (rb_digest_base_s_digest): add volatile to\n\t  protect temporary context object.  [ruby-dev:27979]\n\n\t* ext/iconv/iconv.c (Init_iconv): rb_gc_register_address() should\n\t  be called before actual variable initialization.\n\t  [ruby-dev:27986]\n\nFri Dec  9 23:31:02 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rexml/encoding.rb (encoding=): give priority to particular\n\t  conversion to iconv.  [ruby-core:06520]\n\nThu Dec  8 02:07:19 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (umethod_bind): adjust invoking class for module method.\n\t  [ruby-dev:27964]\n\nThu Dec  8 00:40:52 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (call_trace_func): klass parameter should be a\n\t  class/module that defines calling method.  [ruby-talk:169307]\n\nWed Dec  7 17:10:27 2005  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* sprintf.c (rb_f_sprintf): [ruby-dev:27967]\n\nWed Dec  7 15:31:35 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_str_format): integer overflow check added.\n\n\t* sprintf.c (GETASTER): ditto.\n\nWed Dec  7 01:02:04 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/README.macosx-aqua: [new document] tips to avoid the known\n\t  bug on platform specific dialogs of Tcl/Tk Aqua on MacOS X.\n\n\t* ext/tk/tcltklib.c: fix bug on switching threads and waiting on the\n\t  deleted interpreter on vwait and tkwait command.\n\n\t* ext/tk/lib/multi-tk.rb: kill the meaningless loop for the deleted Tk\n\t  interpreter.\n\n\t* ext/tk/sample/demos-jp/image3.rb: [bug fix] wrong argument.\n\n\t* ext/tk/sample/demos-en/image3.rb: ditto.\n\n\t* ext/tk/sample/demos-jp/menu.rb: fix message for MacOS X.\n\n\t* ext/tk/sample/demos-jp/menu8x.rb: ditto.\n\n\t* ext/tk/sample/demos-en/menu.rb: ditto.\n\nTue Dec  6 16:37:57 2005  Yuya Nishida  <yuya@j96.org>\n\n\t* eval.c (exec_under): avoid accessing ruby_frame->prev.\n\t  [ruby-dev:27948]\n\nThu Dec  1 00:50:33 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_funcall2): allow to call protected methods.\n\t  fixed: [ruby-dev:27890]\n\nWed Nov 30 23:52:17 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (NEWHEAP, ADD2HEAP): set count after pointer was set.\n\t  fixed: [ruby-dev:27896]\n\nWed Nov 30 13:43:07 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-expr-beg): support $! at the end of\n\t  expression.   [ruby-dev:27868]\n\nMon Nov 28 18:55:43 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (init_inetsock_internal): remove setting\n\t  SO_REUSEADDR option on server socket on Cygwin.\n\t  fixed: [ruby-core:6765] ([ ruby-Bugs-2872 ])\n\nMon Nov 28 13:08:54 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (rb_w32_strerror): remove all CR and LF. (avoid broken\n\t  error message on bccwin32 + winsock)\n\nMon Nov 28 09:21:49 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/mkmf.rb (create_makefile): should not change sodir with\n\t  dir.gsub!. (bccwin32 failed to install third party exntesions)\n\t  [ruby-dev:27834]\n\nSun Nov 27 00:56:13 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/wsdl/xmlSchema/complexContent.rb: missing\n\t  ComplexContent#elementformdefault method.\n\nSat Nov 26 19:57:45 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dln.c (conv_to_posix_path): should initialize posix.\n\nThu Nov 24 21:05:58 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* configure.in (AC_CHECK_FUNCS): need to check link().\n\t  fixed: [ruby-dev:27814]\n\nThu Nov 24 01:22:25 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* file.c (w32_io_info): CreateFile failed on Win9x if file was already\n\t  opened. (FILE_SHARE_READ was needed, but actually I don't understand\n\t  the flags of CreateFile well...)\n\nWed Nov 23 20:59:01 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add Tk.pkgconfig_list and Tk.pkgconfig_get\n\t  [Tk8.5 feature].\n\n\t* ext/tk/lib/tk/text.rb: supports new indices modifires on a Text\n\t  widget [Tk8.5 feature].\n\n\t* ext/tk/lib/tk/virtevent.rb: add TkNamedVirtualEvent.\n\n\t* ext/tk/lib/tk/autoload.rb: ditto.\n\n\t* ext/tk/lib/tk/event.rb: add :data key for virtual events [Tk8.5\n\t  feature].\n\nWed Nov 23 18:55:31 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* file.c (w32_io_info): should not call GetFileInformationByHandle\n\t  for pipe.\n\n\t* file.c (w32_io_info): checks return value from rb_w32_get_osfhandle.\n\n\t* file.c (w32_io_info): now can identify directory on WinNT.\n\nWed Nov 23 03:40:49 2005  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* re.c (KR_REHASH): should cast to unsigned for 64bit CPU.\n\t  [ruby-core:06721]\n\nWed Nov 23 11:01:33 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* intern.h, file.c: failed to compile on windows.\n\nWed Nov 23 07:26:44 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: check for X509V3_EXT_nconf_nid.\n\n\t* ext/openssl/ossl_x509ext.c (MakeX509ExtFactory): should use\n\t  OPENSSL_malloc to allocate X509V3_CTX.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509extfactory_create_ext): use\n\t  X509V3_EXT_nconf_nid to avoid SEGV (and to build extensions which\n\t  values are placed in separate section).\n\n\t* test/openssl/test_x509ext.rb: new file.\n\nWed Nov 23 01:22:57 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (test_identical): test if two files are identical.\n\n\t* file.c (rb_f_test): support DOSISH systems where st_ino is not\n\t  reliable.  fixed: [ruby-core:06672]\n\n\t* win32.h, win32.c (rb_w32_osid): check the running platform.\n\nTue Nov 22 23:52:06 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb: match incomplete (in current enconding) multibyte\n\t  string.  http://inamode6.tokuhirom.dnsalias.org/show/1551\n\nTue Nov 22 18:36:11 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (winnt_stat): set mapped errno instead of ENOENT.\n\nTue Nov 22 14:46:57 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (rb_file_s_basename): skip slashes just after UNC top slashes.\n\n\t* test/ruby/test_path.rb (test_dirname, test_basename): follow new\n\t  spec. and add new tests.\n\nTue Nov 22 13:18:32 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (rb_w32_stat): Dir.chdir('//server/shared');\n\t  p Dir.glob('*') should work on WinNT. (implemented our own\n\t  stat(2) on WinNT) [ruby-list:41552] [ruby-dev:27711]\n\nTue Nov 22 02:31:53 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/tile.rb: bug fix (Tk::Tile::USE_TTK_NAMESPACE\n\t  is not defined).\n\nTue Nov 22 01:45:21 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_basename): DOSISH_UNC is defined on cygwin but\n\t  DOSISH is not.  fixed: [ruby-dev:27797]\n\nMon Nov 21 22:50:48 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_path_skip_prefix, rb_file_s_basename): UNC without path\n\t  should not be splitted.  fixed: [ruby-dev:27776] [ruby-dev:27786]\n\n\t* parse.y (dsym): prohibit empty symbol literal by interpolation.\n\t  fixed: [ruby-talk:166529]\n\nMon Nov 21 16:03:48 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/setup.mk: findstr doesn't exist on win9x.\n\t  fixed: [ruby-dev:27756]\n\nSun Nov 20 22:34:06 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (rb_symname_p): [ not followed by ] is not valid symbol.\n\t  fixed: [ruby-talk:166520]\n\nSat Nov 19 19:57:54 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/fileutils.rb (FileUtils::ln): ln documentation fix.\n\t  [ruby-core:06661]\n\nSat Nov 19 07:34:32 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/font.rb: remove dependency on Ruby's version (1.8\n\t  or 1.9).\n\n\t* ext/tk/lib/tkextlib/ICONS/icons.rb: ditto.\n\n\t* ext/tk/sample/tkextlib/treectrl/demo.rb: ditto.\n\nFri Nov 18 17:57:08 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (rb_file_s_dirname): should use skipprefix for UNC path.\n\t  pointed out by nobu ([ruby-dev:27744]). fixed: [ruby-core:5076]\n\nFri Nov 18 17:35:09 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: add restriction to access the entried\n\t  command table and manipulate other IPs (for reason of security).\n\t  Now, a IP object can be controlled by only its master IP or the\n\t  default IP.\n\n\t* ext/tk/lib/remote-tk.rb: add restriction to manipulate.\n\n\t* ext/tk/tcltklib.c (ip_is_slave_of_p): add TclTkIp#slave_of?(ip)\n\t  to check manipulability.\n\n\t* ext/tk/lib/tk.rb: bug fix on handling of Tcl's namespaces.\n\n\t* ext/tk/lib/tk/namespace.rb: ditto.\n\nFri Nov 18 17:26:06 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (rb_file_s_dirname): added checks for some patterns with drive\n\t  letter. fixed: [ruby-dev:27738]\n\n\t* test/ruby/test_path.rb (test_dirname): added tests for above\n\t  patterns.\n\nFri Nov 18 12:18:02 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.h (S_IFIFO): r,w = IO.pipe; r.stat.pipe? now\n\t  returns true on VisualC++6.\n\nWed Nov 16 23:24:17 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (static-ruby): overridable.\n\n\t* ext/extmk.rb (parse_args): force to link extensions statically only\n\t  if static is given for extstatic.\n\n\t* ext/extmk.rb (RUBY, RUBYW): overridable.\n\nTue Nov 15 23:46:35 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/find.rb (Find::find): should not ignore symbolic links to\n\t  non-existing files.  [ruby-talk:165866]\n\nTue Nov 15 16:23:26 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* array.c (rb_ary_fill): previous commit disabled this usage:\n\n\t    a = [0,1,2,3,4,5,6,7,8,9]\n\t    a.fill {|i| a[i] * 10} #=> [nil, nil, ...., nil]\n\n\t  previous commit has the advantage of early garbage collection, but\n\t  potensially this would break some script. so I reverted behavior.\n\nTue Nov 15 16:04:10 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* array.c (rb_ary_fill): tail elements were vanished when the middle\n\t  part of array was filled. (ie: [0,1,2,3,4].fill(-1,2,1) => [0,1,-1])\n\n\t* test/ruby/test_array.rb (test_fill): added.\n\nTue Nov 15 14:39:16 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_fill): should adjust array length correctly when\n\t  an array is expanded in the fill process.  [ruby-core:06625]\n\nMon Nov 14 23:49:57 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_readlink): ERANGE will occur only on GPFS.\n\t  [ruby-dev:27699]\n\nMon Nov 14 17:36:22 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_first): RDoc update from Daniel Berger\n\t  <djberg96@yahoo.com>.  [ruby-core:06577].\n\nFri Nov 11 10:31:44 2005  Zach Dennis  <zdennis@mktec.com>\n\n\t* ext/socket/socket.c: Socket Documentation. [ruby-core:6552]\n\nFri Nov 11 08:20:56 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in (OUTFLAG): keep trailing spaces.  [ruby-dev:27666]\n\n\t* mkconfig.rb: substitution refereces added.\n\nFri Nov 11 07:44:18 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* configure.in: undef HAVE_LINK on BeOS. (link(2) always returns\n\t  EINVAL, and this causes error in test/fileutils.)\n\n\t* file.c: overwride chown(2) and fchown(2) on BeOS. (these functions\n\t  should not change user/group id if -1 is passed as corresponding\n\t  argument, and this causes error in test/fileutils too)\n\t  [ruby-dev:27672]\n\n\t* file.c (rb_file_s_link): checks HAVE_LINK.\n\nTue Nov  8 15:32:27 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/drb/ssl.rb (DRb::SSLConfig#accept): fixed typo.\n\t  [ruby-dev:27560] [ruby-core:4627]\n\nMon Nov  7 13:43:51 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/stubs.c (_nativethread_consistency_check): use simpler\n\t  (low cost) way to check whether the Tcl interpreter was compiled\n\t  with threads enabled of not.\n\n\t* ext/tk/tcltklib.c: reduce warnings.\n\n\t* ext/tk/tkutil/tkutil.c: ditto.\n\nMon Nov  7 00:06:58 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/yaml.rb: removed :nodoc: to generate Kernel doc. [ruby-core:6324]\n\nSun Nov  6 23:39:13 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (Iconv::BrokenLibrary): exception when detected a\n\t  bug of underlying library.\n\nSun Nov  6 21:46:59 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tk/stubs.c (ruby_tcl_create_ip_and_stubs_init): should touch\n\t  interpreter after initialization is done. [ruby-dev:27638]\n\nSun Nov  6 20:13:27 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_readlink): readlink(2) on AIX fails with ERANGE if\n\t  buffer size is less than required.  fixed: [ruby-dev:27634]\n\nWed Nov  2 20:25:28 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/extconf.rb: ext/tk/extconf.rb: change the check parameter\n\t  for Win32.\n\nWed Nov  2 20:14:53 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib: merge into ext/tk and remove.\n\nWed Nov  2 19:03:06 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_rbUpdateObjCmd,\n\t  ip_rb_threadUpdateObjCmd): passed improper flags to DoOneEvent().\n\n\t* ext/tk/tkutil.c: use rb_obj_respond_to() instead of rb_respond_to().\n\nTue Nov  1 14:20:11 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call_super): should call method_missing if super is\n\t  called from Kernel method.\n\n\t* eval.c (exec_under): frame during eval should preserve external\n\t  information.\n\nTue Nov  1 10:50:17 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: should check ERR_peek_last_error().\n\t  [ruby-dev:27597]\n\n\t* ext/openssl/ossl.c (ossl_raise): ditto.\n\nMon Oct 31 17:34:46 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: use proper option for Sun linker. A patch from\n\t  Shinya Kuwamura <kuwa at labs.fujitsu.com>.  [ruby-dev:27603]\n\nMon Oct 31 11:27:22 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/gdbm/test_gdbm.rb, test/sdbm/test_sdbm.rb (test_s_open_error):\n\t  skip on Win32/DOS platforms.\n\nMon Oct 31 05:49:23 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_cipher.c (ossl_cipher_update): input data must\n\t  not be empty. [ruby-talk:161220]\n\n\t* test/openssl/test_cipher.rb: add test for Cipher#update(\"\").\n\nMon Oct 31 05:37:20 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpservlet/cgihandler.rb\n\t  (WEBrick::HTTPServlet::CGIHandler#do_GET): the value of Set-Cookie:\n\t  header field should be splited into each cookie.  [ruby-Bugs:2199]\n\n\t* lib/webrick/cookie.rb (WEBrick::Cookie.parse_set_cookie): new method\n\t  to parse the value of Set-Cookie: header field.\n\n\t* test/webrick/test_cookie.rb, test/webrick/test_cgi.rb,\n\t  test/webrick/webrick.cgi: add some test for cookie.\n\nMon Oct 31 03:19:36 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/readline/readline.c (readline_readline): type check.\n\t  [ruby-core:6089]\n\n\t* numeric.c (fix_rshift): RDoc fix.  [ruby-core:6351]\n\n\t* util.h (strtod): add #undef for platforms defines strtod()\n\t  macro.   [ruby-dev:27563]\n\nMon Oct 31 02:35:59 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* test/ruby/test_float.rb (test_precision): test by assert_in_delta.\n\t  [ruby-dev:27575]\n\nSat Oct 29 01:58:25 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/etc/etc.c: document update from mathew <meta@pobox.com>.\n\t  [ruby-core:06473]\n\n\t* ext/fcntl/fcntl.c: ditto.\n\nThu Oct 27 16:45:31 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (scan_once): wrong condition to use mbclen2().\n\t  [ruby-dev:27535]\n\nWed Oct 26 09:27:27 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/implicit.c (syck_type_id_to_uri): should return\n\t  newly allocated memory. otherwise, type_id will be freed\n\t  twice. [ruby-dev:27384] [ruby-core:6385]\n\nWed Oct 26 09:04:51 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ruby.h (Qfalse, Qtrue, Qnil, Qundef): make sure these immediate\n\t  values have VALUE type. there is an environment where sizeof(VALUE)\n\t  != sizeof(int) like IA64. if 32bit integer (Qtrue) is passed to ANYARGS\n\t  and received by 64bit integer (VALUE), upper bits may have garbage value.\n\t  [ruby-dev:27513]\n\nWed Oct 26 01:58:19 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_EXTERN): macro to export symbols in shared\n\t  library.  [ruby-core:05528]\n\n\t* defines.h, {bcc32,win32,wince}/Makefile.sub (RUBY_EXTERN): moved to\n\t  configuration pass.\n\n\t* ext/extmk.rb (extmake): RUBY_EXTERN for static linked extensions.\n\nTue Oct 25 15:32:00 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rational.rb: applied documentation patch from Gavin Sinclair\n\t  <gsinclair@gmail.com>.  [ruby-core:06364]\n\n\t* lib/irb.rb (IRB::Irb::eval_input): handle prompts with newlines\n\t  in irb auto-indentation mode.  [ruby-core:06358]\n\nTue Oct 25 02:12:08 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rdoc/markup/simple_markup.rb (SM::SimpleMarkup::LABEL_LIST_RE):\n\t  reduce redundant backtrack.  [ruby-talk:161771]\n\nTue Oct 25 00:27:35 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/*: RDoc documentation from Eric Hodel\n\t  <drbrain@segment7.net> added.\n\nMon Oct 24 21:14:29 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in, io.c: use sys/syscall.h if syscall.h is not available.\n\t  [ruby-core:06247]\n\nMon Oct 24 20:49:45 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/Win32API/lib/win32/resolv.rb (get_info): support multiple DNS.\n\t  fixed: [ruby-list:40058], [ruby-dev:27479]\n\nMon Oct 24 07:57:56 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/tk/lib/tk/canvas.rb (TkCanvasItemConfig::__item_val2ruby_optkeys):\n\t  typo fixed.  [ruby-talk:162187]\n\n\t* ext/tk/lib/tk/menu.rb (TkMenuEntryConfig::__item_val2ruby_optkeys):\n\t  ditto.  [ruby-core:06359]\n\nSun Oct 23 21:50:15 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/enumerator/enumerator.c: applied documentation patch from\n\t  James Edward Gray II <james@grayproductions.net>.\n\t  [ruby-core:06348]\n\nSun Oct 23 07:11:11 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/extconf.rb: improve messages [ruby-core:06325].\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tk/canvas.rb, ext/tk/lib/tk/entry.rb,\n\t  ext/tk/lib/tk/frame.rb, ext/tk/lib/tk/image.rb,\n\t  ext/tk/lib/tk/itemconfig.rb, ext/tk/lib/tk/labelframe.rb,\n\t  ext/tk/lib/tk/listbox.rb, ext/tk/lib/tk/menu.rb,\n\t  ext/tk/lib/tk/radiobutton.rb, ext/tk/lib/tk/scale.rb,\n\t  ext/tk/lib/tk/spinbox.rb, ext/tk/lib/tk/text.rb,\n\t  ext/tk/lib/tk/toplevel.rb: improve conversion of option values.\n\n\t* ext/tk/lib/tkextlib/*: ditto.\n\n\t* ext/tk/lib/tkextlib/*: update to support ActiveTcl8.4.11.2.\n\n\t* ext/tk/lib/tkextlib/trofs/*: support Trofs 0.4.3.\n\n\t* ext/tk/lib/tkextlib/tile/*: support Tile 0.7.2.\n\n\t* ext/tk/lib/tkextlib/vu/*: support vu 2.3.0.\n\n\t* ext/tk/lib/tkextlib/tcllib/*: support Tcllib 1.8 (Tklib 0.3).\n\nSat Oct 22 23:54:07 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb, lib/mkmf.rb (with_config): support --with-extension\n\t  options.  [ruby-dev:27449]\n\nSat Oct 22 13:26:57 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (sym_inspect), parse.y (parser_yylex, rb_symname_p): check\n\t  if valid as a symbol name more strictly.  [ruby-dev:27478]\n\n\t* test/ruby/test_symbol.rb: tests for [ruby-core:03573].\n\n\t* time.c (rb_strftime): removed meaningless volatile modifiers, and\n\t  concatenate successive nul characters at once.  [ruby-dev:27472]\n\nFri Oct 21 19:21:56 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* rubysig.h (CHECK_INTS): fixed typo. (I believe bit-or is improper)\n\nFri Oct 21 17:49:32 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bin/erb (ERB::Main::run): typo fixed.  [ruby-core:06337]\n\nFri Oct 21 15:27:17 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bignum.c (bignew_1): convertion from `int' to `char' discards\n\t  upper bits, (ie. (char)0xff00 -> 0) so it's better to test if\n\t  nonzero and set 0 or 1 instead of simply casting ... as a flag usage.\n\t  (but I believe this won't cause actual bug in current implementation)\n\t  [ruby-dev:27055]\n\n\t* time.c: should use LONG_LONG instead of `long long'.\n\nThu Oct 20 09:37:15 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/mkmf.rb (create_makefile): Borland make seems not to allow\n\t  empty dependency list. If this change is not good, please correct\n\t  it.\n\nThu Oct 20 07:55:09 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): get rid of a restriction\n\t  of Borland make.  fixed: [ruby-dev:27460]\n\nThu Oct 20 00:13:18 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* rubysig.h (CHECK_INTS): fix typo.\n\nWed Oct 19 23:58:03 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): do not create unnecessary empty\n\t  directories.  fixed: [ruby-dev:27451]\n\nWed Oct 19 19:26:15 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (rb_gc_mark_parser): get rid of segfault with old yacc.\n\t  fixed: [ruby-dev:27439]\n\nWed Oct 19 08:28:32 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_join): elements may contain null pointer strings.\n\t  report and fixed by Lloyd Zusman (hippoman): [ruby-core:06326]\n\nWed Oct 19 02:34:33 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c, gc.c, time.c: made internal symbols static.  [ruby-dev:27435]\n\nWed Oct 19 01:27:07 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): numeric literal inside character class\n\t  disabled succeeding backtrack.  fixed: [ruby-list:41328]\n\nMon Oct 17 21:18:50 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (parser_heap): byacc never free parser stack.\n\t  fixed: [ruby-dev:27428]\n\nMon Oct 17 16:04:47 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* file.c (chmod_internal, lchmod_internal): fixed type of 2nd argument.\n\nSun Oct 16 22:16:51 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: omit non-existing directories.\n\nSun Oct 16 14:30:05 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/rinda.rb (Rinda::Tuple#initialize): check remote hash\n\t  tuple. fixed: [ruby-list:41227]\n\n\t* test/rinda/test_rinda.rb: test it.\n\nSun Oct 16 03:38:07 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* rubysig.h (CHECK_INTS): prevent signal handler to run during\n\t  critical section.  [ruby-core:04039]\n\n\t* eval.c (load_wait): need not to call rb_thread_schedule()\n\t  explicitly.  [ruby-core:04039]\n\n\t* eval.c (rb_thread_schedule): clear rb_thread_critical.\n\t  [ruby-core:04039]\n\nSat Oct 15 19:56:38 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* bin/erb: typo fixed, again. thanks, Doug Kearns.\n\nFri Oct 14 22:08:26 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (ioctl): should set errno.\n\nFri Oct 14 16:57:32 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/config.rb (Config::FileHandler): :UserDir should be nil.\n\t  It is harmful to permit the access to ~/public_html by default.\n\t  suggested by Hiroyuki Iwatsuki.\n\nThu Oct 13 23:29:51 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (HEAPCNT): bison allocates indivisible size.\n\t  fixed: [ruby-core:06261]\n\n\t* io.c, pack.c, ext/syck/rubyext.c, ext/syck/syck.h, missing/isinf.c:\n\t  get rid of warnings.  fixed: [ruby-core:06247]\n\nWed Oct 12 12:52:57 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.c (Init_openssl): should call\n\t  OpenSSL_add_ssl_algorithms().\n\nWed Oct 12 11:08:54 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (rb_f_test): typo in RDoc comments.\n\nTue Oct 11 21:41:58 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_obj_respond_to): check if obj responds to the given\n\t  method with the given visibility.  [ruby-dev:27408]\n\n\t* eval.c (rb_respond_to): conform to Object#respond_to?.  [ruby-dev:27411]\n\nTue Oct 11 00:01:21 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.c (st_free_table): do not call free() but xfree().\n\t  [ruby-core:06205]\n\nSat Oct  8 20:04:40 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (Init_Binding): add Binding#dup method.  [yarv-dev:666]\n\n\t* parse.y (rb_parser_malloc, rb_parser_free): manage parser stack on\n\t  heap.  [ruby-list:41199]\n\n\t* ext/iconv/charset_alias.rb: parse config.charset_alias file directly.\n\nFri Oct  7 09:54:00 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::Cookie::parse): Cookies from Nokia devices may\n\t  not be parsed correctly.  A patch from August Z. Flatby\n\t  (augustzf) in [ruby-Patches-2595].  [ruby-core:06183]\n\nThu Oct  6 20:12:16 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c (strscan_free): remove useless code.\n\t  [ruby-dev:26368] [ruby-dev:27389]\n\t  (backported from trunk, rev 1.22)\n\nWed Oct  5 04:42:38 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/xmlrpc/server.rb (XMLRPC::Server#initialize): should mount the\n\t  servlet on \"/\".\n\nWed Oct  5 03:59:09 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/xmlrpc/server.rb (XMLRPC::Server#serve): delete wrong call\n\t  of \"join\".\n\nMon Oct  3 00:04:00 2005  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* pack.c (EXTEND16): [ruby-dev:27383]\n\nThu Sep 29 10:26:18 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/dl/dl.c (rb_io_to_ptr): abolish sizeof(FILE).\n\t  [ruby-dev:27317]\n\nThu Sep 29 07:22:05 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* evalc. (rb_f_send): underscores need to be escaped.\n\t  fixed by Doug Kearns.  [ruby-core:06053]\n\nThu Sep 29 00:57:35 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ev_const_get), variable.c (rb_const_get_0): retry only when\n\t  autoload succeeded.\n\n\t* variable.c (rb_autoload_load): now return true if autoload\n\t  succeeded.  fixed: [ruby-dev:27331]\n\nWed Sep 28 23:42:15 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (apply2files): add prototype.\n\n\t* file.c (rb_stat_inspect): constified.\n\n\t* class.c (rb_mod_init_copy, rb_class_init_copy), file.c (rb_stat_init_copy),\n\t  numeric.c (num_init_copy), object.c (rb_obj_init_copy, Init_Object),\n\t  re.c (match_init_copy, rb_reg_init_copy), time.c (time_init_copy):\n\t  undocumented.\n\nWed Sep 28 23:09:23 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb: document update from James Edward Gray II\n\t  <james@grayproductions.net>.  [ruby-core:06027]\n\nWed Sep 28 15:14:19 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI#start): req.query_string should\n\t  refer the value of QUERY_STRING. [ruby-list:41186]\n\n\t* lib/webrick/httprequest.rb (WEBrick::HTTPRequest#query_string=):\n\t  add new method.\n\nWed Sep 28 10:45:44 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: cannot compile with Tcl/Tk8.0.x\n\t  [ruby-dev:27335].\n\nWed Sep 28 08:12:18 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (read_buffered_data): check if reached EOF.  fixed: [ruby-dev:27334]\n\nWed Sep 28 07:56:52 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/yaml/basenode.rb (YAML::BaseNode::match_segment): fix typo.\n\t  [ruby-dev:27237], [ruby-core:05854]\n\n\t* lib/yaml/tag.rb (Module#yaml_as): suppress warnings.\n\n\t* lib/yaml/types.rb (YAML::PrivateType, YAML::DomainType): ditto.\n\nWed Sep 28 03:23:35 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* rubysig.h: fixed build problem with --enable-pthread on platforms\n\t  which don't have setitimer().\n\nMon Sep 26 22:32:13 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (set_trace_func): add rb_secure(4) to prevent adding\n\t  tracing function.\n\nSun Sep 25 12:05:10 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* bin/erb: typo fixed.\n\nSun Sep 25 01:46:43 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): arrange deep-indent\n\t  closing parenthesis at same column as the opening.\n\nSun Sep 25 00:42:11 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-expr-beg): deal with heredoc separately.\n\t  fixed: [ruby-list:41168]\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): not to deepen indent\n\t  level for continuous line inside parentheses.\n\t  http://nabeken.tdiary.net/20050915.html#p02\n\nSun Sep 25 00:18:11 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (unknown_node): show more information.  [ruby-dev:26196]\n\nSat Sep 24 08:56:01 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (cd): no longer accept :noop option, related\n\t  code is useless (backported from trunk, rev 1.67).\n\t  [ruby-core:05858] [ruby-Bugs:2494]\n\nSat Sep 24 08:38:07 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: fix visibility of FileUtils::NoWrite, Verbose,\n\t  DryRun (backported from trunk, rev 1.66). [ruby-core:05954]\n\n\t* test/fileutils/test_nowrite.rb: test it.\n\n\t* test/fileutils/test_dryrun.rb: new file.\n\n\t* test/fileutils/test_verbose.rb: new file.\n\nSat Sep 24 02:40:20 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb: document update from James Edward Gray II\n\t  <james@grayproductions.net>.  [ruby-core:05942]\n\nThu Sep 22 23:36:24 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (find_executable0): default path if environment is not\n\t  set.  [ruby-dev:27281]\n\nThu Sep 22 16:33:12 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* test/readline/test_readline.rb (TestReadline::replace_stdio):\n\t  merged the patch of [ruby-dev:25232] instead of [ruby-dev:25223].\n\nWed Sep 21 23:30:44 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (configuration): generalized nmake dependent code.\n\nWed Sep 21 09:07:55 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.8.3 released.\n\nWed Sep 21 08:52:25 2005  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/token.c: correctly compute identation of a block\n\t  scalar's parent node. [ruby-talk:150620]\n\nWed Sep 21 08:20:24 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* README.EXT, README.EXT.ja: add new features.\n\nWed Sep 21 07:43:58 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (default_argv, Arguable#options): defaults strings\n\t  to be parsed to Arguable instance.\n\nWed Sep 21 02:44:09 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (path_check_0): disallow sticky world writable directory\n\t  in PATH (and $LOAD_PATH).  [ruby-dev:27226]\n\n\t* file.c (fpath_check): typo fixed.\n\nTue Sep 20 22:29:49 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/wsdl/simpletype/rpc/test_rpc.rb, test/wsdl/ref/test_ref.rb,\n\t  test/wsdl/any/test_any.rb test/soap/wsdlDriver/test_calc.rb:\n\t  suppress deliberate warnings with $VERBOSE = nil.\n\nTue Sep 20 21:26:23 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/io/wait/lib/nonblock.rb: disable on platforms non-blocking flag\n\t  is not available.  fixed: [ruby-dev:27187]\n\nTue Sep 20 18:23:04 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (thread_mark): mark th->last_status.  [ruby-dev:27179]\n\nTue Sep 20 18:20:33 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/yaml.rb: require 'yaml/constants'.  [ruby-core:5776]\n\nTue Sep 20 17:48:34 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/xmlrpc/client.rb (XMLRPC::Client::do_rpc): add charset\n\t  information to content-type header.[ruby-core:5127]\n\n\t* lib/xmlrpc/server.rb (CGIServer::serve): ditto.\n\n\t* lib/xmlrpc/server.rb (ModRubyServer::serve): ditto.\n\n\t* lib/xmlrpc/server.rb (WEBrickServlet::service): ditto.\n\nTue Sep 20 17:34:46 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* test/webrick/test_cgi.rb: set ENV[\"PATH\"] to CGIEnvPath on\n\t  windows. bcc32's runtime is not installed into system directory,\n\t  so it cannot be found without this setting. [ruby-dev:27166]\n\nTue Sep 20 17:10:38 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* test/dbm/test_dbm.rb (TestDBM::test_s_open_error): remove\n\t  test_s_open_error test to detect duplicate open.\n\t  [ruby-dev:27202]\n\nTue Sep 20 17:08:31 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* io.c: PIPE_BUF is not defined on BeOS. use _POSIX_PIPE_BUF instead.\n\t  [ruby-dev:27185]\n\nTue Sep 20 16:53:53 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* test/readline/test_readline.rb (TestReadline::replace_stdio):\n\t  BSD seek support from [ruby-dev:25223].  fixed: [ruby-dev:27150]\n\nTue Sep 20 15:39:40 2005  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/emitter.c (syck_scan_scalar): prevent indicators from\n\t  appearing alone or at the end of plain scalars. [ruby-core:5826]\n\n\t* ext/syck/emitter.c (syck_emit_scalar): treat typed scalar nodes\n\t  as complex keys.\n\n\t* lib/syck.h: version 0.60.\n\n\t* lib/yaml/basenode.rb (YAML::BaseNode#at): transform keys during\n\t  key searches.\n\n\t* ext/syck/rubyext.c: loading of binary-typed nodes.  prevent\n\t  emission of plain strings that look like symbols, but which aren't.\n\nTue Sep 20 05:50:22 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* test/xmlrpc/test_webrick_server.rb (setup_http_server):\n\t  should not include 'webrick/https' unless 'use_ssl' because\n\t  it fails where openssl is not installed.\n\nTue Sep 20 00:34:07 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_close): call rb_io_close() directly if io is a T_FILE\n\t  object.  [ruby-dev:27156]\n\nMon Sep 19 19:09:08 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* file.c (rb_file_chown): should accept nil. [ruby-dev:27171]\n\t  (backport from trunk, rev 1.208)\n\nMon Sep 19 18:35:13 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dl/dl.c (rb_io_to_ptr): fix DragonFlyBSD support.\n\t  [ruby-dev:27151]\n\nMon Sep 19 14:17:04 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/syck/emitter.c (syck_emit): passing an int* value to the\n\t  long* parameter causes unaligned access on LP64 systems.\n\t  [ruby-dev:27161]\n\nMon Sep 19 13:44:03 2005  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c: avoid core dump with WIN32OLE_EVENT.\n\t  [ruby-dev:27133]\n\nMon Sep 19 10:36:06 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (cp_r): default is :dereference_root=>true for\n\t  backward compatibility. [ruby-dev:27145]\n\n\t* test/fileutils/test_fileutils.rb (test_cp_r): test it.\n\nMon Sep 19 09:57:39 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: backported from trunk (1.36).\n\t  (again) [ruby-dev:27145]\n\nMon Sep 19 07:45:37 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_pkey.h, ossl_pkey_rsa.c, ossl_pkey_dsa.c:\n\t  an instance variable \"private\" is added to OpenSSL::PKey class.\n\t  this ivar is a flag that shows whether there is a private key\n\t  in the instance.\n\n\t* ext/openssl/ossl_engine.c: (ossl_engine_load_privkey): set private\n\t  key flag.\n\nMon Sep 19 06:41:32 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: backported from trunk (rev 1.65):\n\n\t* lib/fileutils.rb (rm_r): new option :secure.\n\n\t* lib/fileutils.rb (rm_rf): new option :secure.\n\n\t* lib/fileutils.rb: new method #remove_entry_secure.\n\n\t* lib/fileutils.rb (cd): remove option :noop.\n\n\t* lib/fileutils.rb (cp_r): new option :dereference_root.\n\n\t* lib/fileutils.rb (cp_r): new option :dereference_root.\n\n\t* lib/fileutils.rb: new method #remove_entry.\n\n\t* lib/fileutils.rb: new method #chmod_R.\n\n\t* lib/fileutils.rb: new method #chown.\n\n\t* lib/fileutils.rb: new method #chown_R.\n\n\t* lib/fileutils.rb: new method .commands.\n\n\t* lib/fileutils.rb: new method .options.\n\n\t* lib/fileutils.rb: new method .have_option?.\n\n\t* lib/fileutils.rb: new method .options_of.\n\n\t* lib/fileutils.rb: new method .collect_method.\n\n\t* lib/fileutils.rb: use module_function instead of single extend.\n\n\t* test/fileutils/test_fileutils.rb: backported from trunk (1.36).\n\nMon Sep 19 03:17:48 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* file.c (rb_thread_flock): wrap the flock system call by\n\t  TRAP_BEG/TRAP_END to enable signals.  [ruby-dev:27122]\n\n\t* ext/socket/socket.c (bsock_send): wrap the sendto and send system\n\t  call by TRAP_BEG/TRAP_END to enable signals when writing to a socket\n\t  which is full.  [ruby-dev:27132]\n\n\t* io.c (rb_io_syswrite): wrap the write system call by\n\t  TRAP_BEG/TRAP_END to enable signals when writing to a pipe which is\n\t  full.  [ruby-dev:27134]\n\nMon Sep 19 03:02:08 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (io_fwrite): wrap the write system call by TRAP_BEG/TRAP_END to\n\t  enable signals when writing to a pipe which is full.\n\nSun Sep 18 02:10:47 2005  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb: remove comments that are bungling up\n\t  the rdoc and ri output.  output symbols as plain scalars.\n\n\t* ext/syck/rubyext.c (syck_emitter_reset): emit headless\n\t  documents always.\n\n\t* ext/syck/emitter.c (syck_scan_scalar): quote scalars with any\n\t  kind of surrounding line space, tabs or spaces alike.\n\n\t* ext/syck/token.c: accept tabs as whitespace, not for indentation,\n\t  but strip from plain scalars.\n\n\t* test/yaml/test_yaml.rb: remove outdated tests.\n\nSat Sep 17 23:25:04 2005  sheepman  <sheepman@sheepman.sakura.ne.jp>\n\n\t* lib/mathn.rb (Rational::inspect): should preserve original\n\t  operand.  [ruby-core:05806]\n\nSat Sep 17 23:20:27 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::Cookie): should handle multiple values for a\n\t  cookie name.  [ruby-talk:156140]\n\nSat Sep 17 10:42:13 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp#eval_string and bg_eval_string\n\t  should call Kernel.eval on caller's safe-level instead of slave's\n\t  safe-level (Of course, the given script should be evaluated on\n\t  slave's safe-level).\n\nSat Sep 17 09:45:26 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_substr): should propagate taintness even for\n\t  empty strings.  [ruby-dev:27121]\n\n\t* string.c (rb_str_aref): should infect result if range argument\n\t  is tainted.  [ruby-dev:27121]\n\nSat Sep 17 08:35:39 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/maker/base.rb (RSS::Maker::ItemsBase#normalize): fixed\n\t  strange RSS::Maker::Item#max_size behavior.\n\t  Thanks to Kazuhiko <kazuhiko@fdiary.net>.\n\n\t* test/rss/test_maker_1.0.rb (RSS::TestMaker10#test_items): ditto.\n\nFri Sep 16 23:09:20 2005  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_search_event_at): bug fix\n\t  in ext/win32ole/sample/ienavi.rb.\n\n\t* ext/win32ole/win32ole/tests/testOLEEVENT.rb: ditto.\n\nFri Sep 16 22:41:18 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_s_extname): empty string for path name ending with a\n\t  period.  fixed: [ruby-core:05651]\n\n\t* file.c (rb_file_join): smarter behavior at edge cases.\n\t  fixed: [ruby-core:05706]\n\nFri Sep 16 18:34:01 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syck/node.c (syck_replace_str): was using return from the\n\t  void function.  a patch from MIYAMUKO Katsuyuki\n\t  <miyamuko at mtb.biglobe.ne.jp>.  [ruby-dev:27111]\n\nFri Sep 16 14:48:48 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: fix typo on MultiTkIp#bg_eval_string\n\nFri Sep 16 12:02:12 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_resolver_transfer): remove C++ style\n\t  comment (//).  [ruby-core:05793]\n\nFri Sep 16 00:14:14 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/logger/test_logger.rb: unintentionally overwritten changes by\n\t  Usa.  reverted.\n\nFri Sep 16 00:06:18 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI::Socket#initialize): should set\n\t  $stdout.binmode.\n\nThu Sep 15 23:25:21 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/{soap,wsdl,xsd}, test/{soap,wsdl,xsd}: imported soap4r/1.5.5.\n\n\t  #nnn is a ticket number at http://dev.ctor.org/soap4r\n\n\t  * SOAP\n\n\t    * allow to configure an envelope namespace of SOAP request. (#124)\n\t   \tTemporaryNamespace = 'http://www.w3.org/2003/05/soap-envelope'\n\t  \t@client.options[\"soap.envelope.requestnamespace\"] =\n\t\t  TemporaryNamespace\n\t \t@client.options[\"soap.envelope.responsenamespace\"] =\n\t\t  TemporaryNamespace\n\t\t@client.do_proc(...)\n\n\t    * let SOAP request XML indent space configuable.  see\n\t      \"soap.envelope.no_indent\" option. (#130)\n\n\t    * let external CES configuable.\n\t      ex. client[\"soap.mapping.external_ces\"] = 'SJIS'.  $KCODE is used\n\t      by default. (#133)\n\t\texternal CES ::= CES used in Ruby object of client and server\n\t\tinternal CES ::= CES used in SOAP/OM\n\n\t    * add iso-8859-1 external CES support. (#106)\n\n\t    * fixed illegal 'qualified' handling of elements.  it caused\n\t      ASP.NET inteoperability problem. (#144)\n\n\t    * added 'soap.envelope.use_numeric_character_reference' (boolean)\n\t      option to let query XML use numeric character reference in XML,\n\t      not plain UTF-8 character.  !GoogleSearch server seems to not\n\t      allow plain UTF-8 character since 2005-08-15 update. (#147)\n\n\t    * SOAP::Header::SimpleHeader (de)serialization throws an exception\n\t      on !SimpleHeader.on_(in|out)bound when header is a String.  so we\n\t      could not use a simple single element headerItem.  fixed.  thanks\n\t      to emil. (#129)\n\n\t    * out parameter of rpc operation did not work.  (#132)\n\n\t    * follow HTTP redirect only if using http-access2.  (#125) (#145)\n\n\t    * add a workaround for importing an WSDL whose path begins with\n\t      drive letter.  (#115)\n\n\t  * WSDL\n\n\t    * SOAP Data which is defined as a simpletype was not mapped\n\t      correctly to Ruby obj when using wsdl2ruby.rb generated classdef\n\t      file. (#123)\n\n\t    * rpc/literal support. (#118)\n\n\t    * re-implemented local element qualify/unqualify control.  handles\n\t      elementFormDefault and form in WSDL.  (#119)\n\n\t    * Array of an element which has simpleType causes a crash. (#128)\n\n\t    * prarmeterOrder may not contain return part so it can be shorter\n\t      than parts size.  Thanks to Hugh.  (#139)\n\n\t  * Samples\n\n\t    * added !BasicAuth client sample. (#117)\n\n\t    * added Base64 client/server sample.\n\n\t    * added Flickr SOAP interface client sample. (#122)\n\n\t    * added !SalesForce client sample. (#135)\n\n\t    * updated Thawte CA certificate for !GoogleAdWords sample.\n\n\t    * updated a client script with the newer version made by Johan.\n\t      thanks!\n\n\t    * shortened long file names. (#120)\n\n\t    * fixed typo in authheader sample. (#129)\n\n\t    * updated deprecated method usage.  (#138)\n\nThu Sep 15 23:02:57 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.h (rb_w32_stat): added prototype.\n\nThu Sep 15 22:35:55 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/ruby/test_signal.rb (test_exit_action): skip the test using\n\t  fork on fork-less platforms.\n\nThu Sep 15 11:39:18 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/dialog.rb: If a dialog does not show up yet,\n\t  TkDialogObj#name raises an exception. [ruby-talk:156109]\n\nThu Sep 15 01:39:19 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (Rinda::TemplateEntry::initialize): pull\n\t  up method. Tabs converted to spaces.\n\nThu Sep 15 00:18:24 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/net/telnet.rb (Net::Telnet::waitfor): replace sysread with\n\t  readpartial.  [ruby-talk:127641]\n\nWed Sep 14 22:40:26 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (ruby_glob): glob function not using ruby exception system.\n\nWed Sep 14 01:26:03 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/https.rb: backported from trunk, rev 1.3.\n\t  [ruby-dev:25673] (again), [ruby-dev:26617] (again),\n\t  [ruby-dev:27062]\n\n\t* ext/openssl/lib/net/https.rb: removed.\n\n\t* ext/openssl/lib/net/protocols.rb: removed.\n\n\t* lib/net/http.rb: #use_ssl?, #use_ssl are moved from net/https.\n\nTue Sep 13 22:09:40 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb (Logger): added formatter accessor to logger for\n\t  dictating the way in which the logger should format the messages it\n\t  displays.  Thanks to Nicholas Seckar (cf. [ruby-talk:153391]) and\n\t  Daniel Berger.\n\n\t* lib/logger.rb (Logger): added VERSION constant.\n\n\t* lib/logger.rb: removed document for LogDevice. It is an\n\t  implementation detail and is not a public interface.\n\n\t* test/logger/test_logger.rb: added tests.\n\nTue Sep 13 21:47:17 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (BEGIN_CALLARGS): pop halfly pushed status.\n\t  fixed: [ruby-dev:26881]\n\nTue Sep 13 16:26:45 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: backported from trunk, rev 1.128.\n\t  [ruby-dev:25673] [ruby-dev:26617]\n\n\t* lib/net/protocol.rb: backported from trunk, rev 1.78.\n\n\t* lib/net/protocol.rb: new method #old_open to support net/smtp\n\t  and net/pop.\n\n\t* lib/net/smtp.rb: use #old_open.\n\n\t* lib/net/pop.rb: ditto.\n\nTue Sep 13 12:33:05 2005  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml.rb: reworking YAML::Stream to use the new\n\t  emitter.\n\n\t* lib/yaml/stream.rb: ditto.\n\n\t* lib/yaml/rubytypes.rb: added Object#yaml_new.\n\n\t* lib/yaml/tag.rb: the tag_subclasses? method now\n\t  shows up in the class.  allow taguri to be set using an accessor.\n\t  continue support of Object#to_yaml_type.\n\n\t* ext/syck/rubyext.c: new emitter code.  yaml_new and yaml_initialize\n\t  get called, should they be present.  consolidated all the diaspora of internal\n\t  node types into the family below YAML::Syck::Node -- Map,\n\t  Seq, Scalar -- all of whom are SyckNode structs pointing to\n\t  Ruby data.  moved Object#yaml_new into the node_import and made it the\n\t  default behavior.  the target_class is always called wih yaml_new, prepended\n\t  a parameter, which is the klass.  loaded nodes through GenericResolver show their style.\n\t  new Resolver#tagurize converts type ids to taguris.\n\n\t* ext/syck/implicit.re: were 'y' and 'n' seriously omitted??\n\n\t* ext/syck/emitter.c: renovated emitter, walks the tree in advance.\n\t  consolidated redundant block_styles struct into\n\t  the scalar_style struct.  (this means loaded nodes can now\n\t  be sent back to emitter and preserve at least its very basic\n\t  formatting.)\n\n\t* ext/syck/gram.c: headless documents of any kind allowed.\n\n\t* ext/syck/node.c: new syck_replace_str methods and syck_empty_*\n\t  methods for rewriting node contents, while keeping the ID\n\t  and other setup info.  added syck_seq_assign.\n\n\t* ext/syck/syck.h: reflect block_styles and new node functions.\n\nMon Sep 12 20:53:06 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* test/openssl/test_pkcs7.rb (test_enveloped): skip this test\n\t  to avoid a bug of PKCS7_enctypt() (only if ext/openssl is\n\t  compiled with OpenSSL-0.9.7d or earlier versions).\n\t  http://www.mail-archive.com/openssl-dev@openssl.org/msg17376.html\n\nMon Sep 12 14:03:33 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* test/dbm/test_dbm.rb: remove locking test, which may not be\n\t  supported on some platforms.  [ruby-dev:27030]\n\nMon Sep 12 10:45:58 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dl/dl.c (rb_io_to_ptr): merged a patch for DragonFly BSD\n\t  from Takahiro Kambe <taca at back-street.net>.  [ruby-dev:27023]\n\nSun Sep 11 22:05:51 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* bin/erb (ERB::Main#run): set ERB#filename so that it is used\n\t  when reporting syntax/runtime errors. Tabs converted to spaces.\n\nSat Sep 10 10:17:03 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_engine.c (ossl_engine_s_by_id):\n\t  OpenSSL::Engine.by_id calls given block before calling\n\t  ENGINE_init (block parameter is the return value of this method\n\t  itself).  this functionality is useful to load dynamic shared\n\t  engines. the following code is a sample of loading a key using\n\t  OpenSC PKCS #11 module.\n\n\t\trequire \"openssl\"\n\t\tpkcs11 = OpenSSL::Engine.by_id(\"dynamic\"){|e|\n\t\t  e.ctrl_cmd(\"SO_PATH\", \"/usr/lib/opensc/engine_pkcs11.so\")\n\t\t  e.ctrl_cmd(\"LIST_ADD\", \"1\")\n\t\t  e.ctrl_cmd(\"LOAD\")\n\t\t}\n\t\tpkcs11.ctrl_cmd(\"PIN\", \"secret\")\n\t\tkey = pkcs11.load_private_key\n\n\t* ext/openssl/ossl_engine.c (ossl_engine_ctrl_cmd): new method\n\t  OpenSSL::Engine#ctrl_cmd. it wraps ENGINE_ctrl_cmd_string.\n\n\t* ext/openssl/ossl_engine.c (ossl_engine_get_cmds): new method\n\t  OpenSSL::Engine#cmds. it returms engine command definitions.\n\nSat Sep 10 10:09:47 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (asn1str_to_str): new function.\n\n\t* ext/openssl/ossl_pkcs7.c: new class OpenSSL::PKCS7::RecipientInfo.\n\t  this class wraps PKCS7_RECIP_INFO struct.\n\n\t* ext/openssl/ossl_pkcs7.c: OpenSSL::PKCS7::Signer is renamed to\n\t  OpenSSL::PKCS7::SignerInfo. (\"Signer\" remains as an alias of\n\t  SignerInfo.)\n\n\t* test/openssl/test_pkcs7.rb: new file.\n\nSat Sep 10 10:05:51 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ns_spki.c (ossl_spki_initialize): assume that\n\t  the argument is a DER string if Base64 decoding failed.\n\n\t* ext/openssl/ossl_ns_pki.c (ossl_spki_to_der): new method.\n\n\t* test/openssl/test_ns_spki.rb: add new file.\n\nSat Sep 10 09:56:24 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/digest.rb: added SHA224, SHA256, SHA384 and SHA512.\n\t  these features are enabled if this library is compiled with\n\t  OpenSSL 0.9.8 or later.\n\n\t* test/openssl/test_digest.rb: add test for new digests.\n\nSat Sep 10 09:51:30 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.c (ossl_raise): should use ERR_peek_last_error\n\t  to get last error on the current thread. And should report\n\t  errors on the stack while OpenSSL.debug is true.\n\n\t* ext/openssl/ossl.c (ossl_get_errors): new method for debugging\n\t  this library.\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_set_ciphers): fix error message.\n\n\t* ext/openssl/ossl_x509req.c (ossl_x509req_set_attributes): get rid\n\t  of unused variable.\n\n\t* ext/openssl/ossl_x509store.c (ossl_x509store_initialize): should\n\t  set @time to avoid warning.\n\n\t* ext/openssl/ossl_x509store.c (ossl_x509store_set_default_paths,\n\t  X509_STORE_add_cert, X509_STORE_add_crl): should raise error if\n\t  wrapped functions failed.\n\n\t* test/openssl/test_x509store.rb: add test for errors.\n\nFri Sep  9 22:13:19 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): prohibit calling tainted method (>2) when\n\t  $SAFE == 0.\n\nFri Sep  9 16:45:25 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_times): make empty strings to keep taintness,\n\t  and a little improvement.  [ruby-dev:26900]\n\n\t* ext/iconv/iconv.c (iconv_try), ext/iconv/extconf.rb: get rid of meta\n\t  characters in command line option.  fixed: [ruby-talk:155369]\n\nThu Sep  8 14:58:11 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* merged a patch from Takahiro Kambe <taca at back-street.net> to\n\t  support DragonFly BSD.  [ruby-dev:26984]\n\nWed Sep  7 12:55:08 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: abolish mod === tempfile to avoid a problem\n\t  [ruby-dev:26967].\n\nWed Sep  7 10:45:15 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_switch): convert all exceptions to\n\t  SystemExit.  fixed: [ruby-core:05724]\n\n\t* eval.c (rb_thread_terminated): show backtrace before propagate\n\t  exceptions to main thread.\n\nWed Sep  7 08:35:04 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, configure.in (MINIOBJS): miniruby on HP-UX can not load\n\t  extension libraries.\n\n\t* bignum.c (bignew_1, bigadd): K&R style argument actually can't be\n\t  defined as char.\n\n\t* missing/vsnprintf.c: ANSI compiler supports const keyword.\n\n\t* ext/digest/sha2/extconf.rb: reject platforms which has inttypes.h\n\t  but no 64bit integer.\n\n\t* lib/mkmf.rb (what_type?): guesstimate type.\n\n\t* ext/etc/etc.c (setup_passwd), ext/etc/extconf.rb: pw_age might be\n\t  char*.  fixed: [ruby-core:05470]\n\nWed Sep  7 08:32:47 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_cvar_get, rb_mod_cvar_set): document fix from\n\t  sheepman <sheepman@sheepman.sakura.ne.jp>; a bug in visibility\n\t  description.  [ruby-dev:26965]\n\n\t* sprintf.c (rb_f_sprintf): warn \"too many argument\" on verbose\n\t  mode (-v/-w); backported from 1.9.  [ruby-dev:26963]\n\nMon Sep  5 17:03:07 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/ostruct.rb: a patch from Florian Gross <florgro at gmail.com>\n\t  merged to allow recursive inspect (and to_s) for OpenStruct.\n\t  [ruby-core:05532]\n\nMon Sep  5 07:01:12 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/openssl/lib/openssl/buffering.rb (Buffering#do_write):\n\t  should clear data from the buffer which already been output.\n\nFri Sep  2 23:51:54 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib: do not use __send__ to access private methods.  [ruby-dev:26935]\n\nFri Sep  2 03:29:00 2005  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/irb/init.rb: make IRB -I option that is same befavior for ruby.\n\t  [ruby-dev:26872], [ruby-dev: 26920]\n\n\t* lib/irb/locale.rb: support to print help message when OS locale is\n\t  ja_JP.utf-8. [ruby-dev:26872]\n\nThu Sep  1 17:11:25 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): wrong condition for $SAFE restoration.\n\nThu Sep  1 14:12:45 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: On Tcl8.5, MultiTkIp#invoke_hidden doesn't\n\t  work (gives wrong order of arguments).\n\n\t* ext/tk/lib/multi-tk.rb: add MultiTkIp#invoke_hidden_on_namespace\n\t  to support '-namespace' option of 'interp invokehidden' command\n\t  on Tcl8.5.\n\nWed Aug 31 14:43:15 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (OPTFLAGS): default global optimization to\n\t  disabled for all VC++ versions.  fixed: [ruby-dev:26897]\n\nWed Aug 31 11:35:43 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/gdbm/test_gdbm.rb (teardown): should remove GDBM temporary\n\t  file.\n\nWed Aug 31 10:30:56 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* process.c (proc_detach, proc_setmaxgroups): missing argument type\n\t  declaration. (I recommend ANSI-style function)\n\nTue Aug 30 23:20:19 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_rescue2): initialization miss.  fixed: [ruby-dev:26917]\n\n\t* lib/mkmf.rb (xsystem, xpopen): no longer expand by Config.\n\n\t* lib/mkmf.rb (link_command, cc_command, cpp_command): expand\n\t  variables at once, and quote hdrdir.  fixed: [ruby-core:05680]\n\n\t* lib/mkmf.rb (libpathflag): quote paths.\n\nTue Aug 30 19:34:27 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/digest/md5/md5ossl.h, ext/digest/rmd160/rmd160ossl.h,\n\t  ext/digest/sha1/sha1ossl.h: include <stddef.h> to avoid\n\t  error in compilation with OpenSSL-0.9.8. [ruby-list:41068]\n\nMon Aug 29 19:54:21 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/rdoc/usage.rb: improper exceptions. [ruby-dev:26870]\n\n\t* lib/rdoc/usage.rb: support the case when non-ruby code exists before\n\t  shebang. (this is needed when ri.bat is executed on windows)\n\nMon Aug 29 17:48:17 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (method_arity): should return proper arity value.\n\t  [ruby-dev:26390]\n\nMon Aug 29 01:19:57 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb (Time.parse): extract fractional seconds using\n\t  Date._parse.  [ruby-talk:153859]\n\nSat Aug 27 20:20:01 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/curses/curses.c ({curses,window}_clrtoeol): added. suggested\n\t  by Reyn Vlietstra.\n\n\t* ext/curses/curses.c: chtype in curses is not `char', rahter `long'.\n\t  [ruby-Bugs:2298]\n\n\t* ext/curses/view.rb: String =~ String is deprecated.\n\nWed Aug 24 10:53:28 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/logger/test_logger.rb (test_shifting_size): should close log\n\t  device before unlink, since some platform cannot unlink opened\n\t  file.\n\nSun Aug 21 00:13:27 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/wsdl/xmlSchema/importer.rb (WSDL::XMLSchema::Importer#fetch): add\n\t  a workaround for importing an WSDL whose path begins with drive\n\t  letter.  [ruby-dev:26242]\n\nSat Aug 20 22:37:13 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb (write, shift_log?, shift_log): file shifting race\n\t  condition bug fixed.  [ruby-dev:26764]\n\n\t* test/logger/test_logger.rb: tests.\n\nFri Aug 19 18:13:39 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb (Time.apply_offset): fix a problem with last day of\n\t  month.  reported by Lucas Nussbaum.  [ruby-talk:152866]\n\nThu Aug 18 12:46:28 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub (COMMON_HEADERS): reverted 1.42.2.24.\n\t  I misunderstood, bccwin32 on ruby_1_8 uses winsock2 originally.\n\t  [ruby-dev:26806]\n\n\t* win32/win32.h: include winsock2.h instead of winsock.h. (bcc32)\n\nWed Aug 17 23:58:05 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (rb_to_integer): argument constified.\n\n\t* eval.c (terminate_process): take String message.\n\n\t* eval.c (rb_thread_switch): propagate the exception caused thread\n\t  termination directly.  fixed: [ruby-core:05552]\n\nWed Aug 17 00:05:46 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_add_method): preserve safe level in the environment\n\t  where a method is defined .\n\n\t* eval.c (rb_call0): restore preserved safe level in the method\n\t  execution.\n\nMon Aug 15 00:38:51 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_rescue2): reduce PUSH_TAG() as well as NODE_RESCUE.\n\t  [ruby-dev:26800]\n\n\t* range.c (range_check, range_init): reduce useless exceptions.\n\nSat Aug 13 18:51:26 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_block_pass): distinguish current block from others.\n\t  fixed: [ruby-dev:26274]\n\n\t* ext/stringio/stringio.c (strio_set_string): disallow nil.\n\t  http://www.rubyist.net/~nobu/t/20050811.html#c05\n\nThu Aug 11 23:29:03 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c: keep holding string after closed.\n\nThu Aug 11 13:01:48 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss: fixed sort bug. [ruby-list:41018]\n\n\t* lib/rss/1.0.rb (RSS::RDF::Channel#setup_maker_attributes):\n\t  removed self.\n\n\t* lib/rss/maker/base.rb (RSS::Maker::ItemsBase#<=>): use #date\n\t  instead of @date.\n\t  (RSS::Maker::Base::self.def_array_element): added #size.\n\n\t* lib/rss/maker/1.0.rb\n\t  (RSS::Maker::RSS10::Channel#to_rss,\n\t   RSS::Maker::RSS10::Items::Item#to_rss): cleared dc_dates set\n\t  upped by using #date.\n\n\t* lib/rss/maker/dublincore.rb\n\t  (RSS::Maker::ChannelBase, RSS::Maker::ItemsBase::ItemBase):\n\t  fixed opposite alias.\n\n\t* test/rss/test_setup_maker_1.0.rb\n\t  (RSS::TestSetupMaker10::test_setup_maker_items_sort): added some\n\t  tests for RSS::Maker::ItemsBase#do_sort.\n\nWed Aug 10 10:29:40 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: fix bug on handling __ruby2val_optkeys().\n\n\t* ext/tk/lib/tk/itemconfig.rb: fix bug on handling\n\t  __item_ruby2val_optkeys().\n\n\t* ext/tk/lib/tk/canvas.rb: didn't check __item_ruby2val_optkeys().\n\n\t* ext/tk/lib/tkextlib/blt/component.rb: ditto.\n\nTue Aug  9 15:12:04 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: remove dangerous 'rb_jump_tag's.\n\n\t* ext/tk/lib/tk.rb: add __val2ruby_optkeys and __ruby2val_optkeys to\n\t  help to convert option values between ruby and tcl.\n\n\t* ext/tk/lib/tk/itemconfig.rb: add __item_val2ruby_optkeys and\n\t  __item_ruby2val_optkeys to help to convert option values between\n\t    ruby and tcl.\n\n\t* ext/tk/lib/tk/radiobutton.rb: use __ruby2val_optkeys for 'variable'\n\t  option (for the reason of backward compatibility).\n\n\t* ext/tk/lib/tk/composite.rb: clarify the arguments of super().\n\n\t* ext/tk/lib/tk/spinbox.rb: ditto.\n\n\t* ext/tk/lib/tk/text.rb: ditto.\n\n\t* ext/tk/lib/tk/validation.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/*: support to treat tkvariable-type\n\t  configure options.\n\nTue Aug  9 20:30:19 2005  Tadashi Saito  <shiba@mail2.accsnet.ne.jp>\n\n\t* bignum.c (rb_big_coerce): allow bignum x bignum coercing.\n\t  [ruby-dev:26778]\n\nMon Aug  8 20:43:02 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_method.rb: added.  [ruby-dev:26761]\n\nSun Aug  7 23:50:14 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_super.rb: added from HEAD. [ruby-dev:26743]\n\nSun Aug  7 01:31:15 2005  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (WIN32OLE_EVENT#on_event): should set\n\t  only one event handler.\n\n\t* ext/win32ole/tests/testOLEEVENT.rb: ditto.\n\n\t* ext/win32ole/tests/testOLEPARAM.rb: remove re-defined\n\t  test_ole_type_detail method.\n\nSat Aug  6 12:35:24 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/{tk.rb,tk/itemconfig.rb}: configure creates\n\t  TkVariable if key name is 'variable' or 'textvariable'\n\t  by default. [ruby-dev:26749]\n\n\t* ext/tk/lib/tk/{label,radiobutton}.rb: removed its own\n\t  {variable,textvariable} function.\n\n\t* ext/tk/lib/tk/variable.rb: retains backward conpatibility.\n\nFri Aug  5 12:50:32 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c: fixed memory leak when tk_funcall raised\n\t  exception. (copies argv into heap in tk_funcall instead of\n\t  caller)\n\nFri Aug  5 12:42:57 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): need to convert path separetor\n\t  before invoking install command.\n\nFri Aug  5 00:27:04 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c: refactoring - extract ruby string <->\n\t  tcl object conversion as get_str_from_obj and get_obj_from_str.\n\nFri Aug  5 00:19:33 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* extmk.rb (extmake): needs to be wrapped in an Array.\n\nThu Aug  4 18:38:36 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: cannot compile for Tcl7.6/Tk4.2.\n\n\t* ext/tcltklib/tcltklib.c: add nativethread consistency check.\n\n\t* ext/tcltklib/stubs.c: ditto.\n\n\t* ext/tk/lib/tk.rb: forgot to define TclTkIp.encoding and encoding=\n\t  when Tcl is 7.6 or 8.0.\n\n\t* ext/tk/lib/tk/wm.rb: support to make some methods as options of\n\t  root or toplevel widget. [ruby-talk:150336]\n\n\t* ext/tk/lib/tk/root.rb: ditto.\n\n\t* ext/tk/lib/tk/toplevel.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/SUPPRT_STATUS: update RELEASE_DATE\n\nThu Aug  4 08:03:39 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): should not modify $mflags for each\n\t  extentions.\n\nThu Aug  4 00:25:48 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk, Makefile.in, {bcc32,win32,wince}/Makefile.sub: integrated\n\t  macro definitions.\n\n\t* bcc32/Makefile.sub: LIBRUBY_SO should use DLDOBJS, not EXTOBJS.\n\n\t* {win32,wince}/Makefile.sub: separate config.h for compiler versions.\n\nWed Aug  3 21:59:16 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/variable.rb: TkVariable#trace didn't work on\n\t  TkVariable retrived from TkVariable.new_hash.ref. [ruby-dev:26721]\n\nWed Aug  3 08:22:13 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): revert [ruby-talk:111654]\n\t  changes at 2004-09-07.  [ruby-dev:26656]\n\nTue Aug  2 10:20:54 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c: use Tcl_[GS]etVar2Ex instead of\n\t  Tcl_Obj[GS]etVar2. (avoid Tcl_NewStringObj on supported platforms)\n\n\t* ext/tcltklib/tcltklib.c: use ip_{get,set,unset}_variable2_core from\n\t  ip_{get,set,unset}_variable.\n\n\t* ext/tcltklib/tcltklib.c: replaced Tcl_Panic with rb_bug.\n\nTue Aug  2 01:41:28 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/ping.rb (Ping.pingecho): should rescue StandardError.\n\t  [ruby-dev:26677]\n\nMon Aug  1 19:09:41 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c: refactoring - replaced rb_ivar_defined &\n\t  rb_ivar_get with single rb_attr_get call.\n\nMon Aug  1 18:45:07 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c (Tcl_GetStringResult): refactoring - define\n\t  alternative macro on Tcl7.x or earlier.\n\nMon Aug  1 13:57:35 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c (deleted_ip): refactoring - interpreter\n\t  deletion check. [ruby-dev:26664]\n\nMon Aug  1 01:17:40 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (check_insecure_method): use private_methods and\n\t  protected_methods instead of respond_to? to check method visibility.\n\t  [ruby-dev:26616]\n\n\t* test/drb/drbtest.rb: ditto.\n\n\t* test/drb/ut_drb.rb: ditto.\n\nMon Aug  1 00:07:32 2005  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/irb/context.rb: fix `irb --readline` option. [ruby-list:40955]\n\nFri Jul 29 09:59:38 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): push yielded node instead of yielding.\n\t  fixed: [yarv-dev:549]\n\nThu Jul 28 18:09:55 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/stubs.c: When --enable-tcltk-stubs, the initialize\n\t  routine creates a Tcl/Tk interpreter and deletes it. However,\n\t  init cost of Tk's MainWindow is not so small. And that makes it\n\t  impossible to use libraries written with Tcl functions only on\n\t  an environment without a graphical display. This changes support\n\t  delaying initalization of Tk_Stubs until the script needs Tk.\n\n\t* ext/tcltklib/stubs.h: New file. Define prototypes and return\n\t  codes of functions on stubs.c.\n\n\t* ext/tcltklib/tcltklib.c: Support delaying initalization of\n\t  Tk_Stubs until the script needs Tk.\n\n\t* ext/tcltklib/tcltklib.c: Show friendly error messages for errors\n\t  on initialization.\n\n\t* ext/tcltklib/tcltklib.c: Avoid SEGV on ip_finalize() when ruby is\n\t  exiting and $DEBUG is true. (Not fix. If you know the reason of\n\t  why, please fix it.)\n\n\t* ext/tk/tkutil.c (ary2list, ary2list2): bug fix on handling of\n\t  encoding.\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp#eval_string and bg_eval_string\n\t  don't work propery.\n\n\t* ext/tk/lib/tk.rb: Forget extending Tk::Encoding module to Tk.\n\t* ext/tk/lib/tk/variable.rb: TkVarAccess fails to initialize the\n\t  object for an element of a Tcl's array variable.\n\nWed Jul 27 23:23:54 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (obj_free): make message format consistent with one from\n\t  gc_mark().  [ruby-talk:149668]\n\nWed Jul 27 22:11:37 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* sample/rss/tdiary_plugin: removed. because the plugin\n\t  is imported in the tDiary plugin packages.\n\nWed Jul 27 10:59:02 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_each): rewinddir(3) before iteration.\n\t  [ruby-talk:149628]\n\nTue Jul 26 12:57:49 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/openssl_missin.c: include <openssl/engine.h> before\n\t  <openssl/x509_vfy.h> to avoid compilation error of mswin32.\n\t  suggested by NAKAMURA Usaku.\n\nMon Jul 25 21:30:46 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/Makefile.sub: moved CPPFLAGS only for ruby\n\t  source to XCFLAGS.\n\nMon Jul 25 13:45:18 2005  NAJIMA Hiroki  <najima@mickey.ai.kyutech.ac.jp>\n\n\t* io.c: check HAVE_SYS_IOCTL_H before including the header.\n\t  [ruby-dev:26610]\n\nMon Jul 25 14:10:02 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: fix en-bugged part in the last commit.\n\nSat Jul 23 16:49:04 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_engine.c (ossl_engine_s_load): should check\n\t  OPENSSL_NO_STATIC_ENGINE.\n\nFri Jul 22 21:06:08 2005  Tadashi Saito  <shiba@mail2.accsnet.ne.jp>\n\n\t* bignum.c (rb_big_eq): reduce isnan().  [ruby-dev:26600]\n\n\t* numeric.c (flo_eq, flo_gt, flo_ge, flo_lt, flo_le): ditto.\n\nFri Jul 22 15:02:39 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: moved copyright description to lib/rss.rb.\n\n\t* lib/rss.rb: added for convenience.\n\n\t* sample/rss/re_read.rb: added #to_s sample.\n\n\t* sample/rss/blend.rb: use 'require \"rss\"' instead of\n\t  'require \"rss/*\"'.\n\t* sample/rss/list_description.rb: ditto.\n\t* sample/rss/rss_recent.rb: ditto.\n\t* sample/rss/tdiary-plugin/rss-recent.rb: ditto.\n\n\t* sample/rss/tdiary-plugin/rss-recent.rb: 0.0.6 -> 0.0.7.\n\nFri Jul 22 14:37:43 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/parser.rb (RSS::Parser#initialize): accept HTTP/FTP\n\t  URI and local file path too.\n\n\t* test/rss/test_parser.rb (RSS::TestParser#test_parse): test\n\t  for the above.\n\nFri Jul 22 07:01:42 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c (tk_conv_args): forget to revert thread_critical\n\t  and gc_disable when raise ArgumentError.\n\n\t* ext/tk/lib/remote-tk.rb: RemoteTkIp doesn't need to include TkUtil.\n\n\t* ext/tcltklib/tcltklib.c: add TclTkIp#has_mainwindow? method.\n\n\t* ext/tk/lib/tk.rb: add Tk.has_mainwindow? method.\n\n\t* ext/tk/lib/multi-tk.rb: add MultiTkIp#has_mainwindow? method.\n\n\t* ext/tk/lib/remote-tk.rb: add RemoteTkIp#has_mainwindow? method.\n\n\t* ext/tk/lib/multi-tk.rb: slave IP fail to exit itself when $SAFE==4.\n\n\t* ext/tk/lib/multi-tk.rb: remove constants from MultiTkIp module to\n\t  avoid access from external.\n\n\t* ext/tk/lib/multi-tk.rb: check_root flag is ignored on slave IPs'\n\t  mainloop.\n\n\t* ext/tk/lib/multi-tk.rb: hang-up Tk.mainloop called on a slave IP\n\t  with $SAFE==4.\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp#bg_eval_proc doesn't work\n\t  properly.\n\n\t* ext/tk/lib/multi-tk.rb: add MultiTkIp#set_cb_error(proc) and\n\t  cb_error(exc) to log errors at callbacks on safe slave IPs.\n\n\t* ext/tk/lib/multi-tk.rb: fail to get an available slave IP object\n\t  when call Tk.mainloop in the block which is given to new_* method,\n\t    because cannot finish initialize while the root widget is alive.\n\n\t* ext/tk/lib/multi-tk.rb: fail to control a slave IP when Tk.mainloop\n\t  runs on the IP.\n\nWed Jul 20 19:20:37 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (S_ISREG): need to define S_ISREG before it is used first.\n\nWed Jul 20 18:40:50 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* io.c (wsplit_p): patch for the environment where\n\t  fcntl(F_GETFL, O_NONBLOCK) is not supported. in that case,\n\t  set FMODE_WSPLIT without fcntl check. [ruby-dev:26566]\n\nWed Jul 20 18:07:11 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_io_ctl): update FMODE_WSPLIT_INITIALIZED and FMODE_WSPLIT\n\t  by F_SETFL.\n\nWed Jul 20 10:04:51 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_class_path): need to adjust snprintf() len for\n\t  teminating NUL.  [ruby-dev:26581]\n\nWed Jul 20 04:01:55 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/socket/socket.c: sorry, BeOS also uses HAVE_CLOSESOCKET,\n\t  so reverted.\n\n\t* ext/socket/extconf.rb: should not define HAVE_CLOSESOCKET\n\t  on windows.\n\nWed Jul 20 03:16:43 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/socket/socket.c: should not undef close() on win32.\n\t  it's defined to rb_w32_close(), otherwise handle leaks.\n\t  [ruby-Bugs-2131]\n\nWed Jul 20 00:48:16 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (syserr_initialize): don't use str before StringValue()\n\t  check.  [ruby-dev:26579]\n\nTue Jul 19 22:47:29 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (syserr_initialize): add 1 byte for snprintf() size for\n\t  NUL at the end.  [ruby-dev:26574]\n\nTue Jul 19 16:39:46 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_inspect): replace sprintf() with \"%s\" format all\n\t  over the place by snprintf() to avoid integer overflow.\n\nTue Jul 19 14:08:22 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c: rbtk_eventloop_depth is used as int.\n\n\t* ext/tcltklib/tcltklib.c: rbtk_pending_exception is tested with\n\t  NIL_P, so should assign Qnil instead of 0 (Qfalse).\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke_real): fixed memory leak when\n\t  ip is deleted.\n\nTue Jul 19 13:19:46 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/variable.rb: For symmetry, add TkVariable#string. It\n\t  returns a string even if the default value type of the TkVariable\n\t  object is not \"string\".\n\nMon Jul 18 21:40:20 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* eval.c (rb_call0): make the pointer to NODE volatile\n\t  instead of NODE itself.\n\nMon Jul 18 14:32:21 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (rb_call0): make body volatile to avoid optimization problem.\n\t  [ruby-dev:26195]\n\nMon Jul 18 12:23:27 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/io/wait/wait.c: wrong backport from trunk.  fixed: [ruby-dev:26562]\n\nMon Jul 18 09:36:25 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* rubyio.h (FMODE_WSPLIT, FMODE_WSPLIT_INITIALIZED): new constant.\n\n\t* io.c (wsplit_p): new function.\n\t  (io_fwrite): split writing data by PIPE_BUF if wsplit_p is true in\n\t  multi-threaded mode.\n\t  [ruby-dev:26540]\n\nSun Jul 17 13:46:54 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/io/wait/extconf.rb, ext/io/wait/wait.c: Win32 platforms support.\n\nFri Jul 15 23:59:03 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_c.rb (handle_class_module): handle a\n\t  module enclosed in a built-in module.  fixed: [ruby-talk:148239]\n\n\t* lib/rdoc/parsers/parse_c.rb (find_body): allow macros as methods.\n\n\t* lib/rdoc/parsers/parse_c.rb (find_call_seq): allow :nodoc: modifier\n\t  in C.  [ruby-core:04572]\n\nFri Jul 15 18:00:01 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub (COMMON_HEADERS): ruby_1_8 is using winsock.h.\n\t  failed to compile ext/socket on bcc5.6.4. [ruby-dev:26193]\n\nFri Jul 15 07:58:56 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/server.rb (WEBrick::GenericServer#accept_client):\n\t  sockets should be non-blocking mode. [ruby-dev:26405]\n\n\t* lib/webrick/utils.rb (WEBrick::Utils.set_non_blocking): new method.\n\n\t* lib/webrick/httprequest.rb (WEBrick::HTTPRequest#read_chunked):\n\t  should call sock.read repeatedly until the preferred size data\n\t  is obtained.\n\nThu Jul 14 18:27:16 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (rb_w32_strerror): should return correct message\n\t  for ENAMETOOLONG and ENOTEMPTY. (bcc32) [ruby-dev:26533]\n\n\t* win32/win32.c (rb_w32_strerror): stripped CR LF on the tail.\n\t  (bcc32) [ruby-dev:26533]\n\nThu Jul 14 00:45:42 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* LEGAL (ext/nkf/nkf-utf8): updated from nkf1.7 to nkf-utf8.\n\nWed Jul 13 19:37:47 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (rb_w32_mkdir): should set EEXIST (not EACCES)\n\t  if file or directory already exists. (bcc32) [ruby-dev:26508]\n\n\t* win32/win32.c (rb_w32_rmdir): should set ENOTDIR (not EINVAL)\n\t  if it is not directory. (bcc32, win32)\n\n\t* win32/win32.c (rb_w32_rmdir, rb_w32_unlink): restore\n\t  FILE_ATTRIBUTE_READONLY flag on function failure.\n\nWed Jul 13 12:40:00 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: TclTkLib.do_one_event doesn't work.\n\n\t* ext/tk/lib/tk.rb: Tk.thread_update is available.\n\nTue Jul 12 23:32:11 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb: keep curdir unexpanded.\n\nMon Jul 11 08:31:29 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* regex.c (read_special): fix parsing backslashes following \\c in\n\t  regexp.  fixed: [ruby-dev:26500]\n\nMon Jul 11 02:53:00 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI::Socket#request_line):\n\t  mistook in merging the patch of [ruby-dev:26235] at\n\t  revision 1.4.2.6.\n\nSun Jul 10 23:58:04 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#unlink): try Dir.unlink first to\n\t  avoid unlink a directory by root.\n\t  cf. [ruby-dev:26237]\n\nSun Jul 11 05:18:17 2005  Michael Neumann  <mneumann@ruby-lang.org>\n\n\t* lib/xmlrpc/server.rb (XMLRPC::Server): Switch from GServer over to\n\t  WEBrick. This makes file lib/xmlrpc/httpserver.rb obsolete (at least it is\n\t\tno further used by the XML-RPC library).\n\nSun Jul 10 12:47:01 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/debug.rb (debug_command): added a deficient format specifier.\n\t  fixed: [ruby-core:05419]\n\nSat Jul  9 21:28:46 2005  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_method_dispid): convert dispid\n\t  in Ruby and C by INT2NUM and NUM2INT.\n\n\t* ext/win32ole/win32ole.c (ole_invoke2): ditto.\n\n\t* ext/win32ole/test/testWIN32OLE.rb: ditto.\n\n\t* ext/win32ole/test/testOLEMETHOD.rb: ditto.\n\nFri Jul  8 15:45:04 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (RSS::VERSION): 0.1.4 -> 0.1.5.\n\n\t* test/rss/test_version.rb (RSS::TestVersion#test_version):\n\t  ditto.\n\n\t* lib/rss/0.9.rb (RSS::Rss::Channel::Item::Category):\n\t  domain attribute of <category> is optional. Thanks to\n\t  Chris Lee <clee@kde.org>.\n\n\t* test/rss/test_parser.rb (RSS::TestParser#test_category20):\n\t  adjusted test case.\n\nTue Jul  5 23:44:06 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* instruby.rb: expand source library path.\n\nTue Jul  5 23:27:14 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* array.c (sort_2): get rid of yet another bcc's bug.\n\t  fixed: [ruby-core:05152]\n\n\t* eval.c (rb_thread_save_context): must not switch contexts during\n\t  re-allocating stack.  fixed: [ruby-core:05219]\n\nTue Jul  5 15:15:10 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c: fix typo.\n\nTue Jul  5 14:51:35 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: bug fix on treating Unicode strings.\n\n\t* ext/tcltklib/tcltklib.c: add methods to treat encoding mode.\n\n\t* ext/tcltklib/MANUAL.eng: add description of TclTkLib#encoding,\n\t  encoding_system, and so on.\n\n\t* ext/tcltklib/MANUAL.euc: ditto.\n\n\t* ext/tk/tkutil.c: fail to create a Tcl's list string from an\n\t  array including multiple kind of encoded strings.\n\n\t* ext/tk/lib/tk.rb: ditto.\n\n\t* ext/tk/lib/multi-tk.rb: 2nd arg of _{to|from}UTF8 is omissible.\n\n\t* ext/tk/lib/remote-tk.rb: ditto.\n\n\t* ext/tk/lib/tk.rb: override TclTkLib#encoding and encoding= to\n\t  use TkCore::INTERP.encoding and encoding=.\n\n\t* ext/tk/lib/tk.rb: when \"require 'tk'\" and $KCODE=='NONE', check\n\t  DEFAULT_TK_ENCODING to decide Ruby/Tk's system encoding mode.\n\n\t* ext/tk/lib/tk/encodedstr.rb: check both of Tk.encoding and\n\t  Tk.encoding_system. Tk.encoding has higher priority.\n\n\t* ext/tk/lib/tk/optiondb.rb: ditto.\n\n\t* ext/tk/lib/tk/spinbox.rb: ditto.\n\n\t* ext/tk/lib/tk/validation.rb: ditto.\n\n\t* ext/tk/lib/tk/namespace.rb: arguemnts for TclTkIp#_merge_tklist\n\t  should be UTF-8 strings.\n\nMon Jul  4 14:35:52 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sample/svr.rb: service can be stopped by ill-behaved client; use\n\t  tsvr.rb instead.\n\nMon Jul  4 13:25:21 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* missing/erf.c: original erf.c by prof. Okumura is confirmed to\n\t  be public domain.  reverted BSD implementation.\n\nMon Jul  4 11:15:37 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/{dbm,gdbm,sdbm}/test_{dbm,gdbm,sdbm}.rb: skip some tests\n\t  which using fork on fork-less platforms.\n\nSun Jul  3 23:26:30 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/wsdl/document/test_rpc.rb: compare formatted time string of\n\t  Time objects instead of comparing Time objects itself to avoid\n\t  unintended conflict of usec part.  [ruby-dev:26220]\n\nSat Jul  2 22:41:04 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c (unix_send_io, unix_recv_io): support x86-64 and\n\t  IA64.\n\nSat Jul  2 17:06:23 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* defines.h (FLUSH_REGISTER_WINDOWS): defined for IA64.\n\t  (flush_register_windows): declare flush_register_windows.\n\n\t* eval.c (flush_register_windows): new function.\n\nFri Jul  1 17:48:52 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (get2comp): revert all prior changes, and calculate\n\t  proper 2's complement for negative numbers.  backported from\n\t  HEAD.\n\nFri Jul  1 15:50:12 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* missing/erf.c: need to include some headers for some platforms.\n\n\t* win32/win32.h (copysign, scalb): define for compatibility with\n\t  other platforms. [ruby-dev:26430]\n\nFri Jul  1 15:37:42 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* missing/crypt.c: modified to make it compilable on platforms\n\t  other than BSD.  [ruby-dev:26430]\n\n\t* missing/erf.c: ditto.  code from <exp.c> merged.\n\nFri Jul  1 12:44:56 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI.open_http): refine post_connection_check\n\t  call.\n\nFri Jul  1 11:34:08 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* missing/crypt.c: replaced with 4.4BSD version.\n\n\t* missing/erf.c: ditto.\n\n\t* missing/vsnprintf.c: removed the third provision from the old\n\t  BSD license.  [ruby-core:05177]\n\nFri Jul  1 01:45:21 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (enum_min, enum_max): must not return Qundef.\n\t  fixed: [ruby-core:05299]\n\nFri Jul  1 00:18:40 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb (Delegator::respond_to): respond_to? must check\n\t  destination object.  [ruby-talk:146894]\n\nThu Jun 30 19:00:21 2005  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/irb/ruby-lex.rb (RubyLex::identify_number): alternative implements\n\t  for [ruby-dev:26410]. And support a numeric form of 0d99999.\n\nThu Jun 30 17:28:10 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/ruby-lex.rb (RubyLex::identify_number): should not treat\n\t  plain zero as an octal number.  [ruby-dev:26410]\n\nThu Jun 30 15:13:16 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): pre-evaluate argument for unambiguous\n\t  evaluation order.  [ruby-dev:26383]\n\nThu Jun 30 09:53:56 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb (Delegator::method_missing): forward unknown\n\t  method to the destination.  suggested by\n\t  <christophe.poucet@gmail.com>.  [ruby-talk:146776]\n\nTue Jun 28 21:59:29 2005  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* dir.c, eval.c, hash.c, process.c, ruby.c: avoid warning \"unused\n\t  variable\" [ruby-dev:26387]\n\nSat Jun 25 17:15:23 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils.parse_query): should\n\t  discard if key=val pair is empty. patch from Gary Wright.\n\nSat Jun 25 23:30:51 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (detach_process_watcher): terminate process watcher\n\t  thread right after rb_waitpid() succeed.  [ruby-talk:146430]\n\nSat Jun 25 15:49:18 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (enum_min, enum_max): do not ignore nil as the first element.\n\nSat Jun 25 14:40:17 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/sdbm/init.c (fsdbm_select): SDBM#select had returned the array\n\t  which contained each elements twice. [ruby-dev:26358]\n\nFri Jun 25 05:06:47 2005  Michael Neumann  <mneumann@ruby-lang.org>\n\n\t* lib/xmlrpc/*, test/xmlrpc/*: backported changes from HEAD into 1.8\n\nFri Jun 24 17:00:00 2005  Shigeo Kobayashi  <shigeo@tinyforest.jp>\n\n\t* ext/bigdecimal/bigdecimal.c: patch from \"NATORI Shin\"\n\t  (u-tokyo.ac.jp) applied to fix rounding bug.\n\nFri Jun 24 13:06:45 2005  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/common.rb, lib/uri/generic.rb: fixed typo in documents and\n\t  replaced some existent domain name with \"example.com\".\n\nFri Jun 24 12:23:19 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: fix typo on Tk.grid_propagate.\n\n\t* ext/tk/lib/tk.rb: Tk.event_generate and TkWindow#event_generate\n\t  accept TkEvent::Event object as context argument.\n\n\t* ext/tk/lib/tk/event.rb: add TkEvent::Event#valid_fields and\n\t  valid_for_generate to get field parameters of event_generate.\n\nThu Jun 23 23:55:59 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* runruby.rb: should load built rbconfig.rb.\n\nThu Jun 23 16:53:15 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/canvastag.rb: TkcGroup.new cannot include given items.\n\t  TkcGroup#exclude calls wrong method.\n\t  Add alias TkcGroup#add [ruby-talk:146049].\n\n\t* ext/tk/lib/tk/canvas.rb: TkCanvas#dtag and some subcommands of\n\t  TkCanvas#addtag fail to treat a TkcTag argument.\n\n\t* ext/tk/lib/tk/event.rb: add TkEvent::Event#generate to help to send\n\t  current event to other widgets.\n\nMon Jun 20 18:44:04 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (FUNCTION_CALL_MAY_RETURN_TWICE): DUMMY_SETJMP is replaced\n\t  because setjmp is not enough to fix getcontext and SPARC register\n\t  window problem.\n\nMon Jun 20 16:48:36 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/dbm/dbm.c (fdbm_closed): new method DBM#closed?\n\n\t* ext/gdbm/gdbm.c (fgdbm_closed): new method GDBM#closed?\n\n\t* ext/sdbm/init.c (fsdbm_closed): new method SDBM#closed?\n\n\t* test/dbm/test_dbm.rb, test/gdbm/test_gdbm.rb, test/sdbm/test_sdbm.rb\n\t  (teardown): close all db objects before deleting data files.\n\n\t* win32/win32.{ch} (unlink): hook runtime function to change\n\t  file attribute before unlinking.\n\t  fixed: [ruby-dev:26360]\n\nMon Jun 20 02:15:35 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (define_final): document fix: finalizers never get called\n\t  before target object is destroyed.\n\nMon Jun 20 01:26:49 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/openssl_missing.c, ext/openssl/ossl.h,\n\t  ext/openssl/ossl_asn1.c, ext/openssl/ossl_bio.c,\n\t  ext/openssl/ossl_pkcs12.h, ext/openssl/ossl_x509req.c: avoid\n\t  compiler warnings. suggested by Michal Rokos.\n\nSun Jun 19 14:09:07 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (run_final): reduce unnecessary object allocation during\n\t  finalization.\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): deferred finalizers list should\n\t  be cleared before calling them.  fixed: [ruby-talk:145790]\n\nFri Jun 17 13:01:40 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb (Time.parse): fix previous leap seconds support.\n\t  (Time.rfc2822): ditto.\n\t  (Time.xmlschema): ditto.\n\nThu Jun 16 15:06:55 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_rb_threadVwaitCommand): Tcl_Release\n\t  was missing.\n\nThu Jun 16 13:34:48 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add Tk.getMultiple{Open|Save}File() which return\n\t  an Array of selected files.\n\nThu Jun 16 12:53:24 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb (Time.parse): \"Fri Jan  1 08:59:60 +0900 1999\" was\n\t  parsed as \"Fri Jan 01 09:00:00 JST 1999\" even on an environment\n\t  which supports leap seconds.\n\t  (Time.rfc2822): ditto.\n\t  (Time.xmlschema): ditto.\n\nThu Jun 16 08:29:22 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/dl/sym.c (rb_dlsym_call): needs FREE_ARGS before return.\n\t  fixed memory leak. [ruby-Bugs-2034]\n\nWed Jun 15 18:26:39 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: support \"tk inactive\" sub-command [for Tcl/Tk8.5a3]\n\n\t* ext/tk/lib/tk/namespace.rb: support \"namespace path\" sub-command and\n\t  'namespace ensemble' sub-command [for Tcl/Tk8.5a3]\n\nTue Jun 14 02:02:43 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c: add TkUtil::CallbackSubst.subst_arg(m, ...) &\n\t  _define_attribute_aliases(hash) to get substitution-argument from\n\t  attributes (e.g. subst_arg(:x,:y,:num,:button) --> \"%x %y %b %b \").\n\n\t* ext/tk/lib/tk/event.rb: use _define_attribute_aliases().\n\nMon Jun 13 13:01:05 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* hash.c (ruby_setenv): fixed SEGV. [ruby-dev:26186]\n\nMon Jun 13 01:54:20 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* signal.c (sigexit): call rb_thread_signal_exit() instead of\n\t  rb_exit().  [ruby-dev:26347]\n\n\t* eval.c (rb_thread_signal_exit): a new function to exit on main\n\t  thread.\n\n\t* eval.c (rb_thread_switch): exit status should be retrieved from\n\t  ruby_errinfo.\n\n\t* eval.c (rb_f_exit): ensure exit(0) should call\n\t  exit(EXIT_SUCCESS).\n\nMon Jun 13 01:20:02 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (rb_gc_mark_threads): curr_thread may not be part of the\n\t  thread list.  [ruby-dev:26312]\n\nFri Jun 10 23:35:34 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* missing/mkdir.c: remove. [ruby-core:05177]\n\nFri Jun 10 22:54:26 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* missing.h: fd_set stuffs need sys/types.h.  fixed: [ruby-core:05179]\n\nThu Jun  9 23:58:12 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/Win32API/Win32API.c (Win32API_Call): disable global\n\t  optimization. fixed: [ruby-core:05143]\n\nThu Jun  9 23:35:22 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (enum_inject): default the result value to Qundef to use\n\t  first element as initial value if not given.\n\nThu Jun  9 19:55:41 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (ruby_longjmp): new macro to call longjmp, setcontext, etc.\n\t  (ruby_setjmp): new macro to call setjmp, getcontext, etc.\n\t  (ruby_setjmp): call setjmp before getcontext to avoid IA64 register\n\t  stack problem.\n\t  [ruby-talk:144939]\n\n\t* gc.c (Init_stack): remove IA64_MAGIC_STACK_LIMIT.\n\nThu Jun  9 11:55:34 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb (SimpleDelegator::__setobj__): need check for\n\t  recursive delegation.  [ruby-core:04940]\n\nWed Jun  8 18:47:10 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-expr-beg): fix looking point drift.\n\nWed Jun  8 11:11:34 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (get2comp): calculate proper 2's complement for\n\t  negative numbers.  a bug in normalizing negative numbers\n\t  reported from Honda Hiroki <hhonda@ipflex.com>.\n\nWed Jun  8 08:33:10 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (enum_min_by, enum_max_by): return nil if no iteration.\n\t  fixed: [ruby-dev:26245]\n\n\t* eval.c (rb_need_block): ensure a block is given.\n\n\t* eval.c (backtrace): skip successive frames sharing same node.\n\nWed Jun  8 00:15:08 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_getaddrinfo__aix): merged a patch from\n\t  KUBO Takehiro <kubo at jiubao.org> to support AIX.  [ruby-list:40832]\n\nWed Jun  8 00:09:01 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb (Array::to_yaml): merged a patch from\n\t  Tilman Sauerbeck <tilman at code-monkey.de>.  [ruby-core:05055]\n\n\t* lib/yaml/rubytypes.rb (Hash::to_yaml): ditto.\n\nWed Jun  8 00:00:01 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/curses/curses.c (curses_insertln): merged a patch from\n\t  TAKAHASHI Tamotsu <ttakah at lapis.plala.or.jp>.  [ruby-ext:02305]\n\nTue Jun  7 19:34:15 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/init.rb (IRB::IRB.rc_file_generators): more flexible\n\t  IRB.rc_file_generators.  [ruby-core:05163]\n\nTue Jun  7 18:39:31 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/thread.rb: RDoc documentation from Eric Hodel\n\t  <drbrain at segment7.net> added.  [ruby-core:05148]\n\nTue Jun  7 18:30:04 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): add .SUFFIXES from depend file.\n\t  fixed: [ruby-dev:26294]\n\nTue Jun  7 17:39:54 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_cvar_get): Module#class_variable_get(): back\n\t  ported from CVS HEAD.  [ruby-talk:144741]\n\n\t* object.c (rb_mod_cvar_set): Module#class_variable_set().\n\t  [ruby-talk:144741]\n\nTue Jun  7 16:32:53 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): raise exception on debug mode (-d),\n\t  not verbose mode (-v/-w).  [ruby-core:05123]\n\nTue Jun  7 10:30:49 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: slave-ip fails to call procedures\n\t  delegated by master-ip.\n\nSun Jun  5 23:00:35 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/console.rb: create console when required\n\n\t* ext/tk/sample/tkextlib/tile/demo.rb: fix TypeError & create Console\n\nSat Jun  4 14:55:18 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* test/dbm/test_dbm.rb: merged from ext/dbm/testdbm.rb.\n\n\t* test/gdbm/test_gdbm.rb: merged from ext/gdbm/testgdbm.rb.\n\n\t* test/sdbm/test_sdbm.rb: renamed from ext/sdbm/testsdbm.rb with\n\t  modification to use test/unit.\n\nFri Jun  3 14:06:12 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: fix typo.\n\nWed Jun  1 11:32:42 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: can use single quote character in DESTDIR.\n\t  [ruby-dev:26205]\n\nMon May 30 23:48:29 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/macpkg.rb: add PACKAGE_NAME information of Tcl/Tk\n\t  Extension.\n\n\t* ext/tk/lib/tk/msgcat.rb: ditto.\n\n\t* ext/tk/lib/tk/winpkg.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/*: ditto.\n\nSat May 28 16:40:15 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* test/openssl/test_x509store.rb: add test for expired CRL\n\t  and refine some assertions.\n\nSat May 28 05:15:51 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509store.c (ossl_x509stctx_set_time): should\n\t  not set internal flag directry.\n\nSat May 28 02:00:11 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI::Socket#request_line):\n\t  ENV[\"REQUEST_URI\"] is better to get correct Request-URI\n\t  than ENV[\"SCRIPT_NAME\"] + ENV[\"PATH_INFO\"].  [ruby-dev:26235]\n\nFri May 27 16:32:04 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb: use the semicolon as the path separator\n\t  in the environment of MSYS.  fixed: [ruby-dev:26232]\n\nThu May 26 06:08:11 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add shortcut-methods of tk_call + tk_split_list\n\nWed May 25 22:52:42 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/irb/input-method.rb: do not use Readline::HISTORY.pop.\n\t  (backported from HEAD)\n\nWed May 25 21:55:40 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/readline/readline.c: supported libedit. (backported from HEAD)\n\n\t* ext/readline/extconf.rb: ditto.\n\n\t* test/readline/test_readline.rb: ditto.\n\nWed May 25 20:06:27 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: TkComm#tk_split_*list fail to split a kind of SJIS\n\t  strings. To avoid the trouble, add arguments to control converting\n\t  encoding, and do split on a UTF8 string.\n\n\t* ext/tk/lib/multi-tk.rb: modify to attend encoding.\n\n\t* ext/tk/lib/remote-tk.rb: ditto.\n\n\t* ext/tk/lib/tk/itemconfig.rb: ditto.\n\n\t* ext/tk/lib/tk/listbox.rb: ditto.\n\n\t* ext/tk/lib/tk/namespace.rb: ditto.\n\n\t* ext/tk/lib/tk/panedwindow.rb: ditto.\n\n\t* ext/tk/lib/tk/text.rb: ditto.\n\n\t* ext/tk/lib/tk/textmark.rb: ditto.\n\n\t* ext/tk/lib/tk/texttag.rb: ditto.\n\n\t* ext/tk/lib/tk/variable.rb: ditto.\n\n\t* ext/tk/lib/tk/winfo.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb: ditto.\n\n\t* ext/tk/lib/tk.rb: add TkWindow#lower_window/raise_window and\n\t  Tk#lower_window/raise_window by reason of method-name conflict\n\n\t* ext/tk/lib/tk/canvas.rb: bug fix on TkCanvas#delete when given\n\t  non-TkcItem arguments.\n\n\t* ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb: ditto.\n\nWed May 25 12:59:48 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI::Meta::RE_QUOTED_STRING): a content of\n\t  quoted-string should be zero or more characters.\n\nTue May 24 23:42:16 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_pow): support Fixnum ** Float case directly\n\t  without coercing.  [ruby-talk:142697] [ruby-talk:143054]\n\nTue May 24 16:57:24 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (require_libraries): caused SEGV when continuation jumped\n\t  in to the required library code.\n\nTue May 24 11:56:25 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/getopts.rb: should warn only if verbose mode.\n\t  fixed: [ruby-dev:26201]\n\nTue May 24 06:45:31 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-font-lock-syntactic-keywords): string\n\t  literals to be matched non-greedy.\n\nTue May 24 00:34:32 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/calc: method name 'set' was able to crash with a class Set.\n\t  [ruby-dev:26210]\n\n\t* test/wsdl/document/test_rpc.rb: dateTime comparison failed under\n\t  TZ=right/Asia/Tokyo (with leap second.) [ruby-dev:26208]\n\nMon May 23 16:24:05 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/extconf.rb: Framework support on MacOS X Tiger.\n\n\t* ext/tcltklib/README.1st: add description of Framework support options.\n\nMon May 23 12:21:37 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (make_regexp): should not return junk address during\n\t  compile time.  [ruby-dev:26206]\n\nSun May 22 21:54:06 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/{soap,wsdl,xsd}, test/{soap,wsdl,xsd}: imported soap4r/1.5.4.\n\n\t  == SOAP client and server ==\n\n\t  === for both client side and server side ===\n\n\t  * improved document/literal service support.\n\t    style(rpc,document)/use(encoding, literal) combination are all\n\t    supported.  for the detail about combination, see\n\t    test/soap/test_style.rb.\n\n\t  * let WSDLEncodedRegistry#soap2obj map SOAP/OM to Ruby according to\n\t    WSDL as well as obj2soap.  closes #70.\n\n\t  * let SOAP::Mapping::Object handle XML attribute for doc/lit service.\n\t    you can set/get XML attribute via accessor methods which as a name\n\t    'xmlattr_' prefixed (<foo name=\"bar\"/> -> Foo#xmlattr_name).\n\n\t  === client side ===\n\n\t  * WSDLDriver capitalized name operation bug fixed.  from\n\t    1.5.3-ruby1.8.2, operation which has capitalized name (such as\n\t    KeywordSearchRequest in AWS) is defined as a method having\n\t    uncapitalized name. (converted with GenSupport.safemethodname\n\t    to handle operation name 'foo-bar').  it introduced serious\n\t    incompatibility; in the past, it was defined as a capitalized.\n\t    define capitalized method as well under that circumstance.\n\n\t  * added new factory interface 'WSDLDriverFactory#create_rpc_driver'\n\t    to create RPC::Driver, not WSDLDriver (RPC::Driver and WSDLDriver\n\t    are merged).  'WSDLDriverFactory#create_driver' still creates\n\t    WSDLDriver for compatibility but it warns that the method is\n\t    deprecated.  please use create_rpc_driver instead of create_driver.\n\n\t  * allow to use an URI object as an endpoint_url even with net/http,\n\t    not http-access2.\n\n\t  === server side ===\n\n\t  * added mod_ruby support to SOAP::CGIStub.  rename a CGI script\n\t    server.cgi to server.rb and let mod_ruby's RubyHandler handles the\n\t    script.  CGIStub detects if it's running under mod_ruby environment\n\t    or not.\n\n\t  * added fcgi support to SOAP::CGIStub.  see the sample at\n\t    sample/soap/calc/server.fcgi.  (almost same as server.cgi but has\n\t    fcgi handler at the bottom.)\n\n\t  * allow to return a SOAPFault object to respond customized SOAP fault.\n\n\t  * added the interface 'generate_explicit_type' for server side\n\t    (CGIStub, HTTPServer).  call 'self.generate_explicit_type = true'\n\t    if you want to return simplified XML even if it's rpc/encoded\n\t    service.\n\n\t  == WSDL ==\n\n\t  === WSDL definition ===\n\n\t  * improved XML Schema support such as extension, restriction,\n\t    simpleType, complexType + simpleContent, ref, length, import,\n\t    include.\n\n\t  * reduced \"unknown element/attribute\" warnings (warn only 1 time for\n\t    each QName).\n\n\t  * importing XSD file at schemaLocation with xsd:import.\n\n\t  === code generation from WSDL ===\n\n\t  * generator crashed when there's '-' in defined element/attribute\n\t    name.\n\n\t  * added ApacheMap WSDL definition.\n\n\t* sample/{soap,wsdl}: removed.\n\nSun May 22 19:11:35 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/ssl.rb (OpenSSL::SSL::SSLServer#intialize):\n\t  should initialize session id context. [ruby-core:4663]\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_setup): add session id support.\n\nSat May 21 10:24:21 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: tds files were not deleted when DESTDIR\n\t  included '\\' path delimiter. [ruby-dev:26193]\n\nThu May 19 19:04:29 2005  speakillof  <speakillof@yahoo.co.jp>\n\n\t* lib/rexml/encodings/SHIFT-JIS.rb: encoding and decoding were\n\t  swapped. [ruby-core:4772]\n\nWed May 18 23:42:25 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* error.c (exc_exception): reverted to call Exception#initialize\n\t  directly.  fixed: [ruby-dev:26177]\n\nWed May 18 23:39:09 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (glob_helper): get rid of using String.  [ruby-dev:26180]\n\n\t* dir.c (push_braces): should skip balanced braces.\n\n\t* eval.c (ruby_options), win32/win32.c (NtInitialize): move argument\n\t  intialization back.  [ruby-dev:26180]\n\nTue May 17 15:31:31 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpserver.rb (WEBrick::HTTPServer#run): should\n\t  break the loop if the socket reached to EOF. [ruby-talk:142285]\n\nTue May 17 11:52:18 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (unixtime_to_filetime): use localtime() instead of\n\t  gmtime() when using FileLocalTimeToFileTime().\n\nMon May 16 22:28:43 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.h, {bcc32,win32,wince}/Makefile.sub: moved rb_[ugp]id_t\n\t  to get rid of redefinition warnings on mingw.\n\n\t* class.c (rb_class_init_copy): singleton class is disallowed to copy,\n\t  from its definition.  fixed: [ruby-talk:142749]\n\nMon May 16 08:52:29 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.{h,c}: define rb_[pgu]id_t.\n\nMon May 16 00:21:02 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#unlink): use SystemCallError instead of\n\t  Errno::EISDIR because EISDIR is not portable.\n\t  [ruby-core:5001]\n\nSun May 15 22:11:33 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRbObject#method_missing): use raise(exception).\n\t  [ruby-dev:26164]\n\nSun May 15 18:56:35 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in, ruby.h: define rb_[pgu]id_t macros instead of typedefs\n\t  to get rid of types which might not be defined yet.  [ruby-dev:26165]\n\nSun May 15 14:35:46 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#unlink): unlink a symlink to a directory\n\t  was failed.  [ruby-core:4992]\n\nSun May 15 09:57:30 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/win32.c (unixtime_to_filetime): deal with DST.\n\t  [ruby-talk:141817]\n\nSat May 14 23:59:11 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* error.c (exc_exception, {exit,name_err,syserr}_initialize): call\n\t  Execption#initialize.  fixed: [ruby-talk:142593]\n\nSat May 14 23:57:26 2005  Erik Huelsmann  <ehuels@gmail.com>\n\n\t* configure.in: Check for the availability of pid_t, gid_t and uid_t and\n\t  remove AC_TYPE_UID_T.  fixed: [ruby-core:04745]\n\n\t* defines.h: Remove pid_t typedef.\n\n\t* ruby.h: Define rb_pid_t, rb_gid_t and rb_uid_t in accordance with\n\t the available system types.\n\n\t* process.c: Change instances of pid_t and gid_t to their rb_*\n\t counterparts.\n\n\t* ext/pty/pty.c: Change pid_t to rb_pid_t.\n\n\t* vms/config.h: Define HAVE_{P,G,U}ID_T to 1.\n\n\t* win32/Makefile.sub: Remove #define for {g,u}id_t.\n\n\t* win32/win32.c: Change pid_t to rb_pid_t.\n\n\t* wince/Makefile.sub: Remove #define for {g,u}id_t.\n\n\t* wince/sys/types.h: Remove definitions of {p,g,u}id_t.\n\nFri May 13 23:44:22 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: keep srcdir unexpanded.\n\n\t* lib/mkmf.rb (create_makefile): quote topdir and hdrdir if necessary.\n\t  fixed: [ruby-core:04932]\n\n\t* lib/mkmf.rb (configuration), {bcc32,win32,wince}/Makefile.sub: make\n\t  also INSTALL_PROG and INSTALL_DATA system dependent.\n\t  fixed: [ruby-core:04931]\n\nFri May 13 17:54:39 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* variable.c (generic_ivar_get): rb_attr_get should not warn.\n\t  [ruby-dev:26010]\n\nFri May 13 12:28:43 2005  Daniel Berger  <djberge@qwest.com>\n\n\t* array.c (rb_ary_select): can remove argc check. [ruby-core:4911]\n\n\t* test/ruby/test_array.rb: add test for find_all.\n\nFri May 13 11:29:00 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (unknown_node): add volatile directive to prototype.\n\nThu May 12 17:08:48 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_io_eof, remain_size, read_all, io_read, appendline)\n\t  (swallow, rb_io_each_byte, rb_io_getc): revert previous change.\n\n\t* io.c (rb_io_eof, io_fread, appendline, swallow, rb_io_each_byte)\n\t  (rb_io_getc, rb_getc): call clearerr before getc to avoid\n\t  stdio incompatibility.\n\nThu May 12 16:52:20 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/rdoc/parsers/parse_c.rb: more readability for mixing\n\t  progress \"c...\" and warning message.\n\nThu May 12 16:31:00 2005  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c: follow nkf 2.0.5\n\nThu May 12 16:15:01 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_io_eof, remain_size, read_all, io_read, appendline)\n\t  (swallow, rb_io_each_byte, rb_io_getc): don't rely EOF flag.\n\t  [ruby-talk:141527]\n\nThu May 12 15:56:20 2005  Tilman Sauerbeck  <tilman@code-monkey.de>\n\n\t* lib/rdoc/parsers/parse_c.rb: show parsing progress for C files.\n\t  [ruby-core:4341]\n\nThu May 12 13:47:56 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* test/drb/test_drb{ssl,unix}.rb: can test drb\n\t  before install. (backported from HEAD) [ruby-dev:26146]\n\nThu May 12 09:53:57 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* version.c (ruby_show_version): flush for non-tty stdout.\n\nThu May 12 09:07:07 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* test/ruby/envutil.rb, test/drb/drbtest.rb: can test drb\n\t  before install. (backported from HEAD) [ruby-Bugs-1672]\n\nThu May 12 01:23:55 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval), parse.y (arg): reduce fixnum range literal at\n\t  parser.  fixed: [ruby-dev:26113]\n\n\t* eval.c (unknown_node): ignore broken NODE to get rid of accessing\n\t  possibly inaccessible address.  fixed: [ruby-dev:26122]\n\t  should emit more useful information like [ruby-dev:26126], though.\n\nWed May 11 16:20:01 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb: new methods WEBrick::CGI#[], WEBrick::CGI#logger\n\t  and WEBrick::CGI#config. (backported from HEAD)\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils.escape_path): should\n\t  not use String#split(\"/\"). (backported from HEAD)\n\nWed May 11 15:58:39 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (break_jump): break should not cross functions.\n\t  [ruby-list:40818]\n\nWed May 11 10:39:37 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/tempfile.rb (Tempfile#unlink): fixed typo.\n\nWed May 11 01:03:36 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (TMP_ALLOC): use macro NEW_NODE() to get rid of warnings on\n\t  platforms which have no alloca().  fixed: [ruby-talk:141301]\n\nSun May  8 23:17:47 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/timer.rb: fix typo.\n\nSun May  8 16:52:56 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/profiler.rb: fixed \"undefined method `[]' for nil:NilClass\"\n\t  [ruby-core:4775] [ruby-talk:140401] [ruby-dev:26118]\n\nSat May  7 22:58:00 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (have_var): no libs argument is given.\n\nSun May  1 09:58:11 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ruby.c (process_sflag): replace '-' in variable names with '_'.\n\t  [ruby-dev:26107]\n\n\t* ruby.c (set_arg0): use also environment variable space for setting\n\t  $0.  [ruby-core:04774]\n\nWed Apr 27 23:42:22 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/Makefile.sub (OPTFLAGS): default global optimization to\n\t  disabled only for VC++6.\n\nTue Apr 26 22:58:00 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke_core): call Tcl's \"::unknown\"\n\t  command when can't get information of target command.\n\nMon Apr 25 01:18:43 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* regex.c: declare rb_warn to have variadic argument.  [ruby-core:4751]\n\nSat Apr 23 19:45:59 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_RubyExitCommand): exit with status code\n\t  via TclTkIp#_eval didn't work. [ruby-talk:139390]\n\nFri Apr 22 16:41:50 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_set_exc_message): fixed memory leak.\n\n\t* ext/tcltklib/tcltklib.c: eTkCallbackReturn was not initialized.\n\nThu Apr 21 00:07:50 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): support platforms have file separator\n\t  other than /.\n\n\t* {bcc32,win32,wince}/Makefile.sub (BUILD_FILE_SEPARATOR): separator\n\t  of building platform.\n\n\t* {bcc32,win32,wince}/Makefile.sub (CP, INSTALL): use COPY command.\n\nWed Apr 20 23:22:39 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in, common.mk: miniruby depens on MINIOBJS.\n\n\t* dmydln.c (dln_load): dummy function to raise LoadError.\n\n\t* cygwin/GNUmakefile.in, {bcc32,win32,wince}/Makefile.sub: miniruby\n\t  can't load extensions on Windows.\n\nWed Apr 20 23:01:35 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* win32/ifchange.bat: delete testing files.\n\nWed Apr 20 07:27:18 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/configure.bat, {bcc32,win32,wince}/setup.mak:\n\t  add extout option.\n\n\t* bcc32/setup.mak: make configuration variables overridable.\n\nWed Apr 20 04:15:27 2005  Keiju Ishitsuka  <keiju@ruby-lang.org>\n\n\t* lib/irb.rb lib/irb/* doc/irb: IRB 0.9.5\n\nTue Apr 19 23:37:09 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ftools.rb (File.safe_unlink): do not modify a symlinked file.\n\nTue Apr 19 00:06:20 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: expand path for ext/**/extconf.rb.\n\nMon Apr 18 11:25:14 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/zlib/zlib.c (zstream_run): fixed SEGV. [ruby-core:4712]\n\nSun Apr 17 23:57:49 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake, parse_args): do not expand destdir.\n\n\t* ext/extmk.rb (relative_from): treat mere drive letter as an absolute\n\t  path.\n\nSat Apr 16 17:01:16 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* sample/rss/tdiary_plugin/rss-recent.rb (rss_recent_cache_rss):\n\t  use the first date information of items as site date information\n\t  if channel doesn't have date information.\n\nSat Apr 16 15:27:03 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (RUBY_PROG_INSTALL): not add -p option to INSTALL.\n\t  files need timestamps to be kept are only ar-archive on a few\n\t  platforms, and be installed by instruby.rb but not INSTALL.\n\t  fixed: [ruby-core:04721]\n\n\t* mkconfig.rb: purge autoconf value variables.\n\nSat Apr 16 10:36:01 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: quick hack... prepend DESTDIR.\n\t  still have restriction on DESTDIR (\"\", \"/\", \"e:\")\n\nSat Apr 16 03:59:42 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: check for OPENSSL_cleanse.\n\n\t* ext/openssl/openssl_missing.h: ditto.\n\nThu Apr 14 19:18:30 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (remove_file): ignore exceptions caused by\n\t  chmod.\n\n\t* lib/fileutils.rb (remove_dir): try to get rights to rmdir.\n\t  [ruby-Bugs:1502] (2 items backportted from HEAD, rev 1.53-54)\n\nThu Apr 14 16:57:40 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bcc32/Makefile.sub: failed to remove debug information files.\n\t  fixed: [ruby-dev:26034]\n\nWed Apr 13 23:40:21 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (RSS::VERSION): 0.1.3 -> 0.1.4.\n\n\t* lib/rss/rss.rb (RSS::Element#converter): fixed converter\n\t  transmission bug.\n\nWed Apr 13 21:20:35 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (mingw32): extract msvcr*.dll from objdump result.\n\nWed Apr 13 20:24:30 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (mingw32): use actual runtime DLL name as ruby DLL\n\t  name and default load path.\n\n\t* win32/Makefile.sub, win32/setup.mak: ditto.\n\nTue Apr 12 15:33:09 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_finalize): better modification than the\n\t  previous commit [ruby-dev:26029].\n\nTue Apr 12 12:38:06 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_finalize): fix SEGV when Tcl_GlobalEval()\n\t  modifies the argument string to eval.\n\nTue Apr 12 02:21:55 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_finalize): add existence check of\n\t  Tcl commands before calling Tcl_GlobalEval().\n\nMon Apr 11 23:47:21 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: [druby-ja:123] fix: When reference of my object is\n\t  loaded, the object is tainted.\n\n\t* test/drb/test_drb.rb: ditto.\n\nMon Apr 11 22:18:23 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dir.c, file.c (lstat): avoid warnings for mingw.\n\nMon Apr 11 20:11:06 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_finalize): adhoc patch to avoid SEGV\n\t  when exit on Tcl/Tk8.3.x.\n\nMon Apr 11 15:26:25 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb (configuration): shouldn't output hdrdir twice.\n\nMon Apr 11 12:09:05 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* {bcc32,win32,wince}/Makefile.sub: ri data was not installed\n\t  into correct path. [ruby-dev:26011]\n\n\t* bcc32/Makefile.sub: defaulted install-nodoc. [ruby-dev:26011]\n\nSun Apr 10 10:12:42 2005  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c(ole_invoke): retry after converting Qnil\n\t  to VT_EMPTY.\n\n\t* ext/win32ole/win32ole/tests/testWIN32OLE.rb: correct error\n\t  message string \"Unknown\" => \"unknown\".\n\nSat Apr  9 18:20:31 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/image.rb: support to create TkImage object without\n\t  creating a new image object on Tk.\n\n\t* ext/tk/lib/tk/menu.rb: use TkCommandNames on create_self()\n\n\t* ext/tk/lib/tk/root.rb: TkRoot.to_eval() returns '.'.\n\n\t* ext/tk/lib/tk/text.rb: add methods to create a TkText::IndexString\n\t  from (x, y) coords.\n\n\t* ext/tk/lib/tkextlib/tile/: add demo and update support status.\n\nSat Apr  9 14:42:29 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* sample/rss/tdiary_plugin/rss-recent.rb: supported configuration\n\t  via Web browser.\n\nSat Apr  9 11:59:57 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss: backoported from HEAD.\n\n\t* lib/rss: refactored.\n\t  - gave a name to 'x'.\n\t  - undef_method -> remove_method for avoiding a warning in ruby 1.6.\n\n\t* lib/rss/parser.rb: @@setter -> @@setters.\n\n\t* lib/rss/parser.rb\n\t  (RSS::BaseListener.register_uri)\n\t  (RSS::BaseListener.uri_registered?)\n\t  (RSS::BaseListener.install_get_text_element):\n\t  swapped the first argument and the second argument.\n\n\t* lib/rss/taxonomy.rb: swapped the first argument and the second\n\t  argument for RSS::BaseListener.install_get_text_element.\n\t* lib/rss/image.rb: ditto.\n\t* lib/rss/syndication.rb: ditto.\n\t* lib/rss/dublincore.rb: ditto.\n\t* lib/rss/parser.rb: ditto.\n\t* lib/rss/1.0.rb: ditto.\n\t* lib/rss/2.0.rb: ditto.\n\t* lib/rss/0.9.rb: ditto.\n\t* lib/rss/content.rb: ditto.\n\n\t* lib/rss/parser.rb\n\t  (RSS::BaseListener.install_setter)\n\t  (RSS::BaseListener.register_uri): changed fallback way.\n\n\t* lib/rss/parser.rb: added class name registry for complex model\n\t  elements. (ex. have childlen elements, have some attributes and\n\t  a child element and so on.)\n\n\t* lib/rss/dublincore.rb: supported multiple Dublin Core items.\n\t* lib/rss/maker/dublincore.rb: ditto.\n\n\t* lib/rss/maker/image.rb: supproted new Dublin Core API.\n\n\t* lib/rss/maker/base.rb: added default current_element implementation.\n\n\t* lib/rss/trackback.rb (RSS::TrackBackUtils.new_with_value_if_need):\n\t  moved to RSS::Utils.\n\n\t* lib/rss/utils.rb (RSS::Utils.new_with_value_if_need):\n\t  moved from RSS::TrackBackUtils.\n\n\t* lib/rss/maker/image.rb: fixed invalid argument of\n\t  add_need_initialize_variable bug.\n\t* lib/rss/maker/trackback.rb: ditto.\n\n\t* lib/rss/rss.rb (Hash#merge): added for ruby 1.6.\n\n\t* lib/rss/rss.rb (RSS::BaseModel.date_writer): changed to accept nil\n\t  for date value.\n\n\t* test/test_dublincore.rb: added tests for plural accessor and\n\t  multiple Dublin Core items.\n\n\t* test/test_setup_maker_1.0.rb: fixed swapped actual and expected\n\t  values.\n\n\t* test/rss/rss-assertions.rb (assert_multiple_dublin_core): added\n\t  an assertion for testing multiple Dublin Core items.\n\n\t* test/rss/test_maker_dc.rb (test_rss10_multiple): added a test\n\t  for making multiple Dublin Core items.\n\n\t* test/rss/test_maker_dc.rb (test_date): added a test for #date=\n\t  and #dc_date=.\n\n\t* sample/rss/tdiary_plugin/rss-recent.rb:\n\t  new option: @options['rss-recent.use-image-link']:\n\t  use image as link instread of text if available.\n\n\t* sample/rss/tdiary_plugin/rss-recent.rb (RSS_RECENT_VERSION):\n\t  0.0.5 -> 0.0.6.\n\nFri Apr  8 20:17:48 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): hdrdir needs to be defined also in\n\t  Config::CONFIG.\n\n\t* lib/mkmf.rb (configuration, create_makefile): get rid of recursive\n\t  macro reference.\n\nFri Apr  8 18:26:56 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c: add callbacks to OpenSSL::SSL::SSLContexts.\n\t  - SSLContext#client_cert_cb=(aProc). it is called when a client\n\t    certificate is requested by a server and no certificate was not\n\t    set for the SSLContext. it must return an Array which includes\n\t    OpenSSL::X509::Certificate and OpenSSL::PKey::RSA/DSA objects.\n\t  - SSLContext#tmp_dh_callback=(aProc). it is called in key\n\t    exchange with DH algorithm. it must return an OpenSSL::PKey::DH\n\t    object.\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_set_ciphers): ignore the\n\t  argument if it's nil.\n\n\t* ext/openssl/ossl_pkey.c\n\t  (GetPrivPKeyPtr, ossl_pkey_sign): should call rb_funcall first.\n\t  (DupPrivPKeyPtr): new function.\n\n\t* ext/openssl/ossl_pkey_dh.c: add default DH parameters.\n\n\t* ext/openssl/ossl_pkey.h: ditto.\n\nFri Apr  8 01:55:20 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/demos-{en,jp}/goldberg.rb: reduced window size.\n\t  [ruby-dev:25992]\n\nThu Apr  7 23:58:40 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): keep directory names in Makefile as macros.\n\n\t* lib/mkmf.rb (configuration, create_makefile): ditto.\n\n\t* lib/mkmf.rb (CXX_EXT): separate C++ extensions.\n\nThu Apr  7 17:43:25 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* eval.c (rb_call0): \"return\" event hook should be always executed\n\t  if event_hooks is set.  fixed: [ruby-core:04662]\n\t  (backported from HEAD)\n\nMon Apr  4 23:17:52 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb (TkComm#array2tk_list): accept enc-mode argument to\n\t  decide whether convert encoding of each element or not.\n\n\t* ext/tk/lib/tk/variable.rb (TkVariable#value=): fail to convert the\n\t  encoding of array elements when assign an array to an TkVariable\n\t  object.\n\nMon Apr  4 10:26:48 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tk/lib/tk/dialog.rb: fixed typo.\n\nSun Apr  3 17:16:33 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.{h,c} (rb_w32_fdopen): avoid warning on bcc32.\n\t  (backported from HEAD)\n\nSat Apr  2 23:38:54 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (CP, INSTALL): get rid of less portable options.\n\n\t* lib/mkmf.rb (configuration, create_makefile): correct configuration\n\t  variable.\n\n\t* {bcc32,win32,wince}/{Makefile.sub,setup.mak}: leave prefix empty in\n\t  config.status for backward compatibility.  fixed: [ruby-core:04649]\n\n\t* lib/mkmf.rb (create_makefile): ensure library directories get made\n\t  before copying libraries there.\n\nSat Apr  2 16:59:46 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: forgot to update RELEASE_DATE\n\n\t* ext/tk/lib/tk/variable.rb: fix namespace trouble when autoloading\n\n\t* ext/tk/lib/tk/palette.rb: define Tcl variable 'tkPalette' as global\n\n\t* ext/tk/lib/tk/dialog.rb: use array2tk_list method when calling\n\t  Tk.ip_eval.\n\n\t* ext/tk/lib/tk/autoload.rb: add autoload entry 'TkDialogObj' and\n\t  'TkWarningObj'\n\nSat Apr  2 02:19:11 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb (TkWindow.initialize): accept 'without_creating'\n\t  option without 'widgetname' option to allow creating a widget object\n\t  which is used as an argument of Tcl/Tk's widget allocation commands.\n\n\t* ext/tk/lib/tk/image.rb (TkImage.initialize): accept 'imagename'\n\t  option to create a image object by the given name.\n\nThu Mar 31 22:23:51 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (SRC_EXT): exclude just case different suffixes on case\n\t  insensitive file system platforms.\n\n\t* README.EXT, README.EXT.ja (Appendix C): utility functions.\n\nThu Mar 31 14:15:44 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_engine.c (ossl_engine_s_load): should return\n\t  value. [ruby-dev:25971]\n\nThu Mar 31 08:25:50 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* common.mk (RUBYOPT): clear for the environment RubyGems installed.\n\n\t* common.mk (clean-local): keep $(PREP) files till distclean.\n\n\t* common.mk (check): do all tests.\n\nThu Mar 31 06:00:20 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_engine.c (ossl_engine_s_load): should not raise\n\t  error even if the specified engine could not be loaded. (Dynamic\n\t  engines don't have fixed name to load.)\n\nThu Mar 31 00:18:27 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/ifchange.bat, win32/rm.bat: backported from HEAD.\n\nWed Mar 30 23:44:50 2005  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* Makefile.in, */Makefile.sub, */configure.bat,\n\t  cygwin/GNUmakefile.in, common.mk, configure.in, ext/extmk.rb,\n\t  lib/mkmf.rb, instruby.rb, runruby.rb: backport extout.\n\t  [ruby-dev:25963]\n\nWed Mar 30 17:41:48 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: add TclTkIp#_create_console() method to\n\t  create a Tcl/Tk's console window.\n\n\t* ext/tk/lib/multi-tk.rb: support TclTkIp#_create_console() method.\n\n\t* ext/tk/lib/remote-tk.rb: ditto.\n\n\t* ext/tk/lib/tk/console.rb: ditto.\n\n\t* ext/tk/lib/tk.rb: update RELEASE_DATE\n\n\t* ext/tk/sample/demo-*/check2.rb: use 'return' in the Proc object.\n\n\t* ext/tk/sample/tkextlib/**: ditto.\n\nTue Mar 29 22:11:56 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/rinda/test_rinda.rb: use DRbObject.new_with instead of reinit.\n\t  [ruby-dev:25961]\n\nMon Mar 28 23:40:40 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: move method DRbObject#reinit to DRbObject.new_with.\n\t  extract method DRbObject.prepare_backtrace. add DRb.regist_server,\n\t  remove_server, fetch_server. change server in thread variable if\n\t  in-proc server. [druby-ja:113]\n\n\t* lib/drb/gw.rb: ditto.\n\nMon Mar 28 20:43:34 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/syck/rubyext.c: get rid of warnings caused by a bug of VC.\n\nMon Mar 28 08:39:49 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_create): Iconv::Failure requires 3\n\t  arguments.  (pointed out by NaHi)\n\nSat Mar 26 22:51:33 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb (_callback_entry_class?): add for checking whether\n\t  a class is available for a callback entry.\n\n\t* ext/tk/lib/tk.rb (after_cancel): add Tk.after_cancel(afterID) method.\n\n\t* ext/tk/lib/tk.rb (array2tk_list): change from private module method\n\t  of TkComm to public module method.\n\n\t* ext/tk/lib/tk.rb (cget): add check that slot argument is not\n\t  empty string.\n\n\t* ext/tk/lib/tk.rb (configinfo): ditto.\n\n\t* ext/tk/lib/tk/itemconfig.rb (itemcget): add check that slot argument\n\t  is not empty string.\n\n\t* ext/tk/lib/tk/itemconfig.rb (itemconfiginfo): ditto.\n\n\t* ext/tk/lib/tk/entry.rb: add TkEntry#icursor and icursor= (alias of\n\t  cursor and cursor= method).\n\n\t* ext/tk/lib/tk/font.rb: improve font treatment when the font name is\n\t  empty string.\n\n\t* ext/tk/lib/tk/variable.rb: add :variable, :window and :procedure\n\t  type.\n\n\t* ext/tk/lib/tk/variable.rb: improve treatment of array-type\n\t  tkvariable.\n\n\t* ext/tk/lib/tkextlib/blt.rb: add commands for zooming.\n\n\t* ext/tk/lib/tkextlib/blt/*: bug fix.\n\n\t* ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix and add methods\n\t  to call TreeCtrl commands for bindings.\n\n\t* ext/tk/sample/tkextlib/blt/*: new sample scripts.\n\n\t* ext/tk/sample/tkextlib/treectrl/*: ditto.\n\nFri Mar 25 10:53:16 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (WIN32_LEAN_AND_MEAN): removed because a lot of\n\t  troubles.  [ruby-list:40721]\n\nThu Mar 24 23:10:44 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (macro_defined?): try to compile for an old compiler\n\t  which doesn't bail out at #error directive.  [ruby-dev:25818]\n\n\t* lib/mkmf.rb (check_sizeof): refine logging messages.\n\nThu Mar 24 03:57:48 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/utils.rb (WEBrick::Utils.create_listeners):\n\t  - should raise ArgumentError if no port is specified.\n\t  - even if the specified port is 0, all TCPServers should be\n\t  initialized with the port given to the first one.\n\n\t* lib/webrick/server.rb (WEBrick::GenericServer#initialize): if :Port\n\t  parameter is 0, it should be updated with the port number which\n\t  actually listened.\n\nWed Mar 23 00:35:10 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* test/ruby/test_settracefunc.rb (test_event): added tests for\n\t  \"class\" and \"end\" and \"raise\".\n\nTue Mar 22 22:40:18 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* eval.c (rb_call0): check event_hooks instead of trace_func.\n\nTue Mar 22 17:30:44 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* eval.c (rb_add_event_hook): new function to add a hook function for\n\t  interpreter events. (backported form HEAD)\n\nSun Mar 20 22:51:19 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (mkmf_failed): check if Makefile is created without\n\t  create_makefile.\n\nSat Mar 19 23:48:10 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-expr-beg): returned true always.\n\t  fixed: [ruby-list:40683]\n\nSat Mar 19 00:41:02 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/font.rb: add some TkFont class methods to get font\n\t  information without creating a TkFont object.\n\n\t* ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix and define some\n\t  classes for components of Tk::TreeCtrl\n\nThu Mar 17 17:42:13 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (make_struct): allow non local-id field\n\t  names. [ruby-core:04575]\n\n\t* struct.c (inspect_struct): ditto.\n\nWed Mar 16 23:36:02 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* eval.c (rb_call0): call_cfunc() should be protected.\n\n\t* test/ruby/test_settracefunc.rb: added test for c-return.\n\nWed Mar 16 22:20:25 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* object.c (str_to_id): fixed typo.\n\nWed Mar 16 18:08:32 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): reorganize \"return\" event post.\n\nTue Mar 15 23:49:19 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (Init_iconv): InvalidEncoding also should include\n\t  Iconv::Failure.\n\nTue Mar 15 16:38:11 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c (ary2list): give wrong arguments to hash2kv()\n\nMon Mar 14 19:39:33 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/timer.rb (TkTimer): forgot to clear @return_value\n\t  when restarting\n\n\t* ext/tk/lib/tk/sample/cd_timer.rb: new sample of TkRTTimer\n\nMon Mar 14 12:21:03 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/timer.rb (TkRTTimer): forgot to reset the callback\n\t  time. So, 'continue' do all callbacks between 'stop' and 'continue'.\n\nMon Mar 14 08:14:56 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (str_to_id): warn for NUL containing strings.\n\nMon Mar 14 00:13:49 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/timer.rb (TkRTTimer): correct calculation of offset\n\t  value. get a little better accuracy.\n\n\t* ext/tk/sample/demos-en/widget: use a binding with no local variables\n\t  when eval a sample script.\n\n\t* ext/tk/sample/demos-en/bind.rb: ditto.\n\n\t* ext/tk/sample/demos-en/tcolor: ditto.\n\n\t* ext/tk/sample/demos-jp/widget: ditto.\n\n\t* ext/tk/sample/demos-jp/bind.rb: ditto.\n\n\t* ext/tk/sample/demos-jp/tcolor: ditto.\n\nSun Mar 13 10:04:17 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/rinda/test_rinda.rb: remove test_gc. [ruby-dev:25871]\n\nThu Mar 10 19:12:06 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_eventloop_ensure): mis-delete a timer\n\t  handler when exit from a recursive called eventloop\n\n\t* ext/tk/lib/tk/timer.rb: new TkRTTimer class, which can works for a\n\t  realtime operation\n\n\t* ext/tk/sample/tkrttimer.rb: sample of TkRTTimer class\n\n\t* ext/tk/lib/tk/textmark.rb: move  TkTextMark#+ and TkTextMark#- to\n\t  TkText::IndexModMethods\n\n\t* ext/tk/lib/tk/text.rb: improve TkTextMark#+ and TkTextMark#-, and\n\t  add them to TkText::IndexModMethods module\n\n\t* ext/tk/sample/tktextio.rb: add test part of \"seek by text index\n\t  modifiers\"\n\nThu Mar 10 08:10:11 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (make_regexp): need to free internal regexp structure when\n\t  compilation fails.  [ruby-talk:133228]\n\nWed Mar  9 20:25:58 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_start_ssl, ossl_ssl_write): call\n\t  rb_sys_fail if errno isn't 0. [ruby-dev:25831]\n\n\t* ext/openssl/lib/openssl/cipher.rb: fix typo. [ruby-dev:24285]\n\nWed Mar  9 15:46:35 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/server.rb (WEBrick::GenericServer#start): should\n\t  restore @token if accept failure. suggested by Dominique Brezinski.\n\t  [ruby-core:04518]\n\nWed Mar  9 13:37:57 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tktextio.rb: fix bug of handling 'end' position.\n\t  support initial text, overwrite setting and pos_gravity control.\n\nTue Mar  8 18:16:55 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tktextio.rb: New sample script. TkTextIO class in this\n\t  sample supports to use a text widget as if it is a I/O stream (such\n\t  like as StringIO class).\n\nTue Mar  8 13:54:40 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c: workaround for some of 4.4BSD-Lite derived OSs.\n\nTue Mar  8 12:36:17 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c: document from Sam Roberts\n\t  <sroberts@uniserve.com> for getsockopt and setsockopt is merged.\n\t  [ruby-doc:824]\n\nTue Mar  8 01:27:00 2005  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c: follow nkf 1.66\n\t  fixed: [ruby-dev:25828]\n\nMon Mar  7 21:35:02 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* sample/webrick/httpsd.rb: fix typo in comment. suggested by\n\t  Kazuhiko Shiozaki.\n\nMon Mar  7 14:55:43 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): should not push unique number if a block is\n\t  not an orphan.  [ruby-dev:25808]\n\nWed Feb 16 02:55:21 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_start_ssl, ossl_ssl_read,\n\t  ossl_ssl_write):\n\t  - need to set errno on Win32 platform.\n\t  - should call rb_sys_fail instead of rasing SSLError if\n\t    SSL_ERROR_SYSCALL occured.\n\t  - should wait for that the underlying IO become readable or\n\t    writable if the error was SSL_ERROR_WANT_READ or\n\t    SSL_ERROR_WANT_WRITE. [ruby-dev:25795]\n\n\t* ext/openssl/lib/openssl/buffering.rb\n\t  (Buffering#initialize): should set @eof and @rbuffer.\n\t  (Buffering#fill_rbuff): should rescue Errno::EAGAIN.\n\t  (Buffering#consume_rbuf): pointless eof flag resetting is deleted.\n\t  (Buffering#read): should return an empty string if the specified\n\t  size is zero.\n\t  (Buffering#readpartial): new method.\n\t  (Buffering#readline): fix typo.\n\t  (Buffering#getc): return the first character of string correctly.\n\t  (Buffering#each): fix typo.  suggested by Brian Ollenberger.\n\t  (Buffering#readchar): fix typo.\n\t  (Buffering#eof?): should read again it the input buffer is empty.\n\t  (Buffering#do_write): should rescue Errno::EAGAIN.\n\t  (Buffering#puts): use \"\\n\" as the output field separator.\n\n\t* ext/openssl/lib/openssl/ssl.rb: set non-blocking flag to the\n\t  underlying IO.\n\n\t* ext/openssl/extconf.rb: get rid of GNUmakefile generation.\n\n\t* text/openssl/test_pair.rb: test for IO like methods.\n\n\t* test/ruby/ut_eof.rb: test about empty file.\n\nMon Mar  7 10:22:06 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/un.rb: should use OptionParser. (backported form HEAD)\n\nMon Mar  7 09:18:42 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cmp_m): should not return false but nil.\n\t  fixed: [ruby-dev:25811]\n\nMon Mar  7 01:22:14 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c: remove the some codes which depend on the\n\t  difference between Ruby1.8 and 1.9, because st.c on Ruby1.9\n\t  was changed.\n\nMon Mar  7 00:01:04 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fail to call TclTkLib.mainloop when $SAFE==4\n\nSun Mar  6 16:41:33 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: HTTPHeader holds its header fields as an array\n\t  (backport from CVS HEAD rev 1.112-1.123). [ruby-list:40629]\n\n\t* test/net/http/test_httpheader.rb: new file.\n\nSun Mar  6 11:47:10 2005  Sam Roberts  <sroberts@uniserve.com>\n\n\t* lib/pp.rb: rdoced.  [ruby-core:4490]\n\nSun Mar  6 11:36:37 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (File::Stat#pretty_print): Etc.getpwuid and Etc.getgrgid\n\t  may return nil.  [ruby-talk:129826]\n\t  reported by Daniel Berger.\n\nSat Mar  5 18:06:21 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (fnmatch): removed unnecessary code. (ruby_1_8 didn't have\n\t  String#clear, so [ruby-dev:24749] didn't affect it)\n\n\t* win32/win32.c (NtInitialize): ditto. (by numeric.c 1.101.2.14)\n\nSat Mar  5 16:29:26 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: freeze callback-entry objects\n\n\t* ext/tk/lib/tkextlib/tile.rb: support tile-0.6\n\nFri Mar  4 19:39:28 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser#do_includes): replace\n\t  also locally defined modules.\n\n\t* ext/iconv/iconv.c: backport Iconv::InvalidEncoding from CVS HEAD.\n\n\t* ext/strscan/strscan.c: moved misplaced rdoc.\n\nFri Mar  4 15:58:12 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi-lib.rb: add deprecation warning. [ruby-dev:25499]\n\t  getopts.rb, parsearg.rb, importenv.rb as well.\n\nFri Mar  4 11:17:06 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_rbUpdateCommand): get rid of\n\t  warnings with Tcl/Tk 8.3 or former (backport from CVS_HEAD).\n\n\t* ext/tcltklib/tcltklib.c (ip_rb_threadUpdateCommand): ditto.\n\nFri Mar  4 10:15:30 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/set.rb (SortedSet::setup): a hack to shut up warning.\n\t  [ruby-talk:132866]\n\nFri Mar  4 07:07:00 2005  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c: follow nkf 1.63\n\nThu Mar  3 23:49:00 2005  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c: follow nkf 1.62\n\nThu Mar  3 11:49:51 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* sample/rss/tdiary_plugin/rss-recent.rb: added site information.\n\nWed Mar  2 19:53:07 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (parse_args): add DESTDIR only when not directed\n\t  already.  fixed: [ruby-dev:25781]\n\nWed Mar  2 17:14:18 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_eventloop_core): fix typo\n\nWed Mar  2 16:00:02 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: enforce thread-check and exception-handling\n\t  to avoid SEGV trouble.\n\t  [KNOWN BUG] When supports pthread and running multiple Tk\n\t  interpreters, an interrupt signal causes SEGV frequently. That\n\t  may be a trouble of Ruby's signal handler.\n\n\t* ext/tk/tkutil/tkutil.c; fix a bug on converting a SJIS string array\n\t  to a Tcl's list string.\n\n\t* ext/tk/tcltklib.c: wrap Tcl's original \"namespace\" command to\n\t  protect from namespace crash.\n\n\t* ext/tk/lib/multi-tk.rb: enforce exception-handling.\n\n\t* ext/tk/lib/multi-tk.rb: catch IRB_EXIT to work on irb.\n\n\t* ext/tk/lib/tk.rb: ditto.\n\n\t* ext/tk/tcltklib.c: add TclTkLib.mainloop_thread?\n\n\t* ext/tk/lib/multi-tk.rb: (bug fix) callback returns a value.\n\n\t* ext/tk/lib/tk/canvas.rb (delete): bug fix when multiple arguments.\n\n\t* ext/tk/lib/clock.rb: fix 'no method error'.\n\n\t* ext/tk/lib/clock.rb (self.clicks): accept a Symbol argument.\n\n\t* ext/tk/lib/variable.rb: be able to set default_value_type; :numeric,\n\t  :bool, :string, :symbol, :list, :numlist or nil (default; same to\n\t  :string). If set a type, TkVariable#value returns a value of the\n\t  type.\n\n\t* ext/tk/lib/tkextlib/tclx/tclx.rb: add Tk::TclX.signal to warn the\n\t  risk of using TclX extension's 'signal' command.\n\n\t* ext/tk/sample/irbtk.rb: irb with Ruby/Tk.\n\n\t* ext/tk/sample/demos-*/anilabel.rb: bug fix on 'show code'\n\n\t* ext/tk/sample/demos-*/aniwave.rb: new Ruby/Tk animation demo.\n\n\t* ext/tk/sample/demos-*/pendulum.rb: ditto.\n\n\t* ext/tk/sample/demos-*/goldberg.rb: ditto.\n\n\t* ext/tk/sample/demos-*/widget: add entries of animation demos.\n\nTue Mar  1 00:47:43 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/rinda/test_rinda.rb: backport from CVS_HEAD. use\n\t  MockClock.sleep instead of Kernel.sleep [ruby-dev:25387]\n\nTue Mar  1 00:34:24 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb (Rinda::TupleSpace): improved keeper thread.\n\n\t* test/rinda/test_rinda.rb: ditto.\n\nMon Feb 28 11:42:23 2005  Ian Macdonald  <ian@caliban.org>\n\n\t* exception error messages updated.  [ruby-core:04497]\n\nMon Feb 28 09:03:09 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (Init_socket): add bunch of Socket\n\t  constants.  Patch from Sam Roberts <sroberts@uniserve.com>.\n\t  [ruby-core:04409]\n\nWed Feb 23 15:04:32 2005  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (split_userinfo): should split \":pass\" into \"\"\n\t  and \"pass\".  [ruby-dev:25667]\n\nWed Feb 23 08:00:18 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_s_create): no need for negative argc check.\n\t  [ruby-core:04463]\n\n\t* array.c (rb_ary_unshift_m): ditto.\n\nWed Feb 23 01:57:46 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (initialize): handle certs correctly. Thanks,\n\t  NABEYA Kenichi. (backported from CVS HEAD)\n\nTue Feb 22 07:25:18 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (parser_yylex): identfier after dot must not be a variable.\n\nMon Feb 21 10:04:49 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/Makefile.sub (config.h): add fcntl.\n\n\t* win32/win32.[ch] (fcntl): ditto.\n\n\t* win32/win32.c (rb_w32_connect): support nonblocking mode.\n\n\t* ext/socket/socket.c (wait_connectable, ruby_connect): support\n\t  nonblocking connect on various platforms.\n\t  all changes are backported from CVS HEAD. [ruby-core:3154],\n\t  [ruby-core:4364].\n\nSun Feb 20 00:48:48 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::FTP#buffer_open): access mechanism\n\t  re-implemented according to RFC 1738.\n\t  reported by Guillaume Marcais.  [ruby-talk:131650]\n\nSat Feb 19 18:11:47 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRbObject#respond_to?): take two arguments.\n\t  [ruby-dev:25722]\n\n\t* test/drb/drbtest.rb: ditto.\n\nSat Feb 19 13:52:02 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: call OpenSSL::SSL::SSLSocket#post_connection_check\n\t  after connection is made.\n\nSat Feb 19 01:32:03 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/bigdecimal/lib/bigdecimal/newton.rb: resolved LoadError.\n\t  [ruby-dev:25685]\n\n\t* ext/bigdecimal/sample/linear.rb: ditto.\n\n\t* ext/bigdecimal/sample/nlsolve.rb: ditto.\n\n\t* ext/bigdecimal/lib/bigdecimal/nlsolve.rb: removed because this file\n\t  is sample script and same file exists in ext/bigdecimal/sample.\n\nFri Feb 18 17:14:00 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/xmlrpc/parser.rb (XMLRPC::FaultException): make it subclass\n\t  of StandardError class, not Exception class.  [ruby-core:04429]\n\nThu Feb 17 20:11:18 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/drb/drb.rb (DRbServer.default_safe_level): fix typo.\n\nThu Feb 17 20:11:18 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/digest/test_digest.rb: separate test case for each algorithms.\n\t  [ruby-dev:25412]\n\nThu Feb 17 11:54:00 2005  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/collector.rb (collect_file): now deletes paths added\n\t  to $LOAD_PATH instead of restoring it verbatim.\n\n\t* lib/test/unit/autorunner.rb (AutoRunner.run): fixed so that\n\t  'ruby -rtest/unit -rtest1 -rtest2 -e0' will use the objectspace\n\t  collector again. Also tried to simplify the calling convention.\n\n\t* test/runner.rb: adjusted for new AutoRunner semantics.\n\n\t* lib/test/unit.rb: ditto.\n\nThu Feb 17 04:21:47 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/open3.rb (Open3::popen3): $? should not be EXIT_FAILURE.\n\t  fixed: [ruby-core:04444]\n\nThu Feb 17 00:09:45 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/drb/ignore_test_drb.rb: move TestDRbReusePort to new file\n\t  [ruby-dev:25238]\n\n\t* test/drb/test_drb.rb: add method DRbService.ext_service, move\n\t  TestDRbReusePort to new file [ruby-dev:25238]\n\n\t* test/drb/test_drb.rb: ditto.\n\n\t* test/drb/test_drbssl.rb: ditto.\n\n\t* test/drb/test_drbunix.rb: ditto.\n\n\t* test/drb/ut_drb.rb: reduce sleep.\n\nThu Feb 17 00:02:27 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): NODE_IASGN is an assignment.\n\nWed Feb 16 23:34:30 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: add lazy stop_service. ([druby-ja:109])\n\n\t* lib/drb/extserv.rb: ditto.\n\nWed Feb 16 17:07:57 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c: Follow the change of st.c (st_foreach)\n\t  [ruby-list:40623].\n\t  Sometimes mis-convert from a Ruby's Array of SJIS Strings, which\n\t  includes some kind of SJIS characters, to a Tcl's UTF8 list string.\n\nMon Feb 14 23:58:17 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/parser.rb (RSS::ListenerMixin::tag_end):\n\t  fixed invalid namespace handling bug.\n\nMon Feb 14 13:12:38 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/ssl.rb\n\t (OpenSSL::SSL::SSLSocket#post_connection_check): new method.\n\nMon Feb 14 00:40:49 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (InvokeMethod.perform): pass DRb info to sub thread.\n\n\t* test/drb/test_drb.rb (test_01_safe1_safe4_eval): fix test case.\n\nSun Feb 13 23:13:46 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/dublincore.rb (RSS::DublicCoreModel#date{,=}): added\n\t  convenient methods.\n\n\t* lib/rss/0.9.rb (RSS::Rss::Channel#date{,=}): ditto.\n\n\t* lib/rss/2.0.rb (RSS::Rss::Channel::Item#date{,=}): ditto.\n\n\t* test/rss/: added tests for the convenient methods.\n\nSun Feb 13 22:43:03 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRbServer): add default_safe_level, safe_level,\n\t  config[:safe_level] ([druby-ja:120])\n\n\t* test/drb/test_drb.rb, ut_eval.rb, ut_safe1.rb: ditto.\n\nSun Feb 13 16:56:52 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI.start): should set reason-phrase\n\t  to the value of status header field. ([ruby-dev:40617])\n\nSun Feb 13 00:52:33 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb (ERB::Util.h, u): make it module_function.\n\nSat Feb 12 17:29:19 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI.open_loop): send authentication only for\n\t  the URI directly specified.\n\nSat Feb 12 15:07:23 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* random.c (rand_init): suppress warning.\n\nSat Feb 12 13:54:03 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: support https if the platform provides CA\n\t  certificates.\n\nSat Feb 12 06:18:28 2005  URABE Shyouhei  <shyouhei@ice.uec.ac.jp>\n\n\t* ext/etc/etc.c (Init_etc): sGroup needs HAVE_ST_GR_PASSWD check.\n\t  [ruby-dev:25675]\n\nFri Feb 11 17:40:42 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509store.c (ossl_x509store_set_default_paths):\n\t  new method OpenSSL::X509::Store#set_default_paths.\n\nFri Feb 11 11:33:53 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::HTTP#proxy_open): new option supported:\n\t  :http_basic_authentication.\n\t  suggested by Kent Sibilev.  [ruby-core:4392]\n\nFri Feb 11 06:30:07 2005  George Ogata  <g_ogata@optushome.com.au>\n\n\t* misc/ruby-mode.el: ignore parenthesis inside heredoc.\n\t  [ruby-core:04415]\n\nFri Feb 11 04:54:13 2005  Tilman Sauerbeck  <tilman@code-monkey.de>\n\n\t* lib/rdoc/generators/html_generator.rb: [ruby-core:04412]\n\n\t* lib/rdoc/generators/ri_generator.rb: ditto.\n\nThu Feb 10 11:14:17 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (COMMON_HEADERS): shouldn't include winsock2.h.\n\n\t* ext/socket/extconf.rb (sockaddr_storage): remove workaround for\n\t  mswin32.\n\nThu Feb 10 10:29:16 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/curses/curses.c: don't need to check HAVE_WCOLOR_SET excluding\n\t  window_color_set().\n\nThu Feb 10 00:47:25 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (make_struct): fixed: [ruby-core:04402]\n\nWed Feb  9 08:07:08 2005  Paul Duncan  <pabs@pablotron.org>\n\n\t* ext/curses/curses.c (window_color_set): [ruby-core:04393]\n\nTue Feb  8 23:51:47 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: reject :instance_eval, :class_eval, :module_eval\n\t  [druby-ja:117]\n\nTue Feb  8 13:06:12 2005  Sam Roberts  <sroberts@uniserve.com>\n\n\t* ext/socket/socket.c (Init_socket): SO_REUSEPORT added.\n\t  [ruby-talk:130092]\n\nTue Feb  8 09:30:01 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::Cookie): [ruby-talk:130040]\n\nTue Feb  8 00:19:02 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Name#subdomain_of?): new method.\n\t  (Resolv::DNS::Name#inspect): ditto.\n\t  Suggested by Sam Roberts.  [ruby-talk:129086]\n\nMon Feb  7 10:06:30 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c: [ruby-doc:818]\n\nMon Feb  7 01:56:20 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* instruby.rb, rubytest.rb (srcdir): no longer embed srcdir into\n\t  rbconfig.rb. (backported from CVS HEAD)\n\n\t* ext/socket/extconf.rb (sockaddr_storage): winsock2.h have the\n\t  definition of struct sockaddr_storage, but socket.c doesn't\n\t  include it because this version of ruby still has binary level\n\t  compatibility with winsock1.\n\n\t* lib/mkmf.rb (create_makefile): should support header files in\n\t  depend file.\n\nMon Feb  7 01:21:50 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/extconf.rb: check if getaddrinfo() works fine only when\n\t  wide-getaddrinfo option is not given.  fixed: [ruby-dev:25422]\n\n\t* lib/mkmf.rb ($extmk): check if under ext directory.\n\n\t* lib/mkmf.rb (Logging.postpone): allow recursive operation.\n\n\t* lib/mkmf.rb (try_constant): make sure if really a constant, reduce\n\t  the number of times of compile.\n\n\t* lib/mkmf.rb (have_macro, have_var, byte_order): new functions.\n\n\t* lib/mkmf.rb (find_library): allow directory list with separators.\n\n\t* lib/mkmf.rb (arg_config): manage provided configuration options.\n\n\t* lib/mkmf.rb (dir_config): accept arrays of directory names as\n\t  default values.\n\n\t* mkconfig.rb: no longer embed srcdir and compile_dir into\n\t  rbconfig.rb.\n\n\t* lib/mkmf.rb (create_makefile): fix unbalanced parens.\n\nSun Feb  6 19:23:01 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (stack_extend): add prototype because VC++8 doesn't\n\t  accept __declspec(noinline) with K&R style function definitions.\n\t  (backported from CVS HEAD)\n\nSun Feb  6 14:14:26 2005  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb (new_with_hash): changed messages of exception.\n\n\t* lib/date/format.rb (str[fp]time): undocumented conversion\n\t  specifications %[1-3] are now deprecated.\n\nSun Feb  6 12:20:11 2005  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* bignum.c (rb_big2ulong_pack): One too many arguments are passed\n\t  to big2ulong().\n\n\t* re.c (rb_reg_init_copy, rb_reg_initialize_m): One too many\n\t  arguments are passed to rb_reg_initialize().\n\nSun Feb  6 03:24:20 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Resource::TXT): multiple strings was not\n\t  handled.\n\t  (Resolv::DNS::Resource::TXT#strings): new method to return all\n\t  strings.\n\t  (Resolv::DNS::Message::MessageEncoder#put_string_list): new method.\n\t  (Resolv::DNS::Message::MessageDecoder#get_string_list): ditto.\n\t  based on [ruby-talk:129732] by Sam Roberts.\n\nFri Feb  4 00:30:45 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss: supported Image module.\n\t  http://web.resource.org/rss/1.0/modules/image/\n\nThu Feb  3 23:42:36 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_close, strio_close_read, strio_close_write):\n\t  should return nil instead of self as well as IO.  [ruby-dev:25623]\n\n\t* ext/stringio/stringio.c (strio_extend, strio_putc): fill with zero\n\t  extended portion.  [ruby-dev:25626]\n\nWed Feb  2 23:52:53 2005  sheepman  <sheepman@tcn.zaq.ne.jp>\n\n\t* ext/stringio/stringio.c (strio_truncate): should MEMZERO an extended\n\t  part.  [ruby-dev:25618]\n\nWed Feb  2 21:56:01 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (RSS::Element#convert): added.\n\n\t* lib/rss/rss.rb: convert -> need_convert.\n\n\t* lib/rss/1.0.rb: ditto.\n\n\t* lib/rss/0.9.rb: ditto.\n\n\t* lib/rss/2.0.rb: ditto.\n\n\t* lib/rss/trackback.rb: ditto.\n\nTue Feb  1 22:48:48 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRb::DRbObject#respond_to?): check marshal_dump and\n\t  _dump.\n\nTue Feb  1 00:20:23 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (aix): fix linker flags on AIX.  [ruby-talk:125460]\n\nMon Jan 31 13:33:21 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: add invalid namespace check\n\n\t* ext/tk/lib/multi-tk.rb: add invalid_namespace? method\n\n\t* ext/tk/lib/remote-tk.rb: ditto\n\nMon Jan 31 10:29:18 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/context.rb (IRB::Context::initialize): [ruby-core:04330]\n\nSat Jan 29 09:42:12 2005  Sam Roberts  <sroberts@uniserve.com>\n\n\t* lib/resolv.rb (Resolv::DNS::Resource::IN::SRV): Added RFC2782 SRV\n\t  resource record for specifying location of services.\n\nFri Jan 28 17:16:55 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Config.parse_resolv_conf):\n\t  parse options line for ndots option.\n\t  (Resolv::Hosts#lazy_initialize): return self.\n\t  (Resolv::DNS#lazy_initialize): ditto.\n\t  (Resolv::DNS::Config#lazy_initialize): ditto.\n\t  Suggested by Sam Roberts.\n\nThu Jan 27 13:18:03 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.c (st_foreach): report success/failure by return value.\n\t  [ruby-Bugs-1396]\n\nThu Jan 27 00:15:29 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb (setup): support BSD-style\n\t  directory group inheritance. (backport from HEAD, rev 1.32)\n\n\t* test/fileutils/fileasserts.rb (assert_same_entry): show entry\n\t  difference. (backport from HEAD, rev 1.4)\n\nWed Jan 26 23:09:11 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb (WriteAdapter#puts): should append \\n, not\n\t  prepend. [ruby-talk:128302] (backport from HEAD, rev 1.75)\n\nWed Jan 26 10:51:50 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (flock_winnt, flock_win95): unlock file even if\n\t  LOCK_NB is specified. (backported from CVS HEAD)\n\nTue Jan 25 17:11:51 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ruby.c (proc_options): correct -T option in RUBYOPT. (backported\n\t  from CVS HEAD)\n\nTue Jan 25 14:05:52 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix SEGV bug; trouble on canceling remained\n\t  after scripts [ruby-dev:25479]: NULL current namespace when deleting\n\t    Tk interpreter [ruby-talk:126225]\n\n\t* ext/tcltklib/extconf.rb: bug fix; TCL_ENABLE_THREAD flag is inverted\n\t  [ruby-talk:126360]\n\n\t* ext/tcltklib/extconf.rb: add yet another native-thread check\n\n\t* ext/tk/tkutil.c: fix SEGV bug; NULL string pointer when finalize\n\t  Ruby interpreter\n\n\t* ext/tk/lib/multi-tk.rb: avoid warning for deleted safeTk ip frame\n\n\t* ext/tk/lib/tk/bindtag.rb: bug fix; new method of named bindtag\n\t  doesn't return the created object [ruby-dev:25479]\n\n\t* ext/tk/lib/tk/menu.rb: bug on treating arguments [ruby-dev:25479]\n\n\t* ext/tk/lib/tk.rb: bug fix; cannot accept a callback ID string for\n\t  a command argument [ruby-dev:25479]\n\n\t* ext/tk/lib/multi-tk.rb: ditto\n\n\t* ext/tk/lib/tk/*.rb: ditto\n\n\t* ext/tk/lib/tkextlib/*.rb: ditto\n\n\t* ext/tk/sample/demos-jp/anilabel.rb: new demo script\n\n\t* ext/tk/sample/demos-en/anilabel.rb: ditto\n\n\t* ext/tk/sample/tkHTML/ss.rb: local variable scope bug fix\n\t  [ruby-dev:25479]\n\nMon Jan 24 15:44:25 2005  Tilman Sauerbeck  <tilman@code-monkey.de>\n\n\t* lib/rdoc/parsers/parse_c.rb: allow whitespace after function names.\n\t  [ruby-core:4296]\n\n\t* lib/rdoc/parsers/parse_simple.rb: adds support for private comments\n\t  in the \"simple\" parser. [ruby-core:4301]\n\nMon Jan 24 15:44:25 2005  Charles Mills  <cmills@freeshell.org>\n\n\t* lib/rdoc/parsers/parse_c.rb: adds support for constants\n\t  (rb_define_const), accessors (rb_define_attr), and makes a\n\t  couple fixes. [ruby-core:4307]\n\nMon Jan 24 15:44:25 2005  Florian Gro  <florgro@gmail.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb: Logic for def Builtin.method() end\n\t  [ruby-core:4302]\n\nMon Jan 24 15:44:25 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* document updates - [ruby-core:04296], [ruby-core:04301],\n\t  [ruby-core:04302], [ruby-core:04307]\n\nSun Jan 23 12:41:16 2005  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/wsdlDriver.rb: from 1.5.3-ruby1.8.2, operation which has\n\t  capitalized name (such as KeywordSearchRequest in AWS) is defined as\n\t  a method having uncapitalized name. (converted with\n\t  GenSupport.safemethodname to handle operation name 'foo-bar').  it\n\t  introduced serious incompatibility; in the past, it was defined as a\n\t  capitalized.\n\n\t  define capitalized method as well under that circumstance.\n\nSun Jan 23 05:24:42 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ocsp.c (ossl_ocspreq_to_der): should call\n\t  GetOCSPReq at first.\n\nSat Jan 22 23:09:47 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/ssl.rb (accept): rescue SSLError. [druby-ja:110]\n\nSat Jan 22 22:35:03 2005  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/unix.rb: fail if UNIXFileOwner is set. [druby-ja:111]\n\nFri Jan 21 23:58:42 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_set_pos): clear EOF flag.\n\t  [ruby-talk:127511]\n\nFri Jan 21 20:07:02 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Config.resolv): don't raise ResolvError.\n\t  reported by Sam Roberts.  [ruby-talk:127133]\n\nFri Jan 21 16:58:10 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (rb_push_glob): should work for NUL delimited patterns.\n\nFri Jan 21 13:58:37 2005  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (u8tou16): fixed typo. fixed: [ruby-list:40546]\n\t  (backported from CVS HEAD)\n\nFri Jan 21 09:30:16 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* rubyio.h (rb_eof_error): should mark as NORETURN. (backported\n\t  from CVS HEAD)\n\nFri Jan 21 00:31:36 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/syck/rubyext.c (syck_parser_bufsize_set): avoid VC++ warning\n\t  \"local variable 'size' used without having been initialized\".\n\nThu Jan 20 19:03:24 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): shouldn't set $extflags on mswin32.\n\n\t* win32/Makefile.sub (LIBRUBY_SO): should use $DLDOBJS instead of\n\t  $EXTOBJS.\n\t  fixed: [ruby-core:04290] (backported from CVS HEAD)\n\nThu Jan 20 11:42:02 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_new4): should propagate taintedness.\n\n\t* struct.c (rb_struct_set): use original method name, not callee\n\t  name, to retrieve member slot.  [ruby-core:04268]\n\n\t* time.c (time_strftime): protect from format modification from GC\n\t  finalizers.\n\nWed Jan 19 18:06:40 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/ipaddr.rb (to_s, test_to_s): too many colons with some cases.\n\t  (backported from CVS HEAD)\n\nWed Jan 19 01:16:30 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Config.parse_resolv_conf): ignore\n\t  domain and search directive without an argument.\n\t  reported by Sam Roberts.  [ruby-talk:126781]\n\nTue Jan 18 15:03:05 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/ssl.rb (WEBrick::Config::SSL): the default value\n\t  of :SSLEnable is false.\n\n\t* lib/webrick/server.rb (WEBrick::Daemon.start): prepared stdio\n\t  don't allow changing its mode.\n\n\t* lib/webrick/httpproxy.rb (WEBrick::HTTPProxyServer#proxy_service):\n\t  should delete trailing LF from the result of pack(\"m*\").\n\n\t* lib/webrick/httpproxy.rb (WEBrick::HTTPProxyServer#proxy_connect):\n\t  - should delete trailing LF from the result of pack(\"m*\").\n\t  - clear Request-Line not to send the response by HTTPServer#run.\n\n\t* lib/webrick/httputils (WEBrick::HTTPUtils.parse_qvalues):\n\t  refine regexp (and change the name of a local variable).\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils#escape_path): add\n\t  new method to escape URI path component.\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI::Socket#request_line): should\n\t  escape SCRIPT_NAME and PATH_INFO before being parsed as a URI.\n\n\t* test/webrick/*, sample/webrick/httpproxy.rb: add new file.\n\nMon Jan 17 23:33:46 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (aix): fix typo.  [ruby-talk:126401]\n\nMon Jan 17 07:08:51 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/readline/readline.c: suppress warnings.\n\n\t* lib/irb/extend-command.rb (IRB::ContextExtender.def_extend_command):\n\t  ditto.\n\n\t* lib/irb/ext/history.rb (IRB::Context::set_last_value): ditto.\n\n\t* lib/irb/ext/history.rb (IRB::Context::eval_history): ditto.\n\n\t* lib/irb/locale.rb (IRB::Locale::real_load): ditto.\n\n\t* lib/irb/slex.rb (SLex::Node::create_subnode): remove garbage.\n\nMon Jan 17 00:09:42 2005  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/uri/common.rb (PORT): typo fix. fixed: [ruby-core:04256]\n\nSat Jan 15 14:57:22 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ruby.c (proc_options): ignore trailing CRs at the end of short\n\t  options as well as long options.  fixed: [ruby-core:04232]\n\nSat Jan 15 13:35:16 2005  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb (RSS::VERSION): 0.1.2 -> 0.1.3.\n\n\t* lib/rss/rss.rb: accept inheritance. [ruby-talk:126104]\n\nThu Jan 13 04:48:53 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (io_fread): don't warn nonblocking behavior by default.\n\nWed Jan 12 00:36:29 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (rb_class_superclass): superclass of singleton class also\n\t  should be a singleton class.  fixed: [ruby-list:40519]\n\nTue Jan 11 09:44:40 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* numeric.c (Init_Numeric): turn off floating point exceptions\n\t  on bcc32. \"1e300\".to_f had crashed by overflow.\n\nTue Jan 11 03:10:10 2005  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (copy_entry): could not copy symbolic link.\n\t  [ruby-talk:125733]\n\n\t* lib/fileutils.rb (copy_stream): use read/write instead of\n\t  sysread/syswrite.\n\nMon Jan 10 23:08:15 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* variable.c (rb_autoload): hide internal data from ruby level.\n\t  fixed: [ruby-dev:25435], [ruby-list:40498]\n\nMon Jan 10 01:22:55 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_data_object_alloc): klass may be NULL.\n\t  [ruby-list:40498]\n\nSun Jan  9 03:12:58 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (io_fread): warn nonblocking behavior.\n\t  (io_readpartial): new method IO#readpartial.\n\nSat Jan  8 04:38:47 2005  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml.rb: Kernel#y requires an argument.\n\nFri Jan  7 21:12:29 2005  TAMURA Takashi  <sheepman@tcn.zaq.ne.jp>\n\n\t* random.c (rand_init): use ALLOC_N instead of ALLOCA_N\n\t  [ruby-dev:25426]\n\nFri Jan  7 18:03:35 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* gc.c (mark_locations_array): avoid core dump with -O3.\n\t  [ruby-dev:25424]\n\nThu Jan  6 20:31:07 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (zstream_end): should return value. (backported\n\t  from CVS HEAD)\n\nThu Jan  6 19:55:13 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.c (rb_w32_close): didn't close socket handle.\n\t  [ruby-dev:25414]\n\n\t* win32/win32.c (rb_w32_open_osfhandle): bcc32's _open_osfhandle\n\t  never set EMFILE.\n\nThu Jan  6 17:14:31 2005  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* random.c (random_seed): O_NONBLOCK isn't defined on some\n\t  platforms. [ruby-dev:25417]\n\nThu Jan  6 13:45:35 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb: recognize +00:00 and GMT as a localtime.\n\nThu Jan  6 07:58:28 2005  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/usage.rb (RDoc::RDoc.usage_no_exit): Allow for colons\n\t  in path names on DOS machines. (thanks to Johan Nilsson)\n\nWed Jan  5 20:16:32 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* random.c (limited_big_rand): didn't work if SIZEOF_BDIGITS == 2.\n\t  [ruby-dev:25408]\n\n\t* random.c (random_seed): refined.\n\nWed Jan  5 12:49:39 2005  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_initialize): Thread objects cannot be initialized\n\t  again.  fixed: [ruby-core:04067]\n\nWed Jan  5 10:48:16 2005  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* dir.c (dir_s_mkdir): win32 special processing doesn't need any\n\t  longer. (backported from CVS HEAD)\n\n\t* win32/win32.[ch] (rb_w32_mkdir): new function. POSIX.1 compatible\n\t  interface. (backported from CVS HEAD)\n\n\t* win32/win32.[ch] (rb_w32_rmdir): new function. (backported from CVS\n\t  HEAD)\n\nWed Jan  5 02:30:11 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* random.c (init_by_array): imported from mt19937ar-cok.tgz.\n\t  (genrand_int32): ditto.\n\t  (genrand_real): replaced with genrand_res53 in mt19937ar-cok.\n\t  (rand_init): support bignum for longer seed.\n\t  (random_seed): generate longer seed.\n\t  (make_mask): new function.\n\t  (limited_rand): ditto.\n\t  (limited_big_rand): ditto.\n\t  (rb_f_rand): call limited_rand and limited_big_rand.\n\t  [ruby-dev:25403]\n\nTue Jan  4 23:25:29 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_rand): should return positive random number.\n\t  [ruby-dev:25401]\n\nTue Jan  4 11:15:29 2005  TAMURA Takashi  <sheepman@tcn.zaq.ne.jp>\n\n\t* bignum.c (rb_big_rand): do not use rb_big_modulo to generate\n\t  random bignums.  [ruby-dev:25396]\n\nMon Jan  3 14:01:54 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* random.c (random_seed): don't use /dev/urandom if it is not\n\t  character device.\n\nMon Jan  3 11:37:42 2005  Tanaka Akira  <akr@m17n.org>\n\n\t* random.c (random_seed): use /dev/urandom if available.\n\t  [ruby-dev:25392]\n\nMon Jan  3 07:46:42 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpauth/htpasswd.rb (WEBrick::Htpasswd#reload):\n\t  raise NotImplementedError if password is encrypted by digest\n\t  algorithms. This patch is contributed by sheepman. [ruby-list:40467]\n\n\t* lib/webrick/httpauth/digestauth.rb\n\t  (WEBrick::HTTPAuth::DigestAuth#_authenticate): fix digest calculation.\n\t  This patch is contributed by sheepman. [ruby-list:40482]\n\n\t* lib/webrick/{httpauth.rb,httpauth/basicauth.rb,httpproxy.rb}: use\n\t  pack/unpack-template char \"m\" instead of lib/base64.rb to do base64\n\t  encoding/decoding. fixed: [ruby-dev:25336]\n\n\t* test/webrick/test_httpauth.rb: new file.\n\nSat Jan  1 04:20:23 2005  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ns_spki.c (ossl_spki_set_challenge): should call\n\t  StringValue before GetSPKI. fixed: [ruby-dev:25359].\n\nSat Jan  1 01:13:28 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_autoload): [ruby-dev:25373]\n\nFri Dec 31 14:10:43 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::TextFormatter::display_flow_item): Fix problem\n\t  if heading contains formatting.\n\nThu Dec 30 00:41:42 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (svalue_to_avalue): [ruby-dev:25366]\n\n\t* string.c (rb_str_justify): [ruby-dev:25367]\n\nWed Dec 29 11:07:07 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/template/html/kilmer.rb: Update to use new\n\t  sections.\n\nTue Dec 28 22:31:46 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_justify): create buffer string after argument type\n\t  conversion.  fixed: [ruby-dev:25341]\n\nTue Dec 28 15:41:48 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c (reinit): should initialize all static\n\t  variables.  fixed: [ruby-list:40445]\n\nTue Dec 28 15:25:20 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/nkf/lib/kconv.rb (Kconv::RegexpEucjp): second byte is up to\n\t  0xfe.\n\n\t* ext/nkf/lib/kconv.rb (Kconv#kconv): should handle UTF8 and UTF16\n\t  properly.\n\nTue Dec 28 13:35:20 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (rb_deflate_s_deflate, rb_inflate_s_inflate): ensure\n\t  freeing internal zstreams.  fixed: [ruby-dev:25309]\n\n\t* ext/zlib/zlib.c (rb_deflate_init_copy): replace rb_deflate_clone.\n\nTue Dec 28 12:26:45 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub, win32/setup.mak (RDOCTARGET, install,\n\t  install-nodoc, install-doc): rdoc support for mswin32.\n\n\t* win32/configure.bat (--enable-install-doc, --disable-install-doc):\n\t  ditto.\n\nMon Dec 27 20:02:14 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix SEGV bug when deleting Tk interp\n\n\t* ext/tk/lib/multi-tk.rb: ditto\n\nMon Dec 27 16:55:17 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509name.c (Init_ossl_x509name): should use\n\t  rb_hash_new to get exactly a Hash. fix [ruby-dev:25325].\n\nMon Dec 27 16:29:56 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_justify): [ruby-dev:25341]\n\nMon Dec 27 15:47:48 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/fileasserts.rb: sync with HEAD.\n\n\t* test/fileutils/test_fileutils.rb: ditto.\n\n\t* test/fileutils/test_nowrite.rb: ditto.\n\nMon Dec 27 15:21:07 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mv): should raise error when moving a\n\t  directory to the (empty) directory. [ruby-talk:124368]\n\t  (backport from HEAD 1.48)\n\n\t* lib/fileutils.rb (mv): wrongly did not overwrite file on Win32\n\t  platforms. (backport from HEAD 1.48)\n\nSat Dec 25 11:11:48 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.8.2 released.\n\nSat Dec 25 04:23:49 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mkdir, mkdir_p): should ensure directory\n\t  permission. (backportted from HEAD, 1.47)\n\n\t* lib/fileutils.rb (traverse, remove_dir): untaint trasted\n\t  objects. (backportted from HEAD, 1.46)\n\nSat Dec 25 01:28:23 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c: cancel io_reopen() change on Dec. 24th.\n\n\t* dln.c: use <dlfcn.h> for NetBSD.  [ruby-dev:25313]\n\n\t* io.c (rb_f_select): IO list could be altered.  [ruby-dev:25312]\n\nFri Dec 24 23:51:48 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: bcc32 should use RTL dll (backport from HEAD)\n\t  [ruby-dev:25306]\n\n\t* win32/win32.[ch]: ditto.\n\nFri Dec 24 23:27:18 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/image.rb: TkPhotoImage#cget bug fix\n\nFri Dec 24 18:39:25 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.[ch]: failed to compile on bcc32 (and probably wince)\n\t  [ruby-dev:25306]\n\nFri Dec 24 02:52:52 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_reopen, rb_io_reopen): prohibit to change access mode for\n\t  special IO ports.  [ruby-dev:25225]\n\nFri Dec 24 02:22:53 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (rb_syck_io_str_read): [ruby-core:03973]\n\n\t* ext/syck/rubyext.c (syck_loader_transfer): check type conversion.\n\n\t* ext/syck/rubyext.c (syck_parser_assign_io, rb_new_syck_node): duck\n\t  typing.\n\n\t* ext/syck/rubyext.c (syck_parser_s_alloc, syck_parser_initialize):\n\t  allocation framework.\n\n\t* ext/syck/rubyext.c (syck_emitter_s_alloc, syck_emitter_initialize):\n\t  ditto.\n\nFri Dec 24 01:21:00 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/blt.rb: add BLT extension support\n\n\t* ext/tk/lib/tkextlib/blt/*.rb: ditto\n\n\t* ext/tk/lib/tkextlib/blt/tile/*.rb: ditto\n\nThu Dec 23 23:36:28 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (proc_setgroups): check if the argument lenght is\n\t  modified.  fixed: [ruby-dev:25285]\n\nThu Dec 23 13:13:33 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: define TclTkLib::COMPILE_INFO and\n\t  RELEASE_DATE\n\n\t* ext/tcltklib/extconf.rb: ditto\n\n\t* ext/tk/tkutil.c: define TkUtil::RELEASE_DATE\n\n\t* ext/tk/lib/tk.rb: define Tk::RELEASE_DATE\n\nThu Dec 23 09:38:31 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_reopen): restore exact mode.  fixed: [ruby-core:04003]\n\nThu Dec 23 00:16:32 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (bsdi): use $(CC) for LDSHARED.  fixed [ruby-dev:25270]\n\nWed Dec 22 11:14:55 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_mode_modenum): replace O_ACCMODE with O_RDWR.\n\t  fixed: [ruby-dev:25273]\n\nWed Dec 22 08:34:32 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/dl/sym.c (rb_dlsym_initialize): extract internal pointers after\n\t  all argument conversion.  fixed: [ruby-dev:25271]\n\nWed Dec 22 00:08:01 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/*, test/soap/*, sample/soap/authheader/*: eval cleanup.\n\nTue Dec 21 22:07:33 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_traverse, ossl_asn1_decode,\n\t  ossl_asn1_decode_all): temporary value should be marked volatile.\n\nTue Dec 21 14:40:02 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_traverse, ossl_asn1_decode,\n\t  ossl_asn1_decode_all): use rb_str_new4 to avoid SEGV.\n\t  fix [ruby-dev:25261]\n\n\t* test/openssl/test_asn1.rb: add tests for OpenSSL::ASN1.\n\nTue Dec 21 12:22:40 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_reopen): keep duplex pipe in correct mode for exception\n\t  safeness.  fixed: [ruby-dev:25152]\n\nTue Dec 21 12:10:04 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/grid.rb: rescue bug of 'grid configure' on Tcl/Tk8.3-\n\nTue Dec 21 00:53:01 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_traverse): [ruby-dev:25261]\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_decode): ditto.\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_decode_all): ditto.\n\nMon Dec 20 23:22:26 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* added files:\n\t  * lib/soap/mapping/wsdl*.rb\n\t  * lib/wsdl/soap/element.rb\n\t  * lib/wsdl/xmlSchema/simpleContent.rb\n\n\t* modified files:\n\t  * lib/soap/*\n\t  * lib/wsdl/*\n\t  * lib/xsd/*\n\t  * test/soap/*\n\t  * test/wsdl/*\n\t  * test/xsd/*\n\t  * sample/soap/*\n\t  * sample/sdl/*\n\n\t* summary\n\t  * imported from the soap4r repository.  Version: 1.5.3-ruby1.8.2\n\n\t  * added several XSD basetype support: nonPositiveInteger,\n\t    negativeInteger, nonNegativeInteger, unsignedLong, unsignedInt,\n\t    unsignedShort, unsignedByte, positiveInteger\n\n\t  * HTTP client connection/send/receive timeout support.\n\n\t  * HTTP client/server gzipped content encoding support.\n\n\t  * improved WSDL schema definition support; still is far from\n\t    complete, but is making step by step improovement.\n\nMon Dec 20 22:56:39 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* gc.c (stack_end_address): gcc noinline attribute is available since\n\t  gcc-3.1.\n\nMon Dec 20 14:07:02 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: supports new features of Tcl/Tk8.5a2\n\n\t* ext/tk/lib/tk/clock.rb: ditto\n\n\t* ext/tk/lib/tk/text.rb: ditto\n\n\t* ext/tk/lib/tk/panedwindow.rb: ditto\n\nMon Dec 20 12:47:13 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/net/https.rb,protocols.rb,telnets.rb: delete\n\t  doc and code about SSLContext#{key_file,cert_file}.\n\t  fixed: [ruby-dev:25243]\n\nMon Dec 20 12:42:17 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (io_fwrite): workaround for MSVCRT's bug.\n\t  fixed: [ruby-core:03982]\n\nMon Dec 20 11:21:04 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_eof): check if closed before clearerr().\n\t  fixed: [ruby-dev:25251]\n\nMon Dec 20 03:30:40 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session#initialize): empty session id was\n\t  used if request had no session key.  fixed: [ruby-core:03981]\n\nMon Dec 20 01:51:01 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (make_struct): [ruby-dev:25249]\n\nMon Dec 20 00:28:20 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rexml/encodings/SHIFT-JIS.rb: backported from CVS HEAD.\n\n\t* lib/rexml/encodings/SHIFT_JIS.rb: ditto.\n\nSun Dec 19 17:19:48 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509store.c\n\t  (ossl_x509store_set_time): add OpenSSL::X509::Store#time=.\n\t  (ossl_x509stctx_set_time): add OpenSSL::X509::StoreContext#time=.\n\n\t* test/openssl/ossl_x509store.rb: test certificate validity times.\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_to_s): add optional\n\t  second argument to specify the output format (see also\n\t  X509_NAME_print_ex).\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_init): new constants:\n\t  OpenSSL::X509::Name::COMPAT, OpenSSL::X509::Name::RFC2253,\n\t  OpenSSL::X509::ONELINE, OpenSSL::X509::MULTILINE.\n\n\t* ext/openssl/lib/openssl/x509.rb (OpenSSL::X509::Name::RFC2253DN):\n\t  new module to provide the parse for RFC2253 DN format.\n\n\t* ext/openssl/lib/openssl/x509.rb (OpenSSL::X509::Name.parse_rfc2253):\n\t  new method to parse RFC2253 DN format.\n\n\t* test/openssl/ossl_x509name.rb: add tests about RFC2253 DN.\n\n\t* text/openssl/ssl_server.rb: try to listen ports from 20443 to 20542\n\t  while EADDRINUSE is raised.\n\n\t* all changes in this entry are backport from 1.9.\n\nSun Dec 19 17:24:59 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (enable_rpath): use rpath flag to embed the library\n\t  path into extensions on ELF environment.  [ruby-dev:25035]\n\nSun Dec 19 11:01:25 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit.rb: use standalone runner for -e.\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner#options): accept\n\t  multiple -p and -x options.\n\n\t* lib/test/unit/collector/dir.rb (Test::Unit::Collector::Dir#recursive_collect):\n\t  ditto.\n\nSat Dec 18 16:36:23 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (rb_deflate_s_deflate, rb_inflate_s_inflate):\n\t  disallow interrupt by type conversion.  fixed: [ruby-dev:25226]\n\nSat Dec 18 15:16:41 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/webrick/httpauth.rb,\n\t  lib/webrick/httpauth/{basicauth.rb,digestauth.rb}: use\n\t  pack/unpack-template char \"m\" instead of lib/base64.rb to do base64\n\t  encoding/decoding.\n\nSat Dec 18 10:51:01 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_open_dir): new function.  [ruby-dev:25242]\n\nFri Dec 17 18:07:01 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* test/readline/test_readline.rb: fix for BSD. Thanks, GOTOU Yuuzou.\n\t  fixed: [ruby-dev:25218]\n\nFri Dec 17 16:28:12 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: fix bug on setting up system encoding\n\n\t* ext/tk/lib/tk/event.rb: fix error on require process\n\n\t* ext/tk/lib/tk/font.rb: fix abnormal termination error on Windows\n\n\t* ext/tk/lib/tk/virtevent.rb: TkVirtualEvent::PreDefVirtEvent.new()\n\t  accepts event-sequence arguments\n\n\t* ext/tk/lib/tk/text.rb: fail to dump embedded images\n\n\t* ext/tk/lib/tk/text.rb: tag_nextrange and tag_prevrange returns wrong\n\t  types of values\n\n\t* ext/tk/lib/tk/texttag.rb: nextrange and prevrange returns wrong\n\t  types of values\n\n\t* ext/tk/lib/tk/text.rb: add TkText::IndexModMethods module and\n\t  TkText::IndexString class to treat text index modifiers\n\n\t* ext/tk/lib/tk/texttag.rb: use TkText::IndexModMethods module\n\n\t* ext/tk/lib/tk/textmark.rb: ditto\n\n\t* ext/tk/lib/tk/textimage.rb: ditto\n\n\t* ext/tk/lib/tk/textwindow.rb: ditto\n\n\t* ext/tk/lib/tk/textimage.rb: wrong gravity of text mark for embedded\n\t  image\n\n\t* ext/tk/lib/tk/textwindow.rb: wrong gravity of text mark for\n\t  embedded window\n\nFri Dec 17 13:50:00 2004  Akiyoshi, Masamichi  <akiyoshi@hp.com>\n\n\t* vms/vmsruby_private.c, vms/vmsruby_private.h: private routines\n\t  for VMS port are added.\n\n\t* eval.c (ruby_init): change to call VMS private intialization routine.\n\nFri Dec 17 13:33:58 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session#initialize): control adding\n\t  session_id hidden fields.  fixed: [ruby-talk:123850]\n\nThu Dec 16 23:25:25 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb, lib/drb/ssl.rb: backported from CVS HEAD.\n\t  [druby-ja:101]\n\n\t* test/drb/test_drb.rb: adjust and reduce sleep (backported from\n\t  CVS HEAD.)\n\nThu Dec 16 18:44:58 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpserver.rb (WEBrick::HTTPServer#run): should wait\n\t  for reading request till data arrive. [ruby-talk:121068]\n\n\t* lib/webrick/server.rb (WEBrick::GenericServer#start_thread):\n\t  should log about all accepted socket. [ruby-core:03962]\n\n\t* lib/webrick/accesslog.rb (WEBrick::AccessLog#setup_params):\n\t  \"%%\" and \"%u\" are supported. [webricken:135]\n\n\t* lib/webrick/httpservlet/filehandler.rb\n\t  (WEBrick::HTTPServlet::FileHandler#check_filename):\n\t  :NondisclosureName is acceptable if it is Enumerable.\n\n\t* lib/webrick/config.rb (WEBrick::Config::FileHandler):\n\t  default value of :NondisclosureName is [\".ht*\", \"*~\"].\n\nThu Dec 16 18:36:52 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.c (ossl_raise): refine message format.\n\nThu Dec 16 16:29:44 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/demos-en/widget: modify version check for\n\t  supporting features\n\nThu Dec 16 16:03:50 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/bindtag.rb: bug fix [ruby-talk: 123667]\n\n\t* ext/tk/lib/tk/timer.rb: accept :idle for the interval argument\n\n\t* ext/tk/lib/tk.rb: add TkComm._callback_entry?()\n\n\t* ext/tk/lib/multi-tk.rb: add MultiTkIp.cb_entry_class\n\n\t* ext/tk/lib/tk/canvas.rb: use TkComm._callback_entry?()\n\n\t* ext/tk/lib/tk/canvastag.rb: ditto\n\n\t* ext/tk/lib/tk/dialog.rb: ditto\n\n\t* ext/tk/lib/tk/optiondb.rb: ditto\n\n\t* ext/tk/lib/tk/text.rb: ditto\n\n\t* ext/tk/lib/tk/texttag.rb: ditto\n\n\t* ext/tk/lib/tk/textwindow.rb: ditto\n\n\t* ext/tk/lib/tk/timer.rb: ditto\n\n\t* ext/tk/lib/tk/validation.rb: ditto\n\n\t* ext/tk/lib/tkextlib/*: ditto\n\nThu Dec 16 03:14:28 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (basic_encode): return value of pack('m') may\n\t  include multiple CR/LFs.  Backported from main trunk (rev 1.112).\n\t  [ruby-dev:25212]\n\nThu Dec 16 00:33:37 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (Init_Hash): remove custom \"hash\" and \"eql?\".\n\nWed Dec 15 18:57:01 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/set.rb (Set::eql): wrong definition.  [ruby-dev:25207]\n\nWed Dec 15 18:48:42 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/curses/curses.c (window_subwin): call NUM2INT() before\n\t  GetWINDOW(). (backported from CVS HEAD)\n\nWed Dec 15 17:03:50 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.[ch] (rb_w32_isatty): new function to replace MSVCRT's\n\t  isatty because it never sets errno. (backported from CVS HEAD)\n\nWed Dec 15 15:39:32 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_to_a): avoid SEGV\n\t  (rollback the previous commit).\n\nWed Dec 15 16:10:23 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_id_obsolete): warn always.\n\n\t* eval.c (rb_enable_super): ditto.\n\nWed Dec 15 15:31:02 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/set.rb (Set#==): [ruby-dev:25206]\n\nWed Dec 15 14:22:10 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_fdisset): check whether the handle is valid.\n\t  fixed: [ruby-core:03959]\n\nWed Dec 15 10:30:37 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/openssl/ossl_digest.c (ossl_digest_initialize): [ruby-dev:25198]\n\nTue Dec 14 17:10:09 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_close): need to reset osfhnd().\n\nTue Dec 14 14:03:57 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.c (ossl_raise): avoid buffer overrun.\n\t  [ruby-dev:25187]\n\nTue Dec 14 12:36:04 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::initialize): generate new\n\t  session if given session_id does not exist.  [ruby-list:40368]\n\nMon Dec 13 18:13:52 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* gc.c (stack_end_address): new function to obtain stack end address.\n\t  stack_end_address calls __builtin_frame_address(0) to obtain the\n\t  frame pointer of a stack frame of stack_end_address.  The address\n\t  is the stack pointer of the caller's stack frame.\n\t  (SET_STACK_END): use stack_end_address.\n\t  This makes the conservative garbage collector to scan a stack frame\n\t  of the garbage_collect function itself.  This is required because\n\t  callee-save registers may be stored in the frame.\n\t  [ruby-dev:25158]\n\nMon Dec 13 00:58:02 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (cleanpath_aggressive): make it private.\n\t  (cleanpath_conservative): ditto.\n\t  Suggested by Daniel Berger.  [ruby-core:3914]\n\nSun Dec 12 20:06:38 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: backported from CVS HEAD.\n\nSun Dec 12 10:35:10 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/template/html/html.rb (RDoc::Page): Don't\n\t  show an accessor's r/w flag if none was specified\n\nSun Dec 12 10:14:03 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/rdoc.rb (RDoc::RDoc::parse_files): Never exclude files\n\t  explicitly given on the command line.\n\nSun Dec 11 23:54:07 2005  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/*: update to support libraries in ActiveTcl8.4.12.0\n\t  (see ext/tk/ChangeLog.tkextlib).\n\n\t* ext/tk/sample/scrollframe.rb: add a new sample.\n\nSat Dec 11 20:12:21 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: add DRbRemoteError. [ruby-list:40348],\n\t  [ruby-list:40390]\n\n\t* test/drb/drbtest.rb: ditto.\n\n\t* test/drb/ut_drb.rb: ditto.\n\nSat Dec 11 15:38:14 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/jcode.rb (String::succ): [ruby-dev:25156]\n\nSat Dec 11 12:41:55 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (run_trap_eval): prototype; avoid VC++ warnings.\n\n\t* ext/socket/getaddrinfo.c: fix typo. fixed: [ruby-core:03947]\n\n\t* win32/win32.c: need to include dln.h.\n\nSat Dec 11 00:10:18 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_reopen): [ruby-dev:25150]\n\nFri Dec 10 08:39:27 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_listen): get OpenFile just before calling\n\t  listen(2).  fixed: [ruby-dev:25149]\n\nThu Dec  9 17:00:00 2004  Akiyoshi, Masamichi  <akiyoshi@hp.com>\n\n\t* ext/socket/socket.c, ext/socket/getaddrinfo.c: port to VMS\n\nThu Dec  9 16:31:02 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/sdbm/init.c (GetDBM): typo.\n\nThu Dec  9 16:05:00 2004  Akiyoshi, Masamichi  <akiyoshi@hp.com>\n\n\t* defines.h: change path of vms.h\n\t* vms/vms.h: delete reference for snprintf()\n\t* vms/config.h: new file\n\t* vms/config.h_in: deleted\n\nThu Dec  9 14:38:35 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_inspect): escape # which starts an expression\n\t  substitution.  fixed: [ruby-core:03922]\n\n\t* string.c (rb_str_dump): not escape # which isn't a substitution.\n\nThu Dec  9 10:54:36 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dbm/dbm.c (fdbm_select): [ruby-dev:25132]\n\n\t* ext/sdbm/init.c: ditto.\n\n\t* ext/gdbm/gdbm.c: ditto.\n\nThu Dec  9 03:08:36 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_init): set root-win title to \"ruby\" when\n\t  the running script is '-e one-liner' or '-' (stdin).\n\n\t* ext/tcltklib/extconf.rb: add find_library(\"#{lib}#{ver}\",..) for\n\t  stub libs\n\n\t* ext/tk/lib/tk/textmark.rb: TkTextMarkCurrent and TkTextMarkAnchor\n\t  have a wrong parent class.\n\n\t* ext/tk/lib/tk/dialog.rb: rename TkDialog2 --> TkDialogObj and\n\t  TkWarning2 --> TkWarningObj (old names are changed to alias names)\n\n\t* ext/tk/lib/tk/dialog.rb: bug fix of treatment of 'prev_command'\n\t  option and hashes for configuration\n\n\t* ext/tk/lib/tk/dialog.rb: add TkDialogObj#name to return the\n\t  button name\n\n\t* ext/tk/lib/tk/radiobutton.rb: rename enbugged method value() ==>\n\t  get_value() and value=(val) ==> set_value(val).\n\n\t* ext/tk/lib/tk/menu.rb: add TkMenu.new_menuspec\n\n\t* ext/tk/lib/tk/menu.rb: add alias (TkMenuButton = TkMenubutton,\n\t  TkOptionMenuButton = TkOptionMenubutton)\n\n\t* ext/tk/lib/tk/event.rb: new method aliases (same as option keys of\n\t  event_generate) for Event object\n\n\t* ext/tk/lib/tk/font.rb: configinfo returns proper types of values\n\n\t* ext/tk/lib/tk.rb: bind methods accept subst_args + block\n\n\t* ext/tk/lib/tk/canvas.rb: ditto\n\n\t* ext/tk/lib/tk/canvastag.rb: ditto\n\n\t* ext/tk/lib/tk/frame.rb: ditto\n\n\t* ext/tk/lib/tk/text.rb: ditto\n\n\t* ext/tk/lib/tk/texttag.rb: ditto\n\n\t* ext/tk/lib/tk/toplevel.rb: ditto\n\n\t* ext/tk/lib/tkextlib/*: ditto and bug fix\n\nWed Dec  8 23:54:29 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/template/html/html.rb (RDoc::Page): Typo\n\t  meant that h2 tag was invisible.\n\nWed Dec  8 21:56:31 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss, test/rss, sample/rss: backported from CVS HEAD.\n\nWed Dec  8 14:31:36 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_fwrite): change dereference for cosmetic reason.\n\n\t* sprintf.c (rb_f_sprintf): [ruby-dev:25104]\n\nTue Dec  7 19:08:00 2004  Akiyoshi, Masamichi  <akiyoshi@hp.com>\n\n\t* io.c (io_fwrite): fix offset incrementation (for VMS and Human68k)\n\nTue Dec  7 00:27:37 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_setgroups): [ruby-dev:25081]\n\nMon Dec  6 18:08:10 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_eqq): document fix.  [ruby-talk:122541]\n\nMon Dec  6 17:19:13 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* rubysig.h (TRAP_BEG, TRAP_END): safe errno around CHECK_INTS.\n\t  (backported from CVS HEAD)  [ruby-dev:24993]\n\nMon Dec  6 10:18:17 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::look_for_directives_in):\n\t  Oops - 1.8 doesn't have String#clear\n\nMon Dec  6 09:59:23 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_connect): use rb_str_new4().\n\t  [ruby-dev:25052]\n\nMon Dec  6 01:42:08 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_pkey_rsa.c (ossl_rsa_public_encrypt,\n\t  ossl_rsa_public_decrypt, ossl_rsa_private_encrypt,\n\t  ossl_rsa_private_decrypt): should take an optional argument\n\t  to specify padding mode. [ruby-talk:122539]\n\n\t* ext/openssl/ossl_pkey_rsa.c (Init_ossl_rsa): add new constants\n\t  PKCS1_PADDING, SSLV23_PADDING, NO_PADDING and PKCS1_OAEP_PADDING\n\t  under OpenSSL::PKey::RSA.\n\n\t* test/openssl/test_pkey_rsa.rb: new file.\n\nSun Dec  5 19:39:17 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Completion#complete): new parameter\n\t  to direct case insensitiveness.\n\n\t* lib/optparse.rb (OptionParser#order!): ignore case only for long\n\t  option.  [ruby-dev:25048]\n\nSat Dec  4 22:54:15 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_write): remove rb_str_locktmp().  [ruby-dev:25050]\n\n\t* io.c (io_fwrite): takes VALUE string as an argument.\n\t  [ruby-dev:25050]\n\n\t* ext/socket/socket.c (sock_connect): remove rb_str_locktmp().\n\t  [ruby-dev:25050]\n\n\t* ext/socket/socket.c (udp_connect): [ruby-dev:25045]\n\n\t* ext/socket/socket.c (udp_bind): ditto.\n\n\t* ext/socket/socket.c (udp_send): ditto.\n\n\t* ext/socket/socket.c (bsock_send): ditto.\n\n\t* ext/socket/socket.c (s_recvfrom): ditto.\n\n\t* hash.c (rb_hash_hash): should provide \"hash\" method where \"eql?\"\n\t  is redefined.  [ruby-talk:122482]\n\nSat Dec  4 14:54:52 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (proc_invoke): use volatile `tmp' rather than `args'.\n\t  [ruby-core:03882]\n\nSat Dec  4 14:28:56 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::Context::Section::set_comment):\n\t  Section comments may now be bracketed by lines which are\n\t  ignored. You can now write\n\t      # -----------\n\t      # :section: Dave's Section\n\t      # comment material\n\t      # -----------\n\t   The lines before :section: are removed, and identical lines at the end are\n\t   also removed if present.\n\nSat Dec  4 03:33:45 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/readline/readline.c: check $SAFE. (backported from CVS HEAD)\n\n\t* test/readline/test_readline.rb: added tests for readline.\n\t  (backported from CVS HEAD)\n\nSat Dec  4 02:24:00 2004  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf.c: add constant NKF::VERSION\n\n\t* ext/nkf/nkf.c(guess): this becomes an alias of guess2\n\n\t* ext/nkf/test.rb(mime_out2): add --no-cp932\n\n\t* ext/nkf/nkf-utf8/nkf.c: original nkf2 revision 1.47\n\nSat Dec  4 00:35:08 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (bsock_setsockopt): [ruby-dev:25039]\n\nFri Dec  3 18:57:03 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/ostruct.rb: 1.9 marshaling support back-ported.\n\t  [ruby-core:03871]\n\nFri Dec  3 13:45:20 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): copy arguments to frame.argv.\n\t  [ruby-core:03861]\n\nFri Dec  3 12:25:41 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* st.h: fix prototypes.\n\nFri Dec  3 00:21:05 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (convert_type): use rb_respond_to() again.\n\t  [ruby-dev:25021]\n\n\t* eval.c (rb_respond_to): funcall respond_to? if it's redefined.\n\t  [ruby-dev:25021]\n\nFri Dec  3 01:55:24 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: widget configuration by TkWindow#method_missing\n\t  returns proper object. \"widget.option = val\" returns val, and\n\t  \"widget.option(val)\" returns self.\n\n\t* ext/tk/lib/tk/font.rb: TkFont#replace accepts only one font argument.\n\n\t* ext/tk/lib/tk/radiobutton.rb: add TkRadiobutton#value and\n\t  TkRadiobutton#value=(val).\n\n\t* ext/tk/lib/tk/spinbox.rb: callback substitution support on\n\t  command option.\n\n\t* ext/tk/sample/demos-en/widget: bug fix (wrong image height)\n\n\t* ext/tk/sample/demos-jp/widget: ditto.\n\nFri Dec  3 00:11:48 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_file_initialize): [ruby-dev:25032]\n\nThu Dec  2 16:41:03 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_protect): prevent continuations created inside from being\n\t  called from the outside.  [ruby-dev:25003]\n\n\t* eval.c (rb_callcc, rb_cont_call): prohibit calling from different\n\t  signal contexts.  [ruby-dev:25022]\n\nThu Dec  2 09:57:24 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/ostruct.rb (OpenStruct::Marshaler): OpenStruct can be\n\t  marshaled again.  [ruby-core:03862]\n\nThu Dec  2 09:30:06 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (thread_mark): mark thread group.  [ruby-dev:25020]\n\n\t* eval.c (thgroup_add): check whether the argument is really a Thread.\n\nThu Dec  2 07:57:16 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_ctl): [ruby-dev:25019]\n\nWed Dec  1 02:21:02 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* signal.c (sighandler): call handler immediately only for default\n\t  handlers.  [ruby-dev:25003]\n\nTue Nov 30 23:38:18 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (io_fread): need not to null terminate.  [ruby-dev:24998]\n\n\t* io.c (read_all): remove unnecessary rb_str_resize().\n\t  [ruby-dev:24996]  (backported from CVS HEAD)\n\n\t* io.c (io_readpartial): ditto.\n\n\t* io.c (io_read): ditto.\n\nTue Nov 30 16:18:50 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_fread): need not to null terminate.  [ruby-dev:24998]\n\n\t* io.c (read_all): remove unnecessary rb_str_resize().\n\t  [ruby-dev:24996]\n\n\t* io.c (io_read): ditto.\n\nTue Nov 30 00:49:08 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_sysread): use temporary lock.  [ruby-dev:24992]\n\nMon Nov 29 16:06:04 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_write): insufficiently filled string\n\t  being extended when overwriting.  [ruby-core:03836]\n\nMon Nov 29 15:59:05 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/ostruct.rb (OpenStruct::method_missing): check method\n\t  duplication for -d.\n\n\t* lib/ostruct.rb (OpenStruct::initialize): ditto.\n\nMon Nov 29 15:22:28 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/io/nonblock/test_flush.rb: abandon tests when io/nonblock is\n\t  not supported.\n\nMon Nov 29 03:08:30 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (convert_type): direct call conversion methods for the\n\t  performance.  [ruby-core:03845]\n\n\t* eval.c (rb_funcall_rescue): new function.\n\n\t* object.c (rb_Array): avoid using rb_respond_to().\n\n\t* object.c (rb_Integer): ditto.\n\n\t* parse.y (reduce_nodes): empty body should return nil.\n\n\t* string.c (rb_str_aset): the original string should not be\n\t  affected by modifying duplicated string.  [ruby-dev:24981]\n\nMon Nov 29 13:57:38 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (CreateChild): search executable file if no program\n\t  name given. (backported from CVS HEAD)\n\nMon Nov 29 13:37:54 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (fptr_finalize): must not use FILE after fclose().\n\t  [ruby-dev:24985]\n\nMon Nov 29 13:16:31 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (CreateChild): push back the last space before next\n\t  loop because CharNext() eats it.\n\nMon Nov 29 01:18:18 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_io_check_writable): call io_seek regardless of\n\t  NEED_IO_SEEK_BETWEEN_RW.  [ruby-dev:24986]\n\nSat Nov 27 21:43:39 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c: avoid data lost with nonblocking fd and\n\t  stdio buffering in sync mode.  [ruby-dev:24966]\n\t  based on matz's patch [ruby-dev:24967]\n\t  (io_fwrite): new primitive writing function which writes\n\t  directly if sync mode.\n\t  (rb_io_fwrite): wrapper for io_fwrite now.\n\t  (io_write): call io_fwrite instead of rb_io_fwrite.\n\nSat Nov 27 14:44:15 2004  Kent Sibilev  <ksibilev@bellsouth.net>\n\n\t* lib/cgi/session.rb (CGI::Session::initialize): create_new_id is\n\t  now a instance method.  [ruby-core:03832]\n\nSat Nov 27 09:41:21 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_fread): old rb_io_fread with file closing checking.\n\t  (rb_io_fread): wrapper for io_fread now.\n\t  [ruby-dev:24964]\n\nFri Nov 26 18:02:44 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: Tk.destroy uses TkWindow#epath\n\n\t* ext/tk/lib/tk/image.rb: bug fix\n\n\t* ext/tk/lib/tk/wm.rb: add 'iconphoto' method(Windows only)\n\n\t* ext/tk/lib/tkextlib/*: some methods uses TkWindow#epath\n\nFri Nov 26 13:49:06 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (method_missing): raise TypeError for classes do not\n\t  have allocators.  [ruby-core:03752]\n\n\t* lib/erb.rb: add RDoc by James Edward Gray II.  [ruby-core:03786]\n\nFri Nov 26 13:29:02 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::look_for_directives_in): Break\n\t  out of preprocessing when we find a :section: directive (previously cleared out the\n\t  comment, but this apparently now generates an error in gsub!)\n\nFri Nov 26 00:17:40 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_read): move StringValue() check before GetOpenFile().\n\t  [ruby-dev:24959]\n\nThu Nov 25 20:14:57 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/thwait.rb (ThreadsWait#join_nowait): abnormally terminated\n\t  threads should be also processed.  [ruby-talk:121320]\n\nThu Nov 25 10:14:26 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (push_braces): do not reuse buffer strings.  [ruby-core:03806]\n\nThu Nov 25 07:59:41 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): stringify non-nil buffer argument, and always\n\t  taint the result.  [ruby-dev:24955]\n\nWed Nov 24 01:01:31 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_read): integer conversion should be prior to\n\t  GetOpenFile().  [ruby-dev:24952]\n\n\t* configure.in, io.c: cancel [ ruby-Patches-1074 ].\n\nTue Nov 23 08:09:50 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/menu.rb: improve usability of TkOptionMenubutton\n\nTue Nov 23 02:00:21 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_chown): integer conversion should be prior to\n\t  GetOpenFile().  [ruby-dev:24949]\n\nTue Nov 23 00:10:48 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_chown): integer conversion should be prior to\n\t  GetOpenFile().  [ruby-dev:24947]\n\n\t* file.c (rb_file_truncate): ditto.\n\n\t* file.c (rb_file_s_truncate): ditto.\n\n\t* dir.c (dir_seek): use NUM2OFFT().\n\n\t* misc/ruby-mode.el (ruby-non-block-do-re): should not match words\n\t  start with block keyword and underscore.  [ruby-core:03719]\n\nMon Nov 22 22:33:02 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::parse_require): Don't use names\n\t  of variables or constants when oarsing 'require'\n\nMon Nov 22 00:13:35 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_seek): should retrieve dir_data after NUM2INT().\n\t  [ruby-dev:24941]\n\nSat Nov 20 23:57:33 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/README (et al): Add a new directive, :section:, and\n\t  change the output format to accomodate. :section: allows to to\n\t  group together methods, attributes, constants, etc under\n\t  headings in the output. If used, a table of contents is\n\t  generated.\n\nSat Nov 20 23:56:54 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/options.rb (Options::parse): Force --inline-source if\n\t  --one-file option given\n\nSat Nov 20 23:55:19 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_splice): should place index wrapping after\n\t  possible modification.  [ruby-dev:24940]\n\nSat Nov 20 13:26:03 2004  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/utf8tbl.c: original revision 1.7\n\nSat Nov 20 05:34:24 2004  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf/nkf-utf8/nkf.c: original nkf.c rev:1.40\n\n\t* ext/nkf/test.rb: add test for mime encode/decode\n\nSat Nov 20 01:37:34 2004  Johan Holmberg  <holmberg@iar.se>\n\n\t* eval.c (error_print): nicer traceback at interrupt.\n\t  [ruby-core:03774]\n\nSat Nov 20 00:07:16 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_gsub): internal buffer should not be listed by\n\t  ObjectSpace.each_object() by String#gsub.  [ruby-dev:24931]\n\nFri Nov 19 01:20:22 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::FileStore::initialize): raise\n\t  exception if data corresponding to session specified from the\n\t  client does not exist.\n\nFri Nov 19 00:59:31 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_gsub): internal buffer should not be listed by\n\t  ObjectSpace.each_object().  [ruby-dev:24919]\n\nThu Nov 18 18:41:08 2004  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* test/ruby/test_stringchar.rb (test_bang): added.\n\n\t* string.c (rb_str_upcase_bang, rb_str_capitalize_bang)\n\t  (rb_str_swapcase_bang): missing rb_str_modify().  [ruby-dev:24915]\n\nThu Nov 18 00:21:15 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_getpgrp): prohibit for $SAFE=2.\n\t  [ruby-dev:24899]\n\n\t* process.c (get_pid): ditto.  [ruby-dev:24904]\n\n\t* process.c (get_ppid): ditto.\n\n\t* array.c (rb_ary_delete): defer rb_ary_modify() until actual\n\t  modification.  [ruby-dev:24901]\n\nThu Nov 18 10:10:14 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c, rubyio.h (rb_io_modenum_flags): exported.\n\n\t* ext/stringio/stringio.c (strio_initialize): allow Fixnum as mode as\n\t  well as IO.new does.  [ruby-dev:24896]\n\nWed Nov 17 23:42:40 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_settracefunc.rb: added.  [ruby-dev:24884]\n\nWed Nov 17 13:56:57 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (newline_node): should not use FL_SET. [ruby-dev:24874]\n\n\t* parse.y (string_content): should not use FL_UNSET.\n\n\t* node.h (NODE_NEWLINE): remove unused bit to utilize flag field\n\t  in nodes.\n\nWed Nov 17 13:09:40 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/Makefile.sub (test): should build ruby.exe\n\t  before running test. [ruby-core:03756]\n\nWed Nov 17 04:33:01 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* pack.c: all features are backport from 1.9. [ruby-dev:24826]\n\n\t* bignum.c (rb_big2ulong_pack): new function to pack Bignums.\n\nWed Nov 17 03:42:45 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_splice): move rb_str_modify() after\n\t  StringValue(), which may alter the receiver.  [ruby-dev:24878]\n\nTue Nov 16 23:45:07 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (flo_divmod): protect float values from GC by\n\t  assignment to local variables.  [ruby-dev:24873]\n\nTue Nov 16 16:30:21 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/setup.mak (-epilogue-): remove config.h and\n\t  config.status to force updating them.\n\nTue Nov 16 16:20:45 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): position was ignored when a\n\t  buffer was passed.  http://www.yo.rim.or.jp/~nov/d/?date=20041116#p03\n\nTue Nov 16 11:19:07 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner::options): use\n\t  Regexp conversion.\n\nTue Nov 16 01:41:31 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_mod_check): frozen check should be separated.\n\t  [ruby-core:3742]\n\n\t* array.c (rb_ary_update): pedantic check to detect\n\t  rb_ary_to_ary() to modify the receiver.  [ruby-dev:24861]\n\nMon Nov 15 13:50:52 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_justify): typo fixed.  [ruby-dev:24851]\n\nMon Nov 15 11:50:32 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-special-char-p, ruby-parse-partial): handle\n\t  operator symbols.  [ruby-talk:120177]\n\nSun Nov 14 13:27:03 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/pp.rb (PP#object_address_group): remove odd number of 'f'\n\t  prefixed to negative address.\n\nSun Nov 14 08:51:04 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/logger/test_logger.rb: Logger just expects\n\t  Logger#datetime_format to be used for Time#strftime independently of\n\t  locale. [ruby-dev:24828]\n\nFri Nov 12 15:03:26 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (ruby_options): now we cannot call rb_glob() before\n\t  ruby_init(), so call rb_w32_cmdvector() at ruby_options().\n\n\t* win32.{c,h} (rb_w32_cmdvector): rename make_cmdvector() and\n\t  export it.\n\nFri Nov 12 14:08:01 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/event.rb: remove $LOADED_FEATURES trick\n\n\t* ext/tk/lib/tk.rb: ditto\n\nFri Nov 12 00:31:05 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/gdbm/gdbm.c (fgdbm_store): StringValue() may alter string\n\t  pointer.  [ruby-dev:24783]\n\nThu Nov 11 17:36:12 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (rb_globi): also should call back via rb_glob_caller().\n\t  [ruby-dev:24775]\n\nThu Nov 11 16:47:21 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/ruby/test_file.rb (test_truncate_wbuf): we want to test\n\t  only File#truncate, not behaviour of seek(2).\n\nThu Nov 11 09:41:01 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (push_braces): was confusing VALUE and char*.\n\n\t* dir.c (rb_push_glob): Dir.glob should have called its block.\n\nThu Nov 11 01:52:52 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* error.c (syserr_initialize): use stringified object.\n\t  [ruby-dev:24768]\n\nWed Nov 10 22:49:01 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb (SimpleDelegator::dup): wrong number of\n\t  arguments.\n\n\t* lib/delegate.rb (DelegateClass::dup): ditto.\n\nWed Nov 10 12:31:21 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* README.EXT (Example): extconf.rb is indispensable now.\n\nWed Nov 10 03:33:36 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix SEGV when compiled with Tcl/Tk8.3.x\n\t  or older\n\n\t* ext/tk/lib/tkextlib/tile/style.rb: bug fix\n\nTue Nov  9 14:27:18 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Officious): moved from DefaultList.\n\nTue Nov  9 01:05:04 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (rb_glob2): do not allocate buffer from heap to avoid\n\t  memory leaks.  use string object for buffering instead.\n\t  [ruby-dev:24738]\n\n\t* dir.c (join_path): ditto.\n\n\t* io.c (io_read): external input buffer may be modified even after\n\t  rb_str_locktmp().  [ruby-dev:24735]\n\n\t* dir.c (fnmatch): p or s may be NULL.  [ruby-dev:24749]\n\nTue Nov  9 00:53:53 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* regex.c (slow_match): avoid GCC 3.4.x warnings.\n\nTue Nov  9 00:50:06 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/rdoc.rb: Change version numbering of RDoc and ri\n\nMon Nov  8 23:38:35 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/extservm.rb: add DRb::ExtServManager#uri=.\n\t  [ruby-dev:24743]\n\nMon Nov  8 22:20:19 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_class):\n\t  Fix bug where parent class wasn't being detected if the\n\t  child class was defined using the A::B notation.\n\nMon Nov  8 00:14:13 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: add setup for mignw32 cross compiling.\n\t  [ruby-talk:119413]\n\nSun Nov  7 23:49:26 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bind-event methods accept multi substitution\n\t  arguments.\n\n\t* ext/tk/lib/tk/canvas.rb: ditto.\n\n\t* ext/tk/lib/tk/canvastag.rb: ditto.\n\n\t* ext/tk/lib/tk/text.rb: ditto.\n\n\t* ext/tk/lib/tk/texttag.rb: ditto.\n\n\t* ext/tk/lib/tkextlib: ditto.\n\nSat Nov  6 14:58:44 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/server.rb (WEBrick::HTTPServer#start): remove\n\t  :DoNotReverseLookup option. (Socket#do_not_reverse_lookup is a\n\t  ruby 1.9 feature)\n\nSat Nov  6 11:31:04 2004  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb (_parse): checks whether zone was given.\n\nSat Nov  6 00:46:27 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_locktmp): check STR_TMPLOCK flag before\n\t  locking.  [ruby-dev:24727]\n\nFri Nov  5 18:12:42 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/scrollable.rb: divide Scrollable module into\n\t  X_Scrollable and Y_Scrollable\n\n\t* ext/tk/lib/tk/entry.rb: include X_Scrollable instead of Scrollable\n\n\t* ext/tk/lib/tk/autoload.rb: define autoload for X_Scrollable and\n\t  Y_Scrollable\n\nFri Nov  5 16:05:32 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: TkComm._at() supprts both of \"@x,y\" and \"@x\"\n\nFri Nov  5 13:22:58 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/text.rb: sorry. bug fix again.\n\nFri Nov  5 13:17:54 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/text.rb: bug fix\n\nFri Nov  5 08:52:48 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_mark): stricter GC stack check.\n\nFri Nov  5 08:52:48 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_mark): stricter GC stack check.\n\nFri Nov  5 08:34:43 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_gsub): should have removed rb_str_unlocktmp(str).\n\t  [ruby-dev:24708]\n\nThu Nov  4 21:25:38 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_gsub): string modify check no longer based on\n\t  tmplock.  [ruby-dev:24706]\n\nThu Nov  4 19:27:46 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* io.c (rb_f_open): fix typo.\n\nThu Nov  4 15:02:14 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/variable.rb: forget to initialize instance_variables\n\t  of TkVarAccess objects\n\nThu Nov  4 09:11:35 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_mark): enable GC stack checking.\n\nThu Nov  4 03:11:33 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_gsub): lock strings temporarily.  [ruby-dev:24687]\n\n\t* ext/socket/socket.c (s_recvfrom): tmplock input buffer.\n\t  [ruby-dev:24705]\n\nWed Nov  3 22:32:12 2004  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* process.c: On NetBSD don't use setruid() and setrgid().\n\nWed Nov  3 22:24:17 2004  Daigo Moriwaki  <techml@sgtpepper.net>\n\n\t* lib/webrick/httpauth/digestauth.rb: use Base64.encode64 to\n\t  avoid warnings.\n\nWed Nov  3 17:19:59 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_uniq_bang): do not push frozen string from hash\n\t  table.  [ruby-dev:24695]\n\n\t* array.c (rb_ary_and): ditto.\n\n\t* array.c (rb_ary_or): ditto.\n\nWed Nov  3 17:13:02 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* io.c (pipe_open): fix compile error\n\nWed Nov  3 16:58:07 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: support to use different Tcl commands between\n\t  configure and configinfo\n\n\t* ext/tk/lib/font.rb: ditto.\n\n\t* ext/tk/lib/itemconfig.rb: support to use different Tcl commands\n\t  between item_configure and item_configinfo\n\n\t* ext/tk/lib/itemfont.rb: ditto.\n\n\t* ext/tk/extconf.rb: install SUPPORT_STATUS\n\n\t* ext/tk/lib/tkextlib: some bug fixes (see ext/tk/ChangeLog.tkextlib)\n\nWed Nov  3 16:30:41 2004  NARUSE, Yui  <naruse@ruby-lang.org>\n\n\t* ext/nkf: follow nkf 2.0.4\n\nWed Nov  3 15:53:34 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* test/rss/test_maker_*.rb: added tests for RSS Maker.\n\n\t* lib/rss/maker.rb: added RSS Maker.\n\n\t* lib/rss/maker/*.rb: ditto.\n\nTue Nov  2 16:35:57 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/enumerator/enumerator.c (each_cons_i): pass copy of an\n\t  internal consequent array.  [ruby-talk:118691]\n\nTue Nov  2 16:05:21 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_f_fork): need to flush stdout and stderr before\n\t  fork(2).  [ruby-talk:117715]\n\nTue Nov  2 01:20:09 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): nail down dyna_var node when Proc object\n\t  or continuation is created.  [ruby-dev:24671]\n\nMon Nov  1 13:59:28 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb (MANIFEST): do not use anymore, use extconf.rb instead.\n\n\t* ext/enumerator/extconf.rb, ext/fcntl/extconf.rb,\n\t  ext/stringio/extconf.rb: added.\n\n\t* MANIFEST, ext/**/MANIFEST: removed.\n\n\t* README.EXT, README.EXT.ja: remove MANIFEST stuff.\n\nMon Nov  1 01:14:52 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_open): create copy of popen specifier.  [ruby-dev:24656]\n\nMon Nov  1 00:36:48 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* main.c (_stklen): move to gc.c.\n\nSun Oct 31 00:22:28 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_locktmp): lock string temporarily.\n\n\t* string.c (str_independent): add tmplock check.\n\n\t* io.c (io_write): lock output string temporarily.\n\t  [ruby-dev:24649]\n\n\t* io.c (io_write): use rb_str_locktmp().\n\n\t* io.c (read_all): ditto.\n\nSat Oct 30 06:53:24 2004  Peter Vanbroekhoven  <peter.vanbroekhoven@cs.kuleuven.ac.be>\n\n\t* eval.c (rb_eval): NODE_XSTR should pass copy of literal string.\n\nSat Oct 30 00:19:40 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_sort_by): protect continuation jump in.\n\t  [ruby-dev:24642]\n\nFri Oct 29 21:27:51 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_check_initialized): new function to check uninitialized\n\t  object.  [ruby-talk:118234]\n\n\t* file.c (rb_file_path), io.c (rb_io_closed): check if initialized.\n\nFri Oct 29 10:00:30 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): forget to free some memory chunks.\n\t  [ruby-core:03611]\n\n\t* eval.c (ruby_cleanup): ruby_finalize_1 may cause exception,\n\t  should be wrapped by PUSH_TAG/POP_TAG().  [ruby-dev:24627]\n\nThu Oct 28 08:42:02 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (argf_forward): use ANSI style.\n\t  (argf_read): call argf_forward with argv argument.\n\t  [ruby-dev:24624]\n\nThu Oct 28 23:32:54 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (zstream_detach_input): resets klass of z->input if\n\t  z->input isn't nil.\n\nThu Oct 28 23:19:31 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: prefer relative path.  [ruby-talk:93037]\n\nWed Oct 27 18:49:11 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* gc.c: prototype; rb_io_fptr_finalize() doesn't return any value\n\t  at this version.\n\nWed Oct 27 17:27:45 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_sweep): recover ruby_in_compile variable.\n\nWed Oct 27 09:17:30 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (str_gsub): use a string object for exception safeness.\n\t  [ruby-dev:24601]\n\nTue Oct 26 23:52:32 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_getline): rs modification check should not interfere in the loop.\n\nTue Oct 26 23:30:39 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::Context::add_class_or_module):\n\t  Restore correct :nopdoc: behavior with nested classes and modules.\n\nTue Oct 26 18:21:29 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (RESIZE_CAPA): check string attribute before modifying\n\t  capacity member of string structure.  [ruby-dev:24594]\n\nTue Oct 26 11:33:26 2004  David G. Andersen  <dga@lcs.mit.edu>\n\n\t* ext/zlib/zlib.c (gzreader_gets): use memchr() to to gain\n\t  performance.  [ruby-talk:117701]\n\nTue Oct 26 10:56:55 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): raise ArgumentError for extra\n\t  arguments, unless (digit)$ style used.\n\nTue Oct 26 11:33:26 2004  David G. Andersen  <dga@lcs.mit.edu>\n\n\t* ext/zlib/zlib.c (gzreader_gets): use memchr() to to gain\n\t  performance.  [ruby-talk:117701]\n\nTue Oct 26 10:56:55 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): raise ArgumentError for extra\n\t  arguments, unless (digit)$ style used.\n\nMon Oct 25 18:35:39 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (isUNCRoot): should check NUL after '.'.\n\t  [ruby-dev:24590]\n\n\t* win32/win32.c (isUNCRoot): fixed buffer overrun.\n\nMon Oct 25 08:03:26 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (get_backtrace): ignore illegal backtrace.  [ruby-dev:24587]\n\nSun Oct 24 00:41:09 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_load, search_required, rb_require_safe, rb_require): use\n\t  frozen shared string to avoid outside modification.  [ruby-dev:24580]\n\nSat Oct 23 22:18:32 2004  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* eval.c (frame_free): Guy Decoux solved the leak problem.\n\t  Thanks.  [ruby-core:03549]\n\nSat Oct 23 00:20:55 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (zstream_append_input): clear klass for z->input\n\t  to avoid potential vulnerability.\n\n\t* ext/zlib/zlib.c (zstream_run): always use zstream_append_input()\n\t  to avoid SEGV.  [ruby-dev:24568]\n\nFri Oct 22 12:02:28 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_alias): was warning for wrong condition.\n\t  [ruby-dev:24565]\n\nFri Oct 22 10:36:37 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httprequest.rb (WEBrick::HTTPRequest#meta_vars):\n\t  should check if path_info is not nil.\n\nFri Oct 22 00:22:31 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/zlib/zlib.c (zstream_shift_buffer): should restore class\n\t  field of a buffer.  [ruby-dev:24562]\n\nFri Oct 22 00:20:33 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_include): should not treat char as negative value.\n\t  [ruby-dev:24558]\n\nThu Oct 21 21:32:30 2004  IWATSUKI Hiroyuki  <don@na.rim.or.jp>\n\n\t* lib/pstore.rb (PStore#transaction): Use the empty content when a\n\t  file is not found.  [ruby-dev:24561]\n\nThu Oct 21 19:06:15 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpresponse.rb (WEBrick::HTTPResponse#send_body_io):\n\t  ensure to close @body. (http://bugs.debian.org/277520)\n\nThu Oct 21 00:36:41 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_alias): should warn on method discarding.\n\t  [ruby-dev:24546]\n\n\t* ext/zlib/zlib.c (zstream_expand_buffer_into): hide internal\n\t  string buffer by clearing klass.  [ruby-dev:24548]\n\nWed Oct 20 19:45:13 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_gsub): \treentrant check.  [ruby-dev:24432]\n\n\t* backport all SEGV bug fixes from CVS HEAD.  [ruby-dev:24536]\n\nWed Oct 20 04:17:55 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dbm/dbm.c (fdbm_delete_if): should check if deleting element\n\t  is a string.  [ruby-dev:24490]\n\n\t* ext/sdbm/init.c (fsdbm_delete_if): ditto.\n\nWed Oct 20 01:37:18 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_times): Array#* should return an instance of\n\t  the class of right operand.  [ruby-dev:24526]\n\n\t* ext/zlib/zlib.c (zstream_detach_buffer): should not expose\n\t  class-less object to Ruby world. [ruby-dev:24530]\n\n\t* eval.c (proc_dup): provide Proc#dup as well.  [ruby-talk:116915]\n\n\t* eval.c (ruby_exec): stack marking position may be higher than\n\t  expected.  thanks to Guy Decoux.  [ruby-core:03527]\n\nTue Oct 19 22:43:12 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_attr): If\n\t  we come across 'attr' in a context where it isn't\n\t  followed by a symbol, just issue a warning.\n\nTue Oct 19 20:41:37 2004  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole.c(ole_invoke): retrieve the result value when\n\t  retrying the IDispatch::invoke.\n\nTue Oct 19 17:24:11 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): block string buffer modification during\n\t  rb_io_fread() by freezing it temporarily. [ruby-dev:24479]\n\n\t* dir.c (rb_push_glob): block call at once the end of method.\n\t  [ruby-dev:24487]\n\n\t* ext/enumerator/enumerator.c (enum_each_slice): remove\n\t  rb_gc_force_recycle() to prevent potential SEGV.\n\t  [ruby-dev:24499]\n\n\t* ext/zlib/zlib.c (zstream_expand_buffer): hide internal string\n\t  buffer by clearing klass.  [ruby-dev:24510]\n\nTue Oct 19 16:12:18 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c: backport from CVS HEAD\n\nTue Oct 19 08:54:26 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* intern.h, object.c (rb_class_inherited_p): export.\n\nTue Oct 19 08:46:57 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_upto): method result must be checked.  [ruby-dev:24504]\n\n\t* eval.c (error_print): ditto.  [ruby-dev:24519]\n\nMon Oct 18 23:37:05 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (r_object0): check inheritance by the internal function.\n\t  [ruby-dev:24515]\n\nMon Oct 18 15:58:01 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* range.c (range_step, range_each): need cast.\n\nFri Oct 29 16:34:19 2004  Daiki Ueno  <ueno@unixuser.org>\n\n\t* misc/ruby-mode.el (ruby-parse-partial): Parse the rest of the\n\t  line after opening heredoc identifier.  [ruby-dev:24635]\n\nMon Oct 18 07:26:21 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (rb_file_truncate): discard read buffer before truncation.\n\t  [ruby-dev:24197]\n\nMon Oct 18 02:11:21 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/config.rb (WEBrick::Config::General): add default values:\n\t  - WEBrick::Config[:DoNotReverseLookup]\n\t  - WEBrick::Config[:RequestCallback] (it used as an alias of\n\t    :RequestHandler in WEBrick::HTTPServer#run)\n\t  - WEBrick::Config::FileHandler[:AcceptableLanguages]\n\n\t* lib/webrick/httpservlet/filehandler.rb\n\t  (WEBrick::HTTPServlet::FileHandler#set_filename): search files\n\t  having suffix of language-name which Accept-Language header field\n\t  includes if :AcceptableLanguages options is present.\n\n\t* lib/webrick/httpservlet/filehandler.rb\n\t  (WEBrick::HTTPServlet::FileHandler#get_servlet): new method to\n\t  search servlet correspond to the suffix of filename.\n\n\t* lib/webrick/httprequest.rb: add attributes access methods: accept,\n\t  accept_charset, accept_encoding, accept_language, content_length\n\t  and content_type.\n\n\t* lib/webrick/httpresponse.rb: add attribute access methods:\n\t  content_length, content_length=, content_type and content_type=.\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils.mime_types):\n\t  use the second suffix to detect media type. (the first suffix\n\t  may be a language name.)\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils.parse_qvalues):\n\t  add method to parse Accept header field. it returns an Array of\n\t  values sorted by the qvalues.\n\nMon Oct 18 02:04:11 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpserver.rb (WEBrick::HTTPServer#virtual_host): new\n\t  method to register virtual hosting servers.\n\n\t* lib/webrick/server.rb (WEBrick::GenericServer#accept): call\n\t  do_not_reverse_lookup for each socket if :DoNotReverseLookup\n\t  is set.  [ruby-core:02357]\n\nMon Oct 18 00:42:45 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_s_getservbyaname): protocol string\n\t  might be altered.  [ruby-dev:24503]\n\n\t* string.c (rb_str_upto): check if return value from succ is a\n\t  string.  [ruby-dev:24504]\n\nSun Oct 17 23:03:48 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/timer.rb: TkTimer#start and restart accept a block\n\nSun Oct 17 13:05:04 2004  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (fole_func_methods): correct argument mismatch.\n\t* ext/win32ole/win32ole.c (fole_get_methods): ditto.\n\t* ext/win32ole/win32ole.c (fole_put_methods): ditto.\n\t* ext/win32ole/tests/testWIN32OLE.rb: add test for WIN32OLE#ole_func_methods\n\t  WIN32OLE#ole_get_methods, WIN32OLE#ole_put_methods\n\nSat Oct 16 14:45:28 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/0.9.rb (RSS::Rss#to_s): removed garbage.\n\nSat Oct 16 13:42:49 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/: untabified.\n\t* test/rss/: untabified.\n\t* lib/rss/0.9.rb (RSS::Rss#to_s): inent -> indent.\n\nSat Oct 16 13:34:56 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss: supported prety print.\n\t* test/rss/test_1.0.rb: added test for calculating default indent size.\n\nFri Oct 15 18:04:35 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/timer.rb: TkTimer.new(interval, loop){ ... } is\n\t  acceptable. Add TkTimer.start ( == new + start ).\n\nFri Oct 15 12:43:09 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (Init_stack): make prototype declaration consistent with\n\t  the definition in gc.c.\n\nThu Oct 14 14:34:01 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (MODE_BINMODE, MODE_BINARY): fixed reversed condition.\n\nThu Oct 14 13:33:59 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: added link to Tutorial.\n\nMon Oct 11 13:48:20 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/*: untabify\n\nSun Oct 10 12:32:08 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::parse_require): Allow 'require'\n\t  to be used as a variable name\n\nSat Oct  9 21:23:37 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/converter.rb: changed to try to use Iconv for default\n\t  conversion.\n\n\t* lib/rss/rss.rb: 0.0.9 -> 0.1.0.\n\nSat Oct  9 19:50:36 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_getline): should not treat char as negative value.\n\t  [ruby-dev:24460]\n\nFri Oct  8 09:49:32 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): pointer modification check before each\n\t  iteration.  [ruby-dev:24445]\n\nFri Oct  8 01:13:05 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/optiondb.rb: make it more secure\n\nThu Oct  7 23:47:57 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/scrollbar.rb: When 'set' operation, a scrollbar\n\t  cannot propagate view port information from the source widget\n\t  (that calls 'set') to other assigned widgets.\n\nThu Oct  7 17:36:25 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: When CHILDKILLED and so on, Tk.errorCode returns\n\t  a Fixnum for 2nd element (it's pid) of the return value.\n\nThu Oct  7 12:55:04 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_read): should freeze buffer before thread context\n\t  switch. [ruby-dev:24442]\n\n\t* pack.c (pack_unpack): string conversion should at the top of the\n\t  method.  [ruby-dev:24439]\n\n\t* io.c (io_read): buffer should be frozen only after the length\n\t  check.  [ruby-dev:24440]\n\nThu Oct  7 02:56:43 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c: use FMODE_APPEND.\n\nThu Oct  7 01:05:33 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add Tk.errorInfo and Tk.errorCode\n\nThu Oct  7 00:08:37 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_s_sysopen): preserve path in the buffer allocated by\n\t  ALLOCA_N() to prevent modification.  [ruby-dev:24438]\n\nWed Oct  6 09:21:00 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_mode_flags): preserve append mode flag.\n\t  [ruby-dev:24436]\n\n\t* io.c (rb_io_modenum_mode): do not use external output buffer.\n\n\t* string.c (rb_str_justify): differ pointer retrieval to prevent\n\t  padding string modification.  [ruby-dev:24434]\n\n\t* range.c (range_each_func): allow func to terminate loop by\n\t  returning RANGE_EACH_BREAK.\n\n\t* range.c (member_i): use RANGE_EACH_BREAK. [ruby-talk:114959]\n\nMon Oct  4 14:04:14 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_file_open_internal, rb_io_reopen): fname might be altered\n\t  while GC.  [ruby-dev:24408]\n\nMon Oct  4 12:53:45 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/optiondb.rb: support definition of command\n\t  resources on widgets\n\n\t* ext/tk/lib/tk/image.rb: bug fix\n\nSun Oct  3 21:20:03 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (TEXT_REGEXP): allow 8-bit characters for the german\n\t  version of Microsoft Exchange Server. (backported from HEAD)\n\n\t* lib/net/imap.rb (RTEXT_REGEXP): ditto.\n\n\t* lib/net/imap.rb (CTEXT_REGEXP): ditto.\n\nSat Oct  2 20:34:22 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* node.h (NEW_DVAR): extra semicolon.\n\nSat Oct  2 00:42:20 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_byte): retrieve pointer from string value for each\n\t  time.  [ruby-dev:24404]\n\n\t* marshal.c (r_bytes0): ditto.\n\n\t* enum.c (sort_by_i): re-entrance check added.  [ruby-dev:24399]\n\n\t* io.c (io_read): should freeze all reading buffer.\n\t  [ruby-dev:24400]\n\n\t* string.c (rb_str_sum): should use bignums when bits is greater\n\t  than or equals to sizeof(long)*CHAR_BITS. [ruby-dev:24395]\n\n\t* eval.c (specific_eval): defer pointer retrieval to prevent\n\t  unsafe sourcefile string modification.  [ruby-dev:24382]\n\n\t* eval.c (specific_eval): defer pointer retrieval to prevent\n\t  unsafe sourcefile string modification.  [ruby-dev:24382]\n\n\t* string.c (rb_str_sum): wrong cast caused wrong result.\n\t  [ruby-dev:24385]\n\n\t* enum.c (enum_sort_by): hide temporary array from\n\t  ObjectSpace.each_object.  [ruby-dev:24386]\n\n\t* string.c (rb_str_sum): check was done with false pointer.\n\t  [ruby-dev:24383]\n\n\t* string.c (rb_str_sum): string may be altered.  [ruby-dev:24381]\n\nMon Oct 11 17:51:34 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_popen): get mode string via rb_io_flags_mode() to\n\t  avoid mode string modification.  [ruby-dev:24454]\n\n\t* io.c (rb_io_getline_fast): should take delim as unsigned char to\n\t  distinguish EOF and '\\377'.  [ruby-dev:24460]\n\n\t* io.c (rb_io_getline): add check for RS modification.\n\t  [ruby-dev:24461]\n\n\t* enum.c (enum_sort_by): use qsort() directly instead using\n\t  rb_iterate().  [ruby-dev:24462]\n\n\t* enum.c (enum_each_with_index): remove rb_gc_force_recycle() to\n\t  prevent access to recycled object (via continuation for\n\t  example).  [ruby-dev:24463]\n\nFri Oct  1 11:40:14 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_eval): defer pointer retrieval to prevent unsafe\n\t  sourcefile string modification.  [ruby-dev:24373]\n\n\t* io.c (io_read): block string buffer modification during\n\t  rb_io_fread() by freezing it temporarily. [ruby-dev:24366]\n\n\t* io.c (rb_io_s_popen): mode argument may be altered.\n\t  [ruby-dev:24375]\n\n\t* file.c (rb_file_s_basename): ext argument may be altered.\n\t  [ruby-dev:24377]\n\n\t* enum.c (enum_sort_by): use NODE instead of 2 element arrays.\n\t  [ruby-dev:24378]\n\n\t* string.c (rb_str_chomp_bang): StringValue() may change the\n\t  receiver.  [ruby-dev:24371]\n\nFri Oct  1 11:25:20 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/grid.rb: revive TkGrid.grid\n\n\t* ext/tk/lib/tk/pack.rb: revive TkPack.pack\n\n\t* ext/tk/lib/tk/place.rb: revive TkPlace.place\n\nThu Sep 30 00:50:44 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_init): bug fix\n\n\t* ext/tk/tkutil.c (get_eval_string_core): accept a Regexp object\n\n\t* ext/tk/lib/multi-tk.rb: fix bug on 'exit' operation\n\n\t* ext/tk/lib/tk/text.rb: 'tksearch' accepts a Regexp object as a\n\t  matting pattern argument\n\nWed Sep 29 10:58:07 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* enum.c (sort_by_i): internally used object must not be changed\n\t  outside.  [ruby-dev:24368]\n\nMon Sep 27 13:46:45 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* intern.h, struct.c (rb_struct_s_members, rb_struct_members): public\n\t  accessors.  [ruby-dev:24342]\n\n\t* marshal.c (w_object, r_object0): use accessors.\n\nMon Sep 27 09:14:03 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK.\n\t  [ruby-talk:113807]\n\nFri Sep 24 16:09:42 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): propagate DVAR_DONT_RECYCLE on termination\n\t  to avoid double call to rb_gc_force_recycle(). [ruby-dev:24311]\n\nFri Sep 24 08:29:45 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_subseq): original object might be modified after\n\t  sharing data creation.  [ruby-dev:24327]\n\n\t* array.c (rb_ary_replace): ditto.\n\n\t* array.c (ary_make_shared): freeze shared array. [ruby-dev:24325]\n\n\t* struct.c (struct_members): always check struct size and size of\n\t  members list in the class.  [ruby-dev:24320]\n\nThu Sep 23 09:29:14 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_sub_bang): check if string is not modified\n\t  during iteration.  [ruby-dev:24315]\n\n\t* hash.c (rb_hash_rehash): replace st_foreach() by its deep\n\t  checking counterpart.  [ruby-dev:24310]\n\nWed Sep 22 13:38:12 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_rehash): add iteration check.  [ruby-dev:24301]\n\n\t* st.c (st_foreach): add deep check.\n\nWed Sep 22 13:06:14 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_call_handler): workaround for Ctrl-C.\n\t  merge from HEAD.\n\nWed Sep 22 00:11:12 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* process.c: Add documentation for fork()\n\nWed Sep 22 09:04:41 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_collect_bang): element size might change during\n\t  comparison.  [ruby-dev:24300]\n\n\t* array.c (rb_ary_reject_bang): ditto. [ruby-dev:24300]\n\n\t* array.c (rb_ary_eql): ditto. [ruby-dev:24300]\n\nTue Sep 21 18:29:49 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_equal): merge miss.\n\n\t* array.c (rb_ary_uniq_bang): element size might change during\n\t  comparison.  [ruby-dev:24298]\n\nMon Sep 20 00:24:19 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_sort_by): do not use qsort directly.  use\n\t  rb_ary_sort_bang() instead.  [ruby-dev:24291]\n\n\t* enum.c (enum_sort_by): pedantic type check added.\n\t  [ruby-dev:24291]\n\n\t* hash.c (rb_hash_foreach_iter): check iter_lev after each\n\t  iteration.  [ruby-dev:24289]\n\n\t* array.c (rb_ary_and): element size might change during\n\t  comparison.  [ruby-dev:24290]\n\n\t* array.c (rb_ary_or): ditto. [ruby-dev:24292]\n\n\t* array.c (rb_ary_equal): wrong fix. [ruby-dev:24286]\n\nSat Sep 18 15:02:22 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_equal): element size might change during\n\t  comparison.  [ruby-dev:24254]\n\n\t* array.c (rb_ary_diff): ditto. [ruby-dev:24274]\n\n\t* array.c (rb_ary_select): ditto. [ruby-dev:24278]\n\n\t* array.c (rb_ary_delete): ditto. [ruby-dev:24283]\n\n\t* array.c (rb_ary_rindex): ditto. [ruby-dev:24275]\n\n\t* array.c (rb_ary_initialize): element size might change during\n\t  initializing block.  [ruby-dev:24284]\n\nSat Sep 18 14:10:23 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_s_chdir): avoid memory leak and unnecessary chdir to\n\t  the original directory when exception has caused in changing\n\t  direcotry or within block.  thanks to Johan Holmberg\n\t  <holmberg@iar.se> [ruby-core:03446]\n\nFri Sep 17 20:20:27 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mkdir_p): backport from CVS HEAD 1.45. [ruby-core:03420]\n\nFri Sep 17 17:11:08 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_delete): element comparison might change array\n\t  size. [ruby-dev:24273]\n\n\t* file.c (rb_file_truncate): clear stdio buffer before truncating\n\t  the file.  [ruby-dev:24191]\n\n\t* ext/digest/digest.c: use rb_obj_class() instead of CLASS_OF\n\t  which might return singleton class.  [ruby-dev:24202]\n\nFri Sep 17 16:07:09 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: improve exit operation\n\nFri Sep 17 15:01:57 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix SEGV when (thread_)vwait or\n\t  (thread_)tkwait\n\n\t* ext/tk/lib/tk.rb: add alias wait_window to wait_destroy\n\n\t* ext/tk/lib/multi-tk.rb: support calling 'mainloop' on slave\n\t  interpreters (however, the 'real' eventloop must be run on the\n\t  Default Master IP)\n\n\t* ext/tk/lib/remote-tk.rb: follow the changes of ext/tk/lib/multi-tk.rb\n\n\t* ext/tk/sample/remote-ip_sample2.rb: ditto\n\n\t* ext/tk/sample/tkoptdb-safeTk.rb: ditto\n\nThu Sep 16 18:12:32 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI#start): should set REMOTE_USER\n\t  to request.user attribute.\n\n\t* lib/webrick/httpservlet/filehandler.rb\n\t  (WEBrick::HTTPServlet::FileHandler#initialize): should expand\n\t  the pathname of document root directory.\n\nThu Sep 16 15:49:28 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_intern): protect string argument from GC.\n\t  [ruby-core:03411]\n\nWed Sep 15 20:22:23 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tkoptdb-safeTk.rb: fix a bug depend on the changes\n\t  of MultiTkIp\n\nTue Sep 14 23:54:11 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp#eval_string was en-bugged by\n\t  the previous changes.\n\nTue Sep 14 23:45:44 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::TextFormatter::TextFormatter.for):\n\t  Add Eric Hodel's simpleformatter.\n\nTue Sep 14 16:59:37 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix SEGV\n\n\t* ext/tk/lib/multi-tk.rb: improve safe-level handling of argument proc\n\n\t* ext/tk/sample/multi-ip_sample.rb: rename of old 'safe-tk.rb'\n\n\t* ext/tk/sample/safe-tk.rb: new sample script\n\nTue Sep 14 00:15:15 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/zlib/zlib.c: backported from HEAD.\n\nMon Sep 13 19:16:33 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (blk_copy_prev): need frame_dup().  [ruby-dev:24103]\n\nMon Sep 13 16:23:27 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp.new_master and new_slave accept\n\t  safe-level value argument\n\nMon Sep 13 10:20:45 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* object.c (nil_inspect): fix typo.\n\nMon Sep 13 01:03:02 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: improve control of preserv/release tcltkip\n\n\t* ext/tcltklib/tcltklib.c: store original 'exit' command\n\n\t* ext/tk/tkutil.c: fix(?) SEGV\n\nSun Sep 12 23:46:23 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* util.c (ruby_strdup): remove unnecessary code. (xmalloc never\n\t  returns NULL.)\n\n\t* util.c (ruby_getcwd): fix memory leak on failure.\n\nSun Sep 12 02:41:58 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: add TclTkIp#allow_ruby_exit? and\n\t  allow_ruby_exit=\n\n\t* ext/tk/lib/multi-tk.rb: ditto.\n\n\t* ext/tk/lib/remote-tk.rb: ditto.\n\n\t* ext/tcltklib/MANUAL.euc: ditto.\n\n\t* ext/tcltklib/MANUAL.eng: ditto.\n\n\t* ext/tcltklib/tcltklib.c: fix some reasons of SEGV\n\n\t* ext/tk/tkutil.c: ditto.\n\n\t* ext/tk/lib/multi-tk.rb: ditto.\n\n\t* ext/tk/lib/tk/timer.rb: ditto.\n\nSat Sep 11 16:09:46 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb: Fix up cross-file class merging.\n\nFri Sep 10 20:20:53 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_merge_tklist): fix suspicious\n\t  pointer conversion.\n\nFri Sep 10 02:43:54 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/template/kilmer.rb: James Buck's\n\t  patch for call-seq.\n\nThu Sep  9 13:58:56 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_init): change flag value for setting\n\t  'argv' and 'argv0' variable\n\n\t* ext/tk/lib/remote-tk.rb: follow changes of multi-tk.rb\n\nThu Sep  9 11:46:18 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::do_classes): Allow\n\t  spaces aroun parameter to define_method_under (James Buck)\n\nWed Sep  8 18:44:03 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_write): zero fill a gap if exsts.\n\t  [ruby-dev:24190]\n\nWed Sep  8 15:19:49 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_init): cannot create a IP at level 4\n\n\t* ext/tk/lib/multi-tk.rb: improve 'exit' operation, security check,\n\t  and error treatment\n\n\t* ext/tk/lib/multi-tk.rb: allow a trusted slave IP to create slave IPs\n\n\t* ext/tk/lib/tk/listbox.rb: add TkListbox#value, value=, clear,\tand\n\t  erase\n\n\t* ext/tk/lib/tk/text.rb: add TkText#clear and erase\n\nTue Sep  7 15:17:49 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): break immediately if a\n\t  socket is non-blocking.  [ruby-talk:111654]\n\nMon Sep  6 11:08:50 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tk/lib/tk/menu.rb(TkOptionMenubutton#insert): call correct method\n\nMon Sep  6 11:00:47 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_s_chdir): the patch to shut up false warning when\n\t  exception occurred within a block.  a patch was given from Johan\n\t  Holmberg <holmberg at iar.se>.  [ruby-core:03292]\n\nMon Sep  6 07:51:42 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (cvar_cbase): singletons should refer outer cvar scope.\n\t  [ruby-dev:24223]\n\n\t* eval.c (rb_load): should preserve previous ruby_wrapper value.\n\t  [ruby-dev:24226]\n\nSat Sep  4 01:14:57 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (cvar_cbase): class variables cause SEGV in\n\t  instance_eval() for fixnums and symbols. [ruby-dev:24213]\n\nFri Sep  3 17:47:58 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (make_struct): remove redefining constant when\n\t  conflict.  [ruby-dev:24210]\n\nFri Sep  3 11:31:44 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: Tk.after makes TkCore::INTERP.tk_cmd_tbl grow\n\t  [ruby-dev:24207]\n\nFri Sep  3 02:12:48 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix typo [ruby-talk:111266]\n\n\t* ext/tk/lib/tk/text.rb: fix typo\n\n\t* ext/tk/lib/multi-tk.rb: improve safe-level treatment on slave IPs\n\nFri Sep  3 01:54:20 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: already built-in libraries satisfy dependencies.\n\t  [ruby-dev:24028]\n\nThu Sep  2 11:36:20 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (rb_obj_instance_eval): backported from HEAD.\n\nWed Sep  1 21:18:25 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tk/lib/tk/spinbox.rb: fix typo\n\nTue Aug 31 18:24:04 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/tk/tkutil.c (cbsubst_init): fix memory leak\n\n\t* ext/tk/tkutil.c (cbsubst_get_all_subst_keys): fix SEGV\n\nTue Aug 31 16:04:22 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_delete): when a tcltkip is deleted,\n\t  destroy its root widget\n\nTue Aug 31 12:30:36 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (del_root): fix SEGV\n\nMon Aug 30 23:11:06 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_driver.rb (and others): ri now merges documentation\n\t  if it finds the same class in multiple places.\n\nMon Aug 30 22:40:30 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: 'restart' method accepts arguments\n\nMon Aug 30 21:50:14 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* object.c: Add RDoc for Module.included.\n\nMon Aug 30 15:10:46 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (GNU/k*BSD): fixed FTBFS on GNU/k*BSD. [ruby-dev:24051]\n\nMon Aug 30 11:29:35 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (CreateChild): strip trailing spaces. [ruby-dev:24143]\n\t  merge from HEAD.\n\nSun Aug 29 14:08:56 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: compile error on bcc32 [ruby-dev:24081]\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp#eval_string does not work\n\nSat Aug 28 23:04:41 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_and): protect parameters from GC.\n\t  [ruby-talk:110664]\n\nThu Aug 26 04:38:29 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* eval.c (return_jump): Minor typo in error message. Now reads\n\t  \"return can't jump across threads\".\n\nTue Aug 24 17:30:00 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::FileStore#initialize): do not\n\t  use a session id as a filename. (backported from HEAD)\n\n\t* lib/cgi/session/pstore.rb (CGI::Session::PStore#initialize): ditto.\n\n\t* lib/cgi/session/pstore.rb (CGI::Session::PStore#initialize): use\n\t  Dir::tmpdir. (backported from HEAD)\n\nTue Aug 24 14:40:16 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::FileStore#initialize): untaint\n\t  session id after check. (backported from HEAD)\n\nTue Aug 24 09:09:01 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509attr.c (ossl_x509attr_initialize): d2i\n\t  functions may replace the pointer indicated by the first argument.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509ext_initialize): ditto.\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_initialize): ditto.\n\nMon Aug 23 14:04:51 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_read):\n\t  - should return an empty string if specified length to read is 0.\n\t  - should check for pending data and wait for fd before reading.\n\t  - call underlying IO's sysread if SSL session is not started.\n\t  [ruby-dev:24072], [ruby-dev:24075]\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_write):\n\t  - call underlying IO's syswrite if SSL session is not started.\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_pending): new method\n\t  OpenSSL::SSL#pending.\n\n\t* ext/openssl/lib/openssl/buffering.rb: should not use select.\n\nMon Aug 23 12:40:56 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/resolv.rb (Config.default_config_hash): when multiple domains\n\t  are set, Win32::Resolv.get_resolv_info returns Array.\n\nSun Aug 22 01:15:31 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpproxy.rb (WEBrick::HTTPProxyServer#proxy_connect):\n\t  should call :ProxyContentHandler before finishing CONNECT.\n\nSat Aug 21 06:41:16 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/tcltklib/extconf.rb (find_tcl, find_tk): find stub library.\n\n\t* lib/mkmf.rb (arg_config, with_config): deal with '-' and '_'\n\t  uniformly.  [ruby-dev:24118]\n\nThu Aug 19 16:29:45 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: Fail to treat a hash value of 'font' option.\n\n\t* ext/tk/lib/tk.rb: bindinfo cannot return '%' substiturion infomation.\n\n\t* ext/tk/lib/menu.rb: typo bug.\n\nThu Aug 19 15:15:24 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (free_dir): fix memory leak.  reported by yamamoto\n\t  madoka.\n\nThu Aug 19 11:00:00 2004  Akiyoshi, Masamichi  <masamichi.akiyoshi@hp.com>\n\n\t* dln.c (dln_load): Modify to call lib$find_image_symbol for VMS.\n\t* io.c (rb_io_fwrite): Use fputc() for VMS non-stream file.\n\nThu Aug 19 06:07:45 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/token.c: re2c no longer compiled with bit vectors.  caused\n\t  problems for non-ascii characters. [ruby-core:03280]\n\t* ext/syck/implicit.c: ditto.\n\t* ext/syck/bytecode.c: ditto.\n\n\t* lib/yaml/baseemitter.rb: folding now handles double-quoted strings,\n\t  fixed problem with extra line feeds at end of folding, whitespace\n\t  opening scalar blocks.\n\n\t* lib/yaml/rubytypes.rb: subtelties in handling strings with\n\t  non-printable characters and odd whitespace patterns.\n\nWed Aug 18 23:41:33 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb (rbuf_fill): OpenSSL::SSL::SSLSocket has its own\n\t  buffer, select(2) might not work. [ruby-dev:24072]\n\nWed Aug 18 17:10:12 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/tcltklib/stubs.c (ruby_tcltk_stubs): need to call\n\t  Tcl_FindExecutable() for Tcl/Tk 8.4.\n\nWed Aug 18 12:52:55 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_obj_instance_eval): evaluates under special singleton\n\t  classes as for special constants.\n\nTue Aug 17 17:20:59 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_reopen): should clear allocated OpenFile.  pointed\n\t  out by Guy Decoux. [ruby-core:03288]\n\nTue Aug 17 01:36:32 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/usage.rb: Remove extra indent. Tidy 'ri' option\n\t  parsing so RDoc::usage plays better with OptionParser.\n\nSat Aug 14 13:09:10 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: backport from CVS HEAD (rev1.44).\n\n\t* lib/fileutils.rb: cp_r should copy symlink itself, except cp_r\n\t  root.\n\n\t* lib/fileutils.rb: new option mv :force.\n\n\t* lib/fileutils.rb: new module FileUtils::DryRun.\n\nSat Aug 14 02:48:16 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/usage.rb: Added. Allows command line programs\n\t  to report usage using their initial RDoc comment.\n\nFri Aug 13 13:23:17 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils.parse_range_header):\n\t  fix regex for range-spec.\n\n\t* lib/webrick/httpservlet/filehandler.rb\n\t  (WEBrick::HTTPServlet::DefaultFileHandler#make_partial_content):\n\t  multipart/byteranges response was broken.\n\n\t* lib/webrick/httpservlet/erbhandler.rb\n\t  (WEBrick::HTTPServlet::ERBHandler#do_GET): should select media type\n\t  by suffix of script filename.\n\n\t* lib/xmlrpc/server.rb: refine example code.\n\nWed Aug 11 17:17:50 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (RPATHFLAG): stop setting RPATHFLAG on Interix.\n\nSun Aug  8 00:43:31 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/implicit.c: added sexagecimal float#base60.\n\n\t* ext/syck/rubyext.c (yaml_org_handler): ditto.\n\n\t* lib/token.c: indentation absolutely ignored when processing flow\n\t  collections.  plain scalars are trimmed if indentation follows in\n\t  an ambiguous flow collection.\n\nSat Aug  7 00:50:01 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/zlib/zlib.c: Zlib::GzipReader#read(0) returns \"\" instead of nil.\n\nTue Aug  3 13:49:20 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/namespace.rb: bug fix\n\n\t* ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: add Tk::TreeCtrl.loupe\n\nMon Aug  2 18:04:21 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/msgcat.rb (set_translation): bug fix (fail to set\n\t  trans_str to the same as src_str when trans_str is not given.)\n\nMon Aug  2 11:53:06 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::Context::find_symbol): Fix infinite recursion\n\t  looking up some top level symbols (batsman)\n\nMon Aug  2 11:48:29 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::do_methods): Allow '.'s in\n\t  variable names to support SWIG generated files (Hans Fugal)\n\nSat Jul 31 17:40:16 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-expr-beg, ruby-parse-partial,\n\t  ruby-calculate-indent, ruby-move-to-block, ruby-forward-sexp,\n\t  ruby-backward-sexp): keywords must match word-wise.\n\nSat Jul 31 05:47:37 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml.rb (YAML::load_file, YAML::parse_file): added.\n\n\t* lib/yaml/rubytypes.rb: exceptions were using an older\n\t  YAML.object_maker. [ruby-core:03080]\n\n\t* ext/syck/token.c (sycklex_yaml_utf8): using newline_len to\n\t  handline CR-LFs.  \"\\000\" was showing up on folded blocks which\n\t  stopped at EOF.\n\n\t* ext/syck/token.c: re2c compiled with bit vectors now.\n\t* ext/syck/implicit.c: ditto.\n\t* ext/syck/bytecode.c: ditto.\n\nFri Jul 30 16:10:54 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_fromUTF8_core): raise ArgumentError when\n\t  the unknown encoding name is given.\n\n\t* ext/tcltklib/tcltklib.c (lib_toUTF8_core): ditto.\n\n\t* ext/tk/lib/tk.rb (Tk::Encoding.encoding_convertfrom): bug fix.\n\n\t* ext/tk/lib/tk.rb (Tk::Encoding.encoding_convertto): ditto.\n\nWed Jul 28 18:59:17 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::initialize): remove at_exit code for CGI_PARAMS\n\t  and CGI_COOKIES.  they will no longer be used.\n\nWed Jul 28 01:04:44 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (run_final): wrong order of data. [ruby-dev:23984]\n\nTue Jul 27 07:05:04 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): copy on write for argument local variable\n\t  assignment.\n\n\t* eval.c (assign): ditto.\n\n\t* eval.c (rb_call0): update ruby_frame->argv with the default\n\t  value used for the optional arguments.\n\n\t* object.c (Init_Object): \"===\" calls rb_obj_equal() directly.\n\t  [ruby-list:39937]\n\nMon Jul 26 11:22:55 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httputils.rb (WEBrick::HTTPUtils.escape): should\n\t  escape space.\n\nSun Jul 25 11:05:21 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* win32/win32.{h,c} (rb_w32_{f,fd,fs}open): workaround for bcc32's\n\t  {f,fd,fs}open bug. set errno EMFILE and EBADF. [ruby-dev:23963]\n\nSat Jul 24 13:32:47 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (rb_range_beg_len): returns Qnil only when \"beg\" points\n\t  outside of a range.  No boundary check for \"end\".\n\nFri Jul 23 16:40:25 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (define_final): should not disclose NODE* to Ruby world.\n\t  [ruby-dev:23957]\n\nFri Jul 23 09:03:16 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (disconnected?): new method. (backported from HEAD)\n\nThu Jul 22 16:41:54 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::FileStore#update): sets the\n\t permission of the session data file to 0600.\n\n\t* lib/cgi/session/pstore.rb (CGI::Session::Pstore#initialize):\n\t  ditto.\n\nThu Jul 22 00:02:21 2004  Masahiro Kitajima  <katonbo@katontech.com>\n\n\t* process.c (rb_f_system): not need to call last_status_set() any\n\t  longer on _WIN32.\n\nTue Jul 20 09:15:17 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* test/fileutils/test_fileutils.rb: File.link raises EINVAL on BeOS.\n\nMon Jul 19 01:15:07 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpservlet/cgihandler.rb\n\t  (WEBrick::HTTPServlet::CGIhandler#do_GET): set SystemRoot environment\n\t  variable to CGI process on Windows native platforms. [ruby-dev:23936]\n\n\t* lib/webrick/httpservlet/cgihandler.rb\n\t  (WEBrick::HTTPServlet::CGIhandler#do_GET): use $?.exitstatus and\n\t  refine log message.\n\nSun Jul 18 16:14:29 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/msgcat.rb (TkMsgCatalog.callback): bug fix\n\t  ( wrong number of argument )\n\nSun Jul 18 08:13:58 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): remove extra sign digit.\n\nSun Jul 18 03:21:42 2004  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* dir.c (range): use NULL instead of 0.\n\n\t* dir.c (range): get rid of a gcc 3.4 warning.\n\nSun Jul 18 03:12:11 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (receive_responses): return if a LOGOUT response\n\t  received. (backported from HEAD)\n\t* lib/net/imap.rb (send_string_data): wait command continuation\n\t  requests before sending octet data of literals. (backported from HEAD)\n\nSat Jul 17 23:54:59 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/variable.rb: TkVariable#ref returns a TkVariable object\n\nSat Jul 17 22:04:44 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/ldap.rb: method hierarchical? should be in URI::LDAP.\n\nSat Jul 17 18:29:07 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (stmt): not to show same error messages twice.\n\nSat Jul 17 13:13:32 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/ruby-lex.rb (RubyLex::identify_string): %s string do not\n\t  process expression interpolation.  [ruby-talk:106691]\n\nSat Jul 17 05:26:27 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/diagram.rb: Incorporate Micheal Neuman's\n\t  client-side imagemao patch\n\nSat Jul 17 01:57:03 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (THREAD_ALLOC): th->thread should be initialized to NULL.\n\t  [ruby-talk:106657]  The solution was found by Guy Decoux.\n\nFri Jul 16 22:30:28 2004  Michael Neumann  <mneumann@ntecs.de>\n\n\t* file.c (rb_stat_dev_major): new methods File::Stat#dev_major and\n\t  #dev_minor. [ruby-core:03195]\n\nFri Jul 16 15:23:53 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (return_jump, break_jump): raise unexpceted local jump\n\t  exception directly.  [ruby-dev:23740]\n\n\t* lib/base64.rb (Deprecated): super in bound method calls original\n\t  name method in stable version.  [ruby-dev:23916]\n\nFri Jul 16 11:31:49 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/test/unit/ui/{fox,gtk,gtk2}/testrunner.rb: remove\n\t  garbage (patch from akira yamada) [ruby-dev:23911]\n\nFri Jul 16 11:20:00 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): fix output of NaN, Inf and -Inf with\n\t  \"%f\" or etc on MSVCRT platforms. (backported from HEAD)\n\nFri Jul 16 11:17:38 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* error.c (exit_initialize): use EXIT_SUCCESS instead of 0.\n\t  [ruby-dev:23913]\n\n\t* error.c (exit_success_p): new method SystemExit#success?.\n\t  [ruby-dev:23912]\n\n\t* error.c (syserr_initialize): initialization for subclasses.\n\t  [ruby-dev:23912]\n\nThu Jul 15 23:53:38 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser#warn, OptionParser#abort): Exception\n\t  no longer has to_str method.\n\nThu Jul 15 22:59:48 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/readline/extconf.rb: added dir_config for curses, ncurses,\n\t  termcap. (backported from HEAD)\n\nThu Jul 15 20:29:15 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* class.c, error.c, eval.c, intern.h, object.c, variable.c:\n\t  do not set path if it is a singleton class.  [ruby-dev:22588]\n\t  (backport from 1.9)\n\nThu Jul 15 10:15:04 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/, ext/tcltklib/: bug fix\n\n\t* ext/tk/lib/tk.rb: better operation for SIGINT when processing\n\t  callbacks.\n\t* ext/tk/lib/tk/msgcat.rb: ditto.\n\t* ext/tk/lib/tk/variable.rb: ditto.\n\t* ext/tk/lib/tk/timer.rb: ditto.\n\n\t* ext/tk/lib/tk/validation.rb: add Tk::ValidateConfigure.__def_validcmd\n\t  to define validatecommand methods easier\n\n\t* ext/tk/lib/tk.rb (_genobj_for_tkwidget): support autoload Tk ext\n\t  classes\n\n\t* ext/tk/lib/tk/canvas.rb and so on: remove the parent widget type\n\t  check for items (e.g. canvas items; depends on the class) to\n\t  avoid some troubles on Tk extension widget class definition.\n\n\t* ext/tk/lib/tkextlib/: add Iwidget and TkTable extension support\n\n\t* ext/tk/sample/tkextlib/: add samples of Iwidget and TkTable\n\nWed Jul 14 18:08:37 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1cons_to_der): fix type of\n\t  argument. [ruby-dev:23891]\n\n\t* test/openssl/test_x509store.rb: prune tests for CRL checking\n\t  unless X509::V_FLAG_CRL_CHECK is defined.\n\nWed Jul 14 12:29:07 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* util.c (ruby_strtod): should not convert string in the form of\n\t  \"-I.FE-X\" which both \"I\" and \"F\" are ommitted. [ruby-dev:23883]\n\n\t* test/ruby/test_float.rb (test_strtod): add test for bug fix.\n\nWed Jul 14 00:31:15 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* array.c: rdoc patch. merged patch from Johan Holmberg\n\t  <holmberg@iar.se> [ruby-core:3170]\n\nTue Jul 13 19:39:12 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic#merge_path):\n\t  \"URI('http://www.example.com/foo/..') + './'\" should return\n\t  \"URI('http://www.example.com/')\".  [ruby-list:39838]\n\t  \"URI('http://www.example.com/') + './foo/bar/..'\" should return\n\t  \"URI('http://www.example.com/foo/')\".  [ruby-list:39844]\n\n\t* test/uri/test_generic.rb (TestGeneric#test_merge): added tests.\n\nTue Jul 13 15:51:45 2004  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb (init_mkmf): Do not add $(libdir) to $LIBPATH in\n\t   extmk mode.\n\n\t* lib/mkmf.rb (dir_config): Prepend a new library path instead of\n\t  appending so it is tried first.\n\nTue Jul 13 00:50:48 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb: Support call-seq: for Ruby files.\n\nMon Jul 12 21:20:36 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* html_generator.rb: Support hyperlinks of the form {any text}[xxx]\n\t  as well as stuff[xxx]\n\nSat Jul 10 09:30:24 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/marshal/test_struct.rb: use qualified build-tin class name\n\t  (::Struct) to avoid name crash.\n\nSat Jul 10 04:21:56 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: better operation for SIGINT when processing\n\t  callbacks.\n\t* ext/tk/lib/tk/msgcat.rb: ditto.\n\t* ext/tk/lib/tk/variable.rb: ditto.\n\t* ext/tk/lib/tk/timer.rb: ditto.\n\n\t* ext/tk/lib/tk/validation.rb (__def_validcmd):  add a module\n\t  function of Tk::ValidateConfigure to define validatecommand\n\t  methods easier\n\nFri Jul  9 22:36:36 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* array.c, enum.c, pack.c: rdoc patch from Johan Holmberg\n\t  <holmberg@iar.se> [ruby-core:3132] [ruby-core:3136]\n\n\t* numeric.c: rdoc patch.\n\nFri Jul  9 19:26:39 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::HTTPS#proxy_open): raise ArgumentError to\n\t  notice https is not supported.\n\nFri Jul  9 14:28:54 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_raise): accept third argument as well as\n\t  Kernel#raise, and evaluate the arguments to create an exception in\n\t  the caller's context.  [ruby-talk:105507]\n\nFri Jul  9 01:47:08 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib : bug fix\n\t* ext/tk/lib/tkextlib/itcl : add [incr Tcl] support\n\t* ext/tk/lib/tkextlib/itk  : add [incr Tk] support\n\t* ext/tk/lib/tkextlib/iwidgets : midway point of [incr Widgets] support\n\t* ext/tk/sample/tkextlib/iwidgets : very simple examples of\n\t  [incr Widgets]\n\nThu Jul  8 22:52:19 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/{rss,parser,0.9,1.0,2.0}.rb: supported RSS 0.9x/2.0\n\t  validation and validation which disregard order of elements.\n\t* test/rss/test_parser.rb: added tests for RSS 0.9x/2.0\n\t  validation.\n\t* test/rss/{test_trackback,rss-testcase}.rb: fixed no good method\n\t  name.\n\nThu Jul  8 00:05:23 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/tempfile.rb (Tempfile::initialize): got out code of\n\t  generating tmpname.  [ruby-dev:23832][ruby-dev:23837]\n\nWed Jul  7 15:53:14 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* string.c (rb_str_match): raise TypeError when both arguments are\n\t  strings. [ruby-dev:22869] (backported from HEAD)\n\n\t* string.c (rb_str_match2): removed.\n\n\t* Makefile.in, bcc32/Makefile.sub, win32/Makefile.sub,\n\t  wince/Makefile.sub (string.c): now not depend on version.h.\n\nWed Jul  7 00:48:34 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/tk/lib/tkextlib/tktrans.rb,\n\t  ext/tk/lib/tkextlib/treectrl.rb: fix syntax errors.\n\nTue Jul  6 18:38:45 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib : improve framework of developping Tcl/Tk extension\n\t  wrappers\n\nMon Jul  5 23:56:42 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/{trackback,syndication,dublincore,content}.rb: worked\n\t  with ruby 1.6 again.\n\n\t* test/rss/rss-assertions.rb: ditto.\n\nMon Jul  5 22:54:39 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/uri/common.rb (Kernel#URI): new global method for parsing URIs.\n\nMon Jul  5 09:02:52 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_yield, rb_f_catch): 4th argument to rb_yield_0()\n\t  is a set of bit flags.  [ruby-dev:23859]\n\nMon Jul  5 01:27:32 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* lib/drb/drb.rb(DRbConn self.open): If socket pool is full, close\n\t  the socket whose last-access-time is oldest. (and add new one)\n\t  [ruby-dev:23860]\n\nSun Jul  4 12:24:50 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* lib/rss/rss.rb: added copyright header.\n\nSun Jul  4 00:24:40 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* added files\n\t  * lib/soap/attachment.rb\n\t  * lib/soap/header\n\t  * lib/soap/mimemessage.rb\n\t  * lib/soap/rpc/httpserver.rb\n\t  * lib/wsdl/soap/cgiStubCreator.rb\n\t  * lib/wsdl/soap/classDefCreator.rb\n\t  * lib/wsdl/soap/classDefCreatorSupport.rb\n\t  * lib/wsdl/soap/clientSkeltonCreator.rb\n\t  * lib/wsdl/soap/driverCreator.rb\n\t  * lib/wsdl/soap/mappingRegistryCreator.rb\n\t  * lib/wsdl/soap/methodDefCreator.rb\n\t  * lib/wsdl/soap/servantSkeltonCreator.rb\n\t  * lib/wsdl/soap/standaloneServerStubCreator.rb\n\t  * lib/wsdl/xmlSchema/enumeration.rb\n\t  * lib/wsdl/xmlSchema/simpleRestriction.rb\n\t  * lib/wsdl/xmlSchema/simpleType.rb\n\t  * lib/xsd/codegen\n\t  * lib/xsd/codegen.rb\n\t  * sample/soap/authheader\n\t  * sample/soap/raa2.4\n\t  * sample/soap/ssl\n\t  * sample/soap/swa\n\t  * sample/soap/whois.rb\n\t  * sample/soap/calc/samplehttpd.conf\n\t  * sample/soap/exchange/samplehttpd.conf\n\t  * sample/soap/sampleStruct/samplehttpd.conf\n\t  * sample/wsdl/raa2.4\n\t  * sample/wsdl/googleSearch/samplehttpd.conf\n\t  * test/openssl/_test_ssl.rb\n\t  * test/soap/header\n\t  * test/soap/ssl\n\t  * test/soap/struct\n\t  * test/soap/swa\n\t  * test/soap/wsdlDriver\n\t  * test/wsdl/multiplefault.wsdl\n\t  * test/wsdl/simpletype\n\t  * test/wsdl/test_multiplefault.rb\n\n\t* modified files\n\t  * lib/soap/baseData.rb\n\t  * lib/soap/element.rb\n\t  * lib/soap/generator.rb\n\t  * lib/soap/marshal.rb\n\t  * lib/soap/netHttpClient.rb\n\t  * lib/soap/parser.rb\n\t  * lib/soap/processor.rb\n\t  * lib/soap/property.rb\n\t  * lib/soap/soap.rb\n\t  * lib/soap/streamHandler.rb\n\t  * lib/soap/wsdlDriver.rb\n\t  * lib/soap/encodingstyle/handler.rb\n\t  * lib/soap/encodingstyle/literalHandler.rb\n\t  * lib/soap/encodingstyle/soapHandler.rb\n\t  * lib/soap/mapping/factory.rb\n\t  * lib/soap/mapping/mapping.rb\n\t  * lib/soap/mapping/registry.rb\n\t  * lib/soap/mapping/rubytypeFactory.rb\n\t  * lib/soap/mapping/wsdlRegistry.rb\n\t  * lib/soap/rpc/cgistub.rb\n\t  * lib/soap/rpc/driver.rb\n\t  * lib/soap/rpc/element.rb\n\t  * lib/soap/rpc/proxy.rb\n\t  * lib/soap/rpc/router.rb\n\t  * lib/soap/rpc/soaplet.rb\n\t  * lib/soap/rpc/standaloneServer.rb\n\t  * lib/wsdl/data.rb\n\t  * lib/wsdl/definitions.rb\n\t  * lib/wsdl/operation.rb\n\t  * lib/wsdl/parser.rb\n\t  * lib/wsdl/soap/definitions.rb\n\t  * lib/wsdl/xmlSchema/complexContent.rb\n\t  * lib/wsdl/xmlSchema/complexType.rb\n\t  * lib/wsdl/xmlSchema/data.rb\n\t  * lib/wsdl/xmlSchema/parser.rb\n\t  * lib/wsdl/xmlSchema/schema.rb\n\t  * lib/xsd/datatypes.rb\n\t  * lib/xsd/qname.rb\n\t  * sample/soap/calc/httpd.rb\n\t  * sample/soap/exchange/httpd.rb\n\t  * sample/soap/sampleStruct/httpd.rb\n\t  * sample/soap/sampleStruct/server.rb\n\t  * sample/wsdl/amazon/AmazonSearch.rb\n\t  * sample/wsdl/amazon/AmazonSearchDriver.rb\n\t  * sample/wsdl/googleSearch/httpd.rb\n\t  * test/soap/test_basetype.rb\n\t  * test/soap/test_property.rb\n\t  * test/soap/test_streamhandler.rb\n\t  * test/soap/calc/test_calc.rb\n\t  * test/soap/calc/test_calc2.rb\n\t  * test/soap/calc/test_calc_cgi.rb\n\t  * test/soap/helloworld/test_helloworld.rb\n\t  * test/wsdl/test_emptycomplextype.rb\n\t  * test/wsdl/axisArray/test_axisarray.rb\n\t  * test/wsdl/datetime/test_datetime.rb\n\t  * test/wsdl/raa/test_raa.rb\n\t  * test/xsd/test_xmlschemaparser.rb\n\t  * test/xsd/test_xsd.rb\n\n\t* summary\n\t  * add SOAP Header mustUnderstand support.\n\n\t  * add HTTP client SSL configuration and Cookies support (works\n\t    completely with http-access2).\n\n\t  * add header handler for handling sending/receiving SOAP Header.\n\n\t  * map Ruby's anonymous Struct to common SOAP Struct in SOAP Object\n\t    Model.  it caused error.\n\n\t  * add WSDL simpleType support to restrict lexical value space.\n\n\t  * add SOAP with Attachment support.\n\nSat Jul  3 17:19:44 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/tk/lib/tkextlib/tkDND.rb: fix syntax error.\n\nThu Jul  1 23:15:29 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/pstore.rb (transaction): safer backup scheme.  [ruby-list:39102]\n\n\t* lib/pstore.rb (commit_new): use FileUtils.copy_stream for Cygwin.\n\t  [ruby-dev:23157]\n\n\t* lib/pstore.rb (transaction): allow overriding dump and load.\n\t  [ruby-dev:23567]\n\n\t* lib/pstore.rb (PStore#transaction): get rid of opening in write mode\n\t  when read only transaction.  [ruby-dev:23842]\n\n\t* lib/yaml/store.rb: follow lib/pstore.rb's change.\n\nThu Jul  1 18:36:08 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tcltklib : bug fix\n\n\t* ext/tk/lib/tk : bug fix and add Tcl/Tk extension support libraries\n\nThu Jul  1 11:59:45 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: check for EVP_CIPHER_CTX_copy, ENGINE_add,\n\t  EVP_CIPHER_CTX_set_padding, EVP_CipherFinal_ex, EVP_CipherInit_ex,\n\t  EVP_DigestFinal_ex and EVP_DigestInit_ex.\n\n\t* ext/openssl/openssl_missing.c (EVP_CIPHER_CTX_copy): new function.\n\n\t* ext/openssl/openssl_missing.h (EVP_DigestInit_ex, EVP_DigestFinal_ex,\n\t  EVP_CipherInit_ex, EVP_CipherFinal_ex, HMAC_Init_ex): new macro for\n\t  OpenSSL 0.9.6.\n\n\t* ext/openssl/ossl_cipher.c (ossl_cipher_encrypt, ossl_cipher_decrypt):\n\t  re-implemnt (the arguments for this method is ).\n\n\t* ext/openssl/ossl_cipher.c (ossl_cipher_pkcs5_keyivgen): new method\n\t  OpenSSL::Cipher::Cipher#pkcs5_keyivgen. it calls EVP_BytesToKey().\n\n\t* ext/openssl/ossl_cipher.c (ossl_cipher_alloc, ossl_cipher_initialize,\n\t  ossl_cipher_copy, ossl_cipher_reset ossl_cipher_final,\n\t  ossl_cipher_set_key, ossl_cipher_set_iv): replace all EVP_CipherInit\n\t  and EVP_CipherFinal into EVP_CipherInit_ex and EVP_CipherFinal_ex.\n\t  and EVP_CIPHER_CTX_init should only be called once.\n\n\t* ext/openssl/ossl_cipher.c (ossl_cipher_set_key_length): new method\n\t  OpenSSL::Cipher::Cipher#key_len=.\n\n\t* ext/openssl/ossl_cipher.c (ossl_cipher_init_deprecated): new\n\t  finction; print warning for Cipher#<<.\n\n\t* ext/openssl/ossl_digest.c: replace all EVP_DigestInit and\n\t  EVP_DigestFinal into EVP_DigestInit_ex and EVP_DigestFinal_ex.\n\t  and EVP_MD_CTX_init should only be called once.\n\n\t* ext/openssl/ossl_digest.c (digest_final): should call\n\t  EVP_MD_CTX_cleanup to avoid memory leak.\n\n\t* ext/openssl/ossl_hmac.c (ossl_hmac_initialize): repalce HMAC_init\n\t  into HMAC_init_ex. and HMAC_CTX_init is moved to ossl_hmac_alloc.\n\n\t* ext/openssl/ossl_hmac.c (hmac_final): should call\n\t  HMAC_CTX_cleanup to avoid memory leak.\n\n\t* test/openssl/test_cipher.rb, test/openssl/test_digest.rb,\n\t  test/openssl/test_hmac.rb: new file.\n\nThu Jul  1 04:08:30 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_i2d_ASN1_TYPE, ossl_ASN1_TYPE_free):\n\t  workaround for the versions earlier than OpenSSL-0.9.7.\n\nThu Jul  1 03:33:55 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_pkey_dh.c (ossl_dh_initialize): should create\n\t  empty pkey object if no argument is passed. [ruby-talk:103328]\n\n\t* ext/openssl/ossl_pkey_dsa.c (ossl_dsa_initialize): ditto.\n\n\t* ext/openssl/ossl_pkey_rsa.c (ossl_rsa_initialize): ditto.\n\n\t* ext/openssl/ossl_pkey_dh.c: add new methods: OpenSSL::PKey::DH#p,\n\t  OpenSSL::PKey::DH#p=, OpenSSL::PKey::DH#g, OpenSSL::PKey::DH#g=,\n\t  OpenSSL::PKey::DH#pub_key, OpenSSL::PKey::DH#pub_key=,\n\t  OpenSSL::PKey::DH#priv_key and OpenSSL::PKey::DH#priv_key=.\n\n\t* ext/openssl/ossl_pkey_dsa.c: add new methods: OpenSSL::PKey::DSA#p,\n\t  OpenSSL::PKey::DSA#p=, OpenSSL::PKey::DSA#q, OpenSSL::PKey::DSA#q=,\n\t  OpenSSL::PKey::DSA#g, OpenSSL::PKey::DSA#g=,\n\t  OpenSSL::PKey::DSA#pub_key, OpenSSL::PKey::DSA#pub_key=,\n\t  OpenSSL::PKey::DSA#priv_key and OpenSSL::PKey::DSA#priv_key=.\n\nThu Jul  1 03:16:09 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_read): take optional second argument\n\t  to specify a string to be written.\n\n\t* ext/openssl/lib/openssl/buffering.rb (OpenSSL::Buffering#read):\n\t  take optional second argument to specify a string to be written.\n\n\t* ext/openssl/lib/openssl/buffering.rb (OpenSSL::Buffering#gets):\n\t  refine regexp for end-of-line.\n\n\t* ext/opnessl/lib/openssl/ssl.rb\n\t  (OpenSSL::SSL::SocketForwarder#listen): fix typo.\n\nWed Jun 30 11:38:51 2004  Mikael Brockman  <phubuh@phubuh.org>\n\n\t* parse.y (primary): should not be NULL.  [ruby-core:03098]\n\nWed Jun 30 02:53:24 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_emitter_new): set buffer after\n\t  Data_Wrap_Struct to avoid possible GC. [ruby-talk:104835]\n\nTue Jun 29 10:31:19 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval_cmd, rb_thread_trap_eval): restore safe level.\n\n\t* gc.c (define_final, run_final): preserve and restore safe level for\n\t  finalizers.  [ruby-core:03058]\n\n\t* signal.c (signal_exec, rb_trap_exit, trap): preserve and restore\n\t  safe level for signal handlers.  [ruby-dev:23829]\n\nMon Jun 28 14:57:56 2004  Jeff Mitchell  <quixoticsycophant@yahoo.com>\n\n\t* configure.in, lib/mkmf.rb (LIBPATHFLAG): use double quotes due to\n\t  DOSISH compilers.  [ruby-core:03107]\n\nMon Jun 28 00:30:19 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* sample/drb/*.rb: using 'DRb.thread.join' instead of 'gets'\n\nSun Jun 27 22:39:51 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* sample/rss/tdiary_plugin/rss-recent.rb: supported Hiki.\n\nSun Jun 27 12:19:46 2004  Kouhei Sutou  <kou@cozmixng.org>\n\n\t* {lib,sample,test}/rss: added RSS Parser. [ruby-dev:23780]\n\nSat Jun 26 11:07:30 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (aix): -b must come at the start of the command line,\n\t  and -e must not appear while testing libraries.  [ruby-talk:104501]\n\n\t* lib/mkmf.rb (dir_config): quote directory names if necessary.\n\t  [ruby-talk:104505]\n\nFri Jun 25 15:33:19 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/extconf.rb: check stricter.  [ruby-talk:104501]\n\n\t* ext/iconv/extconf.rb: include iconv.h for libiconv.  [ruby-dev:22715]\n\nFri Jun 25 08:31:29 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_atfork): remove \"fork terminates thread\"\n\t  warning.  [ruby-dev:23768]\n\n\t* object.c (rb_obj_clone): backport FL_FINALIZE patch from 1.9.\n\t  [ruby-core:02786][ruby-core:03067]\n\n\t* ext/socket/socket.c (sock_sockaddr): Socket#gethostbyname()\n\t  should give us packed address, not struct sockaddr.\n\t  [ruby-core:03053]\n\nFri Jun 25 02:04:23 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* {bcc32,win32,wince}/setup.mak: remove RUBY_EXTERN lines when\n\t  including version.h. [ruby-talk:104456] (backported from HEAD)\n\nThu Jun 24 14:23:29 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_fread): return already read data when system call is\n\t  interrupted.  [ruby-talk:97206]\n\nThu Jun 24 01:32:43 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* version.h: added declarations of ruby_version,\n\t  ruby_release_date, ruby_platform.\n\t  (backported from HEAD)\n\nWed Jun 23 22:23:37 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* ext/socket/socket.c (sock_s_gethostbyaddr): Work around problem\n\t  with OS X not returning 'from' parameter to recvfrom for\n\t  connection-oriented sockets.\n\nWed Jun 23 01:45:27 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RubyLex::identify_quotation):\n\t  Fix problem with the 'r' being dropped from %r{xxx}\n\nWed Jun 23 00:20:20 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/win32ole/win32ole.c (ole_hresult2msg): remove trailing\n\t  CRs and LFs. (doesn't depend on CR+LF) [ruby-dev:23749]\n\nWed Jun 23 00:00:25 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_initialize): should check fcntl result.  [ruby-dev:23742]\n\nTue Jun 22 21:11:36 2004  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (OLE_FREE): should not call CoFreeUnuse-\n\t  dLibraries().\n\n\t* ext/win32ole/win32ole.c (ole_event_free): ditto.\n\n\t* ext/win32ole/win32ole.c (ole_hresult2msg): truncate error message\n\t  before CR.\n\nTue Jun 22 16:47:42 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (MDTM_REGEXP): fix for demon's ftp server.\n\t  Thanks, Rutger Nijlunsing.\n\nMon Jun 21 10:19:23 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_opendir): use FindFirstFile()/FindNextFile()/\n\t  FindClose() instead of _findfirst()/_findnext()/_findclose().\n\t  merge from HEAD.\n\nSat Jun 19 13:24:15 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (method_call): allow changing $SAFE.  [ruby-dev:23713]\n\nFri Jun 18 23:12:22 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_save_safe_level, rb_set_safe_level, safe_setter): limit\n\t  safe level.\n\nWed Jun 16 23:05:57 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_freeze): prepare string representation before\n\t  freezing. [ruby-talk:103646]\n\nWed Jun 16 16:04:40 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* object.c (rb_mod_le): singleton class inherits Class rather than its\n\t  object's class.  [ruby-dev:23690]\n\nWed Jun 16 16:01:17 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (stack_grow_direction): memoize the direction.\n\n\t* gc.c (Init_stack): should always move to end of VALUE.\n\nTue Jun 15 12:10:04 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix (TkWindow#grab)\n\nMon Jun 14 18:23:27 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/remote-tk.rb: bug fix\n\nSun Jun 13 00:23:04 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/extconf.rb: [EXPERIMENTAL] MacOS X (darwin) support\n\n\t* ext/tcltklib/tcltklib.c: fix thread trouble on callback proc, and\n\t  eliminate warning about instance variable access\n\n\t* ext/tk/lib/tk/menubar.rb: improve supported menu_spec\n\n\t* ext/tk/lib/tk/menuspec.rb: [add] menu_spec support library\n\n\t* ext/tk/lib/tk/root.rb: add menu_spec support\n\n\t* ext/tk/lib/tk/text.rb: bug fix\n\n\t* ext/tk/lib/tk/toplevel.rb: add menu_spec support\n\n\t* ext/tk/sample/menubar?.rb: [add] sample of menu_spec usage\n\nSat Jun 12 11:15:53 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (target_os): strip -gnu suffix on Linux.\n\nFri Jun 11 17:08:21 2004  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* config.guess: Restore a wrongly removed hyphen.\n\nFri Jun 11 14:30:08 2004  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* config.guess: Attempt to avoid system name change on\n\t  Darwin platforms also.\n\nFri Jun 11 14:22:45 2004  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* config.guess, config.sub: Attempt to avoid system name change on\n\t  Linux platforms.  We have been using \"linux\" instead of\n\t  \"linux-gnu\" on this branch.\n\nThu Jun 10 19:19:41 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/sdbm/init.c (fsdbm_store): sdbm should use StringValue().\n\t  [ruby-talk:103062]\n\nWed Jun  9 18:04:14 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic::merge,\n\t  URI::Generic::route_from): accepts non-hierarchical URI.\n\t  [ruby-dev:23631]\n\n\t* test/uri/test_generic.rb (TestGeneric::test_route,\n\t  TestGeneric::test_merge): added tests for above changes.\n\nWed Jun  9 17:39:37 2004  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* config.guess, config.sub: Update to a more recent version as of\n\t  2004-01-20.\n\n\t* configure.in: Add support for DragonFly BSD.\n\nWed Jun  2 20:16:03 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (str_new4): should share shared instance if it already\n\t  exists.  [ruby-dev:23665]\n\nWed Jun  2 12:41:53 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_gets_m): set lastline ($_) even when read line is\n\t  nil.  [ruby-dev:23663]\n\nFri May 28 11:20:31 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): bad influence on frame node.\n\n\t* eval.c (eval): reverted wrongly removed condition.  [ruby-dev:23638]\n\nThu May 27 23:15:18 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb: leading 0 padding of timestamp usec part.\n\n\t* lib/csv.rb (CSV.parse): [CAUTION] behavior changed.  in the past,\n\t  CSV.parse accepts a filename to be read-opened (it was just a\n\t  shortcut of CSV.open(filename, 'r')).  now CSV.parse accepts a\n\t  string or a stream to be parsed e.g.\n\t  CSV.parse(\"1,2\\n3,r\") #=> [['1', '2'], ['3', '4']]\n\n\t* lib/csv.rb: CSV::Row and CSV::Cell are deprecated.  these classes\n\t  are removed in the future.  in the new csv.rb, row is represented\n\t  as just an Array.  since CSV::Row was a subclass of Array, it won't\n\t  hurt almost all programs except one which depended CSV::Row#match.\n\t  and a cell is represented as just a String or nil(NULL).  this\n\t  change will cause widespread destruction.\n\n\t      CSV.open(\"foo.csv\", \"r\") do |row|\n\t\trow.each do |cell|\n\t\t  if cell.is_null       # using Cell#is_null\n\t\t    p \"(NULL)\"\n\t\t  else\n\t\t    p cell.data         # using Cell#data\n\t\t  end\n\t\tend\n\t      end\n\n\t    must be just;\n\n\t      CSV.open(\"foo.csv\", \"r\") do |row|\n\t\trow.each do |cell|\n\t\t  if cell.nil?\n\t\t    p \"(NULL)\"\n\t\t  else\n\t\t    p cell\n\t\t  end\n\t\tend\n\t      end\n\n\t* lib/csv.rb: [CAUTION] record separator(CR, LF, CR+LF) behavior\n\t  change.  CSV.open, CSV.parse, and CSV,generate now do not force\n\t  opened file binmode.  formerly it set binmode explicitly.\n\n\t  with CSV.open, binmode of opened file depends the given mode\n\t  parameter \"r\", \"w\", \"rb\", and \"wb\".  CSV.parse and CSV.generate open\n\t  file with \"r\" and \"w\".\n\n\t  setting mode properly is user's responsibility now.\n\n\t* lib/csv.rb: accepts String as a fs (field separator/column separator)\n\t  and rs (record separator/row separator)\n\n\t* lib/csv.rb (CSV.read, CSV.readlines): added.  works as IO.read and\n\t  IO.readlines in CSV format.\n\n\t* lib/csv.rb: added CSV.foreach(path, rs = nil, &block).  CSV.foreach\n\t  now does not handle \"| cmd\" as a path different from IO.foreach.\n\t  needed?\n\n\t* test/csv/test_csv.rb: updated.\n\n\t* test/ruby/test_float.rb: added test_strtod to test Float(\"0\").\n\nThu May 27 21:37:50 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#initialize): refine pathname initialization\n\t  by pathname.\n\nThu May 27 20:22:05 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* io.c (rb_io_fwrite): check all case errno != 0 [ruby-dev:23648]\n\nThu May 27 14:53:13 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (rb_io_fwrite): workaround for bcc32's fwrite bug.\n\t  add errno checking.  [ruby-dev:23627]\n\nWed May 26 14:19:42 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval, eval): make line number consistent on eval with\n\t  Proc.  [ruby-talk:101253]\n\nWed May 26 13:59:17 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::skip_for_variable): Allow for\n\t  'do' after for statement\n\nWed May 26 13:56:03 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb (Generators::MarkUp::style_url): Fix\n\t  relative path to code CSS file\n\nWed May 26 13:14:52 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_init_copy): copy also positions.  [ruby-talk:100910]\n\nWed May 26 00:00:00 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/syck.c (syck_new_parser): clear parser on init.\n\t  thanks, ts. [ruby-core:02931]\n\n\t* ext/syck/token.c (sycklex_yaml_utf8): buffer underflow.\n\t  thanks, ts. [ruby-core:02929]\n\n\t* lib/yaml/baseemitter.rb (indent_text): simpler flow block code.\n\n\t* lib/yaml.rb: added rdoc to beginning of lib.\n\nMon May 24 10:46:26 2004  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/rdoc/generators/template/html/html.rb: SYSTEM identifiers\n\t  must be absolute URIs\n\nSat May 22 12:00:04 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* MANIFEST: add new encodings in rexml.\n\n\t* ext/tk/MANIFEST: add recent files.\n\nSat May 22 05:37:11 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/remote-tk.rb: (NEW library) controll Tk interpreters\n\t  on the other processes by Tcl/Tk's 'send' command\n\nFri May 21 09:22:05 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_method_parameters):\n\t  Add ()'s around parameters that don't have them\n\nThu May 20 17:02:03 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (check_sizeof): define result size.  [ruby-core:02911]\n\n\t* lib/mkmf.rb (create_header): macro name should not include equal\n\t  sign.\n\nThu May 20 15:59:50 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* ext/socket/socket.c: fix SEGV. [ruby-dev:23550]\n\nThu May 20 14:35:52 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c: check SCM_RIGHTS macro addition to\n\t  the msg_control field to test existence of file descriptor passing\n\t  by msg_control.\n\nThu May 20 12:38:06 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (flo_eq): always check if operands are NaN.\n\t  [ruby-list:39685]\n\nThu May 20 12:34:39 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_visibility):\n\t  At Ryan Davis' suggestion, honor visibility modifers if guarded by a\n\t  statement modifier\n\nThu May 20 12:22:13 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (have_type): do not check pointer to incomplete type,\n\t  which always get compiled.  [ruby-list:39683]\n\nWed May 19 11:09:00 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: change permition of TkObject#tk_send from\n\t  private to public\n\nTue May 18 14:00:46 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* node.h (NEW_DSTR): adjust list length.\n\n\t* parse.y (literal_concat): ditto.\n\nMon May 17 16:14:25 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* numeric.c (flo_to_s): it's preferable that \"p 0.0\" outputs \"0.0\"\n\t  instead of \"0.0e+00\". [ruby-dev:23480]\n\n\t* numeric.c (flo_to_s): it's preferable that \"p 0.00000000000000000001\"\n\t  outputs \"1.0e-20\" instead of \"9.999999999999999e-21\". (the precision\n\t  is considered, but there is assumption DBL_DIG == 15 in current\n\t  implementation)\n\nMon May 17 10:13:33 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (setup_domain_and_type): honor duck typing.\n\t  [ruby-dev:23522]\n\n\t* ext/socket/socket.c (sock_s_getnameinfo): ditto.\n\nMon May 17 01:15:23 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml.rb: removed fallback to pure Ruby parser.\n\n\t* lib/yaml/baseemitter.rb (indent_text): was forcing a mod value\n\t  of zero at times, which kept some blocks from getting indentation.\n\n\t* lib/yaml/baseemitter.rb (node_text): rewriting folded scalars.\n\n\t* ext/syck/syck.h: reports style of scalars now, be they plain, block\n\t  single-, or double-quoted.\n\n\t* ext/syck/syck.c: ditto.\n\n\t* ext/syck/gram.c: ditto.\n\n\t* ext/syck/node.c: ditto.\n\n\t* ext/syck/token.c: ditto.\n\n\t* ext/syck/rubyext.c (yaml_org_handler): symbols loaded only\n\t  if scalar style is plain.\n\n\t* ext/syck/rubyext.c (yaml_org_handler): some empty strings were\n\t  loaded as symbols.\n\n\t* test/yaml/test_yaml.rb (test_perl_regexp): updated test to\n\t  match new regexp serialization.\n\nMon May 17 00:03:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/drb/drb.rb: Cosmetic documentation changes.\n\nSun May 16 22:36:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/test/unit.rb: Removed :nodoc: directive (it prevented effective\n\t  RDoc operation), and added file-level comment.\n\nSun May 16 20:55:49 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/dbm/dbm.c (fdbm_initialize): accept optional 3rd argument to\n\t  specify an open flag.\n\t  (Init_dbm): define open flags: DBM::READER, DBM::WRITER, DBM::WRCREAT\n\t  and DBM::NEWDB.\n\nSun May 16 13:10:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/test/unit/**/*.rb: Removed :nodoc: directives (many were\n\t  generating warnings, many were on private methods).\n\nSat May 15 01:41:34 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): forgot to restore $SAFE value before evaluating\n\t  compiled node.  [ruby-core:02872]\n\nSat May 15 01:33:12 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_each_func): terminates loop if generating value\n\t  is same to @end.  [ruby-talk:100269]\n\nFri May 14 22:08:38 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_new4): should not reuse frozen shared string if\n\t  the original is not an instance of String. [ruby-talk:100193]\n\nFri May 14 18:39:25 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/canvas.rb: improve coords support for canvas items.\n\t  Now, supports all of the followings.\n\t    TkcLine.new(c, 0, 0, 100, 100, :fill=>'red')\n\t    TkcLine.new(c, [0, 0, 100, 100], :fill=>'red')\n\t    TkcLine.new(c, [0, 0], [100, 100], :fill=>'red')\n\t    TkcLine.new(c, [[0, 0], [100, 100]], :fill=>'red')\n\t    TkcLine.new(c, :coords=>[0, 0, 100, 100], :fill=>'red')\n\t    TkcLine.new(c, :coords=>[[0, 0], [100, 100]], :fill=>'red')\n\nFri May 14 12:11:43 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* util.c (ruby_strtod): strtod(\"0\", &end); => end should point '\\0'.\n\t [ruby-dev:23498]\n\nThu May 13 15:47:30 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/net/telnet.rb (Net::Telnet::login): \"options\" can specify\n\t  regexps for login prompt and/or password prompt.\n\nThu May 13 14:23:45 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* hash.c (delete_if_i): use st_delete_safe() (via\n\t  rb_hash_delete()) instead of returning ST_DELETE.\n\t  backport from HEAD.  [ruby-dev:23487]\n\nThu May 13 13:01:30 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/mailto.rb (URI::MailTo::to_s): should include fragment.\n\nThu May 13 11:04:08 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* pack.c (pack_pack): always add with null for 'Z'.\n\n\t* pack.c (pack_unpack): terminated by null for 'Z'.  [ruby-talk:98281]\n\nWed May 12 19:59:43 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (have_type, check_sizeof): replace unusable characters.\n\t  [ruby-talk:99788]\n\nWed May 12 17:41:42 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Config): make it configurable without\n\t  external file such as /etc/resolv.conf.\n\nWed May 12 14:37:27 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509name.c: attribute value of DC (short name of\n\t  domainComponent) should be IA5String.\n\nWed May 12 13:20:19 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk/composite.rb: improve configure methods (based on\n\t  the proposal of [ruby-talk:99671]).\n\nWed May 12 11:51:08 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* class.c (rb_obj_singleton_methods): fix rdoc\n\nMon May 10 21:44:42 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Change scheme for\n\t  looking up symbols in  HTML generator.\n\nMon May 10 16:45:21 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): warning during eval should not cause deadlock.\n\t  [ruby-talk:98651]\n\n\t* eval.c (rb_eval): raise TypeError exception for superclass\n\t  mismatch.  [ruby-list:39567]\n\nMon May 10 12:11:37 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Hack to search parents\n\t  for unqualified constant names.\n\nMon May 10 12:11:37 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Hack to search parents\n\t  for unqualified constant names.\n\nSun May  9 22:37:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/net/ftp.rb: improved documentation\n\t* lib/net/imap.rb: ditto\n\t* lib/net/pop.rb: ditto\n\t* lib/net/smtp.rb: ditto\n\t* lib/net/telnet.rb: ditto\n\nFri May  7 21:50:21 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::parse_include): Allow\n\t  multiple arguments to 'include'\n\nFri May  7 21:31:56 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_list): Array() breaks pathes including \"\\n\".\n\t  [ruby-core:02843]\n\nFri May  7 11:25:53 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* util.c (ruby_strtod): \"0.0000000000000000001\" should be converted\n\t  to 1.0e-19 instead of 0.0. (leading zeros aren't significant digits)\n\t  [ruby-talk:99318] [ruby-dev:23465]\n\nFri May  7 10:00:05 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/tkutil.c (get_eval_string_core): bug fix. [ruby-dev:23466]\n\nThu May  6 22:13:17 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* ext/socket/socket.c (ippaddr): use NUMERICHOST if can not resolve\n\t  hostname.\n\nThu May  6 14:22:29 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb (to_yaml): added instance variable handling\n\t  for Ranges, Strings, Structs, Regexps.\n\n\t* lib/yaml/rubytypes.rb (to_yaml_fold): new method for setting a\n\t  String's flow style.\n\n\t* lib/yaml.rb (YAML::object_maker): now uses Object.allocate.\n\n\t* ext/syck/gram.c: fixed transfer methods on structs, broke it\n\t  last commit.\n\nThu May  6 11:40:28 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (string): accept NIL.\n\n\t* lib/net/imap.rb (body_type_basic): allow body-fields omissions.\n\nThu May  6 01:59:04 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb (Generators::HtmlMethod::params):\n\t  Don't include the &block parameter if we have explicit\n\t  yield parameters.\n\nWed May  5 03:40:29 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/ring.rb: use recv instead of recvfrom.\n\nTue May  4 23:52:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/gserver.rb: documented\n\nTue May  4 23:46:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/xmlrpc/README.txt: introduced for documentation purposes\n\nMon May  3 09:47:24 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_method_or_yield_parameters):\n\t  Fix parsing bug if yield called within 1 line block\n\nSun May  2 01:04:38 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib, ext/tk: renewal Ruby/Tk\n\nFri Apr 30 20:08:41 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* time.c (SIZEOF_TIME_T): support SIZEOF_TIME_T == SIZEOF_INT.\n\nTue Apr 27 13:12:42 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): too many line trace call. (ruby-bugs PR#1320)\n\nTue Apr 27 08:41:28 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb: passing Range tests.\n\n\t* ext/syck/syck.h: version 0.44.\n\n\t* ext/syck/gram.c: transfers no longer open an indentation.\n\t  fixed transfers which precede blocks.\n\n\t* ext/syck/token.c: ditto.\n\n\t* ext/syck/syck.c: fixed segfault if an anchor has been released already.\n\n\t* ext/syck/node.c (syck_free_members): organized order of free'd nodes.\n\n\t* ext/syck/rubyext.c (syck_emitter_write_m): test for proper string with\n\t  StringValue.\n\nMon Apr 26 23:56:54 2004  Daniel Kelley  <news-1082945587@dkelley.gmp.san-jose.ca.us>\n\n\t* README.EXT, README.EXT.ja: fixed wrong function signature.\n\t  [ruby-talk:98349]\n\nMon Apr 26 21:40:09 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::Context::add_alias): Only alias\n\t  to instance methods.\n\nSat Apr 24 10:38:31 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/markup/simple_markup.rb (SM::SimpleMarkup::group_lines):\n\t  Fix bug where consecutive headings are merged.\n\nFri Apr 23 23:26:13 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb: $hdrdir should not contain macros for backward\n\t  compatibility.  [bruby-dev:28]\n\n\t* version.c (ruby_show_copyright): obtain copyright year from\n\t  RUBY_RELEASE_YEAR.\n\n\t* win32/resource.rb: ditto.\n\n\t* win32/resource.rb: default rubyw icon to ruby.ico, and let DLL also\n\t  include them.\n\n\t* win32/resource.rb: include winver.h for older WindowsCE.\n\nFri Apr 23 16:38:46 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb: sync taint/freeze flag between\n\t  a pathname object and its internal string object.\n\nFri Apr 23 14:52:08 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (stmt, arg, aref_args): should not make sole splat into\n\t  array, in aref_args other than aref with op_asgn.\n\nFri Apr 23 14:14:38 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb: don't use Regexp#source to embed regexps.\n\t  [ruby-dev:23432]\n\nThu Apr 22 04:15:36 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (aref_args): should pass expanded list.  [ruby-core:02793]\n\nThu Apr 22 01:12:57 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (flo_to_s): tweak output string based to preserve\n\t  decimal point and to remove trailing zeros.  [ruby-talk:97891]\n\n\t* string.c (rb_str_index_m): use unsigned comparison for T_FIXNUM\n\t  search.  [ruby-talk:97342]\n\nWed Apr 21 22:57:27 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/rinda.rb, test/rinda/test_rinda.rb: check Hash tuple size.\n\nWed Apr 21 20:05:00 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::HTTP#proxy_open): set Host: field explicitly.\n\t  [ruby-list:39542]\n\nMon Apr 19 18:11:15 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_equal): returns true if two hashes have same set\n\t  of key-value set.  [ruby-talk:97559]\n\n\t* hash.c (rb_hash_eql): returns true if two hashes are equal and\n\t  have same default values.\n\nMon Apr 19 08:19:58 2004  Doug Kearns  <djkea2@mugca.its.monash.edu.au>\n\n\t* dln.c, io.c, lib/benchmark.rb, lib/cgi.rb, lib/csv.rb, lib/date.rb,\n\t  lib/ftools.rb, lib/getoptlong.rb, lib/logger.rb, lib/matrix.rb,\n\t  lib/monitor.rb, lib/set.rb, lib/thwait.rb, lib/timeout.rb,\n\t  lib/yaml.rb, lib/drb/drb.rb, lib/irb/workspace.rb, lib/net/ftp.rb,\n\t  lib/net/http.rb, lib/net/imap.rb, lib/net/telnet.rb,\n\t  lib/racc/parser.rb, lib/rinda/rinda.rb, lib/rinda/tuplespace.rb,\n\t  lib/shell/command-processor.rb, lib/soap/rpc/soaplet.rb,\n\t  lib/test/unit/testcase.rb, lib/test/unit/testsuite.rb: typo fix.\n\nMon Apr 19 08:14:18 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_body): Allow for\n\t  #ifdef HAVE_PROTOTYPES\n\nFri Apr 16 22:33:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* ext/iconv/iconv.c: nearly finished RDoc comments.\n\nFri Apr 16 17:04:07 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_equal): always returns true or false, never\n\t  returns nil. [ruby-dev:23404]\n\nFri Apr 16 08:27:02 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: skip linking when libraries to be preloaded not\n\t  compiled.  [ruby-list:39561]\n\nThu Apr 15 23:21:52 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* process.c (pst_success_p): new method Process::Status#success?.\n\t  [ruby-dev:23385]\n\nThu Apr 15 17:12:13 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/gdbm/gdbm.c (Init_gdbm): define GDBM::READER, GDBM::WRITER,\n\t  GDBM::WRCREAT and GDBM::NEWDB.\n\t  (fgdbm_initialize): use specified read/write flag.\n\nWed Apr 14 11:29:56 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* numeric.c (flo_eq): workaround for bcc32's bug.\n\t  (ruby-bugs-ja:PR#594)\n\nWed Apr 14 13:06:35 2004  Doug Kearns  <djkea2@mugca.its.monash.edu.au>\n\n\t* array.c, enum.c, eval.c, file.c, io.c, numeric.c, object.c, prec.c,\n\t  process.c, re.c, string.c: typos in RDoc comments.  [ruby-core:02783]\n\nWed Apr 14 11:06:38 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::scan): Changed\n\t  behavior of :enddoc: -- it now unconditionally terminates\n\t  processing of the current file.\n\nWed Apr 14 11:03:22 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* defines.h: include <net/socket.h> to get fd_set definition in BeOS.\n\nTue Apr 13 23:06:30 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/rinda.rb: change pattern matching.\n\t  a === b -> a == b || a === b. [druby-ja:98]\n\n\t* test/rinda/test_rinda.rb: ditto.\n\nTue Apr 13 19:54:29 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: should not overwrite HTTP request header.\n\t  [ruby-list:39543]\n\nTue Apr 13 01:30:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* ext/iconv/iconv.c: RDoc documentation (from RD; nearly finished).\n\t* ext/iconv/charset_alias.rb: Prevent from RDoc'ing.\n\nMon Apr 12 19:11:29 2004  Eric Hodel  <drbrain@segment7.net>\n\n\t* gc.c (rb_gc_copy_finalizer): typo.  [ruby-core:02774]\n\nMon Apr 12 18:52:32 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_init_i): should return\n\t  a value.\n\nMon Apr 12 10:43:47 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (rb_glob2, rb_glob, rb_globi, push_globs, push_braces,\n\t  rb_push_glob): fix memory leak. (leaked when block was interrupted)\n\nMon Apr 12 10:27:37 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: backport SIZEOF_TIME_T definition from 1.9.\n\n\t* win32/Makefile.sub: ditto.\n\n\t* wince/Makefile.sub: ditto.\n\nSun Apr 11 19:12:35 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ruby.c (require_libraries): restore source file/line after\n\t  statically linked extensions initialized.  [ruby-dev:23357]\n\nSun Apr 11 10:47:04 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::TopLevel::add_class_or_module): Toplevel\n\t  classes and modules are a special case too... (handle extending existing\n\t  classes with or without :enddoc:)\n\nSat Apr 10 23:51:13 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::Context::add_to): Implementation of :enddoc:\n\t  made one too many assumptions...\n\nSat Apr 10 00:00:19 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/markup/simple_markup/inline.rb: Fix problem\n\t  with \\_cat_<b>dog</b>\n\nWed Apr  7 00:19:50 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/rinda.rb: fix hash tuple bug.\n\n\t* lib/rinda/tuplespace.rb: ditto.\n\n\t* test/rinda/test_rinda.rb\n\nTue Apr  6 18:24:18 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_reopen): should use rb_io_check_io().\n\nTue Apr  6 16:46:09 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* configure.in: check the size of time_t.\n\n\t* time.c (time_add): new function.\n\t  (time_plus): use time_add.\n\t  (time_minus): use time_add.\n\nTue Apr  6 13:21:30 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (make_hostent): must return value.\n\nTue Apr  6 00:05:30 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/rinda.rb: add require 'drb/drb'\n\nMon Apr  5 08:18:23 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/rdoc.rb: Remove leading ./ from file names so that cross\n\t  references work properly.\n\nSun Apr  4 20:33:42 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (Init_load): make $LOADED_FEATURES built-in.\n\t  [ruby-dev:23299]\n\n\t* ruby.c (ruby_prog_init): make $PROGRAM_NAME built-in.\n\n\t* lib/English.rb: remove $LOADED_FEATURES and $PROGRAM_NAME.\n\nSun Apr  4 14:01:20 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/options.rb (Options::parse): Allow multiple -x options to RDoc.\n\t  Fix bug where files weren't being excluded properly\n\nSat Apr  3 17:11:05 2004  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/syck.h: version 0.43.\n\n\t* ext/syck/lib/gram.c: allow root-level inline collections.\n\t [ruby-talk:94922]\n\n\t* lib/yaml/rubytypes.rb (Symbol#to_yaml): emit symbols as implicits.\n\t [ruby-talk:94930]\n\n\t* ext/syck/bytecode.c: turn off default implicit typing.\n\n\t* ext/syck/implicit.c: detect base60 integers.\n\n\t* ext/syck/rubyext.c: handle base60, as well as hex and octal\n\t  with commas.  implicit typing of ruby symbols.\n\nFri Apr  2 17:27:17 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (top_include): include in the wrapped load is done for\n\t  the wrapper, not for a singleton class for wrapped main.\n\t  [ruby-dev:23305]\n\nFri Apr  2 15:13:44 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_eq): use temporary double variable to save the\n\t  result (internal float register may be bigger than 64 bits, for\n\t  example, 80 bits on x86).  [ruby-dev:23311]\n\nFri Apr  2 14:35:26 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): should generate unique identifier of the\n\t  pushing block.  [ruby-talk:96363]\n\nFri Apr  2 07:31:38 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (make_hostent): fix memory leak, based on\n\t  the patch from HORIKAWA Hisashi <vzw00011@nifty.ne.jp>.\n\nThu Apr  1 22:55:33 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb: Allow rdoc comments in\n\t  =begin rdoc/=end\n\n\t* lib/rdoc/parsers/parse_rb.rb: Fix problem with comment in\n\t  top-level method being taken as file comment.\n\nThu Apr  1 22:55:04 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_options.rb: Fix undefined variable warning.\n\nThu Apr  1 19:58:37 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/mapping/{factory.rb,registry.rb}: fixed illegal mapped URI\n\t  object with soap/marshal.\n\t  added URIFactory class for URI mapping.  BasetypeFactory checks\n\t  instance_variables when original mapping is not allowed (ivar must\n\t  be empty).  Instance of URI have instance_variables but it must be\n\t  llowed whenever original mapping is allowed or not.\n\n\t* lib/xsd/datatypes.rb: check the smallest positive non-zero\n\t  single-precision float exactly instead of packing with \"f\".\n\t  [ruby-talk:88822]\n\n\t* lib/soap/mapping/rubytypeFactory.rb: should not dump singleton class.\n\t  [ruby-dev:22588]\n\t  c = class << Object.new; class C; self; end; end; SOAPMarshal.dump(c)\n\nWed Mar 31 19:06:23 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c (year_leap_p): new function.\n\t  (timegm_noleapsecond): ditto.\n\t  (search_time_t): use timegm_noleapsecond instead of\n\t  mktime for first guess.\n\nWed Mar 31 12:04:04 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/delegate.rb (DelegateClass): define internal methods of the\n\t  result class, but not metaclass of the caller.  [ruby-talk:96156]\n\n\t* intern.h: provide proper prototypes.  [ruby-core:02724]\n\n\t* ruby.h: missing.h is now prerequisite to intern.h.\n\nTue Mar 30 20:25:34 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c (search_time_t): limit guess range by mktime if it is\n\t  available.  [ruby-dev:23274]\n\nSun Mar 28 14:16:59 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb (auth): failed when account/password include \"%\".\n\t  [ruby-talk:95933]\n\nSat Mar 27 21:40:41 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: permit extra semicolon in content-type field.\n\nSat Mar 27 10:40:48 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* (lib/pp.rb, lib/prettyprint.rb): define seplist in PP::PPMethods\n\t  instead of PrettyPrint.\n\nThu Mar 25 23:28:52 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_overflow_p): backport 1.9 usec overflow function.\n\t  (ruby-bugs PR#1307)\n\nThu Mar 25 23:15:24 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_options.rb (RI::Options::show_version):\n\t  Add --version option\n\nThu Mar 25 04:16:18 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_options.rb (RI::Options): Add the --list-names option,\n\t  which dumps our all known names\n\nThu Mar 25 03:57:47 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_util.rb (NameDescriptor::initialize): No longer\n\t  allow nested classes to be designated using \".\"--you must\n\t  now use \"::\"\n\nThu Mar 25 02:00:18 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/template/html/one_page_html.rb (Page):\n\t  Fix to work with C modules.\n\nWed Mar 24 21:17:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/uri.rb: Documented (thanks Dmitry V. Sabanin).\n\t* lib/uri/common.rb: Ditto.\n\t* lib/uri/ftp.rb: Ditto.\n\t* lib/uri/generic.rb: Ditto.\n\t* lib/uri/http.rb: Ditto.\n\t* lib/uri/https.rb: Ditto.\n\t* lib/uri/ldap.rb: Ditto.\n\t* lib/uri/mailto.rb: Ditto.\n\t  (All backported from 1.9)\n\nWed Mar 24 18:48:26 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb ($ruby, $topdir, $hdrdir): should not be affected by\n\t  DESTDIR after installed.\n\n\t* lib/mkmf.rb (RUBY): / is not recognized as path separator on\n\t  nmake/bmake. [ruby-list:39388]\n\n\t* lib/mkmf.rb (init_mkmf): $INCFLAGS also should be lazy-evaluated.\n\nWed Mar 24 12:32:56 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::handle_class_module):\n\t  Don't document methods if we don't know for sure the\n\t  class or module.\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_class):\n\t  Don't store documentation for singleton classes if we\n\t  don't know the real class.\n\nWed Mar 24 11:11:26 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb (Generators::HTMLGenerator::load_html_template):\n\t  Allow non-RDoc templates by putting a slash in the template name\n\nMon Mar 22 16:19:57 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.1: add -width option to .Bl for old groff.\n\nSun Mar 21 21:11:16 2004  Keiju Ishitsuka  <keiju@ishitsuka.com>\n\n\t* lib/shell/*: bug fix for Shell#system(command_line_string).\n\nSat Mar 20 20:57:10 2004  David Black  <dblack@wobblini.net>\n\n\t* lib/scanf.rb: Backported 1.9 branch\n\t  modifications/corrections to 1.8 branch\n\nSat Mar 20 23:51:03 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (rb_require_safe): preserve old ruby_errinfo.\n\t  [ruby-talk:95409]\n\n\t* eval.c (rb_f_raise): should not clear backtrace information if\n\t  exception object already have one.\n\nSat Mar 20 15:25:36 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/template/html/html.rb (RDoc::Page): Force\n\t  page background to white.\n\nSat Mar 20 09:52:33 2004  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb: _parse() now accepts fractional\n\t  part of second minute that follows a comma or a full stop.\n\nFri Mar 19 01:55:57 2004  Mauricio Fernandez  <batsman.geo@yahoo.com>\n\n\t* io.c (rb_io_sync): need not to check writable. [ruby-core:02674]\n\nThu Mar 18 21:44:38 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: backport drb.rb 1.16.\n\nFri Mar 18 17:49:51 2005  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (make_struct): allow const_id for accessor names.\n\t  [ruby-core:04585]\n\n\t* eval.c (rb_attr): check if attribute name is local_id or\n\t  const_id.\n\nThu Mar 18 16:22:38 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_eq): avoid false positive by using scope and\n\t  dyna_vars.  no longer use frame.uniq.\n\nWed Mar 17 14:44:43 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (range): fix possible \"\\0\" overrun. (in case of \"\\0-\")\n\nMon Mar 15 07:39:13 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): should not re-submit TAG_BREAK if this\n\t  yield is not break destination. [ruby-dev:23197]\n\nSat Mar 13 14:28:16 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/drb/test_drbssl.rb: rescue LoadError. (Barkport from main\n\t  trunk)\n\n\t* test/drb/test_drbunix.rb: ditto.\n\nWed Mar 10 22:28:09 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (remove_dir): should handle symlink correctly.\n\t  This patch is contributed by Christian Loew.  [ruby-talk:94635]\n\t  (Backport from main trunk)\n\nWed Mar 10 16:28:42 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (return_jump): set return value to the return\n\t  destination.  separated from localjump_destination().\n\n\t* eval.c (break_jump): break innermost loop (or thread or proc).\n\n\t* eval.c (rb_yield_0): set exit_value for block break.\n\nWed Mar 10 15:58:43 2004  Ryan Davis  <ryand@zenspider.com>\n\n\t* eval.c (eval): Only print backtrace if generating the backtrace\n\t  doesn't generate an exception.  [ruby-core:02621]\n\nTue Mar  9 13:04:26 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_ungetc): raise IOError instead of calling\n\t  rb_sys_fail().  [ruby-talk:23181]\n\nMon Mar  8 19:32:28 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/common.rb (URI::REGEXP::PATTERN::HOSTPORT): (?:#{PORT})\n\t  -> (?::#{PORT}).  [ruby-dev:23170]\n\nMon Mar  8 15:31:41 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (range): treat incomplete '[' as ordinary character (like\n\t  has_magic does).\n\n\t* dir.c (range):  Cancel above change. More discussion is needed.\n\nSun Mar  7 22:37:46 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/drb/ut_drb.rb: use 'druby://localhost:0'. [ruby-dev:23078]\n\n\t* test/drb/ut_eval.rb: ditto.\n\n\t* test/drb/ut_large.rb: ditto.\n\n\t* test/drb/ut_safe1.rb: ditto.\n\n\t* test/drb/ut_drb_drbssl.rb: use 'drbssl://localhost:0'.\n\nSun Mar  7 16:22:26 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* Makefile.in (lex.c): use $? instead of $<.\n\nFri Mar  5 00:54:14 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/test/unit.rb: MOve RDoc documentation so that you can\n\t  now say 'ri Test::Unit'\n\nTue Mar  2 12:32:59 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub, wince/Makefile.sub (config.h): shouldn't check\n\t  defined? NORETURN. [ruby-dev:23100]\n\nMon Mar  1 12:24:10 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_alias):\n\t  Allow aliases to have parentheses\n\nSun Feb 29 23:14:53 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_class):\n\t  Handle :nodoc: on singleton classes.\n\nSat Feb 28 10:58:49 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* MANIFEST: add test_erb.rb\n\n\t* lib/erb.rb, test/erb/test_erb.rb: don't forget filename,\n\t  if both filename and safe_level given. [ruby-dev:23050]\n\nFri Feb 27 01:00:09 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb, test/drb/drbtest.rb: require drb/eq.rb by default\n\nWed Feb 25 21:16:25 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* instruby.rb (with_destdir): should return the given argument if no\n\t  DESTDIR is given.\n\n\t* instruby.rb: use path name expansion of cmd.exe.\n\nWed Feb 25 09:35:22 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* error.c (NameError::Message): new class for lazy evaluation of\n\t  message to ensure replaced before marshalling. merge from HEAD.\n\t  (ruby-bugs-ja:PR#588)\n\n\t* eval.c (rb_method_missing): use NameError::Message. merge from\n\t  HEAD. (ruby-bugs-ja:PR#588)\n\nTue Feb 24 18:59:37 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (glob_helper): '**/' should not match leading period\n\t  unless File::FNM_DOTMATCH is set. (like '*/') [ruby-dev:23014]\n\nTue Feb 24 13:22:21 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/rdoc.rb (RDoc::RDoc::normalized_file_list): Attempt to get better\n\t  heuristics on which files to include and exclude. Now only include\n\t  non-standard files if they are explicitly named in ARGV.\n\nTue Feb 24 07:23:30 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Deal with :stopdoc: when\n\t  choosing a default main page to display (ie. don't select a page\n\t  if we don't have documentation for it).\n\nTue Feb 24 06:40:14 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RubyLex::identify_identifier): Handle\n\t  class variables in code listings\n\nTue Feb 24 06:40:14 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RubyLex::identify_identifier): Handle\n\t  class variables in code listings\n\nTue Feb 24 06:32:27 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::do_aliases): Handle\n\t  aliases in C files.\n\nTue Feb 24 06:16:22 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/rdoc.rb (RDoc::RDoc::document): Now create op dir _before_\n\t  parsing files.\n\nTue Feb 24 06:08:47 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_constant):\n\t  Start collecting text of constant values earlier: was missing\n\t  values in output if there was no space after '='\n\nTue Feb 24 06:08:25 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Escape contant values.\n\nTue Feb 24 03:45:06 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_config.c (ossl_config_each): add new method\n\t  OpenSSL::Config#each. it iterates with section name, field name\n\t  and value.\n\n\t* ext/openssl/ossl_config.c (Init_ossl_config): include Enumerable.\n\nMon Feb 23 09:16:35 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* instruby.rb (DOSISH): embedded path in batch files should not be\n\t  prefixed by DESTDIR.  [ruby-core:02186]\n\nSun Feb 22 09:54:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* re.c: corrected documentation format (again)\n\nSun Feb 22 09:43:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* re.c: corrected documentation format (rb_reg_initialize_m)\n\nSat Feb 21 22:36:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* ext/zlib/zlib.c: documented, but needs more effort.\n\nSat Feb 21 11:12:15 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* missing/os2.c, missing/x68.c: typo fix.  pointed out by greentea.\n\nFri Feb 20 18:59:47 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/init.rb (IRB::IRB.parse_opts): add -I option to\n\t  irb. [ruby-dev:39243]\n\nThu Feb 19 23:24:16 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb (Generators::HtmlClass::build_attribute_list):\n\t  Support visibility modifiers for attributes\n\nThu Feb 19 23:24:16 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb (Generators::HtmlClass::build_attribute_list):\n\t  Support visibility modifiers for attributes\n\nThu Feb 19 22:39:04 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/rinda/test_rinda.rb: DRb.start_service only once in testsuites.\n\t  DRb.start_service could handle this.\n\nThu Feb 19 22:19:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/ostruct.rb: documented\n\nThu Feb 19 21:28:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* ext/strscan/strscan.c: improved documentation\n\nThu Feb 19 03:10:52 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: synchronized with main trunk (rev 1.11).\n\nThu Feb 19 02:30:34 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: documentation checked.\n\nThu Feb 19 00:11:05 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/markup/simple_markup/preprocess.rb (SM::PreProcess::handle):\n\t  Strip extraneous space from filenames in :include:\n\nWed Feb 18 22:52:00 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/unix.rb: remove O_NONBLOCK, thanks \\ay\n\nWed Feb 18 22:47:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* ext/strscan/strscan.c: documented\n\nWed Feb 18 22:03:11 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/*: should not depend on $KCODE.\n\nWed Feb 18 17:18:01 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/win32ole/win32ole.c: need to include <olectl.h> on Cygwin.\n\nWed Feb 18 10:40:38 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): do not prepend dots for negative\n\t  numbers if FZERO is specified.  [ruby-list:39218]\n\nTue Feb 17 23:40:34 2004  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* sprintf.c (rb_f_sprintf): preserve original val for\n\t  format_integer. [ruby-talk:92975]\n\nTue Feb 17 23:28:45 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/marshaltestlib.rb: common marshal testcase added.\n\n\t* test/ruby/test_marshal.rb: use above testsuite.\n\n\t* test/soap/marshal/test_marshal.rb: ditto.\n\n\t* test/soap/marshal/cmarshal.rb: removed (not used).\n\nTue Feb 17 10:51:23 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_emitter_end_object): takes only one arg.\n\nTue Feb 17 01:35:28 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (rb_eval): care that another thread replace NODE_DREGX_ONCE\n\t  to NODE_LIT.  [ruby-dev:22920]\n\nTue Feb 17 01:24:35 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub (config.h): define\n\t  STACK_GROW_DIRECTION. [ruby-dev:22910]\n\n\t* bcc32/Makefile.sub (config.h): add newer checks.\n\n\t* wince/Makefile.sub (config.h): define NEED_IO_SEEK_BETWEEN_RW.\n\nTue Feb 17 00:38:10 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb: TupleSpace#initialize, stop doubling timeout\n\nTue Feb 17 00:18:03 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/rinda/test_rinda.rb: import test_rinda.rb\n\nTue Feb 17 00:14:30 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: avoid warning \"Redefinition of macro\n\t  'HAVE_GETLOGIN'\".\n\n\t* vms/config.h_in: ditto.\n\nMon Feb 16 23:28:14 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/csv.rb: document reduction.  [ruby-core:02429]\n\nMon Feb 16 22:08:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/generator.rb: corrected doc format\n\t* lib/rinda/rinda.rb: added documentation (from Hugh Sasse)\n\t* lib/rinda/tuplespace.rb: ditto\n\nMon Feb 16 20:41:32 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: show more warnings. (refering to mingw)\n\n\t* bcc32/setup.mak: ditto.\n\nMon Feb 16 13:39:44 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (rb_glob, rb_globi): add const.\n\n\t* ruby.h: ditto.\n\nMon Feb 16 02:16:33 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* bcc32/Makefile.sub: should warn suspicious pointer conversion.\n\n\t* bcc32/setup.mak: ditto.\n\nSun Feb 15 19:06:42 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/tuplespace.rb: TupleSpace#read(tpl, 0), raise\n\t  RequestExpiredError if not found.\n\nSun Feb 15 15:56:46 2004  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c: add IDispatch wrapper in val2variant.\n\t  Thanks, arton.\n\nSun Feb 15 01:46:05 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/mkmf.rb: absolute path of ruby is assigned to $(RUBY).\n\t  [ruby-dev:22870]\n\nSat Feb 14 11:29:41 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* sample/drb/*: import lib/drb/sample\n\nSat Feb 14 11:08:23 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: add pretty_print, thanks gotoken.\n\nFri Feb 13 12:35:08 2004  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: File.link may raise EINVAL and\n\t  EACCES on Windows.\n\nThu Feb 12 21:45:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/ftools.rb: documented\n\nThu Feb 12 21:25:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/base64.rb: backported from HEAD (modularised and documented)\n\nThu Feb 12 20:31:48 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_tmpsrc): cpp32 of Borland C++ ignores #error\n\t  directives in DOS line-ending files at all.\n\nThu Feb 12 02:23:56 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb: use assert_raise instead of assert_raises.\n\n\t* lib/pp.rb: ditto.\n\n\t* lib/time.rb: ditto.\n\n\t* lib/tsort.rb: ditto.\n\t  use TSortHash and TSortArray instead of Hash and Array in test.\n\nWed Feb 11 20:01:12 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* test/ruby/test_file.rb (TestFile::test_fnmatch): added tests for\n\t  File.fnmatch. [ruby-dev:22815][ruby-dev:22819]\n\n\t* test/ruby/test_proc.rb (TestProc::test_eq): added a\n\t  test.  [ruby-dev:22599]\n\n\t* test/ruby/test_proc.rb (TestProc::test_eq): added tests for\n\t   Proc#==.  [ruby-dev:22592], [ruby-dev:22601]\n\nTue Feb 10 16:43:56 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (umethod_bind): purge unused check.  [ruby-dev:22850]\n\nMon Feb  9 17:16:00 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/rdoc/parsers/parse_c.rb: escape '{' and '}' to avoid warnings.\n\nMon Feb  9 13:00:55 2004  Hirokazu Yamamoto  <ocean@m2.ccsnet.ne.jp>\n\n\t* dir.c (fnmatch): File.fnmatch('*?', 'a') should return true.\n\t  [ruby-dev:22815]\n\n\t* dir.c (fnmatch): File.fnmatch('\\[1\\]' , '[1]') should return true.\n\t  [ruby-dev:22819]\n\nSun Feb  8 16:46:13 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/pp.rb (PP::PPMethods::object_address_group): suppress negative\n\t  sign for higher heap areas.\n\nFri Feb  6 22:48:16 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb (gen_url): Support\n\t  https in RDoc hyperlinks\n\nFri Feb  6 22:41:22 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/pp.rb (PPInspectTest#test_to_s_with_iv): rollback the previous\n\t  commit.  [ruby-dev:22813]\n\nFri Feb  6 22:22:50 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/pp.rb (PPInspectTest#test_to_s_with_iv): remove instance\n\t  variable which is defined in the test.\n\nFri Feb  6 00:48:37 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/prettyprint.rb (PrettyPrint#first?): obsoleted.\n\nThu Feb  5 23:56:55 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/prettyprint.rb (PrettyPrint#seplist): added.\n\n\t* lib/pp.rb (PPMethods#pp_object): use seplist.\n\t  (PPMethods#pp_hash): ditto.\n\t  (Array#pretty_print): ditto.\n\t  (Struct#pretty_print): ditto.\n\t  (MatchData#pretty_print): ditto.\n\n\t* lib/set.rb (Set#pretty_print): use seplist.\n\nWed Feb  4 02:12:06 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* file.c (test_l): fix wrong method name in document.\n\t  (test_S): ditto.\n\t  (test_b): ditto.\n\t  (test_c): ditto.\n\t  (test_suid): ditto.\n\t  (test_sgid): ditto.\n\t  (test_sticky): ditto.\n\nTue Feb  3 08:04:57 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (Struct#pretty_print_cycle): follow 1.8 style.\n\nMon Feb  2 19:33:49 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: backport from 1.9 for Interix.\n\n\t* dln.c (dln_load): ditto.\n\nMon Feb  2 13:31:51 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/net/http.rb (canonical_each): fix merge miss.\n\nMon Feb  2 01:54:00 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (Struct#pretty_print): make it 1.8 style.\n\t  (Numeric#pretty_print, FalseClass#pretty_print)\n\t  (TrueClass#pretty_print, Module#pretty_print): fix pp for objects\n\t  with instance variables.  [ruby-talk:91157]\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): return nil on loopback\n\t  address.\n\n\t* lib/resolv-replace.rb (BasicSocket#send): don't replace because\n\t  it has no hostname argument.\n\t  (IPSocket.getaddress): raise SocketError instead of\n\t  Resolv::ResolvError for errors.\n\t  (TCPSocket#initialize, UDPSocket#bind, UDPSocket#connect)\n\t  (SOCKSSocket#initialize): use IPSocket.getaddress instead of\n\t  Resolv.getaddress.\n\t  (UDPSocket#send): recognize 3 arguments form.  try all addresses on\n\t  4 arguments form.\n\nSun Feb  1 18:17:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/net/http.rb: merged coding style changes from HEAD.\n\nSun Feb  1 16:15:00 2004  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/test/unit.rb: rearranged documentation for RDoc's sake.\n\t* lib/matrix.rb: improved documentation.\n\t* lib/net/http.rb: slight documentation formatting improvement.\n\nSun Feb  1 05:30:06 2004  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): warn HTTP_PROXY.\n\t raise an errror on non-http proxy URI.\n\t (OpenURI::Buffer#<<): make a tempfile binmode.  [ruby-talk:90793]\n\nSat Jan 31 09:20:32 2004  NAKAMURA, Hiroshi  <nakahiro@sairon.co.jp>\n\n\t* sample/openssl/gen_csr.rb: wrong usage string.\n\nSat Jan 31 01:00:32 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/wsdlDriver.rb, lib/wsdl/soap/operation.rb: add support of\n\t  \"parts\" attribute of soap:body element in WSDL.\n\n\t* lib/wsdl/xmlSchema/schema.rb: friendly warning message for\n\t  simpleType element which is not supported for now.\n\n\t* lib/soap/mapping/factory.rb: deleted unused methods.\n\n\t* lib/soap/mapping/rubytypeFactory.rb: do no ignore case while xsi:type\n\t  string <-> Ruby class name matching.\n\n\t* test/wsdl/soap/{soapbodyparts.wsdl,test_soapbodyparts.wsdl}: new\n\t  files.\n\nThu Jan 29 23:56:00 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* util.c (mblen): fix overrun.  [ruby-dev:22672]\n\nThu Jan 29 22:41:53 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Allow 'link:' in Tidylinks.\n\t  THis means you can write \"see f1[link:files/f1_rb.html]\".\n\nThu Jan 29 15:33:23 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509hame.c (ossl_x509name_initialize): change\n\t  second argument. it expected to be a Hash not an Integer.\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_add_entry): add new\n\t  function for OpenSSL::X509::Name#add_entry.\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_to_a): append ASN.1\n\t  tag number to each element of return value.\n\n\t* ext/openssl/ossl_x509name.c (Init_ossl_x509name): add constants\n\t  OpenSSL::X509::Name::DEFAULT_OBJECT_TYPE and OBJECT_TYPE_TEMPLATE.\n\n\t* ext/openssl/lib/openssl/x509.rb (OpenSSL::X509::Name#initialize):\n\t  second argument takes OBJECT_TYPE_TEMPLATE by default.\n\n\t* sample/openssl/gen_csr.rb: use OpenSSL::X509::Name.parse.\n\nWed Jan 28 04:29:41 2004  Eric Schwartz  <emschwar@fc.hp.com>\n\n\t* lib/cgi/session.rb: use LOCK_SH to read, and a few other\n\t  improvements.  [ruby-core:02328]\n\nTue Jan 27 11:09:29 2004  FUKUMOTO Atsushi  <fukumoto@nospam.imasy.or.jp>\n\n\t* ext/socket/socket.c (s_recvfrom): sending length should be an\n\t  invariant while retrying on EAGAIN.  [ruby-talk:89962]\n\nTue Jan 27 10:35:18 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/win32ole/win32ole.c (set_argv): fix condition.\n\nTue Jan 27 02:26:31 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httputils.rb (WEBrick:HTTPUtils::parse_header):\n\t  refine regex for header-name.\n\nTue Jan 27 00:30:11 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub: rollback.\n\nMon Jan 26 22:53:04 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* io.c: Remove documentation references to $defout.\n\nMon Jan 26 15:11:47 2004  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* sample/exyacc.rb: escape '}' to avoid warning.\n\nMon Jan 26 14:41:46 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/delegate.rb (Delegator::initialize): preserve\n\t  singleton_method_added method [ruby-dev:22685]\n\n\t* lib/delegate.rb (Delegator::initialize): use Kernel::raise\n\t  instead of mere raise.  [ruby-dev:22681]\n\nMon Jan 26 12:47:17 2004  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: define CONST84 when TCL_MAJOR_VERSION == 7\n\nMon Jan 26 11:35:23 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb: Makefiles should depend on also rbconfig.rb.\n\t  (ruby-bugs:PR#1256)\n\n\t* ext/win32ole/win32ole.c (set_argv): set real arguments to\n\t  WIN32OLE::ARGV.  [ruby-list:39073]\n\nThu Jan 22 22:54:53 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (BEG_REGEXP): allow 8-bit characters in quoted\n\t  strings for Novell GroupWise Internet Agent.\n\t* lib/net/imap.rb (DATA_REGEXP): ditto.\n\nThu Jan 22 16:21:33 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (string_content): reset lexical states at the beginning of\n\t  string contents.  [ruby-list:39061]\n\nWed Jan 21 21:55:51 2004  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: remove O_NONBLOCK, thanks \\ay\n\t* lib/drb/extserv.rb: typo\n\nWed Jan 21 17:57:56 2004  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (envelope): allow NIL.\n\t* lib/net/imap.rb (body): ditto.\n\t* lib/net/imap.rb (number): ditto.\n\t* lib/net/imap.rb (ensure_nz_number): show a detailed error\n\t  message.\n\nWed Jan 21 16:44:20 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (merge_libs): squeeze successive same libraries.\n\t  [ruby-dev:22652]\n\nWed Jan 21 16:01:37 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/digest/rmd160/extconf.rb: have_library appends found library.\n\nWed Jan 21 11:36:00 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (block_append): update nd_end for \"real\" head node.\n\t  [ruby-list:39058]\n\nTue Jan 20 14:48:13 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: should check <openssl/conf_api.h> instead\n\t  of OPENSSL_VERSION_NUMBER. [ruby-list:39056]\n\nTue Jan 20 14:43:17 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/base64.rb: Add RDoc\n\nTue Jan 20 14:25:51 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/abbrev.rb: Add RDoc\n\nTue Jan 20 13:22:39 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Document aliases at\n\t  top-most level.\n\n\t* lib/English.rb: Document English.rb.\n\nTue Jan 20 02:49:22 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: add check for OpenSSL version.\n\t  [ruby-list:39054]\n\nTue Jan 20 02:38:13 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_class): should not dump singleton class.\n\t  [ruby-dev:22631]\n\nTue Jan 20 01:31:36 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (lineno): typo fix(FIX2INT -> INT2FIX).\n\nMon Jan 19 21:53:38 2004  akira yamada  <akira@ruby-lang.org>\n\n\t* io.c, re.c, string.c, time.c: fixed up positions of RDocs.\n\nMon Jan 19 07:09:20 2004  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb: zone was wrong when it was behind UTC.\n\t  Thanks Mark J. Reed.\n\n\t* lib/date/format.rb: %z is now always replaced by four digits\n\t  with a leading plus or minus sign.\n\n\t* sample/cal.rb: added a class, anyway.\n\nSun Jan 18 20:47:35 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.c: use translate_char() on Cygwin.\n\nSun Jan 18 02:33:26 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* defines.h (_WIN32): undef _WIN32 on Cygwin before defining DOSISH.\n\nSun Jan 18 00:23:55 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (class2path): check anonymous class/module before\n\t  checking referable, and allow singleton classes.\n\nFri Jan 16 14:33:35 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (class2path): get class path and check referable.\n\t  [ruby-dev:22588]\n\nFri Jan 16 09:52:23 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_eq): Proc with empty body may not be equal.\n\t  [ruby-dev:22590]\n\nThu Jan 15 13:03:10 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (argf_read): do not append EOF.  (ruby-bugs-ja:PR#585)\n\n\t* io.c (rb_io_fwrite): ad-hockery hack to get rid of HP-UX stdio\n\t  weird behavior.  [ruby-dev:22424]\n\nWed Jan 14 13:31:06 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/extconf.rb: wrapper iconv.rb is dependent on platform.\n\nTue Jan 13 18:54:28 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb(Logger#msg2str): no special treatment for the object\n\t  which responds to :to_str.  commited at 2004-01-11T21:46:27 by\n\t  gsinclair.\n\n\t* lib/logger.rb(LogDevice#initialize): remove type checking if the\n\t  given object is a String.  Kernel.open handles it correctly.\n\t  commited at 2004-01-11T21:46:27 by gsinclair.\n\n\t* test/logger/test_logger.rb: follow above change (ArgumentError ->\n\t  TypeError.)  follow above commit.\n\nTue Jan 13 14:27:13 2004  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* lib/test/unit/ui/testrunnerutilities.rb (TestRunnerUtilities):\n\t  moved run method which allows output level.  [ruby-dev:22554]\n\nTue Jan 13 04:29:52 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_driver.rb (RiDriver::report_method_stuff):\n\t  Show fully-qualified class names in class list.\n\nTue Jan 13 01:04:37 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_paths.rb (RI::Paths): First attempt at\n\t  incorporating DESTDIR in the rdoc installation.\n\nMon Jan 12 23:27:19 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (primary): fix position after FCALL.  [ruby-dev:22574]\n\nMon Jan 12 12:07:22 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::do_methods):\n\t  Someone changed the \"// in eval.c\" comments to \"/*...*/\" style,\n\t  so the parsing of the source file name broke.\n\n\t* object.c: Remove spurious space in TrueClass documentation.\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_body): Fix\n\t  bad regexp: if the code before a documented method contained\n\t  a comment that wasn't terminated by whitespace, that comment\n\t  and all intervening code was included in the following\n\t  method's documentation.\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::HtmlFormatter::break_to_newline):\n\t  HTML formats need explicit line breaks.\n\nMon Jan 12 11:46:30 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (LIBPATHFLAG, RPATHFLAG): enclose paths with single\n\t  quotes.  [ruby-dev:22564]\n\n\t* lib/mkmf.rb (libpathflag): do not enclose with quotes always.\n\n\t* {bcc32,win32,wince}/Makefile.sub (LIBPATHFLAG): quoted.\n\nMon Jan 12 02:24:07 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::HtmlFormatter): Add HTML\n\t  generation support to ri (Elliot Hughes)\n\nMon Jan 12 02:24:07 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::HtmlFormatter): Add HTML\n\t  generation support to ri (Elliot Hughes)\n\nSun Jan 11 02:07:47 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_options.rb (RI::Options::OptionList::OptionList):\n\t  Also accept command line options via the 'RI' environment variable.\n\nSun Jan 11 02:07:47 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_options.rb (RI::Options::OptionList::OptionList):\n\t  Also accept command line options via the 'RI' environment variable.\n\nSat Jan 10 21:27:41 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): need to add message delimiter. [ruby-dev:22561]\n\nSat Jan 10 01:54:50 2004  Eric Sunshine  <sunshine@sunshineco.com>\n\n\t* defines.h (__NeXT__): Ensure that all standard S_IRUSR, S_IWGRP,\n\t  S_IRWXO, etc. macros are defined since future code might require\n\t  them (even though present code only requires a subset).\n\n\t* defines.h (__NeXT__): Bug fix: WORDS_BIGENDIAN was not being set\n\t  correctly on Rhapsody when -arch compiler flag was used (via\n\t  configure's --enable-fat-binary option).\n\nFri Jan  9 10:05:14 2004  Siena.  <siena@faculty.chiba-u.jp>\n\n\t* lib/mkmf.rb (libpathflag): use single quotes.  [ruby-dev:22440]\n\nThu Jan  8 23:49:21 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (RDOCTARGET): new macro.  if you want to install\n\t  rdoc documentation, you need to run configure with\n\t  --enable-install-doc.\n\nThu Jan  8 21:29:43 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_pkey.c (ossl_pkey_to_der): removed; it returns\n\t  public key only.\n\n\t* ext/openssl/ossl_pkey_dh.c (ossl_dh_to_der): new function for\n\t  OpenSSL::PKey::DH#to_der.\n\n\t* ext/openssl/ossl_pkey_dsa.c (ossl_dsa_to_der): new function for\n\t  OpenSSL::PKey::DSA#to_der.\n\n\t* ext/openssl/ossl_pkey_rsa.c (ossl_rsa_to_der): new function for\n\t  OpenSSL::PKey::RSA#to_der.\n\nThu Jan  8 16:51:04 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/wsdl/datetime/test_datetime.rb: fixed a stupid testcase which\n\t  dumps \"E\" at month-end.\n\nThu Jan  8 11:20:01 2004  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c, object.c, process.c, re.c: don't use C++ style comments.\n\nThu Jan  8 04:36:21 2004  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (WEBrick::CGI#initialize): should create\n\t  @config[:Logger] if it was not given.\n\n\t* sample/webrick/*: new files.\n\n\t* MANIFEST: add sample/webrick/*\n\nWed Jan  7 13:00:18 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_driver.rb: Fix problem where ri was\n\t  being too eager to find matches of ambiguous method\n\t  names (such as \"ri Thread.join\" would return both\n\t  Thread.join and ThreadsWait.join)\n\nWed Jan  7 12:35:41 2004  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/debug.rb: revert command parse regexps.  [ruby-list:39014] by\n\t  Shirai,Kaoru.\n\nWed Jan  7 08:21:04 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parserfactory.rb: Check for shebang\n\t  line in files that would otherwise be treated as\n\t  plain text.\n\nTue Jan  6 22:13:34 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_modfunc): should break if m has no super class.\n\t  [ruby-dev:22498]\n\nTue Jan  6 21:55:02 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (fptr_finalize): should save errno just after failure.\n\t  [ruby-dev:22492]\n\nTue Jan  6 14:53:14 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* bin/ri: split out the display side, making it pluggable. Added\n\t  new ri_driver and ri_display files in lib/rdoc/ri.\n\nTue Jan  6 06:37:53 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* bin/rdoc: Add --ri-system switch\n\n\t* lib/.document: Update with list of files that seem to have\n\t  documentation\n\n\t* lib/test/unit.rb: Reorder comment to make it RDoc friendly.\n\n\t* Makefile.in: add install-nodoc target, and make it\n\t  generate RDoc on default install.\n\n\t* lib/rdoc/ri/ri_options.rb (RI::Options::parse): Add\n\t  --doc-dir option to ri.\n\nTue Jan  6 00:04:40 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_method_or_yield_parameters):\n\t  fix parsing if there are braces in a method parameter list\n\nFri Jan  2 14:54:11 2004  Dave Thomas  <dave@pragprog.com>\n\n\t* bin/ri: Add new --classes option, and arrange for\n\t  help messages to be paged too.\n\n\t* bin/rdoc: Add statistics.\n\n\t* process.c: (MG) Added Process documentation\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::AttributeFormatter::wrap):\n\t  Fix problem with labels not displaying in RI labeled\n\t  lists using BS and ANSI modes.\n\nFri Jan  2 01:50:13 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_eof): ARGF.eof? should not have any side effect.\n\t  [ruby-dev:22469]\n\nWed Dec 31 17:25:17 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_each_byte): should return self.  [ruby-dev:22465]\n\nWed Dec 31 11:20:34 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::do_methods): Make\n\t  file referenced in \"// in sss.c\" relative to current file.\n\nWed Dec 31 11:17:37 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/generators/html_generator.rb: Fix problem when\n\t  a public method was aliased, but the alias is then\n\t  made private, and hence doesn't appear in RDoc output.\n\nWed Dec 31 01:33:05 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* array.c, error.c, eval.c, io.c, prec.c, range.c, re.c,\n\t  string.c, time.c: Add RDoc for Kernel functions, and tidy.\n\nTue Dec 30 19:39:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_readline): should raise EOFError at the end of\n\t  files.  [ruby-dev:22458]\n\n\t* io.c (argf_read): should concatenate input files when length\n\t  argument is nil. [ruby-dev:22450]\n\n\t* io.c (argf_read): should update supplied string buffer (2nd\n\t  argument) even when IO#read is called multiple times.\n\n\t* io.c: should initialize lineno by zero. [ruby-dev:22460]\n\nTue Dec 30 12:30:30 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/code_objects.rb (RDoc::Context::find_symbol): If a\n\t  class and a method have the same name, finding Xxx.abc was trying\n\t  to find 'abc' in method 'Xxx', not class 'Xxx'.\n\nTue Dec 30 08:32:32 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_method):\n\t  Handle undoing nesting of yield parameters correctly for:\n\n\t  def each_entry(&b) Dir.foreach(@path) {|f| yield P.new(f) } end\n\nTue Dec 30 08:32:32 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_method):\n\t  Handle undoing nesting of yield parameters correctly for:\n\n\t    def each_entry(&block) Dir.foreach(@path) {|f| yield Pathname.new(f) } end\n\nMon Dec 29 12:51:02 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* eval.c: Add RDoc for Kernel global functions.\n\nMon Dec 29 11:00:16 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* array.c: Tidy up RDoc loose ends.\n\nMon Dec 29 05:05:51 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* struct.c, random: Add RDoc comments\n\nMon Dec 29 02:20:54 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* eval.c: Add RDoc for class Proc, Method, UnboundMethod\n\nMon Dec 29 00:41:44 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* math.c: Add RDoc comments\n\nSun Dec 28 20:19:11 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/stringio/stringio.c (strio_sysread): StringIO.new.sysread didn't\n\t  raise EOFError.\n\n\t* ext/zlib/zlib.c (gzreader_gets): don't increment lineno when\n\t  gzfile_read_all returns \"\".\n\nSun Dec 28 15:25:08 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* class.c,object.c,parse.y,sprintf.c,variable.c: Document classes\n\t  Object, Module, etc...\n\nSun Dec 28 11:55:29 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/csv/test_csv.rb: generate bom.csv and mac.csv files on the fly.\n\t  [ruby-talk:88852]\n\n\t* test/csv/{bom.csv,mac.csv}: removed.\n\nSun Dec 28 08:56:51 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* eval.c: Thead[Group] RDoc (thanks to MG)\n\nSun Dec 28 03:50:05 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_override_comment):\n\t  Escape method names used in regexp\n\nSun Dec 28 01:46:02 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/ri/ri_formatter.rb (RI::TextFormatter::display_flow_item):\n\t  Add support for rules in 'ri' output.\n\nSun Dec 28 01:35:35 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_body):\n\t  Sometimes the Ruby source aliases two otherwise\n\t  unrelated methods (for example Kernel#object_id and\n\t  Kernel#hash are both the same C function). Provide a\n\t  facility to allow the methods to be documented\n\t  separately.\n\nSun Dec 28 01:05:31 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* marshal.c, signal.c: RDoc collemts added by Elliott Hughes\n\nSun Dec 28 00:48:47 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/parsers/parse_c.rb (RDoc::C_Parser::find_class_comment):\n\t  Some source files use lower case class or module names\n\t  when naming the Init_XXX function in C.\n\nSat Dec 27 23:41:46 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: fix \"test: too many arguments\" error.\n\nSat Dec 27 15:32:19 2003  Dave Thomas  <dave@wireless_3.local.thomases.com>\n\n\t* time.c: RDoc comments added\n\nSat Dec 27 15:07:57 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* object.c: Add RDoc comments for Symbol class.\n\nSat Dec 27 14:42:30 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* numeric.c: Add RDoc comments.\n\nSat Dec 27 00:44:00 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (next_argv): warn always for stdin on inplace edit mode.\n\n\t* io.c (read_all): need to check string value.\n\n\t* io.c (argf_read): allow ARGF.read(nil).  [ruby-dev:22433]\n\nFri Dec 26 23:02:09 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_backquote): need not to check nil result.\n\t  [ruby-core:02078]\n\n\t* io.c (rb_io_getline): should return nil when read_all gives\n\t  empty string, even when nil rs is specified. [ruby-core:02077]\n\nFri Dec 26 18:50:59 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: check if getcontext and setcontext are available.\n\n\t* eval.c: use presence of getcontext/setcontext.\n\nFri Dec 26 16:40:53 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (PathnameTest#test_plus): add 2 assertions.\n\nFri Dec 26 09:26:58 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): add sign check for 'i', and 'l'.\n\t  [ruby-dev:22427]\n\n\t* bignum.c (rb_quad_pack): add range check for 'quad int'.\n\nThu Dec 25 22:39:59 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* string.c (rb_str_update): don't return any value.\n\nThu Dec 25 15:30:17 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_update): call rb_str_modify().\n\nThu Dec 25 05:08:09 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (search_required): search actual file name once when no\n\t  extension specified.\n\nThu Dec 25 04:00:44 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.8.1 released.\n\nThu Dec 25 00:17:53 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: check for nanosleep, -lrt if required.\n\t  [ruby-core:02059]\n\n\t* eval.c (thread_timer): use select(2) if nanosleep(2) is not\n\t  available.\n\n\t* eval.c: check __stub_getcontext for glibc on some platforms.\n\t  [ruby-list:38984]\n\nWed Dec 24 23:48:04 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/test_basetype.rb, test/soap/marshal/test_marshal.rb\n\t  test/xsd/test_xsd.rb: use \"(-1.0 / (1.0 / 0.0))\" instead of \"-0.0\"\n\t  to express -0.0.  [ruby-talk:88786]\n\nWed Dec 24 23:29:30 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/tsort.rb (test_orphaned_break): removed.\n\nWed Dec 24 20:53:06 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tkmulticolumnlist.rb: new sample\n\n\t* ext/tk/sample/tkmultilistframe.rb: bug fix\n\nWed Dec 24 20:37:37 2003  Eric Sunshine  <sunshine@sunshineco.com>\n\n\t* configure.in (LDSHARED): Fixed typographical error in assignment of\n\t  LDSHARED for Rhapsody which caused linking of extension modules to\n\t  fail.\n\nWed Dec 24 17:51:18 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_thread_flock): enable thread support again.\n\nWed Dec 24 16:46:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (catch_timer): do not call rb_thread_schedule() inside to\n\t  avoid pthread_mutex_lock() deadlock.  interrupts to system calls\n\t  are detected by TRAP_END via EINTR error.\n\n\t* eval.c (thread_timer): do not post signal unless it is\n\t  absolutely necessary.\n\n\t* rubysig.h (TRAP_END): add CHECK_INTS to switch thread.\n\n\t* regex.c (re_compile_pattern): check if nextp is smaller than\n\t  pend.  [ruby-dev:22372]\n\n\t* eval.c (umethod_bind): remove method overridden check.\n\t  [ruby-dev:22366]\n\nWed Dec 24 16:13:05 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_read): should check for error\n\t  status by SSL_get_error().\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_write): ditto.\n\nWed Dec 24 14:23:27 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): clear the buffer argument\n\t  when returning nil.  [ruby-dev:22363]\n\n\t* test/ruby/ut_eof.rb (TestEOF::test_eof_0, TestEOF::test_eof_1):\n\t  add buffer argument tests.\n\nWed Dec 24 14:07:55 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: Modules are allowed to rescue.\n\n\t* lib/test/unit/autorunner.rb: show output_level in order.\n\n\t* lib/test/unit/collector/dir.rb: get rid of successive same\n\t  directories in load path.\n\n\t* test/testunit/test_assertions.rb (test_assert_nothing_raised,\n\t  test_assert_raise): test for modules.\n\nWed Dec 24 13:43:34 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (authenticate): remove \"\\n\" from base64 encoded\n\t  strings.\n\nWed Dec 24 11:26:41 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/fileutils/test_fileutils.rb: should not create any\n\t  files or directories in current directory.  [ruby-talk:88724]\n\nWed Dec 24 10:29:53 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): never return nil at\n\t  unlimited read.  [ruby-dev:22334]\n\n\t* ext/stringio/stringio.c (strio_read): support second\n\t  argument.  [ruby-dev:22350]\n\nWed Dec 24 09:38:49 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (arg): should return 0 after error.  [ruby-dev:22360]\n\nWed Dec 24 00:56:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): do not return nil at the end of file.\n\t  [ruby-dev:22334]\n\n\t* io.c (argf_read): do not depend on nil at eof behavior of\n\t  IO#read().\n\n\t* eval.c (rb_thread_join): dup exception before re-raising it.\n\n\t* io.c (rb_io_eof): call clearerr() to prevent side effect.  this\n\t  patch is supplied by Masahiro Sakai <sakai@tom.sfc.keio.ac.jp>.\n\t  [ruby-dev:22234]\n\n\t* pack.c (OFF16): get offset for big endian machines.\n\n\t* pack.c (pack_pack): use OFF16 instead of OFF16B.\n\t  [ruby-dev:22344]\n\n\t* pack.c (pack_unpack): ditto.\n\nTue Dec 23 22:47:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_check_readable): set FMODE_RBUF always, even if\n\t  NEED_IO_SEEK_BETWEEN_RW is not defined. [ruby-dev:22340]\n\n\t* io.c (rb_io_check_writable): clear FMODE_RBUF before writing\n\t  something.\n\nTue Dec 23 22:25:00 2003  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/optparse.rb: incomplete RDoc documentation added in place of\n\t  existing RD comments.  Tabs converted to spaces.\n\nTue Dec 23 19:44:47 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/test_streamhandler.rb (test_basic_auth): removed.\n\t  soap4r + basic_auth is not officially supported in ruby/1.8.1 even\n\t  though soap4r + basic_auth + http-access2 should run fine.\n\nTue Dec 23 19:42:59 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_ungetc): raise an exception at unread stream to\n\t  avoid unspecified behavior.  [ruby-dev:22330]\n\n\t* test/ruby/test_system.rb (test_syntax): glob relatively from\n\t  __FILE__.\n\nTue Dec 23 18:09:40 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): remove unnecessary negative value check.\n\t  [ruby-dev:22329]\n\nTue Dec 23 17:26:55 2003  KONISHI Hiromasa  <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/Makefile.sub (config.h): bcc has finite(). [ruby-list:38940]\n\nTue Dec 23 16:08:16 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/rexml/encodings/US-ASCII.rb: typo.  [ruby-talk:88650]\n\n\t* test/ruby/test_system.rb: num of asserts depended on running dir.\n\n\t* test/xsd/test_noencoding.rb: rexml + without iconv/uconv cannot\n\t  handle euc-jp.  install iconv, uconv or xmlscan.\n\nTue Dec 23 14:13:51 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic::check_userinfo,\n\t  URI::Generic::check_user, URI::Generic::check_password): tests\n\t  conflicts/depends with other components closely.\n\n\t* test/uri/test_generic.rb (TestGeneric::test_set_component):\n\t  added tets.\n\nTue Dec 23 11:08:34 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/xsd/test_noencoding.rb: rescue Errno::EINVAL and do not test.\n\t  \"euc-jp\" might not be in supported encoding name list.\n\t  [ruby-talk:88650]\n\nTue Dec 23 06:10:31 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb (CGI): add support for mod_ruby.\n\n\t* lib/webrick/cgi.rb (CGI::Socket): add check for existence of\n\t  OpenSSL module in all HTTPS related methods.\n\n\t* lib/webrick/cgi.rb (CGI::Socket#cipher): should create similar\n\t  value to OpenSSL::SSLSocket#cipher.\n\n\t* lib/webrick/httpresponse.rb (HTTPResponse#setup_header): should\n\t  set \"connection: close\" if @keep_alive is false.\n\n\t* lib/webrick/https.rb (HTTPrequest#meta_vars): add supprt for\n\t  SSL_PROTOCOL, SSL_CIPHER_USEKEYSIZE and SSL_CIPHER_ALGKEYSIZE.\n\nMon Dec 22 23:00:05 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic::check_opaque): fixed typo.\n\nMon Dec 22 21:59:24 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (map_charset): always ensure code is a String.\n\nMon Dec 22 21:15:29 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* class.c (rb_mod_init_copy): always copy singleton class.\n\t  [ruby-dev:22325]\n\nMon Dec 22 20:44:36 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic#route_from): accepts urls which\n\t  has no host-part.\n\n\t* test/uri/test_generic.rb (TestGeneric::test_route): added a test.\n\nMon Dec 22 20:38:44 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/cgi.rb: reduce eval.\n\n\t* lib/cgi.rb (CGI::QueryExtension::read_multipart): alias path to\n\t  local_path.  [ruby-list:38883]\n\nMon Dec 22 20:09:31 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/test_property.rb: remove duplicated test method.\n\nMon Dec 22 18:22:04 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub (config.h): remove\n\t  HAVE_ISINF definition to follow previous commits of missing.h\n\t  and win32/win32.h.\n\nMon Dec 22 17:23:42 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (ac_cv_func_setitimer): moved from defines.h\n\n\t* defines.h, rubysig.h, signal.c: removed macro handling which\n\t  should be done in configure.\n\n\t* configure.in (intrinsics.h): check if present.\n\n\t* ruby.h: include intrinsics.h if available.\n\n\t* bignum.c, marshal.c: include ieeefp.h if available.\n\n\t* missing.h (isinf): define as a macro if finite() and isnan()\n\t  are available.  [ruby-core:02032]\n\nMon Dec 22 17:07:31 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (mingw): set isnan, finite and isinf to yes.\n\nMon Dec 22 13:40:19 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/property.rb: passing block by reference.\n\nMon Dec 22 00:32:43 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_with_disable_interrupt): use ENABLE_INTS instead of\n\t  ALLOW_INTS which may switch context.  [ruby-dev:22319]\n\n\t* ext/syck/emitter.c (syck_emitter_write): str bigger than\n\t  e->bufsize causes buffer overflow.  [ruby-dev:22307]\n\nSun Dec 21 17:29:00 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* class.c (rb_check_inheritable): new function.  [ruby-dev:22316]\n\n\t* intern.h: add prototype.\n\n\t* eval.c (superclass): use rb_check_inheritable().\n\n\t* object.c (rb_class_initialize): check argument validity.\n\nSun Dec 21 16:25:10 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#+): re-implemented to resolve \"..\" in\n\t  beginning of the argument.\n\t  (Pathname#join): concatenate from the last argument.\n\t  (Pathname#parent): just use Pathname#+.\n\nSun Dec 21 00:12:37 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add new methods (TkScrollbar#assign, assign_list)\n\n\t* ext/tk/sample/tkmultilistframe.rb: use TkScrollbar#assign method\n\nSat Dec 20 21:59:03 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httprequest.rb (HTTPRequest#meta_vars): refine regexp.\n\n\t* lib/webrick/cgi.rb (CGI#start): NPH scripts return status line\n\t  instead of Status: header field.\n\n\t* lib/webrick/cgi.rb (CGI::Socket): refine some coditions.\n\nSat Dec 20 16:07:14 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Completion::complete): wrong\n\t  Regexp for word boundary.  pointed out by Gavin Sinclair.\n\n\t* lib/optparse.rb (OptionParser::make_switch): [no-] prefix was\n\t  missing.\n\nSat Dec 20 11:40:10 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/yaml.rb (YAML::YAML): adjust Marshal version.\n\nSat Dec 20 03:56:02 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_with_disable_interrupt): prohibit thread context\n\t  switch during proc execution.  [ruby-dev:21899]\n\nSat Dec 20 02:41:02 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/cgi.rb: add file. (yet another CGI library)\n\n\t* MANIFEST: add lib/webrick/cgi.rb.\n\nSat Dec 20 02:18:31 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): proper indentation\n\t  inside of parentheses.  [ruby-dev:22308]\n\nFri Dec 19 21:24:22 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httprequest.rb (HTTPRequest#meta_vars): should not set\n\t  HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH.\n\n\t* lib/webrick/https.rb (HTTPRequest#parse): should check presence\n\t  of cert() method to detect SSLSocket.\n\nFri Dec 19 22:56:46 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/property.rb (SOAP::Property#load): new method for loading\n\t  property value into existing property tree.\n\n\t* test/soap/test_property.rb: add test.\n\nFri Dec 19 19:21:49 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/runit/cui/testrunner.rb (RUNIT::CUI::TestRunner::run):\n\t  should use Test::Unit::UI::{PROGRESS_ONLY,VERBOSE}.\n\nFri Dec 19 17:36:49 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tkmultilistbox.rb: bug fix\n\n\t* ext/tk/sample/tkmultilistframe.rb: new sample script\n\nFri Dec 19 03:44:27 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httputils.rb (parse_form_data): should return an\n\t  empty Hash if the body is empty.\n\nThu Dec 18 21:47:35 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): should remove deffile if it's\n\t  made by miniruby. based on nobu's patch.\n\nThu Dec 18 21:44:21 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (stack_extend): ignore inline optimization on VC7.\n\n\t* win32/Makefile.sub (OS, RT): can override.\n\n\t* win32/Makefile.sub (LDFLAGS): ditto. shouldn't use pdb:none\n\t  option. based on Tietew's patch [ruby-dev:22289]\n\nThu Dec 18 16:38:44 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (fnmatch): unlike find_dirsep(), rb_path_next() never\n\t  return NULL.\n\nThu Dec 18 15:27:59 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ipaddr.rb (IPSocket::getaddress): merge usa's patch.\n\t  [ruby-dev:21678]\n\nWed Dec 17 15:15:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::Value::[]): should work like\n\t  String#[] if more than one arguments are specified.\n\n\t* lib/delegate.rb: avoid using common instance name as \"@obj\".\n\n\t* lib/cgi.rb (CGI::QueryExtension::Value): Value is no longer\n\t  subclass of String, but DelegateClass(String).\n\n\t* ext/curses/extconf.rb: restore function check for init_color.\n\t  [ruby-list:38905]\n\n\t* Makefile.in: need to specify $(MAINLIBS) for the miniruby\n\t  generation rule.\n\n\t* configure.in: better FreeBSD -lc_r support.\n\nWed Dec 17 00:16:14 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: new method\n\t  StringScanner#beginning_of_line? (alias #bol?)\n\n\t* ext/strscan/strscan.c: new method StringScanner#concat and #<<.\n\n\t* ext/strscan/strscan.c: StringScanner#new(str) does not duplicate\n\t  nor freeze STR (allow destructive modification).\n\n\t* test/strscan/test_stringscanner.rb: test new methods above.\n\n\t* test/strscan/test_stringscanner.rb: test destructive string\n\t  modification.\n\nTue Dec 16 21:20:47 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb: don't use local variable `pp'.\n\n\t* lib/prettyprint.rb: ditto.\n\nTue Dec 16 13:20:43 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: condition bug of if statement on\n\t  {pack,grid}_propagate methods\n\nTue Dec 16 03:17:29 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb: comments in strings. [ruby-talk:88012]\n\n\t* test/yaml/test_yaml.rb: add test.\n\nTue Dec 16 01:14:44 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (catch_timer): check rb_thread_crtical in main native\n\t  thread.\n\n\t* eval.c (thread_timer): just sends signals periodically, to\n\t  prevent main native thread from receiving them in critical\n\t  section.  [ruby-core:01959]\n\nMon Dec 15 13:32:22 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (check_dirname): check string safety and remove extraneous\n\t  trailing directory separators.  [ruby-dev:22279]\n\n\t* file.c: renamed and externalized rb_path_next,\n\t  rb_path_skip_prefix, rb_path_last_separator, rb_path_end.\n\n\t* intern.h: prototypes for rb_path_next, rb_path_skip_prefix,\n\t  rb_path_last_separator, rb_path_end.\n\nMon Dec 15 09:27:46 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/openssl/ossl_pkcs12.c (ossl_pkcs12_initialize): first argument\n\t  of rb_protect should take an argument of VALUE.\n\nSun Dec 14 18:46:48 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/socket.c (Init_socket): IPv6 is not supported although\n\t  AF_INET6 is defined on MinGW.\n\n\t* lib/ipaddr.rb (AF_INET6): workaround in the environment which does\n\t  not support IPv6.\n\nSat Dec 13 18:55:16 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/charset_alias.rb: preserve original order.\n\n\t* ext/iconv/extconf.rb: remove wrapper file at clean.\n\nSat Dec 13 18:09:42 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (thread_timer): use timer by sub-thread and nanosleep.\n\t  [ruby-talk:87519]\n\n\t* gc.c (Init_stack): no stack adjustment for THREAD_SAFE.\n\nSat Dec 13 17:17:59 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_alloc): cache the created object at first time.\n\t  [ruby-talk:61288], [ruby-dev:22240]\n\nSat Dec 13 09:01:23 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in: check ucontext.h.\n\n\t* eval.c: use getcontext/setcontext() instead of setjmp/longjmp()\n\t  on ia64 or with native thread enabled.  [ruby-core:01932]\n\nSat Dec 13 03:09:14 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* lib/yaml/rubytypes.rb: anonymous struct fix. [ruby-core:01946]\n\n\t* test/yaml/test_yaml.rb: add test.\n\nFri Dec 12 22:36:44 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/csv.rb: add Cell#to_str and Cell#to_s for /.../ =~ aCell,\n\t  \"#{aCell}\" and so on.\n\n\t* test/csv/test_csv.rb: add tests.\n\nFri Dec 12 19:33:06 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mkdir): remove trailing `/' from pathes.\n\n\t* lib/fileutils.rb (rmdir): ditto. [ruby-dev:22238]\n\n\t* lib/fileutils.rb (rmdir_r): ditto.\n\n\t* lib/fileutils.rb (fu_copy_dir): check if it is a directory after\n\t  mkdir(2).\n\nFri Dec 12 06:06:09 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_invoke): fix class name in warning message for\n\t  define_method.  [ruby-dev:22235]\n\nThu Dec 11 21:24:43 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_pkcs12.[ch]: new files. add OpenSSL::PKCS12.\n\n\t* ext/openssl/ossl.[ch]: ditto.\n\n\t* ext/openssl/MANIFEST: add ossl_pkcs12.[ch].\n\nThu Dec 11 20:54:28 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mkdir_p): remove trailing `/' befere mkdir(2).\n\t  mkdir(\"nonexistdir/\") does not work on NetBSD/Alpha 1.6.1.\n\n\t* lib/fileutils.rb (fu_list): call to_str for all arguments.\n\nThu Dec 11 20:07:01 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ftools.rb (makedirs): sync with fileutils.\n\nThu Dec 11 19:53:03 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mkdir_p): catch all SystemCallErrors.\n\t  (mkdir(\"C:\\\") causes EACCESS on Windows 2000/NTFS)\n\nThu Dec 11 19:08:02 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (mkdir_p): check if it is a directory after\n\t  mkdir(2) instead of before mkdir(2), to avoid race condition.\n\t  [ruby-talk:87730]\n\t  Refer: mkinstalldirs sh script, GNU mkdir(1) (coreutils 5.0)\n\nThu Dec 11 18:49:30 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: def m( arg ) -> def m(arg).\n\nThu Dec 11 11:39:43 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (ieeefp.h), numeric.c: needed for finite() on\n\t  Solaris.  [ruby-core:01921]\n\n\t* file.c (rb_stat_inspect): adjust format specifier.\n\n\t* parse.c (arg_prepend): nodetype() is for debug use.\n\n\t* ruby.h (ISASCII, etc): cast to int to get rid of warning.\n\n\t* ruby.h (alloca.h): include even in GCC.  [ruby-core:01925]\n\n\t* ext/bigdecimal/bigdecimal.c (GetVpValue): adjust format\n\t  specifier.\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_prec, BigDecimal_coerce,\n\t  BigDecimal_divmod): use rb_assoc_new() to suppress memory usage.\n\n\t* ext/bigdecimal/bigdecimal.c (BigDecimal_split): ditto.\n\n\t* ext/dl/sym.c (rb_dlsym_guardcall): guard itself should be\n\t  volatile.\n\n\t* ext/iconv/iconv.c (iconv_convert): ensure actual parameter with\n\t  format specifier.\n\n\t* ext/pty/pty.c (MasterDevice, SlaveDevice, deviceNo): do not\n\t  define unless used.\n\n\t* ext/pty/pty.c (getDevice): get rid of warning.\n\n\t* ext/socket/socket.c (port_str, sock_s_getaddrinfo,\n\t  sock_s_getnameinfo): FIX2INT() now returns long.\n\n\t* ext/socket/socket.c (init_inetsock_internal): uninitialized\n\t  variable.\n\n\t* ext/syck/rubyext.c (syck_parser_assign_io): add prototype.\n\n\t* ext/syck/rubyext.c (rb_syck_mktime, yaml_org_handler): use\n\t  ISDIGIT() instead of isdigit() to avoid warnings and for\n\t  platforms which don't support non-ascii charater.\n\nWed Dec 10 19:28:56 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): set EOF flag at short read.\n\t  [ruby-dev:22223], [ruby-dev:22224]\n\nWed Dec 10 18:07:25 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/erb.rb: new method ERB#filename(=). [ruby-dev:22208]\n\nWed Dec 10 17:54:51 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): do not set EOF flag when\n\t  requested length is zero.  [ruby-dev:22214]\n\nWed Dec 10 17:17:18 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): should return given string even if data read is\n\t  empty.  [ruby-dev:22207]\n\nWed Dec 10 17:16:06 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): adjust behavior at reading\n\t  beyond EOF to IO.  [ruby-dev:22205]\n\n\t* test/ruby/ut_eof.rb (TestEOF::Seek): test behaviors at reading\n\t  beyond EOF.\n\n\t* test/ruby/test_file.rb, test/stringio/test_stringio.rb: include\n\t  TestEOF::Seek test case.\n\nWed Dec 10 15:01:19 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* test/monitor/test_monitor.rb (test_cond): use Queue#deq\n\t  instead of sleep.\n\nWed Dec 10 14:45:39 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/pty/pty.c (HAVE_SYS_IOCTL_H): need to include <sys/ioctl.h>\n\t  for TIOCSCTTY on *BSD.  based on gotoyuzo's patch.\n\t  (ruby-bugs:PR#1211)\n\n\t* ext/pty/pty.c (establishShell): should close descriptors if fork\n\t  failed.\n\nWed Dec 10 12:53:05 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.h: define execv() using do_aspawn().\n\n\t* process.c (proc_exec_v): remove #ifdef's which stopped needing.\n\nTue Dec  9 23:32:23 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tkcanvas.rb, ext/tk/lib/tkdialog.rb,\n\t  ext/tk/lib/tkentry.rb, ext/tk/lib/tkscrollbox.rb, ext/tk/lib/tktext.rb,\n\t  ext/tk/sample/tkalignbox.rb, ext/tk/sample/tkcombobox.rb,\n\t  ext/tk/sample/tkmultilistbox.rb, ext/tk/sample/tkoptdb.rb, ext/tk/sample/tktextframe.rb,\n\t  ext/tk/sample/demos-en/dialog1.rb, ext/tk/sample/demos-en/dialog2.rb,\n\t  ext/tk/sample/demos-jp/dialog1.rb, ext/tk/sample/demos-jp/dialog2.rb:\n\t  overrided instance methods, which are private methods on the super\n\t  class, are changed to 'private'\n\nTue Dec  9 19:53:02 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/generic.rb (URI::Generic#route_from0): make case insensitive\n\t  for host-part.\n\n\t* test/uri/test_generic.rb (test_route): added tests for the above\n\t  change.\n\nTue Dec  9 14:10:48 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_io_check_readable): don't call io_seek if EOF flag is set,\n\t  to avoid clearing EOF flag.\n\t  (rb_io_check_writable): ditto.\n\nTue Dec  9 02:53:55 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tkalignbox.rb: new sample script\n\nTue Dec  9 00:45:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: renamed #assert_raises to #assert_raise\n\t  and made the former call the latter. [ruby-core:01890]\n\n\t* test/testunit/test_assertions.rb: ditto.\n\nTue Dec  9 00:07:35 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/rpc/standaloneServer.rb: add 'shutdown' and 'status'\n\t  methods as delegates to WEBrick.\n\n\t* test/soap/calc/{test_calc.rb,test_calc2.rb},\n\t  test/soap/helloworld/test_helloworld.rb,\n\t  test/wsdl/datetime/test_datetime.rb, test/wsdl/raa/test_raa.rb:\n\t  follow the change.\n\nMon Dec  8 22:48:03 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/autorunner.rb: remove dependency to a particular\n\t  runner.  [ruby-core:01901], [ruby-list:38869]\n\n\t* lib/test/unit/ui/testrunnerutilities.rb: moved output level\n\t  constants from Console.\n\n\t* lib/test/unit/ui/console/testrunner.rb: ditto.\n\n\t* lib/test/unit/ui/{fox,gtk,gtk2,tk}/testrunner.rb (initialize):\n\t  accept output_level.\n\nMon Dec  8 15:03:30 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/syck/syck.c (syck_io_str_read): get rid of buffer overflow.\n\nMon Dec  8 13:02:11 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/uri/common.rb: new method URI.regexp. [ruby-dev:22121]\n\n\t* test/uri/test_common.rb: add test for URI.regexp.\n\nMon Dec  8 12:44:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c: define swap16 and swap32 only if they are not\n\t  defined. OpenBSD defines these macros. [ruby-dev:22181]\n\nSun Dec  7 20:54:17 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/iconv/iconv.c (map_charset): make case sensitive.\n\t  ext/iconv/charset_alias.rb (charset_alias): don't ignore\n\t  config.charset's information.  sort aliases.\n\nSat Dec  6 22:58:03 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_start_ssl): new function to wrap\n\t  SSL_connect and SSL_accept; if SSL_connect (or SSL_accept) returned\n\t  but not finished the handshake process, we should retry it.\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_connect): call ossl_start_ssl.\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_accept): ditto.\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_read): allow signal traps.\n\nSat Dec  6 21:45:10 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (flush_before_seek): flush before seek on any platform.\n\n\t* configure.in: ditto.\n\nSat Dec  6 17:23:00 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/soap.rb(SOAP::Env.getenv): allow upcase environment variable\n\t  as well as downcase one.\n\n\t* lib/soap/netHttpClient.rb(SOAP::NetHttpClient#proxy=): check URI.\n\nFri Dec  5 23:22:30 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb (Test::Unit::Assertions::assert_raises,\n\t  Test::Unit::Assertions::assert_nothing_raised): use the last\n\t  argument as message unless class object.\n\n\t* test/testunit/test_assertions.rb (test_assert_raises): test for\n\t  multiple exception list.  [ruby-core:01891]\n\n\t* test/testunit/test_assertions.rb (test_assert_nothing_raised): test\n\t  for non-exception classes.\n\nFri Dec  5 22:23:04 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/netHttpClient.rb: proxy support did not work.  fixed.\n\n\t* lib/soap/property.rb: add class methods for loading property from\n\t  stream/file/propertyfile.  propertyfile is a file which is located at\n\t  somedir in $:.\n\n\t* lib/soap/soap.rb, lib/soap/wsdlDriver.rb, lib/soap/rpc/driver.rb,\n\t  lib/wsdl/importer.rb: load property from propertyfile 'soap/property'\n\t  e.g. /usr/local/lib/ruby/site_ruby/1.8/soap/property.\n\n\t* test/soap/test_property.rb, test/soap/test_streamhandler.rb: new file.\n\nFri Dec  5 17:26:23 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_exec_end_proc): maintain tmp_end_procs.\n\t  [ruby-dev:22154]\n\nFri Dec  5 13:36:59 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_exec_end_proc): should not clear end_procs and\n\t  ephemeral_end_procs before execution. [ruby-dev:22144]\n\n\t* eval.c (rb_obj_extend): call Module#extended hook after\n\t  extended_object.  [ruby-list:38866]\n\n\t* object.c (Init_Object): Module#extended defined.\n\nFri Dec  5 13:17:30 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* test/ruby/test_pipe.rb: use IO.pipe instead of IO.popen.\n\nFri Dec  5 11:54:45 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): follow IO#read.\n\n\t* test/ruby/ut_eof.rb, test/ruby/test_file.rb, test/ruby/test_pipe.rb,\n\t  test/stringio/test_stringio.rb: add EOF test.\n\nFri Dec  5 02:49:35 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb (Test::Unit::Assertions::assert_raises):\n\t  allow multiple exception list.  [ruby-core:01884]\n\n\t* lib/test/unit/assertions.rb (Test::Unit::Assertions::assert_nothing_raised):\n\t  check whether arguments are subclass of Exception.\n\nThu Dec  4 23:54:00 2003  Rick Ohnemus  <rick.ohnemus@systemware.com>\n\n\t* dln.c (aix_loaderror): should not use member named 'errno' which\n\t  might be a macro (e.g. on AIX).\n\nThu Dec  4 23:32:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): do not depend on lseek position.\n\t  [ruby-dev:22026]\n\nThu Dec  4 22:37:26 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): preserve $! value when retry happens in the\n\t  rescue clause.  [ruby-talk:86697]\n\nThu Dec  4 21:50:07 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/drb/drb.rb (DRb::DRbMessage::send_request, send_reply):\n\t  should rescue errors and re-raise DRbConnError on write too.\n\t  [ruby-dev:22132]\n\nThu Dec  4 16:41:17 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (exc_list): allow expanding list.  [ruby-dev:22134]\n\nThu Dec  4 14:09:24 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb (test_cp): test if the error is\n\t  kind of SystemCallError.  It is needless details that which errno\n\t  is set on each systems.\n\nThu Dec  4 13:24:13 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/monitor.rb: use Object#__send__ instead of Object#send.\n\nThu Dec  4 13:17:45 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/streamHandler.rb: support latest released version of\n\t  http-access2.\n\nThu Dec  4 13:04:44 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/soap.rb: add SOAP::Env module for environment repository\n\t  such as HTTP_PROXY.\n\n\t* lib/soap/property.rb: property implementation.\n\n\t* lib/soap/streamHandler.rb, lib/soap/wsdlDriver.rb,\n\t  lib/soap/rpc/driver.rb: use soap/property.rb.\n\n\t* lib/wsdl/importer.rb, lib/soap/wsdlDriver.rb, lib/soap/rpc/driver.rb:\n\t  use SOAP::Env.\n\n\t* lib/soap/netHttpClient.rb: add basic_auth, ssl_config, and cookie\n\t  management interface, but ignored for now.\n\n\t* lib/xsd/charset.rb: add XSD::Charset.encoding= interface to set\n\t  wiredump charset explicitly.  it was fixed to 'utf-8' when iconv or\n\t  uconv module was found.\n\nThu Dec  4 10:43:58 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/dl/sym.c (rb_dlsym_guardcall): __declspec(noinline) is VC7\n\t  feature.\n\nThu Dec  4 10:27:12 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: update hyperlink to the Japanese document.\n\nThu Dec  4 09:12:43 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (asn1time_to_time): should check that\n\t  the underlying value of ASN1_TIME isn't NULL. [ruby-core:01881]\n\nThu Dec  4 08:29:43 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/server.rb (GenericServer#start): should rescue\n\t  Exception to avoid unexpected aborting. [ruby-core:01853]\n\n\t* lib/webrick/server.rb (GenericServer#start_thread): should check\n\t  that peeraddr isn't nil before printing.\n\n\t* lib/webrick/httpresponse.rb (HTTPResponse#start_thread): should\n\t  rescue Exception to avoid unexpected aborting of thread.\n\nThu Dec  4 03:48:59 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#link, Pathname#symlink): obsoleted.\n\t  (Pathname#make_link, Pathname#make_symlink): new method.\n\nThu Dec  4 01:45:24 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_read): should not terminate on empty string; wait\n\t  until real EOF.  [ruby-dev:21969]\n\n\t* io.c (argf_read): should adjust length to read, when length is\n\t  specified and read spans command line argument files.\n\nWed Dec  3 19:38:36 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: correct fcntl parameter. [ruby-dev:22120]\n\nWed Dec  3 13:49:07 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: 'format'==>'Kernel.format' (avoid override trouble)\n\n\t* ext/tk/lib/tkafter.rb: ditto.\n\n\t* ext/tk/lib/tkcanvas.rb: ditto.\n\n\t* ext/tk/lib/tkdialog.rb: ditto.\n\n\t* ext/tk/lib/tktext.rb: ditto.\n\nWed Dec  3 13:28:13 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in (lex.c): try gperf first, and copy from the source\n\t  directory if failed.  [ruby-dev:22123]\n\n\t* ext/extmk.rb (MTIMES): let makefiles depend to mkmf.rb.\n\n\t* lib/mkmf.rb (configuration): DLDFLAGS was duplicated.\n\nTue Dec  2 23:18:12 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: wrote the warning about HTTP_PROXY environment\n\t  variable.\n\nTue Dec  2 21:31:42 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* bin/testrb: new test runner.  [ruby-core:01845]\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner.run,\n\t  Test::Unit::AutoRunner#process_args): take test list to run and\n\t  options.\n\n\t* lib/test/unit/autorunner.rb (Test::Unit::AutoRunner::RUNNERS,\n\t  Test::Unit::AutoRunner#run): should not exit inside a library,\n\t  just return the result instead.\n\n\t* lib/test/unit.rb: ditto.\n\n\t* test/runner.rb: exit with the test result.\n\nTue Dec  2 20:18:48 2003  Eric Sunshine  <sunshine@sunshineco.com>\n\n\t* configure.in (AC_PROG_YACC): AC_DEFINE(OLD_YACC) if Yacc is found\n\t  instead of Bison or byacc.\n\n\t* parse.y: If OLD_YACC is defined, ensure that YYMAXDEPTH is at least\n\t  10000 (Bison's default) since some old versions of Yacc define it as\n\t  low as 150 by default, which is too low for Ruby to parse some files,\n\t  such as date/format.rb.  Among other issues, the parse problem causes\n\t  \"make test\" to fail.\n\nTue Dec  2 20:03:20 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: check if Pathnames are usable\n\t  for arguments.\n\nTue Dec  2 04:22:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: fixed #assert_no_match message.\n\n\t* test/testunit/test_assertions.rb: ditto.\n\nTue Dec  2 00:43:00 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/syck.c: string buffering bug.  decrementing by full\n\t  max_size now. [ruby-core:01834]\n\nMon Dec  1 21:33:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_sadded): prohibit singleton method definition for\n\t  Numerics.  fill yet another gap between Fixnum and Bignum.\n\nMon Dec  1 17:33:47 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (htov16): converts endian using swap16. htov32(), hton16,\n\t  hton32 as well. [ruby-talk:85377]\n\n\t* pack.c (swap16): swap 2 bytes no matter how big short is on the\n\t  platform.  swap32() is also prepared.\n\n\t* numeric.c (rb_num2int): returns long to preserve information.\n\t  rb_fix2int(), rb_num2uint(), rb_fix2uint() as well.\n\t  [ruby-talk:85377]\n\n\t* numeric.c (rb_num2uint): should not check for value range if the\n\t  source value is negative.\n\nMon Dec  1 17:14:34 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* sample/optparse/opttest.rb: added.\n\nMon Dec  1 16:10:52 2003  Dave Thomas  <dave@pragprog.com>\n\n\t* lib/rdoc/rdoc.rb: (etc) initial merge into main tree.\n\nMon Dec  1 14:17:49 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_each_src_dest0): call #to_str to allow\n\t  Pathname for arguments. [ruby-core:01795]\n\n\t* test/fileutils/test_fileutils.rb: does much strict test on\n\t  \"same\" files detecting.\n\nMon Dec  1 09:28:14 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub\n\t  (XCFLAGS): re-export $(XCFLAGS).\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub\n\t  (ARCH_FLAG): export $(ARCH_FLAG) (perhaps empty value).\n\nMon Dec  1 01:03:27 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (TRY_LINK, link_command): added support for DLDFLAGS\n\t  and ARCH_FLAG.  [ruby-dev:22085]\n\nSun Nov 30 20:18:07 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: keep ARCH_FLAG separate. export ARCH_FLAG.\n\t  [ruby-core:01819]\n\n\t* Makefile.in: add ARCH_FLAG to CFLAGS.\n\n\t* Makefile.in: add @CPPFLAGS@ to CPPFLAGS.\n\n\t* lib/mkmf.rb (link_command, cc_command): use ARCH_FLAG.\n\n\t* lib/mkmf.rb (configuration): add ARCH_FLAG to DLDFLAGS.\n\n\t* Makefile.in: add ARCH_FLAG to DLDFLAGS.\n\n\t* configure.in: should put getcwd in AC_CHECK_FUNCS, not\n\t  AC_REPLACE_FUNCS.  [ruby-core:01826]\n\nSun Nov 30 18:22:48 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: do not override CCDLDFLAGS, LDFLAGS, XLDFLAGS,\n\t  DLDFLAGS and LDSHARED.\n\n\t* configure.in: XCFLAGS for compiling ruby itself.  ARCH_FLAG is\n\t  reflected in CFLAGS.\n\n\t* lib/mkmf.rb: ditto.  do not import XCFLAGS from config.status.\n\nSun Nov 30 17:37:36 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix [ruby-talk:86746]\n\nSun Nov 30 13:02:00 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/encodingstyle/soapHandler.rb: refactoring - Simplifying\n\t  Conditional Expressions.\n\n\t* lib/wsdl/soap/definitions.rb: refactoring - Move Method.\n\n\t* test/xsd/{test_noencoding.rb,noencoding.xml}: new files.  test for\n\t  encoding unspecified XML file parsing.\n\n\t* test/wsdl/{test_fault.rb,map,datetime}: new files.  test of\n\t  SOAPFault, dateTime and Apache's Map.\n\nSun Nov 30 09:35:14 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* string.c (rb_str_update): get rid of SEGV at just allocated String.\n\t  [ruby-core:01812]\n\nFri Nov 28 23:19:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_mark): explicitly check mark recursion levels, instead\n\t  of unreliable stack length.\n\nFri Nov 28 22:49:56 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/rinda/rinda.rb: fix TupleSpaceProxy#read, read_all.\n\nFri Nov 28 21:44:40 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* test/fileutils/test_fileutils.rb (test_ln_s): should be a file, not\n\t  a directory for FreeBSD.\n\nFri Nov 28 19:37:56 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* hash.c (env_has_value, env_index): must match exactly.\n\n\t* test/ruby/test_env.rb (test_has_value, test_index): condition for\n\t  aboves.\n\nFri Nov 28 17:59:20 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/ruby/test_env.rb: add tests for ENV.\n\nFri Nov 28 17:47:46 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb (DRbMessage#load): rescue Errno::* and raise\n\t  DRbConnError.\n\nFri Nov 28 15:41:15 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#realpath): obsolete the force_absolute\n\t  argument.\n\nFri Nov 28 14:41:52 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/streamHandler.rb: drop unused http parameters.\n\n\t* lib/soap/encodingstyle/soapHandler.rb, lib/soap/mapping/factory.rb,\n\t  lib/soap/mapping/mapping.rb, lib/soap/mapping/registry.rb,\n\t  lib/wsdl/soap/complexType.rb: ApacheSOAP's map support was broken\n\t  under WSDL dynanic client environment.  fixed.\n\n\t* test/wsdl/raa/*: add tests.\n\n\t* lib/xsd/datatypes.rb: dateTime precision bug fix (at least, I hope.)\n\t  bug of soap4r.  XSDDateTimeImple.to_time passed a Float to\n\t  Time.local/Time.gm as an usec, and NUM2LONG(rb_num2long for Float)\n\t  causes rounding error.\n\n\t* test/soap/test_basetype.rb, test/xsd/test_xsd.rb: add tests.\n\nFri Nov 28 04:15:24 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (method_arity): used wrong Proc object.  [ruby-talk:86504]\n\nFri Nov 28 00:47:29 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_f_exit), process.c (rb_f_exit_bang): treat true as\n\t  success, false as failure.  [ruby-dev:22067]\n\n\t* eval.c (rb_f_abort, rb_thread_switch), process.c (rb_f_system): use\n\t  ANSI macro instead of hard coded value.\n\n\t* eval.c (rb_f_exit), process.c (rb_f_exit_bang): use VALUEs not but\n\t  TYPEs.\n\nThu Nov 27 22:05:48 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c, gc.c: FreeBSD/ia64 currently does not have a way for a\n\t  process to get the base address for the RSE backing store, so\n\t  hardcode it for the moment.\n\t  [submitted by: Marcel Moolenaar <marcel@FreeBSD.org>]\n\nThu Nov 27 17:36:42 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkafter.rb: bug fix on TkTimer#cancel_on_exception=(mode).\n\t  TkTimer#wait recieves the exception of the callback.\n\t  The exception is kept on @return_value.\n\nThu Nov 27 16:58:48 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_stat): remove _fullpath() for NUL: device.\n\nWed Nov 26 15:38:47 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* test/fileutils/test_fileutils.rb (test_ln_s): should take the\n\t  existing symbolic link for OpenBSD.\n\nWed Nov 26 04:48:42 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/token.c: removed YYTOKTMP references which\n\t  were causing buffer overflows on large block scalars,\n\t  comments, quoted scalars and plain scalars.\n\n\t* ext/syck/rubyext.c: dynamic changing of buffer size.\n\n\t* ext/syck/syck.h: default buffer size of 4k.\n\nWed Nov 26 00:55:30 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpresponse.rb: add HTTPResponse#keep_alive=.\n\n\t* lib/webrick/httpserver.rb (HTTPServer#run): should pass the\n\t  request's keep_alive flag to the response.\n\nTue Nov 25 21:41:35 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* defines.h (ENV_IGNORECASE): should define when DOSISH without\n\t  human68k. [ruby-dev:22047]\n\n\t* hash.c (env_has_value, env_index): don't ignore case of value.\n\t  [ruby-dev:22048]\n\nTue Nov 25 21:39:37 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (path_check_1): honor sticky bits always.\n\t  [ruby-talk:86273]\n\nTue Nov 25 20:02:14 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: do test in more deep\n\t  directory.\n\n\t* test/fileutils/test_nowrite.rb: ditto.\n\nTue Nov 25 19:04:23 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): ENV case sensitivity test\n\t  refined.\n\nTue Nov 25 18:13:30 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: chdir Dir.tmpdir before each\n\t  test. [ruby-dev:22045]\n\n\t* test/fileutils/test_nowrite.rb: ditto.\n\nTue Nov 25 17:52:11 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): use http_proxy under CGI\n\t  if the environment variable is case sensitive.\n\nTue Nov 25 16:41:33 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/wsdl/multiplefault.wsdl, test/wsdl/test_multiplefault.rb:\n\t  removed.  this test requires extra libraries in soap4r/1.5.*.\n\nTue Nov 25 16:24:42 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/**/*.rb, lib/wsdl/**/*.rb, lib/xsd/**/*.rb: changed license;\n\t  GPL2 -> Ruby's.\n\n\t* lib/soap/rpc/driver.rb, lib/soap/wsdlDriver.rb,\n\t  lib/soap/streamHandler.rb: add interface to streamhandler.\n\n\t* lib/soap/marshal.rb: raise error if parse fails.\n\n\t* lib/soap/netHttpClient.rb: add https support.  Patched by\n\t  Oliver M. Bolzer.\n\n\t* lib/soap/netHttpClient.rb: dump HTTP response message body by itself.\n\n\t* lib/soap/rpc/driver.rb, lib/soap/rpc/proxy.rb,\n\t  lib/soap/wsdlDriver.rb: add driver#mandatorycharset interface to foce\n\t  using charset for parsing response from buggy server.\n\n\t* lib/soap/encodingstyle/soapHandler.rb: support Apache Axis's half\n\t  typed multi-ref array.\n\n\t* lib/soap/mapping/factory.rb, lib/soap/mapping/registry.rb: map\n\t  SOAPStruct which has multi-accessors which name are the same, to an\n\t  array.\n\n\t* lib/soap/rpc/element.rb: fixed illegal parameter order.\n\n\t* lib/soap/rpc/element.rb: element name of response message could have\n\t  the name other than 'return'.\n\n\t* lib/wsdl/operation.rb, lib/wsdl/operationBinding.rb,\n\t  lib/wsdl/soap/classDefCreator.rb, lib/wsdl/soap/methodDefCreator.rb,\n\t  lib/wsdl/soap/methodDefCreatorSupport.rb: WSDL/1.1 allows plural\n\t  fault definition in a operation. [ruby-talk:84948]\n\n\t* test/wsdl/multiplefault.wsdl, test/wsdl/test_multiplefault.rb: add\n\t  test for above fix.\n\n\t* lib/wsdl/soap/complexType.rb: support WSDL array definition with\n\t  maxOccures=\"unbound\".\n\n\t* lib/xsd/charset.rb: use cp932 under emx.  Patched by\n\t  Siena. / SHINAGAWA, Norihide in [ruby-dev:21972]\n\n\t* lib/xsd/xmlparser/parser.rb: set @charset nil by default.  Nil means\n\t  'follow encoding declaration in XML'.\n\n\t* sample/soap/digraph.rb, sample/wsdl/amazon/wsdlDriver.rb,\n\t  sample/wsdl/googleSearch/sampleClient.rb,\n\t  sample/wsdl/googleSearch/wsdlDriver.rb,\n\t  test/wsdl/test_emptycomplextype.rb,\n\t  test/wsdl/marshal/test_wsdlmarshal.rb,\n\t  test/xsd/test_xmlschemaparser.rb: use File.open(...) { |f| f.read }\n\t  instead of File.open(...).read. [ruby-dev:21964]\n\n\t* test/wsdl/emptycomplextype.wsdl, test/wsdl/test_emptycomplextype.rb:\n\t  simplify the test case.\n\n\t* test/wsdl/axisArray/*: add tests for axis's array encoding.\n\nTue Nov 25 16:15:29 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.h: don't treat Cygwin as Windows.\n\nTue Nov 25 15:18:28 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* configure.in: change default value of --enable-pthread (default: no)\n\nTue Nov 25 07:31:16 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (primary): allow newlines just before right argument\n\t  parenthesis.  (ruby-bugs:PR#1221)\n\nMon Nov 24 23:32:06 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI.open_loop, URI::HTTP#proxy_open): use\n\t  catch/throw for redirection instead of exception.\n\t  (OpenURI.open_loop, OpenURI.redirectable?): restrict redirection.\n\nMon Nov 24 19:59:48 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): use CGI_HTTP_PROXY\n\t  instead of HTTP_PROXY in the CGI environment.\n\nMon Nov 24 19:32:55 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/etc/extconf.rb: check for pw_passwd in struct passwd and\n\t  gr_passwd in struct group for DJGPP.\n\n\t* ext/etc/etc.c: ditto.\n\n\t* ext/Setup.dj: support for curses, etc, zlib.\n\nMon Nov 24 17:00:00 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: validate option names.\n\t  :content_length_proc and :progress_proc option implemented.\n\nMon Nov 24 14:53:10 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub\n\t  (XCFLAGS): output empty value instead of `-DRUBY_EXPORT'.\n\nSat Nov 22 23:09:45 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: set enable_pthread to no on MinGW.\n\nSat Nov 22 22:56:20 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* configure.in: add --enable-pthread option (default: yes)\n\nSat Nov 22 22:48:46 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add Tk.grab_release and fix bug of TkComposite\n\n\t* ext/tk/lib/tkafter.rb: bug fix of TkAfter#start\n\n\t* ext/tk/sample/tkcombobox.rb: new sample script\n\n\t* ext/tcltklib/tcltklib.c: add native thread check\n\nSat Nov 22 18:49:47 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/curses/curses.c (window_nodelay): nodelay() of NetBSD's\n\t  libcruses returns no value, just like keypad().\n\nSat Nov 22 17:36:36 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub\n\t  (HAVE_GETCWD): output to config.h.\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub\n\t  (XCFLAGS): output to config.status.\n\nSat Nov 22 13:10:10 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (have_st_ino?): djgpp has valid st_ino.\n\nSat Nov 22 11:28:48 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (Init_stack): stack region is far smaller than usual if\n\t  pthread is used.\n\nSat Nov 22 07:30:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/util/backtracefilter.rb: fixed a bug that occurred\n\t  when an exception had no backtrace.\n\n\t* test/testunit/util/test_backtracefilter.rb: ditto.\n\nFri Nov 21 16:44:18 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkentry.rb: fix the encoding trouble of percent\n\t  substitutions on validatecommand option of TkEntry widget\n\n\t* ext/tk/lib/tk.rb: fix bug on {pack|grid}_propagate() method\n\nFri Nov 21 16:12:11 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.1: Fix markups and grammar.\n\nFri Nov 21 14:49:42 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* ruby.1: wrote about ruby related environment variables.\n\nFri Nov 21 12:28:03 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_extended): singleton methods should not be checked\n\t  when dumping via marshal_dump() or _dump(). [ruby-talk:85909]\n\nFri Nov 21 01:40:00 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* configure.in: check <pthread.h>\n\n\t* ruby.h: include pthread.h if existence.\n\t  define is_ruby_native() macro when not HAVE_NATIVETHREAD\n\n\t* eval.c: undef is_ruby_native() function when not HAVE_NATIVETHREAD\n\nFri Nov 21 00:43:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: use #__send__ instead of #send.\n\n\t* lib/test/unit/testcase.rb: ditto.\n\nThu Nov 20 19:19:22 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: don't find the Cygwin's pthread library on MinGW.\n\nThu Nov 20 19:15:50 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (have_st_ino?): emx (OS/2 with EMX) does not\n\t  have st_ino (always 0). [ruby-dev:21972]\n\n\t* lib/fileutils.rb (rename_cannot_overwrite_file?): emx does not\n\t  allow overwriting files by rename(2).\n\n\t* test/fileutils/test_fileutils.rb: windows? ->\n\t  have_drive_letter?, have_file_perm?\n\nThu Nov 20 17:50:58 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/tkballoonhelp.rb: new sample script\n\n\t* ext/tk/sample/tkmultilistbox.rb: ditto\n\n\t* ext/tk/sample/tktextframe.rb: ditto\n\nThu Nov 20 13:37:34 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ruby.h: define is_ruby_native_thread() for no native thread\n\t  environment\n\n\t* eval.c: ditto\n\nThu Nov 20 12:42:47 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* configure.in: always check existence of the pthread library\n\n\t* ruby.h: define macros for ruby's native thread check\n\n\t* eval.c: add ruby's native thread check\n\n\t* gc.c: ditto\n\nWed Nov 19 14:45:18 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (to_ary): print more friendly warning message.\n\nWed Nov 19 14:32:08 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_same?): add djgpp and wince.\n\n\t* lib/fileutils.rb (cannot_overwrite_file?): add wince.\n\nWed Nov 19 11:04:47 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/fileutils.rb (cannot_overwrite_file?, have_st_ino?): bccwin32\n\t  is same as mswin32.\n\nWed Nov 19 07:54:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit.rb: do not run tests if $! is set.\n\n\t* lib/test/unit/assertionfailederror.rb: extend StandardError instead\n\t  Exception (irb catches the former but not the latter).\n\nTue Nov 18 23:31:36 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* missing/memmove.c (memmove): take void *, not char *.\n\n\t* missing.h (memmove): ditto.\n\n\t* missing.h (strchr, strrchr): return char *, not int.\n\nTue Nov 18 22:20:10 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_same?): temporal fix for windows.\n\nTue Nov 18 19:05:04 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_same?): check by inode instead of path\n\t  name, to detect two hard links pointing to the same content.\n\n\t* test/fileutils.rb: did not create correctly looped symlinks.\n\nTue Nov 18 18:23:05 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_read): behave as IO at empty string.\n\t  [ruby-dev:21939], [ruby-dev:21941]\n\n\t* ext/stringio/stringio.c (strio_getc, strio_getline): set EOF flag.\n\n\t* ext/stringio/stringio.c (strio_rewind, strio_seek, strio_ungetc):\n\t  clear EOF flag.\n\n\t* test/stringio/test_stringio.rb: imported from [ruby-dev:21941].\n\nTue Nov 18 14:06:35 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_each_src_dest): raise if src==dest.\n\t  [ruby-talk:85344] [ruby-core:01699]\n\n\t* lib/fileutils.rb: use Object#is_a? instead of Class#=== to allow\n\t  e.g. remote objects for receivers.\n\n\t* lib/fileutils.rb: FileTest -> File.\n\n\t* lib/fileutils.rb: put parentheses for arguments of File.xxxx?\n\n\t* test/fileutils/test_fileutils.rb (test_cp): test \"cp a a\".\n\n\t* test/fileutils/test_fileutils.rb (test_mv): test \"mv a a\".\n\n\t* test/fileutils/test_fileutils.rb (test_ln): test \"ln a a\".\n\n\t* test/fileutils/test_fileutils.rb (test_ln_s): test \"ln_s a a\".\n\n\t* test/fileutils/test_fileutils.rb (test_install): test \"install a a\".\n\n\t* test/fileutils/fileasserts.rb: new method assert_symlink.\n\n\t* test/fileutils/fileasserts.rb: assert_is_directory -> assert_directory.\n\nMon Nov 17 19:38:49 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (getcwdofdrv): avoid using getcwd() directly, use\n\t  my_getcwd() instead.\n\n\t* merged NeXT, OpenStep, Rhapsody ports patch from Eric Sunshine\n\t  <sunshine@sunshineco.com>.  [ruby-core:01596]\n\nMon Nov 17 10:50:27 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Completion::complete): allow least\n\t  common completion for three or more candidates.\n\nMon Nov 17 09:41:38 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/ui/tk/testrunner.rb,\n\t  lib/test/unit/ui/gtk/testrunner.rb:\n\t  run GUI main loop in sub thread.\n\n\t* lib/test/unit/ui/gtk2/testrunner.rb: imported from rough.\n\n\t* lib/test/unit/autorunner.rb (keyword_display): sort keywords.\n\nSun Nov 16 18:10:57 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): iterator should return value from next inside\n\t  begin/rescue/end.  (ruby-bugs:PR#1218)\n\nSun Nov 16 13:26:07 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): LINK check earlier than anything else,\n\t  i.e. do not dump TYPE_IVAR for already dumped objects.\n\t  (ruby-bugs:PR#1220)\n\n\t* eval.c (rb_eval): call \"inherited\" only when a new class is\n\t  generated; not on reopening.\n\n\t* eval.c (eval): prepend error position in evaluating string to\n\t  \"mesg\" attribute string only when it's available and is a\n\t  string.\n\nSun Nov 16 12:16:10 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: logging response body. [experimental]\n\t  [ruby-list:38800]\n\nSun Nov 16 10:49:38 2003  Gavin Sinclair  <gsinclair@soyabean.com.au>\n\n\t* lib/thread.rb (Thread.exclusive): wrap method definition in\n\t  class Thread to enable rdoc to process.\n\nSun Nov 16 09:45:23 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (set_debug_output): warn if method is called\n\t  after #start.  [ruby-dev:38798]\n\nSun Nov 16 04:41:33 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): do not re-raise exception to avoid unnecessary\n\t  exception copying, instead modify exception and internal\n\t  information to adjust eval().\n\n\t* eval.c (backtrace): can return the current frame information\n\t  only if lev < -1.\n\nSat Nov 15 22:16:42 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* /ext/openssl/ossl_x509ext.c (ossl_x509extfactory_create_ext):\n\t  refine error message.\n\nSat Nov 15 10:05:40 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI.open_loop, OpenURI::HTTP#proxy_open):\n\t  refactored to support options.\n\t  (Buffer): maintain size by this class.\n\nSat Nov 15 07:40:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_method_node): new API to retrieve method body.\n\nFri Nov 14 13:21:30 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fix (en-bugged at 2003/11/07)\n\n\t* ext/tk/lib/tkdialog.rb: TkDialog.new accepts a parent widget\n\t  argument [ruby-talk:85066]\n\nThu Nov 13 20:53:35 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (Kernel[#.]open): hard coded URI schemes removed.\n\t  [ruby-ext:02251]\n\nThu Nov 13 19:17:00 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/test/unit/ui/tk/testrunner.rb: use grid and panedwindow\n\t  (if available)\n\nThu Nov 13 17:56:41 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI.open_uri): use File::RDONLY.\n\t  reported by Take_tk <ggb03124@nifty.ne.jp>.\n\t  [ruby-ext:02245]\n\nThu Nov 13 16:45:53 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509req.c (ossl_x509req_to_der): add function for\n\t  X509::Request#to_der.\n\nThu Nov 13 11:31:14 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Completion#complete): prior shorter\n\t  name to containing longer name.\n\nThu Nov 13 06:08:54 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: stop freezing some classes\n\n\t* ext/tk/lib/multi-tk.rb: ditto.\n\nWed Nov 12 17:32:49 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb (assert_throws, assert_nothing_thrown):\n\t  uncaught throw in sub thread raises ThreadError.\n\n\t* lib/test/unit/ui/tk/testrunner.rb (setup_ui): \"expand\" is not\n\t  necessary.\n\nWed Nov 12 14:09:43 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* test/monitor/test_monitor.rb: fix the timing problem by Queue.\n\nWed Nov 12 12:59:44 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* test/monitor/test_monitor.rb: added.\n\nWed Nov 12 10:14:28 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/monitor.rb: refactored. Thanks, Gennady Bystritsky.\n\nWed Nov 12 06:11:39 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.c (ossl_x509_sk2ary, ossl_x509crl_sk2ary):\n\t  add functions to convert STACK into Array.\n\n\t* ext/openssl/ossl.h: add prototypes.\n\n\t* ext/openssl/ossl_pkcs7.c (ossl_pkcs7_set_certificates,\n\t  ossl_pkcs7_get_certificates, ossl_pkcs7_get_crls,\n\t  ossl_pkcs7_set_crls): add functions for PKCS7#certificates=\n\t  PKCS7#certificates, PKCS7#crls= and PKCS7#crls.\n\nWed Nov 12 00:47:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/ui/testrunnermediator.rb: should require 'test/unit'.\n\nTue Nov 11 23:54:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/ui/gtk/testrunner.rb: added a rescue clause to handle\n\t  the case when the requested font is not available.\n\nTue Nov 11 22:44:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (appendline): file may not end with newline.  a bug if\n\t  READ_DATA_PENDING_PTR is defined. [ruby-talk:84925]\n\nTue Nov 11 10:42:41 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: raise an exception when creating TkWindow\n\t  object, because TkWindow class is an abstract class.\n\nTue Nov 11 03:30:43 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/ext/openssl/ossl_conf.c (ossl_config_get_value): return nil\n\t  if the specified value doesn't exist.\n\n\t* lib/ext/openssl/ossl_conf.c (ossl_config_get_section): return\n\t  a empty hash if the specified section doesn't exist.\n\nMon Nov 10 11:40:29 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/monitor.rb (wait): return true on signal/broadcastfalse and\n\t  false on timeout. Thanks Gennady Bystritsky.\n\nMon Nov 10 00:07:10 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (primary): primary_value may be 0 when syntax error.\n\t  [ruby-talk:84893]\n\nSun Nov  9 02:05:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: un-deprecated #assert_not_nil to\n\t  maintain symmetry with #assert_nil. Also added better output for\n\t  #assert_kind_of.\n\n\t* test/testunit/tc_assertions.rb: ditto.\n\nSat Nov  8 18:50:20 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/wsdl/raa/*: add new testcase for WSDL loading, parsing and\n\t  reading.\n\n\t* test/soap/marshal/*: backport from soap4r/1.5.1.  all differences are\n\t  for ruby/1.6.\n\n\t* lib/soap/*: backport from soap4r/1.5.1.  all differences are for\n\t  ruby/1.6.\n\n\t* lib/wsdl/data.rb, lib/wsdl/xmlSchema/data.rb: move definition of\n\t  ArrayTypeAttrName from ::WSDL::XMLSchema::* to ::WSDL::*.\n\t  [ruby-talk:84813]\n\n\t* lib/wsdl/soap/definitions.rb: element name typo in custom exception\n\t  struct definition which is needed for wsdlDriver; camelCase ->\n\t  underscore_name.\n\nSat Nov  8 13:49:50 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* configure.in: improvement of pthread check\n\nSat Nov  8 13:28:46 2003  Takaaki Tateishi  <ttate@ttsky.net>\n\n\t* ext/dl/sym.c: Add DL.win32_last_error and DL.last_error.\n\t  Thanks, Kaoru Shirai.\n\nSat Nov  8 06:19:38 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: To fix 'pthread-enabled Tcl/Tk' problem,\n\t  TclTkIp#_eval calls Tcl_Eval() on the mainloop thread only\n\t  (queueing a handler to the EventQueue).\n\n\t* ext/tcltklib/README.1st: edit the description of '--with-pthread-ext'\n\nFri Nov  7 23:23:04 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (Pathname#+): if self or the argument is `.', return\n\t  another.\n\t  (Pathname#parent): if self is `.', return `..'.\n\t  (Pathname#children): if self is `.', don't prepend self for a\n\t  pathname in a result.\n\t  (Pathname#join): re-implemented using Pathname#+.\n\t  (Pathname#find): if self is `.', remove `./' prefix of yielding\n\t  pathname.\n\nFri Nov  7 10:23:24 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/socket.c (make_hostent): get rid of SEGV on aliases\n\t  lookup failure.  (ruby-bugs:PR#1215)\n\nFri Nov  7 04:08:05 2003  UENO Katsuhiro  <katsu@blue.sky.or.jp>\n\n\t* ext/zlib/zlib.c (Init_zlib): define Zlib::GzipReader#each_line as\n\t  an alias of Zlib::GzipReader#each.\n\nFri Nov  7 01:03:16 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): save and restore rb_prohibit_interrupt.\n\t  [ruby-dev:21857]\n\nThu Nov  6 18:05:07 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_inspect): show the path also at a closed file.\n\t  [ruby-dev:21851]\n\nThu Nov  6 11:42:07 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_set_string, strio_reopen): check\n\t  tainted.\n\n\t* ext/stringio/stringio.c (strio_copy, strio_ungetc, strio_write,\n\t  strio_putc): add infection.\n\n\t* ext/stringio/stringio.c (strio_path): just nil.  [ruby-dev:21846]\n\n\t* ruby.c (proc_options): reserve searched script path in the\n\t  source file name table.  [ruby-list:38765]\n\n\t* lib/optparse.rb (OptionParser::Completion#complete): default not to\n\t  ignore case on completion.  [ruby-talk:84726]\n\n\t* win32/win32.c (make_cmdvector): process backslashes even if a quote\n\t  is not enclosed.\n\nWed Nov  5 23:49:45 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* sample/openssl/gen_csr.rb: there (at least) is a CA which does not\n\t  accept DN in UTF8STRING format.  it's a sample.\n\nWed Nov  5 22:55:16 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* configure.in, eval.c, signal.c: : add '--with-pthread-ext'\n\t  option to fix the pthread trouble on 'tcltklib'\n\n\t* ext/tcltklib/README.1st: add the description of '--with-pthread-ext'\n\n\t* ext/tk/lib/tktext.rb : add TkText#text_copy, text_cut, text_paste\n\t  to support Tcl/Tk8.4's tk_textCopy, tk_textCut, tk_textPaste\n\n\t* ext/tk/lib/tk.rb : add TkMenu#set_focus support Tcl/Tk's\n\t  tk_menuSetFocus\n\nWed Nov  5 17:33:45 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): allow interrupt during loaded program\n\t  evaluation.  [ruby-dev:21834]\n\n\t* hash.c (rb_hash_fetch): always warn if default argument and a\n\t  block are supplied at the same time. [ruby-dev:21842]\n\n\t* hash.c (env_fetch): ditto.\n\n\t* array.c (rb_ary_fetch): ditto.\n\nWed Nov  5 19:08:47 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (OptionParser::Switch::PlacedArgument::parse):\n\t  do not remove next argument if empty value is placed.\n\n\t* test/optparse: added.\n\nWed Nov  5 17:05:18 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/ui/gtk/testrunner.rb: typo.\n\nWed Nov  5 11:13:32 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* string.c: add #include \"version.h\". this file still depends on it.\n\n\t* Makefile.in, bcc32/Makefile.sub, win32/Makefile.sub,\n\t  wince/Makefile.sub: add version.h dependency to string.c.\n\nWed Nov  5 09:14:23 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/monitor.rb: revert to the previous revision.\n\nWed Nov  5 08:39:51 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/https.rb (HTTPRequest#parse): set @client_cert_chain.\n\n\t* lib/webrick/https.rb (HTTPRequest#meta_vars): create\n\t  SSL_CLIENT_CERT_CHAIN_n from @client_cert_chain.\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_get_peer_cert_chain): return nil\n\t  if no cert-chain was given.\n\nTue Nov  4 23:44:48 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub:\n\t  remove needless version.h dependency.\n\nTue Nov  4 23:38:43 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* class.c, hash.c, string.c: remove #include \"version.h\".\n\n\t* Makefile.in: remove needless version.h dependency.\n\nTue Nov  4 06:54:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): fptr->f may be NULL, if IO is closed in the\n\t  signal handler.\n\n\t* io.c (io_read): ditto.\n\n\t* string.c (get_pat): remove 1.8.0 warning code.\n\n\t* string.c (rb_str_match): extend warning until 1.8.2.\n\n\t* string.c (rb_str_match2): ditto.\n\n\t* class.c (class_instance_method_list): remove 1.8.0 warnings.\n\t  method_list now recurs.  [ruby-dev:21816]\n\n\t* class.c (rb_obj_singleton_methods): ditto.\n\n\t* array.c (rb_ary_select): remove select with block.\n\t  [ruby-dev:21824]\n\n\t* hash.c (rb_hash_select): ditto.\n\n\t* hash.c (env_select): ditto.\n\n\t* re.c (match_select): ditto.\n\n\t* struct.c (rb_struct_select): ditto.\n\nMon Nov  3 22:53:21 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/racc/parser.rb: synchronize with Racc 1.4.4.\n\n\t* ext/racc/cparse/cparse.c: ditto.\n\n\t* ext/racc/cparse/cparse.c (parse_main): should abort when\n\t  the length of LR state stack <=1, not ==0.\n\nMon Nov  3 08:50:47 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (check_uid_switch): remove duplicated error messages.\n\n\t* process.c (check_gid_switch): ditto.\n\nSun Nov  2 02:28:33 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/ssl.rb: new option :SSLExtraChainCert.\n\nSun Nov  2 01:02:04 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (rb_str_hash): Update the HASH_PERL alternative hash\n\t  algorithm in sync with Perl 5.8.\n\n\t* st.c (strhash): Ditto.\n\nSat Nov  1 18:21:09 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_peer_cert_chain): add new method\n\t  SSLSocket#peer_cert_chain.\n\n\t* ext/openssl/ossl_x509req.c (GetX509ReqPtr): new function\n\t  which returns underlying X509_REQ.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509extfactory_set_issuer_cert,\n\t  ossl_x509extfactory_set_subject_cert, ossl_x509extfactory_set_crl,\n\t  ossl_x509extfactory_set_subject_req, ossl_x509extfactory_set_config):\n\t  use underlying C struct without duplication not to leak momory.\n\nSat Nov  1 01:49:03 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/mapping/factory.rb: mark marshalled basetype objects when\n\t  @allow_original_mapping is true.  multi-referencing basetype node is\n\t  prohibited in SOAP/1.1 encoding but soap4r's original ruby object\n\t  mapping requires basetype to be marked to detect self referencing\n\t  loop.  e.g. o = 1; o.instance_eval { @iv = o }  soap4r's original\n\t  mapping is only used through soap/marshal API.\n\n\t* test/soap/marshal/test_marshal.rb: add tests for self referencing\n\t  immutable objects.\n\n\t* test/soap/calc/test_calc_cgi.rb: fix test name.\n\nFri Oct 31 22:26:29 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/string_wce.c (strrchr): should decrement pointer.\n\n\t* wince/Makefile.sub: correct a range of isdigit().\n\nFri Oct 31 12:55:24 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in, lib/mkmf.rb: add RPATHFLAG for NetBSD.\n\t  [ruby-dev:21791]\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, win32/Makefile.sub: ditto.\n\nFri Oct 31 01:38:14 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* wince/Makefile.sub, win32/Makefile.sub (.y.c): allow white spaces\n\t  at the beginning of line to remove by sed. (ruby-bugs-ja:PR#580)\n\nFri Oct 31 01:02:24 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* compar.c (cmp_equal): protect exceptions from <=> comparison\n\t  again.  returns nil if any exception or error happened during\n\t  comparison.\n\n\t* eval.c (search_required): should update *featurep when DLEXT2 is\n\t  defined. (ruby-bugs-ja:PR#581)\n\nThu Oct 30 23:41:04 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb: add DRbArray\n\n\t* lib/drb/invokemethod.rb: fix Hash#each problem. [ruby-dev:21773]\n\n\t* lib/drb/unix.rb: add LoadError. [ruby-dev:21743]\n\nThu Oct 30 23:19:11 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/generator.rb: better XML pretty printing.\n\n\t* lib/soap/encodingstyle/soapHandler.rb: remove unnecessary namespace\n\t  assignment in the element which has \"encodingStyle\" attribute, and\n\t  add necessary namespace assignment for \"arrayType\" attribute.\n\n\t* test/soap/calc/test_calc_cgi.rb: take over $DEBUG to ruby process\n\t  through CGI.\n\nThu Oct 30 22:59:39 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/yaml2byte.c: HASH const too long.  Thanks, matz.\n\nThu Oct 30 19:13:53 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syck/MANIFEST: Add yamlbyte.h.\n\nThu Oct 30 14:25:31 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (READ_DATA_BUFFERED): new macro to detect whether stdio\n\t  buffer filled.\n\n\t* io.c (rb_io_fptr_cleanup): move path deallocation to\n\t  rb_io_fptr_finalize (finalizer called by GC).\n\nThu Oct 30 13:23:39 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (logop): left may be NULL. [ruby-talk:84539]\n\n\t* eval.c (rb_eval): NODE_CASE nd_head may be NULL.\n\nThu Oct 30 10:14:51 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/test/unit/autorunner.rb: make fox runner work.\n\nThu Oct 30 09:32:26 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* process.c (rb_f_system): fixed lack of security check before\n\t  calling do_spawn() on win32. [ruby-talk:84555]\n\nThu Oct 30 02:46:35 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): single array value to normal Proc#call\n\t  (i.e. not via lambda call), should be treated just like yield.\n\t  [ruby-dev:21726]\n\nThu Oct 30 02:25:48 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/buffering.rb (Buffering#initialize):\n\t  add new method to inherit @sync from @io.sync.\n\n\t* ext/openssl/lib/net/protocols.rb (SSLIO#ssl_connect): no need to\n\t  set sync flag explicitly.\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_initialize): call super.\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_setup): set extra chain\n\t  certificates in @extra_chain_cert.\n\nWed Oct 29 22:02:04 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/drb/drbtest.rb: use rbconfig.rb to make the path of ruby\n\t  interpreter to exec, instead of test/ruby/envutil.rb,\n\nWed Oct 29 19:58:59 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/tcltklib/tcltklib.c (CONST84): define CONST84 when it is not\n\t  defined and TCL_MAJOR_VERSION >= 8.\n\n\t* ext/tcltklib/tcltklib.c (VwaitVarProc, WaitVariableProc,\n\t  rb_threadVwaitProc): use CONST84 instead of CONST.\n\n\t* ext/tcltklib/tcltklib.c (ip_rbTkWaitCommand,\n\t  ip_rb_threadTkWaitCommand): use CONST84 always.\n\nWed Oct 29 17:27:05 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* re.c (rb_reg_s_union, Init_Regexp): new method `Regexp.union'.\n\n\t* lib/pathname.rb (realpath): examine Dir.pwd because it may have\n\t  symlinks.\n\nWed Oct 29 17:16:31 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_longjmp): must not disturb original jump.\n\t  [ruby-dev:21733]\n\nWed Oct 29 15:28:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (Init_Proc): taint preallocated exception object\n\t  sysstack_error. [ruby-talk:84534]\n\nWed Oct 29 11:27:39 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (ret_args): node may be NULL. [ruby-talk:84530]\n\nTue Oct 28 15:20:12 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/tcltklib/tcltklib.c (VwaitVarProc, ip_rbVwaitObjCmd,\n\t  WaitVariableProc, WaitVisibilityProc, WaitWindowProc,\n\t  ip_rbTkWaitObjCmd, ip_rbTkWaitCommand, rb_threadVwaitProc,\n\t  rb_threadWaitVisibilityProc, rb_threadWaitWindowProc,\n\t  ip_rb_threadVwaitObjCmd, ip_rb_threadTkWaitObjCmd): prototype;\n\t  avoid VC++ warnings.\n\nMon Oct 27 19:19:55 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_longjmp): ignore reentering error while warning.\n\t  [ruby-dev:21730]\n\nMon Oct 27 00:23:50 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_ruby): bug fix on Win : hang-up when\n\t  calling 'exit' in the Tk callback procedure. [ruby-list:38656]\n\nSat Oct 25 09:18:04 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_method_missing): protect exception from within\n\t  \"inspect\".  (ruby-bugs:PR#1204)\n\nFri Oct 24 23:26:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_each): Hash#each should yield single value.\n\t  [ruby-talk:84420]\n\n\t* hash.c (env_each): ditto for ENV.each.\n\nThu Oct 23 20:25:32 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/server.rb (GenericServer#start): should rescue\n\t  IOError from IO::accept. [ruby-dev:21692]\n\nThu Oct 23 17:59:36 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): initialize stack bottom for embedding.\n\t  [ruby-dev:21686]\n\n\t* ext/dl/extconf.rb: move list of files to clean from DEPEND file,\n\t  to get rid of macro redefinitions.\n\nThu Oct 23 13:44:00 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y: integrate operations for stack_type.  [ruby-dev:21681]\n\nThu Oct 23 00:41:45 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/calc/*, test/soap/helloworld/*: set logging threshold\n\t  to ERROR.\n\nWed Oct 22 12:53:31 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/collector/dir.rb (Test::Unit::Collector::Dir#collect_file):\n\t  ignore tests which raised LoadError.\n\n\t* test/drb/drbtest.rb, test/ruby/test_beginendblock.rb,\n\t  test/ruby/test_system.rb: avoid requiring same file twice.\n\n\t* test/drb/test_drbssl.rb, test/drb/test_drbunix.rb: should not use\n\t  ARGV unless invoked directly.  do not create test cases unless\n\t  required libraries are available.\n\nWed Oct 22 02:31:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): should not ignore exit_value in END\n\t  execution. [ruby-dev:21670]\n\nTue Oct 21 23:16:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): call finalizers and exit procs before\n\t  terminating threads.\n\n\t* eval.c (ruby_cleanup): preserve ruby_errinfo before ruby_finalize_0().\n\nTue Oct 21 15:57:11 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/test/unit/collector/dir.rb (Test::Unit::Collector::Dir#collect_file):\n\t  prepend the directory of target file to the load path.\n\nTue Oct 21 15:08:53 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (do_spawn, do_aspawn): should wait child process even\n\t  if callded with P_OVERLAY.\n\n\t* win32/win32.c (do_spawn, do_aspawn): should return child's exit\n\t  status to parent.\n\nTue Oct 21 00:35:02 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/calc/*, test/soap/helloworld/*: catch the exception from\n\t  test server thread and recover.\n\nTue Oct 21 00:22:57 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* test/drb/*: import drb/runit.\n\nMon Oct 20 23:55:47 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): set current node after arguments evaluation.\n\t  [ruby-dev:21632]\n\n\t* eval.c (rb_yield_0): set current node and keep it at local jump.\n\nMon Oct 20 22:01:18 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_cleanup): keep thread group for main thread.\n\t  [ruby-dev:21644]\n\nMon Oct 20 18:28:10 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_catch): backout.\n\nMon Oct 20 17:31:46 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (PUSH_FRAME): generate unique number to be TAG_JUMP()\n\t  destination.\n\n\t* eval.c (localjump_destination): use unique number in ruby_frame\n\t  for localjump destination.\n\nMon Oct 20 11:31:44 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/ruby/test_signal.rb (test_signal): restore old trap.\n\nMon Oct 20 11:00:46 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_sweep): loosen page free condition to avoid add_heap()\n\t  race condition. [ruby-dev:21633]\n\n\t* gc.c (gc_sweep): do not update malloc_limit when malloc_increase\n\t  is smaller than malloc_limit.\n\nMon Oct 20 09:45:12 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* lib/debug.rb (debug_command): remove debug print.\n\nWed Oct 20 00:25:41 2004  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (search_required): required name must not be changed before\n\t  loading.  [ruby-dev:24492]\n\nSun Oct 19 13:12:30 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (foreachline, dir_foreach): add obsolete warning.\n\nSun Oct 19 00:14:22 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/calc/*, test/soap/helloworkd/*: changed port# of test\n\t  server. (17171)\n\nSat Oct 18 23:01:32 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* missing/acosh.c (DBL_MANT_DIG): typo fix(ifdef -> ifndef).\n\nSat Oct 18 05:48:59 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/rubyext.c: YAML::Syck::compile method.\n\n\t* ext/syck/syck.c: Buffer edge bug.\n\n\t* ext/syck/yaml2byte.c: YAML to bytecode converter.\n\n\t* ext/syck/yamlbyte.h: Ditto.\n\n\t* ext/syck/bytecode.c: Bytecode parser fixes to empty collections\n\t  and empty strings.\n\n\t* ext/syck/token.c: Ditto.\n\nFri Oct 17 23:07:38 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/enumerator/enumerator.c, ext/enumerator/enumerator.txt:\n\t  Provide Kernel#to_enum as an alias for Kernel#enum_for.  Maybe\n\t  this is a better name.\n\nFri Oct 17 23:00:30 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/generator.rb: Add rdoc documentation.\n\nFri Oct 17 22:16:42 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: Reword and fix Overview.\n\n\t* lib/set.rb: It is not necessary to require\n\t  'test/unit/ui/console/testrunner'.\n\nFri Oct 17 11:15:22 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* test/ruby/test_range.rb: added.\n\n\t* MANIFEST: add test/ruby/test_range.rb.\n\nFri Oct 17 03:21:23 2003  William Sobel  <will.sobel@barra.com>\n\n\t* ext/socket/socket.c (make_hostent): h_aliases may be NULL.\n\t  (ruby-bugs:PR#1195)\n\n\t* ext/socket/socket.c (sock_s_gethostbyaddr): ditto.\n\nFri Oct 17 00:12:41 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: (bug fix) instance variable @frame was used\n\t  without initializing on TkComposite module.\n\nThu Oct 16 23:51:04 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: If $DEBUG == true and some exception is caused\n\t  in a callback operation, Ruby/Tk shows a (verbose) backtrace\n\t  information on the callback process.\n\nThu Oct 16 17:09:19 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/debug.rb (DEBUGGER__::Context::debug_command): do not call\n\t  debug_silent_eval() when $1 is not set. (ruby-bugs:PR#1194)\n\nThu Oct 16 16:54:57 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_upto): (\"a\"...\"a\").to_a should return [].\n\t  [ruby-core:01634]\n\nThu Oct 16 16:40:51 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb:\n\t  Add Tk::EncodedString and Tk::UTF8_String class to support\n\t  characters using the \\uXXXX escape to the UNICODE string.\n\n\t* ext/tk/sample/{demos-en,demos-jp}/unicodeout.rb\n\t  new demo-scripts (samples of Tk::UTF8_String)\n\n\t* ext/tk/sample/{demos-en,demos-jp}/widget\n\t  add entries for 'unicodeout.rb'\n\nThu Oct 16 08:38:06 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/digest/test_digest.rb (test_eq): show failed class.\n\n\t* test/ruby/test_iterator.rb (test_break, test_return_trace_func):\n\t  test localjump destination.\n\nWed Oct 15 20:22:31 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/netHttpClient.rb: use URI::HTTP#request_uri instead of\n\t  instance_eval('path_query').  [ruby-list:38575]\n\nWed Oct 15 17:24:45 2003  URABE Shyouhei  <root@mput.dip.jp>\n\n\t* lib/cgi.rb (CGI::Cookie): tiny typo fix.\n\nWed Oct 15 15:00:54 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_run): just return FAILURE instead of parse error\n\t  count.  [ruby-list:38569]\n\nWed Oct 15 13:17:02 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/digest/digest.c (rb_digest_base_alloc): need to initialize\n\t  buffer. [ruby-dev:21622]\n\nWed Oct 15 11:23:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): dump extended modules as well.\n\n\t* marshal.c (r_object0): TYPE_USRMARSHAL should restore extended\n\t  modules before invoking marshal_load.  these two fixes are done\n\t  by Masatoshi Seki <m_seki@mva.biglobe.ne.jp>.\n\nWed Oct 15 09:30:34 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/enumerator/enumerator.c (enumerator_each): avoid VC++ warning.\n\n\t* ext/syck/syck.h: include stdio.h for definition of FILE.\n\nWed Oct 15 08:09:07 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/bytecode.c: Checkin of YAML bytecode support.\n\n\t* ext/syck/gram.c: Ditto.\n\n\t* ext/syck/syck.c: Ditto.\n\n\t* ext/syck/token.c: Ditto.\n\n\t* ext/syck/handler.c: Ditto.\n\n\t* ext/syck/handler.c: Now using 'tag' rather than 'taguri' in type URIs.\n\n\t* ext/syck/rubyext.c: Ditto (on both counts).\n\nWed Oct 15 05:05:53 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/generator.rb: A new library which converts an internal\n\t  iterator to an external iterator.\n\n\t* lib/abbrev.rb: A new library which creates an abbreviation table\n\t  from a list.\n\nWed Oct 15 04:31:51 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/demos-en/entry3.rb, ext/tk/sample/demos-jp/entry3.rb :\n\t  new demo-scripts\n\n\t* ext/tk/sample/demos-en/widget, ext/tk/sample/demos-jp/widget :\n\t  add entries for 'entry3.rb'\n\nWed Oct 15 04:31:47 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* test/digest/test_digest.rb: Moved from ext/digest/test.rb.\n\nWed Oct 15 03:53:20 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: fixed trouble on auto-load Tcl commands (enbug\n\t  on the last commit).\n\nWed Oct 15 00:25:00 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): argument parentheses preceded by spaces should\n\t  be warned; not error.  [ruby-talk:84103]\n\nWed Oct 15 00:20:15 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: replace Tcl/Tk's vwait and tkwait to\n\t  switch on threads smoothly and avoid seg-fault.\n\n\t* ext/tcltklib/tcltklib.c: add TclTkIp._thread_vwait and\n\t  _thread_tkwait for waiting on a thread. (Because Tcl/Tk's vwait\n\t  and tkwait command wait on an eventloop.)\n\n\t* ext/tk/lib/multi-tk.rb: support TclTkIp._thread_vwait and\n\t  _thread_tkwait.\n\n\t* ext/tk/lib/tk.rb: now, TkVariable#wait has 2 arguments.\n\t  If 1st argument is true, waits on a thread. If false, waits on\n\t  an eventloop. If 2nd argument is true, checks existence of\n\t  rootwidgets. If false, doesn't. Default is wait(true, false).\n\n\t* ext/tk/lib/tk.rb: add TkVariable#tkwait(arg) which is equal to\n\t  TkVariable#wait(arg, true). wait_visibility and wait_destroy\n\t  have an argument for waiting on a thread or an eventloop.\n\n\t* ext/tk/lib/tk.rb: improve of accessing Tcl/Tk's special variables.\n\n\t* ext/tk/lib/tkafter.rb: support 'wait on a thread' and 'wait on\n\t  an eventloop'.\n\nWed Oct 15 00:10:24 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/baseData.rb: Introduce SOAPType as the common ancestor of\n\t  SOAPBasetype and SOAPCompoundtype.\n\n\t* lib/soap/generator.rb, lib/soap/element.rb, lib/soap/encodingstyle/*:\n\t  Encoding methods signature change.  Pass SOAPGenerator as a parameter.\n\n\t* lib/soap/mapping/*, test/soap/marshal/test_marshal.rb: Refactoring\n\t  for better marshalling/unmarshalling support.  Now I think SOAP\n\t  marshaller supports all kind of object graph which is supported by\n\t  Ruby's original marshaller.  Of course there could be bugs as always.\n\t  Find it.  :-)\n\n\t* lib/soap/rpc/standaloneServer.rb: Set severity threshould to INFO.\n\t  DEBUG is too noisy.\n\n\t* lib/xsd/datatypes.rb: DateTime#of is obsoleted.  Use DateTime#offset.\n\n\t* test/wsdl/emptycomplextype.wsdl, test/xsd/xmlschema.xml: Avoid\n\t  useless warning.\n\nTue Oct 14 19:09:35 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (ruby_finalize_0): return the given exit status unless\n\t  SystemExit got raised.\n\nTue Oct 14 11:53:49 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* intern.h (ruby_stop): never return.\n\n\t* ruby.h (ruby_run): ditto.\n\nTue Oct 14 04:43:55 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (realpath): make ELOOP check bit more robust.\n\t  (children): prepend self by default.\n\t  (chroot): obsoleted.\n\nTue Oct 14 02:29:31 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_require_safe): segfault after loading .so.\n\nTue Oct 14 02:05:23 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Setup*, ext/enumerator/*: Add ext/enumerator, a helper\n\t  module for the Enumerable interface.\n\nMon Oct 13 23:55:59 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* test/ruby/envutil.rb: use Config::CONFIG[\"ruby_install_name\"],\n\t  not \"ruby\".\n\nMon Oct 13 23:57:29 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_feature_p): match by classified suffix.\n\n\t* eval.c (rb_require_safe): require library in the specified safe\n\t  level.\n\n\t* variable.c (rb_autoload, rb_autoload_load): restore safe level\n\t  when autoload was called.  [ruby-dev:21338]\n\n\t* intern.h: prototypes; rb_require_safe.\n\n\t* test/runner.rb: accept non-option arguments.\n\nMon Oct 13 20:49:51 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_new4): should not preserve FL_TAINT status in the\n\t  internal shared string. [ruby-dev:21601]\n\n\t* string.c (rb_str_new4): ditto.\n\n\t* eval.c: use EXIT_SUCCESS and EXIT_FAILURE for exit values.\n\n\t* process.c: ditto. [ruby-list:38521]\n\nMon Oct 13 19:51:02 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* lib/debug.rb (debug_command): should enter emacs mode when\n\t  assigned any value to the environment variable \"EMACS\".\n\t  On Meadow, (getenv \"EMACS\") is \"meadow\".\n\nSun Oct 12 14:45:03 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/win32ole/extconf.rb: check \"windows.h\", not \"windows\".\n\t  [ruby-talk:84051]\n\nSat Oct 11 20:41:03 2003  Corinna Vinschen  <corinna@vinschen.de>\n\n\t* file.c (eaccess): Use access(2) on Cygwin.\n\nSat Oct 11 17:09:21 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/rexml/quickpath.rb (REXML::QuickPath::match):\n\t  escape '[' to avoid warning.\n\nSat Oct 11 16:08:41 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (realpath): check existence of the file.\n\n\t* lib/pathname.rb (realpath): re-implemented.\n\t  (realpath_root?, realpath_rec): removed\n\nSat Oct 11 10:19:39 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/monitor.rb: handle exceptions correctly. Thanks, Gennady\n\t  Bystritsky.\n\nFri Oct 10 07:50:54 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (is_defined): inheritance line adjustment as like as\n\t  rb_call_super().\n\nFri Oct 10 01:19:00 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_initialize): add\n\t  optional argument to specify the DirectoryString type\n\t  (ASN1::UTF8STRING by default). RFC3280 deprecates PrintableString\n\t  for DirectoryString, and strongly requires to use UTF8String for\n\t  all certificates issued after December, 31 2003.\n\n\t* ext/openssl/lib/openssl/x509.rb (X509::Name::parse): ditto.\n\nThu Oct  9 23:50:21 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): prevent thread from GC.\n\t  [ruby-dev:21572]\n\nThu Oct  9 19:11:44 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): non-volatile should be restored from\n\t  volatile.\n\nThu Oct  9 17:43:36 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (proc_save_safe_level, proc_get_safe_level,\n\t  proc_set_safe_level): save/restore safe level 1..4.\n\nThu Oct  9 16:33:23 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_object0): remove unnecessary iv restoration for\n\t  USRMARSHAL. [ruby-dev:21582]\n\n\t* marshal.c (w_object): dump generic instance variables from\n\t  a string from '_dump'.\n\n\t* variable.c (rb_generic_ivar_table): return 0 if obj's FL_EXIVAR\n\t  is not set.\n\n\t* time.c (time_dump): copy instance variables to dumped string, to\n\t  be included in the marshaled data.\n\n\t* bignum.c (rb_big2ulong): add range check to ensure round trip.\n\nThu Oct  9 15:45:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (uv_to_utf8): change message to \"out of range\", since\n\t  negative values are not \"too big\". [ruby-dev:21567]\n\nThu Oct  9 14:05:38 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_set_end_proc, rb_exec_end_proc): restore safe level.\n\t  [ruby-dev:21557]\n\nThu Oct  9 10:51:04 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): no error if block is empty.\n\nThu Oct  9 06:43:33 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (localjump_error): id should be ID.\n\n\t* eval.c (rb_eval): nd_rval is set in copy_node_scope().\n\n\t* eval.c (rb_yield_0): unused variable.\n\n\t* eval.c (rb_yield_0): nothing to do for empty node.\n\n\t* eval.c (call_end_proc, proc_invoke): adjust backtrace in END.\n\t  [ruby-dev:21551]\n\n\t* eval.c (rb_thread_start_0): set the value by break as the result.\n\t  [ruby-dev:21552]\n\n\t* eval.c (rb_thread_start_0, rb_thread_raise, rb_callcc): save\n\t  variables across THREAD_SAVE_CONTEXT.\n\nThu Oct  9 12:05:46 2003  Eric Sunshine  <sunshine@sunshineco.com>\n\n\t* configure.in: revived NextStep, OpenStep, and Rhapsody ports which\n\t  had become unbuildable; enhanced --enable-fat-binary option so that\n\t  it accepts a list of desired architectures (rather than assuming a\n\t  fixed list), or defaults to a platform-appropriate list if user does\n\t  not provide an explicit list; made the default list of architectures\n\t  for MAB (fat binary) more comprehensive; now uses -fno-common even\n\t  when building the interpreter (in addition to using it for\n\t  extensions), thus allowing the interpreter to be embedded into a\n\t  plugin module of an external project (in addition to allowing\n\t  embedding directly into an application); added checks for\n\t  <netinet/in_systm.h> (needed by `socket' extension) and getcwd(); now\n\t  ensures that -I/usr/local/include is employed when extensions'\n\t  extconf.rb scripts invoke have_header() since extension checks on\n\t  NextStep and OpenStep will fail without it if the desired resource\n\t  resides in the /usr/local tree; fixed formatting of --help message.\n\n\t* Makefile.in: $(LIBRUBY_A) rule now deletes the archive before\n\t  invoking $(AR) since `ar' on Apple/NeXT can not \"update\" MAB archives\n\t  (see configure's --enable-fat-binary option); added rule for new\n\t  missing/getcwd.c.\n\n\t* defines.h: fixed endian handling during MAB build (see configure's\n\t  --enable-fat-binary option) to ensure that all portions of the\n\t  project see the correct WORDS_BIGENDIAN value (some extension modules\n\t  were getting the wrong endian setting); added missing constants\n\t  GETPGRP_VOID, WNOHANG, WUNTRACED, X_OK, and type pid_t for NextStep\n\t  and OpenStep; removed unnecessary and problematic HAVE_SYS_WAIT_H\n\t  define in NeXT section.\n\n\t* dir.c: do not allow NAMLEN() macro to trust dirent::d_namlen on\n\t  NextStep since, on some installations, this value always resolves\n\t  uselessly to zero.\n\n\t* dln.c: added error reporting to NextStep extension loader since the\n\t  previous behavior of failing silently was not useful; now ensures\n\t  that NSLINKMODULE_OPTION_BINDNOW compatibility constant is defined\n\t  for OpenStep and Rhapsody; no longer includes <mach-o/dyld.h> twice\n\t  on Rhapsody since this header lacks multiple-include protection,\n\t  which resulted in \"redefinition\" compilation errors.\n\n\t* main.c: also create hard reference to objc_msgSend() on NeXT\n\t  platforms (in addition to Apple platforms).\n\n\t* lib/mkmf.rb: now exports XCFLAGS from configure script to extension\n\t  makefiles so that extensions can be built MAB (see configure's\n\t  --enable-fat-binary option); also utilize XCFLAGS in cc_command()\n\t  (but not cpp_command() because MAB flags are incompatible with\n\t  direct invocation of `cpp').\n\n\t* ext/curses/extconf.rb: now additionally checks for presence of these\n\t  curses functions which are not present on NextStep or Openstep:\n\t  bkgd(), bkgdset(), color(), curs(), getbkgd(), init(), scrl(), set(),\n\t  setscrreg(), wattroff(), wattron(), wattrset(), wbkgd(), wbkgdset(),\n\t  wscrl(), wsetscrreg()\n\n\t* ext/curses/curses.c: added appropriate #ifdef's for additional set of\n\t  curses functions now checked by extconf.rb; fixed curses_bkgd() and\n\t  window_bkgd() to correctly return boolean result rather than numeric\n\t  result; fixed window_getbkgd() to correctly signal an error by\n\t  returning nil rather than -1.\n\n\t* ext/etc/etc.c: setup_passwd() and setup_group() now check for null\n\t  pointers before invoking rb_tainted_str_new2() upon fields extracted\n\t  from `struct passwd' and `struct group' since null pointers in some\n\t  fields are common on NextStep/OpenStep (especially so for the\n\t  `pw_comment' field) and rb_tainted_str_new2() throws an exception\n\t  when it receives a null pointer.\n\n\t* ext/pty/pty.c: include \"util.h\" for strdup()/ruby_strdup() for\n\t  platforms such as NextStep and OpenStep which lack strdup().\n\n\t* ext/socket/getaddrinfo.c: cast first argument of getservbyname(),\n\t  gethostbyaddr(), and gethostbyname() from (const char*) to non-const\n\t  (char*) for older platforms such as NextStep and OpenStep.\n\n\t* ext/socket/socket.c: include \"util.h\" for strdup()/ruby_strdup() for\n\t  platforms such as NextStep and OpenStep which lack strdup(); include\n\t  <netinet/in_systm.h> if present for NextStep and OpenStep; cast first\n\t  argument of gethostbyaddr() and getservbyname() from (const char*) to\n\t  non-const (char*) for older platforms.\n\n\t* ext/syslog/syslog.c: include \"util.h\" for strdup()/ruby_strdup() for\n\t  platforms such as NextStep and OpenStep which lack strdup().\n\nWed Oct  8 22:19:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit.rb: removed installation instructions.\n\n\t* lib/test/unit/ui/testrunnermediator.rb: moved the run flag to a more\n\t  central location.\n\n\t* lib/test/unit.rb: ditto.\n\n\t* lib/test/unit.rb: extracted the running code in to AutoRunner.\n\n\t* lib/test/unit/autorunner.rb: added.\n\n\t* lib/test/unit/collector/objectspace.rb: extracted common test\n\t  collection functionality in to a module.\n\n\t* lib/test/unit/collector.rb: ditto; added.\n\n\t* test/testunit/collector/test_objectspace.rb: ditto.\n\n\t* lib/test/unit/collector/dir.rb: added. Supports collecting tests out\n\t  of a directory structure.\n\n\t* test/testunit/collector/test_dir.rb: added.\n\n\t* test/runner.rb: simplified to use the new capabilities.\n\nTue Oct  7 15:23:09 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_beginendblock.rb: add tests for nested BEGIN/END.\n\n\t* test/ruby/beginmainend.rb: add tests for nested BEGIN/END.\n\n\t* test/ruby/endblockwarn.rb: new file added to test of END-in-method\n\t  warning.\n\nTue Oct  7 12:23:47 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/fcntl/fcntl.c (Init_fcntl): define Fcntl::O_ACCMODE.\n\n\t* ext/socket/extconf.rb: useless assignment removed.\n\nTue Oct  7 09:13:24 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/ruby/test_beginendblock.rb (test_endinmethod): END{} is now\n\t  allowed in eval.\n\nTue Oct  7 04:15:25 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (stmt): should not expand mrhs if lhs is solely starred.\n\nTue Oct  7 02:57:53 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (stmt): rhs of multiple assignment should not be\n\t  expanded using \"to_a\". [ruby-dev:21527]\n\nTue Oct  7 01:42:34 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1_get_asn1type): use appropriate\n\t  free function for ASN1_OBJECT.\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1obj_get_sn): add new function for\n\t  ASN1::ObjectId#sn; it returns short name text representation of OID.\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1obj_get_ln): add new function for\n\t  ASN1::ObjectId#ln; it returns long name text representation of OID.\n\n\t* ext/openssl/ossl_asn1.c (ossl_asn1obj_get_oid): add new function for\n\t  ASN1::ObjectId#oid; it returns numerical representation of OID.\n\nMon Oct  6 22:59:46 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/csv.rb (IOReader, BasicWriter): call binmode when a given IO\n\t  respond_to?(:binmode).  record separator was wrong when you gave\n\t  text mode IO to Reader.parse and Writer.generate.\n\n\t* test/csv/test_csv.rb: add tests for above change.\n\nSun Oct  5 23:27:09 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/extconf.rb: check recvmsg even if sendmsg is exists.\n\n\t* ext/socket/socket.c (thread_read_select): restored.\n\nMon Oct  6 16:23:38 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (w_object): wrong method name in the message.\n\nMon Oct  6 16:02:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (stmt): END in method should cause warning.\n\t  [ruby-dev:21519]\n\nMon Oct  6 15:17:23 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_iterator.rb (test_block_argument_without_paren):\n\t  added. (follows sample/test.rb)\n\nMon Oct  6 11:57:06 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_beginendblock.rb, test/ruby/beginmainend.rb: added\n\t  test for eval-ed BEGIN END order.\n\nMon Oct  6 09:19:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): should pass \"weak\" value to next level.\n\t  [ruby-dev:21496]\n\n\t* eval.c (proc_alloc): should not use cached object if klass is\n\t  different. [ruby-talk:83685]\n\nSun Oct  5 23:27:09 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb: version information is added in document.\n\nSun Oct  5 23:07:03 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_f_END): block should be given.  [ruby-dev:21497]\n\nSun Oct  5 22:51:23 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/ext/openssl/extconf.rb: add check for some engine functions\n\t  unavailable in OpenSSL-0.9.6.\n\n\t* lib/ext/openssl/ossl_engine.c: ditto.\n\nSun Oct  5 17:56:30 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): fix evaluation order.  [ruby-list:38431]\n\nSun Oct  5 15:05:06 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* test/uri/*: translated RUNIT to Test::Unit.\n\nSun Oct  5 14:37:39 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/xsd/datatypes.rb: Rational -> Decimal string bug fix.\n\n\t* test/soap/marshal/test_marshal.rb: ditto.\n\n\t* test/soap/calc/test_calc_cgi.rb: add Config::CONFIG[\"EXEEXT\"] to\n\t  RUBYBIN.\n\nSun Oct  5 13:47:22 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_beginendblock.rb, test/ruby/beginmainend.rb: add tests\n\t  about scope, order and allowed syntax.\n\nSun Oct  5 11:54:29 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/envutil.rb: added.  split \"rubybin\" from test_system.rb.\n\n\t* test/ruby/test_system.rb: use envutil.rb\n\n\t* test/ruby/test_beginendblock.rb: added.\n\n\t* test/ruby/beginmainend.rb: added.  used in test_beginendblock.rb.\n\nSun Oct  5 11:23:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* test/testunit/runit/test_testresult.rb: removed some unnecessary\n\t  cruft.\n\nSun Oct  5 11:14:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/rubyunit.rb: aliasing TestCase into the top level is\n\t  problematic.\n\n\t* lib/runit/assert.rb: fixed a couple of bugs caused by recent\n\t  refactoring in Test::Unit.\n\n\t* test/testunit/runit/*: added.\n\nSun Oct  5 10:55:29 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/open-uri.rb (URI::Generic#find_proxy): no_proxy support did not\n\t  work.  [ruby-dev:21484]\n\nSun Oct  5 09:52:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: will use pp for output if available.\n\t  Can be disabled by setting Assertions.use_pp = false.\n\n\t* test/testunit/test_assertions.rb: made a small change to exception\n\t  formatting.\n\nSun Oct  5 07:42:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: made small improvements to assertion\n\t  messages. Deprecated Assertions#assert_not_nil; use #assert instead.\n\n\t* test/testunit/test_assertions.rb: ditto.\n\n\t* test/testunit/util/test_procwrapper.rb: use #assert instead of\n\t  #assert_not_nil.\n\nSun Oct  5 04:10:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: refactored message building.\n\nSun Oct  5 03:40:22 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.h: global symbols should be declared\n\t  as external.\n\nSun Oct  5 03:03:20 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* test/ruby/test_exception.rb (test_else): added.\n\nSun Oct  5 02:12:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: changed assertion messages to rely more\n\t  heavily on #inspect. Added backtrace filtering for exceptions in\n\t  assertion messages.\n\n\t* test/testunit/test_assertions.rb: ditto.\n\nSun Oct  5 02:12:00 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/acl.rb, lib/drb/ssl.rb: added.\n\n\t* lib/drb/drb.rb: exit from a thread using 'break'.\n\nSat Oct  4 21:49:14 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* gc.c (Init_stack): the type of space is changed to unsigned int\n\t  from double.  [ruby-dev:21483]\n\nSat Oct  4 17:52:59 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/netHttpClient.rb: follow http-access2.  hosts which matches\n\t  ENV['no_proxy'] or ENV['NO_PROXY'] are not proxyed.\n\t  - [,:] separated. (\"ruby-lang.org:rubyist.net\")\n\t  - no regexp. (give \"ruby-lang.org\", not \"*.ruby-lang.org\")\n\t  - if you want specify host by IP address, give full address.\n\t    (\"192.168.1.1, 192.168.1.2\")\n\n\t* lib/soap/rpc/cgistub.rb: return \"Status: XXX MMM\" line.\n\n\t* test/runner.rb: give testsuite name.\n\nSat Oct  4 15:16:02 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): instance variable dump do not cause error\n\t  for objects that cannot be dumped, if they traversed from\n\t  marshal_dump.  they are just ignored.\n\n\t* gc.c (Init_stack): cast \"space\" (doble value) into unsigned\n\t  int.  should run on PowerPC.\n\n\t* eval.c (rb_eval): should not execute else part if any exception\n\t  is caught. [ruby-dev:21482]\n\n\t* parse.y (f_args): should allow unparenthesized block argument.\n\n\t* parse.y (f_rest_arg): should allow unparenthesized rest\n\t  argument.\n\nSat Oct  4 14:59:51 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (initialize): raise ArgumentError if argument has\n\t  '\\0' character.\n\t  (relative_path_from): new method.\n\t  (each_entry): new method for replacement of dir_foreach.\n\t  (foreach, foreachline, dir_foreach, chdir): obsoleted.\n\nSat Oct  4 12:58:48 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* test/uri/* (6 files): added.\n\nSat Oct  4 12:44:45 2003  akira yamada  <akira@ruby-lang.org>\n\n\t* lib/uri/ftp.rb, lib/uri/mailto.rb: renamed to #to_s from #to_str.\n\nSat Oct  4 07:33:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/testsuite.rb: changed #<< to return self, and added\n\t  #delete.\n\n\t* test/testunit/test_testsuite.rb: ditto. Also slightly refactored\n\t  #test_size.\n\n\t* lib/test/unit/collector/objectspace.rb: collector now preserves the\n\t  hierarchy of suites.\n\n\t* test/testunit/collector/test_objectspace.rb: ditto.\n\nSat Oct  4 04:48:49 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/rubyext.c: default keys handled.\n\n\t* ext/syck/syck.h: lowered default buffer size to 16k for increased\n\t  performance.\n\n\t* test/yaml: checkin of basic unit tests.\n\nSat Oct  4 04:24:19 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: add check for X509V3_set_nconf.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509extfactory_set_config):\n\t  cannot implement if X509V3_set_nconf doesn't exist.\n\nSat Oct  4 02:12:44 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/xsd/datatypes.rb: dump sign by itself.  under the problematic\n\t  platform, sprintf(\"%+.10g\", -0.0) => +0.  sigh.\n\n\t* sample/wsdl/amazon/*: update schema ver2 to ver3.\n\nSat Oct  4 01:33:46 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb (initialize): duplicate and freeze argument.\n\t  (to_s): return duplicated string.\n\t  (children): new method.\n\t  (each_line): new alias to foreachline.\n\nFri Oct  3 16:13:19 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_asn1.c: add DER encoder and decoder.\n\n\t* ext/openssl/ossl_asn1.h: add OpenSSL::ASN1 module.\n\n\t* ext/openssl/ossl.c (Init_openssl): call Init_ossl_asn1.\n\n\t* ext/openssl/extconf.rb: check if X509_ATTRIBUTE has field \"single\".\n\n\t* ext/openssl/ossl_x509attr.c (ossl_x509attr_set_value): accept\n\t  DER encoded data argument.\n\n\t* ext/openssl/ossl_x509attr.c (ossl_x509attr_get_value): return\n\t  DER encoded data in OpenSSL::ASN1 types.\n\nFri Oct  3 13:02:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit.rb: refactored to use optparse.\n\n\t* lib/test/unit.rb: added support for selecting the output\n\t  level from the command-line.\n\n\t* lib/test/unit.rb: added a command-line switch to stop processing\n\t  the command-line, allowing arguments to be passed to tests.\n\n\t* lib/test/unit.rb: changed the method for specifying a runner or a\n\t  filter from the command-line.\n\n\t* lib/test/unit/collector/objectspace.rb: fixed a bug causing all\n\t  tests to be excluded when the filter was set to an empty array.\n\n\t* test/testunit/collector/test_objectspace.rb: ditto.\n\nFri Oct  3 08:14:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb/ruby-lex.rb (RubyLex::identify_identifier): support\n\t  'class ::Foo' syntax. [ruby-talk:83514]\n\nFri Oct  3 08:01:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: added a default message for #assert,\n\t  #assert_block, and #flunk.\n\n\t* test/testunit/test_assertions.rb: ditto.\n\n\t* lib/test/unit/failure.rb: failures now show a better trace of where\n\t  they occurred.\n\n\t* test/testunit/test_failure.rb: ditto (added).\n\n\t* lib/test/unit/testcase.rb: ditto.\n\n\t* test/testunit/test_testcase.rb: ditto.\n\n\t* lib/test/unit/util/backtracefilter.rb: added.\n\n\t* test/testunit/util/test_backtracefilter.rb: added.\n\n\t* lib/test/unit/error.rb: changed to use BacktraceFilter and improved\n\t  output.\n\n\t* test/testunit/test_error.rb: ditto.\n\nThu Oct  2 20:33:49 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_failure_initialize): conform with\n\t  orthodox initialization method.\n\n\t* ext/iconv/iconv.c (iconv_fail): initialize exception instance\n\t  from the class, and do not share instance variables with the\n\t  others.  [ruby-dev:21470]\n\nThu Oct  2 18:20:27 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* time.c (Init_Time): define initialize.  [ruby-dev:21469]\n\nThu Oct  2 17:39:38 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_engine.c: add a new module OpenSSL::Engine.\n\t  it supports OpenSSL hardware cryptographic engine interface.\n\n\t* ext/openssl/ossl_engine.h: ditto.\n\n\t* ext/openssl/MANIFEST: add ossl_engine.c and ossl_engine.h.\n\n\t* ext/openssl/extconf.rb: add check for openssl/engine.h.\n\n\t* ext/openssl/ossl.c: call Init_ossl_engine().\n\n\t* ext/openssl/ossl.h: include openssl/engine.h.\n\n\t* ext/openssl/ossl_pkey_{rsa,dsa,dh}.c: check if underlying\n\t  EVP_PKEY referes engine.\n\nThu Oct  2 17:22:37 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_load): restore instance variables (if any) before\n\t  loading from marshaled data.\n\nThu Oct  2 14:19:15 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (iconv_fail): now yield erred substring, and\n\t  set error object to $!.\n\n\t* ext/iconv/iconv.c (iconv_convert): error handler block should\n\t  return appended part and the rest.  if rest is nil, the\n\t  conversion stops.\n\nThu Oct  2 12:00:18 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* variable.c (rb_const_defined_0): look up constants in Object as\n\t  well.  [ruby-dev:21458]\n\n\t* test/ruby/test_defined.rb (TestDefined::test_defined): test for\n\t  constants.\n\nThu Oct  2 11:17:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/assertions.rb: should not capture an\n\t  AssertionFailedError unless explicitly requested.\n\n\t* test/testunit/test_assertions.rb: ditto.\n\n\t* test/testunit/collector/test_objectspace.rb: fixed a test failure\n\t  caused by methods being returned in different orders on different\n\t  platforms by moving test sorting from TestSuite into the locations\n\t  where suites are constructed. [ruby-talk:83156]\n\n\t* lib/test/unit/testcase.rb: ditto.\n\n\t* lib/test/unit/testsuite.rb: ditto.\n\n\t* lib/test/unit/collector/objectspace.rb: ditto.\n\nThu Oct  2 03:25:01 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* eval.c (rb_thread_raise): prototype; avoid VC++ warning.\n\nThu Oct  2 01:37:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_mdump): new marshal dumper. _dump is still\n\t  available for compatibility.\n\n\t* time.c (time_mload): new marshal loader.\n\n\t* marshal.c (w_object): preserve instance variables for objects\n\t  with marshal_dump.\n\n\t* marshal.c (r_object0): restore instance variables before calling\n\t  marshal_load.\n\n\t* error.c (rb_warn_m): always return nil.\n\nThu Oct  2 01:32:46 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_block_given_p): real required condition is\n\t  ruby_frame->prev->iter == ITER_CUR.\n\n\t* eval.c (rb_block_given_p): ditto.\n\n\t* eval.c (block_pass): update ruby_frame->iter only when previous\n\t  value is ITER_NOT.\n\nThu Oct  2 01:02:35 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_const_defined_at): should exclude constants from\n\t  Object when TYPE(klass) == T_MODULE *and* exclude is on.\n\t  [ruby-dev:21458]\n\n\t* variable.c (rb_const_get_0): do not lookup constants from Object\n\t  when TYPE(klass) == T_MODULE *and* exclude is on.\n\nThu Oct  2 00:21:11 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/logger/test_logger.rb: unlinking file before close causes\n\t  problem under win32 box.\n\n\t* lib/xsd/datatypes.rb(XSDFloat, XSDDouble): add +/- sign explicitly\n\t  when stringified and embedded into XML instance.  Ruby's sprintf may\n\t  format -0.0 as \"0.0\" (no minus sign) depending on underlying C\n\t  sprintf implementation.\n\n\t* test/xsd/test_xsd.rb, test/soap/test_basetype.rb: follow above change.\n\n\t* test/soap/calc/*: give httpd config param \"CGIInterpreter\".\n\t  \"/usr/bin/env ruby\" thing does not work under non-Unix boxes.\n\nSat Oct  2 00:42:20 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_byte): retrieve pointer from string value for each\n\t  time.  [ruby-dev:24404]\n\n\t* marshal.c (r_bytes0): ditto.\n\n\t* enum.c (sort_by_i): re-entrance check added.  [ruby-dev:24399]\n\n\t* io.c (io_read): should freeze all reading buffer.\n\t  [ruby-dev:24400]\n\n\t* string.c (rb_str_sum): should use bignums when bits is greater\n\t  than or equals to sizeof(long)*CHAR_BITS. [ruby-dev:24395]\n\n\t* eval.c (specific_eval): defer pointer retrieval to prevent\n\t  unsafe sourcefile string modification.  [ruby-dev:24382]\n\n\t* string.c (rb_str_sum): wrong cast caused wrong result.\n\t  [ruby-dev:24385]\n\n\t* enum.c (enum_sort_by): hide temporary array from\n\t  ObjectSpace.each_object.  [ruby-dev:24386]\n\n\t* string.c (rb_str_sum): check was done with false pointer.\n\t  [ruby-dev:24383]\n\n\t* string.c (rb_str_sum): string may be altered.  [ruby-dev:24381]\n\nThu Oct  2 00:25:21 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* signal.c (ruby_signal_name): adjust to the prototype.\n\n\t* process.c (pst_inspect): ditto.\n\n\t* ext/etc/etc.c (etc_getgrent, Init_etc): typo.\n\nWed Oct  1 20:49:41 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (heaps): manage slots and limits together.  [ruby-dev:21453]\n\n\t* gc.c (add_heap): should not clear heaps slot even if realloc()\n\t  failed.\n\nWed Oct  1 20:36:49 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* MANIFEST: add wince/mkconfig_wce.rb.\n\nWed Oct  1 17:22:33 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/etc/etc.c: add new functions: setpwent, getpwent, endpwent,\n\t  setgrent, getgrent, endgrent.\n\n\t* ext/socket/socket.c (sock_s_gethostbyname): do not reverse lookup.\n\nWed Oct  1 17:01:30 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_load): Object scope had priority over required file\n\t  scope.  [ruby-dev:21415]\n\nWed Oct  1 14:09:53 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/mkconfig_wce.rb: sorry, forget to commit.\n\nWed Oct  1 10:08:42 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/setup.mak: add sigmarionIII SDK support.\n\n\t* wince/Makefile.sub: ditto.\n\n\t* wince/mkexports.rb: fix linker error in SH4.\n\n\t* wince/mkconfig_wce.rb: camouflage RUBY_PLATFORM for compiling ext.\n\nWed Oct  1 08:02:52 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/time_wce.c (time): add zero check.\n\nTue Sep 30 16:11:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* Makefile.in: copy lex.c from $(srcdir) if it's not the current\n\t  directory.  [ruby-dev:21437]\n\nTue Sep 30 11:29:23 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* process.c (pst_inspect): describe stopped process \"stopped\".\n\nTue Sep 30 09:31:56 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/runner.rb: glob for directories.\n\nTue Sep 30 09:11:43 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): while/until should not capture break unless\n\t  they are destination of the break.\n\nTue Sep 30 03:12:02 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (finish): revert to 1.93.\n\n\t* lib/net/pop.rb (finish): revert to 1.60.\n\n\t* lib/net/smtp.rb (finish): revert to 1.67.\n\n\t* lib/net/http.rb (do_start): ensure to close socket if failed to\n\t  start session.\n\n\t* lib/net/pop.rb (do_start): ditto.\n\n\t* lib/net/smtp.rb (do_start): ditto.\n\n\t* lib/net/smtp.rb: SMTP#started? wrongly returned false always.\n\nTue Sep 30 02:54:49 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/ruby/test_iterator.rb: new test\n\t  test_break__nested_loop[123].\n\nMon Sep 29 23:39:13 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (finish): does not raise IOError even if\n\t  !started?, to allow closing socket which was opened before\n\t  session started.\n\n\t* lib/net/pop.rb (finish): ditto.\n\n\t* lib/net/smtp.rb (finish): ditto.\n\nMon Sep 29 19:06:51 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/win32ole/extconf.rb: add windows.h checking.\n\t  (ruby-bugs:PR#1185)\n\nMon Sep 29 16:18:30 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb: check if the given logdevice object respond_to :write\n\t  and :close, not is_a? IO.  duck duck.\n\n\t* test/logger/test_logger.rb: self IO.pipe reading/writing may be\n\t  locked by the flood.  use tempfile.\n\n\t* lib/wsdl/xmlSchema/data.rb: wrong constant reference.\n\nMon Sep 29 16:11:23 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: clean up temporary symlink.\n\t  Patched by NaHi.  [ruby-dev:21420]\n\nMon Sep 29 11:16:55 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_atfork): wrong format specifier.\n\t  [ruby-dev:21428]\n\n\t* process.c (pst_inspect): better description.\n\nMon Sep 29 02:31:44 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/utils.rb (Utils::su): use setgid and setuid to\n\t  set real and effective IDs. and setup group access list by\n\t  initgroups.\n\nSun Sep 28 11:14:19 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* ext/digest/digest.c (Init_digest): `copy_object' was deprecated.\n\t  `initialize_copy' should be defined.\n\n\t* ext/stringio/stringio.c (Init_stringio): ditto.\n\nSat Sep 27 18:25:13 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/xsd/charset.rb: XSD::Charset.is_ces did return always true under\n\t  $KCODE = \"NONE\" environment.  check added.\n\n\t* test/xsd/test_xsd.rb: add tests for above fix.\n\nSat Sep 27 15:58:50 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/rpc/cgistub.rb: make logging severity threshold higher.\n\n\t* lib/soap/rpc/standaloneServer.rb: defer WEBrick server start to give\n\t  a chance to reset logging severity threshold.\n\n\t* test/soap/calc/test_*, test/soap/helloworld/test_helloworld.rb: run\n\t  silent.\n\nSat Sep 27 09:44:18 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/test_fileutils.rb: clear all errors on Windows.\n\t  [ruby-dev:21417]\n\n\t* test/fileutils/test_nowrite.rb: ditto.\n\nMon Sep 27 09:14:03 2004  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_delete): comparison may change the capacity.\n\t  [ruby-dev:24348]\n\n\t* array.c (rb_ary_fill): fill should honor length argument.\n\t  [ruby-dev:24346]\n\n\t* array.c (rb_ary_replace): should not use ptr from shared array.\n\t  [ruby-dev:24345]\n\n\t* ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK.\n\t  [ruby-talk:113807]\n\nSat Sep 27 04:57:07 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_file.rb: new file.  only asserts unlink-before-close\n\t  behaviour now.\n\n\t* test/soap/marshal/test_digraph.rb: should close before unlink.\n\t  unlink-before-close pattern is not needed here.\n\nSat Sep 27 03:32:37 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/soap/*, test/wsdl/*, test/xsd/*: move TestCase classes into\n\t  each module namespace.  TestMarshal in\n\t  test/soap/marshal/test_marshal.rb crashed with\n\t  test/ruby/test_marshal.rb.\n\nSat Sep 27 01:30:59 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): on win32, type of the 4th\n\t  argument of getsockopt is char *.\n\nFri Sep 26 18:35:40 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/resolv-replace.rb: 1.8 compliance.  [ruby-talk:82946]\n\nFri Sep 26 17:39:27 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_marshal.rb: add test for ruby's objects.\n\nFri Sep 26 09:52:44 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* defines.h (flush_register_windows): use volatile only for gcc on\n\t  Solaris.  [ruby-dev:21403]\n\n\t* lib/mkmf.rb (xsystem): use system directly to honor shell meta\n\t  charaters.\n\nFri Sep 26 00:10:13 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/README: updated.\n\nThu Sep 25 17:48:10 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/openssl/ossl.c (ossl_buf2str): fix type of 1st argument for\n\t  rb_protect.\n\n\t* ext/openssl/ossl_hmac.c (ossl_hmac_digest): should return meaningful\n\t  value.\n\nThu Sep 25 09:00:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/ostruct.rb: Added OpenStruct#==.\n\n\t* test/ostruct/test_ostruct.rb: Added.\n\nThu Sep 25 07:55:26 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/win32ole/win32ole.c, ext/openssl/ossl_pkey_dsa.c,\n\t  ext/openssl/ossl_pkey_rsa.c, ext/bigdecimal/bigdecimal.h: must\n\t  not use C++ or C99 style comment yet.  (ruby-bugs:PR#1184)\n\nThu Sep 25 00:23:22 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* MANIFEST: add SOAP4R.\n\nThu Sep 25 00:13:15 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/soap/* (29 files): SOAP4R added.\n\n\t* lib/wsdl/* (42 files): WSDL4R added.\n\n\t* lib/xsd/* (12 files): XSD4R added.\n\n\t* test/soap/* (16 files): added.\n\n\t* test/wsdl/* (2 files): added.\n\n\t* test/xsd/* (3 files): added.\n\n\t* sample/soap/* (27 files): added.\n\n\t* sample/wsdl/* (13 files): added.\n\nWed Sep 24 02:08:11 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpservlet/cgihandler.rb: conform to mswin32.\n\t  [ruby-talk:82735], [ruby-talk:82748], [ruby-talk:82818]\n\nTue Sep 23 23:10:16 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb: add Logger#<<(msg) for writing msg without any\n\t  formatting.\n\n\t* test/logger/test_logger.rb: ditto.\n\nTue Sep 23 20:47:51 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_warn_m): should not warn if -W0 is specified.\n\t  [ruby-talk:82675]\n\nMon Sep 22 21:28:57 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* MANIFEST: updated.\n\nMon Sep 22 19:22:26 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* configure.in (AC_CHECK_FUNCS): add setuid and setgid.\n\nMon Sep 22 12:34:55 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): skip preceding zeros before counting\n\t  digits in the mantissa. (ruby-bugs:PR#1181)\n\nSun Sep 21 04:12:36 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ocsp.c (ossl_ocspreq_initialize): the argument\n\t  should be a String.\n\n\t* ext/openssl/ossl_ocsp.c (ossl_ocspres_initialize): ditt.\n\n\t* ext/openssl/ossl_x509attr.c (ossl_x509attr_initialize): ditto.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509ext_initialize): ditto.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509ext_set_value): ditto.\n\nSat Sep 20 11:49:05 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb: typo fixed.\n\n\t* test/logger/test_logger.rb: new file.\n\nFri Sep 19 11:39:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* test/testunit/*: Added.\n\n\t* lib/test/unit.rb: Documentation update.\n\n\t* lib/test/unit/ui/console/testrunner.rb (TestRunner#initialize):\n\t  Ditto.\n\n\t* lib/test/unit.rb: Factored out an ObjectSpace collector.\n\n\t* lib/test/unit/collector/objectspace.rb: Ditto.\n\n\t* sample/testunit/*: Added.\n\nFri Sep 19 01:00:48 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/log.rb (BasicLog#log): get rid of as ineffectual\n\t  condition.\n\n\t* lib/webrick/log.rb (BasicLog#format): add \"\\n\" to message.\n\nThu Sep 18 22:43:20 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): should push PROT_PCALL tag for orphans.\n\n\t* eval.c (proc_invoke): should update \"result\" for orphans.\n\nThu Sep 18 20:33:03 2003  Tietew  <tietew-ml-ruby-list@tietew.net>\n\n\t* parse.y (str_xquote): do not prepend escapes in\n\t  backqoute literals.  [ruby-list:38409]\n\nThu Sep 18 20:30:17 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb: update document.\n\nThu Sep 18 15:27:05 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/logger.rb: new file.  Logger, formerly called devel-logger or\n\t  Devel::Logger.\n\n\t* sample/logger/*: new file.  samples of logger.rb.\n\nWed Sep 17 23:41:45 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (localjump_destination): should not raise ThreadError\n\t  exception for \"break\". [ruby-dev:21348]\n\n\t* eval.c (proc_invoke): use result instead of prot_tag->retval.\n\t  retval is no longer propagated to the ancestors.\n\nWed Sep 17 20:34:00 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (tokadd_string, parse_string, yylex): escaped terminator\n\t  is now interpreted as is.  [ruby-talk:82206]\n\nWed Sep 17 18:52:36 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/fileutils/fileassertions.rb: new file.\n\n\t* test/fileutils/test_fileutils.rb: new file.\n\n\t* test/fileutils/test_nowrite.rb: new file.\n\nWed Sep 17 18:51:02 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/strscan/test_stringscanner.rb: require test/unit.\n\nWed Sep 17 18:35:34 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* test/strscan/test_stringscanner.rb: new file.\n\nWed Sep 17 18:03:30 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl: all files are reviewed to simplify and avoid memory leak.\n\n\t* ext/openssl/extconf.rb: add check for assert.h.\n\n\t* ext/openssl/ossl.c (ossl_buf2str): new function to convert\n\t  C buffer to String and free buffer.\n\n\t* ext/openssl/ossl.c (ossl_x509_ary2sk): new function to convert\n\t  Array of OpenSSL::X509 to STACK_OF(X509) with exception safe.\n\n\t* ext/openssl/ossl.c (ossl_to_der, ossl_to_der_if_possible): new\n\t  functions to convert object to DER string.\n\n\t* ext/openssl/ossl.h: ditto.\n\n\t* ext/openssl/ossl_bio.c (ossl_membio2str): new function to convert\n\t  BIO to String object and free BIO.\n\n\t* ext/openssl/ossl_bio.h: ditto.\n\n\t* ext/openssl/ossl_pkcs7.c (ossl_pkcs7_to_der): add for \"to_der\".\n\n\t* ext/openssl/ossl_x509name.c (ossl_x509name_to_der): ditto.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509ext_to_der): ditto.\n\n\t* ext/openssl/ossl_x509ext.c (create_ext_from_array): removed\n\t  and reimplement in openssl/x509.rb.\n\n\t* ext/openssl/ossl_x509attr.c: reimplemented and disable some\n\t  method temporarily. this class doesn't work fine without ASN.1\n\t  data support;-) I'll rewrite in near future.\n\n\t* ext/openssl/lib/openssl/x509.c (X509::Attribute): get rid off\n\t  unused code.\n\n\t* ext/openssl/lib/openssl/x509.c (X509::ExtensionFactory): refine all.\n\nTue Sep 16 22:25:06 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/csv/test_csv.rb: add negative tests of row_sep.\n\nTue Sep 16 18:02:36 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): should not translate character\n\t  class range edge. [ruby-list:38393]\n\nTue Sep 16 16:47:56 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* MANIFEST: add test/csv/mac.csv.\n\n\t* win32/Makefile.sub, bcc32/Makefile.sub (test): add phony NUL target.\n\nMon Sep 15 19:02:52 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/csv.rb: add extra pamameter to specify row(record) separater\n\t  character.  To parse Mac's CR separated CSV, do like this.\n\t    CSV.open(\"mac.csv\", \"r\", ?,, ?\\r) { |row| p row.to_a }\n\t  The 3rd parameter in this example ?, is for column separater and the\n\t  4th ?\\r is for row separater.  Row separater is nil by default.  Nil\n\t  separater means \"\\r\\n\" or \"\\n\".\n\n\t* test/csv/test_csv.rb: add tests for above feature.\n\n\t* test/csv/mac.csv: added.  Sample CR separated CSV file.\n\nFri Sep 12 22:41:48 2003  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* ext/openssl/ossl.c: move ASN.1 stuff to ossl_asn1.[ch]\n\n\t* ext/openssl/ossl.c: move BIO stuff to ossl_bio.[ch]\n\n\t* ext/openssl/ossl_asn1.[ch]: new files\n\n\t* ext/openssl/ossl_bio.[ch]: new files\n\nFri Sep 12 12:30:41 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* intern.h (rb_disable_super, rb_enable_super): replace with dummy\n\t  expressions instead of prototypes.  the functions remain yet for\n\t  binary compatibility.  [ruby-talk:81758]\n\nFri Sep 12 12:09:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_and): convert argument using 'to_int'.\n\n\t* bignum.c (rb_big_or): ditto.\n\n\t* bignum.c (rb_big_xor): ditto.\n\nFri Sep 12 07:06:14 2003  David Black  <dblack@superlink.net>\n\n\t* lib/scanf.rb: Took out useless @matched_item variable; some small\n\t  refactoring.\n\nThu Sep 11 08:43:44 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_require): allow \"require\" on $SAFE>0, if feature\n\t  name is not tainted.\n\n\t* lib/rexml/parsers/baseparser.rb (REXML::Parsers::BaseParser::stream):\n\t  Supports StringIO.\n\nWed Sep 10 22:47:30 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.h: add a workaround for win32 platform.\n\t  libeay32.dll doesn't export functions defined in conf_api.h.\n\n\t* ext/openssl/ossl_config.c (ossl_config_initialize): ditto.\n\n\t* ext/openssl/ossl_config.c (ossl_config_add_value): ditto.\n\n\t* ext/openssl/ossl_config.c (set_conf_section_i): should check\n\t  if the argument is Array.\n\nWed Sep 10 22:41:54 2003  Tietew  <tietew@tietew.net>\n\n\t* eval.c (win32_get_exception_list): avoid VC7 warning.\n\t  [ruby-win32:577]\n\nTue Sep  9 10:39:51 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (struct tag): dst should be VALUE.\n\nTue Sep  9 10:39:51 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (localjump_destination): stop at the scope where the current\n\t  block was created.  [ruby-dev:21353]\n\nTue Sep  9 05:17:04 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_config.rb: avoid compile error in OpenSSL-0.9.6.\n\nTue Sep  9 02:41:35 2003  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* ext/openssl/ossl_config.c: Refine compatibility.\n\nTue Sep  9 01:50:45 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httpserver.rb (HTTPServer#access_log): add \"\\n\" to\n\t  the message.\n\n\t* lib/webrick/log.rb (BasicLog#log): add \"\\n\" only if needed.\n\nMon Sep  8 22:15:33 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/multi-tk.rb: modify security check at creating\n\t  a new interpreter\n\nMon Sep  8 20:00:12 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb, lib/optparse/version.rb: search also all\n\t  capital versions.\n\nMon Sep  8 19:26:33 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.h: include openssl/conf.h and openssl/conf_api.h.\n\n\t* ext/openssl/ossl_config.c: refine all with backward compatibility.\n\n\t* ext/openssl/ossl_config.h: export GetConfigPtr() and DupConfigPtr().\n\n\t* ext/openssl/ossl_x509.c: added new constants under X509 module.\n\t  DEFAULT_CERT_AREA, DEFAULT_CERT_DIR, DEFAULT_CERT_FILE,\n\t  DEFAULT_CERT_DIR_ENV, DEFAULT_CERT_FILE_ENV and DEFAULT_PRIVATE_DIR.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509extfactory_free): don't free\n\t  the members of the struct. it's left to GC.\n\n\t* ext/openssl/ossl_x509ext.c (ossl_x509_set_config): add for config=.\n\n\t* ext/openssl/ossl_x509ext.c (Xossl_x509extfactory_initialize):\n\t  add attr readers: issuer_certificate, subject_certificate,\n\t  subject_request, crl and config.\n\nMon Sep  8 18:26:41 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/accesslog.rb (AccessLog::setup_params): use req.port\n\t  instead of config[:Port] or req.request_uri.port.\n\n\t* lib/webrick/httprequest.rb (HTTPRequest#meta_vars): ditto.\n\n\t* lib/webrick/httpservlet/filehandler.rb (FileHandler#dir_list): ditto.\n\n\t* lib/webrick/config.rb: :Listen option never be used.\n\n\t* lib/webrick/server.rb (GenericServer#initialize): don't use :Listen\n\t  option and add warning message.\n\n\t* lib/webrick/log.rb (BasicLog#<<): shortcut of log(INFO, ...).\n\n\t* lib/webrick/httpserver.rb (HTTPServer#accesslog): use << for logging.\n\nSun Sep  7 16:08:28 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_mainloop_core): fixed signal-trap bug\n\n\t* ext/tk/lib/*.rb : Ruby/Tk works at $SAFE == 4\n\nSat Sep  6 02:26:34 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_*.rb: assert_same, assert_match, and so on.\n\nSat Sep  6 18:45:46 2003  Mauricio Fernandez  <batsman.geo@yahoo.com>\n\n\t* parse.y (assignable): call rb_compile_error(), not rb_bug().\n\t  [ruby-core:01523]\n\nSat Sep  6 17:40:41 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ruby_missing.c: rid of unnecessary backward\n\t  compatibility stuff. and remove DEFINE_ALLOC_WRAPPER from\n\t  all sources.\n\n\t* ext/openssl/ossl_x509ext.c (X509::Extension.new): new method.\n\n\t* ext/openssl/ossl_x509ext.c (X509::Extension#oid=): new method.\n\n\t* ext/openssl/ossl_x509ext.c (X509::Extension#value=): new method.\n\n\t* ext/openssl/ossl_x509ext.c (X509::Extension#critical=): new method.\n\nSat Sep  6 01:23:22 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (CreateChild): need to quote cmd if RUBYSHELL is set.\n\n\t* win32/win32.c (CreateChild): fix condition about whether to call\n\t  shell or not.\n\nSat Sep  6 00:36:20 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* Makefile.in (test): phony target.\n\n\t* lib/mkmf.rb (have_library, find_library): configure by library\n\t  name.\n\n\t* lib/optparse.rb (OptionParser#order, #permute, #parse): allow an\n\t  array as argument.\n\n\t* test/ruby/test_*.rb: moved invariants to left side in\n\t  assert_equal, and use assert_nil, assert_raises and so on.\n\n\t* win32/win32.c (isInternalCmd): distinguish command.com and\n\t  cmd.exe.\n\n\t* win32/win32.c (make_cmdvector): a character just after wildcard\n\t  was ignored.  [ruby-core:01518]\n\nFri Sep  5 20:27:08 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_*.rb: replace 'assert(a == b)' with assert_equal(a, b)'\n\nFri Sep  5 18:00:51 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/x509.rb: new method X509::Name::parse.\n\n\t* ext/openssl/ossl_digest.c: add ossl_digest_new().\n\n\t* ext/openssl/ossl_digest.h: ditto.\n\n\t* ext/openssl/ossl_cipher.c: add ossl_cipher_new().\n\n\t* ext/openssl/ossl_cipher.h: ditto.\n\nFri Sep  5 15:32:04 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-font-lock-maybe-here-docs): should not\n\t  search delimiter forward if found in backward.\n\nFri Sep  5 13:32:48 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/runner.rb: arguments should be keys.\n\nFri Sep  5 12:09:55 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* test/ruby/test_system.rb (test_system): check existence of ruby\n\t  interpreter.\n\nFri Sep  5 11:32:17 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/optparse.rb (--version): fix assignment/reference order.\n\n\t* lib/optparse.rb (OptionParser#help): new; OptionParser#to_s may\n\t  be deprecated in future.\n\n\t* lib/optparse/version.rb (OptionParser#show_version): hide Object.\n\n\t* test/runner.rb: fix optparse usage.\n\n\t* test/runner.rb: glob all testsuits if no tests given.\n\nFri Sep  5 10:42:58 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/runner.rb: added.  gets testcases from command line and runs it.\n\n\t* test/ruby/test_gc.rb: remove useless part which was for dumping test\n\t  result.\n\nFri Sep  5 09:28:59 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby/test_gc.rb: added.  splitter.rb which I made to split\n\t  sample/test.rb into test/ruby/test_* kindly removed GC test (the\n\t  last section in the original test) to reduce things to be worried.\n\nFri Sep  5 03:00:04 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* test/ruby/test_iterator.rb (test_block_in_arg): add no block\n\t  given tests.\n\n\t* test/ruby/test_iterator.rb (test_ljump): uncomment LocalJumpError\n\t  test.\n\nFri Sep  5 01:10:11 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/ruby: tests for ruby itself.\n\n\t* test/ruby/test_*.rb: split sample/test.rb into 28 test/unit testcases.\n\t  some tests could not be translates...  search '!!' mark to see it.\n\n\t* test/csv/test_csv.rb: should require 'csv', not '../lib/csv'.  test\n\t  runner should set load path correctly.\n\nFri Sep  5 01:03:59 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/csv/test_csv.rb: close opened files for CSV::IOBuf explicitly.\n\t  opened file cannot be removed under win32 box.\n\nThu Sep  4 23:59:40 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* parse.y (tokadd_string): newlines have no special meanings in\n\t  %w/%W, otherwise they are ignored only when interpolation is\n\t  enabled.  [ruby-dev:21325]\n\nThu Sep  4 19:38:25 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* ext/io/wait/.cvsignore: added.\n\n\t* ext/openssl/.cvsignore: added.\n\nThu Sep  4 19:28:24 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* sample/openssl: added.  Sample of standard distribution library\n\t  should be locate in sample/{module_name}/*.\n\n\t* ext/openssl/sample/*: removed.  move to sample/openssl/*.\n\nThu Sep  4 18:02:15 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/csv/test_csv.rb: use remove_const to reduce warnings.  use\n\t  Dir.tmpdir to locate working files.\n\nThu Sep  4 17:41:31 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-here-doc-beg-re): underscore also is\n\t  valid delimiter.\n\n\t* misc/ruby-mode.el (ruby-here-doc-end-match): must quote\n\t  arbitrary string to use as regexp.\n\n\t* misc/ruby-mode.el (ruby-font-lock-maybe-here-docs): must not\n\t  call `ruby-here-doc-end-match' unless `ruby-here-doc-beg-re'\n\t  matched.\n\nThu Sep  4 15:40:07 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test/csv/test_csv.rb: run on test/unit original layer.\n\nThu Sep  4 12:54:50 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/token.c: headerless documents with root-level spacing now\n\t  honored.\n\nThu Sep  4 00:06:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (mark_frame_adj): need to adjust argv pointer if using\n\t  system's alloca. [ruby-core:01503]\n\nWed Sep  3 21:33:20 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* test: add test directory.  Test::Unit aware testcases and needed\n\t  files should be located in this directory.  dir/file name convention;\n\t    test/{module_name}/test_{testcase_name}.rb\n\t    test/{module_name}/{needed_files}\n\t  someday, someone will write testrunner which searches test_*.rb and\n\t  run testcases automatically.\n\n\t* test/csv/*: add testcase for lib/csv.rb.\n\nWed Sep  3 01:37:09 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_gets): should call next_argv() before type check\n\t  current_file. [ruby-list:38336]\n\nTue Sep  2 20:37:15 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/net/protocols.rb (SSLIO#ssl_connect): warning\n\t  for skipping server verification.\n\nTue Sep  2 23:36:57 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): should retrieve retval when pcall is true.\n\nTue Sep  2 14:09:20 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/extconf.rb: check s6_addr8 in in6_addr (Tru64 UNIX).\n\t  the patch is submitted by nmu <nmu@users.sourceforge.jp>.\n\n\t* ext/socket/getaddrinfo.c (getaddrinfo): should use in6_addr8 on\n\t  some platforms.\n\n\t* ext/socket/getnameinfo.c (getnameinfo): ditto.\n\nTue Sep  2 14:02:19 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke): fixed bug on passing a exception\n\n\t* ext/tk/lib/{tk.rb, tkcanvas.rb, tkfont.rb, tktext.rb} :\n\t  bug fix and improvement of font control\n\nTue Sep  2 09:51:36 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): should not handle exceptions within rescue\n\t  argument.  [ruby-talk:80804]\n\nTue Sep  2 00:44:37 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* re.c (rb_memsearch): fix overrun.  [ruby-talk:80759]\n\nTue Sep  2 00:41:27 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/iconv/iconv.c (map_charset): use lower case keys.\n\n\t* ext/iconv/iconv.c (iconv_fail): just yield error and return the\n\t  result if a block is given.\n\n\t* ext/iconv/iconv.c (iconv_convert): yield error and append the\n\t  result if a block is given.\n\n\t* ext/iconv/charset_alias.rb (charset_alias): optional third\n\t  argument.\n\n\t* ext/iconv/charset_alias.rb (charset_alias): use CP932 instead of\n\t  SHIFT_JIS on cygwin.\n\nMon Sep  1 18:34:25 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval): make tail recursion in ELSE clause of\n\t  RESCUE a jump.\n\nMon Sep  1 18:00:02 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (aref_args): forgot to call NEW_SPLAT(). reported by\n\t  Dave Butcher.\n\n\t* eval.c (Init_Thread): protect thgroup_default.  suggested by Guy\n\t  Decoux in [ruby-talk:80623]\n\nMon Sep  1 16:59:10 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_thread_switch): add RESTORE_EXIT; exit by another\n\t  thread termination.\n\n\t* eval.c (rb_thread_start_0): should not error_print() within\n\t  terminated thread, because $stderr used by it might be\n\t  overriden now.  [ruby-dev:21280]\n\nSun Aug 31 22:46:55 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (TAG_DST()): take no argument.\n\n\t* process.c (p_gid_sw_ensure): return VALUE.\n\nSun Aug 31 22:27:10 2003  Hidetoshi NAGAI  <nagai@dumbo.ai.kyutech.ac.jp>\n\n\t* process.c (p_gid_sw_ensure): lack of function type\n\nSun Aug 31 12:25:06 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb: --version takes an optional argument; \"all\" or\n\t  a list of package names.\n\nSun Aug 31 10:17:02 2003  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: yyyy/mm is not an acceptable format.\n\n\t* lib/time.rb: follow above.\n\nSat Aug 30 14:25:43 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_iter_break): should not call TAG_JUMP directly.\n\nSat Aug 30 03:58:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (struct BLOCK): remove BLOCKTAG, use scope instead.\n\n\t* eval.c (POP_TAG): no longer propagate retval.  retval is now set\n\t  directly by localjump_destination().\n\n\t* eval.c (localjump_destination): new function to cast\n\t  return/break local jump.\n\n\t* eval.c (rb_yield_0): stop TAG_RETURN/TAG_BREAK escaping.\n\nFri Aug 29 22:35:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* bigdecimal.c *.html: The 2nd arg. for add,sub,mult, and div is 0,\n\t  then result will be the same as +,-,*,/ respectively.\n\nFri Aug 29 17:30:15 2003  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* process.c: bug fix\n\n\t* process.c: add rb_secure(2) to methods of Process::{UID,GID,Sys}\n\n\t* process.c: deny handling IDs during evaluating the block given to\n\t  the Process::{UID,GID}.switch method\n\n\t* ext/tcltklib/tcltklib.c : some methods have no effect if on slave-IP\n\n\t* ext/tcltklib/tcltklib.c : can create a interpreter without Tk\n\n\t* ext/tcltklib/tcltklib.c : bug fix on handling exceptions\n\n\t* ext/tcltklib/MANUAL.euc : modify\n\n\t* ext/tk/lib/tk.rb : freeze some core modules\n\n\t* ext/tk/lib/multi-tk.rb : more secure\n\n\t* ext/tk/lib/tk.rb: TkVariable.new(array) --> treat the array as the\n\t  Tk's list\n\n\t* ext/tk/lib/tk.rb: improve accessibility of TkVariable object\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tkfont.rb, ext/tk/lib/tkcanvas.rb,\n\t  ext/tk/lib/tktext.rb : fix bug of font handling\n\n\t* ext/tk/lib/tkfont.rb TkFont.new() accepts compound fonts\n\nThu Aug 28 22:07:12 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_autoload_load): call const_missing if autoloading\n\t  constant is not defined to allow hook.\n\n\t* eval.c (rb_eval): use rb_const_get_from() instead of\n\t  rb_const_get_at().\n\n\t* eval.c (is_defined): forgot to check NODE_COLON3.\n\nThu Aug 28 17:30:24 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_const_get_0): should check constants defined in\n\t  included modules, if klass is Object. [ruby-talk:79302]\n\n\t* numeric.c (check_uint): check should be done using UINT_MAX, not\n\t  INT_MAX. this fix is submitted by Lyle Johnson\n\t  <lyle@knology.net> in [ruby-core:01486]\n\nThu Aug 28 05:02:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (singleton): typo fixed (ruby-bugs-ja:PR#562)\n\nThu Aug 28 02:37:45 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): *a = [1,2] now assigns [[1,2]] to a.\n\t  consistent with *a = [1], which set [[1]] to a.\n\n\t* node.h: merge NODE_RESTARY to NODE_SPLAT.\n\n\t* parse.y: rules simplified a bit by removing NODE_RESTARY.\n\n\t* sample/test.rb: updated for new assignment behavior.\n\nWed Aug 27 22:33:24 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* error.c (rb_bug): should not use other methods; this function is\n\t  not for ordinary use.  [ruby-dev:21259]\n\nWed Aug 27 15:07:57 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb (check_response): AUTH CRAM-MD5 returns 334\n\t  response. [ruby-list:38279]\n\nWed Aug 27 05:10:15 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* win32/win32.c (map_errno): support winsock error.\n\n\t* win32/win32.c (pipe_exec, CreateChild, poll_child_status, waitpid,\n\t  kill, link, rb_w32_rename, unixtime_to_filetime, rb_w32_utime):\n\t  pass errno to map_errno().\n\n\t* win32/win32.c (rb_w32_select, rb_w32_accept, rb_w32_bind,\n\t  rb_w32_connect, rb_w32_getpeername, rb_w32_getsockname,\n\t  rb_w32_getsockopt, rb_w32_ioctlsocket, rb_w32_listen, rb_w32_recv,\n\t  rb_w32_recvfrom, rb_w32_send, rb_w32_sendto, rb_w32_setsockopt,\n\t  rb_w32_shutdown, rb_w32_socket, rb_w32_gethostbyaddr,\n\t  rb_w32_gethostbyname, rb_w32_gethostname, rb_w32_getprotobyname,\n\t  rb_w32_getprotobynumber, rb_w32_getservbyname, rb_w32_getservbyport,\n\t  rb_w32_fclose, rb_w32_close): use map_errno().\n\n\t* win32/win32.h: add winsock errors.\n\nTue Aug 26 23:53:23 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/ostruct.rb (OpenStruct::method_missing): prohibit modifying\n\t  frozen OpenStruct. [ruby-talk:80214]\n\nTue Aug 26 20:03:50 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_tmpsrc): add the hook for source.\n\t  [ruby-list:38122]\n\nTue Aug 26 15:59:53 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* implicit.c (syck_type_id_to_taguri): corrected detection of\n\t  x-private types.\n\nSun Aug 24 01:02:48 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* file.c (file_expand_path): performance improvement.\n\t  [ruby-talk:79748]\n\nSat Aug 23 23:41:16 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_s_expand_path): avoid calling rb_scan_args() for\n\t  apparent cases. [ruby-talk:79748]\n\nSat Aug 23 18:56:53 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/nkf/nkf.c (rb_nkf_putchar): should use rb_str_resize() to just\n\t  resize a string, rb_str_cat() disallows NULL.  [ruby-dev:21237]\n\nSat Aug 23 16:48:41 2003  Keiju Ishitsuka  <keiju@ishitsuka.com>\n\n\t* lib/irb/ruby-lex.rb: bug fix for \"foo\" !~ /bar/. [ruby-talk:79942]\n\nSat Aug 23 15:59:58 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_eval, rb_iterate, block_pass): reduce PUSH/POP_TAG and\n\t  EXEC_TAG() for retry.  [ruby-dev:21216]\n\nSat Aug 23 02:32:33 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_splat): should check if \"values\" is array.\n\n\t* enum.c (each_with_index_i): typo.\n\nFri Aug 22 17:07:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (inject_i): use rb_yield_values.\n\n\t* enum.c (each_with_index_i): ditto.\n\n\t* eval.c (rb_yield_splat): new function to call \"yield *values\".\n\n\t* string.c (rb_str_scan): use rb_yield_splat().\n\nFri Aug 22 06:13:22 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/rubyext.c: refactoring of the transfer method\n\t  dispatch.  added yaml_org_handler for faster dispatch of\n\t  transfers to base types.\n\n\t* lib/yaml/rubytypes.rb: removed handling of builtins from\n\t  Ruby library.\n\n\t* ext/syck/token.c: quoted and block scalars are now implicit !str\n\n\t* ext/syck/implicit.c: empty string detected as !null.\n\nFri Aug 22 01:00:31 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (block_pass): improve passing current block.\n\nFri Aug 22 00:13:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c: Int. overflow bug in multiplication\n\t  fixed, and VpNmlz() speed up.\n\nWed Aug 20 16:44:49 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): many systems seem to have\n\t  a problem in select() after EINPROGRESS.  [ruby-list:38080]\n\nWed Aug 20 01:31:17 2003  why the lucky stiff  <why@ruby-lang.org>\n\n\t* ext/syck/syck.h: Parser definition problems on HP-UX.\n\t  [ruby-talk:79389]\n\n\t* ext/syck/handler.c (syck_hdlr_get_anchor): Memory leak.\n\n\t* ext/syck/syck.s (syck_io_file_read): Bad arguments to fread.\n\n\t* ext/syck/rubyext.c: Tainting issues.\n\nTue Aug 19 23:20:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c .h .html: to_s(\"+\") implemented.\n\n\t* ext/bigdecimal/lib/bigdecimal/math.rb: E implemented.\n\nTue Aug 19 07:47:09 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/ssl.rb: new file; SSL/TLS enhancement for GenericServer.\n\n\t* lib/webrick/https.rb: SSLSocket handling is moved to webrick/ssl.rb.\n\n\t* lib/webrick/compat.rb (File::fnmatch): remove old migration code.\n\n\t* lib/webrick/httpserver.rb (HTTPServer#run): ditto.\n\n\t* lib/webrick/server.rb (GenericServer#listen): the body of this\n\t  method is pull out as Utils::create_lisnteners.\n\n\t* lib/webrick/utils.rb (Utils::create_lisnteners): new method.\n\n\t* lib/webrick/server.rb (GenericServer#start): should rescue\n\t  unknown errors. and refine comments.\n\n\t* ext/openssl/lib/openssl/ssl.rb (SSLServer#accept): should close\n\t  socket if SSLSocket raises error.\n\nTue Aug 19 11:19:33 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* io.c (next_argv): should not call GetOpenFile() if rb_stdout is\n\t  not a IO (T_FILE).\n\nTue Aug 19 07:47:09 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c: sync_close is moved to SSLSocket as\n\t  a builtin.\n\n\t* ext/openssl/lib/openssl/buffering.rb (Buffering#close): ditto.\n\n\t* ext/openssl/lib/openssl/buffering.rb (Buffering#puts): should\n\t  add a return to the tails of each line.\n\n\t* ext/openssl/lib/openssl/ssl.rb: new class OpenSSL::SSL::SSLServer.\n\n\t* ext/openssl/lib/net/protocols.rb (SSLIO#ssl_connect): use sync_close.\n\n\t* ext/openssl/sample/echo_svr.rb: use SSLServer.\n\n\t* ext/openssl/sample/echo_cli.rb: add example of SSLSocket#sync_close.\n\nTue Aug 19 01:24:34 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/curses/curses.c (_XOPEN_SOURCE_EXTENDED): Mac OS X standard\n\t  headers are inconsistent at this macro.  [ruby-core:01432]\n\n\t* ext/curses/extconf.rb: check if _XOPEN_SOURCE_EXTENDED breaks.\n\n\t* ext/tcltklib/stubs.c: Status macro in X11/Xthreads.h bothers\n\t  winspool.h\n\n\t* instruby.rb: make list at first instead of iterator.\n\t  [ruby-talk:79347]\n\nMon Aug 18 11:23:11 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* dir.c (glob_helper): preserve raw order for **.\n\nSun Aug 17 23:39:55 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/openssl/extconf.rb (HAVE_VA_ARGS_MACRO): need to compile.\n\nSun Aug 17 17:10:03 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/ssl.rb (SSLSocket#sync_close=): add a\n\t  method to specify if the underlying IO will be closed in\n\t  SSLSocket#close.\n\n\t* ext/openssl/lib/openssl/buffering.rb: add forwarders to\n\t  setsockopt, getsockopt and fcntl.\n\n\t* ext/openssl/lib/net/protocols.rb: enable sync for SSLSocket.\n\nSun Aug 17 11:32:04 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): should not force to remake Makefile when\n\t  installation and so on.\n\nSat Aug 16 23:58:18 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* marshal.c (w_symbol, w_object): get rid of warnings.\n\n\t* re.c (rb_memsearch): ditto.\n\n\t* time.c (time_dump): ditto.\n\n\t* ext/extmk.rb (extmake): not continue making when extconf.rb\n\t  failed.\n\n\t* ext/openssl/extconf.rb: check __VA_ARGS__ macro more precisely.\n\n\t* ext/openssl/ossl.h: remove version.h dependency.\n\n\t* ext/openssl/ruby_missing.h: ditto.\n\n\t* lib/mkmf.rb (pkg_config): use --libs output except with\n\t  only-L for other options.  [ruby-list:38099]\n\n\t* lib/mkmf.rb (create_makefile): separate rule for static\n\t  library from shared object.\n\n\t* win32/Makefile.sub, bcc32/Makefile.sub, wince/Makefile.sub:\n\t  define exec_prefix and libdir.\n\nFri Aug 15 23:15:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c .h: Bug in combination of limit & div\n\t  method fixed.\n\n\t* ext/bigdecimal/lib/bigdecimal/math.rb: atan() & sqrt() added.\n\nFri Aug 15 12:01:43 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* configure.in (HUGE_ST_INO): check whether struct stat.st_ino\n\t  is larger than long.  [ruby-dev:21194]\n\t  http://www.geocities.co.jp/SiliconValley-PaloAlto/1409/ruby/beos.html\n\n\t* error.c (syserr_eqq): errno might exceed Fixnum limit.\n\n\t* error.c (Init_Exception): moved base initialization from\n\t  init_syserr().\n\n\t* inits.c (rb_call_inits): postpone initializing errnos until\n\t  Bignum is available.\n\nFri Aug 15 12:01:43 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/curses/curses.c (_XOPEN_SOURCE_EXTENDED): needed to let\n\t  keyname() and so on be declared.\n\n\t* ext/curses/curses.c (curses_resizeterm, window_resize):\n\t  arguments conflicted with macros in term.h.\n\n\t* ext/curses/curses.c (Curses module methods): ensure\n\t  initialized.  [ruby-dev:21191]\n\nFri Aug 15 02:08:53 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (id2ref): recycle check should be done by klass == 0.\n\t  [ruby-core:01408]\n\nFri Aug 15 01:34:23 2003  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* ext/openssl/ossl_pkey.c: move generate_cb here\n\n\t* ext/openssl/ossl_pkey_{dh|dsa|rsa}.c: adapt to this cb\n\n\t* ext/openssl/openssl_missing.[ch]: add (0.9.6x, x<j) missing BN funcs\n\n\t* ext/openssl/ossl_bn.c: use supplied funcs from openssl_missing.c\n\nFri Aug 15 00:38:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c: Bug in div method fixed.\n\n\t* ext/bigdecimal/lib/bigdecimal/math.rb: Newly added.\n\n\t* ext/bigdecimal/sample/pi.rb: Changed so as to use math.rb.\n\nThu Aug 14 21:19:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (Init_Thread): Continuation#[] added.  [ruby-talk:79028]\n\nThu Aug 14 20:03:34 2003  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/win32ole.c (OLE_FREE): should not call\n\t  ole_message_loop.\n\n\t* ext/win32ole/win32ole.c (ole_event_free): ditto.\n\n\t* ext/win32ole/win32ole.c (ole_initialize): stop calling\n\t  OleUninitialize at exit.\n\nThu Aug 14 11:27:37 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* gc.c (rb_data_object_alloc): check type of 1st argument.\n\t  [ruby-dev:21192]\n\nThu Aug 14 00:21:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (mlhs_node): should allow \"::Foo\" (colon3) as lhs.\n\n\t* parse.y (lhs): ditto.\n\n\t* parse.y (yylex): should return tCOLON3 right after kCLASS.\n\t  [ruby-talk:78918]\n\n\t* error.c (exc_initialize): was converting argument to string too\n\t  eagerly.  Only check was needed. [ruby-talk:78958]\n\nWed Aug 13 23:31:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal/bigdecimal.c .h .html: Ambiguity of\n\t  BigDecimal::limit removed.\n\nWed Aug 13 19:21:34 2003  Christian Neukirchen  <chneukirchen@yahoo.de>\n\n\t* lib/webrick/https.rb (HTTPServer#run): should set syncing-mode\n\t  to SSLSocket. [ruby-talk:78919]\n\nWed Aug 13 18:13:49 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (POP_BLOCK): turn on BLOCK_LEFT flag when leaving block.\n\n\t* eval.c (proc_invoke): unpack return/break destination when block\n\t  is already left.\n\nWed Aug 13 15:58:31 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* object.c (rb_class_s_alloc): add function prototype to avoid VC++\n\t  warning.\n\nWed Aug 13 13:50:59 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): should pass some\n\t  class to first argument of Data_Wrap_Struct(). (ruby-bugs:PR#1109)\n\nTue Aug 12 16:55:11 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* Makefile.in: static link libraries to LIBRUBY_SO with static linked\n\t  ext.  [ruby-dev:21157]\n\n\t* ext/extmk.rb (extmake): sort extension library initialization order.\n\n\t* ext/extmk.rb (extmake): compact $extlibs.\n\nTue Aug 12 02:48:56 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (THREAD_SAVE_CONTEXT): should explicitly turn off the\n\t  flag before calling getcontext(2).\n\n\t* eval.c (struct thread): add member to save backing store on\n\t  IA64. (ruby-bugs PR1086)\n\n\t* eval.c (thread_mark): mark IA64 backing store region.\n\n\t* eval.c (thread_free): free saved IA64 backing store.\n\n\t* eval.c (rb_thread_save_context): save IA64 backing store as well.\n\n\t* eval.c (rb_thread_restore_context): restore IA64 backing store.\n\n\t* eval.c (THREAD_ALLOC): initialize IA64 members.\n\nMon Aug 11 22:31:50 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/debug.rb(debug_command): inspection command should inspect\n\t  resulting value even if it's nil.  [ruby-dev:21180] by OMAE, jun\n\t  <jun66j5@ybb.ne.jp>.\n\n\t* lib/debug.rb(debug_command): incomplete regexp.\n\nMon Aug 11 17:33:07 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call_super): do not use rb_block_given_p() for\n\t  check. [ruby-talk:78656]\n\n\t* eval.c (BEGIN_CALLARGS): push ITER_NOT only when ITER_PRE.\n\nSun Aug 10 10:43:05 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/openssl/buffering.rb: increase BLOCK_SIZE\n\t  from 1k to 16k bytes. [ruby-talk:78603]\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_s_alloc): enable\n\t  partial write to allow interruption in SSLSocket#write.\n\nSun Aug 10 00:34:16 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* cygwin/GNUmakefile: remove unnecessary '--drive-name=$(CC)'\n\t  for ccache.\n\nSat Aug  9 10:36:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): do not dump generic instance variable when\n\t  marshal_dump is defined.\n\nSat Aug  9 00:35:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal.c: F style output(like 1234.56789) implemented\n\t  to to_s method.\n\t* ext/bigdecimal_??.html: F style output(like 1234.56789)\n\t  implemented to to_s method.\n\nFri Aug  8 12:33:17 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* bcc32/Makefile.sub: rubyw.exe should be a Windows GUI program.\n\t  add the -aa option to WLDFLAGS.\n\nFri Aug  8 11:29:26 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* marshal.c (w_object): should set `c_arg' at first.\n\nFri Aug  8 03:22:28 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/httputils.rb (FormData#list): should not take\n\t  a side effect for the receiver.\n\nThu Aug  7 14:40:37 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* cygwin/GNUmakefile: better --disbale-shared option support.\n\n\t* cygwin/GNUmakefile: add forwarding DLL target for cygwin.\n\nThu Aug  7 14:21:05 2003  Corinna Vinschen  <vinschen@redhat.com>\n\n\t* configure.in: Fix Cygwin specific naming of libraries to\n\t  be net distribution compliant. (ruby-bugs:PR#1077)\n\t  cygwin-ruby18.dll -> cygruby18.dll\n\nThu Aug  7 12:51:38 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_at_exit): should not be called without a block.\n\t  block_given check added.\n\nThu Aug  7 06:46:06 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): forgot to pop ruby_class.\n\n\t* eval.c (rb_call0): update ruby_class as well as ruby_cref.\n\t  (ruby-bugs-ja:PR#540)\n\nThu Aug  7 04:52:50 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): remove ruby_frame->cbase and unify to\n\t  ruby_cref.  [ruby-talk:78141]\n\nThu Aug  7 04:19:15 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* gc.c: FreeBSD/ia64's mcontext_t is a bit different from that of\n\t  Linux/ia64.  This makes gc.c compile but miniruby coredumps for\n\t  the moment.\n\nThu Aug  7 00:15:00 2003  Shigeo Kobayashi  <shigek@ruby-lang.org>\n\n\t* ext/bigdecimal.c: Comparison results adjusted to Float's.\n\t* ext/bigdecimal.c: Use rb_num_coerce_????(x,y) instead of own.\n\nWed Aug  6 22:58:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/testcase.rb: Added equality checking.\n\t* lib/test/unit/testsuite.rb: Added equality checking.\n\t* lib/test/unit/assertions.rb: Fixed a warning.\n\nWed Aug  6 17:28:10 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): pass LIBPATH to make ruby.  [ruby-dev:21137]\n\n\t* ext/extmk.rb (extmake): set library name as source file name in\n\t  Init_ext().  [ruby-dev:21137]\n\n\t* lib/mkmf.rb (Logging::postpone): postpone logging messages after\n\t  heading message as the result of the block.\n\n\t* lib/mkmf.rb (macro_defined?): append newline to src unless ended\n\t  with it.\n\n\t* lib/mkmf.rb (have_library): treat nil function name as \"main\".\n\t  (ruby-bugs:PR#1083)\n\n\t* lib/mkmf.rb (pkg_config): should append additional libraries to\n\t  $libs but not $LIBS.  [ruby-dev:21137]\n\n\t* ext/io/wait/extconf.rb: check DOSISH macro instead of platform.\n\n\t* ext/digest/sha1/extconf.rb: have_library already appends library\n\t  name.\n\nWed Aug  6 17:23:57 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c: initialize /* OK */ variables by Qnil to stop warnings.\n\nWed Aug  6 04:58:32 2003  NAKAMURA Usaku  <usa@ruby-lang.org>\n\n\t* ext/Setup*: add io/wait and openssl.\n\nWed Aug  6 01:13:38 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_autoload): use ruby_cbase instead of ruby_class.\n\n\t* eval.c (rb_f_autoload_p): ditto.\n\n\t* class.c (rb_mod_init_copy): no longer implements independent\n\t  clone and dup methods.  override \"initialize_copy\" instead.\n\t  [ruby-core:01352]\n\n\t* object.c (rb_class_s_alloc): define Class allocation function.\n\t  this makes Classes to follow clone framework that uses\n\t  initialize_copy.\n\n\t* object.c (rb_class_initialize): separate instantiation and\n\t  initialization.\n\n\t* object.c (rb_obj_alloc): prohibit instantiation from\n\t  uninitialized class.\n\n\t* object.c (rb_class_superclass): check uninitialized class.\n\n\t* array.c (rb_ary_fill): wrong index processing with block.  this\n\t  fix was done by Koji Arai <JCA02266@nifty.ne.jp> [ruby-list:38029]\n\n\t* marshal.c (w_object): should preserve generic ivar for nil,\n\t  true, false, symbols, and fixnums.\n\n\t* marshal.c (w_uclass): base_klass check should be done after\n\t  rb_class_real().\n\nWed Aug  6 01:18:50 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: update document.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/protocol.rb: ditto.\n\nWed Aug  6 00:48:37 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* marshal.c (w_object): should recommend marshal_dump rather than\n\t  _dump_data.\n\nTue Aug  5 17:58:57 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils.rb (install): should preserve timestamp only.\n\nTue Aug  5 17:31:59 2003  Ian Macdonald  <ian@caliban.org>\n\n\t* lib/shell/command-processor.rb (Shell::CommandProcessor::rmdir):\n\t  simple typo.\n\nTue Aug  5 15:47:34 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_load): should preserve current source file/line.\n\nTue Aug  5 10:04:42 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_new4): ptr may refer null_str.\n\nMon Aug  4 17:25:18 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.8.0 released.\n\nFor the changes before 1.8.0, see doc/ChangeLog-1.8.0\n\nLocal variables:\nadd-log-time-format: (lambda ()\n  (let* ((time (current-time))\n\t (system-time-locale \"C\")\n\t (diff (+ (cadr time) 32400))\n\t (lo (% diff 65536))\n\t (hi (+ (car time) (/ diff 65536))))\n  (format-time-string \"%a %b %e %H:%M:%S %Y\" (list hi lo) t)))\nindent-tabs-mode: t\ntab-width: 8\nend:\n"
  },
  {
    "path": "GPL",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\f\n\t\t    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\f\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\f\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\f\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\f\n\t    How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n"
  },
  {
    "path": "LEGAL",
    "content": "LEGAL NOTICE INFORMATION\n------------------------\n\nAll the files in this distribution are covered under either the Ruby's\nlicense (see the file COPYING) or public-domain except some files\nmentioned below.\n\nregex.[ch]:\n\n  These files are under LGPL.  Treat them as LGPL says. (See the file\n  LGPL for details)\n\n    Extended regular expression matching and search library.\n    Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc.\n\n    The GNU C Library is free software; you can redistribute it and/or\n    modify it under the terms of the GNU Library General Public License as\n    published by the Free Software Foundation; either version 2 of the\n    License, or (at your option) any later version.\n\n    The GNU C Library is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n    Library General Public License for more details.\n\n    You should have received a copy of the GNU Library General Public\n    License along with the GNU C Library; see the file LGPL.  If not,\n    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n    Boston, MA 02111-1307, USA.  */\n\n    Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)\n    Last change: May 21, 1993 by t^2\n    removed gapped buffer support, multiple syntax support by matz <matz@nts.co.jp>\n    Perl5 extension added by matz <matz@caelum.co.jp>\n    UTF-8 extension added Jan 16 1999 by Yoshida Masato  <yoshidam@tau.bekkoame.ne.jp>\n\nconfigure:\n\n  This file is free software.\n\n    Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.\n\n    This configure script is free software; the Free Software Foundation\n    gives unlimited permission to copy, distribute and modify it.\n\nconfig.guess:\nconfig.sub:\nparse.c:\n\n  As long as you distribute these files with the file configure, they\n  are covered under the Ruby's license.\n\n      Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999\n      Free Software Foundation, Inc.\n\n    This file is free software; you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful, but\n    WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n    General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n\n    As a special exception to the GNU General Public License, if you\n    distribute this file as part of a program that contains a\n    configuration script generated by Autoconf, you may include it under\n    the same distribution terms that you use for the rest of that program.\n\nutil.c (partly):\nwin32/win32.[ch]:\n\n  You can apply the Artistic License to these files. (or GPL,\n  alternatively)\n\n    Copyright (c) 1993, Intergraph Corporation\n\n    You may distribute under the terms of either the GNU General Public\n    License or the Artistic License, as specified in the perl README file.\n\nrandom.c\n\n  This file is under the new-style BSD license.\n\n    A C-program for MT19937, with initialization improved 2002/2/10.\n    Coded by Takuji Nishimura and Makoto Matsumoto.\n    This is a faster version by taking Shawn Cokus's optimization,\n    Matthe Bellew's simplification, Isaku Wada's real version.\n\n    Before using, initialize the state by using init_genrand(seed) \n    or init_by_array(init_key, key_length).\n\n    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n    All rights reserved.                          \n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions\n    are met:\n\n      1. Redistributions of source code must retain the above copyright\n\t notice, this list of conditions and the following disclaimer.\n\n      2. Redistributions in binary form must reproduce the above copyright\n\t notice, this list of conditions and the following disclaimer in the\n\t documentation and/or other materials provided with the distribution.\n\n      3. The names of its contributors may not be used to endorse or promote \n\t products derived from this software without specific prior written \n\t permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n    \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n    Any feedback is very welcome.\n    http://www.math.keio.ac.jp/matumoto/emt.html\n    email: matumoto@math.keio.ac.jp\n\nst.[ch]:\nx68/*:\nmissing/alloca.c:\nmissing/dup2.c:\nmissing/finite.c:\nmissing/hypot.c:\nmissing/isinf.c:\nmissing/isnan.c:\nmissing/memcmp.c:\nmissing/memmove.c:\nmissing/strcasecmp.c:\nmissing/strchr.c:\nmissing/streror.c:\nmissing/strftime.c:\nmissing/strncasecmp.c:\nmissing/strstr.c:\nmissing/strtol.c:\next/digest/sha1/sha1.[ch]:\n\n  These files are all under public domain.\n\nmissing/strtod.c:\n\n  This file will not be used on most platforms depending on how the\n  configure script results.  In any case you must not receive any fee\n  with the file itself.\n\n    Copyright (c) 1988-1993 The Regents of the University of California.\n    Copyright (c) 1994 Sun Microsystems, Inc.\n\n    Permission to use, copy, modify, and distribute this\n    software and its documentation for any purpose and without\n    fee is hereby granted, provided that the above copyright\n    notice appear in all copies.  The University of California\n    makes no representations about the suitability of this\n    software for any purpose.  It is provided \"as is\" without\n    express or implied warranty.\n\nmissing/strtoul.c:\n\n  This file will not be used on most platforms depending on how the\n  configure script results.  In any case you must not receive any fee\n  with the file itself.\n\n    Copyright 1988 Regents of the University of California\n\n    Permission to use, copy, modify, and distribute this\n    software and its documentation for any purpose and without\n    fee is hereby granted, provided that the above copyright\n    notice appear in all copies.  The University of California\n    makes no representations about the suitability of this\n    software for any purpose.  It is provided \"as is\" without\n    express or implied warranty.\n\nmissing/erf.c:\nmissing/crypt.c:\nmissing/vsnprintf.c:\n\n  This file is under the old-style BSD license.  Note that the\n  paragraph 3 below is now null and void.\n\n    Copyright (c) 1990, 1993\n         The Regents of the University of California.  All rights reserved.\n\n    This code is derived from software contributed to Berkeley by\n    Chris Torek.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions\n    are met:\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n    3. Neither the name of the University nor the names of its contributors\n       may be used to endorse or promote products derived from this software\n       without specific prior written permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n    ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n    SUCH DAMAGE.\n\n    IMPORTANT NOTE:\n    --------------\n    From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change\n    paragraph 3 above is now null and void.\n\next/digest/md5/md5.[ch]:\n\n  These files are under the following license.  Ruby uses modified\n  versions of them.\n\n    Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.\n\n    This software is provided 'as-is', without any express or implied\n    warranty.  In no event will the authors be held liable for any damages\n    arising from the use of this software.\n\n    Permission is granted to anyone to use this software for any purpose,\n    including commercial applications, and to alter it and redistribute it\n    freely, subject to the following restrictions:\n\n    1. The origin of this software must not be misrepresented; you must not\n       claim that you wrote the original software. If you use this software\n       in a product, an acknowledgment in the product documentation would be\n       appreciated but is not required.\n    2. Altered source versions must be plainly marked as such, and must not be\n       misrepresented as being the original software.\n    3. This notice may not be removed or altered from any source distribution.\n\n    L. Peter Deutsch\n    ghost@aladdin.com\n\next/digest/rmd160/rmd160.[ch]:\n\n  These files have the following copyright information, and by the\n  author we are allowed to use it under the new-style BSD license.\n\n    AUTHOR:   Antoon Bosselaers, ESAT-COSIC\n              (Arranged for libc by Todd C. Miller)\n    DATE:     1 March 1996\n\n    Copyright (c) Katholieke Universiteit Leuven\n    1996, All Rights Reserved\n\next/digest/rmd160/rmd160hl.c:\next/digest/sha1/sha1hl.c:\n\n  These files are under the beer-ware license.\n\n    \"THE BEER-WARE LICENSE\" (Revision 42):\n    <phk@login.dkuug.dk> wrote this file.  As long as you retain this notice you\n    can do whatever you want with this stuff. If we meet some day, and you think\n    this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp\n\next/digest/sha2/sha2.[ch]:\next/digest/sha2/sha2hl.c:\n\n  These files are under the new-style BSD license.\n\n    Copyright 2000 Aaron D. Gifford.  All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions\n    are met:\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n    3. Neither the name of the copyright holder nor the names of contributors\n       may be used to endorse or promote products derived from this software\n       without specific prior written permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND\n    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE\n    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n    SUCH DAMAGE.\n\next/nkf/nkf-utf8/config.h:\next/nkf/nkf-utf8/nkf.c:\next/nkf/nkf-utf8/utf8tbl.c:\n\n  These files are under the following license.  So to speak, it is\n  copyrighted semi-public-domain software.\n\n    Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)\n       Everyone is permitted to do anything on this program \n       including copying, modifying, improving,\n       as long as you don't try to pretend that you wrote it.\n       i.e., the above copyright notice has to appear in all copies.\n       Binary distribution requires original version messages.\n       You don't have to ask before copying, redistribution or publishing.\n       THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.\n\next/socket/addrinfo.h:\next/socket/getaddrinfo.c:\next/socket/getnameinfo.c:\n\n  These files are under the new-style BSD license.\n\n    Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions\n    are met:\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in the\n       documentation and/or other materials provided with the distribution.\n    3. Neither the name of the project nor the names of its contributors\n       may be used to endorse or promote products derived from this software\n       without specific prior written permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\n    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n    ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\n    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n    SUCH DAMAGE.\n\next/win32ole/win32ole.c:\n\n  You can apply the Artistic License to this file. (or GPL,\n  alternatively)\n\n    (c) 1995 Microsoft Corporation. All rights reserved.\n    Developed by ActiveWare Internet Corp., http://www.ActiveWare.com\n\n    Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy\n    <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>\n \n    You may distribute under the terms of either the GNU General Public\n    License or the Artistic License, as specified in the README file\n    of the Perl distribution.\n"
  },
  {
    "path": "LGPL",
    "content": "\t\t  GNU LESSER GENERAL PUBLIC LICENSE\n\t\t       Version 2.1, February 1999\n\n Copyright (C) 1991, 1999 Free Software Foundation, Inc.\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n[This is the first released version of the Lesser GPL.  It also counts\n as the successor of the GNU Library Public License, version 2, hence\n the version number 2.1.]\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicenses are intended to guarantee your freedom to share and change\nfree software--to make sure the software is free for all its users.\n\n  This license, the Lesser General Public License, applies to some\nspecially designated software packages--typically libraries--of the\nFree Software Foundation and other authors who decide to use it.  You\ncan use it too, but we suggest you first think carefully about whether\nthis license or the ordinary General Public License is the better\nstrategy to use in any particular case, based on the explanations below.\n\n  When we speak of free software, we are referring to freedom of use,\nnot price.  Our General Public Licenses are designed to make sure that\nyou have the freedom to distribute copies of free software (and charge\nfor this service if you wish); that you receive source code or can get\nit if you want it; that you can change the software and use pieces of\nit in new free programs; and that you are informed that you can do\nthese things.\n\n  To protect your rights, we need to make restrictions that forbid\ndistributors to deny you these rights or to ask you to surrender these\nrights.  These restrictions translate to certain responsibilities for\nyou if you distribute copies of the library or if you modify it.\n\n  For example, if you distribute copies of the library, whether gratis\nor for a fee, you must give the recipients all the rights that we gave\nyou.  You must make sure that they, too, receive or can get the source\ncode.  If you link other code with the library, you must provide\ncomplete object files to the recipients, so that they can relink them\nwith the library after making changes to the library and recompiling\nit.  And you must show them these terms so they know their rights.\n\n  We protect your rights with a two-step method: (1) we copyright the\nlibrary, and (2) we offer you this license, which gives you legal\npermission to copy, distribute and/or modify the library.\n\n  To protect each distributor, we want to make it very clear that\nthere is no warranty for the free library.  Also, if the library is\nmodified by someone else and passed on, the recipients should know\nthat what they have is not the original version, so that the original\nauthor's reputation will not be affected by problems that might be\nintroduced by others.\n\f\n  Finally, software patents pose a constant threat to the existence of\nany free program.  We wish to make sure that a company cannot\neffectively restrict the users of a free program by obtaining a\nrestrictive license from a patent holder.  Therefore, we insist that\nany patent license obtained for a version of the library must be\nconsistent with the full freedom of use specified in this license.\n\n  Most GNU software, including some libraries, is covered by the\nordinary GNU General Public License.  This license, the GNU Lesser\nGeneral Public License, applies to certain designated libraries, and\nis quite different from the ordinary General Public License.  We use\nthis license for certain libraries in order to permit linking those\nlibraries into non-free programs.\n\n  When a program is linked with a library, whether statically or using\na shared library, the combination of the two is legally speaking a\ncombined work, a derivative of the original library.  The ordinary\nGeneral Public License therefore permits such linking only if the\nentire combination fits its criteria of freedom.  The Lesser General\nPublic License permits more lax criteria for linking other code with\nthe library.\n\n  We call this license the \"Lesser\" General Public License because it\ndoes Less to protect the user's freedom than the ordinary General\nPublic License.  It also provides other free software developers Less\nof an advantage over competing non-free programs.  These disadvantages\nare the reason we use the ordinary General Public License for many\nlibraries.  However, the Lesser license provides advantages in certain\nspecial circumstances.\n\n  For example, on rare occasions, there may be a special need to\nencourage the widest possible use of a certain library, so that it becomes\na de-facto standard.  To achieve this, non-free programs must be\nallowed to use the library.  A more frequent case is that a free\nlibrary does the same job as widely used non-free libraries.  In this\ncase, there is little to gain by limiting the free library to free\nsoftware only, so we use the Lesser General Public License.\n\n  In other cases, permission to use a particular library in non-free\nprograms enables a greater number of people to use a large body of\nfree software.  For example, permission to use the GNU C Library in\nnon-free programs enables many more people to use the whole GNU\noperating system, as well as its variant, the GNU/Linux operating\nsystem.\n\n  Although the Lesser General Public License is Less protective of the\nusers' freedom, it does ensure that the user of a program that is\nlinked with the Library has the freedom and the wherewithal to run\nthat program using a modified version of the Library.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.  Pay close attention to the difference between a\n\"work based on the library\" and a \"work that uses the library\".  The\nformer contains code derived from the library, whereas the latter must\nbe combined with the library in order to run.\n\f\n\t\t  GNU LESSER GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License Agreement applies to any software library or other\nprogram which contains a notice placed by the copyright holder or\nother authorized party saying it may be distributed under the terms of\nthis Lesser General Public License (also called \"this License\").\nEach licensee is addressed as \"you\".\n\n  A \"library\" means a collection of software functions and/or data\nprepared so as to be conveniently linked with application programs\n(which use some of those functions and data) to form executables.\n\n  The \"Library\", below, refers to any such software library or work\nwhich has been distributed under these terms.  A \"work based on the\nLibrary\" means either the Library or any derivative work under\ncopyright law: that is to say, a work containing the Library or a\nportion of it, either verbatim or with modifications and/or translated\nstraightforwardly into another language.  (Hereinafter, translation is\nincluded without limitation in the term \"modification\".)\n\n  \"Source code\" for a work means the preferred form of the work for\nmaking modifications to it.  For a library, complete source code means\nall the source code for all modules it contains, plus any associated\ninterface definition files, plus the scripts used to control compilation\nand installation of the library.\n\n  Activities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning a program using the Library is not restricted, and output from\nsuch a program is covered only if its contents constitute a work based\non the Library (independent of the use of the Library in a tool for\nwriting it).  Whether that is true depends on what the Library does\nand what the program that uses the Library does.\n  \n  1. You may copy and distribute verbatim copies of the Library's\ncomplete source code as you receive it, in any medium, provided that\nyou conspicuously and appropriately publish on each copy an\nappropriate copyright notice and disclaimer of warranty; keep intact\nall the notices that refer to this License and to the absence of any\nwarranty; and distribute a copy of this License along with the\nLibrary.\n\n  You may charge a fee for the physical act of transferring a copy,\nand you may at your option offer warranty protection in exchange for a\nfee.\n\f\n  2. You may modify your copy or copies of the Library or any portion\nof it, thus forming a work based on the Library, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) The modified work must itself be a software library.\n\n    b) You must cause the files modified to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    c) You must cause the whole of the work to be licensed at no\n    charge to all third parties under the terms of this License.\n\n    d) If a facility in the modified Library refers to a function or a\n    table of data to be supplied by an application program that uses\n    the facility, other than as an argument passed when the facility\n    is invoked, then you must make a good faith effort to ensure that,\n    in the event an application does not supply such function or\n    table, the facility still operates, and performs whatever part of\n    its purpose remains meaningful.\n\n    (For example, a function in a library to compute square roots has\n    a purpose that is entirely well-defined independent of the\n    application.  Therefore, Subsection 2d requires that any\n    application-supplied function or table used by this function must\n    be optional: if the application does not supply it, the square\n    root function must still compute square roots.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Library,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Library, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote\nit.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Library.\n\nIn addition, mere aggregation of another work not based on the Library\nwith the Library (or with a work based on the Library) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may opt to apply the terms of the ordinary GNU General Public\nLicense instead of this License to a given copy of the Library.  To do\nthis, you must alter all the notices that refer to this License, so\nthat they refer to the ordinary GNU General Public License, version 2,\ninstead of to this License.  (If a newer version than version 2 of the\nordinary GNU General Public License has appeared, then you can specify\nthat version instead if you wish.)  Do not make any other change in\nthese notices.\n\f\n  Once this change is made in a given copy, it is irreversible for\nthat copy, so the ordinary GNU General Public License applies to all\nsubsequent copies and derivative works made from that copy.\n\n  This option is useful when you wish to copy part of the code of\nthe Library into a program that is not a library.\n\n  4. You may copy and distribute the Library (or a portion or\nderivative of it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you accompany\nit with the complete corresponding machine-readable source code, which\nmust be distributed under the terms of Sections 1 and 2 above on a\nmedium customarily used for software interchange.\n\n  If distribution of object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the\nsource code from the same place satisfies the requirement to\ndistribute the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  5. A program that contains no derivative of any portion of the\nLibrary, but is designed to work with the Library by being compiled or\nlinked with it, is called a \"work that uses the Library\".  Such a\nwork, in isolation, is not a derivative work of the Library, and\ntherefore falls outside the scope of this License.\n\n  However, linking a \"work that uses the Library\" with the Library\ncreates an executable that is a derivative of the Library (because it\ncontains portions of the Library), rather than a \"work that uses the\nlibrary\".  The executable is therefore covered by this License.\nSection 6 states terms for distribution of such executables.\n\n  When a \"work that uses the Library\" uses material from a header file\nthat is part of the Library, the object code for the work may be a\nderivative work of the Library even though the source code is not.\nWhether this is true is especially significant if the work can be\nlinked without the Library, or if the work is itself a library.  The\nthreshold for this to be true is not precisely defined by law.\n\n  If such an object file uses only numerical parameters, data\nstructure layouts and accessors, and small macros and small inline\nfunctions (ten lines or less in length), then the use of the object\nfile is unrestricted, regardless of whether it is legally a derivative\nwork.  (Executables containing this object code plus portions of the\nLibrary will still fall under Section 6.)\n\n  Otherwise, if the work is a derivative of the Library, you may\ndistribute the object code for the work under the terms of Section 6.\nAny executables containing that work also fall under Section 6,\nwhether or not they are linked directly with the Library itself.\n\f\n  6. As an exception to the Sections above, you may also combine or\nlink a \"work that uses the Library\" with the Library to produce a\nwork containing portions of the Library, and distribute that work\nunder terms of your choice, provided that the terms permit\nmodification of the work for the customer's own use and reverse\nengineering for debugging such modifications.\n\n  You must give prominent notice with each copy of the work that the\nLibrary is used in it and that the Library and its use are covered by\nthis License.  You must supply a copy of this License.  If the work\nduring execution displays copyright notices, you must include the\ncopyright notice for the Library among them, as well as a reference\ndirecting the user to the copy of this License.  Also, you must do one\nof these things:\n\n    a) Accompany the work with the complete corresponding\n    machine-readable source code for the Library including whatever\n    changes were used in the work (which must be distributed under\n    Sections 1 and 2 above); and, if the work is an executable linked\n    with the Library, with the complete machine-readable \"work that\n    uses the Library\", as object code and/or source code, so that the\n    user can modify the Library and then relink to produce a modified\n    executable containing the modified Library.  (It is understood\n    that the user who changes the contents of definitions files in the\n    Library will not necessarily be able to recompile the application\n    to use the modified definitions.)\n\n    b) Use a suitable shared library mechanism for linking with the\n    Library.  A suitable mechanism is one that (1) uses at run time a\n    copy of the library already present on the user's computer system,\n    rather than copying library functions into the executable, and (2)\n    will operate properly with a modified version of the library, if\n    the user installs one, as long as the modified version is\n    interface-compatible with the version that the work was made with.\n\n    c) Accompany the work with a written offer, valid for at\n    least three years, to give the same user the materials\n    specified in Subsection 6a, above, for a charge no more\n    than the cost of performing this distribution.\n\n    d) If distribution of the work is made by offering access to copy\n    from a designated place, offer equivalent access to copy the above\n    specified materials from the same place.\n\n    e) Verify that the user has already received a copy of these\n    materials or that you have already sent this user a copy.\n\n  For an executable, the required form of the \"work that uses the\nLibrary\" must include any data and utility programs needed for\nreproducing the executable from it.  However, as a special exception,\nthe materials to be distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies\nthe executable.\n\n  It may happen that this requirement contradicts the license\nrestrictions of other proprietary libraries that do not normally\naccompany the operating system.  Such a contradiction means you cannot\nuse both them and the Library together in an executable that you\ndistribute.\n\f\n  7. You may place library facilities that are a work based on the\nLibrary side-by-side in a single library together with other library\nfacilities not covered by this License, and distribute such a combined\nlibrary, provided that the separate distribution of the work based on\nthe Library and of the other library facilities is otherwise\npermitted, and provided that you do these two things:\n\n    a) Accompany the combined library with a copy of the same work\n    based on the Library, uncombined with any other library\n    facilities.  This must be distributed under the terms of the\n    Sections above.\n\n    b) Give prominent notice with the combined library of the fact\n    that part of it is a work based on the Library, and explaining\n    where to find the accompanying uncombined form of the same work.\n\n  8. You may not copy, modify, sublicense, link with, or distribute\nthe Library except as expressly provided under this License.  Any\nattempt otherwise to copy, modify, sublicense, link with, or\ndistribute the Library is void, and will automatically terminate your\nrights under this License.  However, parties who have received copies,\nor rights, from you under this License will not have their licenses\nterminated so long as such parties remain in full compliance.\n\n  9. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Library or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Library (or any work based on the\nLibrary), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Library or works based on it.\n\n  10. Each time you redistribute the Library (or any work based on the\nLibrary), the recipient automatically receives a license from the\noriginal licensor to copy, distribute, link with or modify the Library\nsubject to these terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties with\nthis License.\n\f\n  11. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Library at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Library by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Library.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply,\nand the section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  12. If the distribution and/or use of the Library is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Library under this License may add\nan explicit geographical distribution limitation excluding those countries,\nso that distribution is permitted only in or among countries not thus\nexcluded.  In such case, this License incorporates the limitation as if\nwritten in the body of this License.\n\n  13. The Free Software Foundation may publish revised and/or new\nversions of the Lesser General Public License from time to time.\nSuch new versions will be similar in spirit to the present version,\nbut may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Library\nspecifies a version number of this License which applies to it and\n\"any later version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation.  If the Library does not specify a\nlicense version number, you may choose any version ever published by\nthe Free Software Foundation.\n\f\n  14. If you wish to incorporate parts of the Library into other free\nprograms whose distribution conditions are incompatible with these,\nwrite to the author to ask for permission.  For software which is\ncopyrighted by the Free Software Foundation, write to the Free\nSoftware Foundation; we sometimes make exceptions for this.  Our\ndecision will be guided by the two goals of preserving the free status\nof all derivatives of our free software and of promoting the sharing\nand reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\f\n           How to Apply These Terms to Your New Libraries\n\n  If you develop a new library, and you want it to be of the greatest\npossible use to the public, we recommend making it free software that\neveryone can redistribute and change.  You can do so by permitting\nredistribution under these terms (or, alternatively, under the terms of the\nordinary General Public License).\n\n  To apply these terms, attach the following notices to the library.  It is\nsafest to attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least the\n\"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the library's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This library is free software; you can redistribute it and/or\n    modify it under the terms of the GNU Lesser General Public\n    License as published by the Free Software Foundation; either\n    version 2.1 of the License, or (at your option) any later version.\n\n    This library is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n    Lesser General Public License for more details.\n\n    You should have received a copy of the GNU Lesser General Public\n    License along with this library; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the library, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the\n  library `Frob' (a library for tweaking knobs) written by James Random Hacker.\n\n  <signature of Ty Coon>, 1 April 1990\n  Ty Coon, President of Vice\n\nThat's all there is to it!\n\n\n"
  },
  {
    "path": "Makefile.in",
    "content": "SHELL = /bin/sh\nNULLCMD = :\n\n#### Start of system configuration section. ####\n\nsrcdir = @srcdir@\nVPATH = $(srcdir):$(srcdir)/missing\n\nCC = @CC@\nYACC = @YACC@\nPURIFY =\nAUTOCONF = autoconf\n@SET_MAKE@\nMKFILES = @MAKEFILES@\n\nprefix = @prefix@\nexec_prefix = @exec_prefix@\nbindir = @bindir@\nsbindir = @sbindir@\nlibdir = @libdir@\nlibexecdir = @libexecdir@\ndatarootdir = @datarootdir@\ndatadir = @datadir@\narch = @arch@\nsitearch = @sitearch@\nsitedir = @sitedir@\n\nTESTUI = console\nTESTS =\nRDOCTARGET = @RDOCTARGET@\n\nEXTOUT = @EXTOUT@\nRIDATADIR = $(DESTDIR)$(datadir)/ri/$(MAJOR).$(MINOR)/system\n\nempty =\nOUTFLAG = @OUTFLAG@$(empty)\nCFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@\ncflags = @cflags@\noptflags = @optflags@\ndebugflags = @debugflags@\nCPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@\nLDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@\nEXTLDFLAGS = \nXLDFLAGS = @XLDFLAGS@ $(EXTLDFLAGS)\nEXTLIBS = \nLIBS = @LIBS@ $(EXTLIBS)\nMISSING = @LIBOBJS@ @ALLOCA@\nLDSHARED = @LIBRUBY_LDSHARED@\nDLDFLAGS = @LIBRUBY_DLDFLAGS@ $(EXTLDFLAGS) @ARCH_FLAG@\nSOLIBS = @SOLIBS@\nMAINLIBS = @MAINLIBS@\nMINIOBJS = @MINIOBJS@\n\nRUBY_INSTALL_NAME=@RUBY_INSTALL_NAME@\nRUBY_SO_NAME=@RUBY_SO_NAME@\nEXEEXT = @EXEEXT@\nPROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)\nRUBY = $(RUBY_INSTALL_NAME)\nMINIRUBY = @MINIRUBY@ $(MINIRUBYOPT)\nRUNRUBY = @RUNRUBY@ $(RUNRUBYOPT) --\n\n#### End of system configuration section. ####\n\nMAJOR=\t@MAJOR@\nMINOR=\t@MINOR@\nTEENY=\t@TEENY@\n\nLIBRUBY_A     = @LIBRUBY_A@\nLIBRUBY_SO    = @LIBRUBY_SO@\nLIBRUBY_ALIASES= @LIBRUBY_ALIASES@\nLIBRUBY\t      = @LIBRUBY@\nLIBRUBYARG    = @LIBRUBYARG@\nLIBRUBYARG_STATIC = @LIBRUBYARG_STATIC@\nLIBRUBYARG_SHARED = @LIBRUBYARG_SHARED@\n\nPREP          = @PREP@\nARCHFILE      = @ARCHFILE@\nSETUP         =\nEXTSTATIC     = @EXTSTATIC@\n\nRM            = rm -f\nNM            = @NM@\nAR            = @AR@\nARFLAGS       = rcu\nRANLIB        = @RANLIB@\nAS            = @AS@\nASFLAGS       = @ASFLAGS@\n\nOBJEXT        = @OBJEXT@\nMANTYPE\t      = @MANTYPE@\n\nINSTALLED_LIST= .installed.list\n#### End of variables\n\nall:\n\n.DEFAULT: all\n\n# Prevent GNU make v3 from overflowing arg limit on SysV.\n.NOEXPORT:\n\nminiruby$(EXEEXT):\n\t\t@$(RM) $@\n\t\t$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@\n\n$(PROGRAM):\n\t\t@$(RM) $@\n\t\t$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) $(OUTFLAG)$@\n\n# We must `rm' the library each time this rule is invoked because \"updating\" a\n# MAB library on Apple/NeXT (see --enable-fat-binary in configure) is not\n# supported.\n$(LIBRUBY_A):\n\t\t@$(RM) $@\n\t\t$(AR) $(ARFLAGS) $@ $(OBJS) $(DMYEXT)\n\t\t@-$(RANLIB) $@ 2> /dev/null || true\n\n$(LIBRUBY_SO):\n\t\t@-$(PRE_LIBRUBY_UPDATE)\n\t\t$(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(SOLIBS) $(OUTFLAG)$@\n\t\t@-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link if File.exist? link; \\\n\t\t\t\t\t\t  File.symlink \"$(LIBRUBY_SO)\", link}' \\\n\t\t\t\t$(LIBRUBY_ALIASES) || true\n\nfake.rb:\tMakefile\n\t\t@echo ' \\\n\t\tclass Object; \\\n\t\t  CROSS_COMPILING = RUBY_PLATFORM; \\\n\t\t  remove_const :RUBY_PLATFORM; \\\n\t\t  remove_const :RUBY_VERSION; \\\n\t\t  RUBY_PLATFORM = \"@arch@\"; \\\n\t\t  RUBY_VERSION = \"@MAJOR@.@MINOR@.@TEENY@\"; \\\n\t\tend; \\\n\t\tif RUBY_PLATFORM =~ /mswin|bccwin|mingw/; \\\n\t\t  class File; \\\n\t\t    remove_const :ALT_SEPARATOR; \\\n\t\t    ALT_SEPARATOR = \"\\\\\"; \\\n\t\t  end; \\\n\t\tend; \\\n\t\t' > $@\n\nMakefile:\t$(srcdir)/Makefile.in\n\n$(MKFILES): config.status $(srcdir)/common.mk\n\t\tMAKE=$(MAKE) $(SHELL) ./config.status\n\t\t@{ \\\n\t\t    echo \"all:; -@rm -f conftest.mk\"; \\\n\t\t    echo \"conftest.mk: .force; @echo AUTO_REMAKE\"; \\\n\t\t    echo \".force:\"; \\\n\t\t} > conftest.mk || exit 1; \\\n\t\t$(MAKE) -f conftest.mk | grep '^AUTO_REMAKE$$' >/dev/null 2>&1 || \\\n\t\t{ echo \"Makefile updated, restart.\"; exit 1; }\n\nconfig.status:\t$(srcdir)/configure\n\t\tMINIRUBY=\"$(MINIRUBY)\" $(SHELL) ./config.status --recheck\n\n$(srcdir)/configure: $(srcdir)/configure.in\n\t\tcd $(srcdir) && $(AUTOCONF)\n\nlex.c: keywords\n\t( gperf -C -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ $? > $@.tmp && mv $@.tmp $@ ) || \\\n\tif test -f $@; then \\\n\t  touch $@ && echo $@ touched.; \\\n\telse \\\n\t  cp $(srcdir)/lex.c $@ && echo $@ copied.; \\\n\tfi\n\n.y.c:\n\t$(YACC) $<\n\tsed '/^#/s|y\\.tab\\.c|$@|' y.tab.c > $@\n\trm -f y.tab.c\n\n.c.@OBJEXT@:\n\t$(CC) $(CFLAGS) $(CPPFLAGS) -c $<\n\n.s.@OBJEXT@:\n\t$(AS) $(ASFLAGS) -o $@ $<\n\nclean-local::\n\t@$(RM) ext/extinit.c ext/extinit.$(OBJEXT)\n\ndistclean-local::\n\t@$(RM) ext/config.cache $(RBCONFIG)\n\next/extinit.$(OBJEXT): ext/extinit.c $(SETUP)\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ -c ext/extinit.c\n\nupdate-rubyspec: \n\tif [ -d $(srcdir)/rubyspec ]; then \\\n\t  cd $(srcdir)/rubyspec/mspec; \\\n\t  git pull; \\\n\t  cd ../spec; \\\n\t  git pull; \\\n\telse \\\n\t  mkdir $(srcdir)/rubyspec; \\\n\t  git clone $(MSPEC_GIT_URL) $(srcdir)/rubyspec/mspec; \\\n\t  git clone $(RUBYSPEC_GIT_URL) $(srcdir)/rubyspec/spec; \\\n\tfi\n\ntest-rubyspec:\n\t@if [ ! -d $(srcdir)/rubyspec ]; then echo No rubyspec here.  make update-rubyspec first.; exit 1; fi\n\tRUBY_EXE=\"$(RUNRUBY)\" $(RUNRUBY) $(srcdir)/rubyspec/mspec/bin/mspec-run --background --prefix $(srcdir)/rubyspec/spec -B $(srcdir)/rubyspec/spec/ruby.$(MAJOR).$(MINOR).mspec\n"
  },
  {
    "path": "NEWS",
    "content": "= NEWS\n\nThis document is a list of user visible feature changes made between\nreleases except for bug fixes.\n\nNote that each entry is kept so brief that no reason behind or\nreference information is supplied with.  For a full list of changes\nwith all sufficient information, see the ChangeLog file.\n\n== Changes since the 1.8.7 release\n\n=== Lexical changes\n\n* empty symbol literal\n\n  Empty symbol (:\"\") is allowed.\n\n* looser splat opetator\n\n  You can write things like:\n    x, *y, z = a, *b, c\n    def foo(a, b=1, *c, d); end\n  But when you evaluate them, you will get exceptions.\n\n* new hash immediates\n\n  Ruby 1.9 style hash syntax e.g. { key: value } is now also supported\n  in 1.8.  You can also write a method invocation syntax foo bar: baz.\n\n=== Configuration changes\n\n* version specific directories\n\n  A new configure option --with-ruby-version is added, which allows\n  user to specify the version string (defaulted to \"1.8\") for version\n  specific directories such as library directories, ri directories and\n  gem directories.\n\n=== Library updates (outstanding ones only)\n\n* builtin classes\n\n  * Array#try_convert()\n  * Hash#try_convert()\n  * IO#try_convert()\n  * Regexp#try_convert()\n  * String#try_convert()\n\n    New methods.\n\n  * Array#sample\n\n    New method with which replaces #choice.\n\n  * Enumerable#each_with_object\n  * Enumerator#with_object\n\n    New methods.\n\n  * Enumerator.new { |y| ... }\n\n    Now can generate an enumerator from a block that defines\n    enumeration instead of an enumerable object.\n\n  * Enumerator#rewind\n\n    Now calls the \"rewind\" method of the enclosed object if defined.\n\n  * Enumerator#inspect\n\n    Implemented.\n\n  * Hash#default_proc=\n\n    New method.\n\n  * Hash#key\n\n    Renamed from Hash#index.\n\n  * ENV.key\n\n    Renamed from ENV.index.\n\n  * IO#ungetbyte\n\n    Added as an alias to #ungetc.\n\n  * Proc#===\n\n    New method primarily for use in the case-when construct.\n\n  * Range#cover?\n\n    New alias to #include? for the forward compatibility with 1.9, in\n    which the behavior of Range#include? has changed.\n\n  * Regexp\n\n    The regular expression /\\s/ now properly matches a vertical tab\n    character (VT: \"\\v\") and /\\S/ does not.  It was a bug that /\\s/\n    did not match VT when /[\\s]/ does.  It is clear that VT should\n    always be regarded as white space, not to mention String#strip.\n\n  * String#getbyte\n  * String#setbyte\n  * String#ord\n\n    New methods for the forward compatibility with 1.9, in which the\n    behavior of String#[] and String#[]= have changed.  String#ord is\n    $KCODE aware.\n\n  * Symbol#succ\n  * Symbol#next\n  * Symbol#<=>\n  * Symbol#casecmp\n  * Symbol#=~\n  * Symbol#[]\n  * Symbol#slice\n  * Symbol#length\n  * Symbol#size\n  * Symbol#empty?\n  * Symbol#match\n  * Symbol#upcase\n  * Symbol#downcase\n  * Symbol#capitalize\n  * Symbol#swapcase\n\n    New methods.\n\n* base64\n\n  * Base64#strict_encode64\n  * Base64#strict_decode64\n  * Base64#urlsafe_encode64\n  * Base64#urlsafe_decode64\n\n    New methods.\n\n* dbm\n\n  DBM#key\n\n    Renamed from DBM#index.\n\n* gdbm\n\n  GDBM#key\n\n    Renamed from GDBM#index.\n\n* open-uri\n\n  * Added a lot of new options:\n\n    * :ftp_active_mode => bool\n\n      Specify false to enable FTP passive mode.  It is adviced that\n      this option should be explicitly set for forward compatibility\n      because the default mode is changed in Ruby >= 1.9.\n\n    * :read_timeout => seconds\n    * :proxy_http_basic_authentication => [uri, user, password]\n    * :redirect => bool\n    * :ssl_verify_mode => OpenSSL::SSL::VERIFY_*\n    * :ssl_ca_cert => filename\n\n* rational\n\n  * Performace improved by making overall code optimization and\n    introducing Fixnum#gcd implemented in C.\n\n* sdbm\n\n  SDBM#key\n\n    Renamed from SDBM#index.\n\n* securerandom\n\n  SecureRandom.uuid\n\n    New method to generate a v4 random UUID.\n\n* set\n\n  Set#classify\n  Set#collect!\n  Set#delete_if\n  Set#delete_if\n  Set#divide\n  Set#reject!\n\n    Return an enumerator if no block is given.\n\n* stringio\n\n  * StringIO#ungetbyte\n\n    Added as an alias to #ungetc.\n\n* digest\n    * new methods:\n      * Digest::Class.base64digest\n      * Digest::Instance#base64digest\n      * Digest::Instance#base64digest!\n\n* rss\n\n  * 0.2.4 -> 0.2.7.\n\n  * RSS::Maker.make\n    * raise an exception not returns nil for invalid feed making.\n    * requires block.\n\n  * RSS::Maker.[]\n    * new method to return maker class.\n\n  * RSS::Maker.supported?(version)\n    * new method to check whether given version is supported.\n\n  * RSS::Maker: item.guid.permanent_link?\n    * new alias of item.guid.isPermaLink\n  * RSS::Maker: item.guid.permanent_link=\n    * new alias of item.guid.isPermaLink=\n\n* REXML\n\n  * REXML::Document.entity_expansion_limit=\n\n    New method to set the entity expansion limit. By default the limit is\n    set to 10000.  See the following URL for details.\n\n    http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/\n\n== Changes since the 1.8.6 release\n\n=== Configuration changes\n\n* vendor_ruby directory\n\n  A new library directory named `vendor_ruby' is introduced in\n  addition to `site_ruby'.  The idea is to separate libraries\n  installed by the package system (`vendor') from manually (`site')\n  installed libraries preventing the former from getting overwritten\n  by the latter, while preserving the user option to override vendor\n  libraries with site libraries. (`site_ruby' takes precedence over\n  `vendor_ruby')\n\n  If you are a package maintainer, make each library package configure\n  the library passing the `--vendor' option to `extconf.rb' so that\n  the library files will get installed under `vendor_ruby'.\n\n  You can change the directory locations using configure options such\n  as `--with-sitedir=DIR' and `--with-vendordir=DIR'.\n\n=== Global constants\n\n* new constants\n\n  * RUBY_COPYRIGHT\n  * RUBY_DESCRIPTION\n\n=== Library updates (outstanding ones only)\n\n* new library\n\n  * securerandom\n\n* builtin classes\n\n  * Array#flatten\n  * Array#flatten!\n\n    Takes an optional argument that determines the level of recursion\n    to flatten.\n\n  * Array#eql?\n  * Array#hash\n  * Array#==\n  * Array#<=>\n\n    Handle recursive data properly.\n\n  * Array#index\n  * Array#rindex\n\n    Take a block instead of an argument.\n\n  * Array#collect!\n  * Array#map!\n  * Array#each\n  * Array#each_index\n  * Array#reverse_each\n  * Array#reject\n  * Array#reject!\n  * Array#delete_if\n\n    Return an enumerator if no block is given.\n\n    Note that #map and #collect still return an array unlike Ruby 1.9\n    to keep compatibility.\n\n  * Array#pop\n  * Array#shift\n\n    Take an optional argument specifying the number of elements to\n    remove.\n\n  * Array#choice\n  * Array#combination\n  * Array#cycle\n  * Array#drop\n  * Array#drop_while\n  * Array#permutation\n  * Array#product\n  * Array#shuffle\n  * Array#shuffle!\n  * Array#take,\n  * Array#take_while\n\n    New methods.\n\n  * Binding#eval\n\n    New method.\n\n  * Dir#each\n  * Dir#foreach\n\n    Return an enumerator if no block is given.\n\n  * Enumerable::Enumerator\n\n    New class for various enumeration defined by the enumerator library.\n\n  * Enumerable#each_slice\n  * Enumerable#each_cons\n  * Object#to_enum\n  * Object#enum_for\n\n    New methods for various enumeration defined by the enumerator library.\n\n  * Enumerable#count\n  * Enumerable#cycle\n  * Enumerable#drop\n  * Enumerable#drop_while\n  * Enumerable#find_index\n  * Enumerable#first\n  * Enumerable#group_by\n  * Enumerable#max_by\n  * Enumerable#min_by\n  * Enumerable#minmax\n  * Enumerable#minmax_by\n  * Enumerable#none?\n  * Enumerable#one?\n  * Enumerable#take\n  * Enumerable#take_while\n\n    New methods.\n\n  * Enumerable#find\n  * Enumerable#find_all\n  * Enumerable#partition\n  * Enumerable#reject\n  * Enumerable#select\n  * Enumerable#sort_by\n\n    Return an enumerator if no block is given.\n\n    Note that #map and #collect still return an array unlike Ruby 1.9\n    to keep compatibility.\n\n  * Enumerable#inject\n\n    Accepts a binary operator instead of a block.\n\n  * Enumerable#reduce\n\n    New alias to #inject.\n\n  * Enumerable#to_a\n\n    Can take optional arguments and pass them to #each.\n\n  * Hash#eql?\n  * Hash#hash\n  * Hash#==\n\n    Handle recursive data properly.\n\n  * Hash#delete_if\n  * Hash#each\n  * Hash#each_key\n  * Hash#each_pair\n  * Hash#each_value\n  * Hash#reject!\n  * Hash#select\n  * ENV.delete_if\n  * ENV.each\n  * ENV.each_key\n  * ENV.each_pair\n  * ENV.each_value\n  * ENV.reject!\n  * ENV.select\n\n    Return an enumerator if no block is given.\n\n  * GC.stress\n  * GC.stress=\n\n    New methods.\n\n  * Integer#ord\n  * Integer#odd?\n  * Integer#even?\n  * Integer#pred\n\n    New methods.\n\n  * Integer#downto\n  * Integer#times\n  * Integer#upto\n\n    Return an enumerator if no block is given.\n\n  * IO#each\n  * IO#each_line\n  * IO#each_byte\n  * IO.foreach\n  * ARGF.each\n  * ARGF.each_line\n  * ARGF.each_byte\n\n    Return an enumerator if no block is given.\n\n  * IO#bytes\n  * IO#chars\n  * IO#each_char\n  * IO#getbyte\n  * IO#lines\n  * IO#readbyte\n  * ARGF.bytes\n  * ARGF.chars\n  * ARGF.each_char\n  * ARGF.getbyte\n  * ARGF.lines\n  * ARGF.readbyte\n\n    New methods. \n\n  * Method#name\n  * Method#owner\n  * Method#receiver\n  * UnboundMethod#name\n  * UnboundMethod#owner\n\n    New methods.\n\n  * Module#class_exec\n  * Module#module_exec\n\n    New methods.\n\n  * Numeric#step\n\n    Return an enumerator if no block is given.\n\n  * Object#instance_exec\n  * Object#tap\n\n    New methods.\n\n  * ObjectSpace.each_object\n\n    Return an enumerator if no block is given.\n\n  * Process.exec implemented.\n\n  * Range#each\n  * Range#step\n\n    Return an enumerator if no block is given.\n\n  * Regexp.union accepts an array of patterns.\n\n  * String#bytes\n\n    New method\n\n  * String#bytesize\n\n    New method, returning the size in bytes. (alias length and size)\n\n  * String#chars\n  * String#each_char\n  * String#lines\n  * String#partition\n  * String#rpartition\n  * String#start_with?\n  * String#end_with?\n\n    New methods.  These are $KCODE aware unlike #index, #rindex and\n    #include?.\n\n  * String#each_byte\n  * String#each\n  * String#each_line\n  * String#gsub(pattern)\n\n    Return an enumerator if no block is given.\n\n  * String#upto\n\n    An optional second argument is added to specify if the last value\n    should be included.\n\n  * StopIteration\n\n    New exception class that causes Kernel#loop to stop iteration when\n    raised.\n\n  * Struct#each\n  * Struct#each_pair\n\n    Return an enumerator if no block is given.\n\n  * Symbol#to_proc\n\n    New method.\n\n  * __method__\n\n    New global function that returns the name of the current method as\n    a Symbol.\n\n* enumerator\n\n  * Enumerator is now a built-in module.  The #next and #rewind\n    methods are implemented using the \"generator\" library.  Use with\n    care and be aware of the performance loss.\n\n* ipaddr\n\n  * New methods\n    * IPAddr#<=>\n    * IPAddr#succ\n\n      IPAddr objects are now comparable and enumerable having these\n      methods.  This also means that it is possible to have a Range\n      object between two IPAddr objects.\n\n    * IPAddr#to_range\n\n      A new method to create a Range object for the (network) address.\n\n  * Type coercion support\n    * IPAddr#&\n    * IPAddr#|\n    * IPAddr#==\n    * IPAddr#include?\n\n      These methods now accept a string or an integer instead of an\n      IPAddr object as the argument.\n\n* net/smtp\n\n  * Support SSL/TLS.\n\n* openssl\n\n  * New classes\n    * OpenSSL::PKey::EC\n    * OpenSSL::PKey::EC::Group\n    * OpenSSL::PKey::EC::Point\n    * OpenSSL::PKey::PKCS5\n    * OpenSSL::SSL::Session\n\n  * Documentation!\n\n  * Various new methods (see documentation).\n\n  * Remove redundant module namespace in Cipher, Digest, PKCS7, PKCS12.\n    Compatibility classes are provided which will be removed in Ruby 1.9.\n\n* shellwords\n\n  * Add methods for escaping shell-unsafe characters:\n    * Shellwords.join\n    * Shellwords.escape\n    * Array#shelljoin\n    * String#shellescape\n\n  * Add shorthand methods:\n    * Shellwords.split (alias shellwords)\n    * String#shellsplit\n\n* stringio\n\n  * StringIO#getbyte\n  * StringIO#readbyte\n\n    New methods. (aliases for compatibility with 1.9)\n\n  * StringIO#each_char\n  * StringIO#chars\n\n    New methods.\n\n  * StringIO#each\n  * StringIO#each_line\n  * StringIO#each_byte\n\n    Return an enumerator if no block is given.\n\n* tempfile\n\n  * Tempfile.open and Tempfile.new now accept a suffix for the\n    temporary file to be created.  To specify a suffix, pass an array\n    of [basename, suffix] as the first argument.\n\n      Tempfile.open(['image', 'jpg']) { |tempfile| ... }\n\n* tmpdir\n\n  * New method:\n\n    * Dir.mktmpdir\n\n* uri\n\n  * added LDAPS scheme.\n  * Change for RFC3986:\n    * FTP\n      * URI('ftp://example.com/foo').path #=> 'foo'\n      * URI('ftp://example.com/%2Ffoo').path #=> '/foo'\n      * URI::FTP.build([nil, 'example.com', nil, '/foo', 'i').to_s #=> 'ftp://example.com/%2Ffoo;type=i'\n    * URI merge\n      * URI('http://a/b/c/d;p?q').merge('?y') == URI('http://a/b/c/d;p?y')\n      * URI('http://a/b/c/d;p?q').merge('/./g') == URI('http://a/g')\n      * URI('http://a/b/c/d;p?q').merge('/../g') == URI('http://a/g')\n      * URI('http://a/b/c/d;p?q').merge('../../../g') == URI('http://a/g')\n      * URI('http://a/b/c/d;p?q').merge('../../../../g') == URI('http://a/g')\n\n* rss\n\n  * 0.1.6 -> 0.2.4\n\n  * Fix image module URI\n\n  * Atom support\n\n  * ITunes module support\n\n  * Slash module support\n\n  * content:encoded with RSS 2.0 support\n\n=== Interpreter Implementation\n\n* passing a block to a Proc [experimental]\n\n  This implementation in current shape is known to be buggy/broken,\n  especially with nested block invocation.  Take this as an\n  experimental feature.\n\n* stack trace\n\n  On non-SystemStackError exception, full stack trace is shown.\n\n=== Compatibility issues (excluding feature bug fixes)\n\n* String#slice! had some unintentional bugs and they have been fixed\n  because either they disagreed with documentation or their respective\n  behavior of #slice.  Unfortunately, this causes some\n  incompatibilities in the following (somewhat rare) cases.\n\n  * #slice! no longer expands the array when an out-of-boundary value\n    is given.\n\n      # Ruby 1.8.6\n      a = [1,2]\n      a.slice!(4,0)   #=> nil\n      a               #=> [1,2,nil,nil]\n\n      # Ruby 1.8.7\n      a = [1,2]\n      a.slice!(4,0)   #=> nil\n      a               #=> [1,2]\n\n  * #slice! no longer raises an exception but returns nil when a\n    negative length or out-of-boundary negative position is given.\n\n      # Ruby 1.8.6\n      a = [1,2]\n      a.slice!(1,-1)  #=> (raises IndexError)\n      a.slice!(-5,1)  #=> (raises IndexError)\n\n      # Ruby 1.8.7\n      a = [1,2]\n      a.slice!(1,-1)  #=> nil\n      a.slice!(-5,1)  #=> nil\n\n* String#to_i, String#hex and String#oct no longer accept a sequence\n  of underscores (`__') as part of a number.\n\n    # Ruby 1.8.6\n    '1__0'.to_i     #=> 10\n    '1__0'.to_i(2)  #=> 2  # 0b10\n    '1__0'.oct      #=> 8  # 010\n    '1__0'.hex      #=> 16 # 0x10\n\n    # Ruby 1.8.7\n    '1__0'.to_i     #=> 1\n    '1__0'.to_i(2)  #=> 1\n    '1__0'.oct      #=> 1\n    '1__0'.hex      #=> 1\n\n  The old behavior was inconsistent with Ruby syntax and considered as\n  a bug.\n\n* date\n\n  * Date.parse\n\n    '##.##.##' (where each '#' is a digit) is now taken as 'YY.MM.DD'\n    instead of 'MM.DD.YY'.  While the change may confuse you, you can\n    always use Date.strptime() when you know what you are dealing\n    with.\n\n* stringio\n\n  * StringIO#each_byte\n\n    The return value changed from nil to self.  This is what the\n    document says and the same as each_line() does.\n\n* tempfile\n\n  * The file name format has changed.  No dots are included by default\n    in temporary file names any more.  See above for how to specify a\n    suffix.\n\n* uri\n\n  * See above for details.\n\n== Changes since the 1.8.5 release\n\n=== New platforms/build tools support\n\n* IA64 HP-UX\n\n* Visual C++ 8 SP1\n\n* autoconf 2.6x\n\n=== Global constants\n\n* RUBY_PATCHLEVEL\n\n  New constant since 1.8.5-p1.\n\n=== Library updates (outstanding ones only)\n\n* builtin classes\n\n  * New method: Kernel#instance_variable_defined?\n\n  * New method: Module#class_variable_defined?\n\n  * New feature: Dir::glob() can now take an array of glob patterns.\n\n* date\n\n  * Updated based on date2 4.0.3.\n\n* digest\n\n  * New internal APIs for C and Ruby.\n\n  * Support for autoloading.\n\n      require 'digest'\n\n      # autoloads digest/md5\n      md = Digest::MD5.digest(\"string\")\n\n  * New digest class methods: file\n\n  * New digest instance methods: clone, reset, new, inspect,\n    digest_length (alias size or length), block_length()\n\n  * New library: digest/bubblebabble\n\n  * New function: Digest(name)\n\n* fileutils\n\n  * New option for FileUtils.cp_r(): :remove_destination\n\n* nkf\n\n  * Updated based on nkf as of 2007-01-28.\n\n* thread\n\n  * Replaced with much faster mutex implementation in C.  The former\n    implementation, which is slow but considered to be stable, is\n    available with a configure option `--disable-fastthread'.\n\n* tk\n\n  * Updated Tile extension support based on Tile 0.7.8.\n\n  * Support --without-X11 configure option for non-X11 versions of\n    Tcl/Tk (e.g. Tcl/Tk Aqua).\n\n  * New sample script: irbtkw.rbw -- IRB on Ruby/Tk. It has no trouble\n    about STDIN blocking on Windows.\n\n* webrick\n\n  * New method: WEBrick::Cookie.parse_set_cookies()\n\n=== Compatibility issues (excluding feature bug fixes)\n\n* builtin classes\n\n  * String#intern now raises SecurityError when $SAFE level is greater\n    than zero.\n\n* date\n\n  * Time#to_date and Time#to_datetime are added as private methods.\n    They cause name conflict error in ActiveSupport 1.4.1 and prior,\n    which comes with Rails 1.2.2 and prior.  Updating ActiveSupport\n    and/or Rails to the latest versions fixes the problem.\n\n* digest\n\n  * The constructor does no longer take an initial string to feed.\n    The following examples show how to migrate:\n\n      # Before\n      md = Digest::MD5.new(\"string\")\n      # After (works with any version)\n      md = Digest::MD5.new.update(\"string\")\n        \n      # Before\n      hd = Digest::MD5.new(\"string\").hexdigest\n      # After (works with any version)\n      hd = Digest::MD5.hexdigest(\"string\")\n\n* fileutils\n\n  * A minor implementation change breaks Rake <=0.7.1.\n    Updating Rake to 0.7.2 or higher fixes the problem.\n\n* tk\n\n  * Tk::X_Scrollable (Y_Scrollable) is renamed to Tk::XScrollable\n    (YScrollable). Tk::X_Scrollable (Y_Scrollable) is still available,\n    but it is an alias name.\n"
  },
  {
    "path": "README",
    "content": "* What's Ruby\n\nRuby is the interpreted scripting language for quick and\neasy object-oriented programming.  It has many features to\nprocess text files and to do system management tasks (as in\nPerl).  It is simple, straight-forward, and extensible.\n\n\n* Features of Ruby\n\n  + Simple Syntax\n  + *Normal* Object-Oriented features(ex. class, method calls)\n  + *Advanced* Object-Oriented features(ex. Mix-in, Singleton-method)\n  + Operator Overloading\n  + Exception Handling\n  + Iterators and Closures\n  + Garbage Collection\n  + Dynamic Loading of Object files(on some architecture)\n  + Highly Portable(works on many UNIX machines, and on DOS,\n    Windows, Mac, BeOS etc.)\n\n\n* How to get Ruby\n\nThe Ruby distribution files can be found in the following FTP site:\n\n  ftp://ftp.ruby-lang.org/pub/ruby/\n\nThe latest source code of this version series can be checked out\nthrough SVN with the following command:\n\n  $ svn co http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/\n\nThe trunk of the Ruby source tree can be checked out with the\nfollowing command:\n\n  $ svn co http://svn.ruby-lang.org/repos/ruby/trunk/ ruby\n\nThere are some other branches under development.  Try the following\ncommand and see the list of branches:\n\n  $ svn ls http://svn.ruby-lang.org/repos/ruby/branches/\n\n\n* Ruby home-page\n\nThe URL of the Ruby home-page is:\n\n   http://www.ruby-lang.org/\n\n\n* Mailing list\n\nThere is a mailing list to talk about Ruby.\nTo subscribe this list, please send the following phrase\n\n\tsubscribe YourFirstName YourFamilyName\ne.g.\n        subscribe Joseph Smith\n\nin the mail body (not subject) to the address <ruby-talk-ctl@ruby-lang.org>.\n\n\n* How to compile and install\n\nThis is what you need to do to compile and install Ruby:\n\n  1. If ./configure does not exist or is older than configure.in,\n     run autoconf to (re)generate configure.\n\n  2. Run ./configure, which will generate config.h and Makefile.\n\n     Some C compiler flags may be added by default depending on your\n     environment.  Specify optflags=.. and warnflags=.. as necessary\n     to override them.\n\n  3. Edit defines.h if you need.  Usually this step will not be needed.\n\n  4. Remove comment mark(#) before the module names from ext/Setup (or\n     add module names if not present), if you want to link modules\n     statically.\n\n     If you don't want to compile non static extension modules\n     (probably on architectures which does not allow dynamic loading),\n     remove comment mark from the line \"#option nodynamic\" in\n     ext/Setup.\n\n  5. Run make.\n\n  6. Optionally, run 'make test' to check whether the compiled Ruby\n     interpreter works well.  If you see the message \"test succeeded\",\n     your ruby works as it should (hopefully).\n\n  7. Run 'make install'\n\n     You may have to be a super user to install ruby.\n\nIf you fail to compile ruby, please send the detailed error report with\nthe error log and machine/OS type, to help others.\n\n\n* Copying\n\nSee the file COPYING.\n\n\n* The Author\n\nFeel free to send comments and bug reports to the author.  Here is the \nauthor's latest mail address:\n\n  matz@netlab.jp\n\n-------------------------------------------------------\ncreated at: Thu Aug  3 11:57:36 JST 1995\nLocal variables:\nmode: indented-text\nend:\n"
  },
  {
    "path": "README-kiji",
    "content": "What is Kiji\n============\nKiji is a version of the Ruby Enterprise Edition runtime specifically\nimproved for execution of large long-running programs, such as servers. The\nchanges in Kiji are mostly concerned with MRI's garbage collection algorithm,\nwhich used to take a large portion of the execution time. MRI only uses one\nheap for all objects. Kiji uses two, named \"eden\" and \"longlife\". Longlife\nheap stores all AST nodes (parsed representations of the source code) as well\nas most constant strings. Longlife is collected much less frequently, allowing\nfor CPU time savings.\n\nBuild instructions\n==================\nThe build instructions provided in Ruby's master README file are perfectly\nappropriate for Kiji as well. However, at Twitter we're actually linking it\nwith [Google's tcmalloc library](http://code.google.com/p/google-perftools/).\nAfter you install Google Perftools, you can produce the same binary as we\nuse at Twitter with these commands for configuration:\n\n    export CFLAGS='-O2 -g -Wall -fPIC -fno-builtin-malloc \\\n        -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free \\\n        -fno-stack-protector'\n    export LIBS='-ltcmalloc_minimal'\n    ./configure --disable-pthread --disable-shared --disable-ucontext\n\nEnvironment variables\n=====================\nMRI's memory management could be configured using environment variables. Kiji\npreserves this approach, although the set of available variables is different.\n\nMemory sizing variables\n-----------------------\n\n* `RUBY_GC_HEAP_SIZE=number` is the size, in object slots, of each heap slab.\n  Kiji does away with increasing slab sizes, and heap is always allocated in\n  same increments. One heap object slot is 40 bytes in the current version.\n  Default value is 32768, or (calculating with a 40 byte slot) 1280KiB.\n* `RUBY_GC_EDEN_HEAPS=number` is the target size of the eden heap, in heap\n  slabs. The runtime starts up with a single allocated heap slab, and whenever\n  it fills up and is collected, adds a new one until it reaches the target\n  size. This gradual allocation lessens the memory fragmentation within the\n  heap slabs. Once it reached the target size, it will never shrink below it.\n  It will grow above it if it needs to, but those heap slabs allocated above\n  the target size will be released when they become vacant. Default value is\n  24, which, if used with default slab size, gives the target eden heap size\n  of 30MB.\n* `RUBY_GC_LONGLIFE_LAZINESS=0..1` is the \"laziness\" factor used to govern the\n  allocation strategy of the longlife heap slabs. It is a decimal value\n  between 0 and 1 denoting a ratio. After a longlife GC, if the proportion of\n  empty object slots to total object slots is higher than this setting, the\n  runtime will release vacant heap slabs. Also, if the proportion is higher\n  than this setting, then the runtime will allocate a new longlife heap slab.\n  Default value is 0.05, corresponding to 5%.\n\nGC debugging variables\n----------------------\n\nThe following settings can be used to produce diagnostic output from the\ngarbage collector:\n\n* `RUBY_GC_DEBUG=1` turns GC debug log output on.\n* `RUBY_GC_DATA_FILE=path/to/file` specifies the file where GC debug output is\n  written. Defaults to stderr.\n\nAdvanced GC debugging variables\n-------------------------------\n\nThere are some advanced GC debugging options too, but in order for them to\nwork, you must build a debug version of the executable. To do that, pass the\n`--enable-gc-debug` flag to `./configure`. With such an executable, in\nconjunction with `RUBY_GC_DEBUG=1` you can use the following environment\nvariables:\n\n* `RUBY_GC_DEBUG_SUMMARY=1` will print summary statistics about every GC\n  and a histograms of types of objects that remained alive and were freed in\n  the GC log.\n* `RUBY_GC_DEBUG_DUMP=1` will write files with detailed allocation\n  information: what objects and how many of them were allocated at a\n  particular location in the program (with full backtrace - locations invoked\n  through different paths are distinguished). The files are overwritten after\n  each GC cycle. By default, the files are: \n  * `/tmp/rb_gc_debug_objects.eden.freed.txt`, \n  * `/tmp/rb_gc_debug_objects.eden.live.txt`,\n  * `/tmp/rb_gc_debug_objects.longlife.freed.txt`, and\n  * `/tmp/rb_gc_debug_objects.longlife.live.txt`.\n* `RUBY_GC_DUMP_FILE_PATTERN=c-printf-pattern` specifies a C printf()\n  compliant pattern for naming the allocation tracing files. By default, it is\n  `/tmp/rb_gc_debug_objects.%s.%s.txt`.\n\nThe output of `RUBY_GC_DEBUG_DUMP` is fairly verbose, but you can easily\npost-process it. We ourselves use the following UNIX command line pipe to\nsummarize the traces, sort them, and take the top few entries:\n\n    cat /tmp/rb_gc_debug_objects.eden.live.txt |\n    awk 'BEGIN {} { sums[$2,\" \", $3, \" \", $4, \" \", $5, \" \", $6, \" \", $7, \" \", $8] += $1 } END { for (i in sums) { print sums[i], i } }' |\n    sort -rni |\n    head -n 30 |\n    ruby -e \"STDIN.readlines.each {|l| puts l.split}\"\n\nGC stressing variables\n----------------------\n\nFinally, there are some variables that force the GC into a very\nnon-economical, highly-stressing behavior. We used them internally to diagnose\nbugs within the memory management (or, alternatively, to reasonably assure\nourselves there are none). You probably will not use them, but they're still\nthere in the unlikely case you need them (i.e. to reproduce a bug).\nThese variables also only work in an `--enable-gc-debug` build, but they do\nnot need `RUBY_GC_DEBUG=1`, as they do not produce diagnostic output.\n\n* `RUBY_GC_DEBUG_LONGLIFE_DISABLE=1` turns off longlife heap, effectively\n  reestablishing the MRI's single heap. Useful to measure the performance\n  difference between having and not having a longlife heap, as well as for\n  ruling out that some undesired behavior is due to using longlife heap.\n* `RUBY_GC_DEBUG_STRESS=1` runs full GC (both longlife and eden) after each\n  allocation. Extremely heavy.\n* `RUBY_GC_DEBUG_ALWAYS_MARK=1` marking the eden is allowed to follow edges\n  into the longlife heap (ordinarily, it stops there). Very obscure and\n  unlikely to ever be needed by anyone.\n\nNew APIs\n========\n\nKiji exposes few new APIs:\n\n* `ObjectSpace.allocated_objects` is the number of objects allocated since the\n  Ruby VM started up - it only increases.\n\nObjects have the following two new properties:\n\n* `Object.moved?` is true if an object is on the longlife heap, or if its\n  members (if it is a hash or array) are strings that have been moved to the\n  longlife heap.\n* `Object.longlived?` is true if the object is on the longlife heap.\n\nExecutables built with `--enable-gc-debug` expose the following APIs:\n\n* `GC.exorcise` cleans ghost references from the call stack. Call stack is not\n  by default wiped when methods return, causing some objects pointed to from\n  it to be retained longer than they should.\n* `GC.stress` returns whether full GCs run after every allocation\n* `GC.stress=` sets whether full GCs run after every allocation. Its default\n  value comes from the `RUBY_GC_DEBUG_STRESS` variable.\n* `GC.log(msg)` writes a message to the GC log  file.\n"
  },
  {
    "path": "README.EXT",
    "content": ".\\\" README.EXT -  -*- Text -*- created at: Mon Aug  7 16:45:54 JST 1995\n\nThis document explains how to make extension libraries for Ruby.\n\n1. Basic knowledge\n\nIn C, variables have types and data do not have types.  In contrast,\nRuby variables do not have a static type, and data themselves have\ntypes, so data will need to be converted between the languages.\n\nData in Ruby are represented by the C type `VALUE'.  Each VALUE data\nhas its data-type.\n\nTo retrieve C data from a VALUE, you need to:\n\n (1) Identify the VALUE's data type\n (2) Convert the VALUE into C data\n\nConverting to the wrong data type may cause serious problems.\n\n\n1.1 Data-types\n\nThe Ruby interpreter has the following data types:\n\n\tT_NIL\t\tnil\n\tT_OBJECT\tordinary object\n\tT_CLASS\t\tclass\n\tT_MODULE\tmodule\n\tT_FLOAT\t\tfloating point number\n\tT_STRING\tstring\n\tT_REGEXP\tregular expression\n\tT_ARRAY\t\tarray\n\tT_FIXNUM\tFixnum(31bit integer)\n\tT_HASH\t\tassociative array\n\tT_STRUCT\t(Ruby) structure\n\tT_BIGNUM\tmulti precision integer\n\tT_FILE\t\tIO\n\tT_TRUE\t\ttrue\n\tT_FALSE\t\tfalse\n\tT_DATA\t\tdata\n\tT_SYMBOL        symbol\n\nIn addition, there are several other types used internally:\n\n\tT_ICLASS\n\tT_MATCH\n\tT_UNDEF\n\tT_VARMAP\n\tT_SCOPE\n\tT_NODE\n\nMost of the types are represented by C structures.\n\n1.2 Check Data Type of the VALUE\n\nThe macro TYPE() defined in ruby.h shows the data type of the VALUE.\nTYPE() returns the constant number T_XXXX described above.  To handle\ndata types, your code will look something like this:\n\n  switch (TYPE(obj)) {\n    case T_FIXNUM:\n      /* process Fixnum */\n      break;\n    case T_STRING:\n      /* process String */\n      break;\n    case T_ARRAY:\n      /* process Array */\n      break;\n    default:\n      /* raise exception */\n      rb_raise(rb_eTypeError, \"not valid value\");\n      break;\n  }\n\nThere is the data-type check function\n\n  void Check_Type(VALUE value, int type)\n\nwhich raises an exception if the VALUE does not have the type specified.\n\nThere are also faster check macros for fixnums and nil.\n\n  FIXNUM_P(obj)\n  NIL_P(obj)\n\n1.3 Convert VALUE into C data\n\nThe data for type T_NIL, T_FALSE, T_TRUE are nil, true, false\nrespectively.  They are singletons for the data type.\n\nThe T_FIXNUM data is a 31bit length fixed integer (63bit length on\nsome machines), which can be converted to a C integer by using the\nFIX2INT() macro.  There is also NUM2INT() which converts any Ruby\nnumbers into C integers.  The NUM2INT() macro includes a type check, so\nan exception will be raised if the conversion failed.  NUM2DBL() can\nbe used to retrieve the double float value in the same way.\n\nIn version 1.7 or later it is recommended that you use the new macros\nStringValue() and StringValuePtr() to get a char* from a VALUE.\nStringValue(var) replaces var's value with the result of \"var.to_str()\".\nStringValuePtr(var) does same replacement and returns char*\nrepresentation of var.  These macros will skip the replacement if var is\na String.  Notice that the macros take only the lvalue as their\nargument, to change the value of var in place.\n\nIn version 1.6 or earlier, STR2CSTR() was used to do the same thing\nbut now it is deprecated in version 1.7, because STR2CSTR() has a risk\nof a dangling pointer problem in the to_str() impliclit conversion.\n\nOther data types have corresponding C structures, e.g. struct RArray\nfor T_ARRAY etc. The VALUE of the type which has the corresponding structure\ncan be cast to retrieve the pointer to the struct.  The casting macro\nwill be of the form RXXXX for each data type; for instance, RARRAY(obj). \nSee \"ruby.h\".\n\nFor example, `RSTRING(str)->len' is the way to get the size of the\nRuby String object.  The allocated region can be accessed by\n`RSTRING(str)->ptr'.  For arrays, use `RARRAY(ary)->len' and\n`RARRAY(ary)->ptr' respectively.\n\nNotice: Do not change the value of the structure directly, unless you\nare responsible for the result.  This ends up being the cause of interesting\nbugs.\n\n1.4 Convert C data into VALUE\n\nTo convert C data to Ruby values:\n\n  * FIXNUM\n\n    left shift 1 bit, and turn on LSB.\n\n  * Other pointer values\n\n    cast to VALUE.\n\nYou can determine whether a VALUE is pointer or not by checking its LSB.  \n\nNotice Ruby does not allow arbitrary pointer values to be a VALUE.  They\nshould be pointers to the structures which Ruby knows about.  The known\nstructures are defined in <ruby.h>.\n\nTo convert C numbers to Ruby values, use these macros.\n\n  INT2FIX()\tfor integers within 31bits.\n  INT2NUM()\tfor arbitrary sized integer.\n\nINT2NUM() converts an integer into a Bignum if it is out of the FIXNUM\nrange, but is a bit slower.\n\n1.5 Manipulating Ruby data\n\nAs I already mentioned, it is not recommended to modify an object's internal\nstructure.  To manipulate objects, use the functions supplied by the Ruby\ninterpreter. Some (not all) of the useful functions are listed below:\n\n String functions\n\n  rb_str_new(const char *ptr, long len)\n\n    Creates a new Ruby string.\n\n  rb_str_new2(const char *ptr)\n\n    Creates a new Ruby string from a C string.  This is equivalent to\n    rb_str_new(ptr, strlen(ptr)).\n\n  rb_tainted_str_new(const char *ptr, long len)\n\n    Creates a new tainted Ruby string.  Strings from external data\n    sources should be tainted.\n\n  rb_tainted_str_new2(const char *ptr)\n\n    Creates a new tainted Ruby string from a C string.\n\n  rb_str_cat(VALUE str, const char *ptr, long len)\n\n    Appends len bytes of data from ptr to the Ruby string.\n\n Array functions\n\n  rb_ary_new()\n\n    Creates an array with no elements.\n\n  rb_ary_new2(long len)\n\n    Creates an array with no elements, allocating internal buffer\n    for len elements.\n\n  rb_ary_new3(long n, ...)\n\n    Creates an n-element array from the arguments.\n\n  rb_ary_new4(long n, VALUE *elts)\n\n    Creates an n-element array from a C array.\n\n  rb_ary_push(VALUE ary, VALUE val)\n  rb_ary_pop(VALUE ary)\n  rb_ary_shift(VALUE ary)\n  rb_ary_unshift(VALUE ary, VALUE val)\n\n    Array operations.  The first argument to each functions must be an \n    array.  They may dump core if other types are given.\n\n2. Extending Ruby with C\n\n2.1 Addding new features to Ruby\n\nYou can add new features (classes, methods, etc.) to the Ruby\ninterpreter.  Ruby provides APIs for defining the following things:\n\n * Classes, Modules\n * Methods, Singleton Methods\n * Constants\n\n2.1.1 Class/module definition\n\nTo define a class or module, use the functions below:\n\n  VALUE rb_define_class(const char *name, VALUE super)\n  VALUE rb_define_module(const char *name)\n\nThese functions return the newly created class or module.  You may\nwant to save this reference into a variable to use later.\n\nTo define nested classes or modules, use the functions below:\n\n  VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)\n  VALUE rb_define_module_under(VALUE outer, const char *name)\n\n2.1.2 Method/singleton method definition\n\nTo define methods or singleton methods, use these functions:\n\n  void rb_define_method(VALUE klass, const char *name, \n\t\t        VALUE (*func)(), int argc)\n\n  void rb_define_singleton_method(VALUE object, const char *name, \n\t\t\t          VALUE (*func)(), int argc)\n\nThe `argc' represents the number of the arguments to the C function,\nwhich must be less than 17.  But I doubt you'll need that many.\n\nIf `argc' is negative, it specifies the calling sequence, not number of\nthe arguments.  \n\nIf argc is -1, the function will be called as:\n\n  VALUE func(int argc, VALUE *argv, VALUE obj)\n\nwhere argc is the actual number of arguments, argv is the C array of\nthe arguments, and obj is the receiver.\n\nIf argc is -2, the arguments are passed in a Ruby array. The function\nwill be called like:\n\n  VALUE func(VALUE obj, VALUE args)\n\nwhere obj is the receiver, and args is the Ruby array containing\nactual arguments.\n\nThere are two more functions to define methods.  One is to define\nprivate methods:\n\n  void rb_define_private_method(VALUE klass, const char *name, \n\t\t\t        VALUE (*func)(), int argc)\n\nThe other is to define module functions, which are private AND singleton\nmethods of the module.  For example, sqrt is the module function\ndefined in Math module.  It can be called in the following way:\n\n  Math.sqrt(4)\n\nor\n\n  include Math\n  sqrt(4)\n\nTo define module functions, use:\n\n  void rb_define_module_function(VALUE module, const char *name, \n\t\t\t\t VALUE (*func)(), int argc)\n\nOh, in addition, function-like methods, which are private methods defined\nin the Kernel module, can be defined using:\n\n  void rb_define_global_function(const char *name, VALUE (*func)(), int argc)\n\nTo define an alias for the method,\n\n  void rb_define_alias(VALUE module, const char* new, const char* old);\n\nTo define and undefine the `allocate' class method,\n\n  void rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE klass));\n  void rb_undef_alloc_func(VALUE klass);\n\nfunc have to take the klass as the argument and return a newly\nallocated instance.  This instance should be empty as possible,\nwithout any expensive (including external) resources.\n\n2.1.3 Constant definition\n\nWe have 2 functions to define constants:\n\n  void rb_define_const(VALUE klass, const char *name, VALUE val)\n  void rb_define_global_const(const char *name, VALUE val)\n\nThe former is to define a constant under specified class/module.  The\nlatter is to define a global constant.\n\n2.2 Use Ruby features from C\n\nThere are several ways to invoke Ruby's features from C code.\n\n2.2.1 Evaluate Ruby Programs in a String\n\nThe easiest way to use Ruby's functionality from a C program is to\nevaluate the string as Ruby program.  This function will do the job:\n\n  VALUE rb_eval_string(const char *str)\n\nEvaluation is done under the current context, thus current local variables\nof the innermost method (which is defined by Ruby) can be accessed.\n\n2.2.2 ID or Symbol\n\nYou can invoke methods directly, without parsing the string.  First I need\nto explain about ID.  ID is the integer number to represent Ruby's\nidentifiers such as variable names.  The Ruby data type corresponding to ID\nis Symbol.  It can be accessed from Ruby in the form:\n\n :Identifier\n\nYou can get the ID value from a string within C code by using\n\n  rb_intern(const char *name)\n\nYou can retrieve ID from Ruby object (Symbol or String) given as an\nargument by using\n\n  rb_to_id(VALUE symbol)\n\nYou can convert C ID to Ruby Symbol by using\n\n  VALUE ID2SYM(ID id)\n\nand to convert Ruby Symbol object to ID, use\n\n  ID SYM2ID(VALUE symbol)\n\n2.2.3 Invoke Ruby method from C\n\nTo invoke methods directly, you can use the function below\n\n  VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)\n\nThis function invokes a method on the recv, with the method name\nspecified by the symbol mid.\n\n2.2.4 Accessing the variables and constants\n\nYou can access class variables and instance variables using access\nfunctions.  Also, global variables can be shared between both environments.\nThere's no way to access Ruby's local variables.\n\nThe functions to access/modify instance variables are below:\n\n  VALUE rb_ivar_get(VALUE obj, ID id)\n  VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)\n\nid must be the symbol, which can be retrieved by rb_intern().\n\nTo access the constants of the class/module:\n\n  VALUE rb_const_get(VALUE obj, ID id)\n\nSee 2.1.3 for defining new constant.\n\n3. Information sharing between Ruby and C\n\n3.1 Ruby constants that C can be accessed from C\n\nThe following Ruby constants can be referred from C.\n\n  Qtrue\n  Qfalse\n\nBoolean values.  Qfalse is false in C also (i.e. 0).\n\n  Qnil\n\nRuby nil in C scope.\n\n3.2 Global variables shared between C and Ruby\n\nInformation can be shared between the two environments using shared global\nvariables.  To define them, you can use functions listed below:\n\n  void rb_define_variable(const char *name, VALUE *var)\n\nThis function defines the variable which is shared by both environments.\nThe value of the global variable pointed to by `var' can be accessed\nthrough Ruby's global variable named `name'.\n\nYou can define read-only (from Ruby, of course) variables using the\nfunction below.\n\n  void rb_define_readonly_variable(const char *name, VALUE *var)\n\nYou can defined hooked variables.  The accessor functions (getter and\nsetter) are called on access to the hooked variables.\n\n  void rb_define_hooked_variable(constchar *name, VALUE *var,\n\t\t\t\t VALUE (*getter)(), void (*setter)())\n\nIf you need to supply either setter or getter, just supply 0 for the\nhook you don't need.  If both hooks are 0, rb_define_hooked_variable()\nworks just like rb_define_variable().\n\n  void rb_define_virtual_variable(const char *name,\n\t\t\t\t  VALUE (*getter)(), void (*setter)())\n\nThis function defines a Ruby global variable without a corresponding C\nvariable.  The value of the variable will be set/get only by hooks.\n\nThe prototypes of the getter and setter functions are as follows:\n\n  (*getter)(ID id, void *data, struct global_entry* entry);\n  (*setter)(VALUE val, ID id, void *data, struct global_entry* entry);\n\n3.3 Encapsulate C data into a Ruby object\n\nTo wrap and objectify a C pointer as a Ruby object (so called\nDATA), use Data_Wrap_Struct().\n\n  Data_Wrap_Struct(klass, mark, free, ptr)\n\nData_Wrap_Struct() returns a created DATA object.  The klass argument\nis the class for the DATA object.  The mark argument is the function\nto mark Ruby objects pointed by this data.  The free argument is the\nfunction to free the pointer allocation.  If this is -1, the pointer\nwill be just freed.  The functions mark and free will be called from\ngarbage collector.\n\nYou can allocate and wrap the structure in one step.\n\n  Data_Make_Struct(klass, type, mark, free, sval)\n\nThis macro returns an allocated Data object, wrapping the pointer to\nthe structure, which is also allocated.  This macro works like:\n\n  (sval = ALLOC(type), Data_Wrap_Struct(klass, mark, free, sval))\n\nArguments klass, mark, and free work like their counterparts in\nData_Wrap_Struct().  A pointer to the allocated structure will be\nassigned to sval, which should be a pointer of the type specified.\n\nTo retrieve the C pointer from the Data object, use the macro\nData_Get_Struct().\n\n  Data_Get_Struct(obj, type, sval)\n\nA pointer to the structure will be assigned to the variable sval.\n\nSee the example below for details. \n\n4. Example - Creating dbm extension\n\nOK, here's the example of making an extension library.  This is the\nextension to access DBMs.  The full source is included in the ext/\ndirectory in the Ruby's source tree.\n\n(1) make the directory\n\n  % mkdir ext/dbm\n\nMake a directory for the extension library under ext directory.\n\n(2) design the library\n\nYou need to design the library features, before making it.\n\n(3) write C code.\n\nYou need to write C code for your extension library.  If your library\nhas only one source file, choosing ``LIBRARY.c'' as a file name is\npreferred.  On the other hand, in case your library has multiple source\nfiles, avoid choosing ``LIBRARY.c'' for a file name.  It may conflict\nwith an intermediate file ``LIBRARY.o'' on some platforms.\n\nRuby will execute the initializing function named ``Init_LIBRARY'' in\nthe library.  For example, ``Init_dbm()'' will be executed when loading\nthe library.\n\nHere's the example of an initializing function.\n\n--\nInit_dbm()\n{\n    /* define DBM class */\n    cDBM = rb_define_class(\"DBM\", rb_cObject);\n    /* DBM includes Enumerate module */\n    rb_include_module(cDBM, rb_mEnumerable);\n\n    /* DBM has class method open(): arguments are received as C array */\n    rb_define_singleton_method(cDBM, \"open\", fdbm_s_open, -1);\n\n    /* DBM instance method close(): no args */\n    rb_define_method(cDBM, \"close\", fdbm_close, 0);\n    /* DBM instance method []: 1 argument */\n    rb_define_method(cDBM, \"[]\", fdbm_fetch, 1);\n\t\t:\n\n    /* ID for a instance variable to store DBM data */\n    id_dbm = rb_intern(\"dbm\");\n}\n--\n\nThe dbm extension wraps the dbm struct in the C environment using \nData_Make_Struct.\n\n--\nstruct dbmdata {\n    int  di_size;\n    DBM *di_dbm;\n};\n\n\nobj = Data_Make_Struct(klass, struct dbmdata, 0, free_dbm, dbmp);\n--\n\nThis code wraps the dbmdata structure into a Ruby object.  We avoid wrapping\nDBM* directly, because we want to cache size information.\n\nTo retrieve the dbmdata structure from a Ruby object, we define the\nfollowing macro:\n\n--\n#define GetDBM(obj, dbmp) {\\\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\\\n    if (dbmp->di_dbm == 0) closed_dbm();\\\n}\n--\n\nThis sort of complicated macro does the retrieving and close checking for\nthe DBM.\n\nThere are three kinds of way to receive method arguments.  First,\nmethods with a fixed number of arguments receive arguments like this:\n\n--\nstatic VALUE\nfdbm_delete(obj, keystr)\n    VALUE obj, keystr;\n{\n\t:\n}\n--\n\nThe first argument of the C function is the self, the rest are the\narguments to the method.\n\nSecond, methods with an arbitrary number of arguments receive\narguments like this:\n\n--\nstatic VALUE\nfdbm_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n\t:\n    if (rb_scan_args(argc, argv, \"11\", &file, &vmode) == 1) {\n\tmode = 0666;\t\t/* default value */\n    }\n\t:\n}\n--\n\nThe first argument is the number of method arguments, the second\nargument is the C array of the method arguments, and the third\nargument is the receiver of the method.\n\nYou can use the function rb_scan_args() to check and retrieve the\narguments.  For example, \"11\" means that the method requires at least one\nargument, and at most receives two arguments.\n\nMethods with an arbitrary number of arguments can receive arguments\nby Ruby's array, like this:\n\n--\nstatic VALUE\nfdbm_indexes(obj, args)\n    VALUE obj, args;\n{\n\t:\n}\n--\n\nThe first argument is the receiver, the second one is the Ruby array\nwhich contains the arguments to the method.\n\n** Notice\n\nGC should know about global variables which refer to Ruby's objects, but\nare not exported to the Ruby world.  You need to protect them by\n\n  void rb_global_variable(VALUE *var)\n\n(4) prepare extconf.rb\n\nIf the file named extconf.rb exists, it will be executed to generate\nMakefile.\n\nextconf.rb is the file for checking compilation conditions etc.  You\nneed to put\n\n  require 'mkmf'\n\nat the top of the file.  You can use the functions below to check\nvarious conditions.\n\n  have_library(lib, func): check whether library containing function exists.\n  have_func(func, header): check whether function exists\n  have_header(header): check whether header file exists\n  create_makefile(target): generate Makefile\n\nThe value of the variables below will affect the Makefile.\n\n  $CFLAGS: included in CFLAGS make variable (such as -O)\n  $CPPFLAGS: included in CPPFLAGS make variable (such as -I, -D)\n  $LDFLAGS: included in LDFLAGS make variable (such as -L)\n  $objs: list of object file names\n\nNormally, the object files list is automatically generated by searching\nsource files, but you must define them explicitly if any sources will\nbe generated while building.\n\nIf a compilation condition is not fulfilled, you should not call\n``create_makefile''.  The Makefile will not be generated, compilation will\nnot be done.\n\n(5) prepare depend (optional)\n\nIf the file named depend exists, Makefile will include that file to\ncheck dependencies.  You can make this file by invoking\n\n  % gcc -MM *.c > depend\n\nIt's harmless.  Prepare it.\n\n(6) generate Makefile\n\nTry generating the Makefile by:\n\n  ruby extconf.rb\n\nIf the library should be installed under vendor_ruby directory\ninstead of site_ruby directory, use --vendor option as follows.\n\n  ruby extconf.rb --vendor\n\nYou don't need this step if you put the extension library under the ext\ndirectory of the ruby source tree.  In that case, compilation of the\ninterpreter will do this step for you.\n\n(7) make\n\nType\n\n  make\n\nto compile your extension.  You don't need this step either if you have\nput the extension library under the ext directory of the ruby source tree.\n\n(8) debug\n\nYou may need to rb_debug the extension.  Extensions can be linked\nstatically by adding the directory name in the ext/Setup file so that\nyou can inspect the extension with the debugger.\n\n(9) done, now you have the extension library\n\nYou can do anything you want with your library.  The author of Ruby\nwill not claim any restrictions on your code depending on the Ruby API.\nFeel free to use, modify, distribute or sell your program.\n\nAppendix A. Ruby source files overview\n\nruby language core\n\n  class.c\n  error.c\n  eval.c\n  gc.c\n  object.c\n  parse.y\n  variable.c\n\nutility functions\n\n  dln.c\n  regex.c\n  st.c\n  util.c\n\nruby interpreter implementation\n\n  dmyext.c\n  inits.c\n  main.c\n  ruby.c\n  version.c\n\nclass library\n\n  array.c\n  bignum.c\n  compar.c\n  dir.c\n  enum.c\n  file.c\n  hash.c\n  io.c\n  marshal.c\n  math.c\n  numeric.c\n  pack.c\n  prec.c\n  process.c\n  random.c\n  range.c\n  re.c\n  signal.c\n  sprintf.c\n  string.c\n  struct.c\n  time.c\n\nAppendix B. Ruby extension API reference\n\n** Types\n\n VALUE\n\nThe type for the Ruby object.  Actual structures are defined in ruby.h,\nsuch as struct RString, etc.  To refer the values in structures, use\ncasting macros like RSTRING(obj).\n\n** Variables and constants\n\n Qnil\n\nconst: nil object\n\n Qtrue\n\nconst: true object(default true value)\n\n Qfalse\n\nconst: false object\n\n** C pointer wrapping\n\n Data_Wrap_Struct(VALUE klass, void (*mark)(), void (*free)(), void *sval)\n\nWrap a C pointer into a Ruby object.  If object has references to other\nRuby objects, they should be marked by using the mark function during\nthe GC process.  Otherwise, mark should be 0.  When this object is no\nlonger referred by anywhere, the pointer will be discarded by free\nfunction.\n\n Data_Make_Struct(klass, type, mark, free, sval)\n\nThis macro allocates memory using malloc(), assigns it to the variable\nsval, and returns the DATA encapsulating the pointer to memory region.\n\n Data_Get_Struct(data, type, sval)\n\nThis macro retrieves the pointer value from DATA, and assigns it to\nthe variable sval. \n\n** Checking data types\n\nTYPE(value)\nFIXNUM_P(value)\nNIL_P(value)\nvoid Check_Type(VALUE value, int type)\nvoid Check_SafeStr(VALUE value)\n\n** Data type conversion\n\nFIX2INT(value)\nINT2FIX(i)\nNUM2INT(value)\nINT2NUM(i)\nNUM2DBL(value)\nrb_float_new(f)\nStringValue(value)\nStringValuePtr(value)\nStringValueCStr(value)\nrb_str_new2(s)\n\n** defining class/module\n\n VALUE rb_define_class(const char *name, VALUE super)\n\nDefines a new Ruby class as a subclass of super.\n\n VALUE rb_define_class_under(VALUE module, const char *name, VALUE super)\n\nCreates a new Ruby class as a subclass of super, under the module's\nnamespace.\n\n VALUE rb_define_module(const char *name)\n\nDefines a new Ruby module.\n\n VALUE rb_define_module_under(VALUE module, const char *name)\n\nDefines a new Ruby module under the module's namespace.\n\n void rb_include_module(VALUE klass, VALUE module)\n\nIncludes module into class.  If class already includes it, just\nignored.\n\n void rb_extend_object(VALUE object, VALUE module)\n\nExtend the object with the module's attributes.\n\n** Defining Global Variables\n\n void rb_define_variable(const char *name, VALUE *var)\n\nDefines a global variable which is shared between C and Ruby.  If name\ncontains a character which is not allowed to be part of the symbol,\nit can't be seen from Ruby programs.\n\n void rb_define_readonly_variable(const char *name, VALUE *var)\n\nDefines a read-only global variable.  Works just like\nrb_define_variable(), except the defined variable is read-only.\n\n void rb_define_virtual_variable(const char *name,\n\t\t\t\t VALUE (*getter)(), VALUE (*setter)())\n\nDefines a virtual variable, whose behavior is defined by a pair of C\nfunctions.  The getter function is called when the variable is\nreferenced.  The setter function is called when the variable is set to a\nvalue.  The prototype for getter/setter functions are:\n\n\tVALUE getter(ID id)\n\tvoid setter(VALUE val, ID id)\n\nThe getter function must return the value for the access.\n\n void rb_define_hooked_variable(const char *name, VALUE *var,\n\t\t\t\tVALUE (*getter)(), VALUE (*setter)())\n\nDefines hooked variable.  It's a virtual variable with a C variable.  \nThe getter is called as\n\n\tVALUE getter(ID id, VALUE *var)\n\nreturning a new value.  The setter is called as\n\n\tvoid setter(VALUE val, ID id, VALUE *var)\n\nGC requires C global variables which hold Ruby values to be marked.\n\n void rb_global_variable(VALUE *var)\n\nTells GC to protect these variables.\n\n** Constant Definition\n\n void rb_define_const(VALUE klass, const char *name, VALUE val)\n\nDefines a new constant under the class/module.\n\n void rb_define_global_const(const char *name, VALUE val)\n\nDefines a global constant.  This is just the same as\n\n     rb_define_const(cKernal, name, val)\n\n** Method Definition\n\n rb_define_method(VALUE klass, const char *name, VALUE (*func)(), int argc)\n\nDefines a method for the class.  func is the function pointer.  argc\nis the number of arguments.  if argc is -1, the function will receive\n3 arguments: argc, argv, and self.  if argc is -2, the function will\nreceive 2 arguments, self and args, where args is a Ruby array of\nthe method arguments.\n\n rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(), int argc)\n\nDefines a private method for the class.  Arguments are same as\nrb_define_method().\n\n rb_define_singleton_method(VALUE klass, const char *name, VALUE (*func)(), int argc)\n\nDefines a singleton method.  Arguments are same as rb_define_method().\n\n rb_scan_args(int argc, VALUE *argv, const char *fmt, ...)\n\nRetrieve argument from argc, argv.  The fmt is the format string for\nthe arguments, such as \"12\" for 1 non-optional argument, 2 optional\narguments.  If `*' appears at the end of fmt, it means the rest of\nthe arguments are assigned to the corresponding variable, packed in\nan array.\n\n** Invoking Ruby method\n\n VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)\n\nInvokes a method.  To retrieve mid from a method name, use rb_intern().\n\n VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)\n\nInvokes a method, passing arguments by an array of values.\n\n VALUE rb_eval_string(const char *str)\n\nCompiles and executes the string as a Ruby program.\n\n ID rb_intern(const char *name)\n\nReturns ID corresponding to the name.\n\n char *rb_id2name(ID id)\n\nReturns the name corresponding ID.\n\n char *rb_class2name(VALUE klass)\n\nReturns the name of the class.\n\n int rb_respond_to(VALUE object, ID id)\n\nReturns true if the object responds to the message specified by id.\n\n** Instance Variables\n\n VALUE rb_iv_get(VALUE obj, const char *name)\n\nRetrieve the value of the instance variable.  If the name is not\nprefixed by `@', that variable shall be inaccessible from Ruby.\n\n VALUE rb_iv_set(VALUE obj, const char *name, VALUE val)\n\nSets the value of the instance variable.\n\n** Control Structure\n\n VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)\n\nCalls the function func1, supplying func2 as the block.  func1 will be\ncalled with the argument arg1.  func2 receives the value from yield as\nthe first argument, arg2 as the second argument.\n \n VALUE rb_yield(VALUE val)\n\nEvaluates the block with value val.\n\n VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)\n\nCalls the function func1, with arg1 as the argument.  If an exception\noccurs during func1, it calls func2 with arg2 as the argument.  The\nreturn value of rb_rescue() is the return value from func1 if no\nexception occurs, from func2 otherwise.\n\n VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2)\n\nCalls the function func1 with arg1 as the argument, then calls func2\nwith arg2 if execution terminated.  The return value from\nrb_ensure() is that of func1.\n\n** Exceptions and Errors\n\n void rb_warn(const char *fmt, ...)\n\nPrints a warning message according to a printf-like format.\n\n void rb_warning(const char *fmt, ...)\n\nPrints a warning message according to a printf-like format, if\n$VERBOSE is true.\n\nvoid rb_raise(rb_eRuntimeError, const char *fmt, ...)\n\nRaises RuntimeError.  The fmt is a format string just like printf().\n\n void rb_raise(VALUE exception, const char *fmt, ...)\n\nRaises a class exception.  The fmt is a format string just like printf().\n\n void rb_fatal(const char *fmt, ...)\n\nRaises a fatal error, terminates the interpreter.  No exception handling\nwill be done for fatal errors, but ensure blocks will be executed.\n\n void rb_bug(const char *fmt, ...)\n\nTerminates the interpreter immediately.  This function should be\ncalled under the situation caused by the bug in the interpreter.  No\nexception handling nor ensure execution will be done.\n\n** Initialize and Start the Interpreter\n\nThe embedding API functions are below (not needed for extension libraries):\n\n void ruby_init()\n\nInitializes the interpreter.\n\n void ruby_options(int argc, char **argv)\n\nProcess command line arguments for the interpreter.\n\n void ruby_run()\n\nStarts execution of the interpreter.\n\n void ruby_script(char *name)\n\nSpecifies the name of the script ($0).\n\n** Hooks for the Interpreter Events\n\n void rb_add_event_hook(rb_event_hook_func_t func, rb_event_t events)\n\nAdds a hook function for the specified interpreter events.\nevents should be Or'ed value of:\n\n\tRUBY_EVENT_LINE\n\tRUBY_EVENT_CLASS\n\tRUBY_EVENT_END\n\tRUBY_EVENT_CALL\n\tRUBY_EVENT_RETURN\n\tRUBY_EVENT_C_CALL\n\tRUBY_EVENT_C_RETURN\n\tRUBY_EVENT_RAISE\n\tRUBY_EVENT_ALL\n\nThe definition of rb_event_hook_func_t is below:\n\n typedef void (*rb_event_hook_func_t)(rb_event_t event, NODE *node,\n \t\t\t\t      VALUE self, ID id, VALUE klass)\n\n int rb_remove_event_hook(rb_event_hook_func_t func)\n\nRemoves the specified hook function.\n\nAppendix C. Functions Available in extconf.rb\n\nThese functions are available in extconf.rb:\n\n have_macro(macro, headers)\n\nChecks whether macro is defined with header.  Returns true if the macro\nis defined.\n\n have_library(lib, func)\n\nChecks whether the library exists, containing the specified function.\nReturns true if the library exists.\n\n find_library(lib, func, path...)\n\nChecks whether a library which contains the specified function exists in\npath.  Returns true if the library exists.\n\n have_func(func, header)\n\nChecks whether func exists with header.  Returns true if the function\nexists.  To check functions in an additional library, you need to\ncheck that library first using have_library().\n\n have_var(var, header)\n\nChecks whether var exists with header.  Returns true if the variable\nexists.  To check variables in an additional library, you need to\ncheck that library first using have_library().\n\n have_header(header)\n\nChecks whether header exists.  Returns true if the header file exists.\n\n find_header(header, path...)\n\nChecks whether header exists in path.  Returns true if the header file\nexists.\n\n have_struct_member(type, member, header)\n\nChecks whether type has member with header.  Returns true if the type\nis defined and has the member.\n\n have_type(type, header, opt)\n\nChecks whether type is defined with header.  Returns true if the type\nis defined.\n\n check_sizeof(type, header)\n\nChecks the size of type in char with header.  Returns the size if the\ntype is defined, otherwise nil.\n\n create_makefile(target)\n\nGenerates the Makefile for the extension library.  If you don't invoke\nthis method, the compilation will not be done.\n\n find_executable(bin, path)\n\nFinds command in path, which is File::PATH_SEPARATOR-separated list of\ndirectories.  If path is nil or omitted, environment varialbe PATH\nwill be used.  Returns the path name of the command if it is found,\notherwise nil.\n\n with_config(withval[, default=nil])\n\nParses the command line options and returns the value specified by\n--with-<withval>.\n\n enable_config(config, *defaults)\n disable_config(config, *defaults)\n\nParses the command line options for boolean.  Returns true if\n--enable-<config> is given, or false if --disable-<config> is given.\nOtherwise, yields defaults to the given block and returns the result\nif it is called with a block, or returns defaults.\n\n dir_config(target[, default_dir])\n dir_config(target[, default_include, default_lib])\n\nParses the command line options and adds the directories specified by\n--with-<target>-dir, --with-<target>-include, and/or --with-<target>-lib\nto $CFLAGS and/or $LDFLAGS.  --with-<target>-dir=/path is equivalent to\n--with-<target>-include=/path/include --with-<target>-lib=/path/lib.\nReturns an array of the added directories ([include_dir, lib_dir]).\n\n pkg_config(pkg)\n\nObtains the information for pkg by pkg-config command.  The actual\ncommand name can be overriden by --with-pkg-config command line\noption.\n\n/*\n * Local variables:\n * fill-column: 70\n * end:\n */\n"
  },
  {
    "path": "README.EXT.ja",
    "content": ".\\\" README.EXT.ja -  -*- Text -*- created at: Mon Aug  7 16:45:54 JST 1995\n\nRubyγĥ饤֥κޤ\n\n1μ\n\nCѿˤϷꡤǡˤϷޤ󡥤Ǥ顤\nȤХݥ󥿤intѿȡͤȤƼ\n갷ޤդRubyѿˤϷʤǡ˷\nΰ㤤ΤᡤCRubyߤѴʤСߤ\nǡ򥢥Ǥޤ\n\nRubyΥǡVALUEȤCηɽޤVALUEΥǡ\nϤΥǡפʬΤäƤޤΥǡפ\nΤϥǡ(֥)μºݤι¤̣ƤơRuby\nΥ饹ȤϤޤäΤǤ\n\nVALUECˤȤäựΤǡФˤ\n\n (1) VALUEΥǡפΤ\n (2) VALUECΥǡѴ\n\nξɬפǤ(1)˺ȴְäǡѴԤ\nơǰץबcore dumpޤ\n\n1.1 ǡ\n\nRubyˤϥ桼ȤǽΤʲΥפޤ\n\n\tT_NIL\t\tnil\n\tT_OBJECT\t̾Υ֥\n\tT_CLASS\t\t饹\n\tT_MODULE\t⥸塼\n\tT_FLOAT\t\tư\n\tT_STRING\tʸ\n\tT_REGEXP\tɽ\n\tT_ARRAY\t\t\n\tT_FIXNUM\tFixnum(31bitĹ)\n\tT_HASH\t\tϢ\n\tT_STRUCT\t(Ruby)¤\n\tT_BIGNUM\t¿Ĺ\n\tT_FILE\t\t\n\tT_TRUE\t\t\n\tT_FALSE\t\t\n\tT_DATA\t\tǡ\n\tT_SYMBOL\tܥ\n\n¾ѤƤʲΥפޤ\n\n\tT_ICLASS\n\tT_MATCH\n\tT_UNDEF\n\tT_VARMAP\n\tT_SCOPE\n\tT_NODE\n\nۤȤɤΥפCι¤ΤǼƤޤ\n\n1.2 VALUEΥǡפå\n\nruby.hǤTYPE()ȤޥƤơVALUEΥǡ\nפΤ뤳ȤޤTYPE()ޥϾǾҲ𤷤T_XXXX\nη֤ޤVALUEΥǡפ˱ƽ\nˤϡTYPE()ͤʬ뤳Ȥˤʤޤ\n\n  switch (TYPE(obj)) {\n    case T_FIXNUM:\n      /* FIXNUMν */\n      break;\n    case T_STRING:\n      /* ʸν */\n      break;\n    case T_ARRAY:\n      /* ν */\n      break;\n    default:\n      /* 㳰ȯ */\n      rb_raise(rb_eTypeError, \"not valid value\");\n      break;\n  }\n\nȥǡפåơʤ㳰ȯ\nؿѰդƤޤ\n\n  void Check_Type(VALUE value, int type)\n\nδؿvaluetype̵С㳰ȯޤ\nͿ줿VALUEΥǡפɤå\n뤿ˤϡδؿȤޤ\n\nFIXNUMNIL˴ؤƤϤ®Ƚ̥ޥѰդƤޤ\n\n  FIXNUM_P(obj)\n  NIL_P(obj)\n\n1.3 VALUECΥǡѴ\n\nǡפT_NIL, T_FALSE, T_TRUEǤǡϤ줾\nnil, false, trueǤΥǡפΥ֥ȤϤҤ\nĤĤ¸ߤޤ\n\nǡפT_FIXNUMλ31bitΥ\nFIXNUMCѴ뤿ˤϥޥFIX2INT()פ\nޤ줫顤FIXNUM˸¤餺RubyΥǡѴ\nNUM2INT()פȤޥޤΥޥϥǡ\nפΥå̵ǻȤޤ(ѴǤʤˤ㳰\nȯ)Ʊͤ˥å̵ǻȤѴޥdouble\nФNUM2DBL()פޤ\n\nchar* Ф硢version 1.6 ǤϡSTR2CSTR()פ\nޥȤäƤޤ to_str() ˤۤ\nѴ̤ GC ǽ뤿ᡢversion 1.7 ʹߤǤ\nobsolete Ȥʤꡢ StringValue()  StringValuePtr()\nȤ侩ƤޤStringValue(var)  var  String\n Ǥв⤻Ǥʤ var  var.to_str() η̤\n֤ޥStringValuePtr(var) Ʊͤ var ֤\nƤ var ʸɽФ char* ֤ޥǤvar \nƤľ֤Τǡvar  lvalue Ǥɬפ\nޤ\n\nʳΥǡפбCι¤Τޤб\n빽¤ΤΤVALUEϤΤޤޥ㥹(Ѵ)й¤Τ\nݥ󥿤ѴǤޤ\n\n¤Τϡstruct RXxxxxפȤ̾ruby.hƤ\n㤨ʸϡstruct RStringפǤºݤ˻Ȥǽ\nΤʸ󤯤餤Ȼפޤ\n\nruby.hǤϹ¤Τإ㥹ȤޥRXXXXX()(ʸ\nˤ)Ȥ̾󶡤Ƥޤ(: RSTRING())\n\n㤨СʸstrĹ뤿ˤϡRSTRING(str)->lenפ\nʸstrchar*Ȥ뤿ˤϡRSTRING(str)->ptr\nȤޤξˤϡ줾RARRAY(ary)->lenס\nRARRAY(ary)->ptrפȤʤޤ\n\nRubyι¤Τľܥ˵ĤʤФʤʤ\nȤϡʸι¤ΤȤϻȤǡľѹ\nʤȤǤľѹ硤֥ȤƤ\nȤʤʤäơפ̥Хθˤʤޤ\n\n1.4 CΥǡVALUEѴ\n\nVALUEμºݤι¤\n\n  * FIXNUMξ\n\n    1bitեȤơLSBΩƤ롥\n\n  * ¾Υݥ󥿤ξ\n\n    ΤޤVALUE˥㥹Ȥ롥\n\nȤʤäƤޤäơLSBåVALUEFIXNUM\n狼櫓Ǥ(ݥ󥿤LSBΩäƤʤȤꤷ\n)\n\nǤ顤FIXNUMʳRubyΥ֥Ȥι¤ΤñVALUE\n˥㥹ȤVALUEѴޤǤդι¤\nΤVALUE˥㥹Ƚ櫓ǤϤޤ󡥥㥹Ȥ\nRubyΤäƤ빽¤(ruby.hƤstruct RXxxx\nΤ)Ǥ\n\nFIXNUM˴ؤƤѴޥͳɬפޤC\nVALUEѴޥϰʲΤΤޤɬפ˱\nƻȤʬƤ\n\n  INT2FIX()\tȤ31bit˼ޤ뼫\n  INT2NUM()\tǤդVALUE\n\nINT2NUM()FIXNUMϰϤ˼ޤʤ硤BignumѴ\nƤޤ(٤)\n\n1.5 RubyΥǡ\n\nҤ٤̤ꡤRubyι¤Τ򥢥Ƥι\nԤȤϴޤ󡥤ǡRubyΥǡˤ\nRubyѰդƤؿѤƤ\n\nǤϤäȤȤǤʸ/\nؿ򤢤ޤ(ǤϤʤǤ)\n\n ʸФؿ\n\n  rb_str_new(const char *ptr, long len)\n\n    Rubyʸ롥\n\n  rb_str_new2(const char *ptr)\n\n    Cʸ󤫤Rubyʸ롥δؿεǽ\n    rb_str_new(ptr, strlen(ptr))ƱǤ롥\n\n  rb_tainted_str_new(const char *ptr, long len)\n\n    ޡղä줿Rubyʸ롥\n    Υǡ˴Ťʸˤϱޡղä٤\n    Ǥ롥\n\n  rb_tainted_str_new2(const char *ptr)\n\n    Cʸ󤫤ޡղä줿Rubyʸ롥\n\n  rb_str_cat(VALUE str, const char *ptr, long len)\n\n    RubyʸstrlenХȤʸptrɲä롥\n\n Фؿ\n\n  rb_ary_new()\n\n    Ǥ0롥\n\n  rb_ary_new2(long len)\n\n    Ǥ0롥lenʬΰ򤢤餫\n    ƤƤ\n\n  rb_ary_new3(long n, ...)\n\n    ǻꤷnǤޤ롥\n\n  rb_ary_new4(long n, VALUE *elts)\n\n    ͿnǤ롥\n\n  rb_ary_push(VALUE ary, VALUE val)\n  rb_ary_pop(VALUE ary)\n  rb_ary_shift(VALUE ary)\n  rb_ary_unshift(VALUE ary, VALUE val)\n\n    ArrayƱ̾Υ᥽åɤƱƯ򤹤ؿ1ɬ\n    ǤʤФʤʤ\n\n2RubyεǽȤ\n\nŪRubyǽ񤱤뤳ȤCǤ񤱤ޤRubyΤΤCǵ\nҤƤǤ顤ȤʤǤɡ\nRubyγĥ˻ȤȤ¿ͽ¬뵡ǽ濴˾\n𤷤ޤ\n\n2.1 Ruby˵ǽɲä\n\nRuby󶡤ƤؿȤRuby󥿥ץ꥿˿ǽ\nɲä뤳ȤǤޤRubyǤϰʲεǽɲäؿ\n󶡤Ƥޤ\n\n * 饹⥸塼\n * ᥽åɡðۥ᥽åɤʤ\n * \n\nǤϽ˾Ҳ𤷤ޤ\n\n2.1.1 饹/⥸塼\n\n饹⥸塼뤿ˤϡʲδؿȤޤ\n\n  VALUE rb_define_class(const char *name, VALUE super)\n  VALUE rb_define_module(const char *name)\n\nδؿϿ줿饹⥸塼֤ޤ\n᥽åɤˤͤɬפʤΤǡۤȤɤξ\nͤѿ˳ǼƤɬפǤ礦\n\n饹⥸塼¾Υ饹˥ͥȤ\nϰʲδؿȤޤ\n\n  VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)\n  VALUE rb_define_module_under(VALUE outer, const char *name)\n\n2.1.2 ᥽å/ðۥ᥽å\n\n᥽åɤðۥ᥽åɤˤϰʲδؿȤޤ\n\n  void rb_define_method(VALUE klass, const char *name, \n\t\t        VALUE (*func)(), int argc)\n\n  void rb_define_singleton_method(VALUE object, const char *name, \n\t\t\t          VALUE (*func)(), int argc)\n\n\nǰΤȡðۥ᥽åɡפȤϡΥ֥\nȤФƤͭʥ᥽åɤǤRubyǤϤ褯Smalltalkˤ\n륯饹᥽åɤȤơ饹Фðۥ᥽åɤȤ\nޤ\n\nδؿ argcȤCδؿϤο(\n)ޤargc0ʾλϴؿ˰Ϥο\ṇޤ16İʾΰϻȤޤ(פޤ͡\nʤ)ºݤδؿˤƬΰȤselfͿޤ\nǡꤷ1¿ĤȤˤʤޤ\n\nargcλϰοǤϤʤꤷȤˤʤޤ\nargc-1λϰϤޤargc-2λϰ\nRubyȤϤޤ\n\n᥽åɤؿϤ⤦ĤޤҤȤĤprivate\nåɤؿǡrb_define_method()ƱǤ\n\n  void rb_define_private_method(VALUE klass, const char *name, \n\t\t\t\tVALUE (*func)(), int argc)\n\nprivate᥽åɤȤϴؿǤƤӽФȤνʤ᥽\nɤǤ\n\n⤦ҤȤĤϥ⥸塼ؿΤǤ⥸塼ؿ\nȤϥ⥸塼ðۥ᥽åɤǤꡤƱprivate᥽åɤ\n⤢ΤǤ򤢤Math⥸塼sqrt()ʤɤ\nޤΥ᥽åɤ\n\n  Math.sqrt(4)\n\nȤǤ\n\n  include Math\n  sqrt(4)\n\nȤǤȤޤ⥸塼ؿؿϰʲ\n̤Ǥ\n\n  void rb_define_module_function(VALUE module, const char *name, \n\t\t                 VALUE (*func)(), int argc)\n\nؿŪ᥽å(Kernel⥸塼private method)뤿\nδؿϰʲ̤Ǥ\n\n  void rb_define_global_function(const char *name, VALUE (*func)(), int argc)\n\n\n᥽åɤ̾뤿δؿϰʲ̤Ǥ\n\n  void rb_define_alias(VALUE module, const char* new, const char* old);\n\n饹᥽åallocateꤹ뤿δؿ\nʲ̤Ǥ\n\n  void rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE klass));\n  void rb_undef_alloc_func(VALUE klass);\n\nfuncϥ饹ȤƼäơƤ줿\n󥹤֤ʤƤϤʤޤ󡣤Υ󥹥󥹤ϡ\nʤɤޤޤʤǤֶפΤޤޤˤƤۤ\n褤Ǥ礦\n\n2.1.3 \n\nĥ饤֥꤬ɬפϤ餫Ƥɤ\nǤ礦ؿĤޤ\n\n  void rb_define_const(VALUE klass, const char *name, VALUE val)\n  void rb_define_global_const(const char *name, VALUE val)\n\nԤΥ饹/⥸塼°Ρ\nԤϥХΤǤ\n\n2.2 RubyεǽCƤӽФ\n\nˡ1.5 RubyΥǡ٤ǰҲ𤷤褦ʴؿ\nȤСRubyεǽ¸ƤؿľܸƤӽФȤ\nޤ\n\n# Τ褦ʴؿΰɽϤޤΤȤޤ󡥥\n# 뤷ʤǤ͡\n\nʳˤRubyεǽƤӽФˡϤĤޤ\n\n2.2.1 RubyΥץeval\n\nCRubyεǽƤӽФäȤñˡȤơʸ\nͿ줿RubyΥץɾʲδؿޤ\n\n  VALUE rb_eval_string(const char *str)\n\nɾϸߤδĶǹԤޤĤޤꡤߤΥѿ\nʤɤѤޤ\n\n2.2.2 IDޤϥܥ\n\nCʸͳRubyΥ᥽åɤƤӽФȤǤ\nˡRuby󥿥ץ꥿ǥ᥽åɤѿ̾ꤹ\n˻ȤƤIDˤĤƤޤ礦\n\nIDȤѿ̾᥽å̾ɽǤRubyǤIDб\n֥ȤȤƥܥ(Symbol)ꡤ\n\n :̻\n\nǥǤޤC餳뤿ˤϴؿ\n\n  rb_intern(const char *name)\n\nȤޤRubyȤͿ줿ܥ(ޤʸ\n)IDѴˤϰʲδؿȤޤ\n\n  rb_to_id(VALUE symbol)\n\nID饷ܥ뤿ˤϰʲΥޥȤޤ\n\n  VALUE ID2SYM(ID id)\n\nܥ뤫ID뤿ˤϰʲΥޥȤޤ\n\n  ID SYM2ID(VALUE symbol)\n\n2.2.3 CRubyΥ᥽åɤƤӽФ\n\nCʸͳRubyΥ᥽åɤƤӽФˤϰʲ\nδؿȤޤ\n\n  VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)\n\nδؿϥ֥recvmidǻꤵ᥽åɤƤӽ\nޤ¾˰λλ㤦ʲδؿ⤢ޤ\n\n  VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)\n  VALUE rb_apply(VALUE recv, ID mid, VALUE args)\n\napplyˤϰȤRubyͿޤ\n\n2.2.4 ѿ/򻲾/\n\nCؿȤäƻȡǤΤϡ󥹥\nǤѿϰΤΤCѿȤƥǤ\nޤѿ򻲾ȤˡϸƤޤ\n\n֥ȤΥ󥹥ѿ򻲾ȡؿϰʲ\nǤ\n\n  VALUE rb_ivar_get(VALUE obj, ID id)\n  VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)\n\nidrb_intern()ΤȤäƤ\n\n򻲾ȤˤϰʲδؿȤäƤ\n\n  VALUE rb_const_get(VALUE obj, ID id)\n\n򿷤뤿ˤϡ2.1.3 ٤ǾҲ\nƤؿȤäƤ\n\n3RubyCȤξͭ\n\nCRubyδ֤ǾͭˡˤĤƲ⤷ޤ\n\n3.1 C黲ȤǤRuby\n\nʲRubyCΥ٥뤫黲ȤǤޤ\n\n  Qtrue\n  Qfalse\n\n    ͡QfalseCǤ⵶Ȥߤʤޤ(Ĥޤ0)\n\n  Qnil\n\n    C줫鸫nilס\n\n3.2 CRubyǶͭѿ\n\nCRubyѿȤäƾͭǤޤͭǤ\nѿˤϤĤμबޤΤʤǤäȤɤȤ\nȻפΤrb_define_variable()Ǥ\n\n  void rb_define_variable(const char *name, VALUE *var)\n\nδؿRubyCȤǶͭѿޤѿ̾\n`$'ǻϤޤʤˤϼưŪɲäޤѿͤ\nȼưŪRubyбѿͤѤޤ\n\nޤRuby¦ϹǤʤѿ⤢ޤread only\nѿϰʲδؿޤ\n\n  void rb_define_readonly_variable(const char *name, VALUE *var)\n\nѿ¾hookĤѿǤޤhookդ\nѿϰʲδؿѤޤhookդѿ\nͤλȤhookǹԤɬפޤ\n\n  void rb_define_hooked_variable(const char *name, VALUE *var,\n\t\t\t\t VALUE (*getter)(), void (*setter)())\n\nδؿCδؿˤähookΤĤ줿ѿ\nѿȤ줿ˤϴؿgetterѿͤåȤ\nˤϴؿsetterƤФ롥hookꤷʤgetter\nsetter0ꤷޤ\n\n# gettersetter0ʤrb_define_variable()Ʊˤʤ롥\n\n줫顤CδؿˤäƼ¸Rubyѿ\nؿޤ\n\n  void rb_define_virtual_variable(const char *name,\n\t\t\t\t  VALUE (*getter)(), void (*setter)())\n\nδؿˤä줿RubyѿȤ줿ˤ\ngetterѿͤåȤ줿ˤsetterƤФޤ\n\ngettersetterλͤϰʲ̤Ǥ\n\n  (*getter)(ID id, void *data, struct global_entry* entry);\n  (*setter)(VALUE val, ID id, void *data, struct global_entry* entry);\n\n3.3 CΥǡRuby֥Ȥˤ\n\nC줿ǡ(¤)RubyΥ֥ȤȤ\n갷礬ꤨޤΤ褦ʾˤϡDataȤ\nRuby֥ȤCι¤(ؤΥݥ)򤯤ळȤRuby\n֥ȤȤƼ갷褦ˤʤޤ\n\nData֥Ȥƹ¤ΤRuby֥Ȥ˥ץ\n뤿ˤϡʲΥޥȤޤ\n\n  Data_Wrap_Struct(klass, mark, free, ptr)\n\nΥޥͤ줿Data֥ȤǤ\n\nklassϤData֥ȤΥ饹Ǥptrϥץ벽\nCι¤ΤؤΥݥ󥿤ǤmarkϤι¤ΤRubyΥ֥\nȤؤλȤ˻ȤؿǤΤ褦ʻȤޤޤʤ\nˤ0ꤷޤ\n\n# Τ褦ʻȤϴޤ\n\nfreeϤι¤Τ⤦פˤʤä˸ƤФؿǤ\nؿ١쥯ƤФޤ줬-1ξϡñ\n˳ޤ\n\nCι¤ΤγData֥ȤƱ˹Ԥޥ\nưʲΤΤ󶡤Ƥޤ\n\n  Data_Make_Struct(klass, type, mark, free, sval)\n\nΥޥͤ줿Data֥ȤǤ\n\nklass, mark, freeData_Wrap_StructƱƯ򤷤ޤtype\nϳƤC¤ΤηǤƤ줿¤Τѿsval\nޤѿη (type*) Ǥɬפޤ\n\nData֥Ȥݥ󥿤ФΤϰʲΥޥѤ\nޤ\n\n  Data_Get_Struct(obj, type, sval)\n\nCι¤ΤؤΥݥ󥿤ѿsvalޤ\n\nDataλȤϤäʬˤΤǡ\n򻲾ȤƤ\n\n4 - dbmѥå\n\nޤǤǤȤꤢĥ饤֥ϺϤǤ\nRubyextǥ쥯ȥˤǤ˴ޤޤƤdbm饤֥\nʳŪޤ\n\n(1) ǥ쥯ȥ\n\n  % mkdir ext/dbm\n\nRuby 1.1ǤդΥǥ쥯ȥǥʥߥå饤֥\n뤳ȤǤ褦ˤʤޤRubyŪ˥󥯤\nRubyŸǥ쥯ȥβextǥ쥯ȥ˳ĥ\n饤֥ѤΥǥ쥯ȥɬפޤ̾Ŭ\nǹޤ\n\n(2) ߷פ\n\nޤʤǤɡɤǽ¸뤫ɤޤ\nפɬפޤɤʥ饹Ĥ뤫Υ饹ˤ\nɤʥ᥽åɤ뤫饹󶡤ʤɤˤĤ߷\nޤ\n\n(3) Cɤ\n\nĥ饤֥ΤȤʤCΥ񤭤ޤCΥ\nҤȤĤλˤϡ֥饤֥̾.cפ֤ɤǤ礦C\nΥʣξˤϵդˡ֥饤֥̾.cפȤե\n̾򤱤ɬפޤ֥ȥեȥ⥸塼\nŪ֥饤֥̾.oפȤե\nȤͤ뤫Ǥ\n\nRubyϳĥ饤֥ɤˡInit_饤֥̾פ\nؿưŪ˼¹Ԥޤdbm饤֥ξInit_dbm\nǤδؿǥ饹⥸塼롤᥽åɡʤɤ\nԤޤdbm.cѤޤ\n\n--\nInit_dbm()\n{\n    /* DBM饹 */\n    cDBM = rb_define_class(\"DBM\", rb_cObject);\n    /* DBMEnumerate⥸塼򥤥󥯥롼ɤ */\n    rb_include_module(cDBM, rb_mEnumerable);\n\n    /* DBM饹Υ饹᥽åopen(): CǼ */\n    rb_define_singleton_method(cDBM, \"open\", fdbm_s_open, -1);\n\n    /* DBM饹Υ᥽åclose(): Ϥʤ */\n    rb_define_method(cDBM, \"close\", fdbm_close, 0);\n    /* DBM饹Υ᥽å[]: 1 */\n    rb_define_method(cDBM, \"[]\", fdbm_fetch, 1);\n\t\t:\n\n    /* DBMǡǼ륤󥹥ѿ̾ΤID */\n    id_dbm = rb_intern(\"dbm\");\n}\n--\n\nDBM饤֥dbmΥǡб륪֥ȤˤʤϤ\n顤CdbmRuby˼ɬפޤ\n\n\ndbm.cǤData_Make_StructʲΤ褦˻ȤäƤޤ\n\n--\nstruct dbmdata {\n    int  di_size;\n    DBM *di_dbm;\n};\n\n\nobj = Data_Make_Struct(klass, struct dbmdata, 0, free_dbm, dbmp);\n--\n\nǤdbmstruct¤ΤؤΥݥ󥿤Data˥ץ벽Ƥ\nޤDBM*ľܥץ벽ʤΤclose()ν\nƤΤȤǤ\n\nData֥Ȥdbmstruct¤ΤΥݥ󥿤Ф\n˰ʲΥޥȤäƤޤ\n\n--\n#define GetDBM(obj, dbmp) {\\\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\\\n    if (dbmp->di_dbm == 0) closed_dbm();\\\n}\n--\n\näʣʥޥǤפdbmdata¤ΤΥݥ\nμФȡcloseƤ뤫ɤΥåޤȤƤ\nǤ\n\nDBM饹ˤϤ᥽åɤޤʬह3\nμޤҤȤĤϰοΤΤǡ\nƤdelete᥽åɤޤdelete᥽åɤƤ\nfdbm_delete()ϤΤ褦ˤʤäƤޤ\n\n--\nstatic VALUE\nfdbm_delete(obj, keystr)\n    VALUE obj, keystr;\n{\n\t:\n}\n--\n\nοΥפ1self2ʹߤ᥽å\nΰȤʤޤ\n\nοΤΤCǼΤRubyǼ\nΤȤޤdbm饤֥ǡCǼ\nDBMΥ饹᥽åɤǤopen()ǤƤ\nfdbm_s_open()ϤʤäƤޤ\n\n--\nstatic VALUE\nfdbm_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n\t:\n    if (rb_scan_args(argc, argv, \"11\", &file, &vmode) == 1) {\n\tmode = 0666;\t\t/* default value */\n    }\n\t:\n}\n--\n\nΥפδؿ1Ϳ줿ο2Ϳ\n줿äƤˤʤޤself3ȤͿ\nޤ\n\nͿ줿Ϥ뤿δؿopen()ǤȤ\nƤrb_scan_args()Ǥ3˻ꤷեޥåȤ\n4ѿʹߤ˻ꤷѿͤƤޤ\nեޥåȤϡ1ʸܤάǤʤο2ʸܤ\nάǤο3ʸܤб̵꤬ޤΰ\n뤫ɤ򼨤\"*\"Ǥ2ʸܤ3ʸܤϾάǤ\ndbm.cǤϡեޥåȤ\"11\"Ǥ顤Ϻ1\nǡ2ĤޤǵȤ̣ˤʤޤάƤ\nѿͤnil(CΥ٥ǤQnil)ˤʤޤ\n\nRubyǰΤindexesޤϤ\nǤ\n\n--\nstatic VALUE\nfdbm_indexes(obj, args)\n    VALUE obj, args;\n{\n\t:\n}\n--\n\n1self2RubyǤ\n\n** ջ\n\nRubyȶͭϤʤRubyΥ֥ȤǼǽΤ\nCѿϰʲδؿȤäRuby󥿥ץ꥿ѿ¸\n򶵤ƤƤǤʤGCǥȥ֥򵯤ޤ\n\n  void rb_global_variable(VALUE *var)\n\n(4) extconf.rbѰդ\n\nMakefileοˤʤextconf.rbȤե\nޤextconf.rbϥ饤֥ΥѥɬפʾΥ\nʤɤԤȤŪǤޤ\n\n  require 'mkmf'\n\nextconf.rbƬ֤ޤextconf.rbǤϰʲRuby\nȤȤޤ\n\n  have_library(lib, func): 饤֥¸ߥå\n  have_func(func, header): ؿ¸ߥå\n  have_header(header): إåե¸ߥå\n  create_makefile(target): Makefile\n\nʲѿȤȤǤޤ\n\n  $CFLAGS: ѥɲŪ˻ꤹե饰(-Oʤ)\n  $CPPFLAGS: ץץåɲŪ˻ꤹե饰(-I-Dʤ)\n  $LDFLAGS: 󥯻ɲŪ˻ꤹե饰(-Lʤ)\n  $objs: 󥯤륪֥ȥե̾Υꥹ\n\n֥ȥեΥꥹȤϡ̾ϥե򸡺\nƼưŪޤmakeǥ褦\nŪ˻ꤹɬפޤ\n\n饤֥򥳥ѥ뤹郎·鷺Υ饤֥򥳥\nѥ뤷ʤˤcreate_makefileƤФʤMakefile\n줺ѥԤޤ\n\n(5) dependѰդ\n\n⤷ǥ쥯ȥdependȤե뤬¸ߤС\nMakefile¸طåƤޤ\n\n  % gcc -MM *.c > depend\n\nʤɤǺ뤳Ȥޤä»̵Ǥ礦\n\n(6) Makefile\n\nMakefileºݤ뤿ˤ\n\n  ruby extconf.rb\n\nȤޤextconf.rb require 'mkmf' ιԤʤˤϥ顼\nˤʤޤΤǡɲä\n\n  ruby -r mkmf extconf.rb\n\nȤƤ\n\nsite_ruby ǥ쥯ȥǤʤ\nvendor_ruby ǥ쥯ȥ˥󥹥ȡ뤹ˤ\nʲΤ褦 --vendor ץäƤ\n\n  ruby extconf.rb --vendor\n\nǥ쥯ȥextʲѰդˤRubyΤmakeλ\nưŪMakefileޤΤǡΥƥåפפǤ\n\n(7) make\n\nưŪ󥯥饤֥ˤϤξmakeƤ\nɬפǤ make install ǥ󥹥ȡ뤵ޤ\n\nextʲ˥ǥ쥯ȥѰդϡRubyΥǥ쥯ȥ\nmake¹ԤMakefilemakeɬפˤäƤϤΥ\n塼RubyؤΥ󥯤ޤǼưŪ˼¹ԤƤޤ\nextconf.rb񤭴ʤɤMakefileκɬפʻϤ\nRubyǥ쥯ȥmakeƤ\n\nĥ饤֥make installRuby饤֥Υǥ쥯ȥ\n˥ԡޤ⤷ĥ饤֥ȶĴƻȤRubyǵ\nҤ줿ץबꡤRuby饤֥֤ˤϡ\nĥ饤֥ѤΥǥ쥯ȥβ lib Ȥǥ쥯ȥ\nꡤ ĥ .rb Υե֤ƤƱ˥\nȡ뤵ޤ\n\n(8) ǥХå\n\nޤǥХåʤưʤǤ礦͡ext/Setup˥ǥ\nȥ̾񤯤Ū˥󥯤ΤǥǥХåȤ褦ˤ\nޤʬѥ뤬٤ʤޤɡ\n\n(9) Ǥ\n\nϤäȤʤꡤʤꡤʤꡤͳˤ\nȤRubyκԤϳĥ饤֥˴ؤưڤθ\nĥޤ\n\nAppendix A. RubyΥɤʬ\n\nRubyΥϤĤʬह뤳ȤޤΤ\n饤֥ʬϴŪ˳ĥ饤֥Ʊˤʤ\nƤޤΥϺޤǤǤۤȤǤ\nפޤ\n\nRubyΥ\n\n  class.c\n  error.c\n  eval.c\n  gc.c\n  object.c\n  parse.y\n  variable.c\n\n桼ƥƥؿ\n\n  dln.c\n  regex.c\n  st.c\n  util.c\n\nRubyޥɤμ\n\n  dmyext.c\n  inits.c\n  main.c\n  ruby.c\n  version.c\n\n饹饤֥\n\n  array.c\n  bignum.c\n  compar.c\n  dir.c\n  enum.c\n  file.c\n  hash.c\n  io.c\n  marshal.c\n  math.c\n  numeric.c\n  pack.c\n  prec.c\n  process.c\n  random.c\n  range.c\n  re.c\n  signal.c\n  sprintf.c\n  string.c\n  struct.c\n  time.c\n\nAppendix B. ĥѴؿե\n\nC줫RubyεǽѤAPIϰʲ̤Ǥ롥\n\n** \n\nVALUE\n\n  Ruby֥Ȥɽ뷿ɬפ˱ƥ㥹ȤѤ롥\n  Ȥ߹߷ɽCηruby.h˵ҤƤRǻϤޤ빽¤\n  ΤǤ롥VALUE򤳤˥㥹Ȥ뤿RǻϤޤ빽¤\n  ̾ʸˤ̾ΥޥѰդƤ롥\n\n** ѿ\n\nQnil\n\n  : nil֥\n\nQtrue\n\n  : true֥(Υǥե)\n\nQfalse\n\n  : false֥\n\n** CǡΥץ벽\n\nData_Wrap_Struct(VALUE klass, void (*mark)(), void (*free)(), void *sval)\n\n  CǤդΥݥ󥿤򥫥ץ벽Ruby֥Ȥ֤\n  Υݥ󥿤Ruby饢ʤʤäfreeǻꤷ\n  ؿƤФ롥ޤΥݥ󥿤λؤǡ¾Ruby\n  ȤؤƤ硤mark˻ꤹؿǥޡɬ\n  롥\n\nData_Make_Struct(klass, type, mark, free, sval)\n\n  typeΥmallocѿsval塤򥫥ץ\n  벽ǡ֤ޥ\n\nData_Get_Struct(data, type, sval)\n\n  datatypeΥݥ󥿤Фѿsvalޥ\n\n** å\n\nTYPE(value)\nFIXNUM_P(value)\nNIL_P(value)\nvoid Check_Type(VALUE value, int type)\nvoid Check_SafeStr(VALUE value)\n\n** Ѵ\n\nFIX2INT(value)\nINT2FIX(i)\nNUM2INT(value)\nINT2NUM(i)\nNUM2DBL(value)\nrb_float_new(f)\nStringValue(value)\nStringValuePtr(value)\nStringValueCStr(value)\nrb_str_new2(s)\n\n** 饹/⥸塼\n\nVALUE rb_define_class(const char *name, VALUE super)\n\n  superΥ֥饹ȤƿRuby饹롥\n\nVALUE rb_define_class_under(VALUE module, const char *name, VALUE super)\n\n  superΥ֥饹ȤƿRuby饹module\n  Ȥ롥\n\nVALUE rb_define_module(const char *name)\n\n  Ruby⥸塼롥\n\nVALUE rb_define_module_under(VALUE module, const char *name)\n\n  Ruby⥸塼moduleȤ롥\n\nvoid rb_include_module(VALUE klass, VALUE module)\n\n  ⥸塼򥤥󥯥롼ɤ롥classǤmodule򥤥\n  롼ɤƤˤϲ⤷ʤ(¿ť󥯥롼ɤζػ)\n\nvoid rb_extend_object(VALUE object, VALUE module)\n\n  ֥Ȥ⥸塼(Ƥ᥽å)ǳĥ롥\n\n** ѿ\n\nvoid rb_define_variable(const char *name, VALUE *var)\n\n  RubyCȤǶͭ륰Хѿ롥ѿ̾`$'\n  ϤޤʤˤϼưŪɲä롥nameȤRubyμ̻\n  ȤƵʤʸ(㤨` ')ޤˤRubyץ\n  फϸʤʤ롥\n\nvoid rb_define_readonly_variable(const char *name, VALUE *var)\n\n  RubyCȤǶͭread onlyΥХѿ롥\n  read onlyǤ뤳Ȱʳrb_define_variable()Ʊ\n\nvoid rb_define_virtual_variable(const char *name,\n\t\t\t\tVALUE (*getter)(), void (*setter)())\n\n  ؿˤäƼ¸Rubyѿ롥ѿȤ줿\n  ˤgetterѿͤåȤ줿ˤsetterƤФ\n  롥\n\nvoid rb_define_hooked_variable(const char *name, VALUE *var,\n\t\t\t       VALUE (*getter)(), void (*setter)())\n\n  ؿˤähookΤĤ줿Хѿ롥ѿ\n  Ȥ줿ˤgetterؿͤåȤ줿ˤ\n  setterƤФ롥gettersetter0ꤷˤhook\n  ꤷʤΤƱˤʤ롥\n\nvoid rb_global_variable(VALUE *var)\n\n  GCΤᡤRubyץफϥʤ, Ruby\n  Ȥޤѿޡ롥\n\n** \n\nvoid rb_define_const(VALUE klass, const char *name, VALUE val)\n\n  롥\n\nvoid rb_define_global_const(const char *name, VALUE val)\n\n  롥\n\n     rb_define_const(rb_cObject, name, val)\n\n  Ʊ̣\n\n** ᥽å\n\nrb_define_method(VALUE klass, const char *name, VALUE (*func)(), int argc)\n\n  ᥽åɤ롥argcselfοargc-1λ, \n  ؿˤϰο(selfޤޤʤ)1, 2\n  ȤͿ(3self)argc-2λ, \n  1self, 2args(argsϰޤRuby)\n  Ϳ롥\n \nrb_define_private_method(VALUE klass, const char *name, VALUE (*func)(), int argc)\n\n  private᥽åɤ롥rb_define_method()Ʊ\n\nrb_define_singleton_method(VALUE klass, const char *name, VALUE (*func)(), int argc)\n\n  ðۥ᥽åɤ롥rb_define_method()Ʊ\n\nrb_scan_args(int argc, VALUE *argv, const char *fmt, ...)\n\n  argc, argvͿ줿ʬ򤹤롥fmtɬܰο, \n  ղðο, Ĥΰ뤫ꤹʸ, \"\n  *\"ȤǤ롥 2 ܤο\"*\"Ϥ줾ά\n  ǽǤ롥ɬܰĤʤ0ꤹ롥3\n  ߤѿؤΥݥ󥿤, Ǥѿ˳Ǽ롥\n  ղðбͿƤʤѿQnil\n  롥\n\n** Ruby᥽åɸƤӽФ\n\nVALUE rb_funcall(VALUE recv, ID mid, int narg, ...)\n\n  ᥽åɸƤӽФʸ󤫤mid뤿ˤrb_intern()\n  Ȥ\n\nVALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)\n\n  ᥽åɸƤӽФargc, argvϤ\n\nVALUE rb_eval_string(const char *str)\n\n  ʸRubyץȤȤƥѥ롦¹Ԥ롥\n\nID rb_intern(const char *name)\n\n  ʸбID֤\n\nchar *rb_id2name(ID id)\n\n  IDбʸ֤(ǥХå)\n\nchar *rb_class2name(VALUE klass)\n\n  饹֤̾(ǥХå)饹̾ʤˤ, \n  ̤ä̾ĥ饹֤̾\n\nint rb_respond_to(VALUE obj, ID id)\n\n  objidǼ᥽åɤĤɤ֤\n\n** 󥹥ѿ\n\nVALUE rb_iv_get(VALUE obj, const char *name)\n\n  objΥ󥹥ѿͤ롥`@'ǻϤޤʤ󥹥\n  ѿ Rubyץफ饢Ǥʤֱ줿ץ\n  ѿˤʤ롥ʸ̾ĥ饹(ޤ\n  ⥸塼)Υ󥹥ѿȤƼƤ롥\n\nVALUE rb_iv_set(VALUE obj, const char *name, VALUE val)\n\n  objΥ󥹥ѿval˥åȤ롥\n\n** 湽¤\n\nVALUE rb_iterate(VALUE (*func1)(), VALUE arg1, VALUE (*func2)(), VALUE arg2)\n\n  func2֥åȤꤷ, func1򥤥ƥ졼ȤƸƤ֡ \n  func1ˤ arg1ȤϤ, func2ˤ1˥ƥ졼\n  Ϳ줿, 2arg2Ϥ롥\n \nVALUE rb_yield(VALUE val)\n\n  valͤȤƥƥ졼֥åƤӽФ\n\nVALUE rb_rescue(VALUE (*func1)(), VALUE arg1, VALUE (*func2)(), VALUE arg2)\n\n  ؿfunc1arg1˸ƤӽФfunc1μ¹㳰ȯ\n  ˤ func2arg2ȤƸƤ֡ͤ㳰ȯ\n  ʤäfunc1, 㳰ȯˤfunc2\n  ͤǤ롥\n\nVALUE rb_ensure(VALUE (*func1)(), VALUE arg1, void (*func2)(), VALUE arg2)\n\n  ؿfunc1arg1ȤƼ¹Ԥ, ¹Խλ(Ȥ㳰\n  ȯƤ) func2arg2ȤƼ¹Ԥ롥ͤfunc1\n  ͤǤ(㳰ȯʤ)\n\n** 㳰顼\n\nvoid rb_warning(const char *fmt, ...)\n\n  rb_verboseɸ२顼Ϥ˷ٹɽ롥\n  printf()Ʊ\n\nvoid rb_raise(rb_eRuntimeError, const char *fmt, ...)\n\n  RuntimeError㳰ȯ롥printf()Ʊ\n\nvoid rb_raise(VALUE exception, const char *fmt, ...)\n\n  exceptionǻꤷ㳰ȯ롥fmtʲΰ\n  printf()Ʊ\n\nvoid rb_fatal(const char *fmt, ...)\n\n  ̿Ū㳰ȯ롥̾㳰ϹԤʤ줺, 󥿡\n  ץ꥿λ(ensureǻꤵ줿ɤϽλ\n  ¹Ԥ)\n\nvoid rb_bug(const char *fmt, ...)\n\n  󥿡ץ꥿ʤɥץΥХǤȯϤΤʤ\n  λƤ֡󥿡ץ꥿ϥפľ˽λ롥\n  㳰ϰڹԤʤʤ\n\n** Rubyν¹\n\nRuby򥢥ץꥱˤϰʲΥ󥿥ե\nȤ̾γĥ饤֥ˤɬפʤ\n\nvoid ruby_init()\n\n  Ruby󥿥ץ꥿νԤʤ\n\nvoid ruby_options(int argc, char **argv)\n\n  Ruby󥿥ץ꥿Υޥɥ饤νԤʤ\n\nvoid ruby_run()\n\n  Ruby󥿥ץ꥿¹Ԥ롥\n\nvoid ruby_script(char *name)\n\n  RubyΥץ̾($0)ꤹ롥\n\n\nAppendix C. extconf.rbǻȤؿ\n\nextconf.rbǤѲǽʥѥåδؿϰ\n̤Ǥ롥\n\nhave_macro(macro, headers)\n\n  إåեheader򥤥󥯥롼ɤƥޥmacro\n  Ƥ뤫ɤå롥ޥƤtrue\n  ֤\n\nhave_library(lib, func)\n\n  ؿfuncƤ饤֥lib¸ߤå롥\n  饤֥꤬¸ߤtrue֤\n\nfind_library(lib, func, path...)\n\n  ؿfuncƤ饤֥lib¸ߤ -Lpath ɲ\n  ʤå롥饤֥꤬դätrue֤\n\nhave_func(func, header)\n\n  إåեheader򥤥󥯥롼ɤƴؿfunc¸ߤ\n  롥funcɸǤϥ󥯤ʤ饤֥ΤΤǤ\n  ˤhave_libraryǤΥ饤֥åƤ\n  ؿ¸ߤtrue֤\n\nhave_var(var, header)\n\n  إåեheader򥤥󥯥롼ɤѿvar¸ߤ\n  롥varɸǤϥ󥯤ʤ饤֥ΤΤǤ\n  ˤhave_libraryǤΥ饤֥åƤ\n  ѿ¸ߤtrue֤\n\nhave_header(header)\n\n  إåե¸ߤå롥إåե뤬¸ߤ\n  true֤\n\nfind_header(header, path...)\n\n  إåեheader¸ߤ -Ipath ɲäʤå\n  롥إåե뤬դätrue֤\n\nhave_struct_member(type, member, header)\n\n  إåեheader򥤥󥯥롼ɤƷtype˥member\n  ¸ߤ뤫å롥typeƤơmember\n  Ĥtrue֤\n\nhave_type(type, header, opt)\n\n  إåեheader򥤥󥯥롼ɤƷtype¸ߤ뤫\n  å롥typeƤtrue֤\n\ncheck_sizeof(type, header)\n\n  إåեheader򥤥󥯥롼ɤƷtypecharñ̥\n  Ĵ٤롥typeƤΥ֤\n  ƤʤȤnil֤\n\ncreate_makefile(target)\n\n  ĥ饤֥ѤMakefile롥δؿƤФʤ\n  ФΥ饤֥ϥѥ뤵ʤtargetϥ⥸塼̾\n  ɽ\n\nfind_executable(command, path)\n\n  ޥcommandFile::PATH_SEPARATORǶڤ줿ѥ̾\n  ꥹpathõpathnilޤϾά줿ϡĶ\n  ѿPATHͤѤ롥¹ԲǽʥޥɤĤä\n  ϥѥޤե̾Ĥʤänil֤\n\nwith_config(withval[, default=nil])\n\n  ޥɥ饤--with-<withval>ǻꤵ줿ץͤ롥\n\nenable_config(config, *defaults)\ndisable_config(config, *defaults)\n\n  ޥɥ饤--enable-<config>ޤ\n  --disable-<config>ǻꤵ줿ͤ롥\n  --enable-<config>ꤵƤtrue\n  --disable-<config>ꤵƤfalse֤\n  ɤꤵƤʤϡ֥åĤǸƤӽФƤ\n  *defaultsyield̡֥åʤʤ*defaults֤\n\ndir_config(target[, default_dir])\ndir_config(target[, default_include, default_lib])\n\n  ޥɥ饤--with-<target>-dir, --with-<target>-include,\n  --with-<target>-libΤ줫ǻꤵǥ쥯ȥ\n  $CFLAGS  $LDFLAGS ɲä롥--with-<target>-dir=/path\n  --with-<target>-include=/path/include --with-<target>-lib=/path/lib\n  Ǥ롥ɲä줿 include ǥ쥯ȥ lib ǥ쥯ȥ\n  ֤ ([include_dir, lib_dir])\n\npkg_config(pkg)\n\n  pkg-configޥɤѥåpkgξ롥 \n  pkg-configμºݤΥޥ̾ϡ--with-pkg-configޥ\n  饤󥪥ץǻǽ\n\n/*\n * Local variables:\n * fill-column: 60\n * end:\n */\n"
  },
  {
    "path": "README.ja",
    "content": "* RubyȤ\n\nRubyϥץ뤫ĶϤʥ֥ȻظץȸǤ\nRubyϺǽ餫ʥ֥ȻظȤ߷פƤ\n顤֥Ȼظץߥ󥰤ڤ˹Ԥ\n̾μ³Υץߥ󥰤ǽǤ\n\nRubyϥƥȽطǽϤʤɤͥ졤PerlƱ餤\nǤ˥ץʸˡȡ㳰䥤ƥ졼ʤɤε\nˤäơʬ䤹ץߥ󥰤ޤ\n\n\n* RubyĹ\n\n  + ץʸˡ\n  + ̤Υ֥Ȼظǽ(饹᥽åɥʤ)\n  + üʥ֥Ȼظǽ(Mixin, ðۥ᥽åɤʤ)\n  + 黻ҥС\n  + 㳰ǽ\n  + ƥ졼ȥ\n  + ١쥯\n  + ʥߥåǥ (ƥˤ)\n  + ܿ⤤¿UNIXưǤʤDOSWindows\n    MacBeOSʤɤξǤư\n\n\n* ˡ\n\n** FTP\n\nʲξˤƤޤ\n\n  ftp://ftp.ruby-lang.org/pub/ruby/\n\n** Subversion\n\nܥ֥RubyκǿΥɤϼΥޥɤǼǤޤ\n\n  $ svn co http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/\n\nȯüΥɤϼΥޥɤǼǤޤ\n\n  $ svn co http://svn.ruby-lang.org/repos/ruby/trunk/ ruby\n\n¾˳ȯΥ֥ΰϼΥޥɤǸޤ\n\n  $ svn ls http://svn.ruby-lang.org/repos/ruby/branches/\n\n\n* ۡڡ\n\nRubyΥۡڡURL\n\n   http://www.ruby-lang.org/\n\nǤ\n\n\n* ᡼󥰥ꥹ\n\nRubyΥ᡼󥰥ꥹȤޤô˾\n\n   ruby-list-ctl@ruby-lang.org\n\nޤʸ\n\n   subscribe YourFirstName YourFamilyName\n   \nȽ񤤤äƲ \n\nRubyȯԸ᡼󥰥ꥹȤ⤢ޤǤrubyΥ\nλͳĥʤɼˤĤƵƤޤ\nô˾\n\n   ruby-dev-ctl@ruby-lang.org\n\nޤruby-listƱͤˡǥ᡼뤷Ƥ \n\nRubyĥ⥸塼ˤĤä礦ruby-ext᡼󥰥ꥹȤ\nشطˤĤä礦ruby-math᡼󥰥ꥹȤ\nѸä礦ruby-talk᡼󥰥ꥹȤ⤢ޤˡ\nϤɤƱǤ \n\n\n* ѥ롦󥹥ȡ\n\nʲμǹԤäƤ\n\n  1. ⤷configureե뤬Ĥʤ⤷\n     configure.inŤ褦ʤ顢autoconf¹Ԥ\n     configure\n\n  2. configure¹ԤMakefileʤɤ\n\n     ĶˤäƤϥǥեȤCѥѥץդ\n     ޤconfigureץ optflags=.. warnflags=.. \n     Ǿ񤭤Ǥޤ\n\n  3. (ɬפʤ)defines.hԽ\n\n     ¿ʬɬ̵Ȼפޤ\n\n  4. (ɬפʤ)ext/SetupŪ˥󥯤ĥ⥸塼\n     ꤹ\n\n     ext/Setup˵Ҥ⥸塼Ū˥󥯤ޤ\n\n     ʥߥåǥ󥰤򥵥ݡȤƤʤƥ\n     ǤSetup1ܤΡoption nodynamicפȤԤΥ\n     Ȥ򳰤ɬפޤޤΥƥ\n     ĥ⥸塼Ѥ뤿ˤϡ餫Ū˥\n     Ƥɬפޤ\n\n  5. make¹Ԥƥѥ뤹\n\n  6. make testǥƥȤԤ\n\n     test succeededפɽǤƥ\n     ƤⴰݾڤƤǤϤޤ\n\n  7. make install\n\n     rootǺȤɬפ뤫⤷ޤ\n\n⤷ѥ˥顼ȯˤϥ顼Υȥ\nOSμޤǤܤݡȤԤäƤ\n¾Τˤʤޤ\n\n\n* ܿ\n\nUNIXǤconfigureۤȤɤκۤۼƤϤ\nפ̸Ȥä(˰㤤ʤ)Ԥˤ\nȤݡȤСǤ뤫Τޤ\n\nƥˤäȤ¸ΤGCǤRubyGCо\nΥƥ㤬setjmp()ˤäƤΥ쥸 jmp_buf\nǼ뤳Ȥȡjmp_bufȥå32bit饤Ȥ\n뤳ȤꤷƤޤäԤΩʤб\n˺Ǥ礦ԤβŪñǡgc.cǥå\nޡƤʬ˥饤ȤΥХȿ餷ƥޡ\n륳ɤɲäǺѤߤޤdefined(THINK_C)פ\nƤʬ򻲹ͤˤƤ\n\n# ºݤˤRubyThink CǤϥѥǤޤ\n\n쥸ɥCPUǤϡ쥸ɥ򥹥\n˥եå夹륢֥饳ɤɲäɬפ뤫\nޤ\n\n\n* ۾\n\nCOPYING.jaե򻲾ȤƤ\n\n\n* \n\nȡХݡȤ¾ matz@netlab.jp ޤǡ\n-------------------------------------------------------\ncreated at: Thu Aug  3 11:57:36 JST 1995\nLocal variables:\nmode: indented-text\nend:\n"
  },
  {
    "path": "Rakefile",
    "content": "require 'distro/tasks'"
  },
  {
    "path": "ToDo",
    "content": "Language Spec.\n\n- Class#allocate - basicNew\n- class Foo::Bar<Baz .. end, module Boo::Bar .. end\n* operator !! for rescue. ???\n* objectify characters\n* ../... outside condition invokes operator method too.\n* ... inside condition turns off just before right condition.???\n* package or access control for global variables??\n* named arguments like foo(nation:=\"german\") or foo(nation: \"german\").\n* method to retrieve argument information (needs new C API)\n* multiple return values, yield values.  maybe incompatible ???\n* cascading method invocation ???\n* def Class#method .. end ??\n* def Foo::Bar::baz() .. end ??\n* I18N (or M17N) script/string/regexp\n* Fixnum 0 as false ????\n* discourage use of symbol variables (e.g. $/, etc.) in manual\n* discourage use of Perlish features by giving warnings.\n* non confusing in-block local variable (is it possible?)\n  + remove scope by block\n  + variables appears within block may have independent values.\n* Regexp: make /o thread safe.\n* decide whether begin with rescue or ensure make do..while loop.\n* a +1 to be a+1, not a(+1).\n* unify == and eql? again\n* to_i returns nil if str contains no digit.\n* raise exception by `` error\n* jar like combined library package. -> RubyGems?\n* resumable Exception via Exception#resume.\n* method combination, e.g. before, after, around, etc.\n* .. or something like defadvice in Emacs.\n* property - for methods, or for objects in general.\n* \"in\" modifier, to annotate, or to encourage assertion.\n* selector namespace - something like generic-flet in CLOS, to help RubyBehavior\n* private instance variable (as in Python?) @_foo in class Foo => @_Foo_foo\n* warn/error \"bare word\" method, like \"foo\",  you should type \"foo()\"\n* clarify evaluation order of operator argument (=~, .., ...)\n* :symbol => value hash in the form of {symbol: value, ...} ??\n\nHacking Interpreter\n\n- generational GC\n* non-blocking open (e.g. for named pipe) for thread\n* avoid blocking with gethostbyname/gethostbyaddr (use fork ???)\n* objectify interpreters ???\n* remove rb_eval() recursions\n* syntax tree -> bytecode ???\n* scrambled script, or script filter\n* setuid ruby\n* performance tune for in-block (dynamic) local variables.\n* give warnings to assign magic variables.\n* export rb_io_{addstr,printf,puts,print}\n* autoload should work with threads [ruby-talk:4589]\n* remove stdio dependency from IOs.\n* warn for inconsistent local variable usage (lv m and method m at the same time). \n* MicroRuby\n* Built-in Interactive Ruby.\n* Parser API\n* trap every method invocation, which can be enabled by e.g. trap_call :method.\n* unify Errno exceptions of same errno, or new exception comparison scheme.\n* 2.times{|i| if i==0 then a = 15 else puts eval(\"a\") end} should print nil.\n* Thread#max_stack_size attribute (possible??)\n\nStandard Libraries\n\n- Module#define_method which takes a name and a body (block, proc or method).\n- Enume#inject\n- Array#fetch\n- IO::for_fd\n- Process::waitall [ruby-talk:4557]\n- Process::Status\n- File::lchown, File::lchmod; xxx - still need work for non existing platforms\n- move Time::times to Process.\n- Enumerable#sort_by for Schwartzian transformation\n- fork_and_kill_other_threads.\n- signal list (Signal::trap, Signal::list).\n- move NameError under StandardError.\n- Integer#to_s(base)\n- Hash::new{default}\n- hash etc. should handle self referenceing array/hash\n- Array#select(n1,n2...) works like Array#indexes(n1,n2...)\n- use Mersenne Twister RNG for random.\n- deprecate Array#indexes, and Array#indices.\n- remove dependency on MAXPATHLEN.\n* String#scanf(?)\n* Object#fmt(?)\n* Time::strptime\n* Integer[num], Float[num];  Fixnum[num]?\n* method to retrieve non-number trailer for to_i/to_f.\n* Stream or Port, abstract superclass of IO ?\n* String#{pred,prev}, String#downto\n* optional stepsize argument for succ()\n* Ruby module -- Ruby::Version, Ruby::Interpreter\n* introduce Boolean class; super of TrueClass, FalseClass\n* synchronized method - synchronized{...}, synchronized :foo, :bar\n* Array#&, Array#| to allow duplication. ???\n* way to specify immortal (fork endurance) thread;\n* or raise ForkException to every thread but fork caller.\n* new user-defined marshal scheme. _dump(dumper), _load(restorer)\n* library to load per-user profile seeking .ruby_profile or ruby.ini file.\n* warning framework (warn, warning for Ruby level)\n* marshal should not depend on sprintf (works bad with locale).\n* ternary arg pow: a.pow(b,c) == a**b%c\n* new caller(), e.g. call_stack; needs better name.\n* pointer share mechanism similar to one in String for Array.\n* require \"1.6\" etc. by /usr/lib/ruby/1.6/1.6.rb ;-)\n* save both \"feature names\" and \"normalized path\" in $\"\n* implement Mutex_m (or MutexMixin) using Mutex.\n\nExtension Libraries\n\n* ptk.rb pTk wrapper that is compatible to tk.rb\n* Berkeley DB extension\n* BitVector\n* thread-safe fcgi\n\nRuby Libraries\n\n* urllib.rb, nttplib.rb, etc.\n* format like perl's\n\nTools\n\n* freeze or undump to bundle everything\n* bundle using zlib\n"
  },
  {
    "path": "array.c",
    "content": "/**********************************************************************\n\n  array.c -\n\n  $Author$\n  $Date$\n  created at: Fri Aug  6 09:46:12 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"util.h\"\n#include \"st.h\"\n\nVALUE rb_cArray;\nstatic ID id_cmp;\n\n#define ARY_DEFAULT_SIZE 16\n#define ARY_MAX_SIZE (LONG_MAX / sizeof(VALUE))\n\nvoid\nrb_mem_clear(mem, size)\n    register VALUE *mem;\n    register long size;\n{\n    while (size--) {\n\t*mem++ = Qnil;\n    }\n}\n\nstatic inline void\nmemfill(mem, size, val)\n    register VALUE *mem;\n    register long size;\n    register VALUE val;\n{\n    while (size--) {\n\t*mem++ = val;\n    }\n}\n\n#define ARY_TMPLOCK  FL_USER1\n\nstatic inline void\nrb_ary_modify_check(ary)\n    VALUE ary;\n{\n    if (OBJ_FROZEN(ary)) rb_error_frozen(\"array\");\n    if (FL_TEST(ary, ARY_TMPLOCK))\n\trb_raise(rb_eRuntimeError, \"can't modify array during iteration\");\n    if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify array\");\n}\n\nstatic void\nrb_ary_modify(ary)\n    VALUE ary;\n{\n    VALUE *ptr;\n\n    rb_ary_modify_check(ary);\n    if (FL_TEST(ary, ELTS_SHARED)) {\n\tptr = ALLOC_N(VALUE, RARRAY(ary)->len);\n\tFL_UNSET(ary, ELTS_SHARED);\n\tRARRAY(ary)->aux.capa = RARRAY(ary)->len;\n\tMEMCPY(ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);\n\tRARRAY(ary)->ptr = ptr;\n    }\n}\n\nVALUE\nrb_ary_freeze(ary)\n    VALUE ary;\n{\n    return rb_obj_freeze(ary);\n}\n\n/*\n *  call-seq:\n *     array.frozen?  -> true or false\n *\n *  Return <code>true</code> if this array is frozen (or temporarily frozen\n *  while being sorted).\n */\n\nstatic VALUE\nrb_ary_frozen_p(ary)\n    VALUE ary;\n{\n    if (OBJ_FROZEN(ary)) return Qtrue;\n    if (FL_TEST(ary, ARY_TMPLOCK)) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE ary_alloc _((VALUE));\nstatic VALUE\nary_alloc(klass)\n    VALUE klass;\n{\n    NEWOBJ(ary, struct RArray);\n    OBJSETUP(ary, klass, T_ARRAY);\n\n    ary->len = 0;\n    ary->ptr = 0;\n    ary->aux.capa = 0;\n\n    return (VALUE)ary;\n}\n\nstatic VALUE\nary_new(klass, len)\n    VALUE klass;\n    long len;\n{\n    VALUE ary = ary_alloc(klass);\n\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"negative array size (or size too big)\");\n    }\n    if (len > ARY_MAX_SIZE) {\n\trb_raise(rb_eArgError, \"array size too big\");\n    }\n    if (len == 0) len++;\n    RARRAY(ary)->ptr = ALLOC_N(VALUE, len);\n    RARRAY(ary)->aux.capa = len;\n\n    return ary;\n}\n\nVALUE\nrb_ary_new2(len)\n    long len;\n{\n    return ary_new(rb_cArray, len);\n}\n\n\nVALUE\nrb_ary_new()\n{\n    return rb_ary_new2(ARY_DEFAULT_SIZE);\n}\n\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_ary_new3(long n, ...)\n#else\nrb_ary_new3(n, va_alist)\n    long n;\n    va_dcl\n#endif\n{\n    va_list ar;\n    VALUE ary;\n    long i;\n\n    ary = rb_ary_new2(n);\n\n    va_init_list(ar, n);\n    for (i=0; i<n; i++) {\n\tRARRAY(ary)->ptr[i] = va_arg(ar, VALUE);\n    }\n    va_end(ar);\n\n    RARRAY(ary)->len = n;\n    return ary;\n}\n\nVALUE\nrb_ary_new4(n, elts)\n    long n;\n    const VALUE *elts;\n{\n    VALUE ary;\n\n    ary = rb_ary_new2(n);\n    if (n > 0 && elts) {\n\tMEMCPY(RARRAY(ary)->ptr, elts, VALUE, n);\n    }\n\n    /* This assignment to len will be moved to the above \"if\" block in Ruby 1.9 */\n    RARRAY(ary)->len = n;\n\n    return ary;\n}\n\nstatic VALUE\nary_make_shared(ary)\n    VALUE ary;\n{\n    if (!FL_TEST(ary, ELTS_SHARED)) {\n\tNEWOBJ(shared, struct RArray);\n\tOBJSETUP(shared, rb_cArray, T_ARRAY);\n\n\tshared->len = RARRAY(ary)->len;\n\tshared->ptr = RARRAY(ary)->ptr;\n\tshared->aux.capa = RARRAY(ary)->aux.capa;\n\tRARRAY(ary)->aux.shared = (VALUE)shared;\n\tFL_SET(ary, ELTS_SHARED);\n\tOBJ_FREEZE(shared);\n\treturn (VALUE)shared;\n    }\n    else {\n\treturn RARRAY(ary)->aux.shared;\n    }\n}\n\nVALUE\nrb_assoc_new(car, cdr)\n    VALUE car, cdr;\n{\n    VALUE ary;\n\n    ary = rb_ary_new2(2);\n    RARRAY(ary)->ptr[0] = car;\n    RARRAY(ary)->ptr[1] = cdr;\n    RARRAY(ary)->len = 2;\n\n    return ary;\n}\n\nstatic VALUE\nto_ary(ary)\n    VALUE ary;\n{\n    return rb_convert_type(ary, T_ARRAY, \"Array\", \"to_ary\");\n}\n\nVALUE\nrb_check_array_type(ary)\n    VALUE ary;\n{\n    return rb_check_convert_type(ary, T_ARRAY, \"Array\", \"to_ary\");\n}\n\nstatic VALUE rb_ary_replace _((VALUE, VALUE));\n\n/*\n *  call-seq:\n *     Array.new(size=0, obj=nil)\n *     Array.new(array)\n *     Array.new(size) {|index| block }\n *\n *  Returns a new array. In the first form, the new array is\n *  empty. In the second it is created with _size_ copies of _obj_\n *  (that is, _size_ references to the same\n *  _obj_). The third form creates a copy of the array\n *  passed as a parameter (the array is generated by calling\n *  to_ary  on the parameter). In the last form, an array\n *  of the given size is created. Each element in this array is\n *  calculated by passing the element's index to the given block and\n *  storing the return value.\n *\n *     Array.new\n *     Array.new(2)\n *     Array.new(5, \"A\")\n * \n *     # only one copy of the object is created\n *     a = Array.new(2, Hash.new)\n *     a[0]['cat'] = 'feline'\n *     a\n *     a[1]['cat'] = 'Felix'\n *     a\n * \n *     # here multiple copies are created\n *     a = Array.new(2) { Hash.new }\n *     a[0]['cat'] = 'feline'\n *     a\n * \n *     squares = Array.new(5) {|i| i*i}\n *     squares\n * \n *     copy = Array.new(squares)\n */\n\nstatic VALUE\nrb_ary_initialize(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    long len;\n    VALUE size, val;\n\n    rb_ary_modify(ary);\n    if (rb_scan_args(argc, argv, \"02\", &size, &val) == 0) {\n\tRARRAY(ary)->len = 0;\n\tif (rb_block_given_p()) {\n\t    rb_warning(\"given block not used\");\n\t}\n\treturn ary;\n    }\n\n    if (argc == 1 && !FIXNUM_P(size)) {\n\tval = rb_check_array_type(size);\n\tif (!NIL_P(val)) {\n\t    rb_ary_replace(ary, val);\n\t    return ary;\n\t}\n    }\n\n    len = NUM2LONG(size);\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"negative array size\");\n    }\n    if (len > ARY_MAX_SIZE) {\n\trb_raise(rb_eArgError, \"array size too big\");\n    }\n    if (len > RARRAY(ary)->aux.capa) {\n\tREALLOC_N(RARRAY(ary)->ptr, VALUE, len);\n\tRARRAY(ary)->aux.capa = len;\n    }\n    if (rb_block_given_p()) {\n\tlong i;\n\n\tif (argc == 2) {\n\t    rb_warn(\"block supersedes default value argument\");\n\t}\n\tfor (i=0; i<len; i++) {\n\t    rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));\n\t    RARRAY(ary)->len = i + 1;\n\t}\n    }\n    else {\n\tmemfill(RARRAY(ary)->ptr, len, val);\n\tRARRAY(ary)->len = len;\n    }\n\n    return ary;\n}\n\n\n/* \n* Returns a new array populated with the given objects. \n*\n*   Array.[]( 1, 'a', /^A/ )\n*   Array[ 1, 'a', /^A/ ]\n*   [ 1, 'a', /^A/ ]\n*/\n\nstatic VALUE\nrb_ary_s_create(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE ary = ary_alloc(klass);\n\n    if (argc > 0) {\n\tRARRAY(ary)->ptr = ALLOC_N(VALUE, argc);\n\tMEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);\n    }\n    RARRAY(ary)->len = RARRAY(ary)->aux.capa = argc;\n\n    return ary;\n}\n\nvoid\nrb_ary_store(ary, idx, val)\n    VALUE ary;\n    long idx;\n    VALUE val;\n{\n    if (idx < 0) {\n\tidx += RARRAY(ary)->len;\n\tif (idx < 0) {\n\t    rb_raise(rb_eIndexError, \"index %ld out of array\",\n\t\t    idx - RARRAY(ary)->len);\n\t}\n    }\n    else if (idx >= ARY_MAX_SIZE) {\n\trb_raise(rb_eIndexError, \"index %ld too big\", idx);\n    }\n\n    rb_ary_modify(ary);\n    if (idx >= RARRAY(ary)->aux.capa) {\n\tlong new_capa = RARRAY(ary)->aux.capa / 2;\n\n\tif (new_capa < ARY_DEFAULT_SIZE) {\n\t    new_capa = ARY_DEFAULT_SIZE;\n\t}\n\tif (new_capa >= ARY_MAX_SIZE - idx) {\n\t    new_capa = (ARY_MAX_SIZE - idx) / 2;\n\t}\n\tnew_capa += idx;\n\tREALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);\n\tRARRAY(ary)->aux.capa = new_capa;\n    }\n    if (idx > RARRAY(ary)->len) {\n\trb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len,\n\t\t     idx-RARRAY(ary)->len + 1);\n    }\n\n    if (idx >= RARRAY(ary)->len) {\n\tRARRAY(ary)->len = idx + 1;\n    }\n    RARRAY(ary)->ptr[idx] = val;\n}\n\nstatic VALUE\nary_shared_array(klass, ary)\n    VALUE klass;\n    VALUE ary;\n{\n    VALUE val = ary_alloc(klass);\n\n    ary_make_shared(ary);\n    RARRAY(val)->ptr = RARRAY(ary)->ptr;\n    RARRAY(val)->len = RARRAY(ary)->len;\n    RARRAY(val)->aux.shared = RARRAY(ary)->aux.shared;\n    FL_SET(val, ELTS_SHARED);\n    return val;\n}\n\nstatic VALUE\nary_shared_first(argc, argv, ary, last)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n    int last;\n{\n    VALUE nv, result;\n    long n;\n    long offset = 0;\n\n    rb_scan_args(argc, argv, \"1\", &nv);\n    n = NUM2LONG(nv);\n    if (n > RARRAY(ary)->len) {\n\tn = RARRAY(ary)->len;\n    }\n    else if (n < 0) {\n\trb_raise(rb_eArgError, \"negative array size\");\n    }\n    if (last) {\n\toffset = RARRAY(ary)->len - n;\n    }\n    result = ary_shared_array(rb_cArray, ary);\n    RARRAY(result)->ptr += offset;\n    RARRAY(result)->len = n;\n\n    return result;\n}\n\n/*\n *  call-seq:\n *     array << obj            -> array\n *  \n *  Append---Pushes the given object on to the end of this array. This\n *  expression returns the array itself, so several appends\n *  may be chained together.\n *\n *     [ 1, 2 ] << \"c\" << \"d\" << [ 3, 4 ]\n *             #=>  [ 1, 2, \"c\", \"d\", [ 3, 4 ] ]\n *\n */\n\nVALUE\nrb_ary_push(ary, item)\n    VALUE ary;\n    VALUE item;\n{\n    rb_ary_store(ary, RARRAY(ary)->len, item);\n    return ary;\n}\n\n/* \n *  call-seq:\n *     array.push(obj, ... )   -> array\n *  \n *  Append---Pushes the given object(s) on to the end of this array. This\n *  expression returns the array itself, so several appends\n *  may be chained together.\n *\n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.push(\"d\", \"e\", \"f\")  \n *             #=> [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]\n */\n\nstatic VALUE\nrb_ary_push_m(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    while (argc--) {\n\trb_ary_push(ary, *argv++);\n    }\n    return ary;\n}\n\nVALUE\nrb_ary_pop(ary)\n    VALUE ary;\n{\n    rb_ary_modify_check(ary);\n    if (RARRAY(ary)->len == 0) return Qnil;\n    if (!FL_TEST(ary, ELTS_SHARED) &&\n\t    RARRAY(ary)->len * 3 < RARRAY(ary)->aux.capa &&\n\t    RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {\n\tRARRAY(ary)->aux.capa = RARRAY(ary)->len * 2;\n\tREALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);\n    }\n    return RARRAY(ary)->ptr[--RARRAY(ary)->len];\n}\n\n/*\n *  call-seq:\n *     array.pop    -> obj or nil\n *     array.pop(n) -> array\n *  \n *  Removes the last element from <i>self</i> and returns it, or\n *  <code>nil</code> if the array is empty.\n *\n *  If a number _n_ is given, returns an array of the last n elements\n *  (or less) just like <code>array.slice!(-n, n)</code> does.\n *     \n *     a = [ \"a\", \"b\", \"c\", \"d\" ]\n *     a.pop     #=> \"d\"\n *     a.pop(2)  #=> [\"b\", \"c\"]\n *     a         #=> [\"a\"]\n */\n\nstatic VALUE\nrb_ary_pop_m(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE result;\n\n    if (argc == 0) {\n\treturn rb_ary_pop(ary);\n    }\n\n    rb_ary_modify_check(ary);\n    result = ary_shared_first(argc, argv, ary, Qtrue);\n    RARRAY(ary)->len -= RARRAY(result)->len;\n    return result;\n}\n\nVALUE\nrb_ary_shift(ary)\n    VALUE ary;\n{\n    VALUE top;\n\n    rb_ary_modify_check(ary);\n    if (RARRAY(ary)->len == 0) return Qnil;\n    top = RARRAY(ary)->ptr[0];\n    if (!FL_TEST(ary, ELTS_SHARED)) {\n        if (RARRAY(ary)->len < ARY_DEFAULT_SIZE) {\n            MEMMOVE(RARRAY(ary)->ptr, RARRAY(ary)->ptr+1, VALUE, RARRAY(ary)->len-1);\n\t    RARRAY(ary)->len--;\n            return top;\n        }\n        RARRAY(ary)->ptr[0] = Qnil;\n\tary_make_shared(ary);\n    }\n    RARRAY(ary)->ptr++;\t\t/* shift ptr */\n    RARRAY(ary)->len--;\n\n    return top;\n}\n\n/*\n *  call-seq:\n *     array.shift    -> obj or nil\n *     array.shift(n) -> array\n *  \n *  Returns the first element of <i>self</i> and removes it (shifting all\n *  other elements down by one). Returns <code>nil</code> if the array\n *  is empty.\n *\n *  If a number _n_ is given, returns an array of the first n elements\n *  (or less) just like <code>array.slice!(0, n)</code> does.\n *     \n *     args = [ \"-m\", \"-q\", \"filename\" ]\n *     args.shift     #=> \"-m\"\n *     args           #=> [\"-q\", \"filename\"]\n *\n *     args = [ \"-m\", \"-q\", \"filename\" ]\n *     args.shift(2)  #=> [\"-m\", \"-q\"]\n *     args           #=> [\"filename\"]\n */\n\nstatic VALUE\nrb_ary_shift_m(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE result;\n    long n;\n\n    if (argc == 0) {\n\treturn rb_ary_shift(ary);\n    }\n\n    rb_ary_modify_check(ary);\n    result = ary_shared_first(argc, argv, ary, Qfalse);\n    n = RARRAY(result)->len;\n    if (FL_TEST(ary, ELTS_SHARED)) {\n\tRARRAY(ary)->ptr += n;\n\tRARRAY(ary)->len -= n;\n\t}\n    else {\n\tMEMMOVE(RARRAY(ary)->ptr, RARRAY(ary)->ptr+n, VALUE, RARRAY(ary)->len-n);\n\tRARRAY(ary)->len -= n;\n    }\n\n    return result;\n}\n\nVALUE\nrb_ary_unshift(ary, item)\n    VALUE ary, item;\n{\n    rb_ary_modify(ary);\n    if (RARRAY(ary)->len == RARRAY(ary)->aux.capa) {\n\tlong capa_inc = RARRAY(ary)->aux.capa / 2;\n\tif (capa_inc < ARY_DEFAULT_SIZE) {\n\t    capa_inc = ARY_DEFAULT_SIZE;\n\t}\n\tRARRAY(ary)->aux.capa += capa_inc;\n\tREALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);\n    }\n\n    /* sliding items */\n    MEMMOVE(RARRAY(ary)->ptr + 1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);\n\n    RARRAY(ary)->len++;\n    RARRAY(ary)->ptr[0] = item;\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.unshift(obj, ...)  -> array\n *  \n *  Prepends objects to the front of <i>array</i>.\n *  other elements up one.\n *     \n *     a = [ \"b\", \"c\", \"d\" ]\n *     a.unshift(\"a\")   #=> [\"a\", \"b\", \"c\", \"d\"]\n *     a.unshift(1, 2)  #=> [ 1, 2, \"a\", \"b\", \"c\", \"d\"]\n */\n\nstatic VALUE\nrb_ary_unshift_m(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    long len = RARRAY(ary)->len;\n\n    if (argc == 0) return ary;\n\n    /* make rooms by setting the last item */\n    rb_ary_store(ary, len + argc - 1, Qnil);\n\n    /* sliding items */\n    MEMMOVE(RARRAY(ary)->ptr + argc, RARRAY(ary)->ptr, VALUE, len);\n    MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);\n    \n    return ary;\n}\n\n/* faster version - use this if you don't need to treat negative offset */\nstatic inline VALUE\nrb_ary_elt(ary, offset)\n    VALUE ary;\n    long offset;\n{\n    if (RARRAY(ary)->len == 0) return Qnil;\n    if (offset < 0 || RARRAY(ary)->len <= offset) {\n\treturn Qnil;\n    }\n    return RARRAY(ary)->ptr[offset];\n}\n\nVALUE\nrb_ary_entry(ary, offset)\n    VALUE ary;\n    long offset;\n{\n    if (offset < 0) {\n\toffset += RARRAY(ary)->len;\n    }\n    return rb_ary_elt(ary, offset);\n}\n\nstatic VALUE\nrb_ary_subseq(ary, beg, len)\n    VALUE ary;\n    long beg, len;\n{\n    VALUE klass, ary2, shared;\n    VALUE *ptr;\n\n    if (beg > RARRAY(ary)->len) return Qnil;\n    if (beg < 0 || len < 0) return Qnil;\n\n    if (RARRAY(ary)->len < len || RARRAY(ary)->len < beg + len) {\n\tlen = RARRAY(ary)->len - beg;\n\tif (len < 0)\n\t    len = 0;\n    }\n    klass = rb_obj_class(ary);\n    if (len == 0) return ary_new(klass, 0);\n\n    shared = ary_make_shared(ary);\n    ptr = RARRAY(ary)->ptr;\n    ary2 = ary_alloc(klass);\n    RARRAY(ary2)->ptr = ptr + beg;\n    RARRAY(ary2)->len = len;\n    RARRAY(ary2)->aux.shared = shared;\n    FL_SET(ary2, ELTS_SHARED);\n\n    return ary2;\n}\n\n/* \n *  call-seq:\n *     array[index]                -> obj      or nil\n *     array[start, length]        -> an_array or nil\n *     array[range]                -> an_array or nil\n *     array.slice(index)          -> obj      or nil\n *     array.slice(start, length)  -> an_array or nil\n *     array.slice(range)          -> an_array or nil\n *\n *  Element Reference---Returns the element at _index_,\n *  or returns a subarray starting at _start_ and\n *  continuing for _length_ elements, or returns a subarray\n *  specified by _range_.\n *  Negative indices count backward from the end of the\n *  array (-1 is the last element). Returns nil if the index\n *  (or starting index) are out of range.\n *\n *     a = [ \"a\", \"b\", \"c\", \"d\", \"e\" ]\n *     a[2] +  a[0] + a[1]    #=> \"cab\"\n *     a[6]                   #=> nil\n *     a[1, 2]                #=> [ \"b\", \"c\" ]\n *     a[1..3]                #=> [ \"b\", \"c\", \"d\" ]\n *     a[4..7]                #=> [ \"e\" ]\n *     a[6..10]               #=> nil\n *     a[-3, 3]               #=> [ \"c\", \"d\", \"e\" ]\n *     # special cases\n *     a[5]                   #=> nil\n *     a[5, 1]                #=> []\n *     a[5..10]               #=> []\n *\n */\n\nVALUE\nrb_ary_aref(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE arg;\n    long beg, len;\n\n    if (argc == 2) {\n\tif (SYMBOL_P(argv[0])) {\n\t    rb_raise(rb_eTypeError, \"Symbol as array index\");\n\t}\n\tbeg = NUM2LONG(argv[0]);\n\tlen = NUM2LONG(argv[1]);\n\tif (beg < 0) {\n\t    beg += RARRAY(ary)->len;\n\t}\n\treturn rb_ary_subseq(ary, beg, len);\n    }\n    if (argc != 1) {\n\trb_scan_args(argc, argv, \"11\", 0, 0);\n    }\n    arg = argv[0];\n    /* special case - speeding up */\n    if (FIXNUM_P(arg)) {\n\treturn rb_ary_entry(ary, FIX2LONG(arg));\n    }\n    if (SYMBOL_P(arg)) {\n\trb_raise(rb_eTypeError, \"Symbol as array index\");\n    }\n    /* check if idx is Range */\n    switch (rb_range_beg_len(arg, &beg, &len, RARRAY(ary)->len, 0)) {\n      case Qfalse:\n\tbreak;\n      case Qnil:\n\treturn Qnil;\n      default:\n\treturn rb_ary_subseq(ary, beg, len);\n    }\n    return rb_ary_entry(ary, NUM2LONG(arg));\n}\n\n/* \n *  call-seq:\n *     array.at(index)   ->   obj  or nil\n *\n *  Returns the element at _index_. A\n *  negative index counts from the end of _self_.  Returns +nil+\n *  if the index is out of range. See also <code>Array#[]</code>.\n *  (<code>Array#at</code> is slightly faster than <code>Array#[]</code>,\n *  as it does not accept ranges and so on.)\n *\n *     a = [ \"a\", \"b\", \"c\", \"d\", \"e\" ]\n *     a.at(0)     #=> \"a\"\n *     a.at(-1)    #=> \"e\"\n */\n\nstatic VALUE\nrb_ary_at(ary, pos)\n    VALUE ary, pos;\n{\n    return rb_ary_entry(ary, NUM2LONG(pos));\n}\n\n/*\n *  call-seq:\n *     array.first   ->   obj or nil\n *     array.first(n) -> an_array\n *\n *  Returns the first element, or the first +n+ elements, of the array.\n *  If the array is empty, the first form returns <code>nil</code>, and the\n *  second form returns an empty array.\n *\n *     a = [ \"q\", \"r\", \"s\", \"t\" ]\n *     a.first    #=> \"q\"\n *     a.first(1) #=> [\"q\"]\n *     a.first(3) #=> [\"q\", \"r\", \"s\"]\n */\n\nstatic VALUE\nrb_ary_first(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    if (argc == 0) {\n\tif (RARRAY(ary)->len == 0) return Qnil;\n\treturn RARRAY(ary)->ptr[0];\n    }\n    else {\n\treturn ary_shared_first(argc, argv, ary, Qfalse);\n    }\n}\n\n/*\n *  call-seq:\n *     array.last     ->  obj or nil\n *     array.last(n)  ->  an_array\n *  \n *  Returns the last element(s) of <i>self</i>. If the array is empty,\n *  the first form returns <code>nil</code>.\n *     \n *     [ \"w\", \"x\", \"y\", \"z\" ].last   #=> \"z\"\n */\n\nstatic VALUE\nrb_ary_last(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    if (argc == 0) {\n\tif (RARRAY(ary)->len == 0) return Qnil;\n\treturn RARRAY(ary)->ptr[RARRAY(ary)->len-1];\n    }\n    else {\n\treturn ary_shared_first(argc, argv, ary, Qtrue);\n    }\n}\n\n/*\n *  call-seq:\n *     array.fetch(index)                    -> obj\n *     array.fetch(index, default )          -> obj\n *     array.fetch(index) {|index| block }   -> obj\n *  \n *  Tries to return the element at position <i>index</i>. If the index\n *  lies outside the array, the first form throws an\n *  <code>IndexError</code> exception, the second form returns\n *  <i>default</i>, and the third form returns the value of invoking\n *  the block, passing in the index. Negative values of <i>index</i>\n *  count from the end of the array.\n *     \n *     a = [ 11, 22, 33, 44 ]\n *     a.fetch(1)               #=> 22\n *     a.fetch(-1)              #=> 44\n *     a.fetch(4, 'cat')        #=> \"cat\"\n *     a.fetch(4) { |i| i*i }   #=> 16\n */\n\nstatic VALUE\nrb_ary_fetch(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE pos, ifnone;\n    long block_given;\n    long idx;\n\n    rb_scan_args(argc, argv, \"11\", &pos, &ifnone);\n    block_given = rb_block_given_p();\n    if (block_given && argc == 2) {\n\trb_warn(\"block supersedes default value argument\");\n    }\n    idx = NUM2LONG(pos);\n\n    if (idx < 0) {\n\tidx +=  RARRAY(ary)->len;\n    }\n    if (idx < 0 || RARRAY(ary)->len <= idx) {\n\tif (block_given) return rb_yield(pos);\n\tif (argc == 1) {\n\t    rb_raise(rb_eIndexError, \"index %ld out of array\", idx);\n\t}\n\treturn ifnone;\n    }\n    return RARRAY(ary)->ptr[idx];\n}\n\n/*\n *  call-seq:\n *     array.index(obj)           ->  int or nil\n *     array.index {|item| block} ->  int or nil\n *  \n *  Returns the index of the first object in <i>self</i> such that is\n *  <code>==</code> to <i>obj</i>. If a block is given instead of an\n *  argument, returns first object for which <em>block</em> is true.\n *  Returns <code>nil</code> if no match is found.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.index(\"b\")        #=> 1\n *     a.index(\"z\")        #=> nil\n *     a.index{|x|x==\"b\"}  #=> 1\n *\n *  This is an alias of <code>#find_index</code>.\n */\n\nstatic VALUE\nrb_ary_index(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE val;\n    long i;\n\n    if (argc  == 0) {\n\tRETURN_ENUMERATOR(ary, 0, 0);\n\tfor (i=0; i<RARRAY(ary)->len; i++) {\n\t    if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {\n\t\treturn LONG2NUM(i);\n\t    }\n\t}\n\treturn Qnil;\n    }\n    rb_scan_args(argc, argv, \"01\", &val);\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\tif (rb_equal(RARRAY(ary)->ptr[i], val))\n\t    return LONG2NUM(i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     array.rindex(obj)    ->  int or nil\n *  \n *  Returns the index of the last object in <i>array</i>\n *  <code>==</code> to <i>obj</i>. If a block is given instead of an\n *  argument, returns first object for which <em>block</em> is\n *  true. Returns <code>nil</code> if no match is found.\n *     \n *     a = [ \"a\", \"b\", \"b\", \"b\", \"c\" ]\n *     a.rindex(\"b\")        #=> 3\n *     a.rindex(\"z\")        #=> nil\n *     a.rindex{|x|x==\"b\"}  #=> 3\n */\n\nstatic VALUE\nrb_ary_rindex(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE val;\n    long i = RARRAY(ary)->len;\n\n    if (argc == 0) {\n\tRETURN_ENUMERATOR(ary, 0, 0);\n\twhile (i--) {\n\t    if (RTEST(rb_yield(RARRAY(ary)->ptr[i])))\n\t\treturn LONG2NUM(i);\n\t    if (i > RARRAY(ary)->len) {\n\t\ti = RARRAY(ary)->len;\n\t    }\n\t}\n\treturn Qnil;\n    }\n    rb_scan_args(argc, argv, \"01\", &val);\n    while (i--) {\n\tif (rb_equal(RARRAY(ary)->ptr[i], val))\n\t    return LONG2NUM(i);\n\tif (i > RARRAY(ary)->len) {\n\t    i = RARRAY(ary)->len;\n\t}\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     array.indexes( i1, i2, ... iN )   -> an_array\n *     array.indices( i1, i2, ... iN )   -> an_array\n *  \n *  Deprecated; use <code>Array#values_at</code>.\n */\n\nstatic VALUE\nrb_ary_indexes(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE new_ary;\n    long i;\n\n    rb_warn(\"Array#%s is deprecated; use Array#values_at\", rb_id2name(rb_frame_last_func()));\n    new_ary = rb_ary_new2(argc);\n    for (i=0; i<argc; i++) {\n\trb_ary_push(new_ary, rb_ary_aref(1, argv+i, ary));\n    }\n\n    return new_ary;\n}\n\nVALUE\nrb_ary_to_ary(obj)\n    VALUE obj;\n{\n    if (TYPE(obj) == T_ARRAY) {\n\treturn obj;\n    }\n    if (rb_respond_to(obj, rb_intern(\"to_ary\"))) {\n\treturn rb_convert_type(obj, T_ARRAY, \"Array\", \"to_ary\");\n    }\n    return rb_ary_new3(1, obj);\n}\n\nstatic void\nrb_ary_splice(ary, beg, len, rpl)\n    VALUE ary;\n    long beg, len;\n    VALUE rpl;\n{\n    long rlen;\n\n    if (len < 0) rb_raise(rb_eIndexError, \"negative length (%ld)\", len);\n    if (beg < 0) {\n\tbeg += RARRAY(ary)->len;\n\tif (beg < 0) {\n\t    beg -= RARRAY(ary)->len;\n\t    rb_raise(rb_eIndexError, \"index %ld out of array\", beg);\n\t}\n    }\n    if (RARRAY(ary)->len < len || RARRAY(ary)->len < beg + len) {\n\tlen = RARRAY(ary)->len - beg;\n    }\n\n    if (NIL_P(rpl)) {\n\trlen = 0;\n    }\n    else {\n\trpl = rb_ary_to_ary(rpl);\n\trlen = RARRAY(rpl)->len;\n    }\n    rb_ary_modify(ary);\n\n    if (beg >= RARRAY(ary)->len) {\n\tif (beg > ARY_MAX_SIZE - rlen) {\n\t    rb_raise(rb_eIndexError, \"index %ld too big\", beg);\n\t}\n\tlen = beg + rlen;\n\tif (len >= RARRAY(ary)->aux.capa) {\n\t    REALLOC_N(RARRAY(ary)->ptr, VALUE, len);\n\t    RARRAY(ary)->aux.capa = len;\n\t}\n\trb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len, beg - RARRAY(ary)->len);\n\tif (rlen > 0) {\n\t    MEMCPY(RARRAY(ary)->ptr + beg, RARRAY(rpl)->ptr, VALUE, rlen);\n\t}\n\tRARRAY(ary)->len = len;\n    }\n    else {\n\tlong alen;\n\n\tif (beg + len > RARRAY(ary)->len) {\n\t    len = RARRAY(ary)->len - beg;\n\t}\n\n\talen = RARRAY(ary)->len + rlen - len;\n\tif (alen >= RARRAY(ary)->aux.capa) {\n\t    REALLOC_N(RARRAY(ary)->ptr, VALUE, alen);\n\t    RARRAY(ary)->aux.capa = alen;\n\t}\n\n\tif (len != rlen) {\n\t    MEMMOVE(RARRAY(ary)->ptr + beg + rlen, RARRAY(ary)->ptr + beg + len,\n\t\t    VALUE, RARRAY(ary)->len - (beg + len));\n\t    RARRAY(ary)->len = alen;\n\t}\n\tif (rlen > 0) {\n\t    MEMMOVE(RARRAY(ary)->ptr + beg, RARRAY(rpl)->ptr, VALUE, rlen);\n\t}\n    }\n}\n\n/* \n *  call-seq:\n *     array[index]         = obj                     ->  obj\n *     array[start, length] = obj or an_array or nil  ->  obj or an_array or nil\n *     array[range]         = obj or an_array or nil  ->  obj or an_array or nil\n *\n *  Element Assignment---Sets the element at _index_,\n *  or replaces a subarray starting at _start_ and\n *  continuing for _length_ elements, or replaces a subarray\n *  specified by _range_.  If indices are greater than\n *  the current capacity of the array, the array grows\n *  automatically. A negative indices will count backward\n *  from the end of the array. Inserts elements if _length_ is\n *  zero. If +nil+ is used in the second and third form,\n *  deletes elements from _self_. An +IndexError+ is raised if a\n *  negative index points past the beginning of the array. See also\n *  <code>Array#push</code>, and <code>Array#unshift</code>.\n * \n *     a = Array.new\n *     a[4] = \"4\";                 #=> [nil, nil, nil, nil, \"4\"]\n *     a[0, 3] = [ 'a', 'b', 'c' ] #=> [\"a\", \"b\", \"c\", nil, \"4\"]\n *     a[1..2] = [ 1, 2 ]          #=> [\"a\", 1, 2, nil, \"4\"]\n *     a[0, 2] = \"?\"               #=> [\"?\", 2, nil, \"4\"]\n *     a[0..2] = \"A\"               #=> [\"A\", \"4\"]\n *     a[-1]   = \"Z\"               #=> [\"A\", \"Z\"]\n *     a[1..-1] = nil              #=> [\"A\"]\n */\n\nstatic VALUE\nrb_ary_aset(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    long offset, beg, len;\n\n    if (argc == 3) {\n\tif (SYMBOL_P(argv[0])) {\n\t    rb_raise(rb_eTypeError, \"Symbol as array index\");\n\t}\n\tif (SYMBOL_P(argv[1])) {\n\t    rb_raise(rb_eTypeError, \"Symbol as subarray length\");\n\t}\n\trb_ary_splice(ary, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);\n\treturn argv[2];\n    }\n    if (argc != 2) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for 2)\", argc);\n    }\n    if (FIXNUM_P(argv[0])) {\n\toffset = FIX2LONG(argv[0]);\n\tgoto fixnum;\n    }\n    if (SYMBOL_P(argv[0])) {\n\trb_raise(rb_eTypeError, \"Symbol as array index\");\n    }\n    if (rb_range_beg_len(argv[0], &beg, &len, RARRAY(ary)->len, 1)) {\n\t/* check if idx is Range */\n\trb_ary_splice(ary, beg, len, argv[1]);\n\treturn argv[1];\n    }\n\n    offset = NUM2LONG(argv[0]);\nfixnum:\n    rb_ary_store(ary, offset, argv[1]);\n    return argv[1];\n}\n\n/*\n *  call-seq:\n *     array.insert(index, obj...)  -> array\n *  \n *  Inserts the given values before the element with the given index\n *  (which may be negative).\n *     \n *     a = %w{ a b c d }\n *     a.insert(2, 99)         #=> [\"a\", \"b\", 99, \"c\", \"d\"]\n *     a.insert(-2, 1, 2, 3)   #=> [\"a\", \"b\", 99, \"c\", 1, 2, 3, \"d\"]\n */\n\nstatic VALUE\nrb_ary_insert(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    long pos;\n\n    if (argc == 1) return ary;\n    if (argc < 1) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (at least 1)\");\n    }\n    pos = NUM2LONG(argv[0]);\n    if (pos == -1) {\n\tpos = RARRAY(ary)->len;\n    }\n    if (pos < 0) {\n\tpos++;\n    }\n    rb_ary_splice(ary, pos, 0, rb_ary_new4(argc - 1, argv + 1));\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.each {|item| block }   ->   array\n *  \n *  Calls <i>block</i> once for each element in <i>self</i>, passing that\n *  element as a parameter.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.each {|x| print x, \" -- \" }\n *     \n *  produces:\n *     \n *     a -- b -- c --\n */\n\nVALUE\nrb_ary_each(ary)\n    VALUE ary;\n{\n    long i;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\trb_yield(RARRAY(ary)->ptr[i]);\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.each_index {|index| block }  ->  array\n *  \n *  Same as <code>Array#each</code>, but passes the index of the element\n *  instead of the element itself.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.each_index {|x| print x, \" -- \" }\n *     \n *  produces:\n *     \n *     0 -- 1 -- 2 --\n */\n\nstatic VALUE\nrb_ary_each_index(ary)\n    VALUE ary;\n{\n    long i;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\trb_yield(LONG2NUM(i));\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.reverse_each {|item| block } \n *  \n *  Same as <code>Array#each</code>, but traverses <i>self</i> in reverse\n *  order.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.reverse_each {|x| print x, \" \" }\n *     \n *  produces:\n *     \n *     c b a\n */\n\nstatic VALUE\nrb_ary_reverse_each(ary)\n    VALUE ary;\n{\n    long len;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    len = RARRAY(ary)->len;\n    while (len--) {\n\trb_yield(RARRAY(ary)->ptr[len]);\n\tif (RARRAY(ary)->len < len) {\n\t    len = RARRAY(ary)->len;\n\t}\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.length -> int\n *  \n *  Returns the number of elements in <i>self</i>. May be zero.\n *     \n *     [ 1, 2, 3, 4, 5 ].length   #=> 5\n */\n\nstatic VALUE\nrb_ary_length(ary)\n    VALUE ary;\n{\n    return LONG2NUM(RARRAY(ary)->len);\n}\n\n/*\n *  call-seq:\n *     array.empty?   -> true or false\n *  \n *  Returns <code>true</code> if <i>self</i> array contains no elements.\n *     \n *     [].empty?   #=> true\n */\n\nstatic VALUE\nrb_ary_empty_p(ary)\n    VALUE ary;\n{\n    if (RARRAY(ary)->len == 0)\n\treturn Qtrue;\n    return Qfalse;\n}\n\nVALUE\nrb_ary_dup(ary)\n    VALUE ary;\n{\n    VALUE dup = rb_ary_new2(RARRAY(ary)->len);\n\n    DUPSETUP(dup, ary);\n    MEMCPY(RARRAY(dup)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);\n    RARRAY(dup)->len = RARRAY(ary)->len;\n    return dup;\n}\n\nextern VALUE rb_output_fs;\n\nstatic VALUE\ninspect_join(ary, arg)\n    VALUE ary;\n    VALUE *arg;\n{\n    return rb_ary_join(arg[0], arg[1]);\n}\n\nVALUE\nrb_ary_join(ary, sep)\n    VALUE ary, sep;\n{\n    long len = 1, i;\n    int taint = Qfalse;\n    VALUE result, tmp;\n\n    if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);\n    if (OBJ_TAINTED(ary) || OBJ_TAINTED(sep)) taint = Qtrue;\n\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\ttmp = rb_check_string_type(RARRAY(ary)->ptr[i]);\n\tlen += NIL_P(tmp) ? 10 : RSTRING(tmp)->len;\n    }\n    if (!NIL_P(sep)) {\n\tStringValue(sep);\n\tlen += RSTRING(sep)->len * (RARRAY(ary)->len - 1);\n    }\n    result = rb_str_buf_new(len);\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\ttmp = RARRAY(ary)->ptr[i];\n\tswitch (TYPE(tmp)) {\n\t  case T_STRING:\n\t    break;\n\t  case T_ARRAY:\n\t    if (tmp == ary || rb_inspecting_p(tmp)) {\n\t\ttmp = rb_str_new2(\"[...]\");\n\t    }\n\t    else {\n\t\tVALUE args[2];\n\n\t\targs[0] = tmp;\n\t\targs[1] = sep;\n\t\ttmp = rb_protect_inspect(inspect_join, ary, (VALUE)args);\n\t    }\n\t    break;\n\t  default:\n\t    tmp = rb_obj_as_string(tmp);\n\t}\n\tif (i > 0 && !NIL_P(sep))\n\t    rb_str_buf_append(result, sep);\n\trb_str_buf_append(result, tmp);\n\tif (OBJ_TAINTED(tmp)) taint = Qtrue;\n    }\n\n    if (taint) OBJ_TAINT(result);\n    return result;\n}\n\n/*\n *  call-seq:\n *     array.join(sep=$,)    -> str\n *  \n *  Returns a string created by converting each element of the array to\n *  a string, separated by <i>sep</i>.\n *     \n *     [ \"a\", \"b\", \"c\" ].join        #=> \"abc\"\n *     [ \"a\", \"b\", \"c\" ].join(\"-\")   #=> \"a-b-c\"\n */\n\nstatic VALUE\nrb_ary_join_m(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE sep;\n\n    rb_scan_args(argc, argv, \"01\", &sep);\n    if (NIL_P(sep)) sep = rb_output_fs;\n    \n    return rb_ary_join(ary, sep);\n}\n\n/*\n *  call-seq:\n *     array.to_s -> string\n *  \n *  Returns _self_<code>.join</code>.\n *     \n *     [ \"a\", \"e\", \"i\", \"o\" ].to_s   #=> \"aeio\"\n *\n */\n\nVALUE\nrb_ary_to_s(ary)\n    VALUE ary;\n{\n    if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);\n    \n    return rb_ary_join(ary, rb_output_fs);\n}\n\nstatic ID inspect_key;\n\nstruct inspect_arg {\n    VALUE (*func)();\n    VALUE arg1, arg2;\n};\n\nstatic VALUE\ninspect_call(arg)\n    struct inspect_arg *arg;\n{\n    return (*arg->func)(arg->arg1, arg->arg2);\n}\n\nstatic VALUE\nget_inspect_tbl(create)\n    int create;\n{\n    VALUE inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key);\n\n    if (NIL_P(inspect_tbl)) {\n\tif (create) {\n\t  tbl_init:\n\t    inspect_tbl = rb_ary_new();\n\t    rb_thread_local_aset(rb_thread_current(), inspect_key, inspect_tbl);\n\t}\n    }\n    else if (TYPE(inspect_tbl) != T_ARRAY) {\n\trb_warn(\"invalid inspect_tbl value\");\n\tif (create) goto tbl_init;\n\trb_thread_local_aset(rb_thread_current(), inspect_key, Qnil);\n\treturn Qnil;\n    }\n    return inspect_tbl;\n}\n\nstatic VALUE\ninspect_ensure(obj)\n    VALUE obj;\n{\n    VALUE inspect_tbl;\n\n    inspect_tbl = get_inspect_tbl(Qfalse);\n    if (!NIL_P(inspect_tbl)) {\n\trb_ary_pop(inspect_tbl);\n    }\n    return 0;\n}\n\nVALUE\nrb_protect_inspect(func, obj, arg)\n    VALUE (*func)(ANYARGS);\n    VALUE obj, arg;\n{\n    struct inspect_arg iarg;\n    VALUE inspect_tbl;\n    VALUE id;\n\n    inspect_tbl = get_inspect_tbl(Qtrue);\n    id = rb_obj_id(obj);\n    if (rb_ary_includes(inspect_tbl, id)) {\n\treturn (*func)(obj, arg);\n    }\n    rb_ary_push(inspect_tbl, id);\n    iarg.func = func;\n    iarg.arg1 = obj;\n    iarg.arg2 = arg;\n\n    return rb_ensure(inspect_call, (VALUE)&iarg, inspect_ensure, obj);\n}\n\nVALUE\nrb_inspecting_p(obj)\n    VALUE obj;\n{\n    VALUE inspect_tbl;\n\n    inspect_tbl = get_inspect_tbl(Qfalse);\n    if (NIL_P(inspect_tbl)) return Qfalse;\n    return rb_ary_includes(inspect_tbl, rb_obj_id(obj));\n}\n\nstatic VALUE\ninspect_ary(ary)\n    VALUE ary;\n{\n    int tainted = OBJ_TAINTED(ary);\n    long i;\n    VALUE s, str;\n\n    str = rb_str_buf_new2(\"[\");\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\ts = rb_inspect(RARRAY(ary)->ptr[i]);\n\tif (OBJ_TAINTED(s)) tainted = Qtrue;\n\tif (i > 0) rb_str_buf_cat2(str, \", \");\n\trb_str_buf_append(str, s);\n    }\n    rb_str_buf_cat2(str, \"]\");\n    if (tainted) OBJ_TAINT(str);\n    return str;\n}\n\n/*\n *  call-seq:\n *     array.inspect  -> string\n *\n *  Create a printable version of <i>array</i>.\n */\n\nstatic VALUE\nrb_ary_inspect(ary)\n    VALUE ary;\n{\n    if (RARRAY(ary)->len == 0) return rb_str_new2(\"[]\");\n    if (rb_inspecting_p(ary)) return rb_str_new2(\"[...]\");\n    return rb_protect_inspect(inspect_ary, ary, 0);\n}\n\n/*\n *  call-seq:\n *     array.to_a     -> array\n *  \n *  Returns _self_. If called on a subclass of Array, converts\n *  the receiver to an Array object.\n */\n\nstatic VALUE\nrb_ary_to_a(ary)\n    VALUE ary;\n{\n    if (rb_obj_class(ary) != rb_cArray) {\n\tVALUE dup = rb_ary_new2(RARRAY(ary)->len);\n\trb_ary_replace(dup, ary);\n\treturn dup;\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.to_ary -> array\n *  \n *  Returns _self_.\n */\n\nstatic VALUE\nrb_ary_to_ary_m(ary)\n    VALUE ary;\n{\n    return ary;\n}\n\nVALUE\nrb_ary_reverse(ary)\n    VALUE ary;\n{\n    VALUE *p1, *p2;\n    VALUE tmp;\n\n    rb_ary_modify(ary);\n    if (RARRAY(ary)->len > 1) {\n\tp1 = RARRAY(ary)->ptr;\n\tp2 = p1 + RARRAY(ary)->len - 1;\t/* points last item */\n\n\twhile (p1 < p2) {\n\t    tmp = *p1;\n\t    *p1++ = *p2;\n\t    *p2-- = tmp;\n\t}\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.reverse!   -> array \n *  \n *  Reverses _self_ in place.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.reverse!       #=> [\"c\", \"b\", \"a\"]\n *     a                #=> [\"c\", \"b\", \"a\"]\n */\n\nstatic VALUE\nrb_ary_reverse_bang(ary)\n    VALUE ary;\n{\n    return rb_ary_reverse(ary);\n}\n\n/*\n *  call-seq:\n *     array.reverse -> an_array\n *  \n *  Returns a new array containing <i>self</i>'s elements in reverse order.\n *     \n *     [ \"a\", \"b\", \"c\" ].reverse   #=> [\"c\", \"b\", \"a\"]\n *     [ 1 ].reverse               #=> [1]\n */\n\nstatic VALUE\nrb_ary_reverse_m(ary)\n    VALUE ary;\n{\n    return rb_ary_reverse(rb_ary_dup(ary));\n}\n\nstruct ary_sort_data {\n    VALUE ary;\n    VALUE *ptr;\n    long len;\n};\n\nstatic void\nary_sort_check(data)\n    struct ary_sort_data *data;\n{\n    if (RARRAY(data->ary)->ptr != data->ptr || RARRAY(data->ary)->len != data->len) {\n\trb_raise(rb_eArgError, \"array modified during sort\");\n    }\n}\n\nstatic int\nsort_1(a, b, data)\n    VALUE *a, *b;\n    struct ary_sort_data *data;\n{\n    VALUE retval = rb_yield_values(2, *a, *b);\n    int n;\n\n    n = rb_cmpint(retval, *a, *b);\n    ary_sort_check(data);\n    return n;\n}\n\nstatic int\nsort_2(ap, bp, data)\n    VALUE *ap, *bp;\n    struct ary_sort_data *data;\n{\n    VALUE retval;\n    VALUE a = *ap, b = *bp;\n    int n;\n\n    if (FIXNUM_P(a) && FIXNUM_P(b)) {\n\tif ((long)a > (long)b) return 1;\n\tif ((long)a < (long)b) return -1;\n\treturn 0;\n    }\n    if (TYPE(a) == T_STRING) {\n\tif (TYPE(b) == T_STRING) return rb_str_cmp(a, b);\n    }\n\n    retval = rb_funcall(a, id_cmp, 1, b);\n    n = rb_cmpint(retval, a, b);\n    ary_sort_check(data);\n\n    return n;\n}\n\nstatic VALUE\nsort_internal(ary)\n    VALUE ary;\n{\n    struct ary_sort_data data;\n\n    data.ary = ary;\n    data.ptr = RARRAY(ary)->ptr; data.len = RARRAY(ary)->len;\n    qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),\n\t  rb_block_given_p()?sort_1:sort_2, &data);\n    return ary;\n}\n\nstatic VALUE\nsort_unlock(ary)\n    VALUE ary;\n{\n    FL_UNSET(ary, ARY_TMPLOCK);\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.sort!                   -> array\n *     array.sort! {| a,b | block }  -> array \n *  \n *  Sorts _self_. Comparisons for\n *  the sort will be done using the <code><=></code> operator or using\n *  an optional code block. The block implements a comparison between\n *  <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also\n *  <code>Enumerable#sort_by</code>.\n *     \n *     a = [ \"d\", \"a\", \"e\", \"c\", \"b\" ]\n *     a.sort                    #=> [\"a\", \"b\", \"c\", \"d\", \"e\"]\n *     a.sort {|x,y| y <=> x }   #=> [\"e\", \"d\", \"c\", \"b\", \"a\"]\n */\n\nVALUE\nrb_ary_sort_bang(ary)\n    VALUE ary;\n{\n    rb_ary_modify(ary);\n    if (RARRAY(ary)->len > 1) {\n\tFL_SET(ary, ARY_TMPLOCK);\t/* prohibit modification during sort */\n\trb_ensure(sort_internal, ary, sort_unlock, ary);\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.sort                   -> an_array \n *     array.sort {| a,b | block }  -> an_array \n *  \n *  Returns a new array created by sorting <i>self</i>. Comparisons for\n *  the sort will be done using the <code><=></code> operator or using\n *  an optional code block. The block implements a comparison between\n *  <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also\n *  <code>Enumerable#sort_by</code>.\n *     \n *     a = [ \"d\", \"a\", \"e\", \"c\", \"b\" ]\n *     a.sort                    #=> [\"a\", \"b\", \"c\", \"d\", \"e\"]\n *     a.sort {|x,y| y <=> x }   #=> [\"e\", \"d\", \"c\", \"b\", \"a\"]\n */\n\nVALUE\nrb_ary_sort(ary)\n    VALUE ary;\n{\n    ary = rb_ary_dup(ary);\n    rb_ary_sort_bang(ary);\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.collect {|item| block }  -> an_array\n *     array.map     {|item| block }  -> an_array\n *  \n *  Invokes <i>block</i> once for each element of <i>self</i>. Creates a \n *  new array containing the values returned by the block.\n *  See also <code>Enumerable#collect</code>.\n *     \n *     a = [ \"a\", \"b\", \"c\", \"d\" ]\n *     a.collect {|x| x + \"!\" }   #=> [\"a!\", \"b!\", \"c!\", \"d!\"]\n *     a                          #=> [\"a\", \"b\", \"c\", \"d\"]\n */\n\nstatic VALUE\nrb_ary_collect(ary)\n    VALUE ary;\n{\n    long i;\n    VALUE collect;\n\n    if (!rb_block_given_p()) {\n\treturn rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);\n    }\n\n    collect = rb_ary_new2(RARRAY(ary)->len);\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\trb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i]));\n    }\n    return collect;\n}\n\n/* \n *  call-seq:\n *     array.collect! {|item| block }   ->   array\n *     array.map!     {|item| block }   ->   array\n *\n *  Invokes the block once for each element of _self_, replacing the\n *  element with the value returned by _block_.\n *  See also <code>Enumerable#collect</code>.\n *   \n *     a = [ \"a\", \"b\", \"c\", \"d\" ]\n *     a.collect! {|x| x + \"!\" }\n *     a             #=>  [ \"a!\", \"b!\", \"c!\", \"d!\" ]\n */\n\nstatic VALUE\nrb_ary_collect_bang(ary)\n    VALUE ary;\n{\n    long i;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    rb_ary_modify(ary);\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\trb_ary_store(ary, i, rb_yield(RARRAY(ary)->ptr[i]));\n    }\n    return ary;\n}\n\nVALUE\nrb_values_at(obj, olen, argc, argv, func)\n    VALUE obj;\n    long olen;\n    int argc;\n    VALUE *argv;\n    VALUE (*func) _((VALUE,long));\n{\n    VALUE result = rb_ary_new2(argc);\n    long beg, len, i, j;\n\n    for (i=0; i<argc; i++) {\n\tif (FIXNUM_P(argv[i])) {\n\t    rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));\n\t    continue;\n\t}\n\t/* check if idx is Range */\n\tswitch (rb_range_beg_len(argv[i], &beg, &len, olen, 0)) {\n\t  case Qfalse:\n\t    break;\n\t  case Qnil:\n\t    continue;\n\t  default:\n\t    for (j=0; j<len; j++) {\n\t\trb_ary_push(result, (*func)(obj, j+beg));\n\t    }\n\t    continue;\n\t}\n\trb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));\n    }\n    return result;\n}\n\n/* \n *  call-seq:\n *     array.values_at(selector,... )  -> an_array\n *\n *  Returns an array containing the elements in\n *  _self_ corresponding to the given selector(s). The selectors\n *  may be either integer indices or ranges. \n *  See also <code>Array#select</code>.\n * \n *     a = %w{ a b c d e f }\n *     a.values_at(1, 3, 5)\n *     a.values_at(1, 3, 5, 7)\n *     a.values_at(-1, -3, -5, -7)\n *     a.values_at(1..3, 2...5)\n */\n\nstatic VALUE\nrb_ary_values_at(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    return rb_values_at(ary, RARRAY(ary)->len, argc, argv, rb_ary_entry);\n}\n\n/*\n *  call-seq:\n *     array.select {|item| block } -> an_array\n *  \n *  Invokes the block passing in successive elements from <i>array</i>,\n *  returning an array containing those elements for which the block\n *  returns a true value (equivalent to <code>Enumerable#select</code>).\n *     \n *     a = %w{ a b c d e f }\n *     a.select {|v| v =~ /[aeiou]/}   #=> [\"a\", \"e\"]\n */\n\nstatic VALUE\nrb_ary_select(ary)\n    VALUE ary;\n{\n    VALUE result;\n    long i;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    result = rb_ary_new2(RARRAY(ary)->len);\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\tif (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {\n\t    rb_ary_push(result, rb_ary_elt(ary, i));\n\t}\n    }\n    return result;\n}\n\n/*\n *  call-seq:\n *     array.delete(obj)            -> obj or nil \n *     array.delete(obj) { block }  -> obj or nil\n *  \n *  Deletes items from <i>self</i> that are equal to <i>obj</i>. If\n *  the item is not found, returns <code>nil</code>. If the optional\n *  code block is given, returns the result of <i>block</i> if the item\n *  is not found.\n *     \n *     a = [ \"a\", \"b\", \"b\", \"b\", \"c\" ]\n *     a.delete(\"b\")                   #=> \"b\"\n *     a                               #=> [\"a\", \"c\"]\n *     a.delete(\"z\")                   #=> nil\n *     a.delete(\"z\") { \"not found\" }   #=> \"not found\"\n */\n\nVALUE\nrb_ary_delete(ary, item)\n    VALUE ary;\n    VALUE item;\n{\n    long i1, i2;\n\n    for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {\n\tVALUE e = RARRAY(ary)->ptr[i1];\n\n\tif (rb_equal(e, item)) continue;\n\tif (i1 != i2) {\n\t    rb_ary_store(ary, i2, e);\n\t}\n\ti2++;\n    }\n    if (RARRAY(ary)->len == i2) {\n\tif (rb_block_given_p()) {\n\t    return rb_yield(item);\n\t}\n\treturn Qnil;\n    }\n\n    rb_ary_modify(ary);\n    if (RARRAY(ary)->len > i2) {\n\tRARRAY(ary)->len = i2;\n\tif (i2 * 2 < RARRAY(ary)->aux.capa &&\n\t    RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {\n\t    REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2);\n\t    RARRAY(ary)->aux.capa = i2 * 2;\n\t}\n    }\n\n    return item;\n}\n\nVALUE\nrb_ary_delete_at(ary, pos)\n    VALUE ary;\n    long pos;\n{\n    long i, len = RARRAY(ary)->len;\n    VALUE del;\n\n    if (pos >= len) return Qnil;\n    if (pos < 0) {\n\tpos += len;\n\tif (pos < 0) return Qnil;\n    }\n\n    rb_ary_modify(ary);\n    del = RARRAY(ary)->ptr[pos];\n    for (i = pos + 1; i < len; i++, pos++) {\n\tRARRAY(ary)->ptr[pos] = RARRAY(ary)->ptr[i];\n    }\n    RARRAY(ary)->len = pos;\n\n    return del;\n}\n\n/*\n *  call-seq:\n *     array.delete_at(index)  -> obj or nil\n *  \n *  Deletes the element at the specified index, returning that element,\n *  or <code>nil</code> if the index is out of range. See also\n *  <code>Array#slice!</code>.\n *     \n *     a = %w( ant bat cat dog )\n *     a.delete_at(2)    #=> \"cat\"\n *     a                 #=> [\"ant\", \"bat\", \"dog\"]\n *     a.delete_at(99)   #=> nil\n */\n\nstatic VALUE\nrb_ary_delete_at_m(ary, pos)\n    VALUE ary, pos;\n{\n    return rb_ary_delete_at(ary, NUM2LONG(pos));\n}\n\n/*\n *  call-seq:\n *     array.slice!(index)         -> obj or nil\n *     array.slice!(start, length) -> sub_array or nil\n *     array.slice!(range)         -> sub_array or nil \n *  \n *  Deletes the element(s) given by an index (optionally with a length)\n *  or by a range. Returns the deleted object, subarray, or\n *  <code>nil</code> if the index is out of range. Equivalent to:\n *     \n *     def slice!(*args)\n *       result = self[*args]\n *       self[*args] = nil\n *       result\n *     end\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.slice!(1)     #=> \"b\"\n *     a               #=> [\"a\", \"c\"]\n *     a.slice!(-1)    #=> \"c\"\n *     a               #=> [\"a\"]\n *     a.slice!(100)   #=> nil\n *     a               #=> [\"a\"]\n */\n\nstatic VALUE\nrb_ary_slice_bang(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE arg1, arg2;\n    long pos, len, orig_len;\n\n    rb_ary_modify_check(ary);\n    if (rb_scan_args(argc, argv, \"11\", &arg1, &arg2) == 2) {\n\tpos = NUM2LONG(arg1);\n\tlen = NUM2LONG(arg2);\n      delete_pos_len:\n\tif (len < 0) return Qnil;\n\torig_len = RARRAY_LEN(ary);\n\tif (pos < 0) {\n\t    pos += orig_len;\n\t    if (pos < 0) return Qnil;\n\t}\n\telse if (orig_len < pos) return Qnil;\n\tif (orig_len < pos + len) {\n\t    len = orig_len - pos;\n\t}\n\tif (len == 0) return rb_ary_new2(0);\n\targ2 = rb_ary_new4(len, RARRAY_PTR(ary)+pos);\n\tRBASIC(arg2)->klass = rb_obj_class(ary);\n\trb_ary_splice(ary, pos, len, Qnil);\t/* Qundef in 1.9 */\n\treturn arg2;\n    }\n\n    if (!FIXNUM_P(arg1)) {\n\tswitch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {\n\t  case Qtrue:\n\t    /* valid range */\n\t    goto delete_pos_len;\n\t  case Qnil:\n\t    /* invalid range */\n\t    return Qnil;\n\t  default:\n\t    /* not a range */\n\t    break;\n\t}\n    }\n\n    return rb_ary_delete_at(ary, NUM2LONG(arg1));\n}\n\n/*\n *  call-seq:\n *     array.reject! {|item| block }  -> array or nil\n *  \n *  Equivalent to <code>Array#delete_if</code>, deleting elements from\n *  _self_ for which the block evaluates to true, but returns\n *  <code>nil</code> if no changes were made. Also see\n *  <code>Enumerable#reject</code>.\n */\n\nstatic VALUE\nrb_ary_reject_bang(ary)\n    VALUE ary;\n{\n    long i1, i2;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    rb_ary_modify(ary);\n    for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {\n\tVALUE v = RARRAY(ary)->ptr[i1];\n\tif (RTEST(rb_yield(v))) continue;\n\tif (i1 != i2) {\n\t    rb_ary_store(ary, i2, v);\n\t}\n\ti2++;\n    }\n    if (RARRAY(ary)->len == i2) return Qnil;\n    if (i2 < RARRAY(ary)->len)\n\tRARRAY(ary)->len = i2;\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.reject {|item| block }  -> an_array\n *  \n *  Returns a new array containing the items in _self_\n *  for which the block is not true.\n */\n\nstatic VALUE\nrb_ary_reject(ary)\n    VALUE ary;\n{\n    RETURN_ENUMERATOR(ary, 0, 0);\n    ary = rb_ary_dup(ary);\n    rb_ary_reject_bang(ary);\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.delete_if {|item| block }  -> array\n *  \n *  Deletes every element of <i>self</i> for which <i>block</i> evaluates\n *  to <code>true</code>.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.delete_if {|x| x >= \"b\" }   #=> [\"a\"]\n */\n\nstatic VALUE\nrb_ary_delete_if(ary)\n    VALUE ary;\n{\n    RETURN_ENUMERATOR(ary, 0, 0);\n    rb_ary_reject_bang(ary);\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.zip(arg, ...)                   -> an_array\n *     array.zip(arg, ...) {| arr | block }  -> nil\n *  \n *  Converts any arguments to arrays, then merges elements of\n *  <i>self</i> with corresponding elements from each argument. This\n *  generates a sequence of <code>self.size</code> <em>n</em>-element\n *  arrays, where <em>n</em> is one more that the count of arguments. If\n *  the size of any argument is less than <code>enumObj.size</code>,\n *  <code>nil</code> values are supplied. If a block given, it is\n *  invoked for each output array, otherwise an array of arrays is\n *  returned.\n *     \n *     a = [ 4, 5, 6 ]\n *     b = [ 7, 8, 9 ]\n *     \n *     [1,2,3].zip(a, b)      #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]\n *     [1,2].zip(a,b)         #=> [[1, 4, 7], [2, 5, 8]]\n *     a.zip([1,2],[8])       #=> [[4,1,8], [5,2,nil], [6,nil,nil]]\n */\n\nstatic VALUE\nrb_ary_zip(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    int i, j;\n    long len;\n    VALUE result;\n\n    for (i=0; i<argc; i++) {\n\targv[i] = to_ary(argv[i]);\n    }\n    if (rb_block_given_p()) {\n\tfor (i=0; i<RARRAY(ary)->len; i++) {\n\t    VALUE tmp = rb_ary_new2(argc+1);\n\n\t    rb_ary_push(tmp, rb_ary_elt(ary, i));\n\t    for (j=0; j<argc; j++) {\n\t\trb_ary_push(tmp, rb_ary_elt(argv[j], i));\n\t    }\n\t    rb_yield(tmp);\n\t}\n\treturn Qnil;\n    }\n    len = RARRAY(ary)->len;\n    result = rb_ary_new2(len);\n    for (i=0; i<len; i++) {\n\tVALUE tmp = rb_ary_new2(argc+1);\n\n\trb_ary_push(tmp, rb_ary_elt(ary, i));\n\tfor (j=0; j<argc; j++) {\n\t    rb_ary_push(tmp, rb_ary_elt(argv[j], i));\n\t}\n\trb_ary_push(result, tmp);\n    }\n    return result;\n}\n\n/*\n *  call-seq:\n *     array.transpose -> an_array\n *  \n *  Assumes that <i>self</i> is an array of arrays and transposes the\n *  rows and columns.\n *     \n *     a = [[1,2], [3,4], [5,6]]\n *     a.transpose   #=> [[1, 3, 5], [2, 4, 6]]\n */\n\nstatic VALUE\nrb_ary_transpose(ary)\n    VALUE ary;\n{\n    long elen = -1, alen, i, j;\n    VALUE tmp, result = 0;\n\n    alen = RARRAY(ary)->len;\n    if (alen == 0) return rb_ary_dup(ary);\n    for (i=0; i<alen; i++) {\n\ttmp = to_ary(rb_ary_elt(ary, i));\n\tif (elen < 0) {\t\t/* first element */\n\t    elen = RARRAY(tmp)->len;\n\t    result = rb_ary_new2(elen);\n\t    for (j=0; j<elen; j++) {\n\t\trb_ary_store(result, j, rb_ary_new2(alen));\n\t    }\n\t}\n\telse if (elen != RARRAY(tmp)->len) {\n\t    rb_raise(rb_eIndexError, \"element size differs (%d should be %d)\",\n\t\t     RARRAY(tmp)->len, elen);\n\t}\n\tfor (j=0; j<elen; j++) {\n\t    rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));\n\t}\n    }\n    return result;\n}\n\n/*\n *  call-seq:\n *     array.replace(other_array)  -> array\n *  \n *  Replaces the contents of <i>self</i> with the contents of\n *  <i>other_array</i>, truncating or expanding if necessary.\n *     \n *     a = [ \"a\", \"b\", \"c\", \"d\", \"e\" ]\n *     a.replace([ \"x\", \"y\", \"z\" ])   #=> [\"x\", \"y\", \"z\"]\n *     a                              #=> [\"x\", \"y\", \"z\"]\n */\n\nstatic VALUE\nrb_ary_replace(copy, orig)\n    VALUE copy, orig;\n{\n    VALUE shared;\n\n    rb_ary_modify(copy);\n    orig = to_ary(orig);\n    if (copy == orig) return copy;\n    shared = ary_make_shared(orig);\n    if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))\n\tfree(RARRAY(copy)->ptr);\n    RARRAY(copy)->ptr = RARRAY(orig)->ptr;\n    RARRAY(copy)->len = RARRAY(orig)->len;\n    RARRAY(copy)->aux.shared = shared;\n    FL_SET(copy, ELTS_SHARED);\n\n    return copy;\n}\n\n/* \n *  call-seq:\n *     array.clear    ->  array\n *\n *  Removes all elements from _self_.\n *\n *     a = [ \"a\", \"b\", \"c\", \"d\", \"e\" ]\n *     a.clear    #=> [ ]\n */\n\nVALUE\nrb_ary_clear(ary)\n    VALUE ary;\n{\n    rb_ary_modify(ary);\n    RARRAY(ary)->len = 0;\n    if (ARY_DEFAULT_SIZE * 2 < RARRAY(ary)->aux.capa) {\n\tREALLOC_N(RARRAY(ary)->ptr, VALUE, ARY_DEFAULT_SIZE * 2);\n\tRARRAY(ary)->aux.capa = ARY_DEFAULT_SIZE * 2;\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.fill(obj)                                -> array\n *     array.fill(obj, start [, length])              -> array\n *     array.fill(obj, range )                        -> array\n *     array.fill {|index| block }                    -> array\n *     array.fill(start [, length] ) {|index| block } -> array\n *     array.fill(range) {|index| block }             -> array\n *  \n *  The first three forms set the selected elements of <i>self</i> (which\n *  may be the entire array) to <i>obj</i>. A <i>start</i> of\n *  <code>nil</code> is equivalent to zero. A <i>length</i> of\n *  <code>nil</code> is equivalent to <i>self.length</i>. The last three\n *  forms fill the array with the value of the block. The block is\n *  passed the absolute index of each element to be filled.\n *     \n *     a = [ \"a\", \"b\", \"c\", \"d\" ]\n *     a.fill(\"x\")              #=> [\"x\", \"x\", \"x\", \"x\"]\n *     a.fill(\"z\", 2, 2)        #=> [\"x\", \"x\", \"z\", \"z\"]\n *     a.fill(\"y\", 0..1)        #=> [\"y\", \"y\", \"z\", \"z\"]\n *     a.fill {|i| i*i}         #=> [0, 1, 4, 9]\n *     a.fill(-2) {|i| i*i*i}   #=> [0, 1, 8, 27]\n */\n\nstatic VALUE\nrb_ary_fill(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE item, arg1, arg2;\n    long beg = 0, end = 0, len = 0;\n    VALUE *p, *pend;\n    int block_p = Qfalse;\n\n    if (rb_block_given_p()) {\n\tblock_p = Qtrue;\n\trb_scan_args(argc, argv, \"02\", &arg1, &arg2);\n\targc += 1;\t\t/* hackish */\n    }\n    else {\n\trb_scan_args(argc, argv, \"12\", &item, &arg1, &arg2);\n    }\n    switch (argc) {\n      case 1:\n\tbeg = 0;\n\tlen = RARRAY(ary)->len;\n\tbreak;\n      case 2:\n\tif (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 1)) {\n\t    break;\n\t}\n\t/* fall through */\n      case 3:\n\tbeg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);\n\tif (beg < 0) {\n\t    beg = RARRAY(ary)->len + beg;\n\t    if (beg < 0) beg = 0;\n\t}\n\tlen = NIL_P(arg2) ? RARRAY(ary)->len - beg : NUM2LONG(arg2);\n\tbreak;\n    }\n    rb_ary_modify(ary);\n    if (len < 0) {\n        return ary;\n    }\n    if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {\n\trb_raise(rb_eArgError, \"argument too big\");\n    }\n    end = beg + len;\n    if (end > RARRAY(ary)->len) {\n\tif (end >= RARRAY(ary)->aux.capa) {\n\t    REALLOC_N(RARRAY(ary)->ptr, VALUE, end);\n\t    RARRAY(ary)->aux.capa = end;\n\t}\n\trb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len, end - RARRAY(ary)->len);\n\tRARRAY(ary)->len = end;\n    }\n\n    if (block_p) {\n\tVALUE v;\n\tlong i;\n\n\tfor (i=beg; i<end; i++) {\n\t    v = rb_yield(LONG2NUM(i));\n\t    if (i>=RARRAY(ary)->len) break;\n\t    RARRAY(ary)->ptr[i] = v;\n\t}\n    }\n    else {\n\tp = RARRAY(ary)->ptr + beg;\n\tpend = p + len;\n\twhile (p < pend) {\n\t    *p++ = item;\n\t}\n    }\n    return ary;\n}\n\n/* \n *  call-seq:\n *     array + other_array   -> an_array\n *\n *  Concatenation---Returns a new array built by concatenating the\n *  two arrays together to produce a third array.\n * \n *     [ 1, 2, 3 ] + [ 4, 5 ]    #=> [ 1, 2, 3, 4, 5 ]\n */\n\nVALUE\nrb_ary_plus(x, y)\n    VALUE x, y;\n{\n    VALUE z;\n    long len;\n\n    y = to_ary(y);\n    len = RARRAY(x)->len + RARRAY(y)->len;\n    z = rb_ary_new2(len);\n    MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len);\n    MEMCPY(RARRAY(z)->ptr + RARRAY(x)->len, RARRAY(y)->ptr, VALUE, RARRAY(y)->len);\n    RARRAY(z)->len = len;\n    return z;\n}\n\n/* \n *  call-seq:\n *     array.concat(other_array)   ->  array\n *\n *  Appends the elements in other_array to _self_.\n *  \n *     [ \"a\", \"b\" ].concat( [\"c\", \"d\"] ) #=> [ \"a\", \"b\", \"c\", \"d\" ]\n */\n\n\nVALUE\nrb_ary_concat(x, y)\n    VALUE x, y;\n{\n    y = to_ary(y);\n    if (RARRAY(y)->len > 0) {\n\trb_ary_splice(x, RARRAY(x)->len, 0, y);\n    }\n    return x;\n}\n\n\n/* \n *  call-seq:\n *     array * int     ->    an_array\n *     array * str     ->    a_string\n *\n *  Repetition---With a String argument, equivalent to\n *  self.join(str). Otherwise, returns a new array\n *  built by concatenating the _int_ copies of _self_.\n *\n *\n *     [ 1, 2, 3 ] * 3    #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]\n *     [ 1, 2, 3 ] * \",\"  #=> \"1,2,3\"\n *\n */\n\nstatic VALUE\nrb_ary_times(ary, times)\n    VALUE ary, times;\n{\n    VALUE ary2, tmp;\n    long i, len;\n\n    tmp = rb_check_string_type(times);\n    if (!NIL_P(tmp)) {\n\treturn rb_ary_join(ary, tmp);\n    }\n\n    len = NUM2LONG(times);\n    if (len == 0) return ary_new(rb_obj_class(ary), 0);\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"negative argument\");\n    }\n    if (ARY_MAX_SIZE/len < RARRAY(ary)->len) {\n\trb_raise(rb_eArgError, \"argument too big\");\n    }\n    len *= RARRAY(ary)->len;\n\n    ary2 = ary_new(rb_obj_class(ary), len);\n    RARRAY(ary2)->len = len;\n\n    for (i=0; i<len; i+=RARRAY(ary)->len) {\n\tMEMCPY(RARRAY(ary2)->ptr+i, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);\n    }\n    OBJ_INFECT(ary2, ary);\n\n    return ary2;\n}\n\n/* \n *  call-seq:\n *     array.assoc(obj)   ->  an_array  or  nil\n *\n *  Searches through an array whose elements are also arrays\n *  comparing _obj_ with the first element of each contained array\n *  using obj.==.\n *  Returns the first contained array that matches (that\n *  is, the first associated array),\n *  or +nil+ if no match is found.\n *  See also <code>Array#rassoc</code>.\n *\n *     s1 = [ \"colors\", \"red\", \"blue\", \"green\" ]\n *     s2 = [ \"letters\", \"a\", \"b\", \"c\" ]\n *     s3 = \"foo\"\n *     a  = [ s1, s2, s3 ]\n *     a.assoc(\"letters\")  #=> [ \"letters\", \"a\", \"b\", \"c\" ]\n *     a.assoc(\"foo\")      #=> nil\n */\n\nVALUE\nrb_ary_assoc(ary, key)\n    VALUE ary, key;\n{\n    long i;\n    VALUE v;\n\n    for (i = 0; i < RARRAY(ary)->len; ++i) {\n\tv = rb_check_array_type(RARRAY(ary)->ptr[i]);\n\tif (!NIL_P(v) && RARRAY(v)->len > 0 &&\n\t    rb_equal(RARRAY(v)->ptr[0], key))\n\t    return v;\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     array.rassoc(key) -> an_array or nil\n *  \n *  Searches through the array whose elements are also arrays. Compares\n *  <em>key</em> with the second element of each contained array using\n *  <code>==</code>. Returns the first contained array that matches. See\n *  also <code>Array#assoc</code>.\n *     \n *     a = [ [ 1, \"one\"], [2, \"two\"], [3, \"three\"], [\"ii\", \"two\"] ]\n *     a.rassoc(\"two\")    #=> [2, \"two\"]\n *     a.rassoc(\"four\")   #=> nil\n */\n\nVALUE\nrb_ary_rassoc(ary, value)\n    VALUE ary, value;\n{\n    long i;\n    VALUE v;\n\n    for (i = 0; i < RARRAY(ary)->len; ++i) {\n\tv = RARRAY(ary)->ptr[i];\n\tif (TYPE(v) == T_ARRAY &&\n\t    RARRAY(v)->len > 1 &&\n\t    rb_equal(RARRAY(v)->ptr[1], value))\n\t    return v;\n    }\n    return Qnil;\n}\n\nstatic VALUE recursive_equal _((VALUE, VALUE, int));\nstatic VALUE\nrecursive_equal(ary1, ary2, recur)\n    VALUE ary1, ary2;\n    int recur;\n{\n    long i;\n\n    if (recur) return Qfalse;\n    for (i=0; i<RARRAY(ary1)->len; i++) {\n\tif (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))\n\t    return Qfalse;\n    }\n    return Qtrue;\n}\n\n/* \n *  call-seq:\n *     array == other_array   ->   bool\n *\n *  Equality---Two arrays are equal if they contain the same number\n *  of elements and if each element is equal to (according to\n *  Object.==) the corresponding element in the other array.\n *\n *     [ \"a\", \"c\" ]    == [ \"a\", \"c\", 7 ]     #=> false\n *     [ \"a\", \"c\", 7 ] == [ \"a\", \"c\", 7 ]     #=> true\n *     [ \"a\", \"c\", 7 ] == [ \"a\", \"d\", \"f\" ]   #=> false\n *\n */\n\nstatic VALUE\nrb_ary_equal(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    if (ary1 == ary2) return Qtrue;\n    if (TYPE(ary2) != T_ARRAY) {\n\tif (!rb_respond_to(ary2, rb_intern(\"to_ary\"))) {\n\t    return Qfalse;\n\t}\n\treturn rb_equal(ary2, ary1);\n    }\n    if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;\n    return rb_exec_recursive(recursive_equal, ary1, ary2);\n}\n\nstatic VALUE recursive_eql _((VALUE, VALUE, int));\nstatic VALUE\nrecursive_eql(ary1, ary2, recur)\n    VALUE ary1, ary2;\n    int recur;\n{\n    long i;\n\n    if (recur) return Qfalse;\n    for (i=0; i<RARRAY(ary1)->len; i++) {\n\tif (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))\n\t    return Qfalse;\n    }\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     array.eql?(other)  -> true or false\n *\n *  Returns <code>true</code> if _array_ and _other_ are the same object,\n *  or are both arrays with the same content.\n */\n\nstatic VALUE\nrb_ary_eql(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    if (ary1 == ary2) return Qtrue;\n    if (TYPE(ary2) != T_ARRAY) return Qfalse;\n    if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse;\n    return rb_exec_recursive(recursive_eql, ary1, ary2);\n}\n\nstatic VALUE recursive_hash _((VALUE, VALUE, int));\nstatic VALUE\nrecursive_hash(ary, dummy, recur)\n    VALUE ary;\n    VALUE dummy;\n    int recur;\n{\n    long i, h;\n    VALUE n;\n\n    if (recur) {\n\treturn LONG2FIX(0);\n    }\n\n    h = RARRAY(ary)->len;\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\th = (h << 1) | (h<0 ? 1 : 0);\n\tn = rb_hash(RARRAY(ary)->ptr[i]);\n\th ^= NUM2LONG(n);\n    }\n    return LONG2FIX(h);\n}\n\n/*\n *  call-seq:\n *     array.hash   -> fixnum\n *\n *  Compute a hash-code for this array. Two arrays with the same content\n *  will have the same hash code (and will compare using <code>eql?</code>).\n */\n\nstatic VALUE\nrb_ary_hash(ary)\n    VALUE ary;\n{\n    return rb_exec_recursive(recursive_hash, ary, 0);\n}\n\n/*\n *  call-seq:\n *     array.include?(obj)   -> true or false\n *  \n *  Returns <code>true</code> if the given object is present in\n *  <i>self</i> (that is, if any object <code>==</code> <i>anObject</i>),\n *  <code>false</code> otherwise.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.include?(\"b\")   #=> true\n *     a.include?(\"z\")   #=> false\n */\n\nVALUE\nrb_ary_includes(ary, item)\n    VALUE ary;\n    VALUE item;\n{\n    long i;\n    \n    for (i=0; i<RARRAY(ary)->len; i++) {\n\tif (rb_equal(RARRAY(ary)->ptr[i], item)) {\n\t    return Qtrue;\n\t}\n    }\n    return Qfalse;\n}\n\n\nstatic VALUE recursive_cmp _((VALUE, VALUE, int));\nstatic VALUE\nrecursive_cmp(ary1, ary2, recur)\n    VALUE ary1;\n    VALUE ary2;\n    int recur;\n{\n    long i, len;\n\n    if (recur) return Qnil;\n    len = RARRAY(ary1)->len;\n    if (len > RARRAY(ary2)->len) {\n\tlen = RARRAY(ary2)->len;\n    }\n    for (i=0; i<len; i++) {\n\tVALUE v = rb_funcall(rb_ary_elt(ary1, i), id_cmp, 1, rb_ary_elt(ary2, i));\n\tif (v != INT2FIX(0)) {\n\t    return v;\n\t}\n    }\n    return Qundef;\n}\n\n/* \n *  call-seq:\n *     array <=> other_array   ->  -1, 0, +1\n *\n *  Comparison---Returns an integer (-1, 0,\n *  or +1) if this array is less than, equal to, or greater than\n *  other_array.  Each object in each array is compared\n *  (using <=>). If any value isn't\n *  equal, then that inequality is the return value. If all the\n *  values found are equal, then the return is based on a\n *  comparison of the array lengths.  Thus, two arrays are\n *  ``equal'' according to <code>Array#<=></code> if and only if they have\n *  the same length and the value of each element is equal to the\n *  value of the corresponding element in the other array.\n *  \n *     [ \"a\", \"a\", \"c\" ]    <=> [ \"a\", \"b\", \"c\" ]   #=> -1\n *     [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ]            #=> +1\n *\n */\n\nVALUE\nrb_ary_cmp(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    long len;\n    VALUE v;\n\n    ary2 = to_ary(ary2);\n    if (ary1 == ary2) return INT2FIX(0);\n    v = rb_exec_recursive(recursive_cmp, ary1, ary2);\n    if (v != Qundef) return v;\n    len = RARRAY(ary1)->len - RARRAY(ary2)->len;\n    if (len == 0) return INT2FIX(0);\n    if (len > 0) return INT2FIX(1);\n    return INT2FIX(-1);\n}\n\nstatic VALUE\nary_make_hash(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    VALUE hash = rb_hash_new();\n    long i;\n\n    for (i=0; i<RARRAY(ary1)->len; i++) {\n\trb_hash_aset(hash, RARRAY(ary1)->ptr[i], Qtrue);\n    }\n    if (ary2) {\n\tfor (i=0; i<RARRAY(ary2)->len; i++) {\n\t    rb_hash_aset(hash, RARRAY(ary2)->ptr[i], Qtrue);\n\t}\n    }\n    return hash;\n}\n\n/* \n *  call-seq:\n *     array - other_array    -> an_array\n *\n *  Array Difference---Returns a new array that is a copy of\n *  the original array, removing any items that also appear in\n *  other_array. (If you need set-like behavior, see the\n *  library class Set.)\n *\n *     [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ]  #=>  [ 3, 3, 5 ]\n */\n\nstatic VALUE\nrb_ary_diff(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    VALUE ary3;\n    volatile VALUE hash;\n    long i;\n\n    hash = ary_make_hash(to_ary(ary2), 0);\n    ary3 = rb_ary_new();\n\n    for (i=0; i<RARRAY(ary1)->len; i++) {\n\tif (st_lookup(RHASH(hash)->tbl, RARRAY(ary1)->ptr[i], 0)) continue;\n\trb_ary_push(ary3, rb_ary_elt(ary1, i));\n    }\n    return ary3;\n}\n\n/* \n *  call-seq:\n *     array & other_array\n *\n *  Set Intersection---Returns a new array\n *  containing elements common to the two arrays, with no duplicates.\n *\n *     [ 1, 1, 3, 5 ] & [ 1, 2, 3 ]   #=> [ 1, 3 ]\n */\n\n\nstatic VALUE\nrb_ary_and(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    VALUE hash, ary3, v, vv;\n    long i;\n\n    ary2 = to_ary(ary2);\n    ary3 = rb_ary_new2(RARRAY(ary1)->len < RARRAY(ary2)->len ?\n\t    RARRAY(ary1)->len : RARRAY(ary2)->len);\n    hash = ary_make_hash(ary2, 0);\n\n    for (i=0; i<RARRAY(ary1)->len; i++) {\n\tv = vv = rb_ary_elt(ary1, i);\n\tif (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {\n\t    rb_ary_push(ary3, v);\n\t}\n    }\n\n    return ary3;\n}\n\n/* \n *  call-seq:\n *     array | other_array     ->  an_array\n *\n *  Set Union---Returns a new array by joining this array with\n *  other_array, removing duplicates.\n *\n *     [ \"a\", \"b\", \"c\" ] | [ \"c\", \"d\", \"a\" ]\n *            #=> [ \"a\", \"b\", \"c\", \"d\" ]\n */\n\nstatic VALUE\nrb_ary_or(ary1, ary2)\n    VALUE ary1, ary2;\n{\n    VALUE hash, ary3;\n    VALUE v, vv;\n    long i;\n\n    ary2 = to_ary(ary2);\n    ary3 = rb_ary_new2(RARRAY(ary1)->len+RARRAY(ary2)->len);\n    hash = ary_make_hash(ary1, ary2);\n\n    for (i=0; i<RARRAY(ary1)->len; i++) {\n\tv = vv = rb_ary_elt(ary1, i);\n\tif (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {\n\t    rb_ary_push(ary3, v);\n\t}\n    }\n    for (i=0; i<RARRAY(ary2)->len; i++) {\n\tv = vv = rb_ary_elt(ary2, i);\n\tif (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {\n\t    rb_ary_push(ary3, v);\n\t}\n    }\n    return ary3;\n}\n\n/*\n *  call-seq:\n *     array.uniq! -> array or nil\n *  \n *  Removes duplicate elements from _self_.\n *  Returns <code>nil</code> if no changes are made (that is, no\n *  duplicates are found).\n *     \n *     a = [ \"a\", \"a\", \"b\", \"b\", \"c\" ]\n *     a.uniq!   #=> [\"a\", \"b\", \"c\"]\n *     b = [ \"a\", \"b\", \"c\" ]\n *     b.uniq!   #=> nil\n */\n\nstatic VALUE\nrb_ary_uniq_bang(ary)\n    VALUE ary;\n{\n    VALUE hash, v, vv;\n    long i, j;\n\n    hash = ary_make_hash(ary, 0);\n\n    if (RARRAY(ary)->len == RHASH(hash)->tbl->num_entries) {\n\treturn Qnil;\n    }\n    for (i=j=0; i<RARRAY(ary)->len; i++) {\n\tv = vv = rb_ary_elt(ary, i);\n\tif (st_delete(RHASH(hash)->tbl, (st_data_t*)&vv, 0)) {\n\t    rb_ary_store(ary, j++, v);\n\t}\n    }\n    RARRAY(ary)->len = j;\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.uniq   -> an_array\n *  \n *  Returns a new array by removing duplicate values in <i>self</i>.\n *     \n *     a = [ \"a\", \"a\", \"b\", \"b\", \"c\" ]\n *     a.uniq   #=> [\"a\", \"b\", \"c\"]\n */\n\nstatic VALUE\nrb_ary_uniq(ary)\n    VALUE ary;\n{\n    ary = rb_ary_dup(ary);\n    rb_ary_uniq_bang(ary);\n    return ary;\n}\n\n/* \n *  call-seq:\n *     array.compact!    ->   array  or  nil\n *\n *  Removes +nil+ elements from array.\n *  Returns +nil+ if no changes were made.\n *\n *     [ \"a\", nil, \"b\", nil, \"c\" ].compact! #=> [ \"a\", \"b\", \"c\" ]\n *     [ \"a\", \"b\", \"c\" ].compact!           #=> nil\n */\n\nstatic VALUE\nrb_ary_compact_bang(ary)\n    VALUE ary;\n{\n    VALUE *p, *t, *end;\n\n    rb_ary_modify(ary);\n    p = t = RARRAY(ary)->ptr;\n    end = p + RARRAY(ary)->len;\n    \n    while (t < end) {\n\tif (NIL_P(*t)) t++;\n\telse *p++ = *t++;\n    }\n    if (RARRAY(ary)->len == (p - RARRAY(ary)->ptr)) {\n\treturn Qnil;\n    }\n    RARRAY(ary)->len = RARRAY(ary)->aux.capa = (p - RARRAY(ary)->ptr);\n    REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.compact     ->  an_array\n *\n *  Returns a copy of _self_ with all +nil+ elements removed.\n *\n *     [ \"a\", nil, \"b\", nil, \"c\", nil ].compact\n *                       #=> [ \"a\", \"b\", \"c\" ]\n */\n\nstatic VALUE\nrb_ary_compact(ary)\n    VALUE ary;\n{\n    ary = rb_ary_dup(ary);\n    rb_ary_compact_bang(ary);\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.nitems -> int\n *  \n *  Returns the number of non-<code>nil</code> elements in _self_.\n *\n *  May be zero.\n *     \n *     [ 1, nil, 3, nil, 5 ].nitems   #=> 3\n */\n\nstatic VALUE\nrb_ary_nitems(ary)\n    VALUE ary;\n{\n    long n = 0;\n    VALUE *p, *pend;\n\n    for (p = RARRAY(ary)->ptr, pend = p + RARRAY(ary)->len; p < pend; p++) {\n\tif (!NIL_P(*p)) n++;\n    }\n    return LONG2NUM(n);\n}\n\n/*\n *  call-seq:\n *     array.count      -> int\n *     array.count(obj) -> int\n *     array.count { |item| block }  -> int\n *  \n *  Returns the number of elements.  If an argument is given, counts\n *  the number of elements which equals to <i>obj</i>.  If a block is\n *  given, counts the number of elements yielding a true value.\n *\n *     ary = [1, 2, 4, 2]\n *     ary.count             # => 4\n *     ary.count(2)          # => 2\n *     ary.count{|x|x%2==0}  # => 3\n *\n */\n\nstatic VALUE\nrb_ary_count(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    long n = 0;\n\n    if (argc == 0) {\n\tVALUE *p, *pend;\n\n\tif (!rb_block_given_p())\n\t    return LONG2NUM(RARRAY_LEN(ary));\n\n\tfor (p = RARRAY_PTR(ary), pend = p + RARRAY_LEN(ary); p < pend; p++) {\n\t    if (RTEST(rb_yield(*p))) n++;\n\t}\n    }\n    else {\n\tVALUE obj, *p, *pend;\n\n\trb_scan_args(argc, argv, \"1\", &obj);\n\tif (rb_block_given_p()) {\n\t    rb_warn(\"given block not used\");\n\t}\n\tfor (p = RARRAY_PTR(ary), pend = p + RARRAY_LEN(ary); p < pend; p++) {\n\t    if (rb_equal(*p, obj)) n++;\n\t}\n    }\n\n    return LONG2NUM(n);\n}\n\nstatic VALUE\nflatten(ary, level, modified)\n    VALUE ary;\n    int level;\n    int *modified;\n{\n    long i = 0;\n    VALUE stack, result, tmp, elt;\n    st_table *memo;\n    st_data_t id;\n\n    stack = ary_new(0, ARY_DEFAULT_SIZE);\n    result = ary_new(0, RARRAY_LEN(ary));\n    memo = st_init_numtable();\n    st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);\n    *modified = 0;\n\n    while (1) {\n\twhile (i < RARRAY(ary)->len) {\n\t    elt = RARRAY(ary)->ptr[i++];\n\t    tmp = rb_check_array_type(elt);\n\t    if (RBASIC(result)->klass) {\n\t\trb_raise(rb_eRuntimeError, \"flatten reentered\");\n\t    }\n\t    if (NIL_P(tmp) || (level >= 0 && RARRAY(stack)->len / 2 >= level)) {\n\t\trb_ary_push(result, elt);\n\t    }\n\t    else {\n\t\t*modified = 1;\n\t\tid = (st_data_t)tmp;\n\t\tif (st_lookup(memo, id, 0)) {\n\t\t    st_free_table(memo);\n\t\t    rb_raise(rb_eArgError, \"tried to flatten recursive array\");\n\t\t}\n\t\tst_insert(memo, id, (st_data_t)Qtrue);\n\t\trb_ary_push(stack, ary);\n\t\trb_ary_push(stack, LONG2NUM(i));\n\t\tary = tmp;\n\t\ti = 0;\n\t    }\n\t}\n\tif (RARRAY(stack)->len == 0) {\n\t    break;\n\t}\n\tid = (st_data_t)ary;\n\tst_delete(memo, &id, 0);\n\ttmp = rb_ary_pop(stack);\n\ti = NUM2LONG(tmp);\n\tary = rb_ary_pop(stack);\n    }\n\n    st_free_table(memo);\n\n    RBASIC(result)->klass = rb_class_of(ary);\n    return result;\n}\n\n/*\n *  call-seq:\n *     array.flatten! -> array or nil\n *     array.flatten!(level) -> array or nil\n *  \n *  Flattens _self_ in place.\n *  Returns <code>nil</code> if no modifications were made (i.e.,\n *  <i>array</i> contains no subarrays.)  If the optional <i>level</i>\n *  argument determines the level of recursion to flatten.\n *     \n *     a = [ 1, 2, [3, [4, 5] ] ]\n *     a.flatten!   #=> [1, 2, 3, 4, 5]\n *     a.flatten!   #=> nil\n *     a            #=> [1, 2, 3, 4, 5]\n *     a = [ 1, 2, [3, [4, 5] ] ]\n *     a.flatten!(1) #=> [1, 2, 3, [4, 5]]\n */\n\nstatic VALUE\nrb_ary_flatten_bang(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    int mod = 0, level = -1;\n    VALUE result, lv;\n\n    rb_scan_args(argc, argv, \"01\", &lv);\n    if (!NIL_P(lv)) level = NUM2INT(lv);\n    if (level == 0) return ary;\n\n    result = flatten(ary, level, &mod);\n    if (mod == 0) return Qnil;\n    rb_ary_replace(ary, result);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     array.flatten -> an_array\n *     array.flatten(level) -> an_array\n *  \n *  Returns a new array that is a one-dimensional flattening of this\n *  array (recursively). That is, for every element that is an array,\n *  extract its elements into the new array.  If the optional\n *  <i>level</i> argument determines the level of recursion to flatten.\n *     \n *     s = [ 1, 2, 3 ]           #=> [1, 2, 3]\n *     t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]\n *     a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]\n *     a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n *     a = [ 1, 2, [3, [4, 5] ] ]\n *     a.flatten(1)              #=> [1, 2, 3, [4, 5]]\n */\n\nstatic VALUE\nrb_ary_flatten(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    int mod = 0, level = -1;\n    VALUE result, lv;\n\n    rb_scan_args(argc, argv, \"01\", &lv);\n    if (!NIL_P(lv)) level = NUM2INT(lv);\n    if (level == 0) return ary;\n\n    result = flatten(ary, level, &mod);\n    if (OBJ_TAINTED(ary)) OBJ_TAINT(result);\n\n    return result;\n}\n\n/*\n *  call-seq:\n *     array.shuffle!        -> array or nil\n *  \n *  Shuffles elements in _self_ in place.\n */\n\n\nstatic VALUE\nrb_ary_shuffle_bang(ary)\n    VALUE ary;\n{\n    long i = RARRAY(ary)->len;\n\n    rb_ary_modify(ary);\n    while (i) {\n\tlong j = rb_genrand_real()*i;\n\tVALUE tmp = RARRAY(ary)->ptr[--i];\n\tRARRAY(ary)->ptr[i] = RARRAY(ary)->ptr[j];\n\tRARRAY(ary)->ptr[j] = tmp;\n    }\n    return ary;\n}\n\n\n/*\n *  call-seq:\n *     array.shuffle -> an_array\n *  \n *  Returns a new array with elements of this array shuffled.\n *     \n *     a = [ 1, 2, 3 ]           #=> [1, 2, 3]\n *     a.shuffle                 #=> [2, 3, 1]\n */\n\nstatic VALUE\nrb_ary_shuffle(VALUE ary)\n{\n    ary = rb_ary_dup(ary);\n    rb_ary_shuffle_bang(ary);\n    return ary;\n}\n\n\n/*\n *  call-seq:\n *     array.choice        -> obj\n *  \n *  Choose a random element from an array.\n */\n\n\nstatic VALUE\nrb_ary_choice(ary)\n    VALUE ary;\n{\n    long i, j;\n\n    i = RARRAY(ary)->len;\n    if (i == 0) return Qnil;\n    j = rb_genrand_real()*i;\n    return RARRAY(ary)->ptr[j];\n}\n\n\n/*\n *  call-seq:\n *     ary.cycle {|obj| block }\n *     ary.cycle(n) {|obj| block }\n *  \n *  Calls <i>block</i> for each element repeatedly _n_ times or\n *  forever if none or nil is given.  If a non-positive number is\n *  given or the array is empty, does nothing.  Returns nil if the\n *  loop has finished without getting interrupted.\n *     \n *     a = [\"a\", \"b\", \"c\"]\n *     a.cycle {|x| puts x }  # print, a, b, c, a, b, c,.. forever.\n *     a.cycle(2) {|x| puts x }  # print, a, b, c, a, b, c.\n *     \n */\n\nstatic VALUE\nrb_ary_cycle(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    long n, i;\n    VALUE nv = Qnil;\n\n    rb_scan_args(argc, argv, \"01\", &nv);\n\n    RETURN_ENUMERATOR(ary, argc, argv);\n    if (NIL_P(nv)) {\n        n = -1;\n    }\n    else {\n        n = NUM2LONG(nv);\n        if (n <= 0) return Qnil;\n    }\n\n    while (RARRAY(ary)->len > 0 && (n < 0 || 0 < n--)) {\n        for (i=0; i<RARRAY(ary)->len; i++) {\n            rb_yield(RARRAY(ary)->ptr[i]);\n        }\n    }\n    return Qnil;\n}\n\n#define tmpbuf(n, size) rb_str_tmp_new((n)*(size))\n\n/*\n * Recursively compute permutations of r elements of the set [0..n-1].\n * When we have a complete permutation of array indexes, copy the values\n * at those indexes into a new array and yield that array. \n *\n * n: the size of the set \n * r: the number of elements in each permutation\n * p: the array (of size r) that we're filling in\n * index: what index we're filling in now\n * used: an array of booleans: whether a given index is already used\n * values: the Ruby array that holds the actual values to permute\n */\nstatic void\npermute0(n, r, p, index, used, values)\n    long n, r, *p, index;\n    int *used;\n    VALUE values;\n{\n    long i,j;\n    for (i = 0; i < n; i++) {\n\tif (used[i] == 0) {\n\t    p[index] = i;\n\t    if (index < r-1) {             /* if not done yet */\n\t\tused[i] = 1;               /* mark index used */\n\t\tpermute0(n, r, p, index+1, /* recurse */\n\t\t\t used, values);  \n\t\tused[i] = 0;               /* index unused */\n\t    }\n\t    else {\n\t\t/* We have a complete permutation of array indexes */\n\t\t/* Build a ruby array of the corresponding values */\n\t\t/* And yield it to the associated block */\n\t\tVALUE result = rb_ary_new2(r);\n\t\tVALUE *result_array = RARRAY(result)->ptr;\n\t\tconst VALUE *values_array = RARRAY(values)->ptr;\n\n\t\tfor (j = 0; j < r; j++) result_array[j] = values_array[p[j]];\n\t\tRARRAY(result)->len = r;\n\t\trb_yield(result);\n\t    }\n\t}\n    }\n}\n\n/*\n *  call-seq:\n *     ary.permutation { |p| block }          -> array\n *     ary.permutation                        -> enumerator\n *     ary.permutation(n) { |p| block }       -> array\n *     ary.permutation(n)                     -> enumerator\n *  \n * When invoked with a block, yield all permutations of length <i>n</i>\n * of the elements of <i>ary</i>, then return the array itself.\n * If <i>n</i> is not specified, yield all permutations of all elements.\n * The implementation makes no guarantees about the order in which \n * the permutations are yielded.\n *\n * When invoked without a block, return an enumerator object instead.\n * \n * Examples:\n *\n *     a = [1, 2, 3]\n *     a.permutation.to_a     #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]\n *     a.permutation(1).to_a  #=> [[1],[2],[3]]\n *     a.permutation(2).to_a  #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]\n *     a.permutation(3).to_a  #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]\n *     a.permutation(0).to_a  #=> [[]] # one permutation of length 0\n *     a.permutation(4).to_a  #=> []   # no permutations of length 4\n */\n\nstatic VALUE\nrb_ary_permutation(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    VALUE num;\n    long r, n, i;\n\n    n = RARRAY(ary)->len;                  /* Array length */\n    RETURN_ENUMERATOR(ary, argc, argv);   /* Return enumerator if no block */\n    rb_scan_args(argc, argv, \"01\", &num);\n    r = NIL_P(num) ? n : NUM2LONG(num);   /* Permutation size from argument */\n\n    if (r < 0 || n < r) { \n\t/* no permutations: yield nothing */\n    }\n    else if (r == 0) { /* exactly one permutation: the zero-length array */\n\trb_yield(rb_ary_new2(0));\n    }\n    else if (r == 1) { /* this is a special, easy case */\n\tfor (i = 0; i < RARRAY(ary)->len; i++) {\n\t    rb_yield(rb_ary_new3(1, RARRAY(ary)->ptr[i]));\n\t}\n    }\n    else {             /* this is the general case */\n\tvolatile VALUE t0 = tmpbuf(n,sizeof(long));\n\tlong *p = (long*)RSTRING(t0)->ptr;\n\tvolatile VALUE t1 = tmpbuf(n,sizeof(int));\n\tint *used = (int*)RSTRING(t1)->ptr;\n\tVALUE ary0 = ary_make_shared(ary); /* private defensive copy of ary */\n\n\tfor (i = 0; i < n; i++) used[i] = 0; /* initialize array */\n\n\tpermute0(n, r, p, 0, used, ary0); /* compute and yield permutations */\n\tRB_GC_GUARD(t0);\n\tRB_GC_GUARD(t1);\n    }\n    return ary;\n}\n\nstatic long\ncombi_len(n, k)\n    long n, k;\n{\n    long i, val = 1;\n\n    if (k*2 > n) k = n-k;\n    if (k == 0) return 1;\n    if (k < 0) return 0;\n    val = 1;\n    for (i=1; i <= k; i++,n--) {\n\tlong m = val;\n\tval *= n;\n\tif (val < m) {\n\t    rb_raise(rb_eRangeError, \"too big for combination\");\n\t}\n\tval /= i;\n    }\n    return val;\n}\n\n/*\n *  call-seq:\n *     ary.combination(n) { |c| block }    -> ary\n *     ary.combination(n)                  -> enumerator\n *  \n * When invoked with a block, yields all combinations of length <i>n</i> \n * of elements from <i>ary</i> and then returns <i>ary</i> itself.\n * The implementation makes no guarantees about the order in which \n * the combinations are yielded.\n *\n * When invoked without a block, returns an enumerator object instead.\n *     \n * Examples:\n *\n *     a = [1, 2, 3, 4]\n *     a.combination(1).to_a  #=> [[1],[2],[3],[4]]\n *     a.combination(2).to_a  #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]\n *     a.combination(3).to_a  #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]\n *     a.combination(4).to_a  #=> [[1,2,3,4]]\n *     a.combination(0).to_a  #=> [[]] # one combination of length 0\n *     a.combination(5).to_a  #=> []   # no combinations of length 5\n *     \n */\n\nstatic VALUE\nrb_ary_combination(ary, num)\n    VALUE ary;\n    VALUE num;\n{\n    long n, i, len;\n\n    n = NUM2LONG(num);\n    RETURN_ENUMERATOR(ary, 1, &num);\n    len = RARRAY(ary)->len;\n    if (n < 0 || len < n) {\n\t/* yield nothing */\n    }\n    else if (n == 0) {\n\trb_yield(rb_ary_new2(0));\n    }\n    else if (n == 1) {\n\tfor (i = 0; i < len; i++) {\n\t    rb_yield(rb_ary_new3(1, RARRAY(ary)->ptr[i]));\n\t}\n    }\n    else {\n\tvolatile VALUE t0 = tmpbuf(n+1, sizeof(long));\n\tlong *stack = (long*)RSTRING(t0)->ptr;\n\tlong nlen = combi_len(len, n);\n\tvolatile VALUE cc = rb_ary_new2(n);\n\tVALUE *chosen = RARRAY(cc)->ptr;\n\tlong lev = 0;\n\n\tRBASIC(cc)->klass = 0;\n\tMEMZERO(stack, long, n);\n\tstack[0] = -1;\n\tfor (i = 0; i < nlen; i++) {\n\t    chosen[lev] = RARRAY(ary)->ptr[stack[lev+1]];\n\t    for (lev++; lev < n; lev++) {\n\t\tchosen[lev] = RARRAY(ary)->ptr[stack[lev+1] = stack[lev]+1];\n\t    }\n\t    rb_yield(rb_ary_new4(n, chosen));\n\t    do {\n\t\tstack[lev--]++;\n\t    } while (lev && (stack[lev+1]+n == len+lev+1));\n\t}\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     ary.product(other_ary, ...)\n *  \n *  Returns an array of all combinations of elements from all arrays.\n *  The length of the returned array is the product of the length\n *  of ary and the argument arrays\n *     \n *     [1,2,3].product([4,5])     # => [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]\n *     [1,2].product([1,2])       # => [[1,1],[1,2],[2,1],[2,2]]\n *     [1,2].product([3,4],[5,6]) # => [[1,3,5],[1,3,6],[1,4,5],[1,4,6],\n *                                #     [2,3,5],[2,3,6],[2,4,5],[2,4,6]]\n *     [1,2].product()            # => [[1],[2]]\n *     [1,2].product([])          # => []\n */\n\nstatic VALUE\nrb_ary_product(argc, argv, ary)\n    int argc;\n    VALUE *argv;\n    VALUE ary;\n{\n    int n = argc+1;    /* How many arrays we're operating on */\n    volatile VALUE t0 = tmpbuf(n, sizeof(VALUE));\n    volatile VALUE t1 = tmpbuf(n, sizeof(int));\n    VALUE *arrays = (VALUE*)RSTRING(t0)->ptr; /* The arrays we're computing the product of */\n    int *counters = (int*)RSTRING(t1)->ptr; /* The current position in each one */\n    VALUE result;      /* The array we'll be returning */\n    long i,j;\n    long resultlen = 1;\n\n    RBASIC(t0)->klass = 0;\n    RBASIC(t1)->klass = 0;\n\n    /* initialize the arrays of arrays */\n    arrays[0] = ary;\n    for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);\n    \n    /* initialize the counters for the arrays */\n    for (i = 0; i < n; i++) counters[i] = 0;\n\n    /* Compute the length of the result array; return [] if any is empty */\n    for (i = 0; i < n; i++) {\n\tlong k = RARRAY(arrays[i])->len, l = resultlen;\n\tif (k == 0) return rb_ary_new2(0);\n\tresultlen *= k;\n\tif (resultlen < k || resultlen < l || resultlen / k != l) {\n\t    rb_raise(rb_eRangeError, \"too big to product\");\n\t}\n    }\n\n    /* Otherwise, allocate and fill in an array of results */\n    result = rb_ary_new2(resultlen);\n    for (i = 0; i < resultlen; i++) {\n\tint m;\n\t/* fill in one subarray */\n\tVALUE subarray = rb_ary_new2(n);\n\tfor (j = 0; j < n; j++) {\n\t    rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));\n\t}\n\n\t/* put it on the result array */\n\trb_ary_push(result, subarray);\n\n\t/*\n\t * Increment the last counter.  If it overflows, reset to 0\n\t * and increment the one before it.\n\t */\n\tm = n-1;\n\tcounters[m]++;\n\twhile (m > 0 && counters[m] == RARRAY(arrays[m])->len) {\n\t    counters[m] = 0;\n\t    m--;\n\t    counters[m]++;\n\t}\n    }\n\n    return result;\n}\n\n/*\n *  call-seq:\n *     ary.take(n)               => array\n *  \n *  Returns first n elements from <i>ary</i>.\n *     \n *     a = [1, 2, 3, 4, 5, 0]\n *     a.take(3)             # => [1, 2, 3]\n *     \n */\n\nstatic VALUE\nrb_ary_take(obj, n)\n    VALUE obj;\n    VALUE n;\n{\n    long len = NUM2LONG(n);\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"attempt to take negative size\");\n    }\n\n    return rb_ary_subseq(obj, 0, len);\n}\n\n/*\n *  call-seq:\n *     ary.take_while {|arr| block }   => array\n *  \n *  Passes elements to the block until the block returns nil or false,\n *  then stops iterating and returns an array of all prior elements.\n *     \n *     a = [1, 2, 3, 4, 5, 0]\n *     a.take_while {|i| i < 3 }   # => [1, 2]\n *     \n */\n\nstatic VALUE\nrb_ary_take_while(ary)\n    VALUE ary;\n{\n    long i;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\tif (!RTEST(rb_yield(RARRAY(ary)->ptr[i]))) break;\n    }\n    return rb_ary_take(ary, LONG2FIX(i));\n}\n\n/*\n *  call-seq:\n *     ary.drop(n)               => array\n *  \n *  Drops first n elements from <i>ary</i>, and returns rest elements\n *  in an array.\n *     \n *     a = [1, 2, 3, 4, 5, 0]\n *     a.drop(3)             # => [4, 5, 0]\n *     \n */\n\nstatic VALUE\nrb_ary_drop(ary, n)\n    VALUE ary;\n    VALUE n;\n{\n    VALUE result;\n    long pos = NUM2LONG(n);\n    if (pos < 0) {\n\trb_raise(rb_eArgError, \"attempt to drop negative size\");\n    }\n\n    result = rb_ary_subseq(ary, pos, RARRAY(ary)->len);\n    if (result == Qnil) result = rb_ary_new();\n    return result;\n}\n\n/*\n *  call-seq:\n *     ary.drop_while {|arr| block }   => array\n *  \n *  Drops elements up to, but not including, the first element for\n *  which the block returns nil or false and returns an array\n *  containing the remaining elements.\n *     \n *     a = [1, 2, 3, 4, 5, 0]\n *     a.drop_while {|i| i < 3 }   # => [3, 4, 5, 0]\n *     \n */\n\nstatic VALUE\nrb_ary_drop_while(ary)\n    VALUE ary;\n{\n    long i;\n\n    RETURN_ENUMERATOR(ary, 0, 0);\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\tif (!RTEST(rb_yield(RARRAY(ary)->ptr[i]))) break;\n    }\n    return rb_ary_drop(ary, LONG2FIX(i));\n}\n\n\n\n/* Arrays are ordered, integer-indexed collections of any object. \n * Array indexing starts at 0, as in C or Java.  A negative index is \n * assumed to be relative to the end of the array---that is, an index of -1 \n * indicates the last element of the array, -2 is the next to last \n * element in the array, and so on. \n */\n\nvoid\nInit_Array()\n{\n    rb_cArray  = rb_define_class(\"Array\", rb_cObject);\n    rb_include_module(rb_cArray, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cArray, ary_alloc);\n    rb_define_singleton_method(rb_cArray, \"[]\", rb_ary_s_create, -1);\n    rb_define_method(rb_cArray, \"initialize\", rb_ary_initialize, -1);\n    rb_define_method(rb_cArray, \"initialize_copy\", rb_ary_replace, 1);\n\n    rb_define_method(rb_cArray, \"to_s\", rb_ary_to_s, 0);\n    rb_define_method(rb_cArray, \"inspect\", rb_ary_inspect, 0);\n    rb_define_method(rb_cArray, \"to_a\", rb_ary_to_a, 0);\n    rb_define_method(rb_cArray, \"to_ary\", rb_ary_to_ary_m, 0);\n    rb_define_method(rb_cArray, \"frozen?\",  rb_ary_frozen_p, 0);\n\n    rb_define_method(rb_cArray, \"==\", rb_ary_equal, 1);\n    rb_define_method(rb_cArray, \"eql?\", rb_ary_eql, 1);\n    rb_define_method(rb_cArray, \"hash\", rb_ary_hash, 0);\n\n    rb_define_method(rb_cArray, \"[]\", rb_ary_aref, -1);\n    rb_define_method(rb_cArray, \"[]=\", rb_ary_aset, -1);\n    rb_define_method(rb_cArray, \"at\", rb_ary_at, 1);\n    rb_define_method(rb_cArray, \"fetch\", rb_ary_fetch, -1);\n    rb_define_method(rb_cArray, \"first\", rb_ary_first, -1);\n    rb_define_method(rb_cArray, \"last\", rb_ary_last, -1);\n    rb_define_method(rb_cArray, \"concat\", rb_ary_concat, 1);\n    rb_define_method(rb_cArray, \"<<\", rb_ary_push, 1);\n    rb_define_method(rb_cArray, \"push\", rb_ary_push_m, -1);\n    rb_define_method(rb_cArray, \"pop\", rb_ary_pop_m, -1);\n    rb_define_method(rb_cArray, \"shift\", rb_ary_shift_m, -1);\n    rb_define_method(rb_cArray, \"unshift\", rb_ary_unshift_m, -1);\n    rb_define_method(rb_cArray, \"insert\", rb_ary_insert, -1);\n    rb_define_method(rb_cArray, \"each\", rb_ary_each, 0);\n    rb_define_method(rb_cArray, \"each_index\", rb_ary_each_index, 0);\n    rb_define_method(rb_cArray, \"reverse_each\", rb_ary_reverse_each, 0);\n    rb_define_method(rb_cArray, \"length\", rb_ary_length, 0);\n    rb_define_alias(rb_cArray,  \"size\", \"length\");\n    rb_define_method(rb_cArray, \"empty?\", rb_ary_empty_p, 0);\n    rb_define_method(rb_cArray, \"find_index\", rb_ary_index, -1);\n    rb_define_method(rb_cArray, \"index\", rb_ary_index, -1);\n    rb_define_method(rb_cArray, \"rindex\", rb_ary_rindex, -1);\n    rb_define_method(rb_cArray, \"indexes\", rb_ary_indexes, -1);\n    rb_define_method(rb_cArray, \"indices\", rb_ary_indexes, -1);\n    rb_define_method(rb_cArray, \"join\", rb_ary_join_m, -1);\n    rb_define_method(rb_cArray, \"reverse\", rb_ary_reverse_m, 0);\n    rb_define_method(rb_cArray, \"reverse!\", rb_ary_reverse_bang, 0);\n    rb_define_method(rb_cArray, \"sort\", rb_ary_sort, 0);\n    rb_define_method(rb_cArray, \"sort!\", rb_ary_sort_bang, 0);\n    rb_define_method(rb_cArray, \"collect\", rb_ary_collect, 0);\n    rb_define_method(rb_cArray, \"collect!\", rb_ary_collect_bang, 0);\n    rb_define_method(rb_cArray, \"map\", rb_ary_collect, 0);\n    rb_define_method(rb_cArray, \"map!\", rb_ary_collect_bang, 0);\n    rb_define_method(rb_cArray, \"select\", rb_ary_select, 0);\n    rb_define_method(rb_cArray, \"values_at\", rb_ary_values_at, -1);\n    rb_define_method(rb_cArray, \"delete\", rb_ary_delete, 1);\n    rb_define_method(rb_cArray, \"delete_at\", rb_ary_delete_at_m, 1);\n    rb_define_method(rb_cArray, \"delete_if\", rb_ary_delete_if, 0);\n    rb_define_method(rb_cArray, \"reject\", rb_ary_reject, 0);\n    rb_define_method(rb_cArray, \"reject!\", rb_ary_reject_bang, 0);\n    rb_define_method(rb_cArray, \"zip\", rb_ary_zip, -1);\n    rb_define_method(rb_cArray, \"transpose\", rb_ary_transpose, 0);\n    rb_define_method(rb_cArray, \"replace\", rb_ary_replace, 1);\n    rb_define_method(rb_cArray, \"clear\", rb_ary_clear, 0);\n    rb_define_method(rb_cArray, \"fill\", rb_ary_fill, -1);\n    rb_define_method(rb_cArray, \"include?\", rb_ary_includes, 1);\n    rb_define_method(rb_cArray, \"<=>\", rb_ary_cmp, 1);\n\n    rb_define_method(rb_cArray, \"slice\", rb_ary_aref, -1);\n    rb_define_method(rb_cArray, \"slice!\", rb_ary_slice_bang, -1);\n\n    rb_define_method(rb_cArray, \"assoc\", rb_ary_assoc, 1);\n    rb_define_method(rb_cArray, \"rassoc\", rb_ary_rassoc, 1);\n\n    rb_define_method(rb_cArray, \"+\", rb_ary_plus, 1);\n    rb_define_method(rb_cArray, \"*\", rb_ary_times, 1);\n\n    rb_define_method(rb_cArray, \"-\", rb_ary_diff, 1);\n    rb_define_method(rb_cArray, \"&\", rb_ary_and, 1);\n    rb_define_method(rb_cArray, \"|\", rb_ary_or, 1);\n\n    rb_define_method(rb_cArray, \"uniq\", rb_ary_uniq, 0);\n    rb_define_method(rb_cArray, \"uniq!\", rb_ary_uniq_bang, 0);\n    rb_define_method(rb_cArray, \"compact\", rb_ary_compact, 0);\n    rb_define_method(rb_cArray, \"compact!\", rb_ary_compact_bang, 0);\n    rb_define_method(rb_cArray, \"flatten\", rb_ary_flatten, -1);\n    rb_define_method(rb_cArray, \"flatten!\", rb_ary_flatten_bang, -1);\n    rb_define_method(rb_cArray, \"nitems\", rb_ary_nitems, 0);\n    rb_define_method(rb_cArray, \"count\", rb_ary_count, -1);\n    rb_define_method(rb_cArray, \"shuffle!\", rb_ary_shuffle_bang, 0);\n    rb_define_method(rb_cArray, \"shuffle\", rb_ary_shuffle, 0);\n    rb_define_method(rb_cArray, \"choice\", rb_ary_choice, 0);\n    rb_define_method(rb_cArray, \"cycle\", rb_ary_cycle, -1);\n    rb_define_method(rb_cArray, \"permutation\", rb_ary_permutation, -1);\n    rb_define_method(rb_cArray, \"combination\", rb_ary_combination, 1);\n    rb_define_method(rb_cArray, \"product\", rb_ary_product, -1);\n\n    rb_define_method(rb_cArray, \"take\", rb_ary_take, 1);\n    rb_define_method(rb_cArray, \"take_while\", rb_ary_take_while, 0);\n    rb_define_method(rb_cArray, \"drop\", rb_ary_drop, 1);\n    rb_define_method(rb_cArray, \"drop_while\", rb_ary_drop_while, 0);\n\n    id_cmp = rb_intern(\"<=>\");\n    inspect_key = rb_intern(\"__inspect_key__\");\n}\n"
  },
  {
    "path": "b/source/stack_free_safe.sh",
    "content": "#!/bin/bash\nset -x\n\nset -e; make optflags='-DSTACK_FREE_SAFE_DEBUG=1' && sudo make install; set +e\n#set -e; make optflags='-DXXXSTACK_FREE_SAFE_DEBUG=1' && sudo make install; set +e\nPATH=\"/cnu/PACKAGES/ruby-ree-1.8.7-p253-thread-2-debian5/bin:$PATH\" make test-all 2>&1 | tee log.txt\n\ngrep 'calling stack_free' log.txt | wc -l\ngrep 'calling stack_free' log.txt | grep stack_free_safe_all_dead_threads | wc -l \n"
  },
  {
    "path": "bcc32/Makefile.sub",
    "content": "# -*- makefile -*-\n\nSHELL = $(COMSPEC)\nMKFILES = Makefile\n\n#### Start of system configuration section. ####\n!ifndef OS\nOS = bccwin32\n!endif\n!if !defined(RT)\n!error RT not defined.  Retry from configure pass.\n!endif\n\n## variables may be overridden by $(compile_dir)/Makefile\n!ifndef srcdir\nsrcdir = ..\n!endif\n!ifndef RUBY_INSTALL_NAME\nRUBY_INSTALL_NAME = ruby\n!endif\n!ifndef RUBYW_INSTALL_NAME\nRUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME:ruby=rubyw)\n!elif \"$(RUBYW_INSTALL_NAME)\" == \"$(RUBY_INSTALL_NAME)\"\nRUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME:ruby=rubyw)\n!endif\n!if \"$(RUBYW_INSTALL_NAME)\" == \"$(RUBY_INSTALL_NAME)\"\nRUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME)w\n!endif\n!ifndef RUBY_SO_NAME\nRUBY_SO_NAME = $(RT)-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR)\n!endif\n!ifndef icondirs\n!ifdef ICONDIRS\nicondirs=$(ICONDIRS)\n!endif\n!endif\n!ifdef icondirs\nicondirs=$(icondirs:\\=/)\niconinc=-I$(icondirs: = -I)\n!endif\n###############\n\nVPATH = $(srcdir):$(srcdir)/missing\n.SUFFIXES: .y\n\n!ifndef CC\nCC = bcc32\n!endif\n!ifndef CPP\nCPP = cpp32\n!endif\n!ifndef RC\nRC = brcc32\n!endif\n!ifndef YACC\nYACC = byacc\n!endif\n!ifndef AR\nAR = tlib\n!endif\n\nPURIFY =\nAUTOCONF = autoconf\nRM = $(srcdir:/=\\)\\win32\\rm.bat\n\n!if !defined(PROCESSOR_ARCHITECTURE)\nPROCESSOR_ARCHITECTURE = x86\n!endif\nMACHINE = $(PROCESSOR_ARCHITECTURE)\n!if \"$(PROCESSOR_ARCHITECTURE)\" == \"x86\"\n!ifndef PROCESSOR_LEVEL\nPROCESSOR_LEVEL = 5\n!endif\n!if 6 < $(PROCESSOR_LEVEL)\nPROCESSOR_LEVEL = 6\n!endif\nPROCESSOR_FLAG = -$(PROCESSOR_LEVEL)\nCPU = i$(PROCESSOR_LEVEL)86\nARCH = i386\n!else\nCPU = $(PROCESSOR_ARCHITECTURE)\nARCH = $(PROCESSOR_ARCHITECTURE)\n!endif\n!ifndef DEBUGFLAGS\nDEBUGFLAGS = \n!endif\n!ifndef OPTFLAGS\nOPTFLAGS = -O\n!endif\n\n!ifndef prefix\nprefix = /usr\n!endif\n!ifndef exec_prefix\nexec_prefix = $(prefix)\n!endif\n!ifndef libdir\nlibdir = $(exec_prefix)/lib\n!endif\n!if !defined(datadir)\ndatadir = /share\n!endif\n!ifndef EXTOUT\nEXTOUT = .ext\n!endif\n!ifndef RIDATADIR\nRIDATADIR = $(DESTDIR)$(datadir)/ri/$(MAJOR).$(MINOR)/system\n!endif\n!ifndef TESTUI\nTESTUI = console\n!endif\n!ifndef TESTS\nTESTS =\n!endif\n!ifndef RDOCTARGET\nRDOCTARGET = install-nodoc\n!endif\n\nOUTFLAG       = -o\n!ifndef CFLAGS\nCFLAGS = -q -tWR -tWC $(DEBUGFLAGS) $(OPTFLAGS) $(PROCESSOR_FLAG) -w- -wsus -wcpt -wdup -wext -wrng -wrpt -wzdi\n!endif\n!ifndef LDFLAGS\nLDFLAGS = -S:$(STACK)\n!endif\n!ifndef RFLAGS\nRFLAGS = $(iconinc)\n!endif\n!ifndef EXTLIBS\nEXTLIBS =\n!endif\n!ifndef MEMLIB\nMEMLIB =\n!endif\nLIBS = $(MEMLIB) cw32i.lib import32.lib ws2_32.lib $(EXTLIBS)\nMISSING = acosh.obj crypt.obj erf.obj win32.obj\n\n!ifndef STACK\nSTACK = 0x2000000\n!endif\n\nXCFLAGS = -DRUBY_EXPORT -I. -I$(srcdir) -I$(srcdir)/missing\n\nARFLAGS = /a /p32\nLD = ilink32 -q -Gn\nLDSHARED  = $(LD)\nXLDFLAGS  = -Tpe c0x32.obj\nWLDFLAGS  = -aa -Tpe c0w32.obj\nDLDFLAGS  = -Tpd c0d32.obj\nLIBRUBY_LDSHARED = $(LDSHARED)\nLIBRUBY_DLDFLAGS = -Gi $(DLDFLAGS) $(EXTLDFLAGS)\nLDOBJECTS = $(MAINOBJ)\n\nSOLIBS = \n\nEXEEXT = .exe\nPROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)\nWPROGRAM=$(RUBYW_INSTALL_NAME)$(EXEEXT)\nRUBYDEF = $(RUBY_SO_NAME).def\nMINIRUBY = .\\miniruby$(EXEEXT) -I$(srcdir)/lib $(MINIRUBYOPT)\nRUNRUBY = .\\$(PROGRAM) \"$(srcdir)/runruby.rb\" --extout=\"$(EXTOUT)\" --\n\nORGLIBPATH = $(LIB)\n\n#### End of system configuration section. ####\n\nLIBRUBY_A     = $(RUBY_SO_NAME)-static.lib\nLIBRUBY_SO    = $(RUBY_SO_NAME).dll\nLIBRUBY       = $(RUBY_SO_NAME).lib\nLIBRUBYARG    = $(LIBRUBY)\n\nPREP          = miniruby$(EXEEXT)\n\nOBJEXT        = obj\n\nINSTALLED_LIST= .installed.list\n\nWINMAINOBJ    = winmain.$(OBJEXT)\nMINIOBJS      = dmydln.$(OBJEXT)\n\n.path.c = .;$(srcdir);$(srcdir)/win32;$(srcdir)/missing\n.path.h = .;$(srcdir);$(srcdir)/win32;$(srcdir)/missing\n.path.y = $(srcdir)\n.path. = $(srcdir)\n\n.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) -I. $(CPPFLAGS) -c $(<:/=\\)\n\n.rc.res:\n\t$(RC) $(RFLAGS) -I. -I$(<D). $(iconinc) -I$(srcdir)/win32 $(RFLAGS) -fo$@ $(<:/=\\)\n\n.y.c:\n\t$(YACC) $(YFLAGS) $(<:\\=/)\n\tsed -e \"s!^ *extern char \\*getenv();!/* & */!;s/^\\(#.*\\)y\\.tab/\\1parse/\" y.tab.c > $(@F)\n\t@del y.tab.c\n\nall: $(srcdir)/bcc32/Makefile.sub $(srcdir)/common.mk\n\nruby: $(PROGRAM)\nrubyw: $(WPROGRAM)\n\n!include $(srcdir)/common.mk\n\n$(MKFILES): $(srcdir)/bcc32/Makefile.sub $(srcdir)/bcc32/configure.bat $(srcdir)/bcc32/setup.mak\n\t$(COMSPEC) /C $(srcdir:/=\\)\\bcc32\\configure.bat $(configure_args)\n\t@echo $(MKFILES) should be updated, re-run $(MAKE).\n\t@$(MAKE) > nul -q -f &&|\nPHONY: nul\n\t@exit\n|\n\nCONFIG_H = ./.config.h.time\n\nconfig: config.status\n\nconfig.status: $(CONFIG_H)\n\n$(CONFIG_H): $(MKFILES) $(srcdir)/bcc32/Makefile.sub\n\t@$(srcdir:/=\\)\\win32\\ifchange.bat config.h &&|\n\\#define HAVE_SYS_TYPES_H 1\n\\#define HAVE_SYS_STAT_H 1\n\\#define HAVE_STDLIB_H 1\n\\#define HAVE_STRING_H 1\n\\#define HAVE_MEMORY_H 1\n\\#define HAVE_OFF_T 1\n\\#define SIZEOF_INT 4\n\\#define SIZEOF_SHORT 2\n\\#define SIZEOF_LONG 4\n\\#define SIZEOF_LONG_LONG 0\n\\#define SIZEOF___INT64 8\n\\#define SIZEOF_OFF_T 4\n\\#define SIZEOF_VOIDP 4\n\\#define SIZEOF_FLOAT 4\n\\#define SIZEOF_DOUBLE 8\n\\#define SIZEOF_TIME_T 4\n\\#define HAVE_PROTOTYPES 1\n\\#define TOKEN_PASTE(x,y) x\\#\\#y\n\\#define HAVE_STDARG_PROTOTYPES 1\n\\#define NORETURN(x) x\n\\#define RUBY_EXTERN extern __declspec(dllimport)\n\\#define HAVE_DECL_SYS_NERR 1\n\\#define HAVE_LIMITS_H 1\n\\#define HAVE_FCNTL_H 1\n\\#define HAVE_UTIME_H 1\n\\#define HAVE_FLOAT_H 1\n\\#define rb_uid_t uid_t\n\\#define rb_gid_t gid_t\n\\#define rb_pid_t int\n\\#define HAVE_STRUCT_STAT_ST_RDEV 1\n\\#define HAVE_ST_RDEV 1\n\\#define GETGROUPS_T int\n\\#define RETSIGTYPE void\n\\#define HAVE_ALLOCA 1\n\\#define HAVE_DUP2 1\n\\#define HAVE_MEMMOVE 1\n\\#define HAVE_MKDIR 1\n\\#define HAVE_STRCASECMP 1\n\\#define HAVE_STRNCASECMP 1\n\\#define HAVE_STRERROR 1\n\\#define HAVE_STRFTIME 1\n\\#define HAVE_STRCHR 1\n\\#define HAVE_STRSTR 1\n\\#define HAVE_STRTOD 1\n\\#define HAVE_STRTOL 1\n\\#define HAVE_STRTOUL 1\n\\#define HAVE_VSNPRINTF 1\n\\#define HAVE_ISNAN 1\n\\#define HAVE_FINITE 1\n\\#define HAVE_HYPOT 1\n\\#define HAVE_FMOD 1\n\\#define HAVE_WAITPID 1\n\\#define HAVE_FSYNC 1\n\\#define HAVE_GETCWD 1\n\\#define HAVE_CHSIZE 1\n\\#define HAVE_TIMES 1\n\\#define HAVE_FCNTL 1\n\\#define HAVE_LINK 1\n\\#define HAVE_TELLDIR 1\n\\#define HAVE_SEEKDIR 1\n\\#define HAVE_COSH 1\n\\#define HAVE_SINH 1\n\\#define HAVE_TANH 1\n\\#define RSHIFT(x,y) ((x)>>(int)y)\n\\#define FILE_COUNT level\n\\#define FILE_READPTR curp\n\\#define RUBY_SETJMP(env) _setjmp(env)\n\\#define RUBY_LONGJMP(env,val) longjmp(env,val)\n\\#define RUBY_JMP_BUF jmp_buf\n\\#define inline __inline\n\\#define NEED_IO_SEEK_BETWEEN_RW 1\n\\#define STACK_GROW_DIRECTION -1\n\\#define DEFAULT_KCODE KCODE_NONE\n\\#define DLEXT \".so\"\n\\#define RUBY_LIB \"/lib/ruby/$(MAJOR).$(MINOR)\"\n\\#define RUBY_SITE_LIB \"/lib/ruby/site_ruby\"\n\\#define RUBY_SITE_LIB2 \"/lib/ruby/site_ruby/$(MAJOR).$(MINOR)\"\n\\#define RUBY_VENDOR_LIB \"/lib/ruby/vendor_ruby\"\n\\#define RUBY_VENDOR_LIB2 \"/lib/ruby/vendor_ruby/$(MAJOR).$(MINOR)\"\n\\#define RUBY_PLATFORM \"$(ARCH)-$(OS)\"\n\\#define RUBY_ARCHLIB \"/lib/ruby/$(MAJOR).$(MINOR)/$(ARCH)-$(OS)\"\n\\#define RUBY_SITE_ARCHLIB \"/lib/ruby/site_ruby/$(MAJOR).$(MINOR)/$(ARCH)-$(OS)\"\n\\#define RUBY_VENDOR_ARCHLIB \"/lib/ruby/vendor_ruby/$(MAJOR).$(MINOR)/$(ARCH)-$(OS)\"\n|\n\t@exit > $@\n\nconfig.status: $(MKFILES) $(srcdir)/bcc32/Makefile.sub $(srcdir)/common.mk\n\t@echo Creating $@\n\t@type > $@ &&|\n# Generated automatically by Makefile.sub.\ns,@SHELL@,$$(COMSPEC),;t t\ns,@BUILD_FILE_SEPARATOR@,\\,;t t\ns,@PATH_SEPARATOR@,;,;t t\ns,@CFLAGS@,$(CFLAGS),;t t\ns,@CPPFLAGS@,$(CPPFLAGS),;t t\ns,@CXXFLAGS@,$(CXXFLAGS),;t t\ns,@FFLAGS@,$(FFLAGS),;t t\ns,@LDFLAGS@,,;t t\ns,@LIBS@,$(LIBS),;t t\ns,@exec_prefix@,$${prefix},;t t\ns,@prefix@,,;t t\ns,@program_transform_name@,s,,,,;t t\ns,@bindir@,$${exec_prefix}/bin,;t t\ns,@sbindir@,$${exec_prefix}/sbin,;t t\ns,@libexecdir@,$${exec_prefix}/libexec,;t t\ns,@datadir@,$${prefix}/share,;t t\ns,@sysconfdir@,$${prefix}/etc,;t t\ns,@sharedstatedir@,/etc,;t t\ns,@localstatedir@,/var,;t t\ns,@libdir@,$${exec_prefix}/lib,;t t\ns,@includedir@,$${prefix}/include,;t t\ns,@oldincludedir@,/usr/include,;t t\ns,@infodir@,$${prefix}/info,;t t\ns,@mandir@,$${prefix}/man,;t t\ns,@build@,$(CPU)-pc-$(OS),;t t\ns,@build_alias@,$(CPU)-$(OS),;t t\ns,@build_cpu@,$(CPU),;t t\ns,@build_vendor@,pc,;t t\ns,@build_os@,$(OS),;t t\ns,@host@,$(CPU)-pc-$(OS),;t t\ns,@host_alias@,$(CPU)-$(OS),;t t\ns,@host_cpu@,$(CPU),;t t\ns,@host_vendor@,pc,;t t\ns,@host_os@,$(OS),;t t\ns,@target@,$(ARCH)-pc-$(OS),;t t\ns,@target_alias@,$(ARCH)-$(OS),;t t\ns,@target_cpu@,$(ARCH),;t t\ns,@target_vendor@,pc,;t t\ns,@target_os@,$(OS),;t t\ns,@CC@,$(CC),;t t\ns,@CPP@,cpp32,;t t\ns,@YACC@,$(YACC),;t t\ns,@RANLIB@,,;t t\ns,@AR@,$(AR),;t t\ns,@ARFLAGS@,$(ARFLAGS) ,;t t\ns,@LN_S@,$(LN_S),;t t\ns,@SET_MAKE@,MFLAGS = -$$(MAKEFLAGS),;t t\ns,@CP@,copy > nul,;t t\ns,@LIBOBJS@, acosh.obj crypt.obj erf.obj win32.obj,;t t\ns,@ALLOCA@,$(ALLOCA),;t t\ns,@DEFAULT_KCODE@,$(DEFAULT_KCODE),;t t\ns,@EXEEXT@,.exe,;t t\ns,@OBJEXT@,obj,;t t\ns,@XCFLAGS@,$(XCFLAGS),;t t\ns,@XLDFLAGS@,$(XLDFLAGS),;t t\ns,@DLDFLAGS@,$(DLDFLAGS),;t t\ns,@ARCH_FLAG@,$(ARCH_FLAG),;t t\ns,@STATIC@,$(STATIC),;t t\ns,@CCDLFLAGS@,,;t t\ns,@LDSHARED@,$(LDSHARED),;t t\ns,@DLEXT@,so,;t t\ns,@LIBEXT@,lib,;t t\ns,@STRIP@,$(STRIP),;t t\ns,@EXTSTATIC@,$(EXTSTATIC),;t t\ns,@setup@,Setup,;t t\ns,@MINIRUBY@,$(MINIRUBY),;t t\ns,@PREP@,miniruby$(EXEEXT),;t t\ns,@RUNRUBY@,$(RUNRUBY),;t t\ns,@EXTOUT@,$(EXTOUT),;t t\ns,@ARCHFILE@,,;t t\ns,@RDOCTARGET@,,;t t\ns,@LIBRUBY_LDSHARED@,$$(LDSHARED),;t t\ns,@LIBRUBY_DLDFLAGS@,-Gi $$(DLDFLAGS),;t t\ns,@RUBY_INSTALL_NAME@,$(RUBY_INSTALL_NAME),;t t\ns,@rubyw_install_name@,$(RUBYW_INSTALL_NAME),;t t\ns,@RUBYW_INSTALL_NAME@,$(RUBYW_INSTALL_NAME),;t t\ns,@RUBY_SO_NAME@,$(RUBY_SO_NAME),;t t\ns,@LIBRUBY_A@,$$(RUBY_SO_NAME)-static.lib,;t t\ns,@LIBRUBY_SO@,$$(RUBY_SO_NAME).dll,;t t\ns,@LIBRUBY_ALIASES@,$(LIBRUBY_ALIASES),;t t\ns,@LIBRUBY@,$$(RUBY_SO_NAME).lib,;t t\ns,@LIBRUBYARG@,$$(LIBRUBYARG_SHARED),;t t\ns,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A),;t t\ns,@LIBRUBYARG_SHARED@,$$(LIBRUBY),;t t\ns,@SOLIBS@,$(SOLIBS),;t t\ns,@DLDLIBS@,$(DLDLIBS),;t t\ns,@ENABLE_SHARED@,yes,;t t\ns,@OUTFLAG@,$(OUTFLAG),;t t\ns,@CPPOUTFILE@,,;t t\ns,@LIBPATHFLAG@, -L\"%s\",;t t\ns,@RPATHFLAG@,,;t t\ns,@LIBARG@,%s.lib,;t t\ns,@LINK_SO@,$$(LDSHARED) $$(DLDFLAGS) $$(LIBPATH) $$(OBJS), $$(@:/=\\), nul, $$(LIBS) $$(LOCAL_LIBS), $$(DEFFILE), $$(RESFILE),;t t\ns,@COMPILE_C@,$$(CC) $$(INCFLAGS) $$(CFLAGS) $$(CPPFLAGS) -c $$(<:/=\\),;t t\ns,@COMPILE_CXX@,$$(CXX) $$(INCFLAGS) $$(CXXFLAGS) $$(CPPFLAGS) -P -c $$(<:/=\\),;t t\ns,@COMPILE_RULES@,{$$(srcdir)}.%s{}.%s: {$$(topdir)}.%s{}.%s: {$$(hdrdir)}.%s{}.%s: .%s.%s:,;t t\ns,@RULE_SUBST@,{.;$$(VPATH)}%s,;t t\ns,@COMMON_LIBS@,m advapi32 avicap32 avifil32 cap comctl32 comdlg32 dlcapi gdi32 glu32 imagehlp imm32 inetmib1 kernel32 loadperf lsapi32 lz32 mapi32 mgmtapi mpr msacm32 msvfw32 nddeapi netapi32 ole32 oleaut32 oledlg olepro32 opengl32 pdh pkpd32 rasapi32 rasdlg rassapi rpcrt4 setupapi shell32 shfolder snmpapi sporder tapi32 url user32 vdmdbg version win32spl winmm wintrust wsock32,;t t\ns,@COMMON_MACROS@,WIN32_LEAN_AND_MEAN WIN32,;t t\ns,@COMMON_HEADERS@,winsock2.h windows.h,;t t\ns,@TRY_LINK@,$$(CC) -oconftest $$(INCFLAGS) -I$$(hdrdir) $$(CPPFLAGS) $$(CFLAGS) $$(LIBPATH) $$(LDFLAGS) $$(src) $$(LOCAL_LIBS) $$(LIBS),;t t\ns,@EXPORT_PREFIX@,_,;t t\ns,@arch@,$(ARCH)-$(OS),;t t\ns,@sitearch@,$(ARCH)-$(OS),;t t\ns,@sitedir@,$${prefix}/lib/ruby/site_ruby,;t t\ns,@vendordir@,$${prefix}/lib/ruby/vendor_ruby,;t t\ns,@configure_args@,--enable-shared $(configure_args),;t t\ns,@configure_input@,$$configure_input,;t t\ns,@srcdir@,$(srcdir),;t t\ns,@top_srcdir@,$(srcdir),;t t\n|\n\nminiruby$(EXEEXT):\n\t\t@echo $(LIBS)\n\t\t$(LD) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ) $(MINIOBJS),$@,nul,$(LIBRUBY_A) $(LIBS)\n\n$(PROGRAM):\t$(MAINOBJ) $(LIBRUBY_SO) $(RUBY_INSTALL_NAME).res\n\t\t$(LD) $(LDFLAGS) $(XLDFLAGS) $(MAINOBJ),$@,nul,$(LIBRUBYARG) $(LIBS),,$(RUBY_INSTALL_NAME).res\n\n$(WPROGRAM):\t$(MAINOBJ) $(WINMAINOBJ) $(LIBRUBY_SO) $(RUBYW_INSTALL_NAME).res\n\t\t$(LD) $(LDFLAGS) $(WLDFLAGS) $(MAINOBJ) $(WINMAINOBJ),$@,nul,$(LIBRUBYARG) $(LIBS),,$(RUBYW_INSTALL_NAME).res\n\n$(LIBRUBY_A):\t$(OBJS) $(DMYEXT)\n\t\t@-if exist $@ del $@\n\t\t$(AR) $(ARFLAGS) \"$@\" $(OBJS) $(DMYEXT)\n\n# $(LIBRUBY):\t$(LIBRUBY_SO)\n#\t\timplib $@ $(LIBRUBY_SO)\n\n$(LIBRUBY_SO): $(LIBRUBY_A) $(DLDOBJS) $(RUBYDEF) $(RUBY_SO_NAME).res\n\t\t@echo $(DLDOBJS)\n\t\t@$(PRE_LIBRUBY_UPDATE)\n\t\t$(LIBRUBY_LDSHARED) $(LIBRUBY_DLDFLAGS) $(DLDOBJS:/=\\),$(LIBRUBY_SO),nul,$(LIBRUBY_A) $(LIBS),$(RUBYDEF),$(RUBY_SO_NAME).res\n\n$(LIBRUBY): $(LIBRUBY_SO)\n\n$(RUBYDEF):\t$(LIBRUBY_A) $(PREP)\n\t\t$(MINIRUBY) $(srcdir)/bcc32/mkexports.rb -output=$@ -base=$(RUBY_SO_NAME) $(LIBRUBY_A)\n\n$(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc: rbconfig.rb\n\t\t@$(MINIRUBY) $(srcdir)/win32/resource.rb \\\n\t\t\t-ruby_name=$(RUBY_INSTALL_NAME) \\\n\t\t\t-rubyw_name=$(RUBYW_INSTALL_NAME) \\\n\t\t\t-so_name=$(RUBY_SO_NAME) \\\n\t\t\t. $(icondirs) $(srcdir)/win32\n\npost-install-bin::\n\t@$(NULLCMD)\npost-install-lib::\n\t@$(NULLCMD)\npost-install-ext-comm::\n\t@$(NULLCMD)\npost-install-ext-arch::\n\t@$(NULLCMD)\npost-install-man::\n\t@$(NULLCMD)\npost-install-doc::\n\t@$(NULLCMD)\n\nclean-local::\n\t\t@$(RM) $(WINMAINOBJ) ext\\extinit.c ext\\extinit.$(OBJEXT) *.tds *.il? $(RUBY_SO_NAME).lib\n\t\t@$(RM) $(RUBY_INSTALL_NAME).res $(RUBYW_INSTALL_NAME).res $(RUBY_SO_NAME).res\n\t\t@$(RM) *.map *.pdb *.ilk *.exp $(RUBYDEF)\n\ndistclean-local::\n\t\t@$(RM) ext\\config.cache $(RBCONFIG:/=\\)\n\t\t@$(RM) $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc\n\nupdate-rubyspec:\n\t@echo SPEC_EXISTS=0 > $@.mk\n\t@if exist $(srcdir:/=\\)\\rubyspec\\nul echo SPEC_EXISTS=1 >> $@.mk\n\t@type >> $@.mk &&|\n$()update-rubyspec:\n$()\t@del $@.mk\n$()!if $$(SPEC_EXISTS)\n$()\tcd $(srcdir:/=\\)\\rubyspec\\mspec\n$()\tgit pull\n$()\tcd ..\\spec\\rubyspec\n$()\tgit pull\n$()!else\n$()\tgit clone $(MSPEC_GIT_URL) $(srcdir)/rubyspec/mspec\n$()\tgit clone $(RUBYSPEC_GIT_URL) $(srcdir)/rubyspec/spec/rubyspec\n$()!endif\n|\n\t@$(MAKE) -$(MAKEFLAGS)$(MFLAGS) -f $@.mk\n\ntest-rubyspec:\n\t@echo SPEC_EXISTS=0 > $@.mk\n\t@if exist $(srcdir:/=\\)\\rubyspec\\nul echo SPEC_EXISTS=1 >> $@.mk\n\t@type >> $@.mk &&|\n$()test-rubyspec:\n$()!if $$(SPEC_EXISTS)\n$()\t$(RUNRUBY) $(srcdir)/rubyspec/mspec/bin/mspec -r$(srcdir)/ext/purelib.rb $(srcdir)/rubyspec/spec/rubyspec/$(MAJOR).$(MINOR)\n$()!else\n$()\t@echo No rubyspec here.  put rubyspec to srcdir first.\n$()\t@cd $(srcdir:/=\\)\\rubyspec\n$()!endif\n|\n\t@$(MAKE) -$(MAKEFLAGS) -f $@.mk\n\next/extinit.obj: ext/extinit.c $(SETUP)\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -o$@ -c ext/extinit.c\n\nmain.$(OBJEXT): win32.h\narray.$(OBJEXT): win32.h\nbignum.$(OBJEXT): win32.h\nclass.$(OBJEXT): win32.h\ncompar.$(OBJEXT): win32.h\ndir.$(OBJEXT): dir.h win32.h\ndln.$(OBJEXT): win32.h\nenum.$(OBJEXT): win32.h\nerror.$(OBJEXT): win32.h\neval.$(OBJEXT): win32.h\nfile.$(OBJEXT): win32.h\ngc.$(OBJEXT): win32.h\nhash.$(OBJEXT): win32.h\ninits.$(OBJEXT): win32.h\nio.$(OBJEXT): win32.h\nmarshal.$(OBJEXT): win32.h\nmath.$(OBJEXT): win32.h\nnumeric.$(OBJEXT): win32.h\nobject.$(OBJEXT): win32.h\npack.$(OBJEXT): win32.h\nparse.$(OBJEXT): win32.h\nprocess.$(OBJEXT): win32.h\nprec.$(OBJEXT): win32.h\nrandom.$(OBJEXT): win32.h\nrange.$(OBJEXT): win32.h\nre.$(OBJEXT): win32.h\nregex.$(OBJEXT): win32.h\nruby.$(OBJEXT): win32.h\nsignal.$(OBJEXT): win32.h\nsprintf.$(OBJEXT): win32.h\nst.$(OBJEXT): win32.h\nstring.$(OBJEXT): win32.h\nstruct.$(OBJEXT): win32.h\ntime.$(OBJEXT): win32.h\nutil.$(OBJEXT): win32.h\nvariable.$(OBJEXT): win32.h\nversion.$(OBJEXT): win32.h\n"
  },
  {
    "path": "bcc32/README.bcc32",
    "content": "=begin\n\n= How to build ruby using Borland C++\n\n== Requirement\n\n(1) Borland C++ 5.0 or later.\n\n(2) Please set environment variable (({PATH}))\n    to run required commands properly from the command line.\n\n    Note: building ruby requires following commands.\n     * make\n     * bcc32\n     * tlib\n     * ilink32\n\n(3) If you want to build from CVS source, following commands are required.\n     * byacc ((<URL:http://gnuwin32.sourceforge.net/packages/byacc.htm>))\n     * sed   ((<URL:http://gnuwin32.sourceforge.net/packages/sed.htm>))\n\n(4) We strongly recommend to build ruby on C++Builder, to link following files.\n     * usebormm.lib\n     * memmgr.lib\n\n    RTL's internal memory manager cannot handle large memory block properly,\n    so we should use borlndmm.dll instead.\n     10000.times { \"\" << \".\" * 529671; GC.start } # crash\n\n== How to compile and install\n\n(1) Execute bcc32\\configure.bat on your build directory.\n     ex. c:\\ruby-1.6.7>bcc32\\configure.bat\n     \n(2) Change ((|RUBY_INSTALL_NAME|)) and ((|RUBY_SO_NAME|)) in (({Makefile}))\n    if you want to change the name of the executable files. \n    And add ((|RUBYW_INSTALL_NAME|)) to change the name of the\n    executable without console window if also you want.\n\n(3) Run `((%make%))'\n\n(4) Run `((%make test%))'\n\n(5) Run `((%make DESTDIR=<install_directory> install%))'\n\n    This command will create following directories and install files onto them.\n      * <install_directory>\\bin\n      * <install_directory>\\lib\n      * <install_directory>\\lib\\ruby\n      * <install_directory>\\lib\\ruby\\<MAJOR>.<MINOR>\n      * <install_directory>\\lib\\ruby\\<MAJOR>.<MINOR>\\<PLATFORM>\n      * <install_directory>\\lib\\ruby\\site_ruby\n      * <install_directory>\\lib\\ruby\\site_ruby\\<MAJOR>.<MINOR>\n      * <install_directory>\\lib\\ruby\\site_ruby\\<MAJOR>.<MINOR>\\<PLATFORM>\n      * <install_directory>\\man\\man1\n    If Ruby's version is `x.y.z', the ((|<MAJOR>|)) is `x' and the ((|<MINOR>|)) is `y'.\n    The ((|<PLATFORM>|)) is usually `(({i586-bccwin32}))'.\n\n(6) Requires dynamic RTL (cc3250.dll on C++Builder5) and borlndmm.dll (If built with\n    usebormm.lib) to use installed binary. These files are ordinary in bcc32's bin\n    directory.\n\n== Icons\n\nAny icon files(*.ico) in the build directory, directories specified with\n((|icondirs|)) make variable and (({win32})) directory under the ruby\nsource directory will be included in DLL or executable files, according\nto their base names.\n    $(RUBY_INSTALL_NAME).ico or ruby.ico   --> $(RUBY_INSTALL_NAME).exe\n    $(RUBYW_INSTALL_NAME).ico or rubyw.ico --> $(RUBYW_INSTALL_NAME).exe\n    the others                             --> $(RUBY_SO_NAME).dll\n\nAlthough no icons are distributed with the ruby source or in the official \nsite, you can use anything you like. For example, followings are written \nin Japanese, but you can download at least.\n\n* ((<URL:http://member.nifty.ne.jp/ueivu/rubyico.html>)) or\n  ((<zipped icons|URL:http://member.nifty.ne.jp/ueivu/Ruby_ico.zip>))\n* ((<URL:http://homepage1.nifty.com/a_nakata/ruby/>)) or\n  ((<icon itself|URL:http://homepage1.nifty.com/a_nakata/ruby/RubyIcon.ico>))\n\n== Build examples\n\n* Build on the ruby source directory.\n\n  ex.)\n    ruby source directory:  C:\\ruby\n    build directory:        C:\\ruby\n    install directory:      C:\\usr\\local\n\n    C:\n    cd \\ruby\n    bcc32\\configure\n    make\n    make test\n    make DESTDIR=/usr/local install\n\n* Build on the relative directory from the ruby source directory and CPU type \n  i386.\n\n  ex.)\n    ruby source directory:  C:\\ruby\n    build directory:        C:\\ruby\\bccwin32\n    install directory:      C:\\usr\\local\n    CPU                     i386\n    \n    C:\n    cd \\ruby\n    mkdir bccwin32\n    cd bccwin32\n    ..\\bcc32\\configure target i386-bccwin32\n    make\n    make test\n    make DESTDIR=/usr/local install\n\n* Build on the different drive.\n\n  ex.)\n    ruby source directory:  C:\\src\\ruby\n    build directory:        D:\\build\\ruby\n    install directory:      C:\\usr\\local\n\n    D:\n    cd D:\\build\\ruby\n    C:\\src\\ruby\\bcc32\\configure\n    make\n    make test\n    make DESTDIR=C:/usr/local install\n\n== Bugs\n\nYou can ((*NOT*)) use a path name contains any white space characters as\nthe ruby source directory, this restriction comes from the behavior of\n(({!INCLUDE})) directives of (({MAKE})).\n((- you may call it a bug. -))\n\n=end\n"
  },
  {
    "path": "bcc32/configure.bat",
    "content": "@echo off\r\n::: Don't set environment variable in batch file other than autoexec.bat\r\n::: to avoid \"Out of environment space\" problem on Windows 95/98.\r\n::: set TMPMAKE=~tmp~.mak\r\n\r\necho> ~tmp~.mak ####\r\necho>> ~tmp~.mak conf = %0\r\necho>> ~tmp~.mak $(conf:\\=/): nul\r\necho>> ~tmp~.mak \t@del ~setup~.mak\r\necho>> ~tmp~.mak \t@-$(MAKE) -l$(MAKEFLAGS) -f $(@D)setup.mak \\\r\nif exist pathlist.tmp del pathlist.tmp\r\nif exist confargs.mk del confargs.mk\r\n:loop\r\nif \"%1\" == \"\" goto :end\r\nif \"%1\" == \"--prefix\" goto :prefix\r\nif \"%1\" == \"prefix\" goto :prefix\r\nif \"%1\" == \"--srcdir\" goto :srcdir\r\nif \"%1\" == \"srcdir\" goto :srcdir\r\nif \"%1\" == \"--target\" goto :target\r\nif \"%1\" == \"target\" goto :target\r\nif \"%1\" == \"--with-static-linked-ext\" goto :extstatic\r\nif \"%1\" == \"--program-suffix\" goto :suffix\r\nif \"%1\" == \"RUBY_SUFFIX\" goto :suffix\r\nif \"%1\" == \"--program-name\" goto :installname\r\nif \"%1\" == \"--install-name\" goto :installname\r\nif \"%1\" == \"RUBY_INSTALL_NAME\" goto :installname\r\nif \"%1\" == \"--so-name\" goto :soname\r\nif \"%1\" == \"RUBY_SO_NAME\" goto :soname\r\nif \"%1\" == \"--enable-install-doc\" goto :enable-rdoc\r\nif \"%1\" == \"--disable-install-doc\" goto :disable-rdoc\r\nif \"%1\" == \"--extout\" goto :extout\r\nif \"%1\" == \"EXTOUT\" goto :extout\r\nif \"%1\" == \"--path\" goto :path\r\nif \"%1\" == \"-h\" goto :help\r\nif \"%1\" == \"--help\" goto :help\r\n  echo>>confargs.tmp \t%1 \\\r\n  shift\r\ngoto :loop\r\n:srcdir\r\n  echo>> ~tmp~.mak \t-Dsrcdir=%2 \\\r\n  echo>>confargs.tmp \t--srcdir=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:prefix\r\n  echo>> ~tmp~.mak \t-Dprefix=%2 \\\r\n  echo>>confargs.tmp \t%1=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:suffix\r\n  echo>>confargs.mk !ifndef RUBY_SUFFIX\r\n  echo>>confargs.mk RUBY_SUFFIX = %2\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:installname\r\n  echo>>confargs.mk !ifndef RUBY_INSTALL_NAME\r\n  echo>>confargs.mk RUBY_INSTALL_NAME = %2\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:soname\r\n  echo>>confargs.mk !ifndef RUBY_SO_NAME\r\n  echo>>confargs.mk RUBY_SO_NAME = %2\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:target\r\n  echo>> ~tmp~.mak \t%2 \\\r\n  echo>>confargs.tmp \t--target=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:extstatic\r\n  echo>>confargs.mk !ifndef EXTSTATIC\r\n  echo>>confargs.mk EXTSTATIC = static\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1 \\\r\n  shift\r\ngoto :loop\r\n:enable-rdoc\r\n  echo>>confargs.mk !ifndef RDOCTARGET\r\n  echo>>confargs.mk RDOCTARGET = install-doc\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1 \\\r\n  shift\r\ngoto :loop\r\n:disable-rdoc\r\n  echo>>confargs.mk !ifndef RDOCTARGET\r\n  echo>>confargs.mk RDOCTARGET = install-nodoc\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1 \\\r\n  shift\r\ngoto :loop\r\n:extout\r\n  echo>>confargs.mk !ifndef EXTOUT\r\n  echo>>confargs.mk EXTOUT = %2\r\n  echo>>confargs.mk !endif\r\n  echo>>confargs.tmp \t%1=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:path\r\n  echo>>pathlist.tmp %2;\\\r\n  echo>>confargs.tmp \t%1=%2 \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:help\r\n  echo Configuration:\r\n  echo   --help                  display this help\r\n  echo   --srcdir=DIR            find the sources in DIR [configure dir or `..']\r\n  echo Installation directories:\r\n  echo   --prefix=PREFIX         install files in PREFIX (ignored currently)\r\n  echo System types:\r\n  echo   --target=TARGET         configure for TARGET [i386-bccwin32]\r\n  echo Optional Package:\r\n  echo   --with-static-linked-ext link external modules statically\r\n  echo   --disable-install-doc   install rdoc indexes during install\r\n  del *.tmp\r\n  del ~tmp~.mak\r\ngoto :exit\r\n:end\r\necho>> ~tmp~.mak \t-Dbcc32dir=$(@D)\r\nif not exist confargs.tmp goto :noconfargs\r\n    echo>>confargs.mk configure_args = \\\r\n    type>>confargs.mk confargs.tmp\r\n    echo.>>confargs.mk\r\n    echo>>confargs.mk ####\r\n:noconfargs\r\nif not exist pathlist.tmp goto :nopathlist\r\n    echo>>confargs.mk pathlist = \\\r\n    type>>confargs.mk pathlist.tmp\r\n    echo.>>confargs.mk\r\n    echo>>confargs.mk ####\r\n    echo>>confargs.mk PATH = $(pathlist:;=/bin;)$(PATH)\r\n    echo>>confargs.mk INCLUDE = $(pathlist:;=/include;)\r\n    echo>>confargs.mk LIB = $(pathlist:;=/lib;)\r\n:nopathlist\r\nif exist confargs.mk copy confargs.mk ~setup~.mak > nul\r\ntype>>~setup~.mak ~tmp~.mak\r\ndel *.tmp > nul\r\ndel ~tmp~.mak > nul\r\nmake -s -f ~setup~.mak\r\n:exit\r\n"
  },
  {
    "path": "bcc32/mkexports.rb",
    "content": "#!./miniruby -s\n\n$name = $library = $description = nil\n\nSYM = {}\nSTDIN.reopen(open(\"nul\"))\nARGV.each do |obj|\n  IO.foreach(\"|tdump -q -oiPUBDEF -oiPUBD32 #{obj.tr('/', '\\\\')}\") do |l|\n    next unless /(?:PUBDEF|PUBD32)/ =~ l\n    SYM[$1] = true if /'(.*?)'/ =~ l\n  end\nend\n\nexports = []\nif $name\n  exports << \"Name \" + $name\nelsif $library\n  exports << \"Library \" + $library\nend\nexports << \"Description \" + $description.dump if $description\nexports << \"EXPORTS\" << SYM.keys.sort\n\nif $output\n  open($output, 'w') {|f| f.puts exports.join(\"\\n\")}\nelse\n  puts exports.join(\"\\n\")\nend\n"
  },
  {
    "path": "bcc32/setup.mak",
    "content": "# -*- makefile -*-\n\n!if \"$(srcdir)\" != \"\"\nbcc32dir = $(srcdir)/bcc32\n!elseif \"$(bcc32dir)\" == \"bcc32/\"\nsrcdir = .\n!elseif \"$(bcc32dir:/bcc32/=)/bcc32/\" == \"$(bcc32dir)\"\nsrcdir = $(bcc32dir:/bcc32/=)\n!else\nsrcdir = $(bcc32dir)/..\n!endif\n!ifndef prefix\nprefix = /usr\n!endif\nOS = bccwin32\nRT = $(OS)\nBANG = !\nAPPEND = echo>>$(MAKEFILE)\n!ifdef MAKEFILE\nMAKE = $(MAKE) -f $(MAKEFILE)\n!else\nMAKEFILE = Makefile\n!endif\n\nall: Makefile\nMakefile: -prologue- -generic- -epilogue-\ni386-$(OS): -prologue- -i386- -epilogue-\ni486-$(OS): -prologue- -i486- -epilogue-\ni586-$(OS): -prologue- -i586- -epilogue-\ni686-$(OS): -prologue- -i686- -epilogue-\nalpha-$(OS): -prologue- -alpha- -epilogue-\n\n-prologue-: -basic-vars- -version- -system-vars-\n\n-basic-vars-: nul\n\t@echo Creating $(MAKEFILE)\n\t@type > $(MAKEFILE) &&|\n\\#\\#\\# Makefile for ruby $(OS) \\#\\#\\#\n$(BANG)ifndef srcdir\nsrcdir = $(srcdir:\\=/)\n$(BANG)endif\n$(BANG)ifndef prefix\nprefix = $(prefix:\\=/)\n$(BANG)endif\n|\n!if exist(confargs.mk)\n\t@type confargs.mk >> $(MAKEFILE)\n\t@del confargs.mk\n!endif\n\n-system-vars-: -runtime- -bormm-\n\n-bormm-: nul\n\t@-ilink32 -q -Gn -x usebormm.lib > nul\n\t@-if exist usebormm.tds $(APPEND) MEMLIB = usebormm.lib\n\t@if exist usebormm.* del usebormm.*\n\n-osname-: nul\n\t@echo OS =  >>$(MAKEFILE)\n\n-runtime-: nul\n\ttype > conftest.c &&|\n\\#include <stdio.h>\nint main(){printf(\"\");return 0;}\n|\n\tbcc32 conftest.c cw32i.lib > nul\n\ttdump conftest.exe < nul > conftest.i\n\tgrep \"^Imports from CC\" conftest.i > conftest.c\n\tcpp32 -P- -DFile=\\# -DImports=RTNAME -Dfrom== conftest.c > nul\n\t$(MAKE) > nul -DBANG=$(BANG) -f &&|\n-runtime-: nul\n$(BANG)include conftest.i\nRT = $$(RTNAME:.DLL=)\nOS = $$(RT:CC32=)\n-runtime-:\n\tdel conftest.*\n$(BANG)if \"$$(OS)\" == \"50\"\n\techo OS = bccwin32 >> $(MAKEFILE)\n$(BANG)else\n\techo OS = bccwin32_$$(OS) >> $(MAKEFILE)\n$(BANG)endif\n|\n\t@echo RT = $$(OS) >> $(MAKEFILE)\n\n-version-: nul\n\t@cpp32 -I$(srcdir) -P- -o$(MAKEFILE) > nul &&|\n\\#include \"version.h\"\nMAJOR = RUBY_VERSION_MAJOR\nMINOR = RUBY_VERSION_MINOR\nTEENY = RUBY_VERSION_TEENY\n\nBORLANDC = __BORLANDC__\n|\n\t@$(MAKE) > nul -DBANG=$(BANG) -f &&,\n-version-: nul\n$(BANG)include $(MAKEFILE)\n$(BANG)include $(MAKEFILE).i\n-version-:\n\t@del $(MAKEFILE).i\n\t@type >> $(MAKEFILE) &&|\nMAJOR = $$(MAJOR)\nMINOR = $$(MINOR)\nTEENY = $$(TEENY)\nBORLANDC = $$(BORLANDC)\n|\n,\n\n-generic-: nul\n!if defined(PROCESSOR_ARCHITECTURE) ||  defined(PROCESSOR_LEVEL)\n\t@type >> $(MAKEFILE) &&|\n!if defined(PROCESSOR_ARCHITECTURE)\n$(BANG)ifndef PROCESSOR_ARCHITECTURE\nPROCESSOR_ARCHITECTURE = $(PROCESSOR_ARCHITECTURE)\n$(BANG)endif\n!endif\n!if defined(PROCESSOR_LEVEL)\n$(BANG)ifndef PROCESSOR_LEVEL\nPROCESSOR_LEVEL = $(PROCESSOR_LEVEL)\n$(BANG)endif\n!endif\n|\n!endif\n\n-alpha-: nul\n\t@$(APPEND) !ifndef PROCESSOR_ARCHITECTURE\n\t@$(APPEND) PROCESSOR_ARCHITECTURE = alpha\n\t@$(APPEND) !endif\n-ix86-: nul\n\t@$(APPEND) !ifndef PROCESSOR_ARCHITECTURE\n\t@$(APPEND) PROCESSOR_ARCHITECTURE = x86\n\t@$(APPEND) !endif\n\n-i386-: -ix86-\n\t@$(APPEND) !ifndef PROCESSOR_LEVEL\n\t@$(APPEND) PROCESSOR_LEVEL = 3\n\t@$(APPEND) !endif\n-i486-: -ix86-\n\t@$(APPEND) !ifndef PROCESSOR_LEVEL\n\t@$(APPEND) PROCESSOR_LEVEL = 4\n\t@$(APPEND) !endif\n-i586-: -ix86-\n\t@$(APPEND) !ifndef PROCESSOR_LEVEL\n\t@$(APPEND) PROCESSOR_LEVEL = 5\n\t@$(APPEND) !endif\n-i686-: -ix86-\n\t@$(APPEND) !ifndef PROCESSOR_LEVEL\n\t@$(APPEND) PROCESSOR_LEVEL = 6\n\t@$(APPEND) !endif\n\n-epilogue-: nul\n\t@type >> $(MAKEFILE) &&|\n\n\\# RUBY_INSTALL_NAME = ruby\n\\# RUBY_SO_NAME = $$(RT)-$$(RUBY_INSTALL_NAME)$$(MAJOR)$$(MINOR)\n\\# CFLAGS = -q $$(DEBUGFLAGS) $$(OPTFLAGS) $$(PROCESSOR_FLAG) -w- -wsus -wcpt -wdup -wext -wrng -wrpt -wzdi\n\\# CPPFLAGS = -I. -I$$(srcdir) -I$$(srcdir)/missing -DLIBRUBY_SO=\\\"$$(LIBRUBY_SO)\\\"\n\\# STACK = 0x2000000\n\\# LDFLAGS = -S:$$(STACK)\n\\# RFLAGS = $$(iconinc)\n\\# EXTLIBS = cw32.lib import32.lib user32.lib kernel32.lib\n$(BANG)include $$(srcdir)/bcc32/Makefile.sub\n|\n\t@echo type \"`$(MAKE)'\" to make ruby for $(OS).\n"
  },
  {
    "path": "bignum.c",
    "content": "/**********************************************************************\n\n  bignum.c -\n\n  $Author$\n  $Date$\n  created at: Fri Jun 10 00:48:55 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n\n#include <math.h>\n#include <float.h>\n#include <ctype.h>\n#ifdef HAVE_IEEEFP_H\n#include <ieeefp.h>\n#endif\n\nVALUE rb_cBignum;\n\n#if defined __MINGW32__\n#define USHORT _USHORT\n#endif\n\n#define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits)\n#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)\n#define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)\n#define DIGSPERLONG ((unsigned int)(SIZEOF_LONG/SIZEOF_BDIGITS))\n#if HAVE_LONG_LONG\n# define DIGSPERLL ((unsigned int)(SIZEOF_LONG_LONG/SIZEOF_BDIGITS))\n#endif\n#define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)\n#define BIGDN(x) RSHIFT(x,BITSPERDIG)\n#define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))\n#define BDIGMAX ((BDIGIT)-1)\n\n#define BIGZEROP(x) (RBIGNUM(x)->len == 0 || \\\n\t\t     (BDIGITS(x)[0] == 0 && \\\n\t\t      (RBIGNUM(x)->len == 1 || bigzero_p(x))))\n\nstatic int bigzero_p(VALUE);\nstatic int\nbigzero_p(x)\n    VALUE x;\n{\n    long i;\n    for (i = 0; i < RBIGNUM(x)->len; ++i) {\n\tif (BDIGITS(x)[i]) return 0;\n    }\n    return 1;\n}\n\nstatic VALUE\nbignew_1(klass, len, sign)\n    VALUE klass;\n    long len;\n    int sign;\n{\n    NEWOBJ(big, struct RBignum);\n    OBJSETUP(big, klass, T_BIGNUM);\n    big->sign = sign?1:0;\n    big->len = len;\n    big->digits = ALLOC_N(BDIGIT, len);\n\n    return (VALUE)big;\n}\n\n#define bignew(len,sign) bignew_1(rb_cBignum,len,sign)\n\nVALUE\nrb_big_clone(x)\n    VALUE x;\n{\n    VALUE z = bignew_1(CLASS_OF(x), RBIGNUM(x)->len, RBIGNUM(x)->sign);\n\n    MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT, RBIGNUM(x)->len);\n    return z;\n}\n\n/* modify a bignum by 2's complement */\nstatic void\nget2comp(x)\n    VALUE x;\n{\n    long i = RBIGNUM(x)->len;\n    BDIGIT *ds = BDIGITS(x);\n    BDIGIT_DBL num;\n\n    if (!i) return;\n    while (i--) ds[i] = ~ds[i];\n    i = 0; num = 1;\n    do {\n\tnum += ds[i];\n\tds[i++] = BIGLO(num);\n\tnum = BIGDN(num);\n    } while (i < RBIGNUM(x)->len);\n    if (num != 0) {\n\tREALLOC_N(RBIGNUM(x)->digits, BDIGIT, ++RBIGNUM(x)->len);\n\tds = BDIGITS(x);\n\tds[RBIGNUM(x)->len-1] = RBIGNUM(x)->sign ? ~0 : 1;\n    }\n}\n\nvoid\nrb_big_2comp(x)\t\t\t/* get 2's complement */\n    VALUE x;\n{\n    get2comp(x);\n}\n\nstatic VALUE\nbigtrunc(x)\n    VALUE x;\n{\n    long len = RBIGNUM(x)->len;\n    BDIGIT *ds = BDIGITS(x);\n\n    if (len == 0) return x;\n    while (--len && !ds[len]);\n    RBIGNUM(x)->len = ++len;\n    return x;\n}\n\nstatic VALUE\nbigfixize(x)\n    VALUE x;\n{\n    long len = RBIGNUM(x)->len;\n    BDIGIT *ds = BDIGITS(x);\n\n    if (len*SIZEOF_BDIGITS <= sizeof(VALUE)) {\n\tlong num = 0;\n\twhile (len--) {\n\t    num = BIGUP(num) + ds[len];\n\t}\n\tif (num >= 0) {\n\t    if (RBIGNUM(x)->sign) {\n\t\tif (POSFIXABLE(num)) return LONG2FIX(num);\n\t    }\n\t    else {\n\t\tif (NEGFIXABLE(-(long)num)) return LONG2FIX(-(long)num);\n\t    }\n\t}\n    }\n    return x;\n}\n\nstatic VALUE\nbignorm(x)\n    VALUE x;\n{\n    if (!FIXNUM_P(x) && TYPE(x) == T_BIGNUM) {\n\tx = bigfixize(bigtrunc(x));\n    }\n    return x;\n}\n\nVALUE\nrb_big_norm(x)\n    VALUE x;\n{\n    return bignorm(x);\n}\n\nVALUE\nrb_uint2big(n)\n    unsigned long n;\n{\n    BDIGIT_DBL num = n;\n    long i = 0;\n    BDIGIT *digits;\n    VALUE big;\n\n    big = bignew(DIGSPERLONG, 1);\n    digits = BDIGITS(big);\n    while (i < DIGSPERLONG) {\n\tdigits[i++] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n\n    i = DIGSPERLONG;\n    while (--i && !digits[i]) ;\n    RBIGNUM(big)->len = i+1;\n    return big;\n}\n\nVALUE\nrb_int2big(n)\n    long n;\n{\n    long neg = 0;\n    VALUE big;\n\n    if (n < 0) {\n\tn = -n;\n\tneg = 1;\n    }\n    big = rb_uint2big(n);\n    if (neg) {\n\tRBIGNUM(big)->sign = 0;\n    }\n    return big;\n}\n\nVALUE\nrb_uint2inum(n)\n    unsigned long n;\n{\n    if (POSFIXABLE(n)) return LONG2FIX(n);\n    return rb_uint2big(n);\n}\n\nVALUE\nrb_int2inum(n)\n    long n;\n{\n    if (FIXABLE(n)) return LONG2FIX(n);\n    return rb_int2big(n);\n}\n\n#ifdef HAVE_LONG_LONG\n\nvoid\nrb_quad_pack(buf, val)\n    char *buf;\n    VALUE val;\n{\n    LONG_LONG q;\n\n    val = rb_to_int(val);\n    if (FIXNUM_P(val)) {\n\tq = FIX2LONG(val);\n    }\n    else {\n\tlong len = RBIGNUM(val)->len;\n\tBDIGIT *ds;\n\n\tif (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS)\n\t    rb_raise(rb_eRangeError, \"bignum too big to convert into `quad int'\");\n\tds = BDIGITS(val);\n\tq = 0;\n\twhile (len--) {\n\t    q = BIGUP(q);\n\t    q += ds[len];\n\t}\n\tif (!RBIGNUM(val)->sign) q = -q;\n    }\n    memcpy(buf, (char*)&q, SIZEOF_LONG_LONG);\n}\n\nVALUE\nrb_quad_unpack(buf, sign)\n    const char *buf;\n    int sign;\n{\n    unsigned LONG_LONG q;\n    long neg = 0;\n    long i;\n    BDIGIT *digits;\n    VALUE big;\n\n    memcpy(&q, buf, SIZEOF_LONG_LONG);\n    if (sign) {\n\tif (FIXABLE((LONG_LONG)q)) return LONG2FIX((LONG_LONG)q);\n\tif ((LONG_LONG)q < 0) {\n\t    q = -(LONG_LONG)q;\n\t    neg = 1;\n\t}\n    }\n    else {\n\tif (POSFIXABLE(q)) return LONG2FIX(q);\n    }\n\n    i = 0;\n    big = bignew(DIGSPERLL, 1);\n    digits = BDIGITS(big);\n    while (i < DIGSPERLL) {\n\tdigits[i++] = BIGLO(q);\n\tq = BIGDN(q);\n    }\n\n    i = DIGSPERLL;\n    while (i-- && !digits[i]) ;\n    RBIGNUM(big)->len = i+1;\n\n    if (neg) {\n\tRBIGNUM(big)->sign = 0;\n    }\n    return bignorm(big);\n}\n\n#else\n\n#define QUAD_SIZE 8\n\nvoid\nrb_quad_pack(buf, val)\n    char *buf;\n    VALUE val;\n{\n    long len;\n\n    memset(buf, 0, QUAD_SIZE);\n    val = rb_to_int(val);\n    if (FIXNUM_P(val)) {\n\tval = rb_int2big(FIX2LONG(val));\n    }\n    len = RBIGNUM(val)->len * SIZEOF_BDIGITS;\n    if (len > QUAD_SIZE) {\n\trb_raise(rb_eRangeError, \"bignum too big to convert into `quad int'\");\n    }\n    memcpy(buf, (char*)BDIGITS(val), len);\n    if (!RBIGNUM(val)->sign) {\n\tlen = QUAD_SIZE;\n\twhile (len--) {\n\t    *buf = ~*buf;\n\t    buf++;\n\t}\n    }\n}\n\n#define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0)\n\nVALUE\nrb_quad_unpack(buf, sign)\n    const char *buf;\n    int sign;\n{\n    VALUE big = bignew(QUAD_SIZE/SIZEOF_BDIGITS, 1);\n\n    memcpy((char*)BDIGITS(big), buf, QUAD_SIZE);\n    if (sign && BNEG(buf)) {\n\tlong len = QUAD_SIZE;\n\tchar *tmp = (char*)BDIGITS(big);\n\n\tRBIGNUM(big)->sign = 0;\n\twhile (len--) {\n\t    *tmp = ~*tmp;\n\t    tmp++;\n\t}\n    }\n\n    return bignorm(big);\n}\n\n#endif\n\nVALUE\nrb_cstr_to_inum(str, base, badcheck)\n    const char *str;\n    int base;\n    int badcheck;\n{\n    const char *s = str;\n    char *end;\n    char sign = 1, nondigit = 0;\n    int c;\n    BDIGIT_DBL num;\n    long len, blen = 1;\n    long i;\n    VALUE z;\n    BDIGIT *zds;\n\n#define conv_digit(c) \\\n    (!ISASCII(c) ? -1 : \\\n     isdigit(c) ? ((c) - '0') : \\\n     islower(c) ? ((c) - 'a' + 10) : \\\n     isupper(c) ? ((c) - 'A' + 10) : \\\n     -1)\n\n    if (!str) {\n\tif (badcheck) goto bad;\n\treturn INT2FIX(0);\n    }\n    if (badcheck) {\n\twhile (ISSPACE(*str)) str++;\n    }\n    else {\n\twhile (ISSPACE(*str) || *str == '_') str++;\n    }\n\n    if (str[0] == '+') {\n\tstr++;\n    }\n    else if (str[0] == '-') {\n\tstr++;\n\tsign = 0;\n    }\n    if (str[0] == '+' || str[0] == '-') {\n\tif (badcheck) goto bad;\n\treturn INT2FIX(0);\n    }\n    if (base <= 0) {\n\tif (str[0] == '0') {\n\t    switch (str[1]) {\n\t      case 'x': case 'X':\n\t\tbase = 16;\n\t\tbreak;\n\t      case 'b': case 'B':\n\t\tbase = 2;\n\t\tbreak;\n\t      case 'o': case 'O':\n\t\tbase = 8;\n\t\tbreak;\n\t      case 'd': case 'D':\n\t\tbase = 10;\n\t\tbreak;\n\t      default:\n\t\tbase = 8;\n\t    }\n\t}\n\telse if (base < -1) {\n\t    base = -base;\n\t}\n\telse {\n\t    base = 10;\n\t}\n    }\n    switch (base) {\n      case 2:\n\tlen = 1;\n\tif (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {\n\t    str += 2;\n\t}\n\tbreak;\n      case 3:\n\tlen = 2;\n\tbreak;\n      case 8:\n\tif (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {\n\t    str += 2;\n\t}\n      case 4: case 5: case 6: case 7:\n\tlen = 3;\n\tbreak;\n      case 10:\n\tif (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {\n\t    str += 2;\n\t}\n      case 9: case 11: case 12: case 13: case 14: case 15:\n\tlen = 4;\n\tbreak;\n      case 16:\n\tlen = 4;\n\tif (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {\n\t    str += 2;\n\t}\n\tbreak;\n      default:\n\tif (base < 2 || 36 < base) {\n\t    rb_raise(rb_eArgError, \"illegal radix %d\", base);\n\t}\n\tif (base <= 32) {\n\t    len = 5;\n\t}\n\telse {\n\t    len = 6;\n\t}\n\tbreak;\n    }\n    if (*str == '0') {\t\t/* squeeze preceeding 0s */\n\tint us = 0;\n\twhile ((c = *++str) == '0' || c == '_') {\n\t    if (c == '_') {\n\t\tif (++us >= 2)\n\t\t    break;\n\t    } else\n\t\tus = 0;\n\t}\n\tif (!(c = *str) || ISSPACE(c)) --str;\n    }\n    c = *str;\n    c = conv_digit(c);\n    if (c < 0 || c >= base) {\n\tif (badcheck) goto bad;\n\treturn INT2FIX(0);\n    }\n    len *= strlen(str)*sizeof(char);\n\n    if (len <= (sizeof(VALUE)*CHAR_BIT)) {\n\tunsigned long val = strtoul((char*)str, &end, base);\n\n\tif (*end == '_') goto bigparse;\n\tif (badcheck) {\n\t    if (end == str) goto bad; /* no number */\n\t    while (*end && ISSPACE(*end)) end++;\n\t    if (*end) goto bad;\t      /* trailing garbage */\n\t}\n\n\tif (POSFIXABLE(val)) {\n\t    if (sign) return LONG2FIX(val);\n\t    else {\n\t\tlong result = -(long)val;\n\t\treturn LONG2FIX(result);\n\t    }\n\t}\n\telse {\n\t    VALUE big = rb_uint2big(val);\n\t    RBIGNUM(big)->sign = sign;\n\t    return bignorm(big);\n\t}\n    }\n  bigparse:\n    len = (len/BITSPERDIG)+1;\n    if (badcheck && *str == '_') goto bad;\n\n    z = bignew(len, sign);\n    zds = BDIGITS(z);\n    for (i=len;i--;) zds[i]=0;\n    while ((c = *str++) != 0) {\n\tif (c == '_') {\n\t    if (nondigit) {\n\t\tif (badcheck) goto bad;\n\t\tbreak;\n\t    }\n\t    nondigit = c;\n\t    continue;\n\t}\n\telse if ((c = conv_digit(c)) < 0) {\n\t    break;\n\t}\n\tif (c >= base) break;\n\tnondigit = 0;\n\ti = 0;\n\tnum = c;\n\tfor (;;) {\n\t    while (i<blen) {\n\t\tnum += (BDIGIT_DBL)zds[i]*base;\n\t\tzds[i++] = BIGLO(num);\n\t\tnum = BIGDN(num);\n\t    }\n\t    if (num) {\n\t\tblen++;\n\t\tcontinue;\n\t    }\n\t    break;\n\t}\n    }\n    if (badcheck) {\n\tstr--;\n\tif (s+1 < str && str[-1] == '_') goto bad;\n\twhile (*str && ISSPACE(*str)) str++;\n\tif (*str) {\n\t  bad:\n\t    rb_invalid_str(s, \"Integer\");\n\t}\n    }\n\n    return bignorm(z);\n}\n\nVALUE\nrb_str_to_inum(str, base, badcheck)\n    VALUE str;\n    int base;\n    int badcheck;\n{\n    char *s;\n    long len;\n\n    StringValue(str);\n    if (badcheck) {\n\ts = StringValueCStr(str);\n    }\n    else {\n\ts = RSTRING(str)->ptr;\n    }\n    if (s) {\n\tlen = RSTRING(str)->len;\n\tif (s[len]) {\t\t/* no sentinel somehow */\n\t    char *p = ALLOCA_N(char, len+1);\n\n\t    MEMCPY(p, s, char, len);\n\t    p[len] = '\\0';\n\t    s = p;\n\t}\n    }\n    return rb_cstr_to_inum(s, base, badcheck);\n}\n\n#if HAVE_LONG_LONG\n\nVALUE\nrb_ull2big(n)\n    unsigned LONG_LONG n;\n{\n    BDIGIT_DBL num = n;\n    long i = 0;\n    BDIGIT *digits;\n    VALUE big;\n\n    big = bignew(DIGSPERLL, 1);\n    digits = BDIGITS(big);\n    while (i < DIGSPERLL) {\n\tdigits[i++] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n\n    i = DIGSPERLL;\n    while (i-- && !digits[i]) ;\n    RBIGNUM(big)->len = i+1;\n    return big;\n}\n\nVALUE\nrb_ll2big(n)\n    LONG_LONG n;\n{\n    long neg = 0;\n    VALUE big;\n\n    if (n < 0) {\n\tn = -n;\n\tneg = 1;\n    }\n    big = rb_ull2big(n);\n    if (neg) {\n\tRBIGNUM(big)->sign = 0;\n    }\n    return big;\n}\n\nVALUE\nrb_ull2inum(n)\n    unsigned LONG_LONG n;\n{\n    if (POSFIXABLE(n)) return LONG2FIX(n);\n    return rb_ull2big(n);\n}\n\nVALUE\nrb_ll2inum(n)\n    LONG_LONG n;\n{\n    if (FIXABLE(n)) return LONG2FIX(n);\n    return rb_ll2big(n);\n}\n\n#endif  /* HAVE_LONG_LONG */\n\nVALUE\nrb_cstr2inum(str, base)\n    const char *str;\n    int base;\n{\n    return rb_cstr_to_inum(str, base, base==0);\n}\n\nVALUE\nrb_str2inum(str, base)\n    VALUE str;\n    int base;\n{\n    return rb_str_to_inum(str, base, base==0);\n}\n\nconst char ruby_digitmap[] = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nVALUE\nrb_big2str0(x, base, trim)\n    VALUE x;\n    int base;\n    int trim;\n{\n    volatile VALUE t;\n    BDIGIT *ds;\n    long i, j, hbase;\n    VALUE ss;\n    char *s;\n\n    if (FIXNUM_P(x)) {\n\treturn rb_fix2str(x, base);\n    }\n    i = RBIGNUM(x)->len;\n    if (BIGZEROP(x)) {\n\treturn rb_str_new2(\"0\");\n    }\n    if (i >= LONG_MAX/SIZEOF_BDIGITS/CHAR_BIT) {\n\trb_raise(rb_eRangeError, \"bignum too big to convert into `string'\");\n    }\n    j = SIZEOF_BDIGITS*CHAR_BIT*i;\n    switch (base) {\n      case 2: break;\n      case 3:\n\tj = j * 53L / 84 + 1;\n\tbreak;\n      case 4: case 5: case 6: case 7:\n\tj = (j + 1) / 2;\n\tbreak;\n      case 8: case 9:\n\tj = (j + 2) / 3;\n\tbreak;\n      case 10: case 11: case 12: case 13: case 14: case 15:\n\tj = j * 28L / 93 + 1;\n\tbreak;\n      case 16: case 17: case 18: case 19: case 20: case 21:\n      case 22: case 23: case 24: case 25: case 26: case 27:\n      case 28: case 29: case 30: case 31:\n\tj = (j + 3) / 4;\n\tbreak;\n      case 32: case 33: case 34: case 35: case 36:\n\tj = (j + 4) / 5;\n\tbreak;\n      default:\n\trb_raise(rb_eArgError, \"illegal radix %d\", base);\n\tbreak;\n    }\n    j++;\t\t\t/* space for sign */\n\n    hbase = base * base;\n#if SIZEOF_BDIGITS > 2\n    hbase *= hbase;\n#endif\n\n    t = rb_big_clone(x);\n    ds = BDIGITS(t);\n    ss = rb_str_new(0, j+1);\n    s = RSTRING(ss)->ptr;\n\n    s[0] = RBIGNUM(x)->sign ? '+' : '-';\n    TRAP_BEG;\n    while (i && j > 1) {\n\tlong k = i;\n\tBDIGIT_DBL num = 0;\n\n\twhile (k--) {\n\t    num = BIGUP(num) + ds[k];\n\t    ds[k] = (BDIGIT)(num / hbase);\n\t    num %= hbase;\n\t}\n\tif (trim && ds[i-1] == 0) i--;\n\tk = SIZEOF_BDIGITS;\n\twhile (k--) {\n\t    s[--j] = ruby_digitmap[num % base];\n\t    num /= base;\n\t    if (!trim && j <= 1) break;\n\t    if (trim && i == 0 && num == 0) break;\n\t}\n    }\n    if (trim) {while (s[j] == '0') j++;}\n    i = RSTRING(ss)->len - j;\n    if (RBIGNUM(x)->sign) {\n\tmemmove(s, s+j, i);\n\tRSTRING(ss)->len = i-1;\n    }\n    else {\n\tmemmove(s+1, s+j, i);\n\tRSTRING(ss)->len = i;\n    }\n    s[RSTRING(ss)->len] = '\\0';\n    TRAP_END;\n\n    return ss;\n}\n\nVALUE\nrb_big2str(VALUE x, int base)\n{\n    return rb_big2str0(x, base, Qtrue);\n}\n\n/*\n *  call-seq:\n *     big.to_s(base=10)   =>  string\n *\n *  Returns a string containing the representation of <i>big</i> radix\n *  <i>base</i> (2 through 36).\n *\n *     12345654321.to_s         #=> \"12345654321\"\n *     12345654321.to_s(2)      #=> \"1011011111110110111011110000110001\"\n *     12345654321.to_s(8)      #=> \"133766736061\"\n *     12345654321.to_s(16)     #=> \"2dfdbbc31\"\n *     78546939656932.to_s(36)  #=> \"rubyrules\"\n */\n\nstatic VALUE\nrb_big_to_s(argc, argv, x)\n    int argc;\n    VALUE *argv;\n    VALUE x;\n{\n    VALUE b;\n    int base;\n\n    rb_scan_args(argc, argv, \"01\", &b);\n    if (argc == 0) base = 10;\n    else base = NUM2INT(b);\n    return rb_big2str(x, base);\n}\n\nstatic unsigned long\nbig2ulong(x, type)\n    VALUE x;\n    char *type;\n{\n    long len = RBIGNUM(x)->len;\n    BDIGIT_DBL num;\n    BDIGIT *ds;\n\n    if (len > SIZEOF_LONG/SIZEOF_BDIGITS)\n\trb_raise(rb_eRangeError, \"bignum too big to convert into `%s'\", type);\n    ds = BDIGITS(x);\n    num = 0;\n    while (len--) {\n\tnum = BIGUP(num);\n\tnum += ds[len];\n    }\n    return num;\n}\n\nunsigned long\nrb_big2ulong_pack(x)\n    VALUE x;\n{\n    unsigned long num = big2ulong(x, \"unsigned long\");\n    if (!RBIGNUM(x)->sign) {\n\treturn -num;\n    }\n    return num;\n}\n\nunsigned long\nrb_big2ulong(x)\n    VALUE x;\n{\n    unsigned long num = big2ulong(x, \"unsigned long\");\n\n    if (!RBIGNUM(x)->sign) {\n\tif ((long)num < 0) {\n\t    rb_raise(rb_eRangeError, \"bignum out of range of unsigned long\");\n\t}\n\treturn -num;\n    }\n    return num;\n}\n\nlong\nrb_big2long(x)\n    VALUE x;\n{\n    unsigned long num = big2ulong(x, \"long\");\n\n    if ((long)num < 0 && (RBIGNUM(x)->sign || (long)num != LONG_MIN)) {\n\trb_raise(rb_eRangeError, \"bignum too big to convert into `long'\");\n    }\n    if (!RBIGNUM(x)->sign) return -(long)num;\n    return num;\n}\n\n#if HAVE_LONG_LONG\n\nstatic unsigned LONG_LONG\nbig2ull(x, type)\n    VALUE x;\n    char *type;\n{\n    long len = RBIGNUM(x)->len;\n    BDIGIT_DBL num;\n    BDIGIT *ds;\n\n    if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS)\n\trb_raise(rb_eRangeError, \"bignum too big to convert into `%s'\", type);\n    ds = BDIGITS(x);\n    num = 0;\n    while (len--) {\n\tnum = BIGUP(num);\n\tnum += ds[len];\n    }\n    return num;\n}\n\nunsigned LONG_LONG\nrb_big2ull(x)\n    VALUE x;\n{\n    unsigned LONG_LONG num = big2ull(x, \"unsigned long long\");\n\n    if (!RBIGNUM(x)->sign) return -num;\n    return num;\n}\n\nLONG_LONG\nrb_big2ll(x)\n    VALUE x;\n{\n    unsigned LONG_LONG num = big2ull(x, \"long long\");\n\n    if ((LONG_LONG)num < 0 && (RBIGNUM(x)->sign\n\t\t\t       || (LONG_LONG)num != LLONG_MIN)) {\n\trb_raise(rb_eRangeError, \"bignum too big to convert into `long long'\");\n    }\n    if (!RBIGNUM(x)->sign) return -(LONG_LONG)num;\n    return num;\n}\n\n#endif  /* HAVE_LONG_LONG */\n\nstatic VALUE\ndbl2big(d)\n    double d;\n{\n    long i = 0;\n    BDIGIT c;\n    BDIGIT *digits;\n    VALUE z;\n    double u = (d < 0)?-d:d;\n\n    if (isinf(d)) {\n\trb_raise(rb_eFloatDomainError, d < 0 ? \"-Infinity\" : \"Infinity\");\n    }\n    if (isnan(d)) {\n\trb_raise(rb_eFloatDomainError, \"NaN\");\n    }\n\n    while (!POSFIXABLE(u) || 0 != (long)u) {\n\tu /= (double)(BIGRAD);\n\ti++;\n    }\n    z = bignew(i, d>=0);\n    digits = BDIGITS(z);\n    while (i--) {\n\tu *= BIGRAD;\n\tc = (BDIGIT)u;\n\tu -= c;\n\tdigits[i] = c;\n    }\n\n    return z;\n}\n\nVALUE\nrb_dbl2big(d)\n    double d;\n{\n    return bignorm(dbl2big(d));\n}\n\nstatic double\nbig2dbl(x)\n    VALUE x;\n{\n    double d = 0.0;\n    long i = RBIGNUM(x)->len;\n    BDIGIT *ds = BDIGITS(x);\n\n    while (i--) {\n\td = ds[i] + BIGRAD*d;\n    }\n    if (!RBIGNUM(x)->sign) d = -d;\n    return d;\n}\n\ndouble\nrb_big2dbl(x)\n    VALUE x;\n{\n    double d = big2dbl(x);\n\n    if (isinf(d)) {\n\trb_warn(\"Bignum out of Float range\");\n\td = HUGE_VAL;\n    }\n    return d;\n}\n\n/*\n *  call-seq:\n *     big.to_f -> float\n *\n *  Converts <i>big</i> to a <code>Float</code>. If <i>big</i> doesn't\n *  fit in a <code>Float</code>, the result is infinity.\n *\n */\n\nstatic VALUE\nrb_big_to_f(x)\n    VALUE x;\n{\n    return rb_float_new(rb_big2dbl(x));\n}\n\n/*\n *  call-seq:\n *     big <=> numeric   => -1, 0, +1\n *\n *  Comparison---Returns -1, 0, or +1 depending on whether <i>big</i> is\n *  less than, equal to, or greater than <i>numeric</i>. This is the\n *  basis for the tests in <code>Comparable</code>.\n *\n */\n\nstatic VALUE\nrb_big_cmp(x, y)\n    VALUE x, y;\n{\n    long xlen = RBIGNUM(x)->len;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n\n      case T_BIGNUM:\n\tbreak;\n\n      case T_FLOAT:\n\treturn rb_dbl_cmp(rb_big2dbl(x), RFLOAT(y)->value);\n\n      default:\n\treturn rb_num_coerce_cmp(x, y);\n    }\n\n    if (RBIGNUM(x)->sign > RBIGNUM(y)->sign) return INT2FIX(1);\n    if (RBIGNUM(x)->sign < RBIGNUM(y)->sign) return INT2FIX(-1);\n    if (xlen < RBIGNUM(y)->len)\n\treturn (RBIGNUM(x)->sign) ? INT2FIX(-1) : INT2FIX(1);\n    if (xlen > RBIGNUM(y)->len)\n\treturn (RBIGNUM(x)->sign) ? INT2FIX(1) : INT2FIX(-1);\n\n    while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));\n    if (-1 == xlen) return INT2FIX(0);\n    return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?\n\t(RBIGNUM(x)->sign ? INT2FIX(1) : INT2FIX(-1)) :\n\t    (RBIGNUM(x)->sign ? INT2FIX(-1) : INT2FIX(1));\n}\n\n/*\n *  call-seq:\n *     big == obj  => true or false\n *\n *  Returns <code>true</code> only if <i>obj</i> has the same value\n *  as <i>big</i>. Contrast this with <code>Bignum#eql?</code>, which\n *  requires <i>obj</i> to be a <code>Bignum</code>.\n *\n *     68719476736 == 68719476736.0   #=> true\n */\n\nstatic VALUE\nrb_big_eq(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n      case T_BIGNUM:\n\tbreak;\n      case T_FLOAT:\n        {\n\t    volatile double a, b;\n\n\t    a = RFLOAT(y)->value;\n\t    if (isnan(a)) return Qfalse;\n\t    b = rb_big2dbl(x);\n\t    return (a == b)?Qtrue:Qfalse;\n\t}\n      default:\n\treturn rb_equal(y, x);\n    }\n    if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse;\n    if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse;\n    if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     big.eql?(obj)   => true or false\n *\n *  Returns <code>true</code> only if <i>obj</i> is a\n *  <code>Bignum</code> with the same value as <i>big</i>. Contrast this\n *  with <code>Bignum#==</code>, which performs type conversions.\n *\n *     68719476736.eql?(68719476736.0)   #=> false\n */\n\nstatic VALUE\nrb_big_eql(x, y)\n    VALUE x, y;\n{\n    if (TYPE(y) != T_BIGNUM) return Qfalse;\n    if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse;\n    if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse;\n    if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    -big   =>  other_big\n *\n * Unary minus (returns a new Bignum whose value is 0-big)\n */\n\nstatic VALUE\nrb_big_uminus(x)\n    VALUE x;\n{\n    VALUE z = rb_big_clone(x);\n\n    RBIGNUM(z)->sign = !RBIGNUM(x)->sign;\n\n    return bignorm(z);\n}\n\n/*\n * call-seq:\n *     ~big  =>  integer\n *\n * Inverts the bits in big. As Bignums are conceptually infinite\n * length, the result acts as if it had an infinite number of one\n * bits to the left. In hex representations, this is displayed\n * as two periods to the left of the digits.\n *\n *   sprintf(\"%X\", ~0x1122334455)    #=> \"..FEEDDCCBBAA\"\n */\n\nstatic VALUE\nrb_big_neg(x)\n    VALUE x;\n{\n    VALUE z = rb_big_clone(x);\n    long i;\n    BDIGIT *ds;\n\n    if (!RBIGNUM(x)->sign) get2comp(z);\n    ds = BDIGITS(z);\n    i = RBIGNUM(x)->len;\n    if (!i) return INT2FIX(~0);\n    while (i--) ds[i] = ~ds[i];\n    RBIGNUM(z)->sign = !RBIGNUM(z)->sign;\n    if (RBIGNUM(x)->sign) get2comp(z);\n\n    return bignorm(z);\n}\n\nstatic VALUE\nbigsub(x, y)\n    VALUE x, y;\n{\n    VALUE z = 0;\n    BDIGIT *zds;\n    BDIGIT_DBL_SIGNED num;\n    long i = RBIGNUM(x)->len;\n\n    /* if x is larger than y, swap */\n    if (RBIGNUM(x)->len < RBIGNUM(y)->len) {\n\tz = x; x = y; y = z;\t/* swap x y */\n    }\n    else if (RBIGNUM(x)->len == RBIGNUM(y)->len) {\n\twhile (i > 0) {\n\t    i--;\n\t    if (BDIGITS(x)[i] > BDIGITS(y)[i]) {\n\t\tbreak;\n\t    }\n\t    if (BDIGITS(x)[i] < BDIGITS(y)[i]) {\n\t\tz = x; x = y; y = z;\t/* swap x y */\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    z = bignew(RBIGNUM(x)->len, z==0);\n    zds = BDIGITS(z);\n\n    for (i = 0, num = 0; i < RBIGNUM(y)->len; i++) {\n\tnum += (BDIGIT_DBL_SIGNED)BDIGITS(x)[i] - BDIGITS(y)[i];\n\tzds[i] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n    while (num && i < RBIGNUM(x)->len) {\n\tnum += BDIGITS(x)[i];\n\tzds[i++] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n    while (i < RBIGNUM(x)->len) {\n\tzds[i] = BDIGITS(x)[i];\n\ti++;\n    }\n\n    return z;\n}\n\nstatic VALUE\nbigadd(x, y, sign)\n    VALUE x, y;\n    int sign;\n{\n    VALUE z;\n    BDIGIT_DBL num;\n    long i, len;\n\n    sign = (sign == RBIGNUM(y)->sign);\n    if (RBIGNUM(x)->sign != sign) {\n\tif (sign) return bigsub(y, x);\n\treturn bigsub(x, y);\n    }\n\n    if (RBIGNUM(x)->len > RBIGNUM(y)->len) {\n\tlen = RBIGNUM(x)->len + 1;\n        z = x; x = y; y = z;\n    }\n    else {\n\tlen = RBIGNUM(y)->len + 1;\n    }\n    z = bignew(len, sign);\n\n    len = RBIGNUM(x)->len;\n    for (i = 0, num = 0; i < len; i++) {\n\tnum += (BDIGIT_DBL)BDIGITS(x)[i] + BDIGITS(y)[i];\n\tBDIGITS(z)[i] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n    len = RBIGNUM(y)->len;\n    while (num && i < len) {\n\tnum += BDIGITS(y)[i];\n\tBDIGITS(z)[i++] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n    while (i < len) {\n\tBDIGITS(z)[i] = BDIGITS(y)[i];\n\ti++;\n    }\n    BDIGITS(z)[i] = (BDIGIT)num;\n\n    return z;\n}\n\n/*\n *  call-seq:\n *     big + other  => Numeric\n *\n *  Adds big and other, returning the result.\n */\n\nVALUE\nrb_big_plus(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\t/* fall through */\n      case T_BIGNUM:\n\treturn bignorm(bigadd(x, y, 1));\n\n      case T_FLOAT:\n\treturn rb_float_new(rb_big2dbl(x) + RFLOAT(y)->value);\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\n/*\n *  call-seq:\n *     big - other  => Numeric\n *\n *  Subtracts other from big, returning the result.\n */\n\nVALUE\nrb_big_minus(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\t/* fall through */\n      case T_BIGNUM:\n\treturn bignorm(bigadd(x, y, 0));\n\n      case T_FLOAT:\n\treturn rb_float_new(rb_big2dbl(x) - RFLOAT(y)->value);\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\nVALUE\nrb_big_mul0(x, y)\n    VALUE x, y;\n{\n    long i, j;\n    BDIGIT_DBL n = 0;\n    VALUE z;\n    BDIGIT *zds;\n\n    if (FIXNUM_P(x)) x = rb_int2big(FIX2LONG(x));\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n\n      case T_BIGNUM:\n\tbreak;\n\n      case T_FLOAT:\n\treturn rb_float_new(rb_big2dbl(x) * RFLOAT(y)->value);\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n\n    j = RBIGNUM(x)->len + RBIGNUM(y)->len + 1;\n    z = bignew(j, RBIGNUM(x)->sign==RBIGNUM(y)->sign);\n    zds = BDIGITS(z);\n    while (j--) zds[j] = 0;\n    for (i = 0; i < RBIGNUM(x)->len; i++) {\n\tBDIGIT_DBL dd = BDIGITS(x)[i];\n\tif (dd == 0) continue;\n\tn = 0;\n\tfor (j = 0; j < RBIGNUM(y)->len; j++) {\n\t    BDIGIT_DBL ee = n + (BDIGIT_DBL)dd * BDIGITS(y)[j];\n\t    n = zds[i + j] + ee;\n\t    if (ee) zds[i + j] = BIGLO(n);\n\t    n = BIGDN(n);\n\t}\n\tif (n) {\n\t    zds[i + j] = n;\n\t}\n    }\n\n    return z;\n}\n\n/*\n *  call-seq:\n *     big * other  => Numeric\n *\n *  Multiplies big and other, returning the result.\n */\n\nVALUE\nrb_big_mul(x, y)\n    VALUE x, y;\n{\n    return bignorm(rb_big_mul0(x, y));\n}\n\nstatic void\nbigdivrem(x, y, divp, modp)\n    VALUE x, y;\n    VALUE *divp, *modp;\n{\n    long nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len;\n    long i, j;\n    VALUE yy, z;\n    BDIGIT *xds, *yds, *zds, *tds;\n    BDIGIT_DBL t2;\n    BDIGIT_DBL_SIGNED num;\n    BDIGIT dd, q;\n\n    if (BIGZEROP(y)) rb_num_zerodiv();\n    yds = BDIGITS(y);\n    if (nx < ny || (nx == ny && BDIGITS(x)[nx - 1] < BDIGITS(y)[ny - 1])) {\n\tif (divp) *divp = rb_int2big(0);\n\tif (modp) *modp = x;\n\treturn;\n    }\n    xds = BDIGITS(x);\n    if (ny == 1) {\n\tdd = yds[0];\n\tz = rb_big_clone(x);\n\tzds = BDIGITS(z);\n\tt2 = 0; i = nx;\n\twhile (i--) {\n\t    t2 = BIGUP(t2) + zds[i];\n\t    zds[i] = (BDIGIT)(t2 / dd);\n\t    t2 %= dd;\n\t}\n\tRBIGNUM(z)->sign = RBIGNUM(x)->sign==RBIGNUM(y)->sign;\n\tif (modp) {\n\t    *modp = rb_uint2big((unsigned long)t2);\n\t    RBIGNUM(*modp)->sign = RBIGNUM(x)->sign;\n\t}\n\tif (divp) *divp = z;\n\treturn;\n    }\n    z = bignew(nx==ny?nx+2:nx+1, RBIGNUM(x)->sign==RBIGNUM(y)->sign);\n    zds = BDIGITS(z);\n    if (nx==ny) zds[nx+1] = 0;\n    while (!yds[ny-1]) ny--;\n\n    dd = 0;\n    q = yds[ny-1];\n    while ((q & (1U<<(BITSPERDIG-1))) == 0) {\n\tq <<= 1;\n\tdd++;\n    }\n    if (dd) {\n\tyy = rb_big_clone(y);\n\ttds = BDIGITS(yy);\n\tj = 0;\n\tt2 = 0;\n\twhile (j<ny) {\n\t    t2 += (BDIGIT_DBL)yds[j]<<dd;\n\t    tds[j++] = BIGLO(t2);\n\t    t2 = BIGDN(t2);\n\t}\n\tyds = tds;\n\tj = 0;\n\tt2 = 0;\n\twhile (j<nx) {\n\t    t2 += (BDIGIT_DBL)xds[j]<<dd;\n\t    zds[j++] = BIGLO(t2);\n\t    t2 = BIGDN(t2);\n\t}\n\tzds[j] = (BDIGIT)t2;\n    }\n    else {\n\tzds[nx] = 0;\n\tj = nx;\n\twhile (j--) zds[j] = xds[j];\n    }\n\n    j = nx==ny?nx+1:nx;\n    do {\n\tif (zds[j] ==  yds[ny-1]) q = BIGRAD-1;\n\telse q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);\n\tif (q) {\n\t    i = 0; num = 0; t2 = 0;\n\t    do {\t\t\t/* multiply and subtract */\n\t\tBDIGIT_DBL ee;\n\t\tt2 += (BDIGIT_DBL)yds[i] * q;\n\t\tee = num - BIGLO(t2);\n\t\tnum = (BDIGIT_DBL)zds[j - ny + i] + ee;\n\t\tif (ee) zds[j - ny + i] = BIGLO(num);\n\t\tnum = BIGDN(num);\n\t\tt2 = BIGDN(t2);\n\t    } while (++i < ny);\n\t    num += zds[j - ny + i] - t2;/* borrow from high digit; don't update */\n\t    while (num) {\t\t/* \"add back\" required */\n\t\ti = 0; num = 0; q--;\n\t\tdo {\n\t\t    BDIGIT_DBL ee = num + yds[i];\n\t\t    num = (BDIGIT_DBL)zds[j - ny + i] + ee;\n\t\t    if (ee) zds[j - ny + i] = BIGLO(num);\n\t\t    num = BIGDN(num);\n\t\t} while (++i < ny);\n\t\tnum--;\n\t    }\n\t}\n\tzds[j] = q;\n    } while (--j >= ny);\n    if (divp) {\t\t\t/* move quotient down in z */\n\t*divp = rb_big_clone(z);\n\tzds = BDIGITS(*divp);\n\tj = (nx==ny ? nx+2 : nx+1) - ny;\n\tfor (i = 0;i < j;i++) zds[i] = zds[i+ny];\n\tRBIGNUM(*divp)->len = i;\n    }\n    if (modp) {\t\t\t/* normalize remainder */\n\t*modp = rb_big_clone(z);\n\tzds = BDIGITS(*modp);\n\twhile (--ny && !zds[ny]); ++ny;\n\tif (dd) {\n\t    t2 = 0; i = ny;\n\t    while(i--) {\n\t\tt2 = (t2 | zds[i]) >> dd;\n\t\tq = zds[i];\n\t\tzds[i] = BIGLO(t2);\n\t\tt2 = BIGUP(q);\n\t    }\n\t}\n\tRBIGNUM(*modp)->len = ny;\n\tRBIGNUM(*modp)->sign = RBIGNUM(x)->sign;\n    }\n}\n\nstatic void\nbigdivmod(x, y, divp, modp)\n    VALUE x, y;\n    VALUE *divp, *modp;\n{\n    VALUE mod;\n\n    bigdivrem(x, y, divp, &mod);\n    if (RBIGNUM(x)->sign != RBIGNUM(y)->sign && !BIGZEROP(mod)) {\n\tif (divp) *divp = bigadd(*divp, rb_int2big(1), 0);\n\tif (modp) *modp = bigadd(mod, y, 1);\n    }\n    else {\n\tif (divp) *divp = *divp;\n\tif (modp) *modp = mod;\n    }\n}\n\n/*\n *  call-seq:\n *     big / other     => Numeric\n *     big.div(other)  => Numeric\n *\n *  Divides big by other, returning the result.\n */\n\nstatic VALUE\nrb_big_div(x, y)\n    VALUE x, y;\n{\n    VALUE z;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n\n      case T_BIGNUM:\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    bigdivmod(x, y, &z, 0);\n\n    return bignorm(z);\n}\n\n/*\n *  call-seq:\n *     big % other         => Numeric\n *     big.modulo(other)   => Numeric\n *\n *  Returns big modulo other. See Numeric.divmod for more\n *  information.\n */\n\nstatic VALUE\nrb_big_modulo(x, y)\n    VALUE x, y;\n{\n    VALUE z;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n\n      case T_BIGNUM:\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    bigdivmod(x, y, 0, &z);\n\n    return bignorm(z);\n}\n\n/*\n *  call-seq:\n *     big.remainder(numeric)    => number\n *\n *  Returns the remainder after dividing <i>big</i> by <i>numeric</i>.\n *\n *     -1234567890987654321.remainder(13731)      #=> -6966\n *     -1234567890987654321.remainder(13731.24)   #=> -9906.22531493148\n */\nstatic VALUE\nrb_big_remainder(x, y)\n    VALUE x, y;\n{\n    VALUE z;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n\n      case T_BIGNUM:\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    bigdivrem(x, y, 0, &z);\n\n    return bignorm(z);\n}\n\nstatic int\nbdigbitsize(BDIGIT x)\n{\n    int size = 1;\n    int nb = BITSPERDIG / 2;\n    BDIGIT bits = (~0 << nb);\n\n    if (!x) return 0;\n    while (x > 1) {\n\tif (x & bits) {\n\t    size += nb;\n\t    x >>= nb;\n\t}\n\tx &= ~bits;\n\tnb /= 2;\n\tbits >>= nb;\n    }\n\n    return size;\n}\n\nstatic VALUE big_lshift _((VALUE, unsigned long));\nstatic VALUE big_rshift _((VALUE, unsigned long));\n\nstatic VALUE big_shift(x, n)\n    VALUE x;\n    int n;\n{\n    if (n < 0)\n\treturn big_lshift(x, (unsigned int)n);\n    else if (n > 0)\n\treturn big_rshift(x, (unsigned int)n);\n    return x;\n}\n\n/*\n *  call-seq:\n *     big.divmod(numeric)   => array\n *\n *  See <code>Numeric#divmod</code>.\n *\n */\nVALUE\nrb_big_divmod(x, y)\n    VALUE x, y;\n{\n    VALUE div, mod;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\ty = rb_int2big(FIX2LONG(y));\n\tbreak;\n\n      case T_BIGNUM:\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    bigdivmod(x, y, &div, &mod);\n\n    return rb_assoc_new(bignorm(div), bignorm(mod));\n}\n\n/*\n *  call-seq:\n *     big.quo(numeric) -> float\n *     big.fdiv(numeric) -> float\n *\n *  Returns the floating point result of dividing <i>big</i> by\n *  <i>numeric</i>.\n *\n *     -1234567890987654321.quo(13731)      #=> -89910996357705.5\n *     -1234567890987654321.quo(13731.24)   #=> -89909424858035.7\n *\n */\n\nstatic VALUE\nrb_big_quo(x, y)\n    VALUE x, y;\n{\n    double dx = big2dbl(x);\n    double dy;\n\n    if (isinf(dx)) {\n#define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)\n\tVALUE z;\n\tint ex, ey;\n\n\tex = (RBIGNUM(bigtrunc(x))->len - 1) * BITSPERDIG;\n\tex += bdigbitsize(BDIGITS(x)[RBIGNUM(x)->len - 1]);\n\tex -= 2 * DBL_BIGDIG * BITSPERDIG;\n\tif (ex) x = big_shift(x, ex);\n\n\tswitch (TYPE(y)) {\n\t  case T_FIXNUM:\n\t    y = rb_int2big(FIX2LONG(y));\n\t  case T_BIGNUM: {\n\t    ey = (RBIGNUM(bigtrunc(y))->len - 1) * BITSPERDIG;\n\t    ey += bdigbitsize(BDIGITS(y)[RBIGNUM(y)->len - 1]);\n\t    ey -= DBL_BIGDIG * BITSPERDIG;\n\t    if (ey) y = big_shift(y, ey);\n\t  bignum:\n\t    bigdivrem(x, y, &z, 0);\n\t    return rb_float_new(ldexp(big2dbl(z), ex - ey));\n\t  }\n\t  case T_FLOAT:\n\t    y = dbl2big(ldexp(frexp(RFLOAT(y)->value, &ey), DBL_MANT_DIG));\n\t    ey -= DBL_MANT_DIG;\n\t    goto bignum;\n\t}\n    }\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tdy = (double)FIX2LONG(y);\n\tbreak;\n\n      case T_BIGNUM:\n\tdy = rb_big2dbl(y);\n\tbreak;\n\n      case T_FLOAT:\n\tdy = RFLOAT(y)->value;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    return rb_float_new(dx / dy);\n}\n\nstatic VALUE\nbigsqr(x)\n    VALUE x;\n{\n    long len = RBIGNUM(x)->len, k = len / 2, i;\n    VALUE a, b, a2, z;\n    BDIGIT_DBL num;\n\n    if (len < 4000 / BITSPERDIG) {\n\treturn rb_big_mul0(x, x);\n    }\n\n    a = bignew(len - k, 1);\n    MEMCPY(BDIGITS(a), BDIGITS(x) + k, BDIGIT, len - k);\n    b = bignew(k, 1);\n    MEMCPY(BDIGITS(b), BDIGITS(x), BDIGIT, k);\n\n    a2 = bigtrunc(bigsqr(a));\n    z = bigsqr(b);\n    REALLOC_N(RBIGNUM(z)->digits, BDIGIT, (len = 2 * k + RBIGNUM(a2)->len) + 1);\n    while (RBIGNUM(z)->len < 2 * k) BDIGITS(z)[RBIGNUM(z)->len++] = 0;\n    MEMCPY(BDIGITS(z) + 2 * k, BDIGITS(a2), BDIGIT, RBIGNUM(a2)->len);\n    RBIGNUM(z)->len = len;\n    a2 = bigtrunc(rb_big_mul0(a, b));\n    len = RBIGNUM(a2)->len;\n    TRAP_BEG;\n    for (i = 0, num = 0; i < len; i++) {\n\tnum += (BDIGIT_DBL)BDIGITS(z)[i + k] + ((BDIGIT_DBL)BDIGITS(a2)[i] << 1);\n\tBDIGITS(z)[i + k] = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n    TRAP_END;\n    if (num) {\n\tlen = RBIGNUM(z)->len;\n\tfor (i += k; i < len && num; ++i) {\n\t    num += (BDIGIT_DBL)BDIGITS(z)[i];\n\t    BDIGITS(z)[i] = BIGLO(num);\n\t    num = BIGDN(num);\n\t}\n\tif (num) {\n\t    BDIGITS(z)[RBIGNUM(z)->len++] = BIGLO(num);\n\t}\n    }\n    return bigtrunc(z);\n}\n\n/*\n *  call-seq:\n *     big ** exponent   #=> numeric\n *\n *  Raises _big_ to the _exponent_ power (which may be an integer, float,\n *  or anything that will coerce to a number). The result may be\n *  a Fixnum, Bignum, or Float\n *\n *    123456789 ** 2      #=> 15241578750190521\n *    123456789 ** 1.2    #=> 5126464716.09932\n *    123456789 ** -2     #=> 6.5610001194102e-17\n */\n\nVALUE\nrb_big_pow(x, y)\n    VALUE x, y;\n{\n    double d;\n    long yy;\n\n    if (y == INT2FIX(0)) return INT2FIX(1);\n    switch (TYPE(y)) {\n      case T_FLOAT:\n\td = RFLOAT(y)->value;\n\tbreak;\n\n      case T_BIGNUM:\n\trb_warn(\"in a**b, b may be too big\");\n\td = rb_big2dbl(y);\n\tbreak;\n\n      case T_FIXNUM:\n\tyy = FIX2LONG(y);\n\tif (yy > 0) {\n\t    VALUE z = 0;\n\t    long mask;\n\t    const long BIGLEN_LIMIT = 1024*1024 / SIZEOF_BDIGITS;\n\n\t    if ((RBIGNUM(x)->len > BIGLEN_LIMIT) ||\n\t\t(RBIGNUM(x)->len > BIGLEN_LIMIT / yy)) {\n\t\trb_warn(\"in a**b, b may be too big\");\n\t\td = (double)yy;\n\t\tbreak;\n\t    }\n\t    for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {\n\t\tif (z) z = bigtrunc(bigsqr(z));\n\t\tif (yy & mask) {\n\t\t    z = z ? bigtrunc(rb_big_mul0(z, x)) : x;\n\t\t}\n\t    }\n\t    return bignorm(z);\n\t}\n\td = (double)yy;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    return rb_float_new(pow(rb_big2dbl(x), d));\n}\n\n/*\n * call-seq:\n *     big & numeric   =>  integer\n *\n * Performs bitwise +and+ between _big_ and _numeric_.\n */\n\nVALUE\nrb_big_and(xx, yy)\n    VALUE xx, yy;\n{\n    volatile VALUE x, y, z;\n    BDIGIT *ds1, *ds2, *zds;\n    long i, l1, l2;\n    char sign;\n\n    x = xx;\n    y = rb_to_int(yy);\n    if (FIXNUM_P(y)) {\n\ty = rb_int2big(FIX2LONG(y));\n    }\n    if (!RBIGNUM(y)->sign) {\n\ty = rb_big_clone(y);\n\tget2comp(y);\n    }\n    if (!RBIGNUM(x)->sign) {\n\tx = rb_big_clone(x);\n\tget2comp(x);\n    }\n    if (RBIGNUM(x)->len > RBIGNUM(y)->len) {\n\tl1 = RBIGNUM(y)->len;\n\tl2 = RBIGNUM(x)->len;\n\tds1 = BDIGITS(y);\n\tds2 = BDIGITS(x);\n\tsign = RBIGNUM(y)->sign;\n    }\n    else {\n\tl1 = RBIGNUM(x)->len;\n\tl2 = RBIGNUM(y)->len;\n\tds1 = BDIGITS(x);\n\tds2 = BDIGITS(y);\n\tsign = RBIGNUM(x)->sign;\n    }\n    z = bignew(l2, RBIGNUM(x)->sign || RBIGNUM(y)->sign);\n    zds = BDIGITS(z);\n\n    for (i=0; i<l1; i++) {\n\tzds[i] = ds1[i] & ds2[i];\n    }\n    for (; i<l2; i++) {\n\tzds[i] = sign?0:ds2[i];\n    }\n    if (!RBIGNUM(z)->sign) get2comp(z);\n    return bignorm(z);\n}\n\n/*\n * call-seq:\n *     big | numeric   =>  integer\n *\n * Performs bitwise +or+ between _big_ and _numeric_.\n */\n\nVALUE\nrb_big_or(xx, yy)\n    VALUE xx, yy;\n{\n    volatile VALUE x, y, z;\n    BDIGIT *ds1, *ds2, *zds;\n    long i, l1, l2;\n    char sign;\n\n    x = xx;\n    y = rb_to_int(yy);\n    if (FIXNUM_P(y)) {\n\ty = rb_int2big(FIX2LONG(y));\n    }\n    if (!RBIGNUM(y)->sign) {\n\ty = rb_big_clone(y);\n\tget2comp(y);\n    }\n    if (!RBIGNUM(x)->sign) {\n\tx = rb_big_clone(x);\n\tget2comp(x);\n    }\n    if (RBIGNUM(x)->len > RBIGNUM(y)->len) {\n\tl1 = RBIGNUM(y)->len;\n\tl2 = RBIGNUM(x)->len;\n\tds1 = BDIGITS(y);\n\tds2 = BDIGITS(x);\n\tsign = RBIGNUM(y)->sign;\n    }\n    else {\n\tl1 = RBIGNUM(x)->len;\n\tl2 = RBIGNUM(y)->len;\n\tds1 = BDIGITS(x);\n\tds2 = BDIGITS(y);\n\tsign = RBIGNUM(x)->sign;\n    }\n    z = bignew(l2, RBIGNUM(x)->sign && RBIGNUM(y)->sign);\n    zds = BDIGITS(z);\n\n    for (i=0; i<l1; i++) {\n\tzds[i] = ds1[i] | ds2[i];\n    }\n    for (; i<l2; i++) {\n\tzds[i] = sign?ds2[i]:(BIGRAD-1);\n    }\n    if (!RBIGNUM(z)->sign) get2comp(z);\n\n    return bignorm(z);\n}\n\n/*\n * call-seq:\n *     big ^ numeric   =>  integer\n *\n * Performs bitwise +exclusive or+ between _big_ and _numeric_.\n */\n\nVALUE\nrb_big_xor(xx, yy)\n    VALUE xx, yy;\n{\n    volatile VALUE x, y;\n    VALUE z;\n    BDIGIT *ds1, *ds2, *zds;\n    long i, l1, l2;\n    char sign;\n\n    x = xx;\n    y = rb_to_int(yy);\n    if (FIXNUM_P(y)) {\n\ty = rb_int2big(FIX2LONG(y));\n    }\n    if (!RBIGNUM(y)->sign) {\n\ty = rb_big_clone(y);\n\tget2comp(y);\n    }\n    if (!RBIGNUM(x)->sign) {\n\tx = rb_big_clone(x);\n\tget2comp(x);\n    }\n    if (RBIGNUM(x)->len > RBIGNUM(y)->len) {\n\tl1 = RBIGNUM(y)->len;\n\tl2 = RBIGNUM(x)->len;\n\tds1 = BDIGITS(y);\n\tds2 = BDIGITS(x);\n\tsign = RBIGNUM(y)->sign;\n    }\n    else {\n\tl1 = RBIGNUM(x)->len;\n\tl2 = RBIGNUM(y)->len;\n\tds1 = BDIGITS(x);\n\tds2 = BDIGITS(y);\n\tsign = RBIGNUM(x)->sign;\n    }\n    RBIGNUM(x)->sign = RBIGNUM(x)->sign?1:0;\n    RBIGNUM(y)->sign = RBIGNUM(y)->sign?1:0;\n    z = bignew(l2, !(RBIGNUM(x)->sign ^ RBIGNUM(y)->sign));\n    zds = BDIGITS(z);\n\n    for (i=0; i<l1; i++) {\n\tzds[i] = ds1[i] ^ ds2[i];\n    }\n    for (; i<l2; i++) {\n\tzds[i] = sign?ds2[i]:~ds2[i];\n    }\n    if (!RBIGNUM(z)->sign) get2comp(z);\n\n    return bignorm(z);\n}\n\nstatic VALUE\ncheck_shiftdown(VALUE y, VALUE x)\n{\n    if (!RBIGNUM(x)->len) return INT2FIX(0);\n    if (RBIGNUM(y)->len > SIZEOF_LONG / SIZEOF_BDIGITS) {\n\treturn RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(-1);\n    }\n    return Qnil;\n}\n\n/*\n * call-seq:\n *     big << numeric   =>  integer\n *\n * Shifts big left _numeric_ positions (right if _numeric_ is negative).\n */\n\nVALUE\nrb_big_lshift(x, y)\n    VALUE x, y;\n{\n    long shift;\n    int neg = 0;\n\n    for (;;) {\n\tif (FIXNUM_P(y)) {\n\t    shift = FIX2LONG(y);\n\t    if (shift < 0) {\n\t\tneg = 1;\n\t\tshift = -shift;\n\t    }\n\t    break;\n\t}\n\telse if (TYPE(y) == T_BIGNUM) {\n\t    if (!RBIGNUM(y)->sign) {\n\t\tVALUE t = check_shiftdown(y, x);\n\t\tif (!NIL_P(t)) return t;\n\t\tneg = 1;\n\t    }\n\t    shift = big2ulong(y, \"long\");\n\t    break;\n\t}\n\ty = rb_to_int(y);\n    }\n\n    x = neg ? big_rshift(x, shift) : big_lshift(x, shift);\n    return bignorm(x);\n}\n\nstatic VALUE\nbig_lshift(x, shift)\n    VALUE x;\n    unsigned long shift;\n{\n    BDIGIT *xds, *zds;\n    long s1 = shift/BITSPERDIG;\n    int s2 = shift%BITSPERDIG;\n    VALUE z;\n    BDIGIT_DBL num = 0;\n    long len, i;\n\n    len = RBIGNUM(x)->len;\n    z = bignew(len+s1+1, RBIGNUM(x)->sign);\n    zds = BDIGITS(z);\n    for (i=0; i<s1; i++) {\n\t*zds++ = 0;\n    }\n    xds = BDIGITS(x);\n    for (i=0; i<len; i++) {\n\tnum = num | (BDIGIT_DBL)*xds++<<s2;\n\t*zds++ = BIGLO(num);\n\tnum = BIGDN(num);\n    }\n    *zds = BIGLO(num);\n    return z;\n}\n\n/*\n * call-seq:\n *     big >> numeric   =>  integer\n *\n * Shifts big right _numeric_ positions (left if _numeric_ is negative).\n */\n\nVALUE\nrb_big_rshift(x, y)\n    VALUE x, y;\n{\n    long shift;\n    int neg = 0;\n\n    for (;;) {\n\tif (FIXNUM_P(y)) {\n\t    shift = FIX2LONG(y);\n\t    if (shift < 0) {\n\t\tneg = 1;\n\t\tshift = -shift;\n\t    }\n\t    break;\n\t}\n\telse if (TYPE(y) == T_BIGNUM) {\n\t    if (RBIGNUM(y)->sign) {\n\t\tVALUE t = check_shiftdown(y, x);\n\t\tif (!NIL_P(t)) return t;\n\t    }\n\t    else {\n\t\tneg = 1;\n\t    }\n\t    shift = big2ulong(y, \"long\");\n\t    break;\n\t}\n\ty = rb_to_int(y);\n    }\n\n    x = neg ? big_lshift(x, shift) : big_rshift(x, shift);\n    return bignorm(x);\n}\n\nstatic VALUE\nbig_rshift(x, shift)\n    VALUE x;\n    unsigned long shift;\n{\n    BDIGIT *xds, *zds;\n    long s1 = shift/BITSPERDIG;\n    int s2 = shift%BITSPERDIG;\n    VALUE z;\n    BDIGIT_DBL num = 0;\n    long i, j;\n    volatile VALUE save_x;\n\n    if (s1 > RBIGNUM(x)->len) {\n\tif (RBIGNUM(x)->sign)\n\t    return INT2FIX(0);\n\telse\n\t    return INT2FIX(-1);\n    }\n    if (!RBIGNUM(x)->sign) {\n\tsave_x = x = rb_big_clone(x);\n\tget2comp(x);\n    }\n    xds = BDIGITS(x);\n    i = RBIGNUM(x)->len; j = i - s1;\n    if (j == 0) {\n\tif (RBIGNUM(x)->sign) return INT2FIX(0);\n\telse return INT2FIX(-1);\n    }\n    z = bignew(j, RBIGNUM(x)->sign);\n    if (!RBIGNUM(x)->sign) {\n\tnum = ((BDIGIT_DBL)~0) << BITSPERDIG;\n    }\n    zds = BDIGITS(z);\n    while (i--, j--) {\n\tnum = (num | xds[i]) >> s2;\n\tzds[j] = BIGLO(num);\n\tnum = BIGUP(xds[i]);\n    }\n    if (!RBIGNUM(x)->sign) {\n\tget2comp(z);\n    }\n    return z;\n}\n\n/*\n *  call-seq:\n *     big[n] -> 0, 1\n *\n *  Bit Reference---Returns the <em>n</em>th bit in the (assumed) binary\n *  representation of <i>big</i>, where <i>big</i>[0] is the least\n *  significant bit.\n *\n *     a = 9**15\n *     50.downto(0) do |n|\n *       print a[n]\n *     end\n *\n *  <em>produces:</em>\n *\n *     000101110110100000111000011110010100111100010111001\n *\n */\n\nstatic VALUE\nrb_big_aref(x, y)\n    VALUE x, y;\n{\n    BDIGIT *xds;\n    BDIGIT_DBL num;\n    unsigned long shift;\n    long i, s1, s2;\n\n    if (TYPE(y) == T_BIGNUM) {\n\tif (!RBIGNUM(y)->sign)\n\t    return INT2FIX(0);\n\tif (RBIGNUM(bigtrunc(y))->len > SIZEOF_LONG/SIZEOF_BDIGITS) {\n\t  out_of_range:\n\t    return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(1);\n\t}\n\tshift = big2ulong(y, \"long\");\n    }\n    else {\n\ti = NUM2LONG(y);\n\tif (i < 0) return INT2FIX(0);\n\tshift = (VALUE)i;\n    }\n    s1 = shift/BITSPERDIG;\n    s2 = shift%BITSPERDIG;\n\n    if (s1 >= RBIGNUM(x)->len) goto out_of_range;\n    if (!RBIGNUM(x)->sign) {\n\txds = BDIGITS(x);\n\ti = 0; num = 1;\n\twhile (num += ~xds[i], ++i <= s1) {\n\t    num = BIGDN(num);\n\t}\n    }\n    else {\n\tnum = BDIGITS(x)[s1];\n    }\n    if (num & ((BDIGIT_DBL)1<<s2))\n\treturn INT2FIX(1);\n    return INT2FIX(0);\n}\n\n/*\n * call-seq:\n *   big.hash   => fixnum\n *\n * Compute a hash based on the value of _big_.\n */\n\nstatic VALUE\nrb_big_hash(x)\n    VALUE x;\n{\n    long i, len, key;\n    BDIGIT *digits;\n\n    key = 0; digits = BDIGITS(x); len = RBIGNUM(x)->len;\n    for (i=0; i<len; i++) {\n\tkey ^= *digits++;\n    }\n    return LONG2FIX(key);\n}\n\n/*\n * MISSING: documentation\n */\n\nstatic VALUE\nrb_big_coerce(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\treturn rb_assoc_new(rb_int2big(FIX2LONG(y)), x);\n    }\n    else if (TYPE(y) == T_BIGNUM) {\n       return rb_assoc_new(y, x);\n    }\n    else {\n\trb_raise(rb_eTypeError, \"can't coerce %s to Bignum\",\n\t\t rb_obj_classname(y));\n    }\n    /* not reached */\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     big.abs -> aBignum\n *\n *  Returns the absolute value of <i>big</i>.\n *\n *     -1234567890987654321.abs   #=> 1234567890987654321\n */\n\nstatic VALUE\nrb_big_abs(x)\n    VALUE x;\n{\n    if (!RBIGNUM(x)->sign) {\n\tx = rb_big_clone(x);\n\tRBIGNUM(x)->sign = 1;\n    }\n    return x;\n}\n\nVALUE\nrb_big_rand(max, rand_buf)\n    VALUE max;\n    double *rand_buf;\n{\n    VALUE v;\n    long len = RBIGNUM(max)->len;\n\n    if (BIGZEROP(max)) {\n\treturn rb_float_new(rand_buf[0]);\n    }\n    v = bignew(len,1);\n    len--;\n    BDIGITS(v)[len] = BDIGITS(max)[len] * rand_buf[len];\n    while (len--) {\n\tBDIGITS(v)[len] = ((BDIGIT)~0) * rand_buf[len];\n    }\n\n    return v;\n}\n\n/*\n *  call-seq:\n *     big.size -> integer\n *\n *  Returns the number of bytes in the machine representation of\n *  <i>big</i>.\n *\n *     (256**10 - 1).size   #=> 12\n *     (256**20 - 1).size   #=> 20\n *     (256**40 - 1).size   #=> 40\n */\n\nstatic VALUE\nrb_big_size(big)\n    VALUE big;\n{\n    return LONG2FIX(RBIGNUM(big)->len*SIZEOF_BDIGITS);\n}\n\n/*\n *  Bignum objects hold integers outside the range of\n *  Fixnum. Bignum objects are created\n *  automatically when integer calculations would otherwise overflow a\n *  Fixnum. When a calculation involving\n *  Bignum objects returns a result that will fit in a\n *  Fixnum, the result is automatically converted.\n *\n *  For the purposes of the bitwise operations and <code>[]</code>, a\n *  Bignum is treated as if it were an infinite-length\n *  bitstring with 2's complement representation.\n *\n *  While Fixnum values are immediate, Bignum\n *  objects are not---assignment and parameter passing work with\n *  references to objects, not the objects themselves.\n *\n */\n\nvoid\nInit_Bignum()\n{\n    rb_cBignum = rb_define_class(\"Bignum\", rb_cInteger);\n\n    rb_define_method(rb_cBignum, \"to_s\", rb_big_to_s, -1);\n    rb_define_method(rb_cBignum, \"coerce\", rb_big_coerce, 1);\n    rb_define_method(rb_cBignum, \"-@\", rb_big_uminus, 0);\n    rb_define_method(rb_cBignum, \"+\", rb_big_plus, 1);\n    rb_define_method(rb_cBignum, \"-\", rb_big_minus, 1);\n    rb_define_method(rb_cBignum, \"*\", rb_big_mul, 1);\n    rb_define_method(rb_cBignum, \"/\", rb_big_div, 1);\n    rb_define_method(rb_cBignum, \"%\", rb_big_modulo, 1);\n    rb_define_method(rb_cBignum, \"div\", rb_big_div, 1);\n    rb_define_method(rb_cBignum, \"divmod\", rb_big_divmod, 1);\n    rb_define_method(rb_cBignum, \"modulo\", rb_big_modulo, 1);\n    rb_define_method(rb_cBignum, \"remainder\", rb_big_remainder, 1);\n    rb_define_method(rb_cBignum, \"quo\", rb_big_quo, 1);\n    rb_define_method(rb_cBignum, \"fdiv\", rb_big_quo, 1);\n    rb_define_method(rb_cBignum, \"**\", rb_big_pow, 1);\n    rb_define_method(rb_cBignum, \"&\", rb_big_and, 1);\n    rb_define_method(rb_cBignum, \"|\", rb_big_or, 1);\n    rb_define_method(rb_cBignum, \"^\", rb_big_xor, 1);\n    rb_define_method(rb_cBignum, \"~\", rb_big_neg, 0);\n    rb_define_method(rb_cBignum, \"<<\", rb_big_lshift, 1);\n    rb_define_method(rb_cBignum, \">>\", rb_big_rshift, 1);\n    rb_define_method(rb_cBignum, \"[]\", rb_big_aref, 1);\n\n    rb_define_method(rb_cBignum, \"<=>\", rb_big_cmp, 1);\n    rb_define_method(rb_cBignum, \"==\", rb_big_eq, 1);\n    rb_define_method(rb_cBignum, \"eql?\", rb_big_eql, 1);\n    rb_define_method(rb_cBignum, \"hash\", rb_big_hash, 0);\n    rb_define_method(rb_cBignum, \"to_f\", rb_big_to_f, 0);\n    rb_define_method(rb_cBignum, \"abs\", rb_big_abs, 0);\n    rb_define_method(rb_cBignum, \"size\", rb_big_size, 0);\n}\n"
  },
  {
    "path": "bin/erb",
    "content": "#!/usr/bin/env ruby\n# Tiny eRuby --- ERB2\n# Copyright (c) 1999-2000,2002 Masatoshi SEKI \n# You can redistribute it and/or modify it under the same terms as Ruby.\n\nrequire 'erb'\n\nclass ERB\n  module Main\n    def ARGV.switch\n      return nil if self.empty?\n      arg = self.shift\n      return nil if arg == '--'\n      if arg =~ /^-(.)(.*)/\n        return arg if $1 == '-'\n        raise 'unknown switch \"-\"' if $2.index('-')\n        self.unshift \"-#{$2}\" if $2.size > 0\n        \"-#{$1}\"\n      else\n        self.unshift arg\n        nil\n      end\n    end\n    \n    def ARGV.req_arg\n      self.shift || raise('missing argument')\n    end\n\n    def trim_mode_opt(trim_mode, disable_percent)\n      return trim_mode if disable_percent\n      case trim_mode\n      when 0\n        return '%'\n      when 1\n        return '%>'\n      when 2\n        return '%<>'\n      when '-'\n        return '%-'\n      end\n    end\n    module_function :trim_mode_opt\n\n    def run(factory=ERB)\n      trim_mode = 0\n      disable_percent = false\n      begin\n        while switch = ARGV.switch\n          case switch\n          when '-x'                        # ruby source\n            output = true\n          when '-n'                        # line number\n            number = true\n          when '-v'                        # verbose\n            $VERBOSE = true\n          when '--version'                 # version\n            STDERR.puts factory.version\n            exit\n          when '-d', '--debug'             # debug\n            $DEBUG = true\n          when '-r'                        # require\n            require ARGV.req_arg\n          when '-S'                        # security level\n            arg = ARGV.req_arg\n            raise \"invalid safe_level #{arg.dump}\" unless arg =~ /^[0-4]$/\n            safe_level = arg.to_i\n          when '-T'                        # trim mode\n            arg = ARGV.req_arg\n            if arg == '-'\n              trim_mode = arg \n              next\n            end\n            raise \"invalid trim mode #{arg.dump}\" unless arg =~ /^[0-2]$/\n            trim_mode = arg.to_i\n          when '-K'                        # KCODE\n            arg = ARGV.req_arg\n            case arg.downcase\n            when 'e', '-e', 'euc'\n              $KCODE = 'EUC'\n            when 's', '-s', 'sjis'\n              $KCODE = 'SJIS'\n            when 'u', '-u', 'utf8'\n              $KCODE = 'UTF8'\n            when 'n', '-n', 'none'\n              $KCODE = 'NONE'\n            else\n              raise \"invalid KCODE #{arg.dump}\"\n            end\n          when '-P'\n            disable_percent = true\n          when '--help'\n            raise \"print this help\"\n          else\n            raise \"unknown switch #{switch.dump}\"\n          end\n        end\n      rescue                               # usage\n        STDERR.puts $!.to_s\n        STDERR.puts File.basename($0) + \n          \" [switches] [inputfile]\"\n        STDERR.puts <<EOU\n  -x               print ruby script\n  -n               print ruby script with line number\n  -v               enable verbose mode\n  -d               set $DEBUG to true\n  -r [library]     load a library\n  -K [kcode]       specify KANJI code-set\n  -S [safe_level]  set $SAFE (0..4)\n  -T [trim_mode]   specify trim_mode (0..2, -)\n  -P               ignore lines which start with \"%\"\nEOU\n        exit 1\n      end\n\n      src = $<.read\n      filename = $FILENAME\n      exit 2 unless src\n      trim = trim_mode_opt(trim_mode, disable_percent)\n      erb = factory.new(src.untaint, safe_level, trim)\n      erb.filename = filename\n      if output\n        if number\n          l = 1\n          for line in erb.src\n            puts \"%3d %s\"%[l, line]\n            l += 1\n          end\n        else\n          puts erb.src\n        end\n      else\n        erb.run(TOPLEVEL_BINDING.taint)\n      end\n    end\n    module_function :run\n  end\nend\n\nif __FILE__ == $0\n  ERB::Main.run\nend\n"
  },
  {
    "path": "bin/irb",
    "content": "#!/usr/bin/env ruby\n#\n#   irb.rb - intaractive ruby\n#   \t$Release Version: 0.9.5 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n\nrequire \"irb\"\n\nif __FILE__ == $0\n  IRB.start(__FILE__)\nelse\n  # check -e option\n  if /^-e$/ =~ $0\n    IRB.start(__FILE__)\n  else\n    IRB.setup(__FILE__)\n  end\nend\n"
  },
  {
    "path": "bin/rdoc",
    "content": "#!/usr/bin/env ruby\n#\n#  RDoc: Documentation tool for source code\n#        (see lib/rdoc/rdoc.rb for more information)\n#\n#  Copyright (c) 2003 Dave Thomas\n#  Released under the same terms as Ruby\n#\n#  $Revision$\n\n## Transitional Hack ####\n#\n#  RDoc was initially distributed independently, and installed\n#  itself into <prefix>/lib/ruby/site_ruby/<ver>/rdoc...\n#\n#  Now that RDoc is part of the distribution, it's installed into\n#  <prefix>/lib/ruby/<ver>, which unfortunately appears later in the\n#  search path. This means that if you have previously installed RDoc,\n#  and then install from ruby-lang, you'll pick up the old one by\n#  default. This hack checks for the condition, and readjusts the\n#  search path if necessary.\n\ndef adjust_for_existing_rdoc(path)\n  \n  $stderr.puts %{\n  It seems as if you have a previously-installed RDoc in\n  the directory #{path}.\n\n  Because this is now out-of-date, you might want to consider\n  removing the directories:\n\n    #{File.join(path, \"rdoc\")}\n\n  and\n\n    #{File.join(path, \"markup\")}\n\n  }\n\n  # Move all the site_ruby directories to the end\n  p $:\n  $:.replace($:.partition {|path| /site_ruby/ !~ path}.flatten)\n  p $:\nend\n\n$:.each do |path|\n  if /site_ruby/ =~ path \n    rdoc_path = File.join(path, 'rdoc', 'rdoc.rb')\n    if File.exists?(rdoc_path)\n      adjust_for_existing_rdoc(path)\n      break\n    end\n  end\nend\n\n## End of Transitional Hack ##\n\n\nrequire 'rdoc/rdoc'\n\nbegin\n  r = RDoc::RDoc.new\n  r.document(ARGV)\nrescue RDoc::RDocError => e\n  $stderr.puts e.message\n  exit(1)\nend\n"
  },
  {
    "path": "bin/ri",
    "content": "#!/usr/bin/env ruby\n# usage:\n#\n#   ri  name...\n#\n# where name can be \n#\n#   Class | Class::method | Class#method | Class.method | method\n#\n# All names may be abbreviated to their minimum unbiguous form. If a name\n# _is_ ambiguous, all valid options will be listed.\n#\n# The form '.' method matches either class or instance methods, while \n# #method matches only instance and ::method matches only class methods.\n#\n#\n# == Installing Documentation\n#\n# 'ri' uses a database of documentation built by the RDoc utility.\n# \n# So, how do you install this documentation on your system?\n# It depends on how you installed Ruby.\n#\n# <em>If you installed Ruby from source files</em> (that is, if it some point\n# you typed 'make' during the process :), you can install the RDoc\n# documentation yourself. Just go back to the place where you have \n# your Ruby source and type\n#\n#    make install-doc\n#\n# You'll probably need to do this as a superuser, as the documentation\n# is installed in the Ruby target tree (normally somewhere under \n# <tt>/usr/local</tt>.\n#\n# <em>If you installed Ruby from a binary distribution</em> (perhaps\n# using a one-click installer, or using some other packaging system),\n# then the team that produced the package probably forgot to package\n# the documentation as well. Contact them, and see if they can add\n# it to the next release.\n#\n\n\nrequire 'rdoc/ri/ri_driver'\n\n######################################################################\n\nri = RiDriver.new\nri.process_args\n\n"
  },
  {
    "path": "bin/testrb",
    "content": "#!/usr/bin/env ruby\nrequire 'test/unit'\n(r = Test::Unit::AutoRunner.new(true)).process_args(ARGV) or\n  abort r.options.banner + \" tests...\"\nexit r.run\n"
  },
  {
    "path": "class.c",
    "content": "/**********************************************************************\n\n  class.c -\n\n  $Author$\n  $Date$\n  created at: Tue Aug 10 15:05:44 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n#include \"node.h\"\n#include \"st.h\"\n#include <ctype.h>\n\nextern st_table *rb_class_tbl;\n\nVALUE\nrb_class_boot(super)\n    VALUE super;\n{\n    NEWOBJ(klass, struct RClass);\n    OBJSETUP(klass, rb_cClass, T_CLASS);\n\n    klass->super = super;\n    klass->iv_tbl = 0;\n    klass->m_tbl = 0;\t\t/* safe GC */\n    klass->m_tbl = st_init_numtable();\n\n    OBJ_INFECT(klass, super);\n    return (VALUE)klass;\n}\n\nVALUE\nrb_class_new(super)\n    VALUE super;\n{\n    Check_Type(super, T_CLASS);\n    if (super == rb_cClass) {\n\trb_raise(rb_eTypeError, \"can't make subclass of Class\");\n    }\n    if (FL_TEST(super, FL_SINGLETON)) {\n\trb_raise(rb_eTypeError, \"can't make subclass of virtual class\");\n    }\n    return rb_class_boot(super);\n}\n\nstruct clone_method_data {\n    st_table *tbl;\n    VALUE klass;\n};\n\nstatic int\nclone_method(mid, body, data)\n    ID mid;\n    NODE *body;\n    struct clone_method_data *data;\n{\n    NODE *fbody = body->nd_body;\n\n    if (fbody && nd_type(fbody) == NODE_SCOPE) {\n\tNODE *cref = (NODE*)fbody->nd_rval;\n\n\tif (cref) cref = cref->nd_next;\n\tfbody = rb_copy_node_scope(fbody, NEW_CREF(data->klass, cref));\n    }\n    st_insert(data->tbl, mid, (st_data_t)NEW_METHOD(fbody, body->nd_noex));\n    return ST_CONTINUE;\n}\n\n/* :nodoc: */\nVALUE\nrb_mod_init_copy(clone, orig)\n    VALUE clone, orig;\n{\n    rb_obj_init_copy(clone, orig);\n    if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {\n\tRBASIC(clone)->klass = RBASIC(orig)->klass;\n\tRBASIC(clone)->klass = rb_singleton_class_clone(clone);\n    }\n    RCLASS(clone)->super = RCLASS(orig)->super;\n    if (RCLASS(orig)->iv_tbl) {\n\tID id;\n\n\tRCLASS(clone)->iv_tbl = st_copy(RCLASS(orig)->iv_tbl);\n\tid = rb_intern(\"__classpath__\");\n\tst_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);\n\tid = rb_intern(\"__classid__\");\n\tst_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);\n    }\n    if (RCLASS(orig)->m_tbl) {\n\tstruct clone_method_data data;\n\n\tdata.tbl = RCLASS(clone)->m_tbl = st_init_numtable();\n\tdata.klass = (VALUE)clone;\n\n\tst_foreach(RCLASS(orig)->m_tbl, clone_method, (st_data_t)&data);\n    }\n\n    return clone;\n}\n\n/* :nodoc: */\nVALUE\nrb_class_init_copy(clone, orig)\n    VALUE clone, orig;\n{\n    if (RCLASS(clone)->super != 0) {\n\trb_raise(rb_eTypeError, \"already initialized class\");\n    }\n    if (FL_TEST(orig, FL_SINGLETON)) {\n\trb_raise(rb_eTypeError, \"can't copy singleton class\");\n    }\n    return rb_mod_init_copy(clone, orig);\n}\n\nVALUE\nrb_singleton_class_clone(obj)\n    VALUE obj;\n{\n    VALUE klass = RBASIC(obj)->klass;\n\n    if (!FL_TEST(klass, FL_SINGLETON))\n\treturn klass;\n    else {\n\t/* copy singleton(unnamed) class */\n\tNEWOBJ(clone, struct RClass);\n\tOBJSETUP(clone, 0, RBASIC(klass)->flags);\n\n\tif (BUILTIN_TYPE(obj) == T_CLASS) {\n\t    RBASIC(clone)->klass = (VALUE)clone;\n\t}\n\telse {\n\t    RBASIC(clone)->klass = rb_singleton_class_clone(klass);\n\t}\n\n\tclone->super = RCLASS(klass)->super;\n\tclone->iv_tbl = 0;\n\tclone->m_tbl = 0;\n\tif (RCLASS(klass)->iv_tbl) {\n\t    clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);\n\t}\n\t{\n\t    struct clone_method_data data;\n\n\t    data.tbl = clone->m_tbl = st_init_numtable();\n\t    switch (TYPE(obj)) {\n\t      case T_CLASS:\n\t      case T_MODULE:\n\t\tdata.klass = obj;\n\t\tbreak;\n\t      default:\n\t\tdata.klass = Qnil;\n\t\tbreak;\n\t    }\n\n\t    st_foreach(RCLASS(klass)->m_tbl, clone_method, (st_data_t)&data);\n\t}\n\trb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\n\tFL_SET(clone, FL_SINGLETON);\n\treturn (VALUE)clone;\n    }\n}\n\nvoid\nrb_singleton_class_attached(klass, obj)\n    VALUE klass, obj;\n{\n    if (FL_TEST(klass, FL_SINGLETON)) {\n\tif (!RCLASS(klass)->iv_tbl) {\n\t    RCLASS(klass)->iv_tbl = st_init_numtable();\n\t}\n\tst_insert(RCLASS(klass)->iv_tbl, rb_intern(\"__attached__\"), obj);\n    }\n}\n\nVALUE\nrb_make_metaclass(obj, super)\n    VALUE obj, super;\n{\n    VALUE klass = rb_class_boot(super);\n    FL_SET(klass, FL_SINGLETON);\n    RBASIC(obj)->klass = klass;\n    rb_singleton_class_attached(klass, obj);\n    if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {\n\tRBASIC(klass)->klass = klass;\n\tRCLASS(klass)->super = RBASIC(rb_class_real(RCLASS(obj)->super))->klass;\n    }\n    else {\n\tVALUE metasuper = RBASIC(rb_class_real(super))->klass;\n\n\t/* metaclass of a superclass may be NULL at boot time */\n\tif (metasuper) {\n\t    RBASIC(klass)->klass = metasuper;\n\t}\n    }\n\n    return klass;\n}\n\nVALUE\nrb_define_class_id(id, super)\n    ID id;\n    VALUE super;\n{\n    VALUE klass;\n\n    if (!super) super = rb_cObject;\n    klass = rb_class_new(super);\n    rb_make_metaclass(klass, RBASIC(super)->klass);\n\n    return klass;\n}\n\nvoid\nrb_check_inheritable(super)\n    VALUE super;\n{\n    if (TYPE(super) != T_CLASS) {\n\trb_raise(rb_eTypeError, \"superclass must be a Class (%s given)\",\n\t\t rb_obj_classname(super));\n    }\n    if (RBASIC(super)->flags & FL_SINGLETON) {\n\trb_raise(rb_eTypeError, \"can't make subclass of virtual class\");\n    }\n}\n\nVALUE\nrb_class_inherited(super, klass)\n    VALUE super, klass;\n{\n    if (!super) super = rb_cObject;\n    return rb_funcall(super, rb_intern(\"inherited\"), 1, klass);\n}\n\nVALUE\nrb_define_class(name, super)\n    const char *name;\n    VALUE super;\n{\n    VALUE klass;\n    ID id;\n\n    id = rb_intern(name);\n    if (rb_const_defined(rb_cObject, id)) {\n\tklass = rb_const_get(rb_cObject, id);\n\tif (TYPE(klass) != T_CLASS) {\n\t    rb_raise(rb_eTypeError, \"%s is not a class\", name);\n\t}\n\tif (rb_class_real(RCLASS(klass)->super) != super) {\n\t    rb_name_error(id, \"%s is already defined\", name);\n\t}\n\treturn klass;\n    }\n    if (!super) {\n\trb_warn(\"no super class for `%s', Object assumed\", name);\n    }\n    klass = rb_define_class_id(id, super);\n    st_add_direct(rb_class_tbl, id, klass);\n    rb_name_class(klass, id);\n    rb_const_set(rb_cObject, id, klass);\n    rb_class_inherited(super, klass);\n\n    return klass;\n}\n\nVALUE\nrb_define_class_under(outer, name, super)\n    VALUE outer;\n    const char *name;\n    VALUE super;\n{\n    VALUE klass;\n    ID id;\n\n    id = rb_intern(name);\n    if (rb_const_defined_at(outer, id)) {\n\tklass = rb_const_get_at(outer, id);\n\tif (TYPE(klass) != T_CLASS) {\n\t    rb_raise(rb_eTypeError, \"%s is not a class\", name);\n\t}\n\tif (rb_class_real(RCLASS(klass)->super) != super) {\n\t    rb_name_error(id, \"%s is already defined\", name);\n\t}\n\treturn klass;\n    }\n    if (!super) {\n\trb_warn(\"no super class for `%s::%s', Object assumed\",\n\t\trb_class2name(outer), name);\n    }\n    klass = rb_define_class_id(id, super);\n    rb_set_class_path(klass, outer, name);\n    rb_const_set(outer, id, klass);\n    rb_class_inherited(super, klass);\n\n    return klass;\n}\n\nVALUE\nrb_module_new()\n{\n    NEWOBJ(mdl, struct RClass);\n    OBJSETUP(mdl, rb_cModule, T_MODULE);\n\n    mdl->super = 0;\n    mdl->iv_tbl = 0;\n    mdl->m_tbl = 0;\n    mdl->m_tbl = st_init_numtable();\n\n    return (VALUE)mdl;\n}\n\nVALUE\nrb_define_module_id(id)\n    ID id;\n{\n    VALUE mdl;\n\n    mdl = rb_module_new();\n    rb_name_class(mdl, id);\n\n    return mdl;\n}\n\nVALUE\nrb_define_module(name)\n    const char *name;\n{\n    VALUE module;\n    ID id;\n\n    id = rb_intern(name);\n    if (rb_const_defined(rb_cObject, id)) {\n\tmodule = rb_const_get(rb_cObject, id);\n\tif (TYPE(module) == T_MODULE)\n\t    return module;\n\trb_raise(rb_eTypeError, \"%s is not a module\", rb_obj_classname(module));\n    }\n    module = rb_define_module_id(id);\n    st_add_direct(rb_class_tbl, id, module);\n    rb_const_set(rb_cObject, id, module);\n\n    return module;\n}\n\nVALUE\nrb_define_module_under(outer, name)\n    VALUE outer;\n    const char *name;\n{\n    VALUE module;\n    ID id;\n\n    id = rb_intern(name);\n    if (rb_const_defined_at(outer, id)) {\n\tmodule = rb_const_get_at(outer, id);\n\tif (TYPE(module) == T_MODULE)\n\t    return module;\n\trb_raise(rb_eTypeError, \"%s::%s is not a module\",\n\t\t rb_class2name(outer), rb_obj_classname(module));\n    }\n    module = rb_define_module_id(id);\n    rb_const_set(outer, id, module);\n    rb_set_class_path(module, outer, name);\n\n    return module;\n}\n\nstatic VALUE\ninclude_class_new(module, super)\n    VALUE module, super;\n{\n    NEWOBJ(klass, struct RClass);\n    OBJSETUP(klass, rb_cClass, T_ICLASS);\n\n    if (BUILTIN_TYPE(module) == T_ICLASS) {\n\tmodule = RBASIC(module)->klass;\n    }\n    if (!RCLASS(module)->iv_tbl) {\n\tRCLASS(module)->iv_tbl = st_init_numtable();\n    }\n    klass->iv_tbl = RCLASS(module)->iv_tbl;\n    klass->m_tbl = RCLASS(module)->m_tbl;\n    klass->super = super;\n    if (TYPE(module) == T_ICLASS) {\n\tRBASIC(klass)->klass = RBASIC(module)->klass;\n    }\n    else {\n\tRBASIC(klass)->klass = module;\n    }\n    OBJ_INFECT(klass, module);\n    OBJ_INFECT(klass, super);\n\n    return (VALUE)klass;\n}\n\nvoid\nrb_include_module(klass, module)\n    VALUE klass, module;\n{\n    VALUE p, c;\n    int changed = 0;\n\n    rb_frozen_class_p(klass);\n    if (!OBJ_TAINTED(klass)) {\n\trb_secure(4);\n    }\n    \n    if (TYPE(module) != T_MODULE) {\n\tCheck_Type(module, T_MODULE);\n    }\n\n    OBJ_INFECT(klass, module);\n    c = klass;\n    while (module) {\n\tint superclass_seen = Qfalse;\n\n\tif (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)\n\t    rb_raise(rb_eArgError, \"cyclic include detected\");\n\t/* ignore if the module included already in superclasses */\n\tfor (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {\n\t    switch (BUILTIN_TYPE(p)) {\n\t      case T_ICLASS:\n\t\tif (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {\n\t\t    if (!superclass_seen) {\n\t\t\tc = p;\t/* move insertion point */\n\t\t    }\n\t\t    goto skip;\n\t\t}\n\t\tbreak;\n\t      case T_CLASS:\n\t\tsuperclass_seen = Qtrue;\n\t\tbreak;\n\t    }\n\t}\n\tc = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);\n\tchanged = 1;\n      skip:\n\tmodule = RCLASS(module)->super;\n    }\n    if (changed) rb_clear_cache();\n}\n\n/*\n *  call-seq:\n *     mod.included_modules -> array\n *  \n *  Returns the list of modules included in <i>mod</i>.\n *     \n *     module Mixin\n *     end\n *     \n *     module Outer\n *       include Mixin\n *     end\n *     \n *     Mixin.included_modules   #=> []\n *     Outer.included_modules   #=> [Mixin]\n */\n\nVALUE\nrb_mod_included_modules(mod)\n    VALUE mod;\n{\n    VALUE ary = rb_ary_new();\n    VALUE p;\n\n    for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {\n\tif (BUILTIN_TYPE(p) == T_ICLASS) {\n\t    rb_ary_push(ary, RBASIC(p)->klass);\n\t}\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     mod.include?(module)    => true or false\n *  \n *  Returns <code>true</code> if <i>module</i> is included in\n *  <i>mod</i> or one of <i>mod</i>'s ancestors.\n *     \n *     module A\n *     end\n *     class B\n *       include A\n *     end\n *     class C < B\n *     end\n *     B.include?(A)   #=> true\n *     C.include?(A)   #=> true\n *     A.include?(A)   #=> false\n */\n\nVALUE\nrb_mod_include_p(mod, mod2)\n    VALUE mod;\n    VALUE mod2;\n{\n    VALUE p;\n\n    Check_Type(mod2, T_MODULE);\n    for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {\n\tif (BUILTIN_TYPE(p) == T_ICLASS) {\n\t    if (RBASIC(p)->klass == mod2) return Qtrue;\n\t}\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     mod.ancestors -> array\n *  \n *  Returns a list of modules included in <i>mod</i> (including\n *  <i>mod</i> itself).\n *     \n *     module Mod\n *       include Math\n *       include Comparable\n *     end\n *     \n *     Mod.ancestors    #=> [Mod, Comparable, Math]\n *     Math.ancestors   #=> [Math]\n */\n\nVALUE\nrb_mod_ancestors(mod)\n    VALUE mod;\n{\n    VALUE p, ary = rb_ary_new();\n\n    for (p = mod; p; p = RCLASS(p)->super) {\n\tif (FL_TEST(p, FL_SINGLETON))\n\t    continue;\n\tif (BUILTIN_TYPE(p) == T_ICLASS) {\n\t    rb_ary_push(ary, RBASIC(p)->klass);\n\t}\n\telse {\n\t    rb_ary_push(ary, p);\n\t}\n    }\n    return ary;\n}\n\n#define VISI(x) ((x)&NOEX_MASK)\n#define VISI_CHECK(x,f) (VISI(x) == (f))\n\nstatic int\nins_methods_push(name, type, ary, visi)\n    ID name;\n    long type;\n    VALUE ary;\n    long visi;\n{\n    if (type == -1) return ST_CONTINUE;\n    switch (visi) {\n      case NOEX_PRIVATE:\n      case NOEX_PROTECTED:\n      case NOEX_PUBLIC:\n\tvisi = (type == visi);\n\tbreak;\n      default:\n\tvisi = (type != NOEX_PRIVATE);\n\tbreak;\n    }\n    if (visi) {\n\trb_ary_push(ary, rb_str_new2(rb_id2name(name)));\n    }\n    return ST_CONTINUE;\n}\n\nstatic int\nins_methods_i(name, type, ary)\n    ID name;\n    long type;\n    VALUE ary;\n{\n    return ins_methods_push(name, type, ary, -1); /* everything but private */\n}\n\nstatic int\nins_methods_prot_i(name, type, ary)\n    ID name;\n    long type;\n    VALUE ary;\n{\n    return ins_methods_push(name, type, ary, NOEX_PROTECTED);\n}\n\nstatic int\nins_methods_priv_i(name, type, ary)\n    ID name;\n    long type;\n    VALUE ary;\n{\n    return ins_methods_push(name, type, ary, NOEX_PRIVATE);\n}\n\nstatic int\nins_methods_pub_i(name, type, ary)\n    ID name;\n    long type;\n    VALUE ary;\n{\n    return ins_methods_push(name, type, ary, NOEX_PUBLIC);\n}\n\nstatic int\nmethod_entry(key, body, list)\n    ID key;\n    NODE *body;\n    st_table *list;\n{\n    long type;\n\n    if (key == ID_ALLOCATOR) return ST_CONTINUE;\n    if (!st_lookup(list, key, 0)) {\n\tif (!body->nd_body) type = -1; /* none */\n\telse type = VISI(body->nd_noex);\n\tst_add_direct(list, key, type);\n    }\n    return ST_CONTINUE;\n}\n\nstatic VALUE\nclass_instance_method_list(argc, argv, mod, func)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n    int (*func) _((ID, long, VALUE));\n{\n    VALUE ary;\n    int recur;\n    st_table *list;\n\n    if (argc == 0) {\n\trecur = Qtrue;\n    }\n    else {\n\tVALUE r;\n\trb_scan_args(argc, argv, \"01\", &r);\n\trecur = RTEST(r);\n    }\n\n    list = st_init_numtable();\n    for (; mod; mod = RCLASS(mod)->super) {\n\tst_foreach(RCLASS(mod)->m_tbl, method_entry, (st_data_t)list);\n\tif (BUILTIN_TYPE(mod) == T_ICLASS) continue;\n\tif (FL_TEST(mod, FL_SINGLETON)) continue;\n\tif (!recur) break;\n    }\n    ary = rb_ary_new();\n    st_foreach(list, func, ary);\n    st_free_table(list);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     mod.instance_methods(include_super=true)   => array\n *  \n *  Returns an array containing the names of public instance methods in\n *  the receiver. For a module, these are the public methods; for a\n *  class, they are the instance (not singleton) methods. With no\n *  argument, or with an argument that is <code>false</code>, the\n *  instance methods in <i>mod</i> are returned, otherwise the methods\n *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.\n *     \n *     module A\n *       def method1()  end\n *     end\n *     class B\n *       def method2()  end\n *     end\n *     class C < B\n *       def method3()  end\n *     end\n *     \n *     A.instance_methods                #=> [\"method1\"]\n *     B.instance_methods(false)         #=> [\"method2\"]\n *     C.instance_methods(false)         #=> [\"method3\"]\n *     C.instance_methods(true).length   #=> 43\n */\n\nVALUE\nrb_class_instance_methods(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    return class_instance_method_list(argc, argv, mod, ins_methods_i);\n}\n\n/*\n *  call-seq:\n *     mod.protected_instance_methods(include_super=true)   => array\n *  \n *  Returns a list of the protected instance methods defined in\n *  <i>mod</i>. If the optional parameter is not <code>false</code>, the\n *  methods of any ancestors are included.\n */\n\nVALUE\nrb_class_protected_instance_methods(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    return class_instance_method_list(argc, argv, mod, ins_methods_prot_i);\n}\n\n/*\n *  call-seq:\n *     mod.private_instance_methods(include_super=true)    => array\n *  \n *  Returns a list of the private instance methods defined in\n *  <i>mod</i>. If the optional parameter is not <code>false</code>, the\n *  methods of any ancestors are included.\n *     \n *     module Mod\n *       def method1()  end\n *       private :method1\n *       def method2()  end\n *     end\n *     Mod.instance_methods           #=> [\"method2\"]\n *     Mod.private_instance_methods   #=> [\"method1\"]\n */\n\nVALUE\nrb_class_private_instance_methods(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    return class_instance_method_list(argc, argv, mod, ins_methods_priv_i);\n}\n\n/*\n *  call-seq:\n *     mod.public_instance_methods(include_super=true)   => array\n *  \n *  Returns a list of the public instance methods defined in <i>mod</i>.\n *  If the optional parameter is not <code>false</code>, the methods of\n *  any ancestors are included.\n */\n\nVALUE\nrb_class_public_instance_methods(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    return class_instance_method_list(argc, argv, mod, ins_methods_pub_i);\n}\n\n/*\n *  call-seq:\n *     obj.singleton_methods(all=true)    => array\n *  \n *  Returns an array of the names of singleton methods for <i>obj</i>.\n *  If the optional <i>all</i> parameter is true, the list will include\n *  methods in modules included in <i>obj</i>.\n *     \n *     module Other\n *       def three() end\n *     end\n *     \n *     class Single\n *       def Single.four() end\n *     end\n *     \n *     a = Single.new\n *     \n *     def a.one()\n *     end\n *     \n *     class << a\n *       include Other\n *       def two()\n *       end\n *     end\n *     \n *     Single.singleton_methods    #=> [\"four\"]\n *     a.singleton_methods(false)  #=> [\"two\", \"one\"]\n *     a.singleton_methods         #=> [\"two\", \"one\", \"three\"]\n */\n\nVALUE\nrb_obj_singleton_methods(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE recur, ary, klass;\n    st_table *list;\n\n    rb_scan_args(argc, argv, \"01\", &recur);\n    if (argc == 0) {\n\trecur = Qtrue;\n    }\n    klass = CLASS_OF(obj);\n    list = st_init_numtable();\n    if (klass && FL_TEST(klass, FL_SINGLETON)) {\n\tst_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);\n\tklass = RCLASS(klass)->super;\n    }\n    if (RTEST(recur)) {\n\twhile (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {\n\t    st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);\n\t    klass = RCLASS(klass)->super;\n\t}\n    }\n    ary = rb_ary_new();\n    st_foreach(list, ins_methods_i, ary);\n    st_free_table(list);\n\n    return ary;\n}\n\nvoid\nrb_define_method_id(klass, name, func, argc)\n    VALUE klass;\n    ID name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);\n}\n\nvoid\nrb_define_method(klass, name, func, argc)\n    VALUE klass;\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    ID id = rb_intern(name);\n    int ex = NOEX_PUBLIC;\n\n\n    rb_add_method(klass, id, NEW_CFUNC(func, argc), ex);\n}\n\nvoid\nrb_define_protected_method(klass, name, func, argc)\n    VALUE klass;\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED);\n}\n\nvoid\nrb_define_private_method(klass, name, func, argc)\n    VALUE klass;\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);\n}\n\nvoid\nrb_undef_method(klass, name)\n    VALUE klass;\n    const char *name;\n{\n    rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);\n}\n\n#define SPECIAL_SINGLETON(x,c) do {\\\n    if (obj == (x)) {\\\n\treturn c;\\\n    }\\\n} while (0)\n\nVALUE\nrb_singleton_class(obj)\n    VALUE obj;\n{\n    VALUE klass;\n\n    if (FIXNUM_P(obj) || SYMBOL_P(obj)) {\n\trb_raise(rb_eTypeError, \"can't define singleton\");\n    }\n    if (rb_special_const_p(obj)) {\n\tSPECIAL_SINGLETON(Qnil, rb_cNilClass);\n\tSPECIAL_SINGLETON(Qfalse, rb_cFalseClass);\n\tSPECIAL_SINGLETON(Qtrue, rb_cTrueClass);\n\trb_bug(\"unknown immediate %ld\", obj);\n    }\n\n    DEFER_INTS;\n    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&\n\trb_iv_get(RBASIC(obj)->klass, \"__attached__\") == obj) {\n\tklass = RBASIC(obj)->klass;\n    }\n    else {\n\tklass = rb_make_metaclass(obj, RBASIC(obj)->klass);\n    }\n    if (OBJ_TAINTED(obj)) {\n\tOBJ_TAINT(klass);\n    }\n    else {\n\tFL_UNSET(klass, FL_TAINT);\n    }\n    if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);\n    ALLOW_INTS;\n\n    return klass;\n}\n\nvoid\nrb_define_singleton_method(obj, name, func, argc)\n    VALUE obj;\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_define_method(rb_singleton_class(obj), name, func, argc);\n}\n\nvoid\nrb_define_module_function(module, name, func, argc)\n    VALUE module;\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_define_private_method(module, name, func, argc);\n    rb_define_singleton_method(module, name, func, argc);\n}\n\nvoid\nrb_define_global_function(name, func, argc)\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_define_module_function(rb_mKernel, name, func, argc);\n}\n\nvoid\nrb_define_alias(klass, name1, name2)\n    VALUE klass;\n    const char *name1, *name2;\n{\n    rb_alias(klass, rb_intern(name1), rb_intern(name2));\n}\n\nvoid\nrb_define_attr(klass, name, read, write)\n    VALUE klass;\n    const char *name;\n    int read, write;\n{\n    rb_attr(klass, rb_intern(name), read, write, Qfalse);\n}\n\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n\nint\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)\n#else\nrb_scan_args(argc, argv, fmt, va_alist)\n    int argc;\n    const VALUE *argv;\n    const char *fmt;\n    va_dcl\n#endif\n{\n    int n, i = 0;\n    const char *p = fmt;\n    VALUE *var;\n    va_list vargs;\n\n    va_init_list(vargs, fmt);\n\n    if (*p == '*') goto rest_arg;\n\n    if (ISDIGIT(*p)) {\n\tn = *p - '0';\n\tif (n > argc)\n\t    rb_raise(rb_eArgError, \"wrong number of arguments (%d for %d)\", argc, n);\n\tfor (i=0; i<n; i++) {\n\t    var = va_arg(vargs, VALUE*);\n\t    if (var) *var = argv[i];\n\t}\n\tp++;\n    }\n    else {\n\tgoto error;\n    }\n\n    if (ISDIGIT(*p)) {\n\tn = i + *p - '0';\n\tfor (; i<n; i++) {\n\t    var = va_arg(vargs, VALUE*);\n\t    if (argc > i) {\n\t\tif (var) *var = argv[i];\n\t    }\n\t    else {\n\t\tif (var) *var = Qnil;\n\t    }\n\t}\n\tp++;\n    }\n\n    if(*p == '*') {\n      rest_arg:\n\tvar = va_arg(vargs, VALUE*);\n\tif (argc > i) {\n\t    if (var) *var = rb_ary_new4(argc-i, argv+i);\n\t    i = argc;\n\t}\n\telse {\n\t    if (var) *var = rb_ary_new();\n\t}\n\tp++;\n    }\n\n    if (*p == '&') {\n\tvar = va_arg(vargs, VALUE*);\n\tif (rb_block_given_p()) {\n\t    *var = rb_block_proc();\n\t}\n\telse {\n\t    *var = Qnil;\n\t}\n\tp++;\n    }\n    va_end(vargs);\n\n    if (*p != '\\0') {\n\tgoto error;\n    }\n\n    if (argc > i) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for %d)\", argc, i);\n    }\n\n    return argc;\n\n  error:\n    rb_fatal(\"bad scan arg format: %s\", fmt);\n    return 0;\n}\n"
  },
  {
    "path": "common.mk",
    "content": "bin: $(PROGRAM) $(WPROGRAM)\nlib: $(LIBRUBY)\ndll: $(LIBRUBY_SO)\n\nRUBYLIB       = -\nRUBYOPT       = -\n\nSPEC_GIT_BASE = git://github.com/rubyspec\nMSPEC_GIT_URL = $(SPEC_GIT_BASE)/mspec.git\nRUBYSPEC_GIT_URL = $(SPEC_GIT_BASE)/rubyspec.git\n\nSTATIC_RUBY   = static-ruby\n\nEXTCONF       = extconf.rb\nRBCONFIG      = ./.rbconfig.time\nLIBRUBY_EXTS  = ./.libruby-with-ext.time\nRDOCOUT       = $(EXTOUT)/rdoc\n\nDMYEXT\t      = dmyext.$(OBJEXT)\nMAINOBJ\t      = main.$(OBJEXT)\nEXTOBJS\t      =\nDLDOBJS\t      = $(DMYEXT)\n\nOBJS\t      = array.$(OBJEXT) \\\n\t\tbignum.$(OBJEXT) \\\n\t\tclass.$(OBJEXT) \\\n\t\tcompar.$(OBJEXT) \\\n\t\tdir.$(OBJEXT) \\\n\t\tdln.$(OBJEXT) \\\n\t\tenum.$(OBJEXT) \\\n\t\tenumerator.$(OBJEXT) \\\n\t\terror.$(OBJEXT) \\\n\t\teval.$(OBJEXT) \\\n\t\tfile.$(OBJEXT) \\\n\t\tgc.$(OBJEXT) \\\n\t\thash.$(OBJEXT) \\\n\t\tinits.$(OBJEXT) \\\n\t\tio.$(OBJEXT) \\\n\t\tmarshal.$(OBJEXT) \\\n\t\tmath.$(OBJEXT) \\\n\t\tnumeric.$(OBJEXT) \\\n\t\tobject.$(OBJEXT) \\\n\t\tpack.$(OBJEXT) \\\n\t\tparse.$(OBJEXT) \\\n\t\tpointerset.$(OBJEXT) \\\n\t\tprocess.$(OBJEXT) \\\n\t\tprec.$(OBJEXT) \\\n\t\trandom.$(OBJEXT) \\\n\t\trange.$(OBJEXT) \\\n\t\tre.$(OBJEXT) \\\n\t\tregex.$(OBJEXT) \\\n\t\truby.$(OBJEXT) \\\n\t\tsignal.$(OBJEXT) \\\n\t\tsprintf.$(OBJEXT) \\\n\t\tst.$(OBJEXT) \\\n\t\tstring.$(OBJEXT) \\\n\t\tstruct.$(OBJEXT) \\\n\t\ttime.$(OBJEXT) \\\n\t\tutil.$(OBJEXT) \\\n\t\tvariable.$(OBJEXT) \\\n\t\tversion.$(OBJEXT) \\\n\t\t$(MISSING)\n\nSCRIPT_ARGS   =\t--dest-dir=\"$(DESTDIR)\" \\\n\t\t--extout=\"$(EXTOUT)\" \\\n\t\t--mflags=\"$(MFLAGS)\" \\\n\t\t--make-flags=\"$(MAKEFLAGS)\"\nEXTMK_ARGS    =\t$(SCRIPT_ARGS) --extension $(EXTS) --extstatic $(EXTSTATIC) \\\n\t\t--make-flags=\"MINIRUBY='$(MINIRUBY)'\" --\nINSTRUBY_ARGS =\t$(SCRIPT_ARGS) \\\n\t\t--data-mode=$(INSTALL_DATA_MODE) \\\n\t\t--prog-mode=$(INSTALL_PROG_MODE) \\\n\t\t--installed-list $(INSTALLED_LIST)\nINSTALL_PROG_MODE = 0755\nINSTALL_DATA_MODE = 0644\n\nPRE_LIBRUBY_UPDATE = $(MINIRUBY) -e 'ARGV[1] or File.unlink(ARGV[0]) rescue nil' -- \\\n\t\t\t$(LIBRUBY_EXTS) $(LIBRUBY_SO_UPDATE)\n\nTESTSDIR      = $(srcdir)/test\nTESTWORKDIR   = testwork\n\nall: $(MKFILES) $(PREP) $(RBCONFIG) $(LIBRUBY)\n\t@$(MINIRUBY) $(srcdir)/ext/extmk.rb --make=\"$(MAKE)\" $(EXTMK_ARGS)\nprog: $(PROGRAM) $(WPROGRAM)\n\nminiruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) $(MINIOBJS) $(OBJS) $(DMYEXT)\n\n$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)\n\n$(LIBRUBY_A):\t$(OBJS) $(DMYEXT) $(ARCHFILE)\n\n$(LIBRUBY_SO):\t$(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(LIBRUBY_SO_UPDATE)\n\n$(LIBRUBY_EXTS):\n\t@exit > $@\n\n$(STATIC_RUBY)$(EXEEXT): $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A)\n\t@$(RM) $@\n\t$(PURIFY) $(CC) $(MAINOBJ) $(DLDOBJS) $(EXTOBJS) $(LIBRUBY_A) $(MAINLIBS) $(EXTLIBS) $(LIBS) $(OUTFLAG)$@ $(LDFLAGS) $(XLDFLAGS)\n\nruby.imp: $(OBJS)\n\t@$(NM) -Pgp $(OBJS) | awk 'BEGIN{print \"#!\"}; $$2~/^[BD]$$/{print $$1}' | sort -u -o $@\n\ninstall: install-nodoc $(RDOCTARGET)\ninstall-all: install-nodoc install-doc\n\ninstall-nodoc: pre-install-nodoc do-install-nodoc post-install-nodoc\npre-install-nodoc:: pre-install-local pre-install-ext\ndo-install-nodoc:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --mantype=\"$(MANTYPE)\"\npost-install-nodoc:: post-install-local post-install-ext\n\ninstall-local: pre-install-local do-install-local post-install-local\npre-install-local:: pre-install-bin pre-install-lib pre-install-man\ndo-install-local:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=local --mantype=\"$(MANTYPE)\"\nloadpath: $(PREP)\n\t$(MINIRUBY) -e 'p $$:'\n\npost-install-local:: post-install-bin post-install-lib post-install-man\n\ninstall-ext: pre-install-ext do-install-ext post-install-ext\npre-install-ext:: pre-install-ext-arch pre-install-ext-comm\ndo-install-ext:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=ext\npost-install-ext:: post-install-ext-arch post-install-ext-comm\n\ninstall-arch: pre-install-arch do-install-arch post-install-arch\npre-install-arch:: pre-install-bin pre-install-ext-arch\ndo-install-arch:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=bin --install=ext-arch\npost-install-arch:: post-install-bin post-install-ext-arch\n\ninstall-comm: pre-install-comm do-install-comm post-install-comm\npre-install-comm:: pre-install-lib pre-install-ext-comm pre-install-man\ndo-install-comm:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=lib --install=ext-comm --install=man\npost-install-comm:: post-install-lib post-install-ext-comm post-install-man\n\ninstall-bin: pre-install-bin do-install-bin post-install-bin\npre-install-bin:: install-prereq\ndo-install-bin:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=bin\npost-install-bin::\n\t@$(NULLCMD)\n\ninstall-lib: pre-install-lib do-install-lib post-install-lib\npre-install-lib:: install-prereq\ndo-install-lib:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=lib\npost-install-lib::\n\t@$(NULLCMD)\n\ninstall-ext-comm: pre-install-ext-comm do-install-ext-comm post-install-ext-comm\npre-install-ext-comm:: install-prereq\ndo-install-ext-comm:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=ext-comm\npost-install-ext-comm::\n\t@$(NULLCMD)\n\ninstall-ext-arch: pre-install-ext-arch do-install-ext-arch post-install-ext-arch\npre-install-ext-arch:: install-prereq\ndo-install-ext-arch:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=ext-arch\npost-install-ext-arch::\n\t@$(NULLCMD)\n\ninstall-man: pre-install-man do-install-man post-install-man\npre-install-man:: install-prereq\ndo-install-man:\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=man --mantype=\"$(MANTYPE)\"\npost-install-man::\n\t@$(NULLCMD)\n\nwhat-where: no-install\nno-install: no-install-nodoc no-install-doc\nwhat-where-all: no-install-all\nno-install-all: no-install-nodoc\n\nwhat-where-nodoc: no-install-nodoc\nno-install-nodoc: pre-no-install-nodoc dont-install-nodoc post-no-install-nodoc\npre-no-install-nodoc:: pre-no-install-local pre-no-install-ext\ndont-install-nodoc:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --mantype=\"$(MANTYPE)\"\npost-no-install-nodoc:: post-no-install-local post-no-install-ext\n\nwhat-where-local: no-install-local\nno-install-local: pre-no-install-local dont-install-local post-no-install-local\npre-no-install-local:: pre-no-install-bin pre-no-install-lib pre-no-install-man\ndont-install-local:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=local --mantype=\"$(MANTYPE)\"\npost-no-install-local:: post-no-install-bin post-no-install-lib post-no-install-man\n\nwhat-where-ext: no-install-ext\nno-install-ext: pre-no-install-ext dont-install-ext post-no-install-ext\npre-no-install-ext:: pre-no-install-ext-arch pre-no-install-ext-comm\ndont-install-ext:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=ext\npost-no-install-ext:: post-no-install-ext-arch post-no-install-ext-comm\n\nwhat-where-arch: no-install-arch\nno-install-arch: pre-no-install-arch dont-install-arch post-no-install-arch\npre-no-install-arch:: pre-no-install-bin pre-no-install-ext-arch\ndont-install-arch:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=bin --install=ext-arch\npost-no-install-arch:: post-no-install-lib post-no-install-man post-no-install-ext-arch\n\nwhat-where-comm: no-install-comm\nno-install-comm: pre-no-install-comm dont-install-comm post-no-install-comm\npre-no-install-comm:: pre-no-install-lib pre-no-install-ext-comm pre-no-install-man\ndont-install-comm:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=lib --install=ext-comm --install=man\npost-no-install-comm:: post-no-install-lib post-no-install-ext-comm post-no-install-man\n\nwhat-where-bin: no-install-bin\nno-install-bin: pre-no-install-bin dont-install-bin post-no-install-bin\npre-no-install-bin:: install-prereq\ndont-install-bin:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=bin\npost-no-install-bin::\n\t@$(NULLCMD)\n\nwhat-where-lib: no-install-lib\nno-install-lib: pre-no-install-lib dont-install-lib post-no-install-lib\npre-no-install-lib:: install-prereq\ndont-install-lib:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=lib\npost-no-install-lib::\n\t@$(NULLCMD)\n\nwhat-where-ext-comm: no-install-ext-comm\nno-install-ext-comm: pre-no-install-ext-comm dont-install-ext-comm post-no-install-ext-comm\npre-no-install-ext-comm:: install-prereq\ndont-install-ext-comm:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=ext-comm\npost-no-install-ext-comm::\n\t@$(NULLCMD)\n\nwhat-where-ext-arch: no-install-ext-arch\nno-install-ext-arch: pre-no-install-ext-arch dont-install-ext-arch post-no-install-ext-arch\npre-no-install-ext-arch:: install-prereq\ndont-install-ext-arch:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=ext-arch\npost-no-install-ext-arch::\n\t@$(NULLCMD)\n\nwhat-where-man: no-install-man\nno-install-man: pre-no-install-man dont-install-man post-no-install-man\npre-no-install-man:: install-prereq\ndont-install-man:\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=man --mantype=\"$(MANTYPE)\"\npost-no-install-man::\n\t@$(NULLCMD)\n\ninstall-doc: rdoc pre-install-doc do-install-doc post-install-doc\npre-install-doc:: install-prereq\ndo-install-doc: $(PROGRAM)\n\t$(MINIRUBY) $(srcdir)/instruby.rb --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=rdoc --rdoc-output=\"$(RDOCOUT)\"\npost-install-doc::\n\t@$(NULLCMD)\n\nrdoc: $(PROGRAM) PHONY\n\t@echo Generating RDoc documentation\n\t$(RUNRUBY) \"$(srcdir)/bin/rdoc\" --all --ri --op \"$(RDOCOUT)\" \"$(srcdir)\"\n\nwhat-where-doc: no-install-doc\nno-install-doc: pre-no-install-doc dont-install-doc post-no-install-doc\npre-no-install-doc:: install-prereq\ndont-install-doc::\n\t$(MINIRUBY) $(srcdir)/instruby.rb -n --make=\"$(MAKE)\" $(INSTRUBY_ARGS) --install=rdoc --rdoc-output=\"$(RDOCOUT)\"\npost-no-install-doc::\n\t@$(NULLCMD)\n\nCLEAR_INSTALLED_LIST = clear-installed-list\n\ninstall-prereq: $(CLEAR_INSTALLED_LIST)\n\nclear-installed-list:\n\t@exit > $(INSTALLED_LIST)\n\nclean: clean-ext clean-local\nclean-local::\n\t@$(RM) $(OBJS) $(MINIOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES)\n\t@$(RM) $(PROGRAM) $(WPROGRAM) miniruby$(EXEEXT) dmyext.$(OBJEXT) $(ARCHFILE) .*.time\n\t@$(RM) y.tab.c y.output\nclean-ext:\n\t@-$(MINIRUBY) $(srcdir)/ext/extmk.rb --make=\"$(MAKE)\" $(EXTMK_ARGS) clean\n\ndistclean: distclean-ext distclean-local\ndistclean-local:: clean-local\n\t@$(RM) $(MKFILES) config.h rbconfig.rb\n\t@$(RM) config.cache config.log config.status\n\t@$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP)\ndistclean-ext:\n\t@-$(MINIRUBY) $(srcdir)/ext/extmk.rb --make=\"$(MAKE)\" $(EXTMK_ARGS) distclean\n\nrealclean:: realclean-ext realclean-local\nrealclean-local:: distclean-local\n\t@$(RM) parse.c lex.c\nrealclean-ext::\n\t@-$(MINIRUBY) $(srcdir)/ext/extmk.rb --make=\"$(MAKE)\" $(EXTMK_ARGS) realclean\n\ncheck: test test-all\n\ntest: miniruby$(EXEEXT) $(RBCONFIG) $(PROGRAM) PHONY\n\t@$(MINIRUBY) $(srcdir)/rubytest.rb\n\ntest-all:\n\t$(RUNRUBY) \"$(srcdir)/test/runner.rb\" --basedir=\"$(TESTSDIR)\" --runner=$(TESTUI) $(TESTS)\n\nextconf:\n\t$(MINIRUBY) -run -e mkdir -- -p \"$(EXTCONFDIR)\"\n\t$(RUNRUBY) -C \"$(EXTCONFDIR)\" $(EXTCONF) $(EXTCONFARGS)\n\n$(RBCONFIG): $(srcdir)/mkconfig.rb config.status $(PREP)\n\t@$(MINIRUBY) $(srcdir)/mkconfig.rb -timestamp=$@ \\\n\t\t-install_name=$(RUBY_INSTALL_NAME) \\\n\t\t-so_name=$(RUBY_SO_NAME) rbconfig.rb\n\n.PRECIOUS: $(MKFILES)\n\n.PHONY: test install install-nodoc install-doc dist\n\nPHONY:\n\n{$(VPATH)}parse.c: parse.y\n\nacosh.$(OBJEXT): {$(VPATH)}acosh.c\nalloca.$(OBJEXT): {$(VPATH)}alloca.c\ncrypt.$(OBJEXT): {$(VPATH)}crypt.c\ndup2.$(OBJEXT): {$(VPATH)}dup2.c\nerf.$(OBJEXT): {$(VPATH)}erf.c\nfinite.$(OBJEXT): {$(VPATH)}finite.c\nflock.$(OBJEXT): {$(VPATH)}flock.c\nmemcmp.$(OBJEXT): {$(VPATH)}memcmp.c\nmemmove.$(OBJEXT): {$(VPATH)}memmove.c\nmkdir.$(OBJEXT): {$(VPATH)}mkdir.c\nvsnprintf.$(OBJEXT): {$(VPATH)}vsnprintf.c\nstrcasecmp.$(OBJEXT): {$(VPATH)}strcasecmp.c\nstrncasecmp.$(OBJEXT): {$(VPATH)}strncasecmp.c\nstrchr.$(OBJEXT): {$(VPATH)}strchr.c\nstrdup.$(OBJEXT): {$(VPATH)}strdup.c\nstrerror.$(OBJEXT): {$(VPATH)}strerror.c\nstrftime.$(OBJEXT): {$(VPATH)}strftime.c\nstrstr.$(OBJEXT): {$(VPATH)}strstr.c\nstrtod.$(OBJEXT): {$(VPATH)}strtod.c\nstrtol.$(OBJEXT): {$(VPATH)}strtol.c\nstrtoul.$(OBJEXT): {$(VPATH)}strtoul.c\nnt.$(OBJEXT): {$(VPATH)}nt.c\nx68.$(OBJEXT): {$(VPATH)}x68.c\nos2.$(OBJEXT): {$(VPATH)}os2.c\ndl_os2.$(OBJEXT): {$(VPATH)}dl_os2.c\nia64.$(OBJEXT): {$(VPATH)}ia64.s\n\t$(CC) $(CFLAGS) -c $<\n\n# when I use -I., there is confliction at \"OpenFile\"\n# so, set . into environment varible \"include\"\nwin32.$(OBJEXT): {$(VPATH)}win32.c\n\n###\n\narray.$(OBJEXT): {$(VPATH)}array.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}util.h {$(VPATH)}st.h\nbignum.$(OBJEXT): {$(VPATH)}bignum.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubysig.h\nclass.$(OBJEXT): {$(VPATH)}class.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubysig.h {$(VPATH)}node.h {$(VPATH)}st.h\ncompar.$(OBJEXT): {$(VPATH)}compar.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\ndir.$(OBJEXT): {$(VPATH)}dir.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}util.h\ndln.$(OBJEXT): {$(VPATH)}dln.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}dln.h\ndmydln.$(OBJEXT): {$(VPATH)}dmydln.c dln.$(OBJEXT)\ndmyext.$(OBJEXT): {$(VPATH)}dmyext.c\nenum.$(OBJEXT): {$(VPATH)}enum.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}node.h {$(VPATH)}util.h\nenumerator.$(OBJEXT): {$(VPATH)}enumerator.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nerror.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}env.h {$(VPATH)}st.h\neval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}node.h {$(VPATH)}env.h {$(VPATH)}util.h \\\n  {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h\nfile.$(OBJEXT): {$(VPATH)}file.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubyio.h {$(VPATH)}rubysig.h {$(VPATH)}util.h \\\n  {$(VPATH)}dln.h\ngc.$(OBJEXT): {$(VPATH)}gc.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}node.h \\\n  {$(VPATH)}env.h {$(VPATH)}re.h {$(VPATH)}regex.h \\\n  {$(VPATH)}pointerset.h {$(VPATH)}marktable.h \\\n  {$(VPATH)}marktable.c\nhash.$(OBJEXT): {$(VPATH)}hash.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}st.h {$(VPATH)}util.h {$(VPATH)}rubysig.h\ninits.$(OBJEXT): {$(VPATH)}inits.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nio.$(OBJEXT): {$(VPATH)}io.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubyio.h {$(VPATH)}rubysig.h  {$(VPATH)}util.h \\\n  {$(VPATH)}env.h\nmain.$(OBJEXT): {$(VPATH)}main.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nmarshal.$(OBJEXT): {$(VPATH)}marshal.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubyio.h {$(VPATH)}st.h {$(VPATH)}util.h\nmath.$(OBJEXT): {$(VPATH)}math.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nnumeric.$(OBJEXT): {$(VPATH)}numeric.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}env.h {$(VPATH)}defines.h {$(VPATH)}intern.h \\\n  {$(VPATH)}missing.h\nobject.$(OBJEXT): {$(VPATH)}object.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}st.h {$(VPATH)}util.h\npack.$(OBJEXT): {$(VPATH)}pack.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nparse.$(OBJEXT): {$(VPATH)}parse.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}env.h {$(VPATH)}node.h {$(VPATH)}st.h \\\n  {$(VPATH)}regex.h {$(VPATH)}util.h {$(VPATH)}lex.c\npointerset.$(OBJEXT): {$(VPATH)}pointerset.c {$(VPATH)}pointerset.h\nprec.$(OBJEXT): {$(VPATH)}prec.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nprocess.$(OBJEXT): {$(VPATH)}process.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubysig.h {$(VPATH)}st.h\nrandom.$(OBJEXT): {$(VPATH)}random.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nrange.$(OBJEXT): {$(VPATH)}range.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nre.$(OBJEXT): {$(VPATH)}re.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}re.h {$(VPATH)}regex.h\nregex.$(OBJEXT): {$(VPATH)}regex.c config.h {$(VPATH)}regex.h\nruby.$(OBJEXT): {$(VPATH)}ruby.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}dln.h {$(VPATH)}node.h {$(VPATH)}util.h\nsignal.$(OBJEXT): {$(VPATH)}signal.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}rubysig.h\nsprintf.$(OBJEXT): {$(VPATH)}sprintf.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nst.$(OBJEXT): {$(VPATH)}st.c config.h {$(VPATH)}st.h\nstring.$(OBJEXT): {$(VPATH)}string.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}re.h {$(VPATH)}regex.h\nstruct.$(OBJEXT): {$(VPATH)}struct.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\ntime.$(OBJEXT): {$(VPATH)}time.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h\nutil.$(OBJEXT): {$(VPATH)}util.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}util.h\nvariable.$(OBJEXT): {$(VPATH)}variable.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}env.h {$(VPATH)}node.h {$(VPATH)}st.h {$(VPATH)}util.h\nversion.$(OBJEXT): {$(VPATH)}version.c {$(VPATH)}ruby.h config.h \\\n  {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \\\n  {$(VPATH)}version.h\n\ndist: $(PROGRAM)\n\t$(RUNRUBY) $(srcdir)/distruby.rb\n"
  },
  {
    "path": "compar.c",
    "content": "/**********************************************************************\n\n  compar.c -\n\n  $Author$\n  $Date$\n  created at: Thu Aug 26 14:39:48 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\nVALUE rb_mComparable;\n\nstatic ID cmp;\n\nint\nrb_cmpint(val, a, b)\n    VALUE val, a, b;\n{\n    if (NIL_P(val)) {\n\trb_cmperr(a, b);\n    }\n    if (FIXNUM_P(val)) return FIX2INT(val);\n    if (TYPE(val) == T_BIGNUM) {\n\tif (RBIGNUM(val)->sign) return 1;\n\treturn -1;\n    }\n    if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;\n    if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;\n    return 0;\n}\n\nvoid\nrb_cmperr(x, y)\n    VALUE x, y;\n{\n    const char *classname;\n\n    if (SPECIAL_CONST_P(y)) {\n\ty = rb_inspect(y);\n\tclassname = StringValuePtr(y);\n    }\n    else {\n\tclassname = rb_obj_classname(y);\n    }\n    rb_raise(rb_eArgError, \"comparison of %s with %s failed\",\n\t     rb_obj_classname(x), classname);\n}\n\n#define cmperr() (rb_cmperr(x, y), Qnil)\n\nstatic VALUE\ncmp_eq(a)\n    VALUE *a;\n{\n    VALUE c = rb_funcall(a[0], cmp, 1, a[1]);\n\n    if (NIL_P(c)) return Qnil;\n    if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\ncmp_failed()\n{\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     obj == other    => true or false\n *  \n *  Compares two objects based on the receiver's <code><=></code>\n *  method, returning true if it returns 0. Also returns true if\n *  _obj_ and _other_ are the same object.\n */\n\nstatic VALUE\ncmp_equal(x, y)\n    VALUE x, y;\n{\n    VALUE a[2];\n\n    if (x == y) return Qtrue;\n\n    a[0] = x; a[1] = y;\n    return rb_rescue(cmp_eq, (VALUE)a, cmp_failed, 0);\n}\n\n/*\n *  call-seq:\n *     obj > other    => true or false\n *  \n *  Compares two objects based on the receiver's <code><=></code>\n *  method, returning true if it returns 1.\n */\n\nstatic VALUE\ncmp_gt(x, y)\n    VALUE x, y;\n{\n    VALUE c = rb_funcall(x, cmp, 1, y);\n\n    if (NIL_P(c)) return cmperr();\n    if (rb_cmpint(c, x, y) > 0) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj >= other    => true or false\n *  \n *  Compares two objects based on the receiver's <code><=></code>\n *  method, returning true if it returns 0 or 1.\n */\n\nstatic VALUE\ncmp_ge(x, y)\n    VALUE x, y;\n{\n    VALUE c = rb_funcall(x, cmp, 1, y);\n\n    if (NIL_P(c)) return cmperr();\n    if (rb_cmpint(c, x, y) >= 0) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj < other    => true or false\n *  \n *  Compares two objects based on the receiver's <code><=></code>\n *  method, returning true if it returns -1.\n */\n\nstatic VALUE\ncmp_lt(x, y)\n    VALUE x, y;\n{\n    VALUE c = rb_funcall(x, cmp, 1, y);\n\n    if (NIL_P(c)) return cmperr();\n    if (rb_cmpint(c, x, y) < 0) return Qtrue;\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     obj <= other    => true or false\n *  \n *  Compares two objects based on the receiver's <code><=></code>\n *  method, returning true if it returns -1 or 0.\n */\n\nstatic VALUE\ncmp_le(x, y)\n    VALUE x, y;\n{\n    VALUE c = rb_funcall(x, cmp, 1, y);\n\n    if (NIL_P(c)) return cmperr();\n    if (rb_cmpint(c, x, y) <= 0) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj.between?(min, max)    => true or false\n *  \n *  Returns <code>false</code> if <i>obj</i> <code><=></code>\n *  <i>min</i> is less than zero or if <i>anObject</i> <code><=></code>\n *  <i>max</i> is greater than zero, <code>true</code> otherwise.\n *     \n *     3.between?(1, 5)               #=> true\n *     6.between?(1, 5)               #=> false\n *     'cat'.between?('ant', 'dog')   #=> true\n *     'gnu'.between?('ant', 'dog')   #=> false\n *     \n */\n\nstatic VALUE\ncmp_between(x, min, max)\n    VALUE x, min, max;\n{\n    if (RTEST(cmp_lt(x, min))) return Qfalse;\n    if (RTEST(cmp_gt(x, max))) return Qfalse;\n    return Qtrue;\n}\n\n/*\n *  The <code>Comparable</code> mixin is used by classes whose objects\n *  may be ordered. The class must define the <code><=></code> operator,\n *  which compares the receiver against another object, returning -1, 0,\n *  or +1 depending on whether the receiver is less than, equal to, or\n *  greater than the other object. <code>Comparable</code> uses\n *  <code><=></code> to implement the conventional comparison operators\n *  (<code><</code>, <code><=</code>, <code>==</code>, <code>>=</code>,\n *  and <code>></code>) and the method <code>between?</code>.\n *     \n *     class SizeMatters\n *       include Comparable\n *       attr :str\n *       def <=>(anOther)\n *         str.size <=> anOther.str.size\n *       end\n *       def initialize(str)\n *         @str = str\n *       end\n *       def inspect\n *         @str\n *       end\n *     end\n *     \n *     s1 = SizeMatters.new(\"Z\")\n *     s2 = SizeMatters.new(\"YY\")\n *     s3 = SizeMatters.new(\"XXX\")\n *     s4 = SizeMatters.new(\"WWWW\")\n *     s5 = SizeMatters.new(\"VVVVV\")\n *     \n *     s1 < s2                       #=> true\n *     s4.between?(s1, s3)           #=> false\n *     s4.between?(s3, s5)           #=> true\n *     [ s3, s2, s5, s4, s1 ].sort   #=> [Z, YY, XXX, WWWW, VVVVV]\n *     \n */\n\nvoid\nInit_Comparable()\n{\n    rb_mComparable = rb_define_module(\"Comparable\");\n    rb_define_method(rb_mComparable, \"==\", cmp_equal, 1);\n    rb_define_method(rb_mComparable, \">\", cmp_gt, 1);\n    rb_define_method(rb_mComparable, \">=\", cmp_ge, 1);\n    rb_define_method(rb_mComparable, \"<\", cmp_lt, 1);\n    rb_define_method(rb_mComparable, \"<=\", cmp_le, 1);\n    rb_define_method(rb_mComparable, \"between?\", cmp_between, 2);\n\n    cmp = rb_intern(\"<=>\");\n}\n"
  },
  {
    "path": "config.guess",
    "content": "#! /bin/sh\n# Attempt to guess a canonical system name.\n#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,\n#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.\n\ntimestamp='2004-06-11'\n\n# This file is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n#\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n# Originally written by Per Bothner <per@bothner.com>.\n# Please send patches to <config-patches@gnu.org>.  Submit a context\n# diff and a properly formatted ChangeLog entry.\n#\n# This script attempts to guess a canonical system name similar to\n# config.sub.  If it succeeds, it prints the system name on stdout, and\n# exits with 0.  Otherwise, it exits with 1.\n#\n# The plan is that this can be called by configure scripts if you\n# don't specify an explicit build system type.\n\nme=`echo \"$0\" | sed -e 's,.*/,,'`\n\nusage=\"\\\nUsage: $0 [OPTION]\n\nOutput the configuration name of the system \\`$me' is run on.\n\nOperation modes:\n  -h, --help         print this help, then exit\n  -t, --time-stamp   print date of last modification, then exit\n  -v, --version      print version number, then exit\n\nReport bugs and patches to <config-patches@gnu.org>.\"\n\nversion=\"\\\nGNU config.guess ($timestamp)\n\nOriginally written by Per Bothner.\nCopyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001\nFree Software Foundation, Inc.\n\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\"\n\nhelp=\"\nTry \\`$me --help' for more information.\"\n\n# Parse command line\nwhile test $# -gt 0 ; do\n  case $1 in\n    --time-stamp | --time* | -t )\n       echo \"$timestamp\" ; exit 0 ;;\n    --version | -v )\n       echo \"$version\" ; exit 0 ;;\n    --help | --h* | -h )\n       echo \"$usage\"; exit 0 ;;\n    -- )     # Stop option processing\n       shift; break ;;\n    - )\t# Use stdin as input.\n       break ;;\n    -* )\n       echo \"$me: invalid option $1$help\" >&2\n       exit 1 ;;\n    * )\n       break ;;\n  esac\ndone\n\nif test $# != 0; then\n  echo \"$me: too many arguments$help\" >&2\n  exit 1\nfi\n\ntrap 'exit 1' 1 2 15\n\n# CC_FOR_BUILD -- compiler used by this script. Note that the use of a\n# compiler to aid in system detection is discouraged as it requires\n# temporary files to be created and, as you can see below, it is a\n# headache to deal with in a portable fashion.\n\n# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still\n# use `HOST_CC' if defined, but it is deprecated.\n\n# Portable tmp directory creation inspired by the Autoconf team.\n\nset_cc_for_build='\ntrap \"exitcode=\\$?; (rm -f \\$tmpfiles 2>/dev/null; rmdir \\$tmp 2>/dev/null) && exit \\$exitcode\" 0 ;\ntrap \"rm -f \\$tmpfiles 2>/dev/null; rmdir \\$tmp 2>/dev/null; exit 1\" 1 2 13 15 ;\n: ${TMPDIR=/tmp} ;\n { tmp=`(umask 077 && mktemp -d -q \"$TMPDIR/cgXXXXXX\") 2>/dev/null` && test -n \"$tmp\" && test -d \"$tmp\" ; } ||\n { test -n \"$RANDOM\" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||\n { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo \"Warning: creating insecure temp directory\" >&2 ; } ||\n { echo \"$me: cannot create a temporary directory in $TMPDIR\" >&2 ; exit 1 ; } ;\ndummy=$tmp/dummy ;\ntmpfiles=\"$dummy.c $dummy.o $dummy.rel $dummy\" ;\ncase $CC_FOR_BUILD,$HOST_CC,$CC in\n ,,)    echo \"int x;\" > $dummy.c ;\n\tfor c in cc gcc c89 c99 ; do\n\t  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then\n\t     CC_FOR_BUILD=\"$c\"; break ;\n\t  fi ;\n\tdone ;\n\tif test x\"$CC_FOR_BUILD\" = x ; then\n\t  CC_FOR_BUILD=no_compiler_found ;\n\tfi\n\t;;\n ,,*)   CC_FOR_BUILD=$CC ;;\n ,*,*)  CC_FOR_BUILD=$HOST_CC ;;\nesac ;'\n\n# This is needed to find uname on a Pyramid OSx when run in the BSD universe.\n# (ghazi@noc.rutgers.edu 1994-08-24)\nif (test -f /.attbin/uname) >/dev/null 2>&1 ; then\n\tPATH=$PATH:/.attbin ; export PATH\nfi\n\nUNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown\nUNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown\nUNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown\nUNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown\n\n# Note: order is significant - the case branches are not exclusive.\n\ncase \"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}\" in\n    *:NetBSD:*:*)\n\t# NetBSD (nbsd) targets should (where applicable) match one or\n\t# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,\n\t# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently\n\t# switched to ELF, *-*-netbsd* would select the old\n\t# object file format.  This provides both forward\n\t# compatibility and a consistent mechanism for selecting the\n\t# object file format.\n\t#\n\t# Note: NetBSD doesn't particularly care about the vendor\n\t# portion of the name.  We always set it to \"unknown\".\n\tsysctl=\"sysctl -n hw.machine_arch\"\n\tUNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \\\n\t    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`\n\tcase \"${UNAME_MACHINE_ARCH}\" in\n\t    armeb) machine=armeb-unknown ;;\n\t    arm*) machine=arm-unknown ;;\n\t    sh3el) machine=shl-unknown ;;\n\t    sh3eb) machine=sh-unknown ;;\n\t    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;\n\tesac\n\t# The Operating System including object format, if it has switched\n\t# to ELF recently, or will in the future.\n\tcase \"${UNAME_MACHINE_ARCH}\" in\n\t    arm*|i386|m68k|ns32k|sh3*|sparc|vax)\n\t\teval $set_cc_for_build\n\t\tif echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t\t\t| grep __ELF__ >/dev/null\n\t\tthen\n\t\t    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).\n\t\t    # Return netbsd for either.  FIX?\n\t\t    os=netbsd\n\t\telse\n\t\t    os=netbsdelf\n\t\tfi\n\t\t;;\n\t    *)\n\t        os=netbsd\n\t\t;;\n\tesac\n\t# The OS release\n\t# Debian GNU/NetBSD machines have a different userland, and\n\t# thus, need a distinct triplet. However, they do not need\n\t# kernel version information, so it can be replaced with a\n\t# suitable tag, in the style of linux-gnu.\n\tcase \"${UNAME_VERSION}\" in\n\t    Debian*)\n\t\trelease='-gnu'\n\t\t;;\n\t    *)\n\t\trelease=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\\./'`\n\t\t;;\n\tesac\n\t# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:\n\t# contains redundant information, the shorter form:\n\t# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.\n\techo \"${machine}-${os}${release}\"\n\texit 0 ;;\n    amd64:OpenBSD:*:*)\n\techo x86_64-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    amiga:OpenBSD:*:*)\n\techo m68k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    arc:OpenBSD:*:*)\n\techo mipsel-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    cats:OpenBSD:*:*)\n\techo arm-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    hp300:OpenBSD:*:*)\n\techo m68k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    luna88k:OpenBSD:*:*)\n    \techo m88k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    mac68k:OpenBSD:*:*)\n\techo m68k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    macppc:OpenBSD:*:*)\n\techo powerpc-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    mvme68k:OpenBSD:*:*)\n\techo m68k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    mvme88k:OpenBSD:*:*)\n\techo m88k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    mvmeppc:OpenBSD:*:*)\n\techo powerpc-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    pmax:OpenBSD:*:*)\n\techo mipsel-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    sgi:OpenBSD:*:*)\n\techo mipseb-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    sun3:OpenBSD:*:*)\n\techo m68k-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    wgrisc:OpenBSD:*:*)\n\techo mipsel-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    *:OpenBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}\n\texit 0 ;;\n    *:ekkoBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}\n\texit 0 ;;\n    macppc:MirBSD:*:*)\n\techo powerppc-unknown-mirbsd${UNAME_RELEASE}\n\texit 0 ;;\n    *:MirBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}\n\texit 0 ;;\n    alpha:OSF1:*:*)\n\tcase $UNAME_RELEASE in\n\t*4.0)\n\t\tUNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`\n\t\t;;\n\t*5.*)\n\t        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`\n\t\t;;\n\tesac\n\t# According to Compaq, /usr/sbin/psrinfo has been available on\n\t# OSF/1 and Tru64 systems produced since 1995.  I hope that\n\t# covers most systems running today.  This code pipes the CPU\n\t# types through head -n 1, so we only detect the type of CPU 0.\n\tALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \\(.*\\) processor.*$/\\1/p' | head -n 1`\n\tcase \"$ALPHA_CPU_TYPE\" in\n\t    \"EV4 (21064)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"EV4.5 (21064)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"LCA4 (21066/21068)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"EV5 (21164)\")\n\t\tUNAME_MACHINE=\"alphaev5\" ;;\n\t    \"EV5.6 (21164A)\")\n\t\tUNAME_MACHINE=\"alphaev56\" ;;\n\t    \"EV5.6 (21164PC)\")\n\t\tUNAME_MACHINE=\"alphapca56\" ;;\n\t    \"EV5.7 (21164PC)\")\n\t\tUNAME_MACHINE=\"alphapca57\" ;;\n\t    \"EV6 (21264)\")\n\t\tUNAME_MACHINE=\"alphaev6\" ;;\n\t    \"EV6.7 (21264A)\")\n\t\tUNAME_MACHINE=\"alphaev67\" ;;\n\t    \"EV6.8CB (21264C)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.8AL (21264B)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.8CX (21264D)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.9A (21264/EV69A)\")\n\t\tUNAME_MACHINE=\"alphaev69\" ;;\n\t    \"EV7 (21364)\")\n\t\tUNAME_MACHINE=\"alphaev7\" ;;\n\t    \"EV7.9 (21364A)\")\n\t\tUNAME_MACHINE=\"alphaev79\" ;;\n\tesac\n\t# A Pn.n version is a patched version.\n\t# A Vn.n version is a released version.\n\t# A Tn.n version is a released field test version.\n\t# A Xn.n version is an unreleased experimental baselevel.\n\t# 1.2 uses \"1.2\" for uname -r.\n\techo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`\n\texit 0 ;;\n    Alpha*:OpenVMS:*:*)\n\techo alpha-hp-vms\n\texit 0 ;;\n    Alpha\\ *:Windows_NT*:*)\n\t# How do we know it's Interix rather than the generic POSIX subsystem?\n\t# Should we change UNAME_MACHINE based on the output of uname instead\n\t# of the specific Alpha model?\n\techo alpha-pc-interix\n\texit 0 ;;\n    21064:Windows_NT:50:3)\n\techo alpha-dec-winnt3.5\n\texit 0 ;;\n    Amiga*:UNIX_System_V:4.0:*)\n\techo m68k-unknown-sysv4\n\texit 0;;\n    *:[Aa]miga[Oo][Ss]:*:*)\n\techo ${UNAME_MACHINE}-unknown-amigaos\n\texit 0 ;;\n    *:[Mm]orph[Oo][Ss]:*:*)\n\techo ${UNAME_MACHINE}-unknown-morphos\n\texit 0 ;;\n    *:OS/390:*:*)\n\techo i370-ibm-openedition\n\texit 0 ;;\n    *:OS400:*:*)\n        echo powerpc-ibm-os400\n\texit 0 ;;\n    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)\n\techo arm-acorn-riscix${UNAME_RELEASE}\n\texit 0;;\n    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)\n\techo hppa1.1-hitachi-hiuxmpp\n\texit 0;;\n    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)\n\t# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.\n\tif test \"`(/bin/universe) 2>/dev/null`\" = att ; then\n\t\techo pyramid-pyramid-sysv3\n\telse\n\t\techo pyramid-pyramid-bsd\n\tfi\n\texit 0 ;;\n    NILE*:*:*:dcosx)\n\techo pyramid-pyramid-svr4\n\texit 0 ;;\n    DRS?6000:unix:4.0:6*)\n\techo sparc-icl-nx6\n\texit 0 ;;\n    DRS?6000:UNIX_SV:4.2*:7*)\n\tcase `/usr/bin/uname -p` in\n\t    sparc) echo sparc-icl-nx7 && exit 0 ;;\n\tesac ;;\n    sun4H:SunOS:5.*:*)\n\techo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit 0 ;;\n    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)\n\techo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit 0 ;;\n    i86pc:SunOS:5.*:*)\n\techo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit 0 ;;\n    sun4*:SunOS:6*:*)\n\t# According to config.sub, this is the proper way to canonicalize\n\t# SunOS6.  Hard to guess exactly what SunOS6 will be like, but\n\t# it's likely to be more like Solaris than SunOS4.\n\techo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit 0 ;;\n    sun4*:SunOS:*:*)\n\tcase \"`/usr/bin/arch -k`\" in\n\t    Series*|S4*)\n\t\tUNAME_RELEASE=`uname -v`\n\t\t;;\n\tesac\n\t# Japanese Language versions have a version number like `4.1.3-JL'.\n\techo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`\n\texit 0 ;;\n    sun3*:SunOS:*:*)\n\techo m68k-sun-sunos${UNAME_RELEASE}\n\texit 0 ;;\n    sun*:*:4.2BSD:*)\n\tUNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`\n\ttest \"x${UNAME_RELEASE}\" = \"x\" && UNAME_RELEASE=3\n\tcase \"`/bin/arch`\" in\n\t    sun3)\n\t\techo m68k-sun-sunos${UNAME_RELEASE}\n\t\t;;\n\t    sun4)\n\t\techo sparc-sun-sunos${UNAME_RELEASE}\n\t\t;;\n\tesac\n\texit 0 ;;\n    aushp:SunOS:*:*)\n\techo sparc-auspex-sunos${UNAME_RELEASE}\n\texit 0 ;;\n    # The situation for MiNT is a little confusing.  The machine name\n    # can be virtually everything (everything which is not\n    # \"atarist\" or \"atariste\" at least should have a processor\n    # > m68000).  The system name ranges from \"MiNT\" over \"FreeMiNT\"\n    # to the lowercase version \"mint\" (or \"freemint\").  Finally\n    # the system name \"TOS\" denotes a system which is actually not\n    # MiNT.  But MiNT is downward compatible to TOS, so this should\n    # be no problem.\n    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)\n        echo m68k-atari-mint${UNAME_RELEASE}\n\texit 0 ;;\n    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n        exit 0 ;;\n    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)\n        echo m68k-atari-mint${UNAME_RELEASE}\n\texit 0 ;;\n    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)\n        echo m68k-milan-mint${UNAME_RELEASE}\n        exit 0 ;;\n    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)\n        echo m68k-hades-mint${UNAME_RELEASE}\n        exit 0 ;;\n    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)\n        echo m68k-unknown-mint${UNAME_RELEASE}\n        exit 0 ;;\n    m68k:machten:*:*)\n\techo m68k-apple-machten${UNAME_RELEASE}\n\texit 0 ;;\n    powerpc:machten:*:*)\n\techo powerpc-apple-machten${UNAME_RELEASE}\n\texit 0 ;;\n    RISC*:Mach:*:*)\n\techo mips-dec-mach_bsd4.3\n\texit 0 ;;\n    RISC*:ULTRIX:*:*)\n\techo mips-dec-ultrix${UNAME_RELEASE}\n\texit 0 ;;\n    VAX*:ULTRIX*:*:*)\n\techo vax-dec-ultrix${UNAME_RELEASE}\n\texit 0 ;;\n    2020:CLIX:*:* | 2430:CLIX:*:*)\n\techo clipper-intergraph-clix${UNAME_RELEASE}\n\texit 0 ;;\n    mips:*:*:UMIPS | mips:*:*:RISCos)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n#ifdef __cplusplus\n#include <stdio.h>  /* for printf() prototype */\n\tint main (int argc, char *argv[]) {\n#else\n\tint main (argc, argv) int argc; char *argv[]; {\n#endif\n\t#if defined (host_mips) && defined (MIPSEB)\n\t#if defined (SYSTYPE_SYSV)\n\t  printf (\"mips-mips-riscos%ssysv\\n\", argv[1]); exit (0);\n\t#endif\n\t#if defined (SYSTYPE_SVR4)\n\t  printf (\"mips-mips-riscos%ssvr4\\n\", argv[1]); exit (0);\n\t#endif\n\t#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)\n\t  printf (\"mips-mips-riscos%sbsd\\n\", argv[1]); exit (0);\n\t#endif\n\t#endif\n\t  exit (-1);\n\t}\nEOF\n\t$CC_FOR_BUILD -o $dummy $dummy.c \\\n\t  && $dummy `echo \"${UNAME_RELEASE}\" | sed -n 's/\\([0-9]*\\).*/\\1/p'` \\\n\t  && exit 0\n\techo mips-mips-riscos${UNAME_RELEASE}\n\texit 0 ;;\n    Motorola:PowerMAX_OS:*:*)\n\techo powerpc-motorola-powermax\n\texit 0 ;;\n    Motorola:*:4.3:PL8-*)\n\techo powerpc-harris-powermax\n\texit 0 ;;\n    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)\n\techo powerpc-harris-powermax\n\texit 0 ;;\n    Night_Hawk:Power_UNIX:*:*)\n\techo powerpc-harris-powerunix\n\texit 0 ;;\n    m88k:CX/UX:7*:*)\n\techo m88k-harris-cxux7\n\texit 0 ;;\n    m88k:*:4*:R4*)\n\techo m88k-motorola-sysv4\n\texit 0 ;;\n    m88k:*:3*:R3*)\n\techo m88k-motorola-sysv3\n\texit 0 ;;\n    AViiON:dgux:*:*)\n        # DG/UX returns AViiON for all architectures\n        UNAME_PROCESSOR=`/usr/bin/uname -p`\n\tif [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]\n\tthen\n\t    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \\\n\t       [ ${TARGET_BINARY_INTERFACE}x = x ]\n\t    then\n\t\techo m88k-dg-dgux${UNAME_RELEASE}\n\t    else\n\t\techo m88k-dg-dguxbcs${UNAME_RELEASE}\n\t    fi\n\telse\n\t    echo i586-dg-dgux${UNAME_RELEASE}\n\tfi\n \texit 0 ;;\n    M88*:DolphinOS:*:*)\t# DolphinOS (SVR3)\n\techo m88k-dolphin-sysv3\n\texit 0 ;;\n    M88*:*:R3*:*)\n\t# Delta 88k system running SVR3\n\techo m88k-motorola-sysv3\n\texit 0 ;;\n    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)\n\techo m88k-tektronix-sysv3\n\texit 0 ;;\n    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)\n\techo m68k-tektronix-bsd\n\texit 0 ;;\n    *:IRIX*:*:*)\n\techo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`\n\texit 0 ;;\n    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.\n\techo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id\n\texit 0 ;;              # Note that: echo \"'`uname -s`'\" gives 'AIX '\n    i*86:AIX:*:*)\n\techo i386-ibm-aix\n\texit 0 ;;\n    ia64:AIX:*:*)\n\tif [ -x /usr/bin/oslevel ] ; then\n\t\tIBM_REV=`/usr/bin/oslevel`\n\telse\n\t\tIBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}\n\tfi\n\techo ${UNAME_MACHINE}-ibm-aix${IBM_REV}\n\texit 0 ;;\n    *:AIX:2:3)\n\tif grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then\n\t\teval $set_cc_for_build\n\t\tsed 's/^\t\t//' << EOF >$dummy.c\n\t\t#include <sys/systemcfg.h>\n\n\t\tmain()\n\t\t\t{\n\t\t\tif (!__power_pc())\n\t\t\t\texit(1);\n\t\t\tputs(\"powerpc-ibm-aix3.2.5\");\n\t\t\texit(0);\n\t\t\t}\nEOF\n\t\t$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0\n\t\techo rs6000-ibm-aix3.2.5\n\telif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then\n\t\techo rs6000-ibm-aix3.2.4\n\telse\n\t\techo rs6000-ibm-aix3.2\n\tfi\n\texit 0 ;;\n    *:AIX:*:[45])\n\tIBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`\n\tif /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then\n\t\tIBM_ARCH=rs6000\n\telse\n\t\tIBM_ARCH=powerpc\n\tfi\n\tif [ -x /usr/bin/oslevel ] ; then\n\t\tIBM_REV=`/usr/bin/oslevel`\n\telse\n\t\tIBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}\n\tfi\n\techo ${IBM_ARCH}-ibm-aix${IBM_REV}\n\texit 0 ;;\n    *:AIX:*:*)\n\techo rs6000-ibm-aix\n\texit 0 ;;\n    ibmrt:4.4BSD:*|romp-ibm:BSD:*)\n\techo romp-ibm-bsd4.4\n\texit 0 ;;\n    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and\n\techo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to\n\texit 0 ;;                           # report: romp-ibm BSD 4.3\n    *:BOSX:*:*)\n\techo rs6000-bull-bosx\n\texit 0 ;;\n    DPX/2?00:B.O.S.:*:*)\n\techo m68k-bull-sysv3\n\texit 0 ;;\n    9000/[34]??:4.3bsd:1.*:*)\n\techo m68k-hp-bsd\n\texit 0 ;;\n    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)\n\techo m68k-hp-bsd4.4\n\texit 0 ;;\n    9000/[34678]??:HP-UX:*:*)\n\tHPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`\n\tcase \"${UNAME_MACHINE}\" in\n\t    9000/31? )            HP_ARCH=m68000 ;;\n\t    9000/[34]?? )         HP_ARCH=m68k ;;\n\t    9000/[678][0-9][0-9])\n\t\tif [ -x /usr/bin/getconf ]; then\n\t\t    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`\n                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`\n                    case \"${sc_cpu_version}\" in\n                      523) HP_ARCH=\"hppa1.0\" ;; # CPU_PA_RISC1_0\n                      528) HP_ARCH=\"hppa1.1\" ;; # CPU_PA_RISC1_1\n                      532)                      # CPU_PA_RISC2_0\n                        case \"${sc_kernel_bits}\" in\n                          32) HP_ARCH=\"hppa2.0n\" ;;\n                          64) HP_ARCH=\"hppa2.0w\" ;;\n\t\t\t  '') HP_ARCH=\"hppa2.0\" ;;   # HP-UX 10.20\n                        esac ;;\n                    esac\n\t\tfi\n\t\tif [ \"${HP_ARCH}\" = \"\" ]; then\n\t\t    eval $set_cc_for_build\n\t\t    sed 's/^              //' << EOF >$dummy.c\n\n              #define _HPUX_SOURCE\n              #include <stdlib.h>\n              #include <unistd.h>\n\n              int main ()\n              {\n              #if defined(_SC_KERNEL_BITS)\n                  long bits = sysconf(_SC_KERNEL_BITS);\n              #endif\n                  long cpu  = sysconf (_SC_CPU_VERSION);\n\n                  switch (cpu)\n              \t{\n              \tcase CPU_PA_RISC1_0: puts (\"hppa1.0\"); break;\n              \tcase CPU_PA_RISC1_1: puts (\"hppa1.1\"); break;\n              \tcase CPU_PA_RISC2_0:\n              #if defined(_SC_KERNEL_BITS)\n              \t    switch (bits)\n              \t\t{\n              \t\tcase 64: puts (\"hppa2.0w\"); break;\n              \t\tcase 32: puts (\"hppa2.0n\"); break;\n              \t\tdefault: puts (\"hppa2.0\"); break;\n              \t\t} break;\n              #else  /* !defined(_SC_KERNEL_BITS) */\n              \t    puts (\"hppa2.0\"); break;\n              #endif\n              \tdefault: puts (\"hppa1.0\"); break;\n              \t}\n                  exit (0);\n              }\nEOF\n\t\t    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`\n\t\t    test -z \"$HP_ARCH\" && HP_ARCH=hppa\n\t\tfi ;;\n\tesac\n\tif [ ${HP_ARCH} = \"hppa2.0w\" ]\n\tthen\n\t    # avoid double evaluation of $set_cc_for_build\n\t    test -n \"$CC_FOR_BUILD\" || eval $set_cc_for_build\n\t    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null\n\t    then\n\t\tHP_ARCH=\"hppa2.0w\"\n\t    else\n\t\tHP_ARCH=\"hppa64\"\n\t    fi\n\tfi\n\techo ${HP_ARCH}-hp-hpux${HPUX_REV}\n\texit 0 ;;\n    ia64:HP-UX:*:*)\n\tHPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`\n\techo ia64-hp-hpux${HPUX_REV}\n\texit 0 ;;\n    3050*:HI-UX:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#include <unistd.h>\n\tint\n\tmain ()\n\t{\n\t  long cpu = sysconf (_SC_CPU_VERSION);\n\t  /* The order matters, because CPU_IS_HP_MC68K erroneously returns\n\t     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct\n\t     results, however.  */\n\t  if (CPU_IS_PA_RISC (cpu))\n\t    {\n\t      switch (cpu)\n\t\t{\n\t\t  case CPU_PA_RISC1_0: puts (\"hppa1.0-hitachi-hiuxwe2\"); break;\n\t\t  case CPU_PA_RISC1_1: puts (\"hppa1.1-hitachi-hiuxwe2\"); break;\n\t\t  case CPU_PA_RISC2_0: puts (\"hppa2.0-hitachi-hiuxwe2\"); break;\n\t\t  default: puts (\"hppa-hitachi-hiuxwe2\"); break;\n\t\t}\n\t    }\n\t  else if (CPU_IS_HP_MC68K (cpu))\n\t    puts (\"m68k-hitachi-hiuxwe2\");\n\t  else puts (\"unknown-hitachi-hiuxwe2\");\n\t  exit (0);\n\t}\nEOF\n\t$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0\n\techo unknown-hitachi-hiuxwe2\n\texit 0 ;;\n    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )\n\techo hppa1.1-hp-bsd\n\texit 0 ;;\n    9000/8??:4.3bsd:*:*)\n\techo hppa1.0-hp-bsd\n\texit 0 ;;\n    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)\n\techo hppa1.0-hp-mpeix\n\texit 0 ;;\n    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )\n\techo hppa1.1-hp-osf\n\texit 0 ;;\n    hp8??:OSF1:*:*)\n\techo hppa1.0-hp-osf\n\texit 0 ;;\n    i*86:OSF1:*:*)\n\tif [ -x /usr/sbin/sysversion ] ; then\n\t    echo ${UNAME_MACHINE}-unknown-osf1mk\n\telse\n\t    echo ${UNAME_MACHINE}-unknown-osf1\n\tfi\n\texit 0 ;;\n    parisc*:Lites*:*:*)\n\techo hppa1.1-hp-lites\n\texit 0 ;;\n    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)\n\techo c1-convex-bsd\n        exit 0 ;;\n    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)\n\tif getsysinfo -f scalar_acc\n\tthen echo c32-convex-bsd\n\telse echo c2-convex-bsd\n\tfi\n        exit 0 ;;\n    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)\n\techo c34-convex-bsd\n        exit 0 ;;\n    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)\n\techo c38-convex-bsd\n        exit 0 ;;\n    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)\n\techo c4-convex-bsd\n        exit 0 ;;\n    CRAY*Y-MP:*:*:*)\n\techo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit 0 ;;\n    CRAY*[A-Z]90:*:*:*)\n\techo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \\\n\t| sed -e 's/CRAY.*\\([A-Z]90\\)/\\1/' \\\n\t      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \\\n\t      -e 's/\\.[^.]*$/.X/'\n\texit 0 ;;\n    CRAY*TS:*:*:*)\n\techo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit 0 ;;\n    CRAY*T3E:*:*:*)\n\techo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit 0 ;;\n    CRAY*SV1:*:*:*)\n\techo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit 0 ;;\n    *:UNICOS/mp:*:*)\n\techo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit 0 ;;\n    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)\n\tFUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`\n        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`\n        echo \"${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n        exit 0 ;;\n    5000:UNIX_System_V:4.*:*)\n        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`\n        echo \"sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n\texit 0 ;;\n    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\\ Embedded/OS:*:*)\n\techo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}\n\texit 0 ;;\n    sparc*:BSD/OS:*:*)\n\techo sparc-unknown-bsdi${UNAME_RELEASE}\n\texit 0 ;;\n    *:BSD/OS:*:*)\n\techo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}\n\texit 0 ;;\n    *:FreeBSD:*:*)\n\t# Determine whether the default compiler uses glibc.\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#include <features.h>\n\t#if __GLIBC__ >= 2\n\tLIBC=gnu\n\t#else\n\tLIBC=\n\t#endif\nEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`\n\t# GNU/KFreeBSD systems have a \"k\" prefix to indicate we are using\n\t# FreeBSD's kernel, but not the complete OS.\n\tcase ${LIBC} in gnu) kernel_only='k' ;; esac\n\techo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}\n\texit 0 ;;\n    i*:CYGWIN*:*)\n\techo ${UNAME_MACHINE}-pc-cygwin\n\texit 0 ;;\n    i*:MINGW*:*)\n\techo ${UNAME_MACHINE}-pc-mingw32\n\texit 0 ;;\n    i*:PW*:*)\n\techo ${UNAME_MACHINE}-pc-pw32\n\texit 0 ;;\n    x86:Interix*:[34]*)\n\techo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\\..*//'\n\texit 0 ;;\n    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)\n\techo i${UNAME_MACHINE}-pc-mks\n\texit 0 ;;\n    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)\n\t# How do we know it's Interix rather than the generic POSIX subsystem?\n\t# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we\n\t# UNAME_MACHINE based on the output of uname instead of i386?\n\techo i586-pc-interix\n\texit 0 ;;\n    i*:UWIN*:*)\n\techo ${UNAME_MACHINE}-pc-uwin\n\texit 0 ;;\n    p*:CYGWIN*:*)\n\techo powerpcle-unknown-cygwin\n\texit 0 ;;\n    prep*:SunOS:5.*:*)\n\techo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit 0 ;;\n    *:GNU:*:*)\n\t# the GNU system\n\techo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`\n\texit 0 ;;\n    *:GNU/*:*:*)\n\t# other systems with GNU libc and userland\n\techo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu\n\texit 0 ;;\n    i*86:Minix:*:*)\n\techo ${UNAME_MACHINE}-pc-minix\n\texit 0 ;;\n    arm*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    cris:Linux:*:*)\n\techo cris-axis-linux-gnu\n\texit 0 ;;\n    ia64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    m32r*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    m68*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    mips:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef mips\n\t#undef mipsel\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=mipsel\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=mips\n\t#else\n\tCPU=\n\t#endif\n\t#endif\nEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`\n\ttest x\"${CPU}\" != x && echo \"${CPU}-unknown-linux-gnu\" && exit 0\n\t;;\n    mips64:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef mips64\n\t#undef mips64el\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=mips64el\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=mips64\n\t#else\n\tCPU=\n\t#endif\n\t#endif\nEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`\n\ttest x\"${CPU}\" != x && echo \"${CPU}-unknown-linux-gnu\" && exit 0\n\t;;\n    ppc:Linux:*:*)\n\techo powerpc-unknown-linux-gnu\n\texit 0 ;;\n    ppc64:Linux:*:*)\n\techo powerpc64-unknown-linux-gnu\n\texit 0 ;;\n    alpha:Linux:*:*)\n\tcase `sed -n '/^cpu model/s/^.*: \\(.*\\)/\\1/p' < /proc/cpuinfo` in\n\t  EV5)   UNAME_MACHINE=alphaev5 ;;\n\t  EV56)  UNAME_MACHINE=alphaev56 ;;\n\t  PCA56) UNAME_MACHINE=alphapca56 ;;\n\t  PCA57) UNAME_MACHINE=alphapca56 ;;\n\t  EV6)   UNAME_MACHINE=alphaev6 ;;\n\t  EV67)  UNAME_MACHINE=alphaev67 ;;\n\t  EV68*) UNAME_MACHINE=alphaev68 ;;\n        esac\n\tobjdump --private-headers /bin/sh | grep ld.so.1 >/dev/null\n\tif test \"$?\" = 0 ; then LIBC=\"libc1\" ; else LIBC=\"\" ; fi\n\techo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}\n\texit 0 ;;\n    parisc:Linux:*:* | hppa:Linux:*:*)\n\t# Look for CPU level\n\tcase `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in\n\t  PA7*) echo hppa1.1-unknown-linux-gnu ;;\n\t  PA8*) echo hppa2.0-unknown-linux-gnu ;;\n\t  *)    echo hppa-unknown-linux-gnu ;;\n\tesac\n\texit 0 ;;\n    parisc64:Linux:*:* | hppa64:Linux:*:*)\n\techo hppa64-unknown-linux-gnu\n\texit 0 ;;\n    s390:Linux:*:* | s390x:Linux:*:*)\n\techo ${UNAME_MACHINE}-ibm-linux\n\texit 0 ;;\n    sh64*:Linux:*:*)\n    \techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    sh*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    sparc:Linux:*:* | sparc64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit 0 ;;\n    x86_64:Linux:*:*)\n\techo x86_64-unknown-linux-gnu\n\texit 0 ;;\n    i*86:Linux:*:*)\n\t# The BFD linker knows what the default object file format is, so\n\t# first see if it will tell us. cd to the root directory to prevent\n\t# problems with other programs or directories called `ld' in the path.\n\t# Set LC_ALL=C to ensure ld outputs messages in English.\n\tld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \\\n\t\t\t | sed -ne '/supported targets:/!d\n\t\t\t\t    s/[ \t][ \t]*/ /g\n\t\t\t\t    s/.*supported targets: *//\n\t\t\t\t    s/ .*//\n\t\t\t\t    p'`\n        case \"$ld_supported_targets\" in\n\t  elf32-i386)\n\t\tTENTATIVE=\"${UNAME_MACHINE}-pc-linux-gnu\"\n\t\t;;\n\t  a.out-i386-linux)\n\t\techo \"${UNAME_MACHINE}-pc-linux-gnuaout\"\n\t\texit 0 ;;\n\t  coff-i386)\n\t\techo \"${UNAME_MACHINE}-pc-linux-gnucoff\"\n\t\texit 0 ;;\n\t  \"\")\n\t\t# Either a pre-BFD a.out linker (linux-gnuoldld) or\n\t\t# one that does not give us useful --help.\n\t\techo \"${UNAME_MACHINE}-pc-linux-gnuoldld\"\n\t\texit 0 ;;\n\tesac\n\t# Determine whether the default compiler is a.out or elf\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#include <features.h>\n\t#ifdef __ELF__\n\t# ifdef __GLIBC__\n\t#  if __GLIBC__ >= 2\n\tLIBC=gnu\n\t#  else\n\tLIBC=gnulibc1\n\t#  endif\n\t# else\n\tLIBC=gnulibc1\n\t# endif\n\t#else\n\t#ifdef __INTEL_COMPILER\n\tLIBC=gnu\n\t#else\n\tLIBC=gnuaout\n\t#endif\n\t#endif\n\t#ifdef __dietlibc__\n\tLIBC=dietlibc\n\t#endif\nEOF\n\teval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`\n\ttest x\"${LIBC}\" != x && echo \"${UNAME_MACHINE}-pc-linux-${LIBC}\" && exit 0\n\ttest x\"${TENTATIVE}\" != x && echo \"${TENTATIVE}\" && exit 0\n\t;;\n    i*86:DYNIX/ptx:4*:*)\n\t# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.\n\t# earlier versions are messed up and put the nodename in both\n\t# sysname and nodename.\n\techo i386-sequent-sysv4\n\texit 0 ;;\n    i*86:UNIX_SV:4.2MP:2.*)\n        # Unixware is an offshoot of SVR4, but it has its own version\n        # number series starting with 2...\n        # I am not positive that other SVR4 systems won't match this,\n\t# I just have to hope.  -- rms.\n        # Use sysv4.2uw... so that sysv4* matches it.\n\techo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}\n\texit 0 ;;\n    i*86:OS/2:*:*)\n\t# If we were able to find `uname', then EMX Unix compatibility\n\t# is probably installed.\n\techo ${UNAME_MACHINE}-pc-os2-emx\n\texit 0 ;;\n    i*86:XTS-300:*:STOP)\n\techo ${UNAME_MACHINE}-unknown-stop\n\texit 0 ;;\n    i*86:atheos:*:*)\n\techo ${UNAME_MACHINE}-unknown-atheos\n\texit 0 ;;\n\ti*86:syllable:*:*)\n\techo ${UNAME_MACHINE}-pc-syllable\n\texit 0 ;;\n    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)\n\techo i386-unknown-lynxos${UNAME_RELEASE}\n\texit 0 ;;\n    i*86:*DOS:*:*)\n\techo ${UNAME_MACHINE}-pc-msdosdjgpp\n\texit 0 ;;\n    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)\n\tUNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\\/MP$//'`\n\tif grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then\n\t\techo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}\n\telse\n\t\techo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}\n\tfi\n\texit 0 ;;\n    i*86:*:5:[78]*)\n\tcase `/bin/uname -X | grep \"^Machine\"` in\n\t    *486*)\t     UNAME_MACHINE=i486 ;;\n\t    *Pentium)\t     UNAME_MACHINE=i586 ;;\n\t    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;\n\tesac\n\techo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}\n\texit 0 ;;\n    i*86:*:3.2:*)\n\tif test -f /usr/options/cb.name; then\n\t\tUNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`\n\t\techo ${UNAME_MACHINE}-pc-isc$UNAME_REL\n\telif /bin/uname -X 2>/dev/null >/dev/null ; then\n\t\tUNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`\n\t\t(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486\n\t\t(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i586\n\t\t(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i686\n\t\t(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i686\n\t\techo ${UNAME_MACHINE}-pc-sco$UNAME_REL\n\telse\n\t\techo ${UNAME_MACHINE}-pc-sysv32\n\tfi\n\texit 0 ;;\n    pc:*:*:*)\n\t# Left here for compatibility:\n        # uname -m prints for DJGPP always 'pc', but it prints nothing about\n        # the processor, so we play safe by assuming i386.\n\techo i386-pc-msdosdjgpp\n        exit 0 ;;\n    Intel:Mach:3*:*)\n\techo i386-pc-mach3\n\texit 0 ;;\n    paragon:*:*:*)\n\techo i860-intel-osf1\n\texit 0 ;;\n    i860:*:4.*:*) # i860-SVR4\n\tif grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then\n\t  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4\n\telse # Add other i860-SVR4 vendors below as they are discovered.\n\t  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4\n\tfi\n\texit 0 ;;\n    mini*:CTIX:SYS*5:*)\n\t# \"miniframe\"\n\techo m68010-convergent-sysv\n\texit 0 ;;\n    mc68k:UNIX:SYSTEM5:3.51m)\n\techo m68k-convergent-sysv\n\texit 0 ;;\n    M680?0:D-NIX:5.3:*)\n\techo m68k-diab-dnix\n\texit 0 ;;\n    M68*:*:R3V[5678]*:*)\n\ttest -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;\n    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)\n\tOS_REL=''\n\ttest -r /etc/.relid \\\n\t&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \\([0-9][0-9]\\).*/\\1/p' < /etc/.relid`\n\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t  && echo i486-ncr-sysv4.3${OS_REL} && exit 0\n\t/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \\\n\t  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;\n    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)\n        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n          && echo i486-ncr-sysv4 && exit 0 ;;\n    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)\n\techo m68k-unknown-lynxos${UNAME_RELEASE}\n\texit 0 ;;\n    mc68030:UNIX_System_V:4.*:*)\n\techo m68k-atari-sysv4\n\texit 0 ;;\n    TSUNAMI:LynxOS:2.*:*)\n\techo sparc-unknown-lynxos${UNAME_RELEASE}\n\texit 0 ;;\n    rs6000:LynxOS:2.*:*)\n\techo rs6000-unknown-lynxos${UNAME_RELEASE}\n\texit 0 ;;\n    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)\n\techo powerpc-unknown-lynxos${UNAME_RELEASE}\n\texit 0 ;;\n    SM[BE]S:UNIX_SV:*:*)\n\techo mips-dde-sysv${UNAME_RELEASE}\n\texit 0 ;;\n    RM*:ReliantUNIX-*:*:*)\n\techo mips-sni-sysv4\n\texit 0 ;;\n    RM*:SINIX-*:*:*)\n\techo mips-sni-sysv4\n\texit 0 ;;\n    *:SINIX-*:*:*)\n\tif uname -p 2>/dev/null >/dev/null ; then\n\t\tUNAME_MACHINE=`(uname -p) 2>/dev/null`\n\t\techo ${UNAME_MACHINE}-sni-sysv4\n\telse\n\t\techo ns32k-sni-sysv\n\tfi\n\texit 0 ;;\n    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort\n                      # says <Richard.M.Bartel@ccMail.Census.GOV>\n        echo i586-unisys-sysv4\n        exit 0 ;;\n    *:UNIX_System_V:4*:FTX*)\n\t# From Gerald Hewes <hewes@openmarket.com>.\n\t# How about differentiating between stratus architectures? -djm\n\techo hppa1.1-stratus-sysv4\n\texit 0 ;;\n    *:*:*:FTX*)\n\t# From seanf@swdc.stratus.com.\n\techo i860-stratus-sysv4\n\texit 0 ;;\n    *:VOS:*:*)\n\t# From Paul.Green@stratus.com.\n\techo hppa1.1-stratus-vos\n\texit 0 ;;\n    mc68*:A/UX:*:*)\n\techo m68k-apple-aux${UNAME_RELEASE}\n\texit 0 ;;\n    news*:NEWS-OS:6*:*)\n\techo mips-sony-newsos6\n\texit 0 ;;\n    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)\n\tif [ -d /usr/nec ]; then\n\t        echo mips-nec-sysv${UNAME_RELEASE}\n\telse\n\t        echo mips-unknown-sysv${UNAME_RELEASE}\n\tfi\n        exit 0 ;;\n    BeBox:BeOS:*:*)\t# BeOS running on hardware made by Be, PPC only.\n\techo powerpc-be-beos\n\texit 0 ;;\n    BeMac:BeOS:*:*)\t# BeOS running on Mac or Mac clone, PPC only.\n\techo powerpc-apple-beos\n\texit 0 ;;\n    BePC:BeOS:*:*)\t# BeOS running on Intel PC compatible.\n\techo i586-pc-beos\n\texit 0 ;;\n    SX-4:SUPER-UX:*:*)\n\techo sx4-nec-superux${UNAME_RELEASE}\n\texit 0 ;;\n    SX-5:SUPER-UX:*:*)\n\techo sx5-nec-superux${UNAME_RELEASE}\n\texit 0 ;;\n    SX-6:SUPER-UX:*:*)\n\techo sx6-nec-superux${UNAME_RELEASE}\n\texit 0 ;;\n    Power*:Rhapsody:*:*)\n\techo powerpc-apple-rhapsody${UNAME_RELEASE}\n\texit 0 ;;\n    *:Rhapsody:*:*)\n\techo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}\n\texit 0 ;;\n    *:Darwin:*:*)\n\tcase `uname -p` in\n\t    *86) UNAME_PROCESSOR=i686 ;;\n\t    powerpc) UNAME_PROCESSOR=powerpc ;;\n\tesac\n\techo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}\n\texit 0 ;;\n    *:procnto*:*:* | *:QNX:[0123456789]*:*)\n\tUNAME_PROCESSOR=`uname -p`\n\tif test \"$UNAME_PROCESSOR\" = \"x86\"; then\n\t\tUNAME_PROCESSOR=i386\n\t\tUNAME_MACHINE=pc\n\tfi\n\techo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}\n\texit 0 ;;\n    *:QNX:*:4*)\n\techo i386-pc-qnx\n\texit 0 ;;\n    NSR-?:NONSTOP_KERNEL:*:*)\n\techo nsr-tandem-nsk${UNAME_RELEASE}\n\texit 0 ;;\n    *:NonStop-UX:*:*)\n\techo mips-compaq-nonstopux\n\texit 0 ;;\n    BS2000:POSIX*:*:*)\n\techo bs2000-siemens-sysv\n\texit 0 ;;\n    DS/*:UNIX_System_V:*:*)\n\techo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}\n\texit 0 ;;\n    *:Plan9:*:*)\n\t# \"uname -m\" is not consistent, so use $cputype instead. 386\n\t# is converted to i386 for consistency with other x86\n\t# operating systems.\n\tif test \"$cputype\" = \"386\"; then\n\t    UNAME_MACHINE=i386\n\telse\n\t    UNAME_MACHINE=\"$cputype\"\n\tfi\n\techo ${UNAME_MACHINE}-unknown-plan9\n\texit 0 ;;\n    *:TOPS-10:*:*)\n\techo pdp10-unknown-tops10\n\texit 0 ;;\n    *:TENEX:*:*)\n\techo pdp10-unknown-tenex\n\texit 0 ;;\n    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)\n\techo pdp10-dec-tops20\n\texit 0 ;;\n    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)\n\techo pdp10-xkl-tops20\n\texit 0 ;;\n    *:TOPS-20:*:*)\n\techo pdp10-unknown-tops20\n\texit 0 ;;\n    *:ITS:*:*)\n\techo pdp10-unknown-its\n\texit 0 ;;\n    SEI:*:*:SEIUX)\n        echo mips-sei-seiux${UNAME_RELEASE}\n\texit 0 ;;\n    *:DragonFly:*:*)\n\techo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`\n\texit 0 ;;\nesac\n\n#echo '(No uname command or uname output not recognized.)' 1>&2\n#echo \"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}\" 1>&2\n\neval $set_cc_for_build\ncat >$dummy.c <<EOF\n#ifdef _SEQUENT_\n# include <sys/types.h>\n# include <sys/utsname.h>\n#endif\nmain ()\n{\n#if defined (sony)\n#if defined (MIPSEB)\n  /* BFD wants \"bsd\" instead of \"newsos\".  Perhaps BFD should be changed,\n     I don't know....  */\n  printf (\"mips-sony-bsd\\n\"); exit (0);\n#else\n#include <sys/param.h>\n  printf (\"m68k-sony-newsos%s\\n\",\n#ifdef NEWSOS4\n          \"4\"\n#else\n\t  \"\"\n#endif\n         ); exit (0);\n#endif\n#endif\n\n#if defined (__arm) && defined (__acorn) && defined (__unix)\n  printf (\"arm-acorn-riscix\"); exit (0);\n#endif\n\n#if defined (hp300) && !defined (hpux)\n  printf (\"m68k-hp-bsd\\n\"); exit (0);\n#endif\n\n#if defined (NeXT)\n#if !defined (__ARCHITECTURE__)\n#define __ARCHITECTURE__ \"m68k\"\n#endif\n  int version;\n  version=`(hostinfo | sed -n 's/.*NeXT Mach \\([0-9]*\\).*/\\1/p') 2>/dev/null`;\n  if (version < 4)\n    printf (\"%s-next-nextstep%d\\n\", __ARCHITECTURE__, version);\n  else\n    printf (\"%s-next-openstep%d\\n\", __ARCHITECTURE__, version);\n  exit (0);\n#endif\n\n#if defined (MULTIMAX) || defined (n16)\n#if defined (UMAXV)\n  printf (\"ns32k-encore-sysv\\n\"); exit (0);\n#else\n#if defined (CMU)\n  printf (\"ns32k-encore-mach\\n\"); exit (0);\n#else\n  printf (\"ns32k-encore-bsd\\n\"); exit (0);\n#endif\n#endif\n#endif\n\n#if defined (__386BSD__)\n  printf (\"i386-pc-bsd\\n\"); exit (0);\n#endif\n\n#if defined (sequent)\n#if defined (i386)\n  printf (\"i386-sequent-dynix\\n\"); exit (0);\n#endif\n#if defined (ns32000)\n  printf (\"ns32k-sequent-dynix\\n\"); exit (0);\n#endif\n#endif\n\n#if defined (_SEQUENT_)\n    struct utsname un;\n\n    uname(&un);\n\n    if (strncmp(un.version, \"V2\", 2) == 0) {\n\tprintf (\"i386-sequent-ptx2\\n\"); exit (0);\n    }\n    if (strncmp(un.version, \"V1\", 2) == 0) { /* XXX is V1 correct? */\n\tprintf (\"i386-sequent-ptx1\\n\"); exit (0);\n    }\n    printf (\"i386-sequent-ptx\\n\"); exit (0);\n\n#endif\n\n#if defined (vax)\n# if !defined (ultrix)\n#  include <sys/param.h>\n#  if defined (BSD)\n#   if BSD == 43\n      printf (\"vax-dec-bsd4.3\\n\"); exit (0);\n#   else\n#    if BSD == 199006\n      printf (\"vax-dec-bsd4.3reno\\n\"); exit (0);\n#    else\n      printf (\"vax-dec-bsd\\n\"); exit (0);\n#    endif\n#   endif\n#  else\n    printf (\"vax-dec-bsd\\n\"); exit (0);\n#  endif\n# else\n    printf (\"vax-dec-ultrix\\n\"); exit (0);\n# endif\n#endif\n\n#if defined (alliant) && defined (i860)\n  printf (\"i860-alliant-bsd\\n\"); exit (0);\n#endif\n\n  exit (1);\n}\nEOF\n\n$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0\n\n# Apollos put the system type in the environment.\n\ntest -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }\n\n# Convex versions that predate uname can use getsysinfo(1)\n\nif [ -x /usr/convex/getsysinfo ]\nthen\n    case `getsysinfo -f cpu_type` in\n    c1*)\n\techo c1-convex-bsd\n\texit 0 ;;\n    c2*)\n\tif getsysinfo -f scalar_acc\n\tthen echo c32-convex-bsd\n\telse echo c2-convex-bsd\n\tfi\n\texit 0 ;;\n    c34*)\n\techo c34-convex-bsd\n\texit 0 ;;\n    c38*)\n\techo c38-convex-bsd\n\texit 0 ;;\n    c4*)\n\techo c4-convex-bsd\n\texit 0 ;;\n    esac\nfi\n\ncat >&2 <<EOF\n$0: unable to guess system type\n\nThis script, last modified $timestamp, has failed to recognize\nthe operating system you are using. It is advised that you\ndownload the most up to date version of the config scripts from\n\n    ftp://ftp.gnu.org/pub/gnu/config/\n\nIf the version you run ($0) is already up to date, please\nsend the following data and any information you think might be\npertinent to <config-patches@gnu.org> in order to provide the needed\ninformation to handle your system.\n\nconfig.guess timestamp = $timestamp\n\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`\n\nhostinfo               = `(hostinfo) 2>/dev/null`\n/bin/universe          = `(/bin/universe) 2>/dev/null`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`\n/bin/arch              = `(/bin/arch) 2>/dev/null`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`\n\nUNAME_MACHINE = ${UNAME_MACHINE}\nUNAME_RELEASE = ${UNAME_RELEASE}\nUNAME_SYSTEM  = ${UNAME_SYSTEM}\nUNAME_VERSION = ${UNAME_VERSION}\nEOF\n\nexit 1\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"timestamp='\"\n# time-stamp-format: \"%:y-%02m-%02d\"\n# time-stamp-end: \"'\"\n# End:\n"
  },
  {
    "path": "config.sub",
    "content": "#! /bin/sh\n# Configuration validation subroutine script.\n#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,\n#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.\n\ntimestamp='2004-06-11'\n\n# This file is (in principle) common to ALL GNU software.\n# The presence of a machine in this file suggests that SOME GNU software\n# can handle that machine.  It does not imply ALL GNU software can.\n#\n# This file is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 59 Temple Place - Suite 330,\n# Boston, MA 02111-1307, USA.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n# Please send patches to <config-patches@gnu.org>.  Submit a context\n# diff and a properly formatted ChangeLog entry.\n#\n# Configuration subroutine to validate and canonicalize a configuration type.\n# Supply the specified configuration type as an argument.\n# If it is invalid, we print an error message on stderr and exit with code 1.\n# Otherwise, we print the canonical config type on stdout and succeed.\n\n# This file is supposed to be the same for all GNU packages\n# and recognize all the CPU types, system types and aliases\n# that are meaningful with *any* GNU software.\n# Each package is responsible for reporting which valid configurations\n# it does not support.  The user should be able to distinguish\n# a failure to support a valid configuration from a meaningless\n# configuration.\n\n# The goal of this file is to map all the various variations of a given\n# machine specification into a single specification in the form:\n#\tCPU_TYPE-MANUFACTURER-OPERATING_SYSTEM\n# or in some cases, the newer four-part form:\n#\tCPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM\n# It is wrong to echo any other type of specification.\n\nme=`echo \"$0\" | sed -e 's,.*/,,'`\n\nusage=\"\\\nUsage: $0 [OPTION] CPU-MFR-OPSYS\n       $0 [OPTION] ALIAS\n\nCanonicalize a configuration name.\n\nOperation modes:\n  -h, --help         print this help, then exit\n  -t, --time-stamp   print date of last modification, then exit\n  -v, --version      print version number, then exit\n\nReport bugs and patches to <config-patches@gnu.org>.\"\n\nversion=\"\\\nGNU config.sub ($timestamp)\n\nCopyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001\nFree Software Foundation, Inc.\n\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\"\n\nhelp=\"\nTry \\`$me --help' for more information.\"\n\n# Parse command line\nwhile test $# -gt 0 ; do\n  case $1 in\n    --time-stamp | --time* | -t )\n       echo \"$timestamp\" ; exit 0 ;;\n    --version | -v )\n       echo \"$version\" ; exit 0 ;;\n    --help | --h* | -h )\n       echo \"$usage\"; exit 0 ;;\n    -- )     # Stop option processing\n       shift; break ;;\n    - )\t# Use stdin as input.\n       break ;;\n    -* )\n       echo \"$me: invalid option $1$help\"\n       exit 1 ;;\n\n    *local*)\n       # First pass through any local machine types.\n       echo $1\n       exit 0;;\n\n    * )\n       break ;;\n  esac\ndone\n\ncase $# in\n 0) echo \"$me: missing argument$help\" >&2\n    exit 1;;\n 1) ;;\n *) echo \"$me: too many arguments$help\" >&2\n    exit 1;;\nesac\n\n# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).\n# Here we must recognize all the valid KERNEL-OS combinations.\nmaybe_os=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\2/'`\ncase $maybe_os in\n  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \\\n  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)\n    os=-$maybe_os\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`\n    ;;\n  *)\n    basic_machine=`echo $1 | sed 's/-[^-]*$//'`\n    if [ $basic_machine != $1 ]\n    then os=`echo $1 | sed 's/.*-/-/'`\n    else os=; fi\n    ;;\nesac\n\n### Let's recognize common machines as not being operating systems so\n### that things like config.sub decstation-3100 work.  We also\n### recognize some manufacturers as not being operating systems, so we\n### can provide default operating systems below.\ncase $os in\n\t-sun*os*)\n\t\t# Prevent following clause from handling this invalid input.\n\t\t;;\n\t-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \\\n\t-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \\\n\t-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \\\n\t-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\\\n\t-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \\\n\t-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \\\n\t-apple | -axis)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-sim | -cisco | -oki | -wec | -winbond)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-scout)\n\t\t;;\n\t-wrs)\n\t\tos=-vxworks\n\t\tbasic_machine=$1\n\t\t;;\n\t-chorusos*)\n\t\tos=-chorusos\n\t\tbasic_machine=$1\n\t\t;;\n \t-chorusrdb)\n \t\tos=-chorusrdb\n\t\tbasic_machine=$1\n \t\t;;\n\t-hiux*)\n\t\tos=-hiuxwe2\n\t\t;;\n\t-sco5)\n\t\tos=-sco3.2v5\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco4)\n\t\tos=-sco3.2v4\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco3.2.[4-9]*)\n\t\tos=`echo $os | sed -e 's/sco3.2./sco3.2v/'`\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco3.2v[4-9]*)\n\t\t# Don't forget version if it is 3.2v4 or newer.\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco*)\n\t\tos=-sco3.2v2\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-udk*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-isc)\n\t\tos=-isc2.2\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-clix*)\n\t\tbasic_machine=clipper-intergraph\n\t\t;;\n\t-isc*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-lynx*)\n\t\tos=-lynxos\n\t\t;;\n\t-ptx*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`\n\t\t;;\n\t-windowsnt*)\n\t\tos=`echo $os | sed -e 's/windowsnt/winnt/'`\n\t\t;;\n\t-psos*)\n\t\tos=-psos\n\t\t;;\n\t-mint | -mint[0-9]*)\n\t\tbasic_machine=m68k-atari\n\t\tos=-mint\n\t\t;;\nesac\n\n# Decode aliases for certain CPU-COMPANY combinations.\ncase $basic_machine in\n\t# Recognize the basic CPU types without company name.\n\t# Some are omitted here because they have special meanings below.\n\t1750a | 580 \\\n\t| a29k \\\n\t| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \\\n\t| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \\\n\t| am33_2.0 \\\n\t| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \\\n\t| c4x | clipper \\\n\t| d10v | d30v | dlx | dsp16xx \\\n\t| fr30 | frv \\\n\t| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \\\n\t| i370 | i860 | i960 | ia64 \\\n\t| ip2k | iq2000 \\\n\t| m32r | m68000 | m68k | m88k | mcore \\\n\t| mips | mipsbe | mipseb | mipsel | mipsle \\\n\t| mips16 \\\n\t| mips64 | mips64el \\\n\t| mips64vr | mips64vrel \\\n\t| mips64orion | mips64orionel \\\n\t| mips64vr4100 | mips64vr4100el \\\n\t| mips64vr4300 | mips64vr4300el \\\n\t| mips64vr5000 | mips64vr5000el \\\n\t| mipsisa32 | mipsisa32el \\\n\t| mipsisa32r2 | mipsisa32r2el \\\n\t| mipsisa64 | mipsisa64el \\\n\t| mipsisa64r2 | mipsisa64r2el \\\n\t| mipsisa64sb1 | mipsisa64sb1el \\\n\t| mipsisa64sr71k | mipsisa64sr71kel \\\n\t| mipstx39 | mipstx39el \\\n\t| mn10200 | mn10300 \\\n\t| msp430 \\\n\t| ns16k | ns32k \\\n\t| openrisc | or32 \\\n\t| pdp10 | pdp11 | pj | pjl \\\n\t| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \\\n\t| pyramid \\\n\t| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \\\n\t| sh64 | sh64le \\\n\t| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \\\n\t| strongarm \\\n\t| tahoe | thumb | tic4x | tic80 | tron \\\n\t| v850 | v850e \\\n\t| we32k \\\n\t| x86 | xscale | xstormy16 | xtensa \\\n\t| z8k)\n\t\tbasic_machine=$basic_machine-unknown\n\t\t;;\n\tm6811 | m68hc11 | m6812 | m68hc12)\n\t\t# Motorola 68HC11/12.\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-none\n\t\t;;\n\tm88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)\n\t\t;;\n\n\t# We use `pc' rather than `unknown'\n\t# because (1) that's what they normally are, and\n\t# (2) the word \"unknown\" tends to confuse beginning users.\n\ti*86 | x86_64)\n\t  basic_machine=$basic_machine-pc\n\t  ;;\n\t# Object if more than one company name word.\n\t*-*-*)\n\t\techo Invalid configuration \\`$1\\': machine \\`$basic_machine\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\n\t# Recognize the basic CPU types with company name.\n\t580-* \\\n\t| a29k-* \\\n\t| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \\\n\t| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \\\n\t| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \\\n\t| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \\\n\t| avr-* \\\n\t| bs2000-* \\\n\t| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \\\n\t| clipper-* | cydra-* \\\n\t| d10v-* | d30v-* | dlx-* \\\n\t| elxsi-* \\\n\t| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \\\n\t| h8300-* | h8500-* \\\n\t| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \\\n\t| i*86-* | i860-* | i960-* | ia64-* \\\n\t| ip2k-* | iq2000-* \\\n\t| m32r-* \\\n\t| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \\\n\t| m88110-* | m88k-* | mcore-* \\\n\t| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \\\n\t| mips16-* \\\n\t| mips64-* | mips64el-* \\\n\t| mips64vr-* | mips64vrel-* \\\n\t| mips64orion-* | mips64orionel-* \\\n\t| mips64vr4100-* | mips64vr4100el-* \\\n\t| mips64vr4300-* | mips64vr4300el-* \\\n\t| mips64vr5000-* | mips64vr5000el-* \\\n\t| mipsisa32-* | mipsisa32el-* \\\n\t| mipsisa32r2-* | mipsisa32r2el-* \\\n\t| mipsisa64-* | mipsisa64el-* \\\n\t| mipsisa64r2-* | mipsisa64r2el-* \\\n\t| mipsisa64sb1-* | mipsisa64sb1el-* \\\n\t| mipsisa64sr71k-* | mipsisa64sr71kel-* \\\n\t| mipstx39-* | mipstx39el-* \\\n\t| msp430-* \\\n\t| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \\\n\t| orion-* \\\n\t| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \\\n\t| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \\\n\t| pyramid-* \\\n\t| romp-* | rs6000-* \\\n\t| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \\\n\t| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \\\n\t| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \\\n\t| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \\\n\t| tahoe-* | thumb-* \\\n\t| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \\\n\t| tron-* \\\n\t| v850-* | v850e-* | vax-* \\\n\t| we32k-* \\\n\t| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \\\n\t| xtensa-* \\\n\t| ymp-* \\\n\t| z8k-*)\n\t\t;;\n\t# Recognize the various machine names and aliases which stand\n\t# for a CPU type and a company and sometimes even an OS.\n\t386bsd)\n\t\tbasic_machine=i386-unknown\n\t\tos=-bsd\n\t\t;;\n\t3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)\n\t\tbasic_machine=m68000-att\n\t\t;;\n\t3b*)\n\t\tbasic_machine=we32k-att\n\t\t;;\n\ta29khif)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tadobe68k)\n\t\tbasic_machine=m68010-adobe\n\t\tos=-scout\n\t\t;;\n\talliant | fx80)\n\t\tbasic_machine=fx80-alliant\n\t\t;;\n\taltos | altos3068)\n\t\tbasic_machine=m68k-altos\n\t\t;;\n\tam29k)\n\t\tbasic_machine=a29k-none\n\t\tos=-bsd\n\t\t;;\n\tamd64)\n\t\tbasic_machine=x86_64-pc\n\t\t;;\n\tamd64-*)\n\t\tbasic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tamdahl)\n\t\tbasic_machine=580-amdahl\n\t\tos=-sysv\n\t\t;;\n\tamiga | amiga-*)\n\t\tbasic_machine=m68k-unknown\n\t\t;;\n\tamigaos | amigados)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-amigaos\n\t\t;;\n\tamigaunix | amix)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-sysv4\n\t\t;;\n\tapollo68)\n\t\tbasic_machine=m68k-apollo\n\t\tos=-sysv\n\t\t;;\n\tapollo68bsd)\n\t\tbasic_machine=m68k-apollo\n\t\tos=-bsd\n\t\t;;\n\taux)\n\t\tbasic_machine=m68k-apple\n\t\tos=-aux\n\t\t;;\n\tbalance)\n\t\tbasic_machine=ns32k-sequent\n\t\tos=-dynix\n\t\t;;\n\tc90)\n\t\tbasic_machine=c90-cray\n\t\tos=-unicos\n\t\t;;\n\tconvex-c1)\n\t\tbasic_machine=c1-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c2)\n\t\tbasic_machine=c2-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c32)\n\t\tbasic_machine=c32-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c34)\n\t\tbasic_machine=c34-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c38)\n\t\tbasic_machine=c38-convex\n\t\tos=-bsd\n\t\t;;\n\tcray | j90)\n\t\tbasic_machine=j90-cray\n\t\tos=-unicos\n\t\t;;\n\tcrds | unos)\n\t\tbasic_machine=m68k-crds\n\t\t;;\n\tcris | cris-* | etrax*)\n\t\tbasic_machine=cris-axis\n\t\t;;\n\tda30 | da30-*)\n\t\tbasic_machine=m68k-da30\n\t\t;;\n\tdecstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)\n\t\tbasic_machine=mips-dec\n\t\t;;\n\tdecsystem10* | dec10*)\n\t\tbasic_machine=pdp10-dec\n\t\tos=-tops10\n\t\t;;\n\tdecsystem20* | dec20*)\n\t\tbasic_machine=pdp10-dec\n\t\tos=-tops20\n\t\t;;\n\tdelta | 3300 | motorola-3300 | motorola-delta \\\n\t      | 3300-motorola | delta-motorola)\n\t\tbasic_machine=m68k-motorola\n\t\t;;\n\tdelta88)\n\t\tbasic_machine=m88k-motorola\n\t\tos=-sysv3\n\t\t;;\n\tdpx20 | dpx20-*)\n\t\tbasic_machine=rs6000-bull\n\t\tos=-bosx\n\t\t;;\n\tdpx2* | dpx2*-bull)\n\t\tbasic_machine=m68k-bull\n\t\tos=-sysv3\n\t\t;;\n\tebmon29k)\n\t\tbasic_machine=a29k-amd\n\t\tos=-ebmon\n\t\t;;\n\telxsi)\n\t\tbasic_machine=elxsi-elxsi\n\t\tos=-bsd\n\t\t;;\n\tencore | umax | mmax)\n\t\tbasic_machine=ns32k-encore\n\t\t;;\n\tes1800 | OSE68k | ose68k | ose | OSE)\n\t\tbasic_machine=m68k-ericsson\n\t\tos=-ose\n\t\t;;\n\tfx2800)\n\t\tbasic_machine=i860-alliant\n\t\t;;\n\tgenix)\n\t\tbasic_machine=ns32k-ns\n\t\t;;\n\tgmicro)\n\t\tbasic_machine=tron-gmicro\n\t\tos=-sysv\n\t\t;;\n\tgo32)\n\t\tbasic_machine=i386-pc\n\t\tos=-go32\n\t\t;;\n\th3050r* | hiux*)\n\t\tbasic_machine=hppa1.1-hitachi\n\t\tos=-hiuxwe2\n\t\t;;\n\th8300hms)\n\t\tbasic_machine=h8300-hitachi\n\t\tos=-hms\n\t\t;;\n\th8300xray)\n\t\tbasic_machine=h8300-hitachi\n\t\tos=-xray\n\t\t;;\n\th8500hms)\n\t\tbasic_machine=h8500-hitachi\n\t\tos=-hms\n\t\t;;\n\tharris)\n\t\tbasic_machine=m88k-harris\n\t\tos=-sysv3\n\t\t;;\n\thp300-*)\n\t\tbasic_machine=m68k-hp\n\t\t;;\n\thp300bsd)\n\t\tbasic_machine=m68k-hp\n\t\tos=-bsd\n\t\t;;\n\thp300hpux)\n\t\tbasic_machine=m68k-hp\n\t\tos=-hpux\n\t\t;;\n\thp3k9[0-9][0-9] | hp9[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thp9k2[0-9][0-9] | hp9k31[0-9])\n\t\tbasic_machine=m68000-hp\n\t\t;;\n\thp9k3[2-9][0-9])\n\t\tbasic_machine=m68k-hp\n\t\t;;\n\thp9k6[0-9][0-9] | hp6[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thp9k7[0-79][0-9] | hp7[0-79][0-9])\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k78[0-9] | hp78[0-9])\n\t\t# FIXME: really hppa2.0-hp\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)\n\t\t# FIXME: really hppa2.0-hp\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[0-9][13679] | hp8[0-9][13679])\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[0-9][0-9] | hp8[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thppa-next)\n\t\tos=-nextstep3\n\t\t;;\n\thppaosf)\n\t\tbasic_machine=hppa1.1-hp\n\t\tos=-osf\n\t\t;;\n\thppro)\n\t\tbasic_machine=hppa1.1-hp\n\t\tos=-proelf\n\t\t;;\n\ti370-ibm* | ibm*)\n\t\tbasic_machine=i370-ibm\n\t\t;;\n# I'm not sure what \"Sysv32\" means.  Should this be sysv3.2?\n\ti*86v32)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv32\n\t\t;;\n\ti*86v4*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv4\n\t\t;;\n\ti*86v)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv\n\t\t;;\n\ti*86sol2)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-solaris2\n\t\t;;\n\ti386mach)\n\t\tbasic_machine=i386-mach\n\t\tos=-mach\n\t\t;;\n\ti386-vsta | vsta)\n\t\tbasic_machine=i386-unknown\n\t\tos=-vsta\n\t\t;;\n\tiris | iris4d)\n\t\tbasic_machine=mips-sgi\n\t\tcase $os in\n\t\t    -irix*)\n\t\t\t;;\n\t\t    *)\n\t\t\tos=-irix4\n\t\t\t;;\n\t\tesac\n\t\t;;\n\tisi68 | isi)\n\t\tbasic_machine=m68k-isi\n\t\tos=-sysv\n\t\t;;\n\tm88k-omron*)\n\t\tbasic_machine=m88k-omron\n\t\t;;\n\tmagnum | m3230)\n\t\tbasic_machine=mips-mips\n\t\tos=-sysv\n\t\t;;\n\tmerlin)\n\t\tbasic_machine=ns32k-utek\n\t\tos=-sysv\n\t\t;;\n\tmingw32)\n\t\tbasic_machine=i386-pc\n\t\tos=-mingw32\n\t\t;;\n\tminiframe)\n\t\tbasic_machine=m68000-convergent\n\t\t;;\n\t*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)\n\t\tbasic_machine=m68k-atari\n\t\tos=-mint\n\t\t;;\n\tmips3*-*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`\n\t\t;;\n\tmips3*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown\n\t\t;;\n\tmmix*)\n\t\tbasic_machine=mmix-knuth\n\t\tos=-mmixware\n\t\t;;\n\tmonitor)\n\t\tbasic_machine=m68k-rom68k\n\t\tos=-coff\n\t\t;;\n\tmorphos)\n\t\tbasic_machine=powerpc-unknown\n\t\tos=-morphos\n\t\t;;\n\tmsdos)\n\t\tbasic_machine=i386-pc\n\t\tos=-msdos\n\t\t;;\n\tmvs)\n\t\tbasic_machine=i370-ibm\n\t\tos=-mvs\n\t\t;;\n\tncr3000)\n\t\tbasic_machine=i486-ncr\n\t\tos=-sysv4\n\t\t;;\n\tnetbsd386)\n\t\tbasic_machine=i386-unknown\n\t\tos=-netbsd\n\t\t;;\n\tnetwinder)\n\t\tbasic_machine=armv4l-rebel\n\t\tos=-linux\n\t\t;;\n\tnews | news700 | news800 | news900)\n\t\tbasic_machine=m68k-sony\n\t\tos=-newsos\n\t\t;;\n\tnews1000)\n\t\tbasic_machine=m68030-sony\n\t\tos=-newsos\n\t\t;;\n\tnews-3600 | risc-news)\n\t\tbasic_machine=mips-sony\n\t\tos=-newsos\n\t\t;;\n\tnecv70)\n\t\tbasic_machine=v70-nec\n\t\tos=-sysv\n\t\t;;\n\tnext | m*-next )\n\t\tbasic_machine=m68k-next\n\t\tcase $os in\n\t\t    -nextstep* )\n\t\t\t;;\n\t\t    -ns2*)\n\t\t      os=-nextstep2\n\t\t\t;;\n\t\t    *)\n\t\t      os=-nextstep3\n\t\t\t;;\n\t\tesac\n\t\t;;\n\tnh3000)\n\t\tbasic_machine=m68k-harris\n\t\tos=-cxux\n\t\t;;\n\tnh[45]000)\n\t\tbasic_machine=m88k-harris\n\t\tos=-cxux\n\t\t;;\n\tnindy960)\n\t\tbasic_machine=i960-intel\n\t\tos=-nindy\n\t\t;;\n\tmon960)\n\t\tbasic_machine=i960-intel\n\t\tos=-mon960\n\t\t;;\n\tnonstopux)\n\t\tbasic_machine=mips-compaq\n\t\tos=-nonstopux\n\t\t;;\n\tnp1)\n\t\tbasic_machine=np1-gould\n\t\t;;\n\tnv1)\n\t\tbasic_machine=nv1-cray\n\t\tos=-unicosmp\n\t\t;;\n\tnsr-tandem)\n\t\tbasic_machine=nsr-tandem\n\t\t;;\n\top50n-* | op60c-*)\n\t\tbasic_machine=hppa1.1-oki\n\t\tos=-proelf\n\t\t;;\n\tor32 | or32-*)\n\t\tbasic_machine=or32-unknown\n\t\tos=-coff\n\t\t;;\n\tos400)\n\t\tbasic_machine=powerpc-ibm\n\t\tos=-os400\n\t\t;;\n\tOSE68000 | ose68000)\n\t\tbasic_machine=m68000-ericsson\n\t\tos=-ose\n\t\t;;\n\tos68k)\n\t\tbasic_machine=m68k-none\n\t\tos=-os68k\n\t\t;;\n\tpa-hitachi)\n\t\tbasic_machine=hppa1.1-hitachi\n\t\tos=-hiuxwe2\n\t\t;;\n\tparagon)\n\t\tbasic_machine=i860-intel\n\t\tos=-osf\n\t\t;;\n\tpbd)\n\t\tbasic_machine=sparc-tti\n\t\t;;\n\tpbb)\n\t\tbasic_machine=m68k-tti\n\t\t;;\n\tpc532 | pc532-*)\n\t\tbasic_machine=ns32k-pc532\n\t\t;;\n\tpentium | p5 | k5 | k6 | nexgen | viac3)\n\t\tbasic_machine=i586-pc\n\t\t;;\n\tpentiumpro | p6 | 6x86 | athlon | athlon_*)\n\t\tbasic_machine=i686-pc\n\t\t;;\n\tpentiumii | pentium2 | pentiumiii | pentium3)\n\t\tbasic_machine=i686-pc\n\t\t;;\n\tpentium4)\n\t\tbasic_machine=i786-pc\n\t\t;;\n\tpentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)\n\t\tbasic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentiumpro-* | p6-* | 6x86-* | athlon-*)\n\t\tbasic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)\n\t\tbasic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentium4-*)\n\t\tbasic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpn)\n\t\tbasic_machine=pn-gould\n\t\t;;\n\tpower)\tbasic_machine=power-ibm\n\t\t;;\n\tppc)\tbasic_machine=powerpc-unknown\n\t\t;;\n\tppc-*)\tbasic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppcle | powerpclittle | ppc-le | powerpc-little)\n\t\tbasic_machine=powerpcle-unknown\n\t\t;;\n\tppcle-* | powerpclittle-*)\n\t\tbasic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppc64)\tbasic_machine=powerpc64-unknown\n\t\t;;\n\tppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppc64le | powerpc64little | ppc64-le | powerpc64-little)\n\t\tbasic_machine=powerpc64le-unknown\n\t\t;;\n\tppc64le-* | powerpc64little-*)\n\t\tbasic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tps2)\n\t\tbasic_machine=i386-ibm\n\t\t;;\n\tpw32)\n\t\tbasic_machine=i586-unknown\n\t\tos=-pw32\n\t\t;;\n\trom68k)\n\t\tbasic_machine=m68k-rom68k\n\t\tos=-coff\n\t\t;;\n\trm[46]00)\n\t\tbasic_machine=mips-siemens\n\t\t;;\n\trtpc | rtpc-*)\n\t\tbasic_machine=romp-ibm\n\t\t;;\n\ts390 | s390-*)\n\t\tbasic_machine=s390-ibm\n\t\t;;\n\ts390x | s390x-*)\n\t\tbasic_machine=s390x-ibm\n\t\t;;\n\tsa29200)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tsb1)\n\t\tbasic_machine=mipsisa64sb1-unknown\n\t\t;;\n\tsb1el)\n\t\tbasic_machine=mipsisa64sb1el-unknown\n\t\t;;\n\tsei)\n\t\tbasic_machine=mips-sei\n\t\tos=-seiux\n\t\t;;\n\tsequent)\n\t\tbasic_machine=i386-sequent\n\t\t;;\n\tsh)\n\t\tbasic_machine=sh-hitachi\n\t\tos=-hms\n\t\t;;\n\tsh64)\n\t\tbasic_machine=sh64-unknown\n\t\t;;\n\tsparclite-wrs | simso-wrs)\n\t\tbasic_machine=sparclite-wrs\n\t\tos=-vxworks\n\t\t;;\n\tsps7)\n\t\tbasic_machine=m68k-bull\n\t\tos=-sysv2\n\t\t;;\n\tspur)\n\t\tbasic_machine=spur-unknown\n\t\t;;\n\tst2000)\n\t\tbasic_machine=m68k-tandem\n\t\t;;\n\tstratus)\n\t\tbasic_machine=i860-stratus\n\t\tos=-sysv4\n\t\t;;\n\tsun2)\n\t\tbasic_machine=m68000-sun\n\t\t;;\n\tsun2os3)\n\t\tbasic_machine=m68000-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun2os4)\n\t\tbasic_machine=m68000-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun3os3)\n\t\tbasic_machine=m68k-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun3os4)\n\t\tbasic_machine=m68k-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun4os3)\n\t\tbasic_machine=sparc-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun4os4)\n\t\tbasic_machine=sparc-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun4sol2)\n\t\tbasic_machine=sparc-sun\n\t\tos=-solaris2\n\t\t;;\n\tsun3 | sun3-*)\n\t\tbasic_machine=m68k-sun\n\t\t;;\n\tsun4)\n\t\tbasic_machine=sparc-sun\n\t\t;;\n\tsun386 | sun386i | roadrunner)\n\t\tbasic_machine=i386-sun\n\t\t;;\n\tsv1)\n\t\tbasic_machine=sv1-cray\n\t\tos=-unicos\n\t\t;;\n\tsymmetry)\n\t\tbasic_machine=i386-sequent\n\t\tos=-dynix\n\t\t;;\n\tt3e)\n\t\tbasic_machine=alphaev5-cray\n\t\tos=-unicos\n\t\t;;\n\tt90)\n\t\tbasic_machine=t90-cray\n\t\tos=-unicos\n\t\t;;\n\ttic54x | c54x*)\n\t\tbasic_machine=tic54x-unknown\n\t\tos=-coff\n\t\t;;\n\ttic55x | c55x*)\n\t\tbasic_machine=tic55x-unknown\n\t\tos=-coff\n\t\t;;\n\ttic6x | c6x*)\n\t\tbasic_machine=tic6x-unknown\n\t\tos=-coff\n\t\t;;\n\ttx39)\n\t\tbasic_machine=mipstx39-unknown\n\t\t;;\n\ttx39el)\n\t\tbasic_machine=mipstx39el-unknown\n\t\t;;\n\ttoad1)\n\t\tbasic_machine=pdp10-xkl\n\t\tos=-tops20\n\t\t;;\n\ttower | tower-32)\n\t\tbasic_machine=m68k-ncr\n\t\t;;\n\ttpf)\n\t\tbasic_machine=s390x-ibm\n\t\tos=-tpf\n\t\t;;\n\tudi29k)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tultra3)\n\t\tbasic_machine=a29k-nyu\n\t\tos=-sym1\n\t\t;;\n\tv810 | necv810)\n\t\tbasic_machine=v810-nec\n\t\tos=-none\n\t\t;;\n\tvaxv)\n\t\tbasic_machine=vax-dec\n\t\tos=-sysv\n\t\t;;\n\tvms)\n\t\tbasic_machine=vax-dec\n\t\tos=-vms\n\t\t;;\n\tvpp*|vx|vx-*)\n\t\tbasic_machine=f301-fujitsu\n\t\t;;\n\tvxworks960)\n\t\tbasic_machine=i960-wrs\n\t\tos=-vxworks\n\t\t;;\n\tvxworks68)\n\t\tbasic_machine=m68k-wrs\n\t\tos=-vxworks\n\t\t;;\n\tvxworks29k)\n\t\tbasic_machine=a29k-wrs\n\t\tos=-vxworks\n\t\t;;\n\tw65*)\n\t\tbasic_machine=w65-wdc\n\t\tos=-none\n\t\t;;\n\tw89k-*)\n\t\tbasic_machine=hppa1.1-winbond\n\t\tos=-proelf\n\t\t;;\n\txps | xps100)\n\t\tbasic_machine=xps100-honeywell\n\t\t;;\n\tymp)\n\t\tbasic_machine=ymp-cray\n\t\tos=-unicos\n\t\t;;\n\tz8k-*-coff)\n\t\tbasic_machine=z8k-unknown\n\t\tos=-sim\n\t\t;;\n\tnone)\n\t\tbasic_machine=none-none\n\t\tos=-none\n\t\t;;\n\n# Here we handle the default manufacturer of certain CPU types.  It is in\n# some cases the only manufacturer, in others, it is the most popular.\n\tw89k)\n\t\tbasic_machine=hppa1.1-winbond\n\t\t;;\n\top50n)\n\t\tbasic_machine=hppa1.1-oki\n\t\t;;\n\top60c)\n\t\tbasic_machine=hppa1.1-oki\n\t\t;;\n\tromp)\n\t\tbasic_machine=romp-ibm\n\t\t;;\n\trs6000)\n\t\tbasic_machine=rs6000-ibm\n\t\t;;\n\tvax)\n\t\tbasic_machine=vax-dec\n\t\t;;\n\tpdp10)\n\t\t# there are many clones, so DEC is not a safe bet\n\t\tbasic_machine=pdp10-unknown\n\t\t;;\n\tpdp11)\n\t\tbasic_machine=pdp11-dec\n\t\t;;\n\twe32k)\n\t\tbasic_machine=we32k-att\n\t\t;;\n\tsh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)\n\t\tbasic_machine=sh-unknown\n\t\t;;\n\tsh64)\n\t\tbasic_machine=sh64-unknown\n\t\t;;\n\tsparc | sparcv9 | sparcv9b)\n\t\tbasic_machine=sparc-sun\n\t\t;;\n\tcydra)\n\t\tbasic_machine=cydra-cydrome\n\t\t;;\n\torion)\n\t\tbasic_machine=orion-highlevel\n\t\t;;\n\torion105)\n\t\tbasic_machine=clipper-highlevel\n\t\t;;\n\tmac | mpw | mac-mpw)\n\t\tbasic_machine=m68k-apple\n\t\t;;\n\tpmac | pmac-mpw)\n\t\tbasic_machine=powerpc-apple\n\t\t;;\n\t*-unknown)\n\t\t# Make sure to match an already-canonicalized machine name.\n\t\t;;\n\t*)\n\t\techo Invalid configuration \\`$1\\': machine \\`$basic_machine\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\nesac\n\n# Here we canonicalize certain aliases for manufacturers.\ncase $basic_machine in\n\t*-digital*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`\n\t\t;;\n\t*-commodore*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`\n\t\t;;\n\t*)\n\t\t;;\nesac\n\n# Decode manufacturer-specific aliases for certain operating systems.\n\nif [ x\"$os\" != x\"\" ]\nthen\ncase $os in\n        # First match some system type aliases\n        # that might get confused with valid system types.\n\t# -solaris* is a basic system type, with this one exception.\n\t-solaris1 | -solaris1.*)\n\t\tos=`echo $os | sed -e 's|solaris1|sunos4|'`\n\t\t;;\n\t-solaris)\n\t\tos=-solaris2\n\t\t;;\n\t-svr4*)\n\t\tos=-sysv4\n\t\t;;\n\t-unixware*)\n\t\tos=-sysv4.2uw\n\t\t;;\n\t-gnu/linux*)\n\t\tos=`echo $os | sed -e 's|gnu/linux|linux|'`\n\t\t;;\n\t# First accept the basic system types.\n\t# The portable systems comes first.\n\t# Each alternative MUST END IN A *, to match a version number.\n\t# -sysv* is not here because it comes later, after sysvr4.\n\t-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \\\n\t      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\\\n\t      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \\\n\t      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \\\n\t      | -aos* \\\n\t      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \\\n\t      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \\\n\t      | -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \\\n\t      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \\\n\t      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \\\n\t      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \\\n\t      | -chorusos* | -chorusrdb* \\\n\t      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \\\n\t      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \\\n\t      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \\\n\t      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \\\n\t      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \\\n\t      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \\\n\t      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \\\n\t      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)\n\t# Remember, each alternative MUST END IN *, to match a version number.\n\t\t;;\n\t-qnx*)\n\t\tcase $basic_machine in\n\t\t    x86-* | i*86-*)\n\t\t\t;;\n\t\t    *)\n\t\t\tos=-nto$os\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t-nto-qnx*)\n\t\t;;\n\t-nto*)\n\t\tos=`echo $os | sed -e 's|nto|nto-qnx|'`\n\t\t;;\n\t-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \\\n\t      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \\\n\t      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)\n\t\t;;\n\t-mac*)\n\t\tos=`echo $os | sed -e 's|mac|macos|'`\n\t\t;;\n\t-linux-dietlibc)\n\t\tos=-linux-dietlibc\n\t\t;;\n\t-linux*)\n\t\tos=-linux\n\t\t;;\n\t-sunos5*)\n\t\tos=`echo $os | sed -e 's|sunos5|solaris2|'`\n\t\t;;\n\t-sunos6*)\n\t\tos=`echo $os | sed -e 's|sunos6|solaris3|'`\n\t\t;;\n\t-opened*)\n\t\tos=-openedition\n\t\t;;\n        -os400*)\n\t\tos=-os400\n\t\t;;\n\t-wince*)\n\t\tos=-wince\n\t\t;;\n\t-osfrose*)\n\t\tos=-osfrose\n\t\t;;\n\t-osf*)\n\t\tos=-osf\n\t\t;;\n\t-utek*)\n\t\tos=-bsd\n\t\t;;\n\t-dynix*)\n\t\tos=-bsd\n\t\t;;\n\t-acis*)\n\t\tos=-aos\n\t\t;;\n\t-atheos*)\n\t\tos=-atheos\n\t\t;;\n\t-syllable*)\n\t\tos=-syllable\n\t\t;;\n\t-386bsd)\n\t\tos=-bsd\n\t\t;;\n\t-ctix* | -uts*)\n\t\tos=-sysv\n\t\t;;\n\t-nova*)\n\t\tos=-rtmk-nova\n\t\t;;\n\t-ns2 )\n\t\tos=-nextstep2\n\t\t;;\n\t-nsk*)\n\t\tos=-nsk\n\t\t;;\n\t# Preserve the version number of sinix5.\n\t-sinix5.*)\n\t\tos=`echo $os | sed -e 's|sinix|sysv|'`\n\t\t;;\n\t-sinix*)\n\t\tos=-sysv4\n\t\t;;\n        -tpf*)\n\t\tos=-tpf\n\t\t;;\n\t-triton*)\n\t\tos=-sysv3\n\t\t;;\n\t-oss*)\n\t\tos=-sysv3\n\t\t;;\n\t-svr4)\n\t\tos=-sysv4\n\t\t;;\n\t-svr3)\n\t\tos=-sysv3\n\t\t;;\n\t-sysvr4)\n\t\tos=-sysv4\n\t\t;;\n\t# This must come after -sysvr4.\n\t-sysv*)\n\t\t;;\n\t-ose*)\n\t\tos=-ose\n\t\t;;\n\t-es1800*)\n\t\tos=-ose\n\t\t;;\n\t-xenix)\n\t\tos=-xenix\n\t\t;;\n\t-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)\n\t\tos=-mint\n\t\t;;\n\t-aros*)\n\t\tos=-aros\n\t\t;;\n\t-kaos*)\n\t\tos=-kaos\n\t\t;;\n\t-none)\n\t\t;;\n\t*)\n\t\t# Get rid of the `-' at the beginning of $os.\n\t\tos=`echo $os | sed 's/[^-]*-//'`\n\t\techo Invalid configuration \\`$1\\': system \\`$os\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\nesac\nelse\n\n# Here we handle the default operating systems that come with various machines.\n# The value should be what the vendor currently ships out the door with their\n# machine or put another way, the most popular os provided with the machine.\n\n# Note that if you're going to try to match \"-MANUFACTURER\" here (say,\n# \"-sun\"), then you have to tell the case statement up towards the top\n# that MANUFACTURER isn't an operating system.  Otherwise, code above\n# will signal an error saying that MANUFACTURER isn't an operating\n# system, and we'll never get to this point.\n\ncase $basic_machine in\n\t*-acorn)\n\t\tos=-riscix1.2\n\t\t;;\n\tarm*-rebel)\n\t\tos=-linux\n\t\t;;\n\tarm*-semi)\n\t\tos=-aout\n\t\t;;\n    c4x-* | tic4x-*)\n        os=-coff\n        ;;\n\t# This must come before the *-dec entry.\n\tpdp10-*)\n\t\tos=-tops20\n\t\t;;\n\tpdp11-*)\n\t\tos=-none\n\t\t;;\n\t*-dec | vax-*)\n\t\tos=-ultrix4.2\n\t\t;;\n\tm68*-apollo)\n\t\tos=-domain\n\t\t;;\n\ti386-sun)\n\t\tos=-sunos4.0.2\n\t\t;;\n\tm68000-sun)\n\t\tos=-sunos3\n\t\t# This also exists in the configure program, but was not the\n\t\t# default.\n\t\t# os=-sunos4\n\t\t;;\n\tm68*-cisco)\n\t\tos=-aout\n\t\t;;\n\tmips*-cisco)\n\t\tos=-elf\n\t\t;;\n\tmips*-*)\n\t\tos=-elf\n\t\t;;\n\tor32-*)\n\t\tos=-coff\n\t\t;;\n\t*-tti)\t# must be before sparc entry or we get the wrong os.\n\t\tos=-sysv3\n\t\t;;\n\tsparc-* | *-sun)\n\t\tos=-sunos4.1.1\n\t\t;;\n\t*-be)\n\t\tos=-beos\n\t\t;;\n\t*-ibm)\n\t\tos=-aix\n\t\t;;\n\t*-wec)\n\t\tos=-proelf\n\t\t;;\n\t*-winbond)\n\t\tos=-proelf\n\t\t;;\n\t*-oki)\n\t\tos=-proelf\n\t\t;;\n\t*-hp)\n\t\tos=-hpux\n\t\t;;\n\t*-hitachi)\n\t\tos=-hiux\n\t\t;;\n\ti860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)\n\t\tos=-sysv\n\t\t;;\n\t*-cbm)\n\t\tos=-amigaos\n\t\t;;\n\t*-dg)\n\t\tos=-dgux\n\t\t;;\n\t*-dolphin)\n\t\tos=-sysv3\n\t\t;;\n\tm68k-ccur)\n\t\tos=-rtu\n\t\t;;\n\tm88k-omron*)\n\t\tos=-luna\n\t\t;;\n\t*-next )\n\t\tos=-nextstep\n\t\t;;\n\t*-sequent)\n\t\tos=-ptx\n\t\t;;\n\t*-crds)\n\t\tos=-unos\n\t\t;;\n\t*-ns)\n\t\tos=-genix\n\t\t;;\n\ti370-*)\n\t\tos=-mvs\n\t\t;;\n\t*-next)\n\t\tos=-nextstep3\n\t\t;;\n\t*-gould)\n\t\tos=-sysv\n\t\t;;\n\t*-highlevel)\n\t\tos=-bsd\n\t\t;;\n\t*-encore)\n\t\tos=-bsd\n\t\t;;\n\t*-sgi)\n\t\tos=-irix\n\t\t;;\n\t*-siemens)\n\t\tos=-sysv4\n\t\t;;\n\t*-masscomp)\n\t\tos=-rtu\n\t\t;;\n\tf30[01]-fujitsu | f700-fujitsu)\n\t\tos=-uxpv\n\t\t;;\n\t*-rom68k)\n\t\tos=-coff\n\t\t;;\n\t*-*bug)\n\t\tos=-coff\n\t\t;;\n\t*-apple)\n\t\tos=-macos\n\t\t;;\n\t*-atari*)\n\t\tos=-mint\n\t\t;;\n\t*)\n\t\tos=-none\n\t\t;;\nesac\nfi\n\n# Here we handle the case where we know the os, and the CPU type, but not the\n# manufacturer.  We pick the logical manufacturer.\nvendor=unknown\ncase $basic_machine in\n\t*-unknown)\n\t\tcase $os in\n\t\t\t-riscix*)\n\t\t\t\tvendor=acorn\n\t\t\t\t;;\n\t\t\t-sunos*)\n\t\t\t\tvendor=sun\n\t\t\t\t;;\n\t\t\t-aix*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-beos*)\n\t\t\t\tvendor=be\n\t\t\t\t;;\n\t\t\t-hpux*)\n\t\t\t\tvendor=hp\n\t\t\t\t;;\n\t\t\t-mpeix*)\n\t\t\t\tvendor=hp\n\t\t\t\t;;\n\t\t\t-hiux*)\n\t\t\t\tvendor=hitachi\n\t\t\t\t;;\n\t\t\t-unos*)\n\t\t\t\tvendor=crds\n\t\t\t\t;;\n\t\t\t-dgux*)\n\t\t\t\tvendor=dg\n\t\t\t\t;;\n\t\t\t-luna*)\n\t\t\t\tvendor=omron\n\t\t\t\t;;\n\t\t\t-genix*)\n\t\t\t\tvendor=ns\n\t\t\t\t;;\n\t\t\t-mvs* | -opened*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-os400*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-ptx*)\n\t\t\t\tvendor=sequent\n\t\t\t\t;;\n\t\t\t-tpf*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-vxsim* | -vxworks* | -windiss*)\n\t\t\t\tvendor=wrs\n\t\t\t\t;;\n\t\t\t-aux*)\n\t\t\t\tvendor=apple\n\t\t\t\t;;\n\t\t\t-hms*)\n\t\t\t\tvendor=hitachi\n\t\t\t\t;;\n\t\t\t-mpw* | -macos*)\n\t\t\t\tvendor=apple\n\t\t\t\t;;\n\t\t\t-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)\n\t\t\t\tvendor=atari\n\t\t\t\t;;\n\t\t\t-vos*)\n\t\t\t\tvendor=stratus\n\t\t\t\t;;\n\t\tesac\n\t\tbasic_machine=`echo $basic_machine | sed \"s/unknown/$vendor/\"`\n\t\t;;\nesac\n\necho $basic_machine$os\nexit 0\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"timestamp='\"\n# time-stamp-format: \"%:y-%02m-%02d\"\n# time-stamp-end: \"'\"\n# End:\n"
  },
  {
    "path": "configure.in",
    "content": "dnl Process this file with autoconf to produce a configure script.\nAC_INIT()\n\nAC_PREREQ(2.58)\n\nAC_DEFUN([RUBY_MINGW32],\n[case \"$host_os\" in\ncygwin*)\nAC_CACHE_CHECK(for mingw32 environment, rb_cv_mingw32,\n[AC_TRY_CPP([\n#ifndef __MINGW32__\n# error\n#endif\n], rb_cv_mingw32=yes,rb_cv_mingw32=no)\nrm -f conftest*])\ntest \"$rb_cv_mingw32\" = yes && target_os=\"mingw32\"\n  ;;\nesac])\n\nAC_DEFUN([RUBY_CPPOUTFILE],\n[AC_CACHE_CHECK(whether ${CPP} accepts -o, rb_cv_cppoutfile,\n[cppflags=$CPPFLAGS\nCPPFLAGS='-o conftest.i'\nAC_TRY_CPP([], rb_cv_cppoutfile=yes, rb_cv_cppoutfile=no)\nCPPFLAGS=$cppflags\nrm -f conftest*])\nif test \"$rb_cv_cppoutfile\" = yes; then\n  CPPOUTFILE='-o conftest.i'\nelif test \"$rb_cv_cppoutfile\" = no; then\n  CPPOUTFILE='> conftest.i'\nelif test -n \"$rb_cv_cppoutfile\"; then\n  CPPOUTFILE=\"$rb_cv_cppoutfile\"\nfi\nAC_SUBST(CPPOUTFILE)])\n\nAC_DEFUN([RUBY_PROG_GNU_LD],\n[AC_CACHE_CHECK(whether the linker is GNU ld, rb_cv_prog_gnu_ld,\n[if `$CC $CFLAGS $CPPFLAGS $LDFLAGS --print-prog-name=ld 2>&1` -v 2>&1 | grep \"GNU ld\" > /dev/null; then\n  rb_cv_prog_gnu_ld=yes\nelse\n  rb_cv_prog_gnu_ld=no\nfi\n])\nGNU_LD=$rb_cv_prog_gnu_ld\nAC_SUBST(GNU_LD)])\n\nunset GREP_OPTIONS\nrb_version=`grep RUBY_VERSION $srcdir/version.h`\nMAJOR=`expr \"$rb_version\" : '#define RUBY_VERSION \"\\([0-9][0-9]*\\)\\.[0-9][0-9]*\\.[0-9][0-9]*\"'`\nMINOR=`expr \"$rb_version\" : '#define RUBY_VERSION \"[0-9][0-9]*\\.\\([0-9][0-9]*\\)\\.[0-9][0-9]*\"'`\nTEENY=`expr \"$rb_version\" : '#define RUBY_VERSION \"[0-9][0-9]*\\.[0-9][0-9]*\\.\\([0-9][0-9]*\\)\"'`\nif test \"$MAJOR\" = \"\"; then\n  AC_MSG_ERROR(could not determine MAJOR number from version.h)\nfi\nif test \"$MINOR\" = \"\"; then\n  AC_MSG_ERROR(could not determine MINOR number from version.h)\nfi\nif test \"$TEENY\" = \"\"; then\n  AC_MSG_ERROR(could not determine TEENY number from version.h)\nfi\nAC_SUBST(MAJOR)\nAC_SUBST(MINOR)\nAC_SUBST(TEENY)\ndnl checks for alternative programs\nAC_ARG_WITH(gcc, [  --without-gcc           never use gcc], [\n\tcase $withval in\n\tno)\t: ${CC=cc}\n\t\t;;\n\tyes)\t: ${CC=gcc}\n\t\t;;\n\t*)\tCC=$withval\n\t\t;;\n\tesac])\ndnl If the user switches compilers, we can't believe the cache\nif test ! -z \"$ac_cv_prog_CC\" -a ! -z \"$CC\" -a \"$CC\" != \"$ac_cv_prog_CC\"\nthen\n  AC_MSG_ERROR(cached CC is different -- throw away $cache_file\n(it is also a good idea to do 'make clean' before compiling))\nfi\ntest -z \"$CC\" || ac_cv_prog_CC=\"$CC\"\n\nif test \"$program_prefix\" = NONE; then\n  program_prefix=\nfi\nAC_CANONICAL_TARGET\ntarget_os=`echo $target_os | sed 's/linux-gnu$/linux/;s/linux-gnu/linux-/'`\nac_install_sh='' # unusable for extension libraries.\n\nifelse(currently,disabled, [\ndnl checks for fat-binary\nAC_ARG_ENABLE(fat-binary,\n       [  --enable-fat-binary=ARCHS\n                          build an Apple/NeXT Multi Architecture Binary (MAB);\n                          ARCHS is a comma-delimited list of architectures for\n                          which to build; if ARCHS is omitted, then the package\n                          will be built for all architectures supported by the\n                          platform (\"ppc\" for MacOS/X and Darwin; \"ppc,i386\"\n                          for Rhapsody; \"m68k,i386,sparc\" for OpenStep;\n                          \"m68k,i386,sparc,hppa\" for NextStep); if this option\n                          is disabled or omitted entirely, then the package\n                          will be built only for the target platform],\n       [fat_binary=$enableval], [fat_binary=no])\nif test \"$fat_binary\" != no; then\n\n    AC_MSG_CHECKING([target architectures])\n\n    # Respect TARGET_ARCHS setting from environment if available.\n    if test -z \"$TARGET_ARCHS\"; then\n\t# Respect ARCH given to --enable-fat-binary if present.\n\tif test \"$fat_binary\" != yes; then\n\t    TARGET_ARCHS=`echo \"$fat_binary\" | tr ',' ' '`\n\telse\n\t    # Choose a default set of architectures based upon platform.\n\t    case \"$target_os\" in\n\t    darwin*)\n\t\tTARGET_ARCHS=\"ppc\"\n\t\t;;\n\t    rhapsody*)\n\t\tTARGET_ARCHS=\"ppc i386\"\n\t\t;;\n\t    openstep*)\n\t\tTARGET_ARCHS=\"m68k i386 sparc\"\n\t\t;;\n\t    nextstep*)\n\t\tTARGET_ARCHS=\"m68k i386 sparc hppa\"\n\t\t;;\n\t    *)\n\t\tTARGET_ARCHS=`arch`\n\t    esac\n\tfi\n    fi\n\n    AC_MSG_RESULT([$TARGET_ARCHS])\n\n    # /usr/lib/arch_tool -archify_list $TARGET_ARCHS\n    ARCH_FLAG=\n    for archs in $TARGET_ARCHS\n    do\n        ARCH_FLAG=\"$ARCH_FLAG -arch $archs\"\n    done\n    AC_DEFINE(NEXT_FAT_BINARY)\nfi\n], [fat_binary=no])\n\ncase $target_cpu in\n  i?86) frame_address=yes;;\n  *)    frame_address=no;;\nesac\nAC_ARG_ENABLE(frame-address,\n       [  --enable-frame-address  use GCC __builtin_frame_address(). ],\n       [frame_address=$enableval])\nif test $frame_address = yes; then\n    AC_DEFINE(USE_BUILTIN_FRAME_ADDRESS)\nfi\nAC_ARG_ENABLE(gc-debug,\n       [  --enable-gc-debug       enable additional GC API methods, debugging, and statistics. ],\n       [gc_debug=$enableval])\nif test \"$gc_debug\" = yes; then\n    AC_DEFINE(GC_DEBUG)\nfi\nAC_ARG_WITH(wipe-sites,\n[  --with-wipe-sites=MASK  override default STACK_WIPES_SITES mask in rubysig.h],\n[wipe_sites=$withval])\nif test \"$wipe_sites\" != \"\"; then\n  case $wipe_sites in\n       none|no)  wipe_sites=0x0;;\n       yes) wipe_sites=;;\n  esac\n  if test -n \"$wipe_sites\"; then\n    AC_DEFINE_UNQUOTED(STACK_WIPE_SITES,$wipe_sites)\n  fi\nfi\n\nAC_ARG_PROGRAM\n\ndnl Checks for programs.\n\nif test x\"${build}\" != x\"${host}\"; then\n  AC_CHECK_TOOL(CC, gcc)\nfi\nAC_PROG_CC\nAC_PROG_GCC_TRADITIONAL\nif test \"$GCC\" = yes; then\n    linker_flag=-Wl,\nelse\n    linker_flag=\nfi\n\nRUBY_PROG_GNU_LD\nRUBY_CPPOUTFILE\n\n: ${OUTFLAG='-o '}\nAC_SUBST(OUTFLAG)\n\nRUBY_MINGW32\n\nAC_PROG_YACC\nif test \"$YACC\" = \"yacc\"; then\n  AC_DEFINE([OLD_YACC])\nfi\n\nAC_CHECK_TOOL(RANLIB, ranlib, :)\nAC_CHECK_TOOL(AR, ar)\nif test -z \"$AR\"; then\n  AC_CHECK_PROGS(AR, aal, ar)\nfi\n\nAC_CHECK_TOOL(AS, as)\nASFLAGS=$ASFLAGS\nAC_SUBST(ASFLAGS)\n\ncase \"$target_os\" in\ncygwin*|mingw*)\n    AC_CHECK_TOOL(NM, nm)\n    AC_CHECK_TOOL(WINDRES, windres)\n    AC_CHECK_TOOL(DLLWRAP, dllwrap)\n    target_cpu=`echo $target_cpu | sed s/i.86/i386/`\n    case \"$target_os\" in\n    mingw*)\n\ttest \"$rb_cv_msvcrt\" = \"\" && unset rb_cv_msvcrt\n\tAC_CHECK_TOOL(OBJDUMP, objdump)\n\tAC_CACHE_CHECK(for mingw32 runtime DLL, rb_cv_msvcrt, [\n\tAC_TRY_LINK([#include <stdio.h>],\n\t\t    [FILE* volatile f = stdin; return 0;],\n\t\t    [rb_cv_msvcrt=`$OBJDUMP -p conftest$ac_exeext |\n\t\t\t\t   tr A-Z a-z |\n\t\t\t\t   sed -n '/^[[ \t]]*dll name: \\(msvc.*\\)\\.dll$/{s//\\1/p;q;}'`],\n\t\t    [rb_cv_msvcrt=msvcrt])\n\ttest \"$rb_cv_msvcrt\" = \"\" && rb_cv_msvcrt=msvcrt])\n\tAC_ARG_WITH(winsock2,\n\t\t[  --with-winsock2         link winsock2 (MinGW only)], [\n\t\tcase $withval in\n\t\tyes) with_winsock2=yes;;\n\t\t*)   with_winsock2=no;;\n\t\tesac], [with_winsock2=no])\n\tif test \"$with_winsock2\" = yes; then\n\t  AC_DEFINE(USE_WINSOCK2)\n\tfi\n    esac\n    : ${enable_shared=yes}\n    ;;\naix*)\n    AC_CHECK_TOOL(NM, nm, /usr/ccs/bin/nm, /usr/ccs/bin:$PATH)\n    ;;\nhiuxmpp*)\n    # by TOYODA Eizi <toyoda@npd.kishou.go.jp>\n    AC_DEFINE(__HIUX_MPP__)\n    ;;\nesac\n\nAC_PROG_LN_S\nAC_PROG_MAKE_SET\nAC_PROG_INSTALL\n\n# checks for UNIX variants that set C preprocessor variables\nAC_AIX\nAC_MINIX\n\nAC_SUBST(RM, ['rm -f'])\nAC_SUBST(CP, ['cp'])\nif $as_mkdir_p; then\n  AC_SUBST(MAKEDIRS, ['mkdir -p'])\nelse\n  AC_SUBST(MAKEDIRS, ['install -d'])\nfi\n\ndnl check for large file stuff\nmv confdefs.h confdefs1.h\n: > confdefs.h\nAC_SYS_LARGEFILE\nmv confdefs.h largefile.h\nmv confdefs1.h confdefs.h\ncat largefile.h >> confdefs.h\n\nAC_CHECK_TYPES([long long, off_t])\n\nAC_CHECK_SIZEOF(int, 4)\nAC_CHECK_SIZEOF(short, 2)\nAC_CHECK_SIZEOF(long, 4)\nAC_CHECK_SIZEOF(long long, 0)\nAC_CHECK_SIZEOF(__int64, 0)\nAC_CHECK_SIZEOF(off_t, 0)\nAC_CHECK_SIZEOF(void*, 4)\nAC_CHECK_SIZEOF(float, 4)\nAC_CHECK_SIZEOF(double, 8)\nAC_CHECK_SIZEOF(time_t, 0)\n\nfor id in pid_t gid_t uid_t; do\n    AC_CHECK_TYPE($id, [typ=$id], [typ=int])\n    AC_DEFINE_UNQUOTED(rb_$id, $typ)\ndone\n\nAC_CACHE_CHECK(for prototypes, rb_cv_have_prototypes,\n  [AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);],\n\trb_cv_have_prototypes=yes,\n\trb_cv_have_prototypes=no)])\nif test \"$rb_cv_have_prototypes\" = yes; then\n  AC_DEFINE(HAVE_PROTOTYPES)\nfi\n\nAC_CACHE_CHECK(token paste string, rb_cv_tokenpaste,\n  [AC_TRY_COMPILE([#define paste(a,b) a##b],\n\t\t  [int xy = 1; return paste(x,y);],\n\t\t  rb_cv_tokenpaste=ansi,\n\t\t  rb_cv_tokenpaste=knr)])\nif test \"$rb_cv_tokenpaste\" = ansi; then\n  AC_DEFINE(TOKEN_PASTE(x,y),[x##y])\nelse\n  AC_DEFINE(TOKEN_PASTE(x,y),[x/**/y])\nfi\n\nAC_CACHE_CHECK(for variable length prototypes and stdarg.h, rb_cv_stdarg,\n  [AC_TRY_COMPILE([\n#include <stdarg.h>\nint foo(int x, ...) {\n\tva_list va;\n\tva_start(va, x);\n\tva_arg(va, int);\n\tva_arg(va, char *);\n\tva_arg(va, double);\n\treturn 0;\n}\n], [return foo(10, \"\", 3.14);],\n\trb_cv_stdarg=yes,\n\trb_cv_stdarg=no)])\nif test \"$rb_cv_stdarg\" = yes; then\n  AC_DEFINE(HAVE_STDARG_PROTOTYPES)\nfi\n\nAC_DEFUN([RUBY_FUNC_ATTRIBUTE], [dnl\nm4_ifval([$2], dnl\n  [AS_VAR_PUSHDEF([attrib],[$2])], dnl\n  [AS_VAR_PUSHDEF([attrib],[FUNC_]AS_TR_CPP($1))] dnl\n)dnl\nm4_ifval([$3], dnl\n  [AS_VAR_PUSHDEF([rbcv],[$3])], dnl\n  [AS_VAR_PUSHDEF([rbcv],[rb_cv_func_][$1])]dnl\n)dnl\nAC_CACHE_CHECK(for [$1] function attribute, rbcv,\n[rbcv=x\nif test \"${ac_c_werror_flag+set}\"; then\n  rb_c_werror_flag=\"$ac_c_werror_flag\"\nelse\n  unset rb_c_werror_flag\nfi\nac_c_werror_flag=yes\nfor mac in \"__attribute__ (($1)) x\" \"x __attribute__ (($1))\" \"__declspec($1) x\" x; do\n  AC_TRY_COMPILE(\n    [#define ]attrib[(x) $mac\n    ]attrib[(void conftest_attribute_check(void));], [],\n    [rbcv=\"$mac\"; break])\ndone\nif test \"${rb_c_werror_flag+set}\"; then\n  ac_c_werror_flag=\"$rb_c_werror_flag\"\nelse\n  unset ac_c_werror_flag\nfi\n])\nAC_DEFINE_UNQUOTED(attrib[(x)], $rbcv)\nAS_VAR_POPDEF([attrib])\nAS_VAR_POPDEF([rbcv])\n])\n\nRUBY_FUNC_ATTRIBUTE(noreturn, NORETURN)\nRUBY_FUNC_ATTRIBUTE(noinline, NOINLINE)\n\nAC_CACHE_CHECK([for RUBY_EXTERN], rb_cv_ruby_extern,\n[rb_cv_ruby_extern=no\nfor mac in \"__attribute__((dllimport))\" \"__declspec(dllimport)\"; do\n  AC_TRY_COMPILE(\n    [extern $mac void conftest(void);],\n    [rb_cv_ruby_extern=\"extern $mac\"; break])\ndone])\ntest \"x$rb_cv_ruby_extern\" = xno || AC_DEFINE_UNQUOTED(RUBY_EXTERN, $rb_cv_ruby_extern)\n\nXCFLAGS=\"$XCFLAGS -DRUBY_EXPORT\"\n\ndnl Check whether we need to define sys_nerr locally\nAC_CHECK_DECLS([sys_nerr], [], [], [$ac_includes_default\n#include <errno.h>])\n\ndnl whether link libc_r or not\nAC_ARG_WITH(libc_r,\n\t[  --with-libc_r           link libc_r if possible (FreeBSD only)], [\n\tcase $withval in\n\tyes) with_libc_r=yes;;\n\t*)   with_libc_r=no;;\n\tesac], [with_libc_r=no])\n\nAC_ARG_ENABLE(ucontext,\n        [  --disable-ucontext      do not use getcontext()/setcontext().],\n        [disable_ucontext=yes], [disable_ucontext=no])\n\nAC_ARG_ENABLE(pthread,\n       [  --enable-pthread        use pthread library.],\n       [enable_pthread=$enableval], [enable_pthread=no])\n\nAC_ARG_ENABLE(fastthread,\n       [  --disable-fastthread    do not use the fastthread mutex], [\n\t: handled by ext/thread/extconf.rb\n        ])\n\ndnl Checks for libraries.\ncase \"$target_os\" in\nnextstep*)\t;;\nopenstep*)\t;;\nrhapsody*)\t;;\ndarwin*)\tLIBS=\"-lobjc $LIBS\"\n\t\tCPPFLAGS=\"$CPPFLAGS -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE\"\n\t\tAC_TRY_CPP([#include <AvailabilityMacros.h>\n\t\t    #if MAC_OS_X_VERSION_MAX_ALLOWED <= 1040\n\t\t    #error pre OS X 10.4\n\t\t    [!<===== pre OS X 10.4 =====>]\n\t\t    #endif\n\t\t    ],\n\t\t    [\n\t\t    test \"x$target_cpu\" = xpowerpc && ac_cv_header_ucontext_h=no\n\t\t    ],\n\t\t    [\n\t\t    AC_DEFINE(BROKEN_SETREUID, 1)\n\t\t    AC_DEFINE(BROKEN_SETREGID, 1)\n\t\t    ])\n\t\t;;\nhpux*)\t\tLIBS=\"-lm $LIBS\"\n\t\tac_cv_c_inline=no;;\nhuman*)\t\tac_cv_func_getpgrp_void=yes\n\t\tac_cv_func_setitimer=no\n\t\t;;\nbeos*)\t\tac_cv_func_link=no;;\ncygwin*)\t;;\nmingw*)\t\tif test \"$with_winsock2\" = yes; then\n\t\t  LIBS=\"-lws2_32 $LIBS\"\n\t\telse\n\t\t  LIBS=\"-lwsock32 $LIBS\"\n\t\tfi\n\t\tLIBS=\"-lshell32 $LIBS\"\n\t\tac_cv_header_a_out_h=no\n\t\tac_cv_header_pwd_h=no\n\t\tac_cv_header_utime_h=no\n\t\tac_cv_header_sys_ioctl_h=no\n\t\tac_cv_header_sys_param_h=no\n\t\tac_cv_header_sys_resource_h=no\n\t\tac_cv_header_sys_select_h=no\n\t\tac_cv_header_sys_time_h=no\n\t\tac_cv_header_sys_times_h=no\n\t\tac_cv_func_times=yes\n\t\tac_cv_func_waitpid=yes\n\t\tac_cv_func_fsync=yes\n\t\tac_cv_func_vsnprintf=yes\n\t\tac_cv_func_seekdir=yes\n\t\tac_cv_func_telldir=yes\n\t\tac_cv_func_isinf=yes\n\t\tac_cv_func_isnan=yes\n\t\tac_cv_func_finite=yes\n\t\tac_cv_func_link=yes\n\t\tac_cv_lib_crypt_crypt=no\n\t\tac_cv_func_getpgrp_void=no\n\t\tac_cv_func_setpgrp_void=yes\n\t\tac_cv_func_memcmp_working=yes\n\t\tac_cv_lib_dl_dlopen=no\n\t\trb_cv_binary_elf=no\n\t\trb_cv_negative_time_t=no\n\t\tenable_pthread=no\n\t\tac_cv_func_fcntl=yes\n\t\t;;\nos2-emx*)\tLIBS=\"-lm $LIBS\"\n\t\tac_cv_lib_dir_opendir=no;;\nmsdosdjgpp*)\tLIBS=\"-lm $LIBS\"\n\t\tac_cv_func_getpgrp_void=yes\n\t\tac_cv_func_setitimer=no\n                ac_cv_sizeof_rlim_t=4\n\t\tac_cv_func_setrlimit=no\n\t\t;;\nbsdi*)          LIBS=\"-lm $LIBS\"\n\t\tAC_DEFINE(BROKEN_SETREUID, 1)\n\t\tAC_DEFINE(BROKEN_SETREGID, 1)\n                ac_cv_sizeof_rlim_t=8;;\nfreebsd*)\tLIBS=\"-lm $LIBS\"\n\t\tAC_CACHE_CHECK([whether -lxpg4 has to be linked],\n\t\t  rb_cv_lib_xpg4_needed,\n\t\t  [AC_TRY_CPP([\n#include <osreldate.h>\n#if __FreeBSD_version < 400020 || \\\n   (__FreeBSD_version >= 500000 && __FreeBSD_version < 500005)\n#error needs libxpg4\n#endif\n\t\t   ],\n\t\t   rb_cv_lib_xpg4_needed=no,\n\t\t   rb_cv_lib_xpg4_needed=yes,\n\t\t   rb_cv_lib_xpg4_needed=yes)])\n\t\tif test \"$rb_cv_lib_xpg4_needed\" = yes; then\n\t\t\tAC_CHECK_LIB(xpg4, setlocale)\n\t\tfi\n\t\tif test \"$with_libc_r\" = yes; then\n\t\t\tAC_CACHE_CHECK([whether libc_r is supplementary to libc],\n\t\t\t  rb_cv_supplementary_lib_c_r,\n\t\t\t  [AC_TRY_CPP([\n#include <osreldate.h>\n#if 500016 <= __FreeBSD_version\n#error libc_r is supplementary to libc\n#endif\n\t\t\t   ],\n\t\t\t   rb_cv_supplementary_lib_c_r=no,\n\t\t\t   rb_cv_supplementary_lib_c_r=yes,\n\t\t\t   rb_cv_supplementary_lib_c_r=yes)])\n\t\t\tif test \"$rb_cv_supplementary_lib_c_r\" = yes; then\n\t\t\t   MAINLIBS=\"-lc_r $MAINLIBS\"\n\t\t\tfi\n\t\tfi\n\t\t;;\ndragonfly*)\tLIBS=\"-lm $LIBS\"\n\t\t;;\nbow)\t\tac_cv_func_setitimer=no\n\t\t;;\nsuperux*)     ac_cv_func_setitimer=no\n              ;;\nsolaris*2.1*) if test -z \"$GCC\"; then\n\t           ac_cv_func_isinf=yes\n              fi\n              LIBS=\"-lm $LIBS\"\n              ;;\n*) LIBS=\"-lm $LIBS\";;\nesac\nAC_CHECK_LIB(crypt, crypt)\nAC_CHECK_LIB(dl, dlopen)\t# Dynamic linking for SunOS/Solaris and SYSV\nAC_CHECK_LIB(dld, shl_load)\t# Dynamic linking for HP-UX\nAC_CHECK_LIB(rt, clock_gettime)\t# GNU/Linux\n\ncase \"$target_cpu\" in\nalpha*)\t\tcase \"$target_os\"::\"$GCC\" in\n\t\t*::yes)\tCFLAGS=\"-mieee $CFLAGS\" ;;   # gcc\n\t\tosf*)   CFLAGS=\"-ieee $CFLAGS\" ;;    # ccc\n\t\tesac ;;\nesac\n\ndnl Checks for header files.\nAC_HEADER_DIRENT\nAC_HEADER_STDC\nAC_HEADER_SYS_WAIT\nAC_CHECK_HEADERS(stdlib.h string.h unistd.h limits.h sys/file.h sys/ioctl.h sys/syscall.h\\\n\t\t fcntl.h sys/fcntl.h sys/select.h sys/time.h sys/times.h sys/param.h\\\n\t\t syscall.h pwd.h grp.h a.out.h utime.h memory.h direct.h sys/resource.h \\\n\t\t sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \\\n\t\t ucontext.h intrinsics.h)\n\ndnl Check additional types.\nAC_CHECK_SIZEOF(rlim_t, 0, [\n  #ifdef HAVE_SYS_TYPES_H\n  # include <sys/types.h>\n  #endif\n  #ifdef HAVE_SYS_TIME_H\n  # include <sys/time.h>\n  #endif\n  #ifdef HAVE_SYS_RESOURCE_H\n  # include <sys/resource.h>\n  #endif\n  #ifdef HAVE_UNISTD_H\n  # include <unistd.h>\n  #endif\n  #include <stdio.h>\n])\n\ndnl Checks for typedefs, structures, and compiler characteristics.\nAC_TYPE_SIZE_T\nAC_STRUCT_ST_BLKSIZE\nAC_STRUCT_ST_BLOCKS\nAC_STRUCT_ST_RDEV\n\ndnl Checks for library functions.\nAC_TYPE_GETGROUPS\nAC_TYPE_SIGNAL\ncase \"${target_cpu}-${target_os}\" in\npowerpc-darwin*)\n  AC_LIBSOURCES(alloca.c)\n  AC_SUBST([ALLOCA], [\\${LIBOBJDIR}alloca.${ac_objext}])\n  AC_DEFINE(C_ALLOCA)\n  AC_DEFINE_UNQUOTED(alloca, alloca)\n  ;;\n*)\n  AC_FUNC_ALLOCA\n  ;;\nesac\nAC_FUNC_MEMCMP\nAC_FUNC_FSEEKO\nAC_CHECK_FUNCS(ftello)\n\n# http://sources.redhat.com/ml/libc-hacker/2005-08/msg00008.html\n# Debian GNU/Linux Etch's libc6.1 2.3.6.ds1-13etch5 has this problem.\n# Debian GNU/Linux Lenny's libc6.1 2.7-10 has no problem.\nAC_CACHE_CHECK(for broken erfc of glibc-2.3.6 on IA64, rb_cv_broken_glibc_ia64_erfc,\n  [AC_TRY_RUN([\n#include <math.h>\nint\nmain()\n{\n   erfc(10000.0);\n   return 0;\n}\n],\n\trb_cv_broken_glibc_ia64_erfc=no,\n\trb_cv_broken_glibc_ia64_erfc=yes,\n\trb_cv_broken_glibc_ia64_erfc=no)])\ncase $rb_cv_broken_glibc_ia64_erfc in\n  yes) ac_cv_func_erf=no;;\nesac\n\nAC_REPLACE_FUNCS(dup2 memmove strcasecmp strncasecmp strerror strftime\\\n\t\t strchr strstr strtoul crypt flock vsnprintf\\\n\t\t isnan finite isinf hypot acosh erf)\nAC_CHECK_FUNCS(fmod killpg wait4 waitpid syscall chroot fsync getcwd eaccess\\\n\t      truncate ftruncate chsize times utimes fcntl lockf lstat symlink link\\\n\t      readlink setitimer setruid seteuid setreuid setresuid\\\n\t      setproctitle setrgid setegid setregid setresgid issetugid pause\\\n\t      lchown lchmod getpgrp setpgrp getpgid setpgid initgroups\\\n\t      getgroups setgroups getpriority getrlimit setrlimit sysconf\\\n\t      group_member dlopen sigprocmask\\\n\t      sigaction sigsetjmp _setjmp _longjmp setsid telldir seekdir fchmod\\\n\t      mktime timegm gettimeofday\\\n\t      cosh sinh tanh round setuid setgid setenv unsetenv)\n\nAC_CACHE_CHECK(for __builtin_setjmp, ac_cv_func___builtin_setjmp,\n[AC_TRY_LINK([@%:@include <setjmp.h>\n    jmp_buf jb; void t(v) int v; {__builtin_longjmp(jb, v);}],\n    [__builtin_setjmp(jb);],\n    [ac_cv_func___builtin_setjmp=yes],\n    [ac_cv_func___builtin_setjmp=no])\n])\n\ntest x$ac_cv_func__longjmp = xno && ac_cv_func__setjmp=no\n\nAC_MSG_CHECKING(for setjmp type)\nAC_ARG_WITH(setjmp-type,\n\t[  --with-setjmp-type      select setjmp type], [\n\tcase $withval in\n\t__builtin_setjmp) setjmp_prefix=__builtin_;;\n\t_setjmp) setjmp_prefix=_;;\n\tsigsetjmp) setjmp_prefix=sig;;\n\tsetjmp) setjmp_prefix=;;\n\t'') unset setjmp_prefix;;\n\t*)   AC_MSG_ERROR(invalid setjmp type: $withval);;\n\tesac], [unset setjmp_prefix])\nif test ${setjmp_prefix+set}; then\n    if test \"${setjmp_prefix}\" && eval test '$ac_cv_func_'${setjmp_prefix}setjmp = no; then\n\tAC_MSG_ERROR(${setjmp_prefix}setjmp is not available)\n    fi\nelif test \"$ac_cv_func___builtin_setjmp\" = yes; then\n    setjmp_prefix=__builtin_\nelif test \"$ac_cv_func__setjmp\" = yes; then\n    setjmp_prefix=_\nelif test \"$ac_cv_func_sigsetjmp\" = yes; then\n    case $target_os in\n    solaris*|cygwin*)\n\tsetjmp_prefix=;;\n    *)\n\tsetjmp_prefix=sig;;\n    esac\nelse\n    setjmp_prefix=\nfi\nif test x$setjmp_prefix = xsig; then\n    setjmp_sigmask=yes\nelse\n    unset setjmp_sigmask\nfi\nAC_MSG_RESULT(${setjmp_prefix}setjmp)\nAC_DEFINE_UNQUOTED([RUBY_SETJMP(env)], [${setjmp_prefix}setjmp(env${setjmp_sigmask+,0})])\nAC_DEFINE_UNQUOTED([RUBY_LONGJMP(env,val)], [${setjmp_prefix}longjmp(env,val)])\nAC_DEFINE_UNQUOTED(RUBY_JMP_BUF, ${setjmp_sigmask+${setjmp_prefix}}jmp_buf)\n\nAC_ARG_ENABLE(setreuid,\n       [  --enable-setreuid       use setreuid()/setregid() according to need even if obsolete.],\n       [use_setreuid=$enableval])\nif test \"$use_setreuid\" = yes; then\n    AC_DEFINE(USE_SETREUID)\n    AC_DEFINE(USE_SETREGID)\nfi\nAC_STRUCT_TIMEZONE\nAC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,\n  [AC_TRY_COMPILE([#include <time.h>],\n    [struct tm t; t.tm_gmtoff = 3600;],\n  [rb_cv_member_struct_tm_tm_gmtoff=yes],\n  [rb_cv_member_struct_tm_tm_gmtoff=no])])\nif test \"$rb_cv_member_struct_tm_tm_gmtoff\" = yes; then\n  AC_DEFINE(HAVE_STRUCT_TM_TM_GMTOFF)\nfi\nAC_CACHE_CHECK(for external int daylight, rb_cv_have_daylight,\n  [AC_TRY_LINK([#include <time.h>\n  int i;],\n  \t[i = daylight;],\n\trb_cv_have_daylight=yes,\n\trb_cv_have_daylight=no)])\nif test \"$rb_cv_have_daylight\" = yes; then\n  AC_DEFINE(HAVE_DAYLIGHT)\nfi\nAC_DEFUN([RUBY_CHECK_VARTYPE], [dnl\nAC_CACHE_CHECK([for external $1], rb_cv_var_$1,\n  [rb_cv_var_$1=no\n  AC_TRY_COMPILE([\n#ifndef _XOPEN_SOURCE\n#define _XOPEN_SOURCE 1\n#endif\n$2\n;\nconst volatile void *volatile t;],\n    [t = &(&$1)[0];],\n    [for t in $3; do\n      AC_TRY_COMPILE([\n#ifndef _XOPEN_SOURCE\n#define _XOPEN_SOURCE 1\n#endif\n$2\n;\nextern $t $1;\nconst volatile void *volatile t;],\n        [t = &(&$1)[0];],\n        [rb_cv_var_$1=$t; break])\n    done])])\nif test \"[$rb_cv_var_]$1\" != no; then\n  AC_DEFINE([HAVE_VAR_]m4_toupper($1))\n  AC_DEFINE_UNQUOTED([TYPEOF_VAR_]m4_toupper($1), $rb_cv_var_$1)\nfi])\nRUBY_CHECK_VARTYPE(timezone, [@%:@include <time.h>], [long int])\nRUBY_CHECK_VARTYPE(altzone, [@%:@include <time.h>], [long int])\nif test \"$rb_cv_var_timezone\" = no; then\n  AC_CHECK_FUNCS(timezone)\n  if test \"$ac_cv_func_timezone\" = yes; then\n    AC_CACHE_CHECK([whether timezone requires zero arguments], rb_cv_func_timezone_void,\n      [AC_TRY_COMPILE([@%:@include <time.h>],\n\t[(void)timezone(0, 0);],\n\t[rb_cv_func_timezone_void=no],\n\t[rb_cv_func_timezone_void=yes])]\n    )\n    if test $rb_cv_func_timezone_void = yes; then\n      AC_DEFINE(TIMEZONE_VOID)\n    fi\n  fi\nfi\n\nAC_CACHE_CHECK(for negative time_t for gmtime(3), rb_cv_negative_time_t,\n  [AC_TRY_RUN([\n#include <time.h>\n\nvoid\ncheck(tm, y, m, d, h, s)\n    struct tm *tm;\n    int y, m, d, h, s;\n{\n    if (!tm ||\n\ttm->tm_year != y ||\n\ttm->tm_mon  != m-1 ||\n\ttm->tm_mday != d ||\n\ttm->tm_hour != h ||\n\ttm->tm_sec  != s) {\n\texit(1);\n    }\n}\n\nint\nmain()\n{\n   time_t t = -1;\n   struct tm *tm;\n\n   check(gmtime(&t), 69, 12, 31, 23, 59);\n   t = ~(time_t)0 << 31;\n   check(gmtime(&t), 1, 12, 13, 20, 52);\n   return 0;\n}\n],\n\trb_cv_negative_time_t=yes,\n\trb_cv_negative_time_t=no,\n\trb_cv_negative_time_t=yes)])\nif test \"$rb_cv_negative_time_t\" = yes; then\n  AC_DEFINE(NEGATIVE_TIME_T)\nfi\n\nif test \"$ac_cv_func_sigprocmask\" = yes && test \"$ac_cv_func_sigaction\" = yes; then\n   AC_DEFINE(POSIX_SIGNAL)\nelse\n  AC_CHECK_FUNCS(sigsetmask)\n  AC_CACHE_CHECK(for BSD signal semantics, rb_cv_bsd_signal,\n    [AC_TRY_RUN([\n#include <stdio.h>\n#include <signal.h>\n\nvoid\nsig_handler(dummy)\n     int dummy;\n{\n}\n\nint\nmain()\n{\n  signal(SIGINT, sig_handler);\n  kill(getpid(), SIGINT);\n  kill(getpid(), SIGINT);\n  return 0;\n}\n],\n\trb_cv_bsd_signal=yes,\n\trb_cv_bsd_signal=no,\n\trb_cv_bsd_signal=$ac_cv_func_sigsetmask)])\n  if test \"$rb_cv_bsd_signal\" = yes; then\n    AC_DEFINE(BSD_SIGNAL)\n  fi\nfi\n\nAC_FUNC_GETPGRP\nAC_FUNC_SETPGRP\n\nAC_C_BIGENDIAN\nAC_C_CONST\nAC_C_CHAR_UNSIGNED\nAC_C_INLINE\nAC_C_VOLATILE\n\nif test x\"$target_cpu\" = xia64; then\n    AC_LIBOBJ([ia64])\n    AC_CACHE_CHECK(for __libc_ia64_register_backing_store_base,\n                   rb_cv___libc_ia64_register_backing_store_base,\n    [rb_cv___libc_ia64_register_backing_store_base=no\n    AC_TRY_LINK(\n      [extern unsigned long __libc_ia64_register_backing_store_base;],\n      [unsigned long p = __libc_ia64_register_backing_store_base;\n       printf(\"%ld\\n\", p);],\n      [rb_cv___libc_ia64_register_backing_store_base=yes])])\n    if test $rb_cv___libc_ia64_register_backing_store_base = yes; then\n      AC_DEFINE(HAVE___LIBC_IA64_REGISTER_BACKING_STORE_BASE)\n    fi\nfi\n\nAC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign,\n    [AC_TRY_RUN([\nint\nmain()\n{\n  if (-1==(-1>>1))\n    return 0;\n  return 1;\n}\n],\n\trb_cv_rshift_sign=yes,\n\trb_cv_rshift_sign=no,\n\trb_cv_rshift_sign=yes)])\nif test \"$rb_cv_rshift_sign\" = yes; then\n  AC_DEFINE(RSHIFT(x,y), ((x)>>(int)y))\nelse\n  AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>y) : (x)>>y))\nfi\n\nAC_MSG_CHECKING(read count field in FILE structures)\nAC_CACHE_VAL(rb_cv_fcnt,\n[for fcnt in\tdnl\n     _cnt\tdnl\n     __cnt\tdnl\n     _r\t\tdnl\n     readCount\tdnl\n     _rcount\tdnl for emx0.9c\n; do\n    AC_TRY_COMPILE([#include <stdio.h>\n],\n\t[FILE *f = stdin; f->$fcnt = 0;],\n\trb_cv_fcnt=\"$fcnt\"; break,\n\trb_cv_fcnt=\"not found\")\ndone])\nif test \"$rb_cv_fcnt\" = \"not found\"; then\n  AC_MSG_RESULT([not found(OK if using GNU libc)])\nelse\n  AC_MSG_RESULT($rb_cv_fcnt)\n  AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt)\nfi\n\nAC_MSG_CHECKING(read buffer ptr field in FILE structures)\nAC_CACHE_VAL(rb_cv_frptr,\n[for frptr in\tdnl\n     _IO_read_ptr dnl\n     _ptr\tdnl\n     __ptr\tdnl\n     bufpos\tdnl\n     _p\tdnl\n; do\n    AC_TRY_COMPILE([#include <stdio.h>\n],\n\t[FILE *f = stdin; char buf[256]; f->$frptr = buf;],\n\trb_cv_frptr=\"$frptr\"; break,\n\trb_cv_frptr=\"not found\")\ndone])\nif test \"$rb_cv_frptr\" = \"not found\"; then\n  AC_MSG_RESULT([not found])\nelse\n  AC_MSG_RESULT($rb_cv_frptr)\n  AC_DEFINE_UNQUOTED(FILE_READPTR, $rb_cv_frptr)\n\n  if test \"$rb_cv_fcnt\" = \"not found\"; then\n    AC_MSG_CHECKING(read buffer end field in FILE structures)\n    AC_CACHE_VAL(rb_cv_frend,\n    [for frend in\tdnl\n         _IO_read_end\tdnl\n         bufread \tdnl\n    ; do\n        AC_TRY_COMPILE([#include <stdio.h>\n    ],\n  \t[FILE *f = stdin; char buf[256]; f->$frend = buf;],\n  \trb_cv_frend=\"$frend\"; break,\n  \trb_cv_frend=\"not found\")\n    done])\n    if test \"$rb_cv_frend\" = \"not found\"; then\n      AC_MSG_RESULT([not found])\n    else\n      AC_MSG_RESULT($rb_cv_frend)\n      AC_DEFINE_UNQUOTED(FILE_READEND, $rb_cv_frend)\n    fi\n  fi\nfi\n\nAC_DEFUN([RUBY_CHECK_IO_NEED],\n[AC_CACHE_CHECK(whether need to [$1], [$2],\n    [AC_TRY_RUN([\n#include <stdio.h>\n#ifndef SEEK_SET\n#define SEEK_SET 0\n#endif\n#ifndef SEEK_CUR\n#define SEEK_CUR 1\n#endif\n#define before_seek(f) ]ifelse(index($2,flush_before_seek),-1,[fflush(f)],[(f,0)])[\n#define reset_rw(f) ]ifelse(index($2,seek_between_rw),-1,[do_seek(f,SEEK_CUR)],[(f,0)])[\n#define do_seek(f, w) (before_seek(f), fseek(f,0,w))\n\nchar *fn = \"conftest.dat\";\nchar *wombat = \"wombat\\n\";\nchar *koara = \"koara\\n\";\nchar *kangaroo = \"kangaroo\\n\";\n\nint main()\n{\n    char buf[BUFSIZ];\n    FILE *f;\n    int r = 1;\n\n    if (!(f = fopen(fn, \"w+\"))) return 1;\n    fputs(wombat, f);\n    do_seek(f, SEEK_SET);\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, wombat)) goto fail;\n    reset_rw(f);\n    fputs(koara, f);\n    fputs(kangaroo, f);\n    do_seek(f, SEEK_SET);\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, wombat)) goto fail;\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, koara)) goto fail;\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, kangaroo)) goto fail;\n    do_seek(f, SEEK_SET);\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, wombat)) goto fail;\n    reset_rw(f);\n    fputc('X', f);\n    reset_rw(f);\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, koara+1)) goto fail;\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, kangaroo)) goto fail;\n    do_seek(f, SEEK_SET);\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, wombat)) goto fail;\n    if (!fgets(buf, BUFSIZ, f) || buf[0] != 'X' || strcmp(buf+1, koara+1)) goto fail;\n    if (!fgets(buf, BUFSIZ, f) || strcmp(buf, kangaroo)) goto fail;\n    r = 0;\n  fail:\n    fclose(f);\n    unlink(fn);\n    return r;\n}\n], [$2]=no, [$2]=yes, [$2]=[$3])])])\nRUBY_CHECK_IO_NEED(seek between R/W, rb_cv_need_io_seek_between_rw, yes)\nif test \"$rb_cv_need_io_seek_between_rw\" = yes; then\n  AC_DEFINE(NEED_IO_SEEK_BETWEEN_RW, 1)\nfi\ndnl RUBY_CHECK_IO_NEED(flush before seek, rb_cv_need_io_flush_before_seek, no)\ndnl if test \"$rb_cv_need_io_flush_before_seek\" = yes; then\ndnl   AC_DEFINE(NEED_IO_FLUSH_BEFORE_SEEK, 1)\ndnl fi\n\nAC_CACHE_CHECK([whether st_ino is huge], rb_cv_huge_st_ino,\n[AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([\n#include <sys/stat.h>\nstruct stat test_stat;\n], [sizeof(test_stat.st_ino)>sizeof(long)])],\nrb_cv_huge_st_ino=yes,\nrb_cv_huge_st_ino=no)\n])\nif test $rb_cv_huge_st_ino = yes; then\n  AC_DEFINE(HUGE_ST_INO)\nfi\n\nif test \"$ac_cv_func_sysconf\" = yes; then\n  AC_DEFUN([RUBY_CHECK_SYSCONF], [dnl\n  AC_CACHE_CHECK([whether _SC_$1 is supported], rb_cv_have_sc_[]m4_tolower($1),\n    [AC_TRY_COMPILE([#include <unistd.h>\n      ],\n      [_SC_$1 >= 0],\n      rb_cv_have_sc_[]m4_tolower($1)=yes,\n      rb_cv_have_sc_[]m4_tolower($1)=no)\n    ])\n  if test \"$rb_cv_have_sc_[]m4_tolower($1)\" = yes; then\n    AC_DEFINE(HAVE__SC_$1)\n  fi\n  ])\n  RUBY_CHECK_SYSCONF(CLK_TCK)\nfi\n\ncase \"$target_cpu\" in\nm68*|i?86|ia64|sparc*|alpha*) rb_cv_stack_grow_dir=-1;;\nhppa*) rb_cv_stack_grow_dir=+1;;\nesac\nAC_CACHE_CHECK(stack growing direction, rb_cv_stack_grow_dir,\n  [AC_TRY_RUN([\n/* recurse to get rid of inlining */\nstatic int\nstack_growup_p(addr, n)\n    volatile int *addr, n;\n{\n    volatile int end;\n    if (n > 0)\n\treturn *addr = stack_growup_p(addr, n - 1);\n    else\n\treturn (&end > addr);\n}\nint main()\n{\n    int x;\n    return stack_growup_p(&x, 10);\n}\n], rb_cv_stack_grow_dir=-1, rb_cv_stack_grow_dir=+1, rb_cv_stack_grow_dir=0)])\nAC_DEFINE_UNQUOTED(STACK_GROW_DIRECTION, $rb_cv_stack_grow_dir)\n\nif test x\"$enable_pthread\" = xyes; then\n    for pthread_lib in pthread pthreads c c_r; do\n \tAC_CHECK_LIB($pthread_lib, pthread_kill,\n\t\t     rb_with_pthread=yes, rb_with_pthread=no)\n\tif test \"$rb_with_pthread\" = \"yes\"; then break; fi\n    done\n    if test x\"$rb_with_pthread\" = xyes; then\n\tAC_DEFINE(_REENTRANT)\n\tAC_DEFINE(_THREAD_SAFE)\n\tAC_DEFINE(HAVE_LIBPTHREAD)\n\tcase $pthread_lib in\n\tc)\n\t    ;;\n\tc_r)\n\t    MAINLIBS=\"-pthread $MAINLIBS\"\n\t    ;;\n\t*)\n      \t    LIBS=\"-l$pthread_lib $LIBS\"\n\t    ;;\n\tesac\n    else\n\tAC_MSG_WARN(\"Don't know how to find pthread library on your system -- thread support disabled\")\n    fi\n    AC_CHECK_FUNCS(nanosleep)\n    if test x\"$ac_cv_func_nanosleep\" = xno; then\n       AC_CHECK_LIB(rt, nanosleep)\n       if test x\"$ac_cv_lib_rt_nanosleep\" = xyes; then\n           AC_DEFINE(HAVE_NANOSLEEP)\n       fi\n    fi\nfi\nif test x\"$ac_cv_header_ucontext_h\" = xyes && test x\"$disable_ucontext\" = xno; then\n    if test x\"$rb_with_pthread\" = xyes; then\n\tAC_CHECK_FUNCS(getcontext setcontext)\n    fi\nfi\n\ndnl default value for $KANJI\nDEFAULT_KCODE=\"KCODE_NONE\"\n\nAC_ARG_WITH(default-kcode,\n\t[  --with-default-kcode=CODE specify default value for \\$KCODE (utf8|euc|sjis|none)],\n\t[case $withval in\n\tutf8) DEFAULT_KCODE=\"KCODE_UTF8\";;\n\teuc)  DEFAULT_KCODE=\"KCODE_EUC\";;\n\tsjis) DEFAULT_KCODE=\"KCODE_SJIS\";;\n\tnone) DEFAULT_KCODE=\"KCODE_NONE\";;\n        *)    AC_MSG_WARN($withval is not valid kcode; ignored);;\n\tesac])\nAC_DEFINE_UNQUOTED(DEFAULT_KCODE, $DEFAULT_KCODE)\n\ndnl wheather use dln_a_out or not\nAC_ARG_WITH(dln-a-out,\n\t[  --with-dln-a-out        use dln_a_out if possible], [\n\tcase $withval in\n\tyes) with_dln_a_out=yes;;\n\t*)   with_dln_a_out=no;;\n\tesac], [with_dln_a_out=no])\n\nAC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf,\n[AC_TRY_RUN([\n/* Test for whether ELF binaries are produced */\n#include <fcntl.h>\n#include <stdlib.h>\nmain() {\n\tchar buffer[4];\n\tint i=open(\"conftest\",O_RDONLY);\n\tif(i==-1)\n\t\texit(1); /* fail */\n\tif(read(i,&buffer[0],4)<4)\n\t\texit(1); /* fail */\n\tif(buffer[0] != 127 || buffer[1] != 'E' ||\n           buffer[2] != 'L' || buffer[3] != 'F')\n\t\texit(1); /* fail */\n\texit(0); /* succeed (yes, it's ELF) */\n}\n],\nrb_cv_binary_elf=yes,\nrb_cv_binary_elf=no,\nrb_cv_binary_elf=yes)])\n\nif test \"$rb_cv_binary_elf\" = yes; then\n  AC_DEFINE(USE_ELF)\nfi\n\ncase \"$target_os\" in\nlinux* | gnu* | k*bsd*-gnu | bsdi*)\n    if test \"$rb_cv_binary_elf\" = no; then\n\twith_dln_a_out=yes\n    else\n\tLDFLAGS=\"$LDFLAGS -rdynamic\"\n    fi;;\nesac\nLIBEXT=a\n\nAC_SUBST(DLDFLAGS)dnl\nAC_SUBST(ARCH_FLAG)dnl\n\nAC_SUBST(STATIC)dnl\nAC_SUBST(CCDLFLAGS)dnl\nAC_SUBST(LDSHARED)dnl\nAC_SUBST(DLEXT)dnl\nAC_SUBST(DLEXT2)dnl\nAC_SUBST(LIBEXT)dnl\n\nSTATIC=\n: ${PATHFLAG=''}\n\nif test \"$with_dln_a_out\" != yes; then\n  rb_cv_dlopen=unknown\n  AC_MSG_CHECKING(whether OS depend dynamic link works)\n  if test \"$GCC\" = yes; then\n    case \"$target_os\" in\n    nextstep*)\tCCDLFLAGS=\"$CCDLFLAGS -fno-common\";;\n    openstep*)\tCCDLFLAGS=\"$CCDLFLAGS -fno-common\";;\n    rhapsody*)\tCCDLFLAGS=\"$CCDLFLAGS -fno-common\";;\n    darwin*)\tCCDLFLAGS=\"$CCDLFLAGS -fno-common\";;\n    human*|bsdi*|beos*|cygwin*|mingw*|aix*|interix*) ;;\n    *) CCDLFLAGS=\"$CCDLFLAGS -fPIC\";;\n    esac\n  else\n    case \"$target_os\" in\n\thpux*)\t\tCCDLFLAGS=\"$CCDLFLAGS +Z\";;\n\tsolaris*|irix*)\tCCDLFLAGS=\"$CCDLFLAGS -KPIC\" ;;\n\tsunos*)\t\tCCDLFLAGS=\"$CCDLFLAGS -PIC\" ;;\n\tesix*|uxpds*)   CCDLFLAGS=\"$CCDLFLAGS -KPIC\" ;;\n\t*)\t\t: ${CCDLFLAGS=\"\"} ;;\n    esac\n  fi\n\n\n  AC_ARG_ENABLE(rpath,\n       [  --disable-rpath         embed run path into extension libraries.],\n       [enable_rpath=$enableval], [enable_rpath=\"$rb_cv_binary_elf\"])\n  if test \"$enable_rpath\" = yes; then\n    RPATHFLAG=\" ${linker_flag}-R%1\\$-s\"\n  fi\n\n  case \"$target_os\" in\n\thpux*)\t\tDLDFLAGS=\"$DLDFLAGS -E\"\n\t\t\t: ${LDSHARED='ld -b'}\n\t\t\tXLDFLAGS=\"$XLDFLAGS -Wl,-E\"\n\t\t\t: ${LIBPATHENV=SHLIB_PATH}\n\t\t\tif test \"$rb_cv_prog_gnu_ld\" = no; then\n\t\t\t    RPATHFLAG=' +b %1$-s'\n\t\t\tfi\n\t\t\trb_cv_dlopen=yes;;\n\tsolaris*) \tif test \"$GCC\" = yes; then\n                          : ${LDSHARED='$(CC) -shared'}\n\t\t\t   if test \"$rb_cv_prog_gnu_ld\" = yes; then\n\t \t\t       LDFLAGS=\"$LDFLAGS -Wl,-E\"\n\t\t\t   fi\n\t\t\telse\n\t\t\t   : ${LDSHARED='ld -G'}\n\t\t\tfi\n\t\t\trb_cv_dlopen=yes;;\n\tsunos*) \t: ${LDSHARED='ld -assert nodefinitions'}\n\t\t\trb_cv_dlopen=yes;;\n\tirix*)\t\t: ${LDSHARED='ld -shared'}\n\t\t\trb_cv_dlopen=yes;;\n\tsysv4*) \t: ${LDSHARED='ld -G'}\n\t\t\trb_cv_dlopen=yes;;\n        nto-qnx*)       : ${LDSHARED=\"qcc -shared\"}\n                        rb_cv_dlopen=yes ;;\n\tesix*|uxpds*) \t: ${LDSHARED=\"ld -G\"}\n\t\t\trb_cv_dlopen=yes ;;\n\tosf*) \t\t: ${LDSHARED=\"ld -shared -expect_unresolved \\\"*\\\"\"}\n\t\t\trb_cv_dlopen=yes ;;\n\tbsdi3*) \tcase \"$CC\" in\n\t\t\t*shlicc*)\t: ${LDSHARED=\"$CC -r\"}\n\t\t\t\t\trb_cv_dlopen=yes ;;\n\t\t\tesac ;;\n\tlinux* | gnu* | k*bsd*-gnu | netbsd* | bsdi*)\n\t\t\t: ${LDSHARED='${CC} -shared'}\n\t\t\tif test \"$rb_cv_binary_elf\" = yes; then\n\t\t\t    LDFLAGS=\"$LDFLAGS -Wl,-export-dynamic\"\n\t\t\tfi\n\t\t\trb_cv_dlopen=yes ;;\n\tinterix*) \t: ${LDSHARED=\"$CC -shared\"}\n\t\t\tXLDFLAGS=\"$XLDFLAGS -Wl,-E\"\n\t\t\tLIBPATHFLAG=\" -L%1\\$-s\"\n\t\t\trb_cv_dlopen=yes ;;\n\tfreebsd*|dragonfly*)       : ${LDSHARED=\"$CC -shared\"}\n\t\t\tif test \"$rb_cv_binary_elf\" = yes; then\n\t\t\t    LDFLAGS=\"$LDFLAGS -rdynamic\"\n\t\t\t    DLDFLAGS=\"$DLDFLAGS \"'-Wl,-soname,$(.TARGET)'\n\t\t\telse\n\t\t\t  test \"$GCC\" = yes && test \"$rb_cv_prog_gnu_ld\" = yes || LDSHARED=\"ld -Bshareable\"\n\t\t\tfi\n\t\t\trb_cv_dlopen=yes ;;\n\topenbsd*) \t: ${LDSHARED=\"\\$(CC) -shared ${CCDLFLAGS}\"}\n\t\t\tif test \"$rb_cv_binary_elf\" = yes; then\n\t\t\t    LDFLAGS=\"$LDFLAGS -Wl,-E\"\n\t\t\tfi\n\t\t\trb_cv_dlopen=yes ;;\n\tnextstep*)\t: ${LDSHARED='cc -r -nostdlib'}\n\t\t\tLDFLAGS=\"$LDFLAGS -u libsys_s\"\n\t\t\trb_cv_dlopen=yes ;;\n\topenstep*)\t: ${LDSHARED='cc -dynamic -bundle -undefined suppress'}\n\t\t\t: ${LDFLAGS=\"\"}\n\t\t\trb_cv_dlopen=yes ;;\n\trhapsody*)\t: ${LDSHARED='cc -dynamic -bundle -undefined suppress'}\n\t\t\t: ${LDFLAGS=\"\"}\n\t\t\trb_cv_dlopen=yes ;;\n\tdarwin*)\t: ${LDSHARED='cc -dynamic -bundle -undefined suppress -flat_namespace'}\n\t\t\t: ${LDFLAGS=\"\"}\n\t\t\t: ${LIBPATHENV=DYLD_LIBRARY_PATH}\n\t\t\trb_cv_dlopen=yes ;;\n        aix*)           if test \"$GCC\" = yes; then\n\t\t\t    : ${LDSHARED='$(CC) -shared'}\n\t\t\telse\n\t\t\t    : ${LDSHARED='$(CC)'}\n\t\t\tfi\n\t\t\tLDSHARED=\"$LDSHARED ${linker_flag}-G\"\n\t\t\tDLDFLAGS='-eInit_$(TARGET)'\n\t\t\tXLDFLAGS=\"${linker_flag}-bE:ruby.imp ${linker_flag}-brtl\"\n                        : ${ARCHFILE=\"ruby.imp\"}\n                        TRY_LINK='$(CC) $(LDFLAGS) -oconftest $(INCFLAGS) -I$(hdrdir) $(CPPFLAGS)'\n                        TRY_LINK=\"$TRY_LINK\"' $(CFLAGS) $(src) $(LIBPATH) $(LOCAL_LIBS) $(LIBS)'\n                        : ${LIBPATHENV=SHLIB_PATH}\n                        rb_cv_dlopen=yes ;;\n\thuman*)\t\t: ${DLDFLAGS=''}\n\t\t\t: ${LDSHARED=''}\n\t\t\t: ${LDFLAGS=''}\n\t\t\t: ${LINK_SO='ar cru $@ $(OBJS)'}\n\t\t\trb_cv_dlopen=yes ;;\n\tbeos*) \t\tcase \"$target_cpu\" in\n\t\t\t  powerpc*)\n\t\t\t    : ${LDSHARED=\"ld -xms\"}\n\t\t\t    DLDFLAGS=\"$DLDFLAGS \"'-export Init_$(TARGET) -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o'\n                            ;;\n\t\t\t  i586*)\n\t\t\t    : ${LDSHARED=\"ld -shared\"}\n\t\t\t    DLDFLAGS=\"$DLDFLAGS -L/boot/develop/lib/x86 -lbe -lroot\"\n\t\t\t    ;;\n\t\t\tesac\n\t\t\t: ${LIBPATHENV=LIBRARY_PATH}\n\t\t\trb_cv_dlopen=yes ;;\n\tnto-qnx*)\tDLDFLAGS=\"$DLDFLAGS -L/lib -L/usr/lib -L/usr/local/lib\"\n\t\t\t: ${LDSHARED='ld -Bshareable -x'}\n\t\t\tLDFLAGS=\"$LDFLAGS -L/lib -L/usr/lib -L/usr/local/lib\"\n\t\t\trb_cv_dlopen=yes;;\n\tcygwin*|mingw*)\t: ${LDSHARED=\"${CC} -shared -s\"}\n\t\t\tXLDFLAGS=\"$XLDFLAGS -Wl,--stack,0x02000000\"\n\t\t\tDLDFLAGS=\"${DLDFLAGS} -Wl,--enable-auto-image-base,--enable-auto-import,--export-all\"\n\t\t\t: ${LIBPATHENV=\"\"}\n\t\t\trb_cv_dlopen=yes ;;\n\thiuxmpp)\t: ${LDSHARED='ld -r'} ;;\n\tatheos*) \t: ${LDSHARED=\"$CC -shared\"}\n\t\t\trb_cv_dlopen=yes ;;\n\tos2-emx*)\tLDFLAGS=\"$LDFLAGS -Zbsd-signals\"\n\t\t\t;;\n\t*) \t\t: ${LDSHARED='ld'} ;;\n  esac\n  AC_MSG_RESULT($rb_cv_dlopen)\nfi\ncase ${RPATHFLAG} in\n*'%1$'*)\n    : ${LIBPATHFLAG=' -L%1$-s'};;\n*)\n    : ${LIBPATHFLAG=' -L%s'};;\nesac\nAC_SUBST(LINK_SO)\nAC_SUBST(LIBPATHFLAG)\nAC_SUBST(RPATHFLAG)\nAC_SUBST(LIBPATHENV, \"${LIBPATHENV-LD_LIBRARY_PATH}\")\nAC_SUBST(TRY_LINK)\n\ndln_a_out_works=no\nif test \"$ac_cv_header_a_out_h\" = yes; then\n  if test \"$with_dln_a_out\" = yes || test \"$rb_cv_dlopen\" = unknown; then\n    cat confdefs.h > config.h\n    AC_CACHE_CHECK(whether matz's dln works, rb_cv_dln_a_out,\n    [AC_TRY_COMPILE([\n#define USE_DLN_A_OUT\n#include \"dln.c\"\n],\n\t[],\n\trb_cv_dln_a_out=yes,\n\trb_cv_dln_a_out=no)])\n    if test \"$rb_cv_dln_a_out\" = yes; then\n      dln_a_out_works=yes\n      AC_DEFINE(USE_DLN_A_OUT)\n    fi\n  fi\nfi\n\nif test \"$dln_a_out_works\" = yes; then\n  if test \"$GCC\" = yes; then\n    STATIC=-static\n  else\n    STATIC=-Bstatic\n  fi\n  DLEXT=so\n  CCDLFLAGS=\nelse\n  case \"$target_os\" in\n    hpux*)\tDLEXT=sl;;\n    nextstep*|openstep*|rhapsody*|darwin*)\n\t\tDLEXT=bundle;;\n    os2-emx*)\tDLEXT=dll;;\n    cygwin*|mingw*)\n\t\tDLEXT=so DLEXT2=dll;;\n    *)\t\tDLEXT=so;;\n  esac\nfi\nlen=2 # .rb\nn=`expr \"$DLEXT\"  : '.*'`; test \"$n\" -gt \"$len\" && len=$n\nn=`expr \"$DLEXT2\" : '.*'`; test \"$n\" -gt \"$len\" && len=$n\nAC_DEFINE_UNQUOTED(DLEXT_MAXLEN, `expr $len + 1`)\ntest \".$DLEXT\"  = \".\" || AC_DEFINE_UNQUOTED(DLEXT,  \".$DLEXT\")\ntest \".$DLEXT2\" = \".\" || AC_DEFINE_UNQUOTED(DLEXT2, \".$DLEXT2\")\n\nAC_SUBST(STRIP)dnl\nif test \"$with_dln_a_out\" = yes; then\n  STRIP=true\nelse\n  STRIP=strip\nfi\n\ncase \"$target_os\" in\n  linux* | gnu* | k*bsd*-gnu)\n\tSTRIP='strip -S -x';;\n  nextstep*)\n\tSTRIP='strip -A -n';;\n  openstep*)\n\tSTRIP='strip -A -n';;\n  rhapsody*)\n\tSTRIP='strip -A -n';;\n  darwin*)\n\tSTRIP='strip -A -n';;\nesac\n\nEXTSTATIC=\nAC_SUBST(EXTSTATIC)dnl\nAC_ARG_WITH(static-linked-ext,\n\t    [  --with-static-linked-ext link external modules statically],\n            [case $withval in\n\t     yes) STATIC=\n\t\t  EXTSTATIC=static;;\n\t     *)\t;;\n\t     esac])\n\ncase \"$target_os\" in\n  human*)\n    AC_CHECK_LIB(signal, _harderr)\n    AC_CHECK_LIB(hmem, hmemset)\n    AC_CHECK_FUNCS(select)\n    AC_CACHE_CHECK(whether PD libc _dtos18 fail to convert big number,\n\t\t   rb_cv_missing__dtos18,\n    [AC_TRY_RUN(\nchangequote(<<, >>)dnl\n<<\n#include <stdio.h>\nmain ()\n{\n   char buf[256];\n   sprintf (buf, \"%g\", 1e+300);\n   exit (strcmp (buf, \"1e+300\") ? 0 : 1);\n}\n>>,\nchangequote([, ])dnl\nrb_cv_missing__dtos18=yes, rb_cv_missing__dtos18=no, rb_cv_missing__dtos18=no)])\n    if test \"$rb_cv_missing__dtos18\" = yes; then\n      AC_DEFINE(MISSING__DTOS18)\n    fi\n    AC_CACHE_CHECK(whether PD libc fconvert fail to round,\n\t\t   rb_cv_missing_fconvert,\n    [AC_TRY_RUN(\nchangequote(<<, >>)dnl\n<<\n#include <stdio.h>\n#include <math.h>\nmain ()\n{\n  char buf[256];\n  sprintf (buf, \"%f\", log(exp(1.0)));\n  exit (strcmp (buf, \"1.000000\") ? 0 : 1);\n}\n>>,\nchangequote([, ])dnl\nrb_cv_missing_fconvert=yes, rb_cv_missing_fconvert=no, rb_cv_missing_fconvert=no)])\n    if test \"$rb_cv_missing_fconvert\" = yes; then\n      AC_DEFINE(MISSING_FCONVERT)\n    fi\n    AC_LIBOBJ([x68.o])\n    CFLAGS=\"$CFLAGS -fansi-only\"\n    XCFLAGS=\"$XCFLAGS -cc1-stack=262144 -cpp-stack=2694144\"\n    EXEEXT=.x\n    OBJEXT=o\n    setup=Setup.x68\n    ;;\n  dnl OS/2 environment w/ Autoconf 2.1x for EMX\n  os2-emx)\n    AC_LIBOBJ([os2])\n    setup=Setup.emx\n    ;;\n  *djgpp*)\n    setup=Setup.dj\n    ;;\n  *)\n    setup=Setup\n    ;;\nesac\n\nAC_SUBST(setup)\n\nif test \"$prefix\" = NONE; then\n  prefix=$ac_default_prefix\nfi\n\n#if test \"$fat_binary\" != no ; then\n#  CFLAGS=\"$CFLAGS $ARCH_FLAG\"\n#fi\n\nif test x\"$cross_compiling\" = xyes; then\n  test x\"$MINIRUBY\" = x && MINIRUBY=\"${RUBY-ruby} -I`pwd` -rfake\"\n  PREP=fake.rb\n  RUNRUBY='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'\nelse\n  MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib'\n  MINIRUBY=\"$MINIRUBY\"' -I$(EXTOUT)/common -I./- -r$(srcdir)/ext/purelib.rb'\n  PREP='miniruby$(EXEEXT)'\n  RUNRUBY='$(MINIRUBY) $(srcdir)/runruby.rb --extout=$(EXTOUT)'\nfi\nAC_SUBST(MINIRUBY)\nAC_SUBST(PREP)\nAC_SUBST(RUNRUBY)\nAC_SUBST(EXTOUT, [${EXTOUT-.ext}])\n\nFIRSTMAKEFILE=\"\"\nLIBRUBY_A='lib$(RUBY_SO_NAME)-static.a'\nLIBRUBY='$(LIBRUBY_A)'\nLIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static'\nLIBRUBYARG='$(LIBRUBYARG_STATIC)'\nSOLIBS=\n\ncase \"$target_os\" in\n  cygwin*|mingw*|beos*|openstep*|nextstep*|rhapsody*|darwin*|os2-emx*)\n    : ${DLDLIBS=\"\"}\n    ;;\n  *)\n    DLDLIBS=\"$DLDLIBS -lc\"\n    ;;\nesac\n\nRUBY_SO_NAME='$(RUBY_INSTALL_NAME)'\nLIBRUBY_LDSHARED=$LDSHARED\nLIBRUBY_DLDFLAGS=$DLDFLAGS\nLIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR).$(TEENY)'\nLIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so'\nENABLE_SHARED=no\n\nAC_ARG_ENABLE(shared,\n       [  --enable-shared         build a shared library for Ruby. ],\n       [enable_shared=$enableval])\nif test \"$enable_shared\" = 'yes'; then\n  LIBRUBY='$(LIBRUBY_SO)'\n  LIBRUBYARG_SHARED='-l$(RUBY_SO_NAME)'\n  LIBRUBYARG='$(LIBRUBYARG_SHARED)'\n  CFLAGS=\"$CFLAGS $CCDLFLAGS\"\n  ENABLE_SHARED=yes\n  if test \"$rb_cv_binary_elf\" = yes; then\n    SOLIBS='$(LIBS)'\n  fi\n  case \"$target_os\" in\n    sunos4*)\n\tLIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_SO_NAME).so'\n\t;;\n    linux* | gnu* | k*bsd*-gnu | atheos*)\n\tLIBRUBY_DLDFLAGS='-Wl,-soname,lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR)'\n\tLIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_SO_NAME).so'\n\t;;\n    freebsd*|dragonfly*)\n\tSOLIBS='$(LIBS)'\n\tLIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR)'\n\tif test \"$rb_cv_binary_elf\" != \"yes\" ; then\n\t    LIBRUBY_SO=\"$LIBRUBY_SO.\\$(TEENY)\"\n\t    LIBRUBY_ALIASES=''\n\tfi\n\t;;\n    netbsd*)\n\tSOLIBS='$(LIBS)'\n\tLIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR).$(TEENY)'\n\tLIBRUBY_DLDFLAGS='-Wl,-soname,lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR)'\n\tif test \"$rb_cv_binary_elf\" = yes; then # ELF platforms\n\t   LIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(MAJOR)$(MINOR) lib$(RUBY_SO_NAME).so'\n\telse\t# a.out platforms\n\t   LIBRUBY_ALIASES=\"\"\n\tfi\n \t;;\n    openbsd*)\n\tSOLIBS='$(LIBS)'\n\tLIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).'`expr ${MINOR} \\* 10 + ${TEENY}`\n\t;;\n    solaris*)\n\tSOLIBS='$(LIBS)'\n\tLIBRUBY_SO='lib$(RUBY_SO_NAME).so.$(MAJOR)'\n\tLIBRUBY_ALIASES='lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR).$(TEENY) lib$(RUBY_SO_NAME).so'\n\tif test \"$GCC\" = yes; then\n\t    LIBRUBY_DLDFLAGS=\"$DLDFLAGS \"'-Wl,-h,$(@F)'\n\tfi\n\tXLDFLAGS=\"$XLDFLAGS \"'-R${libdir}'\n \t;;\n    hpux*)\n\tXLDFLAGS=\"$XLDFLAGS \"'-Wl,+s,+b,$(libdir)'\n\tLIBRUBY_SO='lib$(RUBY_SO_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)'\n\tLIBRUBY_ALIASES='lib$(RUBY_SO_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_SO_NAME).sl'\n\t;;\n    aix*)\n\tLIBRUBY_DLDFLAGS=\"${linker_flag}-bnoentry $XLDFLAGS\"\n\tLIBRUBYARG_SHARED='-L${libdir} -l${RUBY_SO_NAME}'\n\tSOLIBS='-lm -lc'\n\t;;\n    beos*)\n\tcase \"$target_cpu\" in\n\tpowerpc*)\n\t    LIBRUBY_DLDFLAGS='-f ruby.exp -lnet -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o'\n\t    ;;\n\tesac\n\t;;\n    darwin*)\n\tLIBRUBY_SO='lib$(RUBY_SO_NAME).$(MAJOR).$(MINOR).$(TEENY).dylib'\n\tLIBRUBY_LDSHARED='cc -dynamiclib -undefined suppress -flat_namespace'\n\tLIBRUBY_DLDFLAGS='-install_name $(libdir)/lib$(RUBY_SO_NAME).dylib -current_version $(MAJOR).$(MINOR).$(TEENY) -compatibility_version $(MAJOR).$(MINOR)'\n\tLIBRUBY_ALIASES='lib$(RUBY_SO_NAME).$(MAJOR).$(MINOR).dylib lib$(RUBY_SO_NAME).dylib'\n\t;;\n    interix*)\n\tLIBRUBYARG_SHARED='-L. -L${libdir} -l$(RUBY_SO_NAME)'\n\t;;\n    *)\n\t;;\n  esac\nfi\nif test \"$enable_rpath\" = yes; then\n    LIBRUBYARG_SHARED=\"${linker_flag}-R ${linker_flag}\\$(libdir) -L\\$(libdir) $LIBRUBYARG_SHARED\"\nfi\n\nLDFLAGS=\"-L. $LDFLAGS\"\nAC_SUBST(ARCHFILE)\n\ndnl build rdoc index if requested\nRDOCTARGET=\"\"\nAC_ARG_ENABLE(install-doc,\n       [  --enable-install-doc    build and install rdoc indexes during install ],\n       [install_doc=$enableval], [install_doc=no])\nif test \"$install_doc\" != no; then\n   RDOCTARGET=\"install-doc\"\nfi\nAC_SUBST(RDOCTARGET)\n\ncase \"$target_os\" in\n    linux*)\n\tXCFLAGS=\"$XCFLAGS -D_GNU_SOURCE=1\"\n\t;;\n    netbsd*)\n    \tCFLAGS=\"$CFLAGS -pipe\"\n\t;;\n    nextstep*|openstep*)\n\t# The -fno-common is needed if we wish to embed the Ruby interpreter\n\t# into a plugin module of some project (as opposed to embedding it\n\t# within the project's application).  The -I/usr/local/include is\n\t# needed because CPP as discovered by configure (cc -E -traditional)\n\t# fails to consult /usr/local/include by default.  This causes\n\t# mkmf.rb's have_header() to fail if the desired resource happens to be\n\t# installed in the /usr/local tree.\n    \tCFLAGS=\"$CFLAGS -pipe -fno-common\"\n\tCPPFLAGS=\"$CPPFLAGS -I/usr/local/include\"\n\t;;\n    rhapsody*)\n    \tCFLAGS=\"$CFLAGS -pipe -no-precomp -fno-common\"\n\t;;\n    darwin*)\n    \tCFLAGS=\"$CFLAGS -pipe -fno-common\"\n\tMINIOBJS=dmydln.o\n\t;;\n    os2-emx)\n    \tCFLAGS=\"$CFLAGS -DOS2 -Zmts\"\n\tLIBRUBY_A=`echo $LIBRUBY_A | sed 's/^lib//'`\n\tLIBRUBY_SO=`echo $LIBRUBY_SO | sed 's/^lib//'`\n\tLIBRUBY_ALIASES=`for i in $LIBRUBY_ALIASES; do echo \"$i\"; done | sed 's/^lib//'`\n\t;;\n    osf*)\n\tif test \"$GCC\" != \"yes\" ; then\n\t  # compile something small: taint.c is fine for this.\n\t  # the main point is the '-v' flag of 'cc'.\n\t  case \"`cc -v -I. -c main.c -o /tmp/main.o 2>&1`\" in\n\t  */gemc_cc*)   # we have the new DEC GEM CC\n                        CFLAGS=\"$CFLAGS -oldc\"\n                        ;;\n          *)            # we have the old MIPS CC\n                        ;;\n          esac\n\t  # cleanup\n\t  rm -f /tmp/main.o\n\t  CFLAGS=\"$CFLAGS -std\"\n\tfi\n\t;;\n    beos*)\n\tcase \"$target_cpu\" in\n\tpowerpc*)\n\t    CFLAGS=\"$CFLAGS -relax_pointers\"\n\t    ;;\n\tesac\n\t;;\n    cygwin*|mingw*)\n\tcase \"$target_os\" in\n\tcygwin*)\n\t    if test x\"$enable_shared\" = xyes; then\n\t\tLIBRUBY_SO='cyg$(RUBY_SO_NAME)'${MAJOR}${MINOR}.dll\n\t\tLIBRUBY='lib$(RUBY_SO_NAME).dll.a'\n\t    fi\n\t    ;;\n\tmingw*)\n\t    RUBY_SO_NAME=${rb_cv_msvcrt}-'$(RUBY_INSTALL_NAME)'${MAJOR}${MINOR}\n\t    if test x\"$enable_shared\" = xyes; then\n\t\tLIBRUBY_SO='$(RUBY_SO_NAME)'.dll\n\t\tLIBRUBY='lib$(LIBRUBY_SO).a'\n\t    fi\n\t    AC_LIBOBJ([win32])\n\t    COMMON_LIBS=m\n#\t    COMMON_MACROS=\"WIN32_LEAN_AND_MEAN=\"\n\t    COMMON_HEADERS=\"windows.h winsock.h\"\n\t    ;;\n\tesac\n\tLIBRUBY_DLDFLAGS=\"${DLDFLAGS}\"' -Wl,--out-implib=$(LIBRUBY)'\n\tLIBRUBY_ALIASES=''\n\tFIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in\n\tSOLIBS='$(LIBS)'\n\tif test x\"$enable_shared\" = xno; then\n\t    LIBRUBY_SO=dummy\n\t    LIBRUBY='lib$(RUBY_SO_NAME).a'\n\t    LIBRUBYARG='-l$(RUBY_SO_NAME)'\n\tfi\n\tMINIOBJS=dmydln.o\n\t;;\n    hpux*)\n\tcase \"$YACC\" in\n\t  *yacc*)\n\t    XCFLAGS=\"$XCFLAGS -DYYMAXDEPTH=300\"\n\t    YACC=\"$YACC -Nl40000 -Nm40000\"\n\t    ;;\n\tesac\n\tMINIOBJS=dmydln.o\n\t;;\n    *)\n\t;;\nesac\n\ncase \"$build_os\" in\n  *msdosdjgpp*) FIRSTMAKEFILE=GNUmakefile:djgpp/GNUmakefile.in;;\nesac\n\nCPPFLAGS=\"$CPPFLAGS \"'$(DEFS)'\ntest -z \"$CFLAGS\" || CFLAGS=\"$CFLAGS \"; CFLAGS=\"$CFLAGS\"'${cflags}'\ntest -z \"$CPPFLAGS\" || CPPFLAGS=\"$CPPFLAGS \"; CPPFLAGS=\"$CPPFLAGS\"'${cppflags}'\nAC_SUBST(cppflags, [])dnl\nAC_SUBST(cflags, ['${optflags} ${debugflags}'])dnl\nAC_SUBST(optflags)dnl\nAC_SUBST(debugflags)dnl\nAC_SUBST(XCFLAGS)dnl\nAC_SUBST(XLDFLAGS)dnl\nAC_SUBST(LIBRUBY_LDSHARED)\nAC_SUBST(LIBRUBY_DLDFLAGS)\nAC_SUBST(RUBY_INSTALL_NAME)\nAC_SUBST(rubyw_install_name)\nAC_SUBST(RUBYW_INSTALL_NAME)\nAC_SUBST(RUBY_SO_NAME)\nAC_SUBST(LIBRUBY_A)\nAC_SUBST(LIBRUBY_SO)\nAC_SUBST(LIBRUBY_ALIASES)\nAC_SUBST(LIBRUBY)\nAC_SUBST(LIBRUBYARG)\nAC_SUBST(LIBRUBYARG_STATIC)\nAC_SUBST(LIBRUBYARG_SHARED)\nAC_SUBST(SOLIBS)\nAC_SUBST(DLDLIBS)\nAC_SUBST(ENABLE_SHARED)\nAC_SUBST(MAINLIBS)\nAC_SUBST(COMMON_LIBS)\nAC_SUBST(COMMON_MACROS)\nAC_SUBST(COMMON_HEADERS)\nAC_SUBST(EXPORT_PREFIX)\nAC_SUBST(MINIOBJS)\n\nMAKEFILES=\"Makefile `echo $FIRSTMAKEFILE | sed 's/:.*//'`\"\nMAKEFILES=\"`echo $MAKEFILES`\"\nAC_SUBST(MAKEFILES)\n\nri_prefix=\ntest \"$program_prefix\" != NONE &&\n  ri_prefix=$program_prefix\n\nri_suffix=\ntest \"$program_suffix\" != NONE &&\n  ri_suffix=$program_suffix\n\nRUBY_INSTALL_NAME=\"${ri_prefix}ruby${ri_suffix}\"\ncase \"$target_os\" in\n  cygwin*|mingw*)\n    RUBYW_INSTALL_NAME=\"${ri_prefix}rubyw${ri_suffix}\"\n    rubyw_install_name=\"$RUBYW_INSTALL_NAME\"\n    ;;\nesac\nRUBY_LIB_PREFIX=`eval echo \\\\\"${libdir}/ruby\\\\\"`\n\nAC_ARG_WITH(sitedir,\n\t    [  --with-sitedir=DIR      site libraries in DIR [[LIBDIR/ruby/site_ruby]]],\n            [sitedir=$withval],\n            [sitedir='${libdir}/ruby/site_ruby'])\nSITE_DIR=`eval echo \\\\\"${sitedir}\\\\\"`\n\ncase \"$target_os\" in\n  cygwin*|mingw*|*djgpp*|os2-emx*)\n    RUBY_LIB_PREFIX=\"`eval echo \"$RUBY_LIB_PREFIX\" | sed 's|^NONE/|/|;s|^'\"$prefix\"'/|/|'`\"\n    RUBY_SITE_LIB_PATH=\"`eval echo \"$SITE_DIR\" | sed 's|^NONE/|/|;s|^'\"$prefix\"'/|/|'`\"\n    ;;\n  *)\n    RUBY_LIB_PREFIX=\"`eval echo \\\\\"$RUBY_LIB_PREFIX\\\\\" | sed 's|^NONE/|'\"$prefix\"'/|'`\"\n    RUBY_SITE_LIB_PATH=\"`eval echo \\\\\"$SITE_DIR\\\\\" | sed 's|^NONE/|'\"$prefix\"'/|'`\"\n    ;;\nesac\nRUBY_LIB_PATH=\"${RUBY_LIB_PREFIX}/${MAJOR}.${MINOR}\"\nRUBY_SITE_LIB_PATH2=\"${RUBY_SITE_LIB_PATH}/${MAJOR}.${MINOR}\"\n\nAC_DEFINE_UNQUOTED(RUBY_LIB, \"${RUBY_LIB_PATH}\")\nAC_DEFINE_UNQUOTED(RUBY_SITE_LIB, \"${RUBY_SITE_LIB_PATH}\")\nAC_DEFINE_UNQUOTED(RUBY_SITE_LIB2, \"${RUBY_SITE_LIB_PATH2}\")\n\nAC_ARG_WITH(vendordir,\n\t    [  --with-vendordir=DIR    vendor libraries in DIR [[LIBDIR/ruby/vendor_ruby]]],\n            [vendordir=$withval],\n            [vendordir='${libdir}/ruby/vendor_ruby'])\nVENDOR_DIR=`eval echo \\\\\"${vendordir}\\\\\"`\ncase \"$target_os\" in\n  cygwin*|mingw*|*djgpp*|os2-emx*)\n    RUBY_VENDOR_LIB_PATH=\"`eval echo \"$VENDOR_DIR\" | sed 's|^NONE/|/|;s|^'\"$prefix\"'/|/|'`\"\n    ;;\n  *)\n    RUBY_VENDOR_LIB_PATH=\"`eval echo \\\\\"$VENDOR_DIR\\\\\" | sed 's|^NONE/|'\"$prefix\"'/|'`\"\n    ;;\nesac\nRUBY_VENDOR_LIB_PATH2=\"${RUBY_VENDOR_LIB_PATH}/${MAJOR}.${MINOR}\"\n\nAC_DEFINE_UNQUOTED(RUBY_VENDOR_LIB, \"${RUBY_VENDOR_LIB_PATH}\")\nAC_DEFINE_UNQUOTED(RUBY_VENDOR_LIB2, \"${RUBY_VENDOR_LIB_PATH2}\")\n\nAC_SUBST(arch)dnl\nAC_SUBST(sitearch)dnl\nAC_SUBST(sitedir)dnl\nAC_SUBST(vendordir)dnl\n\nconfigure_args=$ac_configure_args\nAC_SUBST(configure_args)dnl\n\nif test \"$fat_binary\" != no ; then\n    arch=\"fat-${target_os}\"\n\n    AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB,\n                 \"${RUBY_LIB_PATH}/\" __ARCHITECTURE__ \"-${target_os}\")\n\n    AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB,\n                 \"${RUBY_SITE_LIB_PATH}/\" __ARCHITECTURE__ \"-${target_os}\")\n    AC_DEFINE_UNQUOTED(RUBY_VENDOR_THIN_ARCHLIB,\n                 \"${RUBY_VENDOR_LIB_PATH}/\" __ARCHITECTURE__ \"-${target_os}\")\n    AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ \"-${target_os}\")\nelse\n    arch=\"${target_cpu}-${target_os}\"\n    AC_DEFINE_UNQUOTED(RUBY_PLATFORM, \"${arch}\")\nfi\n\ncase \"$target_os\" in\n  mingw*) sitearch=\"$target_cpu-$rb_cv_msvcrt\" ;;\n  *) sitearch=\"${arch}\" ;;\nesac\n\nAC_DEFINE_UNQUOTED(RUBY_ARCHLIB, \"${RUBY_LIB_PATH}/${arch}\")\nAC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, \"${RUBY_SITE_LIB_PATH2}/${sitearch}\")\nAC_DEFINE_UNQUOTED(RUBY_VENDOR_ARCHLIB, \"${RUBY_VENDOR_LIB_PATH2}/${sitearch}\")\n\nAC_ARG_WITH(search-path,\n\t\t[  --with-search-path=DIR specify the additional search path],\n\t\t[search_path=$withval])\nif test \"$search_path\" != \"\"; then\n    AC_DEFINE_UNQUOTED(RUBY_SEARCH_PATH,\"$search_path\")\nfi\n\nAC_ARG_WITH(mantype,\n\t\t[  --with-mantype=TYPE specify man page type; TYPE is one of man and doc],\n\t\t[\n\t\t\tcase \"$withval\" in\n\t\t\tman|doc)\n\t\t\t\tMANTYPE=$withval\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\tAC_MSG_ERROR(invalid man type: $withval)\n\t\t\t\t;;\n\t\t\tesac\n\t\t])\nif test -z \"$MANTYPE\"; then\n\tAC_PATH_PROGS(NROFF, nroff awf, /bin/false, \"/usr/bin:/usr/ucb\")\n\tif ${NROFF} -mdoc ${srcdir}/ruby.1 >/dev/null 2>&1; then\n\t\tMANTYPE=doc\n\telse\n\t\tMANTYPE=man\n\tfi\nfi\nAC_SUBST(MANTYPE)\n\nif test -f config.h && tr -d '\\015' < confdefs.h | cmp -s config.h -; then\n  echo \"config.h unchanged\"\nelse\n  echo \"creating config.h\"\n  tr -d '\\015' < confdefs.h > config.h\nfi\ntr -d '\\015' < largefile.h > confdefs.h\nrm largefile.h\n\nAC_CONFIG_FILES($FIRSTMAKEFILE)\nAC_CONFIG_FILES(Makefile, [{\n\tsed '/^MISSING/s/\\$U\\././g' Makefile\n\techo; test x\"$EXEEXT\" = x || echo 'miniruby: miniruby$(EXEEXT)'\n\ttest \"$RUBY_INSTALL_NAME$EXEEXT\" = ruby || echo 'ruby: $(PROGRAM);'\n\tsed ['s/{\\$([^(){}]*)[^{}]*}//g'] ${srcdir}/common.mk\n      } >> confmk$$.tmp && mv -f confmk$$.tmp Makefile],\n[RUBY_INSTALL_NAME=$RUBY_INSTALL_NAME EXEEXT=$EXEEXT])\nAC_OUTPUT\n"
  },
  {
    "path": "cygwin/GNUmakefile.in",
    "content": "include Makefile\n\nENABLE_SHARED=@ENABLE_SHARED@\nDLLWRAP = @DLLWRAP@ --target=@target_os@\n\nifeq (@target_os@,cygwin)\n  DLL_BASE_NAME := $(subst .dll,,$(LIBRUBY_SO))\nelse\n  DLL_BASE_NAME := $(RUBY_SO_NAME)\n  DLLWRAP += -mno-cygwin\n  VPATH += $(srcdir)/win32\nendif\n\nifneq ($(ENABLE_SHARED),yes)\n  RUBY_EXP = $(RUBY_INSTALL_NAME).exp\n  EXTOBJS = $(RUBY_EXP)\n  LIBRUBYARG = $(LIBRUBY_A)\n  LIBRUBY_SO =\nendif\n\nifeq ($(RUBY_INSTALL_NAME),ruby)\n  RUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME)w\nelse\n  RUBYW_INSTALL_NAME = $(subst ruby,rubyw,$(RUBY_INSTALL_NAME))\nendif\n\nWPROGRAM = $(RUBYW_INSTALL_NAME)$(EXEEXT)\nSOLIBS := $(DLL_BASE_NAME).res.@OBJEXT@ $(SOLIBS)\nEXTOBJS += $(@:$(EXEEXT)=.res.@OBJEXT@)\nRCFILES = $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(DLL_BASE_NAME).rc\n\nruby: $(PROGRAM)\nrubyw: $(WPROGRAM)\n\n$(LIBRUBY): $(RUBY_EXP) $(LIBRUBY_SO)\n$(RUBY_EXP) $(LIBRUBY_SO): $(DLL_BASE_NAME).res.@OBJEXT@\n\n%.res.@OBJEXT@: %.rc\n\t@WINDRES@ --include-dir . --include-dir $(<D) --include-dir $(srcdir)/win32 $< $@\n\n$(RCFILES): $(RBCONFIG)\n\t@$(MINIRUBY) $(srcdir)/win32/resource.rb \\\n\t  -ruby_name=$(RUBY_INSTALL_NAME) -rubyw_name=$(RUBYW_INSTALL_NAME) \\\n\t  -so_name=$(DLL_BASE_NAME) \\\n\t  . $(icondirs) $(srcdir)/win32\n\n$(PROGRAM): $(RUBY_INSTALL_NAME).res.@OBJEXT@\n$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.@OBJEXT@\n\t@rm -f $@\n\t$(PURIFY) $(CC) -mwindows -e _mainCRTStartup $(LDFLAGS) $(XLDFLAGS) \\\n\t  $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@\n\n$(RUBY_EXP): $(LIBRUBY_A)\n\t$(DLLWRAP) \\\n\t  --output-exp=$(RUBY_EXP) \\\n\t  --export-all $(LIBRUBY_A) $(LIBS) -o $(PROGRAM)\n\t$(LDSHARED) $(DLDFLAGS) $(OBJS) dmyext.o $(SOLIBS) -o $(PROGRAM)\n\t@rm -f $(PROGRAM)\n\nGNUmakefile:\t$(srcdir)/cygwin/GNUmakefile.in\n\nifeq (@target_os@,mingw32)\n$(OBJS) $(MAINOBJ): win32/win32.h\nendif\n\nifeq (@target_os@,cygwin)\ncygwin-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR).dll: $(LIBRUBY_A)\n\t@NM@ --extern --defined $(LIBRUBY_A) | \\\n\t  $(MINIRUBY) -ne 'BEGIN{puts \"EXPORTS\"}; puts $$1+\"=cyg$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR).\"+$$1 if / [CDT] _(.*)$$/' >rubydll.def\n\t@DLLWRAP@ -s --def=rubydll.def -o $@\n\t@rm -f rubydll.def\nendif\n\nclean-local::\n\t@$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@)\n\ndistclean-local::\n\t@$(RM) $(RCFILES)\n"
  },
  {
    "path": "defines.h",
    "content": "/************************************************\n\n  defines.h -\n\n  $Author$\n  $Date$\n  created at: Wed May 18 00:21:44 JST 1994\n\n************************************************/\n#ifndef DEFINES_H\n#define DEFINES_H\n\n#define RUBY\n\n#ifdef __cplusplus\n# ifndef  HAVE_PROTOTYPES\n#  define HAVE_PROTOTYPES 1\n# endif\n# ifndef  HAVE_STDARG_PROTOTYPES\n#  define HAVE_STDARG_PROTOTYPES 1\n# endif\n#endif\n\n#undef _\n#ifdef HAVE_PROTOTYPES\n# define _(args) args\n#else\n# define _(args) ()\n#endif\n\n#undef __\n#ifdef HAVE_STDARG_PROTOTYPES\n# define __(args) args\n#else\n# define __(args) ()\n#endif\n\n#ifdef __cplusplus\n#define ANYARGS ...\n#else\n#define ANYARGS\n#endif\n\n#define xmalloc ruby_xmalloc\n#define xcalloc ruby_xcalloc\n#define xrealloc ruby_xrealloc\n#define xfree ruby_xfree\n\nvoid *xmalloc _((long));\nvoid *xcalloc _((long,long));\nvoid *xrealloc _((void*,long));\nvoid xfree _((void*));\n\n#define likely(x) __builtin_expect((x),1)\n#define unlikely(x) __builtin_expect((x),0)\n\n#if defined(__APPLE__)\n    #define USING_SYSTEM_ALLOCATOR_LIBRARY\n#endif\n\n/* See system_allocator.c for documentation. */\n#ifdef USING_SYSTEM_ALLOCATOR_LIBRARY\n    void *system_malloc(long size);\n    void system_free(void *ptr);\n#else\n    #define system_malloc(size) malloc(size)\n    #define system_free(ptr) free(ptr)\n#endif\n\n#if SIZEOF_LONG_LONG > 0\n# define LONG_LONG long long\n#elif SIZEOF___INT64 > 0\n# define HAVE_LONG_LONG 1\n# define LONG_LONG __int64\n# undef SIZEOF_LONG_LONG\n# define SIZEOF_LONG_LONG SIZEOF___INT64\n#endif\n\n#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG\n# define BDIGIT unsigned int\n# define SIZEOF_BDIGITS SIZEOF_INT\n# define BDIGIT_DBL unsigned LONG_LONG\n# define BDIGIT_DBL_SIGNED LONG_LONG\n#elif SIZEOF_INT*2 <= SIZEOF_LONG\n# define BDIGIT unsigned int\n# define SIZEOF_BDIGITS SIZEOF_INT\n# define BDIGIT_DBL unsigned long\n# define BDIGIT_DBL_SIGNED long\n#elif SIZEOF_SHORT*2 <= SIZEOF_LONG\n# define BDIGIT unsigned short\n# define SIZEOF_BDIGITS SIZEOF_SHORT\n# define BDIGIT_DBL unsigned long\n# define BDIGIT_DBL_SIGNED long\n#else\n# define BDIGIT unsigned short\n# define SIZEOF_BDIGITS (SIZEOF_LONG/2)\n# define BDIGIT_DBL unsigned long\n# define BDIGIT_DBL_SIGNED long\n#endif\n\n#ifdef __CYGWIN__\n#undef _WIN32\n#endif\n\n#if defined(MSDOS) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__)\n#define DOSISH 1\n#ifndef _WIN32_WCE\n# define DOSISH_DRIVE_LETTER\n#endif\n#endif\n\n/* define RUBY_USE_EUC/SJIS for default kanji-code */\n#ifndef DEFAULT_KCODE\n#if defined(DOSISH) || defined(__CYGWIN__) || defined(__MACOS__) || defined(OS2)\n#define DEFAULT_KCODE KCODE_SJIS\n#else\n#define DEFAULT_KCODE KCODE_EUC\n#endif\n#endif\n\n#if defined(__NeXT__) || defined(__APPLE__)\n/* Do not trust WORDS_BIGENDIAN from configure since -arch compiler flag may\n   result in a different endian.  Instead trust __BIG_ENDIAN__ and\n   __LITTLE_ENDIAN__ which are set correctly by -arch. */\n#undef WORDS_BIGENDIAN\n#ifdef __BIG_ENDIAN__\n#define WORDS_BIGENDIAN\n#endif\n#endif\n\n#ifdef __NeXT__\n/* NextStep, OpenStep, Rhapsody */\n#ifndef S_IRUSR\n#define S_IRUSR 0000400        /* read permission, owner */\n#endif\n#ifndef S_IRGRP\n#define S_IRGRP 0000040        /* read permission, group */\n#endif\n#ifndef S_IROTH\n#define S_IROTH 0000004        /* read permission, other */\n#endif\n#ifndef S_IWUSR\n#define S_IWUSR 0000200        /* write permission, owner */\n#endif\n#ifndef S_IWGRP\n#define S_IWGRP 0000020        /* write permission, group */\n#endif\n#ifndef S_IWOTH\n#define S_IWOTH 0000002        /* write permission, other */\n#endif\n#ifndef S_IXUSR\n#define S_IXUSR 0000100        /* execute/search permission, owner */\n#endif\n#ifndef S_IXGRP\n#define S_IXGRP 0000010        /* execute/search permission, group */\n#endif\n#ifndef S_IXOTH\n#define S_IXOTH 0000001        /* execute/search permission, other */\n#endif\n#ifndef S_IRWXU\n#define S_IRWXU 0000700        /* read, write, execute permissions, owner */\n#endif\n#ifndef S_IRWXG\n#define S_IRWXG 0000070        /* read, write, execute permissions, group */\n#endif\n#ifndef S_IRWXO\n#define S_IRWXO 0000007        /* read, write, execute permissions, other */\n#endif\n#ifndef S_ISBLK\n#define S_ISBLK(mode)  (((mode) & (0170000)) == (0060000))\n#endif\n#ifndef S_ISCHR\n#define S_ISCHR(mode)  (((mode) & (0170000)) == (0020000))\n#endif\n#ifndef S_ISDIR\n#define S_ISDIR(mode)  (((mode) & (0170000)) == (0040000))\n#endif\n#ifndef S_ISFIFO\n#define S_ISFIFO(mode) (((mode) & (0170000)) == (0010000))\n#endif\n#ifndef S_ISREG\n#define S_ISREG(mode)  (((mode) & (0170000)) == (0100000))\n#endif\n#ifndef __APPLE__\n/* NextStep, OpenStep (but not Rhapsody) */\n#ifndef GETPGRP_VOID\n#define GETPGRP_VOID 1\n#endif\n#ifndef WNOHANG\n#define WNOHANG 01\n#endif\n#ifndef WUNTRACED\n#define WUNTRACED 02\n#endif\n#ifndef X_OK\n#define X_OK 1\n#endif\n#endif /* __APPLE__ */\n#endif /* NeXT */\n\n#ifdef _WIN32\n#include \"win32/win32.h\"\n#endif\n\n#if defined(__VMS)\n#include \"vms.h\"\n#endif\n\n#if defined(__BEOS__)\n#include <net/socket.h> /* intern.h needs fd_set definition */\n#endif\n\n#ifdef RUBY_EXPORT\n#undef RUBY_EXTERN\n#endif\n\n#ifndef RUBY_EXTERN\n#define RUBY_EXTERN extern\n#endif\n\n#ifndef EXTERN\n#define EXTERN RUBY_EXTERN\t/* deprecated */\n#endif\n\n#ifndef RUBY_MBCHAR_MAXSIZE\n#define RUBY_MBCHAR_MAXSIZE INT_MAX\n        /* MB_CUR_MAX will not work well in C locale */\n#endif\n\n#if defined(sparc) || defined(__sparc__)\nstatic inline void\nflush_register_windows(void)\n{\n    asm\n#ifdef __GNUC__\n\tvolatile\n#endif\n# if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__)\n\t(\"flushw\")\n# else\n\t(\"ta  0x03\")\n# endif /* trap always to flush register windows if we are on a Sparc system */\n\t;\n}\n#  define FLUSH_REGISTER_WINDOWS flush_register_windows()\n#elif defined(__ia64)\nvoid *rb_ia64_bsp(void);\nvoid rb_ia64_flushrs(void);\n#  define FLUSH_REGISTER_WINDOWS rb_ia64_flushrs()\n#else\n#  define FLUSH_REGISTER_WINDOWS ((void)0)\n#endif\n\n#if defined(DOSISH)\n#define PATH_SEP \";\"\n#elif defined(riscos)\n#define PATH_SEP \",\"\n#else\n#define PATH_SEP \":\"\n#endif\n#define PATH_SEP_CHAR PATH_SEP[0]\n\n#if defined(__human68k__)\n#define PATH_ENV \"path\"\n#else\n#define PATH_ENV \"PATH\"\n#endif\n\n#if defined(DOSISH) && !defined(__human68k__) && !defined(__EMX__)\n#define ENV_IGNORECASE\n#endif\n\n#ifndef CASEFOLD_FILESYSTEM\n# if defined DOSISH || defined __VMS\n#   define CASEFOLD_FILESYSTEM 1\n# else\n#   define CASEFOLD_FILESYSTEM 0\n# endif\n#endif\n\n#ifndef DLEXT_MAXLEN\n#define DLEXT_MAXLEN 4\n#endif\n\n#ifndef RUBY_PLATFORM\n#define RUBY_PLATFORM \"unknown-unknown\"\n#endif\n\n#endif\n"
  },
  {
    "path": "dir.c",
    "content": "/**********************************************************************\n\n  dir.c -\n\n  $Author$\n  $Date$\n  created at: Wed Jan  5 09:51:01 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#if defined HAVE_DIRENT_H && !defined _WIN32\n# include <dirent.h>\n# define NAMLEN(dirent) strlen((dirent)->d_name)\n#elif defined HAVE_DIRECT_H && !defined _WIN32\n# include <direct.h>\n# define NAMLEN(dirent) strlen((dirent)->d_name)\n#else\n# define dirent direct\n# if !defined __NeXT__\n#  define NAMLEN(dirent) (dirent)->d_namlen\n# else\n#  /* On some versions of NextStep, d_namlen is always zero, so avoid it. */\n#  define NAMLEN(dirent) strlen((dirent)->d_name)\n# endif\n# if HAVE_SYS_NDIR_H\n#  include <sys/ndir.h>\n# endif\n# if HAVE_SYS_DIR_H\n#  include <sys/dir.h>\n# endif\n# if HAVE_NDIR_H\n#  include <ndir.h>\n# endif\n# ifdef _WIN32\n#  include \"win32/dir.h\"\n# endif\n#endif\n\n#include <errno.h>\n\n#ifndef HAVE_STDLIB_H\nchar *getenv();\n#endif\n\n#ifndef HAVE_STRING_H\nchar *strchr _((char*,char));\n#endif\n\n#include <ctype.h>\n\n#include \"util.h\"\n\n#if !defined HAVE_LSTAT && !defined lstat\n#define lstat stat\n#endif\n\n#ifndef CASEFOLD_FILESYSTEM\n# if defined DOSISH || defined __VMS\n#   define CASEFOLD_FILESYSTEM 1\n# else\n#   define CASEFOLD_FILESYSTEM 0\n# endif\n#endif\n\n#define FNM_NOESCAPE\t0x01\n#define FNM_PATHNAME\t0x02\n#define FNM_DOTMATCH\t0x04\n#define FNM_CASEFOLD\t0x08\n#if CASEFOLD_FILESYSTEM\n#define FNM_SYSCASE\tFNM_CASEFOLD\n#else\n#define FNM_SYSCASE\t0\n#endif\n\n#define FNM_NOMATCH\t1\n#define FNM_ERROR\t2\n\n#define downcase(c) (nocase && ISUPPER(c) ? tolower(c) : (c))\n#define compare(c1, c2) (((unsigned char)(c1)) - ((unsigned char)(c2)))\n\n/* caution: in case *p == '\\0'\n   Next(p) == p + 1 in single byte environment\n   Next(p) == p     in multi byte environment\n*/\n#if defined(CharNext)\n# define Next(p) CharNext(p)\n#elif defined(DJGPP)\n# define Next(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE))\n#elif defined(__EMX__)\n# define Next(p) ((p) + emx_mblen(p))\nstatic inline int\nemx_mblen(const char *p)\n{\n    int n = mblen(p, RUBY_MBCHAR_MAXSIZE);\n    return (n < 0) ? 1 : n;\n}\n#endif\n\n#ifndef Next /* single byte environment */\n# define Next(p) ((p) + 1)\n# define Inc(p) (++(p))\n# define Compare(p1, p2) (compare(downcase(*(p1)), downcase(*(p2))))\n#else /* multi byte environment */\n# define Inc(p) ((p) = Next(p))\n# define Compare(p1, p2) (CompareImpl(p1, p2, nocase))\nstatic int\nCompareImpl(const char *p1, const char *p2, int nocase)\n{\n    const int len1 = Next(p1) - p1;\n    const int len2 = Next(p2) - p2;\n#ifdef _WIN32\n    char buf1[10], buf2[10]; /* large enough? */\n#endif\n\n    if (len1 < 0 || len2 < 0) {\n\trb_fatal(\"CompareImpl: negative len\");\n    }\n\n    if (len1 == 0) return  len2;\n    if (len2 == 0) return -len1;\n\n#ifdef _WIN32\n    if (nocase && rb_w32_iswinnt()) {\n\tif (len1 > 1) {\n\t    if (len1 >= sizeof(buf1)) {\n\t\trb_fatal(\"CompareImpl: too large len\");\n\t    }\n\t    memcpy(buf1, p1, len1);\n\t    buf1[len1] = '\\0';\n\t    CharLower(buf1);\n\t    p1 = buf1; /* trick */\n\t}\n\tif (len2 > 1) {\n\t    if (len2 >= sizeof(buf2)) {\n\t\trb_fatal(\"CompareImpl: too large len\");\n\t    }\n\t    memcpy(buf2, p2, len2);\n\t    buf2[len2] = '\\0';\n\t    CharLower(buf2);\n\t    p2 = buf2; /* trick */\n\t}\n    }\n#endif\n    if (len1 == 1)\n\tif (len2 == 1)\n\t    return compare(downcase(*p1), downcase(*p2));\n\telse {\n\t    const int ret = compare(downcase(*p1), *p2);\n\t    return ret ? ret : -1;\n\t}\n    else\n\tif (len2 == 1) {\n\t    const int ret = compare(*p1, downcase(*p2));\n\t    return ret ? ret : 1;\n\t}\n\telse {\n\t    const int ret = memcmp(p1, p2, len1 < len2 ? len1 : len2);\n\t    return ret ? ret : len1 - len2;\n\t}\n}\n#endif /* environment */\n\nstatic char *\nbracket(p, s, flags)\n    const char *p; /* pattern (next to '[') */\n    const char *s; /* string */\n    int flags;\n{\n    const int nocase = flags & FNM_CASEFOLD;\n    const int escape = !(flags & FNM_NOESCAPE);\n\n    int ok = 0, not = 0;\n\n    if (*p == '!' || *p == '^') {\n\tnot = 1;\n\tp++;\n    }\n\n    while (*p != ']') {\n\tconst char *t1 = p;\n\tif (escape && *t1 == '\\\\')\n\t    t1++;\n\tif (!*t1)\n\t    return NULL;\n\tp = Next(t1);\n\tif (p[0] == '-' && p[1] != ']') {\n\t    const char *t2 = p + 1;\n\t    if (escape && *t2 == '\\\\')\n\t\tt2++;\n\t    if (!*t2)\n\t\treturn NULL;\n\t    p = Next(t2);\n\t    if (!ok && Compare(t1, s) <= 0 && Compare(s, t2) <= 0)\n\t\tok = 1;\n\t}\n\telse\n\t    if (!ok && Compare(t1, s) == 0)\n\t\tok = 1;\n    }\n\n    return ok == not ? NULL : (char *)p + 1;\n}\n\n/* If FNM_PATHNAME is set, only path element will be matched. (upto '/' or '\\0')\n   Otherwise, entire string will be matched.\n   End marker itself won't be compared.\n   And if function succeeds, *pcur reaches end marker.\n*/\n#define UNESCAPE(p) (escape && *(p) == '\\\\' ? (p) + 1 : (p))\n#define ISEND(p) (!*(p) || (pathname && *(p) == '/'))\n#define RETURN(val) return *pcur = p, *scur = s, (val);\n\nstatic int\nfnmatch_helper(pcur, scur, flags)\n    const char **pcur; /* pattern */\n    const char **scur; /* string */\n    int flags;\n{\n    const int period = !(flags & FNM_DOTMATCH);\n    const int pathname = flags & FNM_PATHNAME;\n    const int escape = !(flags & FNM_NOESCAPE);\n    const int nocase = flags & FNM_CASEFOLD;\n\n    const char *ptmp = 0;\n    const char *stmp = 0;\n\n    const char *p = *pcur;\n    const char *s = *scur;\n\n    if (period && *s == '.' && *UNESCAPE(p) != '.') /* leading period */\n\tRETURN(FNM_NOMATCH);\n\n    while (1) {\n\tswitch (*p) {\n\t  case '*':\n\t    do { p++; } while (*p == '*');\n\t    if (ISEND(UNESCAPE(p))) {\n\t\tp = UNESCAPE(p);\n\t\tRETURN(0);\n\t    }\n\t    if (ISEND(s))\n\t\tRETURN(FNM_NOMATCH);\n\t    ptmp = p;\n\t    stmp = s;\n\t    continue;\n\n\t  case '?':\n\t    if (ISEND(s))\n\t\tRETURN(FNM_NOMATCH);\n\t    p++;\n\t    Inc(s);\n\t    continue;\n\n\t  case '[': {\n\t    const char *t;\n\t    if (ISEND(s))\n\t\tRETURN(FNM_NOMATCH);\n\t    if ((t = bracket(p + 1, s, flags)) != 0) {\n\t\tp = t;\n\t\tInc(s);\n\t\tcontinue;\n\t    }\n\t    goto failed;\n\t  }\n\t}\n\n\t/* ordinary */\n\tp = UNESCAPE(p);\n\tif (ISEND(s))\n\t    RETURN(ISEND(p) ? 0 : FNM_NOMATCH);\n\tif (ISEND(p))\n\t    goto failed;\n\tif (Compare(p, s) != 0)\n\t    goto failed;\n\tInc(p);\n\tInc(s);\n\tcontinue;\n\n      failed: /* try next '*' position */\n\tif (ptmp && stmp) {\n\t    p = ptmp;\n\t    Inc(stmp); /* !ISEND(*stmp) */\n\t    s = stmp;\n\t    continue;\n\t}\n\tRETURN(FNM_NOMATCH);\n    }\n}\n\nstatic int\nfnmatch(p, s, flags)\n    const char *p; /* pattern */\n    const char *s; /* string */\n    int flags;\n{\n    const int period = !(flags & FNM_DOTMATCH);\n    const int pathname = flags & FNM_PATHNAME;\n\n    const char *ptmp = 0;\n    const char *stmp = 0;\n\n    if (pathname) {\n\twhile (1) {\n\t    if (p[0] == '*' && p[1] == '*' && p[2] == '/') {\n\t\tdo { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');\n\t\tptmp = p;\n\t\tstmp = s;\n\t    }\n\t    if (fnmatch_helper(&p, &s, flags) == 0) {\n\t\twhile (*s && *s != '/') Inc(s);\n\t\tif (*p && *s) {\n\t\t    p++;\n\t\t    s++;\n\t\t    continue;\n\t\t}\n\t\tif (!*p && !*s)\n\t\t    return 0;\n\t    }\n\t    /* failed : try next recursion */\n\t    if (ptmp && stmp && !(period && *stmp == '.')) {\n\t\twhile (*stmp && *stmp != '/') Inc(stmp);\n\t\tif (*stmp) {\n\t\t    p = ptmp;\n\t\t    stmp++;\n\t\t    s = stmp;\n\t\t    continue;\n\t\t}\n\t    }\n\t    return FNM_NOMATCH;\n\t}\n    }\n    else\n\treturn fnmatch_helper(&p, &s, flags);\n}\n\nVALUE rb_cDir;\n\nstruct dir_data {\n    DIR *dir;\n    char *path;\n};\n\nstatic void\nfree_dir(dir)\n    struct dir_data *dir;\n{\n    if (dir) {\n\tif (dir->dir) closedir(dir->dir);\n\tif (dir->path) free(dir->path);\n    }\n    free(dir);\n}\n\nstatic VALUE dir_close _((VALUE));\n\nstatic VALUE dir_s_alloc _((VALUE));\nstatic VALUE\ndir_s_alloc(klass)\n    VALUE klass;\n{\n    struct dir_data *dirp;\n    VALUE obj = Data_Make_Struct(klass, struct dir_data, 0, free_dir, dirp);\n\n    dirp->dir = NULL;\n    dirp->path = NULL;\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     Dir.new( string ) -> aDir\n *\n *  Returns a new directory object for the named directory.\n */\nstatic VALUE\ndir_initialize(dir, dirname)\n    VALUE dir, dirname;\n{\n    struct dir_data *dp;\n\n    SafeStringValue(dirname);\n    Data_Get_Struct(dir, struct dir_data, dp);\n    if (dp->dir) closedir(dp->dir);\n    if (dp->path) free(dp->path);\n    dp->dir = NULL;\n    dp->path = NULL;\n    dp->dir = opendir(RSTRING(dirname)->ptr);\n    if (dp->dir == NULL) {\n\tif (errno == EMFILE || errno == ENFILE) {\n\t    rb_gc();\n\t    dp->dir = opendir(RSTRING(dirname)->ptr);\n\t}\n\tif (dp->dir == NULL) {\n\t    rb_sys_fail(RSTRING(dirname)->ptr);\n\t}\n    }\n    dp->path = strdup(RSTRING(dirname)->ptr);\n\n    return dir;\n}\n\n/*\n *  call-seq:\n *     Dir.open( string ) => aDir\n *     Dir.open( string ) {| aDir | block } => anObject\n *\n *  With no block, <code>open</code> is a synonym for\n *  <code>Dir::new</code>. If a block is present, it is passed\n *  <i>aDir</i> as a parameter. The directory is closed at the end of\n *  the block, and <code>Dir::open</code> returns the value of the\n *  block.\n */\n\nstatic VALUE\ndir_s_open(klass, dirname)\n    VALUE klass, dirname;\n{\n    struct dir_data *dp;\n    VALUE dir = Data_Make_Struct(klass, struct dir_data, 0, free_dir, dp);\n\n    dir_initialize(dir, dirname);\n    if (rb_block_given_p()) {\n\treturn rb_ensure(rb_yield, dir, dir_close, dir);\n    }\n\n    return dir;\n}\n\nstatic void\ndir_closed()\n{\n    rb_raise(rb_eIOError, \"closed directory\");\n}\n\nstatic void\ndir_check(dir)\n    VALUE dir;\n{\n    if (!OBJ_TAINTED(dir) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: operation on untainted Dir\");\n    rb_check_frozen(dir);\n}\n\n#define GetDIR(obj, dirp) do {\\\n    dir_check(dir);\\\n    Data_Get_Struct(obj, struct dir_data, dirp);\\\n    if (dirp->dir == NULL) dir_closed();\\\n} while (0)\n\n/*\n *  call-seq:\n *     dir.inspect => string\n *\n *  Return a string describing this Dir object.\n */\nstatic VALUE\ndir_inspect(dir)\n    VALUE dir;\n{\n    struct dir_data *dirp;\n\n    Data_Get_Struct(dir, struct dir_data, dirp);\n    if (dirp->path) {\n\tconst char *c = rb_obj_classname(dir);\n\tint len = strlen(c) + strlen(dirp->path) + 4;\n\tVALUE s = rb_str_new(0, len);\n\tsnprintf(RSTRING_PTR(s), len+1, \"#<%s:%s>\", c, dirp->path);\n\treturn s;\n    }\n    return rb_funcall(dir, rb_intern(\"to_s\"), 0, 0);\n}\n\n/*\n *  call-seq:\n *     dir.path => string or nil\n *\n *  Returns the path parameter passed to <em>dir</em>'s constructor.\n *\n *     d = Dir.new(\"..\")\n *     d.path   #=> \"..\"\n */\nstatic VALUE\ndir_path(dir)\n    VALUE dir;\n{\n    struct dir_data *dirp;\n\n    Data_Get_Struct(dir, struct dir_data, dirp);\n    if (!dirp->path) return Qnil;\n    return rb_str_new2(dirp->path);\n}\n\n/*\n *  call-seq:\n *     dir.read => string or nil\n *\n *  Reads the next entry from <em>dir</em> and returns it as a string.\n *  Returns <code>nil</code> at the end of the stream.\n *\n *     d = Dir.new(\"testdir\")\n *     d.read   #=> \".\"\n *     d.read   #=> \"..\"\n *     d.read   #=> \"config.h\"\n */\nstatic VALUE\ndir_read(dir)\n    VALUE dir;\n{\n    struct dir_data *dirp;\n    struct dirent *dp;\n\n    GetDIR(dir, dirp);\n    errno = 0;\n    dp = readdir(dirp->dir);\n    if (dp) {\n\treturn rb_tainted_str_new(dp->d_name, NAMLEN(dp));\n    }\n    else if (errno == 0) {\t/* end of stream */\n\treturn Qnil;\n    }\n    else {\n\trb_sys_fail(0);\n    }\n    return Qnil;\t\t/* not reached */\n}\n\n/*\n *  call-seq:\n *     dir.each { |filename| block }  => dir\n *\n *  Calls the block once for each entry in this directory, passing the\n *  filename of each entry as a parameter to the block.\n *\n *     d = Dir.new(\"testdir\")\n *     d.each  {|x| puts \"Got #{x}\" }\n *\n *  <em>produces:</em>\n *\n *     Got .\n *     Got ..\n *     Got config.h\n *     Got main.rb\n */\nstatic VALUE\ndir_each(dir)\n    VALUE dir;\n{\n    struct dir_data *dirp;\n    struct dirent *dp;\n\n    RETURN_ENUMERATOR(dir, 0, 0);\n    GetDIR(dir, dirp);\n    rewinddir(dirp->dir);\n    for (dp = readdir(dirp->dir); dp != NULL; dp = readdir(dirp->dir)) {\n\trb_yield(rb_tainted_str_new(dp->d_name, NAMLEN(dp)));\n\tif (dirp->dir == NULL) dir_closed();\n    }\n    return dir;\n}\n\n/*\n *  call-seq:\n *     dir.pos => integer\n *     dir.tell => integer\n *\n *  Returns the current position in <em>dir</em>. See also\n *  <code>Dir#seek</code>.\n *\n *     d = Dir.new(\"testdir\")\n *     d.tell   #=> 0\n *     d.read   #=> \".\"\n *     d.tell   #=> 12\n */\nstatic VALUE\ndir_tell(dir)\n    VALUE dir;\n{\n#ifdef HAVE_TELLDIR\n    struct dir_data *dirp;\n    long pos;\n\n    GetDIR(dir, dirp);\n    pos = telldir(dirp->dir);\n    return rb_int2inum(pos);\n#else\n    rb_notimplement();\n#endif\n}\n\n/*\n *  call-seq:\n *     dir.seek( integer ) => dir\n *\n *  Seeks to a particular location in <em>dir</em>. <i>integer</i>\n *  must be a value returned by <code>Dir#tell</code>.\n *\n *     d = Dir.new(\"testdir\")   #=> #<Dir:0x401b3c40>\n *     d.read                   #=> \".\"\n *     i = d.tell               #=> 12\n *     d.read                   #=> \"..\"\n *     d.seek(i)                #=> #<Dir:0x401b3c40>\n *     d.read                   #=> \"..\"\n */\nstatic VALUE\ndir_seek(dir, pos)\n    VALUE dir, pos;\n{\n    struct dir_data *dirp;\n    off_t p = NUM2OFFT(pos);\n\n    GetDIR(dir, dirp);\n#ifdef HAVE_SEEKDIR\n    seekdir(dirp->dir, p);\n    return dir;\n#else\n    rb_notimplement();\n#endif\n}\n\n/*\n *  call-seq:\n *     dir.pos( integer ) => integer\n *\n *  Synonym for <code>Dir#seek</code>, but returns the position\n *  parameter.\n *\n *     d = Dir.new(\"testdir\")   #=> #<Dir:0x401b3c40>\n *     d.read                   #=> \".\"\n *     i = d.pos                #=> 12\n *     d.read                   #=> \"..\"\n *     d.pos = i                #=> 12\n *     d.read                   #=> \"..\"\n */\nstatic VALUE\ndir_set_pos(dir, pos)\n    VALUE dir, pos;\n{\n    dir_seek(dir, pos);\n    return pos;\n}\n\n/*\n *  call-seq:\n *     dir.rewind => dir\n *\n *  Repositions <em>dir</em> to the first entry.\n *\n *     d = Dir.new(\"testdir\")\n *     d.read     #=> \".\"\n *     d.rewind   #=> #<Dir:0x401b3fb0>\n *     d.read     #=> \".\"\n */\nstatic VALUE\ndir_rewind(dir)\n    VALUE dir;\n{\n    struct dir_data *dirp;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(dir)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close\");\n    }\n    GetDIR(dir, dirp);\n    rewinddir(dirp->dir);\n    return dir;\n}\n\n/*\n *  call-seq:\n *     dir.close => nil\n *\n *  Closes the directory stream. Any further attempts to access\n *  <em>dir</em> will raise an <code>IOError</code>.\n *\n *     d = Dir.new(\"testdir\")\n *     d.close   #=> nil\n */\nstatic VALUE\ndir_close(dir)\n    VALUE dir;\n{\n    struct dir_data *dirp;\n\n    GetDIR(dir, dirp);\n    closedir(dirp->dir);\n    dirp->dir = NULL;\n\n    return Qnil;\n}\n\nstatic void\ndir_chdir(path)\n    VALUE path;\n{\n    if (chdir(RSTRING(path)->ptr) < 0)\n\trb_sys_fail(RSTRING(path)->ptr);\n}\n\nstatic int chdir_blocking = 0;\nstatic VALUE chdir_thread = Qnil;\n\nstruct chdir_data {\n    VALUE old_path, new_path;\n    int done;\n};\n\nstatic VALUE\nchdir_yield(args)\n    struct chdir_data *args;\n{\n    dir_chdir(args->new_path);\n    args->done = Qtrue;\n    chdir_blocking++;\n    if (chdir_thread == Qnil)\n\tchdir_thread = rb_thread_current();\n    return rb_yield(args->new_path);\n}\n\nstatic VALUE\nchdir_restore(args)\n    struct chdir_data *args;\n{\n    if (args->done) {\n\tchdir_blocking--;\n\tif (chdir_blocking == 0)\n\t    chdir_thread = Qnil;\n\tdir_chdir(args->old_path);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     Dir.chdir( [ string] ) => 0\n *     Dir.chdir( [ string] ) {| path | block }  => anObject\n *\n *  Changes the current working directory of the process to the given\n *  string. When called without an argument, changes the directory to\n *  the value of the environment variable <code>HOME</code>, or\n *  <code>LOGDIR</code>. <code>SystemCallError</code> (probably\n *  <code>Errno::ENOENT</code>) if the target directory does not exist.\n *\n *  If a block is given, it is passed the name of the new current\n *  directory, and the block is executed with that as the current\n *  directory. The original working directory is restored when the block\n *  exits. The return value of <code>chdir</code> is the value of the\n *  block. <code>chdir</code> blocks can be nested, but in a\n *  multi-threaded program an error will be raised if a thread attempts\n *  to open a <code>chdir</code> block while another thread has one\n *  open.\n *\n *     Dir.chdir(\"/var/spool/mail\")\n *     puts Dir.pwd\n *     Dir.chdir(\"/tmp\") do\n *       puts Dir.pwd\n *       Dir.chdir(\"/usr\") do\n *         puts Dir.pwd\n *       end\n *       puts Dir.pwd\n *     end\n *     puts Dir.pwd\n *\n *  <em>produces:</em>\n *\n *     /var/spool/mail\n *     /tmp\n *     /usr\n *     /tmp\n *     /var/spool/mail\n */\nstatic VALUE\ndir_s_chdir(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE path = Qnil;\n\n    rb_secure(2);\n    if (rb_scan_args(argc, argv, \"01\", &path) == 1) {\n\tSafeStringValue(path);\n    }\n    else {\n\tconst char *dist = getenv(\"HOME\");\n\tif (!dist) {\n\t    dist = getenv(\"LOGDIR\");\n\t    if (!dist) rb_raise(rb_eArgError, \"HOME/LOGDIR not set\");\n\t}\n\tpath = rb_str_new2(dist);\n    }\n\n    if (chdir_blocking > 0) {\n\tif (!rb_block_given_p() || rb_thread_current() != chdir_thread)\n\t    rb_warn(\"conflicting chdir during another chdir block\");\n    }\n\n    if (rb_block_given_p()) {\n\tstruct chdir_data args;\n\tchar *cwd = my_getcwd();\n\n\targs.old_path = rb_tainted_str_new2(cwd); free(cwd);\n\targs.new_path = path;\n\targs.done = Qfalse;\n\treturn rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);\n    }\n    dir_chdir(path);\n\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     Dir.getwd => string\n *     Dir.pwd => string\n *\n *  Returns the path to the current working directory of this process as\n *  a string.\n *\n *     Dir.chdir(\"/tmp\")   #=> 0\n *     Dir.getwd           #=> \"/tmp\"\n */\nstatic VALUE\ndir_s_getwd(dir)\n    VALUE dir;\n{\n    char *path;\n    VALUE cwd;\n\n    rb_secure(4);\n    path = my_getcwd();\n    cwd = rb_tainted_str_new2(path);\n\n    free(path);\n    return cwd;\n}\n\nstatic void check_dirname _((volatile VALUE *));\nstatic void\ncheck_dirname(dir)\n    volatile VALUE *dir;\n{\n    char *path, *pend;\n\n    SafeStringValue(*dir);\n    rb_secure(2);\n    path = RSTRING(*dir)->ptr;\n    if (path && *(pend = rb_path_end(rb_path_skip_prefix(path)))) {\n\t*dir = rb_str_new(path, pend - path);\n    }\n}\n\n/*\n *  call-seq:\n *     Dir.chroot( string ) => 0\n *\n *  Changes this process's idea of the file system root. Only a\n *  privileged process may make this call. Not available on all\n *  platforms. On Unix systems, see <code>chroot(2)</code> for more\n *  information.\n */\nstatic VALUE\ndir_s_chroot(dir, path)\n    VALUE dir, path;\n{\n#if defined(HAVE_CHROOT) && !defined(__CHECKER__)\n    check_dirname(&path);\n\n    if (chroot(RSTRING(path)->ptr) == -1)\n\trb_sys_fail(RSTRING(path)->ptr);\n\n    return INT2FIX(0);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n/*\n *  call-seq:\n *     Dir.mkdir( string [, integer] ) => 0\n *\n *  Makes a new directory named by <i>string</i>, with permissions\n *  specified by the optional parameter <i>anInteger</i>. The\n *  permissions may be modified by the value of\n *  <code>File::umask</code>, and are ignored on NT. Raises a\n *  <code>SystemCallError</code> if the directory cannot be created. See\n *  also the discussion of permissions in the class documentation for\n *  <code>File</code>.\n *\n */\nstatic VALUE\ndir_s_mkdir(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE path, vmode;\n    int mode;\n\n    if (rb_scan_args(argc, argv, \"11\", &path, &vmode) == 2) {\n\tmode = NUM2INT(vmode);\n    }\n    else {\n\tmode = 0777;\n    }\n\n    check_dirname(&path);\n    if (mkdir(RSTRING(path)->ptr, mode) == -1)\n\trb_sys_fail(RSTRING(path)->ptr);\n\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     Dir.delete( string ) => 0\n *     Dir.rmdir( string ) => 0\n *     Dir.unlink( string ) => 0\n *\n *  Deletes the named directory. Raises a subclass of\n *  <code>SystemCallError</code> if the directory isn't empty.\n */\nstatic VALUE\ndir_s_rmdir(obj, dir)\n    VALUE obj, dir;\n{\n    check_dirname(&dir);\n    if (rmdir(RSTRING(dir)->ptr) < 0)\n\trb_sys_fail(RSTRING(dir)->ptr);\n\n    return INT2FIX(0);\n}\n\nstatic void\nsys_warning_1(mesg)\n    const char* mesg;\n{\n    rb_sys_warning(\"%s\", mesg);\n}\n\n#define GLOB_VERBOSE\t(1UL << (sizeof(int) * CHAR_BIT - 1))\n#define sys_warning(val) \\\n    (void)((flags & GLOB_VERBOSE) && rb_protect((VALUE (*)_((VALUE)))sys_warning_1, (VALUE)(val), 0))\n\n#define GLOB_ALLOC(type) (type *)malloc(sizeof(type))\n#define GLOB_ALLOC_N(type, n) (type *)malloc(sizeof(type) * (n))\n#define GLOB_JUMP_TAG(status) ((status == -1) ? rb_memerror() : rb_jump_tag(status))\n\n/*\n * ENOTDIR can be returned by stat(2) if a non-leaf element of the path\n * is not a directory.\n */\n#define to_be_ignored(e) ((e) == ENOENT || (e) == ENOTDIR)\n\n/* System call with warning */\nstatic int\ndo_stat(const char *path, struct stat *pst, int flags)\n\n{\n    int ret = stat(path, pst);\n    if (ret < 0 && !to_be_ignored(errno))\n\tsys_warning(path);\n\n    return ret;\n}\n\nstatic int\ndo_lstat(const char *path, struct stat *pst, int flags)\n{\n    int ret = lstat(path, pst);\n    if (ret < 0 && !to_be_ignored(errno))\n\tsys_warning(path);\n\n    return ret;\n}\n\nstatic DIR *\ndo_opendir(const char *path, int flags)\n{\n    DIR *dirp = opendir(path);\n    if (dirp == NULL && !to_be_ignored(errno))\n\tsys_warning(path);\n\n    return dirp;\n}\n\n/* Return nonzero if S has any special globbing chars in it.  */\nstatic int\nhas_magic(s, flags)\n    const char *s;\n    int flags;\n{\n    const int escape = !(flags & FNM_NOESCAPE);\n    const int nocase = flags & FNM_CASEFOLD;\n\n    register const char *p = s;\n    register char c;\n\n    while ((c = *p++) != 0) {\n\tswitch (c) {\n\t  case '*':\n\t  case '?':\n\t  case '[':\n\t    return 1;\n\n\t  case '\\\\':\n\t    if (escape && !(c = *p++))\n\t\treturn 0;\n\t    continue;\n\n\t  default:\n\t    if (!FNM_SYSCASE && ISALPHA(c) && nocase)\n\t\treturn 1;\n\t}\n\n\tp = Next(p-1);\n    }\n\n    return 0;\n}\n\n/* Find separator in globbing pattern. */\nstatic char *\nfind_dirsep(const char *s, int flags)\n{\n    const int escape = !(flags & FNM_NOESCAPE);\n\n    register const char *p = s;\n    register char c;\n    int open = 0;\n\n    while ((c = *p++) != 0) {\n\tswitch (c) {\n\t  case '[':\n\t    open = 1;\n\t    continue;\n\t  case ']':\n\t    open = 0;\n\t    continue;\n\n\t  case '/':\n\t    if (!open)\n\t\treturn (char *)p-1;\n\t    continue;\n\n\t  case '\\\\':\n\t    if (escape && !(c = *p++))\n\t\treturn (char *)p-1;\n\t    continue;\n\t}\n\n\tp = Next(p-1);\n    }\n\n    return (char *)p-1;\n}\n\n/* Remove escaping backslashes */\nstatic void\nremove_backslashes(p)\n    char *p;\n{\n    char *t = p;\n    char *s = p;\n\n    while (*p) {\n\tif (*p == '\\\\') {\n\t    if (t != s)\n\t\tmemmove(t, s, p - s);\n\t    t += p - s;\n\t    s = ++p;\n\t    if (!*p) break;\n\t}\n\tInc(p);\n    }\n\n    while (*p++);\n\n    if (t != s)\n\tmemmove(t, s, p - s); /* move '\\0' too */\n}\n\n/* Globing pattern */\nenum glob_pattern_type { PLAIN, MAGICAL, RECURSIVE, MATCH_ALL, MATCH_DIR };\n\nstruct glob_pattern {\n    char *str;\n    enum glob_pattern_type type;\n    struct glob_pattern *next;\n};\n\nstatic void glob_free_pattern(struct glob_pattern *list);\n\nstatic struct glob_pattern *\nglob_make_pattern(const char *p, int flags)\n{\n    struct glob_pattern *list, *tmp, **tail = &list;\n    int dirsep = 0; /* pattern is terminated with '/' */\n\n    while (*p) {\n\ttmp = GLOB_ALLOC(struct glob_pattern);\n\tif (!tmp) goto error;\n\tif (p[0] == '*' && p[1] == '*' && p[2] == '/') {\n\t    /* fold continuous RECURSIVEs (needed in glob_helper) */\n\t    do { p += 3; } while (p[0] == '*' && p[1] == '*' && p[2] == '/');\n\t    tmp->type = RECURSIVE;\n\t    tmp->str = 0;\n\t    dirsep = 1;\n\t}\n\telse {\n\t    const char *m = find_dirsep(p, flags);\n\t    char *buf = GLOB_ALLOC_N(char, m-p+1);\n\t    if (!buf) {\n\t\tfree(tmp);\n\t\tgoto error;\n\t    }\n\t    memcpy(buf, p, m-p);\n\t    buf[m-p] = '\\0';\n\t    tmp->type = has_magic(buf, flags) ? MAGICAL : PLAIN;\n\t    tmp->str = buf;\n\t    if (*m) {\n\t\tdirsep = 1;\n\t\tp = m + 1;\n\t    }\n\t    else {\n\t\tdirsep = 0;\n\t\tp = m;\n\t    }\n\t}\n\t*tail = tmp;\n\ttail = &tmp->next;\n    }\n\n    tmp = GLOB_ALLOC(struct glob_pattern);\n    if (!tmp) {\n      error:\n\t*tail = 0;\n\tglob_free_pattern(list);\n\treturn 0;\n    }\n    tmp->type = dirsep ? MATCH_DIR : MATCH_ALL;\n    tmp->str = 0;\n    *tail = tmp;\n    tmp->next = 0;\n\n    return list;\n}\n\nstatic void\nglob_free_pattern(struct glob_pattern *list)\n{\n    while (list) {\n\tstruct glob_pattern *tmp = list;\n\tlist = list->next;\n\tif (tmp->str)\n\t    free(tmp->str);\n\tfree(tmp);\n    }\n}\n\nstatic char *\njoin_path(const char *path, int dirsep, const char *name)\n{\n    long len = strlen(path);\n    char *buf = GLOB_ALLOC_N(char, len+strlen(name)+(dirsep?1:0)+1);\n\n    if (!buf) return 0;\n    memcpy(buf, path, len);\n    if (dirsep) {\n\tstrcpy(buf+len, \"/\");\n\tlen++;\n    }\n    strcpy(buf+len, name);\n    return buf;\n}\n\nenum answer { YES, NO, UNKNOWN };\n\n#ifndef S_ISLNK\n#  ifndef S_IFLNK\n#    define S_ISLNK(m) (0)\n#  else\n#    define S_ISLNK(m) ((m & S_IFMT) == S_IFLNK)\n#  endif\n#endif\n\n#ifndef S_ISDIR\n#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)\n#endif\n\nstruct glob_args {\n    void (*func) _((const char*, VALUE));\n    const char *c;\n    VALUE v;\n};\n\nstatic VALUE glob_func_caller _((VALUE));\n\nstatic VALUE\nglob_func_caller(val)\n    VALUE val;\n{\n    struct glob_args *args = (struct glob_args *)val;\n\n    (*args->func)(args->c, args->v);\n    return Qnil;\n}\n\n#define glob_call_func(func, path, arg) (*func)(path, arg)\n\nstatic int glob_helper _((const char *, int, enum answer, enum answer, struct glob_pattern **, struct glob_pattern **, int, ruby_glob_func *, VALUE));\n\nstatic int\nglob_helper(path, dirsep, exist, isdir, beg, end, flags, func, arg)\n    const char *path;\n    int dirsep; /* '/' should be placed before appending child entry's name to 'path'. */\n    enum answer exist; /* Does 'path' indicate an existing entry? */\n    enum answer isdir; /* Does 'path' indicate a directory or a symlink to a directory? */\n    struct glob_pattern **beg;\n    struct glob_pattern **end;\n    int flags;\n    ruby_glob_func *func;\n    VALUE arg;\n{\n    struct stat st;\n    int status = 0;\n    struct glob_pattern **cur, **new_beg, **new_end;\n    int plain = 0, magical = 0, recursive = 0, match_all = 0, match_dir = 0;\n    int escape = !(flags & FNM_NOESCAPE);\n\n    for (cur = beg; cur < end; ++cur) {\n\tstruct glob_pattern *p = *cur;\n\tif (p->type == RECURSIVE) {\n\t    recursive = 1;\n\t    p = p->next;\n\t}\n\tswitch (p->type) {\n\tcase PLAIN:\n\t    plain = 1;\n\t    break;\n\tcase MAGICAL:\n\t    magical = 1;\n\t    break;\n\tcase MATCH_ALL:\n\t    match_all = 1;\n\t    break;\n\tcase MATCH_DIR:\n\t    match_dir = 1;\n\t    break;\n\tcase RECURSIVE:\n\t    rb_bug(\"continuous RECURSIVEs\");\n\t}\n    }\n\n    if (*path) {\n\tif (match_all && exist == UNKNOWN) {\n\t    if (do_lstat(path, &st, flags) == 0) {\n\t\texist = YES;\n\t\tisdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;\n\t    }\n\t    else {\n\t\texist = NO;\n\t\tisdir = NO;\n\t    }\n\t}\n\tif (match_dir && isdir == UNKNOWN) {\n\t    if (do_stat(path, &st, flags) == 0) {\n\t\texist = YES;\n\t\tisdir = S_ISDIR(st.st_mode) ? YES : NO;\n\t    }\n\t    else {\n\t\texist = NO;\n\t\tisdir = NO;\n\t    }\n\t}\n\tif (match_all && exist == YES) {\n\t    status = glob_call_func(func, path, arg);\n\t    if (status) return status;\n\t}\n\tif (match_dir && isdir == YES) {\n\t    char *tmp = join_path(path, dirsep, \"\");\n\t    if (!tmp) return -1;\n\t    status = glob_call_func(func, tmp, arg);\n\t    free(tmp);\n\t    if (status) return status;\n\t}\n    }\n\n    if (exist == NO || isdir == NO) return 0;\n\n    if (magical || recursive) {\n\tstruct dirent *dp;\n\tDIR *dirp = do_opendir(*path ? path : \".\", flags);\n\tif (dirp == NULL) return 0;\n\n\tfor (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {\n\t    char *buf = join_path(path, dirsep, dp->d_name);\n\t    enum answer new_isdir = UNKNOWN;\n\n\t    if (!buf) {\n\t\tstatus = -1;\n\t\tbreak;\n\t    }\n\t    if (recursive && strcmp(dp->d_name, \".\") != 0 && strcmp(dp->d_name, \"..\") != 0\n\t\t&& fnmatch(\"*\", dp->d_name, flags) == 0) {\n#ifndef _WIN32\n\t\tif (do_lstat(buf, &st, flags) == 0)\n\t\t    new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;\n\t\telse\n\t\t    new_isdir = NO;\n#else\n\t\tnew_isdir = dp->d_isdir ? (!dp->d_isrep ? YES : UNKNOWN) : NO;\n#endif\n\t    }\n\n\t    new_beg = new_end = GLOB_ALLOC_N(struct glob_pattern *, (end - beg) * 2);\n\t    if (!new_beg) {\n\t\tstatus = -1;\n\t\tbreak;\n\t    }\n\n\t    for (cur = beg; cur < end; ++cur) {\n\t\tstruct glob_pattern *p = *cur;\n\t\tif (p->type == RECURSIVE) {\n\t\t    if (new_isdir == YES) /* not symlink but real directory */\n\t\t\t*new_end++ = p; /* append recursive pattern */\n\t\t    p = p->next; /* 0 times recursion */\n\t\t}\n\t\tif (p->type == PLAIN || p->type == MAGICAL) {\n\t\t    if (fnmatch(p->str, dp->d_name, flags) == 0)\n\t\t\t*new_end++ = p->next;\n\t\t}\n\t    }\n\n\t    status = glob_helper(buf, 1, YES, new_isdir, new_beg, new_end, flags, func, arg);\n\t    free(buf);\n\t    free(new_beg);\n\t    if (status) break;\n\t}\n\n\tclosedir(dirp);\n    }\n    else if (plain) {\n\tstruct glob_pattern **copy_beg, **copy_end, **cur2;\n\n\tcopy_beg = copy_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);\n\tif (!copy_beg) return -1;\n\tfor (cur = beg; cur < end; ++cur)\n\t    *copy_end++ = (*cur)->type == PLAIN ? *cur : 0;\n\n\tfor (cur = copy_beg; cur < copy_end; ++cur) {\n\t    if (*cur) {\n\t\tchar *buf;\n\t\tchar *name;\n\t\tname = GLOB_ALLOC_N(char, strlen((*cur)->str) + 1);\n\t\tif (!name) {\n\t\t    status = -1;\n\t\t    break;\n\t\t}\n\t\tstrcpy(name, (*cur)->str);\n\t\tif (escape) remove_backslashes(name);\n\n\t\tnew_beg = new_end = GLOB_ALLOC_N(struct glob_pattern *, end - beg);\n\t\tif (!new_beg) {\n\t\t    free(name);\n\t\t    status = -1;\n\t\t    break;\n\t\t}\n\t\t*new_end++ = (*cur)->next;\n\t\tfor (cur2 = cur + 1; cur2 < copy_end; ++cur2) {\n\t\t    if (*cur2 && fnmatch((*cur2)->str, name, flags) == 0) {\n\t\t\t*new_end++ = (*cur2)->next;\n\t\t\t*cur2 = 0;\n\t\t    }\n\t\t}\n\n\t\tbuf = join_path(path, dirsep, name);\n\t\tfree(name);\n\t\tif (!buf) {\n\t\t    free(new_beg);\n\t\t    status = -1;\n\t\t    break;\n\t\t}\n\t\tstatus = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, new_end, flags, func, arg);\n\t\tfree(buf);\n\t\tfree(new_beg);\n\t\tif (status) break;\n\t    }\n\t}\n\n\tfree(copy_beg);\n    }\n\n    return status;\n}\n\nstatic int\nruby_glob0(path, flags, func, arg)\n    const char *path;\n    int flags;\n    ruby_glob_func *func;\n    VALUE arg;\n{\n    struct glob_pattern *list;\n    const char *root, *start;\n    char *buf;\n    int n;\n    int status;\n\n    start = root = path;\n    flags |= FNM_SYSCASE;\n#if defined DOSISH\n    root = rb_path_skip_prefix(root);\n#endif\n\n    if (root && *root == '/') root++;\n\n    n = root - start;\n    buf = GLOB_ALLOC_N(char, n + 1);\n    if (!buf) return -1;\n    MEMCPY(buf, start, char, n);\n    buf[n] = '\\0';\n\n    list = glob_make_pattern(root, flags);\n    if (!list) {\n\tfree(buf);\n\treturn -1;\n    }\n    status = glob_helper(buf, 0, UNKNOWN, UNKNOWN, &list, &list + 1, flags, func, arg);\n    glob_free_pattern(list);\n    free(buf);\n\n    return status;\n}\n\nint\nruby_glob(path, flags, func, arg)\n    const char *path;\n    int flags;\n    ruby_glob_func *func;\n    VALUE arg;\n{\n    return ruby_glob0(path, flags & ~GLOB_VERBOSE, func, arg);\n}\n\nstatic int rb_glob_caller _((const char *, VALUE));\n\nstatic int\nrb_glob_caller(path, a)\n    const char *path;\n    VALUE a;\n{\n    int status;\n    struct glob_args *args = (struct glob_args *)a;\n\n    args->c = path;\n    rb_protect(glob_func_caller, a, &status);\n    return status;\n}\n\nstatic int\nrb_glob2(path, flags, func, arg)\n    const char *path;\n    int flags;\n    void (*func) _((const char *, VALUE));\n    VALUE arg;\n{\n    struct glob_args args;\n\n    args.func = func;\n    args.v = arg;\n\n    if (flags & FNM_SYSCASE) {\n\trb_warning(\"Dir.glob() ignores File::FNM_CASEFOLD\");\n    }\n\n    return ruby_glob0(path, flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args);\n}\n\nvoid\nrb_glob(path, func, arg)\n    const char *path;\n    void (*func) _((const char*, VALUE));\n    VALUE arg;\n{\n    int status = rb_glob2(path, 0, func, arg);\n    if (status) GLOB_JUMP_TAG(status);\n}\n\nstatic void push_pattern _((const char* path, VALUE ary));\nstatic void\npush_pattern(path, ary)\n    const char *path;\n    VALUE ary;\n{\n    rb_ary_push(ary, rb_tainted_str_new2(path));\n}\n\nint\nruby_brace_expand(str, flags, func, arg)\n    const char *str;\n    int flags;\n    ruby_glob_func *func;\n    VALUE arg;\n{\n    const int escape = !(flags & FNM_NOESCAPE);\n    const char *p = str;\n    const char *s = p;\n    const char *lbrace = 0, *rbrace = 0;\n    int nest = 0, status = 0;\n\n    while (*p) {\n\tif (*p == '{' && nest++ == 0) {\n\t    lbrace = p;\n\t}\n\tif (*p == '}' && --nest <= 0) {\n\t    rbrace = p;\n\t    break;\n\t}\n\tif (*p == '\\\\' && escape) {\n\t    if (!*++p) break;\n\t}\n\tInc(p);\n    }\n\n    if (lbrace && rbrace) {\n\tchar *buf = GLOB_ALLOC_N(char, strlen(s) + 1);\n\tlong shift;\n\n\tif (!buf) return -1;\n\tmemcpy(buf, s, lbrace-s);\n\tshift = (lbrace-s);\n\tp = lbrace;\n\twhile (p < rbrace) {\n\t    const char *t = ++p;\n\t    nest = 0;\n\t    while (p < rbrace && !(*p == ',' && nest == 0)) {\n\t\tif (*p == '{') nest++;\n\t\tif (*p == '}') nest--;\n\t\tif (*p == '\\\\' && escape) {\n\t\t    if (++p == rbrace) break;\n\t\t}\n\t\tInc(p);\n\t    }\n\t    memcpy(buf+shift, t, p-t);\n\t    strcpy(buf+shift+(p-t), rbrace+1);\n\t    status = ruby_brace_expand(buf, flags, func, arg);\n\t    if (status) break;\n\t}\n\tfree(buf);\n    }\n    else if (!lbrace && !rbrace) {\n\tstatus = (*func)(s, arg);\n    }\n\n    return status;\n}\n\nstruct brace_args {\n    ruby_glob_func *func;\n    VALUE value;\n    int flags;\n};\n\nstatic int glob_brace _((const char *, VALUE));\nstatic int\nglob_brace(path, val)\n    const char *path;\n    VALUE val;\n{\n    struct brace_args *arg = (struct brace_args *)val;\n\n    return ruby_glob0(path, arg->flags, arg->func, arg->value);\n}\n\nstatic int\nruby_brace_glob0(str, flags, func, arg)\n    const char *str;\n    int flags;\n    ruby_glob_func *func;\n    VALUE arg;\n{\n    struct brace_args args;\n\n    args.func = func;\n    args.value = arg;\n    args.flags = flags;\n    return ruby_brace_expand(str, flags, glob_brace, (VALUE)&args);\n}\n\nint\nruby_brace_glob(str, flags, func, arg)\n    const char *str;\n    int flags;\n    ruby_glob_func *func;\n    VALUE arg;\n{\n    return ruby_brace_glob0(str, flags & ~GLOB_VERBOSE, func, arg);\n}\n\nstatic int\npush_glob(VALUE ary, const char *str, int flags)\n{\n    struct glob_args args;\n\n    args.func = push_pattern;\n    args.v = ary;\n    return ruby_brace_glob0(str, flags | GLOB_VERBOSE, rb_glob_caller, (VALUE)&args);\n}\n\nstatic VALUE\nrb_push_glob(str, flags) /* '\\0' is delimiter */\n    VALUE str;\n    int flags;\n{\n    long offset = 0;\n    VALUE ary;\n\n    ary = rb_ary_new();\n    SafeStringValue(str);\n\n    while (offset < RSTRING_LEN(str)) {\n\tint status = push_glob(ary, RSTRING(str)->ptr + offset, flags);\n\tchar *p, *pend;\n\tif (status) GLOB_JUMP_TAG(status);\n\tif (offset >= RSTRING_LEN(str)) break;\n\tp = RSTRING(str)->ptr + offset;\n\tp += strlen(p) + 1;\n\tpend = RSTRING(str)->ptr + RSTRING_LEN(str);\n\twhile (p < pend && !*p)\n\t    p++;\n\toffset = p - RSTRING(str)->ptr;\n    }\n\n    return ary;\n}\n\nstatic VALUE\ndir_globs(argc, argv, flags)\n    long argc;\n    VALUE *argv;\n    int flags;\n{\n    VALUE ary = rb_ary_new();\n    long i;\n\n    for (i = 0; i < argc; ++i) {\n\tint status;\n\tVALUE str = argv[i];\n\tSafeStringValue(str);\n\tstatus = push_glob(ary, RSTRING(str)->ptr, flags);\n\tif (status) GLOB_JUMP_TAG(status);\n    }\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     Dir[ array ]                 => array\n *     Dir[ string [, string ...] ] => array\n *\n *  Equivalent to calling\n *  <code>Dir.glob(</code><i>array,</i><code>0)</code> and \n *  <code>Dir.glob([</code><i>string,...</i><code>],0)</code>.\n *\n */\nstatic VALUE\ndir_s_aref(int argc, VALUE *argv, VALUE obj)\n {\n    if (argc == 1) {\n\treturn rb_push_glob(argv[0], 0);\n    }\n    return dir_globs(argc, argv, 0);\n }\n\n/*\n *  call-seq:\n *     Dir.glob( pattern, [flags] ) => array\n *     Dir.glob( pattern, [flags] ) {| filename | block }  => nil\n *\n *  Returns the filenames found by expanding <i>pattern</i> which is\n *  an +Array+ of the patterns or the pattern +String+, either as an\n *  <i>array</i> or as parameters to the block. Note that this pattern\n *  is not a regexp (it's closer to a shell glob). See\n *  <code>File::fnmatch</code> for the meaning of the <i>flags</i>\n *  parameter. Note that case sensitivity depends on your system (so\n *  <code>File::FNM_CASEFOLD</code> is ignored)\n *\n *  <code>*</code>::        Matches any file. Can be restricted by\n *                          other values in the glob. <code>*</code>\n *                          will match all files; <code>c*</code> will\n *                          match all files beginning with\n *                          <code>c</code>; <code>*c</code> will match\n *                          all files ending with <code>c</code>; and\n *                          <code>*c*</code> will match all files that\n *                          have <code>c</code> in them (including at\n *                          the beginning or end). Equivalent to\n *                          <code>/ .* /x</code> in regexp.\n *  <code>**</code>::       Matches directories recursively.\n *  <code>?</code>::        Matches any one character. Equivalent to\n *                          <code>/.{1}/</code> in regexp.\n *  <code>[set]</code>::    Matches any one character in +set+.\n *                          Behaves exactly like character sets in\n *                          Regexp, including set negation\n *                          (<code>[^a-z]</code>).\n *  <code>{p,q}</code>::    Matches either literal <code>p</code> or\n *                          literal <code>q</code>. Matching literals\n *                          may be more than one character in length.\n *                          More than two literals may be specified.\n *                          Equivalent to pattern alternation in\n *                          regexp.\n *  <code>\\</code>::        Escapes the next metacharacter.\n *\n *     Dir[\"config.?\"]                     #=> [\"config.h\"]\n *     Dir.glob(\"config.?\")                #=> [\"config.h\"]\n *     Dir.glob(\"*.[a-z][a-z]\")            #=> [\"main.rb\"]\n *     Dir.glob(\"*.[^r]*\")                 #=> [\"config.h\"]\n *     Dir.glob(\"*.{rb,h}\")                #=> [\"main.rb\", \"config.h\"]\n *     Dir.glob(\"*\")                       #=> [\"config.h\", \"main.rb\"]\n *     Dir.glob(\"*\", File::FNM_DOTMATCH)   #=> [\".\", \"..\", \"config.h\", \"main.rb\"]\n *\n *     rbfiles = File.join(\"**\", \"*.rb\")\n *     Dir.glob(rbfiles)                   #=> [\"main.rb\",\n *                                              \"lib/song.rb\",\n *                                              \"lib/song/karaoke.rb\"]\n *     libdirs = File.join(\"**\", \"lib\")\n *     Dir.glob(libdirs)                   #=> [\"lib\"]\n *\n *     librbfiles = File.join(\"**\", \"lib\", \"**\", \"*.rb\")\n *     Dir.glob(librbfiles)                #=> [\"lib/song.rb\",\n *                                              \"lib/song/karaoke.rb\"]\n *\n *     librbfiles = File.join(\"**\", \"lib\", \"*.rb\")\n *     Dir.glob(librbfiles)                #=> [\"lib/song.rb\"]\n */\nstatic VALUE\ndir_s_glob(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE str, rflags, ary;\n    int flags;\n\n    if (rb_scan_args(argc, argv, \"11\", &str, &rflags) == 2)\n\tflags = NUM2INT(rflags);\n    else\n\tflags = 0;\n\n    ary = rb_check_array_type(str);\n    if (NIL_P(ary)) {\n\tary = rb_push_glob(str, flags);\n    }\n    else {\n\tvolatile VALUE v = ary;\n\tary = dir_globs(RARRAY_LEN(v), RARRAY_PTR(v), flags);\n    }\n\n    if (rb_block_given_p()) {\n\trb_ary_each(ary);\n\treturn Qnil;\n    }\n    return ary;\n}\n\nstatic VALUE\ndir_open_dir(path)\n    VALUE path;\n{\n    VALUE dir = rb_funcall(rb_cDir, rb_intern(\"open\"), 1, path);\n\n    if (TYPE(dir) != T_DATA ||\n\tRDATA(dir)->dfree != (RUBY_DATA_FUNC)free_dir) {\n\trb_raise(rb_eTypeError, \"wrong argument type %s (expected Dir)\",\n\t\t rb_obj_classname(dir));\n    }\n    return dir;\n}\n\n\n/*\n *  call-seq:\n *     Dir.foreach( dirname ) {| filename | block }  => nil\n *\n *  Calls the block once for each entry in the named directory, passing\n *  the filename of each entry as a parameter to the block.\n *\n *     Dir.foreach(\"testdir\") {|x| puts \"Got #{x}\" }\n *\n *  <em>produces:</em>\n *\n *     Got .\n *     Got ..\n *     Got config.h\n *     Got main.rb\n *\n */\nstatic VALUE\ndir_foreach(io, dirname)\n    VALUE io, dirname;\n{\n    VALUE dir;\n\n    RETURN_ENUMERATOR(io, 1, &dirname);\n    dir = dir_open_dir(dirname);\n    rb_ensure(dir_each, dir, dir_close, dir);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     Dir.entries( dirname ) => array\n *\n *  Returns an array containing all of the filenames in the given\n *  directory. Will raise a <code>SystemCallError</code> if the named\n *  directory doesn't exist.\n *\n *     Dir.entries(\"testdir\")   #=> [\".\", \"..\", \"config.h\", \"main.rb\"]\n *\n */\nstatic VALUE\ndir_entries(io, dirname)\n    VALUE io, dirname;\n{\n    VALUE dir;\n\n    dir = dir_open_dir(dirname);\n    return rb_ensure(rb_Array, dir, dir_close, dir);\n}\n\n/*\n *  call-seq:\n *     File.fnmatch( pattern, path, [flags] ) => (true or false)\n *     File.fnmatch?( pattern, path, [flags] ) => (true or false)\n *\n *  Returns true if <i>path</i> matches against <i>pattern</i> The\n *  pattern is not a regular expression; instead it follows rules\n *  similar to shell filename globbing. It may contain the following\n *  metacharacters:\n *\n *  <code>*</code>::        Matches any file. Can be restricted by\n *                          other values in the glob. <code>*</code>\n *                          will match all files; <code>c*</code> will\n *                          match all files beginning with\n *                          <code>c</code>; <code>*c</code> will match\n *                          all files ending with <code>c</code>; and\n *                          <code>*c*</code> will match all files that\n *                          have <code>c</code> in them (including at\n *                          the beginning or end). Equivalent to\n *                          <code>/ .* /x</code> in regexp.\n *  <code>**</code>::       Matches directories recursively or files\n *                          expansively.\n *  <code>?</code>::        Matches any one character. Equivalent to\n *                          <code>/.{1}/</code> in regexp.\n *  <code>[set]</code>::    Matches any one character in +set+.\n *                          Behaves exactly like character sets in\n *                          Regexp, including set negation\n *                          (<code>[^a-z]</code>).\n *  <code>\\</code>::        Escapes the next metacharacter.\n *\n *  <i>flags</i> is a bitwise OR of the <code>FNM_xxx</code>\n *  parameters. The same glob pattern and flags are used by\n *  <code>Dir::glob</code>.\n *\n *     File.fnmatch('cat',       'cat')        #=> true  : match entire string\n *     File.fnmatch('cat',       'category')   #=> false : only match partial string\n *     File.fnmatch('c{at,ub}s', 'cats')       #=> false : { } isn't supported\n *\n *     File.fnmatch('c?t',     'cat')          #=> true  : '?' match only 1 character\n *     File.fnmatch('c??t',    'cat')          #=> false : ditto\n *     File.fnmatch('c*',      'cats')         #=> true  : '*' match 0 or more characters\n *     File.fnmatch('c*t',     'c/a/b/t')      #=> true  : ditto\n *     File.fnmatch('ca[a-z]', 'cat')          #=> true  : inclusive bracket expression\n *     File.fnmatch('ca[^t]',  'cat')          #=> false : exclusive bracket expression ('^' or '!')\n *\n *     File.fnmatch('cat', 'CAT')                     #=> false : case sensitive\n *     File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD) #=> true  : case insensitive\n *\n *     File.fnmatch('?',   '/', File::FNM_PATHNAME)  #=> false : wildcard doesn't match '/' on FNM_PATHNAME\n *     File.fnmatch('*',   '/', File::FNM_PATHNAME)  #=> false : ditto\n *     File.fnmatch('[/]', '/', File::FNM_PATHNAME)  #=> false : ditto\n *\n *     File.fnmatch('\\?',   '?')                       #=> true  : escaped wildcard becomes ordinary\n *     File.fnmatch('\\a',   'a')                       #=> true  : escaped ordinary remains ordinary\n *     File.fnmatch('\\a',   '\\a', File::FNM_NOESCAPE)  #=> true  : FNM_NOESACPE makes '\\' ordinary\n *     File.fnmatch('[\\?]', '?')                       #=> true  : can escape inside bracket expression\n *\n *     File.fnmatch('*',   '.profile')                      #=> false : wildcard doesn't match leading\n *     File.fnmatch('*',   '.profile', File::FNM_DOTMATCH)  #=> true    period by default.\n *     File.fnmatch('.*',  '.profile')                      #=> true\n *\n *     rbfiles = '**' '/' '*.rb' # you don't have to do like this. just write in single string.\n *     File.fnmatch(rbfiles, 'main.rb')                    #=> false\n *     File.fnmatch(rbfiles, './main.rb')                  #=> false\n *     File.fnmatch(rbfiles, 'lib/song.rb')                #=> true\n *     File.fnmatch('**.rb', 'main.rb')                    #=> true\n *     File.fnmatch('**.rb', './main.rb')                  #=> false\n *     File.fnmatch('**.rb', 'lib/song.rb')                #=> true\n *     File.fnmatch('*',           'dave/.profile')                      #=> true\n *\n *     pattern = '*' '/' '*'\n *     File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME)  #=> false\n *     File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true\n *\n *     pattern = '**' '/' 'foo'\n *     File.fnmatch(pattern, 'a/b/c/foo', File::FNM_PATHNAME)     #=> true\n *     File.fnmatch(pattern, '/a/b/c/foo', File::FNM_PATHNAME)    #=> true\n *     File.fnmatch(pattern, 'c:/a/b/c/foo', File::FNM_PATHNAME)  #=> true\n *     File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME)    #=> false\n *     File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true\n */\nstatic VALUE\nfile_s_fnmatch(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE pattern, path;\n    VALUE rflags;\n    int flags;\n\n    if (rb_scan_args(argc, argv, \"21\", &pattern, &path, &rflags) == 3)\n\tflags = NUM2INT(rflags);\n    else\n\tflags = 0;\n\n    StringValue(pattern);\n    StringValue(path);\n\n    if (fnmatch(RSTRING(pattern)->ptr, RSTRING(path)->ptr, flags) == 0)\n\treturn Qtrue;\n\n    return Qfalse;\n}\n\n/*\n *  Objects of class <code>Dir</code> are directory streams representing\n *  directories in the underlying file system. They provide a variety of\n *  ways to list directories and their contents. See also\n *  <code>File</code>.\n *\n *  The directory used in these examples contains the two regular files\n *  (<code>config.h</code> and <code>main.rb</code>), the parent\n *  directory (<code>..</code>), and the directory itself\n *  (<code>.</code>).\n */\nvoid\nInit_Dir()\n{\n    rb_cDir = rb_define_class(\"Dir\", rb_cObject);\n\n    rb_include_module(rb_cDir, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cDir, dir_s_alloc);\n    rb_define_singleton_method(rb_cDir, \"open\", dir_s_open, 1);\n    rb_define_singleton_method(rb_cDir, \"foreach\", dir_foreach, 1);\n    rb_define_singleton_method(rb_cDir, \"entries\", dir_entries, 1);\n\n    rb_define_method(rb_cDir,\"initialize\", dir_initialize, 1);\n    rb_define_method(rb_cDir,\"path\", dir_path, 0);\n    rb_define_method(rb_cDir,\"inspect\", dir_inspect, 0);\n    rb_define_method(rb_cDir,\"read\", dir_read, 0);\n    rb_define_method(rb_cDir,\"each\", dir_each, 0);\n    rb_define_method(rb_cDir,\"rewind\", dir_rewind, 0);\n    rb_define_method(rb_cDir,\"tell\", dir_tell, 0);\n    rb_define_method(rb_cDir,\"seek\", dir_seek, 1);\n    rb_define_method(rb_cDir,\"pos\", dir_tell, 0);\n    rb_define_method(rb_cDir,\"pos=\", dir_set_pos, 1);\n    rb_define_method(rb_cDir,\"close\", dir_close, 0);\n\n    rb_define_singleton_method(rb_cDir,\"chdir\", dir_s_chdir, -1);\n    rb_define_singleton_method(rb_cDir,\"getwd\", dir_s_getwd, 0);\n    rb_define_singleton_method(rb_cDir,\"pwd\", dir_s_getwd, 0);\n    rb_define_singleton_method(rb_cDir,\"chroot\", dir_s_chroot, 1);\n    rb_define_singleton_method(rb_cDir,\"mkdir\", dir_s_mkdir, -1);\n    rb_define_singleton_method(rb_cDir,\"rmdir\", dir_s_rmdir, 1);\n    rb_define_singleton_method(rb_cDir,\"delete\", dir_s_rmdir, 1);\n    rb_define_singleton_method(rb_cDir,\"unlink\", dir_s_rmdir, 1);\n\n    rb_define_singleton_method(rb_cDir,\"glob\", dir_s_glob, -1);\n    rb_define_singleton_method(rb_cDir,\"[]\", dir_s_aref, -1);\n\n    rb_define_singleton_method(rb_cFile,\"fnmatch\", file_s_fnmatch, -1);\n    rb_define_singleton_method(rb_cFile,\"fnmatch?\", file_s_fnmatch, -1);\n\n    rb_file_const(\"FNM_NOESCAPE\", INT2FIX(FNM_NOESCAPE));\n    rb_file_const(\"FNM_PATHNAME\", INT2FIX(FNM_PATHNAME));\n    rb_file_const(\"FNM_DOTMATCH\", INT2FIX(FNM_DOTMATCH));\n    rb_file_const(\"FNM_CASEFOLD\", INT2FIX(FNM_CASEFOLD));\n    rb_file_const(\"FNM_SYSCASE\", INT2FIX(FNM_SYSCASE));\n}\n"
  },
  {
    "path": "distro/debian/compat",
    "content": "5\n"
  },
  {
    "path": "distro/debian/control",
    "content": "Package: ruby-enterprise\nVersion: <%= VENDOR_RUBY_VERSION %>-<%= REE_VERSION %>\nSection: interpreters\nPriority: optional\nArchitecture: <%= arch %>\nEssential: no\nDepends: libc6 (>= 2.6.1-1)\nMaintainer: Hongli Lai <hongli@phusion.nl>\nInstalled-Size: <%= installed_size %>\nDescription: Ruby Enterprise Edition.\n"
  },
  {
    "path": "distro/debian/postinst",
    "content": "#!/bin/sh\n\n"
  },
  {
    "path": "distro/debian/prerm",
    "content": "#!/bin/sh\n\n"
  },
  {
    "path": "distro/dependencies.rb",
    "content": "require \"#{File.dirname(__FILE__)}/platform_info\"\nmodule RubyEnterpriseEdition\n\n# Represents a dependency software that Ruby Enterprise Edition requires. It's used by the\n# installer to check whether all dependencies are available. A Dependency object\n# contains full information about a dependency, such as its name, code for\n# detecting whether it is installed, and installation instructions for the\n# current platform.\nclass Dependency # :nodoc: all\n\t[:name, :install_command, :install_instructions, :install_comments,\n\t :website, :website_comments, :provides].each do |attr_name|\n\t\tattr_writer attr_name\n\t\t\n\t\tdefine_method(attr_name) do\n\t\t\tcall_init_block\n\t\t\treturn instance_variable_get(\"@#{attr_name}\")\n\t\tend\n\tend\n\t\n\tdef initialize(&block)\n\t\t@included_by = []\n\t\t@init_block = block\n\tend\n\t\n\tdef define_checker(&block)\n\t\t@checker = block\n\tend\n\t\n\tdef check\n\t\tcall_init_block\n\t\tresult = Result.new\n\t\t@checker.call(result)\n\t\treturn result\n\tend\n\nprivate\n\tclass Result\n\t\tdef found(filename_or_boolean = nil)\n\t\t\tif filename_or_boolean.nil?\n\t\t\t\t@found = true\n\t\t\telse\n\t\t\t\t@found = filename_or_boolean\n\t\t\tend\n\t\tend\n\t\t\n\t\tdef not_found\n\t\t\tfound(false)\n\t\tend\n\t\t\n\t\tdef found?\n\t\t\treturn !@found.nil? && @found\n\t\tend\n\t\t\n\t\tdef found_at\n\t\t\tif @found.is_a?(TrueClass) || @found.is_a?(FalseClass)\n\t\t\t\treturn nil\n\t\t\telse\n\t\t\t\treturn @found\n\t\t\tend\n\t\tend\n\tend\n\n\tdef call_init_block\n\t\tif @init_block\n\t\t\tinit_block = @init_block\n\t\t\t@init_block = nil\n\t\t\tinit_block.call(self)\n\t\tend\n\tend\nend\n\n# Namespace which contains the different dependencies that Ruby Enterprise Edition may require.\n# See Dependency for more information.\nmodule Dependencies # :nodoc: all\n\tinclude PlatformInfo\n\t\n\tCC = Dependency.new do |dep|\n\t\tdep.name = \"C compiler\"\n\t\tdep.define_checker do |result|\n\t\t\tif PlatformInfo::CC.nil?\n\t\t\t\tresult.not_found\n\t\t\telse\n\t\t\t\tresult.found(PlatformInfo::CC)\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install build-essential\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install gcc-c++\"\n\t\t\twhen :gentoo\n\t\t\t\tdep.install_command = \"emerge -av gcc\"\n\t\t\tend\n\t\telsif RUBY_PLATFORM =~ /darwin/\n\t\t\tdep.install_instructions = \"Please install the Apple Development Tools: http://developer.apple.com/tools/\"\n\t\tend\n\t\tdep.website = \"http://gcc.gnu.org/\"\n\tend\n\t\n\tCXX = Dependency.new do |dep|\n\t\tdep.name = \"C++ compiler\"\n\t\tdep.define_checker do |result|\n\t\t\tif PlatformInfo::CXX.nil?\n\t\t\t\tresult.not_found\n\t\t\telse\n\t\t\t\tresult.found(PlatformInfo::CXX)\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install build-essential\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install gcc-c++\"\n\t\t\twhen :gentoo\n\t\t\t\tdep.install_command = \"emerge -av gcc\"\n\t\t\tend\n\t\telsif RUBY_PLATFORM =~ /darwin/\n\t\t\tdep.install_instructions = \"Please install the Apple Development Tools: http://developer.apple.com/tools/\"\n\t\tend\n\t\tdep.website = \"http://gcc.gnu.org/\"\n\tend\n\t\n\tMake = Dependency.new do |dep|\n\t\tdep.name = \"The 'make' tool\"\n\t\tdep.define_checker do |result|\n\t\t\tmake = PlatformInfo.find_command('make')\n\t\t\tif make\n\t\t\t\tresult.found(make)\n\t\t\telse\n\t\t\t\tresult.not_found\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install build-essential\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install make\"\n\t\t\tend\n\t\telsif RUBY_PLATFORM =~ /darwin/\n\t\t\tdep.install_instructions = \"Please install the Apple Development Tools: http://developer.apple.com/tools/\"\n\t\tend\n\t\tdep.website = \"http://www.gnu.org/software/make/\"\n\tend\n\t\n\tPatch = Dependency.new do |dep|\n\t\tdep.name = \"The 'patch' tool\"\n\t\tdep.define_checker do |result|\n\t\t\tpatch = PlatformInfo.find_command('patch')\n\t\t\tif patch\n\t\t\t\tresult.found(patch)\n\t\t\telse\n\t\t\t\tresult.not_found\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install patch\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install patch\"\n\t\t\tend\n\t\tend\n\t\tdep.website = \"http://www.gnu.org/software/diffutils/\"\n\tend\n\t\n\tZlib_Dev = Dependency.new do |dep|\n\t\tdep.name = \"Zlib development headers\"\n\t\tdep.define_checker do |result|\n\t\t\tbegin\n\t\t\t\tFile.open('/tmp/r8ee-check.c', 'w') do |f|\n\t\t\t\t\tf.write(\"#include <zlib.h>\")\n\t\t\t\tend\n\t\t\t\tDir.chdir('/tmp') do\n\t\t\t\t\tif system(\"(#{PlatformInfo::CC || 'gcc'} #{ENV['CFLAGS']} -c r8ee-check.c) >/dev/null 2>/dev/null\")\n\t\t\t\t\t\tresult.found\n\t\t\t\t\telse\n\t\t\t\t\t\tresult.not_found\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tensure\n\t\t\t\tFile.unlink('/tmp/r8ee-check.c') rescue nil\n\t\t\t\tFile.unlink('/tmp/r8ee-check.o') rescue nil\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install zlib1g-dev\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install zlib-devel\"\n\t\t\tend\n\t\tend\n\t\tdep.website = \"http://www.zlib.net/\"\n\tend\n\t\n\tOpenSSL_Dev = Dependency.new do |dep|\n\t\tdep.name = \"OpenSSL development headers\"\n\t\tdep.define_checker do |result|\n\t\t\tbegin\n\t\t\t\tFile.open('/tmp/r8ee-check.c', 'w') do |f|\n\t\t\t\t\tf.write(\"#include <openssl/ssl.h>\")\n\t\t\t\tend\n\t\t\t\tDir.chdir('/tmp') do\n\t\t\t\t\tif system(\"(#{PlatformInfo::CC || 'gcc'} #{ENV['CFLAGS']} -c r8ee-check.c) >/dev/null 2>/dev/null\")\n\t\t\t\t\t\tresult.found\n\t\t\t\t\telse\n\t\t\t\t\t\tresult.not_found\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tensure\n\t\t\t\tFile.unlink('/tmp/r8ee-check.c') rescue nil\n\t\t\t\tFile.unlink('/tmp/r8ee-check.o') rescue nil\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install libssl-dev\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install openssl-devel\"\n\t\t\tend\n\t\tend\n\t\tdep.website = \"http://www.openssl.org/\"\n\tend\n\t\n\tReadline_Dev = Dependency.new do |dep|\n\t\tdep.name = \"GNU Readline development headers\"\n\t\tdep.define_checker do |result|\n\t\t\tbegin\n\t\t\t\tFile.open('/tmp/r8ee-check.c', 'w') do |f|\n\t\t\t\t\t# readline.h doesn't work on OS X unless we #include stdio.h\n\t\t\t\t\tf.puts(\"#include <stdio.h>\")\n\t\t\t\t\tf.puts(\"#include <readline/readline.h>\")\n\t\t\t\tend\n\t\t\t\tDir.chdir('/tmp') do\n\t\t\t\t\tif system(\"(#{PlatformInfo::CC || 'gcc'} #{ENV['CFLAGS']} -c r8ee-check.c) >/dev/null 2>/dev/null\")\n\t\t\t\t\t\tresult.found\n\t\t\t\t\telse\n\t\t\t\t\t\tresult.not_found\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tensure\n\t\t\t\tFile.unlink('/tmp/r8ee-check.c') rescue nil\n\t\t\t\tFile.unlink('/tmp/r8ee-check.o') rescue nil\n\t\t\tend\n\t\tend\n\t\tif RUBY_PLATFORM =~ /linux/\n\t\t\tcase LINUX_DISTRO\n\t\t\twhen :ubuntu, :debian\n\t\t\t\tdep.install_command = \"apt-get install libreadline5-dev\"\n\t\t\twhen :rhel, :fedora, :centos\n\t\t\t\tdep.install_command = \"yum install readline-devel\"\n\t\t\tend\n\t\tend\n\t\tdep.website = \"http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html\"\n\tend\nend\n\nend # module RubyEnterpriseEdition\n"
  },
  {
    "path": "distro/documentation.txt",
    "content": "= Ruby Enterprise Edition Features Guide\n\n== Overview of Ruby Enterprise Edition (REE)\nRuby Enterprise Edition (REE) is a server-oriented distribution of the official Ruby interpreter, and includes various additional enhancements:\n\n- A copy-on-write friendly garbage collector. Phusion Passenger uses this, in combination with a technique called preforking, to reduce Ruby on Rails applications' memory usage by 33% on average.\n- An improved memory allocator called tcmalloc, which improves performance quite a bit.\n- The ability to tweak garbage collector settings for maximum server performance.\n- The ability to inspect the garbage collector's state and the object heap state, for debugging purposes.\n- The ability to obtain backtraces for all running threads, making it easier for one to debug multithreaded applications.\n- Thread scheduler bug fixes and performance improvements. Threading on Ruby Enterprise Edition can be more than 10 times faster than official Ruby 1.8.\n- Various memory management tweaks so that the Ruby interpreter uses less memory on average, even when copy-on-write is not utilized.\n\nSome of these features are gathered from third party Ruby patches:\nlink:http://railsbench.rubyforge.org/[RailsBench],\nhttp://rubyforge.org/tracker/download.php/426/1700/11497/2087/ruby-track-alloc.patch[Sylvain Joyeux's object allocation patch],\nlink:http://ph7spot.com/articles/caller_for_all_threads[caller_for_all_threads],\nDarryl Gove's and Miriam Blatt's link:http://blogs.sun.com/d/entry/ruby_performance_gains_on_sparc[Sparc optimization patches],\nJoe Damato's and Aman Gupta's http://timetobleed.com/fixing-threads-in-ruby-18-a-2-10x-performance-boost/[zero-copy context switching patch],\nBrent Roman's http://sites.google.com/site/brentsrubypatches[MBARI patch set].\n\n\n== Installation and uninstallation\n\n=== Installation via Debian package or source tarball\nTo install REE, download either the source tarball or the Debian package\nfrom the REE website. The source tarball contains a cross-platform installer.\nInstallation instructions are available on the download page.\n\nNote that this installer is written in Ruby, and thus requires a Ruby\ninterpreter to run. Because not all systems come with a Ruby interpreter by\ndefault, the source tarball also contains a number of precompiled Ruby\ninterpreters for various platforms, with the purpose of running the installer.\nThe `installer` script will automatically use a precompiled Ruby binary for the\ncurrent platform, if available. Precompiled Ruby interpreters for the following\nplatforms are included:\n\n- x86 Linux\n- x86_64 Linux\n- x86 FreeBSD 6\n- Solaris\n\nMacOS X and most FreeBSD systems already come with a Ruby interpreter by default.\n\nSo if you notice that the installer fails to start, please install Ruby first,\nthen re-run the installer.\n\nWARNING: It is not recommended to install REE into '/usr' because it can\noverwrite your existing Ruby installation in a way that the system doesn't\nexpect. You should install REE into an isolated place such as '/opt'.\n\n==== Installation options\n\n===== Disabling tcmalloc\nIf you experience problems with the tcmalloc memory allocator, then you can\ninstall REE without tcmalloc by passing `--no-tcmalloc` to the installer.\n\n===== Non-interactive installation\nYou can install REE non-interactively either by using the Debian package,\nor by passing `--auto=DIRECTORY` to the REE installer. The latter will\ninstruct the installer to non-interactively install REE into the specified\ntarget directory.\n\n===== More options\nYou can read about all of the available installation options by passing\n`--help` to the REE installer.\n\n=== Manual installation (for experts)\nIf you wish to install REE from source, but do not wish to use the included\ninstaller, or if the installer doesn't work, then you can install REE manually.\nPlease follow the instructions below.\n\nNote that these instructions do not cover installing RubyGems.\n\n==== Prerequisites\n\nYou need to have the following dependencies installed:\n\n1. A C and C++ compiler, preferrably gcc.\n2. The 'make' tool.\n3. The 'patch' tool.\n4. C development headers for zlib.\n5. C development headers for OpenSSL.\n6. C development headers for GNU Readline.\n7. yacc or bison.\n\n==== Step 1: Download and extract the source tarball\nType:\n--------------------------\ntar xzvf ruby-enterprise-x.x.x.tar.gz\n--------------------------\n\nA directory called 'ruby-enterprise-x.x.x' will now appear.\n\n==== Step 2: Decide the prefix you want to install REE to\n\nPlease decide on a prefix to install REE to, and put this directory name into\nthe `PREFIX` environment variable. We'll need this value later in these\ninstructions.\n\nFor example, if you want to install REE into /opt/ruby-enterprise, then run:\n\n-------------------------------------\nPREFIX=/opt/ruby-enterprise\n-------------------------------------\n\nPlease note that the rest of this document assumes that REE is installed into\n'/opt/ruby-enterprise'. If you installed REE into a different directory then just\nreplace '/opt/ruby-enterprise' with whatever the real prefix is.\n\n==== Step 3: Apply or unapply the (experimental) fast threading patch\nThe fast threading patch potentially improves Ruby threading performance, but it's\nexperimental at this time. By default, the patch is applied on the source code\nprovided in the tarball; the installer however does not install fast threading by\ndefault by reverse-patching the source code.\n\nIf you want to install REE with the fast threading patch, then you can continue to\nstep 4. If you do not want to install with the fast threading patch, then you must\nfirst reverse-patch the source code as follows:\n\n------------------------------\ncd ruby-enterprise-x.x.x/source\npatch -p1 -R < ../fast-threading.patch\ncd ../..\n------------------------------\n\nPlease note that the fast threading patch only works on x86 and x86_64. On other\narchitectures it will result in a compilation failure.\n\n==== Step 4: Install tcmalloc\nTcmalloc is a memory allocator which is usually more efficient than the\nplatform's native memory allocator. REE doesn't require tcmalloc, but it will\nwork better if tcmalloc is installed.\n\nCompile tcmalloc as follows:\n\n--------------------------\ncd ruby-enterprise-x.x.x/source/distro/google-perftools-*\n./configure --prefix=$PREFIX --disable-dependency-tracking\nmake libtcmalloc_minimal.la\n--------------------------\n\nIf compilation fails, then skip to step 5. REE will work fine without tcmalloc.\n\nAfter compilation, install tcmalloc as follows:\n\n--------------------------\nsudo mkdir -p $PREFIX/lib\nsudo rm -f $PREFIX/lib/libtcmalloc_minimal*.so*\nsudo cp -Rpf .libs/libtcmalloc_minimal*.so* $PREFIX/lib/\n--------------------------\n\n.MacOS X note\nNOTE: Instead of typing 'libtcmalloc_minimal*.so*', type\n      'libtcmalloc_minimal*.bundle*'.\n\nNOTE: The reason why we don't instruct you to type 'make' and 'make install'\n      is because compiling tcmalloc with 'make' usually doesn't work on 64-bit\n      platforms. The above instructions are a little bit more complex, but they\n      work on all platforms where tcmalloc is supported.\n\n==== Step 5: Configure REE\n\nChange the current working directory to 'ruby-enterprise-x.x.x/source'. If\nyou were previously in the google-perftools directory, then type:\n\n--------------------------\ncd ../..\n--------------------------\n\nRun the configure script:\n\n--------------------------\n./configure --prefix=$PREFIX --enable-mbari-api CFLAGS='-g -O2'\n--------------------------\n\n==== Step 6: Compiling and installing the system_allocator library (MacOS X only)\n\nIf you are on MacOS X, then compile and install the 'system_allocator' library:\n\n--------------------------\ngcc -dynamiclib system_allocator.c -install_name @rpath/libsystem_allocator.dylib -o libsystem_allocator.dylib\nsudo install libsystem_allocator.dylib $PREFIX/lib/\n--------------------------\n\n==== Step 7: compiling and installing REE\n\nOpen 'Makefile'. Search for a line which starts with:\n\n--------------------------\nLIBS = \n--------------------------\n\nAppend the string '$(PRELIBS)' to the part after the '=' sign. For example,\non Ubuntu 8.04, the 'LIBS = ' line becomes:\n\n--------------------------\nLIBS = $(PRELIBS) -ldl -lcrypt -lm  $(EXTLIBS)\n--------------------------\n\nSave the file. Now we can proceed with compiling REE:\n\n--------------------------\nmake PRELIBS=\"-Wl,-rpath,$PREFIX/lib -L$PREFIX/lib -ltcmalloc_minimal\"\n--------------------------\n\nNotes:\n\n- If you did not install tcmalloc, then you can omit the '-ltcmalloc_minimal'\n  part.\n- If you are on MacOS X, then you need to append '-lsystem_allocator' to the\n  'PRELIBS' option.\n- If you are on FreeBSD, then you need to append '-lpthread' to the 'PRELIBS'\n  option.\n\nNow that REE has been compiled, install it with:\n\n--------------------------\nsudo make install\n--------------------------\n\n\n=== RubyCocoa compatibility and `--enable-shared`\n\nIn order to use RubyCocoa, the Ruby interpreter must be compiled with\n`--enable-shared`. By default, Ruby Enterprise Edition's interpreter is not compiled\nwith `--enable-shared`. You can compile the Ruby Enterprise Edition interpreter\nwith this flag by passing `-c --enable-shared` to its installer, like this:\n\n---------------------------------------------------------\n./ruby-enterprise-X.X.X/installer -c --enable-shared\n---------------------------------------------------------\n\nPlease note that enabling `--enable-shared` will make the Ruby interpreter about\n20% slower. It is for this reason that we don't recommend enabling `--enable-shared`\non server environments, although it's fine for desktop environments.\n\n=== Tcl/Tk compatibility and `--enable-pthread`\n\nIn order to use Tcl/Tk with threading support, the Ruby interpreter must be compiled\nwith `--enable-pthread`. By default, Ruby Enterprise Edition's interpreter is not\ncompiled with `--enable-pthread`. You can compile the Ruby Enterprise Edition\ninterpreter with this flag by passing `-c --enable-pthread` to its installer,\nlike this:\n\n---------------------------------------------------------\n./ruby-enterprise-X.X.X/installer -c --enable-pthread\n---------------------------------------------------------\n\nPlease note that enabling `--enable-pthread` will make the Ruby interpreter about\n50% slower. It is for this reason that we don't recommend enabling `--enable-shared`\non server environments, although it's fine for desktop environments.\n\n=== How REE installs itself into the system\nBy default, REE installs itself into a directory in '/opt'. If you already had a\nRuby interpreter installed (typically in '/usr'; let's call this 'the system Ruby\ninterpreter'), then REE will have no effect on it: REE lives in isolation and in\nparallel to the system Ruby interpreter. This also means that:\n\n- If you have any software which depends on the system Ruby interpreter, then\n  that software will not break. It will continue to work like before.\n- REE has its own set of Ruby libraries, and its own set of gems and its own\n  set of commands. If you install a new gem using the system Ruby interpreter,\n  then that gem will not show up in REE's gem list, and vice versa.\n- When running Ruby programs, the system Ruby interpreter will be used unless\n  you explicitly configure the system to use REE by default.\n\n==== Why doesn't REE use the system Ruby interpreter's gems?\nREE does not use the system Ruby interpreter's gems because it can cause\nproblems with native extensions, e.g. RMagick, Mongrel, Hpricot, etc. A native\nextension compiled for one Ruby installation might crash when used in a\ndifferent Ruby installation. This is why you must reinstall your gems in\nREE.\n\n=== Upgrading\nTo upgrade REE through the Debian package, just install the Debian package.\n\nTo upgrade REE through the source tarball, run the installer in the source\ntarball and specify the same destination prefix directory that REE is currently\ninstalled in. For example, if REE is currently installed in\n'/opt/ruby-enterprise-20081215', then specify '/opt/ruby-enterprise-20081215'\nin the upgrade source tarball's installer.\n\n=== Uninstallation\nIf you installed REE through a Debian package, then uninstall the Debian package\nwith 'dpkg' or with 'apt-get'.\n\nIf you installed REE through the source tarball, then you can uninstall it by\ndeleting the directory in which REE is installed. For example, if REE was\ninstalled to '/opt/ruby-enterprise-X.X.X' (the default), then just delete that\ndirectory. It is for this reason why we recommend installing REE into its own\ndirectory.\n\n\n== Using Ruby Enterprise Edition\n\n=== General usage\nNormally one would run a Ruby program by invoking the Ruby interpreter with a\nsource file as its first argument:\n\n--------------------------\n$ ruby some_program.rb\n--------------------------\n\nTo run the same program in REE, invoke the equivalent command in REE's\n'bin' folder:\n\n--------------------------------------------------------\n$ /opt/ruby-enterprise-X.X.X/bin/ruby some_program.rb\n--------------------------------------------------------\n\nThe same applies to other Ruby commands such as 'gem', 'irb' and\n'rake'. For example, if you want to install Ruby on Rails for REE, invoke:\n\n--------------------------------------------------------\n$ /opt/ruby-enterprise-X.X.X/bin/gem install rails\n--------------------------------------------------------\n\n=== Using REE with Phusion Passenger\nTo use REE in combination with Phusion Passenger, you must run the Passenger\nApache 2 module installer that's associated with REE. The REE installer installs\nthe Passenger gem by default, so you just have to run the Passenger Apache 2\nmodule installer:\n\n-------------------------------------------------\n/opt/ruby-enterprise-X.X.X/bin/passenger-install-apache2-module\n-------------------------------------------------\n\nThen follow the instructions that the installer gives you.\n\n=== Configuring REE as the default Ruby interpreter\nIt is possible to configure REE as the default Ruby interpreter, so that when\nyou type 'ruby', 'gem', 'irb', 'rake' or other Ruby commands, REE's version is\ninvoked instead of the system Ruby's version.\n\nTo do this, you must add REE's 'bin' directory to the beginning of the `PATH`\nenvironment variable. This environment variable specifies the command shell's\ncommand search path. For example, you can do this on the command-line:\n\n-------------------------------------\n$ ruby some_program.rb    # <--- some_program.rb is being run\n                          #      in the system Ruby interpreter.\n\n$ export PATH=/opt/ruby-enterprise-X.X.X/bin:$PATH\n$ ruby some_program.rb    # <--- some_program.rb will now be run in REE!\n-------------------------------------\n\nInvoking `export PATH=...` on the command-line has no permanent effect: its\neffects disappear as soon as you exit the shell. To make the effect permanent,\nadd an entry to the file `/etc/environment` instead. On Ubuntu Linux,\n`/etc/environment` looks like this:\n\n-------------------------------------\nPATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games\"\nLANG=\"en_US.UTF-8\"\nLANGUAGE=\"en_US:en\"\n-------------------------------------\n\nAdd REE's 'bin' directory to the PATH environment variable, like this:\n\n-------------------------------------\nPATH=\"/opt/ruby-enterprise-x.x.x/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games\"\nLANG=\"en_US.UTF-8\"\nLANGUAGE=\"en_US:en\"\n-------------------------------------\n\n\n== Garbage collector and object space\n\n=== Copy-on-write friendliness\nBy default, REE's garbage collector is not copy-on-write-friendly, just like\na stock Ruby interpreter. Copy-on-write-friendliness can be turned on during\nruntime by calling:\n\n[source, ruby]\n-----------------------------------------------\nGC.copy_on_write_friendly = true\n-----------------------------------------------\n\nNote that Phusion Passenger automatically turns on the copy-on-write-friendly\nmode whenever it detects that it's running in REE.\n\nWith the following method, one can check whether the garbage collector is in\ncopy-on-write-friendly mode:\n\n[source, ruby]\n-----------------------------------------------\nGC.copy_on_write_friendly?\n-----------------------------------------------\n\n=== Garbage collector performance tuning\nRuby's garbage collector tries to adapt memory usage to the amount of memory\nused by the program by dynamically growing or shrinking the allocated heap as\nit sees fit. For long running server applications, this approach isn't always\nthe most efficient one. The performance very much depends on the ratio\n`heap_size / program_size`. It behaves somewhat erratic: adding code can\nactually make your program run faster.\n\nWith REE, one can tune the garbage collector's behavior for better server\nperformance. It is possible to specify the initial heap size to start with.\nThe heap size will never drop below the initial size. By carefully selecting\nthe initial heap size one can decrease startup time and increase throughput\nof server applications.\n\nGarbage collector behavior is controlled through the following environment\nvariables. These environment variables must be set prior to invoking the Ruby\ninterpreter.\n\n*`RUBY_HEAP_MIN_SLOTS`*::\n\tThis specifies the initial number of heap slots. The default is '10000'.\n\n*`RUBY_HEAP_SLOTS_INCREMENT`*::\n\tThe number of additional heap slots to allocate when Ruby needs to\n\tallocate new heap slots for the first time. The default is '10000'.\n+\nFor example, suppose that the default GC settings are in effect, and 10000 Ruby\nobjects exist on the heap (= 10000 used heap slots). When the program creates\nanother object, Ruby will allocate a new heap with 10000 heap slots in it.\nThere are now 20000 heap slots in total, of which 10001 are used and 9999 are\nunused.\n\n*`RUBY_HEAP_SLOTS_GROWTH_FACTOR`*::\n\tMultiplicator used for calculating the number of new heaps slots to\n\tallocate next time Ruby needs new heap slots. The default is '1.8'.\n+\nTake the program in the last example. Suppose that the program creates 10000\nmore objects. Upon creating the 10000th object, Ruby needs to allocate another\nheap. This heap will have `10000 * 1.8 = 18000` heap slots. There are now\n`20000 + 18000 = 38000` heap slots in total, of which 20001 are used and\n17999 are unused.\n+\nThe next time Ruby needs to allocate a new heap, that heap will have\n`18000 * 1.8 = 32400` heap slots.\n\n*`RUBY_GC_MALLOC_LIMIT`*::\n\tThe amount of C data structures which can be allocated without\n\ttriggering a garbage collection. If this is set too low, then the\n\tgarbage collector will be started even if there are empty heap slots\n\tavailable. The default value is '8000000'.\n\n*`RUBY_HEAP_FREE_MIN`*::\n\tThe number of heap slots that should be available after a garbage\n\tcollector run. If fewer heap slots are available, then Ruby will\n\tallocate a new heap according to the `RUBY_HEAP_SLOTS_INCREMENT` and\n\t`RUBY_HEAP_SLOTS_GROWTH_FACTOR` parameters. The default value is '4096'.\n\nThe best settings varies from application to application. You should try\nexperimenting with the values.\n\nlink:http://www.37signals.com[37signals] uses the following settings in production:\n\n----------------------------------\nRUBY_HEAP_MIN_SLOTS=600000\nRUBY_GC_MALLOC_LIMIT=59000000\nRUBY_HEAP_FREE_MIN=100000\n----------------------------------\n\nlink:http://www.twitter.com[Twitter] uses the following settings in production:\n\n----------------------------------\nRUBY_HEAP_MIN_SLOTS=500000\nRUBY_HEAP_SLOTS_INCREMENT=250000\nRUBY_HEAP_SLOTS_GROWTH_FACTOR=1\nRUBY_GC_MALLOC_LIMIT=50000000\n----------------------------------\n\nTwitter's settings mean:\n\n * Start with enough memory to hold the application (Ruby's default is very low,\n   lower than what a Rails application typically needs).\n * Increase it linearly if you need more (Ruby's default is exponential increase).\n * Only garbage-collect every 50 million `malloc` calls (Ruby's default is 6x smaller).\n\nTwitter link:http://blog.evanweaver.com/articles/2009/04/09/ruby-gc-tuning/[claims]\nthat these settings give them about 20% to 40% average performance improvement,\nat the cost of slightly higher peak memory usage.\n\n=== Garbage collector statistics\nOne can inspect various garbage collector statistics by calling certain methods.\nStatistics collection is disabled by default, so before one can obtain the\nstatistics, statistics collection must be enabled by calling:\n\n[source,ruby]\n--------------------------\nGC.enable_stats\n--------------------------\n\nThere's a very minor performance penalty when statistics collection is enabled.\nStatistics collection can be disabled by calling:\n\n[source,ruby]\n--------------------------\nGC.disable_stats\n--------------------------\n\nThe following methods are available for obtaining the collected statistics\ninformation:\n\n*`GC.collections`*::\n\tReturns the number of garbage collections that have been performed\n\tsince GC statistics collection was enabled.\n+\n[source, ruby]\n----------------------------\nGC.enable_stats\ndo_something\nGC.collections     # => 20\n----------------------------\n\n*`GC.time`*::\n\tReturns the total amount of time that has been spent on garbage\n\tcollection since GC statistics collection was enabled, in microseconds.\n+\n[source, ruby]\n----------------------------\nGC.enable_stats\ndo_something\nGC.time            # => 3000000\n----------------------------\n\n*`GC.growth`*::\n\tReturns the number of bytes that have been allocated since the last\n\tgarbage collection run.\n\n*`GC.dump`*::\n\tDumps information about the current GC data structures to the GC\n\tlog file, to `stderr` if no GC log file is specified. One can specify\n\tthe GC log file in the `RUBY_GC_DATA_FILE` environment variable, which\n\tmust be set before starting the Ruby interpreter.\n+\nAt this moment, the only thing that this method does is printing the size of\neach Ruby heap.\n\nThe collected statistics information can be cleared by calling:\n\n[source,ruby]\n--------------------------\nGC.clear_stats\n--------------------------\n\n\n=== Memory allocation and object heap statistics\nOne can obtain various statistics about object allocation. Some of the\nstatistics methods listed here require one to explicitly enable statistics\ncollection, just like the garbage collection statistics methods.\n\nThe following methods are available:\n\n*`GC.allocated_size`*::\n\tReturns the amount of memory (in bytes) that has been allocated since\n\tGC statistics collection was enabled. This is the total amount of bytes\n\tthat has been passed to the C function `ruby_xmalloc()` so far.\n+\n[source, ruby]\n--------------------------------\nGC.allocated_size    #=> 4070\n--------------------------------\n\n*`GC.num_allocations`*::\n\tReturns the number of memory allocation requests that have been\n\tperformed since GC statistics collection was enabled. This is the\n\tnumber of times that the C function `ruby_xmalloc()` has been called.\n+\n[source, ruby]\n--------------------------------\nGC.num_allocations   #=> 4070\n--------------------------------\n\n*`ObjectSpace.live_objects`*::\n\tReturns the number of objects that are currently allocated in the\n\tsystem. This value usually goes down after the garbage collector runs.\n\tThis method does not require one to enable statistics collection.\n+\n[source, ruby]\n--------------------------------\nObjectSpace.live_objects   #=> 30873\n--------------------------------\n\n*`ObjectSpace.allocated_objects`*::\n\tReturns the number of objects that have been allocated since the Ruby\n\tinterpreter started. This number can only increase. To know how many\n\tobjects are currently allocated, use `ObjectSpace.live_objects` instead.\n+\n[source, ruby]\n--------------------------------\nObjectSpace.allocated_objects   #=> 33266\n--------------------------------\n\n\n== Obtaining the backtrace of all threads\nThe method `caller_for_all_threads` returns a Hash which maps each currently\nrunning thread to the thread's backtrace. A backtrace is an array of strings,\nin the same format as the return value of the method `caller`. For example,\nconsider the following program `test.rb`:\n\n[source, ruby]\n---------------------------------\nrequire 'thread'\nrequire 'pp'\n\ndef foo\n   bar\nend\n\ndef bar\n   sleep 10\nend\n\nthread1 = Thread.new do\n   foo\nend\n\nthread2 = Thread.new do\n   STDIN.readline\nend\n\n# Give other threads some chance to run.\nsleep 0.1\n\npp caller_for_all_threads\n---------------------------------\n\nThis program will print:\n\n---------------------------------\n{#<Thread:0x8261954 sleep>=>\n  [\"test.rb:9:in `bar'\",\n   \"test.rb:5:in `foo'\",\n   \"test.rb:13\",\n   \"test.rb:12:in `initialize'\",\n   \"test.rb:12:in `new'\",\n   \"test.rb:12\"],\n #<Thread:0x81986a8 run>=>[\"test.rb:23\"],\n #<Thread:0x82618c8 sleep>=>\n  [\"test.rb:17\",\n   \"test.rb:16:in `initialize'\",\n   \"test.rb:16:in `new'\",\n   \"test.rb:16\"]}\n---------------------------------\n\n=== Phusion Passenger integration\n`caller_for_all_threads` support is integrated into Phusion Passenger version 2.1\n(which at the time of writing hasn't been released yet). Upon sending a 'SIGQUIT'\nsignal to a Phusion Passenger backend process, it will print the backtrace of\nall threads to the Apache error log. This feature is also documented in the\nPhusion Passenger users guide.\n\n\n== Obtaining the source filename and line of arbitrary methods and blocks\nAll Method and Proc objects provide the `__file__` and `__line__` methods for\nobtaining the source filename and line on which said method or proc was defined.\nThis is extremely useful for debugging applications or frameworks that rely on\nheavily on meta-programming.\n\nFor example, consider a Ruby on Rails application which has a User model. The\n`users` database table has a `username` field, so ActiveRecord automatically\ngenerates a `username` method for the User class. By calling `__file__` and\n`__line__` one can see where in the ActiveRecord source code the method is\ndefined:\n\n-------------------------------\n>> method = User.new.method(:username)\n=> #<Method: User#username>\n>> method.__file__\n=> \"/opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb\"\n>> method.__line__\n=> 211\n-------------------------------\n\nA simpler example that doesn't involve Ruby on Rails:\n\n[source, ruby]\n-------------------------------\n# foo.rb\n\nclass Foo\n   def foo\n   end\nend\n\nfoo = Foo.new\n\nmethod = foo.method(:foo)\nmethod.__file__    # => foo.rb\nmethod.__line__    # => 4\n-------------------------------"
  },
  {
    "path": "distro/google-perftools-1.7/AUTHORS",
    "content": "opensource@google.com\n\n"
  },
  {
    "path": "distro/google-perftools-1.7/COPYING",
    "content": "Copyright (c) 2005, Google Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n    * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "distro/google-perftools-1.7/ChangeLog",
    "content": "Fri Feb 04 15:54:31 2011    Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.7 release\n\t* Reduce page map key size under x86_64 by 4.4MB (rus)\n\t* Remove a flaky malloc-extension test (fdabek)\n\t* Improve the performance of PageHeap::New (ond..., csilvers)\n\t* Improve sampling_test with no-inline additions/etc (fdabek)\n\t* 16-byte align debug allocs (jyasskin)\n\t* Change FillProcSelfMaps to detect out-of-buffer-space (csilvers)\n\t* Document the need for sampling to use GetHeapSample (csilvers)\n\t* Try to read TSC frequency from tsc_freq_khs (adurbin)\n\t* Do better at figuring out if tests are running under gdb (ppluzhnikov)\n\t* Improve spinlock contention performance (ruemmler)\n\t* Better internal-function list for pprof's /contention (ruemmler)\n\t* Speed up GoogleOnce (m3b)\n\t* Limit number of incoming/outgoing edges in pprof (sanjay)\n\t* Add pprof --evince to go along with --gv (csilvers)\n\t* Document the various ways to get heap-profiling information (csilvers)\n\t* Separate out synchronization profiling routines (ruemmler)\n\t* Improve malloc-stats output to be more understandable (csilvers)\n\t* Add support for census profiler in pporf (nabeelmian)\n\t* Document how pprof's /symbol must support GET requests (csilvers)\n\t* Improve acx_pthread.m4 (ssuomi, liujisi)\n\t* Speed up pprof's ExtractSymbols (csilvers)\n\t* Ignore some known-leaky (java) libraries in the heap checker (davidyu)\n\t* Make kHideMask use all 64 bits in tests (ppluzhnikov)\n\t* Clean up pprof input-file handling (csilvers)\n\t* BUGFIX: Don't crash if __environ is NULL (csilvers)\n\t* BUGFIX: Fix totally broken debugallocation tests (csilvers)\n\t* BUGFIX: Fix up fake_VDSO handling for unittest (ppluzhnikov)\n\t* BUGFIX: Suppress all large allocs when report threshold is 0 (lexie)\n\t* BUGFIX: mmap2 on i386 takes an off_t, not off64_t (csilvers)\n\t* PORTING: Add missing PERFTOOLS_DLL_DECL (csilvers)\n\t* PORTING: Add stddef.h to make newer gcc's happy (csilvers)\n\t* PORTING: Document some tricks for working under OS X (csilvers)\n\t* PORTING: Don't try to check valgrind for windows (csilvers)\n\t* PORTING: Make array-size a var to compile under clang (chandlerc)\n\t* PORTING: No longer hook _aligned_malloc and _aligned_free (csilvers)\n\t* PORTING: Quiet some gcc warnings (csilvers)\n\t* PORTING: Replace %PRIxPTR with %p to be more portable (csilvers)\n\t* PORTING: Support systems that capitalize /proc weirdly (sanek)\n\t* PORTING: Treat arm3 the same as arm5t in cycletimer (csilvers)\n\t* PORTING: Update windows logging to not allocate memory (csilvers)\n\t* PORTING: avoid double-patching newer windows DLLs (roger.orr)\n\t* PORTING: get dynamic_annotations.c to work on windows (csilvers)\n\t* Add pkg-config .pc files for the 5 libraries we produce (csilvers)\n\t* Added proper libtool versioning, so this lib will be 0.1.0 (csilvers)\n\t* Moved from autoconf 2.64 to 2.65\n\nThu Aug  5 12:48:03 PDT 2010  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.6 release\n\t* Add tc_malloc_usable_size for compatibility with glibc (csilvers)\n\t* Override malloc_usable_size with tc_malloc_usable_size (csilvers)\n\t* Default to no automatic heap sampling in tcmalloc (csilvers)\n\t* Add -DTCMALLOC_LARGE_PAGES, a possibly faster tcmalloc (rus)\n\t* Make some functions extern \"C\" to avoid false ODR warnings (jyasskin)\n\t* pprof: Add SVG-based output (rsc)\n\t* pprof: Extend pprof --tools to allow per-tool configs (csilvers)\n\t* pprof: Improve support of 64-bit and big-endian profiles (csilvers)\n\t* pprof: Add interactive callgrind suport (weidenri...)\n\t* pprof: Improve address->function mapping a bit (dpeng)\n\t* Better detection of when we're running under valgrind (csilvers)\n\t* Better CPU-speed detection under valgrind (saito)\n\t* Use, and recommend, -fno-builtin-malloc when compiling (csilvers)\n\t* Avoid false-sharing of memory between caches (bmaurer)\n\t* BUGFIX: Fix heap sampling to use correct alloc size (bmauer)\n\t* BUGFIX: Avoid gcc 4.0.x bug by making hook-clearing atomic (csilvers)\n\t* BUGFIX: Avoid gcc 4.5.x optimization bug (csilvers)\n\t* BUGFIX: Work around deps-determining bug in libtool 1.5.26 (csilvers)\n\t* BUGFIX: Fixed test to use HAVE_PTHREAD, not HAVE_PTHREADS (csilvers)\n\t* BUGFIX: Fix tls callback behavior on windows when using wpo (wtc)\n\t* BUGFIX: properly align allocation sizes on Windows (antonm)\n\t* BUGFIX: Fix prototypes for tcmalloc/debugalloc wrt throw() (csilvers)\n\t* DOC: Updated heap-checker doc to match reality better (fischman)\n\t* DOC: Document ProfilerFlush, ProfilerStartWithOptions (csilvers)\n\t* DOC: Update docs for heap-profiler functions (csilvers)\n\t* DOC: Clean up documentation around tcmalloc.slack_bytes (fikes)\n\t* DOC: Renamed README.windows to README_windows.txt (csilvers)\n\t* DOC: Update the NEWS file to be non-empty (csilvers)\n\t* PORTING: Fix windows addr2line and nm with proper rc code (csilvers)\n\t* PORTING: Add CycleClock and atomicops support for arm 5 (sanek)\n\t* PORTING: Improve PC finding on cygwin and redhat 7 (csilvers)\n\t* PORTING: speed up function-patching under windows (csilvers)\n\nTue Jan 19 14:46:12 2010  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.5 release\n\t* Add tc_set_new_mode (willchan)\n\t* Make memalign functions + realloc respect tc_set_new_mode (willchan)\n\t* Add ReleaseToSystem(num_bytes) (kash)\n\t* Handle zero-length symbols a bit better in pprof (csilvers)\n\t* Prefer __environ to /proc/self/environ in cpu profiler (csilvers)\n\t* Add HEAP_CHECK_MAX_LEAKS flag to control #leaks to report (glider)\n\t* Add two new numeric pageheap properties to MallocExtension (fikes)\n\t* Print alloc size when mmap fails (hakon)\n\t* Add ITIMER_REAL support to cpu profiler (csilvers, nabeelmian)\n\t* Speed up symbolizer in heap-checker reporting (glider)\n\t* Speed up futexes with FUTEX_PRIVATE_FLAG (m3b)\n\t* Speed up tcmalloc but doing better span coalescing (sanjay)\n\t* Better support for different wget's and addr2maps in pprof (csilvres)\n\t* Implement a nothrow version of delete and delete[] (csilvers)\n\t* BUGFIX: fix a race on module_libcs[i] in windows patching (csilvers)\n\t* BUGFIX: Fix debugallocation to call cpp_alloc for new (willchan)\n\t* BUGFIX: A simple bugfix for --raw mode (mrabkin)\n\t* BUGFIX: Fix C shims to actually be valid C (csilvers)\n\t* BUGFIX: Fix recursively-unmapped-region accounting (ppluzhnikov)\n\t* BUGFIX: better distinguish real and fake vdso (ppluzhnikov)\n\t* WINDOWS: replace debugmodule with more reliable psai (andrey)\n\t* PORTING: Add .bundle as another shared library extension (csilvers)\n\t* PORTING: Fixed a typo bug in the ocnfigure PRIxx m4 macro (csilvers)\n\t* PORTING: Augment sysinfo to work on 64-bit OS X (csilvers)\n\t* PORTING: Use sys/ucontext.h to fix compiing on OS X 10.6 (csilvers)\n\t* PORTING: Fix sysinfo libname reporting for solaris x86 (jeffrey)\n\t* PORTING: Use libunwind for i386 when using --omitfp (ppluzhnikov)\n\t\nThu Sep 10 13:51:15 2009  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.4 release\n\t* Add debugallocation library, to catch memory leaks, stomping, etc\n\t* Add --raw mode to allow for delayed processing of pprof files\n\t* Use less memory when reading CPU profiles\n\t* New environment variables to control kernel-allocs (sbrk, memfs, etc)\n\t* Add MarkThreadBusy(): performance improvement\n\t* Remove static thread-cache-size code; all is dynamic now\n\t* Add new HiddenPointer class to heap checker\n\t* BUGFIX: pvalloc(0) allocates now (found by new debugalloc library)\n\t* BUGFIX: valloc test (not implementation) no longer overruns memory\n\t* BUGFIX: GetHeapProfile no longer deadlocks\n\t* BUGFIX: Support unmapping memory regions before main\n\t* BUGFIX: Fix some malloc-stats formatting\n\t* BUGFIX: Don't crash as often when freeing libc-allocated memory\n\t* BUGFIX: Deal better with incorrect PPROF_PATH when symbolizing\n\t* BUGFIX: weaken new/delete/etc in addition to malloc/free/etc\n\t* BUGFIX: Fix return value of GetAllocatedSize\n\t* PORTING: Fix mmap-#define problem on some 64-bit systems\n\t* PORTING: Call ranlib again (some OS X versions need it)\n\t* PORTING: Fix a leak when building with LLVM\n\t* PORTING: Remove some unneeded bash-ishs from testing scripts\n\t* WINDOWS: Support library unloading as well as loading\n\t* WINDOWS/BUGFIX: Set page to 'xrw' instead of 'rw' when patching\n\t\nTue Jun  9 18:19:06 2009  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.3 release\n\t* Provide our own name for memory functions: tc_malloc, etc (csilvers)\n\t* Weaken memory-alloc functions so user can override them (csilvers)\n\t* Remove meaningless delete(nothrow) and delete[](nothrow) (csilvers)\n\t* BUILD: replace clever libtcmalloc/profiler.a with a new .a (csilvers)\n\t* PORTING: improve windows port  by using google spinlocks (csilvers)\n\t* PORTING: Fix RedHat 9 memory allocation in heapchecker (csilvers)\n\t* PORTING: Rename OS_WINDOWS macro to PLATFORM_WINDOWS (mbelshe)\n\t* PORTING/BUGFIX: Make sure we don't clobber GetLastError (mbelshe)\n\t* BUGFIX: get rid of useless data for callgrind (weidenrinde)\n\t* BUGFIX: Modify windows patching to deadlock sometimes (csilvers)\n\t* BUGFIX: an improved fix for hook handling during fork (csilvers)\n\t* BUGFIX: revamp profiler_unittest.sh, which was very broken (csilvers)\n\t\nFri Apr 17 16:40:48 2009  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.2 release\n\t* Allow large_alloc_threshold=0 to turn it off entirely (csilvers)\n\t* Die more helpfully when out of memory for internal data (csilvers)\n\t* Refactor profile-data gathering, add a new unittest (cgd, nabeelmian)\n\t* BUGFIX: fix rounding errors with static thread-size caches (addi)\n\t* BUGFIX: disable hooks better when forking in leak-checker (csilvers)\n\t* BUGFIX: fix realloc of crt pointers on windows (csilvers)\n\t* BUGFIX: do a better job of finding binaries in .sh tests (csilvers)\n\t* WINDOWS: allow overriding malloc/etc instead of patching (mbelshe)\n\t* PORTING: fix compilation error in a ppc-specific file (csilvers)\n\t* PORTING: deal with quirks in cygwin's /proc/self/maps (csilvers)\n\t* PORTING: use 'A' version of functions for ascii input (mbelshe)\n\t* PORTING: generate .so's on cygwin and mingw (ajenjo)\n\t* PORTING: disable profiler methods on cygwin (jperkins)\n\t* Updated autoconf version to 2.61 and libtool version to 1.5.26\n\nWed Mar 11 11:25:34 2009  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.1 release\n\t* Dynamically resize thread caches -- nice perf. improvement (kash)\n\t* Add VDSO support to give better stacktraces in linux (ppluzhnikov)\n\t* Improve heap-profiling sampling algorithm (ford)\n\t* Rewrite leak-checking code: should be faster and more robust (sanjay)\n\t* Use ps2 instead of ps for dot: better page cropping for gv (csilvers)\n\t* Disable malloc-failure warning messages by default (csilvers)\n\t* Update config/Makefile to disable tests on a per-OS basis (csilvers)\n\t* PORTING: Get perftools compiling under MSVC 7.1 again (csilvers)\n\t* PORTING: Get perftools compiling under cygwin again (csilvers)\n\t* PORTING: automatically set library flags for solaris x86 (csilvers)\n\t* Add TCMALLOC_SKIP_SBRK to mirror TCMALLOC_SKIP_MMAP (csilvers)\n\t* Add --enable flags to allow selective building (csilvers)\n\t* Put addr2line-pdb and nm-pdb in proper output directory (csilvers)\n\t* Remove deprecated DisableChecksIn (sanjay)\n\t* DOCUMENTATION: Document most MallocExtension routines (csilvers)\n\t\nTue Jan  6 13:58:56 2009  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.0 release\n\t* Exactly the same as 1.0rc2\n\nSun Dec 14 17:10:35 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.0rc2 release\n\t* Fix compile error on 64-bit systems (casting ptr to int) (csilvers)\n\nThu Dec 11 16:01:32 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 1.0rc1 release\n\t* Replace API for selectively disabling heap-checker in code (sanjay)\n\t* Add a pre-mmap hook (daven, adlr)\n\t* Add MallocExtension interface to set memory-releasing rate (fikes)\n\t* Augment pprof to allow any string ending in /pprof/profile (csilvers)\n\t* PORTING: Rewrite -- and fix --  malloc patching for windows (dvitek)\n\t* PORTING: Add nm-pdb and addr2line-pdb for use by pprof (dvitek)\n\t* PORTING: Improve cygwin and mingw support (jperkins, csilvers)\n\t* PORTING: Fix pprof for mac os x, other pprof improvements (csilvers)\n\t* PORTING: Fix some PPC bugs in our locking code (anton.blanchard)\n\t* A new unittest, smapling_test, to verify tcmalloc-profiles (csilvers)\n\t* Turn off TLS for gcc < 4.1.2, due to a TLS + -fPIC bug (csilvers)\n\t* Prefer __builtin_frame_address to assembly for stacktraces (nlewycky)\n\t* Separate tcmalloc.cc out into multiple files -- finally! (kash)\n\t* Make our locking code work with -fPIC on 32-bit x86 (aruns)\n\t* Fix an initialization-ordering bug for tcmalloc/profiling (csilvers)\n\t* Use \"initial exec\" model of TLS to speed up tcmalloc (csilvers)\n\t* Enforce 16-byte alignment for tcmalloc, for SSE (sanjay)\n\t\nTue Sep 23 08:56:31 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.99.2 release\n\t* COMPILE FIX: add #include needed for FreeBSD and OS X (csilvers)\n\nSat Sep 20 09:37:18 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.99.1 release\n\t* BUG FIX: look for nm, etc in /usr/bin, not /usr/crosstool (csilvers)\n\nThu Sep 18 16:00:27 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.99 release\n\t* Add IsHeapProfileRunning (csilvers)\n\t* Add C shims for some of the C++ header files (csilvers)\n\t* Fix heap profile file clean-up logic (maxim)\n\t* Rename linuxthreads.c to .cc for better compiler support (csilvers)\n\t* Add source info to disassembly in pprof (sanjay)\n\t* Use open instead of fopen to avoid memory alloc (csilvers)\n\t* Disable malloc extensions when running under valgrind (kcc)\n\t* BUG FIX: Fix out-of-bound error by reordering a check (larryz)\n\t* Add Options struct to ProfileData (cgd)\n\t* Correct PC-handling of --base in pprof (csilvers)\n\t* Handle 1 function occurring twice in an image (sanjay)\n\t* Improve stack-data cleaning (maxim)\n\t* Use 'struct Foo' to make header C compatible (csilvers)\n\t* Add 'total' line to pprof --text (csilvers)\n\t* Pre-allocate buffer for heap-profiler to avoid OOM errors (csilvers)\n\t* Allow a few more env-settings to control tcmalloc (csilvers)\n\t* Document some of the issues involving thread-local storage (csilvers)\n\t* BUG FIX: Define strtoll and friends for windows (csilvers)\n\nMon Jun  9 16:47:03 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.98 release\n\t* Add ProfilerStartWithOptions() (cgd)\n\t* Change tcmalloc_minimal to not do any stack-tracing at all (csilvers)\n\t* Prefer mmap to sbrk for 64-buit debug mode (sanjay)\n\t* Fix accounting for some tcmalloc stats (sanjay)\n\t* Use setrlimit() to keep unittests from killing the machine (odo)\n\t* Fix a bug when sbrk-ing near address 4G (csilvers)\n\t* Make MallocHook thread-safe (jyasskin)\n\t* Fix windows build for MemoryBarrier (jyasskin)\n\t* Fix CPU-profiler docs to mention correct libs (csilvers)\n\t* Fix for GetHeapProfile() when heap-profiling is off (maxim)\n\t* Avoid realloc resizing ping-pongs using hysteresis (csilvers)\n\t* Add --callgrind output support to pprof (klimek)\n\t* Fix profiler.h and heap-profiler.h to be C-compatible (csilvers)\n\t* Break malloc_hook.h into two parts to reduce dependencies (csilvers)\n\t* Better handle systems that don't implement mmap (csilvers)\n\t* PORTING: disable system_alloc_unittest for msvc (csilvers)\n\t* PORTING: Makefile tweaks to build better on cygwin (csilvers)\n\t\nMon Apr 21 15:20:52 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.97 release\n\t* Refactor GetHeapProfile to avoid using malloc (maxim)\n\t* Fix heap-checker and heap-profiler hook interactions (maxim)\n\t* Fix a data race in MemoryRegionMap::Lock (jyasskin)\n\t* Improve thread-safety of leak checker (maxim)\n\t* Fix mmap profile to no longer deadlock (maxim)\n\t* Fix rpm to have devel package depend on non-devel (csilvers)\n\t* PORTING: Fix clock-speed detection for Mac OS X (csilvers)\n\nTue Mar 18 14:30:44 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.96 release\n\t* major atomicops rewrite; fixed atomic ops code for linux/ppc (vchen)\n\t* nix the stacktrace library; now build structure is simpler (csilvers)\n\t* Speed up heap-checker, and reduce extraneous logging (maxim)\n\t* Improve itimer code for NPTL case (cgd)\n\t* Add source code annotations for use by valgrind, etc (kcc)\n\t* PORTING: Fix high resolution timers for Mac OS X (adlr)\n\nTue Feb 19 12:01:31 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.95.1 release  (bugfix release)\n\t* x86_64 compile-fix: nix pread64 and pwrite64 (csilvers)\n\t* more heap-checker debug logging (maxim)\n\t* minor improvement to x86_64 CycleClock (gpike)\n\nTue Feb 12 12:28:32 2008  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.95 release\n\t* Better -- not perfect -- support for linux-ppc (csilvers)\n\t* Fix race condition in libunwind stacktrace (aruns)\n\t* Speed up x86 spinlock locking (m3b)\n\t* Improve heap-checker performance (maxim)\n\t* Heap checker traverses more ptrs inside heap-alloced objects (maxim)\n\t* Remove deprecated ProfilerThreadState function (cgd)\n\t* Update libunwind documentation for statically linked binaries (aruns)\n\nMon Dec  3 23:51:54 2007  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.94.1 release  (bugfix release)\n\t* Fix missing #includes for x86_64 compile using libunwind (csilvers)\n\nThu Nov 29 07:59:43 2007  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.94 release\n\t* PORTING: MinGW/Msys support -- runs same code as MSVC does (csilvers)\n\t* PORTING: Add NumCPUs support for Mac OS X (csilvers)\n\t* Work around a sscanf bug in glibc(?) (waldemar)\n\t* Fix Windows MSVC bug triggered by thread deletion (csilvers)\n\t* Fix bug that triggers in MSVC /O2: missing volatile (gpike)\n\t* March-of-time support: quiet warnings/errors for gcc 4.2, OS X 10.5\n\t* Modify pprof so it works without nm: useful for windows (csilvers)\n\t* pprof: Support filtering for CPU profiles (cgd)\n\t* Bugfix: have realloc report to hooks in all situations (maxim)\n\t* Speed improvement: replace slow memcpy with std::copy (soren)\n\t* Speed: better iterator efficiency in RecordRegionRemoval (soren)\n\t* Speed: minor speed improvements via better bitfield alignment (gpike)\n\t* Documentation: add documentation of binary profile output (cgd)\n\t\nFri Aug 17 12:32:56 2007  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.93 release\n\t* PORTING: everything compiles on Solaris, OS X, FreeBSD (see INSTALL)\n\t* PORTING: cpu-profiler works on most platforms (much better GetPC())\n\t* PORTING: heap-profiler works on most platforms\n\t* PORTING: improved windows support, including release builds\n\t* No longer build or run ptmalloc tests by default\n\t* Add support for using memfs filesystem to allocate memory in linux\n\t* WINDOWS: give debug library and release library different names\n\t\nTue Jul 17 22:26:27 2007  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.92 release\n\t* PERFORMANCE: use a packed cache to speed up tcmalloc\n\t* PORTING: preliminary windows support! (see README.windows)\n\t* PORTING: better support for solaris, OS X, FreeBSD (see INSTALL)\n\t* Envvar support for running the heap-checker under gdb\n\t* Add weak declarations to maybe_threads to fix no-pthreads compile bugs\n\t* Some 64bit fixes, especially with pprof\n\t* Better heap-checker support for some low-level allocations\n\t* Fix bug where heap-profiles would sometimes get truncated\n\t* New documentation about how to handle common heap leak situations\n\t* Use computed includes for hash_map/set: easier config\n\t* Added all used .m4 templates to the distribution\n\nWed Apr 18 16:43:55 2007  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.91 release\n\t* Brown-paper-bag bugfix: compilation error on some x86-64 machines\n\nFri Apr 13 14:50:51 2007  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.90 release\n\t* (As the version-number jump hints, this is a major new release:\n\t  almost every piece of functionality was rewritten.  I can't do\n\t  justice to all the changes, but will concentrate on highlights.)\n\t*** USER-VISIBLE CHANGES:\n\t* Ability to \"release\" unused memory added to tcmalloc\n\t* Exposed more tweaking knobs via environment variables (see docs)\n\t* pprof tries harder to map addresses to functions\n\t* tcmalloc_minimal compiles and runs on FreeBSD 6.0 and Solaris 10\n\t*** INTERNAL CHANGES:\n\t* Much better 64-bit support\n\t* Better multiple-processor support (e.g. multicore contention tweaks)\n\t* Support for recent kernel ABI changes (e.g. new arg to mremap)\n\t* Addition of spinlocks to tcmalloc to reduce contention cost\n\t* Speed up tcmalloc by using __thread on systems that support TLS\n\t* Total redesign of heap-checker to improve liveness checking\n\t* More portable stack-frame analysis -- no more hard-coded constants!\n\t* Disentangled heap-profiler code and heap-checker code\n\t* Several new unittests to test, e.g., thread-contention costs\n\t* Lots of small (but important!) bug fixes: e.g., fixing GetPC on amd64\n\t*** KNOWN PROBLEMS:\n\t* CPU-profiling may crash on x86_64 (64-bit) systems.  See the README\n\t* Profiling/heap-checking may deadlock on x86_64 systems.  See README\n\nWed Jun 14 15:11:14 2006  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.8 release\n\t* Experimental support for remote profiling added to pprof (many)\n\t* Fixed race condition in ProfileData::FlushTable (etune)\n\t* Better support for weird /proc maps (maxim, mec)\n\t* Fix heap-checker interaction with gdb (markus)\n\t* Better 64-bit support in pprof (aruns)\n\t* Reduce scavenging cost in tcmalloc by capping NumMoveSize (sanjay)\n\t* Cast syscall(SYS_mmap); works on more 64-bit systems now (menage)\n\t* Document the text output of pprof! (csilvers)\n\t* Better compiler support for no-THREADS and for old compilers (csilvers)\n\t* Make libunwind the default stack unwinder for x86-64 (aruns)\n\t* Somehow the COPYING file got erased.  Regenerate it (csilvers)\n\nThu Apr 13 20:59:09 2006  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.7 release\n\t* Major rewrite of thread introspection for new kernels (markus)\n\t* Major rewrite of heap-checker to use new thread tools (maxim)\n\t* Add proper support for following data in thread registers (maxim)\n\t* Syscall support for older kernels, including _syscall6 (markus)\n\t* Support PIC mode (markus, mbland, iant)\n\t* Better support for running in non-threaded contexts (csilvers)\n\nFri Jan 27 14:04:27 2006  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.6 release\n\t* More sophisticated stacktrace usage, possibly using libunwind (aruns)\n\t* Update pprof to handle 64-bit profiles (dehnert)\n\t* Fix GetStackTrace to correctly return top stackframe (sanjay)\n\t* Add ANSI compliance for new and new[], including new_handler (jkearney)\n\t* More accuracy by reading ELF files directly rather than objdump (mec)\n\t* Add readline support for pprof (addi)\n\t* Add #includes for PPC (csilvers)\n\t* New PC-detection routine for ibook powerpc (asbestoshead)\n\t* Vastly improved tcmalloc unittest (csilvers)\n\t* Move documentation from /usr/doc to /usr/share/doc\n\nMon Nov 14 17:28:59 2005  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.5 release\n\t* Add va_start/va_end calls around vsnprintf() (csilvers)\n\t* Write our own __syscall_return(), since it's not defined\n\t  consistently on all 64-bit linux distros (markus)\n\nWed Oct 26 15:19:16 2005  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.4 release\n\t* Decrease fragmentation in tcmalloc (lefevere)\n\t* Support for ARM in some of the thread-specific code (markus)\n\t* Turn off heap-checker for statically-linked binaries, which\n\t  cause error leak reports now (etune)\n\t* Many pprof improvements, including a command-line interface (jeff)\n\t* CPU profiling now automatically affects all threads in linux 2.6.\n\t  (Kernel bugs break CPU profiling and threads in linux 2.4 a bit.)\n\t  ProfilerEnable() and ProfilerDisable() are deprecated.  (sanjay)\n\t* tcmalloc now correctly intercepts memalign (m3b, maxim)\n\t* Syntax fix: added missing va_end()s.  Helps non-gcc compiling (etune)\n\t* Fixed a few coredumper bugs: race condition after PTRACE_DETACH,\n\t  ignore non-aligned stackframe pointers (markus, menage)\n\t* 64-bit cleanup, especially for spinlock code (etune) and mmap (sanjay)\n\t* Better support for finding threads in linux (markus)\n\t* tcmalloc now tracks those stack traces that allocate memory (sanjay)\n\t* Work around a weird setspecific problem (sanjay)\n\t* Fix tcmalloc overflow problems when an alloc is close to 2G/4G (sanjay)\n\nFri Jun 24 18:02:26 2005  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.3 release\n\t* Add missing errno include for one of the unittests (csilvers)\n\t* Reduce tcmalloc startup memory from 5M to 256K (sanjay)\n\t* Add support for mallopt() and mallinfo (sanjay)\n\t* Improve stacktrace's performance on some 64-bit systems (etune)\n\t* Improve the stacktrace unittest (etune)\n\nTue May 31 08:14:38 2005  Google Inc. <opensource@google.com>\n\n\t* google-perftools: version 0.2 release\n\t* Use mmap2() instead of mmap(), to map more memory (menage)\n\t* Do correct pthread-local checking in heap-checker! (maxim)\n\t* Avoid overflow on 64-bit machines in pprof (sanjay)\n\t* Add a few more GetPC() functions, including for AMD (csilvers)\n\t* Better method for overriding pthread functions (menage)\n\t* (Hacky) fix to avoid overwriting profile files after fork() (csilvers)\n\t* Crashing bugfix involving dumping heaps on small-stack threads (tudor)\n\t* Allow library versions with letters at the end (csilvers)\n\t* Config fixes for systems that don't define PATH_MAX (csilvers)\n\t* Confix fixes so we no longer need config.h after install (csilvers)\n\t* Fix to pprof to correctly read very big cpu profiles (csilvers)\n\t* Fix to pprof to deal with new commandline flags in modern gv's\n\t* Better error reporting when we can't access /proc/maps (etune)\n\t* Get rid of the libc-preallocate code (which could crash on some\n\t  systems); no longer needed with local-threads fix (csilvers)\n\nTue Feb 8 09:57:17 2005  Google Inc. <opensource@google.com>\n\n\t* google-perftools: initial release:\n\t  The google-perftools package contains some utilities to improve\n\t  and analyze the performance of C++ programs.  This includes an\n\t  optimized thread-caching malloc() and cpu and heap profiling\n\t  utilities.\n"
  },
  {
    "path": "distro/google-perftools-1.7/INSTALL",
    "content": "Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software\nFoundation, Inc.\n\n   This file is free documentation; the Free Software Foundation gives\nunlimited permission to copy, distribute and modify it.\n\n\nPerftools-Specific Install Notes\n================================\n\n*** NOTE FOR 64-BIT LINUX SYSTEMS\n\nThe glibc built-in stack-unwinder on 64-bit systems has some problems\nwith the perftools libraries.  (In particular, the cpu/heap profiler\nmay be in the middle of malloc, holding some malloc-related locks when\nthey invoke the stack unwinder.  The built-in stack unwinder may call\nmalloc recursively, which may require the thread to acquire a lock it\nalready holds: deadlock.)\n\nFor that reason, if you use a 64-bit system, we strongly recommend you\ninstall libunwind before trying to configure or install google\nperftools.  libunwind can be found at\n\n   http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz\n\nEven if you already have libunwind installed, you should check the\nversion.  Versions older than this will not work properly; too-new\nversions introduce new code that does not work well with perftools\n(because libunwind can call malloc, which will lead to deadlock).\n\nCAUTION: if you install libunwind from the url above, be aware that\nyou may have trouble if you try to statically link your binary with\nperftools: that is, if you link with 'gcc -static -lgcc_eh ...'.  This\nis because both libunwind and libgcc implement the same C++ exception\nhandling APIs, but they implement them differently on some platforms.\nThis is not likely to be a problem on ia64, but may be on x86-64.\n\nAlso, if you link binaries statically, make sure that you add \n-Wl,--eh-frame-hdr to your linker options. This is required so that\nlibunwind can find the information generated by the compiler required\nfor stack unwinding.\n\nUsing -static is rare, though, so unless you know this will affect you\nit probably won't.\n\nIf you cannot or do not wish to install libunwind, you can still try\nto use the built-in stack unwinder.  The built-in stack unwinder\nrequires that your application, the tcmalloc library, and system\nlibraries like libc, all be compiled with a frame pointer.  This is\n*not* the default for x86-64.\n\nIf you are on x86-64 system, know that you have a set of system\nlibraries with frame-pointers enabled, and compile all your\napplications with -fno-omit-frame-pointer, then you can enable the\nbuilt-in perftools stack unwinder by passing the\n--enable-frame-pointers flag to configure.\n\nEven with the use of libunwind, there are still known problems with\nstack unwinding on 64-bit systems, particularly x86-64.  See the\n\"64-BIT ISSUES\" section in README.\n\nIf you encounter problems, try compiling perftools with './configure\n--enable-frame-pointers'.  Note you will need to compile your\napplication with frame pointers (via 'gcc -fno-omit-frame-pointer\n...') in this case.\n\n\n*** TCMALLOC LARGE PAGES: TRADING TIME FOR SPACE\n\nInternally, tcmalloc divides its memory into \"pages.\"  The default\npage size is chosen to minimize memory use by reducing fragmentation.\nThe cost is that keeping track of these pages can cost tcmalloc time.\nWe've added a new, experimental flag to tcmalloc that enables a larger\npage size.  In general, this will increase the memory needs of\napplications using tcmalloc.  However, in many cases it will speed up\nthe applications as well, particularly if they allocate and free a lot\nof memory.  We've seen average speedups of 3-5% on Google\napplications.\n\nThis feature is still very experimental; it's not even a configure\nflag yet.  To build libtcmalloc with large pages, run\n\n   ./configure <normal flags> CXXFLAGS=-DTCMALLOC_LARGE_PAGES\n\n(or add -DTCMALLOC_LARGE_PAGES to your existing CXXFLAGS argument).\n\n\n*** NOTE FOR ___tls_get_addr ERROR\n\nWhen compiling perftools on some old systems, like RedHat 8, you may\nget an error like this:\n    ___tls_get_addr: symbol not found\n\nThis means that you have a system where some parts are updated enough\nto support Thread Local Storage, but others are not.  The perftools\nconfigure script can't always detect this kind of case, leading to\nthat error.  To fix it, just comment out the line\n   #define HAVE_TLS 1\nin your config.h file before building.\n\n\n*** TCMALLOC AND DLOPEN\n\nTo improve performance, we use the \"initial exec\" model of Thread\nLocal Storage in tcmalloc.  The price for this is the library will not\nwork correctly if it is loaded via dlopen().  This should not be a\nproblem, since loading a malloc-replacement library via dlopen is\nasking for trouble in any case: some data will be allocated with one\nmalloc, some with another.  If, for some reason, you *do* need to use\ndlopen on tcmalloc, the easiest way is to use a version of tcmalloc\nwith TLS turned off; see the ___tls_get_addr note above.\n\n\n*** COMPILING ON NON-LINUX SYSTEMS\n\nPerftools has been tested on the following systems:\n   FreeBSD 6.0 (x86)\n   Linux Fedora Core 3 (x86)\n   Linux Fedora Core 4 (x86)\n   Linux Fedora Core 5 (x86)\n   Linux Fedora Core 6 (x86)\n   Linux Ubuntu 6.06.1 (x86)\n   Linux Ubuntu 6.06.1 (x86_64)\n   Linux RedHat 9 (x86)\n   Linux Debian 4.0 (PPC)\n   Mac OS X 10.3.9 (Panther) (PowerPC)\n   Mac OS X 10.4.8 (Tiger) (PowerPC)\n   Mac OS X 10.4.8 (Tiger) (x86)\n   Mac OS X 10.5 (Leopard) (x86)\n   Solaris 10 (x86)\n   Windows XP, Visual Studio 2003 (VC++ 7) (x86)\n   Windows XP, Visual Studio 2005 (VC++ 8) (x86)\n   Windows XP, MinGW 5.1.3 (x86)\n   Windows XP, Cygwin 5.1 (x86)\n\nIt works in its full generality on the Linux systems\ntested (though see 64-bit notes above).  Portions of perftools work on\nthe other systems.  The basic memory-allocation library,\ntcmalloc_minimal, works on all systems.  The cpu-profiler also works\nfairly widely.  However, the heap-profiler and heap-checker are not\nyet as widely supported.  In general, the 'configure' script will\ndetect what OS you are building for, and only build the components\nthat work on that OS.\n\nNote that tcmalloc_minimal is perfectly usable as a malloc/new\nreplacement, so it is possible to use tcmalloc on all the systems\nabove, by linking in libtcmalloc_minimal.\n\n** FreeBSD:\n\n   The following binaries build and run successfully (creating\n   libtcmalloc_minimal.so and libprofile.so in the process):\n      % ./configure\n      % make tcmalloc_minimal_unittest tcmalloc_minimal_large_unittest \\\n             addressmap_unittest atomicops_unittest frag_unittest \\\n             low_level_alloc_unittest markidle_unittest memalign_unittest \\\n             packed_cache_test stacktrace_unittest system_alloc_unittest \\\n             thread_dealloc_unittest profiler_unittest.sh\n      % ./tcmalloc_minimal_unittest    # to run this test\n      % [etc]                          # to run other tests\n\n   Three caveats: first, frag_unittest tries to allocate 400M of memory,\n   and if you have less virtual memory on your system, the test may\n   fail with a bad_alloc exception.\n\n   Second, profiler_unittest.sh sometimes fails in the \"fork\" test.\n   This is because stray SIGPROF signals from the parent process are\n   making their way into the child process.  (This may be a kernel\n   bug that only exists in older kernels.)  The profiling code itself\n   is working fine.  This only affects programs that call fork(); for\n   most programs, the cpu profiler is entirely safe to use.\n\n   Third, perftools depends on /proc to get shared library\n   information.  If you are running a FreeBSD system without proc,\n   perftools will not be able to map addresses to functions.  Some\n   unittests will fail as a result.\n\n   Finally, the new test introduced in perftools-1.2,\n   profile_handler_unittest, fails on FreeBSD.  It has something to do\n   with how the itimer works.  The cpu profiler test passes, so I\n   believe the functionality is correct and the issue is with the test\n   somehow.  If anybody is an expert on itimers and SIGPROF in\n   FreeBSD, and would like to debug this, I'd be glad to hear the\n   results!\n\n   libtcmalloc.so successfully builds, and the \"advanced\" tcmalloc\n   functionality all works except for the leak-checker, which has\n   Linux-specific code:\n      % make heap-profiler_unittest.sh maybe_threads_unittest.sh \\\n             tcmalloc_unittest tcmalloc_both_unittest \\\n             tcmalloc_large_unittest              # THESE WORK\n      % make -k heap-checker_unittest.sh \\\n                heap-checker-death_unittest.sh    # THESE DO NOT\n\n   Note that unless you specify --enable-heap-checker explicitly,\n   'make' will not build the heap-checker unittests on a FreeBSD\n   system.\n\n   I have not tested other *BSD systems, but they are probably similar.\n\n** Mac OS X:\n\n   I've tested OS X 10.5 [Leopard], OS X 10.4 [Tiger] and OS X 10.3\n   [Panther] on both intel (x86) and PowerPC systems.  For Panther\n   systems, perftools does not work at all: it depends on a header\n   file, OSAtomic.h, which is new in 10.4.  (It's possible to get the\n   code working for Panther/i386 without too much work; if you're\n   interested in exploring this, drop an e-mail.)\n\n   For the other seven systems, the binaries and libraries that\n   successfully build are exactly the same as for FreeBSD.  See that\n   section for a list of binaries and instructions on building them.\n\n   In addition, it appears OS X regularly fails profiler_unittest.sh\n   in the \"thread\" test (in addition to occassionally failing in the\n   \"fork\" test).  It looks like OS X often delivers the profiling\n   signal to the main thread, even when it's sleeping, rather than\n   spawned threads that are doing actual work.  If anyone knows\n   details of how OS X handles SIGPROF (via setitimer()) events with\n   threads, and has insight into this problem, please send mail to\n   google-perftools@googlegroups.com.\n\n** Solaris 10 x86:\n\n   I've only tested using the GNU C++ compiler, not the Sun C++\n   compiler.  Using g++ requires setting the PATH appropriately when\n   configuring.\n\n   % PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin ./configure\n   % PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin make [...]\n\n   Again, the binaries and libraries that successfully build are\n   exactly the same as for FreeBSD.  (However, while libprofiler.so can\n   be used to generate profiles, pprof is not very successful at\n   reading them -- necessary helper programs like nm don't seem\n   to be installed by default on Solaris, or perhaps are only\n   installed as part of the Sun C++ compiler package.)  See that\n   section for a list of binaries, and instructions on building them.\n\n** Windows:\n\n   Work on Windows is rather preliminary: we haven't found a good way\n   to get stack traces in release mode on windows (that is, when FPO\n   is enabled), so the heap profiling may not be reliable in that\n   case.  Also, heap-checking and CPU profiling do not yet work at\n   all.  But as in other ports, the basic tcmalloc library\n   functionality, overriding malloc and new and such (and even\n   windows-specific functions like _aligned_malloc!), is working fine,\n   at least with VC++ 7.1 (Visual Studio 2003) and VC++ 8.0\n   (Visual Studio 2005), in both debug and release modes.  See\n   README.windows for instructions on how to install on Windows using\n   Visual Studio.\n\n   Cygwin can compile some but not all of perftools.  Furthermore,\n   there is a problem with exception-unwinding in cygwin (it can call\n   malloc, which can call the exception-unwinding-setup code, which\n   can lead to an infinite loop).  I've comitted a workaround to the\n   exception unwinding problem, but it only works in debug mode and\n   when statically linking in tcmalloc.  I hope to have a more proper\n   fix in a later release.  To configure under cygwin, run\n\n      ./configure --disable-shared CXXFLAGS=-g && make\n\n   Most of cygwin will compile (cygwin doesn't allow weak symbols, so\n   the heap-checker and a few other pieces of functionality will not\n   compile).  'make' will compile those libraries and tests that can\n   be compiled.  You can run 'make check' to make sure the basic\n   functionality is working.  I've heard reports that some versions of\n   cygwin fail calls to pthread_join() with EINVAL, causing several\n   tests to fail.  If you have any insight into this, please mail\n   google-perftools@googlegroups.com.\n\n   This Windows functionality is also available using MinGW and Msys,\n   In this case, you can use the regular './configure && make'\n   process.  'make install' should also work.  The Makefile will limit\n   itself to those libraries and binaries that work on windows.\n\n\nBasic Installation\n==================\n\n   These are generic installation instructions.\n\n   The `configure' shell script attempts to guess correct values for\nvarious system-dependent variables used during compilation.  It uses\nthose values to create a `Makefile' in each directory of the package.\nIt may also create one or more `.h' files containing system-dependent\ndefinitions.  Finally, it creates a shell script `config.status' that\nyou can run in the future to recreate the current configuration, and a\nfile `config.log' containing compiler output (useful mainly for\ndebugging `configure').\n\n   It can also use an optional file (typically called `config.cache'\nand enabled with `--cache-file=config.cache' or simply `-C') that saves\nthe results of its tests to speed up reconfiguring.  (Caching is\ndisabled by default to prevent problems with accidental use of stale\ncache files.)\n\n   If you need to do unusual things to compile the package, please try\nto figure out how `configure' could check whether to do them, and mail\ndiffs or instructions to the address given in the `README' so they can\nbe considered for the next release.  If you are using the cache, and at\nsome point `config.cache' contains results you don't want to keep, you\nmay remove or edit it.\n\n   The file `configure.ac' (or `configure.in') is used to create\n`configure' by a program called `autoconf'.  You only need\n`configure.ac' if you want to change it or regenerate `configure' using\na newer version of `autoconf'.\n\nThe simplest way to compile this package is:\n\n  1. `cd' to the directory containing the package's source code and type\n     `./configure' to configure the package for your system.  If you're\n     using `csh' on an old version of System V, you might need to type\n     `sh ./configure' instead to prevent `csh' from trying to execute\n     `configure' itself.\n\n     Running `configure' takes awhile.  While running, it prints some\n     messages telling which features it is checking for.\n\n  2. Type `make' to compile the package.\n\n  3. Optionally, type `make check' to run any self-tests that come with\n     the package.\n\n  4. Type `make install' to install the programs and any data files and\n     documentation.\n\n  5. You can remove the program binaries and object files from the\n     source code directory by typing `make clean'.  To also remove the\n     files that `configure' created (so you can compile the package for\n     a different kind of computer), type `make distclean'.  There is\n     also a `make maintainer-clean' target, but that is intended mainly\n     for the package's developers.  If you use it, you may have to get\n     all sorts of other programs in order to regenerate files that came\n     with the distribution.\n\nCompilers and Options\n=====================\n\n   Some systems require unusual options for compilation or linking that\nthe `configure' script does not know about.  Run `./configure --help'\nfor details on some of the pertinent environment variables.\n\n   You can give `configure' initial values for configuration parameters\nby setting variables in the command line or in the environment.  Here\nis an example:\n\n     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix\n\n   *Note Defining Variables::, for more details.\n\nCompiling For Multiple Architectures\n====================================\n\n   You can compile the package for more than one kind of computer at the\nsame time, by placing the object files for each architecture in their\nown directory.  To do this, you must use a version of `make' that\nsupports the `VPATH' variable, such as GNU `make'.  `cd' to the\ndirectory where you want the object files and executables to go and run\nthe `configure' script.  `configure' automatically checks for the\nsource code in the directory that `configure' is in and in `..'.\n\n   If you have to use a `make' that does not support the `VPATH'\nvariable, you have to compile the package for one architecture at a\ntime in the source code directory.  After you have installed the\npackage for one architecture, use `make distclean' before reconfiguring\nfor another architecture.\n\nInstallation Names\n==================\n\n   By default, `make install' will install the package's files in\n`/usr/local/bin', `/usr/local/man', etc.  You can specify an\ninstallation prefix other than `/usr/local' by giving `configure' the\noption `--prefix=PATH'.\n\n   You can specify separate installation prefixes for\narchitecture-specific files and architecture-independent files.  If you\ngive `configure' the option `--exec-prefix=PATH', the package will use\nPATH as the prefix for installing programs and libraries.\nDocumentation and other data files will still use the regular prefix.\n\n   In addition, if you use an unusual directory layout you can give\noptions like `--bindir=PATH' to specify different values for particular\nkinds of files.  Run `configure --help' for a list of the directories\nyou can set and what kinds of files go in them.\n\n   If the package supports it, you can cause programs to be installed\nwith an extra prefix or suffix on their names by giving `configure' the\noption `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.\n\nOptional Features\n=================\n\n   Some packages pay attention to `--enable-FEATURE' options to\n`configure', where FEATURE indicates an optional part of the package.\nThey may also pay attention to `--with-PACKAGE' options, where PACKAGE\nis something like `gnu-as' or `x' (for the X Window System).  The\n`README' should mention any `--enable-' and `--with-' options that the\npackage recognizes.\n\n   For packages that use the X Window System, `configure' can usually\nfind the X include and library files automatically, but if it doesn't,\nyou can use the `configure' options `--x-includes=DIR' and\n`--x-libraries=DIR' to specify their locations.\n\nSpecifying the System Type\n==========================\n\n   There may be some features `configure' cannot figure out\nautomatically, but needs to determine by the type of machine the package\nwill run on.  Usually, assuming the package is built to be run on the\n_same_ architectures, `configure' can figure that out, but if it prints\na message saying it cannot guess the machine type, give it the\n`--build=TYPE' option.  TYPE can either be a short name for the system\ntype, such as `sun4', or a canonical name which has the form:\n\n     CPU-COMPANY-SYSTEM\n\nwhere SYSTEM can have one of these forms:\n\n     OS KERNEL-OS\n\n   See the file `config.sub' for the possible values of each field.  If\n`config.sub' isn't included in this package, then this package doesn't\nneed to know the machine type.\n\n   If you are _building_ compiler tools for cross-compiling, you should\nuse the `--target=TYPE' option to select the type of system they will\nproduce code for.\n\n   If you want to _use_ a cross compiler, that generates code for a\nplatform different from the build platform, you should specify the\n\"host\" platform (i.e., that on which the generated programs will\neventually be run) with `--host=TYPE'.\n\nSharing Defaults\n================\n\n   If you want to set default values for `configure' scripts to share,\nyou can create a site shell script called `config.site' that gives\ndefault values for variables like `CC', `cache_file', and `prefix'.\n`configure' looks for `PREFIX/share/config.site' if it exists, then\n`PREFIX/etc/config.site' if it exists.  Or, you can set the\n`CONFIG_SITE' environment variable to the location of the site script.\nA warning: not all `configure' scripts look for a site script.\n\nDefining Variables\n==================\n\n   Variables not defined in a site shell script can be set in the\nenvironment passed to `configure'.  However, some packages may run\nconfigure again during the build, and the customized values of these\nvariables may be lost.  In order to avoid this problem, you should set\nthem in the `configure' command line, using `VAR=value'.  For example:\n\n     ./configure CC=/usr/local2/bin/gcc\n\nwill cause the specified gcc to be used as the C compiler (unless it is\noverridden in the site shell script).\n\n`configure' Invocation\n======================\n\n   `configure' recognizes the following options to control how it\noperates.\n\n`--help'\n`-h'\n     Print a summary of the options to `configure', and exit.\n\n`--version'\n`-V'\n     Print the version of Autoconf used to generate the `configure'\n     script, and exit.\n\n`--cache-file=FILE'\n     Enable the cache: use and save the results of the tests in FILE,\n     traditionally `config.cache'.  FILE defaults to `/dev/null' to\n     disable caching.\n\n`--config-cache'\n`-C'\n     Alias for `--cache-file=config.cache'.\n\n`--quiet'\n`--silent'\n`-q'\n     Do not print messages saying which checks are being made.  To\n     suppress all normal output, redirect it to `/dev/null' (any error\n     messages will still be shown).\n\n`--srcdir=DIR'\n     Look for the package's source code in directory DIR.  Usually\n     `configure' can determine that directory automatically.\n\n`configure' also accepts some other, not widely useful, options.  Run\n`configure --help' for more details.\n"
  },
  {
    "path": "distro/google-perftools-1.7/Makefile.am",
    "content": "## Process this file with automake to produce Makefile.in\n\n# Note: for every library we create, we're explicit about what symbols\n# we export.  In order to avoid complications with C++ mangling, we always\n# use the regexp for of specifying symbols.\n\n# Make sure that when we re-make ./configure, we get the macros we need\nACLOCAL_AMFLAGS = -I m4\n\n# This is so we can #include <google/foo>\nAM_CPPFLAGS = -I$(top_srcdir)/src\n\nif !WITH_STACK_TRACE\nAM_CPPFLAGS += -DNO_TCMALLOC_SAMPLES\nendif !WITH_STACK_TRACE\n\n# This is mostly based on configure options\nAM_CXXFLAGS =\n\n# These are good warnings to turn on by default.  We also tell gcc\n# that malloc, free, realloc, mmap, etc. are not builtins (these flags\n# are supported since gcc 3.1.1).  gcc doesn't think most of them are\n# builtins now in any case, but it's best to be explicit in case that\n# changes one day.  gcc ignores functions it doesn't understand.\nif GCC\nAM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare \\\n               -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc \\\n               -fno-builtin-calloc -fno-builtin-cfree \\\n               -fno-builtin-memalign -fno-builtin-posix_memalign \\\n               -fno-builtin-valloc -fno-builtin-pvalloc\nendif GCC\n\n# The -no-undefined flag allows libtool to generate shared libraries for\n# Cygwin and MinGW.  LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.\nAM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)\n\n# We know our low-level code cannot trigger an exception.  On some\n# systems, such as cygwin, it would be disastrous if they did, because\n# the exception handler might call malloc!  If our low-level routines\n# raised an exception within the malloc, they'd deadlock.  Luckily,\n# we control all this code, and do not need exceptions for it.\nif GCC\nNO_EXCEPTIONS = -fno-exceptions\nelse !GCC\nNO_EXCEPTIONS =\nendif !GCC\n\n# These are x86-specific, having to do with frame-pointers.  In\n# particular, some x86_64 systems do not insert frame pointers by\n# default (all i386 systems that I know of, do.  I don't know about\n# non-x86 chips).  We need to tell perftools what to do about that.\nif X86_64_AND_NO_FP_BY_DEFAULT\nif ENABLE_FRAME_POINTERS\nAM_CXXFLAGS += -fno-omit-frame-pointer\nelse\n  # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS),\n  #                 before setting this.\nAM_CXXFLAGS += -DNO_FRAME_POINTER\nendif !ENABLE_FRAME_POINTERS\nendif X86_64_AND_NO_FP_BY_DEFAULT\n\n# For windows systems (at least, mingw), we need to tell all our\n# tests to link in libtcmalloc using -u.  This is because libtcmalloc\n# accomplishes its tasks via patching, leaving no work for the linker\n# to identify, so the linker will ignore libtcmalloc by default unless\n# we explicitly create a dependency via -u.\nTCMALLOC_FLAGS =\nif MINGW\nTCMALLOC_FLAGS += -Wl,-u__tcmalloc\nendif MINGW\n\n# If we have objcopy, make malloc/free/etc weak symbols.  That way folks\n# can override our malloc if they want to (they can still use tc_malloc).\n# Note: the weird-looking symbols are the c++ memory functions:\n# (in order) new, new(nothrow), new[], new[](nothrow), delete, delete[]\n# In theory this will break if mangling changes, but that seems pretty\n# unlikely at this point.  Just in case, I throw in versions with an\n# extra underscore as well, which may help on OS X.\nif HAVE_OBJCOPY_WEAKEN\nWEAKEN = $(OBJCOPY) -W malloc -W free -W realloc -W calloc -W cfree \\\n         -W memalign -W posix_memalign -W valloc -W pvalloc \\\n         -W malloc_stats -W mallopt -W mallinfo \\\n         -W _Znwm -W _ZnwmRKSt9nothrow_t -W _Znam -W _ZnamRKSt9nothrow_t \\\n         -W _ZdlPv -W _ZdaPv \\\n         -W __Znwm -W __ZnwmRKSt9nothrow_t -W __Znam -W __ZnamRKSt9nothrow_t \\\n         -W __ZdlPv -W __ZdaPv\nelse\nWEAKEN = :\nendif !HAVE_OBJCOPY_WEAKEN\n\nLIBS_TO_WEAKEN =\n\ngoogleincludedir = $(includedir)/google\n# The .h files you want to install (that is, .h files that people\n# who install this package can include in their own applications.)\n# We'll add to this later, on a library-by-library basis\ngoogleinclude_HEADERS =\n# tcmalloc.h is a special case, because it's a .h.in file\nnodist_googleinclude_HEADERS = src/google/tcmalloc.h\nnoinst_HEADERS = src/google/tcmalloc.h.in\n\ndocdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)\n# This is for HTML and other documentation you want to install.\n# Add your documentation files (in doc/) in addition to these\n# top-level boilerplate files.  Also add a TODO file if you have one.\n# We'll add to this later, on a library-by-library basis\ndist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README_windows.txt \\\n                TODO\n\n# The libraries (.so's) you want to install\n# We'll add to this later, on a library-by-library basis\nlib_LTLIBRARIES =\n# This is for 'convenience libraries' -- basically just a container for sources\nnoinst_LTLIBRARIES =\n## The location of the windows project file for each binary we make\nWINDOWS_PROJECTS = google-perftools.sln\n\n# unittests you want to run when people type 'make check'.\n# Note: tests cannot take any arguments!\n# In theory, unittests that are scripts should be added to check_SCRIPTS\n# instead.  But check_SCRIPTS is definitely a second-class testing mechanims:\n# it don't get TESTS_ENVIRONMENT, and it doesn't get success/failure counting\n# (in fact, a script failure aborts all the rest of the tests, even with -k).\n# So, for scripts, we add the script to tests, and also put in an empty\n# rule so automake doesn't try to build the script as a C binary.\nTESTS =\n# TESTS_ENVIRONMENT sets environment variables for when you run unittest.\n# We always get \"srcdir\" set for free.\n# We'll add to this later, on a library-by-library basis.\nTESTS_ENVIRONMENT =\n# All script tests should be added here\nnoinst_SCRIPTS =\n# If your test calls another program that, like the test itself, shouldn't\n# be installed, add it here.  (Stuff in TESTS is automatically added later).\nnoinst_PROGRAMS =\n\n# Binaries we might build that should be installed\nbin_PROGRAMS =\n\n# This is my own var, used for extra libraries I make that I need installed\nEXTRA_INSTALL =\n\n## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS\n\ndist_doc_DATA += doc/index.html doc/designstyle.css\n\n\n### ------- library routines, in src/base\n\n# This is a 'convenience library' -- it's not actually installed or anything\nLOGGING_INCLUDES = src/base/logging.h \\\n                   src/base/commandlineflags.h \\\n                   src/base/basictypes.h \\\n                   src/base/dynamic_annotations.h \\\n                   src/third_party/valgrind.h\nnoinst_LTLIBRARIES += liblogging.la\nliblogging_la_SOURCES = src/base/logging.cc \\\n                        src/base/dynamic_annotations.c \\\n                        $(LOGGING_INCLUDES)\n\nSYSINFO_INCLUDES = src/base/sysinfo.h \\\n                   src/base/logging.h \\\n                   src/base/commandlineflags.h \\\n                   src/base/cycleclock.h \\\n                   src/base/basictypes.h\nnoinst_LTLIBRARIES += libsysinfo.la\nlibsysinfo_la_SOURCES = src/base/sysinfo.cc \\\n                        $(SYSINFO_INCLUDES)\nlibsysinfo_la_LIBADD = $(NANOSLEEP_LIBS)\n\n# For MinGW, we use also have to use libwindows Luckily, we need the\n# windows.a library in exactly the same place we need spinlock.a\n# (pretty much everywhere), so we can use the same variable name for\n# each.  We can also optimize the MinGW rule a bit by leaving out\n# files we know aren't used on windows, such as\n# atomicops-internals-x86.cc.  libwindows also obsoletes the need for\n# other files like system_alloc.cc.\nif MINGW\nWINDOWS_INCLUDES = src/windows/port.h \\\n                   src/windows/mingw.h \\\n                   src/windows/mini_disassembler.h \\\n                   src/windows/mini_disassembler_types.h \\\n                   src/windows/preamble_patcher.h\nnoinst_LTLIBRARIES += libwindows.la\nlibwindows_la_SOURCES = $(WINDOWS_INCLUDES) \\\n                        src/windows/port.cc \\\n                        src/windows/ia32_modrm_map.cc \\\n                        src/windows/ia32_opcode_map.cc \\\n                        src/windows/mini_disassembler.cc \\\n                        src/windows/patch_functions.cc \\\n                        src/windows/preamble_patcher.cc \\\n                        src/windows/preamble_patcher_with_stub.cc\n# patch_functions.cc uses Psapi.lib.  MSVC has a #pragma for that, but not us.\nlibwindows_la_LIBADD = -lPsapi\n\nSPINLOCK_INCLUDES = src/base/spinlock.h \\\n                    src/base/spinlock_internal.h \\\n                    src/base/spinlock_win32-inl.h \\\n                    src/base/spinlock_linux-inl.h \\\n                    src/base/spinlock_posix-inl.h \\\n                    src/base/synchronization_profiling.h \\\n                    src/base/atomicops-internals-macosx.h \\\n                    src/base/atomicops-internals-linuxppc.h \\\n                    src/base/atomicops-internals-arm-gcc.h \\\n                    src/base/atomicops-internals-x86-msvc.h \\\n                    src/base/atomicops-internals-x86.h\nnoinst_LTLIBRARIES += libspinlock.la\nlibspinlock_la_SOURCES = src/base/spinlock.cc \\\n                         src/base/spinlock_internal.cc \\\n                         $(SPINLOCK_INCLUDES)\n\nLIBSPINLOCK = libwindows.la libspinlock.la libsysinfo.la liblogging.la\n\n# We also need to tell mingw that sysinfo.cc needs shlwapi.lib.\n# (We do this via a #pragma for msvc, but need to do it here for mingw).\nlibsysinfo_la_LIBADD += -lshlwapi\n\n# patch_functions.cc #includes tcmalloc.cc, so no need to link it in.\nTCMALLOC_CC =\n# windows has its own system for threads and system memory allocation.\nMAYBE_THREADS_CC =\nSYSTEM_ALLOC_CC =\nelse !MINGW\n# spinlock is the only code that uses atomicops.\nSPINLOCK_INCLUDES = src/base/spinlock.h \\\n                    src/base/spinlock_internal.h \\\n                    src/base/atomicops.h \\\n                    src/base/atomicops-internals-macosx.h \\\n                    src/base/atomicops-internals-linuxppc.h \\\n                    src/base/atomicops-internals-x86-msvc.h \\\n                    src/base/atomicops-internals-x86.h\n\nnoinst_LTLIBRARIES += libspinlock.la\nlibspinlock_la_SOURCES = src/base/spinlock.cc \\\n                         src/base/spinlock_internal.cc \\\n                         src/base/atomicops-internals-x86.cc \\\n                         $(SPINLOCK_INCLUDES)\nlibspinlock_la_LIBADD = $(NANOSLEEP_LIBS)\n# spinlock also needs NumCPUs, from libsysinfo, which in turn needs liblogging\nLIBSPINLOCK = libspinlock.la libsysinfo.la liblogging.la\n\nTCMALLOC_CC = src/tcmalloc.cc\nMAYBE_THREADS_CC = src/maybe_threads.cc\nSYSTEM_ALLOC_CC = src/system-alloc.cc\nendif !MINGW\n\n### Unittests\nTESTS += low_level_alloc_unittest\nWINDOWS_PROJECTS += vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcproj\nLOW_LEVEL_ALLOC_UNITTEST_INCLUDES = src/base/low_level_alloc.h \\\n                                    src/base/basictypes.h \\\n                                    src/google/malloc_hook.h \\\n                                    src/google/malloc_hook_c.h \\\n                                    src/malloc_hook-inl.h \\\n                                    $(SPINLOCK_INCLUDES) \\\n                                    $(LOGGING_INCLUDES)\nlow_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \\\n                                   src/malloc_hook.cc \\\n                                   src/tests/low_level_alloc_unittest.cc \\\n                                   $(LOW_LEVEL_ALLOC_UNITTEST_INCLUDES)\n# By default, MallocHook takes stack traces for use by the heap-checker.\n# We don't need that functionality here, so we turn it off to reduce deps.\nlow_level_alloc_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES\nlow_level_alloc_unittest_LDADD = $(LIBSPINLOCK)\n\nTESTS += atomicops_unittest\nATOMICOPS_UNITTEST_INCLUDES = src/base/atomicops.h \\\n                              src/base/atomicops-internals-macosx.h \\\n                              src/base/atomicops-internals-x86-msvc.h \\\n                              src/base/atomicops-internals-x86.h \\\n                              $(LOGGING_INCLUDES)\natomicops_unittest_SOURCES = src/tests/atomicops_unittest.cc \\\n                             $(ATOMICOPS_UNITTEST_INCLUDES)\natomicops_unittest_LDADD = $(LIBSPINLOCK)\n\n\n### ------- stack trace\n\nif WITH_STACK_TRACE\n\n### The header files we use.  We divide into categories based on directory\nS_STACKTRACE_INCLUDES = src/stacktrace_config.h \\\n                        src/stacktrace_generic-inl.h \\\n\t\t\tsrc/stacktrace_libunwind-inl.h \\\n\t\t\tsrc/stacktrace_powerpc-inl.h \\\n\t\t\tsrc/stacktrace_x86_64-inl.h \\\n\t\t\tsrc/stacktrace_x86-inl.h \\\n\t\t\tsrc/stacktrace_win32-inl.h \\\n                        src/base/vdso_support.h\nSG_STACKTRACE_INCLUDES = src/google/stacktrace.h\nSTACKTRACE_INCLUDES = $(S_STACKTRACE_INCLUDES) $(SG_STACKTRACE_INCLUDES)\ngoogleinclude_HEADERS += $(SG_STACKTRACE_INCLUDES)\n\n### Making the library\nnoinst_LTLIBRARIES += libstacktrace.la\nlibstacktrace_la_SOURCES = src/stacktrace.cc \\\n                           src/base/vdso_support.cc \\\n                           $(STACKTRACE_INCLUDES)\nlibstacktrace_la_LIBADD = $(UNWIND_LIBS) $(LIBSPINLOCK)\nSTACKTRACE_SYMBOLS = '(GetStackTrace|GetStackFrames|GetStackTraceWithContext|GetStackFramesWithContext)'\nlibstacktrace_la_LDFLAGS = -export-symbols-regex $(STACKTRACE_SYMBOLS)\n\n### Unittests\nTESTS += stacktrace_unittest\nSTACKTRACE_UNITTEST_INLCUDES = src/config_for_unittests.h \\\n                               src/base/commandlineflags.h \\\n                               $(STACKTRACE_INCLUDES) \\\n                               $(LOGGING_INCLUDES)\nstacktrace_unittest_SOURCES = src/tests/stacktrace_unittest.cc \\\n                              $(STACKTRACE_UNITTEST_INLCUDES)\nstacktrace_unittest_LDADD = libstacktrace.la liblogging.la\n\n### Documentation\ndist_doc_DATA +=\n\nendif WITH_STACK_TRACE\n\n### ------- pprof\n\n# If we are not compiling with stacktrace support, pprof is worthless\nif WITH_STACK_TRACE\n\nbin_SCRIPTS = src/pprof\n\n### Unittests\n\ncheck_SCRIPTS = pprof_unittest\npprof_unittest: $(top_srcdir)/src/pprof\n\t$(top_srcdir)/src/pprof -test\n\n# Let unittests find pprof if they need to run it\nTESTS_ENVIRONMENT += PPROF_PATH=$(top_srcdir)/src/pprof\n\n### Documentation\ndist_man_MANS = doc/pprof.1\ndist_doc_DATA += doc/pprof_remote_servers.html\n\n# On MSVC, we need our own versions of addr2line and nm to work with pprof.\nWINDOWS_PROJECTS += vsprojects/nm-pdb/nm-pdb.vcproj\nWINDOWS_PROJECTS += vsprojects/addr2line-pdb/addr2line-pdb.vcproj\n# This is a slight abuse of WINDOWS_PROJECTS, but not much\nWINDOWS_PROJECTS += src/windows/nm-pdb.c \\\n                    src/windows/addr2line-pdb.c\n\nendif WITH_STACK_TRACE\n\n### ------- tcmalloc_minimal (thread-caching malloc)\n\n### The header files we use.  We divide into categories based on directory\nS_TCMALLOC_MINIMAL_INCLUDES = src/common.h \\\n                              src/internal_logging.h \\\n                              src/system-alloc.h \\\n                              src/packed-cache-inl.h \\\n                              $(SPINLOCK_INCLUDES) \\\n                              src/tcmalloc_guard.h \\\n                              src/base/commandlineflags.h \\\n                              src/base/basictypes.h \\\n                              src/pagemap.h \\\n                              src/sampler.h \\\n                              src/central_freelist.h \\\n                              src/linked_list.h \\\n                              src/page_heap.h \\\n                              src/page_heap_allocator.h \\\n                              src/span.h \\\n                              src/static_vars.h \\\n                              src/symbolize.h \\\n                              src/thread_cache.h \\\n                              src/stack_trace_table.h \\\n                              src/base/thread_annotations.h \\\n                              src/malloc_hook-inl.h \\\n                              src/maybe_threads.h\nSG_TCMALLOC_MINIMAL_INCLUDES = src/google/malloc_hook.h \\\n                               src/google/malloc_hook_c.h \\\n                               src/google/malloc_extension.h \\\n                               src/google/malloc_extension_c.h \\\n                               src/google/stacktrace.h\nTCMALLOC_MINIMAL_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) $(SG_TCMALLOC_MINIMAL_INCLUDES)\ngoogleinclude_HEADERS += $(SG_TCMALLOC_MINIMAL_INCLUDES)\n\n### Making the library\n\n# As we describe at the top of this file, we want to turn off exceptions\n# for all files in this library -- except tcmalloc.cc which needs them\n# to fulfill its API.  Automake doesn't allow per-file CXXFLAGS, so we need\n# to separate into two libraries.\nnoinst_LTLIBRARIES += libtcmalloc_minimal_internal.la\nlibtcmalloc_minimal_internal_la_SOURCES = src/common.cc \\\n                                          src/internal_logging.cc \\\n                                          $(SYSTEM_ALLOC_CC) \\\n                                          src/memfs_malloc.cc \\\n                                          src/central_freelist.cc \\\n                                          src/page_heap.cc \\\n                                          src/sampler.cc \\\n                                          src/span.cc \\\n                                          src/stack_trace_table.cc \\\n                                          src/static_vars.cc \\\n                                          src/symbolize.cc \\\n                                          src/thread_cache.cc \\\n                                          src/malloc_hook.cc \\\n                                          src/malloc_extension.cc \\\n                                          $(MAYBE_THREADS_CC) \\\n                                          $(TCMALLOC_MINIMAL_INCLUDES)\n# We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal.\nlibtcmalloc_minimal_internal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \\\n                                           -DNO_HEAP_CHECK \\\n                                           $(PTHREAD_CFLAGS) -DNDEBUG \\\n                                           $(AM_CXXFLAGS) $(NO_EXCEPTIONS)\nlibtcmalloc_minimal_internal_la_LDFLAGS = $(PTHREAD_CFLAGS)\nlibtcmalloc_minimal_internal_la_LIBADD = $(PTHREAD_LIBS) $(LIBSPINLOCK)\n\nlib_LTLIBRARIES += libtcmalloc_minimal.la\nWINDOWS_PROJECTS += vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj\nlibtcmalloc_minimal_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_MINIMAL_INCLUDES)\nlibtcmalloc_minimal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \\\n                                  $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS)\n# -version-info gets passed to libtool\nlibtcmalloc_minimal_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@\nlibtcmalloc_minimal_la_LIBADD = libtcmalloc_minimal_internal.la $(PTHREAD_LIBS)\n\n# For windows, we're playing around with trying to do some stacktrace\n# support even with libtcmalloc_minimal.  For everyone else, though,\n# we turn off all stack-trace activity for libtcmalloc_minimal.\n# TODO(csilvers): when we're done experimenting, do something principled here\nif MINGW\nLIBTCMALLOC_MINIMAL = libtcmalloc_minimal.la libstacktrace.la\nelse !MINGW\nLIBTCMALLOC_MINIMAL = libtcmalloc_minimal.la\nendif !MINGW\n\nLIBS_TO_WEAKEN += libtcmalloc_minimal.la\n\n### Unittests\n\n# Commented out for the moment because malloc(very_big_num) is broken in\n# standard libc!  At least, in some situations, some of the time.\n## TESTS += malloc_unittest\n## MALLOC_UNITEST_INCLUDES = src/google/malloc_extension.h \\\n##                           src/google/malloc_hook.h \\\n##                           src/google/malloc_hook_c.h \\\n##                           src/malloc_hook-inl.h \\\n##                           src/base/basictypes.h \\\n##                           src/maybe_threads.h\n## malloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n##                           src/malloc_hook.cc \\\n##                           src/malloc_extension.cc \\\n##                           $(MAYBE_THREADS_CC) \\\n##                           $(MALLOC_UNITTEST_INCLUDES)\n## malloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n## malloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\n## malloc_unittest_LDADD = $(PTHREAD_LIBS)\n\nTESTS += tcmalloc_minimal_unittest\nWINDOWS_PROJECTS += vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcproj\nWINDOWS_PROJECTS += vsprojects/tmu-static/tmu-static.vcproj\ntcmalloc_minimal_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n                                    src/tests/testutil.h src/tests/testutil.cc \\\n                                    $(TCMALLOC_UNITTEST_INCLUDES)\ntcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\ntcmalloc_minimal_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) \\\n                                  liblogging.la $(PTHREAD_LIBS)\n\nTESTS += tcmalloc_minimal_large_unittest\nWINDOWS_PROJECTS += vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcproj\ntcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc\ntcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\ntcmalloc_minimal_large_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\n# This tests it works to LD_PRELOAD libtcmalloc (tests maybe_threads.cc)\n# In theory this should work under mingw, but mingw has trouble running\n# shell scripts that end in .exe.  And it doesn't seem to build shared\n# libraries anyway (so can't be LD_PRELOADed) -- in fact, anybody who\n# chooses not to build shared libraries won't be able to run this test.\n# TODO(csilvers): figure out how to nix \".exe\" or otherwise work under mingw\nif !MINGW\nif !ENABLE_STATIC\nTESTS += maybe_threads_unittest.sh$(EXEEXT)\nmaybe_threads_unittest_sh_SOURCES = src/tests/maybe_threads_unittest.sh\nnoinst_SCRIPTS += $(maybe_threads_unittest_sh_SOURCES)\n# This script preloads libtcmalloc, and calls two other binaries as well\n# TODO(csilvers): replace by 'if ! cmp $^ $@ >/dev/null 2>&; then ...; fi'\nmaybe_threads_unittest.sh$(EXEEXT): $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) \\\n                           $(LIBTCMALLOC_MINIMAL) \\\n                           low_level_alloc_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) $@\nendif !ENABLE_STATIC\nendif !MINGW\n\n# These all tests components of tcmalloc_minimal\n\nTESTS += addressmap_unittest\nWINDOWS_PROJECTS += vsprojects/addressmap_unittest/addressmap_unittest.vcproj\nADDRESSMAP_UNITTEST_INCLUDES = src/addressmap-inl.h \\\n                               src/base/commandlineflags.h \\\n                               $(LOGGING_INCLUDES)\naddressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \\\n                              $(ADDRESSMAP_UNITTEST_INCLUDES)\nif MINGW\naddressmap_unittest_SOURCES += src/windows/port.h src/windows/port.cc\nendif MINGW\naddressmap_unittest_CXXFLAGS = -g $(AM_CXXFLAGS)\naddressmap_unittest_LDADD = liblogging.la\n\nif !MINGW\nTESTS += system_alloc_unittest\nsystem_alloc_unittest_SOURCES = src/config_for_unittests.h \\\n                                src/tests/system-alloc_unittest.cc\nsystem_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nsystem_alloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nsystem_alloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nendif !MINGW\n\nTESTS += packed_cache_test\nWINDOWS_PROJECTS += vsprojects/packed-cache_test/packed-cache_test.vcproj\npacked_cache_test_SOURCES = src/tests/packed-cache_test.cc\npacked_cache_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\npacked_cache_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\npacked_cache_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += frag_unittest\nWINDOWS_PROJECTS += vsprojects/frag_unittest/frag_unittest.vcproj\nfrag_unittest_SOURCES = src/tests/frag_unittest.cc src/config_for_unittests.h\nfrag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nfrag_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nfrag_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += markidle_unittest\nWINDOWS_PROJECTS += vsprojects/markidle_unittest/markidle_unittest.vcproj\nmarkidle_unittest_SOURCES = src/tests/markidle_unittest.cc \\\n                            src/config_for_unittests.h \\\n                            src/tests/testutil.h src/tests/testutil.cc\nmarkidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nmarkidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nmarkidle_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += malloc_extension_test\nWINDOWS_PROJECTS += vsprojects/malloc_extension_test/malloc_extension_test.vcproj\nmalloc_extension_test_SOURCES = src/tests/malloc_extension_test.cc \\\n                                src/config_for_unittests.h \\\n                                src/base/logging.h \\\n                                src/google/malloc_extension.h \\\n                                src/google/malloc_extension_c.h\nmalloc_extension_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nmalloc_extension_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nmalloc_extension_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\n# This doesn't work with static linkage, because libtcmalloc.a isn't\n# happy with C linkage (it misses the stdc++ library).  Likewise with\n# mingw, which links foo.a even though it doesn't set ENABLE_STATIC.\n# TODO(csilvers): set enable_static=true in configure.ac:36?\nif !MINGW\nif !ENABLE_STATIC\nTESTS += malloc_extension_c_test\nmalloc_extension_c_test_SOURCES = src/tests/malloc_extension_c_test.c \\\n                                  src/google/malloc_extension.h \\\n                                  src/google/malloc_extension_c.h\nmalloc_extension_c_test_CFLAGS = $(PTHREAD_CFLAGS) $(AM_CFLAGS)\n# -ansi here is just to help ensure the code is bog-standard C.\nif GCC\nmalloc_extension_c_test_CFLAGS += -ansi\nendif GCC\nmalloc_extension_c_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nmalloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nendif !ENABLE_STATIC\nendif !MINGW\n\nif !MINGW\nTESTS += memalign_unittest\nmemalign_unittest_SOURCES = src/tests/memalign_unittest.cc \\\n                            src/tcmalloc.h \\\n                            src/config_for_unittests.h \\\n                            src/tests/testutil.h src/tests/testutil.cc\nmemalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nmemalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nmemalign_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nendif !MINGW\n\nTESTS += page_heap_test\nWINDOWS_PROJECTS += vsprojects/page_heap_test/page_heap_test.vcproj\npage_heap_test_SOURCES = src/tests/page_heap_test.cc \\\n                         src/config_for_unittests.h \\\n                         src/base/logging.h \\\n                         src/common.h \\\n                         src/page_heap.h\npage_heap_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\npage_heap_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\npage_heap_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += pagemap_unittest\nWINDOWS_PROJECTS += vsprojects/pagemap_unittest/pagemap_unittest.vcproj\npagemap_unittest_SOURCES = src/tests/pagemap_unittest.cc \\\n                           src/config_for_unittests.h \\\n                           src/base/logging.h \\\n                           src/pagemap.h\npagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\npagemap_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\npagemap_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += realloc_unittest\nWINDOWS_PROJECTS += vsprojects/realloc_unittest/realloc_unittest.vcproj\nrealloc_unittest_SOURCES = src/tests/realloc_unittest.cc \\\n                           src/config_for_unittests.h \\\n                           src/base/logging.h\nrealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nrealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nrealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += stack_trace_table_test\nWINDOWS_PROJECTS += vsprojects/stack_trace_table_test/stack_trace_table_test.vcproj\nstack_trace_table_test_SOURCES = src/tests/stack_trace_table_test.cc \\\n                                 src/config_for_unittests.h\nstack_trace_table_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nstack_trace_table_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nstack_trace_table_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\nTESTS += thread_dealloc_unittest\nWINDOWS_PROJECTS += vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcproj\nthread_dealloc_unittest_SOURCES = src/tests/thread_dealloc_unittest.cc \\\n                                  src/config_for_unittests.h \\\n                                  src/tests/testutil.h src/tests/testutil.cc\nthread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nthread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nthread_dealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n\n### Documentation\ndist_doc_DATA += doc/tcmalloc.html \\\n                 doc/overview.gif \\\n                 doc/pageheap.gif \\\n                 doc/spanmap.gif \\\n                 doc/threadheap.gif \\\n                 doc/t-test1.times.txt \\\n                 doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.128.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.256.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.512.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.64.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png \t\\\n                 doc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png \t\\\n                 doc/tcmalloc-opspersec.vs.size.1.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.12.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.16.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.2.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.20.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.3.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.4.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.5.threads.png \t\t\\\n                 doc/tcmalloc-opspersec.vs.size.8.threads.png\n\n# I don't know how to say \"distribute the .dot files but don't install them\";\n# noinst doesn't seem to work with data.  I separate them out anyway, in case\n# one day we figure it out.  Regardless, installing the dot files isn't the\n# end of the world.\ndist_doc_DATA += doc/overview.dot \\\n                 doc/pageheap.dot \\\n                 doc/spanmap.dot \\\n                 doc/threadheap.dot\n\n\n### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation)\n\n# Like tcmalloc.cc, debugallocation.cc needs exceptions to fulfill its\n# API.  Luckily, we can reuse everything else from tcmalloc_minimal.\n\nif WITH_DEBUGALLOC\n\nlib_LTLIBRARIES += libtcmalloc_minimal_debug.la\nlibtcmalloc_minimal_debug_la_SOURCES = src/debugallocation.cc \\\n                                       $(TCMALLOC_MINIMAL_INCLUDES)\nlibtcmalloc_minimal_debug_la_CXXFLAGS = $(libtcmalloc_minimal_la_CXXFLAGS) \\\n                                        -DTCMALLOC_FOR_DEBUGALLOCATION\n# version_info gets passed to libtool\nlibtcmalloc_minimal_debug_la_LDFLAGS = $(libtcmalloc_minimal_la_LDFLAGS) \\\n                                       -version-info @TCMALLOC_SO_VERSION@\nlibtcmalloc_minimal_debug_la_LIBADD = $(libtcmalloc_minimal_la_LIBADD)\n\nLIBS_TO_WEAKEN += libtcmalloc_minimal_debug.la\n\n### Unittests\n\nTESTS += tcmalloc_minimal_debug_unittest\ntcmalloc_minimal_debug_unittest_SOURCES = $(tcmalloc_minimal_unittest_SOURCES)\ntcmalloc_minimal_debug_unittest_CXXFLAGS = $(tcmalloc_minimal_unittest_CXXFLAGS) \\\n                                           -DDEBUGALLOCATION\ntcmalloc_minimal_debug_unittest_LDFLAGS = $(tcmalloc_minimal_unittest_LDFLAGS)\ntcmalloc_minimal_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n\nTESTS += malloc_extension_debug_test\nmalloc_extension_debug_test_SOURCES = $(malloc_extension_test_SOURCES)\nmalloc_extension_debug_test_CXXFLAGS = $(malloc_extension_test_CXXFLAGS)\nmalloc_extension_debug_test_LDFLAGS = $(malloc_extension_test_LDFLAGS)\nmalloc_extension_debug_test_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n\nTESTS += memalign_debug_unittest\nmemalign_debug_unittest_SOURCES = $(memalign_unittest_SOURCES)\nmemalign_debug_unittest_CXXFLAGS = $(memalign_unittest_CXXFLAGS)\nmemalign_debug_unittest_LDFLAGS = $(memalign_unittest_LDFLAGS)\nmemalign_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n\nTESTS += realloc_debug_unittest\nrealloc_debug_unittest_SOURCES = $(realloc_unittest_SOURCES)\nrealloc_debug_unittest_CXXFLAGS = $(realloc_unittest_CXXFLAGS)\nrealloc_debug_unittest_LDFLAGS = $(realloc_unittest_LDFLAGS)\nrealloc_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n\nTESTS += debugallocation_test.sh$(EXEEXT)\ndebugallocation_test_sh_SOURCES = src/tests/debugallocation_test.sh\nnoinst_SCRIPTS += $(debugallocation_test_sh_SOURCES)\ndebugallocation_test.sh$(EXEEXT): $(top_srcdir)/$(debugallocation_test_sh_SOURCES) \\\n                                  debugallocation_test\n\trm -f $@\n\tcp -p $(top_srcdir)/$(debugallocation_test_sh_SOURCES) $@\n\n# This is the sub-program used by debugallocation_test.sh\nnoinst_PROGRAMS += debugallocation_test\ndebugallocation_test_SOURCES = src/tests/debugallocation_test.cc\ndebugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ndebugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\ndebugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n\nendif WITH_DEBUGALLOC\n\n\n### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)\n\nif WITH_HEAP_PROFILER_OR_CHECKER\n\n### The header files we use.  We divide into categories based on directory\nS_TCMALLOC_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) \\\n                      $(LOGGING_INCLUDES) \\\n                      src/addressmap-inl.h \\\n                      src/raw_printer.h \\\n                      src/base/elfcore.h \\\n                      src/base/googleinit.h \\\n                      src/base/linux_syscall_support.h \\\n                      src/base/linuxthreads.h \\\n                      src/base/stl_allocator.h \\\n                      src/base/sysinfo.h \\\n                      src/base/thread_lister.h \\\n                      src/heap-profile-table.h\nSG_TCMALLOC_INCLUDES = $(SG_TCMALLOC_MINIMAL_INCLUDES) \\\n                       src/google/heap-profiler.h \\\n                       src/google/heap-checker.h\nTCMALLOC_INCLUDES = $(S_TCMALLOC_INCLUDES) $(SG_TCMALLOC_INCLUDES)\ngoogleinclude_HEADERS += $(SG_TCMALLOC_INCLUDES)\n\n### Making the library\n\n# As we describe at the top of this file, we want to turn off exceptions\n# for all files in this library -- except tcmalloc.cc which needs them\n# to fulfill its API.  Automake doesn't allow per-file CXXFLAGS, so we need\n# to separate into two libraries.\nnoinst_LTLIBRARIES += libtcmalloc_internal.la\nlibtcmalloc_internal_la_SOURCES = $(libtcmalloc_minimal_internal_la_SOURCES) \\\n                                  $(TCMALLOC_INCLUDES) \\\n                                  src/base/low_level_alloc.cc \\\n                                  src/heap-profile-table.cc \\\n                                  src/heap-profiler.cc \\\n                                  src/raw_printer.cc \\\n                                  src/memory_region_map.cc\nlibtcmalloc_internal_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG \\\n                                   $(AM_CXXFLAGS) $(NO_EXCEPTIONS)\nlibtcmalloc_internal_la_LDFLAGS = $(PTHREAD_CFLAGS)\nlibtcmalloc_internal_la_LIBADD = libstacktrace.la $(PTHREAD_LIBS)\n\nlib_LTLIBRARIES += libtcmalloc.la\nlibtcmalloc_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_INCLUDES)\nlibtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS)\nlibtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@\nlibtcmalloc_la_LIBADD = libtcmalloc_internal.la $(PTHREAD_LIBS)\n\nif WITH_HEAP_CHECKER\n# heap-checker-bcad is last, in hopes its global ctor will run first.\n# (Note this is added to libtcmalloc.la, not libtcmalloc_internal.la,\n# but that's ok; the internal/external distinction is only useful for\n# cygwin, and cygwin doesn't use HEAP_CHECKER anyway.)\nHEAP_CHECKER_SOURCES = src/base/thread_lister.c \\\n                       src/base/linuxthreads.cc \\\n                       src/heap-checker.cc \\\n                       src/heap-checker-bcad.cc\nlibtcmalloc_la_SOURCES += $(HEAP_CHECKER_SOURCES)\nelse !WITH_HEAP_CHECKER\nHEAP_CHECKER_SOURCES =\nlibtcmalloc_internal_la_CXXFLAGS += -DNO_HEAP_CHECK\nlibtcmalloc_la_CXXFLAGS += -DNO_HEAP_CHECK\nendif !WITH_HEAP_CHECKER\n\nLIBTCMALLOC = libtcmalloc.la\n\nLIBS_TO_WEAKEN += libtcmalloc.la\n\n### Unittests\n\nTESTS += tcmalloc_unittest\nTCMALLOC_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n                             src/google/malloc_extension.h\ntcmalloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n                            src/tcmalloc.h \\\n                            src/tests/testutil.h src/tests/testutil.cc \\\n                            $(TCMALLOC_UNITTEST_INCLUDES)\ntcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\ntcmalloc_unittest_LDADD = $(LIBTCMALLOC) liblogging.la $(PTHREAD_LIBS)\n\n# This makes sure it's safe to link in both tcmalloc and\n# tcmalloc_minimal.  (One would never do this on purpose, but perhaps\n# by accident...)  When we can compile libprofiler, we also link it in\n# to make sure that works too.\n\nTESTS += tcmalloc_both_unittest\ntcmalloc_both_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n                                 src/tests/testutil.h src/tests/testutil.cc \\\n                                 $(TCMALLOC_UNITTEST_INCLUDES)\ntcmalloc_both_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_both_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nif WITH_CPU_PROFILER\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\ntcmalloc_both_unittest_LDADD = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \\\n                               libprofiler.la liblogging.la $(PTHREAD_LIBS)\nelse\ntcmalloc_both_unittest_LDADD = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \\\n                               liblogging.la $(PTHREAD_LIBS)\nendif !WITH_CPU_PROFILER\n\nTESTS += tcmalloc_large_unittest\ntcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc\ntcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\ntcmalloc_large_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n\nTESTS += raw_printer_test\nraw_printer_test_SOURCES = src/tests/raw_printer_test.cc\nraw_printer_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nraw_printer_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nraw_printer_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n\n# sampler_test and sampling_test both require sampling to be turned\n# on, which it's not by default.  Use the \"standard\" value of 2^19.\nTESTS_ENVIRONMENT += TCMALLOC_SAMPLE_PARAMETER=524288\n\nTESTS += sampler_test\nWINDOWS_PROJECTS += vsprojects/sampler_test/sampler_test.vcproj\nsampler_test_SOURCES = src/tests/sampler_test.cc \\\n                       src/config_for_unittests.h\nsampler_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nsampler_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nsampler_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS) -lm\n\n\n# These unittests often need to run binaries.  They're in the current dir\nTESTS_ENVIRONMENT += BINDIR=.\nTESTS_ENVIRONMENT += TMPDIR=/tmp/perftools\n\nTESTS += sampling_test.sh$(EXEEXT)\nsampling_test_sh_SOURCES = src/tests/sampling_test.sh\nnoinst_SCRIPTS += $(sampling_test_sh_SOURCES)\nsampling_test.sh$(EXEEXT): $(top_srcdir)/$(sampling_test_sh_SOURCES) \\\n                           sampling_test\n\trm -f $@\n\tcp -p $(top_srcdir)/$(sampling_test_sh_SOURCES) $@\n\n# This is the sub-program used by sampling_test.sh\n# The -g is so pprof can get symbol information.\nnoinst_PROGRAMS += sampling_test\nSAMPLING_TEST_INCLUDES = src/config_for_unittests.h \\\n                         src/base/logging.h \\\n                         src/google/malloc_extension.h\nsampling_test_SOURCES = src/tests/sampling_test.cc \\\n                        $(SAMPLING_TEST_INCLUDES)\nsampling_test_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nsampling_test_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nsampling_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n\nendif WITH_HEAP_PROFILER_OR_CHECKER\n\nif WITH_HEAP_PROFILER\n\nTESTS += heap-profiler_unittest.sh$(EXEEXT)\nheap_profiler_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh\nnoinst_SCRIPTS += $(heap_profiler_unittest_sh_SOURCES)\nheap-profiler_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) \\\n                                    heap-profiler_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) $@\n\n# These are sub-programs used by heap-profiler_unittest.sh\nnoinst_PROGRAMS += heap-profiler_unittest\nHEAP_PROFILER_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n                                  src/google/heap-profiler.h\nheap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \\\n                                 $(HEAP_PROFILER_UNITTEST_INCLUDES)\nheap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nheap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nheap_profiler_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n\nendif WITH_HEAP_PROFILER\n\nif WITH_HEAP_CHECKER\n\nTESTS += heap-checker_unittest.sh$(EXEEXT)\nheap_checker_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh\nnoinst_SCRIPTS += $(heap_checker_unittest_sh_SOURCES)\nheap-checker_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) \\\n                                   heap-checker_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) $@\n\nTESTS += heap-checker-death_unittest.sh$(EXEEXT)\nheap_checker_death_unittest_sh_SOURCES = src/tests/heap-checker-death_unittest.sh\nnoinst_SCRIPTS += $(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES)\nheap-checker-death_unittest.sh$(EXEEXT): $(heap_checker_death_unittest_sh_SOURCES) \\\n                                         heap-checker_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES) $@\n\n# These are sub-programs used by heap-checker_unittest.sh\nnoinst_PROGRAMS += heap-checker_unittest\nHEAP_CHECKER_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n                                 src/memory_region_map.h \\\n                                 src/base/commandlineflags.h \\\n                                 src/base/googleinit.h \\\n                                 src/google/heap-checker.h \\\n                                 $(LOGGING_INCLUDES)\nheap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \\\n                                $(HEAP_CHECKER_UNITTEST_INCLUDES)\nheap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nheap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\nheap_checker_unittest_LDADD = $(LIBTCMALLOC) liblogging.la $(PTHREAD_LIBS)\n\nendif WITH_HEAP_CHECKER\n\n### Documentation (above and beyond tcmalloc_minimal documentation)\nif WITH_HEAP_PROFILER\ndist_doc_DATA += doc/heapprofile.html doc/heap-example1.png\nendif WITH_HEAP_PROFILER\n\nif WITH_HEAP_CHECKER\ndist_doc_DATA += doc/heap_checker.html\nendif WITH_HEAP_CHECKER\n\n\n### ------- tcmalloc with debugallocation\n\nif WITH_DEBUGALLOC\nif WITH_HEAP_PROFILER_OR_CHECKER\n\nlib_LTLIBRARIES += libtcmalloc_debug.la\nlibtcmalloc_debug_la_SOURCES = src/debugallocation.cc $(HEAP_CHECKER_SOURCES) \\\n                               $(TCMALLOC_INCLUDES)\nlibtcmalloc_debug_la_CXXFLAGS = $(libtcmalloc_la_CXXFLAGS) \\\n                                -DTCMALLOC_FOR_DEBUGALLOCATION\nlibtcmalloc_debug_la_LDFLAGS = $(libtcmalloc_la_LDFLAGS) \\\n                               -version-info @TCMALLOC_SO_VERSION@\nlibtcmalloc_debug_la_LIBADD = $(libtcmalloc_la_LIBADD)\n\nLIBS_TO_WEAKEN += libtcmalloc_debug.la\n\n### Unittests\n\nTESTS += tcmalloc_debug_unittest\ntcmalloc_debug_unittest_SOURCES = $(tcmalloc_unittest_SOURCES)\ntcmalloc_debug_unittest_CXXFLAGS = $(tcmalloc_unittest_CXXFLAGS) \\\n                                   -DDEBUGALLOCATION\ntcmalloc_debug_unittest_LDFLAGS = $(tcmalloc_unittest_LDFLAGS)\ntcmalloc_debug_unittest_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n\nTESTS += sampler_debug_test\nsampler_debug_test_SOURCES = $(sampler_test_SOURCES)\nsampler_debug_test_CXXFLAGS = $(samples_test_CXXFLAGS)\nsampler_debug_test_LDFLAGS = $(sampler_test_LDFLAGS)\nsampler_debug_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS) -lm\n\nTESTS += sampling_debug_test.sh$(EXEEXT)\nsampling_debug_test_sh_SOURCES = src/tests/sampling_test.sh\nsampling_debug_test.sh$(EXEEXT): $(top_srcdir)/$(sampling_test_sh_SOURCES) \\\n                                 sampling_debug_test\n\trm -f $@\n\tcp -p $(top_srcdir)/$(sampling_test_sh_SOURCES) $@\n\n# This is the sub-program using by sampling_debug_test.sh\n# The -g is so pprof can get symbol information.\nnoinst_PROGRAMS += sampling_debug_test\nsampling_debug_test_SOURCES = $(sampling_test_SOURCES)\nsampling_debug_test_CXXFLAGS = $(sampling_test_CXXFLAGS)\nsampling_debug_test_LDFLAGS = $(sampling_test_LDFLAGS)\nsampling_debug_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n\nendif WITH_HEAP_PROFILER_OR_CHECKER\n\nif WITH_HEAP_PROFILER\n\nTESTS += heap-profiler_debug_unittest.sh$(EXEEXT)\nheap_profiler_debug_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh\nheap-profiler_debug_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) \\\n                                    heap-profiler_debug_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) $@\n\n# These are sub-programs used by heap-profiler_debug_unittest.sh\nnoinst_PROGRAMS += heap-profiler_debug_unittest\nheap_profiler_debug_unittest_SOURCES = $(heap_profiler_unittest_SOURCES)\nheap_profiler_debug_unittest_CXXFLAGS = $(heap_profiler_unittest_CXXFLAGS)\nheap_profiler_debug_unittest_LDFLAGS = $(heap_profiler_unittest_LDFLAGS)\nheap_profiler_debug_unittest_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n\nendif WITH_HEAP_PROFILER\n\nif WITH_HEAP_CHECKER\n\nTESTS += heap-checker_debug_unittest.sh$(EXEEXT)\nheap_checker_debug_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh\nheap-checker_debug_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) \\\n                                   heap-checker_debug_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) $@\n\n# These are sub-programs used by heap-checker_debug_unittest.sh\nnoinst_PROGRAMS += heap-checker_debug_unittest\nheap_checker_debug_unittest_SOURCES = $(heap_checker_unittest_SOURCES)\nheap_checker_debug_unittest_CXXFLAGS = $(heap_checker_unittest_CXXFLAGS)\nheap_checker_debug_unittest_LDFLAGS = $(heap_checker_unittest_LDFLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\nheap_checker_debug_unittest_LDADD = libtcmalloc_debug.la liblogging.la \\\n                                    $(PTHREAD_LIBS)\n\nendif WITH_HEAP_CHECKER\nendif WITH_DEBUGALLOC\n\n\n### ------- CPU profiler\n\nif WITH_CPU_PROFILER\n\n### The header files we use.  We divide into categories based on directory\nS_CPU_PROFILER_INCLUDES = src/profiledata.h \\\n                          src/profile-handler.h \\\n                          src/getpc.h \\\n                          src/base/basictypes.h \\\n                          src/base/commandlineflags.h \\\n                          src/base/googleinit.h \\\n                          src/base/logging.h \\\n                          src/base/simple_mutex.h \\\n                          src/base/sysinfo.h \\\n                          $(SPINLOCK_INCLUDES) \\\n                          $(LOGGING_INCLUDES)\nSG_CPU_PROFILER_INCLUDES = src/google/profiler.h \\\n                           src/google/stacktrace.h\nCPU_PROFILER_INCLUDES = $(S_CPU_PROFILER_INCLUDES) $(SG_CPU_PROFILER_INCLUDES)\ngoogleinclude_HEADERS += $(SG_CPU_PROFILER_INCLUDES)\n\n### Making the library\nlib_LTLIBRARIES += libprofiler.la\nlibprofiler_la_SOURCES = src/profiler.cc \\\n                         src/profile-handler.cc \\\n                         src/profiledata.cc \\\n                         $(CPU_PROFILER_INCLUDES)\nlibprofiler_la_LIBADD = libstacktrace.la\n# We have to include ProfileData for profiledata_unittest\nCPU_PROFILER_SYMBOLS = '(ProfilerStart|ProfilerStartWithOptions|ProfilerStop|ProfilerFlush|ProfilerEnable|ProfilerDisable|ProfilingIsEnabledForAllThreads|ProfilerRegisterThread|ProfilerGetCurrentState|ProfilerState|ProfileData|ProfileHandler)'\nlibprofiler_la_LDFLAGS = -export-symbols-regex $(CPU_PROFILER_SYMBOLS) \\\n                         -version-info @PROFILER_SO_VERSION@\n\n# See discussion above (under LIBTCMALLOC_MINIMAL) for why we do this.\n# Basically it's to work around systems where --rpath doesn't work right.\nLIBPROFILER = libstacktrace.la libprofiler.la\n\n### Unittests\nTESTS += getpc_test\n#WINDOWS_PROJECTS += vsprojects/getpc_test/getpc_test.vcproj\ngetpc_test_SOURCES = src/tests/getpc_test.cc src/getpc.h\n\nTESTS += profiledata_unittest\n#WINDOWS_PROJECTS += vsprojects/profiledata_unittest/profiledata_unittest.vcproj\nprofiledata_unittest_SOURCES = src/tests/profiledata_unittest.cc \\\n                               src/profiledata.h \\\n                               src/base/commandlineflags.h \\\n                               src/base/logging.h \\\n                               src/base/basictypes.h\nprofiledata_unittest_LDADD = $(LIBPROFILER)\n\nTESTS += profile_handler_unittest\nprofile_handler_unittest_SOURCES = src/tests/profile-handler_unittest.cc \\\n                                   src/profile-handler.h\nprofile_handler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)\nprofile_handler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\nprofile_handler_unittest_LDADD = $(LIBPROFILER) $(PTHREAD_LIBS)\n\nTESTS += profiler_unittest.sh$(EXEEXT)\nprofiler_unittest_sh_SOURCES = src/tests/profiler_unittest.sh\nnoinst_SCRIPTS += $(profiler_unittest_sh_SOURCES)\nprofiler_unittest.sh$(EXEEXT): $(top_srcdir)/$(profiler_unittest_sh_SOURCES) \\\n                               profiler1_unittest profiler2_unittest \\\n                               profiler3_unittest profiler4_unittest\n\trm -f $@\n\tcp -p $(top_srcdir)/$(profiler_unittest_sh_SOURCES) $@\n\n# These are sub-programs used by profiler_unittest.sh\nnoinst_PROGRAMS += profiler1_unittest profiler2_unittest profiler3_unittest \\\n                   profiler4_unittest\nPROFILER_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n                             src/google/profiler.h\nPROFILER_UNITTEST_SRCS = src/tests/profiler_unittest.cc \\\n                         src/tests/testutil.h src/tests/testutil.cc \\\n                         $(PROFILER_UNITTEST_INCLUDES)\nprofiler1_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\nprofiler1_unittest_CXXFLAGS = -g -DNO_THREADS $(AM_CXXFLAGS)\nprofiler1_unittest_LDADD = $(LIBPROFILER)\nprofiler2_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\nprofiler2_unittest_CXXFLAGS = -g -DNO_THREADS $(AM_CXXFLAGS)\nprofiler2_unittest_LDADD = -lstacktrace -lprofiler\n# We depend on -lprofiler but haven't yet said how to build it.  Do so now.\nprofiler2_unittest_DEPENDENCIES = $(LIBPROFILER)\nprofiler3_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\nprofiler3_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nprofiler3_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\nprofiler3_unittest_LDADD = $(LIBPROFILER) $(PTHREAD_LIBS)\nprofiler4_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\nprofiler4_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nprofiler4_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\nprofiler4_unittest_LDADD = -lstacktrace -lprofiler $(PTHREAD_LIBS)\n# We depend on -lprofiler but haven't yet said how to build it.  Do so now.\nprofiler4_unittest_DEPENDENCIES = $(LIBPROFILER)\n\n\n### Documentation\ndist_doc_DATA += doc/cpuprofile.html \\\n                 doc/cpuprofile-fileformat.html \\\n                 doc/pprof-test-big.gif \\\n                 doc/pprof-test.gif \\\n                 doc/pprof-vsnprintf-big.gif \\\n                 doc/pprof-vsnprintf.gif\n\nendif WITH_CPU_PROFILER\n\n\n### ------- CPU profiler and heap checker, in one!\n\n# Ideally, folks who wanted to use both tcmalloc and libprofiler,\n# could just link them both into their application.  But while this\n# works fine for .so files, it does not for .a files.  The easiest way\n# around this -- and I've tried a bunch of the hard ways -- is to just\n# to create another set of libraries that has both functionality in it.\n\nif WITH_HEAP_PROFILER_OR_CHECKER\nif WITH_CPU_PROFILER\n\nlib_LTLIBRARIES += libtcmalloc_and_profiler.la\nlibtcmalloc_and_profiler_la_SOURCES = $(libtcmalloc_la_SOURCES) $(libprofiler_la_SOURCES)\nlibtcmalloc_and_profiler_la_CXXFLAGS = $(libtcmalloc_la_CXXFLAGS) $(libprofiler_la_CXXFLAGS)\n# Since this library is meant to be used as a .a, I don't worry as much\n# about .so versioning.  I just give the libtcmalloc version number.\n# TODO(csilvers): use -export-symbols-regex?\nlibtcmalloc_and_profiler_la_LDFLAGS = $(PTHREAD_CFLAGS) \\\n                                      -version-info @TCMALLOC_SO_VERSION@\n# We don't include libprofiler_la_LIBADD here because all it adds is\n# libstacktrace.la, which we already get via libtcmalloc.  Trying to\n# specify it twice causes link-time duplicate-definition errors. :-(\nlibtcmalloc_and_profiler_la_LIBADD = $(libtcmalloc_la_LIBADD)\n\nTESTS += tcmalloc_and_profiler_unittest\ntcmalloc_and_profiler_unittest_SOURCES = $(tcmalloc_both_unittest_SOURCES)\ntcmalloc_and_profiler_unittest_CXXFLAGS = $(tcmalloc_both_unittest_CXXFLAGS)\ntcmalloc_and_profiler_unittest_LDFLAGS = $(tcmalloc_both_unittest_LDFLAGS)\ntcmalloc_and_profiler_unittest_LDADD = libtcmalloc_and_profiler.la\n\nLIBS_TO_WEAKEN += libtcmalloc_and_profiler.la\n\nendif WITH_CPU_PROFILER\nendif WITH_HEAP_PROFILER_OR_CHECKER\n\n## ^^^^ END OF RULES TO MAKE YOUR LIBRARIES, BINARIES, AND UNITTESTS\n\n\n# Do the weakening on some exported libtcmalloc symbols.\ninstall-exec-local: all-local\nall-local: $(LIBS_TO_WEAKEN)\n\tfor la in $(LIBS_TO_WEAKEN); do lib=\".libs/`basename $$la .la`.a\"; [ ! -f \"$$lib\" ] || $(WEAKEN) \"$$lib\"; done\n\n\n# This should always include $(TESTS), but may also include other\n# binaries that you compile but don't want automatically installed.\n# We'll add to this later, on a library-by-library basis\nnoinst_PROGRAMS += $(TESTS)\n\nrpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec\n\t@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}\n\ndeb: dist-gzip packages/deb.sh packages/deb/*\n\t@cd packages && ./deb.sh ${PACKAGE} ${VERSION}\n\n# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = libtcmalloc.pc libtcmalloc_minimal.pc \\\n                 libtcmalloc_debug.pc libtcmalloc_minimal_debug.pc \\\n                 libprofiler.pc\nCLEANFILES = $(pkgconfig_DATA)\n\n# I get the description and URL lines from the rpm spec. I use sed to\n# try to rewrite exec_prefix, libdir, and includedir in terms of\n# prefix, if possible.\nlibtcmalloc.pc: Makefile packages/rpm/rpm.spec\n\techo 'prefix=$(prefix)' > \"$@\".tmp\n\techo 'exec_prefix='`echo '$(exec_prefix)' | sed 's@^$(prefix)@$${prefix}@'` >> \"$@\".tmp\n\techo 'libdir='`echo '$(libdir)' | sed 's@^$(exec_prefix)@$${exec_prefix}@'` >> \"$@\".tmp\n\techo 'includedir='`echo '$(includedir)' | sed 's@^$(prefix)@$${prefix}@'` >> \"$@\".tmp\n\techo '' >> \"$@\".tmp\n\techo 'Name: $(PACKAGE)' >> \"$@\".tmp\n\techo 'Version: $(VERSION)' >> \"$@\".tmp\n\t-grep '^Summary:' packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> \"$@\".tmp\n\t-grep '^URL: ' packages/rpm/rpm.spec >> \"$@\".tmp\n\techo 'Requires:' >> \"$@\".tmp\n\techo 'Libs: -L$${libdir} -ltcmalloc' >> \"$@\".tmp\n\techo 'Libs.private: $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)' >> \"$@\".tmp\n\techo 'Cflags: -I$${includedir}' >> \"$@\".tmp\n\tmv -f \"$@\".tmp \"$@\"\n\n# The other versions are mostly the same.\nlibtcmalloc_minimal.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_minimal/ > \"$@\"\n\nlibtcmalloc_debug.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_debug/ > \"$@\"\n\nlibtcmalloc_minimal_debug.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_minimal_debug/ > \"$@\"\n\nlibprofiler.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-lprofiler/ > \"$@\"\n\nlibtool: $(LIBTOOL_DEPS)\n\t$(SHELL) ./config.status --recheck\n\n# Windows wants write permission to .vcproj files and maybe even sln files.\ndist-hook:\n\ttest -e \"$(distdir)/vsprojects\" \\\n\t   && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/\n\nEXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \\\n             $(SCRIPTS) libtool \\\n             src/windows/get_mangled_names.cc src/windows/override_functions.cc \\\n             src/windows/config.h src/windows/google/tcmalloc.h \\\n             $(WINDOWS_PROJECTS) \\\n             src/solaris/libstdc++.la\n"
  },
  {
    "path": "distro/google-perftools-1.7/Makefile.in",
    "content": "# Makefile.in generated by automake 1.9.6 from Makefile.am.\n# @configure_input@\n\n# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,\n# 2003, 2004, 2005  Free Software Foundation, Inc.\n# This Makefile.in is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\n@SET_MAKE@\n\n# Note: for every library we create, we're explicit about what symbols\n# we export.  In order to avoid complications with C++ mangling, we always\n# use the regexp for of specifying symbols.\n\n\n\n\n\nsrcdir = @srcdir@\ntop_srcdir = @top_srcdir@\nVPATH = @srcdir@\npkgdatadir = $(datadir)/@PACKAGE@\npkglibdir = $(libdir)/@PACKAGE@\npkgincludedir = $(includedir)/@PACKAGE@\ntop_builddir = .\nam__cd = CDPATH=\"$${ZSH_VERSION+.}$(PATH_SEPARATOR)\" && cd\nINSTALL = @INSTALL@\ninstall_sh_DATA = $(install_sh) -c -m 644\ninstall_sh_PROGRAM = $(install_sh) -c\ninstall_sh_SCRIPT = $(install_sh) -c\nINSTALL_HEADER = $(INSTALL_DATA)\ntransform = $(program_transform_name)\nNORMAL_INSTALL = :\nPRE_INSTALL = :\nPOST_INSTALL = :\nNORMAL_UNINSTALL = :\nPRE_UNINSTALL = :\nPOST_UNINSTALL = :\nbuild_triplet = @build@\nhost_triplet = @host@\n@WITH_STACK_TRACE_FALSE@am__append_1 = -DNO_TCMALLOC_SAMPLES\n\n# These are good warnings to turn on by default.  We also tell gcc\n# that malloc, free, realloc, mmap, etc. are not builtins (these flags\n# are supported since gcc 3.1.1).  gcc doesn't think most of them are\n# builtins now in any case, but it's best to be explicit in case that\n# changes one day.  gcc ignores functions it doesn't understand.\n@GCC_TRUE@am__append_2 = -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare \\\n@GCC_TRUE@               -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc \\\n@GCC_TRUE@               -fno-builtin-calloc -fno-builtin-cfree \\\n@GCC_TRUE@               -fno-builtin-memalign -fno-builtin-posix_memalign \\\n@GCC_TRUE@               -fno-builtin-valloc -fno-builtin-pvalloc\n\n\n# These are x86-specific, having to do with frame-pointers.  In\n# particular, some x86_64 systems do not insert frame pointers by\n# default (all i386 systems that I know of, do.  I don't know about\n# non-x86 chips).  We need to tell perftools what to do about that.\n@ENABLE_FRAME_POINTERS_TRUE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@am__append_3 = -fno-omit-frame-pointer\n@ENABLE_FRAME_POINTERS_FALSE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@am__append_4 = -DNO_FRAME_POINTER\n@MINGW_TRUE@am__append_5 = -Wl,-u__tcmalloc\nnoinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \\\n\t$(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \\\n\t$(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_23)\nbin_PROGRAMS =\n@MINGW_TRUE@am__append_6 = libwindows.la libspinlock.la\n\n# We also need to tell mingw that sysinfo.cc needs shlwapi.lib.\n# (We do this via a #pragma for msvc, but need to do it here for mingw).\n@MINGW_TRUE@am__append_7 = -lshlwapi\n@MINGW_FALSE@am__append_8 = libspinlock.la\n@WITH_STACK_TRACE_TRUE@am__append_9 = $(SG_STACKTRACE_INCLUDES)\n\n### Making the library\n@WITH_STACK_TRACE_TRUE@am__append_10 = libstacktrace.la\n\n### Unittests\n@WITH_STACK_TRACE_TRUE@am__append_11 = stacktrace_unittest\n\n### Documentation\n@WITH_STACK_TRACE_TRUE@am__append_12 = doc/pprof_remote_servers.html\n\n# Let unittests find pprof if they need to run it\n@WITH_STACK_TRACE_TRUE@am__append_13 = PPROF_PATH=$(top_srcdir)/src/pprof\n\n# On MSVC, we need our own versions of addr2line and nm to work with pprof.\n# This is a slight abuse of WINDOWS_PROJECTS, but not much\n@WITH_STACK_TRACE_TRUE@am__append_14 =  \\\n@WITH_STACK_TRACE_TRUE@\tvsprojects/nm-pdb/nm-pdb.vcproj \\\n@WITH_STACK_TRACE_TRUE@\tvsprojects/addr2line-pdb/addr2line-pdb.vcproj \\\n@WITH_STACK_TRACE_TRUE@\tsrc/windows/nm-pdb.c \\\n@WITH_STACK_TRACE_TRUE@\tsrc/windows/addr2line-pdb.c\n\n# This tests it works to LD_PRELOAD libtcmalloc (tests maybe_threads.cc)\n# In theory this should work under mingw, but mingw has trouble running\n# shell scripts that end in .exe.  And it doesn't seem to build shared\n# libraries anyway (so can't be LD_PRELOADed) -- in fact, anybody who\n# chooses not to build shared libraries won't be able to run this test.\n# TODO(csilvers): figure out how to nix \".exe\" or otherwise work under mingw\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_15 = maybe_threads_unittest.sh$(EXEEXT)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_16 = $(maybe_threads_unittest_sh_SOURCES)\n@MINGW_TRUE@am__append_17 = src/windows/port.h src/windows/port.cc\n@MINGW_FALSE@am__append_18 = system_alloc_unittest\n\n# This doesn't work with static linkage, because libtcmalloc.a isn't\n# happy with C linkage (it misses the stdc++ library).  Likewise with\n# mingw, which links foo.a even though it doesn't set ENABLE_STATIC.\n# TODO(csilvers): set enable_static=true in configure.ac:36?\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_19 = malloc_extension_c_test\n# -ansi here is just to help ensure the code is bog-standard C.\n@ENABLE_STATIC_FALSE@@GCC_TRUE@@MINGW_FALSE@am__append_20 = -ansi\n@MINGW_FALSE@am__append_21 = memalign_unittest\n\n### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation)\n\n# Like tcmalloc.cc, debugallocation.cc needs exceptions to fulfill its\n# API.  Luckily, we can reuse everything else from tcmalloc_minimal.\n@WITH_DEBUGALLOC_TRUE@am__append_22 = libtcmalloc_minimal_debug.la\n@WITH_DEBUGALLOC_TRUE@am__append_23 = libtcmalloc_minimal_debug.la\n\n### Unittests\n@WITH_DEBUGALLOC_TRUE@am__append_24 = tcmalloc_minimal_debug_unittest \\\n@WITH_DEBUGALLOC_TRUE@\tmalloc_extension_debug_test \\\n@WITH_DEBUGALLOC_TRUE@\tmemalign_debug_unittest \\\n@WITH_DEBUGALLOC_TRUE@\trealloc_debug_unittest \\\n@WITH_DEBUGALLOC_TRUE@\tdebugallocation_test.sh$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@am__append_25 = $(debugallocation_test_sh_SOURCES)\n\n# This is the sub-program used by debugallocation_test.sh\n@WITH_DEBUGALLOC_TRUE@am__append_26 = debugallocation_test\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_27 = $(SG_TCMALLOC_INCLUDES)\n\n### Making the library\n\n# As we describe at the top of this file, we want to turn off exceptions\n# for all files in this library -- except tcmalloc.cc which needs them\n# to fulfill its API.  Automake doesn't allow per-file CXXFLAGS, so we need\n# to separate into two libraries.\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_28 = libtcmalloc_internal.la\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_29 = libtcmalloc.la\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_30 = $(HEAP_CHECKER_SOURCES)\n@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_31 = -DNO_HEAP_CHECK\n@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_32 = -DNO_HEAP_CHECK\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_33 = libtcmalloc.la\n\n### Unittests\n\n# This makes sure it's safe to link in both tcmalloc and\n# tcmalloc_minimal.  (One would never do this on purpose, but perhaps\n# by accident...)  When we can compile libprofiler, we also link it in\n# to make sure that works too.\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_34 = tcmalloc_unittest \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_both_unittest \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_large_unittest \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\traw_printer_test \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampler_test \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampling_test.sh$(EXEEXT)\n\n# sampler_test and sampling_test both require sampling to be turned\n# on, which it's not by default.  Use the \"standard\" value of 2^19.\n\n# These unittests often need to run binaries.  They're in the current dir\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_35 = TCMALLOC_SAMPLE_PARAMETER=524288 \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tBINDIR=. \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tTMPDIR=/tmp/perftools\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_36 = vsprojects/sampler_test/sampler_test.vcproj\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_37 = $(sampling_test_sh_SOURCES)\n\n# This is the sub-program used by sampling_test.sh\n# The -g is so pprof can get symbol information.\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_38 = sampling_test\n@WITH_HEAP_PROFILER_TRUE@am__append_39 = heap-profiler_unittest.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_TRUE@am__append_40 = $(heap_profiler_unittest_sh_SOURCES)\n\n# These are sub-programs used by heap-profiler_unittest.sh\n@WITH_HEAP_PROFILER_TRUE@am__append_41 = heap-profiler_unittest\n@WITH_HEAP_CHECKER_TRUE@am__append_42 =  \\\n@WITH_HEAP_CHECKER_TRUE@\theap-checker_unittest.sh$(EXEEXT) \\\n@WITH_HEAP_CHECKER_TRUE@\theap-checker-death_unittest.sh$(EXEEXT)\n@WITH_HEAP_CHECKER_TRUE@am__append_43 =  \\\n@WITH_HEAP_CHECKER_TRUE@\t$(heap_checker_unittest_sh_SOURCES) \\\n@WITH_HEAP_CHECKER_TRUE@\t$(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES)\n\n# These are sub-programs used by heap-checker_unittest.sh\n@WITH_HEAP_CHECKER_TRUE@am__append_44 = heap-checker_unittest\n\n### Documentation (above and beyond tcmalloc_minimal documentation)\n@WITH_HEAP_PROFILER_TRUE@am__append_45 = doc/heapprofile.html doc/heap-example1.png\n@WITH_HEAP_CHECKER_TRUE@am__append_46 = doc/heap_checker.html\n\n### ------- tcmalloc with debugallocation\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_47 = libtcmalloc_debug.la\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_48 = libtcmalloc_debug.la\n\n### Unittests\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_49 = tcmalloc_debug_unittest \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampler_debug_test \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampling_debug_test.sh$(EXEEXT)\n\n# This is the sub-program using by sampling_debug_test.sh\n# The -g is so pprof can get symbol information.\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_50 = sampling_debug_test\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__append_51 = heap-profiler_debug_unittest.sh$(EXEEXT)\n\n# These are sub-programs used by heap-profiler_debug_unittest.sh\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__append_52 = heap-profiler_debug_unittest\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__append_53 = heap-checker_debug_unittest.sh$(EXEEXT)\n\n# These are sub-programs used by heap-checker_debug_unittest.sh\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__append_54 = heap-checker_debug_unittest\n@WITH_CPU_PROFILER_TRUE@am__append_55 = $(SG_CPU_PROFILER_INCLUDES)\n\n### Making the library\n@WITH_CPU_PROFILER_TRUE@am__append_56 = libprofiler.la\n\n### Unittests\n@WITH_CPU_PROFILER_TRUE@am__append_57 = getpc_test \\\n@WITH_CPU_PROFILER_TRUE@\tprofiledata_unittest \\\n@WITH_CPU_PROFILER_TRUE@\tprofile_handler_unittest \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler_unittest.sh$(EXEEXT)\n@WITH_CPU_PROFILER_TRUE@am__append_58 = $(profiler_unittest_sh_SOURCES)\n\n# These are sub-programs used by profiler_unittest.sh\n@WITH_CPU_PROFILER_TRUE@am__append_59 = profiler1_unittest profiler2_unittest profiler3_unittest \\\n@WITH_CPU_PROFILER_TRUE@                   profiler4_unittest\n\n@WITH_CPU_PROFILER_FALSE@profiler2_unittest_DEPENDENCIES =\n\n### Documentation\n@WITH_CPU_PROFILER_TRUE@am__append_60 = doc/cpuprofile.html \\\n@WITH_CPU_PROFILER_TRUE@                 doc/cpuprofile-fileformat.html \\\n@WITH_CPU_PROFILER_TRUE@                 doc/pprof-test-big.gif \\\n@WITH_CPU_PROFILER_TRUE@                 doc/pprof-test.gif \\\n@WITH_CPU_PROFILER_TRUE@                 doc/pprof-vsnprintf-big.gif \\\n@WITH_CPU_PROFILER_TRUE@                 doc/pprof-vsnprintf.gif\n\n\n### ------- CPU profiler and heap checker, in one!\n\n# Ideally, folks who wanted to use both tcmalloc and libprofiler,\n# could just link them both into their application.  But while this\n# works fine for .so files, it does not for .a files.  The easiest way\n# around this -- and I've tried a bunch of the hard ways -- is to just\n# to create another set of libraries that has both functionality in it.\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_61 = libtcmalloc_and_profiler.la\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_62 = tcmalloc_and_profiler_unittest\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_63 = libtcmalloc_and_profiler.la\nDIST_COMMON = README $(am__configure_deps) $(am__dist_doc_DATA_DIST) \\\n\t$(am__googleinclude_HEADERS_DIST) $(dist_man_MANS) \\\n\t$(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \\\n\t$(top_srcdir)/configure $(top_srcdir)/src/config.h.in \\\n\t$(top_srcdir)/src/google/tcmalloc.h.in AUTHORS COPYING \\\n\tChangeLog INSTALL NEWS TODO compile config.guess config.sub \\\n\tdepcomp install-sh ltmain.sh missing mkinstalldirs\nsubdir = .\nACLOCAL_M4 = $(top_srcdir)/aclocal.m4\nam__aclocal_m4_deps = $(top_srcdir)/m4/ac_have_attribute.m4 \\\n\t$(top_srcdir)/m4/acx_nanosleep.m4 \\\n\t$(top_srcdir)/m4/acx_pthread.m4 \\\n\t$(top_srcdir)/m4/compiler_characteristics.m4 \\\n\t$(top_srcdir)/m4/install_prefix.m4 $(top_srcdir)/m4/libtool.m4 \\\n\t$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \\\n\t$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \\\n\t$(top_srcdir)/m4/namespaces.m4 \\\n\t$(top_srcdir)/m4/pc_from_ucontext.m4 \\\n\t$(top_srcdir)/m4/program_invocation_name.m4 \\\n\t$(top_srcdir)/m4/stl_namespace.m4 $(top_srcdir)/configure.ac\nam__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \\\n\t$(ACLOCAL_M4)\nam__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \\\n configure.lineno configure.status.lineno\nmkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs\nCONFIG_HEADER = $(top_builddir)/src/config.h\nCONFIG_CLEAN_FILES = src/google/tcmalloc.h\nam__vpath_adj_setup = srcdirstrip=`echo \"$(srcdir)\" | sed 's|.|.|g'`;\nam__vpath_adj = case $$p in \\\n    $(srcdir)/*) f=`echo \"$$p\" | sed \"s|^$$srcdirstrip/||\"`;; \\\n    *) f=$$p;; \\\n  esac;\nam__strip_dir = `echo $$p | sed -e 's|^.*/||'`;\nam__installdirs = \"$(DESTDIR)$(libdir)\" \"$(DESTDIR)$(bindir)\" \\\n\t\"$(DESTDIR)$(bindir)\" \"$(DESTDIR)$(man1dir)\" \\\n\t\"$(DESTDIR)$(docdir)\" \"$(DESTDIR)$(pkgconfigdir)\" \\\n\t\"$(DESTDIR)$(googleincludedir)\" \\\n\t\"$(DESTDIR)$(googleincludedir)\"\nlibLTLIBRARIES_INSTALL = $(INSTALL)\nLTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)\nliblogging_la_LIBADD =\nam__objects_1 =\nam_liblogging_la_OBJECTS = logging.lo dynamic_annotations.lo \\\n\t$(am__objects_1)\nliblogging_la_OBJECTS = $(am_liblogging_la_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@libprofiler_la_DEPENDENCIES =  \\\n@WITH_CPU_PROFILER_TRUE@\tlibstacktrace.la\nam__libprofiler_la_SOURCES_DIST = src/profiler.cc \\\n\tsrc/profile-handler.cc src/profiledata.cc src/profiledata.h \\\n\tsrc/profile-handler.h src/getpc.h src/base/basictypes.h \\\n\tsrc/base/commandlineflags.h src/base/googleinit.h \\\n\tsrc/base/logging.h src/base/simple_mutex.h src/base/sysinfo.h \\\n\tsrc/base/spinlock.h src/base/spinlock_internal.h \\\n\tsrc/base/atomicops.h src/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h \\\n\tsrc/google/profiler.h src/google/stacktrace.h\n@WITH_CPU_PROFILER_TRUE@am__objects_2 = $(am__objects_1) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@am__objects_3 = $(am__objects_2) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@am_libprofiler_la_OBJECTS = profiler.lo \\\n@WITH_CPU_PROFILER_TRUE@\tprofile-handler.lo profiledata.lo \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_3)\nlibprofiler_la_OBJECTS = $(am_libprofiler_la_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@am_libprofiler_la_rpath = -rpath $(libdir)\nam__DEPENDENCIES_1 =\n@MINGW_FALSE@libspinlock_la_DEPENDENCIES = $(am__DEPENDENCIES_1)\nam__libspinlock_la_SOURCES_DIST = src/base/spinlock.cc \\\n\tsrc/base/spinlock_internal.cc \\\n\tsrc/base/atomicops-internals-x86.cc src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h\n@MINGW_FALSE@am_libspinlock_la_OBJECTS = spinlock.lo \\\n@MINGW_FALSE@\tspinlock_internal.lo atomicops-internals-x86.lo \\\n@MINGW_FALSE@\t$(am__objects_1)\n@MINGW_TRUE@am_libspinlock_la_OBJECTS = spinlock.lo \\\n@MINGW_TRUE@\tspinlock_internal.lo $(am__objects_1)\nlibspinlock_la_OBJECTS = $(am_libspinlock_la_OBJECTS)\n@MINGW_FALSE@am_libspinlock_la_rpath =\n@MINGW_TRUE@am_libspinlock_la_rpath =\n@MINGW_FALSE@am__DEPENDENCIES_2 = libspinlock.la libsysinfo.la \\\n@MINGW_FALSE@\tliblogging.la\n@MINGW_TRUE@am__DEPENDENCIES_2 = libwindows.la libspinlock.la \\\n@MINGW_TRUE@\tlibsysinfo.la liblogging.la\n@WITH_STACK_TRACE_TRUE@libstacktrace_la_DEPENDENCIES =  \\\n@WITH_STACK_TRACE_TRUE@\t$(am__DEPENDENCIES_1) \\\n@WITH_STACK_TRACE_TRUE@\t$(am__DEPENDENCIES_2)\nam__libstacktrace_la_SOURCES_DIST = src/stacktrace.cc \\\n\tsrc/base/vdso_support.cc src/stacktrace_config.h \\\n\tsrc/stacktrace_generic-inl.h src/stacktrace_libunwind-inl.h \\\n\tsrc/stacktrace_powerpc-inl.h src/stacktrace_x86_64-inl.h \\\n\tsrc/stacktrace_x86-inl.h src/stacktrace_win32-inl.h \\\n\tsrc/base/vdso_support.h src/google/stacktrace.h\n@WITH_STACK_TRACE_TRUE@am__objects_4 = $(am__objects_1) \\\n@WITH_STACK_TRACE_TRUE@\t$(am__objects_1)\n@WITH_STACK_TRACE_TRUE@am_libstacktrace_la_OBJECTS = stacktrace.lo \\\n@WITH_STACK_TRACE_TRUE@\tvdso_support.lo $(am__objects_4)\nlibstacktrace_la_OBJECTS = $(am_libstacktrace_la_OBJECTS)\n@WITH_STACK_TRACE_TRUE@am_libstacktrace_la_rpath =\nlibsysinfo_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \\\n\t$(am__DEPENDENCIES_1)\nam_libsysinfo_la_OBJECTS = sysinfo.lo $(am__objects_1)\nlibsysinfo_la_OBJECTS = $(am_libsysinfo_la_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal.la \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__libtcmalloc_la_SOURCES_DIST = src/tcmalloc.cc src/common.h \\\n\tsrc/internal_logging.h src/system-alloc.h \\\n\tsrc/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/base/logging.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h \\\n\tsrc/addressmap-inl.h src/raw_printer.h src/base/elfcore.h \\\n\tsrc/base/googleinit.h src/base/linux_syscall_support.h \\\n\tsrc/base/linuxthreads.h src/base/stl_allocator.h \\\n\tsrc/base/sysinfo.h src/base/thread_lister.h \\\n\tsrc/heap-profile-table.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h \\\n\tsrc/google/heap-profiler.h src/google/heap-checker.h \\\n\tsrc/base/thread_lister.c src/base/linuxthreads.cc \\\n\tsrc/heap-checker.cc src/heap-checker-bcad.cc\n@MINGW_FALSE@am__objects_5 = libtcmalloc_la-tcmalloc.lo\nam__objects_6 = $(am__objects_1)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_7 = $(am__objects_6) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_8 = $(am__objects_1)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_9 = $(am__objects_7) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_8)\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_10 = thread_lister.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_la-linuxthreads.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_la-heap-checker.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_la-heap-checker-bcad.lo\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_11 = $(am__objects_10)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_la_OBJECTS =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_5) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_9) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_11)\nlibtcmalloc_la_OBJECTS = $(am_libtcmalloc_la_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_la_rpath = -rpath \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(libdir)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__DEPENDENCIES_3 =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal.la \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_and_profiler_la_DEPENDENCIES = $(am__DEPENDENCIES_3)\nam__libtcmalloc_and_profiler_la_SOURCES_DIST = src/tcmalloc.cc \\\n\tsrc/common.h src/internal_logging.h src/system-alloc.h \\\n\tsrc/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/base/logging.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h \\\n\tsrc/addressmap-inl.h src/raw_printer.h src/base/elfcore.h \\\n\tsrc/base/googleinit.h src/base/linux_syscall_support.h \\\n\tsrc/base/linuxthreads.h src/base/stl_allocator.h \\\n\tsrc/base/sysinfo.h src/base/thread_lister.h \\\n\tsrc/heap-profile-table.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h \\\n\tsrc/google/heap-profiler.h src/google/heap-checker.h \\\n\tsrc/base/thread_lister.c src/base/linuxthreads.cc \\\n\tsrc/heap-checker.cc src/heap-checker-bcad.cc src/profiler.cc \\\n\tsrc/profile-handler.cc src/profiledata.cc src/profiledata.h \\\n\tsrc/profile-handler.h src/getpc.h src/base/simple_mutex.h \\\n\tsrc/google/profiler.h\n@MINGW_FALSE@am__objects_12 = libtcmalloc_and_profiler_la-tcmalloc.lo\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_13 = thread_lister.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_and_profiler_la-linuxthreads.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_and_profiler_la-heap-checker.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_and_profiler_la-heap-checker-bcad.lo\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_14 = $(am__objects_13)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_15 =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_12) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_9) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_14)\n@WITH_CPU_PROFILER_TRUE@am__objects_16 = libtcmalloc_and_profiler_la-profiler.lo \\\n@WITH_CPU_PROFILER_TRUE@\tlibtcmalloc_and_profiler_la-profile-handler.lo \\\n@WITH_CPU_PROFILER_TRUE@\tlibtcmalloc_and_profiler_la-profiledata.lo \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_3)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_and_profiler_la_OBJECTS = $(am__objects_15) \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_16)\nlibtcmalloc_and_profiler_la_OBJECTS =  \\\n\t$(am_libtcmalloc_and_profiler_la_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_and_profiler_la_rpath = -rpath \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(libdir)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_debug_la_DEPENDENCIES = $(am__DEPENDENCIES_3)\nam__libtcmalloc_debug_la_SOURCES_DIST = src/debugallocation.cc \\\n\tsrc/base/thread_lister.c src/base/linuxthreads.cc \\\n\tsrc/heap-checker.cc src/heap-checker-bcad.cc src/common.h \\\n\tsrc/internal_logging.h src/system-alloc.h \\\n\tsrc/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/base/logging.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h \\\n\tsrc/addressmap-inl.h src/raw_printer.h src/base/elfcore.h \\\n\tsrc/base/googleinit.h src/base/linux_syscall_support.h \\\n\tsrc/base/linuxthreads.h src/base/stl_allocator.h \\\n\tsrc/base/sysinfo.h src/base/thread_lister.h \\\n\tsrc/heap-profile-table.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h \\\n\tsrc/google/heap-profiler.h src/google/heap-checker.h\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_17 = thread_lister.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_debug_la-linuxthreads.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_debug_la-heap-checker.lo \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_debug_la-heap-checker-bcad.lo\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_debug_la_OBJECTS = libtcmalloc_debug_la-debugallocation.lo \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_17) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_9)\nlibtcmalloc_debug_la_OBJECTS = $(am_libtcmalloc_debug_la_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_debug_la_rpath = -rpath \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(libdir)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibstacktrace.la \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__libtcmalloc_internal_la_SOURCES_DIST = src/common.cc \\\n\tsrc/internal_logging.cc src/system-alloc.cc \\\n\tsrc/memfs_malloc.cc src/central_freelist.cc src/page_heap.cc \\\n\tsrc/sampler.cc src/span.cc src/stack_trace_table.cc \\\n\tsrc/static_vars.cc src/symbolize.cc src/thread_cache.cc \\\n\tsrc/malloc_hook.cc src/malloc_extension.cc \\\n\tsrc/maybe_threads.cc src/common.h src/internal_logging.h \\\n\tsrc/system-alloc.h src/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h \\\n\tsrc/base/logging.h src/base/dynamic_annotations.h \\\n\tsrc/third_party/valgrind.h src/addressmap-inl.h \\\n\tsrc/raw_printer.h src/base/elfcore.h src/base/googleinit.h \\\n\tsrc/base/linux_syscall_support.h src/base/linuxthreads.h \\\n\tsrc/base/stl_allocator.h src/base/sysinfo.h \\\n\tsrc/base/thread_lister.h src/heap-profile-table.h \\\n\tsrc/google/heap-profiler.h src/google/heap-checker.h \\\n\tsrc/base/low_level_alloc.cc src/heap-profile-table.cc \\\n\tsrc/heap-profiler.cc src/raw_printer.cc \\\n\tsrc/memory_region_map.cc\n@MINGW_FALSE@am__objects_18 = libtcmalloc_internal_la-system-alloc.lo\n@MINGW_FALSE@am__objects_19 =  \\\n@MINGW_FALSE@\tlibtcmalloc_internal_la-maybe_threads.lo\nam__objects_20 = $(am__objects_6) $(am__objects_1)\nam__objects_21 = libtcmalloc_internal_la-common.lo \\\n\tlibtcmalloc_internal_la-internal_logging.lo $(am__objects_18) \\\n\tlibtcmalloc_internal_la-memfs_malloc.lo \\\n\tlibtcmalloc_internal_la-central_freelist.lo \\\n\tlibtcmalloc_internal_la-page_heap.lo \\\n\tlibtcmalloc_internal_la-sampler.lo \\\n\tlibtcmalloc_internal_la-span.lo \\\n\tlibtcmalloc_internal_la-stack_trace_table.lo \\\n\tlibtcmalloc_internal_la-static_vars.lo \\\n\tlibtcmalloc_internal_la-symbolize.lo \\\n\tlibtcmalloc_internal_la-thread_cache.lo \\\n\tlibtcmalloc_internal_la-malloc_hook.lo \\\n\tlibtcmalloc_internal_la-malloc_extension.lo $(am__objects_19) \\\n\t$(am__objects_20)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_internal_la_OBJECTS =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_21) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_9) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal_la-low_level_alloc.lo \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal_la-heap-profile-table.lo \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal_la-heap-profiler.lo \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal_la-raw_printer.lo \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc_internal_la-memory_region_map.lo\nlibtcmalloc_internal_la_OBJECTS =  \\\n\t$(am_libtcmalloc_internal_la_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_libtcmalloc_internal_la_rpath =\nlibtcmalloc_minimal_la_DEPENDENCIES = libtcmalloc_minimal_internal.la \\\n\t$(am__DEPENDENCIES_1)\nam__libtcmalloc_minimal_la_SOURCES_DIST = src/tcmalloc.cc src/common.h \\\n\tsrc/internal_logging.h src/system-alloc.h \\\n\tsrc/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h\n@MINGW_FALSE@am__objects_22 = libtcmalloc_minimal_la-tcmalloc.lo\nam_libtcmalloc_minimal_la_OBJECTS = $(am__objects_22) \\\n\t$(am__objects_20)\nlibtcmalloc_minimal_la_OBJECTS = $(am_libtcmalloc_minimal_la_OBJECTS)\nam__DEPENDENCIES_4 = libtcmalloc_minimal_internal.la \\\n\t$(am__DEPENDENCIES_1)\n@WITH_DEBUGALLOC_TRUE@libtcmalloc_minimal_debug_la_DEPENDENCIES =  \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__DEPENDENCIES_4)\nam__libtcmalloc_minimal_debug_la_SOURCES_DIST =  \\\n\tsrc/debugallocation.cc src/common.h src/internal_logging.h \\\n\tsrc/system-alloc.h src/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h\n@WITH_DEBUGALLOC_TRUE@am_libtcmalloc_minimal_debug_la_OBJECTS = libtcmalloc_minimal_debug_la-debugallocation.lo \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__objects_20)\nlibtcmalloc_minimal_debug_la_OBJECTS =  \\\n\t$(am_libtcmalloc_minimal_debug_la_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@am_libtcmalloc_minimal_debug_la_rpath = -rpath \\\n@WITH_DEBUGALLOC_TRUE@\t$(libdir)\nlibtcmalloc_minimal_internal_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \\\n\t$(am__DEPENDENCIES_2)\nam__libtcmalloc_minimal_internal_la_SOURCES_DIST = src/common.cc \\\n\tsrc/internal_logging.cc src/system-alloc.cc \\\n\tsrc/memfs_malloc.cc src/central_freelist.cc src/page_heap.cc \\\n\tsrc/sampler.cc src/span.cc src/stack_trace_table.cc \\\n\tsrc/static_vars.cc src/symbolize.cc src/thread_cache.cc \\\n\tsrc/malloc_hook.cc src/malloc_extension.cc \\\n\tsrc/maybe_threads.cc src/common.h src/internal_logging.h \\\n\tsrc/system-alloc.h src/packed-cache-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/tcmalloc_guard.h \\\n\tsrc/base/commandlineflags.h src/base/basictypes.h \\\n\tsrc/pagemap.h src/sampler.h src/central_freelist.h \\\n\tsrc/linked_list.h src/page_heap.h src/page_heap_allocator.h \\\n\tsrc/span.h src/static_vars.h src/symbolize.h \\\n\tsrc/thread_cache.h src/stack_trace_table.h \\\n\tsrc/base/thread_annotations.h src/malloc_hook-inl.h \\\n\tsrc/maybe_threads.h src/google/malloc_hook.h \\\n\tsrc/google/malloc_hook_c.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h src/google/stacktrace.h\n@MINGW_FALSE@am__objects_23 =  \\\n@MINGW_FALSE@\tlibtcmalloc_minimal_internal_la-system-alloc.lo\n@MINGW_FALSE@am__objects_24 =  \\\n@MINGW_FALSE@\tlibtcmalloc_minimal_internal_la-maybe_threads.lo\nam_libtcmalloc_minimal_internal_la_OBJECTS =  \\\n\tlibtcmalloc_minimal_internal_la-common.lo \\\n\tlibtcmalloc_minimal_internal_la-internal_logging.lo \\\n\t$(am__objects_23) \\\n\tlibtcmalloc_minimal_internal_la-memfs_malloc.lo \\\n\tlibtcmalloc_minimal_internal_la-central_freelist.lo \\\n\tlibtcmalloc_minimal_internal_la-page_heap.lo \\\n\tlibtcmalloc_minimal_internal_la-sampler.lo \\\n\tlibtcmalloc_minimal_internal_la-span.lo \\\n\tlibtcmalloc_minimal_internal_la-stack_trace_table.lo \\\n\tlibtcmalloc_minimal_internal_la-static_vars.lo \\\n\tlibtcmalloc_minimal_internal_la-symbolize.lo \\\n\tlibtcmalloc_minimal_internal_la-thread_cache.lo \\\n\tlibtcmalloc_minimal_internal_la-malloc_hook.lo \\\n\tlibtcmalloc_minimal_internal_la-malloc_extension.lo \\\n\t$(am__objects_24) $(am__objects_20)\nlibtcmalloc_minimal_internal_la_OBJECTS =  \\\n\t$(am_libtcmalloc_minimal_internal_la_OBJECTS)\nlibwindows_la_DEPENDENCIES =\nam__libwindows_la_SOURCES_DIST = src/windows/port.h \\\n\tsrc/windows/mingw.h src/windows/mini_disassembler.h \\\n\tsrc/windows/mini_disassembler_types.h \\\n\tsrc/windows/preamble_patcher.h src/windows/port.cc \\\n\tsrc/windows/ia32_modrm_map.cc src/windows/ia32_opcode_map.cc \\\n\tsrc/windows/mini_disassembler.cc \\\n\tsrc/windows/patch_functions.cc src/windows/preamble_patcher.cc \\\n\tsrc/windows/preamble_patcher_with_stub.cc\n@MINGW_TRUE@am_libwindows_la_OBJECTS = $(am__objects_1) port.lo \\\n@MINGW_TRUE@\tia32_modrm_map.lo ia32_opcode_map.lo \\\n@MINGW_TRUE@\tmini_disassembler.lo patch_functions.lo \\\n@MINGW_TRUE@\tpreamble_patcher.lo preamble_patcher_with_stub.lo\nlibwindows_la_OBJECTS = $(am_libwindows_la_OBJECTS)\n@MINGW_TRUE@am_libwindows_la_rpath =\nbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)\n@WITH_DEBUGALLOC_TRUE@am__EXEEXT_1 = debugallocation_test$(EXEEXT)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__EXEEXT_2 =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampling_test$(EXEEXT)\n@WITH_HEAP_PROFILER_TRUE@am__EXEEXT_3 =  \\\n@WITH_HEAP_PROFILER_TRUE@\theap-profiler_unittest$(EXEEXT)\n@WITH_HEAP_CHECKER_TRUE@am__EXEEXT_4 = heap-checker_unittest$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__EXEEXT_5 = sampling_debug_test$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__EXEEXT_6 = heap-profiler_debug_unittest$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__EXEEXT_7 = heap-checker_debug_unittest$(EXEEXT)\n@WITH_CPU_PROFILER_TRUE@am__EXEEXT_8 = profiler1_unittest$(EXEEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler2_unittest$(EXEEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler3_unittest$(EXEEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler4_unittest$(EXEEXT)\n@WITH_STACK_TRACE_TRUE@am__EXEEXT_9 = stacktrace_unittest$(EXEEXT)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__EXEEXT_10 = maybe_threads_unittest.sh$(EXEEXT)\n@MINGW_FALSE@am__EXEEXT_11 = system_alloc_unittest$(EXEEXT)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__EXEEXT_12 = malloc_extension_c_test$(EXEEXT)\n@MINGW_FALSE@am__EXEEXT_13 = memalign_unittest$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@am__EXEEXT_14 = tcmalloc_minimal_debug_unittest$(EXEEXT) \\\n@WITH_DEBUGALLOC_TRUE@\tmalloc_extension_debug_test$(EXEEXT) \\\n@WITH_DEBUGALLOC_TRUE@\tmemalign_debug_unittest$(EXEEXT) \\\n@WITH_DEBUGALLOC_TRUE@\trealloc_debug_unittest$(EXEEXT) \\\n@WITH_DEBUGALLOC_TRUE@\tdebugallocation_test.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__EXEEXT_15 = tcmalloc_unittest$(EXEEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_both_unittest$(EXEEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_large_unittest$(EXEEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\traw_printer_test$(EXEEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampler_test$(EXEEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampling_test.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_TRUE@am__EXEEXT_16 =  \\\n@WITH_HEAP_PROFILER_TRUE@\theap-profiler_unittest.sh$(EXEEXT)\n@WITH_HEAP_CHECKER_TRUE@am__EXEEXT_17 =  \\\n@WITH_HEAP_CHECKER_TRUE@\theap-checker_unittest.sh$(EXEEXT) \\\n@WITH_HEAP_CHECKER_TRUE@\theap-checker-death_unittest.sh$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__EXEEXT_18 = tcmalloc_debug_unittest$(EXEEXT) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampler_debug_test$(EXEEXT) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tsampling_debug_test.sh$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__EXEEXT_19 = heap-profiler_debug_unittest.sh$(EXEEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__EXEEXT_20 = heap-checker_debug_unittest.sh$(EXEEXT)\n@WITH_CPU_PROFILER_TRUE@am__EXEEXT_21 = getpc_test$(EXEEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiledata_unittest$(EXEEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofile_handler_unittest$(EXEEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler_unittest.sh$(EXEEXT)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__EXEEXT_22 = tcmalloc_and_profiler_unittest$(EXEEXT)\nam__EXEEXT_23 = low_level_alloc_unittest$(EXEEXT) \\\n\tatomicops_unittest$(EXEEXT) $(am__EXEEXT_9) \\\n\ttcmalloc_minimal_unittest$(EXEEXT) \\\n\ttcmalloc_minimal_large_unittest$(EXEEXT) $(am__EXEEXT_10) \\\n\taddressmap_unittest$(EXEEXT) $(am__EXEEXT_11) \\\n\tpacked_cache_test$(EXEEXT) frag_unittest$(EXEEXT) \\\n\tmarkidle_unittest$(EXEEXT) malloc_extension_test$(EXEEXT) \\\n\t$(am__EXEEXT_12) $(am__EXEEXT_13) page_heap_test$(EXEEXT) \\\n\tpagemap_unittest$(EXEEXT) realloc_unittest$(EXEEXT) \\\n\tstack_trace_table_test$(EXEEXT) \\\n\tthread_dealloc_unittest$(EXEEXT) $(am__EXEEXT_14) \\\n\t$(am__EXEEXT_15) $(am__EXEEXT_16) $(am__EXEEXT_17) \\\n\t$(am__EXEEXT_18) $(am__EXEEXT_19) $(am__EXEEXT_20) \\\n\t$(am__EXEEXT_21) $(am__EXEEXT_22)\nPROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)\nam__addressmap_unittest_SOURCES_DIST =  \\\n\tsrc/tests/addressmap_unittest.cc src/addressmap-inl.h \\\n\tsrc/base/commandlineflags.h src/base/logging.h \\\n\tsrc/base/basictypes.h src/base/dynamic_annotations.h \\\n\tsrc/third_party/valgrind.h src/windows/port.h \\\n\tsrc/windows/port.cc\n@MINGW_TRUE@am__objects_25 = addressmap_unittest-port.$(OBJEXT)\nam_addressmap_unittest_OBJECTS =  \\\n\taddressmap_unittest-addressmap_unittest.$(OBJEXT) \\\n\t$(am__objects_6) $(am__objects_25)\naddressmap_unittest_OBJECTS = $(am_addressmap_unittest_OBJECTS)\naddressmap_unittest_DEPENDENCIES = liblogging.la\nam_atomicops_unittest_OBJECTS = atomicops_unittest.$(OBJEXT) \\\n\t$(am__objects_6)\natomicops_unittest_OBJECTS = $(am_atomicops_unittest_OBJECTS)\natomicops_unittest_DEPENDENCIES = $(am__DEPENDENCIES_2)\nam__debugallocation_test_SOURCES_DIST =  \\\n\tsrc/tests/debugallocation_test.cc\n@WITH_DEBUGALLOC_TRUE@am_debugallocation_test_OBJECTS = debugallocation_test-debugallocation_test.$(OBJEXT)\ndebugallocation_test_OBJECTS = $(am_debugallocation_test_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@debugallocation_test_DEPENDENCIES =  \\\n@WITH_DEBUGALLOC_TRUE@\tlibtcmalloc_debug.la \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__DEPENDENCIES_1)\nam__debugallocation_test_sh_SOURCES_DIST =  \\\n\tsrc/tests/debugallocation_test.sh\nam_debugallocation_test_sh_OBJECTS =\ndebugallocation_test_sh_OBJECTS =  \\\n\t$(am_debugallocation_test_sh_OBJECTS)\ndebugallocation_test_sh_LDADD = $(LDADD)\nam_frag_unittest_OBJECTS = frag_unittest-frag_unittest.$(OBJEXT)\nfrag_unittest_OBJECTS = $(am_frag_unittest_OBJECTS)\n@MINGW_FALSE@am__DEPENDENCIES_5 = libtcmalloc_minimal.la\n@MINGW_TRUE@am__DEPENDENCIES_5 = libtcmalloc_minimal.la \\\n@MINGW_TRUE@\tlibstacktrace.la\nfrag_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam__getpc_test_SOURCES_DIST = src/tests/getpc_test.cc src/getpc.h\n@WITH_CPU_PROFILER_TRUE@am_getpc_test_OBJECTS = getpc_test.$(OBJEXT)\ngetpc_test_OBJECTS = $(am_getpc_test_OBJECTS)\ngetpc_test_LDADD = $(LDADD)\nam__heap_checker_death_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/heap-checker-death_unittest.sh\nam_heap_checker_death_unittest_sh_OBJECTS =\nheap_checker_death_unittest_sh_OBJECTS =  \\\n\t$(am_heap_checker_death_unittest_sh_OBJECTS)\nheap_checker_death_unittest_sh_LDADD = $(LDADD)\nam__heap_checker_debug_unittest_SOURCES_DIST =  \\\n\tsrc/tests/heap-checker_unittest.cc src/config_for_unittests.h \\\n\tsrc/memory_region_map.h src/base/commandlineflags.h \\\n\tsrc/base/googleinit.h src/google/heap-checker.h \\\n\tsrc/base/logging.h src/base/basictypes.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h\n@WITH_HEAP_CHECKER_TRUE@am__objects_26 = $(am__objects_1)\n@WITH_HEAP_CHECKER_TRUE@am__objects_27 = heap_checker_debug_unittest-heap-checker_unittest.$(OBJEXT) \\\n@WITH_HEAP_CHECKER_TRUE@\t$(am__objects_26)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am_heap_checker_debug_unittest_OBJECTS = $(am__objects_27)\nheap_checker_debug_unittest_OBJECTS =  \\\n\t$(am_heap_checker_debug_unittest_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap_checker_debug_unittest_DEPENDENCIES = libtcmalloc_debug.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@\tliblogging.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__heap_checker_debug_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/heap-checker_unittest.sh\nam_heap_checker_debug_unittest_sh_OBJECTS =\nheap_checker_debug_unittest_sh_OBJECTS =  \\\n\t$(am_heap_checker_debug_unittest_sh_OBJECTS)\nheap_checker_debug_unittest_sh_LDADD = $(LDADD)\nam__heap_checker_unittest_SOURCES_DIST =  \\\n\tsrc/tests/heap-checker_unittest.cc src/config_for_unittests.h \\\n\tsrc/memory_region_map.h src/base/commandlineflags.h \\\n\tsrc/base/googleinit.h src/google/heap-checker.h \\\n\tsrc/base/logging.h src/base/basictypes.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h\n@WITH_HEAP_CHECKER_TRUE@am_heap_checker_unittest_OBJECTS = heap_checker_unittest-heap-checker_unittest.$(OBJEXT) \\\n@WITH_HEAP_CHECKER_TRUE@\t$(am__objects_26)\nheap_checker_unittest_OBJECTS = $(am_heap_checker_unittest_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__DEPENDENCIES_6 =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibtcmalloc.la\n@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_DEPENDENCIES =  \\\n@WITH_HEAP_CHECKER_TRUE@\t$(am__DEPENDENCIES_6) liblogging.la \\\n@WITH_HEAP_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__heap_checker_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/heap-checker_unittest.sh\nam_heap_checker_unittest_sh_OBJECTS =\nheap_checker_unittest_sh_OBJECTS =  \\\n\t$(am_heap_checker_unittest_sh_OBJECTS)\nheap_checker_unittest_sh_LDADD = $(LDADD)\nam__heap_profiler_debug_unittest_SOURCES_DIST =  \\\n\tsrc/tests/heap-profiler_unittest.cc src/config_for_unittests.h \\\n\tsrc/google/heap-profiler.h\n@WITH_HEAP_PROFILER_TRUE@am__objects_28 = heap_profiler_debug_unittest-heap-profiler_unittest.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am_heap_profiler_debug_unittest_OBJECTS = $(am__objects_28)\nheap_profiler_debug_unittest_OBJECTS =  \\\n\t$(am_heap_profiler_debug_unittest_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap_profiler_debug_unittest_DEPENDENCIES = libtcmalloc_debug.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@\t$(am__DEPENDENCIES_1)\nam__heap_profiler_debug_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/heap-profiler_unittest.sh\nam_heap_profiler_debug_unittest_sh_OBJECTS =\nheap_profiler_debug_unittest_sh_OBJECTS =  \\\n\t$(am_heap_profiler_debug_unittest_sh_OBJECTS)\nheap_profiler_debug_unittest_sh_LDADD = $(LDADD)\nam__heap_profiler_unittest_SOURCES_DIST =  \\\n\tsrc/tests/heap-profiler_unittest.cc src/config_for_unittests.h \\\n\tsrc/google/heap-profiler.h\n@WITH_HEAP_PROFILER_TRUE@am_heap_profiler_unittest_OBJECTS = heap_profiler_unittest-heap-profiler_unittest.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_TRUE@\t$(am__objects_1)\nheap_profiler_unittest_OBJECTS = $(am_heap_profiler_unittest_OBJECTS)\n@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_TRUE@\t$(am__DEPENDENCIES_6) \\\n@WITH_HEAP_PROFILER_TRUE@\t$(am__DEPENDENCIES_1)\nam__heap_profiler_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/heap-profiler_unittest.sh\nam_heap_profiler_unittest_sh_OBJECTS =\nheap_profiler_unittest_sh_OBJECTS =  \\\n\t$(am_heap_profiler_unittest_sh_OBJECTS)\nheap_profiler_unittest_sh_LDADD = $(LDADD)\nam__low_level_alloc_unittest_SOURCES_DIST =  \\\n\tsrc/base/low_level_alloc.cc src/malloc_hook.cc \\\n\tsrc/tests/low_level_alloc_unittest.cc \\\n\tsrc/base/low_level_alloc.h src/base/basictypes.h \\\n\tsrc/google/malloc_hook.h src/google/malloc_hook_c.h \\\n\tsrc/malloc_hook-inl.h src/base/spinlock.h \\\n\tsrc/base/spinlock_internal.h src/base/atomicops.h \\\n\tsrc/base/atomicops-internals-macosx.h \\\n\tsrc/base/atomicops-internals-linuxppc.h \\\n\tsrc/base/atomicops-internals-x86-msvc.h \\\n\tsrc/base/atomicops-internals-x86.h \\\n\tsrc/base/spinlock_win32-inl.h src/base/spinlock_linux-inl.h \\\n\tsrc/base/spinlock_posix-inl.h \\\n\tsrc/base/synchronization_profiling.h \\\n\tsrc/base/atomicops-internals-arm-gcc.h src/base/logging.h \\\n\tsrc/base/commandlineflags.h src/base/dynamic_annotations.h \\\n\tsrc/third_party/valgrind.h\nam__objects_29 = $(am__objects_1) $(am__objects_1)\nam_low_level_alloc_unittest_OBJECTS =  \\\n\tlow_level_alloc_unittest-low_level_alloc.$(OBJEXT) \\\n\tlow_level_alloc_unittest-malloc_hook.$(OBJEXT) \\\n\tlow_level_alloc_unittest-low_level_alloc_unittest.$(OBJEXT) \\\n\t$(am__objects_29)\nlow_level_alloc_unittest_OBJECTS =  \\\n\t$(am_low_level_alloc_unittest_OBJECTS)\nlow_level_alloc_unittest_DEPENDENCIES = $(am__DEPENDENCIES_2)\nam__malloc_extension_c_test_SOURCES_DIST =  \\\n\tsrc/tests/malloc_extension_c_test.c \\\n\tsrc/google/malloc_extension.h src/google/malloc_extension_c.h\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@am_malloc_extension_c_test_OBJECTS = malloc_extension_c_test-malloc_extension_c_test.$(OBJEXT)\nmalloc_extension_c_test_OBJECTS =  \\\n\t$(am_malloc_extension_c_test_OBJECTS)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_DEPENDENCIES =  \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\t$(am__DEPENDENCIES_5) \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\t$(am__DEPENDENCIES_1)\nam__malloc_extension_debug_test_SOURCES_DIST =  \\\n\tsrc/tests/malloc_extension_test.cc src/config_for_unittests.h \\\n\tsrc/base/logging.h src/google/malloc_extension.h \\\n\tsrc/google/malloc_extension_c.h\nam__objects_30 =  \\\n\tmalloc_extension_debug_test-malloc_extension_test.$(OBJEXT)\n@WITH_DEBUGALLOC_TRUE@am_malloc_extension_debug_test_OBJECTS =  \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__objects_30)\nmalloc_extension_debug_test_OBJECTS =  \\\n\t$(am_malloc_extension_debug_test_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@malloc_extension_debug_test_DEPENDENCIES =  \\\n@WITH_DEBUGALLOC_TRUE@\tlibtcmalloc_minimal_debug.la \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__DEPENDENCIES_1)\nam_malloc_extension_test_OBJECTS =  \\\n\tmalloc_extension_test-malloc_extension_test.$(OBJEXT)\nmalloc_extension_test_OBJECTS = $(am_malloc_extension_test_OBJECTS)\nmalloc_extension_test_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam_markidle_unittest_OBJECTS =  \\\n\tmarkidle_unittest-markidle_unittest.$(OBJEXT) \\\n\tmarkidle_unittest-testutil.$(OBJEXT)\nmarkidle_unittest_OBJECTS = $(am_markidle_unittest_OBJECTS)\nmarkidle_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam__maybe_threads_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/maybe_threads_unittest.sh\nam_maybe_threads_unittest_sh_OBJECTS =\nmaybe_threads_unittest_sh_OBJECTS =  \\\n\t$(am_maybe_threads_unittest_sh_OBJECTS)\nmaybe_threads_unittest_sh_LDADD = $(LDADD)\nam__memalign_debug_unittest_SOURCES_DIST =  \\\n\tsrc/tests/memalign_unittest.cc src/tcmalloc.h \\\n\tsrc/config_for_unittests.h src/tests/testutil.h \\\n\tsrc/tests/testutil.cc\n@MINGW_FALSE@am__objects_31 = memalign_debug_unittest-memalign_unittest.$(OBJEXT) \\\n@MINGW_FALSE@\tmemalign_debug_unittest-testutil.$(OBJEXT)\n@WITH_DEBUGALLOC_TRUE@am_memalign_debug_unittest_OBJECTS =  \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__objects_31)\nmemalign_debug_unittest_OBJECTS =  \\\n\t$(am_memalign_debug_unittest_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@memalign_debug_unittest_DEPENDENCIES =  \\\n@WITH_DEBUGALLOC_TRUE@\tlibtcmalloc_minimal_debug.la \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__DEPENDENCIES_1)\nam__memalign_unittest_SOURCES_DIST = src/tests/memalign_unittest.cc \\\n\tsrc/tcmalloc.h src/config_for_unittests.h src/tests/testutil.h \\\n\tsrc/tests/testutil.cc\n@MINGW_FALSE@am_memalign_unittest_OBJECTS =  \\\n@MINGW_FALSE@\tmemalign_unittest-memalign_unittest.$(OBJEXT) \\\n@MINGW_FALSE@\tmemalign_unittest-testutil.$(OBJEXT)\nmemalign_unittest_OBJECTS = $(am_memalign_unittest_OBJECTS)\n@MINGW_FALSE@memalign_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n@MINGW_FALSE@\t$(am__DEPENDENCIES_1)\nam_packed_cache_test_OBJECTS =  \\\n\tpacked_cache_test-packed-cache_test.$(OBJEXT)\npacked_cache_test_OBJECTS = $(am_packed_cache_test_OBJECTS)\npacked_cache_test_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam_page_heap_test_OBJECTS = page_heap_test-page_heap_test.$(OBJEXT)\npage_heap_test_OBJECTS = $(am_page_heap_test_OBJECTS)\npage_heap_test_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam_pagemap_unittest_OBJECTS =  \\\n\tpagemap_unittest-pagemap_unittest.$(OBJEXT)\npagemap_unittest_OBJECTS = $(am_pagemap_unittest_OBJECTS)\npagemap_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam__profile_handler_unittest_SOURCES_DIST =  \\\n\tsrc/tests/profile-handler_unittest.cc src/profile-handler.h\n@WITH_CPU_PROFILER_TRUE@am_profile_handler_unittest_OBJECTS = profile_handler_unittest-profile-handler_unittest.$(OBJEXT)\nprofile_handler_unittest_OBJECTS =  \\\n\t$(am_profile_handler_unittest_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@am__DEPENDENCIES_7 = libstacktrace.la \\\n@WITH_CPU_PROFILER_TRUE@\tlibprofiler.la\n@WITH_CPU_PROFILER_TRUE@profile_handler_unittest_DEPENDENCIES =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__DEPENDENCIES_7) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__DEPENDENCIES_1)\nam__profiledata_unittest_SOURCES_DIST =  \\\n\tsrc/tests/profiledata_unittest.cc src/profiledata.h \\\n\tsrc/base/commandlineflags.h src/base/logging.h \\\n\tsrc/base/basictypes.h\n@WITH_CPU_PROFILER_TRUE@am_profiledata_unittest_OBJECTS =  \\\n@WITH_CPU_PROFILER_TRUE@\tprofiledata_unittest.$(OBJEXT)\nprofiledata_unittest_OBJECTS = $(am_profiledata_unittest_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@profiledata_unittest_DEPENDENCIES =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__DEPENDENCIES_7)\nam__profiler1_unittest_SOURCES_DIST = src/tests/profiler_unittest.cc \\\n\tsrc/tests/testutil.h src/tests/testutil.cc \\\n\tsrc/config_for_unittests.h src/google/profiler.h\n@WITH_CPU_PROFILER_TRUE@am__objects_32 = profiler1_unittest-profiler_unittest.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler1_unittest-testutil.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@am_profiler1_unittest_OBJECTS =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_32)\nprofiler1_unittest_OBJECTS = $(am_profiler1_unittest_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@profiler1_unittest_DEPENDENCIES =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__DEPENDENCIES_7)\nam__profiler2_unittest_SOURCES_DIST = src/tests/profiler_unittest.cc \\\n\tsrc/tests/testutil.h src/tests/testutil.cc \\\n\tsrc/config_for_unittests.h src/google/profiler.h\n@WITH_CPU_PROFILER_TRUE@am__objects_33 = profiler2_unittest-profiler_unittest.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler2_unittest-testutil.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@am_profiler2_unittest_OBJECTS =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_33)\nprofiler2_unittest_OBJECTS = $(am_profiler2_unittest_OBJECTS)\nam__profiler3_unittest_SOURCES_DIST = src/tests/profiler_unittest.cc \\\n\tsrc/tests/testutil.h src/tests/testutil.cc \\\n\tsrc/config_for_unittests.h src/google/profiler.h\n@WITH_CPU_PROFILER_TRUE@am__objects_34 = profiler3_unittest-profiler_unittest.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler3_unittest-testutil.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@am_profiler3_unittest_OBJECTS =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_34)\nprofiler3_unittest_OBJECTS = $(am_profiler3_unittest_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@profiler3_unittest_DEPENDENCIES =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__DEPENDENCIES_7) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__DEPENDENCIES_1)\nam__profiler4_unittest_SOURCES_DIST = src/tests/profiler_unittest.cc \\\n\tsrc/tests/testutil.h src/tests/testutil.cc \\\n\tsrc/config_for_unittests.h src/google/profiler.h\n@WITH_CPU_PROFILER_TRUE@am__objects_35 = profiler4_unittest-profiler_unittest.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\tprofiler4_unittest-testutil.$(OBJEXT) \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@am_profiler4_unittest_OBJECTS =  \\\n@WITH_CPU_PROFILER_TRUE@\t$(am__objects_35)\nprofiler4_unittest_OBJECTS = $(am_profiler4_unittest_OBJECTS)\nam__profiler_unittest_sh_SOURCES_DIST =  \\\n\tsrc/tests/profiler_unittest.sh\nam_profiler_unittest_sh_OBJECTS =\nprofiler_unittest_sh_OBJECTS = $(am_profiler_unittest_sh_OBJECTS)\nprofiler_unittest_sh_LDADD = $(LDADD)\nam__raw_printer_test_SOURCES_DIST = src/tests/raw_printer_test.cc\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_raw_printer_test_OBJECTS = raw_printer_test-raw_printer_test.$(OBJEXT)\nraw_printer_test_OBJECTS = $(am_raw_printer_test_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@raw_printer_test_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_6) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__realloc_debug_unittest_SOURCES_DIST =  \\\n\tsrc/tests/realloc_unittest.cc src/config_for_unittests.h \\\n\tsrc/base/logging.h\nam__objects_36 = realloc_debug_unittest-realloc_unittest.$(OBJEXT)\n@WITH_DEBUGALLOC_TRUE@am_realloc_debug_unittest_OBJECTS =  \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__objects_36)\nrealloc_debug_unittest_OBJECTS = $(am_realloc_debug_unittest_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@realloc_debug_unittest_DEPENDENCIES =  \\\n@WITH_DEBUGALLOC_TRUE@\tlibtcmalloc_minimal_debug.la \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__DEPENDENCIES_1)\nam_realloc_unittest_OBJECTS =  \\\n\trealloc_unittest-realloc_unittest.$(OBJEXT)\nrealloc_unittest_OBJECTS = $(am_realloc_unittest_OBJECTS)\nrealloc_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam__sampler_debug_test_SOURCES_DIST = src/tests/sampler_test.cc \\\n\tsrc/config_for_unittests.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_37 = sampler_debug_test-sampler_test.$(OBJEXT)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_sampler_debug_test_OBJECTS = $(am__objects_37)\nsampler_debug_test_OBJECTS = $(am_sampler_debug_test_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_debug_test_DEPENDENCIES = libtcmalloc_debug.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__sampler_test_SOURCES_DIST = src/tests/sampler_test.cc \\\n\tsrc/config_for_unittests.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_sampler_test_OBJECTS = sampler_test-sampler_test.$(OBJEXT)\nsampler_test_OBJECTS = $(am_sampler_test_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_test_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_6) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__sampling_debug_test_SOURCES_DIST = src/tests/sampling_test.cc \\\n\tsrc/config_for_unittests.h src/base/logging.h \\\n\tsrc/google/malloc_extension.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_38 = sampling_debug_test-sampling_test.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_sampling_debug_test_OBJECTS = $(am__objects_38)\nsampling_debug_test_OBJECTS = $(am_sampling_debug_test_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test_DEPENDENCIES = libtcmalloc_debug.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__sampling_debug_test_sh_SOURCES_DIST = src/tests/sampling_test.sh\nam_sampling_debug_test_sh_OBJECTS =\nsampling_debug_test_sh_OBJECTS = $(am_sampling_debug_test_sh_OBJECTS)\nsampling_debug_test_sh_LDADD = $(LDADD)\nam__sampling_test_SOURCES_DIST = src/tests/sampling_test.cc \\\n\tsrc/config_for_unittests.h src/base/logging.h \\\n\tsrc/google/malloc_extension.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_sampling_test_OBJECTS = sampling_test-sampling_test.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\nsampling_test_OBJECTS = $(am_sampling_test_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_6) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__sampling_test_sh_SOURCES_DIST = src/tests/sampling_test.sh\nam_sampling_test_sh_OBJECTS =\nsampling_test_sh_OBJECTS = $(am_sampling_test_sh_OBJECTS)\nsampling_test_sh_LDADD = $(LDADD)\nam_stack_trace_table_test_OBJECTS =  \\\n\tstack_trace_table_test-stack_trace_table_test.$(OBJEXT)\nstack_trace_table_test_OBJECTS = $(am_stack_trace_table_test_OBJECTS)\nstack_trace_table_test_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam__stacktrace_unittest_SOURCES_DIST =  \\\n\tsrc/tests/stacktrace_unittest.cc src/config_for_unittests.h \\\n\tsrc/base/commandlineflags.h src/stacktrace_config.h \\\n\tsrc/stacktrace_generic-inl.h src/stacktrace_libunwind-inl.h \\\n\tsrc/stacktrace_powerpc-inl.h src/stacktrace_x86_64-inl.h \\\n\tsrc/stacktrace_x86-inl.h src/stacktrace_win32-inl.h \\\n\tsrc/base/vdso_support.h src/google/stacktrace.h \\\n\tsrc/base/logging.h src/base/basictypes.h \\\n\tsrc/base/dynamic_annotations.h src/third_party/valgrind.h\n@WITH_STACK_TRACE_TRUE@am__objects_39 = $(am__objects_4) \\\n@WITH_STACK_TRACE_TRUE@\t$(am__objects_1)\n@WITH_STACK_TRACE_TRUE@am_stacktrace_unittest_OBJECTS =  \\\n@WITH_STACK_TRACE_TRUE@\tstacktrace_unittest.$(OBJEXT) \\\n@WITH_STACK_TRACE_TRUE@\t$(am__objects_39)\nstacktrace_unittest_OBJECTS = $(am_stacktrace_unittest_OBJECTS)\n@WITH_STACK_TRACE_TRUE@stacktrace_unittest_DEPENDENCIES =  \\\n@WITH_STACK_TRACE_TRUE@\tlibstacktrace.la liblogging.la\nam__system_alloc_unittest_SOURCES_DIST = src/config_for_unittests.h \\\n\tsrc/tests/system-alloc_unittest.cc\n@MINGW_FALSE@am_system_alloc_unittest_OBJECTS = system_alloc_unittest-system-alloc_unittest.$(OBJEXT)\nsystem_alloc_unittest_OBJECTS = $(am_system_alloc_unittest_OBJECTS)\n@MINGW_FALSE@system_alloc_unittest_DEPENDENCIES =  \\\n@MINGW_FALSE@\t$(am__DEPENDENCIES_5) $(am__DEPENDENCIES_1)\nam__tcmalloc_and_profiler_unittest_SOURCES_DIST =  \\\n\tsrc/tests/tcmalloc_unittest.cc src/tests/testutil.h \\\n\tsrc/tests/testutil.cc src/config_for_unittests.h \\\n\tsrc/google/malloc_extension.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_40 = tcmalloc_and_profiler_unittest-tcmalloc_unittest.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_and_profiler_unittest-testutil.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_tcmalloc_and_profiler_unittest_OBJECTS = $(am__objects_40)\ntcmalloc_and_profiler_unittest_OBJECTS =  \\\n\t$(am_tcmalloc_and_profiler_unittest_OBJECTS)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_and_profiler_unittest_DEPENDENCIES = libtcmalloc_and_profiler.la\nam__tcmalloc_both_unittest_SOURCES_DIST =  \\\n\tsrc/tests/tcmalloc_unittest.cc src/tests/testutil.h \\\n\tsrc/tests/testutil.cc src/config_for_unittests.h \\\n\tsrc/google/malloc_extension.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_tcmalloc_both_unittest_OBJECTS = tcmalloc_both_unittest-tcmalloc_unittest.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_both_unittest-testutil.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\ntcmalloc_both_unittest_OBJECTS = $(am_tcmalloc_both_unittest_OBJECTS)\n@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_DEPENDENCIES = $(am__DEPENDENCIES_6) \\\n@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_5) \\\n@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tliblogging.la \\\n@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_DEPENDENCIES = $(am__DEPENDENCIES_6) \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_5) \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tlibprofiler.la \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tliblogging.la \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__tcmalloc_debug_unittest_SOURCES_DIST =  \\\n\tsrc/tests/tcmalloc_unittest.cc src/tcmalloc.h \\\n\tsrc/tests/testutil.h src/tests/testutil.cc \\\n\tsrc/config_for_unittests.h src/google/malloc_extension.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__objects_41 = tcmalloc_debug_unittest-tcmalloc_unittest.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_debug_unittest-testutil.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_tcmalloc_debug_unittest_OBJECTS = $(am__objects_41)\ntcmalloc_debug_unittest_OBJECTS =  \\\n\t$(am_tcmalloc_debug_unittest_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_debug_unittest_DEPENDENCIES = libtcmalloc_debug.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__tcmalloc_large_unittest_SOURCES_DIST =  \\\n\tsrc/tests/tcmalloc_large_unittest.cc\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_tcmalloc_large_unittest_OBJECTS = tcmalloc_large_unittest-tcmalloc_large_unittest.$(OBJEXT)\ntcmalloc_large_unittest_OBJECTS =  \\\n\t$(am_tcmalloc_large_unittest_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_6) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam__tcmalloc_minimal_debug_unittest_SOURCES_DIST =  \\\n\tsrc/tests/tcmalloc_unittest.cc src/tests/testutil.h \\\n\tsrc/tests/testutil.cc src/config_for_unittests.h \\\n\tsrc/google/malloc_extension.h\nam__objects_42 =  \\\n\ttcmalloc_minimal_debug_unittest-tcmalloc_unittest.$(OBJEXT) \\\n\ttcmalloc_minimal_debug_unittest-testutil.$(OBJEXT) \\\n\t$(am__objects_1)\n@WITH_DEBUGALLOC_TRUE@am_tcmalloc_minimal_debug_unittest_OBJECTS =  \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__objects_42)\ntcmalloc_minimal_debug_unittest_OBJECTS =  \\\n\t$(am_tcmalloc_minimal_debug_unittest_OBJECTS)\n@WITH_DEBUGALLOC_TRUE@tcmalloc_minimal_debug_unittest_DEPENDENCIES =  \\\n@WITH_DEBUGALLOC_TRUE@\tlibtcmalloc_minimal_debug.la \\\n@WITH_DEBUGALLOC_TRUE@\t$(am__DEPENDENCIES_1)\nam_tcmalloc_minimal_large_unittest_OBJECTS = tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.$(OBJEXT)\ntcmalloc_minimal_large_unittest_OBJECTS =  \\\n\t$(am_tcmalloc_minimal_large_unittest_OBJECTS)\ntcmalloc_minimal_large_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nam__tcmalloc_minimal_unittest_SOURCES_DIST =  \\\n\tsrc/tests/tcmalloc_unittest.cc src/tests/testutil.h \\\n\tsrc/tests/testutil.cc src/config_for_unittests.h \\\n\tsrc/google/malloc_extension.h\nam_tcmalloc_minimal_unittest_OBJECTS =  \\\n\ttcmalloc_minimal_unittest-tcmalloc_unittest.$(OBJEXT) \\\n\ttcmalloc_minimal_unittest-testutil.$(OBJEXT) $(am__objects_1)\ntcmalloc_minimal_unittest_OBJECTS =  \\\n\t$(am_tcmalloc_minimal_unittest_OBJECTS)\ntcmalloc_minimal_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\tliblogging.la $(am__DEPENDENCIES_1)\nam__tcmalloc_unittest_SOURCES_DIST = src/tests/tcmalloc_unittest.cc \\\n\tsrc/tcmalloc.h src/tests/testutil.h src/tests/testutil.cc \\\n\tsrc/config_for_unittests.h src/google/malloc_extension.h\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am_tcmalloc_unittest_OBJECTS = tcmalloc_unittest-tcmalloc_unittest.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\ttcmalloc_unittest-testutil.$(OBJEXT) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__objects_1)\ntcmalloc_unittest_OBJECTS = $(am_tcmalloc_unittest_OBJECTS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_DEPENDENCIES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_6) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tliblogging.la \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__DEPENDENCIES_1)\nam_thread_dealloc_unittest_OBJECTS =  \\\n\tthread_dealloc_unittest-thread_dealloc_unittest.$(OBJEXT) \\\n\tthread_dealloc_unittest-testutil.$(OBJEXT)\nthread_dealloc_unittest_OBJECTS =  \\\n\t$(am_thread_dealloc_unittest_OBJECTS)\nthread_dealloc_unittest_DEPENDENCIES = $(am__DEPENDENCIES_5) \\\n\t$(am__DEPENDENCIES_1)\nbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)\nSCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS)\nDEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src\ndepcomp = $(SHELL) $(top_srcdir)/depcomp\nam__depfiles_maybe = depfiles\nCOMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \\\n\t$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)\nLTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \\\n\t$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \\\n\t$(AM_CFLAGS) $(CFLAGS)\nCCLD = $(CC)\nLINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \\\n\t$(AM_LDFLAGS) $(LDFLAGS) -o $@\nCXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \\\n\t$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)\nLTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \\\n\t$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \\\n\t$(AM_CXXFLAGS) $(CXXFLAGS)\nCXXLD = $(CXX)\nCXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \\\n\t$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@\nSOURCES = $(liblogging_la_SOURCES) $(libprofiler_la_SOURCES) \\\n\t$(libspinlock_la_SOURCES) $(libstacktrace_la_SOURCES) \\\n\t$(libsysinfo_la_SOURCES) $(libtcmalloc_la_SOURCES) \\\n\t$(libtcmalloc_and_profiler_la_SOURCES) \\\n\t$(libtcmalloc_debug_la_SOURCES) \\\n\t$(libtcmalloc_internal_la_SOURCES) \\\n\t$(libtcmalloc_minimal_la_SOURCES) \\\n\t$(libtcmalloc_minimal_debug_la_SOURCES) \\\n\t$(libtcmalloc_minimal_internal_la_SOURCES) \\\n\t$(libwindows_la_SOURCES) $(addressmap_unittest_SOURCES) \\\n\t$(atomicops_unittest_SOURCES) $(debugallocation_test_SOURCES) \\\n\t$(debugallocation_test_sh_SOURCES) $(frag_unittest_SOURCES) \\\n\t$(getpc_test_SOURCES) \\\n\t$(heap_checker_death_unittest_sh_SOURCES) \\\n\t$(heap_checker_debug_unittest_SOURCES) \\\n\t$(heap_checker_debug_unittest_sh_SOURCES) \\\n\t$(heap_checker_unittest_SOURCES) \\\n\t$(heap_checker_unittest_sh_SOURCES) \\\n\t$(heap_profiler_debug_unittest_SOURCES) \\\n\t$(heap_profiler_debug_unittest_sh_SOURCES) \\\n\t$(heap_profiler_unittest_SOURCES) \\\n\t$(heap_profiler_unittest_sh_SOURCES) \\\n\t$(low_level_alloc_unittest_SOURCES) \\\n\t$(malloc_extension_c_test_SOURCES) \\\n\t$(malloc_extension_debug_test_SOURCES) \\\n\t$(malloc_extension_test_SOURCES) $(markidle_unittest_SOURCES) \\\n\t$(maybe_threads_unittest_sh_SOURCES) \\\n\t$(memalign_debug_unittest_SOURCES) \\\n\t$(memalign_unittest_SOURCES) $(packed_cache_test_SOURCES) \\\n\t$(page_heap_test_SOURCES) $(pagemap_unittest_SOURCES) \\\n\t$(profile_handler_unittest_SOURCES) \\\n\t$(profiledata_unittest_SOURCES) $(profiler1_unittest_SOURCES) \\\n\t$(profiler2_unittest_SOURCES) $(profiler3_unittest_SOURCES) \\\n\t$(profiler4_unittest_SOURCES) $(profiler_unittest_sh_SOURCES) \\\n\t$(raw_printer_test_SOURCES) $(realloc_debug_unittest_SOURCES) \\\n\t$(realloc_unittest_SOURCES) $(sampler_debug_test_SOURCES) \\\n\t$(sampler_test_SOURCES) $(sampling_debug_test_SOURCES) \\\n\t$(sampling_debug_test_sh_SOURCES) $(sampling_test_SOURCES) \\\n\t$(sampling_test_sh_SOURCES) $(stack_trace_table_test_SOURCES) \\\n\t$(stacktrace_unittest_SOURCES) \\\n\t$(system_alloc_unittest_SOURCES) \\\n\t$(tcmalloc_and_profiler_unittest_SOURCES) \\\n\t$(tcmalloc_both_unittest_SOURCES) \\\n\t$(tcmalloc_debug_unittest_SOURCES) \\\n\t$(tcmalloc_large_unittest_SOURCES) \\\n\t$(tcmalloc_minimal_debug_unittest_SOURCES) \\\n\t$(tcmalloc_minimal_large_unittest_SOURCES) \\\n\t$(tcmalloc_minimal_unittest_SOURCES) \\\n\t$(tcmalloc_unittest_SOURCES) \\\n\t$(thread_dealloc_unittest_SOURCES)\nDIST_SOURCES = $(liblogging_la_SOURCES) \\\n\t$(am__libprofiler_la_SOURCES_DIST) \\\n\t$(am__libspinlock_la_SOURCES_DIST) \\\n\t$(am__libstacktrace_la_SOURCES_DIST) $(libsysinfo_la_SOURCES) \\\n\t$(am__libtcmalloc_la_SOURCES_DIST) \\\n\t$(am__libtcmalloc_and_profiler_la_SOURCES_DIST) \\\n\t$(am__libtcmalloc_debug_la_SOURCES_DIST) \\\n\t$(am__libtcmalloc_internal_la_SOURCES_DIST) \\\n\t$(am__libtcmalloc_minimal_la_SOURCES_DIST) \\\n\t$(am__libtcmalloc_minimal_debug_la_SOURCES_DIST) \\\n\t$(am__libtcmalloc_minimal_internal_la_SOURCES_DIST) \\\n\t$(am__libwindows_la_SOURCES_DIST) \\\n\t$(am__addressmap_unittest_SOURCES_DIST) \\\n\t$(atomicops_unittest_SOURCES) \\\n\t$(am__debugallocation_test_SOURCES_DIST) \\\n\t$(am__debugallocation_test_sh_SOURCES_DIST) \\\n\t$(frag_unittest_SOURCES) $(am__getpc_test_SOURCES_DIST) \\\n\t$(am__heap_checker_death_unittest_sh_SOURCES_DIST) \\\n\t$(am__heap_checker_debug_unittest_SOURCES_DIST) \\\n\t$(am__heap_checker_debug_unittest_sh_SOURCES_DIST) \\\n\t$(am__heap_checker_unittest_SOURCES_DIST) \\\n\t$(am__heap_checker_unittest_sh_SOURCES_DIST) \\\n\t$(am__heap_profiler_debug_unittest_SOURCES_DIST) \\\n\t$(am__heap_profiler_debug_unittest_sh_SOURCES_DIST) \\\n\t$(am__heap_profiler_unittest_SOURCES_DIST) \\\n\t$(am__heap_profiler_unittest_sh_SOURCES_DIST) \\\n\t$(am__low_level_alloc_unittest_SOURCES_DIST) \\\n\t$(am__malloc_extension_c_test_SOURCES_DIST) \\\n\t$(am__malloc_extension_debug_test_SOURCES_DIST) \\\n\t$(malloc_extension_test_SOURCES) $(markidle_unittest_SOURCES) \\\n\t$(am__maybe_threads_unittest_sh_SOURCES_DIST) \\\n\t$(am__memalign_debug_unittest_SOURCES_DIST) \\\n\t$(am__memalign_unittest_SOURCES_DIST) \\\n\t$(packed_cache_test_SOURCES) $(page_heap_test_SOURCES) \\\n\t$(pagemap_unittest_SOURCES) \\\n\t$(am__profile_handler_unittest_SOURCES_DIST) \\\n\t$(am__profiledata_unittest_SOURCES_DIST) \\\n\t$(am__profiler1_unittest_SOURCES_DIST) \\\n\t$(am__profiler2_unittest_SOURCES_DIST) \\\n\t$(am__profiler3_unittest_SOURCES_DIST) \\\n\t$(am__profiler4_unittest_SOURCES_DIST) \\\n\t$(am__profiler_unittest_sh_SOURCES_DIST) \\\n\t$(am__raw_printer_test_SOURCES_DIST) \\\n\t$(am__realloc_debug_unittest_SOURCES_DIST) \\\n\t$(realloc_unittest_SOURCES) \\\n\t$(am__sampler_debug_test_SOURCES_DIST) \\\n\t$(am__sampler_test_SOURCES_DIST) \\\n\t$(am__sampling_debug_test_SOURCES_DIST) \\\n\t$(am__sampling_debug_test_sh_SOURCES_DIST) \\\n\t$(am__sampling_test_SOURCES_DIST) \\\n\t$(am__sampling_test_sh_SOURCES_DIST) \\\n\t$(stack_trace_table_test_SOURCES) \\\n\t$(am__stacktrace_unittest_SOURCES_DIST) \\\n\t$(am__system_alloc_unittest_SOURCES_DIST) \\\n\t$(am__tcmalloc_and_profiler_unittest_SOURCES_DIST) \\\n\t$(am__tcmalloc_both_unittest_SOURCES_DIST) \\\n\t$(am__tcmalloc_debug_unittest_SOURCES_DIST) \\\n\t$(am__tcmalloc_large_unittest_SOURCES_DIST) \\\n\t$(am__tcmalloc_minimal_debug_unittest_SOURCES_DIST) \\\n\t$(tcmalloc_minimal_large_unittest_SOURCES) \\\n\t$(am__tcmalloc_minimal_unittest_SOURCES_DIST) \\\n\t$(am__tcmalloc_unittest_SOURCES_DIST) \\\n\t$(thread_dealloc_unittest_SOURCES)\nman1dir = $(mandir)/man1\nNROFF = nroff\nMANS = $(dist_man_MANS)\nam__dist_doc_DATA_DIST = AUTHORS COPYING ChangeLog INSTALL NEWS README \\\n\tREADME_windows.txt TODO doc/index.html doc/designstyle.css \\\n\tdoc/pprof_remote_servers.html doc/tcmalloc.html \\\n\tdoc/overview.gif doc/pageheap.gif doc/spanmap.gif \\\n\tdoc/threadheap.gif doc/t-test1.times.txt \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.128.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.256.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.512.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.64.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png \\\n\tdoc/tcmalloc-opspersec.vs.size.1.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.12.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.16.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.2.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.20.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.3.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.4.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.5.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.8.threads.png doc/overview.dot \\\n\tdoc/pageheap.dot doc/spanmap.dot doc/threadheap.dot \\\n\tdoc/heapprofile.html doc/heap-example1.png \\\n\tdoc/heap_checker.html doc/cpuprofile.html \\\n\tdoc/cpuprofile-fileformat.html doc/pprof-test-big.gif \\\n\tdoc/pprof-test.gif doc/pprof-vsnprintf-big.gif \\\n\tdoc/pprof-vsnprintf.gif\ndist_docDATA_INSTALL = $(INSTALL_DATA)\npkgconfigDATA_INSTALL = $(INSTALL_DATA)\nDATA = $(dist_doc_DATA) $(pkgconfig_DATA)\nam__googleinclude_HEADERS_DIST = src/google/stacktrace.h \\\n\tsrc/google/malloc_hook.h src/google/malloc_hook_c.h \\\n\tsrc/google/malloc_extension.h src/google/malloc_extension_c.h \\\n\tsrc/google/heap-profiler.h src/google/heap-checker.h \\\n\tsrc/google/profiler.h\ngoogleincludeHEADERS_INSTALL = $(INSTALL_HEADER)\nnodist_googleincludeHEADERS_INSTALL = $(INSTALL_HEADER)\nHEADERS = $(googleinclude_HEADERS) $(nodist_googleinclude_HEADERS) \\\n\t$(noinst_HEADERS)\nETAGS = etags\nCTAGS = ctags\nDISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)\ndistdir = $(PACKAGE)-$(VERSION)\ntop_distdir = $(distdir)\nam__remove_distdir = \\\n  { test ! -d $(distdir) \\\n    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \\\n         && rm -fr $(distdir); }; }\nDIST_ARCHIVES = $(distdir).tar.gz $(distdir).zip\nGZIP_ENV = --best\ndistuninstallcheck_listfiles = find . -type f -print\ndistcleancheck_listfiles = find . -type f -print\nACLOCAL = @ACLOCAL@\nAMDEP_FALSE = @AMDEP_FALSE@\nAMDEP_TRUE = @AMDEP_TRUE@\nAMTAR = @AMTAR@\nAR = @AR@\nAUTOCONF = @AUTOCONF@\nAUTOHEADER = @AUTOHEADER@\nAUTOMAKE = @AUTOMAKE@\nAWK = @AWK@\nCC = @CC@\nCCDEPMODE = @CCDEPMODE@\nCFLAGS = @CFLAGS@\nCPP = @CPP@\nCPPFLAGS = @CPPFLAGS@\nCXX = @CXX@\nCXXCPP = @CXXCPP@\nCXXDEPMODE = @CXXDEPMODE@\nCXXFLAGS = @CXXFLAGS@\nCYGPATH_W = @CYGPATH_W@\nDEFS = @DEFS@\nDEPDIR = @DEPDIR@\nDSYMUTIL = @DSYMUTIL@\nDUMPBIN = @DUMPBIN@\nECHO_C = @ECHO_C@\nECHO_N = @ECHO_N@\nECHO_T = @ECHO_T@\nEGREP = @EGREP@\nENABLE_FRAME_POINTERS_FALSE = @ENABLE_FRAME_POINTERS_FALSE@\nENABLE_FRAME_POINTERS_TRUE = @ENABLE_FRAME_POINTERS_TRUE@\nENABLE_STATIC_FALSE = @ENABLE_STATIC_FALSE@\nENABLE_STATIC_TRUE = @ENABLE_STATIC_TRUE@\nEXEEXT = @EXEEXT@\nFGREP = @FGREP@\nGCC_FALSE = @GCC_FALSE@\nGCC_TRUE = @GCC_TRUE@\nGREP = @GREP@\nHAVE_OBJCOPY_WEAKEN_FALSE = @HAVE_OBJCOPY_WEAKEN_FALSE@\nHAVE_OBJCOPY_WEAKEN_TRUE = @HAVE_OBJCOPY_WEAKEN_TRUE@\nINSTALL_DATA = @INSTALL_DATA@\nINSTALL_PROGRAM = @INSTALL_PROGRAM@\nINSTALL_SCRIPT = @INSTALL_SCRIPT@\nINSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@\nLD = @LD@\nLDFLAGS = @LDFLAGS@\nLIBOBJS = @LIBOBJS@\nLIBS = @LIBS@\nLIBSTDCXX_LA_LINKER_FLAG = @LIBSTDCXX_LA_LINKER_FLAG@\nLIBTOOL = @LIBTOOL@\nLIBTOOL_DEPS = @LIBTOOL_DEPS@\nLIPO = @LIPO@\nLN_S = @LN_S@\nLTLIBOBJS = @LTLIBOBJS@\nMAKEINFO = @MAKEINFO@\nMINGW_FALSE = @MINGW_FALSE@\nMINGW_TRUE = @MINGW_TRUE@\nNANOSLEEP_LIBS = @NANOSLEEP_LIBS@\nNM = @NM@\nNMEDIT = @NMEDIT@\nOBJCOPY = @OBJCOPY@\nOBJDUMP = @OBJDUMP@\nOBJEXT = @OBJEXT@\nOTOOL = @OTOOL@\nOTOOL64 = @OTOOL64@\nPACKAGE = @PACKAGE@\nPACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@\nPACKAGE_NAME = @PACKAGE_NAME@\nPACKAGE_STRING = @PACKAGE_STRING@\nPACKAGE_TARNAME = @PACKAGE_TARNAME@\nPACKAGE_URL = @PACKAGE_URL@\nPACKAGE_VERSION = @PACKAGE_VERSION@\nPATH_SEPARATOR = @PATH_SEPARATOR@\nPROFILER_SO_VERSION = @PROFILER_SO_VERSION@\nPTHREAD_CC = @PTHREAD_CC@\nPTHREAD_CFLAGS = @PTHREAD_CFLAGS@\nPTHREAD_LIBS = @PTHREAD_LIBS@\nRANLIB = @RANLIB@\nSED = @SED@\nSET_MAKE = @SET_MAKE@\nSHELL = @SHELL@\nSTRIP = @STRIP@\nTCMALLOC_SO_VERSION = @TCMALLOC_SO_VERSION@\nTC_VERSION_MAJOR = @TC_VERSION_MAJOR@\nTC_VERSION_MINOR = @TC_VERSION_MINOR@\nTC_VERSION_PATCH = @TC_VERSION_PATCH@\nUNWIND_LIBS = @UNWIND_LIBS@\nUSE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@\nUSE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@\nVERSION = @VERSION@\nWITH_CPU_PROFILER_FALSE = @WITH_CPU_PROFILER_FALSE@\nWITH_CPU_PROFILER_TRUE = @WITH_CPU_PROFILER_TRUE@\nWITH_DEBUGALLOC_FALSE = @WITH_DEBUGALLOC_FALSE@\nWITH_DEBUGALLOC_TRUE = @WITH_DEBUGALLOC_TRUE@\nWITH_HEAP_CHECKER_FALSE = @WITH_HEAP_CHECKER_FALSE@\nWITH_HEAP_CHECKER_TRUE = @WITH_HEAP_CHECKER_TRUE@\nWITH_HEAP_PROFILER_FALSE = @WITH_HEAP_PROFILER_FALSE@\nWITH_HEAP_PROFILER_OR_CHECKER_FALSE = @WITH_HEAP_PROFILER_OR_CHECKER_FALSE@\nWITH_HEAP_PROFILER_OR_CHECKER_TRUE = @WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\nWITH_HEAP_PROFILER_TRUE = @WITH_HEAP_PROFILER_TRUE@\nWITH_STACK_TRACE_FALSE = @WITH_STACK_TRACE_FALSE@\nWITH_STACK_TRACE_TRUE = @WITH_STACK_TRACE_TRUE@\nX86_64_AND_NO_FP_BY_DEFAULT_FALSE = @X86_64_AND_NO_FP_BY_DEFAULT_FALSE@\nX86_64_AND_NO_FP_BY_DEFAULT_TRUE = @X86_64_AND_NO_FP_BY_DEFAULT_TRUE@\nac_ct_CC = @ac_ct_CC@\nac_ct_CXX = @ac_ct_CXX@\nac_ct_DUMPBIN = @ac_ct_DUMPBIN@\nac_cv_have_struct_mallinfo = @ac_cv_have_struct_mallinfo@\nacx_pthread_config = @acx_pthread_config@\nam__fastdepCC_FALSE = @am__fastdepCC_FALSE@\nam__fastdepCC_TRUE = @am__fastdepCC_TRUE@\nam__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@\nam__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@\nam__include = @am__include@\nam__leading_dot = @am__leading_dot@\nam__quote = @am__quote@\nam__tar = @am__tar@\nam__untar = @am__untar@\nbindir = @bindir@\nbuild = @build@\nbuild_alias = @build_alias@\nbuild_cpu = @build_cpu@\nbuild_os = @build_os@\nbuild_vendor = @build_vendor@\ndatadir = @datadir@\ndatarootdir = @datarootdir@\ndocdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)\ndvidir = @dvidir@\nexec_prefix = @exec_prefix@\nhost = @host@\nhost_alias = @host_alias@\nhost_cpu = @host_cpu@\nhost_os = @host_os@\nhost_vendor = @host_vendor@\nhtmldir = @htmldir@\nincludedir = @includedir@\ninfodir = @infodir@\ninstall_sh = @install_sh@\nlibdir = @libdir@\nlibexecdir = @libexecdir@\nlocaledir = @localedir@\nlocalstatedir = @localstatedir@\nlt_ECHO = @lt_ECHO@\nmandir = @mandir@\nmkdir_p = @mkdir_p@\noldincludedir = @oldincludedir@\npdfdir = @pdfdir@\nprefix = @prefix@\nprogram_transform_name = @program_transform_name@\npsdir = @psdir@\nsbindir = @sbindir@\nsharedstatedir = @sharedstatedir@\nsysconfdir = @sysconfdir@\ntarget_alias = @target_alias@\n\n# Make sure that when we re-make ./configure, we get the macros we need\nACLOCAL_AMFLAGS = -I m4\n\n# This is so we can #include <google/foo>\nAM_CPPFLAGS = -I$(top_srcdir)/src $(am__append_1)\n\n# This is mostly based on configure options\nAM_CXXFLAGS = $(am__append_2) $(am__append_3) $(am__append_4)\n\n# The -no-undefined flag allows libtool to generate shared libraries for\n# Cygwin and MinGW.  LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.\nAM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)\n@GCC_FALSE@NO_EXCEPTIONS = \n\n# We know our low-level code cannot trigger an exception.  On some\n# systems, such as cygwin, it would be disastrous if they did, because\n# the exception handler might call malloc!  If our low-level routines\n# raised an exception within the malloc, they'd deadlock.  Luckily,\n# we control all this code, and do not need exceptions for it.\n@GCC_TRUE@NO_EXCEPTIONS = -fno-exceptions\n\n# For windows systems (at least, mingw), we need to tell all our\n# tests to link in libtcmalloc using -u.  This is because libtcmalloc\n# accomplishes its tasks via patching, leaving no work for the linker\n# to identify, so the linker will ignore libtcmalloc by default unless\n# we explicitly create a dependency via -u.\nTCMALLOC_FLAGS = $(am__append_5)\n@HAVE_OBJCOPY_WEAKEN_FALSE@WEAKEN = :\n\n# If we have objcopy, make malloc/free/etc weak symbols.  That way folks\n# can override our malloc if they want to (they can still use tc_malloc).\n# Note: the weird-looking symbols are the c++ memory functions:\n# (in order) new, new(nothrow), new[], new[](nothrow), delete, delete[]\n# In theory this will break if mangling changes, but that seems pretty\n# unlikely at this point.  Just in case, I throw in versions with an\n# extra underscore as well, which may help on OS X.\n@HAVE_OBJCOPY_WEAKEN_TRUE@WEAKEN = $(OBJCOPY) -W malloc -W free -W realloc -W calloc -W cfree \\\n@HAVE_OBJCOPY_WEAKEN_TRUE@         -W memalign -W posix_memalign -W valloc -W pvalloc \\\n@HAVE_OBJCOPY_WEAKEN_TRUE@         -W malloc_stats -W mallopt -W mallinfo \\\n@HAVE_OBJCOPY_WEAKEN_TRUE@         -W _Znwm -W _ZnwmRKSt9nothrow_t -W _Znam -W _ZnamRKSt9nothrow_t \\\n@HAVE_OBJCOPY_WEAKEN_TRUE@         -W _ZdlPv -W _ZdaPv \\\n@HAVE_OBJCOPY_WEAKEN_TRUE@         -W __Znwm -W __ZnwmRKSt9nothrow_t -W __Znam -W __ZnamRKSt9nothrow_t \\\n@HAVE_OBJCOPY_WEAKEN_TRUE@         -W __ZdlPv -W __ZdaPv\n\nLIBS_TO_WEAKEN = libtcmalloc_minimal.la $(am__append_23) \\\n\t$(am__append_33) $(am__append_48) $(am__append_63)\ngoogleincludedir = $(includedir)/google\n# The .h files you want to install (that is, .h files that people\n# who install this package can include in their own applications.)\n# We'll add to this later, on a library-by-library basis\ngoogleinclude_HEADERS = $(am__append_9) \\\n\t$(SG_TCMALLOC_MINIMAL_INCLUDES) $(am__append_27) \\\n\t$(am__append_55)\n# tcmalloc.h is a special case, because it's a .h.in file\nnodist_googleinclude_HEADERS = src/google/tcmalloc.h\nnoinst_HEADERS = src/google/tcmalloc.h.in\n# This is for HTML and other documentation you want to install.\n# Add your documentation files (in doc/) in addition to these\n# top-level boilerplate files.  Also add a TODO file if you have one.\n# We'll add to this later, on a library-by-library basis\n\n### Documentation\n\n# I don't know how to say \"distribute the .dot files but don't install them\";\n# noinst doesn't seem to work with data.  I separate them out anyway, in case\n# one day we figure it out.  Regardless, installing the dot files isn't the\n# end of the world.\ndist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \\\n\tREADME_windows.txt TODO doc/index.html doc/designstyle.css \\\n\t$(am__append_12) doc/tcmalloc.html doc/overview.gif \\\n\tdoc/pageheap.gif doc/spanmap.gif doc/threadheap.gif \\\n\tdoc/t-test1.times.txt \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.128.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.256.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.512.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.64.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png \\\n\tdoc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png \\\n\tdoc/tcmalloc-opspersec.vs.size.1.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.12.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.16.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.2.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.20.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.3.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.4.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.5.threads.png \\\n\tdoc/tcmalloc-opspersec.vs.size.8.threads.png doc/overview.dot \\\n\tdoc/pageheap.dot doc/spanmap.dot doc/threadheap.dot \\\n\t$(am__append_45) $(am__append_46) $(am__append_60)\n\n# The libraries (.so's) you want to install\n# We'll add to this later, on a library-by-library basis\nlib_LTLIBRARIES = libtcmalloc_minimal.la $(am__append_22) \\\n\t$(am__append_29) $(am__append_47) $(am__append_56) \\\n\t$(am__append_61)\n# This is for 'convenience libraries' -- basically just a container for sources\n\n### Making the library\n\n# As we describe at the top of this file, we want to turn off exceptions\n# for all files in this library -- except tcmalloc.cc which needs them\n# to fulfill its API.  Automake doesn't allow per-file CXXFLAGS, so we need\n# to separate into two libraries.\nnoinst_LTLIBRARIES = liblogging.la libsysinfo.la $(am__append_6) \\\n\t$(am__append_8) $(am__append_10) \\\n\tlibtcmalloc_minimal_internal.la $(am__append_28)\nWINDOWS_PROJECTS = google-perftools.sln \\\n\tvsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcproj \\\n\t$(am__append_14) \\\n\tvsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj \\\n\tvsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcproj \\\n\tvsprojects/tmu-static/tmu-static.vcproj \\\n\tvsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcproj \\\n\tvsprojects/addressmap_unittest/addressmap_unittest.vcproj \\\n\tvsprojects/packed-cache_test/packed-cache_test.vcproj \\\n\tvsprojects/frag_unittest/frag_unittest.vcproj \\\n\tvsprojects/markidle_unittest/markidle_unittest.vcproj \\\n\tvsprojects/malloc_extension_test/malloc_extension_test.vcproj \\\n\tvsprojects/page_heap_test/page_heap_test.vcproj \\\n\tvsprojects/pagemap_unittest/pagemap_unittest.vcproj \\\n\tvsprojects/realloc_unittest/realloc_unittest.vcproj \\\n\tvsprojects/stack_trace_table_test/stack_trace_table_test.vcproj \\\n\tvsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcproj \\\n\t$(am__append_36)\n\n# unittests you want to run when people type 'make check'.\n# Note: tests cannot take any arguments!\n# In theory, unittests that are scripts should be added to check_SCRIPTS\n# instead.  But check_SCRIPTS is definitely a second-class testing mechanims:\n# it don't get TESTS_ENVIRONMENT, and it doesn't get success/failure counting\n# (in fact, a script failure aborts all the rest of the tests, even with -k).\n# So, for scripts, we add the script to tests, and also put in an empty\n# rule so automake doesn't try to build the script as a C binary.\n\n### Unittests\n\n### Unittests\n\n# Commented out for the moment because malloc(very_big_num) is broken in\n# standard libc!  At least, in some situations, some of the time.\n\n# These all tests components of tcmalloc_minimal\nTESTS = low_level_alloc_unittest atomicops_unittest $(am__append_11) \\\n\ttcmalloc_minimal_unittest tcmalloc_minimal_large_unittest \\\n\t$(am__append_15) addressmap_unittest $(am__append_18) \\\n\tpacked_cache_test frag_unittest markidle_unittest \\\n\tmalloc_extension_test $(am__append_19) $(am__append_21) \\\n\tpage_heap_test pagemap_unittest realloc_unittest \\\n\tstack_trace_table_test thread_dealloc_unittest \\\n\t$(am__append_24) $(am__append_34) $(am__append_39) \\\n\t$(am__append_42) $(am__append_49) $(am__append_51) \\\n\t$(am__append_53) $(am__append_57) $(am__append_62)\n# TESTS_ENVIRONMENT sets environment variables for when you run unittest.\n# We always get \"srcdir\" set for free.\n# We'll add to this later, on a library-by-library basis.\nTESTS_ENVIRONMENT = $(am__append_13) $(am__append_35)\n# All script tests should be added here\nnoinst_SCRIPTS = $(am__append_16) $(am__append_25) $(am__append_37) \\\n\t$(am__append_40) $(am__append_43) $(am__append_58)\n\n# This is my own var, used for extra libraries I make that I need installed\nEXTRA_INSTALL = \n\n### ------- library routines, in src/base\n\n# This is a 'convenience library' -- it's not actually installed or anything\nLOGGING_INCLUDES = src/base/logging.h \\\n                   src/base/commandlineflags.h \\\n                   src/base/basictypes.h \\\n                   src/base/dynamic_annotations.h \\\n                   src/third_party/valgrind.h\n\nliblogging_la_SOURCES = src/base/logging.cc \\\n                        src/base/dynamic_annotations.c \\\n                        $(LOGGING_INCLUDES)\n\nSYSINFO_INCLUDES = src/base/sysinfo.h \\\n                   src/base/logging.h \\\n                   src/base/commandlineflags.h \\\n                   src/base/cycleclock.h \\\n                   src/base/basictypes.h\n\nlibsysinfo_la_SOURCES = src/base/sysinfo.cc \\\n                        $(SYSINFO_INCLUDES)\n\nlibsysinfo_la_LIBADD = $(NANOSLEEP_LIBS) $(am__append_7)\n\n# For MinGW, we use also have to use libwindows Luckily, we need the\n# windows.a library in exactly the same place we need spinlock.a\n# (pretty much everywhere), so we can use the same variable name for\n# each.  We can also optimize the MinGW rule a bit by leaving out\n# files we know aren't used on windows, such as\n# atomicops-internals-x86.cc.  libwindows also obsoletes the need for\n# other files like system_alloc.cc.\n@MINGW_TRUE@WINDOWS_INCLUDES = src/windows/port.h \\\n@MINGW_TRUE@                   src/windows/mingw.h \\\n@MINGW_TRUE@                   src/windows/mini_disassembler.h \\\n@MINGW_TRUE@                   src/windows/mini_disassembler_types.h \\\n@MINGW_TRUE@                   src/windows/preamble_patcher.h\n\n@MINGW_TRUE@libwindows_la_SOURCES = $(WINDOWS_INCLUDES) \\\n@MINGW_TRUE@                        src/windows/port.cc \\\n@MINGW_TRUE@                        src/windows/ia32_modrm_map.cc \\\n@MINGW_TRUE@                        src/windows/ia32_opcode_map.cc \\\n@MINGW_TRUE@                        src/windows/mini_disassembler.cc \\\n@MINGW_TRUE@                        src/windows/patch_functions.cc \\\n@MINGW_TRUE@                        src/windows/preamble_patcher.cc \\\n@MINGW_TRUE@                        src/windows/preamble_patcher_with_stub.cc\n\n# patch_functions.cc uses Psapi.lib.  MSVC has a #pragma for that, but not us.\n@MINGW_TRUE@libwindows_la_LIBADD = -lPsapi\n# spinlock is the only code that uses atomicops.\n@MINGW_FALSE@SPINLOCK_INCLUDES = src/base/spinlock.h \\\n@MINGW_FALSE@                    src/base/spinlock_internal.h \\\n@MINGW_FALSE@                    src/base/atomicops.h \\\n@MINGW_FALSE@                    src/base/atomicops-internals-macosx.h \\\n@MINGW_FALSE@                    src/base/atomicops-internals-linuxppc.h \\\n@MINGW_FALSE@                    src/base/atomicops-internals-x86-msvc.h \\\n@MINGW_FALSE@                    src/base/atomicops-internals-x86.h\n\n@MINGW_TRUE@SPINLOCK_INCLUDES = src/base/spinlock.h \\\n@MINGW_TRUE@                    src/base/spinlock_internal.h \\\n@MINGW_TRUE@                    src/base/spinlock_win32-inl.h \\\n@MINGW_TRUE@                    src/base/spinlock_linux-inl.h \\\n@MINGW_TRUE@                    src/base/spinlock_posix-inl.h \\\n@MINGW_TRUE@                    src/base/synchronization_profiling.h \\\n@MINGW_TRUE@                    src/base/atomicops-internals-macosx.h \\\n@MINGW_TRUE@                    src/base/atomicops-internals-linuxppc.h \\\n@MINGW_TRUE@                    src/base/atomicops-internals-arm-gcc.h \\\n@MINGW_TRUE@                    src/base/atomicops-internals-x86-msvc.h \\\n@MINGW_TRUE@                    src/base/atomicops-internals-x86.h\n\n@MINGW_FALSE@libspinlock_la_SOURCES = src/base/spinlock.cc \\\n@MINGW_FALSE@                         src/base/spinlock_internal.cc \\\n@MINGW_FALSE@                         src/base/atomicops-internals-x86.cc \\\n@MINGW_FALSE@                         $(SPINLOCK_INCLUDES)\n\n@MINGW_TRUE@libspinlock_la_SOURCES = src/base/spinlock.cc \\\n@MINGW_TRUE@                         src/base/spinlock_internal.cc \\\n@MINGW_TRUE@                         $(SPINLOCK_INCLUDES)\n\n# spinlock also needs NumCPUs, from libsysinfo, which in turn needs liblogging\n@MINGW_FALSE@LIBSPINLOCK = libspinlock.la libsysinfo.la liblogging.la\n@MINGW_TRUE@LIBSPINLOCK = libwindows.la libspinlock.la libsysinfo.la liblogging.la\n@MINGW_FALSE@TCMALLOC_CC = src/tcmalloc.cc\n\n# patch_functions.cc #includes tcmalloc.cc, so no need to link it in.\n@MINGW_TRUE@TCMALLOC_CC = \n@MINGW_FALSE@MAYBE_THREADS_CC = src/maybe_threads.cc\n# windows has its own system for threads and system memory allocation.\n@MINGW_TRUE@MAYBE_THREADS_CC = \n@MINGW_FALSE@SYSTEM_ALLOC_CC = src/system-alloc.cc\n@MINGW_TRUE@SYSTEM_ALLOC_CC = \n@MINGW_FALSE@libspinlock_la_LIBADD = $(NANOSLEEP_LIBS)\nLOW_LEVEL_ALLOC_UNITTEST_INCLUDES = src/base/low_level_alloc.h \\\n                                    src/base/basictypes.h \\\n                                    src/google/malloc_hook.h \\\n                                    src/google/malloc_hook_c.h \\\n                                    src/malloc_hook-inl.h \\\n                                    $(SPINLOCK_INCLUDES) \\\n                                    $(LOGGING_INCLUDES)\n\nlow_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \\\n                                   src/malloc_hook.cc \\\n                                   src/tests/low_level_alloc_unittest.cc \\\n                                   $(LOW_LEVEL_ALLOC_UNITTEST_INCLUDES)\n\n# By default, MallocHook takes stack traces for use by the heap-checker.\n# We don't need that functionality here, so we turn it off to reduce deps.\nlow_level_alloc_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES\nlow_level_alloc_unittest_LDADD = $(LIBSPINLOCK)\nATOMICOPS_UNITTEST_INCLUDES = src/base/atomicops.h \\\n                              src/base/atomicops-internals-macosx.h \\\n                              src/base/atomicops-internals-x86-msvc.h \\\n                              src/base/atomicops-internals-x86.h \\\n                              $(LOGGING_INCLUDES)\n\natomicops_unittest_SOURCES = src/tests/atomicops_unittest.cc \\\n                             $(ATOMICOPS_UNITTEST_INCLUDES)\n\natomicops_unittest_LDADD = $(LIBSPINLOCK)\n\n### ------- stack trace\n\n### The header files we use.  We divide into categories based on directory\n@WITH_STACK_TRACE_TRUE@S_STACKTRACE_INCLUDES = src/stacktrace_config.h \\\n@WITH_STACK_TRACE_TRUE@                        src/stacktrace_generic-inl.h \\\n@WITH_STACK_TRACE_TRUE@\t\t\tsrc/stacktrace_libunwind-inl.h \\\n@WITH_STACK_TRACE_TRUE@\t\t\tsrc/stacktrace_powerpc-inl.h \\\n@WITH_STACK_TRACE_TRUE@\t\t\tsrc/stacktrace_x86_64-inl.h \\\n@WITH_STACK_TRACE_TRUE@\t\t\tsrc/stacktrace_x86-inl.h \\\n@WITH_STACK_TRACE_TRUE@\t\t\tsrc/stacktrace_win32-inl.h \\\n@WITH_STACK_TRACE_TRUE@                        src/base/vdso_support.h\n\n@WITH_STACK_TRACE_TRUE@SG_STACKTRACE_INCLUDES = src/google/stacktrace.h\n@WITH_STACK_TRACE_TRUE@STACKTRACE_INCLUDES = $(S_STACKTRACE_INCLUDES) $(SG_STACKTRACE_INCLUDES)\n@WITH_STACK_TRACE_TRUE@libstacktrace_la_SOURCES = src/stacktrace.cc \\\n@WITH_STACK_TRACE_TRUE@                           src/base/vdso_support.cc \\\n@WITH_STACK_TRACE_TRUE@                           $(STACKTRACE_INCLUDES)\n\n@WITH_STACK_TRACE_TRUE@libstacktrace_la_LIBADD = $(UNWIND_LIBS) $(LIBSPINLOCK)\n@WITH_STACK_TRACE_TRUE@STACKTRACE_SYMBOLS = '(GetStackTrace|GetStackFrames|GetStackTraceWithContext|GetStackFramesWithContext)'\n@WITH_STACK_TRACE_TRUE@libstacktrace_la_LDFLAGS = -export-symbols-regex $(STACKTRACE_SYMBOLS)\n@WITH_STACK_TRACE_TRUE@STACKTRACE_UNITTEST_INLCUDES = src/config_for_unittests.h \\\n@WITH_STACK_TRACE_TRUE@                               src/base/commandlineflags.h \\\n@WITH_STACK_TRACE_TRUE@                               $(STACKTRACE_INCLUDES) \\\n@WITH_STACK_TRACE_TRUE@                               $(LOGGING_INCLUDES)\n\n@WITH_STACK_TRACE_TRUE@stacktrace_unittest_SOURCES = src/tests/stacktrace_unittest.cc \\\n@WITH_STACK_TRACE_TRUE@                              $(STACKTRACE_UNITTEST_INLCUDES)\n\n@WITH_STACK_TRACE_TRUE@stacktrace_unittest_LDADD = libstacktrace.la liblogging.la\n\n### ------- pprof\n\n# If we are not compiling with stacktrace support, pprof is worthless\n@WITH_STACK_TRACE_TRUE@bin_SCRIPTS = src/pprof\n\n### Unittests\n@WITH_STACK_TRACE_TRUE@check_SCRIPTS = pprof_unittest\n\n### Documentation\n@WITH_STACK_TRACE_TRUE@dist_man_MANS = doc/pprof.1\n\n### ------- tcmalloc_minimal (thread-caching malloc)\n\n### The header files we use.  We divide into categories based on directory\nS_TCMALLOC_MINIMAL_INCLUDES = src/common.h \\\n                              src/internal_logging.h \\\n                              src/system-alloc.h \\\n                              src/packed-cache-inl.h \\\n                              $(SPINLOCK_INCLUDES) \\\n                              src/tcmalloc_guard.h \\\n                              src/base/commandlineflags.h \\\n                              src/base/basictypes.h \\\n                              src/pagemap.h \\\n                              src/sampler.h \\\n                              src/central_freelist.h \\\n                              src/linked_list.h \\\n                              src/page_heap.h \\\n                              src/page_heap_allocator.h \\\n                              src/span.h \\\n                              src/static_vars.h \\\n                              src/symbolize.h \\\n                              src/thread_cache.h \\\n                              src/stack_trace_table.h \\\n                              src/base/thread_annotations.h \\\n                              src/malloc_hook-inl.h \\\n                              src/maybe_threads.h\n\nSG_TCMALLOC_MINIMAL_INCLUDES = src/google/malloc_hook.h \\\n                               src/google/malloc_hook_c.h \\\n                               src/google/malloc_extension.h \\\n                               src/google/malloc_extension_c.h \\\n                               src/google/stacktrace.h\n\nTCMALLOC_MINIMAL_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) $(SG_TCMALLOC_MINIMAL_INCLUDES)\nlibtcmalloc_minimal_internal_la_SOURCES = src/common.cc \\\n                                          src/internal_logging.cc \\\n                                          $(SYSTEM_ALLOC_CC) \\\n                                          src/memfs_malloc.cc \\\n                                          src/central_freelist.cc \\\n                                          src/page_heap.cc \\\n                                          src/sampler.cc \\\n                                          src/span.cc \\\n                                          src/stack_trace_table.cc \\\n                                          src/static_vars.cc \\\n                                          src/symbolize.cc \\\n                                          src/thread_cache.cc \\\n                                          src/malloc_hook.cc \\\n                                          src/malloc_extension.cc \\\n                                          $(MAYBE_THREADS_CC) \\\n                                          $(TCMALLOC_MINIMAL_INCLUDES)\n\n# We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal.\nlibtcmalloc_minimal_internal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \\\n                                           -DNO_HEAP_CHECK \\\n                                           $(PTHREAD_CFLAGS) -DNDEBUG \\\n                                           $(AM_CXXFLAGS) $(NO_EXCEPTIONS)\n\nlibtcmalloc_minimal_internal_la_LDFLAGS = $(PTHREAD_CFLAGS)\nlibtcmalloc_minimal_internal_la_LIBADD = $(PTHREAD_LIBS) $(LIBSPINLOCK)\nlibtcmalloc_minimal_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_MINIMAL_INCLUDES)\nlibtcmalloc_minimal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \\\n                                  $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS)\n\n# -version-info gets passed to libtool\nlibtcmalloc_minimal_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@\nlibtcmalloc_minimal_la_LIBADD = libtcmalloc_minimal_internal.la $(PTHREAD_LIBS)\n@MINGW_FALSE@LIBTCMALLOC_MINIMAL = libtcmalloc_minimal.la\n\n# For windows, we're playing around with trying to do some stacktrace\n# support even with libtcmalloc_minimal.  For everyone else, though,\n# we turn off all stack-trace activity for libtcmalloc_minimal.\n# TODO(csilvers): when we're done experimenting, do something principled here\n@MINGW_TRUE@LIBTCMALLOC_MINIMAL = libtcmalloc_minimal.la libstacktrace.la\ntcmalloc_minimal_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n                                    src/tests/testutil.h src/tests/testutil.cc \\\n                                    $(TCMALLOC_UNITTEST_INCLUDES)\n\ntcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\ntcmalloc_minimal_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) \\\n                                  liblogging.la $(PTHREAD_LIBS)\n\ntcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc\ntcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\ntcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\ntcmalloc_minimal_large_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@maybe_threads_unittest_sh_SOURCES = src/tests/maybe_threads_unittest.sh\nADDRESSMAP_UNITTEST_INCLUDES = src/addressmap-inl.h \\\n                               src/base/commandlineflags.h \\\n                               $(LOGGING_INCLUDES)\n\naddressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \\\n\t$(ADDRESSMAP_UNITTEST_INCLUDES) $(am__append_17)\naddressmap_unittest_CXXFLAGS = -g $(AM_CXXFLAGS)\naddressmap_unittest_LDADD = liblogging.la\n@MINGW_FALSE@system_alloc_unittest_SOURCES = src/config_for_unittests.h \\\n@MINGW_FALSE@                                src/tests/system-alloc_unittest.cc\n\n@MINGW_FALSE@system_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@MINGW_FALSE@system_alloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@MINGW_FALSE@system_alloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\npacked_cache_test_SOURCES = src/tests/packed-cache_test.cc\npacked_cache_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\npacked_cache_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\npacked_cache_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nfrag_unittest_SOURCES = src/tests/frag_unittest.cc src/config_for_unittests.h\nfrag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nfrag_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nfrag_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nmarkidle_unittest_SOURCES = src/tests/markidle_unittest.cc \\\n                            src/config_for_unittests.h \\\n                            src/tests/testutil.h src/tests/testutil.cc\n\nmarkidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nmarkidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nmarkidle_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nmalloc_extension_test_SOURCES = src/tests/malloc_extension_test.cc \\\n                                src/config_for_unittests.h \\\n                                src/base/logging.h \\\n                                src/google/malloc_extension.h \\\n                                src/google/malloc_extension_c.h\n\nmalloc_extension_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nmalloc_extension_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nmalloc_extension_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_SOURCES = src/tests/malloc_extension_c_test.c \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@                                  src/google/malloc_extension.h \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@                                  src/google/malloc_extension_c.h\n\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_CFLAGS =  \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\t$(PTHREAD_CFLAGS) \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\t$(AM_CFLAGS) \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\t$(am__append_20)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n@MINGW_FALSE@memalign_unittest_SOURCES = src/tests/memalign_unittest.cc \\\n@MINGW_FALSE@                            src/tcmalloc.h \\\n@MINGW_FALSE@                            src/config_for_unittests.h \\\n@MINGW_FALSE@                            src/tests/testutil.h src/tests/testutil.cc\n\n@MINGW_FALSE@memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@MINGW_FALSE@memalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@MINGW_FALSE@memalign_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\npage_heap_test_SOURCES = src/tests/page_heap_test.cc \\\n                         src/config_for_unittests.h \\\n                         src/base/logging.h \\\n                         src/common.h \\\n                         src/page_heap.h\n\npage_heap_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\npage_heap_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\npage_heap_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\npagemap_unittest_SOURCES = src/tests/pagemap_unittest.cc \\\n                           src/config_for_unittests.h \\\n                           src/base/logging.h \\\n                           src/pagemap.h\n\npagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\npagemap_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\npagemap_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nrealloc_unittest_SOURCES = src/tests/realloc_unittest.cc \\\n                           src/config_for_unittests.h \\\n                           src/base/logging.h\n\nrealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nrealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nrealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nstack_trace_table_test_SOURCES = src/tests/stack_trace_table_test.cc \\\n                                 src/config_for_unittests.h\n\nstack_trace_table_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nstack_trace_table_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nstack_trace_table_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\nthread_dealloc_unittest_SOURCES = src/tests/thread_dealloc_unittest.cc \\\n                                  src/config_for_unittests.h \\\n                                  src/tests/testutil.h src/tests/testutil.cc\n\nthread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\nthread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\nthread_dealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@libtcmalloc_minimal_debug_la_SOURCES = src/debugallocation.cc \\\n@WITH_DEBUGALLOC_TRUE@                                       $(TCMALLOC_MINIMAL_INCLUDES)\n\n@WITH_DEBUGALLOC_TRUE@libtcmalloc_minimal_debug_la_CXXFLAGS = $(libtcmalloc_minimal_la_CXXFLAGS) \\\n@WITH_DEBUGALLOC_TRUE@                                        -DTCMALLOC_FOR_DEBUGALLOCATION\n\n# version_info gets passed to libtool\n@WITH_DEBUGALLOC_TRUE@libtcmalloc_minimal_debug_la_LDFLAGS = $(libtcmalloc_minimal_la_LDFLAGS) \\\n@WITH_DEBUGALLOC_TRUE@                                       -version-info @TCMALLOC_SO_VERSION@\n\n@WITH_DEBUGALLOC_TRUE@libtcmalloc_minimal_debug_la_LIBADD = $(libtcmalloc_minimal_la_LIBADD)\n@WITH_DEBUGALLOC_TRUE@tcmalloc_minimal_debug_unittest_SOURCES = $(tcmalloc_minimal_unittest_SOURCES)\n@WITH_DEBUGALLOC_TRUE@tcmalloc_minimal_debug_unittest_CXXFLAGS = $(tcmalloc_minimal_unittest_CXXFLAGS) \\\n@WITH_DEBUGALLOC_TRUE@                                           -DDEBUGALLOCATION\n\n@WITH_DEBUGALLOC_TRUE@tcmalloc_minimal_debug_unittest_LDFLAGS = $(tcmalloc_minimal_unittest_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@tcmalloc_minimal_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@malloc_extension_debug_test_SOURCES = $(malloc_extension_test_SOURCES)\n@WITH_DEBUGALLOC_TRUE@malloc_extension_debug_test_CXXFLAGS = $(malloc_extension_test_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@malloc_extension_debug_test_LDFLAGS = $(malloc_extension_test_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@malloc_extension_debug_test_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@memalign_debug_unittest_SOURCES = $(memalign_unittest_SOURCES)\n@WITH_DEBUGALLOC_TRUE@memalign_debug_unittest_CXXFLAGS = $(memalign_unittest_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@memalign_debug_unittest_LDFLAGS = $(memalign_unittest_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@memalign_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@realloc_debug_unittest_SOURCES = $(realloc_unittest_SOURCES)\n@WITH_DEBUGALLOC_TRUE@realloc_debug_unittest_CXXFLAGS = $(realloc_unittest_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@realloc_debug_unittest_LDFLAGS = $(realloc_unittest_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@realloc_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@debugallocation_test_sh_SOURCES = src/tests/debugallocation_test.sh\n@WITH_DEBUGALLOC_TRUE@debugallocation_test_SOURCES = src/tests/debugallocation_test.cc\n@WITH_DEBUGALLOC_TRUE@debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@debugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_DEBUGALLOC_TRUE@debugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n\n### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)\n\n### The header files we use.  We divide into categories based on directory\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@S_TCMALLOC_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      $(LOGGING_INCLUDES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/addressmap-inl.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/raw_printer.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/elfcore.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/googleinit.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/linux_syscall_support.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/linuxthreads.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/stl_allocator.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/sysinfo.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/base/thread_lister.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                      src/heap-profile-table.h\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@SG_TCMALLOC_INCLUDES = $(SG_TCMALLOC_MINIMAL_INCLUDES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                       src/google/heap-profiler.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                       src/google/heap-checker.h\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@TCMALLOC_INCLUDES = $(S_TCMALLOC_INCLUDES) $(SG_TCMALLOC_INCLUDES)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_SOURCES = $(libtcmalloc_minimal_internal_la_SOURCES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                  $(TCMALLOC_INCLUDES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                  src/base/low_level_alloc.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                  src/heap-profile-table.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                  src/heap-profiler.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                  src/raw_printer.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                  src/memory_region_map.cc\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_CXXFLAGS =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(PTHREAD_CFLAGS) -DNDEBUG \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(AM_CXXFLAGS) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(NO_EXCEPTIONS) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__append_31)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_LDFLAGS = $(PTHREAD_CFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_LIBADD = libstacktrace.la $(PTHREAD_LIBS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_SOURCES =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(TCMALLOC_CC) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(TCMALLOC_INCLUDES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__append_30)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_CXXFLAGS =  \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(PTHREAD_CFLAGS) -DNDEBUG \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(AM_CXXFLAGS) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\t$(am__append_32)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_LIBADD = libtcmalloc_internal.la $(PTHREAD_LIBS)\n@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@HEAP_CHECKER_SOURCES = \n\n# heap-checker-bcad is last, in hopes its global ctor will run first.\n# (Note this is added to libtcmalloc.la, not libtcmalloc_internal.la,\n# but that's ok; the internal/external distinction is only useful for\n# cygwin, and cygwin doesn't use HEAP_CHECKER anyway.)\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@HEAP_CHECKER_SOURCES = src/base/thread_lister.c \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                       src/base/linuxthreads.cc \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                       src/heap-checker.cc \\\n@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                       src/heap-checker-bcad.cc\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@LIBTCMALLOC = libtcmalloc.la\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@TCMALLOC_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                             src/google/malloc_extension.h\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                            src/tcmalloc.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                            src/tests/testutil.h src/tests/testutil.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                            $(TCMALLOC_UNITTEST_INCLUDES)\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_LDADD = $(LIBTCMALLOC) liblogging.la $(PTHREAD_LIBS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                 src/tests/testutil.h src/tests/testutil.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                 $(TCMALLOC_UNITTEST_INCLUDES)\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_LDADD = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \\\n@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                               liblogging.la $(PTHREAD_LIBS)\n\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_LDADD = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                               libprofiler.la liblogging.la $(PTHREAD_LIBS)\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@raw_printer_test_SOURCES = src/tests/raw_printer_test.cc\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@raw_printer_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@raw_printer_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@raw_printer_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_test_SOURCES = src/tests/sampler_test.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                       src/config_for_unittests.h\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS) -lm\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test_sh_SOURCES = src/tests/sampling_test.sh\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@SAMPLING_TEST_INCLUDES = src/config_for_unittests.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                         src/base/logging.h \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                         src/google/malloc_extension.h\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test_SOURCES = src/tests/sampling_test.cc \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                        $(SAMPLING_TEST_INCLUDES)\n\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh\n@WITH_HEAP_PROFILER_TRUE@HEAP_PROFILER_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n@WITH_HEAP_PROFILER_TRUE@                                  src/google/heap-profiler.h\n\n@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \\\n@WITH_HEAP_PROFILER_TRUE@                                 $(HEAP_PROFILER_UNITTEST_INCLUDES)\n\n@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)\n@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh\n@WITH_HEAP_CHECKER_TRUE@heap_checker_death_unittest_sh_SOURCES = src/tests/heap-checker-death_unittest.sh\n@WITH_HEAP_CHECKER_TRUE@HEAP_CHECKER_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n@WITH_HEAP_CHECKER_TRUE@                                 src/memory_region_map.h \\\n@WITH_HEAP_CHECKER_TRUE@                                 src/base/commandlineflags.h \\\n@WITH_HEAP_CHECKER_TRUE@                                 src/base/googleinit.h \\\n@WITH_HEAP_CHECKER_TRUE@                                 src/google/heap-checker.h \\\n@WITH_HEAP_CHECKER_TRUE@                                 $(LOGGING_INCLUDES)\n\n@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \\\n@WITH_HEAP_CHECKER_TRUE@                                $(HEAP_CHECKER_UNITTEST_INCLUDES)\n\n@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n# We also put pthreads after tcmalloc, because some pthread\n# implementations define their own malloc, and we need to go on the\n# first linkline to make sure our malloc 'wins'.\n@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_LDADD = $(LIBTCMALLOC) liblogging.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_debug_la_SOURCES = src/debugallocation.cc $(HEAP_CHECKER_SOURCES) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                               $(TCMALLOC_INCLUDES)\n\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_debug_la_CXXFLAGS = $(libtcmalloc_la_CXXFLAGS) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                -DTCMALLOC_FOR_DEBUGALLOCATION\n\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_debug_la_LDFLAGS = $(libtcmalloc_la_LDFLAGS) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                               -version-info @TCMALLOC_SO_VERSION@\n\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_debug_la_LIBADD = $(libtcmalloc_la_LIBADD)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_debug_unittest_SOURCES = $(tcmalloc_unittest_SOURCES)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_debug_unittest_CXXFLAGS = $(tcmalloc_unittest_CXXFLAGS) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                   -DDEBUGALLOCATION\n\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_debug_unittest_LDFLAGS = $(tcmalloc_unittest_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_debug_unittest_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_debug_test_SOURCES = $(sampler_test_SOURCES)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_debug_test_CXXFLAGS = $(samples_test_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_debug_test_LDFLAGS = $(sampler_test_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampler_debug_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS) -lm\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test_sh_SOURCES = src/tests/sampling_test.sh\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test_SOURCES = $(sampling_test_SOURCES)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test_CXXFLAGS = $(sampling_test_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test_LDFLAGS = $(sampling_test_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap_profiler_debug_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap_profiler_debug_unittest_SOURCES = $(heap_profiler_unittest_SOURCES)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap_profiler_debug_unittest_CXXFLAGS = $(heap_profiler_unittest_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap_profiler_debug_unittest_LDFLAGS = $(heap_profiler_unittest_LDFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap_profiler_debug_unittest_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap_checker_debug_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap_checker_debug_unittest_SOURCES = $(heap_checker_unittest_SOURCES)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap_checker_debug_unittest_CXXFLAGS = $(heap_checker_unittest_CXXFLAGS)\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap_checker_debug_unittest_LDFLAGS = $(heap_checker_unittest_LDFLAGS)\n# We want libtcmalloc last on the link line, but due to a bug in\n# libtool involving convenience libs, they need to come last on the\n# link line in order to get dependency ordering right.  This is ok:\n# convenience libraries are .a's, so tcmalloc is still the last .so.\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap_checker_debug_unittest_LDADD = libtcmalloc_debug.la liblogging.la \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@                                    $(PTHREAD_LIBS)\n\n\n### ------- CPU profiler\n\n### The header files we use.  We divide into categories based on directory\n@WITH_CPU_PROFILER_TRUE@S_CPU_PROFILER_INCLUDES = src/profiledata.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/profile-handler.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/getpc.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/base/basictypes.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/base/commandlineflags.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/base/googleinit.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/base/logging.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/base/simple_mutex.h \\\n@WITH_CPU_PROFILER_TRUE@                          src/base/sysinfo.h \\\n@WITH_CPU_PROFILER_TRUE@                          $(SPINLOCK_INCLUDES) \\\n@WITH_CPU_PROFILER_TRUE@                          $(LOGGING_INCLUDES)\n\n@WITH_CPU_PROFILER_TRUE@SG_CPU_PROFILER_INCLUDES = src/google/profiler.h \\\n@WITH_CPU_PROFILER_TRUE@                           src/google/stacktrace.h\n\n@WITH_CPU_PROFILER_TRUE@CPU_PROFILER_INCLUDES = $(S_CPU_PROFILER_INCLUDES) $(SG_CPU_PROFILER_INCLUDES)\n@WITH_CPU_PROFILER_TRUE@libprofiler_la_SOURCES = src/profiler.cc \\\n@WITH_CPU_PROFILER_TRUE@                         src/profile-handler.cc \\\n@WITH_CPU_PROFILER_TRUE@                         src/profiledata.cc \\\n@WITH_CPU_PROFILER_TRUE@                         $(CPU_PROFILER_INCLUDES)\n\n@WITH_CPU_PROFILER_TRUE@libprofiler_la_LIBADD = libstacktrace.la\n# We have to include ProfileData for profiledata_unittest\n@WITH_CPU_PROFILER_TRUE@CPU_PROFILER_SYMBOLS = '(ProfilerStart|ProfilerStartWithOptions|ProfilerStop|ProfilerFlush|ProfilerEnable|ProfilerDisable|ProfilingIsEnabledForAllThreads|ProfilerRegisterThread|ProfilerGetCurrentState|ProfilerState|ProfileData|ProfileHandler)'\n@WITH_CPU_PROFILER_TRUE@libprofiler_la_LDFLAGS = -export-symbols-regex $(CPU_PROFILER_SYMBOLS) \\\n@WITH_CPU_PROFILER_TRUE@                         -version-info @PROFILER_SO_VERSION@\n\n\n# See discussion above (under LIBTCMALLOC_MINIMAL) for why we do this.\n# Basically it's to work around systems where --rpath doesn't work right.\n@WITH_CPU_PROFILER_TRUE@LIBPROFILER = libstacktrace.la libprofiler.la\n#WINDOWS_PROJECTS += vsprojects/getpc_test/getpc_test.vcproj\n@WITH_CPU_PROFILER_TRUE@getpc_test_SOURCES = src/tests/getpc_test.cc src/getpc.h\n#WINDOWS_PROJECTS += vsprojects/profiledata_unittest/profiledata_unittest.vcproj\n@WITH_CPU_PROFILER_TRUE@profiledata_unittest_SOURCES = src/tests/profiledata_unittest.cc \\\n@WITH_CPU_PROFILER_TRUE@                               src/profiledata.h \\\n@WITH_CPU_PROFILER_TRUE@                               src/base/commandlineflags.h \\\n@WITH_CPU_PROFILER_TRUE@                               src/base/logging.h \\\n@WITH_CPU_PROFILER_TRUE@                               src/base/basictypes.h\n\n@WITH_CPU_PROFILER_TRUE@profiledata_unittest_LDADD = $(LIBPROFILER)\n@WITH_CPU_PROFILER_TRUE@profile_handler_unittest_SOURCES = src/tests/profile-handler_unittest.cc \\\n@WITH_CPU_PROFILER_TRUE@                                   src/profile-handler.h\n\n@WITH_CPU_PROFILER_TRUE@profile_handler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)\n@WITH_CPU_PROFILER_TRUE@profile_handler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\n@WITH_CPU_PROFILER_TRUE@profile_handler_unittest_LDADD = $(LIBPROFILER) $(PTHREAD_LIBS)\n@WITH_CPU_PROFILER_TRUE@profiler_unittest_sh_SOURCES = src/tests/profiler_unittest.sh\n@WITH_CPU_PROFILER_TRUE@PROFILER_UNITTEST_INCLUDES = src/config_for_unittests.h \\\n@WITH_CPU_PROFILER_TRUE@                             src/google/profiler.h\n\n@WITH_CPU_PROFILER_TRUE@PROFILER_UNITTEST_SRCS = src/tests/profiler_unittest.cc \\\n@WITH_CPU_PROFILER_TRUE@                         src/tests/testutil.h src/tests/testutil.cc \\\n@WITH_CPU_PROFILER_TRUE@                         $(PROFILER_UNITTEST_INCLUDES)\n\n@WITH_CPU_PROFILER_TRUE@profiler1_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\n@WITH_CPU_PROFILER_TRUE@profiler1_unittest_CXXFLAGS = -g -DNO_THREADS $(AM_CXXFLAGS)\n@WITH_CPU_PROFILER_TRUE@profiler1_unittest_LDADD = $(LIBPROFILER)\n@WITH_CPU_PROFILER_TRUE@profiler2_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\n@WITH_CPU_PROFILER_TRUE@profiler2_unittest_CXXFLAGS = -g -DNO_THREADS $(AM_CXXFLAGS)\n@WITH_CPU_PROFILER_TRUE@profiler2_unittest_LDADD = -lstacktrace -lprofiler\n# We depend on -lprofiler but haven't yet said how to build it.  Do so now.\n@WITH_CPU_PROFILER_TRUE@profiler2_unittest_DEPENDENCIES = $(LIBPROFILER)\n@WITH_CPU_PROFILER_TRUE@profiler3_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\n@WITH_CPU_PROFILER_TRUE@profiler3_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_CPU_PROFILER_TRUE@profiler3_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\n@WITH_CPU_PROFILER_TRUE@profiler3_unittest_LDADD = $(LIBPROFILER) $(PTHREAD_LIBS)\n@WITH_CPU_PROFILER_TRUE@profiler4_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)\n@WITH_CPU_PROFILER_TRUE@profiler4_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)\n@WITH_CPU_PROFILER_TRUE@profiler4_unittest_LDFLAGS = $(PTHREAD_CFLAGS)\n@WITH_CPU_PROFILER_TRUE@profiler4_unittest_LDADD = -lstacktrace -lprofiler $(PTHREAD_LIBS)\n# We depend on -lprofiler but haven't yet said how to build it.  Do so now.\n@WITH_CPU_PROFILER_TRUE@profiler4_unittest_DEPENDENCIES = $(LIBPROFILER)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_and_profiler_la_SOURCES = $(libtcmalloc_la_SOURCES) $(libprofiler_la_SOURCES)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_and_profiler_la_CXXFLAGS = $(libtcmalloc_la_CXXFLAGS) $(libprofiler_la_CXXFLAGS)\n# Since this library is meant to be used as a .a, I don't worry as much\n# about .so versioning.  I just give the libtcmalloc version number.\n# TODO(csilvers): use -export-symbols-regex?\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_and_profiler_la_LDFLAGS = $(PTHREAD_CFLAGS) \\\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                      -version-info @TCMALLOC_SO_VERSION@\n\n# We don't include libprofiler_la_LIBADD here because all it adds is\n# libstacktrace.la, which we already get via libtcmalloc.  Trying to\n# specify it twice causes link-time duplicate-definition errors. :-(\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_and_profiler_la_LIBADD = $(libtcmalloc_la_LIBADD)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_and_profiler_unittest_SOURCES = $(tcmalloc_both_unittest_SOURCES)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_and_profiler_unittest_CXXFLAGS = $(tcmalloc_both_unittest_CXXFLAGS)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_and_profiler_unittest_LDFLAGS = $(tcmalloc_both_unittest_LDFLAGS)\n@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_and_profiler_unittest_LDADD = libtcmalloc_and_profiler.la\n\n# http://linux.die.net/man/1/pkg-config, http://pkg-config.freedesktop.org/wiki\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = libtcmalloc.pc libtcmalloc_minimal.pc \\\n                 libtcmalloc_debug.pc libtcmalloc_minimal_debug.pc \\\n                 libprofiler.pc\n\nCLEANFILES = $(pkgconfig_DATA)\nEXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \\\n             $(SCRIPTS) libtool \\\n             src/windows/get_mangled_names.cc src/windows/override_functions.cc \\\n             src/windows/config.h src/windows/google/tcmalloc.h \\\n             $(WINDOWS_PROJECTS) \\\n             src/solaris/libstdc++.la\n\nall: all-am\n\n.SUFFIXES:\n.SUFFIXES: .c .cc .lo .o .obj\nam--refresh:\n\t@:\n$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)\n\t@for dep in $?; do \\\n\t  case '$(am__configure_deps)' in \\\n\t    *$$dep*) \\\n\t      echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \\\n\t      cd $(srcdir) && $(AUTOMAKE) --gnu  \\\n\t\t&& exit 0; \\\n\t      exit 1;; \\\n\t  esac; \\\n\tdone; \\\n\techo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Makefile'; \\\n\tcd $(top_srcdir) && \\\n\t  $(AUTOMAKE) --gnu  Makefile\n.PRECIOUS: Makefile\nMakefile: $(srcdir)/Makefile.in $(top_builddir)/config.status\n\t@case '$?' in \\\n\t  *config.status*) \\\n\t    echo ' $(SHELL) ./config.status'; \\\n\t    $(SHELL) ./config.status;; \\\n\t  *) \\\n\t    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \\\n\t    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \\\n\tesac;\n\n$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)\n\t$(SHELL) ./config.status --recheck\n\n$(top_srcdir)/configure:  $(am__configure_deps)\n\tcd $(srcdir) && $(AUTOCONF)\n$(ACLOCAL_M4):  $(am__aclocal_m4_deps)\n\tcd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)\n\nsrc/config.h: src/stamp-h1\n\t@if test ! -f $@; then \\\n\t  rm -f src/stamp-h1; \\\n\t  $(MAKE) src/stamp-h1; \\\n\telse :; fi\n\nsrc/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status\n\t@rm -f src/stamp-h1\n\tcd $(top_builddir) && $(SHELL) ./config.status src/config.h\n$(top_srcdir)/src/config.h.in:  $(am__configure_deps) \n\tcd $(top_srcdir) && $(AUTOHEADER)\n\trm -f src/stamp-h1\n\ttouch $@\n\ndistclean-hdr:\n\t-rm -f src/config.h src/stamp-h1\nsrc/google/tcmalloc.h: $(top_builddir)/config.status $(top_srcdir)/src/google/tcmalloc.h.in\n\tcd $(top_builddir) && $(SHELL) ./config.status $@\ninstall-libLTLIBRARIES: $(lib_LTLIBRARIES)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(libdir)\" || $(mkdir_p) \"$(DESTDIR)$(libdir)\"\n\t@list='$(lib_LTLIBRARIES)'; for p in $$list; do \\\n\t  if test -f $$p; then \\\n\t    f=$(am__strip_dir) \\\n\t    echo \" $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'\"; \\\n\t    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) \"$$p\" \"$(DESTDIR)$(libdir)/$$f\"; \\\n\t  else :; fi; \\\n\tdone\n\nuninstall-libLTLIBRARIES:\n\t@$(NORMAL_UNINSTALL)\n\t@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \\\n\t  p=$(am__strip_dir) \\\n\t  echo \" $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'\"; \\\n\t  $(LIBTOOL) --mode=uninstall rm -f \"$(DESTDIR)$(libdir)/$$p\"; \\\n\tdone\n\nclean-libLTLIBRARIES:\n\t-test -z \"$(lib_LTLIBRARIES)\" || rm -f $(lib_LTLIBRARIES)\n\t@list='$(lib_LTLIBRARIES)'; for p in $$list; do \\\n\t  dir=\"`echo $$p | sed -e 's|/[^/]*$$||'`\"; \\\n\t  test \"$$dir\" != \"$$p\" || dir=.; \\\n\t  echo \"rm -f \\\"$${dir}/so_locations\\\"\"; \\\n\t  rm -f \"$${dir}/so_locations\"; \\\n\tdone\n\nclean-noinstLTLIBRARIES:\n\t-test -z \"$(noinst_LTLIBRARIES)\" || rm -f $(noinst_LTLIBRARIES)\n\t@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \\\n\t  dir=\"`echo $$p | sed -e 's|/[^/]*$$||'`\"; \\\n\t  test \"$$dir\" != \"$$p\" || dir=.; \\\n\t  echo \"rm -f \\\"$${dir}/so_locations\\\"\"; \\\n\t  rm -f \"$${dir}/so_locations\"; \\\n\tdone\nliblogging.la: $(liblogging_la_OBJECTS) $(liblogging_la_DEPENDENCIES) \n\t$(CXXLINK)  $(liblogging_la_LDFLAGS) $(liblogging_la_OBJECTS) $(liblogging_la_LIBADD) $(LIBS)\nlibprofiler.la: $(libprofiler_la_OBJECTS) $(libprofiler_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libprofiler_la_rpath) $(libprofiler_la_LDFLAGS) $(libprofiler_la_OBJECTS) $(libprofiler_la_LIBADD) $(LIBS)\nlibspinlock.la: $(libspinlock_la_OBJECTS) $(libspinlock_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libspinlock_la_rpath) $(libspinlock_la_LDFLAGS) $(libspinlock_la_OBJECTS) $(libspinlock_la_LIBADD) $(LIBS)\nlibstacktrace.la: $(libstacktrace_la_OBJECTS) $(libstacktrace_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libstacktrace_la_rpath) $(libstacktrace_la_LDFLAGS) $(libstacktrace_la_OBJECTS) $(libstacktrace_la_LIBADD) $(LIBS)\nlibsysinfo.la: $(libsysinfo_la_OBJECTS) $(libsysinfo_la_DEPENDENCIES) \n\t$(CXXLINK)  $(libsysinfo_la_LDFLAGS) $(libsysinfo_la_OBJECTS) $(libsysinfo_la_LIBADD) $(LIBS)\nlibtcmalloc.la: $(libtcmalloc_la_OBJECTS) $(libtcmalloc_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libtcmalloc_la_rpath) $(libtcmalloc_la_LDFLAGS) $(libtcmalloc_la_OBJECTS) $(libtcmalloc_la_LIBADD) $(LIBS)\nlibtcmalloc_and_profiler.la: $(libtcmalloc_and_profiler_la_OBJECTS) $(libtcmalloc_and_profiler_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libtcmalloc_and_profiler_la_rpath) $(libtcmalloc_and_profiler_la_LDFLAGS) $(libtcmalloc_and_profiler_la_OBJECTS) $(libtcmalloc_and_profiler_la_LIBADD) $(LIBS)\nlibtcmalloc_debug.la: $(libtcmalloc_debug_la_OBJECTS) $(libtcmalloc_debug_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libtcmalloc_debug_la_rpath) $(libtcmalloc_debug_la_LDFLAGS) $(libtcmalloc_debug_la_OBJECTS) $(libtcmalloc_debug_la_LIBADD) $(LIBS)\nlibtcmalloc_internal.la: $(libtcmalloc_internal_la_OBJECTS) $(libtcmalloc_internal_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libtcmalloc_internal_la_rpath) $(libtcmalloc_internal_la_LDFLAGS) $(libtcmalloc_internal_la_OBJECTS) $(libtcmalloc_internal_la_LIBADD) $(LIBS)\nlibtcmalloc_minimal.la: $(libtcmalloc_minimal_la_OBJECTS) $(libtcmalloc_minimal_la_DEPENDENCIES) \n\t$(CXXLINK) -rpath $(libdir) $(libtcmalloc_minimal_la_LDFLAGS) $(libtcmalloc_minimal_la_OBJECTS) $(libtcmalloc_minimal_la_LIBADD) $(LIBS)\nlibtcmalloc_minimal_debug.la: $(libtcmalloc_minimal_debug_la_OBJECTS) $(libtcmalloc_minimal_debug_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libtcmalloc_minimal_debug_la_rpath) $(libtcmalloc_minimal_debug_la_LDFLAGS) $(libtcmalloc_minimal_debug_la_OBJECTS) $(libtcmalloc_minimal_debug_la_LIBADD) $(LIBS)\nlibtcmalloc_minimal_internal.la: $(libtcmalloc_minimal_internal_la_OBJECTS) $(libtcmalloc_minimal_internal_la_DEPENDENCIES) \n\t$(CXXLINK)  $(libtcmalloc_minimal_internal_la_LDFLAGS) $(libtcmalloc_minimal_internal_la_OBJECTS) $(libtcmalloc_minimal_internal_la_LIBADD) $(LIBS)\nlibwindows.la: $(libwindows_la_OBJECTS) $(libwindows_la_DEPENDENCIES) \n\t$(CXXLINK) $(am_libwindows_la_rpath) $(libwindows_la_LDFLAGS) $(libwindows_la_OBJECTS) $(libwindows_la_LIBADD) $(LIBS)\ninstall-binPROGRAMS: $(bin_PROGRAMS)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(bindir)\" || $(mkdir_p) \"$(DESTDIR)$(bindir)\"\n\t@list='$(bin_PROGRAMS)'; for p in $$list; do \\\n\t  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \\\n\t  if test -f $$p \\\n\t     || test -f $$p1 \\\n\t  ; then \\\n\t    f=`echo \"$$p1\" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \\\n\t   echo \" $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'\"; \\\n\t   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) \"$$p\" \"$(DESTDIR)$(bindir)/$$f\" || exit 1; \\\n\t  else :; fi; \\\n\tdone\n\nuninstall-binPROGRAMS:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(bin_PROGRAMS)'; for p in $$list; do \\\n\t  f=`echo \"$$p\" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \\\n\t  echo \" rm -f '$(DESTDIR)$(bindir)/$$f'\"; \\\n\t  rm -f \"$(DESTDIR)$(bindir)/$$f\"; \\\n\tdone\n\nclean-binPROGRAMS:\n\t@list='$(bin_PROGRAMS)'; for p in $$list; do \\\n\t  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \\\n\t  echo \" rm -f $$p $$f\"; \\\n\t  rm -f $$p $$f ; \\\n\tdone\n\nclean-noinstPROGRAMS:\n\t@list='$(noinst_PROGRAMS)'; for p in $$list; do \\\n\t  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \\\n\t  echo \" rm -f $$p $$f\"; \\\n\t  rm -f $$p $$f ; \\\n\tdone\naddressmap_unittest$(EXEEXT): $(addressmap_unittest_OBJECTS) $(addressmap_unittest_DEPENDENCIES) \n\t@rm -f addressmap_unittest$(EXEEXT)\n\t$(CXXLINK) $(addressmap_unittest_LDFLAGS) $(addressmap_unittest_OBJECTS) $(addressmap_unittest_LDADD) $(LIBS)\natomicops_unittest$(EXEEXT): $(atomicops_unittest_OBJECTS) $(atomicops_unittest_DEPENDENCIES) \n\t@rm -f atomicops_unittest$(EXEEXT)\n\t$(CXXLINK) $(atomicops_unittest_LDFLAGS) $(atomicops_unittest_OBJECTS) $(atomicops_unittest_LDADD) $(LIBS)\ndebugallocation_test$(EXEEXT): $(debugallocation_test_OBJECTS) $(debugallocation_test_DEPENDENCIES) \n\t@rm -f debugallocation_test$(EXEEXT)\n\t$(CXXLINK) $(debugallocation_test_LDFLAGS) $(debugallocation_test_OBJECTS) $(debugallocation_test_LDADD) $(LIBS)\n@WITH_DEBUGALLOC_FALSE@debugallocation_test.sh$(EXEEXT): $(debugallocation_test_sh_OBJECTS) $(debugallocation_test_sh_DEPENDENCIES) \n@WITH_DEBUGALLOC_FALSE@\t@rm -f debugallocation_test.sh$(EXEEXT)\n@WITH_DEBUGALLOC_FALSE@\t$(LINK) $(debugallocation_test_sh_LDFLAGS) $(debugallocation_test_sh_OBJECTS) $(debugallocation_test_sh_LDADD) $(LIBS)\nfrag_unittest$(EXEEXT): $(frag_unittest_OBJECTS) $(frag_unittest_DEPENDENCIES) \n\t@rm -f frag_unittest$(EXEEXT)\n\t$(CXXLINK) $(frag_unittest_LDFLAGS) $(frag_unittest_OBJECTS) $(frag_unittest_LDADD) $(LIBS)\ngetpc_test$(EXEEXT): $(getpc_test_OBJECTS) $(getpc_test_DEPENDENCIES) \n\t@rm -f getpc_test$(EXEEXT)\n\t$(CXXLINK) $(getpc_test_LDFLAGS) $(getpc_test_OBJECTS) $(getpc_test_LDADD) $(LIBS)\n@WITH_HEAP_CHECKER_FALSE@heap-checker-death_unittest.sh$(EXEEXT): $(heap_checker_death_unittest_sh_OBJECTS) $(heap_checker_death_unittest_sh_DEPENDENCIES) \n@WITH_HEAP_CHECKER_FALSE@\t@rm -f heap-checker-death_unittest.sh$(EXEEXT)\n@WITH_HEAP_CHECKER_FALSE@\t$(LINK) $(heap_checker_death_unittest_sh_LDFLAGS) $(heap_checker_death_unittest_sh_OBJECTS) $(heap_checker_death_unittest_sh_LDADD) $(LIBS)\nheap-checker_debug_unittest$(EXEEXT): $(heap_checker_debug_unittest_OBJECTS) $(heap_checker_debug_unittest_DEPENDENCIES) \n\t@rm -f heap-checker_debug_unittest$(EXEEXT)\n\t$(CXXLINK) $(heap_checker_debug_unittest_LDFLAGS) $(heap_checker_debug_unittest_OBJECTS) $(heap_checker_debug_unittest_LDADD) $(LIBS)\n@WITH_DEBUGALLOC_FALSE@heap-checker_debug_unittest.sh$(EXEEXT): $(heap_checker_debug_unittest_sh_OBJECTS) $(heap_checker_debug_unittest_sh_DEPENDENCIES) \n@WITH_DEBUGALLOC_FALSE@\t@rm -f heap-checker_debug_unittest.sh$(EXEEXT)\n@WITH_DEBUGALLOC_FALSE@\t$(LINK) $(heap_checker_debug_unittest_sh_LDFLAGS) $(heap_checker_debug_unittest_sh_OBJECTS) $(heap_checker_debug_unittest_sh_LDADD) $(LIBS)\n@WITH_HEAP_CHECKER_FALSE@heap-checker_debug_unittest.sh$(EXEEXT): $(heap_checker_debug_unittest_sh_OBJECTS) $(heap_checker_debug_unittest_sh_DEPENDENCIES) \n@WITH_HEAP_CHECKER_FALSE@\t@rm -f heap-checker_debug_unittest.sh$(EXEEXT)\n@WITH_HEAP_CHECKER_FALSE@\t$(LINK) $(heap_checker_debug_unittest_sh_LDFLAGS) $(heap_checker_debug_unittest_sh_OBJECTS) $(heap_checker_debug_unittest_sh_LDADD) $(LIBS)\nheap-checker_unittest$(EXEEXT): $(heap_checker_unittest_OBJECTS) $(heap_checker_unittest_DEPENDENCIES) \n\t@rm -f heap-checker_unittest$(EXEEXT)\n\t$(CXXLINK) $(heap_checker_unittest_LDFLAGS) $(heap_checker_unittest_OBJECTS) $(heap_checker_unittest_LDADD) $(LIBS)\n@WITH_HEAP_CHECKER_FALSE@heap-checker_unittest.sh$(EXEEXT): $(heap_checker_unittest_sh_OBJECTS) $(heap_checker_unittest_sh_DEPENDENCIES) \n@WITH_HEAP_CHECKER_FALSE@\t@rm -f heap-checker_unittest.sh$(EXEEXT)\n@WITH_HEAP_CHECKER_FALSE@\t$(LINK) $(heap_checker_unittest_sh_LDFLAGS) $(heap_checker_unittest_sh_OBJECTS) $(heap_checker_unittest_sh_LDADD) $(LIBS)\nheap-profiler_debug_unittest$(EXEEXT): $(heap_profiler_debug_unittest_OBJECTS) $(heap_profiler_debug_unittest_DEPENDENCIES) \n\t@rm -f heap-profiler_debug_unittest$(EXEEXT)\n\t$(CXXLINK) $(heap_profiler_debug_unittest_LDFLAGS) $(heap_profiler_debug_unittest_OBJECTS) $(heap_profiler_debug_unittest_LDADD) $(LIBS)\n@WITH_DEBUGALLOC_FALSE@heap-profiler_debug_unittest.sh$(EXEEXT): $(heap_profiler_debug_unittest_sh_OBJECTS) $(heap_profiler_debug_unittest_sh_DEPENDENCIES) \n@WITH_DEBUGALLOC_FALSE@\t@rm -f heap-profiler_debug_unittest.sh$(EXEEXT)\n@WITH_DEBUGALLOC_FALSE@\t$(LINK) $(heap_profiler_debug_unittest_sh_LDFLAGS) $(heap_profiler_debug_unittest_sh_OBJECTS) $(heap_profiler_debug_unittest_sh_LDADD) $(LIBS)\n@WITH_HEAP_PROFILER_FALSE@heap-profiler_debug_unittest.sh$(EXEEXT): $(heap_profiler_debug_unittest_sh_OBJECTS) $(heap_profiler_debug_unittest_sh_DEPENDENCIES) \n@WITH_HEAP_PROFILER_FALSE@\t@rm -f heap-profiler_debug_unittest.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_FALSE@\t$(LINK) $(heap_profiler_debug_unittest_sh_LDFLAGS) $(heap_profiler_debug_unittest_sh_OBJECTS) $(heap_profiler_debug_unittest_sh_LDADD) $(LIBS)\nheap-profiler_unittest$(EXEEXT): $(heap_profiler_unittest_OBJECTS) $(heap_profiler_unittest_DEPENDENCIES) \n\t@rm -f heap-profiler_unittest$(EXEEXT)\n\t$(CXXLINK) $(heap_profiler_unittest_LDFLAGS) $(heap_profiler_unittest_OBJECTS) $(heap_profiler_unittest_LDADD) $(LIBS)\n@WITH_HEAP_PROFILER_FALSE@heap-profiler_unittest.sh$(EXEEXT): $(heap_profiler_unittest_sh_OBJECTS) $(heap_profiler_unittest_sh_DEPENDENCIES) \n@WITH_HEAP_PROFILER_FALSE@\t@rm -f heap-profiler_unittest.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_FALSE@\t$(LINK) $(heap_profiler_unittest_sh_LDFLAGS) $(heap_profiler_unittest_sh_OBJECTS) $(heap_profiler_unittest_sh_LDADD) $(LIBS)\nlow_level_alloc_unittest$(EXEEXT): $(low_level_alloc_unittest_OBJECTS) $(low_level_alloc_unittest_DEPENDENCIES) \n\t@rm -f low_level_alloc_unittest$(EXEEXT)\n\t$(CXXLINK) $(low_level_alloc_unittest_LDFLAGS) $(low_level_alloc_unittest_OBJECTS) $(low_level_alloc_unittest_LDADD) $(LIBS)\nmalloc_extension_c_test$(EXEEXT): $(malloc_extension_c_test_OBJECTS) $(malloc_extension_c_test_DEPENDENCIES) \n\t@rm -f malloc_extension_c_test$(EXEEXT)\n\t$(LINK) $(malloc_extension_c_test_LDFLAGS) $(malloc_extension_c_test_OBJECTS) $(malloc_extension_c_test_LDADD) $(LIBS)\nmalloc_extension_debug_test$(EXEEXT): $(malloc_extension_debug_test_OBJECTS) $(malloc_extension_debug_test_DEPENDENCIES) \n\t@rm -f malloc_extension_debug_test$(EXEEXT)\n\t$(CXXLINK) $(malloc_extension_debug_test_LDFLAGS) $(malloc_extension_debug_test_OBJECTS) $(malloc_extension_debug_test_LDADD) $(LIBS)\nmalloc_extension_test$(EXEEXT): $(malloc_extension_test_OBJECTS) $(malloc_extension_test_DEPENDENCIES) \n\t@rm -f malloc_extension_test$(EXEEXT)\n\t$(CXXLINK) $(malloc_extension_test_LDFLAGS) $(malloc_extension_test_OBJECTS) $(malloc_extension_test_LDADD) $(LIBS)\nmarkidle_unittest$(EXEEXT): $(markidle_unittest_OBJECTS) $(markidle_unittest_DEPENDENCIES) \n\t@rm -f markidle_unittest$(EXEEXT)\n\t$(CXXLINK) $(markidle_unittest_LDFLAGS) $(markidle_unittest_OBJECTS) $(markidle_unittest_LDADD) $(LIBS)\n@ENABLE_STATIC_TRUE@maybe_threads_unittest.sh$(EXEEXT): $(maybe_threads_unittest_sh_OBJECTS) $(maybe_threads_unittest_sh_DEPENDENCIES) \n@ENABLE_STATIC_TRUE@\t@rm -f maybe_threads_unittest.sh$(EXEEXT)\n@ENABLE_STATIC_TRUE@\t$(LINK) $(maybe_threads_unittest_sh_LDFLAGS) $(maybe_threads_unittest_sh_OBJECTS) $(maybe_threads_unittest_sh_LDADD) $(LIBS)\n@MINGW_TRUE@maybe_threads_unittest.sh$(EXEEXT): $(maybe_threads_unittest_sh_OBJECTS) $(maybe_threads_unittest_sh_DEPENDENCIES) \n@MINGW_TRUE@\t@rm -f maybe_threads_unittest.sh$(EXEEXT)\n@MINGW_TRUE@\t$(LINK) $(maybe_threads_unittest_sh_LDFLAGS) $(maybe_threads_unittest_sh_OBJECTS) $(maybe_threads_unittest_sh_LDADD) $(LIBS)\nmemalign_debug_unittest$(EXEEXT): $(memalign_debug_unittest_OBJECTS) $(memalign_debug_unittest_DEPENDENCIES) \n\t@rm -f memalign_debug_unittest$(EXEEXT)\n\t$(CXXLINK) $(memalign_debug_unittest_LDFLAGS) $(memalign_debug_unittest_OBJECTS) $(memalign_debug_unittest_LDADD) $(LIBS)\nmemalign_unittest$(EXEEXT): $(memalign_unittest_OBJECTS) $(memalign_unittest_DEPENDENCIES) \n\t@rm -f memalign_unittest$(EXEEXT)\n\t$(CXXLINK) $(memalign_unittest_LDFLAGS) $(memalign_unittest_OBJECTS) $(memalign_unittest_LDADD) $(LIBS)\npacked_cache_test$(EXEEXT): $(packed_cache_test_OBJECTS) $(packed_cache_test_DEPENDENCIES) \n\t@rm -f packed_cache_test$(EXEEXT)\n\t$(CXXLINK) $(packed_cache_test_LDFLAGS) $(packed_cache_test_OBJECTS) $(packed_cache_test_LDADD) $(LIBS)\npage_heap_test$(EXEEXT): $(page_heap_test_OBJECTS) $(page_heap_test_DEPENDENCIES) \n\t@rm -f page_heap_test$(EXEEXT)\n\t$(CXXLINK) $(page_heap_test_LDFLAGS) $(page_heap_test_OBJECTS) $(page_heap_test_LDADD) $(LIBS)\npagemap_unittest$(EXEEXT): $(pagemap_unittest_OBJECTS) $(pagemap_unittest_DEPENDENCIES) \n\t@rm -f pagemap_unittest$(EXEEXT)\n\t$(CXXLINK) $(pagemap_unittest_LDFLAGS) $(pagemap_unittest_OBJECTS) $(pagemap_unittest_LDADD) $(LIBS)\nprofile_handler_unittest$(EXEEXT): $(profile_handler_unittest_OBJECTS) $(profile_handler_unittest_DEPENDENCIES) \n\t@rm -f profile_handler_unittest$(EXEEXT)\n\t$(CXXLINK) $(profile_handler_unittest_LDFLAGS) $(profile_handler_unittest_OBJECTS) $(profile_handler_unittest_LDADD) $(LIBS)\nprofiledata_unittest$(EXEEXT): $(profiledata_unittest_OBJECTS) $(profiledata_unittest_DEPENDENCIES) \n\t@rm -f profiledata_unittest$(EXEEXT)\n\t$(CXXLINK) $(profiledata_unittest_LDFLAGS) $(profiledata_unittest_OBJECTS) $(profiledata_unittest_LDADD) $(LIBS)\nprofiler1_unittest$(EXEEXT): $(profiler1_unittest_OBJECTS) $(profiler1_unittest_DEPENDENCIES) \n\t@rm -f profiler1_unittest$(EXEEXT)\n\t$(CXXLINK) $(profiler1_unittest_LDFLAGS) $(profiler1_unittest_OBJECTS) $(profiler1_unittest_LDADD) $(LIBS)\nprofiler2_unittest$(EXEEXT): $(profiler2_unittest_OBJECTS) $(profiler2_unittest_DEPENDENCIES) \n\t@rm -f profiler2_unittest$(EXEEXT)\n\t$(CXXLINK) $(profiler2_unittest_LDFLAGS) $(profiler2_unittest_OBJECTS) $(profiler2_unittest_LDADD) $(LIBS)\nprofiler3_unittest$(EXEEXT): $(profiler3_unittest_OBJECTS) $(profiler3_unittest_DEPENDENCIES) \n\t@rm -f profiler3_unittest$(EXEEXT)\n\t$(CXXLINK) $(profiler3_unittest_LDFLAGS) $(profiler3_unittest_OBJECTS) $(profiler3_unittest_LDADD) $(LIBS)\nprofiler4_unittest$(EXEEXT): $(profiler4_unittest_OBJECTS) $(profiler4_unittest_DEPENDENCIES) \n\t@rm -f profiler4_unittest$(EXEEXT)\n\t$(CXXLINK) $(profiler4_unittest_LDFLAGS) $(profiler4_unittest_OBJECTS) $(profiler4_unittest_LDADD) $(LIBS)\n@WITH_CPU_PROFILER_FALSE@profiler_unittest.sh$(EXEEXT): $(profiler_unittest_sh_OBJECTS) $(profiler_unittest_sh_DEPENDENCIES) \n@WITH_CPU_PROFILER_FALSE@\t@rm -f profiler_unittest.sh$(EXEEXT)\n@WITH_CPU_PROFILER_FALSE@\t$(LINK) $(profiler_unittest_sh_LDFLAGS) $(profiler_unittest_sh_OBJECTS) $(profiler_unittest_sh_LDADD) $(LIBS)\nraw_printer_test$(EXEEXT): $(raw_printer_test_OBJECTS) $(raw_printer_test_DEPENDENCIES) \n\t@rm -f raw_printer_test$(EXEEXT)\n\t$(CXXLINK) $(raw_printer_test_LDFLAGS) $(raw_printer_test_OBJECTS) $(raw_printer_test_LDADD) $(LIBS)\nrealloc_debug_unittest$(EXEEXT): $(realloc_debug_unittest_OBJECTS) $(realloc_debug_unittest_DEPENDENCIES) \n\t@rm -f realloc_debug_unittest$(EXEEXT)\n\t$(CXXLINK) $(realloc_debug_unittest_LDFLAGS) $(realloc_debug_unittest_OBJECTS) $(realloc_debug_unittest_LDADD) $(LIBS)\nrealloc_unittest$(EXEEXT): $(realloc_unittest_OBJECTS) $(realloc_unittest_DEPENDENCIES) \n\t@rm -f realloc_unittest$(EXEEXT)\n\t$(CXXLINK) $(realloc_unittest_LDFLAGS) $(realloc_unittest_OBJECTS) $(realloc_unittest_LDADD) $(LIBS)\nsampler_debug_test$(EXEEXT): $(sampler_debug_test_OBJECTS) $(sampler_debug_test_DEPENDENCIES) \n\t@rm -f sampler_debug_test$(EXEEXT)\n\t$(CXXLINK) $(sampler_debug_test_LDFLAGS) $(sampler_debug_test_OBJECTS) $(sampler_debug_test_LDADD) $(LIBS)\nsampler_test$(EXEEXT): $(sampler_test_OBJECTS) $(sampler_test_DEPENDENCIES) \n\t@rm -f sampler_test$(EXEEXT)\n\t$(CXXLINK) $(sampler_test_LDFLAGS) $(sampler_test_OBJECTS) $(sampler_test_LDADD) $(LIBS)\nsampling_debug_test$(EXEEXT): $(sampling_debug_test_OBJECTS) $(sampling_debug_test_DEPENDENCIES) \n\t@rm -f sampling_debug_test$(EXEEXT)\n\t$(CXXLINK) $(sampling_debug_test_LDFLAGS) $(sampling_debug_test_OBJECTS) $(sampling_debug_test_LDADD) $(LIBS)\n@WITH_DEBUGALLOC_FALSE@sampling_debug_test.sh$(EXEEXT): $(sampling_debug_test_sh_OBJECTS) $(sampling_debug_test_sh_DEPENDENCIES) \n@WITH_DEBUGALLOC_FALSE@\t@rm -f sampling_debug_test.sh$(EXEEXT)\n@WITH_DEBUGALLOC_FALSE@\t$(LINK) $(sampling_debug_test_sh_LDFLAGS) $(sampling_debug_test_sh_OBJECTS) $(sampling_debug_test_sh_LDADD) $(LIBS)\n@WITH_HEAP_PROFILER_OR_CHECKER_FALSE@sampling_debug_test.sh$(EXEEXT): $(sampling_debug_test_sh_OBJECTS) $(sampling_debug_test_sh_DEPENDENCIES) \n@WITH_HEAP_PROFILER_OR_CHECKER_FALSE@\t@rm -f sampling_debug_test.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_OR_CHECKER_FALSE@\t$(LINK) $(sampling_debug_test_sh_LDFLAGS) $(sampling_debug_test_sh_OBJECTS) $(sampling_debug_test_sh_LDADD) $(LIBS)\nsampling_test$(EXEEXT): $(sampling_test_OBJECTS) $(sampling_test_DEPENDENCIES) \n\t@rm -f sampling_test$(EXEEXT)\n\t$(CXXLINK) $(sampling_test_LDFLAGS) $(sampling_test_OBJECTS) $(sampling_test_LDADD) $(LIBS)\n@WITH_HEAP_PROFILER_OR_CHECKER_FALSE@sampling_test.sh$(EXEEXT): $(sampling_test_sh_OBJECTS) $(sampling_test_sh_DEPENDENCIES) \n@WITH_HEAP_PROFILER_OR_CHECKER_FALSE@\t@rm -f sampling_test.sh$(EXEEXT)\n@WITH_HEAP_PROFILER_OR_CHECKER_FALSE@\t$(LINK) $(sampling_test_sh_LDFLAGS) $(sampling_test_sh_OBJECTS) $(sampling_test_sh_LDADD) $(LIBS)\nstack_trace_table_test$(EXEEXT): $(stack_trace_table_test_OBJECTS) $(stack_trace_table_test_DEPENDENCIES) \n\t@rm -f stack_trace_table_test$(EXEEXT)\n\t$(CXXLINK) $(stack_trace_table_test_LDFLAGS) $(stack_trace_table_test_OBJECTS) $(stack_trace_table_test_LDADD) $(LIBS)\nstacktrace_unittest$(EXEEXT): $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_DEPENDENCIES) \n\t@rm -f stacktrace_unittest$(EXEEXT)\n\t$(CXXLINK) $(stacktrace_unittest_LDFLAGS) $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_LDADD) $(LIBS)\nsystem_alloc_unittest$(EXEEXT): $(system_alloc_unittest_OBJECTS) $(system_alloc_unittest_DEPENDENCIES) \n\t@rm -f system_alloc_unittest$(EXEEXT)\n\t$(CXXLINK) $(system_alloc_unittest_LDFLAGS) $(system_alloc_unittest_OBJECTS) $(system_alloc_unittest_LDADD) $(LIBS)\ntcmalloc_and_profiler_unittest$(EXEEXT): $(tcmalloc_and_profiler_unittest_OBJECTS) $(tcmalloc_and_profiler_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_and_profiler_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_and_profiler_unittest_LDFLAGS) $(tcmalloc_and_profiler_unittest_OBJECTS) $(tcmalloc_and_profiler_unittest_LDADD) $(LIBS)\ntcmalloc_both_unittest$(EXEEXT): $(tcmalloc_both_unittest_OBJECTS) $(tcmalloc_both_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_both_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_both_unittest_LDFLAGS) $(tcmalloc_both_unittest_OBJECTS) $(tcmalloc_both_unittest_LDADD) $(LIBS)\ntcmalloc_debug_unittest$(EXEEXT): $(tcmalloc_debug_unittest_OBJECTS) $(tcmalloc_debug_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_debug_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_debug_unittest_LDFLAGS) $(tcmalloc_debug_unittest_OBJECTS) $(tcmalloc_debug_unittest_LDADD) $(LIBS)\ntcmalloc_large_unittest$(EXEEXT): $(tcmalloc_large_unittest_OBJECTS) $(tcmalloc_large_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_large_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_large_unittest_LDFLAGS) $(tcmalloc_large_unittest_OBJECTS) $(tcmalloc_large_unittest_LDADD) $(LIBS)\ntcmalloc_minimal_debug_unittest$(EXEEXT): $(tcmalloc_minimal_debug_unittest_OBJECTS) $(tcmalloc_minimal_debug_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_minimal_debug_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_minimal_debug_unittest_LDFLAGS) $(tcmalloc_minimal_debug_unittest_OBJECTS) $(tcmalloc_minimal_debug_unittest_LDADD) $(LIBS)\ntcmalloc_minimal_large_unittest$(EXEEXT): $(tcmalloc_minimal_large_unittest_OBJECTS) $(tcmalloc_minimal_large_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_minimal_large_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_minimal_large_unittest_LDFLAGS) $(tcmalloc_minimal_large_unittest_OBJECTS) $(tcmalloc_minimal_large_unittest_LDADD) $(LIBS)\ntcmalloc_minimal_unittest$(EXEEXT): $(tcmalloc_minimal_unittest_OBJECTS) $(tcmalloc_minimal_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_minimal_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_minimal_unittest_LDFLAGS) $(tcmalloc_minimal_unittest_OBJECTS) $(tcmalloc_minimal_unittest_LDADD) $(LIBS)\ntcmalloc_unittest$(EXEEXT): $(tcmalloc_unittest_OBJECTS) $(tcmalloc_unittest_DEPENDENCIES) \n\t@rm -f tcmalloc_unittest$(EXEEXT)\n\t$(CXXLINK) $(tcmalloc_unittest_LDFLAGS) $(tcmalloc_unittest_OBJECTS) $(tcmalloc_unittest_LDADD) $(LIBS)\nthread_dealloc_unittest$(EXEEXT): $(thread_dealloc_unittest_OBJECTS) $(thread_dealloc_unittest_DEPENDENCIES) \n\t@rm -f thread_dealloc_unittest$(EXEEXT)\n\t$(CXXLINK) $(thread_dealloc_unittest_LDFLAGS) $(thread_dealloc_unittest_OBJECTS) $(thread_dealloc_unittest_LDADD) $(LIBS)\ninstall-binSCRIPTS: $(bin_SCRIPTS)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(bindir)\" || $(mkdir_p) \"$(DESTDIR)$(bindir)\"\n\t@list='$(bin_SCRIPTS)'; for p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  if test -f $$d$$p; then \\\n\t    f=`echo \"$$p\" | sed 's|^.*/||;$(transform)'`; \\\n\t    echo \" $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'\"; \\\n\t    $(binSCRIPT_INSTALL) \"$$d$$p\" \"$(DESTDIR)$(bindir)/$$f\"; \\\n\t  else :; fi; \\\n\tdone\n\nuninstall-binSCRIPTS:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(bin_SCRIPTS)'; for p in $$list; do \\\n\t  f=`echo \"$$p\" | sed 's|^.*/||;$(transform)'`; \\\n\t  echo \" rm -f '$(DESTDIR)$(bindir)/$$f'\"; \\\n\t  rm -f \"$(DESTDIR)$(bindir)/$$f\"; \\\n\tdone\n\nmostlyclean-compile:\n\t-rm -f *.$(OBJEXT)\n\ndistclean-compile:\n\t-rm -f *.tab.c\n\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addressmap_unittest-addressmap_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addressmap_unittest-port.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops-internals-x86.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debugallocation_test-debugallocation_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamic_annotations.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frag_unittest-frag_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getpc_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia32_modrm_map.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ia32_opcode_map.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker-bcad.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-linuxthreads.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-profile-handler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-profiledata.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-profiler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_and_profiler_la-tcmalloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_debug_la-debugallocation.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_debug_la-heap-checker-bcad.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_debug_la-heap-checker.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_debug_la-linuxthreads.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-central_freelist.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-common.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-heap-profile-table.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-heap-profiler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-internal_logging.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-low_level_alloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-malloc_extension.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-malloc_hook.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-maybe_threads.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-memfs_malloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-memory_region_map.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-page_heap.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-raw_printer.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-sampler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-span.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-stack_trace_table.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-static_vars.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-symbolize.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-system-alloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_internal_la-thread_cache.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-heap-checker.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-linuxthreads.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-tcmalloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_debug_la-debugallocation.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-central_freelist.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-common.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-internal_logging.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_extension.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_hook.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-maybe_threads.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-memfs_malloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-page_heap.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-sampler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-span.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-stack_trace_table.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-static_vars.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-symbolize.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-system-alloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_internal_la-thread_cache.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_extension_test-malloc_extension_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markidle_unittest-markidle_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markidle_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memalign_debug_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memalign_unittest-memalign_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memalign_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mini_disassembler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packed_cache_test-packed-cache_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/page_heap_test-page_heap_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pagemap_unittest-pagemap_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patch_functions.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/port.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preamble_patcher.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/preamble_patcher_with_stub.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile-handler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiledata.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiledata_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler1_unittest-profiler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler1_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler2_unittest-profiler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler2_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler3_unittest-profiler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler3_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler4_unittest-profiler_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler4_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_printer_test-raw_printer_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realloc_unittest-realloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sampler_debug_test-sampler_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sampler_test-sampler_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sampling_debug_test-sampling_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sampling_test-sampling_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spinlock.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spinlock_internal.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysinfo.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_both_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_debug_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_dealloc_unittest-testutil.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Po@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_lister.Plo@am__quote@\n@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vdso_support.Plo@am__quote@\n\n.c.o:\n@am__fastdepCC_TRUE@\tif $(COMPILE) -MT $@ -MD -MP -MF \"$(DEPDIR)/$*.Tpo\" -c -o $@ $<; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/$*.Tpo\" \"$(DEPDIR)/$*.Po\"; else rm -f \"$(DEPDIR)/$*.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='$<' object='$@' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(COMPILE) -c $<\n\n.c.obj:\n@am__fastdepCC_TRUE@\tif $(COMPILE) -MT $@ -MD -MP -MF \"$(DEPDIR)/$*.Tpo\" -c -o $@ `$(CYGPATH_W) '$<'`; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/$*.Tpo\" \"$(DEPDIR)/$*.Po\"; else rm -f \"$(DEPDIR)/$*.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='$<' object='$@' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(COMPILE) -c `$(CYGPATH_W) '$<'`\n\n.c.lo:\n@am__fastdepCC_TRUE@\tif $(LTCOMPILE) -MT $@ -MD -MP -MF \"$(DEPDIR)/$*.Tpo\" -c -o $@ $<; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/$*.Tpo\" \"$(DEPDIR)/$*.Plo\"; else rm -f \"$(DEPDIR)/$*.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='$<' object='$@' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(LTCOMPILE) -c -o $@ $<\n\ndynamic_annotations.lo: src/base/dynamic_annotations.c\n@am__fastdepCC_TRUE@\tif $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dynamic_annotations.lo -MD -MP -MF \"$(DEPDIR)/dynamic_annotations.Tpo\" -c -o dynamic_annotations.lo `test -f 'src/base/dynamic_annotations.c' || echo '$(srcdir)/'`src/base/dynamic_annotations.c; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/dynamic_annotations.Tpo\" \"$(DEPDIR)/dynamic_annotations.Plo\"; else rm -f \"$(DEPDIR)/dynamic_annotations.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='src/base/dynamic_annotations.c' object='dynamic_annotations.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dynamic_annotations.lo `test -f 'src/base/dynamic_annotations.c' || echo '$(srcdir)/'`src/base/dynamic_annotations.c\n\nthread_lister.lo: src/base/thread_lister.c\n@am__fastdepCC_TRUE@\tif $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT thread_lister.lo -MD -MP -MF \"$(DEPDIR)/thread_lister.Tpo\" -c -o thread_lister.lo `test -f 'src/base/thread_lister.c' || echo '$(srcdir)/'`src/base/thread_lister.c; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/thread_lister.Tpo\" \"$(DEPDIR)/thread_lister.Plo\"; else rm -f \"$(DEPDIR)/thread_lister.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='src/base/thread_lister.c' object='thread_lister.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o thread_lister.lo `test -f 'src/base/thread_lister.c' || echo '$(srcdir)/'`src/base/thread_lister.c\n\nmalloc_extension_c_test-malloc_extension_c_test.o: src/tests/malloc_extension_c_test.c\n@am__fastdepCC_TRUE@\tif $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_c_test_CFLAGS) $(CFLAGS) -MT malloc_extension_c_test-malloc_extension_c_test.o -MD -MP -MF \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Tpo\" -c -o malloc_extension_c_test-malloc_extension_c_test.o `test -f 'src/tests/malloc_extension_c_test.c' || echo '$(srcdir)/'`src/tests/malloc_extension_c_test.c; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Tpo\" \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Po\"; else rm -f \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='src/tests/malloc_extension_c_test.c' object='malloc_extension_c_test-malloc_extension_c_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_c_test_CFLAGS) $(CFLAGS) -c -o malloc_extension_c_test-malloc_extension_c_test.o `test -f 'src/tests/malloc_extension_c_test.c' || echo '$(srcdir)/'`src/tests/malloc_extension_c_test.c\n\nmalloc_extension_c_test-malloc_extension_c_test.obj: src/tests/malloc_extension_c_test.c\n@am__fastdepCC_TRUE@\tif $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_c_test_CFLAGS) $(CFLAGS) -MT malloc_extension_c_test-malloc_extension_c_test.obj -MD -MP -MF \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Tpo\" -c -o malloc_extension_c_test-malloc_extension_c_test.obj `if test -f 'src/tests/malloc_extension_c_test.c'; then $(CYGPATH_W) 'src/tests/malloc_extension_c_test.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/malloc_extension_c_test.c'; fi`; \\\n@am__fastdepCC_TRUE@\tthen mv -f \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Tpo\" \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Po\"; else rm -f \"$(DEPDIR)/malloc_extension_c_test-malloc_extension_c_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tsource='src/tests/malloc_extension_c_test.c' object='malloc_extension_c_test-malloc_extension_c_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCC_FALSE@\tDEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCC_FALSE@\t$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_c_test_CFLAGS) $(CFLAGS) -c -o malloc_extension_c_test-malloc_extension_c_test.obj `if test -f 'src/tests/malloc_extension_c_test.c'; then $(CYGPATH_W) 'src/tests/malloc_extension_c_test.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/malloc_extension_c_test.c'; fi`\n\n.cc.o:\n@am__fastdepCXX_TRUE@\tif $(CXXCOMPILE) -MT $@ -MD -MP -MF \"$(DEPDIR)/$*.Tpo\" -c -o $@ $<; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/$*.Tpo\" \"$(DEPDIR)/$*.Po\"; else rm -f \"$(DEPDIR)/$*.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='$<' object='$@' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXXCOMPILE) -c -o $@ $<\n\n.cc.obj:\n@am__fastdepCXX_TRUE@\tif $(CXXCOMPILE) -MT $@ -MD -MP -MF \"$(DEPDIR)/$*.Tpo\" -c -o $@ `$(CYGPATH_W) '$<'`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/$*.Tpo\" \"$(DEPDIR)/$*.Po\"; else rm -f \"$(DEPDIR)/$*.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='$<' object='$@' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`\n\n.cc.lo:\n@am__fastdepCXX_TRUE@\tif $(LTCXXCOMPILE) -MT $@ -MD -MP -MF \"$(DEPDIR)/$*.Tpo\" -c -o $@ $<; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/$*.Tpo\" \"$(DEPDIR)/$*.Plo\"; else rm -f \"$(DEPDIR)/$*.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='$<' object='$@' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LTCXXCOMPILE) -c -o $@ $<\n\nlogging.lo: src/base/logging.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT logging.lo -MD -MP -MF \"$(DEPDIR)/logging.Tpo\" -c -o logging.lo `test -f 'src/base/logging.cc' || echo '$(srcdir)/'`src/base/logging.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/logging.Tpo\" \"$(DEPDIR)/logging.Plo\"; else rm -f \"$(DEPDIR)/logging.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/logging.cc' object='logging.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logging.lo `test -f 'src/base/logging.cc' || echo '$(srcdir)/'`src/base/logging.cc\n\nprofiler.lo: src/profiler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profiler.lo -MD -MP -MF \"$(DEPDIR)/profiler.Tpo\" -c -o profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler.Tpo\" \"$(DEPDIR)/profiler.Plo\"; else rm -f \"$(DEPDIR)/profiler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/profiler.cc' object='profiler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc\n\nprofile-handler.lo: src/profile-handler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profile-handler.lo -MD -MP -MF \"$(DEPDIR)/profile-handler.Tpo\" -c -o profile-handler.lo `test -f 'src/profile-handler.cc' || echo '$(srcdir)/'`src/profile-handler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profile-handler.Tpo\" \"$(DEPDIR)/profile-handler.Plo\"; else rm -f \"$(DEPDIR)/profile-handler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/profile-handler.cc' object='profile-handler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profile-handler.lo `test -f 'src/profile-handler.cc' || echo '$(srcdir)/'`src/profile-handler.cc\n\nprofiledata.lo: src/profiledata.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profiledata.lo -MD -MP -MF \"$(DEPDIR)/profiledata.Tpo\" -c -o profiledata.lo `test -f 'src/profiledata.cc' || echo '$(srcdir)/'`src/profiledata.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiledata.Tpo\" \"$(DEPDIR)/profiledata.Plo\"; else rm -f \"$(DEPDIR)/profiledata.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/profiledata.cc' object='profiledata.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profiledata.lo `test -f 'src/profiledata.cc' || echo '$(srcdir)/'`src/profiledata.cc\n\nspinlock.lo: src/base/spinlock.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT spinlock.lo -MD -MP -MF \"$(DEPDIR)/spinlock.Tpo\" -c -o spinlock.lo `test -f 'src/base/spinlock.cc' || echo '$(srcdir)/'`src/base/spinlock.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/spinlock.Tpo\" \"$(DEPDIR)/spinlock.Plo\"; else rm -f \"$(DEPDIR)/spinlock.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/spinlock.cc' object='spinlock.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o spinlock.lo `test -f 'src/base/spinlock.cc' || echo '$(srcdir)/'`src/base/spinlock.cc\n\nspinlock_internal.lo: src/base/spinlock_internal.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT spinlock_internal.lo -MD -MP -MF \"$(DEPDIR)/spinlock_internal.Tpo\" -c -o spinlock_internal.lo `test -f 'src/base/spinlock_internal.cc' || echo '$(srcdir)/'`src/base/spinlock_internal.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/spinlock_internal.Tpo\" \"$(DEPDIR)/spinlock_internal.Plo\"; else rm -f \"$(DEPDIR)/spinlock_internal.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/spinlock_internal.cc' object='spinlock_internal.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o spinlock_internal.lo `test -f 'src/base/spinlock_internal.cc' || echo '$(srcdir)/'`src/base/spinlock_internal.cc\n\natomicops-internals-x86.lo: src/base/atomicops-internals-x86.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops-internals-x86.lo -MD -MP -MF \"$(DEPDIR)/atomicops-internals-x86.Tpo\" -c -o atomicops-internals-x86.lo `test -f 'src/base/atomicops-internals-x86.cc' || echo '$(srcdir)/'`src/base/atomicops-internals-x86.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/atomicops-internals-x86.Tpo\" \"$(DEPDIR)/atomicops-internals-x86.Plo\"; else rm -f \"$(DEPDIR)/atomicops-internals-x86.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/atomicops-internals-x86.cc' object='atomicops-internals-x86.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops-internals-x86.lo `test -f 'src/base/atomicops-internals-x86.cc' || echo '$(srcdir)/'`src/base/atomicops-internals-x86.cc\n\nstacktrace.lo: src/stacktrace.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stacktrace.lo -MD -MP -MF \"$(DEPDIR)/stacktrace.Tpo\" -c -o stacktrace.lo `test -f 'src/stacktrace.cc' || echo '$(srcdir)/'`src/stacktrace.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/stacktrace.Tpo\" \"$(DEPDIR)/stacktrace.Plo\"; else rm -f \"$(DEPDIR)/stacktrace.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/stacktrace.cc' object='stacktrace.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stacktrace.lo `test -f 'src/stacktrace.cc' || echo '$(srcdir)/'`src/stacktrace.cc\n\nvdso_support.lo: src/base/vdso_support.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vdso_support.lo -MD -MP -MF \"$(DEPDIR)/vdso_support.Tpo\" -c -o vdso_support.lo `test -f 'src/base/vdso_support.cc' || echo '$(srcdir)/'`src/base/vdso_support.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/vdso_support.Tpo\" \"$(DEPDIR)/vdso_support.Plo\"; else rm -f \"$(DEPDIR)/vdso_support.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/vdso_support.cc' object='vdso_support.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vdso_support.lo `test -f 'src/base/vdso_support.cc' || echo '$(srcdir)/'`src/base/vdso_support.cc\n\nsysinfo.lo: src/base/sysinfo.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sysinfo.lo -MD -MP -MF \"$(DEPDIR)/sysinfo.Tpo\" -c -o sysinfo.lo `test -f 'src/base/sysinfo.cc' || echo '$(srcdir)/'`src/base/sysinfo.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sysinfo.Tpo\" \"$(DEPDIR)/sysinfo.Plo\"; else rm -f \"$(DEPDIR)/sysinfo.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/sysinfo.cc' object='sysinfo.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sysinfo.lo `test -f 'src/base/sysinfo.cc' || echo '$(srcdir)/'`src/base/sysinfo.cc\n\nlibtcmalloc_la-tcmalloc.lo: src/tcmalloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-tcmalloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_la-tcmalloc.Tpo\" -c -o libtcmalloc_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_la-tcmalloc.Tpo\" \"$(DEPDIR)/libtcmalloc_la-tcmalloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_la-tcmalloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tcmalloc.cc' object='libtcmalloc_la-tcmalloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc\n\nlibtcmalloc_la-linuxthreads.lo: src/base/linuxthreads.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-linuxthreads.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_la-linuxthreads.Tpo\" -c -o libtcmalloc_la-linuxthreads.lo `test -f 'src/base/linuxthreads.cc' || echo '$(srcdir)/'`src/base/linuxthreads.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_la-linuxthreads.Tpo\" \"$(DEPDIR)/libtcmalloc_la-linuxthreads.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_la-linuxthreads.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/linuxthreads.cc' object='libtcmalloc_la-linuxthreads.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-linuxthreads.lo `test -f 'src/base/linuxthreads.cc' || echo '$(srcdir)/'`src/base/linuxthreads.cc\n\nlibtcmalloc_la-heap-checker.lo: src/heap-checker.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-heap-checker.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_la-heap-checker.Tpo\" -c -o libtcmalloc_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_la-heap-checker.Tpo\" \"$(DEPDIR)/libtcmalloc_la-heap-checker.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_la-heap-checker.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-checker.cc' object='libtcmalloc_la-heap-checker.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc\n\nlibtcmalloc_la-heap-checker-bcad.lo: src/heap-checker-bcad.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-heap-checker-bcad.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Tpo\" -c -o libtcmalloc_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Tpo\" \"$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-checker-bcad.cc' object='libtcmalloc_la-heap-checker-bcad.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc\n\nlibtcmalloc_and_profiler_la-tcmalloc.lo: src/tcmalloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-tcmalloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-tcmalloc.Tpo\" -c -o libtcmalloc_and_profiler_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-tcmalloc.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-tcmalloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-tcmalloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tcmalloc.cc' object='libtcmalloc_and_profiler_la-tcmalloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc\n\nlibtcmalloc_and_profiler_la-linuxthreads.lo: src/base/linuxthreads.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-linuxthreads.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-linuxthreads.Tpo\" -c -o libtcmalloc_and_profiler_la-linuxthreads.lo `test -f 'src/base/linuxthreads.cc' || echo '$(srcdir)/'`src/base/linuxthreads.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-linuxthreads.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-linuxthreads.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-linuxthreads.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/linuxthreads.cc' object='libtcmalloc_and_profiler_la-linuxthreads.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-linuxthreads.lo `test -f 'src/base/linuxthreads.cc' || echo '$(srcdir)/'`src/base/linuxthreads.cc\n\nlibtcmalloc_and_profiler_la-heap-checker.lo: src/heap-checker.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-heap-checker.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker.Tpo\" -c -o libtcmalloc_and_profiler_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-checker.cc' object='libtcmalloc_and_profiler_la-heap-checker.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc\n\nlibtcmalloc_and_profiler_la-heap-checker-bcad.lo: src/heap-checker-bcad.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-heap-checker-bcad.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker-bcad.Tpo\" -c -o libtcmalloc_and_profiler_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker-bcad.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker-bcad.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-heap-checker-bcad.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-checker-bcad.cc' object='libtcmalloc_and_profiler_la-heap-checker-bcad.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc\n\nlibtcmalloc_and_profiler_la-profiler.lo: src/profiler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-profiler.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiler.Tpo\" -c -o libtcmalloc_and_profiler_la-profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiler.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiler.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/profiler.cc' object='libtcmalloc_and_profiler_la-profiler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc\n\nlibtcmalloc_and_profiler_la-profile-handler.lo: src/profile-handler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-profile-handler.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-profile-handler.Tpo\" -c -o libtcmalloc_and_profiler_la-profile-handler.lo `test -f 'src/profile-handler.cc' || echo '$(srcdir)/'`src/profile-handler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-profile-handler.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-profile-handler.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-profile-handler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/profile-handler.cc' object='libtcmalloc_and_profiler_la-profile-handler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-profile-handler.lo `test -f 'src/profile-handler.cc' || echo '$(srcdir)/'`src/profile-handler.cc\n\nlibtcmalloc_and_profiler_la-profiledata.lo: src/profiledata.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_and_profiler_la-profiledata.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiledata.Tpo\" -c -o libtcmalloc_and_profiler_la-profiledata.lo `test -f 'src/profiledata.cc' || echo '$(srcdir)/'`src/profiledata.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiledata.Tpo\" \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiledata.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_and_profiler_la-profiledata.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/profiledata.cc' object='libtcmalloc_and_profiler_la-profiledata.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_and_profiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_and_profiler_la-profiledata.lo `test -f 'src/profiledata.cc' || echo '$(srcdir)/'`src/profiledata.cc\n\nlibtcmalloc_debug_la-debugallocation.lo: src/debugallocation.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_debug_la-debugallocation.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_debug_la-debugallocation.Tpo\" -c -o libtcmalloc_debug_la-debugallocation.lo `test -f 'src/debugallocation.cc' || echo '$(srcdir)/'`src/debugallocation.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_debug_la-debugallocation.Tpo\" \"$(DEPDIR)/libtcmalloc_debug_la-debugallocation.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_debug_la-debugallocation.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/debugallocation.cc' object='libtcmalloc_debug_la-debugallocation.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_debug_la-debugallocation.lo `test -f 'src/debugallocation.cc' || echo '$(srcdir)/'`src/debugallocation.cc\n\nlibtcmalloc_debug_la-linuxthreads.lo: src/base/linuxthreads.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_debug_la-linuxthreads.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_debug_la-linuxthreads.Tpo\" -c -o libtcmalloc_debug_la-linuxthreads.lo `test -f 'src/base/linuxthreads.cc' || echo '$(srcdir)/'`src/base/linuxthreads.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_debug_la-linuxthreads.Tpo\" \"$(DEPDIR)/libtcmalloc_debug_la-linuxthreads.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_debug_la-linuxthreads.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/linuxthreads.cc' object='libtcmalloc_debug_la-linuxthreads.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_debug_la-linuxthreads.lo `test -f 'src/base/linuxthreads.cc' || echo '$(srcdir)/'`src/base/linuxthreads.cc\n\nlibtcmalloc_debug_la-heap-checker.lo: src/heap-checker.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_debug_la-heap-checker.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker.Tpo\" -c -o libtcmalloc_debug_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker.Tpo\" \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-checker.cc' object='libtcmalloc_debug_la-heap-checker.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_debug_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc\n\nlibtcmalloc_debug_la-heap-checker-bcad.lo: src/heap-checker-bcad.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_debug_la-heap-checker-bcad.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker-bcad.Tpo\" -c -o libtcmalloc_debug_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker-bcad.Tpo\" \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker-bcad.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_debug_la-heap-checker-bcad.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-checker-bcad.cc' object='libtcmalloc_debug_la-heap-checker-bcad.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_debug_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_debug_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc\n\nlibtcmalloc_internal_la-common.lo: src/common.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-common.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-common.Tpo\" -c -o libtcmalloc_internal_la-common.lo `test -f 'src/common.cc' || echo '$(srcdir)/'`src/common.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-common.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-common.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-common.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/common.cc' object='libtcmalloc_internal_la-common.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-common.lo `test -f 'src/common.cc' || echo '$(srcdir)/'`src/common.cc\n\nlibtcmalloc_internal_la-internal_logging.lo: src/internal_logging.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-internal_logging.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-internal_logging.Tpo\" -c -o libtcmalloc_internal_la-internal_logging.lo `test -f 'src/internal_logging.cc' || echo '$(srcdir)/'`src/internal_logging.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-internal_logging.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-internal_logging.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-internal_logging.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/internal_logging.cc' object='libtcmalloc_internal_la-internal_logging.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-internal_logging.lo `test -f 'src/internal_logging.cc' || echo '$(srcdir)/'`src/internal_logging.cc\n\nlibtcmalloc_internal_la-system-alloc.lo: src/system-alloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-system-alloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-system-alloc.Tpo\" -c -o libtcmalloc_internal_la-system-alloc.lo `test -f 'src/system-alloc.cc' || echo '$(srcdir)/'`src/system-alloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-system-alloc.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-system-alloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-system-alloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/system-alloc.cc' object='libtcmalloc_internal_la-system-alloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-system-alloc.lo `test -f 'src/system-alloc.cc' || echo '$(srcdir)/'`src/system-alloc.cc\n\nlibtcmalloc_internal_la-memfs_malloc.lo: src/memfs_malloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-memfs_malloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-memfs_malloc.Tpo\" -c -o libtcmalloc_internal_la-memfs_malloc.lo `test -f 'src/memfs_malloc.cc' || echo '$(srcdir)/'`src/memfs_malloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-memfs_malloc.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-memfs_malloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-memfs_malloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/memfs_malloc.cc' object='libtcmalloc_internal_la-memfs_malloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-memfs_malloc.lo `test -f 'src/memfs_malloc.cc' || echo '$(srcdir)/'`src/memfs_malloc.cc\n\nlibtcmalloc_internal_la-central_freelist.lo: src/central_freelist.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-central_freelist.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-central_freelist.Tpo\" -c -o libtcmalloc_internal_la-central_freelist.lo `test -f 'src/central_freelist.cc' || echo '$(srcdir)/'`src/central_freelist.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-central_freelist.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-central_freelist.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-central_freelist.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/central_freelist.cc' object='libtcmalloc_internal_la-central_freelist.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-central_freelist.lo `test -f 'src/central_freelist.cc' || echo '$(srcdir)/'`src/central_freelist.cc\n\nlibtcmalloc_internal_la-page_heap.lo: src/page_heap.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-page_heap.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-page_heap.Tpo\" -c -o libtcmalloc_internal_la-page_heap.lo `test -f 'src/page_heap.cc' || echo '$(srcdir)/'`src/page_heap.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-page_heap.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-page_heap.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-page_heap.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/page_heap.cc' object='libtcmalloc_internal_la-page_heap.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-page_heap.lo `test -f 'src/page_heap.cc' || echo '$(srcdir)/'`src/page_heap.cc\n\nlibtcmalloc_internal_la-sampler.lo: src/sampler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-sampler.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-sampler.Tpo\" -c -o libtcmalloc_internal_la-sampler.lo `test -f 'src/sampler.cc' || echo '$(srcdir)/'`src/sampler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-sampler.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-sampler.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-sampler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/sampler.cc' object='libtcmalloc_internal_la-sampler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-sampler.lo `test -f 'src/sampler.cc' || echo '$(srcdir)/'`src/sampler.cc\n\nlibtcmalloc_internal_la-span.lo: src/span.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-span.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-span.Tpo\" -c -o libtcmalloc_internal_la-span.lo `test -f 'src/span.cc' || echo '$(srcdir)/'`src/span.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-span.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-span.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-span.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/span.cc' object='libtcmalloc_internal_la-span.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-span.lo `test -f 'src/span.cc' || echo '$(srcdir)/'`src/span.cc\n\nlibtcmalloc_internal_la-stack_trace_table.lo: src/stack_trace_table.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-stack_trace_table.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-stack_trace_table.Tpo\" -c -o libtcmalloc_internal_la-stack_trace_table.lo `test -f 'src/stack_trace_table.cc' || echo '$(srcdir)/'`src/stack_trace_table.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-stack_trace_table.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-stack_trace_table.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-stack_trace_table.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/stack_trace_table.cc' object='libtcmalloc_internal_la-stack_trace_table.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-stack_trace_table.lo `test -f 'src/stack_trace_table.cc' || echo '$(srcdir)/'`src/stack_trace_table.cc\n\nlibtcmalloc_internal_la-static_vars.lo: src/static_vars.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-static_vars.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-static_vars.Tpo\" -c -o libtcmalloc_internal_la-static_vars.lo `test -f 'src/static_vars.cc' || echo '$(srcdir)/'`src/static_vars.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-static_vars.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-static_vars.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-static_vars.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/static_vars.cc' object='libtcmalloc_internal_la-static_vars.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-static_vars.lo `test -f 'src/static_vars.cc' || echo '$(srcdir)/'`src/static_vars.cc\n\nlibtcmalloc_internal_la-symbolize.lo: src/symbolize.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-symbolize.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-symbolize.Tpo\" -c -o libtcmalloc_internal_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-symbolize.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-symbolize.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-symbolize.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/symbolize.cc' object='libtcmalloc_internal_la-symbolize.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc\n\nlibtcmalloc_internal_la-thread_cache.lo: src/thread_cache.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-thread_cache.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-thread_cache.Tpo\" -c -o libtcmalloc_internal_la-thread_cache.lo `test -f 'src/thread_cache.cc' || echo '$(srcdir)/'`src/thread_cache.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-thread_cache.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-thread_cache.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-thread_cache.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/thread_cache.cc' object='libtcmalloc_internal_la-thread_cache.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-thread_cache.lo `test -f 'src/thread_cache.cc' || echo '$(srcdir)/'`src/thread_cache.cc\n\nlibtcmalloc_internal_la-malloc_hook.lo: src/malloc_hook.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-malloc_hook.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-malloc_hook.Tpo\" -c -o libtcmalloc_internal_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-malloc_hook.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-malloc_hook.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-malloc_hook.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/malloc_hook.cc' object='libtcmalloc_internal_la-malloc_hook.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc\n\nlibtcmalloc_internal_la-malloc_extension.lo: src/malloc_extension.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-malloc_extension.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-malloc_extension.Tpo\" -c -o libtcmalloc_internal_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-malloc_extension.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-malloc_extension.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-malloc_extension.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/malloc_extension.cc' object='libtcmalloc_internal_la-malloc_extension.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc\n\nlibtcmalloc_internal_la-maybe_threads.lo: src/maybe_threads.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-maybe_threads.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-maybe_threads.Tpo\" -c -o libtcmalloc_internal_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-maybe_threads.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-maybe_threads.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-maybe_threads.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/maybe_threads.cc' object='libtcmalloc_internal_la-maybe_threads.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc\n\nlibtcmalloc_internal_la-low_level_alloc.lo: src/base/low_level_alloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-low_level_alloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-low_level_alloc.Tpo\" -c -o libtcmalloc_internal_la-low_level_alloc.lo `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-low_level_alloc.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-low_level_alloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-low_level_alloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/low_level_alloc.cc' object='libtcmalloc_internal_la-low_level_alloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-low_level_alloc.lo `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc\n\nlibtcmalloc_internal_la-heap-profile-table.lo: src/heap-profile-table.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-heap-profile-table.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-heap-profile-table.Tpo\" -c -o libtcmalloc_internal_la-heap-profile-table.lo `test -f 'src/heap-profile-table.cc' || echo '$(srcdir)/'`src/heap-profile-table.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-heap-profile-table.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-heap-profile-table.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-heap-profile-table.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-profile-table.cc' object='libtcmalloc_internal_la-heap-profile-table.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-heap-profile-table.lo `test -f 'src/heap-profile-table.cc' || echo '$(srcdir)/'`src/heap-profile-table.cc\n\nlibtcmalloc_internal_la-heap-profiler.lo: src/heap-profiler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-heap-profiler.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-heap-profiler.Tpo\" -c -o libtcmalloc_internal_la-heap-profiler.lo `test -f 'src/heap-profiler.cc' || echo '$(srcdir)/'`src/heap-profiler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-heap-profiler.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-heap-profiler.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-heap-profiler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/heap-profiler.cc' object='libtcmalloc_internal_la-heap-profiler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-heap-profiler.lo `test -f 'src/heap-profiler.cc' || echo '$(srcdir)/'`src/heap-profiler.cc\n\nlibtcmalloc_internal_la-raw_printer.lo: src/raw_printer.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-raw_printer.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-raw_printer.Tpo\" -c -o libtcmalloc_internal_la-raw_printer.lo `test -f 'src/raw_printer.cc' || echo '$(srcdir)/'`src/raw_printer.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-raw_printer.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-raw_printer.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-raw_printer.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/raw_printer.cc' object='libtcmalloc_internal_la-raw_printer.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-raw_printer.lo `test -f 'src/raw_printer.cc' || echo '$(srcdir)/'`src/raw_printer.cc\n\nlibtcmalloc_internal_la-memory_region_map.lo: src/memory_region_map.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_internal_la-memory_region_map.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_internal_la-memory_region_map.Tpo\" -c -o libtcmalloc_internal_la-memory_region_map.lo `test -f 'src/memory_region_map.cc' || echo '$(srcdir)/'`src/memory_region_map.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_internal_la-memory_region_map.Tpo\" \"$(DEPDIR)/libtcmalloc_internal_la-memory_region_map.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_internal_la-memory_region_map.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/memory_region_map.cc' object='libtcmalloc_internal_la-memory_region_map.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_internal_la-memory_region_map.lo `test -f 'src/memory_region_map.cc' || echo '$(srcdir)/'`src/memory_region_map.cc\n\nlibtcmalloc_minimal_la-tcmalloc.lo: src/tcmalloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-tcmalloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Tpo\" -c -o libtcmalloc_minimal_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tcmalloc.cc' object='libtcmalloc_minimal_la-tcmalloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc\n\nlibtcmalloc_minimal_debug_la-debugallocation.lo: src/debugallocation.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_debug_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_debug_la-debugallocation.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_debug_la-debugallocation.Tpo\" -c -o libtcmalloc_minimal_debug_la-debugallocation.lo `test -f 'src/debugallocation.cc' || echo '$(srcdir)/'`src/debugallocation.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_debug_la-debugallocation.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_debug_la-debugallocation.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_debug_la-debugallocation.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/debugallocation.cc' object='libtcmalloc_minimal_debug_la-debugallocation.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_debug_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_debug_la-debugallocation.lo `test -f 'src/debugallocation.cc' || echo '$(srcdir)/'`src/debugallocation.cc\n\nlibtcmalloc_minimal_internal_la-common.lo: src/common.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-common.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-common.Tpo\" -c -o libtcmalloc_minimal_internal_la-common.lo `test -f 'src/common.cc' || echo '$(srcdir)/'`src/common.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-common.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-common.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-common.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/common.cc' object='libtcmalloc_minimal_internal_la-common.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-common.lo `test -f 'src/common.cc' || echo '$(srcdir)/'`src/common.cc\n\nlibtcmalloc_minimal_internal_la-internal_logging.lo: src/internal_logging.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-internal_logging.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-internal_logging.Tpo\" -c -o libtcmalloc_minimal_internal_la-internal_logging.lo `test -f 'src/internal_logging.cc' || echo '$(srcdir)/'`src/internal_logging.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-internal_logging.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-internal_logging.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-internal_logging.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/internal_logging.cc' object='libtcmalloc_minimal_internal_la-internal_logging.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-internal_logging.lo `test -f 'src/internal_logging.cc' || echo '$(srcdir)/'`src/internal_logging.cc\n\nlibtcmalloc_minimal_internal_la-system-alloc.lo: src/system-alloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-system-alloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-system-alloc.Tpo\" -c -o libtcmalloc_minimal_internal_la-system-alloc.lo `test -f 'src/system-alloc.cc' || echo '$(srcdir)/'`src/system-alloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-system-alloc.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-system-alloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-system-alloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/system-alloc.cc' object='libtcmalloc_minimal_internal_la-system-alloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-system-alloc.lo `test -f 'src/system-alloc.cc' || echo '$(srcdir)/'`src/system-alloc.cc\n\nlibtcmalloc_minimal_internal_la-memfs_malloc.lo: src/memfs_malloc.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-memfs_malloc.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-memfs_malloc.Tpo\" -c -o libtcmalloc_minimal_internal_la-memfs_malloc.lo `test -f 'src/memfs_malloc.cc' || echo '$(srcdir)/'`src/memfs_malloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-memfs_malloc.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-memfs_malloc.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-memfs_malloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/memfs_malloc.cc' object='libtcmalloc_minimal_internal_la-memfs_malloc.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-memfs_malloc.lo `test -f 'src/memfs_malloc.cc' || echo '$(srcdir)/'`src/memfs_malloc.cc\n\nlibtcmalloc_minimal_internal_la-central_freelist.lo: src/central_freelist.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-central_freelist.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-central_freelist.Tpo\" -c -o libtcmalloc_minimal_internal_la-central_freelist.lo `test -f 'src/central_freelist.cc' || echo '$(srcdir)/'`src/central_freelist.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-central_freelist.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-central_freelist.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-central_freelist.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/central_freelist.cc' object='libtcmalloc_minimal_internal_la-central_freelist.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-central_freelist.lo `test -f 'src/central_freelist.cc' || echo '$(srcdir)/'`src/central_freelist.cc\n\nlibtcmalloc_minimal_internal_la-page_heap.lo: src/page_heap.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-page_heap.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-page_heap.Tpo\" -c -o libtcmalloc_minimal_internal_la-page_heap.lo `test -f 'src/page_heap.cc' || echo '$(srcdir)/'`src/page_heap.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-page_heap.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-page_heap.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-page_heap.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/page_heap.cc' object='libtcmalloc_minimal_internal_la-page_heap.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-page_heap.lo `test -f 'src/page_heap.cc' || echo '$(srcdir)/'`src/page_heap.cc\n\nlibtcmalloc_minimal_internal_la-sampler.lo: src/sampler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-sampler.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-sampler.Tpo\" -c -o libtcmalloc_minimal_internal_la-sampler.lo `test -f 'src/sampler.cc' || echo '$(srcdir)/'`src/sampler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-sampler.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-sampler.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-sampler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/sampler.cc' object='libtcmalloc_minimal_internal_la-sampler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-sampler.lo `test -f 'src/sampler.cc' || echo '$(srcdir)/'`src/sampler.cc\n\nlibtcmalloc_minimal_internal_la-span.lo: src/span.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-span.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-span.Tpo\" -c -o libtcmalloc_minimal_internal_la-span.lo `test -f 'src/span.cc' || echo '$(srcdir)/'`src/span.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-span.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-span.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-span.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/span.cc' object='libtcmalloc_minimal_internal_la-span.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-span.lo `test -f 'src/span.cc' || echo '$(srcdir)/'`src/span.cc\n\nlibtcmalloc_minimal_internal_la-stack_trace_table.lo: src/stack_trace_table.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-stack_trace_table.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-stack_trace_table.Tpo\" -c -o libtcmalloc_minimal_internal_la-stack_trace_table.lo `test -f 'src/stack_trace_table.cc' || echo '$(srcdir)/'`src/stack_trace_table.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-stack_trace_table.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-stack_trace_table.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-stack_trace_table.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/stack_trace_table.cc' object='libtcmalloc_minimal_internal_la-stack_trace_table.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-stack_trace_table.lo `test -f 'src/stack_trace_table.cc' || echo '$(srcdir)/'`src/stack_trace_table.cc\n\nlibtcmalloc_minimal_internal_la-static_vars.lo: src/static_vars.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-static_vars.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-static_vars.Tpo\" -c -o libtcmalloc_minimal_internal_la-static_vars.lo `test -f 'src/static_vars.cc' || echo '$(srcdir)/'`src/static_vars.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-static_vars.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-static_vars.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-static_vars.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/static_vars.cc' object='libtcmalloc_minimal_internal_la-static_vars.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-static_vars.lo `test -f 'src/static_vars.cc' || echo '$(srcdir)/'`src/static_vars.cc\n\nlibtcmalloc_minimal_internal_la-symbolize.lo: src/symbolize.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-symbolize.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-symbolize.Tpo\" -c -o libtcmalloc_minimal_internal_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-symbolize.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-symbolize.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-symbolize.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/symbolize.cc' object='libtcmalloc_minimal_internal_la-symbolize.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-symbolize.lo `test -f 'src/symbolize.cc' || echo '$(srcdir)/'`src/symbolize.cc\n\nlibtcmalloc_minimal_internal_la-thread_cache.lo: src/thread_cache.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-thread_cache.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-thread_cache.Tpo\" -c -o libtcmalloc_minimal_internal_la-thread_cache.lo `test -f 'src/thread_cache.cc' || echo '$(srcdir)/'`src/thread_cache.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-thread_cache.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-thread_cache.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-thread_cache.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/thread_cache.cc' object='libtcmalloc_minimal_internal_la-thread_cache.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-thread_cache.lo `test -f 'src/thread_cache.cc' || echo '$(srcdir)/'`src/thread_cache.cc\n\nlibtcmalloc_minimal_internal_la-malloc_hook.lo: src/malloc_hook.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-malloc_hook.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_hook.Tpo\" -c -o libtcmalloc_minimal_internal_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_hook.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_hook.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_hook.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/malloc_hook.cc' object='libtcmalloc_minimal_internal_la-malloc_hook.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc\n\nlibtcmalloc_minimal_internal_la-malloc_extension.lo: src/malloc_extension.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-malloc_extension.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_extension.Tpo\" -c -o libtcmalloc_minimal_internal_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_extension.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_extension.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-malloc_extension.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/malloc_extension.cc' object='libtcmalloc_minimal_internal_la-malloc_extension.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc\n\nlibtcmalloc_minimal_internal_la-maybe_threads.lo: src/maybe_threads.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_internal_la-maybe_threads.lo -MD -MP -MF \"$(DEPDIR)/libtcmalloc_minimal_internal_la-maybe_threads.Tpo\" -c -o libtcmalloc_minimal_internal_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-maybe_threads.Tpo\" \"$(DEPDIR)/libtcmalloc_minimal_internal_la-maybe_threads.Plo\"; else rm -f \"$(DEPDIR)/libtcmalloc_minimal_internal_la-maybe_threads.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/maybe_threads.cc' object='libtcmalloc_minimal_internal_la-maybe_threads.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_internal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_internal_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc\n\nport.lo: src/windows/port.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT port.lo -MD -MP -MF \"$(DEPDIR)/port.Tpo\" -c -o port.lo `test -f 'src/windows/port.cc' || echo '$(srcdir)/'`src/windows/port.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/port.Tpo\" \"$(DEPDIR)/port.Plo\"; else rm -f \"$(DEPDIR)/port.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/port.cc' object='port.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o port.lo `test -f 'src/windows/port.cc' || echo '$(srcdir)/'`src/windows/port.cc\n\nia32_modrm_map.lo: src/windows/ia32_modrm_map.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ia32_modrm_map.lo -MD -MP -MF \"$(DEPDIR)/ia32_modrm_map.Tpo\" -c -o ia32_modrm_map.lo `test -f 'src/windows/ia32_modrm_map.cc' || echo '$(srcdir)/'`src/windows/ia32_modrm_map.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/ia32_modrm_map.Tpo\" \"$(DEPDIR)/ia32_modrm_map.Plo\"; else rm -f \"$(DEPDIR)/ia32_modrm_map.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/ia32_modrm_map.cc' object='ia32_modrm_map.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ia32_modrm_map.lo `test -f 'src/windows/ia32_modrm_map.cc' || echo '$(srcdir)/'`src/windows/ia32_modrm_map.cc\n\nia32_opcode_map.lo: src/windows/ia32_opcode_map.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ia32_opcode_map.lo -MD -MP -MF \"$(DEPDIR)/ia32_opcode_map.Tpo\" -c -o ia32_opcode_map.lo `test -f 'src/windows/ia32_opcode_map.cc' || echo '$(srcdir)/'`src/windows/ia32_opcode_map.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/ia32_opcode_map.Tpo\" \"$(DEPDIR)/ia32_opcode_map.Plo\"; else rm -f \"$(DEPDIR)/ia32_opcode_map.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/ia32_opcode_map.cc' object='ia32_opcode_map.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ia32_opcode_map.lo `test -f 'src/windows/ia32_opcode_map.cc' || echo '$(srcdir)/'`src/windows/ia32_opcode_map.cc\n\nmini_disassembler.lo: src/windows/mini_disassembler.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT mini_disassembler.lo -MD -MP -MF \"$(DEPDIR)/mini_disassembler.Tpo\" -c -o mini_disassembler.lo `test -f 'src/windows/mini_disassembler.cc' || echo '$(srcdir)/'`src/windows/mini_disassembler.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/mini_disassembler.Tpo\" \"$(DEPDIR)/mini_disassembler.Plo\"; else rm -f \"$(DEPDIR)/mini_disassembler.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/mini_disassembler.cc' object='mini_disassembler.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o mini_disassembler.lo `test -f 'src/windows/mini_disassembler.cc' || echo '$(srcdir)/'`src/windows/mini_disassembler.cc\n\npatch_functions.lo: src/windows/patch_functions.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT patch_functions.lo -MD -MP -MF \"$(DEPDIR)/patch_functions.Tpo\" -c -o patch_functions.lo `test -f 'src/windows/patch_functions.cc' || echo '$(srcdir)/'`src/windows/patch_functions.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/patch_functions.Tpo\" \"$(DEPDIR)/patch_functions.Plo\"; else rm -f \"$(DEPDIR)/patch_functions.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/patch_functions.cc' object='patch_functions.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o patch_functions.lo `test -f 'src/windows/patch_functions.cc' || echo '$(srcdir)/'`src/windows/patch_functions.cc\n\npreamble_patcher.lo: src/windows/preamble_patcher.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT preamble_patcher.lo -MD -MP -MF \"$(DEPDIR)/preamble_patcher.Tpo\" -c -o preamble_patcher.lo `test -f 'src/windows/preamble_patcher.cc' || echo '$(srcdir)/'`src/windows/preamble_patcher.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/preamble_patcher.Tpo\" \"$(DEPDIR)/preamble_patcher.Plo\"; else rm -f \"$(DEPDIR)/preamble_patcher.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/preamble_patcher.cc' object='preamble_patcher.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o preamble_patcher.lo `test -f 'src/windows/preamble_patcher.cc' || echo '$(srcdir)/'`src/windows/preamble_patcher.cc\n\npreamble_patcher_with_stub.lo: src/windows/preamble_patcher_with_stub.cc\n@am__fastdepCXX_TRUE@\tif $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT preamble_patcher_with_stub.lo -MD -MP -MF \"$(DEPDIR)/preamble_patcher_with_stub.Tpo\" -c -o preamble_patcher_with_stub.lo `test -f 'src/windows/preamble_patcher_with_stub.cc' || echo '$(srcdir)/'`src/windows/preamble_patcher_with_stub.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/preamble_patcher_with_stub.Tpo\" \"$(DEPDIR)/preamble_patcher_with_stub.Plo\"; else rm -f \"$(DEPDIR)/preamble_patcher_with_stub.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/preamble_patcher_with_stub.cc' object='preamble_patcher_with_stub.lo' libtool=yes @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o preamble_patcher_with_stub.lo `test -f 'src/windows/preamble_patcher_with_stub.cc' || echo '$(srcdir)/'`src/windows/preamble_patcher_with_stub.cc\n\naddressmap_unittest-addressmap_unittest.o: src/tests/addressmap_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -MT addressmap_unittest-addressmap_unittest.o -MD -MP -MF \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo\" -c -o addressmap_unittest-addressmap_unittest.o `test -f 'src/tests/addressmap_unittest.cc' || echo '$(srcdir)/'`src/tests/addressmap_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo\" \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Po\"; else rm -f \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/addressmap_unittest.cc' object='addressmap_unittest-addressmap_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o addressmap_unittest-addressmap_unittest.o `test -f 'src/tests/addressmap_unittest.cc' || echo '$(srcdir)/'`src/tests/addressmap_unittest.cc\n\naddressmap_unittest-addressmap_unittest.obj: src/tests/addressmap_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -MT addressmap_unittest-addressmap_unittest.obj -MD -MP -MF \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo\" -c -o addressmap_unittest-addressmap_unittest.obj `if test -f 'src/tests/addressmap_unittest.cc'; then $(CYGPATH_W) 'src/tests/addressmap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/addressmap_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo\" \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Po\"; else rm -f \"$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/addressmap_unittest.cc' object='addressmap_unittest-addressmap_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o addressmap_unittest-addressmap_unittest.obj `if test -f 'src/tests/addressmap_unittest.cc'; then $(CYGPATH_W) 'src/tests/addressmap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/addressmap_unittest.cc'; fi`\n\naddressmap_unittest-port.o: src/windows/port.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -MT addressmap_unittest-port.o -MD -MP -MF \"$(DEPDIR)/addressmap_unittest-port.Tpo\" -c -o addressmap_unittest-port.o `test -f 'src/windows/port.cc' || echo '$(srcdir)/'`src/windows/port.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/addressmap_unittest-port.Tpo\" \"$(DEPDIR)/addressmap_unittest-port.Po\"; else rm -f \"$(DEPDIR)/addressmap_unittest-port.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/port.cc' object='addressmap_unittest-port.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o addressmap_unittest-port.o `test -f 'src/windows/port.cc' || echo '$(srcdir)/'`src/windows/port.cc\n\naddressmap_unittest-port.obj: src/windows/port.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -MT addressmap_unittest-port.obj -MD -MP -MF \"$(DEPDIR)/addressmap_unittest-port.Tpo\" -c -o addressmap_unittest-port.obj `if test -f 'src/windows/port.cc'; then $(CYGPATH_W) 'src/windows/port.cc'; else $(CYGPATH_W) '$(srcdir)/src/windows/port.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/addressmap_unittest-port.Tpo\" \"$(DEPDIR)/addressmap_unittest-port.Po\"; else rm -f \"$(DEPDIR)/addressmap_unittest-port.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/windows/port.cc' object='addressmap_unittest-port.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o addressmap_unittest-port.obj `if test -f 'src/windows/port.cc'; then $(CYGPATH_W) 'src/windows/port.cc'; else $(CYGPATH_W) '$(srcdir)/src/windows/port.cc'; fi`\n\natomicops_unittest.o: src/tests/atomicops_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_unittest.o -MD -MP -MF \"$(DEPDIR)/atomicops_unittest.Tpo\" -c -o atomicops_unittest.o `test -f 'src/tests/atomicops_unittest.cc' || echo '$(srcdir)/'`src/tests/atomicops_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/atomicops_unittest.Tpo\" \"$(DEPDIR)/atomicops_unittest.Po\"; else rm -f \"$(DEPDIR)/atomicops_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/atomicops_unittest.cc' object='atomicops_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops_unittest.o `test -f 'src/tests/atomicops_unittest.cc' || echo '$(srcdir)/'`src/tests/atomicops_unittest.cc\n\natomicops_unittest.obj: src/tests/atomicops_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_unittest.obj -MD -MP -MF \"$(DEPDIR)/atomicops_unittest.Tpo\" -c -o atomicops_unittest.obj `if test -f 'src/tests/atomicops_unittest.cc'; then $(CYGPATH_W) 'src/tests/atomicops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/atomicops_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/atomicops_unittest.Tpo\" \"$(DEPDIR)/atomicops_unittest.Po\"; else rm -f \"$(DEPDIR)/atomicops_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/atomicops_unittest.cc' object='atomicops_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops_unittest.obj `if test -f 'src/tests/atomicops_unittest.cc'; then $(CYGPATH_W) 'src/tests/atomicops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/atomicops_unittest.cc'; fi`\n\ndebugallocation_test-debugallocation_test.o: src/tests/debugallocation_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debugallocation_test_CXXFLAGS) $(CXXFLAGS) -MT debugallocation_test-debugallocation_test.o -MD -MP -MF \"$(DEPDIR)/debugallocation_test-debugallocation_test.Tpo\" -c -o debugallocation_test-debugallocation_test.o `test -f 'src/tests/debugallocation_test.cc' || echo '$(srcdir)/'`src/tests/debugallocation_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/debugallocation_test-debugallocation_test.Tpo\" \"$(DEPDIR)/debugallocation_test-debugallocation_test.Po\"; else rm -f \"$(DEPDIR)/debugallocation_test-debugallocation_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/debugallocation_test.cc' object='debugallocation_test-debugallocation_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debugallocation_test_CXXFLAGS) $(CXXFLAGS) -c -o debugallocation_test-debugallocation_test.o `test -f 'src/tests/debugallocation_test.cc' || echo '$(srcdir)/'`src/tests/debugallocation_test.cc\n\ndebugallocation_test-debugallocation_test.obj: src/tests/debugallocation_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debugallocation_test_CXXFLAGS) $(CXXFLAGS) -MT debugallocation_test-debugallocation_test.obj -MD -MP -MF \"$(DEPDIR)/debugallocation_test-debugallocation_test.Tpo\" -c -o debugallocation_test-debugallocation_test.obj `if test -f 'src/tests/debugallocation_test.cc'; then $(CYGPATH_W) 'src/tests/debugallocation_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/debugallocation_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/debugallocation_test-debugallocation_test.Tpo\" \"$(DEPDIR)/debugallocation_test-debugallocation_test.Po\"; else rm -f \"$(DEPDIR)/debugallocation_test-debugallocation_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/debugallocation_test.cc' object='debugallocation_test-debugallocation_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debugallocation_test_CXXFLAGS) $(CXXFLAGS) -c -o debugallocation_test-debugallocation_test.obj `if test -f 'src/tests/debugallocation_test.cc'; then $(CYGPATH_W) 'src/tests/debugallocation_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/debugallocation_test.cc'; fi`\n\nfrag_unittest-frag_unittest.o: src/tests/frag_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -MT frag_unittest-frag_unittest.o -MD -MP -MF \"$(DEPDIR)/frag_unittest-frag_unittest.Tpo\" -c -o frag_unittest-frag_unittest.o `test -f 'src/tests/frag_unittest.cc' || echo '$(srcdir)/'`src/tests/frag_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/frag_unittest-frag_unittest.Tpo\" \"$(DEPDIR)/frag_unittest-frag_unittest.Po\"; else rm -f \"$(DEPDIR)/frag_unittest-frag_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/frag_unittest.cc' object='frag_unittest-frag_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -c -o frag_unittest-frag_unittest.o `test -f 'src/tests/frag_unittest.cc' || echo '$(srcdir)/'`src/tests/frag_unittest.cc\n\nfrag_unittest-frag_unittest.obj: src/tests/frag_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -MT frag_unittest-frag_unittest.obj -MD -MP -MF \"$(DEPDIR)/frag_unittest-frag_unittest.Tpo\" -c -o frag_unittest-frag_unittest.obj `if test -f 'src/tests/frag_unittest.cc'; then $(CYGPATH_W) 'src/tests/frag_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/frag_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/frag_unittest-frag_unittest.Tpo\" \"$(DEPDIR)/frag_unittest-frag_unittest.Po\"; else rm -f \"$(DEPDIR)/frag_unittest-frag_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/frag_unittest.cc' object='frag_unittest-frag_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -c -o frag_unittest-frag_unittest.obj `if test -f 'src/tests/frag_unittest.cc'; then $(CYGPATH_W) 'src/tests/frag_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/frag_unittest.cc'; fi`\n\ngetpc_test.o: src/tests/getpc_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT getpc_test.o -MD -MP -MF \"$(DEPDIR)/getpc_test.Tpo\" -c -o getpc_test.o `test -f 'src/tests/getpc_test.cc' || echo '$(srcdir)/'`src/tests/getpc_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/getpc_test.Tpo\" \"$(DEPDIR)/getpc_test.Po\"; else rm -f \"$(DEPDIR)/getpc_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/getpc_test.cc' object='getpc_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o getpc_test.o `test -f 'src/tests/getpc_test.cc' || echo '$(srcdir)/'`src/tests/getpc_test.cc\n\ngetpc_test.obj: src/tests/getpc_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT getpc_test.obj -MD -MP -MF \"$(DEPDIR)/getpc_test.Tpo\" -c -o getpc_test.obj `if test -f 'src/tests/getpc_test.cc'; then $(CYGPATH_W) 'src/tests/getpc_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/getpc_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/getpc_test.Tpo\" \"$(DEPDIR)/getpc_test.Po\"; else rm -f \"$(DEPDIR)/getpc_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/getpc_test.cc' object='getpc_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o getpc_test.obj `if test -f 'src/tests/getpc_test.cc'; then $(CYGPATH_W) 'src/tests/getpc_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/getpc_test.cc'; fi`\n\nheap_checker_debug_unittest-heap-checker_unittest.o: src/tests/heap-checker_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_checker_debug_unittest-heap-checker_unittest.o -MD -MP -MF \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Tpo\" -c -o heap_checker_debug_unittest-heap-checker_unittest.o `test -f 'src/tests/heap-checker_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-checker_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Tpo\" \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-checker_unittest.cc' object='heap_checker_debug_unittest-heap-checker_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_checker_debug_unittest-heap-checker_unittest.o `test -f 'src/tests/heap-checker_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-checker_unittest.cc\n\nheap_checker_debug_unittest-heap-checker_unittest.obj: src/tests/heap-checker_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_checker_debug_unittest-heap-checker_unittest.obj -MD -MP -MF \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Tpo\" -c -o heap_checker_debug_unittest-heap-checker_unittest.obj `if test -f 'src/tests/heap-checker_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-checker_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Tpo\" \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_checker_debug_unittest-heap-checker_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-checker_unittest.cc' object='heap_checker_debug_unittest-heap-checker_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_checker_debug_unittest-heap-checker_unittest.obj `if test -f 'src/tests/heap-checker_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-checker_unittest.cc'; fi`\n\nheap_checker_unittest-heap-checker_unittest.o: src/tests/heap-checker_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_checker_unittest-heap-checker_unittest.o -MD -MP -MF \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo\" -c -o heap_checker_unittest-heap-checker_unittest.o `test -f 'src/tests/heap-checker_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-checker_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo\" \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-checker_unittest.cc' object='heap_checker_unittest-heap-checker_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_checker_unittest-heap-checker_unittest.o `test -f 'src/tests/heap-checker_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-checker_unittest.cc\n\nheap_checker_unittest-heap-checker_unittest.obj: src/tests/heap-checker_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_checker_unittest-heap-checker_unittest.obj -MD -MP -MF \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo\" -c -o heap_checker_unittest-heap-checker_unittest.obj `if test -f 'src/tests/heap-checker_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-checker_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo\" \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-checker_unittest.cc' object='heap_checker_unittest-heap-checker_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_checker_unittest-heap-checker_unittest.obj `if test -f 'src/tests/heap-checker_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-checker_unittest.cc'; fi`\n\nheap_profiler_debug_unittest-heap-profiler_unittest.o: src/tests/heap-profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_profiler_debug_unittest-heap-profiler_unittest.o -MD -MP -MF \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Tpo\" -c -o heap_profiler_debug_unittest-heap-profiler_unittest.o `test -f 'src/tests/heap-profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-profiler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Tpo\" \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-profiler_unittest.cc' object='heap_profiler_debug_unittest-heap-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_profiler_debug_unittest-heap-profiler_unittest.o `test -f 'src/tests/heap-profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-profiler_unittest.cc\n\nheap_profiler_debug_unittest-heap-profiler_unittest.obj: src/tests/heap-profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_profiler_debug_unittest-heap-profiler_unittest.obj -MD -MP -MF \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Tpo\" -c -o heap_profiler_debug_unittest-heap-profiler_unittest.obj `if test -f 'src/tests/heap-profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-profiler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Tpo\" \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_profiler_debug_unittest-heap-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-profiler_unittest.cc' object='heap_profiler_debug_unittest-heap-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_profiler_debug_unittest-heap-profiler_unittest.obj `if test -f 'src/tests/heap-profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-profiler_unittest.cc'; fi`\n\nheap_profiler_unittest-heap-profiler_unittest.o: src/tests/heap-profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_profiler_unittest-heap-profiler_unittest.o -MD -MP -MF \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo\" -c -o heap_profiler_unittest-heap-profiler_unittest.o `test -f 'src/tests/heap-profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-profiler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo\" \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-profiler_unittest.cc' object='heap_profiler_unittest-heap-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_profiler_unittest-heap-profiler_unittest.o `test -f 'src/tests/heap-profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-profiler_unittest.cc\n\nheap_profiler_unittest-heap-profiler_unittest.obj: src/tests/heap-profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_profiler_unittest-heap-profiler_unittest.obj -MD -MP -MF \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo\" -c -o heap_profiler_unittest-heap-profiler_unittest.obj `if test -f 'src/tests/heap-profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-profiler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo\" \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/heap-profiler_unittest.cc' object='heap_profiler_unittest-heap-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_profiler_unittest-heap-profiler_unittest.obj `if test -f 'src/tests/heap-profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-profiler_unittest.cc'; fi`\n\nlow_level_alloc_unittest-low_level_alloc.o: src/base/low_level_alloc.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest-low_level_alloc.o -MD -MP -MF \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Tpo\" -c -o low_level_alloc_unittest-low_level_alloc.o `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Tpo\" \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Po\"; else rm -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/low_level_alloc.cc' object='low_level_alloc_unittest-low_level_alloc.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest-low_level_alloc.o `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc\n\nlow_level_alloc_unittest-low_level_alloc.obj: src/base/low_level_alloc.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest-low_level_alloc.obj -MD -MP -MF \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Tpo\" -c -o low_level_alloc_unittest-low_level_alloc.obj `if test -f 'src/base/low_level_alloc.cc'; then $(CYGPATH_W) 'src/base/low_level_alloc.cc'; else $(CYGPATH_W) '$(srcdir)/src/base/low_level_alloc.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Tpo\" \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Po\"; else rm -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/base/low_level_alloc.cc' object='low_level_alloc_unittest-low_level_alloc.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest-low_level_alloc.obj `if test -f 'src/base/low_level_alloc.cc'; then $(CYGPATH_W) 'src/base/low_level_alloc.cc'; else $(CYGPATH_W) '$(srcdir)/src/base/low_level_alloc.cc'; fi`\n\nlow_level_alloc_unittest-malloc_hook.o: src/malloc_hook.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest-malloc_hook.o -MD -MP -MF \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Tpo\" -c -o low_level_alloc_unittest-malloc_hook.o `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Tpo\" \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Po\"; else rm -f \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/malloc_hook.cc' object='low_level_alloc_unittest-malloc_hook.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest-malloc_hook.o `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc\n\nlow_level_alloc_unittest-malloc_hook.obj: src/malloc_hook.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest-malloc_hook.obj -MD -MP -MF \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Tpo\" -c -o low_level_alloc_unittest-malloc_hook.obj `if test -f 'src/malloc_hook.cc'; then $(CYGPATH_W) 'src/malloc_hook.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_hook.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Tpo\" \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Po\"; else rm -f \"$(DEPDIR)/low_level_alloc_unittest-malloc_hook.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/malloc_hook.cc' object='low_level_alloc_unittest-malloc_hook.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest-malloc_hook.obj `if test -f 'src/malloc_hook.cc'; then $(CYGPATH_W) 'src/malloc_hook.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_hook.cc'; fi`\n\nlow_level_alloc_unittest-low_level_alloc_unittest.o: src/tests/low_level_alloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest-low_level_alloc_unittest.o -MD -MP -MF \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Tpo\" -c -o low_level_alloc_unittest-low_level_alloc_unittest.o `test -f 'src/tests/low_level_alloc_unittest.cc' || echo '$(srcdir)/'`src/tests/low_level_alloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Tpo\" \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Po\"; else rm -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/low_level_alloc_unittest.cc' object='low_level_alloc_unittest-low_level_alloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest-low_level_alloc_unittest.o `test -f 'src/tests/low_level_alloc_unittest.cc' || echo '$(srcdir)/'`src/tests/low_level_alloc_unittest.cc\n\nlow_level_alloc_unittest-low_level_alloc_unittest.obj: src/tests/low_level_alloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest-low_level_alloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Tpo\" -c -o low_level_alloc_unittest-low_level_alloc_unittest.obj `if test -f 'src/tests/low_level_alloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/low_level_alloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/low_level_alloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Tpo\" \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Po\"; else rm -f \"$(DEPDIR)/low_level_alloc_unittest-low_level_alloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/low_level_alloc_unittest.cc' object='low_level_alloc_unittest-low_level_alloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(low_level_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest-low_level_alloc_unittest.obj `if test -f 'src/tests/low_level_alloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/low_level_alloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/low_level_alloc_unittest.cc'; fi`\n\nmalloc_extension_debug_test-malloc_extension_test.o: src/tests/malloc_extension_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_debug_test_CXXFLAGS) $(CXXFLAGS) -MT malloc_extension_debug_test-malloc_extension_test.o -MD -MP -MF \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Tpo\" -c -o malloc_extension_debug_test-malloc_extension_test.o `test -f 'src/tests/malloc_extension_test.cc' || echo '$(srcdir)/'`src/tests/malloc_extension_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Tpo\" \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Po\"; else rm -f \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/malloc_extension_test.cc' object='malloc_extension_debug_test-malloc_extension_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_debug_test_CXXFLAGS) $(CXXFLAGS) -c -o malloc_extension_debug_test-malloc_extension_test.o `test -f 'src/tests/malloc_extension_test.cc' || echo '$(srcdir)/'`src/tests/malloc_extension_test.cc\n\nmalloc_extension_debug_test-malloc_extension_test.obj: src/tests/malloc_extension_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_debug_test_CXXFLAGS) $(CXXFLAGS) -MT malloc_extension_debug_test-malloc_extension_test.obj -MD -MP -MF \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Tpo\" -c -o malloc_extension_debug_test-malloc_extension_test.obj `if test -f 'src/tests/malloc_extension_test.cc'; then $(CYGPATH_W) 'src/tests/malloc_extension_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/malloc_extension_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Tpo\" \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Po\"; else rm -f \"$(DEPDIR)/malloc_extension_debug_test-malloc_extension_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/malloc_extension_test.cc' object='malloc_extension_debug_test-malloc_extension_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_debug_test_CXXFLAGS) $(CXXFLAGS) -c -o malloc_extension_debug_test-malloc_extension_test.obj `if test -f 'src/tests/malloc_extension_test.cc'; then $(CYGPATH_W) 'src/tests/malloc_extension_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/malloc_extension_test.cc'; fi`\n\nmalloc_extension_test-malloc_extension_test.o: src/tests/malloc_extension_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_test_CXXFLAGS) $(CXXFLAGS) -MT malloc_extension_test-malloc_extension_test.o -MD -MP -MF \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Tpo\" -c -o malloc_extension_test-malloc_extension_test.o `test -f 'src/tests/malloc_extension_test.cc' || echo '$(srcdir)/'`src/tests/malloc_extension_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Tpo\" \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Po\"; else rm -f \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/malloc_extension_test.cc' object='malloc_extension_test-malloc_extension_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_test_CXXFLAGS) $(CXXFLAGS) -c -o malloc_extension_test-malloc_extension_test.o `test -f 'src/tests/malloc_extension_test.cc' || echo '$(srcdir)/'`src/tests/malloc_extension_test.cc\n\nmalloc_extension_test-malloc_extension_test.obj: src/tests/malloc_extension_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_test_CXXFLAGS) $(CXXFLAGS) -MT malloc_extension_test-malloc_extension_test.obj -MD -MP -MF \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Tpo\" -c -o malloc_extension_test-malloc_extension_test.obj `if test -f 'src/tests/malloc_extension_test.cc'; then $(CYGPATH_W) 'src/tests/malloc_extension_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/malloc_extension_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Tpo\" \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Po\"; else rm -f \"$(DEPDIR)/malloc_extension_test-malloc_extension_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/malloc_extension_test.cc' object='malloc_extension_test-malloc_extension_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_extension_test_CXXFLAGS) $(CXXFLAGS) -c -o malloc_extension_test-malloc_extension_test.obj `if test -f 'src/tests/malloc_extension_test.cc'; then $(CYGPATH_W) 'src/tests/malloc_extension_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/malloc_extension_test.cc'; fi`\n\nmarkidle_unittest-markidle_unittest.o: src/tests/markidle_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-markidle_unittest.o -MD -MP -MF \"$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo\" -c -o markidle_unittest-markidle_unittest.o `test -f 'src/tests/markidle_unittest.cc' || echo '$(srcdir)/'`src/tests/markidle_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo\" \"$(DEPDIR)/markidle_unittest-markidle_unittest.Po\"; else rm -f \"$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/markidle_unittest.cc' object='markidle_unittest-markidle_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-markidle_unittest.o `test -f 'src/tests/markidle_unittest.cc' || echo '$(srcdir)/'`src/tests/markidle_unittest.cc\n\nmarkidle_unittest-markidle_unittest.obj: src/tests/markidle_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-markidle_unittest.obj -MD -MP -MF \"$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo\" -c -o markidle_unittest-markidle_unittest.obj `if test -f 'src/tests/markidle_unittest.cc'; then $(CYGPATH_W) 'src/tests/markidle_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/markidle_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo\" \"$(DEPDIR)/markidle_unittest-markidle_unittest.Po\"; else rm -f \"$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/markidle_unittest.cc' object='markidle_unittest-markidle_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-markidle_unittest.obj `if test -f 'src/tests/markidle_unittest.cc'; then $(CYGPATH_W) 'src/tests/markidle_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/markidle_unittest.cc'; fi`\n\nmarkidle_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/markidle_unittest-testutil.Tpo\" -c -o markidle_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/markidle_unittest-testutil.Tpo\" \"$(DEPDIR)/markidle_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/markidle_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='markidle_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nmarkidle_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/markidle_unittest-testutil.Tpo\" -c -o markidle_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/markidle_unittest-testutil.Tpo\" \"$(DEPDIR)/markidle_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/markidle_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='markidle_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nmemalign_debug_unittest-memalign_unittest.o: src/tests/memalign_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_debug_unittest-memalign_unittest.o -MD -MP -MF \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Tpo\" -c -o memalign_debug_unittest-memalign_unittest.o `test -f 'src/tests/memalign_unittest.cc' || echo '$(srcdir)/'`src/tests/memalign_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Tpo\" \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Po\"; else rm -f \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/memalign_unittest.cc' object='memalign_debug_unittest-memalign_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_debug_unittest-memalign_unittest.o `test -f 'src/tests/memalign_unittest.cc' || echo '$(srcdir)/'`src/tests/memalign_unittest.cc\n\nmemalign_debug_unittest-memalign_unittest.obj: src/tests/memalign_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_debug_unittest-memalign_unittest.obj -MD -MP -MF \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Tpo\" -c -o memalign_debug_unittest-memalign_unittest.obj `if test -f 'src/tests/memalign_unittest.cc'; then $(CYGPATH_W) 'src/tests/memalign_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/memalign_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Tpo\" \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Po\"; else rm -f \"$(DEPDIR)/memalign_debug_unittest-memalign_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/memalign_unittest.cc' object='memalign_debug_unittest-memalign_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_debug_unittest-memalign_unittest.obj `if test -f 'src/tests/memalign_unittest.cc'; then $(CYGPATH_W) 'src/tests/memalign_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/memalign_unittest.cc'; fi`\n\nmemalign_debug_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_debug_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/memalign_debug_unittest-testutil.Tpo\" -c -o memalign_debug_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_debug_unittest-testutil.Tpo\" \"$(DEPDIR)/memalign_debug_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/memalign_debug_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='memalign_debug_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_debug_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nmemalign_debug_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_debug_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/memalign_debug_unittest-testutil.Tpo\" -c -o memalign_debug_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_debug_unittest-testutil.Tpo\" \"$(DEPDIR)/memalign_debug_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/memalign_debug_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='memalign_debug_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_debug_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nmemalign_unittest-memalign_unittest.o: src/tests/memalign_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_unittest-memalign_unittest.o -MD -MP -MF \"$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo\" -c -o memalign_unittest-memalign_unittest.o `test -f 'src/tests/memalign_unittest.cc' || echo '$(srcdir)/'`src/tests/memalign_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo\" \"$(DEPDIR)/memalign_unittest-memalign_unittest.Po\"; else rm -f \"$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/memalign_unittest.cc' object='memalign_unittest-memalign_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_unittest-memalign_unittest.o `test -f 'src/tests/memalign_unittest.cc' || echo '$(srcdir)/'`src/tests/memalign_unittest.cc\n\nmemalign_unittest-memalign_unittest.obj: src/tests/memalign_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_unittest-memalign_unittest.obj -MD -MP -MF \"$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo\" -c -o memalign_unittest-memalign_unittest.obj `if test -f 'src/tests/memalign_unittest.cc'; then $(CYGPATH_W) 'src/tests/memalign_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/memalign_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo\" \"$(DEPDIR)/memalign_unittest-memalign_unittest.Po\"; else rm -f \"$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/memalign_unittest.cc' object='memalign_unittest-memalign_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_unittest-memalign_unittest.obj `if test -f 'src/tests/memalign_unittest.cc'; then $(CYGPATH_W) 'src/tests/memalign_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/memalign_unittest.cc'; fi`\n\nmemalign_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/memalign_unittest-testutil.Tpo\" -c -o memalign_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_unittest-testutil.Tpo\" \"$(DEPDIR)/memalign_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/memalign_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='memalign_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nmemalign_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/memalign_unittest-testutil.Tpo\" -c -o memalign_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/memalign_unittest-testutil.Tpo\" \"$(DEPDIR)/memalign_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/memalign_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='memalign_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\npacked_cache_test-packed-cache_test.o: src/tests/packed-cache_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(packed_cache_test_CXXFLAGS) $(CXXFLAGS) -MT packed_cache_test-packed-cache_test.o -MD -MP -MF \"$(DEPDIR)/packed_cache_test-packed-cache_test.Tpo\" -c -o packed_cache_test-packed-cache_test.o `test -f 'src/tests/packed-cache_test.cc' || echo '$(srcdir)/'`src/tests/packed-cache_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/packed_cache_test-packed-cache_test.Tpo\" \"$(DEPDIR)/packed_cache_test-packed-cache_test.Po\"; else rm -f \"$(DEPDIR)/packed_cache_test-packed-cache_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/packed-cache_test.cc' object='packed_cache_test-packed-cache_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(packed_cache_test_CXXFLAGS) $(CXXFLAGS) -c -o packed_cache_test-packed-cache_test.o `test -f 'src/tests/packed-cache_test.cc' || echo '$(srcdir)/'`src/tests/packed-cache_test.cc\n\npacked_cache_test-packed-cache_test.obj: src/tests/packed-cache_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(packed_cache_test_CXXFLAGS) $(CXXFLAGS) -MT packed_cache_test-packed-cache_test.obj -MD -MP -MF \"$(DEPDIR)/packed_cache_test-packed-cache_test.Tpo\" -c -o packed_cache_test-packed-cache_test.obj `if test -f 'src/tests/packed-cache_test.cc'; then $(CYGPATH_W) 'src/tests/packed-cache_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/packed-cache_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/packed_cache_test-packed-cache_test.Tpo\" \"$(DEPDIR)/packed_cache_test-packed-cache_test.Po\"; else rm -f \"$(DEPDIR)/packed_cache_test-packed-cache_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/packed-cache_test.cc' object='packed_cache_test-packed-cache_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(packed_cache_test_CXXFLAGS) $(CXXFLAGS) -c -o packed_cache_test-packed-cache_test.obj `if test -f 'src/tests/packed-cache_test.cc'; then $(CYGPATH_W) 'src/tests/packed-cache_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/packed-cache_test.cc'; fi`\n\npage_heap_test-page_heap_test.o: src/tests/page_heap_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(page_heap_test_CXXFLAGS) $(CXXFLAGS) -MT page_heap_test-page_heap_test.o -MD -MP -MF \"$(DEPDIR)/page_heap_test-page_heap_test.Tpo\" -c -o page_heap_test-page_heap_test.o `test -f 'src/tests/page_heap_test.cc' || echo '$(srcdir)/'`src/tests/page_heap_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/page_heap_test-page_heap_test.Tpo\" \"$(DEPDIR)/page_heap_test-page_heap_test.Po\"; else rm -f \"$(DEPDIR)/page_heap_test-page_heap_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/page_heap_test.cc' object='page_heap_test-page_heap_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(page_heap_test_CXXFLAGS) $(CXXFLAGS) -c -o page_heap_test-page_heap_test.o `test -f 'src/tests/page_heap_test.cc' || echo '$(srcdir)/'`src/tests/page_heap_test.cc\n\npage_heap_test-page_heap_test.obj: src/tests/page_heap_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(page_heap_test_CXXFLAGS) $(CXXFLAGS) -MT page_heap_test-page_heap_test.obj -MD -MP -MF \"$(DEPDIR)/page_heap_test-page_heap_test.Tpo\" -c -o page_heap_test-page_heap_test.obj `if test -f 'src/tests/page_heap_test.cc'; then $(CYGPATH_W) 'src/tests/page_heap_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/page_heap_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/page_heap_test-page_heap_test.Tpo\" \"$(DEPDIR)/page_heap_test-page_heap_test.Po\"; else rm -f \"$(DEPDIR)/page_heap_test-page_heap_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/page_heap_test.cc' object='page_heap_test-page_heap_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(page_heap_test_CXXFLAGS) $(CXXFLAGS) -c -o page_heap_test-page_heap_test.obj `if test -f 'src/tests/page_heap_test.cc'; then $(CYGPATH_W) 'src/tests/page_heap_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/page_heap_test.cc'; fi`\n\npagemap_unittest-pagemap_unittest.o: src/tests/pagemap_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pagemap_unittest_CXXFLAGS) $(CXXFLAGS) -MT pagemap_unittest-pagemap_unittest.o -MD -MP -MF \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Tpo\" -c -o pagemap_unittest-pagemap_unittest.o `test -f 'src/tests/pagemap_unittest.cc' || echo '$(srcdir)/'`src/tests/pagemap_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Tpo\" \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Po\"; else rm -f \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/pagemap_unittest.cc' object='pagemap_unittest-pagemap_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pagemap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pagemap_unittest-pagemap_unittest.o `test -f 'src/tests/pagemap_unittest.cc' || echo '$(srcdir)/'`src/tests/pagemap_unittest.cc\n\npagemap_unittest-pagemap_unittest.obj: src/tests/pagemap_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pagemap_unittest_CXXFLAGS) $(CXXFLAGS) -MT pagemap_unittest-pagemap_unittest.obj -MD -MP -MF \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Tpo\" -c -o pagemap_unittest-pagemap_unittest.obj `if test -f 'src/tests/pagemap_unittest.cc'; then $(CYGPATH_W) 'src/tests/pagemap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/pagemap_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Tpo\" \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Po\"; else rm -f \"$(DEPDIR)/pagemap_unittest-pagemap_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/pagemap_unittest.cc' object='pagemap_unittest-pagemap_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pagemap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o pagemap_unittest-pagemap_unittest.obj `if test -f 'src/tests/pagemap_unittest.cc'; then $(CYGPATH_W) 'src/tests/pagemap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/pagemap_unittest.cc'; fi`\n\nprofile_handler_unittest-profile-handler_unittest.o: src/tests/profile-handler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profile_handler_unittest_CXXFLAGS) $(CXXFLAGS) -MT profile_handler_unittest-profile-handler_unittest.o -MD -MP -MF \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Tpo\" -c -o profile_handler_unittest-profile-handler_unittest.o `test -f 'src/tests/profile-handler_unittest.cc' || echo '$(srcdir)/'`src/tests/profile-handler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Tpo\" \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Po\"; else rm -f \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profile-handler_unittest.cc' object='profile_handler_unittest-profile-handler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profile_handler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profile_handler_unittest-profile-handler_unittest.o `test -f 'src/tests/profile-handler_unittest.cc' || echo '$(srcdir)/'`src/tests/profile-handler_unittest.cc\n\nprofile_handler_unittest-profile-handler_unittest.obj: src/tests/profile-handler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profile_handler_unittest_CXXFLAGS) $(CXXFLAGS) -MT profile_handler_unittest-profile-handler_unittest.obj -MD -MP -MF \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Tpo\" -c -o profile_handler_unittest-profile-handler_unittest.obj `if test -f 'src/tests/profile-handler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profile-handler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profile-handler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Tpo\" \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Po\"; else rm -f \"$(DEPDIR)/profile_handler_unittest-profile-handler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profile-handler_unittest.cc' object='profile_handler_unittest-profile-handler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profile_handler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profile_handler_unittest-profile-handler_unittest.obj `if test -f 'src/tests/profile-handler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profile-handler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profile-handler_unittest.cc'; fi`\n\nprofiledata_unittest.o: src/tests/profiledata_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profiledata_unittest.o -MD -MP -MF \"$(DEPDIR)/profiledata_unittest.Tpo\" -c -o profiledata_unittest.o `test -f 'src/tests/profiledata_unittest.cc' || echo '$(srcdir)/'`src/tests/profiledata_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiledata_unittest.Tpo\" \"$(DEPDIR)/profiledata_unittest.Po\"; else rm -f \"$(DEPDIR)/profiledata_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiledata_unittest.cc' object='profiledata_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profiledata_unittest.o `test -f 'src/tests/profiledata_unittest.cc' || echo '$(srcdir)/'`src/tests/profiledata_unittest.cc\n\nprofiledata_unittest.obj: src/tests/profiledata_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profiledata_unittest.obj -MD -MP -MF \"$(DEPDIR)/profiledata_unittest.Tpo\" -c -o profiledata_unittest.obj `if test -f 'src/tests/profiledata_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiledata_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiledata_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiledata_unittest.Tpo\" \"$(DEPDIR)/profiledata_unittest.Po\"; else rm -f \"$(DEPDIR)/profiledata_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiledata_unittest.cc' object='profiledata_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profiledata_unittest.obj `if test -f 'src/tests/profiledata_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiledata_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiledata_unittest.cc'; fi`\n\nprofiler1_unittest-profiler_unittest.o: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler1_unittest-profiler_unittest.o -MD -MP -MF \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo\" -c -o profiler1_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler1_unittest-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler1_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc\n\nprofiler1_unittest-profiler_unittest.obj: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler1_unittest-profiler_unittest.obj -MD -MP -MF \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo\" -c -o profiler1_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler1_unittest-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler1_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`\n\nprofiler1_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler1_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/profiler1_unittest-testutil.Tpo\" -c -o profiler1_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler1_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler1_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler1_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler1_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler1_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nprofiler1_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler1_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/profiler1_unittest-testutil.Tpo\" -c -o profiler1_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler1_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler1_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler1_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler1_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler1_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nprofiler2_unittest-profiler_unittest.o: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler2_unittest-profiler_unittest.o -MD -MP -MF \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Tpo\" -c -o profiler2_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler2_unittest-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler2_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc\n\nprofiler2_unittest-profiler_unittest.obj: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler2_unittest-profiler_unittest.obj -MD -MP -MF \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Tpo\" -c -o profiler2_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler2_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler2_unittest-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler2_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`\n\nprofiler2_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler2_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/profiler2_unittest-testutil.Tpo\" -c -o profiler2_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler2_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler2_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler2_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler2_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler2_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nprofiler2_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler2_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/profiler2_unittest-testutil.Tpo\" -c -o profiler2_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler2_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler2_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler2_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler2_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler2_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler2_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nprofiler3_unittest-profiler_unittest.o: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler3_unittest-profiler_unittest.o -MD -MP -MF \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Tpo\" -c -o profiler3_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler3_unittest-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler3_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc\n\nprofiler3_unittest-profiler_unittest.obj: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler3_unittest-profiler_unittest.obj -MD -MP -MF \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Tpo\" -c -o profiler3_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler3_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler3_unittest-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler3_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`\n\nprofiler3_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler3_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/profiler3_unittest-testutil.Tpo\" -c -o profiler3_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler3_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler3_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler3_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler3_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler3_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nprofiler3_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler3_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/profiler3_unittest-testutil.Tpo\" -c -o profiler3_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler3_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler3_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler3_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler3_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler3_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler3_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nprofiler4_unittest-profiler_unittest.o: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler4_unittest-profiler_unittest.o -MD -MP -MF \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Tpo\" -c -o profiler4_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler4_unittest-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler4_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc\n\nprofiler4_unittest-profiler_unittest.obj: src/tests/profiler_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler4_unittest-profiler_unittest.obj -MD -MP -MF \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Tpo\" -c -o profiler4_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Tpo\" \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Po\"; else rm -f \"$(DEPDIR)/profiler4_unittest-profiler_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/profiler_unittest.cc' object='profiler4_unittest-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler4_unittest-profiler_unittest.obj `if test -f 'src/tests/profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/profiler_unittest.cc'; fi`\n\nprofiler4_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler4_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/profiler4_unittest-testutil.Tpo\" -c -o profiler4_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler4_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler4_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler4_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler4_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler4_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nprofiler4_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler4_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/profiler4_unittest-testutil.Tpo\" -c -o profiler4_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/profiler4_unittest-testutil.Tpo\" \"$(DEPDIR)/profiler4_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/profiler4_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='profiler4_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler4_unittest_CXXFLAGS) $(CXXFLAGS) -c -o profiler4_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nraw_printer_test-raw_printer_test.o: src/tests/raw_printer_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(raw_printer_test_CXXFLAGS) $(CXXFLAGS) -MT raw_printer_test-raw_printer_test.o -MD -MP -MF \"$(DEPDIR)/raw_printer_test-raw_printer_test.Tpo\" -c -o raw_printer_test-raw_printer_test.o `test -f 'src/tests/raw_printer_test.cc' || echo '$(srcdir)/'`src/tests/raw_printer_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/raw_printer_test-raw_printer_test.Tpo\" \"$(DEPDIR)/raw_printer_test-raw_printer_test.Po\"; else rm -f \"$(DEPDIR)/raw_printer_test-raw_printer_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/raw_printer_test.cc' object='raw_printer_test-raw_printer_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(raw_printer_test_CXXFLAGS) $(CXXFLAGS) -c -o raw_printer_test-raw_printer_test.o `test -f 'src/tests/raw_printer_test.cc' || echo '$(srcdir)/'`src/tests/raw_printer_test.cc\n\nraw_printer_test-raw_printer_test.obj: src/tests/raw_printer_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(raw_printer_test_CXXFLAGS) $(CXXFLAGS) -MT raw_printer_test-raw_printer_test.obj -MD -MP -MF \"$(DEPDIR)/raw_printer_test-raw_printer_test.Tpo\" -c -o raw_printer_test-raw_printer_test.obj `if test -f 'src/tests/raw_printer_test.cc'; then $(CYGPATH_W) 'src/tests/raw_printer_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/raw_printer_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/raw_printer_test-raw_printer_test.Tpo\" \"$(DEPDIR)/raw_printer_test-raw_printer_test.Po\"; else rm -f \"$(DEPDIR)/raw_printer_test-raw_printer_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/raw_printer_test.cc' object='raw_printer_test-raw_printer_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(raw_printer_test_CXXFLAGS) $(CXXFLAGS) -c -o raw_printer_test-raw_printer_test.obj `if test -f 'src/tests/raw_printer_test.cc'; then $(CYGPATH_W) 'src/tests/raw_printer_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/raw_printer_test.cc'; fi`\n\nrealloc_debug_unittest-realloc_unittest.o: src/tests/realloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT realloc_debug_unittest-realloc_unittest.o -MD -MP -MF \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Tpo\" -c -o realloc_debug_unittest-realloc_unittest.o `test -f 'src/tests/realloc_unittest.cc' || echo '$(srcdir)/'`src/tests/realloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Tpo\" \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Po\"; else rm -f \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/realloc_unittest.cc' object='realloc_debug_unittest-realloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o realloc_debug_unittest-realloc_unittest.o `test -f 'src/tests/realloc_unittest.cc' || echo '$(srcdir)/'`src/tests/realloc_unittest.cc\n\nrealloc_debug_unittest-realloc_unittest.obj: src/tests/realloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT realloc_debug_unittest-realloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Tpo\" -c -o realloc_debug_unittest-realloc_unittest.obj `if test -f 'src/tests/realloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/realloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/realloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Tpo\" \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Po\"; else rm -f \"$(DEPDIR)/realloc_debug_unittest-realloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/realloc_unittest.cc' object='realloc_debug_unittest-realloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o realloc_debug_unittest-realloc_unittest.obj `if test -f 'src/tests/realloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/realloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/realloc_unittest.cc'; fi`\n\nrealloc_unittest-realloc_unittest.o: src/tests/realloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT realloc_unittest-realloc_unittest.o -MD -MP -MF \"$(DEPDIR)/realloc_unittest-realloc_unittest.Tpo\" -c -o realloc_unittest-realloc_unittest.o `test -f 'src/tests/realloc_unittest.cc' || echo '$(srcdir)/'`src/tests/realloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/realloc_unittest-realloc_unittest.Tpo\" \"$(DEPDIR)/realloc_unittest-realloc_unittest.Po\"; else rm -f \"$(DEPDIR)/realloc_unittest-realloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/realloc_unittest.cc' object='realloc_unittest-realloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o realloc_unittest-realloc_unittest.o `test -f 'src/tests/realloc_unittest.cc' || echo '$(srcdir)/'`src/tests/realloc_unittest.cc\n\nrealloc_unittest-realloc_unittest.obj: src/tests/realloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT realloc_unittest-realloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/realloc_unittest-realloc_unittest.Tpo\" -c -o realloc_unittest-realloc_unittest.obj `if test -f 'src/tests/realloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/realloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/realloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/realloc_unittest-realloc_unittest.Tpo\" \"$(DEPDIR)/realloc_unittest-realloc_unittest.Po\"; else rm -f \"$(DEPDIR)/realloc_unittest-realloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/realloc_unittest.cc' object='realloc_unittest-realloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(realloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o realloc_unittest-realloc_unittest.obj `if test -f 'src/tests/realloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/realloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/realloc_unittest.cc'; fi`\n\nsampler_debug_test-sampler_test.o: src/tests/sampler_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_debug_test_CXXFLAGS) $(CXXFLAGS) -MT sampler_debug_test-sampler_test.o -MD -MP -MF \"$(DEPDIR)/sampler_debug_test-sampler_test.Tpo\" -c -o sampler_debug_test-sampler_test.o `test -f 'src/tests/sampler_test.cc' || echo '$(srcdir)/'`src/tests/sampler_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampler_debug_test-sampler_test.Tpo\" \"$(DEPDIR)/sampler_debug_test-sampler_test.Po\"; else rm -f \"$(DEPDIR)/sampler_debug_test-sampler_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampler_test.cc' object='sampler_debug_test-sampler_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_debug_test_CXXFLAGS) $(CXXFLAGS) -c -o sampler_debug_test-sampler_test.o `test -f 'src/tests/sampler_test.cc' || echo '$(srcdir)/'`src/tests/sampler_test.cc\n\nsampler_debug_test-sampler_test.obj: src/tests/sampler_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_debug_test_CXXFLAGS) $(CXXFLAGS) -MT sampler_debug_test-sampler_test.obj -MD -MP -MF \"$(DEPDIR)/sampler_debug_test-sampler_test.Tpo\" -c -o sampler_debug_test-sampler_test.obj `if test -f 'src/tests/sampler_test.cc'; then $(CYGPATH_W) 'src/tests/sampler_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampler_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampler_debug_test-sampler_test.Tpo\" \"$(DEPDIR)/sampler_debug_test-sampler_test.Po\"; else rm -f \"$(DEPDIR)/sampler_debug_test-sampler_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampler_test.cc' object='sampler_debug_test-sampler_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_debug_test_CXXFLAGS) $(CXXFLAGS) -c -o sampler_debug_test-sampler_test.obj `if test -f 'src/tests/sampler_test.cc'; then $(CYGPATH_W) 'src/tests/sampler_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampler_test.cc'; fi`\n\nsampler_test-sampler_test.o: src/tests/sampler_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_test_CXXFLAGS) $(CXXFLAGS) -MT sampler_test-sampler_test.o -MD -MP -MF \"$(DEPDIR)/sampler_test-sampler_test.Tpo\" -c -o sampler_test-sampler_test.o `test -f 'src/tests/sampler_test.cc' || echo '$(srcdir)/'`src/tests/sampler_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampler_test-sampler_test.Tpo\" \"$(DEPDIR)/sampler_test-sampler_test.Po\"; else rm -f \"$(DEPDIR)/sampler_test-sampler_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampler_test.cc' object='sampler_test-sampler_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_test_CXXFLAGS) $(CXXFLAGS) -c -o sampler_test-sampler_test.o `test -f 'src/tests/sampler_test.cc' || echo '$(srcdir)/'`src/tests/sampler_test.cc\n\nsampler_test-sampler_test.obj: src/tests/sampler_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_test_CXXFLAGS) $(CXXFLAGS) -MT sampler_test-sampler_test.obj -MD -MP -MF \"$(DEPDIR)/sampler_test-sampler_test.Tpo\" -c -o sampler_test-sampler_test.obj `if test -f 'src/tests/sampler_test.cc'; then $(CYGPATH_W) 'src/tests/sampler_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampler_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampler_test-sampler_test.Tpo\" \"$(DEPDIR)/sampler_test-sampler_test.Po\"; else rm -f \"$(DEPDIR)/sampler_test-sampler_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampler_test.cc' object='sampler_test-sampler_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampler_test_CXXFLAGS) $(CXXFLAGS) -c -o sampler_test-sampler_test.obj `if test -f 'src/tests/sampler_test.cc'; then $(CYGPATH_W) 'src/tests/sampler_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampler_test.cc'; fi`\n\nsampling_debug_test-sampling_test.o: src/tests/sampling_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_debug_test_CXXFLAGS) $(CXXFLAGS) -MT sampling_debug_test-sampling_test.o -MD -MP -MF \"$(DEPDIR)/sampling_debug_test-sampling_test.Tpo\" -c -o sampling_debug_test-sampling_test.o `test -f 'src/tests/sampling_test.cc' || echo '$(srcdir)/'`src/tests/sampling_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampling_debug_test-sampling_test.Tpo\" \"$(DEPDIR)/sampling_debug_test-sampling_test.Po\"; else rm -f \"$(DEPDIR)/sampling_debug_test-sampling_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampling_test.cc' object='sampling_debug_test-sampling_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_debug_test_CXXFLAGS) $(CXXFLAGS) -c -o sampling_debug_test-sampling_test.o `test -f 'src/tests/sampling_test.cc' || echo '$(srcdir)/'`src/tests/sampling_test.cc\n\nsampling_debug_test-sampling_test.obj: src/tests/sampling_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_debug_test_CXXFLAGS) $(CXXFLAGS) -MT sampling_debug_test-sampling_test.obj -MD -MP -MF \"$(DEPDIR)/sampling_debug_test-sampling_test.Tpo\" -c -o sampling_debug_test-sampling_test.obj `if test -f 'src/tests/sampling_test.cc'; then $(CYGPATH_W) 'src/tests/sampling_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampling_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampling_debug_test-sampling_test.Tpo\" \"$(DEPDIR)/sampling_debug_test-sampling_test.Po\"; else rm -f \"$(DEPDIR)/sampling_debug_test-sampling_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampling_test.cc' object='sampling_debug_test-sampling_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_debug_test_CXXFLAGS) $(CXXFLAGS) -c -o sampling_debug_test-sampling_test.obj `if test -f 'src/tests/sampling_test.cc'; then $(CYGPATH_W) 'src/tests/sampling_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampling_test.cc'; fi`\n\nsampling_test-sampling_test.o: src/tests/sampling_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_test_CXXFLAGS) $(CXXFLAGS) -MT sampling_test-sampling_test.o -MD -MP -MF \"$(DEPDIR)/sampling_test-sampling_test.Tpo\" -c -o sampling_test-sampling_test.o `test -f 'src/tests/sampling_test.cc' || echo '$(srcdir)/'`src/tests/sampling_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampling_test-sampling_test.Tpo\" \"$(DEPDIR)/sampling_test-sampling_test.Po\"; else rm -f \"$(DEPDIR)/sampling_test-sampling_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampling_test.cc' object='sampling_test-sampling_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_test_CXXFLAGS) $(CXXFLAGS) -c -o sampling_test-sampling_test.o `test -f 'src/tests/sampling_test.cc' || echo '$(srcdir)/'`src/tests/sampling_test.cc\n\nsampling_test-sampling_test.obj: src/tests/sampling_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_test_CXXFLAGS) $(CXXFLAGS) -MT sampling_test-sampling_test.obj -MD -MP -MF \"$(DEPDIR)/sampling_test-sampling_test.Tpo\" -c -o sampling_test-sampling_test.obj `if test -f 'src/tests/sampling_test.cc'; then $(CYGPATH_W) 'src/tests/sampling_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampling_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/sampling_test-sampling_test.Tpo\" \"$(DEPDIR)/sampling_test-sampling_test.Po\"; else rm -f \"$(DEPDIR)/sampling_test-sampling_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/sampling_test.cc' object='sampling_test-sampling_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sampling_test_CXXFLAGS) $(CXXFLAGS) -c -o sampling_test-sampling_test.obj `if test -f 'src/tests/sampling_test.cc'; then $(CYGPATH_W) 'src/tests/sampling_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/sampling_test.cc'; fi`\n\nstack_trace_table_test-stack_trace_table_test.o: src/tests/stack_trace_table_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stack_trace_table_test_CXXFLAGS) $(CXXFLAGS) -MT stack_trace_table_test-stack_trace_table_test.o -MD -MP -MF \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Tpo\" -c -o stack_trace_table_test-stack_trace_table_test.o `test -f 'src/tests/stack_trace_table_test.cc' || echo '$(srcdir)/'`src/tests/stack_trace_table_test.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Tpo\" \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Po\"; else rm -f \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/stack_trace_table_test.cc' object='stack_trace_table_test-stack_trace_table_test.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stack_trace_table_test_CXXFLAGS) $(CXXFLAGS) -c -o stack_trace_table_test-stack_trace_table_test.o `test -f 'src/tests/stack_trace_table_test.cc' || echo '$(srcdir)/'`src/tests/stack_trace_table_test.cc\n\nstack_trace_table_test-stack_trace_table_test.obj: src/tests/stack_trace_table_test.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stack_trace_table_test_CXXFLAGS) $(CXXFLAGS) -MT stack_trace_table_test-stack_trace_table_test.obj -MD -MP -MF \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Tpo\" -c -o stack_trace_table_test-stack_trace_table_test.obj `if test -f 'src/tests/stack_trace_table_test.cc'; then $(CYGPATH_W) 'src/tests/stack_trace_table_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/stack_trace_table_test.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Tpo\" \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Po\"; else rm -f \"$(DEPDIR)/stack_trace_table_test-stack_trace_table_test.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/stack_trace_table_test.cc' object='stack_trace_table_test-stack_trace_table_test.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stack_trace_table_test_CXXFLAGS) $(CXXFLAGS) -c -o stack_trace_table_test-stack_trace_table_test.obj `if test -f 'src/tests/stack_trace_table_test.cc'; then $(CYGPATH_W) 'src/tests/stack_trace_table_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/stack_trace_table_test.cc'; fi`\n\nstacktrace_unittest.o: src/tests/stacktrace_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stacktrace_unittest.o -MD -MP -MF \"$(DEPDIR)/stacktrace_unittest.Tpo\" -c -o stacktrace_unittest.o `test -f 'src/tests/stacktrace_unittest.cc' || echo '$(srcdir)/'`src/tests/stacktrace_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/stacktrace_unittest.Tpo\" \"$(DEPDIR)/stacktrace_unittest.Po\"; else rm -f \"$(DEPDIR)/stacktrace_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/stacktrace_unittest.cc' object='stacktrace_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stacktrace_unittest.o `test -f 'src/tests/stacktrace_unittest.cc' || echo '$(srcdir)/'`src/tests/stacktrace_unittest.cc\n\nstacktrace_unittest.obj: src/tests/stacktrace_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stacktrace_unittest.obj -MD -MP -MF \"$(DEPDIR)/stacktrace_unittest.Tpo\" -c -o stacktrace_unittest.obj `if test -f 'src/tests/stacktrace_unittest.cc'; then $(CYGPATH_W) 'src/tests/stacktrace_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/stacktrace_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/stacktrace_unittest.Tpo\" \"$(DEPDIR)/stacktrace_unittest.Po\"; else rm -f \"$(DEPDIR)/stacktrace_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/stacktrace_unittest.cc' object='stacktrace_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stacktrace_unittest.obj `if test -f 'src/tests/stacktrace_unittest.cc'; then $(CYGPATH_W) 'src/tests/stacktrace_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/stacktrace_unittest.cc'; fi`\n\nsystem_alloc_unittest-system-alloc_unittest.o: src/tests/system-alloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(system_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT system_alloc_unittest-system-alloc_unittest.o -MD -MP -MF \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Tpo\" -c -o system_alloc_unittest-system-alloc_unittest.o `test -f 'src/tests/system-alloc_unittest.cc' || echo '$(srcdir)/'`src/tests/system-alloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Tpo\" \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Po\"; else rm -f \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/system-alloc_unittest.cc' object='system_alloc_unittest-system-alloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(system_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o system_alloc_unittest-system-alloc_unittest.o `test -f 'src/tests/system-alloc_unittest.cc' || echo '$(srcdir)/'`src/tests/system-alloc_unittest.cc\n\nsystem_alloc_unittest-system-alloc_unittest.obj: src/tests/system-alloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(system_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT system_alloc_unittest-system-alloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Tpo\" -c -o system_alloc_unittest-system-alloc_unittest.obj `if test -f 'src/tests/system-alloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/system-alloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/system-alloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Tpo\" \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Po\"; else rm -f \"$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/system-alloc_unittest.cc' object='system_alloc_unittest-system-alloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(system_alloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o system_alloc_unittest-system-alloc_unittest.obj `if test -f 'src/tests/system-alloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/system-alloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/system-alloc_unittest.cc'; fi`\n\ntcmalloc_and_profiler_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_and_profiler_unittest-tcmalloc_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_and_profiler_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_and_profiler_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_and_profiler_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc\n\ntcmalloc_and_profiler_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_and_profiler_unittest-tcmalloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_and_profiler_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_and_profiler_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_and_profiler_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`\n\ntcmalloc_and_profiler_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_and_profiler_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Tpo\" -c -o tcmalloc_and_profiler_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_and_profiler_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_and_profiler_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\ntcmalloc_and_profiler_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_and_profiler_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Tpo\" -c -o tcmalloc_and_profiler_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_and_profiler_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_and_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_and_profiler_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\ntcmalloc_both_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_both_unittest-tcmalloc_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_both_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_both_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_both_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc\n\ntcmalloc_both_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_both_unittest-tcmalloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_both_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_both_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_both_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_both_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`\n\ntcmalloc_both_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_both_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Tpo\" -c -o tcmalloc_both_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_both_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_both_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\ntcmalloc_both_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_both_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Tpo\" -c -o tcmalloc_both_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_both_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_both_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_both_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_both_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\ntcmalloc_debug_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_debug_unittest-tcmalloc_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_debug_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_debug_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_debug_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc\n\ntcmalloc_debug_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_debug_unittest-tcmalloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_debug_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_debug_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_debug_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_debug_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`\n\ntcmalloc_debug_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_debug_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Tpo\" -c -o tcmalloc_debug_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_debug_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_debug_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\ntcmalloc_debug_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_debug_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Tpo\" -c -o tcmalloc_debug_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_debug_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_debug_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_debug_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\ntcmalloc_large_unittest-tcmalloc_large_unittest.o: src/tests/tcmalloc_large_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_large_unittest-tcmalloc_large_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo\" -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_large_unittest-tcmalloc_large_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc\n\ntcmalloc_large_unittest-tcmalloc_large_unittest.obj: src/tests/tcmalloc_large_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_large_unittest-tcmalloc_large_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo\" -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_large_unittest-tcmalloc_large_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`\n\ntcmalloc_minimal_debug_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_debug_unittest-tcmalloc_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_minimal_debug_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_minimal_debug_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_debug_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc\n\ntcmalloc_minimal_debug_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_debug_unittest-tcmalloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_minimal_debug_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_minimal_debug_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_debug_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`\n\ntcmalloc_minimal_debug_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_debug_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Tpo\" -c -o tcmalloc_minimal_debug_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_minimal_debug_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_debug_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\ntcmalloc_minimal_debug_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_debug_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Tpo\" -c -o tcmalloc_minimal_debug_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_debug_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_minimal_debug_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_debug_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_debug_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\ntcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o: src/tests/tcmalloc_large_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo\" -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc\n\ntcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj: src/tests/tcmalloc_large_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo\" -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`\n\ntcmalloc_minimal_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_unittest-tcmalloc_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_minimal_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc\n\ntcmalloc_minimal_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_unittest-tcmalloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_minimal_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`\n\ntcmalloc_minimal_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Tpo\" -c -o tcmalloc_minimal_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_minimal_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\ntcmalloc_minimal_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Tpo\" -c -o tcmalloc_minimal_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_minimal_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_minimal_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\ntcmalloc_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_unittest-tcmalloc_unittest.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc\n\ntcmalloc_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_unittest-tcmalloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo\" -c -o tcmalloc_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo\" \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/tcmalloc_unittest.cc' object='tcmalloc_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`\n\ntcmalloc_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/tcmalloc_unittest-testutil.Tpo\" -c -o tcmalloc_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\ntcmalloc_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/tcmalloc_unittest-testutil.Tpo\" -c -o tcmalloc_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/tcmalloc_unittest-testutil.Tpo\" \"$(DEPDIR)/tcmalloc_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/tcmalloc_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='tcmalloc_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nthread_dealloc_unittest-thread_dealloc_unittest.o: src/tests/thread_dealloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-thread_dealloc_unittest.o -MD -MP -MF \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo\" -c -o thread_dealloc_unittest-thread_dealloc_unittest.o `test -f 'src/tests/thread_dealloc_unittest.cc' || echo '$(srcdir)/'`src/tests/thread_dealloc_unittest.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo\" \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Po\"; else rm -f \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/thread_dealloc_unittest.cc' object='thread_dealloc_unittest-thread_dealloc_unittest.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-thread_dealloc_unittest.o `test -f 'src/tests/thread_dealloc_unittest.cc' || echo '$(srcdir)/'`src/tests/thread_dealloc_unittest.cc\n\nthread_dealloc_unittest-thread_dealloc_unittest.obj: src/tests/thread_dealloc_unittest.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-thread_dealloc_unittest.obj -MD -MP -MF \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo\" -c -o thread_dealloc_unittest-thread_dealloc_unittest.obj `if test -f 'src/tests/thread_dealloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/thread_dealloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/thread_dealloc_unittest.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo\" \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Po\"; else rm -f \"$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/thread_dealloc_unittest.cc' object='thread_dealloc_unittest-thread_dealloc_unittest.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-thread_dealloc_unittest.obj `if test -f 'src/tests/thread_dealloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/thread_dealloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/thread_dealloc_unittest.cc'; fi`\n\nthread_dealloc_unittest-testutil.o: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-testutil.o -MD -MP -MF \"$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo\" -c -o thread_dealloc_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo\" \"$(DEPDIR)/thread_dealloc_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='thread_dealloc_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc\n\nthread_dealloc_unittest-testutil.obj: src/tests/testutil.cc\n@am__fastdepCXX_TRUE@\tif $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-testutil.obj -MD -MP -MF \"$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo\" -c -o thread_dealloc_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \\\n@am__fastdepCXX_TRUE@\tthen mv -f \"$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo\" \"$(DEPDIR)/thread_dealloc_unittest-testutil.Po\"; else rm -f \"$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo\"; exit 1; fi\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tsource='src/tests/testutil.cc' object='thread_dealloc_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@\n@AMDEP_TRUE@@am__fastdepCXX_FALSE@\tDEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@\n@am__fastdepCXX_FALSE@\t$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`\n\nmostlyclean-libtool:\n\t-rm -f *.lo\n\nclean-libtool:\n\t-rm -rf .libs _libs\n\ndistclean-libtool:\n\t-rm -f libtool\nuninstall-info-am:\ninstall-man1: $(man1_MANS) $(man_MANS)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(man1dir)\" || $(mkdir_p) \"$(DESTDIR)$(man1dir)\"\n\t@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \\\n\tl2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \\\n\tfor i in $$l2; do \\\n\t  case \"$$i\" in \\\n\t    *.1*) list=\"$$list $$i\" ;; \\\n\t  esac; \\\n\tdone; \\\n\tfor i in $$list; do \\\n\t  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \\\n\t  else file=$$i; fi; \\\n\t  ext=`echo $$i | sed -e 's/^.*\\\\.//'`; \\\n\t  case \"$$ext\" in \\\n\t    1*) ;; \\\n\t    *) ext='1' ;; \\\n\t  esac; \\\n\t  inst=`echo $$i | sed -e 's/\\\\.[0-9a-z]*$$//'`; \\\n\t  inst=`echo $$inst | sed -e 's/^.*\\///'`; \\\n\t  inst=`echo $$inst | sed '$(transform)'`.$$ext; \\\n\t  echo \" $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'\"; \\\n\t  $(INSTALL_DATA) \"$$file\" \"$(DESTDIR)$(man1dir)/$$inst\"; \\\n\tdone\nuninstall-man1:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \\\n\tl2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \\\n\tfor i in $$l2; do \\\n\t  case \"$$i\" in \\\n\t    *.1*) list=\"$$list $$i\" ;; \\\n\t  esac; \\\n\tdone; \\\n\tfor i in $$list; do \\\n\t  ext=`echo $$i | sed -e 's/^.*\\\\.//'`; \\\n\t  case \"$$ext\" in \\\n\t    1*) ;; \\\n\t    *) ext='1' ;; \\\n\t  esac; \\\n\t  inst=`echo $$i | sed -e 's/\\\\.[0-9a-z]*$$//'`; \\\n\t  inst=`echo $$inst | sed -e 's/^.*\\///'`; \\\n\t  inst=`echo $$inst | sed '$(transform)'`.$$ext; \\\n\t  echo \" rm -f '$(DESTDIR)$(man1dir)/$$inst'\"; \\\n\t  rm -f \"$(DESTDIR)$(man1dir)/$$inst\"; \\\n\tdone\ninstall-dist_docDATA: $(dist_doc_DATA)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(docdir)\" || $(mkdir_p) \"$(DESTDIR)$(docdir)\"\n\t@list='$(dist_doc_DATA)'; for p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" $(dist_docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'\"; \\\n\t  $(dist_docDATA_INSTALL) \"$$d$$p\" \"$(DESTDIR)$(docdir)/$$f\"; \\\n\tdone\n\nuninstall-dist_docDATA:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(dist_doc_DATA)'; for p in $$list; do \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" rm -f '$(DESTDIR)$(docdir)/$$f'\"; \\\n\t  rm -f \"$(DESTDIR)$(docdir)/$$f\"; \\\n\tdone\ninstall-pkgconfigDATA: $(pkgconfig_DATA)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(pkgconfigdir)\" || $(mkdir_p) \"$(DESTDIR)$(pkgconfigdir)\"\n\t@list='$(pkgconfig_DATA)'; for p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'\"; \\\n\t  $(pkgconfigDATA_INSTALL) \"$$d$$p\" \"$(DESTDIR)$(pkgconfigdir)/$$f\"; \\\n\tdone\n\nuninstall-pkgconfigDATA:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(pkgconfig_DATA)'; for p in $$list; do \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'\"; \\\n\t  rm -f \"$(DESTDIR)$(pkgconfigdir)/$$f\"; \\\n\tdone\ninstall-googleincludeHEADERS: $(googleinclude_HEADERS)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(googleincludedir)\" || $(mkdir_p) \"$(DESTDIR)$(googleincludedir)\"\n\t@list='$(googleinclude_HEADERS)'; for p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" $(googleincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(googleincludedir)/$$f'\"; \\\n\t  $(googleincludeHEADERS_INSTALL) \"$$d$$p\" \"$(DESTDIR)$(googleincludedir)/$$f\"; \\\n\tdone\n\nuninstall-googleincludeHEADERS:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(googleinclude_HEADERS)'; for p in $$list; do \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" rm -f '$(DESTDIR)$(googleincludedir)/$$f'\"; \\\n\t  rm -f \"$(DESTDIR)$(googleincludedir)/$$f\"; \\\n\tdone\ninstall-nodist_googleincludeHEADERS: $(nodist_googleinclude_HEADERS)\n\t@$(NORMAL_INSTALL)\n\ttest -z \"$(googleincludedir)\" || $(mkdir_p) \"$(DESTDIR)$(googleincludedir)\"\n\t@list='$(nodist_googleinclude_HEADERS)'; for p in $$list; do \\\n\t  if test -f \"$$p\"; then d=; else d=\"$(srcdir)/\"; fi; \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" $(nodist_googleincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(googleincludedir)/$$f'\"; \\\n\t  $(nodist_googleincludeHEADERS_INSTALL) \"$$d$$p\" \"$(DESTDIR)$(googleincludedir)/$$f\"; \\\n\tdone\n\nuninstall-nodist_googleincludeHEADERS:\n\t@$(NORMAL_UNINSTALL)\n\t@list='$(nodist_googleinclude_HEADERS)'; for p in $$list; do \\\n\t  f=$(am__strip_dir) \\\n\t  echo \" rm -f '$(DESTDIR)$(googleincludedir)/$$f'\"; \\\n\t  rm -f \"$(DESTDIR)$(googleincludedir)/$$f\"; \\\n\tdone\n\nID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)\n\tlist='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '    { files[$$0] = 1; } \\\n\t       END { for (i in files) print i; }'`; \\\n\tmkid -fID $$unique\ntags: TAGS\n\nTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\ttags=; \\\n\there=`pwd`; \\\n\tlist='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '    { files[$$0] = 1; } \\\n\t       END { for (i in files) print i; }'`; \\\n\tif test -z \"$(ETAGS_ARGS)$$tags$$unique\"; then :; else \\\n\t  test -n \"$$unique\" || unique=$$empty_fix; \\\n\t  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \\\n\t    $$tags $$unique; \\\n\tfi\nctags: CTAGS\nCTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \\\n\t\t$(TAGS_FILES) $(LISP)\n\ttags=; \\\n\there=`pwd`; \\\n\tlist='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \\\n\tunique=`for i in $$list; do \\\n\t    if test -f \"$$i\"; then echo $$i; else echo $(srcdir)/$$i; fi; \\\n\t  done | \\\n\t  $(AWK) '    { files[$$0] = 1; } \\\n\t       END { for (i in files) print i; }'`; \\\n\ttest -z \"$(CTAGS_ARGS)$$tags$$unique\" \\\n\t  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \\\n\t     $$tags $$unique\n\nGTAGS:\n\there=`$(am__cd) $(top_builddir) && pwd` \\\n\t  && cd $(top_srcdir) \\\n\t  && gtags -i $(GTAGS_ARGS) $$here\n\ndistclean-tags:\n\t-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags\n\ncheck-TESTS: $(TESTS)\n\t@failed=0; all=0; xfail=0; xpass=0; skip=0; \\\n\tsrcdir=$(srcdir); export srcdir; \\\n\tlist='$(TESTS)'; \\\n\tif test -n \"$$list\"; then \\\n\t  for tst in $$list; do \\\n\t    if test -f ./$$tst; then dir=./; \\\n\t    elif test -f $$tst; then dir=; \\\n\t    else dir=\"$(srcdir)/\"; fi; \\\n\t    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \\\n\t      all=`expr $$all + 1`; \\\n\t      case \" $(XFAIL_TESTS) \" in \\\n\t      *\" $$tst \"*) \\\n\t\txpass=`expr $$xpass + 1`; \\\n\t\tfailed=`expr $$failed + 1`; \\\n\t\techo \"XPASS: $$tst\"; \\\n\t      ;; \\\n\t      *) \\\n\t\techo \"PASS: $$tst\"; \\\n\t      ;; \\\n\t      esac; \\\n\t    elif test $$? -ne 77; then \\\n\t      all=`expr $$all + 1`; \\\n\t      case \" $(XFAIL_TESTS) \" in \\\n\t      *\" $$tst \"*) \\\n\t\txfail=`expr $$xfail + 1`; \\\n\t\techo \"XFAIL: $$tst\"; \\\n\t      ;; \\\n\t      *) \\\n\t\tfailed=`expr $$failed + 1`; \\\n\t\techo \"FAIL: $$tst\"; \\\n\t      ;; \\\n\t      esac; \\\n\t    else \\\n\t      skip=`expr $$skip + 1`; \\\n\t      echo \"SKIP: $$tst\"; \\\n\t    fi; \\\n\t  done; \\\n\t  if test \"$$failed\" -eq 0; then \\\n\t    if test \"$$xfail\" -eq 0; then \\\n\t      banner=\"All $$all tests passed\"; \\\n\t    else \\\n\t      banner=\"All $$all tests behaved as expected ($$xfail expected failures)\"; \\\n\t    fi; \\\n\t  else \\\n\t    if test \"$$xpass\" -eq 0; then \\\n\t      banner=\"$$failed of $$all tests failed\"; \\\n\t    else \\\n\t      banner=\"$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)\"; \\\n\t    fi; \\\n\t  fi; \\\n\t  dashes=\"$$banner\"; \\\n\t  skipped=\"\"; \\\n\t  if test \"$$skip\" -ne 0; then \\\n\t    skipped=\"($$skip tests were not run)\"; \\\n\t    test `echo \"$$skipped\" | wc -c` -le `echo \"$$banner\" | wc -c` || \\\n\t      dashes=\"$$skipped\"; \\\n\t  fi; \\\n\t  report=\"\"; \\\n\t  if test \"$$failed\" -ne 0 && test -n \"$(PACKAGE_BUGREPORT)\"; then \\\n\t    report=\"Please report to $(PACKAGE_BUGREPORT)\"; \\\n\t    test `echo \"$$report\" | wc -c` -le `echo \"$$banner\" | wc -c` || \\\n\t      dashes=\"$$report\"; \\\n\t  fi; \\\n\t  dashes=`echo \"$$dashes\" | sed s/./=/g`; \\\n\t  echo \"$$dashes\"; \\\n\t  echo \"$$banner\"; \\\n\t  test -z \"$$skipped\" || echo \"$$skipped\"; \\\n\t  test -z \"$$report\" || echo \"$$report\"; \\\n\t  echo \"$$dashes\"; \\\n\t  test \"$$failed\" -eq 0; \\\n\telse :; fi\n\ndistdir: $(DISTFILES)\n\t$(am__remove_distdir)\n\tmkdir $(distdir)\n\t$(mkdir_p) $(distdir)/$(top_srcdir) $(distdir)/doc $(distdir)/m4 $(distdir)/packages $(distdir)/packages/rpm $(distdir)/src $(distdir)/src/google $(distdir)/src/solaris $(distdir)/src/tests $(distdir)/src/windows $(distdir)/src/windows/google $(distdir)/vsprojects/addr2line-pdb $(distdir)/vsprojects/addressmap_unittest $(distdir)/vsprojects/frag_unittest $(distdir)/vsprojects/libtcmalloc_minimal $(distdir)/vsprojects/low_level_alloc_unittest $(distdir)/vsprojects/malloc_extension_test $(distdir)/vsprojects/markidle_unittest $(distdir)/vsprojects/nm-pdb $(distdir)/vsprojects/packed-cache_test $(distdir)/vsprojects/page_heap_test $(distdir)/vsprojects/pagemap_unittest $(distdir)/vsprojects/realloc_unittest $(distdir)/vsprojects/sampler_test $(distdir)/vsprojects/stack_trace_table_test $(distdir)/vsprojects/tcmalloc_minimal_large $(distdir)/vsprojects/tcmalloc_minimal_unittest $(distdir)/vsprojects/thread_dealloc_unittest $(distdir)/vsprojects/tmu-static\n\t@srcdirstrip=`echo \"$(srcdir)\" | sed 's|.|.|g'`; \\\n\ttopsrcdirstrip=`echo \"$(top_srcdir)\" | sed 's|.|.|g'`; \\\n\tlist='$(DISTFILES)'; for file in $$list; do \\\n\t  case $$file in \\\n\t    $(srcdir)/*) file=`echo \"$$file\" | sed \"s|^$$srcdirstrip/||\"`;; \\\n\t    $(top_srcdir)/*) file=`echo \"$$file\" | sed \"s|^$$topsrcdirstrip/|$(top_builddir)/|\"`;; \\\n\t  esac; \\\n\t  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \\\n\t  dir=`echo \"$$file\" | sed -e 's,/[^/]*$$,,'`; \\\n\t  if test \"$$dir\" != \"$$file\" && test \"$$dir\" != \".\"; then \\\n\t    dir=\"/$$dir\"; \\\n\t    $(mkdir_p) \"$(distdir)$$dir\"; \\\n\t  else \\\n\t    dir=''; \\\n\t  fi; \\\n\t  if test -d $$d/$$file; then \\\n\t    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \\\n\t      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \\\n\t    fi; \\\n\t    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \\\n\t  else \\\n\t    test -f $(distdir)/$$file \\\n\t    || cp -p $$d/$$file $(distdir)/$$file \\\n\t    || exit 1; \\\n\t  fi; \\\n\tdone\n\t$(MAKE) $(AM_MAKEFLAGS) \\\n\t  top_distdir=\"$(top_distdir)\" distdir=\"$(distdir)\" \\\n\t  dist-hook\n\t-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \\; -o \\\n\t  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \\; -o \\\n\t  ! -type d ! -perm -400 -exec chmod a+r {} \\; -o \\\n\t  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \\; \\\n\t|| chmod -R a+r $(distdir)\ndist-gzip: distdir\n\ttardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz\n\t$(am__remove_distdir)\n\ndist-bzip2: distdir\n\ttardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2\n\t$(am__remove_distdir)\n\ndist-tarZ: distdir\n\ttardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z\n\t$(am__remove_distdir)\n\ndist-shar: distdir\n\tshar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz\n\t$(am__remove_distdir)\ndist-zip: distdir\n\t-rm -f $(distdir).zip\n\tzip -rq $(distdir).zip $(distdir)\n\t$(am__remove_distdir)\n\ndist dist-all: distdir\n\ttardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz\n\t-rm -f $(distdir).zip\n\tzip -rq $(distdir).zip $(distdir)\n\t$(am__remove_distdir)\n\n# This target untars the dist file and tries a VPATH configuration.  Then\n# it guarantees that the distribution is self-contained by making another\n# tarfile.\ndistcheck: dist\n\tcase '$(DIST_ARCHIVES)' in \\\n\t*.tar.gz*) \\\n\t  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\\\n\t*.tar.bz2*) \\\n\t  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\\\n\t*.tar.Z*) \\\n\t  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\\\n\t*.shar.gz*) \\\n\t  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\\\n\t*.zip*) \\\n\t  unzip $(distdir).zip ;;\\\n\tesac\n\tchmod -R a-w $(distdir); chmod a+w $(distdir)\n\tmkdir $(distdir)/_build\n\tmkdir $(distdir)/_inst\n\tchmod a-w $(distdir)\n\tdc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\\\/]:[\\\\/],/,'` \\\n\t  && dc_destdir=\"$${TMPDIR-/tmp}/am-dc-$$$$/\" \\\n\t  && cd $(distdir)/_build \\\n\t  && ../configure --srcdir=.. --prefix=\"$$dc_install_base\" \\\n\t    $(DISTCHECK_CONFIGURE_FLAGS) \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) dvi \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) check \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) install \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) installcheck \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) uninstall \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir=\"$$dc_install_base\" \\\n\t        distuninstallcheck \\\n\t  && chmod -R a-w \"$$dc_install_base\" \\\n\t  && ({ \\\n\t       (cd ../.. && umask 077 && mkdir \"$$dc_destdir\") \\\n\t       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR=\"$$dc_destdir\" install \\\n\t       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR=\"$$dc_destdir\" uninstall \\\n\t       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR=\"$$dc_destdir\" \\\n\t            distuninstallcheck_dir=\"$$dc_destdir\" distuninstallcheck; \\\n\t      } || { rm -rf \"$$dc_destdir\"; exit 1; }) \\\n\t  && rm -rf \"$$dc_destdir\" \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) dist \\\n\t  && rm -rf $(DIST_ARCHIVES) \\\n\t  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck\n\t$(am__remove_distdir)\n\t@(echo \"$(distdir) archives ready for distribution: \"; \\\n\t  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \\\n\t  sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'\ndistuninstallcheck:\n\t@cd $(distuninstallcheck_dir) \\\n\t&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \\\n\t   || { echo \"ERROR: files left after uninstall:\" ; \\\n\t        if test -n \"$(DESTDIR)\"; then \\\n\t          echo \"  (check DESTDIR support)\"; \\\n\t        fi ; \\\n\t        $(distuninstallcheck_listfiles) ; \\\n\t        exit 1; } >&2\ndistcleancheck: distclean\n\t@if test '$(srcdir)' = . ; then \\\n\t  echo \"ERROR: distcleancheck can only run from a VPATH build\" ; \\\n\t  exit 1 ; \\\n\tfi\n\t@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \\\n\t  || { echo \"ERROR: files left in build directory after distclean:\" ; \\\n\t       $(distcleancheck_listfiles) ; \\\n\t       exit 1; } >&2\ncheck-am: all-am\n\t$(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)\n\t$(MAKE) $(AM_MAKEFLAGS) check-TESTS\ncheck: check-am\nall-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \\\n\t\t$(HEADERS) all-local\ninstall-binPROGRAMS: install-libLTLIBRARIES\n\ninstalldirs:\n\tfor dir in \"$(DESTDIR)$(libdir)\" \"$(DESTDIR)$(bindir)\" \"$(DESTDIR)$(bindir)\" \"$(DESTDIR)$(man1dir)\" \"$(DESTDIR)$(docdir)\" \"$(DESTDIR)$(pkgconfigdir)\" \"$(DESTDIR)$(googleincludedir)\" \"$(DESTDIR)$(googleincludedir)\"; do \\\n\t  test -z \"$$dir\" || $(mkdir_p) \"$$dir\"; \\\n\tdone\ninstall: install-am\ninstall-exec: install-exec-am\ninstall-data: install-data-am\nuninstall: uninstall-am\n\ninstall-am: all-am\n\t@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am\n\ninstallcheck: installcheck-am\ninstall-strip:\n\t$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" \\\n\t  install_sh_PROGRAM=\"$(INSTALL_STRIP_PROGRAM)\" INSTALL_STRIP_FLAG=-s \\\n\t  `test -z '$(STRIP)' || \\\n\t    echo \"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'\"` install\nmostlyclean-generic:\n\nclean-generic:\n\t-test -z \"$(CLEANFILES)\" || rm -f $(CLEANFILES)\n\ndistclean-generic:\n\t-test -z \"$(CONFIG_CLEAN_FILES)\" || rm -f $(CONFIG_CLEAN_FILES)\n\nmaintainer-clean-generic:\n\t@echo \"This command is intended for maintainers to use\"\n\t@echo \"it deletes files that may require special tools to rebuild.\"\nclean: clean-am\n\nclean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \\\n\tclean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \\\n\tmostlyclean-am\n\ndistclean: distclean-am\n\t-rm -f $(am__CONFIG_DISTCLEAN_FILES)\n\t-rm -rf ./$(DEPDIR)\n\t-rm -f Makefile\ndistclean-am: clean-am distclean-compile distclean-generic \\\n\tdistclean-hdr distclean-libtool distclean-tags\n\ndvi: dvi-am\n\ndvi-am:\n\nhtml: html-am\n\ninfo: info-am\n\ninfo-am:\n\ninstall-data-am: install-dist_docDATA install-googleincludeHEADERS \\\n\tinstall-man install-nodist_googleincludeHEADERS \\\n\tinstall-pkgconfigDATA\n\ninstall-exec-am: install-binPROGRAMS install-binSCRIPTS \\\n\tinstall-exec-local install-libLTLIBRARIES\n\ninstall-info: install-info-am\n\ninstall-man: install-man1\n\ninstallcheck-am:\n\nmaintainer-clean: maintainer-clean-am\n\t-rm -f $(am__CONFIG_DISTCLEAN_FILES)\n\t-rm -rf $(top_srcdir)/autom4te.cache\n\t-rm -rf ./$(DEPDIR)\n\t-rm -f Makefile\nmaintainer-clean-am: distclean-am maintainer-clean-generic\n\nmostlyclean: mostlyclean-am\n\nmostlyclean-am: mostlyclean-compile mostlyclean-generic \\\n\tmostlyclean-libtool\n\npdf: pdf-am\n\npdf-am:\n\nps: ps-am\n\nps-am:\n\nuninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \\\n\tuninstall-dist_docDATA uninstall-googleincludeHEADERS \\\n\tuninstall-info-am uninstall-libLTLIBRARIES uninstall-man \\\n\tuninstall-nodist_googleincludeHEADERS uninstall-pkgconfigDATA\n\nuninstall-man: uninstall-man1\n\n.PHONY: CTAGS GTAGS all all-am all-local am--refresh check check-TESTS \\\n\tcheck-am clean clean-binPROGRAMS clean-generic \\\n\tclean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \\\n\tclean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \\\n\tdist-hook dist-shar dist-tarZ dist-zip distcheck distclean \\\n\tdistclean-compile distclean-generic distclean-hdr \\\n\tdistclean-libtool distclean-tags distcleancheck distdir \\\n\tdistuninstallcheck dvi dvi-am html html-am info info-am \\\n\tinstall install-am install-binPROGRAMS install-binSCRIPTS \\\n\tinstall-data install-data-am install-dist_docDATA install-exec \\\n\tinstall-exec-am install-exec-local \\\n\tinstall-googleincludeHEADERS install-info install-info-am \\\n\tinstall-libLTLIBRARIES install-man install-man1 \\\n\tinstall-nodist_googleincludeHEADERS install-pkgconfigDATA \\\n\tinstall-strip installcheck installcheck-am installdirs \\\n\tmaintainer-clean maintainer-clean-generic mostlyclean \\\n\tmostlyclean-compile mostlyclean-generic mostlyclean-libtool \\\n\tpdf pdf-am ps ps-am tags uninstall uninstall-am \\\n\tuninstall-binPROGRAMS uninstall-binSCRIPTS \\\n\tuninstall-dist_docDATA uninstall-googleincludeHEADERS \\\n\tuninstall-info-am uninstall-libLTLIBRARIES uninstall-man \\\n\tuninstall-man1 uninstall-nodist_googleincludeHEADERS \\\n\tuninstall-pkgconfigDATA\n\n@ENABLE_FRAME_POINTERS_FALSE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@  # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS),\n@ENABLE_FRAME_POINTERS_FALSE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@  #                 before setting this.\n@WITH_STACK_TRACE_TRUE@pprof_unittest: $(top_srcdir)/src/pprof\n@WITH_STACK_TRACE_TRUE@\t$(top_srcdir)/src/pprof -test\n# This script preloads libtcmalloc, and calls two other binaries as well\n# TODO(csilvers): replace by 'if ! cmp $^ $@ >/dev/null 2>&; then ...; fi'\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@maybe_threads_unittest.sh$(EXEEXT): $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@                           $(LIBTCMALLOC_MINIMAL) \\\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@                           low_level_alloc_unittest\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\trm -f $@\n@ENABLE_STATIC_FALSE@@MINGW_FALSE@\tcp -p $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) $@\n@WITH_DEBUGALLOC_TRUE@debugallocation_test.sh$(EXEEXT): $(top_srcdir)/$(debugallocation_test_sh_SOURCES) \\\n@WITH_DEBUGALLOC_TRUE@                                  debugallocation_test\n@WITH_DEBUGALLOC_TRUE@\trm -f $@\n@WITH_DEBUGALLOC_TRUE@\tcp -p $(top_srcdir)/$(debugallocation_test_sh_SOURCES) $@\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_test.sh$(EXEEXT): $(top_srcdir)/$(sampling_test_sh_SOURCES) \\\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                           sampling_test\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\trm -f $@\n@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tcp -p $(top_srcdir)/$(sampling_test_sh_SOURCES) $@\n@WITH_HEAP_PROFILER_TRUE@heap-profiler_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) \\\n@WITH_HEAP_PROFILER_TRUE@                                    heap-profiler_unittest\n@WITH_HEAP_PROFILER_TRUE@\trm -f $@\n@WITH_HEAP_PROFILER_TRUE@\tcp -p $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) $@\n@WITH_HEAP_CHECKER_TRUE@heap-checker_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) \\\n@WITH_HEAP_CHECKER_TRUE@                                   heap-checker_unittest\n@WITH_HEAP_CHECKER_TRUE@\trm -f $@\n@WITH_HEAP_CHECKER_TRUE@\tcp -p $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) $@\n@WITH_HEAP_CHECKER_TRUE@heap-checker-death_unittest.sh$(EXEEXT): $(heap_checker_death_unittest_sh_SOURCES) \\\n@WITH_HEAP_CHECKER_TRUE@                                         heap-checker_unittest\n@WITH_HEAP_CHECKER_TRUE@\trm -f $@\n@WITH_HEAP_CHECKER_TRUE@\tcp -p $(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES) $@\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@sampling_debug_test.sh$(EXEEXT): $(top_srcdir)/$(sampling_test_sh_SOURCES) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@                                 sampling_debug_test\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\trm -f $@\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@\tcp -p $(top_srcdir)/$(sampling_test_sh_SOURCES) $@\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@heap-profiler_debug_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@                                    heap-profiler_debug_unittest\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@\trm -f $@\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@\tcp -p $(top_srcdir)/$(heap_profiler_unittest_sh_SOURCES) $@\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@heap-checker_debug_unittest.sh$(EXEEXT): $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) \\\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@                                   heap-checker_debug_unittest\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@\trm -f $@\n@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@\tcp -p $(top_srcdir)/$(heap_checker_unittest_sh_SOURCES) $@\n@WITH_CPU_PROFILER_TRUE@profiler_unittest.sh$(EXEEXT): $(top_srcdir)/$(profiler_unittest_sh_SOURCES) \\\n@WITH_CPU_PROFILER_TRUE@                               profiler1_unittest profiler2_unittest \\\n@WITH_CPU_PROFILER_TRUE@                               profiler3_unittest profiler4_unittest\n@WITH_CPU_PROFILER_TRUE@\trm -f $@\n@WITH_CPU_PROFILER_TRUE@\tcp -p $(top_srcdir)/$(profiler_unittest_sh_SOURCES) $@\n\n# Do the weakening on some exported libtcmalloc symbols.\ninstall-exec-local: all-local\nall-local: $(LIBS_TO_WEAKEN)\n\tfor la in $(LIBS_TO_WEAKEN); do lib=\".libs/`basename $$la .la`.a\"; [ ! -f \"$$lib\" ] || $(WEAKEN) \"$$lib\"; done\n\nrpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec\n\t@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}\n\ndeb: dist-gzip packages/deb.sh packages/deb/*\n\t@cd packages && ./deb.sh ${PACKAGE} ${VERSION}\n\n# I get the description and URL lines from the rpm spec. I use sed to\n# try to rewrite exec_prefix, libdir, and includedir in terms of\n# prefix, if possible.\nlibtcmalloc.pc: Makefile packages/rpm/rpm.spec\n\techo 'prefix=$(prefix)' > \"$@\".tmp\n\techo 'exec_prefix='`echo '$(exec_prefix)' | sed 's@^$(prefix)@$${prefix}@'` >> \"$@\".tmp\n\techo 'libdir='`echo '$(libdir)' | sed 's@^$(exec_prefix)@$${exec_prefix}@'` >> \"$@\".tmp\n\techo 'includedir='`echo '$(includedir)' | sed 's@^$(prefix)@$${prefix}@'` >> \"$@\".tmp\n\techo '' >> \"$@\".tmp\n\techo 'Name: $(PACKAGE)' >> \"$@\".tmp\n\techo 'Version: $(VERSION)' >> \"$@\".tmp\n\t-grep '^Summary:' packages/rpm/rpm.spec | sed s/^Summary:/Description:/ | head -n1 >> \"$@\".tmp\n\t-grep '^URL: ' packages/rpm/rpm.spec >> \"$@\".tmp\n\techo 'Requires:' >> \"$@\".tmp\n\techo 'Libs: -L$${libdir} -ltcmalloc' >> \"$@\".tmp\n\techo 'Libs.private: $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)' >> \"$@\".tmp\n\techo 'Cflags: -I$${includedir}' >> \"$@\".tmp\n\tmv -f \"$@\".tmp \"$@\"\n\n# The other versions are mostly the same.\nlibtcmalloc_minimal.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_minimal/ > \"$@\"\n\nlibtcmalloc_debug.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_debug/ > \"$@\"\n\nlibtcmalloc_minimal_debug.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-ltcmalloc_minimal_debug/ > \"$@\"\n\nlibprofiler.pc: libtcmalloc.pc\n\tcat libtcmalloc.pc | sed s/-ltcmalloc/-lprofiler/ > \"$@\"\n\nlibtool: $(LIBTOOL_DEPS)\n\t$(SHELL) ./config.status --recheck\n\n# Windows wants write permission to .vcproj files and maybe even sln files.\ndist-hook:\n\ttest -e \"$(distdir)/vsprojects\" \\\n\t   && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/\n# Tell versions [3.59,3.63) of GNU make to not export all variables.\n# Otherwise a system limit (for SysV at least) may be exceeded.\n.NOEXPORT:\n"
  },
  {
    "path": "distro/google-perftools-1.7/NEWS",
    "content": "== 04 February 2011 ==\n\nI've just released perftools 1.7\n\nI apologize for the delay since the last release; so many great new\npatches and bugfixes kept coming in (and are still coming in; I also\napologize to those folks who have to slip until the next release).  I\npicked this arbitrary time to make a cut.\n\nAmong the many new features in this release is a multi-megabyte\nreduction in the amount of tcmalloc overhead uder x86_64, improved\nperformance in the case of contention, and many many bugfixes,\nespecially architecture-specific bugfixes.  See the\n[http://google-perftools.googlecode.com/svn/tags/perftools-1.7/ChangeLog ChangeLog]\nfor full details.\n\nOne architecture-specific change of note is added comments in the\n[http://google-perftools.googlecode.com/svn/tags/perftools-1.7/README README]\nfor using tcmalloc under OS X.  I'm trying to get my head around the\nexact behavior of the OS X linker, and hope to have more improvements\nfor the next release, but I hope these notes help folks who have been\nhaving trouble with tcmalloc on OS X.\n\n*Windows users*: I've heard reports that some unittests fail on\nWindows when compiled with MSVC 10 in Release mode.  All tests pass in\nDebug mode.  I've not heard of any problems with earlier versions of\nMSVC.  I don't know if this is a problem with the runtime patching (so\nthe static patching discussed in README_windows.txt will still work),\na problem with perftools more generally, or a bug in MSVC 10.  Anyone\nwith windows expertise that can debug this, I'd be glad to hear from!\n\n\n=== 5 August 2010 ===\n\nI've just released perftools 1.6\n\nThis version also has a large number of minor changes, including\nsupport for `malloc_usable_size()` as a glibc-compatible alias to\n`malloc_size()`, the addition of SVG-based output to `pprof`, and\nexperimental support for tcmalloc large pages, which may speed up\ntcmalloc at the cost of greater memory use.  To use tcmalloc large\npages, see the\n[http://google-perftools.googlecode.com/svn/tags/perftools-1.6/INSTALL\nINSTALL file]; for all changes, see the\n[http://google-perftools.googlecode.com/svn/tags/perftools-1.6/ChangeLog\nChangeLog].\n\nOS X NOTE: improvements in the profiler unittest have turned up an OS\nX issue: in multithreaded programs, it seems that OS X often delivers\nthe profiling signal (from sigitimer()) to the main thread, even when\nit's sleeping, rather than spawned threads that are doing actual work.\nIf anyone knows details of how OS X handles SIGPROF events (from\nsetitimer) in threaded programs, and has insight into this problem,\nplease send mail to google-perftools@googlegroups.com.\n\nTo see if you're affected by this, look for profiling time that pprof\nattributes to `___semwait_signal`.  This is work being done in other\nthreads, that is being attributed to sleeping-time in the main thread.\n\n\n=== 20 January 2010 ===\n\nI've just released perftools 1.5\n\nThis version has a slew of changes, leading to somewhat faster\nperformance and improvements in portability.  It adds features like\n`ITIMER_REAL` support to the cpu profiler, and `tc_set_new_mode` to\nmimic the windows function of the same name.  Full details are in the\n[http://google-perftools.googlecode.com/svn/tags/perftools-1.5/ChangeLog\nChangeLog].\n\n\n=== 11 September 2009 ===\n\nI've just released perftools 1.4\n\nThe major change this release is the addition of a debugging malloc\nlibrary!  If you link with `libtcmalloc_debug.so` instead of\n`libtcmalloc.so` (and likewise for the `minimal` variants) you'll get\na debugging malloc, which will catch double-frees, writes to freed\ndata, `free`/`delete` and `delete`/`delete[]` mismatches, and even\n(optionally) writes past the end of an allocated block.\n\nWe plan to do more with this library in the future, including\nsupporting it on Windows, and adding the ability to use the debugging\nlibrary with your default malloc in addition to using it with\ntcmalloc.\n\nThere are also the usual complement of bug fixes, documented in the\nChangeLog, and a few minor user-tunable knobs added to components like\nthe system allocator.\n\n\n=== 9 June 2009 ===\n\nI've just released perftools 1.3\n\nLike 1.2, this has a variety of bug fixes, especially related to the\nWindows build.  One of my bugfixes is to undo the weird `ld -r` fix to\n`.a` files that I introduced in perftools 1.2: it caused problems on\ntoo many platforms.  I've reverted back to normal `.a` files.  To work\naround the original problem that prompted the `ld -r` fix, I now\nprovide `libtcmalloc_and_profiler.a`, for folks who want to link in\nboth.\n\nThe most interesting API change is that I now not only override\n`malloc`/`free`/etc, I also expose them via a unique set of symbols:\n`tc_malloc`/`tc_free`/etc.  This enables clients to write their own\nmemory wrappers that use tcmalloc:\n{{{\n   void* malloc(size_t size) { void* r = tc_malloc(size); Log(r); return r; }\n}}}\n\n\n=== 17 April 2009 ===\n\nI've just released perftools 1.2.\n\nThis is mostly a bugfix release.  The major change is internal: I have\na new system for creating packages, which allows me to create 64-bit\npackages.  (I still don't do that for perftools, because there is\nstill no great 64-bit solution, with libunwind still giving problems\nand --disable-frame-pointers not practical in every environment.)\n\nAnother interesting change involves Windows: a\n[http://code.google.com/p/google-perftools/issues/detail?id=126 new\npatch] allows users to choose to override malloc/free/etc on Windows\nrather than patching, as is done now.  This can be used to create\ncustom CRTs.\n\nMy fix for this\n[http://groups.google.com/group/google-perftools/browse_thread/thread/1ff9b50043090d9d/a59210c4206f2060?lnk=gst&q=dynamic#a59210c4206f2060\nbug involving static linking] ended up being to make libtcmalloc.a and\nlibperftools.a a big .o file, rather than a true `ar` archive.  This\nshould not yield any problems in practice -- in fact, it should be\nbetter, since the heap profiler, leak checker, and cpu profiler will\nnow all work even with the static libraries -- but if you find it\ndoes, please file a bug report.\n\nFinally, the profile_handler_unittest provided in the perftools\ntestsuite (new in this release) is failing on FreeBSD.  The end-to-end\ntest that uses the profile-handler is passing, so I suspect the\nproblem may be with the test, not the perftools code itself.  However,\nI do not know enough about how itimers work on FreeBSD to be able to\ndebug it.  If you can figure it out, please let me know!\n\n=== 11 March 2009 ===\n\nI've just released perftools 1.1!\n\nIt has many changes since perftools 1.0 including\n\n  * Faster performance due to dynamically sized thread caches\n  * Better heap-sampling for more realistic profiles\n  * Improved support on Windows (MSVC 7.1 and cygwin)\n  * Better stacktraces in linux (using VDSO)\n  * Many bug fixes and feature requests\n\nNote: if you use the CPU-profiler with applications that fork without\ndoing an exec right afterwards, please see the README.  Recent testing\nhas shown that profiles are unreliable in that case.  The problem has\nexisted since the first release of perftools.  We expect to have a fix\nfor perftools 1.2.  For more details, see\n[http://code.google.com/p/google-perftools/issues/detail?id=105 issue 105].\n\nEveryone who uses perftools 1.0 is encouraged to upgrade to perftools\n1.1.  If you see any problems with the new release, please file a bug\nreport at http://code.google.com/p/google-perftools/issues/list.\n\nEnjoy!\n"
  },
  {
    "path": "distro/google-perftools-1.7/README",
    "content": "IMPORTANT NOTE FOR 64-BIT USERS\n-------------------------------\nThere are known issues with some perftools functionality on x86_64\nsystems.  See 64-BIT ISSUES, below.\n\n\nTCMALLOC\n--------\nJust link in -ltcmalloc or -ltcmalloc_minimal to get the advantages of\ntcmalloc -- a replacement for malloc and new.  See below for some\nenvironment variables you can use with tcmalloc, as well.\n\ntcmalloc functionality is available on all systems we've tested; see\nINSTALL for more details.  See README_windows.txt for instructions on\nusing tcmalloc on Windows.\n\nNOTE: When compiling with programs with gcc, that you plan to link\nwith libtcmalloc, it's safest to pass in the flags\n\n -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free\n\nwhen compiling.  gcc makes some optimizations assuming it is using its\nown, built-in malloc; that assumption obviously isn't true with\ntcmalloc.  In practice, we haven't seen any problems with this, but\nthe expected risk is highest for users who register their own malloc\nhooks with tcmalloc (using google/malloc_hook.h).  The risk is lowest\nfor folks who use tcmalloc_minimal (or, of course, who pass in the\nabove flags :-) ).\n\n\nHEAP PROFILER\n-------------\nSee doc/heap-profiler.html for information about how to use tcmalloc's\nheap profiler and analyze its output.\n\nAs a quick-start, do the following after installing this package:\n\n1) Link your executable with -ltcmalloc\n2) Run your executable with the HEAPPROFILE environment var set:\n     $ HEAPPROFILE=/tmp/heapprof <path/to/binary> [binary args]\n3) Run pprof to analyze the heap usage\n     $ pprof <path/to/binary> /tmp/heapprof.0045.heap  # run 'ls' to see options\n     $ pprof --gv <path/to/binary> /tmp/heapprof.0045.heap\n\nYou can also use LD_PRELOAD to heap-profile an executable that you\ndidn't compile.\n\nThere are other environment variables, besides HEAPPROFILE, you can\nset to adjust the heap-profiler behavior; c.f. \"ENVIRONMENT VARIABLES\"\nbelow.\n\nThe heap profiler is available on all unix-based systems we've tested;\nsee INSTALL for more details.  It is not currently available on Windows.\n\n\nHEAP CHECKER\n------------\nSee doc/heap-checker.html for information about how to use tcmalloc's\nheap checker.\n\nIn order to catch all heap leaks, tcmalloc must be linked *last* into\nyour executable.  The heap checker may mischaracterize some memory\naccesses in libraries listed after it on the link line.  For instance,\nit may report these libraries as leaking memory when they're not.\n(See the source code for more details.)\n\nHere's a quick-start for how to use:\n\nAs a quick-start, do the following after installing this package:\n\n1) Link your executable with -ltcmalloc\n2) Run your executable with the HEAPCHECK environment var set:\n     $ HEAPCHECK=1 <path/to/binary> [binary args]\n\nOther values for HEAPCHECK: normal (equivalent to \"1\"), strict, draconian\n\nYou can also use LD_PRELOAD to heap-check an executable that you\ndidn't compile.\n\nThe heap checker is only available on Linux at this time; see INSTALL\nfor more details.\n\n\nCPU PROFILER\n------------\nSee doc/cpu-profiler.html for information about how to use the CPU\nprofiler and analyze its output.\n\nAs a quick-start, do the following after installing this package:\n\n1) Link your executable with -lprofiler\n2) Run your executable with the CPUPROFILE environment var set:\n     $ CPUPROFILE=/tmp/prof.out <path/to/binary> [binary args]\n3) Run pprof to analyze the CPU usage\n     $ pprof <path/to/binary> /tmp/prof.out      # -pg-like text output\n     $ pprof --gv <path/to/binary> /tmp/prof.out # really cool graphical output\n\nThere are other environment variables, besides CPUPROFILE, you can set\nto adjust the cpu-profiler behavior; cf \"ENVIRONMENT VARIABLES\" below.\n\nThe CPU profiler is available on all unix-based systems we've tested;\nsee INSTALL for more details.  It is not currently available on Windows.\n\nNOTE: CPU profiling doesn't work after fork (unless you immediately\n      do an exec()-like call afterwards).  Furthermore, if you do\n      fork, and the child calls exit(), it may corrupt the profile\n      data.  You can use _exit() to work around this.  We hope to have\n      a fix for both problems in the next release of perftools\n      (hopefully perftools 1.2).\n\n\nEVERYTHING IN ONE\n-----------------\nIf you want the CPU profiler, heap profiler, and heap leak-checker to\nall be available for your application, you can do:\n   gcc -o myapp ... -lprofiler -ltcmalloc\n\nHowever, if you have a reason to use the static versions of the\nlibrary, this two-library linking won't work:\n   gcc -o myapp ... /usr/lib/libprofiler.a /usr/lib/libtcmalloc.a  # errors!\n\nInstead, use the special libtcmalloc_and_profiler library, which we\nmake for just this purpose:\n   gcc -o myapp ... /usr/lib/libtcmalloc_and_profiler.a\n\n\nENVIRONMENT VARIABLES\n---------------------\nThe cpu profiler, heap checker, and heap profiler will lie dormant,\nusing no memory or CPU, until you turn them on.  (Thus, there's no\nharm in linking -lprofiler into every application, and also -ltcmalloc\nassuming you're ok using the non-libc malloc library.)\n\nThe easiest way to turn them on is by setting the appropriate\nenvironment variables.  We have several variables that let you\nenable/disable features as well as tweak parameters.\n\nHere are some of the most important variables:\n\nHEAPPROFILE=<pre> -- turns on heap profiling and dumps data using this prefix\nHEAPCHECK=<type>  -- turns on heap checking with strictness 'type'\nCPUPROFILE=<file> -- turns on cpu profiling and dumps data to this file.\nPROFILESELECTED=1 -- if set, cpu-profiler will only profile regions of code\n                     surrounded with ProfilerEnable()/ProfilerDisable().\nPROFILEFREQUENCY=x-- how many interrupts/second the cpu-profiler samples.\n\nTCMALLOC_DEBUG=<level> -- the higher level, the more messages malloc emits\nMALLOCSTATS=<level>    -- prints memory-use stats at program-exit\n\nFor a full list of variables, see the documentation pages:\n   doc/cpuprofile.html\n   doc/heapprofile.html\n   doc/heap_checker.html\n\n\nCOMPILING ON NON-LINUX SYSTEMS\n------------------------------\n\nPerftools was developed and tested on x86 Linux systems, and it works\nin its full generality only on those systems.  However, we've\nsuccessfully ported much of the tcmalloc library to FreeBSD, Solaris\nx86, and Darwin (Mac OS X) x86 and ppc; and we've ported the basic\nfunctionality in tcmalloc_minimal to Windows.  See INSTALL for details.\nSee README_windows.txt for details on the Windows port.\n\n\nPERFORMANCE\n-----------\n\nIf you're interested in some third-party comparisons of tcmalloc to\nother malloc libraries, here are a few web pages that have been\nbrought to our attention.  The first discusses the effect of using\nvarious malloc libraries on OpenLDAP.  The second compares tcmalloc to\nwin32's malloc.\n  http://www.highlandsun.com/hyc/malloc/\n  http://gaiacrtn.free.fr/articles/win32perftools.html\n\nIt's possible to build tcmalloc in a way that trades off faster\nperformance (particularly for deletes) at the cost of more memory\nfragmentation (that is, more unusable memory on your system).  See the\nINSTALL file for details.\n\n\nOLD SYSTEM ISSUES\n-----------------\n\nWhen compiling perftools on some old systems, like RedHat 8, you may\nget an error like this:\n    ___tls_get_addr: symbol not found\n\nThis means that you have a system where some parts are updated enough\nto support Thread Local Storage, but others are not.  The perftools\nconfigure script can't always detect this kind of case, leading to\nthat error.  To fix it, just comment out (or delete) the line\n   #define HAVE_TLS 1\nin your config.h file before building.\n\n\nOS X ISSUES\n-----------\n\nYou may need to set the environment variable DYLD_FORCE_FLAT_NAMESPACE\nto use perftools with OS X.  Because of how OS X does symbol binding,\nlibc routines will use libc malloc even when the binary is linked with\n-ltcmalloc.  This is not usually a problem, but becomes one if the\napplication is responsible for freeing that memory: the application\nwill use tcmalloc's free() to try to free memory allocated with libc's\nmalloc(), which will cause no end of confusion.\n\nOne (or both) of these workaround may fix the problem:\n    DYLD_FORCE_FLAT_NAMESPACE=1 myapp\n    DYLD_INSERT_LIBRARIES=path/to/libtcmalloc.dylib myapp\n\nThe best solution may depend on the version of OS X being used.\nNeither solution is likely to work if you dlopen() libraries from\nwithin your application.  If you have any experience with this, we'd\nappreciate you sharing it at\n   http://groups.google.com/group/google-perftools\n\n\n64-BIT ISSUES\n-------------\n\nThere are two issues that can cause program hangs or crashes on x86_64\n64-bit systems, which use the libunwind library to get stack-traces.\nNeither issue should affect the core tcmalloc library; they both\naffect the perftools tools such as cpu-profiler, heap-checker, and\nheap-profiler.\n\n1) Some libc's -- at least glibc 2.4 on x86_64 -- have a bug where the\nlibc function dl_iterate_phdr() acquires its locks in the wrong\norder.  This bug should not affect tcmalloc, but may cause occasional\ndeadlock with the cpu-profiler, heap-profiler, and heap-checker.\nIts likeliness increases the more dlopen() commands an executable has.\nMost executables don't have any, though several library routines like\ngetgrgid() call dlopen() behind the scenes.\n\n2) On x86-64 64-bit systems, while tcmalloc itself works fine, the\ncpu-profiler tool is unreliable: it will sometimes work, but sometimes\ncause a segfault.  I'll explain the problem first, and then some\nworkarounds.\n\nNote that this only affects the cpu-profiler, which is a\ngoogle-perftools feature you must turn on manually by setting the\nCPUPROFILE environment variable.  If you do not turn on cpu-profiling,\nyou shouldn't see any crashes due to perftools.\n\nThe gory details: The underlying problem is in the backtrace()\nfunction, which is a built-in function in libc.\nBacktracing is fairly straightforward in the normal case, but can run\ninto problems when having to backtrace across a signal frame.\nUnfortunately, the cpu-profiler uses signals in order to register a\nprofiling event, so every backtrace that the profiler does crosses a\nsignal frame.\n\nIn our experience, the only time there is trouble is when the signal\nfires in the middle of pthread_mutex_lock.  pthread_mutex_lock is\ncalled quite a bit from system libraries, particularly at program\nstartup and when creating a new thread.\n\nThe solution: The dwarf debugging format has support for 'cfi\nannotations', which make it easy to recognize a signal frame.  Some OS\ndistributions, such as Fedora and gentoo 2007.0, already have added\ncfi annotations to their libc.  A future version of libunwind should\nrecognize these annotations; these systems should not see any\ncrashses.\n\nWorkarounds: If you see problems with crashes when running the\ncpu-profiler, consider inserting ProfilerStart()/ProfilerStop() into\nyour code, rather than setting CPUPROFILE.  This will profile only\nthose sections of the codebase.  Though we haven't done much testing,\nin theory this should reduce the chance of crashes by limiting the\nsignal generation to only a small part of the codebase.  Ideally, you\nwould not use ProfilerStart()/ProfilerStop() around code that spawns\nnew threads, or is otherwise likely to cause a call to\npthread_mutex_lock!\n\n---\n11 January 2011\n"
  },
  {
    "path": "distro/google-perftools-1.7/README_windows.txt",
    "content": "--- COMPILING\r\n\r\nThis project has begun being ported to Windows.  A working solution\r\nfile exists in this directory:\r\n    google-perftools.sln\r\n\r\nYou can load this solution file into either VC++ 7.1 (Visual Studio\r\n2003) or VC++ 8.0 (Visual Studio 2005) -- in the latter case, it will\r\nautomatically convert the files to the latest format for you.\r\n\r\nWhen you build the solution, it will create a number of unittests,\r\nwhich you can run by hand (or, more easily, under the Visual Studio\r\ndebugger) to make sure everything is working properly on your system.\r\nThe binaries will end up in a directory called \"debug\" or \"release\" in\r\nthe top-level directory (next to the .sln file).  It will also create\r\ntwo binaries, nm-pdb and addr2line-pdb, which you should install in\r\nthe same directory you install the 'pprof' perl script.\r\n\r\nI don't know very much about how to install DLLs on Windows, so you'll\r\nhave to figure out that part for yourself.  If you choose to just\r\nre-use the existing .sln, make sure you set the IncludeDir's\r\nappropriately!  Look at the properties for libtcmalloc_minimal.dll.\r\n\r\nNote that these systems are set to build in Debug mode by default.\r\nYou may want to change them to Release mode.\r\n\r\nTo use tcmalloc_minimal in your own projects, you should only need to\r\nbuild the dll and install it someplace, so you can link it into\r\nfurther binaries.  To use the dll, you need to add the following to\r\nthe linker line of your executable:\r\n   \"libtcmalloc_minimal.lib\" /INCLUDE:\"__tcmalloc\" \r\n\r\nHere is how to accomplish this in Visual Studio 2005 (VC8):\r\n\r\n1) Have your executable depend on the tcmalloc library by selecting\r\n   \"Project Dependencies...\" from the \"Project\" menu.  Your executable\r\n   should depend on \"libtcmalloc_minimal\".\r\n\r\n2) Have your executable depend on a tcmalloc symbol -- this is\r\n   necessary so the linker doesn't \"optimize out\" the libtcmalloc\r\n   dependency -- by right-clicking on your executable's project (in\r\n   the solution explorer), selecting Properties from the pull-down\r\n   menu, then selecting \"Configuration Properties\" -> \"Linker\" ->\r\n   \"Input\".  Then, in the \"Force Symbol References\" field, enter the\r\n   text \"__tcmalloc\" (without the quotes).  Be sure to do this for both\r\n   debug and release modes!\r\n\r\nYou can also link tcmalloc code in statically -- see the example\r\nproject tcmalloc_minimal_unittest-static, which does this.  For this\r\nto work, you'll need to add \"/D PERFTOOLS_DLL_DECL=\" to the compile\r\nline of every perftools .cc file.  You do not need to depend on the\r\ntcmalloc symbol in this case (that is, you don't need to do either\r\nstep 1 or step 2 from above).\r\n\r\nAn alternative to all the above is to statically link your application\r\nwith libc, and then replace its malloc with tcmalloc.  This allows you\r\nto just build and link your program normally; the tcmalloc support\r\ncomes in a post-processing step.  This is more reliable than the above\r\ntechnique (which depends on run-time patching, which is inherently\r\nfragile), though more work to set up.  For details, see\r\nhttps://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b\r\n\r\n\r\n--- THE HEAP-PROFILER\r\n\r\nThe heap-profiler has had a preliminary port to Windows.  It has not\r\nbeen well tested, and probably does not work at all when Frame Pointer\r\nOptimization (FPO) is enabled -- that is, in release mode.  The other\r\nfeatures of perftools, such as the cpu-profiler and leak-checker, have\r\nnot yet been ported to Windows at all.\r\n\r\n\r\n--- ISSUES\r\n\r\nNOTE FOR WIN2K USERS: According to reports\r\n(http://code.google.com/p/google-perftools/issues/detail?id=127)\r\nthe stack-tracing necessary for the heap-profiler does not work on\r\nWin2K.  The best workaround is, if you are building on a Win2k system\r\nis to add \"/D NO_TCMALLOC_SAMPLES=\" to your build, to turn off the\r\nstack-tracing.  You will not be able to use the heap-profiler if you\r\ndo this.\r\n\r\nNOTE ON _MSIZE and _RECALLOC: The tcmalloc version of _msize returns\r\nthe size of the region tcmalloc allocated for you -- which is at least\r\nas many bytes you asked for, but may be more.  (btw, these *are* bytes\r\nyou own, even if you didn't ask for all of them, so it's correct code\r\nto access all of them if you want.)  Unfortunately, the Windows CRT\r\n_recalloc() routine assumes that _msize returns exactly as many bytes\r\nas were requested.  As a result, _recalloc() may not zero out new\r\nbytes correctly.  IT'S SAFEST NOT TO USE _RECALLOC WITH TCMALLOC.\r\n_recalloc() is a tricky routine to use in any case (it's not safe to\r\nuse with realloc, for instance).\r\n\r\n\r\nI have little experience with Windows programming, so there may be\r\nbetter ways to set this up than I've done!  If you run across any\r\nproblems, please post to the google-perftools Google Group, or report\r\nthem on the google-perftools Google Code site:\r\n   http://groups.google.com/group/google-perftools\r\n   http://code.google.com/p/google-perftools/issues/list\r\n\r\n-- craig\r\n\r\nLast modified: 3 February 2010\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/TODO",
    "content": "HEAP PROFILER\n\n1) Fix heap profiling under all STLs\n   * Find out how to force non-glibc STL libraries to call new() and\n     delete() for every allocation / deallocation.\n   * Make heap profiler ignore STL-internal allocations for those\n     libraries under which we cannot profile accurately, so we only\n     see object-level leaks.\n2) Remove dependency on tcmalloc?\n3) Port to non-linux O/Ses (right now code uses /proc for library info)\n4) Port to non-x86 architectures (locking code in spinlock is x86-specific)\n5) Port to C?\n6) Figure out how to get setenv() to work properly before main() in\n   shared libaries, and get rid of the profile-naming hack once we\n   do.  (See HeapProfiler::Init().)\n\n\nHEAP CHECKER\n\n1) Remove requirement that the heap-checker must be linked last into\n   an application (hard! -- it needs its global constructor to run\n   first)\n\nTCMALLOC\n\n1) Implement mallinfo/mallopt\n2) Have tcmalloc work correctly when libpthread is not linked in\n   (currently working for glibc, could use other libc's too)\n3) Return memory to the system when requirements drop\n4) Explore coloring allocated objects to avoid cache conflicts\n5) Explore biasing reclamation to larger addresses\n6) Add contention stats to a synchronization.cc (can do spinlocks,\n   but threads? -- may have to provide our own thread implementation)\n\nCPU PROFILER\n\n1) Figure out how to get setenv() to work properly before main() in\n   shared libaries(), and get rid of the profile-naming hack once we\n   do.  (See Profiler::GetUniquePathFromEnv().)\n2) Resolve crashing problems on x86_64 (see README)\n\nSTACKTRACE\n\n1) Remove dependency on linux/x86\n\n---\n11 March 2008\n"
  },
  {
    "path": "distro/google-perftools-1.7/aclocal.m4",
    "content": "# generated automatically by aclocal 1.9.6 -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,\n# 2005  Free Software Foundation, Inc.\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY, to the extent permitted by law; without\n# even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n# PARTICULAR PURPOSE.\n\n# Copyright (C) 2002, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# AM_AUTOMAKE_VERSION(VERSION)\n# ----------------------------\n# Automake X.Y traces this macro to ensure aclocal.m4 has been\n# generated from the m4 files accompanying Automake X.Y.\nAC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version=\"1.9\"])\n\n# AM_SET_CURRENT_AUTOMAKE_VERSION\n# -------------------------------\n# Call AM_AUTOMAKE_VERSION so it can be traced.\n# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.\nAC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],\n\t [AM_AUTOMAKE_VERSION([1.9.6])])\n\n# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-\n\n# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets\n# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to\n# `$srcdir', `$srcdir/..', or `$srcdir/../..'.\n#\n# Of course, Automake must honor this variable whenever it calls a\n# tool from the auxiliary directory.  The problem is that $srcdir (and\n# therefore $ac_aux_dir as well) can be either absolute or relative,\n# depending on how configure is run.  This is pretty annoying, since\n# it makes $ac_aux_dir quite unusable in subdirectories: in the top\n# source directory, any form will work fine, but in subdirectories a\n# relative path needs to be adjusted first.\n#\n# $ac_aux_dir/missing\n#    fails when called from a subdirectory if $ac_aux_dir is relative\n# $top_srcdir/$ac_aux_dir/missing\n#    fails if $ac_aux_dir is absolute,\n#    fails when called from a subdirectory in a VPATH build with\n#          a relative $ac_aux_dir\n#\n# The reason of the latter failure is that $top_srcdir and $ac_aux_dir\n# are both prefixed by $srcdir.  In an in-source build this is usually\n# harmless because $srcdir is `.', but things will broke when you\n# start a VPATH build or use an absolute $srcdir.\n#\n# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,\n# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:\n#   am_aux_dir='\\$(top_srcdir)/'`expr \"$ac_aux_dir\" : \"$srcdir//*\\(.*\\)\"`\n# and then we would define $MISSING as\n#   MISSING=\"\\${SHELL} $am_aux_dir/missing\"\n# This will work as long as MISSING is not called from configure, because\n# unfortunately $(top_srcdir) has no meaning in configure.\n# However there are other variables, like CC, which are often used in\n# configure, and could therefore not use this \"fixed\" $ac_aux_dir.\n#\n# Another solution, used here, is to always expand $ac_aux_dir to an\n# absolute PATH.  The drawback is that using absolute paths prevent a\n# configured tree to be moved without reconfiguration.\n\nAC_DEFUN([AM_AUX_DIR_EXPAND],\n[dnl Rely on autoconf to set up CDPATH properly.\nAC_PREREQ([2.50])dnl\n# expand $ac_aux_dir to an absolute path\nam_aux_dir=`cd $ac_aux_dir && pwd`\n])\n\n# AM_CONDITIONAL                                            -*- Autoconf -*-\n\n# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 7\n\n# AM_CONDITIONAL(NAME, SHELL-CONDITION)\n# -------------------------------------\n# Define a conditional.\nAC_DEFUN([AM_CONDITIONAL],\n[AC_PREREQ(2.52)dnl\n ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],\n\t[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl\nAC_SUBST([$1_TRUE])\nAC_SUBST([$1_FALSE])\nif $2; then\n  $1_TRUE=\n  $1_FALSE='#'\nelse\n  $1_TRUE='#'\n  $1_FALSE=\nfi\nAC_CONFIG_COMMANDS_PRE(\n[if test -z \"${$1_TRUE}\" && test -z \"${$1_FALSE}\"; then\n  AC_MSG_ERROR([[conditional \"$1\" was never defined.\nUsually this means the macro was only invoked conditionally.]])\nfi])])\n\n\n# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 8\n\n# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be\n# written in clear, in which case automake, when reading aclocal.m4,\n# will think it sees a *use*, and therefore will trigger all it's\n# C support machinery.  Also note that it means that autoscan, seeing\n# CC etc. in the Makefile, will ask for an AC_PROG_CC use...\n\n\n# _AM_DEPENDENCIES(NAME)\n# ----------------------\n# See how the compiler implements dependency checking.\n# NAME is \"CC\", \"CXX\", \"GCJ\", or \"OBJC\".\n# We try a few techniques and use that to set a single cache variable.\n#\n# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was\n# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular\n# dependency, and given that the user is not expected to run this macro,\n# just rely on AC_PROG_CC.\nAC_DEFUN([_AM_DEPENDENCIES],\n[AC_REQUIRE([AM_SET_DEPDIR])dnl\nAC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl\nAC_REQUIRE([AM_MAKE_INCLUDE])dnl\nAC_REQUIRE([AM_DEP_TRACK])dnl\n\nifelse([$1], CC,   [depcc=\"$CC\"   am_compiler_list=],\n       [$1], CXX,  [depcc=\"$CXX\"  am_compiler_list=],\n       [$1], OBJC, [depcc=\"$OBJC\" am_compiler_list='gcc3 gcc'],\n       [$1], GCJ,  [depcc=\"$GCJ\"  am_compiler_list='gcc3 gcc'],\n                   [depcc=\"$$1\"   am_compiler_list=])\n\nAC_CACHE_CHECK([dependency style of $depcc],\n               [am_cv_$1_dependencies_compiler_type],\n[if test -z \"$AMDEP_TRUE\" && test -f \"$am_depcomp\"; then\n  # We make a subdir and do the tests there.  Otherwise we can end up\n  # making bogus files that we don't know about and never remove.  For\n  # instance it was reported that on HP-UX the gcc test will end up\n  # making a dummy file named `D' -- because `-MD' means `put the output\n  # in D'.\n  mkdir conftest.dir\n  # Copy depcomp to subdir because otherwise we won't find it if we're\n  # using a relative directory.\n  cp \"$am_depcomp\" conftest.dir\n  cd conftest.dir\n  # We will build objects and dependencies in a subdirectory because\n  # it helps to detect inapplicable dependency modes.  For instance\n  # both Tru64's cc and ICC support -MD to output dependencies as a\n  # side effect of compilation, but ICC will put the dependencies in\n  # the current directory while Tru64 will put them in the object\n  # directory.\n  mkdir sub\n\n  am_cv_$1_dependencies_compiler_type=none\n  if test \"$am_compiler_list\" = \"\"; then\n     am_compiler_list=`sed -n ['s/^#*\\([a-zA-Z0-9]*\\))$/\\1/p'] < ./depcomp`\n  fi\n  for depmode in $am_compiler_list; do\n    # Setup a source with many dependencies, because some compilers\n    # like to wrap large dependency lists on column 80 (with \\), and\n    # we should not choose a depcomp mode which is confused by this.\n    #\n    # We need to recreate these files for each test, as the compiler may\n    # overwrite some of them when testing with obscure command lines.\n    # This happens at least with the AIX C compiler.\n    : > sub/conftest.c\n    for i in 1 2 3 4 5 6; do\n      echo '#include \"conftst'$i'.h\"' >> sub/conftest.c\n      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with\n      # Solaris 8's {/usr,}/bin/sh.\n      touch sub/conftst$i.h\n    done\n    echo \"${am__include} ${am__quote}sub/conftest.Po${am__quote}\" > confmf\n\n    case $depmode in\n    nosideeffect)\n      # after this tag, mechanisms are not by side-effect, so they'll\n      # only be used when explicitly requested\n      if test \"x$enable_dependency_tracking\" = xyes; then\n\tcontinue\n      else\n\tbreak\n      fi\n      ;;\n    none) break ;;\n    esac\n    # We check with `-c' and `-o' for the sake of the \"dashmstdout\"\n    # mode.  It turns out that the SunPro C++ compiler does not properly\n    # handle `-M -o', and we need to detect this.\n    if depmode=$depmode \\\n       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&\n       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then\n      # icc doesn't choke on unknown options, it will just issue warnings\n      # or remarks (even with -Werror).  So we grep stderr for any message\n      # that says an option was ignored or not supported.\n      # When given -MP, icc 7.0 and 7.1 complain thusly:\n      #   icc: Command line warning: ignoring option '-M'; no argument required\n      # The diagnosis changed in icc 8.0:\n      #   icc: Command line remark: option '-MP' not supported\n      if (grep 'ignoring option' conftest.err ||\n          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else\n        am_cv_$1_dependencies_compiler_type=$depmode\n        break\n      fi\n    fi\n  done\n\n  cd ..\n  rm -rf conftest.dir\nelse\n  am_cv_$1_dependencies_compiler_type=none\nfi\n])\nAC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])\nAM_CONDITIONAL([am__fastdep$1], [\n  test \"x$enable_dependency_tracking\" != xno \\\n  && test \"$am_cv_$1_dependencies_compiler_type\" = gcc3])\n])\n\n\n# AM_SET_DEPDIR\n# -------------\n# Choose a directory name for dependency files.\n# This macro is AC_REQUIREd in _AM_DEPENDENCIES\nAC_DEFUN([AM_SET_DEPDIR],\n[AC_REQUIRE([AM_SET_LEADING_DOT])dnl\nAC_SUBST([DEPDIR], [\"${am__leading_dot}deps\"])dnl\n])\n\n\n# AM_DEP_TRACK\n# ------------\nAC_DEFUN([AM_DEP_TRACK],\n[AC_ARG_ENABLE(dependency-tracking,\n[  --disable-dependency-tracking  speeds up one-time build\n  --enable-dependency-tracking   do not reject slow dependency extractors])\nif test \"x$enable_dependency_tracking\" != xno; then\n  am_depcomp=\"$ac_aux_dir/depcomp\"\n  AMDEPBACKSLASH='\\'\nfi\nAM_CONDITIONAL([AMDEP], [test \"x$enable_dependency_tracking\" != xno])\nAC_SUBST([AMDEPBACKSLASH])\n])\n\n# Generate code to set up dependency tracking.              -*- Autoconf -*-\n\n# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n#serial 3\n\n# _AM_OUTPUT_DEPENDENCY_COMMANDS\n# ------------------------------\nAC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],\n[for mf in $CONFIG_FILES; do\n  # Strip MF so we end up with the name of the file.\n  mf=`echo \"$mf\" | sed -e 's/:.*$//'`\n  # Check whether this is an Automake generated Makefile or not.\n  # We used to match only the files named `Makefile.in', but\n  # some people rename them; so instead we look at the file content.\n  # Grep'ing the first line is not enough: some people post-process\n  # each Makefile.in and add a new line on top of each file to say so.\n  # So let's grep whole file.\n  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then\n    dirpart=`AS_DIRNAME(\"$mf\")`\n  else\n    continue\n  fi\n  # Extract the definition of DEPDIR, am__include, and am__quote\n  # from the Makefile without running `make'.\n  DEPDIR=`sed -n 's/^DEPDIR = //p' < \"$mf\"`\n  test -z \"$DEPDIR\" && continue\n  am__include=`sed -n 's/^am__include = //p' < \"$mf\"`\n  test -z \"am__include\" && continue\n  am__quote=`sed -n 's/^am__quote = //p' < \"$mf\"`\n  # When using ansi2knr, U may be empty or an underscore; expand it\n  U=`sed -n 's/^U = //p' < \"$mf\"`\n  # Find all dependency output files, they are included files with\n  # $(DEPDIR) in their names.  We invoke sed twice because it is the\n  # simplest approach to changing $(DEPDIR) to its actual value in the\n  # expansion.\n  for file in `sed -n \"\n    s/^$am__include $am__quote\\(.*(DEPDIR).*\\)$am__quote\"'$/\\1/p' <\"$mf\" | \\\n       sed -e 's/\\$(DEPDIR)/'\"$DEPDIR\"'/g' -e 's/\\$U/'\"$U\"'/g'`; do\n    # Make sure the directory exists.\n    test -f \"$dirpart/$file\" && continue\n    fdir=`AS_DIRNAME([\"$file\"])`\n    AS_MKDIR_P([$dirpart/$fdir])\n    # echo \"creating $dirpart/$file\"\n    echo '# dummy' > \"$dirpart/$file\"\n  done\ndone\n])# _AM_OUTPUT_DEPENDENCY_COMMANDS\n\n\n# AM_OUTPUT_DEPENDENCY_COMMANDS\n# -----------------------------\n# This macro should only be invoked once -- use via AC_REQUIRE.\n#\n# This code is only required when automatic dependency tracking\n# is enabled.  FIXME.  This creates each `.P' file that we will\n# need in order to bootstrap the dependency handling code.\nAC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],\n[AC_CONFIG_COMMANDS([depfiles],\n     [test x\"$AMDEP_TRUE\" != x\"\" || _AM_OUTPUT_DEPENDENCY_COMMANDS],\n     [AMDEP_TRUE=\"$AMDEP_TRUE\" ac_aux_dir=\"$ac_aux_dir\"])\n])\n\n# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 8\n\n# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.\nAU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])\n\n# Do all the work for Automake.                             -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 12\n\n# This macro actually does too much.  Some checks are only needed if\n# your package does certain things.  But this isn't really a big deal.\n\n# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])\n# AM_INIT_AUTOMAKE([OPTIONS])\n# -----------------------------------------------\n# The call with PACKAGE and VERSION arguments is the old style\n# call (pre autoconf-2.50), which is being phased out.  PACKAGE\n# and VERSION should now be passed to AC_INIT and removed from\n# the call to AM_INIT_AUTOMAKE.\n# We support both call styles for the transition.  After\n# the next Automake release, Autoconf can make the AC_INIT\n# arguments mandatory, and then we can depend on a new Autoconf\n# release and drop the old call support.\nAC_DEFUN([AM_INIT_AUTOMAKE],\n[AC_PREREQ([2.58])dnl\ndnl Autoconf wants to disallow AM_ names.  We explicitly allow\ndnl the ones we care about.\nm4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl\nAC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl\nAC_REQUIRE([AC_PROG_INSTALL])dnl\n# test to see if srcdir already configured\nif test \"`cd $srcdir && pwd`\" != \"`pwd`\" &&\n   test -f $srcdir/config.status; then\n  AC_MSG_ERROR([source directory already configured; run \"make distclean\" there first])\nfi\n\n# test whether we have cygpath\nif test -z \"$CYGPATH_W\"; then\n  if (cygpath --version) >/dev/null 2>/dev/null; then\n    CYGPATH_W='cygpath -w'\n  else\n    CYGPATH_W=echo\n  fi\nfi\nAC_SUBST([CYGPATH_W])\n\n# Define the identity of the package.\ndnl Distinguish between old-style and new-style calls.\nm4_ifval([$2],\n[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl\n AC_SUBST([PACKAGE], [$1])dnl\n AC_SUBST([VERSION], [$2])],\n[_AM_SET_OPTIONS([$1])dnl\n AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl\n AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl\n\n_AM_IF_OPTION([no-define],,\n[AC_DEFINE_UNQUOTED(PACKAGE, \"$PACKAGE\", [Name of package])\n AC_DEFINE_UNQUOTED(VERSION, \"$VERSION\", [Version number of package])])dnl\n\n# Some tools Automake needs.\nAC_REQUIRE([AM_SANITY_CHECK])dnl\nAC_REQUIRE([AC_ARG_PROGRAM])dnl\nAM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})\nAM_MISSING_PROG(AUTOCONF, autoconf)\nAM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})\nAM_MISSING_PROG(AUTOHEADER, autoheader)\nAM_MISSING_PROG(MAKEINFO, makeinfo)\nAM_PROG_INSTALL_SH\nAM_PROG_INSTALL_STRIP\nAC_REQUIRE([AM_PROG_MKDIR_P])dnl\n# We need awk for the \"check\" target.  The system \"awk\" is bad on\n# some platforms.\nAC_REQUIRE([AC_PROG_AWK])dnl\nAC_REQUIRE([AC_PROG_MAKE_SET])dnl\nAC_REQUIRE([AM_SET_LEADING_DOT])dnl\n_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],\n              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],\n\t      \t\t     [_AM_PROG_TAR([v7])])])\n_AM_IF_OPTION([no-dependencies],,\n[AC_PROVIDE_IFELSE([AC_PROG_CC],\n                  [_AM_DEPENDENCIES(CC)],\n                  [define([AC_PROG_CC],\n                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl\nAC_PROVIDE_IFELSE([AC_PROG_CXX],\n                  [_AM_DEPENDENCIES(CXX)],\n                  [define([AC_PROG_CXX],\n                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl\n])\n])\n\n\n# When config.status generates a header, we must update the stamp-h file.\n# This file resides in the same directory as the config header\n# that is generated.  The stamp files are numbered to have different names.\n\n# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the\n# loop where config.status creates the headers, so we can generate\n# our stamp files there.\nAC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],\n[# Compute $1's index in $config_headers.\n_am_stamp_count=1\nfor _am_header in $config_headers :; do\n  case $_am_header in\n    $1 | $1:* )\n      break ;;\n    * )\n      _am_stamp_count=`expr $_am_stamp_count + 1` ;;\n  esac\ndone\necho \"timestamp for $1\" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])\n\n# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# AM_PROG_INSTALL_SH\n# ------------------\n# Define $install_sh.\nAC_DEFUN([AM_PROG_INSTALL_SH],\n[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl\ninstall_sh=${install_sh-\"$am_aux_dir/install-sh\"}\nAC_SUBST(install_sh)])\n\n# Copyright (C) 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 2\n\n# Check whether the underlying file-system supports filenames\n# with a leading dot.  For instance MS-DOS doesn't.\nAC_DEFUN([AM_SET_LEADING_DOT],\n[rm -rf .tst 2>/dev/null\nmkdir .tst 2>/dev/null\nif test -d .tst; then\n  am__leading_dot=.\nelse\n  am__leading_dot=_\nfi\nrmdir .tst 2>/dev/null\nAC_SUBST([am__leading_dot])])\n\n# Check to see how 'make' treats includes.\t            -*- Autoconf -*-\n\n# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 3\n\n# AM_MAKE_INCLUDE()\n# -----------------\n# Check to see how make treats includes.\nAC_DEFUN([AM_MAKE_INCLUDE],\n[am_make=${MAKE-make}\ncat > confinc << 'END'\nam__doit:\n\t@echo done\n.PHONY: am__doit\nEND\n# If we don't find an include directive, just comment out the code.\nAC_MSG_CHECKING([for style of include used by $am_make])\nam__include=\"#\"\nam__quote=\n_am_result=none\n# First try GNU make style include.\necho \"include confinc\" > confmf\n# We grep out `Entering directory' and `Leaving directory'\n# messages which can occur if `w' ends up in MAKEFLAGS.\n# In particular we don't look at `^make:' because GNU make might\n# be invoked under some other name (usually \"gmake\"), in which\n# case it prints its new name instead of `make'.\nif test \"`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`\" = \"done\"; then\n   am__include=include\n   am__quote=\n   _am_result=GNU\nfi\n# Now try BSD make style include.\nif test \"$am__include\" = \"#\"; then\n   echo '.include \"confinc\"' > confmf\n   if test \"`$am_make -s -f confmf 2> /dev/null`\" = \"done\"; then\n      am__include=.include\n      am__quote=\"\\\"\"\n      _am_result=BSD\n   fi\nfi\nAC_SUBST([am__include])\nAC_SUBST([am__quote])\nAC_MSG_RESULT([$_am_result])\nrm -f confinc confmf\n])\n\n# Copyright (C) 1999, 2000, 2001, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 3\n\n# AM_PROG_CC_C_O\n# --------------\n# Like AC_PROG_CC_C_O, but changed for automake.\nAC_DEFUN([AM_PROG_CC_C_O],\n[AC_REQUIRE([AC_PROG_CC_C_O])dnl\nAC_REQUIRE([AM_AUX_DIR_EXPAND])dnl\n# FIXME: we rely on the cache variable name because\n# there is no other way.\nset dummy $CC\nac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`\nif eval \"test \\\"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\\\" != yes\"; then\n   # Losing compiler, so override with the script.\n   # FIXME: It is wrong to rewrite CC.\n   # But if we don't then we get into trouble of one sort or another.\n   # A longer-term fix would be to have automake use am__CC in this case,\n   # and then we could set am__CC=\"\\$(top_srcdir)/compile \\$(CC)\"\n   CC=\"$am_aux_dir/compile $CC\"\nfi\n])\n\n# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-\n\n# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 4\n\n# AM_MISSING_PROG(NAME, PROGRAM)\n# ------------------------------\nAC_DEFUN([AM_MISSING_PROG],\n[AC_REQUIRE([AM_MISSING_HAS_RUN])\n$1=${$1-\"${am_missing_run}$2\"}\nAC_SUBST($1)])\n\n\n# AM_MISSING_HAS_RUN\n# ------------------\n# Define MISSING if not defined so far and test if it supports --run.\n# If it does, set am_missing_run to use it, otherwise, to nothing.\nAC_DEFUN([AM_MISSING_HAS_RUN],\n[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl\ntest x\"${MISSING+set}\" = xset || MISSING=\"\\${SHELL} $am_aux_dir/missing\"\n# Use eval to expand $SHELL\nif eval \"$MISSING --run true\"; then\n  am_missing_run=\"$MISSING --run \"\nelse\n  am_missing_run=\n  AC_MSG_WARN([`missing' script is too old or missing])\nfi\n])\n\n# Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# AM_PROG_MKDIR_P\n# ---------------\n# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.\n#\n# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories\n# created by `make install' are always world readable, even if the\n# installer happens to have an overly restrictive umask (e.g. 077).\n# This was a mistake.  There are at least two reasons why we must not\n# use `-m 0755':\n#   - it causes special bits like SGID to be ignored,\n#   - it may be too restrictive (some setups expect 775 directories).\n#\n# Do not use -m 0755 and let people choose whatever they expect by\n# setting umask.\n#\n# We cannot accept any implementation of `mkdir' that recognizes `-p'.\n# Some implementations (such as Solaris 8's) are not thread-safe: if a\n# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'\n# concurrently, both version can detect that a/ is missing, but only\n# one can create it and the other will error out.  Consequently we\n# restrict ourselves to GNU make (using the --version option ensures\n# this.)\nAC_DEFUN([AM_PROG_MKDIR_P],\n[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then\n  # We used to keeping the `.' as first argument, in order to\n  # allow $(mkdir_p) to be used without argument.  As in\n  #   $(mkdir_p) $(somedir)\n  # where $(somedir) is conditionally defined.  However this is wrong\n  # for two reasons:\n  #  1. if the package is installed by a user who cannot write `.'\n  #     make install will fail,\n  #  2. the above comment should most certainly read\n  #     $(mkdir_p) $(DESTDIR)$(somedir)\n  #     so it does not work when $(somedir) is undefined and\n  #     $(DESTDIR) is not.\n  #  To support the latter case, we have to write\n  #     test -z \"$(somedir)\" || $(mkdir_p) $(DESTDIR)$(somedir),\n  #  so the `.' trick is pointless.\n  mkdir_p='mkdir -p --'\nelse\n  # On NextStep and OpenStep, the `mkdir' command does not\n  # recognize any option.  It will interpret all options as\n  # directories to create, and then abort because `.' already\n  # exists.\n  for d in ./-p ./--version;\n  do\n    test -d $d && rmdir $d\n  done\n  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.\n  if test -f \"$ac_aux_dir/mkinstalldirs\"; then\n    mkdir_p='$(mkinstalldirs)'\n  else\n    mkdir_p='$(install_sh) -d'\n  fi\nfi\nAC_SUBST([mkdir_p])])\n\n# Helper functions for option handling.                     -*- Autoconf -*-\n\n# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 3\n\n# _AM_MANGLE_OPTION(NAME)\n# -----------------------\nAC_DEFUN([_AM_MANGLE_OPTION],\n[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])\n\n# _AM_SET_OPTION(NAME)\n# ------------------------------\n# Set option NAME.  Presently that only means defining a flag for this option.\nAC_DEFUN([_AM_SET_OPTION],\n[m4_define(_AM_MANGLE_OPTION([$1]), 1)])\n\n# _AM_SET_OPTIONS(OPTIONS)\n# ----------------------------------\n# OPTIONS is a space-separated list of Automake options.\nAC_DEFUN([_AM_SET_OPTIONS],\n[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])\n\n# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])\n# -------------------------------------------\n# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.\nAC_DEFUN([_AM_IF_OPTION],\n[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])\n\n# Check to make sure that the build environment is sane.    -*- Autoconf -*-\n\n# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005\n# Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 4\n\n# AM_SANITY_CHECK\n# ---------------\nAC_DEFUN([AM_SANITY_CHECK],\n[AC_MSG_CHECKING([whether build environment is sane])\n# Just in case\nsleep 1\necho timestamp > conftest.file\n# Do `set' in a subshell so we don't clobber the current shell's\n# arguments.  Must try -L first in case configure is actually a\n# symlink; some systems play weird games with the mod time of symlinks\n# (eg FreeBSD returns the mod time of the symlink's containing\n# directory).\nif (\n   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`\n   if test \"$[*]\" = \"X\"; then\n      # -L didn't work.\n      set X `ls -t $srcdir/configure conftest.file`\n   fi\n   rm -f conftest.file\n   if test \"$[*]\" != \"X $srcdir/configure conftest.file\" \\\n      && test \"$[*]\" != \"X conftest.file $srcdir/configure\"; then\n\n      # If neither matched, then we have a broken ls.  This can happen\n      # if, for instance, CONFIG_SHELL is bash and it inherits a\n      # broken ls alias from the environment.  This has actually\n      # happened.  Such a system could not be considered \"sane\".\n      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken\nalias in your environment])\n   fi\n\n   test \"$[2]\" = conftest.file\n   )\nthen\n   # Ok.\n   :\nelse\n   AC_MSG_ERROR([newly created file is older than distributed files!\nCheck your system clock])\nfi\nAC_MSG_RESULT(yes)])\n\n# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# AM_PROG_INSTALL_STRIP\n# ---------------------\n# One issue with vendor `install' (even GNU) is that you can't\n# specify the program used to strip binaries.  This is especially\n# annoying in cross-compiling environments, where the build's strip\n# is unlikely to handle the host's binaries.\n# Fortunately install-sh will honor a STRIPPROG variable, so we\n# always use install-sh in `make install-strip', and initialize\n# STRIPPROG with the value of the STRIP variable (set by the user).\nAC_DEFUN([AM_PROG_INSTALL_STRIP],\n[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl\n# Installed binaries are usually stripped using `strip' when the user\n# run `make install-strip'.  However `strip' might not be the right\n# tool to use in cross-compilation environments, therefore Automake\n# will honor the `STRIP' environment variable to overrule this program.\ndnl Don't test for $cross_compiling = yes, because it might be `maybe'.\nif test \"$cross_compiling\" != no; then\n  AC_CHECK_TOOL([STRIP], [strip], :)\nfi\nINSTALL_STRIP_PROGRAM=\"\\${SHELL} \\$(install_sh) -c -s\"\nAC_SUBST([INSTALL_STRIP_PROGRAM])])\n\n# Check how to create a tarball.                            -*- Autoconf -*-\n\n# Copyright (C) 2004, 2005  Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 2\n\n# _AM_PROG_TAR(FORMAT)\n# --------------------\n# Check how to create a tarball in format FORMAT.\n# FORMAT should be one of `v7', `ustar', or `pax'.\n#\n# Substitute a variable $(am__tar) that is a command\n# writing to stdout a FORMAT-tarball containing the directory\n# $tardir.\n#     tardir=directory && $(am__tar) > result.tar\n#\n# Substitute a variable $(am__untar) that extract such\n# a tarball read from stdin.\n#     $(am__untar) < result.tar\nAC_DEFUN([_AM_PROG_TAR],\n[# Always define AMTAR for backward compatibility.\nAM_MISSING_PROG([AMTAR], [tar])\nm4_if([$1], [v7],\n     [am__tar='${AMTAR} chof - \"$$tardir\"'; am__untar='${AMTAR} xf -'],\n     [m4_case([$1], [ustar],, [pax],,\n              [m4_fatal([Unknown tar format])])\nAC_MSG_CHECKING([how to create a $1 tar archive])\n# Loop over all known methods to create a tar archive until one works.\n_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'\n_am_tools=${am_cv_prog_tar_$1-$_am_tools}\n# Do not fold the above two line into one, because Tru64 sh and\n# Solaris sh will not grok spaces in the rhs of `-'.\nfor _am_tool in $_am_tools\ndo\n  case $_am_tool in\n  gnutar)\n    for _am_tar in tar gnutar gtar;\n    do\n      AM_RUN_LOG([$_am_tar --version]) && break\n    done\n    am__tar=\"$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - \"'\"$$tardir\"'\n    am__tar_=\"$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - \"'\"$tardir\"'\n    am__untar=\"$_am_tar -xf -\"\n    ;;\n  plaintar)\n    # Must skip GNU tar: if it does not support --format= it doesn't create\n    # ustar tarball either.\n    (tar --version) >/dev/null 2>&1 && continue\n    am__tar='tar chf - \"$$tardir\"'\n    am__tar_='tar chf - \"$tardir\"'\n    am__untar='tar xf -'\n    ;;\n  pax)\n    am__tar='pax -L -x $1 -w \"$$tardir\"'\n    am__tar_='pax -L -x $1 -w \"$tardir\"'\n    am__untar='pax -r'\n    ;;\n  cpio)\n    am__tar='find \"$$tardir\" -print | cpio -o -H $1 -L'\n    am__tar_='find \"$tardir\" -print | cpio -o -H $1 -L'\n    am__untar='cpio -i -H $1 -d'\n    ;;\n  none)\n    am__tar=false\n    am__tar_=false\n    am__untar=false\n    ;;\n  esac\n\n  # If the value was cached, stop now.  We just wanted to have am__tar\n  # and am__untar set.\n  test -n \"${am_cv_prog_tar_$1}\" && break\n\n  # tar/untar a dummy directory, and stop if the command works\n  rm -rf conftest.dir\n  mkdir conftest.dir\n  echo GrepMe > conftest.dir/file\n  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])\n  rm -rf conftest.dir\n  if test -s conftest.tar; then\n    AM_RUN_LOG([$am__untar <conftest.tar])\n    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break\n  fi\ndone\nrm -rf conftest.dir\n\nAC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])\nAC_MSG_RESULT([$am_cv_prog_tar_$1])])\nAC_SUBST([am__tar])\nAC_SUBST([am__untar])\n]) # _AM_PROG_TAR\n\nm4_include([m4/ac_have_attribute.m4])\nm4_include([m4/acx_nanosleep.m4])\nm4_include([m4/acx_pthread.m4])\nm4_include([m4/compiler_characteristics.m4])\nm4_include([m4/install_prefix.m4])\nm4_include([m4/libtool.m4])\nm4_include([m4/ltoptions.m4])\nm4_include([m4/ltsugar.m4])\nm4_include([m4/ltversion.m4])\nm4_include([m4/lt~obsolete.m4])\nm4_include([m4/namespaces.m4])\nm4_include([m4/pc_from_ucontext.m4])\nm4_include([m4/program_invocation_name.m4])\nm4_include([m4/stl_namespace.m4])\n"
  },
  {
    "path": "distro/google-perftools-1.7/compile",
    "content": "#! /bin/sh\n# Wrapper for compilers which do not understand `-c -o'.\n\nscriptversion=2005-05-14.22\n\n# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.\n# Written by Tom Tromey <tromey@cygnus.com>.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2, or (at your option)\n# any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n# This file is maintained in Automake, please report\n# bugs to <bug-automake@gnu.org> or send patches to\n# <automake-patches@gnu.org>.\n\ncase $1 in\n  '')\n     echo \"$0: No command.  Try \\`$0 --help' for more information.\" 1>&2\n     exit 1;\n     ;;\n  -h | --h*)\n    cat <<\\EOF\nUsage: compile [--help] [--version] PROGRAM [ARGS]\n\nWrapper for compilers which do not understand `-c -o'.\nRemove `-o dest.o' from ARGS, run PROGRAM with the remaining\narguments, and rename the output as expected.\n\nIf you are trying to build a whole package this is not the\nright script to run: please start by reading the file `INSTALL'.\n\nReport bugs to <bug-automake@gnu.org>.\nEOF\n    exit $?\n    ;;\n  -v | --v*)\n    echo \"compile $scriptversion\"\n    exit $?\n    ;;\nesac\n\nofile=\ncfile=\neat=\n\nfor arg\ndo\n  if test -n \"$eat\"; then\n    eat=\n  else\n    case $1 in\n      -o)\n\t# configure might choose to run compile as `compile cc -o foo foo.c'.\n\t# So we strip `-o arg' only if arg is an object.\n\teat=1\n\tcase $2 in\n\t  *.o | *.obj)\n\t    ofile=$2\n\t    ;;\n\t  *)\n\t    set x \"$@\" -o \"$2\"\n\t    shift\n\t    ;;\n\tesac\n\t;;\n      *.c)\n\tcfile=$1\n\tset x \"$@\" \"$1\"\n\tshift\n\t;;\n      *)\n\tset x \"$@\" \"$1\"\n\tshift\n\t;;\n    esac\n  fi\n  shift\ndone\n\nif test -z \"$ofile\" || test -z \"$cfile\"; then\n  # If no `-o' option was seen then we might have been invoked from a\n  # pattern rule where we don't need one.  That is ok -- this is a\n  # normal compilation that the losing compiler can handle.  If no\n  # `.c' file was seen then we are probably linking.  That is also\n  # ok.\n  exec \"$@\"\nfi\n\n# Name of file we expect compiler to create.\ncofile=`echo \"$cfile\" | sed -e 's|^.*/||' -e 's/\\.c$/.o/'`\n\n# Create the lock directory.\n# Note: use `[/.-]' here to ensure that we don't use the same name\n# that we are using for the .o file.  Also, base the name on the expected\n# object file name, since that is what matters with a parallel build.\nlockdir=`echo \"$cofile\" | sed -e 's|[/.-]|_|g'`.d\nwhile true; do\n  if mkdir \"$lockdir\" >/dev/null 2>&1; then\n    break\n  fi\n  sleep 1\ndone\n# FIXME: race condition here if user kills between mkdir and trap.\ntrap \"rmdir '$lockdir'; exit 1\" 1 2 15\n\n# Run the compile.\n\"$@\"\nret=$?\n\nif test -f \"$cofile\"; then\n  mv \"$cofile\" \"$ofile\"\nelif test -f \"${cofile}bj\"; then\n  mv \"${cofile}bj\" \"$ofile\"\nfi\n\nrmdir \"$lockdir\"\nexit $ret\n\n# Local Variables:\n# mode: shell-script\n# sh-indentation: 2\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-end: \"$\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/config.guess",
    "content": "#! /bin/sh\n# Attempt to guess a canonical system name.\n#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,\n#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,\n#   Inc.\n\ntimestamp='2007-07-22'\n\n# This file is free software; you can redistribute it and/or modify it\n# under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA\n# 02110-1301, USA.\n#\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n\n# Originally written by Per Bothner <per@bothner.com>.\n# Please send patches to <config-patches@gnu.org>.  Submit a context\n# diff and a properly formatted ChangeLog entry.\n#\n# This script attempts to guess a canonical system name similar to\n# config.sub.  If it succeeds, it prints the system name on stdout, and\n# exits with 0.  Otherwise, it exits with 1.\n#\n# The plan is that this can be called by configure scripts if you\n# don't specify an explicit build system type.\n\nme=`echo \"$0\" | sed -e 's,.*/,,'`\n\nusage=\"\\\nUsage: $0 [OPTION]\n\nOutput the configuration name of the system \\`$me' is run on.\n\nOperation modes:\n  -h, --help         print this help, then exit\n  -t, --time-stamp   print date of last modification, then exit\n  -v, --version      print version number, then exit\n\nReport bugs and patches to <config-patches@gnu.org>.\"\n\nversion=\"\\\nGNU config.guess ($timestamp)\n\nOriginally written by Per Bothner.\nCopyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005\nFree Software Foundation, Inc.\n\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\"\n\nhelp=\"\nTry \\`$me --help' for more information.\"\n\n# Parse command line\nwhile test $# -gt 0 ; do\n  case $1 in\n    --time-stamp | --time* | -t )\n       echo \"$timestamp\" ; exit ;;\n    --version | -v )\n       echo \"$version\" ; exit ;;\n    --help | --h* | -h )\n       echo \"$usage\"; exit ;;\n    -- )     # Stop option processing\n       shift; break ;;\n    - )\t# Use stdin as input.\n       break ;;\n    -* )\n       echo \"$me: invalid option $1$help\" >&2\n       exit 1 ;;\n    * )\n       break ;;\n  esac\ndone\n\nif test $# != 0; then\n  echo \"$me: too many arguments$help\" >&2\n  exit 1\nfi\n\ntrap 'exit 1' 1 2 15\n\n# CC_FOR_BUILD -- compiler used by this script. Note that the use of a\n# compiler to aid in system detection is discouraged as it requires\n# temporary files to be created and, as you can see below, it is a\n# headache to deal with in a portable fashion.\n\n# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still\n# use `HOST_CC' if defined, but it is deprecated.\n\n# Portable tmp directory creation inspired by the Autoconf team.\n\nset_cc_for_build='\ntrap \"exitcode=\\$?; (rm -f \\$tmpfiles 2>/dev/null; rmdir \\$tmp 2>/dev/null) && exit \\$exitcode\" 0 ;\ntrap \"rm -f \\$tmpfiles 2>/dev/null; rmdir \\$tmp 2>/dev/null; exit 1\" 1 2 13 15 ;\n: ${TMPDIR=/tmp} ;\n { tmp=`(umask 077 && mktemp -d \"$TMPDIR/cgXXXXXX\") 2>/dev/null` && test -n \"$tmp\" && test -d \"$tmp\" ; } ||\n { test -n \"$RANDOM\" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||\n { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo \"Warning: creating insecure temp directory\" >&2 ; } ||\n { echo \"$me: cannot create a temporary directory in $TMPDIR\" >&2 ; exit 1 ; } ;\ndummy=$tmp/dummy ;\ntmpfiles=\"$dummy.c $dummy.o $dummy.rel $dummy\" ;\ncase $CC_FOR_BUILD,$HOST_CC,$CC in\n ,,)    echo \"int x;\" > $dummy.c ;\n\tfor c in cc gcc c89 c99 ; do\n\t  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then\n\t     CC_FOR_BUILD=\"$c\"; break ;\n\t  fi ;\n\tdone ;\n\tif test x\"$CC_FOR_BUILD\" = x ; then\n\t  CC_FOR_BUILD=no_compiler_found ;\n\tfi\n\t;;\n ,,*)   CC_FOR_BUILD=$CC ;;\n ,*,*)  CC_FOR_BUILD=$HOST_CC ;;\nesac ; set_cc_for_build= ;'\n\n# This is needed to find uname on a Pyramid OSx when run in the BSD universe.\n# (ghazi@noc.rutgers.edu 1994-08-24)\nif (test -f /.attbin/uname) >/dev/null 2>&1 ; then\n\tPATH=$PATH:/.attbin ; export PATH\nfi\n\nUNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown\nUNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown\nUNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown\nUNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown\n\n# Note: order is significant - the case branches are not exclusive.\n\ncase \"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}\" in\n    *:NetBSD:*:*)\n\t# NetBSD (nbsd) targets should (where applicable) match one or\n\t# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,\n\t# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently\n\t# switched to ELF, *-*-netbsd* would select the old\n\t# object file format.  This provides both forward\n\t# compatibility and a consistent mechanism for selecting the\n\t# object file format.\n\t#\n\t# Note: NetBSD doesn't particularly care about the vendor\n\t# portion of the name.  We always set it to \"unknown\".\n\tsysctl=\"sysctl -n hw.machine_arch\"\n\tUNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \\\n\t    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`\n\tcase \"${UNAME_MACHINE_ARCH}\" in\n\t    armeb) machine=armeb-unknown ;;\n\t    arm*) machine=arm-unknown ;;\n\t    sh3el) machine=shl-unknown ;;\n\t    sh3eb) machine=sh-unknown ;;\n\t    sh5el) machine=sh5le-unknown ;;\n\t    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;\n\tesac\n\t# The Operating System including object format, if it has switched\n\t# to ELF recently, or will in the future.\n\tcase \"${UNAME_MACHINE_ARCH}\" in\n\t    arm*|i386|m68k|ns32k|sh3*|sparc|vax)\n\t\teval $set_cc_for_build\n\t\tif echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \\\n\t\t\t| grep __ELF__ >/dev/null\n\t\tthen\n\t\t    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).\n\t\t    # Return netbsd for either.  FIX?\n\t\t    os=netbsd\n\t\telse\n\t\t    os=netbsdelf\n\t\tfi\n\t\t;;\n\t    *)\n\t        os=netbsd\n\t\t;;\n\tesac\n\t# The OS release\n\t# Debian GNU/NetBSD machines have a different userland, and\n\t# thus, need a distinct triplet. However, they do not need\n\t# kernel version information, so it can be replaced with a\n\t# suitable tag, in the style of linux-gnu.\n\tcase \"${UNAME_VERSION}\" in\n\t    Debian*)\n\t\trelease='-gnu'\n\t\t;;\n\t    *)\n\t\trelease=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\\./'`\n\t\t;;\n\tesac\n\t# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:\n\t# contains redundant information, the shorter form:\n\t# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.\n\techo \"${machine}-${os}${release}\"\n\texit ;;\n    *:OpenBSD:*:*)\n\tUNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`\n\techo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}\n\texit ;;\n    *:ekkoBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}\n\texit ;;\n    *:SolidBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}\n\texit ;;\n    macppc:MirBSD:*:*)\n\techo powerpc-unknown-mirbsd${UNAME_RELEASE}\n\texit ;;\n    *:MirBSD:*:*)\n\techo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}\n\texit ;;\n    alpha:OSF1:*:*)\n\tcase $UNAME_RELEASE in\n\t*4.0)\n\t\tUNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`\n\t\t;;\n\t*5.*)\n\t        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`\n\t\t;;\n\tesac\n\t# According to Compaq, /usr/sbin/psrinfo has been available on\n\t# OSF/1 and Tru64 systems produced since 1995.  I hope that\n\t# covers most systems running today.  This code pipes the CPU\n\t# types through head -n 1, so we only detect the type of CPU 0.\n\tALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \\(.*\\) processor.*$/\\1/p' | head -n 1`\n\tcase \"$ALPHA_CPU_TYPE\" in\n\t    \"EV4 (21064)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"EV4.5 (21064)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"LCA4 (21066/21068)\")\n\t\tUNAME_MACHINE=\"alpha\" ;;\n\t    \"EV5 (21164)\")\n\t\tUNAME_MACHINE=\"alphaev5\" ;;\n\t    \"EV5.6 (21164A)\")\n\t\tUNAME_MACHINE=\"alphaev56\" ;;\n\t    \"EV5.6 (21164PC)\")\n\t\tUNAME_MACHINE=\"alphapca56\" ;;\n\t    \"EV5.7 (21164PC)\")\n\t\tUNAME_MACHINE=\"alphapca57\" ;;\n\t    \"EV6 (21264)\")\n\t\tUNAME_MACHINE=\"alphaev6\" ;;\n\t    \"EV6.7 (21264A)\")\n\t\tUNAME_MACHINE=\"alphaev67\" ;;\n\t    \"EV6.8CB (21264C)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.8AL (21264B)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.8CX (21264D)\")\n\t\tUNAME_MACHINE=\"alphaev68\" ;;\n\t    \"EV6.9A (21264/EV69A)\")\n\t\tUNAME_MACHINE=\"alphaev69\" ;;\n\t    \"EV7 (21364)\")\n\t\tUNAME_MACHINE=\"alphaev7\" ;;\n\t    \"EV7.9 (21364A)\")\n\t\tUNAME_MACHINE=\"alphaev79\" ;;\n\tesac\n\t# A Pn.n version is a patched version.\n\t# A Vn.n version is a released version.\n\t# A Tn.n version is a released field test version.\n\t# A Xn.n version is an unreleased experimental baselevel.\n\t# 1.2 uses \"1.2\" for uname -r.\n\techo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`\n\texit ;;\n    Alpha\\ *:Windows_NT*:*)\n\t# How do we know it's Interix rather than the generic POSIX subsystem?\n\t# Should we change UNAME_MACHINE based on the output of uname instead\n\t# of the specific Alpha model?\n\techo alpha-pc-interix\n\texit ;;\n    21064:Windows_NT:50:3)\n\techo alpha-dec-winnt3.5\n\texit ;;\n    Amiga*:UNIX_System_V:4.0:*)\n\techo m68k-unknown-sysv4\n\texit ;;\n    *:[Aa]miga[Oo][Ss]:*:*)\n\techo ${UNAME_MACHINE}-unknown-amigaos\n\texit ;;\n    *:[Mm]orph[Oo][Ss]:*:*)\n\techo ${UNAME_MACHINE}-unknown-morphos\n\texit ;;\n    *:OS/390:*:*)\n\techo i370-ibm-openedition\n\texit ;;\n    *:z/VM:*:*)\n\techo s390-ibm-zvmoe\n\texit ;;\n    *:OS400:*:*)\n        echo powerpc-ibm-os400\n\texit ;;\n    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)\n\techo arm-acorn-riscix${UNAME_RELEASE}\n\texit ;;\n    arm:riscos:*:*|arm:RISCOS:*:*)\n\techo arm-unknown-riscos\n\texit ;;\n    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)\n\techo hppa1.1-hitachi-hiuxmpp\n\texit ;;\n    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)\n\t# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.\n\tif test \"`(/bin/universe) 2>/dev/null`\" = att ; then\n\t\techo pyramid-pyramid-sysv3\n\telse\n\t\techo pyramid-pyramid-bsd\n\tfi\n\texit ;;\n    NILE*:*:*:dcosx)\n\techo pyramid-pyramid-svr4\n\texit ;;\n    DRS?6000:unix:4.0:6*)\n\techo sparc-icl-nx6\n\texit ;;\n    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)\n\tcase `/usr/bin/uname -p` in\n\t    sparc) echo sparc-icl-nx7; exit ;;\n\tesac ;;\n    sun4H:SunOS:5.*:*)\n\techo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)\n\techo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)\n\techo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4*:SunOS:6*:*)\n\t# According to config.sub, this is the proper way to canonicalize\n\t# SunOS6.  Hard to guess exactly what SunOS6 will be like, but\n\t# it's likely to be more like Solaris than SunOS4.\n\techo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    sun4*:SunOS:*:*)\n\tcase \"`/usr/bin/arch -k`\" in\n\t    Series*|S4*)\n\t\tUNAME_RELEASE=`uname -v`\n\t\t;;\n\tesac\n\t# Japanese Language versions have a version number like `4.1.3-JL'.\n\techo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`\n\texit ;;\n    sun3*:SunOS:*:*)\n\techo m68k-sun-sunos${UNAME_RELEASE}\n\texit ;;\n    sun*:*:4.2BSD:*)\n\tUNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`\n\ttest \"x${UNAME_RELEASE}\" = \"x\" && UNAME_RELEASE=3\n\tcase \"`/bin/arch`\" in\n\t    sun3)\n\t\techo m68k-sun-sunos${UNAME_RELEASE}\n\t\t;;\n\t    sun4)\n\t\techo sparc-sun-sunos${UNAME_RELEASE}\n\t\t;;\n\tesac\n\texit ;;\n    aushp:SunOS:*:*)\n\techo sparc-auspex-sunos${UNAME_RELEASE}\n\texit ;;\n    # The situation for MiNT is a little confusing.  The machine name\n    # can be virtually everything (everything which is not\n    # \"atarist\" or \"atariste\" at least should have a processor\n    # > m68000).  The system name ranges from \"MiNT\" over \"FreeMiNT\"\n    # to the lowercase version \"mint\" (or \"freemint\").  Finally\n    # the system name \"TOS\" denotes a system which is actually not\n    # MiNT.  But MiNT is downward compatible to TOS, so this should\n    # be no problem.\n    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)\n        echo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)\n\techo m68k-atari-mint${UNAME_RELEASE}\n        exit ;;\n    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)\n        echo m68k-atari-mint${UNAME_RELEASE}\n\texit ;;\n    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)\n        echo m68k-milan-mint${UNAME_RELEASE}\n        exit ;;\n    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)\n        echo m68k-hades-mint${UNAME_RELEASE}\n        exit ;;\n    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)\n        echo m68k-unknown-mint${UNAME_RELEASE}\n        exit ;;\n    m68k:machten:*:*)\n\techo m68k-apple-machten${UNAME_RELEASE}\n\texit ;;\n    powerpc:machten:*:*)\n\techo powerpc-apple-machten${UNAME_RELEASE}\n\texit ;;\n    RISC*:Mach:*:*)\n\techo mips-dec-mach_bsd4.3\n\texit ;;\n    RISC*:ULTRIX:*:*)\n\techo mips-dec-ultrix${UNAME_RELEASE}\n\texit ;;\n    VAX*:ULTRIX*:*:*)\n\techo vax-dec-ultrix${UNAME_RELEASE}\n\texit ;;\n    2020:CLIX:*:* | 2430:CLIX:*:*)\n\techo clipper-intergraph-clix${UNAME_RELEASE}\n\texit ;;\n    mips:*:*:UMIPS | mips:*:*:RISCos)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n#ifdef __cplusplus\n#include <stdio.h>  /* for printf() prototype */\n\tint main (int argc, char *argv[]) {\n#else\n\tint main (argc, argv) int argc; char *argv[]; {\n#endif\n\t#if defined (host_mips) && defined (MIPSEB)\n\t#if defined (SYSTYPE_SYSV)\n\t  printf (\"mips-mips-riscos%ssysv\\n\", argv[1]); exit (0);\n\t#endif\n\t#if defined (SYSTYPE_SVR4)\n\t  printf (\"mips-mips-riscos%ssvr4\\n\", argv[1]); exit (0);\n\t#endif\n\t#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)\n\t  printf (\"mips-mips-riscos%sbsd\\n\", argv[1]); exit (0);\n\t#endif\n\t#endif\n\t  exit (-1);\n\t}\nEOF\n\t$CC_FOR_BUILD -o $dummy $dummy.c &&\n\t  dummyarg=`echo \"${UNAME_RELEASE}\" | sed -n 's/\\([0-9]*\\).*/\\1/p'` &&\n\t  SYSTEM_NAME=`$dummy $dummyarg` &&\n\t    { echo \"$SYSTEM_NAME\"; exit; }\n\techo mips-mips-riscos${UNAME_RELEASE}\n\texit ;;\n    Motorola:PowerMAX_OS:*:*)\n\techo powerpc-motorola-powermax\n\texit ;;\n    Motorola:*:4.3:PL8-*)\n\techo powerpc-harris-powermax\n\texit ;;\n    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)\n\techo powerpc-harris-powermax\n\texit ;;\n    Night_Hawk:Power_UNIX:*:*)\n\techo powerpc-harris-powerunix\n\texit ;;\n    m88k:CX/UX:7*:*)\n\techo m88k-harris-cxux7\n\texit ;;\n    m88k:*:4*:R4*)\n\techo m88k-motorola-sysv4\n\texit ;;\n    m88k:*:3*:R3*)\n\techo m88k-motorola-sysv3\n\texit ;;\n    AViiON:dgux:*:*)\n        # DG/UX returns AViiON for all architectures\n        UNAME_PROCESSOR=`/usr/bin/uname -p`\n\tif [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]\n\tthen\n\t    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \\\n\t       [ ${TARGET_BINARY_INTERFACE}x = x ]\n\t    then\n\t\techo m88k-dg-dgux${UNAME_RELEASE}\n\t    else\n\t\techo m88k-dg-dguxbcs${UNAME_RELEASE}\n\t    fi\n\telse\n\t    echo i586-dg-dgux${UNAME_RELEASE}\n\tfi\n \texit ;;\n    M88*:DolphinOS:*:*)\t# DolphinOS (SVR3)\n\techo m88k-dolphin-sysv3\n\texit ;;\n    M88*:*:R3*:*)\n\t# Delta 88k system running SVR3\n\techo m88k-motorola-sysv3\n\texit ;;\n    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)\n\techo m88k-tektronix-sysv3\n\texit ;;\n    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)\n\techo m68k-tektronix-bsd\n\texit ;;\n    *:IRIX*:*:*)\n\techo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`\n\texit ;;\n    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.\n\techo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id\n\texit ;;               # Note that: echo \"'`uname -s`'\" gives 'AIX '\n    i*86:AIX:*:*)\n\techo i386-ibm-aix\n\texit ;;\n    ia64:AIX:*:*)\n\tif [ -x /usr/bin/oslevel ] ; then\n\t\tIBM_REV=`/usr/bin/oslevel`\n\telse\n\t\tIBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}\n\tfi\n\techo ${UNAME_MACHINE}-ibm-aix${IBM_REV}\n\texit ;;\n    *:AIX:2:3)\n\tif grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then\n\t\teval $set_cc_for_build\n\t\tsed 's/^\t\t//' << EOF >$dummy.c\n\t\t#include <sys/systemcfg.h>\n\n\t\tmain()\n\t\t\t{\n\t\t\tif (!__power_pc())\n\t\t\t\texit(1);\n\t\t\tputs(\"powerpc-ibm-aix3.2.5\");\n\t\t\texit(0);\n\t\t\t}\nEOF\n\t\tif $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`\n\t\tthen\n\t\t\techo \"$SYSTEM_NAME\"\n\t\telse\n\t\t\techo rs6000-ibm-aix3.2.5\n\t\tfi\n\telif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then\n\t\techo rs6000-ibm-aix3.2.4\n\telse\n\t\techo rs6000-ibm-aix3.2\n\tfi\n\texit ;;\n    *:AIX:*:[45])\n\tIBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`\n\tif /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then\n\t\tIBM_ARCH=rs6000\n\telse\n\t\tIBM_ARCH=powerpc\n\tfi\n\tif [ -x /usr/bin/oslevel ] ; then\n\t\tIBM_REV=`/usr/bin/oslevel`\n\telse\n\t\tIBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}\n\tfi\n\techo ${IBM_ARCH}-ibm-aix${IBM_REV}\n\texit ;;\n    *:AIX:*:*)\n\techo rs6000-ibm-aix\n\texit ;;\n    ibmrt:4.4BSD:*|romp-ibm:BSD:*)\n\techo romp-ibm-bsd4.4\n\texit ;;\n    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and\n\techo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to\n\texit ;;                             # report: romp-ibm BSD 4.3\n    *:BOSX:*:*)\n\techo rs6000-bull-bosx\n\texit ;;\n    DPX/2?00:B.O.S.:*:*)\n\techo m68k-bull-sysv3\n\texit ;;\n    9000/[34]??:4.3bsd:1.*:*)\n\techo m68k-hp-bsd\n\texit ;;\n    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)\n\techo m68k-hp-bsd4.4\n\texit ;;\n    9000/[34678]??:HP-UX:*:*)\n\tHPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`\n\tcase \"${UNAME_MACHINE}\" in\n\t    9000/31? )            HP_ARCH=m68000 ;;\n\t    9000/[34]?? )         HP_ARCH=m68k ;;\n\t    9000/[678][0-9][0-9])\n\t\tif [ -x /usr/bin/getconf ]; then\n\t\t    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`\n                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`\n                    case \"${sc_cpu_version}\" in\n                      523) HP_ARCH=\"hppa1.0\" ;; # CPU_PA_RISC1_0\n                      528) HP_ARCH=\"hppa1.1\" ;; # CPU_PA_RISC1_1\n                      532)                      # CPU_PA_RISC2_0\n                        case \"${sc_kernel_bits}\" in\n                          32) HP_ARCH=\"hppa2.0n\" ;;\n                          64) HP_ARCH=\"hppa2.0w\" ;;\n\t\t\t  '') HP_ARCH=\"hppa2.0\" ;;   # HP-UX 10.20\n                        esac ;;\n                    esac\n\t\tfi\n\t\tif [ \"${HP_ARCH}\" = \"\" ]; then\n\t\t    eval $set_cc_for_build\n\t\t    sed 's/^              //' << EOF >$dummy.c\n\n              #define _HPUX_SOURCE\n              #include <stdlib.h>\n              #include <unistd.h>\n\n              int main ()\n              {\n              #if defined(_SC_KERNEL_BITS)\n                  long bits = sysconf(_SC_KERNEL_BITS);\n              #endif\n                  long cpu  = sysconf (_SC_CPU_VERSION);\n\n                  switch (cpu)\n              \t{\n              \tcase CPU_PA_RISC1_0: puts (\"hppa1.0\"); break;\n              \tcase CPU_PA_RISC1_1: puts (\"hppa1.1\"); break;\n              \tcase CPU_PA_RISC2_0:\n              #if defined(_SC_KERNEL_BITS)\n              \t    switch (bits)\n              \t\t{\n              \t\tcase 64: puts (\"hppa2.0w\"); break;\n              \t\tcase 32: puts (\"hppa2.0n\"); break;\n              \t\tdefault: puts (\"hppa2.0\"); break;\n              \t\t} break;\n              #else  /* !defined(_SC_KERNEL_BITS) */\n              \t    puts (\"hppa2.0\"); break;\n              #endif\n              \tdefault: puts (\"hppa1.0\"); break;\n              \t}\n                  exit (0);\n              }\nEOF\n\t\t    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`\n\t\t    test -z \"$HP_ARCH\" && HP_ARCH=hppa\n\t\tfi ;;\n\tesac\n\tif [ ${HP_ARCH} = \"hppa2.0w\" ]\n\tthen\n\t    eval $set_cc_for_build\n\n\t    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating\n\t    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler\n\t    # generating 64-bit code.  GNU and HP use different nomenclature:\n\t    #\n\t    # $ CC_FOR_BUILD=cc ./config.guess\n\t    # => hppa2.0w-hp-hpux11.23\n\t    # $ CC_FOR_BUILD=\"cc +DA2.0w\" ./config.guess\n\t    # => hppa64-hp-hpux11.23\n\n\t    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |\n\t\tgrep __LP64__ >/dev/null\n\t    then\n\t\tHP_ARCH=\"hppa2.0w\"\n\t    else\n\t\tHP_ARCH=\"hppa64\"\n\t    fi\n\tfi\n\techo ${HP_ARCH}-hp-hpux${HPUX_REV}\n\texit ;;\n    ia64:HP-UX:*:*)\n\tHPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`\n\techo ia64-hp-hpux${HPUX_REV}\n\texit ;;\n    3050*:HI-UX:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#include <unistd.h>\n\tint\n\tmain ()\n\t{\n\t  long cpu = sysconf (_SC_CPU_VERSION);\n\t  /* The order matters, because CPU_IS_HP_MC68K erroneously returns\n\t     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct\n\t     results, however.  */\n\t  if (CPU_IS_PA_RISC (cpu))\n\t    {\n\t      switch (cpu)\n\t\t{\n\t\t  case CPU_PA_RISC1_0: puts (\"hppa1.0-hitachi-hiuxwe2\"); break;\n\t\t  case CPU_PA_RISC1_1: puts (\"hppa1.1-hitachi-hiuxwe2\"); break;\n\t\t  case CPU_PA_RISC2_0: puts (\"hppa2.0-hitachi-hiuxwe2\"); break;\n\t\t  default: puts (\"hppa-hitachi-hiuxwe2\"); break;\n\t\t}\n\t    }\n\t  else if (CPU_IS_HP_MC68K (cpu))\n\t    puts (\"m68k-hitachi-hiuxwe2\");\n\t  else puts (\"unknown-hitachi-hiuxwe2\");\n\t  exit (0);\n\t}\nEOF\n\t$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&\n\t\t{ echo \"$SYSTEM_NAME\"; exit; }\n\techo unknown-hitachi-hiuxwe2\n\texit ;;\n    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )\n\techo hppa1.1-hp-bsd\n\texit ;;\n    9000/8??:4.3bsd:*:*)\n\techo hppa1.0-hp-bsd\n\texit ;;\n    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)\n\techo hppa1.0-hp-mpeix\n\texit ;;\n    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )\n\techo hppa1.1-hp-osf\n\texit ;;\n    hp8??:OSF1:*:*)\n\techo hppa1.0-hp-osf\n\texit ;;\n    i*86:OSF1:*:*)\n\tif [ -x /usr/sbin/sysversion ] ; then\n\t    echo ${UNAME_MACHINE}-unknown-osf1mk\n\telse\n\t    echo ${UNAME_MACHINE}-unknown-osf1\n\tfi\n\texit ;;\n    parisc*:Lites*:*:*)\n\techo hppa1.1-hp-lites\n\texit ;;\n    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)\n\techo c1-convex-bsd\n        exit ;;\n    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)\n\tif getsysinfo -f scalar_acc\n\tthen echo c32-convex-bsd\n\telse echo c2-convex-bsd\n\tfi\n        exit ;;\n    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)\n\techo c34-convex-bsd\n        exit ;;\n    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)\n\techo c38-convex-bsd\n        exit ;;\n    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)\n\techo c4-convex-bsd\n        exit ;;\n    CRAY*Y-MP:*:*:*)\n\techo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*[A-Z]90:*:*:*)\n\techo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \\\n\t| sed -e 's/CRAY.*\\([A-Z]90\\)/\\1/' \\\n\t      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \\\n\t      -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*TS:*:*:*)\n\techo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*T3E:*:*:*)\n\techo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    CRAY*SV1:*:*:*)\n\techo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    *:UNICOS/mp:*:*)\n\techo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\\.[^.]*$/.X/'\n\texit ;;\n    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)\n\tFUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`\n        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`\n        echo \"${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n        exit ;;\n    5000:UNIX_System_V:4.*:*)\n        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\\///'`\n        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`\n        echo \"sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}\"\n\texit ;;\n    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\\ Embedded/OS:*:*)\n\techo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}\n\texit ;;\n    sparc*:BSD/OS:*:*)\n\techo sparc-unknown-bsdi${UNAME_RELEASE}\n\texit ;;\n    *:BSD/OS:*:*)\n\techo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}\n\texit ;;\n    *:FreeBSD:*:*)\n\tcase ${UNAME_MACHINE} in\n\t    pc98)\n\t\techo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\t    amd64)\n\t\techo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\t    *)\n\t\techo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;\n\tesac\n\texit ;;\n    i*:CYGWIN*:*)\n\techo ${UNAME_MACHINE}-pc-cygwin\n\texit ;;\n    *:MINGW*:*)\n\techo ${UNAME_MACHINE}-pc-mingw32\n\texit ;;\n    i*:windows32*:*)\n    \t# uname -m includes \"-pc\" on this system.\n    \techo ${UNAME_MACHINE}-mingw32\n\texit ;;\n    i*:PW*:*)\n\techo ${UNAME_MACHINE}-pc-pw32\n\texit ;;\n    *:Interix*:[3456]*)\n    \tcase ${UNAME_MACHINE} in\n\t    x86)\n\t\techo i586-pc-interix${UNAME_RELEASE}\n\t\texit ;;\n\t    EM64T | authenticamd)\n\t\techo x86_64-unknown-interix${UNAME_RELEASE}\n\t\texit ;;\n\tesac ;;\n    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)\n\techo i${UNAME_MACHINE}-pc-mks\n\texit ;;\n    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)\n\t# How do we know it's Interix rather than the generic POSIX subsystem?\n\t# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we\n\t# UNAME_MACHINE based on the output of uname instead of i386?\n\techo i586-pc-interix\n\texit ;;\n    i*:UWIN*:*)\n\techo ${UNAME_MACHINE}-pc-uwin\n\texit ;;\n    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)\n\techo x86_64-unknown-cygwin\n\texit ;;\n    p*:CYGWIN*:*)\n\techo powerpcle-unknown-cygwin\n\texit ;;\n    prep*:SunOS:5.*:*)\n\techo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`\n\texit ;;\n    *:GNU:*:*)\n\t# the GNU system\n\techo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`\n\texit ;;\n    *:GNU/*:*:*)\n\t# other systems with GNU libc and userland\n\techo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu\n\texit ;;\n    i*86:Minix:*:*)\n\techo ${UNAME_MACHINE}-pc-minix\n\texit ;;\n    arm*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    avr32*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    cris:Linux:*:*)\n\techo cris-axis-linux-gnu\n\texit ;;\n    crisv32:Linux:*:*)\n\techo crisv32-axis-linux-gnu\n\texit ;;\n    frv:Linux:*:*)\n    \techo frv-unknown-linux-gnu\n\texit ;;\n    ia64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    m32r*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    m68*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    mips:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef mips\n\t#undef mipsel\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=mipsel\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=mips\n\t#else\n\tCPU=\n\t#endif\n\t#endif\nEOF\n\teval \"`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '\n\t    /^CPU/{\n\t\ts: ::g\n\t\tp\n\t    }'`\"\n\ttest x\"${CPU}\" != x && { echo \"${CPU}-unknown-linux-gnu\"; exit; }\n\t;;\n    mips64:Linux:*:*)\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#undef CPU\n\t#undef mips64\n\t#undef mips64el\n\t#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)\n\tCPU=mips64el\n\t#else\n\t#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)\n\tCPU=mips64\n\t#else\n\tCPU=\n\t#endif\n\t#endif\nEOF\n\teval \"`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '\n\t    /^CPU/{\n\t\ts: ::g\n\t\tp\n\t    }'`\"\n\ttest x\"${CPU}\" != x && { echo \"${CPU}-unknown-linux-gnu\"; exit; }\n\t;;\n    or32:Linux:*:*)\n\techo or32-unknown-linux-gnu\n\texit ;;\n    ppc:Linux:*:*)\n\techo powerpc-unknown-linux-gnu\n\texit ;;\n    ppc64:Linux:*:*)\n\techo powerpc64-unknown-linux-gnu\n\texit ;;\n    alpha:Linux:*:*)\n\tcase `sed -n '/^cpu model/s/^.*: \\(.*\\)/\\1/p' < /proc/cpuinfo` in\n\t  EV5)   UNAME_MACHINE=alphaev5 ;;\n\t  EV56)  UNAME_MACHINE=alphaev56 ;;\n\t  PCA56) UNAME_MACHINE=alphapca56 ;;\n\t  PCA57) UNAME_MACHINE=alphapca56 ;;\n\t  EV6)   UNAME_MACHINE=alphaev6 ;;\n\t  EV67)  UNAME_MACHINE=alphaev67 ;;\n\t  EV68*) UNAME_MACHINE=alphaev68 ;;\n        esac\n\tobjdump --private-headers /bin/sh | grep ld.so.1 >/dev/null\n\tif test \"$?\" = 0 ; then LIBC=\"libc1\" ; else LIBC=\"\" ; fi\n\techo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}\n\texit ;;\n    parisc:Linux:*:* | hppa:Linux:*:*)\n\t# Look for CPU level\n\tcase `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in\n\t  PA7*) echo hppa1.1-unknown-linux-gnu ;;\n\t  PA8*) echo hppa2.0-unknown-linux-gnu ;;\n\t  *)    echo hppa-unknown-linux-gnu ;;\n\tesac\n\texit ;;\n    parisc64:Linux:*:* | hppa64:Linux:*:*)\n\techo hppa64-unknown-linux-gnu\n\texit ;;\n    s390:Linux:*:* | s390x:Linux:*:*)\n\techo ${UNAME_MACHINE}-ibm-linux\n\texit ;;\n    sh64*:Linux:*:*)\n    \techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    sh*:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    sparc:Linux:*:* | sparc64:Linux:*:*)\n\techo ${UNAME_MACHINE}-unknown-linux-gnu\n\texit ;;\n    vax:Linux:*:*)\n\techo ${UNAME_MACHINE}-dec-linux-gnu\n\texit ;;\n    x86_64:Linux:*:*)\n\techo x86_64-unknown-linux-gnu\n\texit ;;\n    xtensa:Linux:*:*)\n    \techo xtensa-unknown-linux-gnu\n\texit ;;\n    i*86:Linux:*:*)\n\t# The BFD linker knows what the default object file format is, so\n\t# first see if it will tell us. cd to the root directory to prevent\n\t# problems with other programs or directories called `ld' in the path.\n\t# Set LC_ALL=C to ensure ld outputs messages in English.\n\tld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \\\n\t\t\t | sed -ne '/supported targets:/!d\n\t\t\t\t    s/[ \t][ \t]*/ /g\n\t\t\t\t    s/.*supported targets: *//\n\t\t\t\t    s/ .*//\n\t\t\t\t    p'`\n        case \"$ld_supported_targets\" in\n\t  elf32-i386)\n\t\tTENTATIVE=\"${UNAME_MACHINE}-pc-linux-gnu\"\n\t\t;;\n\t  a.out-i386-linux)\n\t\techo \"${UNAME_MACHINE}-pc-linux-gnuaout\"\n\t\texit ;;\n\t  coff-i386)\n\t\techo \"${UNAME_MACHINE}-pc-linux-gnucoff\"\n\t\texit ;;\n\t  \"\")\n\t\t# Either a pre-BFD a.out linker (linux-gnuoldld) or\n\t\t# one that does not give us useful --help.\n\t\techo \"${UNAME_MACHINE}-pc-linux-gnuoldld\"\n\t\texit ;;\n\tesac\n\t# Determine whether the default compiler is a.out or elf\n\teval $set_cc_for_build\n\tsed 's/^\t//' << EOF >$dummy.c\n\t#include <features.h>\n\t#ifdef __ELF__\n\t# ifdef __GLIBC__\n\t#  if __GLIBC__ >= 2\n\tLIBC=gnu\n\t#  else\n\tLIBC=gnulibc1\n\t#  endif\n\t# else\n\tLIBC=gnulibc1\n\t# endif\n\t#else\n\t#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)\n\tLIBC=gnu\n\t#else\n\tLIBC=gnuaout\n\t#endif\n\t#endif\n\t#ifdef __dietlibc__\n\tLIBC=dietlibc\n\t#endif\nEOF\n\teval \"`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '\n\t    /^LIBC/{\n\t\ts: ::g\n\t\tp\n\t    }'`\"\n\ttest x\"${LIBC}\" != x && {\n\t\techo \"${UNAME_MACHINE}-pc-linux-${LIBC}\"\n\t\texit\n\t}\n\ttest x\"${TENTATIVE}\" != x && { echo \"${TENTATIVE}\"; exit; }\n\t;;\n    i*86:DYNIX/ptx:4*:*)\n\t# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.\n\t# earlier versions are messed up and put the nodename in both\n\t# sysname and nodename.\n\techo i386-sequent-sysv4\n\texit ;;\n    i*86:UNIX_SV:4.2MP:2.*)\n        # Unixware is an offshoot of SVR4, but it has its own version\n        # number series starting with 2...\n        # I am not positive that other SVR4 systems won't match this,\n\t# I just have to hope.  -- rms.\n        # Use sysv4.2uw... so that sysv4* matches it.\n\techo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}\n\texit ;;\n    i*86:OS/2:*:*)\n\t# If we were able to find `uname', then EMX Unix compatibility\n\t# is probably installed.\n\techo ${UNAME_MACHINE}-pc-os2-emx\n\texit ;;\n    i*86:XTS-300:*:STOP)\n\techo ${UNAME_MACHINE}-unknown-stop\n\texit ;;\n    i*86:atheos:*:*)\n\techo ${UNAME_MACHINE}-unknown-atheos\n\texit ;;\n    i*86:syllable:*:*)\n\techo ${UNAME_MACHINE}-pc-syllable\n\texit ;;\n    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)\n\techo i386-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    i*86:*DOS:*:*)\n\techo ${UNAME_MACHINE}-pc-msdosdjgpp\n\texit ;;\n    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)\n\tUNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\\/MP$//'`\n\tif grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then\n\t\techo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}\n\telse\n\t\techo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}\n\tfi\n\texit ;;\n    i*86:*:5:[678]*)\n    \t# UnixWare 7.x, OpenUNIX and OpenServer 6.\n\tcase `/bin/uname -X | grep \"^Machine\"` in\n\t    *486*)\t     UNAME_MACHINE=i486 ;;\n\t    *Pentium)\t     UNAME_MACHINE=i586 ;;\n\t    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;\n\tesac\n\techo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}\n\texit ;;\n    i*86:*:3.2:*)\n\tif test -f /usr/options/cb.name; then\n\t\tUNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`\n\t\techo ${UNAME_MACHINE}-pc-isc$UNAME_REL\n\telif /bin/uname -X 2>/dev/null >/dev/null ; then\n\t\tUNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`\n\t\t(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486\n\t\t(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i586\n\t\t(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i686\n\t\t(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \\\n\t\t\t&& UNAME_MACHINE=i686\n\t\techo ${UNAME_MACHINE}-pc-sco$UNAME_REL\n\telse\n\t\techo ${UNAME_MACHINE}-pc-sysv32\n\tfi\n\texit ;;\n    pc:*:*:*)\n\t# Left here for compatibility:\n        # uname -m prints for DJGPP always 'pc', but it prints nothing about\n        # the processor, so we play safe by assuming i386.\n\techo i386-pc-msdosdjgpp\n        exit ;;\n    Intel:Mach:3*:*)\n\techo i386-pc-mach3\n\texit ;;\n    paragon:*:*:*)\n\techo i860-intel-osf1\n\texit ;;\n    i860:*:4.*:*) # i860-SVR4\n\tif grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then\n\t  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4\n\telse # Add other i860-SVR4 vendors below as they are discovered.\n\t  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4\n\tfi\n\texit ;;\n    mini*:CTIX:SYS*5:*)\n\t# \"miniframe\"\n\techo m68010-convergent-sysv\n\texit ;;\n    mc68k:UNIX:SYSTEM5:3.51m)\n\techo m68k-convergent-sysv\n\texit ;;\n    M680?0:D-NIX:5.3:*)\n\techo m68k-diab-dnix\n\texit ;;\n    M68*:*:R3V[5678]*:*)\n\ttest -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;\n    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)\n\tOS_REL=''\n\ttest -r /etc/.relid \\\n\t&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \\([0-9][0-9]\\).*/\\1/p' < /etc/.relid`\n\t/bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n\t  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }\n\t/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \\\n\t  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;\n    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)\n        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \\\n          && { echo i486-ncr-sysv4; exit; } ;;\n    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)\n\techo m68k-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    mc68030:UNIX_System_V:4.*:*)\n\techo m68k-atari-sysv4\n\texit ;;\n    TSUNAMI:LynxOS:2.*:*)\n\techo sparc-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    rs6000:LynxOS:2.*:*)\n\techo rs6000-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)\n\techo powerpc-unknown-lynxos${UNAME_RELEASE}\n\texit ;;\n    SM[BE]S:UNIX_SV:*:*)\n\techo mips-dde-sysv${UNAME_RELEASE}\n\texit ;;\n    RM*:ReliantUNIX-*:*:*)\n\techo mips-sni-sysv4\n\texit ;;\n    RM*:SINIX-*:*:*)\n\techo mips-sni-sysv4\n\texit ;;\n    *:SINIX-*:*:*)\n\tif uname -p 2>/dev/null >/dev/null ; then\n\t\tUNAME_MACHINE=`(uname -p) 2>/dev/null`\n\t\techo ${UNAME_MACHINE}-sni-sysv4\n\telse\n\t\techo ns32k-sni-sysv\n\tfi\n\texit ;;\n    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort\n                      # says <Richard.M.Bartel@ccMail.Census.GOV>\n        echo i586-unisys-sysv4\n        exit ;;\n    *:UNIX_System_V:4*:FTX*)\n\t# From Gerald Hewes <hewes@openmarket.com>.\n\t# How about differentiating between stratus architectures? -djm\n\techo hppa1.1-stratus-sysv4\n\texit ;;\n    *:*:*:FTX*)\n\t# From seanf@swdc.stratus.com.\n\techo i860-stratus-sysv4\n\texit ;;\n    i*86:VOS:*:*)\n\t# From Paul.Green@stratus.com.\n\techo ${UNAME_MACHINE}-stratus-vos\n\texit ;;\n    *:VOS:*:*)\n\t# From Paul.Green@stratus.com.\n\techo hppa1.1-stratus-vos\n\texit ;;\n    mc68*:A/UX:*:*)\n\techo m68k-apple-aux${UNAME_RELEASE}\n\texit ;;\n    news*:NEWS-OS:6*:*)\n\techo mips-sony-newsos6\n\texit ;;\n    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)\n\tif [ -d /usr/nec ]; then\n\t        echo mips-nec-sysv${UNAME_RELEASE}\n\telse\n\t        echo mips-unknown-sysv${UNAME_RELEASE}\n\tfi\n        exit ;;\n    BeBox:BeOS:*:*)\t# BeOS running on hardware made by Be, PPC only.\n\techo powerpc-be-beos\n\texit ;;\n    BeMac:BeOS:*:*)\t# BeOS running on Mac or Mac clone, PPC only.\n\techo powerpc-apple-beos\n\texit ;;\n    BePC:BeOS:*:*)\t# BeOS running on Intel PC compatible.\n\techo i586-pc-beos\n\texit ;;\n    SX-4:SUPER-UX:*:*)\n\techo sx4-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-5:SUPER-UX:*:*)\n\techo sx5-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-6:SUPER-UX:*:*)\n\techo sx6-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-7:SUPER-UX:*:*)\n\techo sx7-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-8:SUPER-UX:*:*)\n\techo sx8-nec-superux${UNAME_RELEASE}\n\texit ;;\n    SX-8R:SUPER-UX:*:*)\n\techo sx8r-nec-superux${UNAME_RELEASE}\n\texit ;;\n    Power*:Rhapsody:*:*)\n\techo powerpc-apple-rhapsody${UNAME_RELEASE}\n\texit ;;\n    *:Rhapsody:*:*)\n\techo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}\n\texit ;;\n    *:Darwin:*:*)\n\tUNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown\n\tcase $UNAME_PROCESSOR in\n\t    unknown) UNAME_PROCESSOR=powerpc ;;\n\tesac\n\techo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}\n\texit ;;\n    *:procnto*:*:* | *:QNX:[0123456789]*:*)\n\tUNAME_PROCESSOR=`uname -p`\n\tif test \"$UNAME_PROCESSOR\" = \"x86\"; then\n\t\tUNAME_PROCESSOR=i386\n\t\tUNAME_MACHINE=pc\n\tfi\n\techo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}\n\texit ;;\n    *:QNX:*:4*)\n\techo i386-pc-qnx\n\texit ;;\n    NSE-?:NONSTOP_KERNEL:*:*)\n\techo nse-tandem-nsk${UNAME_RELEASE}\n\texit ;;\n    NSR-?:NONSTOP_KERNEL:*:*)\n\techo nsr-tandem-nsk${UNAME_RELEASE}\n\texit ;;\n    *:NonStop-UX:*:*)\n\techo mips-compaq-nonstopux\n\texit ;;\n    BS2000:POSIX*:*:*)\n\techo bs2000-siemens-sysv\n\texit ;;\n    DS/*:UNIX_System_V:*:*)\n\techo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}\n\texit ;;\n    *:Plan9:*:*)\n\t# \"uname -m\" is not consistent, so use $cputype instead. 386\n\t# is converted to i386 for consistency with other x86\n\t# operating systems.\n\tif test \"$cputype\" = \"386\"; then\n\t    UNAME_MACHINE=i386\n\telse\n\t    UNAME_MACHINE=\"$cputype\"\n\tfi\n\techo ${UNAME_MACHINE}-unknown-plan9\n\texit ;;\n    *:TOPS-10:*:*)\n\techo pdp10-unknown-tops10\n\texit ;;\n    *:TENEX:*:*)\n\techo pdp10-unknown-tenex\n\texit ;;\n    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)\n\techo pdp10-dec-tops20\n\texit ;;\n    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)\n\techo pdp10-xkl-tops20\n\texit ;;\n    *:TOPS-20:*:*)\n\techo pdp10-unknown-tops20\n\texit ;;\n    *:ITS:*:*)\n\techo pdp10-unknown-its\n\texit ;;\n    SEI:*:*:SEIUX)\n        echo mips-sei-seiux${UNAME_RELEASE}\n\texit ;;\n    *:DragonFly:*:*)\n\techo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`\n\texit ;;\n    *:*VMS:*:*)\n    \tUNAME_MACHINE=`(uname -p) 2>/dev/null`\n\tcase \"${UNAME_MACHINE}\" in\n\t    A*) echo alpha-dec-vms ; exit ;;\n\t    I*) echo ia64-dec-vms ; exit ;;\n\t    V*) echo vax-dec-vms ; exit ;;\n\tesac ;;\n    *:XENIX:*:SysV)\n\techo i386-pc-xenix\n\texit ;;\n    i*86:skyos:*:*)\n\techo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'\n\texit ;;\n    i*86:rdos:*:*)\n\techo ${UNAME_MACHINE}-pc-rdos\n\texit ;;\nesac\n\n#echo '(No uname command or uname output not recognized.)' 1>&2\n#echo \"${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}\" 1>&2\n\neval $set_cc_for_build\ncat >$dummy.c <<EOF\n#ifdef _SEQUENT_\n# include <sys/types.h>\n# include <sys/utsname.h>\n#endif\nmain ()\n{\n#if defined (sony)\n#if defined (MIPSEB)\n  /* BFD wants \"bsd\" instead of \"newsos\".  Perhaps BFD should be changed,\n     I don't know....  */\n  printf (\"mips-sony-bsd\\n\"); exit (0);\n#else\n#include <sys/param.h>\n  printf (\"m68k-sony-newsos%s\\n\",\n#ifdef NEWSOS4\n          \"4\"\n#else\n\t  \"\"\n#endif\n         ); exit (0);\n#endif\n#endif\n\n#if defined (__arm) && defined (__acorn) && defined (__unix)\n  printf (\"arm-acorn-riscix\\n\"); exit (0);\n#endif\n\n#if defined (hp300) && !defined (hpux)\n  printf (\"m68k-hp-bsd\\n\"); exit (0);\n#endif\n\n#if defined (NeXT)\n#if !defined (__ARCHITECTURE__)\n#define __ARCHITECTURE__ \"m68k\"\n#endif\n  int version;\n  version=`(hostinfo | sed -n 's/.*NeXT Mach \\([0-9]*\\).*/\\1/p') 2>/dev/null`;\n  if (version < 4)\n    printf (\"%s-next-nextstep%d\\n\", __ARCHITECTURE__, version);\n  else\n    printf (\"%s-next-openstep%d\\n\", __ARCHITECTURE__, version);\n  exit (0);\n#endif\n\n#if defined (MULTIMAX) || defined (n16)\n#if defined (UMAXV)\n  printf (\"ns32k-encore-sysv\\n\"); exit (0);\n#else\n#if defined (CMU)\n  printf (\"ns32k-encore-mach\\n\"); exit (0);\n#else\n  printf (\"ns32k-encore-bsd\\n\"); exit (0);\n#endif\n#endif\n#endif\n\n#if defined (__386BSD__)\n  printf (\"i386-pc-bsd\\n\"); exit (0);\n#endif\n\n#if defined (sequent)\n#if defined (i386)\n  printf (\"i386-sequent-dynix\\n\"); exit (0);\n#endif\n#if defined (ns32000)\n  printf (\"ns32k-sequent-dynix\\n\"); exit (0);\n#endif\n#endif\n\n#if defined (_SEQUENT_)\n    struct utsname un;\n\n    uname(&un);\n\n    if (strncmp(un.version, \"V2\", 2) == 0) {\n\tprintf (\"i386-sequent-ptx2\\n\"); exit (0);\n    }\n    if (strncmp(un.version, \"V1\", 2) == 0) { /* XXX is V1 correct? */\n\tprintf (\"i386-sequent-ptx1\\n\"); exit (0);\n    }\n    printf (\"i386-sequent-ptx\\n\"); exit (0);\n\n#endif\n\n#if defined (vax)\n# if !defined (ultrix)\n#  include <sys/param.h>\n#  if defined (BSD)\n#   if BSD == 43\n      printf (\"vax-dec-bsd4.3\\n\"); exit (0);\n#   else\n#    if BSD == 199006\n      printf (\"vax-dec-bsd4.3reno\\n\"); exit (0);\n#    else\n      printf (\"vax-dec-bsd\\n\"); exit (0);\n#    endif\n#   endif\n#  else\n    printf (\"vax-dec-bsd\\n\"); exit (0);\n#  endif\n# else\n    printf (\"vax-dec-ultrix\\n\"); exit (0);\n# endif\n#endif\n\n#if defined (alliant) && defined (i860)\n  printf (\"i860-alliant-bsd\\n\"); exit (0);\n#endif\n\n  exit (1);\n}\nEOF\n\n$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&\n\t{ echo \"$SYSTEM_NAME\"; exit; }\n\n# Apollos put the system type in the environment.\n\ntest -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }\n\n# Convex versions that predate uname can use getsysinfo(1)\n\nif [ -x /usr/convex/getsysinfo ]\nthen\n    case `getsysinfo -f cpu_type` in\n    c1*)\n\techo c1-convex-bsd\n\texit ;;\n    c2*)\n\tif getsysinfo -f scalar_acc\n\tthen echo c32-convex-bsd\n\telse echo c2-convex-bsd\n\tfi\n\texit ;;\n    c34*)\n\techo c34-convex-bsd\n\texit ;;\n    c38*)\n\techo c38-convex-bsd\n\texit ;;\n    c4*)\n\techo c4-convex-bsd\n\texit ;;\n    esac\nfi\n\ncat >&2 <<EOF\n$0: unable to guess system type\n\nThis script, last modified $timestamp, has failed to recognize\nthe operating system you are using. It is advised that you\ndownload the most up to date version of the config scripts from\n\n  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess\nand\n  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub\n\nIf the version you run ($0) is already up to date, please\nsend the following data and any information you think might be\npertinent to <config-patches@gnu.org> in order to provide the needed\ninformation to handle your system.\n\nconfig.guess timestamp = $timestamp\n\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`\n\nhostinfo               = `(hostinfo) 2>/dev/null`\n/bin/universe          = `(/bin/universe) 2>/dev/null`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`\n/bin/arch              = `(/bin/arch) 2>/dev/null`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`\n\nUNAME_MACHINE = ${UNAME_MACHINE}\nUNAME_RELEASE = ${UNAME_RELEASE}\nUNAME_SYSTEM  = ${UNAME_SYSTEM}\nUNAME_VERSION = ${UNAME_VERSION}\nEOF\n\nexit 1\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"timestamp='\"\n# time-stamp-format: \"%:y-%02m-%02d\"\n# time-stamp-end: \"'\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/config.sub",
    "content": "#! /bin/sh\n# Configuration validation subroutine script.\n#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,\n#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,\n#   Inc.\n\ntimestamp='2007-06-28'\n\n# This file is (in principle) common to ALL GNU software.\n# The presence of a machine in this file suggests that SOME GNU software\n# can handle that machine.  It does not imply ALL GNU software can.\n#\n# This file is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA\n# 02110-1301, USA.\n#\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n\n# Please send patches to <config-patches@gnu.org>.  Submit a context\n# diff and a properly formatted ChangeLog entry.\n#\n# Configuration subroutine to validate and canonicalize a configuration type.\n# Supply the specified configuration type as an argument.\n# If it is invalid, we print an error message on stderr and exit with code 1.\n# Otherwise, we print the canonical config type on stdout and succeed.\n\n# This file is supposed to be the same for all GNU packages\n# and recognize all the CPU types, system types and aliases\n# that are meaningful with *any* GNU software.\n# Each package is responsible for reporting which valid configurations\n# it does not support.  The user should be able to distinguish\n# a failure to support a valid configuration from a meaningless\n# configuration.\n\n# The goal of this file is to map all the various variations of a given\n# machine specification into a single specification in the form:\n#\tCPU_TYPE-MANUFACTURER-OPERATING_SYSTEM\n# or in some cases, the newer four-part form:\n#\tCPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM\n# It is wrong to echo any other type of specification.\n\nme=`echo \"$0\" | sed -e 's,.*/,,'`\n\nusage=\"\\\nUsage: $0 [OPTION] CPU-MFR-OPSYS\n       $0 [OPTION] ALIAS\n\nCanonicalize a configuration name.\n\nOperation modes:\n  -h, --help         print this help, then exit\n  -t, --time-stamp   print date of last modification, then exit\n  -v, --version      print version number, then exit\n\nReport bugs and patches to <config-patches@gnu.org>.\"\n\nversion=\"\\\nGNU config.sub ($timestamp)\n\nCopyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005\nFree Software Foundation, Inc.\n\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\"\n\nhelp=\"\nTry \\`$me --help' for more information.\"\n\n# Parse command line\nwhile test $# -gt 0 ; do\n  case $1 in\n    --time-stamp | --time* | -t )\n       echo \"$timestamp\" ; exit ;;\n    --version | -v )\n       echo \"$version\" ; exit ;;\n    --help | --h* | -h )\n       echo \"$usage\"; exit ;;\n    -- )     # Stop option processing\n       shift; break ;;\n    - )\t# Use stdin as input.\n       break ;;\n    -* )\n       echo \"$me: invalid option $1$help\"\n       exit 1 ;;\n\n    *local*)\n       # First pass through any local machine types.\n       echo $1\n       exit ;;\n\n    * )\n       break ;;\n  esac\ndone\n\ncase $# in\n 0) echo \"$me: missing argument$help\" >&2\n    exit 1;;\n 1) ;;\n *) echo \"$me: too many arguments$help\" >&2\n    exit 1;;\nesac\n\n# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).\n# Here we must recognize all the valid KERNEL-OS combinations.\nmaybe_os=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\2/'`\ncase $maybe_os in\n  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \\\n  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \\\n  storm-chaos* | os2-emx* | rtmk-nova*)\n    os=-$maybe_os\n    basic_machine=`echo $1 | sed 's/^\\(.*\\)-\\([^-]*-[^-]*\\)$/\\1/'`\n    ;;\n  *)\n    basic_machine=`echo $1 | sed 's/-[^-]*$//'`\n    if [ $basic_machine != $1 ]\n    then os=`echo $1 | sed 's/.*-/-/'`\n    else os=; fi\n    ;;\nesac\n\n### Let's recognize common machines as not being operating systems so\n### that things like config.sub decstation-3100 work.  We also\n### recognize some manufacturers as not being operating systems, so we\n### can provide default operating systems below.\ncase $os in\n\t-sun*os*)\n\t\t# Prevent following clause from handling this invalid input.\n\t\t;;\n\t-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \\\n\t-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \\\n\t-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \\\n\t-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\\\n\t-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \\\n\t-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \\\n\t-apple | -axis | -knuth | -cray)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-sim | -cisco | -oki | -wec | -winbond)\n\t\tos=\n\t\tbasic_machine=$1\n\t\t;;\n\t-scout)\n\t\t;;\n\t-wrs)\n\t\tos=-vxworks\n\t\tbasic_machine=$1\n\t\t;;\n\t-chorusos*)\n\t\tos=-chorusos\n\t\tbasic_machine=$1\n\t\t;;\n \t-chorusrdb)\n \t\tos=-chorusrdb\n\t\tbasic_machine=$1\n \t\t;;\n\t-hiux*)\n\t\tos=-hiuxwe2\n\t\t;;\n\t-sco6)\n\t\tos=-sco5v6\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco5)\n\t\tos=-sco3.2v5\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco4)\n\t\tos=-sco3.2v4\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco3.2.[4-9]*)\n\t\tos=`echo $os | sed -e 's/sco3.2./sco3.2v/'`\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco3.2v[4-9]*)\n\t\t# Don't forget version if it is 3.2v4 or newer.\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco5v6*)\n\t\t# Don't forget version if it is 3.2v4 or newer.\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-sco*)\n\t\tos=-sco3.2v2\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-udk*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-isc)\n\t\tos=-isc2.2\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-clix*)\n\t\tbasic_machine=clipper-intergraph\n\t\t;;\n\t-isc*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`\n\t\t;;\n\t-lynx*)\n\t\tos=-lynxos\n\t\t;;\n\t-ptx*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`\n\t\t;;\n\t-windowsnt*)\n\t\tos=`echo $os | sed -e 's/windowsnt/winnt/'`\n\t\t;;\n\t-psos*)\n\t\tos=-psos\n\t\t;;\n\t-mint | -mint[0-9]*)\n\t\tbasic_machine=m68k-atari\n\t\tos=-mint\n\t\t;;\nesac\n\n# Decode aliases for certain CPU-COMPANY combinations.\ncase $basic_machine in\n\t# Recognize the basic CPU types without company name.\n\t# Some are omitted here because they have special meanings below.\n\t1750a | 580 \\\n\t| a29k \\\n\t| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \\\n\t| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \\\n\t| am33_2.0 \\\n\t| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \\\n\t| bfin \\\n\t| c4x | clipper \\\n\t| d10v | d30v | dlx | dsp16xx \\\n\t| fido | fr30 | frv \\\n\t| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \\\n\t| i370 | i860 | i960 | ia64 \\\n\t| ip2k | iq2000 \\\n\t| m32c | m32r | m32rle | m68000 | m68k | m88k \\\n\t| maxq | mb | microblaze | mcore | mep \\\n\t| mips | mipsbe | mipseb | mipsel | mipsle \\\n\t| mips16 \\\n\t| mips64 | mips64el \\\n\t| mips64vr | mips64vrel \\\n\t| mips64orion | mips64orionel \\\n\t| mips64vr4100 | mips64vr4100el \\\n\t| mips64vr4300 | mips64vr4300el \\\n\t| mips64vr5000 | mips64vr5000el \\\n\t| mips64vr5900 | mips64vr5900el \\\n\t| mipsisa32 | mipsisa32el \\\n\t| mipsisa32r2 | mipsisa32r2el \\\n\t| mipsisa64 | mipsisa64el \\\n\t| mipsisa64r2 | mipsisa64r2el \\\n\t| mipsisa64sb1 | mipsisa64sb1el \\\n\t| mipsisa64sr71k | mipsisa64sr71kel \\\n\t| mipstx39 | mipstx39el \\\n\t| mn10200 | mn10300 \\\n\t| mt \\\n\t| msp430 \\\n\t| nios | nios2 \\\n\t| ns16k | ns32k \\\n\t| or32 \\\n\t| pdp10 | pdp11 | pj | pjl \\\n\t| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \\\n\t| pyramid \\\n\t| score \\\n\t| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \\\n\t| sh64 | sh64le \\\n\t| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \\\n\t| sparcv8 | sparcv9 | sparcv9b | sparcv9v \\\n\t| spu | strongarm \\\n\t| tahoe | thumb | tic4x | tic80 | tron \\\n\t| v850 | v850e \\\n\t| we32k \\\n\t| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \\\n\t| z8k)\n\t\tbasic_machine=$basic_machine-unknown\n\t\t;;\n\tm6811 | m68hc11 | m6812 | m68hc12)\n\t\t# Motorola 68HC11/12.\n\t\tbasic_machine=$basic_machine-unknown\n\t\tos=-none\n\t\t;;\n\tm88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)\n\t\t;;\n\tms1)\n\t\tbasic_machine=mt-unknown\n\t\t;;\n\n\t# We use `pc' rather than `unknown'\n\t# because (1) that's what they normally are, and\n\t# (2) the word \"unknown\" tends to confuse beginning users.\n\ti*86 | x86_64)\n\t  basic_machine=$basic_machine-pc\n\t  ;;\n\t# Object if more than one company name word.\n\t*-*-*)\n\t\techo Invalid configuration \\`$1\\': machine \\`$basic_machine\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\n\t# Recognize the basic CPU types with company name.\n\t580-* \\\n\t| a29k-* \\\n\t| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \\\n\t| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \\\n\t| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \\\n\t| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \\\n\t| avr-* | avr32-* \\\n\t| bfin-* | bs2000-* \\\n\t| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \\\n\t| clipper-* | craynv-* | cydra-* \\\n\t| d10v-* | d30v-* | dlx-* \\\n\t| elxsi-* \\\n\t| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \\\n\t| h8300-* | h8500-* \\\n\t| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \\\n\t| i*86-* | i860-* | i960-* | ia64-* \\\n\t| ip2k-* | iq2000-* \\\n\t| m32c-* | m32r-* | m32rle-* \\\n\t| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \\\n\t| m88110-* | m88k-* | maxq-* | mcore-* \\\n\t| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \\\n\t| mips16-* \\\n\t| mips64-* | mips64el-* \\\n\t| mips64vr-* | mips64vrel-* \\\n\t| mips64orion-* | mips64orionel-* \\\n\t| mips64vr4100-* | mips64vr4100el-* \\\n\t| mips64vr4300-* | mips64vr4300el-* \\\n\t| mips64vr5000-* | mips64vr5000el-* \\\n\t| mips64vr5900-* | mips64vr5900el-* \\\n\t| mipsisa32-* | mipsisa32el-* \\\n\t| mipsisa32r2-* | mipsisa32r2el-* \\\n\t| mipsisa64-* | mipsisa64el-* \\\n\t| mipsisa64r2-* | mipsisa64r2el-* \\\n\t| mipsisa64sb1-* | mipsisa64sb1el-* \\\n\t| mipsisa64sr71k-* | mipsisa64sr71kel-* \\\n\t| mipstx39-* | mipstx39el-* \\\n\t| mmix-* \\\n\t| mt-* \\\n\t| msp430-* \\\n\t| nios-* | nios2-* \\\n\t| none-* | np1-* | ns16k-* | ns32k-* \\\n\t| orion-* \\\n\t| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \\\n\t| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \\\n\t| pyramid-* \\\n\t| romp-* | rs6000-* \\\n\t| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \\\n\t| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \\\n\t| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \\\n\t| sparclite-* \\\n\t| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \\\n\t| tahoe-* | thumb-* \\\n\t| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \\\n\t| tron-* \\\n\t| v850-* | v850e-* | vax-* \\\n\t| we32k-* \\\n\t| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \\\n\t| xstormy16-* | xtensa-* \\\n\t| ymp-* \\\n\t| z8k-*)\n\t\t;;\n\t# Recognize the various machine names and aliases which stand\n\t# for a CPU type and a company and sometimes even an OS.\n\t386bsd)\n\t\tbasic_machine=i386-unknown\n\t\tos=-bsd\n\t\t;;\n\t3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)\n\t\tbasic_machine=m68000-att\n\t\t;;\n\t3b*)\n\t\tbasic_machine=we32k-att\n\t\t;;\n\ta29khif)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n    \tabacus)\n\t\tbasic_machine=abacus-unknown\n\t\t;;\n\tadobe68k)\n\t\tbasic_machine=m68010-adobe\n\t\tos=-scout\n\t\t;;\n\talliant | fx80)\n\t\tbasic_machine=fx80-alliant\n\t\t;;\n\taltos | altos3068)\n\t\tbasic_machine=m68k-altos\n\t\t;;\n\tam29k)\n\t\tbasic_machine=a29k-none\n\t\tos=-bsd\n\t\t;;\n\tamd64)\n\t\tbasic_machine=x86_64-pc\n\t\t;;\n\tamd64-*)\n\t\tbasic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tamdahl)\n\t\tbasic_machine=580-amdahl\n\t\tos=-sysv\n\t\t;;\n\tamiga | amiga-*)\n\t\tbasic_machine=m68k-unknown\n\t\t;;\n\tamigaos | amigados)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-amigaos\n\t\t;;\n\tamigaunix | amix)\n\t\tbasic_machine=m68k-unknown\n\t\tos=-sysv4\n\t\t;;\n\tapollo68)\n\t\tbasic_machine=m68k-apollo\n\t\tos=-sysv\n\t\t;;\n\tapollo68bsd)\n\t\tbasic_machine=m68k-apollo\n\t\tos=-bsd\n\t\t;;\n\taux)\n\t\tbasic_machine=m68k-apple\n\t\tos=-aux\n\t\t;;\n\tbalance)\n\t\tbasic_machine=ns32k-sequent\n\t\tos=-dynix\n\t\t;;\n\tc90)\n\t\tbasic_machine=c90-cray\n\t\tos=-unicos\n\t\t;;\n\tconvex-c1)\n\t\tbasic_machine=c1-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c2)\n\t\tbasic_machine=c2-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c32)\n\t\tbasic_machine=c32-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c34)\n\t\tbasic_machine=c34-convex\n\t\tos=-bsd\n\t\t;;\n\tconvex-c38)\n\t\tbasic_machine=c38-convex\n\t\tos=-bsd\n\t\t;;\n\tcray | j90)\n\t\tbasic_machine=j90-cray\n\t\tos=-unicos\n\t\t;;\n\tcraynv)\n\t\tbasic_machine=craynv-cray\n\t\tos=-unicosmp\n\t\t;;\n\tcr16)\n\t\tbasic_machine=cr16-unknown\n\t\tos=-elf\n\t\t;;\n\tcrds | unos)\n\t\tbasic_machine=m68k-crds\n\t\t;;\n\tcrisv32 | crisv32-* | etraxfs*)\n\t\tbasic_machine=crisv32-axis\n\t\t;;\n\tcris | cris-* | etrax*)\n\t\tbasic_machine=cris-axis\n\t\t;;\n\tcrx)\n\t\tbasic_machine=crx-unknown\n\t\tos=-elf\n\t\t;;\n\tda30 | da30-*)\n\t\tbasic_machine=m68k-da30\n\t\t;;\n\tdecstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)\n\t\tbasic_machine=mips-dec\n\t\t;;\n\tdecsystem10* | dec10*)\n\t\tbasic_machine=pdp10-dec\n\t\tos=-tops10\n\t\t;;\n\tdecsystem20* | dec20*)\n\t\tbasic_machine=pdp10-dec\n\t\tos=-tops20\n\t\t;;\n\tdelta | 3300 | motorola-3300 | motorola-delta \\\n\t      | 3300-motorola | delta-motorola)\n\t\tbasic_machine=m68k-motorola\n\t\t;;\n\tdelta88)\n\t\tbasic_machine=m88k-motorola\n\t\tos=-sysv3\n\t\t;;\n\tdjgpp)\n\t\tbasic_machine=i586-pc\n\t\tos=-msdosdjgpp\n\t\t;;\n\tdpx20 | dpx20-*)\n\t\tbasic_machine=rs6000-bull\n\t\tos=-bosx\n\t\t;;\n\tdpx2* | dpx2*-bull)\n\t\tbasic_machine=m68k-bull\n\t\tos=-sysv3\n\t\t;;\n\tebmon29k)\n\t\tbasic_machine=a29k-amd\n\t\tos=-ebmon\n\t\t;;\n\telxsi)\n\t\tbasic_machine=elxsi-elxsi\n\t\tos=-bsd\n\t\t;;\n\tencore | umax | mmax)\n\t\tbasic_machine=ns32k-encore\n\t\t;;\n\tes1800 | OSE68k | ose68k | ose | OSE)\n\t\tbasic_machine=m68k-ericsson\n\t\tos=-ose\n\t\t;;\n\tfx2800)\n\t\tbasic_machine=i860-alliant\n\t\t;;\n\tgenix)\n\t\tbasic_machine=ns32k-ns\n\t\t;;\n\tgmicro)\n\t\tbasic_machine=tron-gmicro\n\t\tos=-sysv\n\t\t;;\n\tgo32)\n\t\tbasic_machine=i386-pc\n\t\tos=-go32\n\t\t;;\n\th3050r* | hiux*)\n\t\tbasic_machine=hppa1.1-hitachi\n\t\tos=-hiuxwe2\n\t\t;;\n\th8300hms)\n\t\tbasic_machine=h8300-hitachi\n\t\tos=-hms\n\t\t;;\n\th8300xray)\n\t\tbasic_machine=h8300-hitachi\n\t\tos=-xray\n\t\t;;\n\th8500hms)\n\t\tbasic_machine=h8500-hitachi\n\t\tos=-hms\n\t\t;;\n\tharris)\n\t\tbasic_machine=m88k-harris\n\t\tos=-sysv3\n\t\t;;\n\thp300-*)\n\t\tbasic_machine=m68k-hp\n\t\t;;\n\thp300bsd)\n\t\tbasic_machine=m68k-hp\n\t\tos=-bsd\n\t\t;;\n\thp300hpux)\n\t\tbasic_machine=m68k-hp\n\t\tos=-hpux\n\t\t;;\n\thp3k9[0-9][0-9] | hp9[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thp9k2[0-9][0-9] | hp9k31[0-9])\n\t\tbasic_machine=m68000-hp\n\t\t;;\n\thp9k3[2-9][0-9])\n\t\tbasic_machine=m68k-hp\n\t\t;;\n\thp9k6[0-9][0-9] | hp6[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thp9k7[0-79][0-9] | hp7[0-79][0-9])\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k78[0-9] | hp78[0-9])\n\t\t# FIXME: really hppa2.0-hp\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)\n\t\t# FIXME: really hppa2.0-hp\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[0-9][13679] | hp8[0-9][13679])\n\t\tbasic_machine=hppa1.1-hp\n\t\t;;\n\thp9k8[0-9][0-9] | hp8[0-9][0-9])\n\t\tbasic_machine=hppa1.0-hp\n\t\t;;\n\thppa-next)\n\t\tos=-nextstep3\n\t\t;;\n\thppaosf)\n\t\tbasic_machine=hppa1.1-hp\n\t\tos=-osf\n\t\t;;\n\thppro)\n\t\tbasic_machine=hppa1.1-hp\n\t\tos=-proelf\n\t\t;;\n\ti370-ibm* | ibm*)\n\t\tbasic_machine=i370-ibm\n\t\t;;\n# I'm not sure what \"Sysv32\" means.  Should this be sysv3.2?\n\ti*86v32)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv32\n\t\t;;\n\ti*86v4*)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv4\n\t\t;;\n\ti*86v)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-sysv\n\t\t;;\n\ti*86sol2)\n\t\tbasic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`\n\t\tos=-solaris2\n\t\t;;\n\ti386mach)\n\t\tbasic_machine=i386-mach\n\t\tos=-mach\n\t\t;;\n\ti386-vsta | vsta)\n\t\tbasic_machine=i386-unknown\n\t\tos=-vsta\n\t\t;;\n\tiris | iris4d)\n\t\tbasic_machine=mips-sgi\n\t\tcase $os in\n\t\t    -irix*)\n\t\t\t;;\n\t\t    *)\n\t\t\tos=-irix4\n\t\t\t;;\n\t\tesac\n\t\t;;\n\tisi68 | isi)\n\t\tbasic_machine=m68k-isi\n\t\tos=-sysv\n\t\t;;\n\tm88k-omron*)\n\t\tbasic_machine=m88k-omron\n\t\t;;\n\tmagnum | m3230)\n\t\tbasic_machine=mips-mips\n\t\tos=-sysv\n\t\t;;\n\tmerlin)\n\t\tbasic_machine=ns32k-utek\n\t\tos=-sysv\n\t\t;;\n\tmingw32)\n\t\tbasic_machine=i386-pc\n\t\tos=-mingw32\n\t\t;;\n\tmingw32ce)\n\t\tbasic_machine=arm-unknown\n\t\tos=-mingw32ce\n\t\t;;\n\tminiframe)\n\t\tbasic_machine=m68000-convergent\n\t\t;;\n\t*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)\n\t\tbasic_machine=m68k-atari\n\t\tos=-mint\n\t\t;;\n\tmips3*-*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`\n\t\t;;\n\tmips3*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown\n\t\t;;\n\tmonitor)\n\t\tbasic_machine=m68k-rom68k\n\t\tos=-coff\n\t\t;;\n\tmorphos)\n\t\tbasic_machine=powerpc-unknown\n\t\tos=-morphos\n\t\t;;\n\tmsdos)\n\t\tbasic_machine=i386-pc\n\t\tos=-msdos\n\t\t;;\n\tms1-*)\n\t\tbasic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`\n\t\t;;\n\tmvs)\n\t\tbasic_machine=i370-ibm\n\t\tos=-mvs\n\t\t;;\n\tncr3000)\n\t\tbasic_machine=i486-ncr\n\t\tos=-sysv4\n\t\t;;\n\tnetbsd386)\n\t\tbasic_machine=i386-unknown\n\t\tos=-netbsd\n\t\t;;\n\tnetwinder)\n\t\tbasic_machine=armv4l-rebel\n\t\tos=-linux\n\t\t;;\n\tnews | news700 | news800 | news900)\n\t\tbasic_machine=m68k-sony\n\t\tos=-newsos\n\t\t;;\n\tnews1000)\n\t\tbasic_machine=m68030-sony\n\t\tos=-newsos\n\t\t;;\n\tnews-3600 | risc-news)\n\t\tbasic_machine=mips-sony\n\t\tos=-newsos\n\t\t;;\n\tnecv70)\n\t\tbasic_machine=v70-nec\n\t\tos=-sysv\n\t\t;;\n\tnext | m*-next )\n\t\tbasic_machine=m68k-next\n\t\tcase $os in\n\t\t    -nextstep* )\n\t\t\t;;\n\t\t    -ns2*)\n\t\t      os=-nextstep2\n\t\t\t;;\n\t\t    *)\n\t\t      os=-nextstep3\n\t\t\t;;\n\t\tesac\n\t\t;;\n\tnh3000)\n\t\tbasic_machine=m68k-harris\n\t\tos=-cxux\n\t\t;;\n\tnh[45]000)\n\t\tbasic_machine=m88k-harris\n\t\tos=-cxux\n\t\t;;\n\tnindy960)\n\t\tbasic_machine=i960-intel\n\t\tos=-nindy\n\t\t;;\n\tmon960)\n\t\tbasic_machine=i960-intel\n\t\tos=-mon960\n\t\t;;\n\tnonstopux)\n\t\tbasic_machine=mips-compaq\n\t\tos=-nonstopux\n\t\t;;\n\tnp1)\n\t\tbasic_machine=np1-gould\n\t\t;;\n\tnsr-tandem)\n\t\tbasic_machine=nsr-tandem\n\t\t;;\n\top50n-* | op60c-*)\n\t\tbasic_machine=hppa1.1-oki\n\t\tos=-proelf\n\t\t;;\n\topenrisc | openrisc-*)\n\t\tbasic_machine=or32-unknown\n\t\t;;\n\tos400)\n\t\tbasic_machine=powerpc-ibm\n\t\tos=-os400\n\t\t;;\n\tOSE68000 | ose68000)\n\t\tbasic_machine=m68000-ericsson\n\t\tos=-ose\n\t\t;;\n\tos68k)\n\t\tbasic_machine=m68k-none\n\t\tos=-os68k\n\t\t;;\n\tpa-hitachi)\n\t\tbasic_machine=hppa1.1-hitachi\n\t\tos=-hiuxwe2\n\t\t;;\n\tparagon)\n\t\tbasic_machine=i860-intel\n\t\tos=-osf\n\t\t;;\n\tpbd)\n\t\tbasic_machine=sparc-tti\n\t\t;;\n\tpbb)\n\t\tbasic_machine=m68k-tti\n\t\t;;\n\tpc532 | pc532-*)\n\t\tbasic_machine=ns32k-pc532\n\t\t;;\n\tpc98)\n\t\tbasic_machine=i386-pc\n\t\t;;\n\tpc98-*)\n\t\tbasic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentium | p5 | k5 | k6 | nexgen | viac3)\n\t\tbasic_machine=i586-pc\n\t\t;;\n\tpentiumpro | p6 | 6x86 | athlon | athlon_*)\n\t\tbasic_machine=i686-pc\n\t\t;;\n\tpentiumii | pentium2 | pentiumiii | pentium3)\n\t\tbasic_machine=i686-pc\n\t\t;;\n\tpentium4)\n\t\tbasic_machine=i786-pc\n\t\t;;\n\tpentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)\n\t\tbasic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentiumpro-* | p6-* | 6x86-* | athlon-*)\n\t\tbasic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)\n\t\tbasic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpentium4-*)\n\t\tbasic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tpn)\n\t\tbasic_machine=pn-gould\n\t\t;;\n\tpower)\tbasic_machine=power-ibm\n\t\t;;\n\tppc)\tbasic_machine=powerpc-unknown\n\t\t;;\n\tppc-*)\tbasic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppcle | powerpclittle | ppc-le | powerpc-little)\n\t\tbasic_machine=powerpcle-unknown\n\t\t;;\n\tppcle-* | powerpclittle-*)\n\t\tbasic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppc64)\tbasic_machine=powerpc64-unknown\n\t\t;;\n\tppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tppc64le | powerpc64little | ppc64-le | powerpc64-little)\n\t\tbasic_machine=powerpc64le-unknown\n\t\t;;\n\tppc64le-* | powerpc64little-*)\n\t\tbasic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`\n\t\t;;\n\tps2)\n\t\tbasic_machine=i386-ibm\n\t\t;;\n\tpw32)\n\t\tbasic_machine=i586-unknown\n\t\tos=-pw32\n\t\t;;\n\trdos)\n\t\tbasic_machine=i386-pc\n\t\tos=-rdos\n\t\t;;\n\trom68k)\n\t\tbasic_machine=m68k-rom68k\n\t\tos=-coff\n\t\t;;\n\trm[46]00)\n\t\tbasic_machine=mips-siemens\n\t\t;;\n\trtpc | rtpc-*)\n\t\tbasic_machine=romp-ibm\n\t\t;;\n\ts390 | s390-*)\n\t\tbasic_machine=s390-ibm\n\t\t;;\n\ts390x | s390x-*)\n\t\tbasic_machine=s390x-ibm\n\t\t;;\n\tsa29200)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tsb1)\n\t\tbasic_machine=mipsisa64sb1-unknown\n\t\t;;\n\tsb1el)\n\t\tbasic_machine=mipsisa64sb1el-unknown\n\t\t;;\n\tsde)\n\t\tbasic_machine=mipsisa32-sde\n\t\tos=-elf\n\t\t;;\n\tsei)\n\t\tbasic_machine=mips-sei\n\t\tos=-seiux\n\t\t;;\n\tsequent)\n\t\tbasic_machine=i386-sequent\n\t\t;;\n\tsh)\n\t\tbasic_machine=sh-hitachi\n\t\tos=-hms\n\t\t;;\n\tsh5el)\n\t\tbasic_machine=sh5le-unknown\n\t\t;;\n\tsh64)\n\t\tbasic_machine=sh64-unknown\n\t\t;;\n\tsparclite-wrs | simso-wrs)\n\t\tbasic_machine=sparclite-wrs\n\t\tos=-vxworks\n\t\t;;\n\tsps7)\n\t\tbasic_machine=m68k-bull\n\t\tos=-sysv2\n\t\t;;\n\tspur)\n\t\tbasic_machine=spur-unknown\n\t\t;;\n\tst2000)\n\t\tbasic_machine=m68k-tandem\n\t\t;;\n\tstratus)\n\t\tbasic_machine=i860-stratus\n\t\tos=-sysv4\n\t\t;;\n\tsun2)\n\t\tbasic_machine=m68000-sun\n\t\t;;\n\tsun2os3)\n\t\tbasic_machine=m68000-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun2os4)\n\t\tbasic_machine=m68000-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun3os3)\n\t\tbasic_machine=m68k-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun3os4)\n\t\tbasic_machine=m68k-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun4os3)\n\t\tbasic_machine=sparc-sun\n\t\tos=-sunos3\n\t\t;;\n\tsun4os4)\n\t\tbasic_machine=sparc-sun\n\t\tos=-sunos4\n\t\t;;\n\tsun4sol2)\n\t\tbasic_machine=sparc-sun\n\t\tos=-solaris2\n\t\t;;\n\tsun3 | sun3-*)\n\t\tbasic_machine=m68k-sun\n\t\t;;\n\tsun4)\n\t\tbasic_machine=sparc-sun\n\t\t;;\n\tsun386 | sun386i | roadrunner)\n\t\tbasic_machine=i386-sun\n\t\t;;\n\tsv1)\n\t\tbasic_machine=sv1-cray\n\t\tos=-unicos\n\t\t;;\n\tsymmetry)\n\t\tbasic_machine=i386-sequent\n\t\tos=-dynix\n\t\t;;\n\tt3e)\n\t\tbasic_machine=alphaev5-cray\n\t\tos=-unicos\n\t\t;;\n\tt90)\n\t\tbasic_machine=t90-cray\n\t\tos=-unicos\n\t\t;;\n\ttic54x | c54x*)\n\t\tbasic_machine=tic54x-unknown\n\t\tos=-coff\n\t\t;;\n\ttic55x | c55x*)\n\t\tbasic_machine=tic55x-unknown\n\t\tos=-coff\n\t\t;;\n\ttic6x | c6x*)\n\t\tbasic_machine=tic6x-unknown\n\t\tos=-coff\n\t\t;;\n\ttx39)\n\t\tbasic_machine=mipstx39-unknown\n\t\t;;\n\ttx39el)\n\t\tbasic_machine=mipstx39el-unknown\n\t\t;;\n\ttoad1)\n\t\tbasic_machine=pdp10-xkl\n\t\tos=-tops20\n\t\t;;\n\ttower | tower-32)\n\t\tbasic_machine=m68k-ncr\n\t\t;;\n\ttpf)\n\t\tbasic_machine=s390x-ibm\n\t\tos=-tpf\n\t\t;;\n\tudi29k)\n\t\tbasic_machine=a29k-amd\n\t\tos=-udi\n\t\t;;\n\tultra3)\n\t\tbasic_machine=a29k-nyu\n\t\tos=-sym1\n\t\t;;\n\tv810 | necv810)\n\t\tbasic_machine=v810-nec\n\t\tos=-none\n\t\t;;\n\tvaxv)\n\t\tbasic_machine=vax-dec\n\t\tos=-sysv\n\t\t;;\n\tvms)\n\t\tbasic_machine=vax-dec\n\t\tos=-vms\n\t\t;;\n\tvpp*|vx|vx-*)\n\t\tbasic_machine=f301-fujitsu\n\t\t;;\n\tvxworks960)\n\t\tbasic_machine=i960-wrs\n\t\tos=-vxworks\n\t\t;;\n\tvxworks68)\n\t\tbasic_machine=m68k-wrs\n\t\tos=-vxworks\n\t\t;;\n\tvxworks29k)\n\t\tbasic_machine=a29k-wrs\n\t\tos=-vxworks\n\t\t;;\n\tw65*)\n\t\tbasic_machine=w65-wdc\n\t\tos=-none\n\t\t;;\n\tw89k-*)\n\t\tbasic_machine=hppa1.1-winbond\n\t\tos=-proelf\n\t\t;;\n\txbox)\n\t\tbasic_machine=i686-pc\n\t\tos=-mingw32\n\t\t;;\n\txps | xps100)\n\t\tbasic_machine=xps100-honeywell\n\t\t;;\n\tymp)\n\t\tbasic_machine=ymp-cray\n\t\tos=-unicos\n\t\t;;\n\tz8k-*-coff)\n\t\tbasic_machine=z8k-unknown\n\t\tos=-sim\n\t\t;;\n\tnone)\n\t\tbasic_machine=none-none\n\t\tos=-none\n\t\t;;\n\n# Here we handle the default manufacturer of certain CPU types.  It is in\n# some cases the only manufacturer, in others, it is the most popular.\n\tw89k)\n\t\tbasic_machine=hppa1.1-winbond\n\t\t;;\n\top50n)\n\t\tbasic_machine=hppa1.1-oki\n\t\t;;\n\top60c)\n\t\tbasic_machine=hppa1.1-oki\n\t\t;;\n\tromp)\n\t\tbasic_machine=romp-ibm\n\t\t;;\n\tmmix)\n\t\tbasic_machine=mmix-knuth\n\t\t;;\n\trs6000)\n\t\tbasic_machine=rs6000-ibm\n\t\t;;\n\tvax)\n\t\tbasic_machine=vax-dec\n\t\t;;\n\tpdp10)\n\t\t# there are many clones, so DEC is not a safe bet\n\t\tbasic_machine=pdp10-unknown\n\t\t;;\n\tpdp11)\n\t\tbasic_machine=pdp11-dec\n\t\t;;\n\twe32k)\n\t\tbasic_machine=we32k-att\n\t\t;;\n\tsh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)\n\t\tbasic_machine=sh-unknown\n\t\t;;\n\tsparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)\n\t\tbasic_machine=sparc-sun\n\t\t;;\n\tcydra)\n\t\tbasic_machine=cydra-cydrome\n\t\t;;\n\torion)\n\t\tbasic_machine=orion-highlevel\n\t\t;;\n\torion105)\n\t\tbasic_machine=clipper-highlevel\n\t\t;;\n\tmac | mpw | mac-mpw)\n\t\tbasic_machine=m68k-apple\n\t\t;;\n\tpmac | pmac-mpw)\n\t\tbasic_machine=powerpc-apple\n\t\t;;\n\t*-unknown)\n\t\t# Make sure to match an already-canonicalized machine name.\n\t\t;;\n\t*)\n\t\techo Invalid configuration \\`$1\\': machine \\`$basic_machine\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\nesac\n\n# Here we canonicalize certain aliases for manufacturers.\ncase $basic_machine in\n\t*-digital*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`\n\t\t;;\n\t*-commodore*)\n\t\tbasic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`\n\t\t;;\n\t*)\n\t\t;;\nesac\n\n# Decode manufacturer-specific aliases for certain operating systems.\n\nif [ x\"$os\" != x\"\" ]\nthen\ncase $os in\n        # First match some system type aliases\n        # that might get confused with valid system types.\n\t# -solaris* is a basic system type, with this one exception.\n\t-solaris1 | -solaris1.*)\n\t\tos=`echo $os | sed -e 's|solaris1|sunos4|'`\n\t\t;;\n\t-solaris)\n\t\tos=-solaris2\n\t\t;;\n\t-svr4*)\n\t\tos=-sysv4\n\t\t;;\n\t-unixware*)\n\t\tos=-sysv4.2uw\n\t\t;;\n\t-gnu/linux*)\n\t\tos=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`\n\t\t;;\n\t# First accept the basic system types.\n\t# The portable systems comes first.\n\t# Each alternative MUST END IN A *, to match a version number.\n\t# -sysv* is not here because it comes later, after sysvr4.\n\t-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \\\n\t      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\\\n\t      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \\\n\t      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \\\n\t      | -aos* \\\n\t      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \\\n\t      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \\\n\t      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \\\n\t      | -openbsd* | -solidbsd* \\\n\t      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \\\n\t      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \\\n\t      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \\\n\t      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \\\n\t      | -chorusos* | -chorusrdb* \\\n\t      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \\\n\t      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \\\n\t      | -uxpv* | -beos* | -mpeix* | -udk* \\\n\t      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \\\n\t      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \\\n\t      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \\\n\t      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \\\n\t      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \\\n\t      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \\\n\t      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)\n\t# Remember, each alternative MUST END IN *, to match a version number.\n\t\t;;\n\t-qnx*)\n\t\tcase $basic_machine in\n\t\t    x86-* | i*86-*)\n\t\t\t;;\n\t\t    *)\n\t\t\tos=-nto$os\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t-nto-qnx*)\n\t\t;;\n\t-nto*)\n\t\tos=`echo $os | sed -e 's|nto|nto-qnx|'`\n\t\t;;\n\t-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \\\n\t      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \\\n\t      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)\n\t\t;;\n\t-mac*)\n\t\tos=`echo $os | sed -e 's|mac|macos|'`\n\t\t;;\n\t-linux-dietlibc)\n\t\tos=-linux-dietlibc\n\t\t;;\n\t-linux*)\n\t\tos=`echo $os | sed -e 's|linux|linux-gnu|'`\n\t\t;;\n\t-sunos5*)\n\t\tos=`echo $os | sed -e 's|sunos5|solaris2|'`\n\t\t;;\n\t-sunos6*)\n\t\tos=`echo $os | sed -e 's|sunos6|solaris3|'`\n\t\t;;\n\t-opened*)\n\t\tos=-openedition\n\t\t;;\n        -os400*)\n\t\tos=-os400\n\t\t;;\n\t-wince*)\n\t\tos=-wince\n\t\t;;\n\t-osfrose*)\n\t\tos=-osfrose\n\t\t;;\n\t-osf*)\n\t\tos=-osf\n\t\t;;\n\t-utek*)\n\t\tos=-bsd\n\t\t;;\n\t-dynix*)\n\t\tos=-bsd\n\t\t;;\n\t-acis*)\n\t\tos=-aos\n\t\t;;\n\t-atheos*)\n\t\tos=-atheos\n\t\t;;\n\t-syllable*)\n\t\tos=-syllable\n\t\t;;\n\t-386bsd)\n\t\tos=-bsd\n\t\t;;\n\t-ctix* | -uts*)\n\t\tos=-sysv\n\t\t;;\n\t-nova*)\n\t\tos=-rtmk-nova\n\t\t;;\n\t-ns2 )\n\t\tos=-nextstep2\n\t\t;;\n\t-nsk*)\n\t\tos=-nsk\n\t\t;;\n\t# Preserve the version number of sinix5.\n\t-sinix5.*)\n\t\tos=`echo $os | sed -e 's|sinix|sysv|'`\n\t\t;;\n\t-sinix*)\n\t\tos=-sysv4\n\t\t;;\n        -tpf*)\n\t\tos=-tpf\n\t\t;;\n\t-triton*)\n\t\tos=-sysv3\n\t\t;;\n\t-oss*)\n\t\tos=-sysv3\n\t\t;;\n\t-svr4)\n\t\tos=-sysv4\n\t\t;;\n\t-svr3)\n\t\tos=-sysv3\n\t\t;;\n\t-sysvr4)\n\t\tos=-sysv4\n\t\t;;\n\t# This must come after -sysvr4.\n\t-sysv*)\n\t\t;;\n\t-ose*)\n\t\tos=-ose\n\t\t;;\n\t-es1800*)\n\t\tos=-ose\n\t\t;;\n\t-xenix)\n\t\tos=-xenix\n\t\t;;\n\t-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)\n\t\tos=-mint\n\t\t;;\n\t-aros*)\n\t\tos=-aros\n\t\t;;\n\t-kaos*)\n\t\tos=-kaos\n\t\t;;\n\t-zvmoe)\n\t\tos=-zvmoe\n\t\t;;\n\t-none)\n\t\t;;\n\t*)\n\t\t# Get rid of the `-' at the beginning of $os.\n\t\tos=`echo $os | sed 's/[^-]*-//'`\n\t\techo Invalid configuration \\`$1\\': system \\`$os\\' not recognized 1>&2\n\t\texit 1\n\t\t;;\nesac\nelse\n\n# Here we handle the default operating systems that come with various machines.\n# The value should be what the vendor currently ships out the door with their\n# machine or put another way, the most popular os provided with the machine.\n\n# Note that if you're going to try to match \"-MANUFACTURER\" here (say,\n# \"-sun\"), then you have to tell the case statement up towards the top\n# that MANUFACTURER isn't an operating system.  Otherwise, code above\n# will signal an error saying that MANUFACTURER isn't an operating\n# system, and we'll never get to this point.\n\ncase $basic_machine in\n        score-*)\n\t\tos=-elf\n\t\t;;\n        spu-*)\n\t\tos=-elf\n\t\t;;\n\t*-acorn)\n\t\tos=-riscix1.2\n\t\t;;\n\tarm*-rebel)\n\t\tos=-linux\n\t\t;;\n\tarm*-semi)\n\t\tos=-aout\n\t\t;;\n        c4x-* | tic4x-*)\n        \tos=-coff\n\t\t;;\n\t# This must come before the *-dec entry.\n\tpdp10-*)\n\t\tos=-tops20\n\t\t;;\n\tpdp11-*)\n\t\tos=-none\n\t\t;;\n\t*-dec | vax-*)\n\t\tos=-ultrix4.2\n\t\t;;\n\tm68*-apollo)\n\t\tos=-domain\n\t\t;;\n\ti386-sun)\n\t\tos=-sunos4.0.2\n\t\t;;\n\tm68000-sun)\n\t\tos=-sunos3\n\t\t# This also exists in the configure program, but was not the\n\t\t# default.\n\t\t# os=-sunos4\n\t\t;;\n\tm68*-cisco)\n\t\tos=-aout\n\t\t;;\n        mep-*)\n\t\tos=-elf\n\t\t;;\n\tmips*-cisco)\n\t\tos=-elf\n\t\t;;\n\tmips*-*)\n\t\tos=-elf\n\t\t;;\n\tor32-*)\n\t\tos=-coff\n\t\t;;\n\t*-tti)\t# must be before sparc entry or we get the wrong os.\n\t\tos=-sysv3\n\t\t;;\n\tsparc-* | *-sun)\n\t\tos=-sunos4.1.1\n\t\t;;\n\t*-be)\n\t\tos=-beos\n\t\t;;\n\t*-haiku)\n\t\tos=-haiku\n\t\t;;\n\t*-ibm)\n\t\tos=-aix\n\t\t;;\n    \t*-knuth)\n\t\tos=-mmixware\n\t\t;;\n\t*-wec)\n\t\tos=-proelf\n\t\t;;\n\t*-winbond)\n\t\tos=-proelf\n\t\t;;\n\t*-oki)\n\t\tos=-proelf\n\t\t;;\n\t*-hp)\n\t\tos=-hpux\n\t\t;;\n\t*-hitachi)\n\t\tos=-hiux\n\t\t;;\n\ti860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)\n\t\tos=-sysv\n\t\t;;\n\t*-cbm)\n\t\tos=-amigaos\n\t\t;;\n\t*-dg)\n\t\tos=-dgux\n\t\t;;\n\t*-dolphin)\n\t\tos=-sysv3\n\t\t;;\n\tm68k-ccur)\n\t\tos=-rtu\n\t\t;;\n\tm88k-omron*)\n\t\tos=-luna\n\t\t;;\n\t*-next )\n\t\tos=-nextstep\n\t\t;;\n\t*-sequent)\n\t\tos=-ptx\n\t\t;;\n\t*-crds)\n\t\tos=-unos\n\t\t;;\n\t*-ns)\n\t\tos=-genix\n\t\t;;\n\ti370-*)\n\t\tos=-mvs\n\t\t;;\n\t*-next)\n\t\tos=-nextstep3\n\t\t;;\n\t*-gould)\n\t\tos=-sysv\n\t\t;;\n\t*-highlevel)\n\t\tos=-bsd\n\t\t;;\n\t*-encore)\n\t\tos=-bsd\n\t\t;;\n\t*-sgi)\n\t\tos=-irix\n\t\t;;\n\t*-siemens)\n\t\tos=-sysv4\n\t\t;;\n\t*-masscomp)\n\t\tos=-rtu\n\t\t;;\n\tf30[01]-fujitsu | f700-fujitsu)\n\t\tos=-uxpv\n\t\t;;\n\t*-rom68k)\n\t\tos=-coff\n\t\t;;\n\t*-*bug)\n\t\tos=-coff\n\t\t;;\n\t*-apple)\n\t\tos=-macos\n\t\t;;\n\t*-atari*)\n\t\tos=-mint\n\t\t;;\n\t*)\n\t\tos=-none\n\t\t;;\nesac\nfi\n\n# Here we handle the case where we know the os, and the CPU type, but not the\n# manufacturer.  We pick the logical manufacturer.\nvendor=unknown\ncase $basic_machine in\n\t*-unknown)\n\t\tcase $os in\n\t\t\t-riscix*)\n\t\t\t\tvendor=acorn\n\t\t\t\t;;\n\t\t\t-sunos*)\n\t\t\t\tvendor=sun\n\t\t\t\t;;\n\t\t\t-aix*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-beos*)\n\t\t\t\tvendor=be\n\t\t\t\t;;\n\t\t\t-hpux*)\n\t\t\t\tvendor=hp\n\t\t\t\t;;\n\t\t\t-mpeix*)\n\t\t\t\tvendor=hp\n\t\t\t\t;;\n\t\t\t-hiux*)\n\t\t\t\tvendor=hitachi\n\t\t\t\t;;\n\t\t\t-unos*)\n\t\t\t\tvendor=crds\n\t\t\t\t;;\n\t\t\t-dgux*)\n\t\t\t\tvendor=dg\n\t\t\t\t;;\n\t\t\t-luna*)\n\t\t\t\tvendor=omron\n\t\t\t\t;;\n\t\t\t-genix*)\n\t\t\t\tvendor=ns\n\t\t\t\t;;\n\t\t\t-mvs* | -opened*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-os400*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-ptx*)\n\t\t\t\tvendor=sequent\n\t\t\t\t;;\n\t\t\t-tpf*)\n\t\t\t\tvendor=ibm\n\t\t\t\t;;\n\t\t\t-vxsim* | -vxworks* | -windiss*)\n\t\t\t\tvendor=wrs\n\t\t\t\t;;\n\t\t\t-aux*)\n\t\t\t\tvendor=apple\n\t\t\t\t;;\n\t\t\t-hms*)\n\t\t\t\tvendor=hitachi\n\t\t\t\t;;\n\t\t\t-mpw* | -macos*)\n\t\t\t\tvendor=apple\n\t\t\t\t;;\n\t\t\t-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)\n\t\t\t\tvendor=atari\n\t\t\t\t;;\n\t\t\t-vos*)\n\t\t\t\tvendor=stratus\n\t\t\t\t;;\n\t\tesac\n\t\tbasic_machine=`echo $basic_machine | sed \"s/unknown/$vendor/\"`\n\t\t;;\nesac\n\necho $basic_machine$os\nexit\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"timestamp='\"\n# time-stamp-format: \"%:y-%02m-%02d\"\n# time-stamp-end: \"'\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/configure",
    "content": "#! /bin/sh\n# Guess values for system-dependent variables and create Makefiles.\n# Generated by GNU Autoconf 2.65 for google-perftools 1.7.\n#\n# Report bugs to <opensource@google.com>.\n#\n#\n# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,\n# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,\n# Inc.\n#\n#\n# This configure script is free software; the Free Software Foundation\n# gives unlimited permission to copy, distribute and modify it.\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nif test \"x$CONFIG_SHELL\" = x; then\n  as_bourne_compatible=\"if test -n \\\"\\${ZSH_VERSION+set}\\\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on \\${1+\\\"\\$@\\\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '\\${1+\\\"\\$@\\\"}'='\\\"\\$@\\\"'\n  setopt NO_GLOB_SUBST\nelse\n  case \\`(set -o) 2>/dev/null\\` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\"\n  as_required=\"as_fn_return () { (exit \\$1); }\nas_fn_success () { as_fn_return 0; }\nas_fn_failure () { as_fn_return 1; }\nas_fn_ret_success () { return 0; }\nas_fn_ret_failure () { return 1; }\n\nexitcode=0\nas_fn_success || { exitcode=1; echo as_fn_success failed.; }\nas_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }\nas_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }\nas_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }\nif ( set x; as_fn_ret_success y && test x = \\\"\\$1\\\" ); then :\n\nelse\n  exitcode=1; echo positional parameters were not saved.\nfi\ntest x\\$exitcode = x0 || exit 1\"\n  as_suggested=\"  as_lineno_1=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_1a=\\$LINENO\n  as_lineno_2=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_2a=\\$LINENO\n  eval 'test \\\"x\\$as_lineno_1'\\$as_run'\\\" != \\\"x\\$as_lineno_2'\\$as_run'\\\" &&\n  test \\\"x\\`expr \\$as_lineno_1'\\$as_run' + 1\\`\\\" = \\\"x\\$as_lineno_2'\\$as_run'\\\"' || exit 1\ntest \\$(( 1 + 1 )) = 2 || exit 1\"\n  if (eval \"$as_required\") 2>/dev/null; then :\n  as_have_required=yes\nelse\n  as_have_required=no\nfi\n  if test x$as_have_required = xyes && (eval \"$as_suggested\") 2>/dev/null; then :\n\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nas_found=false\nfor as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  as_found=:\n  case $as_dir in #(\n\t /*)\n\t   for as_base in sh bash ksh sh5; do\n\t     # Try only shells that exist, to save several forks.\n\t     as_shell=$as_dir/$as_base\n\t     if { test -f \"$as_shell\" || test -f \"$as_shell.exe\"; } &&\n\t\t    { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$as_shell as_have_required=yes\n\t\t   if { $as_echo \"$as_bourne_compatible\"\"$as_suggested\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  break 2\nfi\nfi\n\t   done;;\n       esac\n  as_found=false\ndone\n$as_found || { if { test -f \"$SHELL\" || test -f \"$SHELL.exe\"; } &&\n\t      { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$SHELL\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$SHELL as_have_required=yes\nfi; }\nIFS=$as_save_IFS\n\n\n      if test \"x$CONFIG_SHELL\" != x; then :\n  # We cannot yet assume a decent shell, so we have to provide a\n\t# neutralization value for shells without unset; and this also\n\t# works around shells that cannot unset nonexistent variables.\n\tBASH_ENV=/dev/null\n\tENV=/dev/null\n\t(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV\n\texport CONFIG_SHELL\n\texec \"$CONFIG_SHELL\" \"$as_myself\" ${1+\"$@\"}\nfi\n\n    if test x$as_have_required = xno; then :\n  $as_echo \"$0: This script requires a shell more modern than all\"\n  $as_echo \"$0: the shells that I found on your system.\"\n  if test x${ZSH_VERSION+set} = xset ; then\n    $as_echo \"$0: In particular, zsh $ZSH_VERSION has bugs and should\"\n    $as_echo \"$0: be upgraded to zsh 4.3.4 or later.\"\n  else\n    $as_echo \"$0: Please tell bug-autoconf@gnu.org and\n$0: opensource@google.com about your system, including any\n$0: error possibly output before this message. Then install\n$0: a modern shell, or manually run the script under such a\n$0: shell if you do have one.\"\n  fi\n  exit 1\nfi\nfi\nfi\nSHELL=${CONFIG_SHELL-/bin/sh}\nexport SHELL\n# Unset more variables known to interfere with behavior of common tools.\nCLICOLOR_FORCE= GREP_OPTIONS=\nunset CLICOLOR_FORCE GREP_OPTIONS\n\n## --------------------- ##\n## M4sh Shell Functions. ##\n## --------------------- ##\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\n# as_fn_error ERROR [LINENO LOG_FD]\n# ---------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with status $?, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$?; test $as_status -eq 0 && as_status=1\n  if test \"$3\"; then\n    as_lineno=${as_lineno-\"$2\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $1\" >&$3\n  fi\n  $as_echo \"$as_me: error: $1\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\n\n  as_lineno_1=$LINENO as_lineno_1a=$LINENO\n  as_lineno_2=$LINENO as_lineno_2a=$LINENO\n  eval 'test \"x$as_lineno_1'$as_run'\" != \"x$as_lineno_2'$as_run'\" &&\n  test \"x`expr $as_lineno_1'$as_run' + 1`\" = \"x$as_lineno_2'$as_run'\"' || {\n  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)\n  sed -n '\n    p\n    /[$]LINENO/=\n  ' <$as_myself |\n    sed '\n      s/[$]LINENO.*/&-/\n      t lineno\n      b\n      :lineno\n      N\n      :loop\n      s/[$]LINENO\\([^'$as_cr_alnum'_].*\\n\\)\\(.*\\)/\\2\\1\\2/\n      t loop\n      s/-\\n.*//\n    ' >$as_me.lineno &&\n  chmod +x \"$as_me.lineno\" ||\n    { $as_echo \"$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&2; as_fn_exit 1; }\n\n  # Don't try to exec as it changes $[0], causing all sort of problems\n  # (the dirname of $[0] is not the place where we might find the\n  # original and so on.  Autoconf is especially sensitive to this).\n  . \"./$as_me.lineno\"\n  # Exit status is that of the last command.\n  exit\n}\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -p'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -p'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -p'\n  fi\nelse\n  as_ln_s='cp -p'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nif test -x / >/dev/null 2>&1; then\n  as_test_x='test -x'\nelse\n  if ls -dL / >/dev/null 2>&1; then\n    as_ls_L_option=L\n  else\n    as_ls_L_option=\n  fi\n  as_test_x='\n    eval sh -c '\\''\n      if test -d \"$1\"; then\n\ttest -d \"$1/.\";\n      else\n\tcase $1 in #(\n\t-*)set \"./$1\";;\n\tesac;\n\tcase `ls -ld'$as_ls_L_option' \"$1\" 2>/dev/null` in #((\n\t???[sx]*):;;*)false;;esac;fi\n    '\\'' sh\n  '\nfi\nas_executable_p=$as_test_x\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\n\n# Check that we are running under the correct shell.\nSHELL=${CONFIG_SHELL-/bin/sh}\n\ncase X$lt_ECHO in\nX*--fallback-echo)\n  # Remove one level of quotation (which was required for Make).\n  ECHO=`echo \"$lt_ECHO\" | sed 's,\\\\\\\\\\$\\\\$0,'$0','`\n  ;;\nesac\n\nECHO=${lt_ECHO-echo}\nif test \"X$1\" = X--no-reexec; then\n  # Discard the --no-reexec flag, and continue.\n  shift\nelif test \"X$1\" = X--fallback-echo; then\n  # Avoid inline document here, it may be left over\n  :\nelif test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t' ; then\n  # Yippee, $ECHO works!\n  :\nelse\n  # Restart under the correct shell.\n  exec $SHELL \"$0\" --no-reexec ${1+\"$@\"}\nfi\n\nif test \"X$1\" = X--fallback-echo; then\n  # used as fallback echo\n  shift\n  cat <<_LT_EOF\n$*\n_LT_EOF\n  exit 0\nfi\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nif test -z \"$lt_ECHO\"; then\n  if test \"X${echo_test_string+set}\" != Xset; then\n    # find a string as large as possible, as long as the shell can cope with it\n    for cmd in 'sed 50q \"$0\"' 'sed 20q \"$0\"' 'sed 10q \"$0\"' 'sed 2q \"$0\"' 'echo test'; do\n      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...\n      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&\n\t { test \"X$echo_test_string\" = \"X$echo_test_string\"; } 2>/dev/null\n      then\n        break\n      fi\n    done\n  fi\n\n  if test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t' &&\n     echo_testing_string=`{ $ECHO \"$echo_test_string\"; } 2>/dev/null` &&\n     test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n    :\n  else\n    # The Solaris, AIX, and Digital Unix default echo programs unquote\n    # backslashes.  This makes it impossible to quote backslashes using\n    #   echo \"$something\" | sed 's/\\\\/\\\\\\\\/g'\n    #\n    # So, first we look for a working echo in the user's PATH.\n\n    lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n    for dir in $PATH /usr/ucb; do\n      IFS=\"$lt_save_ifs\"\n      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&\n         test \"X`($dir/echo '\\t') 2>/dev/null`\" = 'X\\t' &&\n         echo_testing_string=`($dir/echo \"$echo_test_string\") 2>/dev/null` &&\n         test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n        ECHO=\"$dir/echo\"\n        break\n      fi\n    done\n    IFS=\"$lt_save_ifs\"\n\n    if test \"X$ECHO\" = Xecho; then\n      # We didn't find a better echo, so look for alternatives.\n      if test \"X`{ print -r '\\t'; } 2>/dev/null`\" = 'X\\t' &&\n         echo_testing_string=`{ print -r \"$echo_test_string\"; } 2>/dev/null` &&\n         test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n        # This shell has a builtin print -r that does the trick.\n        ECHO='print -r'\n      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&\n\t   test \"X$CONFIG_SHELL\" != X/bin/ksh; then\n        # If we have ksh, try running configure again with it.\n        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}\n        export ORIGINAL_CONFIG_SHELL\n        CONFIG_SHELL=/bin/ksh\n        export CONFIG_SHELL\n        exec $CONFIG_SHELL \"$0\" --no-reexec ${1+\"$@\"}\n      else\n        # Try using printf.\n        ECHO='printf %s\\n'\n        if test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t' &&\n\t   echo_testing_string=`{ $ECHO \"$echo_test_string\"; } 2>/dev/null` &&\n\t   test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n\t  # Cool, printf works\n\t  :\n        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL \"$0\" --fallback-echo '\\t') 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = 'X\\t' &&\n\t     echo_testing_string=`($ORIGINAL_CONFIG_SHELL \"$0\" --fallback-echo \"$echo_test_string\") 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n\t  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL\n\t  export CONFIG_SHELL\n\t  SHELL=\"$CONFIG_SHELL\"\n\t  export SHELL\n\t  ECHO=\"$CONFIG_SHELL $0 --fallback-echo\"\n        elif echo_testing_string=`($CONFIG_SHELL \"$0\" --fallback-echo '\\t') 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = 'X\\t' &&\n\t     echo_testing_string=`($CONFIG_SHELL \"$0\" --fallback-echo \"$echo_test_string\") 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n\t  ECHO=\"$CONFIG_SHELL $0 --fallback-echo\"\n        else\n\t  # maybe with a smaller string...\n\t  prev=:\n\n\t  for cmd in 'echo test' 'sed 2q \"$0\"' 'sed 10q \"$0\"' 'sed 20q \"$0\"' 'sed 50q \"$0\"'; do\n\t    if { test \"X$echo_test_string\" = \"X`eval $cmd`\"; } 2>/dev/null\n\t    then\n\t      break\n\t    fi\n\t    prev=\"$cmd\"\n\t  done\n\n\t  if test \"$prev\" != 'sed 50q \"$0\"'; then\n\t    echo_test_string=`eval $prev`\n\t    export echo_test_string\n\t    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} \"$0\" ${1+\"$@\"}\n\t  else\n\t    # Oops.  We lost completely, so just stick with echo.\n\t    ECHO=echo\n\t  fi\n        fi\n      fi\n    fi\n  fi\nfi\n\n# Copy echo and quote the copy suitably for passing to libtool from\n# the Makefile, instead of quoting the original, which is used later.\nlt_ECHO=$ECHO\nif test \"X$lt_ECHO\" = \"X$CONFIG_SHELL $0 --fallback-echo\"; then\n   lt_ECHO=\"$CONFIG_SHELL \\\\\\$\\$0 --fallback-echo\"\nfi\n\n\n\n\ntest -n \"$DJDIR\" || exec 7<&0 </dev/null\nexec 6>&1\n\n# Name of the host.\n# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,\n# so uname gets run too.\nac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`\n\n#\n# Initializations.\n#\nac_default_prefix=/usr/local\nac_clean_files=\nac_config_libobj_dir=.\nLIBOBJS=\ncross_compiling=no\nsubdirs=\nMFLAGS=\nMAKEFLAGS=\n\n# Identity of this package.\nPACKAGE_NAME='google-perftools'\nPACKAGE_TARNAME='google-perftools'\nPACKAGE_VERSION='1.7'\nPACKAGE_STRING='google-perftools 1.7'\nPACKAGE_BUGREPORT='opensource@google.com'\nPACKAGE_URL=''\n\nac_unique_file=\"README\"\n# Factoring default headers for most tests.\nac_includes_default=\"\\\n#include <stdio.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# ifdef HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#ifdef HAVE_STRING_H\n# if !defined STDC_HEADERS && defined HAVE_MEMORY_H\n#  include <memory.h>\n# endif\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#endif\n#ifdef HAVE_STDINT_H\n# include <stdint.h>\n#endif\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\"\n\nac_header_list=\nac_subst_vars='LTLIBOBJS\nLIBOBJS\nWITH_STACK_TRACE_FALSE\nWITH_STACK_TRACE_TRUE\nWITH_HEAP_PROFILER_OR_CHECKER_FALSE\nWITH_HEAP_PROFILER_OR_CHECKER_TRUE\nWITH_DEBUGALLOC_FALSE\nWITH_DEBUGALLOC_TRUE\nWITH_HEAP_CHECKER_FALSE\nWITH_HEAP_CHECKER_TRUE\nWITH_HEAP_PROFILER_FALSE\nWITH_HEAP_PROFILER_TRUE\nWITH_CPU_PROFILER_FALSE\nWITH_CPU_PROFILER_TRUE\nMINGW_FALSE\nMINGW_TRUE\nPTHREAD_CFLAGS\nPTHREAD_LIBS\nPTHREAD_CC\nacx_pthread_config\nLIBSTDCXX_LA_LINKER_FLAG\nNANOSLEEP_LIBS\nX86_64_AND_NO_FP_BY_DEFAULT_FALSE\nX86_64_AND_NO_FP_BY_DEFAULT_TRUE\nENABLE_FRAME_POINTERS_FALSE\nENABLE_FRAME_POINTERS_TRUE\nUNWIND_LIBS\nENABLE_STATIC_FALSE\nENABLE_STATIC_TRUE\nac_cv_have_struct_mallinfo\nUSE_LIBTOOL_FALSE\nUSE_LIBTOOL_TRUE\nLIBTOOL_DEPS\nCXXCPP\nOTOOL64\nOTOOL\nLIPO\nNMEDIT\nDSYMUTIL\nlt_ECHO\nRANLIB\nAR\nOBJDUMP\nLN_S\nNM\nac_ct_DUMPBIN\nDUMPBIN\nLD\nFGREP\nEGREP\nGREP\nSED\nLIBTOOL\nHAVE_OBJCOPY_WEAKEN_FALSE\nHAVE_OBJCOPY_WEAKEN_TRUE\nOBJCOPY\nGCC_FALSE\nGCC_TRUE\nam__fastdepCXX_FALSE\nam__fastdepCXX_TRUE\nCXXDEPMODE\nac_ct_CXX\nCXXFLAGS\nCXX\nCPP\nam__fastdepCC_FALSE\nam__fastdepCC_TRUE\nCCDEPMODE\nAMDEPBACKSLASH\nAMDEP_FALSE\nAMDEP_TRUE\nam__quote\nam__include\nDEPDIR\nOBJEXT\nEXEEXT\nac_ct_CC\nCPPFLAGS\nLDFLAGS\nCFLAGS\nCC\nTC_VERSION_PATCH\nTC_VERSION_MINOR\nTC_VERSION_MAJOR\nam__untar\nam__tar\nAMTAR\nam__leading_dot\nSET_MAKE\nAWK\nmkdir_p\nINSTALL_STRIP_PROGRAM\nSTRIP\ninstall_sh\nMAKEINFO\nAUTOHEADER\nAUTOMAKE\nAUTOCONF\nACLOCAL\nVERSION\nPACKAGE\nCYGPATH_W\nINSTALL_DATA\nINSTALL_SCRIPT\nINSTALL_PROGRAM\nhost_os\nhost_vendor\nhost_cpu\nhost\nbuild_os\nbuild_vendor\nbuild_cpu\nbuild\nPROFILER_SO_VERSION\nTCMALLOC_SO_VERSION\ntarget_alias\nhost_alias\nbuild_alias\nLIBS\nECHO_T\nECHO_N\nECHO_C\nDEFS\nmandir\nlocaledir\nlibdir\npsdir\npdfdir\ndvidir\nhtmldir\ninfodir\ndocdir\noldincludedir\nincludedir\nlocalstatedir\nsharedstatedir\nsysconfdir\ndatadir\ndatarootdir\nlibexecdir\nsbindir\nbindir\nprogram_transform_name\nprefix\nexec_prefix\nPACKAGE_URL\nPACKAGE_BUGREPORT\nPACKAGE_STRING\nPACKAGE_VERSION\nPACKAGE_TARNAME\nPACKAGE_NAME\nPATH_SEPARATOR\nSHELL'\nac_subst_files=''\nac_user_opts='\nenable_option_checking\nenable_cpu_profiler\nenable_heap_profiler\nenable_heap_checker\nenable_debugalloc\nenable_minimal\nenable_dependency_tracking\nenable_fast_install\nenable_shared\nenable_static\nwith_pic\nwith_gnu_ld\nenable_libtool_lock\nenable_frame_pointers\n'\n      ac_precious_vars='build_alias\nhost_alias\ntarget_alias\nCC\nCFLAGS\nLDFLAGS\nLIBS\nCPPFLAGS\nCPP\nCXX\nCXXFLAGS\nCCC\nCXXCPP'\n\n\n# Initialize some variables set by options.\nac_init_help=\nac_init_version=false\nac_unrecognized_opts=\nac_unrecognized_sep=\n# The variables have the same names as the options, with\n# dashes changed to underlines.\ncache_file=/dev/null\nexec_prefix=NONE\nno_create=\nno_recursion=\nprefix=NONE\nprogram_prefix=NONE\nprogram_suffix=NONE\nprogram_transform_name=s,x,x,\nsilent=\nsite=\nsrcdir=\nverbose=\nx_includes=NONE\nx_libraries=NONE\n\n# Installation directory options.\n# These are left unexpanded so users can \"make install exec_prefix=/foo\"\n# and all the variables that are supposed to be based on exec_prefix\n# by default will actually change.\n# Use braces instead of parens because sh, perl, etc. also accept them.\n# (The list follows the same order as the GNU Coding Standards.)\nbindir='${exec_prefix}/bin'\nsbindir='${exec_prefix}/sbin'\nlibexecdir='${exec_prefix}/libexec'\ndatarootdir='${prefix}/share'\ndatadir='${datarootdir}'\nsysconfdir='${prefix}/etc'\nsharedstatedir='${prefix}/com'\nlocalstatedir='${prefix}/var'\nincludedir='${prefix}/include'\noldincludedir='/usr/include'\ndocdir='${datarootdir}/doc/${PACKAGE_TARNAME}'\ninfodir='${datarootdir}/info'\nhtmldir='${docdir}'\ndvidir='${docdir}'\npdfdir='${docdir}'\npsdir='${docdir}'\nlibdir='${exec_prefix}/lib'\nlocaledir='${datarootdir}/locale'\nmandir='${datarootdir}/man'\n\nac_prev=\nac_dashdash=\nfor ac_option\ndo\n  # If the previous option needs an argument, assign it.\n  if test -n \"$ac_prev\"; then\n    eval $ac_prev=\\$ac_option\n    ac_prev=\n    continue\n  fi\n\n  case $ac_option in\n  *=*)\tac_optarg=`expr \"X$ac_option\" : '[^=]*=\\(.*\\)'` ;;\n  *)\tac_optarg=yes ;;\n  esac\n\n  # Accept the important Cygnus configure options, so we can diagnose typos.\n\n  case $ac_dashdash$ac_option in\n  --)\n    ac_dashdash=yes ;;\n\n  -bindir | --bindir | --bindi | --bind | --bin | --bi)\n    ac_prev=bindir ;;\n  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)\n    bindir=$ac_optarg ;;\n\n  -build | --build | --buil | --bui | --bu)\n    ac_prev=build_alias ;;\n  -build=* | --build=* | --buil=* | --bui=* | --bu=*)\n    build_alias=$ac_optarg ;;\n\n  -cache-file | --cache-file | --cache-fil | --cache-fi \\\n  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)\n    ac_prev=cache_file ;;\n  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \\\n  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)\n    cache_file=$ac_optarg ;;\n\n  --config-cache | -C)\n    cache_file=config.cache ;;\n\n  -datadir | --datadir | --datadi | --datad)\n    ac_prev=datadir ;;\n  -datadir=* | --datadir=* | --datadi=* | --datad=*)\n    datadir=$ac_optarg ;;\n\n  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \\\n  | --dataroo | --dataro | --datar)\n    ac_prev=datarootdir ;;\n  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \\\n  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)\n    datarootdir=$ac_optarg ;;\n\n  -disable-* | --disable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*disable-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=no ;;\n\n  -docdir | --docdir | --docdi | --doc | --do)\n    ac_prev=docdir ;;\n  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)\n    docdir=$ac_optarg ;;\n\n  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)\n    ac_prev=dvidir ;;\n  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)\n    dvidir=$ac_optarg ;;\n\n  -enable-* | --enable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*enable-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=\\$ac_optarg ;;\n\n  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \\\n  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \\\n  | --exec | --exe | --ex)\n    ac_prev=exec_prefix ;;\n  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \\\n  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \\\n  | --exec=* | --exe=* | --ex=*)\n    exec_prefix=$ac_optarg ;;\n\n  -gas | --gas | --ga | --g)\n    # Obsolete; use --with-gas.\n    with_gas=yes ;;\n\n  -help | --help | --hel | --he | -h)\n    ac_init_help=long ;;\n  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)\n    ac_init_help=recursive ;;\n  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)\n    ac_init_help=short ;;\n\n  -host | --host | --hos | --ho)\n    ac_prev=host_alias ;;\n  -host=* | --host=* | --hos=* | --ho=*)\n    host_alias=$ac_optarg ;;\n\n  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)\n    ac_prev=htmldir ;;\n  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \\\n  | --ht=*)\n    htmldir=$ac_optarg ;;\n\n  -includedir | --includedir | --includedi | --included | --include \\\n  | --includ | --inclu | --incl | --inc)\n    ac_prev=includedir ;;\n  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \\\n  | --includ=* | --inclu=* | --incl=* | --inc=*)\n    includedir=$ac_optarg ;;\n\n  -infodir | --infodir | --infodi | --infod | --info | --inf)\n    ac_prev=infodir ;;\n  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)\n    infodir=$ac_optarg ;;\n\n  -libdir | --libdir | --libdi | --libd)\n    ac_prev=libdir ;;\n  -libdir=* | --libdir=* | --libdi=* | --libd=*)\n    libdir=$ac_optarg ;;\n\n  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \\\n  | --libexe | --libex | --libe)\n    ac_prev=libexecdir ;;\n  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \\\n  | --libexe=* | --libex=* | --libe=*)\n    libexecdir=$ac_optarg ;;\n\n  -localedir | --localedir | --localedi | --localed | --locale)\n    ac_prev=localedir ;;\n  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)\n    localedir=$ac_optarg ;;\n\n  -localstatedir | --localstatedir | --localstatedi | --localstated \\\n  | --localstate | --localstat | --localsta | --localst | --locals)\n    ac_prev=localstatedir ;;\n  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \\\n  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)\n    localstatedir=$ac_optarg ;;\n\n  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)\n    ac_prev=mandir ;;\n  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)\n    mandir=$ac_optarg ;;\n\n  -nfp | --nfp | --nf)\n    # Obsolete; use --without-fp.\n    with_fp=no ;;\n\n  -no-create | --no-create | --no-creat | --no-crea | --no-cre \\\n  | --no-cr | --no-c | -n)\n    no_create=yes ;;\n\n  -no-recursion | --no-recursion | --no-recursio | --no-recursi \\\n  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)\n    no_recursion=yes ;;\n\n  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \\\n  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \\\n  | --oldin | --oldi | --old | --ol | --o)\n    ac_prev=oldincludedir ;;\n  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \\\n  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \\\n  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)\n    oldincludedir=$ac_optarg ;;\n\n  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)\n    ac_prev=prefix ;;\n  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)\n    prefix=$ac_optarg ;;\n\n  -program-prefix | --program-prefix | --program-prefi | --program-pref \\\n  | --program-pre | --program-pr | --program-p)\n    ac_prev=program_prefix ;;\n  -program-prefix=* | --program-prefix=* | --program-prefi=* \\\n  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)\n    program_prefix=$ac_optarg ;;\n\n  -program-suffix | --program-suffix | --program-suffi | --program-suff \\\n  | --program-suf | --program-su | --program-s)\n    ac_prev=program_suffix ;;\n  -program-suffix=* | --program-suffix=* | --program-suffi=* \\\n  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)\n    program_suffix=$ac_optarg ;;\n\n  -program-transform-name | --program-transform-name \\\n  | --program-transform-nam | --program-transform-na \\\n  | --program-transform-n | --program-transform- \\\n  | --program-transform | --program-transfor \\\n  | --program-transfo | --program-transf \\\n  | --program-trans | --program-tran \\\n  | --progr-tra | --program-tr | --program-t)\n    ac_prev=program_transform_name ;;\n  -program-transform-name=* | --program-transform-name=* \\\n  | --program-transform-nam=* | --program-transform-na=* \\\n  | --program-transform-n=* | --program-transform-=* \\\n  | --program-transform=* | --program-transfor=* \\\n  | --program-transfo=* | --program-transf=* \\\n  | --program-trans=* | --program-tran=* \\\n  | --progr-tra=* | --program-tr=* | --program-t=*)\n    program_transform_name=$ac_optarg ;;\n\n  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)\n    ac_prev=pdfdir ;;\n  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)\n    pdfdir=$ac_optarg ;;\n\n  -psdir | --psdir | --psdi | --psd | --ps)\n    ac_prev=psdir ;;\n  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)\n    psdir=$ac_optarg ;;\n\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil)\n    silent=yes ;;\n\n  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)\n    ac_prev=sbindir ;;\n  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \\\n  | --sbi=* | --sb=*)\n    sbindir=$ac_optarg ;;\n\n  -sharedstatedir | --sharedstatedir | --sharedstatedi \\\n  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \\\n  | --sharedst | --shareds | --shared | --share | --shar \\\n  | --sha | --sh)\n    ac_prev=sharedstatedir ;;\n  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \\\n  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \\\n  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \\\n  | --sha=* | --sh=*)\n    sharedstatedir=$ac_optarg ;;\n\n  -site | --site | --sit)\n    ac_prev=site ;;\n  -site=* | --site=* | --sit=*)\n    site=$ac_optarg ;;\n\n  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)\n    ac_prev=srcdir ;;\n  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)\n    srcdir=$ac_optarg ;;\n\n  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \\\n  | --syscon | --sysco | --sysc | --sys | --sy)\n    ac_prev=sysconfdir ;;\n  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \\\n  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)\n    sysconfdir=$ac_optarg ;;\n\n  -target | --target | --targe | --targ | --tar | --ta | --t)\n    ac_prev=target_alias ;;\n  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)\n    target_alias=$ac_optarg ;;\n\n  -v | -verbose | --verbose | --verbos | --verbo | --verb)\n    verbose=yes ;;\n\n  -version | --version | --versio | --versi | --vers | -V)\n    ac_init_version=: ;;\n\n  -with-* | --with-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*with-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=\\$ac_optarg ;;\n\n  -without-* | --without-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*without-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=no ;;\n\n  --x)\n    # Obsolete; use --with-x.\n    with_x=yes ;;\n\n  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \\\n  | --x-incl | --x-inc | --x-in | --x-i)\n    ac_prev=x_includes ;;\n  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \\\n  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)\n    x_includes=$ac_optarg ;;\n\n  -x-libraries | --x-libraries | --x-librarie | --x-librari \\\n  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)\n    ac_prev=x_libraries ;;\n  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \\\n  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)\n    x_libraries=$ac_optarg ;;\n\n  -*) as_fn_error \"unrecognized option: \\`$ac_option'\nTry \\`$0 --help' for more information.\"\n    ;;\n\n  *=*)\n    ac_envvar=`expr \"x$ac_option\" : 'x\\([^=]*\\)='`\n    # Reject names that are not valid shell variable names.\n    case $ac_envvar in #(\n      '' | [0-9]* | *[!_$as_cr_alnum]* )\n      as_fn_error \"invalid variable name: \\`$ac_envvar'\" ;;\n    esac\n    eval $ac_envvar=\\$ac_optarg\n    export $ac_envvar ;;\n\n  *)\n    # FIXME: should be removed in autoconf 3.0.\n    $as_echo \"$as_me: WARNING: you should use --build, --host, --target\" >&2\n    expr \"x$ac_option\" : \".*[^-._$as_cr_alnum]\" >/dev/null &&\n      $as_echo \"$as_me: WARNING: invalid host type: $ac_option\" >&2\n    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}\n    ;;\n\n  esac\ndone\n\nif test -n \"$ac_prev\"; then\n  ac_option=--`echo $ac_prev | sed 's/_/-/g'`\n  as_fn_error \"missing argument to $ac_option\"\nfi\n\nif test -n \"$ac_unrecognized_opts\"; then\n  case $enable_option_checking in\n    no) ;;\n    fatal) as_fn_error \"unrecognized options: $ac_unrecognized_opts\" ;;\n    *)     $as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2 ;;\n  esac\nfi\n\n# Check all directory arguments for consistency.\nfor ac_var in\texec_prefix prefix bindir sbindir libexecdir datarootdir \\\n\t\tdatadir sysconfdir sharedstatedir localstatedir includedir \\\n\t\toldincludedir docdir infodir htmldir dvidir pdfdir psdir \\\n\t\tlibdir localedir mandir\ndo\n  eval ac_val=\\$$ac_var\n  # Remove trailing slashes.\n  case $ac_val in\n    */ )\n      ac_val=`expr \"X$ac_val\" : 'X\\(.*[^/]\\)' \\| \"X$ac_val\" : 'X\\(.*\\)'`\n      eval $ac_var=\\$ac_val;;\n  esac\n  # Be sure to have absolute directory names.\n  case $ac_val in\n    [\\\\/$]* | ?:[\\\\/]* )  continue;;\n    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;\n  esac\n  as_fn_error \"expected an absolute directory name for --$ac_var: $ac_val\"\ndone\n\n# There might be people who depend on the old broken behavior: `$host'\n# used to hold the argument of --host etc.\n# FIXME: To remove some day.\nbuild=$build_alias\nhost=$host_alias\ntarget=$target_alias\n\n# FIXME: To remove some day.\nif test \"x$host_alias\" != x; then\n  if test \"x$build_alias\" = x; then\n    cross_compiling=maybe\n    $as_echo \"$as_me: WARNING: If you wanted to set the --build type, don't use --host.\n    If a cross compiler is detected then cross compile mode will be used.\" >&2\n  elif test \"x$build_alias\" != \"x$host_alias\"; then\n    cross_compiling=yes\n  fi\nfi\n\nac_tool_prefix=\ntest -n \"$host_alias\" && ac_tool_prefix=$host_alias-\n\ntest \"$silent\" = yes && exec 6>/dev/null\n\n\nac_pwd=`pwd` && test -n \"$ac_pwd\" &&\nac_ls_di=`ls -di .` &&\nac_pwd_ls_di=`cd \"$ac_pwd\" && ls -di .` ||\n  as_fn_error \"working directory cannot be determined\"\ntest \"X$ac_ls_di\" = \"X$ac_pwd_ls_di\" ||\n  as_fn_error \"pwd does not report name of working directory\"\n\n\n# Find the source files, if location was not specified.\nif test -z \"$srcdir\"; then\n  ac_srcdir_defaulted=yes\n  # Try the directory containing this script, then the parent directory.\n  ac_confdir=`$as_dirname -- \"$as_myself\" ||\n$as_expr X\"$as_myself\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_myself\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_myself\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  srcdir=$ac_confdir\n  if test ! -r \"$srcdir/$ac_unique_file\"; then\n    srcdir=..\n  fi\nelse\n  ac_srcdir_defaulted=no\nfi\nif test ! -r \"$srcdir/$ac_unique_file\"; then\n  test \"$ac_srcdir_defaulted\" = yes && srcdir=\"$ac_confdir or ..\"\n  as_fn_error \"cannot find sources ($ac_unique_file) in $srcdir\"\nfi\nac_msg=\"sources are in $srcdir, but \\`cd $srcdir' does not work\"\nac_abs_confdir=`(\n\tcd \"$srcdir\" && test -r \"./$ac_unique_file\" || as_fn_error \"$ac_msg\"\n\tpwd)`\n# When building in place, set srcdir=.\nif test \"$ac_abs_confdir\" = \"$ac_pwd\"; then\n  srcdir=.\nfi\n# Remove unnecessary trailing slashes from srcdir.\n# Double slashes in file names in object file debugging info\n# mess up M-x gdb in Emacs.\ncase $srcdir in\n*/) srcdir=`expr \"X$srcdir\" : 'X\\(.*[^/]\\)' \\| \"X$srcdir\" : 'X\\(.*\\)'`;;\nesac\nfor ac_var in $ac_precious_vars; do\n  eval ac_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_env_${ac_var}_value=\\$${ac_var}\n  eval ac_cv_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_cv_env_${ac_var}_value=\\$${ac_var}\ndone\n\n#\n# Report the --help message.\n#\nif test \"$ac_init_help\" = \"long\"; then\n  # Omit some internal or obsolete options to make the list less imposing.\n  # This message is too long to be a string in the A/UX 3.1 sh.\n  cat <<_ACEOF\n\\`configure' configures google-perftools 1.7 to adapt to many kinds of systems.\n\nUsage: $0 [OPTION]... [VAR=VALUE]...\n\nTo assign environment variables (e.g., CC, CFLAGS...), specify them as\nVAR=VALUE.  See below for descriptions of some of the useful variables.\n\nDefaults for the options are specified in brackets.\n\nConfiguration:\n  -h, --help              display this help and exit\n      --help=short        display options specific to this package\n      --help=recursive    display the short help of all the included packages\n  -V, --version           display version information and exit\n  -q, --quiet, --silent   do not print \\`checking...' messages\n      --cache-file=FILE   cache test results in FILE [disabled]\n  -C, --config-cache      alias for \\`--cache-file=config.cache'\n  -n, --no-create         do not create output files\n      --srcdir=DIR        find the sources in DIR [configure dir or \\`..']\n\nInstallation directories:\n  --prefix=PREFIX         install architecture-independent files in PREFIX\n                          [$ac_default_prefix]\n  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX\n                          [PREFIX]\n\nBy default, \\`make install' will install all the files in\n\\`$ac_default_prefix/bin', \\`$ac_default_prefix/lib' etc.  You can specify\nan installation prefix other than \\`$ac_default_prefix' using \\`--prefix',\nfor instance \\`--prefix=\\$HOME'.\n\nFor better control, use the options below.\n\nFine tuning of the installation directories:\n  --bindir=DIR            user executables [EPREFIX/bin]\n  --sbindir=DIR           system admin executables [EPREFIX/sbin]\n  --libexecdir=DIR        program executables [EPREFIX/libexec]\n  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]\n  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]\n  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]\n  --libdir=DIR            object code libraries [EPREFIX/lib]\n  --includedir=DIR        C header files [PREFIX/include]\n  --oldincludedir=DIR     C header files for non-gcc [/usr/include]\n  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]\n  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]\n  --infodir=DIR           info documentation [DATAROOTDIR/info]\n  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]\n  --mandir=DIR            man documentation [DATAROOTDIR/man]\n  --docdir=DIR            documentation root\n                          [DATAROOTDIR/doc/google-perftools]\n  --htmldir=DIR           html documentation [DOCDIR]\n  --dvidir=DIR            dvi documentation [DOCDIR]\n  --pdfdir=DIR            pdf documentation [DOCDIR]\n  --psdir=DIR             ps documentation [DOCDIR]\n_ACEOF\n\n  cat <<\\_ACEOF\n\nProgram names:\n  --program-prefix=PREFIX            prepend PREFIX to installed program names\n  --program-suffix=SUFFIX            append SUFFIX to installed program names\n  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names\n\nSystem types:\n  --build=BUILD     configure for building on BUILD [guessed]\n  --host=HOST       cross-compile to build programs to run on HOST [BUILD]\n_ACEOF\nfi\n\nif test -n \"$ac_init_help\"; then\n  case $ac_init_help in\n     short | recursive ) echo \"Configuration of google-perftools 1.7:\";;\n   esac\n  cat <<\\_ACEOF\n\nOptional Features:\n  --disable-option-checking  ignore unrecognized --enable/--with options\n  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)\n  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]\n  --disable-cpu-profiler  do not build the cpu profiler\n  --disable-heap-profiler do not build the heap profiler\n  --disable-heap-checker  do not build the heap checker\n  --disable-debugalloc    do not build versions of libs with debugalloc\n  --enable-minimal        build only tcmalloc-minimal (and maybe\n                          tcmalloc-minimal-debug)\n  --disable-dependency-tracking  speeds up one-time build\n  --enable-dependency-tracking   do not reject slow dependency extractors\n  --enable-fast-install[=PKGS]\n                          optimize for fast installation [default=no]\n  --enable-shared[=PKGS]  build shared libraries [default=yes]\n  --enable-static[=PKGS]  build static libraries [default=yes]\n  --disable-libtool-lock  avoid locking (might break parallel builds)\n  --enable-frame-pointers On x86_64 systems, compile with\n                          -fno-omit-frame-pointer (see INSTALL)\n\nOptional Packages:\n  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]\n  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)\n  --with-pic              try to use only PIC/non-PIC objects [default=use\n                          both]\n  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]\n\nSome influential environment variables:\n  CC          C compiler command\n  CFLAGS      C compiler flags\n  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a\n              nonstandard directory <lib dir>\n  LIBS        libraries to pass to the linker, e.g. -l<library>\n  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if\n              you have headers in a nonstandard directory <include dir>\n  CPP         C preprocessor\n  CXX         C++ compiler command\n  CXXFLAGS    C++ compiler flags\n  CXXCPP      C++ preprocessor\n\nUse these variables to override the choices made by `configure' or to help\nit to find libraries and programs with nonstandard names/locations.\n\nReport bugs to <opensource@google.com>.\n_ACEOF\nac_status=$?\nfi\n\nif test \"$ac_init_help\" = \"recursive\"; then\n  # If there are subdirs, report their specific --help.\n  for ac_dir in : $ac_subdirs_all; do test \"x$ac_dir\" = x: && continue\n    test -d \"$ac_dir\" ||\n      { cd \"$srcdir\" && ac_pwd=`pwd` && srcdir=. && test -d \"$ac_dir\"; } ||\n      continue\n    ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n    cd \"$ac_dir\" || { ac_status=$?; continue; }\n    # Check for guested configure.\n    if test -f \"$ac_srcdir/configure.gnu\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure.gnu\" --help=recursive\n    elif test -f \"$ac_srcdir/configure\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure\" --help=recursive\n    else\n      $as_echo \"$as_me: WARNING: no configuration information is in $ac_dir\" >&2\n    fi || ac_status=$?\n    cd \"$ac_pwd\" || { ac_status=$?; break; }\n  done\nfi\n\ntest -n \"$ac_init_help\" && exit $ac_status\nif $ac_init_version; then\n  cat <<\\_ACEOF\ngoogle-perftools configure 1.7\ngenerated by GNU Autoconf 2.65\n\nCopyright (C) 2009 Free Software Foundation, Inc.\nThis configure script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\n_ACEOF\n  exit\nfi\n\n## ------------------------ ##\n## Autoconf initialization. ##\n## ------------------------ ##\n\n# ac_fn_c_try_compile LINENO\n# --------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_compile\n\n# ac_fn_c_try_cpp LINENO\n# ----------------------\n# Try to preprocess conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_cpp ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_cpp conftest.$ac_ext\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_cpp conftest.$ac_ext\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } >/dev/null && {\n\t test -z \"$ac_c_preproc_warn_flag$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n    ac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_cpp\n\n# ac_fn_cxx_try_compile LINENO\n# ----------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_cxx_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_cxx_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_compile\n\n# ac_fn_c_try_link LINENO\n# -----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_link ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext conftest$ac_exeext\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest$ac_exeext && {\n\t test \"$cross_compiling\" = yes ||\n\t $as_test_x conftest$ac_exeext\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information\n  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would\n  # interfere with the next link command; also delete a directory that is\n  # left behind by Apple's compiler.  We do this before executing the actions.\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_link\n\n# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists and can be compiled using the include files in\n# INCLUDES, setting the cache variable VAR accordingly.\nac_fn_c_check_header_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_header_compile\n\n# ac_fn_c_try_run LINENO\n# ----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes\n# that executables *can* be run.\nac_fn_c_try_run ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: program exited with status $ac_status\" >&5\n       $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n       ac_retval=$ac_status\nfi\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_run\n\n# ac_fn_c_check_func LINENO FUNC VAR\n# ----------------------------------\n# Tests whether FUNC exists, setting the cache variable VAR accordingly\nac_fn_c_check_func ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n/* Define $2 to an innocuous variant, in case <limits.h> declares $2.\n   For example, HP-UX 11i <limits.h> declares gettimeofday.  */\n#define $2 innocuous_$2\n\n/* System header to define __stub macros and hopefully few prototypes,\n    which can conflict with char $2 (); below.\n    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n    <limits.h> exists even on freestanding compilers.  */\n\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\n#undef $2\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar $2 ();\n/* The GNU C library defines this for functions which it implements\n    to always fail with ENOSYS.  Some functions are actually named\n    something starting with __ and the normal name is an alias.  */\n#if defined __stub_$2 || defined __stub___$2\nchoke me\n#endif\n\nint\nmain ()\n{\nreturn $2 ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_func\n\n# ac_fn_cxx_try_cpp LINENO\n# ------------------------\n# Try to preprocess conftest.$ac_ext, and return whether this succeeded.\nac_fn_cxx_try_cpp ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_cpp conftest.$ac_ext\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_cpp conftest.$ac_ext\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } >/dev/null && {\n\t test -z \"$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag\" ||\n\t test ! -s conftest.err\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n    ac_retval=1\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_cpp\n\n# ac_fn_cxx_try_link LINENO\n# -------------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded.\nac_fn_cxx_try_link ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext conftest$ac_exeext\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_cxx_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest$ac_exeext && {\n\t test \"$cross_compiling\" = yes ||\n\t $as_test_x conftest$ac_exeext\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information\n  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would\n  # interfere with the next link command; also delete a directory that is\n  # left behind by Apple's compiler.  We do this before executing the actions.\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_link\n\n# ac_fn_c_check_type LINENO TYPE VAR INCLUDES\n# -------------------------------------------\n# Tests whether TYPE exists after having included INCLUDES, setting cache\n# variable VAR accordingly.\nac_fn_c_check_type ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  eval \"$3=no\"\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\nint\nmain ()\n{\nif (sizeof ($2))\n\t return 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\nint\nmain ()\n{\nif (sizeof (($2)))\n\t    return 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\nelse\n  eval \"$3=yes\"\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_type\n\n# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists, giving a warning if it cannot be compiled using\n# the include files in INCLUDES and setting the cache variable VAR\n# accordingly.\nac_fn_c_check_header_mongrel ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nelse\n  # Is the header compilable?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 usability\" >&5\n$as_echo_n \"checking $2 usability... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_header_compiler=yes\nelse\n  ac_header_compiler=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler\" >&5\n$as_echo \"$ac_header_compiler\" >&6; }\n\n# Is the header present?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 presence\" >&5\n$as_echo_n \"checking $2 presence... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <$2>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  ac_header_preproc=yes\nelse\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc\" >&5\n$as_echo \"$ac_header_preproc\" >&6; }\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((\n  yes:no: )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&5\n$as_echo \"$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n    ;;\n  no:yes:* )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled\" >&5\n$as_echo \"$as_me: WARNING: $2: present but cannot be compiled\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?\" >&5\n$as_echo \"$as_me: WARNING: $2:     check for missing prerequisite headers?\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation\" >&5\n$as_echo \"$as_me: WARNING: $2: see the Autoconf documentation\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\n$as_echo \"$as_me: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n( cat <<\\_ASBOX\n## ------------------------------------ ##\n## Report this to opensource@google.com ##\n## ------------------------------------ ##\n_ASBOX\n     ) | sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  eval \"$3=\\$ac_header_compiler\"\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nfi\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_header_mongrel\n\n# ac_fn_c_check_decl LINENO SYMBOL VAR\n# ------------------------------------\n# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.\nac_fn_c_check_decl ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $2 is declared\" >&5\n$as_echo_n \"checking whether $2 is declared... \" >&6; }\nif { as_var=$3; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\nint\nmain ()\n{\n#ifndef $2\n  (void) $2;\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; test \"x$as_lineno_stack\" = x && { as_lineno=; unset as_lineno;}\n\n} # ac_fn_c_check_decl\ncat >config.log <<_ACEOF\nThis file contains any messages produced by compilers while\nrunning configure, to aid debugging if configure makes a mistake.\n\nIt was created by google-perftools $as_me 1.7, which was\ngenerated by GNU Autoconf 2.65.  Invocation command line was\n\n  $ $0 $@\n\n_ACEOF\nexec 5>>config.log\n{\ncat <<_ASUNAME\n## --------- ##\n## Platform. ##\n## --------- ##\n\nhostname = `(hostname || uname -n) 2>/dev/null | sed 1q`\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`\n\n/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`\n/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`\n/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`\n/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`\n\n_ASUNAME\n\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    $as_echo \"PATH: $as_dir\"\n  done\nIFS=$as_save_IFS\n\n} >&5\n\ncat >&5 <<_ACEOF\n\n\n## ----------- ##\n## Core tests. ##\n## ----------- ##\n\n_ACEOF\n\n\n# Keep a trace of the command line.\n# Strip out --no-create and --no-recursion so they do not pile up.\n# Strip out --silent because we don't want to record it for future runs.\n# Also quote any args containing shell meta-characters.\n# Make two passes to allow for proper duplicate-argument suppression.\nac_configure_args=\nac_configure_args0=\nac_configure_args1=\nac_must_keep_next=false\nfor ac_pass in 1 2\ndo\n  for ac_arg\n  do\n    case $ac_arg in\n    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;\n    -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n    | -silent | --silent | --silen | --sile | --sil)\n      continue ;;\n    *\\'*)\n      ac_arg=`$as_echo \"$ac_arg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    case $ac_pass in\n    1) as_fn_append ac_configure_args0 \" '$ac_arg'\" ;;\n    2)\n      as_fn_append ac_configure_args1 \" '$ac_arg'\"\n      if test $ac_must_keep_next = true; then\n\tac_must_keep_next=false # Got value, back to normal.\n      else\n\tcase $ac_arg in\n\t  *=* | --config-cache | -C | -disable-* | --disable-* \\\n\t  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \\\n\t  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \\\n\t  | -with-* | --with-* | -without-* | --without-* | --x)\n\t    case \"$ac_configure_args0 \" in\n\t      \"$ac_configure_args1\"*\" '$ac_arg' \"* ) continue ;;\n\t    esac\n\t    ;;\n\t  -* ) ac_must_keep_next=true ;;\n\tesac\n      fi\n      as_fn_append ac_configure_args \" '$ac_arg'\"\n      ;;\n    esac\n  done\ndone\n{ ac_configure_args0=; unset ac_configure_args0;}\n{ ac_configure_args1=; unset ac_configure_args1;}\n\n# When interrupted or exit'd, cleanup temporary files, and complete\n# config.log.  We remove comments because anyway the quotes in there\n# would cause problems or look ugly.\n# WARNING: Use '\\'' to represent an apostrophe within the trap.\n# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.\ntrap 'exit_status=$?\n  # Save into config.log some information that might help in debugging.\n  {\n    echo\n\n    cat <<\\_ASBOX\n## ---------------- ##\n## Cache variables. ##\n## ---------------- ##\n_ASBOX\n    echo\n    # The following way of writing the cache mishandles newlines in values,\n(\n  for ac_var in `(set) 2>&1 | sed -n '\\''s/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'\\''`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n  (set) 2>&1 |\n    case $as_nl`(ac_space='\\'' '\\''; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      sed -n \\\n\t\"s/'\\''/'\\''\\\\\\\\'\\'''\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\''\\\\2'\\''/p\"\n      ;; #(\n    *)\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n)\n    echo\n\n    cat <<\\_ASBOX\n## ----------------- ##\n## Output variables. ##\n## ----------------- ##\n_ASBOX\n    echo\n    for ac_var in $ac_subst_vars\n    do\n      eval ac_val=\\$$ac_var\n      case $ac_val in\n      *\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n      esac\n      $as_echo \"$ac_var='\\''$ac_val'\\''\"\n    done | sort\n    echo\n\n    if test -n \"$ac_subst_files\"; then\n      cat <<\\_ASBOX\n## ------------------- ##\n## File substitutions. ##\n## ------------------- ##\n_ASBOX\n      echo\n      for ac_var in $ac_subst_files\n      do\n\teval ac_val=\\$$ac_var\n\tcase $ac_val in\n\t*\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n\tesac\n\t$as_echo \"$ac_var='\\''$ac_val'\\''\"\n      done | sort\n      echo\n    fi\n\n    if test -s confdefs.h; then\n      cat <<\\_ASBOX\n## ----------- ##\n## confdefs.h. ##\n## ----------- ##\n_ASBOX\n      echo\n      cat confdefs.h\n      echo\n    fi\n    test \"$ac_signal\" != 0 &&\n      $as_echo \"$as_me: caught signal $ac_signal\"\n    $as_echo \"$as_me: exit $exit_status\"\n  } >&5\n  rm -f core *.core core.conftest.* &&\n    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&\n    exit $exit_status\n' 0\nfor ac_signal in 1 2 13 15; do\n  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal\ndone\nac_signal=0\n\n# confdefs.h avoids OS command line length limits that DEFS can exceed.\nrm -f -r conftest* confdefs.h\n\n$as_echo \"/* confdefs.h */\" > confdefs.h\n\n# Predefined preprocessor variables.\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_NAME \"$PACKAGE_NAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_VERSION \"$PACKAGE_VERSION\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_STRING \"$PACKAGE_STRING\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_URL \"$PACKAGE_URL\"\n_ACEOF\n\n\n# Let the site file select an alternate cache file if it wants to.\n# Prefer an explicitly selected file to automatically selected ones.\nac_site_file1=NONE\nac_site_file2=NONE\nif test -n \"$CONFIG_SITE\"; then\n  ac_site_file1=$CONFIG_SITE\nelif test \"x$prefix\" != xNONE; then\n  ac_site_file1=$prefix/share/config.site\n  ac_site_file2=$prefix/etc/config.site\nelse\n  ac_site_file1=$ac_default_prefix/share/config.site\n  ac_site_file2=$ac_default_prefix/etc/config.site\nfi\nfor ac_site_file in \"$ac_site_file1\" \"$ac_site_file2\"\ndo\n  test \"x$ac_site_file\" = xNONE && continue\n  if test /dev/null != \"$ac_site_file\" && test -r \"$ac_site_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file\" >&5\n$as_echo \"$as_me: loading site script $ac_site_file\" >&6;}\n    sed 's/^/| /' \"$ac_site_file\" >&5\n    . \"$ac_site_file\"\n  fi\ndone\n\nif test -r \"$cache_file\"; then\n  # Some versions of bash will fail to source /dev/null (special files\n  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.\n  if test /dev/null != \"$cache_file\" && test -f \"$cache_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading cache $cache_file\" >&5\n$as_echo \"$as_me: loading cache $cache_file\" >&6;}\n    case $cache_file in\n      [\\\\/]* | ?:[\\\\/]* ) . \"$cache_file\";;\n      *)                      . \"./$cache_file\";;\n    esac\n  fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: creating cache $cache_file\" >&5\n$as_echo \"$as_me: creating cache $cache_file\" >&6;}\n  >$cache_file\nfi\n\nas_fn_append ac_header_list \" stdlib.h\"\nas_fn_append ac_header_list \" unistd.h\"\nas_fn_append ac_header_list \" sys/param.h\"\n# Check that the precious variables saved in the cache have kept the same\n# value.\nac_cache_corrupted=false\nfor ac_var in $ac_precious_vars; do\n  eval ac_old_set=\\$ac_cv_env_${ac_var}_set\n  eval ac_new_set=\\$ac_env_${ac_var}_set\n  eval ac_old_val=\\$ac_cv_env_${ac_var}_value\n  eval ac_new_val=\\$ac_env_${ac_var}_value\n  case $ac_old_set,$ac_new_set in\n    set,)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,set)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was not set in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was not set in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,);;\n    *)\n      if test \"x$ac_old_val\" != \"x$ac_new_val\"; then\n\t# differences in whitespace do not lead to failure.\n\tac_old_val_w=`echo x $ac_old_val`\n\tac_new_val_w=`echo x $ac_new_val`\n\tif test \"$ac_old_val_w\" != \"$ac_new_val_w\"; then\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' has changed since the previous run:\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' has changed since the previous run:\" >&2;}\n\t  ac_cache_corrupted=:\n\telse\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&5\n$as_echo \"$as_me: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&2;}\n\t  eval $ac_var=\\$ac_old_val\n\tfi\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   former value:  \\`$ac_old_val'\" >&5\n$as_echo \"$as_me:   former value:  \\`$ac_old_val'\" >&2;}\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   current value: \\`$ac_new_val'\" >&5\n$as_echo \"$as_me:   current value: \\`$ac_new_val'\" >&2;}\n      fi;;\n  esac\n  # Pass precious variables to config.status.\n  if test \"$ac_new_set\" = set; then\n    case $ac_new_val in\n    *\\'*) ac_arg=$ac_var=`$as_echo \"$ac_new_val\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    *) ac_arg=$ac_var=$ac_new_val ;;\n    esac\n    case \" $ac_configure_args \" in\n      *\" '$ac_arg' \"*) ;; # Avoid dups.  Use of quotes ensures accuracy.\n      *) as_fn_append ac_configure_args \" '$ac_arg'\" ;;\n    esac\n  fi\ndone\nif $ac_cache_corrupted; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build\" >&5\n$as_echo \"$as_me: error: changes in the environment can compromise the build\" >&2;}\n  as_fn_error \"run \\`make distclean' and/or \\`rm $cache_file' and start over\" \"$LINENO\" 5\nfi\n## -------------------- ##\n## Main body of script. ##\n## -------------------- ##\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n# Update this value for every release!  (A:B:C will map to foo.so.(A-C).C.B)\n# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html\nTCMALLOC_SO_VERSION=1:0:1\nPROFILER_SO_VERSION=1:0:1\n\n\n\n\n# The argument here is just something that should be in the current directory\n# (for sanity checking)\n\n\nac_aux_dir=\nfor ac_dir in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"; do\n  for ac_t in install-sh install.sh shtool; do\n    if test -f \"$ac_dir/$ac_t\"; then\n      ac_aux_dir=$ac_dir\n      ac_install_sh=\"$ac_aux_dir/$ac_t -c\"\n      break 2\n    fi\n  done\ndone\nif test -z \"$ac_aux_dir\"; then\n  as_fn_error \"cannot find install-sh, install.sh, or shtool in \\\"$srcdir\\\" \\\"$srcdir/..\\\" \\\"$srcdir/../..\\\"\" \"$LINENO\" 5\nfi\n\n# These three variables are undocumented and unsupported,\n# and are intended to be withdrawn in a future Autoconf release.\n# They can cause serious problems if a builder's source tree is in a directory\n# whose full name contains unusual characters.\nac_config_guess=\"$SHELL $ac_aux_dir/config.guess\"  # Please don't use this var.\nac_config_sub=\"$SHELL $ac_aux_dir/config.sub\"  # Please don't use this var.\nac_configure=\"$SHELL $ac_aux_dir/configure\"  # Please don't use this var.\n\n\n# Make sure we can run config.sub.\n$SHELL \"$ac_aux_dir/config.sub\" sun4 >/dev/null 2>&1 ||\n  as_fn_error \"cannot run $SHELL $ac_aux_dir/config.sub\" \"$LINENO\" 5\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking build system type\" >&5\n$as_echo_n \"checking build system type... \" >&6; }\nif test \"${ac_cv_build+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_build_alias=$build_alias\ntest \"x$ac_build_alias\" = x &&\n  ac_build_alias=`$SHELL \"$ac_aux_dir/config.guess\"`\ntest \"x$ac_build_alias\" = x &&\n  as_fn_error \"cannot guess build type; you must specify one\" \"$LINENO\" 5\nac_cv_build=`$SHELL \"$ac_aux_dir/config.sub\" $ac_build_alias` ||\n  as_fn_error \"$SHELL $ac_aux_dir/config.sub $ac_build_alias failed\" \"$LINENO\" 5\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_build\" >&5\n$as_echo \"$ac_cv_build\" >&6; }\ncase $ac_cv_build in\n*-*-*) ;;\n*) as_fn_error \"invalid value of canonical build\" \"$LINENO\" 5;;\nesac\nbuild=$ac_cv_build\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_build\nshift\nbuild_cpu=$1\nbuild_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\nbuild_os=$*\nIFS=$ac_save_IFS\ncase $build_os in *\\ *) build_os=`echo \"$build_os\" | sed 's/ /-/g'`;; esac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking host system type\" >&5\n$as_echo_n \"checking host system type... \" >&6; }\nif test \"${ac_cv_host+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test \"x$host_alias\" = x; then\n  ac_cv_host=$ac_cv_build\nelse\n  ac_cv_host=`$SHELL \"$ac_aux_dir/config.sub\" $host_alias` ||\n    as_fn_error \"$SHELL $ac_aux_dir/config.sub $host_alias failed\" \"$LINENO\" 5\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_host\" >&5\n$as_echo \"$ac_cv_host\" >&6; }\ncase $ac_cv_host in\n*-*-*) ;;\n*) as_fn_error \"invalid value of canonical host\" \"$LINENO\" 5;;\nesac\nhost=$ac_cv_host\nac_save_IFS=$IFS; IFS='-'\nset x $ac_cv_host\nshift\nhost_cpu=$1\nhost_vendor=$2\nshift; shift\n# Remember, the first character of IFS is used to create $*,\n# except with old shells:\nhost_os=$*\nIFS=$ac_save_IFS\ncase $host_os in *\\ *) host_os=`echo \"$host_os\" | sed 's/ /-/g'`;; esac\n\n\nam__api_version=\"1.9\"\n# Find a good install program.  We prefer a C program (faster),\n# so one script is as good as another.  But avoid the broken or\n# incompatible versions:\n# SysV /etc/install, /usr/sbin/install\n# SunOS /usr/etc/install\n# IRIX /sbin/install\n# AIX /bin/install\n# AmigaOS /C/install, which installs bootblocks on floppy discs\n# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag\n# AFS /usr/afsws/bin/install, which mishandles nonexistent args\n# SVR4 /usr/ucb/install, which tries to use the nonexistent group \"staff\"\n# OS/2's system install, which has a completely different semantic\n# ./install, which can be erroneously created by make from ./install.sh.\n# Reject install programs that cannot install multiple files.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install\" >&5\n$as_echo_n \"checking for a BSD-compatible install... \" >&6; }\nif test -z \"$INSTALL\"; then\nif test \"${ac_cv_path_install+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    # Account for people who put trailing slashes in PATH elements.\ncase $as_dir/ in #((\n  ./ | .// | /[cC]/* | \\\n  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \\\n  ?:[\\\\/]os2[\\\\/]install[\\\\/]* | ?:[\\\\/]OS2[\\\\/]INSTALL[\\\\/]* | \\\n  /usr/ucb/* ) ;;\n  *)\n    # OSF1 and SCO ODT 3.0 have their own names for install.\n    # Don't use installbsd from OSF since it installs stuff as root\n    # by default.\n    for ac_prog in ginstall scoinst install; do\n      for ac_exec_ext in '' $ac_executable_extensions; do\n\tif { test -f \"$as_dir/$ac_prog$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_prog$ac_exec_ext\"; }; then\n\t  if test $ac_prog = install &&\n\t    grep dspmsg \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # AIX install.  It has an incompatible calling convention.\n\t    :\n\t  elif test $ac_prog = install &&\n\t    grep pwplus \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # program-specific install script used by HP pwplus--don't use.\n\t    :\n\t  else\n\t    rm -rf conftest.one conftest.two conftest.dir\n\t    echo one > conftest.one\n\t    echo two > conftest.two\n\t    mkdir conftest.dir\n\t    if \"$as_dir/$ac_prog$ac_exec_ext\" -c conftest.one conftest.two \"`pwd`/conftest.dir\" &&\n\t      test -s conftest.one && test -s conftest.two &&\n\t      test -s conftest.dir/conftest.one &&\n\t      test -s conftest.dir/conftest.two\n\t    then\n\t      ac_cv_path_install=\"$as_dir/$ac_prog$ac_exec_ext -c\"\n\t      break 3\n\t    fi\n\t  fi\n\tfi\n      done\n    done\n    ;;\nesac\n\n  done\nIFS=$as_save_IFS\n\nrm -rf conftest.one conftest.two conftest.dir\n\nfi\n  if test \"${ac_cv_path_install+set}\" = set; then\n    INSTALL=$ac_cv_path_install\n  else\n    # As a last resort, use the slow shell script.  Don't cache a\n    # value for INSTALL within a source directory, because that will\n    # break other packages using the cache if that directory is\n    # removed, or if the value is a relative name.\n    INSTALL=$ac_install_sh\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $INSTALL\" >&5\n$as_echo \"$INSTALL\" >&6; }\n\n# Use test -z because SunOS4 sh mishandles braces in ${var-val}.\n# It thinks the first close brace ends the variable substitution.\ntest -z \"$INSTALL_PROGRAM\" && INSTALL_PROGRAM='${INSTALL}'\n\ntest -z \"$INSTALL_SCRIPT\" && INSTALL_SCRIPT='${INSTALL}'\n\ntest -z \"$INSTALL_DATA\" && INSTALL_DATA='${INSTALL} -m 644'\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether build environment is sane\" >&5\n$as_echo_n \"checking whether build environment is sane... \" >&6; }\n# Just in case\nsleep 1\necho timestamp > conftest.file\n# Do `set' in a subshell so we don't clobber the current shell's\n# arguments.  Must try -L first in case configure is actually a\n# symlink; some systems play weird games with the mod time of symlinks\n# (eg FreeBSD returns the mod time of the symlink's containing\n# directory).\nif (\n   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`\n   if test \"$*\" = \"X\"; then\n      # -L didn't work.\n      set X `ls -t $srcdir/configure conftest.file`\n   fi\n   rm -f conftest.file\n   if test \"$*\" != \"X $srcdir/configure conftest.file\" \\\n      && test \"$*\" != \"X conftest.file $srcdir/configure\"; then\n\n      # If neither matched, then we have a broken ls.  This can happen\n      # if, for instance, CONFIG_SHELL is bash and it inherits a\n      # broken ls alias from the environment.  This has actually\n      # happened.  Such a system could not be considered \"sane\".\n      as_fn_error \"ls -t appears to fail.  Make sure there is not a broken\nalias in your environment\" \"$LINENO\" 5\n   fi\n\n   test \"$2\" = conftest.file\n   )\nthen\n   # Ok.\n   :\nelse\n   as_fn_error \"newly created file is older than distributed files!\nCheck your system clock\" \"$LINENO\" 5\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\ntest \"$program_prefix\" != NONE &&\n  program_transform_name=\"s&^&$program_prefix&;$program_transform_name\"\n# Use a double $ so make ignores it.\ntest \"$program_suffix\" != NONE &&\n  program_transform_name=\"s&\\$&$program_suffix&;$program_transform_name\"\n# Double any \\ or $.\n# By default was `s,x,x', remove it if useless.\nac_script='s/[\\\\$]/&&/g;s/;s,x,x,$//'\nprogram_transform_name=`$as_echo \"$program_transform_name\" | sed \"$ac_script\"`\n\n# expand $ac_aux_dir to an absolute path\nam_aux_dir=`cd $ac_aux_dir && pwd`\n\ntest x\"${MISSING+set}\" = xset || MISSING=\"\\${SHELL} $am_aux_dir/missing\"\n# Use eval to expand $SHELL\nif eval \"$MISSING --run true\"; then\n  am_missing_run=\"$MISSING --run \"\nelse\n  am_missing_run=\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: \\`missing' script is too old or missing\" >&5\n$as_echo \"$as_me: WARNING: \\`missing' script is too old or missing\" >&2;}\nfi\n\nif mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then\n  # We used to keeping the `.' as first argument, in order to\n  # allow $(mkdir_p) to be used without argument.  As in\n  #   $(mkdir_p) $(somedir)\n  # where $(somedir) is conditionally defined.  However this is wrong\n  # for two reasons:\n  #  1. if the package is installed by a user who cannot write `.'\n  #     make install will fail,\n  #  2. the above comment should most certainly read\n  #     $(mkdir_p) $(DESTDIR)$(somedir)\n  #     so it does not work when $(somedir) is undefined and\n  #     $(DESTDIR) is not.\n  #  To support the latter case, we have to write\n  #     test -z \"$(somedir)\" || $(mkdir_p) $(DESTDIR)$(somedir),\n  #  so the `.' trick is pointless.\n  mkdir_p='mkdir -p --'\nelse\n  # On NextStep and OpenStep, the `mkdir' command does not\n  # recognize any option.  It will interpret all options as\n  # directories to create, and then abort because `.' already\n  # exists.\n  for d in ./-p ./--version;\n  do\n    test -d $d && rmdir $d\n  done\n  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.\n  if test -f \"$ac_aux_dir/mkinstalldirs\"; then\n    mkdir_p='$(mkinstalldirs)'\n  else\n    mkdir_p='$(install_sh) -d'\n  fi\nfi\n\nfor ac_prog in gawk mawk nawk awk\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_AWK+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$AWK\"; then\n  ac_cv_prog_AWK=\"$AWK\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_AWK=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nAWK=$ac_cv_prog_AWK\nif test -n \"$AWK\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $AWK\" >&5\n$as_echo \"$AWK\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$AWK\" && break\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \\$(MAKE)\" >&5\n$as_echo_n \"checking whether ${MAKE-make} sets \\$(MAKE)... \" >&6; }\nset x ${MAKE-make}\nac_make=`$as_echo \"$2\" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`\nif { as_var=ac_cv_prog_make_${ac_make}_set; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat >conftest.make <<\\_ACEOF\nSHELL = /bin/sh\nall:\n\t@echo '@@@%%%=$(MAKE)=@@@%%%'\n_ACEOF\n# GNU make sometimes prints \"make[1]: Entering...\", which would confuse us.\ncase `${MAKE-make} -f conftest.make 2>/dev/null` in\n  *@@@%%%=?*=@@@%%%*)\n    eval ac_cv_prog_make_${ac_make}_set=yes;;\n  *)\n    eval ac_cv_prog_make_${ac_make}_set=no;;\nesac\nrm -f conftest.make\nfi\nif eval test \\$ac_cv_prog_make_${ac_make}_set = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n  SET_MAKE=\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n  SET_MAKE=\"MAKE=${MAKE-make}\"\nfi\n\nrm -rf .tst 2>/dev/null\nmkdir .tst 2>/dev/null\nif test -d .tst; then\n  am__leading_dot=.\nelse\n  am__leading_dot=_\nfi\nrmdir .tst 2>/dev/null\n\n# test to see if srcdir already configured\nif test \"`cd $srcdir && pwd`\" != \"`pwd`\" &&\n   test -f $srcdir/config.status; then\n  as_fn_error \"source directory already configured; run \\\"make distclean\\\" there first\" \"$LINENO\" 5\nfi\n\n# test whether we have cygpath\nif test -z \"$CYGPATH_W\"; then\n  if (cygpath --version) >/dev/null 2>/dev/null; then\n    CYGPATH_W='cygpath -w'\n  else\n    CYGPATH_W=echo\n  fi\nfi\n\n\n# Define the identity of the package.\n PACKAGE='google-perftools'\n VERSION='1.7'\n\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE \"$PACKAGE\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define VERSION \"$VERSION\"\n_ACEOF\n\n# Some tools Automake needs.\n\nACLOCAL=${ACLOCAL-\"${am_missing_run}aclocal-${am__api_version}\"}\n\n\nAUTOCONF=${AUTOCONF-\"${am_missing_run}autoconf\"}\n\n\nAUTOMAKE=${AUTOMAKE-\"${am_missing_run}automake-${am__api_version}\"}\n\n\nAUTOHEADER=${AUTOHEADER-\"${am_missing_run}autoheader\"}\n\n\nMAKEINFO=${MAKEINFO-\"${am_missing_run}makeinfo\"}\n\ninstall_sh=${install_sh-\"$am_aux_dir/install-sh\"}\n\n# Installed binaries are usually stripped using `strip' when the user\n# run `make install-strip'.  However `strip' might not be the right\n# tool to use in cross-compilation environments, therefore Automake\n# will honor the `STRIP' environment variable to overrule this program.\nif test \"$cross_compiling\" != no; then\n  if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}strip\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$STRIP\"; then\n  ac_cv_prog_STRIP=\"$STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_STRIP=\"${ac_tool_prefix}strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nSTRIP=$ac_cv_prog_STRIP\nif test -n \"$STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $STRIP\" >&5\n$as_echo \"$STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_STRIP\"; then\n  ac_ct_STRIP=$STRIP\n  # Extract the first word of \"strip\", so it can be a program name with args.\nset dummy strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_STRIP\"; then\n  ac_cv_prog_ac_ct_STRIP=\"$ac_ct_STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_STRIP=\"strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP\nif test -n \"$ac_ct_STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP\" >&5\n$as_echo \"$ac_ct_STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_STRIP\" = x; then\n    STRIP=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    STRIP=$ac_ct_STRIP\n  fi\nelse\n  STRIP=\"$ac_cv_prog_STRIP\"\nfi\n\nfi\nINSTALL_STRIP_PROGRAM=\"\\${SHELL} \\$(install_sh) -c -s\"\n\n# We need awk for the \"check\" target.  The system \"awk\" is bad on\n# some platforms.\n# Always define AMTAR for backward compatibility.\n\nAMTAR=${AMTAR-\"${am_missing_run}tar\"}\n\nam__tar='${AMTAR} chof - \"$$tardir\"'; am__untar='${AMTAR} xf -'\n\n\n\n\n\nac_config_headers=\"$ac_config_headers src/config.h\"\n\n\n# Export the version information (for tc_version and friends)\nTC_VERSION_MAJOR=`expr \"$PACKAGE_VERSION\" : '\\([0-9]*\\)'`\nTC_VERSION_MINOR=`expr \"$PACKAGE_VERSION\" : '[^.]*\\.\\([0-9]*\\)'`\nTC_VERSION_PATCH=`expr \"$PACKAGE_VERSION\" : '[^.0-9]*\\([^0-9]*\\)$'`\n\n\n\n\n\n# The user can choose not to compile in the heap-profiler, the\n# heap-checker, or the cpu-profiler.  There's also the possibility\n# for a 'fully minimal' compile, which leaves out the stacktrace\n# code as well.  By default, we include all of these that the\n# target system supports.\ndefault_enable_cpu_profiler=yes\ndefault_enable_heap_profiler=yes\ndefault_enable_heap_checker=yes\ndefault_enable_debugalloc=yes\ndefault_enable_minimal=no\nneed_nanosleep=yes   # Used later, to decide if to run ACX_NANOSLEEP\ncase \"$host\" in\n   *-mingw*) default_enable_minimal=yes; default_enable_debugalloc=no;\n             need_nanosleep=no;;\n   *-cygwin*) default_enable_heap_checker=no; default_enable_cpu_profiler=no;;\n   *-freebsd*) default_enable_heap_checker=no;;\n   *-darwin*) default_enable_heap_checker=no;;\nesac\n\n# Check whether --enable-cpu-profiler was given.\nif test \"${enable_cpu_profiler+set}\" = set; then :\n  enableval=$enable_cpu_profiler;\nelse\n  enable_cpu_profiler=\"$default_enable_cpu_profiler\"\nfi\n\n# Check whether --enable-heap-profiler was given.\nif test \"${enable_heap_profiler+set}\" = set; then :\n  enableval=$enable_heap_profiler;\nelse\n  enable_heap_profiler=\"$default_enable_heap_profiler\"\nfi\n\n# Check whether --enable-heap-checker was given.\nif test \"${enable_heap_checker+set}\" = set; then :\n  enableval=$enable_heap_checker;\nelse\n  enable_heap_checker=\"$default_enable_heap_checker\"\nfi\n\n# Check whether --enable-debugalloc was given.\nif test \"${enable_debugalloc+set}\" = set; then :\n  enableval=$enable_debugalloc;\nelse\n  enable_debugalloc=\"$default_enable_debugalloc\"\nfi\n\n# Check whether --enable-minimal was given.\nif test \"${enable_minimal+set}\" = set; then :\n  enableval=$enable_minimal;\nelse\n  enable_minimal=\"$default_enable_minimal\"\nfi\n\nif test \"$enable_minimal\" = yes; then\n  enable_cpu_profiler=no\n  enable_heap_profiler=no\n  enable_heap_checker=no\nfi\n\n\n# Checks for programs.\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gcc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"gcc\", so it can be a program name with args.\nset dummy gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CC=\"gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nif test -z \"$CC\"; then\n          if test -n \"$ac_tool_prefix\"; then\n    # Extract the first word of \"${ac_tool_prefix}cc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  fi\nfi\nif test -z \"$CC\"; then\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"/usr/ucb/cc\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_CC=\"cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_CC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set CC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_CC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in cl.exe\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CC=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CC\" && break\n  done\nfi\nif test -z \"$CC\"; then\n  ac_ct_CC=$CC\n  for ac_prog in cl.exe\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CC=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CC\" && break\ndone\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nfi\n\nfi\n\n\ntest -z \"$CC\" && { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\n\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files a.out a.out.dSYM a.exe b.out\"\n# Try to create an executable without -o first, disregard a.out.\n# It will help us diagnose broken compilers, and finding out an intuition\n# of exeext.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the C compiler works\" >&5\n$as_echo_n \"checking whether the C compiler works... \" >&6; }\nac_link_default=`$as_echo \"$ac_link\" | sed 's/ -o *conftest[^ ]*//'`\n\n# The possible output files:\nac_files=\"a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*\"\n\nac_rmfiles=\nfor ac_file in $ac_files\ndo\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    * ) ac_rmfiles=\"$ac_rmfiles $ac_file\";;\n  esac\ndone\nrm -f $ac_rmfiles\n\nif { { ac_try=\"$ac_link_default\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link_default\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.\n# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'\n# in a Makefile.  We should not override ac_cv_exeext if it was cached,\n# so that the user can short-circuit this test for compilers unknown to\n# Autoconf.\nfor ac_file in $ac_files ''\ndo\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )\n\t;;\n    [ab].out )\n\t# We found the default executable, but exeext='' is most\n\t# certainly right.\n\tbreak;;\n    *.* )\n\tif test \"${ac_cv_exeext+set}\" = set && test \"$ac_cv_exeext\" != no;\n\tthen :; else\n\t   ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\tfi\n\t# We set ac_cv_exeext here because the later test for it is not\n\t# safe: cross compilers may not add the suffix if given an `-o'\n\t# argument, so we may need to know it at that point already.\n\t# Even if this section looks crufty: it has the advantage of\n\t# actually working.\n\tbreak;;\n    * )\n\tbreak;;\n  esac\ndone\ntest \"$ac_cv_exeext\" = no && ac_cv_exeext=\n\nelse\n  ac_file=''\nfi\nif test -z \"$ac_file\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n$as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n{ as_fn_set_status 77\nas_fn_error \"C compiler cannot create executables\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name\" >&5\n$as_echo_n \"checking for C compiler default output file name... \" >&6; }\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_file\" >&5\n$as_echo \"$ac_file\" >&6; }\nac_exeext=$ac_cv_exeext\n\nrm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out\nac_clean_files=$ac_clean_files_save\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of executables\" >&5\n$as_echo_n \"checking for suffix of executables... \" >&6; }\nif { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # If both `conftest.exe' and `conftest' are `present' (well, observable)\n# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will\n# work properly (i.e., refer to `conftest.exe'), while it won't with\n# `rm'.\nfor ac_file in conftest.exe conftest conftest.*; do\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    *.* ) ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\t  break;;\n    * ) break;;\n  esac\ndone\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"cannot compute suffix of executables: cannot compile and link\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\nfi\nrm -f conftest conftest$ac_cv_exeext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext\" >&5\n$as_echo \"$ac_cv_exeext\" >&6; }\n\nrm -f conftest.$ac_ext\nEXEEXT=$ac_cv_exeext\nac_exeext=$EXEEXT\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdio.h>\nint\nmain ()\n{\nFILE *f = fopen (\"conftest.out\", \"w\");\n return ferror (f) || fclose (f) != 0;\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files=\"$ac_clean_files conftest.out\"\n# Check that the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling\" >&5\n$as_echo_n \"checking whether we are cross compiling... \" >&6; }\nif test \"$cross_compiling\" != yes; then\n  { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n  if { ac_try='./conftest$ac_cv_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then\n    cross_compiling=no\n  else\n    if test \"$cross_compiling\" = maybe; then\n\tcross_compiling=yes\n    else\n\t{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"cannot run C compiled programs.\nIf you meant to cross compile, use \\`--host'.\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\n    fi\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $cross_compiling\" >&5\n$as_echo \"$cross_compiling\" >&6; }\n\nrm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out\nac_clean_files=$ac_clean_files_save\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of object files\" >&5\n$as_echo_n \"checking for suffix of object files... \" >&6; }\nif test \"${ac_cv_objext+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.o conftest.obj\nif { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  for ac_file in conftest.o conftest.obj conftest.*; do\n  test -f \"$ac_file\" || continue;\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;\n    *) ac_cv_objext=`expr \"$ac_file\" : '.*\\.\\(.*\\)'`\n       break;;\n  esac\ndone\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"cannot compute suffix of object files: cannot compile\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\nfi\nrm -f conftest.$ac_cv_objext conftest.$ac_ext\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext\" >&5\n$as_echo \"$ac_cv_objext\" >&6; }\nOBJEXT=$ac_cv_objext\nac_objext=$OBJEXT\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C compiler... \" >&6; }\nif test \"${ac_cv_c_compiler_gnu+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_c_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu\" >&5\n$as_echo \"$ac_cv_c_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GCC=yes\nelse\n  GCC=\nfi\nac_test_CFLAGS=${CFLAGS+set}\nac_save_CFLAGS=$CFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g\" >&5\n$as_echo_n \"checking whether $CC accepts -g... \" >&6; }\nif test \"${ac_cv_prog_cc_g+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_c_werror_flag=$ac_c_werror_flag\n   ac_c_werror_flag=yes\n   ac_cv_prog_cc_g=no\n   CFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nelse\n  CFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\nelse\n  ac_c_werror_flag=$ac_save_c_werror_flag\n\t CFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_c_werror_flag=$ac_save_c_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g\" >&5\n$as_echo \"$ac_cv_prog_cc_g\" >&6; }\nif test \"$ac_test_CFLAGS\" = set; then\n  CFLAGS=$ac_save_CFLAGS\nelif test $ac_cv_prog_cc_g = yes; then\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-g -O2\"\n  else\n    CFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-O2\"\n  else\n    CFLAGS=\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89\" >&5\n$as_echo_n \"checking for $CC option to accept ISO C89... \" >&6; }\nif test \"${ac_cv_prog_cc_c89+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_prog_cc_c89=no\nac_save_CC=$CC\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdarg.h>\n#include <stdio.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */\nstruct buf { int x; };\nFILE * (*rcsopen) (struct buf *, struct stat *, int);\nstatic char *e (p, i)\n     char **p;\n     int i;\n{\n  return p[i];\n}\nstatic char *f (char * (*g) (char **, int), char **p, ...)\n{\n  char *s;\n  va_list v;\n  va_start (v,p);\n  s = g (p, va_arg (v,int));\n  va_end (v);\n  return s;\n}\n\n/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has\n   function prototypes and stuff, but not '\\xHH' hex character constants.\n   These don't provoke an error unfortunately, instead are silently treated\n   as 'x'.  The following induces an error, until -std is added to get\n   proper ANSI mode.  Curiously '\\x00'!='x' always comes out true, for an\n   array size at least.  It's necessary to write '\\x00'==0 to get something\n   that's true only with -std.  */\nint osf4_cc_array ['\\x00' == 0 ? 1 : -1];\n\n/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters\n   inside strings and character constants.  */\n#define FOO(x) 'x'\nint xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];\n\nint test (int i, double x);\nstruct s1 {int (*f) (int a);};\nstruct s2 {int (*f) (double a);};\nint pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);\nint argc;\nchar **argv;\nint\nmain ()\n{\nreturn f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];\n  ;\n  return 0;\n}\n_ACEOF\nfor ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \\\n\t-Ae \"-Aa -D_HPUX_SOURCE\" \"-Xc -D__EXTENSIONS__\"\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  if ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_c89=$ac_arg\nfi\nrm -f core conftest.err conftest.$ac_objext\n  test \"x$ac_cv_prog_cc_c89\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCC=$ac_save_CC\n\nfi\n# AC_CACHE_VAL\ncase \"x$ac_cv_prog_cc_c89\" in\n  x)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none needed\" >&5\n$as_echo \"none needed\" >&6; } ;;\n  xno)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: unsupported\" >&5\n$as_echo \"unsupported\" >&6; } ;;\n  *)\n    CC=\"$CC $ac_cv_prog_cc_c89\"\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89\" >&5\n$as_echo \"$ac_cv_prog_cc_c89\" >&6; } ;;\nesac\nif test \"x$ac_cv_prog_cc_c89\" != xno; then :\n\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nDEPDIR=\"${am__leading_dot}deps\"\n\nac_config_commands=\"$ac_config_commands depfiles\"\n\n\nam_make=${MAKE-make}\ncat > confinc << 'END'\nam__doit:\n\t@echo done\n.PHONY: am__doit\nEND\n# If we don't find an include directive, just comment out the code.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make\" >&5\n$as_echo_n \"checking for style of include used by $am_make... \" >&6; }\nam__include=\"#\"\nam__quote=\n_am_result=none\n# First try GNU make style include.\necho \"include confinc\" > confmf\n# We grep out `Entering directory' and `Leaving directory'\n# messages which can occur if `w' ends up in MAKEFLAGS.\n# In particular we don't look at `^make:' because GNU make might\n# be invoked under some other name (usually \"gmake\"), in which\n# case it prints its new name instead of `make'.\nif test \"`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`\" = \"done\"; then\n   am__include=include\n   am__quote=\n   _am_result=GNU\nfi\n# Now try BSD make style include.\nif test \"$am__include\" = \"#\"; then\n   echo '.include \"confinc\"' > confmf\n   if test \"`$am_make -s -f confmf 2> /dev/null`\" = \"done\"; then\n      am__include=.include\n      am__quote=\"\\\"\"\n      _am_result=BSD\n   fi\nfi\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $_am_result\" >&5\n$as_echo \"$_am_result\" >&6; }\nrm -f confinc confmf\n\n# Check whether --enable-dependency-tracking was given.\nif test \"${enable_dependency_tracking+set}\" = set; then :\n  enableval=$enable_dependency_tracking;\nfi\n\nif test \"x$enable_dependency_tracking\" != xno; then\n  am_depcomp=\"$ac_aux_dir/depcomp\"\n  AMDEPBACKSLASH='\\'\nfi\n\n\nif test \"x$enable_dependency_tracking\" != xno; then\n  AMDEP_TRUE=\n  AMDEP_FALSE='#'\nelse\n  AMDEP_TRUE='#'\n  AMDEP_FALSE=\nfi\n\n\n\n\ndepcc=\"$CC\"   am_compiler_list=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc\" >&5\n$as_echo_n \"checking dependency style of $depcc... \" >&6; }\nif test \"${am_cv_CC_dependencies_compiler_type+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$AMDEP_TRUE\" && test -f \"$am_depcomp\"; then\n  # We make a subdir and do the tests there.  Otherwise we can end up\n  # making bogus files that we don't know about and never remove.  For\n  # instance it was reported that on HP-UX the gcc test will end up\n  # making a dummy file named `D' -- because `-MD' means `put the output\n  # in D'.\n  mkdir conftest.dir\n  # Copy depcomp to subdir because otherwise we won't find it if we're\n  # using a relative directory.\n  cp \"$am_depcomp\" conftest.dir\n  cd conftest.dir\n  # We will build objects and dependencies in a subdirectory because\n  # it helps to detect inapplicable dependency modes.  For instance\n  # both Tru64's cc and ICC support -MD to output dependencies as a\n  # side effect of compilation, but ICC will put the dependencies in\n  # the current directory while Tru64 will put them in the object\n  # directory.\n  mkdir sub\n\n  am_cv_CC_dependencies_compiler_type=none\n  if test \"$am_compiler_list\" = \"\"; then\n     am_compiler_list=`sed -n 's/^#*\\([a-zA-Z0-9]*\\))$/\\1/p' < ./depcomp`\n  fi\n  for depmode in $am_compiler_list; do\n    # Setup a source with many dependencies, because some compilers\n    # like to wrap large dependency lists on column 80 (with \\), and\n    # we should not choose a depcomp mode which is confused by this.\n    #\n    # We need to recreate these files for each test, as the compiler may\n    # overwrite some of them when testing with obscure command lines.\n    # This happens at least with the AIX C compiler.\n    : > sub/conftest.c\n    for i in 1 2 3 4 5 6; do\n      echo '#include \"conftst'$i'.h\"' >> sub/conftest.c\n      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with\n      # Solaris 8's {/usr,}/bin/sh.\n      touch sub/conftst$i.h\n    done\n    echo \"${am__include} ${am__quote}sub/conftest.Po${am__quote}\" > confmf\n\n    case $depmode in\n    nosideeffect)\n      # after this tag, mechanisms are not by side-effect, so they'll\n      # only be used when explicitly requested\n      if test \"x$enable_dependency_tracking\" = xyes; then\n\tcontinue\n      else\n\tbreak\n      fi\n      ;;\n    none) break ;;\n    esac\n    # We check with `-c' and `-o' for the sake of the \"dashmstdout\"\n    # mode.  It turns out that the SunPro C++ compiler does not properly\n    # handle `-M -o', and we need to detect this.\n    if depmode=$depmode \\\n       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&\n       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then\n      # icc doesn't choke on unknown options, it will just issue warnings\n      # or remarks (even with -Werror).  So we grep stderr for any message\n      # that says an option was ignored or not supported.\n      # When given -MP, icc 7.0 and 7.1 complain thusly:\n      #   icc: Command line warning: ignoring option '-M'; no argument required\n      # The diagnosis changed in icc 8.0:\n      #   icc: Command line remark: option '-MP' not supported\n      if (grep 'ignoring option' conftest.err ||\n          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else\n        am_cv_CC_dependencies_compiler_type=$depmode\n        break\n      fi\n    fi\n  done\n\n  cd ..\n  rm -rf conftest.dir\nelse\n  am_cv_CC_dependencies_compiler_type=none\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type\" >&5\n$as_echo \"$am_cv_CC_dependencies_compiler_type\" >&6; }\nCCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type\n\n\n\nif\n  test \"x$enable_dependency_tracking\" != xno \\\n  && test \"$am_cv_CC_dependencies_compiler_type\" = gcc3; then\n  am__fastdepCC_TRUE=\n  am__fastdepCC_FALSE='#'\nelse\n  am__fastdepCC_TRUE='#'\n  am__fastdepCC_FALSE=\nfi\n\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor\" >&5\n$as_echo_n \"checking how to run the C preprocessor... \" >&6; }\n# On Suns, sometimes $CPP names a directory.\nif test -n \"$CPP\" && test -d \"$CPP\"; then\n  CPP=\nfi\nif test -z \"$CPP\"; then\n  if test \"${ac_cv_prog_CPP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n      # Double quotes because CPP needs to be expanded\n    for CPP in \"$CC -E\" \"$CC -E -traditional-cpp\" \"/lib/cpp\"\n    do\n      ac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n  break\nfi\n\n    done\n    ac_cv_prog_CPP=$CPP\n\nfi\n  CPP=$ac_cv_prog_CPP\nelse\n  ac_cv_prog_CPP=$CPP\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CPP\" >&5\n$as_echo \"$CPP\" >&6; }\nac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error \"C preprocessor \\\"$CPP\\\" fails sanity check\nSee \\`config.log' for more details.\" \"$LINENO\" 5; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\nif test -z \"$CXX\"; then\n  if test -n \"$CCC\"; then\n    CXX=$CCC\n  else\n    if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CXX\"; then\n  ac_cv_prog_CXX=\"$CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CXX=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCXX=$ac_cv_prog_CXX\nif test -n \"$CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CXX\" >&5\n$as_echo \"$CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CXX\" && break\n  done\nfi\nif test -z \"$CXX\"; then\n  ac_ct_CXX=$CXX\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CXX\"; then\n  ac_cv_prog_ac_ct_CXX=\"$ac_ct_CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CXX=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CXX=$ac_cv_prog_ac_ct_CXX\nif test -n \"$ac_ct_CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX\" >&5\n$as_echo \"$ac_ct_CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CXX\" && break\ndone\n\n  if test \"x$ac_ct_CXX\" = x; then\n    CXX=\"g++\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CXX=$ac_ct_CXX\n  fi\nfi\n\n  fi\nfi\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C++ compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C++ compiler... \" >&6; }\nif test \"${ac_cv_cxx_compiler_gnu+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_cxx_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu\" >&5\n$as_echo \"$ac_cv_cxx_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GXX=yes\nelse\n  GXX=\nfi\nac_test_CXXFLAGS=${CXXFLAGS+set}\nac_save_CXXFLAGS=$CXXFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g\" >&5\n$as_echo_n \"checking whether $CXX accepts -g... \" >&6; }\nif test \"${ac_cv_prog_cxx_g+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_cxx_werror_flag=$ac_cxx_werror_flag\n   ac_cxx_werror_flag=yes\n   ac_cv_prog_cxx_g=no\n   CXXFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nelse\n  CXXFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\nelse\n  ac_cxx_werror_flag=$ac_save_cxx_werror_flag\n\t CXXFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_cxx_werror_flag=$ac_save_cxx_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g\" >&5\n$as_echo \"$ac_cv_prog_cxx_g\" >&6; }\nif test \"$ac_test_CXXFLAGS\" = set; then\n  CXXFLAGS=$ac_save_CXXFLAGS\nelif test $ac_cv_prog_cxx_g = yes; then\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-g -O2\"\n  else\n    CXXFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-O2\"\n  else\n    CXXFLAGS=\n  fi\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\ndepcc=\"$CXX\"  am_compiler_list=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc\" >&5\n$as_echo_n \"checking dependency style of $depcc... \" >&6; }\nif test \"${am_cv_CXX_dependencies_compiler_type+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$AMDEP_TRUE\" && test -f \"$am_depcomp\"; then\n  # We make a subdir and do the tests there.  Otherwise we can end up\n  # making bogus files that we don't know about and never remove.  For\n  # instance it was reported that on HP-UX the gcc test will end up\n  # making a dummy file named `D' -- because `-MD' means `put the output\n  # in D'.\n  mkdir conftest.dir\n  # Copy depcomp to subdir because otherwise we won't find it if we're\n  # using a relative directory.\n  cp \"$am_depcomp\" conftest.dir\n  cd conftest.dir\n  # We will build objects and dependencies in a subdirectory because\n  # it helps to detect inapplicable dependency modes.  For instance\n  # both Tru64's cc and ICC support -MD to output dependencies as a\n  # side effect of compilation, but ICC will put the dependencies in\n  # the current directory while Tru64 will put them in the object\n  # directory.\n  mkdir sub\n\n  am_cv_CXX_dependencies_compiler_type=none\n  if test \"$am_compiler_list\" = \"\"; then\n     am_compiler_list=`sed -n 's/^#*\\([a-zA-Z0-9]*\\))$/\\1/p' < ./depcomp`\n  fi\n  for depmode in $am_compiler_list; do\n    # Setup a source with many dependencies, because some compilers\n    # like to wrap large dependency lists on column 80 (with \\), and\n    # we should not choose a depcomp mode which is confused by this.\n    #\n    # We need to recreate these files for each test, as the compiler may\n    # overwrite some of them when testing with obscure command lines.\n    # This happens at least with the AIX C compiler.\n    : > sub/conftest.c\n    for i in 1 2 3 4 5 6; do\n      echo '#include \"conftst'$i'.h\"' >> sub/conftest.c\n      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with\n      # Solaris 8's {/usr,}/bin/sh.\n      touch sub/conftst$i.h\n    done\n    echo \"${am__include} ${am__quote}sub/conftest.Po${am__quote}\" > confmf\n\n    case $depmode in\n    nosideeffect)\n      # after this tag, mechanisms are not by side-effect, so they'll\n      # only be used when explicitly requested\n      if test \"x$enable_dependency_tracking\" = xyes; then\n\tcontinue\n      else\n\tbreak\n      fi\n      ;;\n    none) break ;;\n    esac\n    # We check with `-c' and `-o' for the sake of the \"dashmstdout\"\n    # mode.  It turns out that the SunPro C++ compiler does not properly\n    # handle `-M -o', and we need to detect this.\n    if depmode=$depmode \\\n       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&\n       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then\n      # icc doesn't choke on unknown options, it will just issue warnings\n      # or remarks (even with -Werror).  So we grep stderr for any message\n      # that says an option was ignored or not supported.\n      # When given -MP, icc 7.0 and 7.1 complain thusly:\n      #   icc: Command line warning: ignoring option '-M'; no argument required\n      # The diagnosis changed in icc 8.0:\n      #   icc: Command line remark: option '-MP' not supported\n      if (grep 'ignoring option' conftest.err ||\n          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else\n        am_cv_CXX_dependencies_compiler_type=$depmode\n        break\n      fi\n    fi\n  done\n\n  cd ..\n  rm -rf conftest.dir\nelse\n  am_cv_CXX_dependencies_compiler_type=none\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type\" >&5\n$as_echo \"$am_cv_CXX_dependencies_compiler_type\" >&6; }\nCXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type\n\n\n\nif\n  test \"x$enable_dependency_tracking\" != xno \\\n  && test \"$am_cv_CXX_dependencies_compiler_type\" = gcc3; then\n  am__fastdepCXX_TRUE=\n  am__fastdepCXX_FALSE='#'\nelse\n  am__fastdepCXX_TRUE='#'\n  am__fastdepCXX_FALSE=\nfi\n\n\n\n\nif test \"$GCC\" = yes; then\n  GCC_TRUE=\n  GCC_FALSE='#'\nelse\n  GCC_TRUE='#'\n  GCC_FALSE=\nfi\n   # let the Makefile know if we're gcc\nif test \"x$CC\" != xcc; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together\" >&5\n$as_echo_n \"checking whether $CC and cc understand -c and -o together... \" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together\" >&5\n$as_echo_n \"checking whether cc understands -c and -o together... \" >&6; }\nfi\nset dummy $CC; ac_cc=`$as_echo \"$2\" |\n\t\t      sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`\nif { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval \"test \\\"\\${$as_var+set}\\\" = set\"; }; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\n# Make sure it works both with $CC and with simple cc.\n# We do the test twice because some compilers refuse to overwrite an\n# existing .o file with -o, though they will create one.\nac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'\nrm -f conftest2.*\nif { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } &&\n   test -f conftest2.$ac_objext && { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; };\nthen\n  eval ac_cv_prog_cc_${ac_cc}_c_o=yes\n  if test \"x$CC\" != xcc; then\n    # Test first that cc exists at all.\n    if { ac_try='cc -c conftest.$ac_ext >&5'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then\n      ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'\n      rm -f conftest2.*\n      if { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } &&\n\t test -f conftest2.$ac_objext && { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; };\n      then\n\t# cc works too.\n\t:\n      else\n\t# cc exists but doesn't like -o.\n\teval ac_cv_prog_cc_${ac_cc}_c_o=no\n      fi\n    fi\n  fi\nelse\n  eval ac_cv_prog_cc_${ac_cc}_c_o=no\nfi\nrm -f core conftest*\n\nfi\nif eval test \\$ac_cv_prog_cc_${ac_cc}_c_o = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\n$as_echo \"#define NO_MINUS_C_MINUS_O 1\" >>confdefs.h\n\nfi\n\n# FIXME: we rely on the cache variable name because\n# there is no other way.\nset dummy $CC\nac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`\nif eval \"test \\\"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\\\" != yes\"; then\n   # Losing compiler, so override with the script.\n   # FIXME: It is wrong to rewrite CC.\n   # But if we don't then we get into trouble of one sort or another.\n   # A longer-term fix would be to have automake use am__CC in this case,\n   # and then we could set am__CC=\"\\$(top_srcdir)/compile \\$(CC)\"\n   CC=\"$am_aux_dir/compile $CC\"\nfi\n      # shrug: autogen.sh suddenly needs this for some reason\n\n# Check if we have an objcopy installed that supports -W\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}objcopy\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}objcopy; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OBJCOPY+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OBJCOPY\"; then\n  ac_cv_prog_OBJCOPY=\"$OBJCOPY\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OBJCOPY=\"${ac_tool_prefix}objcopy\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOBJCOPY=$ac_cv_prog_OBJCOPY\nif test -n \"$OBJCOPY\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OBJCOPY\" >&5\n$as_echo \"$OBJCOPY\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OBJCOPY\"; then\n  ac_ct_OBJCOPY=$OBJCOPY\n  # Extract the first word of \"objcopy\", so it can be a program name with args.\nset dummy objcopy; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OBJCOPY+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OBJCOPY\"; then\n  ac_cv_prog_ac_ct_OBJCOPY=\"$ac_ct_OBJCOPY\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OBJCOPY=\"objcopy\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY\nif test -n \"$ac_ct_OBJCOPY\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCOPY\" >&5\n$as_echo \"$ac_ct_OBJCOPY\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OBJCOPY\" = x; then\n    OBJCOPY=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OBJCOPY=$ac_ct_OBJCOPY\n  fi\nelse\n  OBJCOPY=\"$ac_cv_prog_OBJCOPY\"\nfi\n\n\n\nif \"$OBJCOPY\" -W malloc /bin/ls /dev/null; then\n  HAVE_OBJCOPY_WEAKEN_TRUE=\n  HAVE_OBJCOPY_WEAKEN_FALSE='#'\nelse\n  HAVE_OBJCOPY_WEAKEN_TRUE='#'\n  HAVE_OBJCOPY_WEAKEN_FALSE=\nfi\n\n\ncase $host_os in\n  *mingw*)\n    # Disabling fast install keeps libtool from creating wrapper scripts\n    # around the executables it builds.  Such scripts have caused failures on\n    # MinGW.  Using this option means an extra link step is executed during\n    # \"make install\".\n    # Check whether --enable-fast-install was given.\nif test \"${enable_fast_install+set}\" = set; then :\n  enableval=$enable_fast_install; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_fast_install=yes ;;\n    no) enable_fast_install=no ;;\n    *)\n      enable_fast_install=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_fast_install=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_fast_install=no\nfi\n\n\n\n\n\n\n\n\n\n    ;;\n   *)\n    # Check whether --enable-fast-install was given.\nif test \"${enable_fast_install+set}\" = set; then :\n  enableval=$enable_fast_install; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_fast_install=yes ;;\n    no) enable_fast_install=no ;;\n    *)\n      enable_fast_install=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_fast_install=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_fast_install=yes\nfi\n\n\n\n\n\n\n    ;;\nesac\n\ncase `pwd` in\n  *\\ * | *\\\t*)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \\`pwd\\`\" >&5\n$as_echo \"$as_me: WARNING: Libtool does not cope well with whitespace in \\`pwd\\`\" >&2;} ;;\nesac\n\n\n\nmacro_version='2.2.6b'\nmacro_revision='1.3017'\n\n\n\n\n\n\n\n\n\n\n\n\n\nltmain=\"$ac_aux_dir/ltmain.sh\"\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output\" >&5\n$as_echo_n \"checking for a sed that does not truncate output... \" >&6; }\nif test \"${ac_cv_path_SED+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/\n     for ac_i in 1 2 3 4 5 6 7; do\n       ac_script=\"$ac_script$as_nl$ac_script\"\n     done\n     echo \"$ac_script\" 2>/dev/null | sed 99q >conftest.sed\n     { ac_script=; unset ac_script;}\n     if test -z \"$SED\"; then\n  ac_path_SED_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in sed gsed; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_SED=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_SED\" && $as_test_x \"$ac_path_SED\"; } || continue\n# Check for GNU ac_path_SED and select it if it is found.\n  # Check for GNU $ac_path_SED\ncase `\"$ac_path_SED\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_SED=\"$ac_path_SED\" ac_path_SED_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo '' >> \"conftest.nl\"\n    \"$ac_path_SED\" -f conftest.sed < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_SED_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_SED=\"$ac_path_SED\"\n      ac_path_SED_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_SED_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_SED\"; then\n    as_fn_error \"no acceptable sed could be found in \\$PATH\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_SED=$SED\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED\" >&5\n$as_echo \"$ac_cv_path_SED\" >&6; }\n SED=\"$ac_cv_path_SED\"\n  rm -f conftest.sed\n\ntest -z \"$SED\" && SED=sed\nXsed=\"$SED -e 1s/^X//\"\n\n\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e\" >&5\n$as_echo_n \"checking for grep that handles long lines and -e... \" >&6; }\nif test \"${ac_cv_path_GREP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$GREP\"; then\n  ac_path_GREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in grep ggrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_GREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_GREP\" && $as_test_x \"$ac_path_GREP\"; } || continue\n# Check for GNU ac_path_GREP and select it if it is found.\n  # Check for GNU $ac_path_GREP\ncase `\"$ac_path_GREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_GREP=\"$ac_path_GREP\" ac_path_GREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'GREP' >> \"conftest.nl\"\n    \"$ac_path_GREP\" -e 'GREP$' -e '-(cannot match)-' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_GREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_GREP=\"$ac_path_GREP\"\n      ac_path_GREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_GREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_GREP\"; then\n    as_fn_error \"no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_GREP=$GREP\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP\" >&5\n$as_echo \"$ac_cv_path_GREP\" >&6; }\n GREP=\"$ac_cv_path_GREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for egrep\" >&5\n$as_echo_n \"checking for egrep... \" >&6; }\nif test \"${ac_cv_path_EGREP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1\n   then ac_cv_path_EGREP=\"$GREP -E\"\n   else\n     if test -z \"$EGREP\"; then\n  ac_path_EGREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in egrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_EGREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_EGREP\" && $as_test_x \"$ac_path_EGREP\"; } || continue\n# Check for GNU ac_path_EGREP and select it if it is found.\n  # Check for GNU $ac_path_EGREP\ncase `\"$ac_path_EGREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_EGREP=\"$ac_path_EGREP\" ac_path_EGREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'EGREP' >> \"conftest.nl\"\n    \"$ac_path_EGREP\" 'EGREP$' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_EGREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_EGREP=\"$ac_path_EGREP\"\n      ac_path_EGREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_EGREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_EGREP\"; then\n    as_fn_error \"no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_EGREP=$EGREP\nfi\n\n   fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP\" >&5\n$as_echo \"$ac_cv_path_EGREP\" >&6; }\n EGREP=\"$ac_cv_path_EGREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for fgrep\" >&5\n$as_echo_n \"checking for fgrep... \" >&6; }\nif test \"${ac_cv_path_FGREP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1\n   then ac_cv_path_FGREP=\"$GREP -F\"\n   else\n     if test -z \"$FGREP\"; then\n  ac_path_FGREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in fgrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_FGREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      { test -f \"$ac_path_FGREP\" && $as_test_x \"$ac_path_FGREP\"; } || continue\n# Check for GNU ac_path_FGREP and select it if it is found.\n  # Check for GNU $ac_path_FGREP\ncase `\"$ac_path_FGREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_FGREP=\"$ac_path_FGREP\" ac_path_FGREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'FGREP' >> \"conftest.nl\"\n    \"$ac_path_FGREP\" FGREP < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_FGREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_FGREP=\"$ac_path_FGREP\"\n      ac_path_FGREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_FGREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_FGREP\"; then\n    as_fn_error \"no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_FGREP=$FGREP\nfi\n\n   fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP\" >&5\n$as_echo \"$ac_cv_path_FGREP\" >&6; }\n FGREP=\"$ac_cv_path_FGREP\"\n\n\ntest -z \"$GREP\" && GREP=grep\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# Check whether --with-gnu-ld was given.\nif test \"${with_gnu_ld+set}\" = set; then :\n  withval=$with_gnu_ld; test \"$withval\" = no || with_gnu_ld=yes\nelse\n  with_gnu_ld=no\nfi\n\nac_prog=ld\nif test \"$GCC\" = yes; then\n  # Check if gcc -print-prog-name=ld gives a path.\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ld used by $CC\" >&5\n$as_echo_n \"checking for ld used by $CC... \" >&6; }\n  case $host in\n  *-*-mingw*)\n    # gcc leaves a trailing carriage return which upsets mingw\n    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\\015'` ;;\n  *)\n    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;\n  esac\n  case $ac_prog in\n    # Accept absolute paths.\n    [\\\\/]* | ?:[\\\\/]*)\n      re_direlt='/[^/][^/]*/\\.\\./'\n      # Canonicalize the pathname of ld\n      ac_prog=`$ECHO \"$ac_prog\"| $SED 's%\\\\\\\\%/%g'`\n      while $ECHO \"$ac_prog\" | $GREP \"$re_direlt\" > /dev/null 2>&1; do\n\tac_prog=`$ECHO $ac_prog| $SED \"s%$re_direlt%/%\"`\n      done\n      test -z \"$LD\" && LD=\"$ac_prog\"\n      ;;\n  \"\")\n    # If it fails, then pretend we aren't using GCC.\n    ac_prog=ld\n    ;;\n  *)\n    # If it is relative, then search for the first ld in PATH.\n    with_gnu_ld=unknown\n    ;;\n  esac\nelif test \"$with_gnu_ld\" = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for GNU ld\" >&5\n$as_echo_n \"checking for GNU ld... \" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for non-GNU ld\" >&5\n$as_echo_n \"checking for non-GNU ld... \" >&6; }\nfi\nif test \"${lt_cv_path_LD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$LD\"; then\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  for ac_dir in $PATH; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f \"$ac_dir/$ac_prog\" || test -f \"$ac_dir/$ac_prog$ac_exeext\"; then\n      lt_cv_path_LD=\"$ac_dir/$ac_prog\"\n      # Check to see if the program is GNU ld.  I'd rather use --version,\n      # but apparently some variants of GNU ld only accept -v.\n      # Break only if it was the GNU/non-GNU ld that we prefer.\n      case `\"$lt_cv_path_LD\" -v 2>&1 </dev/null` in\n      *GNU* | *'with BFD'*)\n\ttest \"$with_gnu_ld\" != no && break\n\t;;\n      *)\n\ttest \"$with_gnu_ld\" != yes && break\n\t;;\n      esac\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\nelse\n  lt_cv_path_LD=\"$LD\" # Let the user override the test with a path.\nfi\nfi\n\nLD=\"$lt_cv_path_LD\"\nif test -n \"$LD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $LD\" >&5\n$as_echo \"$LD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\ntest -z \"$LD\" && as_fn_error \"no acceptable ld found in \\$PATH\" \"$LINENO\" 5\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld\" >&5\n$as_echo_n \"checking if the linker ($LD) is GNU ld... \" >&6; }\nif test \"${lt_cv_prog_gnu_ld+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  # I'd rather use --version here, but apparently some GNU lds only accept -v.\ncase `$LD -v 2>&1 </dev/null` in\n*GNU* | *'with BFD'*)\n  lt_cv_prog_gnu_ld=yes\n  ;;\n*)\n  lt_cv_prog_gnu_ld=no\n  ;;\nesac\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld\" >&5\n$as_echo \"$lt_cv_prog_gnu_ld\" >&6; }\nwith_gnu_ld=$lt_cv_prog_gnu_ld\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)\" >&5\n$as_echo_n \"checking for BSD- or MS-compatible name lister (nm)... \" >&6; }\nif test \"${lt_cv_path_NM+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$NM\"; then\n  # Let the user override the test.\n  lt_cv_path_NM=\"$NM\"\nelse\n  lt_nm_to_check=\"${ac_tool_prefix}nm\"\n  if test -n \"$ac_tool_prefix\" && test \"$build\" = \"$host\"; then\n    lt_nm_to_check=\"$lt_nm_to_check nm\"\n  fi\n  for lt_tmp_nm in $lt_nm_to_check; do\n    lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do\n      IFS=\"$lt_save_ifs\"\n      test -z \"$ac_dir\" && ac_dir=.\n      tmp_nm=\"$ac_dir/$lt_tmp_nm\"\n      if test -f \"$tmp_nm\" || test -f \"$tmp_nm$ac_exeext\" ; then\n\t# Check to see if the nm accepts a BSD-compat flag.\n\t# Adding the `sed 1q' prevents false positives on HP-UX, which says:\n\t#   nm: unknown option \"B\" ignored\n\t# Tru64's nm complains that /dev/null is an invalid object file\n\tcase `\"$tmp_nm\" -B /dev/null 2>&1 | sed '1q'` in\n\t*/dev/null* | *'Invalid file or object type'*)\n\t  lt_cv_path_NM=\"$tmp_nm -B\"\n\t  break\n\t  ;;\n\t*)\n\t  case `\"$tmp_nm\" -p /dev/null 2>&1 | sed '1q'` in\n\t  */dev/null*)\n\t    lt_cv_path_NM=\"$tmp_nm -p\"\n\t    break\n\t    ;;\n\t  *)\n\t    lt_cv_path_NM=${lt_cv_path_NM=\"$tmp_nm\"} # keep the first match, but\n\t    continue # so that we can try to find one that supports BSD flags\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n      fi\n    done\n    IFS=\"$lt_save_ifs\"\n  done\n  : ${lt_cv_path_NM=no}\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM\" >&5\n$as_echo \"$lt_cv_path_NM\" >&6; }\nif test \"$lt_cv_path_NM\" != \"no\"; then\n  NM=\"$lt_cv_path_NM\"\nelse\n  # Didn't find any BSD compatible name lister, look for dumpbin.\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in \"dumpbin -symbols\" \"link -dump -symbols\"\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_DUMPBIN+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$DUMPBIN\"; then\n  ac_cv_prog_DUMPBIN=\"$DUMPBIN\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_DUMPBIN=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nDUMPBIN=$ac_cv_prog_DUMPBIN\nif test -n \"$DUMPBIN\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $DUMPBIN\" >&5\n$as_echo \"$DUMPBIN\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$DUMPBIN\" && break\n  done\nfi\nif test -z \"$DUMPBIN\"; then\n  ac_ct_DUMPBIN=$DUMPBIN\n  for ac_prog in \"dumpbin -symbols\" \"link -dump -symbols\"\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_DUMPBIN+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_DUMPBIN\"; then\n  ac_cv_prog_ac_ct_DUMPBIN=\"$ac_ct_DUMPBIN\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_DUMPBIN=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN\nif test -n \"$ac_ct_DUMPBIN\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN\" >&5\n$as_echo \"$ac_ct_DUMPBIN\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_DUMPBIN\" && break\ndone\n\n  if test \"x$ac_ct_DUMPBIN\" = x; then\n    DUMPBIN=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    DUMPBIN=$ac_ct_DUMPBIN\n  fi\nfi\n\n\n  if test \"$DUMPBIN\" != \":\"; then\n    NM=\"$DUMPBIN\"\n  fi\nfi\ntest -z \"$NM\" && NM=nm\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface\" >&5\n$as_echo_n \"checking the name lister ($NM) interface... \" >&6; }\nif test \"${lt_cv_nm_interface+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_nm_interface=\"BSD nm\"\n  echo \"int some_variable = 0;\" > conftest.$ac_ext\n  (eval echo \"\\\"\\$as_me:5584: $ac_compile\\\"\" >&5)\n  (eval \"$ac_compile\" 2>conftest.err)\n  cat conftest.err >&5\n  (eval echo \"\\\"\\$as_me:5587: $NM \\\\\\\"conftest.$ac_objext\\\\\\\"\\\"\" >&5)\n  (eval \"$NM \\\"conftest.$ac_objext\\\"\" 2>conftest.err > conftest.out)\n  cat conftest.err >&5\n  (eval echo \"\\\"\\$as_me:5590: output\\\"\" >&5)\n  cat conftest.out >&5\n  if $GREP 'External.*some_variable' conftest.out > /dev/null; then\n    lt_cv_nm_interface=\"MS dumpbin\"\n  fi\n  rm -f conftest*\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface\" >&5\n$as_echo \"$lt_cv_nm_interface\" >&6; }\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether ln -s works\" >&5\n$as_echo_n \"checking whether ln -s works... \" >&6; }\nLN_S=$as_ln_s\nif test \"$LN_S\" = \"ln -s\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no, using $LN_S\" >&5\n$as_echo \"no, using $LN_S\" >&6; }\nfi\n\n# find the maximum length of command line arguments\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments\" >&5\n$as_echo_n \"checking the maximum length of command line arguments... \" >&6; }\nif test \"${lt_cv_sys_max_cmd_len+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n    i=0\n  teststring=\"ABCD\"\n\n  case $build_os in\n  msdosdjgpp*)\n    # On DJGPP, this test can blow up pretty badly due to problems in libc\n    # (any single argument exceeding 2000 bytes causes a buffer overrun\n    # during glob expansion).  Even if it were fixed, the result of this\n    # check would be larger than it should be.\n    lt_cv_sys_max_cmd_len=12288;    # 12K is about right\n    ;;\n\n  gnu*)\n    # Under GNU Hurd, this test is not required because there is\n    # no limit to the length of command line arguments.\n    # Libtool will interpret -1 as no limit whatsoever\n    lt_cv_sys_max_cmd_len=-1;\n    ;;\n\n  cygwin* | mingw* | cegcc*)\n    # On Win9x/ME, this test blows up -- it succeeds, but takes\n    # about 5 minutes as the teststring grows exponentially.\n    # Worse, since 9x/ME are not pre-emptively multitasking,\n    # you end up with a \"frozen\" computer, even though with patience\n    # the test eventually succeeds (with a max line length of 256k).\n    # Instead, let's just punt: use the minimum linelength reported by\n    # all of the supported platforms: 8192 (on NT/2K/XP).\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  amigaos*)\n    # On AmigaOS with pdksh, this test takes hours, literally.\n    # So we just punt and use a minimum line length of 8192.\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)\n    # This has been around since 386BSD, at least.  Likely further.\n    if test -x /sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`\n    elif test -x /usr/sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`\n    else\n      lt_cv_sys_max_cmd_len=65536\t# usable default for all BSDs\n    fi\n    # And add a safety zone\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    ;;\n\n  interix*)\n    # We know the value 262144 and hardcode it with a safety zone (like BSD)\n    lt_cv_sys_max_cmd_len=196608\n    ;;\n\n  osf*)\n    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure\n    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not\n    # nice to cause kernel panics so lets avoid the loop below.\n    # First set a reasonable default.\n    lt_cv_sys_max_cmd_len=16384\n    #\n    if test -x /sbin/sysconfig; then\n      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in\n        *1*) lt_cv_sys_max_cmd_len=-1 ;;\n      esac\n    fi\n    ;;\n  sco3.2v5*)\n    lt_cv_sys_max_cmd_len=102400\n    ;;\n  sysv5* | sco5v6* | sysv4.2uw2*)\n    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`\n    if test -n \"$kargmax\"; then\n      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[\t ]//'`\n    else\n      lt_cv_sys_max_cmd_len=32768\n    fi\n    ;;\n  *)\n    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`\n    if test -n \"$lt_cv_sys_max_cmd_len\"; then\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    else\n      # Make teststring a little bigger before we do anything with it.\n      # a 1K string should be a reasonable start.\n      for i in 1 2 3 4 5 6 7 8 ; do\n        teststring=$teststring$teststring\n      done\n      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}\n      # If test is not a shell built-in, we'll probably end up computing a\n      # maximum length that is only half of the actual maximum length, but\n      # we can't tell.\n      while { test \"X\"`$SHELL $0 --fallback-echo \"X$teststring$teststring\" 2>/dev/null` \\\n\t         = \"XX$teststring$teststring\"; } >/dev/null 2>&1 &&\n\t      test $i != 17 # 1/2 MB should be enough\n      do\n        i=`expr $i + 1`\n        teststring=$teststring$teststring\n      done\n      # Only check the string length outside the loop.\n      lt_cv_sys_max_cmd_len=`expr \"X$teststring\" : \".*\" 2>&1`\n      teststring=\n      # Add a significant safety factor because C++ compilers can tack on\n      # massive amounts of additional arguments before passing them to the\n      # linker.  It appears as though 1/2 is a usable value.\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 2`\n    fi\n    ;;\n  esac\n\nfi\n\nif test -n $lt_cv_sys_max_cmd_len ; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len\" >&5\n$as_echo \"$lt_cv_sys_max_cmd_len\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none\" >&5\n$as_echo \"none\" >&6; }\nfi\nmax_cmd_len=$lt_cv_sys_max_cmd_len\n\n\n\n\n\n\n: ${CP=\"cp -f\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs\" >&5\n$as_echo_n \"checking whether the shell understands some XSI constructs... \" >&6; }\n# Try some XSI features\nxsi_shell=no\n( _lt_dummy=\"a/b/c\"\n  test \"${_lt_dummy##*/},${_lt_dummy%/*},\"${_lt_dummy%\"$_lt_dummy\"}, \\\n      = c,a/b,, \\\n    && eval 'test $(( 1 + 1 )) -eq 2 \\\n    && test \"${#_lt_dummy}\" -eq 5' ) >/dev/null 2>&1 \\\n  && xsi_shell=yes\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $xsi_shell\" >&5\n$as_echo \"$xsi_shell\" >&6; }\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the shell understands \\\"+=\\\"\" >&5\n$as_echo_n \"checking whether the shell understands \\\"+=\\\"... \" >&6; }\nlt_shell_append=no\n( foo=bar; set foo baz; eval \"$1+=\\$2\" && test \"$foo\" = barbaz ) \\\n    >/dev/null 2>&1 \\\n  && lt_shell_append=yes\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_shell_append\" >&5\n$as_echo \"$lt_shell_append\" >&6; }\n\n\nif ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then\n  lt_unset=unset\nelse\n  lt_unset=false\nfi\n\n\n\n\n\n# test EBCDIC or ASCII\ncase `echo X|tr X '\\101'` in\n A) # ASCII based system\n    # \\n is not interpreted correctly by Solaris 8 /usr/ucb/tr\n  lt_SP2NL='tr \\040 \\012'\n  lt_NL2SP='tr \\015\\012 \\040\\040'\n  ;;\n *) # EBCDIC based system\n  lt_SP2NL='tr \\100 \\n'\n  lt_NL2SP='tr \\r\\n \\100\\100'\n  ;;\nesac\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files\" >&5\n$as_echo_n \"checking for $LD option to reload object files... \" >&6; }\nif test \"${lt_cv_ld_reload_flag+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ld_reload_flag='-r'\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag\" >&5\n$as_echo \"$lt_cv_ld_reload_flag\" >&6; }\nreload_flag=$lt_cv_ld_reload_flag\ncase $reload_flag in\n\"\" | \" \"*) ;;\n*) reload_flag=\" $reload_flag\" ;;\nesac\nreload_cmds='$LD$reload_flag -o $output$reload_objs'\ncase $host_os in\n  darwin*)\n    if test \"$GCC\" = yes; then\n      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'\n    else\n      reload_cmds='$LD$reload_flag -o $output$reload_objs'\n    fi\n    ;;\nesac\n\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}objdump\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}objdump; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OBJDUMP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OBJDUMP\"; then\n  ac_cv_prog_OBJDUMP=\"$OBJDUMP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OBJDUMP=\"${ac_tool_prefix}objdump\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOBJDUMP=$ac_cv_prog_OBJDUMP\nif test -n \"$OBJDUMP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OBJDUMP\" >&5\n$as_echo \"$OBJDUMP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OBJDUMP\"; then\n  ac_ct_OBJDUMP=$OBJDUMP\n  # Extract the first word of \"objdump\", so it can be a program name with args.\nset dummy objdump; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OBJDUMP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OBJDUMP\"; then\n  ac_cv_prog_ac_ct_OBJDUMP=\"$ac_ct_OBJDUMP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OBJDUMP=\"objdump\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP\nif test -n \"$ac_ct_OBJDUMP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP\" >&5\n$as_echo \"$ac_ct_OBJDUMP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OBJDUMP\" = x; then\n    OBJDUMP=\"false\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OBJDUMP=$ac_ct_OBJDUMP\n  fi\nelse\n  OBJDUMP=\"$ac_cv_prog_OBJDUMP\"\nfi\n\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n\n\n\n\n\n\n\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries\" >&5\n$as_echo_n \"checking how to recognize dependent libraries... \" >&6; }\nif test \"${lt_cv_deplibs_check_method+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_file_magic_cmd='$MAGIC_CMD'\nlt_cv_file_magic_test_file=\nlt_cv_deplibs_check_method='unknown'\n# Need to set the preceding variable on all platforms that support\n# interlibrary dependencies.\n# 'none' -- dependencies not supported.\n# `unknown' -- same as none, but documents that we really don't know.\n# 'pass_all' -- all dependencies passed with no checks.\n# 'test_compile' -- check by making test program.\n# 'file_magic [[regex]]' -- check by looking for files in library path\n# which responds to the $file_magic_cmd with a given extended regex.\n# If you have `file' or equivalent on your system and you're not sure\n# whether `pass_all' will *always* work, you probably want this one.\n\ncase $host_os in\naix[4-9]*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbeos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbsdi[45]*)\n  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'\n  lt_cv_file_magic_cmd='/usr/bin/file -L'\n  lt_cv_file_magic_test_file=/shlib/libc.so\n  ;;\n\ncygwin*)\n  # func_win32_libid is a shell function defined in ltmain.sh\n  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n  lt_cv_file_magic_cmd='func_win32_libid'\n  ;;\n\nmingw* | pw32*)\n  # Base MSYS/MinGW do not provide the 'file' command needed by\n  # func_win32_libid shell function, so use a weaker test based on 'objdump',\n  # unless we find 'file', for example because we are cross-compiling.\n  if ( file / ) >/dev/null 2>&1; then\n    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n    lt_cv_file_magic_cmd='func_win32_libid'\n  else\n    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'\n    lt_cv_file_magic_cmd='$OBJDUMP -f'\n  fi\n  ;;\n\ncegcc)\n  # use the weaker test based on 'objdump'. See mingw*.\n  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'\n  lt_cv_file_magic_cmd='$OBJDUMP -f'\n  ;;\n\ndarwin* | rhapsody*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nfreebsd* | dragonfly*)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    case $host_cpu in\n    i*86 )\n      # Not sure whether the presence of OpenBSD here was a mistake.\n      # Let's accept both of them until this is cleared up.\n      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'\n      lt_cv_file_magic_cmd=/usr/bin/file\n      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`\n      ;;\n    esac\n  else\n    lt_cv_deplibs_check_method=pass_all\n  fi\n  ;;\n\ngnu*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nhpux10.20* | hpux11*)\n  lt_cv_file_magic_cmd=/usr/bin/file\n  case $host_cpu in\n  ia64*)\n    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'\n    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so\n    ;;\n  hppa*64*)\n    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'\n    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl\n    ;;\n  *)\n    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'\n    lt_cv_file_magic_test_file=/usr/lib/libc.sl\n    ;;\n  esac\n  ;;\n\ninterix[3-9]*)\n  # PIC code is broken on Interix 3.x, that's why |\\.a not |_pic\\.a here\n  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so|\\.a)$'\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $LD in\n  *-32|*\"-32 \") libmagic=32-bit;;\n  *-n32|*\"-n32 \") libmagic=N32;;\n  *-64|*\"-64 \") libmagic=64-bit;;\n  *) libmagic=never-match;;\n  esac\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nnetbsd* | netbsdelf*-gnu)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so\\.[0-9]+\\.[0-9]+|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so|_pic\\.a)$'\n  fi\n  ;;\n\nnewos6*)\n  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'\n  lt_cv_file_magic_cmd=/usr/bin/file\n  lt_cv_file_magic_test_file=/usr/lib/libnls.so\n  ;;\n\n*nto* | *qnx*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nopenbsd*)\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so\\.[0-9]+\\.[0-9]+|\\.so|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\\.so\\.[0-9]+\\.[0-9]+|_pic\\.a)$'\n  fi\n  ;;\n\nosf3* | osf4* | osf5*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nrdos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsolaris*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv4 | sysv4.3*)\n  case $host_vendor in\n  motorola)\n    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'\n    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`\n    ;;\n  ncr)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  sequent)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'\n    ;;\n  sni)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method=\"file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib\"\n    lt_cv_file_magic_test_file=/lib/libc.so\n    ;;\n  siemens)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  pc)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  esac\n  ;;\n\ntpf*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\nesac\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method\" >&5\n$as_echo \"$lt_cv_deplibs_check_method\" >&6; }\nfile_magic_cmd=$lt_cv_file_magic_cmd\ndeplibs_check_method=$lt_cv_deplibs_check_method\ntest -z \"$deplibs_check_method\" && deplibs_check_method=unknown\n\n\n\n\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ar\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ar; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_AR+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$AR\"; then\n  ac_cv_prog_AR=\"$AR\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_AR=\"${ac_tool_prefix}ar\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nAR=$ac_cv_prog_AR\nif test -n \"$AR\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $AR\" >&5\n$as_echo \"$AR\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_AR\"; then\n  ac_ct_AR=$AR\n  # Extract the first word of \"ar\", so it can be a program name with args.\nset dummy ar; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_AR+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_AR\"; then\n  ac_cv_prog_ac_ct_AR=\"$ac_ct_AR\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_AR=\"ar\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_AR=$ac_cv_prog_ac_ct_AR\nif test -n \"$ac_ct_AR\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR\" >&5\n$as_echo \"$ac_ct_AR\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_AR\" = x; then\n    AR=\"false\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    AR=$ac_ct_AR\n  fi\nelse\n  AR=\"$ac_cv_prog_AR\"\nfi\n\ntest -z \"$AR\" && AR=ar\ntest -z \"$AR_FLAGS\" && AR_FLAGS=cru\n\n\n\n\n\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}strip\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$STRIP\"; then\n  ac_cv_prog_STRIP=\"$STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_STRIP=\"${ac_tool_prefix}strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nSTRIP=$ac_cv_prog_STRIP\nif test -n \"$STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $STRIP\" >&5\n$as_echo \"$STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_STRIP\"; then\n  ac_ct_STRIP=$STRIP\n  # Extract the first word of \"strip\", so it can be a program name with args.\nset dummy strip; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_STRIP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_STRIP\"; then\n  ac_cv_prog_ac_ct_STRIP=\"$ac_ct_STRIP\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_STRIP=\"strip\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP\nif test -n \"$ac_ct_STRIP\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP\" >&5\n$as_echo \"$ac_ct_STRIP\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_STRIP\" = x; then\n    STRIP=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    STRIP=$ac_ct_STRIP\n  fi\nelse\n  STRIP=\"$ac_cv_prog_STRIP\"\nfi\n\ntest -z \"$STRIP\" && STRIP=:\n\n\n\n\n\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ranlib\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_RANLIB+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$RANLIB\"; then\n  ac_cv_prog_RANLIB=\"$RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_RANLIB=\"${ac_tool_prefix}ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nRANLIB=$ac_cv_prog_RANLIB\nif test -n \"$RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $RANLIB\" >&5\n$as_echo \"$RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_RANLIB\"; then\n  ac_ct_RANLIB=$RANLIB\n  # Extract the first word of \"ranlib\", so it can be a program name with args.\nset dummy ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_RANLIB+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_RANLIB\"; then\n  ac_cv_prog_ac_ct_RANLIB=\"$ac_ct_RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_RANLIB=\"ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB\nif test -n \"$ac_ct_RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB\" >&5\n$as_echo \"$ac_ct_RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_RANLIB\" = x; then\n    RANLIB=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    RANLIB=$ac_ct_RANLIB\n  fi\nelse\n  RANLIB=\"$ac_cv_prog_RANLIB\"\nfi\n\ntest -z \"$RANLIB\" && RANLIB=:\n\n\n\n\n\n\n# Determine commands to create old-style static archives.\nold_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'\nold_postinstall_cmds='chmod 644 $oldlib'\nold_postuninstall_cmds=\n\nif test -n \"$RANLIB\"; then\n  case $host_os in\n  openbsd*)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB -t \\$oldlib\"\n    ;;\n  *)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB \\$oldlib\"\n    ;;\n  esac\n  old_archive_cmds=\"$old_archive_cmds~\\$RANLIB \\$oldlib\"\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n\n\n# Check for command to grab the raw symbol name followed by C symbol from nm.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object\" >&5\n$as_echo_n \"checking command to parse $NM output from $compiler object... \" >&6; }\nif test \"${lt_cv_sys_global_symbol_pipe+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n# These are sane defaults that work on at least a few old systems.\n# [They come from Ultrix.  What could be older than Ultrix?!! ;)]\n\n# Character class describing NM global symbol codes.\nsymcode='[BCDEGRST]'\n\n# Regexp to match symbols that can be accessed directly from C.\nsympat='\\([_A-Za-z][_A-Za-z0-9]*\\)'\n\n# Define system-specific variables.\ncase $host_os in\naix*)\n  symcode='[BCDT]'\n  ;;\ncygwin* | mingw* | pw32* | cegcc*)\n  symcode='[ABCDGISTW]'\n  ;;\nhpux*)\n  if test \"$host_cpu\" = ia64; then\n    symcode='[ABCDEGRST]'\n  fi\n  ;;\nirix* | nonstopux*)\n  symcode='[BCDEGRST]'\n  ;;\nosf*)\n  symcode='[BCDEGQRST]'\n  ;;\nsolaris*)\n  symcode='[BDRT]'\n  ;;\nsco3.2v5*)\n  symcode='[DT]'\n  ;;\nsysv4.2uw2*)\n  symcode='[DT]'\n  ;;\nsysv5* | sco5v6* | unixware* | OpenUNIX*)\n  symcode='[ABDT]'\n  ;;\nsysv4)\n  symcode='[DFNSTU]'\n  ;;\nesac\n\n# If we're using GNU nm, then use its standard symbol codes.\ncase `$NM -V 2>&1` in\n*GNU* | *'with BFD'*)\n  symcode='[ABCDGIRSTW]' ;;\nesac\n\n# Transform an extracted symbol line into a proper C declaration.\n# Some systems (esp. on ia64) link data and code symbols differently,\n# so use this general approach.\nlt_cv_sys_global_symbol_to_cdecl=\"sed -n -e 's/^T .* \\(.*\\)$/extern int \\1();/p' -e 's/^$symcode* .* \\(.*\\)$/extern char \\1;/p'\"\n\n# Transform an extracted symbol line into symbol name and symbol address\nlt_cv_sys_global_symbol_to_c_name_address=\"sed -n -e 's/^: \\([^ ]*\\) $/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([^ ]*\\) \\([^ ]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p'\"\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix=\"sed -n -e 's/^: \\([^ ]*\\) $/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([^ ]*\\) \\(lib[^ ]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p' -e 's/^$symcode* \\([^ ]*\\) \\([^ ]*\\)$/  {\\\"lib\\2\\\", (void *) \\&\\2},/p'\"\n\n# Handle CRLF in mingw tool chain\nopt_cr=\ncase $build_os in\nmingw*)\n  opt_cr=`$ECHO 'x\\{0,1\\}' | tr x '\\015'` # option cr in regexp\n  ;;\nesac\n\n# Try without a prefix underscore, then with it.\nfor ac_symprfx in \"\" \"_\"; do\n\n  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.\n  symxfrm=\"\\\\1 $ac_symprfx\\\\2 \\\\2\"\n\n  # Write the raw and C identifiers.\n  if test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n    # Fake it for dumpbin and say T for any non-static function\n    # and D for any global variable.\n    # Also find C++ and __fastcall symbols from MSVC++,\n    # which start with @ or ?.\n    lt_cv_sys_global_symbol_pipe=\"$AWK '\"\\\n\"     {last_section=section; section=\\$ 3};\"\\\n\"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};\"\\\n\"     \\$ 0!~/External *\\|/{next};\"\\\n\"     / 0+ UNDEF /{next}; / UNDEF \\([^|]\\)*()/{next};\"\\\n\"     {if(hide[section]) next};\"\\\n\"     {f=0}; \\$ 0~/\\(\\).*\\|/{f=1}; {printf f ? \\\"T \\\" : \\\"D \\\"};\"\\\n\"     {split(\\$ 0, a, /\\||\\r/); split(a[2], s)};\"\\\n\"     s[1]~/^[@?]/{print s[1], s[1]; next};\"\\\n\"     s[1]~prfx {split(s[1],t,\\\"@\\\"); print t[1], substr(t[1],length(prfx))}\"\\\n\"     ' prfx=^$ac_symprfx\"\n  else\n    lt_cv_sys_global_symbol_pipe=\"sed -n -e 's/^.*[\t ]\\($symcode$symcode*\\)[\t ][\t ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'\"\n  fi\n\n  # Check to see that the pipe works correctly.\n  pipe_works=no\n\n  rm -f conftest*\n  cat > conftest.$ac_ext <<_LT_EOF\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nchar nm_test_var;\nvoid nm_test_func(void);\nvoid nm_test_func(void){}\n#ifdef __cplusplus\n}\n#endif\nint main(){nm_test_var='a';nm_test_func();return(0);}\n_LT_EOF\n\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    # Now try to grab the symbols.\n    nlist=conftest.nm\n    if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$NM conftest.$ac_objext \\| $lt_cv_sys_global_symbol_pipe \\> $nlist\\\"\"; } >&5\n  (eval $NM conftest.$ac_objext \\| $lt_cv_sys_global_symbol_pipe \\> $nlist) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s \"$nlist\"; then\n      # Try sorting and uniquifying the output.\n      if sort \"$nlist\" | uniq > \"$nlist\"T; then\n\tmv -f \"$nlist\"T \"$nlist\"\n      else\n\trm -f \"$nlist\"T\n      fi\n\n      # Make sure that we snagged all the symbols we need.\n      if $GREP ' nm_test_var$' \"$nlist\" >/dev/null; then\n\tif $GREP ' nm_test_func$' \"$nlist\" >/dev/null; then\n\t  cat <<_LT_EOF > conftest.$ac_ext\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n_LT_EOF\n\t  # Now generate the symbol file.\n\t  eval \"$lt_cv_sys_global_symbol_to_cdecl\"' < \"$nlist\" | $GREP -v main >> conftest.$ac_ext'\n\n\t  cat <<_LT_EOF >> conftest.$ac_ext\n\n/* The mapping between symbol names and symbols.  */\nconst struct {\n  const char *name;\n  void       *address;\n}\nlt__PROGRAM__LTX_preloaded_symbols[] =\n{\n  { \"@PROGRAM@\", (void *) 0 },\n_LT_EOF\n\t  $SED \"s/^$symcode$symcode* \\(.*\\) \\(.*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/\" < \"$nlist\" | $GREP -v main >> conftest.$ac_ext\n\t  cat <<\\_LT_EOF >> conftest.$ac_ext\n  {0, (void *) 0}\n};\n\n/* This works around a problem in FreeBSD linker */\n#ifdef FREEBSD_WORKAROUND\nstatic const void *lt_preloaded_setup() {\n  return lt__PROGRAM__LTX_preloaded_symbols;\n}\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n_LT_EOF\n\t  # Now try linking the two files.\n\t  mv conftest.$ac_objext conftstm.$ac_objext\n\t  lt_save_LIBS=\"$LIBS\"\n\t  lt_save_CFLAGS=\"$CFLAGS\"\n\t  LIBS=\"conftstm.$ac_objext\"\n\t  CFLAGS=\"$CFLAGS$lt_prog_compiler_no_builtin_flag\"\n\t  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_link\\\"\"; } >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s conftest${ac_exeext}; then\n\t    pipe_works=yes\n\t  fi\n\t  LIBS=\"$lt_save_LIBS\"\n\t  CFLAGS=\"$lt_save_CFLAGS\"\n\telse\n\t  echo \"cannot find nm_test_func in $nlist\" >&5\n\tfi\n      else\n\techo \"cannot find nm_test_var in $nlist\" >&5\n      fi\n    else\n      echo \"cannot run $lt_cv_sys_global_symbol_pipe\" >&5\n    fi\n  else\n    echo \"$progname: failed program was:\" >&5\n    cat conftest.$ac_ext >&5\n  fi\n  rm -rf conftest* conftst*\n\n  # Do not use the global_symbol_pipe unless it works.\n  if test \"$pipe_works\" = yes; then\n    break\n  else\n    lt_cv_sys_global_symbol_pipe=\n  fi\ndone\n\nfi\n\nif test -z \"$lt_cv_sys_global_symbol_pipe\"; then\n  lt_cv_sys_global_symbol_to_cdecl=\nfi\nif test -z \"$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: failed\" >&5\n$as_echo \"failed\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ok\" >&5\n$as_echo \"ok\" >&6; }\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n# Check whether --enable-libtool-lock was given.\nif test \"${enable_libtool_lock+set}\" = set; then :\n  enableval=$enable_libtool_lock;\nfi\n\ntest \"x$enable_libtool_lock\" != xno && enable_libtool_lock=yes\n\n# Some flags need to be propagated to the compiler or linker for good\n# libtool support.\ncase $host in\nia64-*-hpux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    case `/usr/bin/file conftest.$ac_objext` in\n      *ELF-32*)\n\tHPUX_IA64_MODE=\"32\"\n\t;;\n      *ELF-64*)\n\tHPUX_IA64_MODE=\"64\"\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n*-*-irix6*)\n  # Find out which ABI we are using.\n  echo '#line 6796 \"configure\"' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    if test \"$lt_cv_prog_gnu_ld\" = yes; then\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -melf32bsmip\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -melf32bmipn32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -melf64bmip\"\n\t;;\n      esac\n    else\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -32\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -n32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -64\"\n\t  ;;\n      esac\n    fi\n  fi\n  rm -rf conftest*\n  ;;\n\nx86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \\\ns390*-*linux*|s390*-*tpf*|sparc*-*linux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    case `/usr/bin/file conftest.o` in\n      *32-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_i386_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_i386\"\n\t    ;;\n\t  ppc64-*linux*|powerpc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32ppclinux\"\n\t    ;;\n\t  s390x-*linux*)\n\t    LD=\"${LD-ld} -m elf_s390\"\n\t    ;;\n\t  sparc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32_sparc\"\n\t    ;;\n\tesac\n\t;;\n      *64-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_x86_64_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_x86_64\"\n\t    ;;\n\t  ppc*-*linux*|powerpc*-*linux*)\n\t    LD=\"${LD-ld} -m elf64ppc\"\n\t    ;;\n\t  s390*-*linux*|s390*-*tpf*)\n\t    LD=\"${LD-ld} -m elf64_s390\"\n\t    ;;\n\t  sparc*-*linux*)\n\t    LD=\"${LD-ld} -m elf64_sparc\"\n\t    ;;\n\tesac\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n\n*-*-sco3.2v5*)\n  # On SCO OpenServer 5, we need -belf to get full-featured binaries.\n  SAVE_CFLAGS=\"$CFLAGS\"\n  CFLAGS=\"$CFLAGS -belf\"\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf\" >&5\n$as_echo_n \"checking whether the C compiler needs -belf... \" >&6; }\nif test \"${lt_cv_cc_needs_belf+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n     cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  lt_cv_cc_needs_belf=yes\nelse\n  lt_cv_cc_needs_belf=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n     ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf\" >&5\n$as_echo \"$lt_cv_cc_needs_belf\" >&6; }\n  if test x\"$lt_cv_cc_needs_belf\" != x\"yes\"; then\n    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf\n    CFLAGS=\"$SAVE_CFLAGS\"\n  fi\n  ;;\nsparc*-*solaris*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n    case `/usr/bin/file conftest.o` in\n    *64-bit*)\n      case $lt_cv_prog_gnu_ld in\n      yes*) LD=\"${LD-ld} -m elf64_sparc\" ;;\n      *)\n\tif ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then\n\t  LD=\"${LD-ld} -64\"\n\tfi\n\t;;\n      esac\n      ;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\nesac\n\nneed_locks=\"$enable_libtool_lock\"\n\n\n  case $host_os in\n    rhapsody* | darwin*)\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}dsymutil\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}dsymutil; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_DSYMUTIL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$DSYMUTIL\"; then\n  ac_cv_prog_DSYMUTIL=\"$DSYMUTIL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_DSYMUTIL=\"${ac_tool_prefix}dsymutil\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nDSYMUTIL=$ac_cv_prog_DSYMUTIL\nif test -n \"$DSYMUTIL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL\" >&5\n$as_echo \"$DSYMUTIL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_DSYMUTIL\"; then\n  ac_ct_DSYMUTIL=$DSYMUTIL\n  # Extract the first word of \"dsymutil\", so it can be a program name with args.\nset dummy dsymutil; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_DSYMUTIL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_DSYMUTIL\"; then\n  ac_cv_prog_ac_ct_DSYMUTIL=\"$ac_ct_DSYMUTIL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_DSYMUTIL=\"dsymutil\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL\nif test -n \"$ac_ct_DSYMUTIL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL\" >&5\n$as_echo \"$ac_ct_DSYMUTIL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_DSYMUTIL\" = x; then\n    DSYMUTIL=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    DSYMUTIL=$ac_ct_DSYMUTIL\n  fi\nelse\n  DSYMUTIL=\"$ac_cv_prog_DSYMUTIL\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}nmedit\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}nmedit; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_NMEDIT+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$NMEDIT\"; then\n  ac_cv_prog_NMEDIT=\"$NMEDIT\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_NMEDIT=\"${ac_tool_prefix}nmedit\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nNMEDIT=$ac_cv_prog_NMEDIT\nif test -n \"$NMEDIT\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $NMEDIT\" >&5\n$as_echo \"$NMEDIT\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_NMEDIT\"; then\n  ac_ct_NMEDIT=$NMEDIT\n  # Extract the first word of \"nmedit\", so it can be a program name with args.\nset dummy nmedit; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_NMEDIT+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_NMEDIT\"; then\n  ac_cv_prog_ac_ct_NMEDIT=\"$ac_ct_NMEDIT\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_NMEDIT=\"nmedit\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT\nif test -n \"$ac_ct_NMEDIT\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT\" >&5\n$as_echo \"$ac_ct_NMEDIT\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_NMEDIT\" = x; then\n    NMEDIT=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    NMEDIT=$ac_ct_NMEDIT\n  fi\nelse\n  NMEDIT=\"$ac_cv_prog_NMEDIT\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}lipo\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}lipo; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_LIPO+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$LIPO\"; then\n  ac_cv_prog_LIPO=\"$LIPO\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_LIPO=\"${ac_tool_prefix}lipo\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nLIPO=$ac_cv_prog_LIPO\nif test -n \"$LIPO\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $LIPO\" >&5\n$as_echo \"$LIPO\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_LIPO\"; then\n  ac_ct_LIPO=$LIPO\n  # Extract the first word of \"lipo\", so it can be a program name with args.\nset dummy lipo; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_LIPO+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_LIPO\"; then\n  ac_cv_prog_ac_ct_LIPO=\"$ac_ct_LIPO\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_LIPO=\"lipo\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO\nif test -n \"$ac_ct_LIPO\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO\" >&5\n$as_echo \"$ac_ct_LIPO\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_LIPO\" = x; then\n    LIPO=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    LIPO=$ac_ct_LIPO\n  fi\nelse\n  LIPO=\"$ac_cv_prog_LIPO\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}otool\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}otool; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OTOOL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OTOOL\"; then\n  ac_cv_prog_OTOOL=\"$OTOOL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OTOOL=\"${ac_tool_prefix}otool\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOTOOL=$ac_cv_prog_OTOOL\nif test -n \"$OTOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OTOOL\" >&5\n$as_echo \"$OTOOL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OTOOL\"; then\n  ac_ct_OTOOL=$OTOOL\n  # Extract the first word of \"otool\", so it can be a program name with args.\nset dummy otool; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OTOOL+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OTOOL\"; then\n  ac_cv_prog_ac_ct_OTOOL=\"$ac_ct_OTOOL\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OTOOL=\"otool\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL\nif test -n \"$ac_ct_OTOOL\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL\" >&5\n$as_echo \"$ac_ct_OTOOL\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OTOOL\" = x; then\n    OTOOL=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OTOOL=$ac_ct_OTOOL\n  fi\nelse\n  OTOOL=\"$ac_cv_prog_OTOOL\"\nfi\n\n    if test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}otool64\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}otool64; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_OTOOL64+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$OTOOL64\"; then\n  ac_cv_prog_OTOOL64=\"$OTOOL64\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_OTOOL64=\"${ac_tool_prefix}otool64\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nOTOOL64=$ac_cv_prog_OTOOL64\nif test -n \"$OTOOL64\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $OTOOL64\" >&5\n$as_echo \"$OTOOL64\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_OTOOL64\"; then\n  ac_ct_OTOOL64=$OTOOL64\n  # Extract the first word of \"otool64\", so it can be a program name with args.\nset dummy otool64; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_OTOOL64+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_OTOOL64\"; then\n  ac_cv_prog_ac_ct_OTOOL64=\"$ac_ct_OTOOL64\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_OTOOL64=\"otool64\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64\nif test -n \"$ac_ct_OTOOL64\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64\" >&5\n$as_echo \"$ac_ct_OTOOL64\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_OTOOL64\" = x; then\n    OTOOL64=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    OTOOL64=$ac_ct_OTOOL64\n  fi\nelse\n  OTOOL64=\"$ac_cv_prog_OTOOL64\"\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag\" >&5\n$as_echo_n \"checking for -single_module linker flag... \" >&6; }\nif test \"${lt_cv_apple_cc_single_mod+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_apple_cc_single_mod=no\n      if test -z \"${LT_MULTI_MODULE}\"; then\n\t# By default we will add the -single_module flag. You can override\n\t# by either setting the environment variable LT_MULTI_MODULE\n\t# non-empty at configure time, or by adding -multi_module to the\n\t# link flags.\n\trm -rf libconftest.dylib*\n\techo \"int foo(void){return 1;}\" > conftest.c\n\techo \"$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n-dynamiclib -Wl,-single_module conftest.c\" >&5\n\t$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n\t  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err\n        _lt_result=$?\n\tif test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then\n\t  lt_cv_apple_cc_single_mod=yes\n\telse\n\t  cat conftest.err >&5\n\tfi\n\trm -rf libconftest.dylib*\n\trm -f conftest.*\n      fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod\" >&5\n$as_echo \"$lt_cv_apple_cc_single_mod\" >&6; }\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag\" >&5\n$as_echo_n \"checking for -exported_symbols_list linker flag... \" >&6; }\nif test \"${lt_cv_ld_exported_symbols_list+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_ld_exported_symbols_list=no\n      save_LDFLAGS=$LDFLAGS\n      echo \"_main\" > conftest.sym\n      LDFLAGS=\"$LDFLAGS -Wl,-exported_symbols_list,conftest.sym\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  lt_cv_ld_exported_symbols_list=yes\nelse\n  lt_cv_ld_exported_symbols_list=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\tLDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list\" >&5\n$as_echo \"$lt_cv_ld_exported_symbols_list\" >&6; }\n    case $host_os in\n    rhapsody* | darwin1.[012])\n      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;\n    darwin1.*)\n      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n    darwin*) # darwin 5.x on\n      # if running on 10.5 or later, the deployment target defaults\n      # to the OS version, if on x86, and 10.4, the deployment\n      # target defaults to 10.4. Don't you love it?\n      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in\n\t10.0,*86*-darwin8*|10.0,*-darwin[91]*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n\t10.[012]*)\n\t  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n\t10.*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n      esac\n    ;;\n  esac\n    if test \"$lt_cv_apple_cc_single_mod\" = \"yes\"; then\n      _lt_dar_single_mod='$single_module'\n    fi\n    if test \"$lt_cv_ld_exported_symbols_list\" = \"yes\"; then\n      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'\n    else\n      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'\n    fi\n    if test \"$DSYMUTIL\" != \":\"; then\n      _lt_dsymutil='~$DSYMUTIL $lib || :'\n    else\n      _lt_dsymutil=\n    fi\n    ;;\n  esac\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ANSI C header files\" >&5\n$as_echo_n \"checking for ANSI C header files... \" >&6; }\nif test \"${ac_cv_header_stdc+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <float.h>\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_header_stdc=yes\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test $ac_cv_header_stdc = yes; then\n  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <string.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"memchr\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"free\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.\n  if test \"$cross_compiling\" = yes; then :\n  :\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ctype.h>\n#include <stdlib.h>\n#if ((' ' & 0x0FF) == 0x020)\n# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')\n# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))\n#else\n# define ISLOWER(c) \\\n\t\t   (('a' <= (c) && (c) <= 'i') \\\n\t\t     || ('j' <= (c) && (c) <= 'r') \\\n\t\t     || ('s' <= (c) && (c) <= 'z'))\n# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))\n#endif\n\n#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))\nint\nmain ()\n{\n  int i;\n  for (i = 0; i < 256; i++)\n    if (XOR (islower (i), ISLOWER (i))\n\t|| toupper (i) != TOUPPER (i))\n      return 2;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc\" >&5\n$as_echo \"$ac_cv_header_stdc\" >&6; }\nif test $ac_cv_header_stdc = yes; then\n\n$as_echo \"#define STDC_HEADERS 1\" >>confdefs.h\n\nfi\n\n# On IRIX 5.3, sys/types and inttypes.h are conflicting.\nfor ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \\\n\t\t  inttypes.h stdint.h unistd.h\ndo :\n  as_ac_Header=`$as_echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nac_fn_c_check_header_compile \"$LINENO\" \"$ac_header\" \"$as_ac_Header\" \"$ac_includes_default\n\"\neval as_val=\\$$as_ac_Header\n   if test \"x$as_val\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define `$as_echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nfor ac_header in dlfcn.h\ndo :\n  ac_fn_c_check_header_compile \"$LINENO\" \"dlfcn.h\" \"ac_cv_header_dlfcn_h\" \"$ac_includes_default\n\"\nif test \"x$ac_cv_header_dlfcn_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_DLFCN_H 1\n_ACEOF\n\nfi\n\ndone\n\n\n\nac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\nif test -z \"$CXX\"; then\n  if test -n \"$CCC\"; then\n    CXX=$CCC\n  else\n    if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CXX\"; then\n  ac_cv_prog_CXX=\"$CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_CXX=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCXX=$ac_cv_prog_CXX\nif test -n \"$CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CXX\" >&5\n$as_echo \"$CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CXX\" && break\n  done\nfi\nif test -z \"$CXX\"; then\n  ac_ct_CXX=$CXX\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_ac_ct_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CXX\"; then\n  ac_cv_prog_ac_ct_CXX=\"$ac_ct_CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_ac_ct_CXX=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CXX=$ac_cv_prog_ac_ct_CXX\nif test -n \"$ac_ct_CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX\" >&5\n$as_echo \"$ac_ct_CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CXX\" && break\ndone\n\n  if test \"x$ac_ct_CXX\" = x; then\n    CXX=\"g++\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CXX=$ac_ct_CXX\n  fi\nfi\n\n  fi\nfi\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C++ compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C++ compiler... \" >&6; }\nif test \"${ac_cv_cxx_compiler_gnu+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_cxx_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu\" >&5\n$as_echo \"$ac_cv_cxx_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GXX=yes\nelse\n  GXX=\nfi\nac_test_CXXFLAGS=${CXXFLAGS+set}\nac_save_CXXFLAGS=$CXXFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g\" >&5\n$as_echo_n \"checking whether $CXX accepts -g... \" >&6; }\nif test \"${ac_cv_prog_cxx_g+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_cxx_werror_flag=$ac_cxx_werror_flag\n   ac_cxx_werror_flag=yes\n   ac_cv_prog_cxx_g=no\n   CXXFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nelse\n  CXXFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\nelse\n  ac_cxx_werror_flag=$ac_save_cxx_werror_flag\n\t CXXFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_cxx_werror_flag=$ac_save_cxx_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g\" >&5\n$as_echo \"$ac_cv_prog_cxx_g\" >&6; }\nif test \"$ac_test_CXXFLAGS\" = set; then\n  CXXFLAGS=$ac_save_CXXFLAGS\nelif test $ac_cv_prog_cxx_g = yes; then\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-g -O2\"\n  else\n    CXXFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-O2\"\n  else\n    CXXFLAGS=\n  fi\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\ndepcc=\"$CXX\"  am_compiler_list=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc\" >&5\n$as_echo_n \"checking dependency style of $depcc... \" >&6; }\nif test \"${am_cv_CXX_dependencies_compiler_type+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$AMDEP_TRUE\" && test -f \"$am_depcomp\"; then\n  # We make a subdir and do the tests there.  Otherwise we can end up\n  # making bogus files that we don't know about and never remove.  For\n  # instance it was reported that on HP-UX the gcc test will end up\n  # making a dummy file named `D' -- because `-MD' means `put the output\n  # in D'.\n  mkdir conftest.dir\n  # Copy depcomp to subdir because otherwise we won't find it if we're\n  # using a relative directory.\n  cp \"$am_depcomp\" conftest.dir\n  cd conftest.dir\n  # We will build objects and dependencies in a subdirectory because\n  # it helps to detect inapplicable dependency modes.  For instance\n  # both Tru64's cc and ICC support -MD to output dependencies as a\n  # side effect of compilation, but ICC will put the dependencies in\n  # the current directory while Tru64 will put them in the object\n  # directory.\n  mkdir sub\n\n  am_cv_CXX_dependencies_compiler_type=none\n  if test \"$am_compiler_list\" = \"\"; then\n     am_compiler_list=`sed -n 's/^#*\\([a-zA-Z0-9]*\\))$/\\1/p' < ./depcomp`\n  fi\n  for depmode in $am_compiler_list; do\n    # Setup a source with many dependencies, because some compilers\n    # like to wrap large dependency lists on column 80 (with \\), and\n    # we should not choose a depcomp mode which is confused by this.\n    #\n    # We need to recreate these files for each test, as the compiler may\n    # overwrite some of them when testing with obscure command lines.\n    # This happens at least with the AIX C compiler.\n    : > sub/conftest.c\n    for i in 1 2 3 4 5 6; do\n      echo '#include \"conftst'$i'.h\"' >> sub/conftest.c\n      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with\n      # Solaris 8's {/usr,}/bin/sh.\n      touch sub/conftst$i.h\n    done\n    echo \"${am__include} ${am__quote}sub/conftest.Po${am__quote}\" > confmf\n\n    case $depmode in\n    nosideeffect)\n      # after this tag, mechanisms are not by side-effect, so they'll\n      # only be used when explicitly requested\n      if test \"x$enable_dependency_tracking\" = xyes; then\n\tcontinue\n      else\n\tbreak\n      fi\n      ;;\n    none) break ;;\n    esac\n    # We check with `-c' and `-o' for the sake of the \"dashmstdout\"\n    # mode.  It turns out that the SunPro C++ compiler does not properly\n    # handle `-M -o', and we need to detect this.\n    if depmode=$depmode \\\n       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \\\n       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \\\n       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \\\n         >/dev/null 2>conftest.err &&\n       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&\n       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&\n       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then\n      # icc doesn't choke on unknown options, it will just issue warnings\n      # or remarks (even with -Werror).  So we grep stderr for any message\n      # that says an option was ignored or not supported.\n      # When given -MP, icc 7.0 and 7.1 complain thusly:\n      #   icc: Command line warning: ignoring option '-M'; no argument required\n      # The diagnosis changed in icc 8.0:\n      #   icc: Command line remark: option '-MP' not supported\n      if (grep 'ignoring option' conftest.err ||\n          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else\n        am_cv_CXX_dependencies_compiler_type=$depmode\n        break\n      fi\n    fi\n  done\n\n  cd ..\n  rm -rf conftest.dir\nelse\n  am_cv_CXX_dependencies_compiler_type=none\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type\" >&5\n$as_echo \"$am_cv_CXX_dependencies_compiler_type\" >&6; }\nCXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type\n\n\n\nif\n  test \"x$enable_dependency_tracking\" != xno \\\n  && test \"$am_cv_CXX_dependencies_compiler_type\" = gcc3; then\n  am__fastdepCXX_TRUE=\n  am__fastdepCXX_FALSE='#'\nelse\n  am__fastdepCXX_TRUE='#'\n  am__fastdepCXX_FALSE=\nfi\n\n\nif test -n \"$CXX\" && ( test \"X$CXX\" != \"Xno\" &&\n    ( (test \"X$CXX\" = \"Xg++\" && `g++ -v >/dev/null 2>&1` ) ||\n    (test \"X$CXX\" != \"Xg++\"))) ; then\n  ac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor\" >&5\n$as_echo_n \"checking how to run the C++ preprocessor... \" >&6; }\nif test -z \"$CXXCPP\"; then\n  if test \"${ac_cv_prog_CXXCPP+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n      # Double quotes because CXXCPP needs to be expanded\n    for CXXCPP in \"$CXX -E\" \"/lib/cpp\"\n    do\n      ac_preproc_ok=false\nfor ac_cxx_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_cxx_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_cxx_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n  break\nfi\n\n    done\n    ac_cv_prog_CXXCPP=$CXXCPP\n\nfi\n  CXXCPP=$ac_cv_prog_CXXCPP\nelse\n  ac_cv_prog_CXXCPP=$CXXCPP\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CXXCPP\" >&5\n$as_echo \"$CXXCPP\" >&6; }\nac_preproc_ok=false\nfor ac_cxx_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_cxx_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_cxx_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n_lt_caught_CXX_error=yes; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nelse\n  _lt_caught_CXX_error=yes\nfi\n\n\n\n\n\n# Set options\n\n\n\n        enable_dlopen=no\n\n\n  enable_win32_dll=no\n\n\n            # Check whether --enable-shared was given.\nif test \"${enable_shared+set}\" = set; then :\n  enableval=$enable_shared; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_shared=yes ;;\n    no) enable_shared=no ;;\n    *)\n      enable_shared=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_shared=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_shared=yes\nfi\n\n\n\n\n\n\n\n\n\n  # Check whether --enable-static was given.\nif test \"${enable_static+set}\" = set; then :\n  enableval=$enable_static; p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_static=yes ;;\n    no) enable_static=no ;;\n    *)\n     enable_static=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_static=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac\nelse\n  enable_static=yes\nfi\n\n\n\n\n\n\n\n\n\n\n# Check whether --with-pic was given.\nif test \"${with_pic+set}\" = set; then :\n  withval=$with_pic; pic_mode=\"$withval\"\nelse\n  pic_mode=default\nfi\n\n\ntest -z \"$pic_mode\" && pic_mode=default\n\n\n\n\n\n\n\n\n\n\n\n# This can be used to rebuild libtool when needed\nLIBTOOL_DEPS=\"$ltmain\"\n\n# Always use our own libtool.\nLIBTOOL='$(SHELL) $(top_builddir)/libtool'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ntest -z \"$LN_S\" && LN_S=\"ln -s\"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nif test -n \"${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for objdir\" >&5\n$as_echo_n \"checking for objdir... \" >&6; }\nif test \"${lt_cv_objdir+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  rm -f .libs 2>/dev/null\nmkdir .libs 2>/dev/null\nif test -d .libs; then\n  lt_cv_objdir=.libs\nelse\n  # MS-DOS does not allow filenames that begin with a dot.\n  lt_cv_objdir=_libs\nfi\nrmdir .libs 2>/dev/null\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir\" >&5\n$as_echo \"$lt_cv_objdir\" >&6; }\nobjdir=$lt_cv_objdir\n\n\n\n\n\ncat >>confdefs.h <<_ACEOF\n#define LT_OBJDIR \"$lt_cv_objdir/\"\n_ACEOF\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ncase $host_os in\naix3*)\n  # AIX sometimes has problems with the GCC collect2 program.  For some\n  # reason, if we set the COLLECT_NAMES environment variable, the problems\n  # vanish in a puff of smoke.\n  if test \"X${COLLECT_NAMES+set}\" != Xset; then\n    COLLECT_NAMES=\n    export COLLECT_NAMES\n  fi\n  ;;\nesac\n\n# Sed substitution that helps us do robust quoting.  It backslashifies\n# metacharacters that are still active within double-quoted strings.\nsed_quote_subst='s/\\([\"`$\\\\]\\)/\\\\\\1/g'\n\n# Same as above, but do not quote variable references.\ndouble_quote_subst='s/\\([\"`\\\\]\\)/\\\\\\1/g'\n\n# Sed substitution to delay expansion of an escaped shell variable in a\n# double_quote_subst'ed string.\ndelay_variable_subst='s/\\\\\\\\\\\\\\\\\\\\\\$/\\\\\\\\\\\\$/g'\n\n# Sed substitution to delay expansion of an escaped single quote.\ndelay_single_quote_subst='s/'\\''/'\\'\\\\\\\\\\\\\\'\\''/g'\n\n# Sed substitution to avoid accidental globbing in evaled expressions\nno_glob_subst='s/\\*/\\\\\\*/g'\n\n# Global variables:\nofile=libtool\ncan_build_shared=yes\n\n# All known linkers require a `.a' archive for static linking (except MSVC,\n# which needs '.lib').\nlibext=a\n\nwith_gnu_ld=\"$lt_cv_prog_gnu_ld\"\n\nold_CC=\"$CC\"\nold_CFLAGS=\"$CFLAGS\"\n\n# Set sane defaults for various variables\ntest -z \"$CC\" && CC=cc\ntest -z \"$LTCC\" && LTCC=$CC\ntest -z \"$LTCFLAGS\" && LTCFLAGS=$CFLAGS\ntest -z \"$LD\" && LD=ld\ntest -z \"$ac_objext\" && ac_objext=o\n\nfor cc_temp in $compiler\"\"; do\n  case $cc_temp in\n    compile | *[\\\\/]compile | ccache | *[\\\\/]ccache ) ;;\n    distcc | *[\\\\/]distcc | purify | *[\\\\/]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`$ECHO \"X$cc_temp\" | $Xsed -e 's%.*/%%' -e \"s%^$host_alias-%%\"`\n\n\n# Only perform the check for file, if the check method requires it\ntest -z \"$MAGIC_CMD\" && MAGIC_CMD=file\ncase $deplibs_check_method in\nfile_magic*)\n  if test \"$file_magic_cmd\" = '$MAGIC_CMD'; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file\" >&5\n$as_echo_n \"checking for ${ac_tool_prefix}file... \" >&6; }\nif test \"${lt_cv_path_MAGIC_CMD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $MAGIC_CMD in\n[\\\\/*] |  ?:[\\\\/]*)\n  lt_cv_path_MAGIC_CMD=\"$MAGIC_CMD\" # Let the user override the test with a path.\n  ;;\n*)\n  lt_save_MAGIC_CMD=\"$MAGIC_CMD\"\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  ac_dummy=\"/usr/bin$PATH_SEPARATOR$PATH\"\n  for ac_dir in $ac_dummy; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f $ac_dir/${ac_tool_prefix}file; then\n      lt_cv_path_MAGIC_CMD=\"$ac_dir/${ac_tool_prefix}file\"\n      if test -n \"$file_magic_test_file\"; then\n\tcase $deplibs_check_method in\n\t\"file_magic \"*)\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"file_magic \\(.*\\)\"`\n\t  MAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\n\t  if eval $file_magic_cmd \\$file_magic_test_file 2> /dev/null |\n\t    $EGREP \"$file_magic_regex\" > /dev/null; then\n\t    :\n\t  else\n\t    cat <<_LT_EOF 1>&2\n\n*** Warning: the command libtool uses to detect shared libraries,\n*** $file_magic_cmd, produces output that libtool cannot recognize.\n*** The result is that libtool may fail to recognize shared libraries\n*** as such.  This will affect the creation of libtool libraries that\n*** depend on shared libraries, but programs linked with such libtool\n*** libraries will work regardless of this problem.  Nevertheless, you\n*** may want to report the problem to your system manager and/or to\n*** bug-libtool@gnu.org\n\n_LT_EOF\n\t  fi ;;\n\tesac\n      fi\n      break\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\n  MAGIC_CMD=\"$lt_save_MAGIC_CMD\"\n  ;;\nesac\nfi\n\nMAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\nif test -n \"$MAGIC_CMD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD\" >&5\n$as_echo \"$MAGIC_CMD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n\n\n\nif test -z \"$lt_cv_path_MAGIC_CMD\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for file\" >&5\n$as_echo_n \"checking for file... \" >&6; }\nif test \"${lt_cv_path_MAGIC_CMD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $MAGIC_CMD in\n[\\\\/*] |  ?:[\\\\/]*)\n  lt_cv_path_MAGIC_CMD=\"$MAGIC_CMD\" # Let the user override the test with a path.\n  ;;\n*)\n  lt_save_MAGIC_CMD=\"$MAGIC_CMD\"\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  ac_dummy=\"/usr/bin$PATH_SEPARATOR$PATH\"\n  for ac_dir in $ac_dummy; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f $ac_dir/file; then\n      lt_cv_path_MAGIC_CMD=\"$ac_dir/file\"\n      if test -n \"$file_magic_test_file\"; then\n\tcase $deplibs_check_method in\n\t\"file_magic \"*)\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"file_magic \\(.*\\)\"`\n\t  MAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\n\t  if eval $file_magic_cmd \\$file_magic_test_file 2> /dev/null |\n\t    $EGREP \"$file_magic_regex\" > /dev/null; then\n\t    :\n\t  else\n\t    cat <<_LT_EOF 1>&2\n\n*** Warning: the command libtool uses to detect shared libraries,\n*** $file_magic_cmd, produces output that libtool cannot recognize.\n*** The result is that libtool may fail to recognize shared libraries\n*** as such.  This will affect the creation of libtool libraries that\n*** depend on shared libraries, but programs linked with such libtool\n*** libraries will work regardless of this problem.  Nevertheless, you\n*** may want to report the problem to your system manager and/or to\n*** bug-libtool@gnu.org\n\n_LT_EOF\n\t  fi ;;\n\tesac\n      fi\n      break\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\n  MAGIC_CMD=\"$lt_save_MAGIC_CMD\"\n  ;;\nesac\nfi\n\nMAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\nif test -n \"$MAGIC_CMD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD\" >&5\n$as_echo \"$MAGIC_CMD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  else\n    MAGIC_CMD=:\n  fi\nfi\n\n  fi\n  ;;\nesac\n\n# Use C for the default configuration in the libtool script\n\nlt_save_CC=\"$CC\"\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n# Source file extension for C test sources.\nac_ext=c\n\n# Object file extension for compiled C test sources.\nobjext=o\nobjext=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"int some_variable = 0;\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='int main(){return(0);}'\n\n\n\n\n\n\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n\n# Save the default compiler, since it gets overwritten when the other\n# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.\ncompiler_DEFAULT=$CC\n\n# save warnings/boilerplate of simple test code\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_compile_test_code\" >conftest.$ac_ext\neval \"$ac_compile\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_compiler_boilerplate=`cat conftest.err`\n$RM conftest*\n\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_link_test_code\" >conftest.$ac_ext\neval \"$ac_link\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_linker_boilerplate=`cat conftest.err`\n$RM -r conftest*\n\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n\nlt_prog_compiler_no_builtin_flag=\n\nif test \"$GCC\" = yes; then\n  lt_prog_compiler_no_builtin_flag=' -fno-builtin'\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions\" >&5\n$as_echo_n \"checking if $compiler supports -fno-rtti -fno-exceptions... \" >&6; }\nif test \"${lt_cv_prog_compiler_rtti_exceptions+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_rtti_exceptions=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"-fno-rtti -fno-exceptions\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:8669: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:8673: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_rtti_exceptions=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions\" >&5\n$as_echo \"$lt_cv_prog_compiler_rtti_exceptions\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_rtti_exceptions\" = xyes; then\n    lt_prog_compiler_no_builtin_flag=\"$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions\"\nelse\n    :\nfi\n\nfi\n\n\n\n\n\n\n  lt_prog_compiler_wl=\nlt_prog_compiler_pic=\nlt_prog_compiler_static=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC\" >&5\n$as_echo_n \"checking for $compiler option to produce PIC... \" >&6; }\n\n  if test \"$GCC\" = yes; then\n    lt_prog_compiler_wl='-Wl,'\n    lt_prog_compiler_static='-static'\n\n    case $host_os in\n      aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static='-Bstatic'\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            lt_prog_compiler_pic='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      lt_prog_compiler_pic='-DDLL_EXPORT'\n      ;;\n\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      lt_prog_compiler_pic='-fno-common'\n      ;;\n\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t# +Z the default\n\t;;\n      *)\n\tlt_prog_compiler_pic='-fPIC'\n\t;;\n      esac\n      ;;\n\n    interix[3-9]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n\n    msdosdjgpp*)\n      # Just because we use GCC doesn't mean we suddenly get shared libraries\n      # on systems that don't support them.\n      lt_prog_compiler_can_build_shared=no\n      enable_shared=no\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic='-fPIC -shared'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tlt_prog_compiler_pic=-Kconform_pic\n      fi\n      ;;\n\n    *)\n      lt_prog_compiler_pic='-fPIC'\n      ;;\n    esac\n  else\n    # PORTME Check for flag to pass linker flags through the system compiler.\n    case $host_os in\n    aix*)\n      lt_prog_compiler_wl='-Wl,'\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static='-Bstatic'\n      else\n\tlt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'\n      fi\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      lt_prog_compiler_pic='-DDLL_EXPORT'\n      ;;\n\n    hpux9* | hpux10* | hpux11*)\n      lt_prog_compiler_wl='-Wl,'\n      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but\n      # not for PA HP-UX.\n      case $host_cpu in\n      hppa*64*|ia64*)\n\t# +Z the default\n\t;;\n      *)\n\tlt_prog_compiler_pic='+Z'\n\t;;\n      esac\n      # Is there a better lt_prog_compiler_static that works with the bundled CC?\n      lt_prog_compiler_static='${wl}-a ${wl}archive'\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      lt_prog_compiler_wl='-Wl,'\n      # PIC (with -KPIC) is the default.\n      lt_prog_compiler_static='-non_shared'\n      ;;\n\n    linux* | k*bsd*-gnu | kopensolaris*-gnu)\n      case $cc_basename in\n      # old Intel for x86_64 which still supported -KPIC.\n      ecc*)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-KPIC'\n\tlt_prog_compiler_static='-static'\n        ;;\n      # icc used to be incompatible with GCC.\n      # ICC 10 doesn't accept -KPIC any more.\n      icc* | ifort*)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-fPIC'\n\tlt_prog_compiler_static='-static'\n        ;;\n      # Lahey Fortran 8.1.\n      lf95*)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='--shared'\n\tlt_prog_compiler_static='--static'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95*)\n        # Portland Group compilers (*not* the Pentium gcc compiler,\n\t# which looks to be a dead project)\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-fpic'\n\tlt_prog_compiler_static='-Bstatic'\n        ;;\n      ccc*)\n        lt_prog_compiler_wl='-Wl,'\n        # All Alpha code is PIC.\n        lt_prog_compiler_static='-non_shared'\n        ;;\n      xl*)\n\t# IBM XL C 8.0/Fortran 10.1 on PPC\n\tlt_prog_compiler_wl='-Wl,'\n\tlt_prog_compiler_pic='-qpic'\n\tlt_prog_compiler_static='-qstaticlink'\n\t;;\n      *)\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\n\t  # Sun C 5.9\n\t  lt_prog_compiler_pic='-KPIC'\n\t  lt_prog_compiler_static='-Bstatic'\n\t  lt_prog_compiler_wl='-Wl,'\n\t  ;;\n\t*Sun\\ F*)\n\t  # Sun Fortran 8.3 passes all unrecognized flags to the linker\n\t  lt_prog_compiler_pic='-KPIC'\n\t  lt_prog_compiler_static='-Bstatic'\n\t  lt_prog_compiler_wl=''\n\t  ;;\n\tesac\n\t;;\n      esac\n      ;;\n\n    newsos6)\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic='-fPIC -shared'\n      ;;\n\n    osf3* | osf4* | osf5*)\n      lt_prog_compiler_wl='-Wl,'\n      # All OSF/1 code is PIC.\n      lt_prog_compiler_static='-non_shared'\n      ;;\n\n    rdos*)\n      lt_prog_compiler_static='-non_shared'\n      ;;\n\n    solaris*)\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      case $cc_basename in\n      f77* | f90* | f95*)\n\tlt_prog_compiler_wl='-Qoption ld ';;\n      *)\n\tlt_prog_compiler_wl='-Wl,';;\n      esac\n      ;;\n\n    sunos4*)\n      lt_prog_compiler_wl='-Qoption ld '\n      lt_prog_compiler_pic='-PIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    sysv4 | sysv4.2uw2* | sysv4.3*)\n      lt_prog_compiler_wl='-Wl,'\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec ;then\n\tlt_prog_compiler_pic='-Kconform_pic'\n\tlt_prog_compiler_static='-Bstatic'\n      fi\n      ;;\n\n    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n      lt_prog_compiler_wl='-Wl,'\n      lt_prog_compiler_pic='-KPIC'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    unicos*)\n      lt_prog_compiler_wl='-Wl,'\n      lt_prog_compiler_can_build_shared=no\n      ;;\n\n    uts4*)\n      lt_prog_compiler_pic='-pic'\n      lt_prog_compiler_static='-Bstatic'\n      ;;\n\n    *)\n      lt_prog_compiler_can_build_shared=no\n      ;;\n    esac\n  fi\n\ncase $host_os in\n  # For platforms which do not support PIC, -DPIC is meaningless:\n  *djgpp*)\n    lt_prog_compiler_pic=\n    ;;\n  *)\n    lt_prog_compiler_pic=\"$lt_prog_compiler_pic -DPIC\"\n    ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic\" >&5\n$as_echo \"$lt_prog_compiler_pic\" >&6; }\n\n\n\n\n\n\n#\n# Check to make sure the PIC flag actually works.\n#\nif test -n \"$lt_prog_compiler_pic\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works\" >&5\n$as_echo_n \"checking if $compiler PIC flag $lt_prog_compiler_pic works... \" >&6; }\nif test \"${lt_cv_prog_compiler_pic_works+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_pic_works=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"$lt_prog_compiler_pic -DPIC\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:9008: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:9012: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_pic_works=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works\" >&5\n$as_echo \"$lt_cv_prog_compiler_pic_works\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_pic_works\" = xyes; then\n    case $lt_prog_compiler_pic in\n     \"\" | \" \"*) ;;\n     *) lt_prog_compiler_pic=\" $lt_prog_compiler_pic\" ;;\n     esac\nelse\n    lt_prog_compiler_pic=\n     lt_prog_compiler_can_build_shared=no\nfi\n\nfi\n\n\n\n\n\n\n#\n# Check to make sure the static flag actually works.\n#\nwl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\\\"$lt_prog_compiler_static\\\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works\" >&5\n$as_echo_n \"checking if $compiler static flag $lt_tmp_static_flag works... \" >&6; }\nif test \"${lt_cv_prog_compiler_static_works+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_static_works=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS $lt_tmp_static_flag\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&5\n       $ECHO \"X$_lt_linker_boilerplate\" | $Xsed -e '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         lt_cv_prog_compiler_static_works=yes\n       fi\n     else\n       lt_cv_prog_compiler_static_works=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works\" >&5\n$as_echo \"$lt_cv_prog_compiler_static_works\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_static_works\" = xyes; then\n    :\nelse\n    lt_prog_compiler_static=\nfi\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:9113: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:9117: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o\" >&6; }\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:9168: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:9172: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o\" >&6; }\n\n\n\n\nhard_links=\"nottested\"\nif test \"$lt_cv_prog_compiler_c_o\" = no && test \"$need_locks\" != no; then\n  # do not overwrite the value of need_locks provided by the user\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links\" >&5\n$as_echo_n \"checking if we can lock with hard links... \" >&6; }\n  hard_links=yes\n  $RM conftest*\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  touch conftest.a\n  ln conftest.a conftest.b 2>&5 || hard_links=no\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hard_links\" >&5\n$as_echo \"$hard_links\" >&6; }\n  if test \"$hard_links\" = no; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&5\n$as_echo \"$as_me: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&2;}\n    need_locks=warn\n  fi\nelse\n  need_locks=no\nfi\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries\" >&5\n$as_echo_n \"checking whether the $compiler linker ($LD) supports shared libraries... \" >&6; }\n\n  runpath_var=\n  allow_undefined_flag=\n  always_export_symbols=no\n  archive_cmds=\n  archive_expsym_cmds=\n  compiler_needs_object=no\n  enable_shared_with_static_runtimes=no\n  export_dynamic_flag_spec=\n  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  hardcode_automatic=no\n  hardcode_direct=no\n  hardcode_direct_absolute=no\n  hardcode_libdir_flag_spec=\n  hardcode_libdir_flag_spec_ld=\n  hardcode_libdir_separator=\n  hardcode_minus_L=no\n  hardcode_shlibpath_var=unsupported\n  inherit_rpath=no\n  link_all_deplibs=unknown\n  module_cmds=\n  module_expsym_cmds=\n  old_archive_from_new_cmds=\n  old_archive_from_expsyms_cmds=\n  thread_safe_flag_spec=\n  whole_archive_flag_spec=\n  # include_expsyms should be a list of space-separated symbols to be *always*\n  # included in the symbol list\n  include_expsyms=\n  # exclude_expsyms can be an extended regexp of symbols to exclude\n  # it will be wrapped by ` (' and `)$', so one must not match beginning or\n  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',\n  # as well as any symbol that contains `d'.\n  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'\n  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out\n  # platforms (ab)use it in PIC code, but their linkers get confused if\n  # the symbol is explicitly referenced.  Since portable code cannot\n  # rely on this symbol name, it's probably fine to never include it in\n  # preloaded symbol tables.\n  # Exclude shared library initialization/finalization symbols.\n  extract_expsyms_cmds=\n\n  case $host_os in\n  cygwin* | mingw* | pw32* | cegcc*)\n    # FIXME: the MSVC++ port hasn't been tested in a loooong time\n    # When not using gcc, we currently assume that we are using\n    # Microsoft Visual C++.\n    if test \"$GCC\" != yes; then\n      with_gnu_ld=no\n    fi\n    ;;\n  interix*)\n    # we just hope/assume this is gcc and not c89 (= MSVC++)\n    with_gnu_ld=yes\n    ;;\n  openbsd*)\n    with_gnu_ld=no\n    ;;\n  linux* | k*bsd*-gnu)\n    link_all_deplibs=no\n    ;;\n  esac\n\n  ld_shlibs=yes\n  if test \"$with_gnu_ld\" = yes; then\n    # If archive_cmds runs LD, not CC, wlarc should be empty\n    wlarc='${wl}'\n\n    # Set some defaults for GNU ld with shared library support. These\n    # are reset later if shared libraries are not supported. Putting them\n    # here allows them to be overridden if necessary.\n    runpath_var=LD_RUN_PATH\n    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n    export_dynamic_flag_spec='${wl}--export-dynamic'\n    # ancient GNU ld didn't support --whole-archive et. al.\n    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then\n      whole_archive_flag_spec=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n    else\n      whole_archive_flag_spec=\n    fi\n    supports_anon_versioning=no\n    case `$LD -v 2>&1` in\n      *GNU\\ gold*) supports_anon_versioning=yes ;;\n      *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.10.*) ;; # catch versions < 2.11\n      *\\ 2.11.93.0.2\\ *) supports_anon_versioning=yes ;; # RH7.3 ...\n      *\\ 2.11.92.0.12\\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...\n      *\\ 2.11.*) ;; # other 2.11 versions\n      *) supports_anon_versioning=yes ;;\n    esac\n\n    # See if GNU ld supports shared libraries.\n    case $host_os in\n    aix[3-9]*)\n      # On AIX/PPC, the GNU linker is very broken\n      if test \"$host_cpu\" != ia64; then\n\tld_shlibs=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: the GNU linker, at least up to release 2.9.1, is reported\n*** to be unable to reliably create shared libraries on AIX.\n*** Therefore, libtool is disabling shared libraries support.  If you\n*** really care for shared libraries, you may want to modify your PATH\n*** so that a non-GNU linker is found, and then restart.\n\n_LT_EOF\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            archive_expsym_cmds=''\n        ;;\n      m68k)\n            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            hardcode_libdir_flag_spec='-L$libdir'\n            hardcode_minus_L=yes\n        ;;\n      esac\n      ;;\n\n    beos*)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tallow_undefined_flag=unsupported\n\t# Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t# support --undefined.  This deserves some investigation.  FIXME\n\tarchive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,\n      # as there is no search path for DLLs.\n      hardcode_libdir_flag_spec='-L$libdir'\n      allow_undefined_flag=unsupported\n      always_export_symbols=no\n      enable_shared_with_static_runtimes=yes\n      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[BCDGRS][ ]/s/.*[ ]\\([^ ]*\\)/\\1 DATA/'\\'' | $SED -e '\\''/^[AITW][ ]/s/.*[ ]//'\\'' | sort | uniq > $export_symbols'\n\n      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t# If the export-symbols file already is a .def file (1st line\n\t# is EXPORTS), use it as is; otherwise, prepend...\n\tarchive_expsym_cmds='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t  cp $export_symbols $output_objdir/$soname.def;\n\telse\n\t  echo EXPORTS > $output_objdir/$soname.def;\n\t  cat $export_symbols >> $output_objdir/$soname.def;\n\tfi~\n\t$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    interix[3-9]*)\n      hardcode_direct=no\n      hardcode_shlibpath_var=no\n      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n      export_dynamic_flag_spec='${wl}-E'\n      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n      # Instead, shared libraries are loaded at an image base (0x10000000 by\n      # default) and relocated if they conflict, which is a slow very memory\n      # consuming and fragmenting process.  To avoid this, we pick a random,\n      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      archive_expsym_cmds='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      ;;\n\n    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)\n      tmp_diet=no\n      if test \"$host_os\" = linux-dietlibc; then\n\tcase $cc_basename in\n\t  diet\\ *) tmp_diet=yes;;\t# linux-dietlibc with static linking (!diet-dyn)\n\tesac\n      fi\n      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \\\n\t && test \"$tmp_diet\" = no\n      then\n\ttmp_addflag=\n\ttmp_sharedflag='-shared'\n\tcase $cc_basename,$host_cpu in\n        pgcc*)\t\t\t\t# Portland Group C compiler\n\t  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95*)\t# Portland Group f77 and f90 compilers\n\t  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag -Mnomain' ;;\n\tecc*,ia64* | icc*,ia64*)\t# Intel C compiler on ia64\n\t  tmp_addflag=' -i_dynamic' ;;\n\tefc*,ia64* | ifort*,ia64*)\t# Intel Fortran compiler on ia64\n\t  tmp_addflag=' -i_dynamic -nofor_main' ;;\n\tifc* | ifort*)\t\t\t# Intel Fortran compiler\n\t  tmp_addflag=' -nofor_main' ;;\n\tlf95*)\t\t\t\t# Lahey Fortran 8.1\n\t  whole_archive_flag_spec=\n\t  tmp_sharedflag='--shared' ;;\n\txl[cC]*)\t\t\t# IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tesac\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\t\t\t# Sun C 5.9\n\t  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  compiler_needs_object=yes\n\t  tmp_sharedflag='-G' ;;\n\t*Sun\\ F*)\t\t\t# Sun Fortran 8.3\n\t  tmp_sharedflag='-G' ;;\n\tesac\n\tarchive_cmds='$CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\n        if test \"x$supports_anon_versioning\" = xyes; then\n          archive_expsym_cmds='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t    cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t    echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t    $CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n        fi\n\n\tcase $cc_basename in\n\txlf*)\n\t  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself\n\t  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'\n\t  hardcode_libdir_flag_spec=\n\t  hardcode_libdir_flag_spec_ld='-rpath $libdir'\n\t  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'\n\t  if test \"x$supports_anon_versioning\" = xyes; then\n\t    archive_expsym_cmds='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t      cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t      echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'\n\t  fi\n\t  ;;\n\tesac\n      else\n        ld_shlibs=no\n      fi\n      ;;\n\n    netbsd* | netbsdelf*-gnu)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\tarchive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'\n\twlarc=\n      else\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      fi\n      ;;\n\n    solaris*)\n      if $LD -v 2>&1 | $GREP 'BFD 2\\.8' > /dev/null; then\n\tld_shlibs=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: The releases 2.8.* of the GNU linker cannot reliably\n*** create shared libraries on Solaris systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.9.1 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)\n      case `$LD -v 2>&1` in\n        *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.1[0-5].*)\n\tld_shlibs=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not\n*** reliably create shared libraries on SCO systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n\t;;\n\t*)\n\t  # For security reasons, it is highly recommended that you always\n\t  # use absolute paths for naming shared libraries, and exclude the\n\t  # DT_RUNPATH tag from executables and libraries.  But doing so\n\t  # requires that you compile everything twice, which is a pain.\n\t  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n\t    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t  else\n\t    ld_shlibs=no\n\t  fi\n\t;;\n      esac\n      ;;\n\n    sunos4*)\n      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      wlarc=\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    *)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\tld_shlibs=no\n      fi\n      ;;\n    esac\n\n    if test \"$ld_shlibs\" = no; then\n      runpath_var=\n      hardcode_libdir_flag_spec=\n      export_dynamic_flag_spec=\n      whole_archive_flag_spec=\n    fi\n  else\n    # PORTME fill in a description of your system's linker (not GNU ld)\n    case $host_os in\n    aix3*)\n      allow_undefined_flag=unsupported\n      always_export_symbols=yes\n      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'\n      # Note: this linker hardcodes the directories in LIBPATH if there\n      # are no directories specified by -L.\n      hardcode_minus_L=yes\n      if test \"$GCC\" = yes && test -z \"$lt_prog_compiler_static\"; then\n\t# Neither direct hardcoding nor static linking is supported with a\n\t# broken collect2.\n\thardcode_direct=unsupported\n      fi\n      ;;\n\n    aix[4-9]*)\n      if test \"$host_cpu\" = ia64; then\n\t# On IA64, the linker does run time linking by default, so we don't\n\t# have to do anything special.\n\taix_use_runtimelinking=no\n\texp_sym_flag='-Bexport'\n\tno_entry_flag=\"\"\n      else\n\t# If we're using GNU nm, then we don't want the \"-C\" option.\n\t# -C means demangle to AIX nm, but means don't demangle with GNU nm\n\tif $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n\t  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\telse\n\t  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\tfi\n\taix_use_runtimelinking=no\n\n\t# Test if we are trying to use run time linking or normal\n\t# AIX style linking. If -brtl is somewhere in LDFLAGS, we\n\t# need to do runtime linking.\n\tcase $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)\n\t  for ld_flag in $LDFLAGS; do\n\t  if (test $ld_flag = \"-brtl\" || test $ld_flag = \"-Wl,-brtl\"); then\n\t    aix_use_runtimelinking=yes\n\t    break\n\t  fi\n\t  done\n\t  ;;\n\tesac\n\n\texp_sym_flag='-bexport'\n\tno_entry_flag='-bnoentry'\n      fi\n\n      # When large executables or shared objects are built, AIX ld can\n      # have problems creating the table of contents.  If linking a library\n      # or program results in \"error TOC overflow\" add -mminimal-toc to\n      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n      archive_cmds=''\n      hardcode_direct=yes\n      hardcode_direct_absolute=yes\n      hardcode_libdir_separator=':'\n      link_all_deplibs=yes\n      file_list_spec='${wl}-f,'\n\n      if test \"$GCC\" = yes; then\n\tcase $host_os in aix4.[012]|aix4.[012].*)\n\t# We only want to do this on AIX 4.2 and lower, the check\n\t# below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t   strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t  # We have reworked collect2\n\t  :\n\t  else\n\t  # We have old collect2\n\t  hardcode_direct=unsupported\n\t  # It fails to find uninstalled libraries when the uninstalled\n\t  # path is not listed in the libpath.  Setting hardcode_minus_L\n\t  # to unsupported forces relinking\n\t  hardcode_minus_L=yes\n\t  hardcode_libdir_flag_spec='-L$libdir'\n\t  hardcode_libdir_separator=\n\t  fi\n\t  ;;\n\tesac\n\tshared_flag='-shared'\n\tif test \"$aix_use_runtimelinking\" = yes; then\n\t  shared_flag=\"$shared_flag \"'${wl}-G'\n\tfi\n\tlink_all_deplibs=no\n      else\n\t# not using gcc\n\tif test \"$host_cpu\" = ia64; then\n\t# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t# chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n\telse\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag='${wl}-G'\n\t  else\n\t    shared_flag='${wl}-bM:SRE'\n\t  fi\n\tfi\n      fi\n\n      export_dynamic_flag_spec='${wl}-bexpall'\n      # It seems that -bexpall does not export symbols beginning with\n      # underscore (_), so it is better to generate a list of symbols to export.\n      always_export_symbols=yes\n      if test \"$aix_use_runtimelinking\" = yes; then\n\t# Warning - without using the other runtime loading flags (-brtl),\n\t# -berok will link without error, but may produce a broken library.\n\tallow_undefined_flag='-berok'\n        # Determine the default libpath from the value encoded in an\n        # empty executable.\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then $ECHO \"X${wl}${allow_undefined_flag}\" | $Xsed; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n      else\n\tif test \"$host_cpu\" = ia64; then\n\t  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'\n\t  allow_undefined_flag=\"-z nodefs\"\n\t  archive_expsym_cmds=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n\telse\n\t # Determine the default libpath from the value encoded in an\n\t # empty executable.\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n\t hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t  # Warning - without using the other run time loading flags,\n\t  # -berok will link without error, but may produce a broken library.\n\t  no_undefined_flag=' ${wl}-bernotok'\n\t  allow_undefined_flag=' ${wl}-berok'\n\t  # Exported symbols can be pulled into shared objects from archives\n\t  whole_archive_flag_spec='$convenience'\n\t  archive_cmds_need_lc=yes\n\t  # This is similar to how AIX traditionally builds its shared libraries.\n\t  archive_expsym_cmds=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n\tfi\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            archive_expsym_cmds=''\n        ;;\n      m68k)\n            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            hardcode_libdir_flag_spec='-L$libdir'\n            hardcode_minus_L=yes\n        ;;\n      esac\n      ;;\n\n    bsdi[45]*)\n      export_dynamic_flag_spec=-rdynamic\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # When not using gcc, we currently assume that we are using\n      # Microsoft Visual C++.\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      hardcode_libdir_flag_spec=' '\n      allow_undefined_flag=unsupported\n      # Tell ltmain to make .lib files, not .a files.\n      libext=lib\n      # Tell ltmain to make .dll files, not .so files.\n      shrext_cmds=\".dll\"\n      # FIXME: Setting linknames here is a bad hack.\n      archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO \"X$deplibs\" | $Xsed -e '\\''s/ -lc$//'\\''` -link -dll~linknames='\n      # The linker will automatically build a .lib file if we build a DLL.\n      old_archive_from_new_cmds='true'\n      # FIXME: Should let the user specify the lib program.\n      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'\n      fix_srcfile_path='`cygpath -w \"$srcfile\"`'\n      enable_shared_with_static_runtimes=yes\n      ;;\n\n    darwin* | rhapsody*)\n\n\n  archive_cmds_need_lc=no\n  hardcode_direct=no\n  hardcode_automatic=yes\n  hardcode_shlibpath_var=unsupported\n  whole_archive_flag_spec=''\n  link_all_deplibs=yes\n  allow_undefined_flag=\"$_lt_dar_allow_undefined\"\n  case $cc_basename in\n     ifort*) _lt_dar_can_shared=yes ;;\n     *) _lt_dar_can_shared=$GCC ;;\n  esac\n  if test \"$_lt_dar_can_shared\" = \"yes\"; then\n    output_verbose_link_cmd=echo\n    archive_cmds=\"\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring $_lt_dar_single_mod${_lt_dsymutil}\"\n    module_cmds=\"\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dsymutil}\"\n    archive_expsym_cmds=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}\"\n    module_expsym_cmds=\"sed -e 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}\"\n\n  else\n  ld_shlibs=no\n  fi\n\n      ;;\n\n    dgux*)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_shlibpath_var=no\n      ;;\n\n    freebsd1*)\n      ld_shlibs=no\n      ;;\n\n    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor\n    # support.  Future versions do this automatically, but an explicit c++rt0.o\n    # does not break anything, and helps significantly (at the cost of a little\n    # extra space).\n    freebsd2.2*)\n      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    # Unfortunately, older versions of FreeBSD 2 do not have this feature.\n    freebsd2*)\n      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_direct=yes\n      hardcode_minus_L=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.\n    freebsd* | dragonfly*)\n      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    hpux9*)\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      else\n\tarchive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      fi\n      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n      hardcode_libdir_separator=:\n      hardcode_direct=yes\n\n      # hardcode_minus_L: Not really in the search PATH,\n      # but as the default location of the library.\n      hardcode_minus_L=yes\n      export_dynamic_flag_spec='${wl}-E'\n      ;;\n\n    hpux10*)\n      if test \"$GCC\" = yes -a \"$with_gnu_ld\" = no; then\n\tarchive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\thardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n\thardcode_libdir_flag_spec_ld='+b $libdir'\n\thardcode_libdir_separator=:\n\thardcode_direct=yes\n\thardcode_direct_absolute=yes\n\texport_dynamic_flag_spec='${wl}-E'\n\t# hardcode_minus_L: Not really in the search PATH,\n\t# but as the default location of the library.\n\thardcode_minus_L=yes\n      fi\n      ;;\n\n    hpux11*)\n      if test \"$GCC\" = yes -a \"$with_gnu_ld\" = no; then\n\tcase $host_cpu in\n\thppa*64*)\n\t  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      else\n\tcase $host_cpu in\n\thppa*64*)\n\t  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\thardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n\thardcode_libdir_separator=:\n\n\tcase $host_cpu in\n\thppa*64*|ia64*)\n\t  hardcode_direct=no\n\t  hardcode_shlibpath_var=no\n\t  ;;\n\t*)\n\t  hardcode_direct=yes\n\t  hardcode_direct_absolute=yes\n\t  export_dynamic_flag_spec='${wl}-E'\n\n\t  # hardcode_minus_L: Not really in the search PATH,\n\t  # but as the default location of the library.\n\t  hardcode_minus_L=yes\n\t  ;;\n\tesac\n      fi\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t# Try to use the -exported_symbol ld option, if it does not\n\t# work, assume that -exports_file does not work either and\n\t# implicitly export all symbols.\n        save_LDFLAGS=\"$LDFLAGS\"\n        LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nint foo(void) {}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n        LDFLAGS=\"$save_LDFLAGS\"\n      else\n\tarchive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'\n      fi\n      archive_cmds_need_lc='no'\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      inherit_rpath=yes\n      link_all_deplibs=yes\n      ;;\n\n    netbsd* | netbsdelf*-gnu)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\tarchive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out\n      else\n\tarchive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF\n      fi\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    newsos6)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_direct=yes\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      hardcode_shlibpath_var=no\n      ;;\n\n    *nto* | *qnx*)\n      ;;\n\n    openbsd*)\n      if test -f /usr/libexec/ld.so; then\n\thardcode_direct=yes\n\thardcode_shlibpath_var=no\n\thardcode_direct_absolute=yes\n\tif test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'\n\t  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n\t  export_dynamic_flag_spec='${wl}-E'\n\telse\n\t  case $host_os in\n\t   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)\n\t     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n\t     hardcode_libdir_flag_spec='-R$libdir'\n\t     ;;\n\t   *)\n\t     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n\t     ;;\n\t  esac\n\tfi\n      else\n\tld_shlibs=no\n      fi\n      ;;\n\n    os2*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_minus_L=yes\n      allow_undefined_flag=unsupported\n      archive_cmds='$ECHO \"LIBRARY $libname INITINSTANCE\" > $output_objdir/$libname.def~$ECHO \"DESCRIPTION \\\"$libname\\\"\" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO \" SINGLE NONSHARED\" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'\n      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'\n      ;;\n\n    osf3*)\n      if test \"$GCC\" = yes; then\n\tallow_undefined_flag=' ${wl}-expect_unresolved ${wl}\\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n      else\n\tallow_undefined_flag=' -expect_unresolved \\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n      fi\n      archive_cmds_need_lc='no'\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      ;;\n\n    osf4* | osf5*)\t# as osf3* with the addition of -msym flag\n      if test \"$GCC\" = yes; then\n\tallow_undefined_flag=' ${wl}-expect_unresolved ${wl}\\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\thardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      else\n\tallow_undefined_flag=' -expect_unresolved \\*'\n\tarchive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\tarchive_expsym_cmds='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done; printf \"%s\\\\n\" \"-hidden\">> $lib.exp~\n\t$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'\n\n\t# Both c and cxx compiler support -rpath directly\n\thardcode_libdir_flag_spec='-rpath $libdir'\n      fi\n      archive_cmds_need_lc='no'\n      hardcode_libdir_separator=:\n      ;;\n\n    solaris*)\n      no_undefined_flag=' -z defs'\n      if test \"$GCC\" = yes; then\n\twlarc='${wl}'\n\tarchive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n      else\n\tcase `$CC -V 2>&1` in\n\t*\"Compilers 5.0\"*)\n\t  wlarc=''\n\t  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  archive_expsym_cmds='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'\n\t  ;;\n\t*)\n\t  wlarc='${wl}'\n\t  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n\t  ;;\n\tesac\n      fi\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_shlibpath_var=no\n      case $host_os in\n      solaris2.[0-5] | solaris2.[0-5].*) ;;\n      *)\n\t# The compiler driver will combine and reorder linker options,\n\t# but understands `-z linker_flag'.  GCC discards it without `$wl',\n\t# but is careful enough not to reorder.\n\t# Supported since Solaris 2.6 (maybe 2.5.1?)\n\tif test \"$GCC\" = yes; then\n\t  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\telse\n\t  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'\n\tfi\n\t;;\n      esac\n      link_all_deplibs=yes\n      ;;\n\n    sunos4*)\n      if test \"x$host_vendor\" = xsequent; then\n\t# Use $CC to link under sequent, because it throws in some extra .o\n\t# files that make .init and .fini sections work.\n\tarchive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_direct=yes\n      hardcode_minus_L=yes\n      hardcode_shlibpath_var=no\n      ;;\n\n    sysv4)\n      case $host_vendor in\n\tsni)\n\t  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  hardcode_direct=yes # is this really true???\n\t;;\n\tsiemens)\n\t  ## LD is ld it makes a PLAMLIB\n\t  ## CC just makes a GrossModule.\n\t  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'\n\t  reload_cmds='$CC -r -o $output$reload_objs'\n\t  hardcode_direct=no\n        ;;\n\tmotorola)\n\t  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  hardcode_direct=no #Motorola manual says yes, but my tests say they lie\n\t;;\n      esac\n      runpath_var='LD_RUN_PATH'\n      hardcode_shlibpath_var=no\n      ;;\n\n    sysv4.3*)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_shlibpath_var=no\n      export_dynamic_flag_spec='-Bexport'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tarchive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\thardcode_shlibpath_var=no\n\trunpath_var=LD_RUN_PATH\n\thardcode_runpath_var=yes\n\tld_shlibs=yes\n      fi\n      ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)\n      no_undefined_flag='${wl}-z,text'\n      archive_cmds_need_lc=no\n      hardcode_shlibpath_var=no\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6*)\n      # Note: We can NOT use -z defs as we might desire, because we do not\n      # link with -lc, and that would cause any symbols used from libc to\n      # always be unresolved, which means just about no library would\n      # ever link correctly.  If we're not using GNU ld we use -z text\n      # though, which does catch some bad symbols but isn't as heavy-handed\n      # as -z defs.\n      no_undefined_flag='${wl}-z,text'\n      allow_undefined_flag='${wl}-z,nodefs'\n      archive_cmds_need_lc=no\n      hardcode_shlibpath_var=no\n      hardcode_libdir_flag_spec='${wl}-R,$libdir'\n      hardcode_libdir_separator=':'\n      link_all_deplibs=yes\n      export_dynamic_flag_spec='${wl}-Bexport'\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\tarchive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\tarchive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\tarchive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    uts4*)\n      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_shlibpath_var=no\n      ;;\n\n    *)\n      ld_shlibs=no\n      ;;\n    esac\n\n    if test x$host_vendor = xsni; then\n      case $host in\n      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)\n\texport_dynamic_flag_spec='${wl}-Blargedynsym'\n\t;;\n      esac\n    fi\n  fi\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ld_shlibs\" >&5\n$as_echo \"$ld_shlibs\" >&6; }\ntest \"$ld_shlibs\" = no && can_build_shared=no\n\nwith_gnu_ld=$with_gnu_ld\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n#\n# Do we need to explicitly link libc?\n#\ncase \"x$archive_cmds_need_lc\" in\nx|xyes)\n  # Assume -lc should be added\n  archive_cmds_need_lc=yes\n\n  if test \"$enable_shared\" = yes && test \"$GCC\" = yes; then\n    case $archive_cmds in\n    *'~'*)\n      # FIXME: we may have to deal with multi-command sequences.\n      ;;\n    '$CC '*)\n      # Test whether the compiler implicitly links with -lc since on some\n      # systems, -lgcc has to come before -lc. If gcc already passes -lc\n      # to ld, don't add -lc before -lgcc.\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in\" >&5\n$as_echo_n \"checking whether -lc should be explicitly linked in... \" >&6; }\n      $RM conftest*\n      echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n      if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } 2>conftest.err; then\n        soname=conftest\n        lib=conftest\n        libobjs=conftest.$ac_objext\n        deplibs=\n        wl=$lt_prog_compiler_wl\n\tpic_flag=$lt_prog_compiler_pic\n        compiler_flags=-v\n        linker_flags=-v\n        verstring=\n        output_objdir=.\n        libname=conftest\n        lt_save_allow_undefined_flag=$allow_undefined_flag\n        allow_undefined_flag=\n        if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$archive_cmds 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1\\\"\"; } >&5\n  (eval $archive_cmds 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n        then\n\t  archive_cmds_need_lc=no\n        else\n\t  archive_cmds_need_lc=yes\n        fi\n        allow_undefined_flag=$lt_save_allow_undefined_flag\n      else\n        cat conftest.err 1>&5\n      fi\n      $RM conftest*\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc\" >&5\n$as_echo \"$archive_cmds_need_lc\" >&6; }\n      ;;\n    esac\n  fi\n  ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics\" >&5\n$as_echo_n \"checking dynamic linker characteristics... \" >&6; }\n\nif test \"$GCC\" = yes; then\n  case $host_os in\n    darwin*) lt_awk_arg=\"/^libraries:/,/LR/\" ;;\n    *) lt_awk_arg=\"/^libraries:/\" ;;\n  esac\n  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e \"s/^libraries://\" -e \"s,=/,/,g\"`\n  if $ECHO \"$lt_search_path_spec\" | $GREP ';' >/dev/null ; then\n    # if the path contains \";\" then we assume it to be the separator\n    # otherwise default to the standard path separator (i.e. \":\") - it is\n    # assumed that no part of a normal pathname contains \";\" but that should\n    # okay in the real world where \";\" in dirpaths is itself problematic.\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED -e 's/;/ /g'`\n  else\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED  -e \"s/$PATH_SEPARATOR/ /g\"`\n  fi\n  # Ok, now we have the path, separated by spaces, we can step through it\n  # and add multilib dir if necessary.\n  lt_tmp_lt_search_path_spec=\n  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`\n  for lt_sys_path in $lt_search_path_spec; do\n    if test -d \"$lt_sys_path/$lt_multi_os_dir\"; then\n      lt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir\"\n    else\n      test -d \"$lt_sys_path\" && \\\n\tlt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path\"\n    fi\n  done\n  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '\nBEGIN {RS=\" \"; FS=\"/|\\n\";} {\n  lt_foo=\"\";\n  lt_count=0;\n  for (lt_i = NF; lt_i > 0; lt_i--) {\n    if ($lt_i != \"\" && $lt_i != \".\") {\n      if ($lt_i == \"..\") {\n        lt_count++;\n      } else {\n        if (lt_count == 0) {\n          lt_foo=\"/\" $lt_i lt_foo;\n        } else {\n          lt_count--;\n        }\n      }\n    }\n  }\n  if (lt_foo != \"\") { lt_freq[lt_foo]++; }\n  if (lt_freq[lt_foo] == 1) { print lt_foo; }\n}'`\n  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`\nelse\n  sys_lib_search_path_spec=\"/lib /usr/lib /usr/local/lib\"\nfi\nlibrary_names_spec=\nlibname_spec='lib$name'\nsoname_spec=\nshrext_cmds=\".so\"\npostinstall_cmds=\npostuninstall_cmds=\nfinish_cmds=\nfinish_eval=\nshlibpath_var=\nshlibpath_overrides_runpath=unknown\nversion_type=none\ndynamic_linker=\"$host_os ld.so\"\nsys_lib_dlsearch_path_spec=\"/lib /usr/lib\"\nneed_lib_prefix=unknown\nhardcode_into_libs=no\n\n# when you set need_version to no, make sure it does not cause -set_version\n# flags to be left without arguments\nneed_version=unknown\n\ncase $host_os in\naix3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'\n  shlibpath_var=LIBPATH\n\n  # AIX 3 has no versioning support, so we append a major version to the name.\n  soname_spec='${libname}${release}${shared_ext}$major'\n  ;;\n\naix[4-9]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  hardcode_into_libs=yes\n  if test \"$host_cpu\" = ia64; then\n    # AIX 5 supports IA64\n    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'\n    shlibpath_var=LD_LIBRARY_PATH\n  else\n    # With GCC up to 2.95.x, collect2 would create an import file\n    # for dependence libraries.  The import file would start with\n    # the line `#! .'.  This would cause the generated library to\n    # depend on `.', always an invalid library.  This was fixed in\n    # development snapshots of GCC prior to 3.0.\n    case $host_os in\n      aix4 | aix4.[01] | aix4.[01].*)\n      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'\n\t   echo ' yes '\n\t   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then\n\t:\n      else\n\tcan_build_shared=no\n      fi\n      ;;\n    esac\n    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct\n    # soname into executable. Probably we can add versioning support to\n    # collect2, so additional links can be useful in future.\n    if test \"$aix_use_runtimelinking\" = yes; then\n      # If using run time linking (on AIX 4.2 or later) use lib<name>.so\n      # instead of lib<name>.a to let people know that these are not\n      # typical AIX shared libraries.\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    else\n      # We preserve .a as extension for shared libraries through AIX4.2\n      # and later when we are not doing run time linking.\n      library_names_spec='${libname}${release}.a $libname.a'\n      soname_spec='${libname}${release}${shared_ext}$major'\n    fi\n    shlibpath_var=LIBPATH\n  fi\n  ;;\n\namigaos*)\n  case $host_cpu in\n  powerpc)\n    # Since July 2007 AmigaOS4 officially supports .so libraries.\n    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    ;;\n  m68k)\n    library_names_spec='$libname.ixlibrary $libname.a'\n    # Create ${libname}_ixlibrary.a entries in /sys/libs.\n    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO \"X$lib\" | $Xsed -e '\\''s%^.*/\\([^/]*\\)\\.ixlibrary$%\\1%'\\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show \"cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a\"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'\n    ;;\n  esac\n  ;;\n\nbeos*)\n  library_names_spec='${libname}${shared_ext}'\n  dynamic_linker=\"$host_os ld.so\"\n  shlibpath_var=LIBRARY_PATH\n  ;;\n\nbsdi[45]*)\n  version_type=linux\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib\"\n  sys_lib_dlsearch_path_spec=\"/shlib /usr/lib /usr/local/lib\"\n  # the default ld.so.conf also contains /usr/contrib/lib and\n  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow\n  # libtool to hard-code these into programs\n  ;;\n\ncygwin* | mingw* | pw32* | cegcc*)\n  version_type=windows\n  shrext_cmds=\".dll\"\n  need_version=no\n  need_lib_prefix=no\n\n  case $GCC,$host_os in\n  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)\n    library_names_spec='$libname.dll.a'\n    # DLL is installed to $(libdir)/../bin by postinstall_cmds\n    postinstall_cmds='base_file=`basename \\${file}`~\n      dlpath=`$SHELL 2>&1 -c '\\''. $dir/'\\''\\${base_file}'\\''i; echo \\$dlname'\\''`~\n      dldir=$destdir/`dirname \\$dlpath`~\n      test -d \\$dldir || mkdir -p \\$dldir~\n      $install_prog $dir/$dlname \\$dldir/$dlname~\n      chmod a+x \\$dldir/$dlname~\n      if test -n '\\''$stripme'\\'' && test -n '\\''$striplib'\\''; then\n        eval '\\''$striplib \\$dldir/$dlname'\\'' || exit \\$?;\n      fi'\n    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n\n    case $host_os in\n    cygwin*)\n      # Cygwin DLLs use 'cyg' prefix rather than 'lib'\n      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      sys_lib_search_path_spec=\"/usr/lib /lib/w32api /lib /usr/local/lib\"\n      ;;\n    mingw* | cegcc*)\n      # MinGW DLLs use traditional 'lib' prefix\n      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP \"^libraries:\" | $SED -e \"s/^libraries://\" -e \"s,=/,/,g\"`\n      if $ECHO \"$sys_lib_search_path_spec\" | $GREP ';[c-zC-Z]:/' >/dev/null; then\n        # It is most probably a Windows format PATH printed by\n        # mingw gcc, but we are running on Cygwin. Gcc prints its search\n        # path with ; separators, and with drive letters. We can handle the\n        # drive letters (cygwin fileutils understands them), so leave them,\n        # especially as we might pass files found there to a mingw objdump,\n        # which wouldn't understand a cygwinified path. Ahh.\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED -e 's/;/ /g'`\n      else\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED  -e \"s/$PATH_SEPARATOR/ /g\"`\n      fi\n      ;;\n    pw32*)\n      # pw32 DLLs use 'pw' prefix rather than 'lib'\n      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    esac\n    ;;\n\n  *)\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    ;;\n  esac\n  dynamic_linker='Win32 ld.exe'\n  # FIXME: first we should search . and the directory the executable is in\n  shlibpath_var=PATH\n  ;;\n\ndarwin* | rhapsody*)\n  dynamic_linker=\"$host_os dyld\"\n  version_type=darwin\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'\n  soname_spec='${libname}${release}${major}$shared_ext'\n  shlibpath_overrides_runpath=yes\n  shlibpath_var=DYLD_LIBRARY_PATH\n  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'\n\n  sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/local/lib\"\n  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'\n  ;;\n\ndgux*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\nfreebsd1*)\n  dynamic_linker=no\n  ;;\n\nfreebsd* | dragonfly*)\n  # DragonFly does not have aout.  When/if they implement a new\n  # versioning mechanism, adjust this.\n  if test -x /usr/bin/objformat; then\n    objformat=`/usr/bin/objformat`\n  else\n    case $host_os in\n    freebsd[123]*) objformat=aout ;;\n    *) objformat=elf ;;\n    esac\n  fi\n  version_type=freebsd-$objformat\n  case $version_type in\n    freebsd-elf*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n      need_version=no\n      need_lib_prefix=no\n      ;;\n    freebsd-*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'\n      need_version=yes\n      ;;\n  esac\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_os in\n  freebsd2*)\n    shlibpath_overrides_runpath=yes\n    ;;\n  freebsd3.[01]* | freebsdelf3.[01]*)\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \\\n  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)\n    shlibpath_overrides_runpath=no\n    hardcode_into_libs=yes\n    ;;\n  *) # from 4.6 on, and DragonFly\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  esac\n  ;;\n\ngnu*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  hardcode_into_libs=yes\n  ;;\n\nhpux9* | hpux10* | hpux11*)\n  # Give a soname corresponding to the major version so that dld.sl refuses to\n  # link against other versions.\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  case $host_cpu in\n  ia64*)\n    shrext_cmds='.so'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.so\"\n    shlibpath_var=LD_LIBRARY_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    if test \"X$HPUX_IA64_MODE\" = X32; then\n      sys_lib_search_path_spec=\"/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib\"\n    else\n      sys_lib_search_path_spec=\"/usr/lib/hpux64 /usr/local/lib/hpux64\"\n    fi\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  hppa*64*)\n    shrext_cmds='.sl'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    sys_lib_search_path_spec=\"/usr/lib/pa20_64 /usr/ccs/lib/pa20_64\"\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  *)\n    shrext_cmds='.sl'\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=SHLIB_PATH\n    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    ;;\n  esac\n  # HP-UX runs *really* slowly unless shared libraries are mode 555.\n  postinstall_cmds='chmod 555 $lib'\n  ;;\n\ninterix[3-9]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $host_os in\n    nonstopux*) version_type=nonstopux ;;\n    *)\n\tif test \"$lt_cv_prog_gnu_ld\" = yes; then\n\t\tversion_type=linux\n\telse\n\t\tversion_type=irix\n\tfi ;;\n  esac\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'\n  case $host_os in\n  irix5* | nonstopux*)\n    libsuff= shlibsuff=\n    ;;\n  *)\n    case $LD in # libtool.m4 will add one of these switches to LD\n    *-32|*\"-32 \"|*-melf32bsmip|*\"-melf32bsmip \")\n      libsuff= shlibsuff= libmagic=32-bit;;\n    *-n32|*\"-n32 \"|*-melf32bmipn32|*\"-melf32bmipn32 \")\n      libsuff=32 shlibsuff=N32 libmagic=N32;;\n    *-64|*\"-64 \"|*-melf64bmip|*\"-melf64bmip \")\n      libsuff=64 shlibsuff=64 libmagic=64-bit;;\n    *) libsuff= shlibsuff= libmagic=never-match;;\n    esac\n    ;;\n  esac\n  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH\n  shlibpath_overrides_runpath=no\n  sys_lib_search_path_spec=\"/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}\"\n  sys_lib_dlsearch_path_spec=\"/usr/lib${libsuff} /lib${libsuff}\"\n  hardcode_into_libs=yes\n  ;;\n\n# No shared lib support for Linux oldld, aout, or coff.\nlinux*oldld* | linux*aout* | linux*coff*)\n  dynamic_linker=no\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -n $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  # Some binutils ld are patched to set DT_RUNPATH\n  save_LDFLAGS=$LDFLAGS\n  save_libdir=$libdir\n  eval \"libdir=/foo; wl=\\\"$lt_prog_compiler_wl\\\"; \\\n       LDFLAGS=\\\"\\$LDFLAGS $hardcode_libdir_flag_spec\\\"\"\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep \"RUNPATH.*$libdir\" >/dev/null; then :\n  shlibpath_overrides_runpath=yes\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n  LDFLAGS=$save_LDFLAGS\n  libdir=$save_libdir\n\n  # This implies no fast_install, which is unacceptable.\n  # Some rework will be needed to allow for fast_install\n  # before this can be enabled.\n  hardcode_into_libs=yes\n\n  # Append ld.so.conf contents to the search path\n  if test -f /etc/ld.so.conf; then\n    lt_ld_extra=`awk '/^include / { system(sprintf(\"cd /etc; cat %s 2>/dev/null\", \\$2)); skip = 1; } { if (!skip) print \\$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[\t ]*hwcap[\t ]/d;s/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\\n' ' '`\n    sys_lib_dlsearch_path_spec=\"/lib /usr/lib $lt_ld_extra\"\n  fi\n\n  # We used to test for /lib/ld.so.1 and disable shared libraries on\n  # powerpc, because MkLinux only supported shared libraries with the\n  # GNU dynamic linker.  Since this was broken with cross compilers,\n  # most powerpc-linux boxes support dynamic linking these days and\n  # people can always --disable-shared, the test was removed, and we\n  # assume the GNU/Linux dynamic linker is in use.\n  dynamic_linker='GNU/Linux ld.so'\n  ;;\n\nnetbsdelf*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='NetBSD ld.elf_so'\n  ;;\n\nnetbsd*)\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n    finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n    dynamic_linker='NetBSD (a.out) ld.so'\n  else\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    dynamic_linker='NetBSD ld.elf_so'\n  fi\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  ;;\n\nnewsos6)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  ;;\n\n*nto* | *qnx*)\n  version_type=qnx\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='ldqnx.so'\n  ;;\n\nopenbsd*)\n  version_type=sunos\n  sys_lib_dlsearch_path_spec=\"/usr/lib\"\n  need_lib_prefix=no\n  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.\n  case $host_os in\n    openbsd3.3 | openbsd3.3.*)\tneed_version=yes ;;\n    *)\t\t\t\tneed_version=no  ;;\n  esac\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    case $host_os in\n      openbsd2.[89] | openbsd2.[89].*)\n\tshlibpath_overrides_runpath=no\n\t;;\n      *)\n\tshlibpath_overrides_runpath=yes\n\t;;\n      esac\n  else\n    shlibpath_overrides_runpath=yes\n  fi\n  ;;\n\nos2*)\n  libname_spec='$name'\n  shrext_cmds=\".dll\"\n  need_lib_prefix=no\n  library_names_spec='$libname${shared_ext} $libname.a'\n  dynamic_linker='OS/2 ld.exe'\n  shlibpath_var=LIBPATH\n  ;;\n\nosf3* | osf4* | osf5*)\n  version_type=osf\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib\"\n  sys_lib_dlsearch_path_spec=\"$sys_lib_search_path_spec\"\n  ;;\n\nrdos*)\n  dynamic_linker=no\n  ;;\n\nsolaris*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  # ldd complains unless libraries are executable\n  postinstall_cmds='chmod +x $lib'\n  ;;\n\nsunos4*)\n  version_type=sunos\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/usr/etc\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  if test \"$with_gnu_ld\" = yes; then\n    need_lib_prefix=no\n  fi\n  need_version=yes\n  ;;\n\nsysv4 | sysv4.3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_vendor in\n    sni)\n      shlibpath_overrides_runpath=no\n      need_lib_prefix=no\n      runpath_var=LD_RUN_PATH\n      ;;\n    siemens)\n      need_lib_prefix=no\n      ;;\n    motorola)\n      need_lib_prefix=no\n      need_version=no\n      shlibpath_overrides_runpath=no\n      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'\n      ;;\n  esac\n  ;;\n\nsysv4*MP*)\n  if test -d /usr/nec ;then\n    version_type=linux\n    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'\n    soname_spec='$libname${shared_ext}.$major'\n    shlibpath_var=LD_LIBRARY_PATH\n  fi\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  version_type=freebsd-elf\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  if test \"$with_gnu_ld\" = yes; then\n    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'\n  else\n    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'\n    case $host_os in\n      sco3.2v5*)\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec /lib\"\n\t;;\n    esac\n  fi\n  sys_lib_dlsearch_path_spec='/usr/lib'\n  ;;\n\ntpf*)\n  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nuts4*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\n*)\n  dynamic_linker=no\n  ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $dynamic_linker\" >&5\n$as_echo \"$dynamic_linker\" >&6; }\ntest \"$dynamic_linker\" = no && can_build_shared=no\n\nvariables_saved_for_relink=\"PATH $shlibpath_var $runpath_var\"\nif test \"$GCC\" = yes; then\n  variables_saved_for_relink=\"$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH\"\nfi\n\nif test \"${lt_cv_sys_lib_search_path_spec+set}\" = set; then\n  sys_lib_search_path_spec=\"$lt_cv_sys_lib_search_path_spec\"\nfi\nif test \"${lt_cv_sys_lib_dlsearch_path_spec+set}\" = set; then\n  sys_lib_dlsearch_path_spec=\"$lt_cv_sys_lib_dlsearch_path_spec\"\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs\" >&5\n$as_echo_n \"checking how to hardcode library paths into programs... \" >&6; }\nhardcode_action=\nif test -n \"$hardcode_libdir_flag_spec\" ||\n   test -n \"$runpath_var\" ||\n   test \"X$hardcode_automatic\" = \"Xyes\" ; then\n\n  # We can hardcode non-existent directories.\n  if test \"$hardcode_direct\" != no &&\n     # If the only mechanism to avoid hardcoding is shlibpath_var, we\n     # have to relink, otherwise we might link with an installed library\n     # when we should be linking with a yet-to-be-installed one\n     ## test \"$_LT_TAGVAR(hardcode_shlibpath_var, )\" != no &&\n     test \"$hardcode_minus_L\" != no; then\n    # Linking always hardcodes the temporary library directory.\n    hardcode_action=relink\n  else\n    # We can link without hardcoding, and we can hardcode nonexisting dirs.\n    hardcode_action=immediate\n  fi\nelse\n  # We cannot hardcode anything, or else we can only hardcode existing\n  # directories.\n  hardcode_action=unsupported\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hardcode_action\" >&5\n$as_echo \"$hardcode_action\" >&6; }\n\nif test \"$hardcode_action\" = relink ||\n   test \"$inherit_rpath\" = yes; then\n  # Fast installation is not supported\n  enable_fast_install=no\nelif test \"$shlibpath_overrides_runpath\" = yes ||\n     test \"$enable_shared\" = no; then\n  # Fast installation is not necessary\n  enable_fast_install=needless\nfi\n\n\n\n\n\n\n  if test \"x$enable_dlopen\" != xyes; then\n  enable_dlopen=unknown\n  enable_dlopen_self=unknown\n  enable_dlopen_self_static=unknown\nelse\n  lt_cv_dlopen=no\n  lt_cv_dlopen_libs=\n\n  case $host_os in\n  beos*)\n    lt_cv_dlopen=\"load_add_on\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n    ;;\n\n  mingw* | pw32* | cegcc*)\n    lt_cv_dlopen=\"LoadLibrary\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  cygwin*)\n    lt_cv_dlopen=\"dlopen\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  darwin*)\n  # if libdl is installed we need to link against it\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl\" >&5\n$as_echo_n \"checking for dlopen in -ldl... \" >&6; }\nif test \"${ac_cv_lib_dl_dlopen+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldl  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dlopen ();\nint\nmain ()\n{\nreturn dlopen ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dl_dlopen=yes\nelse\n  ac_cv_lib_dl_dlopen=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen\" >&5\n$as_echo \"$ac_cv_lib_dl_dlopen\" >&6; }\nif test \"x$ac_cv_lib_dl_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"\nelse\n\n    lt_cv_dlopen=\"dyld\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n\nfi\n\n    ;;\n\n  *)\n    ac_fn_c_check_func \"$LINENO\" \"shl_load\" \"ac_cv_func_shl_load\"\nif test \"x$ac_cv_func_shl_load\" = x\"\"yes; then :\n  lt_cv_dlopen=\"shl_load\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld\" >&5\n$as_echo_n \"checking for shl_load in -ldld... \" >&6; }\nif test \"${ac_cv_lib_dld_shl_load+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldld  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar shl_load ();\nint\nmain ()\n{\nreturn shl_load ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dld_shl_load=yes\nelse\n  ac_cv_lib_dld_shl_load=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load\" >&5\n$as_echo \"$ac_cv_lib_dld_shl_load\" >&6; }\nif test \"x$ac_cv_lib_dld_shl_load\" = x\"\"yes; then :\n  lt_cv_dlopen=\"shl_load\" lt_cv_dlopen_libs=\"-ldld\"\nelse\n  ac_fn_c_check_func \"$LINENO\" \"dlopen\" \"ac_cv_func_dlopen\"\nif test \"x$ac_cv_func_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl\" >&5\n$as_echo_n \"checking for dlopen in -ldl... \" >&6; }\nif test \"${ac_cv_lib_dl_dlopen+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldl  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dlopen ();\nint\nmain ()\n{\nreturn dlopen ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dl_dlopen=yes\nelse\n  ac_cv_lib_dl_dlopen=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen\" >&5\n$as_echo \"$ac_cv_lib_dl_dlopen\" >&6; }\nif test \"x$ac_cv_lib_dl_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld\" >&5\n$as_echo_n \"checking for dlopen in -lsvld... \" >&6; }\nif test \"${ac_cv_lib_svld_dlopen+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lsvld  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dlopen ();\nint\nmain ()\n{\nreturn dlopen ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_svld_dlopen=yes\nelse\n  ac_cv_lib_svld_dlopen=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen\" >&5\n$as_echo \"$ac_cv_lib_svld_dlopen\" >&6; }\nif test \"x$ac_cv_lib_svld_dlopen\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-lsvld\"\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld\" >&5\n$as_echo_n \"checking for dld_link in -ldld... \" >&6; }\nif test \"${ac_cv_lib_dld_dld_link+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-ldld  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar dld_link ();\nint\nmain ()\n{\nreturn dld_link ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_dld_dld_link=yes\nelse\n  ac_cv_lib_dld_dld_link=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link\" >&5\n$as_echo \"$ac_cv_lib_dld_dld_link\" >&6; }\nif test \"x$ac_cv_lib_dld_dld_link\" = x\"\"yes; then :\n  lt_cv_dlopen=\"dld_link\" lt_cv_dlopen_libs=\"-ldld\"\nfi\n\n\nfi\n\n\nfi\n\n\nfi\n\n\nfi\n\n\nfi\n\n    ;;\n  esac\n\n  if test \"x$lt_cv_dlopen\" != xno; then\n    enable_dlopen=yes\n  else\n    enable_dlopen=no\n  fi\n\n  case $lt_cv_dlopen in\n  dlopen)\n    save_CPPFLAGS=\"$CPPFLAGS\"\n    test \"x$ac_cv_header_dlfcn_h\" = xyes && CPPFLAGS=\"$CPPFLAGS -DHAVE_DLFCN_H\"\n\n    save_LDFLAGS=\"$LDFLAGS\"\n    wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $export_dynamic_flag_spec\\\"\n\n    save_LIBS=\"$LIBS\"\n    LIBS=\"$lt_cv_dlopen_libs $LIBS\"\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself\" >&5\n$as_echo_n \"checking whether a program can dlopen itself... \" >&6; }\nif test \"${lt_cv_dlopen_self+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  \t  if test \"$cross_compiling\" = yes; then :\n  lt_cv_dlopen_self=cross\nelse\n  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n  lt_status=$lt_dlunknown\n  cat > conftest.$ac_ext <<_LT_EOF\n#line 11552 \"configure\"\n#include \"confdefs.h\"\n\n#if HAVE_DLFCN_H\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n\n#ifdef RTLD_GLOBAL\n#  define LT_DLGLOBAL\t\tRTLD_GLOBAL\n#else\n#  ifdef DL_GLOBAL\n#    define LT_DLGLOBAL\t\tDL_GLOBAL\n#  else\n#    define LT_DLGLOBAL\t\t0\n#  endif\n#endif\n\n/* We may have to define LT_DLLAZY_OR_NOW in the command line if we\n   find out it does not work in some platform. */\n#ifndef LT_DLLAZY_OR_NOW\n#  ifdef RTLD_LAZY\n#    define LT_DLLAZY_OR_NOW\t\tRTLD_LAZY\n#  else\n#    ifdef DL_LAZY\n#      define LT_DLLAZY_OR_NOW\t\tDL_LAZY\n#    else\n#      ifdef RTLD_NOW\n#        define LT_DLLAZY_OR_NOW\tRTLD_NOW\n#      else\n#        ifdef DL_NOW\n#          define LT_DLLAZY_OR_NOW\tDL_NOW\n#        else\n#          define LT_DLLAZY_OR_NOW\t0\n#        endif\n#      endif\n#    endif\n#  endif\n#endif\n\nvoid fnord() { int i=42;}\nint main ()\n{\n  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);\n  int status = $lt_dlunknown;\n\n  if (self)\n    {\n      if (dlsym (self,\"fnord\"))       status = $lt_dlno_uscore;\n      else if (dlsym( self,\"_fnord\")) status = $lt_dlneed_uscore;\n      /* dlclose (self); */\n    }\n  else\n    puts (dlerror ());\n\n  return status;\n}\n_LT_EOF\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_link\\\"\"; } >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then\n    (./conftest; exit; ) >&5 2>/dev/null\n    lt_status=$?\n    case x$lt_status in\n      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;\n      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;\n      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;\n    esac\n  else :\n    # compilation failed\n    lt_cv_dlopen_self=no\n  fi\nfi\nrm -fr conftest*\n\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self\" >&5\n$as_echo \"$lt_cv_dlopen_self\" >&6; }\n\n    if test \"x$lt_cv_dlopen_self\" = xyes; then\n      wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $lt_prog_compiler_static\\\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself\" >&5\n$as_echo_n \"checking whether a statically linked program can dlopen itself... \" >&6; }\nif test \"${lt_cv_dlopen_self_static+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  \t  if test \"$cross_compiling\" = yes; then :\n  lt_cv_dlopen_self_static=cross\nelse\n  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n  lt_status=$lt_dlunknown\n  cat > conftest.$ac_ext <<_LT_EOF\n#line 11648 \"configure\"\n#include \"confdefs.h\"\n\n#if HAVE_DLFCN_H\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n\n#ifdef RTLD_GLOBAL\n#  define LT_DLGLOBAL\t\tRTLD_GLOBAL\n#else\n#  ifdef DL_GLOBAL\n#    define LT_DLGLOBAL\t\tDL_GLOBAL\n#  else\n#    define LT_DLGLOBAL\t\t0\n#  endif\n#endif\n\n/* We may have to define LT_DLLAZY_OR_NOW in the command line if we\n   find out it does not work in some platform. */\n#ifndef LT_DLLAZY_OR_NOW\n#  ifdef RTLD_LAZY\n#    define LT_DLLAZY_OR_NOW\t\tRTLD_LAZY\n#  else\n#    ifdef DL_LAZY\n#      define LT_DLLAZY_OR_NOW\t\tDL_LAZY\n#    else\n#      ifdef RTLD_NOW\n#        define LT_DLLAZY_OR_NOW\tRTLD_NOW\n#      else\n#        ifdef DL_NOW\n#          define LT_DLLAZY_OR_NOW\tDL_NOW\n#        else\n#          define LT_DLLAZY_OR_NOW\t0\n#        endif\n#      endif\n#    endif\n#  endif\n#endif\n\nvoid fnord() { int i=42;}\nint main ()\n{\n  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);\n  int status = $lt_dlunknown;\n\n  if (self)\n    {\n      if (dlsym (self,\"fnord\"))       status = $lt_dlno_uscore;\n      else if (dlsym( self,\"_fnord\")) status = $lt_dlneed_uscore;\n      /* dlclose (self); */\n    }\n  else\n    puts (dlerror ());\n\n  return status;\n}\n_LT_EOF\n  if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_link\\\"\"; } >&5\n  (eval $ac_link) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then\n    (./conftest; exit; ) >&5 2>/dev/null\n    lt_status=$?\n    case x$lt_status in\n      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;\n      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;\n      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;\n    esac\n  else :\n    # compilation failed\n    lt_cv_dlopen_self_static=no\n  fi\nfi\nrm -fr conftest*\n\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static\" >&5\n$as_echo \"$lt_cv_dlopen_self_static\" >&6; }\n    fi\n\n    CPPFLAGS=\"$save_CPPFLAGS\"\n    LDFLAGS=\"$save_LDFLAGS\"\n    LIBS=\"$save_LIBS\"\n    ;;\n  esac\n\n  case $lt_cv_dlopen_self in\n  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;\n  *) enable_dlopen_self=unknown ;;\n  esac\n\n  case $lt_cv_dlopen_self_static in\n  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;\n  *) enable_dlopen_self_static=unknown ;;\n  esac\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nstriplib=\nold_striplib=\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible\" >&5\n$as_echo_n \"checking whether stripping libraries is possible... \" >&6; }\nif test -n \"$STRIP\" && $STRIP -V 2>&1 | $GREP \"GNU strip\" >/dev/null; then\n  test -z \"$old_striplib\" && old_striplib=\"$STRIP --strip-debug\"\n  test -z \"$striplib\" && striplib=\"$STRIP --strip-unneeded\"\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n# FIXME - insert some real tests, host_os isn't really good enough\n  case $host_os in\n  darwin*)\n    if test -n \"$STRIP\" ; then\n      striplib=\"$STRIP -x\"\n      old_striplib=\"$STRIP -S\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n    else\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n    fi\n    ;;\n  *)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n    ;;\n  esac\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n  # Report which library types will actually be built\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries\" >&5\n$as_echo_n \"checking if libtool supports shared libraries... \" >&6; }\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $can_build_shared\" >&5\n$as_echo \"$can_build_shared\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries\" >&5\n$as_echo_n \"checking whether to build shared libraries... \" >&6; }\n  test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n  # On AIX, shared libraries and static libraries use the same namespace, and\n  # are all built from PIC.\n  case $host_os in\n  aix3*)\n    test \"$enable_shared\" = yes && enable_static=no\n    if test -n \"$RANLIB\"; then\n      archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n      postinstall_cmds='$RANLIB $lib'\n    fi\n    ;;\n\n  aix[4-9]*)\n    if test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n      test \"$enable_shared\" = yes && enable_static=no\n    fi\n    ;;\n  esac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $enable_shared\" >&5\n$as_echo \"$enable_shared\" >&6; }\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether to build static libraries\" >&5\n$as_echo_n \"checking whether to build static libraries... \" >&6; }\n  # Make sure either enable_shared or enable_static is yes.\n  test \"$enable_shared\" = yes || enable_static=yes\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $enable_static\" >&5\n$as_echo \"$enable_static\" >&6; }\n\n\n\n\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nCC=\"$lt_save_CC\"\n\n\nac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\n\narchive_cmds_need_lc_CXX=no\nallow_undefined_flag_CXX=\nalways_export_symbols_CXX=no\narchive_expsym_cmds_CXX=\ncompiler_needs_object_CXX=no\nexport_dynamic_flag_spec_CXX=\nhardcode_direct_CXX=no\nhardcode_direct_absolute_CXX=no\nhardcode_libdir_flag_spec_CXX=\nhardcode_libdir_flag_spec_ld_CXX=\nhardcode_libdir_separator_CXX=\nhardcode_minus_L_CXX=no\nhardcode_shlibpath_var_CXX=unsupported\nhardcode_automatic_CXX=no\ninherit_rpath_CXX=no\nmodule_cmds_CXX=\nmodule_expsym_cmds_CXX=\nlink_all_deplibs_CXX=unknown\nold_archive_cmds_CXX=$old_archive_cmds\nno_undefined_flag_CXX=\nwhole_archive_flag_spec_CXX=\nenable_shared_with_static_runtimes_CXX=no\n\n# Source file extension for C++ test sources.\nac_ext=cpp\n\n# Object file extension for compiled C++ test sources.\nobjext=o\nobjext_CXX=$objext\n\n# No sense in running all these tests if we already determined that\n# the CXX compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_caught_CXX_error\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"int some_variable = 0;\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n\n\n\n\n\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n\n\n  # save warnings/boilerplate of simple test code\n  ac_outfile=conftest.$ac_objext\necho \"$lt_simple_compile_test_code\" >conftest.$ac_ext\neval \"$ac_compile\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_compiler_boilerplate=`cat conftest.err`\n$RM conftest*\n\n  ac_outfile=conftest.$ac_objext\necho \"$lt_simple_link_test_code\" >conftest.$ac_ext\neval \"$ac_link\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_linker_boilerplate=`cat conftest.err`\n$RM -r conftest*\n\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=$CC\n  lt_save_LD=$LD\n  lt_save_GCC=$GCC\n  GCC=$GXX\n  lt_save_with_gnu_ld=$with_gnu_ld\n  lt_save_path_LD=$lt_cv_path_LD\n  if test -n \"${lt_cv_prog_gnu_ldcxx+set}\"; then\n    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx\n  else\n    $as_unset lt_cv_prog_gnu_ld\n  fi\n  if test -n \"${lt_cv_path_LDCXX+set}\"; then\n    lt_cv_path_LD=$lt_cv_path_LDCXX\n  else\n    $as_unset lt_cv_path_LD\n  fi\n  test -z \"${LDCXX+set}\" || LD=$LDCXX\n  CC=${CXX-\"c++\"}\n  compiler=$CC\n  compiler_CXX=$CC\n  for cc_temp in $compiler\"\"; do\n  case $cc_temp in\n    compile | *[\\\\/]compile | ccache | *[\\\\/]ccache ) ;;\n    distcc | *[\\\\/]distcc | purify | *[\\\\/]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`$ECHO \"X$cc_temp\" | $Xsed -e 's%.*/%%' -e \"s%^$host_alias-%%\"`\n\n\n  if test -n \"$compiler\"; then\n    # We don't want -fno-exception when compiling C++ code, so set the\n    # no_builtin_flag separately\n    if test \"$GXX\" = yes; then\n      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'\n    else\n      lt_prog_compiler_no_builtin_flag_CXX=\n    fi\n\n    if test \"$GXX\" = yes; then\n      # Set up default GNU C++ configuration\n\n\n\n# Check whether --with-gnu-ld was given.\nif test \"${with_gnu_ld+set}\" = set; then :\n  withval=$with_gnu_ld; test \"$withval\" = no || with_gnu_ld=yes\nelse\n  with_gnu_ld=no\nfi\n\nac_prog=ld\nif test \"$GCC\" = yes; then\n  # Check if gcc -print-prog-name=ld gives a path.\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ld used by $CC\" >&5\n$as_echo_n \"checking for ld used by $CC... \" >&6; }\n  case $host in\n  *-*-mingw*)\n    # gcc leaves a trailing carriage return which upsets mingw\n    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\\015'` ;;\n  *)\n    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;\n  esac\n  case $ac_prog in\n    # Accept absolute paths.\n    [\\\\/]* | ?:[\\\\/]*)\n      re_direlt='/[^/][^/]*/\\.\\./'\n      # Canonicalize the pathname of ld\n      ac_prog=`$ECHO \"$ac_prog\"| $SED 's%\\\\\\\\%/%g'`\n      while $ECHO \"$ac_prog\" | $GREP \"$re_direlt\" > /dev/null 2>&1; do\n\tac_prog=`$ECHO $ac_prog| $SED \"s%$re_direlt%/%\"`\n      done\n      test -z \"$LD\" && LD=\"$ac_prog\"\n      ;;\n  \"\")\n    # If it fails, then pretend we aren't using GCC.\n    ac_prog=ld\n    ;;\n  *)\n    # If it is relative, then search for the first ld in PATH.\n    with_gnu_ld=unknown\n    ;;\n  esac\nelif test \"$with_gnu_ld\" = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for GNU ld\" >&5\n$as_echo_n \"checking for GNU ld... \" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for non-GNU ld\" >&5\n$as_echo_n \"checking for non-GNU ld... \" >&6; }\nfi\nif test \"${lt_cv_path_LD+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$LD\"; then\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  for ac_dir in $PATH; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f \"$ac_dir/$ac_prog\" || test -f \"$ac_dir/$ac_prog$ac_exeext\"; then\n      lt_cv_path_LD=\"$ac_dir/$ac_prog\"\n      # Check to see if the program is GNU ld.  I'd rather use --version,\n      # but apparently some variants of GNU ld only accept -v.\n      # Break only if it was the GNU/non-GNU ld that we prefer.\n      case `\"$lt_cv_path_LD\" -v 2>&1 </dev/null` in\n      *GNU* | *'with BFD'*)\n\ttest \"$with_gnu_ld\" != no && break\n\t;;\n      *)\n\ttest \"$with_gnu_ld\" != yes && break\n\t;;\n      esac\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\nelse\n  lt_cv_path_LD=\"$LD\" # Let the user override the test with a path.\nfi\nfi\n\nLD=\"$lt_cv_path_LD\"\nif test -n \"$LD\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $LD\" >&5\n$as_echo \"$LD\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\ntest -z \"$LD\" && as_fn_error \"no acceptable ld found in \\$PATH\" \"$LINENO\" 5\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld\" >&5\n$as_echo_n \"checking if the linker ($LD) is GNU ld... \" >&6; }\nif test \"${lt_cv_prog_gnu_ld+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  # I'd rather use --version here, but apparently some GNU lds only accept -v.\ncase `$LD -v 2>&1 </dev/null` in\n*GNU* | *'with BFD'*)\n  lt_cv_prog_gnu_ld=yes\n  ;;\n*)\n  lt_cv_prog_gnu_ld=no\n  ;;\nesac\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld\" >&5\n$as_echo \"$lt_cv_prog_gnu_ld\" >&6; }\nwith_gnu_ld=$lt_cv_prog_gnu_ld\n\n\n\n\n\n\n\n      # Check if GNU C++ uses GNU ld as the underlying linker, since the\n      # archiving commands below assume that GNU ld is being used.\n      if test \"$with_gnu_ld\" = yes; then\n        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\n        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'\n        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'\n\n        # If archive_cmds runs LD, not CC, wlarc should be empty\n        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to\n        #     investigate it a little bit more. (MM)\n        wlarc='${wl}'\n\n        # ancient GNU ld didn't support --whole-archive et. al.\n        if eval \"`$CC -print-prog-name=ld` --help 2>&1\" |\n\t  $GREP 'no-whole-archive' > /dev/null; then\n          whole_archive_flag_spec_CXX=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n        else\n          whole_archive_flag_spec_CXX=\n        fi\n      else\n        with_gnu_ld=no\n        wlarc=\n\n        # A generic and very simple default shared library creation\n        # command for GNU C++ for the case where it uses the native\n        # linker, instead of GNU ld.  If possible, this setting should\n        # overridden to take advantage of the native linker features on\n        # the platform it is being used on.\n        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'\n      fi\n\n      # Commands to make compiler produce verbose output that lists\n      # what \"hidden\" libraries, object files and flags are used when\n      # linking a shared library.\n      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\n    else\n      GXX=no\n      with_gnu_ld=no\n      wlarc=\n    fi\n\n    # PORTME: fill in a description of your system's C++ link characteristics\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries\" >&5\n$as_echo_n \"checking whether the $compiler linker ($LD) supports shared libraries... \" >&6; }\n    ld_shlibs_CXX=yes\n    case $host_os in\n      aix3*)\n        # FIXME: insert proper C++ library support\n        ld_shlibs_CXX=no\n        ;;\n      aix[4-9]*)\n        if test \"$host_cpu\" = ia64; then\n          # On IA64, the linker does run time linking by default, so we don't\n          # have to do anything special.\n          aix_use_runtimelinking=no\n          exp_sym_flag='-Bexport'\n          no_entry_flag=\"\"\n        else\n          aix_use_runtimelinking=no\n\n          # Test if we are trying to use run time linking or normal\n          # AIX style linking. If -brtl is somewhere in LDFLAGS, we\n          # need to do runtime linking.\n          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)\n\t    for ld_flag in $LDFLAGS; do\n\t      case $ld_flag in\n\t      *-brtl*)\n\t        aix_use_runtimelinking=yes\n\t        break\n\t        ;;\n\t      esac\n\t    done\n\t    ;;\n          esac\n\n          exp_sym_flag='-bexport'\n          no_entry_flag='-bnoentry'\n        fi\n\n        # When large executables or shared objects are built, AIX ld can\n        # have problems creating the table of contents.  If linking a library\n        # or program results in \"error TOC overflow\" add -mminimal-toc to\n        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n        archive_cmds_CXX=''\n        hardcode_direct_CXX=yes\n        hardcode_direct_absolute_CXX=yes\n        hardcode_libdir_separator_CXX=':'\n        link_all_deplibs_CXX=yes\n        file_list_spec_CXX='${wl}-f,'\n\n        if test \"$GXX\" = yes; then\n          case $host_os in aix4.[012]|aix4.[012].*)\n          # We only want to do this on AIX 4.2 and lower, the check\n          # below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t     strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t    # We have reworked collect2\n\t    :\n\t  else\n\t    # We have old collect2\n\t    hardcode_direct_CXX=unsupported\n\t    # It fails to find uninstalled libraries when the uninstalled\n\t    # path is not listed in the libpath.  Setting hardcode_minus_L\n\t    # to unsupported forces relinking\n\t    hardcode_minus_L_CXX=yes\n\t    hardcode_libdir_flag_spec_CXX='-L$libdir'\n\t    hardcode_libdir_separator_CXX=\n\t  fi\n          esac\n          shared_flag='-shared'\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag=\"$shared_flag \"'${wl}-G'\n\t  fi\n        else\n          # not using gcc\n          if test \"$host_cpu\" = ia64; then\n\t  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t  # chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n          else\n\t    if test \"$aix_use_runtimelinking\" = yes; then\n\t      shared_flag='${wl}-G'\n\t    else\n\t      shared_flag='${wl}-bM:SRE'\n\t    fi\n          fi\n        fi\n\n        export_dynamic_flag_spec_CXX='${wl}-bexpall'\n        # It seems that -bexpall does not export symbols beginning with\n        # underscore (_), so it is better to generate a list of symbols to\n\t# export.\n        always_export_symbols_CXX=yes\n        if test \"$aix_use_runtimelinking\" = yes; then\n          # Warning - without using the other runtime loading flags (-brtl),\n          # -berok will link without error, but may produce a broken library.\n          allow_undefined_flag_CXX='-berok'\n          # Determine the default libpath from the value encoded in an empty\n          # executable.\n          cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\n          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then $ECHO \"X${wl}${allow_undefined_flag}\" | $Xsed; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n        else\n          if test \"$host_cpu\" = ia64; then\n\t    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'\n\t    allow_undefined_flag_CXX=\"-z nodefs\"\n\t    archive_expsym_cmds_CXX=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n          else\n\t    # Determine the default libpath from the value encoded in an\n\t    # empty executable.\n\t    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n\n\t    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t    # Warning - without using the other run time loading flags,\n\t    # -berok will link without error, but may produce a broken library.\n\t    no_undefined_flag_CXX=' ${wl}-bernotok'\n\t    allow_undefined_flag_CXX=' ${wl}-berok'\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    whole_archive_flag_spec_CXX='$convenience'\n\t    archive_cmds_need_lc_CXX=yes\n\t    # This is similar to how AIX traditionally builds its shared\n\t    # libraries.\n\t    archive_expsym_cmds_CXX=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n          fi\n        fi\n        ;;\n\n      beos*)\n\tif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t  allow_undefined_flag_CXX=unsupported\n\t  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t  # support --undefined.  This deserves some investigation.  FIXME\n\t  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\telse\n\t  ld_shlibs_CXX=no\n\tfi\n\t;;\n\n      chorus*)\n        case $cc_basename in\n          *)\n\t  # FIXME: insert proper C++ library support\n\t  ld_shlibs_CXX=no\n\t  ;;\n        esac\n        ;;\n\n      cygwin* | mingw* | pw32* | cegcc*)\n        # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,\n        # as there is no search path for DLLs.\n        hardcode_libdir_flag_spec_CXX='-L$libdir'\n        allow_undefined_flag_CXX=unsupported\n        always_export_symbols_CXX=no\n        enable_shared_with_static_runtimes_CXX=yes\n\n        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n          archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n          # If the export-symbols file already is a .def file (1st line\n          # is EXPORTS), use it as is; otherwise, prepend...\n          archive_expsym_cmds_CXX='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t    cp $export_symbols $output_objdir/$soname.def;\n          else\n\t    echo EXPORTS > $output_objdir/$soname.def;\n\t    cat $export_symbols >> $output_objdir/$soname.def;\n          fi~\n          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n        else\n          ld_shlibs_CXX=no\n        fi\n        ;;\n      darwin* | rhapsody*)\n\n\n  archive_cmds_need_lc_CXX=no\n  hardcode_direct_CXX=no\n  hardcode_automatic_CXX=yes\n  hardcode_shlibpath_var_CXX=unsupported\n  whole_archive_flag_spec_CXX=''\n  link_all_deplibs_CXX=yes\n  allow_undefined_flag_CXX=\"$_lt_dar_allow_undefined\"\n  case $cc_basename in\n     ifort*) _lt_dar_can_shared=yes ;;\n     *) _lt_dar_can_shared=$GCC ;;\n  esac\n  if test \"$_lt_dar_can_shared\" = \"yes\"; then\n    output_verbose_link_cmd=echo\n    archive_cmds_CXX=\"\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring $_lt_dar_single_mod${_lt_dsymutil}\"\n    module_cmds_CXX=\"\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dsymutil}\"\n    archive_expsym_cmds_CXX=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}\"\n    module_expsym_cmds_CXX=\"sed -e 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}\"\n       if test \"$lt_cv_apple_cc_single_mod\" != \"yes\"; then\n      archive_cmds_CXX=\"\\$CC -r -keep_private_externs -nostdlib -o \\${lib}-master.o \\$libobjs~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\${lib}-master.o \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring${_lt_dsymutil}\"\n      archive_expsym_cmds_CXX=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -r -keep_private_externs -nostdlib -o \\${lib}-master.o \\$libobjs~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\${lib}-master.o \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring${_lt_dar_export_syms}${_lt_dsymutil}\"\n    fi\n\n  else\n  ld_shlibs_CXX=no\n  fi\n\n\t;;\n\n      dgux*)\n        case $cc_basename in\n          ec++*)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          ghcx*)\n\t    # Green Hills C++ Compiler\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n        esac\n        ;;\n\n      freebsd[12]*)\n        # C++ shared libraries reported to be fairly broken before\n\t# switch to ELF\n        ld_shlibs_CXX=no\n        ;;\n\n      freebsd-elf*)\n        archive_cmds_need_lc_CXX=no\n        ;;\n\n      freebsd* | dragonfly*)\n        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF\n        # conventions\n        ld_shlibs_CXX=yes\n        ;;\n\n      gnu*)\n        ;;\n\n      hpux9*)\n        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'\n        hardcode_libdir_separator_CXX=:\n        export_dynamic_flag_spec_CXX='${wl}-E'\n        hardcode_direct_CXX=yes\n        hardcode_minus_L_CXX=yes # Not in the search PATH,\n\t\t\t\t             # but as the default\n\t\t\t\t             # location of the library.\n\n        case $cc_basename in\n          CC*)\n            # FIXME: insert proper C++ library support\n            ld_shlibs_CXX=no\n            ;;\n          aCC*)\n            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n            # Commands to make compiler produce verbose output that lists\n            # what \"hidden\" libraries, object files and flags are used when\n            # linking a shared library.\n            #\n            # There doesn't appear to be a way to prevent this compiler from\n            # explicitly linking system object files so we need to strip them\n            # from the output so that they don't get included in the library\n            # dependencies.\n            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP \"\\-L\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n            ;;\n          *)\n            if test \"$GXX\" = yes; then\n              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n            else\n              # FIXME: insert proper C++ library support\n              ld_shlibs_CXX=no\n            fi\n            ;;\n        esac\n        ;;\n\n      hpux10*|hpux11*)\n        if test $with_gnu_ld = no; then\n\t  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'\n\t  hardcode_libdir_separator_CXX=:\n\n          case $host_cpu in\n            hppa*64*|ia64*)\n              ;;\n            *)\n\t      export_dynamic_flag_spec_CXX='${wl}-E'\n              ;;\n          esac\n        fi\n        case $host_cpu in\n          hppa*64*|ia64*)\n            hardcode_direct_CXX=no\n            hardcode_shlibpath_var_CXX=no\n            ;;\n          *)\n            hardcode_direct_CXX=yes\n            hardcode_direct_absolute_CXX=yes\n            hardcode_minus_L_CXX=yes # Not in the search PATH,\n\t\t\t\t\t         # but as the default\n\t\t\t\t\t         # location of the library.\n            ;;\n        esac\n\n        case $cc_basename in\n          CC*)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          aCC*)\n\t    case $host_cpu in\n\t      hppa*64*)\n\t        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t      ia64*)\n\t        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t      *)\n\t        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t    esac\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP \"\\-L\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\t    ;;\n          *)\n\t    if test \"$GXX\" = yes; then\n\t      if test $with_gnu_ld = no; then\n\t        case $host_cpu in\n\t          hppa*64*)\n\t            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t          ia64*)\n\t            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t          *)\n\t            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t        esac\n\t      fi\n\t    else\n\t      # FIXME: insert proper C++ library support\n\t      ld_shlibs_CXX=no\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n      interix[3-9]*)\n\thardcode_direct_CXX=no\n\thardcode_shlibpath_var_CXX=no\n\thardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'\n\texport_dynamic_flag_spec_CXX='${wl}-E'\n\t# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n\t# Instead, shared libraries are loaded at an image base (0x10000000 by\n\t# default) and relocated if they conflict, which is a slow very memory\n\t# consuming and fragmenting process.  To avoid this, we pick a random,\n\t# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n\t# time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n\tarchive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n\tarchive_expsym_cmds_CXX='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n\t;;\n      irix5* | irix6*)\n        case $cc_basename in\n          CC*)\n\t    # SGI C++\n\t    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -ar\", where \"CC\" is the IRIX C++ compiler.  This is\n\t    # necessary to make sure instantiated templates are included\n\t    # in the archive.\n\t    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'\n\t    ;;\n          *)\n\t    if test \"$GXX\" = yes; then\n\t      if test \"$with_gnu_ld\" = no; then\n\t        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t      else\n\t        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` -o $lib'\n\t      fi\n\t    fi\n\t    link_all_deplibs_CXX=yes\n\t    ;;\n        esac\n        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'\n        hardcode_libdir_separator_CXX=:\n        inherit_rpath_CXX=yes\n        ;;\n\n      linux* | k*bsd*-gnu | kopensolaris*-gnu)\n        case $cc_basename in\n          KCC*)\n\t    # Kuck and Associates, Inc. (KAI) C++ Compiler\n\n\t    # KCC will only create a shared library if the output file\n\t    # ends with \".so\" (or \".sl\" for HP-UX), so rename the library\n\t    # to its proper name (with version) after linking.\n\t    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\\''s/\\([^()0-9A-Za-z{}]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo $lib | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib; mv \\$templib $lib'\n\t    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\\''s/\\([^()0-9A-Za-z{}]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo $lib | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib ${wl}-retain-symbols-file,$export_symbols; mv \\$templib $lib'\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP \"ld\"`; rm -f libconftest$shared_ext; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\n\t    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'\n\t    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -Bstatic\", where \"CC\" is the KAI C++ compiler.\n\t    old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'\n\t    ;;\n\t  icpc* | ecpc* )\n\t    # Intel C++\n\t    with_gnu_ld=yes\n\t    # version 8.0 and above of icpc choke on multiply defined symbols\n\t    # if we add $predep_objects and $postdep_objects, however 7.1 and\n\t    # earlier do not add the objects themselves.\n\t    case `$CC -V 2>&1` in\n\t      *\"Version 7.\"*)\n\t        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t\tarchive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t\t;;\n\t      *)  # Version 8.0 or newer\n\t        tmp_idyn=\n\t        case $host_cpu in\n\t\t  ia64*) tmp_idyn=' -i_dynamic';;\n\t\tesac\n\t        archive_cmds_CXX='$CC -shared'\"$tmp_idyn\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t\tarchive_expsym_cmds_CXX='$CC -shared'\"$tmp_idyn\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t\t;;\n\t    esac\n\t    archive_cmds_need_lc_CXX=no\n\t    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'\n\t    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'\n\t    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t    ;;\n          pgCC* | pgcpp*)\n            # Portland Group C++ compiler\n\t    case `$CC -V` in\n\t    *pgCC\\ [1-5]* | *pgcpp\\ [1-5]*)\n\t      prelink_cmds_CXX='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~\n\t\tcompile_command=\"$compile_command `find $tpldir -name \\*.o | $NL2SP`\"'\n\t      old_archive_cmds_CXX='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~\n\t\t$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \\*.o | $NL2SP`~\n\t\t$RANLIB $oldlib'\n\t      archive_cmds_CXX='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~\n\t\t$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \\*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'\n\t      archive_expsym_cmds_CXX='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~\n\t\t$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \\*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    *) # Version 6 will use weak symbols\n\t      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'\n\t      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    esac\n\n\t    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'\n\t    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'\n\t    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n            ;;\n\t  cxx*)\n\t    # Compaq C++\n\t    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'\n\n\t    runpath_var=LD_RUN_PATH\n\t    hardcode_libdir_flag_spec_CXX='-rpath $libdir'\n\t    hardcode_libdir_separator_CXX=:\n\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"ld\"`; templist=`$ECHO \"X$templist\" | $Xsed -e \"s/\\(^.*ld.*\\)\\( .*ld .*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\t    ;;\n\t  xl*)\n\t    # IBM XL 8.0 on PPC, with GNU ld\n\t    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'\n\t    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'\n\t    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    if test \"x$supports_anon_versioning\" = xyes; then\n\t      archive_expsym_cmds_CXX='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t\tcat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t\techo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t\t$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n\t    fi\n\t    ;;\n\t  *)\n\t    case `$CC -V 2>&1 | sed 5q` in\n\t    *Sun\\ C*)\n\t      # Sun C++ 5.9\n\t      no_undefined_flag_CXX=' -zdefs'\n\t      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'\n\t      hardcode_libdir_flag_spec_CXX='-R$libdir'\n\t      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t      compiler_needs_object_CXX=yes\n\n\t      # Not sure whether something based on\n\t      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1\n\t      # would be better.\n\t      output_verbose_link_cmd='echo'\n\n\t      # Archives containing C++ object files must be created using\n\t      # \"CC -xar\", where \"CC\" is the Sun C++ compiler.  This is\n\t      # necessary to make sure instantiated templates are included\n\t      # in the archive.\n\t      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'\n\t      ;;\n\t    esac\n\t    ;;\n\tesac\n\t;;\n\n      lynxos*)\n        # FIXME: insert proper C++ library support\n\tld_shlibs_CXX=no\n\t;;\n\n      m88k*)\n        # FIXME: insert proper C++ library support\n        ld_shlibs_CXX=no\n\t;;\n\n      mvs*)\n        case $cc_basename in\n          cxx*)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n\t  *)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n\tesac\n\t;;\n\n      netbsd*)\n        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'\n\t  wlarc=\n\t  hardcode_libdir_flag_spec_CXX='-R$libdir'\n\t  hardcode_direct_CXX=yes\n\t  hardcode_shlibpath_var_CXX=no\n\tfi\n\t# Workaround some broken pre-1.5 toolchains\n\toutput_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e \"s:-lgcc -lc -lgcc::\"'\n\t;;\n\n      *nto* | *qnx*)\n        ld_shlibs_CXX=yes\n\t;;\n\n      openbsd2*)\n        # C++ shared libraries are fairly broken\n\tld_shlibs_CXX=no\n\t;;\n\n      openbsd*)\n\tif test -f /usr/libexec/ld.so; then\n\t  hardcode_direct_CXX=yes\n\t  hardcode_shlibpath_var_CXX=no\n\t  hardcode_direct_absolute_CXX=yes\n\t  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'\n\t  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'\n\t  if test -z \"`echo __ELF__ | $CC -E - | grep __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'\n\t    export_dynamic_flag_spec_CXX='${wl}-E'\n\t    whole_archive_flag_spec_CXX=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n\t  fi\n\t  output_verbose_link_cmd=echo\n\telse\n\t  ld_shlibs_CXX=no\n\tfi\n\t;;\n\n      osf3* | osf4* | osf5*)\n        case $cc_basename in\n          KCC*)\n\t    # Kuck and Associates, Inc. (KAI) C++ Compiler\n\n\t    # KCC will only create a shared library if the output file\n\t    # ends with \".so\" (or \".sl\" for HP-UX), so rename the library\n\t    # to its proper name (with version) after linking.\n\t    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\\''s/\\([^()0-9A-Za-z{}]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo \"$lib\" | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib; mv \\$templib $lib'\n\n\t    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'\n\t    hardcode_libdir_separator_CXX=:\n\n\t    # Archives containing C++ object files must be created using\n\t    # the KAI C++ compiler.\n\t    case $host in\n\t      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;\n\t      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;\n\t    esac\n\t    ;;\n          RCC*)\n\t    # Rational C++ 2.4.1\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          cxx*)\n\t    case $host in\n\t      osf3*)\n\t        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\\*'\n\t        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\t        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'\n\t\t;;\n\t      *)\n\t        allow_undefined_flag_CXX=' -expect_unresolved \\*'\n\t        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\t        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done~\n\t          echo \"-hidden\">> $lib.exp~\n\t          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~\n\t          $RM $lib.exp'\n\t        hardcode_libdir_flag_spec_CXX='-rpath $libdir'\n\t\t;;\n\t    esac\n\n\t    hardcode_libdir_separator_CXX=:\n\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"ld\" | $GREP -v \"ld:\"`; templist=`$ECHO \"X$templist\" | $Xsed -e \"s/\\(^.*ld.*\\)\\( .*ld.*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\t    ;;\n\t  *)\n\t    if test \"$GXX\" = yes && test \"$with_gnu_ld\" = no; then\n\t      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\\*'\n\t      case $host in\n\t        osf3*)\n\t          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t        *)\n\t          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t      esac\n\n\t      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'\n\t      hardcode_libdir_separator_CXX=:\n\n\t      # Commands to make compiler produce verbose output that lists\n\t      # what \"hidden\" libraries, object files and flags are used when\n\t      # linking a shared library.\n\t      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\n\t    else\n\t      # FIXME: insert proper C++ library support\n\t      ld_shlibs_CXX=no\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n      psos*)\n        # FIXME: insert proper C++ library support\n        ld_shlibs_CXX=no\n        ;;\n\n      sunos4*)\n        case $cc_basename in\n          CC*)\n\t    # Sun C++ 4.x\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          lcc*)\n\t    # Lucid\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n        esac\n        ;;\n\n      solaris*)\n        case $cc_basename in\n          CC*)\n\t    # Sun C++ 4.2, 5.x and Centerline C++\n            archive_cmds_need_lc_CXX=yes\n\t    no_undefined_flag_CXX=' -zdefs'\n\t    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t    archive_expsym_cmds_CXX='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t    hardcode_libdir_flag_spec_CXX='-R$libdir'\n\t    hardcode_shlibpath_var_CXX=no\n\t    case $host_os in\n\t      solaris2.[0-5] | solaris2.[0-5].*) ;;\n\t      *)\n\t\t# The compiler driver will combine and reorder linker options,\n\t\t# but understands `-z linker_flag'.\n\t        # Supported since Solaris 2.6 (maybe 2.5.1?)\n\t\twhole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'\n\t        ;;\n\t    esac\n\t    link_all_deplibs_CXX=yes\n\n\t    output_verbose_link_cmd='echo'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -xar\", where \"CC\" is the Sun C++ compiler.  This is\n\t    # necessary to make sure instantiated templates are included\n\t    # in the archive.\n\t    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'\n\t    ;;\n          gcx*)\n\t    # Green Hills C++ Compiler\n\t    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\n\t    # The C++ compiler must be used to create the archive.\n\t    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'\n\t    ;;\n          *)\n\t    # GNU C++ compiler with Solaris linker\n\t    if test \"$GXX\" = yes && test \"$with_gnu_ld\" = no; then\n\t      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'\n\t      if $CC --version | $GREP -v '^2\\.7' > /dev/null; then\n\t        archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\t        archive_expsym_cmds_CXX='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t\t  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t        # Commands to make compiler produce verbose output that lists\n\t        # what \"hidden\" libraries, object files and flags are used when\n\t        # linking a shared library.\n\t        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\t      else\n\t        # g++ 2.7 appears to require `-G' NOT `-shared' on this\n\t        # platform.\n\t        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\t        archive_expsym_cmds_CXX='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t\t  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t        # Commands to make compiler produce verbose output that lists\n\t        # what \"hidden\" libraries, object files and flags are used when\n\t        # linking a shared library.\n\t        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\t      fi\n\n\t      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'\n\t      case $host_os in\n\t\tsolaris2.[0-5] | solaris2.[0-5].*) ;;\n\t\t*)\n\t\t  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\t\t  ;;\n\t      esac\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)\n      no_undefined_flag_CXX='${wl}-z,text'\n      archive_cmds_need_lc_CXX=no\n      hardcode_shlibpath_var_CXX=no\n      runpath_var='LD_RUN_PATH'\n\n      case $cc_basename in\n        CC*)\n\t  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n      esac\n      ;;\n\n      sysv5* | sco3.2v5* | sco5v6*)\n\t# Note: We can NOT use -z defs as we might desire, because we do not\n\t# link with -lc, and that would cause any symbols used from libc to\n\t# always be unresolved, which means just about no library would\n\t# ever link correctly.  If we're not using GNU ld we use -z text\n\t# though, which does catch some bad symbols but isn't as heavy-handed\n\t# as -z defs.\n\tno_undefined_flag_CXX='${wl}-z,text'\n\tallow_undefined_flag_CXX='${wl}-z,nodefs'\n\tarchive_cmds_need_lc_CXX=no\n\thardcode_shlibpath_var_CXX=no\n\thardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'\n\thardcode_libdir_separator_CXX=':'\n\tlink_all_deplibs_CXX=yes\n\texport_dynamic_flag_spec_CXX='${wl}-Bexport'\n\trunpath_var='LD_RUN_PATH'\n\n\tcase $cc_basename in\n          CC*)\n\t    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    ;;\n\t  *)\n\t    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    ;;\n\tesac\n      ;;\n\n      tandem*)\n        case $cc_basename in\n          NCC*)\n\t    # NonStop-UX NCC 3.20\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    ld_shlibs_CXX=no\n\t    ;;\n        esac\n        ;;\n\n      vxworks*)\n        # FIXME: insert proper C++ library support\n        ld_shlibs_CXX=no\n        ;;\n\n      *)\n        # FIXME: insert proper C++ library support\n        ld_shlibs_CXX=no\n        ;;\n    esac\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX\" >&5\n$as_echo \"$ld_shlibs_CXX\" >&6; }\n    test \"$ld_shlibs_CXX\" = no && can_build_shared=no\n\n    GCC_CXX=\"$GXX\"\n    LD_CXX=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    # Dependencies to place before and after the object being linked:\npredep_objects_CXX=\npostdep_objects_CXX=\npredeps_CXX=\npostdeps_CXX=\ncompiler_lib_search_path_CXX=\n\ncat > conftest.$ac_ext <<_LT_EOF\nclass Foo\n{\npublic:\n  Foo (void) { a = 0; }\nprivate:\n  int a;\n};\n_LT_EOF\n\nif { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then\n  # Parse the compiler output and extract the necessary\n  # objects, libraries and library flags.\n\n  # Sentinel used to keep track of whether or not we are before\n  # the conftest object file.\n  pre_test_object_deps_done=no\n\n  for p in `eval \"$output_verbose_link_cmd\"`; do\n    case $p in\n\n    -L* | -R* | -l*)\n       # Some compilers place space between \"-{L,R}\" and the path.\n       # Remove the space.\n       if test $p = \"-L\" ||\n          test $p = \"-R\"; then\n\t prev=$p\n\t continue\n       else\n\t prev=\n       fi\n\n       if test \"$pre_test_object_deps_done\" = no; then\n\t case $p in\n\t -L* | -R*)\n\t   # Internal compiler library paths should come after those\n\t   # provided the user.  The postdeps already come after the\n\t   # user supplied libs so there is no need to process them.\n\t   if test -z \"$compiler_lib_search_path_CXX\"; then\n\t     compiler_lib_search_path_CXX=\"${prev}${p}\"\n\t   else\n\t     compiler_lib_search_path_CXX=\"${compiler_lib_search_path_CXX} ${prev}${p}\"\n\t   fi\n\t   ;;\n\t # The \"-l\" case would never come before the object being\n\t # linked, so don't bother handling this case.\n\t esac\n       else\n\t if test -z \"$postdeps_CXX\"; then\n\t   postdeps_CXX=\"${prev}${p}\"\n\t else\n\t   postdeps_CXX=\"${postdeps_CXX} ${prev}${p}\"\n\t fi\n       fi\n       ;;\n\n    *.$objext)\n       # This assumes that the test object file only shows up\n       # once in the compiler output.\n       if test \"$p\" = \"conftest.$objext\"; then\n\t pre_test_object_deps_done=yes\n\t continue\n       fi\n\n       if test \"$pre_test_object_deps_done\" = no; then\n\t if test -z \"$predep_objects_CXX\"; then\n\t   predep_objects_CXX=\"$p\"\n\t else\n\t   predep_objects_CXX=\"$predep_objects_CXX $p\"\n\t fi\n       else\n\t if test -z \"$postdep_objects_CXX\"; then\n\t   postdep_objects_CXX=\"$p\"\n\t else\n\t   postdep_objects_CXX=\"$postdep_objects_CXX $p\"\n\t fi\n       fi\n       ;;\n\n    *) ;; # Ignore the rest.\n\n    esac\n  done\n\n  # Clean up.\n  rm -f a.out a.exe\nelse\n  echo \"libtool.m4: error: problem compiling CXX test program\"\nfi\n\n$RM -f confest.$objext\n\n# PORTME: override above test on systems where it is broken\ncase $host_os in\ninterix[3-9]*)\n  # Interix 3.5 installs completely hosed .la files for C++, so rather than\n  # hack all around it, let's just trust \"g++\" to DTRT.\n  predep_objects_CXX=\n  postdep_objects_CXX=\n  postdeps_CXX=\n  ;;\n\nlinux*)\n  case `$CC -V 2>&1 | sed 5q` in\n  *Sun\\ C*)\n    # Sun C++ 5.9\n\n    # The more standards-conforming stlport4 library is\n    # incompatible with the Cstd library. Avoid specifying\n    # it if it's in CXXFLAGS. Ignore libCrun as\n    # -library=stlport4 depends on it.\n    case \" $CXX $CXXFLAGS \" in\n    *\" -library=stlport4 \"*)\n      solaris_use_stlport4=yes\n      ;;\n    esac\n\n    if test \"$solaris_use_stlport4\" != yes; then\n      postdeps_CXX='-library=Cstd -library=Crun'\n    fi\n    ;;\n  esac\n  ;;\n\nsolaris*)\n  case $cc_basename in\n  CC*)\n    # The more standards-conforming stlport4 library is\n    # incompatible with the Cstd library. Avoid specifying\n    # it if it's in CXXFLAGS. Ignore libCrun as\n    # -library=stlport4 depends on it.\n    case \" $CXX $CXXFLAGS \" in\n    *\" -library=stlport4 \"*)\n      solaris_use_stlport4=yes\n      ;;\n    esac\n\n    # Adding this requires a known-good setup of shared libraries for\n    # Sun compiler versions before 5.6, else PIC objects from an old\n    # archive will be linked into the output, leading to subtle bugs.\n    if test \"$solaris_use_stlport4\" != yes; then\n      postdeps_CXX='-library=Cstd -library=Crun'\n    fi\n    ;;\n  esac\n  ;;\nesac\n\n\ncase \" $postdeps_CXX \" in\n*\" -lc \"*) archive_cmds_need_lc_CXX=no ;;\nesac\n compiler_lib_search_dirs_CXX=\nif test -n \"${compiler_lib_search_path_CXX}\"; then\n compiler_lib_search_dirs_CXX=`echo \" ${compiler_lib_search_path_CXX}\" | ${SED} -e 's! -L! !g' -e 's!^ !!'`\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    lt_prog_compiler_wl_CXX=\nlt_prog_compiler_pic_CXX=\nlt_prog_compiler_static_CXX=\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC\" >&5\n$as_echo_n \"checking for $compiler option to produce PIC... \" >&6; }\n\n  # C++ specific cases for pic, static, wl, etc.\n  if test \"$GXX\" = yes; then\n    lt_prog_compiler_wl_CXX='-Wl,'\n    lt_prog_compiler_static_CXX='-static'\n\n    case $host_os in\n    aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\tlt_prog_compiler_static_CXX='-Bstatic'\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            lt_prog_compiler_pic_CXX='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n    mingw* | cygwin* | os2* | pw32* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'\n      ;;\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      lt_prog_compiler_pic_CXX='-fno-common'\n      ;;\n    *djgpp*)\n      # DJGPP does not support shared libraries at all\n      lt_prog_compiler_pic_CXX=\n      ;;\n    interix[3-9]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\tlt_prog_compiler_pic_CXX=-Kconform_pic\n      fi\n      ;;\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t;;\n      *)\n\tlt_prog_compiler_pic_CXX='-fPIC'\n\t;;\n      esac\n      ;;\n    *qnx* | *nto*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      lt_prog_compiler_pic_CXX='-fPIC -shared'\n      ;;\n    *)\n      lt_prog_compiler_pic_CXX='-fPIC'\n      ;;\n    esac\n  else\n    case $host_os in\n      aix[4-9]*)\n\t# All AIX code is PIC.\n\tif test \"$host_cpu\" = ia64; then\n\t  # AIX 5 now supports IA64 processor\n\t  lt_prog_compiler_static_CXX='-Bstatic'\n\telse\n\t  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'\n\tfi\n\t;;\n      chorus*)\n\tcase $cc_basename in\n\tcxch68*)\n\t  # Green Hills C++ Compiler\n\t  # _LT_TAGVAR(lt_prog_compiler_static, CXX)=\"--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a\"\n\t  ;;\n\tesac\n\t;;\n      dgux*)\n\tcase $cc_basename in\n\t  ec++*)\n\t    lt_prog_compiler_pic_CXX='-KPIC'\n\t    ;;\n\t  ghcx*)\n\t    # Green Hills C++ Compiler\n\t    lt_prog_compiler_pic_CXX='-pic'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      freebsd* | dragonfly*)\n\t# FreeBSD uses GNU C++\n\t;;\n      hpux9* | hpux10* | hpux11*)\n\tcase $cc_basename in\n\t  CC*)\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'\n\t    if test \"$host_cpu\" != ia64; then\n\t      lt_prog_compiler_pic_CXX='+Z'\n\t    fi\n\t    ;;\n\t  aCC*)\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'\n\t    case $host_cpu in\n\t    hppa*64*|ia64*)\n\t      # +Z the default\n\t      ;;\n\t    *)\n\t      lt_prog_compiler_pic_CXX='+Z'\n\t      ;;\n\t    esac\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      interix*)\n\t# This is c89, which is MS Visual C++ (no shared libs)\n\t# Anyone wants to do a port?\n\t;;\n      irix5* | irix6* | nonstopux*)\n\tcase $cc_basename in\n\t  CC*)\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_static_CXX='-non_shared'\n\t    # CC pic flag -KPIC is the default.\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      linux* | k*bsd*-gnu | kopensolaris*-gnu)\n\tcase $cc_basename in\n\t  KCC*)\n\t    # KAI C++ Compiler\n\t    lt_prog_compiler_wl_CXX='--backend -Wl,'\n\t    lt_prog_compiler_pic_CXX='-fPIC'\n\t    ;;\n\t  ecpc* )\n\t    # old Intel C++ for x86_64 which still supported -KPIC.\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_pic_CXX='-KPIC'\n\t    lt_prog_compiler_static_CXX='-static'\n\t    ;;\n\t  icpc* )\n\t    # Intel C++, used to be incompatible with GCC.\n\t    # ICC 10 doesn't accept -KPIC any more.\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_pic_CXX='-fPIC'\n\t    lt_prog_compiler_static_CXX='-static'\n\t    ;;\n\t  pgCC* | pgcpp*)\n\t    # Portland Group C++ compiler\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_pic_CXX='-fpic'\n\t    lt_prog_compiler_static_CXX='-Bstatic'\n\t    ;;\n\t  cxx*)\n\t    # Compaq C++\n\t    # Make sure the PIC flag is empty.  It appears that all Alpha\n\t    # Linux and Compaq Tru64 Unix objects are PIC.\n\t    lt_prog_compiler_pic_CXX=\n\t    lt_prog_compiler_static_CXX='-non_shared'\n\t    ;;\n\t  xlc* | xlC*)\n\t    # IBM XL 8.0 on PPC\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_pic_CXX='-qpic'\n\t    lt_prog_compiler_static_CXX='-qstaticlink'\n\t    ;;\n\t  *)\n\t    case `$CC -V 2>&1 | sed 5q` in\n\t    *Sun\\ C*)\n\t      # Sun C++ 5.9\n\t      lt_prog_compiler_pic_CXX='-KPIC'\n\t      lt_prog_compiler_static_CXX='-Bstatic'\n\t      lt_prog_compiler_wl_CXX='-Qoption ld '\n\t      ;;\n\t    esac\n\t    ;;\n\tesac\n\t;;\n      lynxos*)\n\t;;\n      m88k*)\n\t;;\n      mvs*)\n\tcase $cc_basename in\n\t  cxx*)\n\t    lt_prog_compiler_pic_CXX='-W c,exportall'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      netbsd* | netbsdelf*-gnu)\n\t;;\n      *qnx* | *nto*)\n        # QNX uses GNU C++, but need to define -shared option too, otherwise\n        # it will coredump.\n        lt_prog_compiler_pic_CXX='-fPIC -shared'\n        ;;\n      osf3* | osf4* | osf5*)\n\tcase $cc_basename in\n\t  KCC*)\n\t    lt_prog_compiler_wl_CXX='--backend -Wl,'\n\t    ;;\n\t  RCC*)\n\t    # Rational C++ 2.4.1\n\t    lt_prog_compiler_pic_CXX='-pic'\n\t    ;;\n\t  cxx*)\n\t    # Digital/Compaq C++\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    # Make sure the PIC flag is empty.  It appears that all Alpha\n\t    # Linux and Compaq Tru64 Unix objects are PIC.\n\t    lt_prog_compiler_pic_CXX=\n\t    lt_prog_compiler_static_CXX='-non_shared'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      psos*)\n\t;;\n      solaris*)\n\tcase $cc_basename in\n\t  CC*)\n\t    # Sun C++ 4.2, 5.x and Centerline C++\n\t    lt_prog_compiler_pic_CXX='-KPIC'\n\t    lt_prog_compiler_static_CXX='-Bstatic'\n\t    lt_prog_compiler_wl_CXX='-Qoption ld '\n\t    ;;\n\t  gcx*)\n\t    # Green Hills C++ Compiler\n\t    lt_prog_compiler_pic_CXX='-PIC'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      sunos4*)\n\tcase $cc_basename in\n\t  CC*)\n\t    # Sun C++ 4.x\n\t    lt_prog_compiler_pic_CXX='-pic'\n\t    lt_prog_compiler_static_CXX='-Bstatic'\n\t    ;;\n\t  lcc*)\n\t    # Lucid\n\t    lt_prog_compiler_pic_CXX='-pic'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n\tcase $cc_basename in\n\t  CC*)\n\t    lt_prog_compiler_wl_CXX='-Wl,'\n\t    lt_prog_compiler_pic_CXX='-KPIC'\n\t    lt_prog_compiler_static_CXX='-Bstatic'\n\t    ;;\n\tesac\n\t;;\n      tandem*)\n\tcase $cc_basename in\n\t  NCC*)\n\t    # NonStop-UX NCC 3.20\n\t    lt_prog_compiler_pic_CXX='-KPIC'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      vxworks*)\n\t;;\n      *)\n\tlt_prog_compiler_can_build_shared_CXX=no\n\t;;\n    esac\n  fi\n\ncase $host_os in\n  # For platforms which do not support PIC, -DPIC is meaningless:\n  *djgpp*)\n    lt_prog_compiler_pic_CXX=\n    ;;\n  *)\n    lt_prog_compiler_pic_CXX=\"$lt_prog_compiler_pic_CXX -DPIC\"\n    ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX\" >&5\n$as_echo \"$lt_prog_compiler_pic_CXX\" >&6; }\n\n\n\n#\n# Check to make sure the PIC flag actually works.\n#\nif test -n \"$lt_prog_compiler_pic_CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works\" >&5\n$as_echo_n \"checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... \" >&6; }\nif test \"${lt_cv_prog_compiler_pic_works_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_pic_works_CXX=no\n   ac_outfile=conftest.$ac_objext\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"$lt_prog_compiler_pic_CXX -DPIC\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:13604: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&5\n   echo \"$as_me:13608: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_pic_works_CXX=yes\n     fi\n   fi\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX\" >&5\n$as_echo \"$lt_cv_prog_compiler_pic_works_CXX\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_pic_works_CXX\" = xyes; then\n    case $lt_prog_compiler_pic_CXX in\n     \"\" | \" \"*) ;;\n     *) lt_prog_compiler_pic_CXX=\" $lt_prog_compiler_pic_CXX\" ;;\n     esac\nelse\n    lt_prog_compiler_pic_CXX=\n     lt_prog_compiler_can_build_shared_CXX=no\nfi\n\nfi\n\n\n\n#\n# Check to make sure the static flag actually works.\n#\nwl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\\\"$lt_prog_compiler_static_CXX\\\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works\" >&5\n$as_echo_n \"checking if $compiler static flag $lt_tmp_static_flag works... \" >&6; }\nif test \"${lt_cv_prog_compiler_static_works_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_static_works_CXX=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS $lt_tmp_static_flag\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&5\n       $ECHO \"X$_lt_linker_boilerplate\" | $Xsed -e '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         lt_cv_prog_compiler_static_works_CXX=yes\n       fi\n     else\n       lt_cv_prog_compiler_static_works_CXX=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX\" >&5\n$as_echo \"$lt_cv_prog_compiler_static_works_CXX\" >&6; }\n\nif test x\"$lt_cv_prog_compiler_static_works_CXX\" = xyes; then\n    :\nelse\n    lt_prog_compiler_static_CXX=\nfi\n\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o_CXX=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:13703: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:13707: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o_CXX=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o_CXX\" >&6; }\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext\" >&5\n$as_echo_n \"checking if $compiler supports -c -o file.$ac_objext... \" >&6; }\nif test \"${lt_cv_prog_compiler_c_o_CXX+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  lt_cv_prog_compiler_c_o_CXX=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [^ ]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:13755: $lt_compile\\\"\" >&5)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&5\n   echo \"$as_me:13759: \\$? = $ac_status\" >&5\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       lt_cv_prog_compiler_c_o_CXX=yes\n     fi\n   fi\n   chmod u+w . 2>&5\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX\" >&5\n$as_echo \"$lt_cv_prog_compiler_c_o_CXX\" >&6; }\n\n\n\n\nhard_links=\"nottested\"\nif test \"$lt_cv_prog_compiler_c_o_CXX\" = no && test \"$need_locks\" != no; then\n  # do not overwrite the value of need_locks provided by the user\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links\" >&5\n$as_echo_n \"checking if we can lock with hard links... \" >&6; }\n  hard_links=yes\n  $RM conftest*\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  touch conftest.a\n  ln conftest.a conftest.b 2>&5 || hard_links=no\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hard_links\" >&5\n$as_echo \"$hard_links\" >&6; }\n  if test \"$hard_links\" = no; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&5\n$as_echo \"$as_me: WARNING: \\`$CC' does not support \\`-c -o', so \\`make -j' may be unsafe\" >&2;}\n    need_locks=warn\n  fi\nelse\n  need_locks=no\nfi\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries\" >&5\n$as_echo_n \"checking whether the $compiler linker ($LD) supports shared libraries... \" >&6; }\n\n  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  case $host_os in\n  aix[4-9]*)\n    # If we're using GNU nm, then we don't want the \"-C\" option.\n    # -C means demangle to AIX nm, but means don't demangle with GNU nm\n    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n    else\n      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && (substr(\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n    fi\n    ;;\n  pw32*)\n    export_symbols_cmds_CXX=\"$ltdll_cmds\"\n  ;;\n  cygwin* | mingw* | cegcc*)\n    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[BCDGRS][ ]/s/.*[ ]\\([^ ]*\\)/\\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\\([^ ]*\\)[ ][^ ]*/\\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\\'' | sort | uniq > $export_symbols'\n  ;;\n  linux* | k*bsd*-gnu)\n    link_all_deplibs_CXX=no\n  ;;\n  *)\n    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  ;;\n  esac\n  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX\" >&5\n$as_echo \"$ld_shlibs_CXX\" >&6; }\ntest \"$ld_shlibs_CXX\" = no && can_build_shared=no\n\nwith_gnu_ld_CXX=$with_gnu_ld\n\n\n\n\n\n\n#\n# Do we need to explicitly link libc?\n#\ncase \"x$archive_cmds_need_lc_CXX\" in\nx|xyes)\n  # Assume -lc should be added\n  archive_cmds_need_lc_CXX=yes\n\n  if test \"$enable_shared\" = yes && test \"$GCC\" = yes; then\n    case $archive_cmds_CXX in\n    *'~'*)\n      # FIXME: we may have to deal with multi-command sequences.\n      ;;\n    '$CC '*)\n      # Test whether the compiler implicitly links with -lc since on some\n      # systems, -lgcc has to come before -lc. If gcc already passes -lc\n      # to ld, don't add -lc before -lgcc.\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in\" >&5\n$as_echo_n \"checking whether -lc should be explicitly linked in... \" >&6; }\n      $RM conftest*\n      echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n      if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$ac_compile\\\"\"; } >&5\n  (eval $ac_compile) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } 2>conftest.err; then\n        soname=conftest\n        lib=conftest\n        libobjs=conftest.$ac_objext\n        deplibs=\n        wl=$lt_prog_compiler_wl_CXX\n\tpic_flag=$lt_prog_compiler_pic_CXX\n        compiler_flags=-v\n        linker_flags=-v\n        verstring=\n        output_objdir=.\n        libname=conftest\n        lt_save_allow_undefined_flag=$allow_undefined_flag_CXX\n        allow_undefined_flag_CXX=\n        if { { eval echo \"\\\"\\$as_me\\\":${as_lineno-$LINENO}: \\\"$archive_cmds_CXX 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1\\\"\"; } >&5\n  (eval $archive_cmds_CXX 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1) 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n        then\n\t  archive_cmds_need_lc_CXX=no\n        else\n\t  archive_cmds_need_lc_CXX=yes\n        fi\n        allow_undefined_flag_CXX=$lt_save_allow_undefined_flag\n      else\n        cat conftest.err 1>&5\n      fi\n      $RM conftest*\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX\" >&5\n$as_echo \"$archive_cmds_need_lc_CXX\" >&6; }\n      ;;\n    esac\n  fi\n  ;;\nesac\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics\" >&5\n$as_echo_n \"checking dynamic linker characteristics... \" >&6; }\n\nlibrary_names_spec=\nlibname_spec='lib$name'\nsoname_spec=\nshrext_cmds=\".so\"\npostinstall_cmds=\npostuninstall_cmds=\nfinish_cmds=\nfinish_eval=\nshlibpath_var=\nshlibpath_overrides_runpath=unknown\nversion_type=none\ndynamic_linker=\"$host_os ld.so\"\nsys_lib_dlsearch_path_spec=\"/lib /usr/lib\"\nneed_lib_prefix=unknown\nhardcode_into_libs=no\n\n# when you set need_version to no, make sure it does not cause -set_version\n# flags to be left without arguments\nneed_version=unknown\n\ncase $host_os in\naix3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'\n  shlibpath_var=LIBPATH\n\n  # AIX 3 has no versioning support, so we append a major version to the name.\n  soname_spec='${libname}${release}${shared_ext}$major'\n  ;;\n\naix[4-9]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  hardcode_into_libs=yes\n  if test \"$host_cpu\" = ia64; then\n    # AIX 5 supports IA64\n    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'\n    shlibpath_var=LD_LIBRARY_PATH\n  else\n    # With GCC up to 2.95.x, collect2 would create an import file\n    # for dependence libraries.  The import file would start with\n    # the line `#! .'.  This would cause the generated library to\n    # depend on `.', always an invalid library.  This was fixed in\n    # development snapshots of GCC prior to 3.0.\n    case $host_os in\n      aix4 | aix4.[01] | aix4.[01].*)\n      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'\n\t   echo ' yes '\n\t   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then\n\t:\n      else\n\tcan_build_shared=no\n      fi\n      ;;\n    esac\n    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct\n    # soname into executable. Probably we can add versioning support to\n    # collect2, so additional links can be useful in future.\n    if test \"$aix_use_runtimelinking\" = yes; then\n      # If using run time linking (on AIX 4.2 or later) use lib<name>.so\n      # instead of lib<name>.a to let people know that these are not\n      # typical AIX shared libraries.\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    else\n      # We preserve .a as extension for shared libraries through AIX4.2\n      # and later when we are not doing run time linking.\n      library_names_spec='${libname}${release}.a $libname.a'\n      soname_spec='${libname}${release}${shared_ext}$major'\n    fi\n    shlibpath_var=LIBPATH\n  fi\n  ;;\n\namigaos*)\n  case $host_cpu in\n  powerpc)\n    # Since July 2007 AmigaOS4 officially supports .so libraries.\n    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    ;;\n  m68k)\n    library_names_spec='$libname.ixlibrary $libname.a'\n    # Create ${libname}_ixlibrary.a entries in /sys/libs.\n    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO \"X$lib\" | $Xsed -e '\\''s%^.*/\\([^/]*\\)\\.ixlibrary$%\\1%'\\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show \"cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a\"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'\n    ;;\n  esac\n  ;;\n\nbeos*)\n  library_names_spec='${libname}${shared_ext}'\n  dynamic_linker=\"$host_os ld.so\"\n  shlibpath_var=LIBRARY_PATH\n  ;;\n\nbsdi[45]*)\n  version_type=linux\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib\"\n  sys_lib_dlsearch_path_spec=\"/shlib /usr/lib /usr/local/lib\"\n  # the default ld.so.conf also contains /usr/contrib/lib and\n  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow\n  # libtool to hard-code these into programs\n  ;;\n\ncygwin* | mingw* | pw32* | cegcc*)\n  version_type=windows\n  shrext_cmds=\".dll\"\n  need_version=no\n  need_lib_prefix=no\n\n  case $GCC,$host_os in\n  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)\n    library_names_spec='$libname.dll.a'\n    # DLL is installed to $(libdir)/../bin by postinstall_cmds\n    postinstall_cmds='base_file=`basename \\${file}`~\n      dlpath=`$SHELL 2>&1 -c '\\''. $dir/'\\''\\${base_file}'\\''i; echo \\$dlname'\\''`~\n      dldir=$destdir/`dirname \\$dlpath`~\n      test -d \\$dldir || mkdir -p \\$dldir~\n      $install_prog $dir/$dlname \\$dldir/$dlname~\n      chmod a+x \\$dldir/$dlname~\n      if test -n '\\''$stripme'\\'' && test -n '\\''$striplib'\\''; then\n        eval '\\''$striplib \\$dldir/$dlname'\\'' || exit \\$?;\n      fi'\n    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n\n    case $host_os in\n    cygwin*)\n      # Cygwin DLLs use 'cyg' prefix rather than 'lib'\n      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      sys_lib_search_path_spec=\"/usr/lib /lib/w32api /lib /usr/local/lib\"\n      ;;\n    mingw* | cegcc*)\n      # MinGW DLLs use traditional 'lib' prefix\n      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP \"^libraries:\" | $SED -e \"s/^libraries://\" -e \"s,=/,/,g\"`\n      if $ECHO \"$sys_lib_search_path_spec\" | $GREP ';[c-zC-Z]:/' >/dev/null; then\n        # It is most probably a Windows format PATH printed by\n        # mingw gcc, but we are running on Cygwin. Gcc prints its search\n        # path with ; separators, and with drive letters. We can handle the\n        # drive letters (cygwin fileutils understands them), so leave them,\n        # especially as we might pass files found there to a mingw objdump,\n        # which wouldn't understand a cygwinified path. Ahh.\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED -e 's/;/ /g'`\n      else\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED  -e \"s/$PATH_SEPARATOR/ /g\"`\n      fi\n      ;;\n    pw32*)\n      # pw32 DLLs use 'pw' prefix rather than 'lib'\n      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    esac\n    ;;\n\n  *)\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    ;;\n  esac\n  dynamic_linker='Win32 ld.exe'\n  # FIXME: first we should search . and the directory the executable is in\n  shlibpath_var=PATH\n  ;;\n\ndarwin* | rhapsody*)\n  dynamic_linker=\"$host_os dyld\"\n  version_type=darwin\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'\n  soname_spec='${libname}${release}${major}$shared_ext'\n  shlibpath_overrides_runpath=yes\n  shlibpath_var=DYLD_LIBRARY_PATH\n  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'\n\n  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'\n  ;;\n\ndgux*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\nfreebsd1*)\n  dynamic_linker=no\n  ;;\n\nfreebsd* | dragonfly*)\n  # DragonFly does not have aout.  When/if they implement a new\n  # versioning mechanism, adjust this.\n  if test -x /usr/bin/objformat; then\n    objformat=`/usr/bin/objformat`\n  else\n    case $host_os in\n    freebsd[123]*) objformat=aout ;;\n    *) objformat=elf ;;\n    esac\n  fi\n  version_type=freebsd-$objformat\n  case $version_type in\n    freebsd-elf*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n      need_version=no\n      need_lib_prefix=no\n      ;;\n    freebsd-*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'\n      need_version=yes\n      ;;\n  esac\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_os in\n  freebsd2*)\n    shlibpath_overrides_runpath=yes\n    ;;\n  freebsd3.[01]* | freebsdelf3.[01]*)\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \\\n  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)\n    shlibpath_overrides_runpath=no\n    hardcode_into_libs=yes\n    ;;\n  *) # from 4.6 on, and DragonFly\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  esac\n  ;;\n\ngnu*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  hardcode_into_libs=yes\n  ;;\n\nhpux9* | hpux10* | hpux11*)\n  # Give a soname corresponding to the major version so that dld.sl refuses to\n  # link against other versions.\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  case $host_cpu in\n  ia64*)\n    shrext_cmds='.so'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.so\"\n    shlibpath_var=LD_LIBRARY_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    if test \"X$HPUX_IA64_MODE\" = X32; then\n      sys_lib_search_path_spec=\"/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib\"\n    else\n      sys_lib_search_path_spec=\"/usr/lib/hpux64 /usr/local/lib/hpux64\"\n    fi\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  hppa*64*)\n    shrext_cmds='.sl'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    sys_lib_search_path_spec=\"/usr/lib/pa20_64 /usr/ccs/lib/pa20_64\"\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  *)\n    shrext_cmds='.sl'\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=SHLIB_PATH\n    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    ;;\n  esac\n  # HP-UX runs *really* slowly unless shared libraries are mode 555.\n  postinstall_cmds='chmod 555 $lib'\n  ;;\n\ninterix[3-9]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $host_os in\n    nonstopux*) version_type=nonstopux ;;\n    *)\n\tif test \"$lt_cv_prog_gnu_ld\" = yes; then\n\t\tversion_type=linux\n\telse\n\t\tversion_type=irix\n\tfi ;;\n  esac\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'\n  case $host_os in\n  irix5* | nonstopux*)\n    libsuff= shlibsuff=\n    ;;\n  *)\n    case $LD in # libtool.m4 will add one of these switches to LD\n    *-32|*\"-32 \"|*-melf32bsmip|*\"-melf32bsmip \")\n      libsuff= shlibsuff= libmagic=32-bit;;\n    *-n32|*\"-n32 \"|*-melf32bmipn32|*\"-melf32bmipn32 \")\n      libsuff=32 shlibsuff=N32 libmagic=N32;;\n    *-64|*\"-64 \"|*-melf64bmip|*\"-melf64bmip \")\n      libsuff=64 shlibsuff=64 libmagic=64-bit;;\n    *) libsuff= shlibsuff= libmagic=never-match;;\n    esac\n    ;;\n  esac\n  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH\n  shlibpath_overrides_runpath=no\n  sys_lib_search_path_spec=\"/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}\"\n  sys_lib_dlsearch_path_spec=\"/usr/lib${libsuff} /lib${libsuff}\"\n  hardcode_into_libs=yes\n  ;;\n\n# No shared lib support for Linux oldld, aout, or coff.\nlinux*oldld* | linux*aout* | linux*coff*)\n  dynamic_linker=no\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -n $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  # Some binutils ld are patched to set DT_RUNPATH\n  save_LDFLAGS=$LDFLAGS\n  save_libdir=$libdir\n  eval \"libdir=/foo; wl=\\\"$lt_prog_compiler_wl_CXX\\\"; \\\n       LDFLAGS=\\\"\\$LDFLAGS $hardcode_libdir_flag_spec_CXX\\\"\"\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_link \"$LINENO\"; then :\n  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep \"RUNPATH.*$libdir\" >/dev/null; then :\n  shlibpath_overrides_runpath=yes\nfi\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n  LDFLAGS=$save_LDFLAGS\n  libdir=$save_libdir\n\n  # This implies no fast_install, which is unacceptable.\n  # Some rework will be needed to allow for fast_install\n  # before this can be enabled.\n  hardcode_into_libs=yes\n\n  # Append ld.so.conf contents to the search path\n  if test -f /etc/ld.so.conf; then\n    lt_ld_extra=`awk '/^include / { system(sprintf(\"cd /etc; cat %s 2>/dev/null\", \\$2)); skip = 1; } { if (!skip) print \\$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[\t ]*hwcap[\t ]/d;s/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\\n' ' '`\n    sys_lib_dlsearch_path_spec=\"/lib /usr/lib $lt_ld_extra\"\n  fi\n\n  # We used to test for /lib/ld.so.1 and disable shared libraries on\n  # powerpc, because MkLinux only supported shared libraries with the\n  # GNU dynamic linker.  Since this was broken with cross compilers,\n  # most powerpc-linux boxes support dynamic linking these days and\n  # people can always --disable-shared, the test was removed, and we\n  # assume the GNU/Linux dynamic linker is in use.\n  dynamic_linker='GNU/Linux ld.so'\n  ;;\n\nnetbsdelf*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='NetBSD ld.elf_so'\n  ;;\n\nnetbsd*)\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n    finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n    dynamic_linker='NetBSD (a.out) ld.so'\n  else\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    dynamic_linker='NetBSD ld.elf_so'\n  fi\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  ;;\n\nnewsos6)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  ;;\n\n*nto* | *qnx*)\n  version_type=qnx\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='ldqnx.so'\n  ;;\n\nopenbsd*)\n  version_type=sunos\n  sys_lib_dlsearch_path_spec=\"/usr/lib\"\n  need_lib_prefix=no\n  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.\n  case $host_os in\n    openbsd3.3 | openbsd3.3.*)\tneed_version=yes ;;\n    *)\t\t\t\tneed_version=no  ;;\n  esac\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    case $host_os in\n      openbsd2.[89] | openbsd2.[89].*)\n\tshlibpath_overrides_runpath=no\n\t;;\n      *)\n\tshlibpath_overrides_runpath=yes\n\t;;\n      esac\n  else\n    shlibpath_overrides_runpath=yes\n  fi\n  ;;\n\nos2*)\n  libname_spec='$name'\n  shrext_cmds=\".dll\"\n  need_lib_prefix=no\n  library_names_spec='$libname${shared_ext} $libname.a'\n  dynamic_linker='OS/2 ld.exe'\n  shlibpath_var=LIBPATH\n  ;;\n\nosf3* | osf4* | osf5*)\n  version_type=osf\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib\"\n  sys_lib_dlsearch_path_spec=\"$sys_lib_search_path_spec\"\n  ;;\n\nrdos*)\n  dynamic_linker=no\n  ;;\n\nsolaris*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  # ldd complains unless libraries are executable\n  postinstall_cmds='chmod +x $lib'\n  ;;\n\nsunos4*)\n  version_type=sunos\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/usr/etc\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  if test \"$with_gnu_ld\" = yes; then\n    need_lib_prefix=no\n  fi\n  need_version=yes\n  ;;\n\nsysv4 | sysv4.3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_vendor in\n    sni)\n      shlibpath_overrides_runpath=no\n      need_lib_prefix=no\n      runpath_var=LD_RUN_PATH\n      ;;\n    siemens)\n      need_lib_prefix=no\n      ;;\n    motorola)\n      need_lib_prefix=no\n      need_version=no\n      shlibpath_overrides_runpath=no\n      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'\n      ;;\n  esac\n  ;;\n\nsysv4*MP*)\n  if test -d /usr/nec ;then\n    version_type=linux\n    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'\n    soname_spec='$libname${shared_ext}.$major'\n    shlibpath_var=LD_LIBRARY_PATH\n  fi\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  version_type=freebsd-elf\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  if test \"$with_gnu_ld\" = yes; then\n    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'\n  else\n    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'\n    case $host_os in\n      sco3.2v5*)\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec /lib\"\n\t;;\n    esac\n  fi\n  sys_lib_dlsearch_path_spec='/usr/lib'\n  ;;\n\ntpf*)\n  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nuts4*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\n*)\n  dynamic_linker=no\n  ;;\nesac\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $dynamic_linker\" >&5\n$as_echo \"$dynamic_linker\" >&6; }\ntest \"$dynamic_linker\" = no && can_build_shared=no\n\nvariables_saved_for_relink=\"PATH $shlibpath_var $runpath_var\"\nif test \"$GCC\" = yes; then\n  variables_saved_for_relink=\"$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH\"\nfi\n\nif test \"${lt_cv_sys_lib_search_path_spec+set}\" = set; then\n  sys_lib_search_path_spec=\"$lt_cv_sys_lib_search_path_spec\"\nfi\nif test \"${lt_cv_sys_lib_dlsearch_path_spec+set}\" = set; then\n  sys_lib_dlsearch_path_spec=\"$lt_cv_sys_lib_dlsearch_path_spec\"\nfi\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs\" >&5\n$as_echo_n \"checking how to hardcode library paths into programs... \" >&6; }\nhardcode_action_CXX=\nif test -n \"$hardcode_libdir_flag_spec_CXX\" ||\n   test -n \"$runpath_var_CXX\" ||\n   test \"X$hardcode_automatic_CXX\" = \"Xyes\" ; then\n\n  # We can hardcode non-existent directories.\n  if test \"$hardcode_direct_CXX\" != no &&\n     # If the only mechanism to avoid hardcoding is shlibpath_var, we\n     # have to relink, otherwise we might link with an installed library\n     # when we should be linking with a yet-to-be-installed one\n     ## test \"$_LT_TAGVAR(hardcode_shlibpath_var, CXX)\" != no &&\n     test \"$hardcode_minus_L_CXX\" != no; then\n    # Linking always hardcodes the temporary library directory.\n    hardcode_action_CXX=relink\n  else\n    # We can link without hardcoding, and we can hardcode nonexisting dirs.\n    hardcode_action_CXX=immediate\n  fi\nelse\n  # We cannot hardcode anything, or else we can only hardcode existing\n  # directories.\n  hardcode_action_CXX=unsupported\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX\" >&5\n$as_echo \"$hardcode_action_CXX\" >&6; }\n\nif test \"$hardcode_action_CXX\" = relink ||\n   test \"$inherit_rpath_CXX\" = yes; then\n  # Fast installation is not supported\n  enable_fast_install=no\nelif test \"$shlibpath_overrides_runpath\" = yes ||\n     test \"$enable_shared\" = no; then\n  # Fast installation is not necessary\n  enable_fast_install=needless\nfi\n\n\n\n\n\n\n\n  fi # test -n \"$compiler\"\n\n  CC=$lt_save_CC\n  LDCXX=$LD\n  LD=$lt_save_LD\n  GCC=$lt_save_GCC\n  with_gnu_ld=$lt_save_with_gnu_ld\n  lt_cv_path_LDCXX=$lt_cv_path_LD\n  lt_cv_path_LD=$lt_save_path_LD\n  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld\n  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld\nfi # test \"$_lt_caught_CXX_error\" != yes\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n\n\n\n\n\n\n\n\n\n\n        ac_config_commands=\"$ac_config_commands libtool\"\n\n\n\n\n# Only expand once:\n\n\n\n\n\nif test \"x$LIBTOOL\" != \"x\"; then\n  USE_LIBTOOL_TRUE=\n  USE_LIBTOOL_FALSE='#'\nelse\n  USE_LIBTOOL_TRUE='#'\n  USE_LIBTOOL_FALSE=\nfi\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for inline\" >&5\n$as_echo_n \"checking for inline... \" >&6; }\nif test \"${ac_cv_c_inline+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_c_inline=no\nfor ac_kw in inline __inline__ __inline; do\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifndef __cplusplus\ntypedef int foo_t;\nstatic $ac_kw foo_t static_foo () {return 0; }\n$ac_kw foo_t foo () {return 0; }\n#endif\n\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_c_inline=$ac_kw\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n  test \"$ac_cv_c_inline\" != no && break\ndone\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline\" >&5\n$as_echo \"$ac_cv_c_inline\" >&6; }\n\ncase $ac_cv_c_inline in\n  inline | yes) ;;\n  *)\n    case $ac_cv_c_inline in\n      no) ac_val=;;\n      *) ac_val=$ac_cv_c_inline;;\n    esac\n    cat >>confdefs.h <<_ACEOF\n#ifndef __cplusplus\n#define inline $ac_val\n#endif\n_ACEOF\n    ;;\nesac\n\n\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for __attribute__\" >&5\n$as_echo_n \"checking for __attribute__... \" >&6; }\n  if test \"${ac_cv___attribute__+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n       static void foo(void) __attribute__ ((unused));\n       void foo(void) { exit(1); }\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv___attribute__=yes\nelse\n  ac_cv___attribute__=no\n\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\n\n  if test \"$ac_cv___attribute__\" = \"yes\"; then\n\n$as_echo \"#define HAVE___ATTRIBUTE__ 1\" >>confdefs.h\n\n  fi\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute__\" >&5\n$as_echo \"$ac_cv___attribute__\" >&6; }\n\n\n# Check whether some low-level functions/files are available\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ANSI C header files\" >&5\n$as_echo_n \"checking for ANSI C header files... \" >&6; }\nif test \"${ac_cv_header_stdc+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <float.h>\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_header_stdc=yes\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test $ac_cv_header_stdc = yes; then\n  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <string.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"memchr\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"free\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.\n  if test \"$cross_compiling\" = yes; then :\n  :\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ctype.h>\n#include <stdlib.h>\n#if ((' ' & 0x0FF) == 0x020)\n# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')\n# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))\n#else\n# define ISLOWER(c) \\\n\t\t   (('a' <= (c) && (c) <= 'i') \\\n\t\t     || ('j' <= (c) && (c) <= 'r') \\\n\t\t     || ('s' <= (c) && (c) <= 'z'))\n# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))\n#endif\n\n#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))\nint\nmain ()\n{\n  int i;\n  for (i = 0; i < 256; i++)\n    if (XOR (islower (i), ISLOWER (i))\n\t|| toupper (i) != TOUPPER (i))\n      return 2;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc\" >&5\n$as_echo \"$ac_cv_header_stdc\" >&6; }\nif test $ac_cv_header_stdc = yes; then\n\n$as_echo \"#define STDC_HEADERS 1\" >>confdefs.h\n\nfi\n\n\n# TODO(csilvers): we could remove a lot when WITH_CPU_PROFILER etc is \"no\".\nac_fn_c_check_type \"$LINENO\" \"__int64\" \"ac_cv_type___int64\" \"$ac_includes_default\"\nif test \"x$ac_cv_type___int64\" = x\"\"yes; then :\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE___INT64 1\n_ACEOF\n\n\nfi\n       # defined in some windows platforms\nac_fn_c_check_type \"$LINENO\" \"struct mallinfo\" \"ac_cv_type_struct_mallinfo\" \"#include <malloc.h>\n\"\nif test \"x$ac_cv_type_struct_mallinfo\" = x\"\"yes; then :\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_STRUCT_MALLINFO 1\n_ACEOF\n\n\nfi\n\nac_fn_c_check_type \"$LINENO\" \"Elf32_Versym\" \"ac_cv_type_Elf32_Versym\" \"#include <elf.h>\n\"\nif test \"x$ac_cv_type_Elf32_Versym\" = x\"\"yes; then :\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_ELF32_VERSYM 1\n_ACEOF\n\n\nfi\n   # for vdso_support.h\nfor ac_func in sbrk\ndo :\n  ac_fn_c_check_func \"$LINENO\" \"sbrk\" \"ac_cv_func_sbrk\"\nif test \"x$ac_cv_func_sbrk\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SBRK 1\n_ACEOF\n\nfi\ndone\n            # for tcmalloc to get memory\nfor ac_func in geteuid\ndo :\n  ac_fn_c_check_func \"$LINENO\" \"geteuid\" \"ac_cv_func_geteuid\"\nif test \"x$ac_cv_func_geteuid\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_GETEUID 1\n_ACEOF\n\nfi\ndone\n         # for turning off services when run as root\nfor ac_header in features.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"features.h\" \"ac_cv_header_features_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_features_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_FEATURES_H 1\n_ACEOF\n\nfi\n\ndone\n    # for vdso_support.h\nfor ac_header in malloc.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"malloc.h\" \"ac_cv_header_malloc_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_malloc_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_MALLOC_H 1\n_ACEOF\n\nfi\n\ndone\n      # some systems define stuff there, others not\nfor ac_header in glob.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"glob.h\" \"ac_cv_header_glob_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_glob_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_GLOB_H 1\n_ACEOF\n\nfi\n\ndone\n        # for heap-profile-table (cleaning up profiles)\nfor ac_header in execinfo.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"execinfo.h\" \"ac_cv_header_execinfo_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_execinfo_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_EXECINFO_H 1\n_ACEOF\n\nfi\n\ndone\n    # for stacktrace? and heapchecker_unittest\nfor ac_header in libunwind.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"libunwind.h\" \"ac_cv_header_libunwind_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_libunwind_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBUNWIND_H 1\n_ACEOF\n\nfi\n\ndone\n   # for stacktrace\nfor ac_header in unwind.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"unwind.h\" \"ac_cv_header_unwind_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_unwind_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_UNWIND_H 1\n_ACEOF\n\nfi\n\ndone\n      # for stacktrace\nfor ac_header in sched.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sched.h\" \"ac_cv_header_sched_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sched_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SCHED_H 1\n_ACEOF\n\nfi\n\ndone\n       # for being nice in our spinlock code\nfor ac_header in conflict-signal.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"conflict-signal.h\" \"ac_cv_header_conflict_signal_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_conflict_signal_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_CONFLICT_SIGNAL_H 1\n_ACEOF\n\nfi\n\ndone\n      # defined on some windows platforms?\nfor ac_header in sys/prctl.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sys/prctl.h\" \"ac_cv_header_sys_prctl_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_prctl_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SYS_PRCTL_H 1\n_ACEOF\n\nfi\n\ndone\n   # for thread_lister (needed by leak-checker)\nfor ac_header in linux/ptrace.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"linux/ptrace.h\" \"ac_cv_header_linux_ptrace_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_linux_ptrace_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LINUX_PTRACE_H 1\n_ACEOF\n\nfi\n\ndone\n# also needed by leak-checker\nfor ac_header in sys/syscall.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sys/syscall.h\" \"ac_cv_header_sys_syscall_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_syscall_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SYS_SYSCALL_H 1\n_ACEOF\n\nfi\n\ndone\n\nfor ac_header in sys/socket.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sys/socket.h\" \"ac_cv_header_sys_socket_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_socket_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SYS_SOCKET_H 1\n_ACEOF\n\nfi\n\ndone\n  # optional; for forking out to symbolizer\nfor ac_header in sys/wait.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sys/wait.h\" \"ac_cv_header_sys_wait_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_wait_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SYS_WAIT_H 1\n_ACEOF\n\nfi\n\ndone\n    # optional; for forking out to symbolizer\nfor ac_header in poll.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"poll.h\" \"ac_cv_header_poll_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_poll_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_POLL_H 1\n_ACEOF\n\nfi\n\ndone\n        # optional; for forking out to symbolizer\nfor ac_header in fcntl.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"fcntl.h\" \"ac_cv_header_fcntl_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_fcntl_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_FCNTL_H 1\n_ACEOF\n\nfi\n\ndone\n       # for tcmalloc_unittest\nfor ac_header in grp.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"grp.h\" \"ac_cv_header_grp_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_grp_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_GRP_H 1\n_ACEOF\n\nfi\n\ndone\n         # for heapchecker_unittest\nfor ac_header in pwd.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"pwd.h\" \"ac_cv_header_pwd_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_pwd_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_PWD_H 1\n_ACEOF\n\nfi\n\ndone\n         # for heapchecker_unittest\nfor ac_header in sys/resource.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sys/resource.h\" \"ac_cv_header_sys_resource_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_resource_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SYS_RESOURCE_H 1\n_ACEOF\n\nfi\n\ndone\n         # for memalign_unittest.cc\nfor ac_header in valgrind.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"valgrind.h\" \"ac_cv_header_valgrind_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_valgrind_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_VALGRIND_H 1\n_ACEOF\n\nfi\n\ndone\n    # we have a local copy if this isn't found\n# We also need <ucontext.h>/<sys/ucontext.h>, but we get those from\n# AC_PC_FROM_UCONTEXT, below.\n\n# We override a lot of memory allocation routines, not all of which are\n# standard.  For those the system doesn't declare, we'll declare ourselves.\nac_fn_c_check_decl \"$LINENO\" \"cfree\" \"ac_cv_have_decl_cfree\" \"#define _XOPEN_SOURCE 600\n                #include <stdlib.h>\n                #include <malloc.h>\n\"\nif test \"x$ac_cv_have_decl_cfree\" = x\"\"yes; then :\n  ac_have_decl=1\nelse\n  ac_have_decl=0\nfi\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_DECL_CFREE $ac_have_decl\n_ACEOF\nac_fn_c_check_decl \"$LINENO\" \"posix_memalign\" \"ac_cv_have_decl_posix_memalign\" \"#define _XOPEN_SOURCE 600\n                #include <stdlib.h>\n                #include <malloc.h>\n\"\nif test \"x$ac_cv_have_decl_posix_memalign\" = x\"\"yes; then :\n  ac_have_decl=1\nelse\n  ac_have_decl=0\nfi\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_DECL_POSIX_MEMALIGN $ac_have_decl\n_ACEOF\nac_fn_c_check_decl \"$LINENO\" \"memalign\" \"ac_cv_have_decl_memalign\" \"#define _XOPEN_SOURCE 600\n                #include <stdlib.h>\n                #include <malloc.h>\n\"\nif test \"x$ac_cv_have_decl_memalign\" = x\"\"yes; then :\n  ac_have_decl=1\nelse\n  ac_have_decl=0\nfi\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_DECL_MEMALIGN $ac_have_decl\n_ACEOF\nac_fn_c_check_decl \"$LINENO\" \"valloc\" \"ac_cv_have_decl_valloc\" \"#define _XOPEN_SOURCE 600\n                #include <stdlib.h>\n                #include <malloc.h>\n\"\nif test \"x$ac_cv_have_decl_valloc\" = x\"\"yes; then :\n  ac_have_decl=1\nelse\n  ac_have_decl=0\nfi\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_DECL_VALLOC $ac_have_decl\n_ACEOF\nac_fn_c_check_decl \"$LINENO\" \"pvalloc\" \"ac_cv_have_decl_pvalloc\" \"#define _XOPEN_SOURCE 600\n                #include <stdlib.h>\n                #include <malloc.h>\n\"\nif test \"x$ac_cv_have_decl_pvalloc\" = x\"\"yes; then :\n  ac_have_decl=1\nelse\n  ac_have_decl=0\nfi\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_DECL_PVALLOC $ac_have_decl\n_ACEOF\n\n\nif test \"$ac_cv_type_struct_mallinfo\" = yes; then\n  ac_cv_have_struct_mallinfo=1\n   # google/tcmalloc.h needs this\nelse\n  ac_cv_have_struct_mallinfo=0\n\nfi\n\n# We need to check for mmap.  cygwin supports mmap, but the autoconf\n# test doesn't work on cygwin:\n#    http://www.cygwin.com/ml/cygwin/2002-04/msg00412.html\n# This workaround comes from\n#    http://cygwin.com/ml/cygwin/2004-11/msg00138.html\ncase \"$host\" in\n  *-*-cygwin*) ac_cv_func_mmap_fixed_mapped=yes\n\n$as_echo \"#define HAVE_MMAP 1\" >>confdefs.h\n\n               ;;\n            *)\n\n\n  for ac_header in $ac_header_list\ndo :\n  as_ac_Header=`$as_echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nac_fn_c_check_header_compile \"$LINENO\" \"$ac_header\" \"$as_ac_Header\" \"$ac_includes_default\n\"\neval as_val=\\$$as_ac_Header\n   if test \"x$as_val\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define `$as_echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\n\n\n\n\n\n\nfor ac_func in getpagesize\ndo :\n  ac_fn_c_check_func \"$LINENO\" \"getpagesize\" \"ac_cv_func_getpagesize\"\nif test \"x$ac_cv_func_getpagesize\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_GETPAGESIZE 1\n_ACEOF\n\nfi\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for working mmap\" >&5\n$as_echo_n \"checking for working mmap... \" >&6; }\nif test \"${ac_cv_func_mmap_fixed_mapped+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test \"$cross_compiling\" = yes; then :\n  ac_cv_func_mmap_fixed_mapped=no\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$ac_includes_default\n/* malloc might have been renamed as rpl_malloc. */\n#undef malloc\n\n/* Thanks to Mike Haertel and Jim Avera for this test.\n   Here is a matrix of mmap possibilities:\n\tmmap private not fixed\n\tmmap private fixed at somewhere currently unmapped\n\tmmap private fixed at somewhere already mapped\n\tmmap shared not fixed\n\tmmap shared fixed at somewhere currently unmapped\n\tmmap shared fixed at somewhere already mapped\n   For private mappings, we should verify that changes cannot be read()\n   back from the file, nor mmap's back from the file at a different\n   address.  (There have been systems where private was not correctly\n   implemented like the infamous i386 svr4.0, and systems where the\n   VM page cache was not coherent with the file system buffer cache\n   like early versions of FreeBSD and possibly contemporary NetBSD.)\n   For shared mappings, we should conversely verify that changes get\n   propagated back to all the places they're supposed to be.\n\n   Grep wants private fixed already mapped.\n   The main things grep needs to know about mmap are:\n   * does it exist and is it safe to write into the mmap'd area\n   * how to use it (BSD variants)  */\n\n#include <fcntl.h>\n#include <sys/mman.h>\n\n#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H\nchar *malloc ();\n#endif\n\n/* This mess was copied from the GNU getpagesize.h.  */\n#ifndef HAVE_GETPAGESIZE\n# ifdef _SC_PAGESIZE\n#  define getpagesize() sysconf(_SC_PAGESIZE)\n# else /* no _SC_PAGESIZE */\n#  ifdef HAVE_SYS_PARAM_H\n#   include <sys/param.h>\n#   ifdef EXEC_PAGESIZE\n#    define getpagesize() EXEC_PAGESIZE\n#   else /* no EXEC_PAGESIZE */\n#    ifdef NBPG\n#     define getpagesize() NBPG * CLSIZE\n#     ifndef CLSIZE\n#      define CLSIZE 1\n#     endif /* no CLSIZE */\n#    else /* no NBPG */\n#     ifdef NBPC\n#      define getpagesize() NBPC\n#     else /* no NBPC */\n#      ifdef PAGESIZE\n#       define getpagesize() PAGESIZE\n#      endif /* PAGESIZE */\n#     endif /* no NBPC */\n#    endif /* no NBPG */\n#   endif /* no EXEC_PAGESIZE */\n#  else /* no HAVE_SYS_PARAM_H */\n#   define getpagesize() 8192\t/* punt totally */\n#  endif /* no HAVE_SYS_PARAM_H */\n# endif /* no _SC_PAGESIZE */\n\n#endif /* no HAVE_GETPAGESIZE */\n\nint\nmain ()\n{\n  char *data, *data2, *data3;\n  const char *cdata2;\n  int i, pagesize;\n  int fd, fd2;\n\n  pagesize = getpagesize ();\n\n  /* First, make a file with some known garbage in it. */\n  data = (char *) malloc (pagesize);\n  if (!data)\n    return 1;\n  for (i = 0; i < pagesize; ++i)\n    *(data + i) = rand ();\n  umask (0);\n  fd = creat (\"conftest.mmap\", 0600);\n  if (fd < 0)\n    return 2;\n  if (write (fd, data, pagesize) != pagesize)\n    return 3;\n  close (fd);\n\n  /* Next, check that the tail of a page is zero-filled.  File must have\n     non-zero length, otherwise we risk SIGBUS for entire page.  */\n  fd2 = open (\"conftest.txt\", O_RDWR | O_CREAT | O_TRUNC, 0600);\n  if (fd2 < 0)\n    return 4;\n  cdata2 = \"\";\n  if (write (fd2, cdata2, 1) != 1)\n    return 5;\n  data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L);\n  if (data2 == MAP_FAILED)\n    return 6;\n  for (i = 0; i < pagesize; ++i)\n    if (*(data2 + i))\n      return 7;\n  close (fd2);\n  if (munmap (data2, pagesize))\n    return 8;\n\n  /* Next, try to mmap the file at a fixed address which already has\n     something else allocated at it.  If we can, also make sure that\n     we see the same garbage.  */\n  fd = open (\"conftest.mmap\", O_RDWR);\n  if (fd < 0)\n    return 9;\n  if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,\n\t\t     MAP_PRIVATE | MAP_FIXED, fd, 0L))\n    return 10;\n  for (i = 0; i < pagesize; ++i)\n    if (*(data + i) != *(data2 + i))\n      return 11;\n\n  /* Finally, make sure that changes to the mapped area do not\n     percolate back to the file as seen by read().  (This is a bug on\n     some variants of i386 svr4.0.)  */\n  for (i = 0; i < pagesize; ++i)\n    *(data2 + i) = *(data2 + i) + 1;\n  data3 = (char *) malloc (pagesize);\n  if (!data3)\n    return 12;\n  if (read (fd, data3, pagesize) != pagesize)\n    return 13;\n  for (i = 0; i < pagesize; ++i)\n    if (*(data + i) != *(data3 + i))\n      return 14;\n  close (fd);\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n  ac_cv_func_mmap_fixed_mapped=yes\nelse\n  ac_cv_func_mmap_fixed_mapped=no\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped\" >&5\n$as_echo \"$ac_cv_func_mmap_fixed_mapped\" >&6; }\nif test $ac_cv_func_mmap_fixed_mapped = yes; then\n\n$as_echo \"#define HAVE_MMAP 1\" >>confdefs.h\n\nfi\nrm -f conftest.mmap conftest.txt\n\n               ;;\nesac\n\n# If AtomicWord != Atomic32, we need to define two versions of all the\n# atomicops functions.  If they're the same, we want to define only one.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking if int32_t is the same type as intptr_t\" >&5\n$as_echo_n \"checking if int32_t is the same type as intptr_t... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdint.h>\nint\nmain ()\n{\nint32_t v1 = 0; intptr_t v2 = 0; return (&v1 - &v2)\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\n$as_echo \"#define INT32_EQUALS_INTPTR 1\" >>confdefs.h\n\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n# We want to access the \"PC\" (Program Counter) register from a struct\n# ucontext.  Every system has its own way of doing that.  We try all the\n# possibilities we know about.  Note REG_PC should come first (REG_RIP\n# is also defined on solaris, but does the wrong thing).  But don't\n# bother if we're not doing cpu-profiling.\n# [*] means that we've not actually tested one of these systems\nif test \"$enable_cpu_profiler\" = yes; then\n  for ac_header in ucontext.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"ucontext.h\" \"ac_cv_header_ucontext_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_ucontext_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_UCONTEXT_H 1\n_ACEOF\n\nfi\n\ndone\n\n   # Redhat 7 has <sys/ucontext.h>, but it barfs if we #include it directly\n   # (this was fixed in later redhats).  <ucontext.h> works fine, so use that.\n   if grep \"Red Hat Linux release 7\" /etc/redhat-release >/dev/null 2>&1; then\n\n$as_echo \"#define HAVE_SYS_UCONTEXT_H 0\" >>confdefs.h\n\n     ac_cv_header_sys_ucontext_h=no\n   else\n     for ac_header in sys/ucontext.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"sys/ucontext.h\" \"ac_cv_header_sys_ucontext_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_sys_ucontext_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_SYS_UCONTEXT_H 1\n_ACEOF\n\nfi\n\ndone\n       # ucontext on OS X 10.6 (at least)\n   fi\n   for ac_header in cygwin/signal.h\ndo :\n  ac_fn_c_check_header_mongrel \"$LINENO\" \"cygwin/signal.h\" \"ac_cv_header_cygwin_signal_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_cygwin_signal_h\" = x\"\"yes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_CYGWIN_SIGNAL_H 1\n_ACEOF\n\nfi\n\ndone\n        # ucontext on cywgin\n   { $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to access the program counter from a struct ucontext\" >&5\n$as_echo_n \"checking how to access the program counter from a struct ucontext... \" >&6; }\n   pc_fields=\"           uc_mcontext.gregs[REG_PC]\"  # Solaris x86 (32 + 64 bit)\n   pc_fields=\"$pc_fields uc_mcontext.gregs[REG_EIP]\" # Linux (i386)\n   pc_fields=\"$pc_fields uc_mcontext.gregs[REG_RIP]\" # Linux (x86_64)\n   pc_fields=\"$pc_fields uc_mcontext.sc_ip\"            # Linux (ia64)\n   pc_fields=\"$pc_fields uc_mcontext.uc_regs->gregs[PT_NIP]\" # Linux (ppc)\n   pc_fields=\"$pc_fields uc_mcontext.gregs[R15]\"     # Linux (arm old [untested])\n   pc_fields=\"$pc_fields uc_mcontext.arm_pc\"           # Linux (arm arch 5)\n   pc_fields=\"$pc_fields uc_mcontext.gp_regs[PT_NIP]\"  # Suse SLES 11 (ppc64)\n   pc_fields=\"$pc_fields uc_mcontext.mc_eip\"           # FreeBSD (i386)\n   pc_fields=\"$pc_fields uc_mcontext.mc_rip\"           # FreeBSD (x86_64 [untested])\n   pc_fields=\"$pc_fields uc_mcontext.__gregs[_REG_EIP]\"  # NetBSD (i386)\n   pc_fields=\"$pc_fields uc_mcontext.__gregs[_REG_RIP]\"  # NetBSD (x86_64)\n   pc_fields=\"$pc_fields uc_mcontext->ss.eip\"          # OS X (i386, <=10.4)\n   pc_fields=\"$pc_fields uc_mcontext->__ss.__eip\"      # OS X (i386, >=10.5)\n   pc_fields=\"$pc_fields uc_mcontext->ss.rip\"          # OS X (x86_64)\n   pc_fields=\"$pc_fields uc_mcontext->__ss.__rip\"      # OS X (>=10.5 [untested])\n   pc_fields=\"$pc_fields uc_mcontext->ss.srr0\"         # OS X (ppc, ppc64 [untested])\n   pc_fields=\"$pc_fields uc_mcontext->__ss.__srr0\"     # OS X (>=10.5 [untested])\n   pc_field_found=false\n   for pc_field in $pc_fields; do\n     if ! $pc_field_found; then\n       # Prefer sys/ucontext.h to ucontext.h, for OS X's sake.\n       if test \"x$ac_cv_header_cygwin_signal_h\" = xyes; then\n         cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#define _GNU_SOURCE 1\n                         #include <cygwin/signal.h>\nint\nmain ()\n{\nucontext_t u; return u.$pc_field == 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\ncat >>confdefs.h <<_ACEOF\n#define PC_FROM_UCONTEXT $pc_field\n_ACEOF\n\n                        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $pc_field\" >&5\n$as_echo \"$pc_field\" >&6; }\n                        pc_field_found=true\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n       elif test \"x$ac_cv_header_sys_ucontext_h\" = xyes; then\n         cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#define _GNU_SOURCE 1\n                         #include <sys/ucontext.h>\nint\nmain ()\n{\nucontext_t u; return u.$pc_field == 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\ncat >>confdefs.h <<_ACEOF\n#define PC_FROM_UCONTEXT $pc_field\n_ACEOF\n\n                        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $pc_field\" >&5\n$as_echo \"$pc_field\" >&6; }\n                        pc_field_found=true\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n       elif test \"x$ac_cv_header_ucontext_h\" = xyes; then\n         cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#define _GNU_SOURCE 1\n                         #include <ucontext.h>\nint\nmain ()\n{\nucontext_t u; return u.$pc_field == 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\ncat >>confdefs.h <<_ACEOF\n#define PC_FROM_UCONTEXT $pc_field\n_ACEOF\n\n                        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $pc_field\" >&5\n$as_echo \"$pc_field\" >&6; }\n                        pc_field_found=true\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n       else     # hope some standard header gives it to us\n         cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\nucontext_t u; return u.$pc_field == 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\ncat >>confdefs.h <<_ACEOF\n#define PC_FROM_UCONTEXT $pc_field\n_ACEOF\n\n                        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $pc_field\" >&5\n$as_echo \"$pc_field\" >&6; }\n                        pc_field_found=true\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n       fi\n     fi\n   done\n   if ! $pc_field_found; then\n     pc_fields=\"           sc_eip\"  # OpenBSD (i386)\n     pc_fields=\"$pc_fields sc_rip\"  # OpenBSD (x86_64)\n     for pc_field in $pc_fields; do\n       if ! $pc_field_found; then\n         cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <signal.h>\nint\nmain ()\n{\nucontext_t u; return u.$pc_field == 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\ncat >>confdefs.h <<_ACEOF\n#define PC_FROM_UCONTEXT $pc_field\n_ACEOF\n\n                        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $pc_field\" >&5\n$as_echo \"$pc_field\" >&6; }\n                        pc_field_found=true\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n       fi\n     done\n   fi\n   if ! $pc_field_found; then\n     { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: Could not find the PC.  Will not try to compile libprofiler...\" >&5\n$as_echo \"$as_me: WARNING: Could not find the PC.  Will not try to compile libprofiler...\" >&2;};\n                      enable_cpu_profiler=no\n   fi\nfi\n\n# Some tests test the behavior of .so files, and only make sense for dynamic.\n\n\nif test \"$enable_static\" = yes; then\n  ENABLE_STATIC_TRUE=\n  ENABLE_STATIC_FALSE='#'\nelse\n  ENABLE_STATIC_TRUE='#'\n  ENABLE_STATIC_FALSE=\nfi\n\n\n# We want to link in libunwind if it exists\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for backtrace in -lunwind\" >&5\n$as_echo_n \"checking for backtrace in -lunwind... \" >&6; }\nif test \"${ac_cv_lib_unwind_backtrace+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lunwind  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar backtrace ();\nint\nmain ()\n{\nreturn backtrace ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_unwind_backtrace=yes\nelse\n  ac_cv_lib_unwind_backtrace=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unwind_backtrace\" >&5\n$as_echo \"$ac_cv_lib_unwind_backtrace\" >&6; }\nif test \"x$ac_cv_lib_unwind_backtrace\" = x\"\"yes; then :\n  UNWIND_LIBS=-lunwind\nelse\n  UNWIND_LIBS=\nfi\n\n\n\n# On x86_64, instead of libunwind, we can choose to compile with frame-pointers\n# (This isn't needed on i386, where -fno-omit-frame-pointer is the default).\n# Check whether --enable-frame_pointers was given.\nif test \"${enable_frame_pointers+set}\" = set; then :\n  enableval=$enable_frame_pointers;\nelse\n  enable_frame_pointers=no\nfi\n\n\n\nif test \"$enable_frame_pointers\" = yes; then\n  ENABLE_FRAME_POINTERS_TRUE=\n  ENABLE_FRAME_POINTERS_FALSE='#'\nelse\n  ENABLE_FRAME_POINTERS_TRUE='#'\n  ENABLE_FRAME_POINTERS_FALSE=\nfi\n\n\n# Some x86_64 systems do not insert frame pointers by default (all\n# i386 systems that I know of, do.  I don't know about non-x86 chips).\n# We want to see if the current system is one of those.\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\nreturn __x86_64__ == 1 ? 0 : 1\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  is_x86_64=yes\nelse\n  is_x86_64=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nOLD_CFLAGS=\"$CFLAGS\"\nCFLAGS=\"$CFLAGS -S -O2 -o fp.s\"\n# This test will always fail because we don't name our output file properly.\n# We do our own determination of success/failure in the grep, below.\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nint f(int x) {return x;}\nint\nmain ()\n{\nreturn f(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  :\nelse\n  :\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\n\nif test \"$is_x86_64\" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1; then\n  X86_64_AND_NO_FP_BY_DEFAULT_TRUE=\n  X86_64_AND_NO_FP_BY_DEFAULT_FALSE='#'\nelse\n  X86_64_AND_NO_FP_BY_DEFAULT_TRUE='#'\n  X86_64_AND_NO_FP_BY_DEFAULT_FALSE=\nfi\n\nrm fp.s\nCFLAGS=\"$OLD_CFLAGS\"\n\n\n# Defines PRIuS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking printf format code for printing a size_t and ssize_t\" >&5\n$as_echo_n \"checking printf format code for printing a size_t and ssize_t... \" >&6; }\nif test \"${ac_cv_formatting_prius_prefix+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stddef.h>\nint\nmain ()\n{\nunsigned int v1 = 0; size_t v2 = 0; return (&v1 - &v2)\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_formatting_prius_prefix=; ac_cv_prius_defined=1\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n     cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stddef.h>\nint\nmain ()\n{\nunsigned long v1 = 0; size_t v2 = 0; return (&v1 - &v2)\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_formatting_prius_prefix=l; ac_cv_prius_defined=1\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n     cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stddef.h>\nint\nmain ()\n{\nunsigned long long v1 = 0; size_t v2 = 0; return (&v1 - &v2)\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_formatting_prius_prefix=ll; ac_cv_prius_defined=1\n\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_formatting_prius_prefix\" >&5\n$as_echo \"$ac_cv_formatting_prius_prefix\" >&6; }\n   if test -z \"$ac_cv_prius_defined\"; then\n      ac_cv_formatting_prius_prefix=z;\n   fi\n\ncat >>confdefs.h <<_ACEOF\n#define PRIuS \"${ac_cv_formatting_prius_prefix}u\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define PRIxS \"${ac_cv_formatting_prius_prefix}x\"\n_ACEOF\n\n\ncat >>confdefs.h <<_ACEOF\n#define PRIdS \"${ac_cv_formatting_prius_prefix}d\"\n_ACEOF\n\n\n\n# Also make sure we get standard PRI... definitions, even with glibc.\n# We have to use AH_VERBATIM because we need the #ifdef guard (gcc buglet)\n\n\n# Check if __builtin_stack_pointer() is available (for elfcore.h)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for __builtin_stack_pointer()\" >&5\n$as_echo_n \"checking for __builtin_stack_pointer()... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\nvoid *sp = __builtin_stack_pointer()\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\n$as_echo \"#define HAVE_BUILTIN_STACK_POINTER 1\" >>confdefs.h\n\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n# Check if __environ is available (for GetenvBeforeMain)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for __environ\" >&5\n$as_echo_n \"checking for __environ... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <unistd.h>\nint\nmain ()\n{\nchar **env = __environ\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\n$as_echo \"#define HAVE___ENVIRON 1\" >>confdefs.h\n\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n# If we support __thread, that can speed up tcmalloc a bit.\n# Note, however, that our code tickles a bug in gcc < 4.1.2\n# involving TLS and -fPIC (which our libraries will use) on x86:\n#   http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for __thread\" >&5\n$as_echo_n \"checking for __thread... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))\n#error gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html\n#endif\nint\nmain ()\n{\nstatic __thread int p = 0\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\n$as_echo \"#define HAVE_TLS 1\" >>confdefs.h\n\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n# Nanosleep requires extra libraries on some architectures (solaris).\n# This sets NANOSLEEP_LIBS.  nanosleep doesn't exist on mingw, which\n# is fine for us because we don't compile libspinlock, which uses it.\nif test \"$need_nanosleep\" = yes; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if nanosleep requires any libraries\" >&5\n$as_echo_n \"checking if nanosleep requires any libraries... \" >&6; }\n\n ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n acx_nanosleep_ok=\"no\"\n NANOSLEEP_LIBS=\n # For most folks, this should just work\n cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <time.h>\nint\nmain ()\n{\nstatic struct timespec ts; nanosleep(&ts, NULL);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  acx_nanosleep_ok=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n # For solaris, we may  need -lrt\n if test \"x$acx_nanosleep_ok\" != \"xyes\"; then\n   OLD_LIBS=\"$LIBS\"\n   LIBS=\"-lrt $LIBS\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <time.h>\nint\nmain ()\n{\nstatic struct timespec ts; nanosleep(&ts, NULL);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  acx_nanosleep_ok=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n   if test \"x$acx_nanosleep_ok\" = \"xyes\"; then\n     NANOSLEEP_LIBS=\"-lrt\"\n   fi\n   LIBS=\"$OLD_LIBS\"\n fi\n if test \"x$acx_nanosleep_ok\" != \"xyes\"; then\n   as_fn_error \"cannot find the nanosleep function\" \"$LINENO\" 5\n else\n   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ${NANOSLEEP_LIBS:-no}\" >&5\n$as_echo \"${NANOSLEEP_LIBS:-no}\" >&6; }\n fi\n ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\nfi\n\n# Solaris 10 6/06 has a bug where /usr/sfw/lib/libstdc++.la is empty.\n# If so, we replace it with our own version.\nLIBSTDCXX_LA_LINKER_FLAG=\nif test -f /usr/sfw/lib/libstdc++.la && ! test -s /usr/sfw/lib/libstdc++.la\nthen\n  LIBSTDCXX_LA_LINKER_FLAG='-L$(top_srcdir)/src/solaris'\nfi\n\n\n# We also need to check if the kernel supports __thread, which requires uname()\nac_fn_c_check_decl \"$LINENO\" \"uname\" \"ac_cv_have_decl_uname\" \"#include <sys/utsname.h>\n\"\nif test \"x$ac_cv_have_decl_uname\" = x\"\"yes; then :\n  ac_have_decl=1\nelse\n  ac_have_decl=0\nfi\n\ncat >>confdefs.h <<_ACEOF\n#define HAVE_DECL_UNAME $ac_have_decl\n_ACEOF\n\n\n# In fact, a lot of the code in this directory depends on pthreads\n\n\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nacx_pthread_ok=no\n\n# We used to check for pthread.h first, but this fails if pthread.h\n# requires special compiler flags (e.g. on True64 or Sequent).\n# It gets checked for in the link test anyway.\n\n# First of all, check if the user has set any of the PTHREAD_LIBS,\n# etcetera environment variables, and if threads linking works using\n# them:\nif test x\"$PTHREAD_LIBS$PTHREAD_CFLAGS\" != x; then\n        save_CFLAGS=\"$CFLAGS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n        save_LIBS=\"$LIBS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS\" >&5\n$as_echo_n \"checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... \" >&6; }\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n/* Override any GCC internal prototype to avoid an error.\n   Use char because int might match the return type of a GCC\n   builtin and then its argument prototype would still apply.  */\n#ifdef __cplusplus\nextern \"C\"\n#endif\nchar pthread_join ();\nint\nmain ()\n{\nreturn pthread_join ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  acx_pthread_ok=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok\" >&5\n$as_echo \"$acx_pthread_ok\" >&6; }\n        if test x\"$acx_pthread_ok\" = xno; then\n                PTHREAD_LIBS=\"\"\n                PTHREAD_CFLAGS=\"\"\n        fi\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\nfi\n\n# We must check for the threads library under a number of different\n# names; the ordering is very important because some systems\n# (e.g. DEC) have both -lpthread and -lpthreads, where one of the\n# libraries is broken (non-POSIX).\n\n# Create a list of thread flags to try.  Items starting with a \"-\" are\n# C compiler flags, and other items are library names, except for \"none\"\n# which indicates that we try without any flags at all, and \"pthread-config\"\n# which is a program returning the flags for the Pth emulation library.\n\nacx_pthread_flags=\"pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config\"\n\n# The ordering *is* (sometimes) important.  Some notes on the\n# individual items follow:\n\n# pthreads: AIX (must check this before -lpthread)\n# none: in case threads are in libc; should be tried before -Kthread and\n#       other compiler flags to prevent continual compiler warnings\n# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)\n# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)\n# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)\n# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)\n# -pthreads: Solaris/gcc\n# -mthreads: Mingw32/gcc, Lynx/gcc\n# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it\n#      doesn't hurt to check since this sometimes defines pthreads too;\n#      also defines -D_REENTRANT)\n#      ... -mt is also the pthreads flag for HP/aCC\n# pthread: Linux, etcetera\n# --thread-safe: KAI C++\n# pthread-config: use pthread-config program (for GNU Pth library)\n\ncase \"${host_cpu}-${host_os}\" in\n        *solaris*)\n\n        # On Solaris (at least, for some versions), libc contains stubbed\n        # (non-functional) versions of the pthreads routines, so link-based\n        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/\n        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather\n        # a function called by this macro, so we could check for that, but\n        # who knows whether they'll stub that too in a future libc.)  So,\n        # we'll just look for -pthreads and -lpthread first:\n\n        acx_pthread_flags=\"-pthreads pthread -mt -pthread $acx_pthread_flags\"\n        ;;\nesac\n\nif test x\"$acx_pthread_ok\" = xno; then\nfor flag in $acx_pthread_flags; do\n\n        case $flag in\n                none)\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags\" >&5\n$as_echo_n \"checking whether pthreads work without any flags... \" >&6; }\n                ;;\n\n                -*)\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag\" >&5\n$as_echo_n \"checking whether pthreads work with $flag... \" >&6; }\n                PTHREAD_CFLAGS=\"$flag\"\n                ;;\n\n\t\tpthread-config)\n\t\t# Extract the first word of \"pthread-config\", so it can be a program name with args.\nset dummy pthread-config; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_acx_pthread_config+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$acx_pthread_config\"; then\n  ac_cv_prog_acx_pthread_config=\"$acx_pthread_config\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_acx_pthread_config=\"yes\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\n  test -z \"$ac_cv_prog_acx_pthread_config\" && ac_cv_prog_acx_pthread_config=\"no\"\nfi\nfi\nacx_pthread_config=$ac_cv_prog_acx_pthread_config\nif test -n \"$acx_pthread_config\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config\" >&5\n$as_echo \"$acx_pthread_config\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n\t\tif test x\"$acx_pthread_config\" = xno; then continue; fi\n\t\tPTHREAD_CFLAGS=\"`pthread-config --cflags`\"\n\t\tPTHREAD_LIBS=\"`pthread-config --ldflags` `pthread-config --libs`\"\n\t\t;;\n\n                *)\n                { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag\" >&5\n$as_echo_n \"checking for the pthreads library -l$flag... \" >&6; }\n                PTHREAD_LIBS=\"-l$flag\"\n                ;;\n        esac\n\n        save_LIBS=\"$LIBS\"\n        save_CFLAGS=\"$CFLAGS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n\n        # Check for various functions.  We must include pthread.h,\n        # since some functions may be macros.  (On the Sequent, we\n        # need a special flag -Kthread to make this header compile.)\n        # We check for pthread_join because it is in -lpthread on IRIX\n        # while pthread_create is in libc.  We check for pthread_attr_init\n        # due to DEC craziness with -lpthreads.  We check for\n        # pthread_cleanup_push because it is one of the few pthread\n        # functions on Solaris that doesn't have a non-functional libc stub.\n        # We try pthread_create on general principles.\n        cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_t th; pthread_join(th, 0);\n                     pthread_attr_init(0); pthread_cleanup_push(0, 0);\n                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  acx_pthread_ok=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\n\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok\" >&5\n$as_echo \"$acx_pthread_ok\" >&6; }\n        if test \"x$acx_pthread_ok\" = xyes; then\n                break;\n        fi\n\n        PTHREAD_LIBS=\"\"\n        PTHREAD_CFLAGS=\"\"\ndone\nfi\n\n# Various other checks:\nif test \"x$acx_pthread_ok\" = xyes; then\n        save_LIBS=\"$LIBS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        save_CFLAGS=\"$CFLAGS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n\n        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute\" >&5\n$as_echo_n \"checking for joinable pthread attribute... \" >&6; }\n\tattr_name=unknown\n\tfor attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do\n\t    cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\nint attr=$attr; return attr;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  attr_name=$attr; break\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\tdone\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $attr_name\" >&5\n$as_echo \"$attr_name\" >&6; }\n        if test \"$attr_name\" != PTHREAD_CREATE_JOINABLE; then\n\ncat >>confdefs.h <<_ACEOF\n#define PTHREAD_CREATE_JOINABLE $attr_name\n_ACEOF\n\n        fi\n\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads\" >&5\n$as_echo_n \"checking if more special flags are required for pthreads... \" >&6; }\n        flag=no\n        case \"${host_cpu}-${host_os}\" in\n            *-aix* | *-freebsd* | *-darwin*) flag=\"-D_THREAD_SAFE\";;\n            *solaris* | *-osf* | *-hpux*) flag=\"-D_REENTRANT\";;\n        esac\n        { $as_echo \"$as_me:${as_lineno-$LINENO}: result: ${flag}\" >&5\n$as_echo \"${flag}\" >&6; }\n        if test \"x$flag\" != xno; then\n            PTHREAD_CFLAGS=\"$flag $PTHREAD_CFLAGS\"\n        fi\n\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\n        # More AIX lossage: must compile with xlc_r or cc_r\n\tif test x\"$GCC\" != xyes; then\n          for ac_prog in xlc_r cc_r\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif test \"${ac_cv_prog_PTHREAD_CC+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$PTHREAD_CC\"; then\n  ac_cv_prog_PTHREAD_CC=\"$PTHREAD_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if { test -f \"$as_dir/$ac_word$ac_exec_ext\" && $as_test_x \"$as_dir/$ac_word$ac_exec_ext\"; }; then\n    ac_cv_prog_PTHREAD_CC=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nPTHREAD_CC=$ac_cv_prog_PTHREAD_CC\nif test -n \"$PTHREAD_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC\" >&5\n$as_echo \"$PTHREAD_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$PTHREAD_CC\" && break\ndone\ntest -n \"$PTHREAD_CC\" || PTHREAD_CC=\"${CC}\"\n\n        else\n          PTHREAD_CC=$CC\n\tfi\n\n\t# The next part tries to detect GCC inconsistency with -shared on some\n\t# architectures and systems. The problem is that in certain\n\t# configurations, when -shared is specified, GCC \"forgets\" to\n\t# internally use various flags which are still necessary.\n\n\t#\n\t# Prepare the flags\n\t#\n\tsave_CFLAGS=\"$CFLAGS\"\n\tsave_LIBS=\"$LIBS\"\n\tsave_CC=\"$CC\"\n\n\t# Try with the flags determined by the earlier checks.\n\t#\n\t# -Wl,-z,defs forces link-time symbol resolution, so that the\n\t# linking checks with -shared actually have any value\n\t#\n\t# FIXME: -fPIC is required for -shared on many architectures,\n\t# so we specify it here, but the right way would probably be to\n\t# properly detect whether it is actually required.\n\tCFLAGS=\"-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS\"\n\tLIBS=\"$PTHREAD_LIBS $LIBS\"\n\tCC=\"$PTHREAD_CC\"\n\n\t# In order not to create several levels of indentation, we test\n\t# the value of \"$done\" until we find the cure or run out of ideas.\n\tdone=\"no\"\n\n\t# First, make sure the CFLAGS we added are actually accepted by our\n\t# compiler.  If not (and OS X's ld, for instance, does not accept -z),\n\t# then we can't do this test.\n\tif test x\"$done\" = xno; then\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether to check for GCC pthread/shared inconsistencies\" >&5\n$as_echo_n \"checking whether to check for GCC pthread/shared inconsistencies... \" >&6; }\n\t   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n\nelse\n  done=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\t   if test \"x$done\" = xyes ; then\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\t   else\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t   fi\n\tfi\n\n\tif test x\"$done\" = xno; then\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -pthread is sufficient with -shared\" >&5\n$as_echo_n \"checking whether -pthread is sufficient with -shared... \" >&6; }\n\t   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_t th; pthread_join(th, 0);\n\t      pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t      pthread_create(0,0,0,0); pthread_cleanup_pop(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  done=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\t   if test \"x$done\" = xyes; then\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t   else\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\t   fi\n\tfi\n\n\t#\n\t# Linux gcc on some architectures such as mips/mipsel forgets\n\t# about -lpthread\n\t#\n\tif test x\"$done\" = xno; then\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lpthread fixes that\" >&5\n$as_echo_n \"checking whether -lpthread fixes that... \" >&6; }\n\t   LIBS=\"-lpthread $PTHREAD_LIBS $save_LIBS\"\n\t   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_t th; pthread_join(th, 0);\n\t      pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t      pthread_create(0,0,0,0); pthread_cleanup_pop(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  done=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\t   if test \"x$done\" = xyes; then\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t      PTHREAD_LIBS=\"-lpthread $PTHREAD_LIBS\"\n\t   else\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\t   fi\n\tfi\n\t#\n\t# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc\n\t#\n\tif test x\"$done\" = xno; then\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lc_r fixes that\" >&5\n$as_echo_n \"checking whether -lc_r fixes that... \" >&6; }\n\t   LIBS=\"-lc_r $PTHREAD_LIBS $save_LIBS\"\n\t   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_t th; pthread_join(th, 0);\n\t        pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t        pthread_create(0,0,0,0); pthread_cleanup_pop(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  done=yes\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\t   if test \"x$done\" = xyes; then\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t      PTHREAD_LIBS=\"-lc_r $PTHREAD_LIBS\"\n\t   else\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\t   fi\n\tfi\n\tif test x\"$done\" = xno; then\n\t   # OK, we have run out of ideas\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries\" >&5\n$as_echo \"$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries\" >&2;}\n\n\t   # so it's not safe to assume that we may use pthreads\n\t   acx_pthread_ok=no\n\tfi\n\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether what we have so far is sufficient with -nostdlib\" >&5\n$as_echo_n \"checking whether what we have so far is sufficient with -nostdlib... \" >&6; }\n\tCFLAGS=\"-nostdlib $CFLAGS\"\n\t# we need c with nostdlib\n\tLIBS=\"$LIBS -lc\"\n\tcat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_t th; pthread_join(th, 0);\n\t       pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t       pthread_create(0,0,0,0); pthread_cleanup_pop(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  done=yes\nelse\n  done=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\tif test \"x$done\" = xyes; then\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\telse\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\tfi\n\n\tif test x\"$done\" = xno; then\n\t   { $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether -lpthread saves the day\" >&5\n$as_echo_n \"checking whether -lpthread saves the day... \" >&6; }\n\t   LIBS=\"-lpthread $LIBS\"\n\t   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <pthread.h>\nint\nmain ()\n{\npthread_t th; pthread_join(th, 0);\n\t       pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t       pthread_create(0,0,0,0); pthread_cleanup_pop(0);\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  done=yes\nelse\n  done=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\n\t   if test \"x$done\" = xyes; then\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\n\t      PTHREAD_LIBS=\"$PTHREAD_LIBS -lpthread\"\n\t   else\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n\t      { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib\" >&5\n$as_echo \"$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib\" >&2;}\n\t   fi\n\tfi\n\n\tCFLAGS=\"$save_CFLAGS\"\n\tLIBS=\"$save_LIBS\"\n\tCC=\"$save_CC\"\nelse\n        PTHREAD_CC=\"$CC\"\nfi\n\n\n\n\n\n# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:\nif test x\"$acx_pthread_ok\" = xyes; then\n\n$as_echo \"#define HAVE_PTHREAD 1\" >>confdefs.h\n\n        :\nelse\n        acx_pthread_ok=no\n\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n# Find out what namespace 'normal' STL code lives in\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the compiler implements namespaces\" >&5\n$as_echo_n \"checking whether the compiler implements namespaces... \" >&6; }\nif test \"${ac_cv_cxx_namespaces+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n                  ac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\n\n                  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nnamespace Outer {\n                                    namespace Inner { int i = 0; }}\nint\nmain ()\n{\nusing namespace Outer::Inner; return i;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_cxx_namespaces=yes\nelse\n  ac_cv_cxx_namespaces=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n                  ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_namespaces\" >&5\n$as_echo \"$ac_cv_cxx_namespaces\" >&6; }\n  if test \"$ac_cv_cxx_namespaces\" = yes; then\n\n$as_echo \"#define HAVE_NAMESPACES 1\" >>confdefs.h\n\n  fi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking what namespace STL code is in\" >&5\n$as_echo_n \"checking what namespace STL code is in... \" >&6; }\nif test \"${ac_cv_cxx_stl_namespace+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n\n\n      ac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\n\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <vector>\nint\nmain ()\n{\nvector<int> t; return 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_cxx_stl_namespace=none\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <vector>\nint\nmain ()\n{\nstd::vector<int> t; return 0;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_cxx_stl_namespace=std\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n      ac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_stl_namespace\" >&5\n$as_echo \"$ac_cv_cxx_stl_namespace\" >&6; }\n   if test \"$ac_cv_cxx_stl_namespace\" = none; then\n\n$as_echo \"#define STL_NAMESPACE /**/\" >>confdefs.h\n\n   fi\n   if test \"$ac_cv_cxx_stl_namespace\" = std; then\n\n$as_echo \"#define STL_NAMESPACE std\" >>confdefs.h\n\n   fi\n\n\n# Figure out where libc has program_invocation_name\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for program_invocation_name\" >&5\n$as_echo_n \"checking for program_invocation_name... \" >&6; }\nif test \"${ac_cv_have_program_invocation_name+set}\" = set; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\nextern char* program_invocation_name;\nint\nmain ()\n{\nreturn *program_invocation_name;\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_have_program_invocation_name=yes\nelse\n  ac_cv_have_program_invocation_name=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_program_invocation_name\" >&5\n$as_echo \"$ac_cv_have_program_invocation_name\" >&6; }\n   if test \"$ac_cv_have_program_invocation_name\" = \"yes\"; then\n\n$as_echo \"#define HAVE_PROGRAM_INVOCATION_NAME 1\" >>confdefs.h\n\n   fi\n\n\n# Make the install prefix available, to figure out where to look for pprof\nac_cv_install_prefix=\"$prefix\";\n   if test x\"$ac_cv_install_prefix\" = x\"NONE\" ; then\n     ac_cv_install_prefix=\"$ac_default_prefix\";\n   fi\n\ncat >>confdefs.h <<_ACEOF\n#define INSTALL_PREFIX \"$ac_cv_install_prefix\"\n_ACEOF\n\n\n\n# For windows, this has a non-trivial value (__declspec(export)), but any\n# system that uses configure wants this to be the empty string.\n\n$as_echo \"#define PERFTOOLS_DLL_DECL /**/\" >>confdefs.h\n\n\n# In theory, config.h files shouldn't need a header guard, but we do,\n# because we (maybe) #include windows/mingw.h from within config.h,\n# and it #includes other .h files.  These all have header guards, so\n# the end result is if config.h is #included twice, its #undefs get\n# evaluated twice, but all the ones in mingw.h/etc only get evaluated\n# once, potentially causing trouble.  c.f.\n#   http://code.google.com/p/google-perftools/issues/detail?id=246\n\n\n# MinGW uses autoconf, but also needs the windows shim routines\n# (since it doesn't have its own support for, say, pthreads).\n# This requires us to #include a special header file, and also to\n# link in some windows versions of .o's instead of the unix versions.\n\n\n\nif expr $host : '.*-mingw' >/dev/null 2>&1; then\n  MINGW_TRUE=\n  MINGW_FALSE='#'\nelse\n  MINGW_TRUE='#'\n  MINGW_FALSE=\nfi\n\n\n# Redhat 7 (and below?) has sys/ucontext.h, but if you try to #include\n# it directly, the compiler gets upset.  So we pretend we don't have\n# it.\nif cat /etc/redhat-release 2>/dev/null | grep \"Red Hat Linux release 7\" >/dev/null 2>&1; then\n\n$as_echo \"#define HAVE_SYS_UCONTEXT_H 0\" >>confdefs.h\n\nfi\n\n# Export the --enable flags we set above.  We do this at the end so\n# other configure rules can enable or disable targets based on what\n# they find.\n\n\nif test \"$enable_cpu_profiler\" = yes; then\n  WITH_CPU_PROFILER_TRUE=\n  WITH_CPU_PROFILER_FALSE='#'\nelse\n  WITH_CPU_PROFILER_TRUE='#'\n  WITH_CPU_PROFILER_FALSE=\nfi\n\n\n\nif test \"$enable_heap_profiler\" = yes; then\n  WITH_HEAP_PROFILER_TRUE=\n  WITH_HEAP_PROFILER_FALSE='#'\nelse\n  WITH_HEAP_PROFILER_TRUE='#'\n  WITH_HEAP_PROFILER_FALSE=\nfi\n\n\n\nif test \"$enable_heap_checker\" = yes; then\n  WITH_HEAP_CHECKER_TRUE=\n  WITH_HEAP_CHECKER_FALSE='#'\nelse\n  WITH_HEAP_CHECKER_TRUE='#'\n  WITH_HEAP_CHECKER_FALSE=\nfi\n\n\n\nif test \"$enable_debugalloc\" = yes; then\n  WITH_DEBUGALLOC_TRUE=\n  WITH_DEBUGALLOC_FALSE='#'\nelse\n  WITH_DEBUGALLOC_TRUE='#'\n  WITH_DEBUGALLOC_FALSE=\nfi\n\n# We make tcmalloc.so if either heap-profiler or heap-checker is asked for.\n\n\nif test \"$enable_heap_profiler\" = yes -o \\\n                    \"$enable_heap_checker\" = yes; then\n  WITH_HEAP_PROFILER_OR_CHECKER_TRUE=\n  WITH_HEAP_PROFILER_OR_CHECKER_FALSE='#'\nelse\n  WITH_HEAP_PROFILER_OR_CHECKER_TRUE='#'\n  WITH_HEAP_PROFILER_OR_CHECKER_FALSE=\nfi\n\n# If we don't use any profilers, we don't need stack traces (or pprof)\n\n\nif test \"$enable_cpu_profiler\" = yes -o \\\n                                      \"$enable_heap_profiler\" = yes -o \\\n                                      \"$enable_heap_checker\" = yes; then\n  WITH_STACK_TRACE_TRUE=\n  WITH_STACK_TRACE_FALSE='#'\nelse\n  WITH_STACK_TRACE_TRUE='#'\n  WITH_STACK_TRACE_FALSE=\nfi\n\n\n# Write generated configuration file\nac_config_files=\"$ac_config_files Makefile src/google/tcmalloc.h\"\n\ncat >confcache <<\\_ACEOF\n# This file is a shell script that caches the results of configure\n# tests run on this system so they can be shared between configure\n# scripts and configure runs, see configure's option --config-cache.\n# It is not useful on other systems.  If it contains results you don't\n# want to keep, you may remove or edit it.\n#\n# config.status only pays attention to the cache file if you give it\n# the --recheck option to rerun configure.\n#\n# `ac_cv_env_foo' variables (set or unset) will be overridden when\n# loading this file, other *unset* `ac_cv_foo' will be assigned the\n# following values.\n\n_ACEOF\n\n# The following way of writing the cache mishandles newlines in values,\n# but we know of no workaround that is simple, portable, and efficient.\n# So, we kill variables containing newlines.\n# Ultrix sh set writes to stderr and can't be redirected directly,\n# and sets the high bit in the cache file unless we assign to the vars.\n(\n  for ac_var in `(set) 2>&1 | sed -n 's/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n\n  (set) 2>&1 |\n    case $as_nl`(ac_space=' '; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      # `set' does not quote correctly, so add quotes: double-quote\n      # substitution turns \\\\\\\\ into \\\\, and sed turns \\\\ into \\.\n      sed -n \\\n\t\"s/'/'\\\\\\\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\\\2'/p\"\n      ;; #(\n    *)\n      # `set' quotes correctly as required by POSIX, so do not add quotes.\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n) |\n  sed '\n     /^ac_cv_env_/b end\n     t clear\n     :clear\n     s/^\\([^=]*\\)=\\(.*[{}].*\\)$/test \"${\\1+set}\" = set || &/\n     t end\n     s/^\\([^=]*\\)=\\(.*\\)$/\\1=${\\1=\\2}/\n     :end' >>confcache\nif diff \"$cache_file\" confcache >/dev/null 2>&1; then :; else\n  if test -w \"$cache_file\"; then\n    test \"x$cache_file\" != \"x/dev/null\" &&\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: updating cache $cache_file\" >&5\n$as_echo \"$as_me: updating cache $cache_file\" >&6;}\n    cat confcache >$cache_file\n  else\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file\" >&5\n$as_echo \"$as_me: not updating unwritable cache $cache_file\" >&6;}\n  fi\nfi\nrm -f confcache\n\ntest \"x$prefix\" = xNONE && prefix=$ac_default_prefix\n# Let make expand exec_prefix.\ntest \"x$exec_prefix\" = xNONE && exec_prefix='${prefix}'\n\nDEFS=-DHAVE_CONFIG_H\n\nac_libobjs=\nac_ltlibobjs=\nfor ac_i in : $LIBOBJS; do test \"x$ac_i\" = x: && continue\n  # 1. Remove the extension, and $U if already installed.\n  ac_script='s/\\$U\\././;s/\\.o$//;s/\\.obj$//'\n  ac_i=`$as_echo \"$ac_i\" | sed \"$ac_script\"`\n  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR\n  #    will be set to the directory where LIBOBJS objects are built.\n  as_fn_append ac_libobjs \" \\${LIBOBJDIR}$ac_i\\$U.$ac_objext\"\n  as_fn_append ac_ltlibobjs \" \\${LIBOBJDIR}$ac_i\"'$U.lo'\ndone\nLIBOBJS=$ac_libobjs\n\nLTLIBOBJS=$ac_ltlibobjs\n\n\nif test -z \"${AMDEP_TRUE}\" && test -z \"${AMDEP_FALSE}\"; then\n  as_fn_error \"conditional \\\"AMDEP\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${am__fastdepCC_TRUE}\" && test -z \"${am__fastdepCC_FALSE}\"; then\n  as_fn_error \"conditional \\\"am__fastdepCC\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${am__fastdepCXX_TRUE}\" && test -z \"${am__fastdepCXX_FALSE}\"; then\n  as_fn_error \"conditional \\\"am__fastdepCXX\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${GCC_TRUE}\" && test -z \"${GCC_FALSE}\"; then\n  as_fn_error \"conditional \\\"GCC\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${HAVE_OBJCOPY_WEAKEN_TRUE}\" && test -z \"${HAVE_OBJCOPY_WEAKEN_FALSE}\"; then\n  as_fn_error \"conditional \\\"HAVE_OBJCOPY_WEAKEN\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${am__fastdepCXX_TRUE}\" && test -z \"${am__fastdepCXX_FALSE}\"; then\n  as_fn_error \"conditional \\\"am__fastdepCXX\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${USE_LIBTOOL_TRUE}\" && test -z \"${USE_LIBTOOL_FALSE}\"; then\n  as_fn_error \"conditional \\\"USE_LIBTOOL\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${ENABLE_STATIC_TRUE}\" && test -z \"${ENABLE_STATIC_FALSE}\"; then\n  as_fn_error \"conditional \\\"ENABLE_STATIC\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${ENABLE_FRAME_POINTERS_TRUE}\" && test -z \"${ENABLE_FRAME_POINTERS_FALSE}\"; then\n  as_fn_error \"conditional \\\"ENABLE_FRAME_POINTERS\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${X86_64_AND_NO_FP_BY_DEFAULT_TRUE}\" && test -z \"${X86_64_AND_NO_FP_BY_DEFAULT_FALSE}\"; then\n  as_fn_error \"conditional \\\"X86_64_AND_NO_FP_BY_DEFAULT\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${MINGW_TRUE}\" && test -z \"${MINGW_FALSE}\"; then\n  as_fn_error \"conditional \\\"MINGW\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${WITH_CPU_PROFILER_TRUE}\" && test -z \"${WITH_CPU_PROFILER_FALSE}\"; then\n  as_fn_error \"conditional \\\"WITH_CPU_PROFILER\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${WITH_HEAP_PROFILER_TRUE}\" && test -z \"${WITH_HEAP_PROFILER_FALSE}\"; then\n  as_fn_error \"conditional \\\"WITH_HEAP_PROFILER\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${WITH_HEAP_CHECKER_TRUE}\" && test -z \"${WITH_HEAP_CHECKER_FALSE}\"; then\n  as_fn_error \"conditional \\\"WITH_HEAP_CHECKER\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${WITH_DEBUGALLOC_TRUE}\" && test -z \"${WITH_DEBUGALLOC_FALSE}\"; then\n  as_fn_error \"conditional \\\"WITH_DEBUGALLOC\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${WITH_HEAP_PROFILER_OR_CHECKER_TRUE}\" && test -z \"${WITH_HEAP_PROFILER_OR_CHECKER_FALSE}\"; then\n  as_fn_error \"conditional \\\"WITH_HEAP_PROFILER_OR_CHECKER\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\nif test -z \"${WITH_STACK_TRACE_TRUE}\" && test -z \"${WITH_STACK_TRACE_FALSE}\"; then\n  as_fn_error \"conditional \\\"WITH_STACK_TRACE\\\" was never defined.\nUsually this means the macro was only invoked conditionally.\" \"$LINENO\" 5\nfi\n\n: ${CONFIG_STATUS=./config.status}\nac_write_fail=0\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files $CONFIG_STATUS\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS\" >&5\n$as_echo \"$as_me: creating $CONFIG_STATUS\" >&6;}\nas_write_fail=0\ncat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1\n#! $SHELL\n# Generated by $as_me.\n# Run this file to recreate the current configuration.\n# Compiler output produced by configure, useful for debugging\n# configure, is in config.log if it exists.\n\ndebug=false\nac_cs_recheck=false\nac_cs_silent=false\n\nSHELL=\\${CONFIG_SHELL-$SHELL}\nexport SHELL\n_ASEOF\ncat >>$CONFIG_STATUS <<\\_ASEOF || as_write_fail=1\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\n\n# as_fn_error ERROR [LINENO LOG_FD]\n# ---------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with status $?, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$?; test $as_status -eq 0 && as_status=1\n  if test \"$3\"; then\n    as_lineno=${as_lineno-\"$2\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $1\" >&$3\n  fi\n  $as_echo \"$as_me: error: $1\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -p'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -p'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -p'\n  fi\nelse\n  as_ln_s='cp -p'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nif test -x / >/dev/null 2>&1; then\n  as_test_x='test -x'\nelse\n  if ls -dL / >/dev/null 2>&1; then\n    as_ls_L_option=L\n  else\n    as_ls_L_option=\n  fi\n  as_test_x='\n    eval sh -c '\\''\n      if test -d \"$1\"; then\n\ttest -d \"$1/.\";\n      else\n\tcase $1 in #(\n\t-*)set \"./$1\";;\n\tesac;\n\tcase `ls -ld'$as_ls_L_option' \"$1\" 2>/dev/null` in #((\n\t???[sx]*):;;*)false;;esac;fi\n    '\\'' sh\n  '\nfi\nas_executable_p=$as_test_x\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\nexec 6>&1\n## ----------------------------------- ##\n## Main body of $CONFIG_STATUS script. ##\n## ----------------------------------- ##\n_ASEOF\ntest $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# Save the log message, to keep $0 and so on meaningful, and to\n# report actual input values of CONFIG_FILES etc. instead of their\n# values after options handling.\nac_log=\"\nThis file was extended by google-perftools $as_me 1.7, which was\ngenerated by GNU Autoconf 2.65.  Invocation command line was\n\n  CONFIG_FILES    = $CONFIG_FILES\n  CONFIG_HEADERS  = $CONFIG_HEADERS\n  CONFIG_LINKS    = $CONFIG_LINKS\n  CONFIG_COMMANDS = $CONFIG_COMMANDS\n  $ $0 $@\n\non `(hostname || uname -n) 2>/dev/null | sed 1q`\n\"\n\n_ACEOF\n\ncase $ac_config_files in *\"\n\"*) set x $ac_config_files; shift; ac_config_files=$*;;\nesac\n\ncase $ac_config_headers in *\"\n\"*) set x $ac_config_headers; shift; ac_config_headers=$*;;\nesac\n\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n# Files that config.status was made for.\nconfig_files=\"$ac_config_files\"\nconfig_headers=\"$ac_config_headers\"\nconfig_commands=\"$ac_config_commands\"\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nac_cs_usage=\"\\\n\\`$as_me' instantiates files and other configuration actions\nfrom templates according to the current configuration.  Unless the files\nand actions are specified as TAGs, all are instantiated by default.\n\nUsage: $0 [OPTION]... [TAG]...\n\n  -h, --help       print this help, then exit\n  -V, --version    print version number and configuration settings, then exit\n      --config     print configuration, then exit\n  -q, --quiet, --silent\n                   do not print progress messages\n  -d, --debug      don't remove temporary files\n      --recheck    update $as_me by reconfiguring in the same conditions\n      --file=FILE[:TEMPLATE]\n                   instantiate the configuration file FILE\n      --header=FILE[:TEMPLATE]\n                   instantiate the configuration header FILE\n\nConfiguration files:\n$config_files\n\nConfiguration headers:\n$config_headers\n\nConfiguration commands:\n$config_commands\n\nReport bugs to <opensource@google.com>.\"\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_cs_config=\"`$as_echo \"$ac_configure_args\" | sed 's/^ //; s/[\\\\\"\"\\`\\$]/\\\\\\\\&/g'`\"\nac_cs_version=\"\\\\\ngoogle-perftools config.status 1.7\nconfigured by $0, generated by GNU Autoconf 2.65,\n  with options \\\\\"\\$ac_cs_config\\\\\"\n\nCopyright (C) 2009 Free Software Foundation, Inc.\nThis config.status script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\"\n\nac_pwd='$ac_pwd'\nsrcdir='$srcdir'\nINSTALL='$INSTALL'\nAWK='$AWK'\ntest -n \"\\$AWK\" || AWK=awk\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# The default lists apply if the user does not specify any file.\nac_need_defaults=:\nwhile test $# != 0\ndo\n  case $1 in\n  --*=*)\n    ac_option=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=`expr \"X$1\" : 'X[^=]*=\\(.*\\)'`\n    ac_shift=:\n    ;;\n  *)\n    ac_option=$1\n    ac_optarg=$2\n    ac_shift=shift\n    ;;\n  esac\n\n  case $ac_option in\n  # Handling of the options.\n  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)\n    ac_cs_recheck=: ;;\n  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )\n    $as_echo \"$ac_cs_version\"; exit ;;\n  --config | --confi | --conf | --con | --co | --c )\n    $as_echo \"$ac_cs_config\"; exit ;;\n  --debug | --debu | --deb | --de | --d | -d )\n    debug=: ;;\n  --file | --fil | --fi | --f )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    as_fn_append CONFIG_FILES \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --header | --heade | --head | --hea )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    as_fn_append CONFIG_HEADERS \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --he | --h)\n    # Conflict between --help and --header\n    as_fn_error \"ambiguous option: \\`$1'\nTry \\`$0 --help' for more information.\";;\n  --help | --hel | -h )\n    $as_echo \"$ac_cs_usage\"; exit ;;\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil | --si | --s)\n    ac_cs_silent=: ;;\n\n  # This is an error.\n  -*) as_fn_error \"unrecognized option: \\`$1'\nTry \\`$0 --help' for more information.\" ;;\n\n  *) as_fn_append ac_config_targets \" $1\"\n     ac_need_defaults=false ;;\n\n  esac\n  shift\ndone\n\nac_configure_extra_args=\n\nif $ac_cs_silent; then\n  exec 6>/dev/null\n  ac_configure_extra_args=\"$ac_configure_extra_args --silent\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nif \\$ac_cs_recheck; then\n  set X '$SHELL' '$0' $ac_configure_args \\$ac_configure_extra_args --no-create --no-recursion\n  shift\n  \\$as_echo \"running CONFIG_SHELL=$SHELL \\$*\" >&6\n  CONFIG_SHELL='$SHELL'\n  export CONFIG_SHELL\n  exec \"\\$@\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nexec 5>>config.log\n{\n  echo\n  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX\n## Running $as_me. ##\n_ASBOX\n  $as_echo \"$ac_log\"\n} >&5\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n#\n# INIT-COMMANDS\n#\nAMDEP_TRUE=\"$AMDEP_TRUE\" ac_aux_dir=\"$ac_aux_dir\"\n\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nsed_quote_subst='$sed_quote_subst'\ndouble_quote_subst='$double_quote_subst'\ndelay_variable_subst='$delay_variable_subst'\nenable_fast_install='`$ECHO \"X$enable_fast_install\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmacro_version='`$ECHO \"X$macro_version\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmacro_revision='`$ECHO \"X$macro_revision\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_shared='`$ECHO \"X$enable_shared\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_static='`$ECHO \"X$enable_static\" | $Xsed -e \"$delay_single_quote_subst\"`'\npic_mode='`$ECHO \"X$pic_mode\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhost_alias='`$ECHO \"X$host_alias\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhost='`$ECHO \"X$host\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhost_os='`$ECHO \"X$host_os\" | $Xsed -e \"$delay_single_quote_subst\"`'\nbuild_alias='`$ECHO \"X$build_alias\" | $Xsed -e \"$delay_single_quote_subst\"`'\nbuild='`$ECHO \"X$build\" | $Xsed -e \"$delay_single_quote_subst\"`'\nbuild_os='`$ECHO \"X$build_os\" | $Xsed -e \"$delay_single_quote_subst\"`'\nSED='`$ECHO \"X$SED\" | $Xsed -e \"$delay_single_quote_subst\"`'\nXsed='`$ECHO \"X$Xsed\" | $Xsed -e \"$delay_single_quote_subst\"`'\nGREP='`$ECHO \"X$GREP\" | $Xsed -e \"$delay_single_quote_subst\"`'\nEGREP='`$ECHO \"X$EGREP\" | $Xsed -e \"$delay_single_quote_subst\"`'\nFGREP='`$ECHO \"X$FGREP\" | $Xsed -e \"$delay_single_quote_subst\"`'\nLD='`$ECHO \"X$LD\" | $Xsed -e \"$delay_single_quote_subst\"`'\nNM='`$ECHO \"X$NM\" | $Xsed -e \"$delay_single_quote_subst\"`'\nLN_S='`$ECHO \"X$LN_S\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmax_cmd_len='`$ECHO \"X$max_cmd_len\" | $Xsed -e \"$delay_single_quote_subst\"`'\nac_objext='`$ECHO \"X$ac_objext\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexeext='`$ECHO \"X$exeext\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_unset='`$ECHO \"X$lt_unset\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_SP2NL='`$ECHO \"X$lt_SP2NL\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_NL2SP='`$ECHO \"X$lt_NL2SP\" | $Xsed -e \"$delay_single_quote_subst\"`'\nreload_flag='`$ECHO \"X$reload_flag\" | $Xsed -e \"$delay_single_quote_subst\"`'\nreload_cmds='`$ECHO \"X$reload_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nOBJDUMP='`$ECHO \"X$OBJDUMP\" | $Xsed -e \"$delay_single_quote_subst\"`'\ndeplibs_check_method='`$ECHO \"X$deplibs_check_method\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfile_magic_cmd='`$ECHO \"X$file_magic_cmd\" | $Xsed -e \"$delay_single_quote_subst\"`'\nAR='`$ECHO \"X$AR\" | $Xsed -e \"$delay_single_quote_subst\"`'\nAR_FLAGS='`$ECHO \"X$AR_FLAGS\" | $Xsed -e \"$delay_single_quote_subst\"`'\nSTRIP='`$ECHO \"X$STRIP\" | $Xsed -e \"$delay_single_quote_subst\"`'\nRANLIB='`$ECHO \"X$RANLIB\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_postinstall_cmds='`$ECHO \"X$old_postinstall_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_postuninstall_cmds='`$ECHO \"X$old_postuninstall_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_archive_cmds='`$ECHO \"X$old_archive_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nCC='`$ECHO \"X$CC\" | $Xsed -e \"$delay_single_quote_subst\"`'\nCFLAGS='`$ECHO \"X$CFLAGS\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler='`$ECHO \"X$compiler\" | $Xsed -e \"$delay_single_quote_subst\"`'\nGCC='`$ECHO \"X$GCC\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_pipe='`$ECHO \"X$lt_cv_sys_global_symbol_pipe\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_cdecl='`$ECHO \"X$lt_cv_sys_global_symbol_to_cdecl\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_c_name_address='`$ECHO \"X$lt_cv_sys_global_symbol_to_c_name_address\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO \"X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix\" | $Xsed -e \"$delay_single_quote_subst\"`'\nobjdir='`$ECHO \"X$objdir\" | $Xsed -e \"$delay_single_quote_subst\"`'\nSHELL='`$ECHO \"X$SHELL\" | $Xsed -e \"$delay_single_quote_subst\"`'\nECHO='`$ECHO \"X$ECHO\" | $Xsed -e \"$delay_single_quote_subst\"`'\nMAGIC_CMD='`$ECHO \"X$MAGIC_CMD\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_no_builtin_flag='`$ECHO \"X$lt_prog_compiler_no_builtin_flag\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_wl='`$ECHO \"X$lt_prog_compiler_wl\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_pic='`$ECHO \"X$lt_prog_compiler_pic\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_static='`$ECHO \"X$lt_prog_compiler_static\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_cv_prog_compiler_c_o='`$ECHO \"X$lt_cv_prog_compiler_c_o\" | $Xsed -e \"$delay_single_quote_subst\"`'\nneed_locks='`$ECHO \"X$need_locks\" | $Xsed -e \"$delay_single_quote_subst\"`'\nDSYMUTIL='`$ECHO \"X$DSYMUTIL\" | $Xsed -e \"$delay_single_quote_subst\"`'\nNMEDIT='`$ECHO \"X$NMEDIT\" | $Xsed -e \"$delay_single_quote_subst\"`'\nLIPO='`$ECHO \"X$LIPO\" | $Xsed -e \"$delay_single_quote_subst\"`'\nOTOOL='`$ECHO \"X$OTOOL\" | $Xsed -e \"$delay_single_quote_subst\"`'\nOTOOL64='`$ECHO \"X$OTOOL64\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlibext='`$ECHO \"X$libext\" | $Xsed -e \"$delay_single_quote_subst\"`'\nshrext_cmds='`$ECHO \"X$shrext_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nextract_expsyms_cmds='`$ECHO \"X$extract_expsyms_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\narchive_cmds_need_lc='`$ECHO \"X$archive_cmds_need_lc\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_shared_with_static_runtimes='`$ECHO \"X$enable_shared_with_static_runtimes\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexport_dynamic_flag_spec='`$ECHO \"X$export_dynamic_flag_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nwhole_archive_flag_spec='`$ECHO \"X$whole_archive_flag_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_needs_object='`$ECHO \"X$compiler_needs_object\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_archive_from_new_cmds='`$ECHO \"X$old_archive_from_new_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_archive_from_expsyms_cmds='`$ECHO \"X$old_archive_from_expsyms_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\narchive_cmds='`$ECHO \"X$archive_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\narchive_expsym_cmds='`$ECHO \"X$archive_expsym_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmodule_cmds='`$ECHO \"X$module_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmodule_expsym_cmds='`$ECHO \"X$module_expsym_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nwith_gnu_ld='`$ECHO \"X$with_gnu_ld\" | $Xsed -e \"$delay_single_quote_subst\"`'\nallow_undefined_flag='`$ECHO \"X$allow_undefined_flag\" | $Xsed -e \"$delay_single_quote_subst\"`'\nno_undefined_flag='`$ECHO \"X$no_undefined_flag\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec='`$ECHO \"X$hardcode_libdir_flag_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_ld='`$ECHO \"X$hardcode_libdir_flag_spec_ld\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_libdir_separator='`$ECHO \"X$hardcode_libdir_separator\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_direct='`$ECHO \"X$hardcode_direct\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_direct_absolute='`$ECHO \"X$hardcode_direct_absolute\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_minus_L='`$ECHO \"X$hardcode_minus_L\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_shlibpath_var='`$ECHO \"X$hardcode_shlibpath_var\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_automatic='`$ECHO \"X$hardcode_automatic\" | $Xsed -e \"$delay_single_quote_subst\"`'\ninherit_rpath='`$ECHO \"X$inherit_rpath\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlink_all_deplibs='`$ECHO \"X$link_all_deplibs\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfix_srcfile_path='`$ECHO \"X$fix_srcfile_path\" | $Xsed -e \"$delay_single_quote_subst\"`'\nalways_export_symbols='`$ECHO \"X$always_export_symbols\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexport_symbols_cmds='`$ECHO \"X$export_symbols_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexclude_expsyms='`$ECHO \"X$exclude_expsyms\" | $Xsed -e \"$delay_single_quote_subst\"`'\ninclude_expsyms='`$ECHO \"X$include_expsyms\" | $Xsed -e \"$delay_single_quote_subst\"`'\nprelink_cmds='`$ECHO \"X$prelink_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfile_list_spec='`$ECHO \"X$file_list_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nvariables_saved_for_relink='`$ECHO \"X$variables_saved_for_relink\" | $Xsed -e \"$delay_single_quote_subst\"`'\nneed_lib_prefix='`$ECHO \"X$need_lib_prefix\" | $Xsed -e \"$delay_single_quote_subst\"`'\nneed_version='`$ECHO \"X$need_version\" | $Xsed -e \"$delay_single_quote_subst\"`'\nversion_type='`$ECHO \"X$version_type\" | $Xsed -e \"$delay_single_quote_subst\"`'\nrunpath_var='`$ECHO \"X$runpath_var\" | $Xsed -e \"$delay_single_quote_subst\"`'\nshlibpath_var='`$ECHO \"X$shlibpath_var\" | $Xsed -e \"$delay_single_quote_subst\"`'\nshlibpath_overrides_runpath='`$ECHO \"X$shlibpath_overrides_runpath\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlibname_spec='`$ECHO \"X$libname_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlibrary_names_spec='`$ECHO \"X$library_names_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nsoname_spec='`$ECHO \"X$soname_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\npostinstall_cmds='`$ECHO \"X$postinstall_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\npostuninstall_cmds='`$ECHO \"X$postuninstall_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfinish_cmds='`$ECHO \"X$finish_cmds\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfinish_eval='`$ECHO \"X$finish_eval\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_into_libs='`$ECHO \"X$hardcode_into_libs\" | $Xsed -e \"$delay_single_quote_subst\"`'\nsys_lib_search_path_spec='`$ECHO \"X$sys_lib_search_path_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nsys_lib_dlsearch_path_spec='`$ECHO \"X$sys_lib_dlsearch_path_spec\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_action='`$ECHO \"X$hardcode_action\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_dlopen='`$ECHO \"X$enable_dlopen\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_dlopen_self='`$ECHO \"X$enable_dlopen_self\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_dlopen_self_static='`$ECHO \"X$enable_dlopen_self_static\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_striplib='`$ECHO \"X$old_striplib\" | $Xsed -e \"$delay_single_quote_subst\"`'\nstriplib='`$ECHO \"X$striplib\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_lib_search_dirs='`$ECHO \"X$compiler_lib_search_dirs\" | $Xsed -e \"$delay_single_quote_subst\"`'\npredep_objects='`$ECHO \"X$predep_objects\" | $Xsed -e \"$delay_single_quote_subst\"`'\npostdep_objects='`$ECHO \"X$postdep_objects\" | $Xsed -e \"$delay_single_quote_subst\"`'\npredeps='`$ECHO \"X$predeps\" | $Xsed -e \"$delay_single_quote_subst\"`'\npostdeps='`$ECHO \"X$postdeps\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_lib_search_path='`$ECHO \"X$compiler_lib_search_path\" | $Xsed -e \"$delay_single_quote_subst\"`'\nLD_CXX='`$ECHO \"X$LD_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_archive_cmds_CXX='`$ECHO \"X$old_archive_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_CXX='`$ECHO \"X$compiler_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nGCC_CXX='`$ECHO \"X$GCC_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_no_builtin_flag_CXX='`$ECHO \"X$lt_prog_compiler_no_builtin_flag_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_wl_CXX='`$ECHO \"X$lt_prog_compiler_wl_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_pic_CXX='`$ECHO \"X$lt_prog_compiler_pic_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_prog_compiler_static_CXX='`$ECHO \"X$lt_prog_compiler_static_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlt_cv_prog_compiler_c_o_CXX='`$ECHO \"X$lt_cv_prog_compiler_c_o_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\narchive_cmds_need_lc_CXX='`$ECHO \"X$archive_cmds_need_lc_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nenable_shared_with_static_runtimes_CXX='`$ECHO \"X$enable_shared_with_static_runtimes_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexport_dynamic_flag_spec_CXX='`$ECHO \"X$export_dynamic_flag_spec_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nwhole_archive_flag_spec_CXX='`$ECHO \"X$whole_archive_flag_spec_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_needs_object_CXX='`$ECHO \"X$compiler_needs_object_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_archive_from_new_cmds_CXX='`$ECHO \"X$old_archive_from_new_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nold_archive_from_expsyms_cmds_CXX='`$ECHO \"X$old_archive_from_expsyms_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\narchive_cmds_CXX='`$ECHO \"X$archive_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\narchive_expsym_cmds_CXX='`$ECHO \"X$archive_expsym_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmodule_cmds_CXX='`$ECHO \"X$module_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nmodule_expsym_cmds_CXX='`$ECHO \"X$module_expsym_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nwith_gnu_ld_CXX='`$ECHO \"X$with_gnu_ld_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nallow_undefined_flag_CXX='`$ECHO \"X$allow_undefined_flag_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nno_undefined_flag_CXX='`$ECHO \"X$no_undefined_flag_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_CXX='`$ECHO \"X$hardcode_libdir_flag_spec_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_libdir_flag_spec_ld_CXX='`$ECHO \"X$hardcode_libdir_flag_spec_ld_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_libdir_separator_CXX='`$ECHO \"X$hardcode_libdir_separator_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_direct_CXX='`$ECHO \"X$hardcode_direct_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_direct_absolute_CXX='`$ECHO \"X$hardcode_direct_absolute_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_minus_L_CXX='`$ECHO \"X$hardcode_minus_L_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_shlibpath_var_CXX='`$ECHO \"X$hardcode_shlibpath_var_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_automatic_CXX='`$ECHO \"X$hardcode_automatic_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\ninherit_rpath_CXX='`$ECHO \"X$inherit_rpath_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nlink_all_deplibs_CXX='`$ECHO \"X$link_all_deplibs_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfix_srcfile_path_CXX='`$ECHO \"X$fix_srcfile_path_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nalways_export_symbols_CXX='`$ECHO \"X$always_export_symbols_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexport_symbols_cmds_CXX='`$ECHO \"X$export_symbols_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nexclude_expsyms_CXX='`$ECHO \"X$exclude_expsyms_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\ninclude_expsyms_CXX='`$ECHO \"X$include_expsyms_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nprelink_cmds_CXX='`$ECHO \"X$prelink_cmds_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nfile_list_spec_CXX='`$ECHO \"X$file_list_spec_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\nhardcode_action_CXX='`$ECHO \"X$hardcode_action_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_lib_search_dirs_CXX='`$ECHO \"X$compiler_lib_search_dirs_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\npredep_objects_CXX='`$ECHO \"X$predep_objects_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\npostdep_objects_CXX='`$ECHO \"X$postdep_objects_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\npredeps_CXX='`$ECHO \"X$predeps_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\npostdeps_CXX='`$ECHO \"X$postdeps_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\ncompiler_lib_search_path_CXX='`$ECHO \"X$compiler_lib_search_path_CXX\" | $Xsed -e \"$delay_single_quote_subst\"`'\n\nLTCC='$LTCC'\nLTCFLAGS='$LTCFLAGS'\ncompiler='$compiler_DEFAULT'\n\n# Quote evaled strings.\nfor var in SED \\\nGREP \\\nEGREP \\\nFGREP \\\nLD \\\nNM \\\nLN_S \\\nlt_SP2NL \\\nlt_NL2SP \\\nreload_flag \\\nOBJDUMP \\\ndeplibs_check_method \\\nfile_magic_cmd \\\nAR \\\nAR_FLAGS \\\nSTRIP \\\nRANLIB \\\nCC \\\nCFLAGS \\\ncompiler \\\nlt_cv_sys_global_symbol_pipe \\\nlt_cv_sys_global_symbol_to_cdecl \\\nlt_cv_sys_global_symbol_to_c_name_address \\\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix \\\nSHELL \\\nECHO \\\nlt_prog_compiler_no_builtin_flag \\\nlt_prog_compiler_wl \\\nlt_prog_compiler_pic \\\nlt_prog_compiler_static \\\nlt_cv_prog_compiler_c_o \\\nneed_locks \\\nDSYMUTIL \\\nNMEDIT \\\nLIPO \\\nOTOOL \\\nOTOOL64 \\\nshrext_cmds \\\nexport_dynamic_flag_spec \\\nwhole_archive_flag_spec \\\ncompiler_needs_object \\\nwith_gnu_ld \\\nallow_undefined_flag \\\nno_undefined_flag \\\nhardcode_libdir_flag_spec \\\nhardcode_libdir_flag_spec_ld \\\nhardcode_libdir_separator \\\nfix_srcfile_path \\\nexclude_expsyms \\\ninclude_expsyms \\\nfile_list_spec \\\nvariables_saved_for_relink \\\nlibname_spec \\\nlibrary_names_spec \\\nsoname_spec \\\nfinish_eval \\\nold_striplib \\\nstriplib \\\ncompiler_lib_search_dirs \\\npredep_objects \\\npostdep_objects \\\npredeps \\\npostdeps \\\ncompiler_lib_search_path \\\nLD_CXX \\\ncompiler_CXX \\\nlt_prog_compiler_no_builtin_flag_CXX \\\nlt_prog_compiler_wl_CXX \\\nlt_prog_compiler_pic_CXX \\\nlt_prog_compiler_static_CXX \\\nlt_cv_prog_compiler_c_o_CXX \\\nexport_dynamic_flag_spec_CXX \\\nwhole_archive_flag_spec_CXX \\\ncompiler_needs_object_CXX \\\nwith_gnu_ld_CXX \\\nallow_undefined_flag_CXX \\\nno_undefined_flag_CXX \\\nhardcode_libdir_flag_spec_CXX \\\nhardcode_libdir_flag_spec_ld_CXX \\\nhardcode_libdir_separator_CXX \\\nfix_srcfile_path_CXX \\\nexclude_expsyms_CXX \\\ninclude_expsyms_CXX \\\nfile_list_spec_CXX \\\ncompiler_lib_search_dirs_CXX \\\npredep_objects_CXX \\\npostdep_objects_CXX \\\npredeps_CXX \\\npostdeps_CXX \\\ncompiler_lib_search_path_CXX; do\n    case \\`eval \\\\\\\\\\$ECHO \"X\\\\\\\\\\$\\$var\"\\` in\n    *[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"X\\\\\\$\\$var\\\\\" | \\\\\\$Xsed -e \\\\\"\\\\\\$sed_quote_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n# Double-quote double-evaled strings.\nfor var in reload_cmds \\\nold_postinstall_cmds \\\nold_postuninstall_cmds \\\nold_archive_cmds \\\nextract_expsyms_cmds \\\nold_archive_from_new_cmds \\\nold_archive_from_expsyms_cmds \\\narchive_cmds \\\narchive_expsym_cmds \\\nmodule_cmds \\\nmodule_expsym_cmds \\\nexport_symbols_cmds \\\nprelink_cmds \\\npostinstall_cmds \\\npostuninstall_cmds \\\nfinish_cmds \\\nsys_lib_search_path_spec \\\nsys_lib_dlsearch_path_spec \\\nold_archive_cmds_CXX \\\nold_archive_from_new_cmds_CXX \\\nold_archive_from_expsyms_cmds_CXX \\\narchive_cmds_CXX \\\narchive_expsym_cmds_CXX \\\nmodule_cmds_CXX \\\nmodule_expsym_cmds_CXX \\\nexport_symbols_cmds_CXX \\\nprelink_cmds_CXX; do\n    case \\`eval \\\\\\\\\\$ECHO \"X\\\\\\\\\\$\\$var\"\\` in\n    *[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"X\\\\\\$\\$var\\\\\" | \\\\\\$Xsed -e \\\\\"\\\\\\$double_quote_subst\\\\\" -e \\\\\"\\\\\\$sed_quote_subst\\\\\" -e \\\\\"\\\\\\$delay_variable_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n# Fix-up fallback echo if it was mangled by the above quoting rules.\ncase \\$lt_ECHO in\n*'\\\\\\$0 --fallback-echo\"')  lt_ECHO=\\`\\$ECHO \"X\\$lt_ECHO\" | \\$Xsed -e 's/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\$0 --fallback-echo\"\\$/\\$0 --fallback-echo\"/'\\`\n  ;;\nesac\n\nac_aux_dir='$ac_aux_dir'\nxsi_shell='$xsi_shell'\nlt_shell_append='$lt_shell_append'\n\n# See if we are running on zsh, and set the options which allow our\n# commands through without removal of \\ escapes INIT.\nif test -n \"\\${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n\n\n    PACKAGE='$PACKAGE'\n    VERSION='$VERSION'\n    TIMESTAMP='$TIMESTAMP'\n    RM='$RM'\n    ofile='$ofile'\n\n\n\n\n\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n\n# Handling of arguments.\nfor ac_config_target in $ac_config_targets\ndo\n  case $ac_config_target in\n    \"src/config.h\") CONFIG_HEADERS=\"$CONFIG_HEADERS src/config.h\" ;;\n    \"depfiles\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS depfiles\" ;;\n    \"libtool\") CONFIG_COMMANDS=\"$CONFIG_COMMANDS libtool\" ;;\n    \"Makefile\") CONFIG_FILES=\"$CONFIG_FILES Makefile\" ;;\n    \"src/google/tcmalloc.h\") CONFIG_FILES=\"$CONFIG_FILES src/google/tcmalloc.h\" ;;\n\n  *) as_fn_error \"invalid argument: \\`$ac_config_target'\" \"$LINENO\" 5;;\n  esac\ndone\n\n\n# If the user did not use the arguments to specify the items to instantiate,\n# then the envvar interface is used.  Set only those that are not.\n# We use the long form for the default assignment because of an extremely\n# bizarre bug on SunOS 4.1.3.\nif $ac_need_defaults; then\n  test \"${CONFIG_FILES+set}\" = set || CONFIG_FILES=$config_files\n  test \"${CONFIG_HEADERS+set}\" = set || CONFIG_HEADERS=$config_headers\n  test \"${CONFIG_COMMANDS+set}\" = set || CONFIG_COMMANDS=$config_commands\nfi\n\n# Have a temporary directory for convenience.  Make it in the build tree\n# simply because there is no reason against having it here, and in addition,\n# creating and moving files from /tmp can sometimes cause problems.\n# Hook for its removal unless debugging.\n# Note that there is a small window in which the directory will not be cleaned:\n# after its creation but before its name has been assigned to `$tmp'.\n$debug ||\n{\n  tmp=\n  trap 'exit_status=$?\n  { test -z \"$tmp\" || test ! -d \"$tmp\" || rm -fr \"$tmp\"; } && exit $exit_status\n' 0\n  trap 'as_fn_exit 1' 1 2 13 15\n}\n# Create a (secure) tmp directory for tmp files.\n\n{\n  tmp=`(umask 077 && mktemp -d \"./confXXXXXX\") 2>/dev/null` &&\n  test -n \"$tmp\" && test -d \"$tmp\"\n}  ||\n{\n  tmp=./conf$$-$RANDOM\n  (umask 077 && mkdir \"$tmp\")\n} || as_fn_error \"cannot create a temporary directory in .\" \"$LINENO\" 5\n\n# Set up the scripts for CONFIG_FILES section.\n# No need to generate them if there are no CONFIG_FILES.\n# This happens for instance with `./config.status config.h'.\nif test -n \"$CONFIG_FILES\"; then\n\n\nac_cr=`echo X | tr X '\\015'`\n# On cygwin, bash can eat \\r inside `` if the user requested igncr.\n# But we know of no other shell where ac_cr would be empty at this\n# point, so we can use a bashism as a fallback.\nif test \"x$ac_cr\" = x; then\n  eval ac_cr=\\$\\'\\\\r\\'\nfi\nac_cs_awk_cr=`$AWK 'BEGIN { print \"a\\rb\" }' </dev/null 2>/dev/null`\nif test \"$ac_cs_awk_cr\" = \"a${ac_cr}b\"; then\n  ac_cs_awk_cr='\\r'\nelse\n  ac_cs_awk_cr=$ac_cr\nfi\n\necho 'BEGIN {' >\"$tmp/subs1.awk\" &&\n_ACEOF\n\n\n{\n  echo \"cat >conf$$subs.awk <<_ACEOF\" &&\n  echo \"$ac_subst_vars\" | sed 's/.*/&!$&$ac_delim/' &&\n  echo \"_ACEOF\"\n} >conf$$subs.sh ||\n  as_fn_error \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\nac_delim_num=`echo \"$ac_subst_vars\" | grep -c '$'`\nac_delim='%!_!# '\nfor ac_last_try in false false false false false :; do\n  . ./conf$$subs.sh ||\n    as_fn_error \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n\n  ac_delim_n=`sed -n \"s/.*$ac_delim\\$/X/p\" conf$$subs.awk | grep -c X`\n  if test $ac_delim_n = $ac_delim_num; then\n    break\n  elif $ac_last_try; then\n    as_fn_error \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\nrm -f conf$$subs.sh\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\ncat >>\"\\$tmp/subs1.awk\" <<\\\\_ACAWK &&\n_ACEOF\nsed -n '\nh\ns/^/S[\"/; s/!.*/\"]=/\np\ng\ns/^[^!]*!//\n:repl\nt repl\ns/'\"$ac_delim\"'$//\nt delim\n:nl\nh\ns/\\(.\\{148\\}\\)..*/\\1/\nt more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\n\"\\\\/\np\nn\nb repl\n:more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt nl\n:delim\nh\ns/\\(.\\{148\\}\\)..*/\\1/\nt more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/\np\nb\n:more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt delim\n' <conf$$subs.awk | sed '\n/^[^\"\"]/{\n  N\n  s/\\n//\n}\n' >>$CONFIG_STATUS || ac_write_fail=1\nrm -f conf$$subs.awk\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n_ACAWK\ncat >>\"\\$tmp/subs1.awk\" <<_ACAWK &&\n  for (key in S) S_is_set[key] = 1\n  FS = \"\u0007\"\n\n}\n{\n  line = $ 0\n  nfields = split(line, field, \"@\")\n  substed = 0\n  len = length(field[1])\n  for (i = 2; i < nfields; i++) {\n    key = field[i]\n    keylen = length(key)\n    if (S_is_set[key]) {\n      value = S[key]\n      line = substr(line, 1, len) \"\" value \"\" substr(line, len + keylen + 3)\n      len += length(value) + length(field[++i])\n      substed = 1\n    } else\n      len += 1 + keylen\n  }\n\n  print line\n}\n\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nif sed \"s/$ac_cr//\" < /dev/null > /dev/null 2>&1; then\n  sed \"s/$ac_cr\\$//; s/$ac_cr/$ac_cs_awk_cr/g\"\nelse\n  cat\nfi < \"$tmp/subs1.awk\" > \"$tmp/subs.awk\" \\\n  || as_fn_error \"could not setup config files machinery\" \"$LINENO\" 5\n_ACEOF\n\n# VPATH may cause trouble with some makes, so we remove $(srcdir),\n# ${srcdir} and @srcdir@ from VPATH if srcdir is \".\", strip leading and\n# trailing colons and then remove the whole line if VPATH becomes empty\n# (actually we leave an empty line to preserve line numbers).\nif test \"x$srcdir\" = x.; then\n  ac_vpsub='/^[\t ]*VPATH[\t ]*=/{\ns/:*\\$(srcdir):*/:/\ns/:*\\${srcdir}:*/:/\ns/:*@srcdir@:*/:/\ns/^\\([^=]*=[\t ]*\\):*/\\1/\ns/:*$//\ns/^[^=]*=[\t ]*$//\n}'\nfi\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nfi # test -n \"$CONFIG_FILES\"\n\n# Set up the scripts for CONFIG_HEADERS section.\n# No need to generate them if there are no CONFIG_HEADERS.\n# This happens for instance with `./config.status Makefile'.\nif test -n \"$CONFIG_HEADERS\"; then\ncat >\"$tmp/defines.awk\" <<\\_ACAWK ||\nBEGIN {\n_ACEOF\n\n# Transform confdefs.h into an awk script `defines.awk', embedded as\n# here-document in config.status, that substitutes the proper values into\n# config.h.in to produce config.h.\n\n# Create a delimiter string that does not exist in confdefs.h, to ease\n# handling of long lines.\nac_delim='%!_!# '\nfor ac_last_try in false false :; do\n  ac_t=`sed -n \"/$ac_delim/p\" confdefs.h`\n  if test -z \"$ac_t\"; then\n    break\n  elif $ac_last_try; then\n    as_fn_error \"could not make $CONFIG_HEADERS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\n\n# For the awk script, D is an array of macro values keyed by name,\n# likewise P contains macro parameters if any.  Preserve backslash\n# newline sequences.\n\nac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*\nsed -n '\ns/.\\{148\\}/&'\"$ac_delim\"'/g\nt rset\n:rset\ns/^[\t ]*#[\t ]*define[\t ][\t ]*/ /\nt def\nd\n:def\ns/\\\\$//\nt bsnl\ns/[\"\\\\]/\\\\&/g\ns/^ \\('\"$ac_word_re\"'\\)\\(([^()]*)\\)[\t ]*\\(.*\\)/P[\"\\1\"]=\"\\2\"\\\nD[\"\\1\"]=\" \\3\"/p\ns/^ \\('\"$ac_word_re\"'\\)[\t ]*\\(.*\\)/D[\"\\1\"]=\" \\2\"/p\nd\n:bsnl\ns/[\"\\\\]/\\\\&/g\ns/^ \\('\"$ac_word_re\"'\\)\\(([^()]*)\\)[\t ]*\\(.*\\)/P[\"\\1\"]=\"\\2\"\\\nD[\"\\1\"]=\" \\3\\\\\\\\\\\\n\"\\\\/p\nt cont\ns/^ \\('\"$ac_word_re\"'\\)[\t ]*\\(.*\\)/D[\"\\1\"]=\" \\2\\\\\\\\\\\\n\"\\\\/p\nt cont\nd\n:cont\nn\ns/.\\{148\\}/&'\"$ac_delim\"'/g\nt clear\n:clear\ns/\\\\$//\nt bsnlc\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/p\nd\n:bsnlc\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\\\\\\\\\n\"\\\\/p\nb cont\n' <confdefs.h | sed '\ns/'\"$ac_delim\"'/\"\\\\\\\n\"/g' >>$CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  for (key in D) D_is_set[key] = 1\n  FS = \"\u0007\"\n}\n/^[\\t ]*#[\\t ]*(define|undef)[\\t ]+$ac_word_re([\\t (]|\\$)/ {\n  line = \\$ 0\n  split(line, arg, \" \")\n  if (arg[1] == \"#\") {\n    defundef = arg[2]\n    mac1 = arg[3]\n  } else {\n    defundef = substr(arg[1], 2)\n    mac1 = arg[2]\n  }\n  split(mac1, mac2, \"(\") #)\n  macro = mac2[1]\n  prefix = substr(line, 1, index(line, defundef) - 1)\n  if (D_is_set[macro]) {\n    # Preserve the white space surrounding the \"#\".\n    print prefix \"define\", macro P[macro] D[macro]\n    next\n  } else {\n    # Replace #undef with comments.  This is necessary, for example,\n    # in the case of _POSIX_SOURCE, which is predefined and required\n    # on some systems where configure will not decide to define it.\n    if (defundef == \"undef\") {\n      print \"/*\", prefix defundef, macro, \"*/\"\n      next\n    }\n  }\n}\n{ print }\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n  as_fn_error \"could not setup config headers machinery\" \"$LINENO\" 5\nfi # test -n \"$CONFIG_HEADERS\"\n\n\neval set X \"  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS\"\nshift\nfor ac_tag\ndo\n  case $ac_tag in\n  :[FHLC]) ac_mode=$ac_tag; continue;;\n  esac\n  case $ac_mode$ac_tag in\n  :[FHL]*:*);;\n  :L* | :C*:*) as_fn_error \"invalid tag \\`$ac_tag'\" \"$LINENO\" 5;;\n  :[FH]-) ac_tag=-:-;;\n  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;\n  esac\n  ac_save_IFS=$IFS\n  IFS=:\n  set x $ac_tag\n  IFS=$ac_save_IFS\n  shift\n  ac_file=$1\n  shift\n\n  case $ac_mode in\n  :L) ac_source=$1;;\n  :[FH])\n    ac_file_inputs=\n    for ac_f\n    do\n      case $ac_f in\n      -) ac_f=\"$tmp/stdin\";;\n      *) # Look for the file first in the build tree, then in the source tree\n\t # (if the path is not absolute).  The absolute path cannot be DOS-style,\n\t # because $ac_f cannot contain `:'.\n\t test -f \"$ac_f\" ||\n\t   case $ac_f in\n\t   [\\\\/$]*) false;;\n\t   *) test -f \"$srcdir/$ac_f\" && ac_f=\"$srcdir/$ac_f\";;\n\t   esac ||\n\t   as_fn_error \"cannot find input file: \\`$ac_f'\" \"$LINENO\" 5;;\n      esac\n      case $ac_f in *\\'*) ac_f=`$as_echo \"$ac_f\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; esac\n      as_fn_append ac_file_inputs \" '$ac_f'\"\n    done\n\n    # Let's still pretend it is `configure' which instantiates (i.e., don't\n    # use $as_me), people would be surprised to read:\n    #    /* config.h.  Generated by config.status.  */\n    configure_input='Generated from '`\n\t  $as_echo \"$*\" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'\n\t`' by configure.'\n    if test x\"$ac_file\" != x-; then\n      configure_input=\"$ac_file.  $configure_input\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: creating $ac_file\" >&5\n$as_echo \"$as_me: creating $ac_file\" >&6;}\n    fi\n    # Neutralize special characters interpreted by sed in replacement strings.\n    case $configure_input in #(\n    *\\&* | *\\|* | *\\\\* )\n       ac_sed_conf_input=`$as_echo \"$configure_input\" |\n       sed 's/[\\\\\\\\&|]/\\\\\\\\&/g'`;; #(\n    *) ac_sed_conf_input=$configure_input;;\n    esac\n\n    case $ac_tag in\n    *:-:* | *:-) cat >\"$tmp/stdin\" \\\n      || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5 ;;\n    esac\n    ;;\n  esac\n\n  ac_dir=`$as_dirname -- \"$ac_file\" ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  as_dir=\"$ac_dir\"; as_fn_mkdir_p\n  ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n\n  case $ac_mode in\n  :F)\n  #\n  # CONFIG_FILE\n  #\n\n  case $INSTALL in\n  [\\\\/$]* | ?:[\\\\/]* ) ac_INSTALL=$INSTALL ;;\n  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;\n  esac\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# If the template does not know about datarootdir, expand it.\n# FIXME: This hack should be removed a few years after 2.60.\nac_datarootdir_hack=; ac_datarootdir_seen=\nac_sed_dataroot='\n/datarootdir/ {\n  p\n  q\n}\n/@datadir@/p\n/@docdir@/p\n/@infodir@/p\n/@localedir@/p\n/@mandir@/p'\ncase `eval \"sed -n \\\"\\$ac_sed_dataroot\\\" $ac_file_inputs\"` in\n*datarootdir*) ac_datarootdir_seen=yes;;\n*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&5\n$as_echo \"$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&2;}\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  ac_datarootdir_hack='\n  s&@datadir@&$datadir&g\n  s&@docdir@&$docdir&g\n  s&@infodir@&$infodir&g\n  s&@localedir@&$localedir&g\n  s&@mandir@&$mandir&g\n  s&\\\\\\${datarootdir}&$datarootdir&g' ;;\nesac\n_ACEOF\n\n# Neutralize VPATH when `$srcdir' = `.'.\n# Shell code in configure.ac might set extrasub.\n# FIXME: do we really want to maintain this feature?\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_sed_extra=\"$ac_vpsub\n$extrasub\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n:t\n/@[a-zA-Z_][a-zA-Z_0-9]*@/!b\ns|@configure_input@|$ac_sed_conf_input|;t t\ns&@top_builddir@&$ac_top_builddir_sub&;t t\ns&@top_build_prefix@&$ac_top_build_prefix&;t t\ns&@srcdir@&$ac_srcdir&;t t\ns&@abs_srcdir@&$ac_abs_srcdir&;t t\ns&@top_srcdir@&$ac_top_srcdir&;t t\ns&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t\ns&@builddir@&$ac_builddir&;t t\ns&@abs_builddir@&$ac_abs_builddir&;t t\ns&@abs_top_builddir@&$ac_abs_top_builddir&;t t\ns&@INSTALL@&$ac_INSTALL&;t t\n$ac_datarootdir_hack\n\"\neval sed \\\"\\$ac_sed_extra\\\" \"$ac_file_inputs\" | $AWK -f \"$tmp/subs.awk\" >$tmp/out \\\n  || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n\ntest -z \"$ac_datarootdir_hack$ac_datarootdir_seen\" &&\n  { ac_out=`sed -n '/\\${datarootdir}/p' \"$tmp/out\"`; test -n \"$ac_out\"; } &&\n  { ac_out=`sed -n '/^[\t ]*datarootdir[\t ]*:*=/p' \"$tmp/out\"`; test -z \"$ac_out\"; } &&\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined.\" >&5\n$as_echo \"$as_me: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined.\" >&2;}\n\n  rm -f \"$tmp/stdin\"\n  case $ac_file in\n  -) cat \"$tmp/out\" && rm -f \"$tmp/out\";;\n  *) rm -f \"$ac_file\" && mv \"$tmp/out\" \"$ac_file\";;\n  esac \\\n  || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n ;;\n  :H)\n  #\n  # CONFIG_HEADER\n  #\n  if test x\"$ac_file\" != x-; then\n    {\n      $as_echo \"/* $configure_input  */\" \\\n      && eval '$AWK -f \"$tmp/defines.awk\"' \"$ac_file_inputs\"\n    } >\"$tmp/config.h\" \\\n      || as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n    if diff \"$ac_file\" \"$tmp/config.h\" >/dev/null 2>&1; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: $ac_file is unchanged\" >&5\n$as_echo \"$as_me: $ac_file is unchanged\" >&6;}\n    else\n      rm -f \"$ac_file\"\n      mv \"$tmp/config.h\" \"$ac_file\" \\\n\t|| as_fn_error \"could not create $ac_file\" \"$LINENO\" 5\n    fi\n  else\n    $as_echo \"/* $configure_input  */\" \\\n      && eval '$AWK -f \"$tmp/defines.awk\"' \"$ac_file_inputs\" \\\n      || as_fn_error \"could not create -\" \"$LINENO\" 5\n  fi\n# Compute \"$ac_file\"'s index in $config_headers.\n_am_stamp_count=1\nfor _am_header in $config_headers :; do\n  case $_am_header in\n    \"$ac_file\" | \"$ac_file\":* )\n      break ;;\n    * )\n      _am_stamp_count=`expr $_am_stamp_count + 1` ;;\n  esac\ndone\necho \"timestamp for \"$ac_file\"\" >`$as_dirname -- \"$ac_file\" ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`/stamp-h$_am_stamp_count\n ;;\n\n  :C)  { $as_echo \"$as_me:${as_lineno-$LINENO}: executing $ac_file commands\" >&5\n$as_echo \"$as_me: executing $ac_file commands\" >&6;}\n ;;\n  esac\n\n\n  case $ac_file$ac_mode in\n    \"depfiles\":C) test x\"$AMDEP_TRUE\" != x\"\" || for mf in $CONFIG_FILES; do\n  # Strip MF so we end up with the name of the file.\n  mf=`echo \"$mf\" | sed -e 's/:.*$//'`\n  # Check whether this is an Automake generated Makefile or not.\n  # We used to match only the files named `Makefile.in', but\n  # some people rename them; so instead we look at the file content.\n  # Grep'ing the first line is not enough: some people post-process\n  # each Makefile.in and add a new line on top of each file to say so.\n  # So let's grep whole file.\n  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then\n    dirpart=`$as_dirname -- \"$mf\" ||\n$as_expr X\"$mf\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$mf\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$mf\" : 'X\\(//\\)$' \\| \\\n\t X\"$mf\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$mf\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  else\n    continue\n  fi\n  # Extract the definition of DEPDIR, am__include, and am__quote\n  # from the Makefile without running `make'.\n  DEPDIR=`sed -n 's/^DEPDIR = //p' < \"$mf\"`\n  test -z \"$DEPDIR\" && continue\n  am__include=`sed -n 's/^am__include = //p' < \"$mf\"`\n  test -z \"am__include\" && continue\n  am__quote=`sed -n 's/^am__quote = //p' < \"$mf\"`\n  # When using ansi2knr, U may be empty or an underscore; expand it\n  U=`sed -n 's/^U = //p' < \"$mf\"`\n  # Find all dependency output files, they are included files with\n  # $(DEPDIR) in their names.  We invoke sed twice because it is the\n  # simplest approach to changing $(DEPDIR) to its actual value in the\n  # expansion.\n  for file in `sed -n \"\n    s/^$am__include $am__quote\\(.*(DEPDIR).*\\)$am__quote\"'$/\\1/p' <\"$mf\" | \\\n       sed -e 's/\\$(DEPDIR)/'\"$DEPDIR\"'/g' -e 's/\\$U/'\"$U\"'/g'`; do\n    # Make sure the directory exists.\n    test -f \"$dirpart/$file\" && continue\n    fdir=`$as_dirname -- \"$file\" ||\n$as_expr X\"$file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$file\" : 'X\\(//\\)$' \\| \\\n\t X\"$file\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n    as_dir=$dirpart/$fdir; as_fn_mkdir_p\n    # echo \"creating $dirpart/$file\"\n    echo '# dummy' > \"$dirpart/$file\"\n  done\ndone\n ;;\n    \"libtool\":C)\n\n    # See if we are running on zsh, and set the options which allow our\n    # commands through without removal of \\ escapes.\n    if test -n \"${ZSH_VERSION+set}\" ; then\n      setopt NO_GLOB_SUBST\n    fi\n\n    cfgfile=\"${ofile}T\"\n    trap \"$RM \\\"$cfgfile\\\"; exit 1\" 1 2 15\n    $RM \"$cfgfile\"\n\n    cat <<_LT_EOF >> \"$cfgfile\"\n#! $SHELL\n\n# `$ECHO \"$ofile\" | sed 's%^.*/%%'` - Provide generalized library-building support services.\n# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION\n# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:\n# NOTE: Changes made to this file will be lost: look at ltmain.sh.\n#\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008 Free Software Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n#   This file is part of GNU Libtool.\n#\n# GNU Libtool is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html, or\n# obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n\n# The names of the tagged configurations supported by this script.\navailable_tags=\"CXX \"\n\n# ### BEGIN LIBTOOL CONFIG\n\n# Whether or not to optimize for fast installation.\nfast_install=$enable_fast_install\n\n# Which release of libtool.m4 was used?\nmacro_version=$macro_version\nmacro_revision=$macro_revision\n\n# Whether or not to build shared libraries.\nbuild_libtool_libs=$enable_shared\n\n# Whether or not to build static libraries.\nbuild_old_libs=$enable_static\n\n# What type of objects to build.\npic_mode=$pic_mode\n\n# The host system.\nhost_alias=$host_alias\nhost=$host\nhost_os=$host_os\n\n# The build system.\nbuild_alias=$build_alias\nbuild=$build\nbuild_os=$build_os\n\n# A sed program that does not truncate output.\nSED=$lt_SED\n\n# Sed that helps us avoid accidentally triggering echo(1) options like -n.\nXsed=\"\\$SED -e 1s/^X//\"\n\n# A grep program that handles long lines.\nGREP=$lt_GREP\n\n# An ERE matcher.\nEGREP=$lt_EGREP\n\n# A literal string matcher.\nFGREP=$lt_FGREP\n\n# A BSD- or MS-compatible name lister.\nNM=$lt_NM\n\n# Whether we need soft or hard links.\nLN_S=$lt_LN_S\n\n# What is the maximum length of a command?\nmax_cmd_len=$max_cmd_len\n\n# Object file suffix (normally \"o\").\nobjext=$ac_objext\n\n# Executable file suffix (normally \"\").\nexeext=$exeext\n\n# whether the shell understands \"unset\".\nlt_unset=$lt_unset\n\n# turn spaces into newlines.\nSP2NL=$lt_lt_SP2NL\n\n# turn newlines into spaces.\nNL2SP=$lt_lt_NL2SP\n\n# How to create reloadable object files.\nreload_flag=$lt_reload_flag\nreload_cmds=$lt_reload_cmds\n\n# An object symbol dumper.\nOBJDUMP=$lt_OBJDUMP\n\n# Method to check whether dependent libraries are shared objects.\ndeplibs_check_method=$lt_deplibs_check_method\n\n# Command to use when deplibs_check_method == \"file_magic\".\nfile_magic_cmd=$lt_file_magic_cmd\n\n# The archiver.\nAR=$lt_AR\nAR_FLAGS=$lt_AR_FLAGS\n\n# A symbol stripping program.\nSTRIP=$lt_STRIP\n\n# Commands used to install an old-style archive.\nRANLIB=$lt_RANLIB\nold_postinstall_cmds=$lt_old_postinstall_cmds\nold_postuninstall_cmds=$lt_old_postuninstall_cmds\n\n# A C compiler.\nLTCC=$lt_CC\n\n# LTCC compiler flags.\nLTCFLAGS=$lt_CFLAGS\n\n# Take the output of nm and produce a listing of raw symbols and C names.\nglobal_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe\n\n# Transform the output of nm in a proper C declaration.\nglobal_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl\n\n# Transform the output of nm in a C name address pair.\nglobal_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address\n\n# Transform the output of nm in a C name address pair when lib prefix is needed.\nglobal_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix\n\n# The name of the directory that contains temporary libtool files.\nobjdir=$objdir\n\n# Shell to use when invoking shell scripts.\nSHELL=$lt_SHELL\n\n# An echo program that does not interpret backslashes.\nECHO=$lt_ECHO\n\n# Used to examine libraries when file_magic_cmd begins with \"file\".\nMAGIC_CMD=$MAGIC_CMD\n\n# Must we lock files when doing compilation?\nneed_locks=$lt_need_locks\n\n# Tool to manipulate archived DWARF debug symbol files on Mac OS X.\nDSYMUTIL=$lt_DSYMUTIL\n\n# Tool to change global to local symbols on Mac OS X.\nNMEDIT=$lt_NMEDIT\n\n# Tool to manipulate fat objects and archives on Mac OS X.\nLIPO=$lt_LIPO\n\n# ldd/readelf like tool for Mach-O binaries on Mac OS X.\nOTOOL=$lt_OTOOL\n\n# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.\nOTOOL64=$lt_OTOOL64\n\n# Old archive suffix (normally \"a\").\nlibext=$libext\n\n# Shared library suffix (normally \".so\").\nshrext_cmds=$lt_shrext_cmds\n\n# The commands to extract the exported symbol list from a shared archive.\nextract_expsyms_cmds=$lt_extract_expsyms_cmds\n\n# Variables whose values should be saved in libtool wrapper scripts and\n# restored at link time.\nvariables_saved_for_relink=$lt_variables_saved_for_relink\n\n# Do we need the \"lib\" prefix for modules?\nneed_lib_prefix=$need_lib_prefix\n\n# Do we need a version for libraries?\nneed_version=$need_version\n\n# Library versioning type.\nversion_type=$version_type\n\n# Shared library runtime path variable.\nrunpath_var=$runpath_var\n\n# Shared library path variable.\nshlibpath_var=$shlibpath_var\n\n# Is shlibpath searched before the hard-coded library search path?\nshlibpath_overrides_runpath=$shlibpath_overrides_runpath\n\n# Format of library name prefix.\nlibname_spec=$lt_libname_spec\n\n# List of archive names.  First name is the real one, the rest are links.\n# The last name is the one that the linker finds with -lNAME\nlibrary_names_spec=$lt_library_names_spec\n\n# The coded name of the library, if different from the real name.\nsoname_spec=$lt_soname_spec\n\n# Command to use after installation of a shared archive.\npostinstall_cmds=$lt_postinstall_cmds\n\n# Command to use after uninstallation of a shared archive.\npostuninstall_cmds=$lt_postuninstall_cmds\n\n# Commands used to finish a libtool library installation in a directory.\nfinish_cmds=$lt_finish_cmds\n\n# As \"finish_cmds\", except a single script fragment to be evaled but\n# not shown.\nfinish_eval=$lt_finish_eval\n\n# Whether we should hardcode library paths into libraries.\nhardcode_into_libs=$hardcode_into_libs\n\n# Compile-time system search path for libraries.\nsys_lib_search_path_spec=$lt_sys_lib_search_path_spec\n\n# Run-time system search path for libraries.\nsys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec\n\n# Whether dlopen is supported.\ndlopen_support=$enable_dlopen\n\n# Whether dlopen of programs is supported.\ndlopen_self=$enable_dlopen_self\n\n# Whether dlopen of statically linked programs is supported.\ndlopen_self_static=$enable_dlopen_self_static\n\n# Commands to strip libraries.\nold_striplib=$lt_old_striplib\nstriplib=$lt_striplib\n\n\n# The linker used to build libraries.\nLD=$lt_LD\n\n# Commands used to build an old-style archive.\nold_archive_cmds=$lt_old_archive_cmds\n\n# A language specific compiler.\nCC=$lt_compiler\n\n# Is the compiler the GNU compiler?\nwith_gcc=$GCC\n\n# Compiler flag to turn off builtin functions.\nno_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag\n\n# How to pass a linker flag through the compiler.\nwl=$lt_lt_prog_compiler_wl\n\n# Additional compiler flags for building library objects.\npic_flag=$lt_lt_prog_compiler_pic\n\n# Compiler flag to prevent dynamic linking.\nlink_static_flag=$lt_lt_prog_compiler_static\n\n# Does compiler simultaneously support -c and -o options?\ncompiler_c_o=$lt_lt_cv_prog_compiler_c_o\n\n# Whether or not to add -lc for building shared libraries.\nbuild_libtool_need_lc=$archive_cmds_need_lc\n\n# Whether or not to disallow shared libs when runtime libs are static.\nallow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes\n\n# Compiler flag to allow reflexive dlopens.\nexport_dynamic_flag_spec=$lt_export_dynamic_flag_spec\n\n# Compiler flag to generate shared objects directly from archives.\nwhole_archive_flag_spec=$lt_whole_archive_flag_spec\n\n# Whether the compiler copes with passing no objects directly.\ncompiler_needs_object=$lt_compiler_needs_object\n\n# Create an old-style archive from a shared archive.\nold_archive_from_new_cmds=$lt_old_archive_from_new_cmds\n\n# Create a temporary old-style archive to link instead of a shared archive.\nold_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds\n\n# Commands used to build a shared archive.\narchive_cmds=$lt_archive_cmds\narchive_expsym_cmds=$lt_archive_expsym_cmds\n\n# Commands used to build a loadable module if different from building\n# a shared archive.\nmodule_cmds=$lt_module_cmds\nmodule_expsym_cmds=$lt_module_expsym_cmds\n\n# Whether we are building with GNU ld or not.\nwith_gnu_ld=$lt_with_gnu_ld\n\n# Flag that allows shared libraries with undefined symbols to be built.\nallow_undefined_flag=$lt_allow_undefined_flag\n\n# Flag that enforces no undefined symbols.\nno_undefined_flag=$lt_no_undefined_flag\n\n# Flag to hardcode \\$libdir into a binary during linking.\n# This must work even if \\$libdir does not exist\nhardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec\n\n# If ld is used when linking, flag to hardcode \\$libdir into a binary\n# during linking.  This must work even if \\$libdir does not exist.\nhardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld\n\n# Whether we need a single \"-rpath\" flag with a separated argument.\nhardcode_libdir_separator=$lt_hardcode_libdir_separator\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary.\nhardcode_direct=$hardcode_direct\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary and the resulting library dependency is\n# \"absolute\",i.e impossible to change by setting \\${shlibpath_var} if the\n# library is relocated.\nhardcode_direct_absolute=$hardcode_direct_absolute\n\n# Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n# into the resulting binary.\nhardcode_minus_L=$hardcode_minus_L\n\n# Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n# into the resulting binary.\nhardcode_shlibpath_var=$hardcode_shlibpath_var\n\n# Set to \"yes\" if building a shared library automatically hardcodes DIR\n# into the library and all subsequent libraries and executables linked\n# against it.\nhardcode_automatic=$hardcode_automatic\n\n# Set to yes if linker adds runtime paths of dependent libraries\n# to runtime path list.\ninherit_rpath=$inherit_rpath\n\n# Whether libtool must link a program against all its dependency libraries.\nlink_all_deplibs=$link_all_deplibs\n\n# Fix the shell variable \\$srcfile for the compiler.\nfix_srcfile_path=$lt_fix_srcfile_path\n\n# Set to \"yes\" if exported symbols are required.\nalways_export_symbols=$always_export_symbols\n\n# The commands to list exported symbols.\nexport_symbols_cmds=$lt_export_symbols_cmds\n\n# Symbols that should not be listed in the preloaded symbols.\nexclude_expsyms=$lt_exclude_expsyms\n\n# Symbols that must always be exported.\ninclude_expsyms=$lt_include_expsyms\n\n# Commands necessary for linking programs (against libraries) with templates.\nprelink_cmds=$lt_prelink_cmds\n\n# Specify filename containing input files.\nfile_list_spec=$lt_file_list_spec\n\n# How to hardcode a shared library path into an executable.\nhardcode_action=$hardcode_action\n\n# The directories searched by this compiler when creating a shared library.\ncompiler_lib_search_dirs=$lt_compiler_lib_search_dirs\n\n# Dependencies to place before and after the objects being linked to\n# create a shared library.\npredep_objects=$lt_predep_objects\npostdep_objects=$lt_postdep_objects\npredeps=$lt_predeps\npostdeps=$lt_postdeps\n\n# The library search path used internally by the compiler when linking\n# a shared library.\ncompiler_lib_search_path=$lt_compiler_lib_search_path\n\n# ### END LIBTOOL CONFIG\n\n_LT_EOF\n\n  case $host_os in\n  aix3*)\n    cat <<\\_LT_EOF >> \"$cfgfile\"\n# AIX sometimes has problems with the GCC collect2 program.  For some\n# reason, if we set the COLLECT_NAMES environment variable, the problems\n# vanish in a puff of smoke.\nif test \"X${COLLECT_NAMES+set}\" != Xset; then\n  COLLECT_NAMES=\n  export COLLECT_NAMES\nfi\n_LT_EOF\n    ;;\n  esac\n\n\nltmain=\"$ac_aux_dir/ltmain.sh\"\n\n\n  # We use sed instead of cat because bash on DJGPP gets confused if\n  # if finds mixed CR/LF and LF-only lines.  Since sed operates in\n  # text mode, it properly converts lines to CR/LF.  This bash problem\n  # is reportedly fixed, but why not run on old versions too?\n  sed '/^# Generated shell functions inserted here/q' \"$ltmain\" >> \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\"; exit 1)\n\n  case $xsi_shell in\n  yes)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_dirname_and_basename file append nondir_replacement\n# perform func_basename and func_dirname in a single function\n# call:\n#   dirname:  Compute the dirname of FILE.  If nonempty,\n#             add APPEND to the result, otherwise set result\n#             to NONDIR_REPLACEMENT.\n#             value returned in \"$func_dirname_result\"\n#   basename: Compute filename of FILE.\n#             value retuned in \"$func_basename_result\"\n# Implementation must be kept synchronized with func_dirname\n# and func_basename. For efficiency, we do not delegate to\n# those functions but instead duplicate the functionality here.\nfunc_dirname_and_basename ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\nfunc_stripname ()\n{\n  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\n  # positional parameters, so assign one to ordinary parameter first.\n  func_stripname_result=${3}\n  func_stripname_result=${func_stripname_result#\"${1}\"}\n  func_stripname_result=${func_stripname_result%\"${2}\"}\n}\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=${1%%=*}\n  func_opt_split_arg=${1#*=}\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  case ${1} in\n    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\n    *)    func_lo2o_result=${1} ;;\n  esac\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=${1%.*}.lo\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=$(( $* ))\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=${#1}\n}\n\n_LT_EOF\n    ;;\n  *) # Bourne compatible functions.\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  # Extract subdirectory from the argument.\n  func_dirname_result=`$ECHO \"X${1}\" | $Xsed -e \"$dirname\"`\n  if test \"X$func_dirname_result\" = \"X${1}\"; then\n    func_dirname_result=\"${3}\"\n  else\n    func_dirname_result=\"$func_dirname_result${2}\"\n  fi\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=`$ECHO \"X${1}\" | $Xsed -e \"$basename\"`\n}\n\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\n# func_strip_suffix prefix name\nfunc_stripname ()\n{\n  case ${2} in\n    .*) func_stripname_result=`$ECHO \"X${3}\" \\\n           | $Xsed -e \"s%^${1}%%\" -e \"s%\\\\\\\\${2}\\$%%\"`;;\n    *)  func_stripname_result=`$ECHO \"X${3}\" \\\n           | $Xsed -e \"s%^${1}%%\" -e \"s%${2}\\$%%\"`;;\n  esac\n}\n\n# sed scripts:\nmy_sed_long_opt='1s/^\\(-[^=]*\\)=.*/\\1/;q'\nmy_sed_long_arg='1s/^-[^=]*=//'\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=`$ECHO \"X${1}\" | $Xsed -e \"$my_sed_long_opt\"`\n  func_opt_split_arg=`$ECHO \"X${1}\" | $Xsed -e \"$my_sed_long_arg\"`\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  func_lo2o_result=`$ECHO \"X${1}\" | $Xsed -e \"$lo2o\"`\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=`$ECHO \"X${1}\" | $Xsed -e 's/\\.[^.]*$/.lo/'`\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=`expr \"$@\"`\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=`expr \"$1\" : \".*\" 2>/dev/null || echo $max_cmd_len`\n}\n\n_LT_EOF\nesac\n\ncase $lt_shell_append in\n  yes)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$1+=\\$2\"\n}\n_LT_EOF\n    ;;\n  *)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$1=\\$$1\\$2\"\n}\n\n_LT_EOF\n    ;;\n  esac\n\n\n  sed -n '/^# Generated shell functions inserted here/,$p' \"$ltmain\" >> \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\"; exit 1)\n\n  mv -f \"$cfgfile\" \"$ofile\" ||\n    (rm -f \"$ofile\" && cp \"$cfgfile\" \"$ofile\" && rm -f \"$cfgfile\")\n  chmod +x \"$ofile\"\n\n\n    cat <<_LT_EOF >> \"$ofile\"\n\n# ### BEGIN LIBTOOL TAG CONFIG: CXX\n\n# The linker used to build libraries.\nLD=$lt_LD_CXX\n\n# Commands used to build an old-style archive.\nold_archive_cmds=$lt_old_archive_cmds_CXX\n\n# A language specific compiler.\nCC=$lt_compiler_CXX\n\n# Is the compiler the GNU compiler?\nwith_gcc=$GCC_CXX\n\n# Compiler flag to turn off builtin functions.\nno_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX\n\n# How to pass a linker flag through the compiler.\nwl=$lt_lt_prog_compiler_wl_CXX\n\n# Additional compiler flags for building library objects.\npic_flag=$lt_lt_prog_compiler_pic_CXX\n\n# Compiler flag to prevent dynamic linking.\nlink_static_flag=$lt_lt_prog_compiler_static_CXX\n\n# Does compiler simultaneously support -c and -o options?\ncompiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX\n\n# Whether or not to add -lc for building shared libraries.\nbuild_libtool_need_lc=$archive_cmds_need_lc_CXX\n\n# Whether or not to disallow shared libs when runtime libs are static.\nallow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX\n\n# Compiler flag to allow reflexive dlopens.\nexport_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX\n\n# Compiler flag to generate shared objects directly from archives.\nwhole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX\n\n# Whether the compiler copes with passing no objects directly.\ncompiler_needs_object=$lt_compiler_needs_object_CXX\n\n# Create an old-style archive from a shared archive.\nold_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX\n\n# Create a temporary old-style archive to link instead of a shared archive.\nold_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX\n\n# Commands used to build a shared archive.\narchive_cmds=$lt_archive_cmds_CXX\narchive_expsym_cmds=$lt_archive_expsym_cmds_CXX\n\n# Commands used to build a loadable module if different from building\n# a shared archive.\nmodule_cmds=$lt_module_cmds_CXX\nmodule_expsym_cmds=$lt_module_expsym_cmds_CXX\n\n# Whether we are building with GNU ld or not.\nwith_gnu_ld=$lt_with_gnu_ld_CXX\n\n# Flag that allows shared libraries with undefined symbols to be built.\nallow_undefined_flag=$lt_allow_undefined_flag_CXX\n\n# Flag that enforces no undefined symbols.\nno_undefined_flag=$lt_no_undefined_flag_CXX\n\n# Flag to hardcode \\$libdir into a binary during linking.\n# This must work even if \\$libdir does not exist\nhardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX\n\n# If ld is used when linking, flag to hardcode \\$libdir into a binary\n# during linking.  This must work even if \\$libdir does not exist.\nhardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX\n\n# Whether we need a single \"-rpath\" flag with a separated argument.\nhardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary.\nhardcode_direct=$hardcode_direct_CXX\n\n# Set to \"yes\" if using DIR/libNAME\\${shared_ext} during linking hardcodes\n# DIR into the resulting binary and the resulting library dependency is\n# \"absolute\",i.e impossible to change by setting \\${shlibpath_var} if the\n# library is relocated.\nhardcode_direct_absolute=$hardcode_direct_absolute_CXX\n\n# Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n# into the resulting binary.\nhardcode_minus_L=$hardcode_minus_L_CXX\n\n# Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n# into the resulting binary.\nhardcode_shlibpath_var=$hardcode_shlibpath_var_CXX\n\n# Set to \"yes\" if building a shared library automatically hardcodes DIR\n# into the library and all subsequent libraries and executables linked\n# against it.\nhardcode_automatic=$hardcode_automatic_CXX\n\n# Set to yes if linker adds runtime paths of dependent libraries\n# to runtime path list.\ninherit_rpath=$inherit_rpath_CXX\n\n# Whether libtool must link a program against all its dependency libraries.\nlink_all_deplibs=$link_all_deplibs_CXX\n\n# Fix the shell variable \\$srcfile for the compiler.\nfix_srcfile_path=$lt_fix_srcfile_path_CXX\n\n# Set to \"yes\" if exported symbols are required.\nalways_export_symbols=$always_export_symbols_CXX\n\n# The commands to list exported symbols.\nexport_symbols_cmds=$lt_export_symbols_cmds_CXX\n\n# Symbols that should not be listed in the preloaded symbols.\nexclude_expsyms=$lt_exclude_expsyms_CXX\n\n# Symbols that must always be exported.\ninclude_expsyms=$lt_include_expsyms_CXX\n\n# Commands necessary for linking programs (against libraries) with templates.\nprelink_cmds=$lt_prelink_cmds_CXX\n\n# Specify filename containing input files.\nfile_list_spec=$lt_file_list_spec_CXX\n\n# How to hardcode a shared library path into an executable.\nhardcode_action=$hardcode_action_CXX\n\n# The directories searched by this compiler when creating a shared library.\ncompiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX\n\n# Dependencies to place before and after the objects being linked to\n# create a shared library.\npredep_objects=$lt_predep_objects_CXX\npostdep_objects=$lt_postdep_objects_CXX\npredeps=$lt_predeps_CXX\npostdeps=$lt_postdeps_CXX\n\n# The library search path used internally by the compiler when linking\n# a shared library.\ncompiler_lib_search_path=$lt_compiler_lib_search_path_CXX\n\n# ### END LIBTOOL TAG CONFIG: CXX\n_LT_EOF\n\n ;;\n\n  esac\ndone # for ac_tag\n\n\nas_fn_exit 0\n_ACEOF\nac_clean_files=$ac_clean_files_save\n\ntest $ac_write_fail = 0 ||\n  as_fn_error \"write failure creating $CONFIG_STATUS\" \"$LINENO\" 5\n\n\n# configure is writing to config.log, and then calls config.status.\n# config.status does its own redirection, appending to config.log.\n# Unfortunately, on DOS this fails, as config.log is still kept open\n# by configure, so config.status won't be able to write to it; its\n# output is simply discarded.  So we exec the FD to /dev/null,\n# effectively closing config.log, so it can be properly (re)opened and\n# appended to by config.status.  When coming back to configure, we\n# need to make the FD available again.\nif test \"$no_create\" != yes; then\n  ac_cs_success=:\n  ac_config_status_args=\n  test \"$silent\" = yes &&\n    ac_config_status_args=\"$ac_config_status_args --quiet\"\n  exec 5>/dev/null\n  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false\n  exec 5>>config.log\n  # Use ||, not &&, to avoid exiting from the if with $? = 1, which\n  # would make configure fail if this is the last instruction.\n  $ac_cs_success || as_fn_exit $?\nfi\nif test -n \"$ac_unrecognized_opts\" && test \"$enable_option_checking\" != no; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts\" >&5\n$as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2;}\nfi\n\n"
  },
  {
    "path": "distro/google-perftools-1.7/configure.ac",
    "content": "## Process this file with autoconf to produce configure.\n## In general, the safest way to proceed is to run ./autogen.sh\n\n# make sure we're interpreted by some minimal autoconf\nAC_PREREQ(2.57)\n\nAC_INIT(google-perftools, 1.7, opensource@google.com)\n# Update this value for every release!  (A:B:C will map to foo.so.(A-C).C.B)\n# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html\nTCMALLOC_SO_VERSION=1:0:1\nPROFILER_SO_VERSION=1:0:1\n\nAC_SUBST(TCMALLOC_SO_VERSION)\nAC_SUBST(PROFILER_SO_VERSION)\n\n# The argument here is just something that should be in the current directory\n# (for sanity checking)\nAC_CONFIG_SRCDIR(README)\nAC_CONFIG_MACRO_DIR([m4])\nAC_CANONICAL_HOST\nAM_INIT_AUTOMAKE([dist-zip])\nAM_CONFIG_HEADER(src/config.h)\n\n# Export the version information (for tc_version and friends)\nTC_VERSION_MAJOR=`expr \"$PACKAGE_VERSION\" : '\\([[0-9]]*\\)'`\nTC_VERSION_MINOR=`expr \"$PACKAGE_VERSION\" : '[[^.]]*\\.\\([[0-9]]*\\)'`\nTC_VERSION_PATCH=`expr \"$PACKAGE_VERSION\" : '[[^.0-9]]*\\([[^0-9]]*\\)$'`\nAC_SUBST(TC_VERSION_MAJOR)\nAC_SUBST(TC_VERSION_MINOR)\nAC_SUBST(TC_VERSION_PATCH)\nAC_SUBST(PACKAGE_STRING)\n\n# The user can choose not to compile in the heap-profiler, the\n# heap-checker, or the cpu-profiler.  There's also the possibility\n# for a 'fully minimal' compile, which leaves out the stacktrace\n# code as well.  By default, we include all of these that the\n# target system supports.\ndefault_enable_cpu_profiler=yes\ndefault_enable_heap_profiler=yes\ndefault_enable_heap_checker=yes\ndefault_enable_debugalloc=yes\ndefault_enable_minimal=no\nneed_nanosleep=yes   # Used later, to decide if to run ACX_NANOSLEEP\ncase \"$host\" in\n   *-mingw*) default_enable_minimal=yes; default_enable_debugalloc=no;\n             need_nanosleep=no;;\n   *-cygwin*) default_enable_heap_checker=no; default_enable_cpu_profiler=no;;\n   *-freebsd*) default_enable_heap_checker=no;;\n   *-darwin*) default_enable_heap_checker=no;;\nesac\n\nAC_ARG_ENABLE([cpu-profiler],\n              [AS_HELP_STRING([--disable-cpu-profiler],\n                              [do not build the cpu profiler])],\n              [],\n              [enable_cpu_profiler=\"$default_enable_cpu_profiler\"])\nAC_ARG_ENABLE([heap-profiler],\n              [AS_HELP_STRING([--disable-heap-profiler],\n                              [do not build the heap profiler])],\n              [],\n              [enable_heap_profiler=\"$default_enable_heap_profiler\"])\nAC_ARG_ENABLE([heap-checker],\n              [AS_HELP_STRING([--disable-heap-checker],\n                              [do not build the heap checker])],\n              [],\n              [enable_heap_checker=\"$default_enable_heap_checker\"])\nAC_ARG_ENABLE([debugalloc],\n              [AS_HELP_STRING([--disable-debugalloc],\n                              [do not build versions of libs with debugalloc])],\n              [],\n              [enable_debugalloc=\"$default_enable_debugalloc\"])\nAC_ARG_ENABLE([minimal],\n              [AS_HELP_STRING([--enable-minimal],\n                              [build only tcmalloc-minimal (and maybe tcmalloc-minimal-debug)])],\n              [],\n              [enable_minimal=\"$default_enable_minimal\"])\nif test \"$enable_minimal\" = yes; then\n  enable_cpu_profiler=no\n  enable_heap_profiler=no\n  enable_heap_checker=no\nfi\n\n\n# Checks for programs.\nAC_PROG_CC\nAC_PROG_CPP\nAC_PROG_CXX\nAM_CONDITIONAL(GCC, test \"$GCC\" = yes)   # let the Makefile know if we're gcc\nAM_PROG_CC_C_O      # shrug: autogen.sh suddenly needs this for some reason\n\n# Check if we have an objcopy installed that supports -W\nAC_CHECK_TOOL([OBJCOPY], [objcopy], [])\nAM_CONDITIONAL(HAVE_OBJCOPY_WEAKEN, [\"$OBJCOPY\" -W malloc /bin/ls /dev/null])\n\ncase $host_os in\n  *mingw*)\n    # Disabling fast install keeps libtool from creating wrapper scripts\n    # around the executables it builds.  Such scripts have caused failures on\n    # MinGW.  Using this option means an extra link step is executed during\n    # \"make install\".\n    AC_DISABLE_FAST_INSTALL\n    ;;\n   *)\n    AC_ENABLE_FAST_INSTALL\n    ;;\nesac\n\nAC_PROG_LIBTOOL\nAC_SUBST(LIBTOOL_DEPS)\nAM_CONDITIONAL(USE_LIBTOOL, test \"x$LIBTOOL\" != \"x\")\n\nAC_C_INLINE\nAX_C___ATTRIBUTE__\n\n# Check whether some low-level functions/files are available\nAC_HEADER_STDC\n\n# TODO(csilvers): we could remove a lot when WITH_CPU_PROFILER etc is \"no\".\nAC_CHECK_TYPES([__int64])       # defined in some windows platforms\nAC_CHECK_TYPES([struct mallinfo],,, [#include <malloc.h>])\nAC_CHECK_TYPES([Elf32_Versym],,, [#include <elf.h>])   # for vdso_support.h\nAC_CHECK_FUNCS(sbrk)            # for tcmalloc to get memory\nAC_CHECK_FUNCS(geteuid)         # for turning off services when run as root\nAC_CHECK_HEADERS(features.h)    # for vdso_support.h\nAC_CHECK_HEADERS(malloc.h)      # some systems define stuff there, others not\nAC_CHECK_HEADERS(glob.h)        # for heap-profile-table (cleaning up profiles)\nAC_CHECK_HEADERS(execinfo.h)    # for stacktrace? and heapchecker_unittest\nAC_CHECK_HEADERS(libunwind.h)   # for stacktrace\nAC_CHECK_HEADERS(unwind.h)      # for stacktrace\nAC_CHECK_HEADERS(sched.h)       # for being nice in our spinlock code\nAC_CHECK_HEADERS(conflict-signal.h)      # defined on some windows platforms?\nAC_CHECK_HEADERS(sys/prctl.h)   # for thread_lister (needed by leak-checker)\nAC_CHECK_HEADERS(linux/ptrace.h)# also needed by leak-checker\nAC_CHECK_HEADERS(sys/syscall.h)\nAC_CHECK_HEADERS(sys/socket.h)  # optional; for forking out to symbolizer\nAC_CHECK_HEADERS(sys/wait.h)    # optional; for forking out to symbolizer\nAC_CHECK_HEADERS(poll.h)        # optional; for forking out to symbolizer\nAC_CHECK_HEADERS(fcntl.h)       # for tcmalloc_unittest\nAC_CHECK_HEADERS(grp.h)         # for heapchecker_unittest\nAC_CHECK_HEADERS(pwd.h)         # for heapchecker_unittest\nAC_CHECK_HEADERS(sys/resource.h)         # for memalign_unittest.cc\nAC_CHECK_HEADERS(valgrind.h)    # we have a local copy if this isn't found\n# We also need <ucontext.h>/<sys/ucontext.h>, but we get those from\n# AC_PC_FROM_UCONTEXT, below.\n\n# We override a lot of memory allocation routines, not all of which are\n# standard.  For those the system doesn't declare, we'll declare ourselves.\nAC_CHECK_DECLS([cfree,\n                posix_memalign,\n                memalign,\n                valloc,\n                pvalloc],,,\n               [#define _XOPEN_SOURCE 600\n                #include <stdlib.h>\n                #include <malloc.h>])\n\nif test \"$ac_cv_type_struct_mallinfo\" = yes; then\n  AC_SUBST(ac_cv_have_struct_mallinfo, 1)   # google/tcmalloc.h needs this\nelse\n  AC_SUBST(ac_cv_have_struct_mallinfo, 0)\nfi\n\n# We need to check for mmap.  cygwin supports mmap, but the autoconf\n# test doesn't work on cygwin:\n#    http://www.cygwin.com/ml/cygwin/2002-04/msg00412.html\n# This workaround comes from\n#    http://cygwin.com/ml/cygwin/2004-11/msg00138.html\ncase \"$host\" in\n  *-*-cygwin*) ac_cv_func_mmap_fixed_mapped=yes\n               AC_DEFINE(HAVE_MMAP, 1,\n                         [Define to 1 if you have a working `mmap' system call.])\n               ;;\n            *) AC_FUNC_MMAP\n               ;;\nesac\n\n# If AtomicWord != Atomic32, we need to define two versions of all the\n# atomicops functions.  If they're the same, we want to define only one.\nAC_MSG_CHECKING([if int32_t is the same type as intptr_t])\nAC_TRY_COMPILE([#include <stdint.h>],\n\t       [int32_t v1 = 0; intptr_t v2 = 0; return (&v1 - &v2)],\n               [AC_DEFINE(INT32_EQUALS_INTPTR, 1,\n                          Define to 1 if int32_t is equivalent to intptr_t)\n                AC_MSG_RESULT([yes])],\n               [AC_MSG_RESULT([no])])\n\n# We want to access the \"PC\" (Program Counter) register from a struct\n# ucontext.  Every system has its own way of doing that.  We try all the\n# possibilities we know about.  Note REG_PC should come first (REG_RIP\n# is also defined on solaris, but does the wrong thing).  But don't\n# bother if we're not doing cpu-profiling.\n# [*] means that we've not actually tested one of these systems\nif test \"$enable_cpu_profiler\" = yes; then\n  AC_PC_FROM_UCONTEXT(AC_MSG_WARN(Could not find the PC.  Will not try to compile libprofiler...);\n                      enable_cpu_profiler=no)\nfi\n\n# Some tests test the behavior of .so files, and only make sense for dynamic.\nAM_CONDITIONAL(ENABLE_STATIC, test \"$enable_static\" = yes)\n\n# We want to link in libunwind if it exists\nAC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind, UNWIND_LIBS=)\nAC_SUBST(UNWIND_LIBS)\n\n# On x86_64, instead of libunwind, we can choose to compile with frame-pointers\n# (This isn't needed on i386, where -fno-omit-frame-pointer is the default).\nAC_ARG_ENABLE(frame_pointers,\n              AS_HELP_STRING([--enable-frame-pointers],\n                             [On x86_64 systems, compile with -fno-omit-frame-pointer (see INSTALL)]),\n\t      , enable_frame_pointers=no)\nAM_CONDITIONAL(ENABLE_FRAME_POINTERS, test \"$enable_frame_pointers\" = yes)\n\n# Some x86_64 systems do not insert frame pointers by default (all\n# i386 systems that I know of, do.  I don't know about non-x86 chips).\n# We want to see if the current system is one of those.\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],\n                  [is_x86_64=yes], [is_x86_64=no])\nOLD_CFLAGS=\"$CFLAGS\"\nCFLAGS=\"$CFLAGS -S -O2 -o fp.s\"\n# This test will always fail because we don't name our output file properly.\n# We do our own determination of success/failure in the grep, below.\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([int f(int x) {return x;}], [return f(0);])],\n                  [:], [:])\nAM_CONDITIONAL(X86_64_AND_NO_FP_BY_DEFAULT,\n               test \"$is_x86_64\" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1)\nrm fp.s\nCFLAGS=\"$OLD_CFLAGS\"\n\n\n# Defines PRIuS\nAC_COMPILER_CHARACTERISTICS\n\n# Also make sure we get standard PRI... definitions, even with glibc.\n# We have to use AH_VERBATIM because we need the #ifdef guard (gcc buglet)\nAH_VERBATIM([__STDC_FORMAT_MACROS],\n            [/* C99 says: define this to get the PRI... macros from stdint.h */\n#ifndef __STDC_FORMAT_MACROS\n# define __STDC_FORMAT_MACROS 1\n#endif])\n\n# Check if __builtin_stack_pointer() is available (for elfcore.h)\nAC_MSG_CHECKING([for __builtin_stack_pointer()])\nAC_LINK_IFELSE([AC_LANG_PROGRAM(, [void *sp = __builtin_stack_pointer()])],\n               [AC_DEFINE(HAVE_BUILTIN_STACK_POINTER, 1,\n                      Define to 1 if compiler supports __builtin_stack_pointer)\n                AC_MSG_RESULT([yes])],\n               [AC_MSG_RESULT([no])])\n\n# Check if __environ is available (for GetenvBeforeMain)\nAC_MSG_CHECKING([for __environ])\nAC_LINK_IFELSE([AC_LANG_PROGRAM([#include <unistd.h>],\n                                [char **env = __environ])],\n               [AC_DEFINE(HAVE___ENVIRON, 1,\n                          [Define to 1 if compiler supports __environ])\n                AC_MSG_RESULT([yes])],\n               [AC_MSG_RESULT([no])])\n\n# If we support __thread, that can speed up tcmalloc a bit.\n# Note, however, that our code tickles a bug in gcc < 4.1.2\n# involving TLS and -fPIC (which our libraries will use) on x86:\n#   http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html\nAC_MSG_CHECKING([for __thread])\nAC_LINK_IFELSE([AC_LANG_PROGRAM([#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))\n#error gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html\n#endif], [static __thread int p = 0])],\n               [AC_DEFINE(HAVE_TLS, 1,\n                      Define to 1 if compiler supports __thread)\n                AC_MSG_RESULT([yes])],\n               [AC_MSG_RESULT([no])])\n\n# Nanosleep requires extra libraries on some architectures (solaris).\n# This sets NANOSLEEP_LIBS.  nanosleep doesn't exist on mingw, which\n# is fine for us because we don't compile libspinlock, which uses it.\nif test \"$need_nanosleep\" = yes; then\n  ACX_NANOSLEEP\n  AC_SUBST(NANOSLEEP_LIBS)\nfi\n\n# Solaris 10 6/06 has a bug where /usr/sfw/lib/libstdc++.la is empty.\n# If so, we replace it with our own version.\nLIBSTDCXX_LA_LINKER_FLAG=\nif test -f /usr/sfw/lib/libstdc++.la && ! test -s /usr/sfw/lib/libstdc++.la\nthen\n  LIBSTDCXX_LA_LINKER_FLAG='-L$(top_srcdir)/src/solaris'\nfi\nAC_SUBST(LIBSTDCXX_LA_LINKER_FLAG)\n\n# We also need to check if the kernel supports __thread, which requires uname()\nAC_CHECK_DECLS(uname,,, [#include <sys/utsname.h>])\n\n# In fact, a lot of the code in this directory depends on pthreads\nACX_PTHREAD\n\n# Find out what namespace 'normal' STL code lives in\nAC_CXX_STL_NAMESPACE\n\n# Figure out where libc has program_invocation_name\nAC_PROGRAM_INVOCATION_NAME\n\n# Make the install prefix available, to figure out where to look for pprof\nAC_INSTALL_PREFIX\n\n# For windows, this has a non-trivial value (__declspec(export)), but any\n# system that uses configure wants this to be the empty string.\nAC_DEFINE(PERFTOOLS_DLL_DECL,,\n          [Always the empty-string on non-windows systems.\n           On windows, should be \"__declspec(dllexport)\".\n\t   This way, when we compile the dll, we export our functions/classes.\n\t   It's safe to define this here because config.h is only used\n\t   internally, to compile the DLL, and every DLL source file\n\t   #includes \"config.h\" before anything else.])\n\n# In theory, config.h files shouldn't need a header guard, but we do,\n# because we (maybe) #include windows/mingw.h from within config.h,\n# and it #includes other .h files.  These all have header guards, so\n# the end result is if config.h is #included twice, its #undefs get\n# evaluated twice, but all the ones in mingw.h/etc only get evaluated\n# once, potentially causing trouble.  c.f.\n#   http://code.google.com/p/google-perftools/issues/detail?id=246\nAH_TOP([\n#ifndef GOOGLE_PERFTOOLS_CONFIG_H_\n#define GOOGLE_PERFTOOLS_CONFIG_H_\n])\n\n# MinGW uses autoconf, but also needs the windows shim routines\n# (since it doesn't have its own support for, say, pthreads).\n# This requires us to #include a special header file, and also to\n# link in some windows versions of .o's instead of the unix versions.\nAH_BOTTOM([\n#ifdef __MINGW32__\n#include \"windows/mingw.h\"\n#endif\n\n#endif  /* #ifndef GOOGLE_PERFTOOLS_CONFIG_H_ */\n])\nAM_CONDITIONAL(MINGW, expr $host : '.*-mingw' >/dev/null 2>&1)\n\n# Redhat 7 (and below?) has sys/ucontext.h, but if you try to #include\n# it directly, the compiler gets upset.  So we pretend we don't have\n# it.\nif cat /etc/redhat-release 2>/dev/null | grep \"Red Hat Linux release 7\" >/dev/null 2>&1; then\nAC_DEFINE(HAVE_SYS_UCONTEXT_H, 0, [<sys/ucontext.h> is broken on redhat 7])\nfi\n\n# Export the --enable flags we set above.  We do this at the end so\n# other configure rules can enable or disable targets based on what\n# they find.\nAM_CONDITIONAL(WITH_CPU_PROFILER, test \"$enable_cpu_profiler\" = yes)\nAM_CONDITIONAL(WITH_HEAP_PROFILER, test \"$enable_heap_profiler\" = yes)\nAM_CONDITIONAL(WITH_HEAP_CHECKER, test \"$enable_heap_checker\" = yes)\nAM_CONDITIONAL(WITH_DEBUGALLOC, test \"$enable_debugalloc\" = yes)\n# We make tcmalloc.so if either heap-profiler or heap-checker is asked for.\nAM_CONDITIONAL(WITH_HEAP_PROFILER_OR_CHECKER,\n               test \"$enable_heap_profiler\" = yes -o \\\n                    \"$enable_heap_checker\" = yes)\n# If we don't use any profilers, we don't need stack traces (or pprof)\nAM_CONDITIONAL(WITH_STACK_TRACE, test \"$enable_cpu_profiler\" = yes -o \\\n                                      \"$enable_heap_profiler\" = yes -o \\\n                                      \"$enable_heap_checker\" = yes)\n\n# Write generated configuration file\nAC_CONFIG_FILES([Makefile src/google/tcmalloc.h])\nAC_OUTPUT\n"
  },
  {
    "path": "distro/google-perftools-1.7/depcomp",
    "content": "#! /bin/sh\n# depcomp - compile a program generating dependencies as side-effects\n\nscriptversion=2005-07-09.11\n\n# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2, or (at your option)\n# any later version.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n# 02110-1301, USA.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.\n\ncase $1 in\n  '')\n     echo \"$0: No command.  Try \\`$0 --help' for more information.\" 1>&2\n     exit 1;\n     ;;\n  -h | --h*)\n    cat <<\\EOF\nUsage: depcomp [--help] [--version] PROGRAM [ARGS]\n\nRun PROGRAMS ARGS to compile a file, generating dependencies\nas side-effects.\n\nEnvironment variables:\n  depmode     Dependency tracking mode.\n  source      Source file read by `PROGRAMS ARGS'.\n  object      Object file output by `PROGRAMS ARGS'.\n  DEPDIR      directory where to store dependencies.\n  depfile     Dependency file to output.\n  tmpdepfile  Temporary file to use when outputing dependencies.\n  libtool     Whether libtool is used (yes/no).\n\nReport bugs to <bug-automake@gnu.org>.\nEOF\n    exit $?\n    ;;\n  -v | --v*)\n    echo \"depcomp $scriptversion\"\n    exit $?\n    ;;\nesac\n\nif test -z \"$depmode\" || test -z \"$source\" || test -z \"$object\"; then\n  echo \"depcomp: Variables source, object and depmode must be set\" 1>&2\n  exit 1\nfi\n\n# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.\ndepfile=${depfile-`echo \"$object\" |\n  sed 's|[^\\\\/]*$|'${DEPDIR-.deps}'/&|;s|\\.\\([^.]*\\)$|.P\\1|;s|Pobj$|Po|'`}\ntmpdepfile=${tmpdepfile-`echo \"$depfile\" | sed 's/\\.\\([^.]*\\)$/.T\\1/'`}\n\nrm -f \"$tmpdepfile\"\n\n# Some modes work just like other modes, but use different flags.  We\n# parameterize here, but still list the modes in the big case below,\n# to make depend.m4 easier to write.  Note that we *cannot* use a case\n# here, because this file can only contain one case statement.\nif test \"$depmode\" = hp; then\n  # HP compiler uses -M and no extra arg.\n  gccflag=-M\n  depmode=gcc\nfi\n\nif test \"$depmode\" = dashXmstdout; then\n   # This is just like dashmstdout with a different argument.\n   dashmflag=-xM\n   depmode=dashmstdout\nfi\n\ncase \"$depmode\" in\ngcc3)\n## gcc 3 implements dependency tracking that does exactly what\n## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like\n## it if -MD -MP comes after the -MF stuff.  Hmm.\n  \"$@\" -MT \"$object\" -MD -MP -MF \"$tmpdepfile\"\n  stat=$?\n  if test $stat -eq 0; then :\n  else\n    rm -f \"$tmpdepfile\"\n    exit $stat\n  fi\n  mv \"$tmpdepfile\" \"$depfile\"\n  ;;\n\ngcc)\n## There are various ways to get dependency output from gcc.  Here's\n## why we pick this rather obscure method:\n## - Don't want to use -MD because we'd like the dependencies to end\n##   up in a subdir.  Having to rename by hand is ugly.\n##   (We might end up doing this anyway to support other compilers.)\n## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like\n##   -MM, not -M (despite what the docs say).\n## - Using -M directly means running the compiler twice (even worse\n##   than renaming).\n  if test -z \"$gccflag\"; then\n    gccflag=-MD,\n  fi\n  \"$@\" -Wp,\"$gccflag$tmpdepfile\"\n  stat=$?\n  if test $stat -eq 0; then :\n  else\n    rm -f \"$tmpdepfile\"\n    exit $stat\n  fi\n  rm -f \"$depfile\"\n  echo \"$object : \\\\\" > \"$depfile\"\n  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n## The second -e expression handles DOS-style file names with drive letters.\n  sed -e 's/^[^:]*: / /' \\\n      -e 's/^['$alpha']:\\/[^:]*: / /' < \"$tmpdepfile\" >> \"$depfile\"\n## This next piece of magic avoids the `deleted header file' problem.\n## The problem is that when a header file which appears in a .P file\n## is deleted, the dependency causes make to die (because there is\n## typically no way to rebuild the header).  We avoid this by adding\n## dummy dependencies for each header file.  Too bad gcc doesn't do\n## this for us directly.\n  tr ' ' '\n' < \"$tmpdepfile\" |\n## Some versions of gcc put a space before the `:'.  On the theory\n## that the space means something, we add a space to the output as\n## well.\n## Some versions of the HPUX 10.20 sed can't process this invocation\n## correctly.  Breaking it into two sed invocations is a workaround.\n    sed -e 's/^\\\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\nhp)\n  # This case exists only to let depend.m4 do its work.  It works by\n  # looking at the text of this script.  This case will never be run,\n  # since it is checked for above.\n  exit 1\n  ;;\n\nsgi)\n  if test \"$libtool\" = yes; then\n    \"$@\" \"-Wp,-MDupdate,$tmpdepfile\"\n  else\n    \"$@\" -MDupdate \"$tmpdepfile\"\n  fi\n  stat=$?\n  if test $stat -eq 0; then :\n  else\n    rm -f \"$tmpdepfile\"\n    exit $stat\n  fi\n  rm -f \"$depfile\"\n\n  if test -f \"$tmpdepfile\"; then  # yes, the sourcefile depend on other files\n    echo \"$object : \\\\\" > \"$depfile\"\n\n    # Clip off the initial element (the dependent).  Don't try to be\n    # clever and replace this with sed code, as IRIX sed won't handle\n    # lines with more than a fixed number of characters (4096 in\n    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;\n    # the IRIX cc adds comments like `#:fec' to the end of the\n    # dependency line.\n    tr ' ' '\n' < \"$tmpdepfile\" \\\n    | sed -e 's/^.*\\.o://' -e 's/#.*$//' -e '/^$/ d' | \\\n    tr '\n' ' ' >> $depfile\n    echo >> $depfile\n\n    # The second pass generates a dummy entry for each header file.\n    tr ' ' '\n' < \"$tmpdepfile\" \\\n   | sed -e 's/^.*\\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \\\n   >> $depfile\n  else\n    # The sourcefile does not contain any dependencies, so just\n    # store a dummy comment line, to avoid errors with the Makefile\n    # \"include basename.Plo\" scheme.\n    echo \"#dummy\" > \"$depfile\"\n  fi\n  rm -f \"$tmpdepfile\"\n  ;;\n\naix)\n  # The C for AIX Compiler uses -M and outputs the dependencies\n  # in a .u file.  In older versions, this file always lives in the\n  # current directory.  Also, the AIX compiler puts `$object:' at the\n  # start of each line; $object doesn't have directory information.\n  # Version 6 uses the directory in both cases.\n  stripped=`echo \"$object\" | sed 's/\\(.*\\)\\..*$/\\1/'`\n  tmpdepfile=\"$stripped.u\"\n  if test \"$libtool\" = yes; then\n    \"$@\" -Wc,-M\n  else\n    \"$@\" -M\n  fi\n  stat=$?\n\n  if test -f \"$tmpdepfile\"; then :\n  else\n    stripped=`echo \"$stripped\" | sed 's,^.*/,,'`\n    tmpdepfile=\"$stripped.u\"\n  fi\n\n  if test $stat -eq 0; then :\n  else\n    rm -f \"$tmpdepfile\"\n    exit $stat\n  fi\n\n  if test -f \"$tmpdepfile\"; then\n    outname=\"$stripped.o\"\n    # Each line is of the form `foo.o: dependent.h'.\n    # Do two passes, one to just change these to\n    # `$object: dependent.h' and one to simply `dependent.h:'.\n    sed -e \"s,^$outname:,$object :,\" < \"$tmpdepfile\" > \"$depfile\"\n    sed -e \"s,^$outname: \\(.*\\)$,\\1:,\" < \"$tmpdepfile\" >> \"$depfile\"\n  else\n    # The sourcefile does not contain any dependencies, so just\n    # store a dummy comment line, to avoid errors with the Makefile\n    # \"include basename.Plo\" scheme.\n    echo \"#dummy\" > \"$depfile\"\n  fi\n  rm -f \"$tmpdepfile\"\n  ;;\n\nicc)\n  # Intel's C compiler understands `-MD -MF file'.  However on\n  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c\n  # ICC 7.0 will fill foo.d with something like\n  #    foo.o: sub/foo.c\n  #    foo.o: sub/foo.h\n  # which is wrong.  We want:\n  #    sub/foo.o: sub/foo.c\n  #    sub/foo.o: sub/foo.h\n  #    sub/foo.c:\n  #    sub/foo.h:\n  # ICC 7.1 will output\n  #    foo.o: sub/foo.c sub/foo.h\n  # and will wrap long lines using \\ :\n  #    foo.o: sub/foo.c ... \\\n  #     sub/foo.h ... \\\n  #     ...\n\n  \"$@\" -MD -MF \"$tmpdepfile\"\n  stat=$?\n  if test $stat -eq 0; then :\n  else\n    rm -f \"$tmpdepfile\"\n    exit $stat\n  fi\n  rm -f \"$depfile\"\n  # Each line is of the form `foo.o: dependent.h',\n  # or `foo.o: dep1.h dep2.h \\', or ` dep3.h dep4.h \\'.\n  # Do two passes, one to just change these to\n  # `$object: dependent.h' and one to simply `dependent.h:'.\n  sed \"s,^[^:]*:,$object :,\" < \"$tmpdepfile\" > \"$depfile\"\n  # Some versions of the HPUX 10.20 sed can't process this invocation\n  # correctly.  Breaking it into two sed invocations is a workaround.\n  sed 's,^[^:]*: \\(.*\\)$,\\1,;s/^\\\\$//;/^$/d;/:$/d' < \"$tmpdepfile\" |\n    sed -e 's/$/ :/' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\ntru64)\n   # The Tru64 compiler uses -MD to generate dependencies as a side\n   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.\n   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put\n   # dependencies in `foo.d' instead, so we check for that too.\n   # Subdirectories are respected.\n   dir=`echo \"$object\" | sed -e 's|/[^/]*$|/|'`\n   test \"x$dir\" = \"x$object\" && dir=\n   base=`echo \"$object\" | sed -e 's|^.*/||' -e 's/\\.o$//' -e 's/\\.lo$//'`\n\n   if test \"$libtool\" = yes; then\n      # With Tru64 cc, shared objects can also be used to make a\n      # static library.  This mecanism is used in libtool 1.4 series to\n      # handle both shared and static libraries in a single compilation.\n      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.\n      #\n      # With libtool 1.5 this exception was removed, and libtool now\n      # generates 2 separate objects for the 2 libraries.  These two\n      # compilations output dependencies in in $dir.libs/$base.o.d and\n      # in $dir$base.o.d.  We have to check for both files, because\n      # one of the two compilations can be disabled.  We should prefer\n      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is\n      # automatically cleaned when .libs/ is deleted, while ignoring\n      # the former would cause a distcleancheck panic.\n      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4\n      tmpdepfile2=$dir$base.o.d          # libtool 1.5\n      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5\n      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504\n      \"$@\" -Wc,-MD\n   else\n      tmpdepfile1=$dir$base.o.d\n      tmpdepfile2=$dir$base.d\n      tmpdepfile3=$dir$base.d\n      tmpdepfile4=$dir$base.d\n      \"$@\" -MD\n   fi\n\n   stat=$?\n   if test $stat -eq 0; then :\n   else\n      rm -f \"$tmpdepfile1\" \"$tmpdepfile2\" \"$tmpdepfile3\" \"$tmpdepfile4\"\n      exit $stat\n   fi\n\n   for tmpdepfile in \"$tmpdepfile1\" \"$tmpdepfile2\" \"$tmpdepfile3\" \"$tmpdepfile4\"\n   do\n     test -f \"$tmpdepfile\" && break\n   done\n   if test -f \"$tmpdepfile\"; then\n      sed -e \"s,^.*\\.[a-z]*:,$object:,\" < \"$tmpdepfile\" > \"$depfile\"\n      # That's a tab and a space in the [].\n      sed -e 's,^.*\\.[a-z]*:[\t ]*,,' -e 's,$,:,' < \"$tmpdepfile\" >> \"$depfile\"\n   else\n      echo \"#dummy\" > \"$depfile\"\n   fi\n   rm -f \"$tmpdepfile\"\n   ;;\n\n#nosideeffect)\n  # This comment above is used by automake to tell side-effect\n  # dependency tracking mechanisms from slower ones.\n\ndashmstdout)\n  # Important note: in order to support this mode, a compiler *must*\n  # always write the preprocessed file to stdout, regardless of -o.\n  \"$@\" || exit $?\n\n  # Remove the call to Libtool.\n  if test \"$libtool\" = yes; then\n    while test $1 != '--mode=compile'; do\n      shift\n    done\n    shift\n  fi\n\n  # Remove `-o $object'.\n  IFS=\" \"\n  for arg\n  do\n    case $arg in\n    -o)\n      shift\n      ;;\n    $object)\n      shift\n      ;;\n    *)\n      set fnord \"$@\" \"$arg\"\n      shift # fnord\n      shift # $arg\n      ;;\n    esac\n  done\n\n  test -z \"$dashmflag\" && dashmflag=-M\n  # Require at least two characters before searching for `:'\n  # in the target name.  This is to cope with DOS-style filenames:\n  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.\n  \"$@\" $dashmflag |\n    sed 's:^[  ]*[^: ][^:][^:]*\\:[    ]*:'\"$object\"'\\: :' > \"$tmpdepfile\"\n  rm -f \"$depfile\"\n  cat < \"$tmpdepfile\" > \"$depfile\"\n  tr ' ' '\n' < \"$tmpdepfile\" | \\\n## Some versions of the HPUX 10.20 sed can't process this invocation\n## correctly.  Breaking it into two sed invocations is a workaround.\n    sed -e 's/^\\\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\ndashXmstdout)\n  # This case only exists to satisfy depend.m4.  It is never actually\n  # run, as this mode is specially recognized in the preamble.\n  exit 1\n  ;;\n\nmakedepend)\n  \"$@\" || exit $?\n  # Remove any Libtool call\n  if test \"$libtool\" = yes; then\n    while test $1 != '--mode=compile'; do\n      shift\n    done\n    shift\n  fi\n  # X makedepend\n  shift\n  cleared=no\n  for arg in \"$@\"; do\n    case $cleared in\n    no)\n      set \"\"; shift\n      cleared=yes ;;\n    esac\n    case \"$arg\" in\n    -D*|-I*)\n      set fnord \"$@\" \"$arg\"; shift ;;\n    # Strip any option that makedepend may not understand.  Remove\n    # the object too, otherwise makedepend will parse it as a source file.\n    -*|$object)\n      ;;\n    *)\n      set fnord \"$@\" \"$arg\"; shift ;;\n    esac\n  done\n  obj_suffix=\"`echo $object | sed 's/^.*\\././'`\"\n  touch \"$tmpdepfile\"\n  ${MAKEDEPEND-makedepend} -o\"$obj_suffix\" -f\"$tmpdepfile\" \"$@\"\n  rm -f \"$depfile\"\n  cat < \"$tmpdepfile\" > \"$depfile\"\n  sed '1,2d' \"$tmpdepfile\" | tr ' ' '\n' | \\\n## Some versions of the HPUX 10.20 sed can't process this invocation\n## correctly.  Breaking it into two sed invocations is a workaround.\n    sed -e 's/^\\\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> \"$depfile\"\n  rm -f \"$tmpdepfile\" \"$tmpdepfile\".bak\n  ;;\n\ncpp)\n  # Important note: in order to support this mode, a compiler *must*\n  # always write the preprocessed file to stdout.\n  \"$@\" || exit $?\n\n  # Remove the call to Libtool.\n  if test \"$libtool\" = yes; then\n    while test $1 != '--mode=compile'; do\n      shift\n    done\n    shift\n  fi\n\n  # Remove `-o $object'.\n  IFS=\" \"\n  for arg\n  do\n    case $arg in\n    -o)\n      shift\n      ;;\n    $object)\n      shift\n      ;;\n    *)\n      set fnord \"$@\" \"$arg\"\n      shift # fnord\n      shift # $arg\n      ;;\n    esac\n  done\n\n  \"$@\" -E |\n    sed -n -e '/^# [0-9][0-9]* \"\\([^\"]*\\)\".*/ s:: \\1 \\\\:p' \\\n       -e '/^#line [0-9][0-9]* \"\\([^\"]*\\)\".*/ s:: \\1 \\\\:p' |\n    sed '$ s: \\\\$::' > \"$tmpdepfile\"\n  rm -f \"$depfile\"\n  echo \"$object : \\\\\" > \"$depfile\"\n  cat < \"$tmpdepfile\" >> \"$depfile\"\n  sed < \"$tmpdepfile\" '/^$/d;s/^ //;s/ \\\\$//;s/$/ :/' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\nmsvisualcpp)\n  # Important note: in order to support this mode, a compiler *must*\n  # always write the preprocessed file to stdout, regardless of -o,\n  # because we must use -o when running libtool.\n  \"$@\" || exit $?\n  IFS=\" \"\n  for arg\n  do\n    case \"$arg\" in\n    \"-Gm\"|\"/Gm\"|\"-Gi\"|\"/Gi\"|\"-ZI\"|\"/ZI\")\n\tset fnord \"$@\"\n\tshift\n\tshift\n\t;;\n    *)\n\tset fnord \"$@\" \"$arg\"\n\tshift\n\tshift\n\t;;\n    esac\n  done\n  \"$@\" -E |\n  sed -n '/^#line [0-9][0-9]* \"\\([^\"]*\\)\"/ s::echo \"`cygpath -u \\\\\"\\1\\\\\"`\":p' | sort | uniq > \"$tmpdepfile\"\n  rm -f \"$depfile\"\n  echo \"$object : \\\\\" > \"$depfile\"\n  . \"$tmpdepfile\" | sed 's% %\\\\ %g' | sed -n '/^\\(.*\\)$/ s::\t\\1 \\\\:p' >> \"$depfile\"\n  echo \"\t\" >> \"$depfile\"\n  . \"$tmpdepfile\" | sed 's% %\\\\ %g' | sed -n '/^\\(.*\\)$/ s::\\1\\::p' >> \"$depfile\"\n  rm -f \"$tmpdepfile\"\n  ;;\n\nnone)\n  exec \"$@\"\n  ;;\n\n*)\n  echo \"Unknown depmode $depmode\" 1>&2\n  exit 1\n  ;;\nesac\n\nexit 0\n\n# Local Variables:\n# mode: shell-script\n# sh-indentation: 2\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-end: \"$\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/cpuprofile-fileformat.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<HTML>\n\n<HEAD>\n  <link rel=\"stylesheet\" href=\"designstyle.css\">\n  <title>Google CPU Profiler Binary Data File Format</title>\n</HEAD>\n\n<BODY>\n\n<h1>Google CPU Profiler Binary Data File Format</h1>\n\n<p align=right>\n  <i>Last modified\n    <script type=text/javascript>\n    var lm = new Date(document.lastModified);\n    document.write(lm.toDateString());\n  </script></i>\n</p>\n\n<p>This file documents the binary data file format produced by the\nGoogle CPU Profiler.  For information about using the CPU Profiler,\nsee <a href=\"cpuprofile.html\">its user guide</a>.\n\n<p>The profiler source code, which generates files using this format, is at\n<code>src/profiler.cc</code></a>.\n\n\n<h2>CPU Profile Data File Structure</h2>\n\n<p>CPU profile data files each consist of four parts, in order:\n\n<ul>\n  <li> Binary header\n  <li> Binary profile records\n  <li> Binary trailer\n  <li> Text list of mapped objects\n</ul>\n\n<p>The binary data is expressed in terms of \"slots.\"  These are words\nlarge enough to hold the program's pointer type, i.e., for 32-bit\nprograms they are 4 bytes in size, and for 64-bit programs they are 8\nbytes.  They are stored in the profile data file in the native byte\norder (i.e., little-endian for x86 and x86_64).\n\n\n<h2>Binary Header</h2>\n\n<p>The binary header format is show below.  Values written by the\nprofiler, along with requirements currently enforced by the analysis\ntools, are shown in parentheses.\n\n<p>\n<table summary=\"Header Format\"\n       frame=\"box\" rules=\"sides\" cellpadding=\"5\" width=\"50%\">\n  <tr>\n    <th width=\"30%\">slot</th>\n    <th width=\"70%\">data</th>\n  </tr>\n\n  <tr>\n    <td>0</td>\n    <td>header count (0; must be 0)</td>\n  </tr>\n\n  <tr>\n    <td>1</td>\n    <td>header slots after this one (3; must be &gt;= 3)</td>\n  </tr>\n\n  <tr>\n    <td>2</td>\n    <td>format version (0; must be 0)</td>\n  </tr>\n\n  <tr>\n    <td>3</td>\n    <td>sampling period, in microseconds</td>\n  </tr>\n\n  <tr>\n    <td>4</td>\n    <td>padding (0)</td>\n  </tr>\n</table>\n\n<p>The headers currently generated for 32-bit and 64-bit little-endian\n(x86 and x86_64) profiles are shown below, for comparison.\n\n<p>\n<table summary=\"Header Example\" frame=\"box\" rules=\"sides\" cellpadding=\"5\">\n  <tr>\n    <th></th>\n    <th>hdr count</th>\n    <th>hdr words</th>\n    <th>version</th>\n    <th>sampling period</th>\n    <th>pad</th>\n  </tr>\n  <tr>\n    <td>32-bit or 64-bit (slots)</td>\n    <td>0</td>\n    <td>3</td>\n    <td>0</td>\n    <td>10000</td>\n    <td>0</td>\n  </tr>\n  <tr>\n    <td>32-bit (4-byte words in file)</td>\n    <td><tt>0x00000</tt></td>\n    <td><tt>0x00003</tt></td>\n    <td><tt>0x00000</tt></td>\n    <td><tt>0x02710</tt></td>\n    <td><tt>0x00000</tt></td>\n  </tr>\n  <tr>\n    <td>64-bit LE (4-byte words in file)</td>\n    <td><tt>0x00000&nbsp;0x00000</tt></td>\n    <td><tt>0x00003&nbsp;0x00000</tt></td>\n    <td><tt>0x00000&nbsp;0x00000</tt></td>\n    <td><tt>0x02710&nbsp;0x00000</tt></td>\n    <td><tt>0x00000&nbsp;0x00000</tt></td>\n  </tr>\n</table>\n\n<p>The contents are shown in terms of slots, and in terms of 4-byte\nwords in the profile data file.  The slot contents for 32-bit and\n64-bit headers are identical.  For 32-bit profiles, the 4-byte word\nview matches the slot view.  For 64-bit profiles, each (8-byte) slot\nis shown as two 4-byte words, ordered as they would appear in the\nfile.\n\n<p>The profiling tools examine the contents of the file and use the\nexpected locations and values of the header words field to detect\nwhether the file is 32-bit or 64-bit.\n\n\n<h2>Binary Profile Records</h2>\n\n<p>The binary profile record format is shown below.\n\n<p>\n<table summary=\"Profile Record Format\"\n       frame=\"box\" rules=\"sides\" cellpadding=\"5\" width=\"50%\">\n  <tr>\n    <th width=\"30%\">slot</th>\n    <th width=\"70%\">data</th>\n  </tr>\n\n  <tr>\n    <td>0</td>\n    <td>sample count, must be &gt;= 1</td>\n  </tr>\n\n  <tr>\n    <td>1</td>\n    <td>number of call chain PCs (num_pcs), must be &gt;= 1</td>\n  </tr>\n\n  <tr>\n    <td>2 .. (num_pcs + 1)</td>\n    <td>call chain PCs, most-recently-called function first.\n  </tr>\n</table>\n\n<p>The total length of a given record is 2 + num_pcs.\n\n<p>Note that multiple profile records can be emitted by the profiler\nhaving an identical call chain.  In that case, analysis tools should\nsum the counts of all records having identical call chains.\n\n<p><b>Note:</b> Some profile analysis tools terminate if they see\n<em>any</em> profile record with a call chain with its first entry\nhaving the address 0.  (This is similar to the binary trailer.)\n\n<h3>Example</h3>\n\nThis example shows the slots contained in a sample profile record.\n\n<p>\n<table summary=\"Profile Record Example\"\n       frame=\"box\" rules=\"sides\" cellpadding=\"5\">\n  <tr>\n    <td>5</td>\n    <td>3</td>\n    <td>0xa0000</td>\n    <td>0xc0000</td>\n    <td>0xe0000</td>\n  </tr>\n</table>\n\n<p>In this example, 5 ticks were received at PC 0xa0000, whose\nfunction had been called by the function containing 0xc0000, which had\nbeen called from the function containing 0xe0000.\n\n\n<h2>Binary Trailer</h2>\n\n<p>The binary trailer consists of three slots of data with fixed\nvalues, shown below.\n\n<p>\n<table summary=\"Trailer Format\"\n       frame=\"box\" rules=\"sides\" cellpadding=\"5\" width=\"50%\">\n  <tr>\n    <th width=\"30%\">slot</th>\n    <th width=\"70%\">value</th>\n  </tr>\n\n  <tr>\n    <td>0</td>\n    <td>0</td>\n  </tr>\n\n  <tr>\n    <td>1</td>\n    <td>1</td>\n  </tr>\n\n  <tr>\n    <td>2</td>\n    <td>0</td>\n  </tr>\n</table>\n\n<p>Note that this is the same data that would contained in a profile\nrecord with sample count = 0, num_pcs = 1, and a one-element call\nchain containing the address 0.\n\n\n<h2>Text List of Mapped Objects</h2>\n\n<p>The binary data in the file is followed immediately by a list of\nmapped objects.  This list consists of lines of text separated by\nnewline characters.\n\n<p>Each line is one of the following types:\n\n<ul>\n  <li>Build specifier, starting with \"<tt>build=</tt>\".  For example:\n    <pre>  build=/path/to/binary</pre>\n    Leading spaces on the line are ignored.\n\n  <li>Mapping line from ProcMapsIterator::FormatLine.  For example:\n    <pre>  40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so</pre>\n    The first address must start at the beginning of the line.\n</ul>\n\n<p>Unrecognized lines should be ignored by analysis tools.\n\n<p>When processing the paths see in mapping lines, occurrences of\n<tt>$build</tt> followed by a non-word character (i.e., characters\nother than underscore or alphanumeric characters), should be replaced\nby the path given on the last build specifier line.\n\n<hr>\n<address>Chris Demetriou<br>\n<!-- Created: Mon Aug 27 12:18:26 PDT 2007 -->\n<!-- hhmts start -->\nLast modified: Mon Aug 27 12:18:26 PDT 2007  (cgd)\n<!-- hhmts end -->\n</address>\n</BODY>\n</HTML>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/cpuprofile.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n\n<HEAD>\n  <link rel=\"stylesheet\" href=\"designstyle.css\">\n  <title>Google CPU Profiler</title>\n</HEAD>\n\n<BODY>\n\n<p align=right>\n  <i>Last modified\n  <script type=text/javascript>\n    var lm = new Date(document.lastModified);\n    document.write(lm.toDateString());\n  </script></i>\n</p>\n\n<p>This is the CPU profiler we use at Google.  There are three parts\nto using it: linking the library into an application, running the\ncode, and analyzing the output.</p>\n\n<p>On the off-chance that you should need to understand it, the CPU\nprofiler data file format is documented separately,\n<a href=\"cpuprofile-fileformat.html\">here</a>.\n\n\n<H1>Linking in the Library</H1>\n\n<p>To install the CPU profiler into your executable, add\n<code>-lprofiler</code> to the link-time step for your executable.\n(It's also probably possible to add in the profiler at run-time using\n<code>LD_PRELOAD</code>, e.g.\n<code>% env LD_PRELOAD=\"/usr/lib/libprofiler.so\" &lt;binary&gt;</code>,\nbut this isn't necessarily recommended.)</p>\n\n<p>This does <i>not</i> turn on CPU profiling; it just inserts the\ncode.  For that reason, it's practical to just always link\n<code>-lprofiler</code> into a binary while developing; that's what we\ndo at Google.  (However, since any user can turn on the profiler by\nsetting an environment variable, it's not necessarily recommended to\ninstall profiler-linked binaries into a production, running\nsystem.)</p>\n\n\n<H1>Running the Code</H1>\n\n<p>There are several alternatives to actually turn on CPU profiling\nfor a given run of an executable:</p>\n\n<ol>\n  <li> <p>Define the environment variable CPUPROFILE to the filename\n       to dump the profile to.  For instance, to profile\n       <code>/usr/local/bin/my_binary_compiled_with_libprofiler_so</code>:</p>\n       <pre>% env CPUPROFILE=/tmp/mybin.prof /usr/local/bin/my_binary_compiled_with_libprofiler_so</pre>\n\n  <li> <p>In your code, bracket the code you want profiled in calls to\n       <code>ProfilerStart()</code> and <code>ProfilerStop()</code>.\n       (These functions are declared in <code>&lt;google/profiler.h&gt;</code>.)\n       <code>ProfilerStart()</code> will take\n       the profile-filename as an argument.</p>\n</ol>\n\n<p>In Linux 2.6 and above, profiling works correctly with threads,\nautomatically profiling all threads.  In Linux 2.4, profiling only\nprofiles the main thread (due to a kernel bug involving itimers and\nthreads).  Profiling works correctly with sub-processes: each child\nprocess gets its own profile with its own name (generated by combining\nCPUPROFILE with the child's process id).</p>\n\n<p>For security reasons, CPU profiling will not write to a file -- and\nis thus not usable -- for setuid programs.</p>\n\n<p>See the include-file <code>google/profiler.h</code> for\nadvanced-use functions, including <code>ProfilerFlush()</code> and\n<code>ProfilerStartWithOptions()</code>.</p>\n\n\n<H2>Modifying Runtime Behavior</H2>\n\n<p>You can more finely control the behavior of the CPU profiler via\nenvironment variables.</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>CPUPROFILE_FREQUENCY=<i>x</i></code></td>\n  <td>default: 100</td>\n  <td>\n    How many interrupts/second the cpu-profiler samples.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>CPUPROFILE_REALTIME=1</code></td>\n  <td>default: [not set]</td>\n  <td>\n    If set to any value (including 0 or the empty string), use\n    ITIMER_REAL instead of ITIMER_PROF to gather profiles.  In\n    general, ITIMER_REAL is not as accurate as ITIMER_PROF, and also\n    interacts badly with use of alarm(), so prefer ITIMER_PROF unless\n    you have a reason prefer ITIMER_REAL.\n  </td>\n</tr>\n\n</table>\n\n\n<h1><a name=\"pprof\">Analyzing the Output</a></h1>\n\n<p><code>pprof</code> is the script used to analyze a profile.  It has\nmany output modes, both textual and graphical.  Some give just raw\nnumbers, much like the <code>-pg</code> output of <code>gcc</code>,\nand others show the data in the form of a dependency graph.</p>\n\n<p>pprof <b>requires</b> <code>perl5</code> to be installed to run.\nIt also requires <code>dot</code> to be installed for any of the\ngraphical output routines, and <code>gv</code> to be installed for\n<code>--gv</code> mode (described below).\n</p>\n\n<p>Here are some ways to call pprof.  These are described in more\ndetail below.</p>\n\n<pre>\n% pprof /bin/ls ls.prof\n                       Enters \"interactive\" mode\n% pprof --text /bin/ls ls.prof\n                       Outputs one line per procedure\n% pprof --gv /bin/ls ls.prof\n                       Displays annotated call-graph via 'gv'\n% pprof --gv --focus=Mutex /bin/ls ls.prof\n                       Restricts to code paths including a .*Mutex.* entry\n% pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof\n                       Code paths including Mutex but not string\n% pprof --list=getdir /bin/ls ls.prof\n                       (Per-line) annotated source listing for getdir()\n% pprof --disasm=getdir /bin/ls ls.prof\n                       (Per-PC) annotated disassembly for getdir()\n% pprof --text localhost:1234\n                       Outputs one line per procedure for localhost:1234\n% pprof --callgrind /bin/ls ls.prof\n                       Outputs the call information in callgrind format\n</pre>\n\n\n<h3>Analyzing Text Output</h3>\n\n<p>Text mode has lines of output that look like this:</p>\n<pre>\n       14   2.1%  17.2%       58   8.7% std::_Rb_tree::find\n</pre>\n\n<p>Here is how to interpret the columns:</p>\n<ol>\n  <li> Number of profiling samples in this function\n  <li> Percentage of profiling samples in this function\n  <li> Percentage of profiling samples in the functions printed so far\n  <li> Number of profiling samples in this function and its callees\n  <li> Percentage of profiling samples in this function and its callees\n  <li> Function name\n</ol>\n\n<h3>Analyzing Callgrind Output</h3>\n\n<p>Use <a href=\"http://kcachegrind.sourceforge.net\">kcachegrind</a> to \nanalyze your callgrind output:</p>\n<pre>\n% pprof --callgrind /bin/ls ls.prof > ls.callgrind\n% kcachegrind ls.callgrind\n</pre>\n\n<p>The cost is specified in 'hits', i.e. how many times a function\nappears in the recorded call stack information. The 'calls' from\nfunction a to b record how many times function b was found in the\nstack traces directly below function a.</p>\n\n<p>Tip: if you use a debug build the output will include file and line\nnumber information and kcachegrind will show an annotated source\ncode view.</p>\n\n<h3>Node Information</h3>\n\n<p>In the various graphical modes of pprof, the output is a call graph\nannotated with timing information, like so:</p>\n\n<A HREF=\"pprof-test-big.gif\">\n<center><table><tr><td>\n   <img src=\"pprof-test.gif\">\n</td></tr></table></center>\n</A>\n\n<p>Each node represents a procedure.  The directed edges indicate\ncaller to callee relations.  Each node is formatted as follows:</p>\n\n<center><pre>\nClass Name\nMethod Name\nlocal (percentage)\n<b>of</b> cumulative (percentage)\n</pre></center>\n\n<p>The last one or two lines contains the timing information.  (The\nprofiling is done via a sampling method, where by default we take 100\nsamples a second.  Therefor one unit of time in the output corresponds\nto about 10 milliseconds of execution time.) The \"local\" time is the\ntime spent executing the instructions directly contained in the\nprocedure (and in any other procedures that were inlined into the\nprocedure).  The \"cumulative\" time is the sum of the \"local\" time and\nthe time spent in any callees.  If the cumulative time is the same as\nthe local time, it is not printed.</p>\n\n<p>For instance, the timing information for test_main_thread()\nindicates that 155 units (about 1.55 seconds) were spent executing the\ncode in <code>test_main_thread()</code> and 200 units were spent while\nexecuting <code>test_main_thread()</code> and its callees such as\n<code>snprintf()</code>.</p>\n\n<p>The size of the node is proportional to the local count.  The\npercentage displayed in the node corresponds to the count divided by\nthe total run time of the program (that is, the cumulative count for\n<code>main()</code>).</p>\n\n<h3>Edge Information</h3>\n\n<p>An edge from one node to another indicates a caller to callee\nrelationship.  Each edge is labelled with the time spent by the callee\non behalf of the caller.  E.g, the edge from\n<code>test_main_thread()</code> to <code>snprintf()</code> indicates\nthat of the 200 samples in <code>test_main_thread()</code>, 37 are\nbecause of calls to <code>snprintf()</code>.</p>\n\n<p>Note that <code>test_main_thread()</code> has an edge to\n<code>vsnprintf()</code>, even though <code>test_main_thread()</code>\ndoesn't call that function directly.  This is because the code was\ncompiled with <code>-O2</code>; the profile reflects the optimized\ncontrol flow.</p>\n\n<h3>Meta Information</h3>\n\n<p>The top of the display should contain some meta information\nlike:</p>\n<pre>\n      /tmp/profiler2_unittest\n      Total samples: 202\n      Focusing on: 202\n      Dropped nodes with &lt;= 1 abs(samples)\n      Dropped edges with &lt;= 0 samples\n</pre>\n\n<p>This section contains the name of the program, and the total\nsamples collected during the profiling run.  If the\n<code>--focus</code> option is on (see the <a href=\"#focus\">Focus</a>\nsection below), the legend also contains the number of samples being\nshown in the focused display.  Furthermore, some unimportant nodes and\nedges are dropped to reduce clutter.  The characteristics of the\ndropped nodes and edges are also displayed in the legend.</p>\n\n<h3><a name=focus>Focus and Ignore</a></h3>\n\n<p>You can ask pprof to generate a display focused on a particular\npiece of the program.  You specify a regular expression.  Any portion\nof the call-graph that is on a path which contains at least one node\nmatching the regular expression is preserved.  The rest of the\ncall-graph is dropped on the floor.  For example, you can focus on the\n<code>vsnprintf()</code> libc call in <code>profiler2_unittest</code>\nas follows:</p>\n\n<pre>\n% pprof --gv --focus=vsnprintf /tmp/profiler2_unittest test.prof\n</pre>\n<A HREF=\"pprof-vsnprintf-big.gif\">\n<center><table><tr><td>\n   <img src=\"pprof-vsnprintf.gif\">\n</td></tr></table></center>\n</A>\n\n<p>Similarly, you can supply the <code>--ignore</code> option to\nignore samples that match a specified regular expression.  E.g., if\nyou are interested in everything except calls to\n<code>snprintf()</code>, you can say:</p>\n<pre>\n% pprof --gv --ignore=snprintf /tmp/profiler2_unittest test.prof\n</pre>\n\n\n<h3>Interactive mode</a></h3>\n\n<p>By default -- if you don't specify any flags to the contrary --\npprof runs in interactive mode.  At the <code>(pprof)</code> prompt,\nyou can run many of the commands described above.  You can type\n<code>help</code> for a list of what commands are available in\ninteractive mode.</p>\n\n<h3><a name=options>pprof Options</a></h3>\n\nFor a complete list of pprof options, you can run <code>pprof\n--help</code>.\n\n<h4>Output Type</h4>\n\n<p>\n<center>\n<table frame=box rules=sides cellpadding=5 width=100%>\n<tr valign=top>\n  <td><code>--text</code></td>\n  <td>\n    Produces a textual listing.  (Note: If you have an X display, and\n    <code>dot</code> and <code>gv</code> installed, you will probably\n    be happier with the <code>--gv</code> output.)\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--gv</code></td>\n  <td>\n    Generates annotated call-graph, converts to postscript, and\n    displays via gv (requres <code>dot</code> and <code>gv</code> be\n    installed).\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--dot</code></td>\n  <td>\n    Generates the annotated call-graph in dot format and\n    emits to stdout (requres <code>dot</code> be installed).\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--ps</code></td>\n  <td>\n    Generates the annotated call-graph in Postscript format and\n    emits to stdout (requres <code>dot</code> be installed).\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--pdf</code></td>\n  <td>\n    Generates the annotated call-graph in PDF format and emits to\n    stdout (requires <code>dot</code> and <code>ps2pdf</code> be\n    installed).\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--gif</code></td>\n  <td>\n    Generates the annotated call-graph in GIF format and\n    emits to stdout (requres <code>dot</code> be installed).\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--list=&lt;<i>regexp</i>&gt;</code></td>\n  <td>\n    <p>Outputs source-code listing of routines whose\n    name matches &lt;regexp&gt;.  Each line\n    in the listing is annotated with flat and cumulative\n    sample counts.</p>\n\n    <p>In the presence of inlined calls, the samples\n    associated with inlined code tend to get assigned\n    to a line that follows the location of the \n    inlined call.  A more precise accounting can be\n    obtained by disassembling the routine using the\n    --disasm flag.</p>\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--disasm=&lt;<i>regexp</i>&gt;</code></td>\n  <td>\n    Generates disassembly of routines that match\n    &lt;regexp&gt;, annotated with flat and\n    cumulative sample counts and emits to stdout.\n  </td>\n</tr>\n</table>\n</center>\n\n<h4>Reporting Granularity</h4>\n\n<p>By default, pprof produces one entry per procedure.  However you can\nuse one of the following options to change the granularity of the\noutput.  The <code>--files</code> option seems to be particularly\nuseless, and may be removed eventually.</p>\n\n<center>\n<table frame=box rules=sides cellpadding=5 width=100%>\n<tr valign=top>\n  <td><code>--addresses</code></td>\n  <td>\n     Produce one node per program address.\n  </td>\n</tr>\n  <td><code>--lines</code></td>\n  <td>\n     Produce one node per source line.\n  </td>\n</tr>\n  <td><code>--functions</code></td>\n  <td>\n     Produce one node per function (this is the default).\n  </td>\n</tr>\n  <td><code>--files</code></td>\n  <td>\n     Produce one node per source file.\n  </td>\n</tr>\n</table>\n</center>\n\n<h4>Controlling the Call Graph Display</h4>\n\n<p>Some nodes and edges are dropped to reduce clutter in the output\ndisplay.  The following options control this effect:</p>\n\n<center>\n<table frame=box rules=sides cellpadding=5 width=100%>\n<tr valign=top>\n  <td><code>--nodecount=&lt;n&gt;</code></td>\n  <td>\n    This option controls the number of displayed nodes.  The nodes\n    are first sorted by decreasing cumulative count, and then only\n    the top N nodes are kept.  The default value is 80.\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--nodefraction=&lt;f&gt;</code></td>\n  <td>\n    This option provides another mechanism for discarding nodes\n    from the display.  If the cumulative count for a node is\n    less than this option's value multiplied by the total count\n    for the profile, the node is dropped.  The default value\n    is 0.005; i.e. nodes that account for less than\n    half a percent of the total time are dropped.  A node\n    is dropped if either this condition is satisfied, or the\n    --nodecount condition is satisfied.\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--edgefraction=&lt;f&gt;</code></td>\n  <td>\n    This option controls the number of displayed edges.  First of all,\n    an edge is dropped if either its source or destination node is\n    dropped.  Otherwise, the edge is dropped if the sample\n    count along the edge is less than this option's value multiplied\n    by the total count for the profile.  The default value is\n    0.001; i.e., edges that account for less than\n    0.1% of the total time are dropped.\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--focus=&lt;re&gt;</code></td>\n  <td>\n    This option controls what region of the graph is displayed\n    based on the regular expression supplied with the option.\n    For any path in the callgraph, we check all nodes in the path\n    against the supplied regular expression.  If none of the nodes\n    match, the path is dropped from the output.\n  </td>\n</tr>\n<tr valign=top>\n  <td><code>--ignore=&lt;re&gt;</code></td>\n  <td>\n    This option controls what region of the graph is displayed\n    based on the regular expression supplied with the option.\n    For any path in the callgraph, we check all nodes in the path\n    against the supplied regular expression.  If any of the nodes\n    match, the path is dropped from the output.\n  </td>\n</tr>\n</table>\n</center>\n\n<p>The dropped edges and nodes account for some count mismatches in\nthe display.  For example, the cumulative count for\n<code>snprintf()</code> in the first diagram above was 41.  However\nthe local count (1) and the count along the outgoing edges (12+1+20+6)\nadd up to only 40.</p>\n\n\n<h1>Caveats</h1>\n\n<ul>\n  <li> If the program exits because of a signal, the generated profile\n       will be <font color=red>incomplete, and may perhaps be\n       completely empty</font>.\n  <li> The displayed graph may have disconnected regions because\n       of the edge-dropping heuristics described above.\n  <li> If the program linked in a library that was not compiled\n       with enough symbolic information, all samples associated\n       with the library may be charged to the last symbol found\n       in the program before the library.  This will artificially\n       inflate the count for that symbol.\n  <li> If you run the program on one machine, and profile it on\n       another, and the shared libraries are different on the two\n       machines, the profiling output may be confusing: samples that\n       fall within  shared libaries may be assigned to arbitrary\n       procedures.\n  <li> If your program forks, the children will also be profiled\n       (since they inherit the same CPUPROFILE setting).  Each process\n       is profiled separately; to distinguish the child profiles from\n       the parent profile and from each other, all children will have\n       their process-id appended to the CPUPROFILE name.\n  <li> Due to a hack we make to work around a possible gcc bug, your\n       profiles may end up named strangely if the first character of\n       your CPUPROFILE variable has ascii value greater than 127.\n       This should be exceedingly rare, but if you need to use such a\n       name, just set prepend <code>./</code> to your filename:\n       <code>CPUPROFILE=./&Auml;gypten</code>.\n</ul>\n\n\n<hr>\n<address>Sanjay Ghemawat<br>\n<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->\n<!-- hhmts start -->\nLast modified: Fri May  9 14:41:29 PDT 2008\n<!-- hhmts end -->\n</address>\n</BODY>\n</HTML>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/designstyle.css",
    "content": "body {\n  background-color: #ffffff;\n  color: black;\n  margin-right: 1in;\n  margin-left: 1in;\n}\n\n\nh1, h2, h3, h4, h5, h6 {\n  color: #3366ff;\n  font-family: sans-serif;\n}\n@media print {\n  /* Darker version for printing */\n  h1, h2, h3, h4, h5, h6 {\n    color: #000080;\n    font-family: helvetica, sans-serif;\n  }\n}\n\nh1 { \n  text-align: center;\n  font-size: 18pt;\n}\nh2 {\n  margin-left: -0.5in;\n}\nh3 {\n  margin-left: -0.25in;\n}\nh4 {\n  margin-left: -0.125in;\n}\nhr {\n  margin-left: -1in;\n}\n\n/* Definition lists: definition term bold */\ndt {\n  font-weight: bold;\n}\n\naddress {\n  text-align: right;\n}\n/* Use the <code> tag for bits of code and <var> for variables and objects. */\ncode,pre,samp,var {\n  color: #006000;\n}\n/* Use the <file> tag for file and directory paths and names. */\nfile {\n  color: #905050;\n  font-family: monospace;\n}\n/* Use the <kbd> tag for stuff the user should type. */\nkbd {\n  color: #600000;\n}\ndiv.note p {\n  float: right;\n  width: 3in;\n  margin-right: 0%;\n  padding: 1px;\n  border: 2px solid #6060a0;\n  background-color: #fffff0;\n}\n\nUL.nobullets {\n  list-style-type: none;\n  list-style-image: none;\n  margin-left: -1em;\n}\n\n/*\nbody:after {\n  content: \"Google Confidential\";\n}\n*/\n\n/* pretty printing styles.  See prettify.js */\n.str { color: #080; }\n.kwd { color: #008; }\n.com { color: #800; }\n.typ { color: #606; }\n.lit { color: #066; }\n.pun { color: #660; }\n.pln { color: #000; }\n.tag { color: #008; }\n.atn { color: #606; }\n.atv { color: #080; }\npre.prettyprint { padding: 2px; border: 1px solid #888; }\n\n.embsrc { background: #eee; }\n\n@media print {\n  .str { color: #060; }\n  .kwd { color: #006; font-weight: bold; }\n  .com { color: #600; font-style: italic; }\n  .typ { color: #404; font-weight: bold; }\n  .lit { color: #044; }\n  .pun { color: #440; }\n  .pln { color: #000; }\n  .tag { color: #006; font-weight: bold; }\n  .atn { color: #404; }\n  .atv { color: #060; }\n}\n\n/* Table Column Headers */\n.hdr { \n  color: #006; \n  font-weight: bold; \n  background-color: #dddddd; }\n.hdr2 { \n  color: #006; \n  background-color: #eeeeee; }"
  },
  {
    "path": "distro/google-perftools-1.7/doc/heap_checker.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n\n<HEAD>\n  <link rel=\"stylesheet\" href=\"designstyle.css\">\n  <title>Google Heap Leak Checker</title>\n</HEAD>\n\n<BODY>\n\n<p align=right>\n  <i>Last modified\n  <script type=text/javascript>\n    var lm = new Date(document.lastModified);\n    document.write(lm.toDateString());\n  </script></i>\n</p>\n\n<p>This is the heap checker we use at Google to detect memory leaks in\nC++ programs.  There are three parts to using it: linking the library\ninto an application, running the code, and analyzing the output.</p>\n\n\n<H1>Linking in the Library</H1>\n\n<p>The heap-checker is part of tcmalloc, so to install the heap\nchecker into your executable, add <code>-ltcmalloc</code> to the\nlink-time step for your executable.  Also, while we don't necessarily\nrecommend this form of usage, it's possible to add in the profiler at\nrun-time using <code>LD_PRELOAD</code>:</p>\n<pre>% env LD_PRELOAD=\"/usr/lib/libtcmalloc.so\" <binary></pre>\n\n<p>This does <i>not</i> turn on heap checking; it just inserts the\ncode.  For that reason, it's practical to just always link\n<code>-ltcmalloc</code> into a binary while developing; that's what we\ndo at Google.  (However, since any user can turn on the profiler by\nsetting an environment variable, it's not necessarily recommended to\ninstall heapchecker-linked binaries into a production, running\nsystem.)  Note that if you wish to use the heap checker, you must\nalso use the tcmalloc memory-allocation library.  There is no way\ncurrently to use the heap checker separate from tcmalloc.</p>\n\n\n<h1>Running the Code</h1>\n\n<p>Note: For security reasons, heap profiling will not write to a file\n-- and is thus not usable -- for setuid programs.</p>\n\n<h2><a name=\"whole_program\">Whole-program Heap Leak Checking</a></h2>\n\n<p>The recommended way to use the heap checker is in \"whole program\"\nmode.  In this case, the heap-checker starts tracking memory\nallocations before the start of <code>main()</code>, and checks again\nat program-exit.  If it finds any memory leaks -- that is, any memory\nnot pointed to by objects that are still \"live\" at program-exit -- it\naborts the program (via <code>exit(1)</code>) and prints a message\ndescribing how to track down the memory leak (using <A\nHREF=\"heapprofile.html#pprof\">pprof</A>).</p>\n\n<p>The heap-checker records the stack trace for each allocation while\nit is active. This causes a significant increase in memory usage, in\naddition to slowing your program down.</p>\n\n<p>Here's how to run a program with whole-program heap checking:</p>\n\n<ol>\n  <li> <p>Define the environment variable HEAPCHECK to the <A\n       HREF=\"#types\">type of heap-checking</A> to do.  For instance,\n       to heap-check\n       <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>\n       <pre>% env HEAPCHECK=normal /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>\n</ol>\n\n<p>No other action is required.</p>\n\n<p>Note that since the heap-checker uses the heap-profiling framework\ninternally, it is not possible to run both the heap-checker and <A\nHREF=\"heapprofile.html\">heap profiler</A> at the same time.</p>\n\n\n<h3><a name=\"types\">Flavors of Heap Checking</a></h3>\n\n<p>These are the legal values when running a whole-program heap\ncheck:</p>\n<ol>\n  <li> <code>minimal</code>\n  <li> <code>normal</code>\n  <li> <code>strict</code>\n  <li> <code>draconian</code>\n</ol>\n\n<p>\"Minimal\" heap-checking starts as late as possible in a\ninitialization, meaning you can leak some memory in your\ninitialization routines (that run before <code>main()</code>, say),\nand not trigger a leak message.  If you frequently (and purposefully)\nleak data in one-time global initializers, \"minimal\" mode is useful\nfor you.  Otherwise, you should avoid it for stricter modes.</p>\n\n<p>\"Normal\" heap-checking tracks <A HREF=\"#live\">live objects</A> and\nreports a leak for any data that is not reachable via a live object\nwhen the program exits.</p>\n\n<p>\"Strict\" heap-checking is much like \"normal\" but has a few extra\nchecks that memory isn't lost in global destructors.  In particular,\nif you have a global variable that allocates memory during program\nexecution, and then \"forgets\" about the memory in the global\ndestructor (say, by setting the pointer to it to NULL) without freeing\nit, that will prompt a leak message in \"strict\" mode, though not in\n\"normal\" mode.</p>\n\n<p>\"Draconian\" heap-checking is appropriate for those who like to be\nvery precise about their memory management, and want the heap-checker\nto help them enforce it.  In \"draconian\" mode, the heap-checker does\nnot do \"live object\" checking at all, so it reports a leak unless\n<i>all</i> allocated memory is freed before program exit. (However,\nyou can use <A HREF=\"#disable\">IgnoreObject()</A> to re-enable\nliveness-checking on an object-by-object basis.)</p>\n\n<p>\"Normal\" mode, as the name implies, is the one used most often at\nGoogle.  It's appropriate for everyday heap-checking use.</p>\n\n<p>In addition, there are two other possible modes:</p>\n<ul>\n  <li> <code>as-is</code>\n  <li> <code>local</code>\n</ul>\n<p><code>as-is</code> is the most flexible mode; it allows you to\nspecify the various <A HREF=\"#options\">knobs</A> of the heap checker\nexplicitly.  <code>local</code> activates the <A\nHREF=\"#explicit\">explicit heap-check instrumentation</A>, but does not\nturn on any whole-program leak checking.</p>\n\n\n<h3><A NAME=\"tweaking\">Tweaking whole-program checking</A></h3>\n\n<p>In some cases you want to check the whole program for memory leaks,\nbut waiting for after <code>main()</code> exits to do the first\nwhole-program leak check is waiting too long: e.g. in a long-running\nserver one might wish to simply periodically check for leaks while the\nserver is running.  In this case, you can call the static method\n<code>NoGlobalLeaks()</code>, to verify no global leaks have happened\nas of that point in the program.</p>\n\n<p>Alternately, doing the check after <code>main()</code> exits might\nbe too late.  Perhaps you have some objects that are known not to\nclean up properly at exit.  You'd like to do the \"at exit\" check\nbefore those objects are destroyed (since while they're live, any\nmemory they point to will not be considered a leak).  In that case,\nyou can call <code>NoGlobalLeaks()</code> manually, near the end of\n<code>main()</code>, and then call <code>CancelGlobalCheck()</code> to\nturn off the automatic post-<code>main()</code> check.</p>\n\n<p>Finally, there's a helper macro for \"strict\" and \"draconian\" modes,\nwhich require all global memory to be freed before program exit.  This\nfreeing can be time-consuming and is often unnecessary, since libc\ncleans up all memory at program-exit for you.  If you want the\nbenefits of \"strict\"/\"draconian\" modes without the cost of all that\nfreeing, look at <code>REGISTER_HEAPCHECK_CLEANUP</code> (in\n<code>heap-checker.h</code>).  This macro allows you to mark specific\ncleanup code as active only when the heap-checker is turned on.</p>\n\n\n<h2><a name=\"explicit\">Explicit (Partial-program) Heap Leak Checking</h2>\n\n<p>Instead of whole-program checking, you can check certain parts of your\ncode to verify they do not have memory leaks.  This check verifies that\nbetween two parts of a program, no memory is allocated without being freed.</p>\n<p>To use this kind of checking code, bracket the code you want\nchecked by creating a <code>HeapLeakChecker</code> object at the\nbeginning of the code segment, and call\n<code>NoLeaks()</code> at the end.  These functions, and all others\nreferred to in this file, are declared in\n<code>&lt;google/heap-checker.h&gt;</code>.\n</p>\n\n<p>Here's an example:</p>\n<pre>\n  HeapLeakChecker heap_checker(\"test_foo\");\n  {\n    code that exercises some foo functionality;\n    this code should not leak memory;\n  }\n  if (!heap_checker.NoLeaks()) assert(NULL == \"heap memory leak\");\n</pre>\n\n<p>Note that adding in the <code>HeapLeakChecker</code> object merely\ninstruments the code for leak-checking.  To actually turn on this\nleak-checking on a particular run of the executable, you must still\nrun with the heap-checker turned on:</p>\n<pre>% env HEAPCHECK=local /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>\n<p>If you want to do whole-program leak checking in addition to this\nmanual leak checking, you can run in <code>normal</code> or some other\nmode instead: they'll run the \"local\" checks in addition to the\nwhole-program check.</p>\n\n\n<h2><a name=\"disable\">Disabling Heap-checking of Known Leaks</a></h2>\n\n<p>Sometimes your code has leaks that you know about and are willing\nto accept.  You would like the heap checker to ignore them when\nchecking your program.  You can do this by bracketing the code in\nquestion with an appropriate heap-checking construct:</p>\n<pre>\n   ...\n   {\n     HeapLeakChecker::Disabler disabler;\n     &lt;leaky code&gt;\n   }\n   ...\n</pre>\nAny objects allocated by <code>leaky code</code> (including inside any\nroutines called by <code>leaky code</code>) and any objects reachable\nfrom such objects are not reported as leaks.\n\n<p>Alternately, you can use <code>IgnoreObject()</code>, which takes a\npointer to an object to ignore.  That memory, and everything reachable\nfrom it (by following pointers), is ignored for the purposes of leak\nchecking.  You can call <code>UnIgnoreObject()</code> to undo the\neffects of <code>IgnoreObject()</code>.</p>\n\n\n<h2><a name=\"options\">Tuning the Heap Checker</h2>\n\n<p>The heap leak checker has many options, some that trade off running\ntime and accuracy, and others that increase the sensitivity at the\nrisk of returning false positives.  For most uses, the range covered\nby the <A HREF=\"#types\">heap-check flavors</A> is enough, but in\nspecialized cases more control can be helpful.</p>\n\n<p>\nThese options are specified via environment varaiables.\n</p>\n\n<p>This first set of options controls sensitivity and accuracy.  These\noptions are ignored unless you run the heap checker in <A\nHREF=\"#types\">as-is</A> mode.\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_AFTER_DESTRUCTORS</code></td>\n  <td>Default: false</td>\n  <td>\n    When true, do the final leak check after all other global\n    destructors have run.  When false, do it after all\n    <code>REGISTER_HEAPCHECK_CLEANUP</code>, typically much earlier in\n    the global-destructor process.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_IGNORE_THREAD_LIVE</code></td>\n  <td>Default: true</td>\n  <td>\n    If true, ignore objects reachable from thread stacks and registers\n    (that is, do not report them as leaks).\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_IGNORE_GLOBAL_LIVE</code></td>\n  <td>Default: true</td>\n  <td>\n    If true, ignore objects reachable from global variables and data\n    (that is, do not report them as leaks).\n  </td>\n</tr>\n\n</table>\n\n<p>These options modify the behavior of whole-program leak\nchecking.</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_MAX_LEAKS</code></td>\n  <td>Default: 20</td>\n  <td>\n    The maximum number of leaks to be printed to stderr (all leaks are still\n    emitted to file output for pprof to visualize). If negative or zero,\n    print all the leaks found.\n  </td>\n</tr>\n\n\n</table>\n\n<p>These options apply to all types of leak checking.</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_IDENTIFY_LEAKS</code></td>\n  <td>Default: false</td>\n  <td>\n    If true, generate the addresses of the leaked objects in the\n    generated memory leak profile files.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_TEST_POINTER_ALIGNMENT</code></td>\n  <td>Default: false</td>\n  <td>\n    If true, check all leaks to see if they might be due to the use\n    of unaligned pointers.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_POINTER_SOURCE_ALIGNMENT</code></td>\n  <td>Default: sizeof(void*)</td>\n  <td>\n    Alignment at which all pointers in memory are supposed to be located.\n    Use 1 if any alignment is ok.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>PPROF_PATH</code></td>\n  <td>Default: pprof</td>\n<td>\n    The location of the <code>pprof</code> executable.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_CHECK_DUMP_DIRECTORY</code></td>\n  <td>Default: /tmp</td>\n  <td>\n    Where the heap-profile files are kept while the program is running.\n  </td>\n</tr>\n\n</table>\n\n\n<h2>Tips for Handling Detected Leaks</h2>\n\n<p>What do you do when the heap leak checker detects a memory leak?\nFirst, you should run the reported <code>pprof</code> command;\nhopefully, that is enough to track down the location where the leak\noccurs.</p>\n\n<p>If the leak is a real leak, you should fix it!</p>\n\n<p>If you are sure that the reported leaks are not dangerous and there\nis no good way to fix them, then you can use\n<code>HeapLeakChecker::Disabler</code> and/or\n<code>HeapLeakChecker::IgnoreObject()</code> to disable heap-checking\nfor certain parts of the codebase.</p>\n\n<p>In \"strict\" or \"draconian\" mode, leaks may be due to incomplete\ncleanup in the destructors of global variables.  If you don't wish to\naugment the cleanup routines, but still want to run in \"strict\" or\n\"draconian\" mode, consider using <A\nHREF=\"#tweaking\"><code>REGISTER_HEAPCHECK_CLEANUP</code></A>.</p>\n\n<h2>Hints for Debugging Detected Leaks</h2>\n\n<p>Sometimes it can be useful to not only know the exact code that\nallocates the leaked objects, but also the addresses of the leaked objects.\nCombining this e.g. with additional logging in the program\none can then track which subset of the allocations\nmade at a certain spot in the code are leaked.\n<br/>\nTo get the addresses of all leaked objects\n  define the environment variable <code>HEAP_CHECK_IDENTIFY_LEAKS</code>\n  to be <code>1</code>.\nThe object addresses will be reported in the form of addresses\nof fake immediate callers of the memory allocation routines.\nNote that the performance of doing leak-checking in this mode\ncan be noticeably worse than the default mode.\n</p>\n\n<p>One relatively common class of leaks that don't look real\nis the case of multiple initialization.\nIn such cases the reported leaks are typically things that are\nlinked from some global objects,\nwhich are initialized and say never modified again.\nThe non-obvious cause of the leak is frequently the fact that\nthe initialization code for these objects executes more than once.\n<br/>\nE.g. if the code of some <code>.cc</code> file is made to be included twice\ninto the binary, then the constructors for global objects defined in that file\nwill execute twice thus leaking the things allocated on the first run.\n<br/>\nSimilar problems can occur if object initialization is done more explicitly\ne.g. on demand by a slightly buggy code\nthat does not always ensure only-once initialization.\n</p>\n\n<p>\nA more rare but even more puzzling problem can be use of not properly\naligned pointers (maybe inside of not properly aligned objects).\nNormally such pointers are not followed by the leak checker,\nhence the objects reachable only via such pointers are reported as leaks.\nIf you suspect this case\n  define the environment variable <code>HEAP_CHECK_TEST_POINTER_ALIGNMENT</code>\n  to be <code>1</code>\nand then look closely at the generated leak report messages.\n</p>\n\n<h1>How It Works</h1>\n\n<p>When a <code>HeapLeakChecker</code> object is constructed, it dumps\na memory-usage profile named\n<code>&lt;prefix&gt;.&lt;name&gt;-beg.heap</code> to a temporary\ndirectory.  When <code>NoLeaks()</code>\nis called (for whole-program checking, this happens automatically at\nprogram-exit), it dumps another profile, named\n<code>&lt;prefix&gt;.&lt;name&gt;-end.heap</code>.\n(<code>&lt;prefix&gt;</code> is typically determined automatically,\nand <code>&lt;name&gt;</code> is typically <code>argv[0]</code>.)  It\nthen compares the two profiles.  If the second profile shows\nmore memory use than the first, the\n<code>NoLeaks()</code> function will\nreturn false.  For \"whole program\" profiling, this will cause the\nexecutable to abort (via <code>exit(1)</code>).  In all cases, it will\nprint a message on how to process the dumped profiles to locate\nleaks.</p>\n\n<h3><A name=live>Detecting Live Objects</A></h3>\n\n<p>At any point during a program's execution, all memory that is\naccessible at that time is considered \"live.\"  This includes global\nvariables, and also any memory that is reachable by following pointers\nfrom a global variable.  It also includes all memory reachable from\nthe current stack frame and from current CPU registers (this captures\nlocal variables).  Finally, it includes the thread equivalents of\nthese: thread-local storage and thread heaps, memory reachable from\nthread-local storage and thread heaps, and memory reachable from\nthread CPU registers.</p>\n\n<p>In all modes except \"draconian,\" live memory is not\nconsidered to be a leak.  We detect this by doing a liveness flood,\ntraversing pointers to heap objects starting from some initial memory\nregions we know to potentially contain live pointer data.  Note that\nthis flood might potentially not find some (global) live data region\nto start the flood from.  If you find such, please file a bug.</p>\n\n<p>The liveness flood attempts to treat any properly aligned byte\nsequences as pointers to heap objects and thinks that it found a good\npointer whenever the current heap memory map contains an object with\nthe address whose byte representation we found.  Some pointers into\nnot-at-start of object will also work here.</p>\n\n<p>As a result of this simple approach, it's possible (though\nunlikely) for the flood to be inexact and occasionally result in\nleaked objects being erroneously determined to be live.  For instance,\nrandom bit patterns can happen to look like pointers to leaked heap\nobjects.  More likely, stale pointer data not corresponding to any\nlive program variables can be still present in memory regions,\nespecially in thread stacks.  For instance, depending on how the local\n<code>malloc</code> is implemented, it may reuse a heap object\naddress:</p>\n<pre>\n    char* p = new char[1];   // new might return 0x80000000, say.\n    delete p;\n    new char[1];             // new might return 0x80000000 again\n    // This last new is a leak, but doesn't seem it: p looks like it points to it\n</pre>\n\n<p>In other words, imprecisions in the liveness flood mean that for\nany heap leak check we might miss some memory leaks.  This means that\nfor local leak checks, we might report a memory leak in the local\narea, even though the leak actually happened before the\n<code>HeapLeakChecker</code> object was constructed.  Note that for\nwhole-program checks, a leak report <i>does</i> always correspond to a\nreal leak (since there's no \"before\" to have created a false-live\nobject).</p>\n\n<p>While this liveness flood approach is not very portable and not\n100% accurate, it works in most cases and saves us from writing a lot\nof explicit clean up code and other hassles when dealing with thread\ndata.</p>\n\n\n<h3>Visualizing Leak with <code>pprof</code></h3>\n\n<p>\nThe heap checker automatically prints basic leak info with stack traces of\nleaked objects' allocation sites, as well as a pprof command line that can be\nused to visualize the call-graph involved in these allocations.\nThe latter can be much more useful for a human\nto see where/why the leaks happened, especially if the leaks are numerous.\n</p>\n\n<h3>Leak-checking and Threads</h3>\n\n<p>At the time of HeapLeakChecker's construction and during\n<code>NoLeaks()</code> calls, we grab a lock\nand then pause all other threads so other threads do not interfere\nwith recording or analyzing the state of the heap.</p>\n\n<p>In general, leak checking works correctly in the presence of\nthreads.  However, thread stack data liveness determination (via\n<code>base/thread_lister.h</code>) does not work when the program is\nrunning under GDB, because the ptrace functionality needed for finding\nthreads is already hooked to by GDB.  Conversely, leak checker's\nptrace attempts might also interfere with GDB.  As a result, GDB can\nresult in potentially false leak reports.  For this reason, the\nheap-checker turns itself off when running under GDB.</p>\n\n<p>Also, <code>thread_lister</code> only works for Linux pthreads;\nleak checking is unlikely to handle other thread implementations\ncorrectly.</p>\n\n<p>As mentioned in the discussion of liveness flooding, thread-stack\nliveness determination might mis-classify as reachable objects that\nvery recently became unreachable (leaked).  This can happen when the\npointers to now-logically-unreachable objects are present in the\nactive thread stack frame.  In other words, trivial code like the\nfollowing might not produce the expected leak checking outcome\ndepending on how the compiled code works with the stack:</p>\n<pre>\n  int* foo = new int [20];\n  HeapLeakChecker check(\"a_check\");\n  foo = NULL;\n  // May fail to trigger.\n  if (!heap_checker.NoLeaks()) assert(NULL == \"heap memory leak\");\n</pre>\n\n\n<hr>\n<address>Maxim Lifantsev<br>\n<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->\n<!-- hhmts start -->\nLast modified: Fri Jul 13 13:14:33 PDT 2007\n<!-- hhmts end -->\n</address>\n</body>\n</html>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/heapprofile.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n\n<HEAD>\n  <link rel=\"stylesheet\" href=\"designstyle.css\">\n  <title>Google Heap Profiler</title>\n</HEAD>\n\n<BODY>\n\n<p align=right>\n  <i>Last modified\n  <script type=text/javascript>\n    var lm = new Date(document.lastModified);\n    document.write(lm.toDateString());\n  </script></i>\n</p>\n\n<p>This is the heap profiler we use at Google, to explore how C++\nprograms manage memory.  This facility can be useful for</p>\n<ul>\n  <li> Figuring out what is in the program heap at any given time\n  <li> Locating memory leaks\n  <li> Finding places that do a lot of allocation\n</ul>\n\n<p>The profiling system instruments all allocations and frees.  It\nkeeps track of various pieces of information per allocation site.  An\nallocation site is defined as the active stack trace at the call to\n<code>malloc</code>, <code>calloc</code>, <code>realloc</code>, or,\n<code>new</code>.</p>\n\n<p>There are three parts to using it: linking the library into an\napplication, running the code, and analyzing the output.</p>\n\n\n<h1>Linking in the Library</h1>\n\n<p>To install the heap profiler into your executable, add\n<code>-ltcmalloc</code> to the link-time step for your executable.\nAlso, while we don't necessarily recommend this form of usage, it's\npossible to add in the profiler at run-time using\n<code>LD_PRELOAD</code>:\n<pre>% env LD_PRELOAD=\"/usr/lib/libtcmalloc.so\" &lt;binary&gt;</pre>\n\n<p>This does <i>not</i> turn on heap profiling; it just inserts the\ncode.  For that reason, it's practical to just always link\n<code>-ltcmalloc</code> into a binary while developing; that's what we\ndo at Google.  (However, since any user can turn on the profiler by\nsetting an environment variable, it's not necessarily recommended to\ninstall profiler-linked binaries into a production, running\nsystem.)  Note that if you wish to use the heap profiler, you must\nalso use the tcmalloc memory-allocation library.  There is no way\ncurrently to use the heap profiler separate from tcmalloc.</p>\n\n\n<h1>Running the Code</h1>\n\n<p>There are several alternatives to actually turn on heap profiling\nfor a given run of an executable:</p>\n\n<ol>\n  <li> <p>Define the environment variable HEAPPROFILE to the filename\n       to dump the profile to.  For instance, to profile\n       <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>\n       <pre>% env HEAPPROFILE=/tmp/mybin.hprof /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>\n  <li> <p>In your code, bracket the code you want profiled in calls to\n       <code>HeapProfilerStart()</code> and <code>HeapProfilerStop()</code>.\n       (These functions are declared in <code>&lt;google/heap-profiler.h&gt;</code>.)\n       <code>HeapProfilerStart()</code> will take the\n       profile-filename-prefix as an argument.  Then, as often as\n       you'd like before calling <code>HeapProfilerStop()</code>, you\n       can use <code>HeapProfilerDump()</code> or\n       <code>GetHeapProfile()</code> to examine the profile.  In case\n       it's useful, <code>IsHeapProfilerRunning()</code> will tell you\n       whether you've already called HeapProfilerStart() or not.</p>\n</ol>\n\n\n<p>For security reasons, heap profiling will not write to a file --\nand is thus not usable -- for setuid programs.</p>\n\n<H2>Modifying Runtime Behavior</H2>\n\n<p>You can more finely control the behavior of the heap profiler via\nenvironment variables.</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>HEAP_PROFILE_ALLOCATION_INTERVAL</code></td>\n  <td>default: 1073741824 (1 Gb)</td>\n  <td>\n    Dump heap profiling information once every specified number of\n    bytes has been allocated by the program.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_PROFILE_INUSE_INTERVAL</code></td>\n  <td>default: 104857600 (100 Mb)</td>\n  <td>\n    Dump heap profiling information whenever the high-water memory\n    usage mark increases by the specified number of bytes.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_PROFILE_MMAP</code></td>\n  <td>default: false</td>\n  <td>\n    Profile <code>mmap</code>, <code>mremap</code> and <code>sbrk</code>\n    calls in addition\n    to <code>malloc</code>, <code>calloc</code>, <code>realloc</code>,\n    and <code>new</code>.  <b>NOTE:</b> this causes the profiler to\n    profile calls internal to tcmalloc, since tcmalloc and friends use\n    mmap and sbrk internally for allocations.  One partial solution is\n    to filter these allocations out when running <code>pprof</code>,\n    with something like\n    <code>pprof --ignore='DoAllocWithArena|SbrkSysAllocator::Alloc|MmapSysAllocator::Alloc</code>.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_PROFILE_MMAP_ONLY</code></td>\n  <td>default: false</td>\n  <td>\n    Only profile <code>mmap</code>, <code>mremap</code>, and <code>sbrk</code>\n    calls; do not profile\n    <code>malloc</code>, <code>calloc</code>, <code>realloc</code>,\n    or <code>new</code>.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>HEAP_PROFILE_MMAP_LOG</code></td>\n  <td>default: false</td>\n  <td>\n    Log <code>mmap</code>/<code>munmap</code> calls.\n  </td>\n</tr>\n\n</table>\n\n<H2>Checking for Leaks</H2>\n\n<p>You can use the heap profiler to manually check for leaks, for\ninstance by reading the profiler output and looking for large\nallocations.  However, for that task, it's easier to use the <A\nHREF=\"heap_checker.html\">automatic heap-checking facility</A> built\ninto tcmalloc.</p>\n\n\n<h1><a name=\"pprof\">Analyzing the Output</a></h1>\n\n<p>If heap-profiling is turned on in a program, the program will\nperiodically write profiles to the filesystem.  The sequence of\nprofiles will be named:</p>\n<pre>\n           &lt;prefix&gt;.0000.heap\n           &lt;prefix&gt;.0001.heap\n           &lt;prefix&gt;.0002.heap\n           ...\n</pre>\n<p>where <code>&lt;prefix&gt;</code> is the filename-prefix supplied\nwhen running the code (e.g. via the <code>HEAPPROFILE</code>\nenvironment variable).  Note that if the supplied prefix\ndoes not start with a <code>/</code>, the profile files will be\nwritten to the program's working directory.</p>\n\n<p>The profile output can be viewed by passing it to the\n<code>pprof</code> tool -- the same tool that's used to analyze <A\nHREF=\"cpuprofile.html\">CPU profiles</A>.\n\n<p>Here are some examples.  These examples assume the binary is named\n<code>gfs_master</code>, and a sequence of heap profile files can be\nfound in files named:</p>\n<pre>\n  /tmp/profile.0001.heap\n  /tmp/profile.0002.heap\n  ...\n  /tmp/profile.0100.heap\n</pre>\n\n<h3>Why is a process so big</h3>\n\n<pre>\n    % pprof --gv gfs_master /tmp/profile.0100.heap\n</pre>\n\n<p>This command will pop-up a <code>gv</code> window that displays\nthe profile information as a directed graph.  Here is a portion\nof the resulting output:</p>\n\n<p><center>\n<img src=\"heap-example1.png\">\n</center></p>\n\nA few explanations:\n<ul>\n<li> <code>GFS_MasterChunk::AddServer</code> accounts for 255.6 MB\n     of the live memory, which is 25% of the total live memory.\n<li> <code>GFS_MasterChunkTable::UpdateState</code> is directly\n     accountable for 176.2 MB of the live memory (i.e., it directly\n     allocated 176.2 MB that has not been freed yet).  Furthermore,\n     it and its callees are responsible for 729.9 MB.  The\n     labels on the outgoing edges give a good indication of the\n     amount allocated by each callee.\n</ul>\n\n<h3>Comparing Profiles</h3>\n\n<p>You often want to skip allocations during the initialization phase\nof a program so you can find gradual memory leaks.  One simple way to\ndo this is to compare two profiles -- both collected after the program\nhas been running for a while.  Specify the name of the first profile\nusing the <code>--base</code> option.  For example:</p>\n<pre>\n   % pprof --base=/tmp/profile.0004.heap gfs_master /tmp/profile.0100.heap\n</pre>\n\n<p>The memory-usage in <code>/tmp/profile.0004.heap</code> will be\nsubtracted from the memory-usage in\n<code>/tmp/profile.0100.heap</code> and the result will be\ndisplayed.</p>\n\n<h3>Text display</h3>\n\n<pre>\n% pprof --text gfs_master /tmp/profile.0100.heap\n   255.6  24.7%  24.7%    255.6  24.7% GFS_MasterChunk::AddServer\n   184.6  17.8%  42.5%    298.8  28.8% GFS_MasterChunkTable::Create\n   176.2  17.0%  59.5%    729.9  70.5% GFS_MasterChunkTable::UpdateState\n   169.8  16.4%  75.9%    169.8  16.4% PendingClone::PendingClone\n    76.3   7.4%  83.3%     76.3   7.4% __default_alloc_template::_S_chunk_alloc\n    49.5   4.8%  88.0%     49.5   4.8% hashtable::resize\n   ...\n</pre>\n\n<p>\n<ul>\n  <li> The first column contains the direct memory use in MB.\n  <li> The fourth column contains memory use by the procedure\n       and all of its callees.\n  <li> The second and fifth columns are just percentage\n       representations of the numbers in the first and fourth columns.\n  <li> The third column is a cumulative sum of the second column\n       (i.e., the <code>k</code>th entry in the third column is the\n       sum of the first <code>k</code> entries in the second column.)\n</ul>\n\n<h3>Ignoring or focusing on specific regions</h3>\n\n<p>The following command will give a graphical display of a subset of\nthe call-graph.  Only paths in the call-graph that match the regular\nexpression <code>DataBuffer</code> are included:</p>\n<pre>\n% pprof --gv --focus=DataBuffer gfs_master /tmp/profile.0100.heap\n</pre>\n\n<p>Similarly, the following command will omit all paths subset of the\ncall-graph.  All paths in the call-graph that match the regular\nexpression <code>DataBuffer</code> are discarded:</p>\n<pre>\n% pprof --gv --ignore=DataBuffer gfs_master /tmp/profile.0100.heap\n</pre>\n\n<h3>Total allocations + object-level information</h3>\n\n<p>All of the previous examples have displayed the amount of in-use\nspace.  I.e., the number of bytes that have been allocated but not\nfreed.  You can also get other types of information by supplying a\nflag to <code>pprof</code>:</p>\n\n<center>\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>--inuse_space</code></td>\n  <td>\n     Display the number of in-use megabytes (i.e. space that has\n     been allocated but not freed).  This is the default.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>--inuse_objects</code></td>\n  <td>\n     Display the number of in-use objects (i.e. number of\n     objects that have been allocated but not freed).\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>--alloc_space</code></td>\n  <td>\n     Display the number of allocated megabytes.  This includes\n     the space that has since been de-allocated.  Use this\n     if you want to find the main allocation sites in the\n     program.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>--alloc_objects</code></td>\n  <td>\n     Display the number of allocated objects.  This includes\n     the objects that have since been de-allocated.  Use this\n     if you want to find the main allocation sites in the\n     program.\n  </td>\n\n</table>\n</center>\n\n\n<h3>Interactive mode</a></h3>\n\n<p>By default -- if you don't specify any flags to the contrary --\npprof runs in interactive mode.  At the <code>(pprof)</code> prompt,\nyou can run many of the commands described above.  You can type\n<code>help</code> for a list of what commands are available in\ninteractive mode.</p>\n\n\n<h1>Caveats</h1>\n\n<ul>\n  <li> Heap profiling requires the use of libtcmalloc.  This\n       requirement may be removed in a future version of the heap\n       profiler, and the heap profiler separated out into its own\n       library.\n     \n  <li> If the program linked in a library that was not compiled\n       with enough symbolic information, all samples associated\n       with the library may be charged to the last symbol found\n       in the program before the libary.  This will artificially\n       inflate the count for that symbol.\n\n  <li> If you run the program on one machine, and profile it on\n       another, and the shared libraries are different on the two\n       machines, the profiling output may be confusing: samples that\n       fall within the shared libaries may be assigned to arbitrary\n       procedures.\n\n  <li> Several libraries, such as some STL implementations, do their\n       own memory management.  This may cause strange profiling\n       results.  We have code in libtcmalloc to cause STL to use\n       tcmalloc for memory management (which in our tests is better\n       than STL's internal management), though it only works for some\n       STL implementations.\n\n  <li> If your program forks, the children will also be profiled\n       (since they inherit the same HEAPPROFILE setting).  Each\n       process is profiled separately; to distinguish the child\n       profiles from the parent profile and from each other, all\n       children will have their process-id attached to the HEAPPROFILE\n       name.\n     \n  <li> Due to a hack we make to work around a possible gcc bug, your\n       profiles may end up named strangely if the first character of\n       your HEAPPROFILE variable has ascii value greater than 127.\n       This should be exceedingly rare, but if you need to use such a\n       name, just set prepend <code>./</code> to your filename:\n       <code>HEAPPROFILE=./&Auml;gypten</code>.\n</ul>\n\n<hr>\n<address>Sanjay Ghemawat<br>\n<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->\n<!-- hhmts start -->\nLast modified: Sat Feb 24 14:33:15 PST 2007  (csilvers)\n<!-- hhmts end -->\n</address>\n</body>\n</html>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/index.html",
    "content": "<HTML>\n\n<HEAD>\n<title>Google Performance Tools</title>\n</HEAD>\n\n<BODY>\n<ul>\n  <li> <A HREF=\"tcmalloc.html\">thread-caching malloc</A>\n  <li> <A HREF=\"heap_checker.html\">heap-checking using tcmalloc</A>\n  <li> <A HREF=\"heapprofile.html\">heap-profiling using tcmalloc</A>\n  <li> <A HREF=\"cpuprofile.html\">CPU profiler</A>\n</ul>\n\n<hr>\nLast modified: Wed Mar 21 22:46:51 PDT 2007\n\n\n</BODY>\n\n</HTML>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/overview.dot",
    "content": "digraph Overview {\nnode [shape = box]\n\n{rank=same\nT1 [label=\"Thread Cache\"]\nTsep [label=\"...\", shape=plaintext]\nTn [label=\"Thread Cache\"]\nT1 -> Tsep -> Tn [style=invis]\n}\n\nC [label=\"Central\\nHeap\"]\nT1 -> C [dir=both]\nTn -> C [dir=both]\n\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/pageheap.dot",
    "content": "digraph PageHeap {\nrankdir=LR\nnode [shape=box, width=0.3, height=0.3]\nnodesep=.05\n\nheap [shape=record, height=3, label=\"<f0>1 page|<f1>2 pages|<f2>3 pages|...|<f255>255 pages|<frest>rest\"]\nO0 [shape=record, label=\"\"]\nO1 [shape=record, label=\"\"]\nO2 [shape=record, label=\"{|}\"]\nO3 [shape=record, label=\"{|}\"]\nO4 [shape=record, label=\"{||}\"]\nO5 [shape=record, label=\"{||}\"]\nO6 [shape=record, label=\"{|...|}\"]\nO7 [shape=record, label=\"{|...|}\"]\nO8 [shape=record, label=\"{|.....|}\"]\nO9 [shape=record, label=\"{|.....|}\"]\nsep1 [shape=plaintext, label=\"...\"]\nsep2 [shape=plaintext, label=\"...\"]\nsep3 [shape=plaintext, label=\"...\"]\nsep4 [shape=plaintext, label=\"...\"]\nsep5 [shape=plaintext, label=\"...\"]\n\nheap:f0 -> O0 -> O1 -> sep1\nheap:f1 -> O2 -> O3 -> sep2\nheap:f2 -> O4 -> O5 -> sep3\nheap:f255 -> O6 -> O7 -> sep4\nheap:frest -> O8 -> O9 -> sep5\n\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/pprof.1",
    "content": ".\\\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.\n.TH PPROF \"1\" \"February 2005\" \"pprof (part of google-perftools)\" Google\n.SH NAME\npprof \\- manual page for pprof (part of google-perftools)\n.SH SYNOPSIS\n.B pprof\n[\\fIoptions\\fR] \\fI<program> <profile>\\fR\n.SH DESCRIPTION\n.IP\nPrints specified cpu- or heap-profile\n.SH OPTIONS\n.TP\n\\fB\\-\\-cum\\fR\nSort by cumulative data\n.TP\n\\fB\\-\\-base=\\fR<base>\nSubtract <base> from <profile> before display\n.SS \"Reporting Granularity:\"\n.TP\n\\fB\\-\\-addresses\\fR\nReport at address level\n.TP\n\\fB\\-\\-lines\\fR\nReport at source line level\n.TP\n\\fB\\-\\-functions\\fR\nReport at function level [default]\n.TP\n\\fB\\-\\-files\\fR\nReport at source file level\n.SS \"Output type:\"\n.TP\n\\fB\\-\\-text\\fR\nGenerate text report [default]\n.TP\n\\fB\\-\\-gv\\fR\nGenerate Postscript and display\n.TP\n\\fB\\-\\-list=\\fR<regexp>\nGenerate source listing of matching routines\n.TP\n\\fB\\-\\-disasm=\\fR<regexp>\nGenerate disassembly of matching routines\n.TP\n\\fB\\-\\-dot\\fR\nGenerate DOT file to stdout\n.TP\n\\fB\\-\\-ps\\fR\nGenerate Postcript to stdout\n.TP\n\\fB\\-\\-pdf\\fR\nGenerate PDF to stdout\n.TP\n\\fB\\-\\-gif\\fR\nGenerate GIF to stdout\n.SS \"Heap-Profile Options:\"\n.TP\n\\fB\\-\\-inuse_space\\fR\nDisplay in-use (mega)bytes [default]\n.TP\n\\fB\\-\\-inuse_objects\\fR\nDisplay in-use objects\n.TP\n\\fB\\-\\-alloc_space\\fR\nDisplay allocated (mega)bytes\n.TP\n\\fB\\-\\-alloc_objects\\fR\nDisplay allocated objects\n.TP\n\\fB\\-\\-show_bytes\\fR\nDisplay space in bytes\n.TP\n\\fB\\-\\-drop_negative\\fR\nIgnore negaive differences\n.SS \"Call-graph Options:\"\n.TP\n\\fB\\-\\-nodecount=\\fR<n>\nShow at most so many nodes [default=80]\n.TP\n\\fB\\-\\-nodefraction=\\fR<f>\nHide nodes below <f>*total [default=.005]\n.TP\n\\fB\\-\\-edgefraction=\\fR<f>\nHide edges below <f>*total [default=.001]\n.TP\n\\fB\\-\\-focus=\\fR<regexp>\nFocus on nodes matching <regexp>\n.TP\n\\fB\\-\\-ignore=\\fR<regexp>\nIgnore nodes matching <regexp>\n.TP\n\\fB\\-\\-scale=\\fR<n>\nSet GV scaling [default=0]\n.SH EXAMPLES\n\npprof /bin/ls ls.prof\n.IP\nOutputs one line per procedure\n.PP\npprof \\fB\\-\\-gv\\fR /bin/ls ls.prof\n.IP\nDisplays annotated call-graph via 'gv'\n.PP\npprof \\fB\\-\\-gv\\fR \\fB\\-\\-focus\\fR=\\fIMutex\\fR /bin/ls ls.prof\n.IP\nRestricts to code paths including a .*Mutex.* entry\n.PP\npprof \\fB\\-\\-gv\\fR \\fB\\-\\-focus\\fR=\\fIMutex\\fR \\fB\\-\\-ignore\\fR=\\fIstring\\fR /bin/ls ls.prof\n.IP\nCode paths including Mutex but not string\n.PP\npprof \\fB\\-\\-list\\fR=\\fIgetdir\\fR /bin/ls ls.prof\n.IP\nDissassembly (with per-line annotations) for getdir()\n.PP\npprof \\fB\\-\\-disasm\\fR=\\fIgetdir\\fR /bin/ls ls.prof\n.IP\nDissassembly (with per-PC annotations) for getdir()\n.SH COPYRIGHT\nCopyright \\(co 2005 Google Inc.\n.SH \"SEE ALSO\"\nFurther documentation for\n.B pprof\nis maintained as a web page called\n.B cpu_profiler.html\nand is likely installed at one of the following locations:\n.IP\n.B /usr/share/google-perftools/cpu_profiler.html\n.br\n.B /usr/local/share/google-perftools/cpu_profiler.html\n.PP\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/pprof_remote_servers.html",
    "content": "<HTML>\n\n<HEAD>\n<title>pprof and Remote Servers</title>\n</HEAD>\n\n<BODY>\n\n<h1><code>pprof</code> and Remote Servers</h1>\n\n<p>In mid-2006, we added an experimental facility to <A\nHREF=\"cpu_profiler.html\">pprof</A>, the tool that analyzes CPU and\nheap profiles.  This facility allows you to collect profile\ninformation from running applications.  It makes it easy to collect\nprofile information without having to stop the program first, and\nwithout having to log into the machine where the application is\nrunning.  This is meant to be used on webservers, but will work on any\napplication that can be modified to accept TCP connections on a port\nof its choosing, and to respond to HTTP requests on that port.</p>\n\n<p>We do not currently have infrastructure, such as apache modules,\nthat you can pop into a webserver or other application to get the\nnecessary functionality \"for free.\"  However, it's easy to generate\nthe necessary data, which should allow the interested developer to add\nthe necessary support into his or her applications.</p>\n\n<p>To use <code>pprof</code> in this experimental \"server\" mode, you\ngive the script a host and port it should query, replacing the normal\ncommandline arguments of application + profile file:</p>\n<pre>\n   % pprof internalweb.mycompany.com:80\n</pre>\n\n<p>The host must be listening on that port, and be able to accept HTTP/1.0\nrequests -- sent via <code>wget</code> and <code>curl</code> -- for\nseveral urls.  The following sections list the urls that\n<code>pprof</code> can send, and the responses it expects in\nreturn.</p>\n\n<p>Here are examples that pprof will recognize, when you give them\non the commandline, are urls.  In general, you\nspecify the host and a port (the port-number is required), and put\nthe service-name at the end of the url.:</p>\n<blockquote><pre>\nhttp://myhost:80/pprof/heap            # retrieves a heap profile\nhttp://myhost:8008/pprof/profile       # retrieves a CPU profile\nhttp://myhost:80                       # retrieves a CPU profile (the default)\nhttp://myhost:8080/                    # retrieves a CPU profile (the default)\nmyhost:8088/pprof/growth               # \"http://\" is optional, but port is not\nhttp://myhost:80/myservice/pprof/heap  # /pprof/heap just has to come at the end\nhttp://myhost:80/pprof/pmuprofile      # CPU profile using performance counters\n</pre></blockquote>\n\n<h2> <code><b>/pprof/heap</b></code> </h2>\n\n<p><code>pprof</code> asks for the url <code>/pprof/heap</code> to\nget heap information.  The actual url is controlled via the variable\n<code>HEAP_PAGE</code> in the <code>pprof</code> script, so you\ncan change it if you'd like.</p>\n\n<p>There are two ways to get this data.  The first is to call</p>\n<pre>\n    MallocExtension::instance()->GetHeapSample(&output);\n</pre>\n<p>and have the server send <code>output</code> back as an HTTP\nresponse to <code>pprof</code>.  <code>MallocExtension</code> is\ndefined in the header file <code>google/malloc_extension.h</code>.</p>\n\n<p>Note this will only only work if the binary is being run with\nsampling turned on (which is not the default).  To do this, set the\nenvironment variable <code>TCMALLOC_SAMPLE_PARAMETER</code> to a\npositive value, such as 524288, before running.</p>\n\n<p>The other way is to call <code>HeapProfileStart(filename)</code>\n(from <code>heap-profiler.h</code>), continue to do work, and then,\nsome number of seconds later, call <code>GetHeapProfile()</code>\n(followed by <code>HeapProfilerStop()</code>).  The server can send\nthe output of <code>GetHeapProfile</code> back as the HTTP response to\npprof.  (Note you must <code>free()</code> this data after using it.)\nThis is similar to how <A HREF=\"#profile\">profile requests</A> are\nhandled, below.  This technique does not require the application to\nrun with sampling turned on.</p>\n\n<p>Here's an example of what the output should look like:</p>\n<pre>\nheap profile:   1923: 127923432 [  1923: 127923432] @ heap_v2/524288\n     1:      312 [     1:      312] @ 0x2aaaabaf5ccc 0x2aaaaba4cd2c 0x2aaaac08c09a\n   928: 122586016 [   928: 122586016] @ 0x2aaaabaf682c 0x400680 0x400bdd 0x2aaaab1c368a 0x2aaaab1c8f77 0x2aaaab1c0396 0x2aaaab1c86ed 0x4007ff 0x2aaaaca62afa\n     1:       16 [     1:       16] @ 0x2aaaabaf5ccc 0x2aaaabb04bac 0x2aaaabc1b262 0x2aaaabc21496 0x2aaaabc214bb\n[...]\n</pre>\n\n\n<p> Older code may produce \"version 1\" heap profiles which look like this:<p/>\n<pre>\nheap profile:  14933: 791700132 [ 14933: 791700132] @ heap\n     1:   848688 [     1:   848688] @ 0xa4b142 0x7f5bfc 0x87065e 0x4056e9 0x4125f8 0x42b4f1 0x45b1ba 0x463248 0x460871 0x45cb7c 0x5f1744 0x607cee 0x5f4a5e 0x40080f 0x2aaaabad7afa\n     1:  1048576 [     1:  1048576] @ 0xa4a9b2 0x7fd025 0x4ca6d8 0x4ca814 0x4caa88 0x2aaaab104cf0 0x404e20 0x4125f8 0x42b4f1 0x45b1ba 0x463248 0x460871 0x45cb7c 0x5f1744 0x607cee 0x5f4a5e 0x40080f 0x2aaaabad7afa\n  2942: 388629374 [  2942: 388629374] @ 0xa4b142 0x4006a0 0x400bed 0x5f0cfa 0x5f1744 0x607cee 0x5f4a5e 0x40080f 0x2aaaabad7afa\n[...]\n</pre>\n<p>pprof accepts both old and new heap profiles and automatically\ndetects which one you are using.</p>\n\n<h2> <code><b>/pprof/growth</b></code> </h2>\n\n<p><code>pprof</code> asks for the url <code>/pprof/growth</code> to\nget heap-profiling delta (growth) information.  The actual url is\ncontrolled via the variable <code>GROWTH_PAGE</code> in the\n<code>pprof</code> script, so you can change it if you'd like.</p>\n\n<p>The server should respond by calling</p>\n<pre>\n    MallocExtension::instance()->GetHeapGrowthStacks(&output);\n</pre>\n<p>and sending <code>output</code> back as an HTTP response to\n<code>pprof</code>.  <code>MallocExtension</code> is defined in the\nheader file <code>google/malloc_extension.h</code>.</p>\n\n<p>Here's an example, from an actual Google webserver, of what the\noutput should look like:</p>\n<pre>\nheap profile:    741: 812122112 [   741: 812122112] @ growth\n     1:  1572864 [     1:  1572864] @ 0x87da564 0x87db8a3 0x84787a4 0x846e851 0x836d12f 0x834cd1c 0x8349ba5 0x10a3177 0x8349961\n     1:  1048576 [     1:  1048576] @ 0x87d92e8 0x87d9213 0x87d9178 0x87d94d3 0x87da9da 0x8a364ff 0x8a437e7 0x8ab7d23 0x8ab7da9 0x8ac7454 0x8348465 0x10a3161 0x8349961\n[...]\n</pre>\n\n\n<h2> <A NAME=\"profile\"><code><b>/pprof/profile</b></code></A> </h2>\n\n<p><code>pprof</code> asks for the url\n<code>/pprof/profile?seconds=XX</code> to get cpu-profiling\ninformation.  The actual url is controlled via the variable\n<code>PROFILE_PAGE</code> in the <code>pprof</code> script, so you can\nchange it if you'd like.</p>\n\n<p>The server should respond by calling\n<code>ProfilerStart(filename)</code>, continuing to do its work, and\nthen, XX seconds later, calling <code>ProfilerStop()</code>.  (These\nfunctions are declared in <code>google/profiler.h</code>.)  The\napplication is responsible for picking a unique filename for\n<code>ProfilerStart()</code>.  After calling\n<code>ProfilerStop()</code>, the server should read the contents of\n<code>filename</code> and send them back as an HTTP response to\n<code>pprof</code>.</p>\n\n<p>Obviously, to get useful profile information the application must\ncontinue to run in the XX seconds that the profiler is running.  Thus,\nthe profile start-stop calls should be done in a separate thread, or\nbe otherwise non-blocking.</p>\n\n<p>The profiler output file is binary, but near the end of it, it\nshould have lines of text somewhat like this:</p>\n<pre>\n01016000-01017000 rw-p 00015000 03:01 59314      /lib/ld-2.2.2.so\n</pre>\n\n<h2> <code><b>/pprof/pmuprofile</b></code> </h2>\n\n<code>pprof</code> asks for a url of the form\n<code>/pprof/pmuprofile?event=hw_event:unit_mask&period=nnn&seconds=xxx</code> \nto get cpu-profiling information.  The actual url is controlled via the variable\n<code>PMUPROFILE_PAGE</code> in the <code>pprof</code> script, so you can\nchange it if you'd like.</p> \n\n<p>\nThis is similar to pprof, but is meant to be used with your CPU's hardware \nperformance counters. The server could be implemented on top of a library \nsuch as <a href=\"http://perfmon2.sourceforge.net/\">\n<code>libpfm</code></a>. It should collect a sample every nnn occurences \nof the event and stop the sampling after xxx seconds. Much of the code \nfor <code>/pprof/profile</code> can be reused for this purpose.\n</p>\n\n<p>The server side routines (the equivalent of\nProfilerStart/ProfilerStart) are not available as part of perftools,\nso this URL is unlikely to be that useful.</p>\n\n<h2> <code><b>/pprof/contention</b></code> </h2>\n\n<p>This is intended to be able to profile (thread) lock contention in\naddition to CPU and memory use.  It's not yet usable.</p>\n\n\n<h2> <code><b>/pprof/cmdline</b></code> </h2>\n\n<p><code>pprof</code> asks for the url <code>/pprof/cmdline</code> to\nfigure out what application it's profiling.  The actual url is\ncontrolled via the variable <code>PROGRAM_NAME_PAGE</code> in the\n<code>pprof</code> script, so you can change it if you'd like.</p>\n\n<p>The server should respond by reading the contents of\n<code>/proc/self/cmdline</code>, converting all internal NUL (\\0)\ncharacters to newlines, and sending the result back as an HTTP\nresponse to <code>pprof</code>.</p>\n\n<p>Here's an example return value:<p>\n<pre>\n/root/server/custom_webserver\n80\n--configfile=/root/server/ws.config\n</pre>\n\n\n<h2> <code><b>/pprof/symbol</b></code> </h2>\n\n<p><code>pprof</code> asks for the url <code>/pprof/symbol</code> to\nmap from hex addresses to variable names.  The actual url is\ncontrolled via the variable <code>SYMBOL_PAGE</code> in the\n<code>pprof</code> script, so you can change it if you'd like.</p>\n\n<p>When the server receives a GET request for\n<code>/pprof/symbol</code>, it should return a line formatted like\nso:</p>\n<pre>\n   num_symbols: ###\n</pre>\n<p>where <code>###</code> is the number of symbols found in the\nbinary.  (For now, the only important distinction is whether the value\nis 0, which it is for executables that lack debug information, or\nnot-0).</p>\n\n<p>This is perhaps the hardest request to write code for, because in\naddition to the GET request for this url, the server must accept POST\nrequests.  This means that after the HTTP headers, pprof will pass in\na list of hex addresses connected by <code>+</code>, like so:</p>\n<pre>\n   curl -d '0x0824d061+0x0824d1cf' http://remote_host:80/pprof/symbol\n</pre>\n\n<p>The server should read the POST data, which will be in one line,\nand for each hex value, should write one line of output to the output\nstream, like so:</p>\n<pre>\n&lt;hex address&gt;&lt;tab&gt;&lt;function name&gt;\n</pre>\n<p>For instance:</p>\n<pre>\n0x08b2dabd    _Update\n</pre>\n\n<p>The other reason this is the most difficult request to implement,\nis that the application will have to figure out for itself how to map\nfrom address to function name.  One possibility is to run <code>nm -C\n-n &lt;program name&gt;</code> to get the mappings at\nprogram-compile-time.  Another, at least on Linux, is to call out to\naddr2line for every <code>pprof/symbol</code> call, for instance\n<code>addr2line -Cfse /proc/<getpid>/exe 0x12345678 0x876543210</code>\n(presumably with some caching!)</p>\n\n<p><code>pprof</code> itself does just this for local profiles (not\nones that talk to remote servers); look at the subroutine\n<code>GetProcedureBoundaries</code>.</p>\n\n\n<hr>\nLast modified: Mon Jun 12 21:30:14 PDT 2006\n</body>\n</html>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/spanmap.dot",
    "content": "digraph SpanMap {\nnode [shape=box, width=0.3, height=0.3]\nnodesep=.05\n\nmap [shape=record, width=6, label=\"<f0>|<f1>|<f2>|<f3>|<f4>|<f5>|<f6>|<f7>|<f8>|<f9>|<f10>\"]\nS0 [label=\"a\"]\nS1 [label=\"b\"]\nS2 [label=\"c\"]\nS3 [label=\"d\"]\nmap:f0 -> S0\nmap:f1 -> S0\nmap:f2 -> S1\nmap:f3 -> S2\nmap:f4 -> S2\nmap:f5 -> S2\nmap:f6 -> S2\nmap:f7 -> S2\nmap:f8 -> S3\nmap:f9 -> S3\nmap:f10 -> S3\n\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/t-test1.times.txt",
    "content": "time.1.ptmalloc.64:0.56 user 0.02 system 0.57 elapsed 100% CPU\ntime.1.tcmalloc.64:0.38 user 0.02 system 0.40 elapsed 98% CPU\ntime.1.ptmalloc.128:0.61 user 0.01 system 0.61 elapsed 101% CPU\ntime.1.tcmalloc.128:0.35 user 0.00 system 0.35 elapsed 99% CPU\ntime.1.ptmalloc.256:0.59 user 0.01 system 0.60 elapsed 100% CPU\ntime.1.tcmalloc.256:0.27 user 0.02 system 0.28 elapsed 102% CPU\ntime.1.ptmalloc.512:0.57 user 0.00 system 0.57 elapsed 100% CPU\ntime.1.tcmalloc.512:0.25 user 0.01 system 0.25 elapsed 101% CPU\ntime.1.ptmalloc.1024:0.52 user 0.00 system 0.52 elapsed 99% CPU\ntime.1.tcmalloc.1024:0.22 user 0.02 system 0.24 elapsed 97% CPU\ntime.1.ptmalloc.2048:0.47 user 0.00 system 0.47 elapsed 99% CPU\ntime.1.tcmalloc.2048:0.22 user 0.02 system 0.25 elapsed 95% CPU\ntime.1.ptmalloc.4096:0.48 user 0.01 system 0.48 elapsed 100% CPU\ntime.1.tcmalloc.4096:0.25 user 0.01 system 0.25 elapsed 100% CPU\ntime.1.ptmalloc.8192:0.49 user 0.02 system 0.49 elapsed 102% CPU\ntime.1.tcmalloc.8192:0.27 user 0.02 system 0.28 elapsed 101% CPU\ntime.1.ptmalloc.16384:0.51 user 0.04 system 0.55 elapsed 99% CPU\ntime.1.tcmalloc.16384:0.35 user 0.02 system 0.37 elapsed 100% CPU\ntime.1.ptmalloc.32768:0.53 user 0.14 system 0.66 elapsed 100% CPU\ntime.1.tcmalloc.32768:0.67 user 0.02 system 0.69 elapsed 99% CPU\ntime.1.ptmalloc.65536:0.68 user 0.31 system 0.98 elapsed 100% CPU\ntime.1.tcmalloc.65536:0.71 user 0.01 system 0.72 elapsed 99% CPU\ntime.1.ptmalloc.131072:0.90 user 0.72 system 1.62 elapsed 99% CPU\ntime.1.tcmalloc.131072:0.94 user 0.03 system 0.97 elapsed 99% CPU\ntime.2.ptmalloc.64:1.05 user 0.00 system 0.53 elapsed 196% CPU\ntime.2.tcmalloc.64:0.66 user 0.03 system 0.37 elapsed 185% CPU\ntime.2.ptmalloc.128:1.77 user 0.01 system 0.89 elapsed 198% CPU\ntime.2.tcmalloc.128:0.53 user 0.01 system 0.29 elapsed 184% CPU\ntime.2.ptmalloc.256:1.14 user 0.01 system 0.62 elapsed 182% CPU\ntime.2.tcmalloc.256:0.45 user 0.02 system 0.26 elapsed 180% CPU\ntime.2.ptmalloc.512:1.26 user 0.40 system 1.79 elapsed 92% CPU\ntime.2.tcmalloc.512:0.43 user 0.02 system 0.27 elapsed 166% CPU\ntime.2.ptmalloc.1024:0.98 user 0.03 system 0.56 elapsed 179% CPU\ntime.2.tcmalloc.1024:0.44 user 0.02 system 0.34 elapsed 134% CPU\ntime.2.ptmalloc.2048:0.87 user 0.02 system 0.44 elapsed 199% CPU\ntime.2.tcmalloc.2048:0.49 user 0.02 system 0.34 elapsed 148% CPU\ntime.2.ptmalloc.4096:0.92 user 0.03 system 0.48 elapsed 196% CPU\ntime.2.tcmalloc.4096:0.50 user 0.02 system 0.49 elapsed 105% CPU\ntime.2.ptmalloc.8192:1.05 user 0.04 system 0.55 elapsed 196% CPU\ntime.2.tcmalloc.8192:0.59 user 0.01 system 0.51 elapsed 116% CPU\ntime.2.ptmalloc.16384:1.30 user 0.14 system 0.72 elapsed 198% CPU\ntime.2.tcmalloc.16384:0.63 user 0.03 system 0.68 elapsed 96% CPU\ntime.2.ptmalloc.32768:1.33 user 0.56 system 1.00 elapsed 189% CPU\ntime.2.tcmalloc.32768:1.16 user 0.01 system 1.17 elapsed 99% CPU\ntime.2.ptmalloc.65536:1.86 user 1.79 system 2.01 elapsed 181% CPU\ntime.2.tcmalloc.65536:1.35 user 0.01 system 1.35 elapsed 100% CPU\ntime.2.ptmalloc.131072:2.61 user 5.19 system 4.81 elapsed 162% CPU\ntime.2.tcmalloc.131072:1.86 user 0.04 system 1.90 elapsed 100% CPU\ntime.3.ptmalloc.64:1.79 user 0.03 system 0.67 elapsed 268% CPU\ntime.3.tcmalloc.64:1.58 user 0.04 system 0.62 elapsed 260% CPU\ntime.3.ptmalloc.128:2.77 user 1.34 system 3.07 elapsed 133% CPU\ntime.3.tcmalloc.128:1.19 user 0.01 system 0.50 elapsed 236% CPU\ntime.3.ptmalloc.256:2.14 user 0.02 system 0.85 elapsed 252% CPU\ntime.3.tcmalloc.256:0.96 user 0.01 system 0.41 elapsed 236% CPU\ntime.3.ptmalloc.512:3.37 user 1.31 system 3.33 elapsed 140% CPU\ntime.3.tcmalloc.512:0.93 user 0.04 system 0.39 elapsed 243% CPU\ntime.3.ptmalloc.1024:1.66 user 0.01 system 0.64 elapsed 260% CPU\ntime.3.tcmalloc.1024:0.81 user 0.02 system 0.44 elapsed 187% CPU\ntime.3.ptmalloc.2048:2.07 user 0.01 system 0.82 elapsed 252% CPU\ntime.3.tcmalloc.2048:1.10 user 0.04 system 0.59 elapsed 191% CPU\ntime.3.ptmalloc.4096:2.01 user 0.03 system 0.79 elapsed 258% CPU\ntime.3.tcmalloc.4096:0.87 user 0.03 system 0.65 elapsed 137% CPU\ntime.3.ptmalloc.8192:2.22 user 0.11 system 0.83 elapsed 280% CPU\ntime.3.tcmalloc.8192:0.96 user 0.06 system 0.75 elapsed 135% CPU\ntime.3.ptmalloc.16384:2.56 user 0.47 system 1.02 elapsed 295% CPU\ntime.3.tcmalloc.16384:0.99 user 0.04 system 1.03 elapsed 99% CPU\ntime.3.ptmalloc.32768:3.29 user 1.75 system 1.96 elapsed 256% CPU\ntime.3.tcmalloc.32768:1.67 user 0.02 system 1.69 elapsed 99% CPU\ntime.3.ptmalloc.65536:4.04 user 6.62 system 4.92 elapsed 216% CPU\ntime.3.tcmalloc.65536:1.91 user 0.02 system 1.98 elapsed 97% CPU\ntime.3.ptmalloc.131072:5.55 user 17.86 system 12.44 elapsed 188% CPU\ntime.3.tcmalloc.131072:2.78 user 0.02 system 2.82 elapsed 99% CPU\ntime.4.ptmalloc.64:3.42 user 1.36 system 3.20 elapsed 149% CPU\ntime.4.tcmalloc.64:2.42 user 0.02 system 0.71 elapsed 341% CPU\ntime.4.ptmalloc.128:3.98 user 1.79 system 3.89 elapsed 148% CPU\ntime.4.tcmalloc.128:1.87 user 0.02 system 0.58 elapsed 325% CPU\ntime.4.ptmalloc.256:4.06 user 2.14 system 4.12 elapsed 150% CPU\ntime.4.tcmalloc.256:1.69 user 0.02 system 0.51 elapsed 331% CPU\ntime.4.ptmalloc.512:4.48 user 2.15 system 4.39 elapsed 150% CPU\ntime.4.tcmalloc.512:1.62 user 0.03 system 0.52 elapsed 314% CPU\ntime.4.ptmalloc.1024:3.18 user 0.03 system 0.84 elapsed 381% CPU\ntime.4.tcmalloc.1024:1.53 user 0.02 system 0.56 elapsed 274% CPU\ntime.4.ptmalloc.2048:3.24 user 0.02 system 0.84 elapsed 384% CPU\ntime.4.tcmalloc.2048:1.44 user 0.04 system 0.66 elapsed 221% CPU\ntime.4.ptmalloc.4096:3.50 user 0.04 system 0.91 elapsed 389% CPU\ntime.4.tcmalloc.4096:1.31 user 0.01 system 0.89 elapsed 148% CPU\ntime.4.ptmalloc.8192:6.77 user 3.85 system 4.14 elapsed 256% CPU\ntime.4.tcmalloc.8192:1.20 user 0.05 system 0.97 elapsed 127% CPU\ntime.4.ptmalloc.16384:7.08 user 5.06 system 4.63 elapsed 262% CPU\ntime.4.tcmalloc.16384:1.27 user 0.03 system 1.25 elapsed 103% CPU\ntime.4.ptmalloc.32768:5.57 user 4.22 system 3.31 elapsed 295% CPU\ntime.4.tcmalloc.32768:2.17 user 0.03 system 2.25 elapsed 97% CPU\ntime.4.ptmalloc.65536:6.11 user 15.05 system 9.19 elapsed 230% CPU\ntime.4.tcmalloc.65536:2.51 user 0.02 system 2.57 elapsed 98% CPU\ntime.4.ptmalloc.131072:7.58 user 33.15 system 21.28 elapsed 191% CPU\ntime.4.tcmalloc.131072:3.57 user 0.07 system 3.66 elapsed 99% CPU\ntime.5.ptmalloc.64:4.44 user 2.08 system 4.37 elapsed 148% CPU\ntime.5.tcmalloc.64:2.87 user 0.02 system 0.79 elapsed 361% CPU\ntime.5.ptmalloc.128:4.77 user 2.77 system 5.14 elapsed 146% CPU\ntime.5.tcmalloc.128:2.65 user 0.03 system 0.72 elapsed 367% CPU\ntime.5.ptmalloc.256:5.82 user 2.88 system 5.49 elapsed 158% CPU\ntime.5.tcmalloc.256:2.33 user 0.01 system 0.66 elapsed 352% CPU\ntime.5.ptmalloc.512:6.27 user 3.11 system 5.34 elapsed 175% CPU\ntime.5.tcmalloc.512:2.14 user 0.03 system 0.70 elapsed 307% CPU\ntime.5.ptmalloc.1024:6.82 user 3.18 system 5.23 elapsed 191% CPU\ntime.5.tcmalloc.1024:2.20 user 0.02 system 0.70 elapsed 313% CPU\ntime.5.ptmalloc.2048:6.57 user 3.46 system 5.22 elapsed 192% CPU\ntime.5.tcmalloc.2048:2.15 user 0.03 system 0.82 elapsed 264% CPU\ntime.5.ptmalloc.4096:8.75 user 5.09 system 5.26 elapsed 263% CPU\ntime.5.tcmalloc.4096:1.68 user 0.03 system 1.08 elapsed 158% CPU\ntime.5.ptmalloc.8192:4.48 user 0.61 system 1.51 elapsed 335% CPU\ntime.5.tcmalloc.8192:1.47 user 0.07 system 1.18 elapsed 129% CPU\ntime.5.ptmalloc.16384:5.71 user 1.98 system 2.14 elapsed 358% CPU\ntime.5.tcmalloc.16384:1.58 user 0.03 system 1.52 elapsed 105% CPU\ntime.5.ptmalloc.32768:7.19 user 7.81 system 5.53 elapsed 270% CPU\ntime.5.tcmalloc.32768:2.63 user 0.05 system 2.72 elapsed 98% CPU\ntime.5.ptmalloc.65536:8.45 user 23.51 system 14.30 elapsed 223% CPU\ntime.5.tcmalloc.65536:3.12 user 0.05 system 3.21 elapsed 98% CPU\ntime.5.ptmalloc.131072:10.22 user 43.63 system 27.84 elapsed 193% CPU\ntime.5.tcmalloc.131072:4.42 user 0.07 system 4.51 elapsed 99% CPU\ntime.6.ptmalloc.64:5.57 user 2.56 system 5.08 elapsed 159% CPU\ntime.6.tcmalloc.64:3.20 user 0.01 system 0.89 elapsed 360% CPU\ntime.6.ptmalloc.128:5.98 user 3.52 system 5.71 elapsed 166% CPU\ntime.6.tcmalloc.128:2.76 user 0.02 system 0.78 elapsed 355% CPU\ntime.6.ptmalloc.256:4.61 user 0.02 system 1.19 elapsed 389% CPU\ntime.6.tcmalloc.256:2.65 user 0.02 system 0.74 elapsed 356% CPU\ntime.6.ptmalloc.512:8.28 user 3.88 system 6.61 elapsed 183% CPU\ntime.6.tcmalloc.512:2.60 user 0.02 system 0.72 elapsed 362% CPU\ntime.6.ptmalloc.1024:4.75 user 0.00 system 1.22 elapsed 387% CPU\ntime.6.tcmalloc.1024:2.56 user 0.02 system 0.79 elapsed 325% CPU\ntime.6.ptmalloc.2048:8.90 user 4.59 system 6.15 elapsed 219% CPU\ntime.6.tcmalloc.2048:2.37 user 0.06 system 0.96 elapsed 250% CPU\ntime.6.ptmalloc.4096:11.41 user 7.02 system 6.31 elapsed 291% CPU\ntime.6.tcmalloc.4096:1.82 user 0.03 system 1.19 elapsed 154% CPU\ntime.6.ptmalloc.8192:11.64 user 8.25 system 5.97 elapsed 332% CPU\ntime.6.tcmalloc.8192:1.83 user 0.07 system 1.38 elapsed 136% CPU\ntime.6.ptmalloc.16384:7.44 user 2.98 system 3.01 elapsed 345% CPU\ntime.6.tcmalloc.16384:1.83 user 0.08 system 1.80 elapsed 105% CPU\ntime.6.ptmalloc.32768:8.69 user 12.35 system 8.04 elapsed 261% CPU\ntime.6.tcmalloc.32768:3.14 user 0.06 system 3.24 elapsed 98% CPU\ntime.6.ptmalloc.65536:10.52 user 35.43 system 20.75 elapsed 221% CPU\ntime.6.tcmalloc.65536:3.62 user 0.03 system 3.72 elapsed 98% CPU\ntime.6.ptmalloc.131072:11.74 user 59.00 system 36.93 elapsed 191% CPU\ntime.6.tcmalloc.131072:5.33 user 0.04 system 5.42 elapsed 98% CPU\ntime.7.ptmalloc.64:6.60 user 3.45 system 6.01 elapsed 167% CPU\ntime.7.tcmalloc.64:3.50 user 0.04 system 0.94 elapsed 376% CPU\ntime.7.ptmalloc.128:7.09 user 4.25 system 6.69 elapsed 169% CPU\ntime.7.tcmalloc.128:3.13 user 0.03 system 0.84 elapsed 374% CPU\ntime.7.ptmalloc.256:9.28 user 4.85 system 7.20 elapsed 196% CPU\ntime.7.tcmalloc.256:3.06 user 0.02 system 0.82 elapsed 375% CPU\ntime.7.ptmalloc.512:9.13 user 4.78 system 6.79 elapsed 204% CPU\ntime.7.tcmalloc.512:2.99 user 0.03 system 0.83 elapsed 359% CPU\ntime.7.ptmalloc.1024:10.85 user 6.41 system 7.52 elapsed 229% CPU\ntime.7.tcmalloc.1024:3.05 user 0.04 system 0.89 elapsed 345% CPU\ntime.7.ptmalloc.2048:5.65 user 0.08 system 1.47 elapsed 388% CPU\ntime.7.tcmalloc.2048:3.01 user 0.01 system 0.98 elapsed 306% CPU\ntime.7.ptmalloc.4096:6.09 user 0.08 system 1.58 elapsed 389% CPU\ntime.7.tcmalloc.4096:2.25 user 0.03 system 1.32 elapsed 171% CPU\ntime.7.ptmalloc.8192:6.73 user 0.85 system 1.99 elapsed 379% CPU\ntime.7.tcmalloc.8192:2.22 user 0.08 system 1.61 elapsed 142% CPU\ntime.7.ptmalloc.16384:8.87 user 4.66 system 4.04 elapsed 334% CPU\ntime.7.tcmalloc.16384:2.07 user 0.07 system 2.07 elapsed 103% CPU\ntime.7.ptmalloc.32768:10.61 user 17.85 system 11.22 elapsed 253% CPU\ntime.7.tcmalloc.32768:3.68 user 0.06 system 3.79 elapsed 98% CPU\ntime.7.ptmalloc.65536:13.05 user 45.97 system 27.28 elapsed 216% CPU\ntime.7.tcmalloc.65536:4.16 user 0.07 system 4.31 elapsed 98% CPU\ntime.7.ptmalloc.131072:13.22 user 62.67 system 41.33 elapsed 183% CPU\ntime.7.tcmalloc.131072:6.10 user 0.06 system 6.25 elapsed 98% CPU\ntime.8.ptmalloc.64:7.31 user 3.92 system 6.39 elapsed 175% CPU\ntime.8.tcmalloc.64:4.00 user 0.01 system 1.04 elapsed 383% CPU\ntime.8.ptmalloc.128:9.40 user 5.41 system 7.67 elapsed 192% CPU\ntime.8.tcmalloc.128:3.61 user 0.02 system 0.94 elapsed 386% CPU\ntime.8.ptmalloc.256:10.61 user 6.35 system 7.96 elapsed 212% CPU\ntime.8.tcmalloc.256:3.30 user 0.02 system 0.99 elapsed 335% CPU\ntime.8.ptmalloc.512:12.42 user 7.10 system 8.79 elapsed 221% CPU\ntime.8.tcmalloc.512:3.35 user 0.04 system 0.94 elapsed 358% CPU\ntime.8.ptmalloc.1024:13.63 user 8.54 system 8.95 elapsed 247% CPU\ntime.8.tcmalloc.1024:3.44 user 0.02 system 0.96 elapsed 359% CPU\ntime.8.ptmalloc.2048:6.45 user 0.03 system 1.67 elapsed 386% CPU\ntime.8.tcmalloc.2048:3.55 user 0.05 system 1.09 elapsed 328% CPU\ntime.8.ptmalloc.4096:6.83 user 0.26 system 1.80 elapsed 393% CPU\ntime.8.tcmalloc.4096:2.78 user 0.06 system 1.53 elapsed 185% CPU\ntime.8.ptmalloc.8192:7.59 user 1.29 system 2.36 elapsed 376% CPU\ntime.8.tcmalloc.8192:2.57 user 0.07 system 1.84 elapsed 142% CPU\ntime.8.ptmalloc.16384:10.15 user 6.20 system 5.20 elapsed 314% CPU\ntime.8.tcmalloc.16384:2.40 user 0.05 system 2.42 elapsed 101% CPU\ntime.8.ptmalloc.32768:11.82 user 24.48 system 14.60 elapsed 248% CPU\ntime.8.tcmalloc.32768:4.37 user 0.05 system 4.47 elapsed 98% CPU\ntime.8.ptmalloc.65536:15.41 user 58.94 system 34.42 elapsed 215% CPU\ntime.8.tcmalloc.65536:4.90 user 0.04 system 4.96 elapsed 99% CPU\ntime.8.ptmalloc.131072:16.07 user 82.93 system 52.51 elapsed 188% CPU\ntime.8.tcmalloc.131072:7.13 user 0.04 system 7.19 elapsed 99% CPU\ntime.9.ptmalloc.64:8.44 user 4.59 system 6.92 elapsed 188% CPU\ntime.9.tcmalloc.64:4.00 user 0.02 system 1.05 elapsed 382% CPU\ntime.9.ptmalloc.128:10.92 user 6.14 system 8.31 elapsed 205% CPU\ntime.9.tcmalloc.128:3.88 user 0.02 system 1.01 elapsed 382% CPU\ntime.9.ptmalloc.256:13.01 user 7.75 system 9.12 elapsed 227% CPU\ntime.9.tcmalloc.256:3.89 user 0.01 system 1.00 elapsed 386% CPU\ntime.9.ptmalloc.512:14.96 user 8.89 system 9.73 elapsed 244% CPU\ntime.9.tcmalloc.512:3.80 user 0.03 system 1.01 elapsed 377% CPU\ntime.9.ptmalloc.1024:15.42 user 10.20 system 9.80 elapsed 261% CPU\ntime.9.tcmalloc.1024:3.86 user 0.03 system 1.19 elapsed 325% CPU\ntime.9.ptmalloc.2048:7.24 user 0.02 system 1.87 elapsed 388% CPU\ntime.9.tcmalloc.2048:3.98 user 0.05 system 1.26 elapsed 319% CPU\ntime.9.ptmalloc.4096:7.96 user 0.18 system 2.06 elapsed 394% CPU\ntime.9.tcmalloc.4096:3.27 user 0.04 system 1.69 elapsed 195% CPU\ntime.9.ptmalloc.8192:9.00 user 1.63 system 2.79 elapsed 380% CPU\ntime.9.tcmalloc.8192:3.00 user 0.06 system 2.05 elapsed 148% CPU\ntime.9.ptmalloc.16384:12.07 user 8.13 system 6.55 elapsed 308% CPU\ntime.9.tcmalloc.16384:2.85 user 0.05 system 2.75 elapsed 105% CPU\ntime.9.ptmalloc.32768:13.99 user 29.65 system 18.02 elapsed 242% CPU\ntime.9.tcmalloc.32768:4.98 user 0.06 system 5.13 elapsed 98% CPU\ntime.9.ptmalloc.65536:16.89 user 70.42 system 42.11 elapsed 207% CPU\ntime.9.tcmalloc.65536:5.55 user 0.04 system 5.65 elapsed 98% CPU\ntime.9.ptmalloc.131072:18.53 user 94.11 system 61.17 elapsed 184% CPU\ntime.9.tcmalloc.131072:8.06 user 0.04 system 8.16 elapsed 99% CPU\ntime.10.ptmalloc.64:9.81 user 5.70 system 7.42 elapsed 208% CPU\ntime.10.tcmalloc.64:4.43 user 0.03 system 1.20 elapsed 370% CPU\ntime.10.ptmalloc.128:12.69 user 7.81 system 9.02 elapsed 227% CPU\ntime.10.tcmalloc.128:4.27 user 0.02 system 1.13 elapsed 378% CPU\ntime.10.ptmalloc.256:15.04 user 9.53 system 9.92 elapsed 247% CPU\ntime.10.tcmalloc.256:4.23 user 0.02 system 1.09 elapsed 388% CPU\ntime.10.ptmalloc.512:17.30 user 10.46 system 10.61 elapsed 261% CPU\ntime.10.tcmalloc.512:4.14 user 0.05 system 1.10 elapsed 379% CPU\ntime.10.ptmalloc.1024:16.96 user 9.38 system 9.30 elapsed 283% CPU\ntime.10.tcmalloc.1024:4.27 user 0.06 system 1.18 elapsed 366% CPU\ntime.10.ptmalloc.2048:8.07 user 0.03 system 2.06 elapsed 393% CPU\ntime.10.tcmalloc.2048:4.49 user 0.07 system 1.33 elapsed 342% CPU\ntime.10.ptmalloc.4096:8.66 user 0.25 system 2.25 elapsed 394% CPU\ntime.10.tcmalloc.4096:3.61 user 0.05 system 1.78 elapsed 205% CPU\ntime.10.ptmalloc.8192:21.52 user 17.43 system 10.41 elapsed 374% CPU\ntime.10.tcmalloc.8192:3.59 user 0.10 system 2.33 elapsed 158% CPU\ntime.10.ptmalloc.16384:20.55 user 24.85 system 12.55 elapsed 361% CPU\ntime.10.tcmalloc.16384:3.29 user 0.04 system 3.22 elapsed 103% CPU\ntime.10.ptmalloc.32768:15.23 user 38.13 system 22.49 elapsed 237% CPU\ntime.10.tcmalloc.32768:5.62 user 0.05 system 5.72 elapsed 99% CPU\ntime.10.ptmalloc.65536:19.80 user 85.42 system 49.98 elapsed 210% CPU\ntime.10.tcmalloc.65536:6.23 user 0.09 system 6.36 elapsed 99% CPU\ntime.10.ptmalloc.131072:20.91 user 106.97 system 69.08 elapsed 185% CPU\ntime.10.tcmalloc.131072:8.94 user 0.09 system 9.09 elapsed 99% CPU\ntime.11.ptmalloc.64:10.82 user 6.34 system 7.92 elapsed 216% CPU\ntime.11.tcmalloc.64:4.80 user 0.03 system 1.24 elapsed 387% CPU\ntime.11.ptmalloc.128:14.58 user 8.61 system 9.81 elapsed 236% CPU\ntime.11.tcmalloc.128:4.65 user 0.03 system 1.21 elapsed 384% CPU\ntime.11.ptmalloc.256:17.38 user 10.98 system 10.75 elapsed 263% CPU\ntime.11.tcmalloc.256:4.51 user 0.03 system 1.18 elapsed 384% CPU\ntime.11.ptmalloc.512:19.18 user 11.71 system 10.95 elapsed 282% CPU\ntime.11.tcmalloc.512:4.57 user 0.02 system 1.19 elapsed 384% CPU\ntime.11.ptmalloc.1024:19.94 user 12.41 system 10.48 elapsed 308% CPU\ntime.11.tcmalloc.1024:4.71 user 0.05 system 1.29 elapsed 367% CPU\ntime.11.ptmalloc.2048:8.70 user 0.04 system 2.35 elapsed 371% CPU\ntime.11.tcmalloc.2048:4.97 user 0.07 system 1.43 elapsed 350% CPU\ntime.11.ptmalloc.4096:22.47 user 18.43 system 10.82 elapsed 377% CPU\ntime.11.tcmalloc.4096:4.22 user 0.03 system 1.91 elapsed 221% CPU\ntime.11.ptmalloc.8192:11.61 user 2.38 system 3.73 elapsed 374% CPU\ntime.11.tcmalloc.8192:3.74 user 0.09 system 2.46 elapsed 155% CPU\ntime.11.ptmalloc.16384:14.13 user 13.38 system 9.60 elapsed 286% CPU\ntime.11.tcmalloc.16384:3.61 user 0.03 system 3.63 elapsed 100% CPU\ntime.11.ptmalloc.32768:17.92 user 43.84 system 26.74 elapsed 230% CPU\ntime.11.tcmalloc.32768:6.31 user 0.03 system 6.45 elapsed 98% CPU\ntime.11.ptmalloc.65536:22.40 user 96.38 system 58.30 elapsed 203% CPU\ntime.11.tcmalloc.65536:6.92 user 0.12 system 6.98 elapsed 100% CPU\ntime.11.ptmalloc.131072:21.03 user 108.04 system 72.78 elapsed 177% CPU\ntime.11.tcmalloc.131072:9.79 user 0.08 system 9.94 elapsed 99% CPU\ntime.12.ptmalloc.64:12.23 user 7.16 system 8.38 elapsed 231% CPU\ntime.12.tcmalloc.64:5.21 user 0.05 system 1.41 elapsed 371% CPU\ntime.12.ptmalloc.128:16.97 user 10.19 system 10.47 elapsed 259% CPU\ntime.12.tcmalloc.128:5.10 user 0.02 system 1.31 elapsed 390% CPU\ntime.12.ptmalloc.256:19.99 user 12.10 system 11.57 elapsed 277% CPU\ntime.12.tcmalloc.256:5.01 user 0.03 system 1.29 elapsed 390% CPU\ntime.12.ptmalloc.512:21.85 user 12.66 system 11.46 elapsed 300% CPU\ntime.12.tcmalloc.512:5.05 user 0.00 system 1.32 elapsed 379% CPU\ntime.12.ptmalloc.1024:9.40 user 0.04 system 2.40 elapsed 393% CPU\ntime.12.tcmalloc.1024:5.14 user 0.02 system 1.39 elapsed 369% CPU\ntime.12.ptmalloc.2048:9.72 user 0.04 system 2.49 elapsed 391% CPU\ntime.12.tcmalloc.2048:5.74 user 0.05 system 1.62 elapsed 355% CPU\ntime.12.ptmalloc.4096:10.64 user 0.20 system 2.75 elapsed 393% CPU\ntime.12.tcmalloc.4096:4.45 user 0.03 system 2.04 elapsed 218% CPU\ntime.12.ptmalloc.8192:12.66 user 3.30 system 4.30 elapsed 371% CPU\ntime.12.tcmalloc.8192:4.21 user 0.13 system 2.65 elapsed 163% CPU\ntime.12.ptmalloc.16384:15.73 user 15.68 system 11.14 elapsed 281% CPU\ntime.12.tcmalloc.16384:4.17 user 0.06 system 4.10 elapsed 102% CPU\ntime.12.ptmalloc.32768:19.45 user 56.00 system 32.74 elapsed 230% CPU\ntime.12.tcmalloc.32768:6.96 user 0.08 system 7.14 elapsed 98% CPU\ntime.12.ptmalloc.65536:23.33 user 110.45 system 65.06 elapsed 205% CPU\ntime.12.tcmalloc.65536:7.77 user 0.15 system 7.72 elapsed 102% CPU\ntime.12.ptmalloc.131072:24.03 user 124.74 system 82.94 elapsed 179% CPU\ntime.12.tcmalloc.131072:10.81 user 0.06 system 10.94 elapsed 99% CPU\ntime.13.ptmalloc.64:14.08 user 7.60 system 8.85 elapsed 244% CPU\ntime.13.tcmalloc.64:5.51 user 0.01 system 1.47 elapsed 375% CPU\ntime.13.ptmalloc.128:18.20 user 10.98 system 10.99 elapsed 265% CPU\ntime.13.tcmalloc.128:5.34 user 0.01 system 1.39 elapsed 382% CPU\ntime.13.ptmalloc.256:21.48 user 13.94 system 12.25 elapsed 289% CPU\ntime.13.tcmalloc.256:5.33 user 0.01 system 1.39 elapsed 381% CPU\ntime.13.ptmalloc.512:24.22 user 14.84 system 12.97 elapsed 301% CPU\ntime.13.tcmalloc.512:5.49 user 0.02 system 1.41 elapsed 389% CPU\ntime.13.ptmalloc.1024:25.26 user 17.03 system 12.85 elapsed 328% CPU\ntime.13.tcmalloc.1024:5.65 user 0.04 system 1.50 elapsed 378% CPU\ntime.13.ptmalloc.2048:10.41 user 0.03 system 2.69 elapsed 387% CPU\ntime.13.tcmalloc.2048:5.93 user 0.10 system 1.77 elapsed 339% CPU\ntime.13.ptmalloc.4096:11.37 user 0.52 system 3.04 elapsed 391% CPU\ntime.13.tcmalloc.4096:5.08 user 0.11 system 2.22 elapsed 233% CPU\ntime.13.ptmalloc.8192:21.76 user 18.54 system 10.58 elapsed 380% CPU\ntime.13.tcmalloc.8192:5.04 user 0.16 system 2.93 elapsed 177% CPU\ntime.13.ptmalloc.16384:26.35 user 34.47 system 17.01 elapsed 357% CPU\ntime.13.tcmalloc.16384:4.66 user 0.04 system 4.66 elapsed 100% CPU\ntime.13.ptmalloc.32768:21.41 user 63.59 system 38.14 elapsed 222% CPU\ntime.13.tcmalloc.32768:7.71 user 0.03 system 7.83 elapsed 98% CPU\ntime.13.ptmalloc.65536:24.99 user 120.80 system 71.59 elapsed 203% CPU\ntime.13.tcmalloc.65536:8.87 user 0.64 system 8.37 elapsed 113% CPU\ntime.13.ptmalloc.131072:25.97 user 142.27 system 96.00 elapsed 175% CPU\ntime.13.tcmalloc.131072:11.48 user 0.06 system 11.67 elapsed 98% CPU\ntime.14.ptmalloc.64:15.01 user 9.11 system 9.41 elapsed 256% CPU\ntime.14.tcmalloc.64:5.98 user 0.02 system 1.58 elapsed 378% CPU\ntime.14.ptmalloc.128:20.34 user 12.72 system 11.62 elapsed 284% CPU\ntime.14.tcmalloc.128:5.88 user 0.04 system 1.51 elapsed 392% CPU\ntime.14.ptmalloc.256:24.26 user 14.95 system 12.92 elapsed 303% CPU\ntime.14.tcmalloc.256:5.72 user 0.02 system 1.50 elapsed 381% CPU\ntime.14.ptmalloc.512:27.28 user 16.45 system 13.89 elapsed 314% CPU\ntime.14.tcmalloc.512:5.99 user 0.02 system 1.54 elapsed 388% CPU\ntime.14.ptmalloc.1024:25.84 user 16.99 system 12.61 elapsed 339% CPU\ntime.14.tcmalloc.1024:5.94 user 0.06 system 1.59 elapsed 375% CPU\ntime.14.ptmalloc.2048:11.96 user 0.01 system 3.12 elapsed 382% CPU\ntime.14.tcmalloc.2048:6.39 user 0.07 system 1.79 elapsed 359% CPU\ntime.14.ptmalloc.4096:20.19 user 11.77 system 8.26 elapsed 386% CPU\ntime.14.tcmalloc.4096:5.65 user 0.05 system 2.32 elapsed 244% CPU\ntime.14.ptmalloc.8192:22.01 user 16.39 system 9.89 elapsed 387% CPU\ntime.14.tcmalloc.8192:5.44 user 0.11 system 3.07 elapsed 180% CPU\ntime.14.ptmalloc.16384:18.15 user 22.40 system 15.02 elapsed 269% CPU\ntime.14.tcmalloc.16384:5.29 user 0.08 system 5.34 elapsed 100% CPU\ntime.14.ptmalloc.32768:24.29 user 72.07 system 42.63 elapsed 225% CPU\ntime.14.tcmalloc.32768:8.47 user 0.02 system 8.62 elapsed 98% CPU\ntime.14.ptmalloc.65536:27.63 user 130.56 system 78.64 elapsed 201% CPU\ntime.14.tcmalloc.65536:9.85 user 1.61 system 9.04 elapsed 126% CPU\ntime.14.ptmalloc.131072:28.87 user 146.38 system 100.54 elapsed 174% CPU\ntime.14.tcmalloc.131072:12.46 user 0.11 system 12.71 elapsed 98% CPU\ntime.15.ptmalloc.64:16.25 user 10.05 system 9.82 elapsed 267% CPU\ntime.15.tcmalloc.64:6.30 user 0.02 system 1.64 elapsed 385% CPU\ntime.15.ptmalloc.128:22.33 user 13.23 system 12.24 elapsed 290% CPU\ntime.15.tcmalloc.128:6.08 user 0.03 system 1.59 elapsed 384% CPU\ntime.15.ptmalloc.256:26.56 user 16.57 system 13.70 elapsed 314% CPU\ntime.15.tcmalloc.256:6.14 user 0.03 system 1.61 elapsed 382% CPU\ntime.15.ptmalloc.512:29.68 user 18.08 system 14.56 elapsed 327% CPU\ntime.15.tcmalloc.512:6.12 user 0.04 system 1.68 elapsed 364% CPU\ntime.15.ptmalloc.1024:17.07 user 6.22 system 6.26 elapsed 371% CPU\ntime.15.tcmalloc.1024:6.38 user 0.02 system 1.75 elapsed 364% CPU\ntime.15.ptmalloc.2048:26.64 user 17.25 system 11.51 elapsed 381% CPU\ntime.15.tcmalloc.2048:6.77 user 0.18 system 1.92 elapsed 361% CPU\ntime.15.ptmalloc.4096:13.21 user 0.74 system 3.57 elapsed 390% CPU\ntime.15.tcmalloc.4096:6.03 user 0.09 system 2.36 elapsed 258% CPU\ntime.15.ptmalloc.8192:22.92 user 17.51 system 10.50 elapsed 385% CPU\ntime.15.tcmalloc.8192:5.96 user 0.12 system 3.36 elapsed 180% CPU\ntime.15.ptmalloc.16384:19.37 user 24.87 system 16.69 elapsed 264% CPU\ntime.15.tcmalloc.16384:5.88 user 0.07 system 5.84 elapsed 101% CPU\ntime.15.ptmalloc.32768:25.43 user 82.30 system 48.98 elapsed 219% CPU\ntime.15.tcmalloc.32768:9.11 user 0.05 system 9.30 elapsed 98% CPU\ntime.15.ptmalloc.65536:29.31 user 140.07 system 83.78 elapsed 202% CPU\ntime.15.tcmalloc.65536:8.51 user 1.59 system 9.75 elapsed 103% CPU\ntime.15.ptmalloc.131072:30.22 user 163.15 system 109.50 elapsed 176% CPU\ntime.15.tcmalloc.131072:13.35 user 0.10 system 13.54 elapsed 99% CPU\ntime.16.ptmalloc.64:17.69 user 10.11 system 10.11 elapsed 274% CPU\ntime.16.tcmalloc.64:6.63 user 0.04 system 1.72 elapsed 387% CPU\ntime.16.ptmalloc.128:23.05 user 14.37 system 12.75 elapsed 293% CPU\ntime.16.tcmalloc.128:6.61 user 0.02 system 1.71 elapsed 387% CPU\ntime.16.ptmalloc.256:29.11 user 19.35 system 14.57 elapsed 332% CPU\ntime.16.tcmalloc.256:6.62 user 0.03 system 1.73 elapsed 382% CPU\ntime.16.ptmalloc.512:31.65 user 18.71 system 14.71 elapsed 342% CPU\ntime.16.tcmalloc.512:6.63 user 0.04 system 1.73 elapsed 383% CPU\ntime.16.ptmalloc.1024:31.99 user 21.22 system 14.87 elapsed 357% CPU\ntime.16.tcmalloc.1024:6.81 user 0.04 system 1.79 elapsed 382% CPU\ntime.16.ptmalloc.2048:30.35 user 21.36 system 13.30 elapsed 388% CPU\ntime.16.tcmalloc.2048:6.91 user 0.50 system 2.01 elapsed 367% CPU\ntime.16.ptmalloc.4096:18.85 user 7.18 system 6.61 elapsed 393% CPU\ntime.16.tcmalloc.4096:6.70 user 0.10 system 2.62 elapsed 259% CPU\ntime.16.ptmalloc.8192:22.19 user 14.30 system 9.37 elapsed 389% CPU\ntime.16.tcmalloc.8192:6.18 user 0.19 system 3.58 elapsed 177% CPU\ntime.16.ptmalloc.16384:31.22 user 46.78 system 22.92 elapsed 340% CPU\ntime.16.tcmalloc.16384:6.79 user 0.07 system 6.86 elapsed 99% CPU\ntime.16.ptmalloc.32768:27.31 user 87.32 system 52.00 elapsed 220% CPU\ntime.16.tcmalloc.32768:9.85 user 0.06 system 10.07 elapsed 98% CPU\ntime.16.ptmalloc.65536:32.83 user 160.62 system 95.67 elapsed 202% CPU\ntime.16.tcmalloc.65536:10.18 user 0.09 system 10.41 elapsed 98% CPU\ntime.16.ptmalloc.131072:31.99 user 173.41 system 115.98 elapsed 177% CPU\ntime.16.tcmalloc.131072:14.52 user 0.05 system 14.67 elapsed 99% CPU\ntime.17.ptmalloc.64:19.38 user 11.61 system 10.61 elapsed 291% CPU\ntime.17.tcmalloc.64:7.11 user 0.02 system 1.84 elapsed 386% CPU\ntime.17.ptmalloc.128:26.25 user 16.15 system 13.53 elapsed 313% CPU\ntime.17.tcmalloc.128:6.97 user 0.02 system 1.78 elapsed 390% CPU\ntime.17.ptmalloc.256:30.66 user 18.36 system 14.97 elapsed 327% CPU\ntime.17.tcmalloc.256:6.94 user 0.04 system 1.80 elapsed 387% CPU\ntime.17.ptmalloc.512:33.71 user 22.79 system 15.95 elapsed 354% CPU\ntime.17.tcmalloc.512:7.00 user 0.02 system 1.83 elapsed 381% CPU\ntime.17.ptmalloc.1024:33.49 user 22.47 system 15.00 elapsed 373% CPU\ntime.17.tcmalloc.1024:7.20 user 0.03 system 1.90 elapsed 380% CPU\ntime.17.ptmalloc.2048:23.87 user 11.92 system 9.26 elapsed 386% CPU\ntime.17.tcmalloc.2048:6.01 user 1.83 system 2.15 elapsed 363% CPU\ntime.17.ptmalloc.4096:14.69 user 0.95 system 3.98 elapsed 392% CPU\ntime.17.tcmalloc.4096:7.25 user 0.10 system 2.62 elapsed 279% CPU\ntime.17.ptmalloc.8192:22.44 user 13.52 system 9.39 elapsed 382% CPU\ntime.17.tcmalloc.8192:7.21 user 0.24 system 3.95 elapsed 188% CPU\ntime.17.ptmalloc.16384:23.33 user 33.67 system 21.89 elapsed 260% CPU\ntime.17.tcmalloc.16384:7.28 user 0.06 system 7.10 elapsed 103% CPU\ntime.17.ptmalloc.32768:29.35 user 103.11 system 60.36 elapsed 219% CPU\ntime.17.tcmalloc.32768:10.53 user 0.07 system 10.71 elapsed 98% CPU\ntime.17.ptmalloc.65536:33.21 user 170.89 system 100.84 elapsed 202% CPU\ntime.17.tcmalloc.65536:10.85 user 0.05 system 11.04 elapsed 98% CPU\ntime.17.ptmalloc.131072:34.98 user 182.87 system 122.05 elapsed 178% CPU\ntime.17.tcmalloc.131072:15.27 user 0.09 system 15.49 elapsed 99% CPU\ntime.18.ptmalloc.64:21.08 user 12.15 system 11.43 elapsed 290% CPU\ntime.18.tcmalloc.64:7.45 user 0.03 system 1.95 elapsed 383% CPU\ntime.18.ptmalloc.128:27.65 user 17.26 system 14.03 elapsed 320% CPU\ntime.18.tcmalloc.128:7.46 user 0.03 system 1.92 elapsed 389% CPU\ntime.18.ptmalloc.256:32.78 user 20.55 system 15.70 elapsed 339% CPU\ntime.18.tcmalloc.256:7.31 user 0.02 system 1.88 elapsed 389% CPU\ntime.18.ptmalloc.512:33.31 user 20.06 system 15.05 elapsed 354% CPU\ntime.18.tcmalloc.512:7.33 user 0.02 system 1.91 elapsed 383% CPU\ntime.18.ptmalloc.1024:35.46 user 24.83 system 16.30 elapsed 369% CPU\ntime.18.tcmalloc.1024:7.60 user 0.06 system 2.05 elapsed 373% CPU\ntime.18.ptmalloc.2048:19.98 user 6.80 system 6.76 elapsed 395% CPU\ntime.18.tcmalloc.2048:6.89 user 1.29 system 2.28 elapsed 357% CPU\ntime.18.ptmalloc.4096:15.99 user 0.93 system 4.32 elapsed 391% CPU\ntime.18.tcmalloc.4096:7.70 user 0.10 system 2.77 elapsed 280% CPU\ntime.18.ptmalloc.8192:23.51 user 14.84 system 9.97 elapsed 384% CPU\ntime.18.tcmalloc.8192:8.16 user 0.27 system 4.25 elapsed 197% CPU\ntime.18.ptmalloc.16384:35.79 user 52.41 system 26.47 elapsed 333% CPU\ntime.18.tcmalloc.16384:7.81 user 0.07 system 7.61 elapsed 103% CPU\ntime.18.ptmalloc.32768:33.17 user 116.07 system 68.64 elapsed 217% CPU\ntime.18.tcmalloc.32768:11.34 user 0.13 system 11.57 elapsed 99% CPU\ntime.18.ptmalloc.65536:35.91 user 177.82 system 106.75 elapsed 200% CPU\ntime.18.tcmalloc.65536:11.54 user 0.06 system 11.74 elapsed 98% CPU\ntime.18.ptmalloc.131072:36.38 user 187.18 system 126.91 elapsed 176% CPU\ntime.18.tcmalloc.131072:16.34 user 0.05 system 16.43 elapsed 99% CPU\ntime.19.ptmalloc.64:22.90 user 13.23 system 11.82 elapsed 305% CPU\ntime.19.tcmalloc.64:7.81 user 0.02 system 2.01 elapsed 388% CPU\ntime.19.ptmalloc.128:30.13 user 18.58 system 14.77 elapsed 329% CPU\ntime.19.tcmalloc.128:7.74 user 0.02 system 2.01 elapsed 386% CPU\ntime.19.ptmalloc.256:35.33 user 21.41 system 16.35 elapsed 347% CPU\ntime.19.tcmalloc.256:7.79 user 0.04 system 2.04 elapsed 382% CPU\ntime.19.ptmalloc.512:39.30 user 26.22 system 17.84 elapsed 367% CPU\ntime.19.tcmalloc.512:7.80 user 0.06 system 2.05 elapsed 381% CPU\ntime.19.ptmalloc.1024:35.70 user 23.90 system 15.66 elapsed 380% CPU\ntime.19.tcmalloc.1024:8.08 user 0.06 system 2.16 elapsed 376% CPU\ntime.19.ptmalloc.2048:18.33 user 3.28 system 5.47 elapsed 394% CPU\ntime.19.tcmalloc.2048:8.71 user 0.05 system 2.40 elapsed 363% CPU\ntime.19.ptmalloc.4096:16.94 user 0.89 system 4.64 elapsed 383% CPU\ntime.19.tcmalloc.4096:8.21 user 0.07 system 2.85 elapsed 289% CPU\ntime.19.ptmalloc.8192:25.61 user 17.15 system 11.33 elapsed 377% CPU\ntime.19.tcmalloc.8192:8.79 user 0.30 system 4.58 elapsed 198% CPU\ntime.19.ptmalloc.16384:27.11 user 46.66 system 29.67 elapsed 248% CPU\ntime.19.tcmalloc.16384:8.64 user 0.05 system 8.58 elapsed 101% CPU\ntime.19.ptmalloc.32768:33.80 user 117.69 system 70.65 elapsed 214% CPU\ntime.19.tcmalloc.32768:11.88 user 0.07 system 12.04 elapsed 99% CPU\ntime.19.ptmalloc.65536:36.90 user 180.21 system 109.01 elapsed 199% CPU\ntime.19.tcmalloc.65536:12.17 user 0.07 system 12.40 elapsed 98% CPU\ntime.19.ptmalloc.131072:38.50 user 195.15 system 132.81 elapsed 175% CPU\ntime.19.tcmalloc.131072:17.44 user 0.10 system 17.65 elapsed 99% CPU\ntime.20.ptmalloc.64:23.37 user 13.74 system 11.86 elapsed 312% CPU\ntime.20.tcmalloc.64:8.18 user 0.02 system 2.10 elapsed 389% CPU\ntime.20.ptmalloc.128:31.29 user 19.97 system 15.53 elapsed 329% CPU\ntime.20.tcmalloc.128:8.03 user 0.02 system 2.12 elapsed 378% CPU\ntime.20.ptmalloc.256:38.40 user 25.65 system 18.25 elapsed 350% CPU\ntime.20.tcmalloc.256:8.05 user 0.05 system 2.12 elapsed 380% CPU\ntime.20.ptmalloc.512:40.60 user 27.70 system 18.46 elapsed 369% CPU\ntime.20.tcmalloc.512:8.22 user 0.08 system 2.20 elapsed 375% CPU\ntime.20.ptmalloc.1024:40.02 user 28.52 system 17.56 elapsed 390% CPU\ntime.20.tcmalloc.1024:8.50 user 0.07 system 2.19 elapsed 391% CPU\ntime.20.ptmalloc.2048:16.13 user 0.23 system 4.23 elapsed 386% CPU\ntime.20.tcmalloc.2048:8.98 user 0.03 system 2.45 elapsed 367% CPU\ntime.20.ptmalloc.4096:17.14 user 0.87 system 4.60 elapsed 391% CPU\ntime.20.tcmalloc.4096:8.93 user 0.20 system 2.97 elapsed 306% CPU\ntime.20.ptmalloc.8192:25.24 user 17.16 system 11.14 elapsed 380% CPU\ntime.20.tcmalloc.8192:9.78 user 0.30 system 5.14 elapsed 195% CPU\ntime.20.ptmalloc.16384:39.93 user 60.36 system 30.24 elapsed 331% CPU\ntime.20.tcmalloc.16384:9.57 user 0.09 system 9.43 elapsed 102% CPU\ntime.20.ptmalloc.32768:36.44 user 130.23 system 76.79 elapsed 217% CPU\ntime.20.tcmalloc.32768:12.71 user 0.09 system 12.97 elapsed 98% CPU\ntime.20.ptmalloc.65536:39.79 user 202.09 system 120.34 elapsed 200% CPU\ntime.20.tcmalloc.65536:12.93 user 0.06 system 13.15 elapsed 98% CPU\ntime.20.ptmalloc.131072:41.91 user 202.76 system 138.51 elapsed 176% CPU\ntime.20.tcmalloc.131072:18.23 user 0.07 system 18.42 elapsed 99% CPU\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/tcmalloc.html",
    "content": "<!doctype html public \"-//w3c//dtd html 4.01 transitional//en\">\n<!-- $Id: $ -->\n<html>\n<head>\n<title>TCMalloc : Thread-Caching Malloc</title>\n<link rel=\"stylesheet\" href=\"designstyle.css\">\n<style type=\"text/css\">\n  em {\n    color: red;\n    font-style: normal;\n  }\n</style>\n</head>\n<body>\n\n<h1>TCMalloc : Thread-Caching Malloc</h1>\n\n<address>Sanjay Ghemawat</address>\n\n<h2><A name=motivation>Motivation</A></h2>\n\n<p>TCMalloc is faster than the glibc 2.3 malloc (available as a\nseparate library called ptmalloc2) and other mallocs that I have\ntested.  ptmalloc2 takes approximately 300 nanoseconds to execute a\nmalloc/free pair on a 2.8 GHz P4 (for small objects).  The TCMalloc\nimplementation takes approximately 50 nanoseconds for the same\noperation pair.  Speed is important for a malloc implementation\nbecause if malloc is not fast enough, application writers are inclined\nto write their own custom free lists on top of malloc.  This can lead\nto extra complexity, and more memory usage unless the application\nwriter is very careful to appropriately size the free lists and\nscavenge idle objects out of the free list.</p>\n\n<p>TCMalloc also reduces lock contention for multi-threaded programs.\nFor small objects, there is virtually zero contention.  For large\nobjects, TCMalloc tries to use fine grained and efficient spinlocks.\nptmalloc2 also reduces lock contention by using per-thread arenas but\nthere is a big problem with ptmalloc2's use of per-thread arenas.  In\nptmalloc2 memory can never move from one arena to another.  This can\nlead to huge amounts of wasted space.  For example, in one Google\napplication, the first phase would allocate approximately 300MB of\nmemory for its URL canonicalization data structures.  When the first\nphase finished, a second phase would be started in the same address\nspace.  If this second phase was assigned a different arena than the\none used by the first phase, this phase would not reuse any of the\nmemory left after the first phase and would add another 300MB to the\naddress space.  Similar memory blowup problems were also noticed in\nother applications.</p>\n\n<p>Another benefit of TCMalloc is space-efficient representation of\nsmall objects.  For example, N 8-byte objects can be allocated while\nusing space approximately <code>8N * 1.01</code> bytes.  I.e., a\none-percent space overhead.  ptmalloc2 uses a four-byte header for\neach object and (I think) rounds up the size to a multiple of 8 bytes\nand ends up using <code>16N</code> bytes.</p>\n\n\n<h2><A NAME=\"Usage\">Usage</A></h2>\n\n<p>To use TCMalloc, just link TCMalloc into your application via the\n\"-ltcmalloc\" linker flag.</p>\n\n<p>You can use TCMalloc in applications you didn't compile yourself,\nby using LD_PRELOAD:</p>\n<pre>\n   $ LD_PRELOAD=\"/usr/lib/libtcmalloc.so\" <binary>\n</pre>\n<p>LD_PRELOAD is tricky, and we don't necessarily recommend this mode\nof usage.</p>\n\n<p>TCMalloc includes a <A HREF=\"heap_checker.html\">heap checker</A>\nand <A HREF=\"heapprofile.html\">heap profiler</A> as well.</p>\n\n<p>If you'd rather link in a version of TCMalloc that does not include\nthe heap profiler and checker (perhaps to reduce binary size for a\nstatic binary), you can link in <code>libtcmalloc_minimal</code>\ninstead.</p>\n\n\n<h2><A NAME=\"Overview\">Overview</A></h2>\n\n<p>TCMalloc assigns each thread a thread-local cache.  Small\nallocations are satisfied from the thread-local cache.  Objects are\nmoved from central data structures into a thread-local cache as\nneeded, and periodic garbage collections are used to migrate memory\nback from a thread-local cache into the central data structures.</p>\n<center><img src=\"overview.gif\"></center>\n\n<p>TCMalloc treats objects with size &lt;= 32K (\"small\" objects)\ndifferently from larger objects.  Large objects are allocated directly\nfrom the central heap using a page-level allocator (a page is a 4K\naligned region of memory).  I.e., a large object is always\npage-aligned and occupies an integral number of pages.</p>\n\n<p>A run of pages can be carved up into a sequence of small objects,\neach equally sized.  For example a run of one page (4K) can be carved\nup into 32 objects of size 128 bytes each.</p>\n\n\n<h2><A NAME=\"Small_Object_Allocation\">Small Object Allocation</A></h2>\n\n<p>Each small object size maps to one of approximately 60 allocatable\nsize-classes.  For example, all allocations in the range 833 to 1024\nbytes are rounded up to 1024.  The size-classes are spaced so that\nsmall sizes are separated by 8 bytes, larger sizes by 16 bytes, even\nlarger sizes by 32 bytes, and so forth.  The maximal spacing is\ncontrolled so that not too much space is wasted when an allocation\nrequest falls just past the end of a size class and has to be rounded\nup to the next class.</p>\n\n<p>A thread cache contains a singly linked list of free objects per\nsize-class.</p>\n<center><img src=\"threadheap.gif\"></center>\n\n<p>When allocating a small object: (1) We map its size to the\ncorresponding size-class.  (2) Look in the corresponding free list in\nthe thread cache for the current thread.  (3) If the free list is not\nempty, we remove the first object from the list and return it.  When\nfollowing this fast path, TCMalloc acquires no locks at all.  This\nhelps speed-up allocation significantly because a lock/unlock pair\ntakes approximately 100 nanoseconds on a 2.8 GHz Xeon.</p>\n\n<p>If the free list is empty: (1) We fetch a bunch of objects from a\ncentral free list for this size-class (the central free list is shared\nby all threads).  (2) Place them in the thread-local free list.  (3)\nReturn one of the newly fetched objects to the applications.</p>\n\n<p>If the central free list is also empty: (1) We allocate a run of\npages from the central page allocator.  (2) Split the run into a set\nof objects of this size-class.  (3) Place the new objects on the\ncentral free list.  (4) As before, move some of these objects to the\nthread-local free list.</p>\n\n<h3><A NAME=\"Sizing_Thread_Cache_Free_Lists\">\n  Sizing Thread Cache Free Lists</A></h3>\n\n<p>It is important to size the thread cache free lists correctly.  If\nthe free list is too small, we'll need to go to the central free list\ntoo often.  If the free list is too big, we'll waste memory as objects\nsit idle in the free list.</p>\n\n<p>Note that the thread caches are just as important for deallocation\nas they are for allocation.  Without a cache, each deallocation would\nrequire moving the memory to the central free list.  Also, some threads\nhave asymmetric alloc/free behavior (e.g. producer and consumer threads),\nso sizing the free list correctly gets trickier.</p>\n\n<p>To size the free lists appropriately, we use a slow-start algorithm\nto determine the maximum length of each individual free list.  As the\nfree list is used more frequently, its maximum length grows.  However,\nif a free list is used more for deallocation than allocation, its\nmaximum length will grow only up to a point where the whole list can\nbe efficiently moved to the central free list at once.</p>\n\n<p>The psuedo-code below illustrates this slow-start algorithm.  Note\nthat <code>num_objects_to_move</code> is specific to each size class.\nBy moving a list of objects with a well-known length, the central\ncache can efficiently pass these lists between thread caches.  If\na thread cache wants fewer than <code>num_objects_to_move</code>,\nthe operation on the central free list has linear time complexity.\nThe downside of always using <code>num_objects_to_move</code> as\nthe number of objects to transfer to and from the central cache is\nthat it wastes memory in threads that don't need all of those objects.\n\n<pre>\nStart each freelist max_length at 1.\n\nAllocation\n  if freelist empty {\n    fetch min(max_length, num_objects_to_move) from central list;\n    if max_length < num_objects_to_move {  // slow-start\n      max_length++;\n    } else {\n      max_length += num_objects_to_move;\n    }\n  }\n\nDeallocation\n  if length > max_length {\n    // Don't try to release num_objects_to_move if we don't have that many.\n    release min(max_length, num_objects_to_move) objects to central list\n    if max_length < num_objects_to_move {\n      // Slow-start up to num_objects_to_move.\n      max_length++;\n    } else if max_length > num_objects_to_move {\n      // If we consistently go over max_length, shrink max_length.\n      overages++;\n      if overages > kMaxOverages {\n        max_length -= num_objects_to_move;\n        overages = 0;\n      }\n    }\n  }\n</pre>\n\nSee also the section on <a href=\"#Garbage_Collection\">Garbage Collection</a>\nto see how it affects the <code>max_length</code>.\n\n<h2><A NAME=\"Large_Object_Allocation\">Large Object Allocation</A></h2>\n\n<p>A large object size (&gt; 32K) is rounded up to a page size (4K)\nand is handled by a central page heap.  The central page heap is again\nan array of free lists.  For <code>i &lt; 256</code>, the\n<code>k</code>th entry is a free list of runs that consist of\n<code>k</code> pages.  The <code>256</code>th entry is a free list of\nruns that have length <code>&gt;= 256</code> pages: </p>\n<center><img src=\"pageheap.gif\"></center>\n\n<p>An allocation for <code>k</code> pages is satisfied by looking in\nthe <code>k</code>th free list.  If that free list is empty, we look\nin the next free list, and so forth.  Eventually, we look in the last\nfree list if necessary.  If that fails, we fetch memory from the\nsystem (using <code>sbrk</code>, <code>mmap</code>, or by mapping in\nportions of <code>/dev/mem</code>).</p>\n\n<p>If an allocation for <code>k</code> pages is satisfied by a run\nof pages of length &gt; <code>k</code>, the remainder of the\nrun is re-inserted back into the appropriate free list in the\npage heap.</p>\n\n\n<h2><A NAME=\"Spans\">Spans</A></h2>\n\n<p>The heap managed by TCMalloc consists of a set of pages.  A run of\ncontiguous pages is represented by a <code>Span</code> object.  A span\ncan either be <em>allocated</em>, or <em>free</em>.  If free, the span\nis one of the entries in a page heap linked-list.  If allocated, it is\neither a large object that has been handed off to the application, or\na run of pages that have been split up into a sequence of small\nobjects.  If split into small objects, the size-class of the objects\nis recorded in the span.</p>\n\n<p>A central array indexed by page number can be used to find the span to\nwhich a page belongs.  For example, span <em>a</em> below occupies 2\npages, span <em>b</em> occupies 1 page, span <em>c</em> occupies 5\npages and span <em>d</em> occupies 3 pages.</p>\n<center><img src=\"spanmap.gif\"></center>\n\n<p>In a 32-bit address space, the central array is represented by a a\n2-level radix tree where the root contains 32 entries and each leaf\ncontains 2^15 entries (a 32-bit address spave has 2^20 4K pages, and\nthe first level of tree divides the 2^20 pages by 2^5).  This leads to\na starting memory usage of 128KB of space (2^15*4 bytes) for the\ncentral array, which seems acceptable.</p>\n\n<p>On 64-bit machines, we use a 3-level radix tree.</p>\n\n\n<h2><A NAME=\"Deallocation\">Deallocation</A></h2>\n\n<p>When an object is deallocated, we compute its page number and look\nit up in the central array to find the corresponding span object.  The\nspan tells us whether or not the object is small, and its size-class\nif it is small.  If the object is small, we insert it into the\nappropriate free list in the current thread's thread cache.  If the\nthread cache now exceeds a predetermined size (2MB by default), we run\na garbage collector that moves unused objects from the thread cache\ninto central free lists.</p>\n\n<p>If the object is large, the span tells us the range of pages covered\nby the object.  Suppose this range is <code>[p,q]</code>.  We also\nlookup the spans for pages <code>p-1</code> and <code>q+1</code>.  If\neither of these neighboring spans are free, we coalesce them with the\n<code>[p,q]</code> span.  The resulting span is inserted into the\nappropriate free list in the page heap.</p>\n\n\n<h2>Central Free Lists for Small Objects</h2>\n\n<p>As mentioned before, we keep a central free list for each\nsize-class.  Each central free list is organized as a two-level data\nstructure: a set of spans, and a linked list of free objects per\nspan.</p>\n\n<p>An object is allocated from a central free list by removing the\nfirst entry from the linked list of some span.  (If all spans have\nempty linked lists, a suitably sized span is first allocated from the\ncentral page heap.)</p>\n\n<p>An object is returned to a central free list by adding it to the\nlinked list of its containing span.  If the linked list length now\nequals the total number of small objects in the span, this span is now\ncompletely free and is returned to the page heap.</p>\n\n\n<h2><A NAME=\"Garbage_Collection\">Garbage Collection of Thread Caches</A></h2>\n\n<p>Garbage collecting objects from a thread cache keeps the size of\nthe cache under control and returns unused objects to the central free\nlists.  Some threads need large caches to perform well while others\ncan get by with little or no cache at all.  When a thread cache goes\nover its <code>max_size</code>, garbage collection kicks in and then the\nthread competes with the other threads for a larger cache.</p>\n\n<p>Garbage collection is run only during a deallocation.  We walk over\nall free lists in the cache and move some number of objects from the\nfree list to the corresponding central list.</p>\n\n<p>The number of objects to be moved from a free list is determined\nusing a per-list low-water-mark <code>L</code>.  <code>L</code>\nrecords the minimum length of the list since the last garbage\ncollection.  Note that we could have shortened the list by\n<code>L</code> objects at the last garbage collection without\nrequiring any extra accesses to the central list.  We use this past\nhistory as a predictor of future accesses and move <code>L/2</code>\nobjects from the thread cache free list to the corresponding central\nfree list.  This algorithm has the nice property that if a thread\nstops using a particular size, all objects of that size will quickly\nmove from the thread cache to the central free list where they can be\nused by other threads.</p>\n\n<p>If a thread consistently deallocates more objects of a certain size\nthan it allocates, this <code>L/2</code> behavior will cause at least\n<code>L/2</code> objects to always sit in the free list.  To avoid\nwasting memory this way, we shrink the maximum length of the freelist\nto converge on <code>num_objects_to_move</code> (see also\n<a href=\"#Sizing_Thread_Cache_Free_Lists\">Sizing Thread Cache Free Lists</a>).\n\n<pre>\nGarbage Collection\n  if (L != 0 && max_length > num_objects_to_move) {\n    max_length = max(max_length - num_objects_to_move, num_objects_to_move)\n  }\n</pre>\n\n<p>The fact that the thread cache went over its <code>max_size</code> is\nan indication that the thread would benefit from a larger cache.  Simply\nincreasing <code>max_size</code> would use an inordinate amount of memory\nin programs that have lots of active threads.  Developers can bound the\nmemory used with the flag --tcmalloc_max_total_thread_cache_bytes.</p>\n\n<p>Each thread cache starts with a small <code>max_size</code>\n(e.g. 64KB) so that idle threads won't pre-allocate memory they don't\nneed.  Each time the cache runs a garbage collection, it will also try\nto grow its <code>max_size</code>.  If the sum of the thread cache\nsizes is less than --tcmalloc_max_total_thread_cache_bytes,\n<code>max_size</code> grows easily.  If not, thread cache 1 will try\nto steal from thread cache 2 (picked round-robin) by decreasing thread\ncache 2's <code>max_size</code>.  In this way, threads that are more\nactive will steal memory from other threads more often than they are\nhave memory stolen from themselves.  Mostly idle threads end up with\nsmall caches and active threads end up with big caches.  Note that\nthis stealing can cause the sum of the thread cache sizes to be\ngreater than --tcmalloc_max_total_thread_cache_bytes until thread\ncache 2 deallocates some memory to trigger a garbage collection.</p>\n\n<h2><A NAME=\"performance\">Performance Notes</A></h2>\n\n<h3>PTMalloc2 unittest</h3>\n\n<p>The PTMalloc2 package (now part of glibc) contains a unittest\nprogram <code>t-test1.c</code>. This forks a number of threads and\nperforms a series of allocations and deallocations in each thread; the\nthreads do not communicate other than by synchronization in the memory\nallocator.</p>\n\n<p><code>t-test1</code> (included in\n<code>tests/tcmalloc/</code>, and compiled as\n<code>ptmalloc_unittest1</code>) was run with a varying numbers of\nthreads (1-20) and maximum allocation sizes (64 bytes -\n32Kbytes). These tests were run on a 2.4GHz dual Xeon system with\nhyper-threading enabled, using Linux glibc-2.3.2 from RedHat 9, with\none million operations per thread in each test. In each case, the test\nwas run once normally, and once with\n<code>LD_PRELOAD=libtcmalloc.so</code>.\n\n<p>The graphs below show the performance of TCMalloc vs PTMalloc2 for\nseveral different metrics. Firstly, total operations (millions) per\nelapsed second vs max allocation size, for varying numbers of\nthreads. The raw data used to generate these graphs (the output of the\n<code>time</code> utility) is available in\n<code>t-test1.times.txt</code>.</p>\n\n<table>\n<tr>\n  <td><img src=\"tcmalloc-opspersec.vs.size.1.threads.png\"></td>\n  <td><img src=\"tcmalloc-opspersec.vs.size.2.threads.png\"></td>\n  <td><img src=\"tcmalloc-opspersec.vs.size.3.threads.png\"></td>\n</tr>\n<tr>\n  <td><img src=\"tcmalloc-opspersec.vs.size.4.threads.png\"></td>\n  <td><img src=\"tcmalloc-opspersec.vs.size.5.threads.png\"></td>\n  <td><img src=\"tcmalloc-opspersec.vs.size.8.threads.png\"></td>\n</tr>\n<tr>\n  <td><img src=\"tcmalloc-opspersec.vs.size.12.threads.png\"></td>\n  <td><img src=\"tcmalloc-opspersec.vs.size.16.threads.png\"></td>\n  <td><img src=\"tcmalloc-opspersec.vs.size.20.threads.png\"></td>\n</tr>\n</table>\n\n\n<ul> \n  <li> TCMalloc is much more consistently scalable than PTMalloc2 - for\n       all thread counts &gt;1 it achieves ~7-9 million ops/sec for small\n       allocations, falling to ~2 million ops/sec for larger\n       allocations. The single-thread case is an obvious outlier,\n       since it is only able to keep a single processor busy and hence\n       can achieve fewer ops/sec. PTMalloc2 has a much higher variance\n       on operations/sec - peaking somewhere around 4 million ops/sec\n       for small allocations and falling to &lt;1 million ops/sec for\n       larger allocations.\n\n  <li> TCMalloc is faster than PTMalloc2 in the vast majority of\n       cases, and particularly for small allocations. Contention\n       between threads is less of a problem in TCMalloc.\n\n  <li> TCMalloc's performance drops off as the allocation size\n       increases. This is because the per-thread cache is\n       garbage-collected when it hits a threshold (defaulting to\n       2MB). With larger allocation sizes, fewer objects can be stored\n       in the cache before it is garbage-collected.\n\n  <li> There is a noticeable drop in TCMalloc's performance at ~32K\n       maximum allocation size; at larger sizes performance drops less\n       quickly. This is due to the 32K maximum size of objects in the\n       per-thread caches; for objects larger than this TCMalloc\n       allocates from the central page heap.\n</ul>\n\n<p>Next, operations (millions) per second of CPU time vs number of\nthreads, for max allocation size 64 bytes - 128 Kbytes.</p>\n\n<table>\n<tr>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.64.bytes.png\"></td>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.256.bytes.png\"></td>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.1024.bytes.png\"></td>\n</tr>\n<tr>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.4096.bytes.png\"></td>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.8192.bytes.png\"></td>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.16384.bytes.png\"></td>\n</tr>\n<tr>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.32768.bytes.png\"></td>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.65536.bytes.png\"></td>\n  <td><img src=\"tcmalloc-opspercpusec.vs.threads.131072.bytes.png\"></td>\n</tr>\n</table>\n\n<p>Here we see again that TCMalloc is both more consistent and more\nefficient than PTMalloc2. For max allocation sizes &lt;32K, TCMalloc\ntypically achieves ~2-2.5 million ops per second of CPU time with a\nlarge number of threads, whereas PTMalloc achieves generally 0.5-1\nmillion ops per second of CPU time, with a lot of cases achieving much\nless than this figure. Above 32K max allocation size, TCMalloc drops\nto 1-1.5 million ops per second of CPU time, and PTMalloc drops almost\nto zero for large numbers of threads (i.e. with PTMalloc, lots of CPU\ntime is being burned spinning waiting for locks in the heavily\nmulti-threaded case).</p>\n\n\n<H2><A NAME=\"runtime\">Modifying Runtime Behavior</A></H2>\n\n<p>You can more finely control the behavior of the tcmalloc via\nenvironment variables.</p>\n\n<p>Generally useful flags:</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>TCMALLOC_SAMPLE_PARAMETER</code></td>\n  <td>default: 0</td>\n  <td>\n    The approximate gap between sampling actions.  That is, we\n    take one sample approximately once every\n    <code>tcmalloc_sample_parmeter</code> bytes of allocation.\n    This sampled heap information is available via\n    <code>MallocExtension::GetHeapSample()</code> or\n    <code>MallocExtension::ReadStackTraces()</code>.  A reasonable\n    value is 524288.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_RELEASE_RATE</code></td>\n  <td>default: 1.0</td>\n  <td>\n    Rate at which we release unused memory to the system, via\n    <code>madvise(MADV_DONTNEED)</code>, on systems that support\n    it.  Zero means we never release memory back to the system.\n    Increase this flag to return memory faster; decrease it\n    to return memory slower.  Reasonable rates are in the\n    range [0,10].\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD</code></td>\n  <td>default: 1073741824</td>\n  <td>\n    Allocations larger than this value cause a stack trace to be\n    dumped to stderr.  The threshold for dumping stack traces is\n    increased by a factor of 1.125 every time we print a message so\n    that the threshold automatically goes up by a factor of ~1000\n    every 60 messages.  This bounds the amount of extra logging\n    generated by this flag.  Default value of this flag is very large\n    and therefore you should see no extra logging unless the flag is\n    overridden.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=<i>x</i></code></td>\n  <td>default: 16777216</td>\n  <td>\n    Bound on the total amount of bytes allocated to thread caches.  This\n    bound is not strict, so it is possible for the cache to go over this\n    bound in certain circumstances.  This value defaults to 16MB.  For\n    applications with many threads, this may not be a large enough cache,\n    which can affect performance.  If you suspect your application is not\n    scaling to many threads due to lock contention in TCMalloc, you can\n    try increasing this value.  This may improve performance, at a cost\n    of extra memory use by TCMalloc.  See <a href=\"#Garbage_Collection\">\n    Garbage Collection</a> for more details.\n  </td>\n</tr>\n\n</table>\n\n<p>Advanced \"tweaking\" flags, that control more precisely how tcmalloc\ntries to allocate memory from the kernel.</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>TCMALLOC_SKIP_MMAP</code></td>\n  <td>default: false</td>\n  <td>\n     If true, do not try to use <code>mmap</code> to obtain memory\n     from the kernel.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_SKIP_SBRK</code></td>\n  <td>default: false</td>\n  <td>\n     If true, do not try to use <code>sbrk</code> to obtain memory\n     from the kernel.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_DEVMEM_START</code></td>\n  <td>default: 0</td>\n  <td>\n    Physical memory starting location in MB for <code>/dev/mem</code>\n    allocation.  Setting this to 0 disables <code>/dev/mem</code>\n    allocation.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_DEVMEM_LIMIT</code></td>\n  <td>default: 0</td>\n  <td>\n     Physical memory limit location in MB for <code>/dev/mem</code>\n     allocation.  Setting this to 0 means no limit.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_DEVMEM_DEVICE</code></td>\n  <td>default: /dev/mem</td>\n  <td>\n     Device to use for allocating unmanaged memory.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_MEMFS_MALLOC_PATH</code></td>\n  <td>default: \"\"</td>\n  <td>\n     If set, specify a path where hugetlbfs or tmpfs is mounted.\n     This may allow for speedier allocations.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_MEMFS_LIMIT_MB</code></td>\n  <td>default: 0</td>\n  <td>\n     Limit total memfs allocation size to specified number of MB.\n     0 means \"no limit\".\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_MEMFS_ABORT_ON_FAIL</code></td>\n  <td>default: false</td>\n  <td>\n     If true, abort() whenever memfs_malloc fails to satisfy an allocation.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>TCMALLOC_MEMFS_IGNORE_MMAP_FAIL</code></td>\n  <td>default: false</td>\n  <td>\n     If true, ignore failures from mmap.\n  </td>\n</tr>\n\n\n</table>\n\n\n<H2><A NAME=\"compiletime\">Modifying Behavior In Code</A></H2>\n\n<p>The <code>MallocExtension</code> class, in\n<code>malloc_extension.h</code>, provides a few knobs that you can\ntweak in your program, to affect tcmalloc's behavior.</p>\n\n<h3>Releasing Memory Back to the System</h3>\n\n<p>By default, tcmalloc will release no-longer-used memory back to the\nkernel gradually, over time.  The <a\nhref=\"#runtime\">tcmalloc_release_rate</a> flag controls how quickly\nthis happens.  You can also force a release at a given point in the\nprogam execution like so:</p>\n<pre>\n   MallocExtension::instance()->ReleaseFreeMemory();\n</pre>\n\n<p>You can also call <code>SetMemoryReleaseRate()</code> to change the\n<code>tcmalloc_release_rate</code> value at runtime, or\n<code>GetMemoryReleaseRate</code> to see what the current release rate\nis.</p>\n\n<h3>Memory Introspection</h3>\n\n<p>There are several routines for getting a human-readable form of the\ncurrent memory usage:</p>\n<pre>\n   MallocExtension::instance()->GetStats(buffer, buffer_length);\n   MallocExtension::instance()->GetHeapSample(&string);\n   MallocExtension::instance()->GetHeapGrowthStacks(&string);\n</pre>\n\n<p>The last two create files in the same format as the heap-profiler,\nand can be passed as data files to pprof.  The first is human-readable\nand is meant for debugging.</p>\n\n<h3>Generic Tcmalloc Status</h3>\n\n<p>TCMalloc has support for setting and retrieving arbitrary\n'properties':</p>\n<pre>\n   MallocExtension::instance()->SetNumericProperty(property_name, value);\n   MallocExtension::instance()->GetNumericProperty(property_name, &value);\n</pre>\n\n<p>It is possible for an application to set and get these properties,\nbut the most useful is when a library sets the properties so the\napplication can read them.  Here are the properties TCMalloc defines;\nyou can access them with a call like\n<code>MallocExtension::instance()->GetNumericProperty(\"generic.heap_size\",\n&value);</code>:</p>\n\n<table frame=box rules=sides cellpadding=5 width=100%>\n\n<tr valign=top>\n  <td><code>generic.current_allocated_bytes</code></td>\n  <td>\n    Number of bytes used by the application.  This will not typically\n    match the memory use reported by the OS, because it does not\n    include TCMalloc overhead or memory fragmentation.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>generic.heap_size</code></td>\n  <td>\n    Bytes of system memory reserved by TCMalloc.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>tcmalloc.pageheap_free_bytes</code></td>\n  <td>\n    Number of bytes in free, mapped pages in page heap.  These bytes\n    can be used to fulfill allocation requests.  They always count\n    towards virtual memory usage, and unless the underlying memory is\n    swapped out by the OS, they also count towards physical memory\n    usage.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>tcmalloc.pageheap_unmapped_bytes</code></td>\n  <td>\n    Number of bytes in free, unmapped pages in page heap.  These are\n    bytes that have been released back to the OS, possibly by one of\n    the MallocExtension \"Release\" calls.  They can be used to fulfill\n    allocation requests, but typically incur a page fault.  They\n    always count towards virtual memory usage, and depending on the\n    OS, typically do not count towards physical memory usage.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>tcmalloc.slack_bytes</code></td>\n  <td>\n    Sum of pageheap_free_bytes and pageheap_unmapped_bytes.  Provided\n    for backwards compatibility only.  Do not use.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>tcmalloc.max_total_thread_cache_bytes</code></td>\n  <td>\n    A limit to how much memory TCMalloc dedicates for small objects.\n    Higher numbers trade off more memory use for -- in some situations\n    -- improved efficiency.\n  </td>\n</tr>\n\n<tr valign=top>\n  <td><code>tcmalloc.current_total_thread_cache_bytes</code></td>\n  <td>\n    A measure of some of the memory TCMalloc is using (for\n    small objects).\n  </td>\n</tr>\n\n</table>\n\n<h2><A NAME=\"caveats\">Caveats</A></h2>\n\n<p>For some systems, TCMalloc may not work correctly with\napplications that aren't linked against <code>libpthread.so</code> (or\nthe equivalent on your OS). It should work on Linux using glibc 2.3,\nbut other OS/libc combinations have not been tested.</p>\n\n<p>TCMalloc may be somewhat more memory hungry than other mallocs,\n(but tends not to have the huge blowups that can happen with other\nmallocs).  In particular, at startup TCMalloc allocates approximately\n240KB of internal memory.</p>\n\n<p>Don't try to load TCMalloc into a running binary (e.g., using JNI\nin Java programs).  The binary will have allocated some objects using\nthe system malloc, and may try to pass them to TCMalloc for\ndeallocation.  TCMalloc will not be able to handle such objects.</p>\n\n<hr>\n\n<address>Sanjay Ghemawat, Paul Menage<br>\n<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->\n<!-- hhmts start -->\nLast modified: Sat Feb 24 13:11:38 PST 2007  (csilvers)\n<!-- hhmts end -->\n</address>\n\n</body>\n</html>\n"
  },
  {
    "path": "distro/google-perftools-1.7/doc/threadheap.dot",
    "content": "digraph ThreadHeap {\nrankdir=LR\nnode [shape=box, width=0.3, height=0.3]\nnodesep=.05\n\nheap [shape=record, height=2, label=\"<f0>class 0|<f1>class 1|<f2>class 2|...\"]\nO0 [label=\"\"]\nO1 [label=\"\"]\nO2 [label=\"\"]\nO3 [label=\"\"]\nO4 [label=\"\"]\nO5 [label=\"\"]\nsep1 [shape=plaintext, label=\"...\"]\nsep2 [shape=plaintext, label=\"...\"]\nsep3 [shape=plaintext, label=\"...\"]\n\nheap:f0 -> O0 -> O1 -> sep1\nheap:f1 -> O2 -> O3 -> sep2\nheap:f2 -> O4 -> O5 -> sep3\n\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/google-perftools.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 8.00\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"libtcmalloc_minimal\", \"vsprojects\\libtcmalloc_minimal\\libtcmalloc_minimal.vcproj\", \"{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"tcmalloc_minimal_unittest\", \"vsprojects\\tcmalloc_minimal_unittest\\tcmalloc_minimal_unittest.vcproj\", \"{7CC73D97-C057-43A6-82EF-E6B567488D02}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"tcmalloc_minimal_large_unittest\", \"vsprojects\\tcmalloc_minimal_large\\tcmalloc_minimal_large_unittest.vcproj\", \"{2D8B9599-C74C-4298-B723-6CF6077563E3}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"addressmap_unittest\", \"vsprojects\\addressmap_unittest\\addressmap_unittest.vcproj\", \"{32EECEB6-7D18-477E-BC7A-30CE98457A88}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"frag_unittest\", \"vsprojects\\frag_unittest\\frag_unittest.vcproj\", \"{24754725-DE0D-4214-8979-324247AAD78E}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"low_level_alloc_unittest\", \"vsprojects\\low_level_alloc_unittest\\low_level_alloc_unittest.vcproj\", \"{A765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"malloc_extension_test\", \"vsprojects\\malloc_extension_test\\malloc_extension_test.vcproj\", \"{3765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"markidle_unittest\", \"vsprojects\\markidle_unittest\\markidle_unittest.vcproj\", \"{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"packed-cache_test\", \"vsprojects\\packed-cache_test\\packed-cache_test.vcproj\", \"{605D3CED-B530-424E-B7D2-2A31F14FD570}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"pagemap_unittest\", \"vsprojects\\pagemap_unittest\\pagemap_unittest.vcproj\", \"{9765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"page_heap_test\", \"vsprojects\\page_heap_test\\page_heap_test.vcproj\", \"{9765198D-5305-4AB0-9A21-A0CD8201EB2B}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"realloc_unittest\", \"vsprojects\\realloc_unittest\\realloc_unittest.vcproj\", \"{4765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"sampler_test\", \"vsprojects\\sampler_test\\sampler_test.vcproj\", \"{B765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"stack_trace_table_test\", \"vsprojects\\stack_trace_table_test\\stack_trace_table_test.vcproj\", \"{A4754725-DE0D-4214-8979-324247AAD78E}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"thread_dealloc_unittest\", \"vsprojects\\thread_dealloc_unittest\\thread_dealloc_unittest.vcproj\", \"{6CFFBD0F-09E3-4282-A711-0564451FDF74}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"tmu-static\", \"vsprojects\\tmu-static\\tmu-static.vcproj\", \"{8F708DCB-7EE4-4BA0-81AA-A52A0BA73B74}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"addr2line-pdb\", \"vsprojects\\addr2line-pdb\\addr2line-pdb.vcproj\", \"{81CA712E-90B8-4AE5-9E89-5B436578D6DA}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"nm-pdb\", \"vsprojects\\nm-pdb\\nm-pdb.vcproj\", \"{3A559C75-FD26-4300-B86B-165FD43EE1CE}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\tEndProjectSection\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfiguration) = preSolution\r\n\t\tDebug = Debug\r\n\t\tRelease = Release\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectDependencies) = postSolution\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfiguration) = postSolution\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Debug.Build.0 = Debug|Win32\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release.ActiveCfg = Release|Win32\r\n\t\t{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}.Release.Build.0 = Release|Win32\r\n\t\t{7CC73D97-C057-43A6-82EF-E6B567488D02}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{7CC73D97-C057-43A6-82EF-E6B567488D02}.Debug.Build.0 = Debug|Win32\r\n\t\t{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release.ActiveCfg = Release|Win32\r\n\t\t{7CC73D97-C057-43A6-82EF-E6B567488D02}.Release.Build.0 = Release|Win32\r\n\t\t{2D8B9599-C74C-4298-B723-6CF6077563E3}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{2D8B9599-C74C-4298-B723-6CF6077563E3}.Debug.Build.0 = Debug|Win32\r\n\t\t{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release.ActiveCfg = Release|Win32\r\n\t\t{2D8B9599-C74C-4298-B723-6CF6077563E3}.Release.Build.0 = Release|Win32\r\n\t\t{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Debug.Build.0 = Debug|Win32\r\n\t\t{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release.ActiveCfg = Release|Win32\r\n\t\t{32EECEB6-7D18-477E-BC7A-30CE98457A88}.Release.Build.0 = Release|Win32\r\n\t\t{24754725-DE0D-4214-8979-324247AAD78E}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{24754725-DE0D-4214-8979-324247AAD78E}.Debug.Build.0 = Debug|Win32\r\n\t\t{24754725-DE0D-4214-8979-324247AAD78E}.Release.ActiveCfg = Release|Win32\r\n\t\t{24754725-DE0D-4214-8979-324247AAD78E}.Release.Build.0 = Release|Win32\r\n\t\t{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.Build.0 = Debug|Win32\r\n\t\t{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.ActiveCfg = Release|Win32\r\n\t\t{A765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.Build.0 = Release|Win32\r\n\t\t{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.Build.0 = Debug|Win32\r\n\t\t{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.ActiveCfg = Release|Win32\r\n\t\t{3765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.Build.0 = Release|Win32\r\n\t\t{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Debug.Build.0 = Debug|Win32\r\n\t\t{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release.ActiveCfg = Release|Win32\r\n\t\t{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}.Release.Build.0 = Release|Win32\r\n\t\t{605D3CED-B530-424E-B7D2-2A31F14FD570}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{605D3CED-B530-424E-B7D2-2A31F14FD570}.Debug.Build.0 = Debug|Win32\r\n\t\t{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release.ActiveCfg = Release|Win32\r\n\t\t{605D3CED-B530-424E-B7D2-2A31F14FD570}.Release.Build.0 = Release|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.Build.0 = Debug|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.ActiveCfg = Release|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.Build.0 = Release|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Debug.Build.0 = Debug|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release.ActiveCfg = Release|Win32\r\n\t\t{9765198D-5305-4AB0-9A21-A0CD8201EB2B}.Release.Build.0 = Release|Win32\r\n\t\t{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.Build.0 = Debug|Win32\r\n\t\t{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.ActiveCfg = Release|Win32\r\n\t\t{4765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.Build.0 = Release|Win32\r\n\t\t{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Debug.Build.0 = Debug|Win32\r\n\t\t{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.ActiveCfg = Release|Win32\r\n\t\t{B765198D-5305-4AB0-9A21-A0CD8201EB2A}.Release.Build.0 = Release|Win32\r\n\t\t{A4754725-DE0D-4214-8979-324247AAD78E}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{A4754725-DE0D-4214-8979-324247AAD78E}.Debug.Build.0 = Debug|Win32\r\n\t\t{A4754725-DE0D-4214-8979-324247AAD78E}.Release.ActiveCfg = Release|Win32\r\n\t\t{A4754725-DE0D-4214-8979-324247AAD78E}.Release.Build.0 = Release|Win32\r\n\t\t{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Debug.Build.0 = Debug|Win32\r\n\t\t{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release.ActiveCfg = Release|Win32\r\n\t\t{6CFFBD0F-09E3-4282-A711-0564451FDF74}.Release.Build.0 = Release|Win32\r\n\t\t{8F708DCB-7EE4-4BA0-81AA-A52A0BA73B74}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{8F708DCB-7EE4-4BA0-81AA-A52A0BA73B74}.Debug.Build.0 = Debug|Win32\r\n\t\t{8F708DCB-7EE4-4BA0-81AA-A52A0BA73B74}.Release.ActiveCfg = Release|Win32\r\n\t\t{8F708DCB-7EE4-4BA0-81AA-A52A0BA73B74}.Release.Build.0 = Release|Win32\r\n\t\t{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Debug.Build.0 = Debug|Win32\r\n\t\t{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release.ActiveCfg = Release|Win32\r\n\t\t{81CA712E-90B8-4AE5-9E89-5B436578D6DA}.Release.Build.0 = Release|Win32\r\n\t\t{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug.ActiveCfg = Debug|Win32\r\n\t\t{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug.Build.0 = Debug|Win32\r\n\t\t{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release.ActiveCfg = Release|Win32\r\n\t\t{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release.Build.0 = Release|Win32\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityAddIns) = postSolution\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/install-sh",
    "content": "#!/bin/sh\n# install - install a program, script, or datafile\n\nscriptversion=2005-05-14.22\n\n# This originates from X11R5 (mit/util/scripts/install.sh), which was\n# later released in X11R6 (xc/config/util/install.sh) with the\n# following copyright and license.\n#\n# Copyright (C) 1994 X Consortium\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to\n# deal in the Software without restriction, including without limitation the\n# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n# sell copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\n# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-\n# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n#\n# Except as contained in this notice, the name of the X Consortium shall not\n# be used in advertising or otherwise to promote the sale, use or other deal-\n# ings in this Software without prior written authorization from the X Consor-\n# tium.\n#\n#\n# FSF changes to this file are in the public domain.\n#\n# Calling this script install-sh is preferred over install.sh, to prevent\n# `make' implicit rules from creating a file called install from it\n# when there is no Makefile.\n#\n# This script is compatible with the BSD install script, but was written\n# from scratch.  It can only install one file at a time, a restriction\n# shared with many OS's install programs.\n\n# set DOITPROG to echo to test this script\n\n# Don't use :- since 4.3BSD and earlier shells don't like it.\ndoit=\"${DOITPROG-}\"\n\n# put in absolute paths if you don't have them in your path; or use env. vars.\n\nmvprog=\"${MVPROG-mv}\"\ncpprog=\"${CPPROG-cp}\"\nchmodprog=\"${CHMODPROG-chmod}\"\nchownprog=\"${CHOWNPROG-chown}\"\nchgrpprog=\"${CHGRPPROG-chgrp}\"\nstripprog=\"${STRIPPROG-strip}\"\nrmprog=\"${RMPROG-rm}\"\nmkdirprog=\"${MKDIRPROG-mkdir}\"\n\nchmodcmd=\"$chmodprog 0755\"\nchowncmd=\nchgrpcmd=\nstripcmd=\nrmcmd=\"$rmprog -f\"\nmvcmd=\"$mvprog\"\nsrc=\ndst=\ndir_arg=\ndstarg=\nno_target_directory=\n\nusage=\"Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE\n   or: $0 [OPTION]... SRCFILES... DIRECTORY\n   or: $0 [OPTION]... -t DIRECTORY SRCFILES...\n   or: $0 [OPTION]... -d DIRECTORIES...\n\nIn the 1st form, copy SRCFILE to DSTFILE.\nIn the 2nd and 3rd, copy all SRCFILES to DIRECTORY.\nIn the 4th, create DIRECTORIES.\n\nOptions:\n-c         (ignored)\n-d         create directories instead of installing files.\n-g GROUP   $chgrpprog installed files to GROUP.\n-m MODE    $chmodprog installed files to MODE.\n-o USER    $chownprog installed files to USER.\n-s         $stripprog installed files.\n-t DIRECTORY  install into DIRECTORY.\n-T         report an error if DSTFILE is a directory.\n--help     display this help and exit.\n--version  display version info and exit.\n\nEnvironment variables override the default commands:\n  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG\n\"\n\nwhile test -n \"$1\"; do\n  case $1 in\n    -c) shift\n        continue;;\n\n    -d) dir_arg=true\n        shift\n        continue;;\n\n    -g) chgrpcmd=\"$chgrpprog $2\"\n        shift\n        shift\n        continue;;\n\n    --help) echo \"$usage\"; exit $?;;\n\n    -m) chmodcmd=\"$chmodprog $2\"\n        shift\n        shift\n        continue;;\n\n    -o) chowncmd=\"$chownprog $2\"\n        shift\n        shift\n        continue;;\n\n    -s) stripcmd=$stripprog\n        shift\n        continue;;\n\n    -t) dstarg=$2\n\tshift\n\tshift\n\tcontinue;;\n\n    -T) no_target_directory=true\n\tshift\n\tcontinue;;\n\n    --version) echo \"$0 $scriptversion\"; exit $?;;\n\n    *)  # When -d is used, all remaining arguments are directories to create.\n\t# When -t is used, the destination is already specified.\n\ttest -n \"$dir_arg$dstarg\" && break\n        # Otherwise, the last argument is the destination.  Remove it from $@.\n\tfor arg\n\tdo\n          if test -n \"$dstarg\"; then\n\t    # $@ is not empty: it contains at least $arg.\n\t    set fnord \"$@\" \"$dstarg\"\n\t    shift # fnord\n\t  fi\n\t  shift # arg\n\t  dstarg=$arg\n\tdone\n\tbreak;;\n  esac\ndone\n\nif test -z \"$1\"; then\n  if test -z \"$dir_arg\"; then\n    echo \"$0: no input file specified.\" >&2\n    exit 1\n  fi\n  # It's OK to call `install-sh -d' without argument.\n  # This can happen when creating conditional directories.\n  exit 0\nfi\n\nfor src\ndo\n  # Protect names starting with `-'.\n  case $src in\n    -*) src=./$src ;;\n  esac\n\n  if test -n \"$dir_arg\"; then\n    dst=$src\n    src=\n\n    if test -d \"$dst\"; then\n      mkdircmd=:\n      chmodcmd=\n    else\n      mkdircmd=$mkdirprog\n    fi\n  else\n    # Waiting for this to be detected by the \"$cpprog $src $dsttmp\" command\n    # might cause directories to be created, which would be especially bad\n    # if $src (and thus $dsttmp) contains '*'.\n    if test ! -f \"$src\" && test ! -d \"$src\"; then\n      echo \"$0: $src does not exist.\" >&2\n      exit 1\n    fi\n\n    if test -z \"$dstarg\"; then\n      echo \"$0: no destination specified.\" >&2\n      exit 1\n    fi\n\n    dst=$dstarg\n    # Protect names starting with `-'.\n    case $dst in\n      -*) dst=./$dst ;;\n    esac\n\n    # If destination is a directory, append the input filename; won't work\n    # if double slashes aren't ignored.\n    if test -d \"$dst\"; then\n      if test -n \"$no_target_directory\"; then\n\techo \"$0: $dstarg: Is a directory\" >&2\n\texit 1\n      fi\n      dst=$dst/`basename \"$src\"`\n    fi\n  fi\n\n  # This sed command emulates the dirname command.\n  dstdir=`echo \"$dst\" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`\n\n  # Make sure that the destination directory exists.\n\n  # Skip lots of stat calls in the usual case.\n  if test ! -d \"$dstdir\"; then\n    defaultIFS='\n\t '\n    IFS=\"${IFS-$defaultIFS}\"\n\n    oIFS=$IFS\n    # Some sh's can't handle IFS=/ for some reason.\n    IFS='%'\n    set x `echo \"$dstdir\" | sed -e 's@/@%@g' -e 's@^%@/@'`\n    shift\n    IFS=$oIFS\n\n    pathcomp=\n\n    while test $# -ne 0 ; do\n      pathcomp=$pathcomp$1\n      shift\n      if test ! -d \"$pathcomp\"; then\n        $mkdirprog \"$pathcomp\"\n\t# mkdir can fail with a `File exist' error in case several\n\t# install-sh are creating the directory concurrently.  This\n\t# is OK.\n\ttest -d \"$pathcomp\" || exit\n      fi\n      pathcomp=$pathcomp/\n    done\n  fi\n\n  if test -n \"$dir_arg\"; then\n    $doit $mkdircmd \"$dst\" \\\n      && { test -z \"$chowncmd\" || $doit $chowncmd \"$dst\"; } \\\n      && { test -z \"$chgrpcmd\" || $doit $chgrpcmd \"$dst\"; } \\\n      && { test -z \"$stripcmd\" || $doit $stripcmd \"$dst\"; } \\\n      && { test -z \"$chmodcmd\" || $doit $chmodcmd \"$dst\"; }\n\n  else\n    dstfile=`basename \"$dst\"`\n\n    # Make a couple of temp file names in the proper directory.\n    dsttmp=$dstdir/_inst.$$_\n    rmtmp=$dstdir/_rm.$$_\n\n    # Trap to clean up those temp files at exit.\n    trap 'ret=$?; rm -f \"$dsttmp\" \"$rmtmp\" && exit $ret' 0\n    trap '(exit $?); exit' 1 2 13 15\n\n    # Copy the file name to the temp name.\n    $doit $cpprog \"$src\" \"$dsttmp\" &&\n\n    # and set any options; do chmod last to preserve setuid bits.\n    #\n    # If any of these fail, we abort the whole thing.  If we want to\n    # ignore errors from any of these, just make sure not to ignore\n    # errors from the above \"$doit $cpprog $src $dsttmp\" command.\n    #\n    { test -z \"$chowncmd\" || $doit $chowncmd \"$dsttmp\"; } \\\n      && { test -z \"$chgrpcmd\" || $doit $chgrpcmd \"$dsttmp\"; } \\\n      && { test -z \"$stripcmd\" || $doit $stripcmd \"$dsttmp\"; } \\\n      && { test -z \"$chmodcmd\" || $doit $chmodcmd \"$dsttmp\"; } &&\n\n    # Now rename the file to the real destination.\n    { $doit $mvcmd -f \"$dsttmp\" \"$dstdir/$dstfile\" 2>/dev/null \\\n      || {\n\t   # The rename failed, perhaps because mv can't rename something else\n\t   # to itself, or perhaps because mv is so ancient that it does not\n\t   # support -f.\n\n\t   # Now remove or move aside any old file at destination location.\n\t   # We try this two ways since rm can't unlink itself on some\n\t   # systems and the destination file might be busy for other\n\t   # reasons.  In this case, the final cleanup might fail but the new\n\t   # file should still install successfully.\n\t   {\n\t     if test -f \"$dstdir/$dstfile\"; then\n\t       $doit $rmcmd -f \"$dstdir/$dstfile\" 2>/dev/null \\\n\t       || $doit $mvcmd -f \"$dstdir/$dstfile\" \"$rmtmp\" 2>/dev/null \\\n\t       || {\n\t\t echo \"$0: cannot unlink or rename $dstdir/$dstfile\" >&2\n\t\t (exit 1); exit 1\n\t       }\n\t     else\n\t       :\n\t     fi\n\t   } &&\n\n\t   # Now rename the file to the real destination.\n\t   $doit $mvcmd \"$dsttmp\" \"$dstdir/$dstfile\"\n\t }\n    }\n  fi || { (exit 1); exit 1; }\ndone\n\n# The final little trick to \"correctly\" pass the exit status to the exit trap.\n{\n  (exit 0); exit 0\n}\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-end: \"$\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/libtool",
    "content": "#! /bin/sh\n\n# libtool - Provide generalized library-building support services.\n# Generated automatically by config.status (google-perftools) 1.7\n# Libtool was configured on host meta.mtv.corp.google.com:\n# NOTE: Changes made to this file will be lost: look at ltmain.sh.\n#\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008 Free Software Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n#   This file is part of GNU Libtool.\n#\n# GNU Libtool is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html, or\n# obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n\n# The names of the tagged configurations supported by this script.\navailable_tags=\"CXX \"\n\n# ### BEGIN LIBTOOL CONFIG\n\n# Whether or not to optimize for fast installation.\nfast_install=yes\n\n# Which release of libtool.m4 was used?\nmacro_version=2.2.6b\nmacro_revision=1.3017\n\n# Whether or not to build shared libraries.\nbuild_libtool_libs=yes\n\n# Whether or not to build static libraries.\nbuild_old_libs=yes\n\n# What type of objects to build.\npic_mode=default\n\n# The host system.\nhost_alias=\nhost=x86_64-unknown-linux-gnu\nhost_os=linux-gnu\n\n# The build system.\nbuild_alias=\nbuild=x86_64-unknown-linux-gnu\nbuild_os=linux-gnu\n\n# A sed program that does not truncate output.\nSED=\"/bin/sed\"\n\n# Sed that helps us avoid accidentally triggering echo(1) options like -n.\nXsed=\"$SED -e 1s/^X//\"\n\n# A grep program that handles long lines.\nGREP=\"/bin/grep\"\n\n# An ERE matcher.\nEGREP=\"/bin/grep -E\"\n\n# A literal string matcher.\nFGREP=\"/bin/grep -F\"\n\n# A BSD- or MS-compatible name lister.\nNM=\"/usr/bin/nm -B\"\n\n# Whether we need soft or hard links.\nLN_S=\"ln -s\"\n\n# What is the maximum length of a command?\nmax_cmd_len=3458764513820540925\n\n# Object file suffix (normally \"o\").\nobjext=o\n\n# Executable file suffix (normally \"\").\nexeext=\n\n# whether the shell understands \"unset\".\nlt_unset=unset\n\n# turn spaces into newlines.\nSP2NL=\"tr \\\\040 \\\\012\"\n\n# turn newlines into spaces.\nNL2SP=\"tr \\\\015\\\\012 \\\\040\\\\040\"\n\n# How to create reloadable object files.\nreload_flag=\" -r\"\nreload_cmds=\"\\$LD\\$reload_flag -o \\$output\\$reload_objs\"\n\n# An object symbol dumper.\nOBJDUMP=\"objdump\"\n\n# Method to check whether dependent libraries are shared objects.\ndeplibs_check_method=\"pass_all\"\n\n# Command to use when deplibs_check_method == \"file_magic\".\nfile_magic_cmd=\"\\$MAGIC_CMD\"\n\n# The archiver.\nAR=\"ar\"\nAR_FLAGS=\"cru\"\n\n# A symbol stripping program.\nSTRIP=\"strip\"\n\n# Commands used to install an old-style archive.\nRANLIB=\"ranlib\"\nold_postinstall_cmds=\"chmod 644 \\$oldlib~\\$RANLIB \\$oldlib\"\nold_postuninstall_cmds=\"\"\n\n# A C compiler.\nLTCC=\"gcc\"\n\n# LTCC compiler flags.\nLTCFLAGS=\"-g -O2\"\n\n# Take the output of nm and produce a listing of raw symbols and C names.\nglobal_symbol_pipe=\"sed -n -e 's/^.*[\t ]\\\\([ABCDGIRSTW][ABCDGIRSTW]*\\\\)[\t ][\t ]*\\\\([_A-Za-z][_A-Za-z0-9]*\\\\)\\$/\\\\1 \\\\2 \\\\2/p'\"\n\n# Transform the output of nm in a proper C declaration.\nglobal_symbol_to_cdecl=\"sed -n -e 's/^T .* \\\\(.*\\\\)\\$/extern int \\\\1();/p' -e 's/^[ABCDGIRSTW]* .* \\\\(.*\\\\)\\$/extern char \\\\1;/p'\"\n\n# Transform the output of nm in a C name address pair.\nglobal_symbol_to_c_name_address=\"sed -n -e 's/^: \\\\([^ ]*\\\\) \\$/  {\\\\\\\"\\\\1\\\\\\\", (void *) 0},/p' -e 's/^[ABCDGIRSTW]* \\\\([^ ]*\\\\) \\\\([^ ]*\\\\)\\$/  {\\\"\\\\2\\\", (void *) \\\\&\\\\2},/p'\"\n\n# Transform the output of nm in a C name address pair when lib prefix is needed.\nglobal_symbol_to_c_name_address_lib_prefix=\"sed -n -e 's/^: \\\\([^ ]*\\\\) \\$/  {\\\\\\\"\\\\1\\\\\\\", (void *) 0},/p' -e 's/^[ABCDGIRSTW]* \\\\([^ ]*\\\\) \\\\(lib[^ ]*\\\\)\\$/  {\\\"\\\\2\\\", (void *) \\\\&\\\\2},/p' -e 's/^[ABCDGIRSTW]* \\\\([^ ]*\\\\) \\\\([^ ]*\\\\)\\$/  {\\\"lib\\\\2\\\", (void *) \\\\&\\\\2},/p'\"\n\n# The name of the directory that contains temporary libtool files.\nobjdir=.libs\n\n# Shell to use when invoking shell scripts.\nSHELL=\"/bin/sh\"\n\n# An echo program that does not interpret backslashes.\nECHO=\"echo\"\n\n# Used to examine libraries when file_magic_cmd begins with \"file\".\nMAGIC_CMD=file\n\n# Must we lock files when doing compilation?\nneed_locks=\"no\"\n\n# Tool to manipulate archived DWARF debug symbol files on Mac OS X.\nDSYMUTIL=\"\"\n\n# Tool to change global to local symbols on Mac OS X.\nNMEDIT=\"\"\n\n# Tool to manipulate fat objects and archives on Mac OS X.\nLIPO=\"\"\n\n# ldd/readelf like tool for Mach-O binaries on Mac OS X.\nOTOOL=\"\"\n\n# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.\nOTOOL64=\"\"\n\n# Old archive suffix (normally \"a\").\nlibext=a\n\n# Shared library suffix (normally \".so\").\nshrext_cmds=\".so\"\n\n# The commands to extract the exported symbol list from a shared archive.\nextract_expsyms_cmds=\"\"\n\n# Variables whose values should be saved in libtool wrapper scripts and\n# restored at link time.\nvariables_saved_for_relink=\"PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH\"\n\n# Do we need the \"lib\" prefix for modules?\nneed_lib_prefix=no\n\n# Do we need a version for libraries?\nneed_version=no\n\n# Library versioning type.\nversion_type=linux\n\n# Shared library runtime path variable.\nrunpath_var=LD_RUN_PATH\n\n# Shared library path variable.\nshlibpath_var=LD_LIBRARY_PATH\n\n# Is shlibpath searched before the hard-coded library search path?\nshlibpath_overrides_runpath=no\n\n# Format of library name prefix.\nlibname_spec=\"lib\\$name\"\n\n# List of archive names.  First name is the real one, the rest are links.\n# The last name is the one that the linker finds with -lNAME\nlibrary_names_spec=\"\\${libname}\\${release}\\${shared_ext}\\$versuffix \\${libname}\\${release}\\${shared_ext}\\$major \\$libname\\${shared_ext}\"\n\n# The coded name of the library, if different from the real name.\nsoname_spec=\"\\${libname}\\${release}\\${shared_ext}\\$major\"\n\n# Command to use after installation of a shared archive.\npostinstall_cmds=\"\"\n\n# Command to use after uninstallation of a shared archive.\npostuninstall_cmds=\"\"\n\n# Commands used to finish a libtool library installation in a directory.\nfinish_cmds=\"PATH=\\\\\\\"\\\\\\$PATH:/sbin\\\\\\\" ldconfig -n \\$libdir\"\n\n# As \"finish_cmds\", except a single script fragment to be evaled but\n# not shown.\nfinish_eval=\"\"\n\n# Whether we should hardcode library paths into libraries.\nhardcode_into_libs=yes\n\n# Compile-time system search path for libraries.\nsys_lib_search_path_spec=\"/usr/lib/gcc/x86_64-linux-gnu/4.4.3 /usr/lib /lib /usr/lib/x86_64-linux-gnu\"\n\n# Run-time system search path for libraries.\nsys_lib_dlsearch_path_spec=\"/lib /usr/lib /usr/lib/nvidia-current /usr/lib32/nvidia-current /usr/lib32/alsa-lib /usr/lib/alsa-lib /usr/local/lib /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu \"\n\n# Whether dlopen is supported.\ndlopen_support=unknown\n\n# Whether dlopen of programs is supported.\ndlopen_self=unknown\n\n# Whether dlopen of statically linked programs is supported.\ndlopen_self_static=unknown\n\n# Commands to strip libraries.\nold_striplib=\"strip --strip-debug\"\nstriplib=\"strip --strip-unneeded\"\n\n\n# The linker used to build libraries.\nLD=\"/usr/bin/ld -m elf_x86_64\"\n\n# Commands used to build an old-style archive.\nold_archive_cmds=\"\\$AR \\$AR_FLAGS \\$oldlib\\$oldobjs~\\$RANLIB \\$oldlib\"\n\n# A language specific compiler.\nCC=\"gcc\"\n\n# Is the compiler the GNU compiler?\nwith_gcc=yes\n\n# Compiler flag to turn off builtin functions.\nno_builtin_flag=\" -fno-builtin\"\n\n# How to pass a linker flag through the compiler.\nwl=\"-Wl,\"\n\n# Additional compiler flags for building library objects.\npic_flag=\" -fPIC -DPIC\"\n\n# Compiler flag to prevent dynamic linking.\nlink_static_flag=\"-static\"\n\n# Does compiler simultaneously support -c and -o options?\ncompiler_c_o=\"yes\"\n\n# Whether or not to add -lc for building shared libraries.\nbuild_libtool_need_lc=no\n\n# Whether or not to disallow shared libs when runtime libs are static.\nallow_libtool_libs_with_static_runtimes=no\n\n# Compiler flag to allow reflexive dlopens.\nexport_dynamic_flag_spec=\"\\${wl}--export-dynamic\"\n\n# Compiler flag to generate shared objects directly from archives.\nwhole_archive_flag_spec=\"\\${wl}--whole-archive\\$convenience \\${wl}--no-whole-archive\"\n\n# Whether the compiler copes with passing no objects directly.\ncompiler_needs_object=\"no\"\n\n# Create an old-style archive from a shared archive.\nold_archive_from_new_cmds=\"\"\n\n# Create a temporary old-style archive to link instead of a shared archive.\nold_archive_from_expsyms_cmds=\"\"\n\n# Commands used to build a shared archive.\narchive_cmds=\"\\$CC -shared \\$libobjs \\$deplibs \\$compiler_flags \\${wl}-soname \\$wl\\$soname -o \\$lib\"\narchive_expsym_cmds=\"echo \\\\\\\"{ global:\\\\\\\" > \\$output_objdir/\\$libname.ver~\n\t    cat \\$export_symbols | sed -e \\\\\\\"s/\\\\\\\\(.*\\\\\\\\)/\\\\\\\\1;/\\\\\\\" >> \\$output_objdir/\\$libname.ver~\n\t    echo \\\\\\\"local: *; };\\\\\\\" >> \\$output_objdir/\\$libname.ver~\n\t    \\$CC -shared \\$libobjs \\$deplibs \\$compiler_flags \\${wl}-soname \\$wl\\$soname \\${wl}-version-script \\${wl}\\$output_objdir/\\$libname.ver -o \\$lib\"\n\n# Commands used to build a loadable module if different from building\n# a shared archive.\nmodule_cmds=\"\"\nmodule_expsym_cmds=\"\"\n\n# Whether we are building with GNU ld or not.\nwith_gnu_ld=\"yes\"\n\n# Flag that allows shared libraries with undefined symbols to be built.\nallow_undefined_flag=\"\"\n\n# Flag that enforces no undefined symbols.\nno_undefined_flag=\"\"\n\n# Flag to hardcode $libdir into a binary during linking.\n# This must work even if $libdir does not exist\nhardcode_libdir_flag_spec=\"\\${wl}-rpath \\${wl}\\$libdir\"\n\n# If ld is used when linking, flag to hardcode $libdir into a binary\n# during linking.  This must work even if $libdir does not exist.\nhardcode_libdir_flag_spec_ld=\"\"\n\n# Whether we need a single \"-rpath\" flag with a separated argument.\nhardcode_libdir_separator=\"\"\n\n# Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n# DIR into the resulting binary.\nhardcode_direct=no\n\n# Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n# DIR into the resulting binary and the resulting library dependency is\n# \"absolute\",i.e impossible to change by setting ${shlibpath_var} if the\n# library is relocated.\nhardcode_direct_absolute=no\n\n# Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n# into the resulting binary.\nhardcode_minus_L=no\n\n# Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n# into the resulting binary.\nhardcode_shlibpath_var=unsupported\n\n# Set to \"yes\" if building a shared library automatically hardcodes DIR\n# into the library and all subsequent libraries and executables linked\n# against it.\nhardcode_automatic=no\n\n# Set to yes if linker adds runtime paths of dependent libraries\n# to runtime path list.\ninherit_rpath=no\n\n# Whether libtool must link a program against all its dependency libraries.\nlink_all_deplibs=no\n\n# Fix the shell variable $srcfile for the compiler.\nfix_srcfile_path=\"\"\n\n# Set to \"yes\" if exported symbols are required.\nalways_export_symbols=no\n\n# The commands to list exported symbols.\nexport_symbols_cmds=\"\\$NM \\$libobjs \\$convenience | \\$global_symbol_pipe | \\$SED 's/.* //' | sort | uniq > \\$export_symbols\"\n\n# Symbols that should not be listed in the preloaded symbols.\nexclude_expsyms=\"_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*\"\n\n# Symbols that must always be exported.\ninclude_expsyms=\"\"\n\n# Commands necessary for linking programs (against libraries) with templates.\nprelink_cmds=\"\"\n\n# Specify filename containing input files.\nfile_list_spec=\"\"\n\n# How to hardcode a shared library path into an executable.\nhardcode_action=immediate\n\n# The directories searched by this compiler when creating a shared library.\ncompiler_lib_search_dirs=\"\"\n\n# Dependencies to place before and after the objects being linked to\n# create a shared library.\npredep_objects=\"\"\npostdep_objects=\"\"\npredeps=\"\"\npostdeps=\"\"\n\n# The library search path used internally by the compiler when linking\n# a shared library.\ncompiler_lib_search_path=\"\"\n\n# ### END LIBTOOL CONFIG\n\n# Generated from ltmain.m4sh.\n\n# ltmain.sh (GNU libtool) 2.2.6b\n# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.\n# This is free software; see the source for copying conditions.  There is NO\n# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n# GNU Libtool is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html,\n# or obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n# Usage: $progname [OPTION]... [MODE-ARG]...\n#\n# Provide generalized library-building support services.\n#\n#     --config             show all configuration variables\n#     --debug              enable verbose shell tracing\n# -n, --dry-run            display commands without modifying any files\n#     --features           display basic configuration information and exit\n#     --mode=MODE          use operation mode MODE\n#     --preserve-dup-deps  don't remove duplicate dependency libraries\n#     --quiet, --silent    don't print informational messages\n#     --tag=TAG            use configuration variables from tag TAG\n# -v, --verbose            print informational messages (default)\n#     --version            print version information\n# -h, --help               print short or long help message\n#\n# MODE must be one of the following:\n#\n#       clean              remove files from the build directory\n#       compile            compile a source file into a libtool object\n#       execute            automatically set library path, then run a program\n#       finish             complete the installation of libtool libraries\n#       install            install libraries or executables\n#       link               create a library or an executable\n#       uninstall          remove libraries from an installed directory\n#\n# MODE-ARGS vary depending on the MODE.\n# Try `$progname --help --mode=MODE' for a more detailed description of MODE.\n#\n# When reporting a bug, please describe a test case to reproduce it and\n# include the following information:\n#\n#       host-triplet:\t$host\n#       shell:\t\t$SHELL\n#       compiler:\t\t$LTCC\n#       compiler flags:\t\t$LTCFLAGS\n#       linker:\t\t$LD (gnu? $with_gnu_ld)\n#       $progname:\t\t(GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1\n#       automake:\t\t$automake_version\n#       autoconf:\t\t$autoconf_version\n#\n# Report bugs to <bug-libtool@gnu.org>.\n\nPROGRAM=ltmain.sh\nPACKAGE=libtool\nVERSION=\"2.2.6b Debian-2.2.6b-2ubuntu1\"\nTIMESTAMP=\"\"\npackage_revision=1.3017\n\n# Be Bourne compatible\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then\n  emulate sh\n  NULLCMD=:\n  # Zsh 3.x and 4.x performs word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac\nfi\nBIN_SH=xpg4; export BIN_SH # for Tru64\nDUALCASE=1; export DUALCASE # for MKS sh\n\n# NLS nuisances: We save the old values to restore during execute mode.\n# Only set LANG and LC_ALL to C if already set.\n# These must not be set unconditionally because not all systems understand\n# e.g. LANG=C (notably SCO).\nlt_user_locale=\nlt_safe_locale=\nfor lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES\ndo\n  eval \"if test \\\"\\${$lt_var+set}\\\" = set; then\n          save_$lt_var=\\$$lt_var\n          $lt_var=C\n\t  export $lt_var\n\t  lt_user_locale=\\\"$lt_var=\\\\\\$save_\\$lt_var; \\$lt_user_locale\\\"\n\t  lt_safe_locale=\\\"$lt_var=C; \\$lt_safe_locale\\\"\n\tfi\"\ndone\n\n$lt_unset CDPATH\n\n\n\n\n\n: ${CP=\"cp -f\"}\n: ${ECHO=\"echo\"}\n: ${EGREP=\"/bin/grep -E\"}\n: ${FGREP=\"/bin/grep -F\"}\n: ${GREP=\"/bin/grep\"}\n: ${LN_S=\"ln -s\"}\n: ${MAKE=\"make\"}\n: ${MKDIR=\"mkdir\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\n: ${SED=\"/bin/sed\"}\n: ${SHELL=\"${CONFIG_SHELL-/bin/sh}\"}\n: ${Xsed=\"$SED -e 1s/^X//\"}\n\n# Global variables:\nEXIT_SUCCESS=0\nEXIT_FAILURE=1\nEXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.\nEXIT_SKIP=77\t  # $? = 77 is used to indicate a skipped test to automake.\n\nexit_status=$EXIT_SUCCESS\n\n# Make sure IFS has a sensible default\nlt_nl='\n'\nIFS=\" \t$lt_nl\"\n\ndirname=\"s,/[^/]*$,,\"\nbasename=\"s,^.*/,,\"\n\n# func_dirname_and_basename file append nondir_replacement\n# perform func_basename and func_dirname in a single function\n# call:\n#   dirname:  Compute the dirname of FILE.  If nonempty,\n#             add APPEND to the result, otherwise set result\n#             to NONDIR_REPLACEMENT.\n#             value returned in \"$func_dirname_result\"\n#   basename: Compute filename of FILE.\n#             value retuned in \"$func_basename_result\"\n# Implementation must be kept synchronized with func_dirname\n# and func_basename. For efficiency, we do not delegate to\n# those functions but instead duplicate the functionality here.\nfunc_dirname_and_basename ()\n{\n  # Extract subdirectory from the argument.\n  func_dirname_result=`$ECHO \"X${1}\" | $Xsed -e \"$dirname\"`\n  if test \"X$func_dirname_result\" = \"X${1}\"; then\n    func_dirname_result=\"${3}\"\n  else\n    func_dirname_result=\"$func_dirname_result${2}\"\n  fi\n  func_basename_result=`$ECHO \"X${1}\" | $Xsed -e \"$basename\"`\n}\n\n# Generated shell functions inserted here.\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_dirname_and_basename file append nondir_replacement\n# perform func_basename and func_dirname in a single function\n# call:\n#   dirname:  Compute the dirname of FILE.  If nonempty,\n#             add APPEND to the result, otherwise set result\n#             to NONDIR_REPLACEMENT.\n#             value returned in \"$func_dirname_result\"\n#   basename: Compute filename of FILE.\n#             value retuned in \"$func_basename_result\"\n# Implementation must be kept synchronized with func_dirname\n# and func_basename. For efficiency, we do not delegate to\n# those functions but instead duplicate the functionality here.\nfunc_dirname_and_basename ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\nfunc_stripname ()\n{\n  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\n  # positional parameters, so assign one to ordinary parameter first.\n  func_stripname_result=${3}\n  func_stripname_result=${func_stripname_result#\"${1}\"}\n  func_stripname_result=${func_stripname_result%\"${2}\"}\n}\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=${1%%=*}\n  func_opt_split_arg=${1#*=}\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  case ${1} in\n    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\n    *)    func_lo2o_result=${1} ;;\n  esac\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=${1%.*}.lo\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=$(( $* ))\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=${#1}\n}\n\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$1+=\\$2\"\n}\n# Generated shell functions inserted here.\n\n# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh\n# is ksh but when the shell is invoked as \"sh\" and the current value of\n# the _XPG environment variable is not equal to 1 (one), the special\n# positional parameter $0, within a function call, is the name of the\n# function.\nprogpath=\"$0\"\n\n# The name of this program:\n# In the unlikely event $progname began with a '-', it would play havoc with\n# func_echo (imagine progname=-n), so we prepend ./ in that case:\nfunc_dirname_and_basename \"$progpath\"\nprogname=$func_basename_result\ncase $progname in\n  -*) progname=./$progname ;;\nesac\n\n# Make sure we have an absolute path for reexecution:\ncase $progpath in\n  [\\\\/]*|[A-Za-z]:\\\\*) ;;\n  *[\\\\/]*)\n     progdir=$func_dirname_result\n     progdir=`cd \"$progdir\" && pwd`\n     progpath=\"$progdir/$progname\"\n     ;;\n  *)\n     save_IFS=\"$IFS\"\n     IFS=:\n     for progdir in $PATH; do\n       IFS=\"$save_IFS\"\n       test -x \"$progdir/$progname\" && break\n     done\n     IFS=\"$save_IFS\"\n     test -n \"$progdir\" || progdir=`pwd`\n     progpath=\"$progdir/$progname\"\n     ;;\nesac\n\n# Sed substitution that helps us do robust quoting.  It backslashifies\n# metacharacters that are still active within double-quoted strings.\nXsed=\"${SED}\"' -e 1s/^X//'\nsed_quote_subst='s/\\([`\"$\\\\]\\)/\\\\\\1/g'\n\n# Same as above, but do not quote variable references.\ndouble_quote_subst='s/\\([\"`\\\\]\\)/\\\\\\1/g'\n\n# Re-`\\' parameter expansions in output of double_quote_subst that were\n# `\\'-ed in input to the same.  If an odd number of `\\' preceded a '$'\n# in input to double_quote_subst, that '$' was protected from expansion.\n# Since each input `\\' is now two `\\'s, look for any number of runs of\n# four `\\'s followed by two `\\'s and then a '$'.  `\\' that '$'.\nbs='\\\\'\nbs2='\\\\\\\\'\nbs4='\\\\\\\\\\\\\\\\'\ndollar='\\$'\nsed_double_backslash=\"\\\n  s/$bs4/&\\\\\n/g\n  s/^$bs2$dollar/$bs&/\n  s/\\\\([^$bs]\\\\)$bs2$dollar/\\\\1$bs2$bs$dollar/g\n  s/\\n//g\"\n\n# Standard options:\nopt_dry_run=false\nopt_help=false\nopt_quiet=false\nopt_verbose=false\nopt_warning=:\n\n# func_echo arg...\n# Echo program name prefixed message, along with the current mode\n# name if it has been set yet.\nfunc_echo ()\n{\n    $ECHO \"$progname${mode+: }$mode: $*\"\n}\n\n# func_verbose arg...\n# Echo program name prefixed message in verbose mode only.\nfunc_verbose ()\n{\n    $opt_verbose && func_echo ${1+\"$@\"}\n\n    # A bug in bash halts the script if the last line of a function\n    # fails when set -e is in force, so we need another command to\n    # work around that:\n    :\n}\n\n# func_error arg...\n# Echo program name prefixed message to standard error.\nfunc_error ()\n{\n    $ECHO \"$progname${mode+: }$mode: \"${1+\"$@\"} 1>&2\n}\n\n# func_warning arg...\n# Echo program name prefixed warning message to standard error.\nfunc_warning ()\n{\n    $opt_warning && $ECHO \"$progname${mode+: }$mode: warning: \"${1+\"$@\"} 1>&2\n\n    # bash bug again:\n    :\n}\n\n# func_fatal_error arg...\n# Echo program name prefixed message to standard error, and exit.\nfunc_fatal_error ()\n{\n    func_error ${1+\"$@\"}\n    exit $EXIT_FAILURE\n}\n\n# func_fatal_help arg...\n# Echo program name prefixed message to standard error, followed by\n# a help hint, and exit.\nfunc_fatal_help ()\n{\n    func_error ${1+\"$@\"}\n    func_fatal_error \"$help\"\n}\nhelp=\"Try \\`$progname --help' for more information.\"  ## default\n\n\n# func_grep expression filename\n# Check whether EXPRESSION matches any line of FILENAME, without output.\nfunc_grep ()\n{\n    $GREP \"$1\" \"$2\" >/dev/null 2>&1\n}\n\n\n# func_mkdir_p directory-path\n# Make sure the entire path to DIRECTORY-PATH is available.\nfunc_mkdir_p ()\n{\n    my_directory_path=\"$1\"\n    my_dir_list=\n\n    if test -n \"$my_directory_path\" && test \"$opt_dry_run\" != \":\"; then\n\n      # Protect directory names starting with `-'\n      case $my_directory_path in\n        -*) my_directory_path=\"./$my_directory_path\" ;;\n      esac\n\n      # While some portion of DIR does not yet exist...\n      while test ! -d \"$my_directory_path\"; do\n        # ...make a list in topmost first order.  Use a colon delimited\n\t# list incase some portion of path contains whitespace.\n        my_dir_list=\"$my_directory_path:$my_dir_list\"\n\n        # If the last portion added has no slash in it, the list is done\n        case $my_directory_path in */*) ;; *) break ;; esac\n\n        # ...otherwise throw away the child directory and loop\n        my_directory_path=`$ECHO \"X$my_directory_path\" | $Xsed -e \"$dirname\"`\n      done\n      my_dir_list=`$ECHO \"X$my_dir_list\" | $Xsed -e 's,:*$,,'`\n\n      save_mkdir_p_IFS=\"$IFS\"; IFS=':'\n      for my_dir in $my_dir_list; do\n\tIFS=\"$save_mkdir_p_IFS\"\n        # mkdir can fail with a `File exist' error if two processes\n        # try to create one of the directories concurrently.  Don't\n        # stop in that case!\n        $MKDIR \"$my_dir\" 2>/dev/null || :\n      done\n      IFS=\"$save_mkdir_p_IFS\"\n\n      # Bail out if we (or some other process) failed to create a directory.\n      test -d \"$my_directory_path\" || \\\n        func_fatal_error \"Failed to create \\`$1'\"\n    fi\n}\n\n\n# func_mktempdir [string]\n# Make a temporary directory that won't clash with other running\n# libtool processes, and avoids race conditions if possible.  If\n# given, STRING is the basename for that directory.\nfunc_mktempdir ()\n{\n    my_template=\"${TMPDIR-/tmp}/${1-$progname}\"\n\n    if test \"$opt_dry_run\" = \":\"; then\n      # Return a directory name, but don't create it in dry-run mode\n      my_tmpdir=\"${my_template}-$$\"\n    else\n\n      # If mktemp works, use that first and foremost\n      my_tmpdir=`mktemp -d \"${my_template}-XXXXXXXX\" 2>/dev/null`\n\n      if test ! -d \"$my_tmpdir\"; then\n        # Failing that, at least try and use $RANDOM to avoid a race\n        my_tmpdir=\"${my_template}-${RANDOM-0}$$\"\n\n        save_mktempdir_umask=`umask`\n        umask 0077\n        $MKDIR \"$my_tmpdir\"\n        umask $save_mktempdir_umask\n      fi\n\n      # If we're not in dry-run mode, bomb out on failure\n      test -d \"$my_tmpdir\" || \\\n        func_fatal_error \"cannot create temporary directory \\`$my_tmpdir'\"\n    fi\n\n    $ECHO \"X$my_tmpdir\" | $Xsed\n}\n\n\n# func_quote_for_eval arg\n# Aesthetically quote ARG to be evaled later.\n# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT\n# is double-quoted, suitable for a subsequent eval, whereas\n# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters\n# which are still active within double quotes backslashified.\nfunc_quote_for_eval ()\n{\n    case $1 in\n      *[\\\\\\`\\\"\\$]*)\n\tfunc_quote_for_eval_unquoted_result=`$ECHO \"X$1\" | $Xsed -e \"$sed_quote_subst\"` ;;\n      *)\n        func_quote_for_eval_unquoted_result=\"$1\" ;;\n    esac\n\n    case $func_quote_for_eval_unquoted_result in\n      # Double-quote args containing shell metacharacters to delay\n      # word splitting, command substitution and and variable\n      # expansion for a subsequent eval.\n      # Many Bourne shells cannot handle close brackets correctly\n      # in scan sets, so we specify it separately.\n      *[\\[\\~\\#\\^\\&\\*\\(\\)\\{\\}\\|\\;\\<\\>\\?\\'\\ \\\t]*|*]*|\"\")\n        func_quote_for_eval_result=\"\\\"$func_quote_for_eval_unquoted_result\\\"\"\n        ;;\n      *)\n        func_quote_for_eval_result=\"$func_quote_for_eval_unquoted_result\"\n    esac\n}\n\n\n# func_quote_for_expand arg\n# Aesthetically quote ARG to be evaled later; same as above,\n# but do not quote variable references.\nfunc_quote_for_expand ()\n{\n    case $1 in\n      *[\\\\\\`\\\"]*)\n\tmy_arg=`$ECHO \"X$1\" | $Xsed \\\n\t    -e \"$double_quote_subst\" -e \"$sed_double_backslash\"` ;;\n      *)\n        my_arg=\"$1\" ;;\n    esac\n\n    case $my_arg in\n      # Double-quote args containing shell metacharacters to delay\n      # word splitting and command substitution for a subsequent eval.\n      # Many Bourne shells cannot handle close brackets correctly\n      # in scan sets, so we specify it separately.\n      *[\\[\\~\\#\\^\\&\\*\\(\\)\\{\\}\\|\\;\\<\\>\\?\\'\\ \\\t]*|*]*|\"\")\n        my_arg=\"\\\"$my_arg\\\"\"\n        ;;\n    esac\n\n    func_quote_for_expand_result=\"$my_arg\"\n}\n\n\n# func_show_eval cmd [fail_exp]\n# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is\n# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP\n# is given, then evaluate it.\nfunc_show_eval ()\n{\n    my_cmd=\"$1\"\n    my_fail_exp=\"${2-:}\"\n\n    ${opt_silent-false} || {\n      func_quote_for_expand \"$my_cmd\"\n      eval \"func_echo $func_quote_for_expand_result\"\n    }\n\n    if ${opt_dry_run-false}; then :; else\n      eval \"$my_cmd\"\n      my_status=$?\n      if test \"$my_status\" -eq 0; then :; else\n\teval \"(exit $my_status); $my_fail_exp\"\n      fi\n    fi\n}\n\n\n# func_show_eval_locale cmd [fail_exp]\n# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is\n# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP\n# is given, then evaluate it.  Use the saved locale for evaluation.\nfunc_show_eval_locale ()\n{\n    my_cmd=\"$1\"\n    my_fail_exp=\"${2-:}\"\n\n    ${opt_silent-false} || {\n      func_quote_for_expand \"$my_cmd\"\n      eval \"func_echo $func_quote_for_expand_result\"\n    }\n\n    if ${opt_dry_run-false}; then :; else\n      eval \"$lt_user_locale\n\t    $my_cmd\"\n      my_status=$?\n      eval \"$lt_safe_locale\"\n      if test \"$my_status\" -eq 0; then :; else\n\teval \"(exit $my_status); $my_fail_exp\"\n      fi\n    fi\n}\n\n\n\n\n\n# func_version\n# Echo version message to standard output and exit.\nfunc_version ()\n{\n    $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {\n        s/^# //\n\ts/^# *$//\n        s/\\((C)\\)[ 0-9,-]*\\( [1-9][0-9]*\\)/\\1\\2/\n        p\n     }' < \"$progpath\"\n     exit $?\n}\n\n# func_usage\n# Echo short help message to standard output and exit.\nfunc_usage ()\n{\n    $SED -n '/^# Usage:/,/# -h/ {\n        s/^# //\n\ts/^# *$//\n\ts/\\$progname/'$progname'/\n\tp\n    }' < \"$progpath\"\n    $ECHO\n    $ECHO \"run \\`$progname --help | more' for full usage\"\n    exit $?\n}\n\n# func_help\n# Echo long help message to standard output and exit.\nfunc_help ()\n{\n    $SED -n '/^# Usage:/,/# Report bugs to/ {\n        s/^# //\n\ts/^# *$//\n\ts*\\$progname*'$progname'*\n\ts*\\$host*'\"$host\"'*\n\ts*\\$SHELL*'\"$SHELL\"'*\n\ts*\\$LTCC*'\"$LTCC\"'*\n\ts*\\$LTCFLAGS*'\"$LTCFLAGS\"'*\n\ts*\\$LD*'\"$LD\"'*\n\ts/\\$with_gnu_ld/'\"$with_gnu_ld\"'/\n\ts/\\$automake_version/'\"`(automake --version) 2>/dev/null |$SED 1q`\"'/\n\ts/\\$autoconf_version/'\"`(autoconf --version) 2>/dev/null |$SED 1q`\"'/\n\tp\n     }' < \"$progpath\"\n    exit $?\n}\n\n# func_missing_arg argname\n# Echo program name prefixed message to standard error and set global\n# exit_cmd.\nfunc_missing_arg ()\n{\n    func_error \"missing argument for $1\"\n    exit_cmd=exit\n}\n\nexit_cmd=:\n\n\n\n\n\n# Check that we have a working $ECHO.\nif test \"X$1\" = X--no-reexec; then\n  # Discard the --no-reexec flag, and continue.\n  shift\nelif test \"X$1\" = X--fallback-echo; then\n  # Avoid inline document here, it may be left over\n  :\nelif test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t'; then\n  # Yippee, $ECHO works!\n  :\nelse\n  # Restart under the correct shell, and then maybe $ECHO will work.\n  exec $SHELL \"$progpath\" --no-reexec ${1+\"$@\"}\nfi\n\nif test \"X$1\" = X--fallback-echo; then\n  # used as fallback echo\n  shift\n  cat <<EOF\n$*\nEOF\n  exit $EXIT_SUCCESS\nfi\n\nmagic=\"%%%MAGIC variable%%%\"\nmagic_exe=\"%%%MAGIC EXE variable%%%\"\n\n# Global variables.\n# $mode is unset\nnonopt=\nexecute_dlfiles=\npreserve_args=\nlo2o=\"s/\\\\.lo\\$/.${objext}/\"\no2lo=\"s/\\\\.${objext}\\$/.lo/\"\nextracted_archives=\nextracted_serial=0\n\nopt_dry_run=false\nopt_duplicate_deps=false\nopt_silent=false\nopt_debug=:\n\n# If this variable is set in any of the actions, the command in it\n# will be execed at the end.  This prevents here-documents from being\n# left over by shells.\nexec_cmd=\n\n# func_fatal_configuration arg...\n# Echo program name prefixed message to standard error, followed by\n# a configuration failure hint, and exit.\nfunc_fatal_configuration ()\n{\n    func_error ${1+\"$@\"}\n    func_error \"See the $PACKAGE documentation for more information.\"\n    func_fatal_error \"Fatal configuration error.\"\n}\n\n\n# func_config\n# Display the configuration for all the tags in this script.\nfunc_config ()\n{\n    re_begincf='^# ### BEGIN LIBTOOL'\n    re_endcf='^# ### END LIBTOOL'\n\n    # Default configuration.\n    $SED \"1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\\$d\" < \"$progpath\"\n\n    # Now print the configurations for the tags.\n    for tagname in $taglist; do\n      $SED -n \"/$re_begincf TAG CONFIG: $tagname\\$/,/$re_endcf TAG CONFIG: $tagname\\$/p\" < \"$progpath\"\n    done\n\n    exit $?\n}\n\n# func_features\n# Display the features supported by this script.\nfunc_features ()\n{\n    $ECHO \"host: $host\"\n    if test \"$build_libtool_libs\" = yes; then\n      $ECHO \"enable shared libraries\"\n    else\n      $ECHO \"disable shared libraries\"\n    fi\n    if test \"$build_old_libs\" = yes; then\n      $ECHO \"enable static libraries\"\n    else\n      $ECHO \"disable static libraries\"\n    fi\n\n    exit $?\n}\n\n# func_enable_tag tagname\n# Verify that TAGNAME is valid, and either flag an error and exit, or\n# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist\n# variable here.\nfunc_enable_tag ()\n{\n  # Global variable:\n  tagname=\"$1\"\n\n  re_begincf=\"^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\\$\"\n  re_endcf=\"^# ### END LIBTOOL TAG CONFIG: $tagname\\$\"\n  sed_extractcf=\"/$re_begincf/,/$re_endcf/p\"\n\n  # Validate tagname.\n  case $tagname in\n    *[!-_A-Za-z0-9,/]*)\n      func_fatal_error \"invalid tag name: $tagname\"\n      ;;\n  esac\n\n  # Don't test for the \"default\" C tag, as we know it's\n  # there but not specially marked.\n  case $tagname in\n    CC) ;;\n    *)\n      if $GREP \"$re_begincf\" \"$progpath\" >/dev/null 2>&1; then\n\ttaglist=\"$taglist $tagname\"\n\n\t# Evaluate the configuration.  Be careful to quote the path\n\t# and the sed script, to avoid splitting on whitespace, but\n\t# also don't use non-portable quotes within backquotes within\n\t# quotes we have to do it in 2 steps:\n\textractedcf=`$SED -n -e \"$sed_extractcf\" < \"$progpath\"`\n\teval \"$extractedcf\"\n      else\n\tfunc_error \"ignoring unknown tag $tagname\"\n      fi\n      ;;\n  esac\n}\n\n# Parse options once, thoroughly.  This comes as soon as possible in\n# the script to make things like `libtool --version' happen quickly.\n{\n\n  # Shorthand for --mode=foo, only valid as the first argument\n  case $1 in\n  clean|clea|cle|cl)\n    shift; set dummy --mode clean ${1+\"$@\"}; shift\n    ;;\n  compile|compil|compi|comp|com|co|c)\n    shift; set dummy --mode compile ${1+\"$@\"}; shift\n    ;;\n  execute|execut|execu|exec|exe|ex|e)\n    shift; set dummy --mode execute ${1+\"$@\"}; shift\n    ;;\n  finish|finis|fini|fin|fi|f)\n    shift; set dummy --mode finish ${1+\"$@\"}; shift\n    ;;\n  install|instal|insta|inst|ins|in|i)\n    shift; set dummy --mode install ${1+\"$@\"}; shift\n    ;;\n  link|lin|li|l)\n    shift; set dummy --mode link ${1+\"$@\"}; shift\n    ;;\n  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)\n    shift; set dummy --mode uninstall ${1+\"$@\"}; shift\n    ;;\n  esac\n\n  # Parse non-mode specific arguments:\n  while test \"$#\" -gt 0; do\n    opt=\"$1\"\n    shift\n\n    case $opt in\n      --config)\t\tfunc_config\t\t\t\t\t;;\n\n      --debug)\t\tpreserve_args=\"$preserve_args $opt\"\n\t\t\tfunc_echo \"enabling shell trace mode\"\n\t\t\topt_debug='set -x'\n\t\t\t$opt_debug\n\t\t\t;;\n\n      -dlopen)\t\ttest \"$#\" -eq 0 && func_missing_arg \"$opt\" && break\n\t\t\texecute_dlfiles=\"$execute_dlfiles $1\"\n\t\t\tshift\n\t\t\t;;\n\n      --dry-run | -n)\topt_dry_run=:\t\t\t\t\t;;\n      --features)       func_features\t\t\t\t\t;;\n      --finish)\t\tmode=\"finish\"\t\t\t\t\t;;\n\n      --mode)\t\ttest \"$#\" -eq 0 && func_missing_arg \"$opt\" && break\n\t\t\tcase $1 in\n\t\t\t  # Valid mode arguments:\n\t\t\t  clean)\t;;\n\t\t\t  compile)\t;;\n\t\t\t  execute)\t;;\n\t\t\t  finish)\t;;\n\t\t\t  install)\t;;\n\t\t\t  link)\t\t;;\n\t\t\t  relink)\t;;\n\t\t\t  uninstall)\t;;\n\n\t\t\t  # Catch anything else as an error\n\t\t\t  *) func_error \"invalid argument for $opt\"\n\t\t\t     exit_cmd=exit\n\t\t\t     break\n\t\t\t     ;;\n\t\t        esac\n\n\t\t\tmode=\"$1\"\n\t\t\tshift\n\t\t\t;;\n\n      --preserve-dup-deps)\n\t\t\topt_duplicate_deps=:\t\t\t\t;;\n\n      --quiet|--silent)\tpreserve_args=\"$preserve_args $opt\"\n\t\t\topt_silent=:\n\t\t\t;;\n\n      --verbose| -v)\tpreserve_args=\"$preserve_args $opt\"\n\t\t\topt_silent=false\n\t\t\t;;\n\n      --tag)\t\ttest \"$#\" -eq 0 && func_missing_arg \"$opt\" && break\n\t\t\tpreserve_args=\"$preserve_args $opt $1\"\n\t\t\tfunc_enable_tag \"$1\"\t# tagname is set here\n\t\t\tshift\n\t\t\t;;\n\n      # Separate optargs to long options:\n      -dlopen=*|--mode=*|--tag=*)\n\t\t\tfunc_opt_split \"$opt\"\n\t\t\tset dummy \"$func_opt_split_opt\" \"$func_opt_split_arg\" ${1+\"$@\"}\n\t\t\tshift\n\t\t\t;;\n\n      -\\?|-h)\t\tfunc_usage\t\t\t\t\t;;\n      --help)\t\topt_help=:\t\t\t\t\t;;\n      --version)\tfunc_version\t\t\t\t\t;;\n\n      -*)\t\tfunc_fatal_help \"unrecognized option \\`$opt'\"\t;;\n\n      *)\t\tnonopt=\"$opt\"\n\t\t\tbreak\n\t\t\t;;\n    esac\n  done\n\n\n  case $host in\n    *cygwin* | *mingw* | *pw32* | *cegcc*)\n      # don't eliminate duplications in $postdeps and $predeps\n      opt_duplicate_compiler_generated_deps=:\n      ;;\n    *)\n      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps\n      ;;\n  esac\n\n  # Having warned about all mis-specified options, bail out if\n  # anything was wrong.\n  $exit_cmd $EXIT_FAILURE\n}\n\n# func_check_version_match\n# Ensure that we are using m4 macros, and libtool script from the same\n# release of libtool.\nfunc_check_version_match ()\n{\n  if test \"$package_revision\" != \"$macro_revision\"; then\n    if test \"$VERSION\" != \"$macro_version\"; then\n      if test -z \"$macro_version\"; then\n        cat >&2 <<_LT_EOF\n$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the\n$progname: definition of this LT_INIT comes from an older release.\n$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION\n$progname: and run autoconf again.\n_LT_EOF\n      else\n        cat >&2 <<_LT_EOF\n$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the\n$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.\n$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION\n$progname: and run autoconf again.\n_LT_EOF\n      fi\n    else\n      cat >&2 <<_LT_EOF\n$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,\n$progname: but the definition of this LT_INIT comes from revision $macro_revision.\n$progname: You should recreate aclocal.m4 with macros from revision $package_revision\n$progname: of $PACKAGE $VERSION and run autoconf again.\n_LT_EOF\n    fi\n\n    exit $EXIT_MISMATCH\n  fi\n}\n\n\n## ----------- ##\n##    Main.    ##\n## ----------- ##\n\n$opt_help || {\n  # Sanity checks first:\n  func_check_version_match\n\n  if test \"$build_libtool_libs\" != yes && test \"$build_old_libs\" != yes; then\n    func_fatal_configuration \"not configured to build any kind of library\"\n  fi\n\n  test -z \"$mode\" && func_fatal_error \"error: you must specify a MODE.\"\n\n\n  # Darwin sucks\n  eval std_shrext=\\\"$shrext_cmds\\\"\n\n\n  # Only execute mode is allowed to have -dlopen flags.\n  if test -n \"$execute_dlfiles\" && test \"$mode\" != execute; then\n    func_error \"unrecognized option \\`-dlopen'\"\n    $ECHO \"$help\" 1>&2\n    exit $EXIT_FAILURE\n  fi\n\n  # Change the help message to a mode-specific one.\n  generic_help=\"$help\"\n  help=\"Try \\`$progname --help --mode=$mode' for more information.\"\n}\n\n\n# func_lalib_p file\n# True iff FILE is a libtool `.la' library or `.lo' object file.\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_lalib_p ()\n{\n    test -f \"$1\" &&\n      $SED -e 4q \"$1\" 2>/dev/null \\\n        | $GREP \"^# Generated by .*$PACKAGE\" > /dev/null 2>&1\n}\n\n# func_lalib_unsafe_p file\n# True iff FILE is a libtool `.la' library or `.lo' object file.\n# This function implements the same check as func_lalib_p without\n# resorting to external programs.  To this end, it redirects stdin and\n# closes it afterwards, without saving the original file descriptor.\n# As a safety measure, use it only where a negative result would be\n# fatal anyway.  Works if `file' does not exist.\nfunc_lalib_unsafe_p ()\n{\n    lalib_p=no\n    if test -f \"$1\" && test -r \"$1\" && exec 5<&0 <\"$1\"; then\n\tfor lalib_p_l in 1 2 3 4\n\tdo\n\t    read lalib_p_line\n\t    case \"$lalib_p_line\" in\n\t\t\\#\\ Generated\\ by\\ *$PACKAGE* ) lalib_p=yes; break;;\n\t    esac\n\tdone\n\texec 0<&5 5<&-\n    fi\n    test \"$lalib_p\" = yes\n}\n\n# func_ltwrapper_script_p file\n# True iff FILE is a libtool wrapper script\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_ltwrapper_script_p ()\n{\n    func_lalib_p \"$1\"\n}\n\n# func_ltwrapper_executable_p file\n# True iff FILE is a libtool wrapper executable\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_ltwrapper_executable_p ()\n{\n    func_ltwrapper_exec_suffix=\n    case $1 in\n    *.exe) ;;\n    *) func_ltwrapper_exec_suffix=.exe ;;\n    esac\n    $GREP \"$magic_exe\" \"$1$func_ltwrapper_exec_suffix\" >/dev/null 2>&1\n}\n\n# func_ltwrapper_scriptname file\n# Assumes file is an ltwrapper_executable\n# uses $file to determine the appropriate filename for a\n# temporary ltwrapper_script.\nfunc_ltwrapper_scriptname ()\n{\n    func_ltwrapper_scriptname_result=\"\"\n    if func_ltwrapper_executable_p \"$1\"; then\n\tfunc_dirname_and_basename \"$1\" \"\" \".\"\n\tfunc_stripname '' '.exe' \"$func_basename_result\"\n\tfunc_ltwrapper_scriptname_result=\"$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper\"\n    fi\n}\n\n# func_ltwrapper_p file\n# True iff FILE is a libtool wrapper script or wrapper executable\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_ltwrapper_p ()\n{\n    func_ltwrapper_script_p \"$1\" || func_ltwrapper_executable_p \"$1\"\n}\n\n\n# func_execute_cmds commands fail_cmd\n# Execute tilde-delimited COMMANDS.\n# If FAIL_CMD is given, eval that upon failure.\n# FAIL_CMD may read-access the current command in variable CMD!\nfunc_execute_cmds ()\n{\n    $opt_debug\n    save_ifs=$IFS; IFS='~'\n    for cmd in $1; do\n      IFS=$save_ifs\n      eval cmd=\\\"$cmd\\\"\n      func_show_eval \"$cmd\" \"${2-:}\"\n    done\n    IFS=$save_ifs\n}\n\n\n# func_source file\n# Source FILE, adding directory component if necessary.\n# Note that it is not necessary on cygwin/mingw to append a dot to\n# FILE even if both FILE and FILE.exe exist: automatic-append-.exe\n# behavior happens only for exec(3), not for open(2)!  Also, sourcing\n# `FILE.' does not work on cygwin managed mounts.\nfunc_source ()\n{\n    $opt_debug\n    case $1 in\n    */* | *\\\\*)\t. \"$1\" ;;\n    *)\t\t. \"./$1\" ;;\n    esac\n}\n\n\n# func_infer_tag arg\n# Infer tagged configuration to use if any are available and\n# if one wasn't chosen via the \"--tag\" command line option.\n# Only attempt this if the compiler in the base compile\n# command doesn't match the default compiler.\n# arg is usually of the form 'gcc ...'\nfunc_infer_tag ()\n{\n    $opt_debug\n    if test -n \"$available_tags\" && test -z \"$tagname\"; then\n      CC_quoted=\n      for arg in $CC; do\n        func_quote_for_eval \"$arg\"\n\tCC_quoted=\"$CC_quoted $func_quote_for_eval_result\"\n      done\n      case $@ in\n      # Blanks in the command may have been stripped by the calling shell,\n      # but not from the CC environment variable when configure was run.\n      \" $CC \"* | \"$CC \"* | \" `$ECHO $CC` \"* | \"`$ECHO $CC` \"* | \" $CC_quoted\"* | \"$CC_quoted \"* | \" `$ECHO $CC_quoted` \"* | \"`$ECHO $CC_quoted` \"*) ;;\n      # Blanks at the start of $base_compile will cause this to fail\n      # if we don't check for them as well.\n      *)\n\tfor z in $available_tags; do\n\t  if $GREP \"^# ### BEGIN LIBTOOL TAG CONFIG: $z$\" < \"$progpath\" > /dev/null; then\n\t    # Evaluate the configuration.\n\t    eval \"`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`\"\n\t    CC_quoted=\n\t    for arg in $CC; do\n\t      # Double-quote args containing other shell metacharacters.\n\t      func_quote_for_eval \"$arg\"\n\t      CC_quoted=\"$CC_quoted $func_quote_for_eval_result\"\n\t    done\n\t    case \"$@ \" in\n\t      \" $CC \"* | \"$CC \"* | \" `$ECHO $CC` \"* | \"`$ECHO $CC` \"* | \" $CC_quoted\"* | \"$CC_quoted \"* | \" `$ECHO $CC_quoted` \"* | \"`$ECHO $CC_quoted` \"*)\n\t      # The compiler in the base compile command matches\n\t      # the one in the tagged configuration.\n\t      # Assume this is the tagged configuration we want.\n\t      tagname=$z\n\t      break\n\t      ;;\n\t    esac\n\t  fi\n\tdone\n\t# If $tagname still isn't set, then no tagged configuration\n\t# was found and let the user know that the \"--tag\" command\n\t# line option must be used.\n\tif test -z \"$tagname\"; then\n\t  func_echo \"unable to infer tagged configuration\"\n\t  func_fatal_error \"specify a tag with \\`--tag'\"\n#\telse\n#\t  func_verbose \"using $tagname tagged configuration\"\n\tfi\n\t;;\n      esac\n    fi\n}\n\n\n\n# func_write_libtool_object output_name pic_name nonpic_name\n# Create a libtool object file (analogous to a \".la\" file),\n# but don't create it if we're doing a dry run.\nfunc_write_libtool_object ()\n{\n    write_libobj=${1}\n    if test \"$build_libtool_libs\" = yes; then\n      write_lobj=\\'${2}\\'\n    else\n      write_lobj=none\n    fi\n\n    if test \"$build_old_libs\" = yes; then\n      write_oldobj=\\'${3}\\'\n    else\n      write_oldobj=none\n    fi\n\n    $opt_dry_run || {\n      cat >${write_libobj}T <<EOF\n# $write_libobj - a libtool object file\n# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n#\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# Name of the PIC object.\npic_object=$write_lobj\n\n# Name of the non-PIC object\nnon_pic_object=$write_oldobj\n\nEOF\n      $MV \"${write_libobj}T\" \"${write_libobj}\"\n    }\n}\n\n# func_mode_compile arg...\nfunc_mode_compile ()\n{\n    $opt_debug\n    # Get the compilation command and the source file.\n    base_compile=\n    srcfile=\"$nonopt\"  #  always keep a non-empty value in \"srcfile\"\n    suppress_opt=yes\n    suppress_output=\n    arg_mode=normal\n    libobj=\n    later=\n    pie_flag=\n\n    for arg\n    do\n      case $arg_mode in\n      arg  )\n\t# do not \"continue\".  Instead, add this to base_compile\n\tlastarg=\"$arg\"\n\targ_mode=normal\n\t;;\n\n      target )\n\tlibobj=\"$arg\"\n\targ_mode=normal\n\tcontinue\n\t;;\n\n      normal )\n\t# Accept any command-line options.\n\tcase $arg in\n\t-o)\n\t  test -n \"$libobj\" && \\\n\t    func_fatal_error \"you cannot specify \\`-o' more than once\"\n\t  arg_mode=target\n\t  continue\n\t  ;;\n\n\t-pie | -fpie | -fPIE)\n          pie_flag=\"$pie_flag $arg\"\n\t  continue\n\t  ;;\n\n\t-shared | -static | -prefer-pic | -prefer-non-pic)\n\t  later=\"$later $arg\"\n\t  continue\n\t  ;;\n\n\t-no-suppress)\n\t  suppress_opt=no\n\t  continue\n\t  ;;\n\n\t-Xcompiler)\n\t  arg_mode=arg  #  the next one goes into the \"base_compile\" arg list\n\t  continue      #  The current \"srcfile\" will either be retained or\n\t  ;;            #  replaced later.  I would guess that would be a bug.\n\n\t-Wc,*)\n\t  func_stripname '-Wc,' '' \"$arg\"\n\t  args=$func_stripname_result\n\t  lastarg=\n\t  save_ifs=\"$IFS\"; IFS=','\n\t  for arg in $args; do\n\t    IFS=\"$save_ifs\"\n\t    func_quote_for_eval \"$arg\"\n\t    lastarg=\"$lastarg $func_quote_for_eval_result\"\n\t  done\n\t  IFS=\"$save_ifs\"\n\t  func_stripname ' ' '' \"$lastarg\"\n\t  lastarg=$func_stripname_result\n\n\t  # Add the arguments to base_compile.\n\t  base_compile=\"$base_compile $lastarg\"\n\t  continue\n\t  ;;\n\n\t*)\n\t  # Accept the current argument as the source file.\n\t  # The previous \"srcfile\" becomes the current argument.\n\t  #\n\t  lastarg=\"$srcfile\"\n\t  srcfile=\"$arg\"\n\t  ;;\n\tesac  #  case $arg\n\t;;\n      esac    #  case $arg_mode\n\n      # Aesthetically quote the previous argument.\n      func_quote_for_eval \"$lastarg\"\n      base_compile=\"$base_compile $func_quote_for_eval_result\"\n    done # for arg\n\n    case $arg_mode in\n    arg)\n      func_fatal_error \"you must specify an argument for -Xcompile\"\n      ;;\n    target)\n      func_fatal_error \"you must specify a target with \\`-o'\"\n      ;;\n    *)\n      # Get the name of the library object.\n      test -z \"$libobj\" && {\n\tfunc_basename \"$srcfile\"\n\tlibobj=\"$func_basename_result\"\n      }\n      ;;\n    esac\n\n    # Recognize several different file suffixes.\n    # If the user specifies -o file.o, it is replaced with file.lo\n    case $libobj in\n    *.[cCFSifmso] | \\\n    *.ada | *.adb | *.ads | *.asm | \\\n    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \\\n    *.[fF][09]? | *.for | *.java | *.obj | *.sx)\n      func_xform \"$libobj\"\n      libobj=$func_xform_result\n      ;;\n    esac\n\n    case $libobj in\n    *.lo) func_lo2o \"$libobj\"; obj=$func_lo2o_result ;;\n    *)\n      func_fatal_error \"cannot determine name of library object from \\`$libobj'\"\n      ;;\n    esac\n\n    func_infer_tag $base_compile\n\n    for arg in $later; do\n      case $arg in\n      -shared)\n\ttest \"$build_libtool_libs\" != yes && \\\n\t  func_fatal_configuration \"can not build a shared library\"\n\tbuild_old_libs=no\n\tcontinue\n\t;;\n\n      -static)\n\tbuild_libtool_libs=no\n\tbuild_old_libs=yes\n\tcontinue\n\t;;\n\n      -prefer-pic)\n\tpic_mode=yes\n\tcontinue\n\t;;\n\n      -prefer-non-pic)\n\tpic_mode=no\n\tcontinue\n\t;;\n      esac\n    done\n\n    func_quote_for_eval \"$libobj\"\n    test \"X$libobj\" != \"X$func_quote_for_eval_result\" \\\n      && $ECHO \"X$libobj\" | $GREP '[]~#^*{};<>?\"'\"'\"'\t &()|`$[]' \\\n      && func_warning \"libobj name \\`$libobj' may not contain shell special characters.\"\n    func_dirname_and_basename \"$obj\" \"/\" \"\"\n    objname=\"$func_basename_result\"\n    xdir=\"$func_dirname_result\"\n    lobj=${xdir}$objdir/$objname\n\n    test -z \"$base_compile\" && \\\n      func_fatal_help \"you must specify a compilation command\"\n\n    # Delete any leftover library objects.\n    if test \"$build_old_libs\" = yes; then\n      removelist=\"$obj $lobj $libobj ${libobj}T\"\n    else\n      removelist=\"$lobj $libobj ${libobj}T\"\n    fi\n\n    # On Cygwin there's no \"real\" PIC flag so we must build both object types\n    case $host_os in\n    cygwin* | mingw* | pw32* | os2* | cegcc*)\n      pic_mode=default\n      ;;\n    esac\n    if test \"$pic_mode\" = no && test \"$deplibs_check_method\" != pass_all; then\n      # non-PIC code in shared libraries is not supported\n      pic_mode=default\n    fi\n\n    # Calculate the filename of the output object if compiler does\n    # not support -o with -c\n    if test \"$compiler_c_o\" = no; then\n      output_obj=`$ECHO \"X$srcfile\" | $Xsed -e 's%^.*/%%' -e 's%\\.[^.]*$%%'`.${objext}\n      lockfile=\"$output_obj.lock\"\n    else\n      output_obj=\n      need_locks=no\n      lockfile=\n    fi\n\n    # Lock this critical section if it is needed\n    # We use this script file to make the link, it avoids creating a new file\n    if test \"$need_locks\" = yes; then\n      until $opt_dry_run || ln \"$progpath\" \"$lockfile\" 2>/dev/null; do\n\tfunc_echo \"Waiting for $lockfile to be removed\"\n\tsleep 2\n      done\n    elif test \"$need_locks\" = warn; then\n      if test -f \"$lockfile\"; then\n\t$ECHO \"\\\n*** ERROR, $lockfile exists and contains:\n`cat $lockfile 2>/dev/null`\n\nThis indicates that another process is trying to use the same\ntemporary object file, and libtool could not work around it because\nyour compiler does not support \\`-c' and \\`-o' together.  If you\nrepeat this compilation, it may succeed, by chance, but you had better\navoid parallel builds (make -j) in this platform, or get a better\ncompiler.\"\n\n\t$opt_dry_run || $RM $removelist\n\texit $EXIT_FAILURE\n      fi\n      removelist=\"$removelist $output_obj\"\n      $ECHO \"$srcfile\" > \"$lockfile\"\n    fi\n\n    $opt_dry_run || $RM $removelist\n    removelist=\"$removelist $lockfile\"\n    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15\n\n    if test -n \"$fix_srcfile_path\"; then\n      eval srcfile=\\\"$fix_srcfile_path\\\"\n    fi\n    func_quote_for_eval \"$srcfile\"\n    qsrcfile=$func_quote_for_eval_result\n\n    # Only build a PIC object if we are building libtool libraries.\n    if test \"$build_libtool_libs\" = yes; then\n      # Without this assignment, base_compile gets emptied.\n      fbsd_hideous_sh_bug=$base_compile\n\n      if test \"$pic_mode\" != no; then\n\tcommand=\"$base_compile $qsrcfile $pic_flag\"\n      else\n\t# Don't build PIC code\n\tcommand=\"$base_compile $qsrcfile\"\n      fi\n\n      func_mkdir_p \"$xdir$objdir\"\n\n      if test -z \"$output_obj\"; then\n\t# Place PIC objects in $objdir\n\tcommand=\"$command -o $lobj\"\n      fi\n\n      func_show_eval_locale \"$command\"\t\\\n          'test -n \"$output_obj\" && $RM $removelist; exit $EXIT_FAILURE'\n\n      if test \"$need_locks\" = warn &&\n\t test \"X`cat $lockfile 2>/dev/null`\" != \"X$srcfile\"; then\n\t$ECHO \"\\\n*** ERROR, $lockfile contains:\n`cat $lockfile 2>/dev/null`\n\nbut it should contain:\n$srcfile\n\nThis indicates that another process is trying to use the same\ntemporary object file, and libtool could not work around it because\nyour compiler does not support \\`-c' and \\`-o' together.  If you\nrepeat this compilation, it may succeed, by chance, but you had better\navoid parallel builds (make -j) in this platform, or get a better\ncompiler.\"\n\n\t$opt_dry_run || $RM $removelist\n\texit $EXIT_FAILURE\n      fi\n\n      # Just move the object if needed, then go on to compile the next one\n      if test -n \"$output_obj\" && test \"X$output_obj\" != \"X$lobj\"; then\n\tfunc_show_eval '$MV \"$output_obj\" \"$lobj\"' \\\n\t  'error=$?; $opt_dry_run || $RM $removelist; exit $error'\n      fi\n\n      # Allow error messages only from the first compilation.\n      if test \"$suppress_opt\" = yes; then\n\tsuppress_output=' >/dev/null 2>&1'\n      fi\n    fi\n\n    # Only build a position-dependent object if we build old libraries.\n    if test \"$build_old_libs\" = yes; then\n      if test \"$pic_mode\" != yes; then\n\t# Don't build PIC code\n\tcommand=\"$base_compile $qsrcfile$pie_flag\"\n      else\n\tcommand=\"$base_compile $qsrcfile $pic_flag\"\n      fi\n      if test \"$compiler_c_o\" = yes; then\n\tcommand=\"$command -o $obj\"\n      fi\n\n      # Suppress compiler output if we already did a PIC compilation.\n      command=\"$command$suppress_output\"\n      func_show_eval_locale \"$command\" \\\n        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'\n\n      if test \"$need_locks\" = warn &&\n\t test \"X`cat $lockfile 2>/dev/null`\" != \"X$srcfile\"; then\n\t$ECHO \"\\\n*** ERROR, $lockfile contains:\n`cat $lockfile 2>/dev/null`\n\nbut it should contain:\n$srcfile\n\nThis indicates that another process is trying to use the same\ntemporary object file, and libtool could not work around it because\nyour compiler does not support \\`-c' and \\`-o' together.  If you\nrepeat this compilation, it may succeed, by chance, but you had better\navoid parallel builds (make -j) in this platform, or get a better\ncompiler.\"\n\n\t$opt_dry_run || $RM $removelist\n\texit $EXIT_FAILURE\n      fi\n\n      # Just move the object if needed\n      if test -n \"$output_obj\" && test \"X$output_obj\" != \"X$obj\"; then\n\tfunc_show_eval '$MV \"$output_obj\" \"$obj\"' \\\n\t  'error=$?; $opt_dry_run || $RM $removelist; exit $error'\n      fi\n    fi\n\n    $opt_dry_run || {\n      func_write_libtool_object \"$libobj\" \"$objdir/$objname\" \"$objname\"\n\n      # Unlock the critical section if it was locked\n      if test \"$need_locks\" != no; then\n\tremovelist=$lockfile\n        $RM \"$lockfile\"\n      fi\n    }\n\n    exit $EXIT_SUCCESS\n}\n\n$opt_help || {\ntest \"$mode\" = compile && func_mode_compile ${1+\"$@\"}\n}\n\nfunc_mode_help ()\n{\n    # We need to display help for each of the modes.\n    case $mode in\n      \"\")\n        # Generic help is extracted from the usage comments\n        # at the start of this file.\n        func_help\n        ;;\n\n      clean)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...\n\nRemove files from the build directory.\n\nRM is the name of the program to use to delete files associated with each FILE\n(typically \\`/bin/rm').  RM-OPTIONS are options (such as \\`-f') to be passed\nto RM.\n\nIf FILE is a libtool library, object or program, all the files associated\nwith it are deleted. Otherwise, only FILE itself is deleted using RM.\"\n        ;;\n\n      compile)\n      $ECHO \\\n\"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE\n\nCompile a source file into a libtool library object.\n\nThis mode accepts the following additional options:\n\n  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE\n  -no-suppress      do not suppress compiler output for multiple passes\n  -prefer-pic       try to building PIC objects only\n  -prefer-non-pic   try to building non-PIC objects only\n  -shared           do not build a \\`.o' file suitable for static linking\n  -static           only build a \\`.o' file suitable for static linking\n\nCOMPILE-COMMAND is a command to be used in creating a \\`standard' object file\nfrom the given SOURCEFILE.\n\nThe output file name is determined by removing the directory component from\nSOURCEFILE, then substituting the C source code suffix \\`.c' with the\nlibrary object suffix, \\`.lo'.\"\n        ;;\n\n      execute)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...\n\nAutomatically set library path, then run a program.\n\nThis mode accepts the following additional options:\n\n  -dlopen FILE      add the directory containing FILE to the library path\n\nThis mode sets the library path environment variable according to \\`-dlopen'\nflags.\n\nIf any of the ARGS are libtool executable wrappers, then they are translated\ninto their corresponding uninstalled binary, and any of their required library\ndirectories are added to the library path.\n\nThen, COMMAND is executed, with ARGS as arguments.\"\n        ;;\n\n      finish)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...\n\nComplete the installation of libtool libraries.\n\nEach LIBDIR is a directory that contains libtool libraries.\n\nThe commands that this mode executes may require superuser privileges.  Use\nthe \\`--dry-run' option if you just want to see what would be executed.\"\n        ;;\n\n      install)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...\n\nInstall executables or libraries.\n\nINSTALL-COMMAND is the installation command.  The first component should be\neither the \\`install' or \\`cp' program.\n\nThe following components of INSTALL-COMMAND are treated specially:\n\n  -inst-prefix PREFIX-DIR  Use PREFIX-DIR as a staging area for installation\n\nThe rest of the components are interpreted as arguments to that command (only\nBSD-compatible install options are recognized).\"\n        ;;\n\n      link)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...\n\nLink object files or libraries together to form another library, or to\ncreate an executable program.\n\nLINK-COMMAND is a command using the C compiler that you would use to create\na program from several object files.\n\nThe following components of LINK-COMMAND are treated specially:\n\n  -all-static       do not do any dynamic linking at all\n  -avoid-version    do not add a version suffix if possible\n  -dlopen FILE      \\`-dlpreopen' FILE if it cannot be dlopened at runtime\n  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols\n  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)\n  -export-symbols SYMFILE\n                    try to export only the symbols listed in SYMFILE\n  -export-symbols-regex REGEX\n                    try to export only the symbols matching REGEX\n  -LLIBDIR          search LIBDIR for required installed libraries\n  -lNAME            OUTPUT-FILE requires the installed library libNAME\n  -module           build a library that can dlopened\n  -no-fast-install  disable the fast-install mode\n  -no-install       link a not-installable executable\n  -no-undefined     declare that a library does not refer to external symbols\n  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects\n  -objectlist FILE  Use a list of object files found in FILE to specify objects\n  -precious-files-regex REGEX\n                    don't remove output files matching REGEX\n  -release RELEASE  specify package release information\n  -rpath LIBDIR     the created library will eventually be installed in LIBDIR\n  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries\n  -shared           only do dynamic linking of libtool libraries\n  -shrext SUFFIX    override the standard shared library file extension\n  -static           do not do any dynamic linking of uninstalled libtool libraries\n  -static-libtool-libs\n                    do not do any dynamic linking of libtool libraries\n  -version-info CURRENT[:REVISION[:AGE]]\n                    specify library version info [each variable defaults to 0]\n  -weak LIBNAME     declare that the target provides the LIBNAME interface\n\nAll other options (arguments beginning with \\`-') are ignored.\n\nEvery other argument is treated as a filename.  Files ending in \\`.la' are\ntreated as uninstalled libtool libraries, other files are standard or library\nobject files.\n\nIf the OUTPUT-FILE ends in \\`.la', then a libtool library is created,\nonly library objects (\\`.lo' files) may be specified, and \\`-rpath' is\nrequired, except when creating a convenience library.\n\nIf OUTPUT-FILE ends in \\`.a' or \\`.lib', then a standard library is created\nusing \\`ar' and \\`ranlib', or on Windows using \\`lib'.\n\nIf OUTPUT-FILE ends in \\`.lo' or \\`.${objext}', then a reloadable object file\nis created, otherwise an executable program is created.\"\n        ;;\n\n      uninstall)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...\n\nRemove libraries from an installation directory.\n\nRM is the name of the program to use to delete files associated with each FILE\n(typically \\`/bin/rm').  RM-OPTIONS are options (such as \\`-f') to be passed\nto RM.\n\nIf FILE is a libtool library, all the files associated with it are deleted.\nOtherwise, only FILE itself is deleted using RM.\"\n        ;;\n\n      *)\n        func_fatal_help \"invalid operation mode \\`$mode'\"\n        ;;\n    esac\n\n    $ECHO\n    $ECHO \"Try \\`$progname --help' for more information about other modes.\"\n\n    exit $?\n}\n\n  # Now that we've collected a possible --mode arg, show help if necessary\n  $opt_help && func_mode_help\n\n\n# func_mode_execute arg...\nfunc_mode_execute ()\n{\n    $opt_debug\n    # The first argument is the command name.\n    cmd=\"$nonopt\"\n    test -z \"$cmd\" && \\\n      func_fatal_help \"you must specify a COMMAND\"\n\n    # Handle -dlopen flags immediately.\n    for file in $execute_dlfiles; do\n      test -f \"$file\" \\\n\t|| func_fatal_help \"\\`$file' is not a file\"\n\n      dir=\n      case $file in\n      *.la)\n\t# Check to see that this really is a libtool archive.\n\tfunc_lalib_unsafe_p \"$file\" \\\n\t  || func_fatal_help \"\\`$lib' is not a valid libtool archive\"\n\n\t# Read the libtool library.\n\tdlname=\n\tlibrary_names=\n\tfunc_source \"$file\"\n\n\t# Skip this library if it cannot be dlopened.\n\tif test -z \"$dlname\"; then\n\t  # Warn if it was a shared library.\n\t  test -n \"$library_names\" && \\\n\t    func_warning \"\\`$file' was not linked with \\`-export-dynamic'\"\n\t  continue\n\tfi\n\n\tfunc_dirname \"$file\" \"\" \".\"\n\tdir=\"$func_dirname_result\"\n\n\tif test -f \"$dir/$objdir/$dlname\"; then\n\t  dir=\"$dir/$objdir\"\n\telse\n\t  if test ! -f \"$dir/$dlname\"; then\n\t    func_fatal_error \"cannot find \\`$dlname' in \\`$dir' or \\`$dir/$objdir'\"\n\t  fi\n\tfi\n\t;;\n\n      *.lo)\n\t# Just add the directory containing the .lo file.\n\tfunc_dirname \"$file\" \"\" \".\"\n\tdir=\"$func_dirname_result\"\n\t;;\n\n      *)\n\tfunc_warning \"\\`-dlopen' is ignored for non-libtool libraries and objects\"\n\tcontinue\n\t;;\n      esac\n\n      # Get the absolute pathname.\n      absdir=`cd \"$dir\" && pwd`\n      test -n \"$absdir\" && dir=\"$absdir\"\n\n      # Now add the directory to shlibpath_var.\n      if eval \"test -z \\\"\\$$shlibpath_var\\\"\"; then\n\teval \"$shlibpath_var=\\\"\\$dir\\\"\"\n      else\n\teval \"$shlibpath_var=\\\"\\$dir:\\$$shlibpath_var\\\"\"\n      fi\n    done\n\n    # This variable tells wrapper scripts just to set shlibpath_var\n    # rather than running their programs.\n    libtool_execute_magic=\"$magic\"\n\n    # Check if any of the arguments is a wrapper script.\n    args=\n    for file\n    do\n      case $file in\n      -*) ;;\n      *)\n\t# Do a test to see if this is really a libtool program.\n\tif func_ltwrapper_script_p \"$file\"; then\n\t  func_source \"$file\"\n\t  # Transform arg to wrapped name.\n\t  file=\"$progdir/$program\"\n\telif func_ltwrapper_executable_p \"$file\"; then\n\t  func_ltwrapper_scriptname \"$file\"\n\t  func_source \"$func_ltwrapper_scriptname_result\"\n\t  # Transform arg to wrapped name.\n\t  file=\"$progdir/$program\"\n\tfi\n\t;;\n      esac\n      # Quote arguments (to preserve shell metacharacters).\n      func_quote_for_eval \"$file\"\n      args=\"$args $func_quote_for_eval_result\"\n    done\n\n    if test \"X$opt_dry_run\" = Xfalse; then\n      if test -n \"$shlibpath_var\"; then\n\t# Export the shlibpath_var.\n\teval \"export $shlibpath_var\"\n      fi\n\n      # Restore saved environment variables\n      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES\n      do\n\teval \"if test \\\"\\${save_$lt_var+set}\\\" = set; then\n                $lt_var=\\$save_$lt_var; export $lt_var\n\t      else\n\t\t$lt_unset $lt_var\n\t      fi\"\n      done\n\n      # Now prepare to actually exec the command.\n      exec_cmd=\"\\$cmd$args\"\n    else\n      # Display what would be done.\n      if test -n \"$shlibpath_var\"; then\n\teval \"\\$ECHO \\\"\\$shlibpath_var=\\$$shlibpath_var\\\"\"\n\t$ECHO \"export $shlibpath_var\"\n      fi\n      $ECHO \"$cmd$args\"\n      exit $EXIT_SUCCESS\n    fi\n}\n\ntest \"$mode\" = execute && func_mode_execute ${1+\"$@\"}\n\n\n# func_mode_finish arg...\nfunc_mode_finish ()\n{\n    $opt_debug\n    libdirs=\"$nonopt\"\n    admincmds=\n\n    if test -n \"$finish_cmds$finish_eval\" && test -n \"$libdirs\"; then\n      for dir\n      do\n\tlibdirs=\"$libdirs $dir\"\n      done\n\n      for libdir in $libdirs; do\n\tif test -n \"$finish_cmds\"; then\n\t  # Do each command in the finish commands.\n\t  func_execute_cmds \"$finish_cmds\" 'admincmds=\"$admincmds\n'\"$cmd\"'\"'\n\tfi\n\tif test -n \"$finish_eval\"; then\n\t  # Do the single finish_eval.\n\t  eval cmds=\\\"$finish_eval\\\"\n\t  $opt_dry_run || eval \"$cmds\" || admincmds=\"$admincmds\n       $cmds\"\n\tfi\n      done\n    fi\n\n    # Exit here if they wanted silent mode.\n    $opt_silent && exit $EXIT_SUCCESS\n\n    $ECHO \"X----------------------------------------------------------------------\" | $Xsed\n    $ECHO \"Libraries have been installed in:\"\n    for libdir in $libdirs; do\n      $ECHO \"   $libdir\"\n    done\n    $ECHO\n    $ECHO \"If you ever happen to want to link against installed libraries\"\n    $ECHO \"in a given directory, LIBDIR, you must either use libtool, and\"\n    $ECHO \"specify the full pathname of the library, or use the \\`-LLIBDIR'\"\n    $ECHO \"flag during linking and do at least one of the following:\"\n    if test -n \"$shlibpath_var\"; then\n      $ECHO \"   - add LIBDIR to the \\`$shlibpath_var' environment variable\"\n      $ECHO \"     during execution\"\n    fi\n    if test -n \"$runpath_var\"; then\n      $ECHO \"   - add LIBDIR to the \\`$runpath_var' environment variable\"\n      $ECHO \"     during linking\"\n    fi\n    if test -n \"$hardcode_libdir_flag_spec\"; then\n      libdir=LIBDIR\n      eval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\n      $ECHO \"   - use the \\`$flag' linker flag\"\n    fi\n    if test -n \"$admincmds\"; then\n      $ECHO \"   - have your system administrator run these commands:$admincmds\"\n    fi\n    if test -f /etc/ld.so.conf; then\n      $ECHO \"   - have your system administrator add LIBDIR to \\`/etc/ld.so.conf'\"\n    fi\n    $ECHO\n\n    $ECHO \"See any operating system documentation about shared libraries for\"\n    case $host in\n      solaris2.[6789]|solaris2.1[0-9])\n        $ECHO \"more information, such as the ld(1), crle(1) and ld.so(8) manual\"\n\t$ECHO \"pages.\"\n\t;;\n      *)\n        $ECHO \"more information, such as the ld(1) and ld.so(8) manual pages.\"\n        ;;\n    esac\n    $ECHO \"X----------------------------------------------------------------------\" | $Xsed\n    exit $EXIT_SUCCESS\n}\n\ntest \"$mode\" = finish && func_mode_finish ${1+\"$@\"}\n\n\n# func_mode_install arg...\nfunc_mode_install ()\n{\n    $opt_debug\n    # There may be an optional sh(1) argument at the beginning of\n    # install_prog (especially on Windows NT).\n    if test \"$nonopt\" = \"$SHELL\" || test \"$nonopt\" = /bin/sh ||\n       # Allow the use of GNU shtool's install command.\n       $ECHO \"X$nonopt\" | $GREP shtool >/dev/null; then\n      # Aesthetically quote it.\n      func_quote_for_eval \"$nonopt\"\n      install_prog=\"$func_quote_for_eval_result \"\n      arg=$1\n      shift\n    else\n      install_prog=\n      arg=$nonopt\n    fi\n\n    # The real first argument should be the name of the installation program.\n    # Aesthetically quote it.\n    func_quote_for_eval \"$arg\"\n    install_prog=\"$install_prog$func_quote_for_eval_result\"\n\n    # We need to accept at least all the BSD install flags.\n    dest=\n    files=\n    opts=\n    prev=\n    install_type=\n    isdir=no\n    stripme=\n    for arg\n    do\n      if test -n \"$dest\"; then\n\tfiles=\"$files $dest\"\n\tdest=$arg\n\tcontinue\n      fi\n\n      case $arg in\n      -d) isdir=yes ;;\n      -f)\n\tcase \" $install_prog \" in\n\t*[\\\\\\ /]cp\\ *) ;;\n\t*) prev=$arg ;;\n\tesac\n\t;;\n      -g | -m | -o)\n\tprev=$arg\n\t;;\n      -s)\n\tstripme=\" -s\"\n\tcontinue\n\t;;\n      -*)\n\t;;\n      *)\n\t# If the previous option needed an argument, then skip it.\n\tif test -n \"$prev\"; then\n\t  prev=\n\telse\n\t  dest=$arg\n\t  continue\n\tfi\n\t;;\n      esac\n\n      # Aesthetically quote the argument.\n      func_quote_for_eval \"$arg\"\n      install_prog=\"$install_prog $func_quote_for_eval_result\"\n    done\n\n    test -z \"$install_prog\" && \\\n      func_fatal_help \"you must specify an install program\"\n\n    test -n \"$prev\" && \\\n      func_fatal_help \"the \\`$prev' option requires an argument\"\n\n    if test -z \"$files\"; then\n      if test -z \"$dest\"; then\n\tfunc_fatal_help \"no file or destination specified\"\n      else\n\tfunc_fatal_help \"you must specify a destination\"\n      fi\n    fi\n\n    # Strip any trailing slash from the destination.\n    func_stripname '' '/' \"$dest\"\n    dest=$func_stripname_result\n\n    # Check to see that the destination is a directory.\n    test -d \"$dest\" && isdir=yes\n    if test \"$isdir\" = yes; then\n      destdir=\"$dest\"\n      destname=\n    else\n      func_dirname_and_basename \"$dest\" \"\" \".\"\n      destdir=\"$func_dirname_result\"\n      destname=\"$func_basename_result\"\n\n      # Not a directory, so check to see that there is only one file specified.\n      set dummy $files; shift\n      test \"$#\" -gt 1 && \\\n\tfunc_fatal_help \"\\`$dest' is not a directory\"\n    fi\n    case $destdir in\n    [\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n    *)\n      for file in $files; do\n\tcase $file in\n\t*.lo) ;;\n\t*)\n\t  func_fatal_help \"\\`$destdir' must be an absolute directory name\"\n\t  ;;\n\tesac\n      done\n      ;;\n    esac\n\n    # This variable tells wrapper scripts just to set variables rather\n    # than running their programs.\n    libtool_install_magic=\"$magic\"\n\n    staticlibs=\n    future_libdirs=\n    current_libdirs=\n    for file in $files; do\n\n      # Do each installation.\n      case $file in\n      *.$libext)\n\t# Do the static libraries later.\n\tstaticlibs=\"$staticlibs $file\"\n\t;;\n\n      *.la)\n\t# Check to see that this really is a libtool archive.\n\tfunc_lalib_unsafe_p \"$file\" \\\n\t  || func_fatal_help \"\\`$file' is not a valid libtool archive\"\n\n\tlibrary_names=\n\told_library=\n\trelink_command=\n\tfunc_source \"$file\"\n\n\t# Add the libdir to current_libdirs if it is the destination.\n\tif test \"X$destdir\" = \"X$libdir\"; then\n\t  case \"$current_libdirs \" in\n\t  *\" $libdir \"*) ;;\n\t  *) current_libdirs=\"$current_libdirs $libdir\" ;;\n\t  esac\n\telse\n\t  # Note the libdir as a future libdir.\n\t  case \"$future_libdirs \" in\n\t  *\" $libdir \"*) ;;\n\t  *) future_libdirs=\"$future_libdirs $libdir\" ;;\n\t  esac\n\tfi\n\n\tfunc_dirname \"$file\" \"/\" \"\"\n\tdir=\"$func_dirname_result\"\n\tdir=\"$dir$objdir\"\n\n\tif test -n \"$relink_command\"; then\n\t  # Determine the prefix the user has applied to our future dir.\n\t  inst_prefix_dir=`$ECHO \"X$destdir\" | $Xsed -e \"s%$libdir\\$%%\"`\n\n\t  # Don't allow the user to place us outside of our expected\n\t  # location b/c this prevents finding dependent libraries that\n\t  # are installed to the same prefix.\n\t  # At present, this check doesn't affect windows .dll's that\n\t  # are installed into $libdir/../bin (currently, that works fine)\n\t  # but it's something to keep an eye on.\n\t  test \"$inst_prefix_dir\" = \"$destdir\" && \\\n\t    func_fatal_error \"error: cannot install \\`$file' to a directory not ending in $libdir\"\n\n\t  if test -n \"$inst_prefix_dir\"; then\n\t    # Stick the inst_prefix_dir data into the link command.\n\t    relink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%\"`\n\t  else\n\t    relink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"s%@inst_prefix_dir@%%\"`\n\t  fi\n\n\t  func_warning \"relinking \\`$file'\"\n\t  func_show_eval \"$relink_command\" \\\n\t    'func_fatal_error \"error: relink \\`$file'\\'' with the above command before installing it\"'\n\tfi\n\n\t# See the names of the shared library.\n\tset dummy $library_names; shift\n\tif test -n \"$1\"; then\n\t  realname=\"$1\"\n\t  shift\n\n\t  srcname=\"$realname\"\n\t  test -n \"$relink_command\" && srcname=\"$realname\"T\n\n\t  # Install the shared library and build the symlinks.\n\t  func_show_eval \"$install_prog $dir/$srcname $destdir/$realname\" \\\n\t      'exit $?'\n\t  tstripme=\"$stripme\"\n\t  case $host_os in\n\t  cygwin* | mingw* | pw32* | cegcc*)\n\t    case $realname in\n\t    *.dll.a)\n\t      tstripme=\"\"\n\t      ;;\n\t    esac\n\t    ;;\n\t  esac\n\t  if test -n \"$tstripme\" && test -n \"$striplib\"; then\n\t    func_show_eval \"$striplib $destdir/$realname\" 'exit $?'\n\t  fi\n\n\t  if test \"$#\" -gt 0; then\n\t    # Delete the old symlinks, and create new ones.\n\t    # Try `ln -sf' first, because the `ln' binary might depend on\n\t    # the symlink we replace!  Solaris /bin/ln does not understand -f,\n\t    # so we also need to try rm && ln -s.\n\t    for linkname\n\t    do\n\t      test \"$linkname\" != \"$realname\" \\\n\t\t&& func_show_eval \"(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })\"\n\t    done\n\t  fi\n\n\t  # Do each command in the postinstall commands.\n\t  lib=\"$destdir/$realname\"\n\t  func_execute_cmds \"$postinstall_cmds\" 'exit $?'\n\tfi\n\n\t# Install the pseudo-library for information purposes.\n\tfunc_basename \"$file\"\n\tname=\"$func_basename_result\"\n\tinstname=\"$dir/$name\"i\n\tfunc_show_eval \"$install_prog $instname $destdir/$name\" 'exit $?'\n\n\t# Maybe install the static library, too.\n\ttest -n \"$old_library\" && staticlibs=\"$staticlibs $dir/$old_library\"\n\t;;\n\n      *.lo)\n\t# Install (i.e. copy) a libtool object.\n\n\t# Figure out destination file name, if it wasn't already specified.\n\tif test -n \"$destname\"; then\n\t  destfile=\"$destdir/$destname\"\n\telse\n\t  func_basename \"$file\"\n\t  destfile=\"$func_basename_result\"\n\t  destfile=\"$destdir/$destfile\"\n\tfi\n\n\t# Deduce the name of the destination old-style object file.\n\tcase $destfile in\n\t*.lo)\n\t  func_lo2o \"$destfile\"\n\t  staticdest=$func_lo2o_result\n\t  ;;\n\t*.$objext)\n\t  staticdest=\"$destfile\"\n\t  destfile=\n\t  ;;\n\t*)\n\t  func_fatal_help \"cannot copy a libtool object to \\`$destfile'\"\n\t  ;;\n\tesac\n\n\t# Install the libtool object if requested.\n\ttest -n \"$destfile\" && \\\n\t  func_show_eval \"$install_prog $file $destfile\" 'exit $?'\n\n\t# Install the old object if enabled.\n\tif test \"$build_old_libs\" = yes; then\n\t  # Deduce the name of the old-style object file.\n\t  func_lo2o \"$file\"\n\t  staticobj=$func_lo2o_result\n\t  func_show_eval \"$install_prog \\$staticobj \\$staticdest\" 'exit $?'\n\tfi\n\texit $EXIT_SUCCESS\n\t;;\n\n      *)\n\t# Figure out destination file name, if it wasn't already specified.\n\tif test -n \"$destname\"; then\n\t  destfile=\"$destdir/$destname\"\n\telse\n\t  func_basename \"$file\"\n\t  destfile=\"$func_basename_result\"\n\t  destfile=\"$destdir/$destfile\"\n\tfi\n\n\t# If the file is missing, and there is a .exe on the end, strip it\n\t# because it is most likely a libtool script we actually want to\n\t# install\n\tstripped_ext=\"\"\n\tcase $file in\n\t  *.exe)\n\t    if test ! -f \"$file\"; then\n\t      func_stripname '' '.exe' \"$file\"\n\t      file=$func_stripname_result\n\t      stripped_ext=\".exe\"\n\t    fi\n\t    ;;\n\tesac\n\n\t# Do a test to see if this is really a libtool program.\n\tcase $host in\n\t*cygwin* | *mingw*)\n\t    if func_ltwrapper_executable_p \"$file\"; then\n\t      func_ltwrapper_scriptname \"$file\"\n\t      wrapper=$func_ltwrapper_scriptname_result\n\t    else\n\t      func_stripname '' '.exe' \"$file\"\n\t      wrapper=$func_stripname_result\n\t    fi\n\t    ;;\n\t*)\n\t    wrapper=$file\n\t    ;;\n\tesac\n\tif func_ltwrapper_script_p \"$wrapper\"; then\n\t  notinst_deplibs=\n\t  relink_command=\n\n\t  func_source \"$wrapper\"\n\n\t  # Check the variables that should have been set.\n\t  test -z \"$generated_by_libtool_version\" && \\\n\t    func_fatal_error \"invalid libtool wrapper script \\`$wrapper'\"\n\n\t  finalize=yes\n\t  for lib in $notinst_deplibs; do\n\t    # Check to see that each library is installed.\n\t    libdir=\n\t    if test -f \"$lib\"; then\n\t      func_source \"$lib\"\n\t    fi\n\t    libfile=\"$libdir/\"`$ECHO \"X$lib\" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test\n\t    if test -n \"$libdir\" && test ! -f \"$libfile\"; then\n\t      func_warning \"\\`$lib' has not been installed in \\`$libdir'\"\n\t      finalize=no\n\t    fi\n\t  done\n\n\t  relink_command=\n\t  func_source \"$wrapper\"\n\n\t  outputname=\n\t  if test \"$fast_install\" = no && test -n \"$relink_command\"; then\n\t    $opt_dry_run || {\n\t      if test \"$finalize\" = yes; then\n\t        tmpdir=`func_mktempdir`\n\t\tfunc_basename \"$file$stripped_ext\"\n\t\tfile=\"$func_basename_result\"\n\t        outputname=\"$tmpdir/$file\"\n\t        # Replace the output file specification.\n\t        relink_command=`$ECHO \"X$relink_command\" | $Xsed -e 's%@OUTPUT@%'\"$outputname\"'%g'`\n\n\t        $opt_silent || {\n\t          func_quote_for_expand \"$relink_command\"\n\t\t  eval \"func_echo $func_quote_for_expand_result\"\n\t        }\n\t        if eval \"$relink_command\"; then :\n\t          else\n\t\t  func_error \"error: relink \\`$file' with the above command before installing it\"\n\t\t  $opt_dry_run || ${RM}r \"$tmpdir\"\n\t\t  continue\n\t        fi\n\t        file=\"$outputname\"\n\t      else\n\t        func_warning \"cannot relink \\`$file'\"\n\t      fi\n\t    }\n\t  else\n\t    # Install the binary that we compiled earlier.\n\t    file=`$ECHO \"X$file$stripped_ext\" | $Xsed -e \"s%\\([^/]*\\)$%$objdir/\\1%\"`\n\t  fi\n\tfi\n\n\t# remove .exe since cygwin /usr/bin/install will append another\n\t# one anyway\n\tcase $install_prog,$host in\n\t*/usr/bin/install*,*cygwin*)\n\t  case $file:$destfile in\n\t  *.exe:*.exe)\n\t    # this is ok\n\t    ;;\n\t  *.exe:*)\n\t    destfile=$destfile.exe\n\t    ;;\n\t  *:*.exe)\n\t    func_stripname '' '.exe' \"$destfile\"\n\t    destfile=$func_stripname_result\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n\tfunc_show_eval \"$install_prog\\$stripme \\$file \\$destfile\" 'exit $?'\n\t$opt_dry_run || if test -n \"$outputname\"; then\n\t  ${RM}r \"$tmpdir\"\n\tfi\n\t;;\n      esac\n    done\n\n    for file in $staticlibs; do\n      func_basename \"$file\"\n      name=\"$func_basename_result\"\n\n      # Set up the ranlib parameters.\n      oldlib=\"$destdir/$name\"\n\n      func_show_eval \"$install_prog \\$file \\$oldlib\" 'exit $?'\n\n      if test -n \"$stripme\" && test -n \"$old_striplib\"; then\n\tfunc_show_eval \"$old_striplib $oldlib\" 'exit $?'\n      fi\n\n      # Do each command in the postinstall commands.\n      func_execute_cmds \"$old_postinstall_cmds\" 'exit $?'\n    done\n\n    test -n \"$future_libdirs\" && \\\n      func_warning \"remember to run \\`$progname --finish$future_libdirs'\"\n\n    if test -n \"$current_libdirs\"; then\n      # Maybe just do a dry run.\n      $opt_dry_run && current_libdirs=\" -n$current_libdirs\"\n      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'\n    else\n      exit $EXIT_SUCCESS\n    fi\n}\n\ntest \"$mode\" = install && func_mode_install ${1+\"$@\"}\n\n\n# func_generate_dlsyms outputname originator pic_p\n# Extract symbols from dlprefiles and create ${outputname}S.o with\n# a dlpreopen symbol table.\nfunc_generate_dlsyms ()\n{\n    $opt_debug\n    my_outputname=\"$1\"\n    my_originator=\"$2\"\n    my_pic_p=\"${3-no}\"\n    my_prefix=`$ECHO \"$my_originator\" | sed 's%[^a-zA-Z0-9]%_%g'`\n    my_dlsyms=\n\n    if test -n \"$dlfiles$dlprefiles\" || test \"$dlself\" != no; then\n      if test -n \"$NM\" && test -n \"$global_symbol_pipe\"; then\n\tmy_dlsyms=\"${my_outputname}S.c\"\n      else\n\tfunc_error \"not configured to extract global symbols from dlpreopened files\"\n      fi\n    fi\n\n    if test -n \"$my_dlsyms\"; then\n      case $my_dlsyms in\n      \"\") ;;\n      *.c)\n\t# Discover the nlist of each of the dlfiles.\n\tnlist=\"$output_objdir/${my_outputname}.nm\"\n\n\tfunc_show_eval \"$RM $nlist ${nlist}S ${nlist}T\"\n\n\t# Parse the name list into a source file.\n\tfunc_verbose \"creating $output_objdir/$my_dlsyms\"\n\n\t$opt_dry_run || $ECHO > \"$output_objdir/$my_dlsyms\" \"\\\n/* $my_dlsyms - symbol resolution table for \\`$my_outputname' dlsym emulation. */\n/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */\n\n#ifdef __cplusplus\nextern \\\"C\\\" {\n#endif\n\n/* External symbol declarations for the compiler. */\\\n\"\n\n\tif test \"$dlself\" = yes; then\n\t  func_verbose \"generating symbol list for \\`$output'\"\n\n\t  $opt_dry_run || echo ': @PROGRAM@ ' > \"$nlist\"\n\n\t  # Add our own program objects to the symbol list.\n\t  progfiles=`$ECHO \"X$objs$old_deplibs\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n\t  for progfile in $progfiles; do\n\t    func_verbose \"extracting global C symbols from \\`$progfile'\"\n\t    $opt_dry_run || eval \"$NM $progfile | $global_symbol_pipe >> '$nlist'\"\n\t  done\n\n\t  if test -n \"$exclude_expsyms\"; then\n\t    $opt_dry_run || {\n\t      eval '$EGREP -v \" ($exclude_expsyms)$\" \"$nlist\" > \"$nlist\"T'\n\t      eval '$MV \"$nlist\"T \"$nlist\"'\n\t    }\n\t  fi\n\n\t  if test -n \"$export_symbols_regex\"; then\n\t    $opt_dry_run || {\n\t      eval '$EGREP -e \"$export_symbols_regex\" \"$nlist\" > \"$nlist\"T'\n\t      eval '$MV \"$nlist\"T \"$nlist\"'\n\t    }\n\t  fi\n\n\t  # Prepare the list of exported symbols\n\t  if test -z \"$export_symbols\"; then\n\t    export_symbols=\"$output_objdir/$outputname.exp\"\n\t    $opt_dry_run || {\n\t      $RM $export_symbols\n\t      eval \"${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \\(.*\\)$/\\1/p' \"'< \"$nlist\" > \"$export_symbols\"'\n\t      case $host in\n\t      *cygwin* | *mingw* | *cegcc* )\n                eval \"echo EXPORTS \"'> \"$output_objdir/$outputname.def\"'\n                eval 'cat \"$export_symbols\" >> \"$output_objdir/$outputname.def\"'\n\t        ;;\n\t      esac\n\t    }\n\t  else\n\t    $opt_dry_run || {\n\t      eval \"${SED} -e 's/\\([].[*^$]\\)/\\\\\\\\\\1/g' -e 's/^/ /' -e 's/$/$/'\"' < \"$export_symbols\" > \"$output_objdir/$outputname.exp\"'\n\t      eval '$GREP -f \"$output_objdir/$outputname.exp\" < \"$nlist\" > \"$nlist\"T'\n\t      eval '$MV \"$nlist\"T \"$nlist\"'\n\t      case $host in\n\t        *cygwin | *mingw* | *cegcc* )\n\t          eval \"echo EXPORTS \"'> \"$output_objdir/$outputname.def\"'\n\t          eval 'cat \"$nlist\" >> \"$output_objdir/$outputname.def\"'\n\t          ;;\n\t      esac\n\t    }\n\t  fi\n\tfi\n\n\tfor dlprefile in $dlprefiles; do\n\t  func_verbose \"extracting global C symbols from \\`$dlprefile'\"\n\t  func_basename \"$dlprefile\"\n\t  name=\"$func_basename_result\"\n\t  $opt_dry_run || {\n\t    eval '$ECHO \": $name \" >> \"$nlist\"'\n\t    eval \"$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'\"\n\t  }\n\tdone\n\n\t$opt_dry_run || {\n\t  # Make sure we have at least an empty file.\n\t  test -f \"$nlist\" || : > \"$nlist\"\n\n\t  if test -n \"$exclude_expsyms\"; then\n\t    $EGREP -v \" ($exclude_expsyms)$\" \"$nlist\" > \"$nlist\"T\n\t    $MV \"$nlist\"T \"$nlist\"\n\t  fi\n\n\t  # Try sorting and uniquifying the output.\n\t  if $GREP -v \"^: \" < \"$nlist\" |\n\t      if sort -k 3 </dev/null >/dev/null 2>&1; then\n\t\tsort -k 3\n\t      else\n\t\tsort +2\n\t      fi |\n\t      uniq > \"$nlist\"S; then\n\t    :\n\t  else\n\t    $GREP -v \"^: \" < \"$nlist\" > \"$nlist\"S\n\t  fi\n\n\t  if test -f \"$nlist\"S; then\n\t    eval \"$global_symbol_to_cdecl\"' < \"$nlist\"S >> \"$output_objdir/$my_dlsyms\"'\n\t  else\n\t    $ECHO '/* NONE */' >> \"$output_objdir/$my_dlsyms\"\n\t  fi\n\n\t  $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\n\n/* The mapping between symbol names and symbols.  */\ntypedef struct {\n  const char *name;\n  void *address;\n} lt_dlsymlist;\n\"\n\t  case $host in\n\t  *cygwin* | *mingw* | *cegcc* )\n\t    $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\n/* DATA imports from DLLs on WIN32 con't be const, because\n   runtime relocations are performed -- see ld's documentation\n   on pseudo-relocs.  */\"\n\t    lt_dlsym_const= ;;\n\t  *osf5*)\n\t    echo >> \"$output_objdir/$my_dlsyms\" \"\\\n/* This system does not cope well with relocations in const data */\"\n\t    lt_dlsym_const= ;;\n\t  *)\n\t    lt_dlsym_const=const ;;\n\t  esac\n\n\t  $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\nextern $lt_dlsym_const lt_dlsymlist\nlt_${my_prefix}_LTX_preloaded_symbols[];\n$lt_dlsym_const lt_dlsymlist\nlt_${my_prefix}_LTX_preloaded_symbols[] =\n{\\\n  { \\\"$my_originator\\\", (void *) 0 },\"\n\n\t  case $need_lib_prefix in\n\t  no)\n\t    eval \"$global_symbol_to_c_name_address\" < \"$nlist\" >> \"$output_objdir/$my_dlsyms\"\n\t    ;;\n\t  *)\n\t    eval \"$global_symbol_to_c_name_address_lib_prefix\" < \"$nlist\" >> \"$output_objdir/$my_dlsyms\"\n\t    ;;\n\t  esac\n\t  $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\n  {0, (void *) 0}\n};\n\n/* This works around a problem in FreeBSD linker */\n#ifdef FREEBSD_WORKAROUND\nstatic const void *lt_preloaded_setup() {\n  return lt_${my_prefix}_LTX_preloaded_symbols;\n}\n#endif\n\n#ifdef __cplusplus\n}\n#endif\\\n\"\n\t} # !$opt_dry_run\n\n\tpic_flag_for_symtable=\n\tcase \"$compile_command \" in\n\t*\" -static \"*) ;;\n\t*)\n\t  case $host in\n\t  # compiling the symbol table file with pic_flag works around\n\t  # a FreeBSD bug that causes programs to crash when -lm is\n\t  # linked before any other PIC object.  But we must not use\n\t  # pic_flag when linking with -static.  The problem exists in\n\t  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.\n\t  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)\n\t    pic_flag_for_symtable=\" $pic_flag -DFREEBSD_WORKAROUND\" ;;\n\t  *-*-hpux*)\n\t    pic_flag_for_symtable=\" $pic_flag\"  ;;\n\t  *)\n\t    if test \"X$my_pic_p\" != Xno; then\n\t      pic_flag_for_symtable=\" $pic_flag\"\n\t    fi\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n\tsymtab_cflags=\n\tfor arg in $LTCFLAGS; do\n\t  case $arg in\n\t  -pie | -fpie | -fPIE) ;;\n\t  *) symtab_cflags=\"$symtab_cflags $arg\" ;;\n\t  esac\n\tdone\n\n\t# Now compile the dynamic symbol file.\n\tfunc_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable \"$my_dlsyms\")' 'exit $?'\n\n\t# Clean up the generated files.\n\tfunc_show_eval '$RM \"$output_objdir/$my_dlsyms\" \"$nlist\" \"${nlist}S\" \"${nlist}T\"'\n\n\t# Transform the symbol file into the correct name.\n\tsymfileobj=\"$output_objdir/${my_outputname}S.$objext\"\n\tcase $host in\n\t*cygwin* | *mingw* | *cegcc* )\n\t  if test -f \"$output_objdir/$my_outputname.def\"; then\n\t    compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%\"`\n\t    finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%\"`\n\t  else\n\t    compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t    finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t  fi\n\t  ;;\n\t*)\n\t  compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t  finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t  ;;\n\tesac\n\t;;\n      *)\n\tfunc_fatal_error \"unknown suffix for \\`$my_dlsyms'\"\n\t;;\n      esac\n    else\n      # We keep going just in case the user didn't refer to\n      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe\n      # really was required.\n\n      # Nullify the symbol file.\n      compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s% @SYMFILE@%%\"`\n      finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s% @SYMFILE@%%\"`\n    fi\n}\n\n# func_win32_libid arg\n# return the library type of file 'arg'\n#\n# Need a lot of goo to handle *both* DLLs and import libs\n# Has to be a shell function in order to 'eat' the argument\n# that is supplied when $file_magic_command is called.\nfunc_win32_libid ()\n{\n  $opt_debug\n  win32_libid_type=\"unknown\"\n  win32_fileres=`file -L $1 2>/dev/null`\n  case $win32_fileres in\n  *ar\\ archive\\ import\\ library*) # definitely import\n    win32_libid_type=\"x86 archive import\"\n    ;;\n  *ar\\ archive*) # could be an import, or static\n    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |\n       $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then\n      win32_nmres=`eval $NM -f posix -A $1 |\n\t$SED -n -e '\n\t    1,100{\n\t\t/ I /{\n\t\t    s,.*,import,\n\t\t    p\n\t\t    q\n\t\t}\n\t    }'`\n      case $win32_nmres in\n      import*)  win32_libid_type=\"x86 archive import\";;\n      *)        win32_libid_type=\"x86 archive static\";;\n      esac\n    fi\n    ;;\n  *DLL*)\n    win32_libid_type=\"x86 DLL\"\n    ;;\n  *executable*) # but shell scripts are \"executable\" too...\n    case $win32_fileres in\n    *MS\\ Windows\\ PE\\ Intel*)\n      win32_libid_type=\"x86 DLL\"\n      ;;\n    esac\n    ;;\n  esac\n  $ECHO \"$win32_libid_type\"\n}\n\n\n\n# func_extract_an_archive dir oldlib\nfunc_extract_an_archive ()\n{\n    $opt_debug\n    f_ex_an_ar_dir=\"$1\"; shift\n    f_ex_an_ar_oldlib=\"$1\"\n    func_show_eval \"(cd \\$f_ex_an_ar_dir && $AR x \\\"\\$f_ex_an_ar_oldlib\\\")\" 'exit $?'\n    if ($AR t \"$f_ex_an_ar_oldlib\" | sort | sort -uc >/dev/null 2>&1); then\n     :\n    else\n      func_fatal_error \"object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib\"\n    fi\n}\n\n\n# func_extract_archives gentop oldlib ...\nfunc_extract_archives ()\n{\n    $opt_debug\n    my_gentop=\"$1\"; shift\n    my_oldlibs=${1+\"$@\"}\n    my_oldobjs=\"\"\n    my_xlib=\"\"\n    my_xabs=\"\"\n    my_xdir=\"\"\n\n    for my_xlib in $my_oldlibs; do\n      # Extract the objects.\n      case $my_xlib in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) my_xabs=\"$my_xlib\" ;;\n\t*) my_xabs=`pwd`\"/$my_xlib\" ;;\n      esac\n      func_basename \"$my_xlib\"\n      my_xlib=\"$func_basename_result\"\n      my_xlib_u=$my_xlib\n      while :; do\n        case \" $extracted_archives \" in\n\t*\" $my_xlib_u \"*)\n\t  func_arith $extracted_serial + 1\n\t  extracted_serial=$func_arith_result\n\t  my_xlib_u=lt$extracted_serial-$my_xlib ;;\n\t*) break ;;\n\tesac\n      done\n      extracted_archives=\"$extracted_archives $my_xlib_u\"\n      my_xdir=\"$my_gentop/$my_xlib_u\"\n\n      func_mkdir_p \"$my_xdir\"\n\n      case $host in\n      *-darwin*)\n\tfunc_verbose \"Extracting $my_xabs\"\n\t# Do not bother doing anything if just a dry run\n\t$opt_dry_run || {\n\t  darwin_orig_dir=`pwd`\n\t  cd $my_xdir || exit $?\n\t  darwin_archive=$my_xabs\n\t  darwin_curdir=`pwd`\n\t  darwin_base_archive=`basename \"$darwin_archive\"`\n\t  darwin_arches=`$LIPO -info \"$darwin_archive\" 2>/dev/null | $GREP Architectures 2>/dev/null || true`\n\t  if test -n \"$darwin_arches\"; then\n\t    darwin_arches=`$ECHO \"$darwin_arches\" | $SED -e 's/.*are://'`\n\t    darwin_arch=\n\t    func_verbose \"$darwin_base_archive has multiple architectures $darwin_arches\"\n\t    for darwin_arch in  $darwin_arches ; do\n\t      func_mkdir_p \"unfat-$$/${darwin_base_archive}-${darwin_arch}\"\n\t      $LIPO -thin $darwin_arch -output \"unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}\" \"${darwin_archive}\"\n\t      cd \"unfat-$$/${darwin_base_archive}-${darwin_arch}\"\n\t      func_extract_an_archive \"`pwd`\" \"${darwin_base_archive}\"\n\t      cd \"$darwin_curdir\"\n\t      $RM \"unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}\"\n\t    done # $darwin_arches\n            ## Okay now we've a bunch of thin objects, gotta fatten them up :)\n\t    darwin_filelist=`find unfat-$$ -type f -name \\*.o -print -o -name \\*.lo -print | $SED -e \"$basename\" | sort -u`\n\t    darwin_file=\n\t    darwin_files=\n\t    for darwin_file in $darwin_filelist; do\n\t      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`\n\t      $LIPO -create -output \"$darwin_file\" $darwin_files\n\t    done # $darwin_filelist\n\t    $RM -rf unfat-$$\n\t    cd \"$darwin_orig_dir\"\n\t  else\n\t    cd $darwin_orig_dir\n\t    func_extract_an_archive \"$my_xdir\" \"$my_xabs\"\n\t  fi # $darwin_arches\n\t} # !$opt_dry_run\n\t;;\n      *)\n        func_extract_an_archive \"$my_xdir\" \"$my_xabs\"\n\t;;\n      esac\n      my_oldobjs=\"$my_oldobjs \"`find $my_xdir -name \\*.$objext -print -o -name \\*.lo -print | $NL2SP`\n    done\n\n    func_extract_archives_result=\"$my_oldobjs\"\n}\n\n\n\n# func_emit_wrapper_part1 [arg=no]\n#\n# Emit the first part of a libtool wrapper script on stdout.\n# For more information, see the description associated with\n# func_emit_wrapper(), below.\nfunc_emit_wrapper_part1 ()\n{\n\tfunc_emit_wrapper_part1_arg1=no\n\tif test -n \"$1\" ; then\n\t  func_emit_wrapper_part1_arg1=$1\n\tfi\n\n\t$ECHO \"\\\n#! $SHELL\n\n# $output - temporary wrapper script for $objdir/$outputname\n# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n#\n# The $output program cannot be directly executed until all the libtool\n# libraries that it depends on are installed.\n#\n# This wrapper script should never be moved out of the build directory.\n# If it is, it will not operate correctly.\n\n# Sed substitution that helps us do robust quoting.  It backslashifies\n# metacharacters that are still active within double-quoted strings.\nXsed='${SED} -e 1s/^X//'\nsed_quote_subst='$sed_quote_subst'\n\n# Be Bourne compatible\nif test -n \\\"\\${ZSH_VERSION+set}\\\" && (emulate sh) >/dev/null 2>&1; then\n  emulate sh\n  NULLCMD=:\n  # Zsh 3.x and 4.x performs word splitting on \\${1+\\\"\\$@\\\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '\\${1+\\\"\\$@\\\"}'='\\\"\\$@\\\"'\n  setopt NO_GLOB_SUBST\nelse\n  case \\`(set -o) 2>/dev/null\\` in *posix*) set -o posix;; esac\nfi\nBIN_SH=xpg4; export BIN_SH # for Tru64\nDUALCASE=1; export DUALCASE # for MKS sh\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nrelink_command=\\\"$relink_command\\\"\n\n# This environment variable determines our operation mode.\nif test \\\"\\$libtool_install_magic\\\" = \\\"$magic\\\"; then\n  # install mode needs the following variables:\n  generated_by_libtool_version='$macro_version'\n  notinst_deplibs='$notinst_deplibs'\nelse\n  # When we are sourced in execute mode, \\$file and \\$ECHO are already set.\n  if test \\\"\\$libtool_execute_magic\\\" != \\\"$magic\\\"; then\n    ECHO=\\\"$qecho\\\"\n    file=\\\"\\$0\\\"\n    # Make sure echo works.\n    if test \\\"X\\$1\\\" = X--no-reexec; then\n      # Discard the --no-reexec flag, and continue.\n      shift\n    elif test \\\"X\\`{ \\$ECHO '\\t'; } 2>/dev/null\\`\\\" = 'X\\t'; then\n      # Yippee, \\$ECHO works!\n      :\n    else\n      # Restart under the correct shell, and then maybe \\$ECHO will work.\n      exec $SHELL \\\"\\$0\\\" --no-reexec \\${1+\\\"\\$@\\\"}\n    fi\n  fi\\\n\"\n\t$ECHO \"\\\n\n  # Find the directory that this script lives in.\n  thisdir=\\`\\$ECHO \\\"X\\$file\\\" | \\$Xsed -e 's%/[^/]*$%%'\\`\n  test \\\"x\\$thisdir\\\" = \\\"x\\$file\\\" && thisdir=.\n\n  # Follow symbolic links until we get to the real thisdir.\n  file=\\`ls -ld \\\"\\$file\\\" | ${SED} -n 's/.*-> //p'\\`\n  while test -n \\\"\\$file\\\"; do\n    destdir=\\`\\$ECHO \\\"X\\$file\\\" | \\$Xsed -e 's%/[^/]*\\$%%'\\`\n\n    # If there was a directory component, then change thisdir.\n    if test \\\"x\\$destdir\\\" != \\\"x\\$file\\\"; then\n      case \\\"\\$destdir\\\" in\n      [\\\\\\\\/]* | [A-Za-z]:[\\\\\\\\/]*) thisdir=\\\"\\$destdir\\\" ;;\n      *) thisdir=\\\"\\$thisdir/\\$destdir\\\" ;;\n      esac\n    fi\n\n    file=\\`\\$ECHO \\\"X\\$file\\\" | \\$Xsed -e 's%^.*/%%'\\`\n    file=\\`ls -ld \\\"\\$thisdir/\\$file\\\" | ${SED} -n 's/.*-> //p'\\`\n  done\n\"\n}\n# end: func_emit_wrapper_part1\n\n# func_emit_wrapper_part2 [arg=no]\n#\n# Emit the second part of a libtool wrapper script on stdout.\n# For more information, see the description associated with\n# func_emit_wrapper(), below.\nfunc_emit_wrapper_part2 ()\n{\n\tfunc_emit_wrapper_part2_arg1=no\n\tif test -n \"$1\" ; then\n\t  func_emit_wrapper_part2_arg1=$1\n\tfi\n\n\t$ECHO \"\\\n\n  # Usually 'no', except on cygwin/mingw when embedded into\n  # the cwrapper.\n  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1\n  if test \\\"\\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\\\" = \\\"yes\\\"; then\n    # special case for '.'\n    if test \\\"\\$thisdir\\\" = \\\".\\\"; then\n      thisdir=\\`pwd\\`\n    fi\n    # remove .libs from thisdir\n    case \\\"\\$thisdir\\\" in\n    *[\\\\\\\\/]$objdir ) thisdir=\\`\\$ECHO \\\"X\\$thisdir\\\" | \\$Xsed -e 's%[\\\\\\\\/][^\\\\\\\\/]*$%%'\\` ;;\n    $objdir )   thisdir=. ;;\n    esac\n  fi\n\n  # Try to get the absolute directory name.\n  absdir=\\`cd \\\"\\$thisdir\\\" && pwd\\`\n  test -n \\\"\\$absdir\\\" && thisdir=\\\"\\$absdir\\\"\n\"\n\n\tif test \"$fast_install\" = yes; then\n\t  $ECHO \"\\\n  program=lt-'$outputname'$exeext\n  progdir=\\\"\\$thisdir/$objdir\\\"\n\n  if test ! -f \\\"\\$progdir/\\$program\\\" ||\n     { file=\\`ls -1dt \\\"\\$progdir/\\$program\\\" \\\"\\$progdir/../\\$program\\\" 2>/dev/null | ${SED} 1q\\`; \\\\\n       test \\\"X\\$file\\\" != \\\"X\\$progdir/\\$program\\\"; }; then\n\n    file=\\\"\\$\\$-\\$program\\\"\n\n    if test ! -d \\\"\\$progdir\\\"; then\n      $MKDIR \\\"\\$progdir\\\"\n    else\n      $RM \\\"\\$progdir/\\$file\\\"\n    fi\"\n\n\t  $ECHO \"\\\n\n    # relink executable if necessary\n    if test -n \\\"\\$relink_command\\\"; then\n      if relink_command_output=\\`eval \\$relink_command 2>&1\\`; then :\n      else\n\t$ECHO \\\"\\$relink_command_output\\\" >&2\n\t$RM \\\"\\$progdir/\\$file\\\"\n\texit 1\n      fi\n    fi\n\n    $MV \\\"\\$progdir/\\$file\\\" \\\"\\$progdir/\\$program\\\" 2>/dev/null ||\n    { $RM \\\"\\$progdir/\\$program\\\";\n      $MV \\\"\\$progdir/\\$file\\\" \\\"\\$progdir/\\$program\\\"; }\n    $RM \\\"\\$progdir/\\$file\\\"\n  fi\"\n\telse\n\t  $ECHO \"\\\n  program='$outputname'\n  progdir=\\\"\\$thisdir/$objdir\\\"\n\"\n\tfi\n\n\t$ECHO \"\\\n\n  if test -f \\\"\\$progdir/\\$program\\\"; then\"\n\n\t# Export our shlibpath_var if we have one.\n\tif test \"$shlibpath_overrides_runpath\" = yes && test -n \"$shlibpath_var\" && test -n \"$temp_rpath\"; then\n\t  $ECHO \"\\\n    # Add our own library path to $shlibpath_var\n    $shlibpath_var=\\\"$temp_rpath\\$$shlibpath_var\\\"\n\n    # Some systems cannot cope with colon-terminated $shlibpath_var\n    # The second colon is a workaround for a bug in BeOS R4 sed\n    $shlibpath_var=\\`\\$ECHO \\\"X\\$$shlibpath_var\\\" | \\$Xsed -e 's/::*\\$//'\\`\n\n    export $shlibpath_var\n\"\n\tfi\n\n\t# fixup the dll searchpath if we need to.\n\tif test -n \"$dllsearchpath\"; then\n\t  $ECHO \"\\\n    # Add the dll search path components to the executable PATH\n    PATH=$dllsearchpath:\\$PATH\n\"\n\tfi\n\n\t$ECHO \"\\\n    if test \\\"\\$libtool_execute_magic\\\" != \\\"$magic\\\"; then\n      # Run the actual program with our arguments.\n\"\n\tcase $host in\n\t# Backslashes separate directories on plain windows\n\t*-*-mingw | *-*-os2* | *-cegcc*)\n\t  $ECHO \"\\\n      exec \\\"\\$progdir\\\\\\\\\\$program\\\" \\${1+\\\"\\$@\\\"}\n\"\n\t  ;;\n\n\t*)\n\t  $ECHO \"\\\n      exec \\\"\\$progdir/\\$program\\\" \\${1+\\\"\\$@\\\"}\n\"\n\t  ;;\n\tesac\n\t$ECHO \"\\\n      \\$ECHO \\\"\\$0: cannot exec \\$program \\$*\\\" 1>&2\n      exit 1\n    fi\n  else\n    # The program doesn't exist.\n    \\$ECHO \\\"\\$0: error: \\\\\\`\\$progdir/\\$program' does not exist\\\" 1>&2\n    \\$ECHO \\\"This script is just a wrapper for \\$program.\\\" 1>&2\n    $ECHO \\\"See the $PACKAGE documentation for more information.\\\" 1>&2\n    exit 1\n  fi\nfi\\\n\"\n}\n# end: func_emit_wrapper_part2\n\n\n# func_emit_wrapper [arg=no]\n#\n# Emit a libtool wrapper script on stdout.\n# Don't directly open a file because we may want to\n# incorporate the script contents within a cygwin/mingw\n# wrapper executable.  Must ONLY be called from within\n# func_mode_link because it depends on a number of variables\n# set therein.\n#\n# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\n# variable will take.  If 'yes', then the emitted script\n# will assume that the directory in which it is stored is\n# the $objdir directory.  This is a cygwin/mingw-specific\n# behavior.\nfunc_emit_wrapper ()\n{\n\tfunc_emit_wrapper_arg1=no\n\tif test -n \"$1\" ; then\n\t  func_emit_wrapper_arg1=$1\n\tfi\n\n\t# split this up so that func_emit_cwrapperexe_src\n\t# can call each part independently.\n\tfunc_emit_wrapper_part1 \"${func_emit_wrapper_arg1}\"\n\tfunc_emit_wrapper_part2 \"${func_emit_wrapper_arg1}\"\n}\n\n\n# func_to_host_path arg\n#\n# Convert paths to host format when used with build tools.\n# Intended for use with \"native\" mingw (where libtool itself\n# is running under the msys shell), or in the following cross-\n# build environments:\n#    $build          $host\n#    mingw (msys)    mingw  [e.g. native]\n#    cygwin          mingw\n#    *nix + wine     mingw\n# where wine is equipped with the `winepath' executable.\n# In the native mingw case, the (msys) shell automatically\n# converts paths for any non-msys applications it launches,\n# but that facility isn't available from inside the cwrapper.\n# Similar accommodations are necessary for $host mingw and\n# $build cygwin.  Calling this function does no harm for other\n# $host/$build combinations not listed above.\n#\n# ARG is the path (on $build) that should be converted to\n# the proper representation for $host. The result is stored\n# in $func_to_host_path_result.\nfunc_to_host_path ()\n{\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\" ; then\n    case $host in\n      *mingw* )\n        lt_sed_naive_backslashify='s|\\\\\\\\*|\\\\|g;s|/|\\\\|g;s|\\\\|\\\\\\\\|g'\n        case $build in\n          *mingw* ) # actually, msys\n            # awkward: cmd appends spaces to result\n            lt_sed_strip_trailing_spaces=\"s/[ ]*\\$//\"\n            func_to_host_path_tmp1=`( cmd //c echo \"$1\" |\\\n              $SED -e \"$lt_sed_strip_trailing_spaces\" ) 2>/dev/null || echo \"\"`\n            func_to_host_path_result=`echo \"$func_to_host_path_tmp1\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          *cygwin* )\n            func_to_host_path_tmp1=`cygpath -w \"$1\"`\n            func_to_host_path_result=`echo \"$func_to_host_path_tmp1\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          * )\n            # Unfortunately, winepath does not exit with a non-zero\n            # error code, so we are forced to check the contents of\n            # stdout. On the other hand, if the command is not\n            # found, the shell will set an exit code of 127 and print\n            # *an error message* to stdout. So we must check for both\n            # error code of zero AND non-empty stdout, which explains\n            # the odd construction:\n            func_to_host_path_tmp1=`winepath -w \"$1\" 2>/dev/null`\n            if test \"$?\" -eq 0 && test -n \"${func_to_host_path_tmp1}\"; then\n              func_to_host_path_result=`echo \"$func_to_host_path_tmp1\" |\\\n                $SED -e \"$lt_sed_naive_backslashify\"`\n            else\n              # Allow warning below.\n              func_to_host_path_result=\"\"\n            fi\n            ;;\n        esac\n        if test -z \"$func_to_host_path_result\" ; then\n          func_error \"Could not determine host path corresponding to\"\n          func_error \"  '$1'\"\n          func_error \"Continuing, but uninstalled executables may not work.\"\n          # Fallback:\n          func_to_host_path_result=\"$1\"\n        fi\n        ;;\n    esac\n  fi\n}\n# end: func_to_host_path\n\n# func_to_host_pathlist arg\n#\n# Convert pathlists to host format when used with build tools.\n# See func_to_host_path(), above. This function supports the\n# following $build/$host combinations (but does no harm for\n# combinations not listed here):\n#    $build          $host\n#    mingw (msys)    mingw  [e.g. native]\n#    cygwin          mingw\n#    *nix + wine     mingw\n#\n# Path separators are also converted from $build format to\n# $host format. If ARG begins or ends with a path separator\n# character, it is preserved (but converted to $host format)\n# on output.\n#\n# ARG is a pathlist (on $build) that should be converted to\n# the proper representation on $host. The result is stored\n# in $func_to_host_pathlist_result.\nfunc_to_host_pathlist ()\n{\n  func_to_host_pathlist_result=\"$1\"\n  if test -n \"$1\" ; then\n    case $host in\n      *mingw* )\n        lt_sed_naive_backslashify='s|\\\\\\\\*|\\\\|g;s|/|\\\\|g;s|\\\\|\\\\\\\\|g'\n        # Remove leading and trailing path separator characters from\n        # ARG. msys behavior is inconsistent here, cygpath turns them\n        # into '.;' and ';.', and winepath ignores them completely.\n        func_to_host_pathlist_tmp2=\"$1\"\n        # Once set for this call, this variable should not be\n        # reassigned. It is used in tha fallback case.\n        func_to_host_pathlist_tmp1=`echo \"$func_to_host_pathlist_tmp2\" |\\\n          $SED -e 's|^:*||' -e 's|:*$||'`\n        case $build in\n          *mingw* ) # Actually, msys.\n            # Awkward: cmd appends spaces to result.\n            lt_sed_strip_trailing_spaces=\"s/[ ]*\\$//\"\n            func_to_host_pathlist_tmp2=`( cmd //c echo \"$func_to_host_pathlist_tmp1\" |\\\n              $SED -e \"$lt_sed_strip_trailing_spaces\" ) 2>/dev/null || echo \"\"`\n            func_to_host_pathlist_result=`echo \"$func_to_host_pathlist_tmp2\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          *cygwin* )\n            func_to_host_pathlist_tmp2=`cygpath -w -p \"$func_to_host_pathlist_tmp1\"`\n            func_to_host_pathlist_result=`echo \"$func_to_host_pathlist_tmp2\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          * )\n            # unfortunately, winepath doesn't convert pathlists\n            func_to_host_pathlist_result=\"\"\n            func_to_host_pathlist_oldIFS=$IFS\n            IFS=:\n            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do\n              IFS=$func_to_host_pathlist_oldIFS\n              if test -n \"$func_to_host_pathlist_f\" ; then\n                func_to_host_path \"$func_to_host_pathlist_f\"\n                if test -n \"$func_to_host_path_result\" ; then\n                  if test -z \"$func_to_host_pathlist_result\" ; then\n                    func_to_host_pathlist_result=\"$func_to_host_path_result\"\n                  else\n                    func_to_host_pathlist_result=\"$func_to_host_pathlist_result;$func_to_host_path_result\"\n                  fi\n                fi\n              fi\n              IFS=:\n            done\n            IFS=$func_to_host_pathlist_oldIFS\n            ;;\n        esac\n        if test -z \"$func_to_host_pathlist_result\" ; then\n          func_error \"Could not determine the host path(s) corresponding to\"\n          func_error \"  '$1'\"\n          func_error \"Continuing, but uninstalled executables may not work.\"\n          # Fallback. This may break if $1 contains DOS-style drive\n          # specifications. The fix is not to complicate the expression\n          # below, but for the user to provide a working wine installation\n          # with winepath so that path translation in the cross-to-mingw\n          # case works properly.\n          lt_replace_pathsep_nix_to_dos=\"s|:|;|g\"\n          func_to_host_pathlist_result=`echo \"$func_to_host_pathlist_tmp1\" |\\\n            $SED -e \"$lt_replace_pathsep_nix_to_dos\"`\n        fi\n        # Now, add the leading and trailing path separators back\n        case \"$1\" in\n          :* ) func_to_host_pathlist_result=\";$func_to_host_pathlist_result\"\n            ;;\n        esac\n        case \"$1\" in\n          *: ) func_to_host_pathlist_result=\"$func_to_host_pathlist_result;\"\n            ;;\n        esac\n        ;;\n    esac\n  fi\n}\n# end: func_to_host_pathlist\n\n# func_emit_cwrapperexe_src\n# emit the source code for a wrapper executable on stdout\n# Must ONLY be called from within func_mode_link because\n# it depends on a number of variable set therein.\nfunc_emit_cwrapperexe_src ()\n{\n\tcat <<EOF\n\n/* $cwrappersource - temporary wrapper executable for $objdir/$outputname\n   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n\n   The $output program cannot be directly executed until all the libtool\n   libraries that it depends on are installed.\n\n   This wrapper executable should never be moved out of the build directory.\n   If it is, it will not operate correctly.\n\n   Currently, it simply execs the wrapper *script* \"$SHELL $output\",\n   but could eventually absorb all of the scripts functionality and\n   exec $objdir/$outputname directly.\n*/\nEOF\n\t    cat <<\"EOF\"\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef _MSC_VER\n# include <direct.h>\n# include <process.h>\n# include <io.h>\n# define setmode _setmode\n#else\n# include <unistd.h>\n# include <stdint.h>\n# ifdef __CYGWIN__\n#  include <io.h>\n#  define HAVE_SETENV\n#  ifdef __STRICT_ANSI__\nchar *realpath (const char *, char *);\nint putenv (char *);\nint setenv (const char *, const char *, int);\n#  endif\n# endif\n#endif\n#include <malloc.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <string.h>\n#include <ctype.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n\n#if defined(PATH_MAX)\n# define LT_PATHMAX PATH_MAX\n#elif defined(MAXPATHLEN)\n# define LT_PATHMAX MAXPATHLEN\n#else\n# define LT_PATHMAX 1024\n#endif\n\n#ifndef S_IXOTH\n# define S_IXOTH 0\n#endif\n#ifndef S_IXGRP\n# define S_IXGRP 0\n#endif\n\n#ifdef _MSC_VER\n# define S_IXUSR _S_IEXEC\n# define stat _stat\n# ifndef _INTPTR_T_DEFINED\n#  define intptr_t int\n# endif\n#endif\n\n#ifndef DIR_SEPARATOR\n# define DIR_SEPARATOR '/'\n# define PATH_SEPARATOR ':'\n#endif\n\n#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \\\n  defined (__OS2__)\n# define HAVE_DOS_BASED_FILE_SYSTEM\n# define FOPEN_WB \"wb\"\n# ifndef DIR_SEPARATOR_2\n#  define DIR_SEPARATOR_2 '\\\\'\n# endif\n# ifndef PATH_SEPARATOR_2\n#  define PATH_SEPARATOR_2 ';'\n# endif\n#endif\n\n#ifndef DIR_SEPARATOR_2\n# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)\n#else /* DIR_SEPARATOR_2 */\n# define IS_DIR_SEPARATOR(ch) \\\n\t(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))\n#endif /* DIR_SEPARATOR_2 */\n\n#ifndef PATH_SEPARATOR_2\n# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)\n#else /* PATH_SEPARATOR_2 */\n# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)\n#endif /* PATH_SEPARATOR_2 */\n\n#ifdef __CYGWIN__\n# define FOPEN_WB \"wb\"\n#endif\n\n#ifndef FOPEN_WB\n# define FOPEN_WB \"w\"\n#endif\n#ifndef _O_BINARY\n# define _O_BINARY 0\n#endif\n\n#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))\n#define XFREE(stale) do { \\\n  if (stale) { free ((void *) stale); stale = 0; } \\\n} while (0)\n\n#undef LTWRAPPER_DEBUGPRINTF\n#if defined DEBUGWRAPPER\n# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args\nstatic void\nltwrapper_debugprintf (const char *fmt, ...)\n{\n    va_list args;\n    va_start (args, fmt);\n    (void) vfprintf (stderr, fmt, args);\n    va_end (args);\n}\n#else\n# define LTWRAPPER_DEBUGPRINTF(args)\n#endif\n\nconst char *program_name = NULL;\n\nvoid *xmalloc (size_t num);\nchar *xstrdup (const char *string);\nconst char *base_name (const char *name);\nchar *find_executable (const char *wrapper);\nchar *chase_symlinks (const char *pathspec);\nint make_executable (const char *path);\nint check_executable (const char *path);\nchar *strendzap (char *str, const char *pat);\nvoid lt_fatal (const char *message, ...);\nvoid lt_setenv (const char *name, const char *value);\nchar *lt_extend_str (const char *orig_value, const char *add, int to_end);\nvoid lt_opt_process_env_set (const char *arg);\nvoid lt_opt_process_env_prepend (const char *arg);\nvoid lt_opt_process_env_append (const char *arg);\nint lt_split_name_value (const char *arg, char** name, char** value);\nvoid lt_update_exe_path (const char *name, const char *value);\nvoid lt_update_lib_path (const char *name, const char *value);\n\nstatic const char *script_text_part1 =\nEOF\n\n\t    func_emit_wrapper_part1 yes |\n\t        $SED -e 's/\\([\\\\\"]\\)/\\\\\\1/g' \\\n\t             -e 's/^/  \"/' -e 's/$/\\\\n\"/'\n\t    echo \";\"\n\t    cat <<EOF\n\nstatic const char *script_text_part2 =\nEOF\n\t    func_emit_wrapper_part2 yes |\n\t        $SED -e 's/\\([\\\\\"]\\)/\\\\\\1/g' \\\n\t             -e 's/^/  \"/' -e 's/$/\\\\n\"/'\n\t    echo \";\"\n\n\t    cat <<EOF\nconst char * MAGIC_EXE = \"$magic_exe\";\nconst char * LIB_PATH_VARNAME = \"$shlibpath_var\";\nEOF\n\n\t    if test \"$shlibpath_overrides_runpath\" = yes && test -n \"$shlibpath_var\" && test -n \"$temp_rpath\"; then\n              func_to_host_pathlist \"$temp_rpath\"\n\t      cat <<EOF\nconst char * LIB_PATH_VALUE   = \"$func_to_host_pathlist_result\";\nEOF\n\t    else\n\t      cat <<\"EOF\"\nconst char * LIB_PATH_VALUE   = \"\";\nEOF\n\t    fi\n\n\t    if test -n \"$dllsearchpath\"; then\n              func_to_host_pathlist \"$dllsearchpath:\"\n\t      cat <<EOF\nconst char * EXE_PATH_VARNAME = \"PATH\";\nconst char * EXE_PATH_VALUE   = \"$func_to_host_pathlist_result\";\nEOF\n\t    else\n\t      cat <<\"EOF\"\nconst char * EXE_PATH_VARNAME = \"\";\nconst char * EXE_PATH_VALUE   = \"\";\nEOF\n\t    fi\n\n\t    if test \"$fast_install\" = yes; then\n\t      cat <<EOF\nconst char * TARGET_PROGRAM_NAME = \"lt-$outputname\"; /* hopefully, no .exe */\nEOF\n\t    else\n\t      cat <<EOF\nconst char * TARGET_PROGRAM_NAME = \"$outputname\"; /* hopefully, no .exe */\nEOF\n\t    fi\n\n\n\t    cat <<\"EOF\"\n\n#define LTWRAPPER_OPTION_PREFIX         \"--lt-\"\n#define LTWRAPPER_OPTION_PREFIX_LENGTH  5\n\nstatic const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;\nstatic const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;\n\nstatic const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX \"dump-script\";\n\nstatic const size_t env_set_opt_len     = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;\nstatic const char *env_set_opt          = LTWRAPPER_OPTION_PREFIX \"env-set\";\n  /* argument is putenv-style \"foo=bar\", value of foo is set to bar */\n\nstatic const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;\nstatic const char *env_prepend_opt      = LTWRAPPER_OPTION_PREFIX \"env-prepend\";\n  /* argument is putenv-style \"foo=bar\", new value of foo is bar${foo} */\n\nstatic const size_t env_append_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;\nstatic const char *env_append_opt       = LTWRAPPER_OPTION_PREFIX \"env-append\";\n  /* argument is putenv-style \"foo=bar\", new value of foo is ${foo}bar */\n\nint\nmain (int argc, char *argv[])\n{\n  char **newargz;\n  int  newargc;\n  char *tmp_pathspec;\n  char *actual_cwrapper_path;\n  char *actual_cwrapper_name;\n  char *target_name;\n  char *lt_argv_zero;\n  intptr_t rval = 127;\n\n  int i;\n\n  program_name = (char *) xstrdup (base_name (argv[0]));\n  LTWRAPPER_DEBUGPRINTF ((\"(main) argv[0]      : %s\\n\", argv[0]));\n  LTWRAPPER_DEBUGPRINTF ((\"(main) program_name : %s\\n\", program_name));\n\n  /* very simple arg parsing; don't want to rely on getopt */\n  for (i = 1; i < argc; i++)\n    {\n      if (strcmp (argv[i], dumpscript_opt) == 0)\n\t{\nEOF\n\t    case \"$host\" in\n\t      *mingw* | *cygwin* )\n\t\t# make stdout use \"unix\" line endings\n\t\techo \"          setmode(1,_O_BINARY);\"\n\t\t;;\n\t      esac\n\n\t    cat <<\"EOF\"\n\t  printf (\"%s\", script_text_part1);\n\t  printf (\"%s\", script_text_part2);\n\t  return 0;\n\t}\n    }\n\n  newargz = XMALLOC (char *, argc + 1);\n  tmp_pathspec = find_executable (argv[0]);\n  if (tmp_pathspec == NULL)\n    lt_fatal (\"Couldn't find %s\", argv[0]);\n  LTWRAPPER_DEBUGPRINTF ((\"(main) found exe (before symlink chase) at : %s\\n\",\n\t\t\t  tmp_pathspec));\n\n  actual_cwrapper_path = chase_symlinks (tmp_pathspec);\n  LTWRAPPER_DEBUGPRINTF ((\"(main) found exe (after symlink chase) at : %s\\n\",\n\t\t\t  actual_cwrapper_path));\n  XFREE (tmp_pathspec);\n\n  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));\n  strendzap (actual_cwrapper_path, actual_cwrapper_name);\n\n  /* wrapper name transforms */\n  strendzap (actual_cwrapper_name, \".exe\");\n  tmp_pathspec = lt_extend_str (actual_cwrapper_name, \".exe\", 1);\n  XFREE (actual_cwrapper_name);\n  actual_cwrapper_name = tmp_pathspec;\n  tmp_pathspec = 0;\n\n  /* target_name transforms -- use actual target program name; might have lt- prefix */\n  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));\n  strendzap (target_name, \".exe\");\n  tmp_pathspec = lt_extend_str (target_name, \".exe\", 1);\n  XFREE (target_name);\n  target_name = tmp_pathspec;\n  tmp_pathspec = 0;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(main) libtool target name: %s\\n\",\n\t\t\t  target_name));\nEOF\n\n\t    cat <<EOF\n  newargz[0] =\n    XMALLOC (char, (strlen (actual_cwrapper_path) +\n\t\t    strlen (\"$objdir\") + 1 + strlen (actual_cwrapper_name) + 1));\n  strcpy (newargz[0], actual_cwrapper_path);\n  strcat (newargz[0], \"$objdir\");\n  strcat (newargz[0], \"/\");\nEOF\n\n\t    cat <<\"EOF\"\n  /* stop here, and copy so we don't have to do this twice */\n  tmp_pathspec = xstrdup (newargz[0]);\n\n  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */\n  strcat (newargz[0], actual_cwrapper_name);\n\n  /* DO want the lt- prefix here if it exists, so use target_name */\n  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);\n  XFREE (tmp_pathspec);\n  tmp_pathspec = NULL;\nEOF\n\n\t    case $host_os in\n\t      mingw*)\n\t    cat <<\"EOF\"\n  {\n    char* p;\n    while ((p = strchr (newargz[0], '\\\\')) != NULL)\n      {\n\t*p = '/';\n      }\n    while ((p = strchr (lt_argv_zero, '\\\\')) != NULL)\n      {\n\t*p = '/';\n      }\n  }\nEOF\n\t    ;;\n\t    esac\n\n\t    cat <<\"EOF\"\n  XFREE (target_name);\n  XFREE (actual_cwrapper_path);\n  XFREE (actual_cwrapper_name);\n\n  lt_setenv (\"BIN_SH\", \"xpg4\"); /* for Tru64 */\n  lt_setenv (\"DUALCASE\", \"1\");  /* for MSK sh */\n  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);\n  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);\n\n  newargc=0;\n  for (i = 1; i < argc; i++)\n    {\n      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)\n        {\n          if (argv[i][env_set_opt_len] == '=')\n            {\n              const char *p = argv[i] + env_set_opt_len + 1;\n              lt_opt_process_env_set (p);\n            }\n          else if (argv[i][env_set_opt_len] == '\\0' && i + 1 < argc)\n            {\n              lt_opt_process_env_set (argv[++i]); /* don't copy */\n            }\n          else\n            lt_fatal (\"%s missing required argument\", env_set_opt);\n          continue;\n        }\n      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)\n        {\n          if (argv[i][env_prepend_opt_len] == '=')\n            {\n              const char *p = argv[i] + env_prepend_opt_len + 1;\n              lt_opt_process_env_prepend (p);\n            }\n          else if (argv[i][env_prepend_opt_len] == '\\0' && i + 1 < argc)\n            {\n              lt_opt_process_env_prepend (argv[++i]); /* don't copy */\n            }\n          else\n            lt_fatal (\"%s missing required argument\", env_prepend_opt);\n          continue;\n        }\n      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)\n        {\n          if (argv[i][env_append_opt_len] == '=')\n            {\n              const char *p = argv[i] + env_append_opt_len + 1;\n              lt_opt_process_env_append (p);\n            }\n          else if (argv[i][env_append_opt_len] == '\\0' && i + 1 < argc)\n            {\n              lt_opt_process_env_append (argv[++i]); /* don't copy */\n            }\n          else\n            lt_fatal (\"%s missing required argument\", env_append_opt);\n          continue;\n        }\n      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)\n        {\n          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX\n             namespace, but it is not one of the ones we know about and\n             have already dealt with, above (inluding dump-script), then\n             report an error. Otherwise, targets might begin to believe\n             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX\n             namespace. The first time any user complains about this, we'll\n             need to make LTWRAPPER_OPTION_PREFIX a configure-time option\n             or a configure.ac-settable value.\n           */\n          lt_fatal (\"Unrecognized option in %s namespace: '%s'\",\n                    ltwrapper_option_prefix, argv[i]);\n        }\n      /* otherwise ... */\n      newargz[++newargc] = xstrdup (argv[i]);\n    }\n  newargz[++newargc] = NULL;\n\n  LTWRAPPER_DEBUGPRINTF     ((\"(main) lt_argv_zero : %s\\n\", (lt_argv_zero ? lt_argv_zero : \"<NULL>\")));\n  for (i = 0; i < newargc; i++)\n    {\n      LTWRAPPER_DEBUGPRINTF ((\"(main) newargz[%d]   : %s\\n\", i, (newargz[i] ? newargz[i] : \"<NULL>\")));\n    }\n\nEOF\n\n\t    case $host_os in\n\t      mingw*)\n\t\tcat <<\"EOF\"\n  /* execv doesn't actually work on mingw as expected on unix */\n  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);\n  if (rval == -1)\n    {\n      /* failed to start process */\n      LTWRAPPER_DEBUGPRINTF ((\"(main) failed to launch target \\\"%s\\\": errno = %d\\n\", lt_argv_zero, errno));\n      return 127;\n    }\n  return rval;\nEOF\n\t\t;;\n\t      *)\n\t\tcat <<\"EOF\"\n  execv (lt_argv_zero, newargz);\n  return rval; /* =127, but avoids unused variable warning */\nEOF\n\t\t;;\n\t    esac\n\n\t    cat <<\"EOF\"\n}\n\nvoid *\nxmalloc (size_t num)\n{\n  void *p = (void *) malloc (num);\n  if (!p)\n    lt_fatal (\"Memory exhausted\");\n\n  return p;\n}\n\nchar *\nxstrdup (const char *string)\n{\n  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),\n\t\t\t  string) : NULL;\n}\n\nconst char *\nbase_name (const char *name)\n{\n  const char *base;\n\n#if defined (HAVE_DOS_BASED_FILE_SYSTEM)\n  /* Skip over the disk name in MSDOS pathnames. */\n  if (isalpha ((unsigned char) name[0]) && name[1] == ':')\n    name += 2;\n#endif\n\n  for (base = name; *name; name++)\n    if (IS_DIR_SEPARATOR (*name))\n      base = name + 1;\n  return base;\n}\n\nint\ncheck_executable (const char *path)\n{\n  struct stat st;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(check_executable)  : %s\\n\",\n\t\t\t  path ? (*path ? path : \"EMPTY!\") : \"NULL!\"));\n  if ((!path) || (!*path))\n    return 0;\n\n  if ((stat (path, &st) >= 0)\n      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))\n    return 1;\n  else\n    return 0;\n}\n\nint\nmake_executable (const char *path)\n{\n  int rval = 0;\n  struct stat st;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(make_executable)   : %s\\n\",\n\t\t\t  path ? (*path ? path : \"EMPTY!\") : \"NULL!\"));\n  if ((!path) || (!*path))\n    return 0;\n\n  if (stat (path, &st) >= 0)\n    {\n      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);\n    }\n  return rval;\n}\n\n/* Searches for the full path of the wrapper.  Returns\n   newly allocated full path name if found, NULL otherwise\n   Does not chase symlinks, even on platforms that support them.\n*/\nchar *\nfind_executable (const char *wrapper)\n{\n  int has_slash = 0;\n  const char *p;\n  const char *p_next;\n  /* static buffer for getcwd */\n  char tmp[LT_PATHMAX + 1];\n  int tmp_len;\n  char *concat_name;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(find_executable)   : %s\\n\",\n\t\t\t  wrapper ? (*wrapper ? wrapper : \"EMPTY!\") : \"NULL!\"));\n\n  if ((wrapper == NULL) || (*wrapper == '\\0'))\n    return NULL;\n\n  /* Absolute path? */\n#if defined (HAVE_DOS_BASED_FILE_SYSTEM)\n  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')\n    {\n      concat_name = xstrdup (wrapper);\n      if (check_executable (concat_name))\n\treturn concat_name;\n      XFREE (concat_name);\n    }\n  else\n    {\n#endif\n      if (IS_DIR_SEPARATOR (wrapper[0]))\n\t{\n\t  concat_name = xstrdup (wrapper);\n\t  if (check_executable (concat_name))\n\t    return concat_name;\n\t  XFREE (concat_name);\n\t}\n#if defined (HAVE_DOS_BASED_FILE_SYSTEM)\n    }\n#endif\n\n  for (p = wrapper; *p; p++)\n    if (*p == '/')\n      {\n\thas_slash = 1;\n\tbreak;\n      }\n  if (!has_slash)\n    {\n      /* no slashes; search PATH */\n      const char *path = getenv (\"PATH\");\n      if (path != NULL)\n\t{\n\t  for (p = path; *p; p = p_next)\n\t    {\n\t      const char *q;\n\t      size_t p_len;\n\t      for (q = p; *q; q++)\n\t\tif (IS_PATH_SEPARATOR (*q))\n\t\t  break;\n\t      p_len = q - p;\n\t      p_next = (*q == '\\0' ? q : q + 1);\n\t      if (p_len == 0)\n\t\t{\n\t\t  /* empty path: current directory */\n\t\t  if (getcwd (tmp, LT_PATHMAX) == NULL)\n\t\t    lt_fatal (\"getcwd failed\");\n\t\t  tmp_len = strlen (tmp);\n\t\t  concat_name =\n\t\t    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);\n\t\t  memcpy (concat_name, tmp, tmp_len);\n\t\t  concat_name[tmp_len] = '/';\n\t\t  strcpy (concat_name + tmp_len + 1, wrapper);\n\t\t}\n\t      else\n\t\t{\n\t\t  concat_name =\n\t\t    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);\n\t\t  memcpy (concat_name, p, p_len);\n\t\t  concat_name[p_len] = '/';\n\t\t  strcpy (concat_name + p_len + 1, wrapper);\n\t\t}\n\t      if (check_executable (concat_name))\n\t\treturn concat_name;\n\t      XFREE (concat_name);\n\t    }\n\t}\n      /* not found in PATH; assume curdir */\n    }\n  /* Relative path | not found in path: prepend cwd */\n  if (getcwd (tmp, LT_PATHMAX) == NULL)\n    lt_fatal (\"getcwd failed\");\n  tmp_len = strlen (tmp);\n  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);\n  memcpy (concat_name, tmp, tmp_len);\n  concat_name[tmp_len] = '/';\n  strcpy (concat_name + tmp_len + 1, wrapper);\n\n  if (check_executable (concat_name))\n    return concat_name;\n  XFREE (concat_name);\n  return NULL;\n}\n\nchar *\nchase_symlinks (const char *pathspec)\n{\n#ifndef S_ISLNK\n  return xstrdup (pathspec);\n#else\n  char buf[LT_PATHMAX];\n  struct stat s;\n  char *tmp_pathspec = xstrdup (pathspec);\n  char *p;\n  int has_symlinks = 0;\n  while (strlen (tmp_pathspec) && !has_symlinks)\n    {\n      LTWRAPPER_DEBUGPRINTF ((\"checking path component for symlinks: %s\\n\",\n\t\t\t      tmp_pathspec));\n      if (lstat (tmp_pathspec, &s) == 0)\n\t{\n\t  if (S_ISLNK (s.st_mode) != 0)\n\t    {\n\t      has_symlinks = 1;\n\t      break;\n\t    }\n\n\t  /* search backwards for last DIR_SEPARATOR */\n\t  p = tmp_pathspec + strlen (tmp_pathspec) - 1;\n\t  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))\n\t    p--;\n\t  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))\n\t    {\n\t      /* no more DIR_SEPARATORS left */\n\t      break;\n\t    }\n\t  *p = '\\0';\n\t}\n      else\n\t{\n\t  char *errstr = strerror (errno);\n\t  lt_fatal (\"Error accessing file %s (%s)\", tmp_pathspec, errstr);\n\t}\n    }\n  XFREE (tmp_pathspec);\n\n  if (!has_symlinks)\n    {\n      return xstrdup (pathspec);\n    }\n\n  tmp_pathspec = realpath (pathspec, buf);\n  if (tmp_pathspec == 0)\n    {\n      lt_fatal (\"Could not follow symlinks for %s\", pathspec);\n    }\n  return xstrdup (tmp_pathspec);\n#endif\n}\n\nchar *\nstrendzap (char *str, const char *pat)\n{\n  size_t len, patlen;\n\n  assert (str != NULL);\n  assert (pat != NULL);\n\n  len = strlen (str);\n  patlen = strlen (pat);\n\n  if (patlen <= len)\n    {\n      str += len - patlen;\n      if (strcmp (str, pat) == 0)\n\t*str = '\\0';\n    }\n  return str;\n}\n\nstatic void\nlt_error_core (int exit_status, const char *mode,\n\t       const char *message, va_list ap)\n{\n  fprintf (stderr, \"%s: %s: \", program_name, mode);\n  vfprintf (stderr, message, ap);\n  fprintf (stderr, \".\\n\");\n\n  if (exit_status >= 0)\n    exit (exit_status);\n}\n\nvoid\nlt_fatal (const char *message, ...)\n{\n  va_list ap;\n  va_start (ap, message);\n  lt_error_core (EXIT_FAILURE, \"FATAL\", message, ap);\n  va_end (ap);\n}\n\nvoid\nlt_setenv (const char *name, const char *value)\n{\n  LTWRAPPER_DEBUGPRINTF ((\"(lt_setenv) setting '%s' to '%s'\\n\",\n                          (name ? name : \"<NULL>\"),\n                          (value ? value : \"<NULL>\")));\n  {\n#ifdef HAVE_SETENV\n    /* always make a copy, for consistency with !HAVE_SETENV */\n    char *str = xstrdup (value);\n    setenv (name, str, 1);\n#else\n    int len = strlen (name) + 1 + strlen (value) + 1;\n    char *str = XMALLOC (char, len);\n    sprintf (str, \"%s=%s\", name, value);\n    if (putenv (str) != EXIT_SUCCESS)\n      {\n        XFREE (str);\n      }\n#endif\n  }\n}\n\nchar *\nlt_extend_str (const char *orig_value, const char *add, int to_end)\n{\n  char *new_value;\n  if (orig_value && *orig_value)\n    {\n      int orig_value_len = strlen (orig_value);\n      int add_len = strlen (add);\n      new_value = XMALLOC (char, add_len + orig_value_len + 1);\n      if (to_end)\n        {\n          strcpy (new_value, orig_value);\n          strcpy (new_value + orig_value_len, add);\n        }\n      else\n        {\n          strcpy (new_value, add);\n          strcpy (new_value + add_len, orig_value);\n        }\n    }\n  else\n    {\n      new_value = xstrdup (add);\n    }\n  return new_value;\n}\n\nint\nlt_split_name_value (const char *arg, char** name, char** value)\n{\n  const char *p;\n  int len;\n  if (!arg || !*arg)\n    return 1;\n\n  p = strchr (arg, (int)'=');\n\n  if (!p)\n    return 1;\n\n  *value = xstrdup (++p);\n\n  len = strlen (arg) - strlen (*value);\n  *name = XMALLOC (char, len);\n  strncpy (*name, arg, len-1);\n  (*name)[len - 1] = '\\0';\n\n  return 0;\n}\n\nvoid\nlt_opt_process_env_set (const char *arg)\n{\n  char *name = NULL;\n  char *value = NULL;\n\n  if (lt_split_name_value (arg, &name, &value) != 0)\n    {\n      XFREE (name);\n      XFREE (value);\n      lt_fatal (\"bad argument for %s: '%s'\", env_set_opt, arg);\n    }\n\n  lt_setenv (name, value);\n  XFREE (name);\n  XFREE (value);\n}\n\nvoid\nlt_opt_process_env_prepend (const char *arg)\n{\n  char *name = NULL;\n  char *value = NULL;\n  char *new_value = NULL;\n\n  if (lt_split_name_value (arg, &name, &value) != 0)\n    {\n      XFREE (name);\n      XFREE (value);\n      lt_fatal (\"bad argument for %s: '%s'\", env_prepend_opt, arg);\n    }\n\n  new_value = lt_extend_str (getenv (name), value, 0);\n  lt_setenv (name, new_value);\n  XFREE (new_value);\n  XFREE (name);\n  XFREE (value);\n}\n\nvoid\nlt_opt_process_env_append (const char *arg)\n{\n  char *name = NULL;\n  char *value = NULL;\n  char *new_value = NULL;\n\n  if (lt_split_name_value (arg, &name, &value) != 0)\n    {\n      XFREE (name);\n      XFREE (value);\n      lt_fatal (\"bad argument for %s: '%s'\", env_append_opt, arg);\n    }\n\n  new_value = lt_extend_str (getenv (name), value, 1);\n  lt_setenv (name, new_value);\n  XFREE (new_value);\n  XFREE (name);\n  XFREE (value);\n}\n\nvoid\nlt_update_exe_path (const char *name, const char *value)\n{\n  LTWRAPPER_DEBUGPRINTF ((\"(lt_update_exe_path) modifying '%s' by prepending '%s'\\n\",\n                          (name ? name : \"<NULL>\"),\n                          (value ? value : \"<NULL>\")));\n\n  if (name && *name && value && *value)\n    {\n      char *new_value = lt_extend_str (getenv (name), value, 0);\n      /* some systems can't cope with a ':'-terminated path #' */\n      int len = strlen (new_value);\n      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))\n        {\n          new_value[len-1] = '\\0';\n        }\n      lt_setenv (name, new_value);\n      XFREE (new_value);\n    }\n}\n\nvoid\nlt_update_lib_path (const char *name, const char *value)\n{\n  LTWRAPPER_DEBUGPRINTF ((\"(lt_update_lib_path) modifying '%s' by prepending '%s'\\n\",\n                          (name ? name : \"<NULL>\"),\n                          (value ? value : \"<NULL>\")));\n\n  if (name && *name && value && *value)\n    {\n      char *new_value = lt_extend_str (getenv (name), value, 0);\n      lt_setenv (name, new_value);\n      XFREE (new_value);\n    }\n}\n\n\nEOF\n}\n# end: func_emit_cwrapperexe_src\n\n# func_mode_link arg...\nfunc_mode_link ()\n{\n    $opt_debug\n    case $host in\n    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n      # It is impossible to link a dll without this setting, and\n      # we shouldn't force the makefile maintainer to figure out\n      # which system we are compiling for in order to pass an extra\n      # flag for every libtool invocation.\n      # allow_undefined=no\n\n      # FIXME: Unfortunately, there are problems with the above when trying\n      # to make a dll which has undefined symbols, in which case not\n      # even a static library is built.  For now, we need to specify\n      # -no-undefined on the libtool link line when we can be certain\n      # that all symbols are satisfied, otherwise we get a static library.\n      allow_undefined=yes\n      ;;\n    *)\n      allow_undefined=yes\n      ;;\n    esac\n    libtool_args=$nonopt\n    base_compile=\"$nonopt $@\"\n    compile_command=$nonopt\n    finalize_command=$nonopt\n\n    compile_rpath=\n    finalize_rpath=\n    compile_shlibpath=\n    finalize_shlibpath=\n    convenience=\n    old_convenience=\n    deplibs=\n    old_deplibs=\n    compiler_flags=\n    linker_flags=\n    dllsearchpath=\n    lib_search_path=`pwd`\n    inst_prefix_dir=\n    new_inherited_linker_flags=\n\n    avoid_version=no\n    dlfiles=\n    dlprefiles=\n    dlself=no\n    export_dynamic=no\n    export_symbols=\n    export_symbols_regex=\n    generated=\n    libobjs=\n    ltlibs=\n    module=no\n    no_install=no\n    objs=\n    non_pic_objects=\n    precious_files_regex=\n    prefer_static_libs=no\n    preload=no\n    prev=\n    prevarg=\n    release=\n    rpath=\n    xrpath=\n    perm_rpath=\n    temp_rpath=\n    thread_safe=no\n    vinfo=\n    vinfo_number=no\n    weak_libs=\n    single_module=\"${wl}-single_module\"\n    func_infer_tag $base_compile\n\n    # We need to know -static, to get the right output filenames.\n    for arg\n    do\n      case $arg in\n      -shared)\n\ttest \"$build_libtool_libs\" != yes && \\\n\t  func_fatal_configuration \"can not build a shared library\"\n\tbuild_old_libs=no\n\tbreak\n\t;;\n      -all-static | -static | -static-libtool-libs)\n\tcase $arg in\n\t-all-static)\n\t  if test \"$build_libtool_libs\" = yes && test -z \"$link_static_flag\"; then\n\t    func_warning \"complete static linking is impossible in this configuration\"\n\t  fi\n\t  if test -n \"$link_static_flag\"; then\n\t    dlopen_self=$dlopen_self_static\n\t  fi\n\t  prefer_static_libs=yes\n\t  ;;\n\t-static)\n\t  if test -z \"$pic_flag\" && test -n \"$link_static_flag\"; then\n\t    dlopen_self=$dlopen_self_static\n\t  fi\n\t  prefer_static_libs=built\n\t  ;;\n\t-static-libtool-libs)\n\t  if test -z \"$pic_flag\" && test -n \"$link_static_flag\"; then\n\t    dlopen_self=$dlopen_self_static\n\t  fi\n\t  prefer_static_libs=yes\n\t  ;;\n\tesac\n\tbuild_libtool_libs=no\n\tbuild_old_libs=yes\n\tbreak\n\t;;\n      esac\n    done\n\n    # See if our shared archives depend on static archives.\n    test -n \"$old_archive_from_new_cmds\" && build_old_libs=yes\n\n    # Go through the arguments, transforming them on the way.\n    while test \"$#\" -gt 0; do\n      arg=\"$1\"\n      shift\n      func_quote_for_eval \"$arg\"\n      qarg=$func_quote_for_eval_unquoted_result\n      func_append libtool_args \" $func_quote_for_eval_result\"\n\n      # If the previous option needs an argument, assign it.\n      if test -n \"$prev\"; then\n\tcase $prev in\n\toutput)\n\t  func_append compile_command \" @OUTPUT@\"\n\t  func_append finalize_command \" @OUTPUT@\"\n\t  ;;\n\tesac\n\n\tcase $prev in\n\tdlfiles|dlprefiles)\n\t  if test \"$preload\" = no; then\n\t    # Add the symbol object into the linking commands.\n\t    func_append compile_command \" @SYMFILE@\"\n\t    func_append finalize_command \" @SYMFILE@\"\n\t    preload=yes\n\t  fi\n\t  case $arg in\n\t  *.la | *.lo) ;;  # We handle these cases below.\n\t  force)\n\t    if test \"$dlself\" = no; then\n\t      dlself=needless\n\t      export_dynamic=yes\n\t    fi\n\t    prev=\n\t    continue\n\t    ;;\n\t  self)\n\t    if test \"$prev\" = dlprefiles; then\n\t      dlself=yes\n\t    elif test \"$prev\" = dlfiles && test \"$dlopen_self\" != yes; then\n\t      dlself=yes\n\t    else\n\t      dlself=needless\n\t      export_dynamic=yes\n\t    fi\n\t    prev=\n\t    continue\n\t    ;;\n\t  *)\n\t    if test \"$prev\" = dlfiles; then\n\t      dlfiles=\"$dlfiles $arg\"\n\t    else\n\t      dlprefiles=\"$dlprefiles $arg\"\n\t    fi\n\t    prev=\n\t    continue\n\t    ;;\n\t  esac\n\t  ;;\n\texpsyms)\n\t  export_symbols=\"$arg\"\n\t  test -f \"$arg\" \\\n\t    || func_fatal_error \"symbol file \\`$arg' does not exist\"\n\t  prev=\n\t  continue\n\t  ;;\n\texpsyms_regex)\n\t  export_symbols_regex=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\tframework)\n\t  case $host in\n\t    *-*-darwin*)\n\t      case \"$deplibs \" in\n\t\t*\" $qarg.ltframework \"*) ;;\n\t\t*) deplibs=\"$deplibs $qarg.ltframework\" # this is fixed later\n\t\t   ;;\n\t      esac\n\t      ;;\n\t  esac\n\t  prev=\n\t  continue\n\t  ;;\n\tinst_prefix)\n\t  inst_prefix_dir=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\tobjectlist)\n\t  if test -f \"$arg\"; then\n\t    save_arg=$arg\n\t    moreargs=\n\t    for fil in `cat \"$save_arg\"`\n\t    do\n#\t      moreargs=\"$moreargs $fil\"\n\t      arg=$fil\n\t      # A libtool-controlled object.\n\n\t      # Check to see that this really is a libtool object.\n\t      if func_lalib_unsafe_p \"$arg\"; then\n\t\tpic_object=\n\t\tnon_pic_object=\n\n\t\t# Read the .lo file\n\t\tfunc_source \"$arg\"\n\n\t\tif test -z \"$pic_object\" ||\n\t\t   test -z \"$non_pic_object\" ||\n\t\t   test \"$pic_object\" = none &&\n\t\t   test \"$non_pic_object\" = none; then\n\t\t  func_fatal_error \"cannot find name of object for \\`$arg'\"\n\t\tfi\n\n\t\t# Extract subdirectory from the argument.\n\t\tfunc_dirname \"$arg\" \"/\" \"\"\n\t\txdir=\"$func_dirname_result\"\n\n\t\tif test \"$pic_object\" != none; then\n\t\t  # Prepend the subdirectory the object is found in.\n\t\t  pic_object=\"$xdir$pic_object\"\n\n\t\t  if test \"$prev\" = dlfiles; then\n\t\t    if test \"$build_libtool_libs\" = yes && test \"$dlopen_support\" = yes; then\n\t\t      dlfiles=\"$dlfiles $pic_object\"\n\t\t      prev=\n\t\t      continue\n\t\t    else\n\t\t      # If libtool objects are unsupported, then we need to preload.\n\t\t      prev=dlprefiles\n\t\t    fi\n\t\t  fi\n\n\t\t  # CHECK ME:  I think I busted this.  -Ossama\n\t\t  if test \"$prev\" = dlprefiles; then\n\t\t    # Preload the old-style object.\n\t\t    dlprefiles=\"$dlprefiles $pic_object\"\n\t\t    prev=\n\t\t  fi\n\n\t\t  # A PIC object.\n\t\t  func_append libobjs \" $pic_object\"\n\t\t  arg=\"$pic_object\"\n\t\tfi\n\n\t\t# Non-PIC object.\n\t\tif test \"$non_pic_object\" != none; then\n\t\t  # Prepend the subdirectory the object is found in.\n\t\t  non_pic_object=\"$xdir$non_pic_object\"\n\n\t\t  # A standard non-PIC object\n\t\t  func_append non_pic_objects \" $non_pic_object\"\n\t\t  if test -z \"$pic_object\" || test \"$pic_object\" = none ; then\n\t\t    arg=\"$non_pic_object\"\n\t\t  fi\n\t\telse\n\t\t  # If the PIC object exists, use it instead.\n\t\t  # $xdir was prepended to $pic_object above.\n\t\t  non_pic_object=\"$pic_object\"\n\t\t  func_append non_pic_objects \" $non_pic_object\"\n\t\tfi\n\t      else\n\t\t# Only an error if not doing a dry-run.\n\t\tif $opt_dry_run; then\n\t\t  # Extract subdirectory from the argument.\n\t\t  func_dirname \"$arg\" \"/\" \"\"\n\t\t  xdir=\"$func_dirname_result\"\n\n\t\t  func_lo2o \"$arg\"\n\t\t  pic_object=$xdir$objdir/$func_lo2o_result\n\t\t  non_pic_object=$xdir$func_lo2o_result\n\t\t  func_append libobjs \" $pic_object\"\n\t\t  func_append non_pic_objects \" $non_pic_object\"\n\t        else\n\t\t  func_fatal_error \"\\`$arg' is not a valid libtool object\"\n\t\tfi\n\t      fi\n\t    done\n\t  else\n\t    func_fatal_error \"link input file \\`$arg' does not exist\"\n\t  fi\n\t  arg=$save_arg\n\t  prev=\n\t  continue\n\t  ;;\n\tprecious_regex)\n\t  precious_files_regex=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\trelease)\n\t  release=\"-$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\trpath | xrpath)\n\t  # We need an absolute path.\n\t  case $arg in\n\t  [\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n\t  *)\n\t    func_fatal_error \"only absolute run-paths are allowed\"\n\t    ;;\n\t  esac\n\t  if test \"$prev\" = rpath; then\n\t    case \"$rpath \" in\n\t    *\" $arg \"*) ;;\n\t    *) rpath=\"$rpath $arg\" ;;\n\t    esac\n\t  else\n\t    case \"$xrpath \" in\n\t    *\" $arg \"*) ;;\n\t    *) xrpath=\"$xrpath $arg\" ;;\n\t    esac\n\t  fi\n\t  prev=\n\t  continue\n\t  ;;\n\tshrext)\n\t  shrext_cmds=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\tweak)\n\t  weak_libs=\"$weak_libs $arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\txcclinker)\n\t  linker_flags=\"$linker_flags $qarg\"\n\t  compiler_flags=\"$compiler_flags $qarg\"\n\t  prev=\n\t  func_append compile_command \" $qarg\"\n\t  func_append finalize_command \" $qarg\"\n\t  continue\n\t  ;;\n\txcompiler)\n\t  compiler_flags=\"$compiler_flags $qarg\"\n\t  prev=\n\t  func_append compile_command \" $qarg\"\n\t  func_append finalize_command \" $qarg\"\n\t  continue\n\t  ;;\n\txlinker)\n\t  linker_flags=\"$linker_flags $qarg\"\n\t  compiler_flags=\"$compiler_flags $wl$qarg\"\n\t  prev=\n\t  func_append compile_command \" $wl$qarg\"\n\t  func_append finalize_command \" $wl$qarg\"\n\t  continue\n\t  ;;\n\t*)\n\t  eval \"$prev=\\\"\\$arg\\\"\"\n\t  prev=\n\t  continue\n\t  ;;\n\tesac\n      fi # test -n \"$prev\"\n\n      prevarg=\"$arg\"\n\n      case $arg in\n      -all-static)\n\tif test -n \"$link_static_flag\"; then\n\t  # See comment for -static flag below, for more details.\n\t  func_append compile_command \" $link_static_flag\"\n\t  func_append finalize_command \" $link_static_flag\"\n\tfi\n\tcontinue\n\t;;\n\n      -allow-undefined)\n\t# FIXME: remove this flag sometime in the future.\n\tfunc_fatal_error \"\\`-allow-undefined' must not be used because it is the default\"\n\t;;\n\n      -avoid-version)\n\tavoid_version=yes\n\tcontinue\n\t;;\n\n      -dlopen)\n\tprev=dlfiles\n\tcontinue\n\t;;\n\n      -dlpreopen)\n\tprev=dlprefiles\n\tcontinue\n\t;;\n\n      -export-dynamic)\n\texport_dynamic=yes\n\tcontinue\n\t;;\n\n      -export-symbols | -export-symbols-regex)\n\tif test -n \"$export_symbols\" || test -n \"$export_symbols_regex\"; then\n\t  func_fatal_error \"more than one -exported-symbols argument is not allowed\"\n\tfi\n\tif test \"X$arg\" = \"X-export-symbols\"; then\n\t  prev=expsyms\n\telse\n\t  prev=expsyms_regex\n\tfi\n\tcontinue\n\t;;\n\n      -framework)\n\tprev=framework\n\tcontinue\n\t;;\n\n      -inst-prefix-dir)\n\tprev=inst_prefix\n\tcontinue\n\t;;\n\n      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*\n      # so, if we see these flags be careful not to treat them like -L\n      -L[A-Z][A-Z]*:*)\n\tcase $with_gcc/$host in\n\tno/*-*-irix* | /*-*-irix*)\n\t  func_append compile_command \" $arg\"\n\t  func_append finalize_command \" $arg\"\n\t  ;;\n\tesac\n\tcontinue\n\t;;\n\n      -L*)\n\tfunc_stripname '-L' '' \"$arg\"\n\tdir=$func_stripname_result\n\tif test -z \"$dir\"; then\n\t  if test \"$#\" -gt 0; then\n\t    func_fatal_error \"require no space between \\`-L' and \\`$1'\"\n\t  else\n\t    func_fatal_error \"need path for \\`-L' option\"\n\t  fi\n\tfi\n\t# We need an absolute path.\n\tcase $dir in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n\t*)\n\t  absdir=`cd \"$dir\" && pwd`\n\t  test -z \"$absdir\" && \\\n\t    func_fatal_error \"cannot determine absolute directory name of \\`$dir'\"\n\t  dir=\"$absdir\"\n\t  ;;\n\tesac\n\tcase \"$deplibs \" in\n\t*\" -L$dir \"*) ;;\n\t*)\n\t  deplibs=\"$deplibs -L$dir\"\n\t  lib_search_path=\"$lib_search_path $dir\"\n\t  ;;\n\tesac\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n\t  testbindir=`$ECHO \"X$dir\" | $Xsed -e 's*/lib$*/bin*'`\n\t  case :$dllsearchpath: in\n\t  *\":$dir:\"*) ;;\n\t  ::) dllsearchpath=$dir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$dir\";;\n\t  esac\n\t  case :$dllsearchpath: in\n\t  *\":$testbindir:\"*) ;;\n\t  ::) dllsearchpath=$testbindir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$testbindir\";;\n\t  esac\n\t  ;;\n\tesac\n\tcontinue\n\t;;\n\n      -l*)\n\tif test \"X$arg\" = \"X-lc\" || test \"X$arg\" = \"X-lm\"; then\n\t  case $host in\n\t  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)\n\t    # These systems don't actually have a C or math library (as such)\n\t    continue\n\t    ;;\n\t  *-*-os2*)\n\t    # These systems don't actually have a C library (as such)\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)\n\t    # Do not include libc due to us having libc/libc_r.\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  *-*-rhapsody* | *-*-darwin1.[012])\n\t    # Rhapsody C and math libraries are in the System framework\n\t    deplibs=\"$deplibs System.ltframework\"\n\t    continue\n\t    ;;\n\t  *-*-sco3.2v5* | *-*-sco5v6*)\n\t    # Causes problems with __ctype\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)\n\t    # Compiler inserts libc in the correct place for threads to work\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  esac\n\telif test \"X$arg\" = \"X-lc_r\"; then\n\t case $host in\n\t *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)\n\t   # Do not include libc_r directly, use -pthread flag.\n\t   continue\n\t   ;;\n\t esac\n\tfi\n\tdeplibs=\"$deplibs $arg\"\n\tcontinue\n\t;;\n\n      -module)\n\tmodule=yes\n\tcontinue\n\t;;\n\n      # Tru64 UNIX uses -model [arg] to determine the layout of C++\n      # classes, name mangling, and exception handling.\n      # Darwin uses the -arch flag to determine output architecture.\n      -model|-arch|-isysroot)\n\tcompiler_flags=\"$compiler_flags $arg\"\n\tfunc_append compile_command \" $arg\"\n\tfunc_append finalize_command \" $arg\"\n\tprev=xcompiler\n\tcontinue\n\t;;\n\n      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)\n\tcompiler_flags=\"$compiler_flags $arg\"\n\tfunc_append compile_command \" $arg\"\n\tfunc_append finalize_command \" $arg\"\n\tcase \"$new_inherited_linker_flags \" in\n\t    *\" $arg \"*) ;;\n\t    * ) new_inherited_linker_flags=\"$new_inherited_linker_flags $arg\" ;;\n\tesac\n\tcontinue\n\t;;\n\n      -multi_module)\n\tsingle_module=\"${wl}-multi_module\"\n\tcontinue\n\t;;\n\n      -no-fast-install)\n\tfast_install=no\n\tcontinue\n\t;;\n\n      -no-install)\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)\n\t  # The PATH hackery in wrapper scripts is required on Windows\n\t  # and Darwin in order for the loader to find any dlls it needs.\n\t  func_warning \"\\`-no-install' is ignored for $host\"\n\t  func_warning \"assuming \\`-no-fast-install' instead\"\n\t  fast_install=no\n\t  ;;\n\t*) no_install=yes ;;\n\tesac\n\tcontinue\n\t;;\n\n      -no-undefined)\n\tallow_undefined=no\n\tcontinue\n\t;;\n\n      -objectlist)\n\tprev=objectlist\n\tcontinue\n\t;;\n\n      -o) prev=output ;;\n\n      -precious-files-regex)\n\tprev=precious_regex\n\tcontinue\n\t;;\n\n      -release)\n\tprev=release\n\tcontinue\n\t;;\n\n      -rpath)\n\tprev=rpath\n\tcontinue\n\t;;\n\n      -R)\n\tprev=xrpath\n\tcontinue\n\t;;\n\n      -R*)\n\tfunc_stripname '-R' '' \"$arg\"\n\tdir=$func_stripname_result\n\t# We need an absolute path.\n\tcase $dir in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n\t*)\n\t  func_fatal_error \"only absolute run-paths are allowed\"\n\t  ;;\n\tesac\n\tcase \"$xrpath \" in\n\t*\" $dir \"*) ;;\n\t*) xrpath=\"$xrpath $dir\" ;;\n\tesac\n\tcontinue\n\t;;\n\n      -shared)\n\t# The effects of -shared are defined in a previous loop.\n\tcontinue\n\t;;\n\n      -shrext)\n\tprev=shrext\n\tcontinue\n\t;;\n\n      -static | -static-libtool-libs)\n\t# The effects of -static are defined in a previous loop.\n\t# We used to do the same as -all-static on platforms that\n\t# didn't have a PIC flag, but the assumption that the effects\n\t# would be equivalent was wrong.  It would break on at least\n\t# Digital Unix and AIX.\n\tcontinue\n\t;;\n\n      -thread-safe)\n\tthread_safe=yes\n\tcontinue\n\t;;\n\n      -version-info)\n\tprev=vinfo\n\tcontinue\n\t;;\n\n      -version-number)\n\tprev=vinfo\n\tvinfo_number=yes\n\tcontinue\n\t;;\n\n      -weak)\n        prev=weak\n\tcontinue\n\t;;\n\n      -Wc,*)\n\tfunc_stripname '-Wc,' '' \"$arg\"\n\targs=$func_stripname_result\n\targ=\n\tsave_ifs=\"$IFS\"; IFS=','\n\tfor flag in $args; do\n\t  IFS=\"$save_ifs\"\n          func_quote_for_eval \"$flag\"\n\t  arg=\"$arg $wl$func_quote_for_eval_result\"\n\t  compiler_flags=\"$compiler_flags $func_quote_for_eval_result\"\n\tdone\n\tIFS=\"$save_ifs\"\n\tfunc_stripname ' ' '' \"$arg\"\n\targ=$func_stripname_result\n\t;;\n\n      -Wl,*)\n\tfunc_stripname '-Wl,' '' \"$arg\"\n\targs=$func_stripname_result\n\targ=\n\tsave_ifs=\"$IFS\"; IFS=','\n\tfor flag in $args; do\n\t  IFS=\"$save_ifs\"\n          func_quote_for_eval \"$flag\"\n\t  arg=\"$arg $wl$func_quote_for_eval_result\"\n\t  compiler_flags=\"$compiler_flags $wl$func_quote_for_eval_result\"\n\t  linker_flags=\"$linker_flags $func_quote_for_eval_result\"\n\tdone\n\tIFS=\"$save_ifs\"\n\tfunc_stripname ' ' '' \"$arg\"\n\targ=$func_stripname_result\n\t;;\n\n      -Xcompiler)\n\tprev=xcompiler\n\tcontinue\n\t;;\n\n      -Xlinker)\n\tprev=xlinker\n\tcontinue\n\t;;\n\n      -XCClinker)\n\tprev=xcclinker\n\tcontinue\n\t;;\n\n      # -msg_* for osf cc\n      -msg_*)\n\tfunc_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n\t;;\n\n      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler\n      # -r[0-9][0-9]* specifies the processor on the SGI compiler\n      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler\n      # +DA*, +DD* enable 64-bit mode on the HP compiler\n      # -q* pass through compiler args for the IBM compiler\n      # -m*, -t[45]*, -txscale* pass through architecture-specific\n      # compiler args for GCC\n      # -F/path gives path to uninstalled frameworks, gcc on darwin\n      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC\n      # @file GCC response files\n      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \\\n      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)\n        func_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n        func_append compile_command \" $arg\"\n        func_append finalize_command \" $arg\"\n        compiler_flags=\"$compiler_flags $arg\"\n        continue\n        ;;\n\n      # Some other compiler flag.\n      -* | +*)\n        func_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n\t;;\n\n      *.$objext)\n\t# A standard object.\n\tobjs=\"$objs $arg\"\n\t;;\n\n      *.lo)\n\t# A libtool-controlled object.\n\n\t# Check to see that this really is a libtool object.\n\tif func_lalib_unsafe_p \"$arg\"; then\n\t  pic_object=\n\t  non_pic_object=\n\n\t  # Read the .lo file\n\t  func_source \"$arg\"\n\n\t  if test -z \"$pic_object\" ||\n\t     test -z \"$non_pic_object\" ||\n\t     test \"$pic_object\" = none &&\n\t     test \"$non_pic_object\" = none; then\n\t    func_fatal_error \"cannot find name of object for \\`$arg'\"\n\t  fi\n\n\t  # Extract subdirectory from the argument.\n\t  func_dirname \"$arg\" \"/\" \"\"\n\t  xdir=\"$func_dirname_result\"\n\n\t  if test \"$pic_object\" != none; then\n\t    # Prepend the subdirectory the object is found in.\n\t    pic_object=\"$xdir$pic_object\"\n\n\t    if test \"$prev\" = dlfiles; then\n\t      if test \"$build_libtool_libs\" = yes && test \"$dlopen_support\" = yes; then\n\t\tdlfiles=\"$dlfiles $pic_object\"\n\t\tprev=\n\t\tcontinue\n\t      else\n\t\t# If libtool objects are unsupported, then we need to preload.\n\t\tprev=dlprefiles\n\t      fi\n\t    fi\n\n\t    # CHECK ME:  I think I busted this.  -Ossama\n\t    if test \"$prev\" = dlprefiles; then\n\t      # Preload the old-style object.\n\t      dlprefiles=\"$dlprefiles $pic_object\"\n\t      prev=\n\t    fi\n\n\t    # A PIC object.\n\t    func_append libobjs \" $pic_object\"\n\t    arg=\"$pic_object\"\n\t  fi\n\n\t  # Non-PIC object.\n\t  if test \"$non_pic_object\" != none; then\n\t    # Prepend the subdirectory the object is found in.\n\t    non_pic_object=\"$xdir$non_pic_object\"\n\n\t    # A standard non-PIC object\n\t    func_append non_pic_objects \" $non_pic_object\"\n\t    if test -z \"$pic_object\" || test \"$pic_object\" = none ; then\n\t      arg=\"$non_pic_object\"\n\t    fi\n\t  else\n\t    # If the PIC object exists, use it instead.\n\t    # $xdir was prepended to $pic_object above.\n\t    non_pic_object=\"$pic_object\"\n\t    func_append non_pic_objects \" $non_pic_object\"\n\t  fi\n\telse\n\t  # Only an error if not doing a dry-run.\n\t  if $opt_dry_run; then\n\t    # Extract subdirectory from the argument.\n\t    func_dirname \"$arg\" \"/\" \"\"\n\t    xdir=\"$func_dirname_result\"\n\n\t    func_lo2o \"$arg\"\n\t    pic_object=$xdir$objdir/$func_lo2o_result\n\t    non_pic_object=$xdir$func_lo2o_result\n\t    func_append libobjs \" $pic_object\"\n\t    func_append non_pic_objects \" $non_pic_object\"\n\t  else\n\t    func_fatal_error \"\\`$arg' is not a valid libtool object\"\n\t  fi\n\tfi\n\t;;\n\n      *.$libext)\n\t# An archive.\n\tdeplibs=\"$deplibs $arg\"\n\told_deplibs=\"$old_deplibs $arg\"\n\tcontinue\n\t;;\n\n      *.la)\n\t# A libtool-controlled library.\n\n\tif test \"$prev\" = dlfiles; then\n\t  # This library was specified with -dlopen.\n\t  dlfiles=\"$dlfiles $arg\"\n\t  prev=\n\telif test \"$prev\" = dlprefiles; then\n\t  # The library was specified with -dlpreopen.\n\t  dlprefiles=\"$dlprefiles $arg\"\n\t  prev=\n\telse\n\t  deplibs=\"$deplibs $arg\"\n\tfi\n\tcontinue\n\t;;\n\n      # Some other compiler argument.\n      *)\n\t# Unknown arguments in both finalize_command and compile_command need\n\t# to be aesthetically quoted because they are evaled later.\n\tfunc_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n\t;;\n      esac # arg\n\n      # Now actually substitute the argument into the commands.\n      if test -n \"$arg\"; then\n\tfunc_append compile_command \" $arg\"\n\tfunc_append finalize_command \" $arg\"\n      fi\n    done # argument parsing loop\n\n    test -n \"$prev\" && \\\n      func_fatal_help \"the \\`$prevarg' option requires an argument\"\n\n    if test \"$export_dynamic\" = yes && test -n \"$export_dynamic_flag_spec\"; then\n      eval arg=\\\"$export_dynamic_flag_spec\\\"\n      func_append compile_command \" $arg\"\n      func_append finalize_command \" $arg\"\n    fi\n\n    oldlibs=\n    # calculate the name of the file, without its directory\n    func_basename \"$output\"\n    outputname=\"$func_basename_result\"\n    libobjs_save=\"$libobjs\"\n\n    if test -n \"$shlibpath_var\"; then\n      # get the directories listed in $shlibpath_var\n      eval shlib_search_path=\\`\\$ECHO \\\"X\\${$shlibpath_var}\\\" \\| \\$Xsed -e \\'s/:/ /g\\'\\`\n    else\n      shlib_search_path=\n    fi\n    eval sys_lib_search_path=\\\"$sys_lib_search_path_spec\\\"\n    eval sys_lib_dlsearch_path=\\\"$sys_lib_dlsearch_path_spec\\\"\n\n    func_dirname \"$output\" \"/\" \"\"\n    output_objdir=\"$func_dirname_result$objdir\"\n    # Create the object directory.\n    func_mkdir_p \"$output_objdir\"\n\n    # Determine the type of output\n    case $output in\n    \"\")\n      func_fatal_help \"you must specify an output file\"\n      ;;\n    *.$libext) linkmode=oldlib ;;\n    *.lo | *.$objext) linkmode=obj ;;\n    *.la) linkmode=lib ;;\n    *) linkmode=prog ;; # Anything else should be a program.\n    esac\n\n    specialdeplibs=\n\n    libs=\n    # Find all interdependent deplibs by searching for libraries\n    # that are linked more than once (e.g. -la -lb -la)\n    for deplib in $deplibs; do\n      if $opt_duplicate_deps ; then\n\tcase \"$libs \" in\n\t*\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\tesac\n      fi\n      libs=\"$libs $deplib\"\n    done\n\n    if test \"$linkmode\" = lib; then\n      libs=\"$predeps $libs $compiler_lib_search_path $postdeps\"\n\n      # Compute libraries that are listed more than once in $predeps\n      # $postdeps and mark them as special (i.e., whose duplicates are\n      # not to be eliminated).\n      pre_post_deps=\n      if $opt_duplicate_compiler_generated_deps; then\n\tfor pre_post_dep in $predeps $postdeps; do\n\t  case \"$pre_post_deps \" in\n\t  *\" $pre_post_dep \"*) specialdeplibs=\"$specialdeplibs $pre_post_deps\" ;;\n\t  esac\n\t  pre_post_deps=\"$pre_post_deps $pre_post_dep\"\n\tdone\n      fi\n      pre_post_deps=\n    fi\n\n    deplibs=\n    newdependency_libs=\n    newlib_search_path=\n    need_relink=no # whether we're linking any uninstalled libtool libraries\n    notinst_deplibs= # not-installed libtool libraries\n    notinst_path= # paths that contain not-installed libtool libraries\n\n    case $linkmode in\n    lib)\n\tpasses=\"conv dlpreopen link\"\n\tfor file in $dlfiles $dlprefiles; do\n\t  case $file in\n\t  *.la) ;;\n\t  *)\n\t    func_fatal_help \"libraries can \\`-dlopen' only libtool libraries: $file\"\n\t    ;;\n\t  esac\n\tdone\n\t;;\n    prog)\n\tcompile_deplibs=\n\tfinalize_deplibs=\n\talldeplibs=no\n\tnewdlfiles=\n\tnewdlprefiles=\n\tpasses=\"conv scan dlopen dlpreopen link\"\n\t;;\n    *)  passes=\"conv\"\n\t;;\n    esac\n\n    for pass in $passes; do\n      # The preopen pass in lib mode reverses $deplibs; put it back here\n      # so that -L comes before libs that need it for instance...\n      if test \"$linkmode,$pass\" = \"lib,link\"; then\n\t## FIXME: Find the place where the list is rebuilt in the wrong\n\t##        order, and fix it there properly\n        tmp_deplibs=\n\tfor deplib in $deplibs; do\n\t  tmp_deplibs=\"$deplib $tmp_deplibs\"\n\tdone\n\tdeplibs=\"$tmp_deplibs\"\n      fi\n\n      if test \"$linkmode,$pass\" = \"lib,link\" ||\n\t test \"$linkmode,$pass\" = \"prog,scan\"; then\n\tlibs=\"$deplibs\"\n\tdeplibs=\n      fi\n      if test \"$linkmode\" = prog; then\n\tcase $pass in\n\tdlopen) libs=\"$dlfiles\" ;;\n\tdlpreopen) libs=\"$dlprefiles\" ;;\n\tlink)\n\t  libs=\"$deplibs %DEPLIBS%\"\n\t  test \"X$link_all_deplibs\" != Xno && libs=\"$libs $dependency_libs\"\n\t  ;;\n\tesac\n      fi\n      if test \"$linkmode,$pass\" = \"lib,dlpreopen\"; then\n\t# Collect and forward deplibs of preopened libtool libs\n\tfor lib in $dlprefiles; do\n\t  # Ignore non-libtool-libs\n\t  dependency_libs=\n\t  case $lib in\n\t  *.la)\tfunc_source \"$lib\" ;;\n\t  esac\n\n\t  # Collect preopened libtool deplibs, except any this library\n\t  # has declared as weak libs\n\t  for deplib in $dependency_libs; do\n            deplib_base=`$ECHO \"X$deplib\" | $Xsed -e \"$basename\"`\n\t    case \" $weak_libs \" in\n\t    *\" $deplib_base \"*) ;;\n\t    *) deplibs=\"$deplibs $deplib\" ;;\n\t    esac\n\t  done\n\tdone\n\tlibs=\"$dlprefiles\"\n      fi\n      if test \"$pass\" = dlopen; then\n\t# Collect dlpreopened libraries\n\tsave_deplibs=\"$deplibs\"\n\tdeplibs=\n      fi\n\n      for deplib in $libs; do\n\tlib=\n\tfound=no\n\tcase $deplib in\n\t-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)\n\t  if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t    compile_deplibs=\"$deplib $compile_deplibs\"\n\t    finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t  else\n\t    compiler_flags=\"$compiler_flags $deplib\"\n\t    if test \"$linkmode\" = lib ; then\n\t\tcase \"$new_inherited_linker_flags \" in\n\t\t    *\" $deplib \"*) ;;\n\t\t    * ) new_inherited_linker_flags=\"$new_inherited_linker_flags $deplib\" ;;\n\t\tesac\n\t    fi\n\t  fi\n\t  continue\n\t  ;;\n\t-l*)\n\t  if test \"$linkmode\" != lib && test \"$linkmode\" != prog; then\n\t    func_warning \"\\`-l' is ignored for archives/objects\"\n\t    continue\n\t  fi\n\t  func_stripname '-l' '' \"$deplib\"\n\t  name=$func_stripname_result\n\t  if test \"$linkmode\" = lib; then\n\t    searchdirs=\"$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path\"\n\t  else\n\t    searchdirs=\"$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path\"\n\t  fi\n\t  for searchdir in $searchdirs; do\n\t    for search_ext in .la $std_shrext .so .a; do\n\t      # Search the libtool library\n\t      lib=\"$searchdir/lib${name}${search_ext}\"\n\t      if test -f \"$lib\"; then\n\t\tif test \"$search_ext\" = \".la\"; then\n\t\t  found=yes\n\t\telse\n\t\t  found=no\n\t\tfi\n\t\tbreak 2\n\t      fi\n\t    done\n\t  done\n\t  if test \"$found\" != yes; then\n\t    # deplib doesn't seem to be a libtool library\n\t    if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    else\n\t      deplibs=\"$deplib $deplibs\"\n\t      test \"$linkmode\" = lib && newdependency_libs=\"$deplib $newdependency_libs\"\n\t    fi\n\t    continue\n\t  else # deplib is a libtool library\n\t    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,\n\t    # We need to do some special things here, and not later.\n\t    if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t      case \" $predeps $postdeps \" in\n\t      *\" $deplib \"*)\n\t\tif func_lalib_p \"$lib\"; then\n\t\t  library_names=\n\t\t  old_library=\n\t\t  func_source \"$lib\"\n\t\t  for l in $old_library $library_names; do\n\t\t    ll=\"$l\"\n\t\t  done\n\t\t  if test \"X$ll\" = \"X$old_library\" ; then # only static version available\n\t\t    found=no\n\t\t    func_dirname \"$lib\" \"\" \".\"\n\t\t    ladir=\"$func_dirname_result\"\n\t\t    lib=$ladir/$old_library\n\t\t    if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t\t    else\n\t\t      deplibs=\"$deplib $deplibs\"\n\t\t      test \"$linkmode\" = lib && newdependency_libs=\"$deplib $newdependency_libs\"\n\t\t    fi\n\t\t    continue\n\t\t  fi\n\t\tfi\n\t\t;;\n\t      *) ;;\n\t      esac\n\t    fi\n\t  fi\n\t  ;; # -l\n\t*.ltframework)\n\t  if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t    compile_deplibs=\"$deplib $compile_deplibs\"\n\t    finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t  else\n\t    deplibs=\"$deplib $deplibs\"\n\t    if test \"$linkmode\" = lib ; then\n\t\tcase \"$new_inherited_linker_flags \" in\n\t\t    *\" $deplib \"*) ;;\n\t\t    * ) new_inherited_linker_flags=\"$new_inherited_linker_flags $deplib\" ;;\n\t\tesac\n\t    fi\n\t  fi\n\t  continue\n\t  ;;\n\t-L*)\n\t  case $linkmode in\n\t  lib)\n\t    deplibs=\"$deplib $deplibs\"\n\t    test \"$pass\" = conv && continue\n\t    newdependency_libs=\"$deplib $newdependency_libs\"\n\t    func_stripname '-L' '' \"$deplib\"\n\t    newlib_search_path=\"$newlib_search_path $func_stripname_result\"\n\t    ;;\n\t  prog)\n\t    if test \"$pass\" = conv; then\n\t      deplibs=\"$deplib $deplibs\"\n\t      continue\n\t    fi\n\t    if test \"$pass\" = scan; then\n\t      deplibs=\"$deplib $deplibs\"\n\t    else\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    fi\n\t    func_stripname '-L' '' \"$deplib\"\n\t    newlib_search_path=\"$newlib_search_path $func_stripname_result\"\n\t    ;;\n\t  *)\n\t    func_warning \"\\`-L' is ignored for archives/objects\"\n\t    ;;\n\t  esac # linkmode\n\t  continue\n\t  ;; # -L\n\t-R*)\n\t  if test \"$pass\" = link; then\n\t    func_stripname '-R' '' \"$deplib\"\n\t    dir=$func_stripname_result\n\t    # Make sure the xrpath contains only unique directories.\n\t    case \"$xrpath \" in\n\t    *\" $dir \"*) ;;\n\t    *) xrpath=\"$xrpath $dir\" ;;\n\t    esac\n\t  fi\n\t  deplibs=\"$deplib $deplibs\"\n\t  continue\n\t  ;;\n\t*.la) lib=\"$deplib\" ;;\n\t*.$libext)\n\t  if test \"$pass\" = conv; then\n\t    deplibs=\"$deplib $deplibs\"\n\t    continue\n\t  fi\n\t  case $linkmode in\n\t  lib)\n\t    # Linking convenience modules into shared libraries is allowed,\n\t    # but linking other static libraries is non-portable.\n\t    case \" $dlpreconveniencelibs \" in\n\t    *\" $deplib \"*) ;;\n\t    *)\n\t      valid_a_lib=no\n\t      case $deplibs_check_method in\n\t\tmatch_pattern*)\n\t\t  set dummy $deplibs_check_method; shift\n\t\t  match_pattern_regex=`expr \"$deplibs_check_method\" : \"$1 \\(.*\\)\"`\n\t\t  if eval \"\\$ECHO \\\"X$deplib\\\"\" 2>/dev/null | $Xsed -e 10q \\\n\t\t    | $EGREP \"$match_pattern_regex\" > /dev/null; then\n\t\t    valid_a_lib=yes\n\t\t  fi\n\t\t;;\n\t\tpass_all)\n\t\t  valid_a_lib=yes\n\t\t;;\n\t      esac\n\t      if test \"$valid_a_lib\" != yes; then\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: Trying to link with static lib archive $deplib.\"\n\t\t$ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t$ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t$ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t$ECHO \"*** because the file extensions .$libext of this argument makes me believe\"\n\t\t$ECHO \"*** that it is just a static archive that I should not use here.\"\n\t      else\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: Linking the shared library $output against the\"\n\t\t$ECHO \"*** static library $deplib is not portable!\"\n\t\tdeplibs=\"$deplib $deplibs\"\n\t      fi\n\t      ;;\n\t    esac\n\t    continue\n\t    ;;\n\t  prog)\n\t    if test \"$pass\" != link; then\n\t      deplibs=\"$deplib $deplibs\"\n\t    else\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    fi\n\t    continue\n\t    ;;\n\t  esac # linkmode\n\t  ;; # *.$libext\n\t*.lo | *.$objext)\n\t  if test \"$pass\" = conv; then\n\t    deplibs=\"$deplib $deplibs\"\n\t  elif test \"$linkmode\" = prog; then\n\t    if test \"$pass\" = dlpreopen || test \"$dlopen_support\" != yes || test \"$build_libtool_libs\" = no; then\n\t      # If there is no dlopen support or we're linking statically,\n\t      # we need to preload.\n\t      newdlprefiles=\"$newdlprefiles $deplib\"\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    else\n\t      newdlfiles=\"$newdlfiles $deplib\"\n\t    fi\n\t  fi\n\t  continue\n\t  ;;\n\t%DEPLIBS%)\n\t  alldeplibs=yes\n\t  continue\n\t  ;;\n\tesac # case $deplib\n\n\tif test \"$found\" = yes || test -f \"$lib\"; then :\n\telse\n\t  func_fatal_error \"cannot find the library \\`$lib' or unhandled argument \\`$deplib'\"\n\tfi\n\n\t# Check to see that this really is a libtool archive.\n\tfunc_lalib_unsafe_p \"$lib\" \\\n\t  || func_fatal_error \"\\`$lib' is not a valid libtool archive\"\n\n\tfunc_dirname \"$lib\" \"\" \".\"\n\tladir=\"$func_dirname_result\"\n\n\tdlname=\n\tdlopen=\n\tdlpreopen=\n\tlibdir=\n\tlibrary_names=\n\told_library=\n\tinherited_linker_flags=\n\t# If the library was installed with an old release of libtool,\n\t# it will not redefine variables installed, or shouldnotlink\n\tinstalled=yes\n\tshouldnotlink=no\n\tavoidtemprpath=\n\n\n\t# Read the .la file\n\tfunc_source \"$lib\"\n\n\t# Convert \"-framework foo\" to \"foo.ltframework\"\n\tif test -n \"$inherited_linker_flags\"; then\n\t  tmp_inherited_linker_flags=`$ECHO \"X$inherited_linker_flags\" | $Xsed -e 's/-framework \\([^ $]*\\)/\\1.ltframework/g'`\n\t  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do\n\t    case \" $new_inherited_linker_flags \" in\n\t      *\" $tmp_inherited_linker_flag \"*) ;;\n\t      *) new_inherited_linker_flags=\"$new_inherited_linker_flags $tmp_inherited_linker_flag\";;\n\t    esac\n\t  done\n\tfi\n\tdependency_libs=`$ECHO \"X $dependency_libs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tif test \"$linkmode,$pass\" = \"lib,link\" ||\n\t   test \"$linkmode,$pass\" = \"prog,scan\" ||\n\t   { test \"$linkmode\" != prog && test \"$linkmode\" != lib; }; then\n\t  test -n \"$dlopen\" && dlfiles=\"$dlfiles $dlopen\"\n\t  test -n \"$dlpreopen\" && dlprefiles=\"$dlprefiles $dlpreopen\"\n\tfi\n\n\tif test \"$pass\" = conv; then\n\t  # Only check for convenience libraries\n\t  deplibs=\"$lib $deplibs\"\n\t  if test -z \"$libdir\"; then\n\t    if test -z \"$old_library\"; then\n\t      func_fatal_error \"cannot find name of link library for \\`$lib'\"\n\t    fi\n\t    # It is a libtool convenience library, so add in its objects.\n\t    convenience=\"$convenience $ladir/$objdir/$old_library\"\n\t    old_convenience=\"$old_convenience $ladir/$objdir/$old_library\"\n\t    tmp_libs=\n\t    for deplib in $dependency_libs; do\n\t      deplibs=\"$deplib $deplibs\"\n\t      if $opt_duplicate_deps ; then\n\t\tcase \"$tmp_libs \" in\n\t\t*\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\t\tesac\n\t      fi\n\t      tmp_libs=\"$tmp_libs $deplib\"\n\t    done\n\t  elif test \"$linkmode\" != prog && test \"$linkmode\" != lib; then\n\t    func_fatal_error \"\\`$lib' is not a convenience library\"\n\t  fi\n\t  continue\n\tfi # $pass = conv\n\n\n\t# Get the name of the library we link against.\n\tlinklib=\n\tfor l in $old_library $library_names; do\n\t  linklib=\"$l\"\n\tdone\n\tif test -z \"$linklib\"; then\n\t  func_fatal_error \"cannot find name of link library for \\`$lib'\"\n\tfi\n\n\t# This library was specified with -dlopen.\n\tif test \"$pass\" = dlopen; then\n\t  if test -z \"$libdir\"; then\n\t    func_fatal_error \"cannot -dlopen a convenience library: \\`$lib'\"\n\t  fi\n\t  if test -z \"$dlname\" ||\n\t     test \"$dlopen_support\" != yes ||\n\t     test \"$build_libtool_libs\" = no; then\n\t    # If there is no dlname, no dlopen support or we're linking\n\t    # statically, we need to preload.  We also need to preload any\n\t    # dependent libraries so libltdl's deplib preloader doesn't\n\t    # bomb out in the load deplibs phase.\n\t    dlprefiles=\"$dlprefiles $lib $dependency_libs\"\n\t  else\n\t    newdlfiles=\"$newdlfiles $lib\"\n\t  fi\n\t  continue\n\tfi # $pass = dlopen\n\n\t# We need an absolute path.\n\tcase $ladir in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) abs_ladir=\"$ladir\" ;;\n\t*)\n\t  abs_ladir=`cd \"$ladir\" && pwd`\n\t  if test -z \"$abs_ladir\"; then\n\t    func_warning \"cannot determine absolute directory name of \\`$ladir'\"\n\t    func_warning \"passing it literally to the linker, although it might fail\"\n\t    abs_ladir=\"$ladir\"\n\t  fi\n\t  ;;\n\tesac\n\tfunc_basename \"$lib\"\n\tlaname=\"$func_basename_result\"\n\n\t# Find the relevant object directory and library name.\n\tif test \"X$installed\" = Xyes; then\n\t  if test ! -f \"$libdir/$linklib\" && test -f \"$abs_ladir/$linklib\"; then\n\t    func_warning \"library \\`$lib' was moved.\"\n\t    dir=\"$ladir\"\n\t    absdir=\"$abs_ladir\"\n\t    libdir=\"$abs_ladir\"\n\t  else\n\t    dir=\"$libdir\"\n\t    absdir=\"$libdir\"\n\t  fi\n\t  test \"X$hardcode_automatic\" = Xyes && avoidtemprpath=yes\n\telse\n\t  if test ! -f \"$ladir/$objdir/$linklib\" && test -f \"$abs_ladir/$linklib\"; then\n\t    dir=\"$ladir\"\n\t    absdir=\"$abs_ladir\"\n\t    # Remove this search path later\n\t    notinst_path=\"$notinst_path $abs_ladir\"\n\t  else\n\t    dir=\"$ladir/$objdir\"\n\t    absdir=\"$abs_ladir/$objdir\"\n\t    # Remove this search path later\n\t    notinst_path=\"$notinst_path $abs_ladir\"\n\t  fi\n\tfi # $installed = yes\n\tfunc_stripname 'lib' '.la' \"$laname\"\n\tname=$func_stripname_result\n\n\t# This library was specified with -dlpreopen.\n\tif test \"$pass\" = dlpreopen; then\n\t  if test -z \"$libdir\" && test \"$linkmode\" = prog; then\n\t    func_fatal_error \"only libraries may -dlpreopen a convenience library: \\`$lib'\"\n\t  fi\n\t  # Prefer using a static library (so that no silly _DYNAMIC symbols\n\t  # are required to link).\n\t  if test -n \"$old_library\"; then\n\t    newdlprefiles=\"$newdlprefiles $dir/$old_library\"\n\t    # Keep a list of preopened convenience libraries to check\n\t    # that they are being used correctly in the link pass.\n\t    test -z \"$libdir\" && \\\n\t\tdlpreconveniencelibs=\"$dlpreconveniencelibs $dir/$old_library\"\n\t  # Otherwise, use the dlname, so that lt_dlopen finds it.\n\t  elif test -n \"$dlname\"; then\n\t    newdlprefiles=\"$newdlprefiles $dir/$dlname\"\n\t  else\n\t    newdlprefiles=\"$newdlprefiles $dir/$linklib\"\n\t  fi\n\tfi # $pass = dlpreopen\n\n\tif test -z \"$libdir\"; then\n\t  # Link the convenience library\n\t  if test \"$linkmode\" = lib; then\n\t    deplibs=\"$dir/$old_library $deplibs\"\n\t  elif test \"$linkmode,$pass\" = \"prog,link\"; then\n\t    compile_deplibs=\"$dir/$old_library $compile_deplibs\"\n\t    finalize_deplibs=\"$dir/$old_library $finalize_deplibs\"\n\t  else\n\t    deplibs=\"$lib $deplibs\" # used for prog,scan pass\n\t  fi\n\t  continue\n\tfi\n\n\n\tif test \"$linkmode\" = prog && test \"$pass\" != link; then\n\t  newlib_search_path=\"$newlib_search_path $ladir\"\n\t  deplibs=\"$lib $deplibs\"\n\n\t  linkalldeplibs=no\n\t  if test \"$link_all_deplibs\" != no || test -z \"$library_names\" ||\n\t     test \"$build_libtool_libs\" = no; then\n\t    linkalldeplibs=yes\n\t  fi\n\n\t  tmp_libs=\n\t  for deplib in $dependency_libs; do\n\t    case $deplib in\n\t    -L*) func_stripname '-L' '' \"$deplib\"\n\t         newlib_search_path=\"$newlib_search_path $func_stripname_result\"\n\t\t ;;\n\t    esac\n\t    # Need to link against all dependency_libs?\n\t    if test \"$linkalldeplibs\" = yes; then\n\t      deplibs=\"$deplib $deplibs\"\n\t    else\n\t      # Need to hardcode shared library paths\n\t      # or/and link against static libraries\n\t      newdependency_libs=\"$deplib $newdependency_libs\"\n\t    fi\n\t    if $opt_duplicate_deps ; then\n\t      case \"$tmp_libs \" in\n\t      *\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\t      esac\n\t    fi\n\t    tmp_libs=\"$tmp_libs $deplib\"\n\t  done # for deplib\n\t  continue\n\tfi # $linkmode = prog...\n\n\tif test \"$linkmode,$pass\" = \"prog,link\"; then\n\t  if test -n \"$library_names\" &&\n\t     { { test \"$prefer_static_libs\" = no ||\n\t         test \"$prefer_static_libs,$installed\" = \"built,yes\"; } ||\n\t       test -z \"$old_library\"; }; then\n\t    # We need to hardcode the library path\n\t    if test -n \"$shlibpath_var\" && test -z \"$avoidtemprpath\" ; then\n\t      # Make sure the rpath contains only unique directories.\n\t      case \"$temp_rpath:\" in\n\t      *\"$absdir:\"*) ;;\n\t      *) temp_rpath=\"$temp_rpath$absdir:\" ;;\n\t      esac\n\t    fi\n\n\t    # Hardcode the library path.\n\t    # Skip directories that are in the system default run-time\n\t    # search path.\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $absdir \"*) ;;\n\t    *)\n\t      case \"$compile_rpath \" in\n\t      *\" $absdir \"*) ;;\n\t      *) compile_rpath=\"$compile_rpath $absdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $libdir \"*) ;;\n\t    *)\n\t      case \"$finalize_rpath \" in\n\t      *\" $libdir \"*) ;;\n\t      *) finalize_rpath=\"$finalize_rpath $libdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t  fi # $linkmode,$pass = prog,link...\n\n\t  if test \"$alldeplibs\" = yes &&\n\t     { test \"$deplibs_check_method\" = pass_all ||\n\t       { test \"$build_libtool_libs\" = yes &&\n\t\t test -n \"$library_names\"; }; }; then\n\t    # We only need to search for static libraries\n\t    continue\n\t  fi\n\tfi\n\n\tlink_static=no # Whether the deplib will be linked statically\n\tuse_static_libs=$prefer_static_libs\n\tif test \"$use_static_libs\" = built && test \"$installed\" = yes; then\n\t  use_static_libs=no\n\tfi\n\tif test -n \"$library_names\" &&\n\t   { test \"$use_static_libs\" = no || test -z \"$old_library\"; }; then\n\t  case $host in\n\t  *cygwin* | *mingw* | *cegcc*)\n\t      # No point in relinking DLLs because paths are not encoded\n\t      notinst_deplibs=\"$notinst_deplibs $lib\"\n\t      need_relink=no\n\t    ;;\n\t  *)\n\t    if test \"$installed\" = no; then\n\t      notinst_deplibs=\"$notinst_deplibs $lib\"\n\t      need_relink=yes\n\t    fi\n\t    ;;\n\t  esac\n\t  # This is a shared library\n\n\t  # Warn about portability, can't link against -module's on some\n\t  # systems (darwin).  Don't bleat about dlopened modules though!\n\t  dlopenmodule=\"\"\n\t  for dlpremoduletest in $dlprefiles; do\n\t    if test \"X$dlpremoduletest\" = \"X$lib\"; then\n\t      dlopenmodule=\"$dlpremoduletest\"\n\t      break\n\t    fi\n\t  done\n\t  if test -z \"$dlopenmodule\" && test \"$shouldnotlink\" = yes && test \"$pass\" = link; then\n\t    $ECHO\n\t    if test \"$linkmode\" = prog; then\n\t      $ECHO \"*** Warning: Linking the executable $output against the loadable module\"\n\t    else\n\t      $ECHO \"*** Warning: Linking the shared library $output against the loadable module\"\n\t    fi\n\t    $ECHO \"*** $linklib is not portable!\"\n\t  fi\n\t  if test \"$linkmode\" = lib &&\n\t     test \"$hardcode_into_libs\" = yes; then\n\t    # Hardcode the library path.\n\t    # Skip directories that are in the system default run-time\n\t    # search path.\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $absdir \"*) ;;\n\t    *)\n\t      case \"$compile_rpath \" in\n\t      *\" $absdir \"*) ;;\n\t      *) compile_rpath=\"$compile_rpath $absdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $libdir \"*) ;;\n\t    *)\n\t      case \"$finalize_rpath \" in\n\t      *\" $libdir \"*) ;;\n\t      *) finalize_rpath=\"$finalize_rpath $libdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t  fi\n\n\t  if test -n \"$old_archive_from_expsyms_cmds\"; then\n\t    # figure out the soname\n\t    set dummy $library_names\n\t    shift\n\t    realname=\"$1\"\n\t    shift\n\t    libname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t    # use dlname if we got it. it's perfectly good, no?\n\t    if test -n \"$dlname\"; then\n\t      soname=\"$dlname\"\n\t    elif test -n \"$soname_spec\"; then\n\t      # bleh windows\n\t      case $host in\n\t      *cygwin* | mingw* | *cegcc*)\n\t        func_arith $current - $age\n\t\tmajor=$func_arith_result\n\t\tversuffix=\"-$major\"\n\t\t;;\n\t      esac\n\t      eval soname=\\\"$soname_spec\\\"\n\t    else\n\t      soname=\"$realname\"\n\t    fi\n\n\t    # Make a new name for the extract_expsyms_cmds to use\n\t    soroot=\"$soname\"\n\t    func_basename \"$soroot\"\n\t    soname=\"$func_basename_result\"\n\t    func_stripname 'lib' '.dll' \"$soname\"\n\t    newlib=libimp-$func_stripname_result.a\n\n\t    # If the library has no export list, then create one now\n\t    if test -f \"$output_objdir/$soname-def\"; then :\n\t    else\n\t      func_verbose \"extracting exported symbol list from \\`$soname'\"\n\t      func_execute_cmds \"$extract_expsyms_cmds\" 'exit $?'\n\t    fi\n\n\t    # Create $newlib\n\t    if test -f \"$output_objdir/$newlib\"; then :; else\n\t      func_verbose \"generating import library for \\`$soname'\"\n\t      func_execute_cmds \"$old_archive_from_expsyms_cmds\" 'exit $?'\n\t    fi\n\t    # make sure the library variables are pointing to the new library\n\t    dir=$output_objdir\n\t    linklib=$newlib\n\t  fi # test -n \"$old_archive_from_expsyms_cmds\"\n\n\t  if test \"$linkmode\" = prog || test \"$mode\" != relink; then\n\t    add_shlibpath=\n\t    add_dir=\n\t    add=\n\t    lib_linked=yes\n\t    case $hardcode_action in\n\t    immediate | unsupported)\n\t      if test \"$hardcode_direct\" = no; then\n\t\tadd=\"$dir/$linklib\"\n\t\tcase $host in\n\t\t  *-*-sco3.2v5.0.[024]*) add_dir=\"-L$dir\" ;;\n\t\t  *-*-sysv4*uw2*) add_dir=\"-L$dir\" ;;\n\t\t  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \\\n\t\t    *-*-unixware7*) add_dir=\"-L$dir\" ;;\n\t\t  *-*-darwin* )\n\t\t    # if the lib is a (non-dlopened) module then we can not\n\t\t    # link against it, someone is ignoring the earlier warnings\n\t\t    if /usr/bin/file -L $add 2> /dev/null |\n\t\t\t $GREP \": [^:]* bundle\" >/dev/null ; then\n\t\t      if test \"X$dlopenmodule\" != \"X$lib\"; then\n\t\t\t$ECHO \"*** Warning: lib $linklib is a module, not a shared library\"\n\t\t\tif test -z \"$old_library\" ; then\n\t\t\t  $ECHO\n\t\t\t  $ECHO \"*** And there doesn't seem to be a static archive available\"\n\t\t\t  $ECHO \"*** The link will probably fail, sorry\"\n\t\t\telse\n\t\t\t  add=\"$dir/$old_library\"\n\t\t\tfi\n\t\t      elif test -n \"$old_library\"; then\n\t\t\tadd=\"$dir/$old_library\"\n\t\t      fi\n\t\t    fi\n\t\tesac\n\t      elif test \"$hardcode_minus_L\" = no; then\n\t\tcase $host in\n\t\t*-*-sunos*) add_shlibpath=\"$dir\" ;;\n\t\tesac\n\t\tadd_dir=\"-L$dir\"\n\t\tadd=\"-l$name\"\n\t      elif test \"$hardcode_shlibpath_var\" = no; then\n\t\tadd_shlibpath=\"$dir\"\n\t\tadd=\"-l$name\"\n\t      else\n\t\tlib_linked=no\n\t      fi\n\t      ;;\n\t    relink)\n\t      if test \"$hardcode_direct\" = yes &&\n\t         test \"$hardcode_direct_absolute\" = no; then\n\t\tadd=\"$dir/$linklib\"\n\t      elif test \"$hardcode_minus_L\" = yes; then\n\t\tadd_dir=\"-L$dir\"\n\t\t# Try looking first in the location we're being installed to.\n\t\tif test -n \"$inst_prefix_dir\"; then\n\t\t  case $libdir in\n\t\t    [\\\\/]*)\n\t\t      add_dir=\"$add_dir -L$inst_prefix_dir$libdir\"\n\t\t      ;;\n\t\t  esac\n\t\tfi\n\t\tadd=\"-l$name\"\n\t      elif test \"$hardcode_shlibpath_var\" = yes; then\n\t\tadd_shlibpath=\"$dir\"\n\t\tadd=\"-l$name\"\n\t      else\n\t\tlib_linked=no\n\t      fi\n\t      ;;\n\t    *) lib_linked=no ;;\n\t    esac\n\n\t    if test \"$lib_linked\" != yes; then\n\t      func_fatal_configuration \"unsupported hardcode properties\"\n\t    fi\n\n\t    if test -n \"$add_shlibpath\"; then\n\t      case :$compile_shlibpath: in\n\t      *\":$add_shlibpath:\"*) ;;\n\t      *) compile_shlibpath=\"$compile_shlibpath$add_shlibpath:\" ;;\n\t      esac\n\t    fi\n\t    if test \"$linkmode\" = prog; then\n\t      test -n \"$add_dir\" && compile_deplibs=\"$add_dir $compile_deplibs\"\n\t      test -n \"$add\" && compile_deplibs=\"$add $compile_deplibs\"\n\t    else\n\t      test -n \"$add_dir\" && deplibs=\"$add_dir $deplibs\"\n\t      test -n \"$add\" && deplibs=\"$add $deplibs\"\n\t      if test \"$hardcode_direct\" != yes &&\n\t\t test \"$hardcode_minus_L\" != yes &&\n\t\t test \"$hardcode_shlibpath_var\" = yes; then\n\t\tcase :$finalize_shlibpath: in\n\t\t*\":$libdir:\"*) ;;\n\t\t*) finalize_shlibpath=\"$finalize_shlibpath$libdir:\" ;;\n\t\tesac\n\t      fi\n\t    fi\n\t  fi\n\n\t  if test \"$linkmode\" = prog || test \"$mode\" = relink; then\n\t    add_shlibpath=\n\t    add_dir=\n\t    add=\n\t    # Finalize command for both is simple: just hardcode it.\n\t    if test \"$hardcode_direct\" = yes &&\n\t       test \"$hardcode_direct_absolute\" = no; then\n\t      add=\"$libdir/$linklib\"\n\t    elif test \"$hardcode_minus_L\" = yes; then\n\t      add_dir=\"-L$libdir\"\n\t      add=\"-l$name\"\n\t    elif test \"$hardcode_shlibpath_var\" = yes; then\n\t      case :$finalize_shlibpath: in\n\t      *\":$libdir:\"*) ;;\n\t      *) finalize_shlibpath=\"$finalize_shlibpath$libdir:\" ;;\n\t      esac\n\t      add=\"-l$name\"\n\t    elif test \"$hardcode_automatic\" = yes; then\n\t      if test -n \"$inst_prefix_dir\" &&\n\t\t test -f \"$inst_prefix_dir$libdir/$linklib\" ; then\n\t\tadd=\"$inst_prefix_dir$libdir/$linklib\"\n\t      else\n\t\tadd=\"$libdir/$linklib\"\n\t      fi\n\t    else\n\t      # We cannot seem to hardcode it, guess we'll fake it.\n\t      add_dir=\"-L$libdir\"\n\t      # Try looking first in the location we're being installed to.\n\t      if test -n \"$inst_prefix_dir\"; then\n\t\tcase $libdir in\n\t\t  [\\\\/]*)\n\t\t    add_dir=\"$add_dir -L$inst_prefix_dir$libdir\"\n\t\t    ;;\n\t\tesac\n\t      fi\n\t      add=\"-l$name\"\n\t    fi\n\n\t    if test \"$linkmode\" = prog; then\n\t      test -n \"$add_dir\" && finalize_deplibs=\"$add_dir $finalize_deplibs\"\n\t      test -n \"$add\" && finalize_deplibs=\"$add $finalize_deplibs\"\n\t    else\n\t      test -n \"$add_dir\" && deplibs=\"$add_dir $deplibs\"\n\t      test -n \"$add\" && deplibs=\"$add $deplibs\"\n\t    fi\n\t  fi\n\telif test \"$linkmode\" = prog; then\n\t  # Here we assume that one of hardcode_direct or hardcode_minus_L\n\t  # is not unsupported.  This is valid on all known static and\n\t  # shared platforms.\n\t  if test \"$hardcode_direct\" != unsupported; then\n\t    test -n \"$old_library\" && linklib=\"$old_library\"\n\t    compile_deplibs=\"$dir/$linklib $compile_deplibs\"\n\t    finalize_deplibs=\"$dir/$linklib $finalize_deplibs\"\n\t  else\n\t    compile_deplibs=\"-l$name -L$dir $compile_deplibs\"\n\t    finalize_deplibs=\"-l$name -L$dir $finalize_deplibs\"\n\t  fi\n\telif test \"$build_libtool_libs\" = yes; then\n\t  # Not a shared library\n\t  if test \"$deplibs_check_method\" != pass_all; then\n\t    # We're trying link a shared library against a static one\n\t    # but the system doesn't support it.\n\n\t    # Just print a warning and add the library to dependency_libs so\n\t    # that the program can be linked against the static library.\n\t    $ECHO\n\t    $ECHO \"*** Warning: This system can not link to static lib archive $lib.\"\n\t    $ECHO \"*** I have the capability to make that library automatically link in when\"\n\t    $ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t    $ECHO \"*** shared version of the library, which you do not appear to have.\"\n\t    if test \"$module\" = yes; then\n\t      $ECHO \"*** But as you try to build a module library, libtool will still create \"\n\t      $ECHO \"*** a static module, that should work as long as the dlopening application\"\n\t      $ECHO \"*** is linked with the -dlopen flag to resolve symbols at runtime.\"\n\t      if test -z \"$global_symbol_pipe\"; then\n\t\t$ECHO\n\t\t$ECHO \"*** However, this would only work if libtool was able to extract symbol\"\n\t\t$ECHO \"*** lists from a program, using \\`nm' or equivalent, but libtool could\"\n\t\t$ECHO \"*** not find such a program.  So, this module is probably useless.\"\n\t\t$ECHO \"*** \\`nm' from GNU binutils and a full rebuild may help.\"\n\t      fi\n\t      if test \"$build_old_libs\" = no; then\n\t\tbuild_libtool_libs=module\n\t\tbuild_old_libs=yes\n\t      else\n\t\tbuild_libtool_libs=no\n\t      fi\n\t    fi\n\t  else\n\t    deplibs=\"$dir/$old_library $deplibs\"\n\t    link_static=yes\n\t  fi\n\tfi # link shared/static library?\n\n\tif test \"$linkmode\" = lib; then\n\t  if test -n \"$dependency_libs\" &&\n\t     { test \"$hardcode_into_libs\" != yes ||\n\t       test \"$build_old_libs\" = yes ||\n\t       test \"$link_static\" = yes; }; then\n\t    # Extract -R from dependency_libs\n\t    temp_deplibs=\n\t    for libdir in $dependency_libs; do\n\t      case $libdir in\n\t      -R*) func_stripname '-R' '' \"$libdir\"\n\t           temp_xrpath=$func_stripname_result\n\t\t   case \" $xrpath \" in\n\t\t   *\" $temp_xrpath \"*) ;;\n\t\t   *) xrpath=\"$xrpath $temp_xrpath\";;\n\t\t   esac;;\n\t      *) temp_deplibs=\"$temp_deplibs $libdir\";;\n\t      esac\n\t    done\n\t    dependency_libs=\"$temp_deplibs\"\n\t  fi\n\n\t  newlib_search_path=\"$newlib_search_path $absdir\"\n\t  # Link against this library\n\t  test \"$link_static\" = no && newdependency_libs=\"$abs_ladir/$laname $newdependency_libs\"\n\t  # ... and its dependency_libs\n\t  tmp_libs=\n\t  for deplib in $dependency_libs; do\n\t    newdependency_libs=\"$deplib $newdependency_libs\"\n\t    if $opt_duplicate_deps ; then\n\t      case \"$tmp_libs \" in\n\t      *\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\t      esac\n\t    fi\n\t    tmp_libs=\"$tmp_libs $deplib\"\n\t  done\n\n\t  if test \"$link_all_deplibs\" != no; then\n\t    # Add the search paths of all dependency libraries\n\t    for deplib in $dependency_libs; do\n\t      path=\n\t      case $deplib in\n\t      -L*) path=\"$deplib\" ;;\n\t      *.la)\n\t        func_dirname \"$deplib\" \"\" \".\"\n\t\tdir=\"$func_dirname_result\"\n\t\t# We need an absolute path.\n\t\tcase $dir in\n\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) absdir=\"$dir\" ;;\n\t\t*)\n\t\t  absdir=`cd \"$dir\" && pwd`\n\t\t  if test -z \"$absdir\"; then\n\t\t    func_warning \"cannot determine absolute directory name of \\`$dir'\"\n\t\t    absdir=\"$dir\"\n\t\t  fi\n\t\t  ;;\n\t\tesac\n\t\tif $GREP \"^installed=no\" $deplib > /dev/null; then\n\t\tcase $host in\n\t\t*-*-darwin*)\n\t\t  depdepl=\n\t\t  eval deplibrary_names=`${SED} -n -e 's/^library_names=\\(.*\\)$/\\1/p' $deplib`\n\t\t  if test -n \"$deplibrary_names\" ; then\n\t\t    for tmp in $deplibrary_names ; do\n\t\t      depdepl=$tmp\n\t\t    done\n\t\t    if test -f \"$absdir/$objdir/$depdepl\" ; then\n\t\t      depdepl=\"$absdir/$objdir/$depdepl\"\n\t\t      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`\n                      if test -z \"$darwin_install_name\"; then\n                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`\n                      fi\n\t\t      compiler_flags=\"$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}\"\n\t\t      linker_flags=\"$linker_flags -dylib_file ${darwin_install_name}:${depdepl}\"\n\t\t      path=\n\t\t    fi\n\t\t  fi\n\t\t  ;;\n\t\t*)\n\t\t  path=\"-L$absdir/$objdir\"\n\t\t  ;;\n\t\tesac\n\t\telse\n\t\t  eval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $deplib`\n\t\t  test -z \"$libdir\" && \\\n\t\t    func_fatal_error \"\\`$deplib' is not a valid libtool archive\"\n\t\t  test \"$absdir\" != \"$libdir\" && \\\n\t\t    func_warning \"\\`$deplib' seems to be moved\"\n\n\t\t  path=\"-L$absdir\"\n\t\tfi\n\t\t;;\n\t      esac\n\t      case \" $deplibs \" in\n\t      *\" $path \"*) ;;\n\t      *) deplibs=\"$path $deplibs\" ;;\n\t      esac\n\t    done\n\t  fi # link_all_deplibs != no\n\tfi # linkmode = lib\n      done # for deplib in $libs\n      if test \"$pass\" = link; then\n\tif test \"$linkmode\" = \"prog\"; then\n\t  compile_deplibs=\"$new_inherited_linker_flags $compile_deplibs\"\n\t  finalize_deplibs=\"$new_inherited_linker_flags $finalize_deplibs\"\n\telse\n\t  compiler_flags=\"$compiler_flags \"`$ECHO \"X $new_inherited_linker_flags\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tfi\n      fi\n      dependency_libs=\"$newdependency_libs\"\n      if test \"$pass\" = dlpreopen; then\n\t# Link the dlpreopened libraries before other libraries\n\tfor deplib in $save_deplibs; do\n\t  deplibs=\"$deplib $deplibs\"\n\tdone\n      fi\n      if test \"$pass\" != dlopen; then\n\tif test \"$pass\" != conv; then\n\t  # Make sure lib_search_path contains only unique directories.\n\t  lib_search_path=\n\t  for dir in $newlib_search_path; do\n\t    case \"$lib_search_path \" in\n\t    *\" $dir \"*) ;;\n\t    *) lib_search_path=\"$lib_search_path $dir\" ;;\n\t    esac\n\t  done\n\t  newlib_search_path=\n\tfi\n\n\tif test \"$linkmode,$pass\" != \"prog,link\"; then\n\t  vars=\"deplibs\"\n\telse\n\t  vars=\"compile_deplibs finalize_deplibs\"\n\tfi\n\tfor var in $vars dependency_libs; do\n\t  # Add libraries to $var in reverse order\n\t  eval tmp_libs=\\\"\\$$var\\\"\n\t  new_libs=\n\t  for deplib in $tmp_libs; do\n\t    # FIXME: Pedantically, this is the right thing to do, so\n\t    #        that some nasty dependency loop isn't accidentally\n\t    #        broken:\n\t    #new_libs=\"$deplib $new_libs\"\n\t    # Pragmatically, this seems to cause very few problems in\n\t    # practice:\n\t    case $deplib in\n\t    -L*) new_libs=\"$deplib $new_libs\" ;;\n\t    -R*) ;;\n\t    *)\n\t      # And here is the reason: when a library appears more\n\t      # than once as an explicit dependence of a library, or\n\t      # is implicitly linked in more than once by the\n\t      # compiler, it is considered special, and multiple\n\t      # occurrences thereof are not removed.  Compare this\n\t      # with having the same library being listed as a\n\t      # dependency of multiple other libraries: in this case,\n\t      # we know (pedantically, we assume) the library does not\n\t      # need to be listed more than once, so we keep only the\n\t      # last copy.  This is not always right, but it is rare\n\t      # enough that we require users that really mean to play\n\t      # such unportable linking tricks to link the library\n\t      # using -Wl,-lname, so that libtool does not consider it\n\t      # for duplicate removal.\n\t      case \" $specialdeplibs \" in\n\t      *\" $deplib \"*) new_libs=\"$deplib $new_libs\" ;;\n\t      *)\n\t\tcase \" $new_libs \" in\n\t\t*\" $deplib \"*) ;;\n\t\t*) new_libs=\"$deplib $new_libs\" ;;\n\t\tesac\n\t\t;;\n\t      esac\n\t      ;;\n\t    esac\n\t  done\n\t  tmp_libs=\n\t  for deplib in $new_libs; do\n\t    case $deplib in\n\t    -L*)\n\t      case \" $tmp_libs \" in\n\t      *\" $deplib \"*) ;;\n\t      *) tmp_libs=\"$tmp_libs $deplib\" ;;\n\t      esac\n\t      ;;\n\t    *) tmp_libs=\"$tmp_libs $deplib\" ;;\n\t    esac\n\t  done\n\t  eval $var=\\\"$tmp_libs\\\"\n\tdone # for var\n      fi\n      # Last step: remove runtime libs from dependency_libs\n      # (they stay in deplibs)\n      tmp_libs=\n      for i in $dependency_libs ; do\n\tcase \" $predeps $postdeps $compiler_lib_search_path \" in\n\t*\" $i \"*)\n\t  i=\"\"\n\t  ;;\n\tesac\n\tif test -n \"$i\" ; then\n\t  tmp_libs=\"$tmp_libs $i\"\n\tfi\n      done\n      dependency_libs=$tmp_libs\n    done # for pass\n    if test \"$linkmode\" = prog; then\n      dlfiles=\"$newdlfiles\"\n    fi\n    if test \"$linkmode\" = prog || test \"$linkmode\" = lib; then\n      dlprefiles=\"$newdlprefiles\"\n    fi\n\n    case $linkmode in\n    oldlib)\n      if test -n \"$dlfiles$dlprefiles\" || test \"$dlself\" != no; then\n\tfunc_warning \"\\`-dlopen' is ignored for archives\"\n      fi\n\n      case \" $deplibs\" in\n      *\\ -l* | *\\ -L*)\n\tfunc_warning \"\\`-l' and \\`-L' are ignored for archives\" ;;\n      esac\n\n      test -n \"$rpath\" && \\\n\tfunc_warning \"\\`-rpath' is ignored for archives\"\n\n      test -n \"$xrpath\" && \\\n\tfunc_warning \"\\`-R' is ignored for archives\"\n\n      test -n \"$vinfo\" && \\\n\tfunc_warning \"\\`-version-info/-version-number' is ignored for archives\"\n\n      test -n \"$release\" && \\\n\tfunc_warning \"\\`-release' is ignored for archives\"\n\n      test -n \"$export_symbols$export_symbols_regex\" && \\\n\tfunc_warning \"\\`-export-symbols' is ignored for archives\"\n\n      # Now set the variables for building old libraries.\n      build_libtool_libs=no\n      oldlibs=\"$output\"\n      objs=\"$objs$old_deplibs\"\n      ;;\n\n    lib)\n      # Make sure we only generate libraries of the form `libNAME.la'.\n      case $outputname in\n      lib*)\n\tfunc_stripname 'lib' '.la' \"$outputname\"\n\tname=$func_stripname_result\n\teval shared_ext=\\\"$shrext_cmds\\\"\n\teval libname=\\\"$libname_spec\\\"\n\t;;\n      *)\n\ttest \"$module\" = no && \\\n\t  func_fatal_help \"libtool library \\`$output' must begin with \\`lib'\"\n\n\tif test \"$need_lib_prefix\" != no; then\n\t  # Add the \"lib\" prefix for modules if required\n\t  func_stripname '' '.la' \"$outputname\"\n\t  name=$func_stripname_result\n\t  eval shared_ext=\\\"$shrext_cmds\\\"\n\t  eval libname=\\\"$libname_spec\\\"\n\telse\n\t  func_stripname '' '.la' \"$outputname\"\n\t  libname=$func_stripname_result\n\tfi\n\t;;\n      esac\n\n      if test -n \"$objs\"; then\n\tif test \"$deplibs_check_method\" != pass_all; then\n\t  func_fatal_error \"cannot build libtool library \\`$output' from non-libtool objects on this host:$objs\"\n\telse\n\t  $ECHO\n\t  $ECHO \"*** Warning: Linking the shared library $output against the non-libtool\"\n\t  $ECHO \"*** objects $objs is not portable!\"\n\t  libobjs=\"$libobjs $objs\"\n\tfi\n      fi\n\n      test \"$dlself\" != no && \\\n\tfunc_warning \"\\`-dlopen self' is ignored for libtool libraries\"\n\n      set dummy $rpath\n      shift\n      test \"$#\" -gt 1 && \\\n\tfunc_warning \"ignoring multiple \\`-rpath's for a libtool library\"\n\n      install_libdir=\"$1\"\n\n      oldlibs=\n      if test -z \"$rpath\"; then\n\tif test \"$build_libtool_libs\" = yes; then\n\t  # Building a libtool convenience library.\n\t  # Some compilers have problems with a `.al' extension so\n\t  # convenience libraries should have the same extension an\n\t  # archive normally would.\n\t  oldlibs=\"$output_objdir/$libname.$libext $oldlibs\"\n\t  build_libtool_libs=convenience\n\t  build_old_libs=yes\n\tfi\n\n\ttest -n \"$vinfo\" && \\\n\t  func_warning \"\\`-version-info/-version-number' is ignored for convenience libraries\"\n\n\ttest -n \"$release\" && \\\n\t  func_warning \"\\`-release' is ignored for convenience libraries\"\n      else\n\n\t# Parse the version information argument.\n\tsave_ifs=\"$IFS\"; IFS=':'\n\tset dummy $vinfo 0 0 0\n\tshift\n\tIFS=\"$save_ifs\"\n\n\ttest -n \"$7\" && \\\n\t  func_fatal_help \"too many parameters to \\`-version-info'\"\n\n\t# convert absolute version numbers to libtool ages\n\t# this retains compatibility with .la files and attempts\n\t# to make the code below a bit more comprehensible\n\n\tcase $vinfo_number in\n\tyes)\n\t  number_major=\"$1\"\n\t  number_minor=\"$2\"\n\t  number_revision=\"$3\"\n\t  #\n\t  # There are really only two kinds -- those that\n\t  # use the current revision as the major version\n\t  # and those that subtract age and use age as\n\t  # a minor version.  But, then there is irix\n\t  # which has an extra 1 added just for fun\n\t  #\n\t  case $version_type in\n\t  darwin|linux|osf|windows|none)\n\t    func_arith $number_major + $number_minor\n\t    current=$func_arith_result\n\t    age=\"$number_minor\"\n\t    revision=\"$number_revision\"\n\t    ;;\n\t  freebsd-aout|freebsd-elf|sunos)\n\t    current=\"$number_major\"\n\t    revision=\"$number_minor\"\n\t    age=\"0\"\n\t    ;;\n\t  irix|nonstopux)\n\t    func_arith $number_major + $number_minor\n\t    current=$func_arith_result\n\t    age=\"$number_minor\"\n\t    revision=\"$number_minor\"\n\t    lt_irix_increment=no\n\t    ;;\n\t  *)\n\t    func_fatal_configuration \"$modename: unknown library version type \\`$version_type'\"\n\t    ;;\n\t  esac\n\t  ;;\n\tno)\n\t  current=\"$1\"\n\t  revision=\"$2\"\n\t  age=\"$3\"\n\t  ;;\n\tesac\n\n\t# Check that each of the things are valid numbers.\n\tcase $current in\n\t0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;\n\t*)\n\t  func_error \"CURRENT \\`$current' must be a nonnegative integer\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\t  ;;\n\tesac\n\n\tcase $revision in\n\t0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;\n\t*)\n\t  func_error \"REVISION \\`$revision' must be a nonnegative integer\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\t  ;;\n\tesac\n\n\tcase $age in\n\t0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;\n\t*)\n\t  func_error \"AGE \\`$age' must be a nonnegative integer\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\t  ;;\n\tesac\n\n\tif test \"$age\" -gt \"$current\"; then\n\t  func_error \"AGE \\`$age' is greater than the current interface number \\`$current'\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\tfi\n\n\t# Calculate the version variables.\n\tmajor=\n\tversuffix=\n\tverstring=\n\tcase $version_type in\n\tnone) ;;\n\n\tdarwin)\n\t  # Like Linux, but with the current version available in\n\t  # verstring for coding it into the library header\n\t  func_arith $current - $age\n\t  major=.$func_arith_result\n\t  versuffix=\"$major.$age.$revision\"\n\t  # Darwin ld doesn't like 0 for these options...\n\t  func_arith $current + 1\n\t  minor_current=$func_arith_result\n\t  xlcverstring=\"${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision\"\n\t  verstring=\"-compatibility_version $minor_current -current_version $minor_current.$revision\"\n\t  ;;\n\n\tfreebsd-aout)\n\t  major=\".$current\"\n\t  versuffix=\".$current.$revision\";\n\t  ;;\n\n\tfreebsd-elf)\n\t  major=\".$current\"\n\t  versuffix=\".$current\"\n\t  ;;\n\n\tirix | nonstopux)\n\t  if test \"X$lt_irix_increment\" = \"Xno\"; then\n\t    func_arith $current - $age\n\t  else\n\t    func_arith $current - $age + 1\n\t  fi\n\t  major=$func_arith_result\n\n\t  case $version_type in\n\t    nonstopux) verstring_prefix=nonstopux ;;\n\t    *)         verstring_prefix=sgi ;;\n\t  esac\n\t  verstring=\"$verstring_prefix$major.$revision\"\n\n\t  # Add in all the interfaces that we are compatible with.\n\t  loop=$revision\n\t  while test \"$loop\" -ne 0; do\n\t    func_arith $revision - $loop\n\t    iface=$func_arith_result\n\t    func_arith $loop - 1\n\t    loop=$func_arith_result\n\t    verstring=\"$verstring_prefix$major.$iface:$verstring\"\n\t  done\n\n\t  # Before this point, $major must not contain `.'.\n\t  major=.$major\n\t  versuffix=\"$major.$revision\"\n\t  ;;\n\n\tlinux)\n\t  func_arith $current - $age\n\t  major=.$func_arith_result\n\t  versuffix=\"$major.$age.$revision\"\n\t  ;;\n\n\tosf)\n\t  func_arith $current - $age\n\t  major=.$func_arith_result\n\t  versuffix=\".$current.$age.$revision\"\n\t  verstring=\"$current.$age.$revision\"\n\n\t  # Add in all the interfaces that we are compatible with.\n\t  loop=$age\n\t  while test \"$loop\" -ne 0; do\n\t    func_arith $current - $loop\n\t    iface=$func_arith_result\n\t    func_arith $loop - 1\n\t    loop=$func_arith_result\n\t    verstring=\"$verstring:${iface}.0\"\n\t  done\n\n\t  # Make executables depend on our current version.\n\t  verstring=\"$verstring:${current}.0\"\n\t  ;;\n\n\tqnx)\n\t  major=\".$current\"\n\t  versuffix=\".$current\"\n\t  ;;\n\n\tsunos)\n\t  major=\".$current\"\n\t  versuffix=\".$current.$revision\"\n\t  ;;\n\n\twindows)\n\t  # Use '-' rather than '.', since we only want one\n\t  # extension on DOS 8.3 filesystems.\n\t  func_arith $current - $age\n\t  major=$func_arith_result\n\t  versuffix=\"-$major\"\n\t  ;;\n\n\t*)\n\t  func_fatal_configuration \"unknown library version type \\`$version_type'\"\n\t  ;;\n\tesac\n\n\t# Clear the version info if we defaulted, and they specified a release.\n\tif test -z \"$vinfo\" && test -n \"$release\"; then\n\t  major=\n\t  case $version_type in\n\t  darwin)\n\t    # we can't check for \"0.0\" in archive_cmds due to quoting\n\t    # problems, so we reset it completely\n\t    verstring=\n\t    ;;\n\t  *)\n\t    verstring=\"0.0\"\n\t    ;;\n\t  esac\n\t  if test \"$need_version\" = no; then\n\t    versuffix=\n\t  else\n\t    versuffix=\".0.0\"\n\t  fi\n\tfi\n\n\t# Remove version info from name if versioning should be avoided\n\tif test \"$avoid_version\" = yes && test \"$need_version\" = no; then\n\t  major=\n\t  versuffix=\n\t  verstring=\"\"\n\tfi\n\n\t# Check to see if the archive will have undefined symbols.\n\tif test \"$allow_undefined\" = yes; then\n\t  if test \"$allow_undefined_flag\" = unsupported; then\n\t    func_warning \"undefined symbols not allowed in $host shared libraries\"\n\t    build_libtool_libs=no\n\t    build_old_libs=yes\n\t  fi\n\telse\n\t  # Don't allow undefined symbols.\n\t  allow_undefined_flag=\"$no_undefined_flag\"\n\tfi\n\n      fi\n\n      func_generate_dlsyms \"$libname\" \"$libname\" \"yes\"\n      libobjs=\"$libobjs $symfileobj\"\n      test \"X$libobjs\" = \"X \" && libobjs=\n\n      if test \"$mode\" != relink; then\n\t# Remove our outputs, but don't remove object files since they\n\t# may have been created when compiling PIC objects.\n\tremovelist=\n\ttempremovelist=`$ECHO \"$output_objdir/*\"`\n\tfor p in $tempremovelist; do\n\t  case $p in\n\t    *.$objext | *.gcno)\n\t       ;;\n\t    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)\n\t       if test \"X$precious_files_regex\" != \"X\"; then\n\t\t if $ECHO \"$p\" | $EGREP -e \"$precious_files_regex\" >/dev/null 2>&1\n\t\t then\n\t\t   continue\n\t\t fi\n\t       fi\n\t       removelist=\"$removelist $p\"\n\t       ;;\n\t    *) ;;\n\t  esac\n\tdone\n\ttest -n \"$removelist\" && \\\n\t  func_show_eval \"${RM}r \\$removelist\"\n      fi\n\n      # Now set the variables for building old libraries.\n      if test \"$build_old_libs\" = yes && test \"$build_libtool_libs\" != convenience ; then\n\toldlibs=\"$oldlibs $output_objdir/$libname.$libext\"\n\n\t# Transform .lo files to .o files.\n\toldobjs=\"$objs \"`$ECHO \"X$libobjs\" | $SP2NL | $Xsed -e '/\\.'${libext}'$/d' -e \"$lo2o\" | $NL2SP`\n      fi\n\n      # Eliminate all temporary directories.\n      #for path in $notinst_path; do\n      #\tlib_search_path=`$ECHO \"X$lib_search_path \" | $Xsed -e \"s% $path % %g\"`\n      #\tdeplibs=`$ECHO \"X$deplibs \" | $Xsed -e \"s% -L$path % %g\"`\n      #\tdependency_libs=`$ECHO \"X$dependency_libs \" | $Xsed -e \"s% -L$path % %g\"`\n      #done\n\n      if test -n \"$xrpath\"; then\n\t# If the user specified any rpath flags, then add them.\n\ttemp_xrpath=\n\tfor libdir in $xrpath; do\n\t  temp_xrpath=\"$temp_xrpath -R$libdir\"\n\t  case \"$finalize_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) finalize_rpath=\"$finalize_rpath $libdir\" ;;\n\t  esac\n\tdone\n\tif test \"$hardcode_into_libs\" != yes || test \"$build_old_libs\" = yes; then\n\t  dependency_libs=\"$temp_xrpath $dependency_libs\"\n\tfi\n      fi\n\n      # Make sure dlfiles contains only unique files that won't be dlpreopened\n      old_dlfiles=\"$dlfiles\"\n      dlfiles=\n      for lib in $old_dlfiles; do\n\tcase \" $dlprefiles $dlfiles \" in\n\t*\" $lib \"*) ;;\n\t*) dlfiles=\"$dlfiles $lib\" ;;\n\tesac\n      done\n\n      # Make sure dlprefiles contains only unique files\n      old_dlprefiles=\"$dlprefiles\"\n      dlprefiles=\n      for lib in $old_dlprefiles; do\n\tcase \"$dlprefiles \" in\n\t*\" $lib \"*) ;;\n\t*) dlprefiles=\"$dlprefiles $lib\" ;;\n\tesac\n      done\n\n      if test \"$build_libtool_libs\" = yes; then\n\tif test -n \"$rpath\"; then\n\t  case $host in\n\t  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)\n\t    # these systems don't actually have a c library (as such)!\n\t    ;;\n\t  *-*-rhapsody* | *-*-darwin1.[012])\n\t    # Rhapsody C library is in the System framework\n\t    deplibs=\"$deplibs System.ltframework\"\n\t    ;;\n\t  *-*-netbsd*)\n\t    # Don't link with libc until the a.out ld.so is fixed.\n\t    ;;\n\t  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)\n\t    # Do not include libc due to us having libc/libc_r.\n\t    ;;\n\t  *-*-sco3.2v5* | *-*-sco5v6*)\n\t    # Causes problems with __ctype\n\t    ;;\n\t  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)\n\t    # Compiler inserts libc in the correct place for threads to work\n\t    ;;\n\t  *)\n\t    # Add libc to deplibs on all other systems if necessary.\n\t    if test \"$build_libtool_need_lc\" = \"yes\"; then\n\t      deplibs=\"$deplibs -lc\"\n\t    fi\n\t    ;;\n\t  esac\n\tfi\n\n\t# Transform deplibs into only deplibs that can be linked in shared.\n\tname_save=$name\n\tlibname_save=$libname\n\trelease_save=$release\n\tversuffix_save=$versuffix\n\tmajor_save=$major\n\t# I'm not sure if I'm treating the release correctly.  I think\n\t# release should show up in the -l (ie -lgmp5) so we don't want to\n\t# add it in twice.  Is that correct?\n\trelease=\"\"\n\tversuffix=\"\"\n\tmajor=\"\"\n\tnewdeplibs=\n\tdroppeddeps=no\n\tcase $deplibs_check_method in\n\tpass_all)\n\t  # Don't check for shared/static.  Everything works.\n\t  # This might be a little naive.  We might want to check\n\t  # whether the library exists or not.  But this is on\n\t  # osf3 & osf4 and I'm not really sure... Just\n\t  # implementing what was already the behavior.\n\t  newdeplibs=$deplibs\n\t  ;;\n\ttest_compile)\n\t  # This code stresses the \"libraries are programs\" paradigm to its\n\t  # limits. Maybe even breaks it.  We compile a program, linking it\n\t  # against the deplibs as a proxy for the library.  Then we can check\n\t  # whether they linked in statically or dynamically with ldd.\n\t  $opt_dry_run || $RM conftest.c\n\t  cat > conftest.c <<EOF\n\t  int main() { return 0; }\nEOF\n\t  $opt_dry_run || $RM conftest\n\t  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then\n\t    ldd_output=`ldd conftest`\n\t    for i in $deplibs; do\n\t      case $i in\n\t      -l*)\n\t\tfunc_stripname -l '' \"$i\"\n\t\tname=$func_stripname_result\n\t\tif test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\t  case \" $predeps $postdeps \" in\n\t\t  *\" $i \"*)\n\t\t    newdeplibs=\"$newdeplibs $i\"\n\t\t    i=\"\"\n\t\t    ;;\n\t\t  esac\n\t\tfi\n\t\tif test -n \"$i\" ; then\n\t\t  libname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\t  deplib_matches=`eval \"\\\\$ECHO \\\"$library_names_spec\\\"\"`\n\t\t  set dummy $deplib_matches; shift\n\t\t  deplib_match=$1\n\t\t  if test `expr \"$ldd_output\" : \".*$deplib_match\"` -ne 0 ; then\n\t\t    newdeplibs=\"$newdeplibs $i\"\n\t\t  else\n\t\t    droppeddeps=yes\n\t\t    $ECHO\n\t\t    $ECHO \"*** Warning: dynamic linker does not accept needed library $i.\"\n\t\t    $ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t    $ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t    $ECHO \"*** shared version of the library, which I believe you do not have\"\n\t\t    $ECHO \"*** because a test_compile did reveal that the linker did not use it for\"\n\t\t    $ECHO \"*** its dynamic dependency list that programs get resolved with at runtime.\"\n\t\t  fi\n\t\tfi\n\t\t;;\n\t      *)\n\t\tnewdeplibs=\"$newdeplibs $i\"\n\t\t;;\n\t      esac\n\t    done\n\t  else\n\t    # Error occurred in the first compile.  Let's try to salvage\n\t    # the situation: Compile a separate program for each library.\n\t    for i in $deplibs; do\n\t      case $i in\n\t      -l*)\n\t\tfunc_stripname -l '' \"$i\"\n\t\tname=$func_stripname_result\n\t\t$opt_dry_run || $RM conftest\n\t\tif $LTCC $LTCFLAGS -o conftest conftest.c $i; then\n\t\t  ldd_output=`ldd conftest`\n\t\t  if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\t    case \" $predeps $postdeps \" in\n\t\t    *\" $i \"*)\n\t\t      newdeplibs=\"$newdeplibs $i\"\n\t\t      i=\"\"\n\t\t      ;;\n\t\t    esac\n\t\t  fi\n\t\t  if test -n \"$i\" ; then\n\t\t    libname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\t    deplib_matches=`eval \"\\\\$ECHO \\\"$library_names_spec\\\"\"`\n\t\t    set dummy $deplib_matches; shift\n\t\t    deplib_match=$1\n\t\t    if test `expr \"$ldd_output\" : \".*$deplib_match\"` -ne 0 ; then\n\t\t      newdeplibs=\"$newdeplibs $i\"\n\t\t    else\n\t\t      droppeddeps=yes\n\t\t      $ECHO\n\t\t      $ECHO \"*** Warning: dynamic linker does not accept needed library $i.\"\n\t\t      $ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t      $ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t      $ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t      $ECHO \"*** because a test_compile did reveal that the linker did not use this one\"\n\t\t      $ECHO \"*** as a dynamic dependency that programs can get resolved with at runtime.\"\n\t\t    fi\n\t\t  fi\n\t\telse\n\t\t  droppeddeps=yes\n\t\t  $ECHO\n\t\t  $ECHO \"*** Warning!  Library $i is needed by this library but I was not able to\"\n\t\t  $ECHO \"*** make it link in!  You will probably need to install it or some\"\n\t\t  $ECHO \"*** library that it depends on before this library will be fully\"\n\t\t  $ECHO \"*** functional.  Installing it before continuing would be even better.\"\n\t\tfi\n\t\t;;\n\t      *)\n\t\tnewdeplibs=\"$newdeplibs $i\"\n\t\t;;\n\t      esac\n\t    done\n\t  fi\n\t  ;;\n\tfile_magic*)\n\t  set dummy $deplibs_check_method; shift\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"$1 \\(.*\\)\"`\n\t  for a_deplib in $deplibs; do\n\t    case $a_deplib in\n\t    -l*)\n\t      func_stripname -l '' \"$a_deplib\"\n\t      name=$func_stripname_result\n\t      if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\tcase \" $predeps $postdeps \" in\n\t\t*\" $a_deplib \"*)\n\t\t  newdeplibs=\"$newdeplibs $a_deplib\"\n\t\t  a_deplib=\"\"\n\t\t  ;;\n\t\tesac\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tlibname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\tfor i in $lib_search_path $sys_lib_search_path $shlib_search_path; do\n\t\t  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`\n\t\t  for potent_lib in $potential_libs; do\n\t\t      # Follow soft links.\n\t\t      if ls -lLd \"$potent_lib\" 2>/dev/null |\n\t\t\t $GREP \" -> \" >/dev/null; then\n\t\t\tcontinue\n\t\t      fi\n\t\t      # The statement above tries to avoid entering an\n\t\t      # endless loop below, in case of cyclic links.\n\t\t      # We might still enter an endless loop, since a link\n\t\t      # loop can be closed while we follow links,\n\t\t      # but so what?\n\t\t      potlib=\"$potent_lib\"\n\t\t      while test -h \"$potlib\" 2>/dev/null; do\n\t\t\tpotliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`\n\t\t\tcase $potliblink in\n\t\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) potlib=\"$potliblink\";;\n\t\t\t*) potlib=`$ECHO \"X$potlib\" | $Xsed -e 's,[^/]*$,,'`\"$potliblink\";;\n\t\t\tesac\n\t\t      done\n\t\t      if eval $file_magic_cmd \\\"\\$potlib\\\" 2>/dev/null |\n\t\t\t $SED -e 10q |\n\t\t\t $EGREP \"$file_magic_regex\" > /dev/null; then\n\t\t\tnewdeplibs=\"$newdeplibs $a_deplib\"\n\t\t\ta_deplib=\"\"\n\t\t\tbreak 2\n\t\t      fi\n\t\t  done\n\t\tdone\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tdroppeddeps=yes\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: linker path does not have real file for library $a_deplib.\"\n\t\t$ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t$ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t$ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t$ECHO \"*** because I did check the linker path looking for a file starting\"\n\t\tif test -z \"$potlib\" ; then\n\t\t  $ECHO \"*** with $libname but no candidates were found. (...for file magic test)\"\n\t\telse\n\t\t  $ECHO \"*** with $libname and none of the candidates passed a file format test\"\n\t\t  $ECHO \"*** using a file magic. Last file checked: $potlib\"\n\t\tfi\n\t      fi\n\t      ;;\n\t    *)\n\t      # Add a -L argument.\n\t      newdeplibs=\"$newdeplibs $a_deplib\"\n\t      ;;\n\t    esac\n\t  done # Gone through all deplibs.\n\t  ;;\n\tmatch_pattern*)\n\t  set dummy $deplibs_check_method; shift\n\t  match_pattern_regex=`expr \"$deplibs_check_method\" : \"$1 \\(.*\\)\"`\n\t  for a_deplib in $deplibs; do\n\t    case $a_deplib in\n\t    -l*)\n\t      func_stripname -l '' \"$a_deplib\"\n\t      name=$func_stripname_result\n\t      if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\tcase \" $predeps $postdeps \" in\n\t\t*\" $a_deplib \"*)\n\t\t  newdeplibs=\"$newdeplibs $a_deplib\"\n\t\t  a_deplib=\"\"\n\t\t  ;;\n\t\tesac\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tlibname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\tfor i in $lib_search_path $sys_lib_search_path $shlib_search_path; do\n\t\t  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`\n\t\t  for potent_lib in $potential_libs; do\n\t\t    potlib=\"$potent_lib\" # see symlink-check above in file_magic test\n\t\t    if eval \"\\$ECHO \\\"X$potent_lib\\\"\" 2>/dev/null | $Xsed -e 10q | \\\n\t\t       $EGREP \"$match_pattern_regex\" > /dev/null; then\n\t\t      newdeplibs=\"$newdeplibs $a_deplib\"\n\t\t      a_deplib=\"\"\n\t\t      break 2\n\t\t    fi\n\t\t  done\n\t\tdone\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tdroppeddeps=yes\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: linker path does not have real file for library $a_deplib.\"\n\t\t$ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t$ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t$ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t$ECHO \"*** because I did check the linker path looking for a file starting\"\n\t\tif test -z \"$potlib\" ; then\n\t\t  $ECHO \"*** with $libname but no candidates were found. (...for regex pattern test)\"\n\t\telse\n\t\t  $ECHO \"*** with $libname and none of the candidates passed a file format test\"\n\t\t  $ECHO \"*** using a regex pattern. Last file checked: $potlib\"\n\t\tfi\n\t      fi\n\t      ;;\n\t    *)\n\t      # Add a -L argument.\n\t      newdeplibs=\"$newdeplibs $a_deplib\"\n\t      ;;\n\t    esac\n\t  done # Gone through all deplibs.\n\t  ;;\n\tnone | unknown | *)\n\t  newdeplibs=\"\"\n\t  tmp_deplibs=`$ECHO \"X $deplibs\" | $Xsed \\\n\t      -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`\n\t  if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t    for i in $predeps $postdeps ; do\n\t      # can't use Xsed below, because $i might contain '/'\n\t      tmp_deplibs=`$ECHO \"X $tmp_deplibs\" | $Xsed -e \"s,$i,,\"`\n\t    done\n\t  fi\n\t  if $ECHO \"X $tmp_deplibs\" | $Xsed -e 's/[\t ]//g' |\n\t     $GREP . >/dev/null; then\n\t    $ECHO\n\t    if test \"X$deplibs_check_method\" = \"Xnone\"; then\n\t      $ECHO \"*** Warning: inter-library dependencies are not supported in this platform.\"\n\t    else\n\t      $ECHO \"*** Warning: inter-library dependencies are not known to be supported.\"\n\t    fi\n\t    $ECHO \"*** All declared inter-library dependencies are being dropped.\"\n\t    droppeddeps=yes\n\t  fi\n\t  ;;\n\tesac\n\tversuffix=$versuffix_save\n\tmajor=$major_save\n\trelease=$release_save\n\tlibname=$libname_save\n\tname=$name_save\n\n\tcase $host in\n\t*-*-rhapsody* | *-*-darwin1.[012])\n\t  # On Rhapsody replace the C library with the System framework\n\t  newdeplibs=`$ECHO \"X $newdeplibs\" | $Xsed -e 's/ -lc / System.ltframework /'`\n\t  ;;\n\tesac\n\n\tif test \"$droppeddeps\" = yes; then\n\t  if test \"$module\" = yes; then\n\t    $ECHO\n\t    $ECHO \"*** Warning: libtool could not satisfy all declared inter-library\"\n\t    $ECHO \"*** dependencies of module $libname.  Therefore, libtool will create\"\n\t    $ECHO \"*** a static module, that should work as long as the dlopening\"\n\t    $ECHO \"*** application is linked with the -dlopen flag.\"\n\t    if test -z \"$global_symbol_pipe\"; then\n\t      $ECHO\n\t      $ECHO \"*** However, this would only work if libtool was able to extract symbol\"\n\t      $ECHO \"*** lists from a program, using \\`nm' or equivalent, but libtool could\"\n\t      $ECHO \"*** not find such a program.  So, this module is probably useless.\"\n\t      $ECHO \"*** \\`nm' from GNU binutils and a full rebuild may help.\"\n\t    fi\n\t    if test \"$build_old_libs\" = no; then\n\t      oldlibs=\"$output_objdir/$libname.$libext\"\n\t      build_libtool_libs=module\n\t      build_old_libs=yes\n\t    else\n\t      build_libtool_libs=no\n\t    fi\n\t  else\n\t    $ECHO \"*** The inter-library dependencies that have been dropped here will be\"\n\t    $ECHO \"*** automatically added whenever a program is linked with this library\"\n\t    $ECHO \"*** or is declared to -dlopen it.\"\n\n\t    if test \"$allow_undefined\" = no; then\n\t      $ECHO\n\t      $ECHO \"*** Since this library must not contain undefined symbols,\"\n\t      $ECHO \"*** because either the platform does not support them or\"\n\t      $ECHO \"*** it was explicitly requested with -no-undefined,\"\n\t      $ECHO \"*** libtool will only create a static version of it.\"\n\t      if test \"$build_old_libs\" = no; then\n\t\toldlibs=\"$output_objdir/$libname.$libext\"\n\t\tbuild_libtool_libs=module\n\t\tbuild_old_libs=yes\n\t      else\n\t\tbuild_libtool_libs=no\n\t      fi\n\t    fi\n\t  fi\n\tfi\n\t# Done checking deplibs!\n\tdeplibs=$newdeplibs\n      fi\n      # Time to change all our \"foo.ltframework\" stuff back to \"-framework foo\"\n      case $host in\n\t*-*-darwin*)\n\t  newdeplibs=`$ECHO \"X $newdeplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  new_inherited_linker_flags=`$ECHO \"X $new_inherited_linker_flags\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  deplibs=`$ECHO \"X $deplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  ;;\n      esac\n\n      # move library search paths that coincide with paths to not yet\n      # installed libraries to the beginning of the library search list\n      new_libs=\n      for path in $notinst_path; do\n\tcase \" $new_libs \" in\n\t*\" -L$path/$objdir \"*) ;;\n\t*)\n\t  case \" $deplibs \" in\n\t  *\" -L$path/$objdir \"*)\n\t    new_libs=\"$new_libs -L$path/$objdir\" ;;\n\t  esac\n\t  ;;\n\tesac\n      done\n      for deplib in $deplibs; do\n\tcase $deplib in\n\t-L*)\n\t  case \" $new_libs \" in\n\t  *\" $deplib \"*) ;;\n\t  *) new_libs=\"$new_libs $deplib\" ;;\n\t  esac\n\t  ;;\n\t*) new_libs=\"$new_libs $deplib\" ;;\n\tesac\n      done\n      deplibs=\"$new_libs\"\n\n      # All the library-specific variables (install_libdir is set above).\n      library_names=\n      old_library=\n      dlname=\n\n      # Test again, we may have decided not to build it any more\n      if test \"$build_libtool_libs\" = yes; then\n\tif test \"$hardcode_into_libs\" = yes; then\n\t  # Hardcode the library paths\n\t  hardcode_libdirs=\n\t  dep_rpath=\n\t  rpath=\"$finalize_rpath\"\n\t  test \"$mode\" != relink && rpath=\"$compile_rpath$rpath\"\n\t  for libdir in $rpath; do\n\t    if test -n \"$hardcode_libdir_flag_spec\"; then\n\t      if test -n \"$hardcode_libdir_separator\"; then\n\t\tif test -z \"$hardcode_libdirs\"; then\n\t\t  hardcode_libdirs=\"$libdir\"\n\t\telse\n\t\t  # Just accumulate the unique libdirs.\n\t\t  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in\n\t\t  *\"$hardcode_libdir_separator$libdir$hardcode_libdir_separator\"*)\n\t\t    ;;\n\t\t  *)\n\t\t    hardcode_libdirs=\"$hardcode_libdirs$hardcode_libdir_separator$libdir\"\n\t\t    ;;\n\t\t  esac\n\t\tfi\n\t      else\n\t\teval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\t\tdep_rpath=\"$dep_rpath $flag\"\n\t      fi\n\t    elif test -n \"$runpath_var\"; then\n\t      case \"$perm_rpath \" in\n\t      *\" $libdir \"*) ;;\n\t      *) perm_rpath=\"$perm_rpath $libdir\" ;;\n\t      esac\n\t    fi\n\t  done\n\t  # Substitute the hardcoded libdirs into the rpath.\n\t  if test -n \"$hardcode_libdir_separator\" &&\n\t     test -n \"$hardcode_libdirs\"; then\n\t    libdir=\"$hardcode_libdirs\"\n\t    if test -n \"$hardcode_libdir_flag_spec_ld\"; then\n\t      eval dep_rpath=\\\"$hardcode_libdir_flag_spec_ld\\\"\n\t    else\n\t      eval dep_rpath=\\\"$hardcode_libdir_flag_spec\\\"\n\t    fi\n\t  fi\n\t  if test -n \"$runpath_var\" && test -n \"$perm_rpath\"; then\n\t    # We should set the runpath_var.\n\t    rpath=\n\t    for dir in $perm_rpath; do\n\t      rpath=\"$rpath$dir:\"\n\t    done\n\t    eval \"$runpath_var='$rpath\\$$runpath_var'; export $runpath_var\"\n\t  fi\n\t  test -n \"$dep_rpath\" && deplibs=\"$dep_rpath $deplibs\"\n\tfi\n\n\tshlibpath=\"$finalize_shlibpath\"\n\ttest \"$mode\" != relink && shlibpath=\"$compile_shlibpath$shlibpath\"\n\tif test -n \"$shlibpath\"; then\n\t  eval \"$shlibpath_var='$shlibpath\\$$shlibpath_var'; export $shlibpath_var\"\n\tfi\n\n\t# Get the real and link names of the library.\n\teval shared_ext=\\\"$shrext_cmds\\\"\n\teval library_names=\\\"$library_names_spec\\\"\n\tset dummy $library_names\n\tshift\n\trealname=\"$1\"\n\tshift\n\n\tif test -n \"$soname_spec\"; then\n\t  eval soname=\\\"$soname_spec\\\"\n\telse\n\t  soname=\"$realname\"\n\tfi\n\tif test -z \"$dlname\"; then\n\t  dlname=$soname\n\tfi\n\n\tlib=\"$output_objdir/$realname\"\n\tlinknames=\n\tfor link\n\tdo\n\t  linknames=\"$linknames $link\"\n\tdone\n\n\t# Use standard objects if they are pic\n\ttest -z \"$pic_flag\" && libobjs=`$ECHO \"X$libobjs\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n\ttest \"X$libobjs\" = \"X \" && libobjs=\n\n\tdelfiles=\n\tif test -n \"$export_symbols\" && test -n \"$include_expsyms\"; then\n\t  $opt_dry_run || cp \"$export_symbols\" \"$output_objdir/$libname.uexp\"\n\t  export_symbols=\"$output_objdir/$libname.uexp\"\n\t  delfiles=\"$delfiles $export_symbols\"\n\tfi\n\n\torig_export_symbols=\n\tcase $host_os in\n\tcygwin* | mingw* | cegcc*)\n\t  if test -n \"$export_symbols\" && test -z \"$export_symbols_regex\"; then\n\t    # exporting using user supplied symfile\n\t    if test \"x`$SED 1q $export_symbols`\" != xEXPORTS; then\n\t      # and it's NOT already a .def file. Must figure out\n\t      # which of the given symbols are data symbols and tag\n\t      # them as such. So, trigger use of export_symbols_cmds.\n\t      # export_symbols gets reassigned inside the \"prepare\n\t      # the list of exported symbols\" if statement, so the\n\t      # include_expsyms logic still works.\n\t      orig_export_symbols=\"$export_symbols\"\n\t      export_symbols=\n\t      always_export_symbols=yes\n\t    fi\n\t  fi\n\t  ;;\n\tesac\n\n\t# Prepare the list of exported symbols\n\tif test -z \"$export_symbols\"; then\n\t  if test \"$always_export_symbols\" = yes || test -n \"$export_symbols_regex\"; then\n\t    func_verbose \"generating symbol list for \\`$libname.la'\"\n\t    export_symbols=\"$output_objdir/$libname.exp\"\n\t    $opt_dry_run || $RM $export_symbols\n\t    cmds=$export_symbols_cmds\n\t    save_ifs=\"$IFS\"; IFS='~'\n\t    for cmd in $cmds; do\n\t      IFS=\"$save_ifs\"\n\t      eval cmd=\\\"$cmd\\\"\n\t      func_len \" $cmd\"\n\t      len=$func_len_result\n\t      if test \"$len\" -lt \"$max_cmd_len\" || test \"$max_cmd_len\" -le -1; then\n\t\tfunc_show_eval \"$cmd\" 'exit $?'\n\t\tskipped_export=false\n\t      else\n\t\t# The command line is too long to execute in one step.\n\t\tfunc_verbose \"using reloadable object file for export list...\"\n\t\tskipped_export=:\n\t\t# Break out early, otherwise skipped_export may be\n\t\t# set to false by a later but shorter cmd.\n\t\tbreak\n\t      fi\n\t    done\n\t    IFS=\"$save_ifs\"\n\t    if test -n \"$export_symbols_regex\" && test \"X$skipped_export\" != \"X:\"; then\n\t      func_show_eval '$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"'\n\t      func_show_eval '$MV \"${export_symbols}T\" \"$export_symbols\"'\n\t    fi\n\t  fi\n\tfi\n\n\tif test -n \"$export_symbols\" && test -n \"$include_expsyms\"; then\n\t  tmp_export_symbols=\"$export_symbols\"\n\t  test -n \"$orig_export_symbols\" && tmp_export_symbols=\"$orig_export_symbols\"\n\t  $opt_dry_run || eval '$ECHO \"X$include_expsyms\" | $Xsed | $SP2NL >> \"$tmp_export_symbols\"'\n\tfi\n\n\tif test \"X$skipped_export\" != \"X:\" && test -n \"$orig_export_symbols\"; then\n\t  # The given exports_symbols file has to be filtered, so filter it.\n\t  func_verbose \"filter symbol list for \\`$libname.la' to tag DATA exports\"\n\t  # FIXME: $output_objdir/$libname.filter potentially contains lots of\n\t  # 's' commands which not all seds can handle. GNU sed should be fine\n\t  # though. Also, the filter scales superlinearly with the number of\n\t  # global variables. join(1) would be nice here, but unfortunately\n\t  # isn't a blessed tool.\n\t  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\\(.*\\)\\([ \\,].*\\),s|^\\1$|\\1\\2|,' < $export_symbols > $output_objdir/$libname.filter\n\t  delfiles=\"$delfiles $export_symbols $output_objdir/$libname.filter\"\n\t  export_symbols=$output_objdir/$libname.def\n\t  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols\n\tfi\n\n\ttmp_deplibs=\n\tfor test_deplib in $deplibs; do\n\t  case \" $convenience \" in\n\t  *\" $test_deplib \"*) ;;\n\t  *)\n\t    tmp_deplibs=\"$tmp_deplibs $test_deplib\"\n\t    ;;\n\t  esac\n\tdone\n\tdeplibs=\"$tmp_deplibs\"\n\n\tif test -n \"$convenience\"; then\n\t  if test -n \"$whole_archive_flag_spec\" &&\n\t    test \"$compiler_needs_object\" = yes &&\n\t    test -z \"$libobjs\"; then\n\t    # extract the archives, so we have objects to list.\n\t    # TODO: could optimize this to just extract one archive.\n\t    whole_archive_flag_spec=\n\t  fi\n\t  if test -n \"$whole_archive_flag_spec\"; then\n\t    save_libobjs=$libobjs\n\t    eval libobjs=\\\"\\$libobjs $whole_archive_flag_spec\\\"\n\t    test \"X$libobjs\" = \"X \" && libobjs=\n\t  else\n\t    gentop=\"$output_objdir/${outputname}x\"\n\t    generated=\"$generated $gentop\"\n\n\t    func_extract_archives $gentop $convenience\n\t    libobjs=\"$libobjs $func_extract_archives_result\"\n\t    test \"X$libobjs\" = \"X \" && libobjs=\n\t  fi\n\tfi\n\n\tif test \"$thread_safe\" = yes && test -n \"$thread_safe_flag_spec\"; then\n\t  eval flag=\\\"$thread_safe_flag_spec\\\"\n\t  linker_flags=\"$linker_flags $flag\"\n\tfi\n\n\t# Make a backup of the uninstalled library when relinking\n\tif test \"$mode\" = relink; then\n\t  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?\n\tfi\n\n\t# Do each of the archive commands.\n\tif test \"$module\" = yes && test -n \"$module_cmds\" ; then\n\t  if test -n \"$export_symbols\" && test -n \"$module_expsym_cmds\"; then\n\t    eval test_cmds=\\\"$module_expsym_cmds\\\"\n\t    cmds=$module_expsym_cmds\n\t  else\n\t    eval test_cmds=\\\"$module_cmds\\\"\n\t    cmds=$module_cmds\n\t  fi\n\telse\n\t  if test -n \"$export_symbols\" && test -n \"$archive_expsym_cmds\"; then\n\t    eval test_cmds=\\\"$archive_expsym_cmds\\\"\n\t    cmds=$archive_expsym_cmds\n\t  else\n\t    eval test_cmds=\\\"$archive_cmds\\\"\n\t    cmds=$archive_cmds\n\t  fi\n\tfi\n\n\tif test \"X$skipped_export\" != \"X:\" &&\n\t   func_len \" $test_cmds\" &&\n\t   len=$func_len_result &&\n\t   test \"$len\" -lt \"$max_cmd_len\" || test \"$max_cmd_len\" -le -1; then\n\t  :\n\telse\n\t  # The command line is too long to link in one step, link piecewise\n\t  # or, if using GNU ld and skipped_export is not :, use a linker\n\t  # script.\n\n\t  # Save the value of $output and $libobjs because we want to\n\t  # use them later.  If we have whole_archive_flag_spec, we\n\t  # want to use save_libobjs as it was before\n\t  # whole_archive_flag_spec was expanded, because we can't\n\t  # assume the linker understands whole_archive_flag_spec.\n\t  # This may have to be revisited, in case too many\n\t  # convenience libraries get linked in and end up exceeding\n\t  # the spec.\n\t  if test -z \"$convenience\" || test -z \"$whole_archive_flag_spec\"; then\n\t    save_libobjs=$libobjs\n\t  fi\n\t  save_output=$output\n\t  output_la=`$ECHO \"X$output\" | $Xsed -e \"$basename\"`\n\n\t  # Clear the reloadable object creation command queue and\n\t  # initialize k to one.\n\t  test_cmds=\n\t  concat_cmds=\n\t  objlist=\n\t  last_robj=\n\t  k=1\n\n\t  if test -n \"$save_libobjs\" && test \"X$skipped_export\" != \"X:\" && test \"$with_gnu_ld\" = yes; then\n\t    output=${output_objdir}/${output_la}.lnkscript\n\t    func_verbose \"creating GNU ld script: $output\"\n\t    $ECHO 'INPUT (' > $output\n\t    for obj in $save_libobjs\n\t    do\n\t      $ECHO \"$obj\" >> $output\n\t    done\n\t    $ECHO ')' >> $output\n\t    delfiles=\"$delfiles $output\"\n\t  elif test -n \"$save_libobjs\" && test \"X$skipped_export\" != \"X:\" && test \"X$file_list_spec\" != X; then\n\t    output=${output_objdir}/${output_la}.lnk\n\t    func_verbose \"creating linker input file list: $output\"\n\t    : > $output\n\t    set x $save_libobjs\n\t    shift\n\t    firstobj=\n\t    if test \"$compiler_needs_object\" = yes; then\n\t      firstobj=\"$1 \"\n\t      shift\n\t    fi\n\t    for obj\n\t    do\n\t      $ECHO \"$obj\" >> $output\n\t    done\n\t    delfiles=\"$delfiles $output\"\n\t    output=$firstobj\\\"$file_list_spec$output\\\"\n\t  else\n\t    if test -n \"$save_libobjs\"; then\n\t      func_verbose \"creating reloadable object files...\"\n\t      output=$output_objdir/$output_la-${k}.$objext\n\t      eval test_cmds=\\\"$reload_cmds\\\"\n\t      func_len \" $test_cmds\"\n\t      len0=$func_len_result\n\t      len=$len0\n\n\t      # Loop over the list of objects to be linked.\n\t      for obj in $save_libobjs\n\t      do\n\t\tfunc_len \" $obj\"\n\t\tfunc_arith $len + $func_len_result\n\t\tlen=$func_arith_result\n\t\tif test \"X$objlist\" = X ||\n\t\t   test \"$len\" -lt \"$max_cmd_len\"; then\n\t\t  func_append objlist \" $obj\"\n\t\telse\n\t\t  # The command $test_cmds is almost too long, add a\n\t\t  # command to the queue.\n\t\t  if test \"$k\" -eq 1 ; then\n\t\t    # The first file doesn't have a previous command to add.\n\t\t    eval concat_cmds=\\\"$reload_cmds $objlist $last_robj\\\"\n\t\t  else\n\t\t    # All subsequent reloadable object files will link in\n\t\t    # the last one created.\n\t\t    eval concat_cmds=\\\"\\$concat_cmds~$reload_cmds $objlist $last_robj~\\$RM $last_robj\\\"\n\t\t  fi\n\t\t  last_robj=$output_objdir/$output_la-${k}.$objext\n\t\t  func_arith $k + 1\n\t\t  k=$func_arith_result\n\t\t  output=$output_objdir/$output_la-${k}.$objext\n\t\t  objlist=$obj\n\t\t  func_len \" $last_robj\"\n\t\t  func_arith $len0 + $func_len_result\n\t\t  len=$func_arith_result\n\t\tfi\n\t      done\n\t      # Handle the remaining objects by creating one last\n\t      # reloadable object file.  All subsequent reloadable object\n\t      # files will link in the last one created.\n\t      test -z \"$concat_cmds\" || concat_cmds=$concat_cmds~\n\t      eval concat_cmds=\\\"\\${concat_cmds}$reload_cmds $objlist $last_robj\\\"\n\t      if test -n \"$last_robj\"; then\n\t        eval concat_cmds=\\\"\\${concat_cmds}~\\$RM $last_robj\\\"\n\t      fi\n\t      delfiles=\"$delfiles $output\"\n\n\t    else\n\t      output=\n\t    fi\n\n\t    if ${skipped_export-false}; then\n\t      func_verbose \"generating symbol list for \\`$libname.la'\"\n\t      export_symbols=\"$output_objdir/$libname.exp\"\n\t      $opt_dry_run || $RM $export_symbols\n\t      libobjs=$output\n\t      # Append the command to create the export file.\n\t      test -z \"$concat_cmds\" || concat_cmds=$concat_cmds~\n\t      eval concat_cmds=\\\"\\$concat_cmds$export_symbols_cmds\\\"\n\t      if test -n \"$last_robj\"; then\n\t\teval concat_cmds=\\\"\\$concat_cmds~\\$RM $last_robj\\\"\n\t      fi\n\t    fi\n\n\t    test -n \"$save_libobjs\" &&\n\t      func_verbose \"creating a temporary reloadable object file: $output\"\n\n\t    # Loop through the commands generated above and execute them.\n\t    save_ifs=\"$IFS\"; IFS='~'\n\t    for cmd in $concat_cmds; do\n\t      IFS=\"$save_ifs\"\n\t      $opt_silent || {\n\t\t  func_quote_for_expand \"$cmd\"\n\t\t  eval \"func_echo $func_quote_for_expand_result\"\n\t      }\n\t      $opt_dry_run || eval \"$cmd\" || {\n\t\tlt_exit=$?\n\n\t\t# Restore the uninstalled library and exit\n\t\tif test \"$mode\" = relink; then\n\t\t  ( cd \"$output_objdir\" && \\\n\t\t    $RM \"${realname}T\" && \\\n\t\t    $MV \"${realname}U\" \"$realname\" )\n\t\tfi\n\n\t\texit $lt_exit\n\t      }\n\t    done\n\t    IFS=\"$save_ifs\"\n\n\t    if test -n \"$export_symbols_regex\" && ${skipped_export-false}; then\n\t      func_show_eval '$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"'\n\t      func_show_eval '$MV \"${export_symbols}T\" \"$export_symbols\"'\n\t    fi\n\t  fi\n\n          if ${skipped_export-false}; then\n\t    if test -n \"$export_symbols\" && test -n \"$include_expsyms\"; then\n\t      tmp_export_symbols=\"$export_symbols\"\n\t      test -n \"$orig_export_symbols\" && tmp_export_symbols=\"$orig_export_symbols\"\n\t      $opt_dry_run || eval '$ECHO \"X$include_expsyms\" | $Xsed | $SP2NL >> \"$tmp_export_symbols\"'\n\t    fi\n\n\t    if test -n \"$orig_export_symbols\"; then\n\t      # The given exports_symbols file has to be filtered, so filter it.\n\t      func_verbose \"filter symbol list for \\`$libname.la' to tag DATA exports\"\n\t      # FIXME: $output_objdir/$libname.filter potentially contains lots of\n\t      # 's' commands which not all seds can handle. GNU sed should be fine\n\t      # though. Also, the filter scales superlinearly with the number of\n\t      # global variables. join(1) would be nice here, but unfortunately\n\t      # isn't a blessed tool.\n\t      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\\(.*\\)\\([ \\,].*\\),s|^\\1$|\\1\\2|,' < $export_symbols > $output_objdir/$libname.filter\n\t      delfiles=\"$delfiles $export_symbols $output_objdir/$libname.filter\"\n\t      export_symbols=$output_objdir/$libname.def\n\t      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols\n\t    fi\n\t  fi\n\n\t  libobjs=$output\n\t  # Restore the value of output.\n\t  output=$save_output\n\n\t  if test -n \"$convenience\" && test -n \"$whole_archive_flag_spec\"; then\n\t    eval libobjs=\\\"\\$libobjs $whole_archive_flag_spec\\\"\n\t    test \"X$libobjs\" = \"X \" && libobjs=\n\t  fi\n\t  # Expand the library linking commands again to reset the\n\t  # value of $libobjs for piecewise linking.\n\n\t  # Do each of the archive commands.\n\t  if test \"$module\" = yes && test -n \"$module_cmds\" ; then\n\t    if test -n \"$export_symbols\" && test -n \"$module_expsym_cmds\"; then\n\t      cmds=$module_expsym_cmds\n\t    else\n\t      cmds=$module_cmds\n\t    fi\n\t  else\n\t    if test -n \"$export_symbols\" && test -n \"$archive_expsym_cmds\"; then\n\t      cmds=$archive_expsym_cmds\n\t    else\n\t      cmds=$archive_cmds\n\t    fi\n\t  fi\n\tfi\n\n\tif test -n \"$delfiles\"; then\n\t  # Append the command to remove temporary files to $cmds.\n\t  eval cmds=\\\"\\$cmds~\\$RM $delfiles\\\"\n\tfi\n\n\t# Add any objects from preloaded convenience libraries\n\tif test -n \"$dlprefiles\"; then\n\t  gentop=\"$output_objdir/${outputname}x\"\n\t  generated=\"$generated $gentop\"\n\n\t  func_extract_archives $gentop $dlprefiles\n\t  libobjs=\"$libobjs $func_extract_archives_result\"\n\t  test \"X$libobjs\" = \"X \" && libobjs=\n\tfi\n\n\tsave_ifs=\"$IFS\"; IFS='~'\n\tfor cmd in $cmds; do\n\t  IFS=\"$save_ifs\"\n\t  eval cmd=\\\"$cmd\\\"\n\t  $opt_silent || {\n\t    func_quote_for_expand \"$cmd\"\n\t    eval \"func_echo $func_quote_for_expand_result\"\n\t  }\n\t  $opt_dry_run || eval \"$cmd\" || {\n\t    lt_exit=$?\n\n\t    # Restore the uninstalled library and exit\n\t    if test \"$mode\" = relink; then\n\t      ( cd \"$output_objdir\" && \\\n\t        $RM \"${realname}T\" && \\\n\t\t$MV \"${realname}U\" \"$realname\" )\n\t    fi\n\n\t    exit $lt_exit\n\t  }\n\tdone\n\tIFS=\"$save_ifs\"\n\n\t# Restore the uninstalled library and exit\n\tif test \"$mode\" = relink; then\n\t  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?\n\n\t  if test -n \"$convenience\"; then\n\t    if test -z \"$whole_archive_flag_spec\"; then\n\t      func_show_eval '${RM}r \"$gentop\"'\n\t    fi\n\t  fi\n\n\t  exit $EXIT_SUCCESS\n\tfi\n\n\t# Create links to the real library.\n\tfor linkname in $linknames; do\n\t  if test \"$realname\" != \"$linkname\"; then\n\t    func_show_eval '(cd \"$output_objdir\" && $RM \"$linkname\" && $LN_S \"$realname\" \"$linkname\")' 'exit $?'\n\t  fi\n\tdone\n\n\t# If -module or -export-dynamic was specified, set the dlname.\n\tif test \"$module\" = yes || test \"$export_dynamic\" = yes; then\n\t  # On all known operating systems, these are identical.\n\t  dlname=\"$soname\"\n\tfi\n      fi\n      ;;\n\n    obj)\n      if test -n \"$dlfiles$dlprefiles\" || test \"$dlself\" != no; then\n\tfunc_warning \"\\`-dlopen' is ignored for objects\"\n      fi\n\n      case \" $deplibs\" in\n      *\\ -l* | *\\ -L*)\n\tfunc_warning \"\\`-l' and \\`-L' are ignored for objects\" ;;\n      esac\n\n      test -n \"$rpath\" && \\\n\tfunc_warning \"\\`-rpath' is ignored for objects\"\n\n      test -n \"$xrpath\" && \\\n\tfunc_warning \"\\`-R' is ignored for objects\"\n\n      test -n \"$vinfo\" && \\\n\tfunc_warning \"\\`-version-info' is ignored for objects\"\n\n      test -n \"$release\" && \\\n\tfunc_warning \"\\`-release' is ignored for objects\"\n\n      case $output in\n      *.lo)\n\ttest -n \"$objs$old_deplibs\" && \\\n\t  func_fatal_error \"cannot build library object \\`$output' from non-libtool objects\"\n\n\tlibobj=$output\n\tfunc_lo2o \"$libobj\"\n\tobj=$func_lo2o_result\n\t;;\n      *)\n\tlibobj=\n\tobj=\"$output\"\n\t;;\n      esac\n\n      # Delete the old objects.\n      $opt_dry_run || $RM $obj $libobj\n\n      # Objects from convenience libraries.  This assumes\n      # single-version convenience libraries.  Whenever we create\n      # different ones for PIC/non-PIC, this we'll have to duplicate\n      # the extraction.\n      reload_conv_objs=\n      gentop=\n      # reload_cmds runs $LD directly, so let us get rid of\n      # -Wl from whole_archive_flag_spec and hope we can get by with\n      # turning comma into space..\n      wl=\n\n      if test -n \"$convenience\"; then\n\tif test -n \"$whole_archive_flag_spec\"; then\n\t  eval tmp_whole_archive_flags=\\\"$whole_archive_flag_spec\\\"\n\t  reload_conv_objs=$reload_objs\\ `$ECHO \"X$tmp_whole_archive_flags\" | $Xsed -e 's|,| |g'`\n\telse\n\t  gentop=\"$output_objdir/${obj}x\"\n\t  generated=\"$generated $gentop\"\n\n\t  func_extract_archives $gentop $convenience\n\t  reload_conv_objs=\"$reload_objs $func_extract_archives_result\"\n\tfi\n      fi\n\n      # Create the old-style object.\n      reload_objs=\"$objs$old_deplibs \"`$ECHO \"X$libobjs\" | $SP2NL | $Xsed -e '/\\.'${libext}$'/d' -e '/\\.lib$/d' -e \"$lo2o\" | $NL2SP`\" $reload_conv_objs\" ### testsuite: skip nested quoting test\n\n      output=\"$obj\"\n      func_execute_cmds \"$reload_cmds\" 'exit $?'\n\n      # Exit if we aren't doing a library object file.\n      if test -z \"$libobj\"; then\n\tif test -n \"$gentop\"; then\n\t  func_show_eval '${RM}r \"$gentop\"'\n\tfi\n\n\texit $EXIT_SUCCESS\n      fi\n\n      if test \"$build_libtool_libs\" != yes; then\n\tif test -n \"$gentop\"; then\n\t  func_show_eval '${RM}r \"$gentop\"'\n\tfi\n\n\t# Create an invalid libtool object if no PIC, so that we don't\n\t# accidentally link it into a program.\n\t# $show \"echo timestamp > $libobj\"\n\t# $opt_dry_run || eval \"echo timestamp > $libobj\" || exit $?\n\texit $EXIT_SUCCESS\n      fi\n\n      if test -n \"$pic_flag\" || test \"$pic_mode\" != default; then\n\t# Only do commands if we really have different PIC objects.\n\treload_objs=\"$libobjs $reload_conv_objs\"\n\toutput=\"$libobj\"\n\tfunc_execute_cmds \"$reload_cmds\" 'exit $?'\n      fi\n\n      if test -n \"$gentop\"; then\n\tfunc_show_eval '${RM}r \"$gentop\"'\n      fi\n\n      exit $EXIT_SUCCESS\n      ;;\n\n    prog)\n      case $host in\n\t*cygwin*) func_stripname '' '.exe' \"$output\"\n\t          output=$func_stripname_result.exe;;\n      esac\n      test -n \"$vinfo\" && \\\n\tfunc_warning \"\\`-version-info' is ignored for programs\"\n\n      test -n \"$release\" && \\\n\tfunc_warning \"\\`-release' is ignored for programs\"\n\n      test \"$preload\" = yes \\\n        && test \"$dlopen_support\" = unknown \\\n\t&& test \"$dlopen_self\" = unknown \\\n\t&& test \"$dlopen_self_static\" = unknown && \\\n\t  func_warning \"\\`LT_INIT([dlopen])' not used. Assuming no dlopen support.\"\n\n      case $host in\n      *-*-rhapsody* | *-*-darwin1.[012])\n\t# On Rhapsody replace the C library is the System framework\n\tcompile_deplibs=`$ECHO \"X $compile_deplibs\" | $Xsed -e 's/ -lc / System.ltframework /'`\n\tfinalize_deplibs=`$ECHO \"X $finalize_deplibs\" | $Xsed -e 's/ -lc / System.ltframework /'`\n\t;;\n      esac\n\n      case $host in\n      *-*-darwin*)\n\t# Don't allow lazy linking, it breaks C++ global constructors\n\t# But is supposedly fixed on 10.4 or later (yay!).\n\tif test \"$tagname\" = CXX ; then\n\t  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in\n\t    10.[0123])\n\t      compile_command=\"$compile_command ${wl}-bind_at_load\"\n\t      finalize_command=\"$finalize_command ${wl}-bind_at_load\"\n\t    ;;\n\t  esac\n\tfi\n\t# Time to change all our \"foo.ltframework\" stuff back to \"-framework foo\"\n\tcompile_deplibs=`$ECHO \"X $compile_deplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tfinalize_deplibs=`$ECHO \"X $finalize_deplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t;;\n      esac\n\n\n      # move library search paths that coincide with paths to not yet\n      # installed libraries to the beginning of the library search list\n      new_libs=\n      for path in $notinst_path; do\n\tcase \" $new_libs \" in\n\t*\" -L$path/$objdir \"*) ;;\n\t*)\n\t  case \" $compile_deplibs \" in\n\t  *\" -L$path/$objdir \"*)\n\t    new_libs=\"$new_libs -L$path/$objdir\" ;;\n\t  esac\n\t  ;;\n\tesac\n      done\n      for deplib in $compile_deplibs; do\n\tcase $deplib in\n\t-L*)\n\t  case \" $new_libs \" in\n\t  *\" $deplib \"*) ;;\n\t  *) new_libs=\"$new_libs $deplib\" ;;\n\t  esac\n\t  ;;\n\t*) new_libs=\"$new_libs $deplib\" ;;\n\tesac\n      done\n      compile_deplibs=\"$new_libs\"\n\n\n      compile_command=\"$compile_command $compile_deplibs\"\n      finalize_command=\"$finalize_command $finalize_deplibs\"\n\n      if test -n \"$rpath$xrpath\"; then\n\t# If the user specified any rpath flags, then add them.\n\tfor libdir in $rpath $xrpath; do\n\t  # This is the magic to use -rpath.\n\t  case \"$finalize_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) finalize_rpath=\"$finalize_rpath $libdir\" ;;\n\t  esac\n\tdone\n      fi\n\n      # Now hardcode the library paths\n      rpath=\n      hardcode_libdirs=\n      for libdir in $compile_rpath $finalize_rpath; do\n\tif test -n \"$hardcode_libdir_flag_spec\"; then\n\t  if test -n \"$hardcode_libdir_separator\"; then\n\t    if test -z \"$hardcode_libdirs\"; then\n\t      hardcode_libdirs=\"$libdir\"\n\t    else\n\t      # Just accumulate the unique libdirs.\n\t      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in\n\t      *\"$hardcode_libdir_separator$libdir$hardcode_libdir_separator\"*)\n\t\t;;\n\t      *)\n\t\thardcode_libdirs=\"$hardcode_libdirs$hardcode_libdir_separator$libdir\"\n\t\t;;\n\t      esac\n\t    fi\n\t  else\n\t    eval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\t    rpath=\"$rpath $flag\"\n\t  fi\n\telif test -n \"$runpath_var\"; then\n\t  case \"$perm_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) perm_rpath=\"$perm_rpath $libdir\" ;;\n\t  esac\n\tfi\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n\t  testbindir=`${ECHO} \"$libdir\" | ${SED} -e 's*/lib$*/bin*'`\n\t  case :$dllsearchpath: in\n\t  *\":$libdir:\"*) ;;\n\t  ::) dllsearchpath=$libdir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$libdir\";;\n\t  esac\n\t  case :$dllsearchpath: in\n\t  *\":$testbindir:\"*) ;;\n\t  ::) dllsearchpath=$testbindir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$testbindir\";;\n\t  esac\n\t  ;;\n\tesac\n      done\n      # Substitute the hardcoded libdirs into the rpath.\n      if test -n \"$hardcode_libdir_separator\" &&\n\t test -n \"$hardcode_libdirs\"; then\n\tlibdir=\"$hardcode_libdirs\"\n\teval rpath=\\\" $hardcode_libdir_flag_spec\\\"\n      fi\n      compile_rpath=\"$rpath\"\n\n      rpath=\n      hardcode_libdirs=\n      for libdir in $finalize_rpath; do\n\tif test -n \"$hardcode_libdir_flag_spec\"; then\n\t  if test -n \"$hardcode_libdir_separator\"; then\n\t    if test -z \"$hardcode_libdirs\"; then\n\t      hardcode_libdirs=\"$libdir\"\n\t    else\n\t      # Just accumulate the unique libdirs.\n\t      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in\n\t      *\"$hardcode_libdir_separator$libdir$hardcode_libdir_separator\"*)\n\t\t;;\n\t      *)\n\t\thardcode_libdirs=\"$hardcode_libdirs$hardcode_libdir_separator$libdir\"\n\t\t;;\n\t      esac\n\t    fi\n\t  else\n\t    eval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\t    rpath=\"$rpath $flag\"\n\t  fi\n\telif test -n \"$runpath_var\"; then\n\t  case \"$finalize_perm_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) finalize_perm_rpath=\"$finalize_perm_rpath $libdir\" ;;\n\t  esac\n\tfi\n      done\n      # Substitute the hardcoded libdirs into the rpath.\n      if test -n \"$hardcode_libdir_separator\" &&\n\t test -n \"$hardcode_libdirs\"; then\n\tlibdir=\"$hardcode_libdirs\"\n\teval rpath=\\\" $hardcode_libdir_flag_spec\\\"\n      fi\n      finalize_rpath=\"$rpath\"\n\n      if test -n \"$libobjs\" && test \"$build_old_libs\" = yes; then\n\t# Transform all the library objects into standard objects.\n\tcompile_command=`$ECHO \"X$compile_command\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n\tfinalize_command=`$ECHO \"X$finalize_command\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n      fi\n\n      func_generate_dlsyms \"$outputname\" \"@PROGRAM@\" \"no\"\n\n      # template prelinking step\n      if test -n \"$prelink_cmds\"; then\n\tfunc_execute_cmds \"$prelink_cmds\" 'exit $?'\n      fi\n\n      wrappers_required=yes\n      case $host in\n      *cygwin* | *mingw* )\n        if test \"$build_libtool_libs\" != yes; then\n          wrappers_required=no\n        fi\n        ;;\n      *cegcc)\n        # Disable wrappers for cegcc, we are cross compiling anyway.\n        wrappers_required=no\n        ;;\n      *)\n        if test \"$need_relink\" = no || test \"$build_libtool_libs\" != yes; then\n          wrappers_required=no\n        fi\n        ;;\n      esac\n      if test \"$wrappers_required\" = no; then\n\t# Replace the output file specification.\n\tcompile_command=`$ECHO \"X$compile_command\" | $Xsed -e 's%@OUTPUT@%'\"$output\"'%g'`\n\tlink_command=\"$compile_command$compile_rpath\"\n\n\t# We have no uninstalled library dependencies, so finalize right now.\n\texit_status=0\n\tfunc_show_eval \"$link_command\" 'exit_status=$?'\n\n\t# Delete the generated files.\n\tif test -f \"$output_objdir/${outputname}S.${objext}\"; then\n\t  func_show_eval '$RM \"$output_objdir/${outputname}S.${objext}\"'\n\tfi\n\n\texit $exit_status\n      fi\n\n      if test -n \"$compile_shlibpath$finalize_shlibpath\"; then\n\tcompile_command=\"$shlibpath_var=\\\"$compile_shlibpath$finalize_shlibpath\\$$shlibpath_var\\\" $compile_command\"\n      fi\n      if test -n \"$finalize_shlibpath\"; then\n\tfinalize_command=\"$shlibpath_var=\\\"$finalize_shlibpath\\$$shlibpath_var\\\" $finalize_command\"\n      fi\n\n      compile_var=\n      finalize_var=\n      if test -n \"$runpath_var\"; then\n\tif test -n \"$perm_rpath\"; then\n\t  # We should set the runpath_var.\n\t  rpath=\n\t  for dir in $perm_rpath; do\n\t    rpath=\"$rpath$dir:\"\n\t  done\n\t  compile_var=\"$runpath_var=\\\"$rpath\\$$runpath_var\\\" \"\n\tfi\n\tif test -n \"$finalize_perm_rpath\"; then\n\t  # We should set the runpath_var.\n\t  rpath=\n\t  for dir in $finalize_perm_rpath; do\n\t    rpath=\"$rpath$dir:\"\n\t  done\n\t  finalize_var=\"$runpath_var=\\\"$rpath\\$$runpath_var\\\" \"\n\tfi\n      fi\n\n      if test \"$no_install\" = yes; then\n\t# We don't need to create a wrapper script.\n\tlink_command=\"$compile_var$compile_command$compile_rpath\"\n\t# Replace the output file specification.\n\tlink_command=`$ECHO \"X$link_command\" | $Xsed -e 's%@OUTPUT@%'\"$output\"'%g'`\n\t# Delete the old output file.\n\t$opt_dry_run || $RM $output\n\t# Link the executable and exit\n\tfunc_show_eval \"$link_command\" 'exit $?'\n\texit $EXIT_SUCCESS\n      fi\n\n      if test \"$hardcode_action\" = relink; then\n\t# Fast installation is not supported\n\tlink_command=\"$compile_var$compile_command$compile_rpath\"\n\trelink_command=\"$finalize_var$finalize_command$finalize_rpath\"\n\n\tfunc_warning \"this platform does not like uninstalled shared libraries\"\n\tfunc_warning \"\\`$output' will be relinked during installation\"\n      else\n\tif test \"$fast_install\" != no; then\n\t  link_command=\"$finalize_var$compile_command$finalize_rpath\"\n\t  if test \"$fast_install\" = yes; then\n\t    relink_command=`$ECHO \"X$compile_var$compile_command$compile_rpath\" | $Xsed -e 's%@OUTPUT@%\\$progdir/\\$file%g'`\n\t  else\n\t    # fast_install is set to needless\n\t    relink_command=\n\t  fi\n\telse\n\t  link_command=\"$compile_var$compile_command$compile_rpath\"\n\t  relink_command=\"$finalize_var$finalize_command$finalize_rpath\"\n\tfi\n      fi\n\n      # Replace the output file specification.\n      link_command=`$ECHO \"X$link_command\" | $Xsed -e 's%@OUTPUT@%'\"$output_objdir/$outputname\"'%g'`\n\n      # Delete the old output files.\n      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname\n\n      func_show_eval \"$link_command\" 'exit $?'\n\n      # Now create the wrapper script.\n      func_verbose \"creating $output\"\n\n      # Quote the relink command for shipping.\n      if test -n \"$relink_command\"; then\n\t# Preserve any variables that may affect compiler behavior\n\tfor var in $variables_saved_for_relink; do\n\t  if eval test -z \\\"\\${$var+set}\\\"; then\n\t    relink_command=\"{ test -z \\\"\\${$var+set}\\\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command\"\n\t  elif eval var_value=\\$$var; test -z \"$var_value\"; then\n\t    relink_command=\"$var=; export $var; $relink_command\"\n\t  else\n\t    func_quote_for_eval \"$var_value\"\n\t    relink_command=\"$var=$func_quote_for_eval_result; export $var; $relink_command\"\n\t  fi\n\tdone\n\trelink_command=\"(cd `pwd`; $relink_command)\"\n\trelink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"$sed_quote_subst\"`\n      fi\n\n      # Quote $ECHO for shipping.\n      if test \"X$ECHO\" = \"X$SHELL $progpath --fallback-echo\"; then\n\tcase $progpath in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) qecho=\"$SHELL $progpath --fallback-echo\";;\n\t*) qecho=\"$SHELL `pwd`/$progpath --fallback-echo\";;\n\tesac\n\tqecho=`$ECHO \"X$qecho\" | $Xsed -e \"$sed_quote_subst\"`\n      else\n\tqecho=`$ECHO \"X$ECHO\" | $Xsed -e \"$sed_quote_subst\"`\n      fi\n\n      # Only actually do things if not in dry run mode.\n      $opt_dry_run || {\n\t# win32 will think the script is a binary if it has\n\t# a .exe suffix, so we strip it off here.\n\tcase $output in\n\t  *.exe) func_stripname '' '.exe' \"$output\"\n\t         output=$func_stripname_result ;;\n\tesac\n\t# test for cygwin because mv fails w/o .exe extensions\n\tcase $host in\n\t  *cygwin*)\n\t    exeext=.exe\n\t    func_stripname '' '.exe' \"$outputname\"\n\t    outputname=$func_stripname_result ;;\n\t  *) exeext= ;;\n\tesac\n\tcase $host in\n\t  *cygwin* | *mingw* )\n\t    func_dirname_and_basename \"$output\" \"\" \".\"\n\t    output_name=$func_basename_result\n\t    output_path=$func_dirname_result\n\t    cwrappersource=\"$output_path/$objdir/lt-$output_name.c\"\n\t    cwrapper=\"$output_path/$output_name.exe\"\n\t    $RM $cwrappersource $cwrapper\n\t    trap \"$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE\" 1 2 15\n\n\t    func_emit_cwrapperexe_src > $cwrappersource\n\n\t    # The wrapper executable is built using the $host compiler,\n\t    # because it contains $host paths and files. If cross-\n\t    # compiling, it, like the target executable, must be\n\t    # executed on the $host or under an emulation environment.\n\t    $opt_dry_run || {\n\t      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource\n\t      $STRIP $cwrapper\n\t    }\n\n\t    # Now, create the wrapper script for func_source use:\n\t    func_ltwrapper_scriptname $cwrapper\n\t    $RM $func_ltwrapper_scriptname_result\n\t    trap \"$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE\" 1 2 15\n\t    $opt_dry_run || {\n\t      # note: this script will not be executed, so do not chmod.\n\t      if test \"x$build\" = \"x$host\" ; then\n\t\t$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result\n\t      else\n\t\tfunc_emit_wrapper no > $func_ltwrapper_scriptname_result\n\t      fi\n\t    }\n\t  ;;\n\t  * )\n\t    $RM $output\n\t    trap \"$RM $output; exit $EXIT_FAILURE\" 1 2 15\n\n\t    func_emit_wrapper no > $output\n\t    chmod +x $output\n\t  ;;\n\tesac\n      }\n      exit $EXIT_SUCCESS\n      ;;\n    esac\n\n    # See if we need to build an old-fashioned archive.\n    for oldlib in $oldlibs; do\n\n      if test \"$build_libtool_libs\" = convenience; then\n\toldobjs=\"$libobjs_save $symfileobj\"\n\taddlibs=\"$convenience\"\n\tbuild_libtool_libs=no\n      else\n\tif test \"$build_libtool_libs\" = module; then\n\t  oldobjs=\"$libobjs_save\"\n\t  build_libtool_libs=no\n\telse\n\t  oldobjs=\"$old_deplibs $non_pic_objects\"\n\t  if test \"$preload\" = yes && test -f \"$symfileobj\"; then\n\t    oldobjs=\"$oldobjs $symfileobj\"\n\t  fi\n\tfi\n\taddlibs=\"$old_convenience\"\n      fi\n\n      if test -n \"$addlibs\"; then\n\tgentop=\"$output_objdir/${outputname}x\"\n\tgenerated=\"$generated $gentop\"\n\n\tfunc_extract_archives $gentop $addlibs\n\toldobjs=\"$oldobjs $func_extract_archives_result\"\n      fi\n\n      # Do each command in the archive commands.\n      if test -n \"$old_archive_from_new_cmds\" && test \"$build_libtool_libs\" = yes; then\n\tcmds=$old_archive_from_new_cmds\n      else\n\n\t# Add any objects from preloaded convenience libraries\n\tif test -n \"$dlprefiles\"; then\n\t  gentop=\"$output_objdir/${outputname}x\"\n\t  generated=\"$generated $gentop\"\n\n\t  func_extract_archives $gentop $dlprefiles\n\t  oldobjs=\"$oldobjs $func_extract_archives_result\"\n\tfi\n\n\t# POSIX demands no paths to be encoded in archives.  We have\n\t# to avoid creating archives with duplicate basenames if we\n\t# might have to extract them afterwards, e.g., when creating a\n\t# static archive out of a convenience library, or when linking\n\t# the entirety of a libtool archive into another (currently\n\t# not supported by libtool).\n\tif (for obj in $oldobjs\n\t    do\n\t      func_basename \"$obj\"\n\t      $ECHO \"$func_basename_result\"\n\t    done | sort | sort -uc >/dev/null 2>&1); then\n\t  :\n\telse\n\t  $ECHO \"copying selected object files to avoid basename conflicts...\"\n\t  gentop=\"$output_objdir/${outputname}x\"\n\t  generated=\"$generated $gentop\"\n\t  func_mkdir_p \"$gentop\"\n\t  save_oldobjs=$oldobjs\n\t  oldobjs=\n\t  counter=1\n\t  for obj in $save_oldobjs\n\t  do\n\t    func_basename \"$obj\"\n\t    objbase=\"$func_basename_result\"\n\t    case \" $oldobjs \" in\n\t    \" \") oldobjs=$obj ;;\n\t    *[\\ /]\"$objbase \"*)\n\t      while :; do\n\t\t# Make sure we don't pick an alternate name that also\n\t\t# overlaps.\n\t\tnewobj=lt$counter-$objbase\n\t\tfunc_arith $counter + 1\n\t\tcounter=$func_arith_result\n\t\tcase \" $oldobjs \" in\n\t\t*[\\ /]\"$newobj \"*) ;;\n\t\t*) if test ! -f \"$gentop/$newobj\"; then break; fi ;;\n\t\tesac\n\t      done\n\t      func_show_eval \"ln $obj $gentop/$newobj || cp $obj $gentop/$newobj\"\n\t      oldobjs=\"$oldobjs $gentop/$newobj\"\n\t      ;;\n\t    *) oldobjs=\"$oldobjs $obj\" ;;\n\t    esac\n\t  done\n\tfi\n\teval cmds=\\\"$old_archive_cmds\\\"\n\n\tfunc_len \" $cmds\"\n\tlen=$func_len_result\n\tif test \"$len\" -lt \"$max_cmd_len\" || test \"$max_cmd_len\" -le -1; then\n\t  cmds=$old_archive_cmds\n\telse\n\t  # the command line is too long to link in one step, link in parts\n\t  func_verbose \"using piecewise archive linking...\"\n\t  save_RANLIB=$RANLIB\n\t  RANLIB=:\n\t  objlist=\n\t  concat_cmds=\n\t  save_oldobjs=$oldobjs\n\t  oldobjs=\n\t  # Is there a better way of finding the last object in the list?\n\t  for obj in $save_oldobjs\n\t  do\n\t    last_oldobj=$obj\n\t  done\n\t  eval test_cmds=\\\"$old_archive_cmds\\\"\n\t  func_len \" $test_cmds\"\n\t  len0=$func_len_result\n\t  len=$len0\n\t  for obj in $save_oldobjs\n\t  do\n\t    func_len \" $obj\"\n\t    func_arith $len + $func_len_result\n\t    len=$func_arith_result\n\t    func_append objlist \" $obj\"\n\t    if test \"$len\" -lt \"$max_cmd_len\"; then\n\t      :\n\t    else\n\t      # the above command should be used before it gets too long\n\t      oldobjs=$objlist\n\t      if test \"$obj\" = \"$last_oldobj\" ; then\n\t\tRANLIB=$save_RANLIB\n\t      fi\n\t      test -z \"$concat_cmds\" || concat_cmds=$concat_cmds~\n\t      eval concat_cmds=\\\"\\${concat_cmds}$old_archive_cmds\\\"\n\t      objlist=\n\t      len=$len0\n\t    fi\n\t  done\n\t  RANLIB=$save_RANLIB\n\t  oldobjs=$objlist\n\t  if test \"X$oldobjs\" = \"X\" ; then\n\t    eval cmds=\\\"\\$concat_cmds\\\"\n\t  else\n\t    eval cmds=\\\"\\$concat_cmds~\\$old_archive_cmds\\\"\n\t  fi\n\tfi\n      fi\n      func_execute_cmds \"$cmds\" 'exit $?'\n    done\n\n    test -n \"$generated\" && \\\n      func_show_eval \"${RM}r$generated\"\n\n    # Now create the libtool archive.\n    case $output in\n    *.la)\n      old_library=\n      test \"$build_old_libs\" = yes && old_library=\"$libname.$libext\"\n      func_verbose \"creating $output\"\n\n      # Preserve any variables that may affect compiler behavior\n      for var in $variables_saved_for_relink; do\n\tif eval test -z \\\"\\${$var+set}\\\"; then\n\t  relink_command=\"{ test -z \\\"\\${$var+set}\\\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command\"\n\telif eval var_value=\\$$var; test -z \"$var_value\"; then\n\t  relink_command=\"$var=; export $var; $relink_command\"\n\telse\n\t  func_quote_for_eval \"$var_value\"\n\t  relink_command=\"$var=$func_quote_for_eval_result; export $var; $relink_command\"\n\tfi\n      done\n      # Quote the link command for shipping.\n      relink_command=\"(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)\"\n      relink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"$sed_quote_subst\"`\n      if test \"$hardcode_automatic\" = yes ; then\n\trelink_command=\n      fi\n\n      # Only create the output if not a dry run.\n      $opt_dry_run || {\n\tfor installed in no yes; do\n\t  if test \"$installed\" = yes; then\n\t    if test -z \"$install_libdir\"; then\n\t      break\n\t    fi\n\t    output=\"$output_objdir/$outputname\"i\n\t    # Replace all uninstalled libtool libraries with the installed ones\n\t    newdependency_libs=\n\t    for deplib in $dependency_libs; do\n\t      case $deplib in\n\t      *.la)\n\t\tfunc_basename \"$deplib\"\n\t\tname=\"$func_basename_result\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $deplib`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$deplib' is not a valid libtool archive\"\n\t\tnewdependency_libs=\"$newdependency_libs $libdir/$name\"\n\t\t;;\n\t      *) newdependency_libs=\"$newdependency_libs $deplib\" ;;\n\t      esac\n\t    done\n\t    dependency_libs=\"$newdependency_libs\"\n\t    newdlfiles=\n\n\t    for lib in $dlfiles; do\n\t      case $lib in\n\t      *.la)\n\t        func_basename \"$lib\"\n\t\tname=\"$func_basename_result\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $lib`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$lib' is not a valid libtool archive\"\n\t\tnewdlfiles=\"$newdlfiles $libdir/$name\"\n\t\t;;\n\t      *) newdlfiles=\"$newdlfiles $lib\" ;;\n\t      esac\n\t    done\n\t    dlfiles=\"$newdlfiles\"\n\t    newdlprefiles=\n\t    for lib in $dlprefiles; do\n\t      case $lib in\n\t      *.la)\n\t\t# Only pass preopened files to the pseudo-archive (for\n\t\t# eventual linking with the app. that links it) if we\n\t\t# didn't already link the preopened objects directly into\n\t\t# the library:\n\t\tfunc_basename \"$lib\"\n\t\tname=\"$func_basename_result\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $lib`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$lib' is not a valid libtool archive\"\n\t\tnewdlprefiles=\"$newdlprefiles $libdir/$name\"\n\t\t;;\n\t      esac\n\t    done\n\t    dlprefiles=\"$newdlprefiles\"\n\t  else\n\t    newdlfiles=\n\t    for lib in $dlfiles; do\n\t      case $lib in\n\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) abs=\"$lib\" ;;\n\t\t*) abs=`pwd`\"/$lib\" ;;\n\t      esac\n\t      newdlfiles=\"$newdlfiles $abs\"\n\t    done\n\t    dlfiles=\"$newdlfiles\"\n\t    newdlprefiles=\n\t    for lib in $dlprefiles; do\n\t      case $lib in\n\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) abs=\"$lib\" ;;\n\t\t*) abs=`pwd`\"/$lib\" ;;\n\t      esac\n\t      newdlprefiles=\"$newdlprefiles $abs\"\n\t    done\n\t    dlprefiles=\"$newdlprefiles\"\n\t  fi\n\t  $RM $output\n\t  # place dlname in correct position for cygwin\n\t  tdlname=$dlname\n\t  case $host,$output,$installed,$module,$dlname in\n\t    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;\n\t  esac\n\t  $ECHO > $output \"\\\n# $outputname - a libtool library file\n# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n#\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# The name that we can dlopen(3).\ndlname='$tdlname'\n\n# Names of this library.\nlibrary_names='$library_names'\n\n# The name of the static archive.\nold_library='$old_library'\n\n# Linker flags that can not go in dependency_libs.\ninherited_linker_flags='$new_inherited_linker_flags'\n\n# Libraries that this one depends upon.\ndependency_libs='$dependency_libs'\n\n# Names of additional weak libraries provided by this library\nweak_library_names='$weak_libs'\n\n# Version information for $libname.\ncurrent=$current\nage=$age\nrevision=$revision\n\n# Is this an already installed library?\ninstalled=$installed\n\n# Should we warn about portability when linking against -modules?\nshouldnotlink=$module\n\n# Files to dlopen/dlpreopen\ndlopen='$dlfiles'\ndlpreopen='$dlprefiles'\n\n# Directory that this library needs to be installed in:\nlibdir='$install_libdir'\"\n\t  if test \"$installed\" = no && test \"$need_relink\" = yes; then\n\t    $ECHO >> $output \"\\\nrelink_command=\\\"$relink_command\\\"\"\n\t  fi\n\tdone\n      }\n\n      # Do a symbolic link so that the libtool archive can be found in\n      # LD_LIBRARY_PATH before the program is installed.\n      func_show_eval '( cd \"$output_objdir\" && $RM \"$outputname\" && $LN_S \"../$outputname\" \"$outputname\" )' 'exit $?'\n      ;;\n    esac\n    exit $EXIT_SUCCESS\n}\n\n{ test \"$mode\" = link || test \"$mode\" = relink; } &&\n    func_mode_link ${1+\"$@\"}\n\n\n# func_mode_uninstall arg...\nfunc_mode_uninstall ()\n{\n    $opt_debug\n    RM=\"$nonopt\"\n    files=\n    rmforce=\n    exit_status=0\n\n    # This variable tells wrapper scripts just to set variables rather\n    # than running their programs.\n    libtool_install_magic=\"$magic\"\n\n    for arg\n    do\n      case $arg in\n      -f) RM=\"$RM $arg\"; rmforce=yes ;;\n      -*) RM=\"$RM $arg\" ;;\n      *) files=\"$files $arg\" ;;\n      esac\n    done\n\n    test -z \"$RM\" && \\\n      func_fatal_help \"you must specify an RM program\"\n\n    rmdirs=\n\n    origobjdir=\"$objdir\"\n    for file in $files; do\n      func_dirname \"$file\" \"\" \".\"\n      dir=\"$func_dirname_result\"\n      if test \"X$dir\" = X.; then\n\tobjdir=\"$origobjdir\"\n      else\n\tobjdir=\"$dir/$origobjdir\"\n      fi\n      func_basename \"$file\"\n      name=\"$func_basename_result\"\n      test \"$mode\" = uninstall && objdir=\"$dir\"\n\n      # Remember objdir for removal later, being careful to avoid duplicates\n      if test \"$mode\" = clean; then\n\tcase \" $rmdirs \" in\n\t  *\" $objdir \"*) ;;\n\t  *) rmdirs=\"$rmdirs $objdir\" ;;\n\tesac\n      fi\n\n      # Don't error if the file doesn't exist and rm -f was used.\n      if { test -L \"$file\"; } >/dev/null 2>&1 ||\n\t { test -h \"$file\"; } >/dev/null 2>&1 ||\n\t test -f \"$file\"; then\n\t:\n      elif test -d \"$file\"; then\n\texit_status=1\n\tcontinue\n      elif test \"$rmforce\" = yes; then\n\tcontinue\n      fi\n\n      rmfiles=\"$file\"\n\n      case $name in\n      *.la)\n\t# Possibly a libtool archive, so verify it.\n\tif func_lalib_p \"$file\"; then\n\t  func_source $dir/$name\n\n\t  # Delete the libtool libraries and symlinks.\n\t  for n in $library_names; do\n\t    rmfiles=\"$rmfiles $objdir/$n\"\n\t  done\n\t  test -n \"$old_library\" && rmfiles=\"$rmfiles $objdir/$old_library\"\n\n\t  case \"$mode\" in\n\t  clean)\n\t    case \"  $library_names \" in\n\t    # \"  \" in the beginning catches empty $dlname\n\t    *\" $dlname \"*) ;;\n\t    *) rmfiles=\"$rmfiles $objdir/$dlname\" ;;\n\t    esac\n\t    test -n \"$libdir\" && rmfiles=\"$rmfiles $objdir/$name $objdir/${name}i\"\n\t    ;;\n\t  uninstall)\n\t    if test -n \"$library_names\"; then\n\t      # Do each command in the postuninstall commands.\n\t      func_execute_cmds \"$postuninstall_cmds\" 'test \"$rmforce\" = yes || exit_status=1'\n\t    fi\n\n\t    if test -n \"$old_library\"; then\n\t      # Do each command in the old_postuninstall commands.\n\t      func_execute_cmds \"$old_postuninstall_cmds\" 'test \"$rmforce\" = yes || exit_status=1'\n\t    fi\n\t    # FIXME: should reinstall the best remaining shared library.\n\t    ;;\n\t  esac\n\tfi\n\t;;\n\n      *.lo)\n\t# Possibly a libtool object, so verify it.\n\tif func_lalib_p \"$file\"; then\n\n\t  # Read the .lo file\n\t  func_source $dir/$name\n\n\t  # Add PIC object to the list of files to remove.\n\t  if test -n \"$pic_object\" &&\n\t     test \"$pic_object\" != none; then\n\t    rmfiles=\"$rmfiles $dir/$pic_object\"\n\t  fi\n\n\t  # Add non-PIC object to the list of files to remove.\n\t  if test -n \"$non_pic_object\" &&\n\t     test \"$non_pic_object\" != none; then\n\t    rmfiles=\"$rmfiles $dir/$non_pic_object\"\n\t  fi\n\tfi\n\t;;\n\n      *)\n\tif test \"$mode\" = clean ; then\n\t  noexename=$name\n\t  case $file in\n\t  *.exe)\n\t    func_stripname '' '.exe' \"$file\"\n\t    file=$func_stripname_result\n\t    func_stripname '' '.exe' \"$name\"\n\t    noexename=$func_stripname_result\n\t    # $file with .exe has already been added to rmfiles,\n\t    # add $file without .exe\n\t    rmfiles=\"$rmfiles $file\"\n\t    ;;\n\t  esac\n\t  # Do a test to see if this is a libtool program.\n\t  if func_ltwrapper_p \"$file\"; then\n\t    if func_ltwrapper_executable_p \"$file\"; then\n\t      func_ltwrapper_scriptname \"$file\"\n\t      relink_command=\n\t      func_source $func_ltwrapper_scriptname_result\n\t      rmfiles=\"$rmfiles $func_ltwrapper_scriptname_result\"\n\t    else\n\t      relink_command=\n\t      func_source $dir/$noexename\n\t    fi\n\n\t    # note $name still contains .exe if it was in $file originally\n\t    # as does the version of $file that was added into $rmfiles\n\t    rmfiles=\"$rmfiles $objdir/$name $objdir/${name}S.${objext}\"\n\t    if test \"$fast_install\" = yes && test -n \"$relink_command\"; then\n\t      rmfiles=\"$rmfiles $objdir/lt-$name\"\n\t    fi\n\t    if test \"X$noexename\" != \"X$name\" ; then\n\t      rmfiles=\"$rmfiles $objdir/lt-${noexename}.c\"\n\t    fi\n\t  fi\n\tfi\n\t;;\n      esac\n      func_show_eval \"$RM $rmfiles\" 'exit_status=1'\n    done\n    objdir=\"$origobjdir\"\n\n    # Try to remove the ${objdir}s in the directories where we deleted files\n    for dir in $rmdirs; do\n      if test -d \"$dir\"; then\n\tfunc_show_eval \"rmdir $dir >/dev/null 2>&1\"\n      fi\n    done\n\n    exit $exit_status\n}\n\n{ test \"$mode\" = uninstall || test \"$mode\" = clean; } &&\n    func_mode_uninstall ${1+\"$@\"}\n\ntest -z \"$mode\" && {\n  help=\"$generic_help\"\n  func_fatal_help \"you must specify a MODE\"\n}\n\ntest -z \"$exec_cmd\" && \\\n  func_fatal_help \"invalid operation mode \\`$mode'\"\n\nif test -n \"$exec_cmd\"; then\n  eval exec \"$exec_cmd\"\n  exit $EXIT_FAILURE\nfi\n\nexit $exit_status\n\n\n# The TAGs below are defined such that we never get into a situation\n# in which we disable both kinds of libraries.  Given conflicting\n# choices, we go for a static library, that is the most portable,\n# since we can't tell whether shared libraries were disabled because\n# the user asked for that or because the platform doesn't support\n# them.  This is particularly important on AIX, because we don't\n# support having both static and shared libraries enabled at the same\n# time on that platform, so we default to a shared-only configuration.\n# If a disable-shared tag is given, we'll fallback to a static-only\n# configuration.  But we'll never go from static-only to shared-only.\n\n# ### BEGIN LIBTOOL TAG CONFIG: disable-shared\nbuild_libtool_libs=no\nbuild_old_libs=yes\n# ### END LIBTOOL TAG CONFIG: disable-shared\n\n# ### BEGIN LIBTOOL TAG CONFIG: disable-static\nbuild_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`\n# ### END LIBTOOL TAG CONFIG: disable-static\n\n# Local Variables:\n# mode:shell-script\n# sh-indentation:2\n# End:\n# vi:sw=2\n\n\n# ### BEGIN LIBTOOL TAG CONFIG: CXX\n\n# The linker used to build libraries.\nLD=\"/usr/bin/ld -m elf_x86_64\"\n\n# Commands used to build an old-style archive.\nold_archive_cmds=\"\\$AR \\$AR_FLAGS \\$oldlib\\$oldobjs~\\$RANLIB \\$oldlib\"\n\n# A language specific compiler.\nCC=\"g++\"\n\n# Is the compiler the GNU compiler?\nwith_gcc=yes\n\n# Compiler flag to turn off builtin functions.\nno_builtin_flag=\" -fno-builtin\"\n\n# How to pass a linker flag through the compiler.\nwl=\"-Wl,\"\n\n# Additional compiler flags for building library objects.\npic_flag=\" -fPIC -DPIC\"\n\n# Compiler flag to prevent dynamic linking.\nlink_static_flag=\"-static\"\n\n# Does compiler simultaneously support -c and -o options?\ncompiler_c_o=\"yes\"\n\n# Whether or not to add -lc for building shared libraries.\nbuild_libtool_need_lc=no\n\n# Whether or not to disallow shared libs when runtime libs are static.\nallow_libtool_libs_with_static_runtimes=no\n\n# Compiler flag to allow reflexive dlopens.\nexport_dynamic_flag_spec=\"\\${wl}--export-dynamic\"\n\n# Compiler flag to generate shared objects directly from archives.\nwhole_archive_flag_spec=\"\\${wl}--whole-archive\\$convenience \\${wl}--no-whole-archive\"\n\n# Whether the compiler copes with passing no objects directly.\ncompiler_needs_object=\"no\"\n\n# Create an old-style archive from a shared archive.\nold_archive_from_new_cmds=\"\"\n\n# Create a temporary old-style archive to link instead of a shared archive.\nold_archive_from_expsyms_cmds=\"\"\n\n# Commands used to build a shared archive.\narchive_cmds=\"\\$CC -shared -nostdlib \\$predep_objects \\$libobjs \\$deplibs \\$postdep_objects \\$compiler_flags \\${wl}-soname \\$wl\\$soname -o \\$lib\"\narchive_expsym_cmds=\"\\$CC -shared -nostdlib \\$predep_objects \\$libobjs \\$deplibs \\$postdep_objects \\$compiler_flags \\${wl}-soname \\$wl\\$soname \\${wl}-retain-symbols-file \\$wl\\$export_symbols -o \\$lib\"\n\n# Commands used to build a loadable module if different from building\n# a shared archive.\nmodule_cmds=\"\"\nmodule_expsym_cmds=\"\"\n\n# Whether we are building with GNU ld or not.\nwith_gnu_ld=\"yes\"\n\n# Flag that allows shared libraries with undefined symbols to be built.\nallow_undefined_flag=\"\"\n\n# Flag that enforces no undefined symbols.\nno_undefined_flag=\"\"\n\n# Flag to hardcode $libdir into a binary during linking.\n# This must work even if $libdir does not exist\nhardcode_libdir_flag_spec=\"\\${wl}-rpath \\${wl}\\$libdir\"\n\n# If ld is used when linking, flag to hardcode $libdir into a binary\n# during linking.  This must work even if $libdir does not exist.\nhardcode_libdir_flag_spec_ld=\"\"\n\n# Whether we need a single \"-rpath\" flag with a separated argument.\nhardcode_libdir_separator=\"\"\n\n# Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n# DIR into the resulting binary.\nhardcode_direct=no\n\n# Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n# DIR into the resulting binary and the resulting library dependency is\n# \"absolute\",i.e impossible to change by setting ${shlibpath_var} if the\n# library is relocated.\nhardcode_direct_absolute=no\n\n# Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n# into the resulting binary.\nhardcode_minus_L=no\n\n# Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n# into the resulting binary.\nhardcode_shlibpath_var=unsupported\n\n# Set to \"yes\" if building a shared library automatically hardcodes DIR\n# into the library and all subsequent libraries and executables linked\n# against it.\nhardcode_automatic=no\n\n# Set to yes if linker adds runtime paths of dependent libraries\n# to runtime path list.\ninherit_rpath=no\n\n# Whether libtool must link a program against all its dependency libraries.\nlink_all_deplibs=no\n\n# Fix the shell variable $srcfile for the compiler.\nfix_srcfile_path=\"\"\n\n# Set to \"yes\" if exported symbols are required.\nalways_export_symbols=no\n\n# The commands to list exported symbols.\nexport_symbols_cmds=\"\\$NM \\$libobjs \\$convenience | \\$global_symbol_pipe | \\$SED 's/.* //' | sort | uniq > \\$export_symbols\"\n\n# Symbols that should not be listed in the preloaded symbols.\nexclude_expsyms=\"_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*\"\n\n# Symbols that must always be exported.\ninclude_expsyms=\"\"\n\n# Commands necessary for linking programs (against libraries) with templates.\nprelink_cmds=\"\"\n\n# Specify filename containing input files.\nfile_list_spec=\"\"\n\n# How to hardcode a shared library path into an executable.\nhardcode_action=immediate\n\n# The directories searched by this compiler when creating a shared library.\ncompiler_lib_search_dirs=\"/usr/lib/gcc/x86_64-linux-gnu/4.4.3 /usr/lib/gcc/x86_64-linux-gnu/4.4.3 /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib /lib/../lib /usr/lib/../lib /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../.. /usr/lib/x86_64-linux-gnu\"\n\n# Dependencies to place before and after the objects being linked to\n# create a shared library.\npredep_objects=\"/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtbeginS.o\"\npostdep_objects=\"/usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crtn.o\"\npredeps=\"\"\npostdeps=\"-lstdc++ -lm -lgcc_s -lc -lgcc_s\"\n\n# The library search path used internally by the compiler when linking\n# a shared library.\ncompiler_lib_search_path=\"-L/usr/lib/gcc/x86_64-linux-gnu/4.4.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../.. -L/usr/lib/x86_64-linux-gnu\"\n\n# ### END LIBTOOL TAG CONFIG: CXX\n"
  },
  {
    "path": "distro/google-perftools-1.7/ltmain.sh",
    "content": "# Generated from ltmain.m4sh.\n\n# ltmain.sh (GNU libtool) 2.2.6b\n# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996\n\n# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.\n# This is free software; see the source for copying conditions.  There is NO\n# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n# GNU Libtool is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n# General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html,\n# or obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n# Usage: $progname [OPTION]... [MODE-ARG]...\n#\n# Provide generalized library-building support services.\n#\n#     --config             show all configuration variables\n#     --debug              enable verbose shell tracing\n# -n, --dry-run            display commands without modifying any files\n#     --features           display basic configuration information and exit\n#     --mode=MODE          use operation mode MODE\n#     --preserve-dup-deps  don't remove duplicate dependency libraries\n#     --quiet, --silent    don't print informational messages\n#     --tag=TAG            use configuration variables from tag TAG\n# -v, --verbose            print informational messages (default)\n#     --version            print version information\n# -h, --help               print short or long help message\n#\n# MODE must be one of the following:\n#\n#       clean              remove files from the build directory\n#       compile            compile a source file into a libtool object\n#       execute            automatically set library path, then run a program\n#       finish             complete the installation of libtool libraries\n#       install            install libraries or executables\n#       link               create a library or an executable\n#       uninstall          remove libraries from an installed directory\n#\n# MODE-ARGS vary depending on the MODE.\n# Try `$progname --help --mode=MODE' for a more detailed description of MODE.\n#\n# When reporting a bug, please describe a test case to reproduce it and\n# include the following information:\n#\n#       host-triplet:\t$host\n#       shell:\t\t$SHELL\n#       compiler:\t\t$LTCC\n#       compiler flags:\t\t$LTCFLAGS\n#       linker:\t\t$LD (gnu? $with_gnu_ld)\n#       $progname:\t\t(GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1\n#       automake:\t\t$automake_version\n#       autoconf:\t\t$autoconf_version\n#\n# Report bugs to <bug-libtool@gnu.org>.\n\nPROGRAM=ltmain.sh\nPACKAGE=libtool\nVERSION=\"2.2.6b Debian-2.2.6b-2ubuntu1\"\nTIMESTAMP=\"\"\npackage_revision=1.3017\n\n# Be Bourne compatible\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then\n  emulate sh\n  NULLCMD=:\n  # Zsh 3.x and 4.x performs word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac\nfi\nBIN_SH=xpg4; export BIN_SH # for Tru64\nDUALCASE=1; export DUALCASE # for MKS sh\n\n# NLS nuisances: We save the old values to restore during execute mode.\n# Only set LANG and LC_ALL to C if already set.\n# These must not be set unconditionally because not all systems understand\n# e.g. LANG=C (notably SCO).\nlt_user_locale=\nlt_safe_locale=\nfor lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES\ndo\n  eval \"if test \\\"\\${$lt_var+set}\\\" = set; then\n          save_$lt_var=\\$$lt_var\n          $lt_var=C\n\t  export $lt_var\n\t  lt_user_locale=\\\"$lt_var=\\\\\\$save_\\$lt_var; \\$lt_user_locale\\\"\n\t  lt_safe_locale=\\\"$lt_var=C; \\$lt_safe_locale\\\"\n\tfi\"\ndone\n\n$lt_unset CDPATH\n\n\n\n\n\n: ${CP=\"cp -f\"}\n: ${ECHO=\"echo\"}\n: ${EGREP=\"/bin/grep -E\"}\n: ${FGREP=\"/bin/grep -F\"}\n: ${GREP=\"/bin/grep\"}\n: ${LN_S=\"ln -s\"}\n: ${MAKE=\"make\"}\n: ${MKDIR=\"mkdir\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\n: ${SED=\"/bin/sed\"}\n: ${SHELL=\"${CONFIG_SHELL-/bin/sh}\"}\n: ${Xsed=\"$SED -e 1s/^X//\"}\n\n# Global variables:\nEXIT_SUCCESS=0\nEXIT_FAILURE=1\nEXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.\nEXIT_SKIP=77\t  # $? = 77 is used to indicate a skipped test to automake.\n\nexit_status=$EXIT_SUCCESS\n\n# Make sure IFS has a sensible default\nlt_nl='\n'\nIFS=\" \t$lt_nl\"\n\ndirname=\"s,/[^/]*$,,\"\nbasename=\"s,^.*/,,\"\n\n# func_dirname_and_basename file append nondir_replacement\n# perform func_basename and func_dirname in a single function\n# call:\n#   dirname:  Compute the dirname of FILE.  If nonempty,\n#             add APPEND to the result, otherwise set result\n#             to NONDIR_REPLACEMENT.\n#             value returned in \"$func_dirname_result\"\n#   basename: Compute filename of FILE.\n#             value retuned in \"$func_basename_result\"\n# Implementation must be kept synchronized with func_dirname\n# and func_basename. For efficiency, we do not delegate to\n# those functions but instead duplicate the functionality here.\nfunc_dirname_and_basename ()\n{\n  # Extract subdirectory from the argument.\n  func_dirname_result=`$ECHO \"X${1}\" | $Xsed -e \"$dirname\"`\n  if test \"X$func_dirname_result\" = \"X${1}\"; then\n    func_dirname_result=\"${3}\"\n  else\n    func_dirname_result=\"$func_dirname_result${2}\"\n  fi\n  func_basename_result=`$ECHO \"X${1}\" | $Xsed -e \"$basename\"`\n}\n\n# Generated shell functions inserted here.\n\n# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh\n# is ksh but when the shell is invoked as \"sh\" and the current value of\n# the _XPG environment variable is not equal to 1 (one), the special\n# positional parameter $0, within a function call, is the name of the\n# function.\nprogpath=\"$0\"\n\n# The name of this program:\n# In the unlikely event $progname began with a '-', it would play havoc with\n# func_echo (imagine progname=-n), so we prepend ./ in that case:\nfunc_dirname_and_basename \"$progpath\"\nprogname=$func_basename_result\ncase $progname in\n  -*) progname=./$progname ;;\nesac\n\n# Make sure we have an absolute path for reexecution:\ncase $progpath in\n  [\\\\/]*|[A-Za-z]:\\\\*) ;;\n  *[\\\\/]*)\n     progdir=$func_dirname_result\n     progdir=`cd \"$progdir\" && pwd`\n     progpath=\"$progdir/$progname\"\n     ;;\n  *)\n     save_IFS=\"$IFS\"\n     IFS=:\n     for progdir in $PATH; do\n       IFS=\"$save_IFS\"\n       test -x \"$progdir/$progname\" && break\n     done\n     IFS=\"$save_IFS\"\n     test -n \"$progdir\" || progdir=`pwd`\n     progpath=\"$progdir/$progname\"\n     ;;\nesac\n\n# Sed substitution that helps us do robust quoting.  It backslashifies\n# metacharacters that are still active within double-quoted strings.\nXsed=\"${SED}\"' -e 1s/^X//'\nsed_quote_subst='s/\\([`\"$\\\\]\\)/\\\\\\1/g'\n\n# Same as above, but do not quote variable references.\ndouble_quote_subst='s/\\([\"`\\\\]\\)/\\\\\\1/g'\n\n# Re-`\\' parameter expansions in output of double_quote_subst that were\n# `\\'-ed in input to the same.  If an odd number of `\\' preceded a '$'\n# in input to double_quote_subst, that '$' was protected from expansion.\n# Since each input `\\' is now two `\\'s, look for any number of runs of\n# four `\\'s followed by two `\\'s and then a '$'.  `\\' that '$'.\nbs='\\\\'\nbs2='\\\\\\\\'\nbs4='\\\\\\\\\\\\\\\\'\ndollar='\\$'\nsed_double_backslash=\"\\\n  s/$bs4/&\\\\\n/g\n  s/^$bs2$dollar/$bs&/\n  s/\\\\([^$bs]\\\\)$bs2$dollar/\\\\1$bs2$bs$dollar/g\n  s/\\n//g\"\n\n# Standard options:\nopt_dry_run=false\nopt_help=false\nopt_quiet=false\nopt_verbose=false\nopt_warning=:\n\n# func_echo arg...\n# Echo program name prefixed message, along with the current mode\n# name if it has been set yet.\nfunc_echo ()\n{\n    $ECHO \"$progname${mode+: }$mode: $*\"\n}\n\n# func_verbose arg...\n# Echo program name prefixed message in verbose mode only.\nfunc_verbose ()\n{\n    $opt_verbose && func_echo ${1+\"$@\"}\n\n    # A bug in bash halts the script if the last line of a function\n    # fails when set -e is in force, so we need another command to\n    # work around that:\n    :\n}\n\n# func_error arg...\n# Echo program name prefixed message to standard error.\nfunc_error ()\n{\n    $ECHO \"$progname${mode+: }$mode: \"${1+\"$@\"} 1>&2\n}\n\n# func_warning arg...\n# Echo program name prefixed warning message to standard error.\nfunc_warning ()\n{\n    $opt_warning && $ECHO \"$progname${mode+: }$mode: warning: \"${1+\"$@\"} 1>&2\n\n    # bash bug again:\n    :\n}\n\n# func_fatal_error arg...\n# Echo program name prefixed message to standard error, and exit.\nfunc_fatal_error ()\n{\n    func_error ${1+\"$@\"}\n    exit $EXIT_FAILURE\n}\n\n# func_fatal_help arg...\n# Echo program name prefixed message to standard error, followed by\n# a help hint, and exit.\nfunc_fatal_help ()\n{\n    func_error ${1+\"$@\"}\n    func_fatal_error \"$help\"\n}\nhelp=\"Try \\`$progname --help' for more information.\"  ## default\n\n\n# func_grep expression filename\n# Check whether EXPRESSION matches any line of FILENAME, without output.\nfunc_grep ()\n{\n    $GREP \"$1\" \"$2\" >/dev/null 2>&1\n}\n\n\n# func_mkdir_p directory-path\n# Make sure the entire path to DIRECTORY-PATH is available.\nfunc_mkdir_p ()\n{\n    my_directory_path=\"$1\"\n    my_dir_list=\n\n    if test -n \"$my_directory_path\" && test \"$opt_dry_run\" != \":\"; then\n\n      # Protect directory names starting with `-'\n      case $my_directory_path in\n        -*) my_directory_path=\"./$my_directory_path\" ;;\n      esac\n\n      # While some portion of DIR does not yet exist...\n      while test ! -d \"$my_directory_path\"; do\n        # ...make a list in topmost first order.  Use a colon delimited\n\t# list incase some portion of path contains whitespace.\n        my_dir_list=\"$my_directory_path:$my_dir_list\"\n\n        # If the last portion added has no slash in it, the list is done\n        case $my_directory_path in */*) ;; *) break ;; esac\n\n        # ...otherwise throw away the child directory and loop\n        my_directory_path=`$ECHO \"X$my_directory_path\" | $Xsed -e \"$dirname\"`\n      done\n      my_dir_list=`$ECHO \"X$my_dir_list\" | $Xsed -e 's,:*$,,'`\n\n      save_mkdir_p_IFS=\"$IFS\"; IFS=':'\n      for my_dir in $my_dir_list; do\n\tIFS=\"$save_mkdir_p_IFS\"\n        # mkdir can fail with a `File exist' error if two processes\n        # try to create one of the directories concurrently.  Don't\n        # stop in that case!\n        $MKDIR \"$my_dir\" 2>/dev/null || :\n      done\n      IFS=\"$save_mkdir_p_IFS\"\n\n      # Bail out if we (or some other process) failed to create a directory.\n      test -d \"$my_directory_path\" || \\\n        func_fatal_error \"Failed to create \\`$1'\"\n    fi\n}\n\n\n# func_mktempdir [string]\n# Make a temporary directory that won't clash with other running\n# libtool processes, and avoids race conditions if possible.  If\n# given, STRING is the basename for that directory.\nfunc_mktempdir ()\n{\n    my_template=\"${TMPDIR-/tmp}/${1-$progname}\"\n\n    if test \"$opt_dry_run\" = \":\"; then\n      # Return a directory name, but don't create it in dry-run mode\n      my_tmpdir=\"${my_template}-$$\"\n    else\n\n      # If mktemp works, use that first and foremost\n      my_tmpdir=`mktemp -d \"${my_template}-XXXXXXXX\" 2>/dev/null`\n\n      if test ! -d \"$my_tmpdir\"; then\n        # Failing that, at least try and use $RANDOM to avoid a race\n        my_tmpdir=\"${my_template}-${RANDOM-0}$$\"\n\n        save_mktempdir_umask=`umask`\n        umask 0077\n        $MKDIR \"$my_tmpdir\"\n        umask $save_mktempdir_umask\n      fi\n\n      # If we're not in dry-run mode, bomb out on failure\n      test -d \"$my_tmpdir\" || \\\n        func_fatal_error \"cannot create temporary directory \\`$my_tmpdir'\"\n    fi\n\n    $ECHO \"X$my_tmpdir\" | $Xsed\n}\n\n\n# func_quote_for_eval arg\n# Aesthetically quote ARG to be evaled later.\n# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT\n# is double-quoted, suitable for a subsequent eval, whereas\n# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters\n# which are still active within double quotes backslashified.\nfunc_quote_for_eval ()\n{\n    case $1 in\n      *[\\\\\\`\\\"\\$]*)\n\tfunc_quote_for_eval_unquoted_result=`$ECHO \"X$1\" | $Xsed -e \"$sed_quote_subst\"` ;;\n      *)\n        func_quote_for_eval_unquoted_result=\"$1\" ;;\n    esac\n\n    case $func_quote_for_eval_unquoted_result in\n      # Double-quote args containing shell metacharacters to delay\n      # word splitting, command substitution and and variable\n      # expansion for a subsequent eval.\n      # Many Bourne shells cannot handle close brackets correctly\n      # in scan sets, so we specify it separately.\n      *[\\[\\~\\#\\^\\&\\*\\(\\)\\{\\}\\|\\;\\<\\>\\?\\'\\ \\\t]*|*]*|\"\")\n        func_quote_for_eval_result=\"\\\"$func_quote_for_eval_unquoted_result\\\"\"\n        ;;\n      *)\n        func_quote_for_eval_result=\"$func_quote_for_eval_unquoted_result\"\n    esac\n}\n\n\n# func_quote_for_expand arg\n# Aesthetically quote ARG to be evaled later; same as above,\n# but do not quote variable references.\nfunc_quote_for_expand ()\n{\n    case $1 in\n      *[\\\\\\`\\\"]*)\n\tmy_arg=`$ECHO \"X$1\" | $Xsed \\\n\t    -e \"$double_quote_subst\" -e \"$sed_double_backslash\"` ;;\n      *)\n        my_arg=\"$1\" ;;\n    esac\n\n    case $my_arg in\n      # Double-quote args containing shell metacharacters to delay\n      # word splitting and command substitution for a subsequent eval.\n      # Many Bourne shells cannot handle close brackets correctly\n      # in scan sets, so we specify it separately.\n      *[\\[\\~\\#\\^\\&\\*\\(\\)\\{\\}\\|\\;\\<\\>\\?\\'\\ \\\t]*|*]*|\"\")\n        my_arg=\"\\\"$my_arg\\\"\"\n        ;;\n    esac\n\n    func_quote_for_expand_result=\"$my_arg\"\n}\n\n\n# func_show_eval cmd [fail_exp]\n# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is\n# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP\n# is given, then evaluate it.\nfunc_show_eval ()\n{\n    my_cmd=\"$1\"\n    my_fail_exp=\"${2-:}\"\n\n    ${opt_silent-false} || {\n      func_quote_for_expand \"$my_cmd\"\n      eval \"func_echo $func_quote_for_expand_result\"\n    }\n\n    if ${opt_dry_run-false}; then :; else\n      eval \"$my_cmd\"\n      my_status=$?\n      if test \"$my_status\" -eq 0; then :; else\n\teval \"(exit $my_status); $my_fail_exp\"\n      fi\n    fi\n}\n\n\n# func_show_eval_locale cmd [fail_exp]\n# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is\n# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP\n# is given, then evaluate it.  Use the saved locale for evaluation.\nfunc_show_eval_locale ()\n{\n    my_cmd=\"$1\"\n    my_fail_exp=\"${2-:}\"\n\n    ${opt_silent-false} || {\n      func_quote_for_expand \"$my_cmd\"\n      eval \"func_echo $func_quote_for_expand_result\"\n    }\n\n    if ${opt_dry_run-false}; then :; else\n      eval \"$lt_user_locale\n\t    $my_cmd\"\n      my_status=$?\n      eval \"$lt_safe_locale\"\n      if test \"$my_status\" -eq 0; then :; else\n\teval \"(exit $my_status); $my_fail_exp\"\n      fi\n    fi\n}\n\n\n\n\n\n# func_version\n# Echo version message to standard output and exit.\nfunc_version ()\n{\n    $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {\n        s/^# //\n\ts/^# *$//\n        s/\\((C)\\)[ 0-9,-]*\\( [1-9][0-9]*\\)/\\1\\2/\n        p\n     }' < \"$progpath\"\n     exit $?\n}\n\n# func_usage\n# Echo short help message to standard output and exit.\nfunc_usage ()\n{\n    $SED -n '/^# Usage:/,/# -h/ {\n        s/^# //\n\ts/^# *$//\n\ts/\\$progname/'$progname'/\n\tp\n    }' < \"$progpath\"\n    $ECHO\n    $ECHO \"run \\`$progname --help | more' for full usage\"\n    exit $?\n}\n\n# func_help\n# Echo long help message to standard output and exit.\nfunc_help ()\n{\n    $SED -n '/^# Usage:/,/# Report bugs to/ {\n        s/^# //\n\ts/^# *$//\n\ts*\\$progname*'$progname'*\n\ts*\\$host*'\"$host\"'*\n\ts*\\$SHELL*'\"$SHELL\"'*\n\ts*\\$LTCC*'\"$LTCC\"'*\n\ts*\\$LTCFLAGS*'\"$LTCFLAGS\"'*\n\ts*\\$LD*'\"$LD\"'*\n\ts/\\$with_gnu_ld/'\"$with_gnu_ld\"'/\n\ts/\\$automake_version/'\"`(automake --version) 2>/dev/null |$SED 1q`\"'/\n\ts/\\$autoconf_version/'\"`(autoconf --version) 2>/dev/null |$SED 1q`\"'/\n\tp\n     }' < \"$progpath\"\n    exit $?\n}\n\n# func_missing_arg argname\n# Echo program name prefixed message to standard error and set global\n# exit_cmd.\nfunc_missing_arg ()\n{\n    func_error \"missing argument for $1\"\n    exit_cmd=exit\n}\n\nexit_cmd=:\n\n\n\n\n\n# Check that we have a working $ECHO.\nif test \"X$1\" = X--no-reexec; then\n  # Discard the --no-reexec flag, and continue.\n  shift\nelif test \"X$1\" = X--fallback-echo; then\n  # Avoid inline document here, it may be left over\n  :\nelif test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t'; then\n  # Yippee, $ECHO works!\n  :\nelse\n  # Restart under the correct shell, and then maybe $ECHO will work.\n  exec $SHELL \"$progpath\" --no-reexec ${1+\"$@\"}\nfi\n\nif test \"X$1\" = X--fallback-echo; then\n  # used as fallback echo\n  shift\n  cat <<EOF\n$*\nEOF\n  exit $EXIT_SUCCESS\nfi\n\nmagic=\"%%%MAGIC variable%%%\"\nmagic_exe=\"%%%MAGIC EXE variable%%%\"\n\n# Global variables.\n# $mode is unset\nnonopt=\nexecute_dlfiles=\npreserve_args=\nlo2o=\"s/\\\\.lo\\$/.${objext}/\"\no2lo=\"s/\\\\.${objext}\\$/.lo/\"\nextracted_archives=\nextracted_serial=0\n\nopt_dry_run=false\nopt_duplicate_deps=false\nopt_silent=false\nopt_debug=:\n\n# If this variable is set in any of the actions, the command in it\n# will be execed at the end.  This prevents here-documents from being\n# left over by shells.\nexec_cmd=\n\n# func_fatal_configuration arg...\n# Echo program name prefixed message to standard error, followed by\n# a configuration failure hint, and exit.\nfunc_fatal_configuration ()\n{\n    func_error ${1+\"$@\"}\n    func_error \"See the $PACKAGE documentation for more information.\"\n    func_fatal_error \"Fatal configuration error.\"\n}\n\n\n# func_config\n# Display the configuration for all the tags in this script.\nfunc_config ()\n{\n    re_begincf='^# ### BEGIN LIBTOOL'\n    re_endcf='^# ### END LIBTOOL'\n\n    # Default configuration.\n    $SED \"1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\\$d\" < \"$progpath\"\n\n    # Now print the configurations for the tags.\n    for tagname in $taglist; do\n      $SED -n \"/$re_begincf TAG CONFIG: $tagname\\$/,/$re_endcf TAG CONFIG: $tagname\\$/p\" < \"$progpath\"\n    done\n\n    exit $?\n}\n\n# func_features\n# Display the features supported by this script.\nfunc_features ()\n{\n    $ECHO \"host: $host\"\n    if test \"$build_libtool_libs\" = yes; then\n      $ECHO \"enable shared libraries\"\n    else\n      $ECHO \"disable shared libraries\"\n    fi\n    if test \"$build_old_libs\" = yes; then\n      $ECHO \"enable static libraries\"\n    else\n      $ECHO \"disable static libraries\"\n    fi\n\n    exit $?\n}\n\n# func_enable_tag tagname\n# Verify that TAGNAME is valid, and either flag an error and exit, or\n# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist\n# variable here.\nfunc_enable_tag ()\n{\n  # Global variable:\n  tagname=\"$1\"\n\n  re_begincf=\"^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\\$\"\n  re_endcf=\"^# ### END LIBTOOL TAG CONFIG: $tagname\\$\"\n  sed_extractcf=\"/$re_begincf/,/$re_endcf/p\"\n\n  # Validate tagname.\n  case $tagname in\n    *[!-_A-Za-z0-9,/]*)\n      func_fatal_error \"invalid tag name: $tagname\"\n      ;;\n  esac\n\n  # Don't test for the \"default\" C tag, as we know it's\n  # there but not specially marked.\n  case $tagname in\n    CC) ;;\n    *)\n      if $GREP \"$re_begincf\" \"$progpath\" >/dev/null 2>&1; then\n\ttaglist=\"$taglist $tagname\"\n\n\t# Evaluate the configuration.  Be careful to quote the path\n\t# and the sed script, to avoid splitting on whitespace, but\n\t# also don't use non-portable quotes within backquotes within\n\t# quotes we have to do it in 2 steps:\n\textractedcf=`$SED -n -e \"$sed_extractcf\" < \"$progpath\"`\n\teval \"$extractedcf\"\n      else\n\tfunc_error \"ignoring unknown tag $tagname\"\n      fi\n      ;;\n  esac\n}\n\n# Parse options once, thoroughly.  This comes as soon as possible in\n# the script to make things like `libtool --version' happen quickly.\n{\n\n  # Shorthand for --mode=foo, only valid as the first argument\n  case $1 in\n  clean|clea|cle|cl)\n    shift; set dummy --mode clean ${1+\"$@\"}; shift\n    ;;\n  compile|compil|compi|comp|com|co|c)\n    shift; set dummy --mode compile ${1+\"$@\"}; shift\n    ;;\n  execute|execut|execu|exec|exe|ex|e)\n    shift; set dummy --mode execute ${1+\"$@\"}; shift\n    ;;\n  finish|finis|fini|fin|fi|f)\n    shift; set dummy --mode finish ${1+\"$@\"}; shift\n    ;;\n  install|instal|insta|inst|ins|in|i)\n    shift; set dummy --mode install ${1+\"$@\"}; shift\n    ;;\n  link|lin|li|l)\n    shift; set dummy --mode link ${1+\"$@\"}; shift\n    ;;\n  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)\n    shift; set dummy --mode uninstall ${1+\"$@\"}; shift\n    ;;\n  esac\n\n  # Parse non-mode specific arguments:\n  while test \"$#\" -gt 0; do\n    opt=\"$1\"\n    shift\n\n    case $opt in\n      --config)\t\tfunc_config\t\t\t\t\t;;\n\n      --debug)\t\tpreserve_args=\"$preserve_args $opt\"\n\t\t\tfunc_echo \"enabling shell trace mode\"\n\t\t\topt_debug='set -x'\n\t\t\t$opt_debug\n\t\t\t;;\n\n      -dlopen)\t\ttest \"$#\" -eq 0 && func_missing_arg \"$opt\" && break\n\t\t\texecute_dlfiles=\"$execute_dlfiles $1\"\n\t\t\tshift\n\t\t\t;;\n\n      --dry-run | -n)\topt_dry_run=:\t\t\t\t\t;;\n      --features)       func_features\t\t\t\t\t;;\n      --finish)\t\tmode=\"finish\"\t\t\t\t\t;;\n\n      --mode)\t\ttest \"$#\" -eq 0 && func_missing_arg \"$opt\" && break\n\t\t\tcase $1 in\n\t\t\t  # Valid mode arguments:\n\t\t\t  clean)\t;;\n\t\t\t  compile)\t;;\n\t\t\t  execute)\t;;\n\t\t\t  finish)\t;;\n\t\t\t  install)\t;;\n\t\t\t  link)\t\t;;\n\t\t\t  relink)\t;;\n\t\t\t  uninstall)\t;;\n\n\t\t\t  # Catch anything else as an error\n\t\t\t  *) func_error \"invalid argument for $opt\"\n\t\t\t     exit_cmd=exit\n\t\t\t     break\n\t\t\t     ;;\n\t\t        esac\n\n\t\t\tmode=\"$1\"\n\t\t\tshift\n\t\t\t;;\n\n      --preserve-dup-deps)\n\t\t\topt_duplicate_deps=:\t\t\t\t;;\n\n      --quiet|--silent)\tpreserve_args=\"$preserve_args $opt\"\n\t\t\topt_silent=:\n\t\t\t;;\n\n      --verbose| -v)\tpreserve_args=\"$preserve_args $opt\"\n\t\t\topt_silent=false\n\t\t\t;;\n\n      --tag)\t\ttest \"$#\" -eq 0 && func_missing_arg \"$opt\" && break\n\t\t\tpreserve_args=\"$preserve_args $opt $1\"\n\t\t\tfunc_enable_tag \"$1\"\t# tagname is set here\n\t\t\tshift\n\t\t\t;;\n\n      # Separate optargs to long options:\n      -dlopen=*|--mode=*|--tag=*)\n\t\t\tfunc_opt_split \"$opt\"\n\t\t\tset dummy \"$func_opt_split_opt\" \"$func_opt_split_arg\" ${1+\"$@\"}\n\t\t\tshift\n\t\t\t;;\n\n      -\\?|-h)\t\tfunc_usage\t\t\t\t\t;;\n      --help)\t\topt_help=:\t\t\t\t\t;;\n      --version)\tfunc_version\t\t\t\t\t;;\n\n      -*)\t\tfunc_fatal_help \"unrecognized option \\`$opt'\"\t;;\n\n      *)\t\tnonopt=\"$opt\"\n\t\t\tbreak\n\t\t\t;;\n    esac\n  done\n\n\n  case $host in\n    *cygwin* | *mingw* | *pw32* | *cegcc*)\n      # don't eliminate duplications in $postdeps and $predeps\n      opt_duplicate_compiler_generated_deps=:\n      ;;\n    *)\n      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps\n      ;;\n  esac\n\n  # Having warned about all mis-specified options, bail out if\n  # anything was wrong.\n  $exit_cmd $EXIT_FAILURE\n}\n\n# func_check_version_match\n# Ensure that we are using m4 macros, and libtool script from the same\n# release of libtool.\nfunc_check_version_match ()\n{\n  if test \"$package_revision\" != \"$macro_revision\"; then\n    if test \"$VERSION\" != \"$macro_version\"; then\n      if test -z \"$macro_version\"; then\n        cat >&2 <<_LT_EOF\n$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the\n$progname: definition of this LT_INIT comes from an older release.\n$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION\n$progname: and run autoconf again.\n_LT_EOF\n      else\n        cat >&2 <<_LT_EOF\n$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the\n$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.\n$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION\n$progname: and run autoconf again.\n_LT_EOF\n      fi\n    else\n      cat >&2 <<_LT_EOF\n$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,\n$progname: but the definition of this LT_INIT comes from revision $macro_revision.\n$progname: You should recreate aclocal.m4 with macros from revision $package_revision\n$progname: of $PACKAGE $VERSION and run autoconf again.\n_LT_EOF\n    fi\n\n    exit $EXIT_MISMATCH\n  fi\n}\n\n\n## ----------- ##\n##    Main.    ##\n## ----------- ##\n\n$opt_help || {\n  # Sanity checks first:\n  func_check_version_match\n\n  if test \"$build_libtool_libs\" != yes && test \"$build_old_libs\" != yes; then\n    func_fatal_configuration \"not configured to build any kind of library\"\n  fi\n\n  test -z \"$mode\" && func_fatal_error \"error: you must specify a MODE.\"\n\n\n  # Darwin sucks\n  eval std_shrext=\\\"$shrext_cmds\\\"\n\n\n  # Only execute mode is allowed to have -dlopen flags.\n  if test -n \"$execute_dlfiles\" && test \"$mode\" != execute; then\n    func_error \"unrecognized option \\`-dlopen'\"\n    $ECHO \"$help\" 1>&2\n    exit $EXIT_FAILURE\n  fi\n\n  # Change the help message to a mode-specific one.\n  generic_help=\"$help\"\n  help=\"Try \\`$progname --help --mode=$mode' for more information.\"\n}\n\n\n# func_lalib_p file\n# True iff FILE is a libtool `.la' library or `.lo' object file.\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_lalib_p ()\n{\n    test -f \"$1\" &&\n      $SED -e 4q \"$1\" 2>/dev/null \\\n        | $GREP \"^# Generated by .*$PACKAGE\" > /dev/null 2>&1\n}\n\n# func_lalib_unsafe_p file\n# True iff FILE is a libtool `.la' library or `.lo' object file.\n# This function implements the same check as func_lalib_p without\n# resorting to external programs.  To this end, it redirects stdin and\n# closes it afterwards, without saving the original file descriptor.\n# As a safety measure, use it only where a negative result would be\n# fatal anyway.  Works if `file' does not exist.\nfunc_lalib_unsafe_p ()\n{\n    lalib_p=no\n    if test -f \"$1\" && test -r \"$1\" && exec 5<&0 <\"$1\"; then\n\tfor lalib_p_l in 1 2 3 4\n\tdo\n\t    read lalib_p_line\n\t    case \"$lalib_p_line\" in\n\t\t\\#\\ Generated\\ by\\ *$PACKAGE* ) lalib_p=yes; break;;\n\t    esac\n\tdone\n\texec 0<&5 5<&-\n    fi\n    test \"$lalib_p\" = yes\n}\n\n# func_ltwrapper_script_p file\n# True iff FILE is a libtool wrapper script\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_ltwrapper_script_p ()\n{\n    func_lalib_p \"$1\"\n}\n\n# func_ltwrapper_executable_p file\n# True iff FILE is a libtool wrapper executable\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_ltwrapper_executable_p ()\n{\n    func_ltwrapper_exec_suffix=\n    case $1 in\n    *.exe) ;;\n    *) func_ltwrapper_exec_suffix=.exe ;;\n    esac\n    $GREP \"$magic_exe\" \"$1$func_ltwrapper_exec_suffix\" >/dev/null 2>&1\n}\n\n# func_ltwrapper_scriptname file\n# Assumes file is an ltwrapper_executable\n# uses $file to determine the appropriate filename for a\n# temporary ltwrapper_script.\nfunc_ltwrapper_scriptname ()\n{\n    func_ltwrapper_scriptname_result=\"\"\n    if func_ltwrapper_executable_p \"$1\"; then\n\tfunc_dirname_and_basename \"$1\" \"\" \".\"\n\tfunc_stripname '' '.exe' \"$func_basename_result\"\n\tfunc_ltwrapper_scriptname_result=\"$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper\"\n    fi\n}\n\n# func_ltwrapper_p file\n# True iff FILE is a libtool wrapper script or wrapper executable\n# This function is only a basic sanity check; it will hardly flush out\n# determined imposters.\nfunc_ltwrapper_p ()\n{\n    func_ltwrapper_script_p \"$1\" || func_ltwrapper_executable_p \"$1\"\n}\n\n\n# func_execute_cmds commands fail_cmd\n# Execute tilde-delimited COMMANDS.\n# If FAIL_CMD is given, eval that upon failure.\n# FAIL_CMD may read-access the current command in variable CMD!\nfunc_execute_cmds ()\n{\n    $opt_debug\n    save_ifs=$IFS; IFS='~'\n    for cmd in $1; do\n      IFS=$save_ifs\n      eval cmd=\\\"$cmd\\\"\n      func_show_eval \"$cmd\" \"${2-:}\"\n    done\n    IFS=$save_ifs\n}\n\n\n# func_source file\n# Source FILE, adding directory component if necessary.\n# Note that it is not necessary on cygwin/mingw to append a dot to\n# FILE even if both FILE and FILE.exe exist: automatic-append-.exe\n# behavior happens only for exec(3), not for open(2)!  Also, sourcing\n# `FILE.' does not work on cygwin managed mounts.\nfunc_source ()\n{\n    $opt_debug\n    case $1 in\n    */* | *\\\\*)\t. \"$1\" ;;\n    *)\t\t. \"./$1\" ;;\n    esac\n}\n\n\n# func_infer_tag arg\n# Infer tagged configuration to use if any are available and\n# if one wasn't chosen via the \"--tag\" command line option.\n# Only attempt this if the compiler in the base compile\n# command doesn't match the default compiler.\n# arg is usually of the form 'gcc ...'\nfunc_infer_tag ()\n{\n    $opt_debug\n    if test -n \"$available_tags\" && test -z \"$tagname\"; then\n      CC_quoted=\n      for arg in $CC; do\n        func_quote_for_eval \"$arg\"\n\tCC_quoted=\"$CC_quoted $func_quote_for_eval_result\"\n      done\n      case $@ in\n      # Blanks in the command may have been stripped by the calling shell,\n      # but not from the CC environment variable when configure was run.\n      \" $CC \"* | \"$CC \"* | \" `$ECHO $CC` \"* | \"`$ECHO $CC` \"* | \" $CC_quoted\"* | \"$CC_quoted \"* | \" `$ECHO $CC_quoted` \"* | \"`$ECHO $CC_quoted` \"*) ;;\n      # Blanks at the start of $base_compile will cause this to fail\n      # if we don't check for them as well.\n      *)\n\tfor z in $available_tags; do\n\t  if $GREP \"^# ### BEGIN LIBTOOL TAG CONFIG: $z$\" < \"$progpath\" > /dev/null; then\n\t    # Evaluate the configuration.\n\t    eval \"`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`\"\n\t    CC_quoted=\n\t    for arg in $CC; do\n\t      # Double-quote args containing other shell metacharacters.\n\t      func_quote_for_eval \"$arg\"\n\t      CC_quoted=\"$CC_quoted $func_quote_for_eval_result\"\n\t    done\n\t    case \"$@ \" in\n\t      \" $CC \"* | \"$CC \"* | \" `$ECHO $CC` \"* | \"`$ECHO $CC` \"* | \" $CC_quoted\"* | \"$CC_quoted \"* | \" `$ECHO $CC_quoted` \"* | \"`$ECHO $CC_quoted` \"*)\n\t      # The compiler in the base compile command matches\n\t      # the one in the tagged configuration.\n\t      # Assume this is the tagged configuration we want.\n\t      tagname=$z\n\t      break\n\t      ;;\n\t    esac\n\t  fi\n\tdone\n\t# If $tagname still isn't set, then no tagged configuration\n\t# was found and let the user know that the \"--tag\" command\n\t# line option must be used.\n\tif test -z \"$tagname\"; then\n\t  func_echo \"unable to infer tagged configuration\"\n\t  func_fatal_error \"specify a tag with \\`--tag'\"\n#\telse\n#\t  func_verbose \"using $tagname tagged configuration\"\n\tfi\n\t;;\n      esac\n    fi\n}\n\n\n\n# func_write_libtool_object output_name pic_name nonpic_name\n# Create a libtool object file (analogous to a \".la\" file),\n# but don't create it if we're doing a dry run.\nfunc_write_libtool_object ()\n{\n    write_libobj=${1}\n    if test \"$build_libtool_libs\" = yes; then\n      write_lobj=\\'${2}\\'\n    else\n      write_lobj=none\n    fi\n\n    if test \"$build_old_libs\" = yes; then\n      write_oldobj=\\'${3}\\'\n    else\n      write_oldobj=none\n    fi\n\n    $opt_dry_run || {\n      cat >${write_libobj}T <<EOF\n# $write_libobj - a libtool object file\n# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n#\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# Name of the PIC object.\npic_object=$write_lobj\n\n# Name of the non-PIC object\nnon_pic_object=$write_oldobj\n\nEOF\n      $MV \"${write_libobj}T\" \"${write_libobj}\"\n    }\n}\n\n# func_mode_compile arg...\nfunc_mode_compile ()\n{\n    $opt_debug\n    # Get the compilation command and the source file.\n    base_compile=\n    srcfile=\"$nonopt\"  #  always keep a non-empty value in \"srcfile\"\n    suppress_opt=yes\n    suppress_output=\n    arg_mode=normal\n    libobj=\n    later=\n    pie_flag=\n\n    for arg\n    do\n      case $arg_mode in\n      arg  )\n\t# do not \"continue\".  Instead, add this to base_compile\n\tlastarg=\"$arg\"\n\targ_mode=normal\n\t;;\n\n      target )\n\tlibobj=\"$arg\"\n\targ_mode=normal\n\tcontinue\n\t;;\n\n      normal )\n\t# Accept any command-line options.\n\tcase $arg in\n\t-o)\n\t  test -n \"$libobj\" && \\\n\t    func_fatal_error \"you cannot specify \\`-o' more than once\"\n\t  arg_mode=target\n\t  continue\n\t  ;;\n\n\t-pie | -fpie | -fPIE)\n          pie_flag=\"$pie_flag $arg\"\n\t  continue\n\t  ;;\n\n\t-shared | -static | -prefer-pic | -prefer-non-pic)\n\t  later=\"$later $arg\"\n\t  continue\n\t  ;;\n\n\t-no-suppress)\n\t  suppress_opt=no\n\t  continue\n\t  ;;\n\n\t-Xcompiler)\n\t  arg_mode=arg  #  the next one goes into the \"base_compile\" arg list\n\t  continue      #  The current \"srcfile\" will either be retained or\n\t  ;;            #  replaced later.  I would guess that would be a bug.\n\n\t-Wc,*)\n\t  func_stripname '-Wc,' '' \"$arg\"\n\t  args=$func_stripname_result\n\t  lastarg=\n\t  save_ifs=\"$IFS\"; IFS=','\n\t  for arg in $args; do\n\t    IFS=\"$save_ifs\"\n\t    func_quote_for_eval \"$arg\"\n\t    lastarg=\"$lastarg $func_quote_for_eval_result\"\n\t  done\n\t  IFS=\"$save_ifs\"\n\t  func_stripname ' ' '' \"$lastarg\"\n\t  lastarg=$func_stripname_result\n\n\t  # Add the arguments to base_compile.\n\t  base_compile=\"$base_compile $lastarg\"\n\t  continue\n\t  ;;\n\n\t*)\n\t  # Accept the current argument as the source file.\n\t  # The previous \"srcfile\" becomes the current argument.\n\t  #\n\t  lastarg=\"$srcfile\"\n\t  srcfile=\"$arg\"\n\t  ;;\n\tesac  #  case $arg\n\t;;\n      esac    #  case $arg_mode\n\n      # Aesthetically quote the previous argument.\n      func_quote_for_eval \"$lastarg\"\n      base_compile=\"$base_compile $func_quote_for_eval_result\"\n    done # for arg\n\n    case $arg_mode in\n    arg)\n      func_fatal_error \"you must specify an argument for -Xcompile\"\n      ;;\n    target)\n      func_fatal_error \"you must specify a target with \\`-o'\"\n      ;;\n    *)\n      # Get the name of the library object.\n      test -z \"$libobj\" && {\n\tfunc_basename \"$srcfile\"\n\tlibobj=\"$func_basename_result\"\n      }\n      ;;\n    esac\n\n    # Recognize several different file suffixes.\n    # If the user specifies -o file.o, it is replaced with file.lo\n    case $libobj in\n    *.[cCFSifmso] | \\\n    *.ada | *.adb | *.ads | *.asm | \\\n    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \\\n    *.[fF][09]? | *.for | *.java | *.obj | *.sx)\n      func_xform \"$libobj\"\n      libobj=$func_xform_result\n      ;;\n    esac\n\n    case $libobj in\n    *.lo) func_lo2o \"$libobj\"; obj=$func_lo2o_result ;;\n    *)\n      func_fatal_error \"cannot determine name of library object from \\`$libobj'\"\n      ;;\n    esac\n\n    func_infer_tag $base_compile\n\n    for arg in $later; do\n      case $arg in\n      -shared)\n\ttest \"$build_libtool_libs\" != yes && \\\n\t  func_fatal_configuration \"can not build a shared library\"\n\tbuild_old_libs=no\n\tcontinue\n\t;;\n\n      -static)\n\tbuild_libtool_libs=no\n\tbuild_old_libs=yes\n\tcontinue\n\t;;\n\n      -prefer-pic)\n\tpic_mode=yes\n\tcontinue\n\t;;\n\n      -prefer-non-pic)\n\tpic_mode=no\n\tcontinue\n\t;;\n      esac\n    done\n\n    func_quote_for_eval \"$libobj\"\n    test \"X$libobj\" != \"X$func_quote_for_eval_result\" \\\n      && $ECHO \"X$libobj\" | $GREP '[]~#^*{};<>?\"'\"'\"'\t &()|`$[]' \\\n      && func_warning \"libobj name \\`$libobj' may not contain shell special characters.\"\n    func_dirname_and_basename \"$obj\" \"/\" \"\"\n    objname=\"$func_basename_result\"\n    xdir=\"$func_dirname_result\"\n    lobj=${xdir}$objdir/$objname\n\n    test -z \"$base_compile\" && \\\n      func_fatal_help \"you must specify a compilation command\"\n\n    # Delete any leftover library objects.\n    if test \"$build_old_libs\" = yes; then\n      removelist=\"$obj $lobj $libobj ${libobj}T\"\n    else\n      removelist=\"$lobj $libobj ${libobj}T\"\n    fi\n\n    # On Cygwin there's no \"real\" PIC flag so we must build both object types\n    case $host_os in\n    cygwin* | mingw* | pw32* | os2* | cegcc*)\n      pic_mode=default\n      ;;\n    esac\n    if test \"$pic_mode\" = no && test \"$deplibs_check_method\" != pass_all; then\n      # non-PIC code in shared libraries is not supported\n      pic_mode=default\n    fi\n\n    # Calculate the filename of the output object if compiler does\n    # not support -o with -c\n    if test \"$compiler_c_o\" = no; then\n      output_obj=`$ECHO \"X$srcfile\" | $Xsed -e 's%^.*/%%' -e 's%\\.[^.]*$%%'`.${objext}\n      lockfile=\"$output_obj.lock\"\n    else\n      output_obj=\n      need_locks=no\n      lockfile=\n    fi\n\n    # Lock this critical section if it is needed\n    # We use this script file to make the link, it avoids creating a new file\n    if test \"$need_locks\" = yes; then\n      until $opt_dry_run || ln \"$progpath\" \"$lockfile\" 2>/dev/null; do\n\tfunc_echo \"Waiting for $lockfile to be removed\"\n\tsleep 2\n      done\n    elif test \"$need_locks\" = warn; then\n      if test -f \"$lockfile\"; then\n\t$ECHO \"\\\n*** ERROR, $lockfile exists and contains:\n`cat $lockfile 2>/dev/null`\n\nThis indicates that another process is trying to use the same\ntemporary object file, and libtool could not work around it because\nyour compiler does not support \\`-c' and \\`-o' together.  If you\nrepeat this compilation, it may succeed, by chance, but you had better\navoid parallel builds (make -j) in this platform, or get a better\ncompiler.\"\n\n\t$opt_dry_run || $RM $removelist\n\texit $EXIT_FAILURE\n      fi\n      removelist=\"$removelist $output_obj\"\n      $ECHO \"$srcfile\" > \"$lockfile\"\n    fi\n\n    $opt_dry_run || $RM $removelist\n    removelist=\"$removelist $lockfile\"\n    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15\n\n    if test -n \"$fix_srcfile_path\"; then\n      eval srcfile=\\\"$fix_srcfile_path\\\"\n    fi\n    func_quote_for_eval \"$srcfile\"\n    qsrcfile=$func_quote_for_eval_result\n\n    # Only build a PIC object if we are building libtool libraries.\n    if test \"$build_libtool_libs\" = yes; then\n      # Without this assignment, base_compile gets emptied.\n      fbsd_hideous_sh_bug=$base_compile\n\n      if test \"$pic_mode\" != no; then\n\tcommand=\"$base_compile $qsrcfile $pic_flag\"\n      else\n\t# Don't build PIC code\n\tcommand=\"$base_compile $qsrcfile\"\n      fi\n\n      func_mkdir_p \"$xdir$objdir\"\n\n      if test -z \"$output_obj\"; then\n\t# Place PIC objects in $objdir\n\tcommand=\"$command -o $lobj\"\n      fi\n\n      func_show_eval_locale \"$command\"\t\\\n          'test -n \"$output_obj\" && $RM $removelist; exit $EXIT_FAILURE'\n\n      if test \"$need_locks\" = warn &&\n\t test \"X`cat $lockfile 2>/dev/null`\" != \"X$srcfile\"; then\n\t$ECHO \"\\\n*** ERROR, $lockfile contains:\n`cat $lockfile 2>/dev/null`\n\nbut it should contain:\n$srcfile\n\nThis indicates that another process is trying to use the same\ntemporary object file, and libtool could not work around it because\nyour compiler does not support \\`-c' and \\`-o' together.  If you\nrepeat this compilation, it may succeed, by chance, but you had better\navoid parallel builds (make -j) in this platform, or get a better\ncompiler.\"\n\n\t$opt_dry_run || $RM $removelist\n\texit $EXIT_FAILURE\n      fi\n\n      # Just move the object if needed, then go on to compile the next one\n      if test -n \"$output_obj\" && test \"X$output_obj\" != \"X$lobj\"; then\n\tfunc_show_eval '$MV \"$output_obj\" \"$lobj\"' \\\n\t  'error=$?; $opt_dry_run || $RM $removelist; exit $error'\n      fi\n\n      # Allow error messages only from the first compilation.\n      if test \"$suppress_opt\" = yes; then\n\tsuppress_output=' >/dev/null 2>&1'\n      fi\n    fi\n\n    # Only build a position-dependent object if we build old libraries.\n    if test \"$build_old_libs\" = yes; then\n      if test \"$pic_mode\" != yes; then\n\t# Don't build PIC code\n\tcommand=\"$base_compile $qsrcfile$pie_flag\"\n      else\n\tcommand=\"$base_compile $qsrcfile $pic_flag\"\n      fi\n      if test \"$compiler_c_o\" = yes; then\n\tcommand=\"$command -o $obj\"\n      fi\n\n      # Suppress compiler output if we already did a PIC compilation.\n      command=\"$command$suppress_output\"\n      func_show_eval_locale \"$command\" \\\n        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'\n\n      if test \"$need_locks\" = warn &&\n\t test \"X`cat $lockfile 2>/dev/null`\" != \"X$srcfile\"; then\n\t$ECHO \"\\\n*** ERROR, $lockfile contains:\n`cat $lockfile 2>/dev/null`\n\nbut it should contain:\n$srcfile\n\nThis indicates that another process is trying to use the same\ntemporary object file, and libtool could not work around it because\nyour compiler does not support \\`-c' and \\`-o' together.  If you\nrepeat this compilation, it may succeed, by chance, but you had better\navoid parallel builds (make -j) in this platform, or get a better\ncompiler.\"\n\n\t$opt_dry_run || $RM $removelist\n\texit $EXIT_FAILURE\n      fi\n\n      # Just move the object if needed\n      if test -n \"$output_obj\" && test \"X$output_obj\" != \"X$obj\"; then\n\tfunc_show_eval '$MV \"$output_obj\" \"$obj\"' \\\n\t  'error=$?; $opt_dry_run || $RM $removelist; exit $error'\n      fi\n    fi\n\n    $opt_dry_run || {\n      func_write_libtool_object \"$libobj\" \"$objdir/$objname\" \"$objname\"\n\n      # Unlock the critical section if it was locked\n      if test \"$need_locks\" != no; then\n\tremovelist=$lockfile\n        $RM \"$lockfile\"\n      fi\n    }\n\n    exit $EXIT_SUCCESS\n}\n\n$opt_help || {\ntest \"$mode\" = compile && func_mode_compile ${1+\"$@\"}\n}\n\nfunc_mode_help ()\n{\n    # We need to display help for each of the modes.\n    case $mode in\n      \"\")\n        # Generic help is extracted from the usage comments\n        # at the start of this file.\n        func_help\n        ;;\n\n      clean)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...\n\nRemove files from the build directory.\n\nRM is the name of the program to use to delete files associated with each FILE\n(typically \\`/bin/rm').  RM-OPTIONS are options (such as \\`-f') to be passed\nto RM.\n\nIf FILE is a libtool library, object or program, all the files associated\nwith it are deleted. Otherwise, only FILE itself is deleted using RM.\"\n        ;;\n\n      compile)\n      $ECHO \\\n\"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE\n\nCompile a source file into a libtool library object.\n\nThis mode accepts the following additional options:\n\n  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE\n  -no-suppress      do not suppress compiler output for multiple passes\n  -prefer-pic       try to building PIC objects only\n  -prefer-non-pic   try to building non-PIC objects only\n  -shared           do not build a \\`.o' file suitable for static linking\n  -static           only build a \\`.o' file suitable for static linking\n\nCOMPILE-COMMAND is a command to be used in creating a \\`standard' object file\nfrom the given SOURCEFILE.\n\nThe output file name is determined by removing the directory component from\nSOURCEFILE, then substituting the C source code suffix \\`.c' with the\nlibrary object suffix, \\`.lo'.\"\n        ;;\n\n      execute)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...\n\nAutomatically set library path, then run a program.\n\nThis mode accepts the following additional options:\n\n  -dlopen FILE      add the directory containing FILE to the library path\n\nThis mode sets the library path environment variable according to \\`-dlopen'\nflags.\n\nIf any of the ARGS are libtool executable wrappers, then they are translated\ninto their corresponding uninstalled binary, and any of their required library\ndirectories are added to the library path.\n\nThen, COMMAND is executed, with ARGS as arguments.\"\n        ;;\n\n      finish)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...\n\nComplete the installation of libtool libraries.\n\nEach LIBDIR is a directory that contains libtool libraries.\n\nThe commands that this mode executes may require superuser privileges.  Use\nthe \\`--dry-run' option if you just want to see what would be executed.\"\n        ;;\n\n      install)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...\n\nInstall executables or libraries.\n\nINSTALL-COMMAND is the installation command.  The first component should be\neither the \\`install' or \\`cp' program.\n\nThe following components of INSTALL-COMMAND are treated specially:\n\n  -inst-prefix PREFIX-DIR  Use PREFIX-DIR as a staging area for installation\n\nThe rest of the components are interpreted as arguments to that command (only\nBSD-compatible install options are recognized).\"\n        ;;\n\n      link)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...\n\nLink object files or libraries together to form another library, or to\ncreate an executable program.\n\nLINK-COMMAND is a command using the C compiler that you would use to create\na program from several object files.\n\nThe following components of LINK-COMMAND are treated specially:\n\n  -all-static       do not do any dynamic linking at all\n  -avoid-version    do not add a version suffix if possible\n  -dlopen FILE      \\`-dlpreopen' FILE if it cannot be dlopened at runtime\n  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols\n  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)\n  -export-symbols SYMFILE\n                    try to export only the symbols listed in SYMFILE\n  -export-symbols-regex REGEX\n                    try to export only the symbols matching REGEX\n  -LLIBDIR          search LIBDIR for required installed libraries\n  -lNAME            OUTPUT-FILE requires the installed library libNAME\n  -module           build a library that can dlopened\n  -no-fast-install  disable the fast-install mode\n  -no-install       link a not-installable executable\n  -no-undefined     declare that a library does not refer to external symbols\n  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects\n  -objectlist FILE  Use a list of object files found in FILE to specify objects\n  -precious-files-regex REGEX\n                    don't remove output files matching REGEX\n  -release RELEASE  specify package release information\n  -rpath LIBDIR     the created library will eventually be installed in LIBDIR\n  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries\n  -shared           only do dynamic linking of libtool libraries\n  -shrext SUFFIX    override the standard shared library file extension\n  -static           do not do any dynamic linking of uninstalled libtool libraries\n  -static-libtool-libs\n                    do not do any dynamic linking of libtool libraries\n  -version-info CURRENT[:REVISION[:AGE]]\n                    specify library version info [each variable defaults to 0]\n  -weak LIBNAME     declare that the target provides the LIBNAME interface\n\nAll other options (arguments beginning with \\`-') are ignored.\n\nEvery other argument is treated as a filename.  Files ending in \\`.la' are\ntreated as uninstalled libtool libraries, other files are standard or library\nobject files.\n\nIf the OUTPUT-FILE ends in \\`.la', then a libtool library is created,\nonly library objects (\\`.lo' files) may be specified, and \\`-rpath' is\nrequired, except when creating a convenience library.\n\nIf OUTPUT-FILE ends in \\`.a' or \\`.lib', then a standard library is created\nusing \\`ar' and \\`ranlib', or on Windows using \\`lib'.\n\nIf OUTPUT-FILE ends in \\`.lo' or \\`.${objext}', then a reloadable object file\nis created, otherwise an executable program is created.\"\n        ;;\n\n      uninstall)\n        $ECHO \\\n\"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...\n\nRemove libraries from an installation directory.\n\nRM is the name of the program to use to delete files associated with each FILE\n(typically \\`/bin/rm').  RM-OPTIONS are options (such as \\`-f') to be passed\nto RM.\n\nIf FILE is a libtool library, all the files associated with it are deleted.\nOtherwise, only FILE itself is deleted using RM.\"\n        ;;\n\n      *)\n        func_fatal_help \"invalid operation mode \\`$mode'\"\n        ;;\n    esac\n\n    $ECHO\n    $ECHO \"Try \\`$progname --help' for more information about other modes.\"\n\n    exit $?\n}\n\n  # Now that we've collected a possible --mode arg, show help if necessary\n  $opt_help && func_mode_help\n\n\n# func_mode_execute arg...\nfunc_mode_execute ()\n{\n    $opt_debug\n    # The first argument is the command name.\n    cmd=\"$nonopt\"\n    test -z \"$cmd\" && \\\n      func_fatal_help \"you must specify a COMMAND\"\n\n    # Handle -dlopen flags immediately.\n    for file in $execute_dlfiles; do\n      test -f \"$file\" \\\n\t|| func_fatal_help \"\\`$file' is not a file\"\n\n      dir=\n      case $file in\n      *.la)\n\t# Check to see that this really is a libtool archive.\n\tfunc_lalib_unsafe_p \"$file\" \\\n\t  || func_fatal_help \"\\`$lib' is not a valid libtool archive\"\n\n\t# Read the libtool library.\n\tdlname=\n\tlibrary_names=\n\tfunc_source \"$file\"\n\n\t# Skip this library if it cannot be dlopened.\n\tif test -z \"$dlname\"; then\n\t  # Warn if it was a shared library.\n\t  test -n \"$library_names\" && \\\n\t    func_warning \"\\`$file' was not linked with \\`-export-dynamic'\"\n\t  continue\n\tfi\n\n\tfunc_dirname \"$file\" \"\" \".\"\n\tdir=\"$func_dirname_result\"\n\n\tif test -f \"$dir/$objdir/$dlname\"; then\n\t  dir=\"$dir/$objdir\"\n\telse\n\t  if test ! -f \"$dir/$dlname\"; then\n\t    func_fatal_error \"cannot find \\`$dlname' in \\`$dir' or \\`$dir/$objdir'\"\n\t  fi\n\tfi\n\t;;\n\n      *.lo)\n\t# Just add the directory containing the .lo file.\n\tfunc_dirname \"$file\" \"\" \".\"\n\tdir=\"$func_dirname_result\"\n\t;;\n\n      *)\n\tfunc_warning \"\\`-dlopen' is ignored for non-libtool libraries and objects\"\n\tcontinue\n\t;;\n      esac\n\n      # Get the absolute pathname.\n      absdir=`cd \"$dir\" && pwd`\n      test -n \"$absdir\" && dir=\"$absdir\"\n\n      # Now add the directory to shlibpath_var.\n      if eval \"test -z \\\"\\$$shlibpath_var\\\"\"; then\n\teval \"$shlibpath_var=\\\"\\$dir\\\"\"\n      else\n\teval \"$shlibpath_var=\\\"\\$dir:\\$$shlibpath_var\\\"\"\n      fi\n    done\n\n    # This variable tells wrapper scripts just to set shlibpath_var\n    # rather than running their programs.\n    libtool_execute_magic=\"$magic\"\n\n    # Check if any of the arguments is a wrapper script.\n    args=\n    for file\n    do\n      case $file in\n      -*) ;;\n      *)\n\t# Do a test to see if this is really a libtool program.\n\tif func_ltwrapper_script_p \"$file\"; then\n\t  func_source \"$file\"\n\t  # Transform arg to wrapped name.\n\t  file=\"$progdir/$program\"\n\telif func_ltwrapper_executable_p \"$file\"; then\n\t  func_ltwrapper_scriptname \"$file\"\n\t  func_source \"$func_ltwrapper_scriptname_result\"\n\t  # Transform arg to wrapped name.\n\t  file=\"$progdir/$program\"\n\tfi\n\t;;\n      esac\n      # Quote arguments (to preserve shell metacharacters).\n      func_quote_for_eval \"$file\"\n      args=\"$args $func_quote_for_eval_result\"\n    done\n\n    if test \"X$opt_dry_run\" = Xfalse; then\n      if test -n \"$shlibpath_var\"; then\n\t# Export the shlibpath_var.\n\teval \"export $shlibpath_var\"\n      fi\n\n      # Restore saved environment variables\n      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES\n      do\n\teval \"if test \\\"\\${save_$lt_var+set}\\\" = set; then\n                $lt_var=\\$save_$lt_var; export $lt_var\n\t      else\n\t\t$lt_unset $lt_var\n\t      fi\"\n      done\n\n      # Now prepare to actually exec the command.\n      exec_cmd=\"\\$cmd$args\"\n    else\n      # Display what would be done.\n      if test -n \"$shlibpath_var\"; then\n\teval \"\\$ECHO \\\"\\$shlibpath_var=\\$$shlibpath_var\\\"\"\n\t$ECHO \"export $shlibpath_var\"\n      fi\n      $ECHO \"$cmd$args\"\n      exit $EXIT_SUCCESS\n    fi\n}\n\ntest \"$mode\" = execute && func_mode_execute ${1+\"$@\"}\n\n\n# func_mode_finish arg...\nfunc_mode_finish ()\n{\n    $opt_debug\n    libdirs=\"$nonopt\"\n    admincmds=\n\n    if test -n \"$finish_cmds$finish_eval\" && test -n \"$libdirs\"; then\n      for dir\n      do\n\tlibdirs=\"$libdirs $dir\"\n      done\n\n      for libdir in $libdirs; do\n\tif test -n \"$finish_cmds\"; then\n\t  # Do each command in the finish commands.\n\t  func_execute_cmds \"$finish_cmds\" 'admincmds=\"$admincmds\n'\"$cmd\"'\"'\n\tfi\n\tif test -n \"$finish_eval\"; then\n\t  # Do the single finish_eval.\n\t  eval cmds=\\\"$finish_eval\\\"\n\t  $opt_dry_run || eval \"$cmds\" || admincmds=\"$admincmds\n       $cmds\"\n\tfi\n      done\n    fi\n\n    # Exit here if they wanted silent mode.\n    $opt_silent && exit $EXIT_SUCCESS\n\n    $ECHO \"X----------------------------------------------------------------------\" | $Xsed\n    $ECHO \"Libraries have been installed in:\"\n    for libdir in $libdirs; do\n      $ECHO \"   $libdir\"\n    done\n    $ECHO\n    $ECHO \"If you ever happen to want to link against installed libraries\"\n    $ECHO \"in a given directory, LIBDIR, you must either use libtool, and\"\n    $ECHO \"specify the full pathname of the library, or use the \\`-LLIBDIR'\"\n    $ECHO \"flag during linking and do at least one of the following:\"\n    if test -n \"$shlibpath_var\"; then\n      $ECHO \"   - add LIBDIR to the \\`$shlibpath_var' environment variable\"\n      $ECHO \"     during execution\"\n    fi\n    if test -n \"$runpath_var\"; then\n      $ECHO \"   - add LIBDIR to the \\`$runpath_var' environment variable\"\n      $ECHO \"     during linking\"\n    fi\n    if test -n \"$hardcode_libdir_flag_spec\"; then\n      libdir=LIBDIR\n      eval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\n      $ECHO \"   - use the \\`$flag' linker flag\"\n    fi\n    if test -n \"$admincmds\"; then\n      $ECHO \"   - have your system administrator run these commands:$admincmds\"\n    fi\n    if test -f /etc/ld.so.conf; then\n      $ECHO \"   - have your system administrator add LIBDIR to \\`/etc/ld.so.conf'\"\n    fi\n    $ECHO\n\n    $ECHO \"See any operating system documentation about shared libraries for\"\n    case $host in\n      solaris2.[6789]|solaris2.1[0-9])\n        $ECHO \"more information, such as the ld(1), crle(1) and ld.so(8) manual\"\n\t$ECHO \"pages.\"\n\t;;\n      *)\n        $ECHO \"more information, such as the ld(1) and ld.so(8) manual pages.\"\n        ;;\n    esac\n    $ECHO \"X----------------------------------------------------------------------\" | $Xsed\n    exit $EXIT_SUCCESS\n}\n\ntest \"$mode\" = finish && func_mode_finish ${1+\"$@\"}\n\n\n# func_mode_install arg...\nfunc_mode_install ()\n{\n    $opt_debug\n    # There may be an optional sh(1) argument at the beginning of\n    # install_prog (especially on Windows NT).\n    if test \"$nonopt\" = \"$SHELL\" || test \"$nonopt\" = /bin/sh ||\n       # Allow the use of GNU shtool's install command.\n       $ECHO \"X$nonopt\" | $GREP shtool >/dev/null; then\n      # Aesthetically quote it.\n      func_quote_for_eval \"$nonopt\"\n      install_prog=\"$func_quote_for_eval_result \"\n      arg=$1\n      shift\n    else\n      install_prog=\n      arg=$nonopt\n    fi\n\n    # The real first argument should be the name of the installation program.\n    # Aesthetically quote it.\n    func_quote_for_eval \"$arg\"\n    install_prog=\"$install_prog$func_quote_for_eval_result\"\n\n    # We need to accept at least all the BSD install flags.\n    dest=\n    files=\n    opts=\n    prev=\n    install_type=\n    isdir=no\n    stripme=\n    for arg\n    do\n      if test -n \"$dest\"; then\n\tfiles=\"$files $dest\"\n\tdest=$arg\n\tcontinue\n      fi\n\n      case $arg in\n      -d) isdir=yes ;;\n      -f)\n\tcase \" $install_prog \" in\n\t*[\\\\\\ /]cp\\ *) ;;\n\t*) prev=$arg ;;\n\tesac\n\t;;\n      -g | -m | -o)\n\tprev=$arg\n\t;;\n      -s)\n\tstripme=\" -s\"\n\tcontinue\n\t;;\n      -*)\n\t;;\n      *)\n\t# If the previous option needed an argument, then skip it.\n\tif test -n \"$prev\"; then\n\t  prev=\n\telse\n\t  dest=$arg\n\t  continue\n\tfi\n\t;;\n      esac\n\n      # Aesthetically quote the argument.\n      func_quote_for_eval \"$arg\"\n      install_prog=\"$install_prog $func_quote_for_eval_result\"\n    done\n\n    test -z \"$install_prog\" && \\\n      func_fatal_help \"you must specify an install program\"\n\n    test -n \"$prev\" && \\\n      func_fatal_help \"the \\`$prev' option requires an argument\"\n\n    if test -z \"$files\"; then\n      if test -z \"$dest\"; then\n\tfunc_fatal_help \"no file or destination specified\"\n      else\n\tfunc_fatal_help \"you must specify a destination\"\n      fi\n    fi\n\n    # Strip any trailing slash from the destination.\n    func_stripname '' '/' \"$dest\"\n    dest=$func_stripname_result\n\n    # Check to see that the destination is a directory.\n    test -d \"$dest\" && isdir=yes\n    if test \"$isdir\" = yes; then\n      destdir=\"$dest\"\n      destname=\n    else\n      func_dirname_and_basename \"$dest\" \"\" \".\"\n      destdir=\"$func_dirname_result\"\n      destname=\"$func_basename_result\"\n\n      # Not a directory, so check to see that there is only one file specified.\n      set dummy $files; shift\n      test \"$#\" -gt 1 && \\\n\tfunc_fatal_help \"\\`$dest' is not a directory\"\n    fi\n    case $destdir in\n    [\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n    *)\n      for file in $files; do\n\tcase $file in\n\t*.lo) ;;\n\t*)\n\t  func_fatal_help \"\\`$destdir' must be an absolute directory name\"\n\t  ;;\n\tesac\n      done\n      ;;\n    esac\n\n    # This variable tells wrapper scripts just to set variables rather\n    # than running their programs.\n    libtool_install_magic=\"$magic\"\n\n    staticlibs=\n    future_libdirs=\n    current_libdirs=\n    for file in $files; do\n\n      # Do each installation.\n      case $file in\n      *.$libext)\n\t# Do the static libraries later.\n\tstaticlibs=\"$staticlibs $file\"\n\t;;\n\n      *.la)\n\t# Check to see that this really is a libtool archive.\n\tfunc_lalib_unsafe_p \"$file\" \\\n\t  || func_fatal_help \"\\`$file' is not a valid libtool archive\"\n\n\tlibrary_names=\n\told_library=\n\trelink_command=\n\tfunc_source \"$file\"\n\n\t# Add the libdir to current_libdirs if it is the destination.\n\tif test \"X$destdir\" = \"X$libdir\"; then\n\t  case \"$current_libdirs \" in\n\t  *\" $libdir \"*) ;;\n\t  *) current_libdirs=\"$current_libdirs $libdir\" ;;\n\t  esac\n\telse\n\t  # Note the libdir as a future libdir.\n\t  case \"$future_libdirs \" in\n\t  *\" $libdir \"*) ;;\n\t  *) future_libdirs=\"$future_libdirs $libdir\" ;;\n\t  esac\n\tfi\n\n\tfunc_dirname \"$file\" \"/\" \"\"\n\tdir=\"$func_dirname_result\"\n\tdir=\"$dir$objdir\"\n\n\tif test -n \"$relink_command\"; then\n\t  # Determine the prefix the user has applied to our future dir.\n\t  inst_prefix_dir=`$ECHO \"X$destdir\" | $Xsed -e \"s%$libdir\\$%%\"`\n\n\t  # Don't allow the user to place us outside of our expected\n\t  # location b/c this prevents finding dependent libraries that\n\t  # are installed to the same prefix.\n\t  # At present, this check doesn't affect windows .dll's that\n\t  # are installed into $libdir/../bin (currently, that works fine)\n\t  # but it's something to keep an eye on.\n\t  test \"$inst_prefix_dir\" = \"$destdir\" && \\\n\t    func_fatal_error \"error: cannot install \\`$file' to a directory not ending in $libdir\"\n\n\t  if test -n \"$inst_prefix_dir\"; then\n\t    # Stick the inst_prefix_dir data into the link command.\n\t    relink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%\"`\n\t  else\n\t    relink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"s%@inst_prefix_dir@%%\"`\n\t  fi\n\n\t  func_warning \"relinking \\`$file'\"\n\t  func_show_eval \"$relink_command\" \\\n\t    'func_fatal_error \"error: relink \\`$file'\\'' with the above command before installing it\"'\n\tfi\n\n\t# See the names of the shared library.\n\tset dummy $library_names; shift\n\tif test -n \"$1\"; then\n\t  realname=\"$1\"\n\t  shift\n\n\t  srcname=\"$realname\"\n\t  test -n \"$relink_command\" && srcname=\"$realname\"T\n\n\t  # Install the shared library and build the symlinks.\n\t  func_show_eval \"$install_prog $dir/$srcname $destdir/$realname\" \\\n\t      'exit $?'\n\t  tstripme=\"$stripme\"\n\t  case $host_os in\n\t  cygwin* | mingw* | pw32* | cegcc*)\n\t    case $realname in\n\t    *.dll.a)\n\t      tstripme=\"\"\n\t      ;;\n\t    esac\n\t    ;;\n\t  esac\n\t  if test -n \"$tstripme\" && test -n \"$striplib\"; then\n\t    func_show_eval \"$striplib $destdir/$realname\" 'exit $?'\n\t  fi\n\n\t  if test \"$#\" -gt 0; then\n\t    # Delete the old symlinks, and create new ones.\n\t    # Try `ln -sf' first, because the `ln' binary might depend on\n\t    # the symlink we replace!  Solaris /bin/ln does not understand -f,\n\t    # so we also need to try rm && ln -s.\n\t    for linkname\n\t    do\n\t      test \"$linkname\" != \"$realname\" \\\n\t\t&& func_show_eval \"(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })\"\n\t    done\n\t  fi\n\n\t  # Do each command in the postinstall commands.\n\t  lib=\"$destdir/$realname\"\n\t  func_execute_cmds \"$postinstall_cmds\" 'exit $?'\n\tfi\n\n\t# Install the pseudo-library for information purposes.\n\tfunc_basename \"$file\"\n\tname=\"$func_basename_result\"\n\tinstname=\"$dir/$name\"i\n\tfunc_show_eval \"$install_prog $instname $destdir/$name\" 'exit $?'\n\n\t# Maybe install the static library, too.\n\ttest -n \"$old_library\" && staticlibs=\"$staticlibs $dir/$old_library\"\n\t;;\n\n      *.lo)\n\t# Install (i.e. copy) a libtool object.\n\n\t# Figure out destination file name, if it wasn't already specified.\n\tif test -n \"$destname\"; then\n\t  destfile=\"$destdir/$destname\"\n\telse\n\t  func_basename \"$file\"\n\t  destfile=\"$func_basename_result\"\n\t  destfile=\"$destdir/$destfile\"\n\tfi\n\n\t# Deduce the name of the destination old-style object file.\n\tcase $destfile in\n\t*.lo)\n\t  func_lo2o \"$destfile\"\n\t  staticdest=$func_lo2o_result\n\t  ;;\n\t*.$objext)\n\t  staticdest=\"$destfile\"\n\t  destfile=\n\t  ;;\n\t*)\n\t  func_fatal_help \"cannot copy a libtool object to \\`$destfile'\"\n\t  ;;\n\tesac\n\n\t# Install the libtool object if requested.\n\ttest -n \"$destfile\" && \\\n\t  func_show_eval \"$install_prog $file $destfile\" 'exit $?'\n\n\t# Install the old object if enabled.\n\tif test \"$build_old_libs\" = yes; then\n\t  # Deduce the name of the old-style object file.\n\t  func_lo2o \"$file\"\n\t  staticobj=$func_lo2o_result\n\t  func_show_eval \"$install_prog \\$staticobj \\$staticdest\" 'exit $?'\n\tfi\n\texit $EXIT_SUCCESS\n\t;;\n\n      *)\n\t# Figure out destination file name, if it wasn't already specified.\n\tif test -n \"$destname\"; then\n\t  destfile=\"$destdir/$destname\"\n\telse\n\t  func_basename \"$file\"\n\t  destfile=\"$func_basename_result\"\n\t  destfile=\"$destdir/$destfile\"\n\tfi\n\n\t# If the file is missing, and there is a .exe on the end, strip it\n\t# because it is most likely a libtool script we actually want to\n\t# install\n\tstripped_ext=\"\"\n\tcase $file in\n\t  *.exe)\n\t    if test ! -f \"$file\"; then\n\t      func_stripname '' '.exe' \"$file\"\n\t      file=$func_stripname_result\n\t      stripped_ext=\".exe\"\n\t    fi\n\t    ;;\n\tesac\n\n\t# Do a test to see if this is really a libtool program.\n\tcase $host in\n\t*cygwin* | *mingw*)\n\t    if func_ltwrapper_executable_p \"$file\"; then\n\t      func_ltwrapper_scriptname \"$file\"\n\t      wrapper=$func_ltwrapper_scriptname_result\n\t    else\n\t      func_stripname '' '.exe' \"$file\"\n\t      wrapper=$func_stripname_result\n\t    fi\n\t    ;;\n\t*)\n\t    wrapper=$file\n\t    ;;\n\tesac\n\tif func_ltwrapper_script_p \"$wrapper\"; then\n\t  notinst_deplibs=\n\t  relink_command=\n\n\t  func_source \"$wrapper\"\n\n\t  # Check the variables that should have been set.\n\t  test -z \"$generated_by_libtool_version\" && \\\n\t    func_fatal_error \"invalid libtool wrapper script \\`$wrapper'\"\n\n\t  finalize=yes\n\t  for lib in $notinst_deplibs; do\n\t    # Check to see that each library is installed.\n\t    libdir=\n\t    if test -f \"$lib\"; then\n\t      func_source \"$lib\"\n\t    fi\n\t    libfile=\"$libdir/\"`$ECHO \"X$lib\" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test\n\t    if test -n \"$libdir\" && test ! -f \"$libfile\"; then\n\t      func_warning \"\\`$lib' has not been installed in \\`$libdir'\"\n\t      finalize=no\n\t    fi\n\t  done\n\n\t  relink_command=\n\t  func_source \"$wrapper\"\n\n\t  outputname=\n\t  if test \"$fast_install\" = no && test -n \"$relink_command\"; then\n\t    $opt_dry_run || {\n\t      if test \"$finalize\" = yes; then\n\t        tmpdir=`func_mktempdir`\n\t\tfunc_basename \"$file$stripped_ext\"\n\t\tfile=\"$func_basename_result\"\n\t        outputname=\"$tmpdir/$file\"\n\t        # Replace the output file specification.\n\t        relink_command=`$ECHO \"X$relink_command\" | $Xsed -e 's%@OUTPUT@%'\"$outputname\"'%g'`\n\n\t        $opt_silent || {\n\t          func_quote_for_expand \"$relink_command\"\n\t\t  eval \"func_echo $func_quote_for_expand_result\"\n\t        }\n\t        if eval \"$relink_command\"; then :\n\t          else\n\t\t  func_error \"error: relink \\`$file' with the above command before installing it\"\n\t\t  $opt_dry_run || ${RM}r \"$tmpdir\"\n\t\t  continue\n\t        fi\n\t        file=\"$outputname\"\n\t      else\n\t        func_warning \"cannot relink \\`$file'\"\n\t      fi\n\t    }\n\t  else\n\t    # Install the binary that we compiled earlier.\n\t    file=`$ECHO \"X$file$stripped_ext\" | $Xsed -e \"s%\\([^/]*\\)$%$objdir/\\1%\"`\n\t  fi\n\tfi\n\n\t# remove .exe since cygwin /usr/bin/install will append another\n\t# one anyway\n\tcase $install_prog,$host in\n\t*/usr/bin/install*,*cygwin*)\n\t  case $file:$destfile in\n\t  *.exe:*.exe)\n\t    # this is ok\n\t    ;;\n\t  *.exe:*)\n\t    destfile=$destfile.exe\n\t    ;;\n\t  *:*.exe)\n\t    func_stripname '' '.exe' \"$destfile\"\n\t    destfile=$func_stripname_result\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n\tfunc_show_eval \"$install_prog\\$stripme \\$file \\$destfile\" 'exit $?'\n\t$opt_dry_run || if test -n \"$outputname\"; then\n\t  ${RM}r \"$tmpdir\"\n\tfi\n\t;;\n      esac\n    done\n\n    for file in $staticlibs; do\n      func_basename \"$file\"\n      name=\"$func_basename_result\"\n\n      # Set up the ranlib parameters.\n      oldlib=\"$destdir/$name\"\n\n      func_show_eval \"$install_prog \\$file \\$oldlib\" 'exit $?'\n\n      if test -n \"$stripme\" && test -n \"$old_striplib\"; then\n\tfunc_show_eval \"$old_striplib $oldlib\" 'exit $?'\n      fi\n\n      # Do each command in the postinstall commands.\n      func_execute_cmds \"$old_postinstall_cmds\" 'exit $?'\n    done\n\n    test -n \"$future_libdirs\" && \\\n      func_warning \"remember to run \\`$progname --finish$future_libdirs'\"\n\n    if test -n \"$current_libdirs\"; then\n      # Maybe just do a dry run.\n      $opt_dry_run && current_libdirs=\" -n$current_libdirs\"\n      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'\n    else\n      exit $EXIT_SUCCESS\n    fi\n}\n\ntest \"$mode\" = install && func_mode_install ${1+\"$@\"}\n\n\n# func_generate_dlsyms outputname originator pic_p\n# Extract symbols from dlprefiles and create ${outputname}S.o with\n# a dlpreopen symbol table.\nfunc_generate_dlsyms ()\n{\n    $opt_debug\n    my_outputname=\"$1\"\n    my_originator=\"$2\"\n    my_pic_p=\"${3-no}\"\n    my_prefix=`$ECHO \"$my_originator\" | sed 's%[^a-zA-Z0-9]%_%g'`\n    my_dlsyms=\n\n    if test -n \"$dlfiles$dlprefiles\" || test \"$dlself\" != no; then\n      if test -n \"$NM\" && test -n \"$global_symbol_pipe\"; then\n\tmy_dlsyms=\"${my_outputname}S.c\"\n      else\n\tfunc_error \"not configured to extract global symbols from dlpreopened files\"\n      fi\n    fi\n\n    if test -n \"$my_dlsyms\"; then\n      case $my_dlsyms in\n      \"\") ;;\n      *.c)\n\t# Discover the nlist of each of the dlfiles.\n\tnlist=\"$output_objdir/${my_outputname}.nm\"\n\n\tfunc_show_eval \"$RM $nlist ${nlist}S ${nlist}T\"\n\n\t# Parse the name list into a source file.\n\tfunc_verbose \"creating $output_objdir/$my_dlsyms\"\n\n\t$opt_dry_run || $ECHO > \"$output_objdir/$my_dlsyms\" \"\\\n/* $my_dlsyms - symbol resolution table for \\`$my_outputname' dlsym emulation. */\n/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */\n\n#ifdef __cplusplus\nextern \\\"C\\\" {\n#endif\n\n/* External symbol declarations for the compiler. */\\\n\"\n\n\tif test \"$dlself\" = yes; then\n\t  func_verbose \"generating symbol list for \\`$output'\"\n\n\t  $opt_dry_run || echo ': @PROGRAM@ ' > \"$nlist\"\n\n\t  # Add our own program objects to the symbol list.\n\t  progfiles=`$ECHO \"X$objs$old_deplibs\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n\t  for progfile in $progfiles; do\n\t    func_verbose \"extracting global C symbols from \\`$progfile'\"\n\t    $opt_dry_run || eval \"$NM $progfile | $global_symbol_pipe >> '$nlist'\"\n\t  done\n\n\t  if test -n \"$exclude_expsyms\"; then\n\t    $opt_dry_run || {\n\t      eval '$EGREP -v \" ($exclude_expsyms)$\" \"$nlist\" > \"$nlist\"T'\n\t      eval '$MV \"$nlist\"T \"$nlist\"'\n\t    }\n\t  fi\n\n\t  if test -n \"$export_symbols_regex\"; then\n\t    $opt_dry_run || {\n\t      eval '$EGREP -e \"$export_symbols_regex\" \"$nlist\" > \"$nlist\"T'\n\t      eval '$MV \"$nlist\"T \"$nlist\"'\n\t    }\n\t  fi\n\n\t  # Prepare the list of exported symbols\n\t  if test -z \"$export_symbols\"; then\n\t    export_symbols=\"$output_objdir/$outputname.exp\"\n\t    $opt_dry_run || {\n\t      $RM $export_symbols\n\t      eval \"${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \\(.*\\)$/\\1/p' \"'< \"$nlist\" > \"$export_symbols\"'\n\t      case $host in\n\t      *cygwin* | *mingw* | *cegcc* )\n                eval \"echo EXPORTS \"'> \"$output_objdir/$outputname.def\"'\n                eval 'cat \"$export_symbols\" >> \"$output_objdir/$outputname.def\"'\n\t        ;;\n\t      esac\n\t    }\n\t  else\n\t    $opt_dry_run || {\n\t      eval \"${SED} -e 's/\\([].[*^$]\\)/\\\\\\\\\\1/g' -e 's/^/ /' -e 's/$/$/'\"' < \"$export_symbols\" > \"$output_objdir/$outputname.exp\"'\n\t      eval '$GREP -f \"$output_objdir/$outputname.exp\" < \"$nlist\" > \"$nlist\"T'\n\t      eval '$MV \"$nlist\"T \"$nlist\"'\n\t      case $host in\n\t        *cygwin | *mingw* | *cegcc* )\n\t          eval \"echo EXPORTS \"'> \"$output_objdir/$outputname.def\"'\n\t          eval 'cat \"$nlist\" >> \"$output_objdir/$outputname.def\"'\n\t          ;;\n\t      esac\n\t    }\n\t  fi\n\tfi\n\n\tfor dlprefile in $dlprefiles; do\n\t  func_verbose \"extracting global C symbols from \\`$dlprefile'\"\n\t  func_basename \"$dlprefile\"\n\t  name=\"$func_basename_result\"\n\t  $opt_dry_run || {\n\t    eval '$ECHO \": $name \" >> \"$nlist\"'\n\t    eval \"$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'\"\n\t  }\n\tdone\n\n\t$opt_dry_run || {\n\t  # Make sure we have at least an empty file.\n\t  test -f \"$nlist\" || : > \"$nlist\"\n\n\t  if test -n \"$exclude_expsyms\"; then\n\t    $EGREP -v \" ($exclude_expsyms)$\" \"$nlist\" > \"$nlist\"T\n\t    $MV \"$nlist\"T \"$nlist\"\n\t  fi\n\n\t  # Try sorting and uniquifying the output.\n\t  if $GREP -v \"^: \" < \"$nlist\" |\n\t      if sort -k 3 </dev/null >/dev/null 2>&1; then\n\t\tsort -k 3\n\t      else\n\t\tsort +2\n\t      fi |\n\t      uniq > \"$nlist\"S; then\n\t    :\n\t  else\n\t    $GREP -v \"^: \" < \"$nlist\" > \"$nlist\"S\n\t  fi\n\n\t  if test -f \"$nlist\"S; then\n\t    eval \"$global_symbol_to_cdecl\"' < \"$nlist\"S >> \"$output_objdir/$my_dlsyms\"'\n\t  else\n\t    $ECHO '/* NONE */' >> \"$output_objdir/$my_dlsyms\"\n\t  fi\n\n\t  $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\n\n/* The mapping between symbol names and symbols.  */\ntypedef struct {\n  const char *name;\n  void *address;\n} lt_dlsymlist;\n\"\n\t  case $host in\n\t  *cygwin* | *mingw* | *cegcc* )\n\t    $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\n/* DATA imports from DLLs on WIN32 con't be const, because\n   runtime relocations are performed -- see ld's documentation\n   on pseudo-relocs.  */\"\n\t    lt_dlsym_const= ;;\n\t  *osf5*)\n\t    echo >> \"$output_objdir/$my_dlsyms\" \"\\\n/* This system does not cope well with relocations in const data */\"\n\t    lt_dlsym_const= ;;\n\t  *)\n\t    lt_dlsym_const=const ;;\n\t  esac\n\n\t  $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\nextern $lt_dlsym_const lt_dlsymlist\nlt_${my_prefix}_LTX_preloaded_symbols[];\n$lt_dlsym_const lt_dlsymlist\nlt_${my_prefix}_LTX_preloaded_symbols[] =\n{\\\n  { \\\"$my_originator\\\", (void *) 0 },\"\n\n\t  case $need_lib_prefix in\n\t  no)\n\t    eval \"$global_symbol_to_c_name_address\" < \"$nlist\" >> \"$output_objdir/$my_dlsyms\"\n\t    ;;\n\t  *)\n\t    eval \"$global_symbol_to_c_name_address_lib_prefix\" < \"$nlist\" >> \"$output_objdir/$my_dlsyms\"\n\t    ;;\n\t  esac\n\t  $ECHO >> \"$output_objdir/$my_dlsyms\" \"\\\n  {0, (void *) 0}\n};\n\n/* This works around a problem in FreeBSD linker */\n#ifdef FREEBSD_WORKAROUND\nstatic const void *lt_preloaded_setup() {\n  return lt_${my_prefix}_LTX_preloaded_symbols;\n}\n#endif\n\n#ifdef __cplusplus\n}\n#endif\\\n\"\n\t} # !$opt_dry_run\n\n\tpic_flag_for_symtable=\n\tcase \"$compile_command \" in\n\t*\" -static \"*) ;;\n\t*)\n\t  case $host in\n\t  # compiling the symbol table file with pic_flag works around\n\t  # a FreeBSD bug that causes programs to crash when -lm is\n\t  # linked before any other PIC object.  But we must not use\n\t  # pic_flag when linking with -static.  The problem exists in\n\t  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.\n\t  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)\n\t    pic_flag_for_symtable=\" $pic_flag -DFREEBSD_WORKAROUND\" ;;\n\t  *-*-hpux*)\n\t    pic_flag_for_symtable=\" $pic_flag\"  ;;\n\t  *)\n\t    if test \"X$my_pic_p\" != Xno; then\n\t      pic_flag_for_symtable=\" $pic_flag\"\n\t    fi\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n\tsymtab_cflags=\n\tfor arg in $LTCFLAGS; do\n\t  case $arg in\n\t  -pie | -fpie | -fPIE) ;;\n\t  *) symtab_cflags=\"$symtab_cflags $arg\" ;;\n\t  esac\n\tdone\n\n\t# Now compile the dynamic symbol file.\n\tfunc_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable \"$my_dlsyms\")' 'exit $?'\n\n\t# Clean up the generated files.\n\tfunc_show_eval '$RM \"$output_objdir/$my_dlsyms\" \"$nlist\" \"${nlist}S\" \"${nlist}T\"'\n\n\t# Transform the symbol file into the correct name.\n\tsymfileobj=\"$output_objdir/${my_outputname}S.$objext\"\n\tcase $host in\n\t*cygwin* | *mingw* | *cegcc* )\n\t  if test -f \"$output_objdir/$my_outputname.def\"; then\n\t    compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%\"`\n\t    finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%\"`\n\t  else\n\t    compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t    finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t  fi\n\t  ;;\n\t*)\n\t  compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t  finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s%@SYMFILE@%$symfileobj%\"`\n\t  ;;\n\tesac\n\t;;\n      *)\n\tfunc_fatal_error \"unknown suffix for \\`$my_dlsyms'\"\n\t;;\n      esac\n    else\n      # We keep going just in case the user didn't refer to\n      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe\n      # really was required.\n\n      # Nullify the symbol file.\n      compile_command=`$ECHO \"X$compile_command\" | $Xsed -e \"s% @SYMFILE@%%\"`\n      finalize_command=`$ECHO \"X$finalize_command\" | $Xsed -e \"s% @SYMFILE@%%\"`\n    fi\n}\n\n# func_win32_libid arg\n# return the library type of file 'arg'\n#\n# Need a lot of goo to handle *both* DLLs and import libs\n# Has to be a shell function in order to 'eat' the argument\n# that is supplied when $file_magic_command is called.\nfunc_win32_libid ()\n{\n  $opt_debug\n  win32_libid_type=\"unknown\"\n  win32_fileres=`file -L $1 2>/dev/null`\n  case $win32_fileres in\n  *ar\\ archive\\ import\\ library*) # definitely import\n    win32_libid_type=\"x86 archive import\"\n    ;;\n  *ar\\ archive*) # could be an import, or static\n    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |\n       $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then\n      win32_nmres=`eval $NM -f posix -A $1 |\n\t$SED -n -e '\n\t    1,100{\n\t\t/ I /{\n\t\t    s,.*,import,\n\t\t    p\n\t\t    q\n\t\t}\n\t    }'`\n      case $win32_nmres in\n      import*)  win32_libid_type=\"x86 archive import\";;\n      *)        win32_libid_type=\"x86 archive static\";;\n      esac\n    fi\n    ;;\n  *DLL*)\n    win32_libid_type=\"x86 DLL\"\n    ;;\n  *executable*) # but shell scripts are \"executable\" too...\n    case $win32_fileres in\n    *MS\\ Windows\\ PE\\ Intel*)\n      win32_libid_type=\"x86 DLL\"\n      ;;\n    esac\n    ;;\n  esac\n  $ECHO \"$win32_libid_type\"\n}\n\n\n\n# func_extract_an_archive dir oldlib\nfunc_extract_an_archive ()\n{\n    $opt_debug\n    f_ex_an_ar_dir=\"$1\"; shift\n    f_ex_an_ar_oldlib=\"$1\"\n    func_show_eval \"(cd \\$f_ex_an_ar_dir && $AR x \\\"\\$f_ex_an_ar_oldlib\\\")\" 'exit $?'\n    if ($AR t \"$f_ex_an_ar_oldlib\" | sort | sort -uc >/dev/null 2>&1); then\n     :\n    else\n      func_fatal_error \"object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib\"\n    fi\n}\n\n\n# func_extract_archives gentop oldlib ...\nfunc_extract_archives ()\n{\n    $opt_debug\n    my_gentop=\"$1\"; shift\n    my_oldlibs=${1+\"$@\"}\n    my_oldobjs=\"\"\n    my_xlib=\"\"\n    my_xabs=\"\"\n    my_xdir=\"\"\n\n    for my_xlib in $my_oldlibs; do\n      # Extract the objects.\n      case $my_xlib in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) my_xabs=\"$my_xlib\" ;;\n\t*) my_xabs=`pwd`\"/$my_xlib\" ;;\n      esac\n      func_basename \"$my_xlib\"\n      my_xlib=\"$func_basename_result\"\n      my_xlib_u=$my_xlib\n      while :; do\n        case \" $extracted_archives \" in\n\t*\" $my_xlib_u \"*)\n\t  func_arith $extracted_serial + 1\n\t  extracted_serial=$func_arith_result\n\t  my_xlib_u=lt$extracted_serial-$my_xlib ;;\n\t*) break ;;\n\tesac\n      done\n      extracted_archives=\"$extracted_archives $my_xlib_u\"\n      my_xdir=\"$my_gentop/$my_xlib_u\"\n\n      func_mkdir_p \"$my_xdir\"\n\n      case $host in\n      *-darwin*)\n\tfunc_verbose \"Extracting $my_xabs\"\n\t# Do not bother doing anything if just a dry run\n\t$opt_dry_run || {\n\t  darwin_orig_dir=`pwd`\n\t  cd $my_xdir || exit $?\n\t  darwin_archive=$my_xabs\n\t  darwin_curdir=`pwd`\n\t  darwin_base_archive=`basename \"$darwin_archive\"`\n\t  darwin_arches=`$LIPO -info \"$darwin_archive\" 2>/dev/null | $GREP Architectures 2>/dev/null || true`\n\t  if test -n \"$darwin_arches\"; then\n\t    darwin_arches=`$ECHO \"$darwin_arches\" | $SED -e 's/.*are://'`\n\t    darwin_arch=\n\t    func_verbose \"$darwin_base_archive has multiple architectures $darwin_arches\"\n\t    for darwin_arch in  $darwin_arches ; do\n\t      func_mkdir_p \"unfat-$$/${darwin_base_archive}-${darwin_arch}\"\n\t      $LIPO -thin $darwin_arch -output \"unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}\" \"${darwin_archive}\"\n\t      cd \"unfat-$$/${darwin_base_archive}-${darwin_arch}\"\n\t      func_extract_an_archive \"`pwd`\" \"${darwin_base_archive}\"\n\t      cd \"$darwin_curdir\"\n\t      $RM \"unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}\"\n\t    done # $darwin_arches\n            ## Okay now we've a bunch of thin objects, gotta fatten them up :)\n\t    darwin_filelist=`find unfat-$$ -type f -name \\*.o -print -o -name \\*.lo -print | $SED -e \"$basename\" | sort -u`\n\t    darwin_file=\n\t    darwin_files=\n\t    for darwin_file in $darwin_filelist; do\n\t      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`\n\t      $LIPO -create -output \"$darwin_file\" $darwin_files\n\t    done # $darwin_filelist\n\t    $RM -rf unfat-$$\n\t    cd \"$darwin_orig_dir\"\n\t  else\n\t    cd $darwin_orig_dir\n\t    func_extract_an_archive \"$my_xdir\" \"$my_xabs\"\n\t  fi # $darwin_arches\n\t} # !$opt_dry_run\n\t;;\n      *)\n        func_extract_an_archive \"$my_xdir\" \"$my_xabs\"\n\t;;\n      esac\n      my_oldobjs=\"$my_oldobjs \"`find $my_xdir -name \\*.$objext -print -o -name \\*.lo -print | $NL2SP`\n    done\n\n    func_extract_archives_result=\"$my_oldobjs\"\n}\n\n\n\n# func_emit_wrapper_part1 [arg=no]\n#\n# Emit the first part of a libtool wrapper script on stdout.\n# For more information, see the description associated with\n# func_emit_wrapper(), below.\nfunc_emit_wrapper_part1 ()\n{\n\tfunc_emit_wrapper_part1_arg1=no\n\tif test -n \"$1\" ; then\n\t  func_emit_wrapper_part1_arg1=$1\n\tfi\n\n\t$ECHO \"\\\n#! $SHELL\n\n# $output - temporary wrapper script for $objdir/$outputname\n# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n#\n# The $output program cannot be directly executed until all the libtool\n# libraries that it depends on are installed.\n#\n# This wrapper script should never be moved out of the build directory.\n# If it is, it will not operate correctly.\n\n# Sed substitution that helps us do robust quoting.  It backslashifies\n# metacharacters that are still active within double-quoted strings.\nXsed='${SED} -e 1s/^X//'\nsed_quote_subst='$sed_quote_subst'\n\n# Be Bourne compatible\nif test -n \\\"\\${ZSH_VERSION+set}\\\" && (emulate sh) >/dev/null 2>&1; then\n  emulate sh\n  NULLCMD=:\n  # Zsh 3.x and 4.x performs word splitting on \\${1+\\\"\\$@\\\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '\\${1+\\\"\\$@\\\"}'='\\\"\\$@\\\"'\n  setopt NO_GLOB_SUBST\nelse\n  case \\`(set -o) 2>/dev/null\\` in *posix*) set -o posix;; esac\nfi\nBIN_SH=xpg4; export BIN_SH # for Tru64\nDUALCASE=1; export DUALCASE # for MKS sh\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nrelink_command=\\\"$relink_command\\\"\n\n# This environment variable determines our operation mode.\nif test \\\"\\$libtool_install_magic\\\" = \\\"$magic\\\"; then\n  # install mode needs the following variables:\n  generated_by_libtool_version='$macro_version'\n  notinst_deplibs='$notinst_deplibs'\nelse\n  # When we are sourced in execute mode, \\$file and \\$ECHO are already set.\n  if test \\\"\\$libtool_execute_magic\\\" != \\\"$magic\\\"; then\n    ECHO=\\\"$qecho\\\"\n    file=\\\"\\$0\\\"\n    # Make sure echo works.\n    if test \\\"X\\$1\\\" = X--no-reexec; then\n      # Discard the --no-reexec flag, and continue.\n      shift\n    elif test \\\"X\\`{ \\$ECHO '\\t'; } 2>/dev/null\\`\\\" = 'X\\t'; then\n      # Yippee, \\$ECHO works!\n      :\n    else\n      # Restart under the correct shell, and then maybe \\$ECHO will work.\n      exec $SHELL \\\"\\$0\\\" --no-reexec \\${1+\\\"\\$@\\\"}\n    fi\n  fi\\\n\"\n\t$ECHO \"\\\n\n  # Find the directory that this script lives in.\n  thisdir=\\`\\$ECHO \\\"X\\$file\\\" | \\$Xsed -e 's%/[^/]*$%%'\\`\n  test \\\"x\\$thisdir\\\" = \\\"x\\$file\\\" && thisdir=.\n\n  # Follow symbolic links until we get to the real thisdir.\n  file=\\`ls -ld \\\"\\$file\\\" | ${SED} -n 's/.*-> //p'\\`\n  while test -n \\\"\\$file\\\"; do\n    destdir=\\`\\$ECHO \\\"X\\$file\\\" | \\$Xsed -e 's%/[^/]*\\$%%'\\`\n\n    # If there was a directory component, then change thisdir.\n    if test \\\"x\\$destdir\\\" != \\\"x\\$file\\\"; then\n      case \\\"\\$destdir\\\" in\n      [\\\\\\\\/]* | [A-Za-z]:[\\\\\\\\/]*) thisdir=\\\"\\$destdir\\\" ;;\n      *) thisdir=\\\"\\$thisdir/\\$destdir\\\" ;;\n      esac\n    fi\n\n    file=\\`\\$ECHO \\\"X\\$file\\\" | \\$Xsed -e 's%^.*/%%'\\`\n    file=\\`ls -ld \\\"\\$thisdir/\\$file\\\" | ${SED} -n 's/.*-> //p'\\`\n  done\n\"\n}\n# end: func_emit_wrapper_part1\n\n# func_emit_wrapper_part2 [arg=no]\n#\n# Emit the second part of a libtool wrapper script on stdout.\n# For more information, see the description associated with\n# func_emit_wrapper(), below.\nfunc_emit_wrapper_part2 ()\n{\n\tfunc_emit_wrapper_part2_arg1=no\n\tif test -n \"$1\" ; then\n\t  func_emit_wrapper_part2_arg1=$1\n\tfi\n\n\t$ECHO \"\\\n\n  # Usually 'no', except on cygwin/mingw when embedded into\n  # the cwrapper.\n  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1\n  if test \\\"\\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\\\" = \\\"yes\\\"; then\n    # special case for '.'\n    if test \\\"\\$thisdir\\\" = \\\".\\\"; then\n      thisdir=\\`pwd\\`\n    fi\n    # remove .libs from thisdir\n    case \\\"\\$thisdir\\\" in\n    *[\\\\\\\\/]$objdir ) thisdir=\\`\\$ECHO \\\"X\\$thisdir\\\" | \\$Xsed -e 's%[\\\\\\\\/][^\\\\\\\\/]*$%%'\\` ;;\n    $objdir )   thisdir=. ;;\n    esac\n  fi\n\n  # Try to get the absolute directory name.\n  absdir=\\`cd \\\"\\$thisdir\\\" && pwd\\`\n  test -n \\\"\\$absdir\\\" && thisdir=\\\"\\$absdir\\\"\n\"\n\n\tif test \"$fast_install\" = yes; then\n\t  $ECHO \"\\\n  program=lt-'$outputname'$exeext\n  progdir=\\\"\\$thisdir/$objdir\\\"\n\n  if test ! -f \\\"\\$progdir/\\$program\\\" ||\n     { file=\\`ls -1dt \\\"\\$progdir/\\$program\\\" \\\"\\$progdir/../\\$program\\\" 2>/dev/null | ${SED} 1q\\`; \\\\\n       test \\\"X\\$file\\\" != \\\"X\\$progdir/\\$program\\\"; }; then\n\n    file=\\\"\\$\\$-\\$program\\\"\n\n    if test ! -d \\\"\\$progdir\\\"; then\n      $MKDIR \\\"\\$progdir\\\"\n    else\n      $RM \\\"\\$progdir/\\$file\\\"\n    fi\"\n\n\t  $ECHO \"\\\n\n    # relink executable if necessary\n    if test -n \\\"\\$relink_command\\\"; then\n      if relink_command_output=\\`eval \\$relink_command 2>&1\\`; then :\n      else\n\t$ECHO \\\"\\$relink_command_output\\\" >&2\n\t$RM \\\"\\$progdir/\\$file\\\"\n\texit 1\n      fi\n    fi\n\n    $MV \\\"\\$progdir/\\$file\\\" \\\"\\$progdir/\\$program\\\" 2>/dev/null ||\n    { $RM \\\"\\$progdir/\\$program\\\";\n      $MV \\\"\\$progdir/\\$file\\\" \\\"\\$progdir/\\$program\\\"; }\n    $RM \\\"\\$progdir/\\$file\\\"\n  fi\"\n\telse\n\t  $ECHO \"\\\n  program='$outputname'\n  progdir=\\\"\\$thisdir/$objdir\\\"\n\"\n\tfi\n\n\t$ECHO \"\\\n\n  if test -f \\\"\\$progdir/\\$program\\\"; then\"\n\n\t# Export our shlibpath_var if we have one.\n\tif test \"$shlibpath_overrides_runpath\" = yes && test -n \"$shlibpath_var\" && test -n \"$temp_rpath\"; then\n\t  $ECHO \"\\\n    # Add our own library path to $shlibpath_var\n    $shlibpath_var=\\\"$temp_rpath\\$$shlibpath_var\\\"\n\n    # Some systems cannot cope with colon-terminated $shlibpath_var\n    # The second colon is a workaround for a bug in BeOS R4 sed\n    $shlibpath_var=\\`\\$ECHO \\\"X\\$$shlibpath_var\\\" | \\$Xsed -e 's/::*\\$//'\\`\n\n    export $shlibpath_var\n\"\n\tfi\n\n\t# fixup the dll searchpath if we need to.\n\tif test -n \"$dllsearchpath\"; then\n\t  $ECHO \"\\\n    # Add the dll search path components to the executable PATH\n    PATH=$dllsearchpath:\\$PATH\n\"\n\tfi\n\n\t$ECHO \"\\\n    if test \\\"\\$libtool_execute_magic\\\" != \\\"$magic\\\"; then\n      # Run the actual program with our arguments.\n\"\n\tcase $host in\n\t# Backslashes separate directories on plain windows\n\t*-*-mingw | *-*-os2* | *-cegcc*)\n\t  $ECHO \"\\\n      exec \\\"\\$progdir\\\\\\\\\\$program\\\" \\${1+\\\"\\$@\\\"}\n\"\n\t  ;;\n\n\t*)\n\t  $ECHO \"\\\n      exec \\\"\\$progdir/\\$program\\\" \\${1+\\\"\\$@\\\"}\n\"\n\t  ;;\n\tesac\n\t$ECHO \"\\\n      \\$ECHO \\\"\\$0: cannot exec \\$program \\$*\\\" 1>&2\n      exit 1\n    fi\n  else\n    # The program doesn't exist.\n    \\$ECHO \\\"\\$0: error: \\\\\\`\\$progdir/\\$program' does not exist\\\" 1>&2\n    \\$ECHO \\\"This script is just a wrapper for \\$program.\\\" 1>&2\n    $ECHO \\\"See the $PACKAGE documentation for more information.\\\" 1>&2\n    exit 1\n  fi\nfi\\\n\"\n}\n# end: func_emit_wrapper_part2\n\n\n# func_emit_wrapper [arg=no]\n#\n# Emit a libtool wrapper script on stdout.\n# Don't directly open a file because we may want to\n# incorporate the script contents within a cygwin/mingw\n# wrapper executable.  Must ONLY be called from within\n# func_mode_link because it depends on a number of variables\n# set therein.\n#\n# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\n# variable will take.  If 'yes', then the emitted script\n# will assume that the directory in which it is stored is\n# the $objdir directory.  This is a cygwin/mingw-specific\n# behavior.\nfunc_emit_wrapper ()\n{\n\tfunc_emit_wrapper_arg1=no\n\tif test -n \"$1\" ; then\n\t  func_emit_wrapper_arg1=$1\n\tfi\n\n\t# split this up so that func_emit_cwrapperexe_src\n\t# can call each part independently.\n\tfunc_emit_wrapper_part1 \"${func_emit_wrapper_arg1}\"\n\tfunc_emit_wrapper_part2 \"${func_emit_wrapper_arg1}\"\n}\n\n\n# func_to_host_path arg\n#\n# Convert paths to host format when used with build tools.\n# Intended for use with \"native\" mingw (where libtool itself\n# is running under the msys shell), or in the following cross-\n# build environments:\n#    $build          $host\n#    mingw (msys)    mingw  [e.g. native]\n#    cygwin          mingw\n#    *nix + wine     mingw\n# where wine is equipped with the `winepath' executable.\n# In the native mingw case, the (msys) shell automatically\n# converts paths for any non-msys applications it launches,\n# but that facility isn't available from inside the cwrapper.\n# Similar accommodations are necessary for $host mingw and\n# $build cygwin.  Calling this function does no harm for other\n# $host/$build combinations not listed above.\n#\n# ARG is the path (on $build) that should be converted to\n# the proper representation for $host. The result is stored\n# in $func_to_host_path_result.\nfunc_to_host_path ()\n{\n  func_to_host_path_result=\"$1\"\n  if test -n \"$1\" ; then\n    case $host in\n      *mingw* )\n        lt_sed_naive_backslashify='s|\\\\\\\\*|\\\\|g;s|/|\\\\|g;s|\\\\|\\\\\\\\|g'\n        case $build in\n          *mingw* ) # actually, msys\n            # awkward: cmd appends spaces to result\n            lt_sed_strip_trailing_spaces=\"s/[ ]*\\$//\"\n            func_to_host_path_tmp1=`( cmd //c echo \"$1\" |\\\n              $SED -e \"$lt_sed_strip_trailing_spaces\" ) 2>/dev/null || echo \"\"`\n            func_to_host_path_result=`echo \"$func_to_host_path_tmp1\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          *cygwin* )\n            func_to_host_path_tmp1=`cygpath -w \"$1\"`\n            func_to_host_path_result=`echo \"$func_to_host_path_tmp1\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          * )\n            # Unfortunately, winepath does not exit with a non-zero\n            # error code, so we are forced to check the contents of\n            # stdout. On the other hand, if the command is not\n            # found, the shell will set an exit code of 127 and print\n            # *an error message* to stdout. So we must check for both\n            # error code of zero AND non-empty stdout, which explains\n            # the odd construction:\n            func_to_host_path_tmp1=`winepath -w \"$1\" 2>/dev/null`\n            if test \"$?\" -eq 0 && test -n \"${func_to_host_path_tmp1}\"; then\n              func_to_host_path_result=`echo \"$func_to_host_path_tmp1\" |\\\n                $SED -e \"$lt_sed_naive_backslashify\"`\n            else\n              # Allow warning below.\n              func_to_host_path_result=\"\"\n            fi\n            ;;\n        esac\n        if test -z \"$func_to_host_path_result\" ; then\n          func_error \"Could not determine host path corresponding to\"\n          func_error \"  '$1'\"\n          func_error \"Continuing, but uninstalled executables may not work.\"\n          # Fallback:\n          func_to_host_path_result=\"$1\"\n        fi\n        ;;\n    esac\n  fi\n}\n# end: func_to_host_path\n\n# func_to_host_pathlist arg\n#\n# Convert pathlists to host format when used with build tools.\n# See func_to_host_path(), above. This function supports the\n# following $build/$host combinations (but does no harm for\n# combinations not listed here):\n#    $build          $host\n#    mingw (msys)    mingw  [e.g. native]\n#    cygwin          mingw\n#    *nix + wine     mingw\n#\n# Path separators are also converted from $build format to\n# $host format. If ARG begins or ends with a path separator\n# character, it is preserved (but converted to $host format)\n# on output.\n#\n# ARG is a pathlist (on $build) that should be converted to\n# the proper representation on $host. The result is stored\n# in $func_to_host_pathlist_result.\nfunc_to_host_pathlist ()\n{\n  func_to_host_pathlist_result=\"$1\"\n  if test -n \"$1\" ; then\n    case $host in\n      *mingw* )\n        lt_sed_naive_backslashify='s|\\\\\\\\*|\\\\|g;s|/|\\\\|g;s|\\\\|\\\\\\\\|g'\n        # Remove leading and trailing path separator characters from\n        # ARG. msys behavior is inconsistent here, cygpath turns them\n        # into '.;' and ';.', and winepath ignores them completely.\n        func_to_host_pathlist_tmp2=\"$1\"\n        # Once set for this call, this variable should not be\n        # reassigned. It is used in tha fallback case.\n        func_to_host_pathlist_tmp1=`echo \"$func_to_host_pathlist_tmp2\" |\\\n          $SED -e 's|^:*||' -e 's|:*$||'`\n        case $build in\n          *mingw* ) # Actually, msys.\n            # Awkward: cmd appends spaces to result.\n            lt_sed_strip_trailing_spaces=\"s/[ ]*\\$//\"\n            func_to_host_pathlist_tmp2=`( cmd //c echo \"$func_to_host_pathlist_tmp1\" |\\\n              $SED -e \"$lt_sed_strip_trailing_spaces\" ) 2>/dev/null || echo \"\"`\n            func_to_host_pathlist_result=`echo \"$func_to_host_pathlist_tmp2\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          *cygwin* )\n            func_to_host_pathlist_tmp2=`cygpath -w -p \"$func_to_host_pathlist_tmp1\"`\n            func_to_host_pathlist_result=`echo \"$func_to_host_pathlist_tmp2\" |\\\n              $SED -e \"$lt_sed_naive_backslashify\"`\n            ;;\n          * )\n            # unfortunately, winepath doesn't convert pathlists\n            func_to_host_pathlist_result=\"\"\n            func_to_host_pathlist_oldIFS=$IFS\n            IFS=:\n            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do\n              IFS=$func_to_host_pathlist_oldIFS\n              if test -n \"$func_to_host_pathlist_f\" ; then\n                func_to_host_path \"$func_to_host_pathlist_f\"\n                if test -n \"$func_to_host_path_result\" ; then\n                  if test -z \"$func_to_host_pathlist_result\" ; then\n                    func_to_host_pathlist_result=\"$func_to_host_path_result\"\n                  else\n                    func_to_host_pathlist_result=\"$func_to_host_pathlist_result;$func_to_host_path_result\"\n                  fi\n                fi\n              fi\n              IFS=:\n            done\n            IFS=$func_to_host_pathlist_oldIFS\n            ;;\n        esac\n        if test -z \"$func_to_host_pathlist_result\" ; then\n          func_error \"Could not determine the host path(s) corresponding to\"\n          func_error \"  '$1'\"\n          func_error \"Continuing, but uninstalled executables may not work.\"\n          # Fallback. This may break if $1 contains DOS-style drive\n          # specifications. The fix is not to complicate the expression\n          # below, but for the user to provide a working wine installation\n          # with winepath so that path translation in the cross-to-mingw\n          # case works properly.\n          lt_replace_pathsep_nix_to_dos=\"s|:|;|g\"\n          func_to_host_pathlist_result=`echo \"$func_to_host_pathlist_tmp1\" |\\\n            $SED -e \"$lt_replace_pathsep_nix_to_dos\"`\n        fi\n        # Now, add the leading and trailing path separators back\n        case \"$1\" in\n          :* ) func_to_host_pathlist_result=\";$func_to_host_pathlist_result\"\n            ;;\n        esac\n        case \"$1\" in\n          *: ) func_to_host_pathlist_result=\"$func_to_host_pathlist_result;\"\n            ;;\n        esac\n        ;;\n    esac\n  fi\n}\n# end: func_to_host_pathlist\n\n# func_emit_cwrapperexe_src\n# emit the source code for a wrapper executable on stdout\n# Must ONLY be called from within func_mode_link because\n# it depends on a number of variable set therein.\nfunc_emit_cwrapperexe_src ()\n{\n\tcat <<EOF\n\n/* $cwrappersource - temporary wrapper executable for $objdir/$outputname\n   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n\n   The $output program cannot be directly executed until all the libtool\n   libraries that it depends on are installed.\n\n   This wrapper executable should never be moved out of the build directory.\n   If it is, it will not operate correctly.\n\n   Currently, it simply execs the wrapper *script* \"$SHELL $output\",\n   but could eventually absorb all of the scripts functionality and\n   exec $objdir/$outputname directly.\n*/\nEOF\n\t    cat <<\"EOF\"\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef _MSC_VER\n# include <direct.h>\n# include <process.h>\n# include <io.h>\n# define setmode _setmode\n#else\n# include <unistd.h>\n# include <stdint.h>\n# ifdef __CYGWIN__\n#  include <io.h>\n#  define HAVE_SETENV\n#  ifdef __STRICT_ANSI__\nchar *realpath (const char *, char *);\nint putenv (char *);\nint setenv (const char *, const char *, int);\n#  endif\n# endif\n#endif\n#include <malloc.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <string.h>\n#include <ctype.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n\n#if defined(PATH_MAX)\n# define LT_PATHMAX PATH_MAX\n#elif defined(MAXPATHLEN)\n# define LT_PATHMAX MAXPATHLEN\n#else\n# define LT_PATHMAX 1024\n#endif\n\n#ifndef S_IXOTH\n# define S_IXOTH 0\n#endif\n#ifndef S_IXGRP\n# define S_IXGRP 0\n#endif\n\n#ifdef _MSC_VER\n# define S_IXUSR _S_IEXEC\n# define stat _stat\n# ifndef _INTPTR_T_DEFINED\n#  define intptr_t int\n# endif\n#endif\n\n#ifndef DIR_SEPARATOR\n# define DIR_SEPARATOR '/'\n# define PATH_SEPARATOR ':'\n#endif\n\n#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \\\n  defined (__OS2__)\n# define HAVE_DOS_BASED_FILE_SYSTEM\n# define FOPEN_WB \"wb\"\n# ifndef DIR_SEPARATOR_2\n#  define DIR_SEPARATOR_2 '\\\\'\n# endif\n# ifndef PATH_SEPARATOR_2\n#  define PATH_SEPARATOR_2 ';'\n# endif\n#endif\n\n#ifndef DIR_SEPARATOR_2\n# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)\n#else /* DIR_SEPARATOR_2 */\n# define IS_DIR_SEPARATOR(ch) \\\n\t(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))\n#endif /* DIR_SEPARATOR_2 */\n\n#ifndef PATH_SEPARATOR_2\n# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)\n#else /* PATH_SEPARATOR_2 */\n# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)\n#endif /* PATH_SEPARATOR_2 */\n\n#ifdef __CYGWIN__\n# define FOPEN_WB \"wb\"\n#endif\n\n#ifndef FOPEN_WB\n# define FOPEN_WB \"w\"\n#endif\n#ifndef _O_BINARY\n# define _O_BINARY 0\n#endif\n\n#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))\n#define XFREE(stale) do { \\\n  if (stale) { free ((void *) stale); stale = 0; } \\\n} while (0)\n\n#undef LTWRAPPER_DEBUGPRINTF\n#if defined DEBUGWRAPPER\n# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args\nstatic void\nltwrapper_debugprintf (const char *fmt, ...)\n{\n    va_list args;\n    va_start (args, fmt);\n    (void) vfprintf (stderr, fmt, args);\n    va_end (args);\n}\n#else\n# define LTWRAPPER_DEBUGPRINTF(args)\n#endif\n\nconst char *program_name = NULL;\n\nvoid *xmalloc (size_t num);\nchar *xstrdup (const char *string);\nconst char *base_name (const char *name);\nchar *find_executable (const char *wrapper);\nchar *chase_symlinks (const char *pathspec);\nint make_executable (const char *path);\nint check_executable (const char *path);\nchar *strendzap (char *str, const char *pat);\nvoid lt_fatal (const char *message, ...);\nvoid lt_setenv (const char *name, const char *value);\nchar *lt_extend_str (const char *orig_value, const char *add, int to_end);\nvoid lt_opt_process_env_set (const char *arg);\nvoid lt_opt_process_env_prepend (const char *arg);\nvoid lt_opt_process_env_append (const char *arg);\nint lt_split_name_value (const char *arg, char** name, char** value);\nvoid lt_update_exe_path (const char *name, const char *value);\nvoid lt_update_lib_path (const char *name, const char *value);\n\nstatic const char *script_text_part1 =\nEOF\n\n\t    func_emit_wrapper_part1 yes |\n\t        $SED -e 's/\\([\\\\\"]\\)/\\\\\\1/g' \\\n\t             -e 's/^/  \"/' -e 's/$/\\\\n\"/'\n\t    echo \";\"\n\t    cat <<EOF\n\nstatic const char *script_text_part2 =\nEOF\n\t    func_emit_wrapper_part2 yes |\n\t        $SED -e 's/\\([\\\\\"]\\)/\\\\\\1/g' \\\n\t             -e 's/^/  \"/' -e 's/$/\\\\n\"/'\n\t    echo \";\"\n\n\t    cat <<EOF\nconst char * MAGIC_EXE = \"$magic_exe\";\nconst char * LIB_PATH_VARNAME = \"$shlibpath_var\";\nEOF\n\n\t    if test \"$shlibpath_overrides_runpath\" = yes && test -n \"$shlibpath_var\" && test -n \"$temp_rpath\"; then\n              func_to_host_pathlist \"$temp_rpath\"\n\t      cat <<EOF\nconst char * LIB_PATH_VALUE   = \"$func_to_host_pathlist_result\";\nEOF\n\t    else\n\t      cat <<\"EOF\"\nconst char * LIB_PATH_VALUE   = \"\";\nEOF\n\t    fi\n\n\t    if test -n \"$dllsearchpath\"; then\n              func_to_host_pathlist \"$dllsearchpath:\"\n\t      cat <<EOF\nconst char * EXE_PATH_VARNAME = \"PATH\";\nconst char * EXE_PATH_VALUE   = \"$func_to_host_pathlist_result\";\nEOF\n\t    else\n\t      cat <<\"EOF\"\nconst char * EXE_PATH_VARNAME = \"\";\nconst char * EXE_PATH_VALUE   = \"\";\nEOF\n\t    fi\n\n\t    if test \"$fast_install\" = yes; then\n\t      cat <<EOF\nconst char * TARGET_PROGRAM_NAME = \"lt-$outputname\"; /* hopefully, no .exe */\nEOF\n\t    else\n\t      cat <<EOF\nconst char * TARGET_PROGRAM_NAME = \"$outputname\"; /* hopefully, no .exe */\nEOF\n\t    fi\n\n\n\t    cat <<\"EOF\"\n\n#define LTWRAPPER_OPTION_PREFIX         \"--lt-\"\n#define LTWRAPPER_OPTION_PREFIX_LENGTH  5\n\nstatic const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;\nstatic const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;\n\nstatic const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX \"dump-script\";\n\nstatic const size_t env_set_opt_len     = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;\nstatic const char *env_set_opt          = LTWRAPPER_OPTION_PREFIX \"env-set\";\n  /* argument is putenv-style \"foo=bar\", value of foo is set to bar */\n\nstatic const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;\nstatic const char *env_prepend_opt      = LTWRAPPER_OPTION_PREFIX \"env-prepend\";\n  /* argument is putenv-style \"foo=bar\", new value of foo is bar${foo} */\n\nstatic const size_t env_append_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;\nstatic const char *env_append_opt       = LTWRAPPER_OPTION_PREFIX \"env-append\";\n  /* argument is putenv-style \"foo=bar\", new value of foo is ${foo}bar */\n\nint\nmain (int argc, char *argv[])\n{\n  char **newargz;\n  int  newargc;\n  char *tmp_pathspec;\n  char *actual_cwrapper_path;\n  char *actual_cwrapper_name;\n  char *target_name;\n  char *lt_argv_zero;\n  intptr_t rval = 127;\n\n  int i;\n\n  program_name = (char *) xstrdup (base_name (argv[0]));\n  LTWRAPPER_DEBUGPRINTF ((\"(main) argv[0]      : %s\\n\", argv[0]));\n  LTWRAPPER_DEBUGPRINTF ((\"(main) program_name : %s\\n\", program_name));\n\n  /* very simple arg parsing; don't want to rely on getopt */\n  for (i = 1; i < argc; i++)\n    {\n      if (strcmp (argv[i], dumpscript_opt) == 0)\n\t{\nEOF\n\t    case \"$host\" in\n\t      *mingw* | *cygwin* )\n\t\t# make stdout use \"unix\" line endings\n\t\techo \"          setmode(1,_O_BINARY);\"\n\t\t;;\n\t      esac\n\n\t    cat <<\"EOF\"\n\t  printf (\"%s\", script_text_part1);\n\t  printf (\"%s\", script_text_part2);\n\t  return 0;\n\t}\n    }\n\n  newargz = XMALLOC (char *, argc + 1);\n  tmp_pathspec = find_executable (argv[0]);\n  if (tmp_pathspec == NULL)\n    lt_fatal (\"Couldn't find %s\", argv[0]);\n  LTWRAPPER_DEBUGPRINTF ((\"(main) found exe (before symlink chase) at : %s\\n\",\n\t\t\t  tmp_pathspec));\n\n  actual_cwrapper_path = chase_symlinks (tmp_pathspec);\n  LTWRAPPER_DEBUGPRINTF ((\"(main) found exe (after symlink chase) at : %s\\n\",\n\t\t\t  actual_cwrapper_path));\n  XFREE (tmp_pathspec);\n\n  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));\n  strendzap (actual_cwrapper_path, actual_cwrapper_name);\n\n  /* wrapper name transforms */\n  strendzap (actual_cwrapper_name, \".exe\");\n  tmp_pathspec = lt_extend_str (actual_cwrapper_name, \".exe\", 1);\n  XFREE (actual_cwrapper_name);\n  actual_cwrapper_name = tmp_pathspec;\n  tmp_pathspec = 0;\n\n  /* target_name transforms -- use actual target program name; might have lt- prefix */\n  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));\n  strendzap (target_name, \".exe\");\n  tmp_pathspec = lt_extend_str (target_name, \".exe\", 1);\n  XFREE (target_name);\n  target_name = tmp_pathspec;\n  tmp_pathspec = 0;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(main) libtool target name: %s\\n\",\n\t\t\t  target_name));\nEOF\n\n\t    cat <<EOF\n  newargz[0] =\n    XMALLOC (char, (strlen (actual_cwrapper_path) +\n\t\t    strlen (\"$objdir\") + 1 + strlen (actual_cwrapper_name) + 1));\n  strcpy (newargz[0], actual_cwrapper_path);\n  strcat (newargz[0], \"$objdir\");\n  strcat (newargz[0], \"/\");\nEOF\n\n\t    cat <<\"EOF\"\n  /* stop here, and copy so we don't have to do this twice */\n  tmp_pathspec = xstrdup (newargz[0]);\n\n  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */\n  strcat (newargz[0], actual_cwrapper_name);\n\n  /* DO want the lt- prefix here if it exists, so use target_name */\n  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);\n  XFREE (tmp_pathspec);\n  tmp_pathspec = NULL;\nEOF\n\n\t    case $host_os in\n\t      mingw*)\n\t    cat <<\"EOF\"\n  {\n    char* p;\n    while ((p = strchr (newargz[0], '\\\\')) != NULL)\n      {\n\t*p = '/';\n      }\n    while ((p = strchr (lt_argv_zero, '\\\\')) != NULL)\n      {\n\t*p = '/';\n      }\n  }\nEOF\n\t    ;;\n\t    esac\n\n\t    cat <<\"EOF\"\n  XFREE (target_name);\n  XFREE (actual_cwrapper_path);\n  XFREE (actual_cwrapper_name);\n\n  lt_setenv (\"BIN_SH\", \"xpg4\"); /* for Tru64 */\n  lt_setenv (\"DUALCASE\", \"1\");  /* for MSK sh */\n  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);\n  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);\n\n  newargc=0;\n  for (i = 1; i < argc; i++)\n    {\n      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)\n        {\n          if (argv[i][env_set_opt_len] == '=')\n            {\n              const char *p = argv[i] + env_set_opt_len + 1;\n              lt_opt_process_env_set (p);\n            }\n          else if (argv[i][env_set_opt_len] == '\\0' && i + 1 < argc)\n            {\n              lt_opt_process_env_set (argv[++i]); /* don't copy */\n            }\n          else\n            lt_fatal (\"%s missing required argument\", env_set_opt);\n          continue;\n        }\n      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)\n        {\n          if (argv[i][env_prepend_opt_len] == '=')\n            {\n              const char *p = argv[i] + env_prepend_opt_len + 1;\n              lt_opt_process_env_prepend (p);\n            }\n          else if (argv[i][env_prepend_opt_len] == '\\0' && i + 1 < argc)\n            {\n              lt_opt_process_env_prepend (argv[++i]); /* don't copy */\n            }\n          else\n            lt_fatal (\"%s missing required argument\", env_prepend_opt);\n          continue;\n        }\n      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)\n        {\n          if (argv[i][env_append_opt_len] == '=')\n            {\n              const char *p = argv[i] + env_append_opt_len + 1;\n              lt_opt_process_env_append (p);\n            }\n          else if (argv[i][env_append_opt_len] == '\\0' && i + 1 < argc)\n            {\n              lt_opt_process_env_append (argv[++i]); /* don't copy */\n            }\n          else\n            lt_fatal (\"%s missing required argument\", env_append_opt);\n          continue;\n        }\n      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)\n        {\n          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX\n             namespace, but it is not one of the ones we know about and\n             have already dealt with, above (inluding dump-script), then\n             report an error. Otherwise, targets might begin to believe\n             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX\n             namespace. The first time any user complains about this, we'll\n             need to make LTWRAPPER_OPTION_PREFIX a configure-time option\n             or a configure.ac-settable value.\n           */\n          lt_fatal (\"Unrecognized option in %s namespace: '%s'\",\n                    ltwrapper_option_prefix, argv[i]);\n        }\n      /* otherwise ... */\n      newargz[++newargc] = xstrdup (argv[i]);\n    }\n  newargz[++newargc] = NULL;\n\n  LTWRAPPER_DEBUGPRINTF     ((\"(main) lt_argv_zero : %s\\n\", (lt_argv_zero ? lt_argv_zero : \"<NULL>\")));\n  for (i = 0; i < newargc; i++)\n    {\n      LTWRAPPER_DEBUGPRINTF ((\"(main) newargz[%d]   : %s\\n\", i, (newargz[i] ? newargz[i] : \"<NULL>\")));\n    }\n\nEOF\n\n\t    case $host_os in\n\t      mingw*)\n\t\tcat <<\"EOF\"\n  /* execv doesn't actually work on mingw as expected on unix */\n  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);\n  if (rval == -1)\n    {\n      /* failed to start process */\n      LTWRAPPER_DEBUGPRINTF ((\"(main) failed to launch target \\\"%s\\\": errno = %d\\n\", lt_argv_zero, errno));\n      return 127;\n    }\n  return rval;\nEOF\n\t\t;;\n\t      *)\n\t\tcat <<\"EOF\"\n  execv (lt_argv_zero, newargz);\n  return rval; /* =127, but avoids unused variable warning */\nEOF\n\t\t;;\n\t    esac\n\n\t    cat <<\"EOF\"\n}\n\nvoid *\nxmalloc (size_t num)\n{\n  void *p = (void *) malloc (num);\n  if (!p)\n    lt_fatal (\"Memory exhausted\");\n\n  return p;\n}\n\nchar *\nxstrdup (const char *string)\n{\n  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),\n\t\t\t  string) : NULL;\n}\n\nconst char *\nbase_name (const char *name)\n{\n  const char *base;\n\n#if defined (HAVE_DOS_BASED_FILE_SYSTEM)\n  /* Skip over the disk name in MSDOS pathnames. */\n  if (isalpha ((unsigned char) name[0]) && name[1] == ':')\n    name += 2;\n#endif\n\n  for (base = name; *name; name++)\n    if (IS_DIR_SEPARATOR (*name))\n      base = name + 1;\n  return base;\n}\n\nint\ncheck_executable (const char *path)\n{\n  struct stat st;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(check_executable)  : %s\\n\",\n\t\t\t  path ? (*path ? path : \"EMPTY!\") : \"NULL!\"));\n  if ((!path) || (!*path))\n    return 0;\n\n  if ((stat (path, &st) >= 0)\n      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))\n    return 1;\n  else\n    return 0;\n}\n\nint\nmake_executable (const char *path)\n{\n  int rval = 0;\n  struct stat st;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(make_executable)   : %s\\n\",\n\t\t\t  path ? (*path ? path : \"EMPTY!\") : \"NULL!\"));\n  if ((!path) || (!*path))\n    return 0;\n\n  if (stat (path, &st) >= 0)\n    {\n      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);\n    }\n  return rval;\n}\n\n/* Searches for the full path of the wrapper.  Returns\n   newly allocated full path name if found, NULL otherwise\n   Does not chase symlinks, even on platforms that support them.\n*/\nchar *\nfind_executable (const char *wrapper)\n{\n  int has_slash = 0;\n  const char *p;\n  const char *p_next;\n  /* static buffer for getcwd */\n  char tmp[LT_PATHMAX + 1];\n  int tmp_len;\n  char *concat_name;\n\n  LTWRAPPER_DEBUGPRINTF ((\"(find_executable)   : %s\\n\",\n\t\t\t  wrapper ? (*wrapper ? wrapper : \"EMPTY!\") : \"NULL!\"));\n\n  if ((wrapper == NULL) || (*wrapper == '\\0'))\n    return NULL;\n\n  /* Absolute path? */\n#if defined (HAVE_DOS_BASED_FILE_SYSTEM)\n  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')\n    {\n      concat_name = xstrdup (wrapper);\n      if (check_executable (concat_name))\n\treturn concat_name;\n      XFREE (concat_name);\n    }\n  else\n    {\n#endif\n      if (IS_DIR_SEPARATOR (wrapper[0]))\n\t{\n\t  concat_name = xstrdup (wrapper);\n\t  if (check_executable (concat_name))\n\t    return concat_name;\n\t  XFREE (concat_name);\n\t}\n#if defined (HAVE_DOS_BASED_FILE_SYSTEM)\n    }\n#endif\n\n  for (p = wrapper; *p; p++)\n    if (*p == '/')\n      {\n\thas_slash = 1;\n\tbreak;\n      }\n  if (!has_slash)\n    {\n      /* no slashes; search PATH */\n      const char *path = getenv (\"PATH\");\n      if (path != NULL)\n\t{\n\t  for (p = path; *p; p = p_next)\n\t    {\n\t      const char *q;\n\t      size_t p_len;\n\t      for (q = p; *q; q++)\n\t\tif (IS_PATH_SEPARATOR (*q))\n\t\t  break;\n\t      p_len = q - p;\n\t      p_next = (*q == '\\0' ? q : q + 1);\n\t      if (p_len == 0)\n\t\t{\n\t\t  /* empty path: current directory */\n\t\t  if (getcwd (tmp, LT_PATHMAX) == NULL)\n\t\t    lt_fatal (\"getcwd failed\");\n\t\t  tmp_len = strlen (tmp);\n\t\t  concat_name =\n\t\t    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);\n\t\t  memcpy (concat_name, tmp, tmp_len);\n\t\t  concat_name[tmp_len] = '/';\n\t\t  strcpy (concat_name + tmp_len + 1, wrapper);\n\t\t}\n\t      else\n\t\t{\n\t\t  concat_name =\n\t\t    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);\n\t\t  memcpy (concat_name, p, p_len);\n\t\t  concat_name[p_len] = '/';\n\t\t  strcpy (concat_name + p_len + 1, wrapper);\n\t\t}\n\t      if (check_executable (concat_name))\n\t\treturn concat_name;\n\t      XFREE (concat_name);\n\t    }\n\t}\n      /* not found in PATH; assume curdir */\n    }\n  /* Relative path | not found in path: prepend cwd */\n  if (getcwd (tmp, LT_PATHMAX) == NULL)\n    lt_fatal (\"getcwd failed\");\n  tmp_len = strlen (tmp);\n  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);\n  memcpy (concat_name, tmp, tmp_len);\n  concat_name[tmp_len] = '/';\n  strcpy (concat_name + tmp_len + 1, wrapper);\n\n  if (check_executable (concat_name))\n    return concat_name;\n  XFREE (concat_name);\n  return NULL;\n}\n\nchar *\nchase_symlinks (const char *pathspec)\n{\n#ifndef S_ISLNK\n  return xstrdup (pathspec);\n#else\n  char buf[LT_PATHMAX];\n  struct stat s;\n  char *tmp_pathspec = xstrdup (pathspec);\n  char *p;\n  int has_symlinks = 0;\n  while (strlen (tmp_pathspec) && !has_symlinks)\n    {\n      LTWRAPPER_DEBUGPRINTF ((\"checking path component for symlinks: %s\\n\",\n\t\t\t      tmp_pathspec));\n      if (lstat (tmp_pathspec, &s) == 0)\n\t{\n\t  if (S_ISLNK (s.st_mode) != 0)\n\t    {\n\t      has_symlinks = 1;\n\t      break;\n\t    }\n\n\t  /* search backwards for last DIR_SEPARATOR */\n\t  p = tmp_pathspec + strlen (tmp_pathspec) - 1;\n\t  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))\n\t    p--;\n\t  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))\n\t    {\n\t      /* no more DIR_SEPARATORS left */\n\t      break;\n\t    }\n\t  *p = '\\0';\n\t}\n      else\n\t{\n\t  char *errstr = strerror (errno);\n\t  lt_fatal (\"Error accessing file %s (%s)\", tmp_pathspec, errstr);\n\t}\n    }\n  XFREE (tmp_pathspec);\n\n  if (!has_symlinks)\n    {\n      return xstrdup (pathspec);\n    }\n\n  tmp_pathspec = realpath (pathspec, buf);\n  if (tmp_pathspec == 0)\n    {\n      lt_fatal (\"Could not follow symlinks for %s\", pathspec);\n    }\n  return xstrdup (tmp_pathspec);\n#endif\n}\n\nchar *\nstrendzap (char *str, const char *pat)\n{\n  size_t len, patlen;\n\n  assert (str != NULL);\n  assert (pat != NULL);\n\n  len = strlen (str);\n  patlen = strlen (pat);\n\n  if (patlen <= len)\n    {\n      str += len - patlen;\n      if (strcmp (str, pat) == 0)\n\t*str = '\\0';\n    }\n  return str;\n}\n\nstatic void\nlt_error_core (int exit_status, const char *mode,\n\t       const char *message, va_list ap)\n{\n  fprintf (stderr, \"%s: %s: \", program_name, mode);\n  vfprintf (stderr, message, ap);\n  fprintf (stderr, \".\\n\");\n\n  if (exit_status >= 0)\n    exit (exit_status);\n}\n\nvoid\nlt_fatal (const char *message, ...)\n{\n  va_list ap;\n  va_start (ap, message);\n  lt_error_core (EXIT_FAILURE, \"FATAL\", message, ap);\n  va_end (ap);\n}\n\nvoid\nlt_setenv (const char *name, const char *value)\n{\n  LTWRAPPER_DEBUGPRINTF ((\"(lt_setenv) setting '%s' to '%s'\\n\",\n                          (name ? name : \"<NULL>\"),\n                          (value ? value : \"<NULL>\")));\n  {\n#ifdef HAVE_SETENV\n    /* always make a copy, for consistency with !HAVE_SETENV */\n    char *str = xstrdup (value);\n    setenv (name, str, 1);\n#else\n    int len = strlen (name) + 1 + strlen (value) + 1;\n    char *str = XMALLOC (char, len);\n    sprintf (str, \"%s=%s\", name, value);\n    if (putenv (str) != EXIT_SUCCESS)\n      {\n        XFREE (str);\n      }\n#endif\n  }\n}\n\nchar *\nlt_extend_str (const char *orig_value, const char *add, int to_end)\n{\n  char *new_value;\n  if (orig_value && *orig_value)\n    {\n      int orig_value_len = strlen (orig_value);\n      int add_len = strlen (add);\n      new_value = XMALLOC (char, add_len + orig_value_len + 1);\n      if (to_end)\n        {\n          strcpy (new_value, orig_value);\n          strcpy (new_value + orig_value_len, add);\n        }\n      else\n        {\n          strcpy (new_value, add);\n          strcpy (new_value + add_len, orig_value);\n        }\n    }\n  else\n    {\n      new_value = xstrdup (add);\n    }\n  return new_value;\n}\n\nint\nlt_split_name_value (const char *arg, char** name, char** value)\n{\n  const char *p;\n  int len;\n  if (!arg || !*arg)\n    return 1;\n\n  p = strchr (arg, (int)'=');\n\n  if (!p)\n    return 1;\n\n  *value = xstrdup (++p);\n\n  len = strlen (arg) - strlen (*value);\n  *name = XMALLOC (char, len);\n  strncpy (*name, arg, len-1);\n  (*name)[len - 1] = '\\0';\n\n  return 0;\n}\n\nvoid\nlt_opt_process_env_set (const char *arg)\n{\n  char *name = NULL;\n  char *value = NULL;\n\n  if (lt_split_name_value (arg, &name, &value) != 0)\n    {\n      XFREE (name);\n      XFREE (value);\n      lt_fatal (\"bad argument for %s: '%s'\", env_set_opt, arg);\n    }\n\n  lt_setenv (name, value);\n  XFREE (name);\n  XFREE (value);\n}\n\nvoid\nlt_opt_process_env_prepend (const char *arg)\n{\n  char *name = NULL;\n  char *value = NULL;\n  char *new_value = NULL;\n\n  if (lt_split_name_value (arg, &name, &value) != 0)\n    {\n      XFREE (name);\n      XFREE (value);\n      lt_fatal (\"bad argument for %s: '%s'\", env_prepend_opt, arg);\n    }\n\n  new_value = lt_extend_str (getenv (name), value, 0);\n  lt_setenv (name, new_value);\n  XFREE (new_value);\n  XFREE (name);\n  XFREE (value);\n}\n\nvoid\nlt_opt_process_env_append (const char *arg)\n{\n  char *name = NULL;\n  char *value = NULL;\n  char *new_value = NULL;\n\n  if (lt_split_name_value (arg, &name, &value) != 0)\n    {\n      XFREE (name);\n      XFREE (value);\n      lt_fatal (\"bad argument for %s: '%s'\", env_append_opt, arg);\n    }\n\n  new_value = lt_extend_str (getenv (name), value, 1);\n  lt_setenv (name, new_value);\n  XFREE (new_value);\n  XFREE (name);\n  XFREE (value);\n}\n\nvoid\nlt_update_exe_path (const char *name, const char *value)\n{\n  LTWRAPPER_DEBUGPRINTF ((\"(lt_update_exe_path) modifying '%s' by prepending '%s'\\n\",\n                          (name ? name : \"<NULL>\"),\n                          (value ? value : \"<NULL>\")));\n\n  if (name && *name && value && *value)\n    {\n      char *new_value = lt_extend_str (getenv (name), value, 0);\n      /* some systems can't cope with a ':'-terminated path #' */\n      int len = strlen (new_value);\n      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))\n        {\n          new_value[len-1] = '\\0';\n        }\n      lt_setenv (name, new_value);\n      XFREE (new_value);\n    }\n}\n\nvoid\nlt_update_lib_path (const char *name, const char *value)\n{\n  LTWRAPPER_DEBUGPRINTF ((\"(lt_update_lib_path) modifying '%s' by prepending '%s'\\n\",\n                          (name ? name : \"<NULL>\"),\n                          (value ? value : \"<NULL>\")));\n\n  if (name && *name && value && *value)\n    {\n      char *new_value = lt_extend_str (getenv (name), value, 0);\n      lt_setenv (name, new_value);\n      XFREE (new_value);\n    }\n}\n\n\nEOF\n}\n# end: func_emit_cwrapperexe_src\n\n# func_mode_link arg...\nfunc_mode_link ()\n{\n    $opt_debug\n    case $host in\n    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n      # It is impossible to link a dll without this setting, and\n      # we shouldn't force the makefile maintainer to figure out\n      # which system we are compiling for in order to pass an extra\n      # flag for every libtool invocation.\n      # allow_undefined=no\n\n      # FIXME: Unfortunately, there are problems with the above when trying\n      # to make a dll which has undefined symbols, in which case not\n      # even a static library is built.  For now, we need to specify\n      # -no-undefined on the libtool link line when we can be certain\n      # that all symbols are satisfied, otherwise we get a static library.\n      allow_undefined=yes\n      ;;\n    *)\n      allow_undefined=yes\n      ;;\n    esac\n    libtool_args=$nonopt\n    base_compile=\"$nonopt $@\"\n    compile_command=$nonopt\n    finalize_command=$nonopt\n\n    compile_rpath=\n    finalize_rpath=\n    compile_shlibpath=\n    finalize_shlibpath=\n    convenience=\n    old_convenience=\n    deplibs=\n    old_deplibs=\n    compiler_flags=\n    linker_flags=\n    dllsearchpath=\n    lib_search_path=`pwd`\n    inst_prefix_dir=\n    new_inherited_linker_flags=\n\n    avoid_version=no\n    dlfiles=\n    dlprefiles=\n    dlself=no\n    export_dynamic=no\n    export_symbols=\n    export_symbols_regex=\n    generated=\n    libobjs=\n    ltlibs=\n    module=no\n    no_install=no\n    objs=\n    non_pic_objects=\n    precious_files_regex=\n    prefer_static_libs=no\n    preload=no\n    prev=\n    prevarg=\n    release=\n    rpath=\n    xrpath=\n    perm_rpath=\n    temp_rpath=\n    thread_safe=no\n    vinfo=\n    vinfo_number=no\n    weak_libs=\n    single_module=\"${wl}-single_module\"\n    func_infer_tag $base_compile\n\n    # We need to know -static, to get the right output filenames.\n    for arg\n    do\n      case $arg in\n      -shared)\n\ttest \"$build_libtool_libs\" != yes && \\\n\t  func_fatal_configuration \"can not build a shared library\"\n\tbuild_old_libs=no\n\tbreak\n\t;;\n      -all-static | -static | -static-libtool-libs)\n\tcase $arg in\n\t-all-static)\n\t  if test \"$build_libtool_libs\" = yes && test -z \"$link_static_flag\"; then\n\t    func_warning \"complete static linking is impossible in this configuration\"\n\t  fi\n\t  if test -n \"$link_static_flag\"; then\n\t    dlopen_self=$dlopen_self_static\n\t  fi\n\t  prefer_static_libs=yes\n\t  ;;\n\t-static)\n\t  if test -z \"$pic_flag\" && test -n \"$link_static_flag\"; then\n\t    dlopen_self=$dlopen_self_static\n\t  fi\n\t  prefer_static_libs=built\n\t  ;;\n\t-static-libtool-libs)\n\t  if test -z \"$pic_flag\" && test -n \"$link_static_flag\"; then\n\t    dlopen_self=$dlopen_self_static\n\t  fi\n\t  prefer_static_libs=yes\n\t  ;;\n\tesac\n\tbuild_libtool_libs=no\n\tbuild_old_libs=yes\n\tbreak\n\t;;\n      esac\n    done\n\n    # See if our shared archives depend on static archives.\n    test -n \"$old_archive_from_new_cmds\" && build_old_libs=yes\n\n    # Go through the arguments, transforming them on the way.\n    while test \"$#\" -gt 0; do\n      arg=\"$1\"\n      shift\n      func_quote_for_eval \"$arg\"\n      qarg=$func_quote_for_eval_unquoted_result\n      func_append libtool_args \" $func_quote_for_eval_result\"\n\n      # If the previous option needs an argument, assign it.\n      if test -n \"$prev\"; then\n\tcase $prev in\n\toutput)\n\t  func_append compile_command \" @OUTPUT@\"\n\t  func_append finalize_command \" @OUTPUT@\"\n\t  ;;\n\tesac\n\n\tcase $prev in\n\tdlfiles|dlprefiles)\n\t  if test \"$preload\" = no; then\n\t    # Add the symbol object into the linking commands.\n\t    func_append compile_command \" @SYMFILE@\"\n\t    func_append finalize_command \" @SYMFILE@\"\n\t    preload=yes\n\t  fi\n\t  case $arg in\n\t  *.la | *.lo) ;;  # We handle these cases below.\n\t  force)\n\t    if test \"$dlself\" = no; then\n\t      dlself=needless\n\t      export_dynamic=yes\n\t    fi\n\t    prev=\n\t    continue\n\t    ;;\n\t  self)\n\t    if test \"$prev\" = dlprefiles; then\n\t      dlself=yes\n\t    elif test \"$prev\" = dlfiles && test \"$dlopen_self\" != yes; then\n\t      dlself=yes\n\t    else\n\t      dlself=needless\n\t      export_dynamic=yes\n\t    fi\n\t    prev=\n\t    continue\n\t    ;;\n\t  *)\n\t    if test \"$prev\" = dlfiles; then\n\t      dlfiles=\"$dlfiles $arg\"\n\t    else\n\t      dlprefiles=\"$dlprefiles $arg\"\n\t    fi\n\t    prev=\n\t    continue\n\t    ;;\n\t  esac\n\t  ;;\n\texpsyms)\n\t  export_symbols=\"$arg\"\n\t  test -f \"$arg\" \\\n\t    || func_fatal_error \"symbol file \\`$arg' does not exist\"\n\t  prev=\n\t  continue\n\t  ;;\n\texpsyms_regex)\n\t  export_symbols_regex=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\tframework)\n\t  case $host in\n\t    *-*-darwin*)\n\t      case \"$deplibs \" in\n\t\t*\" $qarg.ltframework \"*) ;;\n\t\t*) deplibs=\"$deplibs $qarg.ltframework\" # this is fixed later\n\t\t   ;;\n\t      esac\n\t      ;;\n\t  esac\n\t  prev=\n\t  continue\n\t  ;;\n\tinst_prefix)\n\t  inst_prefix_dir=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\tobjectlist)\n\t  if test -f \"$arg\"; then\n\t    save_arg=$arg\n\t    moreargs=\n\t    for fil in `cat \"$save_arg\"`\n\t    do\n#\t      moreargs=\"$moreargs $fil\"\n\t      arg=$fil\n\t      # A libtool-controlled object.\n\n\t      # Check to see that this really is a libtool object.\n\t      if func_lalib_unsafe_p \"$arg\"; then\n\t\tpic_object=\n\t\tnon_pic_object=\n\n\t\t# Read the .lo file\n\t\tfunc_source \"$arg\"\n\n\t\tif test -z \"$pic_object\" ||\n\t\t   test -z \"$non_pic_object\" ||\n\t\t   test \"$pic_object\" = none &&\n\t\t   test \"$non_pic_object\" = none; then\n\t\t  func_fatal_error \"cannot find name of object for \\`$arg'\"\n\t\tfi\n\n\t\t# Extract subdirectory from the argument.\n\t\tfunc_dirname \"$arg\" \"/\" \"\"\n\t\txdir=\"$func_dirname_result\"\n\n\t\tif test \"$pic_object\" != none; then\n\t\t  # Prepend the subdirectory the object is found in.\n\t\t  pic_object=\"$xdir$pic_object\"\n\n\t\t  if test \"$prev\" = dlfiles; then\n\t\t    if test \"$build_libtool_libs\" = yes && test \"$dlopen_support\" = yes; then\n\t\t      dlfiles=\"$dlfiles $pic_object\"\n\t\t      prev=\n\t\t      continue\n\t\t    else\n\t\t      # If libtool objects are unsupported, then we need to preload.\n\t\t      prev=dlprefiles\n\t\t    fi\n\t\t  fi\n\n\t\t  # CHECK ME:  I think I busted this.  -Ossama\n\t\t  if test \"$prev\" = dlprefiles; then\n\t\t    # Preload the old-style object.\n\t\t    dlprefiles=\"$dlprefiles $pic_object\"\n\t\t    prev=\n\t\t  fi\n\n\t\t  # A PIC object.\n\t\t  func_append libobjs \" $pic_object\"\n\t\t  arg=\"$pic_object\"\n\t\tfi\n\n\t\t# Non-PIC object.\n\t\tif test \"$non_pic_object\" != none; then\n\t\t  # Prepend the subdirectory the object is found in.\n\t\t  non_pic_object=\"$xdir$non_pic_object\"\n\n\t\t  # A standard non-PIC object\n\t\t  func_append non_pic_objects \" $non_pic_object\"\n\t\t  if test -z \"$pic_object\" || test \"$pic_object\" = none ; then\n\t\t    arg=\"$non_pic_object\"\n\t\t  fi\n\t\telse\n\t\t  # If the PIC object exists, use it instead.\n\t\t  # $xdir was prepended to $pic_object above.\n\t\t  non_pic_object=\"$pic_object\"\n\t\t  func_append non_pic_objects \" $non_pic_object\"\n\t\tfi\n\t      else\n\t\t# Only an error if not doing a dry-run.\n\t\tif $opt_dry_run; then\n\t\t  # Extract subdirectory from the argument.\n\t\t  func_dirname \"$arg\" \"/\" \"\"\n\t\t  xdir=\"$func_dirname_result\"\n\n\t\t  func_lo2o \"$arg\"\n\t\t  pic_object=$xdir$objdir/$func_lo2o_result\n\t\t  non_pic_object=$xdir$func_lo2o_result\n\t\t  func_append libobjs \" $pic_object\"\n\t\t  func_append non_pic_objects \" $non_pic_object\"\n\t        else\n\t\t  func_fatal_error \"\\`$arg' is not a valid libtool object\"\n\t\tfi\n\t      fi\n\t    done\n\t  else\n\t    func_fatal_error \"link input file \\`$arg' does not exist\"\n\t  fi\n\t  arg=$save_arg\n\t  prev=\n\t  continue\n\t  ;;\n\tprecious_regex)\n\t  precious_files_regex=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\trelease)\n\t  release=\"-$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\trpath | xrpath)\n\t  # We need an absolute path.\n\t  case $arg in\n\t  [\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n\t  *)\n\t    func_fatal_error \"only absolute run-paths are allowed\"\n\t    ;;\n\t  esac\n\t  if test \"$prev\" = rpath; then\n\t    case \"$rpath \" in\n\t    *\" $arg \"*) ;;\n\t    *) rpath=\"$rpath $arg\" ;;\n\t    esac\n\t  else\n\t    case \"$xrpath \" in\n\t    *\" $arg \"*) ;;\n\t    *) xrpath=\"$xrpath $arg\" ;;\n\t    esac\n\t  fi\n\t  prev=\n\t  continue\n\t  ;;\n\tshrext)\n\t  shrext_cmds=\"$arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\tweak)\n\t  weak_libs=\"$weak_libs $arg\"\n\t  prev=\n\t  continue\n\t  ;;\n\txcclinker)\n\t  linker_flags=\"$linker_flags $qarg\"\n\t  compiler_flags=\"$compiler_flags $qarg\"\n\t  prev=\n\t  func_append compile_command \" $qarg\"\n\t  func_append finalize_command \" $qarg\"\n\t  continue\n\t  ;;\n\txcompiler)\n\t  compiler_flags=\"$compiler_flags $qarg\"\n\t  prev=\n\t  func_append compile_command \" $qarg\"\n\t  func_append finalize_command \" $qarg\"\n\t  continue\n\t  ;;\n\txlinker)\n\t  linker_flags=\"$linker_flags $qarg\"\n\t  compiler_flags=\"$compiler_flags $wl$qarg\"\n\t  prev=\n\t  func_append compile_command \" $wl$qarg\"\n\t  func_append finalize_command \" $wl$qarg\"\n\t  continue\n\t  ;;\n\t*)\n\t  eval \"$prev=\\\"\\$arg\\\"\"\n\t  prev=\n\t  continue\n\t  ;;\n\tesac\n      fi # test -n \"$prev\"\n\n      prevarg=\"$arg\"\n\n      case $arg in\n      -all-static)\n\tif test -n \"$link_static_flag\"; then\n\t  # See comment for -static flag below, for more details.\n\t  func_append compile_command \" $link_static_flag\"\n\t  func_append finalize_command \" $link_static_flag\"\n\tfi\n\tcontinue\n\t;;\n\n      -allow-undefined)\n\t# FIXME: remove this flag sometime in the future.\n\tfunc_fatal_error \"\\`-allow-undefined' must not be used because it is the default\"\n\t;;\n\n      -avoid-version)\n\tavoid_version=yes\n\tcontinue\n\t;;\n\n      -dlopen)\n\tprev=dlfiles\n\tcontinue\n\t;;\n\n      -dlpreopen)\n\tprev=dlprefiles\n\tcontinue\n\t;;\n\n      -export-dynamic)\n\texport_dynamic=yes\n\tcontinue\n\t;;\n\n      -export-symbols | -export-symbols-regex)\n\tif test -n \"$export_symbols\" || test -n \"$export_symbols_regex\"; then\n\t  func_fatal_error \"more than one -exported-symbols argument is not allowed\"\n\tfi\n\tif test \"X$arg\" = \"X-export-symbols\"; then\n\t  prev=expsyms\n\telse\n\t  prev=expsyms_regex\n\tfi\n\tcontinue\n\t;;\n\n      -framework)\n\tprev=framework\n\tcontinue\n\t;;\n\n      -inst-prefix-dir)\n\tprev=inst_prefix\n\tcontinue\n\t;;\n\n      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*\n      # so, if we see these flags be careful not to treat them like -L\n      -L[A-Z][A-Z]*:*)\n\tcase $with_gcc/$host in\n\tno/*-*-irix* | /*-*-irix*)\n\t  func_append compile_command \" $arg\"\n\t  func_append finalize_command \" $arg\"\n\t  ;;\n\tesac\n\tcontinue\n\t;;\n\n      -L*)\n\tfunc_stripname '-L' '' \"$arg\"\n\tdir=$func_stripname_result\n\tif test -z \"$dir\"; then\n\t  if test \"$#\" -gt 0; then\n\t    func_fatal_error \"require no space between \\`-L' and \\`$1'\"\n\t  else\n\t    func_fatal_error \"need path for \\`-L' option\"\n\t  fi\n\tfi\n\t# We need an absolute path.\n\tcase $dir in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n\t*)\n\t  absdir=`cd \"$dir\" && pwd`\n\t  test -z \"$absdir\" && \\\n\t    func_fatal_error \"cannot determine absolute directory name of \\`$dir'\"\n\t  dir=\"$absdir\"\n\t  ;;\n\tesac\n\tcase \"$deplibs \" in\n\t*\" -L$dir \"*) ;;\n\t*)\n\t  deplibs=\"$deplibs -L$dir\"\n\t  lib_search_path=\"$lib_search_path $dir\"\n\t  ;;\n\tesac\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n\t  testbindir=`$ECHO \"X$dir\" | $Xsed -e 's*/lib$*/bin*'`\n\t  case :$dllsearchpath: in\n\t  *\":$dir:\"*) ;;\n\t  ::) dllsearchpath=$dir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$dir\";;\n\t  esac\n\t  case :$dllsearchpath: in\n\t  *\":$testbindir:\"*) ;;\n\t  ::) dllsearchpath=$testbindir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$testbindir\";;\n\t  esac\n\t  ;;\n\tesac\n\tcontinue\n\t;;\n\n      -l*)\n\tif test \"X$arg\" = \"X-lc\" || test \"X$arg\" = \"X-lm\"; then\n\t  case $host in\n\t  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)\n\t    # These systems don't actually have a C or math library (as such)\n\t    continue\n\t    ;;\n\t  *-*-os2*)\n\t    # These systems don't actually have a C library (as such)\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)\n\t    # Do not include libc due to us having libc/libc_r.\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  *-*-rhapsody* | *-*-darwin1.[012])\n\t    # Rhapsody C and math libraries are in the System framework\n\t    deplibs=\"$deplibs System.ltframework\"\n\t    continue\n\t    ;;\n\t  *-*-sco3.2v5* | *-*-sco5v6*)\n\t    # Causes problems with __ctype\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)\n\t    # Compiler inserts libc in the correct place for threads to work\n\t    test \"X$arg\" = \"X-lc\" && continue\n\t    ;;\n\t  esac\n\telif test \"X$arg\" = \"X-lc_r\"; then\n\t case $host in\n\t *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)\n\t   # Do not include libc_r directly, use -pthread flag.\n\t   continue\n\t   ;;\n\t esac\n\tfi\n\tdeplibs=\"$deplibs $arg\"\n\tcontinue\n\t;;\n\n      -module)\n\tmodule=yes\n\tcontinue\n\t;;\n\n      # Tru64 UNIX uses -model [arg] to determine the layout of C++\n      # classes, name mangling, and exception handling.\n      # Darwin uses the -arch flag to determine output architecture.\n      -model|-arch|-isysroot)\n\tcompiler_flags=\"$compiler_flags $arg\"\n\tfunc_append compile_command \" $arg\"\n\tfunc_append finalize_command \" $arg\"\n\tprev=xcompiler\n\tcontinue\n\t;;\n\n      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)\n\tcompiler_flags=\"$compiler_flags $arg\"\n\tfunc_append compile_command \" $arg\"\n\tfunc_append finalize_command \" $arg\"\n\tcase \"$new_inherited_linker_flags \" in\n\t    *\" $arg \"*) ;;\n\t    * ) new_inherited_linker_flags=\"$new_inherited_linker_flags $arg\" ;;\n\tesac\n\tcontinue\n\t;;\n\n      -multi_module)\n\tsingle_module=\"${wl}-multi_module\"\n\tcontinue\n\t;;\n\n      -no-fast-install)\n\tfast_install=no\n\tcontinue\n\t;;\n\n      -no-install)\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)\n\t  # The PATH hackery in wrapper scripts is required on Windows\n\t  # and Darwin in order for the loader to find any dlls it needs.\n\t  func_warning \"\\`-no-install' is ignored for $host\"\n\t  func_warning \"assuming \\`-no-fast-install' instead\"\n\t  fast_install=no\n\t  ;;\n\t*) no_install=yes ;;\n\tesac\n\tcontinue\n\t;;\n\n      -no-undefined)\n\tallow_undefined=no\n\tcontinue\n\t;;\n\n      -objectlist)\n\tprev=objectlist\n\tcontinue\n\t;;\n\n      -o) prev=output ;;\n\n      -precious-files-regex)\n\tprev=precious_regex\n\tcontinue\n\t;;\n\n      -release)\n\tprev=release\n\tcontinue\n\t;;\n\n      -rpath)\n\tprev=rpath\n\tcontinue\n\t;;\n\n      -R)\n\tprev=xrpath\n\tcontinue\n\t;;\n\n      -R*)\n\tfunc_stripname '-R' '' \"$arg\"\n\tdir=$func_stripname_result\n\t# We need an absolute path.\n\tcase $dir in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) ;;\n\t*)\n\t  func_fatal_error \"only absolute run-paths are allowed\"\n\t  ;;\n\tesac\n\tcase \"$xrpath \" in\n\t*\" $dir \"*) ;;\n\t*) xrpath=\"$xrpath $dir\" ;;\n\tesac\n\tcontinue\n\t;;\n\n      -shared)\n\t# The effects of -shared are defined in a previous loop.\n\tcontinue\n\t;;\n\n      -shrext)\n\tprev=shrext\n\tcontinue\n\t;;\n\n      -static | -static-libtool-libs)\n\t# The effects of -static are defined in a previous loop.\n\t# We used to do the same as -all-static on platforms that\n\t# didn't have a PIC flag, but the assumption that the effects\n\t# would be equivalent was wrong.  It would break on at least\n\t# Digital Unix and AIX.\n\tcontinue\n\t;;\n\n      -thread-safe)\n\tthread_safe=yes\n\tcontinue\n\t;;\n\n      -version-info)\n\tprev=vinfo\n\tcontinue\n\t;;\n\n      -version-number)\n\tprev=vinfo\n\tvinfo_number=yes\n\tcontinue\n\t;;\n\n      -weak)\n        prev=weak\n\tcontinue\n\t;;\n\n      -Wc,*)\n\tfunc_stripname '-Wc,' '' \"$arg\"\n\targs=$func_stripname_result\n\targ=\n\tsave_ifs=\"$IFS\"; IFS=','\n\tfor flag in $args; do\n\t  IFS=\"$save_ifs\"\n          func_quote_for_eval \"$flag\"\n\t  arg=\"$arg $wl$func_quote_for_eval_result\"\n\t  compiler_flags=\"$compiler_flags $func_quote_for_eval_result\"\n\tdone\n\tIFS=\"$save_ifs\"\n\tfunc_stripname ' ' '' \"$arg\"\n\targ=$func_stripname_result\n\t;;\n\n      -Wl,*)\n\tfunc_stripname '-Wl,' '' \"$arg\"\n\targs=$func_stripname_result\n\targ=\n\tsave_ifs=\"$IFS\"; IFS=','\n\tfor flag in $args; do\n\t  IFS=\"$save_ifs\"\n          func_quote_for_eval \"$flag\"\n\t  arg=\"$arg $wl$func_quote_for_eval_result\"\n\t  compiler_flags=\"$compiler_flags $wl$func_quote_for_eval_result\"\n\t  linker_flags=\"$linker_flags $func_quote_for_eval_result\"\n\tdone\n\tIFS=\"$save_ifs\"\n\tfunc_stripname ' ' '' \"$arg\"\n\targ=$func_stripname_result\n\t;;\n\n      -Xcompiler)\n\tprev=xcompiler\n\tcontinue\n\t;;\n\n      -Xlinker)\n\tprev=xlinker\n\tcontinue\n\t;;\n\n      -XCClinker)\n\tprev=xcclinker\n\tcontinue\n\t;;\n\n      # -msg_* for osf cc\n      -msg_*)\n\tfunc_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n\t;;\n\n      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler\n      # -r[0-9][0-9]* specifies the processor on the SGI compiler\n      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler\n      # +DA*, +DD* enable 64-bit mode on the HP compiler\n      # -q* pass through compiler args for the IBM compiler\n      # -m*, -t[45]*, -txscale* pass through architecture-specific\n      # compiler args for GCC\n      # -F/path gives path to uninstalled frameworks, gcc on darwin\n      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC\n      # @file GCC response files\n      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \\\n      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)\n        func_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n        func_append compile_command \" $arg\"\n        func_append finalize_command \" $arg\"\n        compiler_flags=\"$compiler_flags $arg\"\n        continue\n        ;;\n\n      # Some other compiler flag.\n      -* | +*)\n        func_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n\t;;\n\n      *.$objext)\n\t# A standard object.\n\tobjs=\"$objs $arg\"\n\t;;\n\n      *.lo)\n\t# A libtool-controlled object.\n\n\t# Check to see that this really is a libtool object.\n\tif func_lalib_unsafe_p \"$arg\"; then\n\t  pic_object=\n\t  non_pic_object=\n\n\t  # Read the .lo file\n\t  func_source \"$arg\"\n\n\t  if test -z \"$pic_object\" ||\n\t     test -z \"$non_pic_object\" ||\n\t     test \"$pic_object\" = none &&\n\t     test \"$non_pic_object\" = none; then\n\t    func_fatal_error \"cannot find name of object for \\`$arg'\"\n\t  fi\n\n\t  # Extract subdirectory from the argument.\n\t  func_dirname \"$arg\" \"/\" \"\"\n\t  xdir=\"$func_dirname_result\"\n\n\t  if test \"$pic_object\" != none; then\n\t    # Prepend the subdirectory the object is found in.\n\t    pic_object=\"$xdir$pic_object\"\n\n\t    if test \"$prev\" = dlfiles; then\n\t      if test \"$build_libtool_libs\" = yes && test \"$dlopen_support\" = yes; then\n\t\tdlfiles=\"$dlfiles $pic_object\"\n\t\tprev=\n\t\tcontinue\n\t      else\n\t\t# If libtool objects are unsupported, then we need to preload.\n\t\tprev=dlprefiles\n\t      fi\n\t    fi\n\n\t    # CHECK ME:  I think I busted this.  -Ossama\n\t    if test \"$prev\" = dlprefiles; then\n\t      # Preload the old-style object.\n\t      dlprefiles=\"$dlprefiles $pic_object\"\n\t      prev=\n\t    fi\n\n\t    # A PIC object.\n\t    func_append libobjs \" $pic_object\"\n\t    arg=\"$pic_object\"\n\t  fi\n\n\t  # Non-PIC object.\n\t  if test \"$non_pic_object\" != none; then\n\t    # Prepend the subdirectory the object is found in.\n\t    non_pic_object=\"$xdir$non_pic_object\"\n\n\t    # A standard non-PIC object\n\t    func_append non_pic_objects \" $non_pic_object\"\n\t    if test -z \"$pic_object\" || test \"$pic_object\" = none ; then\n\t      arg=\"$non_pic_object\"\n\t    fi\n\t  else\n\t    # If the PIC object exists, use it instead.\n\t    # $xdir was prepended to $pic_object above.\n\t    non_pic_object=\"$pic_object\"\n\t    func_append non_pic_objects \" $non_pic_object\"\n\t  fi\n\telse\n\t  # Only an error if not doing a dry-run.\n\t  if $opt_dry_run; then\n\t    # Extract subdirectory from the argument.\n\t    func_dirname \"$arg\" \"/\" \"\"\n\t    xdir=\"$func_dirname_result\"\n\n\t    func_lo2o \"$arg\"\n\t    pic_object=$xdir$objdir/$func_lo2o_result\n\t    non_pic_object=$xdir$func_lo2o_result\n\t    func_append libobjs \" $pic_object\"\n\t    func_append non_pic_objects \" $non_pic_object\"\n\t  else\n\t    func_fatal_error \"\\`$arg' is not a valid libtool object\"\n\t  fi\n\tfi\n\t;;\n\n      *.$libext)\n\t# An archive.\n\tdeplibs=\"$deplibs $arg\"\n\told_deplibs=\"$old_deplibs $arg\"\n\tcontinue\n\t;;\n\n      *.la)\n\t# A libtool-controlled library.\n\n\tif test \"$prev\" = dlfiles; then\n\t  # This library was specified with -dlopen.\n\t  dlfiles=\"$dlfiles $arg\"\n\t  prev=\n\telif test \"$prev\" = dlprefiles; then\n\t  # The library was specified with -dlpreopen.\n\t  dlprefiles=\"$dlprefiles $arg\"\n\t  prev=\n\telse\n\t  deplibs=\"$deplibs $arg\"\n\tfi\n\tcontinue\n\t;;\n\n      # Some other compiler argument.\n      *)\n\t# Unknown arguments in both finalize_command and compile_command need\n\t# to be aesthetically quoted because they are evaled later.\n\tfunc_quote_for_eval \"$arg\"\n\targ=\"$func_quote_for_eval_result\"\n\t;;\n      esac # arg\n\n      # Now actually substitute the argument into the commands.\n      if test -n \"$arg\"; then\n\tfunc_append compile_command \" $arg\"\n\tfunc_append finalize_command \" $arg\"\n      fi\n    done # argument parsing loop\n\n    test -n \"$prev\" && \\\n      func_fatal_help \"the \\`$prevarg' option requires an argument\"\n\n    if test \"$export_dynamic\" = yes && test -n \"$export_dynamic_flag_spec\"; then\n      eval arg=\\\"$export_dynamic_flag_spec\\\"\n      func_append compile_command \" $arg\"\n      func_append finalize_command \" $arg\"\n    fi\n\n    oldlibs=\n    # calculate the name of the file, without its directory\n    func_basename \"$output\"\n    outputname=\"$func_basename_result\"\n    libobjs_save=\"$libobjs\"\n\n    if test -n \"$shlibpath_var\"; then\n      # get the directories listed in $shlibpath_var\n      eval shlib_search_path=\\`\\$ECHO \\\"X\\${$shlibpath_var}\\\" \\| \\$Xsed -e \\'s/:/ /g\\'\\`\n    else\n      shlib_search_path=\n    fi\n    eval sys_lib_search_path=\\\"$sys_lib_search_path_spec\\\"\n    eval sys_lib_dlsearch_path=\\\"$sys_lib_dlsearch_path_spec\\\"\n\n    func_dirname \"$output\" \"/\" \"\"\n    output_objdir=\"$func_dirname_result$objdir\"\n    # Create the object directory.\n    func_mkdir_p \"$output_objdir\"\n\n    # Determine the type of output\n    case $output in\n    \"\")\n      func_fatal_help \"you must specify an output file\"\n      ;;\n    *.$libext) linkmode=oldlib ;;\n    *.lo | *.$objext) linkmode=obj ;;\n    *.la) linkmode=lib ;;\n    *) linkmode=prog ;; # Anything else should be a program.\n    esac\n\n    specialdeplibs=\n\n    libs=\n    # Find all interdependent deplibs by searching for libraries\n    # that are linked more than once (e.g. -la -lb -la)\n    for deplib in $deplibs; do\n      if $opt_duplicate_deps ; then\n\tcase \"$libs \" in\n\t*\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\tesac\n      fi\n      libs=\"$libs $deplib\"\n    done\n\n    if test \"$linkmode\" = lib; then\n      libs=\"$predeps $libs $compiler_lib_search_path $postdeps\"\n\n      # Compute libraries that are listed more than once in $predeps\n      # $postdeps and mark them as special (i.e., whose duplicates are\n      # not to be eliminated).\n      pre_post_deps=\n      if $opt_duplicate_compiler_generated_deps; then\n\tfor pre_post_dep in $predeps $postdeps; do\n\t  case \"$pre_post_deps \" in\n\t  *\" $pre_post_dep \"*) specialdeplibs=\"$specialdeplibs $pre_post_deps\" ;;\n\t  esac\n\t  pre_post_deps=\"$pre_post_deps $pre_post_dep\"\n\tdone\n      fi\n      pre_post_deps=\n    fi\n\n    deplibs=\n    newdependency_libs=\n    newlib_search_path=\n    need_relink=no # whether we're linking any uninstalled libtool libraries\n    notinst_deplibs= # not-installed libtool libraries\n    notinst_path= # paths that contain not-installed libtool libraries\n\n    case $linkmode in\n    lib)\n\tpasses=\"conv dlpreopen link\"\n\tfor file in $dlfiles $dlprefiles; do\n\t  case $file in\n\t  *.la) ;;\n\t  *)\n\t    func_fatal_help \"libraries can \\`-dlopen' only libtool libraries: $file\"\n\t    ;;\n\t  esac\n\tdone\n\t;;\n    prog)\n\tcompile_deplibs=\n\tfinalize_deplibs=\n\talldeplibs=no\n\tnewdlfiles=\n\tnewdlprefiles=\n\tpasses=\"conv scan dlopen dlpreopen link\"\n\t;;\n    *)  passes=\"conv\"\n\t;;\n    esac\n\n    for pass in $passes; do\n      # The preopen pass in lib mode reverses $deplibs; put it back here\n      # so that -L comes before libs that need it for instance...\n      if test \"$linkmode,$pass\" = \"lib,link\"; then\n\t## FIXME: Find the place where the list is rebuilt in the wrong\n\t##        order, and fix it there properly\n        tmp_deplibs=\n\tfor deplib in $deplibs; do\n\t  tmp_deplibs=\"$deplib $tmp_deplibs\"\n\tdone\n\tdeplibs=\"$tmp_deplibs\"\n      fi\n\n      if test \"$linkmode,$pass\" = \"lib,link\" ||\n\t test \"$linkmode,$pass\" = \"prog,scan\"; then\n\tlibs=\"$deplibs\"\n\tdeplibs=\n      fi\n      if test \"$linkmode\" = prog; then\n\tcase $pass in\n\tdlopen) libs=\"$dlfiles\" ;;\n\tdlpreopen) libs=\"$dlprefiles\" ;;\n\tlink)\n\t  libs=\"$deplibs %DEPLIBS%\"\n\t  test \"X$link_all_deplibs\" != Xno && libs=\"$libs $dependency_libs\"\n\t  ;;\n\tesac\n      fi\n      if test \"$linkmode,$pass\" = \"lib,dlpreopen\"; then\n\t# Collect and forward deplibs of preopened libtool libs\n\tfor lib in $dlprefiles; do\n\t  # Ignore non-libtool-libs\n\t  dependency_libs=\n\t  case $lib in\n\t  *.la)\tfunc_source \"$lib\" ;;\n\t  esac\n\n\t  # Collect preopened libtool deplibs, except any this library\n\t  # has declared as weak libs\n\t  for deplib in $dependency_libs; do\n            deplib_base=`$ECHO \"X$deplib\" | $Xsed -e \"$basename\"`\n\t    case \" $weak_libs \" in\n\t    *\" $deplib_base \"*) ;;\n\t    *) deplibs=\"$deplibs $deplib\" ;;\n\t    esac\n\t  done\n\tdone\n\tlibs=\"$dlprefiles\"\n      fi\n      if test \"$pass\" = dlopen; then\n\t# Collect dlpreopened libraries\n\tsave_deplibs=\"$deplibs\"\n\tdeplibs=\n      fi\n\n      for deplib in $libs; do\n\tlib=\n\tfound=no\n\tcase $deplib in\n\t-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)\n\t  if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t    compile_deplibs=\"$deplib $compile_deplibs\"\n\t    finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t  else\n\t    compiler_flags=\"$compiler_flags $deplib\"\n\t    if test \"$linkmode\" = lib ; then\n\t\tcase \"$new_inherited_linker_flags \" in\n\t\t    *\" $deplib \"*) ;;\n\t\t    * ) new_inherited_linker_flags=\"$new_inherited_linker_flags $deplib\" ;;\n\t\tesac\n\t    fi\n\t  fi\n\t  continue\n\t  ;;\n\t-l*)\n\t  if test \"$linkmode\" != lib && test \"$linkmode\" != prog; then\n\t    func_warning \"\\`-l' is ignored for archives/objects\"\n\t    continue\n\t  fi\n\t  func_stripname '-l' '' \"$deplib\"\n\t  name=$func_stripname_result\n\t  if test \"$linkmode\" = lib; then\n\t    searchdirs=\"$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path\"\n\t  else\n\t    searchdirs=\"$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path\"\n\t  fi\n\t  for searchdir in $searchdirs; do\n\t    for search_ext in .la $std_shrext .so .a; do\n\t      # Search the libtool library\n\t      lib=\"$searchdir/lib${name}${search_ext}\"\n\t      if test -f \"$lib\"; then\n\t\tif test \"$search_ext\" = \".la\"; then\n\t\t  found=yes\n\t\telse\n\t\t  found=no\n\t\tfi\n\t\tbreak 2\n\t      fi\n\t    done\n\t  done\n\t  if test \"$found\" != yes; then\n\t    # deplib doesn't seem to be a libtool library\n\t    if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    else\n\t      deplibs=\"$deplib $deplibs\"\n\t      test \"$linkmode\" = lib && newdependency_libs=\"$deplib $newdependency_libs\"\n\t    fi\n\t    continue\n\t  else # deplib is a libtool library\n\t    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,\n\t    # We need to do some special things here, and not later.\n\t    if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t      case \" $predeps $postdeps \" in\n\t      *\" $deplib \"*)\n\t\tif func_lalib_p \"$lib\"; then\n\t\t  library_names=\n\t\t  old_library=\n\t\t  func_source \"$lib\"\n\t\t  for l in $old_library $library_names; do\n\t\t    ll=\"$l\"\n\t\t  done\n\t\t  if test \"X$ll\" = \"X$old_library\" ; then # only static version available\n\t\t    found=no\n\t\t    func_dirname \"$lib\" \"\" \".\"\n\t\t    ladir=\"$func_dirname_result\"\n\t\t    lib=$ladir/$old_library\n\t\t    if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t\t    else\n\t\t      deplibs=\"$deplib $deplibs\"\n\t\t      test \"$linkmode\" = lib && newdependency_libs=\"$deplib $newdependency_libs\"\n\t\t    fi\n\t\t    continue\n\t\t  fi\n\t\tfi\n\t\t;;\n\t      *) ;;\n\t      esac\n\t    fi\n\t  fi\n\t  ;; # -l\n\t*.ltframework)\n\t  if test \"$linkmode,$pass\" = \"prog,link\"; then\n\t    compile_deplibs=\"$deplib $compile_deplibs\"\n\t    finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t  else\n\t    deplibs=\"$deplib $deplibs\"\n\t    if test \"$linkmode\" = lib ; then\n\t\tcase \"$new_inherited_linker_flags \" in\n\t\t    *\" $deplib \"*) ;;\n\t\t    * ) new_inherited_linker_flags=\"$new_inherited_linker_flags $deplib\" ;;\n\t\tesac\n\t    fi\n\t  fi\n\t  continue\n\t  ;;\n\t-L*)\n\t  case $linkmode in\n\t  lib)\n\t    deplibs=\"$deplib $deplibs\"\n\t    test \"$pass\" = conv && continue\n\t    newdependency_libs=\"$deplib $newdependency_libs\"\n\t    func_stripname '-L' '' \"$deplib\"\n\t    newlib_search_path=\"$newlib_search_path $func_stripname_result\"\n\t    ;;\n\t  prog)\n\t    if test \"$pass\" = conv; then\n\t      deplibs=\"$deplib $deplibs\"\n\t      continue\n\t    fi\n\t    if test \"$pass\" = scan; then\n\t      deplibs=\"$deplib $deplibs\"\n\t    else\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    fi\n\t    func_stripname '-L' '' \"$deplib\"\n\t    newlib_search_path=\"$newlib_search_path $func_stripname_result\"\n\t    ;;\n\t  *)\n\t    func_warning \"\\`-L' is ignored for archives/objects\"\n\t    ;;\n\t  esac # linkmode\n\t  continue\n\t  ;; # -L\n\t-R*)\n\t  if test \"$pass\" = link; then\n\t    func_stripname '-R' '' \"$deplib\"\n\t    dir=$func_stripname_result\n\t    # Make sure the xrpath contains only unique directories.\n\t    case \"$xrpath \" in\n\t    *\" $dir \"*) ;;\n\t    *) xrpath=\"$xrpath $dir\" ;;\n\t    esac\n\t  fi\n\t  deplibs=\"$deplib $deplibs\"\n\t  continue\n\t  ;;\n\t*.la) lib=\"$deplib\" ;;\n\t*.$libext)\n\t  if test \"$pass\" = conv; then\n\t    deplibs=\"$deplib $deplibs\"\n\t    continue\n\t  fi\n\t  case $linkmode in\n\t  lib)\n\t    # Linking convenience modules into shared libraries is allowed,\n\t    # but linking other static libraries is non-portable.\n\t    case \" $dlpreconveniencelibs \" in\n\t    *\" $deplib \"*) ;;\n\t    *)\n\t      valid_a_lib=no\n\t      case $deplibs_check_method in\n\t\tmatch_pattern*)\n\t\t  set dummy $deplibs_check_method; shift\n\t\t  match_pattern_regex=`expr \"$deplibs_check_method\" : \"$1 \\(.*\\)\"`\n\t\t  if eval \"\\$ECHO \\\"X$deplib\\\"\" 2>/dev/null | $Xsed -e 10q \\\n\t\t    | $EGREP \"$match_pattern_regex\" > /dev/null; then\n\t\t    valid_a_lib=yes\n\t\t  fi\n\t\t;;\n\t\tpass_all)\n\t\t  valid_a_lib=yes\n\t\t;;\n\t      esac\n\t      if test \"$valid_a_lib\" != yes; then\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: Trying to link with static lib archive $deplib.\"\n\t\t$ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t$ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t$ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t$ECHO \"*** because the file extensions .$libext of this argument makes me believe\"\n\t\t$ECHO \"*** that it is just a static archive that I should not use here.\"\n\t      else\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: Linking the shared library $output against the\"\n\t\t$ECHO \"*** static library $deplib is not portable!\"\n\t\tdeplibs=\"$deplib $deplibs\"\n\t      fi\n\t      ;;\n\t    esac\n\t    continue\n\t    ;;\n\t  prog)\n\t    if test \"$pass\" != link; then\n\t      deplibs=\"$deplib $deplibs\"\n\t    else\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    fi\n\t    continue\n\t    ;;\n\t  esac # linkmode\n\t  ;; # *.$libext\n\t*.lo | *.$objext)\n\t  if test \"$pass\" = conv; then\n\t    deplibs=\"$deplib $deplibs\"\n\t  elif test \"$linkmode\" = prog; then\n\t    if test \"$pass\" = dlpreopen || test \"$dlopen_support\" != yes || test \"$build_libtool_libs\" = no; then\n\t      # If there is no dlopen support or we're linking statically,\n\t      # we need to preload.\n\t      newdlprefiles=\"$newdlprefiles $deplib\"\n\t      compile_deplibs=\"$deplib $compile_deplibs\"\n\t      finalize_deplibs=\"$deplib $finalize_deplibs\"\n\t    else\n\t      newdlfiles=\"$newdlfiles $deplib\"\n\t    fi\n\t  fi\n\t  continue\n\t  ;;\n\t%DEPLIBS%)\n\t  alldeplibs=yes\n\t  continue\n\t  ;;\n\tesac # case $deplib\n\n\tif test \"$found\" = yes || test -f \"$lib\"; then :\n\telse\n\t  func_fatal_error \"cannot find the library \\`$lib' or unhandled argument \\`$deplib'\"\n\tfi\n\n\t# Check to see that this really is a libtool archive.\n\tfunc_lalib_unsafe_p \"$lib\" \\\n\t  || func_fatal_error \"\\`$lib' is not a valid libtool archive\"\n\n\tfunc_dirname \"$lib\" \"\" \".\"\n\tladir=\"$func_dirname_result\"\n\n\tdlname=\n\tdlopen=\n\tdlpreopen=\n\tlibdir=\n\tlibrary_names=\n\told_library=\n\tinherited_linker_flags=\n\t# If the library was installed with an old release of libtool,\n\t# it will not redefine variables installed, or shouldnotlink\n\tinstalled=yes\n\tshouldnotlink=no\n\tavoidtemprpath=\n\n\n\t# Read the .la file\n\tfunc_source \"$lib\"\n\n\t# Convert \"-framework foo\" to \"foo.ltframework\"\n\tif test -n \"$inherited_linker_flags\"; then\n\t  tmp_inherited_linker_flags=`$ECHO \"X$inherited_linker_flags\" | $Xsed -e 's/-framework \\([^ $]*\\)/\\1.ltframework/g'`\n\t  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do\n\t    case \" $new_inherited_linker_flags \" in\n\t      *\" $tmp_inherited_linker_flag \"*) ;;\n\t      *) new_inherited_linker_flags=\"$new_inherited_linker_flags $tmp_inherited_linker_flag\";;\n\t    esac\n\t  done\n\tfi\n\tdependency_libs=`$ECHO \"X $dependency_libs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tif test \"$linkmode,$pass\" = \"lib,link\" ||\n\t   test \"$linkmode,$pass\" = \"prog,scan\" ||\n\t   { test \"$linkmode\" != prog && test \"$linkmode\" != lib; }; then\n\t  test -n \"$dlopen\" && dlfiles=\"$dlfiles $dlopen\"\n\t  test -n \"$dlpreopen\" && dlprefiles=\"$dlprefiles $dlpreopen\"\n\tfi\n\n\tif test \"$pass\" = conv; then\n\t  # Only check for convenience libraries\n\t  deplibs=\"$lib $deplibs\"\n\t  if test -z \"$libdir\"; then\n\t    if test -z \"$old_library\"; then\n\t      func_fatal_error \"cannot find name of link library for \\`$lib'\"\n\t    fi\n\t    # It is a libtool convenience library, so add in its objects.\n\t    convenience=\"$convenience $ladir/$objdir/$old_library\"\n\t    old_convenience=\"$old_convenience $ladir/$objdir/$old_library\"\n\t    tmp_libs=\n\t    for deplib in $dependency_libs; do\n\t      deplibs=\"$deplib $deplibs\"\n\t      if $opt_duplicate_deps ; then\n\t\tcase \"$tmp_libs \" in\n\t\t*\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\t\tesac\n\t      fi\n\t      tmp_libs=\"$tmp_libs $deplib\"\n\t    done\n\t  elif test \"$linkmode\" != prog && test \"$linkmode\" != lib; then\n\t    func_fatal_error \"\\`$lib' is not a convenience library\"\n\t  fi\n\t  continue\n\tfi # $pass = conv\n\n\n\t# Get the name of the library we link against.\n\tlinklib=\n\tfor l in $old_library $library_names; do\n\t  linklib=\"$l\"\n\tdone\n\tif test -z \"$linklib\"; then\n\t  func_fatal_error \"cannot find name of link library for \\`$lib'\"\n\tfi\n\n\t# This library was specified with -dlopen.\n\tif test \"$pass\" = dlopen; then\n\t  if test -z \"$libdir\"; then\n\t    func_fatal_error \"cannot -dlopen a convenience library: \\`$lib'\"\n\t  fi\n\t  if test -z \"$dlname\" ||\n\t     test \"$dlopen_support\" != yes ||\n\t     test \"$build_libtool_libs\" = no; then\n\t    # If there is no dlname, no dlopen support or we're linking\n\t    # statically, we need to preload.  We also need to preload any\n\t    # dependent libraries so libltdl's deplib preloader doesn't\n\t    # bomb out in the load deplibs phase.\n\t    dlprefiles=\"$dlprefiles $lib $dependency_libs\"\n\t  else\n\t    newdlfiles=\"$newdlfiles $lib\"\n\t  fi\n\t  continue\n\tfi # $pass = dlopen\n\n\t# We need an absolute path.\n\tcase $ladir in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) abs_ladir=\"$ladir\" ;;\n\t*)\n\t  abs_ladir=`cd \"$ladir\" && pwd`\n\t  if test -z \"$abs_ladir\"; then\n\t    func_warning \"cannot determine absolute directory name of \\`$ladir'\"\n\t    func_warning \"passing it literally to the linker, although it might fail\"\n\t    abs_ladir=\"$ladir\"\n\t  fi\n\t  ;;\n\tesac\n\tfunc_basename \"$lib\"\n\tlaname=\"$func_basename_result\"\n\n\t# Find the relevant object directory and library name.\n\tif test \"X$installed\" = Xyes; then\n\t  if test ! -f \"$libdir/$linklib\" && test -f \"$abs_ladir/$linklib\"; then\n\t    func_warning \"library \\`$lib' was moved.\"\n\t    dir=\"$ladir\"\n\t    absdir=\"$abs_ladir\"\n\t    libdir=\"$abs_ladir\"\n\t  else\n\t    dir=\"$libdir\"\n\t    absdir=\"$libdir\"\n\t  fi\n\t  test \"X$hardcode_automatic\" = Xyes && avoidtemprpath=yes\n\telse\n\t  if test ! -f \"$ladir/$objdir/$linklib\" && test -f \"$abs_ladir/$linklib\"; then\n\t    dir=\"$ladir\"\n\t    absdir=\"$abs_ladir\"\n\t    # Remove this search path later\n\t    notinst_path=\"$notinst_path $abs_ladir\"\n\t  else\n\t    dir=\"$ladir/$objdir\"\n\t    absdir=\"$abs_ladir/$objdir\"\n\t    # Remove this search path later\n\t    notinst_path=\"$notinst_path $abs_ladir\"\n\t  fi\n\tfi # $installed = yes\n\tfunc_stripname 'lib' '.la' \"$laname\"\n\tname=$func_stripname_result\n\n\t# This library was specified with -dlpreopen.\n\tif test \"$pass\" = dlpreopen; then\n\t  if test -z \"$libdir\" && test \"$linkmode\" = prog; then\n\t    func_fatal_error \"only libraries may -dlpreopen a convenience library: \\`$lib'\"\n\t  fi\n\t  # Prefer using a static library (so that no silly _DYNAMIC symbols\n\t  # are required to link).\n\t  if test -n \"$old_library\"; then\n\t    newdlprefiles=\"$newdlprefiles $dir/$old_library\"\n\t    # Keep a list of preopened convenience libraries to check\n\t    # that they are being used correctly in the link pass.\n\t    test -z \"$libdir\" && \\\n\t\tdlpreconveniencelibs=\"$dlpreconveniencelibs $dir/$old_library\"\n\t  # Otherwise, use the dlname, so that lt_dlopen finds it.\n\t  elif test -n \"$dlname\"; then\n\t    newdlprefiles=\"$newdlprefiles $dir/$dlname\"\n\t  else\n\t    newdlprefiles=\"$newdlprefiles $dir/$linklib\"\n\t  fi\n\tfi # $pass = dlpreopen\n\n\tif test -z \"$libdir\"; then\n\t  # Link the convenience library\n\t  if test \"$linkmode\" = lib; then\n\t    deplibs=\"$dir/$old_library $deplibs\"\n\t  elif test \"$linkmode,$pass\" = \"prog,link\"; then\n\t    compile_deplibs=\"$dir/$old_library $compile_deplibs\"\n\t    finalize_deplibs=\"$dir/$old_library $finalize_deplibs\"\n\t  else\n\t    deplibs=\"$lib $deplibs\" # used for prog,scan pass\n\t  fi\n\t  continue\n\tfi\n\n\n\tif test \"$linkmode\" = prog && test \"$pass\" != link; then\n\t  newlib_search_path=\"$newlib_search_path $ladir\"\n\t  deplibs=\"$lib $deplibs\"\n\n\t  linkalldeplibs=no\n\t  if test \"$link_all_deplibs\" != no || test -z \"$library_names\" ||\n\t     test \"$build_libtool_libs\" = no; then\n\t    linkalldeplibs=yes\n\t  fi\n\n\t  tmp_libs=\n\t  for deplib in $dependency_libs; do\n\t    case $deplib in\n\t    -L*) func_stripname '-L' '' \"$deplib\"\n\t         newlib_search_path=\"$newlib_search_path $func_stripname_result\"\n\t\t ;;\n\t    esac\n\t    # Need to link against all dependency_libs?\n\t    if test \"$linkalldeplibs\" = yes; then\n\t      deplibs=\"$deplib $deplibs\"\n\t    else\n\t      # Need to hardcode shared library paths\n\t      # or/and link against static libraries\n\t      newdependency_libs=\"$deplib $newdependency_libs\"\n\t    fi\n\t    if $opt_duplicate_deps ; then\n\t      case \"$tmp_libs \" in\n\t      *\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\t      esac\n\t    fi\n\t    tmp_libs=\"$tmp_libs $deplib\"\n\t  done # for deplib\n\t  continue\n\tfi # $linkmode = prog...\n\n\tif test \"$linkmode,$pass\" = \"prog,link\"; then\n\t  if test -n \"$library_names\" &&\n\t     { { test \"$prefer_static_libs\" = no ||\n\t         test \"$prefer_static_libs,$installed\" = \"built,yes\"; } ||\n\t       test -z \"$old_library\"; }; then\n\t    # We need to hardcode the library path\n\t    if test -n \"$shlibpath_var\" && test -z \"$avoidtemprpath\" ; then\n\t      # Make sure the rpath contains only unique directories.\n\t      case \"$temp_rpath:\" in\n\t      *\"$absdir:\"*) ;;\n\t      *) temp_rpath=\"$temp_rpath$absdir:\" ;;\n\t      esac\n\t    fi\n\n\t    # Hardcode the library path.\n\t    # Skip directories that are in the system default run-time\n\t    # search path.\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $absdir \"*) ;;\n\t    *)\n\t      case \"$compile_rpath \" in\n\t      *\" $absdir \"*) ;;\n\t      *) compile_rpath=\"$compile_rpath $absdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $libdir \"*) ;;\n\t    *)\n\t      case \"$finalize_rpath \" in\n\t      *\" $libdir \"*) ;;\n\t      *) finalize_rpath=\"$finalize_rpath $libdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t  fi # $linkmode,$pass = prog,link...\n\n\t  if test \"$alldeplibs\" = yes &&\n\t     { test \"$deplibs_check_method\" = pass_all ||\n\t       { test \"$build_libtool_libs\" = yes &&\n\t\t test -n \"$library_names\"; }; }; then\n\t    # We only need to search for static libraries\n\t    continue\n\t  fi\n\tfi\n\n\tlink_static=no # Whether the deplib will be linked statically\n\tuse_static_libs=$prefer_static_libs\n\tif test \"$use_static_libs\" = built && test \"$installed\" = yes; then\n\t  use_static_libs=no\n\tfi\n\tif test -n \"$library_names\" &&\n\t   { test \"$use_static_libs\" = no || test -z \"$old_library\"; }; then\n\t  case $host in\n\t  *cygwin* | *mingw* | *cegcc*)\n\t      # No point in relinking DLLs because paths are not encoded\n\t      notinst_deplibs=\"$notinst_deplibs $lib\"\n\t      need_relink=no\n\t    ;;\n\t  *)\n\t    if test \"$installed\" = no; then\n\t      notinst_deplibs=\"$notinst_deplibs $lib\"\n\t      need_relink=yes\n\t    fi\n\t    ;;\n\t  esac\n\t  # This is a shared library\n\n\t  # Warn about portability, can't link against -module's on some\n\t  # systems (darwin).  Don't bleat about dlopened modules though!\n\t  dlopenmodule=\"\"\n\t  for dlpremoduletest in $dlprefiles; do\n\t    if test \"X$dlpremoduletest\" = \"X$lib\"; then\n\t      dlopenmodule=\"$dlpremoduletest\"\n\t      break\n\t    fi\n\t  done\n\t  if test -z \"$dlopenmodule\" && test \"$shouldnotlink\" = yes && test \"$pass\" = link; then\n\t    $ECHO\n\t    if test \"$linkmode\" = prog; then\n\t      $ECHO \"*** Warning: Linking the executable $output against the loadable module\"\n\t    else\n\t      $ECHO \"*** Warning: Linking the shared library $output against the loadable module\"\n\t    fi\n\t    $ECHO \"*** $linklib is not portable!\"\n\t  fi\n\t  if test \"$linkmode\" = lib &&\n\t     test \"$hardcode_into_libs\" = yes; then\n\t    # Hardcode the library path.\n\t    # Skip directories that are in the system default run-time\n\t    # search path.\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $absdir \"*) ;;\n\t    *)\n\t      case \"$compile_rpath \" in\n\t      *\" $absdir \"*) ;;\n\t      *) compile_rpath=\"$compile_rpath $absdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t    case \" $sys_lib_dlsearch_path \" in\n\t    *\" $libdir \"*) ;;\n\t    *)\n\t      case \"$finalize_rpath \" in\n\t      *\" $libdir \"*) ;;\n\t      *) finalize_rpath=\"$finalize_rpath $libdir\"\n\t      esac\n\t      ;;\n\t    esac\n\t  fi\n\n\t  if test -n \"$old_archive_from_expsyms_cmds\"; then\n\t    # figure out the soname\n\t    set dummy $library_names\n\t    shift\n\t    realname=\"$1\"\n\t    shift\n\t    libname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t    # use dlname if we got it. it's perfectly good, no?\n\t    if test -n \"$dlname\"; then\n\t      soname=\"$dlname\"\n\t    elif test -n \"$soname_spec\"; then\n\t      # bleh windows\n\t      case $host in\n\t      *cygwin* | mingw* | *cegcc*)\n\t        func_arith $current - $age\n\t\tmajor=$func_arith_result\n\t\tversuffix=\"-$major\"\n\t\t;;\n\t      esac\n\t      eval soname=\\\"$soname_spec\\\"\n\t    else\n\t      soname=\"$realname\"\n\t    fi\n\n\t    # Make a new name for the extract_expsyms_cmds to use\n\t    soroot=\"$soname\"\n\t    func_basename \"$soroot\"\n\t    soname=\"$func_basename_result\"\n\t    func_stripname 'lib' '.dll' \"$soname\"\n\t    newlib=libimp-$func_stripname_result.a\n\n\t    # If the library has no export list, then create one now\n\t    if test -f \"$output_objdir/$soname-def\"; then :\n\t    else\n\t      func_verbose \"extracting exported symbol list from \\`$soname'\"\n\t      func_execute_cmds \"$extract_expsyms_cmds\" 'exit $?'\n\t    fi\n\n\t    # Create $newlib\n\t    if test -f \"$output_objdir/$newlib\"; then :; else\n\t      func_verbose \"generating import library for \\`$soname'\"\n\t      func_execute_cmds \"$old_archive_from_expsyms_cmds\" 'exit $?'\n\t    fi\n\t    # make sure the library variables are pointing to the new library\n\t    dir=$output_objdir\n\t    linklib=$newlib\n\t  fi # test -n \"$old_archive_from_expsyms_cmds\"\n\n\t  if test \"$linkmode\" = prog || test \"$mode\" != relink; then\n\t    add_shlibpath=\n\t    add_dir=\n\t    add=\n\t    lib_linked=yes\n\t    case $hardcode_action in\n\t    immediate | unsupported)\n\t      if test \"$hardcode_direct\" = no; then\n\t\tadd=\"$dir/$linklib\"\n\t\tcase $host in\n\t\t  *-*-sco3.2v5.0.[024]*) add_dir=\"-L$dir\" ;;\n\t\t  *-*-sysv4*uw2*) add_dir=\"-L$dir\" ;;\n\t\t  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \\\n\t\t    *-*-unixware7*) add_dir=\"-L$dir\" ;;\n\t\t  *-*-darwin* )\n\t\t    # if the lib is a (non-dlopened) module then we can not\n\t\t    # link against it, someone is ignoring the earlier warnings\n\t\t    if /usr/bin/file -L $add 2> /dev/null |\n\t\t\t $GREP \": [^:]* bundle\" >/dev/null ; then\n\t\t      if test \"X$dlopenmodule\" != \"X$lib\"; then\n\t\t\t$ECHO \"*** Warning: lib $linklib is a module, not a shared library\"\n\t\t\tif test -z \"$old_library\" ; then\n\t\t\t  $ECHO\n\t\t\t  $ECHO \"*** And there doesn't seem to be a static archive available\"\n\t\t\t  $ECHO \"*** The link will probably fail, sorry\"\n\t\t\telse\n\t\t\t  add=\"$dir/$old_library\"\n\t\t\tfi\n\t\t      elif test -n \"$old_library\"; then\n\t\t\tadd=\"$dir/$old_library\"\n\t\t      fi\n\t\t    fi\n\t\tesac\n\t      elif test \"$hardcode_minus_L\" = no; then\n\t\tcase $host in\n\t\t*-*-sunos*) add_shlibpath=\"$dir\" ;;\n\t\tesac\n\t\tadd_dir=\"-L$dir\"\n\t\tadd=\"-l$name\"\n\t      elif test \"$hardcode_shlibpath_var\" = no; then\n\t\tadd_shlibpath=\"$dir\"\n\t\tadd=\"-l$name\"\n\t      else\n\t\tlib_linked=no\n\t      fi\n\t      ;;\n\t    relink)\n\t      if test \"$hardcode_direct\" = yes &&\n\t         test \"$hardcode_direct_absolute\" = no; then\n\t\tadd=\"$dir/$linklib\"\n\t      elif test \"$hardcode_minus_L\" = yes; then\n\t\tadd_dir=\"-L$dir\"\n\t\t# Try looking first in the location we're being installed to.\n\t\tif test -n \"$inst_prefix_dir\"; then\n\t\t  case $libdir in\n\t\t    [\\\\/]*)\n\t\t      add_dir=\"$add_dir -L$inst_prefix_dir$libdir\"\n\t\t      ;;\n\t\t  esac\n\t\tfi\n\t\tadd=\"-l$name\"\n\t      elif test \"$hardcode_shlibpath_var\" = yes; then\n\t\tadd_shlibpath=\"$dir\"\n\t\tadd=\"-l$name\"\n\t      else\n\t\tlib_linked=no\n\t      fi\n\t      ;;\n\t    *) lib_linked=no ;;\n\t    esac\n\n\t    if test \"$lib_linked\" != yes; then\n\t      func_fatal_configuration \"unsupported hardcode properties\"\n\t    fi\n\n\t    if test -n \"$add_shlibpath\"; then\n\t      case :$compile_shlibpath: in\n\t      *\":$add_shlibpath:\"*) ;;\n\t      *) compile_shlibpath=\"$compile_shlibpath$add_shlibpath:\" ;;\n\t      esac\n\t    fi\n\t    if test \"$linkmode\" = prog; then\n\t      test -n \"$add_dir\" && compile_deplibs=\"$add_dir $compile_deplibs\"\n\t      test -n \"$add\" && compile_deplibs=\"$add $compile_deplibs\"\n\t    else\n\t      test -n \"$add_dir\" && deplibs=\"$add_dir $deplibs\"\n\t      test -n \"$add\" && deplibs=\"$add $deplibs\"\n\t      if test \"$hardcode_direct\" != yes &&\n\t\t test \"$hardcode_minus_L\" != yes &&\n\t\t test \"$hardcode_shlibpath_var\" = yes; then\n\t\tcase :$finalize_shlibpath: in\n\t\t*\":$libdir:\"*) ;;\n\t\t*) finalize_shlibpath=\"$finalize_shlibpath$libdir:\" ;;\n\t\tesac\n\t      fi\n\t    fi\n\t  fi\n\n\t  if test \"$linkmode\" = prog || test \"$mode\" = relink; then\n\t    add_shlibpath=\n\t    add_dir=\n\t    add=\n\t    # Finalize command for both is simple: just hardcode it.\n\t    if test \"$hardcode_direct\" = yes &&\n\t       test \"$hardcode_direct_absolute\" = no; then\n\t      add=\"$libdir/$linklib\"\n\t    elif test \"$hardcode_minus_L\" = yes; then\n\t      add_dir=\"-L$libdir\"\n\t      add=\"-l$name\"\n\t    elif test \"$hardcode_shlibpath_var\" = yes; then\n\t      case :$finalize_shlibpath: in\n\t      *\":$libdir:\"*) ;;\n\t      *) finalize_shlibpath=\"$finalize_shlibpath$libdir:\" ;;\n\t      esac\n\t      add=\"-l$name\"\n\t    elif test \"$hardcode_automatic\" = yes; then\n\t      if test -n \"$inst_prefix_dir\" &&\n\t\t test -f \"$inst_prefix_dir$libdir/$linklib\" ; then\n\t\tadd=\"$inst_prefix_dir$libdir/$linklib\"\n\t      else\n\t\tadd=\"$libdir/$linklib\"\n\t      fi\n\t    else\n\t      # We cannot seem to hardcode it, guess we'll fake it.\n\t      add_dir=\"-L$libdir\"\n\t      # Try looking first in the location we're being installed to.\n\t      if test -n \"$inst_prefix_dir\"; then\n\t\tcase $libdir in\n\t\t  [\\\\/]*)\n\t\t    add_dir=\"$add_dir -L$inst_prefix_dir$libdir\"\n\t\t    ;;\n\t\tesac\n\t      fi\n\t      add=\"-l$name\"\n\t    fi\n\n\t    if test \"$linkmode\" = prog; then\n\t      test -n \"$add_dir\" && finalize_deplibs=\"$add_dir $finalize_deplibs\"\n\t      test -n \"$add\" && finalize_deplibs=\"$add $finalize_deplibs\"\n\t    else\n\t      test -n \"$add_dir\" && deplibs=\"$add_dir $deplibs\"\n\t      test -n \"$add\" && deplibs=\"$add $deplibs\"\n\t    fi\n\t  fi\n\telif test \"$linkmode\" = prog; then\n\t  # Here we assume that one of hardcode_direct or hardcode_minus_L\n\t  # is not unsupported.  This is valid on all known static and\n\t  # shared platforms.\n\t  if test \"$hardcode_direct\" != unsupported; then\n\t    test -n \"$old_library\" && linklib=\"$old_library\"\n\t    compile_deplibs=\"$dir/$linklib $compile_deplibs\"\n\t    finalize_deplibs=\"$dir/$linklib $finalize_deplibs\"\n\t  else\n\t    compile_deplibs=\"-l$name -L$dir $compile_deplibs\"\n\t    finalize_deplibs=\"-l$name -L$dir $finalize_deplibs\"\n\t  fi\n\telif test \"$build_libtool_libs\" = yes; then\n\t  # Not a shared library\n\t  if test \"$deplibs_check_method\" != pass_all; then\n\t    # We're trying link a shared library against a static one\n\t    # but the system doesn't support it.\n\n\t    # Just print a warning and add the library to dependency_libs so\n\t    # that the program can be linked against the static library.\n\t    $ECHO\n\t    $ECHO \"*** Warning: This system can not link to static lib archive $lib.\"\n\t    $ECHO \"*** I have the capability to make that library automatically link in when\"\n\t    $ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t    $ECHO \"*** shared version of the library, which you do not appear to have.\"\n\t    if test \"$module\" = yes; then\n\t      $ECHO \"*** But as you try to build a module library, libtool will still create \"\n\t      $ECHO \"*** a static module, that should work as long as the dlopening application\"\n\t      $ECHO \"*** is linked with the -dlopen flag to resolve symbols at runtime.\"\n\t      if test -z \"$global_symbol_pipe\"; then\n\t\t$ECHO\n\t\t$ECHO \"*** However, this would only work if libtool was able to extract symbol\"\n\t\t$ECHO \"*** lists from a program, using \\`nm' or equivalent, but libtool could\"\n\t\t$ECHO \"*** not find such a program.  So, this module is probably useless.\"\n\t\t$ECHO \"*** \\`nm' from GNU binutils and a full rebuild may help.\"\n\t      fi\n\t      if test \"$build_old_libs\" = no; then\n\t\tbuild_libtool_libs=module\n\t\tbuild_old_libs=yes\n\t      else\n\t\tbuild_libtool_libs=no\n\t      fi\n\t    fi\n\t  else\n\t    deplibs=\"$dir/$old_library $deplibs\"\n\t    link_static=yes\n\t  fi\n\tfi # link shared/static library?\n\n\tif test \"$linkmode\" = lib; then\n\t  if test -n \"$dependency_libs\" &&\n\t     { test \"$hardcode_into_libs\" != yes ||\n\t       test \"$build_old_libs\" = yes ||\n\t       test \"$link_static\" = yes; }; then\n\t    # Extract -R from dependency_libs\n\t    temp_deplibs=\n\t    for libdir in $dependency_libs; do\n\t      case $libdir in\n\t      -R*) func_stripname '-R' '' \"$libdir\"\n\t           temp_xrpath=$func_stripname_result\n\t\t   case \" $xrpath \" in\n\t\t   *\" $temp_xrpath \"*) ;;\n\t\t   *) xrpath=\"$xrpath $temp_xrpath\";;\n\t\t   esac;;\n\t      *) temp_deplibs=\"$temp_deplibs $libdir\";;\n\t      esac\n\t    done\n\t    dependency_libs=\"$temp_deplibs\"\n\t  fi\n\n\t  newlib_search_path=\"$newlib_search_path $absdir\"\n\t  # Link against this library\n\t  test \"$link_static\" = no && newdependency_libs=\"$abs_ladir/$laname $newdependency_libs\"\n\t  # ... and its dependency_libs\n\t  tmp_libs=\n\t  for deplib in $dependency_libs; do\n\t    newdependency_libs=\"$deplib $newdependency_libs\"\n\t    if $opt_duplicate_deps ; then\n\t      case \"$tmp_libs \" in\n\t      *\" $deplib \"*) specialdeplibs=\"$specialdeplibs $deplib\" ;;\n\t      esac\n\t    fi\n\t    tmp_libs=\"$tmp_libs $deplib\"\n\t  done\n\n\t  if test \"$link_all_deplibs\" != no; then\n\t    # Add the search paths of all dependency libraries\n\t    for deplib in $dependency_libs; do\n\t      path=\n\t      case $deplib in\n\t      -L*) path=\"$deplib\" ;;\n\t      *.la)\n\t        func_dirname \"$deplib\" \"\" \".\"\n\t\tdir=\"$func_dirname_result\"\n\t\t# We need an absolute path.\n\t\tcase $dir in\n\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) absdir=\"$dir\" ;;\n\t\t*)\n\t\t  absdir=`cd \"$dir\" && pwd`\n\t\t  if test -z \"$absdir\"; then\n\t\t    func_warning \"cannot determine absolute directory name of \\`$dir'\"\n\t\t    absdir=\"$dir\"\n\t\t  fi\n\t\t  ;;\n\t\tesac\n\t\tif $GREP \"^installed=no\" $deplib > /dev/null; then\n\t\tcase $host in\n\t\t*-*-darwin*)\n\t\t  depdepl=\n\t\t  eval deplibrary_names=`${SED} -n -e 's/^library_names=\\(.*\\)$/\\1/p' $deplib`\n\t\t  if test -n \"$deplibrary_names\" ; then\n\t\t    for tmp in $deplibrary_names ; do\n\t\t      depdepl=$tmp\n\t\t    done\n\t\t    if test -f \"$absdir/$objdir/$depdepl\" ; then\n\t\t      depdepl=\"$absdir/$objdir/$depdepl\"\n\t\t      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`\n                      if test -z \"$darwin_install_name\"; then\n                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`\n                      fi\n\t\t      compiler_flags=\"$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}\"\n\t\t      linker_flags=\"$linker_flags -dylib_file ${darwin_install_name}:${depdepl}\"\n\t\t      path=\n\t\t    fi\n\t\t  fi\n\t\t  ;;\n\t\t*)\n\t\t  path=\"-L$absdir/$objdir\"\n\t\t  ;;\n\t\tesac\n\t\telse\n\t\t  eval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $deplib`\n\t\t  test -z \"$libdir\" && \\\n\t\t    func_fatal_error \"\\`$deplib' is not a valid libtool archive\"\n\t\t  test \"$absdir\" != \"$libdir\" && \\\n\t\t    func_warning \"\\`$deplib' seems to be moved\"\n\n\t\t  path=\"-L$absdir\"\n\t\tfi\n\t\t;;\n\t      esac\n\t      case \" $deplibs \" in\n\t      *\" $path \"*) ;;\n\t      *) deplibs=\"$path $deplibs\" ;;\n\t      esac\n\t    done\n\t  fi # link_all_deplibs != no\n\tfi # linkmode = lib\n      done # for deplib in $libs\n      if test \"$pass\" = link; then\n\tif test \"$linkmode\" = \"prog\"; then\n\t  compile_deplibs=\"$new_inherited_linker_flags $compile_deplibs\"\n\t  finalize_deplibs=\"$new_inherited_linker_flags $finalize_deplibs\"\n\telse\n\t  compiler_flags=\"$compiler_flags \"`$ECHO \"X $new_inherited_linker_flags\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tfi\n      fi\n      dependency_libs=\"$newdependency_libs\"\n      if test \"$pass\" = dlpreopen; then\n\t# Link the dlpreopened libraries before other libraries\n\tfor deplib in $save_deplibs; do\n\t  deplibs=\"$deplib $deplibs\"\n\tdone\n      fi\n      if test \"$pass\" != dlopen; then\n\tif test \"$pass\" != conv; then\n\t  # Make sure lib_search_path contains only unique directories.\n\t  lib_search_path=\n\t  for dir in $newlib_search_path; do\n\t    case \"$lib_search_path \" in\n\t    *\" $dir \"*) ;;\n\t    *) lib_search_path=\"$lib_search_path $dir\" ;;\n\t    esac\n\t  done\n\t  newlib_search_path=\n\tfi\n\n\tif test \"$linkmode,$pass\" != \"prog,link\"; then\n\t  vars=\"deplibs\"\n\telse\n\t  vars=\"compile_deplibs finalize_deplibs\"\n\tfi\n\tfor var in $vars dependency_libs; do\n\t  # Add libraries to $var in reverse order\n\t  eval tmp_libs=\\\"\\$$var\\\"\n\t  new_libs=\n\t  for deplib in $tmp_libs; do\n\t    # FIXME: Pedantically, this is the right thing to do, so\n\t    #        that some nasty dependency loop isn't accidentally\n\t    #        broken:\n\t    #new_libs=\"$deplib $new_libs\"\n\t    # Pragmatically, this seems to cause very few problems in\n\t    # practice:\n\t    case $deplib in\n\t    -L*) new_libs=\"$deplib $new_libs\" ;;\n\t    -R*) ;;\n\t    *)\n\t      # And here is the reason: when a library appears more\n\t      # than once as an explicit dependence of a library, or\n\t      # is implicitly linked in more than once by the\n\t      # compiler, it is considered special, and multiple\n\t      # occurrences thereof are not removed.  Compare this\n\t      # with having the same library being listed as a\n\t      # dependency of multiple other libraries: in this case,\n\t      # we know (pedantically, we assume) the library does not\n\t      # need to be listed more than once, so we keep only the\n\t      # last copy.  This is not always right, but it is rare\n\t      # enough that we require users that really mean to play\n\t      # such unportable linking tricks to link the library\n\t      # using -Wl,-lname, so that libtool does not consider it\n\t      # for duplicate removal.\n\t      case \" $specialdeplibs \" in\n\t      *\" $deplib \"*) new_libs=\"$deplib $new_libs\" ;;\n\t      *)\n\t\tcase \" $new_libs \" in\n\t\t*\" $deplib \"*) ;;\n\t\t*) new_libs=\"$deplib $new_libs\" ;;\n\t\tesac\n\t\t;;\n\t      esac\n\t      ;;\n\t    esac\n\t  done\n\t  tmp_libs=\n\t  for deplib in $new_libs; do\n\t    case $deplib in\n\t    -L*)\n\t      case \" $tmp_libs \" in\n\t      *\" $deplib \"*) ;;\n\t      *) tmp_libs=\"$tmp_libs $deplib\" ;;\n\t      esac\n\t      ;;\n\t    *) tmp_libs=\"$tmp_libs $deplib\" ;;\n\t    esac\n\t  done\n\t  eval $var=\\\"$tmp_libs\\\"\n\tdone # for var\n      fi\n      # Last step: remove runtime libs from dependency_libs\n      # (they stay in deplibs)\n      tmp_libs=\n      for i in $dependency_libs ; do\n\tcase \" $predeps $postdeps $compiler_lib_search_path \" in\n\t*\" $i \"*)\n\t  i=\"\"\n\t  ;;\n\tesac\n\tif test -n \"$i\" ; then\n\t  tmp_libs=\"$tmp_libs $i\"\n\tfi\n      done\n      dependency_libs=$tmp_libs\n    done # for pass\n    if test \"$linkmode\" = prog; then\n      dlfiles=\"$newdlfiles\"\n    fi\n    if test \"$linkmode\" = prog || test \"$linkmode\" = lib; then\n      dlprefiles=\"$newdlprefiles\"\n    fi\n\n    case $linkmode in\n    oldlib)\n      if test -n \"$dlfiles$dlprefiles\" || test \"$dlself\" != no; then\n\tfunc_warning \"\\`-dlopen' is ignored for archives\"\n      fi\n\n      case \" $deplibs\" in\n      *\\ -l* | *\\ -L*)\n\tfunc_warning \"\\`-l' and \\`-L' are ignored for archives\" ;;\n      esac\n\n      test -n \"$rpath\" && \\\n\tfunc_warning \"\\`-rpath' is ignored for archives\"\n\n      test -n \"$xrpath\" && \\\n\tfunc_warning \"\\`-R' is ignored for archives\"\n\n      test -n \"$vinfo\" && \\\n\tfunc_warning \"\\`-version-info/-version-number' is ignored for archives\"\n\n      test -n \"$release\" && \\\n\tfunc_warning \"\\`-release' is ignored for archives\"\n\n      test -n \"$export_symbols$export_symbols_regex\" && \\\n\tfunc_warning \"\\`-export-symbols' is ignored for archives\"\n\n      # Now set the variables for building old libraries.\n      build_libtool_libs=no\n      oldlibs=\"$output\"\n      objs=\"$objs$old_deplibs\"\n      ;;\n\n    lib)\n      # Make sure we only generate libraries of the form `libNAME.la'.\n      case $outputname in\n      lib*)\n\tfunc_stripname 'lib' '.la' \"$outputname\"\n\tname=$func_stripname_result\n\teval shared_ext=\\\"$shrext_cmds\\\"\n\teval libname=\\\"$libname_spec\\\"\n\t;;\n      *)\n\ttest \"$module\" = no && \\\n\t  func_fatal_help \"libtool library \\`$output' must begin with \\`lib'\"\n\n\tif test \"$need_lib_prefix\" != no; then\n\t  # Add the \"lib\" prefix for modules if required\n\t  func_stripname '' '.la' \"$outputname\"\n\t  name=$func_stripname_result\n\t  eval shared_ext=\\\"$shrext_cmds\\\"\n\t  eval libname=\\\"$libname_spec\\\"\n\telse\n\t  func_stripname '' '.la' \"$outputname\"\n\t  libname=$func_stripname_result\n\tfi\n\t;;\n      esac\n\n      if test -n \"$objs\"; then\n\tif test \"$deplibs_check_method\" != pass_all; then\n\t  func_fatal_error \"cannot build libtool library \\`$output' from non-libtool objects on this host:$objs\"\n\telse\n\t  $ECHO\n\t  $ECHO \"*** Warning: Linking the shared library $output against the non-libtool\"\n\t  $ECHO \"*** objects $objs is not portable!\"\n\t  libobjs=\"$libobjs $objs\"\n\tfi\n      fi\n\n      test \"$dlself\" != no && \\\n\tfunc_warning \"\\`-dlopen self' is ignored for libtool libraries\"\n\n      set dummy $rpath\n      shift\n      test \"$#\" -gt 1 && \\\n\tfunc_warning \"ignoring multiple \\`-rpath's for a libtool library\"\n\n      install_libdir=\"$1\"\n\n      oldlibs=\n      if test -z \"$rpath\"; then\n\tif test \"$build_libtool_libs\" = yes; then\n\t  # Building a libtool convenience library.\n\t  # Some compilers have problems with a `.al' extension so\n\t  # convenience libraries should have the same extension an\n\t  # archive normally would.\n\t  oldlibs=\"$output_objdir/$libname.$libext $oldlibs\"\n\t  build_libtool_libs=convenience\n\t  build_old_libs=yes\n\tfi\n\n\ttest -n \"$vinfo\" && \\\n\t  func_warning \"\\`-version-info/-version-number' is ignored for convenience libraries\"\n\n\ttest -n \"$release\" && \\\n\t  func_warning \"\\`-release' is ignored for convenience libraries\"\n      else\n\n\t# Parse the version information argument.\n\tsave_ifs=\"$IFS\"; IFS=':'\n\tset dummy $vinfo 0 0 0\n\tshift\n\tIFS=\"$save_ifs\"\n\n\ttest -n \"$7\" && \\\n\t  func_fatal_help \"too many parameters to \\`-version-info'\"\n\n\t# convert absolute version numbers to libtool ages\n\t# this retains compatibility with .la files and attempts\n\t# to make the code below a bit more comprehensible\n\n\tcase $vinfo_number in\n\tyes)\n\t  number_major=\"$1\"\n\t  number_minor=\"$2\"\n\t  number_revision=\"$3\"\n\t  #\n\t  # There are really only two kinds -- those that\n\t  # use the current revision as the major version\n\t  # and those that subtract age and use age as\n\t  # a minor version.  But, then there is irix\n\t  # which has an extra 1 added just for fun\n\t  #\n\t  case $version_type in\n\t  darwin|linux|osf|windows|none)\n\t    func_arith $number_major + $number_minor\n\t    current=$func_arith_result\n\t    age=\"$number_minor\"\n\t    revision=\"$number_revision\"\n\t    ;;\n\t  freebsd-aout|freebsd-elf|sunos)\n\t    current=\"$number_major\"\n\t    revision=\"$number_minor\"\n\t    age=\"0\"\n\t    ;;\n\t  irix|nonstopux)\n\t    func_arith $number_major + $number_minor\n\t    current=$func_arith_result\n\t    age=\"$number_minor\"\n\t    revision=\"$number_minor\"\n\t    lt_irix_increment=no\n\t    ;;\n\t  *)\n\t    func_fatal_configuration \"$modename: unknown library version type \\`$version_type'\"\n\t    ;;\n\t  esac\n\t  ;;\n\tno)\n\t  current=\"$1\"\n\t  revision=\"$2\"\n\t  age=\"$3\"\n\t  ;;\n\tesac\n\n\t# Check that each of the things are valid numbers.\n\tcase $current in\n\t0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;\n\t*)\n\t  func_error \"CURRENT \\`$current' must be a nonnegative integer\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\t  ;;\n\tesac\n\n\tcase $revision in\n\t0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;\n\t*)\n\t  func_error \"REVISION \\`$revision' must be a nonnegative integer\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\t  ;;\n\tesac\n\n\tcase $age in\n\t0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;\n\t*)\n\t  func_error \"AGE \\`$age' must be a nonnegative integer\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\t  ;;\n\tesac\n\n\tif test \"$age\" -gt \"$current\"; then\n\t  func_error \"AGE \\`$age' is greater than the current interface number \\`$current'\"\n\t  func_fatal_error \"\\`$vinfo' is not valid version information\"\n\tfi\n\n\t# Calculate the version variables.\n\tmajor=\n\tversuffix=\n\tverstring=\n\tcase $version_type in\n\tnone) ;;\n\n\tdarwin)\n\t  # Like Linux, but with the current version available in\n\t  # verstring for coding it into the library header\n\t  func_arith $current - $age\n\t  major=.$func_arith_result\n\t  versuffix=\"$major.$age.$revision\"\n\t  # Darwin ld doesn't like 0 for these options...\n\t  func_arith $current + 1\n\t  minor_current=$func_arith_result\n\t  xlcverstring=\"${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision\"\n\t  verstring=\"-compatibility_version $minor_current -current_version $minor_current.$revision\"\n\t  ;;\n\n\tfreebsd-aout)\n\t  major=\".$current\"\n\t  versuffix=\".$current.$revision\";\n\t  ;;\n\n\tfreebsd-elf)\n\t  major=\".$current\"\n\t  versuffix=\".$current\"\n\t  ;;\n\n\tirix | nonstopux)\n\t  if test \"X$lt_irix_increment\" = \"Xno\"; then\n\t    func_arith $current - $age\n\t  else\n\t    func_arith $current - $age + 1\n\t  fi\n\t  major=$func_arith_result\n\n\t  case $version_type in\n\t    nonstopux) verstring_prefix=nonstopux ;;\n\t    *)         verstring_prefix=sgi ;;\n\t  esac\n\t  verstring=\"$verstring_prefix$major.$revision\"\n\n\t  # Add in all the interfaces that we are compatible with.\n\t  loop=$revision\n\t  while test \"$loop\" -ne 0; do\n\t    func_arith $revision - $loop\n\t    iface=$func_arith_result\n\t    func_arith $loop - 1\n\t    loop=$func_arith_result\n\t    verstring=\"$verstring_prefix$major.$iface:$verstring\"\n\t  done\n\n\t  # Before this point, $major must not contain `.'.\n\t  major=.$major\n\t  versuffix=\"$major.$revision\"\n\t  ;;\n\n\tlinux)\n\t  func_arith $current - $age\n\t  major=.$func_arith_result\n\t  versuffix=\"$major.$age.$revision\"\n\t  ;;\n\n\tosf)\n\t  func_arith $current - $age\n\t  major=.$func_arith_result\n\t  versuffix=\".$current.$age.$revision\"\n\t  verstring=\"$current.$age.$revision\"\n\n\t  # Add in all the interfaces that we are compatible with.\n\t  loop=$age\n\t  while test \"$loop\" -ne 0; do\n\t    func_arith $current - $loop\n\t    iface=$func_arith_result\n\t    func_arith $loop - 1\n\t    loop=$func_arith_result\n\t    verstring=\"$verstring:${iface}.0\"\n\t  done\n\n\t  # Make executables depend on our current version.\n\t  verstring=\"$verstring:${current}.0\"\n\t  ;;\n\n\tqnx)\n\t  major=\".$current\"\n\t  versuffix=\".$current\"\n\t  ;;\n\n\tsunos)\n\t  major=\".$current\"\n\t  versuffix=\".$current.$revision\"\n\t  ;;\n\n\twindows)\n\t  # Use '-' rather than '.', since we only want one\n\t  # extension on DOS 8.3 filesystems.\n\t  func_arith $current - $age\n\t  major=$func_arith_result\n\t  versuffix=\"-$major\"\n\t  ;;\n\n\t*)\n\t  func_fatal_configuration \"unknown library version type \\`$version_type'\"\n\t  ;;\n\tesac\n\n\t# Clear the version info if we defaulted, and they specified a release.\n\tif test -z \"$vinfo\" && test -n \"$release\"; then\n\t  major=\n\t  case $version_type in\n\t  darwin)\n\t    # we can't check for \"0.0\" in archive_cmds due to quoting\n\t    # problems, so we reset it completely\n\t    verstring=\n\t    ;;\n\t  *)\n\t    verstring=\"0.0\"\n\t    ;;\n\t  esac\n\t  if test \"$need_version\" = no; then\n\t    versuffix=\n\t  else\n\t    versuffix=\".0.0\"\n\t  fi\n\tfi\n\n\t# Remove version info from name if versioning should be avoided\n\tif test \"$avoid_version\" = yes && test \"$need_version\" = no; then\n\t  major=\n\t  versuffix=\n\t  verstring=\"\"\n\tfi\n\n\t# Check to see if the archive will have undefined symbols.\n\tif test \"$allow_undefined\" = yes; then\n\t  if test \"$allow_undefined_flag\" = unsupported; then\n\t    func_warning \"undefined symbols not allowed in $host shared libraries\"\n\t    build_libtool_libs=no\n\t    build_old_libs=yes\n\t  fi\n\telse\n\t  # Don't allow undefined symbols.\n\t  allow_undefined_flag=\"$no_undefined_flag\"\n\tfi\n\n      fi\n\n      func_generate_dlsyms \"$libname\" \"$libname\" \"yes\"\n      libobjs=\"$libobjs $symfileobj\"\n      test \"X$libobjs\" = \"X \" && libobjs=\n\n      if test \"$mode\" != relink; then\n\t# Remove our outputs, but don't remove object files since they\n\t# may have been created when compiling PIC objects.\n\tremovelist=\n\ttempremovelist=`$ECHO \"$output_objdir/*\"`\n\tfor p in $tempremovelist; do\n\t  case $p in\n\t    *.$objext | *.gcno)\n\t       ;;\n\t    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)\n\t       if test \"X$precious_files_regex\" != \"X\"; then\n\t\t if $ECHO \"$p\" | $EGREP -e \"$precious_files_regex\" >/dev/null 2>&1\n\t\t then\n\t\t   continue\n\t\t fi\n\t       fi\n\t       removelist=\"$removelist $p\"\n\t       ;;\n\t    *) ;;\n\t  esac\n\tdone\n\ttest -n \"$removelist\" && \\\n\t  func_show_eval \"${RM}r \\$removelist\"\n      fi\n\n      # Now set the variables for building old libraries.\n      if test \"$build_old_libs\" = yes && test \"$build_libtool_libs\" != convenience ; then\n\toldlibs=\"$oldlibs $output_objdir/$libname.$libext\"\n\n\t# Transform .lo files to .o files.\n\toldobjs=\"$objs \"`$ECHO \"X$libobjs\" | $SP2NL | $Xsed -e '/\\.'${libext}'$/d' -e \"$lo2o\" | $NL2SP`\n      fi\n\n      # Eliminate all temporary directories.\n      #for path in $notinst_path; do\n      #\tlib_search_path=`$ECHO \"X$lib_search_path \" | $Xsed -e \"s% $path % %g\"`\n      #\tdeplibs=`$ECHO \"X$deplibs \" | $Xsed -e \"s% -L$path % %g\"`\n      #\tdependency_libs=`$ECHO \"X$dependency_libs \" | $Xsed -e \"s% -L$path % %g\"`\n      #done\n\n      if test -n \"$xrpath\"; then\n\t# If the user specified any rpath flags, then add them.\n\ttemp_xrpath=\n\tfor libdir in $xrpath; do\n\t  temp_xrpath=\"$temp_xrpath -R$libdir\"\n\t  case \"$finalize_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) finalize_rpath=\"$finalize_rpath $libdir\" ;;\n\t  esac\n\tdone\n\tif test \"$hardcode_into_libs\" != yes || test \"$build_old_libs\" = yes; then\n\t  dependency_libs=\"$temp_xrpath $dependency_libs\"\n\tfi\n      fi\n\n      # Make sure dlfiles contains only unique files that won't be dlpreopened\n      old_dlfiles=\"$dlfiles\"\n      dlfiles=\n      for lib in $old_dlfiles; do\n\tcase \" $dlprefiles $dlfiles \" in\n\t*\" $lib \"*) ;;\n\t*) dlfiles=\"$dlfiles $lib\" ;;\n\tesac\n      done\n\n      # Make sure dlprefiles contains only unique files\n      old_dlprefiles=\"$dlprefiles\"\n      dlprefiles=\n      for lib in $old_dlprefiles; do\n\tcase \"$dlprefiles \" in\n\t*\" $lib \"*) ;;\n\t*) dlprefiles=\"$dlprefiles $lib\" ;;\n\tesac\n      done\n\n      if test \"$build_libtool_libs\" = yes; then\n\tif test -n \"$rpath\"; then\n\t  case $host in\n\t  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)\n\t    # these systems don't actually have a c library (as such)!\n\t    ;;\n\t  *-*-rhapsody* | *-*-darwin1.[012])\n\t    # Rhapsody C library is in the System framework\n\t    deplibs=\"$deplibs System.ltframework\"\n\t    ;;\n\t  *-*-netbsd*)\n\t    # Don't link with libc until the a.out ld.so is fixed.\n\t    ;;\n\t  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)\n\t    # Do not include libc due to us having libc/libc_r.\n\t    ;;\n\t  *-*-sco3.2v5* | *-*-sco5v6*)\n\t    # Causes problems with __ctype\n\t    ;;\n\t  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)\n\t    # Compiler inserts libc in the correct place for threads to work\n\t    ;;\n\t  *)\n\t    # Add libc to deplibs on all other systems if necessary.\n\t    if test \"$build_libtool_need_lc\" = \"yes\"; then\n\t      deplibs=\"$deplibs -lc\"\n\t    fi\n\t    ;;\n\t  esac\n\tfi\n\n\t# Transform deplibs into only deplibs that can be linked in shared.\n\tname_save=$name\n\tlibname_save=$libname\n\trelease_save=$release\n\tversuffix_save=$versuffix\n\tmajor_save=$major\n\t# I'm not sure if I'm treating the release correctly.  I think\n\t# release should show up in the -l (ie -lgmp5) so we don't want to\n\t# add it in twice.  Is that correct?\n\trelease=\"\"\n\tversuffix=\"\"\n\tmajor=\"\"\n\tnewdeplibs=\n\tdroppeddeps=no\n\tcase $deplibs_check_method in\n\tpass_all)\n\t  # Don't check for shared/static.  Everything works.\n\t  # This might be a little naive.  We might want to check\n\t  # whether the library exists or not.  But this is on\n\t  # osf3 & osf4 and I'm not really sure... Just\n\t  # implementing what was already the behavior.\n\t  newdeplibs=$deplibs\n\t  ;;\n\ttest_compile)\n\t  # This code stresses the \"libraries are programs\" paradigm to its\n\t  # limits. Maybe even breaks it.  We compile a program, linking it\n\t  # against the deplibs as a proxy for the library.  Then we can check\n\t  # whether they linked in statically or dynamically with ldd.\n\t  $opt_dry_run || $RM conftest.c\n\t  cat > conftest.c <<EOF\n\t  int main() { return 0; }\nEOF\n\t  $opt_dry_run || $RM conftest\n\t  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then\n\t    ldd_output=`ldd conftest`\n\t    for i in $deplibs; do\n\t      case $i in\n\t      -l*)\n\t\tfunc_stripname -l '' \"$i\"\n\t\tname=$func_stripname_result\n\t\tif test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\t  case \" $predeps $postdeps \" in\n\t\t  *\" $i \"*)\n\t\t    newdeplibs=\"$newdeplibs $i\"\n\t\t    i=\"\"\n\t\t    ;;\n\t\t  esac\n\t\tfi\n\t\tif test -n \"$i\" ; then\n\t\t  libname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\t  deplib_matches=`eval \"\\\\$ECHO \\\"$library_names_spec\\\"\"`\n\t\t  set dummy $deplib_matches; shift\n\t\t  deplib_match=$1\n\t\t  if test `expr \"$ldd_output\" : \".*$deplib_match\"` -ne 0 ; then\n\t\t    newdeplibs=\"$newdeplibs $i\"\n\t\t  else\n\t\t    droppeddeps=yes\n\t\t    $ECHO\n\t\t    $ECHO \"*** Warning: dynamic linker does not accept needed library $i.\"\n\t\t    $ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t    $ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t    $ECHO \"*** shared version of the library, which I believe you do not have\"\n\t\t    $ECHO \"*** because a test_compile did reveal that the linker did not use it for\"\n\t\t    $ECHO \"*** its dynamic dependency list that programs get resolved with at runtime.\"\n\t\t  fi\n\t\tfi\n\t\t;;\n\t      *)\n\t\tnewdeplibs=\"$newdeplibs $i\"\n\t\t;;\n\t      esac\n\t    done\n\t  else\n\t    # Error occurred in the first compile.  Let's try to salvage\n\t    # the situation: Compile a separate program for each library.\n\t    for i in $deplibs; do\n\t      case $i in\n\t      -l*)\n\t\tfunc_stripname -l '' \"$i\"\n\t\tname=$func_stripname_result\n\t\t$opt_dry_run || $RM conftest\n\t\tif $LTCC $LTCFLAGS -o conftest conftest.c $i; then\n\t\t  ldd_output=`ldd conftest`\n\t\t  if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\t    case \" $predeps $postdeps \" in\n\t\t    *\" $i \"*)\n\t\t      newdeplibs=\"$newdeplibs $i\"\n\t\t      i=\"\"\n\t\t      ;;\n\t\t    esac\n\t\t  fi\n\t\t  if test -n \"$i\" ; then\n\t\t    libname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\t    deplib_matches=`eval \"\\\\$ECHO \\\"$library_names_spec\\\"\"`\n\t\t    set dummy $deplib_matches; shift\n\t\t    deplib_match=$1\n\t\t    if test `expr \"$ldd_output\" : \".*$deplib_match\"` -ne 0 ; then\n\t\t      newdeplibs=\"$newdeplibs $i\"\n\t\t    else\n\t\t      droppeddeps=yes\n\t\t      $ECHO\n\t\t      $ECHO \"*** Warning: dynamic linker does not accept needed library $i.\"\n\t\t      $ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t      $ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t      $ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t      $ECHO \"*** because a test_compile did reveal that the linker did not use this one\"\n\t\t      $ECHO \"*** as a dynamic dependency that programs can get resolved with at runtime.\"\n\t\t    fi\n\t\t  fi\n\t\telse\n\t\t  droppeddeps=yes\n\t\t  $ECHO\n\t\t  $ECHO \"*** Warning!  Library $i is needed by this library but I was not able to\"\n\t\t  $ECHO \"*** make it link in!  You will probably need to install it or some\"\n\t\t  $ECHO \"*** library that it depends on before this library will be fully\"\n\t\t  $ECHO \"*** functional.  Installing it before continuing would be even better.\"\n\t\tfi\n\t\t;;\n\t      *)\n\t\tnewdeplibs=\"$newdeplibs $i\"\n\t\t;;\n\t      esac\n\t    done\n\t  fi\n\t  ;;\n\tfile_magic*)\n\t  set dummy $deplibs_check_method; shift\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"$1 \\(.*\\)\"`\n\t  for a_deplib in $deplibs; do\n\t    case $a_deplib in\n\t    -l*)\n\t      func_stripname -l '' \"$a_deplib\"\n\t      name=$func_stripname_result\n\t      if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\tcase \" $predeps $postdeps \" in\n\t\t*\" $a_deplib \"*)\n\t\t  newdeplibs=\"$newdeplibs $a_deplib\"\n\t\t  a_deplib=\"\"\n\t\t  ;;\n\t\tesac\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tlibname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\tfor i in $lib_search_path $sys_lib_search_path $shlib_search_path; do\n\t\t  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`\n\t\t  for potent_lib in $potential_libs; do\n\t\t      # Follow soft links.\n\t\t      if ls -lLd \"$potent_lib\" 2>/dev/null |\n\t\t\t $GREP \" -> \" >/dev/null; then\n\t\t\tcontinue\n\t\t      fi\n\t\t      # The statement above tries to avoid entering an\n\t\t      # endless loop below, in case of cyclic links.\n\t\t      # We might still enter an endless loop, since a link\n\t\t      # loop can be closed while we follow links,\n\t\t      # but so what?\n\t\t      potlib=\"$potent_lib\"\n\t\t      while test -h \"$potlib\" 2>/dev/null; do\n\t\t\tpotliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`\n\t\t\tcase $potliblink in\n\t\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) potlib=\"$potliblink\";;\n\t\t\t*) potlib=`$ECHO \"X$potlib\" | $Xsed -e 's,[^/]*$,,'`\"$potliblink\";;\n\t\t\tesac\n\t\t      done\n\t\t      if eval $file_magic_cmd \\\"\\$potlib\\\" 2>/dev/null |\n\t\t\t $SED -e 10q |\n\t\t\t $EGREP \"$file_magic_regex\" > /dev/null; then\n\t\t\tnewdeplibs=\"$newdeplibs $a_deplib\"\n\t\t\ta_deplib=\"\"\n\t\t\tbreak 2\n\t\t      fi\n\t\t  done\n\t\tdone\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tdroppeddeps=yes\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: linker path does not have real file for library $a_deplib.\"\n\t\t$ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t$ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t$ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t$ECHO \"*** because I did check the linker path looking for a file starting\"\n\t\tif test -z \"$potlib\" ; then\n\t\t  $ECHO \"*** with $libname but no candidates were found. (...for file magic test)\"\n\t\telse\n\t\t  $ECHO \"*** with $libname and none of the candidates passed a file format test\"\n\t\t  $ECHO \"*** using a file magic. Last file checked: $potlib\"\n\t\tfi\n\t      fi\n\t      ;;\n\t    *)\n\t      # Add a -L argument.\n\t      newdeplibs=\"$newdeplibs $a_deplib\"\n\t      ;;\n\t    esac\n\t  done # Gone through all deplibs.\n\t  ;;\n\tmatch_pattern*)\n\t  set dummy $deplibs_check_method; shift\n\t  match_pattern_regex=`expr \"$deplibs_check_method\" : \"$1 \\(.*\\)\"`\n\t  for a_deplib in $deplibs; do\n\t    case $a_deplib in\n\t    -l*)\n\t      func_stripname -l '' \"$a_deplib\"\n\t      name=$func_stripname_result\n\t      if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t\tcase \" $predeps $postdeps \" in\n\t\t*\" $a_deplib \"*)\n\t\t  newdeplibs=\"$newdeplibs $a_deplib\"\n\t\t  a_deplib=\"\"\n\t\t  ;;\n\t\tesac\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tlibname=`eval \"\\\\$ECHO \\\"$libname_spec\\\"\"`\n\t\tfor i in $lib_search_path $sys_lib_search_path $shlib_search_path; do\n\t\t  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`\n\t\t  for potent_lib in $potential_libs; do\n\t\t    potlib=\"$potent_lib\" # see symlink-check above in file_magic test\n\t\t    if eval \"\\$ECHO \\\"X$potent_lib\\\"\" 2>/dev/null | $Xsed -e 10q | \\\n\t\t       $EGREP \"$match_pattern_regex\" > /dev/null; then\n\t\t      newdeplibs=\"$newdeplibs $a_deplib\"\n\t\t      a_deplib=\"\"\n\t\t      break 2\n\t\t    fi\n\t\t  done\n\t\tdone\n\t      fi\n\t      if test -n \"$a_deplib\" ; then\n\t\tdroppeddeps=yes\n\t\t$ECHO\n\t\t$ECHO \"*** Warning: linker path does not have real file for library $a_deplib.\"\n\t\t$ECHO \"*** I have the capability to make that library automatically link in when\"\n\t\t$ECHO \"*** you link to this library.  But I can only do this if you have a\"\n\t\t$ECHO \"*** shared version of the library, which you do not appear to have\"\n\t\t$ECHO \"*** because I did check the linker path looking for a file starting\"\n\t\tif test -z \"$potlib\" ; then\n\t\t  $ECHO \"*** with $libname but no candidates were found. (...for regex pattern test)\"\n\t\telse\n\t\t  $ECHO \"*** with $libname and none of the candidates passed a file format test\"\n\t\t  $ECHO \"*** using a regex pattern. Last file checked: $potlib\"\n\t\tfi\n\t      fi\n\t      ;;\n\t    *)\n\t      # Add a -L argument.\n\t      newdeplibs=\"$newdeplibs $a_deplib\"\n\t      ;;\n\t    esac\n\t  done # Gone through all deplibs.\n\t  ;;\n\tnone | unknown | *)\n\t  newdeplibs=\"\"\n\t  tmp_deplibs=`$ECHO \"X $deplibs\" | $Xsed \\\n\t      -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`\n\t  if test \"X$allow_libtool_libs_with_static_runtimes\" = \"Xyes\" ; then\n\t    for i in $predeps $postdeps ; do\n\t      # can't use Xsed below, because $i might contain '/'\n\t      tmp_deplibs=`$ECHO \"X $tmp_deplibs\" | $Xsed -e \"s,$i,,\"`\n\t    done\n\t  fi\n\t  if $ECHO \"X $tmp_deplibs\" | $Xsed -e 's/[\t ]//g' |\n\t     $GREP . >/dev/null; then\n\t    $ECHO\n\t    if test \"X$deplibs_check_method\" = \"Xnone\"; then\n\t      $ECHO \"*** Warning: inter-library dependencies are not supported in this platform.\"\n\t    else\n\t      $ECHO \"*** Warning: inter-library dependencies are not known to be supported.\"\n\t    fi\n\t    $ECHO \"*** All declared inter-library dependencies are being dropped.\"\n\t    droppeddeps=yes\n\t  fi\n\t  ;;\n\tesac\n\tversuffix=$versuffix_save\n\tmajor=$major_save\n\trelease=$release_save\n\tlibname=$libname_save\n\tname=$name_save\n\n\tcase $host in\n\t*-*-rhapsody* | *-*-darwin1.[012])\n\t  # On Rhapsody replace the C library with the System framework\n\t  newdeplibs=`$ECHO \"X $newdeplibs\" | $Xsed -e 's/ -lc / System.ltframework /'`\n\t  ;;\n\tesac\n\n\tif test \"$droppeddeps\" = yes; then\n\t  if test \"$module\" = yes; then\n\t    $ECHO\n\t    $ECHO \"*** Warning: libtool could not satisfy all declared inter-library\"\n\t    $ECHO \"*** dependencies of module $libname.  Therefore, libtool will create\"\n\t    $ECHO \"*** a static module, that should work as long as the dlopening\"\n\t    $ECHO \"*** application is linked with the -dlopen flag.\"\n\t    if test -z \"$global_symbol_pipe\"; then\n\t      $ECHO\n\t      $ECHO \"*** However, this would only work if libtool was able to extract symbol\"\n\t      $ECHO \"*** lists from a program, using \\`nm' or equivalent, but libtool could\"\n\t      $ECHO \"*** not find such a program.  So, this module is probably useless.\"\n\t      $ECHO \"*** \\`nm' from GNU binutils and a full rebuild may help.\"\n\t    fi\n\t    if test \"$build_old_libs\" = no; then\n\t      oldlibs=\"$output_objdir/$libname.$libext\"\n\t      build_libtool_libs=module\n\t      build_old_libs=yes\n\t    else\n\t      build_libtool_libs=no\n\t    fi\n\t  else\n\t    $ECHO \"*** The inter-library dependencies that have been dropped here will be\"\n\t    $ECHO \"*** automatically added whenever a program is linked with this library\"\n\t    $ECHO \"*** or is declared to -dlopen it.\"\n\n\t    if test \"$allow_undefined\" = no; then\n\t      $ECHO\n\t      $ECHO \"*** Since this library must not contain undefined symbols,\"\n\t      $ECHO \"*** because either the platform does not support them or\"\n\t      $ECHO \"*** it was explicitly requested with -no-undefined,\"\n\t      $ECHO \"*** libtool will only create a static version of it.\"\n\t      if test \"$build_old_libs\" = no; then\n\t\toldlibs=\"$output_objdir/$libname.$libext\"\n\t\tbuild_libtool_libs=module\n\t\tbuild_old_libs=yes\n\t      else\n\t\tbuild_libtool_libs=no\n\t      fi\n\t    fi\n\t  fi\n\tfi\n\t# Done checking deplibs!\n\tdeplibs=$newdeplibs\n      fi\n      # Time to change all our \"foo.ltframework\" stuff back to \"-framework foo\"\n      case $host in\n\t*-*-darwin*)\n\t  newdeplibs=`$ECHO \"X $newdeplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  new_inherited_linker_flags=`$ECHO \"X $new_inherited_linker_flags\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  deplibs=`$ECHO \"X $deplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t  ;;\n      esac\n\n      # move library search paths that coincide with paths to not yet\n      # installed libraries to the beginning of the library search list\n      new_libs=\n      for path in $notinst_path; do\n\tcase \" $new_libs \" in\n\t*\" -L$path/$objdir \"*) ;;\n\t*)\n\t  case \" $deplibs \" in\n\t  *\" -L$path/$objdir \"*)\n\t    new_libs=\"$new_libs -L$path/$objdir\" ;;\n\t  esac\n\t  ;;\n\tesac\n      done\n      for deplib in $deplibs; do\n\tcase $deplib in\n\t-L*)\n\t  case \" $new_libs \" in\n\t  *\" $deplib \"*) ;;\n\t  *) new_libs=\"$new_libs $deplib\" ;;\n\t  esac\n\t  ;;\n\t*) new_libs=\"$new_libs $deplib\" ;;\n\tesac\n      done\n      deplibs=\"$new_libs\"\n\n      # All the library-specific variables (install_libdir is set above).\n      library_names=\n      old_library=\n      dlname=\n\n      # Test again, we may have decided not to build it any more\n      if test \"$build_libtool_libs\" = yes; then\n\tif test \"$hardcode_into_libs\" = yes; then\n\t  # Hardcode the library paths\n\t  hardcode_libdirs=\n\t  dep_rpath=\n\t  rpath=\"$finalize_rpath\"\n\t  test \"$mode\" != relink && rpath=\"$compile_rpath$rpath\"\n\t  for libdir in $rpath; do\n\t    if test -n \"$hardcode_libdir_flag_spec\"; then\n\t      if test -n \"$hardcode_libdir_separator\"; then\n\t\tif test -z \"$hardcode_libdirs\"; then\n\t\t  hardcode_libdirs=\"$libdir\"\n\t\telse\n\t\t  # Just accumulate the unique libdirs.\n\t\t  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in\n\t\t  *\"$hardcode_libdir_separator$libdir$hardcode_libdir_separator\"*)\n\t\t    ;;\n\t\t  *)\n\t\t    hardcode_libdirs=\"$hardcode_libdirs$hardcode_libdir_separator$libdir\"\n\t\t    ;;\n\t\t  esac\n\t\tfi\n\t      else\n\t\teval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\t\tdep_rpath=\"$dep_rpath $flag\"\n\t      fi\n\t    elif test -n \"$runpath_var\"; then\n\t      case \"$perm_rpath \" in\n\t      *\" $libdir \"*) ;;\n\t      *) perm_rpath=\"$perm_rpath $libdir\" ;;\n\t      esac\n\t    fi\n\t  done\n\t  # Substitute the hardcoded libdirs into the rpath.\n\t  if test -n \"$hardcode_libdir_separator\" &&\n\t     test -n \"$hardcode_libdirs\"; then\n\t    libdir=\"$hardcode_libdirs\"\n\t    if test -n \"$hardcode_libdir_flag_spec_ld\"; then\n\t      eval dep_rpath=\\\"$hardcode_libdir_flag_spec_ld\\\"\n\t    else\n\t      eval dep_rpath=\\\"$hardcode_libdir_flag_spec\\\"\n\t    fi\n\t  fi\n\t  if test -n \"$runpath_var\" && test -n \"$perm_rpath\"; then\n\t    # We should set the runpath_var.\n\t    rpath=\n\t    for dir in $perm_rpath; do\n\t      rpath=\"$rpath$dir:\"\n\t    done\n\t    eval \"$runpath_var='$rpath\\$$runpath_var'; export $runpath_var\"\n\t  fi\n\t  test -n \"$dep_rpath\" && deplibs=\"$dep_rpath $deplibs\"\n\tfi\n\n\tshlibpath=\"$finalize_shlibpath\"\n\ttest \"$mode\" != relink && shlibpath=\"$compile_shlibpath$shlibpath\"\n\tif test -n \"$shlibpath\"; then\n\t  eval \"$shlibpath_var='$shlibpath\\$$shlibpath_var'; export $shlibpath_var\"\n\tfi\n\n\t# Get the real and link names of the library.\n\teval shared_ext=\\\"$shrext_cmds\\\"\n\teval library_names=\\\"$library_names_spec\\\"\n\tset dummy $library_names\n\tshift\n\trealname=\"$1\"\n\tshift\n\n\tif test -n \"$soname_spec\"; then\n\t  eval soname=\\\"$soname_spec\\\"\n\telse\n\t  soname=\"$realname\"\n\tfi\n\tif test -z \"$dlname\"; then\n\t  dlname=$soname\n\tfi\n\n\tlib=\"$output_objdir/$realname\"\n\tlinknames=\n\tfor link\n\tdo\n\t  linknames=\"$linknames $link\"\n\tdone\n\n\t# Use standard objects if they are pic\n\ttest -z \"$pic_flag\" && libobjs=`$ECHO \"X$libobjs\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n\ttest \"X$libobjs\" = \"X \" && libobjs=\n\n\tdelfiles=\n\tif test -n \"$export_symbols\" && test -n \"$include_expsyms\"; then\n\t  $opt_dry_run || cp \"$export_symbols\" \"$output_objdir/$libname.uexp\"\n\t  export_symbols=\"$output_objdir/$libname.uexp\"\n\t  delfiles=\"$delfiles $export_symbols\"\n\tfi\n\n\torig_export_symbols=\n\tcase $host_os in\n\tcygwin* | mingw* | cegcc*)\n\t  if test -n \"$export_symbols\" && test -z \"$export_symbols_regex\"; then\n\t    # exporting using user supplied symfile\n\t    if test \"x`$SED 1q $export_symbols`\" != xEXPORTS; then\n\t      # and it's NOT already a .def file. Must figure out\n\t      # which of the given symbols are data symbols and tag\n\t      # them as such. So, trigger use of export_symbols_cmds.\n\t      # export_symbols gets reassigned inside the \"prepare\n\t      # the list of exported symbols\" if statement, so the\n\t      # include_expsyms logic still works.\n\t      orig_export_symbols=\"$export_symbols\"\n\t      export_symbols=\n\t      always_export_symbols=yes\n\t    fi\n\t  fi\n\t  ;;\n\tesac\n\n\t# Prepare the list of exported symbols\n\tif test -z \"$export_symbols\"; then\n\t  if test \"$always_export_symbols\" = yes || test -n \"$export_symbols_regex\"; then\n\t    func_verbose \"generating symbol list for \\`$libname.la'\"\n\t    export_symbols=\"$output_objdir/$libname.exp\"\n\t    $opt_dry_run || $RM $export_symbols\n\t    cmds=$export_symbols_cmds\n\t    save_ifs=\"$IFS\"; IFS='~'\n\t    for cmd in $cmds; do\n\t      IFS=\"$save_ifs\"\n\t      eval cmd=\\\"$cmd\\\"\n\t      func_len \" $cmd\"\n\t      len=$func_len_result\n\t      if test \"$len\" -lt \"$max_cmd_len\" || test \"$max_cmd_len\" -le -1; then\n\t\tfunc_show_eval \"$cmd\" 'exit $?'\n\t\tskipped_export=false\n\t      else\n\t\t# The command line is too long to execute in one step.\n\t\tfunc_verbose \"using reloadable object file for export list...\"\n\t\tskipped_export=:\n\t\t# Break out early, otherwise skipped_export may be\n\t\t# set to false by a later but shorter cmd.\n\t\tbreak\n\t      fi\n\t    done\n\t    IFS=\"$save_ifs\"\n\t    if test -n \"$export_symbols_regex\" && test \"X$skipped_export\" != \"X:\"; then\n\t      func_show_eval '$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"'\n\t      func_show_eval '$MV \"${export_symbols}T\" \"$export_symbols\"'\n\t    fi\n\t  fi\n\tfi\n\n\tif test -n \"$export_symbols\" && test -n \"$include_expsyms\"; then\n\t  tmp_export_symbols=\"$export_symbols\"\n\t  test -n \"$orig_export_symbols\" && tmp_export_symbols=\"$orig_export_symbols\"\n\t  $opt_dry_run || eval '$ECHO \"X$include_expsyms\" | $Xsed | $SP2NL >> \"$tmp_export_symbols\"'\n\tfi\n\n\tif test \"X$skipped_export\" != \"X:\" && test -n \"$orig_export_symbols\"; then\n\t  # The given exports_symbols file has to be filtered, so filter it.\n\t  func_verbose \"filter symbol list for \\`$libname.la' to tag DATA exports\"\n\t  # FIXME: $output_objdir/$libname.filter potentially contains lots of\n\t  # 's' commands which not all seds can handle. GNU sed should be fine\n\t  # though. Also, the filter scales superlinearly with the number of\n\t  # global variables. join(1) would be nice here, but unfortunately\n\t  # isn't a blessed tool.\n\t  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\\(.*\\)\\([ \\,].*\\),s|^\\1$|\\1\\2|,' < $export_symbols > $output_objdir/$libname.filter\n\t  delfiles=\"$delfiles $export_symbols $output_objdir/$libname.filter\"\n\t  export_symbols=$output_objdir/$libname.def\n\t  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols\n\tfi\n\n\ttmp_deplibs=\n\tfor test_deplib in $deplibs; do\n\t  case \" $convenience \" in\n\t  *\" $test_deplib \"*) ;;\n\t  *)\n\t    tmp_deplibs=\"$tmp_deplibs $test_deplib\"\n\t    ;;\n\t  esac\n\tdone\n\tdeplibs=\"$tmp_deplibs\"\n\n\tif test -n \"$convenience\"; then\n\t  if test -n \"$whole_archive_flag_spec\" &&\n\t    test \"$compiler_needs_object\" = yes &&\n\t    test -z \"$libobjs\"; then\n\t    # extract the archives, so we have objects to list.\n\t    # TODO: could optimize this to just extract one archive.\n\t    whole_archive_flag_spec=\n\t  fi\n\t  if test -n \"$whole_archive_flag_spec\"; then\n\t    save_libobjs=$libobjs\n\t    eval libobjs=\\\"\\$libobjs $whole_archive_flag_spec\\\"\n\t    test \"X$libobjs\" = \"X \" && libobjs=\n\t  else\n\t    gentop=\"$output_objdir/${outputname}x\"\n\t    generated=\"$generated $gentop\"\n\n\t    func_extract_archives $gentop $convenience\n\t    libobjs=\"$libobjs $func_extract_archives_result\"\n\t    test \"X$libobjs\" = \"X \" && libobjs=\n\t  fi\n\tfi\n\n\tif test \"$thread_safe\" = yes && test -n \"$thread_safe_flag_spec\"; then\n\t  eval flag=\\\"$thread_safe_flag_spec\\\"\n\t  linker_flags=\"$linker_flags $flag\"\n\tfi\n\n\t# Make a backup of the uninstalled library when relinking\n\tif test \"$mode\" = relink; then\n\t  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?\n\tfi\n\n\t# Do each of the archive commands.\n\tif test \"$module\" = yes && test -n \"$module_cmds\" ; then\n\t  if test -n \"$export_symbols\" && test -n \"$module_expsym_cmds\"; then\n\t    eval test_cmds=\\\"$module_expsym_cmds\\\"\n\t    cmds=$module_expsym_cmds\n\t  else\n\t    eval test_cmds=\\\"$module_cmds\\\"\n\t    cmds=$module_cmds\n\t  fi\n\telse\n\t  if test -n \"$export_symbols\" && test -n \"$archive_expsym_cmds\"; then\n\t    eval test_cmds=\\\"$archive_expsym_cmds\\\"\n\t    cmds=$archive_expsym_cmds\n\t  else\n\t    eval test_cmds=\\\"$archive_cmds\\\"\n\t    cmds=$archive_cmds\n\t  fi\n\tfi\n\n\tif test \"X$skipped_export\" != \"X:\" &&\n\t   func_len \" $test_cmds\" &&\n\t   len=$func_len_result &&\n\t   test \"$len\" -lt \"$max_cmd_len\" || test \"$max_cmd_len\" -le -1; then\n\t  :\n\telse\n\t  # The command line is too long to link in one step, link piecewise\n\t  # or, if using GNU ld and skipped_export is not :, use a linker\n\t  # script.\n\n\t  # Save the value of $output and $libobjs because we want to\n\t  # use them later.  If we have whole_archive_flag_spec, we\n\t  # want to use save_libobjs as it was before\n\t  # whole_archive_flag_spec was expanded, because we can't\n\t  # assume the linker understands whole_archive_flag_spec.\n\t  # This may have to be revisited, in case too many\n\t  # convenience libraries get linked in and end up exceeding\n\t  # the spec.\n\t  if test -z \"$convenience\" || test -z \"$whole_archive_flag_spec\"; then\n\t    save_libobjs=$libobjs\n\t  fi\n\t  save_output=$output\n\t  output_la=`$ECHO \"X$output\" | $Xsed -e \"$basename\"`\n\n\t  # Clear the reloadable object creation command queue and\n\t  # initialize k to one.\n\t  test_cmds=\n\t  concat_cmds=\n\t  objlist=\n\t  last_robj=\n\t  k=1\n\n\t  if test -n \"$save_libobjs\" && test \"X$skipped_export\" != \"X:\" && test \"$with_gnu_ld\" = yes; then\n\t    output=${output_objdir}/${output_la}.lnkscript\n\t    func_verbose \"creating GNU ld script: $output\"\n\t    $ECHO 'INPUT (' > $output\n\t    for obj in $save_libobjs\n\t    do\n\t      $ECHO \"$obj\" >> $output\n\t    done\n\t    $ECHO ')' >> $output\n\t    delfiles=\"$delfiles $output\"\n\t  elif test -n \"$save_libobjs\" && test \"X$skipped_export\" != \"X:\" && test \"X$file_list_spec\" != X; then\n\t    output=${output_objdir}/${output_la}.lnk\n\t    func_verbose \"creating linker input file list: $output\"\n\t    : > $output\n\t    set x $save_libobjs\n\t    shift\n\t    firstobj=\n\t    if test \"$compiler_needs_object\" = yes; then\n\t      firstobj=\"$1 \"\n\t      shift\n\t    fi\n\t    for obj\n\t    do\n\t      $ECHO \"$obj\" >> $output\n\t    done\n\t    delfiles=\"$delfiles $output\"\n\t    output=$firstobj\\\"$file_list_spec$output\\\"\n\t  else\n\t    if test -n \"$save_libobjs\"; then\n\t      func_verbose \"creating reloadable object files...\"\n\t      output=$output_objdir/$output_la-${k}.$objext\n\t      eval test_cmds=\\\"$reload_cmds\\\"\n\t      func_len \" $test_cmds\"\n\t      len0=$func_len_result\n\t      len=$len0\n\n\t      # Loop over the list of objects to be linked.\n\t      for obj in $save_libobjs\n\t      do\n\t\tfunc_len \" $obj\"\n\t\tfunc_arith $len + $func_len_result\n\t\tlen=$func_arith_result\n\t\tif test \"X$objlist\" = X ||\n\t\t   test \"$len\" -lt \"$max_cmd_len\"; then\n\t\t  func_append objlist \" $obj\"\n\t\telse\n\t\t  # The command $test_cmds is almost too long, add a\n\t\t  # command to the queue.\n\t\t  if test \"$k\" -eq 1 ; then\n\t\t    # The first file doesn't have a previous command to add.\n\t\t    eval concat_cmds=\\\"$reload_cmds $objlist $last_robj\\\"\n\t\t  else\n\t\t    # All subsequent reloadable object files will link in\n\t\t    # the last one created.\n\t\t    eval concat_cmds=\\\"\\$concat_cmds~$reload_cmds $objlist $last_robj~\\$RM $last_robj\\\"\n\t\t  fi\n\t\t  last_robj=$output_objdir/$output_la-${k}.$objext\n\t\t  func_arith $k + 1\n\t\t  k=$func_arith_result\n\t\t  output=$output_objdir/$output_la-${k}.$objext\n\t\t  objlist=$obj\n\t\t  func_len \" $last_robj\"\n\t\t  func_arith $len0 + $func_len_result\n\t\t  len=$func_arith_result\n\t\tfi\n\t      done\n\t      # Handle the remaining objects by creating one last\n\t      # reloadable object file.  All subsequent reloadable object\n\t      # files will link in the last one created.\n\t      test -z \"$concat_cmds\" || concat_cmds=$concat_cmds~\n\t      eval concat_cmds=\\\"\\${concat_cmds}$reload_cmds $objlist $last_robj\\\"\n\t      if test -n \"$last_robj\"; then\n\t        eval concat_cmds=\\\"\\${concat_cmds}~\\$RM $last_robj\\\"\n\t      fi\n\t      delfiles=\"$delfiles $output\"\n\n\t    else\n\t      output=\n\t    fi\n\n\t    if ${skipped_export-false}; then\n\t      func_verbose \"generating symbol list for \\`$libname.la'\"\n\t      export_symbols=\"$output_objdir/$libname.exp\"\n\t      $opt_dry_run || $RM $export_symbols\n\t      libobjs=$output\n\t      # Append the command to create the export file.\n\t      test -z \"$concat_cmds\" || concat_cmds=$concat_cmds~\n\t      eval concat_cmds=\\\"\\$concat_cmds$export_symbols_cmds\\\"\n\t      if test -n \"$last_robj\"; then\n\t\teval concat_cmds=\\\"\\$concat_cmds~\\$RM $last_robj\\\"\n\t      fi\n\t    fi\n\n\t    test -n \"$save_libobjs\" &&\n\t      func_verbose \"creating a temporary reloadable object file: $output\"\n\n\t    # Loop through the commands generated above and execute them.\n\t    save_ifs=\"$IFS\"; IFS='~'\n\t    for cmd in $concat_cmds; do\n\t      IFS=\"$save_ifs\"\n\t      $opt_silent || {\n\t\t  func_quote_for_expand \"$cmd\"\n\t\t  eval \"func_echo $func_quote_for_expand_result\"\n\t      }\n\t      $opt_dry_run || eval \"$cmd\" || {\n\t\tlt_exit=$?\n\n\t\t# Restore the uninstalled library and exit\n\t\tif test \"$mode\" = relink; then\n\t\t  ( cd \"$output_objdir\" && \\\n\t\t    $RM \"${realname}T\" && \\\n\t\t    $MV \"${realname}U\" \"$realname\" )\n\t\tfi\n\n\t\texit $lt_exit\n\t      }\n\t    done\n\t    IFS=\"$save_ifs\"\n\n\t    if test -n \"$export_symbols_regex\" && ${skipped_export-false}; then\n\t      func_show_eval '$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"'\n\t      func_show_eval '$MV \"${export_symbols}T\" \"$export_symbols\"'\n\t    fi\n\t  fi\n\n          if ${skipped_export-false}; then\n\t    if test -n \"$export_symbols\" && test -n \"$include_expsyms\"; then\n\t      tmp_export_symbols=\"$export_symbols\"\n\t      test -n \"$orig_export_symbols\" && tmp_export_symbols=\"$orig_export_symbols\"\n\t      $opt_dry_run || eval '$ECHO \"X$include_expsyms\" | $Xsed | $SP2NL >> \"$tmp_export_symbols\"'\n\t    fi\n\n\t    if test -n \"$orig_export_symbols\"; then\n\t      # The given exports_symbols file has to be filtered, so filter it.\n\t      func_verbose \"filter symbol list for \\`$libname.la' to tag DATA exports\"\n\t      # FIXME: $output_objdir/$libname.filter potentially contains lots of\n\t      # 's' commands which not all seds can handle. GNU sed should be fine\n\t      # though. Also, the filter scales superlinearly with the number of\n\t      # global variables. join(1) would be nice here, but unfortunately\n\t      # isn't a blessed tool.\n\t      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\\(.*\\)\\([ \\,].*\\),s|^\\1$|\\1\\2|,' < $export_symbols > $output_objdir/$libname.filter\n\t      delfiles=\"$delfiles $export_symbols $output_objdir/$libname.filter\"\n\t      export_symbols=$output_objdir/$libname.def\n\t      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols\n\t    fi\n\t  fi\n\n\t  libobjs=$output\n\t  # Restore the value of output.\n\t  output=$save_output\n\n\t  if test -n \"$convenience\" && test -n \"$whole_archive_flag_spec\"; then\n\t    eval libobjs=\\\"\\$libobjs $whole_archive_flag_spec\\\"\n\t    test \"X$libobjs\" = \"X \" && libobjs=\n\t  fi\n\t  # Expand the library linking commands again to reset the\n\t  # value of $libobjs for piecewise linking.\n\n\t  # Do each of the archive commands.\n\t  if test \"$module\" = yes && test -n \"$module_cmds\" ; then\n\t    if test -n \"$export_symbols\" && test -n \"$module_expsym_cmds\"; then\n\t      cmds=$module_expsym_cmds\n\t    else\n\t      cmds=$module_cmds\n\t    fi\n\t  else\n\t    if test -n \"$export_symbols\" && test -n \"$archive_expsym_cmds\"; then\n\t      cmds=$archive_expsym_cmds\n\t    else\n\t      cmds=$archive_cmds\n\t    fi\n\t  fi\n\tfi\n\n\tif test -n \"$delfiles\"; then\n\t  # Append the command to remove temporary files to $cmds.\n\t  eval cmds=\\\"\\$cmds~\\$RM $delfiles\\\"\n\tfi\n\n\t# Add any objects from preloaded convenience libraries\n\tif test -n \"$dlprefiles\"; then\n\t  gentop=\"$output_objdir/${outputname}x\"\n\t  generated=\"$generated $gentop\"\n\n\t  func_extract_archives $gentop $dlprefiles\n\t  libobjs=\"$libobjs $func_extract_archives_result\"\n\t  test \"X$libobjs\" = \"X \" && libobjs=\n\tfi\n\n\tsave_ifs=\"$IFS\"; IFS='~'\n\tfor cmd in $cmds; do\n\t  IFS=\"$save_ifs\"\n\t  eval cmd=\\\"$cmd\\\"\n\t  $opt_silent || {\n\t    func_quote_for_expand \"$cmd\"\n\t    eval \"func_echo $func_quote_for_expand_result\"\n\t  }\n\t  $opt_dry_run || eval \"$cmd\" || {\n\t    lt_exit=$?\n\n\t    # Restore the uninstalled library and exit\n\t    if test \"$mode\" = relink; then\n\t      ( cd \"$output_objdir\" && \\\n\t        $RM \"${realname}T\" && \\\n\t\t$MV \"${realname}U\" \"$realname\" )\n\t    fi\n\n\t    exit $lt_exit\n\t  }\n\tdone\n\tIFS=\"$save_ifs\"\n\n\t# Restore the uninstalled library and exit\n\tif test \"$mode\" = relink; then\n\t  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?\n\n\t  if test -n \"$convenience\"; then\n\t    if test -z \"$whole_archive_flag_spec\"; then\n\t      func_show_eval '${RM}r \"$gentop\"'\n\t    fi\n\t  fi\n\n\t  exit $EXIT_SUCCESS\n\tfi\n\n\t# Create links to the real library.\n\tfor linkname in $linknames; do\n\t  if test \"$realname\" != \"$linkname\"; then\n\t    func_show_eval '(cd \"$output_objdir\" && $RM \"$linkname\" && $LN_S \"$realname\" \"$linkname\")' 'exit $?'\n\t  fi\n\tdone\n\n\t# If -module or -export-dynamic was specified, set the dlname.\n\tif test \"$module\" = yes || test \"$export_dynamic\" = yes; then\n\t  # On all known operating systems, these are identical.\n\t  dlname=\"$soname\"\n\tfi\n      fi\n      ;;\n\n    obj)\n      if test -n \"$dlfiles$dlprefiles\" || test \"$dlself\" != no; then\n\tfunc_warning \"\\`-dlopen' is ignored for objects\"\n      fi\n\n      case \" $deplibs\" in\n      *\\ -l* | *\\ -L*)\n\tfunc_warning \"\\`-l' and \\`-L' are ignored for objects\" ;;\n      esac\n\n      test -n \"$rpath\" && \\\n\tfunc_warning \"\\`-rpath' is ignored for objects\"\n\n      test -n \"$xrpath\" && \\\n\tfunc_warning \"\\`-R' is ignored for objects\"\n\n      test -n \"$vinfo\" && \\\n\tfunc_warning \"\\`-version-info' is ignored for objects\"\n\n      test -n \"$release\" && \\\n\tfunc_warning \"\\`-release' is ignored for objects\"\n\n      case $output in\n      *.lo)\n\ttest -n \"$objs$old_deplibs\" && \\\n\t  func_fatal_error \"cannot build library object \\`$output' from non-libtool objects\"\n\n\tlibobj=$output\n\tfunc_lo2o \"$libobj\"\n\tobj=$func_lo2o_result\n\t;;\n      *)\n\tlibobj=\n\tobj=\"$output\"\n\t;;\n      esac\n\n      # Delete the old objects.\n      $opt_dry_run || $RM $obj $libobj\n\n      # Objects from convenience libraries.  This assumes\n      # single-version convenience libraries.  Whenever we create\n      # different ones for PIC/non-PIC, this we'll have to duplicate\n      # the extraction.\n      reload_conv_objs=\n      gentop=\n      # reload_cmds runs $LD directly, so let us get rid of\n      # -Wl from whole_archive_flag_spec and hope we can get by with\n      # turning comma into space..\n      wl=\n\n      if test -n \"$convenience\"; then\n\tif test -n \"$whole_archive_flag_spec\"; then\n\t  eval tmp_whole_archive_flags=\\\"$whole_archive_flag_spec\\\"\n\t  reload_conv_objs=$reload_objs\\ `$ECHO \"X$tmp_whole_archive_flags\" | $Xsed -e 's|,| |g'`\n\telse\n\t  gentop=\"$output_objdir/${obj}x\"\n\t  generated=\"$generated $gentop\"\n\n\t  func_extract_archives $gentop $convenience\n\t  reload_conv_objs=\"$reload_objs $func_extract_archives_result\"\n\tfi\n      fi\n\n      # Create the old-style object.\n      reload_objs=\"$objs$old_deplibs \"`$ECHO \"X$libobjs\" | $SP2NL | $Xsed -e '/\\.'${libext}$'/d' -e '/\\.lib$/d' -e \"$lo2o\" | $NL2SP`\" $reload_conv_objs\" ### testsuite: skip nested quoting test\n\n      output=\"$obj\"\n      func_execute_cmds \"$reload_cmds\" 'exit $?'\n\n      # Exit if we aren't doing a library object file.\n      if test -z \"$libobj\"; then\n\tif test -n \"$gentop\"; then\n\t  func_show_eval '${RM}r \"$gentop\"'\n\tfi\n\n\texit $EXIT_SUCCESS\n      fi\n\n      if test \"$build_libtool_libs\" != yes; then\n\tif test -n \"$gentop\"; then\n\t  func_show_eval '${RM}r \"$gentop\"'\n\tfi\n\n\t# Create an invalid libtool object if no PIC, so that we don't\n\t# accidentally link it into a program.\n\t# $show \"echo timestamp > $libobj\"\n\t# $opt_dry_run || eval \"echo timestamp > $libobj\" || exit $?\n\texit $EXIT_SUCCESS\n      fi\n\n      if test -n \"$pic_flag\" || test \"$pic_mode\" != default; then\n\t# Only do commands if we really have different PIC objects.\n\treload_objs=\"$libobjs $reload_conv_objs\"\n\toutput=\"$libobj\"\n\tfunc_execute_cmds \"$reload_cmds\" 'exit $?'\n      fi\n\n      if test -n \"$gentop\"; then\n\tfunc_show_eval '${RM}r \"$gentop\"'\n      fi\n\n      exit $EXIT_SUCCESS\n      ;;\n\n    prog)\n      case $host in\n\t*cygwin*) func_stripname '' '.exe' \"$output\"\n\t          output=$func_stripname_result.exe;;\n      esac\n      test -n \"$vinfo\" && \\\n\tfunc_warning \"\\`-version-info' is ignored for programs\"\n\n      test -n \"$release\" && \\\n\tfunc_warning \"\\`-release' is ignored for programs\"\n\n      test \"$preload\" = yes \\\n        && test \"$dlopen_support\" = unknown \\\n\t&& test \"$dlopen_self\" = unknown \\\n\t&& test \"$dlopen_self_static\" = unknown && \\\n\t  func_warning \"\\`LT_INIT([dlopen])' not used. Assuming no dlopen support.\"\n\n      case $host in\n      *-*-rhapsody* | *-*-darwin1.[012])\n\t# On Rhapsody replace the C library is the System framework\n\tcompile_deplibs=`$ECHO \"X $compile_deplibs\" | $Xsed -e 's/ -lc / System.ltframework /'`\n\tfinalize_deplibs=`$ECHO \"X $finalize_deplibs\" | $Xsed -e 's/ -lc / System.ltframework /'`\n\t;;\n      esac\n\n      case $host in\n      *-*-darwin*)\n\t# Don't allow lazy linking, it breaks C++ global constructors\n\t# But is supposedly fixed on 10.4 or later (yay!).\n\tif test \"$tagname\" = CXX ; then\n\t  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in\n\t    10.[0123])\n\t      compile_command=\"$compile_command ${wl}-bind_at_load\"\n\t      finalize_command=\"$finalize_command ${wl}-bind_at_load\"\n\t    ;;\n\t  esac\n\tfi\n\t# Time to change all our \"foo.ltframework\" stuff back to \"-framework foo\"\n\tcompile_deplibs=`$ECHO \"X $compile_deplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\tfinalize_deplibs=`$ECHO \"X $finalize_deplibs\" | $Xsed -e 's% \\([^ $]*\\).ltframework% -framework \\1%g'`\n\t;;\n      esac\n\n\n      # move library search paths that coincide with paths to not yet\n      # installed libraries to the beginning of the library search list\n      new_libs=\n      for path in $notinst_path; do\n\tcase \" $new_libs \" in\n\t*\" -L$path/$objdir \"*) ;;\n\t*)\n\t  case \" $compile_deplibs \" in\n\t  *\" -L$path/$objdir \"*)\n\t    new_libs=\"$new_libs -L$path/$objdir\" ;;\n\t  esac\n\t  ;;\n\tesac\n      done\n      for deplib in $compile_deplibs; do\n\tcase $deplib in\n\t-L*)\n\t  case \" $new_libs \" in\n\t  *\" $deplib \"*) ;;\n\t  *) new_libs=\"$new_libs $deplib\" ;;\n\t  esac\n\t  ;;\n\t*) new_libs=\"$new_libs $deplib\" ;;\n\tesac\n      done\n      compile_deplibs=\"$new_libs\"\n\n\n      compile_command=\"$compile_command $compile_deplibs\"\n      finalize_command=\"$finalize_command $finalize_deplibs\"\n\n      if test -n \"$rpath$xrpath\"; then\n\t# If the user specified any rpath flags, then add them.\n\tfor libdir in $rpath $xrpath; do\n\t  # This is the magic to use -rpath.\n\t  case \"$finalize_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) finalize_rpath=\"$finalize_rpath $libdir\" ;;\n\t  esac\n\tdone\n      fi\n\n      # Now hardcode the library paths\n      rpath=\n      hardcode_libdirs=\n      for libdir in $compile_rpath $finalize_rpath; do\n\tif test -n \"$hardcode_libdir_flag_spec\"; then\n\t  if test -n \"$hardcode_libdir_separator\"; then\n\t    if test -z \"$hardcode_libdirs\"; then\n\t      hardcode_libdirs=\"$libdir\"\n\t    else\n\t      # Just accumulate the unique libdirs.\n\t      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in\n\t      *\"$hardcode_libdir_separator$libdir$hardcode_libdir_separator\"*)\n\t\t;;\n\t      *)\n\t\thardcode_libdirs=\"$hardcode_libdirs$hardcode_libdir_separator$libdir\"\n\t\t;;\n\t      esac\n\t    fi\n\t  else\n\t    eval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\t    rpath=\"$rpath $flag\"\n\t  fi\n\telif test -n \"$runpath_var\"; then\n\t  case \"$perm_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) perm_rpath=\"$perm_rpath $libdir\" ;;\n\t  esac\n\tfi\n\tcase $host in\n\t*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)\n\t  testbindir=`${ECHO} \"$libdir\" | ${SED} -e 's*/lib$*/bin*'`\n\t  case :$dllsearchpath: in\n\t  *\":$libdir:\"*) ;;\n\t  ::) dllsearchpath=$libdir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$libdir\";;\n\t  esac\n\t  case :$dllsearchpath: in\n\t  *\":$testbindir:\"*) ;;\n\t  ::) dllsearchpath=$testbindir;;\n\t  *) dllsearchpath=\"$dllsearchpath:$testbindir\";;\n\t  esac\n\t  ;;\n\tesac\n      done\n      # Substitute the hardcoded libdirs into the rpath.\n      if test -n \"$hardcode_libdir_separator\" &&\n\t test -n \"$hardcode_libdirs\"; then\n\tlibdir=\"$hardcode_libdirs\"\n\teval rpath=\\\" $hardcode_libdir_flag_spec\\\"\n      fi\n      compile_rpath=\"$rpath\"\n\n      rpath=\n      hardcode_libdirs=\n      for libdir in $finalize_rpath; do\n\tif test -n \"$hardcode_libdir_flag_spec\"; then\n\t  if test -n \"$hardcode_libdir_separator\"; then\n\t    if test -z \"$hardcode_libdirs\"; then\n\t      hardcode_libdirs=\"$libdir\"\n\t    else\n\t      # Just accumulate the unique libdirs.\n\t      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in\n\t      *\"$hardcode_libdir_separator$libdir$hardcode_libdir_separator\"*)\n\t\t;;\n\t      *)\n\t\thardcode_libdirs=\"$hardcode_libdirs$hardcode_libdir_separator$libdir\"\n\t\t;;\n\t      esac\n\t    fi\n\t  else\n\t    eval flag=\\\"$hardcode_libdir_flag_spec\\\"\n\t    rpath=\"$rpath $flag\"\n\t  fi\n\telif test -n \"$runpath_var\"; then\n\t  case \"$finalize_perm_rpath \" in\n\t  *\" $libdir \"*) ;;\n\t  *) finalize_perm_rpath=\"$finalize_perm_rpath $libdir\" ;;\n\t  esac\n\tfi\n      done\n      # Substitute the hardcoded libdirs into the rpath.\n      if test -n \"$hardcode_libdir_separator\" &&\n\t test -n \"$hardcode_libdirs\"; then\n\tlibdir=\"$hardcode_libdirs\"\n\teval rpath=\\\" $hardcode_libdir_flag_spec\\\"\n      fi\n      finalize_rpath=\"$rpath\"\n\n      if test -n \"$libobjs\" && test \"$build_old_libs\" = yes; then\n\t# Transform all the library objects into standard objects.\n\tcompile_command=`$ECHO \"X$compile_command\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n\tfinalize_command=`$ECHO \"X$finalize_command\" | $SP2NL | $Xsed -e \"$lo2o\" | $NL2SP`\n      fi\n\n      func_generate_dlsyms \"$outputname\" \"@PROGRAM@\" \"no\"\n\n      # template prelinking step\n      if test -n \"$prelink_cmds\"; then\n\tfunc_execute_cmds \"$prelink_cmds\" 'exit $?'\n      fi\n\n      wrappers_required=yes\n      case $host in\n      *cygwin* | *mingw* )\n        if test \"$build_libtool_libs\" != yes; then\n          wrappers_required=no\n        fi\n        ;;\n      *cegcc)\n        # Disable wrappers for cegcc, we are cross compiling anyway.\n        wrappers_required=no\n        ;;\n      *)\n        if test \"$need_relink\" = no || test \"$build_libtool_libs\" != yes; then\n          wrappers_required=no\n        fi\n        ;;\n      esac\n      if test \"$wrappers_required\" = no; then\n\t# Replace the output file specification.\n\tcompile_command=`$ECHO \"X$compile_command\" | $Xsed -e 's%@OUTPUT@%'\"$output\"'%g'`\n\tlink_command=\"$compile_command$compile_rpath\"\n\n\t# We have no uninstalled library dependencies, so finalize right now.\n\texit_status=0\n\tfunc_show_eval \"$link_command\" 'exit_status=$?'\n\n\t# Delete the generated files.\n\tif test -f \"$output_objdir/${outputname}S.${objext}\"; then\n\t  func_show_eval '$RM \"$output_objdir/${outputname}S.${objext}\"'\n\tfi\n\n\texit $exit_status\n      fi\n\n      if test -n \"$compile_shlibpath$finalize_shlibpath\"; then\n\tcompile_command=\"$shlibpath_var=\\\"$compile_shlibpath$finalize_shlibpath\\$$shlibpath_var\\\" $compile_command\"\n      fi\n      if test -n \"$finalize_shlibpath\"; then\n\tfinalize_command=\"$shlibpath_var=\\\"$finalize_shlibpath\\$$shlibpath_var\\\" $finalize_command\"\n      fi\n\n      compile_var=\n      finalize_var=\n      if test -n \"$runpath_var\"; then\n\tif test -n \"$perm_rpath\"; then\n\t  # We should set the runpath_var.\n\t  rpath=\n\t  for dir in $perm_rpath; do\n\t    rpath=\"$rpath$dir:\"\n\t  done\n\t  compile_var=\"$runpath_var=\\\"$rpath\\$$runpath_var\\\" \"\n\tfi\n\tif test -n \"$finalize_perm_rpath\"; then\n\t  # We should set the runpath_var.\n\t  rpath=\n\t  for dir in $finalize_perm_rpath; do\n\t    rpath=\"$rpath$dir:\"\n\t  done\n\t  finalize_var=\"$runpath_var=\\\"$rpath\\$$runpath_var\\\" \"\n\tfi\n      fi\n\n      if test \"$no_install\" = yes; then\n\t# We don't need to create a wrapper script.\n\tlink_command=\"$compile_var$compile_command$compile_rpath\"\n\t# Replace the output file specification.\n\tlink_command=`$ECHO \"X$link_command\" | $Xsed -e 's%@OUTPUT@%'\"$output\"'%g'`\n\t# Delete the old output file.\n\t$opt_dry_run || $RM $output\n\t# Link the executable and exit\n\tfunc_show_eval \"$link_command\" 'exit $?'\n\texit $EXIT_SUCCESS\n      fi\n\n      if test \"$hardcode_action\" = relink; then\n\t# Fast installation is not supported\n\tlink_command=\"$compile_var$compile_command$compile_rpath\"\n\trelink_command=\"$finalize_var$finalize_command$finalize_rpath\"\n\n\tfunc_warning \"this platform does not like uninstalled shared libraries\"\n\tfunc_warning \"\\`$output' will be relinked during installation\"\n      else\n\tif test \"$fast_install\" != no; then\n\t  link_command=\"$finalize_var$compile_command$finalize_rpath\"\n\t  if test \"$fast_install\" = yes; then\n\t    relink_command=`$ECHO \"X$compile_var$compile_command$compile_rpath\" | $Xsed -e 's%@OUTPUT@%\\$progdir/\\$file%g'`\n\t  else\n\t    # fast_install is set to needless\n\t    relink_command=\n\t  fi\n\telse\n\t  link_command=\"$compile_var$compile_command$compile_rpath\"\n\t  relink_command=\"$finalize_var$finalize_command$finalize_rpath\"\n\tfi\n      fi\n\n      # Replace the output file specification.\n      link_command=`$ECHO \"X$link_command\" | $Xsed -e 's%@OUTPUT@%'\"$output_objdir/$outputname\"'%g'`\n\n      # Delete the old output files.\n      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname\n\n      func_show_eval \"$link_command\" 'exit $?'\n\n      # Now create the wrapper script.\n      func_verbose \"creating $output\"\n\n      # Quote the relink command for shipping.\n      if test -n \"$relink_command\"; then\n\t# Preserve any variables that may affect compiler behavior\n\tfor var in $variables_saved_for_relink; do\n\t  if eval test -z \\\"\\${$var+set}\\\"; then\n\t    relink_command=\"{ test -z \\\"\\${$var+set}\\\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command\"\n\t  elif eval var_value=\\$$var; test -z \"$var_value\"; then\n\t    relink_command=\"$var=; export $var; $relink_command\"\n\t  else\n\t    func_quote_for_eval \"$var_value\"\n\t    relink_command=\"$var=$func_quote_for_eval_result; export $var; $relink_command\"\n\t  fi\n\tdone\n\trelink_command=\"(cd `pwd`; $relink_command)\"\n\trelink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"$sed_quote_subst\"`\n      fi\n\n      # Quote $ECHO for shipping.\n      if test \"X$ECHO\" = \"X$SHELL $progpath --fallback-echo\"; then\n\tcase $progpath in\n\t[\\\\/]* | [A-Za-z]:[\\\\/]*) qecho=\"$SHELL $progpath --fallback-echo\";;\n\t*) qecho=\"$SHELL `pwd`/$progpath --fallback-echo\";;\n\tesac\n\tqecho=`$ECHO \"X$qecho\" | $Xsed -e \"$sed_quote_subst\"`\n      else\n\tqecho=`$ECHO \"X$ECHO\" | $Xsed -e \"$sed_quote_subst\"`\n      fi\n\n      # Only actually do things if not in dry run mode.\n      $opt_dry_run || {\n\t# win32 will think the script is a binary if it has\n\t# a .exe suffix, so we strip it off here.\n\tcase $output in\n\t  *.exe) func_stripname '' '.exe' \"$output\"\n\t         output=$func_stripname_result ;;\n\tesac\n\t# test for cygwin because mv fails w/o .exe extensions\n\tcase $host in\n\t  *cygwin*)\n\t    exeext=.exe\n\t    func_stripname '' '.exe' \"$outputname\"\n\t    outputname=$func_stripname_result ;;\n\t  *) exeext= ;;\n\tesac\n\tcase $host in\n\t  *cygwin* | *mingw* )\n\t    func_dirname_and_basename \"$output\" \"\" \".\"\n\t    output_name=$func_basename_result\n\t    output_path=$func_dirname_result\n\t    cwrappersource=\"$output_path/$objdir/lt-$output_name.c\"\n\t    cwrapper=\"$output_path/$output_name.exe\"\n\t    $RM $cwrappersource $cwrapper\n\t    trap \"$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE\" 1 2 15\n\n\t    func_emit_cwrapperexe_src > $cwrappersource\n\n\t    # The wrapper executable is built using the $host compiler,\n\t    # because it contains $host paths and files. If cross-\n\t    # compiling, it, like the target executable, must be\n\t    # executed on the $host or under an emulation environment.\n\t    $opt_dry_run || {\n\t      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource\n\t      $STRIP $cwrapper\n\t    }\n\n\t    # Now, create the wrapper script for func_source use:\n\t    func_ltwrapper_scriptname $cwrapper\n\t    $RM $func_ltwrapper_scriptname_result\n\t    trap \"$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE\" 1 2 15\n\t    $opt_dry_run || {\n\t      # note: this script will not be executed, so do not chmod.\n\t      if test \"x$build\" = \"x$host\" ; then\n\t\t$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result\n\t      else\n\t\tfunc_emit_wrapper no > $func_ltwrapper_scriptname_result\n\t      fi\n\t    }\n\t  ;;\n\t  * )\n\t    $RM $output\n\t    trap \"$RM $output; exit $EXIT_FAILURE\" 1 2 15\n\n\t    func_emit_wrapper no > $output\n\t    chmod +x $output\n\t  ;;\n\tesac\n      }\n      exit $EXIT_SUCCESS\n      ;;\n    esac\n\n    # See if we need to build an old-fashioned archive.\n    for oldlib in $oldlibs; do\n\n      if test \"$build_libtool_libs\" = convenience; then\n\toldobjs=\"$libobjs_save $symfileobj\"\n\taddlibs=\"$convenience\"\n\tbuild_libtool_libs=no\n      else\n\tif test \"$build_libtool_libs\" = module; then\n\t  oldobjs=\"$libobjs_save\"\n\t  build_libtool_libs=no\n\telse\n\t  oldobjs=\"$old_deplibs $non_pic_objects\"\n\t  if test \"$preload\" = yes && test -f \"$symfileobj\"; then\n\t    oldobjs=\"$oldobjs $symfileobj\"\n\t  fi\n\tfi\n\taddlibs=\"$old_convenience\"\n      fi\n\n      if test -n \"$addlibs\"; then\n\tgentop=\"$output_objdir/${outputname}x\"\n\tgenerated=\"$generated $gentop\"\n\n\tfunc_extract_archives $gentop $addlibs\n\toldobjs=\"$oldobjs $func_extract_archives_result\"\n      fi\n\n      # Do each command in the archive commands.\n      if test -n \"$old_archive_from_new_cmds\" && test \"$build_libtool_libs\" = yes; then\n\tcmds=$old_archive_from_new_cmds\n      else\n\n\t# Add any objects from preloaded convenience libraries\n\tif test -n \"$dlprefiles\"; then\n\t  gentop=\"$output_objdir/${outputname}x\"\n\t  generated=\"$generated $gentop\"\n\n\t  func_extract_archives $gentop $dlprefiles\n\t  oldobjs=\"$oldobjs $func_extract_archives_result\"\n\tfi\n\n\t# POSIX demands no paths to be encoded in archives.  We have\n\t# to avoid creating archives with duplicate basenames if we\n\t# might have to extract them afterwards, e.g., when creating a\n\t# static archive out of a convenience library, or when linking\n\t# the entirety of a libtool archive into another (currently\n\t# not supported by libtool).\n\tif (for obj in $oldobjs\n\t    do\n\t      func_basename \"$obj\"\n\t      $ECHO \"$func_basename_result\"\n\t    done | sort | sort -uc >/dev/null 2>&1); then\n\t  :\n\telse\n\t  $ECHO \"copying selected object files to avoid basename conflicts...\"\n\t  gentop=\"$output_objdir/${outputname}x\"\n\t  generated=\"$generated $gentop\"\n\t  func_mkdir_p \"$gentop\"\n\t  save_oldobjs=$oldobjs\n\t  oldobjs=\n\t  counter=1\n\t  for obj in $save_oldobjs\n\t  do\n\t    func_basename \"$obj\"\n\t    objbase=\"$func_basename_result\"\n\t    case \" $oldobjs \" in\n\t    \" \") oldobjs=$obj ;;\n\t    *[\\ /]\"$objbase \"*)\n\t      while :; do\n\t\t# Make sure we don't pick an alternate name that also\n\t\t# overlaps.\n\t\tnewobj=lt$counter-$objbase\n\t\tfunc_arith $counter + 1\n\t\tcounter=$func_arith_result\n\t\tcase \" $oldobjs \" in\n\t\t*[\\ /]\"$newobj \"*) ;;\n\t\t*) if test ! -f \"$gentop/$newobj\"; then break; fi ;;\n\t\tesac\n\t      done\n\t      func_show_eval \"ln $obj $gentop/$newobj || cp $obj $gentop/$newobj\"\n\t      oldobjs=\"$oldobjs $gentop/$newobj\"\n\t      ;;\n\t    *) oldobjs=\"$oldobjs $obj\" ;;\n\t    esac\n\t  done\n\tfi\n\teval cmds=\\\"$old_archive_cmds\\\"\n\n\tfunc_len \" $cmds\"\n\tlen=$func_len_result\n\tif test \"$len\" -lt \"$max_cmd_len\" || test \"$max_cmd_len\" -le -1; then\n\t  cmds=$old_archive_cmds\n\telse\n\t  # the command line is too long to link in one step, link in parts\n\t  func_verbose \"using piecewise archive linking...\"\n\t  save_RANLIB=$RANLIB\n\t  RANLIB=:\n\t  objlist=\n\t  concat_cmds=\n\t  save_oldobjs=$oldobjs\n\t  oldobjs=\n\t  # Is there a better way of finding the last object in the list?\n\t  for obj in $save_oldobjs\n\t  do\n\t    last_oldobj=$obj\n\t  done\n\t  eval test_cmds=\\\"$old_archive_cmds\\\"\n\t  func_len \" $test_cmds\"\n\t  len0=$func_len_result\n\t  len=$len0\n\t  for obj in $save_oldobjs\n\t  do\n\t    func_len \" $obj\"\n\t    func_arith $len + $func_len_result\n\t    len=$func_arith_result\n\t    func_append objlist \" $obj\"\n\t    if test \"$len\" -lt \"$max_cmd_len\"; then\n\t      :\n\t    else\n\t      # the above command should be used before it gets too long\n\t      oldobjs=$objlist\n\t      if test \"$obj\" = \"$last_oldobj\" ; then\n\t\tRANLIB=$save_RANLIB\n\t      fi\n\t      test -z \"$concat_cmds\" || concat_cmds=$concat_cmds~\n\t      eval concat_cmds=\\\"\\${concat_cmds}$old_archive_cmds\\\"\n\t      objlist=\n\t      len=$len0\n\t    fi\n\t  done\n\t  RANLIB=$save_RANLIB\n\t  oldobjs=$objlist\n\t  if test \"X$oldobjs\" = \"X\" ; then\n\t    eval cmds=\\\"\\$concat_cmds\\\"\n\t  else\n\t    eval cmds=\\\"\\$concat_cmds~\\$old_archive_cmds\\\"\n\t  fi\n\tfi\n      fi\n      func_execute_cmds \"$cmds\" 'exit $?'\n    done\n\n    test -n \"$generated\" && \\\n      func_show_eval \"${RM}r$generated\"\n\n    # Now create the libtool archive.\n    case $output in\n    *.la)\n      old_library=\n      test \"$build_old_libs\" = yes && old_library=\"$libname.$libext\"\n      func_verbose \"creating $output\"\n\n      # Preserve any variables that may affect compiler behavior\n      for var in $variables_saved_for_relink; do\n\tif eval test -z \\\"\\${$var+set}\\\"; then\n\t  relink_command=\"{ test -z \\\"\\${$var+set}\\\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command\"\n\telif eval var_value=\\$$var; test -z \"$var_value\"; then\n\t  relink_command=\"$var=; export $var; $relink_command\"\n\telse\n\t  func_quote_for_eval \"$var_value\"\n\t  relink_command=\"$var=$func_quote_for_eval_result; export $var; $relink_command\"\n\tfi\n      done\n      # Quote the link command for shipping.\n      relink_command=\"(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)\"\n      relink_command=`$ECHO \"X$relink_command\" | $Xsed -e \"$sed_quote_subst\"`\n      if test \"$hardcode_automatic\" = yes ; then\n\trelink_command=\n      fi\n\n      # Only create the output if not a dry run.\n      $opt_dry_run || {\n\tfor installed in no yes; do\n\t  if test \"$installed\" = yes; then\n\t    if test -z \"$install_libdir\"; then\n\t      break\n\t    fi\n\t    output=\"$output_objdir/$outputname\"i\n\t    # Replace all uninstalled libtool libraries with the installed ones\n\t    newdependency_libs=\n\t    for deplib in $dependency_libs; do\n\t      case $deplib in\n\t      *.la)\n\t\tfunc_basename \"$deplib\"\n\t\tname=\"$func_basename_result\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $deplib`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$deplib' is not a valid libtool archive\"\n\t\tnewdependency_libs=\"$newdependency_libs $libdir/$name\"\n\t\t;;\n\t      *) newdependency_libs=\"$newdependency_libs $deplib\" ;;\n\t      esac\n\t    done\n\t    dependency_libs=\"$newdependency_libs\"\n\t    newdlfiles=\n\n\t    for lib in $dlfiles; do\n\t      case $lib in\n\t      *.la)\n\t        func_basename \"$lib\"\n\t\tname=\"$func_basename_result\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $lib`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$lib' is not a valid libtool archive\"\n\t\tnewdlfiles=\"$newdlfiles $libdir/$name\"\n\t\t;;\n\t      *) newdlfiles=\"$newdlfiles $lib\" ;;\n\t      esac\n\t    done\n\t    dlfiles=\"$newdlfiles\"\n\t    newdlprefiles=\n\t    for lib in $dlprefiles; do\n\t      case $lib in\n\t      *.la)\n\t\t# Only pass preopened files to the pseudo-archive (for\n\t\t# eventual linking with the app. that links it) if we\n\t\t# didn't already link the preopened objects directly into\n\t\t# the library:\n\t\tfunc_basename \"$lib\"\n\t\tname=\"$func_basename_result\"\n\t\teval libdir=`${SED} -n -e 's/^libdir=\\(.*\\)$/\\1/p' $lib`\n\t\ttest -z \"$libdir\" && \\\n\t\t  func_fatal_error \"\\`$lib' is not a valid libtool archive\"\n\t\tnewdlprefiles=\"$newdlprefiles $libdir/$name\"\n\t\t;;\n\t      esac\n\t    done\n\t    dlprefiles=\"$newdlprefiles\"\n\t  else\n\t    newdlfiles=\n\t    for lib in $dlfiles; do\n\t      case $lib in\n\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) abs=\"$lib\" ;;\n\t\t*) abs=`pwd`\"/$lib\" ;;\n\t      esac\n\t      newdlfiles=\"$newdlfiles $abs\"\n\t    done\n\t    dlfiles=\"$newdlfiles\"\n\t    newdlprefiles=\n\t    for lib in $dlprefiles; do\n\t      case $lib in\n\t\t[\\\\/]* | [A-Za-z]:[\\\\/]*) abs=\"$lib\" ;;\n\t\t*) abs=`pwd`\"/$lib\" ;;\n\t      esac\n\t      newdlprefiles=\"$newdlprefiles $abs\"\n\t    done\n\t    dlprefiles=\"$newdlprefiles\"\n\t  fi\n\t  $RM $output\n\t  # place dlname in correct position for cygwin\n\t  tdlname=$dlname\n\t  case $host,$output,$installed,$module,$dlname in\n\t    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;\n\t  esac\n\t  $ECHO > $output \"\\\n# $outputname - a libtool library file\n# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION\n#\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# The name that we can dlopen(3).\ndlname='$tdlname'\n\n# Names of this library.\nlibrary_names='$library_names'\n\n# The name of the static archive.\nold_library='$old_library'\n\n# Linker flags that can not go in dependency_libs.\ninherited_linker_flags='$new_inherited_linker_flags'\n\n# Libraries that this one depends upon.\ndependency_libs='$dependency_libs'\n\n# Names of additional weak libraries provided by this library\nweak_library_names='$weak_libs'\n\n# Version information for $libname.\ncurrent=$current\nage=$age\nrevision=$revision\n\n# Is this an already installed library?\ninstalled=$installed\n\n# Should we warn about portability when linking against -modules?\nshouldnotlink=$module\n\n# Files to dlopen/dlpreopen\ndlopen='$dlfiles'\ndlpreopen='$dlprefiles'\n\n# Directory that this library needs to be installed in:\nlibdir='$install_libdir'\"\n\t  if test \"$installed\" = no && test \"$need_relink\" = yes; then\n\t    $ECHO >> $output \"\\\nrelink_command=\\\"$relink_command\\\"\"\n\t  fi\n\tdone\n      }\n\n      # Do a symbolic link so that the libtool archive can be found in\n      # LD_LIBRARY_PATH before the program is installed.\n      func_show_eval '( cd \"$output_objdir\" && $RM \"$outputname\" && $LN_S \"../$outputname\" \"$outputname\" )' 'exit $?'\n      ;;\n    esac\n    exit $EXIT_SUCCESS\n}\n\n{ test \"$mode\" = link || test \"$mode\" = relink; } &&\n    func_mode_link ${1+\"$@\"}\n\n\n# func_mode_uninstall arg...\nfunc_mode_uninstall ()\n{\n    $opt_debug\n    RM=\"$nonopt\"\n    files=\n    rmforce=\n    exit_status=0\n\n    # This variable tells wrapper scripts just to set variables rather\n    # than running their programs.\n    libtool_install_magic=\"$magic\"\n\n    for arg\n    do\n      case $arg in\n      -f) RM=\"$RM $arg\"; rmforce=yes ;;\n      -*) RM=\"$RM $arg\" ;;\n      *) files=\"$files $arg\" ;;\n      esac\n    done\n\n    test -z \"$RM\" && \\\n      func_fatal_help \"you must specify an RM program\"\n\n    rmdirs=\n\n    origobjdir=\"$objdir\"\n    for file in $files; do\n      func_dirname \"$file\" \"\" \".\"\n      dir=\"$func_dirname_result\"\n      if test \"X$dir\" = X.; then\n\tobjdir=\"$origobjdir\"\n      else\n\tobjdir=\"$dir/$origobjdir\"\n      fi\n      func_basename \"$file\"\n      name=\"$func_basename_result\"\n      test \"$mode\" = uninstall && objdir=\"$dir\"\n\n      # Remember objdir for removal later, being careful to avoid duplicates\n      if test \"$mode\" = clean; then\n\tcase \" $rmdirs \" in\n\t  *\" $objdir \"*) ;;\n\t  *) rmdirs=\"$rmdirs $objdir\" ;;\n\tesac\n      fi\n\n      # Don't error if the file doesn't exist and rm -f was used.\n      if { test -L \"$file\"; } >/dev/null 2>&1 ||\n\t { test -h \"$file\"; } >/dev/null 2>&1 ||\n\t test -f \"$file\"; then\n\t:\n      elif test -d \"$file\"; then\n\texit_status=1\n\tcontinue\n      elif test \"$rmforce\" = yes; then\n\tcontinue\n      fi\n\n      rmfiles=\"$file\"\n\n      case $name in\n      *.la)\n\t# Possibly a libtool archive, so verify it.\n\tif func_lalib_p \"$file\"; then\n\t  func_source $dir/$name\n\n\t  # Delete the libtool libraries and symlinks.\n\t  for n in $library_names; do\n\t    rmfiles=\"$rmfiles $objdir/$n\"\n\t  done\n\t  test -n \"$old_library\" && rmfiles=\"$rmfiles $objdir/$old_library\"\n\n\t  case \"$mode\" in\n\t  clean)\n\t    case \"  $library_names \" in\n\t    # \"  \" in the beginning catches empty $dlname\n\t    *\" $dlname \"*) ;;\n\t    *) rmfiles=\"$rmfiles $objdir/$dlname\" ;;\n\t    esac\n\t    test -n \"$libdir\" && rmfiles=\"$rmfiles $objdir/$name $objdir/${name}i\"\n\t    ;;\n\t  uninstall)\n\t    if test -n \"$library_names\"; then\n\t      # Do each command in the postuninstall commands.\n\t      func_execute_cmds \"$postuninstall_cmds\" 'test \"$rmforce\" = yes || exit_status=1'\n\t    fi\n\n\t    if test -n \"$old_library\"; then\n\t      # Do each command in the old_postuninstall commands.\n\t      func_execute_cmds \"$old_postuninstall_cmds\" 'test \"$rmforce\" = yes || exit_status=1'\n\t    fi\n\t    # FIXME: should reinstall the best remaining shared library.\n\t    ;;\n\t  esac\n\tfi\n\t;;\n\n      *.lo)\n\t# Possibly a libtool object, so verify it.\n\tif func_lalib_p \"$file\"; then\n\n\t  # Read the .lo file\n\t  func_source $dir/$name\n\n\t  # Add PIC object to the list of files to remove.\n\t  if test -n \"$pic_object\" &&\n\t     test \"$pic_object\" != none; then\n\t    rmfiles=\"$rmfiles $dir/$pic_object\"\n\t  fi\n\n\t  # Add non-PIC object to the list of files to remove.\n\t  if test -n \"$non_pic_object\" &&\n\t     test \"$non_pic_object\" != none; then\n\t    rmfiles=\"$rmfiles $dir/$non_pic_object\"\n\t  fi\n\tfi\n\t;;\n\n      *)\n\tif test \"$mode\" = clean ; then\n\t  noexename=$name\n\t  case $file in\n\t  *.exe)\n\t    func_stripname '' '.exe' \"$file\"\n\t    file=$func_stripname_result\n\t    func_stripname '' '.exe' \"$name\"\n\t    noexename=$func_stripname_result\n\t    # $file with .exe has already been added to rmfiles,\n\t    # add $file without .exe\n\t    rmfiles=\"$rmfiles $file\"\n\t    ;;\n\t  esac\n\t  # Do a test to see if this is a libtool program.\n\t  if func_ltwrapper_p \"$file\"; then\n\t    if func_ltwrapper_executable_p \"$file\"; then\n\t      func_ltwrapper_scriptname \"$file\"\n\t      relink_command=\n\t      func_source $func_ltwrapper_scriptname_result\n\t      rmfiles=\"$rmfiles $func_ltwrapper_scriptname_result\"\n\t    else\n\t      relink_command=\n\t      func_source $dir/$noexename\n\t    fi\n\n\t    # note $name still contains .exe if it was in $file originally\n\t    # as does the version of $file that was added into $rmfiles\n\t    rmfiles=\"$rmfiles $objdir/$name $objdir/${name}S.${objext}\"\n\t    if test \"$fast_install\" = yes && test -n \"$relink_command\"; then\n\t      rmfiles=\"$rmfiles $objdir/lt-$name\"\n\t    fi\n\t    if test \"X$noexename\" != \"X$name\" ; then\n\t      rmfiles=\"$rmfiles $objdir/lt-${noexename}.c\"\n\t    fi\n\t  fi\n\tfi\n\t;;\n      esac\n      func_show_eval \"$RM $rmfiles\" 'exit_status=1'\n    done\n    objdir=\"$origobjdir\"\n\n    # Try to remove the ${objdir}s in the directories where we deleted files\n    for dir in $rmdirs; do\n      if test -d \"$dir\"; then\n\tfunc_show_eval \"rmdir $dir >/dev/null 2>&1\"\n      fi\n    done\n\n    exit $exit_status\n}\n\n{ test \"$mode\" = uninstall || test \"$mode\" = clean; } &&\n    func_mode_uninstall ${1+\"$@\"}\n\ntest -z \"$mode\" && {\n  help=\"$generic_help\"\n  func_fatal_help \"you must specify a MODE\"\n}\n\ntest -z \"$exec_cmd\" && \\\n  func_fatal_help \"invalid operation mode \\`$mode'\"\n\nif test -n \"$exec_cmd\"; then\n  eval exec \"$exec_cmd\"\n  exit $EXIT_FAILURE\nfi\n\nexit $exit_status\n\n\n# The TAGs below are defined such that we never get into a situation\n# in which we disable both kinds of libraries.  Given conflicting\n# choices, we go for a static library, that is the most portable,\n# since we can't tell whether shared libraries were disabled because\n# the user asked for that or because the platform doesn't support\n# them.  This is particularly important on AIX, because we don't\n# support having both static and shared libraries enabled at the same\n# time on that platform, so we default to a shared-only configuration.\n# If a disable-shared tag is given, we'll fallback to a static-only\n# configuration.  But we'll never go from static-only to shared-only.\n\n# ### BEGIN LIBTOOL TAG CONFIG: disable-shared\nbuild_libtool_libs=no\nbuild_old_libs=yes\n# ### END LIBTOOL TAG CONFIG: disable-shared\n\n# ### BEGIN LIBTOOL TAG CONFIG: disable-static\nbuild_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`\n# ### END LIBTOOL TAG CONFIG: disable-static\n\n# Local Variables:\n# mode:shell-script\n# sh-indentation:2\n# End:\n# vi:sw=2\n\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/ac_have_attribute.m4",
    "content": "AC_DEFUN([AX_C___ATTRIBUTE__], [\n  AC_MSG_CHECKING(for __attribute__)\n  AC_CACHE_VAL(ac_cv___attribute__, [\n    AC_TRY_COMPILE(\n      [#include <stdlib.h>\n       static void foo(void) __attribute__ ((unused));\n       void foo(void) { exit(1); }],\n      [],\n      ac_cv___attribute__=yes,\n      ac_cv___attribute__=no\n    )])\n  if test \"$ac_cv___attribute__\" = \"yes\"; then\n    AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])\n  fi\n  AC_MSG_RESULT($ac_cv___attribute__)\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/acx_nanosleep.m4",
    "content": "# Check for support for nanosleep.  It's defined in <time.h>, but on\n# some systems, such as solaris, you need to link in a library to use it.\n# We set acx_nanosleep_ok if nanosleep is supported; in that case,\n# NANOSLEEP_LIBS is set to whatever libraries are needed to support\n# nanosleep.\n\nAC_DEFUN([ACX_NANOSLEEP],\n[AC_MSG_CHECKING(if nanosleep requires any libraries)\n AC_LANG_SAVE\n AC_LANG_C\n acx_nanosleep_ok=\"no\"\n NANOSLEEP_LIBS=\n # For most folks, this should just work\n AC_TRY_LINK([#include <time.h>],\n             [static struct timespec ts; nanosleep(&ts, NULL);],\n             [acx_nanosleep_ok=yes])\n # For solaris, we may  need -lrt\n if test \"x$acx_nanosleep_ok\" != \"xyes\"; then\n   OLD_LIBS=\"$LIBS\"\n   LIBS=\"-lrt $LIBS\"\n   AC_TRY_LINK([#include <time.h>],\n               [static struct timespec ts; nanosleep(&ts, NULL);],\n               [acx_nanosleep_ok=yes])\n   if test \"x$acx_nanosleep_ok\" = \"xyes\"; then\n     NANOSLEEP_LIBS=\"-lrt\"\n   fi\n   LIBS=\"$OLD_LIBS\"\n fi\n if test \"x$acx_nanosleep_ok\" != \"xyes\"; then\n   AC_MSG_ERROR([cannot find the nanosleep function])\n else\n   AC_MSG_RESULT(${NANOSLEEP_LIBS:-no})\n fi\n AC_LANG_RESTORE\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/acx_pthread.m4",
    "content": "# This was retrieved from\n#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi\n# See also (perhaps for new versions?)\n#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi\n#\n# We've rewritten the inconsistency check code (from avahi), to work\n# more broadly.  In particular, it no longer assumes ld accepts -zdefs.\n# This caused a restructing of the code, but the functionality has only\n# changed a little.\n\ndnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])\ndnl\ndnl @summary figure out how to build C programs using POSIX threads\ndnl\ndnl This macro figures out how to build C programs using POSIX threads.\ndnl It sets the PTHREAD_LIBS output variable to the threads library and\ndnl linker flags, and the PTHREAD_CFLAGS output variable to any special\ndnl C compiler flags that are needed. (The user can also force certain\ndnl compiler flags/libs to be tested by setting these environment\ndnl variables.)\ndnl\ndnl Also sets PTHREAD_CC to any special C compiler that is needed for\ndnl multi-threaded programs (defaults to the value of CC otherwise).\ndnl (This is necessary on AIX to use the special cc_r compiler alias.)\ndnl\ndnl NOTE: You are assumed to not only compile your program with these\ndnl flags, but also link it with them as well. e.g. you should link\ndnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS\ndnl $LIBS\ndnl\ndnl If you are only building threads programs, you may wish to use\ndnl these variables in your default LIBS, CFLAGS, and CC:\ndnl\ndnl        LIBS=\"$PTHREAD_LIBS $LIBS\"\ndnl        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\ndnl        CC=\"$PTHREAD_CC\"\ndnl\ndnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute\ndnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to\ndnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).\ndnl\ndnl ACTION-IF-FOUND is a list of shell commands to run if a threads\ndnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to\ndnl run it if it is not found. If ACTION-IF-FOUND is not specified, the\ndnl default action will define HAVE_PTHREAD.\ndnl\ndnl Please let the authors know if this macro fails on any platform, or\ndnl if you have any other suggestions or comments. This macro was based\ndnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with\ndnl help from M. Frigo), as well as ac_pthread and hb_pthread macros\ndnl posted by Alejandro Forero Cuervo to the autoconf macro repository.\ndnl We are also grateful for the helpful feedback of numerous users.\ndnl\ndnl @category InstalledPackages\ndnl @author Steven G. Johnson <stevenj@alum.mit.edu>\ndnl @version 2006-05-29\ndnl @license GPLWithACException\ndnl \ndnl Checks for GCC shared/pthread inconsistency based on work by\ndnl Marcin Owsiany <marcin@owsiany.pl>\n\n\nAC_DEFUN([ACX_PTHREAD], [\nAC_REQUIRE([AC_CANONICAL_HOST])\nAC_LANG_SAVE\nAC_LANG_C\nacx_pthread_ok=no\n\n# We used to check for pthread.h first, but this fails if pthread.h\n# requires special compiler flags (e.g. on True64 or Sequent).\n# It gets checked for in the link test anyway.\n\n# First of all, check if the user has set any of the PTHREAD_LIBS,\n# etcetera environment variables, and if threads linking works using\n# them:\nif test x\"$PTHREAD_LIBS$PTHREAD_CFLAGS\" != x; then\n        save_CFLAGS=\"$CFLAGS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n        save_LIBS=\"$LIBS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])\n        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)\n        AC_MSG_RESULT($acx_pthread_ok)\n        if test x\"$acx_pthread_ok\" = xno; then\n                PTHREAD_LIBS=\"\"\n                PTHREAD_CFLAGS=\"\"\n        fi\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\nfi\n\n# We must check for the threads library under a number of different\n# names; the ordering is very important because some systems\n# (e.g. DEC) have both -lpthread and -lpthreads, where one of the\n# libraries is broken (non-POSIX).\n\n# Create a list of thread flags to try.  Items starting with a \"-\" are\n# C compiler flags, and other items are library names, except for \"none\"\n# which indicates that we try without any flags at all, and \"pthread-config\"\n# which is a program returning the flags for the Pth emulation library.\n\nacx_pthread_flags=\"pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config\"\n\n# The ordering *is* (sometimes) important.  Some notes on the\n# individual items follow:\n\n# pthreads: AIX (must check this before -lpthread)\n# none: in case threads are in libc; should be tried before -Kthread and\n#       other compiler flags to prevent continual compiler warnings\n# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)\n# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)\n# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)\n# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)\n# -pthreads: Solaris/gcc\n# -mthreads: Mingw32/gcc, Lynx/gcc\n# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it\n#      doesn't hurt to check since this sometimes defines pthreads too;\n#      also defines -D_REENTRANT)\n#      ... -mt is also the pthreads flag for HP/aCC\n# pthread: Linux, etcetera\n# --thread-safe: KAI C++\n# pthread-config: use pthread-config program (for GNU Pth library)\n\ncase \"${host_cpu}-${host_os}\" in\n        *solaris*)\n\n        # On Solaris (at least, for some versions), libc contains stubbed\n        # (non-functional) versions of the pthreads routines, so link-based\n        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/\n        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather\n        # a function called by this macro, so we could check for that, but\n        # who knows whether they'll stub that too in a future libc.)  So,\n        # we'll just look for -pthreads and -lpthread first:\n\n        acx_pthread_flags=\"-pthreads pthread -mt -pthread $acx_pthread_flags\"\n        ;;\nesac\n\nif test x\"$acx_pthread_ok\" = xno; then\nfor flag in $acx_pthread_flags; do\n\n        case $flag in\n                none)\n                AC_MSG_CHECKING([whether pthreads work without any flags])\n                ;;\n\n                -*)\n                AC_MSG_CHECKING([whether pthreads work with $flag])\n                PTHREAD_CFLAGS=\"$flag\"\n                ;;\n\n\t\tpthread-config)\n\t\tAC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)\n\t\tif test x\"$acx_pthread_config\" = xno; then continue; fi\n\t\tPTHREAD_CFLAGS=\"`pthread-config --cflags`\"\n\t\tPTHREAD_LIBS=\"`pthread-config --ldflags` `pthread-config --libs`\"\n\t\t;;\n\n                *)\n                AC_MSG_CHECKING([for the pthreads library -l$flag])\n                PTHREAD_LIBS=\"-l$flag\"\n                ;;\n        esac\n\n        save_LIBS=\"$LIBS\"\n        save_CFLAGS=\"$CFLAGS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n\n        # Check for various functions.  We must include pthread.h,\n        # since some functions may be macros.  (On the Sequent, we\n        # need a special flag -Kthread to make this header compile.)\n        # We check for pthread_join because it is in -lpthread on IRIX\n        # while pthread_create is in libc.  We check for pthread_attr_init\n        # due to DEC craziness with -lpthreads.  We check for\n        # pthread_cleanup_push because it is one of the few pthread\n        # functions on Solaris that doesn't have a non-functional libc stub.\n        # We try pthread_create on general principles.\n        AC_TRY_LINK([#include <pthread.h>],\n                    [pthread_t th; pthread_join(th, 0);\n                     pthread_attr_init(0); pthread_cleanup_push(0, 0);\n                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],\n                    [acx_pthread_ok=yes])\n\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\n\n        AC_MSG_RESULT($acx_pthread_ok)\n        if test \"x$acx_pthread_ok\" = xyes; then\n                break;\n        fi\n\n        PTHREAD_LIBS=\"\"\n        PTHREAD_CFLAGS=\"\"\ndone\nfi\n\n# Various other checks:\nif test \"x$acx_pthread_ok\" = xyes; then\n        save_LIBS=\"$LIBS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        save_CFLAGS=\"$CFLAGS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n\n        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.\n\tAC_MSG_CHECKING([for joinable pthread attribute])\n\tattr_name=unknown\n\tfor attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do\n\t    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],\n                        [attr_name=$attr; break])\n\tdone\n        AC_MSG_RESULT($attr_name)\n        if test \"$attr_name\" != PTHREAD_CREATE_JOINABLE; then\n            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,\n                               [Define to necessary symbol if this constant\n                                uses a non-standard name on your system.])\n        fi\n\n        AC_MSG_CHECKING([if more special flags are required for pthreads])\n        flag=no\n        case \"${host_cpu}-${host_os}\" in\n            *-aix* | *-freebsd* | *-darwin*) flag=\"-D_THREAD_SAFE\";;\n            *solaris* | *-osf* | *-hpux*) flag=\"-D_REENTRANT\";;\n        esac\n        AC_MSG_RESULT(${flag})\n        if test \"x$flag\" != xno; then\n            PTHREAD_CFLAGS=\"$flag $PTHREAD_CFLAGS\"\n        fi\n\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\n        # More AIX lossage: must compile with xlc_r or cc_r\n\tif test x\"$GCC\" != xyes; then\n          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})\n        else\n          PTHREAD_CC=$CC\n\tfi\n\n\t# The next part tries to detect GCC inconsistency with -shared on some\n\t# architectures and systems. The problem is that in certain\n\t# configurations, when -shared is specified, GCC \"forgets\" to\n\t# internally use various flags which are still necessary.\n\t\n\t#\n\t# Prepare the flags\n\t#\n\tsave_CFLAGS=\"$CFLAGS\"\n\tsave_LIBS=\"$LIBS\"\n\tsave_CC=\"$CC\"\n\t\n\t# Try with the flags determined by the earlier checks.\n\t#\n\t# -Wl,-z,defs forces link-time symbol resolution, so that the\n\t# linking checks with -shared actually have any value\n\t#\n\t# FIXME: -fPIC is required for -shared on many architectures,\n\t# so we specify it here, but the right way would probably be to\n\t# properly detect whether it is actually required.\n\tCFLAGS=\"-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS\"\n\tLIBS=\"$PTHREAD_LIBS $LIBS\"\n\tCC=\"$PTHREAD_CC\"\n\t\n\t# In order not to create several levels of indentation, we test\n\t# the value of \"$done\" until we find the cure or run out of ideas.\n\tdone=\"no\"\n\t\n\t# First, make sure the CFLAGS we added are actually accepted by our\n\t# compiler.  If not (and OS X's ld, for instance, does not accept -z),\n\t# then we can't do this test.\n\tif test x\"$done\" = xno; then\n\t   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])\n\t   AC_TRY_LINK(,, , [done=yes])\n\t\n\t   if test \"x$done\" = xyes ; then\n\t      AC_MSG_RESULT([no])\n\t   else\n\t      AC_MSG_RESULT([yes])\n\t   fi\n\tfi\n\t\n\tif test x\"$done\" = xno; then\n\t   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])\n\t   AC_TRY_LINK([#include <pthread.h>],\n\t      [pthread_t th; pthread_join(th, 0);\n\t      pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],\n\t      [done=yes])\n\t   \n\t   if test \"x$done\" = xyes; then\n\t      AC_MSG_RESULT([yes])\n\t   else\n\t      AC_MSG_RESULT([no])\n\t   fi\n\tfi\n\t\n\t#\n\t# Linux gcc on some architectures such as mips/mipsel forgets\n\t# about -lpthread\n\t#\n\tif test x\"$done\" = xno; then\n\t   AC_MSG_CHECKING([whether -lpthread fixes that])\n\t   LIBS=\"-lpthread $PTHREAD_LIBS $save_LIBS\"\n\t   AC_TRY_LINK([#include <pthread.h>],\n\t      [pthread_t th; pthread_join(th, 0);\n\t      pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],\n\t      [done=yes])\n\t\n\t   if test \"x$done\" = xyes; then\n\t      AC_MSG_RESULT([yes])\n\t      PTHREAD_LIBS=\"-lpthread $PTHREAD_LIBS\"\n\t   else\n\t      AC_MSG_RESULT([no])\n\t   fi\n\tfi\n\t#\n\t# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc\n\t#\n\tif test x\"$done\" = xno; then\n\t   AC_MSG_CHECKING([whether -lc_r fixes that])\n\t   LIBS=\"-lc_r $PTHREAD_LIBS $save_LIBS\"\n\t   AC_TRY_LINK([#include <pthread.h>],\n\t       [pthread_t th; pthread_join(th, 0);\n\t        pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],\n\t       [done=yes])\n\t\n\t   if test \"x$done\" = xyes; then\n\t      AC_MSG_RESULT([yes])\n\t      PTHREAD_LIBS=\"-lc_r $PTHREAD_LIBS\"\n\t   else\n\t      AC_MSG_RESULT([no])\n\t   fi\n\tfi\n\tif test x\"$done\" = xno; then\n\t   # OK, we have run out of ideas\n\t   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])\n\t\n\t   # so it's not safe to assume that we may use pthreads\n\t   acx_pthread_ok=no\n\tfi\n\t\n\tAC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib])\n\tCFLAGS=\"-nostdlib $CFLAGS\"\n\t# we need c with nostdlib\n\tLIBS=\"$LIBS -lc\"\n\tAC_TRY_LINK([#include <pthread.h>],\n\t      [pthread_t th; pthread_join(th, 0);\n\t       pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t       pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],\n\t      [done=yes],[done=no])\n\n\tif test \"x$done\" = xyes; then\n\t   AC_MSG_RESULT([yes])\n\telse\n\t   AC_MSG_RESULT([no])\n\tfi\n\t\n\tif test x\"$done\" = xno; then\n\t   AC_MSG_CHECKING([whether -lpthread saves the day])\n\t   LIBS=\"-lpthread $LIBS\"\n\t   AC_TRY_LINK([#include <pthread.h>],\n\t      [pthread_t th; pthread_join(th, 0);\n\t       pthread_attr_init(0); pthread_cleanup_push(0, 0);\n\t       pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],\n\t      [done=yes],[done=no])\n\n\t   if test \"x$done\" = xyes; then\n\t      AC_MSG_RESULT([yes])\n\t      PTHREAD_LIBS=\"$PTHREAD_LIBS -lpthread\"\n\t   else\n\t      AC_MSG_RESULT([no])\n\t      AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib])\n\t   fi\n\tfi\n\n\tCFLAGS=\"$save_CFLAGS\"\n\tLIBS=\"$save_LIBS\"\n\tCC=\"$save_CC\"\nelse\n        PTHREAD_CC=\"$CC\"\nfi\n\nAC_SUBST(PTHREAD_LIBS)\nAC_SUBST(PTHREAD_CFLAGS)\nAC_SUBST(PTHREAD_CC)\n\n# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:\nif test x\"$acx_pthread_ok\" = xyes; then\n        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])\n        :\nelse\n        acx_pthread_ok=no\n        $2\nfi\nAC_LANG_RESTORE\n])dnl ACX_PTHREAD\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/compiler_characteristics.m4",
    "content": "# Check compiler characteristics (e.g. type sizes, PRIxx macros, ...)\n\n# If types $1 and $2 are compatible, perform action $3\nAC_DEFUN([AC_TYPES_COMPATIBLE],\n  [AC_TRY_COMPILE([#include <stddef.h>], [$1 v1 = 0; $2 v2 = 0; return (&v1 - &v2)], $3)])\n\ndefine(AC_PRIUS_COMMENT, [printf format code for printing a size_t and ssize_t])\n\nAC_DEFUN([AC_COMPILER_CHARACTERISTICS],\n  [AC_CACHE_CHECK(AC_PRIUS_COMMENT, ac_cv_formatting_prius_prefix,\n    [AC_TYPES_COMPATIBLE(unsigned int, size_t, \n\t                 ac_cv_formatting_prius_prefix=; ac_cv_prius_defined=1)\n     AC_TYPES_COMPATIBLE(unsigned long, size_t,\n\t                 ac_cv_formatting_prius_prefix=l; ac_cv_prius_defined=1)\n     AC_TYPES_COMPATIBLE(unsigned long long, size_t,\n                         ac_cv_formatting_prius_prefix=ll; ac_cv_prius_defined=1\n     )])\n   if test -z \"$ac_cv_prius_defined\"; then \n      ac_cv_formatting_prius_prefix=z;\n   fi\n   AC_DEFINE_UNQUOTED(PRIuS, \"${ac_cv_formatting_prius_prefix}u\", AC_PRIUS_COMMENT)\n   AC_DEFINE_UNQUOTED(PRIxS, \"${ac_cv_formatting_prius_prefix}x\", AC_PRIUS_COMMENT)\n   AC_DEFINE_UNQUOTED(PRIdS, \"${ac_cv_formatting_prius_prefix}d\", AC_PRIUS_COMMENT)\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/install_prefix.m4",
    "content": "AC_DEFUN([AC_INSTALL_PREFIX],\n  [ac_cv_install_prefix=\"$prefix\";\n   if test x\"$ac_cv_install_prefix\" = x\"NONE\" ; then\n     ac_cv_install_prefix=\"$ac_default_prefix\";\n   fi\n   AC_DEFINE_UNQUOTED(INSTALL_PREFIX, \"$ac_cv_install_prefix\",\n     [prefix where we look for installed files])\n   ])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/libtool.m4",
    "content": "# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-\n#\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008 Free Software Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\nm4_define([_LT_COPYING], [dnl\n#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,\n#                 2006, 2007, 2008 Free Software Foundation, Inc.\n#   Written by Gordon Matzigkeit, 1996\n#\n#   This file is part of GNU Libtool.\n#\n# GNU Libtool is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# As a special exception to the GNU General Public License,\n# if you distribute this file as part of a program or library that\n# is built using GNU Libtool, you may include this file under the\n# same distribution terms that you use for the rest of that program.\n#\n# GNU Libtool is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with GNU Libtool; see the file COPYING.  If not, a copy\n# can be downloaded from http://www.gnu.org/licenses/gpl.html, or\n# obtained by writing to the Free Software Foundation, Inc.,\n# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n])\n\n# serial 56 LT_INIT\n\n\n# LT_PREREQ(VERSION)\n# ------------------\n# Complain and exit if this libtool version is less that VERSION.\nm4_defun([LT_PREREQ],\n[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,\n       [m4_default([$3],\n\t\t   [m4_fatal([Libtool version $1 or higher is required],\n\t\t             63)])],\n       [$2])])\n\n\n# _LT_CHECK_BUILDDIR\n# ------------------\n# Complain if the absolute build directory name contains unusual characters\nm4_defun([_LT_CHECK_BUILDDIR],\n[case `pwd` in\n  *\\ * | *\\\t*)\n    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;\nesac\n])\n\n\n# LT_INIT([OPTIONS])\n# ------------------\nAC_DEFUN([LT_INIT],\n[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT\nAC_BEFORE([$0], [LT_LANG])dnl\nAC_BEFORE([$0], [LT_OUTPUT])dnl\nAC_BEFORE([$0], [LTDL_INIT])dnl\nm4_require([_LT_CHECK_BUILDDIR])dnl\n\ndnl Autoconf doesn't catch unexpanded LT_ macros by default:\nm4_pattern_forbid([^_?LT_[A-Z_]+$])dnl\nm4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl\ndnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4\ndnl unless we require an AC_DEFUNed macro:\nAC_REQUIRE([LTOPTIONS_VERSION])dnl\nAC_REQUIRE([LTSUGAR_VERSION])dnl\nAC_REQUIRE([LTVERSION_VERSION])dnl\nAC_REQUIRE([LTOBSOLETE_VERSION])dnl\nm4_require([_LT_PROG_LTMAIN])dnl\n\ndnl Parse OPTIONS\n_LT_SET_OPTIONS([$0], [$1])\n\n# This can be used to rebuild libtool when needed\nLIBTOOL_DEPS=\"$ltmain\"\n\n# Always use our own libtool.\nLIBTOOL='$(SHELL) $(top_builddir)/libtool'\nAC_SUBST(LIBTOOL)dnl\n\n_LT_SETUP\n\n# Only expand once:\nm4_define([LT_INIT])\n])# LT_INIT\n\n# Old names:\nAU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])\nAU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_PROG_LIBTOOL], [])\ndnl AC_DEFUN([AM_PROG_LIBTOOL], [])\n\n\n# _LT_CC_BASENAME(CC)\n# -------------------\n# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.\nm4_defun([_LT_CC_BASENAME],\n[for cc_temp in $1\"\"; do\n  case $cc_temp in\n    compile | *[[\\\\/]]compile | ccache | *[[\\\\/]]ccache ) ;;\n    distcc | *[[\\\\/]]distcc | purify | *[[\\\\/]]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`$ECHO \"X$cc_temp\" | $Xsed -e 's%.*/%%' -e \"s%^$host_alias-%%\"`\n])\n\n\n# _LT_FILEUTILS_DEFAULTS\n# ----------------------\n# It is okay to use these file commands and assume they have been set\n# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.\nm4_defun([_LT_FILEUTILS_DEFAULTS],\n[: ${CP=\"cp -f\"}\n: ${MV=\"mv -f\"}\n: ${RM=\"rm -f\"}\n])# _LT_FILEUTILS_DEFAULTS\n\n\n# _LT_SETUP\n# ---------\nm4_defun([_LT_SETUP],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_CANONICAL_BUILD])dnl\n_LT_DECL([], [host_alias], [0], [The host system])dnl\n_LT_DECL([], [host], [0])dnl\n_LT_DECL([], [host_os], [0])dnl\ndnl\n_LT_DECL([], [build_alias], [0], [The build system])dnl\n_LT_DECL([], [build], [0])dnl\n_LT_DECL([], [build_os], [0])dnl\ndnl\nAC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([LT_PATH_LD])dnl\nAC_REQUIRE([LT_PATH_NM])dnl\ndnl\nAC_REQUIRE([AC_PROG_LN_S])dnl\ntest -z \"$LN_S\" && LN_S=\"ln -s\"\n_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl\ndnl\nAC_REQUIRE([LT_CMD_MAX_LEN])dnl\n_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally \"o\")])dnl\n_LT_DECL([], [exeext], [0], [Executable file suffix (normally \"\")])dnl\ndnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_CHECK_SHELL_FEATURES])dnl\nm4_require([_LT_CMD_RELOAD])dnl\nm4_require([_LT_CHECK_MAGIC_METHOD])dnl\nm4_require([_LT_CMD_OLD_ARCHIVE])dnl\nm4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl\n\n_LT_CONFIG_LIBTOOL_INIT([\n# See if we are running on zsh, and set the options which allow our\n# commands through without removal of \\ escapes INIT.\nif test -n \"\\${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n])\nif test -n \"${ZSH_VERSION+set}\" ; then\n   setopt NO_GLOB_SUBST\nfi\n\n_LT_CHECK_OBJDIR\n\nm4_require([_LT_TAG_COMPILER])dnl\n_LT_PROG_ECHO_BACKSLASH\n\ncase $host_os in\naix3*)\n  # AIX sometimes has problems with the GCC collect2 program.  For some\n  # reason, if we set the COLLECT_NAMES environment variable, the problems\n  # vanish in a puff of smoke.\n  if test \"X${COLLECT_NAMES+set}\" != Xset; then\n    COLLECT_NAMES=\n    export COLLECT_NAMES\n  fi\n  ;;\nesac\n\n# Sed substitution that helps us do robust quoting.  It backslashifies\n# metacharacters that are still active within double-quoted strings.\nsed_quote_subst='s/\\([[\"`$\\\\]]\\)/\\\\\\1/g'\n\n# Same as above, but do not quote variable references.\ndouble_quote_subst='s/\\([[\"`\\\\]]\\)/\\\\\\1/g'\n\n# Sed substitution to delay expansion of an escaped shell variable in a\n# double_quote_subst'ed string.\ndelay_variable_subst='s/\\\\\\\\\\\\\\\\\\\\\\$/\\\\\\\\\\\\$/g'\n\n# Sed substitution to delay expansion of an escaped single quote.\ndelay_single_quote_subst='s/'\\''/'\\'\\\\\\\\\\\\\\'\\''/g'\n\n# Sed substitution to avoid accidental globbing in evaled expressions\nno_glob_subst='s/\\*/\\\\\\*/g'\n\n# Global variables:\nofile=libtool\ncan_build_shared=yes\n\n# All known linkers require a `.a' archive for static linking (except MSVC,\n# which needs '.lib').\nlibext=a\n\nwith_gnu_ld=\"$lt_cv_prog_gnu_ld\"\n\nold_CC=\"$CC\"\nold_CFLAGS=\"$CFLAGS\"\n\n# Set sane defaults for various variables\ntest -z \"$CC\" && CC=cc\ntest -z \"$LTCC\" && LTCC=$CC\ntest -z \"$LTCFLAGS\" && LTCFLAGS=$CFLAGS\ntest -z \"$LD\" && LD=ld\ntest -z \"$ac_objext\" && ac_objext=o\n\n_LT_CC_BASENAME([$compiler])\n\n# Only perform the check for file, if the check method requires it\ntest -z \"$MAGIC_CMD\" && MAGIC_CMD=file\ncase $deplibs_check_method in\nfile_magic*)\n  if test \"$file_magic_cmd\" = '$MAGIC_CMD'; then\n    _LT_PATH_MAGIC\n  fi\n  ;;\nesac\n\n# Use C for the default configuration in the libtool script\nLT_SUPPORTED_TAG([CC])\n_LT_LANG_C_CONFIG\n_LT_LANG_DEFAULT_CONFIG\n_LT_CONFIG_COMMANDS\n])# _LT_SETUP\n\n\n# _LT_PROG_LTMAIN\n# ---------------\n# Note that this code is called both from `configure', and `config.status'\n# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,\n# `config.status' has no value for ac_aux_dir unless we are using Automake,\n# so we pass a copy along to make sure it has a sensible value anyway.\nm4_defun([_LT_PROG_LTMAIN],\n[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl\n_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])\nltmain=\"$ac_aux_dir/ltmain.sh\"\n])# _LT_PROG_LTMAIN\n\n\n## ------------------------------------- ##\n## Accumulate code for creating libtool. ##\n## ------------------------------------- ##\n\n# So that we can recreate a full libtool script including additional\n# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS\n# in macros and then make a single call at the end using the `libtool'\n# label.\n\n\n# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])\n# ----------------------------------------\n# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.\nm4_define([_LT_CONFIG_LIBTOOL_INIT],\n[m4_ifval([$1],\n          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],\n                     [$1\n])])])\n\n# Initialize.\nm4_define([_LT_OUTPUT_LIBTOOL_INIT])\n\n\n# _LT_CONFIG_LIBTOOL([COMMANDS])\n# ------------------------------\n# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.\nm4_define([_LT_CONFIG_LIBTOOL],\n[m4_ifval([$1],\n          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],\n                     [$1\n])])])\n\n# Initialize.\nm4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])\n\n\n# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])\n# -----------------------------------------------------\nm4_defun([_LT_CONFIG_SAVE_COMMANDS],\n[_LT_CONFIG_LIBTOOL([$1])\n_LT_CONFIG_LIBTOOL_INIT([$2])\n])\n\n\n# _LT_FORMAT_COMMENT([COMMENT])\n# -----------------------------\n# Add leading comment marks to the start of each line, and a trailing\n# full-stop to the whole comment if one is not present already.\nm4_define([_LT_FORMAT_COMMENT],\n[m4_ifval([$1], [\nm4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],\n              [['`$\\]], [\\\\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])\n)])\n\n\n\n## ------------------------ ##\n## FIXME: Eliminate VARNAME ##\n## ------------------------ ##\n\n\n# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])\n# -------------------------------------------------------------------\n# CONFIGNAME is the name given to the value in the libtool script.\n# VARNAME is the (base) name used in the configure script.\n# VALUE may be 0, 1 or 2 for a computed quote escaped value based on\n# VARNAME.  Any other value will be used directly.\nm4_define([_LT_DECL],\n[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],\n    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],\n\t[m4_ifval([$1], [$1], [$2])])\n    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])\n    m4_ifval([$4],\n\t[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])\n    lt_dict_add_subkey([lt_decl_dict], [$2],\n\t[tagged?], [m4_ifval([$5], [yes], [no])])])\n])\n\n\n# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])\n# --------------------------------------------------------\nm4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])\n\n\n# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])\n# ------------------------------------------------\nm4_define([lt_decl_tag_varnames],\n[_lt_decl_filter([tagged?], [yes], $@)])\n\n\n# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])\n# ---------------------------------------------------------\nm4_define([_lt_decl_filter],\n[m4_case([$#],\n  [0], [m4_fatal([$0: too few arguments: $#])],\n  [1], [m4_fatal([$0: too few arguments: $#: $1])],\n  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],\n  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],\n  [lt_dict_filter([lt_decl_dict], $@)])[]dnl\n])\n\n\n# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])\n# --------------------------------------------------\nm4_define([lt_decl_quote_varnames],\n[_lt_decl_filter([value], [1], $@)])\n\n\n# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])\n# ---------------------------------------------------\nm4_define([lt_decl_dquote_varnames],\n[_lt_decl_filter([value], [2], $@)])\n\n\n# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])\n# ---------------------------------------------------\nm4_define([lt_decl_varnames_tagged],\n[m4_assert([$# <= 2])dnl\n_$0(m4_quote(m4_default([$1], [[, ]])),\n    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),\n    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])\nm4_define([_lt_decl_varnames_tagged],\n[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])\n\n\n# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])\n# ------------------------------------------------\nm4_define([lt_decl_all_varnames],\n[_$0(m4_quote(m4_default([$1], [[, ]])),\n     m4_if([$2], [],\n\t   m4_quote(lt_decl_varnames),\n\tm4_quote(m4_shift($@))))[]dnl\n])\nm4_define([_lt_decl_all_varnames],\n[lt_join($@, lt_decl_varnames_tagged([$1],\n\t\t\tlt_decl_tag_varnames([[, ]], m4_shift($@))))dnl\n])\n\n\n# _LT_CONFIG_STATUS_DECLARE([VARNAME])\n# ------------------------------------\n# Quote a variable value, and forward it to `config.status' so that its\n# declaration there will have the same value as in `configure'.  VARNAME\n# must have a single quote delimited value for this to work.\nm4_define([_LT_CONFIG_STATUS_DECLARE],\n[$1='`$ECHO \"X$][$1\" | $Xsed -e \"$delay_single_quote_subst\"`'])\n\n\n# _LT_CONFIG_STATUS_DECLARATIONS\n# ------------------------------\n# We delimit libtool config variables with single quotes, so when\n# we write them to config.status, we have to be sure to quote all\n# embedded single quotes properly.  In configure, this macro expands\n# each variable declared with _LT_DECL (and _LT_TAGDECL) into:\n#\n#    <var>='`$ECHO \"X$<var>\" | $Xsed -e \"$delay_single_quote_subst\"`'\nm4_defun([_LT_CONFIG_STATUS_DECLARATIONS],\n[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),\n    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])\n\n\n# _LT_LIBTOOL_TAGS\n# ----------------\n# Output comment and list of tags supported by the script\nm4_defun([_LT_LIBTOOL_TAGS],\n[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl\navailable_tags=\"_LT_TAGS\"dnl\n])\n\n\n# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])\n# -----------------------------------\n# Extract the dictionary values for VARNAME (optionally with TAG) and\n# expand to a commented shell variable setting:\n#\n#    # Some comment about what VAR is for.\n#    visible_name=$lt_internal_name\nm4_define([_LT_LIBTOOL_DECLARE],\n[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],\n\t\t\t\t\t   [description])))[]dnl\nm4_pushdef([_libtool_name],\n    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl\nm4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),\n    [0], [_libtool_name=[$]$1],\n    [1], [_libtool_name=$lt_[]$1],\n    [2], [_libtool_name=$lt_[]$1],\n    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl\nm4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl\n])\n\n\n# _LT_LIBTOOL_CONFIG_VARS\n# -----------------------\n# Produce commented declarations of non-tagged libtool config variables\n# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'\n# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG\n# section) are produced by _LT_LIBTOOL_TAG_VARS.\nm4_defun([_LT_LIBTOOL_CONFIG_VARS],\n[m4_foreach([_lt_var],\n    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),\n    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])\n\n\n# _LT_LIBTOOL_TAG_VARS(TAG)\n# -------------------------\nm4_define([_LT_LIBTOOL_TAG_VARS],\n[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),\n    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])\n\n\n# _LT_TAGVAR(VARNAME, [TAGNAME])\n# ------------------------------\nm4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])\n\n\n# _LT_CONFIG_COMMANDS\n# -------------------\n# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of\n# variables for single and double quote escaping we saved from calls\n# to _LT_DECL, we can put quote escaped variables declarations\n# into `config.status', and then the shell code to quote escape them in\n# for loops in `config.status'.  Finally, any additional code accumulated\n# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.\nm4_defun([_LT_CONFIG_COMMANDS],\n[AC_PROVIDE_IFELSE([LT_OUTPUT],\n\tdnl If the libtool generation code has been placed in $CONFIG_LT,\n\tdnl instead of duplicating it all over again into config.status,\n\tdnl then we will have config.status run $CONFIG_LT later, so it\n\tdnl needs to know what name is stored there:\n        [AC_CONFIG_COMMANDS([libtool],\n            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],\n    dnl If the libtool generation code is destined for config.status,\n    dnl expand the accumulated commands and init code now:\n    [AC_CONFIG_COMMANDS([libtool],\n        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])\n])#_LT_CONFIG_COMMANDS\n\n\n# Initialize.\nm4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],\n[\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nsed_quote_subst='$sed_quote_subst'\ndouble_quote_subst='$double_quote_subst'\ndelay_variable_subst='$delay_variable_subst'\n_LT_CONFIG_STATUS_DECLARATIONS\nLTCC='$LTCC'\nLTCFLAGS='$LTCFLAGS'\ncompiler='$compiler_DEFAULT'\n\n# Quote evaled strings.\nfor var in lt_decl_all_varnames([[ \\\n]], lt_decl_quote_varnames); do\n    case \\`eval \\\\\\\\\\$ECHO \"X\\\\\\\\\\$\\$var\"\\` in\n    *[[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"X\\\\\\$\\$var\\\\\" | \\\\\\$Xsed -e \\\\\"\\\\\\$sed_quote_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n# Double-quote double-evaled strings.\nfor var in lt_decl_all_varnames([[ \\\n]], lt_decl_dquote_varnames); do\n    case \\`eval \\\\\\\\\\$ECHO \"X\\\\\\\\\\$\\$var\"\\` in\n    *[[\\\\\\\\\\\\\\`\\\\\"\\\\\\$]]*)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\`\\\\\\$ECHO \\\\\"X\\\\\\$\\$var\\\\\" | \\\\\\$Xsed -e \\\\\"\\\\\\$double_quote_subst\\\\\" -e \\\\\"\\\\\\$sed_quote_subst\\\\\" -e \\\\\"\\\\\\$delay_variable_subst\\\\\"\\\\\\`\\\\\\\\\\\\\"\"\n      ;;\n    *)\n      eval \"lt_\\$var=\\\\\\\\\\\\\"\\\\\\$\\$var\\\\\\\\\\\\\"\"\n      ;;\n    esac\ndone\n\n# Fix-up fallback echo if it was mangled by the above quoting rules.\ncase \\$lt_ECHO in\n*'\\\\\\[$]0 --fallback-echo\"')dnl \"\n  lt_ECHO=\\`\\$ECHO \"X\\$lt_ECHO\" | \\$Xsed -e 's/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[$]0 --fallback-echo\"\\[$]/\\[$]0 --fallback-echo\"/'\\`\n  ;;\nesac\n\n_LT_OUTPUT_LIBTOOL_INIT\n])\n\n\n# LT_OUTPUT\n# ---------\n# This macro allows early generation of the libtool script (before\n# AC_OUTPUT is called), incase it is used in configure for compilation\n# tests.\nAC_DEFUN([LT_OUTPUT],\n[: ${CONFIG_LT=./config.lt}\nAC_MSG_NOTICE([creating $CONFIG_LT])\ncat >\"$CONFIG_LT\" <<_LTEOF\n#! $SHELL\n# Generated by $as_me.\n# Run this file to recreate a libtool stub with the current configuration.\n\nlt_cl_silent=false\nSHELL=\\${CONFIG_SHELL-$SHELL}\n_LTEOF\n\ncat >>\"$CONFIG_LT\" <<\\_LTEOF\nAS_SHELL_SANITIZE\n_AS_PREPARE\n\nexec AS_MESSAGE_FD>&1\nexec AS_MESSAGE_LOG_FD>>config.log\n{\n  echo\n  AS_BOX([Running $as_me.])\n} >&AS_MESSAGE_LOG_FD\n\nlt_cl_help=\"\\\n\\`$as_me' creates a local libtool stub from the current configuration,\nfor use in further configure time tests before the real libtool is\ngenerated.\n\nUsage: $[0] [[OPTIONS]]\n\n  -h, --help      print this help, then exit\n  -V, --version   print version number, then exit\n  -q, --quiet     do not print progress messages\n  -d, --debug     don't remove temporary files\n\nReport bugs to <bug-libtool@gnu.org>.\"\n\nlt_cl_version=\"\\\nm4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl\nm4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])\nconfigured by $[0], generated by m4_PACKAGE_STRING.\n\nCopyright (C) 2008 Free Software Foundation, Inc.\nThis config.lt script is free software; the Free Software Foundation\ngives unlimited permision to copy, distribute and modify it.\"\n\nwhile test $[#] != 0\ndo\n  case $[1] in\n    --version | --v* | -V )\n      echo \"$lt_cl_version\"; exit 0 ;;\n    --help | --h* | -h )\n      echo \"$lt_cl_help\"; exit 0 ;;\n    --debug | --d* | -d )\n      debug=: ;;\n    --quiet | --q* | --silent | --s* | -q )\n      lt_cl_silent=: ;;\n\n    -*) AC_MSG_ERROR([unrecognized option: $[1]\nTry \\`$[0] --help' for more information.]) ;;\n\n    *) AC_MSG_ERROR([unrecognized argument: $[1]\nTry \\`$[0] --help' for more information.]) ;;\n  esac\n  shift\ndone\n\nif $lt_cl_silent; then\n  exec AS_MESSAGE_FD>/dev/null\nfi\n_LTEOF\n\ncat >>\"$CONFIG_LT\" <<_LTEOF\n_LT_OUTPUT_LIBTOOL_COMMANDS_INIT\n_LTEOF\n\ncat >>\"$CONFIG_LT\" <<\\_LTEOF\nAC_MSG_NOTICE([creating $ofile])\n_LT_OUTPUT_LIBTOOL_COMMANDS\nAS_EXIT(0)\n_LTEOF\nchmod +x \"$CONFIG_LT\"\n\n# configure is writing to config.log, but config.lt does its own redirection,\n# appending to config.log, which fails on DOS, as config.log is still kept\n# open by configure.  Here we exec the FD to /dev/null, effectively closing\n# config.log, so it can be properly (re)opened and appended to by config.lt.\nif test \"$no_create\" != yes; then\n  lt_cl_success=:\n  test \"$silent\" = yes &&\n    lt_config_lt_args=\"$lt_config_lt_args --quiet\"\n  exec AS_MESSAGE_LOG_FD>/dev/null\n  $SHELL \"$CONFIG_LT\" $lt_config_lt_args || lt_cl_success=false\n  exec AS_MESSAGE_LOG_FD>>config.log\n  $lt_cl_success || AS_EXIT(1)\nfi\n])# LT_OUTPUT\n\n\n# _LT_CONFIG(TAG)\n# ---------------\n# If TAG is the built-in tag, create an initial libtool script with a\n# default configuration from the untagged config vars.  Otherwise add code\n# to config.status for appending the configuration named by TAG from the\n# matching tagged config vars.\nm4_defun([_LT_CONFIG],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\n_LT_CONFIG_SAVE_COMMANDS([\n  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl\n  m4_if(_LT_TAG, [C], [\n    # See if we are running on zsh, and set the options which allow our\n    # commands through without removal of \\ escapes.\n    if test -n \"${ZSH_VERSION+set}\" ; then\n      setopt NO_GLOB_SUBST\n    fi\n\n    cfgfile=\"${ofile}T\"\n    trap \"$RM \\\"$cfgfile\\\"; exit 1\" 1 2 15\n    $RM \"$cfgfile\"\n\n    cat <<_LT_EOF >> \"$cfgfile\"\n#! $SHELL\n\n# `$ECHO \"$ofile\" | sed 's%^.*/%%'` - Provide generalized library-building support services.\n# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION\n# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:\n# NOTE: Changes made to this file will be lost: look at ltmain.sh.\n#\n_LT_COPYING\n_LT_LIBTOOL_TAGS\n\n# ### BEGIN LIBTOOL CONFIG\n_LT_LIBTOOL_CONFIG_VARS\n_LT_LIBTOOL_TAG_VARS\n# ### END LIBTOOL CONFIG\n\n_LT_EOF\n\n  case $host_os in\n  aix3*)\n    cat <<\\_LT_EOF >> \"$cfgfile\"\n# AIX sometimes has problems with the GCC collect2 program.  For some\n# reason, if we set the COLLECT_NAMES environment variable, the problems\n# vanish in a puff of smoke.\nif test \"X${COLLECT_NAMES+set}\" != Xset; then\n  COLLECT_NAMES=\n  export COLLECT_NAMES\nfi\n_LT_EOF\n    ;;\n  esac\n\n  _LT_PROG_LTMAIN\n\n  # We use sed instead of cat because bash on DJGPP gets confused if\n  # if finds mixed CR/LF and LF-only lines.  Since sed operates in\n  # text mode, it properly converts lines to CR/LF.  This bash problem\n  # is reportedly fixed, but why not run on old versions too?\n  sed '/^# Generated shell functions inserted here/q' \"$ltmain\" >> \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\"; exit 1)\n\n  _LT_PROG_XSI_SHELLFNS\n\n  sed -n '/^# Generated shell functions inserted here/,$p' \"$ltmain\" >> \"$cfgfile\" \\\n    || (rm -f \"$cfgfile\"; exit 1)\n\n  mv -f \"$cfgfile\" \"$ofile\" ||\n    (rm -f \"$ofile\" && cp \"$cfgfile\" \"$ofile\" && rm -f \"$cfgfile\")\n  chmod +x \"$ofile\"\n],\n[cat <<_LT_EOF >> \"$ofile\"\n\ndnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded\ndnl in a comment (ie after a #).\n# ### BEGIN LIBTOOL TAG CONFIG: $1\n_LT_LIBTOOL_TAG_VARS(_LT_TAG)\n# ### END LIBTOOL TAG CONFIG: $1\n_LT_EOF\n])dnl /m4_if\n],\n[m4_if([$1], [], [\n    PACKAGE='$PACKAGE'\n    VERSION='$VERSION'\n    TIMESTAMP='$TIMESTAMP'\n    RM='$RM'\n    ofile='$ofile'], [])\n])dnl /_LT_CONFIG_SAVE_COMMANDS\n])# _LT_CONFIG\n\n\n# LT_SUPPORTED_TAG(TAG)\n# ---------------------\n# Trace this macro to discover what tags are supported by the libtool\n# --tag option, using:\n#    autoconf --trace 'LT_SUPPORTED_TAG:$1'\nAC_DEFUN([LT_SUPPORTED_TAG], [])\n\n\n# C support is built-in for now\nm4_define([_LT_LANG_C_enabled], [])\nm4_define([_LT_TAGS], [])\n\n\n# LT_LANG(LANG)\n# -------------\n# Enable libtool support for the given language if not already enabled.\nAC_DEFUN([LT_LANG],\n[AC_BEFORE([$0], [LT_OUTPUT])dnl\nm4_case([$1],\n  [C],\t\t\t[_LT_LANG(C)],\n  [C++],\t\t[_LT_LANG(CXX)],\n  [Java],\t\t[_LT_LANG(GCJ)],\n  [Fortran 77],\t\t[_LT_LANG(F77)],\n  [Fortran],\t\t[_LT_LANG(FC)],\n  [Windows Resource],\t[_LT_LANG(RC)],\n  [m4_ifdef([_LT_LANG_]$1[_CONFIG],\n    [_LT_LANG($1)],\n    [m4_fatal([$0: unsupported language: \"$1\"])])])dnl\n])# LT_LANG\n\n\n# _LT_LANG(LANGNAME)\n# ------------------\nm4_defun([_LT_LANG],\n[m4_ifdef([_LT_LANG_]$1[_enabled], [],\n  [LT_SUPPORTED_TAG([$1])dnl\n  m4_append([_LT_TAGS], [$1 ])dnl\n  m4_define([_LT_LANG_]$1[_enabled], [])dnl\n  _LT_LANG_$1_CONFIG($1)])dnl\n])# _LT_LANG\n\n\n# _LT_LANG_DEFAULT_CONFIG\n# -----------------------\nm4_defun([_LT_LANG_DEFAULT_CONFIG],\n[AC_PROVIDE_IFELSE([AC_PROG_CXX],\n  [LT_LANG(CXX)],\n  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])\n\nAC_PROVIDE_IFELSE([AC_PROG_F77],\n  [LT_LANG(F77)],\n  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])\n\nAC_PROVIDE_IFELSE([AC_PROG_FC],\n  [LT_LANG(FC)],\n  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])\n\ndnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal\ndnl pulling things in needlessly.\nAC_PROVIDE_IFELSE([AC_PROG_GCJ],\n  [LT_LANG(GCJ)],\n  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],\n    [LT_LANG(GCJ)],\n    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],\n      [LT_LANG(GCJ)],\n      [m4_ifdef([AC_PROG_GCJ],\n\t[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])\n       m4_ifdef([A][M_PROG_GCJ],\n\t[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])\n       m4_ifdef([LT_PROG_GCJ],\n\t[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])\n\nAC_PROVIDE_IFELSE([LT_PROG_RC],\n  [LT_LANG(RC)],\n  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])\n])# _LT_LANG_DEFAULT_CONFIG\n\n# Obsolete macros:\nAU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])\nAU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])\nAU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])\nAU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_CXX], [])\ndnl AC_DEFUN([AC_LIBTOOL_F77], [])\ndnl AC_DEFUN([AC_LIBTOOL_FC], [])\ndnl AC_DEFUN([AC_LIBTOOL_GCJ], [])\n\n\n# _LT_TAG_COMPILER\n# ----------------\nm4_defun([_LT_TAG_COMPILER],\n[AC_REQUIRE([AC_PROG_CC])dnl\n\n_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl\n_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl\n_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl\n_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl\n\n# If no C compiler was specified, use CC.\nLTCC=${LTCC-\"$CC\"}\n\n# If no C compiler flags were specified, use CFLAGS.\nLTCFLAGS=${LTCFLAGS-\"$CFLAGS\"}\n\n# Allow CC to be a program name with arguments.\ncompiler=$CC\n])# _LT_TAG_COMPILER\n\n\n# _LT_COMPILER_BOILERPLATE\n# ------------------------\n# Check for compiler boilerplate output or warnings with\n# the simple compiler test code.\nm4_defun([_LT_COMPILER_BOILERPLATE],\n[m4_require([_LT_DECL_SED])dnl\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_compile_test_code\" >conftest.$ac_ext\neval \"$ac_compile\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_compiler_boilerplate=`cat conftest.err`\n$RM conftest*\n])# _LT_COMPILER_BOILERPLATE\n\n\n# _LT_LINKER_BOILERPLATE\n# ----------------------\n# Check for linker boilerplate output or warnings with\n# the simple link test code.\nm4_defun([_LT_LINKER_BOILERPLATE],\n[m4_require([_LT_DECL_SED])dnl\nac_outfile=conftest.$ac_objext\necho \"$lt_simple_link_test_code\" >conftest.$ac_ext\neval \"$ac_link\" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err\n_lt_linker_boilerplate=`cat conftest.err`\n$RM -r conftest*\n])# _LT_LINKER_BOILERPLATE\n\n# _LT_REQUIRED_DARWIN_CHECKS\n# -------------------------\nm4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[\n  case $host_os in\n    rhapsody* | darwin*)\n    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])\n    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])\n    AC_CHECK_TOOL([LIPO], [lipo], [:])\n    AC_CHECK_TOOL([OTOOL], [otool], [:])\n    AC_CHECK_TOOL([OTOOL64], [otool64], [:])\n    _LT_DECL([], [DSYMUTIL], [1],\n      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])\n    _LT_DECL([], [NMEDIT], [1],\n      [Tool to change global to local symbols on Mac OS X])\n    _LT_DECL([], [LIPO], [1],\n      [Tool to manipulate fat objects and archives on Mac OS X])\n    _LT_DECL([], [OTOOL], [1],\n      [ldd/readelf like tool for Mach-O binaries on Mac OS X])\n    _LT_DECL([], [OTOOL64], [1],\n      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])\n\n    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],\n      [lt_cv_apple_cc_single_mod=no\n      if test -z \"${LT_MULTI_MODULE}\"; then\n\t# By default we will add the -single_module flag. You can override\n\t# by either setting the environment variable LT_MULTI_MODULE\n\t# non-empty at configure time, or by adding -multi_module to the\n\t# link flags.\n\trm -rf libconftest.dylib*\n\techo \"int foo(void){return 1;}\" > conftest.c\n\techo \"$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n-dynamiclib -Wl,-single_module conftest.c\" >&AS_MESSAGE_LOG_FD\n\t$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \\\n\t  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err\n        _lt_result=$?\n\tif test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then\n\t  lt_cv_apple_cc_single_mod=yes\n\telse\n\t  cat conftest.err >&AS_MESSAGE_LOG_FD\n\tfi\n\trm -rf libconftest.dylib*\n\trm -f conftest.*\n      fi])\n    AC_CACHE_CHECK([for -exported_symbols_list linker flag],\n      [lt_cv_ld_exported_symbols_list],\n      [lt_cv_ld_exported_symbols_list=no\n      save_LDFLAGS=$LDFLAGS\n      echo \"_main\" > conftest.sym\n      LDFLAGS=\"$LDFLAGS -Wl,-exported_symbols_list,conftest.sym\"\n      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],\n\t[lt_cv_ld_exported_symbols_list=yes],\n\t[lt_cv_ld_exported_symbols_list=no])\n\tLDFLAGS=\"$save_LDFLAGS\"\n    ])\n    case $host_os in\n    rhapsody* | darwin1.[[012]])\n      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;\n    darwin1.*)\n      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n    darwin*) # darwin 5.x on\n      # if running on 10.5 or later, the deployment target defaults\n      # to the OS version, if on x86, and 10.4, the deployment\n      # target defaults to 10.4. Don't you love it?\n      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in\n\t10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n\t10.[[012]]*)\n\t  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;\n\t10.*)\n\t  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;\n      esac\n    ;;\n  esac\n    if test \"$lt_cv_apple_cc_single_mod\" = \"yes\"; then\n      _lt_dar_single_mod='$single_module'\n    fi\n    if test \"$lt_cv_ld_exported_symbols_list\" = \"yes\"; then\n      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'\n    else\n      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'\n    fi\n    if test \"$DSYMUTIL\" != \":\"; then\n      _lt_dsymutil='~$DSYMUTIL $lib || :'\n    else\n      _lt_dsymutil=\n    fi\n    ;;\n  esac\n])\n\n\n# _LT_DARWIN_LINKER_FEATURES\n# --------------------------\n# Checks for linker and compiler features on darwin\nm4_defun([_LT_DARWIN_LINKER_FEATURES],\n[\n  m4_require([_LT_REQUIRED_DARWIN_CHECKS])\n  _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n  _LT_TAGVAR(hardcode_direct, $1)=no\n  _LT_TAGVAR(hardcode_automatic, $1)=yes\n  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported\n  _LT_TAGVAR(whole_archive_flag_spec, $1)=''\n  _LT_TAGVAR(link_all_deplibs, $1)=yes\n  _LT_TAGVAR(allow_undefined_flag, $1)=\"$_lt_dar_allow_undefined\"\n  case $cc_basename in\n     ifort*) _lt_dar_can_shared=yes ;;\n     *) _lt_dar_can_shared=$GCC ;;\n  esac\n  if test \"$_lt_dar_can_shared\" = \"yes\"; then\n    output_verbose_link_cmd=echo\n    _LT_TAGVAR(archive_cmds, $1)=\"\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring $_lt_dar_single_mod${_lt_dsymutil}\"\n    _LT_TAGVAR(module_cmds, $1)=\"\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dsymutil}\"\n    _LT_TAGVAR(archive_expsym_cmds, $1)=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\$libobjs \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}\"\n    _LT_TAGVAR(module_expsym_cmds, $1)=\"sed -e 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC \\$allow_undefined_flag -o \\$lib -bundle \\$libobjs \\$deplibs \\$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}\"\n    m4_if([$1], [CXX],\n[   if test \"$lt_cv_apple_cc_single_mod\" != \"yes\"; then\n      _LT_TAGVAR(archive_cmds, $1)=\"\\$CC -r -keep_private_externs -nostdlib -o \\${lib}-master.o \\$libobjs~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\${lib}-master.o \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring${_lt_dsymutil}\"\n      _LT_TAGVAR(archive_expsym_cmds, $1)=\"sed 's,^,_,' < \\$export_symbols > \\$output_objdir/\\${libname}-symbols.expsym~\\$CC -r -keep_private_externs -nostdlib -o \\${lib}-master.o \\$libobjs~\\$CC -dynamiclib \\$allow_undefined_flag -o \\$lib \\${lib}-master.o \\$deplibs \\$compiler_flags -install_name \\$rpath/\\$soname \\$verstring${_lt_dar_export_syms}${_lt_dsymutil}\"\n    fi\n],[])\n  else\n  _LT_TAGVAR(ld_shlibs, $1)=no\n  fi\n])\n\n# _LT_SYS_MODULE_PATH_AIX\n# -----------------------\n# Links a minimal program and checks the executable\n# for the system default hardcoded library path. In most cases,\n# this is /usr/lib:/lib, but when the MPI compilers are used\n# the location of the communication and MPI libs are included too.\n# If we don't find anything, use the default library path according\n# to the aix ld manual.\nm4_defun([_LT_SYS_MODULE_PATH_AIX],\n[m4_require([_LT_DECL_SED])dnl\nAC_LINK_IFELSE(AC_LANG_PROGRAM,[\nlt_aix_libpath_sed='\n    /Import File Strings/,/^$/ {\n\t/^0/ {\n\t    s/^0  *\\(.*\\)$/\\1/\n\t    p\n\t}\n    }'\naix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\n# Check for a 64-bit object if we didn't find anything.\nif test -z \"$aix_libpath\"; then\n  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e \"$lt_aix_libpath_sed\"`\nfi],[])\nif test -z \"$aix_libpath\"; then aix_libpath=\"/usr/lib:/lib\"; fi\n])# _LT_SYS_MODULE_PATH_AIX\n\n\n# _LT_SHELL_INIT(ARG)\n# -------------------\nm4_define([_LT_SHELL_INIT],\n[ifdef([AC_DIVERSION_NOTICE],\n\t     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],\n\t [AC_DIVERT_PUSH(NOTICE)])\n$1\nAC_DIVERT_POP\n])# _LT_SHELL_INIT\n\n\n# _LT_PROG_ECHO_BACKSLASH\n# -----------------------\n# Add some code to the start of the generated configure script which\n# will find an echo command which doesn't interpret backslashes.\nm4_defun([_LT_PROG_ECHO_BACKSLASH],\n[_LT_SHELL_INIT([\n# Check that we are running under the correct shell.\nSHELL=${CONFIG_SHELL-/bin/sh}\n\ncase X$lt_ECHO in\nX*--fallback-echo)\n  # Remove one level of quotation (which was required for Make).\n  ECHO=`echo \"$lt_ECHO\" | sed 's,\\\\\\\\\\[$]\\\\[$]0,'[$]0','`\n  ;;\nesac\n\nECHO=${lt_ECHO-echo}\nif test \"X[$]1\" = X--no-reexec; then\n  # Discard the --no-reexec flag, and continue.\n  shift\nelif test \"X[$]1\" = X--fallback-echo; then\n  # Avoid inline document here, it may be left over\n  :\nelif test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t' ; then\n  # Yippee, $ECHO works!\n  :\nelse\n  # Restart under the correct shell.\n  exec $SHELL \"[$]0\" --no-reexec ${1+\"[$]@\"}\nfi\n\nif test \"X[$]1\" = X--fallback-echo; then\n  # used as fallback echo\n  shift\n  cat <<_LT_EOF\n[$]*\n_LT_EOF\n  exit 0\nfi\n\n# The HP-UX ksh and POSIX shell print the target directory to stdout\n# if CDPATH is set.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\nif test -z \"$lt_ECHO\"; then\n  if test \"X${echo_test_string+set}\" != Xset; then\n    # find a string as large as possible, as long as the shell can cope with it\n    for cmd in 'sed 50q \"[$]0\"' 'sed 20q \"[$]0\"' 'sed 10q \"[$]0\"' 'sed 2q \"[$]0\"' 'echo test'; do\n      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...\n      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&\n\t { test \"X$echo_test_string\" = \"X$echo_test_string\"; } 2>/dev/null\n      then\n        break\n      fi\n    done\n  fi\n\n  if test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t' &&\n     echo_testing_string=`{ $ECHO \"$echo_test_string\"; } 2>/dev/null` &&\n     test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n    :\n  else\n    # The Solaris, AIX, and Digital Unix default echo programs unquote\n    # backslashes.  This makes it impossible to quote backslashes using\n    #   echo \"$something\" | sed 's/\\\\/\\\\\\\\/g'\n    #\n    # So, first we look for a working echo in the user's PATH.\n\n    lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n    for dir in $PATH /usr/ucb; do\n      IFS=\"$lt_save_ifs\"\n      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&\n         test \"X`($dir/echo '\\t') 2>/dev/null`\" = 'X\\t' &&\n         echo_testing_string=`($dir/echo \"$echo_test_string\") 2>/dev/null` &&\n         test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n        ECHO=\"$dir/echo\"\n        break\n      fi\n    done\n    IFS=\"$lt_save_ifs\"\n\n    if test \"X$ECHO\" = Xecho; then\n      # We didn't find a better echo, so look for alternatives.\n      if test \"X`{ print -r '\\t'; } 2>/dev/null`\" = 'X\\t' &&\n         echo_testing_string=`{ print -r \"$echo_test_string\"; } 2>/dev/null` &&\n         test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n        # This shell has a builtin print -r that does the trick.\n        ECHO='print -r'\n      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&\n\t   test \"X$CONFIG_SHELL\" != X/bin/ksh; then\n        # If we have ksh, try running configure again with it.\n        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}\n        export ORIGINAL_CONFIG_SHELL\n        CONFIG_SHELL=/bin/ksh\n        export CONFIG_SHELL\n        exec $CONFIG_SHELL \"[$]0\" --no-reexec ${1+\"[$]@\"}\n      else\n        # Try using printf.\n        ECHO='printf %s\\n'\n        if test \"X`{ $ECHO '\\t'; } 2>/dev/null`\" = 'X\\t' &&\n\t   echo_testing_string=`{ $ECHO \"$echo_test_string\"; } 2>/dev/null` &&\n\t   test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n\t  # Cool, printf works\n\t  :\n        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL \"[$]0\" --fallback-echo '\\t') 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = 'X\\t' &&\n\t     echo_testing_string=`($ORIGINAL_CONFIG_SHELL \"[$]0\" --fallback-echo \"$echo_test_string\") 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n\t  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL\n\t  export CONFIG_SHELL\n\t  SHELL=\"$CONFIG_SHELL\"\n\t  export SHELL\n\t  ECHO=\"$CONFIG_SHELL [$]0 --fallback-echo\"\n        elif echo_testing_string=`($CONFIG_SHELL \"[$]0\" --fallback-echo '\\t') 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = 'X\\t' &&\n\t     echo_testing_string=`($CONFIG_SHELL \"[$]0\" --fallback-echo \"$echo_test_string\") 2>/dev/null` &&\n\t     test \"X$echo_testing_string\" = \"X$echo_test_string\"; then\n\t  ECHO=\"$CONFIG_SHELL [$]0 --fallback-echo\"\n        else\n\t  # maybe with a smaller string...\n\t  prev=:\n\n\t  for cmd in 'echo test' 'sed 2q \"[$]0\"' 'sed 10q \"[$]0\"' 'sed 20q \"[$]0\"' 'sed 50q \"[$]0\"'; do\n\t    if { test \"X$echo_test_string\" = \"X`eval $cmd`\"; } 2>/dev/null\n\t    then\n\t      break\n\t    fi\n\t    prev=\"$cmd\"\n\t  done\n\n\t  if test \"$prev\" != 'sed 50q \"[$]0\"'; then\n\t    echo_test_string=`eval $prev`\n\t    export echo_test_string\n\t    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} \"[$]0\" ${1+\"[$]@\"}\n\t  else\n\t    # Oops.  We lost completely, so just stick with echo.\n\t    ECHO=echo\n\t  fi\n        fi\n      fi\n    fi\n  fi\nfi\n\n# Copy echo and quote the copy suitably for passing to libtool from\n# the Makefile, instead of quoting the original, which is used later.\nlt_ECHO=$ECHO\nif test \"X$lt_ECHO\" = \"X$CONFIG_SHELL [$]0 --fallback-echo\"; then\n   lt_ECHO=\"$CONFIG_SHELL \\\\\\$\\[$]0 --fallback-echo\"\nfi\n\nAC_SUBST(lt_ECHO)\n])\n_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])\n_LT_DECL([], [ECHO], [1],\n    [An echo program that does not interpret backslashes])\n])# _LT_PROG_ECHO_BACKSLASH\n\n\n# _LT_ENABLE_LOCK\n# ---------------\nm4_defun([_LT_ENABLE_LOCK],\n[AC_ARG_ENABLE([libtool-lock],\n  [AS_HELP_STRING([--disable-libtool-lock],\n    [avoid locking (might break parallel builds)])])\ntest \"x$enable_libtool_lock\" != xno && enable_libtool_lock=yes\n\n# Some flags need to be propagated to the compiler or linker for good\n# libtool support.\ncase $host in\nia64-*-hpux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    case `/usr/bin/file conftest.$ac_objext` in\n      *ELF-32*)\n\tHPUX_IA64_MODE=\"32\"\n\t;;\n      *ELF-64*)\n\tHPUX_IA64_MODE=\"64\"\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n*-*-irix6*)\n  # Find out which ABI we are using.\n  echo '[#]line __oline__ \"configure\"' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    if test \"$lt_cv_prog_gnu_ld\" = yes; then\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -melf32bsmip\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -melf32bmipn32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -melf64bmip\"\n\t;;\n      esac\n    else\n      case `/usr/bin/file conftest.$ac_objext` in\n\t*32-bit*)\n\t  LD=\"${LD-ld} -32\"\n\t  ;;\n\t*N32*)\n\t  LD=\"${LD-ld} -n32\"\n\t  ;;\n\t*64-bit*)\n\t  LD=\"${LD-ld} -64\"\n\t  ;;\n      esac\n    fi\n  fi\n  rm -rf conftest*\n  ;;\n\nx86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \\\ns390*-*linux*|s390*-*tpf*|sparc*-*linux*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    case `/usr/bin/file conftest.o` in\n      *32-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_i386_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_i386\"\n\t    ;;\n\t  ppc64-*linux*|powerpc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32ppclinux\"\n\t    ;;\n\t  s390x-*linux*)\n\t    LD=\"${LD-ld} -m elf_s390\"\n\t    ;;\n\t  sparc64-*linux*)\n\t    LD=\"${LD-ld} -m elf32_sparc\"\n\t    ;;\n\tesac\n\t;;\n      *64-bit*)\n\tcase $host in\n\t  x86_64-*kfreebsd*-gnu)\n\t    LD=\"${LD-ld} -m elf_x86_64_fbsd\"\n\t    ;;\n\t  x86_64-*linux*)\n\t    LD=\"${LD-ld} -m elf_x86_64\"\n\t    ;;\n\t  ppc*-*linux*|powerpc*-*linux*)\n\t    LD=\"${LD-ld} -m elf64ppc\"\n\t    ;;\n\t  s390*-*linux*|s390*-*tpf*)\n\t    LD=\"${LD-ld} -m elf64_s390\"\n\t    ;;\n\t  sparc*-*linux*)\n\t    LD=\"${LD-ld} -m elf64_sparc\"\n\t    ;;\n\tesac\n\t;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\n\n*-*-sco3.2v5*)\n  # On SCO OpenServer 5, we need -belf to get full-featured binaries.\n  SAVE_CFLAGS=\"$CFLAGS\"\n  CFLAGS=\"$CFLAGS -belf\"\n  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,\n    [AC_LANG_PUSH(C)\n     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])\n     AC_LANG_POP])\n  if test x\"$lt_cv_cc_needs_belf\" != x\"yes\"; then\n    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf\n    CFLAGS=\"$SAVE_CFLAGS\"\n  fi\n  ;;\nsparc*-*solaris*)\n  # Find out which ABI we are using.\n  echo 'int i;' > conftest.$ac_ext\n  if AC_TRY_EVAL(ac_compile); then\n    case `/usr/bin/file conftest.o` in\n    *64-bit*)\n      case $lt_cv_prog_gnu_ld in\n      yes*) LD=\"${LD-ld} -m elf64_sparc\" ;;\n      *)\n\tif ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then\n\t  LD=\"${LD-ld} -64\"\n\tfi\n\t;;\n      esac\n      ;;\n    esac\n  fi\n  rm -rf conftest*\n  ;;\nesac\n\nneed_locks=\"$enable_libtool_lock\"\n])# _LT_ENABLE_LOCK\n\n\n# _LT_CMD_OLD_ARCHIVE\n# -------------------\nm4_defun([_LT_CMD_OLD_ARCHIVE],\n[AC_CHECK_TOOL(AR, ar, false)\ntest -z \"$AR\" && AR=ar\ntest -z \"$AR_FLAGS\" && AR_FLAGS=cru\n_LT_DECL([], [AR], [1], [The archiver])\n_LT_DECL([], [AR_FLAGS], [1])\n\nAC_CHECK_TOOL(STRIP, strip, :)\ntest -z \"$STRIP\" && STRIP=:\n_LT_DECL([], [STRIP], [1], [A symbol stripping program])\n\nAC_CHECK_TOOL(RANLIB, ranlib, :)\ntest -z \"$RANLIB\" && RANLIB=:\n_LT_DECL([], [RANLIB], [1],\n    [Commands used to install an old-style archive])\n\n# Determine commands to create old-style static archives.\nold_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'\nold_postinstall_cmds='chmod 644 $oldlib'\nold_postuninstall_cmds=\n\nif test -n \"$RANLIB\"; then\n  case $host_os in\n  openbsd*)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB -t \\$oldlib\"\n    ;;\n  *)\n    old_postinstall_cmds=\"$old_postinstall_cmds~\\$RANLIB \\$oldlib\"\n    ;;\n  esac\n  old_archive_cmds=\"$old_archive_cmds~\\$RANLIB \\$oldlib\"\nfi\n_LT_DECL([], [old_postinstall_cmds], [2])\n_LT_DECL([], [old_postuninstall_cmds], [2])\n_LT_TAGDECL([], [old_archive_cmds], [2],\n    [Commands used to build an old-style archive])\n])# _LT_CMD_OLD_ARCHIVE\n\n\n# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,\n#\t\t[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])\n# ----------------------------------------------------------------\n# Check whether the given compiler option works\nAC_DEFUN([_LT_COMPILER_OPTION],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_SED])dnl\nAC_CACHE_CHECK([$1], [$2],\n  [$2=no\n   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n   lt_compiler_flag=\"$3\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   # The option is referenced via a variable to avoid confusing sed.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [[^ ]]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:__oline__: $lt_compile\\\"\" >&AS_MESSAGE_LOG_FD)\n   (eval \"$lt_compile\" 2>conftest.err)\n   ac_status=$?\n   cat conftest.err >&AS_MESSAGE_LOG_FD\n   echo \"$as_me:__oline__: \\$? = $ac_status\" >&AS_MESSAGE_LOG_FD\n   if (exit $ac_status) && test -s \"$ac_outfile\"; then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings other than the usual output.\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' >conftest.exp\n     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then\n       $2=yes\n     fi\n   fi\n   $RM conftest*\n])\n\nif test x\"[$]$2\" = xyes; then\n    m4_if([$5], , :, [$5])\nelse\n    m4_if([$6], , :, [$6])\nfi\n])# _LT_COMPILER_OPTION\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])\n\n\n# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,\n#                  [ACTION-SUCCESS], [ACTION-FAILURE])\n# ----------------------------------------------------\n# Check whether the given linker option works\nAC_DEFUN([_LT_LINKER_OPTION],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_SED])dnl\nAC_CACHE_CHECK([$1], [$2],\n  [$2=no\n   save_LDFLAGS=\"$LDFLAGS\"\n   LDFLAGS=\"$LDFLAGS $3\"\n   echo \"$lt_simple_link_test_code\" > conftest.$ac_ext\n   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then\n     # The linker can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     if test -s conftest.err; then\n       # Append any errors to the config.log.\n       cat conftest.err 1>&AS_MESSAGE_LOG_FD\n       $ECHO \"X$_lt_linker_boilerplate\" | $Xsed -e '/^$/d' > conftest.exp\n       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2\n       if diff conftest.exp conftest.er2 >/dev/null; then\n         $2=yes\n       fi\n     else\n       $2=yes\n     fi\n   fi\n   $RM -r conftest*\n   LDFLAGS=\"$save_LDFLAGS\"\n])\n\nif test x\"[$]$2\" = xyes; then\n    m4_if([$4], , :, [$4])\nelse\n    m4_if([$5], , :, [$5])\nfi\n])# _LT_LINKER_OPTION\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])\n\n\n# LT_CMD_MAX_LEN\n#---------------\nAC_DEFUN([LT_CMD_MAX_LEN],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\n# find the maximum length of command line arguments\nAC_MSG_CHECKING([the maximum length of command line arguments])\nAC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl\n  i=0\n  teststring=\"ABCD\"\n\n  case $build_os in\n  msdosdjgpp*)\n    # On DJGPP, this test can blow up pretty badly due to problems in libc\n    # (any single argument exceeding 2000 bytes causes a buffer overrun\n    # during glob expansion).  Even if it were fixed, the result of this\n    # check would be larger than it should be.\n    lt_cv_sys_max_cmd_len=12288;    # 12K is about right\n    ;;\n\n  gnu*)\n    # Under GNU Hurd, this test is not required because there is\n    # no limit to the length of command line arguments.\n    # Libtool will interpret -1 as no limit whatsoever\n    lt_cv_sys_max_cmd_len=-1;\n    ;;\n\n  cygwin* | mingw* | cegcc*)\n    # On Win9x/ME, this test blows up -- it succeeds, but takes\n    # about 5 minutes as the teststring grows exponentially.\n    # Worse, since 9x/ME are not pre-emptively multitasking,\n    # you end up with a \"frozen\" computer, even though with patience\n    # the test eventually succeeds (with a max line length of 256k).\n    # Instead, let's just punt: use the minimum linelength reported by\n    # all of the supported platforms: 8192 (on NT/2K/XP).\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  amigaos*)\n    # On AmigaOS with pdksh, this test takes hours, literally.\n    # So we just punt and use a minimum line length of 8192.\n    lt_cv_sys_max_cmd_len=8192;\n    ;;\n\n  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)\n    # This has been around since 386BSD, at least.  Likely further.\n    if test -x /sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`\n    elif test -x /usr/sbin/sysctl; then\n      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`\n    else\n      lt_cv_sys_max_cmd_len=65536\t# usable default for all BSDs\n    fi\n    # And add a safety zone\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    ;;\n\n  interix*)\n    # We know the value 262144 and hardcode it with a safety zone (like BSD)\n    lt_cv_sys_max_cmd_len=196608\n    ;;\n\n  osf*)\n    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure\n    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not\n    # nice to cause kernel panics so lets avoid the loop below.\n    # First set a reasonable default.\n    lt_cv_sys_max_cmd_len=16384\n    #\n    if test -x /sbin/sysconfig; then\n      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in\n        *1*) lt_cv_sys_max_cmd_len=-1 ;;\n      esac\n    fi\n    ;;\n  sco3.2v5*)\n    lt_cv_sys_max_cmd_len=102400\n    ;;\n  sysv5* | sco5v6* | sysv4.2uw2*)\n    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`\n    if test -n \"$kargmax\"; then\n      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[\t ]]//'`\n    else\n      lt_cv_sys_max_cmd_len=32768\n    fi\n    ;;\n  *)\n    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`\n    if test -n \"$lt_cv_sys_max_cmd_len\"; then\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 4`\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\* 3`\n    else\n      # Make teststring a little bigger before we do anything with it.\n      # a 1K string should be a reasonable start.\n      for i in 1 2 3 4 5 6 7 8 ; do\n        teststring=$teststring$teststring\n      done\n      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}\n      # If test is not a shell built-in, we'll probably end up computing a\n      # maximum length that is only half of the actual maximum length, but\n      # we can't tell.\n      while { test \"X\"`$SHELL [$]0 --fallback-echo \"X$teststring$teststring\" 2>/dev/null` \\\n\t         = \"XX$teststring$teststring\"; } >/dev/null 2>&1 &&\n\t      test $i != 17 # 1/2 MB should be enough\n      do\n        i=`expr $i + 1`\n        teststring=$teststring$teststring\n      done\n      # Only check the string length outside the loop.\n      lt_cv_sys_max_cmd_len=`expr \"X$teststring\" : \".*\" 2>&1`\n      teststring=\n      # Add a significant safety factor because C++ compilers can tack on\n      # massive amounts of additional arguments before passing them to the\n      # linker.  It appears as though 1/2 is a usable value.\n      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \\/ 2`\n    fi\n    ;;\n  esac\n])\nif test -n $lt_cv_sys_max_cmd_len ; then\n  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)\nelse\n  AC_MSG_RESULT(none)\nfi\nmax_cmd_len=$lt_cv_sys_max_cmd_len\n_LT_DECL([], [max_cmd_len], [0],\n    [What is the maximum length of a command?])\n])# LT_CMD_MAX_LEN\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])\n\n\n# _LT_HEADER_DLFCN\n# ----------------\nm4_defun([_LT_HEADER_DLFCN],\n[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl\n])# _LT_HEADER_DLFCN\n\n\n# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,\n#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)\n# ----------------------------------------------------------------\nm4_defun([_LT_TRY_DLOPEN_SELF],\n[m4_require([_LT_HEADER_DLFCN])dnl\nif test \"$cross_compiling\" = yes; then :\n  [$4]\nelse\n  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2\n  lt_status=$lt_dlunknown\n  cat > conftest.$ac_ext <<_LT_EOF\n[#line __oline__ \"configure\"\n#include \"confdefs.h\"\n\n#if HAVE_DLFCN_H\n#include <dlfcn.h>\n#endif\n\n#include <stdio.h>\n\n#ifdef RTLD_GLOBAL\n#  define LT_DLGLOBAL\t\tRTLD_GLOBAL\n#else\n#  ifdef DL_GLOBAL\n#    define LT_DLGLOBAL\t\tDL_GLOBAL\n#  else\n#    define LT_DLGLOBAL\t\t0\n#  endif\n#endif\n\n/* We may have to define LT_DLLAZY_OR_NOW in the command line if we\n   find out it does not work in some platform. */\n#ifndef LT_DLLAZY_OR_NOW\n#  ifdef RTLD_LAZY\n#    define LT_DLLAZY_OR_NOW\t\tRTLD_LAZY\n#  else\n#    ifdef DL_LAZY\n#      define LT_DLLAZY_OR_NOW\t\tDL_LAZY\n#    else\n#      ifdef RTLD_NOW\n#        define LT_DLLAZY_OR_NOW\tRTLD_NOW\n#      else\n#        ifdef DL_NOW\n#          define LT_DLLAZY_OR_NOW\tDL_NOW\n#        else\n#          define LT_DLLAZY_OR_NOW\t0\n#        endif\n#      endif\n#    endif\n#  endif\n#endif\n\nvoid fnord() { int i=42;}\nint main ()\n{\n  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);\n  int status = $lt_dlunknown;\n\n  if (self)\n    {\n      if (dlsym (self,\"fnord\"))       status = $lt_dlno_uscore;\n      else if (dlsym( self,\"_fnord\")) status = $lt_dlneed_uscore;\n      /* dlclose (self); */\n    }\n  else\n    puts (dlerror ());\n\n  return status;\n}]\n_LT_EOF\n  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then\n    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null\n    lt_status=$?\n    case x$lt_status in\n      x$lt_dlno_uscore) $1 ;;\n      x$lt_dlneed_uscore) $2 ;;\n      x$lt_dlunknown|x*) $3 ;;\n    esac\n  else :\n    # compilation failed\n    $3\n  fi\nfi\nrm -fr conftest*\n])# _LT_TRY_DLOPEN_SELF\n\n\n# LT_SYS_DLOPEN_SELF\n# ------------------\nAC_DEFUN([LT_SYS_DLOPEN_SELF],\n[m4_require([_LT_HEADER_DLFCN])dnl\nif test \"x$enable_dlopen\" != xyes; then\n  enable_dlopen=unknown\n  enable_dlopen_self=unknown\n  enable_dlopen_self_static=unknown\nelse\n  lt_cv_dlopen=no\n  lt_cv_dlopen_libs=\n\n  case $host_os in\n  beos*)\n    lt_cv_dlopen=\"load_add_on\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n    ;;\n\n  mingw* | pw32* | cegcc*)\n    lt_cv_dlopen=\"LoadLibrary\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  cygwin*)\n    lt_cv_dlopen=\"dlopen\"\n    lt_cv_dlopen_libs=\n    ;;\n\n  darwin*)\n  # if libdl is installed we need to link against it\n    AC_CHECK_LIB([dl], [dlopen],\n\t\t[lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"],[\n    lt_cv_dlopen=\"dyld\"\n    lt_cv_dlopen_libs=\n    lt_cv_dlopen_self=yes\n    ])\n    ;;\n\n  *)\n    AC_CHECK_FUNC([shl_load],\n\t  [lt_cv_dlopen=\"shl_load\"],\n      [AC_CHECK_LIB([dld], [shl_load],\n\t    [lt_cv_dlopen=\"shl_load\" lt_cv_dlopen_libs=\"-ldld\"],\n\t[AC_CHECK_FUNC([dlopen],\n\t      [lt_cv_dlopen=\"dlopen\"],\n\t  [AC_CHECK_LIB([dl], [dlopen],\n\t\t[lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-ldl\"],\n\t    [AC_CHECK_LIB([svld], [dlopen],\n\t\t  [lt_cv_dlopen=\"dlopen\" lt_cv_dlopen_libs=\"-lsvld\"],\n\t      [AC_CHECK_LIB([dld], [dld_link],\n\t\t    [lt_cv_dlopen=\"dld_link\" lt_cv_dlopen_libs=\"-ldld\"])\n\t      ])\n\t    ])\n\t  ])\n\t])\n      ])\n    ;;\n  esac\n\n  if test \"x$lt_cv_dlopen\" != xno; then\n    enable_dlopen=yes\n  else\n    enable_dlopen=no\n  fi\n\n  case $lt_cv_dlopen in\n  dlopen)\n    save_CPPFLAGS=\"$CPPFLAGS\"\n    test \"x$ac_cv_header_dlfcn_h\" = xyes && CPPFLAGS=\"$CPPFLAGS -DHAVE_DLFCN_H\"\n\n    save_LDFLAGS=\"$LDFLAGS\"\n    wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $export_dynamic_flag_spec\\\"\n\n    save_LIBS=\"$LIBS\"\n    LIBS=\"$lt_cv_dlopen_libs $LIBS\"\n\n    AC_CACHE_CHECK([whether a program can dlopen itself],\n\t  lt_cv_dlopen_self, [dnl\n\t  _LT_TRY_DLOPEN_SELF(\n\t    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,\n\t    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)\n    ])\n\n    if test \"x$lt_cv_dlopen_self\" = xyes; then\n      wl=$lt_prog_compiler_wl eval LDFLAGS=\\\"\\$LDFLAGS $lt_prog_compiler_static\\\"\n      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],\n\t  lt_cv_dlopen_self_static, [dnl\n\t  _LT_TRY_DLOPEN_SELF(\n\t    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,\n\t    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)\n      ])\n    fi\n\n    CPPFLAGS=\"$save_CPPFLAGS\"\n    LDFLAGS=\"$save_LDFLAGS\"\n    LIBS=\"$save_LIBS\"\n    ;;\n  esac\n\n  case $lt_cv_dlopen_self in\n  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;\n  *) enable_dlopen_self=unknown ;;\n  esac\n\n  case $lt_cv_dlopen_self_static in\n  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;\n  *) enable_dlopen_self_static=unknown ;;\n  esac\nfi\n_LT_DECL([dlopen_support], [enable_dlopen], [0],\n\t [Whether dlopen is supported])\n_LT_DECL([dlopen_self], [enable_dlopen_self], [0],\n\t [Whether dlopen of programs is supported])\n_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],\n\t [Whether dlopen of statically linked programs is supported])\n])# LT_SYS_DLOPEN_SELF\n\n# Old name:\nAU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])\n\n\n# _LT_COMPILER_C_O([TAGNAME])\n# ---------------------------\n# Check to see if options -c and -o are simultaneously supported by compiler.\n# This macro does not hard code the compiler like AC_PROG_CC_C_O.\nm4_defun([_LT_COMPILER_C_O],\n[m4_require([_LT_DECL_SED])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_TAG_COMPILER])dnl\nAC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],\n  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],\n  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no\n   $RM -r conftest 2>/dev/null\n   mkdir conftest\n   cd conftest\n   mkdir out\n   echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n   lt_compiler_flag=\"-o out/conftest2.$ac_objext\"\n   # Insert the option either (1) after the last *FLAGS variable, or\n   # (2) before a word containing \"conftest.\", or (3) at the end.\n   # Note that $ac_compile itself does not contain backslashes and begins\n   # with a dollar sign (not a hyphen), so the echo should work correctly.\n   lt_compile=`echo \"$ac_compile\" | $SED \\\n   -e 's:.*FLAGS}\\{0,1\\} :&$lt_compiler_flag :; t' \\\n   -e 's: [[^ ]]*conftest\\.: $lt_compiler_flag&:; t' \\\n   -e 's:$: $lt_compiler_flag:'`\n   (eval echo \"\\\"\\$as_me:__oline__: $lt_compile\\\"\" >&AS_MESSAGE_LOG_FD)\n   (eval \"$lt_compile\" 2>out/conftest.err)\n   ac_status=$?\n   cat out/conftest.err >&AS_MESSAGE_LOG_FD\n   echo \"$as_me:__oline__: \\$? = $ac_status\" >&AS_MESSAGE_LOG_FD\n   if (exit $ac_status) && test -s out/conftest2.$ac_objext\n   then\n     # The compiler can only warn and ignore the option if not recognized\n     # So say no if there are warnings\n     $ECHO \"X$_lt_compiler_boilerplate\" | $Xsed -e '/^$/d' > out/conftest.exp\n     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2\n     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then\n       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes\n     fi\n   fi\n   chmod u+w . 2>&AS_MESSAGE_LOG_FD\n   $RM conftest*\n   # SGI C++ compiler will create directory out/ii_files/ for\n   # template instantiation\n   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files\n   $RM out/* && rmdir out\n   cd ..\n   $RM -r conftest\n   $RM conftest*\n])\n_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],\n\t[Does compiler simultaneously support -c and -o options?])\n])# _LT_COMPILER_C_O\n\n\n# _LT_COMPILER_FILE_LOCKS([TAGNAME])\n# ----------------------------------\n# Check to see if we can do hard links to lock some files if needed\nm4_defun([_LT_COMPILER_FILE_LOCKS],\n[m4_require([_LT_ENABLE_LOCK])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\n_LT_COMPILER_C_O([$1])\n\nhard_links=\"nottested\"\nif test \"$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)\" = no && test \"$need_locks\" != no; then\n  # do not overwrite the value of need_locks provided by the user\n  AC_MSG_CHECKING([if we can lock with hard links])\n  hard_links=yes\n  $RM conftest*\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  touch conftest.a\n  ln conftest.a conftest.b 2>&5 || hard_links=no\n  ln conftest.a conftest.b 2>/dev/null && hard_links=no\n  AC_MSG_RESULT([$hard_links])\n  if test \"$hard_links\" = no; then\n    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])\n    need_locks=warn\n  fi\nelse\n  need_locks=no\nfi\n_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])\n])# _LT_COMPILER_FILE_LOCKS\n\n\n# _LT_CHECK_OBJDIR\n# ----------------\nm4_defun([_LT_CHECK_OBJDIR],\n[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],\n[rm -f .libs 2>/dev/null\nmkdir .libs 2>/dev/null\nif test -d .libs; then\n  lt_cv_objdir=.libs\nelse\n  # MS-DOS does not allow filenames that begin with a dot.\n  lt_cv_objdir=_libs\nfi\nrmdir .libs 2>/dev/null])\nobjdir=$lt_cv_objdir\n_LT_DECL([], [objdir], [0],\n         [The name of the directory that contains temporary libtool files])dnl\nm4_pattern_allow([LT_OBJDIR])dnl\nAC_DEFINE_UNQUOTED(LT_OBJDIR, \"$lt_cv_objdir/\",\n  [Define to the sub-directory in which libtool stores uninstalled libraries.])\n])# _LT_CHECK_OBJDIR\n\n\n# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])\n# --------------------------------------\n# Check hardcoding attributes.\nm4_defun([_LT_LINKER_HARDCODE_LIBPATH],\n[AC_MSG_CHECKING([how to hardcode library paths into programs])\n_LT_TAGVAR(hardcode_action, $1)=\nif test -n \"$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\" ||\n   test -n \"$_LT_TAGVAR(runpath_var, $1)\" ||\n   test \"X$_LT_TAGVAR(hardcode_automatic, $1)\" = \"Xyes\" ; then\n\n  # We can hardcode non-existent directories.\n  if test \"$_LT_TAGVAR(hardcode_direct, $1)\" != no &&\n     # If the only mechanism to avoid hardcoding is shlibpath_var, we\n     # have to relink, otherwise we might link with an installed library\n     # when we should be linking with a yet-to-be-installed one\n     ## test \"$_LT_TAGVAR(hardcode_shlibpath_var, $1)\" != no &&\n     test \"$_LT_TAGVAR(hardcode_minus_L, $1)\" != no; then\n    # Linking always hardcodes the temporary library directory.\n    _LT_TAGVAR(hardcode_action, $1)=relink\n  else\n    # We can link without hardcoding, and we can hardcode nonexisting dirs.\n    _LT_TAGVAR(hardcode_action, $1)=immediate\n  fi\nelse\n  # We cannot hardcode anything, or else we can only hardcode existing\n  # directories.\n  _LT_TAGVAR(hardcode_action, $1)=unsupported\nfi\nAC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])\n\nif test \"$_LT_TAGVAR(hardcode_action, $1)\" = relink ||\n   test \"$_LT_TAGVAR(inherit_rpath, $1)\" = yes; then\n  # Fast installation is not supported\n  enable_fast_install=no\nelif test \"$shlibpath_overrides_runpath\" = yes ||\n     test \"$enable_shared\" = no; then\n  # Fast installation is not necessary\n  enable_fast_install=needless\nfi\n_LT_TAGDECL([], [hardcode_action], [0],\n    [How to hardcode a shared library path into an executable])\n])# _LT_LINKER_HARDCODE_LIBPATH\n\n\n# _LT_CMD_STRIPLIB\n# ----------------\nm4_defun([_LT_CMD_STRIPLIB],\n[m4_require([_LT_DECL_EGREP])\nstriplib=\nold_striplib=\nAC_MSG_CHECKING([whether stripping libraries is possible])\nif test -n \"$STRIP\" && $STRIP -V 2>&1 | $GREP \"GNU strip\" >/dev/null; then\n  test -z \"$old_striplib\" && old_striplib=\"$STRIP --strip-debug\"\n  test -z \"$striplib\" && striplib=\"$STRIP --strip-unneeded\"\n  AC_MSG_RESULT([yes])\nelse\n# FIXME - insert some real tests, host_os isn't really good enough\n  case $host_os in\n  darwin*)\n    if test -n \"$STRIP\" ; then\n      striplib=\"$STRIP -x\"\n      old_striplib=\"$STRIP -S\"\n      AC_MSG_RESULT([yes])\n    else\n      AC_MSG_RESULT([no])\n    fi\n    ;;\n  *)\n    AC_MSG_RESULT([no])\n    ;;\n  esac\nfi\n_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])\n_LT_DECL([], [striplib], [1])\n])# _LT_CMD_STRIPLIB\n\n\n# _LT_SYS_DYNAMIC_LINKER([TAG])\n# -----------------------------\n# PORTME Fill in your ld.so characteristics\nm4_defun([_LT_SYS_DYNAMIC_LINKER],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_OBJDUMP])dnl\nm4_require([_LT_DECL_SED])dnl\nAC_MSG_CHECKING([dynamic linker characteristics])\nm4_if([$1],\n\t[], [\nif test \"$GCC\" = yes; then\n  case $host_os in\n    darwin*) lt_awk_arg=\"/^libraries:/,/LR/\" ;;\n    *) lt_awk_arg=\"/^libraries:/\" ;;\n  esac\n  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e \"s/^libraries://\" -e \"s,=/,/,g\"`\n  if $ECHO \"$lt_search_path_spec\" | $GREP ';' >/dev/null ; then\n    # if the path contains \";\" then we assume it to be the separator\n    # otherwise default to the standard path separator (i.e. \":\") - it is\n    # assumed that no part of a normal pathname contains \";\" but that should\n    # okay in the real world where \";\" in dirpaths is itself problematic.\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED -e 's/;/ /g'`\n  else\n    lt_search_path_spec=`$ECHO \"$lt_search_path_spec\" | $SED  -e \"s/$PATH_SEPARATOR/ /g\"`\n  fi\n  # Ok, now we have the path, separated by spaces, we can step through it\n  # and add multilib dir if necessary.\n  lt_tmp_lt_search_path_spec=\n  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`\n  for lt_sys_path in $lt_search_path_spec; do\n    if test -d \"$lt_sys_path/$lt_multi_os_dir\"; then\n      lt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir\"\n    else\n      test -d \"$lt_sys_path\" && \\\n\tlt_tmp_lt_search_path_spec=\"$lt_tmp_lt_search_path_spec $lt_sys_path\"\n    fi\n  done\n  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '\nBEGIN {RS=\" \"; FS=\"/|\\n\";} {\n  lt_foo=\"\";\n  lt_count=0;\n  for (lt_i = NF; lt_i > 0; lt_i--) {\n    if ($lt_i != \"\" && $lt_i != \".\") {\n      if ($lt_i == \"..\") {\n        lt_count++;\n      } else {\n        if (lt_count == 0) {\n          lt_foo=\"/\" $lt_i lt_foo;\n        } else {\n          lt_count--;\n        }\n      }\n    }\n  }\n  if (lt_foo != \"\") { lt_freq[[lt_foo]]++; }\n  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }\n}'`\n  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`\nelse\n  sys_lib_search_path_spec=\"/lib /usr/lib /usr/local/lib\"\nfi])\nlibrary_names_spec=\nlibname_spec='lib$name'\nsoname_spec=\nshrext_cmds=\".so\"\npostinstall_cmds=\npostuninstall_cmds=\nfinish_cmds=\nfinish_eval=\nshlibpath_var=\nshlibpath_overrides_runpath=unknown\nversion_type=none\ndynamic_linker=\"$host_os ld.so\"\nsys_lib_dlsearch_path_spec=\"/lib /usr/lib\"\nneed_lib_prefix=unknown\nhardcode_into_libs=no\n\n# when you set need_version to no, make sure it does not cause -set_version\n# flags to be left without arguments\nneed_version=unknown\n\ncase $host_os in\naix3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'\n  shlibpath_var=LIBPATH\n\n  # AIX 3 has no versioning support, so we append a major version to the name.\n  soname_spec='${libname}${release}${shared_ext}$major'\n  ;;\n\naix[[4-9]]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  hardcode_into_libs=yes\n  if test \"$host_cpu\" = ia64; then\n    # AIX 5 supports IA64\n    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'\n    shlibpath_var=LD_LIBRARY_PATH\n  else\n    # With GCC up to 2.95.x, collect2 would create an import file\n    # for dependence libraries.  The import file would start with\n    # the line `#! .'.  This would cause the generated library to\n    # depend on `.', always an invalid library.  This was fixed in\n    # development snapshots of GCC prior to 3.0.\n    case $host_os in\n      aix4 | aix4.[[01]] | aix4.[[01]].*)\n      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'\n\t   echo ' yes '\n\t   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then\n\t:\n      else\n\tcan_build_shared=no\n      fi\n      ;;\n    esac\n    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct\n    # soname into executable. Probably we can add versioning support to\n    # collect2, so additional links can be useful in future.\n    if test \"$aix_use_runtimelinking\" = yes; then\n      # If using run time linking (on AIX 4.2 or later) use lib<name>.so\n      # instead of lib<name>.a to let people know that these are not\n      # typical AIX shared libraries.\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    else\n      # We preserve .a as extension for shared libraries through AIX4.2\n      # and later when we are not doing run time linking.\n      library_names_spec='${libname}${release}.a $libname.a'\n      soname_spec='${libname}${release}${shared_ext}$major'\n    fi\n    shlibpath_var=LIBPATH\n  fi\n  ;;\n\namigaos*)\n  case $host_cpu in\n  powerpc)\n    # Since July 2007 AmigaOS4 officially supports .so libraries.\n    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    ;;\n  m68k)\n    library_names_spec='$libname.ixlibrary $libname.a'\n    # Create ${libname}_ixlibrary.a entries in /sys/libs.\n    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO \"X$lib\" | $Xsed -e '\\''s%^.*/\\([[^/]]*\\)\\.ixlibrary$%\\1%'\\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show \"cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a\"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'\n    ;;\n  esac\n  ;;\n\nbeos*)\n  library_names_spec='${libname}${shared_ext}'\n  dynamic_linker=\"$host_os ld.so\"\n  shlibpath_var=LIBRARY_PATH\n  ;;\n\nbsdi[[45]]*)\n  version_type=linux\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib\"\n  sys_lib_dlsearch_path_spec=\"/shlib /usr/lib /usr/local/lib\"\n  # the default ld.so.conf also contains /usr/contrib/lib and\n  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow\n  # libtool to hard-code these into programs\n  ;;\n\ncygwin* | mingw* | pw32* | cegcc*)\n  version_type=windows\n  shrext_cmds=\".dll\"\n  need_version=no\n  need_lib_prefix=no\n\n  case $GCC,$host_os in\n  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)\n    library_names_spec='$libname.dll.a'\n    # DLL is installed to $(libdir)/../bin by postinstall_cmds\n    postinstall_cmds='base_file=`basename \\${file}`~\n      dlpath=`$SHELL 2>&1 -c '\\''. $dir/'\\''\\${base_file}'\\''i; echo \\$dlname'\\''`~\n      dldir=$destdir/`dirname \\$dlpath`~\n      test -d \\$dldir || mkdir -p \\$dldir~\n      $install_prog $dir/$dlname \\$dldir/$dlname~\n      chmod a+x \\$dldir/$dlname~\n      if test -n '\\''$stripme'\\'' && test -n '\\''$striplib'\\''; then\n        eval '\\''$striplib \\$dldir/$dlname'\\'' || exit \\$?;\n      fi'\n    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\\''. $file; echo \\$dlname'\\''`~\n      dlpath=$dir/\\$dldll~\n       $RM \\$dlpath'\n    shlibpath_overrides_runpath=yes\n\n    case $host_os in\n    cygwin*)\n      # Cygwin DLLs use 'cyg' prefix rather than 'lib'\n      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n      sys_lib_search_path_spec=\"/usr/lib /lib/w32api /lib /usr/local/lib\"\n      ;;\n    mingw* | cegcc*)\n      # MinGW DLLs use traditional 'lib' prefix\n      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP \"^libraries:\" | $SED -e \"s/^libraries://\" -e \"s,=/,/,g\"`\n      if $ECHO \"$sys_lib_search_path_spec\" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then\n        # It is most probably a Windows format PATH printed by\n        # mingw gcc, but we are running on Cygwin. Gcc prints its search\n        # path with ; separators, and with drive letters. We can handle the\n        # drive letters (cygwin fileutils understands them), so leave them,\n        # especially as we might pass files found there to a mingw objdump,\n        # which wouldn't understand a cygwinified path. Ahh.\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED -e 's/;/ /g'`\n      else\n        sys_lib_search_path_spec=`$ECHO \"$sys_lib_search_path_spec\" | $SED  -e \"s/$PATH_SEPARATOR/ /g\"`\n      fi\n      ;;\n    pw32*)\n      # pw32 DLLs use 'pw' prefix rather than 'lib'\n      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'\n      ;;\n    esac\n    ;;\n\n  *)\n    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'\n    ;;\n  esac\n  dynamic_linker='Win32 ld.exe'\n  # FIXME: first we should search . and the directory the executable is in\n  shlibpath_var=PATH\n  ;;\n\ndarwin* | rhapsody*)\n  dynamic_linker=\"$host_os dyld\"\n  version_type=darwin\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'\n  soname_spec='${libname}${release}${major}$shared_ext'\n  shlibpath_overrides_runpath=yes\n  shlibpath_var=DYLD_LIBRARY_PATH\n  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'\nm4_if([$1], [],[\n  sys_lib_search_path_spec=\"$sys_lib_search_path_spec /usr/local/lib\"])\n  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'\n  ;;\n\ndgux*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\nfreebsd1*)\n  dynamic_linker=no\n  ;;\n\nfreebsd* | dragonfly*)\n  # DragonFly does not have aout.  When/if they implement a new\n  # versioning mechanism, adjust this.\n  if test -x /usr/bin/objformat; then\n    objformat=`/usr/bin/objformat`\n  else\n    case $host_os in\n    freebsd[[123]]*) objformat=aout ;;\n    *) objformat=elf ;;\n    esac\n  fi\n  version_type=freebsd-$objformat\n  case $version_type in\n    freebsd-elf*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n      need_version=no\n      need_lib_prefix=no\n      ;;\n    freebsd-*)\n      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'\n      need_version=yes\n      ;;\n  esac\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_os in\n  freebsd2*)\n    shlibpath_overrides_runpath=yes\n    ;;\n  freebsd3.[[01]]* | freebsdelf3.[[01]]*)\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \\\n  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)\n    shlibpath_overrides_runpath=no\n    hardcode_into_libs=yes\n    ;;\n  *) # from 4.6 on, and DragonFly\n    shlibpath_overrides_runpath=yes\n    hardcode_into_libs=yes\n    ;;\n  esac\n  ;;\n\ngnu*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  hardcode_into_libs=yes\n  ;;\n\nhpux9* | hpux10* | hpux11*)\n  # Give a soname corresponding to the major version so that dld.sl refuses to\n  # link against other versions.\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  case $host_cpu in\n  ia64*)\n    shrext_cmds='.so'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.so\"\n    shlibpath_var=LD_LIBRARY_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    if test \"X$HPUX_IA64_MODE\" = X32; then\n      sys_lib_search_path_spec=\"/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib\"\n    else\n      sys_lib_search_path_spec=\"/usr/lib/hpux64 /usr/local/lib/hpux64\"\n    fi\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  hppa*64*)\n    shrext_cmds='.sl'\n    hardcode_into_libs=yes\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH\n    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    sys_lib_search_path_spec=\"/usr/lib/pa20_64 /usr/ccs/lib/pa20_64\"\n    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec\n    ;;\n  *)\n    shrext_cmds='.sl'\n    dynamic_linker=\"$host_os dld.sl\"\n    shlibpath_var=SHLIB_PATH\n    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    ;;\n  esac\n  # HP-UX runs *really* slowly unless shared libraries are mode 555.\n  postinstall_cmds='chmod 555 $lib'\n  ;;\n\ninterix[[3-9]]*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $host_os in\n    nonstopux*) version_type=nonstopux ;;\n    *)\n\tif test \"$lt_cv_prog_gnu_ld\" = yes; then\n\t\tversion_type=linux\n\telse\n\t\tversion_type=irix\n\tfi ;;\n  esac\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'\n  case $host_os in\n  irix5* | nonstopux*)\n    libsuff= shlibsuff=\n    ;;\n  *)\n    case $LD in # libtool.m4 will add one of these switches to LD\n    *-32|*\"-32 \"|*-melf32bsmip|*\"-melf32bsmip \")\n      libsuff= shlibsuff= libmagic=32-bit;;\n    *-n32|*\"-n32 \"|*-melf32bmipn32|*\"-melf32bmipn32 \")\n      libsuff=32 shlibsuff=N32 libmagic=N32;;\n    *-64|*\"-64 \"|*-melf64bmip|*\"-melf64bmip \")\n      libsuff=64 shlibsuff=64 libmagic=64-bit;;\n    *) libsuff= shlibsuff= libmagic=never-match;;\n    esac\n    ;;\n  esac\n  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH\n  shlibpath_overrides_runpath=no\n  sys_lib_search_path_spec=\"/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}\"\n  sys_lib_dlsearch_path_spec=\"/usr/lib${libsuff} /lib${libsuff}\"\n  hardcode_into_libs=yes\n  ;;\n\n# No shared lib support for Linux oldld, aout, or coff.\nlinux*oldld* | linux*aout* | linux*coff*)\n  dynamic_linker=no\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -n $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  # Some binutils ld are patched to set DT_RUNPATH\n  save_LDFLAGS=$LDFLAGS\n  save_libdir=$libdir\n  eval \"libdir=/foo; wl=\\\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\\\"; \\\n       LDFLAGS=\\\"\\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\\\"\"\n  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],\n    [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep \"RUNPATH.*$libdir\" >/dev/null],\n       [shlibpath_overrides_runpath=yes])])\n  LDFLAGS=$save_LDFLAGS\n  libdir=$save_libdir\n\n  # This implies no fast_install, which is unacceptable.\n  # Some rework will be needed to allow for fast_install\n  # before this can be enabled.\n  hardcode_into_libs=yes\n\n  # Append ld.so.conf contents to the search path\n  if test -f /etc/ld.so.conf; then\n    lt_ld_extra=`awk '/^include / { system(sprintf(\"cd /etc; cat %s 2>/dev/null\", \\[$]2)); skip = 1; } { if (!skip) print \\[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[\t ]*hwcap[\t ]/d;s/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\\n' ' '`\n    sys_lib_dlsearch_path_spec=\"/lib /usr/lib $lt_ld_extra\"\n  fi\n\n  # We used to test for /lib/ld.so.1 and disable shared libraries on\n  # powerpc, because MkLinux only supported shared libraries with the\n  # GNU dynamic linker.  Since this was broken with cross compilers,\n  # most powerpc-linux boxes support dynamic linking these days and\n  # people can always --disable-shared, the test was removed, and we\n  # assume the GNU/Linux dynamic linker is in use.\n  dynamic_linker='GNU/Linux ld.so'\n  ;;\n\nnetbsdelf*-gnu)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='NetBSD ld.elf_so'\n  ;;\n\nnetbsd*)\n  version_type=sunos\n  need_lib_prefix=no\n  need_version=no\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n    finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n    dynamic_linker='NetBSD (a.out) ld.so'\n  else\n    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'\n    soname_spec='${libname}${release}${shared_ext}$major'\n    dynamic_linker='NetBSD ld.elf_so'\n  fi\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  ;;\n\nnewsos6)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  ;;\n\n*nto* | *qnx*)\n  version_type=qnx\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  dynamic_linker='ldqnx.so'\n  ;;\n\nopenbsd*)\n  version_type=sunos\n  sys_lib_dlsearch_path_spec=\"/usr/lib\"\n  need_lib_prefix=no\n  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.\n  case $host_os in\n    openbsd3.3 | openbsd3.3.*)\tneed_version=yes ;;\n    *)\t\t\t\tneed_version=no  ;;\n  esac\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/sbin\" ldconfig -m $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    case $host_os in\n      openbsd2.[[89]] | openbsd2.[[89]].*)\n\tshlibpath_overrides_runpath=no\n\t;;\n      *)\n\tshlibpath_overrides_runpath=yes\n\t;;\n      esac\n  else\n    shlibpath_overrides_runpath=yes\n  fi\n  ;;\n\nos2*)\n  libname_spec='$name'\n  shrext_cmds=\".dll\"\n  need_lib_prefix=no\n  library_names_spec='$libname${shared_ext} $libname.a'\n  dynamic_linker='OS/2 ld.exe'\n  shlibpath_var=LIBPATH\n  ;;\n\nosf3* | osf4* | osf5*)\n  version_type=osf\n  need_lib_prefix=no\n  need_version=no\n  soname_spec='${libname}${release}${shared_ext}$major'\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  sys_lib_search_path_spec=\"/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib\"\n  sys_lib_dlsearch_path_spec=\"$sys_lib_search_path_spec\"\n  ;;\n\nrdos*)\n  dynamic_linker=no\n  ;;\n\nsolaris*)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  # ldd complains unless libraries are executable\n  postinstall_cmds='chmod +x $lib'\n  ;;\n\nsunos4*)\n  version_type=sunos\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'\n  finish_cmds='PATH=\"\\$PATH:/usr/etc\" ldconfig $libdir'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  if test \"$with_gnu_ld\" = yes; then\n    need_lib_prefix=no\n  fi\n  need_version=yes\n  ;;\n\nsysv4 | sysv4.3*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  case $host_vendor in\n    sni)\n      shlibpath_overrides_runpath=no\n      need_lib_prefix=no\n      runpath_var=LD_RUN_PATH\n      ;;\n    siemens)\n      need_lib_prefix=no\n      ;;\n    motorola)\n      need_lib_prefix=no\n      need_version=no\n      shlibpath_overrides_runpath=no\n      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'\n      ;;\n  esac\n  ;;\n\nsysv4*MP*)\n  if test -d /usr/nec ;then\n    version_type=linux\n    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'\n    soname_spec='$libname${shared_ext}.$major'\n    shlibpath_var=LD_LIBRARY_PATH\n  fi\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  version_type=freebsd-elf\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=yes\n  hardcode_into_libs=yes\n  if test \"$with_gnu_ld\" = yes; then\n    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'\n  else\n    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'\n    case $host_os in\n      sco3.2v5*)\n        sys_lib_search_path_spec=\"$sys_lib_search_path_spec /lib\"\n\t;;\n    esac\n  fi\n  sys_lib_dlsearch_path_spec='/usr/lib'\n  ;;\n\ntpf*)\n  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\nuts4*)\n  version_type=linux\n  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'\n  soname_spec='${libname}${release}${shared_ext}$major'\n  shlibpath_var=LD_LIBRARY_PATH\n  ;;\n\n*)\n  dynamic_linker=no\n  ;;\nesac\nAC_MSG_RESULT([$dynamic_linker])\ntest \"$dynamic_linker\" = no && can_build_shared=no\n\nvariables_saved_for_relink=\"PATH $shlibpath_var $runpath_var\"\nif test \"$GCC\" = yes; then\n  variables_saved_for_relink=\"$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH\"\nfi\n\nif test \"${lt_cv_sys_lib_search_path_spec+set}\" = set; then\n  sys_lib_search_path_spec=\"$lt_cv_sys_lib_search_path_spec\"\nfi\nif test \"${lt_cv_sys_lib_dlsearch_path_spec+set}\" = set; then\n  sys_lib_dlsearch_path_spec=\"$lt_cv_sys_lib_dlsearch_path_spec\"\nfi\n\n_LT_DECL([], [variables_saved_for_relink], [1],\n    [Variables whose values should be saved in libtool wrapper scripts and\n    restored at link time])\n_LT_DECL([], [need_lib_prefix], [0],\n    [Do we need the \"lib\" prefix for modules?])\n_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])\n_LT_DECL([], [version_type], [0], [Library versioning type])\n_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])\n_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])\n_LT_DECL([], [shlibpath_overrides_runpath], [0],\n    [Is shlibpath searched before the hard-coded library search path?])\n_LT_DECL([], [libname_spec], [1], [Format of library name prefix])\n_LT_DECL([], [library_names_spec], [1],\n    [[List of archive names.  First name is the real one, the rest are links.\n    The last name is the one that the linker finds with -lNAME]])\n_LT_DECL([], [soname_spec], [1],\n    [[The coded name of the library, if different from the real name]])\n_LT_DECL([], [postinstall_cmds], [2],\n    [Command to use after installation of a shared archive])\n_LT_DECL([], [postuninstall_cmds], [2],\n    [Command to use after uninstallation of a shared archive])\n_LT_DECL([], [finish_cmds], [2],\n    [Commands used to finish a libtool library installation in a directory])\n_LT_DECL([], [finish_eval], [1],\n    [[As \"finish_cmds\", except a single script fragment to be evaled but\n    not shown]])\n_LT_DECL([], [hardcode_into_libs], [0],\n    [Whether we should hardcode library paths into libraries])\n_LT_DECL([], [sys_lib_search_path_spec], [2],\n    [Compile-time system search path for libraries])\n_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],\n    [Run-time system search path for libraries])\n])# _LT_SYS_DYNAMIC_LINKER\n\n\n# _LT_PATH_TOOL_PREFIX(TOOL)\n# --------------------------\n# find a file program which can recognize shared library\nAC_DEFUN([_LT_PATH_TOOL_PREFIX],\n[m4_require([_LT_DECL_EGREP])dnl\nAC_MSG_CHECKING([for $1])\nAC_CACHE_VAL(lt_cv_path_MAGIC_CMD,\n[case $MAGIC_CMD in\n[[\\\\/*] |  ?:[\\\\/]*])\n  lt_cv_path_MAGIC_CMD=\"$MAGIC_CMD\" # Let the user override the test with a path.\n  ;;\n*)\n  lt_save_MAGIC_CMD=\"$MAGIC_CMD\"\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\ndnl $ac_dummy forces splitting on constant user-supplied paths.\ndnl POSIX.2 word splitting is done only on the output of word expansions,\ndnl not every word.  This closes a longstanding sh security hole.\n  ac_dummy=\"m4_if([$2], , $PATH, [$2])\"\n  for ac_dir in $ac_dummy; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f $ac_dir/$1; then\n      lt_cv_path_MAGIC_CMD=\"$ac_dir/$1\"\n      if test -n \"$file_magic_test_file\"; then\n\tcase $deplibs_check_method in\n\t\"file_magic \"*)\n\t  file_magic_regex=`expr \"$deplibs_check_method\" : \"file_magic \\(.*\\)\"`\n\t  MAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\n\t  if eval $file_magic_cmd \\$file_magic_test_file 2> /dev/null |\n\t    $EGREP \"$file_magic_regex\" > /dev/null; then\n\t    :\n\t  else\n\t    cat <<_LT_EOF 1>&2\n\n*** Warning: the command libtool uses to detect shared libraries,\n*** $file_magic_cmd, produces output that libtool cannot recognize.\n*** The result is that libtool may fail to recognize shared libraries\n*** as such.  This will affect the creation of libtool libraries that\n*** depend on shared libraries, but programs linked with such libtool\n*** libraries will work regardless of this problem.  Nevertheless, you\n*** may want to report the problem to your system manager and/or to\n*** bug-libtool@gnu.org\n\n_LT_EOF\n\t  fi ;;\n\tesac\n      fi\n      break\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\n  MAGIC_CMD=\"$lt_save_MAGIC_CMD\"\n  ;;\nesac])\nMAGIC_CMD=\"$lt_cv_path_MAGIC_CMD\"\nif test -n \"$MAGIC_CMD\"; then\n  AC_MSG_RESULT($MAGIC_CMD)\nelse\n  AC_MSG_RESULT(no)\nfi\n_LT_DECL([], [MAGIC_CMD], [0],\n\t [Used to examine libraries when file_magic_cmd begins with \"file\"])dnl\n])# _LT_PATH_TOOL_PREFIX\n\n# Old name:\nAU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])\n\n\n# _LT_PATH_MAGIC\n# --------------\n# find a file program which can recognize a shared library\nm4_defun([_LT_PATH_MAGIC],\n[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)\nif test -z \"$lt_cv_path_MAGIC_CMD\"; then\n  if test -n \"$ac_tool_prefix\"; then\n    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)\n  else\n    MAGIC_CMD=:\n  fi\nfi\n])# _LT_PATH_MAGIC\n\n\n# LT_PATH_LD\n# ----------\n# find the pathname to the GNU or non-GNU linker\nAC_DEFUN([LT_PATH_LD],\n[AC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_CANONICAL_BUILD])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_DECL_EGREP])dnl\n\nAC_ARG_WITH([gnu-ld],\n    [AS_HELP_STRING([--with-gnu-ld],\n\t[assume the C compiler uses GNU ld @<:@default=no@:>@])],\n    [test \"$withval\" = no || with_gnu_ld=yes],\n    [with_gnu_ld=no])dnl\n\nac_prog=ld\nif test \"$GCC\" = yes; then\n  # Check if gcc -print-prog-name=ld gives a path.\n  AC_MSG_CHECKING([for ld used by $CC])\n  case $host in\n  *-*-mingw*)\n    # gcc leaves a trailing carriage return which upsets mingw\n    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\\015'` ;;\n  *)\n    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;\n  esac\n  case $ac_prog in\n    # Accept absolute paths.\n    [[\\\\/]]* | ?:[[\\\\/]]*)\n      re_direlt='/[[^/]][[^/]]*/\\.\\./'\n      # Canonicalize the pathname of ld\n      ac_prog=`$ECHO \"$ac_prog\"| $SED 's%\\\\\\\\%/%g'`\n      while $ECHO \"$ac_prog\" | $GREP \"$re_direlt\" > /dev/null 2>&1; do\n\tac_prog=`$ECHO $ac_prog| $SED \"s%$re_direlt%/%\"`\n      done\n      test -z \"$LD\" && LD=\"$ac_prog\"\n      ;;\n  \"\")\n    # If it fails, then pretend we aren't using GCC.\n    ac_prog=ld\n    ;;\n  *)\n    # If it is relative, then search for the first ld in PATH.\n    with_gnu_ld=unknown\n    ;;\n  esac\nelif test \"$with_gnu_ld\" = yes; then\n  AC_MSG_CHECKING([for GNU ld])\nelse\n  AC_MSG_CHECKING([for non-GNU ld])\nfi\nAC_CACHE_VAL(lt_cv_path_LD,\n[if test -z \"$LD\"; then\n  lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n  for ac_dir in $PATH; do\n    IFS=\"$lt_save_ifs\"\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f \"$ac_dir/$ac_prog\" || test -f \"$ac_dir/$ac_prog$ac_exeext\"; then\n      lt_cv_path_LD=\"$ac_dir/$ac_prog\"\n      # Check to see if the program is GNU ld.  I'd rather use --version,\n      # but apparently some variants of GNU ld only accept -v.\n      # Break only if it was the GNU/non-GNU ld that we prefer.\n      case `\"$lt_cv_path_LD\" -v 2>&1 </dev/null` in\n      *GNU* | *'with BFD'*)\n\ttest \"$with_gnu_ld\" != no && break\n\t;;\n      *)\n\ttest \"$with_gnu_ld\" != yes && break\n\t;;\n      esac\n    fi\n  done\n  IFS=\"$lt_save_ifs\"\nelse\n  lt_cv_path_LD=\"$LD\" # Let the user override the test with a path.\nfi])\nLD=\"$lt_cv_path_LD\"\nif test -n \"$LD\"; then\n  AC_MSG_RESULT($LD)\nelse\n  AC_MSG_RESULT(no)\nfi\ntest -z \"$LD\" && AC_MSG_ERROR([no acceptable ld found in \\$PATH])\n_LT_PATH_LD_GNU\nAC_SUBST([LD])\n\n_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])\n])# LT_PATH_LD\n\n# Old names:\nAU_ALIAS([AM_PROG_LD], [LT_PATH_LD])\nAU_ALIAS([AC_PROG_LD], [LT_PATH_LD])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_PROG_LD], [])\ndnl AC_DEFUN([AC_PROG_LD], [])\n\n\n# _LT_PATH_LD_GNU\n#- --------------\nm4_defun([_LT_PATH_LD_GNU],\n[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,\n[# I'd rather use --version here, but apparently some GNU lds only accept -v.\ncase `$LD -v 2>&1 </dev/null` in\n*GNU* | *'with BFD'*)\n  lt_cv_prog_gnu_ld=yes\n  ;;\n*)\n  lt_cv_prog_gnu_ld=no\n  ;;\nesac])\nwith_gnu_ld=$lt_cv_prog_gnu_ld\n])# _LT_PATH_LD_GNU\n\n\n# _LT_CMD_RELOAD\n# --------------\n# find reload flag for linker\n#   -- PORTME Some linkers may need a different reload flag.\nm4_defun([_LT_CMD_RELOAD],\n[AC_CACHE_CHECK([for $LD option to reload object files],\n  lt_cv_ld_reload_flag,\n  [lt_cv_ld_reload_flag='-r'])\nreload_flag=$lt_cv_ld_reload_flag\ncase $reload_flag in\n\"\" | \" \"*) ;;\n*) reload_flag=\" $reload_flag\" ;;\nesac\nreload_cmds='$LD$reload_flag -o $output$reload_objs'\ncase $host_os in\n  darwin*)\n    if test \"$GCC\" = yes; then\n      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'\n    else\n      reload_cmds='$LD$reload_flag -o $output$reload_objs'\n    fi\n    ;;\nesac\n_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl\n_LT_DECL([], [reload_cmds], [2])dnl\n])# _LT_CMD_RELOAD\n\n\n# _LT_CHECK_MAGIC_METHOD\n# ----------------------\n# how to check for library dependencies\n#  -- PORTME fill in with the dynamic library characteristics\nm4_defun([_LT_CHECK_MAGIC_METHOD],\n[m4_require([_LT_DECL_EGREP])\nm4_require([_LT_DECL_OBJDUMP])\nAC_CACHE_CHECK([how to recognize dependent libraries],\nlt_cv_deplibs_check_method,\n[lt_cv_file_magic_cmd='$MAGIC_CMD'\nlt_cv_file_magic_test_file=\nlt_cv_deplibs_check_method='unknown'\n# Need to set the preceding variable on all platforms that support\n# interlibrary dependencies.\n# 'none' -- dependencies not supported.\n# `unknown' -- same as none, but documents that we really don't know.\n# 'pass_all' -- all dependencies passed with no checks.\n# 'test_compile' -- check by making test program.\n# 'file_magic [[regex]]' -- check by looking for files in library path\n# which responds to the $file_magic_cmd with a given extended regex.\n# If you have `file' or equivalent on your system and you're not sure\n# whether `pass_all' will *always* work, you probably want this one.\n\ncase $host_os in\naix[[4-9]]*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbeos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nbsdi[[45]]*)\n  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'\n  lt_cv_file_magic_cmd='/usr/bin/file -L'\n  lt_cv_file_magic_test_file=/shlib/libc.so\n  ;;\n\ncygwin*)\n  # func_win32_libid is a shell function defined in ltmain.sh\n  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n  lt_cv_file_magic_cmd='func_win32_libid'\n  ;;\n\nmingw* | pw32*)\n  # Base MSYS/MinGW do not provide the 'file' command needed by\n  # func_win32_libid shell function, so use a weaker test based on 'objdump',\n  # unless we find 'file', for example because we are cross-compiling.\n  if ( file / ) >/dev/null 2>&1; then\n    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'\n    lt_cv_file_magic_cmd='func_win32_libid'\n  else\n    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'\n    lt_cv_file_magic_cmd='$OBJDUMP -f'\n  fi\n  ;;\n\ncegcc)\n  # use the weaker test based on 'objdump'. See mingw*.\n  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'\n  lt_cv_file_magic_cmd='$OBJDUMP -f'\n  ;;\n\ndarwin* | rhapsody*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nfreebsd* | dragonfly*)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    case $host_cpu in\n    i*86 )\n      # Not sure whether the presence of OpenBSD here was a mistake.\n      # Let's accept both of them until this is cleared up.\n      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'\n      lt_cv_file_magic_cmd=/usr/bin/file\n      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`\n      ;;\n    esac\n  else\n    lt_cv_deplibs_check_method=pass_all\n  fi\n  ;;\n\ngnu*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nhpux10.20* | hpux11*)\n  lt_cv_file_magic_cmd=/usr/bin/file\n  case $host_cpu in\n  ia64*)\n    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'\n    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so\n    ;;\n  hppa*64*)\n    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']\n    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl\n    ;;\n  *)\n    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'\n    lt_cv_file_magic_test_file=/usr/lib/libc.sl\n    ;;\n  esac\n  ;;\n\ninterix[[3-9]]*)\n  # PIC code is broken on Interix 3.x, that's why |\\.a not |_pic\\.a here\n  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so|\\.a)$'\n  ;;\n\nirix5* | irix6* | nonstopux*)\n  case $LD in\n  *-32|*\"-32 \") libmagic=32-bit;;\n  *-n32|*\"-n32 \") libmagic=N32;;\n  *-64|*\"-64 \") libmagic=64-bit;;\n  *) libmagic=never-match;;\n  esac\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\n# This must be Linux ELF.\nlinux* | k*bsd*-gnu | kopensolaris*-gnu)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nnetbsd* | netbsdelf*-gnu)\n  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so\\.[[0-9]]+\\.[[0-9]]+|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so|_pic\\.a)$'\n  fi\n  ;;\n\nnewos6*)\n  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'\n  lt_cv_file_magic_cmd=/usr/bin/file\n  lt_cv_file_magic_test_file=/usr/lib/libnls.so\n  ;;\n\n*nto* | *qnx*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nopenbsd*)\n  if test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so\\.[[0-9]]+\\.[[0-9]]+|\\.so|_pic\\.a)$'\n  else\n    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\\.so\\.[[0-9]]+\\.[[0-9]]+|_pic\\.a)$'\n  fi\n  ;;\n\nosf3* | osf4* | osf5*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nrdos*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsolaris*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\n\nsysv4 | sysv4.3*)\n  case $host_vendor in\n  motorola)\n    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'\n    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`\n    ;;\n  ncr)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  sequent)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'\n    ;;\n  sni)\n    lt_cv_file_magic_cmd='/bin/file'\n    lt_cv_deplibs_check_method=\"file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib\"\n    lt_cv_file_magic_test_file=/lib/libc.so\n    ;;\n  siemens)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  pc)\n    lt_cv_deplibs_check_method=pass_all\n    ;;\n  esac\n  ;;\n\ntpf*)\n  lt_cv_deplibs_check_method=pass_all\n  ;;\nesac\n])\nfile_magic_cmd=$lt_cv_file_magic_cmd\ndeplibs_check_method=$lt_cv_deplibs_check_method\ntest -z \"$deplibs_check_method\" && deplibs_check_method=unknown\n\n_LT_DECL([], [deplibs_check_method], [1],\n    [Method to check whether dependent libraries are shared objects])\n_LT_DECL([], [file_magic_cmd], [1],\n    [Command to use when deplibs_check_method == \"file_magic\"])\n])# _LT_CHECK_MAGIC_METHOD\n\n\n# LT_PATH_NM\n# ----------\n# find the pathname to a BSD- or MS-compatible name lister\nAC_DEFUN([LT_PATH_NM],\n[AC_REQUIRE([AC_PROG_CC])dnl\nAC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,\n[if test -n \"$NM\"; then\n  # Let the user override the test.\n  lt_cv_path_NM=\"$NM\"\nelse\n  lt_nm_to_check=\"${ac_tool_prefix}nm\"\n  if test -n \"$ac_tool_prefix\" && test \"$build\" = \"$host\"; then\n    lt_nm_to_check=\"$lt_nm_to_check nm\"\n  fi\n  for lt_tmp_nm in $lt_nm_to_check; do\n    lt_save_ifs=\"$IFS\"; IFS=$PATH_SEPARATOR\n    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do\n      IFS=\"$lt_save_ifs\"\n      test -z \"$ac_dir\" && ac_dir=.\n      tmp_nm=\"$ac_dir/$lt_tmp_nm\"\n      if test -f \"$tmp_nm\" || test -f \"$tmp_nm$ac_exeext\" ; then\n\t# Check to see if the nm accepts a BSD-compat flag.\n\t# Adding the `sed 1q' prevents false positives on HP-UX, which says:\n\t#   nm: unknown option \"B\" ignored\n\t# Tru64's nm complains that /dev/null is an invalid object file\n\tcase `\"$tmp_nm\" -B /dev/null 2>&1 | sed '1q'` in\n\t*/dev/null* | *'Invalid file or object type'*)\n\t  lt_cv_path_NM=\"$tmp_nm -B\"\n\t  break\n\t  ;;\n\t*)\n\t  case `\"$tmp_nm\" -p /dev/null 2>&1 | sed '1q'` in\n\t  */dev/null*)\n\t    lt_cv_path_NM=\"$tmp_nm -p\"\n\t    break\n\t    ;;\n\t  *)\n\t    lt_cv_path_NM=${lt_cv_path_NM=\"$tmp_nm\"} # keep the first match, but\n\t    continue # so that we can try to find one that supports BSD flags\n\t    ;;\n\t  esac\n\t  ;;\n\tesac\n      fi\n    done\n    IFS=\"$lt_save_ifs\"\n  done\n  : ${lt_cv_path_NM=no}\nfi])\nif test \"$lt_cv_path_NM\" != \"no\"; then\n  NM=\"$lt_cv_path_NM\"\nelse\n  # Didn't find any BSD compatible name lister, look for dumpbin.\n  AC_CHECK_TOOLS(DUMPBIN, [\"dumpbin -symbols\" \"link -dump -symbols\"], :)\n  AC_SUBST([DUMPBIN])\n  if test \"$DUMPBIN\" != \":\"; then\n    NM=\"$DUMPBIN\"\n  fi\nfi\ntest -z \"$NM\" && NM=nm\nAC_SUBST([NM])\n_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl\n\nAC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],\n  [lt_cv_nm_interface=\"BSD nm\"\n  echo \"int some_variable = 0;\" > conftest.$ac_ext\n  (eval echo \"\\\"\\$as_me:__oline__: $ac_compile\\\"\" >&AS_MESSAGE_LOG_FD)\n  (eval \"$ac_compile\" 2>conftest.err)\n  cat conftest.err >&AS_MESSAGE_LOG_FD\n  (eval echo \"\\\"\\$as_me:__oline__: $NM \\\\\\\"conftest.$ac_objext\\\\\\\"\\\"\" >&AS_MESSAGE_LOG_FD)\n  (eval \"$NM \\\"conftest.$ac_objext\\\"\" 2>conftest.err > conftest.out)\n  cat conftest.err >&AS_MESSAGE_LOG_FD\n  (eval echo \"\\\"\\$as_me:__oline__: output\\\"\" >&AS_MESSAGE_LOG_FD)\n  cat conftest.out >&AS_MESSAGE_LOG_FD\n  if $GREP 'External.*some_variable' conftest.out > /dev/null; then\n    lt_cv_nm_interface=\"MS dumpbin\"\n  fi\n  rm -f conftest*])\n])# LT_PATH_NM\n\n# Old names:\nAU_ALIAS([AM_PROG_NM], [LT_PATH_NM])\nAU_ALIAS([AC_PROG_NM], [LT_PATH_NM])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_PROG_NM], [])\ndnl AC_DEFUN([AC_PROG_NM], [])\n\n\n# LT_LIB_M\n# --------\n# check for math library\nAC_DEFUN([LT_LIB_M],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nLIBM=\ncase $host in\n*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)\n  # These system don't have libm, or don't need it\n  ;;\n*-ncr-sysv4.3*)\n  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=\"-lmw\")\n  AC_CHECK_LIB(m, cos, LIBM=\"$LIBM -lm\")\n  ;;\n*)\n  AC_CHECK_LIB(m, cos, LIBM=\"-lm\")\n  ;;\nesac\nAC_SUBST([LIBM])\n])# LT_LIB_M\n\n# Old name:\nAU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_CHECK_LIBM], [])\n\n\n# _LT_COMPILER_NO_RTTI([TAGNAME])\n# -------------------------------\nm4_defun([_LT_COMPILER_NO_RTTI],\n[m4_require([_LT_TAG_COMPILER])dnl\n\n_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=\n\nif test \"$GCC\" = yes; then\n  _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'\n\n  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],\n    lt_cv_prog_compiler_rtti_exceptions,\n    [-fno-rtti -fno-exceptions], [],\n    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=\"$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions\"])\nfi\n_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],\n\t[Compiler flag to turn off builtin functions])\n])# _LT_COMPILER_NO_RTTI\n\n\n# _LT_CMD_GLOBAL_SYMBOLS\n# ----------------------\nm4_defun([_LT_CMD_GLOBAL_SYMBOLS],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\nAC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([LT_PATH_NM])dnl\nAC_REQUIRE([LT_PATH_LD])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_TAG_COMPILER])dnl\n\n# Check for command to grab the raw symbol name followed by C symbol from nm.\nAC_MSG_CHECKING([command to parse $NM output from $compiler object])\nAC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],\n[\n# These are sane defaults that work on at least a few old systems.\n# [They come from Ultrix.  What could be older than Ultrix?!! ;)]\n\n# Character class describing NM global symbol codes.\nsymcode='[[BCDEGRST]]'\n\n# Regexp to match symbols that can be accessed directly from C.\nsympat='\\([[_A-Za-z]][[_A-Za-z0-9]]*\\)'\n\n# Define system-specific variables.\ncase $host_os in\naix*)\n  symcode='[[BCDT]]'\n  ;;\ncygwin* | mingw* | pw32* | cegcc*)\n  symcode='[[ABCDGISTW]]'\n  ;;\nhpux*)\n  if test \"$host_cpu\" = ia64; then\n    symcode='[[ABCDEGRST]]'\n  fi\n  ;;\nirix* | nonstopux*)\n  symcode='[[BCDEGRST]]'\n  ;;\nosf*)\n  symcode='[[BCDEGQRST]]'\n  ;;\nsolaris*)\n  symcode='[[BDRT]]'\n  ;;\nsco3.2v5*)\n  symcode='[[DT]]'\n  ;;\nsysv4.2uw2*)\n  symcode='[[DT]]'\n  ;;\nsysv5* | sco5v6* | unixware* | OpenUNIX*)\n  symcode='[[ABDT]]'\n  ;;\nsysv4)\n  symcode='[[DFNSTU]]'\n  ;;\nesac\n\n# If we're using GNU nm, then use its standard symbol codes.\ncase `$NM -V 2>&1` in\n*GNU* | *'with BFD'*)\n  symcode='[[ABCDGIRSTW]]' ;;\nesac\n\n# Transform an extracted symbol line into a proper C declaration.\n# Some systems (esp. on ia64) link data and code symbols differently,\n# so use this general approach.\nlt_cv_sys_global_symbol_to_cdecl=\"sed -n -e 's/^T .* \\(.*\\)$/extern int \\1();/p' -e 's/^$symcode* .* \\(.*\\)$/extern char \\1;/p'\"\n\n# Transform an extracted symbol line into symbol name and symbol address\nlt_cv_sys_global_symbol_to_c_name_address=\"sed -n -e 's/^: \\([[^ ]]*\\) $/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([[^ ]]*\\) \\([[^ ]]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p'\"\nlt_cv_sys_global_symbol_to_c_name_address_lib_prefix=\"sed -n -e 's/^: \\([[^ ]]*\\) $/  {\\\\\\\"\\1\\\\\\\", (void *) 0},/p' -e 's/^$symcode* \\([[^ ]]*\\) \\(lib[[^ ]]*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/p' -e 's/^$symcode* \\([[^ ]]*\\) \\([[^ ]]*\\)$/  {\\\"lib\\2\\\", (void *) \\&\\2},/p'\"\n\n# Handle CRLF in mingw tool chain\nopt_cr=\ncase $build_os in\nmingw*)\n  opt_cr=`$ECHO 'x\\{0,1\\}' | tr x '\\015'` # option cr in regexp\n  ;;\nesac\n\n# Try without a prefix underscore, then with it.\nfor ac_symprfx in \"\" \"_\"; do\n\n  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.\n  symxfrm=\"\\\\1 $ac_symprfx\\\\2 \\\\2\"\n\n  # Write the raw and C identifiers.\n  if test \"$lt_cv_nm_interface\" = \"MS dumpbin\"; then\n    # Fake it for dumpbin and say T for any non-static function\n    # and D for any global variable.\n    # Also find C++ and __fastcall symbols from MSVC++,\n    # which start with @ or ?.\n    lt_cv_sys_global_symbol_pipe=\"$AWK ['\"\\\n\"     {last_section=section; section=\\$ 3};\"\\\n\"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};\"\\\n\"     \\$ 0!~/External *\\|/{next};\"\\\n\"     / 0+ UNDEF /{next}; / UNDEF \\([^|]\\)*()/{next};\"\\\n\"     {if(hide[section]) next};\"\\\n\"     {f=0}; \\$ 0~/\\(\\).*\\|/{f=1}; {printf f ? \\\"T \\\" : \\\"D \\\"};\"\\\n\"     {split(\\$ 0, a, /\\||\\r/); split(a[2], s)};\"\\\n\"     s[1]~/^[@?]/{print s[1], s[1]; next};\"\\\n\"     s[1]~prfx {split(s[1],t,\\\"@\\\"); print t[1], substr(t[1],length(prfx))}\"\\\n\"     ' prfx=^$ac_symprfx]\"\n  else\n    lt_cv_sys_global_symbol_pipe=\"sed -n -e 's/^.*[[\t ]]\\($symcode$symcode*\\)[[\t ]][[\t ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'\"\n  fi\n\n  # Check to see that the pipe works correctly.\n  pipe_works=no\n\n  rm -f conftest*\n  cat > conftest.$ac_ext <<_LT_EOF\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nchar nm_test_var;\nvoid nm_test_func(void);\nvoid nm_test_func(void){}\n#ifdef __cplusplus\n}\n#endif\nint main(){nm_test_var='a';nm_test_func();return(0);}\n_LT_EOF\n\n  if AC_TRY_EVAL(ac_compile); then\n    # Now try to grab the symbols.\n    nlist=conftest.nm\n    if AC_TRY_EVAL(NM conftest.$ac_objext \\| $lt_cv_sys_global_symbol_pipe \\> $nlist) && test -s \"$nlist\"; then\n      # Try sorting and uniquifying the output.\n      if sort \"$nlist\" | uniq > \"$nlist\"T; then\n\tmv -f \"$nlist\"T \"$nlist\"\n      else\n\trm -f \"$nlist\"T\n      fi\n\n      # Make sure that we snagged all the symbols we need.\n      if $GREP ' nm_test_var$' \"$nlist\" >/dev/null; then\n\tif $GREP ' nm_test_func$' \"$nlist\" >/dev/null; then\n\t  cat <<_LT_EOF > conftest.$ac_ext\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n_LT_EOF\n\t  # Now generate the symbol file.\n\t  eval \"$lt_cv_sys_global_symbol_to_cdecl\"' < \"$nlist\" | $GREP -v main >> conftest.$ac_ext'\n\n\t  cat <<_LT_EOF >> conftest.$ac_ext\n\n/* The mapping between symbol names and symbols.  */\nconst struct {\n  const char *name;\n  void       *address;\n}\nlt__PROGRAM__LTX_preloaded_symbols[[]] =\n{\n  { \"@PROGRAM@\", (void *) 0 },\n_LT_EOF\n\t  $SED \"s/^$symcode$symcode* \\(.*\\) \\(.*\\)$/  {\\\"\\2\\\", (void *) \\&\\2},/\" < \"$nlist\" | $GREP -v main >> conftest.$ac_ext\n\t  cat <<\\_LT_EOF >> conftest.$ac_ext\n  {0, (void *) 0}\n};\n\n/* This works around a problem in FreeBSD linker */\n#ifdef FREEBSD_WORKAROUND\nstatic const void *lt_preloaded_setup() {\n  return lt__PROGRAM__LTX_preloaded_symbols;\n}\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n_LT_EOF\n\t  # Now try linking the two files.\n\t  mv conftest.$ac_objext conftstm.$ac_objext\n\t  lt_save_LIBS=\"$LIBS\"\n\t  lt_save_CFLAGS=\"$CFLAGS\"\n\t  LIBS=\"conftstm.$ac_objext\"\n\t  CFLAGS=\"$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)\"\n\t  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then\n\t    pipe_works=yes\n\t  fi\n\t  LIBS=\"$lt_save_LIBS\"\n\t  CFLAGS=\"$lt_save_CFLAGS\"\n\telse\n\t  echo \"cannot find nm_test_func in $nlist\" >&AS_MESSAGE_LOG_FD\n\tfi\n      else\n\techo \"cannot find nm_test_var in $nlist\" >&AS_MESSAGE_LOG_FD\n      fi\n    else\n      echo \"cannot run $lt_cv_sys_global_symbol_pipe\" >&AS_MESSAGE_LOG_FD\n    fi\n  else\n    echo \"$progname: failed program was:\" >&AS_MESSAGE_LOG_FD\n    cat conftest.$ac_ext >&5\n  fi\n  rm -rf conftest* conftst*\n\n  # Do not use the global_symbol_pipe unless it works.\n  if test \"$pipe_works\" = yes; then\n    break\n  else\n    lt_cv_sys_global_symbol_pipe=\n  fi\ndone\n])\nif test -z \"$lt_cv_sys_global_symbol_pipe\"; then\n  lt_cv_sys_global_symbol_to_cdecl=\nfi\nif test -z \"$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl\"; then\n  AC_MSG_RESULT(failed)\nelse\n  AC_MSG_RESULT(ok)\nfi\n\n_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],\n    [Take the output of nm and produce a listing of raw symbols and C names])\n_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],\n    [Transform the output of nm in a proper C declaration])\n_LT_DECL([global_symbol_to_c_name_address],\n    [lt_cv_sys_global_symbol_to_c_name_address], [1],\n    [Transform the output of nm in a C name address pair])\n_LT_DECL([global_symbol_to_c_name_address_lib_prefix],\n    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],\n    [Transform the output of nm in a C name address pair when lib prefix is needed])\n]) # _LT_CMD_GLOBAL_SYMBOLS\n\n\n# _LT_COMPILER_PIC([TAGNAME])\n# ---------------------------\nm4_defun([_LT_COMPILER_PIC],\n[m4_require([_LT_TAG_COMPILER])dnl\n_LT_TAGVAR(lt_prog_compiler_wl, $1)=\n_LT_TAGVAR(lt_prog_compiler_pic, $1)=\n_LT_TAGVAR(lt_prog_compiler_static, $1)=\n\nAC_MSG_CHECKING([for $compiler option to produce PIC])\nm4_if([$1], [CXX], [\n  # C++ specific cases for pic, static, wl, etc.\n  if test \"$GXX\" = yes; then\n    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\n    case $host_os in\n    aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n    mingw* | cygwin* | os2* | pw32* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      m4_if([$1], [GCJ], [],\n\t[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n      ;;\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'\n      ;;\n    *djgpp*)\n      # DJGPP does not support shared libraries at all\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n      ;;\n    interix[[3-9]]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic\n      fi\n      ;;\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t;;\n      esac\n      ;;\n    *qnx* | *nto*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n      ;;\n    *)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n      ;;\n    esac\n  else\n    case $host_os in\n      aix[[4-9]]*)\n\t# All AIX code is PIC.\n\tif test \"$host_cpu\" = ia64; then\n\t  # AIX 5 now supports IA64 processor\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\telse\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'\n\tfi\n\t;;\n      chorus*)\n\tcase $cc_basename in\n\tcxch68*)\n\t  # Green Hills C++ Compiler\n\t  # _LT_TAGVAR(lt_prog_compiler_static, $1)=\"--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a\"\n\t  ;;\n\tesac\n\t;;\n      dgux*)\n\tcase $cc_basename in\n\t  ec++*)\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    ;;\n\t  ghcx*)\n\t    # Green Hills C++ Compiler\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      freebsd* | dragonfly*)\n\t# FreeBSD uses GNU C++\n\t;;\n      hpux9* | hpux10* | hpux11*)\n\tcase $cc_basename in\n\t  CC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'\n\t    if test \"$host_cpu\" != ia64; then\n\t      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'\n\t    fi\n\t    ;;\n\t  aCC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'\n\t    case $host_cpu in\n\t    hppa*64*|ia64*)\n\t      # +Z the default\n\t      ;;\n\t    *)\n\t      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'\n\t      ;;\n\t    esac\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      interix*)\n\t# This is c89, which is MS Visual C++ (no shared libs)\n\t# Anyone wants to do a port?\n\t;;\n      irix5* | irix6* | nonstopux*)\n\tcase $cc_basename in\n\t  CC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n\t    # CC pic flag -KPIC is the default.\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      linux* | k*bsd*-gnu | kopensolaris*-gnu)\n\tcase $cc_basename in\n\t  KCC*)\n\t    # KAI C++ Compiler\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t    ;;\n\t  ecpc* )\n\t    # old Intel C++ for x86_64 which still supported -KPIC.\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\t    ;;\n\t  icpc* )\n\t    # Intel C++, used to be incompatible with GCC.\n\t    # ICC 10 doesn't accept -KPIC any more.\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\t    ;;\n\t  pgCC* | pgcpp*)\n\t    # Portland Group C++ compiler\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    ;;\n\t  cxx*)\n\t    # Compaq C++\n\t    # Make sure the PIC flag is empty.  It appears that all Alpha\n\t    # Linux and Compaq Tru64 Unix objects are PIC.\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n\t    ;;\n\t  xlc* | xlC*)\n\t    # IBM XL 8.0 on PPC\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'\n\t    ;;\n\t  *)\n\t    case `$CC -V 2>&1 | sed 5q` in\n\t    *Sun\\ C*)\n\t      # Sun C++ 5.9\n\t      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n\t      ;;\n\t    esac\n\t    ;;\n\tesac\n\t;;\n      lynxos*)\n\t;;\n      m88k*)\n\t;;\n      mvs*)\n\tcase $cc_basename in\n\t  cxx*)\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      netbsd* | netbsdelf*-gnu)\n\t;;\n      *qnx* | *nto*)\n        # QNX uses GNU C++, but need to define -shared option too, otherwise\n        # it will coredump.\n        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n        ;;\n      osf3* | osf4* | osf5*)\n\tcase $cc_basename in\n\t  KCC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'\n\t    ;;\n\t  RCC*)\n\t    # Rational C++ 2.4.1\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    ;;\n\t  cxx*)\n\t    # Digital/Compaq C++\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    # Make sure the PIC flag is empty.  It appears that all Alpha\n\t    # Linux and Compaq Tru64 Unix objects are PIC.\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      psos*)\n\t;;\n      solaris*)\n\tcase $cc_basename in\n\t  CC*)\n\t    # Sun C++ 4.2, 5.x and Centerline C++\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n\t    ;;\n\t  gcx*)\n\t    # Green Hills C++ Compiler\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      sunos4*)\n\tcase $cc_basename in\n\t  CC*)\n\t    # Sun C++ 4.x\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    ;;\n\t  lcc*)\n\t    # Lucid\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n\tcase $cc_basename in\n\t  CC*)\n\t    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t    ;;\n\tesac\n\t;;\n      tandem*)\n\tcase $cc_basename in\n\t  NCC*)\n\t    # NonStop-UX NCC 3.20\n\t    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t    ;;\n\t  *)\n\t    ;;\n\tesac\n\t;;\n      vxworks*)\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n\t;;\n    esac\n  fi\n],\n[\n  if test \"$GCC\" = yes; then\n    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n\n    case $host_os in\n      aix*)\n      # All AIX code is PIC.\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n        ;;\n      m68k)\n            # FIXME: we need at least 68020 code to build shared libraries, but\n            # adding the `-m68020' flag to GCC prevents building anything better,\n            # like `-m68040'.\n            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'\n        ;;\n      esac\n      ;;\n\n    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)\n      # PIC is the default for these OSes.\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      # Although the cygwin gcc ignores -fPIC, still need this for old-style\n      # (--disable-auto-import) libraries\n      m4_if([$1], [GCJ], [],\n\t[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n      ;;\n\n    darwin* | rhapsody*)\n      # PIC is the default on this platform\n      # Common symbols not allowed in MH_DYLIB files\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'\n      ;;\n\n    hpux*)\n      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit\n      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag\n      # sets the default TLS model and affects inlining.\n      case $host_cpu in\n      hppa*64*)\n\t# +Z the default\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t;;\n      esac\n      ;;\n\n    interix[[3-9]]*)\n      # Interix 3.x gcc -fpic/-fPIC options generate broken code.\n      # Instead, we relocate shared libraries at runtime.\n      ;;\n\n    msdosdjgpp*)\n      # Just because we use GCC doesn't mean we suddenly get shared libraries\n      # on systems that don't support them.\n      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n      enable_shared=no\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic\n      fi\n      ;;\n\n    *)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n      ;;\n    esac\n  else\n    # PORTME Check for flag to pass linker flags through the system compiler.\n    case $host_os in\n    aix*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      if test \"$host_cpu\" = ia64; then\n\t# AIX 5 now supports IA64 processor\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      else\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'\n      fi\n      ;;\n\n    mingw* | cygwin* | pw32* | os2* | cegcc*)\n      # This hack is so that the source file can tell whether it is being\n      # built for inclusion in a dll (and should export symbols for example).\n      m4_if([$1], [GCJ], [],\n\t[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])\n      ;;\n\n    hpux9* | hpux10* | hpux11*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but\n      # not for PA HP-UX.\n      case $host_cpu in\n      hppa*64*|ia64*)\n\t# +Z the default\n\t;;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'\n\t;;\n      esac\n      # Is there a better lt_prog_compiler_static that works with the bundled CC?\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      # PIC (with -KPIC) is the default.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n      ;;\n\n    linux* | k*bsd*-gnu | kopensolaris*-gnu)\n      case $cc_basename in\n      # old Intel for x86_64 which still supported -KPIC.\n      ecc*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n        ;;\n      # icc used to be incompatible with GCC.\n      # ICC 10 doesn't accept -KPIC any more.\n      icc* | ifort*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'\n        ;;\n      # Lahey Fortran 8.1.\n      lf95*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'\n\t;;\n      pgcc* | pgf77* | pgf90* | pgf95*)\n        # Portland Group compilers (*not* the Pentium gcc compiler,\n\t# which looks to be a dead project)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n        ;;\n      ccc*)\n        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n        # All Alpha code is PIC.\n        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n        ;;\n      xl*)\n\t# IBM XL C 8.0/Fortran 10.1 on PPC\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'\n\t;;\n      *)\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\n\t  # Sun C 5.9\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n\t  ;;\n\t*Sun\\ F*)\n\t  # Sun Fortran 8.3 passes all unrecognized flags to the linker\n\t  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n\t  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n\t  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''\n\t  ;;\n\tesac\n\t;;\n      esac\n      ;;\n\n    newsos6)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    *nto* | *qnx*)\n      # QNX uses GNU C++, but need to define -shared option too, otherwise\n      # it will coredump.\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'\n      ;;\n\n    osf3* | osf4* | osf5*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      # All OSF/1 code is PIC.\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n      ;;\n\n    rdos*)\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'\n      ;;\n\n    solaris*)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      case $cc_basename in\n      f77* | f90* | f95*)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;\n      *)\n\t_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;\n      esac\n      ;;\n\n    sunos4*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    sysv4 | sysv4.2uw2* | sysv4.3*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec ;then\n\t_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'\n\t_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      fi\n      ;;\n\n    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    unicos*)\n      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'\n      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n      ;;\n\n    uts4*)\n      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'\n      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'\n      ;;\n\n    *)\n      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no\n      ;;\n    esac\n  fi\n])\ncase $host_os in\n  # For platforms which do not support PIC, -DPIC is meaningless:\n  *djgpp*)\n    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\n    ;;\n  *)\n    _LT_TAGVAR(lt_prog_compiler_pic, $1)=\"$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])\"\n    ;;\nesac\nAC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])\n_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],\n\t[How to pass a linker flag through the compiler])\n\n#\n# Check to make sure the PIC flag actually works.\n#\nif test -n \"$_LT_TAGVAR(lt_prog_compiler_pic, $1)\"; then\n  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],\n    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],\n    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],\n    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in\n     \"\" | \" \"*) ;;\n     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=\" $_LT_TAGVAR(lt_prog_compiler_pic, $1)\" ;;\n     esac],\n    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=\n     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])\nfi\n_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],\n\t[Additional compiler flags for building library objects])\n\n#\n# Check to make sure the static flag actually works.\n#\nwl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\\\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\\\"\n_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],\n  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),\n  $lt_tmp_static_flag,\n  [],\n  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])\n_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],\n\t[Compiler flag to prevent dynamic linking])\n])# _LT_COMPILER_PIC\n\n\n# _LT_LINKER_SHLIBS([TAGNAME])\n# ----------------------------\n# See if the linker supports building shared libraries.\nm4_defun([_LT_LINKER_SHLIBS],\n[AC_REQUIRE([LT_PATH_LD])dnl\nAC_REQUIRE([LT_PATH_NM])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_EGREP])dnl\nm4_require([_LT_DECL_SED])dnl\nm4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl\nm4_require([_LT_TAG_COMPILER])dnl\nAC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])\nm4_if([$1], [CXX], [\n  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  case $host_os in\n  aix[[4-9]]*)\n    # If we're using GNU nm, then we don't want the \"-C\" option.\n    # -C means demangle to AIX nm, but means don't demangle with GNU nm\n    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n    else\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n    fi\n    ;;\n  pw32*)\n    _LT_TAGVAR(export_symbols_cmds, $1)=\"$ltdll_cmds\"\n  ;;\n  cygwin* | mingw* | cegcc*)\n    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\\([[^ ]]*\\)/\\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\\([[^ ]]*\\)[[ ]][[^ ]]*/\\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\\'' | sort | uniq > $export_symbols'\n  ;;\n  linux* | k*bsd*-gnu)\n    _LT_TAGVAR(link_all_deplibs, $1)=no\n  ;;\n  *)\n    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  ;;\n  esac\n  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']\n], [\n  runpath_var=\n  _LT_TAGVAR(allow_undefined_flag, $1)=\n  _LT_TAGVAR(always_export_symbols, $1)=no\n  _LT_TAGVAR(archive_cmds, $1)=\n  _LT_TAGVAR(archive_expsym_cmds, $1)=\n  _LT_TAGVAR(compiler_needs_object, $1)=no\n  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n  _LT_TAGVAR(export_dynamic_flag_spec, $1)=\n  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\\''s/.* //'\\'' | sort | uniq > $export_symbols'\n  _LT_TAGVAR(hardcode_automatic, $1)=no\n  _LT_TAGVAR(hardcode_direct, $1)=no\n  _LT_TAGVAR(hardcode_direct_absolute, $1)=no\n  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=\n  _LT_TAGVAR(hardcode_libdir_separator, $1)=\n  _LT_TAGVAR(hardcode_minus_L, $1)=no\n  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported\n  _LT_TAGVAR(inherit_rpath, $1)=no\n  _LT_TAGVAR(link_all_deplibs, $1)=unknown\n  _LT_TAGVAR(module_cmds, $1)=\n  _LT_TAGVAR(module_expsym_cmds, $1)=\n  _LT_TAGVAR(old_archive_from_new_cmds, $1)=\n  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=\n  _LT_TAGVAR(thread_safe_flag_spec, $1)=\n  _LT_TAGVAR(whole_archive_flag_spec, $1)=\n  # include_expsyms should be a list of space-separated symbols to be *always*\n  # included in the symbol list\n  _LT_TAGVAR(include_expsyms, $1)=\n  # exclude_expsyms can be an extended regexp of symbols to exclude\n  # it will be wrapped by ` (' and `)$', so one must not match beginning or\n  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',\n  # as well as any symbol that contains `d'.\n  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']\n  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out\n  # platforms (ab)use it in PIC code, but their linkers get confused if\n  # the symbol is explicitly referenced.  Since portable code cannot\n  # rely on this symbol name, it's probably fine to never include it in\n  # preloaded symbol tables.\n  # Exclude shared library initialization/finalization symbols.\ndnl Note also adjust exclude_expsyms for C++ above.\n  extract_expsyms_cmds=\n\n  case $host_os in\n  cygwin* | mingw* | pw32* | cegcc*)\n    # FIXME: the MSVC++ port hasn't been tested in a loooong time\n    # When not using gcc, we currently assume that we are using\n    # Microsoft Visual C++.\n    if test \"$GCC\" != yes; then\n      with_gnu_ld=no\n    fi\n    ;;\n  interix*)\n    # we just hope/assume this is gcc and not c89 (= MSVC++)\n    with_gnu_ld=yes\n    ;;\n  openbsd*)\n    with_gnu_ld=no\n    ;;\n  linux* | k*bsd*-gnu)\n    _LT_TAGVAR(link_all_deplibs, $1)=no\n    ;;\n  esac\n\n  _LT_TAGVAR(ld_shlibs, $1)=yes\n  if test \"$with_gnu_ld\" = yes; then\n    # If archive_cmds runs LD, not CC, wlarc should be empty\n    wlarc='${wl}'\n\n    # Set some defaults for GNU ld with shared library support. These\n    # are reset later if shared libraries are not supported. Putting them\n    # here allows them to be overridden if necessary.\n    runpath_var=LD_RUN_PATH\n    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n    # ancient GNU ld didn't support --whole-archive et. al.\n    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then\n      _LT_TAGVAR(whole_archive_flag_spec, $1)=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n    else\n      _LT_TAGVAR(whole_archive_flag_spec, $1)=\n    fi\n    supports_anon_versioning=no\n    case `$LD -v 2>&1` in\n      *GNU\\ gold*) supports_anon_versioning=yes ;;\n      *\\ [[01]].* | *\\ 2.[[0-9]].* | *\\ 2.10.*) ;; # catch versions < 2.11\n      *\\ 2.11.93.0.2\\ *) supports_anon_versioning=yes ;; # RH7.3 ...\n      *\\ 2.11.92.0.12\\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...\n      *\\ 2.11.*) ;; # other 2.11 versions\n      *) supports_anon_versioning=yes ;;\n    esac\n\n    # See if GNU ld supports shared libraries.\n    case $host_os in\n    aix[[3-9]]*)\n      # On AIX/PPC, the GNU linker is very broken\n      if test \"$host_cpu\" != ia64; then\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: the GNU linker, at least up to release 2.9.1, is reported\n*** to be unable to reliably create shared libraries on AIX.\n*** Therefore, libtool is disabling shared libraries support.  If you\n*** really care for shared libraries, you may want to modify your PATH\n*** so that a non-GNU linker is found, and then restart.\n\n_LT_EOF\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            _LT_TAGVAR(archive_expsym_cmds, $1)=''\n        ;;\n      m68k)\n            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n            _LT_TAGVAR(hardcode_minus_L, $1)=yes\n        ;;\n      esac\n      ;;\n\n    beos*)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t_LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t# Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t# support --undefined.  This deserves some investigation.  FIXME\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,\n      # as there is no search path for DLLs.\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      _LT_TAGVAR(always_export_symbols, $1)=no\n      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\\([[^ ]]*\\)/\\1 DATA/'\\'' | $SED -e '\\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\\'' | sort | uniq > $export_symbols'\n\n      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n\t# If the export-symbols file already is a .def file (1st line\n\t# is EXPORTS), use it as is; otherwise, prepend...\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t  cp $export_symbols $output_objdir/$soname.def;\n\telse\n\t  echo EXPORTS > $output_objdir/$soname.def;\n\t  cat $export_symbols >> $output_objdir/$soname.def;\n\tfi~\n\t$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    interix[[3-9]]*)\n      _LT_TAGVAR(hardcode_direct, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n      # Instead, shared libraries are loaded at an image base (0x10000000 by\n      # default) and relocated if they conflict, which is a slow very memory\n      # consuming and fragmenting process.  To avoid this, we pick a random,\n      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      _LT_TAGVAR(archive_expsym_cmds, $1)='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n      ;;\n\n    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)\n      tmp_diet=no\n      if test \"$host_os\" = linux-dietlibc; then\n\tcase $cc_basename in\n\t  diet\\ *) tmp_diet=yes;;\t# linux-dietlibc with static linking (!diet-dyn)\n\tesac\n      fi\n      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \\\n\t && test \"$tmp_diet\" = no\n      then\n\ttmp_addflag=\n\ttmp_sharedflag='-shared'\n\tcase $cc_basename,$host_cpu in\n        pgcc*)\t\t\t\t# Portland Group C compiler\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag'\n\t  ;;\n\tpgf77* | pgf90* | pgf95*)\t# Portland Group f77 and f90 compilers\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  tmp_addflag=' $pic_flag -Mnomain' ;;\n\tecc*,ia64* | icc*,ia64*)\t# Intel C compiler on ia64\n\t  tmp_addflag=' -i_dynamic' ;;\n\tefc*,ia64* | ifort*,ia64*)\t# Intel Fortran compiler on ia64\n\t  tmp_addflag=' -i_dynamic -nofor_main' ;;\n\tifc* | ifort*)\t\t\t# Intel Fortran compiler\n\t  tmp_addflag=' -nofor_main' ;;\n\tlf95*)\t\t\t\t# Lahey Fortran 8.1\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)=\n\t  tmp_sharedflag='--shared' ;;\n\txl[[cC]]*)\t\t\t# IBM XL C 8.0 on PPC (deal with xlf below)\n\t  tmp_sharedflag='-qmkshrobj'\n\t  tmp_addflag= ;;\n\tesac\n\tcase `$CC -V 2>&1 | sed 5q` in\n\t*Sun\\ C*)\t\t\t# Sun C 5.9\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t  _LT_TAGVAR(compiler_needs_object, $1)=yes\n\t  tmp_sharedflag='-G' ;;\n\t*Sun\\ F*)\t\t\t# Sun Fortran 8.3\n\t  tmp_sharedflag='-G' ;;\n\tesac\n\t_LT_TAGVAR(archive_cmds, $1)='$CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\n        if test \"x$supports_anon_versioning\" = xyes; then\n          _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t    cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t    echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t    $CC '\"$tmp_sharedflag\"\"$tmp_addflag\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n        fi\n\n\tcase $cc_basename in\n\txlf*)\n\t  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'\n\t  if test \"x$supports_anon_versioning\" = xyes; then\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t      cat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t      echo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'\n\t  fi\n\t  ;;\n\tesac\n      else\n        _LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    netbsd* | netbsdelf*-gnu)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'\n\twlarc=\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      fi\n      ;;\n\n    solaris*)\n      if $LD -v 2>&1 | $GREP 'BFD 2\\.8' > /dev/null; then\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: The releases 2.8.* of the GNU linker cannot reliably\n*** create shared libraries on Solaris systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.9.1 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)\n      case `$LD -v 2>&1` in\n        *\\ [[01]].* | *\\ 2.[[0-9]].* | *\\ 2.1[[0-5]].*)\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\tcat <<_LT_EOF 1>&2\n\n*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not\n*** reliably create shared libraries on SCO systems.  Therefore, libtool\n*** is disabling shared libraries support.  We urge you to upgrade GNU\n*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify\n*** your PATH or compiler configuration so that the native linker is\n*** used, and then restart.\n\n_LT_EOF\n\t;;\n\t*)\n\t  # For security reasons, it is highly recommended that you always\n\t  # use absolute paths for naming shared libraries, and exclude the\n\t  # DT_RUNPATH tag from executables and libraries.  But doing so\n\t  # requires that you compile everything twice, which is a pain.\n\t  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t  else\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t  fi\n\t;;\n      esac\n      ;;\n\n    sunos4*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      wlarc=\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    *)\n      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n    esac\n\n    if test \"$_LT_TAGVAR(ld_shlibs, $1)\" = no; then\n      runpath_var=\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)=\n      _LT_TAGVAR(whole_archive_flag_spec, $1)=\n    fi\n  else\n    # PORTME fill in a description of your system's linker (not GNU ld)\n    case $host_os in\n    aix3*)\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      _LT_TAGVAR(always_export_symbols, $1)=yes\n      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'\n      # Note: this linker hardcodes the directories in LIBPATH if there\n      # are no directories specified by -L.\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      if test \"$GCC\" = yes && test -z \"$lt_prog_compiler_static\"; then\n\t# Neither direct hardcoding nor static linking is supported with a\n\t# broken collect2.\n\t_LT_TAGVAR(hardcode_direct, $1)=unsupported\n      fi\n      ;;\n\n    aix[[4-9]]*)\n      if test \"$host_cpu\" = ia64; then\n\t# On IA64, the linker does run time linking by default, so we don't\n\t# have to do anything special.\n\taix_use_runtimelinking=no\n\texp_sym_flag='-Bexport'\n\tno_entry_flag=\"\"\n      else\n\t# If we're using GNU nm, then we don't want the \"-C\" option.\n\t# -C means demangle to AIX nm, but means don't demangle with GNU nm\n\tif $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then\n\t  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\telse\n\t  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\\''{ if (((\\$ 2 == \"T\") || (\\$ 2 == \"D\") || (\\$ 2 == \"B\")) && ([substr](\\$ 3,1,1) != \".\")) { print \\$ 3 } }'\\'' | sort -u > $export_symbols'\n\tfi\n\taix_use_runtimelinking=no\n\n\t# Test if we are trying to use run time linking or normal\n\t# AIX style linking. If -brtl is somewhere in LDFLAGS, we\n\t# need to do runtime linking.\n\tcase $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)\n\t  for ld_flag in $LDFLAGS; do\n\t  if (test $ld_flag = \"-brtl\" || test $ld_flag = \"-Wl,-brtl\"); then\n\t    aix_use_runtimelinking=yes\n\t    break\n\t  fi\n\t  done\n\t  ;;\n\tesac\n\n\texp_sym_flag='-bexport'\n\tno_entry_flag='-bnoentry'\n      fi\n\n      # When large executables or shared objects are built, AIX ld can\n      # have problems creating the table of contents.  If linking a library\n      # or program results in \"error TOC overflow\" add -mminimal-toc to\n      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n      _LT_TAGVAR(archive_cmds, $1)=''\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'\n\n      if test \"$GCC\" = yes; then\n\tcase $host_os in aix4.[[012]]|aix4.[[012]].*)\n\t# We only want to do this on AIX 4.2 and lower, the check\n\t# below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t   strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t  # We have reworked collect2\n\t  :\n\t  else\n\t  # We have old collect2\n\t  _LT_TAGVAR(hardcode_direct, $1)=unsupported\n\t  # It fails to find uninstalled libraries when the uninstalled\n\t  # path is not listed in the libpath.  Setting hardcode_minus_L\n\t  # to unsupported forces relinking\n\t  _LT_TAGVAR(hardcode_minus_L, $1)=yes\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n\t  _LT_TAGVAR(hardcode_libdir_separator, $1)=\n\t  fi\n\t  ;;\n\tesac\n\tshared_flag='-shared'\n\tif test \"$aix_use_runtimelinking\" = yes; then\n\t  shared_flag=\"$shared_flag \"'${wl}-G'\n\tfi\n\t_LT_TAGVAR(link_all_deplibs, $1)=no\n      else\n\t# not using gcc\n\tif test \"$host_cpu\" = ia64; then\n\t# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t# chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n\telse\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag='${wl}-G'\n\t  else\n\t    shared_flag='${wl}-bM:SRE'\n\t  fi\n\tfi\n      fi\n\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'\n      # It seems that -bexpall does not export symbols beginning with\n      # underscore (_), so it is better to generate a list of symbols to export.\n      _LT_TAGVAR(always_export_symbols, $1)=yes\n      if test \"$aix_use_runtimelinking\" = yes; then\n\t# Warning - without using the other runtime loading flags (-brtl),\n\t# -berok will link without error, but may produce a broken library.\n\t_LT_TAGVAR(allow_undefined_flag, $1)='-berok'\n        # Determine the default libpath from the value encoded in an\n        # empty executable.\n        _LT_SYS_MODULE_PATH_AIX\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then $ECHO \"X${wl}${allow_undefined_flag}\" | $Xsed; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n      else\n\tif test \"$host_cpu\" = ia64; then\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=\"-z nodefs\"\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n\telse\n\t # Determine the default libpath from the value encoded in an\n\t # empty executable.\n\t _LT_SYS_MODULE_PATH_AIX\n\t _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t  # Warning - without using the other run time loading flags,\n\t  # -berok will link without error, but may produce a broken library.\n\t  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'\n\t  # Exported symbols can be pulled into shared objects from archives\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'\n\t  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\t  # This is similar to how AIX traditionally builds its shared libraries.\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n\tfi\n      fi\n      ;;\n\n    amigaos*)\n      case $host_cpu in\n      powerpc)\n            # see comment about AmigaOS4 .so support\n            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n            _LT_TAGVAR(archive_expsym_cmds, $1)=''\n        ;;\n      m68k)\n            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO \"#define NAME $libname\" > $output_objdir/a2ixlibrary.data~$ECHO \"#define LIBRARY_ID 1\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define VERSION $major\" >> $output_objdir/a2ixlibrary.data~$ECHO \"#define REVISION $revision\" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'\n            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n            _LT_TAGVAR(hardcode_minus_L, $1)=yes\n        ;;\n      esac\n      ;;\n\n    bsdi[[45]]*)\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic\n      ;;\n\n    cygwin* | mingw* | pw32* | cegcc*)\n      # When not using gcc, we currently assume that we are using\n      # Microsoft Visual C++.\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      # Tell ltmain to make .lib files, not .a files.\n      libext=lib\n      # Tell ltmain to make .dll files, not .so files.\n      shrext_cmds=\".dll\"\n      # FIXME: Setting linknames here is a bad hack.\n      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO \"X$deplibs\" | $Xsed -e '\\''s/ -lc$//'\\''` -link -dll~linknames='\n      # The linker will automatically build a .lib file if we build a DLL.\n      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'\n      # FIXME: Should let the user specify the lib program.\n      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'\n      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w \"$srcfile\"`'\n      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n      ;;\n\n    darwin* | rhapsody*)\n      _LT_DARWIN_LINKER_FEATURES($1)\n      ;;\n\n    dgux*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    freebsd1*)\n      _LT_TAGVAR(ld_shlibs, $1)=no\n      ;;\n\n    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor\n    # support.  Future versions do this automatically, but an explicit c++rt0.o\n    # does not break anything, and helps significantly (at the cost of a little\n    # extra space).\n    freebsd2.2*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    # Unfortunately, older versions of FreeBSD 2 do not have this feature.\n    freebsd2*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.\n    freebsd* | dragonfly*)\n      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    hpux9*)\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n\n      # hardcode_minus_L: Not really in the search PATH,\n      # but as the default location of the library.\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n      ;;\n\n    hpux10*)\n      if test \"$GCC\" = yes -a \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n\t_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'\n\t_LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\t_LT_TAGVAR(hardcode_direct, $1)=yes\n\t_LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\t# hardcode_minus_L: Not really in the search PATH,\n\t# but as the default location of the library.\n\t_LT_TAGVAR(hardcode_minus_L, $1)=yes\n      fi\n      ;;\n\n    hpux11*)\n      if test \"$GCC\" = yes -a \"$with_gnu_ld\" = no; then\n\tcase $host_cpu in\n\thppa*64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      else\n\tcase $host_cpu in\n\thppa*64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tia64*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\tesac\n      fi\n      if test \"$with_gnu_ld\" = no; then\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n\t_LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\tcase $host_cpu in\n\thppa*64*|ia64*)\n\t  _LT_TAGVAR(hardcode_direct, $1)=no\n\t  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes\n\t  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\t  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\n\t  # hardcode_minus_L: Not really in the search PATH,\n\t  # but as the default location of the library.\n\t  _LT_TAGVAR(hardcode_minus_L, $1)=yes\n\t  ;;\n\tesac\n      fi\n      ;;\n\n    irix5* | irix6* | nonstopux*)\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t# Try to use the -exported_symbol ld option, if it does not\n\t# work, assume that -exports_file does not work either and\n\t# implicitly export all symbols.\n        save_LDFLAGS=\"$LDFLAGS\"\n        LDFLAGS=\"$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null\"\n        AC_LINK_IFELSE(int foo(void) {},\n          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'\n        )\n        LDFLAGS=\"$save_LDFLAGS\"\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'\n      fi\n      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      _LT_TAGVAR(inherit_rpath, $1)=yes\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      ;;\n\n    netbsd* | netbsdelf*-gnu)\n      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    newsos6)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    *nto* | *qnx*)\n      ;;\n\n    openbsd*)\n      if test -f /usr/libexec/ld.so; then\n\t_LT_TAGVAR(hardcode_direct, $1)=yes\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t_LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\tif test -z \"`echo __ELF__ | $CC -E - | $GREP __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\telse\n\t  case $host_os in\n\t   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)\n\t     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'\n\t     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t     ;;\n\t   *)\n\t     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'\n\t     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t     ;;\n\t  esac\n\tfi\n      else\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n      fi\n      ;;\n\n    os2*)\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n      _LT_TAGVAR(archive_cmds, $1)='$ECHO \"LIBRARY $libname INITINSTANCE\" > $output_objdir/$libname.def~$ECHO \"DESCRIPTION \\\"$libname\\\"\" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO \" SINGLE NONSHARED\" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'\n      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'\n      ;;\n\n    osf3*)\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n      else\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n      fi\n      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      ;;\n\n    osf4* | osf5*)\t# as osf3* with the addition of -msym flag\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n      else\n\t_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \\*'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done; printf \"%s\\\\n\" \"-hidden\">> $lib.exp~\n\t$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'\n\n\t# Both c and cxx compiler support -rpath directly\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'\n      fi\n      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n      ;;\n\n    solaris*)\n      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'\n      if test \"$GCC\" = yes; then\n\twlarc='${wl}'\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n      else\n\tcase `$CC -V 2>&1` in\n\t*\"Compilers 5.0\"*)\n\t  wlarc=''\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'\n\t  ;;\n\t*)\n\t  wlarc='${wl}'\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'\n\t  ;;\n\tesac\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      case $host_os in\n      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;\n      *)\n\t# The compiler driver will combine and reorder linker options,\n\t# but understands `-z linker_flag'.  GCC discards it without `$wl',\n\t# but is careful enough not to reorder.\n\t# Supported since Solaris 2.6 (maybe 2.5.1?)\n\tif test \"$GCC\" = yes; then\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\telse\n\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'\n\tfi\n\t;;\n      esac\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      ;;\n\n    sunos4*)\n      if test \"x$host_vendor\" = xsequent; then\n\t# Use $CC to link under sequent, because it throws in some extra .o\n\t# files that make .init and .fini sections work.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'\n      fi\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_direct, $1)=yes\n      _LT_TAGVAR(hardcode_minus_L, $1)=yes\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    sysv4)\n      case $host_vendor in\n\tsni)\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???\n\t;;\n\tsiemens)\n\t  ## LD is ld it makes a PLAMLIB\n\t  ## CC just makes a GrossModule.\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'\n\t  _LT_TAGVAR(hardcode_direct, $1)=no\n        ;;\n\tmotorola)\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie\n\t;;\n      esac\n      runpath_var='LD_RUN_PATH'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    sysv4.3*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'\n      ;;\n\n    sysv4*MP*)\n      if test -d /usr/nec; then\n\t_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\trunpath_var=LD_RUN_PATH\n\thardcode_runpath_var=yes\n\t_LT_TAGVAR(ld_shlibs, $1)=yes\n      fi\n      ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)\n      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    sysv5* | sco3.2v5* | sco5v6*)\n      # Note: We can NOT use -z defs as we might desire, because we do not\n      # link with -lc, and that would cause any symbols used from libc to\n      # always be unresolved, which means just about no library would\n      # ever link correctly.  If we're not using GNU ld we use -z text\n      # though, which does catch some bad symbols but isn't as heavy-handed\n      # as -z defs.\n      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'\n      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n      _LT_TAGVAR(link_all_deplibs, $1)=yes\n      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'\n      runpath_var='LD_RUN_PATH'\n\n      if test \"$GCC\" = yes; then\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      else\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n      fi\n      ;;\n\n    uts4*)\n      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'\n      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      ;;\n\n    *)\n      _LT_TAGVAR(ld_shlibs, $1)=no\n      ;;\n    esac\n\n    if test x$host_vendor = xsni; then\n      case $host in\n      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'\n\t;;\n      esac\n    fi\n  fi\n])\nAC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])\ntest \"$_LT_TAGVAR(ld_shlibs, $1)\" = no && can_build_shared=no\n\n_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld\n\n_LT_DECL([], [libext], [0], [Old archive suffix (normally \"a\")])dnl\n_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally \".so\")])dnl\n_LT_DECL([], [extract_expsyms_cmds], [2],\n    [The commands to extract the exported symbol list from a shared archive])\n\n#\n# Do we need to explicitly link libc?\n#\ncase \"x$_LT_TAGVAR(archive_cmds_need_lc, $1)\" in\nx|xyes)\n  # Assume -lc should be added\n  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\n  if test \"$enable_shared\" = yes && test \"$GCC\" = yes; then\n    case $_LT_TAGVAR(archive_cmds, $1) in\n    *'~'*)\n      # FIXME: we may have to deal with multi-command sequences.\n      ;;\n    '$CC '*)\n      # Test whether the compiler implicitly links with -lc since on some\n      # systems, -lgcc has to come before -lc. If gcc already passes -lc\n      # to ld, don't add -lc before -lgcc.\n      AC_MSG_CHECKING([whether -lc should be explicitly linked in])\n      $RM conftest*\n      echo \"$lt_simple_compile_test_code\" > conftest.$ac_ext\n\n      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then\n        soname=conftest\n        lib=conftest\n        libobjs=conftest.$ac_objext\n        deplibs=\n        wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)\n\tpic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)\n        compiler_flags=-v\n        linker_flags=-v\n        verstring=\n        output_objdir=.\n        libname=conftest\n        lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)\n        _LT_TAGVAR(allow_undefined_flag, $1)=\n        if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\\>\\&1 \\| $GREP \\\" -lc \\\" \\>/dev/null 2\\>\\&1)\n        then\n\t  _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n        else\n\t  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n        fi\n        _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag\n      else\n        cat conftest.err 1>&5\n      fi\n      $RM conftest*\n      AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])\n      ;;\n    esac\n  fi\n  ;;\nesac\n\n_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],\n    [Whether or not to add -lc for building shared libraries])\n_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],\n    [enable_shared_with_static_runtimes], [0],\n    [Whether or not to disallow shared libs when runtime libs are static])\n_LT_TAGDECL([], [export_dynamic_flag_spec], [1],\n    [Compiler flag to allow reflexive dlopens])\n_LT_TAGDECL([], [whole_archive_flag_spec], [1],\n    [Compiler flag to generate shared objects directly from archives])\n_LT_TAGDECL([], [compiler_needs_object], [1],\n    [Whether the compiler copes with passing no objects directly])\n_LT_TAGDECL([], [old_archive_from_new_cmds], [2],\n    [Create an old-style archive from a shared archive])\n_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],\n    [Create a temporary old-style archive to link instead of a shared archive])\n_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])\n_LT_TAGDECL([], [archive_expsym_cmds], [2])\n_LT_TAGDECL([], [module_cmds], [2],\n    [Commands used to build a loadable module if different from building\n    a shared archive.])\n_LT_TAGDECL([], [module_expsym_cmds], [2])\n_LT_TAGDECL([], [with_gnu_ld], [1],\n    [Whether we are building with GNU ld or not])\n_LT_TAGDECL([], [allow_undefined_flag], [1],\n    [Flag that allows shared libraries with undefined symbols to be built])\n_LT_TAGDECL([], [no_undefined_flag], [1],\n    [Flag that enforces no undefined symbols])\n_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],\n    [Flag to hardcode $libdir into a binary during linking.\n    This must work even if $libdir does not exist])\n_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],\n    [[If ld is used when linking, flag to hardcode $libdir into a binary\n    during linking.  This must work even if $libdir does not exist]])\n_LT_TAGDECL([], [hardcode_libdir_separator], [1],\n    [Whether we need a single \"-rpath\" flag with a separated argument])\n_LT_TAGDECL([], [hardcode_direct], [0],\n    [Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n    DIR into the resulting binary])\n_LT_TAGDECL([], [hardcode_direct_absolute], [0],\n    [Set to \"yes\" if using DIR/libNAME${shared_ext} during linking hardcodes\n    DIR into the resulting binary and the resulting library dependency is\n    \"absolute\", i.e impossible to change by setting ${shlibpath_var} if the\n    library is relocated])\n_LT_TAGDECL([], [hardcode_minus_L], [0],\n    [Set to \"yes\" if using the -LDIR flag during linking hardcodes DIR\n    into the resulting binary])\n_LT_TAGDECL([], [hardcode_shlibpath_var], [0],\n    [Set to \"yes\" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR\n    into the resulting binary])\n_LT_TAGDECL([], [hardcode_automatic], [0],\n    [Set to \"yes\" if building a shared library automatically hardcodes DIR\n    into the library and all subsequent libraries and executables linked\n    against it])\n_LT_TAGDECL([], [inherit_rpath], [0],\n    [Set to yes if linker adds runtime paths of dependent libraries\n    to runtime path list])\n_LT_TAGDECL([], [link_all_deplibs], [0],\n    [Whether libtool must link a program against all its dependency libraries])\n_LT_TAGDECL([], [fix_srcfile_path], [1],\n    [Fix the shell variable $srcfile for the compiler])\n_LT_TAGDECL([], [always_export_symbols], [0],\n    [Set to \"yes\" if exported symbols are required])\n_LT_TAGDECL([], [export_symbols_cmds], [2],\n    [The commands to list exported symbols])\n_LT_TAGDECL([], [exclude_expsyms], [1],\n    [Symbols that should not be listed in the preloaded symbols])\n_LT_TAGDECL([], [include_expsyms], [1],\n    [Symbols that must always be exported])\n_LT_TAGDECL([], [prelink_cmds], [2],\n    [Commands necessary for linking programs (against libraries) with templates])\n_LT_TAGDECL([], [file_list_spec], [1],\n    [Specify filename containing input files])\ndnl FIXME: Not yet implemented\ndnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],\ndnl    [Compiler flag to generate thread safe objects])\n])# _LT_LINKER_SHLIBS\n\n\n# _LT_LANG_C_CONFIG([TAG])\n# ------------------------\n# Ensure that the configuration variables for a C compiler are suitably\n# defined.  These variables are subsequently used by _LT_CONFIG to write\n# the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_C_CONFIG],\n[m4_require([_LT_DECL_EGREP])dnl\nlt_save_CC=\"$CC\"\nAC_LANG_PUSH(C)\n\n# Source file extension for C test sources.\nac_ext=c\n\n# Object file extension for compiled C test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"int some_variable = 0;\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='int main(){return(0);}'\n\n_LT_TAG_COMPILER\n# Save the default compiler, since it gets overwritten when the other\n# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.\ncompiler_DEFAULT=$CC\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n  _LT_COMPILER_NO_RTTI($1)\n  _LT_COMPILER_PIC($1)\n  _LT_COMPILER_C_O($1)\n  _LT_COMPILER_FILE_LOCKS($1)\n  _LT_LINKER_SHLIBS($1)\n  _LT_SYS_DYNAMIC_LINKER($1)\n  _LT_LINKER_HARDCODE_LIBPATH($1)\n  LT_SYS_DLOPEN_SELF\n  _LT_CMD_STRIPLIB\n\n  # Report which library types will actually be built\n  AC_MSG_CHECKING([if libtool supports shared libraries])\n  AC_MSG_RESULT([$can_build_shared])\n\n  AC_MSG_CHECKING([whether to build shared libraries])\n  test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n  # On AIX, shared libraries and static libraries use the same namespace, and\n  # are all built from PIC.\n  case $host_os in\n  aix3*)\n    test \"$enable_shared\" = yes && enable_static=no\n    if test -n \"$RANLIB\"; then\n      archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n      postinstall_cmds='$RANLIB $lib'\n    fi\n    ;;\n\n  aix[[4-9]]*)\n    if test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n      test \"$enable_shared\" = yes && enable_static=no\n    fi\n    ;;\n  esac\n  AC_MSG_RESULT([$enable_shared])\n\n  AC_MSG_CHECKING([whether to build static libraries])\n  # Make sure either enable_shared or enable_static is yes.\n  test \"$enable_shared\" = yes || enable_static=yes\n  AC_MSG_RESULT([$enable_static])\n\n  _LT_CONFIG($1)\nfi\nAC_LANG_POP\nCC=\"$lt_save_CC\"\n])# _LT_LANG_C_CONFIG\n\n\n# _LT_PROG_CXX\n# ------------\n# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++\n# compiler, we have our own version here.\nm4_defun([_LT_PROG_CXX],\n[\npushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])\nAC_PROG_CXX\nif test -n \"$CXX\" && ( test \"X$CXX\" != \"Xno\" &&\n    ( (test \"X$CXX\" = \"Xg++\" && `g++ -v >/dev/null 2>&1` ) ||\n    (test \"X$CXX\" != \"Xg++\"))) ; then\n  AC_PROG_CXXCPP\nelse\n  _lt_caught_CXX_error=yes\nfi\npopdef([AC_MSG_ERROR])\n])# _LT_PROG_CXX\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([_LT_PROG_CXX], [])\n\n\n# _LT_LANG_CXX_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for a C++ compiler are suitably\n# defined.  These variables are subsequently used by _LT_CONFIG to write\n# the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_CXX_CONFIG],\n[AC_REQUIRE([_LT_PROG_CXX])dnl\nm4_require([_LT_FILEUTILS_DEFAULTS])dnl\nm4_require([_LT_DECL_EGREP])dnl\n\nAC_LANG_PUSH(C++)\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n_LT_TAGVAR(allow_undefined_flag, $1)=\n_LT_TAGVAR(always_export_symbols, $1)=no\n_LT_TAGVAR(archive_expsym_cmds, $1)=\n_LT_TAGVAR(compiler_needs_object, $1)=no\n_LT_TAGVAR(export_dynamic_flag_spec, $1)=\n_LT_TAGVAR(hardcode_direct, $1)=no\n_LT_TAGVAR(hardcode_direct_absolute, $1)=no\n_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=\n_LT_TAGVAR(hardcode_libdir_separator, $1)=\n_LT_TAGVAR(hardcode_minus_L, $1)=no\n_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported\n_LT_TAGVAR(hardcode_automatic, $1)=no\n_LT_TAGVAR(inherit_rpath, $1)=no\n_LT_TAGVAR(module_cmds, $1)=\n_LT_TAGVAR(module_expsym_cmds, $1)=\n_LT_TAGVAR(link_all_deplibs, $1)=unknown\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(no_undefined_flag, $1)=\n_LT_TAGVAR(whole_archive_flag_spec, $1)=\n_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n\n# Source file extension for C++ test sources.\nac_ext=cpp\n\n# Object file extension for compiled C++ test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# No sense in running all these tests if we already determined that\n# the CXX compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_caught_CXX_error\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"int some_variable = 0;\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n  _LT_TAG_COMPILER\n\n  # save warnings/boilerplate of simple test code\n  _LT_COMPILER_BOILERPLATE\n  _LT_LINKER_BOILERPLATE\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=$CC\n  lt_save_LD=$LD\n  lt_save_GCC=$GCC\n  GCC=$GXX\n  lt_save_with_gnu_ld=$with_gnu_ld\n  lt_save_path_LD=$lt_cv_path_LD\n  if test -n \"${lt_cv_prog_gnu_ldcxx+set}\"; then\n    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx\n  else\n    $as_unset lt_cv_prog_gnu_ld\n  fi\n  if test -n \"${lt_cv_path_LDCXX+set}\"; then\n    lt_cv_path_LD=$lt_cv_path_LDCXX\n  else\n    $as_unset lt_cv_path_LD\n  fi\n  test -z \"${LDCXX+set}\" || LD=$LDCXX\n  CC=${CXX-\"c++\"}\n  compiler=$CC\n  _LT_TAGVAR(compiler, $1)=$CC\n  _LT_CC_BASENAME([$compiler])\n\n  if test -n \"$compiler\"; then\n    # We don't want -fno-exception when compiling C++ code, so set the\n    # no_builtin_flag separately\n    if test \"$GXX\" = yes; then\n      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'\n    else\n      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=\n    fi\n\n    if test \"$GXX\" = yes; then\n      # Set up default GNU C++ configuration\n\n      LT_PATH_LD\n\n      # Check if GNU C++ uses GNU ld as the underlying linker, since the\n      # archiving commands below assume that GNU ld is being used.\n      if test \"$with_gnu_ld\" = yes; then\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\n        # If archive_cmds runs LD, not CC, wlarc should be empty\n        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to\n        #     investigate it a little bit more. (MM)\n        wlarc='${wl}'\n\n        # ancient GNU ld didn't support --whole-archive et. al.\n        if eval \"`$CC -print-prog-name=ld` --help 2>&1\" |\n\t  $GREP 'no-whole-archive' > /dev/null; then\n          _LT_TAGVAR(whole_archive_flag_spec, $1)=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n        else\n          _LT_TAGVAR(whole_archive_flag_spec, $1)=\n        fi\n      else\n        with_gnu_ld=no\n        wlarc=\n\n        # A generic and very simple default shared library creation\n        # command for GNU C++ for the case where it uses the native\n        # linker, instead of GNU ld.  If possible, this setting should\n        # overridden to take advantage of the native linker features on\n        # the platform it is being used on.\n        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'\n      fi\n\n      # Commands to make compiler produce verbose output that lists\n      # what \"hidden\" libraries, object files and flags are used when\n      # linking a shared library.\n      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\n    else\n      GXX=no\n      with_gnu_ld=no\n      wlarc=\n    fi\n\n    # PORTME: fill in a description of your system's C++ link characteristics\n    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])\n    _LT_TAGVAR(ld_shlibs, $1)=yes\n    case $host_os in\n      aix3*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n      aix[[4-9]]*)\n        if test \"$host_cpu\" = ia64; then\n          # On IA64, the linker does run time linking by default, so we don't\n          # have to do anything special.\n          aix_use_runtimelinking=no\n          exp_sym_flag='-Bexport'\n          no_entry_flag=\"\"\n        else\n          aix_use_runtimelinking=no\n\n          # Test if we are trying to use run time linking or normal\n          # AIX style linking. If -brtl is somewhere in LDFLAGS, we\n          # need to do runtime linking.\n          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)\n\t    for ld_flag in $LDFLAGS; do\n\t      case $ld_flag in\n\t      *-brtl*)\n\t        aix_use_runtimelinking=yes\n\t        break\n\t        ;;\n\t      esac\n\t    done\n\t    ;;\n          esac\n\n          exp_sym_flag='-bexport'\n          no_entry_flag='-bnoentry'\n        fi\n\n        # When large executables or shared objects are built, AIX ld can\n        # have problems creating the table of contents.  If linking a library\n        # or program results in \"error TOC overflow\" add -mminimal-toc to\n        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not\n        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.\n\n        _LT_TAGVAR(archive_cmds, $1)=''\n        _LT_TAGVAR(hardcode_direct, $1)=yes\n        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n        _LT_TAGVAR(link_all_deplibs, $1)=yes\n        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'\n\n        if test \"$GXX\" = yes; then\n          case $host_os in aix4.[[012]]|aix4.[[012]].*)\n          # We only want to do this on AIX 4.2 and lower, the check\n          # below for broken collect2 doesn't work under 4.3+\n\t  collect2name=`${CC} -print-prog-name=collect2`\n\t  if test -f \"$collect2name\" &&\n\t     strings \"$collect2name\" | $GREP resolve_lib_name >/dev/null\n\t  then\n\t    # We have reworked collect2\n\t    :\n\t  else\n\t    # We have old collect2\n\t    _LT_TAGVAR(hardcode_direct, $1)=unsupported\n\t    # It fails to find uninstalled libraries when the uninstalled\n\t    # path is not listed in the libpath.  Setting hardcode_minus_L\n\t    # to unsupported forces relinking\n\t    _LT_TAGVAR(hardcode_minus_L, $1)=yes\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=\n\t  fi\n          esac\n          shared_flag='-shared'\n\t  if test \"$aix_use_runtimelinking\" = yes; then\n\t    shared_flag=\"$shared_flag \"'${wl}-G'\n\t  fi\n        else\n          # not using gcc\n          if test \"$host_cpu\" = ia64; then\n\t  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release\n\t  # chokes on -Wl,-G. The following line is correct:\n\t  shared_flag='-G'\n          else\n\t    if test \"$aix_use_runtimelinking\" = yes; then\n\t      shared_flag='${wl}-G'\n\t    else\n\t      shared_flag='${wl}-bM:SRE'\n\t    fi\n          fi\n        fi\n\n        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'\n        # It seems that -bexpall does not export symbols beginning with\n        # underscore (_), so it is better to generate a list of symbols to\n\t# export.\n        _LT_TAGVAR(always_export_symbols, $1)=yes\n        if test \"$aix_use_runtimelinking\" = yes; then\n          # Warning - without using the other runtime loading flags (-brtl),\n          # -berok will link without error, but may produce a broken library.\n          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'\n          # Determine the default libpath from the value encoded in an empty\n          # executable.\n          _LT_SYS_MODULE_PATH_AIX\n          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\n          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags `if test \"x${allow_undefined_flag}\" != \"x\"; then $ECHO \"X${wl}${allow_undefined_flag}\" | $Xsed; else :; fi` '\"\\${wl}$exp_sym_flag:\\$export_symbols $shared_flag\"\n        else\n          if test \"$host_cpu\" = ia64; then\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'\n\t    _LT_TAGVAR(allow_undefined_flag, $1)=\"-z nodefs\"\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs '\"\\${wl}$no_entry_flag\"' $compiler_flags ${wl}${allow_undefined_flag} '\"\\${wl}$exp_sym_flag:\\$export_symbols\"\n          else\n\t    # Determine the default libpath from the value encoded in an\n\t    # empty executable.\n\t    _LT_SYS_MODULE_PATH_AIX\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n\t    # Warning - without using the other run time loading flags,\n\t    # -berok will link without error, but may produce a broken library.\n\t    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'\n\t    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'\n\t    # Exported symbols can be pulled into shared objects from archives\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'\n\t    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes\n\t    # This is similar to how AIX traditionally builds its shared\n\t    # libraries.\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)=\"\\$CC $shared_flag\"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'\n          fi\n        fi\n        ;;\n\n      beos*)\n\tif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then\n\t  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n\t  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc\n\t  # support --undefined.  This deserves some investigation.  FIXME\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\telse\n\t  _LT_TAGVAR(ld_shlibs, $1)=no\n\tfi\n\t;;\n\n      chorus*)\n        case $cc_basename in\n          *)\n\t  # FIXME: insert proper C++ library support\n\t  _LT_TAGVAR(ld_shlibs, $1)=no\n\t  ;;\n        esac\n        ;;\n\n      cygwin* | mingw* | pw32* | cegcc*)\n        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,\n        # as there is no search path for DLLs.\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'\n        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported\n        _LT_TAGVAR(always_export_symbols, $1)=no\n        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes\n\n        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then\n          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n          # If the export-symbols file already is a .def file (1st line\n          # is EXPORTS), use it as is; otherwise, prepend...\n          _LT_TAGVAR(archive_expsym_cmds, $1)='if test \"x`$SED 1q $export_symbols`\" = xEXPORTS; then\n\t    cp $export_symbols $output_objdir/$soname.def;\n          else\n\t    echo EXPORTS > $output_objdir/$soname.def;\n\t    cat $export_symbols >> $output_objdir/$soname.def;\n          fi~\n          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'\n        else\n          _LT_TAGVAR(ld_shlibs, $1)=no\n        fi\n        ;;\n      darwin* | rhapsody*)\n        _LT_DARWIN_LINKER_FEATURES($1)\n\t;;\n\n      dgux*)\n        case $cc_basename in\n          ec++*)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          ghcx*)\n\t    # Green Hills C++ Compiler\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n        esac\n        ;;\n\n      freebsd[[12]]*)\n        # C++ shared libraries reported to be fairly broken before\n\t# switch to ELF\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n\n      freebsd-elf*)\n        _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n        ;;\n\n      freebsd* | dragonfly*)\n        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF\n        # conventions\n        _LT_TAGVAR(ld_shlibs, $1)=yes\n        ;;\n\n      gnu*)\n        ;;\n\n      hpux9*)\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n        _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n        _LT_TAGVAR(hardcode_direct, $1)=yes\n        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,\n\t\t\t\t             # but as the default\n\t\t\t\t             # location of the library.\n\n        case $cc_basename in\n          CC*)\n            # FIXME: insert proper C++ library support\n            _LT_TAGVAR(ld_shlibs, $1)=no\n            ;;\n          aCC*)\n            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n            # Commands to make compiler produce verbose output that lists\n            # what \"hidden\" libraries, object files and flags are used when\n            # linking a shared library.\n            #\n            # There doesn't appear to be a way to prevent this compiler from\n            # explicitly linking system object files so we need to strip them\n            # from the output so that they don't get included in the library\n            # dependencies.\n            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP \"\\-L\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n            ;;\n          *)\n            if test \"$GXX\" = yes; then\n              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'\n            else\n              # FIXME: insert proper C++ library support\n              _LT_TAGVAR(ld_shlibs, $1)=no\n            fi\n            ;;\n        esac\n        ;;\n\n      hpux10*|hpux11*)\n        if test $with_gnu_ld = no; then\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'\n\t  _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n          case $host_cpu in\n            hppa*64*|ia64*)\n              ;;\n            *)\n\t      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n              ;;\n          esac\n        fi\n        case $host_cpu in\n          hppa*64*|ia64*)\n            _LT_TAGVAR(hardcode_direct, $1)=no\n            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n            ;;\n          *)\n            _LT_TAGVAR(hardcode_direct, $1)=yes\n            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,\n\t\t\t\t\t         # but as the default\n\t\t\t\t\t         # location of the library.\n            ;;\n        esac\n\n        case $cc_basename in\n          CC*)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          aCC*)\n\t    case $host_cpu in\n\t      hppa*64*)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t      ia64*)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t      *)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t        ;;\n\t    esac\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP \"\\-L\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\t    ;;\n          *)\n\t    if test \"$GXX\" = yes; then\n\t      if test $with_gnu_ld = no; then\n\t        case $host_cpu in\n\t          hppa*64*)\n\t            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t          ia64*)\n\t            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t          *)\n\t            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t            ;;\n\t        esac\n\t      fi\n\t    else\n\t      # FIXME: insert proper C++ library support\n\t      _LT_TAGVAR(ld_shlibs, $1)=no\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n      interix[[3-9]]*)\n\t_LT_TAGVAR(hardcode_direct, $1)=no\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\t# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.\n\t# Instead, shared libraries are loaded at an image base (0x10000000 by\n\t# default) and relocated if they conflict, which is a slow very memory\n\t# consuming and fragmenting process.  To avoid this, we pick a random,\n\t# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link\n\t# time.  Moving up from 0x10000000 also allows more sbrk(2) space.\n\t_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n\t_LT_TAGVAR(archive_expsym_cmds, $1)='sed \"s,^,_,\" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \\* 262144 + 1342177280` -o $lib'\n\t;;\n      irix5* | irix6*)\n        case $cc_basename in\n          CC*)\n\t    # SGI C++\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -ar\", where \"CC\" is the IRIX C++ compiler.  This is\n\t    # necessary to make sure instantiated templates are included\n\t    # in the archive.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'\n\t    ;;\n          *)\n\t    if test \"$GXX\" = yes; then\n\t      if test \"$with_gnu_ld\" = no; then\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t      else\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` -o $lib'\n\t      fi\n\t    fi\n\t    _LT_TAGVAR(link_all_deplibs, $1)=yes\n\t    ;;\n        esac\n        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n        _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n        _LT_TAGVAR(inherit_rpath, $1)=yes\n        ;;\n\n      linux* | k*bsd*-gnu | kopensolaris*-gnu)\n        case $cc_basename in\n          KCC*)\n\t    # Kuck and Associates, Inc. (KAI) C++ Compiler\n\n\t    # KCC will only create a shared library if the output file\n\t    # ends with \".so\" (or \".sl\" for HP-UX), so rename the library\n\t    # to its proper name (with version) after linking.\n\t    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\\''s/\\([[^()0-9A-Za-z{}]]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo $lib | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib; mv \\$templib $lib'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\\''s/\\([[^()0-9A-Za-z{}]]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo $lib | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib ${wl}-retain-symbols-file,$export_symbols; mv \\$templib $lib'\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP \"ld\"`; rm -f libconftest$shared_ext; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -Bstatic\", where \"CC\" is the KAI C++ compiler.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'\n\t    ;;\n\t  icpc* | ecpc* )\n\t    # Intel C++\n\t    with_gnu_ld=yes\n\t    # version 8.0 and above of icpc choke on multiply defined symbols\n\t    # if we add $predep_objects and $postdep_objects, however 7.1 and\n\t    # earlier do not add the objects themselves.\n\t    case `$CC -V 2>&1` in\n\t      *\"Version 7.\"*)\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t\t;;\n\t      *)  # Version 8.0 or newer\n\t        tmp_idyn=\n\t        case $host_cpu in\n\t\t  ia64*) tmp_idyn=' -i_dynamic';;\n\t\tesac\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'\"$tmp_idyn\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t\t_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'\"$tmp_idyn\"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'\n\t\t;;\n\t    esac\n\t    _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'\n\t    ;;\n          pgCC* | pgcpp*)\n            # Portland Group C++ compiler\n\t    case `$CC -V` in\n\t    *pgCC\\ [[1-5]]* | *pgcpp\\ [[1-5]]*)\n\t      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~\n\t\tcompile_command=\"$compile_command `find $tpldir -name \\*.o | $NL2SP`\"'\n\t      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~\n\t\t$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \\*.o | $NL2SP`~\n\t\t$RANLIB $oldlib'\n\t      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~\n\t\t$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \\*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~\n\t\trm -rf $tpldir~\n\t\t$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~\n\t\t$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \\*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    *) # Version 6 will use weak symbols\n\t      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'\n\t      ;;\n\t    esac\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\\\"\\\"; do test  -n \\\"$conv\\\" && new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n            ;;\n\t  cxx*)\n\t    # Compaq C++\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'\n\n\t    runpath_var=LD_RUN_PATH\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"ld\"`; templist=`$ECHO \"X$templist\" | $Xsed -e \"s/\\(^.*ld.*\\)\\( .*ld .*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\t    ;;\n\t  xl*)\n\t    # IBM XL 8.0 on PPC, with GNU ld\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'\n\t    if test \"x$supports_anon_versioning\" = xyes; then\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $output_objdir/$libname.ver~\n\t\tcat $export_symbols | sed -e \"s/\\(.*\\)/\\1;/\" >> $output_objdir/$libname.ver~\n\t\techo \"local: *; };\" >> $output_objdir/$libname.ver~\n\t\t$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'\n\t    fi\n\t    ;;\n\t  *)\n\t    case `$CC -V 2>&1 | sed 5q` in\n\t    *Sun\\ C*)\n\t      # Sun C++ 5.9\n\t      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'\n\t      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'\n\t      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\\\"\\\"; do test -z \\\"$conv\\\" || new_convenience=\\\"$new_convenience,$conv\\\"; done; $ECHO \\\"$new_convenience\\\"` ${wl}--no-whole-archive'\n\t      _LT_TAGVAR(compiler_needs_object, $1)=yes\n\n\t      # Not sure whether something based on\n\t      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1\n\t      # would be better.\n\t      output_verbose_link_cmd='echo'\n\n\t      # Archives containing C++ object files must be created using\n\t      # \"CC -xar\", where \"CC\" is the Sun C++ compiler.  This is\n\t      # necessary to make sure instantiated templates are included\n\t      # in the archive.\n\t      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'\n\t      ;;\n\t    esac\n\t    ;;\n\tesac\n\t;;\n\n      lynxos*)\n        # FIXME: insert proper C++ library support\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\t;;\n\n      m88k*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n\t;;\n\n      mvs*)\n        case $cc_basename in\n          cxx*)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n\t  *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n\tesac\n\t;;\n\n      netbsd*)\n        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then\n\t  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'\n\t  wlarc=\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes\n\t  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\tfi\n\t# Workaround some broken pre-1.5 toolchains\n\toutput_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e \"s:-lgcc -lc -lgcc::\"'\n\t;;\n\n      *nto* | *qnx*)\n        _LT_TAGVAR(ld_shlibs, $1)=yes\n\t;;\n\n      openbsd2*)\n        # C++ shared libraries are fairly broken\n\t_LT_TAGVAR(ld_shlibs, $1)=no\n\t;;\n\n      openbsd*)\n\tif test -f /usr/libexec/ld.so; then\n\t  _LT_TAGVAR(hardcode_direct, $1)=yes\n\t  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'\n\t  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t  if test -z \"`echo __ELF__ | $CC -E - | grep __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'\n\t    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'\n\t    _LT_TAGVAR(whole_archive_flag_spec, $1)=\"$wlarc\"'--whole-archive$convenience '\"$wlarc\"'--no-whole-archive'\n\t  fi\n\t  output_verbose_link_cmd=echo\n\telse\n\t  _LT_TAGVAR(ld_shlibs, $1)=no\n\tfi\n\t;;\n\n      osf3* | osf4* | osf5*)\n        case $cc_basename in\n          KCC*)\n\t    # Kuck and Associates, Inc. (KAI) C++ Compiler\n\n\t    # KCC will only create a shared library if the output file\n\t    # ends with \".so\" (or \".sl\" for HP-UX), so rename the library\n\t    # to its proper name (with version) after linking.\n\t    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\\''s/\\([[^()0-9A-Za-z{}]]\\)/\\\\\\\\\\1/g'\\''`; templib=`echo \"$lib\" | $SED -e \"s/\\${tempext}\\..*/.so/\"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \\$templib; mv \\$templib $lib'\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t    # Archives containing C++ object files must be created using\n\t    # the KAI C++ compiler.\n\t    case $host in\n\t      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;\n\t      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;\n\t    esac\n\t    ;;\n          RCC*)\n\t    # Rational C++ 2.4.1\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          cxx*)\n\t    case $host in\n\t      osf3*)\n\t        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\t        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t\t;;\n\t      *)\n\t        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \\*'\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'\n\t        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf \"%s %s\\\\n\" -exported_symbol \"\\$i\" >> $lib.exp; done~\n\t          echo \"-hidden\">> $lib.exp~\n\t          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n \"$verstring\" && $ECHO \"X-set_version $verstring\" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~\n\t          $RM $lib.exp'\n\t        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'\n\t\t;;\n\t    esac\n\n\t    _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t    # Commands to make compiler produce verbose output that lists\n\t    # what \"hidden\" libraries, object files and flags are used when\n\t    # linking a shared library.\n\t    #\n\t    # There doesn't appear to be a way to prevent this compiler from\n\t    # explicitly linking system object files so we need to strip them\n\t    # from the output so that they don't get included in the library\n\t    # dependencies.\n\t    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"ld\" | $GREP -v \"ld:\"`; templist=`$ECHO \"X$templist\" | $Xsed -e \"s/\\(^.*ld.*\\)\\( .*ld.*$\\)/\\1/\"`; list=\"\"; for z in $templist; do case $z in conftest.$objext) list=\"$list $z\";; *.$objext);; *) list=\"$list $z\";;esac; done; $ECHO \"X$list\" | $Xsed'\n\t    ;;\n\t  *)\n\t    if test \"$GXX\" = yes && test \"$with_gnu_ld\" = no; then\n\t      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\\*'\n\t      case $host in\n\t        osf3*)\n\t          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"X${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t        *)\n\t          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n \"$verstring\" && $ECHO \"${wl}-set_version ${wl}$verstring\" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'\n\t\t  ;;\n\t      esac\n\n\t      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'\n\t      _LT_TAGVAR(hardcode_libdir_separator, $1)=:\n\n\t      # Commands to make compiler produce verbose output that lists\n\t      # what \"hidden\" libraries, object files and flags are used when\n\t      # linking a shared library.\n\t      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\n\t    else\n\t      # FIXME: insert proper C++ library support\n\t      _LT_TAGVAR(ld_shlibs, $1)=no\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n      psos*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n\n      sunos4*)\n        case $cc_basename in\n          CC*)\n\t    # Sun C++ 4.x\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          lcc*)\n\t    # Lucid\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n        esac\n        ;;\n\n      solaris*)\n        case $cc_basename in\n          CC*)\n\t    # Sun C++ 4.2, 5.x and Centerline C++\n            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes\n\t    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'\n\t    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t    case $host_os in\n\t      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;\n\t      *)\n\t\t# The compiler driver will combine and reorder linker options,\n\t\t# but understands `-z linker_flag'.\n\t        # Supported since Solaris 2.6 (maybe 2.5.1?)\n\t\t_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'\n\t        ;;\n\t    esac\n\t    _LT_TAGVAR(link_all_deplibs, $1)=yes\n\n\t    output_verbose_link_cmd='echo'\n\n\t    # Archives containing C++ object files must be created using\n\t    # \"CC -xar\", where \"CC\" is the Sun C++ compiler.  This is\n\t    # necessary to make sure instantiated templates are included\n\t    # in the archive.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'\n\t    ;;\n          gcx*)\n\t    # Green Hills C++ Compiler\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\n\t    # The C++ compiler must be used to create the archive.\n\t    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'\n\t    ;;\n          *)\n\t    # GNU C++ compiler with Solaris linker\n\t    if test \"$GXX\" = yes && test \"$with_gnu_ld\" = no; then\n\t      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'\n\t      if $CC --version | $GREP -v '^2\\.7' > /dev/null; then\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\t        _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t\t  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t        # Commands to make compiler produce verbose output that lists\n\t        # what \"hidden\" libraries, object files and flags are used when\n\t        # linking a shared library.\n\t        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\t      else\n\t        # g++ 2.7 appears to require `-G' NOT `-shared' on this\n\t        # platform.\n\t        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'\n\t        _LT_TAGVAR(archive_expsym_cmds, $1)='echo \"{ global:\" > $lib.exp~cat $export_symbols | $SED -e \"s/\\(.*\\)/\\1;/\" >> $lib.exp~echo \"local: *; };\" >> $lib.exp~\n\t\t  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'\n\n\t        # Commands to make compiler produce verbose output that lists\n\t        # what \"hidden\" libraries, object files and flags are used when\n\t        # linking a shared library.\n\t        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP \"\\-L\"'\n\t      fi\n\n\t      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'\n\t      case $host_os in\n\t\tsolaris2.[[0-5]] | solaris2.[[0-5]].*) ;;\n\t\t*)\n\t\t  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'\n\t\t  ;;\n\t      esac\n\t    fi\n\t    ;;\n        esac\n        ;;\n\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)\n      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n      _LT_TAGVAR(archive_cmds_need_lc, $1)=no\n      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n      runpath_var='LD_RUN_PATH'\n\n      case $cc_basename in\n        CC*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n\t*)\n\t  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t  ;;\n      esac\n      ;;\n\n      sysv5* | sco3.2v5* | sco5v6*)\n\t# Note: We can NOT use -z defs as we might desire, because we do not\n\t# link with -lc, and that would cause any symbols used from libc to\n\t# always be unresolved, which means just about no library would\n\t# ever link correctly.  If we're not using GNU ld we use -z text\n\t# though, which does catch some bad symbols but isn't as heavy-handed\n\t# as -z defs.\n\t_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'\n\t_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'\n\t_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\t_LT_TAGVAR(hardcode_shlibpath_var, $1)=no\n\t_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'\n\t_LT_TAGVAR(hardcode_libdir_separator, $1)=':'\n\t_LT_TAGVAR(link_all_deplibs, $1)=yes\n\t_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'\n\trunpath_var='LD_RUN_PATH'\n\n\tcase $cc_basename in\n          CC*)\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    ;;\n\t  *)\n\t    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'\n\t    ;;\n\tesac\n      ;;\n\n      tandem*)\n        case $cc_basename in\n          NCC*)\n\t    # NonStop-UX NCC 3.20\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n          *)\n\t    # FIXME: insert proper C++ library support\n\t    _LT_TAGVAR(ld_shlibs, $1)=no\n\t    ;;\n        esac\n        ;;\n\n      vxworks*)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n\n      *)\n        # FIXME: insert proper C++ library support\n        _LT_TAGVAR(ld_shlibs, $1)=no\n        ;;\n    esac\n\n    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])\n    test \"$_LT_TAGVAR(ld_shlibs, $1)\" = no && can_build_shared=no\n\n    _LT_TAGVAR(GCC, $1)=\"$GXX\"\n    _LT_TAGVAR(LD, $1)=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    _LT_SYS_HIDDEN_LIBDEPS($1)\n    _LT_COMPILER_PIC($1)\n    _LT_COMPILER_C_O($1)\n    _LT_COMPILER_FILE_LOCKS($1)\n    _LT_LINKER_SHLIBS($1)\n    _LT_SYS_DYNAMIC_LINKER($1)\n    _LT_LINKER_HARDCODE_LIBPATH($1)\n\n    _LT_CONFIG($1)\n  fi # test -n \"$compiler\"\n\n  CC=$lt_save_CC\n  LDCXX=$LD\n  LD=$lt_save_LD\n  GCC=$lt_save_GCC\n  with_gnu_ld=$lt_save_with_gnu_ld\n  lt_cv_path_LDCXX=$lt_cv_path_LD\n  lt_cv_path_LD=$lt_save_path_LD\n  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld\n  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld\nfi # test \"$_lt_caught_CXX_error\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_CXX_CONFIG\n\n\n# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])\n# ---------------------------------\n# Figure out \"hidden\" library dependencies from verbose\n# compiler output when linking a shared library.\n# Parse the compiler output and extract the necessary\n# objects, libraries and library flags.\nm4_defun([_LT_SYS_HIDDEN_LIBDEPS],\n[m4_require([_LT_FILEUTILS_DEFAULTS])dnl\n# Dependencies to place before and after the object being linked:\n_LT_TAGVAR(predep_objects, $1)=\n_LT_TAGVAR(postdep_objects, $1)=\n_LT_TAGVAR(predeps, $1)=\n_LT_TAGVAR(postdeps, $1)=\n_LT_TAGVAR(compiler_lib_search_path, $1)=\n\ndnl we can't use the lt_simple_compile_test_code here,\ndnl because it contains code intended for an executable,\ndnl not a library.  It's possible we should let each\ndnl tag define a new lt_????_link_test_code variable,\ndnl but it's only used here...\nm4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF\nint a;\nvoid foo (void) { a = 0; }\n_LT_EOF\n], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF\nclass Foo\n{\npublic:\n  Foo (void) { a = 0; }\nprivate:\n  int a;\n};\n_LT_EOF\n], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF\n      subroutine foo\n      implicit none\n      integer*4 a\n      a=0\n      return\n      end\n_LT_EOF\n], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF\n      subroutine foo\n      implicit none\n      integer a\n      a=0\n      return\n      end\n_LT_EOF\n], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF\npublic class foo {\n  private int a;\n  public void bar (void) {\n    a = 0;\n  }\n};\n_LT_EOF\n])\ndnl Parse the compiler output and extract the necessary\ndnl objects, libraries and library flags.\nif AC_TRY_EVAL(ac_compile); then\n  # Parse the compiler output and extract the necessary\n  # objects, libraries and library flags.\n\n  # Sentinel used to keep track of whether or not we are before\n  # the conftest object file.\n  pre_test_object_deps_done=no\n\n  for p in `eval \"$output_verbose_link_cmd\"`; do\n    case $p in\n\n    -L* | -R* | -l*)\n       # Some compilers place space between \"-{L,R}\" and the path.\n       # Remove the space.\n       if test $p = \"-L\" ||\n          test $p = \"-R\"; then\n\t prev=$p\n\t continue\n       else\n\t prev=\n       fi\n\n       if test \"$pre_test_object_deps_done\" = no; then\n\t case $p in\n\t -L* | -R*)\n\t   # Internal compiler library paths should come after those\n\t   # provided the user.  The postdeps already come after the\n\t   # user supplied libs so there is no need to process them.\n\t   if test -z \"$_LT_TAGVAR(compiler_lib_search_path, $1)\"; then\n\t     _LT_TAGVAR(compiler_lib_search_path, $1)=\"${prev}${p}\"\n\t   else\n\t     _LT_TAGVAR(compiler_lib_search_path, $1)=\"${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}\"\n\t   fi\n\t   ;;\n\t # The \"-l\" case would never come before the object being\n\t # linked, so don't bother handling this case.\n\t esac\n       else\n\t if test -z \"$_LT_TAGVAR(postdeps, $1)\"; then\n\t   _LT_TAGVAR(postdeps, $1)=\"${prev}${p}\"\n\t else\n\t   _LT_TAGVAR(postdeps, $1)=\"${_LT_TAGVAR(postdeps, $1)} ${prev}${p}\"\n\t fi\n       fi\n       ;;\n\n    *.$objext)\n       # This assumes that the test object file only shows up\n       # once in the compiler output.\n       if test \"$p\" = \"conftest.$objext\"; then\n\t pre_test_object_deps_done=yes\n\t continue\n       fi\n\n       if test \"$pre_test_object_deps_done\" = no; then\n\t if test -z \"$_LT_TAGVAR(predep_objects, $1)\"; then\n\t   _LT_TAGVAR(predep_objects, $1)=\"$p\"\n\t else\n\t   _LT_TAGVAR(predep_objects, $1)=\"$_LT_TAGVAR(predep_objects, $1) $p\"\n\t fi\n       else\n\t if test -z \"$_LT_TAGVAR(postdep_objects, $1)\"; then\n\t   _LT_TAGVAR(postdep_objects, $1)=\"$p\"\n\t else\n\t   _LT_TAGVAR(postdep_objects, $1)=\"$_LT_TAGVAR(postdep_objects, $1) $p\"\n\t fi\n       fi\n       ;;\n\n    *) ;; # Ignore the rest.\n\n    esac\n  done\n\n  # Clean up.\n  rm -f a.out a.exe\nelse\n  echo \"libtool.m4: error: problem compiling $1 test program\"\nfi\n\n$RM -f confest.$objext\n\n# PORTME: override above test on systems where it is broken\nm4_if([$1], [CXX],\n[case $host_os in\ninterix[[3-9]]*)\n  # Interix 3.5 installs completely hosed .la files for C++, so rather than\n  # hack all around it, let's just trust \"g++\" to DTRT.\n  _LT_TAGVAR(predep_objects,$1)=\n  _LT_TAGVAR(postdep_objects,$1)=\n  _LT_TAGVAR(postdeps,$1)=\n  ;;\n\nlinux*)\n  case `$CC -V 2>&1 | sed 5q` in\n  *Sun\\ C*)\n    # Sun C++ 5.9\n\n    # The more standards-conforming stlport4 library is\n    # incompatible with the Cstd library. Avoid specifying\n    # it if it's in CXXFLAGS. Ignore libCrun as\n    # -library=stlport4 depends on it.\n    case \" $CXX $CXXFLAGS \" in\n    *\" -library=stlport4 \"*)\n      solaris_use_stlport4=yes\n      ;;\n    esac\n\n    if test \"$solaris_use_stlport4\" != yes; then\n      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'\n    fi\n    ;;\n  esac\n  ;;\n\nsolaris*)\n  case $cc_basename in\n  CC*)\n    # The more standards-conforming stlport4 library is\n    # incompatible with the Cstd library. Avoid specifying\n    # it if it's in CXXFLAGS. Ignore libCrun as\n    # -library=stlport4 depends on it.\n    case \" $CXX $CXXFLAGS \" in\n    *\" -library=stlport4 \"*)\n      solaris_use_stlport4=yes\n      ;;\n    esac\n\n    # Adding this requires a known-good setup of shared libraries for\n    # Sun compiler versions before 5.6, else PIC objects from an old\n    # archive will be linked into the output, leading to subtle bugs.\n    if test \"$solaris_use_stlport4\" != yes; then\n      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'\n    fi\n    ;;\n  esac\n  ;;\nesac\n])\n\ncase \" $_LT_TAGVAR(postdeps, $1) \" in\n*\" -lc \"*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;\nesac\n _LT_TAGVAR(compiler_lib_search_dirs, $1)=\nif test -n \"${_LT_TAGVAR(compiler_lib_search_path, $1)}\"; then\n _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo \" ${_LT_TAGVAR(compiler_lib_search_path, $1)}\" | ${SED} -e 's! -L! !g' -e 's!^ !!'`\nfi\n_LT_TAGDECL([], [compiler_lib_search_dirs], [1],\n    [The directories searched by this compiler when creating a shared library])\n_LT_TAGDECL([], [predep_objects], [1],\n    [Dependencies to place before and after the objects being linked to\n    create a shared library])\n_LT_TAGDECL([], [postdep_objects], [1])\n_LT_TAGDECL([], [predeps], [1])\n_LT_TAGDECL([], [postdeps], [1])\n_LT_TAGDECL([], [compiler_lib_search_path], [1],\n    [The library search path used internally by the compiler when linking\n    a shared library])\n])# _LT_SYS_HIDDEN_LIBDEPS\n\n\n# _LT_PROG_F77\n# ------------\n# Since AC_PROG_F77 is broken, in that it returns the empty string\n# if there is no fortran compiler, we have our own version here.\nm4_defun([_LT_PROG_F77],\n[\npushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])\nAC_PROG_F77\nif test -z \"$F77\" || test \"X$F77\" = \"Xno\"; then\n  _lt_disable_F77=yes\nfi\npopdef([AC_MSG_ERROR])\n])# _LT_PROG_F77\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([_LT_PROG_F77], [])\n\n\n# _LT_LANG_F77_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for a Fortran 77 compiler are\n# suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_F77_CONFIG],\n[AC_REQUIRE([_LT_PROG_F77])dnl\nAC_LANG_PUSH(Fortran 77)\n\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n_LT_TAGVAR(allow_undefined_flag, $1)=\n_LT_TAGVAR(always_export_symbols, $1)=no\n_LT_TAGVAR(archive_expsym_cmds, $1)=\n_LT_TAGVAR(export_dynamic_flag_spec, $1)=\n_LT_TAGVAR(hardcode_direct, $1)=no\n_LT_TAGVAR(hardcode_direct_absolute, $1)=no\n_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=\n_LT_TAGVAR(hardcode_libdir_separator, $1)=\n_LT_TAGVAR(hardcode_minus_L, $1)=no\n_LT_TAGVAR(hardcode_automatic, $1)=no\n_LT_TAGVAR(inherit_rpath, $1)=no\n_LT_TAGVAR(module_cmds, $1)=\n_LT_TAGVAR(module_expsym_cmds, $1)=\n_LT_TAGVAR(link_all_deplibs, $1)=unknown\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(no_undefined_flag, $1)=\n_LT_TAGVAR(whole_archive_flag_spec, $1)=\n_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n\n# Source file extension for f77 test sources.\nac_ext=f\n\n# Object file extension for compiled f77 test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# No sense in running all these tests if we already determined that\n# the F77 compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_disable_F77\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"\\\n      subroutine t\n      return\n      end\n\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code=\"\\\n      program t\n      end\n\"\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n  _LT_TAG_COMPILER\n\n  # save warnings/boilerplate of simple test code\n  _LT_COMPILER_BOILERPLATE\n  _LT_LINKER_BOILERPLATE\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=\"$CC\"\n  lt_save_GCC=$GCC\n  CC=${F77-\"f77\"}\n  compiler=$CC\n  _LT_TAGVAR(compiler, $1)=$CC\n  _LT_CC_BASENAME([$compiler])\n  GCC=$G77\n  if test -n \"$compiler\"; then\n    AC_MSG_CHECKING([if libtool supports shared libraries])\n    AC_MSG_RESULT([$can_build_shared])\n\n    AC_MSG_CHECKING([whether to build shared libraries])\n    test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n    # On AIX, shared libraries and static libraries use the same namespace, and\n    # are all built from PIC.\n    case $host_os in\n      aix3*)\n        test \"$enable_shared\" = yes && enable_static=no\n        if test -n \"$RANLIB\"; then\n          archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n          postinstall_cmds='$RANLIB $lib'\n        fi\n        ;;\n      aix[[4-9]]*)\n\tif test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n\t  test \"$enable_shared\" = yes && enable_static=no\n\tfi\n        ;;\n    esac\n    AC_MSG_RESULT([$enable_shared])\n\n    AC_MSG_CHECKING([whether to build static libraries])\n    # Make sure either enable_shared or enable_static is yes.\n    test \"$enable_shared\" = yes || enable_static=yes\n    AC_MSG_RESULT([$enable_static])\n\n    _LT_TAGVAR(GCC, $1)=\"$G77\"\n    _LT_TAGVAR(LD, $1)=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    _LT_COMPILER_PIC($1)\n    _LT_COMPILER_C_O($1)\n    _LT_COMPILER_FILE_LOCKS($1)\n    _LT_LINKER_SHLIBS($1)\n    _LT_SYS_DYNAMIC_LINKER($1)\n    _LT_LINKER_HARDCODE_LIBPATH($1)\n\n    _LT_CONFIG($1)\n  fi # test -n \"$compiler\"\n\n  GCC=$lt_save_GCC\n  CC=\"$lt_save_CC\"\nfi # test \"$_lt_disable_F77\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_F77_CONFIG\n\n\n# _LT_PROG_FC\n# -----------\n# Since AC_PROG_FC is broken, in that it returns the empty string\n# if there is no fortran compiler, we have our own version here.\nm4_defun([_LT_PROG_FC],\n[\npushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])\nAC_PROG_FC\nif test -z \"$FC\" || test \"X$FC\" = \"Xno\"; then\n  _lt_disable_FC=yes\nfi\npopdef([AC_MSG_ERROR])\n])# _LT_PROG_FC\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([_LT_PROG_FC], [])\n\n\n# _LT_LANG_FC_CONFIG([TAG])\n# -------------------------\n# Ensure that the configuration variables for a Fortran compiler are\n# suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_FC_CONFIG],\n[AC_REQUIRE([_LT_PROG_FC])dnl\nAC_LANG_PUSH(Fortran)\n\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n_LT_TAGVAR(allow_undefined_flag, $1)=\n_LT_TAGVAR(always_export_symbols, $1)=no\n_LT_TAGVAR(archive_expsym_cmds, $1)=\n_LT_TAGVAR(export_dynamic_flag_spec, $1)=\n_LT_TAGVAR(hardcode_direct, $1)=no\n_LT_TAGVAR(hardcode_direct_absolute, $1)=no\n_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=\n_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=\n_LT_TAGVAR(hardcode_libdir_separator, $1)=\n_LT_TAGVAR(hardcode_minus_L, $1)=no\n_LT_TAGVAR(hardcode_automatic, $1)=no\n_LT_TAGVAR(inherit_rpath, $1)=no\n_LT_TAGVAR(module_cmds, $1)=\n_LT_TAGVAR(module_expsym_cmds, $1)=\n_LT_TAGVAR(link_all_deplibs, $1)=unknown\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n_LT_TAGVAR(no_undefined_flag, $1)=\n_LT_TAGVAR(whole_archive_flag_spec, $1)=\n_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no\n\n# Source file extension for fc test sources.\nac_ext=${ac_fc_srcext-f}\n\n# Object file extension for compiled fc test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# No sense in running all these tests if we already determined that\n# the FC compiler isn't working.  Some variables (like enable_shared)\n# are currently assumed to apply to all compilers on this platform,\n# and will be corrupted by setting them based on a non-working compiler.\nif test \"$_lt_disable_FC\" != yes; then\n  # Code to be used in simple compile tests\n  lt_simple_compile_test_code=\"\\\n      subroutine t\n      return\n      end\n\"\n\n  # Code to be used in simple link tests\n  lt_simple_link_test_code=\"\\\n      program t\n      end\n\"\n\n  # ltmain only uses $CC for tagged configurations so make sure $CC is set.\n  _LT_TAG_COMPILER\n\n  # save warnings/boilerplate of simple test code\n  _LT_COMPILER_BOILERPLATE\n  _LT_LINKER_BOILERPLATE\n\n  # Allow CC to be a program name with arguments.\n  lt_save_CC=\"$CC\"\n  lt_save_GCC=$GCC\n  CC=${FC-\"f95\"}\n  compiler=$CC\n  GCC=$ac_cv_fc_compiler_gnu\n\n  _LT_TAGVAR(compiler, $1)=$CC\n  _LT_CC_BASENAME([$compiler])\n\n  if test -n \"$compiler\"; then\n    AC_MSG_CHECKING([if libtool supports shared libraries])\n    AC_MSG_RESULT([$can_build_shared])\n\n    AC_MSG_CHECKING([whether to build shared libraries])\n    test \"$can_build_shared\" = \"no\" && enable_shared=no\n\n    # On AIX, shared libraries and static libraries use the same namespace, and\n    # are all built from PIC.\n    case $host_os in\n      aix3*)\n        test \"$enable_shared\" = yes && enable_static=no\n        if test -n \"$RANLIB\"; then\n          archive_cmds=\"$archive_cmds~\\$RANLIB \\$lib\"\n          postinstall_cmds='$RANLIB $lib'\n        fi\n        ;;\n      aix[[4-9]]*)\n\tif test \"$host_cpu\" != ia64 && test \"$aix_use_runtimelinking\" = no ; then\n\t  test \"$enable_shared\" = yes && enable_static=no\n\tfi\n        ;;\n    esac\n    AC_MSG_RESULT([$enable_shared])\n\n    AC_MSG_CHECKING([whether to build static libraries])\n    # Make sure either enable_shared or enable_static is yes.\n    test \"$enable_shared\" = yes || enable_static=yes\n    AC_MSG_RESULT([$enable_static])\n\n    _LT_TAGVAR(GCC, $1)=\"$ac_cv_fc_compiler_gnu\"\n    _LT_TAGVAR(LD, $1)=\"$LD\"\n\n    ## CAVEAT EMPTOR:\n    ## There is no encapsulation within the following macros, do not change\n    ## the running order or otherwise move them around unless you know exactly\n    ## what you are doing...\n    _LT_SYS_HIDDEN_LIBDEPS($1)\n    _LT_COMPILER_PIC($1)\n    _LT_COMPILER_C_O($1)\n    _LT_COMPILER_FILE_LOCKS($1)\n    _LT_LINKER_SHLIBS($1)\n    _LT_SYS_DYNAMIC_LINKER($1)\n    _LT_LINKER_HARDCODE_LIBPATH($1)\n\n    _LT_CONFIG($1)\n  fi # test -n \"$compiler\"\n\n  GCC=$lt_save_GCC\n  CC=\"$lt_save_CC\"\nfi # test \"$_lt_disable_FC\" != yes\n\nAC_LANG_POP\n])# _LT_LANG_FC_CONFIG\n\n\n# _LT_LANG_GCJ_CONFIG([TAG])\n# --------------------------\n# Ensure that the configuration variables for the GNU Java Compiler compiler\n# are suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_GCJ_CONFIG],\n[AC_REQUIRE([LT_PROG_GCJ])dnl\nAC_LANG_SAVE\n\n# Source file extension for Java test sources.\nac_ext=java\n\n# Object file extension for compiled Java test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code=\"class foo {}\"\n\n# Code to be used in simple link tests\nlt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n_LT_TAG_COMPILER\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=\"$CC\"\nlt_save_GCC=$GCC\nGCC=yes\nCC=${GCJ-\"gcj\"}\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_TAGVAR(LD, $1)=\"$LD\"\n_LT_CC_BASENAME([$compiler])\n\n# GCJ did not exist at the time GCC didn't implicitly link libc in.\n_LT_TAGVAR(archive_cmds_need_lc, $1)=no\n\n_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds\n\n## CAVEAT EMPTOR:\n## There is no encapsulation within the following macros, do not change\n## the running order or otherwise move them around unless you know exactly\n## what you are doing...\nif test -n \"$compiler\"; then\n  _LT_COMPILER_NO_RTTI($1)\n  _LT_COMPILER_PIC($1)\n  _LT_COMPILER_C_O($1)\n  _LT_COMPILER_FILE_LOCKS($1)\n  _LT_LINKER_SHLIBS($1)\n  _LT_LINKER_HARDCODE_LIBPATH($1)\n\n  _LT_CONFIG($1)\nfi\n\nAC_LANG_RESTORE\n\nGCC=$lt_save_GCC\nCC=\"$lt_save_CC\"\n])# _LT_LANG_GCJ_CONFIG\n\n\n# _LT_LANG_RC_CONFIG([TAG])\n# -------------------------\n# Ensure that the configuration variables for the Windows resource compiler\n# are suitably defined.  These variables are subsequently used by _LT_CONFIG\n# to write the compiler configuration to `libtool'.\nm4_defun([_LT_LANG_RC_CONFIG],\n[AC_REQUIRE([LT_PROG_RC])dnl\nAC_LANG_SAVE\n\n# Source file extension for RC test sources.\nac_ext=rc\n\n# Object file extension for compiled RC test sources.\nobjext=o\n_LT_TAGVAR(objext, $1)=$objext\n\n# Code to be used in simple compile tests\nlt_simple_compile_test_code='sample MENU { MENUITEM \"&Soup\", 100, CHECKED }'\n\n# Code to be used in simple link tests\nlt_simple_link_test_code=\"$lt_simple_compile_test_code\"\n\n# ltmain only uses $CC for tagged configurations so make sure $CC is set.\n_LT_TAG_COMPILER\n\n# save warnings/boilerplate of simple test code\n_LT_COMPILER_BOILERPLATE\n_LT_LINKER_BOILERPLATE\n\n# Allow CC to be a program name with arguments.\nlt_save_CC=\"$CC\"\nlt_save_GCC=$GCC\nGCC=\nCC=${RC-\"windres\"}\ncompiler=$CC\n_LT_TAGVAR(compiler, $1)=$CC\n_LT_CC_BASENAME([$compiler])\n_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes\n\nif test -n \"$compiler\"; then\n  :\n  _LT_CONFIG($1)\nfi\n\nGCC=$lt_save_GCC\nAC_LANG_RESTORE\nCC=\"$lt_save_CC\"\n])# _LT_LANG_RC_CONFIG\n\n\n# LT_PROG_GCJ\n# -----------\nAC_DEFUN([LT_PROG_GCJ],\n[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],\n  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],\n    [AC_CHECK_TOOL(GCJ, gcj,)\n      test \"x${GCJFLAGS+set}\" = xset || GCJFLAGS=\"-g -O2\"\n      AC_SUBST(GCJFLAGS)])])[]dnl\n])\n\n# Old name:\nAU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([LT_AC_PROG_GCJ], [])\n\n\n# LT_PROG_RC\n# ----------\nAC_DEFUN([LT_PROG_RC],\n[AC_CHECK_TOOL(RC, windres,)\n])\n\n# Old name:\nAU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([LT_AC_PROG_RC], [])\n\n\n# _LT_DECL_EGREP\n# --------------\n# If we don't have a new enough Autoconf to choose the best grep\n# available, choose the one first in the user's PATH.\nm4_defun([_LT_DECL_EGREP],\n[AC_REQUIRE([AC_PROG_EGREP])dnl\nAC_REQUIRE([AC_PROG_FGREP])dnl\ntest -z \"$GREP\" && GREP=grep\n_LT_DECL([], [GREP], [1], [A grep program that handles long lines])\n_LT_DECL([], [EGREP], [1], [An ERE matcher])\n_LT_DECL([], [FGREP], [1], [A literal string matcher])\ndnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too\nAC_SUBST([GREP])\n])\n\n\n# _LT_DECL_OBJDUMP\n# --------------\n# If we don't have a new enough Autoconf to choose the best objdump\n# available, choose the one first in the user's PATH.\nm4_defun([_LT_DECL_OBJDUMP],\n[AC_CHECK_TOOL(OBJDUMP, objdump, false)\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])\nAC_SUBST([OBJDUMP])\n])\n\n\n# _LT_DECL_SED\n# ------------\n# Check for a fully-functional sed program, that truncates\n# as few characters as possible.  Prefer GNU sed if found.\nm4_defun([_LT_DECL_SED],\n[AC_PROG_SED\ntest -z \"$SED\" && SED=sed\nXsed=\"$SED -e 1s/^X//\"\n_LT_DECL([], [SED], [1], [A sed program that does not truncate output])\n_LT_DECL([], [Xsed], [\"\\$SED -e 1s/^X//\"],\n    [Sed that helps us avoid accidentally triggering echo(1) options like -n])\n])# _LT_DECL_SED\n\nm4_ifndef([AC_PROG_SED], [\n############################################################\n# NOTE: This macro has been submitted for inclusion into   #\n#  GNU Autoconf as AC_PROG_SED.  When it is available in   #\n#  a released version of Autoconf we should remove this    #\n#  macro and use it instead.                               #\n############################################################\n\nm4_defun([AC_PROG_SED],\n[AC_MSG_CHECKING([for a sed that does not truncate output])\nAC_CACHE_VAL(lt_cv_path_SED,\n[# Loop through the user's path and test for sed and gsed.\n# Then use that list of sed's as ones to test for truncation.\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  for lt_ac_prog in sed gsed; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      if $as_executable_p \"$as_dir/$lt_ac_prog$ac_exec_ext\"; then\n        lt_ac_sed_list=\"$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext\"\n      fi\n    done\n  done\ndone\nIFS=$as_save_IFS\nlt_ac_max=0\nlt_ac_count=0\n# Add /usr/xpg4/bin/sed as it is typically found on Solaris\n# along with /bin/sed that truncates output.\nfor lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do\n  test ! -f $lt_ac_sed && continue\n  cat /dev/null > conftest.in\n  lt_ac_count=0\n  echo $ECHO_N \"0123456789$ECHO_C\" >conftest.in\n  # Check for GNU sed and select it if it is found.\n  if \"$lt_ac_sed\" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then\n    lt_cv_path_SED=$lt_ac_sed\n    break\n  fi\n  while true; do\n    cat conftest.in conftest.in >conftest.tmp\n    mv conftest.tmp conftest.in\n    cp conftest.in conftest.nl\n    echo >>conftest.nl\n    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break\n    cmp -s conftest.out conftest.nl || break\n    # 10000 chars as input seems more than enough\n    test $lt_ac_count -gt 10 && break\n    lt_ac_count=`expr $lt_ac_count + 1`\n    if test $lt_ac_count -gt $lt_ac_max; then\n      lt_ac_max=$lt_ac_count\n      lt_cv_path_SED=$lt_ac_sed\n    fi\n  done\ndone\n])\nSED=$lt_cv_path_SED\nAC_SUBST([SED])\nAC_MSG_RESULT([$SED])\n])#AC_PROG_SED\n])#m4_ifndef\n\n# Old name:\nAU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([LT_AC_PROG_SED], [])\n\n\n# _LT_CHECK_SHELL_FEATURES\n# ------------------------\n# Find out whether the shell is Bourne or XSI compatible,\n# or has some other useful features.\nm4_defun([_LT_CHECK_SHELL_FEATURES],\n[AC_MSG_CHECKING([whether the shell understands some XSI constructs])\n# Try some XSI features\nxsi_shell=no\n( _lt_dummy=\"a/b/c\"\n  test \"${_lt_dummy##*/},${_lt_dummy%/*},\"${_lt_dummy%\"$_lt_dummy\"}, \\\n      = c,a/b,, \\\n    && eval 'test $(( 1 + 1 )) -eq 2 \\\n    && test \"${#_lt_dummy}\" -eq 5' ) >/dev/null 2>&1 \\\n  && xsi_shell=yes\nAC_MSG_RESULT([$xsi_shell])\n_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])\n\nAC_MSG_CHECKING([whether the shell understands \"+=\"])\nlt_shell_append=no\n( foo=bar; set foo baz; eval \"$[1]+=\\$[2]\" && test \"$foo\" = barbaz ) \\\n    >/dev/null 2>&1 \\\n  && lt_shell_append=yes\nAC_MSG_RESULT([$lt_shell_append])\n_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])\n\nif ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then\n  lt_unset=unset\nelse\n  lt_unset=false\nfi\n_LT_DECL([], [lt_unset], [0], [whether the shell understands \"unset\"])dnl\n\n# test EBCDIC or ASCII\ncase `echo X|tr X '\\101'` in\n A) # ASCII based system\n    # \\n is not interpreted correctly by Solaris 8 /usr/ucb/tr\n  lt_SP2NL='tr \\040 \\012'\n  lt_NL2SP='tr \\015\\012 \\040\\040'\n  ;;\n *) # EBCDIC based system\n  lt_SP2NL='tr \\100 \\n'\n  lt_NL2SP='tr \\r\\n \\100\\100'\n  ;;\nesac\n_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl\n_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl\n])# _LT_CHECK_SHELL_FEATURES\n\n\n# _LT_PROG_XSI_SHELLFNS\n# ---------------------\n# Bourne and XSI compatible variants of some useful shell functions.\nm4_defun([_LT_PROG_XSI_SHELLFNS],\n[case $xsi_shell in\n  yes)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_dirname_and_basename file append nondir_replacement\n# perform func_basename and func_dirname in a single function\n# call:\n#   dirname:  Compute the dirname of FILE.  If nonempty,\n#             add APPEND to the result, otherwise set result\n#             to NONDIR_REPLACEMENT.\n#             value returned in \"$func_dirname_result\"\n#   basename: Compute filename of FILE.\n#             value retuned in \"$func_basename_result\"\n# Implementation must be kept synchronized with func_dirname\n# and func_basename. For efficiency, we do not delegate to\n# those functions but instead duplicate the functionality here.\nfunc_dirname_and_basename ()\n{\n  case ${1} in\n    */*) func_dirname_result=\"${1%/*}${2}\" ;;\n    *  ) func_dirname_result=\"${3}\" ;;\n  esac\n  func_basename_result=\"${1##*/}\"\n}\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\nfunc_stripname ()\n{\n  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\n  # positional parameters, so assign one to ordinary parameter first.\n  func_stripname_result=${3}\n  func_stripname_result=${func_stripname_result#\"${1}\"}\n  func_stripname_result=${func_stripname_result%\"${2}\"}\n}\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=${1%%=*}\n  func_opt_split_arg=${1#*=}\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  case ${1} in\n    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\n    *)    func_lo2o_result=${1} ;;\n  esac\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=${1%.*}.lo\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=$(( $[*] ))\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=${#1}\n}\n\n_LT_EOF\n    ;;\n  *) # Bourne compatible functions.\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_dirname file append nondir_replacement\n# Compute the dirname of FILE.  If nonempty, add APPEND to the result,\n# otherwise set result to NONDIR_REPLACEMENT.\nfunc_dirname ()\n{\n  # Extract subdirectory from the argument.\n  func_dirname_result=`$ECHO \"X${1}\" | $Xsed -e \"$dirname\"`\n  if test \"X$func_dirname_result\" = \"X${1}\"; then\n    func_dirname_result=\"${3}\"\n  else\n    func_dirname_result=\"$func_dirname_result${2}\"\n  fi\n}\n\n# func_basename file\nfunc_basename ()\n{\n  func_basename_result=`$ECHO \"X${1}\" | $Xsed -e \"$basename\"`\n}\n\ndnl func_dirname_and_basename\ndnl A portable version of this function is already defined in general.m4sh\ndnl so there is no need for it here.\n\n# func_stripname prefix suffix name\n# strip PREFIX and SUFFIX off of NAME.\n# PREFIX and SUFFIX must not contain globbing or regex special\n# characters, hashes, percent signs, but SUFFIX may contain a leading\n# dot (in which case that matches only a dot).\n# func_strip_suffix prefix name\nfunc_stripname ()\n{\n  case ${2} in\n    .*) func_stripname_result=`$ECHO \"X${3}\" \\\n           | $Xsed -e \"s%^${1}%%\" -e \"s%\\\\\\\\${2}\\$%%\"`;;\n    *)  func_stripname_result=`$ECHO \"X${3}\" \\\n           | $Xsed -e \"s%^${1}%%\" -e \"s%${2}\\$%%\"`;;\n  esac\n}\n\n# sed scripts:\nmy_sed_long_opt='1s/^\\(-[[^=]]*\\)=.*/\\1/;q'\nmy_sed_long_arg='1s/^-[[^=]]*=//'\n\n# func_opt_split\nfunc_opt_split ()\n{\n  func_opt_split_opt=`$ECHO \"X${1}\" | $Xsed -e \"$my_sed_long_opt\"`\n  func_opt_split_arg=`$ECHO \"X${1}\" | $Xsed -e \"$my_sed_long_arg\"`\n}\n\n# func_lo2o object\nfunc_lo2o ()\n{\n  func_lo2o_result=`$ECHO \"X${1}\" | $Xsed -e \"$lo2o\"`\n}\n\n# func_xform libobj-or-source\nfunc_xform ()\n{\n  func_xform_result=`$ECHO \"X${1}\" | $Xsed -e 's/\\.[[^.]]*$/.lo/'`\n}\n\n# func_arith arithmetic-term...\nfunc_arith ()\n{\n  func_arith_result=`expr \"$[@]\"`\n}\n\n# func_len string\n# STRING may not start with a hyphen.\nfunc_len ()\n{\n  func_len_result=`expr \"$[1]\" : \".*\" 2>/dev/null || echo $max_cmd_len`\n}\n\n_LT_EOF\nesac\n\ncase $lt_shell_append in\n  yes)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$[1]+=\\$[2]\"\n}\n_LT_EOF\n    ;;\n  *)\n    cat << \\_LT_EOF >> \"$cfgfile\"\n\n# func_append var value\n# Append VALUE to the end of shell variable VAR.\nfunc_append ()\n{\n  eval \"$[1]=\\$$[1]\\$[2]\"\n}\n\n_LT_EOF\n    ;;\n  esac\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/ltoptions.m4",
    "content": "# Helper functions for option handling.                    -*- Autoconf -*-\n#\n#   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.\n#   Written by Gary V. Vaughan, 2004\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# serial 6 ltoptions.m4\n\n# This is to help aclocal find these macros, as it can't see m4_define.\nAC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])\n\n\n# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)\n# ------------------------------------------\nm4_define([_LT_MANGLE_OPTION],\n[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])\n\n\n# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)\n# ---------------------------------------\n# Set option OPTION-NAME for macro MACRO-NAME, and if there is a\n# matching handler defined, dispatch to it.  Other OPTION-NAMEs are\n# saved as a flag.\nm4_define([_LT_SET_OPTION],\n[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl\nm4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),\n        _LT_MANGLE_DEFUN([$1], [$2]),\n    [m4_warning([Unknown $1 option `$2'])])[]dnl\n])\n\n\n# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])\n# ------------------------------------------------------------\n# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.\nm4_define([_LT_IF_OPTION],\n[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])\n\n\n# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)\n# -------------------------------------------------------\n# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME\n# are set.\nm4_define([_LT_UNLESS_OPTIONS],\n[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),\n\t    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),\n\t\t      [m4_define([$0_found])])])[]dnl\nm4_ifdef([$0_found], [m4_undefine([$0_found])], [$3\n])[]dnl\n])\n\n\n# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)\n# ----------------------------------------\n# OPTION-LIST is a space-separated list of Libtool options associated\n# with MACRO-NAME.  If any OPTION has a matching handler declared with\n# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about\n# the unknown option and exit.\nm4_defun([_LT_SET_OPTIONS],\n[# Set options\nm4_foreach([_LT_Option], m4_split(m4_normalize([$2])),\n    [_LT_SET_OPTION([$1], _LT_Option)])\n\nm4_if([$1],[LT_INIT],[\n  dnl\n  dnl Simply set some default values (i.e off) if boolean options were not\n  dnl specified:\n  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no\n  ])\n  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no\n  ])\n  dnl\n  dnl If no reference was made to various pairs of opposing options, then\n  dnl we run the default mode handler for the pair.  For example, if neither\n  dnl `shared' nor `disable-shared' was passed, we enable building of shared\n  dnl archives by default:\n  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])\n  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])\n  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])\n  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],\n  \t\t   [_LT_ENABLE_FAST_INSTALL])\n  ])\n])# _LT_SET_OPTIONS\n\n\n## --------------------------------- ##\n## Macros to handle LT_INIT options. ##\n## --------------------------------- ##\n\n# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)\n# -----------------------------------------\nm4_define([_LT_MANGLE_DEFUN],\n[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])\n\n\n# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)\n# -----------------------------------------------\nm4_define([LT_OPTION_DEFINE],\n[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl\n])# LT_OPTION_DEFINE\n\n\n# dlopen\n# ------\nLT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes\n])\n\nAU_DEFUN([AC_LIBTOOL_DLOPEN],\n[_LT_SET_OPTION([LT_INIT], [dlopen])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you\nput the `dlopen' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])\n\n\n# win32-dll\n# ---------\n# Declare package support for building win32 dll's.\nLT_OPTION_DEFINE([LT_INIT], [win32-dll],\n[enable_win32_dll=yes\n\ncase $host in\n*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)\n  AC_CHECK_TOOL(AS, as, false)\n  AC_CHECK_TOOL(DLLTOOL, dlltool, false)\n  AC_CHECK_TOOL(OBJDUMP, objdump, false)\n  ;;\nesac\n\ntest -z \"$AS\" && AS=as\n_LT_DECL([], [AS],      [0], [Assembler program])dnl\n\ntest -z \"$DLLTOOL\" && DLLTOOL=dlltool\n_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl\n\ntest -z \"$OBJDUMP\" && OBJDUMP=objdump\n_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl\n])# win32-dll\n\nAU_DEFUN([AC_LIBTOOL_WIN32_DLL],\n[AC_REQUIRE([AC_CANONICAL_HOST])dnl\n_LT_SET_OPTION([LT_INIT], [win32-dll])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you\nput the `win32-dll' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])\n\n\n# _LT_ENABLE_SHARED([DEFAULT])\n# ----------------------------\n# implement the --enable-shared flag, and supports the `shared' and\n# `disable-shared' LT_INIT options.\n# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.\nm4_define([_LT_ENABLE_SHARED],\n[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl\nAC_ARG_ENABLE([shared],\n    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],\n\t[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],\n    [p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_shared=yes ;;\n    no) enable_shared=no ;;\n    *)\n      enable_shared=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_shared=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)\n\n    _LT_DECL([build_libtool_libs], [enable_shared], [0],\n\t[Whether or not to build shared libraries])\n])# _LT_ENABLE_SHARED\n\nLT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])\nLT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])\n\n# Old names:\nAC_DEFUN([AC_ENABLE_SHARED],\n[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])\n])\n\nAC_DEFUN([AC_DISABLE_SHARED],\n[_LT_SET_OPTION([LT_INIT], [disable-shared])\n])\n\nAU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])\nAU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_ENABLE_SHARED], [])\ndnl AC_DEFUN([AM_DISABLE_SHARED], [])\n\n\n\n# _LT_ENABLE_STATIC([DEFAULT])\n# ----------------------------\n# implement the --enable-static flag, and support the `static' and\n# `disable-static' LT_INIT options.\n# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.\nm4_define([_LT_ENABLE_STATIC],\n[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl\nAC_ARG_ENABLE([static],\n    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],\n\t[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],\n    [p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_static=yes ;;\n    no) enable_static=no ;;\n    *)\n     enable_static=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_static=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)\n\n    _LT_DECL([build_old_libs], [enable_static], [0],\n\t[Whether or not to build static libraries])\n])# _LT_ENABLE_STATIC\n\nLT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])\nLT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])\n\n# Old names:\nAC_DEFUN([AC_ENABLE_STATIC],\n[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])\n])\n\nAC_DEFUN([AC_DISABLE_STATIC],\n[_LT_SET_OPTION([LT_INIT], [disable-static])\n])\n\nAU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])\nAU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AM_ENABLE_STATIC], [])\ndnl AC_DEFUN([AM_DISABLE_STATIC], [])\n\n\n\n# _LT_ENABLE_FAST_INSTALL([DEFAULT])\n# ----------------------------------\n# implement the --enable-fast-install flag, and support the `fast-install'\n# and `disable-fast-install' LT_INIT options.\n# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.\nm4_define([_LT_ENABLE_FAST_INSTALL],\n[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl\nAC_ARG_ENABLE([fast-install],\n    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],\n    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],\n    [p=${PACKAGE-default}\n    case $enableval in\n    yes) enable_fast_install=yes ;;\n    no) enable_fast_install=no ;;\n    *)\n      enable_fast_install=no\n      # Look at the argument we got.  We use all the common list separators.\n      lt_save_ifs=\"$IFS\"; IFS=\"${IFS}$PATH_SEPARATOR,\"\n      for pkg in $enableval; do\n\tIFS=\"$lt_save_ifs\"\n\tif test \"X$pkg\" = \"X$p\"; then\n\t  enable_fast_install=yes\n\tfi\n      done\n      IFS=\"$lt_save_ifs\"\n      ;;\n    esac],\n    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)\n\n_LT_DECL([fast_install], [enable_fast_install], [0],\n\t [Whether or not to optimize for fast installation])dnl\n])# _LT_ENABLE_FAST_INSTALL\n\nLT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])\nLT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])\n\n# Old names:\nAU_DEFUN([AC_ENABLE_FAST_INSTALL],\n[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you put\nthe `fast-install' option into LT_INIT's first parameter.])\n])\n\nAU_DEFUN([AC_DISABLE_FAST_INSTALL],\n[_LT_SET_OPTION([LT_INIT], [disable-fast-install])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you put\nthe `disable-fast-install' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])\ndnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])\n\n\n# _LT_WITH_PIC([MODE])\n# --------------------\n# implement the --with-pic flag, and support the `pic-only' and `no-pic'\n# LT_INIT options.\n# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.\nm4_define([_LT_WITH_PIC],\n[AC_ARG_WITH([pic],\n    [AS_HELP_STRING([--with-pic],\n\t[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],\n    [pic_mode=\"$withval\"],\n    [pic_mode=default])\n\ntest -z \"$pic_mode\" && pic_mode=m4_default([$1], [default])\n\n_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl\n])# _LT_WITH_PIC\n\nLT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])\nLT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])\n\n# Old name:\nAU_DEFUN([AC_LIBTOOL_PICMODE],\n[_LT_SET_OPTION([LT_INIT], [pic-only])\nAC_DIAGNOSE([obsolete],\n[$0: Remove this warning and the call to _LT_SET_OPTION when you\nput the `pic-only' option into LT_INIT's first parameter.])\n])\n\ndnl aclocal-1.4 backwards compatibility:\ndnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])\n\n## ----------------- ##\n## LTDL_INIT Options ##\n## ----------------- ##\n\nm4_define([_LTDL_MODE], [])\nLT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],\n\t\t [m4_define([_LTDL_MODE], [nonrecursive])])\nLT_OPTION_DEFINE([LTDL_INIT], [recursive],\n\t\t [m4_define([_LTDL_MODE], [recursive])])\nLT_OPTION_DEFINE([LTDL_INIT], [subproject],\n\t\t [m4_define([_LTDL_MODE], [subproject])])\n\nm4_define([_LTDL_TYPE], [])\nLT_OPTION_DEFINE([LTDL_INIT], [installable],\n\t\t [m4_define([_LTDL_TYPE], [installable])])\nLT_OPTION_DEFINE([LTDL_INIT], [convenience],\n\t\t [m4_define([_LTDL_TYPE], [convenience])])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/ltsugar.m4",
    "content": "# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-\n#\n# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.\n# Written by Gary V. Vaughan, 2004\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# serial 6 ltsugar.m4\n\n# This is to help aclocal find these macros, as it can't see m4_define.\nAC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])\n\n\n# lt_join(SEP, ARG1, [ARG2...])\n# -----------------------------\n# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their\n# associated separator.\n# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier\n# versions in m4sugar had bugs.\nm4_define([lt_join],\n[m4_if([$#], [1], [],\n       [$#], [2], [[$2]],\n       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])\nm4_define([_lt_join],\n[m4_if([$#$2], [2], [],\n       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])\n\n\n# lt_car(LIST)\n# lt_cdr(LIST)\n# ------------\n# Manipulate m4 lists.\n# These macros are necessary as long as will still need to support\n# Autoconf-2.59 which quotes differently.\nm4_define([lt_car], [[$1]])\nm4_define([lt_cdr],\n[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],\n       [$#], 1, [],\n       [m4_dquote(m4_shift($@))])])\nm4_define([lt_unquote], $1)\n\n\n# lt_append(MACRO-NAME, STRING, [SEPARATOR])\n# ------------------------------------------\n# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.\n# Note that neither SEPARATOR nor STRING are expanded; they are appended\n# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).\n# No SEPARATOR is output if MACRO-NAME was previously undefined (different\n# than defined and empty).\n#\n# This macro is needed until we can rely on Autoconf 2.62, since earlier\n# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.\nm4_define([lt_append],\n[m4_define([$1],\n\t   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])\n\n\n\n# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])\n# ----------------------------------------------------------\n# Produce a SEP delimited list of all paired combinations of elements of\n# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list\n# has the form PREFIXmINFIXSUFFIXn.\n# Needed until we can rely on m4_combine added in Autoconf 2.62.\nm4_define([lt_combine],\n[m4_if(m4_eval([$# > 3]), [1],\n       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl\n[[m4_foreach([_Lt_prefix], [$2],\n\t     [m4_foreach([_Lt_suffix],\n\t\t]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,\n\t[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])\n\n\n# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])\n# -----------------------------------------------------------------------\n# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited\n# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.\nm4_define([lt_if_append_uniq],\n[m4_ifdef([$1],\n\t  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],\n\t\t [lt_append([$1], [$2], [$3])$4],\n\t\t [$5])],\n\t  [lt_append([$1], [$2], [$3])$4])])\n\n\n# lt_dict_add(DICT, KEY, VALUE)\n# -----------------------------\nm4_define([lt_dict_add],\n[m4_define([$1($2)], [$3])])\n\n\n# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)\n# --------------------------------------------\nm4_define([lt_dict_add_subkey],\n[m4_define([$1($2:$3)], [$4])])\n\n\n# lt_dict_fetch(DICT, KEY, [SUBKEY])\n# ----------------------------------\nm4_define([lt_dict_fetch],\n[m4_ifval([$3],\n\tm4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),\n    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])\n\n\n# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])\n# -----------------------------------------------------------------\nm4_define([lt_if_dict_fetch],\n[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],\n\t[$5],\n    [$6])])\n\n\n# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])\n# --------------------------------------------------------------\nm4_define([lt_dict_filter],\n[m4_if([$5], [], [],\n  [lt_join(m4_quote(m4_default([$4], [[, ]])),\n           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),\n\t\t      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/ltversion.m4",
    "content": "# ltversion.m4 -- version numbers\t\t\t-*- Autoconf -*-\n#\n#   Copyright (C) 2004 Free Software Foundation, Inc.\n#   Written by Scott James Remnant, 2004\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# Generated from ltversion.in.\n\n# serial 3017 ltversion.m4\n# This file is part of GNU Libtool\n\nm4_define([LT_PACKAGE_VERSION], [2.2.6b])\nm4_define([LT_PACKAGE_REVISION], [1.3017])\n\nAC_DEFUN([LTVERSION_VERSION],\n[macro_version='2.2.6b'\nmacro_revision='1.3017'\n_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])\n_LT_DECL(, macro_revision, 0)\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/lt~obsolete.m4",
    "content": "# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-\n#\n#   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.\n#   Written by Scott James Remnant, 2004.\n#\n# This file is free software; the Free Software Foundation gives\n# unlimited permission to copy and/or distribute it, with or without\n# modifications, as long as this notice is preserved.\n\n# serial 4 lt~obsolete.m4\n\n# These exist entirely to fool aclocal when bootstrapping libtool.\n#\n# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)\n# which have later been changed to m4_define as they aren't part of the\n# exported API, or moved to Autoconf or Automake where they belong.\n#\n# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN\n# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us\n# using a macro with the same name in our local m4/libtool.m4 it'll\n# pull the old libtool.m4 in (it doesn't see our shiny new m4_define\n# and doesn't know about Autoconf macros at all.)\n#\n# So we provide this file, which has a silly filename so it's always\n# included after everything else.  This provides aclocal with the\n# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything\n# because those macros already exist, or will be overwritten later.\n# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. \n#\n# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.\n# Yes, that means every name once taken will need to remain here until\n# we give up compatibility with versions before 1.7, at which point\n# we need to keep only those names which we still refer to.\n\n# This is to help aclocal find these macros, as it can't see m4_define.\nAC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])\n\nm4_ifndef([AC_LIBTOOL_LINKER_OPTION],\t[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])\nm4_ifndef([AC_PROG_EGREP],\t\t[AC_DEFUN([AC_PROG_EGREP])])\nm4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],\t[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])\nm4_ifndef([_LT_AC_SHELL_INIT],\t\t[AC_DEFUN([_LT_AC_SHELL_INIT])])\nm4_ifndef([_LT_AC_SYS_LIBPATH_AIX],\t[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])\nm4_ifndef([_LT_PROG_LTMAIN],\t\t[AC_DEFUN([_LT_PROG_LTMAIN])])\nm4_ifndef([_LT_AC_TAGVAR],\t\t[AC_DEFUN([_LT_AC_TAGVAR])])\nm4_ifndef([AC_LTDL_ENABLE_INSTALL],\t[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])\nm4_ifndef([AC_LTDL_PREOPEN],\t\t[AC_DEFUN([AC_LTDL_PREOPEN])])\nm4_ifndef([_LT_AC_SYS_COMPILER],\t[AC_DEFUN([_LT_AC_SYS_COMPILER])])\nm4_ifndef([_LT_AC_LOCK],\t\t[AC_DEFUN([_LT_AC_LOCK])])\nm4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],\t[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])\nm4_ifndef([_LT_AC_TRY_DLOPEN_SELF],\t[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])\nm4_ifndef([AC_LIBTOOL_PROG_CC_C_O],\t[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])\nm4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])\nm4_ifndef([AC_LIBTOOL_OBJDIR],\t\t[AC_DEFUN([AC_LIBTOOL_OBJDIR])])\nm4_ifndef([AC_LTDL_OBJDIR],\t\t[AC_DEFUN([AC_LTDL_OBJDIR])])\nm4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])\nm4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],\t[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])\nm4_ifndef([AC_PATH_MAGIC],\t\t[AC_DEFUN([AC_PATH_MAGIC])])\nm4_ifndef([AC_PROG_LD_GNU],\t\t[AC_DEFUN([AC_PROG_LD_GNU])])\nm4_ifndef([AC_PROG_LD_RELOAD_FLAG],\t[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])\nm4_ifndef([AC_DEPLIBS_CHECK_METHOD],\t[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])\nm4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])\nm4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])\nm4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])\nm4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],\t[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])\nm4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],\t[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])\nm4_ifndef([LT_AC_PROG_EGREP],\t\t[AC_DEFUN([LT_AC_PROG_EGREP])])\nm4_ifndef([LT_AC_PROG_SED],\t\t[AC_DEFUN([LT_AC_PROG_SED])])\nm4_ifndef([_LT_CC_BASENAME],\t\t[AC_DEFUN([_LT_CC_BASENAME])])\nm4_ifndef([_LT_COMPILER_BOILERPLATE],\t[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])\nm4_ifndef([_LT_LINKER_BOILERPLATE],\t[AC_DEFUN([_LT_LINKER_BOILERPLATE])])\nm4_ifndef([_AC_PROG_LIBTOOL],\t\t[AC_DEFUN([_AC_PROG_LIBTOOL])])\nm4_ifndef([AC_LIBTOOL_SETUP],\t\t[AC_DEFUN([AC_LIBTOOL_SETUP])])\nm4_ifndef([_LT_AC_CHECK_DLFCN],\t\t[AC_DEFUN([_LT_AC_CHECK_DLFCN])])\nm4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],\t[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])\nm4_ifndef([_LT_AC_TAGCONFIG],\t\t[AC_DEFUN([_LT_AC_TAGCONFIG])])\nm4_ifndef([AC_DISABLE_FAST_INSTALL],\t[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])\nm4_ifndef([_LT_AC_LANG_CXX],\t\t[AC_DEFUN([_LT_AC_LANG_CXX])])\nm4_ifndef([_LT_AC_LANG_F77],\t\t[AC_DEFUN([_LT_AC_LANG_F77])])\nm4_ifndef([_LT_AC_LANG_GCJ],\t\t[AC_DEFUN([_LT_AC_LANG_GCJ])])\nm4_ifndef([AC_LIBTOOL_RC],\t\t[AC_DEFUN([AC_LIBTOOL_RC])])\nm4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])\nm4_ifndef([_LT_AC_LANG_C_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])\nm4_ifndef([_LT_AC_LANG_CXX_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])\nm4_ifndef([_LT_AC_LANG_F77_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])\nm4_ifndef([_LT_AC_LANG_GCJ_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])\nm4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],\t[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])\nm4_ifndef([_LT_AC_LANG_RC_CONFIG],\t[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])\nm4_ifndef([AC_LIBTOOL_CONFIG],\t\t[AC_DEFUN([AC_LIBTOOL_CONFIG])])\nm4_ifndef([_LT_AC_FILE_LTDLL_C],\t[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/namespaces.m4",
    "content": "# Checks whether the compiler implements namespaces\nAC_DEFUN([AC_CXX_NAMESPACES],\n [AC_CACHE_CHECK(whether the compiler implements namespaces,\n                 ac_cv_cxx_namespaces,\n                 [AC_LANG_SAVE\n                  AC_LANG_CPLUSPLUS\n                  AC_TRY_COMPILE([namespace Outer {\n                                    namespace Inner { int i = 0; }}],\n                                 [using namespace Outer::Inner; return i;],\n                                 ac_cv_cxx_namespaces=yes,\n                                 ac_cv_cxx_namespaces=no)\n                  AC_LANG_RESTORE])\n  if test \"$ac_cv_cxx_namespaces\" = yes; then\n    AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])\n  fi])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/pc_from_ucontext.m4",
    "content": "# We want to access the \"PC\" (Program Counter) register from a struct\n# ucontext.  Every system has its own way of doing that.  We try all the\n# possibilities we know about.  Note REG_PC should come first (REG_RIP\n# is also defined on solaris, but does the wrong thing).\n\n# OpenBSD doesn't have ucontext.h, but we can get PC from ucontext_t\n# by using signal.h.\n\n# The first argument of AC_PC_FROM_UCONTEXT will be invoked when we\n# cannot find a way to obtain PC from ucontext.\n\nAC_DEFUN([AC_PC_FROM_UCONTEXT],\n  [AC_CHECK_HEADERS(ucontext.h)\n   # Redhat 7 has <sys/ucontext.h>, but it barfs if we #include it directly\n   # (this was fixed in later redhats).  <ucontext.h> works fine, so use that.\n   if grep \"Red Hat Linux release 7\" /etc/redhat-release >/dev/null 2>&1; then\n     AC_DEFINE(HAVE_SYS_UCONTEXT_H, 0, [<sys/ucontext.h> is broken on redhat 7])\n     ac_cv_header_sys_ucontext_h=no\n   else\n     AC_CHECK_HEADERS(sys/ucontext.h)       # ucontext on OS X 10.6 (at least)\n   fi\n   AC_CHECK_HEADERS(cygwin/signal.h)        # ucontext on cywgin\n   AC_MSG_CHECKING([how to access the program counter from a struct ucontext])\n   pc_fields=\"           uc_mcontext.gregs[[REG_PC]]\"  # Solaris x86 (32 + 64 bit)\n   pc_fields=\"$pc_fields uc_mcontext.gregs[[REG_EIP]]\" # Linux (i386)\n   pc_fields=\"$pc_fields uc_mcontext.gregs[[REG_RIP]]\" # Linux (x86_64)\n   pc_fields=\"$pc_fields uc_mcontext.sc_ip\"            # Linux (ia64)\n   pc_fields=\"$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]\" # Linux (ppc)\n   pc_fields=\"$pc_fields uc_mcontext.gregs[[R15]]\"     # Linux (arm old [untested])\n   pc_fields=\"$pc_fields uc_mcontext.arm_pc\"           # Linux (arm arch 5)\n   pc_fields=\"$pc_fields uc_mcontext.gp_regs[[PT_NIP]]\"  # Suse SLES 11 (ppc64)\n   pc_fields=\"$pc_fields uc_mcontext.mc_eip\"           # FreeBSD (i386)\n   pc_fields=\"$pc_fields uc_mcontext.mc_rip\"           # FreeBSD (x86_64 [untested])\n   pc_fields=\"$pc_fields uc_mcontext.__gregs[[_REG_EIP]]\"  # NetBSD (i386)\n   pc_fields=\"$pc_fields uc_mcontext.__gregs[[_REG_RIP]]\"  # NetBSD (x86_64)\n   pc_fields=\"$pc_fields uc_mcontext->ss.eip\"          # OS X (i386, <=10.4)\n   pc_fields=\"$pc_fields uc_mcontext->__ss.__eip\"      # OS X (i386, >=10.5)\n   pc_fields=\"$pc_fields uc_mcontext->ss.rip\"          # OS X (x86_64)\n   pc_fields=\"$pc_fields uc_mcontext->__ss.__rip\"      # OS X (>=10.5 [untested])\n   pc_fields=\"$pc_fields uc_mcontext->ss.srr0\"         # OS X (ppc, ppc64 [untested])\n   pc_fields=\"$pc_fields uc_mcontext->__ss.__srr0\"     # OS X (>=10.5 [untested])\n   pc_field_found=false\n   for pc_field in $pc_fields; do\n     if ! $pc_field_found; then\n       # Prefer sys/ucontext.h to ucontext.h, for OS X's sake.\n       if test \"x$ac_cv_header_cygwin_signal_h\" = xyes; then\n         AC_TRY_COMPILE([#define _GNU_SOURCE 1\n                         #include <cygwin/signal.h>],\n                        [ucontext_t u; return u.$pc_field == 0;],\n                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,\n                                           How to access the PC from a struct ucontext)\n                        AC_MSG_RESULT([$pc_field])\n                        pc_field_found=true)\n       elif test \"x$ac_cv_header_sys_ucontext_h\" = xyes; then\n         AC_TRY_COMPILE([#define _GNU_SOURCE 1\n                         #include <sys/ucontext.h>],\n                        [ucontext_t u; return u.$pc_field == 0;],\n                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,\n                                           How to access the PC from a struct ucontext)\n                        AC_MSG_RESULT([$pc_field])\n                        pc_field_found=true)\n       elif test \"x$ac_cv_header_ucontext_h\" = xyes; then\n         AC_TRY_COMPILE([#define _GNU_SOURCE 1\n                         #include <ucontext.h>],\n                        [ucontext_t u; return u.$pc_field == 0;],\n                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,\n                                           How to access the PC from a struct ucontext)\n                        AC_MSG_RESULT([$pc_field])\n                        pc_field_found=true)\n       else     # hope some standard header gives it to us\n         AC_TRY_COMPILE([],\n                        [ucontext_t u; return u.$pc_field == 0;],\n                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,\n                                           How to access the PC from a struct ucontext)\n                        AC_MSG_RESULT([$pc_field])\n                        pc_field_found=true)\n       fi\n     fi\n   done\n   if ! $pc_field_found; then\n     pc_fields=\"           sc_eip\"  # OpenBSD (i386)\n     pc_fields=\"$pc_fields sc_rip\"  # OpenBSD (x86_64)\n     for pc_field in $pc_fields; do\n       if ! $pc_field_found; then\n         AC_TRY_COMPILE([#include <signal.h>],\n                        [ucontext_t u; return u.$pc_field == 0;],\n                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,\n                                           How to access the PC from a struct ucontext)\n                        AC_MSG_RESULT([$pc_field])\n                        pc_field_found=true)\n       fi\n     done\n   fi\n   if ! $pc_field_found; then\n     [$1]\n   fi])\n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/program_invocation_name.m4",
    "content": "# We need to be careful to avoid having the reference to\n# program_invocation_name optimized out.  We do that by\n# returning the value.\n\nAC_DEFUN([AC_PROGRAM_INVOCATION_NAME],\n  [AC_CACHE_CHECK(\n    for program_invocation_name,\n    ac_cv_have_program_invocation_name,\n    AC_TRY_LINK([extern char* program_invocation_name;],\n\t        [return *program_invocation_name;],\n\t        [ac_cv_have_program_invocation_name=yes],\n\t\t[ac_cv_have_program_invocation_name=no])\n   )\n   if test \"$ac_cv_have_program_invocation_name\" = \"yes\"; then\n     AC_DEFINE(HAVE_PROGRAM_INVOCATION_NAME, 1,\n               [define if libc has program_invocation_name])\n   fi\n   ])\n   \n"
  },
  {
    "path": "distro/google-perftools-1.7/m4/stl_namespace.m4",
    "content": "# We check what namespace stl code like vector expects to be executed in\n\nAC_DEFUN([AC_CXX_STL_NAMESPACE],\n  [AC_CACHE_CHECK(\n      what namespace STL code is in,\n      ac_cv_cxx_stl_namespace,\n      [AC_REQUIRE([AC_CXX_NAMESPACES])\n      AC_LANG_SAVE\n      AC_LANG_CPLUSPLUS\n      AC_TRY_COMPILE([#include <vector>],\n                     [vector<int> t; return 0;],\n                     ac_cv_cxx_stl_namespace=none)\n      AC_TRY_COMPILE([#include <vector>],\n                     [std::vector<int> t; return 0;],\n                     ac_cv_cxx_stl_namespace=std)\n      AC_LANG_RESTORE])\n   if test \"$ac_cv_cxx_stl_namespace\" = none; then\n      AC_DEFINE(STL_NAMESPACE,,\n                [the namespace where STL code like vector<> is defined])\n   fi\n   if test \"$ac_cv_cxx_stl_namespace\" = std; then\n      AC_DEFINE(STL_NAMESPACE,std,\n                [the namespace where STL code like vector<> is defined])\n   fi\n])\n"
  },
  {
    "path": "distro/google-perftools-1.7/missing",
    "content": "#! /bin/sh\n# Common stub for a few missing GNU programs while installing.\n\nscriptversion=2005-06-08.21\n\n# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005\n#   Free Software Foundation, Inc.\n# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2, or (at your option)\n# any later version.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n# 02110-1301, USA.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\nif test $# -eq 0; then\n  echo 1>&2 \"Try \\`$0 --help' for more information\"\n  exit 1\nfi\n\nrun=:\n\n# In the cases where this matters, `missing' is being run in the\n# srcdir already.\nif test -f configure.ac; then\n  configure_ac=configure.ac\nelse\n  configure_ac=configure.in\nfi\n\nmsg=\"missing on your system\"\n\ncase \"$1\" in\n--run)\n  # Try to run requested program, and just exit if it succeeds.\n  run=\n  shift\n  \"$@\" && exit 0\n  # Exit code 63 means version mismatch.  This often happens\n  # when the user try to use an ancient version of a tool on\n  # a file that requires a minimum version.  In this case we\n  # we should proceed has if the program had been absent, or\n  # if --run hadn't been passed.\n  if test $? = 63; then\n    run=:\n    msg=\"probably too old\"\n  fi\n  ;;\n\n  -h|--h|--he|--hel|--help)\n    echo \"\\\n$0 [OPTION]... PROGRAM [ARGUMENT]...\n\nHandle \\`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an\nerror status if there is no known handling for PROGRAM.\n\nOptions:\n  -h, --help      display this help and exit\n  -v, --version   output version information and exit\n  --run           try to run the given command, and emulate it if it fails\n\nSupported PROGRAM values:\n  aclocal      touch file \\`aclocal.m4'\n  autoconf     touch file \\`configure'\n  autoheader   touch file \\`config.h.in'\n  automake     touch all \\`Makefile.in' files\n  bison        create \\`y.tab.[ch]', if possible, from existing .[ch]\n  flex         create \\`lex.yy.c', if possible, from existing .c\n  help2man     touch the output file\n  lex          create \\`lex.yy.c', if possible, from existing .c\n  makeinfo     touch the output file\n  tar          try tar, gnutar, gtar, then tar without non-portable flags\n  yacc         create \\`y.tab.[ch]', if possible, from existing .[ch]\n\nSend bug reports to <bug-automake@gnu.org>.\"\n    exit $?\n    ;;\n\n  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)\n    echo \"missing $scriptversion (GNU Automake)\"\n    exit $?\n    ;;\n\n  -*)\n    echo 1>&2 \"$0: Unknown \\`$1' option\"\n    echo 1>&2 \"Try \\`$0 --help' for more information\"\n    exit 1\n    ;;\n\nesac\n\n# Now exit if we have it, but it failed.  Also exit now if we\n# don't have it and --version was passed (most likely to detect\n# the program).\ncase \"$1\" in\n  lex|yacc)\n    # Not GNU programs, they don't have --version.\n    ;;\n\n  tar)\n    if test -n \"$run\"; then\n       echo 1>&2 \"ERROR: \\`tar' requires --run\"\n       exit 1\n    elif test \"x$2\" = \"x--version\" || test \"x$2\" = \"x--help\"; then\n       exit 1\n    fi\n    ;;\n\n  *)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    elif test \"x$2\" = \"x--version\" || test \"x$2\" = \"x--help\"; then\n       # Could not run --version or --help.  This is probably someone\n       # running `$TOOL --version' or `$TOOL --help' to check whether\n       # $TOOL exists and not knowing $TOOL uses missing.\n       exit 1\n    fi\n    ;;\nesac\n\n# If it does not exist, or fails to run (possibly an outdated version),\n# try to emulate it.\ncase \"$1\" in\n  aclocal*)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n         you modified \\`acinclude.m4' or \\`${configure_ac}'.  You might want\n         to install the \\`Automake' and \\`Perl' packages.  Grab them from\n         any GNU archive site.\"\n    touch aclocal.m4\n    ;;\n\n  autoconf)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n         you modified \\`${configure_ac}'.  You might want to install the\n         \\`Autoconf' and \\`GNU m4' packages.  Grab them from any GNU\n         archive site.\"\n    touch configure\n    ;;\n\n  autoheader)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n         you modified \\`acconfig.h' or \\`${configure_ac}'.  You might want\n         to install the \\`Autoconf' and \\`GNU m4' packages.  Grab them\n         from any GNU archive site.\"\n    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\\([^)]*\\)).*/\\1/p' ${configure_ac}`\n    test -z \"$files\" && files=\"config.h\"\n    touch_files=\n    for f in $files; do\n      case \"$f\" in\n      *:*) touch_files=\"$touch_files \"`echo \"$f\" |\n\t\t\t\t       sed -e 's/^[^:]*://' -e 's/:.*//'`;;\n      *) touch_files=\"$touch_files $f.in\";;\n      esac\n    done\n    touch $touch_files\n    ;;\n\n  automake*)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n         you modified \\`Makefile.am', \\`acinclude.m4' or \\`${configure_ac}'.\n         You might want to install the \\`Automake' and \\`Perl' packages.\n         Grab them from any GNU archive site.\"\n    find . -type f -name Makefile.am -print |\n\t   sed 's/\\.am$/.in/' |\n\t   while read f; do touch \"$f\"; done\n    ;;\n\n  autom4te)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is needed, but is $msg.\n         You might have modified some files without having the\n         proper tools for further handling them.\n         You can get \\`$1' as part of \\`Autoconf' from any GNU\n         archive site.\"\n\n    file=`echo \"$*\" | sed -n 's/.*--output[ =]*\\([^ ]*\\).*/\\1/p'`\n    test -z \"$file\" && file=`echo \"$*\" | sed -n 's/.*-o[ ]*\\([^ ]*\\).*/\\1/p'`\n    if test -f \"$file\"; then\n\ttouch $file\n    else\n\ttest -z \"$file\" || exec >$file\n\techo \"#! /bin/sh\"\n\techo \"# Created by GNU Automake missing as a replacement of\"\n\techo \"#  $ $@\"\n\techo \"exit 0\"\n\tchmod +x $file\n\texit 1\n    fi\n    ;;\n\n  bison|yacc)\n    echo 1>&2 \"\\\nWARNING: \\`$1' $msg.  You should only need it if\n         you modified a \\`.y' file.  You may need the \\`Bison' package\n         in order for those modifications to take effect.  You can get\n         \\`Bison' from any GNU archive site.\"\n    rm -f y.tab.c y.tab.h\n    if [ $# -ne 1 ]; then\n        eval LASTARG=\"\\${$#}\"\n\tcase \"$LASTARG\" in\n\t*.y)\n\t    SRCFILE=`echo \"$LASTARG\" | sed 's/y$/c/'`\n\t    if [ -f \"$SRCFILE\" ]; then\n\t         cp \"$SRCFILE\" y.tab.c\n\t    fi\n\t    SRCFILE=`echo \"$LASTARG\" | sed 's/y$/h/'`\n\t    if [ -f \"$SRCFILE\" ]; then\n\t         cp \"$SRCFILE\" y.tab.h\n\t    fi\n\t  ;;\n\tesac\n    fi\n    if [ ! -f y.tab.h ]; then\n\techo >y.tab.h\n    fi\n    if [ ! -f y.tab.c ]; then\n\techo 'main() { return 0; }' >y.tab.c\n    fi\n    ;;\n\n  lex|flex)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n         you modified a \\`.l' file.  You may need the \\`Flex' package\n         in order for those modifications to take effect.  You can get\n         \\`Flex' from any GNU archive site.\"\n    rm -f lex.yy.c\n    if [ $# -ne 1 ]; then\n        eval LASTARG=\"\\${$#}\"\n\tcase \"$LASTARG\" in\n\t*.l)\n\t    SRCFILE=`echo \"$LASTARG\" | sed 's/l$/c/'`\n\t    if [ -f \"$SRCFILE\" ]; then\n\t         cp \"$SRCFILE\" lex.yy.c\n\t    fi\n\t  ;;\n\tesac\n    fi\n    if [ ! -f lex.yy.c ]; then\n\techo 'main() { return 0; }' >lex.yy.c\n    fi\n    ;;\n\n  help2man)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n\t you modified a dependency of a manual page.  You may need the\n\t \\`Help2man' package in order for those modifications to take\n\t effect.  You can get \\`Help2man' from any GNU archive site.\"\n\n    file=`echo \"$*\" | sed -n 's/.*-o \\([^ ]*\\).*/\\1/p'`\n    if test -z \"$file\"; then\n\tfile=`echo \"$*\" | sed -n 's/.*--output=\\([^ ]*\\).*/\\1/p'`\n    fi\n    if [ -f \"$file\" ]; then\n\ttouch $file\n    else\n\ttest -z \"$file\" || exec >$file\n\techo \".ab help2man is required to generate this page\"\n\texit 1\n    fi\n    ;;\n\n  makeinfo)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is $msg.  You should only need it if\n         you modified a \\`.texi' or \\`.texinfo' file, or any other file\n         indirectly affecting the aspect of the manual.  The spurious\n         call might also be the consequence of using a buggy \\`make' (AIX,\n         DU, IRIX).  You might want to install the \\`Texinfo' package or\n         the \\`GNU make' package.  Grab either from any GNU archive site.\"\n    # The file to touch is that specified with -o ...\n    file=`echo \"$*\" | sed -n 's/.*-o \\([^ ]*\\).*/\\1/p'`\n    if test -z \"$file\"; then\n      # ... or it is the one specified with @setfilename ...\n      infile=`echo \"$*\" | sed 's/.* \\([^ ]*\\) *$/\\1/'`\n      file=`sed -n '/^@setfilename/ { s/.* \\([^ ]*\\) *$/\\1/; p; q; }' $infile`\n      # ... or it is derived from the source name (dir/f.texi becomes f.info)\n      test -z \"$file\" && file=`echo \"$infile\" | sed 's,.*/,,;s,.[^.]*$,,'`.info\n    fi\n    # If the file does not exist, the user really needs makeinfo;\n    # let's fail without touching anything.\n    test -f $file || exit 1\n    touch $file\n    ;;\n\n  tar)\n    shift\n\n    # We have already tried tar in the generic part.\n    # Look for gnutar/gtar before invocation to avoid ugly error\n    # messages.\n    if (gnutar --version > /dev/null 2>&1); then\n       gnutar \"$@\" && exit 0\n    fi\n    if (gtar --version > /dev/null 2>&1); then\n       gtar \"$@\" && exit 0\n    fi\n    firstarg=\"$1\"\n    if shift; then\n\tcase \"$firstarg\" in\n\t*o*)\n\t    firstarg=`echo \"$firstarg\" | sed s/o//`\n\t    tar \"$firstarg\" \"$@\" && exit 0\n\t    ;;\n\tesac\n\tcase \"$firstarg\" in\n\t*h*)\n\t    firstarg=`echo \"$firstarg\" | sed s/h//`\n\t    tar \"$firstarg\" \"$@\" && exit 0\n\t    ;;\n\tesac\n    fi\n\n    echo 1>&2 \"\\\nWARNING: I can't seem to be able to run \\`tar' with the given arguments.\n         You may want to install GNU tar or Free paxutils, or check the\n         command line arguments.\"\n    exit 1\n    ;;\n\n  *)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is needed, and is $msg.\n         You might have modified some files without having the\n         proper tools for further handling them.  Check the \\`README' file,\n         it often tells you about the needed prerequisites for installing\n         this package.  You may also peek at any GNU archive site, in case\n         some other package would contain this missing \\`$1' program.\"\n    exit 1\n    ;;\nesac\n\nexit 0\n\n# Local variables:\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-end: \"$\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/mkinstalldirs",
    "content": "#! /bin/sh\n# mkinstalldirs --- make directory hierarchy\n\nscriptversion=2005-06-29.22\n\n# Original author: Noah Friedman <friedman@prep.ai.mit.edu>\n# Created: 1993-05-16\n# Public domain.\n#\n# This file is maintained in Automake, please report\n# bugs to <bug-automake@gnu.org> or send patches to\n# <automake-patches@gnu.org>.\n\nerrstatus=0\ndirmode=\n\nusage=\"\\\nUsage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...\n\nCreate each directory DIR (with mode MODE, if specified), including all\nleading file name components.\n\nReport bugs to <bug-automake@gnu.org>.\"\n\n# process command line arguments\nwhile test $# -gt 0 ; do\n  case $1 in\n    -h | --help | --h*)         # -h for help\n      echo \"$usage\"\n      exit $?\n      ;;\n    -m)                         # -m PERM arg\n      shift\n      test $# -eq 0 && { echo \"$usage\" 1>&2; exit 1; }\n      dirmode=$1\n      shift\n      ;;\n    --version)\n      echo \"$0 $scriptversion\"\n      exit $?\n      ;;\n    --)                         # stop option processing\n      shift\n      break\n      ;;\n    -*)                         # unknown option\n      echo \"$usage\" 1>&2\n      exit 1\n      ;;\n    *)                          # first non-opt arg\n      break\n      ;;\n  esac\ndone\n\nfor file\ndo\n  if test -d \"$file\"; then\n    shift\n  else\n    break\n  fi\ndone\n\ncase $# in\n  0) exit 0 ;;\nesac\n\n# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and\n# mkdir -p a/c at the same time, both will detect that a is missing,\n# one will create a, then the other will try to create a and die with\n# a \"File exists\" error.  This is a problem when calling mkinstalldirs\n# from a parallel make.  We use --version in the probe to restrict\n# ourselves to GNU mkdir, which is thread-safe.\ncase $dirmode in\n  '')\n    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then\n      echo \"mkdir -p -- $*\"\n      exec mkdir -p -- \"$@\"\n    else\n      # On NextStep and OpenStep, the `mkdir' command does not\n      # recognize any option.  It will interpret all options as\n      # directories to create, and then abort because `.' already\n      # exists.\n      test -d ./-p && rmdir ./-p\n      test -d ./--version && rmdir ./--version\n    fi\n    ;;\n  *)\n    if mkdir -m \"$dirmode\" -p --version . >/dev/null 2>&1 &&\n       test ! -d ./--version; then\n      echo \"mkdir -m $dirmode -p -- $*\"\n      exec mkdir -m \"$dirmode\" -p -- \"$@\"\n    else\n      # Clean up after NextStep and OpenStep mkdir.\n      for d in ./-m ./-p ./--version \"./$dirmode\";\n      do\n        test -d $d && rmdir $d\n      done\n    fi\n    ;;\nesac\n\nfor file\ndo\n  case $file in\n    /*) pathcomp=/ ;;\n    *)  pathcomp= ;;\n  esac\n  oIFS=$IFS\n  IFS=/\n  set fnord $file\n  shift\n  IFS=$oIFS\n\n  for d\n  do\n    test \"x$d\" = x && continue\n\n    pathcomp=$pathcomp$d\n    case $pathcomp in\n      -*) pathcomp=./$pathcomp ;;\n    esac\n\n    if test ! -d \"$pathcomp\"; then\n      echo \"mkdir $pathcomp\"\n\n      mkdir \"$pathcomp\" || lasterr=$?\n\n      if test ! -d \"$pathcomp\"; then\n\terrstatus=$lasterr\n      else\n\tif test ! -z \"$dirmode\"; then\n\t  echo \"chmod $dirmode $pathcomp\"\n\t  lasterr=\n\t  chmod \"$dirmode\" \"$pathcomp\" || lasterr=$?\n\n\t  if test ! -z \"$lasterr\"; then\n\t    errstatus=$lasterr\n\t  fi\n\tfi\n      fi\n    fi\n\n    pathcomp=$pathcomp/\n  done\ndone\n\nexit $errstatus\n\n# Local Variables:\n# mode: shell-script\n# sh-indentation: 2\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-end: \"$\"\n# End:\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/README",
    "content": "The list of files here isn't complete.  For a step-by-step guide on\nhow to set this package up correctly, check out\n    http://www.debian.org/doc/maint-guide/\n\nMost of the files that are in this directory are boilerplate.\nHowever, you may need to change the list of binary-arch dependencies\nin 'rules'.\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/changelog",
    "content": "google-perftools (1.7-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Fri, 04 Feb 2011 15:54:31 -0800\n\ngoogle-perftools (1.6-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Thu, 05 Aug 2010 12:48:03 -0700\n\ngoogle-perftools (1.5-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 19 Jan 2010 14:46:12 -0800\n\ngoogle-perftools (1.4-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Thu, 10 Sep 2009 13:51:15 -0700\n\ngoogle-perftools (1.3-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 09 Jun 2009 18:19:06 -0700\n\ngoogle-perftools (1.2-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Fri, 17 Apr 2009 16:40:48 -0700\n\ngoogle-perftools (1.1-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Wed, 11 Mar 2009 11:25:34 -0700\n\ngoogle-perftools (1.0-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 06 Jan 2009 13:58:56 -0800\n\t\ngoogle-perftools (1.0rc1-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Thu, 11 Dec 2008 16:01:32 -0800\n\t\ngoogle-perftools (0.99.1-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Sat, 20 Sep 2008 09:37:18 -0700\n\t\ngoogle-perftools (0.99-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Thu, 18 Sep 2008 16:00:27 -0700\n\t\ngoogle-perftools (0.98-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Mon, 09 Jun 2008 16:47:03 -0700\n\t\ngoogle-perftools (0.97-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Mon, 21 Apr 2008 15:20:52 -0700\n\t\ngoogle-perftools (0.96-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 18 Mar 2008 14:30:44 -0700\n\t\ngoogle-perftools (0.95-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 12 Feb 2008 12:28:32 -0800\n\ngoogle-perftools (0.94-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Thu, 29 Nov 2007 07:59:43 -0800\n\ngoogle-perftools (0.93-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Fri, 17 Aug 2007 12:32:56 -0700\n\ngoogle-perftools (0.92-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 17 Jul 2007 22:26:27 -0700\n\ngoogle-perftools (0.91-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Wed, 18 Apr 2007 16:43:55 -0700\n\ngoogle-perftools (0.90-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Fri, 13 Apr 2007 14:50:51 -0700\n\ngoogle-perftools (0.8-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Wed, 14 Jun 2006 15:11:14 -0700\n\ngoogle-perftools (0.7-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Thu, 13 Apr 2006 20:59:09 -0700\n\ngoogle-perftools (0.6-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Fri, 27 Jan 2006 14:04:27 -0800\n\ngoogle-perftools (0.5-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Mon Nov 14 17:28:59 2005\n\ngoogle-perftools (0.4-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Wed, 26 Oct 2005 15:19:16 -0700\n\ngoogle-perftools (0.3-1) unstable; urgency=low\n\n  * New upstream release.\n  \n -- Google Inc. <opensource@google.com>  Fri, 24 Jun 2005 18:02:26 -0700\n\ngoogle-perftools (0.2-1) unstable; urgency=low\n\n  * New upstream release.\n\n -- Google Inc. <opensource@google.com>  Tue, 31 May 2005 08:14:38 -0700\n\ngoogle-perftools (0.1-1) unstable; urgency=low\n\n  * Initial release.\n    The google-perftools package contains some utilities to improve\n    and analyze the performance of C++ programs.  This includes an\n    optimized thread-caching malloc() and cpu and heap profiling\n    utilities.\n\n -- Google Inc. <opensource@google.com>  Fri, 11 Mar 2005 08:07:33 -0800\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/compat",
    "content": "4\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/control",
    "content": "Source: google-perftools\nPriority: optional\nMaintainer: Google Inc. <google-perftools@googlegroups.com>\nBuild-Depends: debhelper (>= 4.0.0), binutils\nStandards-Version: 3.6.1\n\nPackage: libgoogle-perftools-dev\nSection: libdevel\nArchitecture: any\nDepends: libgoogle-perftools0 (= ${Source-Version})\nDescription: libraries for CPU and heap analysis, plus an efficient thread-caching malloc\n The google-perftools package contains some utilities to improve and\n analyze the performance of C++ programs.  This includes an optimized\n thread-caching malloc() and cpu and heap profiling utilities.  The\n devel package contains static and debug libraries and header files\n for developing applications that use the google-perftools package.\n\nPackage: libgoogle-perftools0\nSection: libs\nArchitecture: any\nDepends: ${shlibs:Depends}\nDescription: libraries for CPU and heap analysis, plus an efficient thread-caching malloc\n The google-perftools package contains some utilities to improve and\n analyze the performance of C++ programs.  This includes an optimized\n thread-caching malloc() and cpu and heap profiling utilities.\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/copyright",
    "content": "This package was debianized by Google Inc. <opensource@google.com> on\n15 February 2005.\n\nIt was downloaded from http://code.google.com/\n\nUpstream Author: opensource@google.com\n\nCopyright (c) 2005, Google Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n    * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/docs",
    "content": "AUTHORS\nCOPYING\nChangeLog\nINSTALL\nNEWS\nREADME\nTODO\ndoc/cpuprofile.html\ndoc/cpuprofile-fileformat.html\ndoc/designstyle.css\ndoc/heap-example1.png\ndoc/heap_checker.html\ndoc/heapprofile.html\ndoc/index.html\ndoc/overview.gif\ndoc/pageheap.gif\ndoc/pprof-test-big.gif\ndoc/pprof-test.gif\ndoc/pprof-vsnprintf-big.gif\ndoc/pprof-vsnprintf.gif\ndoc/pprof.1\ndoc/pprof_remote_servers.html\ndoc/spanmap.gif\ndoc/t-test1.times.txt\ndoc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.128.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.256.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.512.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.64.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png\ndoc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png\ndoc/tcmalloc-opspersec.vs.size.1.threads.png\ndoc/tcmalloc-opspersec.vs.size.12.threads.png\ndoc/tcmalloc-opspersec.vs.size.16.threads.png\ndoc/tcmalloc-opspersec.vs.size.2.threads.png\ndoc/tcmalloc-opspersec.vs.size.20.threads.png\ndoc/tcmalloc-opspersec.vs.size.3.threads.png\ndoc/tcmalloc-opspersec.vs.size.4.threads.png\ndoc/tcmalloc-opspersec.vs.size.5.threads.png\ndoc/tcmalloc-opspersec.vs.size.8.threads.png\ndoc/tcmalloc.html\ndoc/threadheap.gif\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/libgoogle-perftools-dev.dirs",
    "content": "usr/lib\nusr/lib/pkgconfig\nusr/include\nusr/include/google\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/libgoogle-perftools-dev.install",
    "content": "usr/include/google/*\nusr/lib/lib*.so\nusr/lib/lib*.a\nusr/lib/*.la\nusr/lib/pkgconfig/*.pc\ndebian/tmp/usr/include/google/*\ndebian/tmp/usr/lib/lib*.so\ndebian/tmp/usr/lib/lib*.a\ndebian/tmp/usr/lib/*.la\ndebian/tmp/usr/lib/pkgconfig/*.pc\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/libgoogle-perftools0.dirs",
    "content": "usr/lib\nusr/bin\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/libgoogle-perftools0.install",
    "content": "usr/lib/lib*.so.*\nusr/bin/pprof*\ndebian/tmp/usr/lib/lib*.so.*\ndebian/tmp/usr/bin/pprof*\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/libgoogle-perftools0.manpages",
    "content": "doc/pprof.1\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb/rules",
    "content": "#!/usr/bin/make -f\n# -*- makefile -*-\n# Sample debian/rules that uses debhelper.\n# This file was originally written by Joey Hess and Craig Small.\n# As a special exception, when this file is copied by dh-make into a\n# dh-make output file, you may use that output file without restriction.\n# This special exception was added by Craig Small in version 0.37 of dh-make.\n\n# Uncomment this to turn on verbose mode.\n#export DH_VERBOSE=1\n\n\n# These are used for cross-compiling and for saving the configure script\n# from having to guess our platform (since we know it already)\nDEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)\nDEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)\n\n\nCFLAGS = -Wall -g\n\nifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))\n\tCFLAGS += -O0\nelse\n\tCFLAGS += -O2\nendif\nifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))\n\tINSTALL_PROGRAM += -s\nendif\n\n# shared library versions, option 1\n#version=2.0.5\n#major=2\n# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so\nversion=`ls src/.libs/lib*.so.* | \\\n awk '{if (match($$0,/[0-9]+\\.[0-9]+\\.[0-9]+$$/)) print substr($$0,RSTART)}'`\nmajor=`ls src/.libs/lib*.so.* | \\\n awk '{if (match($$0,/\\.so\\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`\n\nconfig.status: configure\n\tdh_testdir\n\t# Add here commands to configure the package.\n\tCFLAGS=\"$(CFLAGS)\" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\\$${prefix}/share/man --infodir=\\$${prefix}/share/info\n\n\nbuild: build-stamp\nbuild-stamp:  config.status\n\tdh_testdir\n\n\t# Add here commands to compile the package.\n\t$(MAKE)\n\n\ttouch build-stamp\n\nclean:\n\tdh_testdir\n\tdh_testroot\n\trm -f build-stamp \n\n\t# Add here commands to clean up after the build process.\n\t-$(MAKE) distclean\nifneq \"$(wildcard /usr/share/misc/config.sub)\" \"\"\n\tcp -f /usr/share/misc/config.sub config.sub\nendif\nifneq \"$(wildcard /usr/share/misc/config.guess)\" \"\"\n\tcp -f /usr/share/misc/config.guess config.guess\nendif\n\n\n\tdh_clean \n\ninstall: build\n\tdh_testdir\n\tdh_testroot\n\tdh_clean -k \n\tdh_installdirs\n\n\t# Add here commands to install the package into debian/tmp\n\t$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp\n\n\n# Build architecture-independent files here.\nbinary-indep: build install\n# We have nothing to do by default.\n\n# Build architecture-dependent files here.\nbinary-arch: build install\n\tdh_testdir\n\tdh_testroot\n\tdh_installchangelogs ChangeLog\n\tdh_installdocs\n\tdh_installexamples\n\tdh_install --sourcedir=debian/tmp\n#\tdh_installmenu\n#\tdh_installdebconf\t\n#\tdh_installlogrotate\n#\tdh_installemacsen\n#\tdh_installpam\n#\tdh_installmime\n#\tdh_installinit\n#\tdh_installcron\n#\tdh_installinfo\n\tdh_installman\n\tdh_link\n\tdh_strip\n\tdh_compress\n\tdh_fixperms\n#\tdh_perl\n#\tdh_python\n\tdh_makeshlibs\n\tdh_installdeb\n\tdh_shlibdeps\n\tdh_gencontrol\n\tdh_md5sums\n\tdh_builddeb\n\nbinary: binary-indep binary-arch\n.PHONY: build clean binary-indep binary-arch binary install \n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/deb.sh",
    "content": "#!/bin/bash -e\n\n# This takes one commandline argument, the name of the package.  If no\n# name is given, then we'll end up just using the name associated with\n# an arbitrary .tar.gz file in the rootdir.  That's fine: there's probably\n# only one.\n#\n# Run this from the 'packages' directory, just under rootdir\n\n## Set LIB to lib if exporting a library, empty-string else\nLIB=\n#LIB=lib\n\nPACKAGE=\"$1\"\nVERSION=\"$2\"\n\n# We can only build Debian packages, if the Debian build tools are installed\nif [ \\! -x /usr/bin/debuild ]; then\n  echo \"Cannot find /usr/bin/debuild. Not building Debian packages.\" 1>&2\n  exit 0\nfi\n\n# Double-check we're in the packages directory, just under rootdir\nif [ \\! -r ../Makefile -a \\! -r ../INSTALL ]; then\n  echo \"Must run $0 in the 'packages' directory, under the root directory.\" 1>&2\n  echo \"Also, you must run \\\"make dist\\\" before running this script.\" 1>&2\n  exit 0\nfi\n\n# Find the top directory for this package\ntopdir=\"${PWD%/*}\"\n\n# Find the tar archive built by \"make dist\"\narchive=\"${PACKAGE}-${VERSION}\"\narchive_with_underscore=\"${PACKAGE}_${VERSION}\"\nif [ -z \"${archive}\" ]; then\n  echo \"Cannot find ../$PACKAGE*.tar.gz. Run \\\"make dist\\\" first.\" 1>&2\n  exit 0\nfi\n\n# Create a pristine directory for building the Debian package files\ntrap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM\n\nrm -rf tmp\nmkdir -p tmp\ncd tmp\n\n# Debian has very specific requirements about the naming of build\n# directories, and tar archives. It also wants to write all generated\n# packages to the parent of the source directory. We accommodate these\n# requirements by building directly from the tar file.\nln -s \"${topdir}/${archive}.tar.gz\" \"${LIB}${archive}.orig.tar.gz\"\n# Some version of debuilder want foo.orig.tar.gz with _ between versions.\nln -s \"${topdir}/${archive}.tar.gz\" \"${LIB}${archive_with_underscore}.orig.tar.gz\"\ntar zfx \"${LIB}${archive}.orig.tar.gz\"\n[ -n \"${LIB}\" ] && mv \"${archive}\" \"${LIB}${archive}\"\ncd \"${LIB}${archive}\"\n# This is one of those 'specific requirements': where the deb control files live\ncp -a \"packages/deb\" \"debian\"\n\n# Now, we can call Debian's standard build tool\ndebuild -uc -us\ncd ../..                            # get back to the original top-level dir\n\n# We'll put the result in a subdirectory that's named after the OS version\n# we've made this .deb file for.\ndestdir=\"debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)\"\n\nrm -rf \"$destdir\"\nmkdir -p \"$destdir\"\nmv $(find tmp -mindepth 1 -maxdepth 1 -type f) \"$destdir\"\n\necho\necho \"The Debian package files are located in $PWD/$destdir\"\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/rpm/rpm.spec",
    "content": "%define\tRELEASE\t1\n%define rel     %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}\n%define\tprefix\t/usr\n\nName: %NAME\nSummary: Performance tools for C++\nVersion: %VERSION\nRelease: %rel\nGroup: Development/Libraries\nURL: http://code.google.com/p/google-perftools/\nLicense: BSD\nVendor: Google\nPackager: Google <google-perftools@googlegroups.com>\nSource: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz\nDistribution: Redhat 7 and above.\nBuildroot: %{_tmppath}/%{name}-root\nPrefix: %prefix\n\n%description\nThe %name packages contains some utilities to improve and analyze the\nperformance of C++ programs.  This includes an optimized thread-caching\nmalloc() and cpu and heap profiling utilities.\n\n%package devel\nSummary: Performance tools for C++\nGroup: Development/Libraries\nRequires: %{NAME} = %{VERSION}\n\n%description devel\nThe %name-devel package contains static and debug libraries and header\nfiles for developing applications that use the %name package.\n\n%changelog\n\t* Mon Apr 20 2009  <opensource@google.com>\n\t- Change build rule to use a configure line more like '%configure'\n\t- Change install to use DESTDIR instead of prefix for configure\n\t- Use wildcards for doc/ and lib/ directories\n\n\t* Fri Mar 11 2005  <opensource@google.com>\n\t- First draft\n\n%prep\n%setup\n\n%build\n# I can't use '% configure', because it defines -m32 which breaks some\n# of the low-level atomicops files in this package.  But I do take\n# as much from % configure (in /usr/lib/rpm/macros) as I can.\n./configure --prefix=%{_prefix} --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} --datadir=%{_datadir} --includedir=%{_includedir} --libdir=%{_libdir} --libexecdir=%{_libexecdir} --localstatedir=%{_localstatedir} --sharedstatedir=%{_sharedstatedir} --mandir=%{_mandir} --infodir=%{_infodir}\nmake\n\n%install\nrm -rf $RPM_BUILD_ROOT\nmake DESTDIR=$RPM_BUILD_ROOT install\n\n%clean\nrm -rf $RPM_BUILD_ROOT\n\n%files\n%defattr(-,root,root)\n\n%docdir %{prefix}/share/doc/%{NAME}-%{VERSION}\n%{prefix}/share/doc/%{NAME}-%{VERSION}/*\n\n%{_libdir}/*.so.*\n%{_bindir}/pprof\n%{_mandir}/man1/pprof.1*\n\n%files devel\n%defattr(-,root,root)\n\n%{_includedir}/google\n%{_libdir}/*.a\n%{_libdir}/*.la\n%{_libdir}/*.so\n%{_libdir}/pkgconfig/*.pc\n"
  },
  {
    "path": "distro/google-perftools-1.7/packages/rpm.sh",
    "content": "#!/bin/sh -e\n\n# Run this from the 'packages' directory, just under rootdir\n\n# We can only build rpm packages, if the rpm build tools are installed\nif [ \\! -x /usr/bin/rpmbuild ]\nthen\n  echo \"Cannot find /usr/bin/rpmbuild. Not building an rpm.\" 1>&2\n  exit 0\nfi\n\n# Check the commandline flags\nPACKAGE=\"$1\"\nVERSION=\"$2\"\nfullname=\"${PACKAGE}-${VERSION}\"\narchive=../$fullname.tar.gz\n\nif [ -z \"$1\" -o -z \"$2\" ]\nthen\n  echo \"Usage: $0 <package name> <package version>\" 1>&2\n  exit 0\nfi\n\n# Double-check we're in the packages directory, just under rootdir\nif [ \\! -r ../Makefile -a \\! -r ../INSTALL ]\nthen\n  echo \"Must run $0 in the 'packages' directory, under the root directory.\" 1>&2\n  echo \"Also, you must run \\\"make dist\\\" before running this script.\" 1>&2\n  exit 0\nfi\n\nif [ \\! -r \"$archive\" ]\nthen\n  echo \"Cannot find $archive. Run \\\"make dist\\\" first.\" 1>&2\n  exit 0\nfi\n\n# Create the directory where the input lives, and where the output should live\nRPM_SOURCE_DIR=\"/tmp/rpmsource-$fullname\"\nRPM_BUILD_DIR=\"/tmp/rpmbuild-$fullname\"\n\ntrap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM\n\nrm -rf \"$RPM_SOURCE_DIR\" \"$RPM_BUILD_DIR\"\nmkdir \"$RPM_SOURCE_DIR\"\nmkdir \"$RPM_BUILD_DIR\"\n\ncp \"$archive\" \"$RPM_SOURCE_DIR\"\n\n# rpmbuild -- as far as I can tell -- asks the OS what CPU it has.\n# This may differ from what kind of binaries gcc produces.  dpkg\n# does a better job of this, so if we can run 'dpkg --print-architecture'\n# to get the build CPU, we use that in preference of the rpmbuild\n# default.\ntarget=`dpkg --print-architecture 2>/dev/null`   # \"\" if dpkg isn't found\nif [ -n \"$target\" ]\nthen\n   target=\" --target $target\"\nfi\n\nrpmbuild -bb rpm/rpm.spec $target \\\n  --define \"NAME $PACKAGE\" \\\n  --define \"VERSION $VERSION\" \\\n  --define \"_sourcedir $RPM_SOURCE_DIR\" \\\n  --define \"_builddir $RPM_BUILD_DIR\" \\\n  --define \"_rpmdir $RPM_SOURCE_DIR\"\n\n# We put the output in a directory based on what system we've built for\ndestdir=rpm-unknown\nif [ -r /etc/issue ]\nthen\n   grep \"Red Hat.*release 7\" /etc/issue >/dev/null 2>&1 && destdir=rh7\n   grep \"Red Hat.*release 8\" /etc/issue >/dev/null 2>&1 && destdir=rh8\n   grep \"Red Hat.*release 9\" /etc/issue >/dev/null 2>&1 && destdir=rh9\n   grep \"Fedora Core.*release 1\" /etc/issue >/dev/null 2>&1 && destdir=fc1\n   grep \"Fedora Core.*release 2\" /etc/issue >/dev/null 2>&1 && destdir=fc2\n   grep \"Fedora Core.*release 3\" /etc/issue >/dev/null 2>&1 && destdir=fc3\nfi\n\nrm -rf \"$destdir\"\nmkdir -p \"$destdir\"\n# We want to get not only the main package but devel etc, hence the middle *\nmv \"$RPM_SOURCE_DIR\"/*/\"${PACKAGE}\"-*\"${VERSION}\"*.rpm \"$destdir\"\n\necho\necho \"The rpm package file(s) are located in $PWD/$destdir\"\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/addressmap-inl.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// A fast map from addresses to values.  Assumes that addresses are\n// clustered.  The main use is intended to be for heap-profiling.\n// May be too memory-hungry for other uses.\n//\n// We use a user-defined allocator/de-allocator so that we can use\n// this data structure during heap-profiling.\n//\n// IMPLEMENTATION DETAIL:\n//\n// Some default definitions/parameters:\n//  * Block      -- aligned 128-byte region of the address space\n//  * Cluster    -- aligned 1-MB region of the address space\n//  * Block-ID   -- block-number within a cluster\n//  * Cluster-ID -- Starting address of cluster divided by cluster size\n//\n// We use a three-level map to represent the state:\n//  1. A hash-table maps from a cluster-ID to the data for that cluster.\n//  2. For each non-empty cluster we keep an array indexed by\n//     block-ID tht points to the first entry in the linked-list\n//     for the block.\n//  3. At the bottom, we keep a singly-linked list of all\n//     entries in a block (for non-empty blocks).\n//\n//    hash table\n//  +-------------+\n//  | id->cluster |---> ...\n//  |     ...     |\n//  | id->cluster |--->  Cluster\n//  +-------------+     +-------+    Data for one block\n//                      |  nil  |   +------------------------------------+\n//                      |   ----+---|->[addr/value]-->[addr/value]-->... |\n//                      |  nil  |   +------------------------------------+\n//                      |   ----+--> ...\n//                      |  nil  |\n//                      |  ...  |\n//                      +-------+\n//\n// Note that we require zero-bytes of overhead for completely empty\n// clusters.  The minimum space requirement for a cluster is the size\n// of the hash-table entry plus a pointer value for each block in\n// the cluster.  Empty blocks impose no extra space requirement.\n//\n// The cost of a lookup is:\n//      a. A hash-table lookup to find the cluster\n//      b. An array access in the cluster structure\n//      c. A traversal over the linked-list for a block\n\n#ifndef BASE_ADDRESSMAP_INL_H_\n#define BASE_ADDRESSMAP_INL_H_\n\n#include \"config.h\"\n#include <stddef.h>\n#include <string.h>\n#if defined HAVE_STDINT_H\n#include <stdint.h>             // to get uint16_t (ISO naming madness)\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>           // another place uint16_t might be defined\n#else\n#include <sys/types.h>          // our last best hope\n#endif\n\n// This class is thread-unsafe -- that is, instances of this class can\n// not be accessed concurrently by multiple threads -- because the\n// callback function for Iterate() may mutate contained values. If the\n// callback functions you pass do not mutate their Value* argument,\n// AddressMap can be treated as thread-compatible -- that is, it's\n// safe for multiple threads to call \"const\" methods on this class,\n// but not safe for one thread to call const methods on this class\n// while another thread is calling non-const methods on the class.\ntemplate <class Value>\nclass AddressMap {\n public:\n  typedef void* (*Allocator)(size_t size);\n  typedef void  (*DeAllocator)(void* ptr);\n  typedef const void* Key;\n\n  // Create an AddressMap that uses the specified allocator/deallocator.\n  // The allocator/deallocator should behave like malloc/free.\n  // For instance, the allocator does not need to return initialized memory.\n  AddressMap(Allocator alloc, DeAllocator dealloc);\n  ~AddressMap();\n\n  // If the map contains an entry for \"key\", return it. Else return NULL.\n  inline const Value* Find(Key key) const;\n  inline Value* FindMutable(Key key);\n\n  // Insert <key,value> into the map.  Any old value associated\n  // with key is forgotten.\n  void Insert(Key key, Value value);\n\n  // Remove any entry for key in the map.  If an entry was found\n  // and removed, stores the associated value in \"*removed_value\"\n  // and returns true.  Else returns false.\n  bool FindAndRemove(Key key, Value* removed_value);\n\n  // Similar to Find but we assume that keys are addresses of non-overlapping\n  // memory ranges whose sizes are given by size_func.\n  // If the map contains a range into which \"key\" points\n  // (at its start or inside of it, but not at the end),\n  // return the address of the associated value\n  // and store its key in \"*res_key\".\n  // Else return NULL.\n  // max_size specifies largest range size possibly in existence now.\n  typedef size_t (*ValueSizeFunc)(const Value& v);\n  const Value* FindInside(ValueSizeFunc size_func, size_t max_size,\n                          Key key, Key* res_key);\n\n  // Iterate over the address map calling 'callback'\n  // for all stored key-value pairs and passing 'arg' to it.\n  // We don't use full Closure/Callback machinery not to add\n  // unnecessary dependencies to this class with low-level uses.\n  template<class Type>\n  inline void Iterate(void (*callback)(Key, Value*, Type), Type arg) const;\n\n private:\n  typedef uintptr_t Number;\n\n  // The implementation assumes that addresses inserted into the map\n  // will be clustered.  We take advantage of this fact by splitting\n  // up the address-space into blocks and using a linked-list entry\n  // for each block.\n\n  // Size of each block.  There is one linked-list for each block, so\n  // do not make the block-size too big.  Oterwise, a lot of time\n  // will be spent traversing linked lists.\n  static const int kBlockBits = 7;\n  static const int kBlockSize = 1 << kBlockBits;\n\n  // Entry kept in per-block linked-list\n  struct Entry {\n    Entry* next;\n    Key    key;\n    Value  value;\n  };\n\n  // We further group a sequence of consecutive blocks into a cluster.\n  // The data for a cluster is represented as a dense array of\n  // linked-lists, one list per contained block.\n  static const int kClusterBits = 13;\n  static const Number kClusterSize = 1 << (kBlockBits + kClusterBits);\n  static const int kClusterBlocks = 1 << kClusterBits;\n\n  // We use a simple chaining hash-table to represent the clusters.\n  struct Cluster {\n    Cluster* next;                      // Next cluster in hash table chain\n    Number   id;                        // Cluster ID\n    Entry*   blocks[kClusterBlocks];    // Per-block linked-lists\n  };\n\n  // Number of hash-table entries.  With the block-size/cluster-size\n  // defined above, each cluster covers 1 MB, so an 4K entry\n  // hash-table will give an average hash-chain length of 1 for 4GB of\n  // in-use memory.\n  static const int kHashBits = 12;\n  static const int kHashSize = 1 << 12;\n\n  // Number of entry objects allocated at a time\n  static const int ALLOC_COUNT = 64;\n\n  Cluster**     hashtable_;              // The hash-table\n  Entry*        free_;                   // Free list of unused Entry objects\n\n  // Multiplicative hash function:\n  // The value \"kHashMultiplier\" is the bottom 32 bits of\n  //    int((sqrt(5)-1)/2 * 2^32)\n  // This is a good multiplier as suggested in CLR, Knuth.  The hash\n  // value is taken to be the top \"k\" bits of the bottom 32 bits\n  // of the muliplied value.\n  static const uint32_t kHashMultiplier = 2654435769u;\n  static int HashInt(Number x) {\n    // Multiply by a constant and take the top bits of the result.\n    const uint32_t m = static_cast<uint32_t>(x) * kHashMultiplier;\n    return static_cast<int>(m >> (32 - kHashBits));\n  }\n\n  // Find cluster object for specified address.  If not found\n  // and \"create\" is true, create the object.  If not found\n  // and \"create\" is false, return NULL.\n  //\n  // This method is bitwise-const if create is false.\n  Cluster* FindCluster(Number address, bool create) {\n    // Look in hashtable\n    const Number cluster_id = address >> (kBlockBits + kClusterBits);\n    const int h = HashInt(cluster_id);\n    for (Cluster* c = hashtable_[h]; c != NULL; c = c->next) {\n      if (c->id == cluster_id) {\n        return c;\n      }\n    }\n\n    // Create cluster if necessary\n    if (create) {\n      Cluster* c = New<Cluster>(1);\n      c->id = cluster_id;\n      c->next = hashtable_[h];\n      hashtable_[h] = c;\n      return c;\n    }\n    return NULL;\n  }\n\n  // Return the block ID for an address within its cluster\n  static int BlockID(Number address) {\n    return (address >> kBlockBits) & (kClusterBlocks - 1);\n  }\n\n  //--------------------------------------------------------------\n  // Memory management -- we keep all objects we allocate linked\n  // together in a singly linked list so we can get rid of them\n  // when we are all done.  Furthermore, we allow the client to\n  // pass in custom memory allocator/deallocator routines.\n  //--------------------------------------------------------------\n  struct Object {\n    Object* next;\n    // The real data starts here\n  };\n\n  Allocator     alloc_;                 // The allocator\n  DeAllocator   dealloc_;               // The deallocator\n  Object*       allocated_;             // List of allocated objects\n\n  // Allocates a zeroed array of T with length \"num\".  Also inserts\n  // the allocated block into a linked list so it can be deallocated\n  // when we are all done.\n  template <class T> T* New(int num) {\n    void* ptr = (*alloc_)(sizeof(Object) + num*sizeof(T));\n    memset(ptr, 0, sizeof(Object) + num*sizeof(T));\n    Object* obj = reinterpret_cast<Object*>(ptr);\n    obj->next = allocated_;\n    allocated_ = obj;\n    return reinterpret_cast<T*>(reinterpret_cast<Object*>(ptr) + 1);\n  }\n};\n\n// More implementation details follow:\n\ntemplate <class Value>\nAddressMap<Value>::AddressMap(Allocator alloc, DeAllocator dealloc)\n  : free_(NULL),\n    alloc_(alloc),\n    dealloc_(dealloc),\n    allocated_(NULL) {\n  hashtable_ = New<Cluster*>(kHashSize);\n}\n\ntemplate <class Value>\nAddressMap<Value>::~AddressMap() {\n  // De-allocate all of the objects we allocated\n  for (Object* obj = allocated_; obj != NULL; /**/) {\n    Object* next = obj->next;\n    (*dealloc_)(obj);\n    obj = next;\n  }\n}\n\ntemplate <class Value>\ninline const Value* AddressMap<Value>::Find(Key key) const {\n  return const_cast<AddressMap*>(this)->FindMutable(key);\n}\n\ntemplate <class Value>\ninline Value* AddressMap<Value>::FindMutable(Key key) {\n  const Number num = reinterpret_cast<Number>(key);\n  const Cluster* const c = FindCluster(num, false/*do not create*/);\n  if (c != NULL) {\n    for (Entry* e = c->blocks[BlockID(num)]; e != NULL; e = e->next) {\n      if (e->key == key) {\n        return &e->value;\n      }\n    }\n  }\n  return NULL;\n}\n\ntemplate <class Value>\nvoid AddressMap<Value>::Insert(Key key, Value value) {\n  const Number num = reinterpret_cast<Number>(key);\n  Cluster* const c = FindCluster(num, true/*create*/);\n\n  // Look in linked-list for this block\n  const int block = BlockID(num);\n  for (Entry* e = c->blocks[block]; e != NULL; e = e->next) {\n    if (e->key == key) {\n      e->value = value;\n      return;\n    }\n  }\n\n  // Create entry\n  if (free_ == NULL) {\n    // Allocate a new batch of entries and add to free-list\n    Entry* array = New<Entry>(ALLOC_COUNT);\n    for (int i = 0; i < ALLOC_COUNT-1; i++) {\n      array[i].next = &array[i+1];\n    }\n    array[ALLOC_COUNT-1].next = free_;\n    free_ = &array[0];\n  }\n  Entry* e = free_;\n  free_ = e->next;\n  e->key = key;\n  e->value = value;\n  e->next = c->blocks[block];\n  c->blocks[block] = e;\n}\n\ntemplate <class Value>\nbool AddressMap<Value>::FindAndRemove(Key key, Value* removed_value) {\n  const Number num = reinterpret_cast<Number>(key);\n  Cluster* const c = FindCluster(num, false/*do not create*/);\n  if (c != NULL) {\n    for (Entry** p = &c->blocks[BlockID(num)]; *p != NULL; p = &(*p)->next) {\n      Entry* e = *p;\n      if (e->key == key) {\n        *removed_value = e->value;\n        *p = e->next;         // Remove e from linked-list\n        e->next = free_;      // Add e to free-list\n        free_ = e;\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\ntemplate <class Value>\nconst Value* AddressMap<Value>::FindInside(ValueSizeFunc size_func,\n                                           size_t max_size,\n                                           Key key,\n                                           Key* res_key) {\n  const Number key_num = reinterpret_cast<Number>(key);\n  Number num = key_num;  // we'll move this to move back through the clusters\n  while (1) {\n    const Cluster* c = FindCluster(num, false/*do not create*/);\n    if (c != NULL) {\n      while (1) {\n        const int block = BlockID(num);\n        bool had_smaller_key = false;\n        for (const Entry* e = c->blocks[block]; e != NULL; e = e->next) {\n          const Number e_num = reinterpret_cast<Number>(e->key);\n          if (e_num <= key_num) {\n            if (e_num == key_num  ||  // to handle 0-sized ranges\n                key_num < e_num + (*size_func)(e->value)) {\n              *res_key = e->key;\n              return &e->value;\n            }\n            had_smaller_key = true;\n          }\n        }\n        if (had_smaller_key) return NULL;  // got a range before 'key'\n                                           // and it did not contain 'key'\n        if (block == 0) break;\n        // try address-wise previous block\n        num |= kBlockSize - 1;  // start at the last addr of prev block\n        num -= kBlockSize;\n        if (key_num - num > max_size) return NULL;\n      }\n    }\n    if (num < kClusterSize) return NULL;  // first cluster\n    // go to address-wise previous cluster to try\n    num |= kClusterSize - 1;  // start at the last block of previous cluster\n    num -= kClusterSize;\n    if (key_num - num > max_size) return NULL;\n      // Having max_size to limit the search is crucial: else\n      // we have to traverse a lot of empty clusters (or blocks).\n      // We can avoid needing max_size if we put clusters into\n      // a search tree, but performance suffers considerably\n      // if we use this approach by using stl::set.\n  }\n}\n\ntemplate <class Value>\ntemplate <class Type>\ninline void AddressMap<Value>::Iterate(void (*callback)(Key, Value*, Type),\n                                       Type arg) const {\n  // We could optimize this by traversing only non-empty clusters and/or blocks\n  // but it does not speed up heap-checker noticeably.\n  for (int h = 0; h < kHashSize; ++h) {\n    for (const Cluster* c = hashtable_[h]; c != NULL; c = c->next) {\n      for (int b = 0; b < kClusterBlocks; ++b) {\n        for (Entry* e = c->blocks[b]; e != NULL; e = e->next) {\n          callback(e->key, &e->value, arg);\n        }\n      }\n    }\n  }\n}\n\n#endif  // BASE_ADDRESSMAP_INL_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops-internals-arm-gcc.h",
    "content": "/* Copyright (c) 2010, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Lei Zhang, Sasha Levitskiy\n */\n\n// This file is an internal atomic implementation, use base/atomicops.h instead.\n//\n// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.\n\n#ifndef BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_\n#define BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_\n\n#include <stdio.h>\n#include \"base/basictypes.h\"  // For COMPILE_ASSERT\n\ntypedef int32_t Atomic32;\n\nnamespace base {\nnamespace subtle {\n\ntypedef int64_t Atomic64;\n\n// 0xffff0fc0 is the hard coded address of a function provided by\n// the kernel which implements an atomic compare-exchange. On older\n// ARM architecture revisions (pre-v6) this may be implemented using\n// a syscall. This address is stable, and in active use (hard coded)\n// by at least glibc-2.7 and the Android C library.\n// pLinuxKernelCmpxchg has both acquire and release barrier sematincs.\ntypedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,\n                                           Atomic32 new_value,\n                                           volatile Atomic32* ptr);\nLinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =\n    (LinuxKernelCmpxchgFunc) 0xffff0fc0;\n\ntypedef void (*LinuxKernelMemoryBarrierFunc)(void);\nLinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =\n    (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;\n\n\ninline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,\n                                         Atomic32 old_value,\n                                         Atomic32 new_value) {\n  Atomic32 prev_value = *ptr;\n  do {\n    if (!pLinuxKernelCmpxchg(old_value, new_value,\n                             const_cast<Atomic32*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,\n                                         Atomic32 new_value) {\n  Atomic32 old_value;\n  do {\n    old_value = *ptr;\n  } while (pLinuxKernelCmpxchg(old_value, new_value,\n                               const_cast<Atomic32*>(ptr)));\n  return old_value;\n}\n\ninline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,\n                                        Atomic32 increment) {\n  for (;;) {\n    // Atomic exchange the old value with an incremented one.\n    Atomic32 old_value = *ptr;\n    Atomic32 new_value = old_value + increment;\n    if (pLinuxKernelCmpxchg(old_value, new_value,\n                            const_cast<Atomic32*>(ptr)) == 0) {\n      // The exchange took place as expected.\n      return new_value;\n    }\n    // Otherwise, *ptr changed mid-loop and we need to retry.\n  }\n}\n\ninline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,\n                                          Atomic32 increment) {\n  return Barrier_AtomicIncrement(ptr, increment);\n}\n\ninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value;\n}\n\ninline void MemoryBarrier() {\n  pLinuxKernelMemoryBarrier();\n}\n\ninline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value;\n  MemoryBarrier();\n}\n\ninline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {\n  MemoryBarrier();\n  *ptr = value;\n}\n\ninline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {\n  return *ptr;\n}\n\ninline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {\n  Atomic32 value = *ptr;\n  MemoryBarrier();\n  return value;\n}\n\ninline Atomic32 Release_Load(volatile const Atomic32* ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n\n// 64-bit versions are not implemented yet.\n\ninline void NotImplementedFatalError(const char *function_name) {\n  fprintf(stderr, \"64-bit %s() not implemented on this platform\\n\",\n          function_name);\n  abort();\n}\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,\n                                         Atomic64 old_value,\n                                         Atomic64 new_value) {\n  NotImplementedFatalError(\"NoBarrier_CompareAndSwap\");\n  return 0;\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,\n                                         Atomic64 new_value) {\n  NotImplementedFatalError(\"NoBarrier_AtomicExchange\");\n  return 0;\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,\n                                          Atomic64 increment) {\n  NotImplementedFatalError(\"NoBarrier_AtomicIncrement\");\n  return 0;\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,\n                                        Atomic64 increment) {\n  NotImplementedFatalError(\"Barrier_AtomicIncrement\");\n  return 0;\n}\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NotImplementedFatalError(\"NoBarrier_Store\");\n}\n\ninline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NoBarrier_AtomicExchange(ptr, value);\n              // acts as a barrier in this implementation\n}\n\ninline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NotImplementedFatalError(\"Release_Store\");\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n  NotImplementedFatalError(\"NoBarrier_Load\");\n  return 0;\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {\n  Atomic64 value = NoBarrier_Load(ptr);\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64* ptr) {\n  MemoryBarrier();\n  return NoBarrier_Load(ptr);\n}\n\ninline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\n}  // namespace base::subtle\n}  // namespace base\n\n#endif  // BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops-internals-linuxppc.h",
    "content": "/* Copyright (c) 2008, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n */\n\n// Implementation of atomic operations for ppc-linux.  This file should not\n// be included directly.  Clients should instead include\n// \"base/atomicops.h\".\n\n#ifndef BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_\n#define BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_\n\ntypedef int32_t Atomic32;\n\n#ifdef __PPC64__\n#define BASE_HAS_ATOMIC64 1\n#endif\n\nnamespace base {\nnamespace subtle {\n\nstatic inline void _sync(void) {\n  __asm__ __volatile__(\"sync\": : : \"memory\");\n}\n\nstatic inline void _lwsync(void) {\n  // gcc defines __NO_LWSYNC__ when appropriate; see\n  //    http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01238.html\n#ifdef __NO_LWSYNC__\n  __asm__ __volatile__(\"msync\": : : \"memory\");\n#else\n  __asm__ __volatile__(\"lwsync\": : : \"memory\");\n#endif\n}\n\nstatic inline void _isync(void) {\n  __asm__ __volatile__(\"isync\": : : \"memory\");\n}\n\nstatic inline Atomic32 OSAtomicAdd32(Atomic32 amount, Atomic32 *value) {\n  Atomic32 t;\n  __asm__ __volatile__(\n\"1:\t\tlwarx   %0,0,%3\\n\\\n\t\tadd     %0,%2,%0\\n\\\n\t\tstwcx.  %0,0,%3 \\n\\\n\t\tbne-    1b\"\n\t\t: \"=&r\" (t), \"+m\" (*value)\n\t\t: \"r\" (amount), \"r\" (value)\n                : \"cc\");\n  return t;\n}\n\nstatic inline Atomic32 OSAtomicAdd32Barrier(Atomic32 amount, Atomic32 *value) {\n  Atomic32 t;\n  _lwsync();\n  t = OSAtomicAdd32(amount, value);\n  // This is based on the code snippet in the architecture manual (Vol\n  // 2, Appendix B).  It's a little tricky: correctness depends on the\n  // fact that the code right before this (in OSAtomicAdd32) has a\n  // conditional branch with a data dependency on the update.\n  // Otherwise, we'd have to use sync.\n  _isync();\n  return t;\n}\n\nstatic inline bool OSAtomicCompareAndSwap32(Atomic32 old_value,\n                                            Atomic32 new_value,\n                                            Atomic32 *value) {\n  Atomic32 prev;\n  __asm__ __volatile__(\n\"1:\t\tlwarx   %0,0,%2\\n\\\n\t\tcmpw    0,%0,%3\\n\\\n\t\tbne-    2f\\n\\\n\t\tstwcx.  %4,0,%2\\n\\\n\t\tbne-    1b\\n\\\n2:\"\n                : \"=&r\" (prev), \"+m\" (*value)\n                : \"r\" (value), \"r\" (old_value), \"r\" (new_value)\n                : \"cc\");\n  return prev == old_value;\n}\n\nstatic inline Atomic32 OSAtomicCompareAndSwap32Acquire(Atomic32 old_value,\n                                                       Atomic32 new_value,\n                                                       Atomic32 *value) {\n  Atomic32 t;\n  t = OSAtomicCompareAndSwap32(old_value, new_value, value);\n  // This is based on the code snippet in the architecture manual (Vol\n  // 2, Appendix B).  It's a little tricky: correctness depends on the\n  // fact that the code right before this (in\n  // OSAtomicCompareAndSwap32) has a conditional branch with a data\n  // dependency on the update.  Otherwise, we'd have to use sync.\n  _isync();\n  return t;\n}\n\nstatic inline Atomic32 OSAtomicCompareAndSwap32Release(Atomic32 old_value,\n                                                       Atomic32 new_value,\n                                                       Atomic32 *value) {\n  _lwsync();\n  return OSAtomicCompareAndSwap32(old_value, new_value, value);\n}\n\ntypedef int64_t Atomic64;\n\ninline void MemoryBarrier() {\n  // This can't be _lwsync(); we need to order the immediately\n  // preceding stores against any load that may follow, but lwsync\n  // doesn't guarantee that.\n  _sync();\n}\n\n// 32-bit Versions.\n\ninline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,\n                                         Atomic32 old_value,\n                                         Atomic32 new_value) {\n  Atomic32 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap32(old_value, new_value,\n                                 const_cast<Atomic32*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,\n                                         Atomic32 new_value) {\n  Atomic32 old_value;\n  do {\n    old_value = *ptr;\n  } while (!OSAtomicCompareAndSwap32(old_value, new_value,\n                                     const_cast<Atomic32*>(ptr)));\n  return old_value;\n}\n\ninline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,\n                                          Atomic32 increment) {\n  return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));\n}\n\ninline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,\n                                        Atomic32 increment) {\n  return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));\n}\n\ninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  Atomic32 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap32Acquire(old_value, new_value,\n                                        const_cast<Atomic32*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  Atomic32 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap32Release(old_value, new_value,\n                                        const_cast<Atomic32*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\n#ifdef __PPC64__\n\n// 64-bit Versions.\n\nstatic inline Atomic64 OSAtomicAdd64(Atomic64 amount, Atomic64 *value) {\n  Atomic64 t;\n  __asm__ __volatile__(\n\"1:\t\tldarx   %0,0,%3\\n\\\n\t\tadd     %0,%2,%0\\n\\\n\t\tstdcx.  %0,0,%3 \\n\\\n\t\tbne-    1b\"\n\t\t: \"=&r\" (t), \"+m\" (*value)\n\t\t: \"r\" (amount), \"r\" (value)\n                : \"cc\");\n  return t;\n}\n\nstatic inline Atomic64 OSAtomicAdd64Barrier(Atomic64 amount, Atomic64 *value) {\n  Atomic64 t;\n  _lwsync();\n  t = OSAtomicAdd64(amount, value);\n  // This is based on the code snippet in the architecture manual (Vol\n  // 2, Appendix B).  It's a little tricky: correctness depends on the\n  // fact that the code right before this (in OSAtomicAdd64) has a\n  // conditional branch with a data dependency on the update.\n  // Otherwise, we'd have to use sync.\n  _isync();\n  return t;\n}\n\nstatic inline bool OSAtomicCompareAndSwap64(Atomic64 old_value,\n                                            Atomic64 new_value,\n                                            Atomic64 *value) {\n  Atomic64 prev;\n  __asm__ __volatile__(\n\"1:\t\tldarx   %0,0,%2\\n\\\n\t\tcmpw    0,%0,%3\\n\\\n\t\tbne-    2f\\n\\\n\t\tstdcx.  %4,0,%2\\n\\\n\t\tbne-    1b\\n\\\n2:\"\n                : \"=&r\" (prev), \"+m\" (*value)\n                : \"r\" (value), \"r\" (old_value), \"r\" (new_value)\n                : \"cc\");\n  return prev == old_value;\n}\n\nstatic inline Atomic64 OSAtomicCompareAndSwap64Acquire(Atomic64 old_value,\n                                                       Atomic64 new_value,\n                                                       Atomic64 *value) {\n  Atomic64 t;\n  t = OSAtomicCompareAndSwap64(old_value, new_value, value);\n  // This is based on the code snippet in the architecture manual (Vol\n  // 2, Appendix B).  It's a little tricky: correctness depends on the\n  // fact that the code right before this (in\n  // OSAtomicCompareAndSwap64) has a conditional branch with a data\n  // dependency on the update.  Otherwise, we'd have to use sync.\n  _isync();\n  return t;\n}\n\nstatic inline Atomic64 OSAtomicCompareAndSwap64Release(Atomic64 old_value,\n                                                       Atomic64 new_value,\n                                                       Atomic64 *value) {\n  _lwsync();\n  return OSAtomicCompareAndSwap64(old_value, new_value, value);\n}\n\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,\n                                         Atomic64 old_value,\n                                         Atomic64 new_value) {\n  Atomic64 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap64(old_value, new_value,\n                                 const_cast<Atomic64*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,\n                                         Atomic64 new_value) {\n  Atomic64 old_value;\n  do {\n    old_value = *ptr;\n  } while (!OSAtomicCompareAndSwap64(old_value, new_value,\n                                     const_cast<Atomic64*>(ptr)));\n  return old_value;\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,\n                                          Atomic64 increment) {\n  return OSAtomicAdd64(increment, const_cast<Atomic64*>(ptr));\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,\n                                        Atomic64 increment) {\n  return OSAtomicAdd64Barrier(increment, const_cast<Atomic64*>(ptr));\n}\n\ninline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  Atomic64 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap64Acquire(old_value, new_value,\n                                        const_cast<Atomic64*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  Atomic64 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap64Release(old_value, new_value,\n                                        const_cast<Atomic64*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\n#endif\n\ninline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {\n  *ptr = value;\n  // This can't be _lwsync(); we need to order the immediately\n  // preceding stores against any load that may follow, but lwsync\n  // doesn't guarantee that.\n  _sync();\n}\n\ninline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {\n  _lwsync();\n  *ptr = value;\n}\n\ninline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {\n  return *ptr;\n}\n\ninline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {\n  Atomic32 value = *ptr;\n  _lwsync();\n  return value;\n}\n\ninline Atomic32 Release_Load(volatile const Atomic32 *ptr) {\n  // This can't be _lwsync(); we need to order the immediately\n  // preceding stores against any load that may follow, but lwsync\n  // doesn't guarantee that.\n  _sync();\n  return *ptr;\n}\n\n#ifdef __PPC64__\n\n// 64-bit Versions.\n\ninline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  *ptr = value;\n  // This can't be _lwsync(); we need to order the immediately\n  // preceding stores against any load that may follow, but lwsync\n  // doesn't guarantee that.\n  _sync();\n}\n\ninline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  _lwsync();\n  *ptr = value;\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {\n  return *ptr;\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {\n  Atomic64 value = *ptr;\n  _lwsync();\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64 *ptr) {\n  // This can't be _lwsync(); we need to order the immediately\n  // preceding stores against any load that may follow, but lwsync\n  // doesn't guarantee that.\n  _sync();\n  return *ptr;\n}\n\n#endif\n\n}   // namespace base::subtle\n}   // namespace base\n\n#endif  // BASE_ATOMICOPS_INTERNALS_LINUXPPC_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops-internals-macosx.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n// Implementation of atomic operations for Mac OS X.  This file should not\n// be included directly.  Clients should instead include\n// \"base/atomicops.h\".\n\n#ifndef BASE_ATOMICOPS_INTERNALS_MACOSX_H_\n#define BASE_ATOMICOPS_INTERNALS_MACOSX_H_\n\ntypedef int32_t Atomic32;\n\n// MacOS uses long for intptr_t, AtomicWord and Atomic32 are always different\n// on the Mac, even when they are the same size.  Similarly, on __ppc64__,\n// AtomicWord and Atomic64 are always different.  Thus, we need explicit\n// casting.\n#ifdef __LP64__\n#define AtomicWordCastType base::subtle::Atomic64\n#else\n#define AtomicWordCastType Atomic32\n#endif\n\n#if defined(__LP64__) || defined(__i386__)\n#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*\n#endif\n\n#include <libkern/OSAtomic.h>\n\nnamespace base {\nnamespace subtle {\n\n#if !defined(__LP64__) && defined(__ppc__)\n\n// The Mac 64-bit OSAtomic implementations are not available for 32-bit PowerPC,\n// while the underlying assembly instructions are available only some\n// implementations of PowerPC.\n\n// The following inline functions will fail with the error message at compile\n// time ONLY IF they are called.  So it is safe to use this header if user\n// code only calls AtomicWord and Atomic32 operations.\n//\n// NOTE(vchen): Implementation notes to implement the atomic ops below may\n// be found in \"PowerPC Virtual Environment Architecture, Book II,\n// Version 2.02\", January 28, 2005, Appendix B, page 46.  Unfortunately,\n// extra care must be taken to ensure data are properly 8-byte aligned, and\n// that data are returned correctly according to Mac OS X ABI specs.\n\ninline int64_t OSAtomicCompareAndSwap64(\n    int64_t oldValue, int64_t newValue, int64_t *theValue) {\n  __asm__ __volatile__(\n      \"_OSAtomicCompareAndSwap64_not_supported_for_32_bit_ppc\\n\\t\");\n  return 0;\n}\n\ninline int64_t OSAtomicAdd64(int64_t theAmount, int64_t *theValue) {\n  __asm__ __volatile__(\n      \"_OSAtomicAdd64_not_supported_for_32_bit_ppc\\n\\t\");\n  return 0;\n}\n\ninline int64_t OSAtomicCompareAndSwap64Barrier(\n    int64_t oldValue, int64_t newValue, int64_t *theValue) {\n  int64_t prev = OSAtomicCompareAndSwap64(oldValue, newValue, theValue);\n  OSMemoryBarrier();\n  return prev;\n}\n\ninline int64_t OSAtomicAdd64Barrier(\n    int64_t theAmount, int64_t *theValue) {\n  int64_t new_val = OSAtomicAdd64(theAmount, theValue);\n  OSMemoryBarrier();\n  return new_val;\n}\n#endif\n\ntypedef int64_t Atomic64;\n\ninline void MemoryBarrier() {\n  OSMemoryBarrier();\n}\n\n// 32-bit Versions.\n\ninline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,\n                                         Atomic32 old_value,\n                                         Atomic32 new_value) {\n  Atomic32 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap32(old_value, new_value,\n                                 const_cast<Atomic32*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,\n                                         Atomic32 new_value) {\n  Atomic32 old_value;\n  do {\n    old_value = *ptr;\n  } while (!OSAtomicCompareAndSwap32(old_value, new_value,\n                                     const_cast<Atomic32*>(ptr)));\n  return old_value;\n}\n\ninline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,\n                                          Atomic32 increment) {\n  return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));\n}\n\ninline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,\n                                          Atomic32 increment) {\n  return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));\n}\n\ninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  Atomic32 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,\n                                        const_cast<Atomic32*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return Acquire_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {\n  *ptr = value;\n  MemoryBarrier();\n}\n\ninline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {\n  MemoryBarrier();\n  *ptr = value;\n}\n\ninline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {\n  return *ptr;\n}\n\ninline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {\n  Atomic32 value = *ptr;\n  MemoryBarrier();\n  return value;\n}\n\ninline Atomic32 Release_Load(volatile const Atomic32 *ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n// 64-bit version\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,\n                                         Atomic64 old_value,\n                                         Atomic64 new_value) {\n  Atomic64 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap64(old_value, new_value,\n                                 const_cast<Atomic64*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,\n                                         Atomic64 new_value) {\n  Atomic64 old_value;\n  do {\n    old_value = *ptr;\n  } while (!OSAtomicCompareAndSwap64(old_value, new_value,\n                                     const_cast<Atomic64*>(ptr)));\n  return old_value;\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,\n                                          Atomic64 increment) {\n  return OSAtomicAdd64(increment, const_cast<Atomic64*>(ptr));\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,\n                                        Atomic64 increment) {\n  return OSAtomicAdd64Barrier(increment, const_cast<Atomic64*>(ptr));\n}\n\ninline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  Atomic64 prev_value;\n  do {\n    if (OSAtomicCompareAndSwap64Barrier(old_value, new_value,\n                                        const_cast<Atomic64*>(ptr))) {\n      return old_value;\n    }\n    prev_value = *ptr;\n  } while (prev_value == old_value);\n  return prev_value;\n}\n\ninline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  // The lib kern interface does not distinguish between\n  // Acquire and Release memory barriers; they are equivalent.\n  return Acquire_CompareAndSwap(ptr, old_value, new_value);\n}\n\n#ifdef __LP64__\n\n// 64-bit implementation on 64-bit platform\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  *ptr = value;\n  MemoryBarrier();\n}\n\ninline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  MemoryBarrier();\n  *ptr = value;\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n  return *ptr;\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {\n  Atomic64 value = *ptr;\n  MemoryBarrier();\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64 *ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n#else\n\n// 64-bit implementation on 32-bit platform\n\n#if defined(__ppc__)\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n   __asm__ __volatile__(\n       \"_NoBarrier_Store_not_supported_for_32_bit_ppc\\n\\t\");\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n   __asm__ __volatile__(\n       \"_NoBarrier_Load_not_supported_for_32_bit_ppc\\n\\t\");\n   return 0;\n}\n\n#elif defined(__i386__)\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n  __asm__ __volatile__(\"movq %1, %%mm0\\n\\t\"    // Use mmx reg for 64-bit atomic\n                       \"movq %%mm0, %0\\n\\t\"  // moves (ptr could be read-only)\n                       \"emms\\n\\t\"              // Reset FP registers\n                       : \"=m\" (*ptr)\n                       : \"m\" (value)\n                       : // mark the FP stack and mmx registers as clobbered\n                         \"st\", \"st(1)\", \"st(2)\", \"st(3)\", \"st(4)\",\n                         \"st(5)\", \"st(6)\", \"st(7)\", \"mm0\", \"mm1\",\n                         \"mm2\", \"mm3\", \"mm4\", \"mm5\", \"mm6\", \"mm7\");\n\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n  Atomic64 value;\n  __asm__ __volatile__(\"movq %1, %%mm0\\n\\t\"  // Use mmx reg for 64-bit atomic\n                       \"movq %%mm0, %0\\n\\t\"  // moves (ptr could be read-only)\n                       \"emms\\n\\t\"            // Reset FP registers\n                       : \"=m\" (value)\n                       : \"m\" (*ptr)\n                       : // mark the FP stack and mmx registers as clobbered\n                         \"st\", \"st(1)\", \"st(2)\", \"st(3)\", \"st(4)\",\n                         \"st(5)\", \"st(6)\", \"st(7)\", \"mm0\", \"mm1\",\n                         \"mm2\", \"mm3\", \"mm4\", \"mm5\", \"mm6\", \"mm7\");\n\n  return value;\n}\n#endif\n\n\ninline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  NoBarrier_Store(ptr, value);\n  MemoryBarrier();\n}\n\ninline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {\n  MemoryBarrier();\n  NoBarrier_Store(ptr, value);\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {\n  Atomic64 value = NoBarrier_Load(ptr);\n  MemoryBarrier();\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64 *ptr) {\n  MemoryBarrier();\n  return NoBarrier_Load(ptr);\n}\n#endif  // __LP64__\n\n}   // namespace base::subtle\n}   // namespace base\n\n#endif  // BASE_ATOMICOPS_INTERNALS_MACOSX_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops-internals-x86-msvc.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n */\n\n// Implementation of atomic operations for x86.  This file should not\n// be included directly.  Clients should instead include\n// \"base/atomicops.h\".\n\n#ifndef BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_\n#define BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"base/basictypes.h\"  // For COMPILE_ASSERT\n\ntypedef int32 Atomic32;\n\n#if defined(_WIN64)\n#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*\n#endif\n\nnamespace base {\nnamespace subtle {\n\ntypedef int64 Atomic64;\n\n// 32-bit low-level operations on any platform\n\n// MinGW has a bug in the header files where it doesn't indicate the\n// first argument is volatile -- they're not up to date.  See\n//   http://readlist.com/lists/lists.sourceforge.net/mingw-users/0/3861.html\n// We have to const_cast away the volatile to avoid compiler warnings.\n// TODO(csilvers): remove this once MinGW has updated MinGW/include/winbase.h\n#ifdef __MINGW32__\ninline LONG InterlockedCompareExchange(volatile LONG* ptr,\n                                       LONG newval, LONG oldval) {\n  return ::InterlockedCompareExchange(const_cast<LONG*>(ptr), newval, oldval);\n}\ninline LONG InterlockedExchange(volatile LONG* ptr, LONG newval) {\n  return ::InterlockedExchange(const_cast<LONG*>(ptr), newval);\n}\ninline LONG InterlockedExchangeAdd(volatile LONG* ptr, LONG increment) {\n  return ::InterlockedExchangeAdd(const_cast<LONG*>(ptr), increment);\n}\n#endif  // ifdef __MINGW32__\n\ninline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,\n                                         Atomic32 old_value,\n                                         Atomic32 new_value) {\n  LONG result = InterlockedCompareExchange(\n      reinterpret_cast<volatile LONG*>(ptr),\n      static_cast<LONG>(new_value),\n      static_cast<LONG>(old_value));\n  return static_cast<Atomic32>(result);\n}\n\ninline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,\n                                         Atomic32 new_value) {\n  LONG result = InterlockedExchange(\n      reinterpret_cast<volatile LONG*>(ptr),\n      static_cast<LONG>(new_value));\n  return static_cast<Atomic32>(result);\n}\n\ninline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,\n                                        Atomic32 increment) {\n  return InterlockedExchangeAdd(\n      reinterpret_cast<volatile LONG*>(ptr),\n      static_cast<LONG>(increment)) + increment;\n}\n\ninline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,\n                                          Atomic32 increment) {\n  return Barrier_AtomicIncrement(ptr, increment);\n}\n\n}  // namespace base::subtle\n}  // namespace base\n\n\n// In msvc8/vs2005, winnt.h already contains a definition for\n// MemoryBarrier in the global namespace.  Add it there for earlier\n// versions and forward to it from within the namespace.\n#if !(defined(_MSC_VER) && _MSC_VER >= 1400)\ninline void MemoryBarrier() {\n  Atomic32 value = 0;\n  base::subtle::NoBarrier_AtomicExchange(&value, 0);\n                        // actually acts as a barrier in thisd implementation\n}\n#endif\n\nnamespace base {\nnamespace subtle {\n\ninline void MemoryBarrier() {\n  ::MemoryBarrier();\n}\n\ninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {\n  NoBarrier_AtomicExchange(ptr, value);\n              // acts as a barrier in this implementation\n}\n\ninline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value; // works w/o barrier for current Intel chips as of June 2005\n  // See comments in Atomic64 version of Release_Store() below.\n}\n\ninline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {\n  return *ptr;\n}\n\ninline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {\n  Atomic32 value = *ptr;\n  return value;\n}\n\ninline Atomic32 Release_Load(volatile const Atomic32* ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n// 64-bit operations\n\n#if defined(_WIN64) || defined(__MINGW64__)\n\n// 64-bit low-level operations on 64-bit platform.\n\nCOMPILE_ASSERT(sizeof(Atomic64) == sizeof(PVOID), atomic_word_is_atomic);\n\n// Like for the __MINGW32__ case above, this works around a header\n// error in mingw, where it's missing 'volatile'.\n#ifdef __MINGW64__\ninline PVOID InterlockedCompareExchangePointer(volatile PVOID* ptr,\n                                               PVOID newval, PVOID oldval) {\n  return ::InterlockedCompareExchangePointer(const_cast<PVOID*>(ptr),\n                                             newval, oldval);\n}\ninline PVOID InterlockedExchangePointer(volatile PVOID* ptr, PVOID newval) {\n  return ::InterlockedExchangePointer(const_cast<PVOID*>(ptr), newval);\n}\ninline LONGLONG InterlockedExchangeAdd64(volatile LONGLONG* ptr,\n                                         LONGLONG increment) {\n  return ::InterlockedExchangeAdd64(const_cast<LONGLONG*>(ptr), increment);\n}\n#endif  // ifdef __MINGW64__\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,\n                                         Atomic64 old_value,\n                                         Atomic64 new_value) {\n  PVOID result = InterlockedCompareExchangePointer(\n    reinterpret_cast<volatile PVOID*>(ptr),\n    reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));\n  return reinterpret_cast<Atomic64>(result);\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,\n                                         Atomic64 new_value) {\n  PVOID result = InterlockedExchangePointer(\n    reinterpret_cast<volatile PVOID*>(ptr),\n    reinterpret_cast<PVOID>(new_value));\n  return reinterpret_cast<Atomic64>(result);\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,\n                                        Atomic64 increment) {\n  return InterlockedExchangeAdd64(\n      reinterpret_cast<volatile LONGLONG*>(ptr),\n      static_cast<LONGLONG>(increment)) + increment;\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,\n                                          Atomic64 increment) {\n  return Barrier_AtomicIncrement(ptr, increment);\n}\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NoBarrier_AtomicExchange(ptr, value);\n              // acts as a barrier in this implementation\n}\n\ninline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {\n  *ptr = value; // works w/o barrier for current Intel chips as of June 2005\n\n  // When new chips come out, check:\n  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:\n  //  System Programming Guide, Chatper 7: Multiple-processor management,\n  //  Section 7.2, Memory Ordering.\n  // Last seen at:\n  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n  return *ptr;\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {\n  Atomic64 value = *ptr;\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64* ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n#else  // defined(_WIN64) || defined(__MINGW64__)\n\n// 64-bit low-level operations on 32-bit platform\n\n// TBD(vchen): The GNU assembly below must be converted to MSVC inline\n// assembly.\n\ninline void NotImplementedFatalError(const char *function_name) {\n  fprintf(stderr, \"64-bit %s() not implemented on this platform\\n\",\n          function_name);\n  abort();\n}\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,\n                                         Atomic64 old_value,\n                                         Atomic64 new_value) {\n#if 0 // Not implemented\n  Atomic64 prev;\n  __asm__ __volatile__(\"movl (%3), %%ebx\\n\\t\"    // Move 64-bit new_value into\n                       \"movl 4(%3), %%ecx\\n\\t\"   // ecx:ebx\n                       \"lock; cmpxchg8b %1\\n\\t\"  // If edx:eax (old_value) same\n                       : \"=A\" (prev)             // as contents of ptr:\n                       : \"m\" (*ptr),             //   ecx:ebx => ptr\n                         \"0\" (old_value),        // else:\n                         \"r\" (&new_value)        //   old *ptr => edx:eax\n                       : \"memory\", \"%ebx\", \"%ecx\");\n  return prev;\n#else\n  NotImplementedFatalError(\"NoBarrier_CompareAndSwap\");\n  return 0;\n#endif\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,\n                                         Atomic64 new_value) {\n#if 0 // Not implemented\n  __asm__ __volatile__(\n                       \"movl (%2), %%ebx\\n\\t\"    // Move 64-bit new_value into\n                       \"movl 4(%2), %%ecx\\n\\t\"   // ecx:ebx\n                       \"0:\\n\\t\"\n                       \"movl %1, %%eax\\n\\t\"      // Read contents of ptr into\n                       \"movl 4%1, %%edx\\n\\t\"     // edx:eax\n                       \"lock; cmpxchg8b %1\\n\\t\"  // Attempt cmpxchg; if *ptr\n                       \"jnz 0b\\n\\t\"              // is no longer edx:eax, loop\n                       : \"=A\" (new_value)\n                       : \"m\" (*ptr),\n                         \"r\" (&new_value)\n                       : \"memory\", \"%ebx\", \"%ecx\");\n  return new_value;  // Now it's the previous value.\n#else\n  NotImplementedFatalError(\"NoBarrier_AtomicExchange\");\n  return 0;\n#endif\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,\n                                          Atomic64 increment) {\n#if 0 // Not implemented\n  Atomic64 temp = increment;\n  __asm__ __volatile__(\n                       \"0:\\n\\t\"\n                       \"movl (%3), %%ebx\\n\\t\"    // Move 64-bit increment into\n                       \"movl 4(%3), %%ecx\\n\\t\"   // ecx:ebx\n                       \"movl (%2), %%eax\\n\\t\"    // Read contents of ptr into\n                       \"movl 4(%2), %%edx\\n\\t\"   // edx:eax\n                       \"add %%eax, %%ebx\\n\\t\"    // sum => ecx:ebx\n                       \"adc %%edx, %%ecx\\n\\t\"    // edx:eax still has old *ptr\n                       \"lock; cmpxchg8b (%2)\\n\\t\"// Attempt cmpxchg; if *ptr\n                       \"jnz 0b\\n\\t\"              // is no longer edx:eax, loop\n                       : \"=A\"(temp), \"+m\"(*ptr)\n                       : \"D\" (ptr), \"S\" (&increment)\n                       : \"memory\", \"%ebx\", \"%ecx\");\n  // temp now contains the previous value of *ptr\n  return temp + increment;\n#else\n  NotImplementedFatalError(\"NoBarrier_AtomicIncrement\");\n  return 0;\n#endif\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,\n                                        Atomic64 increment) {\n#if 0 // Not implemented\n  Atomic64 new_val = NoBarrier_AtomicIncrement(ptr, increment);\n  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {\n    __asm__ __volatile__(\"lfence\" : : : \"memory\");\n  }\n  return new_val;\n#else\n  NotImplementedFatalError(\"Barrier_AtomicIncrement\");\n  return 0;\n#endif\n}\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n#if 0 // Not implemented\n  __asm {\n    mov mm0, value;  // Use mmx reg for 64-bit atomic moves\n    mov ptr, mm0;\n    emms;            // Empty mmx state to enable FP registers\n  }\n#else\n  NotImplementedFatalError(\"NoBarrier_Store\");\n#endif\n}\n\ninline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NoBarrier_AtomicExchange(ptr, value);\n              // acts as a barrier in this implementation\n}\n\ninline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NoBarrier_Store(ptr, value);\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n#if 0 // Not implemented\n  Atomic64 value;\n  __asm {\n    mov mm0, ptr;    // Use mmx reg for 64-bit atomic moves\n    mov value, mm0;\n    emms;            // Empty mmx state to enable FP registers\n  }\n  return value;\n#else\n  NotImplementedFatalError(\"NoBarrier_Store\");\n  return 0;\n#endif\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {\n  Atomic64 value = NoBarrier_Load(ptr);\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64* ptr) {\n  MemoryBarrier();\n  return NoBarrier_Load(ptr);\n}\n\n#endif  // defined(_WIN64) || defined(__MINGW64__)\n\n\ninline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\n}  // namespace base::subtle\n}  // namespace base\n\n#endif  // BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops-internals-x86.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * This module gets enough CPU information to optimize the\n * atomicops module on x86.\n */\n\n#include \"base/atomicops.h\"\n#include \"base/basictypes.h\"\n#include \"base/googleinit.h\"\n#include \"base/logging.h\"\n#include <string.h>\n\n// This file only makes sense with atomicops-internals-x86.h -- it\n// depends on structs that are defined in that file.  If atomicops.h\n// doesn't sub-include that file, then we aren't needed, and shouldn't\n// try to do anything.\n#ifdef BASE_ATOMICOPS_INTERNALS_X86_H_\n\n// Inline cpuid instruction.  In PIC compilations, %ebx contains the address\n// of the global offset table.  To avoid breaking such executables, this code\n// must preserve that register's value across cpuid instructions.\n#if defined(__i386__)\n#define cpuid(a, b, c, d, inp) \\\n  asm (\"mov %%ebx, %%edi\\n\"    \\\n       \"cpuid\\n\"               \\\n       \"xchg %%edi, %%ebx\\n\"   \\\n       : \"=a\" (a), \"=D\" (b), \"=c\" (c), \"=d\" (d) : \"a\" (inp))\n#elif defined (__x86_64__)\n#define cpuid(a, b, c, d, inp) \\\n  asm (\"mov %%rbx, %%rdi\\n\"    \\\n       \"cpuid\\n\"               \\\n       \"xchg %%rdi, %%rbx\\n\"   \\\n       : \"=a\" (a), \"=D\" (b), \"=c\" (c), \"=d\" (d) : \"a\" (inp))\n#endif\n\n#if defined(cpuid)        // initialize the struct only on x86\n\n// Set the flags so that code will run correctly and conservatively\n// until InitGoogle() is called.\nstruct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {\n  false,          // bug can't exist before process spawns multiple threads\n  false,          // no SSE2\n  false,          // no cmpxchg16b\n};\n\n// Initialize the AtomicOps_Internalx86CPUFeatures struct.\nstatic void AtomicOps_Internalx86CPUFeaturesInit() {\n  uint32 eax;\n  uint32 ebx;\n  uint32 ecx;\n  uint32 edx;\n\n  // Get vendor string (issue CPUID with eax = 0)\n  cpuid(eax, ebx, ecx, edx, 0);\n  char vendor[13];\n  memcpy(vendor, &ebx, 4);\n  memcpy(vendor + 4, &edx, 4);\n  memcpy(vendor + 8, &ecx, 4);\n  vendor[12] = 0;\n\n  // get feature flags in ecx/edx, and family/model in eax\n  cpuid(eax, ebx, ecx, edx, 1);\n\n  int family = (eax >> 8) & 0xf;        // family and model fields\n  int model = (eax >> 4) & 0xf;\n  if (family == 0xf) {                  // use extended family and model fields\n    family += (eax >> 20) & 0xff;\n    model += ((eax >> 16) & 0xf) << 4;\n  }\n\n  // Opteron Rev E has a bug in which on very rare occasions a locked\n  // instruction doesn't act as a read-acquire barrier if followed by a\n  // non-locked read-modify-write instruction.  Rev F has this bug in \n  // pre-release versions, but not in versions released to customers,\n  // so we test only for Rev E, which is family 15, model 32..63 inclusive.\n  if (strcmp(vendor, \"AuthenticAMD\") == 0 &&       // AMD\n      family == 15 &&\n      32 <= model && model <= 63) {\n    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;\n  } else {\n    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;\n  }\n\n  // edx bit 26 is SSE2 which we use to tell use whether we can use mfence\n  AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);\n\n  // ecx bit 13 indicates whether the cmpxchg16b instruction is supported\n  AtomicOps_Internalx86CPUFeatures.has_cmpxchg16b = ((ecx >> 13) & 1);\n}\n\nREGISTER_MODULE_INITIALIZER(atomicops_x86, {\n  AtomicOps_Internalx86CPUFeaturesInit();\n});\n\n#endif\n\n#endif  /* ifdef BASE_ATOMICOPS_INTERNALS_X86_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops-internals-x86.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n */\n\n// Implementation of atomic operations for x86.  This file should not\n// be included directly.  Clients should instead include\n// \"base/atomicops.h\".\n\n#ifndef BASE_ATOMICOPS_INTERNALS_X86_H_\n#define BASE_ATOMICOPS_INTERNALS_X86_H_\n\ntypedef int32_t Atomic32;\n#define BASE_HAS_ATOMIC64 1  // Use only in tests and base/atomic*\n\n\n// NOTE(vchen): x86 does not need to define AtomicWordCastType, because it\n// already matches Atomic32 or Atomic64, depending on the platform.\n\n\n// This struct is not part of the public API of this module; clients may not\n// use it.\n// Features of this x86.  Values may not be correct before main() is run,\n// but are set conservatively.\nstruct AtomicOps_x86CPUFeatureStruct {\n  bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence\n                            // after acquire compare-and-swap.\n  bool has_sse2;            // Processor has SSE2.\n  bool has_cmpxchg16b;      // Processor supports cmpxchg16b instruction.\n};\nextern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;\n\n\n#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__(\"\" : : : \"memory\")\n\n\nnamespace base {\nnamespace subtle {\n\ntypedef int64_t Atomic64;\n\n// 32-bit low-level operations on any platform.\n\ninline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,\n                                         Atomic32 old_value,\n                                         Atomic32 new_value) {\n  Atomic32 prev;\n  __asm__ __volatile__(\"lock; cmpxchgl %1,%2\"\n                       : \"=a\" (prev)\n                       : \"q\" (new_value), \"m\" (*ptr), \"0\" (old_value)\n                       : \"memory\");\n  return prev;\n}\n\ninline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,\n                                         Atomic32 new_value) {\n  __asm__ __volatile__(\"xchgl %1,%0\"  // The lock prefix is implicit for xchg.\n                       : \"=r\" (new_value)\n                       : \"m\" (*ptr), \"0\" (new_value)\n                       : \"memory\");\n  return new_value;  // Now it's the previous value.\n}\n\ninline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,\n                                          Atomic32 increment) {\n  Atomic32 temp = increment;\n  __asm__ __volatile__(\"lock; xaddl %0,%1\"\n                       : \"+r\" (temp), \"+m\" (*ptr)\n                       : : \"memory\");\n  // temp now holds the old value of *ptr\n  return temp + increment;\n}\n\ninline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,\n                                        Atomic32 increment) {\n  Atomic32 temp = increment;\n  __asm__ __volatile__(\"lock; xaddl %0,%1\"\n                       : \"+r\" (temp), \"+m\" (*ptr)\n                       : : \"memory\");\n  // temp now holds the old value of *ptr\n  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {\n    __asm__ __volatile__(\"lfence\" : : : \"memory\");\n  }\n  return temp + increment;\n}\n\ninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {\n    __asm__ __volatile__(\"lfence\" : : : \"memory\");\n  }\n  return x;\n}\n\ninline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value;\n}\n\n#if defined(__x86_64__)\n\n// 64-bit implementations of memory barrier can be simpler, because it\n// \"mfence\" is guaranteed to exist.\ninline void MemoryBarrier() {\n  __asm__ __volatile__(\"mfence\" : : : \"memory\");\n}\n\ninline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {\n  *ptr = value;\n  MemoryBarrier();\n}\n\n#else\n\ninline void MemoryBarrier() {\n  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {\n    __asm__ __volatile__(\"mfence\" : : : \"memory\");\n  } else { // mfence is faster but not present on PIII\n    Atomic32 x = 0;\n    NoBarrier_AtomicExchange(&x, 0);  // acts as a barrier on PIII\n  }\n}\n\ninline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {\n  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {\n    *ptr = value;\n    __asm__ __volatile__(\"mfence\" : : : \"memory\");\n  } else {\n    NoBarrier_AtomicExchange(ptr, value);\n                          // acts as a barrier on PIII\n  }\n}\n#endif\n\ninline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {\n  ATOMICOPS_COMPILER_BARRIER();\n  *ptr = value; // An x86 store acts as a release barrier.\n  // See comments in Atomic64 version of Release_Store(), below.\n}\n\ninline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {\n  return *ptr;\n}\n\ninline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {\n  Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.\n  // See comments in Atomic64 version of Release_Store(), below.\n  ATOMICOPS_COMPILER_BARRIER();\n  return value;\n}\n\ninline Atomic32 Release_Load(volatile const Atomic32* ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n#if defined(__x86_64__)\n\n// 64-bit low-level operations on 64-bit platform.\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,\n                                         Atomic64 old_value,\n                                         Atomic64 new_value) {\n  Atomic64 prev;\n  __asm__ __volatile__(\"lock; cmpxchgq %1,%2\"\n                       : \"=a\" (prev)\n                       : \"q\" (new_value), \"m\" (*ptr), \"0\" (old_value)\n                       : \"memory\");\n  return prev;\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,\n                                         Atomic64 new_value) {\n  __asm__ __volatile__(\"xchgq %1,%0\"  // The lock prefix is implicit for xchg.\n                       : \"=r\" (new_value)\n                       : \"m\" (*ptr), \"0\" (new_value)\n                       : \"memory\");\n  return new_value;  // Now it's the previous value.\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,\n                                          Atomic64 increment) {\n  Atomic64 temp = increment;\n  __asm__ __volatile__(\"lock; xaddq %0,%1\"\n                       : \"+r\" (temp), \"+m\" (*ptr)\n                       : : \"memory\");\n  // temp now contains the previous value of *ptr\n  return temp + increment;\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,\n                                        Atomic64 increment) {\n  Atomic64 temp = increment;\n  __asm__ __volatile__(\"lock; xaddq %0,%1\"\n                       : \"+r\" (temp), \"+m\" (*ptr)\n                       : : \"memory\");\n  // temp now contains the previous value of *ptr\n  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {\n    __asm__ __volatile__(\"lfence\" : : : \"memory\");\n  }\n  return temp + increment;\n}\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n  *ptr = value;\n}\n\ninline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {\n  *ptr = value;\n  MemoryBarrier();\n}\n\ninline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {\n  ATOMICOPS_COMPILER_BARRIER();\n\n  *ptr = value; // An x86 store acts as a release barrier\n                // for current AMD/Intel chips as of Jan 2008.\n                // See also Acquire_Load(), below.\n\n  // When new chips come out, check:\n  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:\n  //  System Programming Guide, Chatper 7: Multiple-processor management,\n  //  Section 7.2, Memory Ordering.\n  // Last seen at:\n  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm\n  //\n  // x86 stores/loads fail to act as barriers for a few instructions (clflush\n  // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are\n  // not generated by the compiler, and are rare.  Users of these instructions\n  // need to know about cache behaviour in any case since all of these involve\n  // either flushing cache lines or non-temporal cache hints.\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n  return *ptr;\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {\n  Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,\n                         // for current AMD/Intel chips as of Jan 2008.\n                         // See also Release_Store(), above.\n  ATOMICOPS_COMPILER_BARRIER();\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64* ptr) {\n  MemoryBarrier();\n  return *ptr;\n}\n\n#else // defined(__x86_64__)\n\n// 64-bit low-level operations on 32-bit platform.\n\n#if !((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))\n// For compilers older than gcc 4.1, we use inline asm.\n//\n// Potential pitfalls:\n//\n// 1. %ebx points to Global offset table (GOT) with -fPIC.\n//    We need to preserve this register.\n// 2. When explicit registers are used in inline asm, the\n//    compiler may not be aware of it and might try to reuse\n//    the same register for another argument which has constraints\n//    that allow it (\"r\" for example).\n\ninline Atomic64 __sync_val_compare_and_swap(volatile Atomic64* ptr,\n                                            Atomic64 old_value,\n                                            Atomic64 new_value) {\n  Atomic64 prev;\n  __asm__ __volatile__(\"push %%ebx\\n\\t\"\n                       \"movl (%3), %%ebx\\n\\t\"    // Move 64-bit new_value into\n                       \"movl 4(%3), %%ecx\\n\\t\"   // ecx:ebx\n                       \"lock; cmpxchg8b (%1)\\n\\t\"// If edx:eax (old_value) same\n                       \"pop %%ebx\\n\\t\"\n                       : \"=A\" (prev)             // as contents of ptr:\n                       : \"D\" (ptr),              //   ecx:ebx => ptr\n                         \"0\" (old_value),        // else:\n                         \"S\" (&new_value)        //   old *ptr => edx:eax\n                       : \"memory\", \"%ecx\");\n  return prev;\n}\n#endif  // Compiler < gcc-4.1\n\ninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,\n                                         Atomic64 old_val,\n                                         Atomic64 new_val) {\n  return __sync_val_compare_and_swap(ptr, old_val, new_val);\n}\n\ninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,\n                                         Atomic64 new_val) {\n  Atomic64 old_val;\n\n  do {\n    old_val = *ptr;\n  } while (__sync_val_compare_and_swap(ptr, old_val, new_val) != old_val);\n\n  return old_val;\n}\n\ninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,\n                                          Atomic64 increment) {\n  Atomic64 old_val, new_val;\n\n  do {\n    old_val = *ptr;\n    new_val = old_val + increment;\n  } while (__sync_val_compare_and_swap(ptr, old_val, new_val) != old_val);\n\n  return old_val + increment;\n}\n\ninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,\n                                        Atomic64 increment) {\n  Atomic64 new_val = NoBarrier_AtomicIncrement(ptr, increment);\n  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {\n    __asm__ __volatile__(\"lfence\" : : : \"memory\");\n  }\n  return new_val;\n}\n\ninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {\n  __asm__ __volatile__(\"movq %1, %%mm0\\n\\t\"  // Use mmx reg for 64-bit atomic\n                       \"movq %%mm0, %0\\n\\t\"  // moves (ptr could be read-only)\n                       \"emms\\n\\t\"            // Empty mmx state/Reset FP regs\n                       : \"=m\" (*ptr)\n                       : \"m\" (value)\n                       : // mark the FP stack and mmx registers as clobbered\n\t\t\t \"st\", \"st(1)\", \"st(2)\", \"st(3)\", \"st(4)\",\n                         \"st(5)\", \"st(6)\", \"st(7)\", \"mm0\", \"mm1\",\n                         \"mm2\", \"mm3\", \"mm4\", \"mm5\", \"mm6\", \"mm7\");\n}\n\ninline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {\n  NoBarrier_Store(ptr, value);\n  MemoryBarrier();\n}\n\ninline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {\n  ATOMICOPS_COMPILER_BARRIER();\n  NoBarrier_Store(ptr, value);\n}\n\ninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {\n  Atomic64 value;\n  __asm__ __volatile__(\"movq %1, %%mm0\\n\\t\"  // Use mmx reg for 64-bit atomic\n                       \"movq %%mm0, %0\\n\\t\"  // moves (ptr could be read-only)\n                       \"emms\\n\\t\"            // Empty mmx state/Reset FP regs\n                       : \"=m\" (value)\n                       : \"m\" (*ptr)\n                       : // mark the FP stack and mmx registers as clobbered\n                         \"st\", \"st(1)\", \"st(2)\", \"st(3)\", \"st(4)\",\n                         \"st(5)\", \"st(6)\", \"st(7)\", \"mm0\", \"mm1\",\n                         \"mm2\", \"mm3\", \"mm4\", \"mm5\", \"mm6\", \"mm7\");\n  return value;\n}\n\ninline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {\n  Atomic64 value = NoBarrier_Load(ptr);\n  ATOMICOPS_COMPILER_BARRIER();\n  return value;\n}\n\ninline Atomic64 Release_Load(volatile const Atomic64* ptr) {\n  MemoryBarrier();\n  return NoBarrier_Load(ptr);\n}\n\n#endif // defined(__x86_64__)\n\ninline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {\n    __asm__ __volatile__(\"lfence\" : : : \"memory\");\n  }\n  return x;\n}\n\ninline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,\n                                       Atomic64 old_value,\n                                       Atomic64 new_value) {\n  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);\n}\n\n} // namespace base::subtle\n} // namespace base\n\n#undef ATOMICOPS_COMPILER_BARRIER\n\n#endif  // BASE_ATOMICOPS_INTERNALS_X86_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/atomicops.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n */\n\n// For atomic operations on statistics counters, see atomic_stats_counter.h.\n// For atomic operations on sequence numbers, see atomic_sequence_num.h.\n// For atomic operations on reference counts, see atomic_refcount.h.\n\n// Some fast atomic operations -- typically with machine-dependent\n// implementations.  This file may need editing as Google code is\n// ported to different architectures.\n\n// The routines exported by this module are subtle.  If you use them, even if\n// you get the code right, it will depend on careful reasoning about atomicity\n// and memory ordering; it will be less readable, and harder to maintain.  If\n// you plan to use these routines, you should have a good reason, such as solid\n// evidence that performance would otherwise suffer, or there being no\n// alternative.  You should assume only properties explicitly guaranteed by the\n// specifications in this file.  You are almost certainly _not_ writing code\n// just for the x86; if you assume x86 semantics, x86 hardware bugs and\n// implementations on other archtectures will cause your code to break.  If you\n// do not know what you are doing, avoid these routines, and use a Mutex.\n//\n// It is incorrect to make direct assignments to/from an atomic variable.\n// You should use one of the Load or Store routines.  The NoBarrier\n// versions are provided when no barriers are needed:\n//   NoBarrier_Store()\n//   NoBarrier_Load()\n// Although there are currently no compiler enforcement, you are encouraged\n// to use these.  Moreover, if you choose to use base::subtle::Atomic64 type,\n// you MUST use one of the Load or Store routines to get correct behavior\n// on 32-bit platforms.\n//\n// The intent is eventually to put all of these routines in namespace\n// base::subtle\n\n#ifndef THREAD_ATOMICOPS_H_\n#define THREAD_ATOMICOPS_H_\n\n#include <config.h>\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n\n// ------------------------------------------------------------------------\n// Include the platform specific implementations of the types\n// and operations listed below.  Implementations are to provide Atomic32\n// and Atomic64 operations. If there is a mismatch between intptr_t and\n// the Atomic32 or Atomic64 types for a platform, the platform-specific header\n// should define the macro, AtomicWordCastType in a clause similar to the\n// following:\n// #if ...pointers are 64 bits...\n// # define AtomicWordCastType base::subtle::Atomic64\n// #else\n// # define AtomicWordCastType Atomic32\n// #endif\n// TODO(csilvers): figure out ARCH_PIII/ARCH_K8 (perhaps via ./configure?)\n// ------------------------------------------------------------------------\n\n// TODO(csilvers): match piii, not just __i386.  Also, match k8\n#if defined(__MACH__) && defined(__APPLE__)\n#include \"base/atomicops-internals-macosx.h\"\n#elif defined(__GNUC__) && defined(__ARM_ARCH_5T__)\n#include \"base/atomicops-internals-arm-gcc.h\"\n#elif defined(_MSC_VER) && defined(_M_IX86)\n#include \"base/atomicops-internals-x86-msvc.h\"\n#elif defined(__MINGW32__) && defined(__i386__)\n#include \"base/atomicops-internals-x86-msvc.h\"\n#elif defined(__GNUC__) && (defined(__i386) || defined(ARCH_K8))\n#include \"base/atomicops-internals-x86.h\"\n#elif defined(__linux__) && defined(__PPC__)\n#include \"base/atomicops-internals-linuxppc.h\"\n#else\n// Assume x86 for now.  If you need to support a new architecture and\n// don't know how to implement atomic ops, you can probably get away\n// with using pthreads, since atomicops is only used by spinlock.h/cc\n//#error You need to implement atomic operations for this architecture\n#include \"base/atomicops-internals-x86.h\"\n#endif\n\n// Signed type that can hold a pointer and supports the atomic ops below, as\n// well as atomic loads and stores.  Instances must be naturally-aligned.\ntypedef intptr_t AtomicWord;\n\n#ifdef AtomicWordCastType\n// ------------------------------------------------------------------------\n// This section is needed only when explicit type casting is required to\n// cast AtomicWord to one of the basic atomic types (Atomic64 or Atomic32).\n// It also serves to document the AtomicWord interface.\n// ------------------------------------------------------------------------\n\nnamespace base {\nnamespace subtle {\n\n// Atomically execute:\n//      result = *ptr;\n//      if (*ptr == old_value)\n//        *ptr = new_value;\n//      return result;\n//\n// I.e., replace \"*ptr\" with \"new_value\" if \"*ptr\" used to be \"old_value\".\n// Always return the old value of \"*ptr\"\n//\n// This routine implies no memory barriers.\ninline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,\n                                           AtomicWord old_value,\n                                           AtomicWord new_value) {\n  return NoBarrier_CompareAndSwap(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr),\n      old_value, new_value);\n}\n\n// Atomically store new_value into *ptr, returning the previous value held in\n// *ptr.  This routine implies no memory barriers.\ninline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,\n                                           AtomicWord new_value) {\n  return NoBarrier_AtomicExchange(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr), new_value);\n}\n\n// Atomically increment *ptr by \"increment\".  Returns the new value of\n// *ptr with the increment applied.  This routine implies no memory\n// barriers.\ninline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,\n                                            AtomicWord increment) {\n  return NoBarrier_AtomicIncrement(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr), increment);\n}\n\ninline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,\n                                          AtomicWord increment) {\n  return Barrier_AtomicIncrement(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr), increment);\n}\n\n// ------------------------------------------------------------------------\n// These following lower-level operations are typically useful only to people\n// implementing higher-level synchronization operations like spinlocks,\n// mutexes, and condition-variables.  They combine CompareAndSwap(), a load, or\n// a store with appropriate memory-ordering instructions.  \"Acquire\" operations\n// ensure that no later memory access can be reordered ahead of the operation.\n// \"Release\" operations ensure that no previous memory access can be reordered\n// after the operation.  \"Barrier\" operations have both \"Acquire\" and \"Release\"\n// semantics.   A MemoryBarrier() has \"Barrier\" semantics, but does no memory\n// access.\n// ------------------------------------------------------------------------\ninline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,\n                                         AtomicWord old_value,\n                                         AtomicWord new_value) {\n  return base::subtle::Acquire_CompareAndSwap(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr),\n      old_value, new_value);\n}\n\ninline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,\n                                         AtomicWord old_value,\n                                         AtomicWord new_value) {\n  return base::subtle::Release_CompareAndSwap(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr),\n      old_value, new_value);\n}\n\ninline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {\n  NoBarrier_Store(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);\n}\n\ninline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {\n  return base::subtle::Acquire_Store(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);\n}\n\ninline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {\n  return base::subtle::Release_Store(\n      reinterpret_cast<volatile AtomicWordCastType*>(ptr), value);\n}\n\ninline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {\n  return NoBarrier_Load(\n      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));\n}\n\ninline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {\n  return base::subtle::Acquire_Load(\n      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));\n}\n\ninline AtomicWord Release_Load(volatile const AtomicWord* ptr) {\n  return base::subtle::Release_Load(\n      reinterpret_cast<volatile const AtomicWordCastType*>(ptr));\n}\n\n}  // namespace base::subtle\n}  // namespace base\n#endif  // AtomicWordCastType\n\n// ------------------------------------------------------------------------\n// Commented out type definitions and method declarations for documentation\n// of the interface provided by this module.\n// ------------------------------------------------------------------------\n\n#if 0\n\n// Signed 32-bit type that supports the atomic ops below, as well as atomic\n// loads and stores.  Instances must be naturally aligned.  This type differs\n// from AtomicWord in 64-bit binaries where AtomicWord is 64-bits.\ntypedef int32_t Atomic32;\n\n// Corresponding operations on Atomic32\nnamespace base {\nnamespace subtle {\n\n// Signed 64-bit type that supports the atomic ops below, as well as atomic\n// loads and stores.  Instances must be naturally aligned.  This type differs\n// from AtomicWord in 32-bit binaries where AtomicWord is 32-bits.\ntypedef int64_t Atomic64;\n\nAtomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,\n                                  Atomic32 old_value,\n                                  Atomic32 new_value);\nAtomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);\nAtomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);\nAtomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,\n                                 Atomic32 increment);\nAtomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,\n                                Atomic32 old_value,\n                                Atomic32 new_value);\nAtomic32 Release_CompareAndSwap(volatile Atomic32* ptr,\n                                Atomic32 old_value,\n                                Atomic32 new_value);\nvoid NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);\nvoid Acquire_Store(volatile Atomic32* ptr, Atomic32 value);\nvoid Release_Store(volatile Atomic32* ptr, Atomic32 value);\nAtomic32 NoBarrier_Load(volatile const Atomic32* ptr);\nAtomic32 Acquire_Load(volatile const Atomic32* ptr);\nAtomic32 Release_Load(volatile const Atomic32* ptr);\n\n// Corresponding operations on Atomic64\nAtomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,\n                                  Atomic64 old_value,\n                                  Atomic64 new_value);\nAtomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);\nAtomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);\nAtomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);\n\nAtomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,\n                                Atomic64 old_value,\n                                Atomic64 new_value);\nAtomic64 Release_CompareAndSwap(volatile Atomic64* ptr,\n                                Atomic64 old_value,\n                                Atomic64 new_value);\nvoid NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);\nvoid Acquire_Store(volatile Atomic64* ptr, Atomic64 value);\nvoid Release_Store(volatile Atomic64* ptr, Atomic64 value);\nAtomic64 NoBarrier_Load(volatile const Atomic64* ptr);\nAtomic64 Acquire_Load(volatile const Atomic64* ptr);\nAtomic64 Release_Load(volatile const Atomic64* ptr);\n}  // namespace base::subtle\n}  // namespace base\n\nvoid MemoryBarrier();\n\n#endif  // 0\n\n\n// ------------------------------------------------------------------------\n// The following are to be deprecated when all uses have been changed to\n// use the base::subtle namespace.\n// ------------------------------------------------------------------------\n\n#ifdef AtomicWordCastType\n// AtomicWord versions to be deprecated\ninline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,\n                                         AtomicWord old_value,\n                                         AtomicWord new_value) {\n  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,\n                                         AtomicWord old_value,\n                                         AtomicWord new_value) {\n  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);\n}\n\ninline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {\n  return base::subtle::Acquire_Store(ptr, value);\n}\n\ninline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {\n  return base::subtle::Release_Store(ptr, value);\n}\n\ninline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {\n  return base::subtle::Acquire_Load(ptr);\n}\n\ninline AtomicWord Release_Load(volatile const AtomicWord* ptr) {\n  return base::subtle::Release_Load(ptr);\n}\n#endif  // AtomicWordCastType\n\n// 32-bit Acquire/Release operations to be deprecated.\n\ninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);\n}\ninline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,\n                                       Atomic32 old_value,\n                                       Atomic32 new_value) {\n  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);\n}\ninline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {\n  base::subtle::Acquire_Store(ptr, value);\n}\ninline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {\n  return base::subtle::Release_Store(ptr, value);\n}\ninline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {\n  return base::subtle::Acquire_Load(ptr);\n}\ninline Atomic32 Release_Load(volatile const Atomic32* ptr) {\n  return base::subtle::Release_Load(ptr);\n}\n\n#ifdef BASE_HAS_ATOMIC64\n\n// 64-bit Acquire/Release operations to be deprecated.\n\ninline base::subtle::Atomic64 Acquire_CompareAndSwap(\n    volatile base::subtle::Atomic64* ptr,\n    base::subtle::Atomic64 old_value, base::subtle::Atomic64 new_value) {\n  return base::subtle::Acquire_CompareAndSwap(ptr, old_value, new_value);\n}\ninline base::subtle::Atomic64 Release_CompareAndSwap(\n    volatile base::subtle::Atomic64* ptr,\n    base::subtle::Atomic64 old_value, base::subtle::Atomic64 new_value) {\n  return base::subtle::Release_CompareAndSwap(ptr, old_value, new_value);\n}\ninline void Acquire_Store(\n    volatile base::subtle::Atomic64* ptr, base::subtle::Atomic64 value) {\n  base::subtle::Acquire_Store(ptr, value);\n}\ninline void Release_Store(\n    volatile base::subtle::Atomic64* ptr, base::subtle::Atomic64 value) {\n  return base::subtle::Release_Store(ptr, value);\n}\ninline base::subtle::Atomic64 Acquire_Load(\n    volatile const base::subtle::Atomic64* ptr) {\n  return base::subtle::Acquire_Load(ptr);\n}\ninline base::subtle::Atomic64 Release_Load(\n    volatile const base::subtle::Atomic64* ptr) {\n  return base::subtle::Release_Load(ptr);\n}\n\n#endif  // BASE_HAS_ATOMIC64\n\n#endif  // THREAD_ATOMICOPS_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/basictypes.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#ifndef _BASICTYPES_H_\n#define _BASICTYPES_H_\n\n#include <config.h>\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>     // gets us PRId64, etc\n#endif\n\n// To use this in an autoconf setting, make sure you run the following\n// autoconf macros:\n//    AC_HEADER_STDC              /* for stdint_h and inttypes_h */\n//    AC_CHECK_TYPES([__int64])   /* defined in some windows platforms */\n\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>           // uint16_t might be here; PRId64 too.\n#endif\n#ifdef HAVE_STDINT_H\n#include <stdint.h>             // to get uint16_t (ISO naming madness)\n#endif\n#include <sys/types.h>          // our last best hope for uint16_t\n\n// Standard typedefs\n// All Google code is compiled with -funsigned-char to make \"char\"\n// unsigned.  Google code therefore doesn't need a \"uchar\" type.\n// TODO(csilvers): how do we make sure unsigned-char works on non-gcc systems?\ntypedef signed char         schar;\ntypedef int8_t              int8;\ntypedef int16_t             int16;\ntypedef int32_t             int32;\ntypedef int64_t             int64;\n\n// NOTE: unsigned types are DANGEROUS in loops and other arithmetical\n// places.  Use the signed types unless your variable represents a bit\n// pattern (eg a hash value) or you really need the extra bit.  Do NOT\n// use 'unsigned' to express \"this value should always be positive\";\n// use assertions for this.\n\ntypedef uint8_t            uint8;\ntypedef uint16_t           uint16;\ntypedef uint32_t           uint32;\ntypedef uint64_t           uint64;\n\nconst uint16 kuint16max = (   (uint16) 0xFFFF);\nconst uint32 kuint32max = (   (uint32) 0xFFFFFFFF);\nconst uint64 kuint64max = ( (((uint64) kuint32max) << 32) | kuint32max );\n\nconst  int8  kint8max   = (   (  int8) 0x7F);\nconst  int16 kint16max  = (   ( int16) 0x7FFF);\nconst  int32 kint32max  = (   ( int32) 0x7FFFFFFF);\nconst  int64 kint64max =  ( ((( int64) kint32max) << 32) | kuint32max );\n\nconst  int8  kint8min   = (   (  int8) 0x80);\nconst  int16 kint16min  = (   ( int16) 0x8000);\nconst  int32 kint32min  = (   ( int32) 0x80000000);\nconst  int64 kint64min =  ( ((( int64) kint32min) << 32) | 0 );\n\n// Define the \"portable\" printf and scanf macros, if they're not\n// already there (via the inttypes.h we #included above, hopefully).\n// Mostly it's old systems that don't support inttypes.h, so we assume\n// they're 32 bit.\n#ifndef PRIx64\n#define PRIx64 \"llx\"\n#endif\n#ifndef SCNx64\n#define SCNx64 \"llx\"\n#endif\n#ifndef PRId64\n#define PRId64 \"lld\"\n#endif\n#ifndef SCNd64\n#define SCNd64 \"lld\"\n#endif\n#ifndef PRIu64\n#define PRIu64 \"llu\"\n#endif\n#ifndef PRIxPTR\n#define PRIxPTR \"lx\"\n#endif\n\n// Also allow for printing of a pthread_t.\n#define GPRIuPTHREAD \"lu\"\n#define GPRIxPTHREAD \"lx\"\n#if defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__)\n#define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast<uintptr_t>(pthreadt)\n#else\n#define PRINTABLE_PTHREAD(pthreadt) pthreadt\n#endif\n\n// A macro to disallow the evil copy constructor and operator= functions\n// This should be used in the private: declarations for a class\n#define DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \\\n  TypeName(const TypeName&);                    \\\n  void operator=(const TypeName&)\n\n// An alternate name that leaves out the moral judgment... :-)\n#define DISALLOW_COPY_AND_ASSIGN(TypeName) DISALLOW_EVIL_CONSTRUCTORS(TypeName)\n\n// The COMPILE_ASSERT macro can be used to verify that a compile time\n// expression is true. For example, you could use it to verify the\n// size of a static array:\n//\n//   COMPILE_ASSERT(sizeof(num_content_type_names) == sizeof(int),\n//                  content_type_names_incorrect_size);\n//\n// or to make sure a struct is smaller than a certain size:\n//\n//   COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);\n//\n// The second argument to the macro is the name of the variable. If\n// the expression is false, most compilers will issue a warning/error\n// containing the name of the variable.\n//\n// Implementation details of COMPILE_ASSERT:\n//\n// - COMPILE_ASSERT works by defining an array type that has -1\n//   elements (and thus is invalid) when the expression is false.\n//\n// - The simpler definition\n//\n//     #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]\n//\n//   does not work, as gcc supports variable-length arrays whose sizes\n//   are determined at run-time (this is gcc's extension and not part\n//   of the C++ standard).  As a result, gcc fails to reject the\n//   following code with the simple definition:\n//\n//     int foo;\n//     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is\n//                               // not a compile-time constant.\n//\n// - By using the type CompileAssert<(bool(expr))>, we ensures that\n//   expr is a compile-time constant.  (Template arguments must be\n//   determined at compile-time.)\n//\n// - The outter parentheses in CompileAssert<(bool(expr))> are necessary\n//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written\n//\n//     CompileAssert<bool(expr)>\n//\n//   instead, these compilers will refuse to compile\n//\n//     COMPILE_ASSERT(5 > 0, some_message);\n//\n//   (They seem to think the \">\" in \"5 > 0\" marks the end of the\n//   template argument list.)\n//\n// - The array size is (bool(expr) ? 1 : -1), instead of simply\n//\n//     ((expr) ? 1 : -1).\n//\n//   This is to avoid running into a bug in MS VC 7.1, which\n//   causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.\n\ntemplate <bool>\nstruct CompileAssert {\n};\n\n#define COMPILE_ASSERT(expr, msg)                               \\\n  typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]\n\n#define arraysize(a)  (sizeof(a) / sizeof(*(a)))\n\n#define OFFSETOF_MEMBER(strct, field)                                   \\\n   (reinterpret_cast<char*>(&reinterpret_cast<strct*>(16)->field) -     \\\n    reinterpret_cast<char*>(16))\n\n#ifdef HAVE___ATTRIBUTE__\n# define ATTRIBUTE_WEAK      __attribute__((weak))\n# define ATTRIBUTE_NOINLINE  __attribute__((noinline))\n#else\n# define ATTRIBUTE_WEAK\n# define ATTRIBUTE_NOINLINE\n#endif\n\n// Section attributes are supported for both ELF and Mach-O, but in\n// very different ways.  Here's the API we provide:\n// 1) ATTRIBUTE_SECTION: put this with the declaration of all functions\n//    you want to be in the same linker section\n// 2) DEFINE_ATTRIBUTE_SECTION_VARS: must be called once per unique\n//    name.  You want to make sure this is executed before any\n//    DECLARE_ATTRIBUTE_SECTION_VARS; the easiest way is to put them\n//    in the same .cc file.  Put this call at the global level.\n// 3) INIT_ATTRIBUTE_SECTION_VARS: you can scatter calls to this in\n//    multiple places to help ensure execution before any\n//    DECLARE_ATTRIBUTE_SECTION_VARS.  You must have at least one\n//    DEFINE, but you can have many INITs.  Put each in its own scope.\n// 4) DECLARE_ATTRIBUTE_SECTION_VARS: must be called before using\n//    ATTRIBUTE_SECTION_START or ATTRIBUTE_SECTION_STOP on a name.\n//    Put this call at the global level.\n// 5) ATTRIBUTE_SECTION_START/ATTRIBUTE_SECTION_STOP: call this to say\n//    where in memory a given section is.  All functions declared with\n//    ATTRIBUTE_SECTION are guaranteed to be between START and STOP.\n\n#if defined(HAVE___ATTRIBUTE__) && defined(__ELF__)\n# define ATTRIBUTE_SECTION(name) __attribute__ ((section (#name)))\n\n  // Weak section declaration to be used as a global declaration\n  // for ATTRIBUTE_SECTION_START|STOP(name) to compile and link\n  // even without functions with ATTRIBUTE_SECTION(name).\n# define DECLARE_ATTRIBUTE_SECTION_VARS(name) \\\n    extern char __start_##name[] ATTRIBUTE_WEAK; \\\n    extern char __stop_##name[] ATTRIBUTE_WEAK\n# define INIT_ATTRIBUTE_SECTION_VARS(name)     // no-op for ELF\n# define DEFINE_ATTRIBUTE_SECTION_VARS(name)   // no-op for ELF\n\n  // Return void* pointers to start/end of a section of code with functions\n  // having ATTRIBUTE_SECTION(name), or 0 if no such function exists.\n  // One must DECLARE_ATTRIBUTE_SECTION(name) for this to compile and link.\n# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))\n# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))\n# define HAVE_ATTRIBUTE_SECTION_START 1\n\n#elif defined(HAVE___ATTRIBUTE__) && defined(__MACH__)\n# define ATTRIBUTE_SECTION(name) __attribute__ ((section (\"__TEXT, \" #name)))\n\n#include <mach-o/getsect.h>\n#include <mach-o/dyld.h>\nclass AssignAttributeStartEnd {\n public:\n  AssignAttributeStartEnd(const char* name, char** pstart, char** pend) {\n    // Find out what dynamic library name is defined in\n    if (_dyld_present()) {\n      for (int i = _dyld_image_count() - 1; i >= 0; --i) {\n        const mach_header* hdr = _dyld_get_image_header(i);\n#ifdef MH_MAGIC_64\n        if (hdr->magic == MH_MAGIC_64) {\n          uint64_t len;\n          *pstart = getsectdatafromheader_64((mach_header_64*)hdr,\n                                             \"__TEXT\", name, &len);\n          if (*pstart) {   // NULL if not defined in this dynamic library\n            *pstart += _dyld_get_image_vmaddr_slide(i);   // correct for reloc\n            *pend = *pstart + len;\n            return;\n          }\n        }\n#endif\n        if (hdr->magic == MH_MAGIC) {\n          uint32_t len;\n          *pstart = getsectdatafromheader(hdr, \"__TEXT\", name, &len);\n          if (*pstart) {   // NULL if not defined in this dynamic library\n            *pstart += _dyld_get_image_vmaddr_slide(i);   // correct for reloc\n            *pend = *pstart + len;\n            return;\n          }\n        }\n      }\n    }\n    // If we get here, not defined in a dll at all.  See if defined statically.\n    unsigned long len;    // don't ask me why this type isn't uint32_t too...\n    *pstart = getsectdata(\"__TEXT\", name, &len);\n    *pend = *pstart + len;\n  }\n};\n\n#define DECLARE_ATTRIBUTE_SECTION_VARS(name)    \\\n  extern char* __start_##name;                  \\\n  extern char* __stop_##name\n\n#define INIT_ATTRIBUTE_SECTION_VARS(name)               \\\n  DECLARE_ATTRIBUTE_SECTION_VARS(name);                 \\\n  static const AssignAttributeStartEnd __assign_##name( \\\n    #name, &__start_##name, &__stop_##name)\n\n#define DEFINE_ATTRIBUTE_SECTION_VARS(name)     \\\n  char* __start_##name, *__stop_##name;         \\\n  INIT_ATTRIBUTE_SECTION_VARS(name)\n\n# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))\n# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))\n# define HAVE_ATTRIBUTE_SECTION_START 1\n\n#else  // not HAVE___ATTRIBUTE__ && __ELF__, nor HAVE___ATTRIBUTE__ && __MACH__\n# define ATTRIBUTE_SECTION(name)\n# define DECLARE_ATTRIBUTE_SECTION_VARS(name)\n# define INIT_ATTRIBUTE_SECTION_VARS(name)\n# define DEFINE_ATTRIBUTE_SECTION_VARS(name)\n# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))\n# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))\n\n#endif  // HAVE___ATTRIBUTE__ and __ELF__ or __MACH__\n\n#if defined(HAVE___ATTRIBUTE__) && (defined(__i386__) || defined(__x86_64__))\n# define CACHELINE_SIZE 64\n# define CACHELINE_ALIGNED __attribute__((aligned(CACHELINE_SIZE)))\n#else\n# define CACHELINE_ALIGNED\n#endif  // defined(HAVE___ATTRIBUTE__) && (__i386__ || __x86_64__)\n\n\n// The following enum should be used only as a constructor argument to indicate\n// that the variable has static storage class, and that the constructor should\n// do nothing to its state.  It indicates to the reader that it is legal to\n// declare a static nistance of the class, provided the constructor is given\n// the base::LINKER_INITIALIZED argument.  Normally, it is unsafe to declare a\n// static variable that has a constructor or a destructor because invocation\n// order is undefined.  However, IF the type can be initialized by filling with\n// zeroes (which the loader does for static variables), AND the destructor also\n// does nothing to the storage, then a constructor declared as\n//       explicit MyClass(base::LinkerInitialized x) {}\n// and invoked as\n//       static MyClass my_variable_name(base::LINKER_INITIALIZED);\nnamespace base {\nenum LinkerInitialized { LINKER_INITIALIZED };\n}\n\n#endif  // _BASICTYPES_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/commandlineflags.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// This file is a compatibility layer that defines Google's version of\n// command line flags that are used for configuration.\n//\n// We put flags into their own namespace.  It is purposefully\n// named in an opaque way that people should have trouble typing\n// directly.  The idea is that DEFINE puts the flag in the weird\n// namespace, and DECLARE imports the flag from there into the\n// current namespace.  The net result is to force people to use\n// DECLARE to get access to a flag, rather than saying\n//   extern bool FLAGS_logtostderr;\n// or some such instead.  We want this so we can put extra\n// functionality (like sanity-checking) in DECLARE if we want,\n// and make sure it is picked up everywhere.\n//\n// We also put the type of the variable in the namespace, so that\n// people can't DECLARE_int32 something that they DEFINE_bool'd\n// elsewhere.\n#ifndef BASE_COMMANDLINEFLAGS_H_\n#define BASE_COMMANDLINEFLAGS_H_\n\n#include <config.h>\n#include <string>\n#include <string.h>               // for memchr\n#include <stdlib.h>               // for getenv\n#include \"base/basictypes.h\"\n\n#define DECLARE_VARIABLE(type, name)                                          \\\n  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \\\n  extern PERFTOOLS_DLL_DECL type FLAGS_##name;                                \\\n  }                                                                           \\\n  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name\n\n#define DEFINE_VARIABLE(type, name, value, meaning) \\\n  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \\\n  PERFTOOLS_DLL_DECL type FLAGS_##name(value);                                \\\n  char FLAGS_no##name;                                                        \\\n  }                                                                           \\\n  using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name\n\n// bool specialization\n#define DECLARE_bool(name) \\\n  DECLARE_VARIABLE(bool, name)\n#define DEFINE_bool(name, value, meaning) \\\n  DEFINE_VARIABLE(bool, name, value, meaning)\n\n// int32 specialization\n#define DECLARE_int32(name) \\\n  DECLARE_VARIABLE(int32, name)\n#define DEFINE_int32(name, value, meaning) \\\n  DEFINE_VARIABLE(int32, name, value, meaning)\n\n// int64 specialization\n#define DECLARE_int64(name) \\\n  DECLARE_VARIABLE(int64, name)\n#define DEFINE_int64(name, value, meaning) \\\n  DEFINE_VARIABLE(int64, name, value, meaning)\n\n#define DECLARE_uint64(name) \\\n  DECLARE_VARIABLE(uint64, name)\n#define DEFINE_uint64(name, value, meaning) \\\n  DEFINE_VARIABLE(uint64, name, value, meaning)\n\n// double specialization\n#define DECLARE_double(name) \\\n  DECLARE_VARIABLE(double, name)\n#define DEFINE_double(name, value, meaning) \\\n  DEFINE_VARIABLE(double, name, value, meaning)\n\n// Special case for string, because we have to specify the namespace\n// std::string, which doesn't play nicely with our FLAG__namespace hackery.\n#define DECLARE_string(name)                                          \\\n  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead {  \\\n  extern std::string FLAGS_##name;                                                   \\\n  }                                                                           \\\n  using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name\n#define DEFINE_string(name, value, meaning) \\\n  namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead {  \\\n  std::string FLAGS_##name(value);                                                   \\\n  char FLAGS_no##name;                                                        \\\n  }                                                                           \\\n  using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name\n\n// These macros (could be functions, but I don't want to bother with a .cc\n// file), make it easier to initialize flags from the environment.\n\n#define EnvToString(envname, dflt)   \\\n  (!getenv(envname) ? (dflt) : getenv(envname))\n\n#define EnvToBool(envname, dflt)   \\\n  (!getenv(envname) ? (dflt) : memchr(\"tTyY1\\0\", getenv(envname)[0], 6) != NULL)\n\n#define EnvToInt(envname, dflt)  \\\n  (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))\n\n#define EnvToInt64(envname, dflt)  \\\n  (!getenv(envname) ? (dflt) : strtoll(getenv(envname), NULL, 10))\n\n#define EnvToDouble(envname, dflt)  \\\n  (!getenv(envname) ? (dflt) : strtod(getenv(envname), NULL))\n\n#endif  // BASE_COMMANDLINEFLAGS_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/cycleclock.h",
    "content": "// Copyright (c) 2004, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ----------------------------------------------------------------------\n// CycleClock\n//    A CycleClock tells you the current time in Cycles.  The \"time\"\n//    is actually time since power-on.  This is like time() but doesn't\n//    involve a system call and is much more precise.\n//\n// NOTE: Not all cpu/platform/kernel combinations guarantee that this\n// clock increments at a constant rate or is synchronized across all logical\n// cpus in a system.\n//\n// Also, in some out of order CPU implementations, the CycleClock is not \n// serializing. So if you're trying to count at cycles granularity, your\n// data might be inaccurate due to out of order instruction execution.\n// ----------------------------------------------------------------------\n\n#ifndef GOOGLE_BASE_CYCLECLOCK_H_\n#define GOOGLE_BASE_CYCLECLOCK_H_\n\n#include \"base/basictypes.h\"   // make sure we get the def for int64\n#if defined(__MACH__) && defined(__APPLE__)\n# include <mach/mach_time.h>\n#elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_3__)\n# include <sys/time.h>\n#endif\n\n// NOTE: only i386 and x86_64 have been well tested.\n// PPC, sparc, alpha, and ia64 are based on\n//    http://peter.kuscsik.com/wordpress/?p=14\n// with modifications by m3b.  See also\n//    https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h\nstruct CycleClock {\n  // This should return the number of cycles since power-on.  Thread-safe.\n  static inline int64 Now() {\n#if defined(__MACH__) && defined(__APPLE__)\n    // this goes at the top because we need ALL Macs, regardless of\n    // architecture, to return the number of \"mach time units\" that\n    // have passed since startup.  See sysinfo.cc where\n    // InitializeSystemInfo() sets the supposed cpu clock frequency of\n    // macs to the number of mach time units per second, not actual\n    // CPU clock frequency (which can change in the face of CPU\n    // frequency scaling).  Also note that when the Mac sleeps, this\n    // counter pauses; it does not continue counting, nor does it\n    // reset to zero.\n    return mach_absolute_time();\n#elif defined(__i386__)\n    int64 ret;\n    __asm__ volatile (\"rdtsc\" : \"=A\" (ret) );\n    return ret;\n#elif defined(__x86_64__) || defined(__amd64__)\n    uint64 low, high;\n    __asm__ volatile (\"rdtsc\" : \"=a\" (low), \"=d\" (high));\n    return (high << 32) | low;\n#elif defined(__powerpc__) || defined(__ppc__)\n    // This returns a time-base, which is not always precisely a cycle-count.\n    int64 tbl, tbu0, tbu1;\n    asm(\"mftbu %0\" : \"=r\" (tbu0));\n    asm(\"mftb  %0\" : \"=r\" (tbl));\n    asm(\"mftbu %0\" : \"=r\" (tbu1));\n    tbl &= -static_cast<int64>(tbu0 == tbu1);\n    // high 32 bits in tbu1; low 32 bits in tbl  (tbu0 is garbage)\n    return (tbu1 << 32) | tbl;\n#elif defined(__sparc__)\n    int64 tick;\n    asm(\".byte 0x83, 0x41, 0x00, 0x00\");\n    asm(\"mov   %%g1, %0\" : \"=r\" (tick));\n    return tick;\n#elif defined(__ia64__)\n    int64 itc;\n    asm(\"mov %0 = ar.itc\" : \"=r\" (itc));\n    return itc;\n#elif defined(_MSC_VER) && defined(_M_IX86)\n    _asm rdtsc\n\n// If none of the above cases trigger, we use a solution based on\n// a system call (gettimeofday or similar).  We do these in order\n// from fastest to slowest.  We do not have an '#else' catch-all\n// case here that just calls gettimeofday(); that system call is\n// slow, and this function is expected to be fast, so we don't want\n// to use it without an explicit decision that it's the only way.\n#elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_3__)\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return static_cast<uint64>(tv.tv_sec) * 1000000 + tv.tv_usec;\n#else\n    // We could define __alpha here as well, but it only has a 32-bit\n    // timer (good for like 4 seconds), which isn't very useful.\n#error You need to define CycleTimer for your O/S and CPU\n#endif\n  }\n};\n\n\n#endif  // GOOGLE_BASE_CYCLECLOCK_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/dynamic_annotations.c",
    "content": "/* Copyright (c) 2008-2009, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Kostya Serebryany\n */\n\n#ifdef __cplusplus\n# error \"This file should be built as pure C to avoid name mangling\"\n#endif\n\n#include \"config.h\"\n#include <stdlib.h>\n#include <string.h>\n\n#include \"base/dynamic_annotations.h\"\n\n#ifdef __GNUC__\n/* valgrind.h uses gcc extensions so it won't build with other compilers */\n# ifdef HAVE_VALGRIND_H    /* prefer the user's copy if they have it */\n#  include <valgrind.h>\n# else                     /* otherwise just use the copy that we have */\n#  include \"third_party/valgrind.h\"\n# endif\n#endif\n\n/* Each function is empty and called (via a macro) only in debug mode.\n   The arguments are captured by dynamic tools at runtime. */\n\n#if DYNAMIC_ANNOTATIONS_ENABLED == 1\n\nvoid AnnotateRWLockCreate(const char *file, int line,\n                          const volatile void *lock){}\nvoid AnnotateRWLockDestroy(const char *file, int line,\n                           const volatile void *lock){}\nvoid AnnotateRWLockAcquired(const char *file, int line,\n                            const volatile void *lock, long is_w){}\nvoid AnnotateRWLockReleased(const char *file, int line,\n                            const volatile void *lock, long is_w){}\nvoid AnnotateBarrierInit(const char *file, int line,\n                         const volatile void *barrier, long count,\n                         long reinitialization_allowed) {}\nvoid AnnotateBarrierWaitBefore(const char *file, int line,\n                               const volatile void *barrier) {}\nvoid AnnotateBarrierWaitAfter(const char *file, int line,\n                              const volatile void *barrier) {}\nvoid AnnotateBarrierDestroy(const char *file, int line,\n                            const volatile void *barrier) {}\n\nvoid AnnotateCondVarWait(const char *file, int line,\n                         const volatile void *cv,\n                         const volatile void *lock){}\nvoid AnnotateCondVarSignal(const char *file, int line,\n                           const volatile void *cv){}\nvoid AnnotateCondVarSignalAll(const char *file, int line,\n                              const volatile void *cv){}\nvoid AnnotatePublishMemoryRange(const char *file, int line,\n                                const volatile void *address,\n                                long size){}\nvoid AnnotateUnpublishMemoryRange(const char *file, int line,\n                                  const volatile void *address,\n                                  long size){}\nvoid AnnotatePCQCreate(const char *file, int line,\n                       const volatile void *pcq){}\nvoid AnnotatePCQDestroy(const char *file, int line,\n                        const volatile void *pcq){}\nvoid AnnotatePCQPut(const char *file, int line,\n                    const volatile void *pcq){}\nvoid AnnotatePCQGet(const char *file, int line,\n                    const volatile void *pcq){}\nvoid AnnotateNewMemory(const char *file, int line,\n                       const volatile void *mem,\n                       long size){}\nvoid AnnotateExpectRace(const char *file, int line,\n                        const volatile void *mem,\n                        const char *description){}\nvoid AnnotateBenignRace(const char *file, int line,\n                        const volatile void *mem,\n                        const char *description){}\nvoid AnnotateBenignRaceSized(const char *file, int line,\n                             const volatile void *mem,\n                             long size,\n                             const char *description) {}\nvoid AnnotateMutexIsUsedAsCondVar(const char *file, int line,\n                                  const volatile void *mu){}\nvoid AnnotateTraceMemory(const char *file, int line,\n                         const volatile void *arg){}\nvoid AnnotateThreadName(const char *file, int line,\n                        const char *name){}\nvoid AnnotateIgnoreReadsBegin(const char *file, int line){}\nvoid AnnotateIgnoreReadsEnd(const char *file, int line){}\nvoid AnnotateIgnoreWritesBegin(const char *file, int line){}\nvoid AnnotateIgnoreWritesEnd(const char *file, int line){}\nvoid AnnotateEnableRaceDetection(const char *file, int line, int enable){}\nvoid AnnotateNoOp(const char *file, int line,\n                  const volatile void *arg){}\nvoid AnnotateFlushState(const char *file, int line){}\n\n#endif  /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */\n\nstatic int GetRunningOnValgrind(void) {\n#ifdef RUNNING_ON_VALGRIND\n  if (RUNNING_ON_VALGRIND) return 1;\n#endif\n#ifdef _MSC_VER\n  /* Visual Studio can complain about getenv, so use a windows equivalent. */\n  char value[100] = \"1\";    /* something that is not \"0\" */\n  int res = GetEnvironmentVariableA(\"RUNNING_ON_VALGRIND\",\n                                    value, sizeof(value));\n  /* value will remain \"1\" if the called failed for some reason. */\n  return (res > 0 && strcmp(value, \"0\") != 0);\n#else\n  /* TODO(csilvers): use GetenvBeforeMain() instead?  Will need to\n   *                 change it to be extern \"C\".\n   */\n  char *running_on_valgrind_str = getenv(\"RUNNING_ON_VALGRIND\");\n  if (running_on_valgrind_str) {\n    return strcmp(running_on_valgrind_str, \"0\") != 0;\n  }\n  return 0;\n#endif\n}\n\n/* See the comments in dynamic_annotations.h */\nint RunningOnValgrind(void) {\n  static volatile int running_on_valgrind = -1;\n  int local_running_on_valgrind = running_on_valgrind;\n  /* C doesn't have thread-safe initialization of statics, and we\n     don't want to depend on pthread_once here, so hack it. */\n  ANNOTATE_BENIGN_RACE(&running_on_valgrind, \"safe hack\");\n  if (local_running_on_valgrind == -1)\n    running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();\n  return local_running_on_valgrind;\n}\n\n/* See the comments in dynamic_annotations.h */\ndouble ValgrindSlowdown(void) {\n  /* Same initialization hack as in RunningOnValgrind(). */\n  static volatile double slowdown = 0.0;\n  double local_slowdown = slowdown;\n  ANNOTATE_BENIGN_RACE(&slowdown, \"safe hack\");\n  if (RunningOnValgrind() == 0) {\n    return 1.0;\n  }\n  if (local_slowdown == 0.0) {\n    char *env = getenv(\"VALGRIND_SLOWDOWN\");\n    slowdown = local_slowdown = env ? atof(env) : 50.0;\n  }\n  return local_slowdown;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/dynamic_annotations.h",
    "content": "/* Copyright (c) 2008, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Kostya Serebryany\n */\n\n/* This file defines dynamic annotations for use with dynamic analysis\n   tool such as valgrind, PIN, etc.\n\n   Dynamic annotation is a source code annotation that affects\n   the generated code (that is, the annotation is not a comment).\n   Each such annotation is attached to a particular\n   instruction and/or to a particular object (address) in the program.\n\n   The annotations that should be used by users are macros in all upper-case\n   (e.g., ANNOTATE_NEW_MEMORY).\n\n   Actual implementation of these macros may differ depending on the\n   dynamic analysis tool being used.\n\n   See http://code.google.com/p/data-race-test/  for more information.\n\n   This file supports the following dynamic analysis tools:\n   - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero).\n      Macros are defined empty.\n   - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1).\n      Macros are defined as calls to non-inlinable empty functions\n      that are intercepted by Valgrind. */\n\n#ifndef BASE_DYNAMIC_ANNOTATIONS_H_\n#define BASE_DYNAMIC_ANNOTATIONS_H_\n\n#ifndef DYNAMIC_ANNOTATIONS_ENABLED\n# define DYNAMIC_ANNOTATIONS_ENABLED 0\n#endif\n\n#if DYNAMIC_ANNOTATIONS_ENABLED != 0\n\n  /* -------------------------------------------------------------\n     Annotations useful when implementing condition variables such as CondVar,\n     using conditional critical sections (Await/LockWhen) and when constructing\n     user-defined synchronization mechanisms.\n\n     The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can\n     be used to define happens-before arcs in user-defined synchronization\n     mechanisms:  the race detector will infer an arc from the former to the\n     latter when they share the same argument pointer.\n\n     Example 1 (reference counting):\n\n     void Unref() {\n       ANNOTATE_HAPPENS_BEFORE(&refcount_);\n       if (AtomicDecrementByOne(&refcount_) == 0) {\n         ANNOTATE_HAPPENS_AFTER(&refcount_);\n         delete this;\n       }\n     }\n\n     Example 2 (message queue):\n\n     void MyQueue::Put(Type *e) {\n       MutexLock lock(&mu_);\n       ANNOTATE_HAPPENS_BEFORE(e);\n       PutElementIntoMyQueue(e);\n     }\n\n     Type *MyQueue::Get() {\n       MutexLock lock(&mu_);\n       Type *e = GetElementFromMyQueue();\n       ANNOTATE_HAPPENS_AFTER(e);\n       return e;\n     }\n\n     Note: when possible, please use the existing reference counting and message\n     queue implementations instead of inventing new ones. */\n\n  /* Report that wait on the condition variable at address \"cv\" has succeeded\n     and the lock at address \"lock\" is held. */\n  #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \\\n    AnnotateCondVarWait(__FILE__, __LINE__, cv, lock)\n\n  /* Report that wait on the condition variable at \"cv\" has succeeded.  Variant\n     w/o lock. */\n  #define ANNOTATE_CONDVAR_WAIT(cv) \\\n    AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL)\n\n  /* Report that we are about to signal on the condition variable at address\n     \"cv\". */\n  #define ANNOTATE_CONDVAR_SIGNAL(cv) \\\n    AnnotateCondVarSignal(__FILE__, __LINE__, cv)\n\n  /* Report that we are about to signal_all on the condition variable at \"cv\". */\n  #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \\\n    AnnotateCondVarSignalAll(__FILE__, __LINE__, cv)\n\n  /* Annotations for user-defined synchronization mechanisms. */\n  #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj)\n  #define ANNOTATE_HAPPENS_AFTER(obj)  ANNOTATE_CONDVAR_WAIT(obj)\n\n  /* Report that the bytes in the range [pointer, pointer+size) are about\n     to be published safely. The race checker will create a happens-before\n     arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to\n     subsequent accesses to this memory.\n     Note: this annotation may not work properly if the race detector uses\n     sampling, i.e. does not observe all memory accesses.\n     */\n  #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \\\n    AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size)\n\n  /* DEPRECATED. Don't use it. */\n  #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \\\n    AnnotateUnpublishMemoryRange(__FILE__, __LINE__, pointer, size)\n\n  /* DEPRECATED. Don't use it. */\n  #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size)   \\\n    do {                                              \\\n      ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \\\n      ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size);   \\\n    } while (0)\n\n  /* Instruct the tool to create a happens-before arc between mu->Unlock() and\n     mu->Lock(). This annotation may slow down the race detector and hide real\n     races. Normally it is used only when it would be difficult to annotate each\n     of the mutex's critical sections individually using the annotations above.\n     This annotation makes sense only for hybrid race detectors. For pure\n     happens-before detectors this is a no-op. For more details see\n     http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */\n  #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \\\n    AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)\n\n  /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */\n  #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \\\n    AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu)\n\n  /* -------------------------------------------------------------\n     Annotations useful when defining memory allocators, or when memory that\n     was protected in one way starts to be protected in another. */\n\n  /* Report that a new memory at \"address\" of size \"size\" has been allocated.\n     This might be used when the memory has been retrieved from a free list and\n     is about to be reused, or when a the locking discipline for a variable\n     changes. */\n  #define ANNOTATE_NEW_MEMORY(address, size) \\\n    AnnotateNewMemory(__FILE__, __LINE__, address, size)\n\n  /* -------------------------------------------------------------\n     Annotations useful when defining FIFO queues that transfer data between\n     threads. */\n\n  /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at\n     address \"pcq\" has been created.  The ANNOTATE_PCQ_* annotations\n     should be used only for FIFO queues.  For non-FIFO queues use\n     ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */\n  #define ANNOTATE_PCQ_CREATE(pcq) \\\n    AnnotatePCQCreate(__FILE__, __LINE__, pcq)\n\n  /* Report that the queue at address \"pcq\" is about to be destroyed. */\n  #define ANNOTATE_PCQ_DESTROY(pcq) \\\n    AnnotatePCQDestroy(__FILE__, __LINE__, pcq)\n\n  /* Report that we are about to put an element into a FIFO queue at address\n     \"pcq\". */\n  #define ANNOTATE_PCQ_PUT(pcq) \\\n    AnnotatePCQPut(__FILE__, __LINE__, pcq)\n\n  /* Report that we've just got an element from a FIFO queue at address \"pcq\". */\n  #define ANNOTATE_PCQ_GET(pcq) \\\n    AnnotatePCQGet(__FILE__, __LINE__, pcq)\n\n  /* -------------------------------------------------------------\n     Annotations that suppress errors.  It is usually better to express the\n     program's synchronization using the other annotations, but these can\n     be used when all else fails. */\n\n  /* Report that we may have a benign race at \"pointer\", with size\n     \"sizeof(*(pointer))\". \"pointer\" must be a non-void* pointer.  Insert at the\n     point where \"pointer\" has been allocated, preferably close to the point\n     where the race happens.  See also ANNOTATE_BENIGN_RACE_STATIC. */\n  #define ANNOTATE_BENIGN_RACE(pointer, description) \\\n    AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \\\n                            sizeof(*(pointer)), description)\n\n  /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to\n     the memory range [address, address+size). */\n  #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \\\n    AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)\n\n  /* Request the analysis tool to ignore all reads in the current thread\n     until ANNOTATE_IGNORE_READS_END is called.\n     Useful to ignore intentional racey reads, while still checking\n     other reads and all writes.\n     See also ANNOTATE_UNPROTECTED_READ. */\n  #define ANNOTATE_IGNORE_READS_BEGIN() \\\n    AnnotateIgnoreReadsBegin(__FILE__, __LINE__)\n\n  /* Stop ignoring reads. */\n  #define ANNOTATE_IGNORE_READS_END() \\\n    AnnotateIgnoreReadsEnd(__FILE__, __LINE__)\n\n  /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */\n  #define ANNOTATE_IGNORE_WRITES_BEGIN() \\\n    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)\n\n  /* Stop ignoring writes. */\n  #define ANNOTATE_IGNORE_WRITES_END() \\\n    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)\n\n  /* Start ignoring all memory accesses (reads and writes). */\n  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \\\n    do {\\\n      ANNOTATE_IGNORE_READS_BEGIN();\\\n      ANNOTATE_IGNORE_WRITES_BEGIN();\\\n    }while(0)\\\n\n  /* Stop ignoring all memory accesses. */\n  #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \\\n    do {\\\n      ANNOTATE_IGNORE_WRITES_END();\\\n      ANNOTATE_IGNORE_READS_END();\\\n    }while(0)\\\n\n  /* Enable (enable!=0) or disable (enable==0) race detection for all threads.\n     This annotation could be useful if you want to skip expensive race analysis\n     during some period of program execution, e.g. during initialization. */\n  #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \\\n    AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)\n\n  /* -------------------------------------------------------------\n     Annotations useful for debugging. */\n\n  /* Request to trace every access to \"address\". */\n  #define ANNOTATE_TRACE_MEMORY(address) \\\n    AnnotateTraceMemory(__FILE__, __LINE__, address)\n\n  /* Report the current thread name to a race detector. */\n  #define ANNOTATE_THREAD_NAME(name) \\\n    AnnotateThreadName(__FILE__, __LINE__, name)\n\n  /* -------------------------------------------------------------\n     Annotations useful when implementing locks.  They are not\n     normally needed by modules that merely use locks.\n     The \"lock\" argument is a pointer to the lock object. */\n\n  /* Report that a lock has been created at address \"lock\". */\n  #define ANNOTATE_RWLOCK_CREATE(lock) \\\n    AnnotateRWLockCreate(__FILE__, __LINE__, lock)\n\n  /* Report that the lock at address \"lock\" is about to be destroyed. */\n  #define ANNOTATE_RWLOCK_DESTROY(lock) \\\n    AnnotateRWLockDestroy(__FILE__, __LINE__, lock)\n\n  /* Report that the lock at address \"lock\" has been acquired.\n     is_w=1 for writer lock, is_w=0 for reader lock. */\n  #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \\\n    AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)\n\n  /* Report that the lock at address \"lock\" is about to be released. */\n  #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \\\n    AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)\n\n  /* -------------------------------------------------------------\n     Annotations useful when implementing barriers.  They are not\n     normally needed by modules that merely use barriers.\n     The \"barrier\" argument is a pointer to the barrier object. */\n\n  /* Report that the \"barrier\" has been initialized with initial \"count\".\n   If 'reinitialization_allowed' is true, initialization is allowed to happen\n   multiple times w/o calling barrier_destroy() */\n  #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \\\n    AnnotateBarrierInit(__FILE__, __LINE__, barrier, count, \\\n                        reinitialization_allowed)\n\n  /* Report that we are about to enter barrier_wait(\"barrier\"). */\n  #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \\\n    AnnotateBarrierWaitBefore(__FILE__, __LINE__, barrier)\n\n  /* Report that we just exited barrier_wait(\"barrier\"). */\n  #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \\\n    AnnotateBarrierWaitAfter(__FILE__, __LINE__, barrier)\n\n  /* Report that the \"barrier\" has been destroyed. */\n  #define ANNOTATE_BARRIER_DESTROY(barrier) \\\n    AnnotateBarrierDestroy(__FILE__, __LINE__, barrier)\n\n  /* -------------------------------------------------------------\n     Annotations useful for testing race detectors. */\n\n  /* Report that we expect a race on the variable at \"address\".\n     Use only in unit tests for a race detector. */\n  #define ANNOTATE_EXPECT_RACE(address, description) \\\n    AnnotateExpectRace(__FILE__, __LINE__, address, description)\n\n  /* A no-op. Insert where you like to test the interceptors. */\n  #define ANNOTATE_NO_OP(arg) \\\n    AnnotateNoOp(__FILE__, __LINE__, arg)\n\n  /* Force the race detector to flush its state. The actual effect depends on\n   * the implementation of the detector. */\n  #define ANNOTATE_FLUSH_STATE() \\\n    AnnotateFlushState(__FILE__, __LINE__)\n\n\n#else  /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */\n\n  #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */\n  #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */\n  #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */\n  #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */\n  #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */\n  #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */\n  #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */\n  #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */\n  #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */\n  #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */\n  #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */\n  #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */\n  #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */\n  #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */\n  #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */\n  #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size)  /* empty */\n  #define ANNOTATE_SWAP_MEMORY_RANGE(address, size)  /* empty */\n  #define ANNOTATE_PCQ_CREATE(pcq) /* empty */\n  #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */\n  #define ANNOTATE_PCQ_PUT(pcq) /* empty */\n  #define ANNOTATE_PCQ_GET(pcq) /* empty */\n  #define ANNOTATE_NEW_MEMORY(address, size) /* empty */\n  #define ANNOTATE_EXPECT_RACE(address, description) /* empty */\n  #define ANNOTATE_BENIGN_RACE(address, description) /* empty */\n  #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */\n  #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */\n  #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */\n  #define ANNOTATE_TRACE_MEMORY(arg) /* empty */\n  #define ANNOTATE_THREAD_NAME(name) /* empty */\n  #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */\n  #define ANNOTATE_IGNORE_READS_END() /* empty */\n  #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */\n  #define ANNOTATE_IGNORE_WRITES_END() /* empty */\n  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */\n  #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */\n  #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */\n  #define ANNOTATE_NO_OP(arg) /* empty */\n  #define ANNOTATE_FLUSH_STATE() /* empty */\n\n#endif  /* DYNAMIC_ANNOTATIONS_ENABLED */\n\n/* Macro definitions for GCC attributes that allow static thread safety\n   analysis to recognize and use some of the dynamic annotations as\n   escape hatches.\n   TODO(lcwu): remove the check for __SUPPORT_DYN_ANNOTATION__ once the\n   default crosstool/GCC supports these GCC attributes.  */\n\n#define ANNOTALYSIS_STATIC_INLINE\n#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY ;\n\n#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) \\\n  && (!defined(SWIG)) && defined(__SUPPORT_DYN_ANNOTATION__)\n\n#if DYNAMIC_ANNOTATIONS_ENABLED == 0\n#define ANNOTALYSIS_ONLY 1\n#undef ANNOTALYSIS_STATIC_INLINE\n#define ANNOTALYSIS_STATIC_INLINE static inline\n#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY\n#define ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY {}\n#endif\n#define ANNOTALYSIS_IGNORE_READS_BEGIN   __attribute__ ((ignore_reads_begin))\n#define ANNOTALYSIS_IGNORE_READS_END     __attribute__ ((ignore_reads_end))\n#define ANNOTALYSIS_IGNORE_WRITES_BEGIN  __attribute__ ((ignore_writes_begin))\n#define ANNOTALYSIS_IGNORE_WRITES_END    __attribute__ ((ignore_writes_end))\n#define ANNOTALYSIS_UNPROTECTED_READ     __attribute__ ((unprotected_read))\n\n#else\n\n#define ANNOTALYSIS_IGNORE_READS_BEGIN\n#define ANNOTALYSIS_IGNORE_READS_END\n#define ANNOTALYSIS_IGNORE_WRITES_BEGIN\n#define ANNOTALYSIS_IGNORE_WRITES_END\n#define ANNOTALYSIS_UNPROTECTED_READ\n\n#endif\n\n/* Use the macros above rather than using these functions directly. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nvoid AnnotateRWLockCreate(const char *file, int line,\n                          const volatile void *lock);\nvoid AnnotateRWLockDestroy(const char *file, int line,\n                           const volatile void *lock);\nvoid AnnotateRWLockAcquired(const char *file, int line,\n                            const volatile void *lock, long is_w);\nvoid AnnotateRWLockReleased(const char *file, int line,\n                            const volatile void *lock, long is_w);\nvoid AnnotateBarrierInit(const char *file, int line,\n                         const volatile void *barrier, long count,\n                         long reinitialization_allowed);\nvoid AnnotateBarrierWaitBefore(const char *file, int line,\n                               const volatile void *barrier);\nvoid AnnotateBarrierWaitAfter(const char *file, int line,\n                              const volatile void *barrier);\nvoid AnnotateBarrierDestroy(const char *file, int line,\n                            const volatile void *barrier);\nvoid AnnotateCondVarWait(const char *file, int line,\n                         const volatile void *cv,\n                         const volatile void *lock);\nvoid AnnotateCondVarSignal(const char *file, int line,\n                           const volatile void *cv);\nvoid AnnotateCondVarSignalAll(const char *file, int line,\n                              const volatile void *cv);\nvoid AnnotatePublishMemoryRange(const char *file, int line,\n                                const volatile void *address,\n                                long size);\nvoid AnnotateUnpublishMemoryRange(const char *file, int line,\n                                  const volatile void *address,\n                                  long size);\nvoid AnnotatePCQCreate(const char *file, int line,\n                       const volatile void *pcq);\nvoid AnnotatePCQDestroy(const char *file, int line,\n                        const volatile void *pcq);\nvoid AnnotatePCQPut(const char *file, int line,\n                    const volatile void *pcq);\nvoid AnnotatePCQGet(const char *file, int line,\n                    const volatile void *pcq);\nvoid AnnotateNewMemory(const char *file, int line,\n                       const volatile void *address,\n                       long size);\nvoid AnnotateExpectRace(const char *file, int line,\n                        const volatile void *address,\n                        const char *description);\nvoid AnnotateBenignRace(const char *file, int line,\n                        const volatile void *address,\n                        const char *description);\nvoid AnnotateBenignRaceSized(const char *file, int line,\n                        const volatile void *address,\n                        long size,\n                        const char *description);\nvoid AnnotateMutexIsUsedAsCondVar(const char *file, int line,\n                                  const volatile void *mu);\nvoid AnnotateTraceMemory(const char *file, int line,\n                         const volatile void *arg);\nvoid AnnotateThreadName(const char *file, int line,\n                        const char *name);\nANNOTALYSIS_STATIC_INLINE\nvoid AnnotateIgnoreReadsBegin(const char *file, int line)\n    ANNOTALYSIS_IGNORE_READS_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY\nANNOTALYSIS_STATIC_INLINE\nvoid AnnotateIgnoreReadsEnd(const char *file, int line)\n    ANNOTALYSIS_IGNORE_READS_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY\nANNOTALYSIS_STATIC_INLINE\nvoid AnnotateIgnoreWritesBegin(const char *file, int line)\n    ANNOTALYSIS_IGNORE_WRITES_BEGIN ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY\nANNOTALYSIS_STATIC_INLINE\nvoid AnnotateIgnoreWritesEnd(const char *file, int line)\n    ANNOTALYSIS_IGNORE_WRITES_END ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY\nvoid AnnotateEnableRaceDetection(const char *file, int line, int enable);\nvoid AnnotateNoOp(const char *file, int line,\n                  const volatile void *arg);\nvoid AnnotateFlushState(const char *file, int line);\n\n/* Return non-zero value if running under valgrind.\n\n  If \"valgrind.h\" is included into dynamic_annotations.c,\n  the regular valgrind mechanism will be used.\n  See http://valgrind.org/docs/manual/manual-core-adv.html about\n  RUNNING_ON_VALGRIND and other valgrind \"client requests\".\n  The file \"valgrind.h\" may be obtained by doing\n     svn co svn://svn.valgrind.org/valgrind/trunk/include\n\n  If for some reason you can't use \"valgrind.h\" or want to fake valgrind,\n  there are two ways to make this function return non-zero:\n    - Use environment variable: export RUNNING_ON_VALGRIND=1\n    - Make your tool intercept the function RunningOnValgrind() and\n      change its return value.\n */\nint RunningOnValgrind(void);\n\n/* ValgrindSlowdown returns:\n    * 1.0, if (RunningOnValgrind() == 0)\n    * 50.0, if (RunningOnValgrind() != 0 && getenv(\"VALGRIND_SLOWDOWN\") == NULL)\n    * atof(getenv(\"VALGRIND_SLOWDOWN\")) otherwise\n   This function can be used to scale timeout values:\n   EXAMPLE:\n   for (;;) {\n     DoExpensiveBackgroundTask();\n     SleepForSeconds(5 * ValgrindSlowdown());\n   }\n */\ndouble ValgrindSlowdown(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)\n\n  /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.\n\n     Instead of doing\n        ANNOTATE_IGNORE_READS_BEGIN();\n        ... = x;\n        ANNOTATE_IGNORE_READS_END();\n     one can use\n        ... = ANNOTATE_UNPROTECTED_READ(x); */\n  template <class T>\n  inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x)\n      ANNOTALYSIS_UNPROTECTED_READ {\n    ANNOTATE_IGNORE_READS_BEGIN();\n    T res = x;\n    ANNOTATE_IGNORE_READS_END();\n    return res;\n  }\n  /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */\n  #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)        \\\n    namespace {                                                       \\\n      class static_var ## _annotator {                                \\\n       public:                                                        \\\n        static_var ## _annotator() {                                  \\\n          ANNOTATE_BENIGN_RACE_SIZED(&static_var,                     \\\n                                      sizeof(static_var),             \\\n            # static_var \": \" description);                           \\\n        }                                                             \\\n      };                                                              \\\n      static static_var ## _annotator the ## static_var ## _annotator;\\\n    }\n#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */\n\n  #define ANNOTATE_UNPROTECTED_READ(x) (x)\n  #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)  /* empty */\n\n#endif /* DYNAMIC_ANNOTATIONS_ENABLED */\n\n/* Annotalysis, a GCC based static analyzer, is able to understand and use\n   some of the dynamic annotations defined in this file. However, dynamic\n   annotations are usually disabled in the opt mode (to avoid additional\n   runtime overheads) while Annotalysis only works in the opt mode.\n   In order for Annotalysis to use these dynamic annotations when they\n   are disabled, we re-define these annotations here. Note that unlike the\n   original macro definitions above, these macros are expanded to calls to\n   static inline functions so that the compiler will be able to remove the\n   calls after the analysis. */\n\n#ifdef ANNOTALYSIS_ONLY\n\n  #undef ANNOTALYSIS_ONLY\n\n  /* Undefine and re-define the macros that the static analyzer understands. */\n  #undef ANNOTATE_IGNORE_READS_BEGIN\n  #define ANNOTATE_IGNORE_READS_BEGIN()           \\\n    AnnotateIgnoreReadsBegin(__FILE__, __LINE__)\n\n  #undef ANNOTATE_IGNORE_READS_END\n  #define ANNOTATE_IGNORE_READS_END()             \\\n    AnnotateIgnoreReadsEnd(__FILE__, __LINE__)\n\n  #undef ANNOTATE_IGNORE_WRITES_BEGIN\n  #define ANNOTATE_IGNORE_WRITES_BEGIN()          \\\n    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)\n\n  #undef ANNOTATE_IGNORE_WRITES_END\n  #define ANNOTATE_IGNORE_WRITES_END()            \\\n    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)\n\n  #undef ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN\n  #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN()       \\\n    do {                                                 \\\n      ANNOTATE_IGNORE_READS_BEGIN();                     \\\n      ANNOTATE_IGNORE_WRITES_BEGIN();                    \\\n    }while(0)                                            \\\n\n  #undef ANNOTATE_IGNORE_READS_AND_WRITES_END\n  #define ANNOTATE_IGNORE_READS_AND_WRITES_END()  \\\n    do {                                          \\\n      ANNOTATE_IGNORE_WRITES_END();               \\\n      ANNOTATE_IGNORE_READS_END();                \\\n    }while(0)                                     \\\n\n  #if defined(__cplusplus)\n    #undef ANNOTATE_UNPROTECTED_READ\n    template <class T>\n    inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x)\n        __attribute__ ((unprotected_read)) {\n      ANNOTATE_IGNORE_READS_BEGIN();\n      T res = x;\n      ANNOTATE_IGNORE_READS_END();\n      return res;\n    }\n  #endif /* __cplusplus */\n\n#endif /* ANNOTALYSIS_ONLY */\n\n/* Undefine the macros intended only in this file. */\n#undef ANNOTALYSIS_STATIC_INLINE\n#undef ANNOTALYSIS_SEMICOLON_OR_EMPTY_BODY\n\n#endif  /* BASE_DYNAMIC_ANNOTATIONS_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/elfcore.h",
    "content": "/* Copyright (c) 2005-2008, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Markus Gutschke, Carl Crous\n */\n\n#ifndef _ELFCORE_H\n#define _ELFCORE_H\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* We currently only support x86-32, x86-64, ARM, and MIPS on Linux.\n * Porting to other related platforms should not be difficult.\n */\n#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \\\n     defined(__mips__)) && defined(__linux)\n\n#include <stdarg.h>\n#include <stdint.h>\n#include <sys/types.h>\n#include <config.h>\n\n\n/* Define the DUMPER symbol to make sure that there is exactly one\n * core dumper built into the library.\n */\n#define DUMPER \"ELF\"\n\n/* By the time that we get a chance to read CPU registers in the\n * calling thread, they are already in a not particularly useful\n * state. Besides, there will be multiple frames on the stack that are\n * just making the core file confusing. To fix this problem, we take a\n * snapshot of the frame pointer, stack pointer, and instruction\n * pointer at an earlier time, and then insert these values into the\n * core file.\n */\n\n#if defined(__i386__) || defined(__x86_64__)\n  typedef struct i386_regs {    /* Normal (non-FPU) CPU registers            */\n  #ifdef __x86_64__\n    #define BP rbp\n    #define SP rsp\n    #define IP rip\n    uint64_t  r15,r14,r13,r12,rbp,rbx,r11,r10;\n    uint64_t  r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;\n    uint64_t  rip,cs,eflags;\n    uint64_t  rsp,ss;\n    uint64_t  fs_base, gs_base;\n    uint64_t  ds,es,fs,gs;\n  #else\n    #define BP ebp\n    #define SP esp\n    #define IP eip\n    uint32_t  ebx, ecx, edx, esi, edi, ebp, eax;\n    uint16_t  ds, __ds, es, __es;\n    uint16_t  fs, __fs, gs, __gs;\n    uint32_t  orig_eax, eip;\n    uint16_t  cs, __cs;\n    uint32_t  eflags, esp;\n    uint16_t  ss, __ss;\n  #endif\n  } i386_regs;\n#elif defined(__ARM_ARCH_3__)\n  typedef struct arm_regs {     /* General purpose registers                 */\n    #define BP uregs[11]        /* Frame pointer                             */\n    #define SP uregs[13]        /* Stack pointer                             */\n    #define IP uregs[15]        /* Program counter                           */\n    #define LR uregs[14]        /* Link register                             */\n    long uregs[18];\n  } arm_regs;\n#elif defined(__mips__)\n  typedef struct mips_regs {\n    unsigned long pad[6];       /* Unused padding to match kernel structures */\n    unsigned long uregs[32];    /* General purpose registers.                */\n    unsigned long hi;           /* Used for multiplication and division.     */\n    unsigned long lo;\n    unsigned long cp0_epc;      /* Program counter.                          */\n    unsigned long cp0_badvaddr;\n    unsigned long cp0_status;\n    unsigned long cp0_cause;\n    unsigned long unused;\n  } mips_regs;\n#endif\n\n#if defined(__i386__) && defined(__GNUC__)\n  /* On x86 we provide an optimized version of the FRAME() macro, if the\n   * compiler supports a GCC-style asm() directive. This results in somewhat\n   * more accurate values for CPU registers.\n   */\n  typedef struct Frame {\n    struct i386_regs uregs;\n    int              errno_;\n    pid_t            tid;\n  } Frame;\n  #define FRAME(f) Frame f;                                           \\\n                   do {                                               \\\n                     f.errno_ = errno;                                \\\n                     f.tid    = sys_gettid();                         \\\n                     __asm__ volatile (                               \\\n                       \"push %%ebp\\n\"                                 \\\n                       \"push %%ebx\\n\"                                 \\\n                       \"mov  %%ebx,0(%%eax)\\n\"                        \\\n                       \"mov  %%ecx,4(%%eax)\\n\"                        \\\n                       \"mov  %%edx,8(%%eax)\\n\"                        \\\n                       \"mov  %%esi,12(%%eax)\\n\"                       \\\n                       \"mov  %%edi,16(%%eax)\\n\"                       \\\n                       \"mov  %%ebp,20(%%eax)\\n\"                       \\\n                       \"mov  %%eax,24(%%eax)\\n\"                       \\\n                       \"mov  %%ds,%%ebx\\n\"                            \\\n                       \"mov  %%ebx,28(%%eax)\\n\"                       \\\n                       \"mov  %%es,%%ebx\\n\"                            \\\n                       \"mov  %%ebx,32(%%eax)\\n\"                       \\\n                       \"mov  %%fs,%%ebx\\n\"                            \\\n                       \"mov  %%ebx,36(%%eax)\\n\"                       \\\n                       \"mov  %%gs,%%ebx\\n\"                            \\\n                       \"mov  %%ebx, 40(%%eax)\\n\"                      \\\n                       \"call 0f\\n\"                                    \\\n                     \"0:pop %%ebx\\n\"                                  \\\n                       \"add  $1f-0b,%%ebx\\n\"                          \\\n                       \"mov  %%ebx,48(%%eax)\\n\"                       \\\n                       \"mov  %%cs,%%ebx\\n\"                            \\\n                       \"mov  %%ebx,52(%%eax)\\n\"                       \\\n                       \"pushf\\n\"                                      \\\n                       \"pop  %%ebx\\n\"                                 \\\n                       \"mov  %%ebx,56(%%eax)\\n\"                       \\\n                       \"mov  %%esp,%%ebx\\n\"                           \\\n                       \"add  $8,%%ebx\\n\"                              \\\n                       \"mov  %%ebx,60(%%eax)\\n\"                       \\\n                       \"mov  %%ss,%%ebx\\n\"                            \\\n                       \"mov  %%ebx,64(%%eax)\\n\"                       \\\n                       \"pop  %%ebx\\n\"                                 \\\n                       \"pop  %%ebp\\n\"                                 \\\n                     \"1:\"                                             \\\n                       : : \"a\" (&f) : \"memory\");                      \\\n                     } while (0)\n  #define SET_FRAME(f,r)                                              \\\n                     do {                                             \\\n                       errno = (f).errno_;                            \\\n                       (r)   = (f).uregs;                             \\\n                     } while (0)\n#elif defined(__x86_64__) && defined(__GNUC__)\n  /* The FRAME and SET_FRAME macros for x86_64.  */\n  typedef struct Frame {\n    struct i386_regs uregs;\n    int              errno_;\n    pid_t            tid;\n  } Frame;\n  #define FRAME(f) Frame f;                                           \\\n                   do {                                               \\\n                     f.errno_ = errno;                                \\\n                     f.tid    = sys_gettid();                         \\\n                     __asm__ volatile (                               \\\n                       \"push %%rbp\\n\"                                 \\\n                       \"push %%rbx\\n\"                                 \\\n                       \"mov  %%r15,0(%%rax)\\n\"                        \\\n                       \"mov  %%r14,8(%%rax)\\n\"                        \\\n                       \"mov  %%r13,16(%%rax)\\n\"                       \\\n                       \"mov  %%r12,24(%%rax)\\n\"                       \\\n                       \"mov  %%rbp,32(%%rax)\\n\"                       \\\n                       \"mov  %%rbx,40(%%rax)\\n\"                       \\\n                       \"mov  %%r11,48(%%rax)\\n\"                       \\\n                       \"mov  %%r10,56(%%rax)\\n\"                       \\\n                       \"mov  %%r9,64(%%rax)\\n\"                        \\\n                       \"mov  %%r8,72(%%rax)\\n\"                        \\\n                       \"mov  %%rax,80(%%rax)\\n\"                       \\\n                       \"mov  %%rcx,88(%%rax)\\n\"                       \\\n                       \"mov  %%rdx,96(%%rax)\\n\"                       \\\n                       \"mov  %%rsi,104(%%rax)\\n\"                      \\\n                       \"mov  %%rdi,112(%%rax)\\n\"                      \\\n                       \"mov  %%ds,%%rbx\\n\"                            \\\n                       \"mov  %%rbx,184(%%rax)\\n\"                      \\\n                       \"mov  %%es,%%rbx\\n\"                            \\\n                       \"mov  %%rbx,192(%%rax)\\n\"                      \\\n                       \"mov  %%fs,%%rbx\\n\"                            \\\n                       \"mov  %%rbx,200(%%rax)\\n\"                      \\\n                       \"mov  %%gs,%%rbx\\n\"                            \\\n                       \"mov  %%rbx,208(%%rax)\\n\"                      \\\n                       \"call 0f\\n\"                                    \\\n                     \"0:pop %%rbx\\n\"                                  \\\n                       \"add  $1f-0b,%%rbx\\n\"                          \\\n                       \"mov  %%rbx,128(%%rax)\\n\"                      \\\n                       \"mov  %%cs,%%rbx\\n\"                            \\\n                       \"mov  %%rbx,136(%%rax)\\n\"                      \\\n                       \"pushf\\n\"                                      \\\n                       \"pop  %%rbx\\n\"                                 \\\n                       \"mov  %%rbx,144(%%rax)\\n\"                      \\\n                       \"mov  %%rsp,%%rbx\\n\"                           \\\n                       \"add  $16,%%ebx\\n\"                             \\\n                       \"mov  %%rbx,152(%%rax)\\n\"                      \\\n                       \"mov  %%ss,%%rbx\\n\"                            \\\n                       \"mov  %%rbx,160(%%rax)\\n\"                      \\\n                       \"pop  %%rbx\\n\"                                 \\\n                       \"pop  %%rbp\\n\"                                 \\\n                     \"1:\"                                             \\\n                       : : \"a\" (&f) : \"memory\");                      \\\n                     } while (0)\n  #define SET_FRAME(f,r)                                              \\\n                     do {                                             \\\n                       errno = (f).errno_;                            \\\n                       (f).uregs.fs_base = (r).fs_base;               \\\n                       (f).uregs.gs_base = (r).gs_base;               \\\n                       (r)   = (f).uregs;                             \\\n                     } while (0)\n#elif defined(__ARM_ARCH_3__) && defined(__GNUC__)\n  /* ARM calling conventions are a little more tricky. A little assembly\n   * helps in obtaining an accurate snapshot of all registers.\n   */\n  typedef struct Frame {\n    struct arm_regs arm;\n    int             errno_;\n    pid_t           tid;\n  } Frame;\n  #define FRAME(f) Frame f;                                           \\\n                   do {                                               \\\n                     long cpsr;                                       \\\n                     f.errno_ = errno;                                \\\n                     f.tid    = sys_gettid();                         \\\n                     __asm__ volatile(                                \\\n                       \"stmia %0, {r0-r15}\\n\" /* All integer regs   */\\\n                       : : \"r\"(&f.arm) : \"memory\");                   \\\n                     f.arm.uregs[16] = 0;                             \\\n                     __asm__ volatile(                                \\\n                       \"mrs %0, cpsr\\n\"       /* Condition code reg */\\\n                       : \"=r\"(cpsr));                                 \\\n                     f.arm.uregs[17] = cpsr;                          \\\n                   } while (0)\n  #define SET_FRAME(f,r)                                              \\\n                     do {                                             \\\n                       /* Don't override the FPU status register.   */\\\n                       /* Use the value obtained from ptrace(). This*/\\\n                       /* works, because our code does not perform  */\\\n                       /* any FPU operations, itself.               */\\\n                       long fps      = (f).arm.uregs[16];             \\\n                       errno         = (f).errno_;                    \\\n                       (r)           = (f).arm;                       \\\n                       (r).uregs[16] = fps;                           \\\n                     } while (0)\n#elif defined(__mips__) && defined(__GNUC__)\n  typedef struct Frame {\n    struct mips_regs mips_regs;\n    int              errno_;\n    pid_t            tid;\n  } Frame;\n  #define MIPSREG(n) ({ register unsigned long r __asm__(\"$\"#n); r; })\n  #define FRAME(f) Frame f = { 0 };                                   \\\n                   do {                                               \\\n                     unsigned long hi, lo;                            \\\n                     register unsigned long pc __asm__(\"$31\");        \\\n                     f.mips_regs.uregs[ 0] = MIPSREG( 0);             \\\n                     f.mips_regs.uregs[ 1] = MIPSREG( 1);             \\\n                     f.mips_regs.uregs[ 2] = MIPSREG( 2);             \\\n                     f.mips_regs.uregs[ 3] = MIPSREG( 3);             \\\n                     f.mips_regs.uregs[ 4] = MIPSREG( 4);             \\\n                     f.mips_regs.uregs[ 5] = MIPSREG( 5);             \\\n                     f.mips_regs.uregs[ 6] = MIPSREG( 6);             \\\n                     f.mips_regs.uregs[ 7] = MIPSREG( 7);             \\\n                     f.mips_regs.uregs[ 8] = MIPSREG( 8);             \\\n                     f.mips_regs.uregs[ 9] = MIPSREG( 9);             \\\n                     f.mips_regs.uregs[10] = MIPSREG(10);             \\\n                     f.mips_regs.uregs[11] = MIPSREG(11);             \\\n                     f.mips_regs.uregs[12] = MIPSREG(12);             \\\n                     f.mips_regs.uregs[13] = MIPSREG(13);             \\\n                     f.mips_regs.uregs[14] = MIPSREG(14);             \\\n                     f.mips_regs.uregs[15] = MIPSREG(15);             \\\n                     f.mips_regs.uregs[16] = MIPSREG(16);             \\\n                     f.mips_regs.uregs[17] = MIPSREG(17);             \\\n                     f.mips_regs.uregs[18] = MIPSREG(18);             \\\n                     f.mips_regs.uregs[19] = MIPSREG(19);             \\\n                     f.mips_regs.uregs[20] = MIPSREG(20);             \\\n                     f.mips_regs.uregs[21] = MIPSREG(21);             \\\n                     f.mips_regs.uregs[22] = MIPSREG(22);             \\\n                     f.mips_regs.uregs[23] = MIPSREG(23);             \\\n                     f.mips_regs.uregs[24] = MIPSREG(24);             \\\n                     f.mips_regs.uregs[25] = MIPSREG(25);             \\\n                     f.mips_regs.uregs[26] = MIPSREG(26);             \\\n                     f.mips_regs.uregs[27] = MIPSREG(27);             \\\n                     f.mips_regs.uregs[28] = MIPSREG(28);             \\\n                     f.mips_regs.uregs[29] = MIPSREG(29);             \\\n                     f.mips_regs.uregs[30] = MIPSREG(30);             \\\n                     f.mips_regs.uregs[31] = MIPSREG(31);             \\\n                     __asm__ volatile (\"mfhi %0\" : \"=r\"(hi));         \\\n                     __asm__ volatile (\"mflo %0\" : \"=r\"(lo));         \\\n                     __asm__ volatile (\"jal 1f; 1:nop\" : \"=r\"(pc));   \\\n                     f.mips_regs.hi       = hi;                       \\\n                     f.mips_regs.lo       = lo;                       \\\n                     f.mips_regs.cp0_epc  = pc;                       \\\n                     f.errno_             = errno;                    \\\n                     f.tid                = sys_gettid();             \\\n                   } while (0)\n  #define SET_FRAME(f,r)                                              \\\n                   do {                                               \\\n                     errno       = (f).errno_;                        \\\n                     memcpy((r).uregs, (f).mips_regs.uregs,           \\\n                            32*sizeof(unsigned long));                \\\n                     (r).hi      = (f).mips_regs.hi;                  \\\n                     (r).lo      = (f).mips_regs.lo;                  \\\n                     (r).cp0_epc = (f).mips_regs.cp0_epc;             \\\n                   } while (0)\n#else\n  /* If we do not have a hand-optimized assembly version of the FRAME()\n   * macro, we cannot reliably unroll the stack. So, we show a few additional\n   * stack frames for the coredumper.\n   */\n  typedef struct Frame {\n    pid_t tid;\n  } Frame;\n  #define FRAME(f) Frame f; do { f.tid = sys_gettid(); } while (0)\n  #define SET_FRAME(f,r) do { } while (0)\n#endif\n\n\n/* Internal function for generating a core file. This API can change without\n * notice and is only supposed to be used internally by the core dumper.\n *\n * This function works for both single- and multi-threaded core\n * dumps. If called as\n *\n *   FRAME(frame);\n *   InternalGetCoreDump(&frame, 0, NULL, ap);\n *\n * it creates a core file that only contains information about the\n * calling thread.\n *\n * Optionally, the caller can provide information about other threads\n * by passing their process ids in \"thread_pids\". The process id of\n * the caller should not be included in this array. All of the threads\n * must have been attached to with ptrace(), prior to calling this\n * function. They will be detached when \"InternalGetCoreDump()\" returns.\n *\n * This function either returns a file handle that can be read for obtaining\n * a core dump, or \"-1\" in case of an error. In the latter case, \"errno\"\n * will be set appropriately.\n *\n * While \"InternalGetCoreDump()\" is not technically async signal safe, you\n * might be tempted to invoke it from a signal handler. The code goes to\n * great lengths to make a best effort that this will actually work. But in\n * any case, you must make sure that you preserve the value of \"errno\"\n * yourself. It is guaranteed to be clobbered otherwise.\n *\n * Also, \"InternalGetCoreDump\" is not strictly speaking re-entrant. Again,\n * it makes a best effort to behave reasonably when called in a multi-\n * threaded environment, but it is ultimately the caller's responsibility\n * to provide locking.\n */\nint InternalGetCoreDump(void *frame, int num_threads, pid_t *thread_pids,\n                        va_list ap\n                     /* const struct CoreDumpParameters *params,\n                        const char *file_name,\n                        const char *PATH\n                      */);\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif /* _ELFCORE_H */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/googleinit.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Jacob Hoffman-Andrews\n\n#ifndef _GOOGLEINIT_H\n#define _GOOGLEINIT_H\n\nclass GoogleInitializer {\n public:\n  typedef void (*void_function)(void);\n  GoogleInitializer(const char* name, void_function f) {\n    f();\n  }\n};\n\n#define REGISTER_MODULE_INITIALIZER(name, body)                 \\\n  namespace {                                                   \\\n    static void google_init_module_##name () { body; }          \\\n    GoogleInitializer google_initializer_module_##name(#name,   \\\n            google_init_module_##name);                         \\\n  }\n\n#endif /* _GOOGLEINIT_H */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/linux_syscall_support.h",
    "content": "/* Copyright (c) 2005-2008, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Markus Gutschke\n */\n\n/* This file includes Linux-specific support functions common to the\n * coredumper and the thread lister; primarily, this is a collection\n * of direct system calls, and a couple of symbols missing from\n * standard header files.\n * There are a few options that the including file can set to control\n * the behavior of this file:\n *\n * SYS_CPLUSPLUS:\n *   The entire header file will normally be wrapped in 'extern \"C\" { }\",\n *   making it suitable for compilation as both C and C++ source. If you\n *   do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit\n *   the wrapping. N.B. doing so will suppress inclusion of all prerequisite\n *   system header files, too. It is the caller's responsibility to provide\n *   the necessary definitions.\n *\n * SYS_ERRNO:\n *   All system calls will update \"errno\" unless overriden by setting the\n *   SYS_ERRNO macro prior to including this file. SYS_ERRNO should be\n *   an l-value.\n *\n * SYS_INLINE:\n *   New symbols will be defined \"static inline\", unless overridden by\n *   the SYS_INLINE macro.\n *\n * SYS_LINUX_SYSCALL_SUPPORT_H\n *   This macro is used to avoid multiple inclusions of this header file.\n *   If you need to include this file more than once, make sure to\n *   unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.\n *\n * SYS_PREFIX:\n *   New system calls will have a prefix of \"sys_\" unless overridden by\n *   the SYS_PREFIX macro. Valid values for this macro are [0..9] which\n *   results in prefixes \"sys[0..9]_\". It is also possible to set this\n *   macro to -1, which avoids all prefixes.\n *\n * This file defines a few internal symbols that all start with \"LSS_\".\n * Do not access these symbols from outside this file. They are not part\n * of the supported API.\n */\n#ifndef SYS_LINUX_SYSCALL_SUPPORT_H\n#define SYS_LINUX_SYSCALL_SUPPORT_H\n\n/* We currently only support x86-32, x86-64, ARM, MIPS, and PPC on Linux.\n * Porting to other related platforms should not be difficult.\n */\n#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) ||   \\\n     defined(__mips__) || defined(__PPC__)) && defined(__linux)\n\n#ifndef SYS_CPLUSPLUS\n#ifdef __cplusplus\n/* Some system header files in older versions of gcc neglect to properly\n * handle being included from C++. As it appears to be harmless to have\n * multiple nested 'extern \"C\"' blocks, just add another one here.\n */\nextern \"C\" {\n#endif\n\n#include <errno.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <string.h>\n#include <sys/ptrace.h>\n#include <sys/resource.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <syscall.h>\n#include <unistd.h>\n#include <linux/unistd.h>\n#include <endian.h>\n\n#ifdef __mips__\n/* Include definitions of the ABI currently in use.                          */\n#include <sgidefs.h>\n#endif\n\n#endif\n\n/* As glibc often provides subtly incompatible data structures (and implicit\n * wrapper functions that convert them), we provide our own kernel data\n * structures for use by the system calls.\n * These structures have been developed by using Linux 2.6.23 headers for\n * reference. Note though, we do not care about exact API compatibility\n * with the kernel, and in fact the kernel often does not have a single\n * API that works across architectures. Instead, we try to mimic the glibc\n * API where reasonable, and only guarantee ABI compatibility with the\n * kernel headers.\n * Most notably, here are a few changes that were made to the structures\n * defined by kernel headers:\n *\n * - we only define structures, but not symbolic names for kernel data\n *   types. For the latter, we directly use the native C datatype\n *   (i.e. \"unsigned\" instead of \"mode_t\").\n * - in a few cases, it is possible to define identical structures for\n *   both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by\n *   standardizing on the 64bit version of the data types. In particular,\n *   this means that we use \"unsigned\" where the 32bit headers say\n *   \"unsigned long\".\n * - overall, we try to minimize the number of cases where we need to\n *   conditionally define different structures.\n * - the \"struct kernel_sigaction\" class of structures have been\n *   modified to more closely mimic glibc's API by introducing an\n *   anonymous union for the function pointer.\n * - a small number of field names had to have an underscore appended to\n *   them, because glibc defines a global macro by the same name.\n */\n\n/* include/linux/dirent.h                                                    */\nstruct kernel_dirent64 {\n  unsigned long long d_ino;\n  long long          d_off;\n  unsigned short     d_reclen;\n  unsigned char      d_type;\n  char               d_name[256];\n};\n\n/* include/linux/dirent.h                                                    */\nstruct kernel_dirent {\n  long               d_ino;\n  long               d_off;\n  unsigned short     d_reclen;\n  char               d_name[256];\n};\n\n/* include/linux/uio.h                                                       */\nstruct kernel_iovec {\n  void               *iov_base;\n  unsigned long      iov_len;\n};\n\n/* include/linux/socket.h                                                    */\nstruct kernel_msghdr {\n  void               *msg_name;\n  int                msg_namelen;\n  struct kernel_iovec*msg_iov;\n  unsigned long      msg_iovlen;\n  void               *msg_control;\n  unsigned long      msg_controllen;\n  unsigned           msg_flags;\n};\n\n/* include/asm-generic/poll.h                                                */\nstruct kernel_pollfd {\n  int                fd;\n  short              events;\n  short              revents;\n};\n\n/* include/linux/resource.h                                                  */\nstruct kernel_rlimit {\n  unsigned long      rlim_cur;\n  unsigned long      rlim_max;\n};\n\n/* include/linux/time.h                                                      */\nstruct kernel_timespec {\n  long               tv_sec;\n  long               tv_nsec;\n};\n\n/* include/linux/time.h                                                      */\nstruct kernel_timeval {\n  long               tv_sec;\n  long               tv_usec;\n};\n\n/* include/linux/resource.h                                                  */\nstruct kernel_rusage {\n  struct kernel_timeval ru_utime;\n  struct kernel_timeval ru_stime;\n  long               ru_maxrss;\n  long               ru_ixrss;\n  long               ru_idrss;\n  long               ru_isrss;\n  long               ru_minflt;\n  long               ru_majflt;\n  long               ru_nswap;\n  long               ru_inblock;\n  long               ru_oublock;\n  long               ru_msgsnd;\n  long               ru_msgrcv;\n  long               ru_nsignals;\n  long               ru_nvcsw;\n  long               ru_nivcsw;\n};\n\nstruct siginfo;\n#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__PPC__)\n\n/* include/asm-{arm,i386,mips,ppc}/signal.h                                  */\nstruct kernel_old_sigaction {\n  union {\n    void             (*sa_handler_)(int);\n    void             (*sa_sigaction_)(int, struct siginfo *, void *);\n  };\n  unsigned long      sa_mask;\n  unsigned long      sa_flags;\n  void               (*sa_restorer)(void);\n} __attribute__((packed,aligned(4)));\n#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)\n  #define kernel_old_sigaction kernel_sigaction\n#endif\n\n/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the\n * exactly match the size of the signal set, even though the API was\n * intended to be extensible. We define our own KERNEL_NSIG to deal with\n * this.\n * Please note that glibc provides signals [1.._NSIG-1], whereas the\n * kernel (and this header) provides the range [1..KERNEL_NSIG]. The\n * actual number of signals is obviously the same, but the constants\n * differ by one.\n */\n#ifdef __mips__\n#define KERNEL_NSIG 128\n#else\n#define KERNEL_NSIG  64\n#endif\n\n/* include/asm-{arm,i386,mips,x86_64}/signal.h                               */\nstruct kernel_sigset_t {\n  unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/\n                    (8*sizeof(unsigned long))];\n};\n\n/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h                           */\nstruct kernel_sigaction {\n#ifdef __mips__\n  unsigned long      sa_flags;\n  union {\n    void             (*sa_handler_)(int);\n    void             (*sa_sigaction_)(int, struct siginfo *, void *);\n  };\n  struct kernel_sigset_t sa_mask;\n#else\n  union {\n    void             (*sa_handler_)(int);\n    void             (*sa_sigaction_)(int, struct siginfo *, void *);\n  };\n  unsigned long      sa_flags;\n  void               (*sa_restorer)(void);\n  struct kernel_sigset_t sa_mask;\n#endif\n};\n\n/* include/linux/socket.h                                                    */\nstruct kernel_sockaddr {\n  unsigned short     sa_family;\n  char               sa_data[14];\n};\n\n/* include/asm-{arm,i386,mips,ppc}/stat.h                                    */\n#ifdef __mips__\n#if _MIPS_SIM == _MIPS_SIM_ABI64\nstruct kernel_stat {\n#else\nstruct kernel_stat64 {\n#endif\n  unsigned           st_dev;\n  unsigned           __pad0[3];\n  unsigned long long st_ino;\n  unsigned           st_mode;\n  unsigned           st_nlink;\n  unsigned           st_uid;\n  unsigned           st_gid;\n  unsigned           st_rdev;\n  unsigned           __pad1[3];\n  long long          st_size;\n  unsigned           st_atime_;\n  unsigned           st_atime_nsec_;\n  unsigned           st_mtime_;\n  unsigned           st_mtime_nsec_;\n  unsigned           st_ctime_;\n  unsigned           st_ctime_nsec_;\n  unsigned           st_blksize;\n  unsigned           __pad2;\n  unsigned long long st_blocks;\n};\n#elif defined __PPC__\nstruct kernel_stat64 {\n  unsigned long long st_dev;\n  unsigned long long st_ino;\n  unsigned           st_mode;\n  unsigned           st_nlink;\n  unsigned           st_uid;\n  unsigned           st_gid;\n  unsigned long long st_rdev;\n  unsigned short int __pad2;\n  long long          st_size;\n  long               st_blksize;\n  long long          st_blocks;\n  long               st_atime_;\n  unsigned long      st_atime_nsec_;\n  long               st_mtime_;\n  unsigned long      st_mtime_nsec_;\n  long               st_ctime_;\n  unsigned long      st_ctime_nsec_;\n  unsigned long      __unused4;\n  unsigned long      __unused5;\n};\n#else\nstruct kernel_stat64 {\n  unsigned long long st_dev;\n  unsigned char      __pad0[4];\n  unsigned           __st_ino;\n  unsigned           st_mode;\n  unsigned           st_nlink;\n  unsigned           st_uid;\n  unsigned           st_gid;\n  unsigned long long st_rdev;\n  unsigned char      __pad3[4];\n  long long          st_size;\n  unsigned           st_blksize;\n  unsigned long long st_blocks;\n  unsigned           st_atime_;\n  unsigned           st_atime_nsec_;\n  unsigned           st_mtime_;\n  unsigned           st_mtime_nsec_;\n  unsigned           st_ctime_;\n  unsigned           st_ctime_nsec_;\n  unsigned long long st_ino;\n};\n#endif\n\n/* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h                             */\n#if defined(__i386__) || defined(__ARM_ARCH_3__)\nstruct kernel_stat {\n  /* The kernel headers suggest that st_dev and st_rdev should be 32bit\n   * quantities encoding 12bit major and 20bit minor numbers in an interleaved\n   * format. In reality, we do not see useful data in the top bits. So,\n   * we'll leave the padding in here, until we find a better solution.\n   */\n  unsigned short     st_dev;\n  short              pad1;\n  unsigned           st_ino;\n  unsigned short     st_mode;\n  unsigned short     st_nlink;\n  unsigned short     st_uid;\n  unsigned short     st_gid;\n  unsigned short     st_rdev;\n  short              pad2;\n  unsigned           st_size;\n  unsigned           st_blksize;\n  unsigned           st_blocks;\n  unsigned           st_atime_;\n  unsigned           st_atime_nsec_;\n  unsigned           st_mtime_;\n  unsigned           st_mtime_nsec_;\n  unsigned           st_ctime_;\n  unsigned           st_ctime_nsec_;\n  unsigned           __unused4;\n  unsigned           __unused5;\n};\n#elif defined(__x86_64__)\nstruct kernel_stat {\n  unsigned long      st_dev;\n  unsigned long      st_ino;\n  unsigned long      st_nlink;\n  unsigned           st_mode;\n  unsigned           st_uid;\n  unsigned           st_gid;\n  unsigned           __pad0;\n  unsigned long      st_rdev;\n  long               st_size;\n  long               st_blksize;\n  long               st_blocks;\n  unsigned long      st_atime_;\n  unsigned long      st_atime_nsec_;\n  unsigned long      st_mtime_;\n  unsigned long      st_mtime_nsec_;\n  unsigned long      st_ctime_;\n  unsigned long      st_ctime_nsec_;\n  long               __unused[3];\n};\n#elif defined(__PPC__)\nstruct kernel_stat {\n  unsigned           st_dev;\n  unsigned long      st_ino;      // ino_t\n  unsigned long      st_mode;     // mode_t\n  unsigned short     st_nlink;    // nlink_t\n  unsigned           st_uid;      // uid_t\n  unsigned           st_gid;      // gid_t\n  unsigned           st_rdev;\n  long               st_size;     // off_t\n  unsigned long      st_blksize;\n  unsigned long      st_blocks;\n  unsigned long      st_atime_;\n  unsigned long      st_atime_nsec_;\n  unsigned long      st_mtime_;\n  unsigned long      st_mtime_nsec_;\n  unsigned long      st_ctime_;\n  unsigned long      st_ctime_nsec_;\n  unsigned long      __unused4;\n  unsigned long      __unused5;\n};\n#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)\nstruct kernel_stat {\n  unsigned           st_dev;\n  int                st_pad1[3];\n  unsigned           st_ino;\n  unsigned           st_mode;\n  unsigned           st_nlink;\n  unsigned           st_uid;\n  unsigned           st_gid;\n  unsigned           st_rdev;\n  int                st_pad2[2];\n  long               st_size;\n  int                st_pad3;\n  long               st_atime_;\n  long               st_atime_nsec_;\n  long               st_mtime_;\n  long               st_mtime_nsec_;\n  long               st_ctime_;\n  long               st_ctime_nsec_;\n  int                st_blksize;\n  int                st_blocks;\n  int                st_pad4[14];\n};\n#endif\n\n/* include/asm-{arm,i386,mips,x86_64,ppc}/statfs.h                           */\n#ifdef __mips__\n#if _MIPS_SIM != _MIPS_SIM_ABI64\nstruct kernel_statfs64 {\n  unsigned long      f_type;\n  unsigned long      f_bsize;\n  unsigned long      f_frsize;\n  unsigned long      __pad;\n  unsigned long long f_blocks;\n  unsigned long long f_bfree;\n  unsigned long long f_files;\n  unsigned long long f_ffree;\n  unsigned long long f_bavail;\n  struct { int val[2]; } f_fsid;\n  unsigned long      f_namelen;\n  unsigned long      f_spare[6];\n};\n#endif\n#elif !defined(__x86_64__)\nstruct kernel_statfs64 {\n  unsigned long      f_type;\n  unsigned long      f_bsize;\n  unsigned long long f_blocks;\n  unsigned long long f_bfree;\n  unsigned long long f_bavail;\n  unsigned long long f_files;\n  unsigned long long f_ffree;\n  struct { int val[2]; } f_fsid;\n  unsigned long      f_namelen;\n  unsigned long      f_frsize;\n  unsigned long      f_spare[5];\n};\n#endif\n\n/* include/asm-{arm,i386,mips,x86_64,ppc,generic}/statfs.h                   */\n#ifdef __mips__\nstruct kernel_statfs {\n  long               f_type;\n  long               f_bsize;\n  long               f_frsize;\n  long               f_blocks;\n  long               f_bfree;\n  long               f_files;\n  long               f_ffree;\n  long               f_bavail;\n  struct { int val[2]; } f_fsid;\n  long               f_namelen;\n  long               f_spare[6];\n};\n#else\nstruct kernel_statfs {\n  /* x86_64 actually defines all these fields as signed, whereas all other  */\n  /* platforms define them as unsigned. Leaving them at unsigned should not */\n  /* cause any problems.                                                    */\n  unsigned long      f_type;\n  unsigned long      f_bsize;\n  unsigned long      f_blocks;\n  unsigned long      f_bfree;\n  unsigned long      f_bavail;\n  unsigned long      f_files;\n  unsigned long      f_ffree;\n  struct { int val[2]; } f_fsid;\n  unsigned long      f_namelen;\n  unsigned long      f_frsize;\n  unsigned long      f_spare[5];\n};\n#endif\n\n\n/* Definitions missing from the standard header files                        */\n#ifndef O_DIRECTORY\n#if defined(__ARM_ARCH_3__)\n#define O_DIRECTORY             0040000\n#else\n#define O_DIRECTORY             0200000\n#endif\n#endif\n#ifndef NT_PRXFPREG\n#define NT_PRXFPREG             0x46e62b7f\n#endif\n#ifndef PTRACE_GETFPXREGS\n#define PTRACE_GETFPXREGS       ((enum __ptrace_request)18)\n#endif\n#ifndef PR_GET_DUMPABLE\n#define PR_GET_DUMPABLE         3\n#endif\n#ifndef PR_SET_DUMPABLE\n#define PR_SET_DUMPABLE         4\n#endif\n#ifndef AT_FDCWD\n#define AT_FDCWD                (-100)\n#endif\n#ifndef AT_SYMLINK_NOFOLLOW\n#define AT_SYMLINK_NOFOLLOW     0x100\n#endif\n#ifndef AT_REMOVEDIR\n#define AT_REMOVEDIR            0x200\n#endif\n#ifndef MREMAP_FIXED\n#define MREMAP_FIXED            2\n#endif\n#ifndef SA_RESTORER\n#define SA_RESTORER             0x04000000\n#endif\n#ifndef CPUCLOCK_PROF\n#define CPUCLOCK_PROF           0\n#endif\n#ifndef CPUCLOCK_VIRT\n#define CPUCLOCK_VIRT           1\n#endif\n#ifndef CPUCLOCK_SCHED\n#define CPUCLOCK_SCHED          2\n#endif\n#ifndef CPUCLOCK_PERTHREAD_MASK\n#define CPUCLOCK_PERTHREAD_MASK 4\n#endif\n#ifndef MAKE_PROCESS_CPUCLOCK\n#define MAKE_PROCESS_CPUCLOCK(pid, clock)                                     \\\n        ((~(int)(pid) << 3) | (int)(clock))\n#endif\n#ifndef MAKE_THREAD_CPUCLOCK\n#define MAKE_THREAD_CPUCLOCK(tid, clock)                                      \\\n        ((~(int)(tid) << 3) | (int)((clock) | CPUCLOCK_PERTHREAD_MASK))\n#endif\n\n#if defined(__i386__)\n#ifndef __NR_setresuid\n#define __NR_setresuid          164\n#define __NR_setresgid          170\n#endif\n#ifndef __NR_rt_sigaction\n#define __NR_rt_sigaction       174\n#define __NR_rt_sigprocmask     175\n#define __NR_rt_sigpending      176\n#define __NR_rt_sigsuspend      179\n#endif\n#ifndef __NR_pread64\n#define __NR_pread64            180\n#endif\n#ifndef __NR_pwrite64\n#define __NR_pwrite64           181\n#endif\n#ifndef __NR_ugetrlimit\n#define __NR_ugetrlimit         191\n#endif\n#ifndef __NR_stat64\n#define __NR_stat64             195\n#endif\n#ifndef __NR_fstat64\n#define __NR_fstat64            197\n#endif\n#ifndef __NR_setresuid32\n#define __NR_setresuid32        208\n#define __NR_setresgid32        210\n#endif\n#ifndef __NR_setfsuid32\n#define __NR_setfsuid32         215\n#define __NR_setfsgid32         216\n#endif\n#ifndef __NR_getdents64\n#define __NR_getdents64         220\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             224\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          225\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           226\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          227\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           229\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          230\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          232\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         233\n#endif\n#ifndef __NR_futex\n#define __NR_futex              240\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  241\n#define __NR_sched_getaffinity  242\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    258\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      265\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       266\n#endif\n#ifndef __NR_statfs64\n#define __NR_statfs64           268\n#endif\n#ifndef __NR_fstatfs64\n#define __NR_fstatfs64          269\n#endif\n#ifndef __NR_fadvise64_64\n#define __NR_fadvise64_64       272\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         289\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         290\n#endif\n#ifndef __NR_openat\n#define __NR_openat             295\n#endif\n#ifndef __NR_fstatat64\n#define __NR_fstatat64          300\n#endif\n#ifndef __NR_unlinkat\n#define __NR_unlinkat           301\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         317\n#endif\n#ifndef __NR_getcpu\n#define __NR_getcpu             318\n#endif\n#ifndef __NR_fallocate\n#define __NR_fallocate          324\n#endif\n/* End of i386 definitions                                                   */\n#elif defined(__ARM_ARCH_3__)\n#ifndef __NR_setresuid\n#define __NR_setresuid          (__NR_SYSCALL_BASE + 164)\n#define __NR_setresgid          (__NR_SYSCALL_BASE + 170)\n#endif\n#ifndef __NR_rt_sigaction\n#define __NR_rt_sigaction       (__NR_SYSCALL_BASE + 174)\n#define __NR_rt_sigprocmask     (__NR_SYSCALL_BASE + 175)\n#define __NR_rt_sigpending      (__NR_SYSCALL_BASE + 176)\n#define __NR_rt_sigsuspend      (__NR_SYSCALL_BASE + 179)\n#endif\n#ifndef __NR_pread64\n#define __NR_pread64            (__NR_SYSCALL_BASE + 180)\n#endif\n#ifndef __NR_pwrite64\n#define __NR_pwrite64           (__NR_SYSCALL_BASE + 181)\n#endif\n#ifndef __NR_ugetrlimit\n#define __NR_ugetrlimit         (__NR_SYSCALL_BASE + 191)\n#endif\n#ifndef __NR_stat64\n#define __NR_stat64             (__NR_SYSCALL_BASE + 195)\n#endif\n#ifndef __NR_fstat64\n#define __NR_fstat64            (__NR_SYSCALL_BASE + 197)\n#endif\n#ifndef __NR_setresuid32\n#define __NR_setresuid32        (__NR_SYSCALL_BASE + 208)\n#define __NR_setresgid32        (__NR_SYSCALL_BASE + 210)\n#endif\n#ifndef __NR_setfsuid32\n#define __NR_setfsuid32         (__NR_SYSCALL_BASE + 215)\n#define __NR_setfsgid32         (__NR_SYSCALL_BASE + 216)\n#endif\n#ifndef __NR_getdents64\n#define __NR_getdents64         (__NR_SYSCALL_BASE + 217)\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             (__NR_SYSCALL_BASE + 224)\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          (__NR_SYSCALL_BASE + 225)\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           (__NR_SYSCALL_BASE + 226)\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          (__NR_SYSCALL_BASE + 227)\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           (__NR_SYSCALL_BASE + 229)\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          (__NR_SYSCALL_BASE + 230)\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          (__NR_SYSCALL_BASE + 232)\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         (__NR_SYSCALL_BASE + 233)\n#endif\n#ifndef __NR_futex\n#define __NR_futex              (__NR_SYSCALL_BASE + 240)\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  (__NR_SYSCALL_BASE + 241)\n#define __NR_sched_getaffinity  (__NR_SYSCALL_BASE + 242)\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    (__NR_SYSCALL_BASE + 256)\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      (__NR_SYSCALL_BASE + 263)\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       (__NR_SYSCALL_BASE + 264)\n#endif\n#ifndef __NR_statfs64\n#define __NR_statfs64           (__NR_SYSCALL_BASE + 266)\n#endif\n#ifndef __NR_fstatfs64\n#define __NR_fstatfs64          (__NR_SYSCALL_BASE + 267)\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         (__NR_SYSCALL_BASE + 314)\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         (__NR_SYSCALL_BASE + 315)\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         (__NR_SYSCALL_BASE + 344)\n#endif\n#ifndef __NR_getcpu\n#define __NR_getcpu             (__NR_SYSCALL_BASE + 345)\n#endif\n/* End of ARM 3 definitions                                                  */\n#elif defined(__x86_64__)\n#ifndef __NR_pread64\n#define __NR_pread64             17\n#endif\n#ifndef __NR_pwrite64\n#define __NR_pwrite64            18\n#endif\n#ifndef __NR_setresuid\n#define __NR_setresuid          117\n#define __NR_setresgid          119\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             186\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          187\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           188\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          189\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           191\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          192\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          194\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         195\n#endif\n#ifndef __NR_futex\n#define __NR_futex              202\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  203\n#define __NR_sched_getaffinity  204\n#endif\n#ifndef __NR_getdents64\n#define __NR_getdents64         217\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    218\n#endif\n#ifndef __NR_fadvise64\n#define __NR_fadvise64          221\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      228\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       229\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         251\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         252\n#endif\n#ifndef __NR_openat\n#define __NR_openat             257\n#endif\n#ifndef __NR_newfstatat\n#define __NR_newfstatat         262\n#endif\n#ifndef __NR_unlinkat\n#define __NR_unlinkat           263\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         279\n#endif\n#ifndef __NR_fallocate\n#define __NR_fallocate          285\n#endif\n/* End of x86-64 definitions                                                 */\n#elif defined(__mips__)\n#if _MIPS_SIM == _MIPS_SIM_ABI32\n#ifndef __NR_setresuid\n#define __NR_setresuid          (__NR_Linux + 185)\n#define __NR_setresgid          (__NR_Linux + 190)\n#endif\n#ifndef __NR_rt_sigaction\n#define __NR_rt_sigaction       (__NR_Linux + 194)\n#define __NR_rt_sigprocmask     (__NR_Linux + 195)\n#define __NR_rt_sigpending      (__NR_Linux + 196)\n#define __NR_rt_sigsuspend      (__NR_Linux + 199)\n#endif\n#ifndef __NR_pread64\n#define __NR_pread64            (__NR_Linux + 200)\n#endif\n#ifndef __NR_pwrite64\n#define __NR_pwrite64           (__NR_Linux + 201)\n#endif\n#ifndef __NR_stat64\n#define __NR_stat64             (__NR_Linux + 213)\n#endif\n#ifndef __NR_fstat64\n#define __NR_fstat64            (__NR_Linux + 215)\n#endif\n#ifndef __NR_getdents64\n#define __NR_getdents64         (__NR_Linux + 219)\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             (__NR_Linux + 222)\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          (__NR_Linux + 223)\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           (__NR_Linux + 224)\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          (__NR_Linux + 225)\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           (__NR_Linux + 227)\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          (__NR_Linux + 228)\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          (__NR_Linux + 230)\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         (__NR_Linux + 231)\n#endif\n#ifndef __NR_futex\n#define __NR_futex              (__NR_Linux + 238)\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  (__NR_Linux + 239)\n#define __NR_sched_getaffinity  (__NR_Linux + 240)\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    (__NR_Linux + 252)\n#endif\n#ifndef __NR_statfs64\n#define __NR_statfs64           (__NR_Linux + 255)\n#endif\n#ifndef __NR_fstatfs64\n#define __NR_fstatfs64          (__NR_Linux + 256)\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      (__NR_Linux + 263)\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       (__NR_Linux + 264)\n#endif\n#ifndef __NR_openat\n#define __NR_openat             (__NR_Linux + 288)\n#endif\n#ifndef __NR_fstatat\n#define __NR_fstatat            (__NR_Linux + 293)\n#endif\n#ifndef __NR_unlinkat\n#define __NR_unlinkat           (__NR_Linux + 294)\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         (__NR_Linux + 308)\n#endif\n#ifndef __NR_getcpu\n#define __NR_getcpu             (__NR_Linux + 312)\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         (__NR_Linux + 314)\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         (__NR_Linux + 315)\n#endif\n/* End of MIPS (old 32bit API) definitions */\n#elif  _MIPS_SIM == _MIPS_SIM_ABI64\n#ifndef __NR_pread64\n#define __NR_pread64            (__NR_Linux +  16)\n#endif\n#ifndef __NR_pwrite64\n#define __NR_pwrite64           (__NR_Linux +  17)\n#endif\n#ifndef __NR_setresuid\n#define __NR_setresuid          (__NR_Linux + 115)\n#define __NR_setresgid          (__NR_Linux + 117)\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             (__NR_Linux + 178)\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          (__NR_Linux + 179)\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           (__NR_Linux + 180)\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          (__NR_Linux + 181)\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           (__NR_Linux + 183)\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          (__NR_Linux + 184)\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          (__NR_Linux + 186)\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         (__NR_Linux + 187)\n#endif\n#ifndef __NR_futex\n#define __NR_futex              (__NR_Linux + 194)\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  (__NR_Linux + 195)\n#define __NR_sched_getaffinity  (__NR_Linux + 196)\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    (__NR_Linux + 212)\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      (__NR_Linux + 222)\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       (__NR_Linux + 223)\n#endif\n#ifndef __NR_openat\n#define __NR_openat             (__NR_Linux + 247)\n#endif\n#ifndef __NR_fstatat\n#define __NR_fstatat            (__NR_Linux + 252)\n#endif\n#ifndef __NR_unlinkat\n#define __NR_unlinkat           (__NR_Linux + 253)\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         (__NR_Linux + 267)\n#endif\n#ifndef __NR_getcpu\n#define __NR_getcpu             (__NR_Linux + 271)\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         (__NR_Linux + 273)\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         (__NR_Linux + 274)\n#endif\n/* End of MIPS (64bit API) definitions */\n#else\n#ifndef __NR_setresuid\n#define __NR_setresuid          (__NR_Linux + 115)\n#define __NR_setresgid          (__NR_Linux + 117)\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             (__NR_Linux + 178)\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          (__NR_Linux + 179)\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           (__NR_Linux + 180)\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          (__NR_Linux + 181)\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           (__NR_Linux + 183)\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          (__NR_Linux + 184)\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          (__NR_Linux + 186)\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         (__NR_Linux + 187)\n#endif\n#ifndef __NR_futex\n#define __NR_futex              (__NR_Linux + 194)\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  (__NR_Linux + 195)\n#define __NR_sched_getaffinity  (__NR_Linux + 196)\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    (__NR_Linux + 213)\n#endif\n#ifndef __NR_statfs64\n#define __NR_statfs64           (__NR_Linux + 217)\n#endif\n#ifndef __NR_fstatfs64\n#define __NR_fstatfs64          (__NR_Linux + 218)\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      (__NR_Linux + 226)\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       (__NR_Linux + 227)\n#endif\n#ifndef __NR_openat\n#define __NR_openat             (__NR_Linux + 251)\n#endif\n#ifndef __NR_fstatat\n#define __NR_fstatat            (__NR_Linux + 256)\n#endif\n#ifndef __NR_unlinkat\n#define __NR_unlinkat           (__NR_Linux + 257)\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         (__NR_Linux + 271)\n#endif\n#ifndef __NR_getcpu\n#define __NR_getcpu             (__NR_Linux + 275)\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         (__NR_Linux + 277)\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         (__NR_Linux + 278)\n#endif\n/* End of MIPS (new 32bit API) definitions                                   */\n#endif\n/* End of MIPS definitions                                                   */\n#elif defined(__PPC__)\n#ifndef __NR_setfsuid\n#define __NR_setfsuid           138\n#define __NR_setfsgid           139\n#endif\n#ifndef __NR_setresuid\n#define __NR_setresuid          164\n#define __NR_setresgid          169\n#endif\n#ifndef __NR_rt_sigaction\n#define __NR_rt_sigaction       173\n#define __NR_rt_sigprocmask     174\n#define __NR_rt_sigpending      175\n#define __NR_rt_sigsuspend      178\n#endif\n#ifndef __NR_pread64\n#define __NR_pread64            179\n#endif\n#ifndef __NR_pwrite64\n#define __NR_pwrite64           180\n#endif\n#ifndef __NR_ugetrlimit\n#define __NR_ugetrlimit         190\n#endif\n#ifndef __NR_readahead\n#define __NR_readahead          191\n#endif\n#ifndef __NR_stat64\n#define __NR_stat64             195\n#endif\n#ifndef __NR_fstat64\n#define __NR_fstat64            197\n#endif\n#ifndef __NR_getdents64\n#define __NR_getdents64         202\n#endif\n#ifndef __NR_gettid\n#define __NR_gettid             207\n#endif\n#ifndef __NR_setxattr\n#define __NR_setxattr           209\n#endif\n#ifndef __NR_lsetxattr\n#define __NR_lsetxattr          210\n#endif\n#ifndef __NR_getxattr\n#define __NR_getxattr           212\n#endif\n#ifndef __NR_lgetxattr\n#define __NR_lgetxattr          213\n#endif\n#ifndef __NR_listxattr\n#define __NR_listxattr          215\n#endif\n#ifndef __NR_llistxattr\n#define __NR_llistxattr         216\n#endif\n#ifndef __NR_futex\n#define __NR_futex              221\n#endif\n#ifndef __NR_sched_setaffinity\n#define __NR_sched_setaffinity  222\n#define __NR_sched_getaffinity  223\n#endif\n#ifndef __NR_set_tid_address\n#define __NR_set_tid_address    232\n#endif\n#ifndef __NR_clock_gettime\n#define __NR_clock_gettime      246\n#endif\n#ifndef __NR_clock_getres\n#define __NR_clock_getres       247\n#endif\n#ifndef __NR_statfs64\n#define __NR_statfs64           252\n#endif\n#ifndef __NR_fstatfs64\n#define __NR_fstatfs64          253\n#endif\n#ifndef __NR_fadvise64_64\n#define __NR_fadvise64_64       254\n#endif\n#ifndef __NR_ioprio_set\n#define __NR_ioprio_set         273\n#endif\n#ifndef __NR_ioprio_get\n#define __NR_ioprio_get         274\n#endif\n#ifndef __NR_openat\n#define __NR_openat             286\n#endif\n#ifndef __NR_fstatat64\n#define __NR_fstatat64          291\n#endif\n#ifndef __NR_unlinkat\n#define __NR_unlinkat           292\n#endif\n#ifndef __NR_move_pages\n#define __NR_move_pages         301\n#endif\n#ifndef __NR_getcpu\n#define __NR_getcpu             302\n#endif\n/* End of powerpc defininitions                                              */\n#endif\n\n\n/* After forking, we must make sure to only call system calls.               */\n#if __BOUNDED_POINTERS__\n  #error \"Need to port invocations of syscalls for bounded ptrs\"\n#else\n  /* The core dumper and the thread lister get executed after threads\n   * have been suspended. As a consequence, we cannot call any functions\n   * that acquire locks. Unfortunately, libc wraps most system calls\n   * (e.g. in order to implement pthread_atfork, and to make calls\n   * cancellable), which means we cannot call these functions. Instead,\n   * we have to call syscall() directly.\n   */\n  #undef LSS_ERRNO\n  #ifdef SYS_ERRNO\n    /* Allow the including file to override the location of errno. This can\n     * be useful when using clone() with the CLONE_VM option.\n     */\n    #define LSS_ERRNO SYS_ERRNO\n  #else\n    #define LSS_ERRNO errno\n  #endif\n\n  #undef LSS_INLINE\n  #ifdef SYS_INLINE\n    #define LSS_INLINE SYS_INLINE\n  #else\n    #define LSS_INLINE static inline\n  #endif\n\n  /* Allow the including file to override the prefix used for all new\n   * system calls. By default, it will be set to \"sys_\".\n   */\n  #undef LSS_NAME\n  #ifndef SYS_PREFIX\n    #define LSS_NAME(name) sys_##name\n  #elif SYS_PREFIX < 0\n    #define LSS_NAME(name) name\n  #elif SYS_PREFIX == 0\n    #define LSS_NAME(name) sys0_##name\n  #elif SYS_PREFIX == 1\n    #define LSS_NAME(name) sys1_##name\n  #elif SYS_PREFIX == 2\n    #define LSS_NAME(name) sys2_##name\n  #elif SYS_PREFIX == 3\n    #define LSS_NAME(name) sys3_##name\n  #elif SYS_PREFIX == 4\n    #define LSS_NAME(name) sys4_##name\n  #elif SYS_PREFIX == 5\n    #define LSS_NAME(name) sys5_##name\n  #elif SYS_PREFIX == 6\n    #define LSS_NAME(name) sys6_##name\n  #elif SYS_PREFIX == 7\n    #define LSS_NAME(name) sys7_##name\n  #elif SYS_PREFIX == 8\n    #define LSS_NAME(name) sys8_##name\n  #elif SYS_PREFIX == 9\n    #define LSS_NAME(name) sys9_##name\n  #endif\n\n  #undef  LSS_RETURN\n  #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__))\n  /* Failing system calls return a negative result in the range of\n   * -1..-4095. These are \"errno\" values with the sign inverted.\n   */\n  #define LSS_RETURN(type, res)                                               \\\n    do {                                                                      \\\n      if ((unsigned long)(res) >= (unsigned long)(-4095)) {                   \\\n        LSS_ERRNO = -(res);                                                   \\\n        res = -1;                                                             \\\n      }                                                                       \\\n      return (type) (res);                                                    \\\n    } while (0)\n  #elif defined(__mips__)\n  /* On MIPS, failing system calls return -1, and set errno in a\n   * separate CPU register.\n   */\n  #define LSS_RETURN(type, res, err)                                          \\\n    do {                                                                      \\\n      if (err) {                                                              \\\n        LSS_ERRNO = (res);                                                    \\\n        res = -1;                                                             \\\n      }                                                                       \\\n      return (type) (res);                                                    \\\n    } while (0)\n  #elif defined(__PPC__)\n  /* On PPC, failing system calls return -1, and set errno in a\n   * separate CPU register. See linux/unistd.h.\n   */\n  #define LSS_RETURN(type, res, err)                                          \\\n   do {                                                                       \\\n     if (err & 0x10000000 ) {                                                 \\\n       LSS_ERRNO = (res);                                                     \\\n       res = -1;                                                              \\\n     }                                                                        \\\n     return (type) (res);                                                     \\\n   } while (0)\n  #endif\n  #if defined(__i386__)\n    /* In PIC mode (e.g. when building shared libraries), gcc for i386\n     * reserves ebx. Unfortunately, most distribution ship with implementations\n     * of _syscallX() which clobber ebx.\n     * Also, most definitions of _syscallX() neglect to mark \"memory\" as being\n     * clobbered. This causes problems with compilers, that do a better job\n     * at optimizing across __asm__ calls.\n     * So, we just have to redefine all of the _syscallX() macros.\n     */\n    #undef  LSS_BODY\n    #define LSS_BODY(type,args...)                                            \\\n      long __res;                                                             \\\n      __asm__ __volatile__(\"push %%ebx\\n\"                                     \\\n                           \"movl %2,%%ebx\\n\"                                  \\\n                           \"int $0x80\\n\"                                      \\\n                           \"pop %%ebx\"                                        \\\n                           args                                               \\\n                           : \"memory\");                                       \\\n      LSS_RETURN(type,__res)\n    #undef  _syscall0\n    #define _syscall0(type,name)                                              \\\n      type LSS_NAME(name)(void) {                                             \\\n        long __res;                                                           \\\n        __asm__ volatile(\"int $0x80\"                                          \\\n                         : \"=a\" (__res)                                       \\\n                         : \"0\" (__NR_##name)                                  \\\n                         : \"memory\");                                         \\\n        LSS_RETURN(type,__res);                                               \\\n      }\n    #undef  _syscall1\n    #define _syscall1(type,name,type1,arg1)                                   \\\n      type LSS_NAME(name)(type1 arg1) {                                       \\\n        LSS_BODY(type,                                                        \\\n             : \"=a\" (__res)                                                   \\\n             : \"0\" (__NR_##name), \"ri\" ((long)(arg1)));                       \\\n      }\n    #undef  _syscall2\n    #define _syscall2(type,name,type1,arg1,type2,arg2)                        \\\n      type LSS_NAME(name)(type1 arg1,type2 arg2) {                            \\\n        LSS_BODY(type,                                                        \\\n             : \"=a\" (__res)                                                   \\\n             : \"0\" (__NR_##name),\"ri\" ((long)(arg1)), \"c\" ((long)(arg2)));    \\\n      }\n    #undef  _syscall3\n    #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)             \\\n      type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) {                 \\\n        LSS_BODY(type,                                                        \\\n             : \"=a\" (__res)                                                   \\\n             : \"0\" (__NR_##name), \"ri\" ((long)(arg1)), \"c\" ((long)(arg2)),    \\\n               \"d\" ((long)(arg3)));                                           \\\n      }\n    #undef  _syscall4\n    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \\\n        LSS_BODY(type,                                                        \\\n             : \"=a\" (__res)                                                   \\\n             : \"0\" (__NR_##name), \"ri\" ((long)(arg1)), \"c\" ((long)(arg2)),    \\\n               \"d\" ((long)(arg3)),\"S\" ((long)(arg4)));                        \\\n      }\n    #undef  _syscall5\n    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5)                                             \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5) {                                       \\\n        long __res;                                                           \\\n        __asm__ __volatile__(\"push %%ebx\\n\"                                   \\\n                             \"movl %2,%%ebx\\n\"                                \\\n                             \"movl %1,%%eax\\n\"                                \\\n                             \"int  $0x80\\n\"                                   \\\n                             \"pop  %%ebx\"                                     \\\n                             : \"=a\" (__res)                                   \\\n                             : \"i\" (__NR_##name), \"ri\" ((long)(arg1)),        \\\n                               \"c\" ((long)(arg2)), \"d\" ((long)(arg3)),        \\\n                               \"S\" ((long)(arg4)), \"D\" ((long)(arg5))         \\\n                             : \"memory\");                                     \\\n        LSS_RETURN(type,__res);                                               \\\n      }\n    #undef  _syscall6\n    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5,type6,arg6)                                  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5, type6 arg6) {                           \\\n        long __res;                                                           \\\n        struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 };   \\\n        __asm__ __volatile__(\"push %%ebp\\n\"                                   \\\n                             \"push %%ebx\\n\"                                   \\\n                             \"movl 4(%2),%%ebp\\n\"                             \\\n                             \"movl 0(%2), %%ebx\\n\"                            \\\n                             \"movl %1,%%eax\\n\"                                \\\n                             \"int  $0x80\\n\"                                   \\\n                             \"pop  %%ebx\\n\"                                   \\\n                             \"pop  %%ebp\"                                     \\\n                             : \"=a\" (__res)                                   \\\n                             : \"i\" (__NR_##name),  \"0\" ((long)(&__s)),        \\\n                               \"c\" ((long)(arg2)), \"d\" ((long)(arg3)),        \\\n                               \"S\" ((long)(arg4)), \"D\" ((long)(arg5))         \\\n                             : \"memory\");                                     \\\n        LSS_RETURN(type,__res);                                               \\\n      }\n    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,\n                                   int flags, void *arg, int *parent_tidptr,\n                                   void *newtls, int *child_tidptr) {\n      long __res;\n      __asm__ __volatile__(/* if (fn == NULL)\n                            *   return -EINVAL;\n                            */\n                           \"movl   %3,%%ecx\\n\"\n                           \"jecxz  1f\\n\"\n\n                           /* if (child_stack == NULL)\n                            *   return -EINVAL;\n                            */\n                           \"movl   %4,%%ecx\\n\"\n                           \"jecxz  1f\\n\"\n\n                           /* Set up alignment of the child stack:\n                            * child_stack = (child_stack & ~0xF) - 20;\n                            */\n                           \"andl   $-16,%%ecx\\n\"\n                           \"subl   $20,%%ecx\\n\"\n\n                           /* Push \"arg\" and \"fn\" onto the stack that will be\n                            * used by the child.\n                            */\n                           \"movl   %6,%%eax\\n\"\n                           \"movl   %%eax,4(%%ecx)\\n\"\n                           \"movl   %3,%%eax\\n\"\n                           \"movl   %%eax,(%%ecx)\\n\"\n\n                           /* %eax = syscall(%eax = __NR_clone,\n                            *                %ebx = flags,\n                            *                %ecx = child_stack,\n                            *                %edx = parent_tidptr,\n                            *                %esi = newtls,\n                            *                %edi = child_tidptr)\n                            * Also, make sure that %ebx gets preserved as it is\n                            * used in PIC mode.\n                            */\n                           \"movl   %8,%%esi\\n\"\n                           \"movl   %7,%%edx\\n\"\n                           \"movl   %5,%%eax\\n\"\n                           \"movl   %9,%%edi\\n\"\n                           \"pushl  %%ebx\\n\"\n                           \"movl   %%eax,%%ebx\\n\"\n                           \"movl   %2,%%eax\\n\"\n                           \"int    $0x80\\n\"\n\n                           /* In the parent: restore %ebx\n                            * In the child:  move \"fn\" into %ebx\n                            */\n                           \"popl   %%ebx\\n\"\n\n                           /* if (%eax != 0)\n                            *   return %eax;\n                            */\n                           \"test   %%eax,%%eax\\n\"\n                           \"jnz    1f\\n\"\n\n                           /* In the child, now. Terminate frame pointer chain.\n                            */\n                           \"movl   $0,%%ebp\\n\"\n\n                           /* Call \"fn\". \"arg\" is already on the stack.\n                            */\n                           \"call   *%%ebx\\n\"\n\n                           /* Call _exit(%ebx). Unfortunately older versions\n                            * of gcc restrict the number of arguments that can\n                            * be passed to asm(). So, we need to hard-code the\n                            * system call number.\n                            */\n                           \"movl   %%eax,%%ebx\\n\"\n                           \"movl   $1,%%eax\\n\"\n                           \"int    $0x80\\n\"\n\n                           /* Return to parent.\n                            */\n                         \"1:\\n\"\n                           : \"=a\" (__res)\n                           : \"0\"(-EINVAL), \"i\"(__NR_clone),\n                             \"m\"(fn), \"m\"(child_stack), \"m\"(flags), \"m\"(arg),\n                             \"m\"(parent_tidptr), \"m\"(newtls), \"m\"(child_tidptr)\n                           : \"memory\", \"ecx\", \"edx\", \"esi\", \"edi\");\n      LSS_RETURN(int, __res);\n    }\n\n    #define __NR__fadvise64_64 __NR_fadvise64_64\n    LSS_INLINE _syscall6(int, _fadvise64_64, int, fd,\n                         unsigned, offset_lo, unsigned, offset_hi,\n                         unsigned, len_lo, unsigned, len_hi,\n                         int, advice)\n\n    LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset,\n                                       loff_t len, int advice) {\n      return LSS_NAME(_fadvise64_64)(fd,\n                                     (unsigned)offset, (unsigned)(offset >>32),\n                                     (unsigned)len, (unsigned)(len >> 32),\n                                     advice);\n    }\n\n    #define __NR__fallocate __NR_fallocate\n    LSS_INLINE _syscall6(int, _fallocate, int, fd,\n                         int, mode,\n                         unsigned, offset_lo, unsigned, offset_hi,\n                         unsigned, len_lo, unsigned, len_hi)\n\n    LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode,\n                                       loff_t offset, loff_t len) {\n      union { loff_t off; unsigned w[2]; } o = { offset }, l = { len };\n      return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]);\n    }\n\n    LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {\n      /* On i386, the kernel does not know how to return from a signal\n       * handler. Instead, it relies on user space to provide a\n       * restorer function that calls the {rt_,}sigreturn() system call.\n       * Unfortunately, we cannot just reference the glibc version of this\n       * function, as glibc goes out of its way to make it inaccessible.\n       */\n      void (*res)(void);\n      __asm__ __volatile__(\"call   2f\\n\"\n                         \"0:.align 16\\n\"\n                         \"1:movl   %1,%%eax\\n\"\n                           \"int    $0x80\\n\"\n                         \"2:popl   %0\\n\"\n                           \"addl   $(1b-0b),%0\\n\"\n                           : \"=a\" (res)\n                           : \"i\"  (__NR_rt_sigreturn));\n      return res;\n    }\n    LSS_INLINE void (*LSS_NAME(restore)(void))(void) {\n      /* On i386, the kernel does not know how to return from a signal\n       * handler. Instead, it relies on user space to provide a\n       * restorer function that calls the {rt_,}sigreturn() system call.\n       * Unfortunately, we cannot just reference the glibc version of this\n       * function, as glibc goes out of its way to make it inaccessible.\n       */\n      void (*res)(void);\n      __asm__ __volatile__(\"call   2f\\n\"\n                         \"0:.align 16\\n\"\n                         \"1:pop    %%eax\\n\"\n                           \"movl   %1,%%eax\\n\"\n                           \"int    $0x80\\n\"\n                         \"2:popl   %0\\n\"\n                           \"addl   $(1b-0b),%0\\n\"\n                           : \"=a\" (res)\n                           : \"i\"  (__NR_sigreturn));\n      return res;\n    }\n  #elif defined(__x86_64__)\n    /* There are no known problems with any of the _syscallX() macros\n     * currently shipping for x86_64, but we still need to be able to define\n     * our own version so that we can override the location of the errno\n     * location (e.g. when using the clone() system call with the CLONE_VM\n     * option).\n     */\n    #undef  LSS_BODY\n    #define LSS_BODY(type,name, ...)                                          \\\n          long __res;                                                         \\\n          __asm__ __volatile__(\"syscall\" : \"=a\" (__res) : \"0\" (__NR_##name),  \\\n            ##__VA_ARGS__ : \"r11\", \"rcx\", \"memory\");                          \\\n          LSS_RETURN(type, __res)\n    #undef _syscall0\n    #define _syscall0(type,name)                                              \\\n      type LSS_NAME(name)() {                                                 \\\n        LSS_BODY(type, name);                                                 \\\n      }\n    #undef _syscall1\n    #define _syscall1(type,name,type1,arg1)                                   \\\n      type LSS_NAME(name)(type1 arg1) {                                       \\\n        LSS_BODY(type, name, \"D\" ((long)(arg1)));                             \\\n      }\n    #undef _syscall2\n    #define _syscall2(type,name,type1,arg1,type2,arg2)                        \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \\\n        LSS_BODY(type, name, \"D\" ((long)(arg1)), \"S\" ((long)(arg2)));         \\\n      }\n    #undef _syscall3\n    #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)             \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \\\n        LSS_BODY(type, name, \"D\" ((long)(arg1)), \"S\" ((long)(arg2)),          \\\n                             \"d\" ((long)(arg3)));                             \\\n      }\n    #undef _syscall4\n    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \\\n          long __res;                                                         \\\n          __asm__ __volatile__(\"movq %5,%%r10; syscall\" :                     \\\n            \"=a\" (__res) : \"0\" (__NR_##name),                                 \\\n            \"D\" ((long)(arg1)), \"S\" ((long)(arg2)), \"d\" ((long)(arg3)),       \\\n            \"g\" ((long)(arg4)) : \"r10\", \"r11\", \"rcx\", \"memory\");              \\\n          LSS_RETURN(type, __res);                                            \\\n      }\n    #undef _syscall5\n    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5)                                             \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5) {                                       \\\n          long __res;                                                         \\\n          __asm__ __volatile__(\"movq %5,%%r10; movq %6,%%r8; syscall\" :       \\\n            \"=a\" (__res) : \"0\" (__NR_##name),                                 \\\n            \"D\" ((long)(arg1)), \"S\" ((long)(arg2)), \"d\" ((long)(arg3)),       \\\n            \"g\" ((long)(arg4)), \"g\" ((long)(arg5)) :                          \\\n            \"r8\", \"r10\", \"r11\", \"rcx\", \"memory\");                             \\\n          LSS_RETURN(type, __res);                                            \\\n      }\n    #undef _syscall6\n    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5,type6,arg6)                                  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5, type6 arg6) {                           \\\n          long __res;                                                         \\\n          __asm__ __volatile__(\"movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;\"   \\\n                               \"syscall\" :                                    \\\n            \"=a\" (__res) : \"0\" (__NR_##name),                                 \\\n            \"D\" ((long)(arg1)), \"S\" ((long)(arg2)), \"d\" ((long)(arg3)),       \\\n            \"g\" ((long)(arg4)), \"g\" ((long)(arg5)), \"g\" ((long)(arg6)) :      \\\n            \"r8\", \"r9\", \"r10\", \"r11\", \"rcx\", \"memory\");                       \\\n          LSS_RETURN(type, __res);                                            \\\n      }\n    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,\n                                   int flags, void *arg, int *parent_tidptr,\n                                   void *newtls, int *child_tidptr) {\n      long __res;\n      {\n        register void *__tls  __asm__(\"r8\")  = newtls;\n        register int  *__ctid __asm__(\"r10\") = child_tidptr;\n        __asm__ __volatile__(/* if (fn == NULL)\n                              *   return -EINVAL;\n                              */\n                             \"testq  %4,%4\\n\"\n                             \"jz     1f\\n\"\n\n                             /* if (child_stack == NULL)\n                              *   return -EINVAL;\n                              */\n                             \"testq  %5,%5\\n\"\n                             \"jz     1f\\n\"\n\n                             /* childstack -= 2*sizeof(void *);\n                              */\n                             \"subq   $16,%5\\n\"\n\n                             /* Push \"arg\" and \"fn\" onto the stack that will be\n                              * used by the child.\n                              */\n                             \"movq   %7,8(%5)\\n\"\n                             \"movq   %4,0(%5)\\n\"\n\n                             /* %rax = syscall(%rax = __NR_clone,\n                              *                %rdi = flags,\n                              *                %rsi = child_stack,\n                              *                %rdx = parent_tidptr,\n                              *                %r8  = new_tls,\n                              *                %r10 = child_tidptr)\n                              */\n                             \"movq   %2,%%rax\\n\"\n                             \"syscall\\n\"\n\n                             /* if (%rax != 0)\n                              *   return;\n                              */\n                             \"testq  %%rax,%%rax\\n\"\n                             \"jnz    1f\\n\"\n\n                             /* In the child. Terminate frame pointer chain.\n                              */\n                             \"xorq   %%rbp,%%rbp\\n\"\n\n                             /* Call \"fn(arg)\".\n                              */\n                             \"popq   %%rax\\n\"\n                             \"popq   %%rdi\\n\"\n                             \"call   *%%rax\\n\"\n\n                             /* Call _exit(%ebx).\n                              */\n                             \"movq   %%rax,%%rdi\\n\"\n                             \"movq   %3,%%rax\\n\"\n                             \"syscall\\n\"\n\n                             /* Return to parent.\n                              */\n                           \"1:\\n\"\n                             : \"=a\" (__res)\n                             : \"0\"(-EINVAL), \"i\"(__NR_clone), \"i\"(__NR_exit),\n                               \"r\"(fn), \"S\"(child_stack), \"D\"(flags), \"r\"(arg),\n                               \"d\"(parent_tidptr), \"r\"(__tls), \"r\"(__ctid)\n                             : \"memory\", \"r11\", \"rcx\");\n      }\n      LSS_RETURN(int, __res);\n    }\n    LSS_INLINE _syscall4(int, fadvise64, int, fd, loff_t, offset, loff_t, len,\n                         int,  advice)\n\n    LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) {\n      /* On x86-64, the kernel does not know how to return from\n       * a signal handler. Instead, it relies on user space to provide a\n       * restorer function that calls the rt_sigreturn() system call.\n       * Unfortunately, we cannot just reference the glibc version of this\n       * function, as glibc goes out of its way to make it inaccessible.\n       */\n      void (*res)(void);\n      __asm__ __volatile__(\"call   2f\\n\"\n                         \"0:.align 16\\n\"\n                         \"1:movq   %1,%%rax\\n\"\n                           \"syscall\\n\"\n                         \"2:popq   %0\\n\"\n                           \"addq   $(1b-0b),%0\\n\"\n                           : \"=a\" (res)\n                           : \"i\"  (__NR_rt_sigreturn));\n      return res;\n    }\n  #elif defined(__ARM_ARCH_3__)\n    /* Most definitions of _syscallX() neglect to mark \"memory\" as being\n     * clobbered. This causes problems with compilers, that do a better job\n     * at optimizing across __asm__ calls.\n     * So, we just have to redefine all fo the _syscallX() macros.\n     */\n    #undef LSS_REG\n    #define LSS_REG(r,a) register long __r##r __asm__(\"r\"#r) = (long)a\n    #undef  LSS_BODY\n    #define LSS_BODY(type,name,args...)                                       \\\n          register long __res_r0 __asm__(\"r0\");                               \\\n          long __res;                                                         \\\n          __asm__ __volatile__ (__syscall(name)                               \\\n                                : \"=r\"(__res_r0) : args : \"lr\", \"memory\");    \\\n          __res = __res_r0;                                                   \\\n          LSS_RETURN(type, __res)\n    #undef _syscall0\n    #define _syscall0(type, name)                                             \\\n      type LSS_NAME(name)() {                                                 \\\n        LSS_BODY(type, name);                                                 \\\n      }\n    #undef _syscall1\n    #define _syscall1(type, name, type1, arg1)                                \\\n      type LSS_NAME(name)(type1 arg1) {                                       \\\n        LSS_REG(0, arg1); LSS_BODY(type, name, \"r\"(__r0));                    \\\n      }\n    #undef _syscall2\n    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \\\n        LSS_REG(0, arg1); LSS_REG(1, arg2);                                   \\\n        LSS_BODY(type, name, \"r\"(__r0), \"r\"(__r1));                           \\\n      }\n    #undef _syscall3\n    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \\\n        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \\\n        LSS_BODY(type, name, \"r\"(__r0), \"r\"(__r1), \"r\"(__r2));                \\\n      }\n    #undef _syscall4\n    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \\\n        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \\\n        LSS_REG(3, arg4);                                                     \\\n        LSS_BODY(type, name, \"r\"(__r0), \"r\"(__r1), \"r\"(__r2), \"r\"(__r3));     \\\n      }\n    #undef _syscall5\n    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5)                                             \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5) {                                       \\\n        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \\\n        LSS_REG(3, arg4); LSS_REG(4, arg5);                                   \\\n        LSS_BODY(type, name, \"r\"(__r0), \"r\"(__r1), \"r\"(__r2), \"r\"(__r3),      \\\n                             \"r\"(__r4));                                      \\\n      }\n    #undef _syscall6\n    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5,type6,arg6)                                  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5, type6 arg6) {                           \\\n        LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3);                 \\\n        LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6);                 \\\n        LSS_BODY(type, name, \"r\"(__r0), \"r\"(__r1), \"r\"(__r2), \"r\"(__r3),      \\\n                             \"r\"(__r4), \"r\"(__r5));                           \\\n      }\n    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,\n                                   int flags, void *arg, int *parent_tidptr,\n                                   void *newtls, int *child_tidptr) {\n      long __res;\n      {\n        register int   __flags __asm__(\"r0\") = flags;\n        register void *__stack __asm__(\"r1\") = child_stack;\n        register void *__ptid  __asm__(\"r2\") = parent_tidptr;\n        register void *__tls   __asm__(\"r3\") = newtls;\n        register int  *__ctid  __asm__(\"r4\") = child_tidptr;\n        __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)\n                              *   return -EINVAL;\n                              */\n                             \"cmp   %2,#0\\n\"\n                             \"cmpne %3,#0\\n\"\n                             \"moveq %0,%1\\n\"\n                             \"beq   1f\\n\"\n\n                             /* Push \"arg\" and \"fn\" onto the stack that will be\n                              * used by the child.\n                              */\n                             \"str   %5,[%3,#-4]!\\n\"\n                             \"str   %2,[%3,#-4]!\\n\"\n\n                             /* %r0 = syscall(%r0 = flags,\n                              *               %r1 = child_stack,\n                              *               %r2 = parent_tidptr,\n                              *               %r3 = newtls,\n                              *               %r4 = child_tidptr)\n                              */\n                             __syscall(clone)\"\\n\"\n\n                             /* if (%r0 != 0)\n                              *   return %r0;\n                              */\n                             \"movs  %0,r0\\n\"\n                             \"bne   1f\\n\"\n\n                             /* In the child, now. Call \"fn(arg)\".\n                              */\n                             \"ldr   r0,[sp, #4]\\n\"\n                             \"mov   lr,pc\\n\"\n                             \"ldr   pc,[sp]\\n\"\n\n                             /* Call _exit(%r0).\n                              */\n                             __syscall(exit)\"\\n\"\n                           \"1:\\n\"\n                             : \"=r\" (__res)\n                             : \"i\"(-EINVAL),\n                               \"r\"(fn), \"r\"(__stack), \"r\"(__flags), \"r\"(arg),\n                               \"r\"(__ptid), \"r\"(__tls), \"r\"(__ctid)\n                             : \"lr\", \"memory\");\n      }\n      LSS_RETURN(int, __res);\n    }\n  #elif defined(__mips__)\n    #undef LSS_REG\n    #define LSS_REG(r,a) register unsigned long __r##r __asm__(\"$\"#r) =       \\\n                                 (unsigned long)(a)\n    #undef  LSS_BODY\n    #define LSS_BODY(type,name,r7,...)                                        \\\n          register unsigned long __v0 __asm__(\"$2\") = __NR_##name;            \\\n          __asm__ __volatile__ (\"syscall\\n\"                                   \\\n                                : \"=&r\"(__v0), r7 (__r7)                      \\\n                                : \"0\"(__v0), ##__VA_ARGS__                    \\\n                                : \"$8\", \"$9\", \"$10\", \"$11\", \"$12\",            \\\n                                  \"$13\", \"$14\", \"$15\", \"$24\", \"memory\");      \\\n          LSS_RETURN(type, __v0, __r7)\n    #undef _syscall0\n    #define _syscall0(type, name)                                             \\\n      type LSS_NAME(name)() {                                                 \\\n        register unsigned long __r7 __asm__(\"$7\");                            \\\n        LSS_BODY(type, name, \"=r\");                                           \\\n      }\n    #undef _syscall1\n    #define _syscall1(type, name, type1, arg1)                                \\\n      type LSS_NAME(name)(type1 arg1) {                                       \\\n        register unsigned long __r7 __asm__(\"$7\");                            \\\n        LSS_REG(4, arg1); LSS_BODY(type, name, \"=r\", \"r\"(__r4));              \\\n      }\n    #undef _syscall2\n    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2) {                           \\\n        register unsigned long __r7 __asm__(\"$7\");                            \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2);                                   \\\n        LSS_BODY(type, name, \"=r\", \"r\"(__r4), \"r\"(__r5));                     \\\n      }\n    #undef _syscall3\n    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {               \\\n        register unsigned long __r7 __asm__(\"$7\");                            \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \\\n        LSS_BODY(type, name, \"=r\", \"r\"(__r4), \"r\"(__r5), \"r\"(__r6));          \\\n      }\n    #undef _syscall4\n    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {   \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \\\n        LSS_REG(7, arg4);                                                     \\\n        LSS_BODY(type, name, \"+r\", \"r\"(__r4), \"r\"(__r5), \"r\"(__r6));          \\\n      }\n    #undef _syscall5\n    #if _MIPS_SIM == _MIPS_SIM_ABI32\n    /* The old 32bit MIPS system call API passes the fifth and sixth argument\n     * on the stack, whereas the new APIs use registers \"r8\" and \"r9\".\n     */\n    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5)                                             \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5) {                                       \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \\\n        LSS_REG(7, arg4);                                                     \\\n        register unsigned long __v0 __asm__(\"$2\");                            \\\n        __asm__ __volatile__ (\".set noreorder\\n\"                              \\\n                              \"lw    $2, %6\\n\"                                \\\n                              \"subu  $29, 32\\n\"                               \\\n                              \"sw    $2, 16($29)\\n\"                           \\\n                              \"li    $2, %2\\n\"                                \\\n                              \"syscall\\n\"                                     \\\n                              \"addiu $29, 32\\n\"                               \\\n                              \".set reorder\\n\"                                \\\n                              : \"=&r\"(__v0), \"+r\" (__r7)                      \\\n                              : \"i\" (__NR_##name), \"r\"(__r4), \"r\"(__r5),      \\\n                                \"r\"(__r6), \"m\" ((unsigned long)arg5)          \\\n                              : \"$8\", \"$9\", \"$10\", \"$11\", \"$12\",              \\\n                                \"$13\", \"$14\", \"$15\", \"$24\", \"memory\");        \\\n        LSS_RETURN(type, __v0, __r7);                                         \\\n      }\n    #else\n    #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5)                                             \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5) {                                       \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \\\n        LSS_REG(7, arg4); LSS_REG(8, arg5);                                   \\\n        LSS_BODY(type, name, \"+r\", \"r\"(__r4), \"r\"(__r5), \"r\"(__r6),           \\\n                 \"r\"(__r8));                                                  \\\n      }\n    #endif\n    #undef _syscall6\n    #if _MIPS_SIM == _MIPS_SIM_ABI32\n    /* The old 32bit MIPS system call API passes the fifth and sixth argument\n     * on the stack, whereas the new APIs use registers \"r8\" and \"r9\".\n     */\n    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5,type6,arg6)                                  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5, type6 arg6) {                           \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \\\n        LSS_REG(7, arg4);                                                     \\\n        register unsigned long __v0 __asm__(\"$2\");                            \\\n        __asm__ __volatile__ (\".set noreorder\\n\"                              \\\n                              \"lw    $2, %6\\n\"                                \\\n                              \"lw    $8, %7\\n\"                                \\\n                              \"subu  $29, 32\\n\"                               \\\n                              \"sw    $2, 16($29)\\n\"                           \\\n                              \"sw    $8, 20($29)\\n\"                           \\\n                              \"li    $2, %2\\n\"                                \\\n                              \"syscall\\n\"                                     \\\n                              \"addiu $29, 32\\n\"                               \\\n                              \".set reorder\\n\"                                \\\n                              : \"=&r\"(__v0), \"+r\" (__r7)                      \\\n                              : \"i\" (__NR_##name), \"r\"(__r4), \"r\"(__r5),      \\\n                                \"r\"(__r6), \"r\" ((unsigned long)arg5),         \\\n                                \"r\" ((unsigned long)arg6)                     \\\n                              : \"$8\", \"$9\", \"$10\", \"$11\", \"$12\",              \\\n                                \"$13\", \"$14\", \"$15\", \"$24\", \"memory\");        \\\n        LSS_RETURN(type, __v0, __r7);                                         \\\n      }\n    #else\n    #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,  \\\n                      type5,arg5,type6,arg6)                                  \\\n      type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,     \\\n                          type5 arg5,type6 arg6) {                            \\\n        LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3);                 \\\n        LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6);                 \\\n        LSS_BODY(type, name, \"+r\", \"r\"(__r4), \"r\"(__r5), \"r\"(__r6),           \\\n                 \"r\"(__r8), \"r\"(__r9));                                       \\\n      }\n    #endif\n    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,\n                                   int flags, void *arg, int *parent_tidptr,\n                                   void *newtls, int *child_tidptr) {\n      register unsigned long __v0 __asm__(\"$2\");\n      register unsigned long __r7 __asm__(\"$7\") = (unsigned long)newtls;\n      {\n        register int   __flags __asm__(\"$4\") = flags;\n        register void *__stack __asm__(\"$5\") = child_stack;\n        register void *__ptid  __asm__(\"$6\") = parent_tidptr;\n        register int  *__ctid  __asm__(\"$8\") = child_tidptr;\n        __asm__ __volatile__(\n          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32\n                             \"subu  $29,24\\n\"\n          #elif _MIPS_SIM == _MIPS_SIM_NABI32\n                             \"sub   $29,16\\n\"\n          #else\n                             \"dsubu $29,16\\n\"\n          #endif\n\n                             /* if (fn == NULL || child_stack == NULL)\n                              *   return -EINVAL;\n                              */\n                             \"li    %0,%2\\n\"\n                             \"beqz  %5,1f\\n\"\n                             \"beqz  %6,1f\\n\"\n\n                             /* Push \"arg\" and \"fn\" onto the stack that will be\n                              * used by the child.\n                              */\n          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32\n                             \"subu  %6,32\\n\"\n                             \"sw    %5,0(%6)\\n\"\n                             \"sw    %8,4(%6)\\n\"\n          #elif _MIPS_SIM == _MIPS_SIM_NABI32\n                             \"sub   %6,32\\n\"\n                             \"sw    %5,0(%6)\\n\"\n                             \"sw    %8,8(%6)\\n\"\n          #else\n                             \"dsubu %6,32\\n\"\n                             \"sd    %5,0(%6)\\n\"\n                             \"sd    %8,8(%6)\\n\"\n          #endif\n\n                             /* $7 = syscall($4 = flags,\n                              *              $5 = child_stack,\n                              *              $6 = parent_tidptr,\n                              *              $7 = newtls,\n                              *              $8 = child_tidptr)\n                              */\n                             \"li    $2,%3\\n\"\n                             \"syscall\\n\"\n\n                             /* if ($7 != 0)\n                              *   return $2;\n                              */\n                             \"bnez  $7,1f\\n\"\n                             \"bnez  $2,1f\\n\"\n\n                             /* In the child, now. Call \"fn(arg)\".\n                              */\n          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32\n                            \"lw    $25,0($29)\\n\"\n                            \"lw    $4,4($29)\\n\"\n          #elif _MIPS_SIM == _MIPS_SIM_NABI32\n                            \"lw    $25,0($29)\\n\"\n                            \"lw    $4,8($29)\\n\"\n          #else\n                            \"ld    $25,0($29)\\n\"\n                            \"ld    $4,8($29)\\n\"\n          #endif\n                            \"jalr  $25\\n\"\n\n                             /* Call _exit($2)\n                              */\n                            \"move  $4,$2\\n\"\n                            \"li    $2,%4\\n\"\n                            \"syscall\\n\"\n\n                           \"1:\\n\"\n          #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32\n                             \"addu  $29, 24\\n\"\n          #elif _MIPS_SIM == _MIPS_SIM_NABI32\n                             \"add   $29, 16\\n\"\n          #else\n                             \"daddu $29,16\\n\"\n          #endif\n                             : \"=&r\" (__v0), \"=r\" (__r7)\n                             : \"i\"(-EINVAL), \"i\"(__NR_clone), \"i\"(__NR_exit),\n                               \"r\"(fn), \"r\"(__stack), \"r\"(__flags), \"r\"(arg),\n                               \"r\"(__ptid), \"r\"(__r7), \"r\"(__ctid)\n                             : \"$9\", \"$10\", \"$11\", \"$12\", \"$13\", \"$14\", \"$15\",\n                               \"$24\", \"memory\");\n      }\n      LSS_RETURN(int, __v0, __r7);\n    }\n  #elif defined (__PPC__)\n    #undef  LSS_LOADARGS_0\n    #define LSS_LOADARGS_0(name, dummy...)                                    \\\n        __sc_0 = __NR_##name\n    #undef  LSS_LOADARGS_1\n    #define LSS_LOADARGS_1(name, arg1)                                        \\\n            LSS_LOADARGS_0(name);                                             \\\n            __sc_3 = (unsigned long) (arg1)\n    #undef  LSS_LOADARGS_2\n    #define LSS_LOADARGS_2(name, arg1, arg2)                                  \\\n            LSS_LOADARGS_1(name, arg1);                                       \\\n            __sc_4 = (unsigned long) (arg2)\n    #undef  LSS_LOADARGS_3\n    #define LSS_LOADARGS_3(name, arg1, arg2, arg3)                            \\\n            LSS_LOADARGS_2(name, arg1, arg2);                                 \\\n            __sc_5 = (unsigned long) (arg3)\n    #undef  LSS_LOADARGS_4\n    #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4)                      \\\n            LSS_LOADARGS_3(name, arg1, arg2, arg3);                           \\\n            __sc_6 = (unsigned long) (arg4)\n    #undef  LSS_LOADARGS_5\n    #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5)                \\\n            LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4);                     \\\n            __sc_7 = (unsigned long) (arg5)\n    #undef  LSS_LOADARGS_6\n    #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6)          \\\n            LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5);               \\\n            __sc_8 = (unsigned long) (arg6)\n    #undef  LSS_ASMINPUT_0\n    #define LSS_ASMINPUT_0 \"0\" (__sc_0)\n    #undef  LSS_ASMINPUT_1\n    #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, \"1\" (__sc_3)\n    #undef  LSS_ASMINPUT_2\n    #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, \"2\" (__sc_4)\n    #undef  LSS_ASMINPUT_3\n    #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, \"3\" (__sc_5)\n    #undef  LSS_ASMINPUT_4\n    #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, \"4\" (__sc_6)\n    #undef  LSS_ASMINPUT_5\n    #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, \"5\" (__sc_7)\n    #undef  LSS_ASMINPUT_6\n    #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, \"6\" (__sc_8)\n    #undef  LSS_BODY\n    #define LSS_BODY(nr, type, name, args...)                                 \\\n        long __sc_ret, __sc_err;                                              \\\n        {                                                                     \\\n                        register unsigned long __sc_0 __asm__ (\"r0\");         \\\n                        register unsigned long __sc_3 __asm__ (\"r3\");         \\\n                        register unsigned long __sc_4 __asm__ (\"r4\");         \\\n                        register unsigned long __sc_5 __asm__ (\"r5\");         \\\n                        register unsigned long __sc_6 __asm__ (\"r6\");         \\\n                        register unsigned long __sc_7 __asm__ (\"r7\");         \\\n                        register unsigned long __sc_8 __asm__ (\"r8\");         \\\n                                                                              \\\n            LSS_LOADARGS_##nr(name, args);                                    \\\n            __asm__ __volatile__                                              \\\n                (\"sc\\n\\t\"                                                     \\\n                 \"mfcr %0\"                                                    \\\n                 : \"=&r\" (__sc_0),                                            \\\n                   \"=&r\" (__sc_3), \"=&r\" (__sc_4),                            \\\n                   \"=&r\" (__sc_5), \"=&r\" (__sc_6),                            \\\n                   \"=&r\" (__sc_7), \"=&r\" (__sc_8)                             \\\n                 : LSS_ASMINPUT_##nr                                          \\\n                 : \"cr0\", \"ctr\", \"memory\",                                    \\\n                   \"r9\", \"r10\", \"r11\", \"r12\");                                \\\n            __sc_ret = __sc_3;                                                \\\n            __sc_err = __sc_0;                                                \\\n        }                                                                     \\\n        LSS_RETURN(type, __sc_ret, __sc_err)\n    #undef _syscall0\n    #define _syscall0(type, name)                                             \\\n       type LSS_NAME(name)(void) {                                            \\\n          LSS_BODY(0, type, name);                                            \\\n       }\n    #undef _syscall1\n    #define _syscall1(type, name, type1, arg1)                                \\\n       type LSS_NAME(name)(type1 arg1) {                                      \\\n          LSS_BODY(1, type, name, arg1);                                      \\\n       }\n    #undef _syscall2\n    #define _syscall2(type, name, type1, arg1, type2, arg2)                   \\\n       type LSS_NAME(name)(type1 arg1, type2 arg2) {                          \\\n          LSS_BODY(2, type, name, arg1, arg2);                                \\\n       }\n    #undef _syscall3\n    #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3)      \\\n       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) {              \\\n          LSS_BODY(3, type, name, arg1, arg2, arg3);                          \\\n       }\n    #undef _syscall4\n    #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3,      \\\n                                  type4, arg4)                                \\\n       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {  \\\n          LSS_BODY(4, type, name, arg1, arg2, arg3, arg4);                    \\\n       }\n    #undef _syscall5\n    #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3,      \\\n                                  type4, arg4, type5, arg5)                   \\\n       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \\\n                                               type5 arg5) {                  \\\n          LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5);              \\\n       }\n    #undef _syscall6\n    #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3,      \\\n                                  type4, arg4, type5, arg5, type6, arg6)      \\\n       type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4,    \\\n                                               type5 arg5, type6 arg6) {      \\\n          LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6);        \\\n       }\n    /* clone function adapted from glibc 2.3.6 clone.S                       */\n    /* TODO(csilvers): consider wrapping some args up in a struct, like we\n     * do for i386's _syscall6, so we can compile successfully on gcc 2.95\n     */\n    LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,\n                                   int flags, void *arg, int *parent_tidptr,\n                                   void *newtls, int *child_tidptr) {\n      long __ret, __err;\n      {\n        register int (*__fn)(void *)    __asm__ (\"r8\")  = fn;\n        register void *__cstack                 __asm__ (\"r4\")  = child_stack;\n        register int __flags                    __asm__ (\"r3\")  = flags;\n        register void * __arg                   __asm__ (\"r9\")  = arg;\n        register int * __ptidptr                __asm__ (\"r5\")  = parent_tidptr;\n        register void * __newtls                __asm__ (\"r6\")  = newtls;\n        register int * __ctidptr                __asm__ (\"r7\")  = child_tidptr;\n        __asm__ __volatile__(\n            /* check for fn == NULL\n             * and child_stack == NULL\n             */\n            \"cmpwi cr0, %6, 0\\n\\t\"\n            \"cmpwi cr1, %7, 0\\n\\t\"\n            \"cror cr0*4+eq, cr1*4+eq, cr0*4+eq\\n\\t\"\n            \"beq- cr0, 1f\\n\\t\"\n\n            /* set up stack frame for child                                  */\n            \"clrrwi %7, %7, 4\\n\\t\"\n            \"li 0, 0\\n\\t\"\n            \"stwu 0, -16(%7)\\n\\t\"\n\n            /* fn, arg, child_stack are saved across the syscall: r28-30     */\n            \"mr 28, %6\\n\\t\"\n            \"mr 29, %7\\n\\t\"\n            \"mr 27, %9\\n\\t\"\n\n            /* syscall                                                       */\n            \"li 0, %4\\n\\t\"\n            /* flags already in r3\n             * child_stack already in r4\n             * ptidptr already in r5\n             * newtls already in r6\n             * ctidptr already in r7\n             */\n            \"sc\\n\\t\"\n\n            /* Test if syscall was successful                                */\n            \"cmpwi cr1, 3, 0\\n\\t\"\n            \"crandc cr1*4+eq, cr1*4+eq, cr0*4+so\\n\\t\"\n            \"bne- cr1, 1f\\n\\t\"\n\n            /* Do the function call                                          */\n            \"mtctr 28\\n\\t\"\n            \"mr 3, 27\\n\\t\"\n            \"bctrl\\n\\t\"\n\n            /* Call _exit(r3)                                                */\n            \"li 0, %5\\n\\t\"\n            \"sc\\n\\t\"\n\n            /* Return to parent                                              */\n            \"1:\\n\"\n            \"mfcr %1\\n\\t\"\n            \"mr %0, 3\\n\\t\"\n              : \"=r\" (__ret), \"=r\" (__err)\n              : \"0\" (-1), \"1\" (EINVAL),\n                \"i\" (__NR_clone), \"i\" (__NR_exit),\n                \"r\" (__fn), \"r\" (__cstack), \"r\" (__flags),\n                \"r\" (__arg), \"r\" (__ptidptr), \"r\" (__newtls),\n                \"r\" (__ctidptr)\n              : \"cr0\", \"cr1\", \"memory\", \"ctr\",\n                \"r0\", \"r29\", \"r27\", \"r28\");\n      }\n      LSS_RETURN(int, __ret, __err);\n    }\n  #endif\n  #define __NR__exit   __NR_exit\n  #define __NR__gettid __NR_gettid\n  #define __NR__mremap __NR_mremap\n  LSS_INLINE _syscall1(int,     chdir,           const char *,p)\n  LSS_INLINE _syscall1(int,     close,           int,         f)\n  LSS_INLINE _syscall2(int,     clock_getres,    int,         c,\n                       struct kernel_timespec*, t)\n  LSS_INLINE _syscall2(int,     clock_gettime,   int,         c,\n                       struct kernel_timespec*, t)\n  LSS_INLINE _syscall1(int,     dup,             int,         f)\n  LSS_INLINE _syscall2(int,     dup2,            int,         s,\n                       int,            d)\n  LSS_INLINE _syscall3(int,     execve,          const char*, f,\n                       const char*const*,a,const char*const*, e)\n  LSS_INLINE _syscall1(int,     _exit,           int,         e)\n  LSS_INLINE _syscall3(int,     fcntl,           int,         f,\n                       int,            c, long,   a)\n  LSS_INLINE _syscall0(pid_t,   fork)\n  LSS_INLINE _syscall2(int,     fstat,           int,         f,\n                      struct kernel_stat*,   b)\n  LSS_INLINE _syscall2(int,     fstatfs,         int,         f,\n                      struct kernel_statfs*, b)\n  LSS_INLINE _syscall4(int,     futex,           int*,        a,\n                       int,            o, int,    v,\n                      struct kernel_timespec*, t)\n  LSS_INLINE _syscall3(int,     getdents,        int,         f,\n                      struct kernel_dirent*, d, int,    c)\n  LSS_INLINE _syscall3(int,     getdents64,      int,         f,\n                      struct kernel_dirent64*, d, int,    c)\n  LSS_INLINE _syscall0(gid_t,   getegid)\n  LSS_INLINE _syscall0(uid_t,   geteuid)\n  LSS_INLINE _syscall0(pid_t,   getpgrp)\n  LSS_INLINE _syscall0(pid_t,   getpid)\n  LSS_INLINE _syscall0(pid_t,   getppid)\n  LSS_INLINE _syscall2(int,     getpriority,     int,         a,\n                       int,            b)\n  LSS_INLINE _syscall2(int,     getrlimit,       int,         r,\n                      struct kernel_rlimit*, l)\n  LSS_INLINE _syscall1(pid_t,   getsid,          pid_t,       p)\n  LSS_INLINE _syscall0(pid_t,   _gettid)\n  LSS_INLINE _syscall5(int,     setxattr,        const char *,p,\n                       const char *,   n,        const void *,v,\n                       size_t,         s,        int,         f)\n  LSS_INLINE _syscall5(int,     lsetxattr,       const char *,p,\n                       const char *,   n,        const void *,v,\n                       size_t,         s,        int,         f)\n  LSS_INLINE _syscall4(ssize_t, getxattr,        const char *,p,\n                       const char *,   n,        void *,      v, size_t, s)\n  LSS_INLINE _syscall4(ssize_t, lgetxattr,       const char *,p,\n                       const char *,   n,        void *,      v, size_t, s)\n  LSS_INLINE _syscall3(ssize_t, listxattr,       const char *,p,\n                       char *,   l,              size_t,      s)\n  LSS_INLINE _syscall3(ssize_t, llistxattr,      const char *,p,\n                       char *,   l,              size_t,      s)\n  LSS_INLINE _syscall2(int,     ioprio_get,      int,         which,\n                       int,     who)\n  LSS_INLINE _syscall3(int,     ioprio_set,      int,         which,\n                       int,     who,             int,         ioprio)\n  LSS_INLINE _syscall2(int,     kill,            pid_t,       p,\n                       int,            s)\n  LSS_INLINE _syscall3(off_t,   lseek,           int,         f,\n                       off_t,          o, int,    w)\n  LSS_INLINE _syscall2(int,     munmap,          void*,       s,\n                       size_t,         l)\n  LSS_INLINE _syscall6(long,    move_pages,      pid_t,       p,\n                       unsigned long,  n, void **,g, int *,   d,\n                       int *,          s, int,    f)\n  LSS_INLINE _syscall5(void*,   _mremap,         void*,       o,\n                       size_t,         os,       size_t,      ns,\n                       unsigned long,  f, void *, a)\n  LSS_INLINE _syscall3(int,     open,            const char*, p,\n                       int,            f, int,    m)\n  LSS_INLINE _syscall3(int,     poll,           struct kernel_pollfd*, u,\n                       unsigned int,   n, int,    t)\n  LSS_INLINE _syscall2(int,     prctl,           int,         o,\n                       long,           a)\n  LSS_INLINE _syscall4(long,    ptrace,          int,         r,\n                       pid_t,          p, void *, a, void *, d)\n  LSS_INLINE _syscall3(ssize_t, read,            int,         f,\n                       void *,         b, size_t, c)\n  LSS_INLINE _syscall3(int,     readlink,        const char*, p,\n                       char*,          b, size_t, s)\n  LSS_INLINE _syscall4(int,     rt_sigaction,    int,         s,\n                       const struct kernel_sigaction*, a,\n                       struct kernel_sigaction*, o, size_t,   c)\n  LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s,\n                       size_t,         c)\n  LSS_INLINE _syscall4(int, rt_sigprocmask,      int,         h,\n                       const struct kernel_sigset_t*,  s,\n                       struct kernel_sigset_t*,        o, size_t, c);\n  LSS_INLINE _syscall2(int, rt_sigsuspend,\n                       const struct kernel_sigset_t*, s,  size_t, c);\n  LSS_INLINE _syscall3(int,     sched_getaffinity,pid_t,      p,\n                       unsigned int,   l, unsigned long *, m)\n  LSS_INLINE _syscall3(int,     sched_setaffinity,pid_t,      p,\n                       unsigned int,   l, unsigned long *, m)\n  LSS_INLINE _syscall0(int,     sched_yield)\n  LSS_INLINE _syscall1(long,    set_tid_address, int *,       t)\n  LSS_INLINE _syscall1(int,     setfsgid,        gid_t,       g)\n  LSS_INLINE _syscall1(int,     setfsuid,        uid_t,       u)\n  LSS_INLINE _syscall1(int,     setuid,          uid_t,       u)\n  LSS_INLINE _syscall1(int,     setgid,          gid_t,       g)\n  LSS_INLINE _syscall2(int,     setpgid,         pid_t,       p,\n                       pid_t,          g)\n  LSS_INLINE _syscall3(int,     setpriority,     int,         a,\n                       int,            b, int,    p)\n  LSS_INLINE _syscall3(int,     setresgid,       gid_t,       r,\n                       gid_t,          e, gid_t,  s)\n  LSS_INLINE _syscall3(int,     setresuid,       uid_t,       r,\n                       uid_t,          e, uid_t,  s)\n  LSS_INLINE _syscall2(int,     setrlimit,       int,         r,\n                       const struct kernel_rlimit*, l)\n  LSS_INLINE _syscall0(pid_t,    setsid)\n  LSS_INLINE _syscall2(int,     sigaltstack,     const stack_t*, s,\n                       const stack_t*, o)\n  LSS_INLINE _syscall2(int,     stat,            const char*, f,\n                      struct kernel_stat*,   b)\n  LSS_INLINE _syscall2(int,     statfs,          const char*, f,\n                      struct kernel_statfs*, b)\n  LSS_INLINE _syscall3(ssize_t, write,            int,        f,\n                       const void *,   b, size_t, c)\n  LSS_INLINE _syscall3(ssize_t, writev,           int,        f,\n                       const struct kernel_iovec*, v, size_t, c)\n  #if defined(__NR_getcpu)\n    LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,\n                         unsigned *, node, void *, unused);\n  #endif\n  #if defined(__x86_64__) ||                                                  \\\n     (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)\n    LSS_INLINE _syscall3(int, recvmsg,            int,   s,\n                        struct kernel_msghdr*,     m, int, f)\n    LSS_INLINE _syscall3(int, sendmsg,            int,   s,\n                         const struct kernel_msghdr*, m, int, f)\n    LSS_INLINE _syscall6(int, sendto,             int,   s,\n                         const void*,             m, size_t, l,\n                         int,                     f,\n                         const struct kernel_sockaddr*, a, int, t)\n    LSS_INLINE _syscall2(int, shutdown,           int,   s,\n                         int,                     h)\n    LSS_INLINE _syscall3(int, socket,             int,   d,\n                         int,                     t, int,       p)\n    LSS_INLINE _syscall4(int, socketpair,         int,   d,\n                         int,                     t, int,       p, int*, s)\n  #endif\n  #if defined(__x86_64__)\n    LSS_INLINE _syscall4(int, fallocate, int, fd, int, mode,\n                         loff_t, offset, loff_t, len)\n    LSS_INLINE _syscall6(void*, mmap,              void*, s,\n                         size_t,                   l, int,               p,\n                         int,                      f, int,               d,\n                         __off64_t,                o)\n    LSS_INLINE _syscall4(int, newfstatat,         int,   d,\n                         const char *,            p,\n                        struct kernel_stat*,       b, int, f)\n\n    LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {\n      return LSS_NAME(setfsgid)(gid);\n    }\n\n    LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {\n      return LSS_NAME(setfsuid)(uid);\n    }\n\n    LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {\n      return LSS_NAME(setresgid)(rgid, egid, sgid);\n    }\n\n    LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {\n      return LSS_NAME(setresuid)(ruid, euid, suid);\n    }\n\n    LSS_INLINE int LSS_NAME(sigaction)(int signum,\n                                       const struct kernel_sigaction *act,\n                                       struct kernel_sigaction *oldact) {\n      /* On x86_64, the kernel requires us to always set our own\n       * SA_RESTORER in order to be able to return from a signal handler.\n       * This function must have a \"magic\" signature that the \"gdb\"\n       * (and maybe the kernel?) can recognize.\n       */\n      if (act != NULL && !(act->sa_flags & SA_RESTORER)) {\n        struct kernel_sigaction a = *act;\n        a.sa_flags   |= SA_RESTORER;\n        a.sa_restorer = LSS_NAME(restore_rt)();\n        return LSS_NAME(rt_sigaction)(signum, &a, oldact,\n                                      (KERNEL_NSIG+7)/8);\n      } else {\n        return LSS_NAME(rt_sigaction)(signum, act, oldact,\n                                      (KERNEL_NSIG+7)/8);\n      }\n    }\n\n    LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {\n      return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);\n    }\n\n    LSS_INLINE int LSS_NAME(sigprocmask)(int how,\n                                         const struct kernel_sigset_t *set,\n                                         struct kernel_sigset_t *oldset) {\n      return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);\n    }\n\n    LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {\n      return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);\n    }\n  #endif\n  #if defined(__x86_64__) || defined(__ARM_ARCH_3__) ||                       \\\n     (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)\n    LSS_INLINE _syscall4(pid_t, wait4,            pid_t, p,\n                         int*,                    s, int,       o,\n                        struct kernel_rusage*,     r)\n\n    LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){\n      return LSS_NAME(wait4)(pid, status, options, 0);\n    }\n  #endif\n  #if defined(__i386__) || defined(__x86_64__)\n    LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)\n    LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)\n  #endif\n  #if defined(__i386__) || defined(__ARM_ARCH_3__)\n    #define __NR__setfsgid32  __NR_setfsgid32\n    #define __NR__setfsuid32  __NR_setfsuid32\n    #define __NR__setresgid32 __NR_setresgid32\n    #define __NR__setresuid32 __NR_setresuid32\n    LSS_INLINE _syscall2(int,   ugetrlimit,        int,          r,\n                        struct kernel_rlimit*, l)\n    LSS_INLINE _syscall1(int,     _setfsgid32,      gid_t,       f)\n    LSS_INLINE _syscall1(int,     _setfsuid32,      uid_t,       f)\n    LSS_INLINE _syscall3(int,     _setresgid32,    gid_t,       r,\n                         gid_t,          e, gid_t,  s)\n    LSS_INLINE _syscall3(int,     _setresuid32,    uid_t,       r,\n                         uid_t,          e, uid_t,  s)\n\n    LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {\n      int rc;\n      if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&\n          LSS_ERRNO == ENOSYS) {\n        if ((unsigned int)gid & ~0xFFFFu) {\n          rc = EINVAL;\n        } else {\n          rc = LSS_NAME(setfsgid)(gid);\n        }\n      }\n      return rc;\n    }\n\n    LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {\n      int rc;\n      if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&\n          LSS_ERRNO == ENOSYS) {\n        if ((unsigned int)uid & ~0xFFFFu) {\n          rc = EINVAL;\n        } else {\n          rc = LSS_NAME(setfsuid)(uid);\n        }\n      }\n      return rc;\n    }\n\n    LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {\n      int rc;\n      if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&\n          LSS_ERRNO == ENOSYS) {\n        if ((unsigned int)rgid & ~0xFFFFu ||\n            (unsigned int)egid & ~0xFFFFu ||\n            (unsigned int)sgid & ~0xFFFFu) {\n          rc = EINVAL;\n        } else {\n          rc = LSS_NAME(setresgid)(rgid, egid, sgid);\n        }\n      }\n      return rc;\n    }\n\n    LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {\n      int rc;\n      if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&\n          LSS_ERRNO == ENOSYS) {\n        if ((unsigned int)ruid & ~0xFFFFu ||\n            (unsigned int)euid & ~0xFFFFu ||\n            (unsigned int)suid & ~0xFFFFu) {\n          rc = EINVAL;\n        } else {\n          rc = LSS_NAME(setresuid)(ruid, euid, suid);\n        }\n      }\n      return rc;\n    }\n  #endif\n  LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {\n    memset(&set->sig, 0, sizeof(set->sig));\n    return 0;\n  }\n  \n  LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) {\n    memset(&set->sig, -1, sizeof(set->sig));\n    return 0;\n  }\n  \n  LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set,\n                                     int signum) {\n    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {\n      LSS_ERRNO = EINVAL;\n      return -1;\n    } else {\n      set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]\n          |= 1UL << ((signum - 1) % (8*sizeof(set->sig[0])));\n      return 0;\n    }\n  }\n  \n  LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set,\n                                        int signum) {\n    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {\n      LSS_ERRNO = EINVAL;\n      return -1;\n    } else {\n      set->sig[(signum - 1)/(8*sizeof(set->sig[0]))]\n          &= ~(1UL << ((signum - 1) % (8*sizeof(set->sig[0]))));\n      return 0;\n    }\n  }\n  \n  LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set,\n                                          int signum) {\n    if (signum < 1 || signum > (int)(8*sizeof(set->sig))) {\n      LSS_ERRNO = EINVAL;\n      return -1;\n    } else {\n      return !!(set->sig[(signum - 1)/(8*sizeof(set->sig[0]))] &\n                (1UL << ((signum - 1) % (8*sizeof(set->sig[0])))));\n    }\n  }\n  #if defined(__i386__) || defined(__ARM_ARCH_3__) ||                         \\\n     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || defined(__PPC__)\n    #define __NR__sigaction   __NR_sigaction\n    #define __NR__sigpending  __NR_sigpending\n    #define __NR__sigprocmask __NR_sigprocmask\n    #define __NR__sigsuspend  __NR_sigsuspend\n    #define __NR__socketcall  __NR_socketcall\n    LSS_INLINE _syscall2(int, fstat64,             int, f,\n                         struct kernel_stat64 *, b)\n    LSS_INLINE _syscall5(int, _llseek,     uint, fd, ulong, hi, ulong, lo,\n                         loff_t *, res, uint, wh)\n    LSS_INLINE _syscall1(void*, mmap,              void*, a)\n#ifndef __PPC64__\n    LSS_INLINE _syscall6(void*, mmap2,             void*, s,\n                         size_t,                   l, int,               p,\n                         int,                      f, int,               d,\n                         off_t,                    o)\n#endif\n    LSS_INLINE _syscall3(int,   _sigaction,        int,   s,\n                         const struct kernel_old_sigaction*,  a,\n                         struct kernel_old_sigaction*,        o)\n    LSS_INLINE _syscall1(int,   _sigpending, unsigned long*, s)\n    LSS_INLINE _syscall3(int,   _sigprocmask,      int,   h,\n                         const unsigned long*,     s,\n                         unsigned long*,           o)\n    #ifdef __PPC__\n    LSS_INLINE _syscall1(int, _sigsuspend,         unsigned long, s)\n    #else\n    LSS_INLINE _syscall3(int, _sigsuspend,         const void*, a,\n                         int,                      b,\n                         unsigned long,            s)\n    #endif\n    LSS_INLINE _syscall2(int, stat64,              const char *, p,\n                         struct kernel_stat64 *, b)\n\n    LSS_INLINE int LSS_NAME(sigaction)(int signum,\n                                       const struct kernel_sigaction *act,\n                                       struct kernel_sigaction *oldact) {\n      int old_errno = LSS_ERRNO;\n      int rc;\n      struct kernel_sigaction a;\n      if (act != NULL) {\n        a             = *act;\n        #ifdef __i386__\n        /* On i386, the kernel requires us to always set our own\n         * SA_RESTORER when using realtime signals. Otherwise, it does not\n         * know how to return from a signal handler. This function must have\n         * a \"magic\" signature that the \"gdb\" (and maybe the kernel?) can\n         * recognize.\n         * Apparently, a SA_RESTORER is implicitly set by the kernel, when\n         * using non-realtime signals.\n         *\n         * TODO: Test whether ARM needs a restorer\n         */\n        if (!(a.sa_flags & SA_RESTORER)) {\n          a.sa_flags   |= SA_RESTORER;\n          a.sa_restorer = (a.sa_flags & SA_SIGINFO)\n                          ? LSS_NAME(restore_rt)() : LSS_NAME(restore)();\n        }\n        #endif\n      }\n      rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact,\n                                  (KERNEL_NSIG+7)/8);\n      if (rc < 0 && LSS_ERRNO == ENOSYS) {\n        struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa;\n        if (!act) {\n          ptr_a            = NULL;\n        } else {\n          oa.sa_handler_   = act->sa_handler_;\n          memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask));\n          #ifndef __mips__\n          oa.sa_restorer   = act->sa_restorer;\n          #endif\n          oa.sa_flags      = act->sa_flags;\n        }\n        if (!oldact) {\n          ptr_oa           = NULL;\n        }\n        LSS_ERRNO = old_errno;\n        rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa);\n        if (rc == 0 && oldact) {\n          if (act) {\n            memcpy(oldact, act, sizeof(*act));\n          } else {\n            memset(oldact, 0, sizeof(*oldact));\n          }\n          oldact->sa_handler_    = ptr_oa->sa_handler_;\n          oldact->sa_flags       = ptr_oa->sa_flags;\n          memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask));\n          #ifndef __mips__\n          oldact->sa_restorer    = ptr_oa->sa_restorer;\n          #endif\n        }\n      }\n      return rc;\n    }\n\n    LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) {\n      int old_errno = LSS_ERRNO;\n      int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8);\n      if (rc < 0 && LSS_ERRNO == ENOSYS) {\n        LSS_ERRNO = old_errno;\n        LSS_NAME(sigemptyset)(set);\n        rc = LSS_NAME(_sigpending)(&set->sig[0]);\n      }\n      return rc;\n    }\n\n    LSS_INLINE int LSS_NAME(sigprocmask)(int how,\n                                         const struct kernel_sigset_t *set,\n                                         struct kernel_sigset_t *oldset) {\n      int olderrno = LSS_ERRNO;\n      int rc = LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);\n      if (rc < 0 && LSS_ERRNO == ENOSYS) {\n        LSS_ERRNO = olderrno;\n        if (oldset) {\n          LSS_NAME(sigemptyset)(oldset);\n        }\n        rc = LSS_NAME(_sigprocmask)(how,\n                                    set ? &set->sig[0] : NULL,\n                                    oldset ? &oldset->sig[0] : NULL);\n      }\n      return rc;\n    }\n\n    LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) {\n      int olderrno = LSS_ERRNO;\n      int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8);\n      if (rc < 0 && LSS_ERRNO == ENOSYS) {\n        LSS_ERRNO = olderrno;\n        rc = LSS_NAME(_sigsuspend)(\n        #ifndef __PPC__\n                                   set, 0,\n        #endif\n                                   set->sig[0]);\n      }\n      return rc;\n    }\n  #endif\n  #if defined(__PPC__)\n    #undef LSS_SC_LOADARGS_0\n    #define LSS_SC_LOADARGS_0(dummy...)\n    #undef LSS_SC_LOADARGS_1\n    #define LSS_SC_LOADARGS_1(arg1)                                           \\\n        __sc_4  = (unsigned long) (arg1)\n    #undef LSS_SC_LOADARGS_2\n    #define LSS_SC_LOADARGS_2(arg1, arg2)                                     \\\n        LSS_SC_LOADARGS_1(arg1);                                              \\\n        __sc_5  = (unsigned long) (arg2)\n    #undef LSS_SC_LOADARGS_3\n    #define LSS_SC_LOADARGS_3(arg1, arg2, arg3)                               \\\n        LSS_SC_LOADARGS_2(arg1, arg2);                                        \\\n        __sc_6  = (unsigned long) (arg3)\n    #undef LSS_SC_LOADARGS_4\n    #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4)                         \\\n        LSS_SC_LOADARGS_3(arg1, arg2, arg3);                                  \\\n        __sc_7  = (unsigned long) (arg4)\n    #undef LSS_SC_LOADARGS_5\n    #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5)                   \\\n        LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4);                            \\\n        __sc_8  = (unsigned long) (arg5)\n    #undef LSS_SC_BODY\n    #define LSS_SC_BODY(nr, type, opt, args...)                               \\\n        long __sc_ret, __sc_err;                                              \\\n        {                                                                     \\\n          register unsigned long __sc_0 __asm__ (\"r0\") = __NR_socketcall;     \\\n          register unsigned long __sc_3 __asm__ (\"r3\") = opt;                 \\\n          register unsigned long __sc_4 __asm__ (\"r4\");                       \\\n          register unsigned long __sc_5 __asm__ (\"r5\");                       \\\n          register unsigned long __sc_6 __asm__ (\"r6\");                       \\\n          register unsigned long __sc_7 __asm__ (\"r7\");                       \\\n          register unsigned long __sc_8 __asm__ (\"r8\");                       \\\n          LSS_SC_LOADARGS_##nr(args);                                         \\\n          __asm__ __volatile__                                                \\\n              (\"stwu 1, -48(1)\\n\\t\"                                           \\\n               \"stw 4, 20(1)\\n\\t\"                                             \\\n               \"stw 5, 24(1)\\n\\t\"                                             \\\n               \"stw 6, 28(1)\\n\\t\"                                             \\\n               \"stw 7, 32(1)\\n\\t\"                                             \\\n               \"stw 8, 36(1)\\n\\t\"                                             \\\n               \"addi 4, 1, 20\\n\\t\"                                            \\\n               \"sc\\n\\t\"                                                       \\\n               \"mfcr %0\"                                                      \\\n                 : \"=&r\" (__sc_0),                                            \\\n                   \"=&r\" (__sc_3), \"=&r\" (__sc_4),                            \\\n                   \"=&r\" (__sc_5), \"=&r\" (__sc_6),                            \\\n                   \"=&r\" (__sc_7), \"=&r\" (__sc_8)                             \\\n                 : LSS_ASMINPUT_##nr                                          \\\n                 : \"cr0\", \"ctr\", \"memory\");                                   \\\n          __sc_ret = __sc_3;                                                  \\\n          __sc_err = __sc_0;                                                  \\\n        }                                                                     \\\n        LSS_RETURN(type, __sc_ret, __sc_err)\n\n    LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,\n                                         int flags){\n      LSS_SC_BODY(3, ssize_t, 17, s, msg, flags);\n    }\n\n    LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,\n                                         const struct kernel_msghdr *msg,\n                                         int flags) {\n      LSS_SC_BODY(3, ssize_t, 16, s, msg, flags);\n    }\n\n    // TODO(csilvers): why is this ifdef'ed out?\n#if 0\n    LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,\n                                        int flags,\n                                        const struct kernel_sockaddr *to,\n                                        unsigned int tolen) {\n      LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen);\n    }\n#endif\n\n    LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {\n      LSS_SC_BODY(2, int, 13, s, how);\n    }\n\n    LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {\n      LSS_SC_BODY(3, int, 1, domain, type, protocol);\n    }\n\n    LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,\n                                        int sv[2]) {\n      LSS_SC_BODY(4, int, 8, d, type, protocol, sv);\n    }\n  #endif\n  #if defined(__i386__) || defined(__ARM_ARCH_3__) ||                         \\\n      (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)\n    #define __NR__socketcall  __NR_socketcall\n    LSS_INLINE _syscall2(int,      _socketcall,    int,   c,\n                         va_list,                  a)\n\n    LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {\n      int rc;\n      va_list ap;\n      va_start(ap, op);\n      rc = LSS_NAME(_socketcall)(op, ap);\n      va_end(ap);\n      return rc;\n    }\n\n    LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg,\n                                         int flags){\n      return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);\n    }\n\n    LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s,\n                                         const struct kernel_msghdr *msg,\n                                         int flags) {\n      return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);\n    }\n\n    LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,\n                                        int flags,\n                                        const struct kernel_sockaddr *to,\n                                        unsigned int tolen) {\n      return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);\n    }\n\n    LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {\n      return LSS_NAME(socketcall)(13, s, how);\n    }\n\n    LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {\n      return LSS_NAME(socketcall)(1, domain, type, protocol);\n    }\n\n    LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,\n                                        int sv[2]) {\n      return LSS_NAME(socketcall)(8, d, type, protocol, sv);\n    }\n  #endif\n  #if defined(__i386__) || defined(__PPC__)\n    LSS_INLINE _syscall4(int,   fstatat64,        int,   d,\n                         const char *,      p,\n                         struct kernel_stat64 *,   b,    int,   f)\n  #endif\n  #if defined(__i386__) || defined(__PPC__) ||                                \\\n     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)\n    LSS_INLINE _syscall3(pid_t, waitpid,          pid_t, p,\n                         int*,              s,    int,   o)\n  #endif\n  #if defined(__mips__)\n    /* sys_pipe() on MIPS has non-standard calling conventions, as it returns\n     * both file handles through CPU registers.\n     */\n    LSS_INLINE int LSS_NAME(pipe)(int *p) {\n      register unsigned long __v0 __asm__(\"$2\") = __NR_pipe;\n      register unsigned long __v1 __asm__(\"$3\");\n      register unsigned long __r7 __asm__(\"$7\");\n      __asm__ __volatile__ (\"syscall\\n\"\n                            : \"=&r\"(__v0), \"=&r\"(__v1), \"+r\" (__r7)\n                            : \"0\"(__v0)\n                            : \"$8\", \"$9\", \"$10\", \"$11\", \"$12\",\n                              \"$13\", \"$14\", \"$15\", \"$24\", \"memory\");\n      if (__r7) {\n        LSS_ERRNO = __v0;\n        return -1;\n      } else {\n        p[0] = __v0;\n        p[1] = __v1;\n        return 0;\n      }\n    }\n  #else\n    LSS_INLINE _syscall1(int,     pipe,           int *, p)\n  #endif\n  /* TODO(csilvers): see if ppc can/should support this as well              */\n  #if defined(__i386__) || defined(__ARM_ARCH_3__) ||                         \\\n     (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64)\n    #define __NR__statfs64  __NR_statfs64\n    #define __NR__fstatfs64 __NR_fstatfs64\n    LSS_INLINE _syscall3(int, _statfs64,     const char*, p,\n                         size_t, s,struct kernel_statfs64*, b)\n    LSS_INLINE _syscall3(int, _fstatfs64,          int,   f,\n                         size_t, s,struct kernel_statfs64*, b)\n    LSS_INLINE int LSS_NAME(statfs64)(const char *p,\n                                     struct kernel_statfs64 *b) {\n      return LSS_NAME(_statfs64)(p, sizeof(*b), b);\n    }\n    LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) {\n      return LSS_NAME(_fstatfs64)(f, sizeof(*b), b);\n    }\n  #endif\n\n  LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) {\n    extern char **environ;\n    return LSS_NAME(execve)(path, argv, (const char *const *)environ);\n  }\n\n  LSS_INLINE pid_t LSS_NAME(gettid)() {\n    pid_t tid = LSS_NAME(_gettid)();\n    if (tid != -1) {\n      return tid;\n    }\n    return LSS_NAME(getpid)();\n  }\n\n  LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,\n                                    size_t new_size, int flags, ...) {\n    va_list ap;\n    void *new_address, *rc;\n    va_start(ap, flags);\n    new_address = va_arg(ap, void *);\n    rc = LSS_NAME(_mremap)(old_address, old_size, new_size,\n                           flags, new_address);\n    va_end(ap);\n    return rc;\n  }\n\n  LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {\n    /* PTRACE_DETACH can sometimes forget to wake up the tracee and it\n     * then sends job control signals to the real parent, rather than to\n     * the tracer. We reduce the risk of this happening by starting a\n     * whole new time slice, and then quickly sending a SIGCONT signal\n     * right after detaching from the tracee.\n     */\n    int rc, err;\n    LSS_NAME(sched_yield)();\n    rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);\n    err = LSS_ERRNO;\n    LSS_NAME(kill)(pid, SIGCONT);\n    LSS_ERRNO = err;\n    return rc;\n  }\n\n  LSS_INLINE int LSS_NAME(raise)(int sig) {\n    return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);\n  }\n\n  LSS_INLINE int LSS_NAME(setpgrp)() {\n    return LSS_NAME(setpgid)(0, 0);\n  }\n\n  LSS_INLINE int LSS_NAME(sysconf)(int name) {\n    extern int __getpagesize(void);\n    switch (name) {\n      case _SC_OPEN_MAX: {\n        struct kernel_rlimit limit;\n        return LSS_NAME(getrlimit)(RLIMIT_NOFILE, &limit) < 0\n               ? 8192 : limit.rlim_cur;\n      }\n      case _SC_PAGESIZE:\n        return __getpagesize();\n      default:\n        errno = ENOSYS;\n        return -1;\n    }\n  }\n  #if defined(__x86_64__) ||                                                  \\\n     (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64)\n    LSS_INLINE _syscall4(ssize_t, pread64,        int,         f,\n                         void *,         b, size_t,   c,\n                         loff_t,         o)\n    LSS_INLINE _syscall4(ssize_t, pwrite64,       int,         f,\n                         const void *,   b, size_t,   c,\n                         loff_t,         o)\n    LSS_INLINE _syscall3(int,     readahead,      int,         f,\n                         loff_t,         o, unsigned, c)\n  #else\n    #define __NR__pread64   __NR_pread64\n    #define __NR__pwrite64  __NR_pwrite64\n    #define __NR__readahead __NR_readahead\n    LSS_INLINE _syscall5(ssize_t, _pread64,        int,         f,\n                         void *,         b, size_t, c, unsigned, o1,\n                         unsigned, o2)\n    LSS_INLINE _syscall5(ssize_t, _pwrite64,       int,         f,\n                         const void *,   b, size_t, c, unsigned, o1,\n                         long, o2)\n    LSS_INLINE _syscall4(int, _readahead,          int,         f,\n                         unsigned,       o1, unsigned, o2, size_t, c);\n    /* We force 64bit-wide parameters onto the stack, then access each\n     * 32-bit component individually. This guarantees that we build the\n     * correct parameters independent of the native byte-order of the\n     * underlying architecture.\n     */\n    LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count,\n                                         loff_t off) {\n      union { loff_t off; unsigned arg[2]; } o = { off };\n      return LSS_NAME(_pread64)(fd, buf, count, o.arg[0], o.arg[1]);\n    }\n    LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf,\n                                          size_t count, loff_t off) {\n      union { loff_t off; unsigned arg[2]; } o = { off };\n      return LSS_NAME(_pwrite64)(fd, buf, count, o.arg[0], o.arg[1]);\n    }\n    LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, int len) {\n      union { loff_t off; unsigned arg[2]; } o = { off };\n      return LSS_NAME(_readahead)(fd, o.arg[0], o.arg[1], len);\n    }\n  #endif\n#endif\n\n#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)\n}\n#endif\n\n#endif\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/linuxthreads.cc",
    "content": "/* Copyright (c) 2005-2007, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Markus Gutschke\n */\n\n#include \"base/linuxthreads.h\"\n\n#ifdef THREADS\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <sched.h>\n#include <signal.h>\n#include <stdlib.h>\n#include <string.h>\n#include <fcntl.h>\n#include <sys/socket.h>\n#include <sys/wait.h>\n\n#include \"base/linux_syscall_support.h\"\n#include \"base/thread_lister.h\"\n\n#ifndef CLONE_UNTRACED\n#define CLONE_UNTRACED 0x00800000\n#endif\n\n\n/* Synchronous signals that should not be blocked while in the lister thread.\n */\nstatic const int sync_signals[]  = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,\n                                     SIGXCPU, SIGXFSZ };\n\n/* itoa() is not a standard function, and we cannot safely call printf()\n * after suspending threads. So, we just implement our own copy. A\n * recursive approach is the easiest here.\n */\nstatic char *local_itoa(char *buf, int i) {\n  if (i < 0) {\n    *buf++ = '-';\n    return local_itoa(buf, -i);\n  } else {\n    if (i >= 10)\n      buf = local_itoa(buf, i/10);\n    *buf++ = (i%10) + '0';\n    *buf   = '\\000';\n    return buf;\n  }\n}\n\n\n/* Wrapper around clone() that runs \"fn\" on the same stack as the\n * caller! Unlike fork(), the cloned thread shares the same address space.\n * The caller must be careful to use only minimal amounts of stack until\n * the cloned thread has returned.\n * There is a good chance that the cloned thread and the caller will share\n * the same copy of errno!\n */\n#ifdef __GNUC__\n#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3\n/* Try to force this function into a separate stack frame, and make sure\n * that arguments are passed on the stack.\n */\nstatic int local_clone (int (*fn)(void *), void *arg, ...)\n  __attribute__ ((noinline));\n#endif\n#endif\n\nstatic int local_clone (int (*fn)(void *), void *arg, ...) {\n  /* Leave 4kB of gap between the callers stack and the new clone. This\n   * should be more than sufficient for the caller to call waitpid() until\n   * the cloned thread terminates.\n   *\n   * It is important that we set the CLONE_UNTRACED flag, because newer\n   * versions of \"gdb\" otherwise attempt to attach to our thread, and will\n   * attempt to reap its status codes. This subsequently results in the\n   * caller hanging indefinitely in waitpid(), waiting for a change in\n   * status that will never happen. By setting the CLONE_UNTRACED flag, we\n   * prevent \"gdb\" from stealing events, but we still expect the thread\n   * lister to fail, because it cannot PTRACE_ATTACH to the process that\n   * is being debugged. This is OK and the error code will be reported\n   * correctly.\n   */\n  return sys_clone(fn, (char *)&arg - 4096,\n                   CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0);\n}\n\n\n/* Local substitute for the atoi() function, which is not necessarily safe\n * to call once threads are suspended (depending on whether libc looks up\n * locale information,  when executing atoi()).\n */\nstatic int local_atoi(const char *s) {\n  int n   = 0;\n  int neg = *s == '-';\n  if (neg)\n    s++;\n  while (*s >= '0' && *s <= '9')\n    n = 10*n + (*s++ - '0');\n  return neg ? -n : n;\n}\n\n\n/* Re-runs fn until it doesn't cause EINTR\n */\n#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)\n\n\n/* Wrap a class around system calls, in order to give us access to\n * a private copy of errno. This only works in C++, but it has the\n * advantage of not needing nested functions, which are a non-standard\n * language extension.\n */\n#ifdef __cplusplus\nnamespace {\n  class SysCalls {\n   public:\n    #define SYS_CPLUSPLUS\n    #define SYS_ERRNO     my_errno\n    #define SYS_INLINE    inline\n    #define SYS_PREFIX    -1\n    #undef  SYS_LINUX_SYSCALL_SUPPORT_H\n    #include \"linux_syscall_support.h\"\n    SysCalls() : my_errno(0) { }\n    int my_errno;\n  };\n}\n#define ERRNO sys.my_errno\n#else\n#define ERRNO my_errno\n#endif\n\n\n/* Wrapper for open() which is guaranteed to never return EINTR.\n */\nstatic int c_open(const char *fname, int flags, int mode) {\n  ssize_t rc;\n  NO_INTR(rc = sys_open(fname, flags, mode));\n  return rc;\n}\n\n\n/* abort() is not safely reentrant, and changes it's behavior each time\n * it is called. This means, if the main application ever called abort()\n * we cannot safely call it again. This would happen if we were called\n * from a SIGABRT signal handler in the main application. So, document\n * that calling SIGABRT from the thread lister makes it not signal safe\n * (and vice-versa).\n * Also, since we share address space with the main application, we\n * cannot call abort() from the callback and expect the main application\n * to behave correctly afterwards. In fact, the only thing we can do, is\n * to terminate the main application with extreme prejudice (aka\n * PTRACE_KILL).\n * We set up our own SIGABRT handler to do this.\n * In order to find the main application from the signal handler, we\n * need to store information about it in global variables. This is\n * safe, because the main application should be suspended at this\n * time. If the callback ever called ResumeAllProcessThreads(), then\n * we are running a higher risk, though. So, try to avoid calling\n * abort() after calling ResumeAllProcessThreads.\n */\nstatic volatile int *sig_pids, sig_num_threads, sig_proc, sig_marker;\n\n\n/* Signal handler to help us recover from dying while we are attached to\n * other threads.\n */\nstatic void SignalHandler(int signum, siginfo_t *si, void *data) {\n  if (sig_pids != NULL) {\n    if (signum == SIGABRT) {\n      while (sig_num_threads-- > 0) {\n        /* Not sure if sched_yield is really necessary here, but it does not */\n        /* hurt, and it might be necessary for the same reasons that we have */\n        /* to do so in sys_ptrace_detach().                                  */\n        sys_sched_yield();\n        sys_ptrace(PTRACE_KILL, sig_pids[sig_num_threads], 0, 0);\n      }\n    } else if (sig_num_threads > 0) {\n      ResumeAllProcessThreads(sig_num_threads, (int *)sig_pids);\n    }\n  }\n  sig_pids = NULL;\n  if (sig_marker >= 0)\n    NO_INTR(sys_close(sig_marker));\n  sig_marker = -1;\n  if (sig_proc >= 0)\n    NO_INTR(sys_close(sig_proc));\n  sig_proc = -1;\n\n  sys__exit(signum == SIGABRT ? 1 : 2);\n}\n\n\n/* Try to dirty the stack, and hope that the compiler is not smart enough\n * to optimize this function away. Or worse, the compiler could inline the\n * function and permanently allocate the data on the stack.\n */\nstatic void DirtyStack(size_t amount) {\n  char buf[amount];\n  memset(buf, 0, amount);\n  sys_read(-1, buf, amount);\n}\n\n\n/* Data structure for passing arguments to the lister thread.\n */\n#define ALT_STACKSIZE (MINSIGSTKSZ + 4096)\n\nstruct ListerParams {\n  int         result, err;\n  char        *altstack_mem;\n  ListAllProcessThreadsCallBack callback;\n  void        *parameter;\n  va_list     ap;\n};\n\n\nstatic void ListerThread(struct ListerParams *args) {\n  int                found_parent = 0;\n  pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();\n  char               proc_self_task[80], marker_name[48], *marker_path;\n  const char         *proc_paths[3];\n  const char *const  *proc_path = proc_paths;\n  int                proc = -1, marker = -1, num_threads = 0;\n  int                max_threads = 0, sig;\n  struct kernel_stat marker_sb, proc_sb;\n  stack_t            altstack;\n\n  /* Create \"marker\" that we can use to detect threads sharing the same\n   * address space and the same file handles. By setting the FD_CLOEXEC flag\n   * we minimize the risk of misidentifying child processes as threads;\n   * and since there is still a race condition,  we will filter those out\n   * later, anyway.\n   */\n  if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||\n      sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {\n  failure:\n    args->result = -1;\n    args->err    = errno;\n    if (marker >= 0)\n      NO_INTR(sys_close(marker));\n    sig_marker = marker = -1;\n    if (proc >= 0)\n      NO_INTR(sys_close(proc));\n    sig_proc = proc = -1;\n    sys__exit(1);\n  }\n\n  /* Compute search paths for finding thread directories in /proc            */\n  local_itoa(strrchr(strcpy(proc_self_task, \"/proc/\"), '\\000'), ppid);\n  strcpy(marker_name, proc_self_task);\n  marker_path = marker_name + strlen(marker_name);\n  strcat(proc_self_task, \"/task/\");\n  proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */\n  proc_paths[1] = \"/proc/\";       /* /proc/                                  */\n  proc_paths[2] = NULL;\n\n  /* Compute path for marker socket in /proc                                 */\n  local_itoa(strcpy(marker_path, \"/fd/\") + 4, marker);\n  if (sys_stat(marker_name, &marker_sb) < 0) {\n    goto failure;\n  }\n\n  /* Catch signals on an alternate pre-allocated stack. This way, we can\n   * safely execute the signal handler even if we ran out of memory.\n   */\n  memset(&altstack, 0, sizeof(altstack));\n  altstack.ss_sp    = args->altstack_mem;\n  altstack.ss_flags = 0;\n  altstack.ss_size  = ALT_STACKSIZE;\n  sys_sigaltstack(&altstack, (const stack_t *)NULL);\n\n  /* Some kernels forget to wake up traced processes, when the\n   * tracer dies.  So, intercept synchronous signals and make sure\n   * that we wake up our tracees before dying. It is the caller's\n   * responsibility to ensure that asynchronous signals do not\n   * interfere with this function.\n   */\n  sig_marker = marker;\n  sig_proc   = -1;\n  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {\n    struct kernel_sigaction sa;\n    memset(&sa, 0, sizeof(sa));\n    sa.sa_sigaction_ = SignalHandler;\n    sys_sigfillset(&sa.sa_mask);\n    sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;\n    sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);\n  }\n  \n  /* Read process directories in /proc/...                                   */\n  for (;;) {\n    /* Some kernels know about threads, and hide them in \"/proc\"\n     * (although they are still there, if you know the process\n     * id). Threads are moved into a separate \"task\" directory. We\n     * check there first, and then fall back on the older naming\n     * convention if necessary.\n     */\n    if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {\n      if (*++proc_path != NULL)\n        continue;\n      goto failure;\n    }\n    if (sys_fstat(proc, &proc_sb) < 0)\n      goto failure;\n    \n    /* Since we are suspending threads, we cannot call any libc\n     * functions that might acquire locks. Most notably, we cannot\n     * call malloc(). So, we have to allocate memory on the stack,\n     * instead. Since we do not know how much memory we need, we\n     * make a best guess. And if we guessed incorrectly we retry on\n     * a second iteration (by jumping to \"detach_threads\").\n     *\n     * Unless the number of threads is increasing very rapidly, we\n     * should never need to do so, though, as our guestimate is very\n     * conservative.\n     */\n    if (max_threads < proc_sb.st_nlink + 100)\n      max_threads = proc_sb.st_nlink + 100;\n    \n    /* scope */ {\n      pid_t pids[max_threads];\n      int   added_entries = 0;\n      sig_num_threads     = num_threads;\n      sig_pids            = pids;\n      for (;;) {\n        struct kernel_dirent *entry;\n        char buf[4096];\n        ssize_t nbytes = sys_getdents(proc, (struct kernel_dirent *)buf,\n                                      sizeof(buf));\n        if (nbytes < 0)\n          goto failure;\n        else if (nbytes == 0) {\n          if (added_entries) {\n            /* Need to keep iterating over \"/proc\" in multiple\n             * passes until we no longer find any more threads. This\n             * algorithm eventually completes, when all threads have\n             * been suspended.\n             */\n            added_entries = 0;\n            sys_lseek(proc, 0, SEEK_SET);\n            continue;\n          }\n          break;\n        }\n        for (entry = (struct kernel_dirent *)buf;\n             entry < (struct kernel_dirent *)&buf[nbytes];\n             entry = (struct kernel_dirent *)((char *)entry+entry->d_reclen)) {\n          if (entry->d_ino != 0) {\n            const char *ptr = entry->d_name;\n            pid_t pid;\n            \n            /* Some kernels hide threads by preceding the pid with a '.'     */\n            if (*ptr == '.')\n              ptr++;\n            \n            /* If the directory is not numeric, it cannot be a\n             * process/thread\n             */\n            if (*ptr < '0' || *ptr > '9')\n              continue;\n            pid = local_atoi(ptr);\n\n            /* Attach (and suspend) all threads                              */\n            if (pid && pid != clone_pid) {\n              struct kernel_stat tmp_sb;\n              char fname[entry->d_reclen + 48];\n              strcat(strcat(strcpy(fname, \"/proc/\"),\n                            entry->d_name), marker_path);\n              \n              /* Check if the marker is identical to the one we created      */\n              if (sys_stat(fname, &tmp_sb) >= 0 &&\n                  marker_sb.st_ino == tmp_sb.st_ino) {\n                long i, j;\n\n                /* Found one of our threads, make sure it is no duplicate    */\n                for (i = 0; i < num_threads; i++) {\n                  /* Linear search is slow, but should not matter much for\n                   * the typically small number of threads.\n                   */\n                  if (pids[i] == pid) {\n                    /* Found a duplicate; most likely on second pass         */\n                    goto next_entry;\n                  }\n                }\n                \n                /* Check whether data structure needs growing                */\n                if (num_threads >= max_threads) {\n                  /* Back to square one, this time with more memory          */\n                  NO_INTR(sys_close(proc));\n                  goto detach_threads;\n                }\n\n                /* Attaching to thread suspends it                           */\n                pids[num_threads++] = pid;\n                sig_num_threads     = num_threads;\n                if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,\n                               (void *)0) < 0) {\n                  /* If operation failed, ignore thread. Maybe it\n                   * just died?  There might also be a race\n                   * condition with a concurrent core dumper or\n                   * with a debugger. In that case, we will just\n                   * make a best effort, rather than failing\n                   * entirely.\n                   */\n                  num_threads--;\n                  sig_num_threads = num_threads;\n                  goto next_entry;\n                }\n                while (sys_waitpid(pid, (int *)0, __WALL) < 0) {\n                  if (errno != EINTR) {\n                    sys_ptrace_detach(pid);\n                    num_threads--;\n                    sig_num_threads = num_threads;\n                    goto next_entry;\n                  }\n                }\n                \n                if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||\n                    sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {\n                  /* Address spaces are distinct, even though both\n                   * processes show the \"marker\". This is probably\n                   * a forked child process rather than a thread.\n                   */\n                  sys_ptrace_detach(pid);\n                  num_threads--;\n                  sig_num_threads = num_threads;\n                } else {\n                  found_parent |= pid == ppid;\n                  added_entries++;\n                }\n              }\n            }\n          }\n        next_entry:;\n        }\n      }\n      NO_INTR(sys_close(proc));\n      sig_proc = proc = -1;\n\n      /* If we failed to find any threads, try looking somewhere else in\n       * /proc. Maybe, threads are reported differently on this system.\n       */\n      if (num_threads > 1 || !*++proc_path) {\n        NO_INTR(sys_close(marker));\n        sig_marker = marker = -1;\n\n        /* If we never found the parent process, something is very wrong.\n         * Most likely, we are running in debugger. Any attempt to operate\n         * on the threads would be very incomplete. Let's just report an\n         * error to the caller.\n         */\n        if (!found_parent) {\n          ResumeAllProcessThreads(num_threads, pids);\n          sys__exit(3);\n        }\n\n        /* Now we are ready to call the callback,\n         * which takes care of resuming the threads for us.\n         */\n        args->result = args->callback(args->parameter, num_threads,\n                                      pids, args->ap);\n        args->err = errno;\n\n        /* Callback should have resumed threads, but better safe than sorry  */\n        if (ResumeAllProcessThreads(num_threads, pids)) {\n          /* Callback forgot to resume at least one thread, report error     */\n          args->err    = EINVAL;\n          args->result = -1;\n        }\n\n        sys__exit(0);\n      }\n    detach_threads:\n      /* Resume all threads prior to retrying the operation                  */\n      ResumeAllProcessThreads(num_threads, pids);\n      sig_pids = NULL;\n      num_threads = 0;\n      sig_num_threads = num_threads;\n      max_threads += 100;\n    }\n  }\n}\n\n\n/* This function gets the list of all linux threads of the current process\n * passes them to the 'callback' along with the 'parameter' pointer; at the\n * call back call time all the threads are paused via\n * PTRACE_ATTACH.\n * The callback is executed from a separate thread which shares only the\n * address space, the filesystem, and the filehandles with the caller. Most\n * notably, it does not share the same pid and ppid; and if it terminates,\n * the rest of the application is still there. 'callback' is supposed to do\n * or arrange for ResumeAllProcessThreads. This happens automatically, if\n * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous\n * signals are blocked. If the 'callback' decides to unblock them, it must\n * ensure that they cannot terminate the application, or that\n * ResumeAllProcessThreads will get called.\n * It is an error for the 'callback' to make any library calls that could\n * acquire locks. Most notably, this means that most system calls have to\n * avoid going through libc. Also, this means that it is not legal to call\n * exit() or abort().\n * We return -1 on error and the return value of 'callback' on success.\n */\nint ListAllProcessThreads(void *parameter,\n                          ListAllProcessThreadsCallBack callback, ...) {\n  char                   altstack_mem[ALT_STACKSIZE];\n  struct ListerParams    args;\n  pid_t                  clone_pid;\n  int                    dumpable = 1, sig;\n  struct kernel_sigset_t sig_blocked, sig_old;\n\n  va_start(args.ap, callback);\n\n  /* If we are short on virtual memory, initializing the alternate stack\n   * might trigger a SIGSEGV. Let's do this early, before it could get us\n   * into more trouble (i.e. before signal handlers try to use the alternate\n   * stack, and before we attach to other threads).\n   */\n  memset(altstack_mem, 0, sizeof(altstack_mem));\n\n  /* Some of our cleanup functions could conceivable use more stack space.\n   * Try to touch the stack right now. This could be defeated by the compiler\n   * being too smart for it's own good, so try really hard.\n   */\n  DirtyStack(32768);\n\n  /* Make this process \"dumpable\". This is necessary in order to ptrace()\n   * after having called setuid().\n   */\n  dumpable = sys_prctl(PR_GET_DUMPABLE, 0);\n  if (!dumpable)\n    sys_prctl(PR_SET_DUMPABLE, 1);\n\n  /* Fill in argument block for dumper thread                                */\n  args.result       = -1;\n  args.err          = 0;\n  args.altstack_mem = altstack_mem;\n  args.parameter    = parameter;\n  args.callback     = callback;\n\n  /* Before cloning the thread lister, block all asynchronous signals, as we */\n  /* are not prepared to handle them.                                        */\n  sys_sigfillset(&sig_blocked);\n  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {\n    sys_sigdelset(&sig_blocked, sync_signals[sig]);\n  }\n  if (sys_sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old)) {\n    args.err = errno;\n    args.result = -1;\n    goto failed;\n  }\n\n  /* scope */ {\n    /* After cloning, both the parent and the child share the same instance\n     * of errno. We must make sure that at least one of these processes\n     * (in our case, the parent) uses modified syscall macros that update\n     * a local copy of errno, instead.\n     */\n    #ifdef __cplusplus\n      #define sys0_sigprocmask sys.sigprocmask\n      #define sys0_waitpid     sys.waitpid\n      SysCalls sys;\n    #else\n      int my_errno;\n      #define SYS_ERRNO        my_errno\n      #define SYS_INLINE       inline\n      #define SYS_PREFIX       0\n      #undef  SYS_LINUX_SYSCALL_SUPPORT_H\n      #include \"linux_syscall_support.h\"\n    #endif\n  \n    int clone_errno;\n    clone_pid = local_clone((int (*)(void *))ListerThread, &args);\n    clone_errno = errno;\n\n    sys_sigprocmask(SIG_SETMASK, &sig_old, &sig_old);\n\n    if (clone_pid >= 0) {\n      int status, rc;\n      while ((rc = sys0_waitpid(clone_pid, &status, __WALL)) < 0 &&\n             ERRNO == EINTR) {\n             /* Keep waiting                                                 */\n      }\n      if (rc < 0) {\n        args.err = ERRNO;\n        args.result = -1;\n      } else if (WIFEXITED(status)) {\n        switch (WEXITSTATUS(status)) {\n          case 0: break;             /* Normal process termination           */\n          case 2: args.err = EFAULT; /* Some fault (e.g. SIGSEGV) detected   */\n                  args.result = -1;\n                  break;\n          case 3: args.err = EPERM;  /* Process is already being traced      */\n                  args.result = -1;\n                  break;\n          default:args.err = ECHILD; /* Child died unexpectedly              */\n                  args.result = -1;\n                  break;\n        }\n      } else if (!WIFEXITED(status)) {\n        args.err    = EFAULT;        /* Terminated due to an unhandled signal*/\n        args.result = -1;\n      }\n    } else {\n      args.result = -1;\n      args.err    = clone_errno;\n    }\n  }\n\n  /* Restore the \"dumpable\" state of the process                             */\nfailed:\n  if (!dumpable)\n    sys_prctl(PR_SET_DUMPABLE, dumpable);\n\n  va_end(args.ap);\n\n  errno = args.err;\n  return args.result;\n}\n\n/* This function resumes the list of all linux threads that\n * ListAllProcessThreads pauses before giving to its callback.\n * The function returns non-zero if at least one thread was\n * suspended and has now been resumed.\n */\nint ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {\n  int detached_at_least_one = 0;\n  while (num_threads-- > 0) {\n    detached_at_least_one |= sys_ptrace_detach(thread_pids[num_threads]) >= 0;\n  }\n  return detached_at_least_one;\n}\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/linuxthreads.h",
    "content": "/* Copyright (c) 2005-2007, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Markus Gutschke\n */\n\n#ifndef _LINUXTHREADS_H\n#define _LINUXTHREADS_H\n\n/* Include thread_lister.h to get the interface that we implement for linux.\n */\n\n/* We currently only support x86-32 and x86-64 on Linux. Porting to other\n * related platforms should not be difficult.\n */\n#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \\\n     defined(__mips__) || defined(__PPC__)) && defined(__linux)\n\n/* Define the THREADS symbol to make sure that there is exactly one core dumper\n * built into the library.\n */\n#define THREADS \"Linux /proc\"\n\n#endif\n\n#endif  /* _LINUXTHREADS_H */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/logging.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// This file just provides storage for FLAGS_verbose.\n\n#include <config.h>\n#include \"base/logging.h\"\n#include \"base/commandlineflags.h\"\n\nDEFINE_int32(verbose, EnvToInt(\"PERFTOOLS_VERBOSE\", 0),\n             \"Set to numbers >0 for more verbose output, or <0 for less.  \"\n             \"--verbose == -4 means we log fatal errors only.\");\n\n\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n\n// While windows does have a POSIX-compatible API\n// (_open/_write/_close), it acquires memory.  Using this lower-level\n// windows API is the closest we can get to being \"raw\".\nRawFD RawOpenForWriting(const char* filename) {\n  // CreateFile allocates memory if file_name isn't absolute, so if\n  // that ever becomes a problem then we ought to compute the absolute\n  // path on its behalf (perhaps the ntdll/kernel function isn't aware\n  // of the working directory?)\n  RawFD fd = CreateFileA(filename, GENERIC_WRITE, 0, NULL,\n                         CREATE_ALWAYS, 0, NULL);\n  if (fd != kIllegalRawFD && GetLastError() == ERROR_ALREADY_EXISTS)\n    SetEndOfFile(fd);    // truncate the existing file\n  return fd;\n}\n\nvoid RawWrite(RawFD handle, const char* buf, size_t len) {\n  while (len > 0) {\n    DWORD wrote;\n    BOOL ok = WriteFile(handle, buf, len, &wrote, NULL);\n    // We do not use an asynchronous file handle, so ok==false means an error\n    if (!ok) break;\n    buf += wrote;\n    len -= wrote;\n  }\n}\n\nvoid RawClose(RawFD handle) {\n  CloseHandle(handle);\n}\n\n#else  // _WIN32 || __CYGWIN__ || __CYGWIN32__\n\n#ifdef HAVE_SYS_TYPES_H\n#include <sys/types.h>\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>\n#endif\n\n// Re-run fn until it doesn't cause EINTR.\n#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)\n\nRawFD RawOpenForWriting(const char* filename) {\n  return open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664);\n}\n\nvoid RawWrite(RawFD fd, const char* buf, size_t len) {\n  while (len > 0) {\n    ssize_t r;\n    NO_INTR(r = write(fd, buf, len));\n    if (r <= 0) break;\n    buf += r;\n    len -= r;\n  }\n}\n\nvoid RawClose(RawFD fd) {\n  NO_INTR(close(fd));\n}\n\n#endif  // _WIN32 || __CYGWIN__ || __CYGWIN32__\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/logging.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// This file contains #include information about logging-related stuff.\n// Pretty much everybody needs to #include this file so that they can\n// log various happenings.\n//\n#ifndef _LOGGING_H_\n#define _LOGGING_H_\n\n#include <config.h>\n#include <stdarg.h>\n#include <stdlib.h>\n#include <stdio.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>    // for write()\n#endif\n#include <string.h>    // for strlen(), strcmp()\n#include <assert.h>\n#include <errno.h>     // for errno\n#include \"base/commandlineflags.h\"\n\n// On some systems (like freebsd), we can't call write() at all in a\n// global constructor, perhaps because errno hasn't been set up.\n// (In windows, we can't call it because it might call malloc.)\n// Calling the write syscall is safer (it doesn't set errno), so we\n// prefer that.  Note we don't care about errno for logging: we just\n// do logging on a best-effort basis.\n#if defined(_MSC_VER)\n#define WRITE_TO_STDERR(buf, len) WriteToStderr(buf, len);  // in port.cc\n#elif defined(HAVE_SYS_SYSCALL_H)\n#include <sys/syscall.h>\n#define WRITE_TO_STDERR(buf, len) syscall(SYS_write, STDERR_FILENO, buf, len)\n#else\n#define WRITE_TO_STDERR(buf, len) write(STDERR_FILENO, buf, len)\n#endif\n\n\n// We log all messages at this log-level and below.\n// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4\nDECLARE_int32(verbose);\n\n// CHECK dies with a fatal error if condition is not true.  It is *not*\n// controlled by NDEBUG, so the check will be executed regardless of\n// compilation mode.  Therefore, it is safe to do things like:\n//    CHECK(fp->Write(x) == 4)\n// Note we use write instead of printf/puts to avoid the risk we'll\n// call malloc().\n#define CHECK(condition)                                                \\\n  do {                                                                  \\\n    if (!(condition)) {                                                 \\\n      WRITE_TO_STDERR(\"Check failed: \" #condition \"\\n\",                 \\\n                      sizeof(\"Check failed: \" #condition \"\\n\")-1);      \\\n      exit(1);                                                          \\\n    }                                                                   \\\n  } while (0)\n\n// This takes a message to print.  The name is historical.\n#define RAW_CHECK(condition, message)                                          \\\n  do {                                                                         \\\n    if (!(condition)) {                                                        \\\n      WRITE_TO_STDERR(\"Check failed: \" #condition \": \" message \"\\n\",           \\\n                      sizeof(\"Check failed: \" #condition \": \" message \"\\n\")-1);\\\n      exit(1);                                                                 \\\n    }                                                                          \\\n  } while (0)\n\n// This is like RAW_CHECK, but only in debug-mode\n#ifdef NDEBUG\nenum { DEBUG_MODE = 0 };\n#define RAW_DCHECK(condition, message)\n#else\nenum { DEBUG_MODE = 1 };\n#define RAW_DCHECK(condition, message)  RAW_CHECK(condition, message)\n#endif\n\n// This prints errno as well.  Note we use write instead of printf/puts to\n// avoid the risk we'll call malloc().\n#define PCHECK(condition)                                               \\\n  do {                                                                  \\\n    if (!(condition)) {                                                 \\\n      const int err_no = errno;                                         \\\n      WRITE_TO_STDERR(\"Check failed: \" #condition \": \",                 \\\n                      sizeof(\"Check failed: \" #condition \": \")-1);      \\\n      WRITE_TO_STDERR(strerror(err_no), strlen(strerror(err_no)));      \\\n      WRITE_TO_STDERR(\"\\n\", sizeof(\"\\n\")-1);                            \\\n      exit(1);                                                          \\\n    }                                                                   \\\n  } while (0)\n\n// Helper macro for binary operators; prints the two values on error\n// Don't use this macro directly in your code, use CHECK_EQ et al below\n\n// WARNING: These don't compile correctly if one of the arguments is a pointer\n// and the other is NULL. To work around this, simply static_cast NULL to the\n// type of the desired pointer.\n\n// TODO(jandrews): Also print the values in case of failure.  Requires some\n// sort of type-sensitive ToString() function.\n#define CHECK_OP(op, val1, val2)                                        \\\n  do {                                                                  \\\n    if (!((val1) op (val2))) {                                          \\\n      fprintf(stderr, \"Check failed: %s %s %s\\n\", #val1, #op, #val2);   \\\n      exit(1);                                                          \\\n    }                                                                   \\\n  } while (0)\n\n#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)\n#define CHECK_NE(val1, val2) CHECK_OP(!=, val1, val2)\n#define CHECK_LE(val1, val2) CHECK_OP(<=, val1, val2)\n#define CHECK_LT(val1, val2) CHECK_OP(< , val1, val2)\n#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)\n#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)\n\n// Synonyms for CHECK_* that are used in some unittests.\n#define EXPECT_EQ(val1, val2) CHECK_EQ(val1, val2)\n#define EXPECT_NE(val1, val2) CHECK_NE(val1, val2)\n#define EXPECT_LE(val1, val2) CHECK_LE(val1, val2)\n#define EXPECT_LT(val1, val2) CHECK_LT(val1, val2)\n#define EXPECT_GE(val1, val2) CHECK_GE(val1, val2)\n#define EXPECT_GT(val1, val2) CHECK_GT(val1, val2)\n#define ASSERT_EQ(val1, val2) EXPECT_EQ(val1, val2)\n#define ASSERT_NE(val1, val2) EXPECT_NE(val1, val2)\n#define ASSERT_LE(val1, val2) EXPECT_LE(val1, val2)\n#define ASSERT_LT(val1, val2) EXPECT_LT(val1, val2)\n#define ASSERT_GE(val1, val2) EXPECT_GE(val1, val2)\n#define ASSERT_GT(val1, val2) EXPECT_GT(val1, val2)\n// As are these variants.\n#define EXPECT_TRUE(cond)     CHECK(cond)\n#define EXPECT_FALSE(cond)    CHECK(!(cond))\n#define EXPECT_STREQ(a, b)    CHECK(strcmp(a, b) == 0)\n#define ASSERT_TRUE(cond)     EXPECT_TRUE(cond)\n#define ASSERT_FALSE(cond)    EXPECT_FALSE(cond)\n#define ASSERT_STREQ(a, b)    EXPECT_STREQ(a, b)\n\n// Used for (libc) functions that return -1 and set errno\n#define CHECK_ERR(invocation)  PCHECK((invocation) != -1)\n\n// A few more checks that only happen in debug mode\n#ifdef NDEBUG\n#define DCHECK_EQ(val1, val2)\n#define DCHECK_NE(val1, val2)\n#define DCHECK_LE(val1, val2)\n#define DCHECK_LT(val1, val2)\n#define DCHECK_GE(val1, val2)\n#define DCHECK_GT(val1, val2)\n#else\n#define DCHECK_EQ(val1, val2)  CHECK_EQ(val1, val2)\n#define DCHECK_NE(val1, val2)  CHECK_NE(val1, val2)\n#define DCHECK_LE(val1, val2)  CHECK_LE(val1, val2)\n#define DCHECK_LT(val1, val2)  CHECK_LT(val1, val2)\n#define DCHECK_GE(val1, val2)  CHECK_GE(val1, val2)\n#define DCHECK_GT(val1, val2)  CHECK_GT(val1, val2)\n#endif\n\n\n#ifdef ERROR\n#undef ERROR      // may conflict with ERROR macro on windows\n#endif\nenum LogSeverity {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};\n\n// NOTE: we add a newline to the end of the output if it's not there already\ninline void LogPrintf(int severity, const char* pat, va_list ap) {\n  // We write directly to the stderr file descriptor and avoid FILE\n  // buffering because that may invoke malloc()\n  char buf[600];\n  vsnprintf(buf, sizeof(buf)-1, pat, ap);\n  if (buf[0] != '\\0' && buf[strlen(buf)-1] != '\\n') {\n    assert(strlen(buf)+1 < sizeof(buf));\n    strcat(buf, \"\\n\");\n  }\n  WRITE_TO_STDERR(buf, strlen(buf));\n  if ((severity) == FATAL)\n    abort(); // LOG(FATAL) indicates a big problem, so don't run atexit() calls\n}\n\n// Note that since the order of global constructors is unspecified,\n// global code that calls RAW_LOG may execute before FLAGS_verbose is set.\n// Such code will run with verbosity == 0 no matter what.\n#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)\n\n// In a better world, we'd use __VA_ARGS__, but VC++ 7 doesn't support it.\n#define LOG_PRINTF(severity, pat) do {          \\\n  if (VLOG_IS_ON(severity)) {                   \\\n    va_list ap;                                 \\\n    va_start(ap, pat);                          \\\n    LogPrintf(severity, pat, ap);               \\\n    va_end(ap);                                 \\\n  }                                             \\\n} while (0)\n\n// RAW_LOG is the main function; some synonyms are used in unittests.\ninline void RAW_LOG(int lvl, const char* pat, ...)  { LOG_PRINTF(lvl, pat); }\ninline void RAW_VLOG(int lvl, const char* pat, ...) { LOG_PRINTF(lvl, pat); }\ninline void LOG(int lvl, const char* pat, ...)      { LOG_PRINTF(lvl, pat); }\ninline void VLOG(int lvl, const char* pat, ...)     { LOG_PRINTF(lvl, pat); }\ninline void LOG_IF(int lvl, bool cond, const char* pat, ...) {\n  if (cond)  LOG_PRINTF(lvl, pat);\n}\n\n// This isn't technically logging, but it's also IO and also is an\n// attempt to be \"raw\" -- that is, to not use any higher-level libc\n// routines that might allocate memory or (ideally) try to allocate\n// locks.  We use an opaque file handle (not necessarily an int)\n// to allow even more low-level stuff in the future.\n// Like other \"raw\" routines, these functions are best effort, and\n// thus don't return error codes (except RawOpenForWriting()).\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n#define NOMINMAX     // @#!$& windows\n#include <windows.h>\ntypedef HANDLE RawFD;\nconst RawFD kIllegalRawFD = INVALID_HANDLE_VALUE;\n#else\ntypedef int RawFD;\nconst RawFD kIllegalRawFD = -1;   // what open returns if it fails\n#endif  // defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n\nRawFD RawOpenForWriting(const char* filename);   // uses default permissions\nvoid RawWrite(RawFD fd, const char* buf, size_t len);\nvoid RawClose(RawFD fd);\n\n#endif // _LOGGING_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/low_level_alloc.cc",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n// A low-level allocator that can be used by other low-level\n// modules without introducing dependency cycles.\n// This allocator is slow and wasteful of memory;\n// it should not be used when performance is key.\n\n#include \"base/low_level_alloc.h\"\n#include \"base/dynamic_annotations.h\"\n#include \"base/spinlock.h\"\n#include \"base/logging.h\"\n#include \"malloc_hook-inl.h\"\n#include <google/malloc_hook.h>\n#include <errno.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#endif\n#include <new>                   // for placement-new\n\n// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old\n// form of the name instead.\n#ifndef MAP_ANONYMOUS\n# define MAP_ANONYMOUS MAP_ANON\n#endif\n\n// A first-fit allocator with amortized logarithmic free() time.\n\n// ---------------------------------------------------------------------------\nstatic const int kMaxLevel = 30;\n\n// We put this class-only struct in a namespace to avoid polluting the\n// global namespace with this struct name (thus risking an ODR violation).\nnamespace low_level_alloc_internal {\n  // This struct describes one allocated block, or one free block.\n  struct AllocList {\n    struct Header {\n      intptr_t size;  // size of entire region, including this field. Must be\n                      // first.  Valid in both allocated and unallocated blocks\n      intptr_t magic; // kMagicAllocated or kMagicUnallocated xor this\n      LowLevelAlloc::Arena *arena; // pointer to parent arena\n      void *dummy_for_alignment;   // aligns regions to 0 mod 2*sizeof(void*)\n    } header;\n\n    // Next two fields: in unallocated blocks: freelist skiplist data\n    //                  in allocated blocks: overlaps with client data\n    int levels;           // levels in skiplist used\n    AllocList *next[kMaxLevel];   // actually has levels elements.\n                                  // The AllocList node may not have room for\n                                  // all kMaxLevel entries.  See max_fit in\n                                  // LLA_SkiplistLevels()\n  };\n}\nusing low_level_alloc_internal::AllocList;\n\n\n// ---------------------------------------------------------------------------\n// A trivial skiplist implementation.  This is used to keep the freelist\n// in address order while taking only logarithmic time per insert and delete.\n\n// An integer approximation of log2(size/base)\n// Requires size >= base.\nstatic int IntLog2(size_t size, size_t base) {\n  int result = 0;\n  for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)\n    result++;\n  }\n  //    floor(size / 2**result) <= base < floor(size / 2**(result-1))\n  // =>     log2(size/(base+1)) <= result < 1+log2(size/base)\n  // => result ~= log2(size/base)\n  return result;\n}\n\n// Return a random integer n:  p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.\nstatic int Random() {\n  static int32 r = 1;         // no locking---it's not critical\n  ANNOTATE_BENIGN_RACE(&r, \"benign race, not critical.\");\n  int result = 1;\n  while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) {\n    result++;\n  }\n  return result;\n}\n\n// Return a number of skiplist levels for a node of size bytes, where\n// base is the minimum node size.  Compute level=log2(size / base)+n\n// where n is 1 if random is false and otherwise a random number generated with\n// the standard distribution for a skiplist:  See Random() above.\n// Bigger nodes tend to have more skiplist levels due to the log2(size / base)\n// term, so first-fit searches touch fewer nodes.  \"level\" is clipped so\n// level<kMaxLevel and next[level-1] will fit in the node.\n// 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel\nstatic int LLA_SkiplistLevels(size_t size, size_t base, bool random) {\n  // max_fit is the maximum number of levels that will fit in a node for the\n  // given size.   We can't return more than max_fit, no matter what the\n  // random number generator says.\n  int max_fit = (size-OFFSETOF_MEMBER(AllocList, next)) / sizeof (AllocList *);\n  int level = IntLog2(size, base) + (random? Random() : 1);\n  if (level > max_fit)     level = max_fit;\n  if (level > kMaxLevel-1) level = kMaxLevel - 1;\n  RAW_CHECK(level >= 1, \"block not big enough for even one level\");\n  return level;\n}\n\n// Return \"atleast\", the first element of AllocList *head s.t. *atleast >= *e.\n// For 0 <= i < head->levels, set prev[i] to \"no_greater\", where no_greater\n// points to the last element at level i in the AllocList less than *e, or is\n// head if no such element exists.\nstatic AllocList *LLA_SkiplistSearch(AllocList *head,\n                                     AllocList *e, AllocList **prev) {\n  AllocList *p = head;\n  for (int level = head->levels - 1; level >= 0; level--) {\n    for (AllocList *n; (n = p->next[level]) != 0 && n < e; p = n) {\n    }\n    prev[level] = p;\n  }\n  return (head->levels == 0) ?  0 : prev[0]->next[0];\n}\n\n// Insert element *e into AllocList *head.  Set prev[] as LLA_SkiplistSearch.\n// Requires that e->levels be previously set by the caller (using\n// LLA_SkiplistLevels())\nstatic void LLA_SkiplistInsert(AllocList *head, AllocList *e,\n                               AllocList **prev) {\n  LLA_SkiplistSearch(head, e, prev);\n  for (; head->levels < e->levels; head->levels++) { // extend prev pointers\n    prev[head->levels] = head;                       // to all *e's levels\n  }\n  for (int i = 0; i != e->levels; i++) { // add element to list\n    e->next[i] = prev[i]->next[i];\n    prev[i]->next[i] = e;\n  }\n}\n\n// Remove element *e from AllocList *head.  Set prev[] as LLA_SkiplistSearch().\n// Requires that e->levels be previous set by the caller (using\n// LLA_SkiplistLevels())\nstatic void LLA_SkiplistDelete(AllocList *head, AllocList *e,\n                               AllocList **prev) {\n  AllocList *found = LLA_SkiplistSearch(head, e, prev);\n  RAW_CHECK(e == found, \"element not in freelist\");\n  for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {\n    prev[i]->next[i] = e->next[i];\n  }\n  while (head->levels > 0 && head->next[head->levels - 1] == 0) {\n    head->levels--;   // reduce head->levels if level unused\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Arena implementation\n\nstruct LowLevelAlloc::Arena {\n  Arena() : mu(SpinLock::LINKER_INITIALIZED) {} // does nothing; for static init\n  explicit Arena(int) : pagesize(0) {}  // set pagesize to zero explicitly\n                                        // for non-static init\n\n  SpinLock mu;            // protects freelist, allocation_count,\n                          // pagesize, roundup, min_size\n  AllocList freelist;     // head of free list; sorted by addr (under mu)\n  int32 allocation_count; // count of allocated blocks (under mu)\n  int32 flags;            // flags passed to NewArena (ro after init)\n  size_t pagesize;        // ==getpagesize()  (init under mu, then ro)\n  size_t roundup;         // lowest power of 2 >= max(16,sizeof (AllocList))\n                          // (init under mu, then ro)\n  size_t min_size;        // smallest allocation block size\n                          // (init under mu, then ro)\n};\n\n// The default arena, which is used when 0 is passed instead of an Arena\n// pointer.\nstatic struct LowLevelAlloc::Arena default_arena;\n\n// Non-malloc-hooked arenas: used only to allocate metadata for arenas that\n// do not want malloc hook reporting, so that for them there's no malloc hook\n// reporting even during arena creation.\nstatic struct LowLevelAlloc::Arena unhooked_arena;\nstatic struct LowLevelAlloc::Arena unhooked_async_sig_safe_arena;\n\n// magic numbers to identify allocated and unallocated blocks\nstatic const intptr_t kMagicAllocated = 0x4c833e95;\nstatic const intptr_t kMagicUnallocated = ~kMagicAllocated;\n\nnamespace {\n  class ArenaLock {\n   public:\n    explicit ArenaLock(LowLevelAlloc::Arena *arena)\n        EXCLUSIVE_LOCK_FUNCTION(arena->mu)\n        : left_(false), mask_valid_(false), arena_(arena) {\n      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {\n      // We've decided not to support async-signal-safe arena use until\n      // there a demonstrated need.  Here's how one could do it though\n      // (would need to be made more portable).\n#if 0\n        sigset_t all;\n        sigfillset(&all);\n        this->mask_valid_ =\n            (pthread_sigmask(SIG_BLOCK, &all, &this->mask_) == 0);\n#else\n        RAW_CHECK(false, \"We do not yet support async-signal-safe arena.\");\n#endif\n      }\n      this->arena_->mu.Lock();\n    }\n    ~ArenaLock() { RAW_CHECK(this->left_, \"haven't left Arena region\"); }\n    void Leave() UNLOCK_FUNCTION(arena_->mu) {\n      this->arena_->mu.Unlock();\n#if 0\n      if (this->mask_valid_) {\n        pthread_sigmask(SIG_SETMASK, &this->mask_, 0);\n      }\n#endif\n      this->left_ = true;\n    }\n   private:\n    bool left_;       // whether left region\n    bool mask_valid_;\n#if 0\n    sigset_t mask_;   // old mask of blocked signals\n#endif\n    LowLevelAlloc::Arena *arena_;\n    DISALLOW_COPY_AND_ASSIGN(ArenaLock);\n  };\n} // anonymous namespace\n\n// create an appropriate magic number for an object at \"ptr\"\n// \"magic\" should be kMagicAllocated or kMagicUnallocated\ninline static intptr_t Magic(intptr_t magic, AllocList::Header *ptr) {\n  return magic ^ reinterpret_cast<intptr_t>(ptr);\n}\n\n// Initialize the fields of an Arena\nstatic void ArenaInit(LowLevelAlloc::Arena *arena) {\n  if (arena->pagesize == 0) {\n    arena->pagesize = getpagesize();\n    // Round up block sizes to a power of two close to the header size.\n    arena->roundup = 16;\n    while (arena->roundup < sizeof (arena->freelist.header)) {\n      arena->roundup += arena->roundup;\n    }\n    // Don't allocate blocks less than twice the roundup size to avoid tiny\n    // free blocks.\n    arena->min_size = 2 * arena->roundup;\n    arena->freelist.header.size = 0;\n    arena->freelist.header.magic =\n        Magic(kMagicUnallocated, &arena->freelist.header);\n    arena->freelist.header.arena = arena;\n    arena->freelist.levels = 0;\n    memset(arena->freelist.next, 0, sizeof (arena->freelist.next));\n    arena->allocation_count = 0;\n    if (arena == &default_arena) {\n      // Default arena should be hooked, e.g. for heap-checker to trace\n      // pointer chains through objects in the default arena.\n      arena->flags = LowLevelAlloc::kCallMallocHook;\n    } else if (arena == &unhooked_async_sig_safe_arena) {\n      arena->flags = LowLevelAlloc::kAsyncSignalSafe;\n    } else {\n      arena->flags = 0;   // other arenas' flags may be overridden by client,\n                          // but unhooked_arena will have 0 in 'flags'.\n    }\n  }\n}\n\n// L < meta_data_arena->mu\nLowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32 flags,\n                                              Arena *meta_data_arena) {\n  RAW_CHECK(meta_data_arena != 0, \"must pass a valid arena\");\n  if (meta_data_arena == &default_arena) {\n    if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {\n      meta_data_arena = &unhooked_async_sig_safe_arena;\n    } else if ((flags & LowLevelAlloc::kCallMallocHook) == 0) {\n      meta_data_arena = &unhooked_arena;\n    }\n  }\n  // Arena(0) uses the constructor for non-static contexts\n  Arena *result =\n    new (AllocWithArena(sizeof (*result), meta_data_arena)) Arena(0);\n  ArenaInit(result);\n  result->flags = flags;\n  return result;\n}\n\n// L < arena->mu, L < arena->arena->mu\nbool LowLevelAlloc::DeleteArena(Arena *arena) {\n  RAW_CHECK(arena != 0 && arena != &default_arena && arena != &unhooked_arena,\n            \"may not delete default arena\");\n  ArenaLock section(arena);\n  bool empty = (arena->allocation_count == 0);\n  section.Leave();\n  if (empty) {\n    while (arena->freelist.next[0] != 0) {\n      AllocList *region = arena->freelist.next[0];\n      size_t size = region->header.size;\n      arena->freelist.next[0] = region->next[0];\n      RAW_CHECK(region->header.magic ==\n                Magic(kMagicUnallocated, &region->header),\n                \"bad magic number in DeleteArena()\");\n      RAW_CHECK(region->header.arena == arena,\n                \"bad arena pointer in DeleteArena()\");\n      RAW_CHECK(size % arena->pagesize == 0,\n                \"empty arena has non-page-aligned block size\");\n      RAW_CHECK(reinterpret_cast<intptr_t>(region) % arena->pagesize == 0,\n                \"empty arena has non-page-aligned block\");\n      int munmap_result;\n      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {\n        munmap_result = munmap(region, size);\n      } else {\n        munmap_result = MallocHook::UnhookedMUnmap(region, size);\n      }\n      RAW_CHECK(munmap_result == 0,\n                \"LowLevelAlloc::DeleteArena:  munmap failed address\");\n    }\n    Free(arena);\n  }\n  return empty;\n}\n\n// ---------------------------------------------------------------------------\n\n// Return value rounded up to next multiple of align.\n// align must be a power of two.\nstatic intptr_t RoundUp(intptr_t addr, intptr_t align) {\n  return (addr + align - 1) & ~(align - 1);\n}\n\n// Equivalent to \"return prev->next[i]\" but with sanity checking\n// that the freelist is in the correct order, that it\n// consists of regions marked \"unallocated\", and that no two regions\n// are adjacent in memory (they should have been coalesced).\n// L < arena->mu\nstatic AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {\n  RAW_CHECK(i < prev->levels, \"too few levels in Next()\");\n  AllocList *next = prev->next[i];\n  if (next != 0) {\n    RAW_CHECK(next->header.magic == Magic(kMagicUnallocated, &next->header),\n              \"bad magic number in Next()\");\n    RAW_CHECK(next->header.arena == arena,\n              \"bad arena pointer in Next()\");\n    if (prev != &arena->freelist) {\n      RAW_CHECK(prev < next, \"unordered freelist\");\n      RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <\n                reinterpret_cast<char *>(next), \"malformed freelist\");\n    }\n  }\n  return next;\n}\n\n// Coalesce list item \"a\" with its successor if they are adjacent.\nstatic void Coalesce(AllocList *a) {\n  AllocList *n = a->next[0];\n  if (n != 0 && reinterpret_cast<char *>(a) + a->header.size ==\n                    reinterpret_cast<char *>(n)) {\n    LowLevelAlloc::Arena *arena = a->header.arena;\n    a->header.size += n->header.size;\n    n->header.magic = 0;\n    n->header.arena = 0;\n    AllocList *prev[kMaxLevel];\n    LLA_SkiplistDelete(&arena->freelist, n, prev);\n    LLA_SkiplistDelete(&arena->freelist, a, prev);\n    a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, true);\n    LLA_SkiplistInsert(&arena->freelist, a, prev);\n  }\n}\n\n// Adds block at location \"v\" to the free list\n// L >= arena->mu\nstatic void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {\n  AllocList *f = reinterpret_cast<AllocList *>(\n                        reinterpret_cast<char *>(v) - sizeof (f->header));\n  RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),\n            \"bad magic number in AddToFreelist()\");\n  RAW_CHECK(f->header.arena == arena,\n            \"bad arena pointer in AddToFreelist()\");\n  f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, true);\n  AllocList *prev[kMaxLevel];\n  LLA_SkiplistInsert(&arena->freelist, f, prev);\n  f->header.magic = Magic(kMagicUnallocated, &f->header);\n  Coalesce(f);                  // maybe coalesce with successor\n  Coalesce(prev[0]);            // maybe coalesce with predecessor\n}\n\n// Frees storage allocated by LowLevelAlloc::Alloc().\n// L < arena->mu\nvoid LowLevelAlloc::Free(void *v) {\n  if (v != 0) {\n    AllocList *f = reinterpret_cast<AllocList *>(\n                        reinterpret_cast<char *>(v) - sizeof (f->header));\n    RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),\n              \"bad magic number in Free()\");\n    LowLevelAlloc::Arena *arena = f->header.arena;\n    if ((arena->flags & kCallMallocHook) != 0) {\n      MallocHook::InvokeDeleteHook(v);\n    }\n    ArenaLock section(arena);\n    AddToFreelist(v, arena);\n    RAW_CHECK(arena->allocation_count > 0, \"nothing in arena to free\");\n    arena->allocation_count--;\n    section.Leave();\n  }\n}\n\n// allocates and returns a block of size bytes, to be freed with Free()\n// L < arena->mu\nstatic void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {\n  void *result = 0;\n  if (request != 0) {\n    AllocList *s;       // will point to region that satisfies request\n    ArenaLock section(arena);\n    ArenaInit(arena);\n    // round up with header\n    size_t req_rnd = RoundUp(request + sizeof (s->header), arena->roundup);\n    for (;;) {      // loop until we find a suitable region\n      // find the minimum levels that a block of this size must have\n      int i = LLA_SkiplistLevels(req_rnd, arena->min_size, false) - 1;\n      if (i < arena->freelist.levels) {   // potential blocks exist\n        AllocList *before = &arena->freelist;  // predecessor of s\n        while ((s = Next(i, before, arena)) != 0 && s->header.size < req_rnd) {\n          before = s;\n        }\n        if (s != 0) {       // we found a region\n          break;\n        }\n      }\n      // we unlock before mmap() both because mmap() may call a callback hook,\n      // and because it may be slow.\n      arena->mu.Unlock();\n      // mmap generous 64K chunks to decrease\n      // the chances/impact of fragmentation:\n      size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16);\n      void *new_pages;\n      if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {\n        new_pages = MallocHook::UnhookedMMap(0, new_pages_size,\n            PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);\n      } else {\n        new_pages = mmap(0, new_pages_size,\n            PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);\n      }\n      RAW_CHECK(new_pages != MAP_FAILED, \"mmap error\");\n      arena->mu.Lock();\n      s = reinterpret_cast<AllocList *>(new_pages);\n      s->header.size = new_pages_size;\n      // Pretend the block is allocated; call AddToFreelist() to free it.\n      s->header.magic = Magic(kMagicAllocated, &s->header);\n      s->header.arena = arena;\n      AddToFreelist(&s->levels, arena);  // insert new region into free list\n    }\n    AllocList *prev[kMaxLevel];\n    LLA_SkiplistDelete(&arena->freelist, s, prev);    // remove from free list\n    // s points to the first free region that's big enough\n    if (req_rnd + arena->min_size <= s->header.size) {  // big enough to split\n      AllocList *n = reinterpret_cast<AllocList *>\n                        (req_rnd + reinterpret_cast<char *>(s));\n      n->header.size = s->header.size - req_rnd;\n      n->header.magic = Magic(kMagicAllocated, &n->header);\n      n->header.arena = arena;\n      s->header.size = req_rnd;\n      AddToFreelist(&n->levels, arena);\n    }\n    s->header.magic = Magic(kMagicAllocated, &s->header);\n    RAW_CHECK(s->header.arena == arena, \"\");\n    arena->allocation_count++;\n    section.Leave();\n    result = &s->levels;\n  }\n  ANNOTATE_NEW_MEMORY(result, request);\n  return result;\n}\n\nvoid *LowLevelAlloc::Alloc(size_t request) {\n  void *result = DoAllocWithArena(request, &default_arena);\n  if ((default_arena.flags & kCallMallocHook) != 0) {\n    // this call must be directly in the user-called allocator function\n    // for MallocHook::GetCallerStackTrace to work properly\n    MallocHook::InvokeNewHook(result, request);\n  }\n  return result;\n}\n\nvoid *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) {\n  RAW_CHECK(arena != 0, \"must pass a valid arena\");\n  void *result = DoAllocWithArena(request, arena);\n  if ((arena->flags & kCallMallocHook) != 0) {\n    // this call must be directly in the user-called allocator function\n    // for MallocHook::GetCallerStackTrace to work properly\n    MallocHook::InvokeNewHook(result, request);\n  }\n  return result;\n}\n\nLowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() {\n  return &default_arena;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/low_level_alloc.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#if !defined(_BASE_LOW_LEVEL_ALLOC_H_)\n#define _BASE_LOW_LEVEL_ALLOC_H_\n\n// A simple thread-safe memory allocator that does not depend on\n// mutexes or thread-specific data.  It is intended to be used\n// sparingly, and only when malloc() would introduce an unwanted\n// dependency, such as inside the heap-checker.\n\n#include <config.h>\n#include <stddef.h>             // for size_t\n#include \"base/basictypes.h\"\n\nclass LowLevelAlloc {\n public:\n  struct Arena;       // an arena from which memory may be allocated\n\n  // Returns a pointer to a block of at least \"request\" bytes\n  // that have been newly allocated from the specific arena.\n  // for Alloc() call the DefaultArena() is used.\n  // Returns 0 if passed request==0.\n  // Does not return 0 under other circumstances; it crashes if memory\n  // is not available.\n  static void *Alloc(size_t request)\n    ATTRIBUTE_SECTION(malloc_hook);\n  static void *AllocWithArena(size_t request, Arena *arena)\n    ATTRIBUTE_SECTION(malloc_hook);\n\n  // Deallocates a region of memory that was previously allocated with\n  // Alloc().   Does nothing if passed 0.   \"s\" must be either 0,\n  // or must have been returned from a call to Alloc() and not yet passed to\n  // Free() since that call to Alloc().  The space is returned to the arena\n  // from which it was allocated.\n  static void Free(void *s) ATTRIBUTE_SECTION(malloc_hook);\n\n    // ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free\n    // are to put all callers of MallocHook::Invoke* in this module\n    // into special section,\n    // so that MallocHook::GetCallerStackTrace can function accurately.\n\n  // Create a new arena.\n  // The root metadata for the new arena is allocated in the\n  // meta_data_arena; the DefaultArena() can be passed for meta_data_arena.\n  // These values may be ored into flags:\n  enum {\n    // Report calls to Alloc() and Free() via the MallocHook interface.\n    // Set in the DefaultArena.\n    kCallMallocHook = 0x0001,\n\n    // Make calls to Alloc(), Free() be async-signal-safe.  Not set in\n    // DefaultArena().\n    kAsyncSignalSafe = 0x0002,\n\n    // When used with DefaultArena(), the NewArena() and DeleteArena() calls\n    // obey the flags given explicitly in the NewArena() call, even if those\n    // flags differ from the settings in DefaultArena().  So the call\n    // NewArena(kAsyncSignalSafe, DefaultArena()) is itself async-signal-safe,\n    // as well as generatating an arena that provides async-signal-safe\n    // Alloc/Free.\n  };\n  static Arena *NewArena(int32 flags, Arena *meta_data_arena);\n\n  // Destroys an arena allocated by NewArena and returns true,\n  // provided no allocated blocks remain in the arena.\n  // If allocated blocks remain in the arena, does nothing and\n  // returns false.\n  // It is illegal to attempt to destroy the DefaultArena().\n  static bool DeleteArena(Arena *arena);\n\n  // The default arena that always exists.\n  static Arena *DefaultArena();\n\n private:\n  LowLevelAlloc();      // no instances\n};\n\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/simple_mutex.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n// ---\n// Author: Craig Silverstein.\n//\n// A simple mutex wrapper, supporting locks and read-write locks.\n// You should assume the locks are *not* re-entrant.\n//\n// To use: you should define the following macros in your configure.ac:\n//   ACX_PTHREAD\n//   AC_RWLOCK\n// The latter is defined in ../autoconf.\n//\n// This class is meant to be internal-only and should be wrapped by an\n// internal namespace.  Before you use this module, please give the\n// name of your internal namespace for this module.  Or, if you want\n// to expose it, you'll want to move it to the Google namespace.  We\n// cannot put this class in global namespace because there can be some\n// problems when we have multiple versions of Mutex in each shared object.\n//\n// NOTE: TryLock() is broken for NO_THREADS mode, at least in NDEBUG\n//       mode.\n//\n// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:\n//    http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html\n// Because of that, we might as well use windows locks for\n// cygwin.  They seem to be more reliable than the cygwin pthreads layer.\n//\n// TRICKY IMPLEMENTATION NOTE:\n// This class is designed to be safe to use during\n// dynamic-initialization -- that is, by global constructors that are\n// run before main() starts.  The issue in this case is that\n// dynamic-initialization happens in an unpredictable order, and it\n// could be that someone else's dynamic initializer could call a\n// function that tries to acquire this mutex -- but that all happens\n// before this mutex's constructor has run.  (This can happen even if\n// the mutex and the function that uses the mutex are in the same .cc\n// file.)  Basically, because Mutex does non-trivial work in its\n// constructor, it's not, in the naive implementation, safe to use\n// before dynamic initialization has run on it.\n//\n// The solution used here is to pair the actual mutex primitive with a\n// bool that is set to true when the mutex is dynamically initialized.\n// (Before that it's false.)  Then we modify all mutex routines to\n// look at the bool, and not try to lock/unlock until the bool makes\n// it to true (which happens after the Mutex constructor has run.)\n//\n// This works because before main() starts -- particularly, during\n// dynamic initialization -- there are no threads, so a) it's ok that\n// the mutex operations are a no-op, since we don't need locking then\n// anyway; and b) we can be quite confident our bool won't change\n// state between a call to Lock() and a call to Unlock() (that would\n// require a global constructor in one translation unit to call Lock()\n// and another global constructor in another translation unit to call\n// Unlock() later, which is pretty perverse).\n//\n// That said, it's tricky, and can conceivably fail; it's safest to\n// avoid trying to acquire a mutex in a global constructor, if you\n// can.  One way it can fail is that a really smart compiler might\n// initialize the bool to true at static-initialization time (too\n// early) rather than at dynamic-initialization time.  To discourage\n// that, we set is_safe_ to true in code (not the constructor\n// colon-initializer) and set it to true via a function that always\n// evaluates to true, but that the compiler can't know always\n// evaluates to true.  This should be good enough.\n//\n// A related issue is code that could try to access the mutex\n// after it's been destroyed in the global destructors (because\n// the Mutex global destructor runs before some other global\n// destructor, that tries to acquire the mutex).  The way we\n// deal with this is by taking a constructor arg that global\n// mutexes should pass in, that causes the destructor to do no\n// work.  We still depend on the compiler not doing anything\n// weird to a Mutex's memory after it is destroyed, but for a\n// static global variable, that's pretty safe.\n\n#ifndef GOOGLE_MUTEX_H_\n#define GOOGLE_MUTEX_H_\n\n#include <config.h>\n\n#if defined(NO_THREADS)\n  typedef int MutexType;      // to keep a lock-count\n#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n# ifndef WIN32_LEAN_AND_MEAN\n#   define WIN32_LEAN_AND_MEAN  // We only need minimal includes\n# endif\n  // We need Windows NT or later for TryEnterCriticalSection().  If you\n  // don't need that functionality, you can remove these _WIN32_WINNT\n  // lines, and change TryLock() to assert(0) or something.\n# ifndef _WIN32_WINNT\n#   define _WIN32_WINNT 0x0400\n# endif\n# include <windows.h>\n  typedef CRITICAL_SECTION MutexType;\n#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)\n  // Needed for pthread_rwlock_*.  If it causes problems, you could take it\n  // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it\n  // *does* cause problems for FreeBSD, or MacOSX, but isn't needed\n  // for locking there.)\n# ifdef __linux__\n#   define _XOPEN_SOURCE 500  // may be needed to get the rwlock calls\n# endif\n# include <pthread.h>\n  typedef pthread_rwlock_t MutexType;\n#elif defined(HAVE_PTHREAD)\n# include <pthread.h>\n  typedef pthread_mutex_t MutexType;\n#else\n# error Need to implement mutex.h for your architecture, or #define NO_THREADS\n#endif\n\n#include <assert.h>\n#include <stdlib.h>      // for abort()\n\n#define MUTEX_NAMESPACE perftools_mutex_namespace\n\nnamespace MUTEX_NAMESPACE {\n\nclass Mutex {\n public:\n  // This is used for the single-arg constructor\n  enum LinkerInitialized { LINKER_INITIALIZED };\n\n  // Create a Mutex that is not held by anybody.  This constructor is\n  // typically used for Mutexes allocated on the heap or the stack.\n  inline Mutex();\n  // This constructor should be used for global, static Mutex objects.\n  // It inhibits work being done by the destructor, which makes it\n  // safer for code that tries to acqiure this mutex in their global\n  // destructor.\n  inline Mutex(LinkerInitialized);\n\n  // Destructor\n  inline ~Mutex();\n\n  inline void Lock();    // Block if needed until free then acquire exclusively\n  inline void Unlock();  // Release a lock acquired via Lock()\n  inline bool TryLock(); // If free, Lock() and return true, else return false\n  // Note that on systems that don't support read-write locks, these may\n  // be implemented as synonyms to Lock() and Unlock().  So you can use\n  // these for efficiency, but don't use them anyplace where being able\n  // to do shared reads is necessary to avoid deadlock.\n  inline void ReaderLock();   // Block until free or shared then acquire a share\n  inline void ReaderUnlock(); // Release a read share of this Mutex\n  inline void WriterLock() { Lock(); }     // Acquire an exclusive lock\n  inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()\n\n private:\n  MutexType mutex_;\n  // We want to make sure that the compiler sets is_safe_ to true only\n  // when we tell it to, and never makes assumptions is_safe_ is\n  // always true.  volatile is the most reliable way to do that.\n  volatile bool is_safe_;\n  // This indicates which constructor was called.\n  bool destroy_;\n\n  inline void SetIsSafe() { is_safe_ = true; }\n\n  // Catch the error of writing Mutex when intending MutexLock.\n  Mutex(Mutex* /*ignored*/) {}\n  // Disallow \"evil\" constructors\n  Mutex(const Mutex&);\n  void operator=(const Mutex&);\n};\n\n// Now the implementation of Mutex for various systems\n#if defined(NO_THREADS)\n\n// When we don't have threads, we can be either reading or writing,\n// but not both.  We can have lots of readers at once (in no-threads\n// mode, that's most likely to happen in recursive function calls),\n// but only one writer.  We represent this by having mutex_ be -1 when\n// writing and a number > 0 when reading (and 0 when no lock is held).\n//\n// In debug mode, we assert these invariants, while in non-debug mode\n// we do nothing, for efficiency.  That's why everything is in an\n// assert.\n\nMutex::Mutex() : mutex_(0) { }\nMutex::Mutex(Mutex::LinkerInitialized) : mutex_(0) { }\nMutex::~Mutex()            { assert(mutex_ == 0); }\nvoid Mutex::Lock()         { assert(--mutex_ == -1); }\nvoid Mutex::Unlock()       { assert(mutex_++ == -1); }\nbool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }\nvoid Mutex::ReaderLock()   { assert(++mutex_ > 0); }\nvoid Mutex::ReaderUnlock() { assert(mutex_-- > 0); }\n\n#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n\nMutex::Mutex() : destroy_(true) {\n  InitializeCriticalSection(&mutex_);\n  SetIsSafe();\n}\nMutex::Mutex(LinkerInitialized) : destroy_(false) {\n  InitializeCriticalSection(&mutex_);\n  SetIsSafe();\n}\nMutex::~Mutex()            { if (destroy_) DeleteCriticalSection(&mutex_); }\nvoid Mutex::Lock()         { if (is_safe_) EnterCriticalSection(&mutex_); }\nvoid Mutex::Unlock()       { if (is_safe_) LeaveCriticalSection(&mutex_); }\nbool Mutex::TryLock()      { return is_safe_ ?\n                                 TryEnterCriticalSection(&mutex_) != 0 : true; }\nvoid Mutex::ReaderLock()   { Lock(); }      // we don't have read-write locks\nvoid Mutex::ReaderUnlock() { Unlock(); }\n\n#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)\n\n#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \\\n  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \\\n} while (0)\n\nMutex::Mutex() : destroy_(true) {\n  SetIsSafe();\n  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();\n}\nMutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {\n  SetIsSafe();\n  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();\n}\nMutex::~Mutex()       { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); }\nvoid Mutex::Lock()         { SAFE_PTHREAD(pthread_rwlock_wrlock); }\nvoid Mutex::Unlock()       { SAFE_PTHREAD(pthread_rwlock_unlock); }\nbool Mutex::TryLock()      { return is_safe_ ?\n                               pthread_rwlock_trywrlock(&mutex_) == 0 : true; }\nvoid Mutex::ReaderLock()   { SAFE_PTHREAD(pthread_rwlock_rdlock); }\nvoid Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }\n#undef SAFE_PTHREAD\n\n#elif defined(HAVE_PTHREAD)\n\n#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \\\n  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \\\n} while (0)\n\nMutex::Mutex() : destroy_(true) {\n  SetIsSafe();\n  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();\n}\nMutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) {\n  SetIsSafe();\n  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();\n}\nMutex::~Mutex()       { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); }\nvoid Mutex::Lock()         { SAFE_PTHREAD(pthread_mutex_lock); }\nvoid Mutex::Unlock()       { SAFE_PTHREAD(pthread_mutex_unlock); }\nbool Mutex::TryLock()      { return is_safe_ ?\n                                 pthread_mutex_trylock(&mutex_) == 0 : true; }\nvoid Mutex::ReaderLock()   { Lock(); }\nvoid Mutex::ReaderUnlock() { Unlock(); }\n#undef SAFE_PTHREAD\n\n#endif\n\n// --------------------------------------------------------------------------\n// Some helper classes\n\n// MutexLock(mu) acquires mu when constructed and releases it when destroyed.\nclass MutexLock {\n public:\n  explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }\n  ~MutexLock() { mu_->Unlock(); }\n private:\n  Mutex * const mu_;\n  // Disallow \"evil\" constructors\n  MutexLock(const MutexLock&);\n  void operator=(const MutexLock&);\n};\n\n// ReaderMutexLock and WriterMutexLock do the same, for rwlocks\nclass ReaderMutexLock {\n public:\n  explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }\n  ~ReaderMutexLock() { mu_->ReaderUnlock(); }\n private:\n  Mutex * const mu_;\n  // Disallow \"evil\" constructors\n  ReaderMutexLock(const ReaderMutexLock&);\n  void operator=(const ReaderMutexLock&);\n};\n\nclass WriterMutexLock {\n public:\n  explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }\n  ~WriterMutexLock() { mu_->WriterUnlock(); }\n private:\n  Mutex * const mu_;\n  // Disallow \"evil\" constructors\n  WriterMutexLock(const WriterMutexLock&);\n  void operator=(const WriterMutexLock&);\n};\n\n// Catch bug where variable name is omitted, e.g. MutexLock (&mu);\n#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)\n#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)\n#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)\n\n}  // namespace MUTEX_NAMESPACE\n\nusing namespace MUTEX_NAMESPACE;\n\n#undef MUTEX_NAMESPACE\n\n#endif  /* #define GOOGLE_SIMPLE_MUTEX_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock.cc",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n */\n\n#include <config.h>\n#include \"base/spinlock.h\"\n#include \"base/synchronization_profiling.h\"\n#include \"base/spinlock_internal.h\"\n#include \"base/cycleclock.h\"\n#include \"base/sysinfo.h\"   /* for NumCPUs() */\n\n// NOTE on the Lock-state values:\n//\n//   kSpinLockFree represents the unlocked state\n//   kSpinLockHeld represents the locked state with no waiters\n//\n// Values greater than kSpinLockHeld represent the locked state with waiters,\n// where the value is the time the current lock holder had to\n// wait before obtaining the lock.  The kSpinLockSleeper state is a special\n// \"locked with waiters\" state that indicates that a sleeper needs to\n// be woken, but the thread that just released the lock didn't wait.\n\nstatic int adaptive_spin_count = 0;\n\nconst base::LinkerInitialized SpinLock::LINKER_INITIALIZED =\n    base::LINKER_INITIALIZED;\n\nnamespace {\nstruct SpinLock_InitHelper {\n  SpinLock_InitHelper() {\n    // On multi-cpu machines, spin for longer before yielding\n    // the processor or sleeping.  Reduces idle time significantly.\n    if (NumCPUs() > 1) {\n      adaptive_spin_count = 1000;\n    }\n  }\n};\n\n// Hook into global constructor execution:\n// We do not do adaptive spinning before that,\n// but nothing lock-intensive should be going on at that time.\nstatic SpinLock_InitHelper init_helper;\n\n}  // unnamed namespace\n\n// Monitor the lock to see if its value changes within some time period\n// (adaptive_spin_count loop iterations).  A timestamp indicating\n// when the thread initially started waiting for the lock is passed in via\n// the initial_wait_timestamp value.  The total wait time in cycles for the\n// lock is returned in the wait_cycles parameter.  The last value read\n// from the lock is returned from the method.\nAtomic32 SpinLock::SpinLoop(int64 initial_wait_timestamp,\n                            Atomic32* wait_cycles) {\n  int c = adaptive_spin_count;\n  while (base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree && --c > 0) {\n  }\n  Atomic32 spin_loop_wait_cycles = CalculateWaitCycles(initial_wait_timestamp);\n  Atomic32 lock_value =\n      base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,\n                                           spin_loop_wait_cycles);\n  *wait_cycles = spin_loop_wait_cycles;\n  return lock_value;\n}\n\nvoid SpinLock::SlowLock() {\n  // The lock was not obtained initially, so this thread needs to wait for\n  // it.  Record the current timestamp in the local variable wait_start_time\n  // so the total wait time can be stored in the lockword once this thread\n  // obtains the lock.\n  int64 wait_start_time = CycleClock::Now();\n  Atomic32 wait_cycles;\n  Atomic32 lock_value = SpinLoop(wait_start_time, &wait_cycles);\n\n  int lock_wait_call_count = 0;\n  while (lock_value != kSpinLockFree) {\n    // If the lock is currently held, but not marked as having a sleeper, mark\n    // it as having a sleeper.\n    if (lock_value == kSpinLockHeld) {\n      // Here, just \"mark\" that the thread is going to sleep.  Don't store the\n      // lock wait time in the lock as that will cause the current lock\n      // owner to think it experienced contention.\n      lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,\n                                                        kSpinLockHeld,\n                                                        kSpinLockSleeper);\n      if (lock_value == kSpinLockHeld) {\n        // Successfully transitioned to kSpinLockSleeper.  Pass\n        // kSpinLockSleeper to the SpinLockWait routine to properly indicate\n        // the last lock_value observed.\n        lock_value = kSpinLockSleeper;\n      } else if (lock_value == kSpinLockFree) {\n        // Lock is free again, so try and aquire it before sleeping.  The\n        // new lock state will be the number of cycles this thread waited if\n        // this thread obtains the lock.\n        lock_value = base::subtle::Acquire_CompareAndSwap(&lockword_,\n                                                          kSpinLockFree,\n                                                          wait_cycles);\n        continue;  // skip the delay at the end of the loop\n      }\n    }\n\n    // Wait for an OS specific delay.\n    base::internal::SpinLockDelay(&lockword_, lock_value,\n                                  ++lock_wait_call_count);\n    // Spin again after returning from the wait routine to give this thread\n    // some chance of obtaining the lock.\n    lock_value = SpinLoop(wait_start_time, &wait_cycles);\n  }\n}\n\n// The wait time for contentionz lock profiling must fit into 32 bits.\n// However, the lower 32-bits of the cycle counter wrap around too quickly\n// with high frequency processors, so a right-shift by 7 is performed to\n// quickly divide the cycles by 128.  Using these 32 bits, reduces the\n// granularity of time measurement to 128 cycles, and loses track\n// of wait time for waits greater than 109 seconds on a 5 GHz machine\n// [(2^32 cycles/5 Ghz)*128 = 109.95 seconds]. Waits this long should be\n// very rare and the reduced granularity should not be an issue given\n// processors in the Google fleet operate at a minimum of one billion\n// cycles/sec.\nenum { PROFILE_TIMESTAMP_SHIFT = 7 };\n\nvoid SpinLock::SlowUnlock(uint64 wait_cycles) {\n  base::internal::SpinLockWake(&lockword_, false);  // wake waiter if necessary\n\n  // Collect contentionz profile info, expanding the wait_cycles back out to\n  // the full value.  If wait_cycles is <= kSpinLockSleeper, then no wait\n  // was actually performed, so don't record the wait time.  Note, that the\n  // CalculateWaitCycles method adds in kSpinLockSleeper cycles\n  // unconditionally to guarantee the wait time is not kSpinLockFree or\n  // kSpinLockHeld.  The adding in of these small number of cycles may\n  // overestimate the contention by a slight amount 50% of the time.  However,\n  // if this code tried to correct for that addition by subtracting out the\n  // kSpinLockSleeper amount that would underestimate the contention slightly\n  // 50% of the time.  Both ways get the wrong answer, so the code\n  // overestimates to be more conservative. Overestimating also makes the code\n  // a little simpler.\n  //\n  if (wait_cycles > kSpinLockSleeper) {\n    base::SubmitSpinLockProfileData(this,\n                                    wait_cycles << PROFILE_TIMESTAMP_SHIFT);\n  }\n}\n\ninline int32 SpinLock::CalculateWaitCycles(int64 wait_start_time) {\n  int32 wait_cycles = ((CycleClock::Now() - wait_start_time) >>\n                       PROFILE_TIMESTAMP_SHIFT);\n  // The number of cycles waiting for the lock is used as both the\n  // wait_cycles and lock value, so it can't be kSpinLockFree or\n  // kSpinLockHeld.  Make sure the value returned is at least\n  // kSpinLockSleeper.\n  wait_cycles |= kSpinLockSleeper;\n  return wait_cycles;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n */\n\n//\n// Fast spinlocks (at least on x86, a lock/unlock pair is approximately\n// half the cost of a Mutex because the unlock just does a store instead\n// of a compare-and-swap which is expensive).\n\n// SpinLock is async signal safe.\n// If used within a signal handler, all lock holders\n// should block the signal even outside the signal handler.\n\n#ifndef BASE_SPINLOCK_H_\n#define BASE_SPINLOCK_H_\n\n#include <config.h>\n#include \"base/atomicops.h\"\n#include \"base/basictypes.h\"\n#include \"base/dynamic_annotations.h\"\n#include \"base/thread_annotations.h\"\n\nclass LOCKABLE SpinLock {\n public:\n  SpinLock() : lockword_(kSpinLockFree) { }\n\n  // Special constructor for use with static SpinLock objects.  E.g.,\n  //\n  //    static SpinLock lock(base::LINKER_INITIALIZED);\n  //\n  // When intialized using this constructor, we depend on the fact\n  // that the linker has already initialized the memory appropriately.\n  // A SpinLock constructed like this can be freely used from global\n  // initializers without worrying about the order in which global\n  // initializers run.\n  explicit SpinLock(base::LinkerInitialized /*x*/) {\n    // Does nothing; lockword_ is already initialized\n  }\n\n  // Acquire this SpinLock.\n  // TODO(csilvers): uncomment the annotation when we figure out how to\n  //                 support this macro with 0 args (see thread_annotations.h)\n  inline void Lock() /*EXCLUSIVE_LOCK_FUNCTION()*/ {\n    if (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,\n                                             kSpinLockHeld) != kSpinLockFree) {\n      SlowLock();\n    }\n    ANNOTATE_RWLOCK_ACQUIRED(this, 1);\n  }\n\n  // Try to acquire this SpinLock without blocking and return true if the\n  // acquisition was successful.  If the lock was not acquired, false is\n  // returned.  If this SpinLock is free at the time of the call, TryLock\n  // will return true with high probability.\n  inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) {\n    bool res =\n        (base::subtle::Acquire_CompareAndSwap(&lockword_, kSpinLockFree,\n                                              kSpinLockHeld) == kSpinLockFree);\n    if (res) {\n      ANNOTATE_RWLOCK_ACQUIRED(this, 1);\n    }\n    return res;\n  }\n\n  // Release this SpinLock, which must be held by the calling thread.\n  // TODO(csilvers): uncomment the annotation when we figure out how to\n  //                 support this macro with 0 args (see thread_annotations.h)\n  inline void Unlock() /*UNLOCK_FUNCTION()*/ {\n    uint64 wait_cycles =\n        static_cast<uint64>(base::subtle::NoBarrier_Load(&lockword_));\n    ANNOTATE_RWLOCK_RELEASED(this, 1);\n    base::subtle::Release_Store(&lockword_, kSpinLockFree);\n    if (wait_cycles != kSpinLockHeld) {\n      // Collect contentionz profile info, and speed the wakeup of any waiter.\n      // The wait_cycles value indicates how long this thread spent waiting\n      // for the lock.\n      SlowUnlock(wait_cycles);\n    }\n  }\n\n  // Determine if the lock is held.  When the lock is held by the invoking\n  // thread, true will always be returned. Intended to be used as\n  // CHECK(lock.IsHeld()).\n  inline bool IsHeld() const {\n    return base::subtle::NoBarrier_Load(&lockword_) != kSpinLockFree;\n  }\n\n  static const base::LinkerInitialized LINKER_INITIALIZED;  // backwards compat\n private:\n  enum { kSpinLockFree = 0 };\n  enum { kSpinLockHeld = 1 };\n  enum { kSpinLockSleeper = 2 };\n\n  volatile Atomic32 lockword_;\n\n  void SlowLock();\n  void SlowUnlock(uint64 wait_cycles);\n  Atomic32 SpinLoop(int64 initial_wait_timestamp, Atomic32* wait_cycles);\n  inline int32 CalculateWaitCycles(int64 wait_start_time);\n\n  DISALLOW_COPY_AND_ASSIGN(SpinLock);\n};\n\n// Corresponding locker object that arranges to acquire a spinlock for\n// the duration of a C++ scope.\nclass SCOPED_LOCKABLE SpinLockHolder {\n private:\n  SpinLock* lock_;\n public:\n  inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l)\n      : lock_(l) {\n    l->Lock();\n  }\n  // TODO(csilvers): uncomment the annotation when we figure out how to\n  //                 support this macro with 0 args (see thread_annotations.h)\n  inline ~SpinLockHolder() /*UNLOCK_FUNCTION()*/ { lock_->Unlock(); }\n};\n// Catch bug where variable name is omitted, e.g. SpinLockHolder (&lock);\n#define SpinLockHolder(x) COMPILE_ASSERT(0, spin_lock_decl_missing_var_name)\n\n\n#endif  // BASE_SPINLOCK_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock_internal.cc",
    "content": "/* Copyright (c) 2010, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n// The OS-specific header included below must provide two calls:\n// base::internal::SpinLockDelay() and base::internal::SpinLockWake().\n// See spinlock_internal.h for the spec of SpinLockWake().\n\n// void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop)\n// SpinLockDelay() generates an apprproate spin delay on iteration \"loop\" of a\n// spin loop on location *w, whose previously observed value was \"value\".\n// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick,\n// or may wait for a delay that can be truncated by a call to SpinlockWake(w).\n// In all cases, it must return in bounded time even if SpinlockWake() is not\n// called.\n\n#include \"base/spinlock_internal.h\"\n\n#if defined(_WIN32)\n#include \"base/spinlock_win32-inl.h\"\n#elif defined(__linux__)\n#include \"base/spinlock_linux-inl.h\"\n#else\n#include \"base/spinlock_posix-inl.h\"\n#endif\n\nnamespace base {\nnamespace internal {\n\n// See spinlock_internal.h for spec.\nint32 SpinLockWait(volatile Atomic32 *w, int n,\n                   const SpinLockWaitTransition trans[]) {\n  int32 v;\n  bool done = false;\n  for (int loop = 0; !done; loop++) {\n    v = base::subtle::Acquire_Load(w);\n    int i;\n    for (i = 0; i != n && v != trans[i].from; i++) {\n    }\n    if (i == n) {\n      SpinLockDelay(w, v, loop);     // no matching transition\n    } else if (trans[i].to == v ||   // null transition\n               base::subtle::Acquire_CompareAndSwap(w, v, trans[i].to) == v) {\n      done = trans[i].done;\n    }\n  }\n  return v;\n}\n\n} // namespace internal\n} // namespace base\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock_internal.h",
    "content": "/* Copyright (c) 2010, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * This file is an internal part spinlock.cc and once.cc\n * It may not be used directly by code outside of //base.\n */\n\n#ifndef BASE_SPINLOCK_INTERNAL_H_\n#define BASE_SPINLOCK_INTERNAL_H_\n\n#include <config.h>\n#include \"base/basictypes.h\"\n#include \"base/atomicops.h\"\n\nnamespace base {\nnamespace internal {\n\n// SpinLockWait() waits until it can perform one of several transitions from\n// \"from\" to \"to\".  It returns when it performs a transition where done==true.\nstruct SpinLockWaitTransition {\n  int32 from;\n  int32 to;\n  bool done;\n};\n\n// Wait until *w can transition from trans[i].from to trans[i].to for some i\n// satisfying 0<=i<n && trans[i].done, atomically make the transition,\n// then return the old value of *w.   Make any other atomic tranistions\n// where !trans[i].done, but continue waiting.\nint32 SpinLockWait(volatile Atomic32 *w, int n,\n                   const SpinLockWaitTransition trans[]);\nvoid SpinLockWake(volatile Atomic32 *w, bool all);\nvoid SpinLockDelay(volatile Atomic32 *w, int32 value, int loop);\n\n} // namespace internal\n} // namespace base\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock_linux-inl.h",
    "content": "/* Copyright (c) 2009, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * This file is a Linux-specific part of spinlock_internal.cc\n */\n\n#include <sched.h>\n#include <time.h>\n#include <limits.h>\n#include \"base/linux_syscall_support.h\"\n\n#define FUTEX_WAIT 0\n#define FUTEX_WAKE 1\n#define FUTEX_PRIVATE_FLAG 128\n\nstatic bool have_futex;\nstatic int futex_private_flag = FUTEX_PRIVATE_FLAG;\n\nnamespace {\nstatic struct InitModule {\n  InitModule() {\n    int x = 0;\n    // futexes are ints, so we can use them only when\n    // that's the same size as the lockword_ in SpinLock.\n    have_futex = (sizeof (Atomic32) == sizeof (int) &&\n                  sys_futex(&x, FUTEX_WAKE, 1, 0) >= 0);\n    if (have_futex &&\n        sys_futex(&x, FUTEX_WAKE | futex_private_flag, 1, 0) < 0) {\n      futex_private_flag = 0;\n    }\n  }\n} init_module;\n\n}  // anonymous namespace\n\n\nnamespace base {\nnamespace internal {\n\nvoid SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {\n  if (loop != 0) {\n    int save_errno = errno;\n    struct timespec tm;\n    tm.tv_sec = 0;\n    if (have_futex) {\n      tm.tv_nsec = 1000000;   // 1ms; really we're trying to sleep for one\n                              // kernel clock tick\n    } else {\n      tm.tv_nsec = 2000001;   // above 2ms so linux 2.4 doesn't spin\n    }\n    if (have_futex) {\n      sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),\n                FUTEX_WAIT | futex_private_flag,\n                value, reinterpret_cast<struct kernel_timespec *>(&tm));\n    } else {\n      nanosleep(&tm, NULL);\n    }\n    errno = save_errno;\n  }\n}\n\nvoid SpinLockWake(volatile Atomic32 *w, bool all) {\n  if (have_futex) {\n    sys_futex(reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),\n              FUTEX_WAKE | futex_private_flag, all? INT_MAX : 1, 0);\n  }\n}\n\n} // namespace internal\n} // namespace base\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock_posix-inl.h",
    "content": "/* Copyright (c) 2009, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * This file is a Posix-specific part of spinlock_internal.cc\n */\n\n#include <config.h>\n#include <errno.h>\n#ifdef HAVE_SCHED_H\n#include <sched.h>      /* For sched_yield() */\n#endif\n#include <time.h>       /* For nanosleep() */\n\nnamespace base {\nnamespace internal {\n\nvoid SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {\n  int save_errno = errno;\n  if (loop == 0) {\n  } else if (loop == 1) {\n    sched_yield();\n  } else {\n    struct timespec tm;\n    tm.tv_sec = 0;\n    tm.tv_nsec = 1000000;\n    nanosleep(&tm, NULL);\n  }\n  errno = save_errno;\n}\n\nvoid SpinLockWake(volatile Atomic32 *w, bool all) {\n}\n\n} // namespace internal\n} // namespace base\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/spinlock_win32-inl.h",
    "content": "/* Copyright (c) 2009, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * This file is a Win32-specific part of spinlock_internal.cc\n */\n\n\n#include <windows.h>\n\nnamespace base {\nnamespace internal {\n\nvoid SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {\n  if (loop == 0) {\n  } else if (loop == 1) {\n    Sleep(0);\n  } else {\n    Sleep(1);\n  }\n}\n\nvoid SpinLockWake(volatile Atomic32 *w, bool all) {\n}\n\n} // namespace internal\n} // namespace base\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/stl_allocator.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Maxim Lifantsev\n */\n\n\n#ifndef BASE_STL_ALLOCATOR_H_\n#define BASE_STL_ALLOCATOR_H_\n\n#include <config.h>\n\n#include <stddef.h>   // for ptrdiff_t\n#include <limits>\n\n#include \"base/basictypes.h\"\n#include \"base/logging.h\"\n\n// Generic allocator class for STL objects\n// that uses a given type-less allocator Alloc, which must provide:\n//   static void* Alloc::Allocate(size_t size);\n//   static void Alloc::Free(void* ptr, size_t size);\n//\n// STL_Allocator<T, MyAlloc> provides the same thread-safety\n// guarantees as MyAlloc.\n//\n// Usage example:\n//   set<T, less<T>, STL_Allocator<T, MyAlloc> > my_set;\n// CAVEAT: Parts of the code below are probably specific\n//         to the STL version(s) we are using.\n//         The code is simply lifted from what std::allocator<> provides.\ntemplate <typename T, class Alloc>\nclass STL_Allocator {\n public:\n  typedef size_t     size_type;\n  typedef ptrdiff_t  difference_type;\n  typedef T*         pointer;\n  typedef const T*   const_pointer;\n  typedef T&         reference;\n  typedef const T&   const_reference;\n  typedef T          value_type;\n\n  template <class T1> struct rebind {\n    typedef STL_Allocator<T1, Alloc> other;\n  };\n\n  STL_Allocator() { }\n  STL_Allocator(const STL_Allocator&) { }\n  template <class T1> STL_Allocator(const STL_Allocator<T1, Alloc>&) { }\n  ~STL_Allocator() { }\n\n  pointer address(reference x) const { return &x; }\n  const_pointer address(const_reference x) const { return &x; }\n\n  pointer allocate(size_type n, const void* = 0) {\n    RAW_DCHECK((n * sizeof(T)) / sizeof(T) == n, \"n is too big to allocate\");\n    return static_cast<T*>(Alloc::Allocate(n * sizeof(T)));\n  }\n  void deallocate(pointer p, size_type n) { Alloc::Free(p, n * sizeof(T)); }\n\n  size_type max_size() const { return size_t(-1) / sizeof(T); }\n\n  void construct(pointer p, const T& val) { ::new(p) T(val); }\n  void destroy(pointer p) { p->~T(); }\n\n  // There's no state, so these allocators are always equal\n  bool operator==(const STL_Allocator&) const { return true; }\n};\n\n#endif  // BASE_STL_ALLOCATOR_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/synchronization_profiling.h",
    "content": "/* Copyright (c) 2010, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Chris Ruemmler\n */\n\n#ifndef BASE_AUXILIARY_SYNCHRONIZATION_PROFILING_H_\n#define BASE_AUXILIARY_SYNCHRONIZATION_PROFILING_H_\n\n#include \"base/basictypes.h\"\n\nnamespace base {\n\n// We can do contention-profiling of SpinLocks, but the code is in\n// mutex.cc, which is not always linked in with spinlock.  Hence we\n// provide a weak definition, which are used if mutex.cc isn't linked in.\n\n// Submit the number of cycles the spinlock spent contending.\nATTRIBUTE_WEAK extern void SubmitSpinLockProfileData(const void *, int64);\nextern void SubmitSpinLockProfileData(const void *contendedlock,\n                                      int64 wait_cycles) {}\n}\n#endif  // BASE_AUXILIARY_SYNCHRONIZATION_PROFILING_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/sysinfo.cc",
    "content": "// Copyright (c) 2006, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include <config.h>\n#if (defined(_WIN32) || defined(__MINGW32__)) && !defined(__CYGWIN__) && !defined(__CYGWIN32)\n# define PLATFORM_WINDOWS 1\n#endif\n\n#include <stdlib.h>   // for getenv()\n#include <stdio.h>    // for snprintf(), sscanf()\n#include <string.h>   // for memmove(), memchr(), etc.\n#include <fcntl.h>    // for open()\n#include <errno.h>    // for errno\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>   // for read()\n#endif\n#if defined __MACH__          // Mac OS X, almost certainly\n#include <mach-o/dyld.h>      // for iterating over dll's in ProcMapsIter\n#include <mach-o/loader.h>    // for iterating over dll's in ProcMapsIter\n#include <sys/types.h>\n#include <sys/sysctl.h>       // how we figure out numcpu's on OS X\n#elif defined __FreeBSD__\n#include <sys/sysctl.h>\n#elif defined __sun__         // Solaris\n#include <procfs.h>           // for, e.g., prmap_t\n#elif defined(PLATFORM_WINDOWS)\n#include <process.h>          // for getpid() (actually, _getpid())\n#include <shlwapi.h>          // for SHGetValueA()\n#include <tlhelp32.h>         // for Module32First()\n#endif\n#include \"base/sysinfo.h\"\n#include \"base/commandlineflags.h\"\n#include \"base/dynamic_annotations.h\"   // for RunningOnValgrind\n#include \"base/logging.h\"\n#include \"base/cycleclock.h\"\n\n#ifdef PLATFORM_WINDOWS\n#ifdef MODULEENTRY32\n// In a change from the usual W-A pattern, there is no A variant of\n// MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.\n// In unicode mode, tlhelp32.h #defines MODULEENTRY32 to be\n// MODULEENTRY32W.  These #undefs are the only way I see to get back\n// access to the original, ascii struct (and related functions).\n#undef MODULEENTRY32\n#undef Module32First\n#undef Module32Next\n#undef PMODULEENTRY32\n#undef LPMODULEENTRY32\n#endif  /* MODULEENTRY32 */\n// MinGW doesn't seem to define this, perhaps some windowsen don't either.\n#ifndef TH32CS_SNAPMODULE32\n#define TH32CS_SNAPMODULE32  0\n#endif  /* TH32CS_SNAPMODULE32 */\n#endif  /* PLATFORM_WINDOWS */\n\n// Re-run fn until it doesn't cause EINTR.\n#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)\n\n// open/read/close can set errno, which may be illegal at this\n// time, so prefer making the syscalls directly if we can.\n#ifdef HAVE_SYS_SYSCALL_H\n# include <sys/syscall.h>\n# define safeopen(filename, mode)  syscall(SYS_open, filename, mode)\n# define saferead(fd, buffer, size)  syscall(SYS_read, fd, buffer, size)\n# define safeclose(fd)  syscall(SYS_close, fd)\n#else\n# define safeopen(filename, mode)  open(filename, mode)\n# define saferead(fd, buffer, size)  read(fd, buffer, size)\n# define safeclose(fd)  close(fd)\n#endif\n\n// ----------------------------------------------------------------------\n// GetenvBeforeMain()\n// GetUniquePathFromEnv()\n//    Some non-trivial getenv-related functions.\n// ----------------------------------------------------------------------\n\n// It's not safe to call getenv() in the malloc hooks, because they\n// might be called extremely early, before libc is done setting up\n// correctly.  In particular, the thread library may not be done\n// setting up errno.  So instead, we use the built-in __environ array\n// if it exists, and otherwise read /proc/self/environ directly, using\n// system calls to read the file, and thus avoid setting errno.\n// /proc/self/environ has a limit of how much data it exports (around\n// 8K), so it's not an ideal solution.\nconst char* GetenvBeforeMain(const char* name) {\n#if defined(HAVE___ENVIRON)   // if we have it, it's declared in unistd.h\n  if (__environ) {            // can exist but be NULL, if statically linked\n    const int namelen = strlen(name);\n    for (char** p = __environ; *p; p++) {\n      if (!memcmp(*p, name, namelen) && (*p)[namelen] == '=')  // it's a match\n        return *p + namelen+1;                                 // point after =\n    }\n    return NULL;\n  }\n#endif\n#if defined(PLATFORM_WINDOWS)\n  // TODO(mbelshe) - repeated calls to this function will overwrite the\n  // contents of the static buffer.\n  static char envvar_buf[1024];  // enough to hold any envvar we care about\n  if (!GetEnvironmentVariableA(name, envvar_buf, sizeof(envvar_buf)-1))\n    return NULL;\n  return envvar_buf;\n#endif\n  // static is ok because this function should only be called before\n  // main(), when we're single-threaded.\n  static char envbuf[16<<10];\n  if (*envbuf == '\\0') {    // haven't read the environ yet\n    int fd = safeopen(\"/proc/self/environ\", O_RDONLY);\n    // The -2 below guarantees the last two bytes of the buffer will be \\0\\0\n    if (fd == -1 ||           // unable to open the file, fall back onto libc\n        saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file\n      RAW_VLOG(1, \"Unable to open /proc/self/environ, falling back \"\n               \"on getenv(\\\"%s\\\"), which may not work\", name);\n      if (fd != -1) safeclose(fd);\n      return getenv(name);\n    }\n    safeclose(fd);\n  }\n  const int namelen = strlen(name);\n  const char* p = envbuf;\n  while (*p != '\\0') {    // will happen at the \\0\\0 that terminates the buffer\n    // proc file has the format NAME=value\\0NAME=value\\0NAME=value\\0...\n    const char* endp = (char*)memchr(p, '\\0', sizeof(envbuf) - (p - envbuf));\n    if (endp == NULL)            // this entry isn't NUL terminated\n      return NULL;\n    else if (!memcmp(p, name, namelen) && p[namelen] == '=')    // it's a match\n      return p + namelen+1;      // point after =\n    p = endp + 1;\n  }\n  return NULL;                   // env var never found\n}\n\n// This takes as an argument an environment-variable name (like\n// CPUPROFILE) whose value is supposed to be a file-path, and sets\n// path to that path, and returns true.  If the env var doesn't exist,\n// or is the empty string, leave path unchanged and returns false.\n// The reason this is non-trivial is that this function handles munged\n// pathnames.  Here's why:\n//\n// If we're a child process of the 'main' process, we can't just use\n// getenv(\"CPUPROFILE\") -- the parent process will be using that path.\n// Instead we append our pid to the pathname.  How do we tell if we're a\n// child process?  Ideally we'd set an environment variable that all\n// our children would inherit.  But -- and this is seemingly a bug in\n// gcc -- if you do a setenv() in a shared libarary in a global\n// constructor, the environment setting is lost by the time main() is\n// called.  The only safe thing we can do in such a situation is to\n// modify the existing envvar.  So we do a hack: in the parent, we set\n// the high bit of the 1st char of CPUPROFILE.  In the child, we\n// notice the high bit is set and append the pid().  This works\n// assuming cpuprofile filenames don't normally have the high bit set\n// in their first character!  If that assumption is violated, we'll\n// still get a profile, but one with an unexpected name.\n// TODO(csilvers): set an envvar instead when we can do it reliably.\nbool GetUniquePathFromEnv(const char* env_name, char* path) {\n  char* envval = getenv(env_name);\n  if (envval == NULL || *envval == '\\0')\n    return false;\n  if (envval[0] & 128) {                  // high bit is set\n    snprintf(path, PATH_MAX, \"%c%s_%u\",   // add pid and clear high bit\n             envval[0] & 127, envval+1, (unsigned int)(getpid()));\n  } else {\n    snprintf(path, PATH_MAX, \"%s\", envval);\n    envval[0] |= 128;                     // set high bit for kids to see\n  }\n  return true;\n}\n\n// ----------------------------------------------------------------------\n// CyclesPerSecond()\n// NumCPUs()\n//    It's important this not call malloc! -- they may be called at\n//    global-construct time, before we've set up all our proper malloc\n//    hooks and such.\n// ----------------------------------------------------------------------\n\nstatic double cpuinfo_cycles_per_second = 1.0;  // 0.0 might be dangerous\nstatic int cpuinfo_num_cpus = 1;  // Conservative guess\n\nstatic void SleepForMilliseconds(int milliseconds) {\n#ifdef PLATFORM_WINDOWS\n  _sleep(milliseconds);   // Windows's _sleep takes milliseconds argument\n#else\n  // Sleep for a few milliseconds\n  struct timespec sleep_time;\n  sleep_time.tv_sec = milliseconds / 1000;\n  sleep_time.tv_nsec = (milliseconds % 1000) * 1000000;\n  while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR)\n    ;  // Ignore signals and wait for the full interval to elapse.\n#endif\n}\n\n// Helper function estimates cycles/sec by observing cycles elapsed during\n// sleep(). Using small sleep time decreases accuracy significantly.\nstatic int64 EstimateCyclesPerSecond(const int estimate_time_ms) {\n  assert(estimate_time_ms > 0);\n  if (estimate_time_ms <= 0)\n    return 1;\n  double multiplier = 1000.0 / (double)estimate_time_ms;  // scale by this much\n\n  const int64 start_ticks = CycleClock::Now();\n  SleepForMilliseconds(estimate_time_ms);\n  const int64 guess = int64(multiplier * (CycleClock::Now() - start_ticks));\n  return guess;\n}\n\n// Helper function for reading an int from a file. Returns true if successful\n// and the memory location pointed to by value is set to the value read.\nstatic bool ReadIntFromFile(const char *file, int *value) {\n  bool ret = false;\n  int fd = open(file, O_RDONLY);\n  if (fd != -1) {\n    char line[1024];\n    char* err;\n    memset(line, '\\0', sizeof(line));\n    read(fd, line, sizeof(line) - 1);\n    const int temp_value = strtol(line, &err, 10);\n    if (line[0] != '\\0' && (*err == '\\n' || *err == '\\0')) {\n      *value = temp_value;\n      ret = true;\n    }\n    close(fd);\n  }\n  return ret;\n}\n\n// WARNING: logging calls back to InitializeSystemInfo() so it must\n// not invoke any logging code.  Also, InitializeSystemInfo() can be\n// called before main() -- in fact it *must* be since already_called\n// isn't protected -- before malloc hooks are properly set up, so\n// we make an effort not to call any routines which might allocate\n// memory.\n\nstatic void InitializeSystemInfo() {\n  static bool already_called = false;   // safe if we run before threads\n  if (already_called)  return;\n  already_called = true;\n\n  bool saw_mhz = false;\n\n  if (RunningOnValgrind()) {\n    // Valgrind may slow the progress of time artificially (--scale-time=N\n    // option). We thus can't rely on CPU Mhz info stored in /sys or /proc\n    // files. Thus, actually measure the cps.\n    cpuinfo_cycles_per_second = EstimateCyclesPerSecond(100);\n    saw_mhz = true;\n  }\n\n#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n  char line[1024];\n  char* err;\n  int freq;\n\n  // If the kernel is exporting the tsc frequency use that. There are issues\n  // where cpuinfo_max_freq cannot be relied on because the BIOS may be\n  // exporintg an invalid p-state (on x86) or p-states may be used to put the\n  // processor in a new mode (turbo mode). Essentially, those frequencies\n  // cannot always be relied upon. The same reasons apply to /proc/cpuinfo as\n  // well.\n  if (!saw_mhz &&\n      ReadIntFromFile(\"/sys/devices/system/cpu/cpu0/tsc_freq_khz\", &freq)) {\n      // The value is in kHz (as the file name suggests).  For example, on a\n      // 2GHz warpstation, the file contains the value \"2000000\".\n      cpuinfo_cycles_per_second = freq * 1000.0;\n      saw_mhz = true;\n  }\n\n  // If CPU scaling is in effect, we want to use the *maximum* frequency,\n  // not whatever CPU speed some random processor happens to be using now.\n  if (!saw_mhz &&\n      ReadIntFromFile(\"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\",\n                      &freq)) {\n    // The value is in kHz.  For example, on a 2GHz machine, the file\n    // contains the value \"2000000\".\n    cpuinfo_cycles_per_second = freq * 1000.0;\n    saw_mhz = true;\n  }\n\n  // Read /proc/cpuinfo for other values, and if there is no cpuinfo_max_freq.\n  const char* pname = \"/proc/cpuinfo\";\n  int fd = open(pname, O_RDONLY);\n  if (fd == -1) {\n    perror(pname);\n    if (!saw_mhz) {\n      cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);\n    }\n    return;          // TODO: use generic tester instead?\n  }\n\n  double bogo_clock = 1.0;\n  int num_cpus = 0;\n  line[0] = line[1] = '\\0';\n  int chars_read = 0;\n  do {   // we'll exit when the last read didn't read anything\n    // Move the next line to the beginning of the buffer\n    const int oldlinelen = strlen(line);\n    if (sizeof(line) == oldlinelen + 1)    // oldlinelen took up entire line\n      line[0] = '\\0';\n    else                                   // still other lines left to save\n      memmove(line, line + oldlinelen+1, sizeof(line) - (oldlinelen+1));\n    // Terminate the new line, reading more if we can't find the newline\n    char* newline = strchr(line, '\\n');\n    if (newline == NULL) {\n      const int linelen = strlen(line);\n      const int bytes_to_read = sizeof(line)-1 - linelen;\n      assert(bytes_to_read > 0);  // because the memmove recovered >=1 bytes\n      chars_read = read(fd, line + linelen, bytes_to_read);\n      line[linelen + chars_read] = '\\0';\n      newline = strchr(line, '\\n');\n    }\n    if (newline != NULL)\n      *newline = '\\0';\n\n    if (!saw_mhz && strncasecmp(line, \"cpu MHz\", sizeof(\"cpu MHz\")-1) == 0) {\n      const char* freqstr = strchr(line, ':');\n      if (freqstr) {\n        cpuinfo_cycles_per_second = strtod(freqstr+1, &err) * 1000000.0;\n        if (freqstr[1] != '\\0' && *err == '\\0')\n          saw_mhz = true;\n      }\n    } else if (strncasecmp(line, \"bogomips\", sizeof(\"bogomips\")-1) == 0) {\n      const char* freqstr = strchr(line, ':');\n      if (freqstr)\n        bogo_clock = strtod(freqstr+1, &err) * 1000000.0;\n      if (freqstr == NULL || freqstr[1] == '\\0' || *err != '\\0')\n        bogo_clock = 1.0;\n    } else if (strncasecmp(line, \"processor\", sizeof(\"processor\")-1) == 0) {\n      num_cpus++;  // count up every time we see an \"processor :\" entry\n    }\n  } while (chars_read > 0);\n  close(fd);\n\n  if (!saw_mhz) {\n    // If we didn't find anything better, we'll use bogomips, but\n    // we're not happy about it.\n    cpuinfo_cycles_per_second = bogo_clock;\n  }\n  if (cpuinfo_cycles_per_second == 0.0) {\n    cpuinfo_cycles_per_second = 1.0;   // maybe unnecessary, but safe\n  }\n  if (num_cpus > 0) {\n    cpuinfo_num_cpus = num_cpus;\n  }\n\n#elif defined __FreeBSD__\n  // For this sysctl to work, the machine must be configured without\n  // SMP, APIC, or APM support.  hz should be 64-bit in freebsd 7.0\n  // and later.  Before that, it's a 32-bit quantity (and gives the\n  // wrong answer on machines faster than 2^32 Hz).  See\n  //  http://lists.freebsd.org/pipermail/freebsd-i386/2004-November/001846.html\n  // But also compare FreeBSD 7.0:\n  //  http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG70#L223\n  //  231         error = sysctl_handle_quad(oidp, &freq, 0, req);\n  // To FreeBSD 6.3 (it's the same in 6-STABLE):\n  //  http://fxr.watson.org/fxr/source/i386/i386/tsc.c?v=RELENG6#L131\n  //  139         error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);\n#if __FreeBSD__ >= 7\n  uint64_t hz = 0;\n#else\n  unsigned int hz = 0;\n#endif\n  size_t sz = sizeof(hz);\n  const char *sysctl_path = \"machdep.tsc_freq\";\n  if ( sysctlbyname(sysctl_path, &hz, &sz, NULL, 0) != 0 ) {\n    fprintf(stderr, \"Unable to determine clock rate from sysctl: %s: %s\\n\",\n            sysctl_path, strerror(errno));\n    cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);\n  } else {\n    cpuinfo_cycles_per_second = hz;\n  }\n  // TODO(csilvers): also figure out cpuinfo_num_cpus\n\n#elif defined(PLATFORM_WINDOWS)\n# pragma comment(lib, \"shlwapi.lib\")  // for SHGetValue()\n  // In NT, read MHz from the registry. If we fail to do so or we're in win9x\n  // then make a crude estimate.\n  OSVERSIONINFO os;\n  os.dwOSVersionInfoSize = sizeof(os);\n  DWORD data, data_size = sizeof(data);\n  if (GetVersionEx(&os) &&\n      os.dwPlatformId == VER_PLATFORM_WIN32_NT &&\n      SUCCEEDED(SHGetValueA(HKEY_LOCAL_MACHINE,\n                         \"HARDWARE\\\\DESCRIPTION\\\\System\\\\CentralProcessor\\\\0\",\n                           \"~MHz\", NULL, &data, &data_size)))\n    cpuinfo_cycles_per_second = (int64)data * (int64)(1000 * 1000); // was mhz\n  else\n    cpuinfo_cycles_per_second = EstimateCyclesPerSecond(500); // TODO <500?\n\n  // Get the number of processors.\n  SYSTEM_INFO info;\n  GetSystemInfo(&info);\n  cpuinfo_num_cpus = info.dwNumberOfProcessors;\n\n#elif defined(__MACH__) && defined(__APPLE__)\n  // returning \"mach time units\" per second. the current number of elapsed\n  // mach time units can be found by calling uint64 mach_absolute_time();\n  // while not as precise as actual CPU cycles, it is accurate in the face\n  // of CPU frequency scaling and multi-cpu/core machines.\n  // Our mac users have these types of machines, and accuracy\n  // (i.e. correctness) trumps precision.\n  // See cycleclock.h: CycleClock::Now(), which returns number of mach time\n  // units on Mac OS X.\n  mach_timebase_info_data_t timebase_info;\n  mach_timebase_info(&timebase_info);\n  double mach_time_units_per_nanosecond =\n      static_cast<double>(timebase_info.denom) /\n      static_cast<double>(timebase_info.numer);\n  cpuinfo_cycles_per_second = mach_time_units_per_nanosecond * 1e9;\n\n  int num_cpus = 0;\n  size_t size = sizeof(num_cpus);\n  int numcpus_name[] = { CTL_HW, HW_NCPU };\n  if (::sysctl(numcpus_name, arraysize(numcpus_name), &num_cpus, &size, 0, 0)\n      == 0\n      && (size == sizeof(num_cpus)))\n    cpuinfo_num_cpus = num_cpus;\n\n#else\n  // Generic cycles per second counter\n  cpuinfo_cycles_per_second = EstimateCyclesPerSecond(1000);\n#endif\n}\n\ndouble CyclesPerSecond(void) {\n  InitializeSystemInfo();\n  return cpuinfo_cycles_per_second;\n}\n\nint NumCPUs(void) {\n  InitializeSystemInfo();\n  return cpuinfo_num_cpus;\n}\n\n// ----------------------------------------------------------------------\n// HasPosixThreads()\n//      Return true if we're running POSIX (e.g., NPTL on Linux)\n//      threads, as opposed to a non-POSIX thread libary.  The thing\n//      that we care about is whether a thread's pid is the same as\n//      the thread that spawned it.  If so, this function returns\n//      true.\n// ----------------------------------------------------------------------\nbool HasPosixThreads() {\n#if defined(__linux__)\n#ifndef _CS_GNU_LIBPTHREAD_VERSION\n#define _CS_GNU_LIBPTHREAD_VERSION 3\n#endif\n  char buf[32];\n  //  We assume that, if confstr() doesn't know about this name, then\n  //  the same glibc is providing LinuxThreads.\n  if (confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf)) == 0)\n    return false;\n  return strncmp(buf, \"NPTL\", 4) == 0;\n#elif defined(PLATFORM_WINDOWS) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n  return false;\n#else  // other OS\n  return true;      //  Assume that everything else has Posix\n#endif  // else OS_LINUX\n}\n\n// ----------------------------------------------------------------------\n\n#if defined __linux__ || defined __FreeBSD__ || defined __sun__ || defined __CYGWIN__ || defined __CYGWIN32__\nstatic void ConstructFilename(const char* spec, pid_t pid,\n                              char* buf, int buf_size) {\n  CHECK_LT(snprintf(buf, buf_size,\n                    spec,\n                    pid ? pid : getpid()), buf_size);\n}\n#endif\n\n// A templatized helper function instantiated for Mach (OS X) only.\n// It can handle finding info for both 32 bits and 64 bits.\n// Returns true if it successfully handled the hdr, false else.\n#ifdef __MACH__          // Mac OS X, almost certainly\ntemplate<uint32_t kMagic, uint32_t kLCSegment,\n         typename MachHeader, typename SegmentCommand>\nstatic bool NextExtMachHelper(const mach_header* hdr,\n                              int current_image, int current_load_cmd,\n                              uint64 *start, uint64 *end, char **flags,\n                              uint64 *offset, int64 *inode, char **filename,\n                              uint64 *file_mapping, uint64 *file_pages,\n                              uint64 *anon_mapping, uint64 *anon_pages,\n                              dev_t *dev) {\n  static char kDefaultPerms[5] = \"r-xp\";\n  if (hdr->magic != kMagic)\n    return false;\n  const char* lc = (const char *)hdr + sizeof(MachHeader);\n  // TODO(csilvers): make this not-quadradic (increment and hold state)\n  for (int j = 0; j < current_load_cmd; j++)  // advance to *our* load_cmd\n    lc += ((const load_command *)lc)->cmdsize;\n  if (((const load_command *)lc)->cmd == kLCSegment) {\n    const intptr_t dlloff = _dyld_get_image_vmaddr_slide(current_image);\n    const SegmentCommand* sc = (const SegmentCommand *)lc;\n    if (start) *start = sc->vmaddr + dlloff;\n    if (end) *end = sc->vmaddr + sc->vmsize + dlloff;\n    if (flags) *flags = kDefaultPerms;  // can we do better?\n    if (offset) *offset = sc->fileoff;\n    if (inode) *inode = 0;\n    if (filename)\n      *filename = const_cast<char*>(_dyld_get_image_name(current_image));\n    if (file_mapping) *file_mapping = 0;\n    if (file_pages) *file_pages = 0;   // could we use sc->filesize?\n    if (anon_mapping) *anon_mapping = 0;\n    if (anon_pages) *anon_pages = 0;\n    if (dev) *dev = 0;\n    return true;\n  }\n\n  return false;\n}\n#endif\n\nProcMapsIterator::ProcMapsIterator(pid_t pid) {\n  Init(pid, NULL, false);\n}\n\nProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer) {\n  Init(pid, buffer, false);\n}\n\nProcMapsIterator::ProcMapsIterator(pid_t pid, Buffer *buffer,\n                                   bool use_maps_backing) {\n  Init(pid, buffer, use_maps_backing);\n}\n\nvoid ProcMapsIterator::Init(pid_t pid, Buffer *buffer,\n                            bool use_maps_backing) {\n  pid_ = pid;\n  using_maps_backing_ = use_maps_backing;\n  dynamic_buffer_ = NULL;\n  if (!buffer) {\n    // If the user didn't pass in any buffer storage, allocate it\n    // now. This is the normal case; the signal handler passes in a\n    // static buffer.\n    buffer = dynamic_buffer_ = new Buffer;\n  } else {\n    dynamic_buffer_ = NULL;\n  }\n\n  ibuf_ = buffer->buf_;\n\n  stext_ = etext_ = nextline_ = ibuf_;\n  ebuf_ = ibuf_ + Buffer::kBufSize - 1;\n  nextline_ = ibuf_;\n\n#if defined(__linux__) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n  if (use_maps_backing) {  // don't bother with clever \"self\" stuff in this case\n    ConstructFilename(\"/proc/%d/maps_backing\", pid, ibuf_, Buffer::kBufSize);\n  } else if (pid == 0) {\n    // We have to kludge a bit to deal with the args ConstructFilename\n    // expects.  The 1 is never used -- it's only impt. that it's not 0.\n    ConstructFilename(\"/proc/self/maps\", 1, ibuf_, Buffer::kBufSize);\n  } else {\n    ConstructFilename(\"/proc/%d/maps\", pid, ibuf_, Buffer::kBufSize);\n  }\n  // No error logging since this can be called from the crash dump\n  // handler at awkward moments. Users should call Valid() before\n  // using.\n  NO_INTR(fd_ = open(ibuf_, O_RDONLY));\n#elif defined(__FreeBSD__)\n  // We don't support maps_backing on freebsd\n  if (pid == 0) {\n    ConstructFilename(\"/proc/curproc/map\", 1, ibuf_, Buffer::kBufSize);\n  } else {\n    ConstructFilename(\"/proc/%d/map\", pid, ibuf_, Buffer::kBufSize);\n  }\n  NO_INTR(fd_ = open(ibuf_, O_RDONLY));\n#elif defined(__sun__)\n  if (pid == 0) {\n    ConstructFilename(\"/proc/self/map\", 1, ibuf_, Buffer::kBufSize);\n  } else {\n    ConstructFilename(\"/proc/%d/map\", pid, ibuf_, Buffer::kBufSize);\n  }\n  NO_INTR(fd_ = open(ibuf_, O_RDONLY));\n#elif defined(__MACH__)\n  current_image_ = _dyld_image_count();   // count down from the top\n  current_load_cmd_ = -1;\n#elif defined(PLATFORM_WINDOWS)\n  snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE |\n                                       TH32CS_SNAPMODULE32,\n                                       GetCurrentProcessId());\n  memset(&module_, 0, sizeof(module_));\n#else\n  fd_ = -1;   // so Valid() is always false\n#endif\n\n}\n\nProcMapsIterator::~ProcMapsIterator() {\n#if defined(PLATFORM_WINDOWS)\n  if (snapshot_ != INVALID_HANDLE_VALUE) CloseHandle(snapshot_);\n#elif defined(__MACH__)\n  // no cleanup necessary!\n#else\n  if (fd_ >= 0) NO_INTR(close(fd_));\n#endif\n  delete dynamic_buffer_;\n}\n\nbool ProcMapsIterator::Valid() const {\n#if defined(PLATFORM_WINDOWS)\n  return snapshot_ != INVALID_HANDLE_VALUE;\n#elif defined(__MACH__)\n  return 1;\n#else\n  return fd_ != -1;\n#endif\n}\n\nbool ProcMapsIterator::Next(uint64 *start, uint64 *end, char **flags,\n                            uint64 *offset, int64 *inode, char **filename) {\n  return NextExt(start, end, flags, offset, inode, filename, NULL, NULL,\n                 NULL, NULL, NULL);\n}\n\n// This has too many arguments.  It should really be building\n// a map object and returning it.  The problem is that this is called\n// when the memory allocator state is undefined, hence the arguments.\nbool ProcMapsIterator::NextExt(uint64 *start, uint64 *end, char **flags,\n                               uint64 *offset, int64 *inode, char **filename,\n                               uint64 *file_mapping, uint64 *file_pages,\n                               uint64 *anon_mapping, uint64 *anon_pages,\n                               dev_t *dev) {\n\n#if defined(__linux__) || defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__CYGWIN32__)\n  do {\n    // Advance to the start of the next line\n    stext_ = nextline_;\n\n    // See if we have a complete line in the buffer already\n    nextline_ = static_cast<char *>(memchr (stext_, '\\n', etext_ - stext_));\n    if (!nextline_) {\n      // Shift/fill the buffer so we do have a line\n      int count = etext_ - stext_;\n\n      // Move the current text to the start of the buffer\n      memmove(ibuf_, stext_, count);\n      stext_ = ibuf_;\n      etext_ = ibuf_ + count;\n\n      int nread = 0;            // fill up buffer with text\n      while (etext_ < ebuf_) {\n        NO_INTR(nread = read(fd_, etext_, ebuf_ - etext_));\n        if (nread > 0)\n          etext_ += nread;\n        else\n          break;\n      }\n\n      // Zero out remaining characters in buffer at EOF to avoid returning\n      // garbage from subsequent calls.\n      if (etext_ != ebuf_ && nread == 0) {\n        memset(etext_, 0, ebuf_ - etext_);\n      }\n      *etext_ = '\\n';   // sentinel; safe because ibuf extends 1 char beyond ebuf\n      nextline_ = static_cast<char *>(memchr (stext_, '\\n', etext_ + 1 - stext_));\n    }\n    *nextline_ = 0;                // turn newline into nul\n    nextline_ += ((nextline_ < etext_)? 1 : 0);  // skip nul if not end of text\n    // stext_ now points at a nul-terminated line\n    uint64 tmpstart, tmpend, tmpoffset;\n    int64 tmpinode;\n    int major, minor;\n    unsigned filename_offset = 0;\n#if defined(__linux__)\n    // for now, assume all linuxes have the same format\n    if (sscanf(stext_, \"%\"SCNx64\"-%\"SCNx64\" %4s %\"SCNx64\" %x:%x %\"SCNd64\" %n\",\n               start ? start : &tmpstart,\n               end ? end : &tmpend,\n               flags_,\n               offset ? offset : &tmpoffset,\n               &major, &minor,\n               inode ? inode : &tmpinode, &filename_offset) != 7) continue;\n#elif defined(__CYGWIN__) || defined(__CYGWIN32__)\n    // cygwin is like linux, except the third field is the \"entry point\"\n    // rather than the offset (see format_process_maps at\n    // http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/fhandler_process.cc?rev=1.89&content-type=text/x-cvsweb-markup&cvsroot=src\n    // Offset is always be 0 on cygwin: cygwin implements an mmap\n    // by loading the whole file and then calling NtMapViewOfSection.\n    // Cygwin also seems to set its flags kinda randomly; use windows default.\n    char tmpflags[5];\n    if (offset)\n      *offset = 0;\n    strcpy(flags_, \"r-xp\");\n    if (sscanf(stext_, \"%llx-%llx %4s %llx %x:%x %lld %n\",\n               start ? start : &tmpstart,\n               end ? end : &tmpend,\n               tmpflags,\n               &tmpoffset,\n               &major, &minor,\n               inode ? inode : &tmpinode, &filename_offset) != 7) continue;\n#elif defined(__FreeBSD__)\n    // For the format, see http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/fs/procfs/procfs_map.c?rev=1.31&content-type=text/x-cvsweb-markup\n    tmpstart = tmpend = tmpoffset = 0;\n    tmpinode = 0;\n    major = minor = 0;   // can't get this info in freebsd\n    if (inode)\n      *inode = 0;        // nor this\n    if (offset)\n      *offset = 0;       // seems like this should be in there, but maybe not\n    // start end resident privateresident obj(?) prot refcnt shadowcnt\n    // flags copy_on_write needs_copy type filename:\n    // 0x8048000 0x804a000 2 0 0xc104ce70 r-x 1 0 0x0 COW NC vnode /bin/cat\n    if (sscanf(stext_, \"0x%\"SCNx64\" 0x%\"SCNx64\" %*d %*d %*p %3s %*d %*d 0x%*x %*s %*s %*s %n\",\n               start ? start : &tmpstart,\n               end ? end : &tmpend,\n               flags_,\n               &filename_offset) != 3) continue;\n#endif\n\n    // Depending on the Linux kernel being used, there may or may not be a space\n    // after the inode if there is no filename.  sscanf will in such situations\n    // nondeterministically either fill in filename_offset or not (the results\n    // differ on multiple calls in the same run even with identical arguments).\n    // We don't want to wander off somewhere beyond the end of the string.\n    size_t stext_length = strlen(stext_);\n    if (filename_offset == 0 || filename_offset > stext_length)\n      filename_offset = stext_length;\n\n    // We found an entry\n    if (flags) *flags = flags_;\n    if (filename) *filename = stext_ + filename_offset;\n    if (dev) *dev = minor | (major << 8);\n\n    if (using_maps_backing_) {\n      // Extract and parse physical page backing info.\n      char *backing_ptr = stext_ + filename_offset +\n          strlen(stext_+filename_offset);\n\n      // find the second '('\n      int paren_count = 0;\n      while (--backing_ptr > stext_) {\n        if (*backing_ptr == '(') {\n          ++paren_count;\n          if (paren_count >= 2) {\n            uint64 tmp_file_mapping;\n            uint64 tmp_file_pages;\n            uint64 tmp_anon_mapping;\n            uint64 tmp_anon_pages;\n\n            sscanf(backing_ptr+1, \"F %\"SCNx64\" %\"SCNd64\") (A %\"SCNx64\" %\"SCNd64\")\",\n                   file_mapping ? file_mapping : &tmp_file_mapping,\n                   file_pages ? file_pages : &tmp_file_pages,\n                   anon_mapping ? anon_mapping : &tmp_anon_mapping,\n                   anon_pages ? anon_pages : &tmp_anon_pages);\n            // null terminate the file name (there is a space\n            // before the first (.\n            backing_ptr[-1] = 0;\n            break;\n          }\n        }\n      }\n    }\n\n    return true;\n  } while (etext_ > ibuf_);\n#elif defined(__sun__)\n  // This is based on MA_READ == 4, MA_WRITE == 2, MA_EXEC == 1\n  static char kPerms[8][4] = { \"---\", \"--x\", \"-w-\", \"-wx\",\n                               \"r--\", \"r-x\", \"rw-\", \"rwx\" };\n  COMPILE_ASSERT(MA_READ == 4, solaris_ma_read_must_equal_4);\n  COMPILE_ASSERT(MA_WRITE == 2, solaris_ma_write_must_equal_2);\n  COMPILE_ASSERT(MA_EXEC == 1, solaris_ma_exec_must_equal_1);\n  Buffer object_path;\n  int nread = 0;            // fill up buffer with text\n  NO_INTR(nread = read(fd_, ibuf_, sizeof(prmap_t)));\n  if (nread == sizeof(prmap_t)) {\n    long inode_from_mapname = 0;\n    prmap_t* mapinfo = reinterpret_cast<prmap_t*>(ibuf_);\n    // Best-effort attempt to get the inode from the filename.  I think the\n    // two middle ints are major and minor device numbers, but I'm not sure.\n    sscanf(mapinfo->pr_mapname, \"ufs.%*d.%*d.%ld\", &inode_from_mapname);\n\n    if (pid_ == 0) {\n      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,\n                        \"/proc/self/path/%s\", mapinfo->pr_mapname),\n               Buffer::kBufSize);\n    } else {\n      CHECK_LT(snprintf(object_path.buf_, Buffer::kBufSize,\n                        \"/proc/%d/path/%s\", pid_, mapinfo->pr_mapname),\n               Buffer::kBufSize);\n    }\n    ssize_t len = readlink(object_path.buf_, current_filename_, PATH_MAX);\n    CHECK_LT(len, PATH_MAX);\n    if (len < 0)\n      len = 0;\n    current_filename_[len] = '\\0';\n\n    if (start) *start = mapinfo->pr_vaddr;\n    if (end) *end = mapinfo->pr_vaddr + mapinfo->pr_size;\n    if (flags) *flags = kPerms[mapinfo->pr_mflags & 7];\n    if (offset) *offset = mapinfo->pr_offset;\n    if (inode) *inode = inode_from_mapname;\n    if (filename) *filename = current_filename_;\n    if (file_mapping) *file_mapping = 0;\n    if (file_pages) *file_pages = 0;\n    if (anon_mapping) *anon_mapping = 0;\n    if (anon_pages) *anon_pages = 0;\n    if (dev) *dev = 0;\n    return true;\n  }\n#elif defined(__MACH__)\n  // We return a separate entry for each segment in the DLL. (TODO(csilvers):\n  // can we do better?)  A DLL (\"image\") has load-commands, some of which\n  // talk about segment boundaries.\n  // cf image_for_address from http://svn.digium.com/view/asterisk/team/oej/minivoicemail/dlfcn.c?revision=53912\n  for (; current_image_ >= 0; current_image_--) {\n    const mach_header* hdr = _dyld_get_image_header(current_image_);\n    if (!hdr) continue;\n    if (current_load_cmd_ < 0)   // set up for this image\n      current_load_cmd_ = hdr->ncmds;  // again, go from the top down\n\n    // We start with the next load command (we've already looked at this one).\n    for (current_load_cmd_--; current_load_cmd_ >= 0; current_load_cmd_--) {\n#ifdef MH_MAGIC_64\n      if (NextExtMachHelper<MH_MAGIC_64, LC_SEGMENT_64,\n                            struct mach_header_64, struct segment_command_64>(\n                                hdr, current_image_, current_load_cmd_,\n                                start, end, flags, offset, inode, filename,\n                                file_mapping, file_pages, anon_mapping,\n                                anon_pages, dev)) {\n        return true;\n      }\n#endif\n      if (NextExtMachHelper<MH_MAGIC, LC_SEGMENT,\n                            struct mach_header, struct segment_command>(\n                                hdr, current_image_, current_load_cmd_,\n                                start, end, flags, offset, inode, filename,\n                                file_mapping, file_pages, anon_mapping,\n                                anon_pages, dev)) {\n        return true;\n      }\n    }\n    // If we get here, no more load_cmd's in this image talk about\n    // segments.  Go on to the next image.\n  }\n#elif defined(PLATFORM_WINDOWS)\n  static char kDefaultPerms[5] = \"r-xp\";\n  BOOL ok;\n  if (module_.dwSize == 0) {  // only possible before first call\n    module_.dwSize = sizeof(module_);\n    ok = Module32First(snapshot_, &module_);\n  } else {\n    ok = Module32Next(snapshot_, &module_);\n  }\n  if (ok) {\n    uint64 base_addr = reinterpret_cast<DWORD_PTR>(module_.modBaseAddr);\n    if (start) *start = base_addr;\n    if (end) *end = base_addr + module_.modBaseSize;\n    if (flags) *flags = kDefaultPerms;\n    if (offset) *offset = 0;\n    if (inode) *inode = 0;\n    if (filename) *filename = module_.szExePath;\n    if (file_mapping) *file_mapping = 0;\n    if (file_pages) *file_pages = 0;\n    if (anon_mapping) *anon_mapping = 0;\n    if (anon_pages) *anon_pages = 0;\n    if (dev) *dev = 0;\n    return true;\n  }\n#endif\n\n  // We didn't find anything\n  return false;\n}\n\nint ProcMapsIterator::FormatLine(char* buffer, int bufsize,\n                                 uint64 start, uint64 end, const char *flags,\n                                 uint64 offset, int64 inode,\n                                 const char *filename, dev_t dev) {\n  // We assume 'flags' looks like 'rwxp' or 'rwx'.\n  char r = (flags && flags[0] == 'r') ? 'r' : '-';\n  char w = (flags && flags[0] && flags[1] == 'w') ? 'w' : '-';\n  char x = (flags && flags[0] && flags[1] && flags[2] == 'x') ? 'x' : '-';\n  // p always seems set on linux, so we set the default to 'p', not '-'\n  char p = (flags && flags[0] && flags[1] && flags[2] && flags[3] != 'p')\n      ? '-' : 'p';\n\n  const int rc = snprintf(buffer, bufsize,\n                          \"%08\"PRIx64\"-%08\"PRIx64\" %c%c%c%c %08\"PRIx64\" %02x:%02x %-11\"PRId64\" %s\\n\",\n                          start, end, r,w,x,p, offset,\n                          static_cast<int>(dev/256), static_cast<int>(dev%256),\n                          inode, filename);\n  return (rc < 0 || rc >= bufsize) ? 0 : rc;\n}\n\nnamespace tcmalloc {\n\n// Helper to add the list of mapped shared libraries to a profile.\n// Fill formatted \"/proc/self/maps\" contents into buffer 'buf' of size 'size'\n// and return the actual size occupied in 'buf'.  We fill wrote_all to true\n// if we successfully wrote all proc lines to buf, false else.\n// We do not provision for 0-terminating 'buf'.\nint FillProcSelfMaps(char buf[], int size, bool* wrote_all) {\n  ProcMapsIterator::Buffer iterbuf;\n  ProcMapsIterator it(0, &iterbuf);   // 0 means \"current pid\"\n\n  uint64 start, end, offset;\n  int64 inode;\n  char *flags, *filename;\n  int bytes_written = 0;\n  *wrote_all = true;\n  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {\n    const int line_length = it.FormatLine(buf + bytes_written,\n                                          size - bytes_written,\n                                          start, end, flags, offset,\n                                          inode, filename, 0);\n    if (line_length == 0)\n      *wrote_all = false;     // failed to write this line out\n    else\n      bytes_written += line_length;\n\n  }\n  return bytes_written;\n}\n\n// Dump the same data as FillProcSelfMaps reads to fd.\n// It seems easier to repeat parts of FillProcSelfMaps here than to\n// reuse it via a call.\nvoid DumpProcSelfMaps(RawFD fd) {\n  ProcMapsIterator::Buffer iterbuf;\n  ProcMapsIterator it(0, &iterbuf);   // 0 means \"current pid\"\n\n  uint64 start, end, offset;\n  int64 inode;\n  char *flags, *filename;\n  ProcMapsIterator::Buffer linebuf;\n  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {\n    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),\n                                start, end, flags, offset, inode, filename,\n                                0);\n    RawWrite(fd, linebuf.buf_, written);\n  }\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/sysinfo.h",
    "content": "// Copyright (c) 2006, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// All functions here are thread-hostile due to file caching unless\n// commented otherwise.\n\n#ifndef _SYSINFO_H_\n#define _SYSINFO_H_\n\n#include <config.h>\n\n#include <time.h>\n#if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))\n#include <windows.h>   // for DWORD\n#include <TlHelp32.h>  // for CreateToolhelp32Snapshot\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>    // for pid_t\n#endif\n#include <stddef.h>    // for size_t\n#include <limits.h>    // for PATH_MAX\n#include \"base/basictypes.h\"\n#include \"base/logging.h\"   // for RawFD\n\n// This getenv function is safe to call before the C runtime is initialized.\n// On Windows, it utilizes GetEnvironmentVariable() and on unix it uses\n// /proc/self/environ instead calling getenv().  It's intended to be used in\n// routines that run before main(), when the state required for getenv() may\n// not be set up yet.  In particular, errno isn't set up until relatively late\n// (after the pthreads library has a chance to make it threadsafe), and\n// getenv() doesn't work until then. \n// On some platforms, this call will utilize the same, static buffer for\n// repeated GetenvBeforeMain() calls. Callers should not expect pointers from\n// this routine to be long lived.\n// Note that on unix, /proc only has the environment at the time the\n// application was started, so this routine ignores setenv() calls/etc.  Also\n// note it only reads the first 16K of the environment.\nextern const char* GetenvBeforeMain(const char* name);\n\n// This takes as an argument an environment-variable name (like\n// CPUPROFILE) whose value is supposed to be a file-path, and sets\n// path to that path, and returns true.  Non-trivial for surprising\n// reasons, as documented in sysinfo.cc.  path must have space PATH_MAX.\nextern bool GetUniquePathFromEnv(const char* env_name, char* path);\n\nextern int NumCPUs();\n\n// processor cycles per second of each processor.  Thread-safe.\nextern double CyclesPerSecond(void);\n\n\n//  Return true if we're running POSIX (e.g., NPTL on Linux) threads,\n//  as opposed to a non-POSIX thread libary.  The thing that we care\n//  about is whether a thread's pid is the same as the thread that\n//  spawned it.  If so, this function returns true.\n//  Thread-safe.\n//  Note: We consider false negatives to be OK.\nbool HasPosixThreads();\n\n#ifndef SWIG  // SWIG doesn't like struct Buffer and variable arguments.\n\n// A ProcMapsIterator abstracts access to /proc/maps for a given\n// process. Needs to be stack-allocatable and avoid using stdio/malloc\n// so it can be used in the google stack dumper, heap-profiler, etc.\n//\n// On Windows and Mac OS X, this iterator iterates *only* over DLLs\n// mapped into this process space.  For Linux, FreeBSD, and Solaris,\n// it iterates over *all* mapped memory regions, including anonymous\n// mmaps.  For other O/Ss, it is unlikely to work at all, and Valid()\n// will always return false.  Also note: this routine only works on\n// FreeBSD if procfs is mounted: make sure this is in your /etc/fstab:\n//    proc            /proc   procfs  rw 0 0\nclass ProcMapsIterator {\n public:\n  struct Buffer {\n#ifdef __FreeBSD__\n    // FreeBSD requires us to read all of the maps file at once, so\n    // we have to make a buffer that's \"always\" big enough\n    static const size_t kBufSize = 102400;\n#else   // a one-line buffer is good enough\n    static const size_t kBufSize = PATH_MAX + 1024;\n#endif\n    char buf_[kBufSize];\n  };\n\n\n  // Create a new iterator for the specified pid.  pid can be 0 for \"self\".\n  explicit ProcMapsIterator(pid_t pid);\n\n  // Create an iterator with specified storage (for use in signal\n  // handler). \"buffer\" should point to a ProcMapsIterator::Buffer\n  // buffer can be NULL in which case a bufer will be allocated.\n  ProcMapsIterator(pid_t pid, Buffer *buffer);\n\n  // Iterate through maps_backing instead of maps if use_maps_backing\n  // is true.  Otherwise the same as above.  buffer can be NULL and\n  // it will allocate a buffer itself.\n  ProcMapsIterator(pid_t pid, Buffer *buffer,\n                   bool use_maps_backing);\n\n  // Returns true if the iterator successfully initialized;\n  bool Valid() const;\n\n  // Returns a pointer to the most recently parsed line. Only valid\n  // after Next() returns true, and until the iterator is destroyed or\n  // Next() is called again.  This may give strange results on non-Linux\n  // systems.  Prefer FormatLine() if that may be a concern.\n  const char *CurrentLine() const { return stext_; }\n\n  // Writes the \"canonical\" form of the /proc/xxx/maps info for a single\n  // line to the passed-in buffer. Returns the number of bytes written,\n  // or 0 if it was not able to write the complete line.  (To guarantee\n  // success, buffer should have size at least Buffer::kBufSize.)\n  // Takes as arguments values set via a call to Next().  The\n  // \"canonical\" form of the line (taken from linux's /proc/xxx/maps):\n  //    <start_addr(hex)>-<end_addr(hex)> <perms(rwxp)> <offset(hex)>   +\n  //    <major_dev(hex)>:<minor_dev(hex)> <inode> <filename> Note: the\n  // eg\n  //    08048000-0804c000 r-xp 00000000 03:01 3793678    /bin/cat\n  // If you don't have the dev_t (dev), feel free to pass in 0.\n  // (Next() doesn't return a dev_t, though NextExt does.)\n  //\n  // Note: if filename and flags were obtained via a call to Next(),\n  // then the output of this function is only valid if Next() returned\n  // true, and only until the iterator is destroyed or Next() is\n  // called again.  (Since filename, at least, points into CurrentLine.)\n  static int FormatLine(char* buffer, int bufsize,\n                        uint64 start, uint64 end, const char *flags,\n                        uint64 offset, int64 inode, const char *filename,\n                        dev_t dev);\n\n  // Find the next entry in /proc/maps; return true if found or false\n  // if at the end of the file.\n  //\n  // Any of the result pointers can be NULL if you're not interested\n  // in those values.\n  //\n  // If \"flags\" and \"filename\" are passed, they end up pointing to\n  // storage within the ProcMapsIterator that is valid only until the\n  // iterator is destroyed or Next() is called again. The caller may\n  // modify the contents of these strings (up as far as the first NUL,\n  // and only until the subsequent call to Next()) if desired.\n\n  // The offsets are all uint64 in order to handle the case of a\n  // 32-bit process running on a 64-bit kernel\n  //\n  // IMPORTANT NOTE: see top-of-class notes for details about what\n  // mapped regions Next() iterates over, depending on O/S.\n  // TODO(csilvers): make flags and filename const.\n  bool Next(uint64 *start, uint64 *end, char **flags,\n            uint64 *offset, int64 *inode, char **filename);\n\n  bool NextExt(uint64 *start, uint64 *end, char **flags,\n               uint64 *offset, int64 *inode, char **filename,\n               uint64 *file_mapping, uint64 *file_pages,\n               uint64 *anon_mapping, uint64 *anon_pages,\n               dev_t *dev);\n\n  ~ProcMapsIterator();\n\n private:\n  void Init(pid_t pid, Buffer *buffer, bool use_maps_backing);\n\n  char *ibuf_;        // input buffer\n  char *stext_;       // start of text\n  char *etext_;       // end of text\n  char *nextline_;    // start of next line\n  char *ebuf_;        // end of buffer (1 char for a nul)\n#if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))\n  HANDLE snapshot_;   // filehandle on dll info\n  // In a change from the usual W-A pattern, there is no A variant of\n  // MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.\n  // We want the original A variants, and this #undef is the only\n  // way I see to get them.  Redefining it when we're done prevents us\n  // from affecting other .cc files.\n# ifdef MODULEENTRY32  // Alias of W\n#   undef MODULEENTRY32\n  MODULEENTRY32 module_;   // info about current dll (and dll iterator)\n#   define MODULEENTRY32 MODULEENTRY32W\n# else  // It's the ascii, the one we want.\n  MODULEENTRY32 module_;   // info about current dll (and dll iterator)\n# endif\n#elif defined(__MACH__)\n  int current_image_; // dll's are called \"images\" in macos parlance\n  int current_load_cmd_;   // the segment of this dll we're examining\n#elif defined(__sun__)     // Solaris\n  int fd_;\n  char current_filename_[PATH_MAX];\n#else\n  int fd_;            // filehandle on /proc/*/maps\n#endif\n  pid_t pid_;\n  char flags_[10];\n  Buffer* dynamic_buffer_;  // dynamically-allocated Buffer\n  bool using_maps_backing_; // true if we are looking at maps_backing instead of maps.\n};\n\n#endif  /* #ifndef SWIG */\n\n// Helper routines\n\nnamespace tcmalloc {\nint FillProcSelfMaps(char buf[], int size, bool* wrote_all);\nvoid DumpProcSelfMaps(RawFD fd);\n}\n\n#endif   /* #ifndef _SYSINFO_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/thread_annotations.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Le-Chun Wu\n//\n// This header file contains the macro definitions for thread safety\n// annotations that allow the developers to document the locking policies\n// of their multi-threaded code. The annotations can also help program\n// analysis tools to identify potential thread safety issues.\n//\n// The annotations are implemented using GCC's \"attributes\" extension.\n// Using the macros defined here instead of the raw GCC attributes allows\n// for portability and future compatibility.\n//\n// This functionality is not yet fully implemented in perftools,\n// but may be one day.\n\n#ifndef BASE_THREAD_ANNOTATIONS_H_\n#define BASE_THREAD_ANNOTATIONS_H_\n\n\n#if defined(__GNUC__) \\\n  && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \\\n  && defined(__SUPPORT_TS_ANNOTATION__) && (!defined(SWIG))\n#define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))\n#else\n#define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op\n#endif\n\n\n// Document if a shared variable/field needs to be protected by a lock.\n// GUARDED_BY allows the user to specify a particular lock that should be\n// held when accessing the annotated variable, while GUARDED_VAR only\n// indicates a shared variable should be guarded (by any lock). GUARDED_VAR\n// is primarily used when the client cannot express the name of the lock.\n#define GUARDED_BY(x)          THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))\n#define GUARDED_VAR            THREAD_ANNOTATION_ATTRIBUTE__(guarded)\n\n// Document if the memory location pointed to by a pointer should be guarded\n// by a lock when dereferencing the pointer. Similar to GUARDED_VAR,\n// PT_GUARDED_VAR is primarily used when the client cannot express the name\n// of the lock. Note that a pointer variable to a shared memory location\n// could itself be a shared variable. For example, if a shared global pointer\n// q, which is guarded by mu1, points to a shared memory location that is\n// guarded by mu2, q should be annotated as follows:\n//     int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);\n#define PT_GUARDED_BY(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))\n#define PT_GUARDED_VAR \\\n  THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded)\n\n// Document the acquisition order between locks that can be held\n// simultaneously by a thread. For any two locks that need to be annotated\n// to establish an acquisition order, only one of them needs the annotation.\n// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER\n// and ACQUIRED_BEFORE.)\n#define ACQUIRED_AFTER(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))\n#define ACQUIRED_BEFORE(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))\n\n// The following three annotations document the lock requirements for\n// functions/methods.\n\n// Document if a function expects certain locks to be held before it is called\n#define EXCLUSIVE_LOCKS_REQUIRED(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))\n\n#define SHARED_LOCKS_REQUIRED(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(x))\n\n// Document the locks acquired in the body of the function. These locks\n// cannot be held when calling this function (as google3's Mutex locks are\n// non-reentrant).\n#define LOCKS_EXCLUDED(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))\n\n// Document the lock the annotated function returns without acquiring it.\n#define LOCK_RETURNED(x)       THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))\n\n// Document if a class/type is a lockable type (such as the Mutex class).\n#define LOCKABLE               THREAD_ANNOTATION_ATTRIBUTE__(lockable)\n\n// Document if a class is a scoped lockable type (such as the MutexLock class).\n#define SCOPED_LOCKABLE        THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)\n\n// The following annotations specify lock and unlock primitives.\n#define EXCLUSIVE_LOCK_FUNCTION(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(x))\n\n#define SHARED_LOCK_FUNCTION(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(shared_lock(x))\n\n#define EXCLUSIVE_TRYLOCK_FUNCTION(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(x))\n\n#define SHARED_TRYLOCK_FUNCTION(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock(x))\n\n#define UNLOCK_FUNCTION(x) \\\n  THREAD_ANNOTATION_ATTRIBUTE__(unlock(x))\n\n// An escape hatch for thread safety analysis to ignore the annotated function.\n#define NO_THREAD_SAFETY_ANALYSIS \\\n  THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)\n\n#endif  // BASE_THREAD_ANNOTATIONS_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/thread_lister.c",
    "content": "/* Copyright (c) 2005-2007, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Markus Gutschke\n */\n\n#include \"config.h\"\n#include <stdio.h>         /* needed for NULL on some powerpc platforms (?!) */\n#ifdef HAVE_SYS_PRCTL\n# include <sys/prctl.h>\n#endif\n#include \"base/thread_lister.h\"\n#include \"base/linuxthreads.h\"\n/* Include other thread listers here that define THREADS macro\n * only when they can provide a good implementation.\n */\n\n#ifndef THREADS\n\n/* Default trivial thread lister for single-threaded applications,\n * or if the multi-threading code has not been ported, yet.\n */\n\nint ListAllProcessThreads(void *parameter,\n                          ListAllProcessThreadsCallBack callback, ...) {\n  int rc;\n  va_list ap;\n  pid_t pid;\n\n#ifdef HAVE_SYS_PRCTL\n  int dumpable = prctl(PR_GET_DUMPABLE, 0);\n  if (!dumpable)\n    prctl(PR_SET_DUMPABLE, 1);\n#endif\n  va_start(ap, callback);\n  pid = getpid();\n  rc = callback(parameter, 1, &pid, ap);\n  va_end(ap);\n#ifdef HAVE_SYS_PRCTL\n  if (!dumpable)\n    prctl(PR_SET_DUMPABLE, 0);\n#endif\n  return rc;\n}\n\nint ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {\n  return 1;\n}\n\n#endif   /* ifndef THREADS */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/thread_lister.h",
    "content": "/* Copyright (c) 2005-2007, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Markus Gutschke\n */\n\n#ifndef _THREAD_LISTER_H\n#define _THREAD_LISTER_H\n\n#include <stdarg.h>\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef int (*ListAllProcessThreadsCallBack)(void *parameter,\n                                             int num_threads,\n                                             pid_t *thread_pids,\n                                             va_list ap);\n\n/* This function gets the list of all linux threads of the current process\n * passes them to the 'callback' along with the 'parameter' pointer; at the\n * call back call time all the threads are paused via\n * PTRACE_ATTACH.\n * The callback is executed from a separate thread which shares only the\n * address space, the filesystem, and the filehandles with the caller. Most\n * notably, it does not share the same pid and ppid; and if it terminates,\n * the rest of the application is still there. 'callback' is supposed to do\n * or arrange for ResumeAllProcessThreads. This happens automatically, if\n * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous\n * signals are blocked. If the 'callback' decides to unblock them, it must\n * ensure that they cannot terminate the application, or that\n * ResumeAllProcessThreads will get called.\n * It is an error for the 'callback' to make any library calls that could\n * acquire locks. Most notably, this means that most system calls have to\n * avoid going through libc. Also, this means that it is not legal to call\n * exit() or abort().\n * We return -1 on error and the return value of 'callback' on success.\n */\nint ListAllProcessThreads(void *parameter,\n                          ListAllProcessThreadsCallBack callback, ...);\n\n/* This function resumes the list of all linux threads that\n * ListAllProcessThreads pauses before giving to its callback.\n * The function returns non-zero if at least one thread was\n * suspended and has now been resumed.\n */\nint ResumeAllProcessThreads(int num_threads, pid_t *thread_pids);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* _THREAD_LISTER_H */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/vdso_support.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Paul Pluzhnikov\n//\n// Allow dynamic symbol lookup in the kernel VDSO page.\n//\n// VDSOSupport -- a class representing kernel VDSO (if present).\n//\n\n#include \"base/vdso_support.h\"\n\n#ifdef HAVE_VDSO_SUPPORT     // defined in vdso_support.h\n\n#include <fcntl.h>\n#include <stddef.h>   // for ptrdiff_t\n\n#include \"base/atomicops.h\"  // for MemoryBarrier\n#include \"base/linux_syscall_support.h\"\n#include \"base/logging.h\"\n#include \"base/dynamic_annotations.h\"\n#include \"base/basictypes.h\"  // for COMPILE_ASSERT\n\nusing base::subtle::MemoryBarrier;\n\n#ifndef AT_SYSINFO_EHDR\n#define AT_SYSINFO_EHDR 33\n#endif\n\n// From binutils/include/elf/common.h (this doesn't appear to be documented\n// anywhere else).\n//\n//   /* This flag appears in a Versym structure.  It means that the symbol\n//      is hidden, and is only visible with an explicit version number.\n//      This is a GNU extension.  */\n//   #define VERSYM_HIDDEN           0x8000\n//\n//   /* This is the mask for the rest of the Versym information.  */\n//   #define VERSYM_VERSION          0x7fff\n\n#define VERSYM_VERSION 0x7fff\n\nnamespace base {\n\nnamespace {\ntemplate <int N> class ElfClass {\n public:\n  static const int kElfClass = -1;\n  static int ElfBind(const ElfW(Sym) *) {\n    CHECK(false); // << \"Unexpected word size\";\n    return 0;\n  }\n  static int ElfType(const ElfW(Sym) *) {\n    CHECK(false); // << \"Unexpected word size\";\n    return 0;\n  }\n};\n\ntemplate <> class ElfClass<32> {\n public:\n  static const int kElfClass = ELFCLASS32;\n  static int ElfBind(const ElfW(Sym) *symbol) {\n    return ELF32_ST_BIND(symbol->st_info);\n  }\n  static int ElfType(const ElfW(Sym) *symbol) {\n    return ELF32_ST_TYPE(symbol->st_info);\n  }\n};\n\ntemplate <> class ElfClass<64> {\n public:\n  static const int kElfClass = ELFCLASS64;\n  static int ElfBind(const ElfW(Sym) *symbol) {\n    return ELF64_ST_BIND(symbol->st_info);\n  }\n  static int ElfType(const ElfW(Sym) *symbol) {\n    return ELF64_ST_TYPE(symbol->st_info);\n  }\n};\n\ntypedef ElfClass<__WORDSIZE> CurrentElfClass;\n\n// Extract an element from one of the ELF tables, cast it to desired type.\n// This is just a simple arithmetic and a glorified cast.\n// Callers are responsible for bounds checking.\ntemplate <class T>\nconst T* GetTableElement(const ElfW(Ehdr) *ehdr,\n                         ElfW(Off) table_offset,\n                         ElfW(Word) element_size,\n                         size_t index) {\n  return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr)\n                                    + table_offset\n                                    + index * element_size);\n}\n}  // namespace\n\nconst void *const VDSOSupport::kInvalidBase =\n    reinterpret_cast<const void *>(~0L);\n\nconst void *VDSOSupport::vdso_base_ = kInvalidBase;\nVDSOSupport::GetCpuFn VDSOSupport::getcpu_fn_ = &InitAndGetCPU;\n\nVDSOSupport::ElfMemImage::ElfMemImage(const void *base) {\n  CHECK(base != kInvalidBase);\n  Init(base);\n}\n\nint VDSOSupport::ElfMemImage::GetNumSymbols() const {\n  if (!hash_) {\n    return 0;\n  }\n  // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash\n  return hash_[1];\n}\n\nconst ElfW(Sym) *VDSOSupport::ElfMemImage::GetDynsym(int index) const {\n  CHECK_LT(index, GetNumSymbols());\n  return dynsym_ + index;\n}\n\nconst ElfW(Versym) *VDSOSupport::ElfMemImage::GetVersym(int index) const {\n  CHECK_LT(index, GetNumSymbols());\n  return versym_ + index;\n}\n\nconst ElfW(Phdr) *VDSOSupport::ElfMemImage::GetPhdr(int index) const {\n  CHECK_LT(index, ehdr_->e_phnum);\n  return GetTableElement<ElfW(Phdr)>(ehdr_,\n                                     ehdr_->e_phoff,\n                                     ehdr_->e_phentsize,\n                                     index);\n}\n\nconst char *VDSOSupport::ElfMemImage::GetDynstr(ElfW(Word) offset) const {\n  CHECK_LT(offset, strsize_);\n  return dynstr_ + offset;\n}\n\nconst void *VDSOSupport::ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {\n  if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) {\n    // Symbol corresponds to \"special\" (e.g. SHN_ABS) section.\n    return reinterpret_cast<const void *>(sym->st_value);\n  }\n  CHECK_LT(link_base_, sym->st_value);\n  return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_;\n}\n\nconst ElfW(Verdef) *VDSOSupport::ElfMemImage::GetVerdef(int index) const {\n  CHECK_LE(index, verdefnum_);\n  const ElfW(Verdef) *version_definition = verdef_;\n  while (version_definition->vd_ndx < index && version_definition->vd_next) {\n    const char *const version_definition_as_char =\n        reinterpret_cast<const char *>(version_definition);\n    version_definition =\n        reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char +\n                                               version_definition->vd_next);\n  }\n  return version_definition->vd_ndx == index ? version_definition : NULL;\n}\n\nconst ElfW(Verdaux) *VDSOSupport::ElfMemImage::GetVerdefAux(\n    const ElfW(Verdef) *verdef) const {\n  return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1);\n}\n\nconst char *VDSOSupport::ElfMemImage::GetVerstr(ElfW(Word) offset) const {\n  CHECK_LT(offset, strsize_);\n  return dynstr_ + offset;\n}\n\nvoid VDSOSupport::ElfMemImage::Init(const void *base) {\n  ehdr_      = NULL;\n  dynsym_    = NULL;\n  dynstr_    = NULL;\n  versym_    = NULL;\n  verdef_    = NULL;\n  hash_      = NULL;\n  strsize_   = 0;\n  verdefnum_ = 0;\n  link_base_ = ~0L;  // Sentinel: PT_LOAD .p_vaddr can't possibly be this.\n  if (!base) {\n    return;\n  }\n  const intptr_t base_as_uintptr_t = reinterpret_cast<uintptr_t>(base);\n  // Fake VDSO has low bit set.\n  const bool fake_vdso = ((base_as_uintptr_t & 1) != 0);\n  base = reinterpret_cast<const void *>(base_as_uintptr_t & ~1);\n  const char *const base_as_char = reinterpret_cast<const char *>(base);\n  if (base_as_char[EI_MAG0] != ELFMAG0 || base_as_char[EI_MAG1] != ELFMAG1 ||\n      base_as_char[EI_MAG2] != ELFMAG2 || base_as_char[EI_MAG3] != ELFMAG3) {\n    RAW_DCHECK(false, \"no ELF magic\"); // at %p\", base);\n    return;\n  }\n  int elf_class = base_as_char[EI_CLASS];\n  if (elf_class != CurrentElfClass::kElfClass) {\n    DCHECK_EQ(elf_class, CurrentElfClass::kElfClass);\n    return;\n  }\n  switch (base_as_char[EI_DATA]) {\n    case ELFDATA2LSB: {\n      if (__LITTLE_ENDIAN != __BYTE_ORDER) {\n        DCHECK_EQ(__LITTLE_ENDIAN, __BYTE_ORDER); // << \": wrong byte order\";\n        return;\n      }\n      break;\n    }\n    case ELFDATA2MSB: {\n      if (__BIG_ENDIAN != __BYTE_ORDER) {\n        DCHECK_EQ(__BIG_ENDIAN, __BYTE_ORDER); // << \": wrong byte order\";\n        return;\n      }\n      break;\n    }\n    default: {\n      RAW_DCHECK(false, \"unexpected data encoding\"); // << base_as_char[EI_DATA];\n      return;\n    }\n  }\n\n  ehdr_ = reinterpret_cast<const ElfW(Ehdr) *>(base);\n  const ElfW(Phdr) *dynamic_program_header = NULL;\n  for (int i = 0; i < ehdr_->e_phnum; ++i) {\n    const ElfW(Phdr) *const program_header = GetPhdr(i);\n    switch (program_header->p_type) {\n      case PT_LOAD:\n        if (link_base_ == ~0L) {\n          link_base_ = program_header->p_vaddr;\n        }\n        break;\n      case PT_DYNAMIC:\n        dynamic_program_header = program_header;\n        break;\n    }\n  }\n  if (link_base_ == ~0L || !dynamic_program_header) {\n    RAW_DCHECK(~0L != link_base_, \"no PT_LOADs in VDSO\");\n    RAW_DCHECK(dynamic_program_header, \"no PT_DYNAMIC in VDSO\");\n    // Mark this image as not present. Can not recur infinitely.\n    Init(0);\n    return;\n  }\n  ptrdiff_t relocation =\n      base_as_char - reinterpret_cast<const char *>(link_base_);\n  ElfW(Dyn) *dynamic_entry =\n      reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr +\n                                    relocation);\n  for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) {\n    ElfW(Xword) value = dynamic_entry->d_un.d_val;\n    if (fake_vdso) {\n      // A complication: in the real VDSO, dynamic entries are not relocated\n      // (it wasn't loaded by a dynamic loader). But when testing with a\n      // \"fake\" dlopen()ed vdso library, the loader relocates some (but\n      // not all!) of them before we get here.\n      if (dynamic_entry->d_tag == DT_VERDEF) {\n        // The only dynamic entry (of the ones we care about) libc-2.3.6\n        // loader doesn't relocate.\n        value += relocation;\n      }\n    } else {\n      // Real VDSO. Everything needs to be relocated.\n      value += relocation;\n    }\n    switch (dynamic_entry->d_tag) {\n      case DT_HASH:\n        hash_ = reinterpret_cast<ElfW(Word) *>(value);\n        break;\n      case DT_SYMTAB:\n        dynsym_ = reinterpret_cast<ElfW(Sym) *>(value);\n        break;\n      case DT_STRTAB:\n        dynstr_ = reinterpret_cast<const char *>(value);\n        break;\n      case DT_VERSYM:\n        versym_ = reinterpret_cast<ElfW(Versym) *>(value);\n        break;\n      case DT_VERDEF:\n        verdef_ = reinterpret_cast<ElfW(Verdef) *>(value);\n        break;\n      case DT_VERDEFNUM:\n        verdefnum_ = dynamic_entry->d_un.d_val;\n        break;\n      case DT_STRSZ:\n        strsize_ = dynamic_entry->d_un.d_val;\n        break;\n      default:\n        // Unrecognized entries explicitly ignored.\n        break;\n    }\n  }\n  if (!hash_ || !dynsym_ || !dynstr_ || !versym_ ||\n      !verdef_ || !verdefnum_ || !strsize_) {\n    RAW_DCHECK(hash_, \"invalid VDSO (no DT_HASH)\");\n    RAW_DCHECK(dynsym_, \"invalid VDSO (no DT_SYMTAB)\");\n    RAW_DCHECK(dynstr_, \"invalid VDSO (no DT_STRTAB)\");\n    RAW_DCHECK(versym_, \"invalid VDSO (no DT_VERSYM)\");\n    RAW_DCHECK(verdef_, \"invalid VDSO (no DT_VERDEF)\");\n    RAW_DCHECK(verdefnum_, \"invalid VDSO (no DT_VERDEFNUM)\");\n    RAW_DCHECK(strsize_, \"invalid VDSO (no DT_STRSZ)\");\n    // Mark this image as not present. Can not recur infinitely.\n    Init(0);\n    return;\n  }\n}\n\nVDSOSupport::VDSOSupport()\n    // If vdso_base_ is still set to kInvalidBase, we got here\n    // before VDSOSupport::Init has been called. Call it now.\n    : image_(vdso_base_ == kInvalidBase ? Init() : vdso_base_) {\n}\n\n// NOTE: we can't use GoogleOnceInit() below, because we can be\n// called by tcmalloc, and none of the *once* stuff may be functional yet.\n//\n// In addition, we hope that the VDSOSupportHelper constructor\n// causes this code to run before there are any threads, and before\n// InitGoogle() has executed any chroot or setuid calls.\n//\n// Finally, even if there is a race here, it is harmless, because\n// the operation should be idempotent.\nconst void *VDSOSupport::Init() {\n  if (vdso_base_ == kInvalidBase) {\n    // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]\n    // on stack, and so glibc works as if VDSO was not present.\n    // But going directly to kernel via /proc/self/auxv below bypasses\n    // Valgrind zapping. So we check for Valgrind separately.\n    if (RunningOnValgrind()) {\n      vdso_base_ = NULL;\n      getcpu_fn_ = &GetCPUViaSyscall;\n      return NULL;\n    }\n    int fd = open(\"/proc/self/auxv\", O_RDONLY);\n    if (fd == -1) {\n      // Kernel too old to have a VDSO.\n      vdso_base_ = NULL;\n      getcpu_fn_ = &GetCPUViaSyscall;\n      return NULL;\n    }\n    ElfW(auxv_t) aux;\n    while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {\n      if (aux.a_type == AT_SYSINFO_EHDR) {\n        COMPILE_ASSERT(sizeof(vdso_base_) == sizeof(aux.a_un.a_val),\n                       unexpected_sizeof_pointer_NE_sizeof_a_val);\n        vdso_base_ = reinterpret_cast<void *>(aux.a_un.a_val);\n        break;\n      }\n    }\n    close(fd);\n    if (vdso_base_ == kInvalidBase) {\n      // Didn't find AT_SYSINFO_EHDR in auxv[].\n      vdso_base_ = NULL;\n    }\n  }\n  GetCpuFn fn = &GetCPUViaSyscall;  // default if VDSO not present.\n  if (vdso_base_) {\n    VDSOSupport vdso;\n    SymbolInfo info;\n    if (vdso.LookupSymbol(\"__vdso_getcpu\", \"LINUX_2.6\", STT_FUNC, &info)) {\n      // Casting from an int to a pointer is not legal C++.  To emphasize\n      // this, we use a C-style cast rather than a C++-style cast.\n      fn = (GetCpuFn)(info.address);\n    }\n  }\n  // Subtle: this code runs outside of any locks; prevent compiler\n  // from assigning to getcpu_fn_ more than once.\n  base::subtle::MemoryBarrier();\n  getcpu_fn_ = fn;\n  return vdso_base_;\n}\n\nconst void *VDSOSupport::SetBase(const void *base) {\n  const void *old_base = vdso_base_;\n  vdso_base_ = base;\n  image_.Init(base);\n  // Also reset getcpu_fn_, so GetCPU could be tested with simulated VDSO.\n  getcpu_fn_ = &InitAndGetCPU;\n  return old_base;\n}\n\nbool VDSOSupport::LookupSymbol(const char *name,\n                               const char *version,\n                               int type,\n                               SymbolInfo *info) const {\n  for (SymbolIterator it = begin(); it != end(); ++it) {\n    if (strcmp(it->name, name) == 0 && strcmp(it->version, version) == 0 &&\n        CurrentElfClass::ElfType(it->symbol) == type) {\n      if (info) {\n        *info = *it;\n      }\n      return true;\n    }\n  }\n  return false;\n}\n\nbool VDSOSupport::LookupSymbolByAddress(const void *address,\n                                        SymbolInfo *info_out) const {\n  for (SymbolIterator it = begin(); it != end(); ++it) {\n    const char *const symbol_start =\n        reinterpret_cast<const char *>(it->address);\n    const char *const symbol_end = symbol_start + it->symbol->st_size;\n    if (symbol_start <= address && address < symbol_end) {\n      if (info_out) {\n        // Client wants to know details for that symbol (the usual case).\n        if (CurrentElfClass::ElfBind(it->symbol) == STB_GLOBAL) {\n          // Strong symbol; just return it.\n          *info_out = *it;\n          return true;\n        } else {\n          // Weak or local. Record it, but keep looking for a strong one.\n          *info_out = *it;\n        }\n      } else {\n        // Client only cares if there is an overlapping symbol.\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\nVDSOSupport::SymbolIterator::SymbolIterator(const void *const image, int index)\n    : index_(index), image_(image) {\n}\n\nconst VDSOSupport::SymbolInfo *VDSOSupport::SymbolIterator::operator->() const {\n  return &info_;\n}\n\nconst VDSOSupport::SymbolInfo& VDSOSupport::SymbolIterator::operator*() const {\n  return info_;\n}\n\nbool VDSOSupport::SymbolIterator::operator==(const SymbolIterator &rhs) const {\n  return this->image_ == rhs.image_ && this->index_ == rhs.index_;\n}\n\nbool VDSOSupport::SymbolIterator::operator!=(const SymbolIterator &rhs) const {\n  return !(*this == rhs);\n}\n\nVDSOSupport::SymbolIterator &VDSOSupport::SymbolIterator::operator++() {\n  this->Update(1);\n  return *this;\n}\n\nVDSOSupport::SymbolIterator VDSOSupport::begin() const {\n  SymbolIterator it(&image_, 0);\n  it.Update(0);\n  return it;\n}\n\nVDSOSupport::SymbolIterator VDSOSupport::end() const {\n  return SymbolIterator(&image_, image_.GetNumSymbols());\n}\n\nvoid VDSOSupport::SymbolIterator::Update(int increment) {\n  const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_);\n  CHECK(image->IsPresent() || increment == 0);\n  if (!image->IsPresent()) {\n    return;\n  }\n  index_ += increment;\n  if (index_ >= image->GetNumSymbols()) {\n    index_ = image->GetNumSymbols();\n    return;\n  }\n  const ElfW(Sym)    *symbol = image->GetDynsym(index_);\n  const ElfW(Versym) *version_symbol = image->GetVersym(index_);\n  CHECK(symbol && version_symbol);\n  const char *const symbol_name = image->GetDynstr(symbol->st_name);\n  const ElfW(Versym) version_index = version_symbol[0] & VERSYM_VERSION;\n  const ElfW(Verdef) *version_definition = NULL;\n  const char *version_name = \"\";\n  if (symbol->st_shndx == SHN_UNDEF) {\n    // Undefined symbols reference DT_VERNEED, not DT_VERDEF, and\n    // version_index could well be greater than verdefnum_, so calling\n    // GetVerdef(version_index) may trigger assertion.\n  } else {\n    version_definition = image->GetVerdef(version_index);\n  }\n  if (version_definition) {\n    // I am expecting 1 or 2 auxiliary entries: 1 for the version itself,\n    // optional 2nd if the version has a parent.\n    CHECK_LE(1, version_definition->vd_cnt);\n    CHECK_LE(version_definition->vd_cnt, 2);\n    const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition);\n    version_name = image->GetVerstr(version_aux->vda_name);\n  }\n  info_.name    = symbol_name;\n  info_.version = version_name;\n  info_.address = image->GetSymAddr(symbol);\n  info_.symbol  = symbol;\n}\n\n// NOLINT on 'long' because this routine mimics kernel api.\nlong VDSOSupport::GetCPUViaSyscall(unsigned *cpu, void *, void *) { // NOLINT\n#if defined(__NR_getcpu)\n  return sys_getcpu(cpu, NULL, NULL);\n#else\n  // x86_64 never implemented sys_getcpu(), except as a VDSO call.\n  errno = ENOSYS;\n  return -1;\n#endif\n}\n\n// Use fast __vdso_getcpu if available.\nlong VDSOSupport::InitAndGetCPU(unsigned *cpu, void *x, void *y) { // NOLINT\n  Init();\n  CHECK_NE(getcpu_fn_, &InitAndGetCPU); // << \"Init() did not set getcpu_fn_\";\n  return (*getcpu_fn_)(cpu, x, y);\n}\n\n// This function must be very fast, and may be called from very\n// low level (e.g. tcmalloc). Hence I avoid things like\n// GoogleOnceInit() and ::operator new.\nint GetCPU(void) {\n  unsigned cpu;\n  int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu, NULL, NULL);\n  return ret_code == 0 ? cpu : ret_code;\n}\n\n// We need to make sure VDSOSupport::Init() is called before\n// the main() runs, since it might do something like setuid or\n// chroot.  If VDSOSupport\n// is used in any global constructor, this will happen, since\n// VDSOSupport's constructor calls Init.  But if not, we need to\n// ensure it here, with a global constructor of our own.  This\n// is an allowed exception to the normal rule against non-trivial\n// global constructors.\nstatic class VDSOInitHelper {\n public:\n  VDSOInitHelper() { VDSOSupport::Init(); }\n} vdso_init_helper;\n}\n\n#endif  // HAVE_VDSO_SUPPORT\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/base/vdso_support.h",
    "content": "// Copyright 2008 Google Inc. All Rights Reserved.\n// Author: ppluzhnikov@google.com (Paul Pluzhnikov)\n//\n// Allow dynamic symbol lookup in the kernel VDSO page.\n//\n// VDSO stands for \"Virtual Dynamic Shared Object\" -- a page of\n// executable code, which looks like a shared library, but doesn't\n// necessarily exist anywhere on disk, and which gets mmap()ed into\n// every process by kernels which support VDSO, such as 2.6.x for 32-bit\n// executables, and 2.6.24 and above for 64-bit executables.\n//\n// More details could be found here:\n// http://www.trilithium.com/johan/2005/08/linux-gate/\n//\n// VDSOSupport -- a class representing kernel VDSO (if present).\n//\n// Example usage:\n//  VDSOSupport vdso;\n//  VDSOSupport::SymbolInfo info;\n//  typedef (*FN)(unsigned *, void *, void *);\n//  FN fn = NULL;\n//  if (vdso.LookupSymbol(\"__vdso_getcpu\", \"LINUX_2.6\", STT_FUNC, &info)) {\n//     fn = reinterpret_cast<FN>(info.address);\n//  }\n\n#ifndef BASE_VDSO_SUPPORT_H_\n#define BASE_VDSO_SUPPORT_H_\n\n#include <config.h>\n#ifdef HAVE_FEATURES_H\n#include <features.h>   // for __GLIBC__\n#endif\n\n// Maybe one day we can rewrite this file not to require the elf\n// symbol extensions in glibc, but for right now we need them.\n#if defined(__ELF__) && defined(__GLIBC__)\n\n#define HAVE_VDSO_SUPPORT 1\n\n#include <stdlib.h>     // for NULL\n#include <link.h>  // for ElfW\n#include \"base/basictypes.h\"\n\nnamespace base {\n\n// NOTE: this class may be used from within tcmalloc, and can not\n// use any memory allocation routines.\nclass VDSOSupport {\n public:\n  // Sentinel: there could never be a VDSO at this address.\n  static const void *const kInvalidBase;\n\n  // Information about a single vdso symbol.\n  // All pointers are into .dynsym, .dynstr, or .text of the VDSO.\n  // Do not free() them or modify through them.\n  struct SymbolInfo {\n    const char      *name;      // E.g. \"__vdso_getcpu\"\n    const char      *version;   // E.g. \"LINUX_2.6\", could be \"\"\n                                // for unversioned symbol.\n    const void      *address;   // Relocated symbol address.\n    const ElfW(Sym) *symbol;    // Symbol in the dynamic symbol table.\n  };\n\n  // Supports iteration over all dynamic symbols.\n  class SymbolIterator {\n   public:\n    friend class VDSOSupport;\n    const SymbolInfo *operator->() const;\n    const SymbolInfo &operator*() const;\n    SymbolIterator& operator++();\n    bool operator!=(const SymbolIterator &rhs) const;\n    bool operator==(const SymbolIterator &rhs) const;\n   private:\n    SymbolIterator(const void *const image, int index);\n    void Update(int incr);\n    SymbolInfo info_;\n    int index_;\n    const void *const image_;\n  };\n\n  VDSOSupport();\n\n  // Answers whether we have a vdso at all.\n  bool IsPresent() const { return image_.IsPresent(); }\n\n  // Allow to iterate over all VDSO symbols.\n  SymbolIterator begin() const;\n  SymbolIterator end() const;\n\n  // Look up versioned dynamic symbol in the kernel VDSO.\n  // Returns false if VDSO is not present, or doesn't contain given\n  // symbol/version/type combination.\n  // If info_out != NULL, additional details are filled in.\n  bool LookupSymbol(const char *name, const char *version,\n                    int symbol_type, SymbolInfo *info_out) const;\n\n  // Find info about symbol (if any) which overlaps given address.\n  // Returns true if symbol was found; false if VDSO isn't present\n  // or doesn't have a symbol overlapping given address.\n  // If info_out != NULL, additional details are filled in.\n  bool LookupSymbolByAddress(const void *address, SymbolInfo *info_out) const;\n\n  // Used only for testing. Replace real VDSO base with a mock.\n  // Returns previous value of vdso_base_. After you are done testing,\n  // you are expected to call SetBase() with previous value, in order to\n  // reset state to the way it was.\n  const void *SetBase(const void *s);\n\n  // Computes vdso_base_ and returns it. Should be called as early as\n  // possible; before any thread creation, chroot or setuid.\n  static const void *Init();\n\n private:\n  // An in-memory ELF image (may not exist on disk).\n  class ElfMemImage {\n   public:\n    explicit ElfMemImage(const void *base);\n    void                 Init(const void *base);\n    bool                 IsPresent() const { return ehdr_ != NULL; }\n    const ElfW(Phdr)*    GetPhdr(int index) const;\n    const ElfW(Sym)*     GetDynsym(int index) const;\n    const ElfW(Versym)*  GetVersym(int index) const;\n    const ElfW(Verdef)*  GetVerdef(int index) const;\n    const ElfW(Verdaux)* GetVerdefAux(const ElfW(Verdef) *verdef) const;\n    const char*          GetDynstr(ElfW(Word) offset) const;\n    const void*          GetSymAddr(const ElfW(Sym) *sym) const;\n    const char*          GetVerstr(ElfW(Word) offset) const;\n    int                  GetNumSymbols() const;\n   private:\n    const ElfW(Ehdr) *ehdr_;\n    const ElfW(Sym) *dynsym_;\n    const ElfW(Versym) *versym_;\n    const ElfW(Verdef) *verdef_;\n    const ElfW(Word) *hash_;\n    const char *dynstr_;\n    size_t strsize_;\n    size_t verdefnum_;\n    ElfW(Addr) link_base_;     // Link-time base (p_vaddr of first PT_LOAD).\n  };\n\n  // image_ represents VDSO ELF image in memory.\n  // image_.ehdr_ == NULL implies there is no VDSO.\n  ElfMemImage image_;\n\n  // Cached value of auxv AT_SYSINFO_EHDR, computed once.\n  // This is a tri-state:\n  //   kInvalidBase   => value hasn't been determined yet.\n  //              0   => there is no VDSO.\n  //           else   => vma of VDSO Elf{32,64}_Ehdr.\n  //\n  // When testing with mock VDSO, low bit is set.\n  // The low bit is always available because vdso_base_ is\n  // page-aligned.\n  static const void *vdso_base_;\n\n  // NOLINT on 'long' because these routines mimic kernel api.\n  // The 'cache' parameter may be used by some versions of the kernel,\n  // and should be NULL or point to a static buffer containing at\n  // least two 'long's.\n  static long InitAndGetCPU(unsigned *cpu, void *cache,     // NOLINT 'long'.\n                            void *unused);\n  static long GetCPUViaSyscall(unsigned *cpu, void *cache,  // NOLINT 'long'.\n                               void *unused);\n  typedef long (*GetCpuFn)(unsigned *cpu, void *cache,      // NOLINT 'long'.\n                           void *unused);\n\n  // This function pointer may point to InitAndGetCPU,\n  // GetCPUViaSyscall, or __vdso_getcpu at different stages of initialization.\n  static GetCpuFn getcpu_fn_;\n\n  friend int GetCPU(void);  // Needs access to getcpu_fn_.\n\n  DISALLOW_COPY_AND_ASSIGN(VDSOSupport);\n};\n\n// Same as sched_getcpu() on later glibc versions.\n// Return current CPU, using (fast) __vdso_getcpu@LINUX_2.6 if present,\n// otherwise use syscall(SYS_getcpu,...).\n// May return -1 with errno == ENOSYS if the kernel doesn't\n// support SYS_getcpu.\nint GetCPU();\n}  // namespace base\n\n#endif  // __ELF__ and __GLIBC__\n\n#endif  // BASE_VDSO_SUPPORT_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/central_freelist.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#include \"config.h\"\n#include \"central_freelist.h\"\n\n#include \"linked_list.h\"\n#include \"static_vars.h\"\n\nnamespace tcmalloc {\n\nvoid CentralFreeList::Init(size_t cl) {\n  size_class_ = cl;\n  tcmalloc::DLL_Init(&empty_);\n  tcmalloc::DLL_Init(&nonempty_);\n  counter_ = 0;\n\n  cache_size_ = 1;\n  used_slots_ = 0;\n  ASSERT(cache_size_ <= kNumTransferEntries);\n}\n\nvoid CentralFreeList::ReleaseListToSpans(void* start) {\n  while (start) {\n    void *next = SLL_Next(start);\n    ReleaseToSpans(start);\n    start = next;\n  }\n}\n\n// MapObjectToSpan should logically be part of ReleaseToSpans.  But\n// this triggers an optimization bug in gcc 4.5.0.  Moving to a\n// separate function, and making sure that function isn't inlined,\n// seems to fix the problem.  It also should be fixed for gcc 4.5.1.\nstatic\n#if __GNUC__ == 4 && __GNUC_MINOR__ == 5 && __GNUC_PATCHLEVEL__ == 0\n__attribute__ ((noinline))\n#endif\nSpan* MapObjectToSpan(void* object) {\n  const PageID p = reinterpret_cast<uintptr_t>(object) >> kPageShift;\n  Span* span = Static::pageheap()->GetDescriptor(p);\n  return span;\n}\n\nvoid CentralFreeList::ReleaseToSpans(void* object) {\n  Span* span = MapObjectToSpan(object);\n  ASSERT(span != NULL);\n  ASSERT(span->refcount > 0);\n\n  // If span is empty, move it to non-empty list\n  if (span->objects == NULL) {\n    tcmalloc::DLL_Remove(span);\n    tcmalloc::DLL_Prepend(&nonempty_, span);\n    Event(span, 'N', 0);\n  }\n\n  // The following check is expensive, so it is disabled by default\n  if (false) {\n    // Check that object does not occur in list\n    int got = 0;\n    for (void* p = span->objects; p != NULL; p = *((void**) p)) {\n      ASSERT(p != object);\n      got++;\n    }\n    ASSERT(got + span->refcount ==\n           (span->length<<kPageShift) /\n           Static::sizemap()->ByteSizeForClass(span->sizeclass));\n  }\n\n  counter_++;\n  span->refcount--;\n  if (span->refcount == 0) {\n    Event(span, '#', 0);\n    counter_ -= ((span->length<<kPageShift) /\n                 Static::sizemap()->ByteSizeForClass(span->sizeclass));\n    tcmalloc::DLL_Remove(span);\n\n    // Release central list lock while operating on pageheap\n    lock_.Unlock();\n    {\n      SpinLockHolder h(Static::pageheap_lock());\n      Static::pageheap()->Delete(span);\n    }\n    lock_.Lock();\n  } else {\n    *(reinterpret_cast<void**>(object)) = span->objects;\n    span->objects = object;\n  }\n}\n\nbool CentralFreeList::EvictRandomSizeClass(\n    int locked_size_class, bool force) {\n  static int race_counter = 0;\n  int t = race_counter++;  // Updated without a lock, but who cares.\n  if (t >= kNumClasses) {\n    while (t >= kNumClasses) {\n      t -= kNumClasses;\n    }\n    race_counter = t;\n  }\n  ASSERT(t >= 0);\n  ASSERT(t < kNumClasses);\n  if (t == locked_size_class) return false;\n  return Static::central_cache()[t].ShrinkCache(locked_size_class, force);\n}\n\nbool CentralFreeList::MakeCacheSpace() {\n  // Is there room in the cache?\n  if (used_slots_ < cache_size_) return true;\n  // Check if we can expand this cache?\n  if (cache_size_ == kNumTransferEntries) return false;\n  // Ok, we'll try to grab an entry from some other size class.\n  if (EvictRandomSizeClass(size_class_, false) ||\n      EvictRandomSizeClass(size_class_, true)) {\n    // Succeeded in evicting, we're going to make our cache larger.\n    cache_size_++;\n    return true;\n  }\n  return false;\n}\n\n\nnamespace {\nclass LockInverter {\n private:\n  SpinLock *held_, *temp_;\n public:\n  inline explicit LockInverter(SpinLock* held, SpinLock *temp)\n    : held_(held), temp_(temp) { held_->Unlock(); temp_->Lock(); }\n  inline ~LockInverter() { temp_->Unlock(); held_->Lock();  }\n};\n}\n\n// This function is marked as NO_THREAD_SAFETY_ANALYSIS because it uses\n// LockInverter to release one lock and acquire another in scoped-lock\n// style, which our current annotation/analysis does not support.\nbool CentralFreeList::ShrinkCache(int locked_size_class, bool force)\n    NO_THREAD_SAFETY_ANALYSIS {\n  // Start with a quick check without taking a lock.\n  if (cache_size_ == 0) return false;\n  // We don't evict from a full cache unless we are 'forcing'.\n  if (force == false && used_slots_ == cache_size_) return false;\n\n  // Grab lock, but first release the other lock held by this thread.  We use\n  // the lock inverter to ensure that we never hold two size class locks\n  // concurrently.  That can create a deadlock because there is no well\n  // defined nesting order.\n  LockInverter li(&Static::central_cache()[locked_size_class].lock_, &lock_);\n  ASSERT(used_slots_ <= cache_size_);\n  ASSERT(0 <= cache_size_);\n  if (cache_size_ == 0) return false;\n  if (used_slots_ == cache_size_) {\n    if (force == false) return false;\n    // ReleaseListToSpans releases the lock, so we have to make all the\n    // updates to the central list before calling it.\n    cache_size_--;\n    used_slots_--;\n    ReleaseListToSpans(tc_slots_[used_slots_].head);\n    return true;\n  }\n  cache_size_--;\n  return true;\n}\n\nvoid CentralFreeList::InsertRange(void *start, void *end, int N) {\n  SpinLockHolder h(&lock_);\n  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&\n    MakeCacheSpace()) {\n    int slot = used_slots_++;\n    ASSERT(slot >=0);\n    ASSERT(slot < kNumTransferEntries);\n    TCEntry *entry = &tc_slots_[slot];\n    entry->head = start;\n    entry->tail = end;\n    return;\n  }\n  ReleaseListToSpans(start);\n}\n\nint CentralFreeList::RemoveRange(void **start, void **end, int N) {\n  ASSERT(N > 0);\n  lock_.Lock();\n  if (N == Static::sizemap()->num_objects_to_move(size_class_) &&\n      used_slots_ > 0) {\n    int slot = --used_slots_;\n    ASSERT(slot >= 0);\n    TCEntry *entry = &tc_slots_[slot];\n    *start = entry->head;\n    *end = entry->tail;\n    lock_.Unlock();\n    return N;\n  }\n\n  int result = 0;\n  void* head = NULL;\n  void* tail = NULL;\n  // TODO: Prefetch multiple TCEntries?\n  tail = FetchFromSpansSafe();\n  if (tail != NULL) {\n    SLL_SetNext(tail, NULL);\n    head = tail;\n    result = 1;\n    while (result < N) {\n      void *t = FetchFromSpans();\n      if (!t) break;\n      SLL_Push(&head, t);\n      result++;\n    }\n  }\n  lock_.Unlock();\n  *start = head;\n  *end = tail;\n  return result;\n}\n\n\nvoid* CentralFreeList::FetchFromSpansSafe() {\n  void *t = FetchFromSpans();\n  if (!t) {\n    Populate();\n    t = FetchFromSpans();\n  }\n  return t;\n}\n\nvoid* CentralFreeList::FetchFromSpans() {\n  if (tcmalloc::DLL_IsEmpty(&nonempty_)) return NULL;\n  Span* span = nonempty_.next;\n\n  ASSERT(span->objects != NULL);\n  span->refcount++;\n  void* result = span->objects;\n  span->objects = *(reinterpret_cast<void**>(result));\n  if (span->objects == NULL) {\n    // Move to empty list\n    tcmalloc::DLL_Remove(span);\n    tcmalloc::DLL_Prepend(&empty_, span);\n    Event(span, 'E', 0);\n  }\n  counter_--;\n  return result;\n}\n\n// Fetch memory from the system and add to the central cache freelist.\nvoid CentralFreeList::Populate() {\n  // Release central list lock while operating on pageheap\n  lock_.Unlock();\n  const size_t npages = Static::sizemap()->class_to_pages(size_class_);\n\n  Span* span;\n  {\n    SpinLockHolder h(Static::pageheap_lock());\n    span = Static::pageheap()->New(npages);\n    if (span) Static::pageheap()->RegisterSizeClass(span, size_class_);\n  }\n  if (span == NULL) {\n    MESSAGE(\"tcmalloc: allocation failed\", npages << kPageShift);\n    lock_.Lock();\n    return;\n  }\n  ASSERT(span->length == npages);\n  // Cache sizeclass info eagerly.  Locking is not necessary.\n  // (Instead of being eager, we could just replace any stale info\n  // about this span, but that seems to be no better in practice.)\n  for (int i = 0; i < npages; i++) {\n    Static::pageheap()->CacheSizeClass(span->start + i, size_class_);\n  }\n\n  // Split the block into pieces and add to the free-list\n  // TODO: coloring of objects to avoid cache conflicts?\n  void** tail = &span->objects;\n  char* ptr = reinterpret_cast<char*>(span->start << kPageShift);\n  char* limit = ptr + (npages << kPageShift);\n  const size_t size = Static::sizemap()->ByteSizeForClass(size_class_);\n  int num = 0;\n  while (ptr + size <= limit) {\n    *tail = ptr;\n    tail = reinterpret_cast<void**>(ptr);\n    ptr += size;\n    num++;\n  }\n  ASSERT(ptr <= limit);\n  *tail = NULL;\n  span->refcount = 0; // No sub-object in use yet\n\n  // Add span to list of non-empty spans\n  lock_.Lock();\n  tcmalloc::DLL_Prepend(&nonempty_, span);\n  counter_ += num;\n}\n\nint CentralFreeList::tc_length() {\n  SpinLockHolder h(&lock_);\n  return used_slots_ * Static::sizemap()->num_objects_to_move(size_class_);\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/central_freelist.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#ifndef TCMALLOC_CENTRAL_FREELIST_H_\n#define TCMALLOC_CENTRAL_FREELIST_H_\n\n#include \"config.h\"\n#include \"base/thread_annotations.h\"\n#include \"base/spinlock.h\"\n#include \"common.h\"\n#include \"span.h\"\n\nnamespace tcmalloc {\n\n// Data kept per size-class in central cache.\nclass CentralFreeList {\n public:\n  void Init(size_t cl);\n\n  // These methods all do internal locking.\n\n  // Insert the specified range into the central freelist.  N is the number of\n  // elements in the range.  RemoveRange() is the opposite operation.\n  void InsertRange(void *start, void *end, int N);\n\n  // Returns the actual number of fetched elements and sets *start and *end.\n  int RemoveRange(void **start, void **end, int N);\n\n  // Returns the number of free objects in cache.\n  int length() {\n    SpinLockHolder h(&lock_);\n    return counter_;\n  }\n\n  // Returns the number of free objects in the transfer cache.\n  int tc_length();\n\n private:\n  // TransferCache is used to cache transfers of\n  // sizemap.num_objects_to_move(size_class) back and forth between\n  // thread caches and the central cache for a given size class.\n  struct TCEntry {\n    void *head;  // Head of chain of objects.\n    void *tail;  // Tail of chain of objects.\n  };\n\n  // A central cache freelist can have anywhere from 0 to kNumTransferEntries\n  // slots to put link list chains into.  To keep memory usage bounded the total\n  // number of TCEntries across size classes is fixed.  Currently each size\n  // class is initially given one TCEntry which also means that the maximum any\n  // one class can have is kNumClasses.\n  static const int kNumTransferEntries = kNumClasses;\n\n  // REQUIRES: lock_ is held\n  // Remove object from cache and return.\n  // Return NULL if no free entries in cache.\n  void* FetchFromSpans() EXCLUSIVE_LOCKS_REQUIRED(lock_);\n\n  // REQUIRES: lock_ is held\n  // Remove object from cache and return.  Fetches\n  // from pageheap if cache is empty.  Only returns\n  // NULL on allocation failure.\n  void* FetchFromSpansSafe() EXCLUSIVE_LOCKS_REQUIRED(lock_);\n\n  // REQUIRES: lock_ is held\n  // Release a linked list of objects to spans.\n  // May temporarily release lock_.\n  void ReleaseListToSpans(void *start) EXCLUSIVE_LOCKS_REQUIRED(lock_);\n\n  // REQUIRES: lock_ is held\n  // Release an object to spans.\n  // May temporarily release lock_.\n  void ReleaseToSpans(void* object) EXCLUSIVE_LOCKS_REQUIRED(lock_);\n\n  // REQUIRES: lock_ is held\n  // Populate cache by fetching from the page heap.\n  // May temporarily release lock_.\n  void Populate() EXCLUSIVE_LOCKS_REQUIRED(lock_);\n\n  // REQUIRES: lock is held.\n  // Tries to make room for a TCEntry.  If the cache is full it will try to\n  // expand it at the cost of some other cache size.  Return false if there is\n  // no space.\n  bool MakeCacheSpace() EXCLUSIVE_LOCKS_REQUIRED(lock_);\n\n  // REQUIRES: lock_ for locked_size_class is held.\n  // Picks a \"random\" size class to steal TCEntry slot from.  In reality it\n  // just iterates over the sizeclasses but does so without taking a lock.\n  // Returns true on success.\n  // May temporarily lock a \"random\" size class.\n  static bool EvictRandomSizeClass(int locked_size_class, bool force);\n\n  // REQUIRES: lock_ is *not* held.\n  // Tries to shrink the Cache.  If force is true it will relase objects to\n  // spans if it allows it to shrink the cache.  Return false if it failed to\n  // shrink the cache.  Decrements cache_size_ on succeess.\n  // May temporarily take lock_.  If it takes lock_, the locked_size_class\n  // lock is released to keep the thread from holding two size class locks\n  // concurrently which could lead to a deadlock.\n  bool ShrinkCache(int locked_size_class, bool force) LOCKS_EXCLUDED(lock_);\n\n  // This lock protects all the data members.  cached_entries and cache_size_\n  // may be looked at without holding the lock.\n  SpinLock lock_;\n\n  // We keep linked lists of empty and non-empty spans.\n  size_t   size_class_;     // My size class\n  Span     empty_;          // Dummy header for list of empty spans\n  Span     nonempty_;       // Dummy header for list of non-empty spans\n  size_t   counter_;        // Number of free objects in cache entry\n\n  // Here we reserve space for TCEntry cache slots.  Since one size class can\n  // end up getting all the TCEntries quota in the system we just preallocate\n  // sufficient number of entries here.\n  TCEntry tc_slots_[kNumTransferEntries];\n\n  // Number of currently used cached entries in tc_slots_.  This variable is\n  // updated under a lock but can be read without one.\n  int32_t used_slots_;\n  // The current number of slots for this size class.  This is an\n  // adaptive value that is increased if there is lots of traffic\n  // on a given size class.\n  int32_t cache_size_;\n};\n\n// Pads each CentralCache object to multiple of 64 bytes.  Since some\n// compilers (such as MSVC) don't like it when the padding is 0, I use\n// template specialization to remove the padding entirely when\n// sizeof(CentralFreeList) is a multiple of 64.\ntemplate<int kFreeListSizeMod64>\nclass CentralFreeListPaddedTo : public CentralFreeList {\n private:\n  char pad_[64 - kFreeListSizeMod64];\n};\n\ntemplate<>\nclass CentralFreeListPaddedTo<0> : public CentralFreeList {\n};\n\nclass CentralFreeListPadded : public CentralFreeListPaddedTo<\n  sizeof(CentralFreeList) % 64> {\n};\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_CENTRAL_FREELIST_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/common.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#include \"config.h\"\n#include \"system-alloc.h\"\n#include \"config.h\"\n#include \"common.h\"\n\nnamespace tcmalloc {\n\n// Note: the following only works for \"n\"s that fit in 32-bits, but\n// that is fine since we only use it for small sizes.\nstatic inline int LgFloor(size_t n) {\n  int log = 0;\n  for (int i = 4; i >= 0; --i) {\n    int shift = (1 << i);\n    size_t x = n >> shift;\n    if (x != 0) {\n      n = x;\n      log += shift;\n    }\n  }\n  ASSERT(n == 1);\n  return log;\n}\n\nint AlignmentForSize(size_t size) {\n  int alignment = kAlignment;\n  if (size >= 2048) {\n    // Cap alignment at 256 for large sizes.\n    alignment = 256;\n  } else if (size >= 128) {\n    // Space wasted due to alignment is at most 1/8, i.e., 12.5%.\n    alignment = (1 << LgFloor(size)) / 8;\n  } else if (size >= 16) {\n    // We need an alignment of at least 16 bytes to satisfy\n    // requirements for some SSE types.\n    alignment = 16;\n  }\n  CHECK_CONDITION(size < 16 || alignment >= 16);\n  CHECK_CONDITION((alignment & (alignment - 1)) == 0);\n  return alignment;\n}\n\nint SizeMap::NumMoveSize(size_t size) {\n  if (size == 0) return 0;\n  // Use approx 64k transfers between thread and central caches.\n  int num = static_cast<int>(64.0 * 1024.0 / size);\n  if (num < 2) num = 2;\n\n  // Avoid bringing too many objects into small object free lists.\n  // If this value is too large:\n  // - We waste memory with extra objects sitting in the thread caches.\n  // - The central freelist holds its lock for too long while\n  //   building a linked list of objects, slowing down the allocations\n  //   of other threads.\n  // If this value is too small:\n  // - We go to the central freelist too often and we have to acquire\n  //   its lock each time.\n  // This value strikes a balance between the constraints above.\n  if (num > 32) num = 32;\n\n  return num;\n}\n\n// Initialize the mapping arrays\nvoid SizeMap::Init() {\n  // Do some sanity checking on add_amount[]/shift_amount[]/class_array[]\n  if (ClassIndex(0) < 0) {\n    CRASH(\"Invalid class index %d for size 0\\n\", ClassIndex(0));\n  }\n  if (ClassIndex(kMaxSize) >= sizeof(class_array_)) {\n    CRASH(\"Invalid class index %d for kMaxSize\\n\", ClassIndex(kMaxSize));\n  }\n\n  // Compute the size classes we want to use\n  int sc = 1;   // Next size class to assign\n  int alignment = kAlignment;\n  CHECK_CONDITION(kAlignment <= 16);\n  int last_lg = -1;\n  for (size_t size = kAlignment; size <= kMaxSize; size += alignment) {\n    int lg = LgFloor(size);\n    if (lg > last_lg) {\n      // Increase alignment every so often to reduce number of size classes.\n      alignment = AlignmentForSize(size);\n      last_lg = lg;\n    }\n    CHECK_CONDITION((size % alignment) == 0);\n\n    // Allocate enough pages so leftover is less than 1/8 of total.\n    // This bounds wasted space to at most 12.5%.\n    size_t psize = kPageSize;\n    while ((psize % size) > (psize >> 3)) {\n      psize += kPageSize;\n    }\n    const size_t my_pages = psize >> kPageShift;\n\n    if (sc > 1 && my_pages == class_to_pages_[sc-1]) {\n      // See if we can merge this into the previous class without\n      // increasing the fragmentation of the previous class.\n      const size_t my_objects = (my_pages << kPageShift) / size;\n      const size_t prev_objects = (class_to_pages_[sc-1] << kPageShift)\n                                  / class_to_size_[sc-1];\n      if (my_objects == prev_objects) {\n        // Adjust last class to include this size\n        class_to_size_[sc-1] = size;\n        continue;\n      }\n    }\n\n    // Add new class\n    class_to_pages_[sc] = my_pages;\n    class_to_size_[sc] = size;\n    sc++;\n  }\n  if (sc != kNumClasses) {\n    CRASH(\"wrong number of size classes: found %d instead of %d\\n\",\n          sc, int(kNumClasses));\n  }\n\n  // Initialize the mapping arrays\n  int next_size = 0;\n  for (int c = 1; c < kNumClasses; c++) {\n    const int max_size_in_class = class_to_size_[c];\n    for (int s = next_size; s <= max_size_in_class; s += kAlignment) {\n      class_array_[ClassIndex(s)] = c;\n    }\n    next_size = max_size_in_class + kAlignment;\n  }\n\n  // Double-check sizes just to be safe\n  for (size_t size = 0; size <= kMaxSize; size++) {\n    const int sc = SizeClass(size);\n    if (sc <= 0 || sc >= kNumClasses) {\n      CRASH(\"Bad size class %d for %\" PRIuS \"\\n\", sc, size);\n    }\n    if (sc > 1 && size <= class_to_size_[sc-1]) {\n      CRASH(\"Allocating unnecessarily large class %d for %\" PRIuS\n            \"\\n\", sc, size);\n    }\n    const size_t s = class_to_size_[sc];\n    if (size > s) {\n      CRASH(\"Bad size %\" PRIuS \" for %\" PRIuS \" (sc = %d)\\n\", s, size, sc);\n    }\n    if (s == 0) {\n      CRASH(\"Bad size %\" PRIuS \" for %\" PRIuS \" (sc = %d)\\n\", s, size, sc);\n    }\n  }\n\n  // Initialize the num_objects_to_move array.\n  for (size_t cl = 1; cl  < kNumClasses; ++cl) {\n    num_objects_to_move_[cl] = NumMoveSize(ByteSizeForClass(cl));\n  }\n}\n\nvoid SizeMap::Dump(TCMalloc_Printer* out) {\n  // Dump class sizes and maximum external wastage per size class\n  for (size_t cl = 1; cl  < kNumClasses; ++cl) {\n    const int alloc_size = class_to_pages_[cl] << kPageShift;\n    const int alloc_objs = alloc_size / class_to_size_[cl];\n    const int min_used = (class_to_size_[cl-1] + 1) * alloc_objs;\n    const int max_waste = alloc_size - min_used;\n    out->printf(\"SC %3d [ %8d .. %8d ] from %8d ; %2.0f%% maxwaste\\n\",\n                int(cl),\n                int(class_to_size_[cl-1] + 1),\n                int(class_to_size_[cl]),\n                int(class_to_pages_[cl] << kPageShift),\n                max_waste * 100.0 / alloc_size\n                );\n  }\n}\n\n// Metadata allocator -- keeps stats about how many bytes allocated.\nstatic uint64_t metadata_system_bytes_ = 0;\nvoid* MetaDataAlloc(size_t bytes) {\n  void* result = TCMalloc_SystemAlloc(bytes, NULL);\n  if (result != NULL) {\n    metadata_system_bytes_ += bytes;\n  }\n  return result;\n}\n\nuint64_t metadata_system_bytes() { return metadata_system_bytes_; }\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/common.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// Common definitions for tcmalloc code.\n\n#ifndef TCMALLOC_COMMON_H_\n#define TCMALLOC_COMMON_H_\n\n#include \"config.h\"\n#include <stddef.h>\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n#include <stdarg.h>\n#include \"base/commandlineflags.h\"\n#include \"internal_logging.h\"\n\n// Type that can hold a page number\ntypedef uintptr_t PageID;\n\n// Type that can hold the length of a run of pages\ntypedef uintptr_t Length;\n\n//-------------------------------------------------------------------\n// Configuration\n//-------------------------------------------------------------------\n\n// Using large pages speeds up the execution at a cost of larger memory use.\n// Deallocation may speed up by a factor as the page map gets 8x smaller, so\n// lookups in the page map result in fewer L2 cache misses, which translates to\n// speedup for application/platform combinations with high L2 cache pressure.\n// As the number of size classes increases with large pages, we increase\n// the thread cache allowance to avoid passing more free ranges to and from\n// central lists.  Also, larger pages are less likely to get freed.\n// These two factors cause a bounded increase in memory use.\n\n#if defined(TCMALLOC_LARGE_PAGES)\nstatic const size_t kPageShift  = 15;\nstatic const size_t kNumClasses = 95;\nstatic const size_t kMaxThreadCacheSize = 4 << 20;\n#else\nstatic const size_t kPageShift  = 12;\nstatic const size_t kNumClasses = 61;\nstatic const size_t kMaxThreadCacheSize = 2 << 20;\n#endif\n\nstatic const size_t kPageSize   = 1 << kPageShift;\nstatic const size_t kMaxSize    = 8u * kPageSize;\nstatic const size_t kAlignment  = 8;\nstatic const size_t kLargeSizeClass = 0;\n// For all span-lengths < kMaxPages we keep an exact-size list.\nstatic const size_t kMaxPages = 1 << (20 - kPageShift);\n\n// Default bound on the total amount of thread caches.\nstatic const size_t kDefaultOverallThreadCacheSize = 8u * kMaxThreadCacheSize;\n\n// Lower bound on the per-thread cache sizes\nstatic const size_t kMinThreadCacheSize = kMaxSize * 2;\n\n// The number of bytes one ThreadCache will steal from another when\n// the first ThreadCache is forced to Scavenge(), delaying the\n// next call to Scavenge for this thread.\nstatic const size_t kStealAmount = 1 << 16;\n\n// The number of times that a deallocation can cause a freelist to\n// go over its max_length() before shrinking max_length().\nstatic const int kMaxOverages = 3;\n\n// Maximum length we allow a per-thread free-list to have before we\n// move objects from it into the corresponding central free-list.  We\n// want this big to avoid locking the central free-list too often.  It\n// should not hurt to make this list somewhat big because the\n// scavenging code will shrink it down when its contents are not in use.\nstatic const int kMaxDynamicFreeListLength = 8192;\n\nstatic const Length kMaxValidPages = (~static_cast<Length>(0)) >> kPageShift;\n\n#ifdef __x86_64__\n// All current and planned x86_64 processors only look at the lower 48 bits\n// in virtual to physical address translation.  The top 16 are thus unused.\n// TODO(rus): Under what operating systems can we increase it safely to 17?\n// This lets us use smaller page maps.  On first allocation, a 36-bit page map\n// uses only 96 KB instead of the 4.5 MB used by a 52-bit page map.\nstatic const int kAddressBits = 48;\n#else\nstatic const int kAddressBits = 8 * sizeof(void*);\n#endif\n\nnamespace tcmalloc {\n\n// Convert byte size into pages.  This won't overflow, but may return\n// an unreasonably large value if bytes is huge enough.\ninline Length pages(size_t bytes) {\n  return (bytes >> kPageShift) +\n      ((bytes & (kPageSize - 1)) > 0 ? 1 : 0);\n}\n\n// For larger allocation sizes, we use larger memory alignments to\n// reduce the number of size classes.\nint AlignmentForSize(size_t size);\n\n// Size-class information + mapping\nclass SizeMap {\n private:\n  // Number of objects to move between a per-thread list and a central\n  // list in one shot.  We want this to be not too small so we can\n  // amortize the lock overhead for accessing the central list.  Making\n  // it too big may temporarily cause unnecessary memory wastage in the\n  // per-thread free list until the scavenger cleans up the list.\n  int num_objects_to_move_[kNumClasses];\n\n  //-------------------------------------------------------------------\n  // Mapping from size to size_class and vice versa\n  //-------------------------------------------------------------------\n\n  // Sizes <= 1024 have an alignment >= 8.  So for such sizes we have an\n  // array indexed by ceil(size/8).  Sizes > 1024 have an alignment >= 128.\n  // So for these larger sizes we have an array indexed by ceil(size/128).\n  //\n  // We flatten both logical arrays into one physical array and use\n  // arithmetic to compute an appropriate index.  The constants used by\n  // ClassIndex() were selected to make the flattening work.\n  //\n  // Examples:\n  //   Size       Expression                      Index\n  //   -------------------------------------------------------\n  //   0          (0 + 7) / 8                     0\n  //   1          (1 + 7) / 8                     1\n  //   ...\n  //   1024       (1024 + 7) / 8                  128\n  //   1025       (1025 + 127 + (120<<7)) / 128   129\n  //   ...\n  //   32768      (32768 + 127 + (120<<7)) / 128  376\n  static const int kMaxSmallSize = 1024;\n  static const size_t kClassArraySize =\n      (((1 << kPageShift) * 8u + 127 + (120 << 7)) >> 7) + 1;\n  unsigned char class_array_[kClassArraySize];\n\n  // Compute index of the class_array[] entry for a given size\n  static inline int ClassIndex(int s) {\n    ASSERT(0 <= s);\n    ASSERT(s <= kMaxSize);\n    const bool big = (s > kMaxSmallSize);\n    const int add_amount = big ? (127 + (120<<7)) : 7;\n    const int shift_amount = big ? 7 : 3;\n    return (s + add_amount) >> shift_amount;\n  }\n\n  int NumMoveSize(size_t size);\n\n  // Mapping from size class to max size storable in that class\n  size_t class_to_size_[kNumClasses];\n\n  // Mapping from size class to number of pages to allocate at a time\n  size_t class_to_pages_[kNumClasses];\n\n public:\n  // Constructor should do nothing since we rely on explicit Init()\n  // call, which may or may not be called before the constructor runs.\n  SizeMap() { }\n\n  // Initialize the mapping arrays\n  void Init();\n\n  inline int SizeClass(int size) {\n    return class_array_[ClassIndex(size)];\n  }\n\n  // Get the byte-size for a specified class\n  inline size_t ByteSizeForClass(size_t cl) {\n    return class_to_size_[cl];\n  }\n\n  // Mapping from size class to max size storable in that class\n  inline size_t class_to_size(size_t cl) {\n    return class_to_size_[cl];\n  }\n\n  // Mapping from size class to number of pages to allocate at a time\n  inline size_t class_to_pages(size_t cl) {\n    return class_to_pages_[cl];\n  }\n\n  // Number of objects to move between a per-thread list and a central\n  // list in one shot.  We want this to be not too small so we can\n  // amortize the lock overhead for accessing the central list.  Making\n  // it too big may temporarily cause unnecessary memory wastage in the\n  // per-thread free list until the scavenger cleans up the list.\n  inline int num_objects_to_move(size_t cl) {\n    return num_objects_to_move_[cl];\n  }\n\n  // Dump contents of the computed size map\n  void Dump(TCMalloc_Printer* out);\n};\n\n// Allocates \"bytes\" worth of memory and returns it.  Increments\n// metadata_system_bytes appropriately.  May return NULL if allocation\n// fails.  Requires pageheap_lock is held.\nvoid* MetaDataAlloc(size_t bytes);\n\n// Returns the total number of bytes allocated from the system.\n// Requires pageheap_lock is held.\nuint64_t metadata_system_bytes();\n\n// size/depth are made the same size as a pointer so that some generic\n// code below can conveniently cast them back and forth to void*.\nstatic const int kMaxStackDepth = 31;\nstruct StackTrace {\n  uintptr_t size;          // Size of object\n  uintptr_t depth;         // Number of PC values stored in array below\n  void*     stack[kMaxStackDepth];\n};\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_COMMON_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/config.h.in",
    "content": "/* src/config.h.in.  Generated from configure.ac by autoheader.  */\n\n\n#ifndef GOOGLE_PERFTOOLS_CONFIG_H_\n#define GOOGLE_PERFTOOLS_CONFIG_H_\n\n\n/* Define to 1 if compiler supports __builtin_stack_pointer */\n#undef HAVE_BUILTIN_STACK_POINTER\n\n/* Define to 1 if you have the <conflict-signal.h> header file. */\n#undef HAVE_CONFLICT_SIGNAL_H\n\n/* Define to 1 if you have the <cygwin/signal.h> header file. */\n#undef HAVE_CYGWIN_SIGNAL_H\n\n/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.\n   */\n#undef HAVE_DECL_CFREE\n\n/* Define to 1 if you have the declaration of `memalign', and to 0 if you\n   don't. */\n#undef HAVE_DECL_MEMALIGN\n\n/* Define to 1 if you have the declaration of `posix_memalign', and to 0 if\n   you don't. */\n#undef HAVE_DECL_POSIX_MEMALIGN\n\n/* Define to 1 if you have the declaration of `pvalloc', and to 0 if you\n   don't. */\n#undef HAVE_DECL_PVALLOC\n\n/* Define to 1 if you have the declaration of `uname', and to 0 if you don't.\n   */\n#undef HAVE_DECL_UNAME\n\n/* Define to 1 if you have the declaration of `valloc', and to 0 if you don't.\n   */\n#undef HAVE_DECL_VALLOC\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n#undef HAVE_DLFCN_H\n\n/* Define to 1 if the system has the type `Elf32_Versym'. */\n#undef HAVE_ELF32_VERSYM\n\n/* Define to 1 if you have the <execinfo.h> header file. */\n#undef HAVE_EXECINFO_H\n\n/* Define to 1 if you have the <fcntl.h> header file. */\n#undef HAVE_FCNTL_H\n\n/* Define to 1 if you have the <features.h> header file. */\n#undef HAVE_FEATURES_H\n\n/* Define to 1 if you have the `geteuid' function. */\n#undef HAVE_GETEUID\n\n/* Define to 1 if you have the `getpagesize' function. */\n#undef HAVE_GETPAGESIZE\n\n/* Define to 1 if you have the <glob.h> header file. */\n#undef HAVE_GLOB_H\n\n/* Define to 1 if you have the <grp.h> header file. */\n#undef HAVE_GRP_H\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#undef HAVE_INTTYPES_H\n\n/* Define to 1 if you have the <libunwind.h> header file. */\n#undef HAVE_LIBUNWIND_H\n\n/* Define to 1 if you have the <linux/ptrace.h> header file. */\n#undef HAVE_LINUX_PTRACE_H\n\n/* Define to 1 if you have the <malloc.h> header file. */\n#undef HAVE_MALLOC_H\n\n/* Define to 1 if you have the <memory.h> header file. */\n#undef HAVE_MEMORY_H\n\n/* Define to 1 if you have a working `mmap' system call. */\n#undef HAVE_MMAP\n\n/* define if the compiler implements namespaces */\n#undef HAVE_NAMESPACES\n\n/* Define to 1 if you have the <poll.h> header file. */\n#undef HAVE_POLL_H\n\n/* define if libc has program_invocation_name */\n#undef HAVE_PROGRAM_INVOCATION_NAME\n\n/* Define if you have POSIX threads libraries and header files. */\n#undef HAVE_PTHREAD\n\n/* Define to 1 if you have the <pwd.h> header file. */\n#undef HAVE_PWD_H\n\n/* Define to 1 if you have the `sbrk' function. */\n#undef HAVE_SBRK\n\n/* Define to 1 if you have the <sched.h> header file. */\n#undef HAVE_SCHED_H\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#undef HAVE_STDINT_H\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#undef HAVE_STDLIB_H\n\n/* Define to 1 if you have the <strings.h> header file. */\n#undef HAVE_STRINGS_H\n\n/* Define to 1 if you have the <string.h> header file. */\n#undef HAVE_STRING_H\n\n/* Define to 1 if the system has the type `struct mallinfo'. */\n#undef HAVE_STRUCT_MALLINFO\n\n/* Define to 1 if you have the <sys/param.h> header file. */\n#undef HAVE_SYS_PARAM_H\n\n/* Define to 1 if you have the <sys/prctl.h> header file. */\n#undef HAVE_SYS_PRCTL_H\n\n/* Define to 1 if you have the <sys/resource.h> header file. */\n#undef HAVE_SYS_RESOURCE_H\n\n/* Define to 1 if you have the <sys/socket.h> header file. */\n#undef HAVE_SYS_SOCKET_H\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#undef HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/syscall.h> header file. */\n#undef HAVE_SYS_SYSCALL_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#undef HAVE_SYS_TYPES_H\n\n/* <sys/ucontext.h> is broken on redhat 7 */\n#undef HAVE_SYS_UCONTEXT_H\n\n/* Define to 1 if you have the <sys/wait.h> header file. */\n#undef HAVE_SYS_WAIT_H\n\n/* Define to 1 if compiler supports __thread */\n#undef HAVE_TLS\n\n/* Define to 1 if you have the <ucontext.h> header file. */\n#undef HAVE_UCONTEXT_H\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#undef HAVE_UNISTD_H\n\n/* Define to 1 if you have the <unwind.h> header file. */\n#undef HAVE_UNWIND_H\n\n/* Define to 1 if you have the <valgrind.h> header file. */\n#undef HAVE_VALGRIND_H\n\n/* define if your compiler has __attribute__ */\n#undef HAVE___ATTRIBUTE__\n\n/* Define to 1 if compiler supports __environ */\n#undef HAVE___ENVIRON\n\n/* Define to 1 if the system has the type `__int64'. */\n#undef HAVE___INT64\n\n/* prefix where we look for installed files */\n#undef INSTALL_PREFIX\n\n/* Define to 1 if int32_t is equivalent to intptr_t */\n#undef INT32_EQUALS_INTPTR\n\n/* Define to the sub-directory in which libtool stores uninstalled libraries.\n   */\n#undef LT_OBJDIR\n\n/* Define to 1 if your C compiler doesn't accept -c and -o together. */\n#undef NO_MINUS_C_MINUS_O\n\n/* Name of package */\n#undef PACKAGE\n\n/* Define to the address where bug reports for this package should be sent. */\n#undef PACKAGE_BUGREPORT\n\n/* Define to the full name of this package. */\n#undef PACKAGE_NAME\n\n/* Define to the full name and version of this package. */\n#undef PACKAGE_STRING\n\n/* Define to the one symbol short name of this package. */\n#undef PACKAGE_TARNAME\n\n/* Define to the home page for this package. */\n#undef PACKAGE_URL\n\n/* Define to the version of this package. */\n#undef PACKAGE_VERSION\n\n/* How to access the PC from a struct ucontext */\n#undef PC_FROM_UCONTEXT\n\n/* Always the empty-string on non-windows systems. On windows, should be\n   \"__declspec(dllexport)\". This way, when we compile the dll, we export our\n   functions/classes. It's safe to define this here because config.h is only\n   used internally, to compile the DLL, and every DLL source file #includes\n   \"config.h\" before anything else. */\n#undef PERFTOOLS_DLL_DECL\n\n/* printf format code for printing a size_t and ssize_t */\n#undef PRIdS\n\n/* printf format code for printing a size_t and ssize_t */\n#undef PRIuS\n\n/* printf format code for printing a size_t and ssize_t */\n#undef PRIxS\n\n/* Define to necessary symbol if this constant uses a non-standard name on\n   your system. */\n#undef PTHREAD_CREATE_JOINABLE\n\n/* Define to 1 if you have the ANSI C header files. */\n#undef STDC_HEADERS\n\n/* the namespace where STL code like vector<> is defined */\n#undef STL_NAMESPACE\n\n/* Version number of package */\n#undef VERSION\n\n/* C99 says: define this to get the PRI... macros from stdint.h */\n#ifndef __STDC_FORMAT_MACROS\n# define __STDC_FORMAT_MACROS 1\n#endif\n\n/* Define to `__inline__' or `__inline' if that's what the C compiler\n   calls it, or to nothing if 'inline' is not supported under any name.  */\n#ifndef __cplusplus\n#undef inline\n#endif\n\n\n#ifdef __MINGW32__\n#include \"windows/mingw.h\"\n#endif\n\n#endif  /* #ifndef GOOGLE_PERFTOOLS_CONFIG_H_ */\n\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/config_for_unittests.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// All Rights Reserved.\n//\n// Author: Craig Silverstein\n//\n// This file is needed for windows -- unittests are not part of the\n// perftools dll, but still want to include config.h just like the\n// dll does, so they can use internal tools and APIs for testing.\n//\n// The problem is that config.h declares PERFTOOLS_DLL_DECL to be\n// for exporting symbols, but the unittest needs to *import* symbols\n// (since it's not the dll).\n//\n// The solution is to have this file, which is just like config.h but\n// sets PERFTOOLS_DLL_DECL to do a dllimport instead of a dllexport.\n//\n// The reason we need this extra PERFTOOLS_DLL_DECL_FOR_UNITTESTS\n// variable is in case people want to set PERFTOOLS_DLL_DECL explicitly\n// to something other than __declspec(dllexport).  In that case, they\n// may want to use something other than __declspec(dllimport) for the\n// unittest case.  For that, we allow folks to define both\n// PERFTOOLS_DLL_DECL and PERFTOOLS_DLL_DECL_FOR_UNITTESTS explicitly.\n//\n// NOTE: This file is equivalent to config.h on non-windows systems,\n// which never defined PERFTOOLS_DLL_DECL_FOR_UNITTESTS and always\n// define PERFTOOLS_DLL_DECL to the empty string.\n\n#include \"config.h\"\n\n#undef PERFTOOLS_DLL_DECL\n#ifdef PERFTOOLS_DLL_DECL_FOR_UNITTESTS\n# define PERFTOOLS_DLL_DECL  PERFTOOLS_DLL_DECL_FOR_UNITTESTS\n#else\n# define PERFTOOLS_DLL_DECL  // if DLL_DECL_FOR_UNITTESTS isn't defined, use \"\"\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/debugallocation.cc",
    "content": "// Copyright (c) 2000, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Urs Holzle <opensource@google.com>\n\n#include \"config.h\"\n#ifdef HAVE_MALLOC_H\n#include <malloc.h>\n#endif\n#include <pthread.h>\n#include <stdio.h>\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>\n#endif\n#include <stdarg.h>\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#endif\n#include <sys/types.h>\n#include <sys/stat.h>\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#include <errno.h>\n#include <string.h>\n\n#include \"base/commandlineflags.h\"\n#include \"base/googleinit.h\"\n#include \"base/logging.h\"\n#include \"google/malloc_extension.h\"\n#include \"google/malloc_hook.h\"\n#include \"google/stacktrace.h\"\n#include \"addressmap-inl.h\"\n#include \"malloc_hook-inl.h\"\n#include \"symbolize.h\"\n\n#ifdef TCMALLOC_FOR_DEBUGALLOCATION\n#include \"tcmalloc.cc\"\n#else\n#include \"base/spinlock.h\"\n// Else we already have a SpinLock defined in tcmalloc/internal_spinlock.h\n#endif\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    // I guess we're not on a glibc system\n# define __THROW   // __THROW is just an optimization, so ok to make it \"\"\n#endif\n\n// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old\n// form of the name instead.\n#ifndef MAP_ANONYMOUS\n# define MAP_ANONYMOUS MAP_ANON\n#endif\n\n// ========================================================================= //\n\nDEFINE_bool(malloctrace,\n            EnvToBool(\"TCMALLOC_TRACE\", false),\n            \"Enables memory (de)allocation tracing to /tmp/google.alloc.\");\n#ifdef HAVE_MMAP\nDEFINE_bool(malloc_page_fence,\n            EnvToBool(\"TCMALLOC_PAGE_FENCE\", false),\n            \"Enables putting of memory allocations at page boundaries \"\n            \"with a guard page following the allocation (to catch buffer \"\n            \"overruns right when they happen).\");\nDEFINE_bool(malloc_page_fence_never_reclaim,\n            EnvToBool(\"TCMALLOC_PAGE_FRANCE_NEVER_RECLAIM\", false),\n            \"Enables making the virtual address space inaccessible \"\n            \"upon a deallocation instead of returning it and reusing later.\");\n#else\nDEFINE_bool(malloc_page_fence, false, \"Not usable (requires mmap)\");\nDEFINE_bool(malloc_page_fence_never_reclaim, false, \"Not usable (required mmap)\");\n#endif\nDEFINE_bool(malloc_reclaim_memory,\n            EnvToBool(\"TCMALLOC_RECLAIM_MEMORY\", true),\n            \"If set to false, we never return memory to malloc \"\n            \"when an object is deallocated. This ensures that all \"\n            \"heap object addresses are unique.\");\nDEFINE_int32(max_free_queue_size,\n             EnvToInt(\"TCMALLOC_MAX_FREE_QUEUE_SIZE\", 10*1024*1024),\n             \"If greater than 0, keep freed blocks in a queue instead of \"\n             \"releasing them to the allocator immediately.  Release them when \"\n             \"the total size of all blocks in the queue would otherwise exceed \"\n             \"this limit.\");\n\nDEFINE_bool(symbolize_stacktrace,\n            EnvToBool(\"TCMALLOC_SYMBOLIZE_STACKTRACE\", true),\n            \"Symbolize the stack trace when provided (on some error exits)\");\n\n// ========================================================================= //\n\n// A safe version of printf() that does not do any allocation and\n// uses very little stack space.\nstatic void TracePrintf(int fd, const char *fmt, ...)\n  __attribute__ ((__format__ (__printf__, 2, 3)));\n\n//\n// GNU has some weird \"weak aliasing\" thing that permits us to define our\n// own malloc(), free(), and realloc() which can use the normal versions of\n// of themselves by calling __libc_malloc(), __libc_free(), and\n// __libc_realloc().\n//\nextern \"C\" {\n  extern void* __libc_malloc(size_t size);\n  extern void __libc_free(void* ptr);\n  extern void* __libc_realloc(void* ptr, size_t size);\n  extern void* __libc_calloc(size_t nmemb, size_t size);\n  extern int __libc_mallopt(int cmd, int value);\n#ifdef HAVE_STRUCT_MALLINFO\n  extern struct mallinfo __libc_mallinfo(void);\n#endif\n}\n\n// Define the malloc/free/mallopt/mallinfo implementations\n// we will be working on top of.\n// TODO(csilvers): provide debugallocation on top of libc alloc,\n//                 so this #ifdef might sometimes be false.\n#ifdef TCMALLOC_FOR_DEBUGALLOCATION\n\n// The do_* functions are defined in tcmalloc.cc,\n// which is included before this file\n// when TCMALLOC_FOR_DEBUGALLOCATION is defined.\n#define BASE_MALLOC_NEW(size)  cpp_alloc(size, false)\n#define BASE_MALLOC      do_malloc_or_cpp_alloc\n#define BASE_FREE        do_free\n#define BASE_MALLOPT     do_mallopt\n#define BASE_MALLINFO    do_mallinfo\n\n#else\n\n// We are working on top of standard libc's malloc library\n#define BASE_MALLOC_NEW  __libc_malloc\n#define BASE_MALLOC      __libc_malloc\n#define BASE_FREE        __libc_free\n#define BASE_MALLOPT     __libc_mallopt\n#define BASE_MALLINFO    __libc_mallinfo\n\n#endif\n\n// ========================================================================= //\n\nclass MallocBlock;\n\n// A circular buffer to hold freed blocks of memory.  MallocBlock::Deallocate\n// (below) pushes blocks into this queue instead of returning them to the\n// underlying allocator immediately.  See MallocBlock::Deallocate for more\n// information.\n//\n// We can't use an STL class for this because we need to be careful not to\n// perform any heap de-allocations in any of the code in this class, since the\n// code in MallocBlock::Deallocate is not re-entrant.\ntemplate <typename QueueEntry>\nclass FreeQueue {\n public:\n  FreeQueue() : q_front_(0), q_back_(0) {}\n\n  bool Full() {\n    return (q_front_ + 1) % kFreeQueueSize == q_back_;\n  }\n\n  void Push(QueueEntry block) {\n    q_[q_front_] = block;\n    q_front_ = (q_front_ + 1) % kFreeQueueSize;\n  }\n\n  QueueEntry Pop() {\n    const QueueEntry& ret = q_[q_back_];\n    q_back_ = (q_back_ + 1) % kFreeQueueSize;\n    return ret;\n  }\n\n  size_t size() const {\n    return (q_front_ - q_back_ + kFreeQueueSize) % kFreeQueueSize;\n  }\n\n private:\n  // Maximum number of blocks kept in the free queue before being freed.\n  static const int kFreeQueueSize = 1024;\n\n  QueueEntry q_[kFreeQueueSize];\n  int q_front_;\n  int q_back_;\n};\n\nstruct MallocBlockQueueEntry {\n  MallocBlockQueueEntry() : block(NULL), size(0),\n                            num_deleter_pcs(0), deleter_threadid(0) {}\n  MallocBlockQueueEntry(MallocBlock* b, size_t s) : block(b), size(s) {\n    if (FLAGS_max_free_queue_size != 0) {\n      // Adjust the number of frames to skip (4) if you change the\n      // location of this call.\n      num_deleter_pcs =\n          GetStackTrace(deleter_pcs,\n                        sizeof(deleter_pcs) / sizeof(deleter_pcs[0]),\n                        4);\n      deleter_threadid = pthread_self();\n    } else {\n      num_deleter_pcs = 0;\n      // Zero is an illegal pthread id by my reading of the pthread\n      // implementation:\n      deleter_threadid = 0;\n    }\n  }\n\n  MallocBlock* block;\n  size_t size;\n\n  // When deleted and put in the free queue, we (flag-controlled)\n  // record the stack so that if corruption is later found, we can\n  // print the deleter's stack.  (These three vars add 144 bytes of\n  // overhead under the LP64 data model.)\n  void* deleter_pcs[16];\n  int num_deleter_pcs;\n  pthread_t deleter_threadid;\n};\n\nclass MallocBlock {\n public:  // allocation type constants\n\n  // Different allocation types we distinguish.\n  // Note: The lower 4 bits are not random: we index kAllocName array\n  // by these values masked with kAllocTypeMask;\n  // the rest are \"random\" magic bits to help catch memory corruption.\n  static const int kMallocType = 0xEFCDAB90;\n  static const int kNewType = 0xFEBADC81;\n  static const int kArrayNewType = 0xBCEADF72;\n\n private:  // constants\n\n  // A mask used on alloc types above to get to 0, 1, 2\n  static const int kAllocTypeMask = 0x3;\n  // An additional bit to set in AllocType constants\n  // to mark now deallocated regions.\n  static const int kDeallocatedTypeBit = 0x4;\n\n  // For better memory debugging, we initialize all storage to known\n  // values, and overwrite the storage when it's deallocated:\n  // Byte that fills uninitialized storage.\n  static const int kMagicUninitializedByte = 0xAB;\n  // Byte that fills deallocated storage.\n  // NOTE: tcmalloc.cc depends on the value of kMagicDeletedByte\n  //       to work around a bug in the pthread library.\n  static const int kMagicDeletedByte = 0xCD;\n  // A size_t (type of alloc_type_ below) in a deallocated storage\n  // filled with kMagicDeletedByte.\n  static const size_t kMagicDeletedSizeT =\n      0xCDCDCDCD | (((size_t)0xCDCDCDCD << 16) << 16);\n    // Initializer works for 32 and 64 bit size_ts;\n    // \"<< 16 << 16\" is to fool gcc from issuing a warning\n    // when size_ts are 32 bits.\n\n  // NOTE: on Linux, you can enable malloc debugging support in libc by\n  // setting the environment variable MALLOC_CHECK_ to 1 before you\n  // start the program (see man malloc).\n\n  // We use either BASE_MALLOC or mmap to make the actual allocation. In\n  // order to remember which one of the two was used for any block, we store an\n  // appropriate magic word next to the block.\n  static const int kMagicMalloc = 0xDEADBEEF;\n  static const int kMagicMMap = 0xABCDEFAB;\n\n  // This array will be filled with 0xCD, for use with memcmp.\n  static unsigned char kMagicDeletedBuffer[1024];\n  static bool deleted_buffer_initialized_;\n\n private:  // data layout\n\n                    // The four fields size1_,offset_,magic1_,alloc_type_\n                    // should together occupy a multiple of 16 bytes. (At the\n                    // moment, sizeof(size_t) == 4 or 8 depending on piii vs\n                    // k8, and 4 of those sum to 16 or 32 bytes).\n                    // This, combined with BASE_MALLOC's alignment guarantees,\n                    // ensures that SSE types can be stored into the returned\n                    // block, at &size2_.\n  size_t size1_;\n  size_t offset_;   // normally 0 unless memaligned memory\n                    // see comments in memalign() and FromRawPointer().\n  size_t magic1_;\n  size_t alloc_type_;\n  // here comes the actual data (variable length)\n  // ...\n  // then come the size2_ and magic2_, or a full page of mprotect-ed memory\n  // if the malloc_page_fence feature is enabled.\n  size_t size2_;\n  int magic2_;\n\n private:  // static data and helpers\n\n  // Allocation map: stores the allocation type for each allocated object,\n  // or the type or'ed with kDeallocatedTypeBit\n  // for each formerly allocated object.\n  typedef AddressMap<int> AllocMap;\n  static AllocMap* alloc_map_;\n  // This protects alloc_map_ and consistent state of metadata\n  // for each still-allocated object in it.\n  // We use spin locks instead of pthread_mutex_t locks\n  // to prevent crashes via calls to pthread_mutex_(un)lock\n  // for the (de)allocations coming from pthreads initialization itself.\n  static SpinLock alloc_map_lock_;\n\n  // A queue of freed blocks.  Instead of releasing blocks to the allocator\n  // immediately, we put them in a queue, freeing them only when necessary\n  // to keep the total size of all the freed blocks below the limit set by\n  // FLAGS_max_free_queue_size.\n  static FreeQueue<MallocBlockQueueEntry>* free_queue_;\n\n  static size_t free_queue_size_;  // total size of blocks in free_queue_\n  // protects free_queue_ and free_queue_size_\n  static SpinLock free_queue_lock_;\n\n  // Names of allocation types (kMallocType, kNewType, kArrayNewType)\n  static const char* const kAllocName[];\n  // Names of corresponding deallocation types\n  static const char* const kDeallocName[];\n\n  static const char* AllocName(int type) {\n    return kAllocName[type & kAllocTypeMask];\n  }\n\n  static const char* DeallocName(int type) {\n    return kDeallocName[type & kAllocTypeMask];\n  }\n\n private:  // helper accessors\n\n  bool IsMMapped() const { return kMagicMMap == magic1_; }\n\n  bool IsValidMagicValue(int value) const {\n    return kMagicMMap == value  ||  kMagicMalloc == value;\n  }\n\n  static size_t real_malloced_size(size_t size) {\n    return size + sizeof(MallocBlock);\n  }\n  static size_t real_mmapped_size(size_t size) {\n    return size + MallocBlock::data_offset();\n  }\n\n  size_t real_size() {\n    return IsMMapped() ? real_mmapped_size(size1_) : real_malloced_size(size1_);\n  }\n\n  // NOTE: if the block is mmapped (that is, we're using the\n  // malloc_page_fence option) then there's no size2 or magic2\n  // (instead, the guard page begins where size2 would be).\n\n  size_t* size2_addr() { return (size_t*)((char*)&size2_ + size1_); }\n  const size_t* size2_addr() const {\n    return (const size_t*)((char*)&size2_ + size1_);\n  }\n\n  int* magic2_addr() { return (int*)(size2_addr() + 1); }\n  const int* magic2_addr() const { return (const int*)(size2_addr() + 1); }\n\n private:  // other helpers\n\n  void Initialize(size_t size, int type) {\n    RAW_CHECK(IsValidMagicValue(magic1_), \"\");\n    // record us as allocated in the map\n    alloc_map_lock_.Lock();\n    if (!alloc_map_) {\n      void* p = BASE_MALLOC(sizeof(AllocMap));\n      alloc_map_ = new(p) AllocMap(BASE_MALLOC, BASE_FREE);\n    }\n    alloc_map_->Insert(data_addr(), type);\n    // initialize us\n    size1_ = size;\n    offset_ = 0;\n    alloc_type_ = type;\n    if (!IsMMapped()) {\n      *magic2_addr() = magic1_;\n      *size2_addr() = size;\n    }\n    alloc_map_lock_.Unlock();\n    memset(data_addr(), kMagicUninitializedByte, size);\n    if (!IsMMapped()) {\n      RAW_CHECK(size1_ == *size2_addr(), \"should hold\");\n      RAW_CHECK(magic1_ == *magic2_addr(), \"should hold\");\n    }\n  }\n\n  size_t CheckAndClear(int type) {\n    alloc_map_lock_.Lock();\n    CheckLocked(type);\n    if (!IsMMapped()) {\n      RAW_CHECK(size1_ == *size2_addr(), \"should hold\");\n    }\n    // record us as deallocated in the map\n    alloc_map_->Insert(data_addr(), type | kDeallocatedTypeBit);\n    alloc_map_lock_.Unlock();\n    // clear us\n    const size_t size = real_size();\n    memset(this, kMagicDeletedByte, size);\n    return size;\n  }\n\n  void CheckLocked(int type) const {\n    int map_type = 0;\n    const int* found_type =\n      alloc_map_ != NULL ? alloc_map_->Find(data_addr()) : NULL;\n    if (found_type == NULL) {\n      RAW_LOG(FATAL, \"memory allocation bug: object at %p \"\n                     \"has never been allocated\", data_addr());\n    } else {\n      map_type = *found_type;\n    }\n    if ((map_type & kDeallocatedTypeBit) != 0) {\n      RAW_LOG(FATAL, \"memory allocation bug: object at %p \"\n                     \"has been already deallocated (it was allocated with %s)\",\n                     data_addr(), AllocName(map_type & ~kDeallocatedTypeBit));\n    }\n    if (alloc_type_ == kMagicDeletedSizeT) {\n      RAW_LOG(FATAL, \"memory stomping bug: a word before object at %p \"\n                     \"has been corrupted; or else the object has been already \"\n                     \"deallocated and our memory map has been corrupted\",\n                     data_addr());\n    }\n    if (!IsValidMagicValue(magic1_)) {\n      RAW_LOG(FATAL, \"memory stomping bug: a word before object at %p \"\n                     \"has been corrupted; \"\n                     \"or else our memory map has been corrupted and this is a \"\n                     \"deallocation for not (currently) heap-allocated object\",\n                     data_addr());\n    }\n    if (!IsMMapped()) {\n      if (size1_ != *size2_addr()) {\n        RAW_LOG(FATAL, \"memory stomping bug: a word after object at %p \"\n                       \"has been corrupted\", data_addr());\n      }\n      if (!IsValidMagicValue(*magic2_addr())) {\n        RAW_LOG(FATAL, \"memory stomping bug: a word after object at %p \"\n                \"has been corrupted\", data_addr());\n      }\n    }\n    if (alloc_type_ != type) {\n      if ((alloc_type_ != MallocBlock::kMallocType) &&\n          (alloc_type_ != MallocBlock::kNewType)    &&\n          (alloc_type_ != MallocBlock::kArrayNewType)) {\n        RAW_LOG(FATAL, \"memory stomping bug: a word before object at %p \"\n                       \"has been corrupted\", data_addr());\n      }\n      RAW_LOG(FATAL, \"memory allocation/deallocation mismatch at %p: \"\n                     \"allocated with %s being deallocated with %s\",\n                     data_addr(), AllocName(alloc_type_), DeallocName(type));\n    }\n    if (alloc_type_ != map_type) {\n      RAW_LOG(FATAL, \"memory stomping bug: our memory map has been corrupted : \"\n                     \"allocation at %p made with %s \"\n                     \"is recorded in the map to be made with %s\",\n                     data_addr(), AllocName(alloc_type_),  AllocName(map_type));\n    }\n  }\n\n public:  // public accessors\n\n  void* data_addr() { return (void*)&size2_; }\n  const void* data_addr() const { return (const void*)&size2_; }\n\n  static size_t data_offset() { return OFFSETOF_MEMBER(MallocBlock, size2_); }\n\n  size_t data_size() const { return size1_; }\n\n  void set_offset(int offset) { this->offset_ = offset; }\n\n public:  // our main interface\n\n  static MallocBlock* Allocate(size_t size, int type) {\n    // Prevent an integer overflow / crash with large allocation sizes.\n    // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually\n    // be the maximum value, depending on how the compiler treats ~0. The worst\n    // practical effect is that allocations are limited to 4Gb or so, even if\n    // the address space could take more.\n    static size_t max_size_t = ~0;\n    if (size > max_size_t - sizeof(MallocBlock)) {\n      RAW_LOG(ERROR, \"Massive size passed to malloc: %\"PRIuS\"\", size);\n      return NULL;\n    }\n    MallocBlock* b = NULL;\n    const bool use_malloc_page_fence = FLAGS_malloc_page_fence;\n#ifdef HAVE_MMAP\n    if (use_malloc_page_fence) {\n      // Put the block towards the end of the page and make the next page\n      // inaccessible. This will catch buffer overrun right when it happens.\n      size_t sz = real_mmapped_size(size);\n      int pagesize = getpagesize();\n      int num_pages = (sz + pagesize - 1) / pagesize + 1;\n      char* p = (char*) mmap(NULL, num_pages * pagesize, PROT_READ|PROT_WRITE,\n                             MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n      if (p == MAP_FAILED) {\n        // If the allocation fails, abort rather than returning NULL to\n        // malloc. This is because in most cases, the program will run out\n        // of memory in this mode due to tremendous amount of wastage. There\n        // is no point in propagating the error elsewhere.\n        RAW_LOG(FATAL, \"Out of memory: possibly due to page fence overhead: %s\",\n                strerror(errno));\n      }\n      // Mark the page after the block inaccessible\n      if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) {\n        RAW_LOG(FATAL, \"Guard page setup failed: %s\", strerror(errno));\n      }\n      b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz);\n    } else {\n      b = (MallocBlock*) (type == kMallocType ?\n                          BASE_MALLOC(real_malloced_size(size)) :\n                          BASE_MALLOC_NEW(real_malloced_size(size)));\n    }\n#else\n    b = (MallocBlock*) (type == kMallocType ?\n                        BASE_MALLOC(real_malloced_size(size)) :\n                        BASE_MALLOC_NEW(real_malloced_size(size)));\n#endif\n\n    // It would be nice to output a diagnostic on allocation failure\n    // here, but logging (other than FATAL) requires allocating\n    // memory, which could trigger a nasty recursion. Instead, preserve\n    // malloc semantics and return NULL on failure.\n    if (b != NULL) {\n      b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc;\n      b->Initialize(size, type);\n    }\n    return b;\n  }\n\n  void Deallocate(int type) {\n    if (IsMMapped()) {  // have to do this before CheckAndClear\n#ifdef HAVE_MMAP\n      int size = CheckAndClear(type);\n      int pagesize = getpagesize();\n      int num_pages = (size + pagesize - 1) / pagesize + 1;\n      char* p = (char*) this;\n      if (FLAGS_malloc_page_fence_never_reclaim  ||\n          !FLAGS_malloc_reclaim_memory) {\n        mprotect(p - (num_pages - 1) * pagesize + size,\n                 num_pages * pagesize, PROT_NONE);\n      } else {\n        munmap(p - (num_pages - 1) * pagesize + size, num_pages * pagesize);\n      }\n#endif\n    } else {\n      const size_t size = CheckAndClear(type);\n      if (FLAGS_malloc_reclaim_memory) {\n        // Instead of freeing the block immediately, push it onto a queue of\n        // recently freed blocks.  Free only enough blocks to keep from\n        // exceeding the capacity of the queue or causing the total amount of\n        // un-released memory in the queue from exceeding\n        // FLAGS_max_free_queue_size.\n        ProcessFreeQueue(this, size, FLAGS_max_free_queue_size);\n      }\n    }\n  }\n\n  static size_t FreeQueueSize() {\n    SpinLockHolder l(&free_queue_lock_);\n    return free_queue_size_;\n  }\n\n  static void ProcessFreeQueue(MallocBlock* b, size_t size,\n                               int max_free_queue_size) {\n    SpinLockHolder l(&free_queue_lock_);\n    if (free_queue_ == NULL)\n      free_queue_ = new FreeQueue<MallocBlockQueueEntry>;\n    RAW_CHECK(!free_queue_->Full(), \"Free queue mustn't be full!\");\n\n    if (b != NULL) {\n      free_queue_size_ += size + sizeof(MallocBlockQueueEntry);\n      MallocBlockQueueEntry new_entry(b, size);\n      free_queue_->Push(new_entry);\n    }\n\n    // Free blocks until the total size of unfreed blocks no longer exceeds\n    // max_free_queue_size, and the free queue has at least one free\n    // space in it.\n    while (free_queue_size_ > max_free_queue_size || free_queue_->Full()) {\n      MallocBlockQueueEntry cur = free_queue_->Pop();\n      CheckForDanglingWrites(cur);\n      free_queue_size_ -= cur.size + sizeof(MallocBlockQueueEntry);\n      BASE_FREE(cur.block);\n    }\n    RAW_CHECK(free_queue_size_ >= 0, \"Free queue size went negative!\");\n  }\n\n  static void CheckForDanglingWrites(const MallocBlockQueueEntry& queue_entry) {\n    // Initialize the buffer if necessary.\n    if (!deleted_buffer_initialized_) {\n      // This is threadsafe.  We hold free_queue_lock_.\n      memset(kMagicDeletedBuffer, 0xcd, sizeof(kMagicDeletedBuffer));\n      deleted_buffer_initialized_ = true;\n    }\n\n    const unsigned char* p =\n        reinterpret_cast<unsigned char*>(queue_entry.block);\n\n    static const size_t size_of_buffer = sizeof(kMagicDeletedBuffer);\n    const size_t size = queue_entry.size;\n    const size_t buffers = size / size_of_buffer;\n    const size_t remainder = size % size_of_buffer;\n    size_t buffer_idx;\n    for (buffer_idx = 0; buffer_idx < buffers; ++buffer_idx) {\n      CheckForCorruptedBuffer(queue_entry, buffer_idx, p, size_of_buffer);\n      p += size_of_buffer;\n    }\n    CheckForCorruptedBuffer(queue_entry, buffer_idx, p, remainder);\n  }\n\n  static void CheckForCorruptedBuffer(const MallocBlockQueueEntry& queue_entry,\n                                      size_t buffer_idx,\n                                      const unsigned char* buffer,\n                                      size_t size_of_buffer) {\n    if (memcmp(buffer, kMagicDeletedBuffer, size_of_buffer) == 0) {\n      return;\n    }\n\n    RAW_LOG(ERROR,\n            \"Found a corrupted memory buffer in MallocBlock (may be offset \"\n            \"from user ptr): buffer index: %zd, buffer ptr: %p, size of \"\n            \"buffer: %zd\", buffer_idx, buffer, size_of_buffer);\n\n    // The magic deleted buffer should only be 1024 bytes, but in case\n    // this changes, let's put an upper limit on the number of debug\n    // lines we'll output:\n    if (size_of_buffer <= 1024) {\n      for (int i = 0; i < size_of_buffer; ++i) {\n        if (buffer[i] != 0xcd) {\n          RAW_LOG(ERROR, \"Buffer byte %d is 0x%02x (should be 0xcd).\",\n                  i, buffer[i]);\n        }\n      }\n    } else {\n      RAW_LOG(ERROR, \"Buffer too large to print corruption.\");\n    }\n\n    const MallocBlock* b = queue_entry.block;\n    const size_t size = queue_entry.size;\n    if (queue_entry.num_deleter_pcs > 0) {\n      TracePrintf(STDERR_FILENO, \"Deleted by thread %p\\n\",\n                  reinterpret_cast<void*>(\n                      PRINTABLE_PTHREAD(queue_entry.deleter_threadid)));\n\n      // We don't want to allocate or deallocate memory here, so we use\n      // placement-new.  It's ok that we don't destroy this, since we're\n      // just going to error-exit below anyway.  Union is for alignment.\n      union { void* alignment; char buf[sizeof(SymbolTable)]; } tablebuf;\n      SymbolTable* symbolization_table = new (tablebuf.buf) SymbolTable;\n      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {\n        // Symbolizes the previous address of pc because pc may be in the\n        // next function.  This may happen when the function ends with\n        // a call to a function annotated noreturn (e.g. CHECK).\n        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);\n        symbolization_table->Add(pc - 1);\n      }\n      if (FLAGS_symbolize_stacktrace)\n        symbolization_table->Symbolize();\n      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {\n        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);\n        TracePrintf(STDERR_FILENO, \"    @ %p %s\\n\",\n                    pc, symbolization_table->GetSymbol(pc - 1));\n      }\n    } else {\n      RAW_LOG(ERROR,\n              \"Skipping the printing of the deleter's stack!  Its stack was \"\n              \"not found; either the corruption occurred too early in \"\n              \"execution to obtain a stack trace or --max_free_queue_size was \"\n              \"set to 0.\");\n    }\n\n    RAW_LOG(FATAL,\n            \"Memory was written to after being freed.  MallocBlock: %p, user \"\n            \"ptr: %p, size: %zd.  If you can't find the source of the error, \"\n            \"try using valgrind or purify, or study the output of the \"\n            \"deleter's stack printed above.\", b, b->data_addr(), size);\n  }\n\n  static MallocBlock* FromRawPointer(void* p) {\n    const size_t data_offset = MallocBlock::data_offset();\n    // Find the header just before client's memory.\n    MallocBlock *mb = reinterpret_cast<MallocBlock *>(\n                reinterpret_cast<char *>(p) - data_offset);\n    // If mb->alloc_type_ is kMagicDeletedSizeT, we're not an ok pointer.\n    if (mb->alloc_type_ == kMagicDeletedSizeT) {\n      RAW_LOG(FATAL, \"memory allocation bug: object at %p has been already\"\n                     \" deallocated; or else a word before the object has been\"\n                     \" corrupted (memory stomping bug)\", p);\n    }\n    // If mb->offset_ is zero (common case), mb is the real header.  If\n    // mb->offset_ is non-zero, this block was allocated by memalign, and\n    // mb->offset_ is the distance backwards to the real header from mb,\n    // which is a fake header.  The following subtraction works for both zero\n    // and non-zero values.\n    return reinterpret_cast<MallocBlock *>(\n                reinterpret_cast<char *>(mb) - mb->offset_);\n  }\n  static const MallocBlock* FromRawPointer(const void* p) {\n    // const-safe version: we just cast about\n    return FromRawPointer(const_cast<void*>(p));\n  }\n\n  void Check(int type) {\n    alloc_map_lock_.Lock();\n    CheckLocked(type);\n    alloc_map_lock_.Unlock();\n  }\n\n  static bool CheckEverything() {\n    alloc_map_lock_.Lock();\n    if (alloc_map_ != NULL)  alloc_map_->Iterate(CheckCallback, 0);\n    alloc_map_lock_.Unlock();\n    return true;  // if we get here, we're okay\n  }\n\n  static bool MemoryStats(int* blocks, size_t* total,\n                          int histogram[kMallocHistogramSize]) {\n    memset(histogram, 0, kMallocHistogramSize * sizeof(int));\n    alloc_map_lock_.Lock();\n    stats_blocks_ = 0;\n    stats_total_ = 0;\n    stats_histogram_ = histogram;\n    if (alloc_map_ != NULL) alloc_map_->Iterate(StatsCallback, 0);\n    *blocks = stats_blocks_;\n    *total = stats_total_;\n    alloc_map_lock_.Unlock();\n    return true;\n  }\n\n private:  // helpers for CheckEverything and MemoryStats\n\n  static void CheckCallback(const void* ptr, int* type, int dummy) {\n    if ((*type & kDeallocatedTypeBit) == 0) {\n      FromRawPointer(ptr)->CheckLocked(*type);\n    }\n  }\n\n  // Accumulation variables for StatsCallback protected by alloc_map_lock_\n  static int stats_blocks_;\n  static size_t stats_total_;\n  static int* stats_histogram_;\n\n  static void StatsCallback(const void* ptr, int* type, int dummy) {\n    if ((*type & kDeallocatedTypeBit) == 0) {\n      const MallocBlock* b = FromRawPointer(ptr);\n      b->CheckLocked(*type);\n      ++stats_blocks_;\n      size_t mysize = b->size1_;\n      int entry = 0;\n      stats_total_ += mysize;\n      while (mysize) {\n        ++entry;\n        mysize >>= 1;\n      }\n      RAW_CHECK(entry < kMallocHistogramSize,\n                \"kMallocHistogramSize should be at least as large as log2 \"\n                \"of the maximum process memory size\");\n      stats_histogram_[entry] += 1;\n    }\n  }\n};\n\nvoid DanglingWriteChecker() {\n  // Clear out the remaining free queue to check for dangling writes.\n  MallocBlock::ProcessFreeQueue(NULL, 0, 0);\n}\n\n// ========================================================================= //\n\nconst int MallocBlock::kMagicMalloc;\nconst int MallocBlock::kMagicMMap;\n\nMallocBlock::AllocMap* MallocBlock::alloc_map_ = NULL;\nSpinLock MallocBlock::alloc_map_lock_(SpinLock::LINKER_INITIALIZED);\n\nFreeQueue<MallocBlockQueueEntry>* MallocBlock::free_queue_ = NULL;\nsize_t MallocBlock::free_queue_size_ = 0;\nSpinLock MallocBlock::free_queue_lock_(SpinLock::LINKER_INITIALIZED);\n\nunsigned char MallocBlock::kMagicDeletedBuffer[1024];\nbool MallocBlock::deleted_buffer_initialized_ = false;\n\nconst char* const MallocBlock::kAllocName[] = {\n  \"malloc\",\n  \"new\",\n  \"new []\",\n  NULL,\n};\n\nconst char* const MallocBlock::kDeallocName[] = {\n  \"free\",\n  \"delete\",\n  \"delete []\",\n  NULL,\n};\n\nint MallocBlock::stats_blocks_;\nsize_t MallocBlock::stats_total_;\nint* MallocBlock::stats_histogram_;\n\n// ========================================================================= //\n\n// The following cut-down version of printf() avoids\n// using stdio or ostreams.\n// This is to guarantee no recursive calls into\n// the allocator and to bound the stack space consumed.  (The pthread\n// manager thread in linuxthreads has a very small stack,\n// so fprintf can't be called.)\nstatic void TracePrintf(int fd, const char *fmt, ...) {\n  char buf[64];\n  int i = 0;\n  va_list ap;\n  va_start(ap, fmt);\n  const char *p = fmt;\n  char numbuf[25];\n  numbuf[sizeof(numbuf)-1] = 0;\n  while (*p != '\\0') {              // until end of format string\n    char *s = &numbuf[sizeof(numbuf)-1];\n    if (p[0] == '%' && p[1] != 0) {  // handle % formats\n      int64 l = 0;\n      unsigned long base = 0;\n      if (*++p == 's') {                            // %s\n        s = va_arg(ap, char *);\n      } else if (*p == 'l' && p[1] == 'd') {        // %ld\n        l = va_arg(ap, long);\n        base = 10;\n        p++;\n      } else if (*p == 'l' && p[1] == 'u') {        // %lu\n        l = va_arg(ap, unsigned long);\n        base = 10;\n        p++;\n      } else if (*p == 'z' && p[1] == 'u') {        // %zu\n        l = va_arg(ap, size_t);\n        base = 10;\n        p++;\n      } else if (*p == 'u') {                       // %u\n        l = va_arg(ap, unsigned int);\n        base = 10;\n      } else if (*p == 'd') {                       // %d\n        l = va_arg(ap, int);\n        base = 10;\n      } else if (*p == 'p') {                       // %p\n        l = va_arg(ap, intptr_t);\n        base = 16;\n      } else {\n        write(STDERR_FILENO, \"Unimplemented TracePrintf format\\n\", 33);\n        write(STDERR_FILENO, p, 2);\n        write(STDERR_FILENO, \"\\n\", 1);\n        abort();\n      }\n      p++;\n      if (base != 0) {\n        bool minus = (l < 0 && base == 10);\n        uint64 ul = minus? -l : l;\n        do {\n          *--s = \"0123456789abcdef\"[ul % base];\n          ul /= base;\n        } while (ul != 0);\n        if (base == 16) {\n          *--s = 'x';\n          *--s = '0';\n        } else if (minus) {\n          *--s = '-';\n        }\n      }\n    } else {                        // handle normal characters\n      *--s = *p++;\n    }\n    while (*s != 0) {\n      if (i == sizeof(buf)) {\n        write(fd, buf, i);\n        i = 0;\n      }\n      buf[i++] = *s++;\n    }\n  }\n  if (i != 0) {\n    write(fd, buf, i);\n  }\n  va_end(ap);\n}\n\n// Return the file descriptor we're writing a log to\nstatic int TraceFd() {\n  static int trace_fd = -1;\n  if (trace_fd == -1) {            // Open the trace file on the first call\n    trace_fd = open(\"/tmp/google.alloc\", O_CREAT|O_TRUNC|O_WRONLY, 0666);\n    if (trace_fd == -1) {\n      trace_fd = 2;\n      TracePrintf(trace_fd,\n                  \"Can't open /tmp/google.alloc.  Logging to stderr.\\n\");\n    }\n    // Add a header to the log.\n    TracePrintf(trace_fd, \"Trace started: %lu\\n\",\n                static_cast<unsigned long>(time(NULL)));\n    TracePrintf(trace_fd,\n                \"func\\tsize\\tptr\\tthread_id\\tstack pcs for tools/symbolize\\n\");\n  }\n  return trace_fd;\n}\n\n// Print the hex stack dump on a single line.   PCs are separated by tabs.\nstatic void TraceStack(void) {\n  void *pcs[16];\n  int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0);\n  for (int i = 0; i != n; i++) {\n    TracePrintf(TraceFd(), \"\\t%p\", pcs[i]);\n  }\n}\n\n// This protects MALLOC_TRACE, to make sure its info is atomically written.\nstatic SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED);\n\n#define MALLOC_TRACE(name, size, addr)                                  \\\n  do {                                                                  \\\n    if (FLAGS_malloctrace) {                                            \\\n      SpinLockHolder l(&malloc_trace_lock);                             \\\n      TracePrintf(TraceFd(), \"%s\\t%\"PRIuS\"\\t%p\\t%\"GPRIuPTHREAD,         \\\n                  name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \\\n      TraceStack();                                                     \\\n      TracePrintf(TraceFd(), \"\\n\");                                     \\\n    }                                                                   \\\n  } while (0)\n\n// ========================================================================= //\n\n// Write the characters buf[0, ..., size-1] to\n// the malloc trace buffer.\n// This function is intended for debugging,\n// and is not declared in any header file.\n// You must insert a declaration of it by hand when you need\n// to use it.\nvoid __malloctrace_write(const char *buf, size_t size) {\n  if (FLAGS_malloctrace) {\n    write(TraceFd(), buf, size);\n  }\n}\n\n// ========================================================================= //\n\n// General debug allocation/deallocation\n\nstatic inline void* DebugAllocate(size_t size, int type) {\n  MallocBlock* ptr = MallocBlock::Allocate(size, type);\n  if (ptr == NULL)  return NULL;\n  MALLOC_TRACE(\"malloc\", size, ptr->data_addr());\n  return ptr->data_addr();\n}\n\nstatic inline void DebugDeallocate(void* ptr, int type) {\n  MALLOC_TRACE(\"free\",\n               (ptr != 0 ? MallocBlock::FromRawPointer(ptr)->data_size() : 0),\n               ptr);\n  if (ptr)  MallocBlock::FromRawPointer(ptr)->Deallocate(type);\n}\n\n// ========================================================================= //\n\n// Alloc/free stuff for debug hooks for malloc & friends\n\n// CAVEAT: The code structure below ensures that MallocHook methods are always\n//         called from the stack frame of the invoked allocation function.\n//         heap-checker.cc depends on this to start a stack trace from\n//         the call to the (de)allocation function.\n\n// Put all callers of MallocHook::Invoke* in this module into\n// ATTRIBUTE_SECTION(google_malloc) section,\n// so that MallocHook::GetCallerStackTrace can function accurately:\n\nextern \"C\" {\n  void* malloc(size_t size) __THROW ATTRIBUTE_SECTION(google_malloc);\n  void free(void* ptr) __THROW ATTRIBUTE_SECTION(google_malloc);\n  void* realloc(void* ptr, size_t size) __THROW\n    ATTRIBUTE_SECTION(google_malloc);\n  void* calloc(size_t nmemb, size_t size) __THROW\n    ATTRIBUTE_SECTION(google_malloc);\n  void cfree(void* ptr) __THROW ATTRIBUTE_SECTION(google_malloc);\n\n  void* memalign(size_t __alignment, size_t __size) __THROW\n    ATTRIBUTE_SECTION(google_malloc);\n  int posix_memalign(void** ptr, size_t align, size_t size) __THROW\n    ATTRIBUTE_SECTION(google_malloc);\n  void* valloc(size_t __size) __THROW\n    ATTRIBUTE_SECTION(google_malloc);\n  void* pvalloc(size_t __size) __THROW\n    ATTRIBUTE_SECTION(google_malloc);\n}\n\nstatic void *MemalignOverride(size_t align, size_t size,\n                              const void *caller) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\n\nvoid* operator new(size_t size) throw (std::bad_alloc)\n  ATTRIBUTE_SECTION(google_malloc);\nvoid* operator new(size_t size, const std::nothrow_t&) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\nvoid operator delete(void* p) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\nvoid operator delete(void* p, const std::nothrow_t&) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\nvoid* operator new[](size_t size) throw (std::bad_alloc)\n  ATTRIBUTE_SECTION(google_malloc);\nvoid* operator new[](size_t size, const std::nothrow_t&) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\nvoid operator delete[](void* p) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\nvoid operator delete[](void* p, const std::nothrow_t&) __THROW\n  ATTRIBUTE_SECTION(google_malloc);\n\nextern \"C\" void* malloc(size_t size) __THROW {\n  void* ptr = DebugAllocate(size, MallocBlock::kMallocType);\n  MallocHook::InvokeNewHook(ptr, size);\n  return ptr;\n}\n\nextern \"C\" void free(void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  DebugDeallocate(ptr, MallocBlock::kMallocType);\n}\n\nextern \"C\" void* realloc(void* ptr, size_t size) __THROW {\n  if (ptr == NULL) {\n    ptr = DebugAllocate(size, MallocBlock::kMallocType);\n    MallocHook::InvokeNewHook(ptr, size);\n    return ptr;\n  }\n  if (size == 0) {\n    MallocHook::InvokeDeleteHook(ptr);\n    DebugDeallocate(ptr, MallocBlock::kMallocType);\n    return NULL;\n  }\n  MallocBlock* old = MallocBlock::FromRawPointer(ptr);\n  old->Check(MallocBlock::kMallocType);\n  MallocBlock* p = MallocBlock::Allocate(size, MallocBlock::kMallocType);\n\n  // If realloc fails we are to leave the old block untouched and\n  // return null\n  if (p == NULL)  return NULL;\n\n  memcpy(p->data_addr(), old->data_addr(),\n         (old->data_size() < size) ? old->data_size() : size);\n  MallocHook::InvokeDeleteHook(ptr);\n  MallocHook::InvokeNewHook(p->data_addr(), size);\n  DebugDeallocate(ptr, MallocBlock::kMallocType);\n  MALLOC_TRACE(\"realloc\", p->data_size(), p->data_addr());\n  return p->data_addr();\n}\n\nextern \"C\" void* calloc(size_t count, size_t size) __THROW {\n  // Overflow check\n  const size_t total_size = count * size;\n  if (size != 0 && total_size / size != count) return NULL;\n\n  void* block = DebugAllocate(total_size, MallocBlock::kMallocType);\n  MallocHook::InvokeNewHook(block, total_size);\n  if (block)  memset(block, 0, total_size);\n  return block;\n}\n\nextern \"C\" void cfree(void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  DebugDeallocate(ptr, MallocBlock::kMallocType);\n}\n\n// Round \"value\" up to next \"alignment\" boundary.\n// Requires that \"alignment\" be a power of two.\nstatic intptr_t RoundUp(intptr_t value, intptr_t alignment) {\n  return (value + alignment - 1) & ~(alignment - 1);\n}\n\nstatic void *do_debug_memalign(size_t alignment, size_t size) {\n  // Allocate >= size bytes aligned on \"alignment\" boundary\n  // \"alignment\" is a power of two.\n  void *p = 0;\n  RAW_CHECK((alignment & (alignment-1)) == 0, \"must be power of two\");\n  const size_t data_offset = MallocBlock::data_offset();\n  // Allocate \"alignment-1\" extra bytes to ensure alignment is possible, and\n  // a further data_offset bytes for an additional fake header.\n  size_t extra_bytes = data_offset + alignment - 1;\n  if (size + extra_bytes < size) return NULL;         // Overflow\n  p = DebugAllocate(size + extra_bytes, MallocBlock::kMallocType);\n  if (p != 0) {\n    intptr_t orig_p = reinterpret_cast<intptr_t>(p);\n    // Leave data_offset bytes for fake header, and round up to meet\n    // alignment.\n    p = reinterpret_cast<void *>(RoundUp(orig_p + data_offset, alignment));\n    // Create a fake header block with an offset_ that points back to the\n    // real header.  FromRawPointer uses this value.\n    MallocBlock *fake_hdr = reinterpret_cast<MallocBlock *>(\n                reinterpret_cast<char *>(p) - data_offset);\n    // offset_ is distance between real and fake headers.\n    // p is now end of fake header (beginning of client area),\n    // and orig_p is the end of the real header, so offset_\n    // is their difference.\n    fake_hdr->set_offset(reinterpret_cast<intptr_t>(p) - orig_p);\n  }\n  return p;\n}\n\n// Override __libc_memalign in libc on linux boxes.\n// They have a bug in libc that causes them (very rarely) to allocate\n// with __libc_memalign() yet deallocate with free().\n// This function is an exception to the rule of calling MallocHook method\n// from the stack frame of the allocation function;\n// heap-checker handles this special case explicitly.\nstatic void *MemalignOverride(size_t align, size_t size,\n                              const void *caller) __THROW {\n  void *p = do_debug_memalign(align, size);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\nvoid *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;\n\nextern \"C\" void* memalign(size_t align, size_t size) __THROW {\n  void *p = do_debug_memalign(align, size);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\n// Implementation taken from tcmalloc/tcmalloc.cc\nextern \"C\" int posix_memalign(void** result_ptr,\n                              size_t align, size_t size) __THROW {\n  if (((align % sizeof(void*)) != 0) ||\n      ((align & (align - 1)) != 0) ||\n      (align == 0)) {\n    return EINVAL;\n  }\n\n  void* result = do_debug_memalign(align, size);\n  MallocHook::InvokeNewHook(result, size);\n  if (result == NULL) {\n    return ENOMEM;\n  } else {\n    *result_ptr = result;\n    return 0;\n  }\n}\n\nextern \"C\" void* valloc(size_t size) __THROW {\n  // Allocate >= size bytes starting on a page boundary\n  void *p = do_debug_memalign(getpagesize(), size);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\nextern \"C\" void* pvalloc(size_t size) __THROW {\n  // Round size up to a multiple of pages\n  // then allocate memory on a page boundary\n  int pagesize = getpagesize();\n  size = RoundUp(size, pagesize);\n  if (size == 0) {     // pvalloc(0) should allocate one page, according to\n    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html\n  }\n  void *p = do_debug_memalign(pagesize, size);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\nextern \"C\" int mallopt(int cmd, int value) __THROW {\n  return BASE_MALLOPT(cmd, value);\n}\n\n#ifdef HAVE_STRUCT_MALLINFO\nextern \"C\" struct mallinfo mallinfo(void) __THROW {\n  return BASE_MALLINFO();\n}\n#endif\n\n// ========================================================================= //\n\n// Alloc/free stuff for debug operator new & friends\n\n// This is mostly the same a cpp_alloc in tcmalloc.cc.\ninline void* cpp_debug_alloc(size_t size, int new_type, bool nothrow) {\n  for (;;) {\n    void* p = DebugAllocate(size, new_type);\n#ifdef PREANSINEW\n    return p;\n#else\n    if (p == NULL) {  // allocation failed\n      // Get the current new handler.  NB: this function is not\n      // thread-safe.  We make a feeble stab at making it so here, but\n      // this lock only protects against tcmalloc interfering with\n      // itself, not with other libraries calling set_new_handler.\n      std::new_handler nh;\n      {\n        SpinLockHolder h(&set_new_handler_lock);\n        nh = std::set_new_handler(0);\n        (void) std::set_new_handler(nh);\n      }\n#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)\n      if (nh) {\n        // Since exceptions are disabled, we don't really know if new_handler\n        // failed.  Assume it will abort if it fails.\n        (*nh)();\n        continue;\n      }\n      return 0;\n#else\n      // If no new_handler is established, the allocation failed.\n      if (!nh) {\n        if (nothrow) return 0;\n        throw std::bad_alloc();\n      }\n      // Otherwise, try the new_handler.  If it returns, retry the\n      // allocation.  If it throws std::bad_alloc, fail the allocation.\n      // if it throws something else, don't interfere.\n      try {\n        (*nh)();\n      } catch (const std::bad_alloc&) {\n        if (!nothrow) throw;\n        return p;\n      }\n#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)\n    } else {  // allocation success\n      return p;\n    }\n#endif  // PREANSINEW\n  }\n}\n\nvoid* operator new(size_t size) throw (std::bad_alloc) {\n  void* ptr = cpp_debug_alloc(size, MallocBlock::kNewType, false);\n  MallocHook::InvokeNewHook(ptr, size);\n  if (ptr == NULL) {\n    RAW_LOG(FATAL, \"Unable to allocate %\"PRIuS\" bytes: new failed.\", size);\n  }\n  return ptr;\n}\n\nvoid* operator new(size_t size, const std::nothrow_t&) __THROW {\n  void* ptr = cpp_debug_alloc(size, MallocBlock::kNewType, true);\n  MallocHook::InvokeNewHook(ptr, size);\n  return ptr;\n}\n\nvoid operator delete(void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  DebugDeallocate(ptr, MallocBlock::kNewType);\n}\n\n// Some STL implementations explicitly invoke this.\n// It is completely equivalent to a normal delete (delete never throws).\nvoid operator delete(void* ptr, const std::nothrow_t&) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  DebugDeallocate(ptr, MallocBlock::kNewType);\n}\n\n// ========================================================================= //\n\n// Alloc/free stuff for debug operator new[] & friends\n\nvoid* operator new[](size_t size) throw (std::bad_alloc) {\n  void* ptr = cpp_debug_alloc(size, MallocBlock::kArrayNewType, false);\n  MallocHook::InvokeNewHook(ptr, size);\n  if (ptr == NULL) {\n    RAW_LOG(FATAL, \"Unable to allocate %\"PRIuS\" bytes: new[] failed.\", size);\n  }\n  return ptr;\n}\n\nvoid* operator new[](size_t size, const std::nothrow_t&) __THROW {\n  void* ptr = cpp_debug_alloc(size, MallocBlock::kArrayNewType, true);\n  MallocHook::InvokeNewHook(ptr, size);\n  return ptr;\n}\n\nvoid operator delete[](void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  DebugDeallocate(ptr, MallocBlock::kArrayNewType);\n}\n\n// Some STL implementations explicitly invoke this.\n// It is completely equivalent to a normal delete (delete never throws).\nvoid operator delete[](void* ptr, const std::nothrow_t&) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  DebugDeallocate(ptr, MallocBlock::kArrayNewType);\n}\n\n// ========================================================================= //\n\n// The following functions may be called via MallocExtension::instance()\n// for memory verification and statistics.\n#ifdef TCMALLOC_FOR_DEBUGALLOCATION\n// Inherit from tcmalloc's version\ntypedef TCMallocImplementation ParentImplementation;\n#else\n// Inherit from default version\ntypedef MallocExtension ParentImplementation;\n#endif\n\nclass DebugMallocImplementation : public ParentImplementation {\n public:\n  virtual bool GetNumericProperty(const char* name, size_t* value) {\n    bool result = ParentImplementation::GetNumericProperty(name, value);\n    if (result && (strcmp(name, \"generic.current_allocated_bytes\") == 0)) {\n      // Subtract bytes kept in the free queue\n      size_t qsize = MallocBlock::FreeQueueSize();\n      if (*value >= qsize) {\n        *value -= qsize;\n      }\n    }\n    return result;\n  }\n\n  virtual bool VerifyNewMemory(void* p) {\n    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kNewType);\n    return true;\n  }\n\n  virtual bool VerifyArrayNewMemory(void* p) {\n    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kArrayNewType);\n    return true;\n  }\n\n  virtual bool VerifyMallocMemory(void* p) {\n    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kMallocType);\n    return true;\n  }\n\n  virtual bool VerifyAllMemory() {\n    return MallocBlock::CheckEverything();\n  }\n\n  virtual bool MallocMemoryStats(int* blocks, size_t* total,\n                                 int histogram[kMallocHistogramSize]) {\n    return MallocBlock::MemoryStats(blocks, total, histogram);\n  }\n\n  virtual size_t GetAllocatedSize(void* p) {\n    if (p) {\n      return MallocBlock::FromRawPointer(p)->data_size();\n    }\n    return 0;\n  }\n  virtual size_t GetEstimatedAllocatedSize(size_t size) {\n    return size;\n  }\n\n  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {\n    static const char* kDebugFreeQueue = \"debug.free_queue\";\n\n    ParentImplementation::GetFreeListSizes(v);\n\n    MallocExtension::FreeListInfo i;\n    i.type = kDebugFreeQueue;\n    i.min_object_size = 0;\n    i.max_object_size = numeric_limits<size_t>::max();\n    i.total_bytes_free = MallocBlock::FreeQueueSize();\n    v->push_back(i);\n  }\n\n };\n\nstatic DebugMallocImplementation debug_malloc_implementation;\n\nREGISTER_MODULE_INITIALIZER(debugallocation, {\n  // Either we or valgrind will control memory management.  We\n  // register our extension if we're the winner.\n  if (RunningOnValgrind()) {\n    // Let Valgrind uses its own malloc (so don't register our extension).\n  } else {\n    MallocExtension::Register(&debug_malloc_implementation);\n    // When the program exits, check all blocks still in the free\n    // queue for corruption.\n    atexit(DanglingWriteChecker);\n  }\n});\n\n#ifdef TCMALLOC_FOR_DEBUGALLOCATION\n\n// Redefine malloc_stats to use tcmalloc's implementation:\nextern \"C\" void malloc_stats(void) __THROW {\n  do_malloc_stats();\n}\n\n// Some library routines on RedHat 9 allocate memory using malloc()\n// and free it using __libc_free() (or vice-versa).  Since we provide\n// our own implementations of malloc/free using tcmalloc.cc,\n// we need to make sure that the __libc_XXX variants\n// also point to the same implementations.\n//\n// Note: this might not override __libc_XXX calls withing libc itself,\n// but it can be important for other libraries that mention these functions\n// or when this code is LD_PRELOAD-ed.\n// TODO: In case these __libc_* definitions do not actually matter,\n// they should go away from here and from tcmalloc/tcmalloc.cc.\n//\nextern \"C\" {\n  void* __libc_malloc(size_t size)              { return malloc(size);       }\n  void  __libc_free(void* ptr)                  { free(ptr);                 }\n  void* __libc_realloc(void* ptr, size_t size)  { return realloc(ptr, size); }\n  void* __libc_calloc(size_t n, size_t size)    { return calloc(n, size);    }\n  void  __libc_cfree(void* ptr)                 { cfree(ptr);                }\n  void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); }\n  void* __libc_valloc(size_t size)              { return valloc(size);       }\n  void* __libc_pvalloc(size_t size)             { return pvalloc(size);      }\n  int __posix_memalign(void** r, size_t a, size_t s) {\n    return posix_memalign(r, a, s);\n  }\n}\n\n#endif  // #ifdef TCMALLOC_FOR_DEBUGALLOCATION\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/getpc.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// This is an internal header file used by profiler.cc.  It defines\n// the single (inline) function GetPC.  GetPC is used in a signal\n// handler to figure out the instruction that was being executed when\n// the signal-handler was triggered.\n//\n// To get this, we use the ucontext_t argument to the signal-handler\n// callback, which holds the full context of what was going on when\n// the signal triggered.  How to get from a ucontext_t to a Program\n// Counter is OS-dependent.\n\n#ifndef BASE_GETPC_H_\n#define BASE_GETPC_H_\n\n#include \"config.h\"\n\n// On many linux systems, we may need _GNU_SOURCE to get access to\n// the defined constants that define the register we want to see (eg\n// REG_EIP).  Note this #define must come first!\n#define _GNU_SOURCE 1\n// If #define _GNU_SOURCE causes problems, this might work instead.\n// It will cause problems for FreeBSD though!, because it turns off\n// the needed __BSD_VISIBLE.\n//#define _XOPEN_SOURCE 500\n\n#include <string.h>         // for memcmp\n#if defined(HAVE_SYS_UCONTEXT_H)\n#include <sys/ucontext.h>\n#elif defined(HAVE_UCONTEXT_H)\n#include <ucontext.h>       // for ucontext_t (and also mcontext_t)\n#elif defined(HAVE_CYGWIN_SIGNAL_H)\n#include <cygwin/signal.h>\ntypedef ucontext ucontext_t;\n#endif\n\n\n// Take the example where function Foo() calls function Bar().  For\n// many architectures, Bar() is responsible for setting up and tearing\n// down its own stack frame.  In that case, it's possible for the\n// interrupt to happen when execution is in Bar(), but the stack frame\n// is not properly set up (either before it's done being set up, or\n// after it's been torn down but before Bar() returns).  In those\n// cases, the stack trace cannot see the caller function anymore.\n//\n// GetPC can try to identify this situation, on architectures where it\n// might occur, and unwind the current function call in that case to\n// avoid false edges in the profile graph (that is, edges that appear\n// to show a call skipping over a function).  To do this, we hard-code\n// in the asm instructions we might see when setting up or tearing\n// down a stack frame.\n//\n// This is difficult to get right: the instructions depend on the\n// processor, the compiler ABI, and even the optimization level.  This\n// is a best effort patch -- if we fail to detect such a situation, or\n// mess up the PC, nothing happens; the returned PC is not used for\n// any further processing.\nstruct CallUnrollInfo {\n  // Offset from (e)ip register where this instruction sequence\n  // should be matched. Interpreted as bytes. Offset 0 is the next\n  // instruction to execute. Be extra careful with negative offsets in\n  // architectures of variable instruction length (like x86) - it is\n  // not that easy as taking an offset to step one instruction back!\n  int pc_offset;\n  // The actual instruction bytes. Feel free to make it larger if you\n  // need a longer sequence.\n  char ins[16];\n  // How many bytes to match from ins array?\n  int ins_size;\n  // The offset from the stack pointer (e)sp where to look for the\n  // call return address. Interpreted as bytes.\n  int return_sp_offset;\n};\n\n\n// The dereferences needed to get the PC from a struct ucontext were\n// determined at configure time, and stored in the macro\n// PC_FROM_UCONTEXT in config.h.  The only thing we need to do here,\n// then, is to do the magic call-unrolling for systems that support it.\n\n// -- Special case 1: linux x86, for which we have CallUnrollInfo\n#if defined(__linux) && defined(__i386) && defined(__GNUC__)\nstatic const CallUnrollInfo callunrollinfo[] = {\n  // Entry to a function:  push %ebp;  mov  %esp,%ebp\n  // Top-of-stack contains the caller IP.\n  { 0,\n    {0x55, 0x89, 0xe5}, 3,\n    0\n  },\n  // Entry to a function, second instruction:  push %ebp;  mov  %esp,%ebp\n  // Top-of-stack contains the old frame, caller IP is +4.\n  { -1,\n    {0x55, 0x89, 0xe5}, 3,\n    4\n  },\n  // Return from a function: RET.\n  // Top-of-stack contains the caller IP.\n  { 0,\n    {0xc3}, 1,\n    0\n  }\n};\n\ninline void* GetPC(const ucontext_t& signal_ucontext) {\n  // See comment above struct CallUnrollInfo.  Only try instruction\n  // flow matching if both eip and esp looks reasonable.\n  const int eip = signal_ucontext.uc_mcontext.gregs[REG_EIP];\n  const int esp = signal_ucontext.uc_mcontext.gregs[REG_ESP];\n  if ((eip & 0xffff0000) != 0 && (~eip & 0xffff0000) != 0 &&\n      (esp & 0xffff0000) != 0) {\n    char* eip_char = reinterpret_cast<char*>(eip);\n    for (int i = 0; i < sizeof(callunrollinfo)/sizeof(*callunrollinfo); ++i) {\n      if (!memcmp(eip_char + callunrollinfo[i].pc_offset,\n                  callunrollinfo[i].ins, callunrollinfo[i].ins_size)) {\n        // We have a match.\n        void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset);\n        return *retaddr;\n      }\n    }\n  }\n  return (void*)eip;\n}\n\n// Special case #2: Windows, which has to do something totally different.\n#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)\n// If this is ever implemented, probably the way to do it is to have\n// profiler.cc use a high-precision timer via timeSetEvent:\n//    http://msdn2.microsoft.com/en-us/library/ms712713.aspx\n// We'd use it in mode TIME_CALLBACK_FUNCTION/TIME_PERIODIC.\n// The callback function would be something like prof_handler, but\n// alas the arguments are different: no ucontext_t!  I don't know\n// how we'd get the PC (using StackWalk64?)\n//    http://msdn2.microsoft.com/en-us/library/ms680650.aspx\n\n#include \"base/logging.h\"   // for RAW_LOG\n#ifndef HAVE_CYGWIN_SIGNAL_H\ntypedef int ucontext_t;\n#endif\n\ninline void* GetPC(const struct ucontext_t& signal_ucontext) {\n  RAW_LOG(ERROR, \"GetPC is not yet implemented on Windows\\n\");\n  return NULL;\n}\n\n// Normal cases.  If this doesn't compile, it's probably because\n// PC_FROM_UCONTEXT is the empty string.  You need to figure out\n// the right value for your system, and add it to the list in\n// configure.ac (or set it manually in your config.h).\n#else\ninline void* GetPC(const ucontext_t& signal_ucontext) {\n  return (void*)signal_ucontext.PC_FROM_UCONTEXT;   // defined in config.h\n}\n\n#endif\n\n#endif  // BASE_GETPC_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/heap-checker.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Maxim Lifantsev (with design ideas by Sanjay Ghemawat)\n//\n//\n// Module for detecing heap (memory) leaks.\n//\n// For full(er) information, see doc/heap_checker.html\n//\n// This module can be linked into programs with\n// no slowdown caused by this unless you activate the leak-checker:\n//\n//    1. Set the environment variable HEAPCHEK to _type_ before\n//       running the program.\n//\n// _type_ is usually \"normal\" but can also be \"minimal\", \"strict\", or\n// \"draconian\".  (See the html file for other options, like 'local'.)\n//\n// After that, just run your binary.  If the heap-checker detects\n// a memory leak at program-exit, it will print instructions on how\n// to track down the leak.\n\n#ifndef BASE_HEAP_CHECKER_H_\n#define BASE_HEAP_CHECKER_H_\n\n#include <sys/types.h>  // for size_t\n// I can't #include config.h in this public API file, but I should\n// really use configure (and make malloc_extension.h a .in file) to\n// figure out if the system has stdint.h or not.  But I'm lazy, so\n// for now I'm assuming it's a problem only with MSVC.\n#ifndef _MSC_VER\n#include <stdint.h>     // for uintptr_t\n#endif\n#include <stdarg.h>     // for va_list\n#include <vector>\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n\n// The class is thread-safe with respect to all the provided static methods,\n// as well as HeapLeakChecker objects: they can be accessed by multiple threads.\nclass PERFTOOLS_DLL_DECL HeapLeakChecker {\n public:\n\n  // ----------------------------------------------------------------------- //\n  // Static functions for working with (whole-program) leak checking.\n\n  // If heap leak checking is currently active in some mode\n  // e.g. if leak checking was started (and is still active now)\n  // due to HEAPCHECK=... defined in the environment.\n  // The return value reflects iff HeapLeakChecker objects manually\n  // constructed right now will be doing leak checking or nothing.\n  // Note that we can go from active to inactive state during InitGoogle()\n  // if FLAGS_heap_check gets set to \"\" by some code before/during InitGoogle().\n  static bool IsActive();\n\n  // Return pointer to the whole-program checker if it has been created\n  // and NULL otherwise.\n  // Once GlobalChecker() returns non-NULL that object will not disappear and\n  // will be returned by all later GlobalChecker calls.\n  // This is mainly to access BytesLeaked() and ObjectsLeaked() (see below)\n  // for the whole-program checker after one calls NoGlobalLeaks()\n  // or similar and gets false.\n  static HeapLeakChecker* GlobalChecker();\n\n  // Do whole-program leak check now (if it was activated for this binary);\n  // return false only if it was activated and has failed.\n  // The mode of the check is controlled by the command-line flags.\n  // This method can be called repeatedly.\n  // Things like GlobalChecker()->SameHeap() can also be called explicitly\n  // to do the desired flavor of the check.\n  static bool NoGlobalLeaks();\n\n  // If whole-program checker if active,\n  // cancel its automatic execution after main() exits.\n  // This requires that some leak check (e.g. NoGlobalLeaks())\n  // has been called at least once on the whole-program checker.\n  static void CancelGlobalCheck();\n\n  // ----------------------------------------------------------------------- //\n  // Non-static functions for starting and doing leak checking.\n\n  // Start checking and name the leak check performed.\n  // The name is used in naming dumped profiles\n  // and needs to be unique only within your binary.\n  // It must also be a string that can be a part of a file name,\n  // in particular not contain path expressions.\n  explicit HeapLeakChecker(const char *name);\n\n  // Destructor (verifies that some *NoLeaks or *SameHeap method\n  // has been called at least once).\n  ~HeapLeakChecker();\n\n  // These used to be different but are all the same now: they return\n  // true iff all memory allocated since this HeapLeakChecker object\n  // was constructor is still reachable from global state.\n  //\n  // Because we fork to convert addresses to symbol-names, and forking\n  // is not thread-safe, and we may be called in a threaded context,\n  // we do not try to symbolize addresses when called manually.\n  bool NoLeaks() { return DoNoLeaks(DO_NOT_SYMBOLIZE); }\n\n  // These forms are obsolete; use NoLeaks() instead.\n  // TODO(csilvers): mark as DEPRECATED.\n  bool QuickNoLeaks()  { return NoLeaks(); }\n  bool BriefNoLeaks()  { return NoLeaks(); }\n  bool SameHeap()      { return NoLeaks(); }\n  bool QuickSameHeap() { return NoLeaks(); }\n  bool BriefSameHeap() { return NoLeaks(); }\n\n  // Detailed information about the number of leaked bytes and objects\n  // (both of these can be negative as well).\n  // These are available only after a *SameHeap or *NoLeaks\n  // method has been called.\n  // Note that it's possible for both of these to be zero\n  // while SameHeap() or NoLeaks() returned false in case\n  // of a heap state change that is significant\n  // but preserves the byte and object counts.\n  ssize_t BytesLeaked() const;\n  ssize_t ObjectsLeaked() const;\n\n  // ----------------------------------------------------------------------- //\n  // Static helpers to make us ignore certain leaks.\n\n  // Scoped helper class.  Should be allocated on the stack inside a\n  // block of code.  Any heap allocations done in the code block\n  // covered by the scoped object (including in nested function calls\n  // done by the code block) will not be reported as leaks.  This is\n  // the recommended replacement for the GetDisableChecksStart() and\n  // DisableChecksToHereFrom() routines below.\n  //\n  // Example:\n  //   void Foo() {\n  //     HeapLeakChecker::Disabler disabler;\n  //     ... code that allocates objects whose leaks should be ignored ...\n  //   }\n  //\n  // REQUIRES: Destructor runs in same thread as constructor\n  class Disabler {\n   public:\n    Disabler();\n    ~Disabler();\n   private:\n    Disabler(const Disabler&);        // disallow copy\n    void operator=(const Disabler&);  // and assign\n  };\n\n  // Ignore an object located at 'ptr' (can go at the start or into the object)\n  // as well as all heap objects (transitively) referenced from it\n  // for the purposes of heap leak checking.\n  // If 'ptr' does not point to an active allocated object\n  // at the time of this call, it is ignored;\n  // but if it does, the object must not get deleted from the heap later on;\n  // it must also be not already ignored at the time of this call.\n  //\n  // See also HiddenPointer, below, if you need to prevent a pointer from\n  // being traversed by the heap checker but do not wish to transitively\n  // whitelist objects referenced through it.\n  static void IgnoreObject(const void* ptr);\n\n  // Undo what an earlier IgnoreObject() call promised and asked to do.\n  // At the time of this call 'ptr' must point at or inside of an active\n  // allocated object which was previously registered with IgnoreObject().\n  static void UnIgnoreObject(const void* ptr);\n\n  // ----------------------------------------------------------------------- //\n  // Initialization; to be called from main() only.\n\n  // Full starting of recommended whole-program checking.\n  static void InternalInitStart();\n\n  // ----------------------------------------------------------------------- //\n  // Internal types defined in .cc\n\n  class Allocator;\n  struct RangeValue;\n\n private:\n\n  // ----------------------------------------------------------------------- //\n  // Various helpers\n\n  // Create the name of the heap profile file.\n  // Should be deleted via Allocator::Free().\n  char* MakeProfileNameLocked();\n\n  // Helper for constructors\n  void Create(const char *name, bool make_start_snapshot);\n\n  enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE };\n\n  // Helper for *NoLeaks and *SameHeap\n  bool DoNoLeaks(ShouldSymbolize should_symbolize);\n\n  // These used to be public, but they are now deprecated.\n  // Will remove entirely when all internal uses are fixed.\n  // In the meantime, use friendship so the unittest can still test them.\n  static void* GetDisableChecksStart();\n  static void DisableChecksToHereFrom(const void* start_address);\n  static void DisableChecksIn(const char* pattern);\n  friend void RangeDisabledLeaks();\n  friend void NamedTwoDisabledLeaks();\n  friend void* RunNamedDisabledLeaks(void*);\n  friend void TestHeapLeakCheckerNamedDisabling();\n  friend int main(int, char**);\n\n\n  // Helper for DisableChecksIn\n  static void DisableChecksInLocked(const char* pattern);\n\n  // Disable checks based on stack trace entry at a depth <=\n  // max_depth.  Used to hide allocations done inside some special\n  // libraries.\n  static void DisableChecksFromToLocked(const void* start_address,\n                                        const void* end_address,\n                                        int max_depth);\n\n  // Helper for DoNoLeaks to ignore all objects reachable from all live data\n  static void IgnoreAllLiveObjectsLocked(const void* self_stack_top);\n\n  // Callback we pass to ListAllProcessThreads (see thread_lister.h)\n  // that is invoked when all threads of our process are found and stopped.\n  // The call back does the things needed to ignore live data reachable from\n  // thread stacks and registers for all our threads\n  // as well as do other global-live-data ignoring\n  // (via IgnoreNonThreadLiveObjectsLocked)\n  // during the quiet state of all threads being stopped.\n  // For the argument meaning see the comment by ListAllProcessThreads.\n  // Here we only use num_threads and thread_pids, that ListAllProcessThreads\n  // fills for us with the number and pids of all the threads of our process\n  // it found and attached to.\n  static int IgnoreLiveThreadsLocked(void* parameter,\n                                     int num_threads,\n                                     pid_t* thread_pids,\n                                     va_list ap);\n\n  // Helper for IgnoreAllLiveObjectsLocked and IgnoreLiveThreadsLocked\n  // that we prefer to execute from IgnoreLiveThreadsLocked\n  // while all threads are stopped.\n  // This helper does live object discovery and ignoring\n  // for all objects that are reachable from everything\n  // not related to thread stacks and registers.\n  static void IgnoreNonThreadLiveObjectsLocked();\n\n  // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked\n  // to discover and ignore all heap objects\n  // reachable from currently considered live objects\n  // (live_objects static global variable in out .cc file).\n  // \"name\", \"name2\" are two strings that we print one after another\n  // in a debug message to describe what kind of live object sources\n  // are being used.\n  static void IgnoreLiveObjectsLocked(const char* name, const char* name2);\n\n  // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially\n  // calls DoMainHeapCheck\n  static void RunHeapCleanups();\n\n  // Do the overall whole-program heap leak check if needed;\n  // returns true when did the leak check.\n  static bool DoMainHeapCheck();\n\n  // Type of task for UseProcMapsLocked\n  enum ProcMapsTask {\n    RECORD_GLOBAL_DATA,\n    DISABLE_LIBRARY_ALLOCS\n  };\n\n  // Success/Error Return codes for UseProcMapsLocked.\n  enum ProcMapsResult {\n    PROC_MAPS_USED,\n    CANT_OPEN_PROC_MAPS,\n    NO_SHARED_LIBS_IN_PROC_MAPS\n  };\n\n  // Read /proc/self/maps, parse it, and do the 'proc_maps_task' for each line.\n  static ProcMapsResult UseProcMapsLocked(ProcMapsTask proc_maps_task);\n\n  // A ProcMapsTask to disable allocations from 'library'\n  // that is mapped to [start_address..end_address)\n  // (only if library is a certain system library).\n  static void DisableLibraryAllocsLocked(const char* library,\n                                         uintptr_t start_address,\n                                         uintptr_t end_address);\n\n  // Return true iff \"*ptr\" points to a heap object\n  // (\"*ptr\" can point at the start or inside of a heap object\n  //  so that this works e.g. for pointers to C++ arrays, C++ strings,\n  //  multiple-inherited objects, or pointers to members).\n  // We also fill *object_size for this object then\n  // and we move \"*ptr\" to point to the very start of the heap object.\n  static inline bool HaveOnHeapLocked(const void** ptr, size_t* object_size);\n\n  // Helper to shutdown heap leak checker when it's not needed\n  // or can't function properly.\n  static void TurnItselfOffLocked();\n\n  // Internally-used c-tor to start whole-executable checking.\n  HeapLeakChecker();\n\n  // ----------------------------------------------------------------------- //\n  // Friends and externally accessed helpers.\n\n  // Helper for VerifyHeapProfileTableStackGet in the unittest\n  // to get the recorded allocation caller for ptr,\n  // which must be a heap object.\n  static const void* GetAllocCaller(void* ptr);\n  friend void VerifyHeapProfileTableStackGet();\n\n  // This gets to execute before constructors for all global objects\n  static void BeforeConstructorsLocked();\n  friend void HeapLeakChecker_BeforeConstructors();\n\n  // This gets to execute after destructors for all global objects\n  friend void HeapLeakChecker_AfterDestructors();\n\n  // ----------------------------------------------------------------------- //\n  // Member data.\n\n  class SpinLock* lock_;  // to make HeapLeakChecker objects thread-safe\n  const char* name_;  // our remembered name (we own it)\n                      // NULL means this leak checker is a noop\n\n  // Snapshot taken when the checker was created.  May be NULL\n  // for the global heap checker object.  We use void* instead of\n  // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h.\n  void* start_snapshot_;\n\n  bool has_checked_;  // if we have done the leak check, so these are ready:\n  ssize_t inuse_bytes_increase_;  // bytes-in-use increase for this checker\n  ssize_t inuse_allocs_increase_;  // allocations-in-use increase\n                                   // for this checker\n  bool keep_profiles_;  // iff we should keep the heap profiles we've made\n\n  // ----------------------------------------------------------------------- //\n\n  // Disallow \"evil\" constructors.\n  HeapLeakChecker(const HeapLeakChecker&);\n  void operator=(const HeapLeakChecker&);\n};\n\n\n// Holds a pointer that will not be traversed by the heap checker.\n// Contrast with HeapLeakChecker::IgnoreObject(o), in which o and\n// all objects reachable from o are ignored by the heap checker.\ntemplate <class T>\nclass HiddenPointer {\n public:\n  explicit HiddenPointer(T* t)\n      : masked_t_(reinterpret_cast<uintptr_t>(t) ^ kHideMask) {\n  }\n  // Returns unhidden pointer.  Be careful where you save the result.\n  T* get() const { return reinterpret_cast<T*>(masked_t_ ^ kHideMask); }\n\n private:\n  // Arbitrary value, but not such that xor'ing with it is likely\n  // to map one valid pointer to another valid pointer:\n  static const uintptr_t kHideMask =\n      static_cast<uintptr_t>(0xF03A5F7BF03A5F7Bll);\n  uintptr_t masked_t_;\n};\n\n// A class that exists solely to run its destructor.  This class should not be\n// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro below.\nclass PERFTOOLS_DLL_DECL HeapCleaner {\n public:\n  typedef void (*void_function)(void);\n  HeapCleaner(void_function f);\n  static void RunHeapCleanups();\n private:\n  static std::vector<void_function>* heap_cleanups_;\n};\n\n// A macro to declare module heap check cleanup tasks\n// (they run only if we are doing heap leak checking.)\n// 'body' should be the cleanup code to run.  'name' doesn't matter,\n// but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls.\n#define REGISTER_HEAPCHECK_CLEANUP(name, body)  \\\n  namespace { \\\n  void heapcheck_cleanup_##name() { body; } \\\n  static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \\\n  }\n\n#endif  // BASE_HEAP_CHECKER_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/heap-profiler.h",
    "content": "/* Copyright (c) 2005, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n *\n * Module for heap-profiling.\n *\n * For full(er) information, see doc/heapprofile.html\n *\n * This module can be linked into your program with\n * no slowdown caused by this unless you activate the profiler\n * using one of the following methods:\n *\n *    1. Before starting the program, set the environment variable\n *       \"HEAPPROFILE\" to be the name of the file to which the profile\n *       data should be written.\n *\n *    2. Programmatically, start and stop the profiler using the\n *       routines \"HeapProfilerStart(filename)\" and \"HeapProfilerStop()\".\n *\n */\n\n#ifndef BASE_HEAP_PROFILER_H_\n#define BASE_HEAP_PROFILER_H_\n\n#include <stddef.h>\n\n/* Annoying stuff for windows; makes sure clients can import these functions */\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n/* All this code should be usable from within C apps. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Start profiling and arrange to write profile data to file names\n * of the form: \"prefix.0000\", \"prefix.0001\", ...\n */\nPERFTOOLS_DLL_DECL void HeapProfilerStart(const char* prefix);\n\n/* Returns non-zero if we are currently profiling the heap.  (Returns\n * an int rather than a bool so it's usable from C.)  This is true\n * between calls to HeapProfilerStart() and HeapProfilerStop(), and\n * also if the program has been run with HEAPPROFILER, or some other\n * way to turn on whole-program profiling.\n */\nint IsHeapProfilerRunning();\n\n/* Stop heap profiling.  Can be restarted again with HeapProfilerStart(),\n * but the currently accumulated profiling information will be cleared.\n */\nPERFTOOLS_DLL_DECL void HeapProfilerStop();\n\n/* Dump a profile now - can be used for dumping at a hopefully\n * quiescent state in your program, in order to more easily track down\n * memory leaks. Will include the reason in the logged message\n */\nPERFTOOLS_DLL_DECL void HeapProfilerDump(const char *reason);\n\n/* Generate current heap profiling information.\n * Returns an empty string when heap profiling is not active.\n * The returned pointer is a '\\0'-terminated string allocated using malloc()\n * and should be free()-ed as soon as the caller does not need it anymore.\n */\nPERFTOOLS_DLL_DECL char* GetHeapProfile();\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  /* BASE_HEAP_PROFILER_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/malloc_extension.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// Extra extensions exported by some malloc implementations.  These\n// extensions are accessed through a virtual base class so an\n// application can link against a malloc that does not implement these\n// extensions, and it will get default versions that do nothing.\n//\n// NOTE FOR C USERS: If you wish to use this functionality from within\n// a C program, see malloc_extension_c.h.\n\n#ifndef BASE_MALLOC_EXTENSION_H_\n#define BASE_MALLOC_EXTENSION_H_\n\n#include <stddef.h>\n// I can't #include config.h in this public API file, but I should\n// really use configure (and make malloc_extension.h a .in file) to\n// figure out if the system has stdint.h or not.  But I'm lazy, so\n// for now I'm assuming it's a problem only with MSVC.\n#ifndef _MSC_VER\n#include <stdint.h>\n#endif\n#include <string>\n#include <vector>\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\nstatic const int kMallocHistogramSize = 64;\n\n// One day, we could support other types of writers (perhaps for C?)\ntypedef std::string MallocExtensionWriter;\n\nnamespace base {\nstruct MallocRange;\n}\n\n// The default implementations of the following routines do nothing.\n// All implementations should be thread-safe; the current one\n// (TCMallocImplementation) is.\nclass PERFTOOLS_DLL_DECL MallocExtension {\n public:\n  virtual ~MallocExtension();\n\n  // Call this very early in the program execution -- say, in a global\n  // constructor -- to set up parameters and state needed by all\n  // instrumented malloc implemenatations.  One example: this routine\n  // sets environemnt variables to tell STL to use libc's malloc()\n  // instead of doing its own memory management.  This is safe to call\n  // multiple times, as long as each time is before threads start up.\n  static void Initialize();\n\n  // See \"verify_memory.h\" to see what these routines do\n  virtual bool VerifyAllMemory();\n  virtual bool VerifyNewMemory(void* p);\n  virtual bool VerifyArrayNewMemory(void* p);\n  virtual bool VerifyMallocMemory(void* p);\n  virtual bool MallocMemoryStats(int* blocks, size_t* total,\n                                 int histogram[kMallocHistogramSize]);\n\n  // Get a human readable description of the current state of the malloc\n  // data structures.  The state is stored as a null-terminated string\n  // in a prefix of \"buffer[0,buffer_length-1]\".\n  // REQUIRES: buffer_length > 0.\n  virtual void GetStats(char* buffer, int buffer_length);\n\n  // Outputs to \"writer\" a sample of live objects and the stack traces\n  // that allocated these objects.  The format of the returned output\n  // is equivalent to the output of the heap profiler and can\n  // therefore be passed to \"pprof\".\n  // NOTE: by default, tcmalloc does not do any heap sampling, and this\n  //       function will always return an empty sample.  To get useful\n  //       data from GetHeapSample, you must also set the environment\n  //       variable TCMALLOC_SAMPLE_PARAMETER to a value such as 524288.\n  virtual void GetHeapSample(MallocExtensionWriter* writer);\n\n  // Outputs to \"writer\" the stack traces that caused growth in the\n  // address space size.  The format of the returned output is\n  // equivalent to the output of the heap profiler and can therefore\n  // be passed to \"pprof\".  (This does not depend on, or require,\n  // TCMALLOC_SAMPLE_PARAMETER.)\n  virtual void GetHeapGrowthStacks(MallocExtensionWriter* writer);\n\n  // Invokes func(arg, range) for every controlled memory\n  // range.  *range is filled in with information about the range.\n  //\n  // This is a best-effort interface useful only for performance\n  // analysis.  The implementation may not call func at all.\n  typedef void (RangeFunction)(void*, const base::MallocRange*);\n  virtual void Ranges(void* arg, RangeFunction func);\n\n  // -------------------------------------------------------------------\n  // Control operations for getting and setting malloc implementation\n  // specific parameters.  Some currently useful properties:\n  //\n  // generic\n  // -------\n  // \"generic.current_allocated_bytes\"\n  //      Number of bytes currently allocated by application\n  //      This property is not writable.\n  //\n  // \"generic.heap_size\"\n  //      Number of bytes in the heap ==\n  //            current_allocated_bytes +\n  //            fragmentation +\n  //            freed memory regions\n  //      This property is not writable.\n  //\n  // tcmalloc\n  // --------\n  // \"tcmalloc.max_total_thread_cache_bytes\"\n  //      Upper limit on total number of bytes stored across all\n  //      per-thread caches.  Default: 16MB.\n  //\n  // \"tcmalloc.current_total_thread_cache_bytes\"\n  //      Number of bytes used across all thread caches.\n  //      This property is not writable.\n  //\n  // \"tcmalloc.pageheap_free_bytes\"\n  //      Number of bytes in free, mapped pages in page heap.  These\n  //      bytes can be used to fulfill allocation requests.  They\n  //      always count towards virtual memory usage, and unless the\n  //      underlying memory is swapped out by the OS, they also count\n  //      towards physical memory usage.  This property is not writable.\n  //\n  // \"tcmalloc.pageheap_unmapped_bytes\"\n  //        Number of bytes in free, unmapped pages in page heap.\n  //        These are bytes that have been released back to the OS,\n  //        possibly by one of the MallocExtension \"Release\" calls.\n  //        They can be used to fulfill allocation requests, but\n  //        typically incur a page fault.  They always count towards\n  //        virtual memory usage, and depending on the OS, typically\n  //        do not count towards physical memory usage.  This property\n  //        is not writable.\n  // -------------------------------------------------------------------\n\n  // Get the named \"property\"'s value.  Returns true if the property\n  // is known.  Returns false if the property is not a valid property\n  // name for the current malloc implementation.\n  // REQUIRES: property != NULL; value != NULL\n  virtual bool GetNumericProperty(const char* property, size_t* value);\n\n  // Set the named \"property\"'s value.  Returns true if the property\n  // is known and writable.  Returns false if the property is not a\n  // valid property name for the current malloc implementation, or\n  // is not writable.\n  // REQUIRES: property != NULL\n  virtual bool SetNumericProperty(const char* property, size_t value);\n\n  // Mark the current thread as \"idle\".  This routine may optionally\n  // be called by threads as a hint to the malloc implementation that\n  // any thread-specific resources should be released.  Note: this may\n  // be an expensive routine, so it should not be called too often.\n  //\n  // Also, if the code that calls this routine will go to sleep for\n  // a while, it should take care to not allocate anything between\n  // the call to this routine and the beginning of the sleep.\n  //\n  // Most malloc implementations ignore this routine.\n  virtual void MarkThreadIdle();\n\n  // Mark the current thread as \"busy\".  This routine should be\n  // called after MarkThreadIdle() if the thread will now do more\n  // work.  If this method is not called, performance may suffer.\n  //\n  // Most malloc implementations ignore this routine.\n  virtual void MarkThreadBusy();\n\n  // Try to release num_bytes of free memory back to the operating\n  // system for reuse.  Use this extension with caution -- to get this\n  // memory back may require faulting pages back in by the OS, and\n  // that may be slow.  (Currently only implemented in tcmalloc.)\n  virtual void ReleaseToSystem(size_t num_bytes);\n\n  // Same as ReleaseToSystem() but release as much memory as possible.\n  virtual void ReleaseFreeMemory();\n\n  // Sets the rate at which we release unused memory to the system.\n  // Zero means we never release memory back to the system.  Increase\n  // this flag to return memory faster; decrease it to return memory\n  // slower.  Reasonable rates are in the range [0,10].  (Currently\n  // only implemented in tcmalloc).\n  virtual void SetMemoryReleaseRate(double rate);\n\n  // Gets the release rate.  Returns a value < 0 if unknown.\n  virtual double GetMemoryReleaseRate();\n\n  // Returns the estimated number of bytes that will be allocated for\n  // a request of \"size\" bytes.  This is an estimate: an allocation of\n  // SIZE bytes may reserve more bytes, but will never reserve less.\n  // (Currently only implemented in tcmalloc, other implementations\n  // always return SIZE.)\n  // This is equivalent to malloc_good_size() in OS X.\n  virtual size_t GetEstimatedAllocatedSize(size_t size);\n\n  // Returns the actual number N of bytes reserved by tcmalloc for the\n  // pointer p.  The client is allowed to use the range of bytes\n  // [p, p+N) in any way it wishes (i.e. N is the \"usable size\" of this\n  // allocation).  This number may be equal to or greater than the number\n  // of bytes requested when p was allocated.\n  // p must have been allocated by this malloc implementation,\n  // must not be an interior pointer -- that is, must be exactly\n  // the pointer returned to by malloc() et al., not some offset\n  // from that -- and should not have been freed yet.  p may be NULL.\n  // (Currently only implemented in tcmalloc; other implementations\n  // will return 0.)\n  // This is equivalent to malloc_size() in OS X, malloc_usable_size()\n  // in glibc, and _msize() for windows.\n  virtual size_t GetAllocatedSize(void* p);\n\n  // The current malloc implementation.  Always non-NULL.\n  static MallocExtension* instance();\n\n  // Change the malloc implementation.  Typically called by the\n  // malloc implementation during initialization.\n  static void Register(MallocExtension* implementation);\n\n  // Returns detailed information about malloc's freelists. For each list,\n  // return a FreeListInfo:\n  struct FreeListInfo {\n    size_t min_object_size;\n    size_t max_object_size;\n    size_t total_bytes_free;\n    const char* type;\n  };\n  // Each item in the vector refers to a different freelist. The lists\n  // are identified by the range of allocations that objects in the\n  // list can satisfy ([min_object_size, max_object_size]) and the\n  // type of freelist (see below). The current size of the list is\n  // returned in total_bytes_free (which count against a processes\n  // resident and virtual size).\n  //\n  // Currently supported types are:\n  //\n  // \"tcmalloc.page{_unmapped}\" - tcmalloc's page heap. An entry for each size\n  //          class in the page heap is returned. Bytes in \"page_unmapped\"\n  //          are no longer backed by physical memory and do not count against\n  //          the resident size of a process.\n  //\n  // \"tcmalloc.large{_unmapped}\" - tcmalloc's list of objects larger\n  //          than the largest page heap size class. Only one \"large\"\n  //          entry is returned. There is no upper-bound on the size\n  //          of objects in the large free list; this call returns\n  //          kint64max for max_object_size.  Bytes in\n  //          \"large_unmapped\" are no longer backed by physical memory\n  //          and do not count against the resident size of a process.\n  //\n  // \"tcmalloc.central\" - tcmalloc's central free-list. One entry per\n  //          size-class is returned. Never unmapped.\n  //\n  // \"debug.free_queue\" - free objects queued by the debug allocator\n  //                      and not returned to tcmalloc.\n  //\n  // \"tcmalloc.thread\" - tcmalloc's per-thread caches. Never unmapped.\n  virtual void GetFreeListSizes(std::vector<FreeListInfo>* v);\n\n protected:\n  // Get a list of stack traces of sampled allocation points.  Returns\n  // a pointer to a \"new[]-ed\" result array, and stores the sample\n  // period in \"sample_period\".\n  //\n  // The state is stored as a sequence of adjacent entries\n  // in the returned array.  Each entry has the following form:\n  //    uintptr_t count;        // Number of objects with following trace\n  //    uintptr_t size;         // Total size of objects with following trace\n  //    uintptr_t depth;        // Number of PC values in stack trace\n  //    void*     stack[depth]; // PC values that form the stack trace\n  //\n  // The list of entries is terminated by a \"count\" of 0.\n  //\n  // It is the responsibility of the caller to \"delete[]\" the returned array.\n  //\n  // May return NULL to indicate no results.\n  //\n  // This is an internal extension.  Callers should use the more\n  // convenient \"GetHeapSample(string*)\" method defined above.\n  virtual void** ReadStackTraces(int* sample_period);\n\n  // Like ReadStackTraces(), but returns stack traces that caused growth\n  // in the address space size.\n  virtual void** ReadHeapGrowthStackTraces();\n};\n\nnamespace base {\n\n// Information passed per range.  More fields may be added later.\nstruct MallocRange {\n  enum Type {\n    INUSE,                // Application is using this range\n    FREE,                 // Range is currently free\n    UNMAPPED,             // Backing physical memory has been returned to the OS\n    UNKNOWN,\n    // More enum values may be added in the future\n  };\n\n  uintptr_t address;    // Address of range\n  size_t length;        // Byte length of range\n  Type type;            // Type of this range\n  double fraction;      // Fraction of range that is being used (0 if !INUSE)\n\n  // Perhaps add the following:\n  // - stack trace if this range was sampled\n  // - heap growth stack trace if applicable to this range\n  // - age when allocated (for inuse) or freed (if not in use)\n};\n\n} // namespace base\n\n#endif  // BASE_MALLOC_EXTENSION_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/malloc_extension_c.h",
    "content": "/* Copyright (c) 2008, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * --\n * Author: Craig Silverstein\n *\n * C shims for the C++ malloc_extension.h.  See malloc_extension.h for\n * details.  Note these C shims always work on\n * MallocExtension::instance(); it is not possible to have more than\n * one MallocExtension object in C applications.\n */\n\n#ifndef _MALLOC_EXTENSION_C_H_\n#define _MALLOC_EXTENSION_C_H_\n\n#include <stddef.h>\n#include <sys/types.h>\n\n/* Annoying stuff for windows -- makes sure clients can import these fns */\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define kMallocExtensionHistogramSize 64\n\nPERFTOOLS_DLL_DECL int MallocExtension_VerifyAllMemory(void);\nPERFTOOLS_DLL_DECL int MallocExtension_VerifyNewMemory(void* p);\nPERFTOOLS_DLL_DECL int MallocExtension_VerifyArrayNewMemory(void* p);\nPERFTOOLS_DLL_DECL int MallocExtension_VerifyMallocMemory(void* p);\nPERFTOOLS_DLL_DECL int MallocExtension_MallocMemoryStats(int* blocks, size_t* total,\n                                      int histogram[kMallocExtensionHistogramSize]);\nPERFTOOLS_DLL_DECL void MallocExtension_GetStats(char* buffer, int buffer_length);\n\n/* TODO(csilvers): write a C version of these routines, that perhaps\n * takes a function ptr and a void *.\n */\n/* void MallocExtension_GetHeapSample(string* result); */\n/* void MallocExtension_GetHeapGrowthStacks(string* result); */\n\nPERFTOOLS_DLL_DECL int MallocExtension_GetNumericProperty(const char* property, size_t* value);\nPERFTOOLS_DLL_DECL int MallocExtension_SetNumericProperty(const char* property, size_t value);\nPERFTOOLS_DLL_DECL void MallocExtension_MarkThreadIdle(void);\nPERFTOOLS_DLL_DECL void MallocExtension_MarkThreadBusy(void);\nPERFTOOLS_DLL_DECL void MallocExtension_ReleaseToSystem(size_t num_bytes);\nPERFTOOLS_DLL_DECL void MallocExtension_ReleaseFreeMemory(void);\nPERFTOOLS_DLL_DECL size_t MallocExtension_GetEstimatedAllocatedSize(size_t size);\nPERFTOOLS_DLL_DECL size_t MallocExtension_GetAllocatedSize(void* p);\n\n#ifdef __cplusplus\n}   // extern \"C\"\n#endif\n\n#endif /* _MALLOC_EXTENSION_C_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/malloc_hook.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Some of our malloc implementations can invoke the following hooks\n// whenever memory is allocated or deallocated.  If the hooks are\n// NULL, they are not invoked.  MallocHook is thread-safe, and things\n// you do before calling SetFooHook(MyHook) are visible to any\n// resulting calls to MyHook.  Hooks must be thread-safe, and if you\n// write:\n//\n//   MallocHook::NewHook old_new_hook_ = NULL;\n//   ...\n//   old_new_hook_ = MallocHook::SetNewHook(&MyNewHook);\n//\n// old_new_hook_ could still be NULL the first couple times MyNewHook\n// is called.\n//\n// One important user of these hooks is the heap profiler.\n//\n// CAVEAT: If you add new MallocHook::Invoke* calls (not for chaining hooks),\n// then those calls must be directly in the code of the (de)allocation\n// function that is provided to the user and that function must have\n// an ATTRIBUTE_SECTION(malloc_hook) attribute.\n//\n// Note: Get*Hook() and Invoke*Hook() functions are defined in\n// malloc_hook-inl.h.  If you need to get or invoke a hook (which you\n// shouldn't unless you're part of tcmalloc), be sure to #include\n// malloc_hook-inl.h in addition to malloc_hook.h.\n//\n// NOTE FOR C USERS: If you want to use malloc_hook functionality from\n// a C program, #include malloc_hook_c.h instead of this file.\n//\n// TODO(csilvers): support a non-inlined function called\n// Assert*HookIs()?  This is the context in which I normally see\n// Get*Hook() called in non-tcmalloc code.\n\n#ifndef _MALLOC_HOOK_H_\n#define _MALLOC_HOOK_H_\n\n#include <stddef.h>\n#include <sys/types.h>\nextern \"C\" {\n#include <google/malloc_hook_c.h>  // a C version of the malloc_hook interface\n}\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n// Note: malloc_hook_c.h defines MallocHook_*Hook and\n// MallocHook_Set*Hook.  The version of these inside the MallocHook\n// class are defined in terms of the malloc_hook_c version.  See\n// malloc_hook_c.h for details of these types/functions.\n\nclass PERFTOOLS_DLL_DECL MallocHook {\n public:\n  // The NewHook is invoked whenever an object is allocated.\n  // It may be passed NULL if the allocator returned NULL.\n  typedef MallocHook_NewHook NewHook;\n  inline static NewHook GetNewHook();\n  inline static NewHook SetNewHook(NewHook hook) {\n    return MallocHook_SetNewHook(hook);\n  }\n  inline static void InvokeNewHook(const void* p, size_t s);\n\n  // The DeleteHook is invoked whenever an object is deallocated.\n  // It may be passed NULL if the caller is trying to delete NULL.\n  typedef MallocHook_DeleteHook DeleteHook;\n  inline static DeleteHook GetDeleteHook();\n  inline static DeleteHook SetDeleteHook(DeleteHook hook) {\n    return MallocHook_SetDeleteHook(hook);\n  }\n  inline static void InvokeDeleteHook(const void* p);\n\n  // The PreMmapHook is invoked with mmap or mmap64 arguments just\n  // before the call is actually made.  Such a hook may be useful\n  // in memory limited contexts, to catch allocations that will exceed\n  // a memory limit, and take outside actions to increase that limit.\n  typedef MallocHook_PreMmapHook PreMmapHook;\n  inline static PreMmapHook GetPreMmapHook();\n  inline static PreMmapHook SetPreMmapHook(PreMmapHook hook) {\n    return MallocHook_SetPreMmapHook(hook);\n  }\n  inline static void InvokePreMmapHook(const void* start,\n                                       size_t size,\n                                       int protection,\n                                       int flags,\n                                       int fd,\n                                       off_t offset);\n\n  // The MmapHook is invoked whenever a region of memory is mapped.\n  // It may be passed MAP_FAILED if the mmap failed.\n  typedef MallocHook_MmapHook MmapHook;\n  inline static MmapHook GetMmapHook();\n  inline static MmapHook SetMmapHook(MmapHook hook) {\n    return MallocHook_SetMmapHook(hook);\n  }\n  inline static void InvokeMmapHook(const void* result,\n                                    const void* start,\n                                    size_t size,\n                                    int protection,\n                                    int flags,\n                                    int fd,\n                                    off_t offset);\n\n  // The MunmapHook is invoked whenever a region of memory is unmapped.\n  typedef MallocHook_MunmapHook MunmapHook;\n  inline static MunmapHook GetMunmapHook();\n  inline static MunmapHook SetMunmapHook(MunmapHook hook) {\n    return MallocHook_SetMunmapHook(hook);\n  }\n  inline static void InvokeMunmapHook(const void* p, size_t size);\n\n  // The MremapHook is invoked whenever a region of memory is remapped.\n  typedef MallocHook_MremapHook MremapHook;\n  inline static MremapHook GetMremapHook();\n  inline static MremapHook SetMremapHook(MremapHook hook) {\n    return MallocHook_SetMremapHook(hook);\n  }\n  inline static void InvokeMremapHook(const void* result,\n                                      const void* old_addr,\n                                      size_t old_size,\n                                      size_t new_size,\n                                      int flags,\n                                      const void* new_addr);\n\n  // The PreSbrkHook is invoked just before sbrk is called -- except when\n  // the increment is 0.  This is because sbrk(0) is often called\n  // to get the top of the memory stack, and is not actually a\n  // memory-allocation call.  It may be useful in memory-limited contexts,\n  // to catch allocations that will exceed the limit and take outside\n  // actions to increase such a limit.\n  typedef MallocHook_PreSbrkHook PreSbrkHook;\n  inline static PreSbrkHook GetPreSbrkHook();\n  inline static PreSbrkHook SetPreSbrkHook(PreSbrkHook hook) {\n    return MallocHook_SetPreSbrkHook(hook);\n  }\n  inline static void InvokePreSbrkHook(ptrdiff_t increment);\n\n  // The SbrkHook is invoked whenever sbrk is called -- except when\n  // the increment is 0.  This is because sbrk(0) is often called\n  // to get the top of the memory stack, and is not actually a\n  // memory-allocation call.\n  typedef MallocHook_SbrkHook SbrkHook;\n  inline static SbrkHook GetSbrkHook();\n  inline static SbrkHook SetSbrkHook(SbrkHook hook) {\n    return MallocHook_SetSbrkHook(hook);\n  }\n  inline static void InvokeSbrkHook(const void* result, ptrdiff_t increment);\n\n  // Get the current stack trace.  Try to skip all routines up to and\n  // and including the caller of MallocHook::Invoke*.\n  // Use \"skip_count\" (similarly to GetStackTrace from stacktrace.h)\n  // as a hint about how many routines to skip if better information\n  // is not available.\n  inline static int GetCallerStackTrace(void** result, int max_depth,\n                                        int skip_count) {\n    return MallocHook_GetCallerStackTrace(result, max_depth, skip_count);\n  }\n\n  // Unhooked versions of mmap() and munmap().   These should be used\n  // only by experts, since they bypass heapchecking, etc.\n  static void* UnhookedMMap(void *start, size_t length, int prot, int flags,\n                            int fd, off_t offset);\n  static int UnhookedMUnmap(void *start, size_t length);\n};\n\n#endif /* _MALLOC_HOOK_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/malloc_hook_c.h",
    "content": "/* Copyright (c) 2008, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * --\n * Author: Craig Silverstein\n *\n * C shims for the C++ malloc_hook.h.  See malloc_hook.h for details\n * on how to use these.\n */\n\n#ifndef _MALLOC_HOOK_C_H_\n#define _MALLOC_HOOK_C_H_\n\n#include <stddef.h>\n#include <sys/types.h>\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n/* Get the current stack trace.  Try to skip all routines up to and\n * and including the caller of MallocHook::Invoke*.\n * Use \"skip_count\" (similarly to GetStackTrace from stacktrace.h)\n * as a hint about how many routines to skip if better information\n * is not available.\n */\nPERFTOOLS_DLL_DECL\nint MallocHook_GetCallerStackTrace(void** result, int max_depth,\n                                   int skip_count);\n\n\ntypedef void (*MallocHook_NewHook)(const void* ptr, size_t size);\nPERFTOOLS_DLL_DECL\nMallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook);\n\ntypedef void (*MallocHook_DeleteHook)(const void* ptr);\nPERFTOOLS_DLL_DECL\nMallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook);\n\ntypedef void (*MallocHook_PreMmapHook)(const void *start,\n                                       size_t size,\n                                       int protection,\n                                       int flags,\n                                       int fd,\n                                       off_t offset);\nPERFTOOLS_DLL_DECL\nMallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook);\n\ntypedef void (*MallocHook_MmapHook)(const void* result,\n                                    const void* start,\n                                    size_t size,\n                                    int protection,\n                                    int flags,\n                                    int fd,\n                                    off_t offset);\nPERFTOOLS_DLL_DECL\nMallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook);\n\ntypedef void (*MallocHook_MunmapHook)(const void* ptr, size_t size);\nPERFTOOLS_DLL_DECL\nMallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook);\n\ntypedef void (*MallocHook_MremapHook)(const void* result,\n                                      const void* old_addr,\n                                      size_t old_size,\n                                      size_t new_size,\n                                      int flags,\n                                      const void* new_addr);\nPERFTOOLS_DLL_DECL\nMallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook);\n\ntypedef void (*MallocHook_PreSbrkHook)(ptrdiff_t increment);\nPERFTOOLS_DLL_DECL\nMallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook);\n\ntypedef void (*MallocHook_SbrkHook)(const void* result, ptrdiff_t increment);\nPERFTOOLS_DLL_DECL\nMallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook);\n\n#endif /* _MALLOC_HOOK_C_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/profiler.h",
    "content": "/* Copyright (c) 2005, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n *\n * Module for CPU profiling based on periodic pc-sampling.\n *\n * For full(er) information, see doc/cpuprofile.html\n *\n * This module is linked into your program with\n * no slowdown caused by this unless you activate the profiler\n * using one of the following methods:\n *\n *    1. Before starting the program, set the environment variable\n *       \"PROFILE\" to be the name of the file to which the profile\n *       data should be written.\n *\n *    2. Programmatically, start and stop the profiler using the\n *       routines \"ProfilerStart(filename)\" and \"ProfilerStop()\".\n *\n *\n * (Note: if using linux 2.4 or earlier, only the main thread may be\n * profiled.)\n *\n * Use pprof to view the resulting profile output.\n *    % pprof <path_to_executable> <profile_file_name>\n *    % pprof --gv  <path_to_executable> <profile_file_name>\n *\n * These functions are thread-safe.\n */\n\n#ifndef BASE_PROFILER_H_\n#define BASE_PROFILER_H_\n\n#include <time.h>       /* For time_t */\n\n/* Annoying stuff for windows; makes sure clients can import these functions */\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n/* All this code should be usable from within C apps. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Profiler options, for use with ProfilerStartWithOptions.  To use:\n *\n *   struct ProfilerOptions options;\n *   memset(&options, 0, sizeof options);\n *\n * then fill in fields as needed.\n *\n * This structure is intended to be usable from C code, so no constructor\n * is provided to initialize it.  (Use memset as described above).\n */\nstruct ProfilerOptions {\n  /* Filter function and argument.\n   *\n   * If filter_in_thread is not NULL, when a profiling tick is delivered\n   * the profiler will call:\n   *\n   *   (*filter_in_thread)(filter_in_thread_arg)\n   *\n   * If it returns nonzero, the sample will be included in the profile.\n   * Note that filter_in_thread runs in a signal handler, so must be\n   * async-signal-safe.\n   *\n   * A typical use would be to set up filter results for each thread\n   * in the system before starting the profiler, then to make\n   * filter_in_thread be a very simple function which retrieves those\n   * results in an async-signal-safe way.  Retrieval could be done\n   * using thread-specific data, or using a shared data structure that\n   * supports async-signal-safe lookups.\n   */\n  int (*filter_in_thread)(void *arg);\n  void *filter_in_thread_arg;\n};\n\n/* Start profiling and write profile info into fname, discarding any\n * existing profiling data in that file.\n *\n * This is equivalent to calling ProfilerStartWithOptions(fname, NULL).\n */\nPERFTOOLS_DLL_DECL int ProfilerStart(const char* fname);\n\n/* Start profiling and write profile into fname, discarding any\n * existing profiling data in that file.\n *\n * The profiler is configured using the options given by 'options'.\n * Options which are not specified are given default values.\n *\n * 'options' may be NULL, in which case all are given default values.\n *\n * Returns nonzero if profiling was started sucessfully, or zero else.\n */\nPERFTOOLS_DLL_DECL int ProfilerStartWithOptions(\n    const char *fname, const struct ProfilerOptions *options);\n\n/* Stop profiling. Can be started again with ProfilerStart(), but\n * the currently accumulated profiling data will be cleared.\n */\nPERFTOOLS_DLL_DECL void ProfilerStop();\n\n/* Flush any currently buffered profiling state to the profile file.\n * Has no effect if the profiler has not been started.\n */\nPERFTOOLS_DLL_DECL void ProfilerFlush();\n\n\n/* DEPRECATED: these functions were used to enable/disable profiling\n * in the current thread, but no longer do anything.\n */\nPERFTOOLS_DLL_DECL void ProfilerEnable();\nPERFTOOLS_DLL_DECL void ProfilerDisable();\n\n/* Returns nonzero if profile is currently enabled, zero if it's not. */\nPERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads();\n\n/* Routine for registering new threads with the profiler.\n */\nPERFTOOLS_DLL_DECL void ProfilerRegisterThread();\n\n/* Stores state about profiler's current status into \"*state\". */\nstruct ProfilerState {\n  int    enabled;             /* Is profiling currently enabled? */\n  time_t start_time;          /* If enabled, when was profiling started? */\n  char   profile_name[1024];  /* Name of profile file being written, or '\\0' */\n  int    samples_gathered;    /* Number of samples gatheered to far (or 0) */\n};\nPERFTOOLS_DLL_DECL void ProfilerGetCurrentState(struct ProfilerState* state);\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  /* BASE_PROFILER_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/stacktrace.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Routines to extract the current stack trace.  These functions are\n// thread-safe.\n\n#ifndef GOOGLE_STACKTRACE_H_\n#define GOOGLE_STACKTRACE_H_\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n\n// Skips the most recent \"skip_count\" stack frames (also skips the\n// frame generated for the \"GetStackFrames\" routine itself), and then\n// records the pc values for up to the next \"max_depth\" frames in\n// \"result\", and the corresponding stack frame sizes in \"sizes\".\n// Returns the number of values recorded in \"result\"/\"sizes\".\n//\n// Example:\n//      main() { foo(); }\n//      foo() { bar(); }\n//      bar() {\n//        void* result[10];\n//        int sizes[10];\n//        int depth = GetStackFrames(result, sizes, 10, 1);\n//      }\n//\n// The GetStackFrames call will skip the frame for \"bar\".  It will\n// return 2 and will produce pc values that map to the following\n// procedures:\n//      result[0]       foo\n//      result[1]       main\n// (Actually, there may be a few more entries after \"main\" to account for\n// startup procedures.)\n// And corresponding stack frame sizes will also be recorded:\n//    sizes[0]       16\n//    sizes[1]       16\n// (Stack frame sizes of 16 above are just for illustration purposes.)\n// Stack frame sizes of 0 or less indicate that those frame sizes couldn't\n// be identified.\n//\n// This routine may return fewer stack frame entries than are\n// available. Also note that \"result\" and \"sizes\" must both be non-NULL.\nextern PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,\n                          int skip_count);\n\n// Same as above, but to be used from a signal handler. The \"uc\" parameter\n// should be the pointer to ucontext_t which was passed as the 3rd parameter\n// to sa_sigaction signal handler. It may help the unwinder to get a\n// better stack trace under certain conditions. The \"uc\" may safely be NULL.\nextern PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,\n                                     int skip_count, const void *uc);\n\n// This is similar to the GetStackFrames routine, except that it returns\n// the stack trace only, and not the stack frame sizes as well.\n// Example:\n//      main() { foo(); }\n//      foo() { bar(); }\n//      bar() {\n//        void* result[10];\n//        int depth = GetStackTrace(result, 10, 1);\n//      }\n//\n// This produces:\n//      result[0]       foo\n//      result[1]       main\n//           ....       ...\n//\n// \"result\" must not be NULL.\nextern PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,\n                                            int skip_count);\n\n// Same as above, but to be used from a signal handler. The \"uc\" parameter\n// should be the pointer to ucontext_t which was passed as the 3rd parameter\n// to sa_sigaction signal handler. It may help the unwinder to get a\n// better stack trace under certain conditions. The \"uc\" may safely be NULL.\nextern PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,\n                                    int skip_count, const void *uc);\n\n#endif /* GOOGLE_STACKTRACE_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/google/tcmalloc.h.in",
    "content": "/* Copyright (c) 2003, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat <opensource@google.com>\n *         .h file by Craig Silverstein <opensource@google.com>\n */\n\n#ifndef TCMALLOC_TCMALLOC_H_\n#define TCMALLOC_TCMALLOC_H_\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    /* I guess we're not on a glibc system */\n# define __THROW   /* __THROW is just an optimization, so ok to make it \"\" */\n#endif\n\n// Define the version number so folks can check against it\n#define TC_VERSION_MAJOR  @TC_VERSION_MAJOR@\n#define TC_VERSION_MINOR  @TC_VERSION_MINOR@\n#define TC_VERSION_PATCH  \"@TC_VERSION_PATCH@\"\n#define TC_VERSION_STRING \"google-perftools @TC_VERSION_MAJOR@.@TC_VERSION_MINOR@@TC_VERSION_PATCH@\"\n\n#include <stdlib.h>   // for struct mallinfo, if it's defined\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n#ifdef __cplusplus\n#include <new>          // for std::nothrow_t\n\nextern \"C\" {\n#endif\n  // Returns a human-readable version string.  If major, minor,\n  // and/or patch are not NULL, they are set to the major version,\n  // minor version, and patch-code (a string, usually \"\").\n  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,\n                                            const char** patch) __THROW;\n\n  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW;\n\n  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,\n                                       size_t __size) __THROW;\n  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,\n                                           size_t align, size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) __THROW;\n\n  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW;\n  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW;\n#if @ac_cv_have_struct_mallinfo@\n  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW;\n#endif\n\n  // This is an alias for MallocExtension::instance()->GetAllocatedSize().\n  // It is equivalent to\n  //    OS X: malloc_size()\n  //    glibc: malloc_usable_size()\n  //    Windows: _msize()\n  size_t tc_malloc_size(void* ptr) __THROW;\n\n#ifdef __cplusplus\n  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_new(size_t size);\n  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,\n                                          const std::nothrow_t&) __THROW;\n  PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;\n  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,\n                                            const std::nothrow_t&) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);\n  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,\n                                               const std::nothrow_t&) __THROW;\n  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;\n  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,\n                                                 const std::nothrow_t&) __THROW;\n}\n#endif\n\n#endif  // #ifndef TCMALLOC_TCMALLOC_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/heap-checker-bcad.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// All Rights Reserved.\n//\n// Author: Maxim Lifantsev\n//\n// A file to ensure that components of heap leak checker run before\n// all global object constructors and after all global object\n// destructors.\n//\n// This file must be the last library any binary links against.\n// Otherwise, the heap checker may not be able to run early enough to\n// catalog all the global objects in your program.  If this happens,\n// and later in the program you allocate memory and have one of these\n// \"uncataloged\" global objects point to it, the heap checker will\n// consider that allocation to be a leak, even though it's not (since\n// the allocated object is reachable from global data and hence \"live\").\n\n#include <stdlib.h>      // for abort()\n#include <google/malloc_extension.h>\n\n// A dummy variable to refer from heap-checker.cc.  This is to make\n// sure this file is not optimized out by the linker.\nbool heap_leak_checker_bcad_variable;\n\nextern void HeapLeakChecker_BeforeConstructors();  // in heap-checker.cc\nextern void HeapLeakChecker_AfterDestructors();  // in heap-checker.cc\n\n// A helper class to ensure that some components of heap leak checking\n// can happen before construction and after destruction\n// of all global/static objects.\nclass HeapLeakCheckerGlobalPrePost {\n public:\n  HeapLeakCheckerGlobalPrePost() {\n    if (count_ == 0) {\n      HeapLeakChecker_BeforeConstructors();\n      // This needs to be called before the first allocation of an STL\n      // object, but after libc is done setting up threads (because it\n      // calls setenv, which requires a thread-aware errno).  By\n      // putting it here, we hope it's the first bit of code executed\n      // after the libc global-constructor code.\n      MallocExtension::Initialize();\n    }\n    ++count_;\n  }\n  ~HeapLeakCheckerGlobalPrePost() {\n    if (count_ <= 0)  abort();\n    --count_;\n    if (count_ == 0)  HeapLeakChecker_AfterDestructors();\n  }\n private:\n  // Counter of constructions/destructions of objects of this class\n  // (just in case there are more than one of them).\n  static int count_;\n};\n\nint HeapLeakCheckerGlobalPrePost::count_ = 0;\n\n// The early-construction/late-destruction global object.\nstatic const HeapLeakCheckerGlobalPrePost heap_leak_checker_global_pre_post;\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/heap-checker.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// All Rights Reserved.\n//\n// Author: Maxim Lifantsev\n//\n\n#include \"config.h\"\n\n#include <fcntl.h>    // for O_RDONLY (we use syscall to do actual reads)\n#include <string.h>\n#include <errno.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#endif\n#ifdef HAVE_PTHREAD\n#include <pthread.h>\n#endif\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <time.h>\n#include <assert.h>\n\n#ifdef HAVE_LINUX_PTRACE_H\n#include <linux/ptrace.h>\n#endif\n#ifdef HAVE_SYS_SYSCALL_H\n#include <sys/syscall.h>\n#endif\n#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)\n#include <wtypes.h>\n#include <winbase.h>\n#undef ERROR     // windows defines these as macros, which can cause trouble\n#undef max\n#undef min\n#endif\n\n#include <string>\n#include <vector>\n#include <map>\n#include <set>\n#include <algorithm>\n#include <functional>\n\n#include <google/heap-checker.h>\n\n#include \"base/basictypes.h\"\n#include \"base/googleinit.h\"\n#include \"base/logging.h\"\n#include <google/stacktrace.h>\n#include \"base/commandlineflags.h\"\n#include \"base/elfcore.h\"              // for i386_regs\n#include \"base/thread_lister.h\"\n#include \"heap-profile-table.h\"\n#include \"base/low_level_alloc.h\"\n#include \"malloc_hook-inl.h\"\n#include <google/malloc_hook.h>\n#include <google/malloc_extension.h>\n#include \"maybe_threads.h\"\n#include \"memory_region_map.h\"\n#include \"base/spinlock.h\"\n#include \"base/sysinfo.h\"\n#include \"base/stl_allocator.h\"\n\nusing std::string;\nusing std::basic_string;\nusing std::pair;\nusing std::map;\nusing std::set;\nusing std::vector;\nusing std::swap;\nusing std::make_pair;\nusing std::min;\nusing std::max;\nusing std::less;\nusing std::char_traits;\n\n// If current process is being ptrace()d, 'TracerPid' in /proc/self/status\n// will be non-zero.\nstatic bool IsDebuggerAttached(void) {    // only works under linux, probably\n  char buf[256];   // TracerPid comes relatively earlier in status output\n  int fd = open(\"/proc/self/status\", O_RDONLY);\n  if (fd == -1) {\n    return false;  // Can't tell for sure.\n  }\n  const int len = read(fd, buf, sizeof(buf));\n  bool rc = false;\n  if (len > 0) {\n    const char *const kTracerPid = \"TracerPid:\\t\";\n    buf[len - 1] = '\\0';\n    const char *p = strstr(buf, kTracerPid);\n    if (p != NULL) {\n      rc = (strncmp(p + strlen(kTracerPid), \"0\\n\", 2) != 0);\n    }\n  }\n  close(fd);\n  return rc;\n}\n\n// This is the default if you don't link in -lprofiler\nextern \"C\" {\nATTRIBUTE_WEAK PERFTOOLS_DLL_DECL bool ProfilingIsEnabledForAllThreads();\nbool ProfilingIsEnabledForAllThreads() { return false; }\n}\n\n//----------------------------------------------------------------------\n// Flags that control heap-checking\n//----------------------------------------------------------------------\n\nDEFINE_string(heap_check,\n              EnvToString(\"HEAPCHECK\", \"\"),\n              \"The heap leak checking to be done over the whole executable: \"\n              \"\\\"minimal\\\", \\\"normal\\\", \\\"strict\\\", \"\n              \"\\\"draconian\\\", \\\"as-is\\\", and \\\"local\\\" \"\n              \" or the empty string are the supported choices. \"\n              \"(See HeapLeakChecker::InternalInitStart for details.)\");\n\nDEFINE_bool(heap_check_report, true, \"Obsolete\");\n\nDEFINE_bool(heap_check_before_constructors,\n            true,\n            \"deprecated; pretty much always true now\");\n\nDEFINE_bool(heap_check_after_destructors,\n            EnvToBool(\"HEAP_CHECK_AFTER_DESTRUCTORS\", false),\n            \"If overall heap check is to end after global destructors \"\n            \"or right after all REGISTER_HEAPCHECK_CLEANUP's\");\n\nDEFINE_bool(heap_check_strict_check, true, \"Obsolete\");\n\nDEFINE_bool(heap_check_ignore_global_live,\n            EnvToBool(\"HEAP_CHECK_IGNORE_GLOBAL_LIVE\", true),\n            \"If overall heap check is to ignore heap objects reachable \"\n            \"from the global data\");\n\nDEFINE_bool(heap_check_identify_leaks,\n            EnvToBool(\"HEAP_CHECK_IDENTIFY_LEAKS\", false),\n            \"If heap check should generate the addresses of the leaked \"\n            \"objects in the memory leak profiles.  This may be useful \"\n            \"in tracking down leaks where only a small fraction of \"\n            \"objects allocated at the same stack trace are leaked.\");\n\nDEFINE_bool(heap_check_ignore_thread_live,\n            EnvToBool(\"HEAP_CHECK_IGNORE_THREAD_LIVE\", true),\n            \"If set to true, objects reachable from thread stacks \"\n            \"and registers are not reported as leaks\");\n\nDEFINE_bool(heap_check_test_pointer_alignment,\n            EnvToBool(\"HEAP_CHECK_TEST_POINTER_ALIGNMENT\", false),\n            \"Set to true to check if the found leak can be due to \"\n            \"use of unaligned pointers\");\n\n// Alignment at which all pointers in memory are supposed to be located;\n// use 1 if any alignment is ok.\n// heap_check_test_pointer_alignment flag guides if we try the value of 1.\n// The larger it can be, the lesser is the chance of missing real leaks.\nstatic const size_t kPointerSourceAlignment = sizeof(void*);\nDEFINE_int32(heap_check_pointer_source_alignment,\n\t     EnvToInt(\"HEAP_CHECK_POINTER_SOURCE_ALIGNMENT\",\n                      kPointerSourceAlignment),\n             \"Alignment at which all pointers in memory are supposed to be \"\n             \"located.  Use 1 if any alignment is ok.\");\n\n// A reasonable default to handle pointers inside of typical class objects:\n// Too low and we won't be able to traverse pointers to normally-used\n// nested objects and base parts of multiple-inherited objects.\n// Too high and it will both slow down leak checking (FindInsideAlloc\n// in HaveOnHeapLocked will get slower when there are large on-heap objects)\n// and make it probabilistically more likely to miss leaks\n// of large-sized objects.\nstatic const int64 kHeapCheckMaxPointerOffset = 1024;\nDEFINE_int64(heap_check_max_pointer_offset,\n\t     EnvToInt(\"HEAP_CHECK_MAX_POINTER_OFFSET\",\n                      kHeapCheckMaxPointerOffset),\n             \"Largest pointer offset for which we traverse \"\n             \"pointers going inside of heap allocated objects. \"\n             \"Set to -1 to use the actual largest heap object size.\");\n\nDEFINE_bool(heap_check_run_under_gdb,\n            EnvToBool(\"HEAP_CHECK_RUN_UNDER_GDB\", false),\n            \"If false, turns off heap-checking library when running under gdb \"\n            \"(normally, set to 'true' only when debugging the heap-checker)\");\n\nDEFINE_int32(heap_check_delay_seconds, 0,\n             \"Number of seconds to delay on-exit heap checking.\"\n             \" If you set this flag,\"\n             \" you may also want to set exit_timeout_seconds in order to\"\n             \" avoid exit timeouts.\\n\"\n             \"NOTE: This flag is to be used only to help diagnose issues\"\n             \" where it is suspected that the heap checker is reporting\"\n             \" false leaks that will disappear if the heap checker delays\"\n             \" its checks. Report any such issues to the heap-checker\"\n             \" maintainer(s).\");\n\n//----------------------------------------------------------------------\n\nDEFINE_string(heap_profile_pprof,\n              EnvToString(\"PPROF_PATH\", \"pprof\"),\n              \"OBSOLETE; not used\");\n\nDEFINE_string(heap_check_dump_directory,\n              EnvToString(\"HEAP_CHECK_DUMP_DIRECTORY\", \"/tmp\"),\n              \"Directory to put heap-checker leak dump information\");\n\n\n//----------------------------------------------------------------------\n// HeapLeakChecker global data\n//----------------------------------------------------------------------\n\n// Global lock for all the global data of this module.\nstatic SpinLock heap_checker_lock(SpinLock::LINKER_INITIALIZED);\n\n//----------------------------------------------------------------------\n\n// Heap profile prefix for leak checking profiles.\n// Gets assigned once when leak checking is turned on, then never modified.\nstatic const string* profile_name_prefix = NULL;\n\n// Whole-program heap leak checker.\n// Gets assigned once when leak checking is turned on,\n// then main_heap_checker is never deleted.\nstatic HeapLeakChecker* main_heap_checker = NULL;\n\n// Whether we will use main_heap_checker to do a check at program exit\n// automatically. In any case user can ask for more checks on main_heap_checker\n// via GlobalChecker().\nstatic bool do_main_heap_check = false;\n\n// The heap profile we use to collect info about the heap.\n// This is created in HeapLeakChecker::BeforeConstructorsLocked\n// together with setting heap_checker_on (below) to true\n// and registering our new/delete malloc hooks;\n// similarly all are unset in HeapLeakChecker::TurnItselfOffLocked.\nstatic HeapProfileTable* heap_profile = NULL;\n\n// If we are doing (or going to do) any kind of heap-checking.\nstatic bool heap_checker_on = false;\n\n// pid of the process that does whole-program heap leak checking\nstatic pid_t heap_checker_pid = 0;\n\n// If we did heap profiling during global constructors execution\nstatic bool constructor_heap_profiling = false;\n\n// RAW_VLOG level we dump key INFO messages at.  If you want to turn\n// off these messages, set the environment variable PERFTOOLS_VERBOSE=-1.\nstatic const int heap_checker_info_level = 0;\n\n//----------------------------------------------------------------------\n// Cancel our InitialMallocHook_* if present.\nstatic void CancelInitialMallocHooks();  // defined below\n\n//----------------------------------------------------------------------\n// HeapLeakChecker's own memory allocator that is\n// independent of the normal program allocator.\n//----------------------------------------------------------------------\n\n// Wrapper of LowLevelAlloc for STL_Allocator and direct use.\n// We always access this class under held heap_checker_lock,\n// this allows us to in particular protect the period when threads are stopped\n// at random spots with ListAllProcessThreads by heap_checker_lock,\n// w/o worrying about the lock in LowLevelAlloc::Arena.\n// We rely on the fact that we use an own arena with an own lock here.\nclass HeapLeakChecker::Allocator {\n public:\n  static void Init() {\n    RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n    RAW_DCHECK(arena_ == NULL, \"\");\n    arena_ = LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());\n  }\n  static void Shutdown() {\n    RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n    if (!LowLevelAlloc::DeleteArena(arena_)  ||  alloc_count_ != 0) {\n      RAW_LOG(FATAL, \"Internal heap checker leak of %d objects\", alloc_count_);\n    }\n  }\n  static int alloc_count() {\n    RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n    return alloc_count_;\n  }\n  static void* Allocate(size_t n) {\n    RAW_DCHECK(arena_  &&  heap_checker_lock.IsHeld(), \"\");\n    void* p = LowLevelAlloc::AllocWithArena(n, arena_);\n    if (p) alloc_count_ += 1;\n    return p;\n  }\n  static void Free(void* p) {\n    RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n    if (p) alloc_count_ -= 1;\n    LowLevelAlloc::Free(p);\n  }\n  static void Free(void* p, size_t /* n */) {\n    Free(p);\n  }\n  // destruct, free, and make *p to be NULL\n  template<typename T> static void DeleteAndNull(T** p) {\n    (*p)->~T();\n    Free(*p);\n    *p = NULL;\n  }\n  template<typename T> static void DeleteAndNullIfNot(T** p) {\n    if (*p != NULL) DeleteAndNull(p);\n  }\n private:\n  static LowLevelAlloc::Arena* arena_;\n  static int alloc_count_;\n};\n\nLowLevelAlloc::Arena* HeapLeakChecker::Allocator::arena_ = NULL;\nint HeapLeakChecker::Allocator::alloc_count_ = 0;\n\n//----------------------------------------------------------------------\n// HeapLeakChecker live object tracking components\n//----------------------------------------------------------------------\n\n// Cases of live object placement we distinguish\nenum ObjectPlacement {\n  MUST_BE_ON_HEAP,   // Must point to a live object of the matching size in the\n                     // heap_profile map of the heap when we get to it\n  IGNORED_ON_HEAP,   // Is a live (ignored) object on heap\n  MAYBE_LIVE,        // Is a piece of writable memory from /proc/self/maps\n  IN_GLOBAL_DATA,    // Is part of global data region of the executable\n  THREAD_DATA,       // Part of a thread stack and a thread descriptor with TLS\n  THREAD_REGISTERS,  // Values in registers of some thread\n};\n\n// Information about an allocated object\nstruct AllocObject {\n  const void* ptr;        // the object\n  uintptr_t size;         // its size\n  ObjectPlacement place;  // where ptr points to\n\n  AllocObject(const void* p, size_t s, ObjectPlacement l)\n    : ptr(p), size(s), place(l) { }\n};\n\n// All objects (memory ranges) ignored via HeapLeakChecker::IgnoreObject\n// Key is the object's address; value is its size.\ntypedef map<uintptr_t, size_t, less<uintptr_t>,\n            STL_Allocator<pair<const uintptr_t, size_t>,\n                          HeapLeakChecker::Allocator>\n           > IgnoredObjectsMap;\nstatic IgnoredObjectsMap* ignored_objects = NULL;\n\n// All objects (memory ranges) that we consider to be the sources of pointers\n// to live (not leaked) objects.\n// At different times this holds (what can be reached from) global data regions\n// and the objects we've been told to ignore.\n// For any AllocObject::ptr \"live_objects\" is supposed to contain at most one\n// record at any time. We maintain this by checking with the heap_profile map\n// of the heap and removing the live heap objects we've handled from it.\n// This vector is maintained as a stack and the frontier of reachable\n// live heap objects in our flood traversal of them.\ntypedef vector<AllocObject,\n               STL_Allocator<AllocObject, HeapLeakChecker::Allocator>\n              > LiveObjectsStack;\nstatic LiveObjectsStack* live_objects = NULL;\n\n// A special string type that uses my allocator\ntypedef basic_string<char, char_traits<char>,\n                     STL_Allocator<char, HeapLeakChecker::Allocator>\n                    > HCL_string;\n\n// A placeholder to fill-in the starting values for live_objects\n// for each library so we can keep the library-name association for logging.\ntypedef map<HCL_string, LiveObjectsStack, less<HCL_string>,\n            STL_Allocator<pair<const HCL_string, LiveObjectsStack>,\n                          HeapLeakChecker::Allocator>\n           > LibraryLiveObjectsStacks;\nstatic LibraryLiveObjectsStacks* library_live_objects = NULL;\n\n// Value stored in the map of disabled address ranges;\n// its key is the end of the address range.\n// We'll ignore allocations with a return address in a disabled range\n// if the address occurs at 'max_depth' or less in the stack trace.\nstruct HeapLeakChecker::RangeValue {\n  uintptr_t start_address;  // the start of the range\n  int       max_depth;      // the maximal stack depth to disable at\n};\ntypedef map<uintptr_t, HeapLeakChecker::RangeValue, less<uintptr_t>,\n            STL_Allocator<pair<const uintptr_t, HeapLeakChecker::RangeValue>,\n                          HeapLeakChecker::Allocator>\n           > DisabledRangeMap;\n// The disabled program counter address ranges for profile dumping\n// that are registered with HeapLeakChecker::DisableChecksFromToLocked.\nstatic DisabledRangeMap* disabled_ranges = NULL;\n\n// Set of stack tops.\n// These are used to consider live only appropriate chunks of the memory areas\n// that are used for stacks (and maybe thread-specific data as well)\n// so that we do not treat pointers from outdated stack frames as live.\ntypedef set<uintptr_t, less<uintptr_t>,\n            STL_Allocator<uintptr_t, HeapLeakChecker::Allocator>\n           > StackTopSet;\nstatic StackTopSet* stack_tops = NULL;\n\n// A map of ranges of code addresses for the system libraries\n// that can mmap/mremap/sbrk-allocate memory regions for stacks\n// and thread-local storage that we want to consider as live global data.\n// Maps from the end address to the start address.\ntypedef map<uintptr_t, uintptr_t, less<uintptr_t>,\n            STL_Allocator<pair<const uintptr_t, uintptr_t>,\n                          HeapLeakChecker::Allocator>\n           > GlobalRegionCallerRangeMap;\nstatic GlobalRegionCallerRangeMap* global_region_caller_ranges = NULL;\n\n// TODO(maxim): make our big data structs into own modules\n\n// Disabler is implemented by keeping track of a per-thread count\n// of active Disabler objects.  Any objects allocated while the\n// count > 0 are not reported.\n\n#ifdef HAVE_TLS\n\nstatic __thread int thread_disable_counter\n// The \"inital exec\" model is faster than the default TLS model, at\n// the cost you can't dlopen this library.  But dlopen on heap-checker\n// doesn't work anyway -- it must run before main -- so this is a good\n// trade-off.\n# ifdef HAVE___ATTRIBUTE__\n   __attribute__ ((tls_model (\"initial-exec\")))\n# endif\n    ;\ninline int get_thread_disable_counter() {\n  return thread_disable_counter;\n}\ninline void set_thread_disable_counter(int value) {\n  thread_disable_counter = value;\n}\n\n#else  // #ifdef HAVE_TLS\n\nstatic pthread_key_t thread_disable_counter_key;\nstatic int main_thread_counter;   // storage for use before main()\nstatic bool use_main_thread_counter = true;\n\n// TODO(csilvers): this is called from NewHook, in the middle of malloc().\n// If perftools_pthread_getspecific calls malloc, that will lead to an\n// infinite loop.  I don't know how to fix that, so I hope it never happens!\ninline int get_thread_disable_counter() {\n  if (use_main_thread_counter)  // means we're running really early\n    return main_thread_counter;\n  void* p = perftools_pthread_getspecific(thread_disable_counter_key);\n  return (intptr_t)p;   // kinda evil: store the counter directly in the void*\n}\n\ninline void set_thread_disable_counter(int value) {\n  if (use_main_thread_counter) {   // means we're running really early\n    main_thread_counter = value;\n    return;\n  }\n  intptr_t pointer_sized_value = value;\n  // kinda evil: store the counter directly in the void*\n  void* p = (void*)pointer_sized_value;\n  // NOTE: this may call malloc, which will call NewHook which will call\n  // get_thread_disable_counter() which will call pthread_getspecific().  I\n  // don't know if anything bad can happen if we call getspecific() in the\n  // middle of a setspecific() call.  It seems to work ok in practice...\n  perftools_pthread_setspecific(thread_disable_counter_key, p);\n}\n\n// The idea here is that this initializer will run pretty late: after\n// pthreads have been totally set up.  At this point we can call\n// pthreads routines, so we set those up.\nclass InitThreadDisableCounter {\n public:\n  InitThreadDisableCounter() {\n    perftools_pthread_key_create(&thread_disable_counter_key, NULL);\n    // Set up the main thread's value, which we have a special variable for.\n    void* p = (void*)main_thread_counter;   // store the counter directly\n    perftools_pthread_setspecific(thread_disable_counter_key, p);\n    use_main_thread_counter = false;\n  }\n};\nInitThreadDisableCounter init_thread_disable_counter;\n\n#endif  // #ifdef HAVE_TLS\n\nHeapLeakChecker::Disabler::Disabler() {\n  // It is faster to unconditionally increment the thread-local\n  // counter than to check whether or not heap-checking is on\n  // in a thread-safe manner.\n  int counter = get_thread_disable_counter();\n  set_thread_disable_counter(counter + 1);\n  RAW_VLOG(10, \"Increasing thread disable counter to %d\", counter + 1);\n}\n\nHeapLeakChecker::Disabler::~Disabler() {\n  int counter = get_thread_disable_counter();\n  RAW_DCHECK(counter > 0, \"\");\n  if (counter > 0) {\n    set_thread_disable_counter(counter - 1);\n    RAW_VLOG(10, \"Decreasing thread disable counter to %d\", counter);\n  } else {\n    RAW_VLOG(0, \"Thread disable counter underflow : %d\", counter);\n  }\n}\n\n//----------------------------------------------------------------------\n\n// The size of the largest heap object allocated so far.\nstatic size_t max_heap_object_size = 0;\n// The possible range of addresses that can point\n// into one of the elements of heap_objects.\nstatic uintptr_t min_heap_address = uintptr_t(-1LL);\nstatic uintptr_t max_heap_address = 0;\n\n//----------------------------------------------------------------------\n\n// Simple casting helpers for uintptr_t and void*:\ntemplate<typename T>\ninline static const void* AsPtr(T addr) {\n  return reinterpret_cast<void*>(addr);\n}\ninline static uintptr_t AsInt(const void* ptr) {\n  return reinterpret_cast<uintptr_t>(ptr);\n}\n\n//----------------------------------------------------------------------\n\n// Our hooks for MallocHook\nstatic void NewHook(const void* ptr, size_t size) {\n  if (ptr != NULL) {\n    const int counter = get_thread_disable_counter();\n    const bool ignore = (counter > 0);\n    RAW_VLOG(16, \"Recording Alloc: %p of %\"PRIuS \"; %d\", ptr, size,\n             int(counter));\n    { SpinLockHolder l(&heap_checker_lock);\n      if (size > max_heap_object_size) max_heap_object_size = size;\n      uintptr_t addr = AsInt(ptr);\n      if (addr < min_heap_address) min_heap_address = addr;\n      addr += size;\n      if (addr > max_heap_address) max_heap_address = addr;\n      if (heap_checker_on) {\n        heap_profile->RecordAlloc(ptr, size, 0);\n        if (ignore) {\n          heap_profile->MarkAsIgnored(ptr);\n        }\n      }\n    }\n    RAW_VLOG(17, \"Alloc Recorded: %p of %\"PRIuS\"\", ptr, size);\n  }\n}\n\nstatic void DeleteHook(const void* ptr) {\n  if (ptr != NULL) {\n    RAW_VLOG(16, \"Recording Free %p\", ptr);\n    { SpinLockHolder l(&heap_checker_lock);\n      if (heap_checker_on) heap_profile->RecordFree(ptr);\n    }\n    RAW_VLOG(17, \"Free Recorded: %p\", ptr);\n  }\n}\n\n//----------------------------------------------------------------------\n\nenum StackDirection {\n  GROWS_TOWARDS_HIGH_ADDRESSES,\n  GROWS_TOWARDS_LOW_ADDRESSES,\n  UNKNOWN_DIRECTION\n};\n\n// Determine which way the stack grows:\n\nstatic StackDirection ATTRIBUTE_NOINLINE GetStackDirection(\n    const uintptr_t *const ptr) {\n  uintptr_t x;\n  if (&x < ptr)\n    return GROWS_TOWARDS_LOW_ADDRESSES;\n  if (ptr < &x)\n    return GROWS_TOWARDS_HIGH_ADDRESSES;\n\n  RAW_CHECK(0, \"\");  // Couldn't determine the stack direction.\n\n  return UNKNOWN_DIRECTION;\n}\n\n// Direction of stack growth (will initialize via GetStackDirection())\nstatic StackDirection stack_direction = UNKNOWN_DIRECTION;\n\n// This routine is called for every thread stack we know about to register it.\nstatic void RegisterStackLocked(const void* top_ptr) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  RAW_DCHECK(MemoryRegionMap::LockIsHeld(), \"\");\n  RAW_VLOG(10, \"Thread stack at %p\", top_ptr);\n  uintptr_t top = AsInt(top_ptr);\n  stack_tops->insert(top);  // add for later use\n\n  // make sure stack_direction is initialized\n  if (stack_direction == UNKNOWN_DIRECTION) {\n    stack_direction = GetStackDirection(&top);\n  }\n\n  // Find memory region with this stack\n  MemoryRegionMap::Region region;\n  if (MemoryRegionMap::FindAndMarkStackRegion(top, &region)) {\n    // Make the proper portion of the stack live:\n    if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {\n      RAW_VLOG(11, \"Live stack at %p of %\"PRIuPTR\" bytes\",\n                  top_ptr, region.end_addr - top);\n      live_objects->push_back(AllocObject(top_ptr, region.end_addr - top,\n                                          THREAD_DATA));\n    } else {  // GROWS_TOWARDS_HIGH_ADDRESSES\n      RAW_VLOG(11, \"Live stack at %p of %\"PRIuPTR\" bytes\",\n                  AsPtr(region.start_addr),\n                  top - region.start_addr);\n      live_objects->push_back(AllocObject(AsPtr(region.start_addr),\n                                          top - region.start_addr,\n                                          THREAD_DATA));\n    }\n  // not in MemoryRegionMap, look in library_live_objects:\n  } else if (FLAGS_heap_check_ignore_global_live) {\n    for (LibraryLiveObjectsStacks::iterator lib = library_live_objects->begin();\n         lib != library_live_objects->end(); ++lib) {\n      for (LiveObjectsStack::iterator span = lib->second.begin();\n           span != lib->second.end(); ++span) {\n        uintptr_t start = AsInt(span->ptr);\n        uintptr_t end = start + span->size;\n        if (start <= top  &&  top < end) {\n          RAW_VLOG(11, \"Stack at %p is inside /proc/self/maps chunk %p..%p\",\n                      top_ptr, AsPtr(start), AsPtr(end));\n          // Shrink start..end region by chopping away the memory regions in\n          // MemoryRegionMap that land in it to undo merging of regions\n          // in /proc/self/maps, so that we correctly identify what portion\n          // of start..end is actually the stack region.\n          uintptr_t stack_start = start;\n          uintptr_t stack_end = end;\n          // can optimize-away this loop, but it does not run often\n          RAW_DCHECK(MemoryRegionMap::LockIsHeld(), \"\");\n          for (MemoryRegionMap::RegionIterator r =\n                 MemoryRegionMap::BeginRegionLocked();\n               r != MemoryRegionMap::EndRegionLocked(); ++r) {\n            if (top < r->start_addr  &&  r->start_addr < stack_end) {\n              stack_end = r->start_addr;\n            }\n            if (stack_start < r->end_addr  &&  r->end_addr <= top) {\n              stack_start = r->end_addr;\n            }\n          }\n          if (stack_start != start  ||  stack_end != end) {\n            RAW_VLOG(11, \"Stack at %p is actually inside memory chunk %p..%p\",\n                        top_ptr, AsPtr(stack_start), AsPtr(stack_end));\n          }\n          // Make the proper portion of the stack live:\n          if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {\n            RAW_VLOG(11, \"Live stack at %p of %\"PRIuPTR\" bytes\",\n                        top_ptr, stack_end - top);\n            live_objects->push_back(\n              AllocObject(top_ptr, stack_end - top, THREAD_DATA));\n          } else {  // GROWS_TOWARDS_HIGH_ADDRESSES\n            RAW_VLOG(11, \"Live stack at %p of %\"PRIuPTR\" bytes\",\n                        AsPtr(stack_start), top - stack_start);\n            live_objects->push_back(\n              AllocObject(AsPtr(stack_start), top - stack_start, THREAD_DATA));\n          }\n          lib->second.erase(span);  // kill the rest of the region\n          // Put the non-stack part(s) of the region back:\n          if (stack_start != start) {\n            lib->second.push_back(AllocObject(AsPtr(start), stack_start - start,\n                                  MAYBE_LIVE));\n          }\n          if (stack_end != end) {\n            lib->second.push_back(AllocObject(AsPtr(stack_end), end - stack_end,\n                                  MAYBE_LIVE));\n          }\n          return;\n        }\n      }\n    }\n    RAW_LOG(ERROR, \"Memory region for stack at %p not found. \"\n                   \"Will likely report false leak positives.\", top_ptr);\n  }\n}\n\n// Iterator for heap allocation map data to make ignored objects \"live\"\n// (i.e., treated as roots for the mark-and-sweep phase)\nstatic void MakeIgnoredObjectsLiveCallbackLocked(\n    const void* ptr, const HeapProfileTable::AllocInfo& info) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  if (info.ignored) {\n    live_objects->push_back(AllocObject(ptr, info.object_size,\n                                        MUST_BE_ON_HEAP));\n  }\n}\n\n// Iterator for heap allocation map data to make objects allocated from\n// disabled regions of code to be live.\nstatic void MakeDisabledLiveCallbackLocked(\n    const void* ptr, const HeapProfileTable::AllocInfo& info) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  bool stack_disable = false;\n  bool range_disable = false;\n  for (int depth = 0; depth < info.stack_depth; depth++) {\n    uintptr_t addr = AsInt(info.call_stack[depth]);\n    if (disabled_ranges) {\n      DisabledRangeMap::const_iterator iter\n        = disabled_ranges->upper_bound(addr);\n      if (iter != disabled_ranges->end()) {\n        RAW_DCHECK(iter->first > addr, \"\");\n        if (iter->second.start_address < addr  &&\n            iter->second.max_depth > depth) {\n          range_disable = true;  // in range; dropping\n          break;\n        }\n      }\n    }\n  }\n  if (stack_disable || range_disable) {\n    uintptr_t start_address = AsInt(ptr);\n    uintptr_t end_address = start_address + info.object_size;\n    StackTopSet::const_iterator iter\n      = stack_tops->lower_bound(start_address);\n    if (iter != stack_tops->end()) {\n      RAW_DCHECK(*iter >= start_address, \"\");\n      if (*iter < end_address) {\n        // We do not disable (treat as live) whole allocated regions\n        // if they are used to hold thread call stacks\n        // (i.e. when we find a stack inside).\n        // The reason is that we'll treat as live the currently used\n        // stack portions anyway (see RegisterStackLocked),\n        // and the rest of the region where the stack lives can well\n        // contain outdated stack variables which are not live anymore,\n        // hence should not be treated as such.\n        RAW_VLOG(11, \"Not %s-disabling %\"PRIuS\" bytes at %p\"\n                    \": have stack inside: %p\",\n                    (stack_disable ? \"stack\" : \"range\"),\n                    info.object_size, ptr, AsPtr(*iter));\n        return;\n      }\n    }\n    RAW_VLOG(11, \"%s-disabling %\"PRIuS\" bytes at %p\",\n                (stack_disable ? \"Stack\" : \"Range\"), info.object_size, ptr);\n    live_objects->push_back(AllocObject(ptr, info.object_size,\n                                        MUST_BE_ON_HEAP));\n  }\n}\n\n// This function takes some fields from a /proc/self/maps line:\n//\n//   start_address  start address of a memory region.\n//   end_address    end address of a memory region\n//   permissions    rwx + private/shared bit\n//   filename       filename of the mapped file\n//\n// If the region is not writeable, then it cannot have any heap\n// pointers in it, otherwise we record it as a candidate live region\n// to get filtered later.\nstatic void RecordGlobalDataLocked(uintptr_t start_address,\n                                   uintptr_t end_address,\n                                   const char* permissions,\n                                   const char* filename) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  // Ignore non-writeable regions.\n  if (strchr(permissions, 'w') == NULL) return;\n  if (filename == NULL  ||  *filename == '\\0')  filename = \"UNNAMED\";\n  RAW_VLOG(11, \"Looking into %s: 0x%\" PRIxPTR \"..0x%\" PRIxPTR,\n              filename, start_address, end_address);\n  (*library_live_objects)[filename].\n    push_back(AllocObject(AsPtr(start_address),\n                          end_address - start_address,\n                          MAYBE_LIVE));\n}\n\n// See if 'library' from /proc/self/maps has base name 'library_base'\n// i.e. contains it and has '.' or '-' after it.\nstatic bool IsLibraryNamed(const char* library, const char* library_base) {\n  const char* p = strstr(library, library_base);\n  size_t sz = strlen(library_base);\n  return p != NULL  &&  (p[sz] == '.'  ||  p[sz] == '-');\n}\n\n// static\nvoid HeapLeakChecker::DisableLibraryAllocsLocked(const char* library,\n                                                 uintptr_t start_address,\n                                                 uintptr_t end_address) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  int depth = 0;\n  // TODO(maxim): maybe this should be extended to also use objdump\n  //              and pick the text portion of the library more precisely.\n  if (IsLibraryNamed(library, \"/libpthread\")  ||\n        // libpthread has a lot of small \"system\" leaks we don't care about.\n        // In particular it allocates memory to store data supplied via\n        // pthread_setspecific (which can be the only pointer to a heap object).\n      IsLibraryNamed(library, \"/libdl\")  ||\n        // library loaders leak some \"system\" heap that we don't care about\n      IsLibraryNamed(library, \"/libcrypto\")  ||\n        // Sometimes libcrypto of OpenSSH is compiled with -fomit-frame-pointer\n        // (any library can be, of course, but this one often is because speed\n        // is so important for making crypto usable).  We ignore all its\n        // allocations because we can't see the call stacks.  We'd prefer\n        // to ignore allocations done in files/symbols that match\n        // \"default_malloc_ex|default_realloc_ex\"\n        // but that doesn't work when the end-result binary is stripped.\n      IsLibraryNamed(library, \"/libjvm\")  ||\n        // JVM has a lot of leaks we don't care about.\n      IsLibraryNamed(library, \"/libzip\")\n        // The JVM leaks java.util.zip.Inflater after loading classes.\n     ) {\n    depth = 1;  // only disable allocation calls directly from the library code\n  } else if (IsLibraryNamed(library, \"/ld\")\n               // library loader leaks some \"system\" heap\n               // (e.g. thread-local storage) that we don't care about\n            ) {\n    depth = 2;  // disable allocation calls directly from the library code\n                // and at depth 2 from it.\n    // We need depth 2 here solely because of a libc bug that\n    // forces us to jump through __memalign_hook and MemalignOverride hoops\n    // in tcmalloc.cc.\n    // Those buggy __libc_memalign() calls are in ld-linux.so and happen for\n    // thread-local storage allocations that we want to ignore here.\n    // We go with the depth-2 hack as a workaround for this libc bug:\n    // otherwise we'd need to extend MallocHook interface\n    // so that correct stack depth adjustment can be propagated from\n    // the exceptional case of MemalignOverride.\n    // Using depth 2 here should not mask real leaks because ld-linux.so\n    // does not call user code.\n  }\n  if (depth) {\n    RAW_VLOG(10, \"Disabling allocations from %s at depth %d:\", library, depth);\n    DisableChecksFromToLocked(AsPtr(start_address), AsPtr(end_address), depth);\n    if (IsLibraryNamed(library, \"/libpthread\")  ||\n        IsLibraryNamed(library, \"/libdl\")  ||\n        IsLibraryNamed(library, \"/ld\")) {\n      RAW_VLOG(10, \"Global memory regions made by %s will be live data\",\n                  library);\n      if (global_region_caller_ranges == NULL) {\n        global_region_caller_ranges =\n          new(Allocator::Allocate(sizeof(GlobalRegionCallerRangeMap)))\n            GlobalRegionCallerRangeMap;\n      }\n      global_region_caller_ranges\n        ->insert(make_pair(end_address, start_address));\n    }\n  }\n}\n\n// static\nHeapLeakChecker::ProcMapsResult HeapLeakChecker::UseProcMapsLocked(\n                                  ProcMapsTask proc_maps_task) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  // Need to provide own scratch memory to ProcMapsIterator:\n  ProcMapsIterator::Buffer buffer;\n  ProcMapsIterator it(0, &buffer);\n  if (!it.Valid()) {\n    int errsv = errno;\n    RAW_LOG(ERROR, \"Could not open /proc/self/maps: errno=%d. \"\n                   \"Libraries will not be handled correctly.\", errsv);\n    return CANT_OPEN_PROC_MAPS;\n  }\n  uint64 start_address, end_address, file_offset;\n  int64 inode;\n  char *permissions, *filename;\n  bool saw_shared_lib = false;\n  while (it.Next(&start_address, &end_address, &permissions,\n                 &file_offset, &inode, &filename)) {\n    if (start_address >= end_address) {\n      // Warn if a line we can be interested in is ill-formed:\n      if (inode != 0) {\n        RAW_LOG(ERROR, \"Errors reading /proc/self/maps. \"\n                       \"Some global memory regions will not \"\n                       \"be handled correctly.\");\n      }\n      // Silently skip other ill-formed lines: some are possible\n      // probably due to the interplay of how /proc/self/maps is updated\n      // while we read it in chunks in ProcMapsIterator and\n      // do things in this loop.\n      continue;\n    }\n    // Determine if any shared libraries are present.\n    if (inode != 0 && strstr(filename, \"lib\") && strstr(filename, \".so\")) {\n      saw_shared_lib = true;\n    }\n    switch (proc_maps_task) {\n      case DISABLE_LIBRARY_ALLOCS:\n        // All lines starting like\n        // \"401dc000-4030f000 r??p 00132000 03:01 13991972  lib/bin\"\n        // identify a data and code sections of a shared library or our binary\n        if (inode != 0 && strncmp(permissions, \"r-xp\", 4) == 0) {\n          DisableLibraryAllocsLocked(filename, start_address, end_address);\n        }\n        break;\n      case RECORD_GLOBAL_DATA:\n        RecordGlobalDataLocked(start_address, end_address,\n                               permissions, filename);\n        break;\n      default:\n        RAW_CHECK(0, \"\");\n    }\n  }\n  if (!saw_shared_lib) {\n    RAW_LOG(ERROR, \"No shared libs detected. Will likely report false leak \"\n                   \"positives for statically linked executables.\");\n    return NO_SHARED_LIBS_IN_PROC_MAPS;\n  }\n  return PROC_MAPS_USED;\n}\n\n// Total number and size of live objects dropped from the profile;\n// (re)initialized in IgnoreAllLiveObjectsLocked.\nstatic int64 live_objects_total;\nstatic int64 live_bytes_total;\n\n// pid of the thread that is doing the current leak check\n// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)\nstatic pid_t self_thread_pid = 0;\n\n// Status of our thread listing callback execution\n// (protected by our lock; used from within IgnoreAllLiveObjectsLocked)\nstatic enum {\n  CALLBACK_NOT_STARTED,\n  CALLBACK_STARTED,\n  CALLBACK_COMPLETED,\n} thread_listing_status = CALLBACK_NOT_STARTED;\n\n// Ideally to avoid deadlocks this function should not result in any libc\n// or other function calls that might need to lock a mutex:\n// It is called when all threads of a process are stopped\n// at arbitrary points thus potentially holding those locks.\n//\n// In practice we are calling some simple i/o and sprintf-type library functions\n// for logging messages, but use only our own LowLevelAlloc::Arena allocator.\n//\n// This is known to be buggy: the library i/o function calls are able to cause\n// deadlocks when they request a lock that a stopped thread happens to hold.\n// This issue as far as we know have so far not resulted in any deadlocks\n// in practice, so for now we are taking our chance that the deadlocks\n// have insignificant frequency.\n//\n// If such deadlocks become a problem we should make the i/o calls\n// into appropriately direct system calls (or eliminate them),\n// in particular write() is not safe and vsnprintf() is potentially dangerous\n// due to reliance on locale functions (these are called through RAW_LOG\n// and in other ways).\n//\n/*static*/ int HeapLeakChecker::IgnoreLiveThreadsLocked(void* parameter,\n                                                        int num_threads,\n                                                        pid_t* thread_pids,\n                                                        va_list /*ap*/) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  thread_listing_status = CALLBACK_STARTED;\n  RAW_VLOG(11, \"Found %d threads (from pid %d)\", num_threads, getpid());\n\n  if (FLAGS_heap_check_ignore_global_live) {\n    UseProcMapsLocked(RECORD_GLOBAL_DATA);\n  }\n\n  // We put the registers from other threads here\n  // to make pointers stored in them live.\n  vector<void*, STL_Allocator<void*, Allocator> > thread_registers;\n\n  int failures = 0;\n  for (int i = 0; i < num_threads; ++i) {\n    // the leak checking thread itself is handled\n    // specially via self_thread_stack, not here:\n    if (thread_pids[i] == self_thread_pid) continue;\n    RAW_VLOG(11, \"Handling thread with pid %d\", thread_pids[i]);\n#if (defined(__i386__) || defined(__x86_64)) && \\\n    defined(HAVE_LINUX_PTRACE_H) && defined(HAVE_SYS_SYSCALL_H) && defined(DUMPER)\n    i386_regs thread_regs;\n#define sys_ptrace(r, p, a, d)  syscall(SYS_ptrace, (r), (p), (a), (d))\n    // We use sys_ptrace to avoid thread locking\n    // because this is called from ListAllProcessThreads\n    // when all but this thread are suspended.\n    if (sys_ptrace(PTRACE_GETREGS, thread_pids[i], NULL, &thread_regs) == 0) {\n      // Need to use SP to get all the data from the very last stack frame:\n      COMPILE_ASSERT(sizeof(thread_regs.SP) == sizeof(void*),\n                     SP_register_does_not_look_like_a_pointer);\n      RegisterStackLocked(reinterpret_cast<void*>(thread_regs.SP));\n      // Make registers live (just in case PTRACE_ATTACH resulted in some\n      // register pointers still being in the registers and not on the stack):\n      for (void** p = reinterpret_cast<void**>(&thread_regs);\n           p < reinterpret_cast<void**>(&thread_regs + 1); ++p) {\n        RAW_VLOG(12, \"Thread register %p\", *p);\n        thread_registers.push_back(*p);\n      }\n    } else {\n      failures += 1;\n    }\n#else\n    failures += 1;\n#endif\n  }\n  // Use all the collected thread (stack) liveness sources:\n  IgnoreLiveObjectsLocked(\"threads stack data\", \"\");\n  if (thread_registers.size()) {\n    // Make thread registers be live heap data sources.\n    // we rely here on the fact that vector is in one memory chunk:\n    RAW_VLOG(11, \"Live registers at %p of %\"PRIuS\" bytes\",\n                &thread_registers[0], thread_registers.size() * sizeof(void*));\n    live_objects->push_back(AllocObject(&thread_registers[0],\n                                        thread_registers.size() * sizeof(void*),\n                                        THREAD_REGISTERS));\n    IgnoreLiveObjectsLocked(\"threads register data\", \"\");\n  }\n  // Do all other liveness walking while all threads are stopped:\n  IgnoreNonThreadLiveObjectsLocked();\n  // Can now resume the threads:\n  ResumeAllProcessThreads(num_threads, thread_pids);\n  thread_listing_status = CALLBACK_COMPLETED;\n  return failures;\n}\n\n// Stack top of the thread that is doing the current leak check\n// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)\nstatic const void* self_thread_stack_top;\n\n// static\nvoid HeapLeakChecker::IgnoreNonThreadLiveObjectsLocked() {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  RAW_DCHECK(MemoryRegionMap::LockIsHeld(), \"\");\n  RAW_VLOG(11, \"Handling self thread with pid %d\", self_thread_pid);\n  // Register our own stack:\n\n  // Important that all stack ranges (including the one here)\n  // are known before we start looking at them\n  // in MakeDisabledLiveCallbackLocked:\n  RegisterStackLocked(self_thread_stack_top);\n  IgnoreLiveObjectsLocked(\"stack data\", \"\");\n\n  // Make objects we were told to ignore live:\n  if (ignored_objects) {\n    for (IgnoredObjectsMap::const_iterator object = ignored_objects->begin();\n         object != ignored_objects->end(); ++object) {\n      const void* ptr = AsPtr(object->first);\n      RAW_VLOG(11, \"Ignored live object at %p of %\"PRIuS\" bytes\",\n                  ptr, object->second);\n      live_objects->\n        push_back(AllocObject(ptr, object->second, MUST_BE_ON_HEAP));\n      // we do this liveness check for ignored_objects before doing any\n      // live heap walking to make sure it does not fail needlessly:\n      size_t object_size;\n      if (!(heap_profile->FindAlloc(ptr, &object_size)  &&\n            object->second == object_size)) {\n        RAW_LOG(FATAL, \"Object at %p of %\"PRIuS\" bytes from an\"\n                       \" IgnoreObject() has disappeared\", ptr, object->second);\n      }\n    }\n    IgnoreLiveObjectsLocked(\"ignored objects\", \"\");\n  }\n\n  // Treat objects that were allocated when a Disabler was live as\n  // roots.  I.e., if X was allocated while a Disabler was active,\n  // and Y is reachable from X, arrange that neither X nor Y are\n  // treated as leaks.\n  heap_profile->IterateAllocs(MakeIgnoredObjectsLiveCallbackLocked);\n  IgnoreLiveObjectsLocked(\"disabled objects\", \"\");\n\n  // Make code-address-disabled objects live and ignored:\n  // This in particular makes all thread-specific data live\n  // because the basic data structure to hold pointers to thread-specific data\n  // is allocated from libpthreads and we have range-disabled that\n  // library code with UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);\n  // so now we declare all thread-specific data reachable from there as live.\n  heap_profile->IterateAllocs(MakeDisabledLiveCallbackLocked);\n  IgnoreLiveObjectsLocked(\"disabled code\", \"\");\n\n  // Actually make global data live:\n  if (FLAGS_heap_check_ignore_global_live) {\n    bool have_null_region_callers = false;\n    for (LibraryLiveObjectsStacks::iterator l = library_live_objects->begin();\n         l != library_live_objects->end(); ++l) {\n      RAW_CHECK(live_objects->empty(), \"\");\n      // Process library_live_objects in l->second\n      // filtering them by MemoryRegionMap:\n      // It's safe to iterate over MemoryRegionMap\n      // w/o locks here as we are inside MemoryRegionMap::Lock():\n      RAW_DCHECK(MemoryRegionMap::LockIsHeld(), \"\");\n      // The only change to MemoryRegionMap possible in this loop\n      // is region addition as a result of allocating more memory\n      // for live_objects. This won't invalidate the RegionIterator\n      // or the intent of the loop.\n      // --see the comment by MemoryRegionMap::BeginRegionLocked().\n      for (MemoryRegionMap::RegionIterator region =\n             MemoryRegionMap::BeginRegionLocked();\n           region != MemoryRegionMap::EndRegionLocked(); ++region) {\n        // \"region\" from MemoryRegionMap is to be subtracted from\n        // (tentatively live) regions in l->second\n        // if it has a stack inside or it was allocated by\n        // a non-special caller (not one covered by a range\n        // in global_region_caller_ranges).\n        // This will in particular exclude all memory chunks used\n        // by the heap itself as well as what's been allocated with\n        // any allocator on top of mmap.\n        bool subtract = true;\n        if (!region->is_stack  &&  global_region_caller_ranges) {\n          if (region->caller() == static_cast<uintptr_t>(NULL)) {\n            have_null_region_callers = true;\n          } else {\n            GlobalRegionCallerRangeMap::const_iterator iter\n              = global_region_caller_ranges->upper_bound(region->caller());\n            if (iter != global_region_caller_ranges->end()) {\n              RAW_DCHECK(iter->first > region->caller(), \"\");\n              if (iter->second < region->caller()) {  // in special region\n                subtract = false;\n              }\n            }\n          }\n        }\n        if (subtract) {\n          // The loop puts the result of filtering l->second into live_objects:\n          for (LiveObjectsStack::const_iterator i = l->second.begin();\n               i != l->second.end(); ++i) {\n            // subtract *region from *i\n            uintptr_t start = AsInt(i->ptr);\n            uintptr_t end = start + i->size;\n            if (region->start_addr <= start  &&  end <= region->end_addr) {\n              // full deletion due to subsumption\n            } else if (start < region->start_addr  &&\n                       region->end_addr < end) {  // cutting-out split\n              live_objects->push_back(AllocObject(i->ptr,\n                                                  region->start_addr - start,\n                                                  IN_GLOBAL_DATA));\n              live_objects->push_back(AllocObject(AsPtr(region->end_addr),\n                                                  end - region->end_addr,\n                                                  IN_GLOBAL_DATA));\n            } else if (region->end_addr > start  &&\n                       region->start_addr <= start) {  // cut from start\n              live_objects->push_back(AllocObject(AsPtr(region->end_addr),\n                                                  end - region->end_addr,\n                                                  IN_GLOBAL_DATA));\n            } else if (region->start_addr > start  &&\n                       region->start_addr < end) {  // cut from end\n              live_objects->push_back(AllocObject(i->ptr,\n                                                  region->start_addr - start,\n                                                  IN_GLOBAL_DATA));\n            } else {  // pass: no intersection\n              live_objects->push_back(AllocObject(i->ptr, i->size,\n                                                  IN_GLOBAL_DATA));\n            }\n          }\n          // Move live_objects back into l->second\n          // for filtering by the next region.\n          live_objects->swap(l->second);\n          live_objects->clear();\n        }\n      }\n      // Now get and use live_objects from the final version of l->second:\n      if (VLOG_IS_ON(11)) {\n        for (LiveObjectsStack::const_iterator i = l->second.begin();\n             i != l->second.end(); ++i) {\n          RAW_VLOG(11, \"Library live region at %p of %\"PRIuPTR\" bytes\",\n                      i->ptr, i->size);\n        }\n      }\n      live_objects->swap(l->second);\n      IgnoreLiveObjectsLocked(\"in globals of\\n  \", l->first.c_str());\n    }\n    if (have_null_region_callers) {\n      RAW_LOG(ERROR, \"Have memory regions w/o callers: \"\n                     \"might report false leaks\");\n    }\n    Allocator::DeleteAndNull(&library_live_objects);\n  }\n}\n\n// Callback for ListAllProcessThreads in IgnoreAllLiveObjectsLocked below\n// to test/verify that we have just the one main thread, in which case\n// we can do everything in that main thread,\n// so that CPU profiler can collect all its samples.\n// Returns the number of threads in the process.\nstatic int IsOneThread(void* parameter, int num_threads,\n                       pid_t* thread_pids, va_list ap) {\n  if (num_threads != 1) {\n    RAW_LOG(WARNING, \"Have threads: Won't CPU-profile the bulk of leak \"\n                     \"checking work happening in IgnoreLiveThreadsLocked!\");\n  }\n  ResumeAllProcessThreads(num_threads, thread_pids);\n  return num_threads;\n}\n\n// Dummy for IgnoreAllLiveObjectsLocked below.\n// Making it global helps with compiler warnings.\nstatic va_list dummy_ap;\n\n// static\nvoid HeapLeakChecker::IgnoreAllLiveObjectsLocked(const void* self_stack_top) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  RAW_CHECK(live_objects == NULL, \"\");\n  live_objects = new(Allocator::Allocate(sizeof(LiveObjectsStack)))\n                   LiveObjectsStack;\n  stack_tops = new(Allocator::Allocate(sizeof(StackTopSet))) StackTopSet;\n  // reset the counts\n  live_objects_total = 0;\n  live_bytes_total = 0;\n  // Reduce max_heap_object_size to FLAGS_heap_check_max_pointer_offset\n  // for the time of leak check.\n  // FLAGS_heap_check_max_pointer_offset caps max_heap_object_size\n  // to manage reasonably low chances of random bytes\n  // appearing to be pointing into large actually leaked heap objects.\n  const size_t old_max_heap_object_size = max_heap_object_size;\n  max_heap_object_size = (\n    FLAGS_heap_check_max_pointer_offset != -1\n    ? min(size_t(FLAGS_heap_check_max_pointer_offset), max_heap_object_size)\n    : max_heap_object_size);\n  // Record global data as live:\n  if (FLAGS_heap_check_ignore_global_live) {\n    library_live_objects =\n      new(Allocator::Allocate(sizeof(LibraryLiveObjectsStacks)))\n        LibraryLiveObjectsStacks;\n  }\n  // Ignore all thread stacks:\n  thread_listing_status = CALLBACK_NOT_STARTED;\n  bool need_to_ignore_non_thread_objects = true;\n  self_thread_pid = getpid();\n  self_thread_stack_top = self_stack_top;\n  if (FLAGS_heap_check_ignore_thread_live) {\n    // In case we are doing CPU profiling we'd like to do all the work\n    // in the main thread, not in the special thread created by\n    // ListAllProcessThreads, so that CPU profiler can collect all its samples.\n    // The machinery of ListAllProcessThreads conflicts with the CPU profiler\n    // by also relying on signals and ::sigaction.\n    // We can do this (run everything in the main thread) safely\n    // only if there's just the main thread itself in our process.\n    // This variable reflects these two conditions:\n    bool want_and_can_run_in_main_thread =\n      ProfilingIsEnabledForAllThreads()  &&\n      ListAllProcessThreads(NULL, IsOneThread) == 1;\n    // When the normal path of ListAllProcessThreads below is taken,\n    // we fully suspend the threads right here before any liveness checking\n    // and keep them suspended for the whole time of liveness checking\n    // inside of the IgnoreLiveThreadsLocked callback.\n    // (The threads can't (de)allocate due to lock on the delete hook but\n    //  if not suspended they could still mess with the pointer\n    //  graph while we walk it).\n    int r = want_and_can_run_in_main_thread\n            ? IgnoreLiveThreadsLocked(NULL, 1, &self_thread_pid, dummy_ap)\n            : ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked);\n    need_to_ignore_non_thread_objects = r < 0;\n    if (r < 0) {\n      RAW_LOG(WARNING, \"Thread finding failed with %d errno=%d\", r, errno);\n      if (thread_listing_status == CALLBACK_COMPLETED) {\n        RAW_LOG(INFO, \"Thread finding callback \"\n                      \"finished ok; hopefully everything is fine\");\n        need_to_ignore_non_thread_objects = false;\n      } else if (thread_listing_status == CALLBACK_STARTED) {\n        RAW_LOG(FATAL, \"Thread finding callback was \"\n                       \"interrupted or crashed; can't fix this\");\n      } else {  // CALLBACK_NOT_STARTED\n        RAW_LOG(ERROR, \"Could not find thread stacks. \"\n                       \"Will likely report false leak positives.\");\n      }\n    } else if (r != 0) {\n      RAW_LOG(ERROR, \"Thread stacks not found for %d threads. \"\n                     \"Will likely report false leak positives.\", r);\n    } else {\n      RAW_VLOG(11, \"Thread stacks appear to be found for all threads\");\n    }\n  } else {\n    RAW_LOG(WARNING, \"Not looking for thread stacks; \"\n                     \"objects reachable only from there \"\n                     \"will be reported as leaks\");\n  }\n  // Do all other live data ignoring here if we did not do it\n  // within thread listing callback with all threads stopped.\n  if (need_to_ignore_non_thread_objects) {\n    if (FLAGS_heap_check_ignore_global_live) {\n      UseProcMapsLocked(RECORD_GLOBAL_DATA);\n    }\n    IgnoreNonThreadLiveObjectsLocked();\n  }\n  if (live_objects_total) {\n    RAW_VLOG(10, \"Ignoring %\"PRId64\" reachable objects of %\"PRId64\" bytes\",\n                live_objects_total, live_bytes_total);\n  }\n  // Free these: we made them here and heap_profile never saw them\n  Allocator::DeleteAndNull(&live_objects);\n  Allocator::DeleteAndNull(&stack_tops);\n  max_heap_object_size = old_max_heap_object_size;  // reset this var\n}\n\n// Alignment at which we should consider pointer positions\n// in IgnoreLiveObjectsLocked. Will normally use the value of\n// FLAGS_heap_check_pointer_source_alignment.\nstatic size_t pointer_source_alignment = kPointerSourceAlignment;\n// Global lock for HeapLeakChecker::DoNoLeaks\n// to protect pointer_source_alignment.\nstatic SpinLock alignment_checker_lock(SpinLock::LINKER_INITIALIZED);\n\n// This function changes the live bits in the heap_profile-table's state:\n// we only record the live objects to be skipped.\n//\n// When checking if a byte sequence points to a heap object we use\n// HeapProfileTable::FindInsideAlloc to handle both pointers to\n// the start and inside of heap-allocated objects.\n// The \"inside\" case needs to be checked to support\n// at least the following relatively common cases:\n// - C++ arrays allocated with new FooClass[size] for classes\n//   with destructors have their size recorded in a sizeof(int) field\n//   before the place normal pointers point to.\n// - basic_string<>-s for e.g. the C++ library of gcc 3.4\n//   have the meta-info in basic_string<...>::_Rep recorded\n//   before the place normal pointers point to.\n// - Multiple-inherited objects have their pointers when cast to\n//   different base classes pointing inside of the actually\n//   allocated object.\n// - Sometimes reachability pointers point to member objects of heap objects,\n//   and then those member objects point to the full heap object.\n// - Third party UnicodeString: it stores a 32-bit refcount\n//   (in both 32-bit and 64-bit binaries) as the first uint32\n//   in the allocated memory and a normal pointer points at\n//   the second uint32 behind the refcount.\n// By finding these additional objects here\n// we slightly increase the chance to mistake random memory bytes\n// for a pointer and miss a leak in a particular run of a binary.\n//\n/*static*/ void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,\n                                                         const char* name2) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  int64 live_object_count = 0;\n  int64 live_byte_count = 0;\n  while (!live_objects->empty()) {\n    const char* object =\n      reinterpret_cast<const char*>(live_objects->back().ptr);\n    size_t size = live_objects->back().size;\n    const ObjectPlacement place = live_objects->back().place;\n    live_objects->pop_back();\n    if (place == MUST_BE_ON_HEAP  &&  heap_profile->MarkAsLive(object)) {\n      live_object_count += 1;\n      live_byte_count += size;\n    }\n    RAW_VLOG(13, \"Looking for heap pointers in %p of %\"PRIuS\" bytes\",\n                object, size);\n    const char* const whole_object = object;\n    size_t const whole_size = size;\n    // Try interpretting any byte sequence in object,size as a heap pointer:\n    const size_t remainder = AsInt(object) % pointer_source_alignment;\n    if (remainder) {\n      object += pointer_source_alignment - remainder;\n      if (size >= pointer_source_alignment - remainder) {\n        size -= pointer_source_alignment - remainder;\n      } else {\n        size = 0;\n      }\n    }\n    if (size < sizeof(void*)) continue;\n    const char* const max_object = object + size - sizeof(void*);\n    while (object <= max_object) {\n      // potentially unaligned load:\n      const uintptr_t addr = *reinterpret_cast<const uintptr_t*>(object);\n      // Do fast check before the more expensive HaveOnHeapLocked lookup:\n      // this code runs for all memory words that are potentially pointers:\n      const bool can_be_on_heap =\n        // Order tests by the likelyhood of the test failing in 64/32 bit modes.\n        // Yes, this matters: we either lose 5..6% speed in 32 bit mode\n        // (which is already slower) or by a factor of 1.5..1.91 in 64 bit mode.\n        // After the alignment test got dropped the above performance figures\n        // must have changed; might need to revisit this.\n#if defined(__x86_64__)\n        addr <= max_heap_address  &&  // <= is for 0-sized object with max addr\n        min_heap_address <= addr;\n#else\n        min_heap_address <= addr  &&\n        addr <= max_heap_address;  // <= is for 0-sized object with max addr\n#endif\n      if (can_be_on_heap) {\n        const void* ptr = reinterpret_cast<const void*>(addr);\n        // Too expensive (inner loop): manually uncomment when debugging:\n        // RAW_VLOG(17, \"Trying pointer to %p at %p\", ptr, object);\n        size_t object_size;\n        if (HaveOnHeapLocked(&ptr, &object_size)  &&\n            heap_profile->MarkAsLive(ptr)) {\n          // We take the (hopefully low) risk here of encountering by accident\n          // a byte sequence in memory that matches an address of\n          // a heap object which is in fact leaked.\n          // I.e. in very rare and probably not repeatable/lasting cases\n          // we might miss some real heap memory leaks.\n          RAW_VLOG(14, \"Found pointer to %p of %\"PRIuS\" bytes at %p \"\n                      \"inside %p of size %\"PRIuS\"\",\n                      ptr, object_size, object, whole_object, whole_size);\n          if (VLOG_IS_ON(15)) {\n            // log call stacks to help debug how come something is not a leak\n            HeapProfileTable::AllocInfo alloc;\n            if (!heap_profile->FindAllocDetails(ptr, &alloc)) {\n              RAW_LOG(FATAL, \"FindAllocDetails failed on ptr %p\", ptr);\n            }\n            RAW_LOG(INFO, \"New live %p object's alloc stack:\", ptr);\n            for (int i = 0; i < alloc.stack_depth; ++i) {\n              RAW_LOG(INFO, \"  @ %p\", alloc.call_stack[i]);\n            }\n          }\n          live_object_count += 1;\n          live_byte_count += object_size;\n          live_objects->push_back(AllocObject(ptr, object_size,\n                                              IGNORED_ON_HEAP));\n        }\n      }\n      object += pointer_source_alignment;\n    }\n  }\n  live_objects_total += live_object_count;\n  live_bytes_total += live_byte_count;\n  if (live_object_count) {\n    RAW_VLOG(10, \"Removed %\"PRId64\" live heap objects of %\"PRId64\" bytes: %s%s\",\n                live_object_count, live_byte_count, name, name2);\n  }\n}\n\n//----------------------------------------------------------------------\n// HeapLeakChecker leak check disabling components\n//----------------------------------------------------------------------\n\n// static\nvoid HeapLeakChecker::DisableChecksIn(const char* pattern) {\n  RAW_LOG(WARNING, \"DisableChecksIn(%s) is ignored\", pattern);\n}\n\n// static\nvoid HeapLeakChecker::IgnoreObject(const void* ptr) {\n  SpinLockHolder l(&heap_checker_lock);\n  if (!heap_checker_on) return;\n  size_t object_size;\n  if (!HaveOnHeapLocked(&ptr, &object_size)) {\n    RAW_LOG(ERROR, \"No live heap object at %p to ignore\", ptr);\n  } else {\n    RAW_VLOG(10, \"Going to ignore live object at %p of %\"PRIuS\" bytes\",\n                ptr, object_size);\n    if (ignored_objects == NULL)  {\n      ignored_objects = new(Allocator::Allocate(sizeof(IgnoredObjectsMap)))\n                          IgnoredObjectsMap;\n    }\n    if (!ignored_objects->insert(make_pair(AsInt(ptr), object_size)).second) {\n      RAW_LOG(FATAL, \"Object at %p is already being ignored\", ptr);\n    }\n  }\n}\n\n// static\nvoid HeapLeakChecker::UnIgnoreObject(const void* ptr) {\n  SpinLockHolder l(&heap_checker_lock);\n  if (!heap_checker_on) return;\n  size_t object_size;\n  if (!HaveOnHeapLocked(&ptr, &object_size)) {\n    RAW_LOG(FATAL, \"No live heap object at %p to un-ignore\", ptr);\n  } else {\n    bool found = false;\n    if (ignored_objects) {\n      IgnoredObjectsMap::iterator object = ignored_objects->find(AsInt(ptr));\n      if (object != ignored_objects->end()  &&  object_size == object->second) {\n        ignored_objects->erase(object);\n        found = true;\n        RAW_VLOG(10, \"Now not going to ignore live object \"\n                    \"at %p of %\"PRIuS\" bytes\", ptr, object_size);\n      }\n    }\n    if (!found)  RAW_LOG(FATAL, \"Object at %p has not been ignored\", ptr);\n  }\n}\n\n//----------------------------------------------------------------------\n// HeapLeakChecker non-static functions\n//----------------------------------------------------------------------\n\nchar* HeapLeakChecker::MakeProfileNameLocked() {\n  RAW_DCHECK(lock_->IsHeld(), \"\");\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  const int len = profile_name_prefix->size() + strlen(name_) + 5 +\n                  strlen(HeapProfileTable::kFileExt) + 1;\n  char* file_name = reinterpret_cast<char*>(Allocator::Allocate(len));\n  snprintf(file_name, len, \"%s.%s-end%s\",\n           profile_name_prefix->c_str(), name_,\n           HeapProfileTable::kFileExt);\n  return file_name;\n}\n\nvoid HeapLeakChecker::Create(const char *name, bool make_start_snapshot) {\n  SpinLockHolder l(lock_);\n  name_ = NULL;  // checker is inactive\n  start_snapshot_ = NULL;\n  has_checked_ = false;\n  inuse_bytes_increase_ = 0;\n  inuse_allocs_increase_ = 0;\n  keep_profiles_ = false;\n  char* n = new char[strlen(name) + 1];   // do this before we lock\n  IgnoreObject(n);  // otherwise it might be treated as live due to our stack\n  { // Heap activity in other threads is paused for this whole scope.\n    SpinLockHolder al(&alignment_checker_lock);\n    SpinLockHolder hl(&heap_checker_lock);\n    MemoryRegionMap::LockHolder ml;\n    if (heap_checker_on  &&  profile_name_prefix != NULL) {\n      RAW_DCHECK(strchr(name, '/') == NULL, \"must be a simple name\");\n      memcpy(n, name, strlen(name) + 1);\n      name_ = n;  // checker is active\n      if (make_start_snapshot) {\n        start_snapshot_ = heap_profile->TakeSnapshot();\n      }\n\n      const HeapProfileTable::Stats& t = heap_profile->total();\n      const size_t start_inuse_bytes = t.alloc_size - t.free_size;\n      const size_t start_inuse_allocs = t.allocs - t.frees;\n      RAW_VLOG(10, \"Start check \\\"%s\\\" profile: %\"PRIuS\" bytes \"\n               \"in %\"PRIuS\" objects\",\n               name_, start_inuse_bytes, start_inuse_allocs);\n    } else {\n      RAW_LOG(WARNING, \"Heap checker is not active, \"\n                       \"hence checker \\\"%s\\\" will do nothing!\", name);\n    RAW_LOG(WARNING, \"To activate set the HEAPCHECK environment variable.\\n\");\n    }\n  }\n  if (name_ == NULL) {\n    UnIgnoreObject(n);\n    delete[] n;  // must be done after we unlock\n  }\n}\n\nHeapLeakChecker::HeapLeakChecker(const char *name) : lock_(new SpinLock) {\n  RAW_DCHECK(strcmp(name, \"_main_\") != 0, \"_main_ is reserved\");\n  Create(name, true/*create start_snapshot_*/);\n}\n\nHeapLeakChecker::HeapLeakChecker() : lock_(new SpinLock) {\n  if (FLAGS_heap_check_before_constructors) {\n    // We want to check for leaks of objects allocated during global\n    // constructors (i.e., objects allocated already).  So we do not\n    // create a baseline snapshot and hence check for leaks of objects\n    // that may have already been created.\n    Create(\"_main_\", false);\n  } else {\n    // We want to ignore leaks of objects allocated during global\n    // constructors (i.e., objects allocated already).  So we snapshot\n    // the current heap contents and use them as a baseline that is\n    // not reported by the leak checker.\n    Create(\"_main_\", true);\n  }\n}\n\nssize_t HeapLeakChecker::BytesLeaked() const {\n  SpinLockHolder l(lock_);\n  if (!has_checked_) {\n    RAW_LOG(FATAL, \"*NoLeaks|SameHeap must execute before this call\");\n  }\n  return inuse_bytes_increase_;\n}\n\nssize_t HeapLeakChecker::ObjectsLeaked() const {\n  SpinLockHolder l(lock_);\n  if (!has_checked_) {\n    RAW_LOG(FATAL, \"*NoLeaks|SameHeap must execute before this call\");\n  }\n  return inuse_allocs_increase_;\n}\n\n// Save pid of main thread for using in naming dump files\nstatic int32 main_thread_pid = getpid();\n#ifdef HAVE_PROGRAM_INVOCATION_NAME\nextern char* program_invocation_name;\nextern char* program_invocation_short_name;\nstatic const char* invocation_name() { return program_invocation_short_name; }\nstatic string invocation_path() { return program_invocation_name; }\n#else\nstatic const char* invocation_name() { return \"<your binary>\"; }\nstatic string invocation_path() { return \"<your binary>\"; }\n#endif\n\n// Prints commands that users can run to get more information\n// about the reported leaks.\nstatic void SuggestPprofCommand(const char* pprof_file_arg) {\n  // Extra help information to print for the user when the test is\n  // being run in a way where the straightforward pprof command will\n  // not suffice.\n  string extra_help;\n\n  // Common header info to print for remote runs\n  const string remote_header =\n      \"This program is being executed remotely and therefore the pprof\\n\"\n      \"command printed above will not work.  Either run this program\\n\"\n      \"locally, or adjust the pprof command as follows to allow it to\\n\"\n      \"work on your local machine:\\n\";\n\n  // Extra command for fetching remote data\n  string fetch_cmd;\n\n  RAW_LOG(WARNING,\n          \"\\n\\n\"\n          \"If the preceding stack traces are not enough to find \"\n          \"the leaks, try running THIS shell command:\\n\\n\"\n          \"%s%s %s \\\"%s\\\" --inuse_objects --lines --heapcheck \"\n          \" --edgefraction=1e-10 --nodefraction=1e-10 --gv\\n\"\n          \"\\n\"\n          \"%s\"\n          \"If you are still puzzled about why the leaks are \"\n          \"there, try rerunning this program with \"\n          \"HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with \"\n          \"HEAP_CHECK_MAX_POINTER_OFFSET=-1\\n\"\n          \"If the leak report occurs in a small fraction of runs, \"\n          \"try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB \"\n          \"or with TCMALLOC_RECLAIM_MEMORY=false, \"  // only works for debugalloc\n          \"it might help find leaks more repeatably\\n\",\n          fetch_cmd.c_str(),\n          \"pprof\",           // works as long as pprof is on your path\n          invocation_path().c_str(),\n          pprof_file_arg,\n          extra_help.c_str()\n          );\n}\n\nbool HeapLeakChecker::DoNoLeaks(ShouldSymbolize should_symbolize) {\n  SpinLockHolder l(lock_);\n  // The locking also helps us keep the messages\n  // for the two checks close together.\n  SpinLockHolder al(&alignment_checker_lock);\n\n  // thread-safe: protected by alignment_checker_lock\n  static bool have_disabled_hooks_for_symbolize = false;\n  // Once we've checked for leaks and symbolized the results once, it's\n  // not safe to do it again.  This is because in order to symbolize\n  // safely, we had to disable all the malloc hooks here, so we no\n  // longer can be confident we've collected all the data we need.\n  if (have_disabled_hooks_for_symbolize) {\n    RAW_LOG(FATAL, \"Must not call heap leak checker manually after \"\n            \" program-exit's automatic check.\");\n  }\n\n  HeapProfileTable::Snapshot* leaks = NULL;\n  char* pprof_file = NULL;\n\n  {\n    // Heap activity in other threads is paused during this function\n    // (i.e. until we got all profile difference info).\n    SpinLockHolder hl(&heap_checker_lock);\n    if (heap_checker_on == false) {\n      if (name_ != NULL) {  // leak checking enabled when created the checker\n        RAW_LOG(WARNING, \"Heap leak checker got turned off after checker \"\n                \"\\\"%s\\\" has been created, no leak check is being done for it!\",\n                name_);\n      }\n      return true;\n    }\n\n    // Update global_region_caller_ranges. They may need to change since\n    // e.g. initialization because shared libraries might have been loaded or\n    // unloaded.\n    Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);\n    ProcMapsResult pm_result = UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);\n    RAW_CHECK(pm_result == PROC_MAPS_USED, \"\");\n\n    // Keep track of number of internally allocated objects so we\n    // can detect leaks in the heap-leak-checket itself\n    const int initial_allocs = Allocator::alloc_count();\n\n    if (name_ == NULL) {\n      RAW_LOG(FATAL, \"Heap leak checker must not be turned on \"\n              \"after construction of a HeapLeakChecker\");\n    }\n\n    MemoryRegionMap::LockHolder ml;\n    int a_local_var;  // Use our stack ptr to make stack data live:\n\n    // Sanity check that nobody is messing with the hooks we need:\n    // Important to have it here: else we can misteriously SIGSEGV\n    // in IgnoreLiveObjectsLocked inside ListAllProcessThreads's callback\n    // by looking into a region that got unmapped w/o our knowledge.\n    MemoryRegionMap::CheckMallocHooks();\n    if (MallocHook::GetNewHook() != NewHook  ||\n        MallocHook::GetDeleteHook() != DeleteHook) {\n      RAW_LOG(FATAL, \"Had our new/delete MallocHook-s replaced. \"\n              \"Are you using another MallocHook client? \"\n              \"Use --heap_check=\\\"\\\" to avoid this conflict.\");\n    }\n\n    // Make the heap profile, other threads are locked out.\n    HeapProfileTable::Snapshot* base =\n        reinterpret_cast<HeapProfileTable::Snapshot*>(start_snapshot_);\n    RAW_DCHECK(FLAGS_heap_check_pointer_source_alignment > 0, \"\");\n    pointer_source_alignment = FLAGS_heap_check_pointer_source_alignment;\n    IgnoreAllLiveObjectsLocked(&a_local_var);\n    leaks = heap_profile->NonLiveSnapshot(base);\n\n    inuse_bytes_increase_ = static_cast<ssize_t>(leaks->total().alloc_size);\n    inuse_allocs_increase_ = static_cast<ssize_t>(leaks->total().allocs);\n    if (leaks->Empty()) {\n      heap_profile->ReleaseSnapshot(leaks);\n      leaks = NULL;\n\n      // We can only check for internal leaks along the no-user-leak\n      // path since in the leak path we temporarily release\n      // heap_checker_lock and another thread can come in and disturb\n      // allocation counts.\n      if (Allocator::alloc_count() != initial_allocs) {\n        RAW_LOG(FATAL, \"Internal HeapChecker leak of %d objects ; %d -> %d\",\n                Allocator::alloc_count() - initial_allocs,\n                initial_allocs, Allocator::alloc_count());\n      }\n    } else if (FLAGS_heap_check_test_pointer_alignment) {\n      if (pointer_source_alignment == 1) {\n        RAW_LOG(WARNING, \"--heap_check_test_pointer_alignment has no effect: \"\n                \"--heap_check_pointer_source_alignment was already set to 1\");\n      } else {\n        // Try with reduced pointer aligment\n        pointer_source_alignment = 1;\n        IgnoreAllLiveObjectsLocked(&a_local_var);\n        HeapProfileTable::Snapshot* leaks_wo_align =\n            heap_profile->NonLiveSnapshot(base);\n        pointer_source_alignment = FLAGS_heap_check_pointer_source_alignment;\n        if (leaks_wo_align->Empty()) {\n          RAW_LOG(WARNING, \"Found no leaks without pointer alignment: \"\n                  \"something might be placing pointers at \"\n                  \"unaligned addresses! This needs to be fixed.\");\n        } else {\n          RAW_LOG(INFO, \"Found leaks without pointer alignment as well: \"\n                  \"unaligned pointers must not be the cause of leaks.\");\n          RAW_LOG(INFO, \"--heap_check_test_pointer_alignment did not help \"\n                  \"to diagnose the leaks.\");\n        }\n        heap_profile->ReleaseSnapshot(leaks_wo_align);\n      }\n    }\n\n    if (leaks != NULL) {\n      pprof_file = MakeProfileNameLocked();\n    }\n  }\n\n  has_checked_ = true;\n  if (leaks == NULL) {\n    if (FLAGS_heap_check_max_pointer_offset == -1) {\n      RAW_LOG(WARNING,\n              \"Found no leaks without max_pointer_offset restriction: \"\n              \"it's possible that the default value of \"\n              \"heap_check_max_pointer_offset flag is too low. \"\n              \"Do you use pointers with larger than that offsets \"\n              \"pointing in the middle of heap-allocated objects?\");\n    }\n    const HeapProfileTable::Stats& stats = heap_profile->total();\n    RAW_VLOG(heap_checker_info_level,\n             \"No leaks found for check \\\"%s\\\" \"\n             \"(but no 100%% guarantee that there aren't any): \"\n             \"found %\"PRId64\" reachable heap objects of %\"PRId64\" bytes\",\n             name_,\n             int64(stats.allocs - stats.frees),\n             int64(stats.alloc_size - stats.free_size));\n  } else {\n    if (should_symbolize == SYMBOLIZE) {\n      // To turn addresses into symbols, we need to fork, which is a\n      // problem if both parent and child end up trying to call the\n      // same malloc-hooks we've set up, at the same time.  To avoid\n      // trouble, we turn off the hooks before symbolizing.  Note that\n      // this makes it unsafe to ever leak-report again!  Luckily, we\n      // typically only want to report once in a program's run, at the\n      // very end.\n      if (MallocHook::GetNewHook() == NewHook)\n        MallocHook::SetNewHook(NULL);\n      if (MallocHook::GetDeleteHook() == DeleteHook)\n        MallocHook::SetDeleteHook(NULL);\n      MemoryRegionMap::Shutdown();\n      // Make sure all the hooks really got unset:\n      RAW_CHECK(MallocHook::GetNewHook() == NULL, \"\");\n      RAW_CHECK(MallocHook::GetDeleteHook() == NULL, \"\");\n      RAW_CHECK(MallocHook::GetMmapHook() == NULL, \"\");\n      RAW_CHECK(MallocHook::GetSbrkHook() == NULL, \"\");\n      have_disabled_hooks_for_symbolize = true;\n      leaks->ReportLeaks(name_, pprof_file, true);  // true = should_symbolize\n    } else {\n      leaks->ReportLeaks(name_, pprof_file, false);\n    }\n    if (FLAGS_heap_check_identify_leaks) {\n      leaks->ReportIndividualObjects();\n    }\n\n    SuggestPprofCommand(pprof_file);\n\n    {\n      SpinLockHolder hl(&heap_checker_lock);\n      heap_profile->ReleaseSnapshot(leaks);\n      Allocator::Free(pprof_file);\n    }\n  }\n\n  return (leaks == NULL);\n}\n\nHeapLeakChecker::~HeapLeakChecker() {\n  if (name_ != NULL) {  // had leak checking enabled when created the checker\n    if (!has_checked_) {\n      RAW_LOG(FATAL, \"Some *NoLeaks|SameHeap method\"\n                     \" must be called on any created HeapLeakChecker\");\n    }\n\n    // Deallocate any snapshot taken at start\n    if (start_snapshot_ != NULL) {\n      SpinLockHolder l(&heap_checker_lock);\n      heap_profile->ReleaseSnapshot(\n          reinterpret_cast<HeapProfileTable::Snapshot*>(start_snapshot_));\n    }\n\n    UnIgnoreObject(name_);\n    delete[] name_;\n    name_ = NULL;\n  }\n  delete lock_;\n}\n\n//----------------------------------------------------------------------\n// HeapLeakChecker overall heap check components\n//----------------------------------------------------------------------\n\n// static\nbool HeapLeakChecker::IsActive() {\n  SpinLockHolder l(&heap_checker_lock);\n  return heap_checker_on;\n}\n\nvector<HeapCleaner::void_function>* HeapCleaner::heap_cleanups_ = NULL;\n\n// When a HeapCleaner object is intialized, add its function to the static list\n// of cleaners to be run before leaks checking.\nHeapCleaner::HeapCleaner(void_function f) {\n  if (heap_cleanups_ == NULL)\n    heap_cleanups_ = new vector<HeapCleaner::void_function>;\n  heap_cleanups_->push_back(f);\n}\n\n// Run all of the cleanup functions and delete the vector.\nvoid HeapCleaner::RunHeapCleanups() {\n  if (!heap_cleanups_)\n    return;\n  for (int i = 0; i < heap_cleanups_->size(); i++) {\n    void (*f)(void) = (*heap_cleanups_)[i];\n    f();\n  }\n  delete heap_cleanups_;\n  heap_cleanups_ = NULL;\n}\n\n// Program exit heap cleanup registered with atexit().\n// Will not get executed when we crash on a signal.\n//\n/*static*/ void HeapLeakChecker::RunHeapCleanups() {\n  { SpinLockHolder l(&heap_checker_lock);\n    // can get here (via forks?) with other pids\n    if (heap_checker_pid != getpid()) return;\n  }\n  HeapCleaner::RunHeapCleanups();\n  if (!FLAGS_heap_check_after_destructors) DoMainHeapCheck();\n}\n\nstatic bool internal_init_start_has_run = false;\n\n// Called exactly once, before main() (but hopefully just before).\n// This picks a good unique name for the dumped leak checking heap profiles.\n//\n// Because we crash when InternalInitStart is called more than once,\n// it's fine that we hold heap_checker_lock only around pieces of\n// this function: this is still enough for thread-safety w.r.t. other functions\n// of this module.\n// We can't hold heap_checker_lock throughout because it would deadlock\n// on a memory allocation since our new/delete hooks can be on.\n//\n/*static*/ void HeapLeakChecker::InternalInitStart() {\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_CHECK(!internal_init_start_has_run,\n              \"Heap-check constructor called twice.  Perhaps you both linked\"\n              \" in the heap checker, and also used LD_PRELOAD to load it?\");\n    internal_init_start_has_run = true;\n\n    if (FLAGS_heap_check.empty()) {\n      // turns out we do not need checking in the end; can stop profiling\n      TurnItselfOffLocked();\n      return;\n    }\n  }\n\n  // Changing this to false can be useful when debugging heap-checker itself:\n  if (!FLAGS_heap_check_run_under_gdb && IsDebuggerAttached()) {\n    RAW_LOG(WARNING, \"Someone is ptrace()ing us; will turn itself off\");\n    SpinLockHolder l(&heap_checker_lock);\n    TurnItselfOffLocked();\n    return;\n  }\n\n  { SpinLockHolder l(&heap_checker_lock);\n    if (!constructor_heap_profiling) {\n      RAW_LOG(FATAL, \"Can not start so late. You have to enable heap checking \"\n\t             \"with HEAPCHECK=<mode>.\");\n    }\n  }\n\n  // Set all flags\n  RAW_DCHECK(FLAGS_heap_check_pointer_source_alignment > 0, \"\");\n  if (FLAGS_heap_check == \"minimal\") {\n    // The least we can check.\n    FLAGS_heap_check_before_constructors = false;  // from after main\n                                                   // (ignore more)\n    FLAGS_heap_check_after_destructors = false;  // to after cleanup\n                                                 // (most data is live)\n    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live\n    FLAGS_heap_check_ignore_global_live = true;  // ignore all live\n  } else if (FLAGS_heap_check == \"normal\") {\n    // Faster than 'minimal' and not much stricter.\n    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)\n    FLAGS_heap_check_after_destructors = false;  // to after cleanup\n                                                 // (most data is live)\n    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live\n    FLAGS_heap_check_ignore_global_live = true;  // ignore all live\n  } else if (FLAGS_heap_check == \"strict\") {\n    // A bit stricter than 'normal': global destructors must fully clean up\n    // after themselves if they are present.\n    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)\n    FLAGS_heap_check_after_destructors = true;  // to after destructors\n                                                // (less data live)\n    FLAGS_heap_check_ignore_thread_live = true;  // ignore all live\n    FLAGS_heap_check_ignore_global_live = true;  // ignore all live\n  } else if (FLAGS_heap_check == \"draconian\") {\n    // Drop not very portable and not very exact live heap flooding.\n    FLAGS_heap_check_before_constructors = true;  // from no profile (fast)\n    FLAGS_heap_check_after_destructors = true;  // to after destructors\n                                                // (need them)\n    FLAGS_heap_check_ignore_thread_live = false;  // no live flood (stricter)\n    FLAGS_heap_check_ignore_global_live = false;  // no live flood (stricter)\n  } else if (FLAGS_heap_check == \"as-is\") {\n    // do nothing: use other flags as is\n  } else if (FLAGS_heap_check == \"local\") {\n    // do nothing\n  } else {\n    RAW_LOG(FATAL, \"Unsupported heap_check flag: %s\",\n                   FLAGS_heap_check.c_str());\n  }\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_DCHECK(heap_checker_pid == getpid(), \"\");\n    heap_checker_on = true;\n    RAW_DCHECK(heap_profile, \"\");\n    ProcMapsResult pm_result = UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);\n      // might neeed to do this more than once\n      // if one later dynamically loads libraries that we want disabled\n    if (pm_result != PROC_MAPS_USED) {  // can't function\n      TurnItselfOffLocked();\n      return;\n    }\n  }\n\n  // make a good place and name for heap profile leak dumps\n  string* profile_prefix =\n    new string(FLAGS_heap_check_dump_directory + \"/\" + invocation_name());\n\n  // Finalize prefix for dumping leak checking profiles.\n  const int32 our_pid = getpid();   // safest to call getpid() outside lock\n  { SpinLockHolder l(&heap_checker_lock);\n    // main_thread_pid might still be 0 if this function is being called before\n    // global constructors.  In that case, our pid *is* the main pid.\n    if (main_thread_pid == 0)\n      main_thread_pid = our_pid;\n  }\n  char pid_buf[15];\n  snprintf(pid_buf, sizeof(pid_buf), \".%d\", main_thread_pid);\n  *profile_prefix += pid_buf;\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_DCHECK(profile_name_prefix == NULL, \"\");\n    profile_name_prefix = profile_prefix;\n  }\n\n  // Make sure new/delete hooks are installed properly\n  // and heap profiler is indeed able to keep track\n  // of the objects being allocated.\n  // We test this to make sure we are indeed checking for leaks.\n  char* test_str = new char[5];\n  size_t size;\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_CHECK(heap_profile->FindAlloc(test_str, &size),\n              \"our own new/delete not linked?\");\n  }\n  delete[] test_str;\n  { SpinLockHolder l(&heap_checker_lock);\n    // This check can fail when it should not if another thread allocates\n    // into this same spot right this moment,\n    // which is unlikely since this code runs in InitGoogle.\n    RAW_CHECK(!heap_profile->FindAlloc(test_str, &size),\n              \"our own new/delete not linked?\");\n  }\n  // If we crash in the above code, it probably means that\n  // \"nm <this_binary> | grep new\" will show that tcmalloc's new/delete\n  // implementation did not get linked-in into this binary\n  // (i.e. nm will list __builtin_new and __builtin_vec_new as undefined).\n  // If this happens, it is a BUILD bug to be fixed.\n\n  RAW_VLOG(heap_checker_info_level,\n           \"WARNING: Perftools heap leak checker is active \"\n           \"-- Performance may suffer\");\n\n  if (FLAGS_heap_check != \"local\") {\n    // Schedule registered heap cleanup\n    atexit(RunHeapCleanups);\n    HeapLeakChecker* main_hc = new HeapLeakChecker();\n    SpinLockHolder l(&heap_checker_lock);\n    RAW_DCHECK(main_heap_checker == NULL,\n               \"Repeated creation of main_heap_checker\");\n    main_heap_checker = main_hc;\n    do_main_heap_check = true;\n  }\n\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_CHECK(heap_checker_on  &&  constructor_heap_profiling,\n              \"Leak checking is expected to be fully turned on now\");\n  }\n\n  // For binaries built in debug mode, this will set release queue of\n  // debugallocation.cc to 100M to make it less likely for real leaks to\n  // be hidden due to reuse of heap memory object addresses.\n  // Running a test with --malloc_reclaim_memory=0 would help find leaks even\n  // better, but the test might run out of memory as a result.\n  // The scenario is that a heap object at address X is allocated and freed,\n  // but some other data-structure still retains a pointer to X.\n  // Then the same heap memory is used for another object, which is leaked,\n  // but the leak is not noticed due to the pointer to the original object at X.\n  // TODO(csilvers): support this in some manner.\n#if 0\n  SetCommandLineOptionWithMode(\"max_free_queue_size\", \"104857600\",  // 100M\n                               SET_FLAG_IF_DEFAULT);\n#endif\n}\n\n// We want this to run early as well, but not so early as\n// ::BeforeConstructors (we want flag assignments to have already\n// happened, for instance).  Initializer-registration does the trick.\nREGISTER_MODULE_INITIALIZER(init_start, HeapLeakChecker::InternalInitStart());\n\n// static\nbool HeapLeakChecker::DoMainHeapCheck() {\n  if (FLAGS_heap_check_delay_seconds > 0) {\n    sleep(FLAGS_heap_check_delay_seconds);\n  }\n  { SpinLockHolder l(&heap_checker_lock);\n    if (!do_main_heap_check) return false;\n    RAW_DCHECK(heap_checker_pid == getpid(), \"\");\n    do_main_heap_check = false;  // will do it now; no need to do it more\n  }\n\n  if (!NoGlobalLeaks()) {\n    if (FLAGS_heap_check_identify_leaks) {\n      RAW_LOG(FATAL, \"Whole-program memory leaks found.\");\n    }\n    RAW_LOG(ERROR, \"Exiting with error code (instead of crashing) \"\n                   \"because of whole-program memory leaks\");\n    _exit(1);    // we don't want to call atexit() routines!\n  }\n  return true;\n}\n\n// static\nHeapLeakChecker* HeapLeakChecker::GlobalChecker() {\n  SpinLockHolder l(&heap_checker_lock);\n  return main_heap_checker;\n}\n\n// static\nbool HeapLeakChecker::NoGlobalLeaks() {\n  // we never delete or change main_heap_checker once it's set:\n  HeapLeakChecker* main_hc = GlobalChecker();\n  if (main_hc) {\n    RAW_VLOG(10, \"Checking for whole-program memory leaks\");\n    // The program is over, so it's safe to symbolize addresses (which\n    // requires a fork) because no serious work is expected to be done\n    // after this.  Symbolizing is really useful -- knowing what\n    // function has a leak is better than knowing just an address --\n    // and while we can only safely symbolize once in a program run,\n    // now is the time (after all, there's no \"later\" that would be better).\n    return main_hc->DoNoLeaks(SYMBOLIZE);\n  }\n  return true;\n}\n\n// static\nvoid HeapLeakChecker::CancelGlobalCheck() {\n  SpinLockHolder l(&heap_checker_lock);\n  if (do_main_heap_check) {\n    RAW_VLOG(heap_checker_info_level,\n             \"Canceling the automatic at-exit whole-program memory leak check\");\n    do_main_heap_check = false;\n  }\n}\n\n//----------------------------------------------------------------------\n// HeapLeakChecker global constructor/destructor ordering components\n//----------------------------------------------------------------------\n\n#ifdef HAVE___ATTRIBUTE__   // we need __attribute__((weak)) for this to work\n#define INSTALLED_INITIAL_MALLOC_HOOKS\n\nvoid HeapLeakChecker_BeforeConstructors();  // below\nstatic bool in_initial_malloc_hook = false;\n\n// Helper for InitialMallocHook_* below\nstatic inline void InitHeapLeakCheckerFromMallocHook() {\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_CHECK(!in_initial_malloc_hook,\n              \"Something did not reset initial MallocHook-s\");\n    in_initial_malloc_hook = true;\n  }\n  // Initialize heap checker on the very first allocation/mmap/sbrk call:\n  HeapLeakChecker_BeforeConstructors();\n  { SpinLockHolder l(&heap_checker_lock);\n    in_initial_malloc_hook = false;\n  }\n}\n\n// These will owerwrite the weak definitions in malloc_hook.cc:\n\n// Important to have this to catch the first allocation call from the binary:\nextern \"C\" void InitialMallocHook_New(const void* ptr, size_t size) {\n  InitHeapLeakCheckerFromMallocHook();\n  // record this first allocation as well (if we need to):\n  MallocHook::InvokeNewHook(ptr, size);\n}\n\n// Important to have this to catch the first mmap call (say from tcmalloc):\nextern \"C\" void InitialMallocHook_MMap(const void* result,\n                                       const void* start,\n                                       size_t size,\n                                       int protection,\n                                       int flags,\n                                       int fd,\n                                       off_t offset) {\n  InitHeapLeakCheckerFromMallocHook();\n  // record this first mmap as well (if we need to):\n  MallocHook::InvokeMmapHook(\n    result, start, size, protection, flags, fd, offset);\n}\n\n// Important to have this to catch the first sbrk call (say from tcmalloc):\nextern \"C\" void InitialMallocHook_Sbrk(const void* result,\n                                       ptrdiff_t increment) {\n  InitHeapLeakCheckerFromMallocHook();\n  // record this first sbrk as well (if we need to):\n  MallocHook::InvokeSbrkHook(result, increment);\n}\n\n// static\nvoid CancelInitialMallocHooks() {\n  if (MallocHook::GetNewHook() == InitialMallocHook_New) {\n    MallocHook::SetNewHook(NULL);\n  }\n  RAW_DCHECK(MallocHook::GetNewHook() == NULL, \"\");\n  if (MallocHook::GetMmapHook() == InitialMallocHook_MMap) {\n    MallocHook::SetMmapHook(NULL);\n  }\n  RAW_DCHECK(MallocHook::GetMmapHook() == NULL, \"\");\n  if (MallocHook::GetSbrkHook() == InitialMallocHook_Sbrk) {\n    MallocHook::SetSbrkHook(NULL);\n  }\n  RAW_DCHECK(MallocHook::GetSbrkHook() == NULL, \"\");\n}\n\n#else\n\n// static\nvoid CancelInitialMallocHooks() {}\n\n#endif\n\n// static\nvoid HeapLeakChecker::BeforeConstructorsLocked() {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  RAW_CHECK(!constructor_heap_profiling,\n            \"BeforeConstructorsLocked called multiple times\");\n  CancelInitialMallocHooks();\n  // Set hooks early to crash if 'new' gets called before we make heap_profile,\n  // and make sure no other hooks existed:\n  if (MallocHook::SetNewHook(NewHook) != NULL  ||\n      MallocHook::SetDeleteHook(DeleteHook) != NULL) {\n    RAW_LOG(FATAL, \"Had other new/delete MallocHook-s set. \"\n                   \"Somehow leak checker got activated \"\n                   \"after something else have set up these hooks.\");\n  }\n  constructor_heap_profiling = true;\n  MemoryRegionMap::Init(1);\n    // Set up MemoryRegionMap with (at least) one caller stack frame to record\n    // (important that it's done before HeapProfileTable creation below).\n  Allocator::Init();\n  RAW_CHECK(heap_profile == NULL, \"\");\n  heap_profile = new(Allocator::Allocate(sizeof(HeapProfileTable)))\n                   HeapProfileTable(&Allocator::Allocate, &Allocator::Free);\n  RAW_VLOG(10, \"Starting tracking the heap\");\n  heap_checker_on = true;\n}\n\n// static\nvoid HeapLeakChecker::TurnItselfOffLocked() {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  // Set FLAGS_heap_check to \"\", for users who test for it\n  if (!FLAGS_heap_check.empty())  // be a noop in the common case\n    FLAGS_heap_check.clear();     // because clear() could allocate memory\n  if (constructor_heap_profiling) {\n    RAW_CHECK(heap_checker_on, \"\");\n    RAW_VLOG(heap_checker_info_level, \"Turning perftools heap leak checking off\");\n    heap_checker_on = false;\n    // Unset our hooks checking they were the ones set:\n    if (MallocHook::SetNewHook(NULL) != NewHook  ||\n        MallocHook::SetDeleteHook(NULL) != DeleteHook) {\n      RAW_LOG(FATAL, \"Had our new/delete MallocHook-s replaced. \"\n                     \"Are you using another MallocHook client?\");\n    }\n    Allocator::DeleteAndNull(&heap_profile);\n    // free our optional global data:\n    Allocator::DeleteAndNullIfNot(&ignored_objects);\n    Allocator::DeleteAndNullIfNot(&disabled_ranges);\n    Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);\n    Allocator::Shutdown();\n    MemoryRegionMap::Shutdown();\n  }\n  RAW_CHECK(!heap_checker_on, \"\");\n}\n\nextern bool heap_leak_checker_bcad_variable;  // in heap-checker-bcad.cc\n\nstatic bool has_called_before_constructors = false;\n\nvoid HeapLeakChecker_BeforeConstructors() {\n  SpinLockHolder l(&heap_checker_lock);\n  // We can be called from several places: the first mmap/sbrk/alloc call\n  // or the first global c-tor from heap-checker-bcad.cc:\n  // Do not re-execute initialization:\n  if (has_called_before_constructors) return;\n  has_called_before_constructors = true;\n\n  heap_checker_pid = getpid();  // set it always\n  heap_leak_checker_bcad_variable = true;\n  // just to reference it, so that heap-checker-bcad.o is linked in\n\n  // This function can be called *very* early, before the normal\n  // global-constructor that sets FLAGS_verbose.  Set it manually now,\n  // so the RAW_LOG messages here are controllable.\n  const char* verbose_str = GetenvBeforeMain(\"PERFTOOLS_VERBOSE\");\n  if (verbose_str && atoi(verbose_str)) {  // different than the default of 0?\n    FLAGS_verbose = atoi(verbose_str);\n  }\n\n  bool need_heap_check = true;\n  // The user indicates a desire for heap-checking via the HEAPCHECK\n  // environment variable.  If it's not set, there's no way to do\n  // heap-checking.\n  if (!GetenvBeforeMain(\"HEAPCHECK\")) {\n    need_heap_check = false;\n  }\n#ifdef HAVE_GETEUID\n  if (need_heap_check && getuid() != geteuid()) {\n    // heap-checker writes out files.  Thus, for security reasons, we don't\n    // recognize the env. var. to turn on heap-checking if we're setuid.\n    RAW_LOG(WARNING, (\"HeapChecker: ignoring HEAPCHECK because \"\n                      \"program seems to be setuid\\n\"));\n    need_heap_check = false;\n  }\n#endif\n  if (need_heap_check) {\n    HeapLeakChecker::BeforeConstructorsLocked();\n  } else {  // cancel our initial hooks\n    CancelInitialMallocHooks();\n  }\n}\n\n// This function is executed after all global object destructors run.\nvoid HeapLeakChecker_AfterDestructors() {\n  { SpinLockHolder l(&heap_checker_lock);\n    // can get here (via forks?) with other pids\n    if (heap_checker_pid != getpid()) return;\n  }\n  if (FLAGS_heap_check_after_destructors) {\n    if (HeapLeakChecker::DoMainHeapCheck()) {\n      const struct timespec sleep_time = { 0, 500000000 };  // 500 ms\n      nanosleep(&sleep_time, NULL);\n        // Need this hack to wait for other pthreads to exit.\n        // Otherwise tcmalloc find errors\n        // on a free() call from pthreads.\n    }\n  }\n  SpinLockHolder l(&heap_checker_lock);\n  RAW_CHECK(!do_main_heap_check, \"should have done it\");\n}\n\n//----------------------------------------------------------------------\n// HeapLeakChecker disabling helpers\n//----------------------------------------------------------------------\n\n// These functions are at the end of the file to prevent their inlining:\n\n// static\nvoid HeapLeakChecker::DisableChecksFromToLocked(const void* start_address,\n                                                const void* end_address,\n                                                int max_depth) {\n  RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  RAW_DCHECK(start_address < end_address, \"\");\n  if (disabled_ranges == NULL) {\n    disabled_ranges = new(Allocator::Allocate(sizeof(DisabledRangeMap)))\n                        DisabledRangeMap;\n  }\n  RangeValue value;\n  value.start_address = AsInt(start_address);\n  value.max_depth = max_depth;\n  if (disabled_ranges->insert(make_pair(AsInt(end_address), value)).second) {\n    RAW_VLOG(10, \"Disabling leak checking in stack traces \"\n                \"under frame addresses between %p..%p\",\n                start_address, end_address);\n  } else {  // check that this is just a verbatim repetition\n    RangeValue const& val = disabled_ranges->find(AsInt(end_address))->second;\n    if (val.max_depth != value.max_depth  ||\n        val.start_address != value.start_address) {\n      RAW_LOG(FATAL, \"Two DisableChecksToHereFrom calls conflict: \"\n                     \"(%p, %p, %d) vs. (%p, %p, %d)\",\n                     AsPtr(val.start_address), end_address, val.max_depth,\n                     start_address, end_address, max_depth);\n    }\n  }\n}\n\n// static\ninline bool HeapLeakChecker::HaveOnHeapLocked(const void** ptr,\n                                              size_t* object_size) {\n  // Commented-out because HaveOnHeapLocked is very performance-critical:\n  // RAW_DCHECK(heap_checker_lock.IsHeld(), \"\");\n  const uintptr_t addr = AsInt(*ptr);\n  if (heap_profile->FindInsideAlloc(\n        *ptr, max_heap_object_size, ptr, object_size)) {\n    RAW_VLOG(16, \"Got pointer into %p at +%\"PRIuPTR\" offset\",\n             *ptr, addr - AsInt(*ptr));\n    return true;\n  }\n  return false;\n}\n\n// static\nconst void* HeapLeakChecker::GetAllocCaller(void* ptr) {\n  // this is used only in the unittest, so the heavy checks are fine\n  HeapProfileTable::AllocInfo info;\n  { SpinLockHolder l(&heap_checker_lock);\n    RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), \"\");\n  }\n  RAW_CHECK(info.stack_depth >= 1, \"\");\n  return info.call_stack[0];\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/heap-profile-table.cc",
    "content": "// Copyright (c) 2006, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//         Maxim Lifantsev (refactoring)\n//\n\n#include <config.h>\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>   // for write()\n#endif\n#include <fcntl.h>    // for open()\n#ifdef HAVE_GLOB_H\n#include <glob.h>\n#ifndef GLOB_NOMATCH  // true on some old cygwins\n# define GLOB_NOMATCH 0\n#endif\n#endif\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h> // for PRIxPTR\n#endif\n#ifdef HAVE_POLL_H\n#include <poll.h>\n#endif\n#include <errno.h>\n#include <stdarg.h>\n#include <string>\n#include <map>\n#include <algorithm>  // for sort(), equal(), and copy()\n\n#include \"heap-profile-table.h\"\n\n#include \"base/logging.h\"\n#include \"raw_printer.h\"\n#include \"symbolize.h\"\n#include <google/stacktrace.h>\n#include <google/malloc_hook.h>\n#include \"base/commandlineflags.h\"\n#include \"base/logging.h\"    // for the RawFD I/O commands\n#include \"base/sysinfo.h\"\n\nusing std::sort;\nusing std::equal;\nusing std::copy;\nusing std::string;\nusing std::map;\n\nusing tcmalloc::FillProcSelfMaps;   // from sysinfo.h\nusing tcmalloc::DumpProcSelfMaps;   // from sysinfo.h\n\n//----------------------------------------------------------------------\n\nDEFINE_bool(cleanup_old_heap_profiles,\n            EnvToBool(\"HEAP_PROFILE_CLEANUP\", true),\n            \"At initialization time, delete old heap profiles.\");\n\nDEFINE_int32(heap_check_max_leaks,\n             EnvToInt(\"HEAP_CHECK_MAX_LEAKS\", 20),\n             \"The maximum number of leak reports to print.\");\n\n//----------------------------------------------------------------------\n\n// header of the dumped heap profile\nstatic const char kProfileHeader[] = \"heap profile: \";\nstatic const char kProcSelfMapsHeader[] = \"\\nMAPPED_LIBRARIES:\\n\";\n\n//----------------------------------------------------------------------\n\nconst char HeapProfileTable::kFileExt[] = \".heap\";\n\n//----------------------------------------------------------------------\n\nstatic const int kHashTableSize = 179999;   // Size for table_.\n/*static*/ const int HeapProfileTable::kMaxStackDepth;\n\n//----------------------------------------------------------------------\n\n// We strip out different number of stack frames in debug mode\n// because less inlining happens in that case\n#ifdef NDEBUG\nstatic const int kStripFrames = 2;\n#else\nstatic const int kStripFrames = 3;\n#endif\n\n// For sorting Stats or Buckets by in-use space\nstatic bool ByAllocatedSpace(HeapProfileTable::Stats* a,\n                             HeapProfileTable::Stats* b) {\n  // Return true iff \"a\" has more allocated space than \"b\"\n  return (a->alloc_size - a->free_size) > (b->alloc_size - b->free_size);\n}\n\n//----------------------------------------------------------------------\n\nHeapProfileTable::HeapProfileTable(Allocator alloc, DeAllocator dealloc)\n    : alloc_(alloc), dealloc_(dealloc) {\n  // Make the table\n  const int table_bytes = kHashTableSize * sizeof(*table_);\n  table_ = reinterpret_cast<Bucket**>(alloc_(table_bytes));\n  memset(table_, 0, table_bytes);\n  // Make allocation map\n  allocation_ =\n    new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_);\n  // init the rest:\n  memset(&total_, 0, sizeof(total_));\n  num_buckets_ = 0;\n}\n\nHeapProfileTable::~HeapProfileTable() {\n  // free allocation map\n  allocation_->~AllocationMap();\n  dealloc_(allocation_);\n  allocation_ = NULL;\n  // free hash table\n  for (int b = 0; b < kHashTableSize; b++) {\n    for (Bucket* x = table_[b]; x != 0; /**/) {\n      Bucket* b = x;\n      x = x->next;\n      dealloc_(b->stack);\n      dealloc_(b);\n    }\n  }\n  dealloc_(table_);\n  table_ = NULL;\n}\n\nHeapProfileTable::Bucket* HeapProfileTable::GetBucket(int depth,\n                                                      const void* const key[]) {\n  // Make hash-value\n  uintptr_t h = 0;\n  for (int i = 0; i < depth; i++) {\n    h += reinterpret_cast<uintptr_t>(key[i]);\n    h += h << 10;\n    h ^= h >> 6;\n  }\n  h += h << 3;\n  h ^= h >> 11;\n\n  // Lookup stack trace in table\n  unsigned int buck = ((unsigned int) h) % kHashTableSize;\n  for (Bucket* b = table_[buck]; b != 0; b = b->next) {\n    if ((b->hash == h) &&\n        (b->depth == depth) &&\n        equal(key, key + depth, b->stack)) {\n      return b;\n    }\n  }\n\n  // Create new bucket\n  const size_t key_size = sizeof(key[0]) * depth;\n  const void** kcopy = reinterpret_cast<const void**>(alloc_(key_size));\n  copy(key, key + depth, kcopy);\n  Bucket* b = reinterpret_cast<Bucket*>(alloc_(sizeof(Bucket)));\n  memset(b, 0, sizeof(*b));\n  b->hash  = h;\n  b->depth = depth;\n  b->stack = kcopy;\n  b->next  = table_[buck];\n  table_[buck] = b;\n  num_buckets_++;\n  return b;\n}\n\nvoid HeapProfileTable::RecordAlloc(const void* ptr, size_t bytes,\n                                   int skip_count) {\n  void* key[kMaxStackDepth];\n  int depth = MallocHook::GetCallerStackTrace(\n    key, kMaxStackDepth, kStripFrames + skip_count + 1);\n  RecordAllocWithStack(ptr, bytes, depth, key);\n}\n\nvoid HeapProfileTable::RecordAllocWithStack(\n    const void* ptr, size_t bytes, int stack_depth,\n    const void* const call_stack[]) {\n  Bucket* b = GetBucket(stack_depth, call_stack);\n  b->allocs++;\n  b->alloc_size += bytes;\n  total_.allocs++;\n  total_.alloc_size += bytes;\n\n  AllocValue v;\n  v.set_bucket(b);  // also did set_live(false); set_ignore(false)\n  v.bytes = bytes;\n  allocation_->Insert(ptr, v);\n}\n\nvoid HeapProfileTable::RecordFree(const void* ptr) {\n  AllocValue v;\n  if (allocation_->FindAndRemove(ptr, &v)) {\n    Bucket* b = v.bucket();\n    b->frees++;\n    b->free_size += v.bytes;\n    total_.frees++;\n    total_.free_size += v.bytes;\n  }\n}\n\nbool HeapProfileTable::FindAlloc(const void* ptr, size_t* object_size) const {\n  const AllocValue* alloc_value = allocation_->Find(ptr);\n  if (alloc_value != NULL) *object_size = alloc_value->bytes;\n  return alloc_value != NULL;\n}\n\nbool HeapProfileTable::FindAllocDetails(const void* ptr,\n                                        AllocInfo* info) const {\n  const AllocValue* alloc_value = allocation_->Find(ptr);\n  if (alloc_value != NULL) {\n    info->object_size = alloc_value->bytes;\n    info->call_stack = alloc_value->bucket()->stack;\n    info->stack_depth = alloc_value->bucket()->depth;\n  }\n  return alloc_value != NULL;\n}\n\nbool HeapProfileTable::FindInsideAlloc(const void* ptr,\n                                       size_t max_size,\n                                       const void** object_ptr,\n                                       size_t* object_size) const {\n  const AllocValue* alloc_value =\n    allocation_->FindInside(&AllocValueSize, max_size, ptr, object_ptr);\n  if (alloc_value != NULL) *object_size = alloc_value->bytes;\n  return alloc_value != NULL;\n}\n\nbool HeapProfileTable::MarkAsLive(const void* ptr) {\n  AllocValue* alloc = allocation_->FindMutable(ptr);\n  if (alloc && !alloc->live()) {\n    alloc->set_live(true);\n    return true;\n  }\n  return false;\n}\n\nvoid HeapProfileTable::MarkAsIgnored(const void* ptr) {\n  AllocValue* alloc = allocation_->FindMutable(ptr);\n  if (alloc) {\n    alloc->set_ignore(true);\n  }\n}\n\n// We'd be happier using snprintfer, but we don't to reduce dependencies.\nint HeapProfileTable::UnparseBucket(const Bucket& b,\n                                    char* buf, int buflen, int bufsize,\n                                    const char* extra,\n                                    Stats* profile_stats) {\n  if (profile_stats != NULL) {\n    profile_stats->allocs += b.allocs;\n    profile_stats->alloc_size += b.alloc_size;\n    profile_stats->frees += b.frees;\n    profile_stats->free_size += b.free_size;\n  }\n  int printed =\n    snprintf(buf + buflen, bufsize - buflen, \"%6d: %8\"PRId64\" [%6d: %8\"PRId64\"] @%s\",\n             b.allocs - b.frees,\n             b.alloc_size - b.free_size,\n             b.allocs,\n             b.alloc_size,\n             extra);\n  // If it looks like the snprintf failed, ignore the fact we printed anything\n  if (printed < 0 || printed >= bufsize - buflen) return buflen;\n  buflen += printed;\n  for (int d = 0; d < b.depth; d++) {\n    printed = snprintf(buf + buflen, bufsize - buflen, \" 0x%08\" PRIxPTR,\n                       reinterpret_cast<uintptr_t>(b.stack[d]));\n    if (printed < 0 || printed >= bufsize - buflen) return buflen;\n    buflen += printed;\n  }\n  printed = snprintf(buf + buflen, bufsize - buflen, \"\\n\");\n  if (printed < 0 || printed >= bufsize - buflen) return buflen;\n  buflen += printed;\n  return buflen;\n}\n\nHeapProfileTable::Bucket**\nHeapProfileTable::MakeSortedBucketList() const {\n  Bucket** list =\n    reinterpret_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_));\n\n  int n = 0;\n  for (int b = 0; b < kHashTableSize; b++) {\n    for (Bucket* x = table_[b]; x != 0; x = x->next) {\n      list[n++] = x;\n    }\n  }\n  RAW_DCHECK(n == num_buckets_, \"\");\n\n  sort(list, list + num_buckets_, ByAllocatedSpace);\n\n  return list;\n}\n\nvoid HeapProfileTable::IterateOrderedAllocContexts(\n    AllocContextIterator callback) const {\n  Bucket** list = MakeSortedBucketList();\n  AllocContextInfo info;\n  for (int i = 0; i < num_buckets_; ++i) {\n    *static_cast<Stats*>(&info) = *static_cast<Stats*>(list[i]);\n    info.stack_depth = list[i]->depth;\n    info.call_stack = list[i]->stack;\n    callback(info);\n  }\n  dealloc_(list);\n}\n\nint HeapProfileTable::FillOrderedProfile(char buf[], int size) const {\n  Bucket** list = MakeSortedBucketList();\n\n  // Our file format is \"bucket, bucket, ..., bucket, proc_self_maps_info\".\n  // In the cases buf is too small, we'd rather leave out the last\n  // buckets than leave out the /proc/self/maps info.  To ensure that,\n  // we actually print the /proc/self/maps info first, then move it to\n  // the end of the buffer, then write the bucket info into whatever\n  // is remaining, and then move the maps info one last time to close\n  // any gaps.  Whew!\n  int map_length = snprintf(buf, size, \"%s\", kProcSelfMapsHeader);\n  if (map_length < 0 || map_length >= size) return 0;\n  bool dummy;   // \"wrote_all\" -- did /proc/self/maps fit in its entirety?\n  map_length += FillProcSelfMaps(buf + map_length, size - map_length, &dummy);\n  RAW_DCHECK(map_length <= size, \"\");\n  char* const map_start = buf + size - map_length;      // move to end\n  memmove(map_start, buf, map_length);\n  size -= map_length;\n\n  Stats stats;\n  memset(&stats, 0, sizeof(stats));\n  int bucket_length = snprintf(buf, size, \"%s\", kProfileHeader);\n  if (bucket_length < 0 || bucket_length >= size) return 0;\n  bucket_length = UnparseBucket(total_, buf, bucket_length, size,\n                                \" heapprofile\", &stats);\n  for (int i = 0; i < num_buckets_; i++) {\n    bucket_length = UnparseBucket(*list[i], buf, bucket_length, size, \"\",\n                                  &stats);\n  }\n  RAW_DCHECK(bucket_length < size, \"\");\n\n  dealloc_(list);\n\n  RAW_DCHECK(buf + bucket_length <= map_start, \"\");\n  memmove(buf + bucket_length, map_start, map_length);  // close the gap\n\n  return bucket_length + map_length;\n}\n\ninline\nvoid HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v,\n                                           const DumpArgs& args) {\n  if (v->live()) {\n    v->set_live(false);\n    return;\n  }\n  if (v->ignore()) {\n    return;\n  }\n  Bucket b;\n  memset(&b, 0, sizeof(b));\n  b.allocs = 1;\n  b.alloc_size = v->bytes;\n  b.depth = v->bucket()->depth;\n  b.stack = v->bucket()->stack;\n  char buf[1024];\n  int len = UnparseBucket(b, buf, 0, sizeof(buf), \"\", args.profile_stats);\n  RawWrite(args.fd, buf, len);\n}\n\n// Callback from NonLiveSnapshot; adds entry to arg->dest\n// if not the entry is not live and is not present in arg->base.\nvoid HeapProfileTable::AddIfNonLive(const void* ptr, AllocValue* v,\n                                    AddNonLiveArgs* arg) {\n  if (v->live()) {\n    v->set_live(false);\n  } else {\n    if (arg->base != NULL && arg->base->map_.Find(ptr) != NULL) {\n      // Present in arg->base, so do not save\n    } else {\n      arg->dest->Add(ptr, *v);\n    }\n  }\n}\n\nbool HeapProfileTable::WriteProfile(const char* file_name,\n                                    const Bucket& total,\n                                    AllocationMap* allocations) {\n  RAW_VLOG(1, \"Dumping non-live heap profile to %s\", file_name);\n  RawFD fd = RawOpenForWriting(file_name);\n  if (fd != kIllegalRawFD) {\n    RawWrite(fd, kProfileHeader, strlen(kProfileHeader));\n    char buf[512];\n    int len = UnparseBucket(total, buf, 0, sizeof(buf), \" heapprofile\",\n                            NULL);\n    RawWrite(fd, buf, len);\n    const DumpArgs args(fd, NULL);\n    allocations->Iterate<const DumpArgs&>(DumpNonLiveIterator, args);\n    RawWrite(fd, kProcSelfMapsHeader, strlen(kProcSelfMapsHeader));\n    DumpProcSelfMaps(fd);\n    RawClose(fd);\n    return true;\n  } else {\n    RAW_LOG(ERROR, \"Failed dumping filtered heap profile to %s\", file_name);\n    return false;\n  }\n}\n\nvoid HeapProfileTable::CleanupOldProfiles(const char* prefix) {\n  if (!FLAGS_cleanup_old_heap_profiles)\n    return;\n  string pattern = string(prefix) + \".*\" + kFileExt;\n#if defined(HAVE_GLOB_H)\n  glob_t g;\n  const int r = glob(pattern.c_str(), GLOB_ERR, NULL, &g);\n  if (r == 0 || r == GLOB_NOMATCH) {\n    const int prefix_length = strlen(prefix);\n    for (int i = 0; i < g.gl_pathc; i++) {\n      const char* fname = g.gl_pathv[i];\n      if ((strlen(fname) >= prefix_length) &&\n          (memcmp(fname, prefix, prefix_length) == 0)) {\n        RAW_VLOG(1, \"Removing old heap profile %s\", fname);\n        unlink(fname);\n      }\n    }\n  }\n  globfree(&g);\n#else   /* HAVE_GLOB_H */\n  RAW_LOG(WARNING, \"Unable to remove old heap profiles (can't run glob())\");\n#endif\n}\n\nHeapProfileTable::Snapshot* HeapProfileTable::TakeSnapshot() {\n  Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);\n  allocation_->Iterate(AddToSnapshot, s);\n  return s;\n}\n\nvoid HeapProfileTable::ReleaseSnapshot(Snapshot* s) {\n  s->~Snapshot();\n  dealloc_(s);\n}\n\n// Callback from TakeSnapshot; adds a single entry to snapshot\nvoid HeapProfileTable::AddToSnapshot(const void* ptr, AllocValue* v,\n                                     Snapshot* snapshot) {\n  snapshot->Add(ptr, *v);\n}\n\nHeapProfileTable::Snapshot* HeapProfileTable::NonLiveSnapshot(\n    Snapshot* base) {\n  RAW_VLOG(2, \"NonLiveSnapshot input: %d %d\\n\",\n           int(total_.allocs - total_.frees),\n           int(total_.alloc_size - total_.free_size));\n\n  Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);\n  AddNonLiveArgs args;\n  args.dest = s;\n  args.base = base;\n  allocation_->Iterate<AddNonLiveArgs*>(AddIfNonLive, &args);\n  RAW_VLOG(2, \"NonLiveSnapshot output: %d %d\\n\",\n           int(s->total_.allocs - s->total_.frees),\n           int(s->total_.alloc_size - s->total_.free_size));\n  return s;\n}\n\n// Information kept per unique bucket seen\nstruct HeapProfileTable::Snapshot::Entry {\n  int count;\n  int bytes;\n  Bucket* bucket;\n  Entry() : count(0), bytes(0) { }\n\n  // Order by decreasing bytes\n  bool operator<(const Entry& x) const {\n    return this->bytes > x.bytes;\n  }\n};\n\n// State used to generate leak report.  We keep a mapping from Bucket pointer\n// the collected stats for that bucket.\nstruct HeapProfileTable::Snapshot::ReportState {\n  map<Bucket*, Entry> buckets_;\n};\n\n// Callback from ReportLeaks; updates ReportState.\nvoid HeapProfileTable::Snapshot::ReportCallback(const void* ptr,\n                                                AllocValue* v,\n                                                ReportState* state) {\n  Entry* e = &state->buckets_[v->bucket()]; // Creates empty Entry first time\n  e->bucket = v->bucket();\n  e->count++;\n  e->bytes += v->bytes;\n}\n\nvoid HeapProfileTable::Snapshot::ReportLeaks(const char* checker_name,\n                                             const char* filename,\n                                             bool should_symbolize) {\n  // This is only used by the heap leak checker, but is intimately\n  // tied to the allocation map that belongs in this module and is\n  // therefore placed here.\n  RAW_LOG(ERROR, \"Leak check %s detected leaks of %\"PRIuS\" bytes \"\n          \"in %\"PRIuS\" objects\",\n          checker_name,\n          size_t(total_.alloc_size),\n          size_t(total_.allocs));\n\n  // Group objects by Bucket\n  ReportState state;\n  map_.Iterate(&ReportCallback, &state);\n\n  // Sort buckets by decreasing leaked size\n  const int n = state.buckets_.size();\n  Entry* entries = new Entry[n];\n  int dst = 0;\n  for (map<Bucket*,Entry>::const_iterator iter = state.buckets_.begin();\n       iter != state.buckets_.end();\n       ++iter) {\n    entries[dst++] = iter->second;\n  }\n  sort(entries, entries + n);\n\n  // Report a bounded number of leaks to keep the leak report from\n  // growing too long.\n  const int to_report =\n      (FLAGS_heap_check_max_leaks > 0 &&\n       n > FLAGS_heap_check_max_leaks) ? FLAGS_heap_check_max_leaks : n;\n  RAW_LOG(ERROR, \"The %d largest leaks:\", to_report);\n\n  // Print\n  SymbolTable symbolization_table;\n  for (int i = 0; i < to_report; i++) {\n    const Entry& e = entries[i];\n    for (int j = 0; j < e.bucket->depth; j++) {\n      symbolization_table.Add(e.bucket->stack[j]);\n    }\n  }\n  static const int kBufSize = 2<<10;\n  char buffer[kBufSize];\n  if (should_symbolize)\n    symbolization_table.Symbolize();\n  for (int i = 0; i < to_report; i++) {\n    const Entry& e = entries[i];\n    base::RawPrinter printer(buffer, kBufSize);\n    printer.Printf(\"Leak of %d bytes in %d objects allocated from:\\n\",\n                   e.bytes, e.count);\n    for (int j = 0; j < e.bucket->depth; j++) {\n      const void* pc = e.bucket->stack[j];\n      printer.Printf(\"\\t@ %\"PRIxPTR\" %s\\n\",\n          reinterpret_cast<uintptr_t>(pc), symbolization_table.GetSymbol(pc));\n    }\n    RAW_LOG(ERROR, \"%s\", buffer);\n  }\n\n  if (to_report < n) {\n    RAW_LOG(ERROR, \"Skipping leaks numbered %d..%d\",\n            to_report, n-1);\n  }\n  delete[] entries;\n\n  // TODO: Dump the sorted Entry list instead of dumping raw data?\n  // (should be much shorter)\n  if (!HeapProfileTable::WriteProfile(filename, total_, &map_)) {\n    RAW_LOG(ERROR, \"Could not write pprof profile to %s\", filename);\n  }\n}\n\nvoid HeapProfileTable::Snapshot::ReportObject(const void* ptr,\n                                              AllocValue* v,\n                                              char* unused) {\n  // Perhaps also log the allocation stack trace (unsymbolized)\n  // on this line in case somebody finds it useful.\n  RAW_LOG(ERROR, \"leaked %\"PRIuS\" byte object %p\", v->bytes, ptr);\n}\n\nvoid HeapProfileTable::Snapshot::ReportIndividualObjects() {\n  char unused;\n  map_.Iterate(ReportObject, &unused);\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/heap-profile-table.h",
    "content": "// Copyright (c) 2006, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//         Maxim Lifantsev (refactoring)\n//\n\n#ifndef BASE_HEAP_PROFILE_TABLE_H_\n#define BASE_HEAP_PROFILE_TABLE_H_\n\n#include \"addressmap-inl.h\"\n#include \"base/basictypes.h\"\n#include \"base/logging.h\"   // for RawFD\n\n// Table to maintain a heap profile data inside,\n// i.e. the set of currently active heap memory allocations.\n// thread-unsafe and non-reentrant code:\n// each instance object must be used by one thread\n// at a time w/o self-recursion.\n//\n// TODO(maxim): add a unittest for this class.\nclass HeapProfileTable {\n public:\n\n  // Extension to be used for heap pforile files.\n  static const char kFileExt[];\n\n  // Longest stack trace we record.\n  static const int kMaxStackDepth = 32;\n\n  // data types ----------------------------\n\n  // Profile stats.\n  struct Stats {\n    int32 allocs;      // Number of allocation calls\n    int32 frees;       // Number of free calls\n    int64 alloc_size;  // Total size of all allocated objects so far\n    int64 free_size;   // Total size of all freed objects so far\n\n    // semantic equality\n    bool Equivalent(const Stats& x) const {\n      return allocs - frees == x.allocs - x.frees  &&\n             alloc_size - free_size == x.alloc_size - x.free_size;\n    }\n  };\n\n  // Info we can return about an allocation.\n  struct AllocInfo {\n    size_t object_size;  // size of the allocation\n    const void* const* call_stack;  // call stack that made the allocation call\n    int stack_depth;  // depth of call_stack\n    bool live;\n    bool ignored;\n  };\n\n  // Info we return about an allocation context.\n  // An allocation context is a unique caller stack trace\n  // of an allocation operation.\n  struct AllocContextInfo : public Stats {\n    int stack_depth;                // Depth of stack trace\n    const void* const* call_stack;  // Stack trace\n  };\n\n  // Memory (de)allocator interface we'll use.\n  typedef void* (*Allocator)(size_t size);\n  typedef void  (*DeAllocator)(void* ptr);\n\n  // interface ---------------------------\n\n  HeapProfileTable(Allocator alloc, DeAllocator dealloc);\n  ~HeapProfileTable();\n\n  // Record an allocation at 'ptr' of 'bytes' bytes.\n  // skip_count gives the number of stack frames between this call\n  // and the memory allocation function that was asked to do the allocation.\n  void RecordAlloc(const void* ptr, size_t bytes, int skip_count);\n\n  // Direct version of RecordAlloc when the caller stack to use\n  // is already known: call_stack of depth stack_depth.\n  void RecordAllocWithStack(const void* ptr, size_t bytes,\n                            int stack_depth, const void* const call_stack[]);\n\n  // Record the deallocation of memory at 'ptr'.\n  void RecordFree(const void* ptr);\n\n  // Return true iff we have recorded an allocation at 'ptr'.\n  // If yes, fill *object_size with the allocation byte size.\n  bool FindAlloc(const void* ptr, size_t* object_size) const;\n  // Same as FindAlloc, but fills all of *info.\n  bool FindAllocDetails(const void* ptr, AllocInfo* info) const;\n\n  // Return true iff \"ptr\" points into a recorded allocation\n  // If yes, fill *object_ptr with the actual allocation address\n  // and *object_size with the allocation byte size.\n  // max_size specifies largest currently possible allocation size.\n  bool FindInsideAlloc(const void* ptr, size_t max_size,\n                       const void** object_ptr, size_t* object_size) const;\n\n  // If \"ptr\" points to a recorded allocation and it's not marked as live\n  // mark it as live and return true. Else return false.\n  // All allocations start as non-live.\n  bool MarkAsLive(const void* ptr);\n\n  // If \"ptr\" points to a recorded allocation, mark it as \"ignored\".\n  // Ignored objects are treated like other objects, except that they\n  // are skipped in heap checking reports.\n  void MarkAsIgnored(const void* ptr);\n\n  // Return current total (de)allocation statistics.\n  const Stats& total() const { return total_; }\n\n  // Allocation data iteration callback: gets passed object pointer and\n  // fully-filled AllocInfo.\n  typedef void (*AllocIterator)(const void* ptr, const AllocInfo& info);\n\n  // Iterate over the allocation profile data calling \"callback\"\n  // for every allocation.\n  void IterateAllocs(AllocIterator callback) const {\n    allocation_->Iterate(MapArgsAllocIterator, callback);\n  }\n\n  // Allocation context profile data iteration callback\n  typedef void (*AllocContextIterator)(const AllocContextInfo& info);\n\n  // Iterate over the allocation context profile data calling \"callback\"\n  // for every allocation context. Allocation contexts are ordered by the\n  // size of allocated space.\n  void IterateOrderedAllocContexts(AllocContextIterator callback) const;\n\n  // Fill profile data into buffer 'buf' of size 'size'\n  // and return the actual size occupied by the dump in 'buf'.\n  // The profile buckets are dumped in the decreasing order\n  // of currently allocated bytes.\n  // We do not provision for 0-terminating 'buf'.\n  int FillOrderedProfile(char buf[], int size) const;\n\n  // Cleanup any old profile files matching prefix + \".*\" + kFileExt.\n  static void CleanupOldProfiles(const char* prefix);\n\n  // Return a snapshot of the current contents of *this.\n  // Caller must call ReleaseSnapshot() on result when no longer needed.\n  // The result is only valid while this exists and until\n  // the snapshot is discarded by calling ReleaseSnapshot().\n  class Snapshot;\n  Snapshot* TakeSnapshot();\n\n  // Release a previously taken snapshot.  snapshot must not\n  // be used after this call.\n  void ReleaseSnapshot(Snapshot* snapshot);\n\n  // Return a snapshot of every non-live, non-ignored object in *this.\n  // If \"base\" is non-NULL, skip any objects present in \"base\".\n  // As a side-effect, clears the \"live\" bit on every live object in *this.\n  // Caller must call ReleaseSnapshot() on result when no longer needed.\n  Snapshot* NonLiveSnapshot(Snapshot* base);\n\n private:\n\n  // data types ----------------------------\n\n  // Hash table bucket to hold (de)allocation stats\n  // for a given allocation call stack trace.\n  struct Bucket : public Stats {\n    uintptr_t    hash;   // Hash value of the stack trace\n    int          depth;  // Depth of stack trace\n    const void** stack;  // Stack trace\n    Bucket*      next;   // Next entry in hash-table\n  };\n\n  // Info stored in the address map\n  struct AllocValue {\n    // Access to the stack-trace bucket\n    Bucket* bucket() const {\n      return reinterpret_cast<Bucket*>(bucket_rep & ~uintptr_t(kMask));\n    }\n    // This also does set_live(false).\n    void set_bucket(Bucket* b) { bucket_rep = reinterpret_cast<uintptr_t>(b); }\n    size_t  bytes;   // Number of bytes in this allocation\n\n    // Access to the allocation liveness flag (for leak checking)\n    bool live() const { return bucket_rep & kLive; }\n    void set_live(bool l) {\n      bucket_rep = (bucket_rep & ~uintptr_t(kLive)) | (l ? kLive : 0);\n    }\n\n    // Should this allocation be ignored if it looks like a leak?\n    bool ignore() const { return bucket_rep & kIgnore; }\n    void set_ignore(bool r) {\n      bucket_rep = (bucket_rep & ~uintptr_t(kIgnore)) | (r ? kIgnore : 0);\n    }\n\n   private:\n    // We store a few bits in the bottom bits of bucket_rep.\n    // (Alignment is at least four, so we have at least two bits.)\n    static const int kLive = 1;\n    static const int kIgnore = 2;\n    static const int kMask = kLive | kIgnore;\n\n    uintptr_t bucket_rep;\n  };\n\n  // helper for FindInsideAlloc\n  static size_t AllocValueSize(const AllocValue& v) { return v.bytes; }\n\n  typedef AddressMap<AllocValue> AllocationMap;\n\n  // Arguments that need to be passed DumpNonLiveIterator callback below.\n  struct DumpArgs {\n    RawFD fd;  // file to write to\n    Stats* profile_stats;  // stats to update (may be NULL)\n\n    DumpArgs(RawFD a, Stats* d)\n      : fd(a), profile_stats(d) { }\n  };\n\n  // helpers ----------------------------\n\n  // Unparse bucket b and print its portion of profile dump into buf.\n  // We return the amount of space in buf that we use.  We start printing\n  // at buf + buflen, and promise not to go beyond buf + bufsize.\n  // We do not provision for 0-terminating 'buf'.\n  //\n  // If profile_stats is non-NULL, we update *profile_stats by\n  // counting bucket b.\n  //\n  // \"extra\" is appended to the unparsed bucket.  Typically it is empty,\n  // but may be set to something like \" heapprofile\" for the total\n  // bucket to indicate the type of the profile.\n  static int UnparseBucket(const Bucket& b,\n                           char* buf, int buflen, int bufsize,\n                           const char* extra,\n                           Stats* profile_stats);\n\n  // Get the bucket for the caller stack trace 'key' of depth 'depth'\n  // creating the bucket if needed.\n  Bucket* GetBucket(int depth, const void* const key[]);\n\n  // Helper for IterateAllocs to do callback signature conversion\n  // from AllocationMap::Iterate to AllocIterator.\n  static void MapArgsAllocIterator(const void* ptr, AllocValue* v,\n                                   AllocIterator callback) {\n    AllocInfo info;\n    info.object_size = v->bytes;\n    info.call_stack = v->bucket()->stack;\n    info.stack_depth = v->bucket()->depth;\n    info.live = v->live();\n    info.ignored = v->ignore();\n    callback(ptr, info);\n  }\n\n  // Helper for DumpNonLiveProfile to do object-granularity\n  // heap profile dumping. It gets passed to AllocationMap::Iterate.\n  inline static void DumpNonLiveIterator(const void* ptr, AllocValue* v,\n                                         const DumpArgs& args);\n\n  // Helper for IterateOrderedAllocContexts and FillOrderedProfile.\n  // Creates a sorted list of Buckets whose length is num_buckets_.\n  // The caller is responsible for dellocating the returned list.\n  Bucket** MakeSortedBucketList() const;\n\n  // Helper for TakeSnapshot.  Saves object to snapshot.\n  static void AddToSnapshot(const void* ptr, AllocValue* v, Snapshot* s);\n\n  // Arguments passed to AddIfNonLive\n  struct AddNonLiveArgs {\n    Snapshot* dest;\n    Snapshot* base;\n  };\n\n  // Helper for NonLiveSnapshot.  Adds the object to the destination\n  // snapshot if it is non-live.\n  static void AddIfNonLive(const void* ptr, AllocValue* v,\n                           AddNonLiveArgs* arg);\n\n  // Write contents of \"*allocations\" as a heap profile to\n  // \"file_name\".  \"total\" must contain the total of all entries in\n  // \"*allocations\".\n  static bool WriteProfile(const char* file_name,\n                           const Bucket& total,\n                           AllocationMap* allocations);\n\n  // data ----------------------------\n\n  // Memory (de)allocator that we use.\n  Allocator alloc_;\n  DeAllocator dealloc_;\n\n  // Overall profile stats; we use only the Stats part,\n  // but make it a Bucket to pass to UnparseBucket.\n  Bucket total_;\n\n  // Bucket hash table.\n  // We hand-craft one instead of using one of the pre-written\n  // ones because we do not want to use malloc when operating on the table.\n  // It is only few lines of code, so no big deal.\n  Bucket** table_;\n  int num_buckets_;\n\n  // Map of all currently allocated objects we know about.\n  AllocationMap* allocation_;\n\n  DISALLOW_COPY_AND_ASSIGN(HeapProfileTable);\n};\n\nclass HeapProfileTable::Snapshot {\n public:\n  const Stats& total() const { return total_; }\n\n  // Report anything in this snapshot as a leak.\n  // May use new/delete for temporary storage.\n  // If should_symbolize is true, will fork (which is not threadsafe)\n  // to turn addresses into symbol names.  Set to false for maximum safety.\n  // Also writes a heap profile to \"filename\" that contains\n  // all of the objects in this snapshot.\n  void ReportLeaks(const char* checker_name, const char* filename,\n                   bool should_symbolize);\n\n  // Report the addresses of all leaked objects.\n  // May use new/delete for temporary storage.\n  void ReportIndividualObjects();\n\n  bool Empty() const {\n    return (total_.allocs == 0) && (total_.alloc_size == 0);\n  }\n\n private:\n  friend class HeapProfileTable;\n\n  // Total count/size are stored in a Bucket so we can reuse UnparseBucket\n  Bucket total_;\n\n  // We share the Buckets managed by the parent table, but have our\n  // own object->bucket map.\n  AllocationMap map_;\n\n  Snapshot(Allocator alloc, DeAllocator dealloc) : map_(alloc, dealloc) {\n    memset(&total_, 0, sizeof(total_));\n  }\n\n  // Callback used to populate a Snapshot object with entries found\n  // in another allocation map.\n  inline void Add(const void* ptr, const AllocValue& v) {\n    map_.Insert(ptr, v);\n    total_.allocs++;\n    total_.alloc_size += v.bytes;\n  }\n\n  // Helpers for sorting and generating leak reports\n  struct Entry;\n  struct ReportState;\n  static void ReportCallback(const void* ptr, AllocValue* v, ReportState*);\n  static void ReportObject(const void* ptr, AllocValue* v, char*);\n\n  DISALLOW_COPY_AND_ASSIGN(Snapshot);\n};\n\n#endif  // BASE_HEAP_PROFILE_TABLE_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/heap-profiler.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// TODO: Log large allocations\n\n#include <config.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>\n#endif\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>    // for open()\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#endif\n#include <errno.h>\n#include <assert.h>\n#include <sys/types.h>\n\n#include <algorithm>\n#include <string>\n\n#include <google/heap-profiler.h>\n\n#include \"base/logging.h\"\n#include \"base/basictypes.h\"   // for PRId64, among other things\n#include \"base/googleinit.h\"\n#include \"base/commandlineflags.h\"\n#include \"malloc_hook-inl.h\"\n#include \"tcmalloc_guard.h\"\n#include <google/malloc_hook.h>\n#include <google/malloc_extension.h>\n#include \"base/spinlock.h\"\n#include \"base/low_level_alloc.h\"\n#include \"base/sysinfo.h\"      // for GetUniquePathFromEnv()\n#include \"heap-profile-table.h\"\n#include \"memory_region_map.h\"\n\n\n#ifndef\tPATH_MAX\n#ifdef MAXPATHLEN\n#define\tPATH_MAX\tMAXPATHLEN\n#else\n#define\tPATH_MAX\t4096         // seems conservative for max filename len!\n#endif\n#endif\n\nusing STL_NAMESPACE::string;\nusing STL_NAMESPACE::sort;\n\n//----------------------------------------------------------------------\n// Flags that control heap-profiling\n//\n// The thread-safety of the profiler depends on these being immutable\n// after main starts, so don't change them.\n//----------------------------------------------------------------------\n\nDEFINE_int64(heap_profile_allocation_interval,\n             EnvToInt64(\"HEAP_PROFILE_ALLOCATION_INTERVAL\", 1 << 30 /*1GB*/),\n             \"If non-zero, dump heap profiling information once every \"\n             \"specified number of bytes allocated by the program since \"\n             \"the last dump.\");\nDEFINE_int64(heap_profile_deallocation_interval,\n             EnvToInt64(\"HEAP_PROFILE_DEALLOCATION_INTERVAL\", 0),\n             \"If non-zero, dump heap profiling information once every \"\n             \"specified number of bytes deallocated by the program \"\n             \"since the last dump.\");\n// We could also add flags that report whenever inuse_bytes changes by\n// X or -X, but there hasn't been a need for that yet, so we haven't.\nDEFINE_int64(heap_profile_inuse_interval,\n             EnvToInt64(\"HEAP_PROFILE_INUSE_INTERVAL\", 100 << 20 /*100MB*/),\n             \"If non-zero, dump heap profiling information whenever \"\n             \"the high-water memory usage mark increases by the specified \"\n             \"number of bytes.\");\nDEFINE_bool(mmap_log,\n            EnvToBool(\"HEAP_PROFILE_MMAP_LOG\", false),\n            \"Should mmap/munmap calls be logged?\");\nDEFINE_bool(mmap_profile,\n            EnvToBool(\"HEAP_PROFILE_MMAP\", false),\n            \"If heap-profiling is on, also profile mmap, mremap, and sbrk)\");\nDEFINE_bool(only_mmap_profile,\n            EnvToBool(\"HEAP_PROFILE_ONLY_MMAP\", false),\n            \"If heap-profiling is on, only profile mmap, mremap, and sbrk; \"\n            \"do not profile malloc/new/etc\");\n\n\n//----------------------------------------------------------------------\n// Locking\n//----------------------------------------------------------------------\n\n// A pthread_mutex has way too much lock contention to be used here.\n//\n// I would like to use Mutex, but it can call malloc(),\n// which can cause us to fall into an infinite recursion.\n//\n// So we use a simple spinlock.\nstatic SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);\n\n//----------------------------------------------------------------------\n// Simple allocator for heap profiler's internal memory\n//----------------------------------------------------------------------\n\nstatic LowLevelAlloc::Arena *heap_profiler_memory;\n\nstatic void* ProfilerMalloc(size_t bytes) {\n  return LowLevelAlloc::AllocWithArena(bytes, heap_profiler_memory);\n}\nstatic void ProfilerFree(void* p) {\n  LowLevelAlloc::Free(p);\n}\n\n// We use buffers of this size in DoGetHeapProfile.\nstatic const int kProfileBufferSize = 1 << 20;\n\n// This is a last-ditch buffer we use in DumpProfileLocked in case we\n// can't allocate more memory from ProfilerMalloc.  We expect this\n// will be used by HeapProfileEndWriter when the application has to\n// exit due to out-of-memory.  This buffer is allocated in\n// HeapProfilerStart.  Access to this must be protected by heap_lock.\nstatic char* global_profiler_buffer = NULL;\n\n\n//----------------------------------------------------------------------\n// Profiling control/state data\n//----------------------------------------------------------------------\n\n// Access to all of these is protected by heap_lock.\nstatic bool  is_on = false;           // If are on as a subsytem.\nstatic bool  dumping = false;         // Dumping status to prevent recursion\nstatic char* filename_prefix = NULL;  // Prefix used for profile file names\n                                      // (NULL if no need for dumping yet)\nstatic int   dump_count = 0;          // How many dumps so far\nstatic int64 last_dump_alloc = 0;     // alloc_size when did we last dump\nstatic int64 last_dump_free = 0;      // free_size when did we last dump\nstatic int64 high_water_mark = 0;     // In-use-bytes at last high-water dump\n\nstatic HeapProfileTable* heap_profile = NULL;  // the heap profile table\n\n//----------------------------------------------------------------------\n// Profile generation\n//----------------------------------------------------------------------\n\nenum AddOrRemove { ADD, REMOVE };\n\n// Add or remove all MMap-allocated regions to/from *heap_profile.\n// Assumes heap_lock is held.\nstatic void AddRemoveMMapDataLocked(AddOrRemove mode) {\n  RAW_DCHECK(heap_lock.IsHeld(), \"\");\n  if (!FLAGS_mmap_profile || !is_on) return;\n  if (!FLAGS_mmap_log) MemoryRegionMap::CheckMallocHooks();\n  // MemoryRegionMap maintained all the data we need for all\n  // mmap-like allocations, so we just use it here:\n  MemoryRegionMap::LockHolder l;\n  for (MemoryRegionMap::RegionIterator r = MemoryRegionMap::BeginRegionLocked();\n       r != MemoryRegionMap::EndRegionLocked(); ++r) {\n    if (mode == ADD) {\n      heap_profile->RecordAllocWithStack(\n        reinterpret_cast<const void*>(r->start_addr),\n        r->end_addr - r->start_addr,\n        r->call_stack_depth, r->call_stack);\n    } else {\n      heap_profile->RecordFree(reinterpret_cast<void*>(r->start_addr));\n    }\n  }\n}\n\n// Input must be a buffer of size at least 1MB.\nstatic char* DoGetHeapProfileLocked(char* buf, int buflen) {\n  // We used to be smarter about estimating the required memory and\n  // then capping it to 1MB and generating the profile into that.\n  if (buf == NULL || buflen < 1)\n    return NULL;\n\n  RAW_DCHECK(heap_lock.IsHeld(), \"\");\n  int bytes_written = 0;\n  if (is_on) {\n    HeapProfileTable::Stats const stats = heap_profile->total();\n    (void)stats;   // avoid an unused-variable warning in non-debug mode.\n    AddRemoveMMapDataLocked(ADD);\n    bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);\n    // FillOrderedProfile should not reduce the set of active mmap-ed regions,\n    // hence MemoryRegionMap will let us remove everything we've added above:\n    AddRemoveMMapDataLocked(REMOVE);\n    RAW_DCHECK(stats.Equivalent(heap_profile->total()), \"\");\n    // if this fails, we somehow removed by AddRemoveMMapDataLocked\n    // more than we have added.\n  }\n  buf[bytes_written] = '\\0';\n  RAW_DCHECK(bytes_written == strlen(buf), \"\");\n\n  return buf;\n}\n\nextern \"C\" char* GetHeapProfile() {\n  // Use normal malloc: we return the profile to the user to free it:\n  char* buffer = reinterpret_cast<char*>(malloc(kProfileBufferSize));\n  SpinLockHolder l(&heap_lock);\n  return DoGetHeapProfileLocked(buffer, kProfileBufferSize);\n}\n\n// defined below\nstatic void NewHook(const void* ptr, size_t size);\nstatic void DeleteHook(const void* ptr);\n\n// Helper for HeapProfilerDump.\nstatic void DumpProfileLocked(const char* reason) {\n  RAW_DCHECK(heap_lock.IsHeld(), \"\");\n  RAW_DCHECK(is_on, \"\");\n  RAW_DCHECK(!dumping, \"\");\n\n  if (filename_prefix == NULL) return;  // we do not yet need dumping\n\n  if (FLAGS_only_mmap_profile == false) {\n    if (MallocHook::GetNewHook() != NewHook  ||\n        MallocHook::GetDeleteHook() != DeleteHook) {\n      RAW_LOG(FATAL, \"Had our new/delete MallocHook-s replaced. \"\n                     \"Are you using another MallocHook client? \"\n                     \"Do not use --heap_profile=... to avoid this conflict.\");\n    }\n  }\n\n  dumping = true;\n\n  // Make file name\n  char file_name[1000];\n  dump_count++;\n  snprintf(file_name, sizeof(file_name), \"%s.%04d%s\",\n           filename_prefix, dump_count, HeapProfileTable::kFileExt);\n\n  // Dump the profile\n  RAW_VLOG(0, \"Dumping heap profile to %s (%s)\", file_name, reason);\n  // We must use file routines that don't access memory, since we hold\n  // a memory lock now.\n  RawFD fd = RawOpenForWriting(file_name);\n  if (fd == kIllegalRawFD) {\n    RAW_LOG(ERROR, \"Failed dumping heap profile to %s\", file_name);\n    dumping = false;\n    return;\n  }\n\n  // This case may be impossible, but it's best to be safe.\n  // It's safe to use the global buffer: we're protected by heap_lock.\n  if (global_profiler_buffer == NULL) {\n    global_profiler_buffer =\n        reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));\n  }\n\n  char* profile = DoGetHeapProfileLocked(global_profiler_buffer,\n                                         kProfileBufferSize);\n  RawWrite(fd, profile, strlen(profile));\n  RawClose(fd);\n\n  dumping = false;\n}\n\n//----------------------------------------------------------------------\n// Profile collection\n//----------------------------------------------------------------------\n\n// Dump a profile after either an allocation or deallocation, if\n// the memory use has changed enough since the last dump.\nstatic void MaybeDumpProfileLocked() {\n  if (!dumping) {\n    const HeapProfileTable::Stats& total = heap_profile->total();\n    const int64 inuse_bytes = total.alloc_size - total.free_size;\n    bool need_to_dump = false;\n    char buf[128];\n    if (FLAGS_heap_profile_allocation_interval > 0 &&\n        total.alloc_size >=\n        last_dump_alloc + FLAGS_heap_profile_allocation_interval) {\n      snprintf(buf, sizeof(buf), (\"%\"PRId64\" MB allocated cumulatively, \"\n                                  \"%\"PRId64\" MB currently in use\"),\n               total.alloc_size >> 20, inuse_bytes >> 20);\n      need_to_dump = true;\n    } else if (FLAGS_heap_profile_deallocation_interval > 0 &&\n               total.free_size >=\n               last_dump_free + FLAGS_heap_profile_deallocation_interval) {\n      snprintf(buf, sizeof(buf), (\"%\"PRId64\" MB freed cumulatively, \"\n                                  \"%\"PRId64\" MB currently in use\"),\n               total.free_size >> 20, inuse_bytes >> 20);\n      need_to_dump = true;\n    } else if (FLAGS_heap_profile_inuse_interval > 0 &&\n               inuse_bytes >\n               high_water_mark + FLAGS_heap_profile_inuse_interval) {\n      snprintf(buf, sizeof(buf), \"%\"PRId64\" MB currently in use\",\n               inuse_bytes >> 20);\n      need_to_dump = true;\n    }\n    if (need_to_dump) {\n      DumpProfileLocked(buf);\n\n      last_dump_alloc = total.alloc_size;\n      last_dump_free = total.free_size;\n      if (inuse_bytes > high_water_mark)\n        high_water_mark = inuse_bytes;\n    }\n  }\n}\n\n// Record an allocation in the profile.\nstatic void RecordAlloc(const void* ptr, size_t bytes, int skip_count) {\n  SpinLockHolder l(&heap_lock);\n  if (is_on) {\n    heap_profile->RecordAlloc(ptr, bytes, skip_count + 1);\n    MaybeDumpProfileLocked();\n  }\n}\n\n// Record a deallocation in the profile.\nstatic void RecordFree(const void* ptr) {\n  SpinLockHolder l(&heap_lock);\n  if (is_on) {\n    heap_profile->RecordFree(ptr);\n    MaybeDumpProfileLocked();\n  }\n}\n\n//----------------------------------------------------------------------\n// Allocation/deallocation hooks for MallocHook\n//----------------------------------------------------------------------\n\n// static\nvoid NewHook(const void* ptr, size_t size) {\n  if (ptr != NULL) RecordAlloc(ptr, size, 0);\n}\n\n// static\nvoid DeleteHook(const void* ptr) {\n  if (ptr != NULL) RecordFree(ptr);\n}\n\n// TODO(jandrews): Re-enable stack tracing\n#ifdef TODO_REENABLE_STACK_TRACING\nstatic void RawInfoStackDumper(const char* message, void*) {\n  RAW_LOG(INFO, \"%.*s\", static_cast<int>(strlen(message) - 1), message);\n  // -1 is to chop the \\n which will be added by RAW_LOG\n}\n#endif\n\n// Saved MemoryRegionMap's hooks to daisy-chain calls to.\nMallocHook::MmapHook saved_mmap_hook = NULL;\nMallocHook::MremapHook saved_mremap_hook = NULL;\nMallocHook::MunmapHook saved_munmap_hook = NULL;\nMallocHook::SbrkHook saved_sbrk_hook = NULL;\n\nstatic void MmapHook(const void* result, const void* start, size_t size,\n                     int prot, int flags, int fd, off_t offset) {\n  if (FLAGS_mmap_log) {  // log it\n    // We use PRIxS not just '%p' to avoid deadlocks\n    // in pretty-printing of NULL as \"nil\".\n    // TODO(maxim): instead should use a safe snprintf reimplementation\n    RAW_LOG(INFO,\n            \"mmap(start=0x%\"PRIxPTR\", len=%\"PRIuS\", prot=0x%x, flags=0x%x, \"\n            \"fd=%d, offset=0x%x) = 0x%\"PRIxPTR\"\",\n            (uintptr_t) start, size, prot, flags, fd, (unsigned int) offset,\n            (uintptr_t) result);\n#ifdef TODO_REENABLE_STACK_TRACING\n    DumpStackTrace(1, RawInfoStackDumper, NULL);\n#endif\n  }\n  if (saved_mmap_hook) {\n    // Call MemoryRegionMap's hook: it will record needed info about the mmap\n    // for us w/o deadlocks:\n    (*saved_mmap_hook)(result, start, size, prot, flags, fd, offset);\n  }\n}\n\nstatic void MremapHook(const void* result, const void* old_addr,\n                       size_t old_size, size_t new_size,\n                       int flags, const void* new_addr) {\n  if (FLAGS_mmap_log) {  // log it\n    // We use PRIxS not just '%p' to avoid deadlocks\n    // in pretty-printing of NULL as \"nil\".\n    // TODO(maxim): instead should use a safe snprintf reimplementation\n    RAW_LOG(INFO,\n            \"mremap(old_addr=0x%\"PRIxPTR\", old_size=%\"PRIuS\", \"\n            \"new_size=%\"PRIuS\", flags=0x%x, new_addr=0x%\"PRIxPTR\") = \"\n            \"0x%\"PRIxPTR\"\",\n            (uintptr_t) old_addr, old_size, new_size, flags,\n            (uintptr_t) new_addr, (uintptr_t) result);\n#ifdef TODO_REENABLE_STACK_TRACING\n    DumpStackTrace(1, RawInfoStackDumper, NULL);\n#endif\n  }\n  if (saved_mremap_hook) {  // call MemoryRegionMap's hook\n    (*saved_mremap_hook)(result, old_addr, old_size, new_size, flags, new_addr);\n  }\n}\n\nstatic void MunmapHook(const void* ptr, size_t size) {\n  if (FLAGS_mmap_log) {  // log it\n    // We use PRIxS not just '%p' to avoid deadlocks\n    // in pretty-printing of NULL as \"nil\".\n    // TODO(maxim): instead should use a safe snprintf reimplementation\n    RAW_LOG(INFO, \"munmap(start=0x%\"PRIxPTR\", len=%\"PRIuS\")\",\n                  (uintptr_t) ptr, size);\n#ifdef TODO_REENABLE_STACK_TRACING\n    DumpStackTrace(1, RawInfoStackDumper, NULL);\n#endif\n  }\n  if (saved_munmap_hook) {  // call MemoryRegionMap's hook\n    (*saved_munmap_hook)(ptr, size);\n  }\n}\n\nstatic void SbrkHook(const void* result, ptrdiff_t increment) {\n  if (FLAGS_mmap_log) {  // log it\n    RAW_LOG(INFO, \"sbrk(inc=%\"PRIdS\") = 0x%\"PRIxPTR\"\",\n                  increment, (uintptr_t) result);\n#ifdef TODO_REENABLE_STACK_TRACING\n    DumpStackTrace(1, RawInfoStackDumper, NULL);\n#endif\n  }\n  if (saved_sbrk_hook) {  // call MemoryRegionMap's hook\n    (*saved_sbrk_hook)(result, increment);\n  }\n}\n\n//----------------------------------------------------------------------\n// Starting/stopping/dumping\n//----------------------------------------------------------------------\n\nextern \"C\" void HeapProfilerStart(const char* prefix) {\n  SpinLockHolder l(&heap_lock);\n\n  if (is_on) return;\n\n  is_on = true;\n\n  RAW_VLOG(0, \"Starting tracking the heap\");\n\n  // This should be done before the hooks are set up, since it should\n  // call new, and we want that to be accounted for correctly.\n  MallocExtension::Initialize();\n\n  if (FLAGS_only_mmap_profile) {\n    FLAGS_mmap_profile = true;\n  }\n\n  if (FLAGS_mmap_profile) {\n    // Ask MemoryRegionMap to record all mmap, mremap, and sbrk\n    // call stack traces of at least size kMaxStackDepth:\n    MemoryRegionMap::Init(HeapProfileTable::kMaxStackDepth);\n  }\n\n  if (FLAGS_mmap_log) {\n    // Install our hooks to do the logging\n    // and maybe save MemoryRegionMap's hooks to call:\n    saved_mmap_hook = MallocHook::SetMmapHook(MmapHook);\n    saved_mremap_hook = MallocHook::SetMremapHook(MremapHook);\n    saved_munmap_hook = MallocHook::SetMunmapHook(MunmapHook);\n    saved_sbrk_hook = MallocHook::SetSbrkHook(SbrkHook);\n  }\n\n  heap_profiler_memory =\n    LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());\n\n  // Reserve space now for the heap profiler, so we can still write a\n  // heap profile even if the application runs out of memory.\n  global_profiler_buffer =\n      reinterpret_cast<char*>(ProfilerMalloc(kProfileBufferSize));\n\n  heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))\n                   HeapProfileTable(ProfilerMalloc, ProfilerFree);\n\n  last_dump_alloc = 0;\n  last_dump_free = 0;\n  high_water_mark = 0;\n\n  // We do not reset dump_count so if the user does a sequence of\n  // HeapProfilerStart/HeapProfileStop, we will get a continuous\n  // sequence of profiles.\n\n  if (FLAGS_only_mmap_profile == false) {\n    // Now set the hooks that capture new/delete and malloc/free\n    // and check that these are the only hooks:\n    if (MallocHook::SetNewHook(NewHook) != NULL  ||\n        MallocHook::SetDeleteHook(DeleteHook) != NULL) {\n      RAW_LOG(FATAL, \"Had other new/delete MallocHook-s set. \"\n                     \"Are you using the heap leak checker? \"\n                     \"Use --heap_check=\\\"\\\" to avoid this conflict.\");\n    }\n  }\n\n  // Copy filename prefix\n  RAW_DCHECK(filename_prefix == NULL, \"\");\n  const int prefix_length = strlen(prefix);\n  filename_prefix = reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1));\n  memcpy(filename_prefix, prefix, prefix_length);\n  filename_prefix[prefix_length] = '\\0';\n}\n\nextern \"C\" int IsHeapProfilerRunning() {\n  SpinLockHolder l(&heap_lock);\n  return is_on ? 1 : 0;   // return an int, because C code doesn't have bool\n}\n\nextern \"C\" void HeapProfilerStop() {\n  SpinLockHolder l(&heap_lock);\n\n  if (!is_on) return;\n\n  if (FLAGS_only_mmap_profile == false) {\n    // Unset our new/delete hooks, checking they were the ones set:\n    if (MallocHook::SetNewHook(NULL) != NewHook  ||\n        MallocHook::SetDeleteHook(NULL) != DeleteHook) {\n      RAW_LOG(FATAL, \"Had our new/delete MallocHook-s replaced. \"\n                     \"Are you using another MallocHook client? \"\n                     \"Do not use --heap_profile=... to avoid this conflict.\");\n    }\n  }\n  if (FLAGS_mmap_log) {\n    // Restore mmap/sbrk hooks, checking that our hooks were the ones set:\n    if (MallocHook::SetMmapHook(saved_mmap_hook) != MmapHook  ||\n        MallocHook::SetMremapHook(saved_mremap_hook) != MremapHook  ||\n        MallocHook::SetMunmapHook(saved_munmap_hook) != MunmapHook  ||\n        MallocHook::SetSbrkHook(saved_sbrk_hook) != SbrkHook) {\n      RAW_LOG(FATAL, \"Had our mmap/mremap/munmap/sbrk MallocHook-s replaced. \"\n                     \"Are you using another MallocHook client? \"\n                     \"Do not use --heap_profile=... to avoid this conflict.\");\n    }\n  }\n\n  // free profile\n  heap_profile->~HeapProfileTable();\n  ProfilerFree(heap_profile);\n  heap_profile = NULL;\n\n  // free output-buffer memory\n  ProfilerFree(global_profiler_buffer);\n\n  // free prefix\n  ProfilerFree(filename_prefix);\n  filename_prefix = NULL;\n\n  if (!LowLevelAlloc::DeleteArena(heap_profiler_memory)) {\n    RAW_LOG(FATAL, \"Memory leak in HeapProfiler:\");\n  }\n\n  if (FLAGS_mmap_profile) {\n    MemoryRegionMap::Shutdown();\n  }\n\n  is_on = false;\n}\n\nextern \"C\" void HeapProfilerDump(const char *reason) {\n  SpinLockHolder l(&heap_lock);\n  if (is_on && !dumping) {\n    DumpProfileLocked(reason);\n  }\n}\n\n//----------------------------------------------------------------------\n// Initialization/finalization code\n//----------------------------------------------------------------------\n\n// Initialization code\nstatic void HeapProfilerInit() {\n  // Everything after this point is for setting up the profiler based on envvar\n  char fname[PATH_MAX];\n  if (!GetUniquePathFromEnv(\"HEAPPROFILE\", fname)) {\n    return;\n  }\n  // We do a uid check so we don't write out files in a setuid executable.\n#ifdef HAVE_GETEUID\n  if (getuid() != geteuid()) {\n    RAW_LOG(WARNING, (\"HeapProfiler: ignoring HEAPPROFILE because \"\n                      \"program seems to be setuid\\n\"));\n    return;\n  }\n#endif\n\n  HeapProfileTable::CleanupOldProfiles(fname);\n\n  HeapProfilerStart(fname);\n}\n\n// class used for finalization -- dumps the heap-profile at program exit\nstruct HeapProfileEndWriter {\n  ~HeapProfileEndWriter() { HeapProfilerDump(\"Exiting\"); }\n};\n\n// We want to make sure tcmalloc is up and running before starting the profiler\nstatic const TCMallocGuard tcmalloc_initializer;\nREGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());\nstatic HeapProfileEndWriter heap_profile_end_writer;\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/internal_logging.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Sanjay Ghemawat <opensource@google.com>\n\n#include <config.h>\n#include <stdio.h>\n#include <stdarg.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>    // for write()\n#endif\n#include <string.h>\n#include <google/malloc_extension.h>\n#include \"internal_logging.h\"\n\nstatic const int kLogBufSize = 800;\n\nvoid TCMalloc_MESSAGE(const char* filename,\n                      int line_number,\n                      const char* format, ...) {\n  char buf[kLogBufSize];\n  const int n = snprintf(buf, sizeof(buf), \"%s:%d] \", filename, line_number);\n  if (n < kLogBufSize) {\n    va_list ap;\n    va_start(ap, format);\n    vsnprintf(buf + n, kLogBufSize - n, format, ap);\n    va_end(ap);\n  }\n  write(STDERR_FILENO, buf, strlen(buf));\n}\n\nstatic const int kStatsBufferSize = 16 << 10;\nstatic char stats_buffer[kStatsBufferSize] = { 0 };\n\nstatic void TCMalloc_CRASH_internal(bool dump_stats,\n                                    const char* filename,\n                                    int line_number,\n                                    const char* format, va_list ap) {\n  char buf[kLogBufSize];\n  const int n = snprintf(buf, sizeof(buf), \"%s:%d] \", filename, line_number);\n  if (n < kLogBufSize) {\n    vsnprintf(buf + n, kLogBufSize - n, format, ap);\n  }\n  write(STDERR_FILENO, buf, strlen(buf));\n  if (dump_stats) {\n    MallocExtension::instance()->GetStats(stats_buffer, kStatsBufferSize);\n    write(STDERR_FILENO, stats_buffer, strlen(stats_buffer));\n  }\n\n  abort();\n}\n\nvoid TCMalloc_CRASH(bool dump_stats,\n                    const char* filename,\n                    int line_number,\n                    const char* format, ...) {\n  va_list ap;\n  va_start(ap, format);\n  TCMalloc_CRASH_internal(dump_stats, filename, line_number, format, ap);\n  va_end(ap);\n}\n\n\nvoid TCMalloc_CrashReporter::PrintfAndDie(const char* format, ...) {\n  va_list ap;\n  va_start(ap, format);\n  TCMalloc_CRASH_internal(dump_stats_, file_, line_, format, ap);\n  va_end(ap);\n}\n\nvoid TCMalloc_Printer::printf(const char* format, ...) {\n  if (left_ > 0) {\n    va_list ap;\n    va_start(ap, format);\n    const int r = vsnprintf(buf_, left_, format, ap);\n    va_end(ap);\n    if (r < 0) {\n      // Perhaps an old glibc that returns -1 on truncation?\n      left_ = 0;\n    } else if (r > left_) {\n      // Truncation\n      left_ = 0;\n    } else {\n      left_ -= r;\n      buf_ += r;\n    }\n  }\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/internal_logging.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// Internal logging and related utility routines.\n\n#ifndef TCMALLOC_INTERNAL_LOGGING_H_\n#define TCMALLOC_INTERNAL_LOGGING_H_\n\n#include <config.h>\n#include <stdlib.h>   // for abort()\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>   // for write()\n#endif\n\n//-------------------------------------------------------------------\n// Utility routines\n//-------------------------------------------------------------------\n\n// Safe debugging routine: we write directly to the stderr file\n// descriptor and avoid FILE buffering because that may invoke\n// malloc()\nextern void TCMalloc_MESSAGE(const char* filename,\n                             int line_number,\n                             const char* format, ...)\n#ifdef HAVE___ATTRIBUTE__\n  __attribute__ ((__format__ (__printf__, 3, 4)))\n#endif\n;\n\n// Right now, the only non-fatal messages we want to report are when\n// an allocation fails (we'll return NULL eventually, but sometimes\n// want more prominent notice to help debug).  message should be\n// a literal string with no %<whatever> format directives.\n#ifdef TCMALLOC_WARNINGS\n#define MESSAGE(message, num_bytes)                                     \\\n   TCMalloc_MESSAGE(__FILE__, __LINE__, message \" (%\"PRIuS\" bytes)\\n\",  \\\n                    static_cast<size_t>(num_bytes))\n#else\n#define MESSAGE(message, num_bytes)\n#endif\n\n// Dumps the specified message and then calls abort().  If\n// \"dump_stats\" is specified, the first call will also dump the\n// tcmalloc stats.\nextern void TCMalloc_CRASH(bool dump_stats,\n                           const char* filename,\n                           int line_number,\n                           const char* format, ...)\n#ifdef HAVE___ATTRIBUTE__\n  __attribute__ ((__format__ (__printf__, 4, 5)))\n#endif\n;\n\n// This is a class that makes using the macro easier.  With this class,\n// CRASH(\"%d\", i) expands to TCMalloc_CrashReporter.PrintfAndDie(\"%d\", i).\nclass PERFTOOLS_DLL_DECL TCMalloc_CrashReporter {\n public:\n  TCMalloc_CrashReporter(bool dump_stats, const char* file, int line)\n      : dump_stats_(dump_stats), file_(file), line_(line) {\n  }\n  void PrintfAndDie(const char* format, ...)\n#ifdef HAVE___ATTRIBUTE__\n      __attribute__ ((__format__ (__printf__, 2, 3)))  // 2,3 due to \"this\"\n#endif\n;\n\n private:\n  bool dump_stats_;\n  const char* file_;\n  int line_;\n};\n\n#define CRASH \\\n  TCMalloc_CrashReporter(false, __FILE__, __LINE__).PrintfAndDie\n\n#define CRASH_WITH_STATS \\\n  TCMalloc_CrashReporter(true, __FILE__, __LINE__).PrintfAndDie\n\n// Like assert(), but executed even in NDEBUG mode\n#undef CHECK_CONDITION\n#define CHECK_CONDITION(cond)                                            \\\ndo {                                                                     \\\n  if (!(cond)) {                                                         \\\n    CRASH(\"assertion failed: %s\\n\", #cond);   \\\n  }                                                                      \\\n} while (0)\n\n// Our own version of assert() so we can avoid hanging by trying to do\n// all kinds of goofy printing while holding the malloc lock.\n#ifndef NDEBUG\n#define ASSERT(cond) CHECK_CONDITION(cond)\n#else\n#define ASSERT(cond) ((void) 0)\n#endif\n\n// Print into buffer\nclass TCMalloc_Printer {\n private:\n  char* buf_;           // Where should we write next\n  int   left_;          // Space left in buffer (including space for \\0)\n\n public:\n  // REQUIRES: \"length > 0\"\n  TCMalloc_Printer(char* buf, int length) : buf_(buf), left_(length) {\n    buf[0] = '\\0';\n  }\n\n  void printf(const char* format, ...)\n#ifdef HAVE___ATTRIBUTE__\n    __attribute__ ((__format__ (__printf__, 2, 3)))\n#endif\n;\n};\n\n#endif  // TCMALLOC_INTERNAL_LOGGING_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/linked_list.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// Some very basic linked list functions for dealing with using void * as\n// storage.\n\n#ifndef TCMALLOC_LINKED_LIST_H_\n#define TCMALLOC_LINKED_LIST_H_\n\n#include <stddef.h>\n\nnamespace tcmalloc {\n\ninline void *SLL_Next(void *t) {\n  return *(reinterpret_cast<void**>(t));\n}\n\ninline void SLL_SetNext(void *t, void *n) {\n  *(reinterpret_cast<void**>(t)) = n;\n}\n\ninline void SLL_Push(void **list, void *element) {\n  SLL_SetNext(element, *list);\n  *list = element;\n}\n\ninline void *SLL_Pop(void **list) {\n  void *result = *list;\n  *list = SLL_Next(*list);\n  return result;\n}\n\n// Remove N elements from a linked list to which head points.  head will be\n// modified to point to the new head.  start and end will point to the first\n// and last nodes of the range.  Note that end will point to NULL after this\n// function is called.\ninline void SLL_PopRange(void **head, int N, void **start, void **end) {\n  if (N == 0) {\n    *start = NULL;\n    *end = NULL;\n    return;\n  }\n\n  void *tmp = *head;\n  for (int i = 1; i < N; ++i) {\n    tmp = SLL_Next(tmp);\n  }\n\n  *start = *head;\n  *end = tmp;\n  *head = SLL_Next(tmp);\n  // Unlink range from list.\n  SLL_SetNext(tmp, NULL);\n}\n\ninline void SLL_PushRange(void **head, void *start, void *end) {\n  if (!start) return;\n  SLL_SetNext(end, *head);\n  *head = start;\n}\n\ninline size_t SLL_Size(void *head) {\n  int count = 0;\n  while (head) {\n    count++;\n    head = SLL_Next(head);\n  }\n  return count;\n}\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_LINKED_LIST_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/malloc_extension.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#include <config.h>\n#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdio.h>\n#if defined HAVE_STDINT_H\n#include <stdint.h>\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>\n#else\n#include <sys/types.h>\n#endif\n#include <string>\n#include \"base/dynamic_annotations.h\"\n#include \"base/sysinfo.h\"    // for FillProcSelfMaps\n#ifndef NO_HEAP_CHECK\n#include \"google/heap-checker.h\"\n#endif\n#include \"google/malloc_extension.h\"\n#include \"maybe_threads.h\"\n\nusing STL_NAMESPACE::string;\nusing STL_NAMESPACE::vector;\n\nstatic void DumpAddressMap(string* result) {\n  *result += \"\\nMAPPED_LIBRARIES:\\n\";\n  // We keep doubling until we get a fit\n  const size_t old_resultlen = result->size();\n  for (int amap_size = 10240; amap_size < 10000000; amap_size *= 2) {\n    result->resize(old_resultlen + amap_size);\n    bool wrote_all = false;\n    const int bytes_written =\n        tcmalloc::FillProcSelfMaps(&((*result)[old_resultlen]), amap_size,\n                                   &wrote_all);\n    if (wrote_all) {   // we fit!\n      (*result)[old_resultlen + bytes_written] = '\\0';\n      result->resize(old_resultlen + bytes_written);\n      return;\n    }\n  }\n  result->reserve(old_resultlen);   // just don't print anything\n}\n\n// Note: this routine is meant to be called before threads are spawned.\nvoid MallocExtension::Initialize() {\n  static bool initialize_called = false;\n\n  if (initialize_called) return;\n  initialize_called = true;\n\n#ifdef __GLIBC__\n  // GNU libc++ versions 3.3 and 3.4 obey the environment variables\n  // GLIBCPP_FORCE_NEW and GLIBCXX_FORCE_NEW respectively.  Setting\n  // one of these variables forces the STL default allocator to call\n  // new() or delete() for each allocation or deletion.  Otherwise\n  // the STL allocator tries to avoid the high cost of doing\n  // allocations by pooling memory internally.  However, tcmalloc\n  // does allocations really fast, especially for the types of small\n  // items one sees in STL, so it's better off just using us.\n  // TODO: control whether we do this via an environment variable?\n  setenv(\"GLIBCPP_FORCE_NEW\", \"1\", false /* no overwrite*/);\n  setenv(\"GLIBCXX_FORCE_NEW\", \"1\", false /* no overwrite*/);\n\n  // Now we need to make the setenv 'stick', which it may not do since\n  // the env is flakey before main() is called.  But luckily stl only\n  // looks at this env var the first time it tries to do an alloc, and\n  // caches what it finds.  So we just cause an stl alloc here.\n  string dummy(\"I need to be allocated\");\n  dummy += \"!\";         // so the definition of dummy isn't optimized out\n#endif  /* __GLIBC__ */\n}\n\n// Default implementation -- does nothing\nMallocExtension::~MallocExtension() { }\nbool MallocExtension::VerifyAllMemory() { return true; }\nbool MallocExtension::VerifyNewMemory(void* p) { return true; }\nbool MallocExtension::VerifyArrayNewMemory(void* p) { return true; }\nbool MallocExtension::VerifyMallocMemory(void* p) { return true; }\n\nbool MallocExtension::GetNumericProperty(const char* property, size_t* value) {\n  return false;\n}\n\nbool MallocExtension::SetNumericProperty(const char* property, size_t value) {\n  return false;\n}\n\nvoid MallocExtension::GetStats(char* buffer, int length) {\n  assert(length > 0);\n  buffer[0] = '\\0';\n}\n\nbool MallocExtension::MallocMemoryStats(int* blocks, size_t* total,\n                                       int histogram[kMallocHistogramSize]) {\n  *blocks = 0;\n  *total = 0;\n  memset(histogram, 0, sizeof(*histogram) * kMallocHistogramSize);\n  return true;\n}\n\nvoid** MallocExtension::ReadStackTraces(int* sample_period) {\n  return NULL;\n}\n\nvoid** MallocExtension::ReadHeapGrowthStackTraces() {\n  return NULL;\n}\n\nvoid MallocExtension::MarkThreadIdle() {\n  // Default implementation does nothing\n}\n\nvoid MallocExtension::MarkThreadBusy() {\n  // Default implementation does nothing\n}\n\nvoid MallocExtension::ReleaseToSystem(size_t num_bytes) {\n  // Default implementation does nothing\n}\n\nvoid MallocExtension::ReleaseFreeMemory() {\n  ReleaseToSystem(static_cast<size_t>(-1));   // SIZE_T_MAX\n}\n\nvoid MallocExtension::SetMemoryReleaseRate(double rate) {\n  // Default implementation does nothing\n}\n\ndouble MallocExtension::GetMemoryReleaseRate() {\n  return -1.0;\n}\n\nsize_t MallocExtension::GetEstimatedAllocatedSize(size_t size) {\n  return size;\n}\n\nsize_t MallocExtension::GetAllocatedSize(void* p) {\n  return 0;\n}\n\nvoid MallocExtension::GetFreeListSizes(\n    vector<MallocExtension::FreeListInfo>* v) {\n  v->clear();\n}\n\n// The current malloc extension object.\n\nstatic pthread_once_t module_init = PTHREAD_ONCE_INIT;\nstatic MallocExtension* current_instance = NULL;\n\nstatic void InitModule() {\n  current_instance = new MallocExtension;\n#ifndef NO_HEAP_CHECK\n  HeapLeakChecker::IgnoreObject(current_instance);\n#endif\n}\n\nMallocExtension* MallocExtension::instance() {\n  perftools_pthread_once(&module_init, InitModule);\n  return current_instance;\n}\n\nvoid MallocExtension::Register(MallocExtension* implementation) {\n  perftools_pthread_once(&module_init, InitModule);\n  // When running under valgrind, our custom malloc is replaced with\n  // valgrind's one and malloc extensions will not work.  (Note:\n  // callers should be responsible for checking that they are the\n  // malloc that is really being run, before calling Register.  This\n  // is just here as an extra sanity check.)\n  if (!RunningOnValgrind()) {\n    current_instance = implementation;\n  }\n}\n\n// -----------------------------------------------------------------------\n// Heap sampling support\n// -----------------------------------------------------------------------\n\nnamespace {\n\n// Accessors\nuintptr_t Count(void** entry) {\n  return reinterpret_cast<uintptr_t>(entry[0]);\n}\nuintptr_t Size(void** entry) {\n  return reinterpret_cast<uintptr_t>(entry[1]);\n}\nuintptr_t Depth(void** entry) {\n  return reinterpret_cast<uintptr_t>(entry[2]);\n}\nvoid* PC(void** entry, int i) {\n  return entry[3+i];\n}\n\nvoid PrintCountAndSize(MallocExtensionWriter* writer,\n                       uintptr_t count, uintptr_t size) {\n  char buf[100];\n  snprintf(buf, sizeof(buf),\n           \"%6lld: %8lld [%6lld: %8lld] @\",\n           static_cast<long long>(count),\n           static_cast<long long>(size),\n           static_cast<long long>(count),\n           static_cast<long long>(size));\n  writer->append(buf, strlen(buf));\n}\n\nvoid PrintHeader(MallocExtensionWriter* writer,\n                 const char* label, void** entries) {\n  // Compute the total count and total size\n  uintptr_t total_count = 0;\n  uintptr_t total_size = 0;\n  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {\n    total_count += Count(entry);\n    total_size += Size(entry);\n  }\n\n  const char* const kTitle = \"heap profile: \";\n  writer->append(kTitle, strlen(kTitle));\n  PrintCountAndSize(writer, total_count, total_size);\n  writer->append(\" \", 1);\n  writer->append(label, strlen(label));\n  writer->append(\"\\n\", 1);\n}\n\nvoid PrintStackEntry(MallocExtensionWriter* writer, void** entry) {\n  PrintCountAndSize(writer, Count(entry), Size(entry));\n\n  for (int i = 0; i < Depth(entry); i++) {\n    char buf[32];\n    snprintf(buf, sizeof(buf), \" %p\", PC(entry, i));\n    writer->append(buf, strlen(buf));\n  }\n  writer->append(\"\\n\", 1);\n}\n\n}\n\nvoid MallocExtension::GetHeapSample(MallocExtensionWriter* writer) {\n  int sample_period = 0;\n  void** entries = ReadStackTraces(&sample_period);\n  if (entries == NULL) {\n    const char* const kErrorMsg =\n        \"This malloc implementation does not support sampling.\\n\"\n        \"As of 2005/01/26, only tcmalloc supports sampling, and\\n\"\n        \"you are probably running a binary that does not use\\n\"\n        \"tcmalloc.\\n\";\n    writer->append(kErrorMsg, strlen(kErrorMsg));\n    return;\n  }\n\n  char label[32];\n  sprintf(label, \"heap_v2/%d\", sample_period);\n  PrintHeader(writer, label, entries);\n  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {\n    PrintStackEntry(writer, entry);\n  }\n  delete[] entries;\n\n  DumpAddressMap(writer);\n}\n\nvoid MallocExtension::GetHeapGrowthStacks(MallocExtensionWriter* writer) {\n  void** entries = ReadHeapGrowthStackTraces();\n  if (entries == NULL) {\n    const char* const kErrorMsg =\n        \"This malloc implementation does not support \"\n        \"ReadHeapGrowthStackTraces().\\n\"\n        \"As of 2005/09/27, only tcmalloc supports this, and you\\n\"\n        \"are probably running a binary that does not use tcmalloc.\\n\";\n    writer->append(kErrorMsg, strlen(kErrorMsg));\n    return;\n  }\n\n  // Do not canonicalize the stack entries, so that we get a\n  // time-ordered list of stack traces, which may be useful if the\n  // client wants to focus on the latest stack traces.\n  PrintHeader(writer, \"growth\", entries);\n  for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {\n    PrintStackEntry(writer, entry);\n  }\n  delete[] entries;\n\n  DumpAddressMap(writer);\n}\n\nvoid MallocExtension::Ranges(void* arg, RangeFunction func) {\n  // No callbacks by default\n}\n\n// These are C shims that work on the current instance.\n\n#define C_SHIM(fn, retval, paramlist, arglist)          \\\n  extern \"C\" PERFTOOLS_DLL_DECL retval MallocExtension_##fn paramlist {    \\\n    return MallocExtension::instance()->fn arglist;     \\\n  }\n\nC_SHIM(VerifyAllMemory, int, (void), ());\nC_SHIM(VerifyNewMemory, int, (void* p), (p));\nC_SHIM(VerifyArrayNewMemory, int, (void* p), (p));\nC_SHIM(VerifyMallocMemory, int, (void* p), (p));\nC_SHIM(MallocMemoryStats, int,\n       (int* blocks, size_t* total, int histogram[kMallocHistogramSize]),\n       (blocks, total, histogram));\n\nC_SHIM(GetStats, void,\n       (char* buffer, int buffer_length), (buffer, buffer_length));\nC_SHIM(GetNumericProperty, int,\n       (const char* property, size_t* value), (property, value));\nC_SHIM(SetNumericProperty, int,\n       (const char* property, size_t value), (property, value));\n\nC_SHIM(MarkThreadIdle, void, (void), ());\nC_SHIM(MarkThreadBusy, void, (void), ());\nC_SHIM(ReleaseFreeMemory, void, (void), ());\nC_SHIM(ReleaseToSystem, void, (size_t num_bytes), (num_bytes));\nC_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size));\nC_SHIM(GetAllocatedSize, size_t, (void* p), (p));\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/malloc_hook-inl.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// This has the implementation details of malloc_hook that are needed\n// to use malloc-hook inside the tcmalloc system.  It does not hold\n// any of the client-facing calls that are used to add new hooks.\n\n#ifndef _MALLOC_HOOK_INL_H_\n#define _MALLOC_HOOK_INL_H_\n\n#include <stddef.h>\n#include <sys/types.h>\n#include \"base/atomicops.h\"\n#include \"base/basictypes.h\"\n#include <google/malloc_hook.h>\n\nnamespace base { namespace internal {\n\n// A simple atomic pointer class that can be initialized by the linker\n// when you define a namespace-scope variable as:\n//\n//   AtomicPtr<Foo*> my_global = { &initial_value };\n//\n// This isn't suitable for a general atomic<> class because of the\n// public access to data_.\ntemplate<typename PtrT>\nclass AtomicPtr {\n public:\n  COMPILE_ASSERT(sizeof(PtrT) <= sizeof(AtomicWord),\n                 PtrT_should_fit_in_AtomicWord);\n\n  PtrT Get() const {\n    // Depending on the system, Acquire_Load(AtomicWord*) may have\n    // been defined to return an AtomicWord, Atomic32, or Atomic64.\n    // We hide that implementation detail here with an explicit cast.\n    // This prevents MSVC 2005, at least, from complaining (it has to\n    // do with __wp64; AtomicWord is __wp64, but Atomic32/64 aren't).\n    return reinterpret_cast<PtrT>(static_cast<AtomicWord>(\n      base::subtle::Acquire_Load(&data_)));\n  }\n\n  // Sets the contained value to new_val and returns the old value,\n  // atomically, with acquire and release semantics.\n  // This is a full-barrier instruction.\n  PtrT Exchange(PtrT new_val);\n\n  // Atomically executes:\n  //      result = data_\n  //      if (data_ == old_val)\n  //        data_ = new_val;\n  //      return result;\n  // This is a full-barrier instruction.\n  PtrT CompareAndSwap(PtrT old_val, PtrT new_val);\n\n  // Not private so that the class is an aggregate and can be\n  // initialized by the linker. Don't access this directly.\n  AtomicWord data_;\n};\n\n// These are initialized in malloc_hook.cc\nextern AtomicPtr<MallocHook::NewHook>     new_hook_;\nextern AtomicPtr<MallocHook::DeleteHook>  delete_hook_;\nextern AtomicPtr<MallocHook::PreMmapHook> premmap_hook_;\nextern AtomicPtr<MallocHook::MmapHook>    mmap_hook_;\nextern AtomicPtr<MallocHook::MunmapHook>  munmap_hook_;\nextern AtomicPtr<MallocHook::MremapHook>  mremap_hook_;\nextern AtomicPtr<MallocHook::PreSbrkHook> presbrk_hook_;\nextern AtomicPtr<MallocHook::SbrkHook>    sbrk_hook_;\n\n} }  // namespace base::internal\n\ninline MallocHook::NewHook MallocHook::GetNewHook() {\n  return base::internal::new_hook_.Get();\n}\n\ninline void MallocHook::InvokeNewHook(const void* p, size_t s) {\n  MallocHook::NewHook hook = MallocHook::GetNewHook();\n  if (hook != NULL) (*hook)(p, s);\n}\n\ninline MallocHook::DeleteHook MallocHook::GetDeleteHook() {\n  return base::internal::delete_hook_.Get();\n}\n\ninline void MallocHook::InvokeDeleteHook(const void* p) {\n  MallocHook::DeleteHook hook = MallocHook::GetDeleteHook();\n  if (hook != NULL) (*hook)(p);\n}\n\ninline MallocHook::PreMmapHook MallocHook::GetPreMmapHook() {\n  return base::internal::premmap_hook_.Get();\n}\n\ninline void MallocHook::InvokePreMmapHook(const void* start,\n                                          size_t size,\n                                          int protection,\n                                          int flags,\n                                          int fd,\n                                          off_t offset) {\n  MallocHook::PreMmapHook hook = MallocHook::GetPreMmapHook();\n  if (hook != NULL) (*hook)(start, size,\n                            protection, flags,\n                            fd, offset);\n}\n\ninline MallocHook::MmapHook MallocHook::GetMmapHook() {\n  return base::internal::mmap_hook_.Get();\n}\n\ninline void MallocHook::InvokeMmapHook(const void* result,\n                                       const void* start,\n                                       size_t size,\n                                       int protection,\n                                       int flags,\n                                       int fd,\n                                       off_t offset) {\n  MallocHook::MmapHook hook = MallocHook::GetMmapHook();\n  if (hook != NULL) (*hook)(result,\n                            start, size,\n                            protection, flags,\n                            fd, offset);\n}\n\ninline MallocHook::MunmapHook MallocHook::GetMunmapHook() {\n  return base::internal::munmap_hook_.Get();\n}\n\ninline void MallocHook::InvokeMunmapHook(const void* p, size_t size) {\n  MallocHook::MunmapHook hook = MallocHook::GetMunmapHook();\n  if (hook != NULL) (*hook)(p, size);\n}\n\ninline MallocHook::MremapHook MallocHook::GetMremapHook() {\n  return base::internal::mremap_hook_.Get();\n}\n\ninline void MallocHook::InvokeMremapHook(const void* result,\n                                         const void* old_addr,\n                                         size_t old_size,\n                                         size_t new_size,\n                                         int flags,\n                                         const void* new_addr) {\n  MallocHook::MremapHook hook = MallocHook::GetMremapHook();\n  if (hook != NULL) (*hook)(result,\n                            old_addr, old_size,\n                            new_size, flags, new_addr);\n}\n\ninline MallocHook::PreSbrkHook MallocHook::GetPreSbrkHook() {\n  return base::internal::presbrk_hook_.Get();\n}\n\ninline void MallocHook::InvokePreSbrkHook(ptrdiff_t increment) {\n  MallocHook::PreSbrkHook hook = MallocHook::GetPreSbrkHook();\n  if (hook != NULL && increment != 0) (*hook)(increment);\n}\n\ninline MallocHook::SbrkHook MallocHook::GetSbrkHook() {\n  return base::internal::sbrk_hook_.Get();\n}\n\ninline void MallocHook::InvokeSbrkHook(const void* result,\n                                       ptrdiff_t increment) {\n  MallocHook::SbrkHook hook = MallocHook::GetSbrkHook();\n  if (hook != NULL && increment != 0) (*hook)(result, increment);\n}\n\n#endif /* _MALLOC_HOOK_INL_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/malloc_hook.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#include <config.h>\n\n// Disable the glibc prototype of mremap(), as older versions of the\n// system headers define this function with only four arguments,\n// whereas newer versions allow an optional fifth argument:\n#ifdef HAVE_MMAP\n# define mremap glibc_mremap\n# include <sys/mman.h>\n# undef mremap\n#endif\n\n#include <algorithm>\n#include \"base/basictypes.h\"\n#include \"base/logging.h\"\n#include \"malloc_hook-inl.h\"\n#include <google/malloc_hook.h>\n\n// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if\n// you're porting to a system where you really can't get a stacktrace.\n#ifdef NO_TCMALLOC_SAMPLES\n  // We use #define so code compiles even if you #include stacktrace.h somehow.\n# define GetStackTrace(stack, depth, skip)  (0)\n#else\n# include <google/stacktrace.h>\n#endif\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    // I guess we're not on a glibc system\n# define __THROW   // __THROW is just an optimization, so ok to make it \"\"\n#endif\n\nusing std::copy;\n\n\n// Declarations of five default weak hook functions, that can be overridden by\n// linking-in a strong definition (as heap-checker.cc does).  These are extern\n// \"C\" so that they don't trigger gold's --detect-odr-violations warning, which\n// only looks at C++ symbols.\n//\n// These default hooks let some other library we link in\n// to define strong versions of InitialMallocHook_New, InitialMallocHook_MMap,\n// InitialMallocHook_PreMMap, InitialMallocHook_PreSbrk, and\n// InitialMallocHook_Sbrk to have a chance to hook into the very first\n// invocation of an allocation function call, mmap, or sbrk.\n//\n// These functions are declared here as weak, and defined later, rather than a\n// more straightforward simple weak definition, as a workround for an icc\n// compiler issue ((Intel reference 290819).  This issue causes icc to resolve\n// weak symbols too early, at compile rather than link time.  By declaring it\n// (weak) here, then defining it below after its use, we can avoid the problem.\n//\nextern \"C\" {\n\nATTRIBUTE_WEAK\nvoid InitialMallocHook_New(const void* ptr, size_t size);\n\nATTRIBUTE_WEAK\nvoid InitialMallocHook_PreMMap(const void* start,\n                               size_t size,\n                               int protection,\n                               int flags,\n                               int fd,\n                               off_t offset);\n\nATTRIBUTE_WEAK\nvoid InitialMallocHook_MMap(const void* result,\n                            const void* start,\n                            size_t size,\n                            int protection,\n                            int flags,\n                            int fd,\n                            off_t offset);\n\nATTRIBUTE_WEAK\nvoid InitialMallocHook_PreSbrk(ptrdiff_t increment);\n\nATTRIBUTE_WEAK\nvoid InitialMallocHook_Sbrk(const void* result, ptrdiff_t increment);\n\n}  // extern \"C\"\n\nnamespace base { namespace internal {\ntemplate<typename PtrT>\nPtrT AtomicPtr<PtrT>::Exchange(PtrT new_val) {\n  base::subtle::MemoryBarrier();  // Release semantics.\n  // Depending on the system, NoBarrier_AtomicExchange(AtomicWord*)\n  // may have been defined to return an AtomicWord, Atomic32, or\n  // Atomic64.  We hide that implementation detail here with an\n  // explicit cast.  This prevents MSVC 2005, at least, from complaining.\n  PtrT old_val = reinterpret_cast<PtrT>(static_cast<AtomicWord>(\n      base::subtle::NoBarrier_AtomicExchange(\n          &data_,\n          reinterpret_cast<AtomicWord>(new_val))));\n  base::subtle::MemoryBarrier();  // And acquire semantics.\n  return old_val;\n}\n\ntemplate<typename PtrT>\nPtrT AtomicPtr<PtrT>::CompareAndSwap(PtrT old_val, PtrT new_val) {\n  base::subtle::MemoryBarrier();  // Release semantics.\n  PtrT retval = reinterpret_cast<PtrT>(static_cast<AtomicWord>(\n      base::subtle::NoBarrier_CompareAndSwap(\n          &data_,\n          reinterpret_cast<AtomicWord>(old_val),\n          reinterpret_cast<AtomicWord>(new_val))));\n  base::subtle::MemoryBarrier();  // And acquire semantics.\n  return retval;\n}\n\nAtomicPtr<MallocHook::NewHook>    new_hook_ = {\n  reinterpret_cast<AtomicWord>(InitialMallocHook_New) };\nAtomicPtr<MallocHook::DeleteHook> delete_hook_ = { 0 };\nAtomicPtr<MallocHook::PreMmapHook> premmap_hook_ = {\n  reinterpret_cast<AtomicWord>(InitialMallocHook_PreMMap) };\nAtomicPtr<MallocHook::MmapHook>   mmap_hook_ = {\n  reinterpret_cast<AtomicWord>(InitialMallocHook_MMap) };\nAtomicPtr<MallocHook::MunmapHook> munmap_hook_ = { 0 };\nAtomicPtr<MallocHook::MremapHook> mremap_hook_ = { 0 };\nAtomicPtr<MallocHook::PreSbrkHook> presbrk_hook_ = {\n  reinterpret_cast<AtomicWord>(InitialMallocHook_PreSbrk) };\nAtomicPtr<MallocHook::SbrkHook>   sbrk_hook_ = {\n  reinterpret_cast<AtomicWord>(InitialMallocHook_Sbrk) };\n\n} }  // namespace base::internal\n\nusing base::internal::new_hook_;\nusing base::internal::delete_hook_;\nusing base::internal::premmap_hook_;\nusing base::internal::mmap_hook_;\nusing base::internal::munmap_hook_;\nusing base::internal::mremap_hook_;\nusing base::internal::presbrk_hook_;\nusing base::internal::sbrk_hook_;\n\n\n// These are available as C bindings as well as C++, hence their\n// definition outside the MallocHook class.\nextern \"C\"\nMallocHook_NewHook MallocHook_SetNewHook(MallocHook_NewHook hook) {\n  return new_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_DeleteHook MallocHook_SetDeleteHook(MallocHook_DeleteHook hook) {\n  return delete_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_PreMmapHook MallocHook_SetPreMmapHook(MallocHook_PreMmapHook hook) {\n  return premmap_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_MmapHook MallocHook_SetMmapHook(MallocHook_MmapHook hook) {\n  return mmap_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_MunmapHook MallocHook_SetMunmapHook(MallocHook_MunmapHook hook) {\n  return munmap_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_MremapHook MallocHook_SetMremapHook(MallocHook_MremapHook hook) {\n  return mremap_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_PreSbrkHook MallocHook_SetPreSbrkHook(MallocHook_PreSbrkHook hook) {\n  return presbrk_hook_.Exchange(hook);\n}\n\nextern \"C\"\nMallocHook_SbrkHook MallocHook_SetSbrkHook(MallocHook_SbrkHook hook) {\n  return sbrk_hook_.Exchange(hook);\n}\n\n\n// The definitions of weak default malloc hooks (New, MMap, and Sbrk)\n// that self deinstall on their first call.  This is entirely for\n// efficiency: the default version of these functions will be called a\n// maximum of one time.  If these functions were a no-op instead, they'd\n// be called every time, costing an extra function call per malloc.\n//\n// However, this 'delete self' isn't safe in general -- it's possible\n// that this function will be called via a daisy chain.  That is,\n// someone else might do\n//    old_hook = MallocHook::SetNewHook(&myhook);\n//    void myhook(void* ptr, size_t size) {\n//       do_my_stuff();\n//       old_hook(ptr, size);   // daisy-chain the hooks\n//    }\n// If old_hook is InitialMallocHook_New(), then this is broken code! --\n// after the first run it'll deregister not only InitialMallocHook_New()\n// but also myhook.  To protect against that, InitialMallocHook_New()\n// makes sure it's the 'top-level' hook before doing the deregistration.\n// This means the daisy-chain case will be less efficient because the\n// hook will be called, and do an if check, for every new.  Alas.\n// TODO(csilvers): add support for removing a hook from the middle of a chain.\n\nvoid InitialMallocHook_New(const void* ptr, size_t size) {\n  // Set new_hook to NULL iff its previous value was InitialMallocHook_New\n  new_hook_.CompareAndSwap(&InitialMallocHook_New, NULL);\n}\n\nvoid InitialMallocHook_PreMMap(const void* start,\n                               size_t size,\n                               int protection,\n                               int flags,\n                               int fd,\n                               off_t offset) {\n  premmap_hook_.CompareAndSwap(&InitialMallocHook_PreMMap, NULL);\n}\n\nvoid InitialMallocHook_MMap(const void* result,\n                            const void* start,\n                            size_t size,\n                            int protection,\n                            int flags,\n                            int fd,\n                            off_t offset) {\n  mmap_hook_.CompareAndSwap(&InitialMallocHook_MMap, NULL);\n}\n\nvoid InitialMallocHook_PreSbrk(ptrdiff_t increment) {\n  presbrk_hook_.CompareAndSwap(&InitialMallocHook_PreSbrk, NULL);\n}\n\nvoid InitialMallocHook_Sbrk(const void* result, ptrdiff_t increment) {\n  sbrk_hook_.CompareAndSwap(&InitialMallocHook_Sbrk, NULL);\n}\n\nDEFINE_ATTRIBUTE_SECTION_VARS(google_malloc);\nDECLARE_ATTRIBUTE_SECTION_VARS(google_malloc);\n  // actual functions are in debugallocation.cc or tcmalloc.cc\nDEFINE_ATTRIBUTE_SECTION_VARS(malloc_hook);\nDECLARE_ATTRIBUTE_SECTION_VARS(malloc_hook);\n  // actual functions are in this file, malloc_hook.cc, and low_level_alloc.cc\n\n#define ADDR_IN_ATTRIBUTE_SECTION(addr, name) \\\n  (reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_START(name)) <= \\\n     reinterpret_cast<uintptr_t>(addr) && \\\n   reinterpret_cast<uintptr_t>(addr) < \\\n     reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_STOP(name)))\n\n// Return true iff 'caller' is a return address within a function\n// that calls one of our hooks via MallocHook:Invoke*.\n// A helper for GetCallerStackTrace.\nstatic inline bool InHookCaller(const void* caller) {\n  return ADDR_IN_ATTRIBUTE_SECTION(caller, google_malloc) ||\n         ADDR_IN_ATTRIBUTE_SECTION(caller, malloc_hook);\n  // We can use one section for everything except tcmalloc_or_debug\n  // due to its special linkage mode, which prevents merging of the sections.\n}\n\n#undef ADDR_IN_ATTRIBUTE_SECTION\n\nstatic bool checked_sections = false;\n\nstatic inline void CheckInHookCaller() {\n  if (!checked_sections) {\n    INIT_ATTRIBUTE_SECTION_VARS(google_malloc);\n    if (ATTRIBUTE_SECTION_START(google_malloc) ==\n        ATTRIBUTE_SECTION_STOP(google_malloc)) {\n      RAW_LOG(ERROR, \"google_malloc section is missing, \"\n                     \"thus InHookCaller is broken!\");\n    }\n    INIT_ATTRIBUTE_SECTION_VARS(malloc_hook);\n    if (ATTRIBUTE_SECTION_START(malloc_hook) ==\n        ATTRIBUTE_SECTION_STOP(malloc_hook)) {\n      RAW_LOG(ERROR, \"malloc_hook section is missing, \"\n                     \"thus InHookCaller is broken!\");\n    }\n    checked_sections = true;\n  }\n}\n\n// We can improve behavior/compactness of this function\n// if we pass a generic test function (with a generic arg)\n// into the implementations for GetStackTrace instead of the skip_count.\nextern \"C\" int MallocHook_GetCallerStackTrace(void** result, int max_depth,\n                                              int skip_count) {\n#if defined(NO_TCMALLOC_SAMPLES)\n  return 0;\n#elif !defined(HAVE_ATTRIBUTE_SECTION_START)\n  // Fall back to GetStackTrace and good old but fragile frame skip counts.\n  // Note: this path is inaccurate when a hook is not called directly by an\n  // allocation function but is daisy-chained through another hook,\n  // search for MallocHook::(Get|Set|Invoke)* to find such cases.\n  return GetStackTrace(result, max_depth, skip_count + int(DEBUG_MODE));\n  // due to -foptimize-sibling-calls in opt mode\n  // there's no need for extra frame skip here then\n#else\n  CheckInHookCaller();\n  // MallocHook caller determination via InHookCaller works, use it:\n  static const int kMaxSkip = 32 + 6 + 3;\n    // Constant tuned to do just one GetStackTrace call below in practice\n    // and not get many frames that we don't actually need:\n    // currently max passsed max_depth is 32,\n    // max passed/needed skip_count is 6\n    // and 3 is to account for some hook daisy chaining.\n  static const int kStackSize = kMaxSkip + 1;\n  void* stack[kStackSize];\n  int depth = GetStackTrace(stack, kStackSize, 1);  // skip this function frame\n  if (depth == 0)   // silenty propagate cases when GetStackTrace does not work\n    return 0;\n  for (int i = 0; i < depth; ++i) {  // stack[0] is our immediate caller\n    if (InHookCaller(stack[i])) {\n      RAW_VLOG(10, \"Found hooked allocator at %d: %p <- %p\",\n                   i, stack[i], stack[i+1]);\n      i += 1;  // skip hook caller frame\n      depth -= i;  // correct depth\n      if (depth > max_depth) depth = max_depth;\n      copy(stack + i, stack + i + depth, result);\n      if (depth < max_depth  &&  depth + i == kStackSize) {\n        // get frames for the missing depth\n        depth +=\n          GetStackTrace(result + depth, max_depth - depth, 1 + kStackSize);\n      }\n      return depth;\n    }\n  }\n  RAW_LOG(WARNING, \"Hooked allocator frame not found, returning empty trace\");\n    // If this happens try increasing kMaxSkip\n    // or else something must be wrong with InHookCaller,\n    // e.g. for every section used in InHookCaller\n    // all functions in that section must be inside the same library.\n  return 0;\n#endif\n}\n\n// On Linux/x86, we override mmap/munmap/mremap/sbrk\n// and provide support for calling the related hooks.\n//\n// We define mmap() and mmap64(), which somewhat reimplements libc's mmap\n// syscall stubs.  Unfortunately libc only exports the stubs via weak symbols\n// (which we're overriding with our mmap64() and mmap() wrappers) so we can't\n// just call through to them.\n\n\n#if defined(__linux) && \\\n    (defined(__i386__) || defined(__x86_64__) || defined(__PPC__))\n#include <unistd.h>\n#include <syscall.h>\n#include <sys/mman.h>\n#include <errno.h>\n#include \"base/linux_syscall_support.h\"\n\n// The x86-32 case and the x86-64 case differ:\n// 32b has a mmap2() syscall, 64b does not.\n// 64b and 32b have different calling conventions for mmap().\n#if defined(__x86_64__) || defined(__PPC64__)\n\nstatic inline void* do_mmap64(void *start, size_t length,\n                              int prot, int flags,\n                              int fd, __off64_t offset) __THROW {\n  return (void *)syscall(SYS_mmap, start, length, prot, flags, fd, offset);\n}\n\n#elif defined(__i386__) || defined(__PPC__)\n\nstatic inline void* do_mmap64(void *start, size_t length,\n                              int prot, int flags,\n                              int fd, __off64_t offset) __THROW {\n  void *result;\n\n  // Try mmap2() unless it's not supported\n  static bool have_mmap2 = true;\n  if (have_mmap2) {\n    static int pagesize = 0;\n    if (!pagesize) pagesize = getpagesize();\n\n    // Check that the offset is page aligned\n    if (offset & (pagesize - 1)) {\n      result = MAP_FAILED;\n      errno = EINVAL;\n      goto out;\n    }\n\n    result = (void *)syscall(SYS_mmap2, \n                       start, length, prot, flags, fd,\n                       (off_t) (offset / pagesize));\n    if (result != MAP_FAILED || errno != ENOSYS)  goto out;\n\n    // We don't have mmap2() after all - don't bother trying it in future\n    have_mmap2 = false;\n  }\n\n  if (((off_t)offset) != offset) {\n    // If we're trying to map a 64-bit offset, fail now since we don't\n    // have 64-bit mmap() support.\n    result = MAP_FAILED;\n    errno = EINVAL;\n    goto out;\n  }\n\n  {\n    // Fall back to old 32-bit offset mmap() call\n    // Old syscall interface cannot handle six args, so pass in an array\n    int32 args[6] = { (int32) start, length, prot, flags, fd, (off_t) offset };\n    result = (void *)syscall(SYS_mmap, args);\n  }\n out:\n  return result;\n}\n\n# endif  // defined(__x86_64__)\n\n// We use do_mmap64 abstraction to put MallocHook::InvokeMmapHook\n// calls right into mmap and mmap64, so that the stack frames in the caller's\n// stack are at the same offsets for all the calls of memory allocating\n// functions.\n\n// Put all callers of MallocHook::Invoke* in this module into\n// malloc_hook section,\n// so that MallocHook::GetCallerStackTrace can function accurately:\n\n// Make sure mmap doesn't get #define'd away by <sys/mman.h>\n#undef mmap\n\nextern \"C\" {\n  void* mmap64(void *start, size_t length, int prot, int flags,\n               int fd, __off64_t offset  ) __THROW\n    ATTRIBUTE_SECTION(malloc_hook);\n  void* mmap(void *start, size_t length,int prot, int flags,\n             int fd, off_t offset) __THROW\n    ATTRIBUTE_SECTION(malloc_hook);\n  int munmap(void* start, size_t length) __THROW\n    ATTRIBUTE_SECTION(malloc_hook);\n  void* mremap(void* old_addr, size_t old_size, size_t new_size,\n               int flags, ...) __THROW\n    ATTRIBUTE_SECTION(malloc_hook);\n  void* sbrk(ptrdiff_t increment) __THROW\n    ATTRIBUTE_SECTION(malloc_hook);\n}\n\nextern \"C\" void* mmap64(void *start, size_t length, int prot, int flags,\n                        int fd, __off64_t offset) __THROW {\n  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);\n  void *result = do_mmap64(start, length, prot, flags, fd, offset);\n  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);\n  return result;\n}\n\n#if !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH)\n\nextern \"C\" void* mmap(void *start, size_t length, int prot, int flags,\n                      int fd, off_t offset) __THROW {\n  MallocHook::InvokePreMmapHook(start, length, prot, flags, fd, offset);\n  void *result = do_mmap64(start, length, prot, flags, fd,\n                           static_cast<size_t>(offset)); // avoid sign extension\n  MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);\n  return result;\n}\n\n#endif  // !defined(__USE_FILE_OFFSET64) || !defined(__REDIRECT_NTH)\n\nextern \"C\" int munmap(void* start, size_t length) __THROW {\n  MallocHook::InvokeMunmapHook(start, length);\n  return syscall(SYS_munmap, start, length);\n}\n\nextern \"C\" void* mremap(void* old_addr, size_t old_size, size_t new_size,\n                        int flags, ...) __THROW {\n  va_list ap;\n  va_start(ap, flags);\n  void *new_address = va_arg(ap, void *);\n  va_end(ap);\n  void* result = sys_mremap(old_addr, old_size, new_size, flags, new_address);\n  MallocHook::InvokeMremapHook(result, old_addr, old_size, new_size, flags,\n                               new_address);\n  return result;\n}\n\n// libc's version:\nextern \"C\" void* __sbrk(ptrdiff_t increment);\n\nextern \"C\" void* sbrk(ptrdiff_t increment) __THROW {\n  MallocHook::InvokePreSbrkHook(increment);\n  void *result = __sbrk(increment);\n  MallocHook::InvokeSbrkHook(result, increment);\n  return result;\n}\n\n/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,\n                                         int flags, int fd, off_t offset) {\n  return do_mmap64(start, length, prot, flags, fd, offset);\n}\n\n/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {\n  return sys_munmap(start, length);\n}\n\n#else   // defined(__linux) &&\n        // (defined(__i386__) || defined(__x86_64__) || defined(__PPC__))\n\n/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,\n                                         int flags, int fd, off_t offset) {\n  return mmap(start, length, prot, flags, fd, offset);\n}\n\n/*static*/int MallocHook::UnhookedMUnmap(void *start, size_t length) {\n  return munmap(start, length);\n}\n\n#endif  // defined(__linux) &&\n        // (defined(__i386__) || defined(__x86_64__) || defined(__PPC__))\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/maybe_threads.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Paul Menage <opensource@google.com>\n//\n// Some wrappers for pthread functions so that we can be LD_PRELOADed\n// against non-pthreads apps.\n//\n// This module will behave very strangely if some pthreads functions\n// exist and others don't.\n\n#include \"config.h\"\n#include <assert.h>\n#include <string.h>    // for memcmp\n// We don't actually need strings. But including this header seems to\n// stop the compiler trying to short-circuit our pthreads existence\n// tests and claiming that the address of a function is always\n// non-zero. I have no idea why ...\n#include <string>\n#include \"maybe_threads.h\"\n#include \"base/basictypes.h\"\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    // I guess we're not on a glibc system\n# define __THROW   // __THROW is just an optimization, so ok to make it \"\"\n#endif\n\n// These are the methods we're going to conditionally include.\nextern \"C\" {\n  int pthread_key_create (pthread_key_t*, void (*)(void*))\n      __THROW ATTRIBUTE_WEAK;\n  void *pthread_getspecific(pthread_key_t)\n      __THROW ATTRIBUTE_WEAK;\n  int pthread_setspecific(pthread_key_t, const void*)\n      __THROW ATTRIBUTE_WEAK;\n  int pthread_once(pthread_once_t *, void (*)(void))\n      ATTRIBUTE_WEAK;\n}\n\n#define MAX_PERTHREAD_VALS 16\nstatic void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS];\nstatic int next_key;\n\nint perftools_pthread_key_create(pthread_key_t *key,\n                                 void (*destr_function) (void *)) {\n  if (pthread_key_create) {\n    return pthread_key_create(key, destr_function);\n  } else {\n    assert(next_key < MAX_PERTHREAD_VALS);\n    *key = (pthread_key_t)(next_key++);\n    return 0;\n  }\n}\n\nvoid *perftools_pthread_getspecific(pthread_key_t key) {\n  if (pthread_getspecific) {\n    return pthread_getspecific(key);\n  } else {\n    return perftools_pthread_specific_vals[(int)key];\n  }\n}\n\nint perftools_pthread_setspecific(pthread_key_t key, void *val) {\n  if (pthread_setspecific) {\n    return pthread_setspecific(key, val);\n  } else {\n    perftools_pthread_specific_vals[(int)key] = val;\n    return 0;\n  }\n}\n\nstatic pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;\nint perftools_pthread_once(pthread_once_t *ctl,\n                           void  (*init_routine) (void)) {\n  if (pthread_once) {\n    return pthread_once(ctl, init_routine);\n  } else {\n    if (memcmp(ctl, &pthread_once_init, sizeof(*ctl)) == 0) {\n      init_routine();\n      ++*(char*)(ctl);        // make it so it's no longer equal to init\n    }\n    return 0;\n  }\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/maybe_threads.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Paul Menage <opensource@google.com>\n\n//-------------------------------------------------------------------\n// Some wrappers for pthread functions so that we can be LD_PRELOADed\n// against non-pthreads apps.\n//-------------------------------------------------------------------\n\n#ifndef GOOGLE_MAYBE_THREADS_H_\n#define GOOGLE_MAYBE_THREADS_H_\n\n#ifdef HAVE_PTHREAD\n#include <pthread.h>\n#endif\n\nint perftools_pthread_key_create(pthread_key_t *key,\n                                 void (*destr_function) (void *));\nvoid *perftools_pthread_getspecific(pthread_key_t key);\nint perftools_pthread_setspecific(pthread_key_t key, void *val);\nint perftools_pthread_once(pthread_once_t *ctl,\n                           void  (*init_routine) (void));\n\n#endif  /* GOOGLE_MAYBE_THREADS_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/memfs_malloc.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Arun Sharma\n//\n// A tcmalloc system allocator that uses a memory based filesystem such as\n// tmpfs or hugetlbfs\n//\n// Since these only exist on linux, we only register this allocator there.\n\n#ifdef __linux\n\n#include <config.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <inttypes.h>\n#include <sys/mman.h>\n#include <sys/param.h>\n#include <sys/types.h>\n#include <sys/vfs.h>           // for statfs\n#include <string>\n\n#include \"base/basictypes.h\"\n#include \"base/googleinit.h\"\n#include \"base/sysinfo.h\"\n#include \"system-alloc.h\"\n#include \"internal_logging.h\"\n\nusing std::string;\n\nDEFINE_string(memfs_malloc_path, EnvToString(\"TCMALLOC_MEMFS_MALLOC_PATH\", \"\"),\n              \"Path where hugetlbfs or tmpfs is mounted. The caller is \"\n              \"responsible for ensuring that the path is unique and does \"\n              \"not conflict with another process\");\nDEFINE_int64(memfs_malloc_limit_mb,\n             EnvToInt(\"TCMALLOC_MEMFS_LIMIT_MB\", 0),\n             \"Limit total allocation size to the \"\n             \"specified number of MiB.  0 == no limit.\");\nDEFINE_bool(memfs_malloc_abort_on_fail,\n            EnvToBool(\"TCMALLOC_MEMFS_ABORT_ON_FAIL\", false),\n            \"abort() whenever memfs_malloc fails to satisfy an allocation \"\n            \"for any reason.\");\nDEFINE_bool(memfs_malloc_ignore_mmap_fail,\n            EnvToBool(\"TCMALLOC_MEMFS_IGNORE_MMAP_FAIL\", false),\n            \"Ignore failures from mmap\");\n\n// Hugetlbfs based allocator for tcmalloc\nclass HugetlbSysAllocator: public SysAllocator {\npublic:\n  HugetlbSysAllocator(int fd, int page_size)\n    : big_page_size_(page_size),\n      hugetlb_fd_(fd),\n      hugetlb_base_(0) {\n  }\n\n  void* Alloc(size_t size, size_t *actual_size, size_t alignment);\n\n  void DumpStats(TCMalloc_Printer* printer);\n\nprivate:\n  int64 big_page_size_;\n  int hugetlb_fd_;      // file descriptor for hugetlb\n  off_t hugetlb_base_;\n};\n\nvoid HugetlbSysAllocator::DumpStats(TCMalloc_Printer* printer) {\n  printer->printf(\"HugetlbSysAllocator: failed_=%d allocated=%\"PRId64\"\\n\",\n                  failed_, static_cast<int64_t>(hugetlb_base_));\n}\n\n// No locking needed here since we assume that tcmalloc calls\n// us with an internal lock held (see tcmalloc/system-alloc.cc).\nvoid* HugetlbSysAllocator::Alloc(size_t size, size_t *actual_size,\n                                 size_t alignment) {\n\n  // don't go any further if we haven't opened the backing file\n  if (hugetlb_fd_ == -1) {\n    return NULL;\n  }\n\n  // We don't respond to allocation requests smaller than big_page_size_ unless\n  // the caller is willing to take more than they asked for.\n  if (actual_size == NULL && size < big_page_size_) {\n    return NULL;\n  }\n\n  // Enforce huge page alignment.  Be careful to deal with overflow.\n  if (alignment < big_page_size_) alignment = big_page_size_;\n  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;\n  if (aligned_size < size) {\n    return NULL;\n  }\n  size = aligned_size;\n\n  // Ask for extra memory if alignment > pagesize\n  size_t extra = 0;\n  if (alignment > big_page_size_) {\n    extra = alignment - big_page_size_;\n  }\n\n  // Test if this allocation would put us over the limit.\n  off_t limit = FLAGS_memfs_malloc_limit_mb*1024*1024;\n  if (limit > 0 && hugetlb_base_ + size + extra > limit) {\n    // Disable the allocator when there's less than one page left.\n    if (limit - hugetlb_base_ < big_page_size_) {\n      TCMalloc_MESSAGE(__FILE__, __LINE__, \"reached memfs_malloc_limit_mb\\n\");\n      failed_ = true;\n    }\n    else {\n      TCMalloc_MESSAGE(__FILE__, __LINE__, \"alloc size=%\"PRIuS\n                       \" too large while %\"PRId64\" bytes remain\\n\",\n                       size, static_cast<int64_t>(limit - hugetlb_base_));\n    }\n    if (FLAGS_memfs_malloc_abort_on_fail) {\n      CRASH(\"memfs_malloc_abort_on_fail is set\\n\");\n    }\n    return NULL;\n  }\n\n  // This is not needed for hugetlbfs, but needed for tmpfs.  Annoyingly\n  // hugetlbfs returns EINVAL for ftruncate.\n  int ret = ftruncate(hugetlb_fd_, hugetlb_base_ + size + extra);\n  if (ret != 0 && errno != EINVAL) {\n    TCMalloc_MESSAGE(__FILE__, __LINE__, \"ftruncate failed: %s\\n\",\n                     strerror(errno));\n    failed_ = true;\n    if (FLAGS_memfs_malloc_abort_on_fail) {\n      CRASH(\"memfs_malloc_abort_on_fail is set\\n\");\n    }\n    return NULL;\n  }\n\n  // Note: size + extra does not overflow since:\n  //            size + alignment < (1<<NBITS).\n  // and        extra <= alignment\n  // therefore  size + extra < (1<<NBITS)\n  void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,\n                      MAP_SHARED, hugetlb_fd_, hugetlb_base_);\n  if (result == reinterpret_cast<void*>(MAP_FAILED)) {\n    if (!FLAGS_memfs_malloc_ignore_mmap_fail) {\n      TCMalloc_MESSAGE(__FILE__, __LINE__, \"mmap of size %\"PRIuS\" failed: %s\\n\",\n                       size + extra, strerror(errno));\n      failed_ = true;\n      if (FLAGS_memfs_malloc_abort_on_fail) {\n        CRASH(\"memfs_malloc_abort_on_fail is set\\n\");\n      }\n    }\n    return NULL;\n  }\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);\n\n  // Adjust the return memory so it is aligned\n  size_t adjust = 0;\n  if ((ptr & (alignment - 1)) != 0) {\n    adjust = alignment - (ptr & (alignment - 1));\n  }\n  ptr += adjust;\n  hugetlb_base_ += (size + extra);\n\n  if (actual_size) {\n    *actual_size = size + extra - adjust;\n  }\n\n  return reinterpret_cast<void*>(ptr);\n}\n\nstatic void InitSystemAllocator() {\n  if (FLAGS_memfs_malloc_path.length()) {\n    char path[PATH_MAX];\n    int rc = snprintf(path, sizeof(path), \"%s.XXXXXX\",\n                      FLAGS_memfs_malloc_path.c_str());\n    if (rc < 0 || rc >= sizeof(path)) {\n      CRASH(\"XX fatal: memfs_malloc_path too long\\n\");\n    }\n\n    int hugetlb_fd = mkstemp(path);\n    if (hugetlb_fd == -1) {\n      TCMalloc_MESSAGE(__FILE__, __LINE__,\n                       \"warning: unable to create memfs_malloc_path %s: %s\\n\",\n                       path, strerror(errno));\n      return;\n    }\n\n    // Cleanup memory on process exit\n    if (unlink(path) == -1) {\n      CRASH(\"fatal: error unlinking memfs_malloc_path %s: %s\\n\",\n            path, strerror(errno));\n    }\n\n    // Use fstatfs to figure out the default page size for memfs\n    struct statfs sfs;\n    if (fstatfs(hugetlb_fd, &sfs) == -1) {\n      CRASH(\"fatal: error fstatfs of memfs_malloc_path: %s\\n\",\n            strerror(errno));\n    }\n    int64 page_size = sfs.f_bsize;\n\n    SysAllocator *alloc = new HugetlbSysAllocator(hugetlb_fd, page_size);\n    // Register ourselves with tcmalloc\n    RegisterSystemAllocator(alloc, 0);\n  }\n}\n\nREGISTER_MODULE_INITIALIZER(memfs_malloc, { InitSystemAllocator(); });\n\n#endif   /* ifdef __linux */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/memory_region_map.cc",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Maxim Lifantsev\n */\n\n//\n// Background and key design points of MemoryRegionMap.\n//\n// MemoryRegionMap is a low-level module with quite atypical requirements that\n// result in some degree of non-triviality of the implementation and design.\n//\n// MemoryRegionMap collects info about *all* memory regions created with\n// mmap, munmap, mremap, sbrk.\n// They key word above is 'all': all that are happening in a process\n// during its lifetime frequently starting even before global object\n// constructor execution.\n//\n// This is needed by the primary client of MemoryRegionMap:\n// HeapLeakChecker uses the regions and the associated stack traces\n// to figure out what part of the memory is the heap:\n// if MemoryRegionMap were to miss some (early) regions, leak checking would\n// stop working correctly.\n//\n// To accomplish the goal of functioning before/during global object\n// constructor execution MemoryRegionMap is done as a singleton service\n// that relies on own on-demand initialized static constructor-less data,\n// and only relies on other low-level modules that can also function properly\n// even before global object constructors run.\n//\n// Accomplishing the goal of collecting data about all mmap, munmap, mremap,\n// sbrk occurrences is a more involved: conceptually to do this one needs to\n// record some bits of data in particular about any mmap or sbrk call,\n// but to do that one needs to allocate memory for that data at some point,\n// but all memory allocations in the end themselves come from an mmap\n// or sbrk call (that's how the address space of the process grows).\n//\n// Also note that we need to do all the above recording from\n// within an mmap/sbrk hook which is sometimes/frequently is made by a memory\n// allocator, including the allocator MemoryRegionMap itself must rely on.\n// In the case of heap-checker usage this includes even the very first\n// mmap/sbrk call happening in the program: heap-checker gets activated due to\n// a link-time installed mmap/sbrk hook and it initializes MemoryRegionMap\n// and asks it to record info about this very first call right from that\n// very first hook invocation.\n//\n// MemoryRegionMap is doing its memory allocations via LowLevelAlloc:\n// unlike more complex standard memory allocator, LowLevelAlloc cooperates with\n// MemoryRegionMap by not holding any of its own locks while it calls mmap\n// to get memory, thus we are able to call LowLevelAlloc from\n// our mmap/sbrk hooks without causing a deadlock in it.\n// For the same reason of deadlock prevention the locking in MemoryRegionMap\n// itself is write-recursive which is an exception to Google's mutex usage.\n//\n// We still need to break the infinite cycle of mmap calling our hook,\n// which asks LowLevelAlloc for memory to record this mmap,\n// which (sometimes) causes mmap, which calls our hook, and so on.\n// We do this as follows: on a recursive call of MemoryRegionMap's\n// mmap/sbrk/mremap hook we record the data about the allocation in a\n// static fixed-sized stack (saved_regions), when the recursion unwinds\n// but before returning from the outer hook call we unwind this stack and\n// move the data from saved_regions to its permanent place in the RegionSet,\n// which can cause more allocations and mmap-s and recursion and unwinding,\n// but the whole process ends eventually due to the fact that for the small\n// allocations we are doing LowLevelAlloc reuses one mmap call and parcels out\n// the memory it created to satisfy several of our allocation requests.\n//\n\n// ========================================================================= //\n\n#include <config.h>\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#elif !defined(MAP_FAILED)\n#define MAP_FAILED -1  // the only thing we need from mman.h\n#endif\n#ifdef HAVE_PTHREAD\n#include <pthread.h>   // for pthread_t, pthread_self()\n#endif\n\n#include <algorithm>\n#include <set>\n\n#include \"memory_region_map.h\"\n\n#include \"base/logging.h\"\n#include \"base/low_level_alloc.h\"\n#include \"malloc_hook-inl.h\"\n\n#include <google/stacktrace.h>\n#include <google/malloc_hook.h>\n\n// MREMAP_FIXED is a linux extension.  How it's used in this file,\n// setting it to 0 is equivalent to saying, \"This feature isn't\n// supported\", which is right.\n#ifndef MREMAP_FIXED\n# define MREMAP_FIXED  0\n#endif\n\nusing std::max;\n\n// ========================================================================= //\n\nint MemoryRegionMap::client_count_ = 0;\nint MemoryRegionMap::max_stack_depth_ = 0;\nMemoryRegionMap::RegionSet* MemoryRegionMap::regions_ = NULL;\nLowLevelAlloc::Arena* MemoryRegionMap::arena_ = NULL;\nSpinLock MemoryRegionMap::lock_(SpinLock::LINKER_INITIALIZED);\nSpinLock MemoryRegionMap::owner_lock_(  // ACQUIRED_AFTER(lock_)\n    SpinLock::LINKER_INITIALIZED);\nint MemoryRegionMap::recursion_count_ = 0;  // GUARDED_BY(owner_lock_)\npthread_t MemoryRegionMap::lock_owner_tid_;  // GUARDED_BY(owner_lock_)\n\n// ========================================================================= //\n\n// Simple hook into execution of global object constructors,\n// so that we do not call pthread_self() when it does not yet work.\nstatic bool libpthread_initialized = false;\nstatic bool initializer = (libpthread_initialized = true, true);\n\nstatic inline bool current_thread_is(pthread_t should_be) {\n  // Before main() runs, there's only one thread, so we're always that thread\n  if (!libpthread_initialized) return true;\n  // this starts working only sometime well into global constructor execution:\n  return pthread_equal(pthread_self(), should_be);\n}\n\n// ========================================================================= //\n\n// Constructor-less place-holder to store a RegionSet in.\nunion MemoryRegionMap::RegionSetRep {\n  char rep[sizeof(RegionSet)];\n  void* align_it;  // do not need a better alignment for 'rep' than this\n  RegionSet* region_set() { return reinterpret_cast<RegionSet*>(rep); }\n};\n\n// The bytes where MemoryRegionMap::regions_ will point to.\n// We use RegionSetRep with noop c-tor so that global construction\n// does not interfere.\nstatic MemoryRegionMap::RegionSetRep regions_rep;\n\n// ========================================================================= //\n\n// Has InsertRegionLocked been called recursively\n// (or rather should we *not* use regions_ to record a hooked mmap).\nstatic bool recursive_insert = false;\n\nvoid MemoryRegionMap::Init(int max_stack_depth) {\n  RAW_VLOG(10, \"MemoryRegionMap Init\");\n  RAW_CHECK(max_stack_depth >= 0, \"\");\n  // Make sure we don't overflow the memory in region stacks:\n  RAW_CHECK(max_stack_depth <= kMaxStackDepth,\n            \"need to increase kMaxStackDepth?\");\n  Lock();\n  client_count_ += 1;\n  max_stack_depth_ = max(max_stack_depth_, max_stack_depth);\n  if (client_count_ > 1) {\n    // not first client: already did initialization-proper\n    Unlock();\n    RAW_VLOG(10, \"MemoryRegionMap Init increment done\");\n    return;\n  }\n  // Set our hooks and make sure no other hooks existed:\n  if (MallocHook::SetMmapHook(MmapHook) != NULL  ||\n      MallocHook::SetMremapHook(MremapHook) != NULL  ||\n      MallocHook::SetSbrkHook(SbrkHook) != NULL  ||\n      MallocHook::SetMunmapHook(MunmapHook) != NULL) {\n    RAW_LOG(FATAL, \"Had other mmap/mremap/munmap/sbrk MallocHook-s set. \"\n                   \"Make sure only one of MemoryRegionMap and the other \"\n                   \"client is active.\");\n  }\n  // We need to set recursive_insert since the NewArena call itself\n  // will already do some allocations with mmap which our hooks will catch\n  // recursive_insert allows us to buffer info about these mmap calls.\n  // Note that Init() can be (and is) sometimes called\n  // already from within an mmap/sbrk hook.\n  recursive_insert = true;\n  arena_ = LowLevelAlloc::NewArena(0, LowLevelAlloc::DefaultArena());\n  recursive_insert = false;\n  HandleSavedRegionsLocked(&InsertRegionLocked);  // flush the buffered ones\n    // Can't instead use HandleSavedRegionsLocked(&DoInsertRegionLocked) before\n    // recursive_insert = false; as InsertRegionLocked will also construct\n    // regions_ on demand for us.\n  Unlock();\n  RAW_VLOG(10, \"MemoryRegionMap Init done\");\n}\n\nbool MemoryRegionMap::Shutdown() {\n  RAW_VLOG(10, \"MemoryRegionMap Shutdown\");\n  Lock();\n  RAW_CHECK(client_count_ > 0, \"\");\n  client_count_ -= 1;\n  if (client_count_ != 0) {  // not last client; need not really shutdown\n    Unlock();\n    RAW_VLOG(10, \"MemoryRegionMap Shutdown decrement done\");\n    return true;\n  }\n  CheckMallocHooks();  // we assume no other hooks\n  MallocHook::SetMmapHook(NULL);\n  MallocHook::SetMremapHook(NULL);\n  MallocHook::SetSbrkHook(NULL);\n  MallocHook::SetMunmapHook(NULL);\n  if (regions_) regions_->~RegionSet();\n  regions_ = NULL;\n  bool deleted_arena = LowLevelAlloc::DeleteArena(arena_);\n  if (deleted_arena) {\n    arena_ = 0;\n  } else {\n    RAW_LOG(WARNING, \"Can't delete LowLevelAlloc arena: it's being used\");\n  }\n  Unlock();\n  RAW_VLOG(10, \"MemoryRegionMap Shutdown done\");\n  return deleted_arena;\n}\n\nvoid MemoryRegionMap::CheckMallocHooks() {\n  if (MallocHook::GetMmapHook() != MmapHook  ||\n      MallocHook::GetMunmapHook() != MunmapHook  ||\n      MallocHook::GetMremapHook() != MremapHook  ||\n      MallocHook::GetSbrkHook() != SbrkHook) {\n    RAW_LOG(FATAL, \"Our mmap/mremap/munmap/sbrk MallocHook-s got changed.\");\n  }\n}\n\n// Invariants (once libpthread_initialized is true):\n//   * While lock_ is not held, recursion_count_ is 0 (and\n//     lock_owner_tid_ is the previous owner, but we don't rely on\n//     that).\n//   * recursion_count_ and lock_owner_tid_ are only written while\n//     both lock_ and owner_lock_ are held. They may be read under\n//     just owner_lock_.\n//   * At entry and exit of Lock() and Unlock(), the current thread\n//     owns lock_ iff pthread_equal(lock_owner_tid_, pthread_self())\n//     && recursion_count_ > 0.\nvoid MemoryRegionMap::Lock() {\n  {\n    SpinLockHolder l(&owner_lock_);\n    if (recursion_count_ > 0 && current_thread_is(lock_owner_tid_)) {\n      RAW_CHECK(lock_.IsHeld(), \"Invariants violated\");\n      recursion_count_++;\n      RAW_CHECK(recursion_count_ <= 5,\n                \"recursive lock nesting unexpectedly deep\");\n      return;\n    }\n  }\n  lock_.Lock();\n  {\n    SpinLockHolder l(&owner_lock_);\n    RAW_CHECK(recursion_count_ == 0,\n              \"Last Unlock didn't reset recursion_count_\");\n    if (libpthread_initialized)\n      lock_owner_tid_ = pthread_self();\n    recursion_count_ = 1;\n  }\n}\n\nvoid MemoryRegionMap::Unlock() {\n  SpinLockHolder l(&owner_lock_);\n  RAW_CHECK(recursion_count_ >  0, \"unlock when not held\");\n  RAW_CHECK(lock_.IsHeld(),\n            \"unlock when not held, and recursion_count_ is wrong\");\n  RAW_CHECK(current_thread_is(lock_owner_tid_), \"unlock by non-holder\");\n  recursion_count_--;\n  if (recursion_count_ == 0) {\n    lock_.Unlock();\n  }\n}\n\nbool MemoryRegionMap::LockIsHeld() {\n  SpinLockHolder l(&owner_lock_);\n  return lock_.IsHeld()  &&  current_thread_is(lock_owner_tid_);\n}\n\nconst MemoryRegionMap::Region*\nMemoryRegionMap::DoFindRegionLocked(uintptr_t addr) {\n  RAW_CHECK(LockIsHeld(), \"should be held (by this thread)\");\n  if (regions_ != NULL) {\n    Region sample;\n    sample.SetRegionSetKey(addr);\n    RegionSet::iterator region = regions_->lower_bound(sample);\n    if (region != regions_->end()) {\n      RAW_CHECK(addr <= region->end_addr, \"\");\n      if (region->start_addr <= addr  &&  addr < region->end_addr) {\n        return &(*region);\n      }\n    }\n  }\n  return NULL;\n}\n\nbool MemoryRegionMap::FindRegion(uintptr_t addr, Region* result) {\n  Lock();\n  const Region* region = DoFindRegionLocked(addr);\n  if (region != NULL) *result = *region;  // create it as an independent copy\n  Unlock();\n  return region != NULL;\n}\n\nbool MemoryRegionMap::FindAndMarkStackRegion(uintptr_t stack_top,\n                                             Region* result) {\n  Lock();\n  const Region* region = DoFindRegionLocked(stack_top);\n  if (region != NULL) {\n    RAW_VLOG(10, \"Stack at %p is inside region %p..%p\",\n                reinterpret_cast<void*>(stack_top),\n                reinterpret_cast<void*>(region->start_addr),\n                reinterpret_cast<void*>(region->end_addr));\n    const_cast<Region*>(region)->set_is_stack();  // now we know\n      // cast is safe (set_is_stack does not change the set ordering key)\n    *result = *region;  // create *result as an independent copy\n  }\n  Unlock();\n  return region != NULL;\n}\n\nMemoryRegionMap::RegionIterator MemoryRegionMap::BeginRegionLocked() {\n  RAW_CHECK(LockIsHeld(), \"should be held (by this thread)\");\n  RAW_CHECK(regions_ != NULL, \"\");\n  return regions_->begin();\n}\n\nMemoryRegionMap::RegionIterator MemoryRegionMap::EndRegionLocked() {\n  RAW_CHECK(LockIsHeld(), \"should be held (by this thread)\");\n  RAW_CHECK(regions_ != NULL, \"\");\n  return regions_->end();\n}\n\ninline void MemoryRegionMap::DoInsertRegionLocked(const Region& region) {\n  RAW_VLOG(12, \"Inserting region %p..%p from %p\",\n              reinterpret_cast<void*>(region.start_addr),\n              reinterpret_cast<void*>(region.end_addr),\n              reinterpret_cast<void*>(region.caller()));\n  RegionSet::const_iterator i = regions_->lower_bound(region);\n  if (i != regions_->end() && i->start_addr <= region.start_addr) {\n    RAW_DCHECK(region.end_addr <= i->end_addr, \"\");  // lower_bound ensures this\n    return;  // 'region' is a subset of an already recorded region; do nothing\n    // We can be stricter and allow this only when *i has been created via\n    // an mmap with MAP_NORESERVE flag set.\n  }\n  if (DEBUG_MODE) {\n    RAW_CHECK(i == regions_->end()  ||  !region.Overlaps(*i),\n              \"Wow, overlapping memory regions\");\n    Region sample;\n    sample.SetRegionSetKey(region.start_addr);\n    i = regions_->lower_bound(sample);\n    RAW_CHECK(i == regions_->end()  ||  !region.Overlaps(*i),\n              \"Wow, overlapping memory regions\");\n  }\n  region.AssertIsConsistent();  // just making sure\n  // This inserts and allocates permanent storage for region\n  // and its call stack data: it's safe to do it now:\n  regions_->insert(region);\n  RAW_VLOG(12, \"Inserted region %p..%p :\",\n              reinterpret_cast<void*>(region.start_addr),\n              reinterpret_cast<void*>(region.end_addr));\n  if (VLOG_IS_ON(12))  LogAllLocked();\n}\n\n// These variables are local to MemoryRegionMap::InsertRegionLocked()\n// and MemoryRegionMap::HandleSavedRegionsLocked()\n// and are file-level to ensure that they are initialized at load time.\n\n// Number of unprocessed region inserts.\nstatic int saved_regions_count = 0;\n\n// Unprocessed inserts (must be big enough to hold all allocations that can\n// be caused by a InsertRegionLocked call).\n// Region has no constructor, so that c-tor execution does not interfere\n// with the any-time use of the static memory behind saved_regions.\nstatic MemoryRegionMap::Region saved_regions[20];\n\ninline void MemoryRegionMap::HandleSavedRegionsLocked(\n              void (*insert_func)(const Region& region)) {\n  while (saved_regions_count > 0) {\n    // Making a local-var copy of the region argument to insert_func\n    // including its stack (w/o doing any memory allocations) is important:\n    // in many cases the memory in saved_regions\n    // will get written-to during the (*insert_func)(r) call below.\n    Region r = saved_regions[--saved_regions_count];\n    (*insert_func)(r);\n  }\n}\n\ninline void MemoryRegionMap::InsertRegionLocked(const Region& region) {\n  RAW_CHECK(LockIsHeld(), \"should be held (by this thread)\");\n  // We can be called recursively, because RegionSet constructor\n  // and DoInsertRegionLocked() (called below) can call the allocator.\n  // recursive_insert tells us if that's the case. When this happens,\n  // region insertion information is recorded in saved_regions[],\n  // and taken into account when the recursion unwinds.\n  // Do the insert:\n  if (recursive_insert) {  // recursion: save in saved_regions\n    RAW_VLOG(12, \"Saving recursive insert of region %p..%p from %p\",\n                reinterpret_cast<void*>(region.start_addr),\n                reinterpret_cast<void*>(region.end_addr),\n                reinterpret_cast<void*>(region.caller()));\n    RAW_CHECK(saved_regions_count < arraysize(saved_regions), \"\");\n    // Copy 'region' to saved_regions[saved_regions_count]\n    // together with the contents of its call_stack,\n    // then increment saved_regions_count.\n    saved_regions[saved_regions_count++] = region;\n  } else {  // not a recusrive call\n    if (regions_ == NULL) {  // init regions_\n      RAW_VLOG(12, \"Initializing region set\");\n      regions_ = regions_rep.region_set();\n      recursive_insert = true;\n      new(regions_) RegionSet();\n      HandleSavedRegionsLocked(&DoInsertRegionLocked);\n      recursive_insert = false;\n    }\n    recursive_insert = true;\n    // Do the actual insertion work to put new regions into regions_:\n    DoInsertRegionLocked(region);\n    HandleSavedRegionsLocked(&DoInsertRegionLocked);\n    recursive_insert = false;\n  }\n}\n\n// We strip out different number of stack frames in debug mode\n// because less inlining happens in that case\n#ifdef NDEBUG\nstatic const int kStripFrames = 1;\n#else\nstatic const int kStripFrames = 3;\n#endif\n\nvoid MemoryRegionMap::RecordRegionAddition(const void* start, size_t size) {\n  // Record start/end info about this memory acquisition call in a new region:\n  Region region;\n  region.Create(start, size);\n  // First get the call stack info into the local varible 'region':\n  const int depth =\n    max_stack_depth_ > 0\n    ? MallocHook::GetCallerStackTrace(const_cast<void**>(region.call_stack),\n                                      max_stack_depth_, kStripFrames + 1)\n    : 0;\n  region.set_call_stack_depth(depth);  // record stack info fully\n  RAW_VLOG(10, \"New global region %p..%p from %p\",\n              reinterpret_cast<void*>(region.start_addr),\n              reinterpret_cast<void*>(region.end_addr),\n              reinterpret_cast<void*>(region.caller()));\n  // Note: none of the above allocates memory.\n  Lock();  // recursively lock\n  InsertRegionLocked(region);\n    // This will (eventually) allocate storage for and copy over the stack data\n    // from region.call_stack_data_ that is pointed by region.call_stack().\n  Unlock();\n}\n\nvoid MemoryRegionMap::RecordRegionRemoval(const void* start, size_t size) {\n  Lock();\n  if (recursive_insert) {\n    // First remove the removed region from saved_regions, if it's\n    // there, to prevent overrunning saved_regions in recursive\n    // map/unmap call sequences, and also from later inserting regions\n    // which have already been unmapped.\n    uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);\n    uintptr_t end_addr = start_addr + size;\n    int put_pos = 0;\n    int old_count = saved_regions_count;\n    for (int i = 0; i < old_count; ++i, ++put_pos) {\n      Region& r = saved_regions[i];\n      if (r.start_addr == start_addr && r.end_addr == end_addr) {\n        // An exact match, so it's safe to remove.\n        --saved_regions_count;\n        --put_pos;\n        RAW_VLOG(10, (\"Insta-Removing saved region %p..%p; \"\n                     \"now have %d saved regions\"),\n                 reinterpret_cast<void*>(start_addr),\n                 reinterpret_cast<void*>(end_addr),\n                 saved_regions_count);\n      } else {\n        if (put_pos < i) {\n          saved_regions[put_pos] = saved_regions[i];\n        }\n      }\n    }\n  }\n  if (regions_ == NULL) {  // We must have just unset the hooks,\n                           // but this thread was already inside the hook.\n    Unlock();\n    return;\n  }\n  if (!recursive_insert) {\n    HandleSavedRegionsLocked(&InsertRegionLocked);\n  }\n    // first handle adding saved regions if any\n  uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);\n  uintptr_t end_addr = start_addr + size;\n  // subtract start_addr, end_addr from all the regions\n  RAW_VLOG(10, \"Removing global region %p..%p; have %\"PRIuS\" regions\",\n              reinterpret_cast<void*>(start_addr),\n              reinterpret_cast<void*>(end_addr),\n              regions_->size());\n  Region sample;\n  sample.SetRegionSetKey(start_addr);\n  // Only iterate over the regions that might overlap start_addr..end_addr:\n  for (RegionSet::iterator region = regions_->lower_bound(sample);\n       region != regions_->end()  &&  region->start_addr < end_addr;\n       /*noop*/) {\n    RAW_VLOG(13, \"Looking at region %p..%p\",\n                reinterpret_cast<void*>(region->start_addr),\n                reinterpret_cast<void*>(region->end_addr));\n    if (start_addr <= region->start_addr  &&\n        region->end_addr <= end_addr) {  // full deletion\n      RAW_VLOG(12, \"Deleting region %p..%p\",\n                  reinterpret_cast<void*>(region->start_addr),\n                  reinterpret_cast<void*>(region->end_addr));\n      RegionSet::iterator d = region;\n      ++region;\n      regions_->erase(d);\n      continue;\n    } else if (region->start_addr < start_addr  &&\n               end_addr < region->end_addr) {  // cutting-out split\n      RAW_VLOG(12, \"Splitting region %p..%p in two\",\n                  reinterpret_cast<void*>(region->start_addr),\n                  reinterpret_cast<void*>(region->end_addr));\n      // Make another region for the start portion:\n      // The new region has to be the start portion because we can't\n      // just modify region->end_addr as it's the sorting key.\n      Region r = *region;\n      r.set_end_addr(start_addr);\n      InsertRegionLocked(r);\n      // cut *region from start:\n      const_cast<Region&>(*region).set_start_addr(end_addr);\n    } else if (end_addr > region->start_addr  &&\n               start_addr <= region->start_addr) {  // cut from start\n      RAW_VLOG(12, \"Start-chopping region %p..%p\",\n                  reinterpret_cast<void*>(region->start_addr),\n                  reinterpret_cast<void*>(region->end_addr));\n      const_cast<Region&>(*region).set_start_addr(end_addr);\n    } else if (start_addr > region->start_addr  &&\n               start_addr < region->end_addr) {  // cut from end\n      RAW_VLOG(12, \"End-chopping region %p..%p\",\n                  reinterpret_cast<void*>(region->start_addr),\n                  reinterpret_cast<void*>(region->end_addr));\n      // Can't just modify region->end_addr (it's the sorting key):\n      Region r = *region;\n      r.set_end_addr(start_addr);\n      RegionSet::iterator d = region;\n      ++region;\n      // It's safe to erase before inserting since r is independent of *d:\n      // r contains an own copy of the call stack:\n      regions_->erase(d);\n      InsertRegionLocked(r);\n      continue;\n    }\n    ++region;\n  }\n  RAW_VLOG(12, \"Removed region %p..%p; have %\"PRIuS\" regions\",\n              reinterpret_cast<void*>(start_addr),\n              reinterpret_cast<void*>(end_addr),\n              regions_->size());\n  if (VLOG_IS_ON(12))  LogAllLocked();\n  Unlock();\n}\n\nvoid MemoryRegionMap::MmapHook(const void* result,\n                               const void* start, size_t size,\n                               int prot, int flags,\n                               int fd, off_t offset) {\n  // TODO(maxim): replace all 0x%\"PRIxS\" by %p when RAW_VLOG uses a safe\n  // snprintf reimplementation that does not malloc to pretty-print NULL\n  RAW_VLOG(10, \"MMap = 0x%\"PRIxPTR\" of %\"PRIuS\" at %llu \"\n              \"prot %d flags %d fd %d offs %lld\",\n              reinterpret_cast<uintptr_t>(result), size,\n              reinterpret_cast<uint64>(start), prot, flags, fd,\n              static_cast<int64>(offset));\n  if (result != reinterpret_cast<void*>(MAP_FAILED)  &&  size != 0) {\n    RecordRegionAddition(result, size);\n  }\n}\n\nvoid MemoryRegionMap::MunmapHook(const void* ptr, size_t size) {\n  RAW_VLOG(10, \"MUnmap of %p %\"PRIuS\"\", ptr, size);\n  if (size != 0) {\n    RecordRegionRemoval(ptr, size);\n  }\n}\n\nvoid MemoryRegionMap::MremapHook(const void* result,\n                                 const void* old_addr, size_t old_size,\n                                 size_t new_size, int flags,\n                                 const void* new_addr) {\n  RAW_VLOG(10, \"MRemap = 0x%\"PRIxPTR\" of 0x%\"PRIxPTR\" %\"PRIuS\" \"\n              \"to %\"PRIuS\" flags %d new_addr=0x%\"PRIxPTR,\n              (uintptr_t)result, (uintptr_t)old_addr,\n               old_size, new_size, flags,\n               flags & MREMAP_FIXED ? (uintptr_t)new_addr : 0);\n  if (result != reinterpret_cast<void*>(-1)) {\n    RecordRegionRemoval(old_addr, old_size);\n    RecordRegionAddition(result, new_size);\n  }\n}\n\nextern \"C\" void* __sbrk(ptrdiff_t increment);  // defined in libc\n\nvoid MemoryRegionMap::SbrkHook(const void* result, ptrdiff_t increment) {\n  RAW_VLOG(10, \"Sbrk = 0x%\"PRIxPTR\" of %\"PRIdS\"\", (uintptr_t)result, increment);\n  if (result != reinterpret_cast<void*>(-1)) {\n    if (increment > 0) {\n      void* new_end = sbrk(0);\n      RecordRegionAddition(result, reinterpret_cast<uintptr_t>(new_end) -\n                                   reinterpret_cast<uintptr_t>(result));\n    } else if (increment < 0) {\n      void* new_end = sbrk(0);\n      RecordRegionRemoval(new_end, reinterpret_cast<uintptr_t>(result) -\n                                   reinterpret_cast<uintptr_t>(new_end));\n    }\n  }\n}\n\nvoid MemoryRegionMap::LogAllLocked() {\n  RAW_CHECK(LockIsHeld(), \"should be held (by this thread)\");\n  RAW_LOG(INFO, \"List of regions:\");\n  uintptr_t previous = 0;\n  for (RegionSet::const_iterator r = regions_->begin();\n       r != regions_->end(); ++r) {\n    RAW_LOG(INFO, \"Memory region 0x%\"PRIxPTR\"..0x%\"PRIxPTR\" \"\n                  \"from 0x%\"PRIxPTR\" stack=%d\",\n                  r->start_addr, r->end_addr, r->caller(), r->is_stack);\n    RAW_CHECK(previous < r->end_addr, \"wow, we messed up the set order\");\n      // this must be caused by uncontrolled recursive operations on regions_\n    previous = r->end_addr;\n  }\n  RAW_LOG(INFO, \"End of regions list\");\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/memory_region_map.h",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Maxim Lifantsev\n */\n\n#ifndef BASE_MEMORY_REGION_MAP_H_\n#define BASE_MEMORY_REGION_MAP_H_\n\n#include <config.h>\n\n#ifdef HAVE_PTHREAD\n#include <pthread.h>\n#endif\n#include <set>\n#include \"base/stl_allocator.h\"\n#include \"base/spinlock.h\"\n#include \"base/thread_annotations.h\"\n#include \"base/low_level_alloc.h\"\n\n// TODO(maxim): add a unittest:\n//  execute a bunch of mmaps and compare memory map what strace logs\n//  execute a bunch of mmap/munmup and compare memory map with\n//  own accounting of what those mmaps generated\n\n// Thread-safe class to collect and query the map of all memory regions\n// in a process that have been created with mmap, munmap, mremap, sbrk.\n// For each memory region, we keep track of (and provide to users)\n// the stack trace that allocated that memory region.\n// The recorded stack trace depth is bounded by\n// a user-supplied max_stack_depth parameter of Init().\n// After initialization with Init()\n// (which can happened even before global object constructor execution)\n// we collect the map by installing and monitoring MallocHook-s\n// to mmap, munmap, mremap, sbrk.\n// At any time one can query this map via provided interface.\n// For more details on the design of MemoryRegionMap\n// see the comment at the top of our .cc file.\nclass MemoryRegionMap {\n private:\n  // Max call stack recording depth supported by Init().  Set it to be\n  // high enough for all our clients.  Note: we do not define storage\n  // for this (doing that requires special handling in windows), so\n  // don't take the address of it!\n  static const int kMaxStackDepth = 32;\n\n public:\n  // interface ================================================================\n\n  // Every client of MemoryRegionMap must call Init() before first use,\n  // and Shutdown() after last use.  This allows us to reference count\n  // this (singleton) class properly.  MemoryRegionMap assumes it's the\n  // only client of MallocHooks, so a client can only register other\n  // MallocHooks after calling Init() and must unregister them before\n  // calling Shutdown().\n\n  // Initialize this module to record memory allocation stack traces.\n  // Stack traces that have more than \"max_stack_depth\" frames\n  // are automatically shrunk to \"max_stack_depth\" when they are recorded.\n  // Init() can be called more than once w/o harm, largest max_stack_depth\n  // will be the effective one.\n  // It will install mmap, munmap, mremap, sbrk hooks\n  // and initialize arena_ and our hook and locks, hence one can use\n  // MemoryRegionMap::Lock()/Unlock() to manage the locks.\n  // Uses Lock/Unlock inside.\n  static void Init(int max_stack_depth);\n\n  // Try to shutdown this module undoing what Init() did.\n  // Returns true iff could do full shutdown (or it was not attempted).\n  // Full shutdown is attempted when the number of Shutdown() calls equals\n  // the number of Init() calls.\n  static bool Shutdown();\n\n  // Check that our hooks are still in place and crash if not.\n  // No need for locking.\n  static void CheckMallocHooks();\n\n  // Locks to protect our internal data structures.\n  // These also protect use of arena_ if our Init() has been done.\n  // The lock is recursive.\n  static void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_);\n  static void Unlock() UNLOCK_FUNCTION(lock_);\n\n  // Returns true when the lock is held by this thread (for use in RAW_CHECK-s).\n  static bool LockIsHeld();\n\n  // Locker object that acquires the MemoryRegionMap::Lock\n  // for the duration of its lifetime (a C++ scope).\n  class LockHolder {\n   public:\n    LockHolder() { Lock(); }\n    ~LockHolder() { Unlock(); }\n   private:\n    DISALLOW_COPY_AND_ASSIGN(LockHolder);\n  };\n\n  // A memory region that we know about through malloc_hook-s.\n  // This is essentially an interface through which MemoryRegionMap\n  // exports the collected data to its clients.  Thread-compatible.\n  struct Region {\n    uintptr_t start_addr;  // region start address\n    uintptr_t end_addr;  // region end address\n    int call_stack_depth;  // number of caller stack frames that we saved\n    const void* call_stack[kMaxStackDepth];  // caller address stack array\n                                             // filled to call_stack_depth size\n    bool is_stack;  // does this region contain a thread's stack:\n                    // a user of MemoryRegionMap supplies this info\n\n    // Convenience accessor for call_stack[0],\n    // i.e. (the program counter of) the immediate caller\n    // of this region's allocation function,\n    // but it also returns NULL when call_stack_depth is 0,\n    // i.e whe we weren't able to get the call stack.\n    // This usually happens in recursive calls, when the stack-unwinder\n    // calls mmap() which in turn calls the stack-unwinder.\n    uintptr_t caller() const {\n      return reinterpret_cast<uintptr_t>(call_stack_depth >= 1\n                                         ? call_stack[0] : NULL);\n    }\n\n    // Return true iff this region overlaps region x.\n    bool Overlaps(const Region& x) const {\n      return start_addr < x.end_addr  &&  end_addr > x.start_addr;\n    }\n\n   private:  // helpers for MemoryRegionMap\n    friend class MemoryRegionMap;\n\n    // The ways we create Region-s:\n    void Create(const void* start, size_t size) {\n      start_addr = reinterpret_cast<uintptr_t>(start);\n      end_addr = start_addr + size;\n      is_stack = false;  // not a stack till marked such\n      call_stack_depth = 0;\n      AssertIsConsistent();\n    }\n    void set_call_stack_depth(int depth) {\n      RAW_DCHECK(call_stack_depth == 0, \"\");  // only one such set is allowed\n      call_stack_depth = depth;\n      AssertIsConsistent();\n    }\n\n    // The ways we modify Region-s:\n    void set_is_stack() { is_stack = true; }\n    void set_start_addr(uintptr_t addr) {\n      start_addr = addr;\n      AssertIsConsistent();\n    }\n    void set_end_addr(uintptr_t addr) {\n      end_addr = addr;\n      AssertIsConsistent();\n    }\n\n    // Verifies that *this contains consistent data, crashes if not the case.\n    void AssertIsConsistent() const {\n      RAW_DCHECK(start_addr < end_addr, \"\");\n      RAW_DCHECK(call_stack_depth >= 0  &&\n                 call_stack_depth <= kMaxStackDepth, \"\");\n    }\n\n    // Post-default construction helper to make a Region suitable\n    // for searching in RegionSet regions_.\n    void SetRegionSetKey(uintptr_t addr) {\n      // make sure *this has no usable data:\n      if (DEBUG_MODE) memset(this, 0xFF, sizeof(*this));\n      end_addr = addr;\n    }\n\n    // Note: call_stack[kMaxStackDepth] as a member lets us make Region\n    // a simple self-contained struct with correctly behaving bit-vise copying.\n    // This simplifies the code of this module but wastes some memory:\n    // in most-often use case of this module (leak checking)\n    // only one call_stack element out of kMaxStackDepth is actually needed.\n    // Making the storage for call_stack variable-sized,\n    // substantially complicates memory management for the Region-s:\n    // as they need to be created and manipulated for some time\n    // w/o any memory allocations, yet are also given out to the users.\n  };\n\n  // Find the region that covers addr and write its data into *result if found,\n  // in which case *result gets filled so that it stays fully functional\n  // even when the underlying region gets removed from MemoryRegionMap.\n  // Returns success. Uses Lock/Unlock inside.\n  static bool FindRegion(uintptr_t addr, Region* result);\n\n  // Find the region that contains stack_top, mark that region as\n  // a stack region, and write its data into *result if found,\n  // in which case *result gets filled so that it stays fully functional\n  // even when the underlying region gets removed from MemoryRegionMap.\n  // Returns success. Uses Lock/Unlock inside.\n  static bool FindAndMarkStackRegion(uintptr_t stack_top, Region* result);\n\n private:  // our internal types ==============================================\n\n  // Region comparator for sorting with STL\n  struct RegionCmp {\n    bool operator()(const Region& x, const Region& y) const {\n      return x.end_addr < y.end_addr;\n    }\n  };\n\n  // We allocate STL objects in our own arena.\n  struct MyAllocator {\n    static void *Allocate(size_t n) {\n      return LowLevelAlloc::AllocWithArena(n, arena_);\n    }\n    static void Free(const void *p, size_t /* n */) {\n      LowLevelAlloc::Free(const_cast<void*>(p));\n    }\n  };\n\n  // Set of the memory regions\n  typedef std::set<Region, RegionCmp,\n              STL_Allocator<Region, MyAllocator> > RegionSet;\n\n public:  // more in-depth interface ==========================================\n\n  // STL iterator with values of Region\n  typedef RegionSet::const_iterator RegionIterator;\n\n  // Return the begin/end iterators to all the regions.\n  // These need Lock/Unlock protection around their whole usage (loop).\n  // Even when the same thread causes modifications during such a loop\n  // (which are permitted due to recursive locking)\n  // the loop iterator will still be valid as long as its region\n  // has not been deleted, but EndRegionLocked should be\n  // re-evaluated whenever the set of regions has changed.\n  static RegionIterator BeginRegionLocked();\n  static RegionIterator EndRegionLocked();\n\n  // Effectively private type from our .cc =================================\n  // public to let us declare global objects:\n  union RegionSetRep;\n\n private:\n\n  // representation ===========================================================\n\n  // Counter of clients of this module that have called Init().\n  static int client_count_;\n\n  // Maximal number of caller stack frames to save (>= 0).\n  static int max_stack_depth_;\n\n  // Arena used for our allocations in regions_.\n  static LowLevelAlloc::Arena* arena_;\n\n  // Set of the mmap/sbrk/mremap-ed memory regions\n  // To be accessed *only* when Lock() is held.\n  // Hence we protect the non-recursive lock used inside of arena_\n  // with our recursive Lock(). This lets a user prevent deadlocks\n  // when threads are stopped by ListAllProcessThreads at random spots\n  // simply by acquiring our recursive Lock() before that.\n  static RegionSet* regions_;\n\n  // Lock to protect regions_ variable and the data behind.\n  static SpinLock lock_;\n  // Lock to protect the recursive lock itself.\n  static SpinLock owner_lock_;\n\n  // Recursion count for the recursive lock.\n  static int recursion_count_;\n  // The thread id of the thread that's inside the recursive lock.\n  static pthread_t lock_owner_tid_;\n\n  // helpers ==================================================================\n\n  // Helper for FindRegion and FindAndMarkStackRegion:\n  // returns the region covering 'addr' or NULL; assumes our lock_ is held.\n  static const Region* DoFindRegionLocked(uintptr_t addr);\n\n  // Verifying wrapper around regions_->insert(region)\n  // To be called to do InsertRegionLocked's work only!\n  inline static void DoInsertRegionLocked(const Region& region);\n  // Handle regions saved by InsertRegionLocked into a tmp static array\n  // by calling insert_func on them.\n  inline static void HandleSavedRegionsLocked(\n                       void (*insert_func)(const Region& region));\n  // Wrapper around DoInsertRegionLocked\n  // that handles the case of recursive allocator calls.\n  inline static void InsertRegionLocked(const Region& region);\n\n  // Record addition of a memory region at address \"start\" of size \"size\"\n  // (called from our mmap/mremap/sbrk hooks).\n  static void RecordRegionAddition(const void* start, size_t size);\n  // Record deletion of a memory region at address \"start\" of size \"size\"\n  // (called from our munmap/mremap/sbrk hooks).\n  static void RecordRegionRemoval(const void* start, size_t size);\n\n  // Hooks for MallocHook\n  static void MmapHook(const void* result,\n                       const void* start, size_t size,\n                       int prot, int flags,\n                       int fd, off_t offset);\n  static void MunmapHook(const void* ptr, size_t size);\n  static void MremapHook(const void* result, const void* old_addr,\n                         size_t old_size, size_t new_size, int flags,\n                         const void* new_addr);\n  static void SbrkHook(const void* result, ptrdiff_t increment);\n\n  // Log all memory regions; Useful for debugging only.\n  // Assumes Lock() is held\n  static void LogAllLocked();\n\n  DISALLOW_COPY_AND_ASSIGN(MemoryRegionMap);\n};\n\n#endif  // BASE_MEMORY_REGION_MAP_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/packed-cache-inl.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Geoff Pike\n//\n// This file provides a minimal cache that can hold a <key, value> pair\n// with little if any wasted space.  The types of the key and value\n// must be unsigned integral types or at least have unsigned semantics\n// for >>, casting, and similar operations.\n//\n// Synchronization is not provided.  However, the cache is implemented\n// as an array of cache entries whose type is chosen at compile time.\n// If a[i] is atomic on your hardware for the chosen array type then\n// raciness will not necessarily lead to bugginess.  The cache entries\n// must be large enough to hold a partial key and a value packed\n// together.  The partial keys are bit strings of length\n// kKeybits - kHashbits, and the values are bit strings of length kValuebits.\n//\n// In an effort to use minimal space, every cache entry represents\n// some <key, value> pair; the class provides no way to mark a cache\n// entry as empty or uninitialized.  In practice, you may want to have\n// reserved keys or values to get around this limitation.  For example, in\n// tcmalloc's PageID-to-sizeclass cache, a value of 0 is used as\n// \"unknown sizeclass.\"\n//\n// Usage Considerations\n// --------------------\n//\n// kHashbits controls the size of the cache.  The best value for\n// kHashbits will of course depend on the application.  Perhaps try\n// tuning the value of kHashbits by measuring different values on your\n// favorite benchmark.  Also remember not to be a pig; other\n// programs that need resources may suffer if you are.\n//\n// The main uses for this class will be when performance is\n// critical and there's a convenient type to hold the cache's\n// entries.  As described above, the number of bits required\n// for a cache entry is (kKeybits - kHashbits) + kValuebits.  Suppose\n// kKeybits + kValuebits is 43.  Then it probably makes sense to\n// chose kHashbits >= 11 so that cache entries fit in a uint32.\n//\n// On the other hand, suppose kKeybits = kValuebits = 64.  Then\n// using this class may be less worthwhile.  You'll probably\n// be using 128 bits for each entry anyway, so maybe just pick\n// a hash function, H, and use an array indexed by H(key):\n//    void Put(K key, V value) { a_[H(key)] = pair<K, V>(key, value); }\n//    V GetOrDefault(K key, V default) { const pair<K, V> &p = a_[H(key)]; ... }\n//    etc.\n//\n// Further Details\n// ---------------\n//\n// For caches used only by one thread, the following is true:\n// 1. For a cache c,\n//      (c.Put(key, value), c.GetOrDefault(key, 0)) == value\n//    and\n//      (c.Put(key, value), <...>, c.GetOrDefault(key, 0)) == value\n//    if the elided code contains no c.Put calls.\n//\n// 2. Has(key) will return false if no <key, value> pair with that key\n//    has ever been Put.  However, a newly initialized cache will have\n//    some <key, value> pairs already present.  When you create a new\n//    cache, you must specify an \"initial value.\"  The initialization\n//    procedure is equivalent to Clear(initial_value), which is\n//    equivalent to Put(k, initial_value) for all keys k from 0 to\n//    2^kHashbits - 1.\n//\n// 3. If key and key' differ then the only way Put(key, value) may\n//    cause Has(key') to change is that Has(key') may change from true to\n//    false. Furthermore, a Put() call that doesn't change Has(key')\n//    doesn't change GetOrDefault(key', ...) either.\n//\n// Implementation details:\n//\n// This is a direct-mapped cache with 2^kHashbits entries; the hash\n// function simply takes the low bits of the key.  We store whole keys\n// if a whole key plus a whole value fits in an entry.  Otherwise, an\n// entry is the high bits of a key and a value, packed together.\n// E.g., a 20 bit key and a 7 bit value only require a uint16 for each\n// entry if kHashbits >= 11.\n//\n// Alternatives to this scheme will be added as needed.\n\n#ifndef TCMALLOC_PACKED_CACHE_INL_H_\n#define TCMALLOC_PACKED_CACHE_INL_H_\n\n#include \"config.h\"\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n#include \"base/basictypes.h\"  // for COMPILE_ASSERT\n#include \"internal_logging.h\"\n\n// A safe way of doing \"(1 << n) - 1\" -- without worrying about overflow\n// Note this will all be resolved to a constant expression at compile-time\n#define N_ONES_(IntType, N)                                     \\\n  ( (N) == 0 ? 0 : ((static_cast<IntType>(1) << ((N)-1))-1 +    \\\n                    (static_cast<IntType>(1) << ((N)-1))) )\n\n// The types K and V provide upper bounds on the number of valid keys\n// and values, but we explicitly require the keys to be less than\n// 2^kKeybits and the values to be less than 2^kValuebits.  The size of\n// the table is controlled by kHashbits, and the type of each entry in\n// the cache is T.  See also the big comment at the top of the file.\ntemplate <int kKeybits, typename T>\nclass PackedCache {\n public:\n  typedef uintptr_t K;\n  typedef size_t V;\n  static const int kHashbits = 12;\n  static const int kValuebits = 7;\n  static const bool kUseWholeKeys = kKeybits + kValuebits <= 8 * sizeof(T);\n\n  explicit PackedCache(V initial_value) {\n    COMPILE_ASSERT(kKeybits <= sizeof(K) * 8, key_size);\n    COMPILE_ASSERT(kValuebits <= sizeof(V) * 8, value_size);\n    COMPILE_ASSERT(kHashbits <= kKeybits, hash_function);\n    COMPILE_ASSERT(kKeybits - kHashbits + kValuebits <= kTbits,\n                   entry_size_must_be_big_enough);\n    Clear(initial_value);\n  }\n\n  void Put(K key, V value) {\n    ASSERT(key == (key & kKeyMask));\n    ASSERT(value == (value & kValueMask));\n    array_[Hash(key)] = KeyToUpper(key) | value;\n  }\n\n  bool Has(K key) const {\n    ASSERT(key == (key & kKeyMask));\n    return KeyMatch(array_[Hash(key)], key);\n  }\n\n  V GetOrDefault(K key, V default_value) const {\n    // As with other code in this class, we touch array_ as few times\n    // as we can.  Assuming entries are read atomically (e.g., their\n    // type is uintptr_t on most hardware) then certain races are\n    // harmless.\n    ASSERT(key == (key & kKeyMask));\n    T entry = array_[Hash(key)];\n    return KeyMatch(entry, key) ? EntryToValue(entry) : default_value;\n  }\n\n  void Clear(V value) {\n    ASSERT(value == (value & kValueMask));\n    for (int i = 0; i < 1 << kHashbits; i++) {\n      ASSERT(kUseWholeKeys || KeyToUpper(i) == 0);\n      array_[i] = kUseWholeKeys ? (value | KeyToUpper(i)) : value;\n    }\n  }\n\n private:\n  // We are going to pack a value and the upper part of a key (or a\n  // whole key) into an entry of type T.  The UPPER type is for the\n  // upper part of a key, after the key has been masked and shifted\n  // for inclusion in an entry.\n  typedef T UPPER;\n\n  static V EntryToValue(T t) { return t & kValueMask; }\n\n  // If we have space for a whole key, we just shift it left.\n  // Otherwise kHashbits determines where in a K to find the upper\n  // part of the key, and kValuebits determines where in the entry to\n  // put it.\n  static UPPER KeyToUpper(K k) {\n    if (kUseWholeKeys) {\n      return static_cast<T>(k) << kValuebits;\n    } else {\n      const int shift = kHashbits - kValuebits;\n      // Assume kHashbits >= kValuebits.  It'd be easy to lift this assumption.\n      return static_cast<T>(k >> shift) & kUpperMask;\n    }\n  }\n\n  static size_t Hash(K key) {\n    return static_cast<size_t>(key) & N_ONES_(size_t, kHashbits);\n  }\n\n  // Does the entry match the relevant part of the given key?\n  static bool KeyMatch(T entry, K key) {\n    return kUseWholeKeys ?\n        (entry >> kValuebits == key) :\n        ((KeyToUpper(key) ^ entry) & kUpperMask) == 0;\n  }\n\n  static const int kTbits = 8 * sizeof(T);\n  static const int kUpperbits = kUseWholeKeys ? kKeybits : kKeybits - kHashbits;\n\n  // For masking a K.\n  static const K kKeyMask = N_ONES_(K, kKeybits);\n\n  // For masking a T.\n  static const T kUpperMask = N_ONES_(T, kUpperbits) << kValuebits;\n\n  // For masking a V or a T.\n  static const V kValueMask = N_ONES_(V, kValuebits);\n\n  // array_ is the cache.  Its elements are volatile because any\n  // thread can write any array element at any time.\n  volatile T array_[1 << kHashbits];\n};\n\n#undef N_ONES_\n\n#endif  // TCMALLOC_PACKED_CACHE_INL_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/page_heap.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#include <config.h>\n#include \"page_heap.h\"\n\n#include \"static_vars.h\"\n#include \"system-alloc.h\"\n\nDEFINE_double(tcmalloc_release_rate,\n              EnvToDouble(\"TCMALLOC_RELEASE_RATE\", 1.0),\n              \"Rate at which we release unused memory to the system.  \"\n              \"Zero means we never release memory back to the system.  \"\n              \"Increase this flag to return memory faster; decrease it \"\n              \"to return memory slower.  Reasonable rates are in the \"\n              \"range [0,10]\");\n\nnamespace tcmalloc {\n\nPageHeap::PageHeap()\n    : pagemap_(MetaDataAlloc),\n      pagemap_cache_(0),\n      scavenge_counter_(0),\n      // Start scavenging at kMaxPages list\n      release_index_(kMaxPages) {\n  COMPILE_ASSERT(kNumClasses <= (1 << PageMapCache::kValuebits), valuebits);\n  DLL_Init(&large_.normal);\n  DLL_Init(&large_.returned);\n  for (int i = 0; i < kMaxPages; i++) {\n    DLL_Init(&free_[i].normal);\n    DLL_Init(&free_[i].returned);\n  }\n}\n\nSpan* PageHeap::SearchFreeAndLargeLists(Length n) {\n  ASSERT(Check());\n  ASSERT(n > 0);\n\n  // Find first size >= n that has a non-empty list\n  for (Length s = n; s < kMaxPages; s++) {\n    Span* ll = &free_[s].normal;\n    // If we're lucky, ll is non-empty, meaning it has a suitable span.\n    if (!DLL_IsEmpty(ll)) {\n      ASSERT(ll->next->location == Span::ON_NORMAL_FREELIST);\n      return Carve(ll->next, n);\n    }\n    // Alternatively, maybe there's a usable returned span.\n    ll = &free_[s].returned;\n    if (!DLL_IsEmpty(ll)) {\n      ASSERT(ll->next->location == Span::ON_RETURNED_FREELIST);\n      return Carve(ll->next, n);\n    }\n  }\n  // No luck in free lists, our last chance is in a larger class.\n  return AllocLarge(n);  // May be NULL\n}\n\nSpan* PageHeap::New(Length n) {\n  ASSERT(Check());\n  ASSERT(n > 0);\n\n  Span* result = SearchFreeAndLargeLists(n);\n  if (result != NULL)\n    return result;\n\n  // Grow the heap and try again.\n  if (!GrowHeap(n)) {\n    ASSERT(Check());\n    return NULL;\n  }\n  return SearchFreeAndLargeLists(n);\n}\n\nSpan* PageHeap::AllocLarge(Length n) {\n  // find the best span (closest to n in size).\n  // The following loops implements address-ordered best-fit.\n  Span *best = NULL;\n\n  // Search through normal list\n  for (Span* span = large_.normal.next;\n       span != &large_.normal;\n       span = span->next) {\n    if (span->length >= n) {\n      if ((best == NULL)\n          || (span->length < best->length)\n          || ((span->length == best->length) && (span->start < best->start))) {\n        best = span;\n        ASSERT(best->location == Span::ON_NORMAL_FREELIST);\n      }\n    }\n  }\n\n  // Search through released list in case it has a better fit\n  for (Span* span = large_.returned.next;\n       span != &large_.returned;\n       span = span->next) {\n    if (span->length >= n) {\n      if ((best == NULL)\n          || (span->length < best->length)\n          || ((span->length == best->length) && (span->start < best->start))) {\n        best = span;\n        ASSERT(best->location == Span::ON_RETURNED_FREELIST);\n      }\n    }\n  }\n\n  return best == NULL ? NULL : Carve(best, n);\n}\n\nSpan* PageHeap::Split(Span* span, Length n) {\n  ASSERT(0 < n);\n  ASSERT(n < span->length);\n  ASSERT(span->location == Span::IN_USE);\n  ASSERT(span->sizeclass == 0);\n  Event(span, 'T', n);\n\n  const int extra = span->length - n;\n  Span* leftover = NewSpan(span->start + n, extra);\n  ASSERT(leftover->location == Span::IN_USE);\n  Event(leftover, 'U', extra);\n  RecordSpan(leftover);\n  pagemap_.set(span->start + n - 1, span); // Update map from pageid to span\n  span->length = n;\n\n  return leftover;\n}\n\nSpan* PageHeap::Carve(Span* span, Length n) {\n  ASSERT(n > 0);\n  ASSERT(span->location != Span::IN_USE);\n  const int old_location = span->location;\n  RemoveFromFreeList(span);\n  span->location = Span::IN_USE;\n  Event(span, 'A', n);\n\n  const int extra = span->length - n;\n  ASSERT(extra >= 0);\n  if (extra > 0) {\n    Span* leftover = NewSpan(span->start + n, extra);\n    leftover->location = old_location;\n    Event(leftover, 'S', extra);\n    RecordSpan(leftover);\n    PrependToFreeList(leftover);  // Skip coalescing - no candidates possible\n    span->length = n;\n    pagemap_.set(span->start + n - 1, span);\n  }\n  ASSERT(Check());\n  return span;\n}\n\nvoid PageHeap::Delete(Span* span) {\n  ASSERT(Check());\n  ASSERT(span->location == Span::IN_USE);\n  ASSERT(span->length > 0);\n  ASSERT(GetDescriptor(span->start) == span);\n  ASSERT(GetDescriptor(span->start + span->length - 1) == span);\n  const Length n = span->length;\n  span->sizeclass = 0;\n  span->sample = 0;\n  span->location = Span::ON_NORMAL_FREELIST;\n  Event(span, 'D', span->length);\n  MergeIntoFreeList(span);  // Coalesces if possible\n  IncrementalScavenge(n);\n  ASSERT(Check());\n}\n\nvoid PageHeap::MergeIntoFreeList(Span* span) {\n  ASSERT(span->location != Span::IN_USE);\n\n  // Coalesce -- we guarantee that \"p\" != 0, so no bounds checking\n  // necessary.  We do not bother resetting the stale pagemap\n  // entries for the pieces we are merging together because we only\n  // care about the pagemap entries for the boundaries.\n  //\n  // Note that only similar spans are merged together.  For example,\n  // we do not coalesce \"returned\" spans with \"normal\" spans.\n  const PageID p = span->start;\n  const Length n = span->length;\n  Span* prev = GetDescriptor(p-1);\n  if (prev != NULL && prev->location == span->location) {\n    // Merge preceding span into this span\n    ASSERT(prev->start + prev->length == p);\n    const Length len = prev->length;\n    RemoveFromFreeList(prev);\n    DeleteSpan(prev);\n    span->start -= len;\n    span->length += len;\n    pagemap_.set(span->start, span);\n    Event(span, 'L', len);\n  }\n  Span* next = GetDescriptor(p+n);\n  if (next != NULL && next->location == span->location) {\n    // Merge next span into this span\n    ASSERT(next->start == p+n);\n    const Length len = next->length;\n    RemoveFromFreeList(next);\n    DeleteSpan(next);\n    span->length += len;\n    pagemap_.set(span->start + span->length - 1, span);\n    Event(span, 'R', len);\n  }\n\n  PrependToFreeList(span);\n}\n\nvoid PageHeap::PrependToFreeList(Span* span) {\n  ASSERT(span->location != Span::IN_USE);\n  SpanList* list = (span->length < kMaxPages) ? &free_[span->length] : &large_;\n  if (span->location == Span::ON_NORMAL_FREELIST) {\n    stats_.free_bytes += (span->length << kPageShift);\n    DLL_Prepend(&list->normal, span);\n  } else {\n    stats_.unmapped_bytes += (span->length << kPageShift);\n    DLL_Prepend(&list->returned, span);\n  }\n}\n\nvoid PageHeap::RemoveFromFreeList(Span* span) {\n  ASSERT(span->location != Span::IN_USE);\n  if (span->location == Span::ON_NORMAL_FREELIST) {\n    stats_.free_bytes -= (span->length << kPageShift);\n  } else {\n    stats_.unmapped_bytes -= (span->length << kPageShift);\n  }\n  DLL_Remove(span);\n}\n\nvoid PageHeap::IncrementalScavenge(Length n) {\n  // Fast path; not yet time to release memory\n  scavenge_counter_ -= n;\n  if (scavenge_counter_ >= 0) return;  // Not yet time to scavenge\n\n  const double rate = FLAGS_tcmalloc_release_rate;\n  if (rate <= 1e-6) {\n    // Tiny release rate means that releasing is disabled.\n    scavenge_counter_ = kDefaultReleaseDelay;\n    return;\n  }\n\n  Length released_pages = ReleaseAtLeastNPages(1);\n\n  if (released_pages == 0) {\n    // Nothing to scavenge, delay for a while.\n    scavenge_counter_ = kDefaultReleaseDelay;\n  } else {\n    // Compute how long to wait until we return memory.\n    // FLAGS_tcmalloc_release_rate==1 means wait for 1000 pages\n    // after releasing one page.\n    const double mult = 1000.0 / rate;\n    double wait = mult * static_cast<double>(released_pages);\n    if (wait > kMaxReleaseDelay) {\n      // Avoid overflow and bound to reasonable range.\n      wait = kMaxReleaseDelay;\n    }\n    scavenge_counter_ = static_cast<int64_t>(wait);\n  }\n}\n\nLength PageHeap::ReleaseLastNormalSpan(SpanList* slist) {\n  Span* s = slist->normal.prev;\n  ASSERT(s->location == Span::ON_NORMAL_FREELIST);\n  RemoveFromFreeList(s);\n  const Length n = s->length;\n  TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),\n                         static_cast<size_t>(s->length << kPageShift));\n  s->location = Span::ON_RETURNED_FREELIST;\n  MergeIntoFreeList(s);  // Coalesces if possible.\n  return n;\n}\n\nLength PageHeap::ReleaseAtLeastNPages(Length num_pages) {\n  Length released_pages = 0;\n  Length prev_released_pages = -1;\n\n  // Round robin through the lists of free spans, releasing the last\n  // span in each list.  Stop after releasing at least num_pages.\n  while (released_pages < num_pages) {\n    if (released_pages == prev_released_pages) {\n      // Last iteration of while loop made no progress.\n      break;\n    }\n    prev_released_pages = released_pages;\n\n    for (int i = 0; i < kMaxPages+1 && released_pages < num_pages;\n         i++, release_index_++) {\n      if (release_index_ > kMaxPages) release_index_ = 0;\n      SpanList* slist = (release_index_ == kMaxPages) ?\n          &large_ : &free_[release_index_];\n      if (!DLL_IsEmpty(&slist->normal)) {\n        Length released_len = ReleaseLastNormalSpan(slist);\n        released_pages += released_len;\n      }\n    }\n  }\n  return released_pages;\n}\n\nvoid PageHeap::RegisterSizeClass(Span* span, size_t sc) {\n  // Associate span object with all interior pages as well\n  ASSERT(span->location == Span::IN_USE);\n  ASSERT(GetDescriptor(span->start) == span);\n  ASSERT(GetDescriptor(span->start+span->length-1) == span);\n  Event(span, 'C', sc);\n  span->sizeclass = sc;\n  for (Length i = 1; i < span->length-1; i++) {\n    pagemap_.set(span->start+i, span);\n  }\n}\n\nstatic double MB(uint64_t bytes) {\n  return bytes / 1048576.0;\n}\n\nstatic double PagesToMB(uint64_t pages) {\n  return (pages << kPageShift) / 1048576.0;\n}\n\nvoid PageHeap::GetClassSizes(int64 class_sizes_normal[kMaxPages],\n                             int64 class_sizes_returned[kMaxPages],\n                             int64* normal_pages_in_spans,\n                             int64* returned_pages_in_spans) {\n\n  for (int s = 0; s < kMaxPages; s++) {\n    if (class_sizes_normal != NULL) {\n      class_sizes_normal[s] = DLL_Length(&free_[s].normal);\n    }\n    if (class_sizes_returned != NULL) {\n      class_sizes_returned[s] = DLL_Length(&free_[s].returned);\n    }\n  }\n\n  if (normal_pages_in_spans != NULL) {\n    *normal_pages_in_spans = 0;\n    for (Span* s = large_.normal.next; s != &large_.normal; s = s->next) {\n      *normal_pages_in_spans += s->length;;\n    }\n  }\n\n  if (returned_pages_in_spans != NULL) {\n    *returned_pages_in_spans = 0;\n    for (Span* s = large_.returned.next; s != &large_.returned; s = s->next) {\n      *returned_pages_in_spans += s->length;\n    }\n  }\n}\n\nvoid PageHeap::Dump(TCMalloc_Printer* out) {\n  int nonempty_sizes = 0;\n  for (int s = 0; s < kMaxPages; s++) {\n    if (!DLL_IsEmpty(&free_[s].normal) || !DLL_IsEmpty(&free_[s].returned)) {\n      nonempty_sizes++;\n    }\n  }\n  out->printf(\"------------------------------------------------\\n\");\n  out->printf(\"PageHeap: %d sizes; %6.1f MB free; %6.1f MB unmapped\\n\",\n              nonempty_sizes, MB(stats_.free_bytes), MB(stats_.unmapped_bytes));\n  out->printf(\"------------------------------------------------\\n\");\n  uint64_t total_normal = 0;\n  uint64_t total_returned = 0;\n  for (int s = 0; s < kMaxPages; s++) {\n    const int n_length = DLL_Length(&free_[s].normal);\n    const int r_length = DLL_Length(&free_[s].returned);\n    if (n_length + r_length > 0) {\n      uint64_t n_pages = s * n_length;\n      uint64_t r_pages = s * r_length;\n      total_normal += n_pages;\n      total_returned += r_pages;\n      out->printf(\"%6u pages * %6u spans ~ %6.1f MB; %6.1f MB cum\"\n                  \"; unmapped: %6.1f MB; %6.1f MB cum\\n\",\n                  s,\n                  (n_length + r_length),\n                  PagesToMB(n_pages + r_pages),\n                  PagesToMB(total_normal + total_returned),\n                  PagesToMB(r_pages),\n                  PagesToMB(total_returned));\n    }\n  }\n\n  uint64_t n_pages = 0;\n  uint64_t r_pages = 0;\n  int n_spans = 0;\n  int r_spans = 0;\n  out->printf(\"Normal large spans:\\n\");\n  for (Span* s = large_.normal.next; s != &large_.normal; s = s->next) {\n    out->printf(\"   [ %6\" PRIuPTR \" pages ] %6.1f MB\\n\",\n                s->length, PagesToMB(s->length));\n    n_pages += s->length;\n    n_spans++;\n  }\n  out->printf(\"Unmapped large spans:\\n\");\n  for (Span* s = large_.returned.next; s != &large_.returned; s = s->next) {\n    out->printf(\"   [ %6\" PRIuPTR \" pages ] %6.1f MB\\n\",\n                s->length, PagesToMB(s->length));\n    r_pages += s->length;\n    r_spans++;\n  }\n  total_normal += n_pages;\n  total_returned += r_pages;\n  out->printf(\">255   large * %6u spans ~ %6.1f MB; %6.1f MB cum\"\n              \"; unmapped: %6.1f MB; %6.1f MB cum\\n\",\n              (n_spans + r_spans),\n              PagesToMB(n_pages + r_pages),\n              PagesToMB(total_normal + total_returned),\n              PagesToMB(r_pages),\n              PagesToMB(total_returned));\n}\n\nbool PageHeap::GetNextRange(PageID start, base::MallocRange* r) {\n  Span* span = reinterpret_cast<Span*>(pagemap_.Next(start));\n  if (span == NULL) {\n    return false;\n  }\n  r->address = span->start << kPageShift;\n  r->length = span->length << kPageShift;\n  r->fraction = 0;\n  switch (span->location) {\n    case Span::IN_USE:\n      r->type = base::MallocRange::INUSE;\n      r->fraction = 1;\n      if (span->sizeclass > 0) {\n        // Only some of the objects in this span may be in use.\n        const size_t osize = Static::sizemap()->class_to_size(span->sizeclass);\n        r->fraction = (1.0 * osize * span->refcount) / r->length;\n      }\n      break;\n    case Span::ON_NORMAL_FREELIST:\n      r->type = base::MallocRange::FREE;\n      break;\n    case Span::ON_RETURNED_FREELIST:\n      r->type = base::MallocRange::UNMAPPED;\n      break;\n    default:\n      r->type = base::MallocRange::UNKNOWN;\n      break;\n  }\n  return true;\n}\n\nstatic void RecordGrowth(size_t growth) {\n  StackTrace* t = Static::stacktrace_allocator()->New();\n  t->depth = GetStackTrace(t->stack, kMaxStackDepth-1, 3);\n  t->size = growth;\n  t->stack[kMaxStackDepth-1] = reinterpret_cast<void*>(Static::growth_stacks());\n  Static::set_growth_stacks(t);\n}\n\nbool PageHeap::GrowHeap(Length n) {\n  ASSERT(kMaxPages >= kMinSystemAlloc);\n  if (n > kMaxValidPages) return false;\n  Length ask = (n>kMinSystemAlloc) ? n : static_cast<Length>(kMinSystemAlloc);\n  size_t actual_size;\n  void* ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize);\n  if (ptr == NULL) {\n    if (n < ask) {\n      // Try growing just \"n\" pages\n      ask = n;\n      ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize);\n    }\n    if (ptr == NULL) return false;\n  }\n  ask = actual_size >> kPageShift;\n  RecordGrowth(ask << kPageShift);\n\n  uint64_t old_system_bytes = stats_.system_bytes;\n  stats_.system_bytes += (ask << kPageShift);\n  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;\n  ASSERT(p > 0);\n\n  // If we have already a lot of pages allocated, just pre allocate a bunch of\n  // memory for the page map. This prevents fragmentation by pagemap metadata\n  // when a program keeps allocating and freeing large blocks.\n\n  if (old_system_bytes < kPageMapBigAllocationThreshold\n      && stats_.system_bytes >= kPageMapBigAllocationThreshold) {\n    pagemap_.PreallocateMoreMemory();\n  }\n\n  // Make sure pagemap_ has entries for all of the new pages.\n  // Plus ensure one before and one after so coalescing code\n  // does not need bounds-checking.\n  if (pagemap_.Ensure(p-1, ask+2)) {\n    // Pretend the new area is allocated and then Delete() it to cause\n    // any necessary coalescing to occur.\n    Span* span = NewSpan(p, ask);\n    RecordSpan(span);\n    Delete(span);\n    ASSERT(Check());\n    return true;\n  } else {\n    // We could not allocate memory within \"pagemap_\"\n    // TODO: Once we can return memory to the system, return the new span\n    return false;\n  }\n}\n\nbool PageHeap::Check() {\n  ASSERT(free_[0].normal.next == &free_[0].normal);\n  ASSERT(free_[0].returned.next == &free_[0].returned);\n  return true;\n}\n\nbool PageHeap::CheckExpensive() {\n  bool result = Check();\n  CheckList(&large_.normal, kMaxPages, 1000000000, Span::ON_NORMAL_FREELIST);\n  CheckList(&large_.returned, kMaxPages, 1000000000, Span::ON_RETURNED_FREELIST);\n  for (Length s = 1; s < kMaxPages; s++) {\n    CheckList(&free_[s].normal, s, s, Span::ON_NORMAL_FREELIST);\n    CheckList(&free_[s].returned, s, s, Span::ON_RETURNED_FREELIST);\n  }\n  return result;\n}\n\nbool PageHeap::CheckList(Span* list, Length min_pages, Length max_pages,\n                         int freelist) {\n  for (Span* s = list->next; s != list; s = s->next) {\n    CHECK_CONDITION(s->location == freelist);  // NORMAL or RETURNED\n    CHECK_CONDITION(s->length >= min_pages);\n    CHECK_CONDITION(s->length <= max_pages);\n    CHECK_CONDITION(GetDescriptor(s->start) == s);\n    CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s);\n  }\n  return true;\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/page_heap.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#ifndef TCMALLOC_PAGE_HEAP_H_\n#define TCMALLOC_PAGE_HEAP_H_\n\n#include <config.h>\n#include <google/malloc_extension.h>\n#include \"common.h\"\n#include \"packed-cache-inl.h\"\n#include \"pagemap.h\"\n#include \"span.h\"\n\n// We need to dllexport PageHeap just for the unittest.  MSVC complains\n// that we don't dllexport the PageHeap members, but we don't need to\n// test those, so I just suppress this warning.\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4251)\n#endif\n\n// This #ifdef should almost never be set.  Set NO_TCMALLOC_SAMPLES if\n// you're porting to a system where you really can't get a stacktrace.\n#ifdef NO_TCMALLOC_SAMPLES\n  // We use #define so code compiles even if you #include stacktrace.h somehow.\n# define GetStackTrace(stack, depth, skip)  (0)\n#else\n# include <google/stacktrace.h>\n#endif\n\nnamespace tcmalloc {\n\n// -------------------------------------------------------------------------\n// Map from page-id to per-page data\n// -------------------------------------------------------------------------\n\n// We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines.\n// We also use a simple one-level cache for hot PageID-to-sizeclass mappings,\n// because sometimes the sizeclass is all the information we need.\n\n// Selector class -- general selector uses 3-level map\ntemplate <int BITS> class MapSelector {\n public:\n  typedef TCMalloc_PageMap3<BITS-kPageShift> Type;\n  typedef PackedCache<BITS-kPageShift, uint64_t> CacheType;\n};\n\n// A two-level map for 32-bit machines\ntemplate <> class MapSelector<32> {\n public:\n  typedef TCMalloc_PageMap2<32-kPageShift> Type;\n  typedef PackedCache<32-kPageShift, uint16_t> CacheType;\n};\n\n// -------------------------------------------------------------------------\n// Page-level allocator\n//  * Eager coalescing\n//\n// Heap for page-level allocation.  We allow allocating and freeing a\n// contiguous runs of pages (called a \"span\").\n// -------------------------------------------------------------------------\n\nclass PERFTOOLS_DLL_DECL PageHeap {\n public:\n  PageHeap();\n\n  // Allocate a run of \"n\" pages.  Returns zero if out of memory.\n  // Caller should not pass \"n == 0\" -- instead, n should have\n  // been rounded up already.\n  Span* New(Length n);\n\n  // Delete the span \"[p, p+n-1]\".\n  // REQUIRES: span was returned by earlier call to New() and\n  //           has not yet been deleted.\n  void Delete(Span* span);\n\n  // Mark an allocated span as being used for small objects of the\n  // specified size-class.\n  // REQUIRES: span was returned by an earlier call to New()\n  //           and has not yet been deleted.\n  void RegisterSizeClass(Span* span, size_t sc);\n\n  // Split an allocated span into two spans: one of length \"n\" pages\n  // followed by another span of length \"span->length - n\" pages.\n  // Modifies \"*span\" to point to the first span of length \"n\" pages.\n  // Returns a pointer to the second span.\n  //\n  // REQUIRES: \"0 < n < span->length\"\n  // REQUIRES: span->location == IN_USE\n  // REQUIRES: span->sizeclass == 0\n  Span* Split(Span* span, Length n);\n\n  // Return the descriptor for the specified page.  Returns NULL if\n  // this PageID was not allocated previously.\n  inline Span* GetDescriptor(PageID p) const {\n    return reinterpret_cast<Span*>(pagemap_.get(p));\n  }\n\n  // Dump state to stderr\n  void Dump(TCMalloc_Printer* out);\n\n  // If this page heap is managing a range with starting page # >= start,\n  // store info about the range in *r and return true.  Else return false.\n  bool GetNextRange(PageID start, base::MallocRange* r);\n\n  // Page heap statistics\n  struct Stats {\n    Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0) {}\n    uint64_t system_bytes;    // Total bytes allocated from system\n    uint64_t free_bytes;      // Total bytes on normal freelists\n    uint64_t unmapped_bytes;  // Total bytes on returned freelists\n  };\n  inline Stats stats() const { return stats_; }\n  void GetClassSizes(int64 class_sizes_normal[kMaxPages],\n                     int64 class_sizes_returned[kMaxPages],\n                     int64* normal_pages_in_spans,\n                     int64* returned_pages_in_spans);\n\n  bool Check();\n  // Like Check() but does some more comprehensive checking.\n  bool CheckExpensive();\n  bool CheckList(Span* list, Length min_pages, Length max_pages,\n                 int freelist);  // ON_NORMAL_FREELIST or ON_RETURNED_FREELIST\n\n  // Try to release at least num_pages for reuse by the OS.  Returns\n  // the actual number of pages released, which may be less than\n  // num_pages if there weren't enough pages to release. The result\n  // may also be larger than num_pages since page_heap might decide to\n  // release one large range instead of fragmenting it into two\n  // smaller released and unreleased ranges.\n  Length ReleaseAtLeastNPages(Length num_pages);\n\n  // Return 0 if we have no information, or else the correct sizeclass for p.\n  // Reads and writes to pagemap_cache_ do not require locking.\n  // The entries are 64 bits on 64-bit hardware and 16 bits on\n  // 32-bit hardware, and we don't mind raciness as long as each read of\n  // an entry yields a valid entry, not a partially updated entry.\n  size_t GetSizeClassIfCached(PageID p) const {\n    return pagemap_cache_.GetOrDefault(p, 0);\n  }\n  void CacheSizeClass(PageID p, size_t cl) const { pagemap_cache_.Put(p, cl); }\n\n private:\n  // Allocates a big block of memory for the pagemap once we reach more than\n  // 128MB\n  static const size_t kPageMapBigAllocationThreshold = 128 << 20;\n\n  // Minimum number of pages to fetch from system at a time.  Must be\n  // significantly bigger than kBlockSize to amortize system-call\n  // overhead, and also to reduce external fragementation.  Also, we\n  // should keep this value big because various incarnations of Linux\n  // have small limits on the number of mmap() regions per\n  // address-space.\n  // REQUIRED: kMinSystemAlloc <= kMaxPages;\n  static const int kMinSystemAlloc = kMaxPages;\n\n  // Never delay scavenging for more than the following number of\n  // deallocated pages.  With 4K pages, this comes to 4GB of\n  // deallocation.\n  static const int kMaxReleaseDelay = 1 << 20;\n\n  // If there is nothing to release, wait for so many pages before\n  // scavenging again.  With 4K pages, this comes to 1GB of memory.\n  static const int kDefaultReleaseDelay = 1 << 18;\n\n  // Pick the appropriate map and cache types based on pointer size\n  typedef MapSelector<kAddressBits>::Type PageMap;\n  typedef MapSelector<kAddressBits>::CacheType PageMapCache;\n  PageMap pagemap_;\n  mutable PageMapCache pagemap_cache_;\n\n  // We segregate spans of a given size into two circular linked\n  // lists: one for normal spans, and one for spans whose memory\n  // has been returned to the system.\n  struct SpanList {\n    Span        normal;\n    Span        returned;\n  };\n\n  // List of free spans of length >= kMaxPages\n  SpanList large_;\n\n  // Array mapping from span length to a doubly linked list of free spans\n  SpanList free_[kMaxPages];\n\n  // Statistics on system, free, and unmapped bytes\n  Stats stats_;\n\n  Span* SearchFreeAndLargeLists(Length n);\n\n  bool GrowHeap(Length n);\n\n  // REQUIRES: span->length >= n\n  // REQUIRES: span->location != IN_USE\n  // Remove span from its free list, and move any leftover part of\n  // span into appropriate free lists.  Also update \"span\" to have\n  // length exactly \"n\" and mark it as non-free so it can be returned\n  // to the client.  After all that, decrease free_pages_ by n and\n  // return span.\n  Span* Carve(Span* span, Length n);\n\n  void RecordSpan(Span* span) {\n    pagemap_.set(span->start, span);\n    if (span->length > 1) {\n      pagemap_.set(span->start + span->length - 1, span);\n    }\n  }\n\n  // Allocate a large span of length == n.  If successful, returns a\n  // span of exactly the specified length.  Else, returns NULL.\n  Span* AllocLarge(Length n);\n\n  // Coalesce span with neighboring spans if possible, prepend to\n  // appropriate free list, and adjust stats.\n  void MergeIntoFreeList(Span* span);\n\n  // Prepends span to appropriate free list, and adjusts stats.\n  void PrependToFreeList(Span* span);\n\n  // Removes span from its free list, and adjust stats.\n  void RemoveFromFreeList(Span* span);\n\n  // Incrementally release some memory to the system.\n  // IncrementalScavenge(n) is called whenever n pages are freed.\n  void IncrementalScavenge(Length n);\n\n  // Release the last span on the normal portion of this list.\n  // Return the length of that span.\n  Length ReleaseLastNormalSpan(SpanList* slist);\n\n\n  // Number of pages to deallocate before doing more scavenging\n  int64_t scavenge_counter_;\n\n  // Index of last free list where we released memory to the OS.\n  int release_index_;\n};\n\n}  // namespace tcmalloc\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n#endif  // TCMALLOC_PAGE_HEAP_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/page_heap_allocator.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_\n#define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_\n\nnamespace tcmalloc {\n\n// Simple allocator for objects of a specified type.  External locking\n// is required before accessing one of these objects.\ntemplate <class T>\nclass PageHeapAllocator {\n public:\n  // We use an explicit Init function because these variables are statically\n  // allocated and their constructors might not have run by the time some\n  // other static variable tries to allocate memory.\n  void Init() {\n    ASSERT(sizeof(T) <= kAllocIncrement);\n    inuse_ = 0;\n    free_area_ = NULL;\n    free_avail_ = 0;\n    free_list_ = NULL;\n    // Reserve some space at the beginning to avoid fragmentation.\n    Delete(New());\n  }\n\n  T* New() {\n    // Consult free list\n    void* result;\n    if (free_list_ != NULL) {\n      result = free_list_;\n      free_list_ = *(reinterpret_cast<void**>(result));\n    } else {\n      if (free_avail_ < sizeof(T)) {\n        // Need more room. We assume that MetaDataAlloc returns\n        // suitably aligned memory.\n        free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));\n        if (free_area_ == NULL) {\n          CRASH(\"FATAL ERROR: Out of memory trying to allocate internal \"\n                \"tcmalloc data (%d bytes, object-size %d)\\n\",\n                kAllocIncrement, static_cast<int>(sizeof(T)));\n        }\n        free_avail_ = kAllocIncrement;\n      }\n      result = free_area_;\n      free_area_ += sizeof(T);\n      free_avail_ -= sizeof(T);\n    }\n    inuse_++;\n    return reinterpret_cast<T*>(result);\n  }\n\n  void Delete(T* p) {\n    *(reinterpret_cast<void**>(p)) = free_list_;\n    free_list_ = p;\n    inuse_--;\n  }\n\n  int inuse() const { return inuse_; }\n\n private:\n  // How much to allocate from system at a time\n  static const int kAllocIncrement = 128 << 10;\n\n  // Free area from which to carve new objects\n  char* free_area_;\n  size_t free_avail_;\n\n  // Free list of already carved objects\n  void* free_list_;\n\n  // Number of allocated but unfreed objects\n  int inuse_;\n};\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/pagemap.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// A data structure used by the caching malloc.  It maps from page# to\n// a pointer that contains info about that page.  We use two\n// representations: one for 32-bit addresses, and another for 64 bit\n// addresses.  Both representations provide the same interface.  The\n// first representation is implemented as a flat array, the seconds as\n// a three-level radix tree that strips away approximately 1/3rd of\n// the bits every time.\n//\n// The BITS parameter should be the number of bits required to hold\n// a page number.  E.g., with 32 bit pointers and 4K pages (i.e.,\n// page offset fits in lower 12 bits), BITS == 20.\n\n#ifndef TCMALLOC_PAGEMAP_H_\n#define TCMALLOC_PAGEMAP_H_\n\n#include \"config.h\"\n#if defined HAVE_STDINT_H\n#include <stdint.h>\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>\n#else\n#include <sys/types.h>\n#endif\n#include \"internal_logging.h\"\n\n// Single-level array\ntemplate <int BITS>\nclass TCMalloc_PageMap1 {\n private:\n  static const int LENGTH = 1 << BITS;\n\n  void** array_;\n\n public:\n  typedef uintptr_t Number;\n\n  explicit TCMalloc_PageMap1(void* (*allocator)(size_t)) {\n    array_ = reinterpret_cast<void**>((*allocator)(sizeof(void*) << BITS));\n    memset(array_, 0, sizeof(void*) << BITS);\n  }\n\n  // Ensure that the map contains initialized entries \"x .. x+n-1\".\n  // Returns true if successful, false if we could not allocate memory.\n  bool Ensure(Number x, size_t n) {\n    // Nothing to do since flat array was allocated at start.  All\n    // that's left is to check for overflow (that is, we don't want to\n    // ensure a number y where array_[y] would be an out-of-bounds\n    // access).\n    return n <= LENGTH - x;   // an overflow-free way to do \"x + n <= LENGTH\"\n  }\n\n  void PreallocateMoreMemory() {}\n\n  // Return the current value for KEY.  Returns NULL if not yet set,\n  // or if k is out of range.\n  void* get(Number k) const {\n    if ((k >> BITS) > 0) {\n      return NULL;\n    }\n    return array_[k];\n  }\n\n  // REQUIRES \"k\" is in range \"[0,2^BITS-1]\".\n  // REQUIRES \"k\" has been ensured before.\n  //\n  // Sets the value 'v' for key 'k'.\n  void set(Number k, void* v) {\n    array_[k] = v;\n  }\n\n  // Return the first non-NULL pointer found in this map for\n  // a page number >= k.  Returns NULL if no such number is found.\n  void* Next(Number k) const {\n    while (k < (1 << BITS)) {\n      if (array_[k] != NULL) return array_[k];\n      k++;\n    }\n    return NULL;\n  }\n};\n\n// Two-level radix tree\ntemplate <int BITS>\nclass TCMalloc_PageMap2 {\n private:\n  // Put 32 entries in the root and (2^BITS)/32 entries in each leaf.\n  static const int ROOT_BITS = 5;\n  static const int ROOT_LENGTH = 1 << ROOT_BITS;\n\n  static const int LEAF_BITS = BITS - ROOT_BITS;\n  static const int LEAF_LENGTH = 1 << LEAF_BITS;\n\n  // Leaf node\n  struct Leaf {\n    void* values[LEAF_LENGTH];\n  };\n\n  Leaf* root_[ROOT_LENGTH];             // Pointers to 32 child nodes\n  void* (*allocator_)(size_t);          // Memory allocator\n\n public:\n  typedef uintptr_t Number;\n\n  explicit TCMalloc_PageMap2(void* (*allocator)(size_t)) {\n    allocator_ = allocator;\n    memset(root_, 0, sizeof(root_));\n  }\n\n  void* get(Number k) const {\n    const Number i1 = k >> LEAF_BITS;\n    const Number i2 = k & (LEAF_LENGTH-1);\n    if ((k >> BITS) > 0 || root_[i1] == NULL) {\n      return NULL;\n    }\n    return root_[i1]->values[i2];\n  }\n\n  void set(Number k, void* v) {\n    ASSERT(k >> BITS == 0);\n    const Number i1 = k >> LEAF_BITS;\n    const Number i2 = k & (LEAF_LENGTH-1);\n    root_[i1]->values[i2] = v;\n  }\n\n  bool Ensure(Number start, size_t n) {\n    for (Number key = start; key <= start + n - 1; ) {\n      const Number i1 = key >> LEAF_BITS;\n\n      // Check for overflow\n      if (i1 >= ROOT_LENGTH)\n        return false;\n\n      // Make 2nd level node if necessary\n      if (root_[i1] == NULL) {\n        Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf)));\n        if (leaf == NULL) return false;\n        memset(leaf, 0, sizeof(*leaf));\n        root_[i1] = leaf;\n      }\n\n      // Advance key past whatever is covered by this leaf node\n      key = ((key >> LEAF_BITS) + 1) << LEAF_BITS;\n    }\n    return true;\n  }\n\n  void PreallocateMoreMemory() {\n    // Allocate enough to keep track of all possible pages\n    Ensure(0, 1 << BITS);\n  }\n\n  void* Next(Number k) const {\n    while (k < (1 << BITS)) {\n      const Number i1 = k >> LEAF_BITS;\n      Leaf* leaf = root_[i1];\n      if (leaf != NULL) {\n        // Scan forward in leaf\n        for (Number i2 = k & (LEAF_LENGTH - 1); i2 < LEAF_LENGTH; i2++) {\n          if (leaf->values[i2] != NULL) {\n            return leaf->values[i2];\n          }\n        }\n      }\n      // Skip to next top-level entry\n      k = (i1 + 1) << LEAF_BITS;\n    }\n    return NULL;\n  }\n};\n\n// Three-level radix tree\ntemplate <int BITS>\nclass TCMalloc_PageMap3 {\n private:\n  // How many bits should we consume at each interior level\n  static const int INTERIOR_BITS = (BITS + 2) / 3; // Round-up\n  static const int INTERIOR_LENGTH = 1 << INTERIOR_BITS;\n\n  // How many bits should we consume at leaf level\n  static const int LEAF_BITS = BITS - 2*INTERIOR_BITS;\n  static const int LEAF_LENGTH = 1 << LEAF_BITS;\n\n  // Interior node\n  struct Node {\n    Node* ptrs[INTERIOR_LENGTH];\n  };\n\n  // Leaf node\n  struct Leaf {\n    void* values[LEAF_LENGTH];\n  };\n\n  Node* root_;                          // Root of radix tree\n  void* (*allocator_)(size_t);          // Memory allocator\n\n  Node* NewNode() {\n    Node* result = reinterpret_cast<Node*>((*allocator_)(sizeof(Node)));\n    if (result != NULL) {\n      memset(result, 0, sizeof(*result));\n    }\n    return result;\n  }\n\n public:\n  typedef uintptr_t Number;\n\n  explicit TCMalloc_PageMap3(void* (*allocator)(size_t)) {\n    allocator_ = allocator;\n    root_ = NewNode();\n  }\n\n  void* get(Number k) const {\n    const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);\n    const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);\n    const Number i3 = k & (LEAF_LENGTH-1);\n    if ((k >> BITS) > 0 ||\n        root_->ptrs[i1] == NULL || root_->ptrs[i1]->ptrs[i2] == NULL) {\n      return NULL;\n    }\n    return reinterpret_cast<Leaf*>(root_->ptrs[i1]->ptrs[i2])->values[i3];\n  }\n\n  void set(Number k, void* v) {\n    ASSERT(k >> BITS == 0);\n    const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);\n    const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);\n    const Number i3 = k & (LEAF_LENGTH-1);\n    reinterpret_cast<Leaf*>(root_->ptrs[i1]->ptrs[i2])->values[i3] = v;\n  }\n\n  bool Ensure(Number start, size_t n) {\n    for (Number key = start; key <= start + n - 1; ) {\n      const Number i1 = key >> (LEAF_BITS + INTERIOR_BITS);\n      const Number i2 = (key >> LEAF_BITS) & (INTERIOR_LENGTH-1);\n\n      // Check for overflow\n      if (i1 >= INTERIOR_LENGTH || i2 >= INTERIOR_LENGTH)\n        return false;\n\n      // Make 2nd level node if necessary\n      if (root_->ptrs[i1] == NULL) {\n        Node* n = NewNode();\n        if (n == NULL) return false;\n        root_->ptrs[i1] = n;\n      }\n\n      // Make leaf node if necessary\n      if (root_->ptrs[i1]->ptrs[i2] == NULL) {\n        Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf)));\n        if (leaf == NULL) return false;\n        memset(leaf, 0, sizeof(*leaf));\n        root_->ptrs[i1]->ptrs[i2] = reinterpret_cast<Node*>(leaf);\n      }\n\n      // Advance key past whatever is covered by this leaf node\n      key = ((key >> LEAF_BITS) + 1) << LEAF_BITS;\n    }\n    return true;\n  }\n\n  void PreallocateMoreMemory() {\n  }\n\n  void* Next(Number k) const {\n    while (k < (Number(1) << BITS)) {\n      const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS);\n      const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1);\n      if (root_->ptrs[i1] == NULL) {\n        // Advance to next top-level entry\n        k = (i1 + 1) << (LEAF_BITS + INTERIOR_BITS);\n      } else {\n        Leaf* leaf = reinterpret_cast<Leaf*>(root_->ptrs[i1]->ptrs[i2]);\n        if (leaf != NULL) {\n          for (Number i3 = (k & (LEAF_LENGTH-1)); i3 < LEAF_LENGTH; i3++) {\n            if (leaf->values[i3] != NULL) {\n              return leaf->values[i3];\n            }\n          }\n        }\n        // Advance to next interior entry\n        k = ((k >> LEAF_BITS) + 1) << LEAF_BITS;\n      }\n    }\n    return NULL;\n  }\n};\n\n#endif  // TCMALLOC_PAGEMAP_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/pprof",
    "content": "#! /usr/bin/env perl\n\n# Copyright (c) 1998-2007, Google Inc.\n# All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n# \n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# ---\n# Program for printing the profile generated by common/profiler.cc,\n# or by the heap profiler (common/debugallocation.cc)\n#\n# The profile contains a sequence of entries of the form:\n#       <count> <stack trace>\n# This program parses the profile, and generates user-readable\n# output.\n#\n# Examples:\n#\n# % tools/pprof \"program\" \"profile\"\n#   Enters \"interactive\" mode\n#\n# % tools/pprof --text \"program\" \"profile\"\n#   Generates one line per procedure\n#\n# % tools/pprof --gv \"program\" \"profile\"\n#   Generates annotated call-graph and displays via \"gv\"\n#\n# % tools/pprof --gv --focus=Mutex \"program\" \"profile\"\n#   Restrict to code paths that involve an entry that matches \"Mutex\"\n#\n# % tools/pprof --gv --focus=Mutex --ignore=string \"program\" \"profile\"\n#   Restrict to code paths that involve an entry that matches \"Mutex\"\n#   and does not match \"string\"\n#\n# % tools/pprof --list=IBF_CheckDocid \"program\" \"profile\"\n#   Generates disassembly listing of all routines with at least one\n#   sample that match the --list=<regexp> pattern.  The listing is\n#   annotated with the flat and cumulative sample counts at each line.\n#\n# % tools/pprof --disasm=IBF_CheckDocid \"program\" \"profile\"\n#   Generates disassembly listing of all routines with at least one\n#   sample that match the --disasm=<regexp> pattern.  The listing is\n#   annotated with the flat and cumulative sample counts at each PC value.\n#\n# TODO: Use color to indicate files?\n\nuse strict;\nuse warnings;\nuse Getopt::Long;\n\nmy $PPROF_VERSION = \"1.7\";\n\n# These are the object tools we use which can come from a\n# user-specified location using --tools, from the PPROF_TOOLS\n# environment variable, or from the environment.\nmy %obj_tool_map = (\n  \"objdump\" => \"objdump\",\n  \"nm\" => \"nm\",\n  \"addr2line\" => \"addr2line\",\n  \"c++filt\" => \"c++filt\",\n  ## ConfigureObjTools may add architecture-specific entries:\n  #\"nm_pdb\" => \"nm-pdb\",       # for reading windows (PDB-format) executables\n  #\"addr2line_pdb\" => \"addr2line-pdb\",                                # ditto\n  #\"otool\" => \"otool\",         # equivalent of objdump on OS X\n);\nmy $DOT = \"dot\";          # leave non-absolute, since it may be in /usr/local\nmy $GV = \"gv\";\nmy $EVINCE = \"evince\";    # could also be xpdf or perhaps acroread\nmy $KCACHEGRIND = \"kcachegrind\";\nmy $PS2PDF = \"ps2pdf\";\n# These are used for dynamic profiles\nmy $URL_FETCHER = \"curl -s\";\n\n# These are the web pages that servers need to support for dynamic profiles\nmy $HEAP_PAGE = \"/pprof/heap\";\nmy $PROFILE_PAGE = \"/pprof/profile\";   # must support cgi-param \"?seconds=#\"\nmy $PMUPROFILE_PAGE = \"/pprof/pmuprofile(?:\\\\?.*)?\"; # must support cgi-param\n                                                # ?seconds=#&event=x&period=n\nmy $GROWTH_PAGE = \"/pprof/growth\";\nmy $CONTENTION_PAGE = \"/pprof/contention\";\nmy $WALL_PAGE = \"/pprof/wall(?:\\\\?.*)?\";  # accepts options like namefilter\nmy $FILTEREDPROFILE_PAGE = \"/pprof/filteredprofile(?:\\\\?.*)?\";\nmy $CENSUSPROFILE_PAGE = \"/pprof/censusprofile\";  # must support \"?seconds=#\"\nmy $SYMBOL_PAGE = \"/pprof/symbol\";     # must support symbol lookup via POST\nmy $PROGRAM_NAME_PAGE = \"/pprof/cmdline\";\n\n# These are the web pages that can be named on the command line.\n# All the alternatives must begin with /.\nmy $PROFILES = \"($HEAP_PAGE|$PROFILE_PAGE|$PMUPROFILE_PAGE|\" .\n               \"$GROWTH_PAGE|$CONTENTION_PAGE|$WALL_PAGE|\" .\n               \"$FILTEREDPROFILE_PAGE|$CENSUSPROFILE_PAGE)\";\n\n# default binary name\nmy $UNKNOWN_BINARY = \"(unknown)\";\n\n# There is a pervasive dependency on the length (in hex characters,\n# i.e., nibbles) of an address, distinguishing between 32-bit and\n# 64-bit profiles.  To err on the safe size, default to 64-bit here:\nmy $address_length = 16;\n\n# A list of paths to search for shared object files\nmy @prefix_list = ();\n\n# Special routine name that should not have any symbols.\n# Used as separator to parse \"addr2line -i\" output.\nmy $sep_symbol = '_fini';\nmy $sep_address = undef;\n\n##### Argument parsing #####\n\nsub usage_string {\n  return <<EOF;\nUsage:\npprof [options] <program> <profiles>\n   <profiles> is a space separated list of profile names.\npprof [options] <symbolized-profiles>\n   <symbolized-profiles> is a list of profile files where each file contains\n   the necessary symbol mappings  as well as profile data (likely generated\n   with --raw).\npprof [options] <profile>\n   <profile> is a remote form.  Symbols are obtained from host:port$SYMBOL_PAGE\n\n   Each name can be:\n   /path/to/profile        - a path to a profile file\n   host:port[/<service>]   - a location of a service to get profile from\n\n   The /<service> can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile,\n                         $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,\n                         $CENSUSPROFILE_PAGE, or /pprof/filteredprofile.\n   For instance: \"pprof http://myserver.com:80$HEAP_PAGE\".\n   If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).\npprof --symbols <program>\n   Maps addresses to symbol names.  In this mode, stdin should be a\n   list of library mappings, in the same format as is found in the heap-\n   and cpu-profile files (this loosely matches that of /proc/self/maps\n   on linux), followed by a list of hex addresses to map, one per line.\n\n   For more help with querying remote servers, including how to add the\n   necessary server-side support code, see this filename (or one like it):\n\n   /usr/doc/google-perftools-$PPROF_VERSION/pprof_remote_servers.html\n\nOptions:\n   --cum               Sort by cumulative data\n   --base=<base>       Subtract <base> from <profile> before display\n   --interactive       Run in interactive mode (interactive \"help\" gives help) [default]\n   --seconds=<n>       Length of time for dynamic profiles [default=30 secs]\n   --add_lib=<file>    Read additional symbols and line info from the given library\n   --lib_prefix=<dir>  Comma separated list of library path prefixes\n\nReporting Granularity:\n   --addresses         Report at address level\n   --lines             Report at source line level\n   --functions         Report at function level [default]\n   --files             Report at source file level\n\nOutput type:\n   --text              Generate text report\n   --callgrind         Generate callgrind format to stdout\n   --gv                Generate Postscript and display\n   --evince            Generate PDF and display\n   --web               Generate SVG and display\n   --list=<regexp>     Generate source listing of matching routines\n   --disasm=<regexp>   Generate disassembly of matching routines\n   --symbols           Print demangled symbol names found at given addresses\n   --dot               Generate DOT file to stdout\n   --ps                Generate Postcript to stdout\n   --pdf               Generate PDF to stdout\n   --svg               Generate SVG to stdout\n   --gif               Generate GIF to stdout\n   --raw               Generate symbolized pprof data (useful with remote fetch)\n\nHeap-Profile Options:\n   --inuse_space       Display in-use (mega)bytes [default]\n   --inuse_objects     Display in-use objects\n   --alloc_space       Display allocated (mega)bytes\n   --alloc_objects     Display allocated objects\n   --show_bytes        Display space in bytes\n   --drop_negative     Ignore negative differences\n\nContention-profile options:\n   --total_delay       Display total delay at each region [default]\n   --contentions       Display number of delays at each region\n   --mean_delay        Display mean delay at each region\n\nCall-graph Options:\n   --nodecount=<n>     Show at most so many nodes [default=80]\n   --nodefraction=<f>  Hide nodes below <f>*total [default=.005]\n   --edgefraction=<f>  Hide edges below <f>*total [default=.001]\n   --maxdegree=<n>     Max incoming/outgoing edges per node [default=8]\n   --focus=<regexp>    Focus on nodes matching <regexp>\n   --ignore=<regexp>   Ignore nodes matching <regexp>\n   --scale=<n>         Set GV scaling [default=0]\n   --heapcheck         Make nodes with non-0 object counts\n                       (i.e. direct leak generators) more visible\n\nMiscellaneous:\n   --tools=<prefix or binary:fullpath>[,...]   \\$PATH for object tool pathnames\n   --test              Run unit tests\n   --help              This message\n   --version           Version information\n\nEnvironment Variables:\n   PPROF_TMPDIR        Profiles directory. Defaults to \\$HOME/pprof\n   PPROF_TOOLS         Prefix for object tools pathnames\n\nExamples:\n\npprof /bin/ls ls.prof\n                       Enters \"interactive\" mode\npprof --text /bin/ls ls.prof\n                       Outputs one line per procedure\npprof --web /bin/ls ls.prof\n                       Displays annotated call-graph in web browser\npprof --gv /bin/ls ls.prof\n                       Displays annotated call-graph via 'gv'\npprof --gv --focus=Mutex /bin/ls ls.prof\n                       Restricts to code paths including a .*Mutex.* entry\npprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof\n                       Code paths including Mutex but not string\npprof --list=getdir /bin/ls ls.prof\n                       (Per-line) annotated source listing for getdir()\npprof --disasm=getdir /bin/ls ls.prof\n                       (Per-PC) annotated disassembly for getdir()\n\npprof http://localhost:1234/\n                       Enters \"interactive\" mode\npprof --text localhost:1234\n                       Outputs one line per procedure for localhost:1234\npprof --raw localhost:1234 > ./local.raw\npprof --text ./local.raw\n                       Fetches a remote profile for later analysis and then\n                       analyzes it in text mode.\nEOF\n}\n\nsub version_string {\n  return <<EOF\npprof (part of google-perftools $PPROF_VERSION)\n\nCopyright 1998-2007 Google Inc.\n\nThis is BSD licensed software; see the source for copying conditions\nand license information.\nThere is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE.\nEOF\n}\n\nsub usage {\n  my $msg = shift;\n  print STDERR \"$msg\\n\\n\";\n  print STDERR usage_string();\n  print STDERR \"\\nFATAL ERROR: $msg\\n\";    # just as a reminder\n  exit(1);\n}\n\nsub Init() {\n  # Setup tmp-file name and handler to clean it up.\n  # We do this in the very beginning so that we can use\n  # error() and cleanup() function anytime here after.\n  $main::tmpfile_sym = \"/tmp/pprof$$.sym\";\n  $main::tmpfile_ps = \"/tmp/pprof$$\";\n  $main::next_tmpfile = 0;\n  $SIG{'INT'} = \\&sighandler;\n\n  # Cache from filename/linenumber to source code\n  $main::source_cache = ();\n\n  $main::opt_help = 0;\n  $main::opt_version = 0;\n\n  $main::opt_cum = 0;\n  $main::opt_base = '';\n  $main::opt_addresses = 0;\n  $main::opt_lines = 0;\n  $main::opt_functions = 0;\n  $main::opt_files = 0;\n  $main::opt_lib_prefix = \"\";\n\n  $main::opt_text = 0;\n  $main::opt_callgrind = 0;\n  $main::opt_list = \"\";\n  $main::opt_disasm = \"\";\n  $main::opt_symbols = 0;\n  $main::opt_gv = 0;\n  $main::opt_evince = 0;\n  $main::opt_web = 0;\n  $main::opt_dot = 0;\n  $main::opt_ps = 0;\n  $main::opt_pdf = 0;\n  $main::opt_gif = 0;\n  $main::opt_svg = 0;\n  $main::opt_raw = 0;\n\n  $main::opt_nodecount = 80;\n  $main::opt_nodefraction = 0.005;\n  $main::opt_edgefraction = 0.001;\n  $main::opt_maxdegree = 8;\n  $main::opt_focus = '';\n  $main::opt_ignore = '';\n  $main::opt_scale = 0;\n  $main::opt_heapcheck = 0;\n  $main::opt_seconds = 30;\n  $main::opt_lib = \"\";\n\n  $main::opt_inuse_space   = 0;\n  $main::opt_inuse_objects = 0;\n  $main::opt_alloc_space   = 0;\n  $main::opt_alloc_objects = 0;\n  $main::opt_show_bytes    = 0;\n  $main::opt_drop_negative = 0;\n  $main::opt_interactive   = 0;\n\n  $main::opt_total_delay = 0;\n  $main::opt_contentions = 0;\n  $main::opt_mean_delay = 0;\n\n  $main::opt_tools   = \"\";\n  $main::opt_debug   = 0;\n  $main::opt_test    = 0;\n\n  # These are undocumented flags used only by unittests.\n  $main::opt_test_stride = 0;\n\n  # Are we using $SYMBOL_PAGE?\n  $main::use_symbol_page = 0;\n\n  # Files returned by TempName.\n  %main::tempnames = ();\n\n  # Type of profile we are dealing with\n  # Supported types:\n  #     cpu\n  #     heap\n  #     growth\n  #     contention\n  $main::profile_type = '';     # Empty type means \"unknown\"\n\n  GetOptions(\"help!\"          => \\$main::opt_help,\n             \"version!\"       => \\$main::opt_version,\n             \"cum!\"           => \\$main::opt_cum,\n             \"base=s\"         => \\$main::opt_base,\n             \"seconds=i\"      => \\$main::opt_seconds,\n             \"add_lib=s\"      => \\$main::opt_lib,\n             \"lib_prefix=s\"   => \\$main::opt_lib_prefix,\n             \"functions!\"     => \\$main::opt_functions,\n             \"lines!\"         => \\$main::opt_lines,\n             \"addresses!\"     => \\$main::opt_addresses,\n             \"files!\"         => \\$main::opt_files,\n             \"text!\"          => \\$main::opt_text,\n             \"callgrind!\"     => \\$main::opt_callgrind,\n             \"list=s\"         => \\$main::opt_list,\n             \"disasm=s\"       => \\$main::opt_disasm,\n             \"symbols!\"       => \\$main::opt_symbols,\n             \"gv!\"            => \\$main::opt_gv,\n             \"evince!\"        => \\$main::opt_evince,\n             \"web!\"           => \\$main::opt_web,\n             \"dot!\"           => \\$main::opt_dot,\n             \"ps!\"            => \\$main::opt_ps,\n             \"pdf!\"           => \\$main::opt_pdf,\n             \"svg!\"           => \\$main::opt_svg,\n             \"gif!\"           => \\$main::opt_gif,\n             \"raw!\"           => \\$main::opt_raw,\n             \"interactive!\"   => \\$main::opt_interactive,\n             \"nodecount=i\"    => \\$main::opt_nodecount,\n             \"nodefraction=f\" => \\$main::opt_nodefraction,\n             \"edgefraction=f\" => \\$main::opt_edgefraction,\n             \"maxdegree=i\"    => \\$main::opt_maxdegree,\n             \"focus=s\"        => \\$main::opt_focus,\n             \"ignore=s\"       => \\$main::opt_ignore,\n             \"scale=i\"        => \\$main::opt_scale,\n             \"heapcheck\"      => \\$main::opt_heapcheck,\n             \"inuse_space!\"   => \\$main::opt_inuse_space,\n             \"inuse_objects!\" => \\$main::opt_inuse_objects,\n             \"alloc_space!\"   => \\$main::opt_alloc_space,\n             \"alloc_objects!\" => \\$main::opt_alloc_objects,\n             \"show_bytes!\"    => \\$main::opt_show_bytes,\n             \"drop_negative!\" => \\$main::opt_drop_negative,\n             \"total_delay!\"   => \\$main::opt_total_delay,\n             \"contentions!\"   => \\$main::opt_contentions,\n             \"mean_delay!\"    => \\$main::opt_mean_delay,\n             \"tools=s\"        => \\$main::opt_tools,\n             \"test!\"          => \\$main::opt_test,\n             \"debug!\"         => \\$main::opt_debug,\n             # Undocumented flags used only by unittests:\n             \"test_stride=i\"  => \\$main::opt_test_stride,\n      ) || usage(\"Invalid option(s)\");\n\n  # Deal with the standard --help and --version\n  if ($main::opt_help) {\n    print usage_string();\n    exit(0);\n  }\n\n  if ($main::opt_version) {\n    print version_string();\n    exit(0);\n  }\n\n  # Disassembly/listing/symbols mode requires address-level info\n  if ($main::opt_disasm || $main::opt_list || $main::opt_symbols) {\n    $main::opt_functions = 0;\n    $main::opt_lines = 0;\n    $main::opt_addresses = 1;\n    $main::opt_files = 0;\n  }\n\n  # Check heap-profiling flags\n  if ($main::opt_inuse_space +\n      $main::opt_inuse_objects +\n      $main::opt_alloc_space +\n      $main::opt_alloc_objects > 1) {\n    usage(\"Specify at most on of --inuse/--alloc options\");\n  }\n\n  # Check output granularities\n  my $grains =\n      $main::opt_functions +\n      $main::opt_lines +\n      $main::opt_addresses +\n      $main::opt_files +\n      0;\n  if ($grains > 1) {\n    usage(\"Only specify one output granularity option\");\n  }\n  if ($grains == 0) {\n    $main::opt_functions = 1;\n  }\n\n  # Check output modes\n  my $modes =\n      $main::opt_text +\n      $main::opt_callgrind +\n      ($main::opt_list eq '' ? 0 : 1) +\n      ($main::opt_disasm eq '' ? 0 : 1) +\n      ($main::opt_symbols == 0 ? 0 : 1) +\n      $main::opt_gv +\n      $main::opt_evince +\n      $main::opt_web +\n      $main::opt_dot +\n      $main::opt_ps +\n      $main::opt_pdf +\n      $main::opt_svg +\n      $main::opt_gif +\n      $main::opt_raw +\n      $main::opt_interactive +\n      0;\n  if ($modes > 1) {\n    usage(\"Only specify one output mode\");\n  }\n  if ($modes == 0) {\n    if (-t STDOUT) {  # If STDOUT is a tty, activate interactive mode\n      $main::opt_interactive = 1;\n    } else {\n      $main::opt_text = 1;\n    }\n  }\n\n  if ($main::opt_test) {\n    RunUnitTests();\n    # Should not return\n    exit(1);\n  }\n\n  # Binary name and profile arguments list\n  $main::prog = \"\";\n  @main::pfile_args = ();\n\n  # Remote profiling without a binary (using $SYMBOL_PAGE instead)\n  if (IsProfileURL($ARGV[0])) {\n    $main::use_symbol_page = 1;\n  } elsif (IsSymbolizedProfileFile($ARGV[0])) {\n    $main::use_symbolized_profile = 1;\n    $main::prog = $UNKNOWN_BINARY;  # will be set later from the profile file\n  }\n\n  if ($main::use_symbol_page || $main::use_symbolized_profile) {\n    # We don't need a binary!\n    my %disabled = ('--lines' => $main::opt_lines,\n                    '--disasm' => $main::opt_disasm);\n    for my $option (keys %disabled) {\n      usage(\"$option cannot be used without a binary\") if $disabled{$option};\n    }\n    # Set $main::prog later...\n    scalar(@ARGV) || usage(\"Did not specify profile file\");\n  } elsif ($main::opt_symbols) {\n    # --symbols needs a binary-name (to run nm on, etc) but not profiles\n    $main::prog = shift(@ARGV) || usage(\"Did not specify program\");\n  } else {\n    $main::prog = shift(@ARGV) || usage(\"Did not specify program\");\n    scalar(@ARGV) || usage(\"Did not specify profile file\");\n  }\n\n  # Parse profile file/location arguments\n  foreach my $farg (@ARGV) {\n    if ($farg =~ m/(.*)\\@([0-9]+)(|\\/.*)$/ ) {\n      my $machine = $1;\n      my $num_machines = $2;\n      my $path = $3;\n      for (my $i = 0; $i < $num_machines; $i++) {\n        unshift(@main::pfile_args, \"$i.$machine$path\");\n      }\n    } else {\n      unshift(@main::pfile_args, $farg);\n    }\n  }\n\n  if ($main::use_symbol_page) {\n    unless (IsProfileURL($main::pfile_args[0])) {\n      error(\"The first profile should be a remote form to use $SYMBOL_PAGE\\n\");\n    }\n    CheckSymbolPage();\n    $main::prog = FetchProgramName();\n  } elsif (!$main::use_symbolized_profile) {  # may not need objtools!\n    ConfigureObjTools($main::prog)\n  }\n\n  # Break the opt_list_prefix into the prefix_list array\n  @prefix_list = split (',', $main::opt_lib_prefix);\n\n  # Remove trailing / from the prefixes, in the list to prevent\n  # searching things like /my/path//lib/mylib.so\n  foreach (@prefix_list) {\n    s|/+$||;\n  }\n}\n\nsub Main() {\n  Init();\n  $main::collected_profile = undef;\n  @main::profile_files = ();\n  $main::op_time = time();\n\n  # Printing symbols is special and requires a lot less info that most.\n  if ($main::opt_symbols) {\n    PrintSymbols(*STDIN);   # Get /proc/maps and symbols output from stdin\n    return;\n  }\n\n  # Fetch all profile data\n  FetchDynamicProfiles();\n\n  # this will hold symbols that we read from the profile files\n  my $symbol_map = {};\n\n  # Read one profile, pick the last item on the list\n  my $data = ReadProfile($main::prog, pop(@main::profile_files));\n  my $profile = $data->{profile};\n  my $pcs = $data->{pcs};\n  my $libs = $data->{libs};   # Info about main program and shared libraries\n  $symbol_map = MergeSymbols($symbol_map, $data->{symbols});\n\n  # Add additional profiles, if available.\n  if (scalar(@main::profile_files) > 0) {\n    foreach my $pname (@main::profile_files) {\n      my $data2 = ReadProfile($main::prog, $pname);\n      $profile = AddProfile($profile, $data2->{profile});\n      $pcs = AddPcs($pcs, $data2->{pcs});\n      $symbol_map = MergeSymbols($symbol_map, $data2->{symbols});\n    }\n  }\n\n  # Subtract base from profile, if specified\n  if ($main::opt_base ne '') {\n    my $base = ReadProfile($main::prog, $main::opt_base);\n    $profile = SubtractProfile($profile, $base->{profile});\n    $pcs = AddPcs($pcs, $base->{pcs});\n    $symbol_map = MergeSymbols($symbol_map, $base->{symbols});\n  }\n\n  # Get total data in profile\n  my $total = TotalProfile($profile);\n\n  # Collect symbols\n  my $symbols;\n  if ($main::use_symbolized_profile) {\n    $symbols = FetchSymbols($pcs, $symbol_map);\n  } elsif ($main::use_symbol_page) {\n    $symbols = FetchSymbols($pcs);\n  } else {\n    # TODO(csilvers): $libs uses the /proc/self/maps data from profile1,\n    # which may differ from the data from subsequent profiles, especially\n    # if they were run on different machines.  Use appropriate libs for\n    # each pc somehow.\n    $symbols = ExtractSymbols($libs, $pcs);\n  }\n\n  # Remove uniniteresting stack items\n  $profile = RemoveUninterestingFrames($symbols, $profile);\n\n  # Focus?\n  if ($main::opt_focus ne '') {\n    $profile = FocusProfile($symbols, $profile, $main::opt_focus);\n  }\n\n  # Ignore?\n  if ($main::opt_ignore ne '') {\n    $profile = IgnoreProfile($symbols, $profile, $main::opt_ignore);\n  }\n\n  my $calls = ExtractCalls($symbols, $profile);\n\n  # Reduce profiles to required output granularity, and also clean\n  # each stack trace so a given entry exists at most once.\n  my $reduced = ReduceProfile($symbols, $profile);\n\n  # Get derived profiles\n  my $flat = FlatProfile($reduced);\n  my $cumulative = CumulativeProfile($reduced);\n\n  # Print\n  if (!$main::opt_interactive) {\n    if ($main::opt_disasm) {\n      PrintDisassembly($libs, $flat, $cumulative, $main::opt_disasm, $total);\n    } elsif ($main::opt_list) {\n      PrintListing($libs, $flat, $cumulative, $main::opt_list);\n    } elsif ($main::opt_text) {\n      # Make sure the output is empty when have nothing to report\n      # (only matters when --heapcheck is given but we must be\n      # compatible with old branches that did not pass --heapcheck always):\n      if ($total != 0) {\n        printf(\"Total: %s %s\\n\", Unparse($total), Units());\n      }\n      PrintText($symbols, $flat, $cumulative, $total, -1);\n    } elsif ($main::opt_raw) {\n      PrintSymbolizedProfile($symbols, $profile, $main::prog);\n    } elsif ($main::opt_callgrind) {\n      PrintCallgrind($calls);\n    } else {\n      if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {\n        if ($main::opt_gv) {\n          RunGV(TempName($main::next_tmpfile, \"ps\"), \"\");\n        } elsif ($main::opt_evince) {\n\t  RunEvince(TempName($main::next_tmpfile, \"pdf\"), \"\");\n        } elsif ($main::opt_web) {\n          my $tmp = TempName($main::next_tmpfile, \"svg\");\n          RunWeb($tmp);\n          # The command we run might hand the file name off\n          # to an already running browser instance and then exit.\n          # Normally, we'd remove $tmp on exit (right now),\n          # but fork a child to remove $tmp a little later, so that the\n          # browser has time to load it first.\n          delete $main::tempnames{$tmp};\n          if (fork() == 0) {\n            sleep 5;\n            unlink($tmp);\n            exit(0);\n          }\n        }\n      } else {\n        cleanup();\n        exit(1);\n      }\n    }\n  } else {\n    InteractiveMode($profile, $symbols, $libs, $total);\n  }\n\n  cleanup();\n  exit(0);\n}\n\n##### Entry Point #####\n\nMain();\n\n# Temporary code to detect if we're running on a Goobuntu system.\n# These systems don't have the right stuff installed for the special\n# Readline libraries to work, so as a temporary workaround, we default\n# to using the normal stdio code, rather than the fancier readline-based\n# code\nsub ReadlineMightFail {\n  if (-e '/lib/libtermcap.so.2') {\n    return 0;  # libtermcap exists, so readline should be okay\n  } else {\n    return 1;\n  }\n}\n\nsub RunGV {\n  my $fname = shift;\n  my $bg = shift;       # \"\" or \" &\" if we should run in background\n  if (!system(\"$GV --version >/dev/null 2>&1\")) {\n    # Options using double dash are supported by this gv version.\n    # Also, turn on noantialias to better handle bug in gv for\n    # postscript files with large dimensions.\n    # TODO: Maybe we should not pass the --noantialias flag\n    # if the gv version is known to work properly without the flag.\n    system(\"$GV --scale=$main::opt_scale --noantialias \" . $fname . $bg);\n  } else {\n    # Old gv version - only supports options that use single dash.\n    print STDERR \"$GV -scale $main::opt_scale\\n\";\n    system(\"$GV -scale $main::opt_scale \" . $fname . $bg);\n  }\n}\n\nsub RunEvince {\n  my $fname = shift;\n  my $bg = shift;       # \"\" or \" &\" if we should run in background\n  system(\"$EVINCE \" . $fname . $bg);\n}\n\nsub RunWeb {\n  my $fname = shift;\n  print STDERR \"Loading web page file:///$fname\\n\";\n\n  if (`uname` =~ /Darwin/) {\n    # OS X: open will use standard preference for SVG files.\n    system(\"/usr/bin/open\", $fname);\n    return;\n  }\n\n  # Some kind of Unix; try generic symlinks, then specific browsers.\n  # (Stop once we find one.)\n  # Works best if the browser is already running.\n  my @alt = (\n    \"/etc/alternatives/gnome-www-browser\",\n    \"/etc/alternatives/x-www-browser\",\n    \"google-chrome\",\n    \"firefox\",\n  );\n  foreach my $b (@alt) {\n    if (system($b, $fname) == 0) {\n      return;\n    }\n  }\n\n  print STDERR \"Could not load web browser.\\n\";\n}\n\nsub RunKcachegrind {\n  my $fname = shift;\n  my $bg = shift;       # \"\" or \" &\" if we should run in background\n  print STDERR \"Starting '$KCACHEGRIND \" . $fname . $bg . \"'\\n\";\n  system(\"$KCACHEGRIND \" . $fname . $bg);\n}\n\n\n##### Interactive helper routines #####\n\nsub InteractiveMode {\n  $| = 1;  # Make output unbuffered for interactive mode\n  my ($orig_profile, $symbols, $libs, $total) = @_;\n\n  print STDERR \"Welcome to pprof!  For help, type 'help'.\\n\";\n\n  # Use ReadLine if it's installed and input comes from a console.\n  if ( -t STDIN &&\n       !ReadlineMightFail() &&\n       defined(eval {require Term::ReadLine}) ) {\n    my $term = new Term::ReadLine 'pprof';\n    while ( defined ($_ = $term->readline('(pprof) '))) {\n      $term->addhistory($_) if /\\S/;\n      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {\n        last;    # exit when we get an interactive command to quit\n      }\n    }\n  } else {       # don't have readline\n    while (1) {\n      print STDERR \"(pprof) \";\n      $_ = <STDIN>;\n      last if ! defined $_ ;\n      s/\\r//g;         # turn windows-looking lines into unix-looking lines\n\n      # Save some flags that might be reset by InteractiveCommand()\n      my $save_opt_lines = $main::opt_lines;\n\n      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {\n        last;    # exit when we get an interactive command to quit\n      }\n\n      # Restore flags\n      $main::opt_lines = $save_opt_lines;\n    }\n  }\n}\n\n# Takes two args: orig profile, and command to run.\n# Returns 1 if we should keep going, or 0 if we were asked to quit\nsub InteractiveCommand {\n  my($orig_profile, $symbols, $libs, $total, $command) = @_;\n  $_ = $command;                # just to make future m//'s easier\n  if (!defined($_)) {\n    print STDERR \"\\n\";\n    return 0;\n  }\n  if (m/^\\s*quit/) {\n    return 0;\n  }\n  if (m/^\\s*help/) {\n    InteractiveHelpMessage();\n    return 1;\n  }\n  # Clear all the mode options -- mode is controlled by \"$command\"\n  $main::opt_text = 0;\n  $main::opt_callgrind = 0;\n  $main::opt_disasm = 0;\n  $main::opt_list = 0;\n  $main::opt_gv = 0;\n  $main::opt_evince = 0;\n  $main::opt_cum = 0;\n\n  if (m/^\\s*(text|top)(\\d*)\\s*(.*)/) {\n    $main::opt_text = 1;\n\n    my $line_limit = ($2 ne \"\") ? int($2) : 10;\n\n    my $routine;\n    my $ignore;\n    ($routine, $ignore) = ParseInteractiveArgs($3);\n\n    my $profile = ProcessProfile($orig_profile, $symbols, \"\", $ignore);\n    my $reduced = ReduceProfile($symbols, $profile);\n\n    # Get derived profiles\n    my $flat = FlatProfile($reduced);\n    my $cumulative = CumulativeProfile($reduced);\n\n    PrintText($symbols, $flat, $cumulative, $total, $line_limit);\n    return 1;\n  }\n  if (m/^\\s*callgrind\\s*([^ \\n]*)/) {\n    $main::opt_callgrind = 1;\n\n    # Get derived profiles\n    my $calls = ExtractCalls($symbols, $orig_profile);\n    my $filename = $1;\n    if ( $1 eq '' ) {\n      $filename = TempName($main::next_tmpfile, \"callgrind\");\n    }\n    PrintCallgrind($calls, $filename);\n    if ( $1 eq '' ) {\n      RunKcachegrind($filename, \" & \");\n      $main::next_tmpfile++;\n    }\n\n    return 1;\n  }\n  if (m/^\\s*list\\s*(.+)/) {\n    $main::opt_list = 1;\n\n    my $routine;\n    my $ignore;\n    ($routine, $ignore) = ParseInteractiveArgs($1);\n\n    my $profile = ProcessProfile($orig_profile, $symbols, \"\", $ignore);\n    my $reduced = ReduceProfile($symbols, $profile);\n\n    # Get derived profiles\n    my $flat = FlatProfile($reduced);\n    my $cumulative = CumulativeProfile($reduced);\n\n    PrintListing($libs, $flat, $cumulative, $routine);\n    return 1;\n  }\n  if (m/^\\s*disasm\\s*(.+)/) {\n    $main::opt_disasm = 1;\n\n    my $routine;\n    my $ignore;\n    ($routine, $ignore) = ParseInteractiveArgs($1);\n\n    # Process current profile to account for various settings\n    my $profile = ProcessProfile($orig_profile, $symbols, \"\", $ignore);\n    my $reduced = ReduceProfile($symbols, $profile);\n\n    # Get derived profiles\n    my $flat = FlatProfile($reduced);\n    my $cumulative = CumulativeProfile($reduced);\n\n    PrintDisassembly($libs, $flat, $cumulative, $routine, $total);\n    return 1;\n  }\n  if (m/^\\s*(gv|web|evince)\\s*(.*)/) {\n    $main::opt_gv = 0;\n    $main::opt_evince = 0;\n    $main::opt_web = 0;\n    if ($1 eq \"gv\") {\n      $main::opt_gv = 1;\n    } elsif ($1 eq \"evince\") {\n      $main::opt_evince = 1;\n    } elsif ($1 eq \"web\") {\n      $main::opt_web = 1;\n    }\n\n    my $focus;\n    my $ignore;\n    ($focus, $ignore) = ParseInteractiveArgs($2);\n\n    # Process current profile to account for various settings\n    my $profile = ProcessProfile($orig_profile, $symbols, $focus, $ignore);\n    my $reduced = ReduceProfile($symbols, $profile);\n\n    # Get derived profiles\n    my $flat = FlatProfile($reduced);\n    my $cumulative = CumulativeProfile($reduced);\n\n    if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {\n      if ($main::opt_gv) {\n        RunGV(TempName($main::next_tmpfile, \"ps\"), \" &\");\n      } elsif ($main::opt_evince) {\n        RunEvince(TempName($main::next_tmpfile, \"pdf\"), \" &\");\n      } elsif ($main::opt_web) {\n        RunWeb(TempName($main::next_tmpfile, \"svg\"));\n      }\n      $main::next_tmpfile++;\n    }\n    return 1;\n  }\n  if (m/^\\s*$/) {\n    return 1;\n  }\n  print STDERR \"Unknown command: try 'help'.\\n\";\n  return 1;\n}\n\n\nsub ProcessProfile {\n  my $orig_profile = shift;\n  my $symbols = shift;\n  my $focus = shift;\n  my $ignore = shift;\n\n  # Process current profile to account for various settings\n  my $profile = $orig_profile;\n  my $total_count = TotalProfile($profile);\n  printf(\"Total: %s %s\\n\", Unparse($total_count), Units());\n  if ($focus ne '') {\n    $profile = FocusProfile($symbols, $profile, $focus);\n    my $focus_count = TotalProfile($profile);\n    printf(\"After focusing on '%s': %s %s of %s (%0.1f%%)\\n\",\n           $focus,\n           Unparse($focus_count), Units(),\n           Unparse($total_count), ($focus_count*100.0) / $total_count);\n  }\n  if ($ignore ne '') {\n    $profile = IgnoreProfile($symbols, $profile, $ignore);\n    my $ignore_count = TotalProfile($profile);\n    printf(\"After ignoring '%s': %s %s of %s (%0.1f%%)\\n\",\n           $ignore,\n           Unparse($ignore_count), Units(),\n           Unparse($total_count),\n           ($ignore_count*100.0) / $total_count);\n  }\n\n  return $profile;\n}\n\nsub InteractiveHelpMessage {\n  print STDERR <<ENDOFHELP;\nInteractive pprof mode\n\nCommands:\n  gv\n  gv [focus] [-ignore1] [-ignore2]\n      Show graphical hierarchical display of current profile.  Without\n      any arguments, shows all samples in the profile.  With the optional\n      \"focus\" argument, restricts the samples shown to just those where\n      the \"focus\" regular expression matches a routine name on the stack\n      trace.\n\n  web\n  web [focus] [-ignore1] [-ignore2]\n      Like GV, but displays profile in your web browser instead of using\n      Ghostview. Works best if your web browser is already running.\n      To change the browser that gets used:\n      On Linux, set the /etc/alternatives/gnome-www-browser symlink.\n      On OS X, change the Finder association for SVG files.\n\n  list [routine_regexp] [-ignore1] [-ignore2]\n      Show source listing of routines whose names match \"routine_regexp\"\n\n  top [--cum] [-ignore1] [-ignore2]\n  top20 [--cum] [-ignore1] [-ignore2]\n  top37 [--cum] [-ignore1] [-ignore2]\n      Show top lines ordered by flat profile count, or cumulative count\n      if --cum is specified.  If a number is present after 'top', the\n      top K routines will be shown (defaults to showing the top 10)\n\n  disasm [routine_regexp] [-ignore1] [-ignore2]\n      Show disassembly of routines whose names match \"routine_regexp\",\n      annotated with sample counts.\n\n  callgrind\n  callgrind [filename]\n      Generates callgrind file. If no filename is given, kcachegrind is called.\n\n  help - This listing\n  quit or ^D - End pprof\n\nFor commands that accept optional -ignore tags, samples where any routine in\nthe stack trace matches the regular expression in any of the -ignore\nparameters will be ignored.\n\nFurther pprof details are available at this location (or one similar):\n\n /usr/doc/google-perftools-$PPROF_VERSION/cpu_profiler.html\n /usr/doc/google-perftools-$PPROF_VERSION/heap_profiler.html\n\nENDOFHELP\n}\nsub ParseInteractiveArgs {\n  my $args = shift;\n  my $focus = \"\";\n  my $ignore = \"\";\n  my @x = split(/ +/, $args);\n  foreach $a (@x) {\n    if ($a =~ m/^(--|-)lines$/) {\n      $main::opt_lines = 1;\n    } elsif ($a =~ m/^(--|-)cum$/) {\n      $main::opt_cum = 1;\n    } elsif ($a =~ m/^-(.*)/) {\n      $ignore .= (($ignore ne \"\") ? \"|\" : \"\" ) . $1;\n    } else {\n      $focus .= (($focus ne \"\") ? \"|\" : \"\" ) . $a;\n    }\n  }\n  if ($ignore ne \"\") {\n    print STDERR \"Ignoring samples in call stacks that match '$ignore'\\n\";\n  }\n  return ($focus, $ignore);\n}\n\n##### Output code #####\n\nsub TempName {\n  my $fnum = shift;\n  my $ext = shift;\n  my $file = \"$main::tmpfile_ps.$fnum.$ext\";\n  $main::tempnames{$file} = 1;\n  return $file;\n}\n\n# Print profile data in packed binary format (64-bit) to standard out\nsub PrintProfileData {\n  my $profile = shift;\n\n  # print header (64-bit style)\n  # (zero) (header-size) (version) (sample-period) (zero)\n  print pack('L*', 0, 0, 3, 0, 0, 0, 1, 0, 0, 0);\n\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @addrs = split(/\\n/, $k);\n    if ($#addrs >= 0) {\n      my $depth = $#addrs + 1;\n      # int(foo / 2**32) is the only reliable way to get rid of bottom\n      # 32 bits on both 32- and 64-bit systems.\n      print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32));\n      print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32));\n\n      foreach my $full_addr (@addrs) {\n        my $addr = $full_addr;\n        $addr =~ s/0x0*//;  # strip off leading 0x, zeroes\n        if (length($addr) > 16) {\n          print STDERR \"Invalid address in profile: $full_addr\\n\";\n          next;\n        }\n        my $low_addr = substr($addr, -8);       # get last 8 hex chars\n        my $high_addr = substr($addr, -16, 8);  # get up to 8 more hex chars\n        print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr));\n      }\n    }\n  }\n}\n\n# Print symbols and profile data\nsub PrintSymbolizedProfile {\n  my $symbols = shift;\n  my $profile = shift;\n  my $prog = shift;\n\n  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $symbol_marker = $&;\n\n  print '--- ', $symbol_marker, \"\\n\";\n  if (defined($prog)) {\n    print 'binary=', $prog, \"\\n\";\n  }\n  while (my ($pc, $name) = each(%{$symbols})) {\n    my $sep = ' ';\n    print '0x', $pc;\n    # We have a list of function names, which include the inlined\n    # calls.  They are separated (and terminated) by --, which is\n    # illegal in function names.\n    for (my $j = 2; $j <= $#{$name}; $j += 3) {\n      print $sep, $name->[$j];\n      $sep = '--';\n    }\n    print \"\\n\";\n  }\n  print '---', \"\\n\";\n\n  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $profile_marker = $&;\n  print '--- ', $profile_marker, \"\\n\";\n  if (defined($main::collected_profile)) {\n    # if used with remote fetch, simply dump the collected profile to output.\n    open(SRC, \"<$main::collected_profile\");\n    while (<SRC>) {\n      print $_;\n    }\n    close(SRC);\n  } else {\n    # dump a cpu-format profile to standard out\n    PrintProfileData($profile);\n  }\n}\n\n# Print text output\nsub PrintText {\n  my $symbols = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $total = shift;\n  my $line_limit = shift;\n\n  # Which profile to sort by?\n  my $s = $main::opt_cum ? $cumulative : $flat;\n\n  my $running_sum = 0;\n  my $lines = 0;\n  foreach my $k (sort { GetEntry($s, $b) <=> GetEntry($s, $a) || $a cmp $b }\n                 keys(%{$cumulative})) {\n    my $f = GetEntry($flat, $k);\n    my $c = GetEntry($cumulative, $k);\n    $running_sum += $f;\n\n    my $sym = $k;\n    if (exists($symbols->{$k})) {\n      $sym = $symbols->{$k}->[0] . \" \" . $symbols->{$k}->[1];\n      if ($main::opt_addresses) {\n        $sym = $k . \" \" . $sym;\n      }\n    }\n\n    if ($f != 0 || $c != 0) {\n      printf(\"%8s %6s %6s %8s %6s %s\\n\",\n             Unparse($f),\n             Percent($f, $total),\n             Percent($running_sum, $total),\n             Unparse($c),\n             Percent($c, $total),\n             $sym);\n    }\n    $lines++;\n    last if ($line_limit >= 0 && $lines > $line_limit);\n  }\n}\n\n# Print the call graph in a way that's suiteable for callgrind.\nsub PrintCallgrind {\n  my $calls = shift;\n  my $filename;\n  if ($main::opt_interactive) {\n    $filename = shift;\n    print STDERR \"Writing callgrind file to '$filename'.\\n\"\n  } else {\n    $filename = \"&STDOUT\";\n  }\n  open(CG, \">\".$filename );\n  printf CG (\"events: Hits\\n\\n\");\n  foreach my $call ( map { $_->[0] }\n                     sort { $a->[1] cmp $b ->[1] ||\n                            $a->[2] <=> $b->[2] }\n                     map { /([^:]+):(\\d+):([^ ]+)( -> ([^:]+):(\\d+):(.+))?/;\n                           [$_, $1, $2] }\n                     keys %$calls ) {\n    my $count = int($calls->{$call});\n    $call =~ /([^:]+):(\\d+):([^ ]+)( -> ([^:]+):(\\d+):(.+))?/;\n    my ( $caller_file, $caller_line, $caller_function,\n         $callee_file, $callee_line, $callee_function ) =\n       ( $1, $2, $3, $5, $6, $7 );\n\n      \n    printf CG (\"fl=$caller_file\\nfn=$caller_function\\n\");\n    if (defined $6) {\n      printf CG (\"cfl=$callee_file\\n\");\n      printf CG (\"cfn=$callee_function\\n\");\n      printf CG (\"calls=$count $callee_line\\n\");\n    }\n    printf CG (\"$caller_line $count\\n\\n\");\n  }\n}\n\n# Print disassembly for all all routines that match $main::opt_disasm\nsub PrintDisassembly {\n  my $libs = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $disasm_opts = shift;\n  my $total = shift;\n\n  foreach my $lib (@{$libs}) {\n    my $symbol_table = GetProcedureBoundaries($lib->[0], $disasm_opts);\n    my $offset = AddressSub($lib->[1], $lib->[3]);\n    foreach my $routine (sort ByName keys(%{$symbol_table})) {\n      my $start_addr = $symbol_table->{$routine}->[0];\n      my $end_addr = $symbol_table->{$routine}->[1];\n      # See if there are any samples in this routine\n      my $length = hex(AddressSub($end_addr, $start_addr));\n      my $addr = AddressAdd($start_addr, $offset);\n      for (my $i = 0; $i < $length; $i++) {\n        if (defined($cumulative->{$addr})) {\n          PrintDisassembledFunction($lib->[0], $offset,\n                                    $routine, $flat, $cumulative,\n                                    $start_addr, $end_addr, $total);\n          last;\n        }\n        $addr = AddressInc($addr);\n      }\n    }\n  }\n}\n\n# Return reference to array of tuples of the form:\n#       [start_address, filename, linenumber, instruction, limit_address]\n# E.g.,\n#       [\"0x806c43d\", \"/foo/bar.cc\", 131, \"ret\", \"0x806c440\"]\nsub Disassemble {\n  my $prog = shift;\n  my $offset = shift;\n  my $start_addr = shift;\n  my $end_addr = shift;\n\n  my $objdump = $obj_tool_map{\"objdump\"};\n  my $cmd = sprintf(\"$objdump -C -d -l --no-show-raw-insn \" .\n                    \"--start-address=0x$start_addr \" .\n                    \"--stop-address=0x$end_addr $prog\");\n  open(OBJDUMP, \"$cmd |\") || error(\"$objdump: $!\\n\");\n  my @result = ();\n  my $filename = \"\";\n  my $linenumber = -1;\n  my $last = [\"\", \"\", \"\", \"\"];\n  while (<OBJDUMP>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    chop;\n    if (m|\\s*([^:\\s]+):(\\d+)\\s*$|) {\n      # Location line of the form:\n      #   <filename>:<linenumber>\n      $filename = $1;\n      $linenumber = $2;\n    } elsif (m/^ +([0-9a-f]+):\\s*(.*)/) {\n      # Disassembly line -- zero-extend address to full length\n      my $addr = HexExtend($1);\n      my $k = AddressAdd($addr, $offset);\n      $last->[4] = $k;   # Store ending address for previous instruction\n      $last = [$k, $filename, $linenumber, $2, $end_addr];\n      push(@result, $last);\n    }\n  }\n  close(OBJDUMP);\n  return @result;\n}\n\n# The input file should contain lines of the form /proc/maps-like\n# output (same format as expected from the profiles) or that looks\n# like hex addresses (like \"0xDEADBEEF\").  We will parse all\n# /proc/maps output, and for all the hex addresses, we will output\n# \"short\" symbol names, one per line, in the same order as the input.\nsub PrintSymbols {\n  my $maps_and_symbols_file = shift;\n\n  # ParseLibraries expects pcs to be in a set.  Fine by us...\n  my @pclist = ();   # pcs in sorted order\n  my $pcs = {};\n  my $map = \"\";\n  foreach my $line (<$maps_and_symbols_file>) {\n    $line =~ s/\\r//g;    # turn windows-looking lines into unix-looking lines\n    if ($line =~ /\\b(0x[0-9a-f]+)\\b/i) {\n      push(@pclist, HexExtend($1));\n      $pcs->{$pclist[-1]} = 1;\n    } else {\n      $map .= $line;\n    }\n  }\n\n  my $libs = ParseLibraries($main::prog, $map, $pcs);\n  my $symbols = ExtractSymbols($libs, $pcs);\n\n  foreach my $pc (@pclist) {\n    # ->[0] is the shortname, ->[2] is the full name\n    print(($symbols->{$pc}->[0] || \"??\") . \"\\n\");\n  }\n}\n\n\n# For sorting functions by name\nsub ByName {\n  return ShortFunctionName($a) cmp ShortFunctionName($b);\n}\n\n# Print source-listing for all all routines that match $main::opt_list\nsub PrintListing {\n  my $libs = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $list_opts = shift;\n\n  foreach my $lib (@{$libs}) {\n    my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts);\n    my $offset = AddressSub($lib->[1], $lib->[3]);\n    foreach my $routine (sort ByName keys(%{$symbol_table})) {\n      # Print if there are any samples in this routine\n      my $start_addr = $symbol_table->{$routine}->[0];\n      my $end_addr = $symbol_table->{$routine}->[1];\n      my $length = hex(AddressSub($end_addr, $start_addr));\n      my $addr = AddressAdd($start_addr, $offset);\n      for (my $i = 0; $i < $length; $i++) {\n        if (defined($cumulative->{$addr})) {\n          PrintSource($lib->[0], $offset,\n                      $routine, $flat, $cumulative,\n                      $start_addr, $end_addr);\n          last;\n        }\n        $addr = AddressInc($addr);\n      }\n    }\n  }\n}\n\n# Returns the indentation of the line, if it has any non-whitespace\n# characters.  Otherwise, returns -1.\nsub Indentation {\n  my $line = shift;\n  if (m/^(\\s*)\\S/) {\n    return length($1);\n  } else {\n    return -1;\n  }\n}\n\n# Print source-listing for one routine\nsub PrintSource {\n  my $prog = shift;\n  my $offset = shift;\n  my $routine = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $start_addr = shift;\n  my $end_addr = shift;\n\n  # Disassemble all instructions (just to get line numbers)\n  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);\n\n  # Hack 1: assume that the first source file encountered in the\n  # disassembly contains the routine\n  my $filename = undef;\n  for (my $i = 0; $i <= $#instructions; $i++) {\n    if ($instructions[$i]->[2] >= 0) {\n      $filename = $instructions[$i]->[1];\n      last;\n    }\n  }\n  if (!defined($filename)) {\n    print STDERR \"no filename found in $routine\\n\";\n    return;\n  }\n\n  # Hack 2: assume that the largest line number from $filename is the\n  # end of the procedure.  This is typically safe since if P1 contains\n  # an inlined call to P2, then P2 usually occurs earlier in the\n  # source file.  If this does not work, we might have to compute a\n  # density profile or just print all regions we find.\n  my $lastline = 0;\n  for (my $i = 0; $i <= $#instructions; $i++) {\n    my $f = $instructions[$i]->[1];\n    my $l = $instructions[$i]->[2];\n    if (($f eq $filename) && ($l > $lastline)) {\n      $lastline = $l;\n    }\n  }\n\n  # Hack 3: assume the first source location from \"filename\" is the start of\n  # the source code.\n  my $firstline = 1;\n  for (my $i = 0; $i <= $#instructions; $i++) {\n    if ($instructions[$i]->[1] eq $filename) {\n      $firstline = $instructions[$i]->[2];\n      last;\n    }\n  }\n\n  # Hack 4: Extend last line forward until its indentation is less than\n  # the indentation we saw on $firstline\n  my $oldlastline = $lastline;\n  {\n    if (!open(FILE, \"<$filename\")) {\n      print STDERR \"$filename: $!\\n\";\n      return;\n    }\n    my $l = 0;\n    my $first_indentation = -1;\n    while (<FILE>) {\n      s/\\r//g;         # turn windows-looking lines into unix-looking lines\n      $l++;\n      my $indent = Indentation($_);\n      if ($l >= $firstline) {\n        if ($first_indentation < 0 && $indent >= 0) {\n          $first_indentation = $indent;\n          last if ($first_indentation == 0);\n        }\n      }\n      if ($l >= $lastline && $indent >= 0) {\n        if ($indent >= $first_indentation) {\n          $lastline = $l+1;\n        } else {\n          last;\n        }\n      }\n    }\n    close(FILE);\n  }\n\n  # Assign all samples to the range $firstline,$lastline,\n  # Hack 4: If an instruction does not occur in the range, its samples\n  # are moved to the next instruction that occurs in the range.\n  my $samples1 = {};\n  my $samples2 = {};\n  my $running1 = 0;     # Unassigned flat counts\n  my $running2 = 0;     # Unassigned cumulative counts\n  my $total1 = 0;       # Total flat counts\n  my $total2 = 0;       # Total cumulative counts\n  foreach my $e (@instructions) {\n    # Add up counts for all address that fall inside this instruction\n    my $c1 = 0;\n    my $c2 = 0;\n    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {\n      $c1 += GetEntry($flat, $a);\n      $c2 += GetEntry($cumulative, $a);\n    }\n    $running1 += $c1;\n    $running2 += $c2;\n    $total1 += $c1;\n    $total2 += $c2;\n    my $file = $e->[1];\n    my $line = $e->[2];\n    if (($file eq $filename) &&\n        ($line >= $firstline) &&\n        ($line <= $lastline)) {\n      # Assign all accumulated samples to this line\n      AddEntry($samples1, $line, $running1);\n      AddEntry($samples2, $line, $running2);\n      $running1 = 0;\n      $running2 = 0;\n    }\n  }\n\n  # Assign any leftover samples to $lastline\n  AddEntry($samples1, $lastline, $running1);\n  AddEntry($samples2, $lastline, $running2);\n\n  printf(\"ROUTINE ====================== %s in %s\\n\" .\n         \"%6s %6s Total %s (flat / cumulative)\\n\",\n         ShortFunctionName($routine),\n         $filename,\n         Units(),\n         Unparse($total1),\n         Unparse($total2));\n  if (!open(FILE, \"<$filename\")) {\n    print STDERR \"$filename: $!\\n\";\n    return;\n  }\n  my $l = 0;\n  while (<FILE>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    $l++;\n    if ($l >= $firstline - 5 &&\n        (($l <= $oldlastline + 5) || ($l <= $lastline))) {\n      chop;\n      my $text = $_;\n      if ($l == $firstline) { printf(\"---\\n\"); }\n      printf(\"%6s %6s %4d: %s\\n\",\n             UnparseAlt(GetEntry($samples1, $l)),\n             UnparseAlt(GetEntry($samples2, $l)),\n             $l,\n             $text);\n      if ($l == $lastline)  { printf(\"---\\n\"); }\n    };\n  }\n  close(FILE);\n}\n\n# Return the source line for the specified file/linenumber.\n# Returns undef if not found.\nsub SourceLine {\n  my $file = shift;\n  my $line = shift;\n\n  # Look in cache\n  if (!defined($main::source_cache{$file})) {\n    if (100 < scalar keys(%main::source_cache)) {\n      # Clear the cache when it gets too big\n      $main::source_cache = ();\n    }\n\n    # Read all lines from the file\n    if (!open(FILE, \"<$file\")) {\n      print STDERR \"$file: $!\\n\";\n      $main::source_cache{$file} = [];  # Cache the negative result\n      return undef;\n    }\n    my $lines = [];\n    push(@{$lines}, \"\");        # So we can use 1-based line numbers as indices\n    while (<FILE>) {\n      push(@{$lines}, $_);\n    }\n    close(FILE);\n\n    # Save the lines in the cache\n    $main::source_cache{$file} = $lines;\n  }\n\n  my $lines = $main::source_cache{$file};\n  if (($line < 0) || ($line > $#{$lines})) {\n    return undef;\n  } else {\n    return $lines->[$line];\n  }\n}\n\n# Print disassembly for one routine with interspersed source if available\nsub PrintDisassembledFunction {\n  my $prog = shift;\n  my $offset = shift;\n  my $routine = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $start_addr = shift;\n  my $end_addr = shift;\n  my $total = shift;\n\n  # Disassemble all instructions\n  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);\n\n  # Make array of counts per instruction\n  my @flat_count = ();\n  my @cum_count = ();\n  my $flat_total = 0;\n  my $cum_total = 0;\n  foreach my $e (@instructions) {\n    # Add up counts for all address that fall inside this instruction\n    my $c1 = 0;\n    my $c2 = 0;\n    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {\n      $c1 += GetEntry($flat, $a);\n      $c2 += GetEntry($cumulative, $a);\n    }\n    push(@flat_count, $c1);\n    push(@cum_count, $c2);\n    $flat_total += $c1;\n    $cum_total += $c2;\n  }\n\n  # Print header with total counts\n  printf(\"ROUTINE ====================== %s\\n\" .\n         \"%6s %6s %s (flat, cumulative) %.1f%% of total\\n\",\n         ShortFunctionName($routine),\n         Unparse($flat_total),\n         Unparse($cum_total),\n         Units(),\n         ($cum_total * 100.0) / $total);\n\n  # Process instructions in order\n  my $current_file = \"\";\n  for (my $i = 0; $i <= $#instructions; ) {\n    my $e = $instructions[$i];\n\n    # Print the new file name whenever we switch files\n    if ($e->[1] ne $current_file) {\n      $current_file = $e->[1];\n      my $fname = $current_file;\n      $fname =~ s|^\\./||;   # Trim leading \"./\"\n\n      # Shorten long file names\n      if (length($fname) >= 58) {\n        $fname = \"...\" . substr($fname, -55);\n      }\n      printf(\"-------------------- %s\\n\", $fname);\n    }\n\n    # TODO: Compute range of lines to print together to deal with\n    # small reorderings.\n    my $first_line = $e->[2];\n    my $last_line = $first_line;\n    my %flat_sum = ();\n    my %cum_sum = ();\n    for (my $l = $first_line; $l <= $last_line; $l++) {\n      $flat_sum{$l} = 0;\n      $cum_sum{$l} = 0;\n    }\n\n    # Find run of instructions for this range of source lines\n    my $first_inst = $i;\n    while (($i <= $#instructions) &&\n           ($instructions[$i]->[2] >= $first_line) &&\n           ($instructions[$i]->[2] <= $last_line)) {\n      $e = $instructions[$i];\n      $flat_sum{$e->[2]} += $flat_count[$i];\n      $cum_sum{$e->[2]} += $cum_count[$i];\n      $i++;\n    }\n    my $last_inst = $i - 1;\n\n    # Print source lines\n    for (my $l = $first_line; $l <= $last_line; $l++) {\n      my $line = SourceLine($current_file, $l);\n      if (!defined($line)) {\n        $line = \"?\\n\";\n        next;\n      } else {\n        $line =~ s/^\\s+//;\n      }\n      printf(\"%6s %6s %5d: %s\",\n             UnparseAlt($flat_sum{$l}),\n             UnparseAlt($cum_sum{$l}),\n             $l,\n             $line);\n    }\n\n    # Print disassembly\n    for (my $x = $first_inst; $x <= $last_inst; $x++) {\n      my $e = $instructions[$x];\n      my $address = $e->[0];\n      $address = AddressSub($address, $offset);  # Make relative to section\n      $address =~ s/^0x//;\n      $address =~ s/^0*//;\n\n      # Trim symbols\n      my $d = $e->[3];\n      while ($d =~ s/\\([^()%]*\\)(\\s*const)?//g) { } # Argument types, not (%rax)\n      while ($d =~ s/(\\w+)<[^<>]*>/$1/g)  { }       # Remove template arguments\n\n      printf(\"%6s %6s    %8s: %6s\\n\",\n             UnparseAlt($flat_count[$x]),\n             UnparseAlt($cum_count[$x]),\n             $address,\n             $d);\n    }\n  }\n}\n\n# Print DOT graph\nsub PrintDot {\n  my $prog = shift;\n  my $symbols = shift;\n  my $raw = shift;\n  my $flat = shift;\n  my $cumulative = shift;\n  my $overall_total = shift;\n\n  # Get total\n  my $local_total = TotalProfile($flat);\n  my $nodelimit = int($main::opt_nodefraction * $local_total);\n  my $edgelimit = int($main::opt_edgefraction * $local_total);\n  my $nodecount = $main::opt_nodecount;\n\n  # Find nodes to include\n  my @list = (sort { abs(GetEntry($cumulative, $b)) <=>\n                     abs(GetEntry($cumulative, $a))\n                     || $a cmp $b }\n              keys(%{$cumulative}));\n  my $last = $nodecount - 1;\n  if ($last > $#list) {\n    $last = $#list;\n  }\n  while (($last >= 0) &&\n         (abs(GetEntry($cumulative, $list[$last])) <= $nodelimit)) {\n    $last--;\n  }\n  if ($last < 0) {\n    print STDERR \"No nodes to print\\n\";\n    return 0;\n  }\n\n  if ($nodelimit > 0 || $edgelimit > 0) {\n    printf STDERR (\"Dropping nodes with <= %s %s; edges with <= %s abs(%s)\\n\",\n                   Unparse($nodelimit), Units(),\n                   Unparse($edgelimit), Units());\n  }\n\n  # Open DOT output file\n  my $output;\n  if ($main::opt_gv) {\n    $output = \"| $DOT -Tps2 >\" . TempName($main::next_tmpfile, \"ps\");\n  } elsif ($main::opt_evince) {\n    $output = \"| $DOT -Tps2 | $PS2PDF - \" . TempName($main::next_tmpfile, \"pdf\");\n  } elsif ($main::opt_ps) {\n    $output = \"| $DOT -Tps2\";\n  } elsif ($main::opt_pdf) {\n    $output = \"| $DOT -Tps2 | $PS2PDF - -\";\n  } elsif ($main::opt_web || $main::opt_svg) {\n    # We need to post-process the SVG, so write to a temporary file always.\n    $output = \"| $DOT -Tsvg >\" . TempName($main::next_tmpfile, \"svg\");\n  } elsif ($main::opt_gif) {\n    $output = \"| $DOT -Tgif\";\n  } else {\n    $output = \">&STDOUT\";\n  }\n  open(DOT, $output) || error(\"$output: $!\\n\");\n\n  # Title\n  printf DOT (\"digraph \\\"%s; %s %s\\\" {\\n\",\n              $prog,\n              Unparse($overall_total),\n              Units());\n  if ($main::opt_pdf) {\n    # The output is more printable if we set the page size for dot.\n    printf DOT (\"size=\\\"8,11\\\"\\n\");\n  }\n  printf DOT (\"node [width=0.375,height=0.25];\\n\");\n\n  # Print legend\n  printf DOT (\"Legend [shape=box,fontsize=24,shape=plaintext,\" .\n              \"label=\\\"%s\\\\l%s\\\\l%s\\\\l%s\\\\l%s\\\\l\\\"];\\n\",\n              $prog,\n              sprintf(\"Total %s: %s\", Units(), Unparse($overall_total)),\n              sprintf(\"Focusing on: %s\", Unparse($local_total)),\n              sprintf(\"Dropped nodes with <= %s abs(%s)\",\n                      Unparse($nodelimit), Units()),\n              sprintf(\"Dropped edges with <= %s %s\",\n                      Unparse($edgelimit), Units())\n              );\n\n  # Print nodes\n  my %node = ();\n  my $nextnode = 1;\n  foreach my $a (@list[0..$last]) {\n    # Pick font size\n    my $f = GetEntry($flat, $a);\n    my $c = GetEntry($cumulative, $a);\n\n    my $fs = 8;\n    if ($local_total > 0) {\n      $fs = 8 + (50.0 * sqrt(abs($f * 1.0 / $local_total)));\n    }\n\n    $node{$a} = $nextnode++;\n    my $sym = $a;\n    $sym =~ s/\\s+/\\\\n/g;\n    $sym =~ s/::/\\\\n/g;\n\n    # Extra cumulative info to print for non-leaves\n    my $extra = \"\";\n    if ($f != $c) {\n      $extra = sprintf(\"\\\\rof %s (%s)\",\n                       Unparse($c),\n                       Percent($c, $overall_total));\n    }\n    my $style = \"\";\n    if ($main::opt_heapcheck) {\n      if ($f > 0) {\n        # make leak-causing nodes more visible (add a background)\n        $style = \",style=filled,fillcolor=gray\"\n      } elsif ($f < 0) {\n        # make anti-leak-causing nodes (which almost never occur)\n        # stand out as well (triple border)\n        $style = \",peripheries=3\"\n      }\n    }\n\n    printf DOT (\"N%d [label=\\\"%s\\\\n%s (%s)%s\\\\r\" .\n                \"\\\",shape=box,fontsize=%.1f%s];\\n\",\n                $node{$a},\n                $sym,\n                Unparse($f),\n                Percent($f, $overall_total),\n                $extra,\n                $fs,\n                $style,\n               );\n  }\n\n  # Get edges and counts per edge\n  my %edge = ();\n  my $n;\n  foreach my $k (keys(%{$raw})) {\n    # TODO: omit low %age edges\n    $n = $raw->{$k};\n    my @translated = TranslateStack($symbols, $k);\n    for (my $i = 1; $i <= $#translated; $i++) {\n      my $src = $translated[$i];\n      my $dst = $translated[$i-1];\n      #next if ($src eq $dst);  # Avoid self-edges?\n      if (exists($node{$src}) && exists($node{$dst})) {\n        my $edge_label = \"$src\\001$dst\";\n        if (!exists($edge{$edge_label})) {\n          $edge{$edge_label} = 0;\n        }\n        $edge{$edge_label} += $n;\n      }\n    }\n  }\n\n  # Print edges (process in order of decreasing counts)\n  my %indegree = ();   # Number of incoming edges added per node so far\n  my %outdegree = ();  # Number of outgoing edges added per node so far\n  foreach my $e (sort { $edge{$b} <=> $edge{$a} } keys(%edge)) {\n    my @x = split(/\\001/, $e);\n    $n = $edge{$e};\n\n    # Initialize degree of kept incoming and outgoing edges if necessary\n    my $src = $x[0];\n    my $dst = $x[1];\n    if (!exists($outdegree{$src})) { $outdegree{$src} = 0; }\n    if (!exists($indegree{$dst})) { $indegree{$dst} = 0; }\n\n    my $keep;\n    if ($indegree{$dst} == 0) {\n      # Keep edge if needed for reachability\n      $keep = 1;\n    } elsif (abs($n) <= $edgelimit) {\n      # Drop if we are below --edgefraction\n      $keep = 0;\n    } elsif ($outdegree{$src} >= $main::opt_maxdegree ||\n             $indegree{$dst} >= $main::opt_maxdegree) {\n      # Keep limited number of in/out edges per node\n      $keep = 0;\n    } else {\n      $keep = 1;\n    }\n\n    if ($keep) {\n      $outdegree{$src}++;\n      $indegree{$dst}++;\n\n      # Compute line width based on edge count\n      my $fraction = abs($local_total ? (3 * ($n / $local_total)) : 0);\n      if ($fraction > 1) { $fraction = 1; }\n      my $w = $fraction * 2;\n      if ($w < 1 && ($main::opt_web || $main::opt_svg)) {\n        # SVG output treats line widths < 1 poorly.\n        $w = 1;\n      }\n\n      # Dot sometimes segfaults if given edge weights that are too large, so\n      # we cap the weights at a large value\n      my $edgeweight = abs($n) ** 0.7;\n      if ($edgeweight > 100000) { $edgeweight = 100000; }\n      $edgeweight = int($edgeweight);\n\n      my $style = sprintf(\"setlinewidth(%f)\", $w);\n      if ($x[1] =~ m/\\(inline\\)/) {\n        $style .= \",dashed\";\n      }\n\n      # Use a slightly squashed function of the edge count as the weight\n      printf DOT (\"N%s -> N%s [label=%s, weight=%d, style=\\\"%s\\\"];\\n\",\n                  $node{$x[0]},\n                  $node{$x[1]},\n                  Unparse($n),\n                  $edgeweight,\n                  $style);\n    }\n  }\n\n  print DOT (\"}\\n\");\n  close(DOT);\n\n  if ($main::opt_web || $main::opt_svg) {\n    # Rewrite SVG to be more usable inside web browser.\n    RewriteSvg(TempName($main::next_tmpfile, \"svg\"));\n  }\n\n  return 1;\n}\n\nsub RewriteSvg {\n  my $svgfile = shift;\n\n  open(SVG, $svgfile) || die \"open temp svg: $!\";\n  my @svg = <SVG>;\n  close(SVG);\n  unlink $svgfile;\n  my $svg = join('', @svg);\n\n  # Dot's SVG output is\n  #\n  #    <svg width=\"___\" height=\"___\"\n  #     viewBox=\"___\" xmlns=...>\n  #    <g id=\"graph0\" transform=\"...\">\n  #    ...\n  #    </g>\n  #    </svg>\n  #\n  # Change it to\n  #\n  #    <svg width=\"100%\" height=\"100%\"\n  #     xmlns=...>\n  #    $svg_javascript\n  #    <g id=\"viewport\" transform=\"translate(0,0)\">\n  #    <g id=\"graph0\" transform=\"...\">\n  #    ...\n  #    </g>\n  #    </g>\n  #    </svg>\n\n  # Fix width, height; drop viewBox.\n  $svg =~ s/(?s)<svg width=\"[^\"]+\" height=\"[^\"]+\"(.*?)viewBox=\"[^\"]+\"/<svg width=\"100%\" height=\"100%\"$1/;\n\n  # Insert script, viewport <g> above first <g>\n  my $svg_javascript = SvgJavascript();\n  my $viewport = \"<g id=\\\"viewport\\\" transform=\\\"translate(0,0)\\\">\\n\";\n  $svg =~ s/<g id=\"graph\\d\"/$svg_javascript$viewport$&/;\n\n  # Insert final </g> above </svg>.\n  $svg =~ s/(.*)(<\\/svg>)/$1<\\/g>$2/;\n  $svg =~ s/<g id=\"graph\\d\"(.*?)/<g id=\"viewport\"$1/;\n\n  if ($main::opt_svg) {\n    # --svg: write to standard output.\n    print $svg;\n  } else {\n    # Write back to temporary file.\n    open(SVG, \">$svgfile\") || die \"open $svgfile: $!\";\n    print SVG $svg;\n    close(SVG);\n  }\n}\n\nsub SvgJavascript {\n  return <<'EOF';\n<script type=\"text/ecmascript\"><![CDATA[\n// SVGPan\n// http://www.cyberz.org/blog/2009/12/08/svgpan-a-javascript-svg-panzoomdrag-library/\n// Local modification: if(true || ...) below to force panning, never moving.\n\n/**\n *  SVGPan library 1.2\n * ====================\n *\n * Given an unique existing element with id \"viewport\", including the\n * the library into any SVG adds the following capabilities:\n *\n *  - Mouse panning\n *  - Mouse zooming (using the wheel)\n *  - Object dargging\n *\n * Known issues:\n *\n *  - Zooming (while panning) on Safari has still some issues\n *\n * Releases:\n *\n * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui\n *\tFixed a bug with browser mouse handler interaction\n *\n * 1.1, Wed Feb  3 17:39:33 GMT 2010, Zeng Xiaohui\n *\tUpdated the zoom code to support the mouse wheel on Safari/Chrome\n *\n * 1.0, Andrea Leofreddi\n *\tFirst release\n *\n * This code is licensed under the following BSD license:\n *\n * Copyright 2009-2010 Andrea Leofreddi <a.leofreddi@itcharm.com>. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification, are\n * permitted provided that the following conditions are met:\n *\n *    1. Redistributions of source code must retain the above copyright notice, this list of\n *       conditions and the following disclaimer.\n *\n *    2. Redistributions in binary form must reproduce the above copyright notice, this list\n *       of conditions and the following disclaimer in the documentation and/or other materials\n *       provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED\n * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR\n * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * The views and conclusions contained in the software and documentation are those of the\n * authors and should not be interpreted as representing official policies, either expressed\n * or implied, of Andrea Leofreddi.\n */\n\nvar root = document.documentElement;\n\nvar state = 'none', stateTarget, stateOrigin, stateTf;\n\nsetupHandlers(root);\n\n/**\n * Register handlers\n */\nfunction setupHandlers(root){\n\tsetAttributes(root, {\n\t\t\"onmouseup\" : \"add(evt)\",\n\t\t\"onmousedown\" : \"handleMouseDown(evt)\",\n\t\t\"onmousemove\" : \"handleMouseMove(evt)\",\n\t\t\"onmouseup\" : \"handleMouseUp(evt)\",\n\t\t//\"onmouseout\" : \"handleMouseUp(evt)\", // Decomment this to stop the pan functionality when dragging out of the SVG element\n\t});\n\n\tif(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)\n\t\twindow.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari\n\telse\n\t\twindow.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others\n\n\tvar g = svgDoc.getElementById(\"svg\");\n\tg.width = \"100%\";\n\tg.height = \"100%\";\n}\n\n/**\n * Instance an SVGPoint object with given event coordinates.\n */\nfunction getEventPoint(evt) {\n\tvar p = root.createSVGPoint();\n\n\tp.x = evt.clientX;\n\tp.y = evt.clientY;\n\n\treturn p;\n}\n\n/**\n * Sets the current transform matrix of an element.\n */\nfunction setCTM(element, matrix) {\n\tvar s = \"matrix(\" + matrix.a + \",\" + matrix.b + \",\" + matrix.c + \",\" + matrix.d + \",\" + matrix.e + \",\" + matrix.f + \")\";\n\n\telement.setAttribute(\"transform\", s);\n}\n\n/**\n * Dumps a matrix to a string (useful for debug).\n */\nfunction dumpMatrix(matrix) {\n\tvar s = \"[ \" + matrix.a + \", \" + matrix.c + \", \" + matrix.e + \"\\n  \" + matrix.b + \", \" + matrix.d + \", \" + matrix.f + \"\\n  0, 0, 1 ]\";\n\n\treturn s;\n}\n\n/**\n * Sets attributes of an element.\n */\nfunction setAttributes(element, attributes){\n\tfor (i in attributes)\n\t\telement.setAttributeNS(null, i, attributes[i]);\n}\n\n/**\n * Handle mouse move event.\n */\nfunction handleMouseWheel(evt) {\n\tif(evt.preventDefault)\n\t\tevt.preventDefault();\n\n\tevt.returnValue = false;\n\n\tvar svgDoc = evt.target.ownerDocument;\n\n\tvar delta;\n\n\tif(evt.wheelDelta)\n\t\tdelta = evt.wheelDelta / 3600; // Chrome/Safari\n\telse\n\t\tdelta = evt.detail / -90; // Mozilla\n\n\tvar z = 1 + delta; // Zoom factor: 0.9/1.1\n\n\tvar g = svgDoc.getElementById(\"viewport\");\n\n\tvar p = getEventPoint(evt);\n\n\tp = p.matrixTransform(g.getCTM().inverse());\n\n\t// Compute new scale matrix in current mouse position\n\tvar k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);\n\n        setCTM(g, g.getCTM().multiply(k));\n\n\tstateTf = stateTf.multiply(k.inverse());\n}\n\n/**\n * Handle mouse move event.\n */\nfunction handleMouseMove(evt) {\n\tif(evt.preventDefault)\n\t\tevt.preventDefault();\n\n\tevt.returnValue = false;\n\n\tvar svgDoc = evt.target.ownerDocument;\n\n\tvar g = svgDoc.getElementById(\"viewport\");\n\n\tif(state == 'pan') {\n\t\t// Pan mode\n\t\tvar p = getEventPoint(evt).matrixTransform(stateTf);\n\n\t\tsetCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));\n\t} else if(state == 'move') {\n\t\t// Move mode\n\t\tvar p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());\n\n\t\tsetCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));\n\n\t\tstateOrigin = p;\n\t}\n}\n\n/**\n * Handle click event.\n */\nfunction handleMouseDown(evt) {\n\tif(evt.preventDefault)\n\t\tevt.preventDefault();\n\n\tevt.returnValue = false;\n\n\tvar svgDoc = evt.target.ownerDocument;\n\n\tvar g = svgDoc.getElementById(\"viewport\");\n\n\tif(true || evt.target.tagName == \"svg\") {\n\t\t// Pan mode\n\t\tstate = 'pan';\n\n\t\tstateTf = g.getCTM().inverse();\n\n\t\tstateOrigin = getEventPoint(evt).matrixTransform(stateTf);\n\t} else {\n\t\t// Move mode\n\t\tstate = 'move';\n\n\t\tstateTarget = evt.target;\n\n\t\tstateTf = g.getCTM().inverse();\n\n\t\tstateOrigin = getEventPoint(evt).matrixTransform(stateTf);\n\t}\n}\n\n/**\n * Handle mouse button release event.\n */\nfunction handleMouseUp(evt) {\n\tif(evt.preventDefault)\n\t\tevt.preventDefault();\n\n\tevt.returnValue = false;\n\n\tvar svgDoc = evt.target.ownerDocument;\n\n\tif(state == 'pan' || state == 'move') {\n\t\t// Quit pan mode\n\t\tstate = '';\n\t}\n}\n\n]]></script>\nEOF\n}\n\n# Return a small number that identifies the argument.\n# Multiple calls with the same argument will return the same number.\n# Calls with different arguments will return different numbers.\nsub ShortIdFor {\n  my $key = shift;\n  my $id = $main::uniqueid{$key};\n  if (!defined($id)) {\n    $id = keys(%main::uniqueid) + 1;\n    $main::uniqueid{$key} = $id;\n  }\n  return $id;\n}\n\n# Translate a stack of addresses into a stack of symbols\nsub TranslateStack {\n  my $symbols = shift;\n  my $k = shift;\n\n  my @addrs = split(/\\n/, $k);\n  my @result = ();\n  for (my $i = 0; $i <= $#addrs; $i++) {\n    my $a = $addrs[$i];\n\n    # Skip large addresses since they sometimes show up as fake entries on RH9\n    if (length($a) > 8 && $a gt \"7fffffffffffffff\") {\n      next;\n    }\n\n    if ($main::opt_disasm || $main::opt_list) {\n      # We want just the address for the key\n      push(@result, $a);\n      next;\n    }\n\n    my $symlist = $symbols->{$a};\n    if (!defined($symlist)) {\n      $symlist = [$a, \"\", $a];\n    }\n\n    # We can have a sequence of symbols for a particular entry\n    # (more than one symbol in the case of inlining).  Callers\n    # come before callees in symlist, so walk backwards since\n    # the translated stack should contain callees before callers.\n    for (my $j = $#{$symlist}; $j >= 2; $j -= 3) {\n      my $func = $symlist->[$j-2];\n      my $fileline = $symlist->[$j-1];\n      my $fullfunc = $symlist->[$j];\n      if ($j > 2) {\n        $func = \"$func (inline)\";\n      }\n\n      # Do not merge nodes corresponding to Callback::Run since that\n      # causes confusing cycles in dot display.  Instead, we synthesize\n      # a unique name for this frame per caller.\n      if ($func =~ m/Callback.*::Run$/) {\n        my $caller = ($i > 0) ? $addrs[$i-1] : 0;\n        $func = \"Run#\" . ShortIdFor($caller);\n      }\n\n      if ($main::opt_addresses) {\n        push(@result, \"$a $func $fileline\");\n      } elsif ($main::opt_lines) {\n        if ($func eq '??' && $fileline eq '??:0') {\n          push(@result, \"$a\");\n        } else {\n          push(@result, \"$func $fileline\");\n        }\n      } elsif ($main::opt_functions) {\n        if ($func eq '??') {\n          push(@result, \"$a\");\n        } else {\n          push(@result, $func);\n        }\n      } elsif ($main::opt_files) {\n        if ($fileline eq '??:0' || $fileline eq '') {\n          push(@result, \"$a\");\n        } else {\n          my $f = $fileline;\n          $f =~ s/:\\d+$//;\n          push(@result, $f);\n        }\n      } else {\n        push(@result, $a);\n        last;  # Do not print inlined info\n      }\n    }\n  }\n\n  # print join(\",\", @addrs), \" => \", join(\",\", @result), \"\\n\";\n  return @result;\n}\n\n# Generate percent string for a number and a total\nsub Percent {\n  my $num = shift;\n  my $tot = shift;\n  if ($tot != 0) {\n    return sprintf(\"%.1f%%\", $num * 100.0 / $tot);\n  } else {\n    return ($num == 0) ? \"nan\" : (($num > 0) ? \"+inf\" : \"-inf\");\n  }\n}\n\n# Generate pretty-printed form of number\nsub Unparse {\n  my $num = shift;\n  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {\n    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {\n      return sprintf(\"%d\", $num);\n    } else {\n      if ($main::opt_show_bytes) {\n        return sprintf(\"%d\", $num);\n      } else {\n        return sprintf(\"%.1f\", $num / 1048576.0);\n      }\n    }\n  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {\n    return sprintf(\"%.3f\", $num / 1e9); # Convert nanoseconds to seconds\n  } else {\n    return sprintf(\"%d\", $num);\n  }\n}\n\n# Alternate pretty-printed form: 0 maps to \".\"\nsub UnparseAlt {\n  my $num = shift;\n  if ($num == 0) {\n    return \".\";\n  } else {\n    return Unparse($num);\n  }\n}\n\n# Return output units\nsub Units {\n  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {\n    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {\n      return \"objects\";\n    } else {\n      if ($main::opt_show_bytes) {\n        return \"B\";\n      } else {\n        return \"MB\";\n      }\n    }\n  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {\n    return \"seconds\";\n  } else {\n    return \"samples\";\n  }\n}\n\n##### Profile manipulation code #####\n\n# Generate flattened profile:\n# If count is charged to stack [a,b,c,d], in generated profile,\n# it will be charged to [a]\nsub FlatProfile {\n  my $profile = shift;\n  my $result = {};\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @addrs = split(/\\n/, $k);\n    if ($#addrs >= 0) {\n      AddEntry($result, $addrs[0], $count);\n    }\n  }\n  return $result;\n}\n\n# Generate cumulative profile:\n# If count is charged to stack [a,b,c,d], in generated profile,\n# it will be charged to [a], [b], [c], [d]\nsub CumulativeProfile {\n  my $profile = shift;\n  my $result = {};\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @addrs = split(/\\n/, $k);\n    foreach my $a (@addrs) {\n      AddEntry($result, $a, $count);\n    }\n  }\n  return $result;\n}\n\n# If the second-youngest PC on the stack is always the same, returns\n# that pc.  Otherwise, returns undef.\nsub IsSecondPcAlwaysTheSame {\n  my $profile = shift;\n\n  my $second_pc = undef;\n  foreach my $k (keys(%{$profile})) {\n    my @addrs = split(/\\n/, $k);\n    if ($#addrs < 1) {\n      return undef;\n    }\n    if (not defined $second_pc) {\n      $second_pc = $addrs[1];\n    } else {\n      if ($second_pc ne $addrs[1]) {\n        return undef;\n      }\n    }\n  }\n  return $second_pc;\n}\n\nsub ExtractSymbolLocation {\n  my $symbols = shift;\n  my $address = shift;\n  # 'addr2line' outputs \"??:0\" for unknown locations; we do the\n  # same to be consistent.\n  my $location = \"??:0:unknown\";\n  if (exists $symbols->{$address}) {\n    my $file = $symbols->{$address}->[1];\n    if ($file eq \"?\") {\n      $file = \"??:0\"\n    }\n    $location = $file . \":\" . $symbols->{$address}->[0];\n  }\n  return $location;\n}\n\n# Extracts a graph of calls.\nsub ExtractCalls {\n  my $symbols = shift;\n  my $profile = shift;\n\n  my $calls = {};\n  while( my ($stack_trace, $count) = each %$profile ) {\n    my @address = split(/\\n/, $stack_trace);\n    my $destination = ExtractSymbolLocation($symbols, $address[0]);\n    AddEntry($calls, $destination, $count);\n    for (my $i = 1; $i <= $#address; $i++) {\n      my $source = ExtractSymbolLocation($symbols, $address[$i]);\n      my $call = \"$source -> $destination\";\n      AddEntry($calls, $call, $count);\n      $destination = $source;\n    }\n  }\n\n  return $calls;\n}\n\nsub RemoveUninterestingFrames {\n  my $symbols = shift;\n  my $profile = shift;\n\n  # List of function names to skip\n  my %skip = ();\n  my $skip_regexp = 'NOMATCH';\n  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {\n    foreach my $name ('calloc',\n                      'cfree',\n                      'malloc',\n                      'free',\n                      'memalign',\n                      'posix_memalign',\n                      'pvalloc',\n                      'valloc',\n                      'realloc',\n                      'tc_calloc',\n                      'tc_cfree',\n                      'tc_malloc',\n                      'tc_free',\n                      'tc_memalign',\n                      'tc_posix_memalign',\n                      'tc_pvalloc',\n                      'tc_valloc',\n                      'tc_realloc',\n                      'tc_new',\n                      'tc_delete',\n                      'tc_newarray',\n                      'tc_deletearray',\n                      'tc_new_nothrow',\n                      'tc_newarray_nothrow',\n                      'do_malloc',\n                      '::do_malloc',   # new name -- got moved to an unnamed ns\n                      '::do_malloc_or_cpp_alloc',\n                      'DoSampledAllocation',\n                      'simple_alloc::allocate',\n                      '__malloc_alloc_template::allocate',\n                      '__builtin_delete',\n                      '__builtin_new',\n                      '__builtin_vec_delete',\n                      '__builtin_vec_new',\n                      'operator new',\n                      'operator new[]',\n                      # These mark the beginning/end of our custom sections\n                      '__start_google_malloc',\n                      '__stop_google_malloc',\n                      '__start_malloc_hook',\n                      '__stop_malloc_hook') {\n      $skip{$name} = 1;\n      $skip{\"_\" . $name} = 1;   # Mach (OS X) adds a _ prefix to everything\n    }\n    # TODO: Remove TCMalloc once everything has been\n    # moved into the tcmalloc:: namespace and we have flushed\n    # old code out of the system.\n    $skip_regexp = \"TCMalloc|^tcmalloc::\";\n  } elsif ($main::profile_type eq 'contention') {\n    foreach my $vname ('base::RecordLockProfileData',\n                       'base::SubmitMutexProfileData',\n                       'base::SubmitSpinLockProfileData',\n                       'Mutex::Unlock',\n                       'Mutex::UnlockSlow',\n                       'Mutex::ReaderUnlock',\n                       'MutexLock::~MutexLock',\n                       'SpinLock::Unlock',\n                       'SpinLock::SlowUnlock',\n                       'SpinLockHolder::~SpinLockHolder') {\n      $skip{$vname} = 1;\n    }\n  } elsif ($main::profile_type eq 'cpu') {\n    # Drop signal handlers used for CPU profile collection\n    # TODO(dpeng): this should not be necessary; it's taken\n    # care of by the general 2nd-pc mechanism below.\n    foreach my $name ('ProfileData::Add',           # historical\n                      'ProfileData::prof_handler',  # historical\n                      'CpuProfiler::prof_handler',\n                      '__FRAME_END__',\n                      '__pthread_sighandler',\n                      '__restore') {\n      $skip{$name} = 1;\n    }\n  } else {\n    # Nothing skipped for unknown types\n  }\n\n  if ($main::profile_type eq 'cpu') {\n    # If all the second-youngest program counters are the same,\n    # this STRONGLY suggests that it is an artifact of measurement,\n    # i.e., stack frames pushed by the CPU profiler signal handler.\n    # Hence, we delete them.\n    # (The topmost PC is read from the signal structure, not from\n    # the stack, so it does not get involved.)\n    while (my $second_pc = IsSecondPcAlwaysTheSame($profile)) {\n      my $result = {};\n      my $func = '';\n      if (exists($symbols->{$second_pc})) {\n        $second_pc = $symbols->{$second_pc}->[0];\n      }\n      print STDERR \"Removing $second_pc from all stack traces.\\n\";\n      foreach my $k (keys(%{$profile})) {\n        my $count = $profile->{$k};\n        my @addrs = split(/\\n/, $k);\n        splice @addrs, 1, 1;\n        my $reduced_path = join(\"\\n\", @addrs);\n        AddEntry($result, $reduced_path, $count);\n      }\n      $profile = $result;\n    }\n  }\n\n  my $result = {};\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @addrs = split(/\\n/, $k);\n    my @path = ();\n    foreach my $a (@addrs) {\n      if (exists($symbols->{$a})) {\n        my $func = $symbols->{$a}->[0];\n        if ($skip{$func} || ($func =~ m/$skip_regexp/)) {\n          next;\n        }\n      }\n      push(@path, $a);\n    }\n    my $reduced_path = join(\"\\n\", @path);\n    AddEntry($result, $reduced_path, $count);\n  }\n  return $result;\n}\n\n# Reduce profile to granularity given by user\nsub ReduceProfile {\n  my $symbols = shift;\n  my $profile = shift;\n  my $result = {};\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @translated = TranslateStack($symbols, $k);\n    my @path = ();\n    my %seen = ();\n    $seen{''} = 1;      # So that empty keys are skipped\n    foreach my $e (@translated) {\n      # To avoid double-counting due to recursion, skip a stack-trace\n      # entry if it has already been seen\n      if (!$seen{$e}) {\n        $seen{$e} = 1;\n        push(@path, $e);\n      }\n    }\n    my $reduced_path = join(\"\\n\", @path);\n    AddEntry($result, $reduced_path, $count);\n  }\n  return $result;\n}\n\n# Does the specified symbol array match the regexp?\nsub SymbolMatches {\n  my $sym = shift;\n  my $re = shift;\n  if (defined($sym)) {\n    for (my $i = 0; $i < $#{$sym}; $i += 3) {\n      if ($sym->[$i] =~ m/$re/ || $sym->[$i+1] =~ m/$re/) {\n        return 1;\n      }\n    }\n  }\n  return 0;\n}\n\n# Focus only on paths involving specified regexps\nsub FocusProfile {\n  my $symbols = shift;\n  my $profile = shift;\n  my $focus = shift;\n  my $result = {};\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @addrs = split(/\\n/, $k);\n    foreach my $a (@addrs) {\n      # Reply if it matches either the address/shortname/fileline\n      if (($a =~ m/$focus/) || SymbolMatches($symbols->{$a}, $focus)) {\n        AddEntry($result, $k, $count);\n        last;\n      }\n    }\n  }\n  return $result;\n}\n\n# Focus only on paths not involving specified regexps\nsub IgnoreProfile {\n  my $symbols = shift;\n  my $profile = shift;\n  my $ignore = shift;\n  my $result = {};\n  foreach my $k (keys(%{$profile})) {\n    my $count = $profile->{$k};\n    my @addrs = split(/\\n/, $k);\n    my $matched = 0;\n    foreach my $a (@addrs) {\n      # Reply if it matches either the address/shortname/fileline\n      if (($a =~ m/$ignore/) || SymbolMatches($symbols->{$a}, $ignore)) {\n        $matched = 1;\n        last;\n      }\n    }\n    if (!$matched) {\n      AddEntry($result, $k, $count);\n    }\n  }\n  return $result;\n}\n\n# Get total count in profile\nsub TotalProfile {\n  my $profile = shift;\n  my $result = 0;\n  foreach my $k (keys(%{$profile})) {\n    $result += $profile->{$k};\n  }\n  return $result;\n}\n\n# Add A to B\nsub AddProfile {\n  my $A = shift;\n  my $B = shift;\n\n  my $R = {};\n  # add all keys in A\n  foreach my $k (keys(%{$A})) {\n    my $v = $A->{$k};\n    AddEntry($R, $k, $v);\n  }\n  # add all keys in B\n  foreach my $k (keys(%{$B})) {\n    my $v = $B->{$k};\n    AddEntry($R, $k, $v);\n  }\n  return $R;\n}\n\n# Merges symbol maps\nsub MergeSymbols {\n  my $A = shift;\n  my $B = shift;\n\n  my $R = {};\n  foreach my $k (keys(%{$A})) {\n    $R->{$k} = $A->{$k};\n  }\n  if (defined($B)) {\n    foreach my $k (keys(%{$B})) {\n      $R->{$k} = $B->{$k};\n    }\n  }\n  return $R;\n}\n\n\n# Add A to B\nsub AddPcs {\n  my $A = shift;\n  my $B = shift;\n\n  my $R = {};\n  # add all keys in A\n  foreach my $k (keys(%{$A})) {\n    $R->{$k} = 1\n  }\n  # add all keys in B\n  foreach my $k (keys(%{$B})) {\n    $R->{$k} = 1\n  }\n  return $R;\n}\n\n# Subtract B from A\nsub SubtractProfile {\n  my $A = shift;\n  my $B = shift;\n\n  my $R = {};\n  foreach my $k (keys(%{$A})) {\n    my $v = $A->{$k} - GetEntry($B, $k);\n    if ($v < 0 && $main::opt_drop_negative) {\n      $v = 0;\n    }\n    AddEntry($R, $k, $v);\n  }\n  if (!$main::opt_drop_negative) {\n    # Take care of when subtracted profile has more entries\n    foreach my $k (keys(%{$B})) {\n      if (!exists($A->{$k})) {\n        AddEntry($R, $k, 0 - $B->{$k});\n      }\n    }\n  }\n  return $R;\n}\n\n# Get entry from profile; zero if not present\nsub GetEntry {\n  my $profile = shift;\n  my $k = shift;\n  if (exists($profile->{$k})) {\n    return $profile->{$k};\n  } else {\n    return 0;\n  }\n}\n\n# Add entry to specified profile\nsub AddEntry {\n  my $profile = shift;\n  my $k = shift;\n  my $n = shift;\n  if (!exists($profile->{$k})) {\n    $profile->{$k} = 0;\n  }\n  $profile->{$k} += $n;\n}\n\n# Add a stack of entries to specified profile, and add them to the $pcs\n# list.\nsub AddEntries {\n  my $profile = shift;\n  my $pcs = shift;\n  my $stack = shift;\n  my $count = shift;\n  my @k = ();\n\n  foreach my $e (split(/\\s+/, $stack)) {\n    my $pc = HexExtend($e);\n    $pcs->{$pc} = 1;\n    push @k, $pc;\n  }\n  AddEntry($profile, (join \"\\n\", @k), $count);\n}\n\n##### Code to profile a server dynamically #####\n\nsub CheckSymbolPage {\n  my $url = SymbolPageURL();\n  open(SYMBOL, \"$URL_FETCHER '$url' |\");\n  my $line = <SYMBOL>;\n  $line =~ s/\\r//g;         # turn windows-looking lines into unix-looking lines\n  close(SYMBOL);\n  unless (defined($line)) {\n    error(\"$url doesn't exist\\n\");\n  }\n\n  if ($line =~ /^num_symbols:\\s+(\\d+)$/) {\n    if ($1 == 0) {\n      error(\"Stripped binary. No symbols available.\\n\");\n    }\n  } else {\n    error(\"Failed to get the number of symbols from $url\\n\");\n  }\n}\n\nsub IsProfileURL {\n  my $profile_name = shift;\n  if (-f $profile_name) {\n    printf STDERR \"Using local file $profile_name.\\n\";\n    return 0;\n  }\n  return 1;\n}\n\nsub ParseProfileURL {\n  my $profile_name = shift;\n\n  if (!defined($profile_name) || $profile_name eq \"\") {\n    return ();\n  }\n\n  # Split profile URL - matches all non-empty strings, so no test.\n  $profile_name =~ m,^(https?://)?([^/]+)(.*?)(/|$PROFILES)?$,;\n\n  my $proto = $1 || \"http://\";\n  my $hostport = $2;\n  my $prefix = $3;\n  my $profile = $4 || \"/\";\n\n  my $host = $hostport;\n  $host =~ s/:.*//;\n\n  my $baseurl = \"$proto$hostport$prefix\";\n  return ($host, $baseurl, $profile);\n}\n\n# We fetch symbols from the first profile argument.\nsub SymbolPageURL {\n  my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]);\n  return \"$baseURL$SYMBOL_PAGE\";\n}\n\nsub FetchProgramName() {\n  my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]);\n  my $url = \"$baseURL$PROGRAM_NAME_PAGE\";\n  my $command_line = \"$URL_FETCHER '$url'\";\n  open(CMDLINE, \"$command_line |\") or error($command_line);\n  my $cmdline = <CMDLINE>;\n  $cmdline =~ s/\\r//g;   # turn windows-looking lines into unix-looking lines\n  close(CMDLINE);\n  error(\"Failed to get program name from $url\\n\") unless defined($cmdline);\n  $cmdline =~ s/\\x00.+//;  # Remove argv[1] and latters.\n  $cmdline =~ s!\\n!!g;  # Remove LFs.\n  return $cmdline;\n}\n\n# Gee, curl's -L (--location) option isn't reliable at least\n# with its 7.12.3 version.  Curl will forget to post data if\n# there is a redirection.  This function is a workaround for\n# curl.  Redirection happens on borg hosts.\nsub ResolveRedirectionForCurl {\n  my $url = shift;\n  my $command_line = \"$URL_FETCHER --head '$url'\";\n  open(CMDLINE, \"$command_line |\") or error($command_line);\n  while (<CMDLINE>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    if (/^Location: (.*)/) {\n      $url = $1;\n    }\n  }\n  close(CMDLINE);\n  return $url;\n}\n\n# Add a timeout flat to URL_FETCHER\nsub AddFetchTimeout {\n  my $fetcher = shift;\n  my $timeout = shift;\n  if (defined($timeout)) {\n    if ($fetcher =~ m/\\bcurl -s/) {\n      $fetcher .= sprintf(\" --max-time %d\", $timeout);\n    } elsif ($fetcher =~ m/\\brpcget\\b/) {\n      $fetcher .= sprintf(\" --deadline=%d\", $timeout);\n    }\n  }\n  return $fetcher;\n}\n\n# Reads a symbol map from the file handle name given as $1, returning\n# the resulting symbol map.  Also processes variables relating to symbols.\n# Currently, the only variable processed is 'binary=<value>' which updates\n# $main::prog to have the correct program name.\nsub ReadSymbols {\n  my $in = shift;\n  my $map = {};\n  while (<$in>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    # Removes all the leading zeroes from the symbols, see comment below.\n    if (m/^0x0*([0-9a-f]+)\\s+(.+)/) {\n      $map->{$1} = $2;\n    } elsif (m/^---/) {\n      last;\n    } elsif (m/^([a-z][^=]*)=(.*)$/ ) {\n      my ($variable, $value) = ($1, $2);\n      for ($variable, $value) {\n        s/^\\s+//;\n        s/\\s+$//;\n      }\n      if ($variable eq \"binary\") {\n        if ($main::prog ne $UNKNOWN_BINARY && $main::prog ne $value) {\n          printf STDERR (\"Warning: Mismatched binary name '%s', using '%s'.\\n\",\n                         $main::prog, $value);\n        }\n        $main::prog = $value;\n      } else {\n        printf STDERR (\"Ignoring unknown variable in symbols list: \" .\n            \"'%s' = '%s'\\n\", $variable, $value);\n      }\n    }\n  }\n  return $map;\n}\n\n# Fetches and processes symbols to prepare them for use in the profile output\n# code.  If the optional 'symbol_map' arg is not given, fetches symbols from\n# $SYMBOL_PAGE for all PC values found in profile.  Otherwise, the raw symbols\n# are assumed to have already been fetched into 'symbol_map' and are simply\n# extracted and processed.\nsub FetchSymbols {\n  my $pcset = shift;\n  my $symbol_map = shift;\n\n  my %seen = ();\n  my @pcs = grep { !$seen{$_}++ } keys(%$pcset);  # uniq\n\n  if (!defined($symbol_map)) {\n    my $post_data = join(\"+\", sort((map {\"0x\" . \"$_\"} @pcs)));\n\n    open(POSTFILE, \">$main::tmpfile_sym\");\n    print POSTFILE $post_data;\n    close(POSTFILE);\n\n    my $url = SymbolPageURL();\n\n    my $command_line;\n    if ($URL_FETCHER =~ m/\\bcurl -s/) {\n      $url = ResolveRedirectionForCurl($url);\n      $command_line = \"$URL_FETCHER -d '\\@$main::tmpfile_sym' '$url'\";\n    } else {\n      $command_line = \"$URL_FETCHER --post '$url' < '$main::tmpfile_sym'\";\n    }\n    # We use c++filt in case $SYMBOL_PAGE gives us mangled symbols.\n    my $cppfilt = $obj_tool_map{\"c++filt\"};\n    open(SYMBOL, \"$command_line | $cppfilt |\") or error($command_line);\n    $symbol_map = ReadSymbols(*SYMBOL{IO});\n    close(SYMBOL);\n  }\n\n  my $symbols = {};\n  foreach my $pc (@pcs) {\n    my $fullname;\n    # For 64 bits binaries, symbols are extracted with 8 leading zeroes.\n    # Then /symbol reads the long symbols in as uint64, and outputs\n    # the result with a \"0x%08llx\" format which get rid of the zeroes.\n    # By removing all the leading zeroes in both $pc and the symbols from\n    # /symbol, the symbols match and are retrievable from the map.\n    my $shortpc = $pc;\n    $shortpc =~ s/^0*//;\n    # Each line may have a list of names, which includes the function\n    # and also other functions it has inlined.  They are separated\n    # (in PrintSymbolizedFile), by --, which is illegal in function names.\n    my $fullnames;\n    if (defined($symbol_map->{$shortpc})) {\n      $fullnames = $symbol_map->{$shortpc};\n    } else {\n      $fullnames = \"0x\" . $pc;  # Just use addresses\n    }\n    my $sym = [];\n    $symbols->{$pc} = $sym;\n    foreach my $fullname (split(\"--\", $fullnames)) {\n      my $name = ShortFunctionName($fullname);\n      push(@{$sym}, $name, \"?\", $fullname);\n    }\n  }\n  return $symbols;\n}\n\nsub BaseName {\n  my $file_name = shift;\n  $file_name =~ s!^.*/!!;  # Remove directory name\n  return $file_name;\n}\n\nsub MakeProfileBaseName {\n  my ($binary_name, $profile_name) = @_;\n  my ($host, $baseURL, $path) = ParseProfileURL($profile_name);\n  my $binary_shortname = BaseName($binary_name);\n  return sprintf(\"%s.%s.%s\",\n                 $binary_shortname, $main::op_time, $host);\n}\n\nsub FetchDynamicProfile {\n  my $binary_name = shift;\n  my $profile_name = shift;\n  my $fetch_name_only = shift;\n  my $encourage_patience = shift;\n\n  if (!IsProfileURL($profile_name)) {\n    return $profile_name;\n  } else {\n    my ($host, $baseURL, $path) = ParseProfileURL($profile_name);\n    if ($path eq \"\" || $path eq \"/\") {\n      # Missing type specifier defaults to cpu-profile\n      $path = $PROFILE_PAGE;\n    }\n\n    my $profile_file = MakeProfileBaseName($binary_name, $profile_name);\n\n    my $url = \"$baseURL$path\";\n    my $fetch_timeout = undef;\n    if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE/) {\n      if ($path =~ m/[?]/) {\n        $url .= \"&\";\n      } else {\n        $url .= \"?\";\n      }\n      $url .= sprintf(\"seconds=%d\", $main::opt_seconds);\n      $fetch_timeout = $main::opt_seconds * 1.01 + 60;\n    } else {\n      # For non-CPU profiles, we add a type-extension to\n      # the target profile file name.\n      my $suffix = $path;\n      $suffix =~ s,/,.,g;\n      $profile_file .= $suffix;\n    }\n\n    my $profile_dir = $ENV{\"PPROF_TMPDIR\"} || ($ENV{HOME} . \"/pprof\");\n    if (! -d $profile_dir) {\n      mkdir($profile_dir)\n          || die(\"Unable to create profile directory $profile_dir: $!\\n\");\n    }\n    my $tmp_profile = \"$profile_dir/.tmp.$profile_file\";\n    my $real_profile = \"$profile_dir/$profile_file\";\n\n    if ($fetch_name_only > 0) {\n      return $real_profile;\n    }\n\n    my $fetcher = AddFetchTimeout($URL_FETCHER, $fetch_timeout);\n    my $cmd = \"$fetcher '$url' > '$tmp_profile'\";\n    if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE|$CENSUSPROFILE_PAGE/){\n      print STDERR \"Gathering CPU profile from $url for $main::opt_seconds seconds to\\n  ${real_profile}\\n\";\n      if ($encourage_patience) {\n        print STDERR \"Be patient...\\n\";\n      }\n    } else {\n      print STDERR \"Fetching $path profile from $url to\\n  ${real_profile}\\n\";\n    }\n\n    (system($cmd) == 0) || error(\"Failed to get profile: $cmd: $!\\n\");\n    (system(\"mv $tmp_profile $real_profile\") == 0) || error(\"Unable to rename profile\\n\");\n    print STDERR \"Wrote profile to $real_profile\\n\";\n    $main::collected_profile = $real_profile;\n    return $main::collected_profile;\n  }\n}\n\n# Collect profiles in parallel\nsub FetchDynamicProfiles {\n  my $items = scalar(@main::pfile_args);\n  my $levels = log($items) / log(2);\n\n  if ($items == 1) {\n    $main::profile_files[0] = FetchDynamicProfile($main::prog, $main::pfile_args[0], 0, 1);\n  } else {\n    # math rounding issues\n    if ((2 ** $levels) < $items) {\n     $levels++;\n    }\n    my $count = scalar(@main::pfile_args);\n    for (my $i = 0; $i < $count; $i++) {\n      $main::profile_files[$i] = FetchDynamicProfile($main::prog, $main::pfile_args[$i], 1, 0);\n    }\n    print STDERR \"Fetching $count profiles, Be patient...\\n\";\n    FetchDynamicProfilesRecurse($levels, 0, 0);\n    $main::collected_profile = join(\" \\\\\\n    \", @main::profile_files);\n  }\n}\n\n# Recursively fork a process to get enough processes\n# collecting profiles\nsub FetchDynamicProfilesRecurse {\n  my $maxlevel = shift;\n  my $level = shift;\n  my $position = shift;\n\n  if (my $pid = fork()) {\n    $position = 0 | ($position << 1);\n    TryCollectProfile($maxlevel, $level, $position);\n    wait;\n  } else {\n    $position = 1 | ($position << 1);\n    TryCollectProfile($maxlevel, $level, $position);\n    cleanup();\n    exit(0);\n  }\n}\n\n# Collect a single profile\nsub TryCollectProfile {\n  my $maxlevel = shift;\n  my $level = shift;\n  my $position = shift;\n\n  if ($level >= ($maxlevel - 1)) {\n    if ($position < scalar(@main::pfile_args)) {\n      FetchDynamicProfile($main::prog, $main::pfile_args[$position], 0, 0);\n    }\n  } else {\n    FetchDynamicProfilesRecurse($maxlevel, $level+1, $position);\n  }\n}\n\n##### Parsing code #####\n\n# Provide a small streaming-read module to handle very large\n# cpu-profile files.  Stream in chunks along a sliding window.\n# Provides an interface to get one 'slot', correctly handling\n# endian-ness differences.  A slot is one 32-bit or 64-bit word\n# (depending on the input profile).  We tell endianness and bit-size\n# for the profile by looking at the first 8 bytes: in cpu profiles,\n# the second slot is always 3 (we'll accept anything that's not 0).\nBEGIN {\n  package CpuProfileStream;\n\n  sub new {\n    my ($class, $file, $fname) = @_;\n    my $self = { file        => $file,\n                 base        => 0,\n                 stride      => 512 * 1024,   # must be a multiple of bitsize/8\n                 slots       => [],\n                 unpack_code => \"\",           # N for big-endian, V for little\n                 perl_is_64bit => 1,          # matters if profile is 64-bit\n    };\n    bless $self, $class;\n    # Let unittests adjust the stride\n    if ($main::opt_test_stride > 0) {\n      $self->{stride} = $main::opt_test_stride;\n    }\n    # Read the first two slots to figure out bitsize and endianness.\n    my $slots = $self->{slots};\n    my $str;\n    read($self->{file}, $str, 8);\n    # Set the global $address_length based on what we see here.\n    # 8 is 32-bit (8 hexadecimal chars); 16 is 64-bit (16 hexadecimal chars).\n    $address_length = ($str eq (chr(0)x8)) ? 16 : 8;\n    if ($address_length == 8) {\n      if (substr($str, 6, 2) eq chr(0)x2) {\n        $self->{unpack_code} = 'V';  # Little-endian.\n      } elsif (substr($str, 4, 2) eq chr(0)x2) {\n        $self->{unpack_code} = 'N';  # Big-endian\n      } else {\n        ::error(\"$fname: header size >= 2**16\\n\");\n      }\n      @$slots = unpack($self->{unpack_code} . \"*\", $str);\n    } else {\n      # If we're a 64-bit profile, check if we're a 64-bit-capable\n      # perl.  Otherwise, each slot will be represented as a float\n      # instead of an int64, losing precision and making all the\n      # 64-bit addresses wrong.  We won't complain yet, but will\n      # later if we ever see a value that doesn't fit in 32 bits.\n      my $has_q = 0;\n      eval { $has_q = pack(\"Q\", \"1\") ? 1 : 1; };\n      if (!$has_q) {\n\t$self->{perl_is_64bit} = 0;\n      }\n      read($self->{file}, $str, 8);\n      if (substr($str, 4, 4) eq chr(0)x4) {\n        # We'd love to use 'Q', but it's a) not universal, b) not endian-proof.\n        $self->{unpack_code} = 'V';  # Little-endian.\n      } elsif (substr($str, 0, 4) eq chr(0)x4) {\n        $self->{unpack_code} = 'N';  # Big-endian\n      } else {\n        ::error(\"$fname: header size >= 2**32\\n\");\n      }\n      my @pair = unpack($self->{unpack_code} . \"*\", $str);\n      # Since we know one of the pair is 0, it's fine to just add them.\n      @$slots = (0, $pair[0] + $pair[1]);\n    }\n    return $self;\n  }\n\n  # Load more data when we access slots->get(X) which is not yet in memory.\n  sub overflow {\n    my ($self) = @_;\n    my $slots = $self->{slots};\n    $self->{base} += $#$slots + 1;   # skip over data we're replacing\n    my $str;\n    read($self->{file}, $str, $self->{stride});\n    if ($address_length == 8) {      # the 32-bit case\n      # This is the easy case: unpack provides 32-bit unpacking primitives.\n      @$slots = unpack($self->{unpack_code} . \"*\", $str);\n    } else {\n      # We need to unpack 32 bits at a time and combine.\n      my @b32_values = unpack($self->{unpack_code} . \"*\", $str);\n      my @b64_values = ();\n      for (my $i = 0; $i < $#b32_values; $i += 2) {\n        # TODO(csilvers): if this is a 32-bit perl, the math below\n        #    could end up in a too-large int, which perl will promote\n        #    to a double, losing necessary precision.  Deal with that.\n\t#    Right now, we just die.\n\tmy ($lo, $hi) = ($b32_values[$i], $b32_values[$i+1]);\n        if ($self->{unpack_code} eq 'N') {    # big-endian\n\t  ($lo, $hi) = ($hi, $lo);\n\t}\n\tmy $value = $lo + $hi * (2**32);\n\tif (!$self->{perl_is_64bit} &&   # check value is exactly represented\n\t    (($value % (2**32)) != $lo || int($value / (2**32)) != $hi)) {\n\t  ::error(\"Need a 64-bit perl to process this 64-bit profile.\\n\");\n\t}\n\tpush(@b64_values, $value);\n      }\n      @$slots = @b64_values;\n    }\n  }\n\n  # Access the i-th long in the file (logically), or -1 at EOF.\n  sub get {\n    my ($self, $idx) = @_;\n    my $slots = $self->{slots};\n    while ($#$slots >= 0) {\n      if ($idx < $self->{base}) {\n        # The only time we expect a reference to $slots[$i - something]\n        # after referencing $slots[$i] is reading the very first header.\n        # Since $stride > |header|, that shouldn't cause any lookback\n        # errors.  And everything after the header is sequential.\n        print STDERR \"Unexpected look-back reading CPU profile\";\n        return -1;   # shrug, don't know what better to return\n      } elsif ($idx > $self->{base} + $#$slots) {\n        $self->overflow();\n      } else {\n        return $slots->[$idx - $self->{base}];\n      }\n    }\n    # If we get here, $slots is [], which means we've reached EOF\n    return -1;  # unique since slots is supposed to hold unsigned numbers\n  }\n}\n\n# Reads the top, 'header' section of a profile, and returns the last\n# line of the header, commonly called a 'header line'.  The header\n# section of a profile consists of zero or more 'command' lines that\n# are instructions to pprof, which pprof executes when reading the\n# header.  All 'command' lines start with a %.  After the command\n# lines is the 'header line', which is a profile-specific line that\n# indicates what type of profile it is, and perhaps other global\n# information about the profile.  For instance, here's a header line\n# for a heap profile:\n#   heap profile:     53:    38236 [  5525:  1284029] @ heapprofile\n# For historical reasons, the CPU profile does not contain a text-\n# readable header line.  If the profile looks like a CPU profile,\n# this function returns \"\".  If no header line could be found, this\n# function returns undef.\n#\n# The following commands are recognized:\n#   %warn -- emit the rest of this line to stderr, prefixed by 'WARNING:'\n#\n# The input file should be in binmode.\nsub ReadProfileHeader {\n  local *PROFILE = shift;\n  my $firstchar = \"\";\n  my $line = \"\";\n  read(PROFILE, $firstchar, 1);\n  seek(PROFILE, -1, 1);                    # unread the firstchar\n  if ($firstchar !~ /[[:print:]]/) {       # is not a text character\n    return \"\";\n  }\n  while (defined($line = <PROFILE>)) {\n    $line =~ s/\\r//g;   # turn windows-looking lines into unix-looking lines\n    if ($line =~ /^%warn\\s+(.*)/) {        # 'warn' command\n      # Note this matches both '%warn blah\\n' and '%warn\\n'.\n      print STDERR \"WARNING: $1\\n\";        # print the rest of the line\n    } elsif ($line =~ /^%/) {\n      print STDERR \"Ignoring unknown command from profile header: $line\";\n    } else {\n      # End of commands, must be the header line.\n      return $line;\n    }\n  }\n  return undef;     # got to EOF without seeing a header line\n}\n\nsub IsSymbolizedProfileFile {\n  my $file_name = shift;\n  if (!(-e $file_name) || !(-r $file_name)) {\n    return 0;\n  }\n  # Check if the file contains a symbol-section marker.\n  open(TFILE, \"<$file_name\");\n  binmode TFILE;\n  my $firstline = ReadProfileHeader(*TFILE);\n  close(TFILE);\n  if (!$firstline) {\n    return 0;\n  }\n  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $symbol_marker = $&;\n  return $firstline =~ /^--- *$symbol_marker/;\n}\n\n# Parse profile generated by common/profiler.cc and return a reference\n# to a map:\n#      $result->{version}     Version number of profile file\n#      $result->{period}      Sampling period (in microseconds)\n#      $result->{profile}     Profile object\n#      $result->{map}         Memory map info from profile\n#      $result->{pcs}         Hash of all PC values seen, key is hex address\nsub ReadProfile {\n  my $prog = shift;\n  my $fname = shift;\n  my $result;            # return value\n\n  $CONTENTION_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $contention_marker = $&;\n  $GROWTH_PAGE  =~ m,[^/]+$,;    # matches everything after the last slash\n  my $growth_marker = $&;\n  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $symbol_marker = $&;\n  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash\n  my $profile_marker = $&;\n\n  # Look at first line to see if it is a heap or a CPU profile.\n  # CPU profile may start with no header at all, and just binary data\n  # (starting with \\0\\0\\0\\0) -- in that case, don't try to read the\n  # whole firstline, since it may be gigabytes(!) of data.\n  open(PROFILE, \"<$fname\") || error(\"$fname: $!\\n\");\n  binmode PROFILE;      # New perls do UTF-8 processing\n  my $header = ReadProfileHeader(*PROFILE);\n  if (!defined($header)) {   # means \"at EOF\"\n    error(\"Profile is empty.\\n\");\n  }\n\n  my $symbols;\n  if ($header =~ m/^--- *$symbol_marker/o) {\n    # Verify that the user asked for a symbolized profile\n    if (!$main::use_symbolized_profile) {\n      # we have both a binary and symbolized profiles, abort\n      error(\"FATAL ERROR: Symbolized profile\\n   $fname\\ncannot be used with \" .\n\t    \"a binary arg. Try again without passing\\n   $prog\\n\");\n    }\n    # Read the symbol section of the symbolized profile file.\n    $symbols = ReadSymbols(*PROFILE{IO});\n    # Read the next line to get the header for the remaining profile.\n    $header = ReadProfileHeader(*PROFILE) || \"\";\n  }\n\n  $main::profile_type = '';\n  if ($header =~ m/^heap profile:.*$growth_marker/o) {\n    $main::profile_type = 'growth';\n    $result =  ReadHeapProfile($prog, *PROFILE, $header);\n  } elsif ($header =~ m/^heap profile:/) {\n    $main::profile_type = 'heap';\n    $result =  ReadHeapProfile($prog, *PROFILE, $header);\n  } elsif ($header =~ m/^--- *$contention_marker/o) {\n    $main::profile_type = 'contention';\n    $result = ReadSynchProfile($prog, *PROFILE);\n  } elsif ($header =~ m/^--- *Stacks:/) {\n    print STDERR\n      \"Old format contention profile: mistakenly reports \" .\n      \"condition variable signals as lock contentions.\\n\";\n    $main::profile_type = 'contention';\n    $result = ReadSynchProfile($prog, *PROFILE);\n  } elsif ($header =~ m/^--- *$profile_marker/) {\n    # the binary cpu profile data starts immediately after this line\n    $main::profile_type = 'cpu';\n    $result = ReadCPUProfile($prog, $fname, *PROFILE);\n  } else {\n    if (defined($symbols)) {\n      # a symbolized profile contains a format we don't recognize, bail out\n      error(\"$fname: Cannot recognize profile section after symbols.\\n\");\n    }\n    # no ascii header present -- must be a CPU profile\n    $main::profile_type = 'cpu';\n    $result = ReadCPUProfile($prog, $fname, *PROFILE);\n  }\n\n  close(PROFILE);\n\n  # if we got symbols along with the profile, return those as well\n  if (defined($symbols)) {\n    $result->{symbols} = $symbols;\n  }\n\n  return $result;\n}\n\n# Subtract one from caller pc so we map back to call instr.\n# However, don't do this if we're reading a symbolized profile\n# file, in which case the subtract-one was done when the file\n# was written.\n#\n# We apply the same logic to all readers, though ReadCPUProfile uses an\n# independent implementation.\nsub FixCallerAddresses {\n  my $stack = shift;\n  if ($main::use_symbolized_profile) {\n    return $stack;\n  } else {\n    $stack =~ /(\\s)/;\n    my $delimiter = $1;\n    my @addrs = split(' ', $stack);\n    my @fixedaddrs;\n    $#fixedaddrs = $#addrs;\n    if ($#addrs >= 0) {\n      $fixedaddrs[0] = $addrs[0];\n    }\n    for (my $i = 1; $i <= $#addrs; $i++) {\n      $fixedaddrs[$i] = AddressSub($addrs[$i], \"0x1\");\n    }\n    return join $delimiter, @fixedaddrs;\n  }\n}\n\n# CPU profile reader\nsub ReadCPUProfile {\n  my $prog = shift;\n  my $fname = shift;       # just used for logging\n  local *PROFILE = shift;\n  my $version;\n  my $period;\n  my $i;\n  my $profile = {};\n  my $pcs = {};\n\n  # Parse string into array of slots.\n  my $slots = CpuProfileStream->new(*PROFILE, $fname);\n\n  # Read header.  The current header version is a 5-element structure\n  # containing:\n  #   0: header count (always 0)\n  #   1: header \"words\" (after this one: 3)\n  #   2: format version (0)\n  #   3: sampling period (usec)\n  #   4: unused padding (always 0)\n  if ($slots->get(0) != 0 ) {\n    error(\"$fname: not a profile file, or old format profile file\\n\");\n  }\n  $i = 2 + $slots->get(1);\n  $version = $slots->get(2);\n  $period = $slots->get(3);\n  # Do some sanity checking on these header values.\n  if ($version > (2**32) || $period > (2**32) || $i > (2**32) || $i < 5) {\n    error(\"$fname: not a profile file, or corrupted profile file\\n\");\n  }\n\n  # Parse profile\n  while ($slots->get($i) != -1) {\n    my $n = $slots->get($i++);\n    my $d = $slots->get($i++);\n    if ($d > (2**16)) {  # TODO(csilvers): what's a reasonable max-stack-depth?\n      my $addr = sprintf(\"0%o\", $i * ($address_length == 8 ? 4 : 8));\n      print STDERR \"At index $i (address $addr):\\n\";\n      error(\"$fname: stack trace depth >= 2**32\\n\");\n    }\n    if ($slots->get($i) == 0) {\n      # End of profile data marker\n      $i += $d;\n      last;\n    }\n\n    # Make key out of the stack entries\n    my @k = ();\n    for (my $j = 0; $j < $d; $j++) {\n      my $pc = $slots->get($i+$j);\n      # Subtract one from caller pc so we map back to call instr.\n      # However, don't do this if we're reading a symbolized profile\n      # file, in which case the subtract-one was done when the file\n      # was written.\n      if ($j > 0 && !$main::use_symbolized_profile) {\n        $pc--;\n      }\n      $pc = sprintf(\"%0*x\", $address_length, $pc);\n      $pcs->{$pc} = 1;\n      push @k, $pc;\n    }\n\n    AddEntry($profile, (join \"\\n\", @k), $n);\n    $i += $d;\n  }\n\n  # Parse map\n  my $map = '';\n  seek(PROFILE, $i * 4, 0);\n  read(PROFILE, $map, (stat PROFILE)[7]);\n\n  my $r = {};\n  $r->{version} = $version;\n  $r->{period} = $period;\n  $r->{profile} = $profile;\n  $r->{libs} = ParseLibraries($prog, $map, $pcs);\n  $r->{pcs} = $pcs;\n\n  return $r;\n}\n\nsub ReadHeapProfile {\n  my $prog = shift;\n  local *PROFILE = shift;\n  my $header = shift;\n\n  my $index = 1;\n  if ($main::opt_inuse_space) {\n    $index = 1;\n  } elsif ($main::opt_inuse_objects) {\n    $index = 0;\n  } elsif ($main::opt_alloc_space) {\n    $index = 3;\n  } elsif ($main::opt_alloc_objects) {\n    $index = 2;\n  }\n\n  # Find the type of this profile.  The header line looks like:\n  #    heap profile:   1246:  8800744 [  1246:  8800744] @ <heap-url>/266053\n  # There are two pairs <count: size>, the first inuse objects/space, and the\n  # second allocated objects/space.  This is followed optionally by a profile\n  # type, and if that is present, optionally by a sampling frequency.\n  # For remote heap profiles (v1):\n  # The interpretation of the sampling frequency is that the profiler, for\n  # each sample, calculates a uniformly distributed random integer less than\n  # the given value, and records the next sample after that many bytes have\n  # been allocated.  Therefore, the expected sample interval is half of the\n  # given frequency.  By default, if not specified, the expected sample\n  # interval is 128KB.  Only remote-heap-page profiles are adjusted for\n  # sample size.\n  # For remote heap profiles (v2):\n  # The sampling frequency is the rate of a Poisson process. This means that\n  # the probability of sampling an allocation of size X with sampling rate Y\n  # is 1 - exp(-X/Y)\n  # For version 2, a typical header line might look like this:\n  # heap profile:   1922: 127792360 [  1922: 127792360] @ <heap-url>_v2/524288\n  # the trailing number (524288) is the sampling rate. (Version 1 showed\n  # double the 'rate' here)\n  my $sampling_algorithm = 0;\n  my $sample_adjustment = 0;\n  chomp($header);\n  my $type = \"unknown\";\n  if ($header =~ m\"^heap profile:\\s*(\\d+):\\s+(\\d+)\\s+\\[\\s*(\\d+):\\s+(\\d+)\\](\\s*@\\s*([^/]*)(/(\\d+))?)?\") {\n    if (defined($6) && ($6 ne '')) {\n      $type = $6;\n      my $sample_period = $8;\n      # $type is \"heapprofile\" for profiles generated by the\n      # heap-profiler, and either \"heap\" or \"heap_v2\" for profiles\n      # generated by sampling directly within tcmalloc.  It can also\n      # be \"growth\" for heap-growth profiles.  The first is typically\n      # found for profiles generated locally, and the others for\n      # remote profiles.\n      if (($type eq \"heapprofile\") || ($type !~ /heap/) ) {\n        # No need to adjust for the sampling rate with heap-profiler-derived data\n        $sampling_algorithm = 0;\n      } elsif ($type =~ /_v2/) {\n        $sampling_algorithm = 2;     # version 2 sampling\n        if (defined($sample_period) && ($sample_period ne '')) {\n          $sample_adjustment = int($sample_period);\n        }\n      } else {\n        $sampling_algorithm = 1;     # version 1 sampling\n        if (defined($sample_period) && ($sample_period ne '')) {\n          $sample_adjustment = int($sample_period)/2;\n        }\n      }\n    } else {\n      # We detect whether or not this is a remote-heap profile by checking\n      # that the total-allocated stats ($n2,$s2) are exactly the\n      # same as the in-use stats ($n1,$s1).  It is remotely conceivable\n      # that a non-remote-heap profile may pass this check, but it is hard\n      # to imagine how that could happen.\n      # In this case it's so old it's guaranteed to be remote-heap version 1.\n      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);\n      if (($n1 == $n2) && ($s1 == $s2)) {\n        # This is likely to be a remote-heap based sample profile\n        $sampling_algorithm = 1;\n      }\n    }\n  }\n\n  if ($sampling_algorithm > 0) {\n    # For remote-heap generated profiles, adjust the counts and sizes to\n    # account for the sample rate (we sample once every 128KB by default).\n    if ($sample_adjustment == 0) {\n      # Turn on profile adjustment.\n      $sample_adjustment = 128*1024;\n      print STDERR \"Adjusting heap profiles for 1-in-128KB sampling rate\\n\";\n    } else {\n      printf STDERR (\"Adjusting heap profiles for 1-in-%d sampling rate\\n\",\n                     $sample_adjustment);\n    }\n    if ($sampling_algorithm > 1) {\n      # We don't bother printing anything for the original version (version 1)\n      printf STDERR \"Heap version $sampling_algorithm\\n\";\n    }\n  }\n\n  my $profile = {};\n  my $pcs = {};\n  my $map = \"\";\n\n  while (<PROFILE>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    if (/^MAPPED_LIBRARIES:/) {\n      # Read the /proc/self/maps data\n      while (<PROFILE>) {\n        s/\\r//g;         # turn windows-looking lines into unix-looking lines\n        $map .= $_;\n      }\n      last;\n    }\n\n    if (/^--- Memory map:/) {\n      # Read /proc/self/maps data as formatted by DumpAddressMap()\n      my $buildvar = \"\";\n      while (<PROFILE>) {\n        s/\\r//g;         # turn windows-looking lines into unix-looking lines\n        # Parse \"build=<dir>\" specification if supplied\n        if (m/^\\s*build=(.*)\\n/) {\n          $buildvar = $1;\n        }\n\n        # Expand \"$build\" variable if available\n        $_ =~ s/\\$build\\b/$buildvar/g;\n\n        $map .= $_;\n      }\n      last;\n    }\n\n    # Read entry of the form:\n    #  <count1>: <bytes1> [<count2>: <bytes2>] @ a1 a2 a3 ... an\n    s/^\\s*//;\n    s/\\s*$//;\n    if (m/^\\s*(\\d+):\\s+(\\d+)\\s+\\[\\s*(\\d+):\\s+(\\d+)\\]\\s+@\\s+(.*)$/) {\n      my $stack = $5;\n      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);\n\n      if ($sample_adjustment) {\n        if ($sampling_algorithm == 2) {\n          # Remote-heap version 2\n          # The sampling frequency is the rate of a Poisson process.\n          # This means that the probability of sampling an allocation of\n          # size X with sampling rate Y is 1 - exp(-X/Y)\n\t  if ($n1 != 0) {\n\t    my $ratio = (($s1*1.0)/$n1)/($sample_adjustment);\n\t    my $scale_factor = 1/(1 - exp(-$ratio));\n\t    $n1 *= $scale_factor;\n\t    $s1 *= $scale_factor;\n\t  }\n\t  if ($n2 != 0) {\n\t    my $ratio = (($s2*1.0)/$n2)/($sample_adjustment);\n\t    my $scale_factor = 1/(1 - exp(-$ratio));\n\t    $n2 *= $scale_factor;\n\t    $s2 *= $scale_factor;\n\t  }\n        } else {\n          # Remote-heap version 1\n          my $ratio;\n          $ratio = (($s1*1.0)/$n1)/($sample_adjustment);\n          if ($ratio < 1) {\n            $n1 /= $ratio;\n            $s1 /= $ratio;\n          }\n          $ratio = (($s2*1.0)/$n2)/($sample_adjustment);\n          if ($ratio < 1) {\n            $n2 /= $ratio;\n            $s2 /= $ratio;\n          }\n        }\n      }\n\n      my @counts = ($n1, $s1, $n2, $s2);\n      AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]);\n    }\n  }\n\n  my $r = {};\n  $r->{version} = \"heap\";\n  $r->{period} = 1;\n  $r->{profile} = $profile;\n  $r->{libs} = ParseLibraries($prog, $map, $pcs);\n  $r->{pcs} = $pcs;\n  return $r;\n}\n\nsub ReadSynchProfile {\n  my $prog = shift;\n  local *PROFILE = shift;\n  my $header = shift;\n\n  my $map = '';\n  my $profile = {};\n  my $pcs = {};\n  my $sampling_period = 1;\n  my $cyclespernanosec = 2.8;   # Default assumption for old binaries\n  my $seen_clockrate = 0;\n  my $line;\n\n  my $index = 0;\n  if ($main::opt_total_delay) {\n    $index = 0;\n  } elsif ($main::opt_contentions) {\n    $index = 1;\n  } elsif ($main::opt_mean_delay) {\n    $index = 2;\n  }\n\n  while ( $line = <PROFILE> ) {\n    $line =~ s/\\r//g;      # turn windows-looking lines into unix-looking lines\n    if ( $line =~ /^\\s*(\\d+)\\s+(\\d+) \\@\\s*(.*?)\\s*$/ ) {\n      my ($cycles, $count, $stack) = ($1, $2, $3);\n\n      # Convert cycles to nanoseconds\n      $cycles /= $cyclespernanosec;\n\n      # Adjust for sampling done by application\n      $cycles *= $sampling_period;\n      $count *= $sampling_period;\n\n      my @values = ($cycles, $count, $cycles / $count);\n      AddEntries($profile, $pcs, FixCallerAddresses($stack), $values[$index]);\n\n    } elsif ( $line =~ /^(slow release).*thread \\d+  \\@\\s*(.*?)\\s*$/ ||\n              $line =~ /^\\s*(\\d+) \\@\\s*(.*?)\\s*$/ ) {\n      my ($cycles, $stack) = ($1, $2);\n      if ($cycles !~ /^\\d+$/) {\n        next;\n      }\n\n      # Convert cycles to nanoseconds\n      $cycles /= $cyclespernanosec;\n\n      # Adjust for sampling done by application\n      $cycles *= $sampling_period;\n\n      AddEntries($profile, $pcs, FixCallerAddresses($stack), $cycles);\n\n    } elsif ( $line =~ m/^([a-z][^=]*)=(.*)$/ ) {\n      my ($variable, $value) = ($1,$2);\n      for ($variable, $value) {\n        s/^\\s+//;\n        s/\\s+$//;\n      }\n      if ($variable eq \"cycles/second\") {\n        $cyclespernanosec = $value / 1e9;\n        $seen_clockrate = 1;\n      } elsif ($variable eq \"sampling period\") {\n        $sampling_period = $value;\n      } elsif ($variable eq \"ms since reset\") {\n        # Currently nothing is done with this value in pprof\n        # So we just silently ignore it for now\n      } elsif ($variable eq \"discarded samples\") {\n        # Currently nothing is done with this value in pprof\n        # So we just silently ignore it for now\n      } else {\n        printf STDERR (\"Ignoring unnknown variable in /contention output: \" .\n                       \"'%s' = '%s'\\n\",$variable,$value);\n      }\n    } else {\n      # Memory map entry\n      $map .= $line;\n    }\n  }\n\n  if (!$seen_clockrate) {\n    printf STDERR (\"No cycles/second entry in profile; Guessing %.1f GHz\\n\",\n                   $cyclespernanosec);\n  }\n\n  my $r = {};\n  $r->{version} = 0;\n  $r->{period} = $sampling_period;\n  $r->{profile} = $profile;\n  $r->{libs} = ParseLibraries($prog, $map, $pcs);\n  $r->{pcs} = $pcs;\n  return $r;\n}\n\n# Given a hex value in the form \"0x1abcd\" return \"0001abcd\" or\n# \"000000000001abcd\", depending on the current address length.\n# There's probably a more idiomatic (or faster) way to do this...\nsub HexExtend {\n  my $addr = shift;\n\n  $addr =~ s/^0x//;\n\n  if (length $addr > $address_length) {\n    printf STDERR \"Warning:  address $addr is longer than address length $address_length\\n\";\n  }\n\n  return substr(\"000000000000000\".$addr, -$address_length);\n}\n\n##### Symbol extraction #####\n\n# Aggressively search the lib_prefix values for the given library\n# If all else fails, just return the name of the library unmodified.\n# If the lib_prefix is \"/my/path,/other/path\" and $file is \"/lib/dir/mylib.so\"\n# it will search the following locations in this order, until it finds a file:\n#   /my/path/lib/dir/mylib.so\n#   /other/path/lib/dir/mylib.so\n#   /my/path/dir/mylib.so\n#   /other/path/dir/mylib.so\n#   /my/path/mylib.so\n#   /other/path/mylib.so\n#   /lib/dir/mylib.so              (returned as last resort)\nsub FindLibrary {\n  my $file = shift;\n  my $suffix = $file;\n\n  # Search for the library as described above\n  do {\n    foreach my $prefix (@prefix_list) {\n      my $fullpath = $prefix . $suffix;\n      if (-e $fullpath) {\n        return $fullpath;\n      }\n    }\n  } while ($suffix =~ s|^/[^/]+/|/|);\n  return $file;\n}\n\n# Return path to library with debugging symbols.\n# For libc libraries, the copy in /usr/lib/debug contains debugging symbols\nsub DebuggingLibrary {\n  my $file = shift;\n  if ($file =~ m|^/| && -f \"/usr/lib/debug$file\") {\n    return \"/usr/lib/debug$file\";\n  }\n  return undef;\n}\n\n# Parse text section header of a library using objdump\nsub ParseTextSectionHeaderFromObjdump {\n  my $lib = shift;\n\n  my $size = undef;\n  my $vma;\n  my $file_offset;\n  # Get objdump output from the library file to figure out how to\n  # map between mapped addresses and addresses in the library.\n  my $objdump = $obj_tool_map{\"objdump\"};\n  open(OBJDUMP, \"$objdump -h $lib |\")\n                || error(\"$objdump $lib: $!\\n\");\n  while (<OBJDUMP>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    # Idx Name          Size      VMA       LMA       File off  Algn\n    #  10 .text         00104b2c  420156f0  420156f0  000156f0  2**4\n    # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file\n    # offset may still be 8.  But AddressSub below will still handle that.\n    my @x = split;\n    if (($#x >= 6) && ($x[1] eq '.text')) {\n      $size = $x[2];\n      $vma = $x[3];\n      $file_offset = $x[5];\n      last;\n    }\n  }\n  close(OBJDUMP);\n\n  if (!defined($size)) {\n    return undef;\n  }\n\n  my $r = {};\n  $r->{size} = $size;\n  $r->{vma} = $vma;\n  $r->{file_offset} = $file_offset;\n\n  return $r;\n}\n\n# Parse text section header of a library using otool (on OS X)\nsub ParseTextSectionHeaderFromOtool {\n  my $lib = shift;\n\n  my $size = undef;\n  my $vma = undef;\n  my $file_offset = undef;\n  # Get otool output from the library file to figure out how to\n  # map between mapped addresses and addresses in the library.\n  my $otool = $obj_tool_map{\"otool\"};\n  open(OTOOL, \"$otool -l $lib |\")\n                || error(\"$otool $lib: $!\\n\");\n  my $cmd = \"\";\n  my $sectname = \"\";\n  my $segname = \"\";\n  foreach my $line (<OTOOL>) {\n    $line =~ s/\\r//g;      # turn windows-looking lines into unix-looking lines\n    # Load command <#>\n    #       cmd LC_SEGMENT\n    # [...]\n    # Section\n    #   sectname __text\n    #    segname __TEXT\n    #       addr 0x000009f8\n    #       size 0x00018b9e\n    #     offset 2552\n    #      align 2^2 (4)\n    # We will need to strip off the leading 0x from the hex addresses,\n    # and convert the offset into hex.\n    if ($line =~ /Load command/) {\n      $cmd = \"\";\n      $sectname = \"\";\n      $segname = \"\";\n    } elsif ($line =~ /Section/) {\n      $sectname = \"\";\n      $segname = \"\";\n    } elsif ($line =~ /cmd (\\w+)/) {\n      $cmd = $1;\n    } elsif ($line =~ /sectname (\\w+)/) {\n      $sectname = $1;\n    } elsif ($line =~ /segname (\\w+)/) {\n      $segname = $1;\n    } elsif (!(($cmd eq \"LC_SEGMENT\" || $cmd eq \"LC_SEGMENT_64\") &&\n               $sectname eq \"__text\" &&\n               $segname eq \"__TEXT\")) {\n      next;\n    } elsif ($line =~ /\\baddr 0x([0-9a-fA-F]+)/) {\n      $vma = $1;\n    } elsif ($line =~ /\\bsize 0x([0-9a-fA-F]+)/) {\n      $size = $1;\n    } elsif ($line =~ /\\boffset ([0-9]+)/) {\n      $file_offset = sprintf(\"%016x\", $1);\n    }\n    if (defined($vma) && defined($size) && defined($file_offset)) {\n      last;\n    }\n  }\n  close(OTOOL);\n\n  if (!defined($vma) || !defined($size) || !defined($file_offset)) {\n     return undef;\n  }\n\n  my $r = {};\n  $r->{size} = $size;\n  $r->{vma} = $vma;\n  $r->{file_offset} = $file_offset;\n\n  return $r;\n}\n\nsub ParseTextSectionHeader {\n  # obj_tool_map(\"otool\") is only defined if we're in a Mach-O environment\n  if (defined($obj_tool_map{\"otool\"})) {\n    my $r = ParseTextSectionHeaderFromOtool(@_);\n    if (defined($r)){\n      return $r;\n    }\n  }\n  # If otool doesn't work, or we don't have it, fall back to objdump\n  return ParseTextSectionHeaderFromObjdump(@_);\n}\n\n# Split /proc/pid/maps dump into a list of libraries\nsub ParseLibraries {\n  return if $main::use_symbol_page;  # We don't need libraries info.\n  my $prog = shift;\n  my $map = shift;\n  my $pcs = shift;\n\n  my $result = [];\n  my $h = \"[a-f0-9]+\";\n  my $zero_offset = HexExtend(\"0\");\n\n  my $buildvar = \"\";\n  foreach my $l (split(\"\\n\", $map)) {\n    if ($l =~ m/^\\s*build=(.*)$/) {\n      $buildvar = $1;\n    }\n\n    my $start;\n    my $finish;\n    my $offset;\n    my $lib;\n    if ($l =~ /^($h)-($h)\\s+..x.\\s+($h)\\s+\\S+:\\S+\\s+\\d+\\s+(\\S+\\.(so|dll|dylib|bundle)((\\.\\d+)+\\w*(\\.\\d+){0,3})?)$/i) {\n      # Full line from /proc/self/maps.  Example:\n      #   40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so\n      $start = HexExtend($1);\n      $finish = HexExtend($2);\n      $offset = HexExtend($3);\n      $lib = $4;\n      $lib =~ s|\\\\|/|g;     # turn windows-style paths into unix-style paths\n    } elsif ($l =~ /^\\s*($h)-($h):\\s*(\\S+\\.so(\\.\\d+)*)/) {\n      # Cooked line from DumpAddressMap.  Example:\n      #   40000000-40015000: /lib/ld-2.3.2.so\n      $start = HexExtend($1);\n      $finish = HexExtend($2);\n      $offset = $zero_offset;\n      $lib = $3;\n    } else {\n      next;\n    }\n\n    # Expand \"$build\" variable if available\n    $lib =~ s/\\$build\\b/$buildvar/g;\n\n    $lib = FindLibrary($lib);\n\n    # Check for pre-relocated libraries, which use pre-relocated symbol tables\n    # and thus require adjusting the offset that we'll use to translate\n    # VM addresses into symbol table addresses.\n    # Only do this if we're not going to fetch the symbol table from a\n    # debugging copy of the library.\n    if (!DebuggingLibrary($lib)) {\n      my $text = ParseTextSectionHeader($lib);\n      if (defined($text)) {\n         my $vma_offset = AddressSub($text->{vma}, $text->{file_offset});\n         $offset = AddressAdd($offset, $vma_offset);\n      }\n    }\n\n    push(@{$result}, [$lib, $start, $finish, $offset]);\n  }\n\n  # Append special entry for additional library (not relocated)\n  if ($main::opt_lib ne \"\") {\n    my $text = ParseTextSectionHeader($main::opt_lib);\n    if (defined($text)) {\n       my $start = $text->{vma};\n       my $finish = AddressAdd($start, $text->{size});\n\n       push(@{$result}, [$main::opt_lib, $start, $finish, $start]);\n    }\n  }\n\n  # Append special entry for the main program.  This covers\n  # 0..max_pc_value_seen, so that we assume pc values not found in one\n  # of the library ranges will be treated as coming from the main\n  # program binary.\n  my $min_pc = HexExtend(\"0\");\n  my $max_pc = $min_pc;          # find the maximal PC value in any sample\n  foreach my $pc (keys(%{$pcs})) {\n    if (HexExtend($pc) gt $max_pc) { $max_pc = HexExtend($pc); }\n  }\n  push(@{$result}, [$prog, $min_pc, $max_pc, $zero_offset]);\n\n  return $result;\n}\n\n# Add two hex addresses of length $address_length.\n# Run pprof --test for unit test if this is changed.\nsub AddressAdd {\n  my $addr1 = shift;\n  my $addr2 = shift;\n  my $sum;\n\n  if ($address_length == 8) {\n    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:\n    $sum = (hex($addr1)+hex($addr2)) % (0x10000000 * 16);\n    return sprintf(\"%08x\", $sum);\n\n  } else {\n    # Do the addition in 7-nibble chunks to trivialize carry handling.\n\n    if ($main::opt_debug and $main::opt_test) {\n      print STDERR \"AddressAdd $addr1 + $addr2 = \";\n    }\n\n    my $a1 = substr($addr1,-7);\n    $addr1 = substr($addr1,0,-7);\n    my $a2 = substr($addr2,-7);\n    $addr2 = substr($addr2,0,-7);\n    $sum = hex($a1) + hex($a2);\n    my $c = 0;\n    if ($sum > 0xfffffff) {\n      $c = 1;\n      $sum -= 0x10000000;\n    }\n    my $r = sprintf(\"%07x\", $sum);\n\n    $a1 = substr($addr1,-7);\n    $addr1 = substr($addr1,0,-7);\n    $a2 = substr($addr2,-7);\n    $addr2 = substr($addr2,0,-7);\n    $sum = hex($a1) + hex($a2) + $c;\n    $c = 0;\n    if ($sum > 0xfffffff) {\n      $c = 1;\n      $sum -= 0x10000000;\n    }\n    $r = sprintf(\"%07x\", $sum) . $r;\n\n    $sum = hex($addr1) + hex($addr2) + $c;\n    if ($sum > 0xff) { $sum -= 0x100; }\n    $r = sprintf(\"%02x\", $sum) . $r;\n\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"$r\\n\"; }\n\n    return $r;\n  }\n}\n\n\n# Subtract two hex addresses of length $address_length.\n# Run pprof --test for unit test if this is changed.\nsub AddressSub {\n  my $addr1 = shift;\n  my $addr2 = shift;\n  my $diff;\n\n  if ($address_length == 8) {\n    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:\n    $diff = (hex($addr1)-hex($addr2)) % (0x10000000 * 16);\n    return sprintf(\"%08x\", $diff);\n\n  } else {\n    # Do the addition in 7-nibble chunks to trivialize borrow handling.\n    # if ($main::opt_debug) { print STDERR \"AddressSub $addr1 - $addr2 = \"; }\n\n    my $a1 = hex(substr($addr1,-7));\n    $addr1 = substr($addr1,0,-7);\n    my $a2 = hex(substr($addr2,-7));\n    $addr2 = substr($addr2,0,-7);\n    my $b = 0;\n    if ($a2 > $a1) {\n      $b = 1;\n      $a1 += 0x10000000;\n    }\n    $diff = $a1 - $a2;\n    my $r = sprintf(\"%07x\", $diff);\n\n    $a1 = hex(substr($addr1,-7));\n    $addr1 = substr($addr1,0,-7);\n    $a2 = hex(substr($addr2,-7)) + $b;\n    $addr2 = substr($addr2,0,-7);\n    $b = 0;\n    if ($a2 > $a1) {\n      $b = 1;\n      $a1 += 0x10000000;\n    }\n    $diff = $a1 - $a2;\n    $r = sprintf(\"%07x\", $diff) . $r;\n\n    $a1 = hex($addr1);\n    $a2 = hex($addr2) + $b;\n    if ($a2 > $a1) { $a1 += 0x100; }\n    $diff = $a1 - $a2;\n    $r = sprintf(\"%02x\", $diff) . $r;\n\n    # if ($main::opt_debug) { print STDERR \"$r\\n\"; }\n\n    return $r;\n  }\n}\n\n# Increment a hex addresses of length $address_length.\n# Run pprof --test for unit test if this is changed.\nsub AddressInc {\n  my $addr = shift;\n  my $sum;\n\n  if ($address_length == 8) {\n    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:\n    $sum = (hex($addr)+1) % (0x10000000 * 16);\n    return sprintf(\"%08x\", $sum);\n\n  } else {\n    # Do the addition in 7-nibble chunks to trivialize carry handling.\n    # We are always doing this to step through the addresses in a function,\n    # and will almost never overflow the first chunk, so we check for this\n    # case and exit early.\n\n    # if ($main::opt_debug) { print STDERR \"AddressInc $addr1 = \"; }\n\n    my $a1 = substr($addr,-7);\n    $addr = substr($addr,0,-7);\n    $sum = hex($a1) + 1;\n    my $r = sprintf(\"%07x\", $sum);\n    if ($sum <= 0xfffffff) {\n      $r = $addr . $r;\n      # if ($main::opt_debug) { print STDERR \"$r\\n\"; }\n      return HexExtend($r);\n    } else {\n      $r = \"0000000\";\n    }\n\n    $a1 = substr($addr,-7);\n    $addr = substr($addr,0,-7);\n    $sum = hex($a1) + 1;\n    $r = sprintf(\"%07x\", $sum) . $r;\n    if ($sum <= 0xfffffff) {\n      $r = $addr . $r;\n      # if ($main::opt_debug) { print STDERR \"$r\\n\"; }\n      return HexExtend($r);\n    } else {\n      $r = \"00000000000000\";\n    }\n\n    $sum = hex($addr) + 1;\n    if ($sum > 0xff) { $sum -= 0x100; }\n    $r = sprintf(\"%02x\", $sum) . $r;\n\n    # if ($main::opt_debug) { print STDERR \"$r\\n\"; }\n    return $r;\n  }\n}\n\n# Extract symbols for all PC values found in profile\nsub ExtractSymbols {\n  my $libs = shift;\n  my $pcset = shift;\n\n  my $symbols = {};\n\n  # Map each PC value to the containing library.  To make this faster,\n  # we sort libraries by their starting pc value (highest first), and\n  # advance through the libraries as we advance the pc.  Sometimes the\n  # addresses of libraries may overlap with the addresses of the main\n  # binary, so to make sure the libraries 'win', we iterate over the\n  # libraries in reverse order (which assumes the binary doesn't start\n  # in the middle of a library, which seems a fair assumption).\n  my @pcs = (sort { $a cmp $b } keys(%{$pcset}));  # pcset is 0-extended strings\n  foreach my $lib (sort {$b->[1] cmp $a->[1]} @{$libs}) {\n    my $libname = $lib->[0];\n    my $start = $lib->[1];\n    my $finish = $lib->[2];\n    my $offset = $lib->[3];\n\n    # Get list of pcs that belong in this library.\n    my $contained = [];\n    my ($start_pc_index, $finish_pc_index);\n    # Find smallest finish_pc_index such that $finish < $pc[$finish_pc_index].\n    for ($finish_pc_index = $#pcs + 1; $finish_pc_index > 0;\n\t $finish_pc_index--) {\n      last if $pcs[$finish_pc_index - 1] le $finish;\n    }\n    # Find smallest start_pc_index such that $start <= $pc[$start_pc_index].\n    for ($start_pc_index = $finish_pc_index; $start_pc_index > 0;\n\t $start_pc_index--) {\n      last if $pcs[$start_pc_index - 1] lt $start;\n    }\n    # This keeps PC values higher than $pc[$finish_pc_index] in @pcs,\n    # in case there are overlaps in libraries and the main binary.\n    @{$contained} = splice(@pcs, $start_pc_index,\n\t\t\t   $finish_pc_index - $start_pc_index);\n    # Map to symbols\n    MapToSymbols($libname, AddressSub($start, $offset), $contained, $symbols);\n  }\n\n  return $symbols;\n}\n\n# Map list of PC values to symbols for a given image\nsub MapToSymbols {\n  my $image = shift;\n  my $offset = shift;\n  my $pclist = shift;\n  my $symbols = shift;\n\n  my $debug = 0;\n\n  # Ignore empty binaries\n  if ($#{$pclist} < 0) { return; }\n\n  # Figure out the addr2line command to use\n  my $addr2line = $obj_tool_map{\"addr2line\"};\n  my $cmd = \"$addr2line -f -C -e $image\";\n  if (exists $obj_tool_map{\"addr2line_pdb\"}) {\n    $addr2line = $obj_tool_map{\"addr2line_pdb\"};\n    $cmd = \"$addr2line --demangle -f -C -e $image\";\n  }\n\n  # If \"addr2line\" isn't installed on the system at all, just use\n  # nm to get what info we can (function names, but not line numbers).\n  if (system(\"$addr2line --help >/dev/null 2>&1\") != 0) {\n    MapSymbolsWithNM($image, $offset, $pclist, $symbols);\n    return;\n  }\n\n  # \"addr2line -i\" can produce a variable number of lines per input\n  # address, with no separator that allows us to tell when data for\n  # the next address starts.  So we find the address for a special\n  # symbol (_fini) and interleave this address between all real\n  # addresses passed to addr2line.  The name of this special symbol\n  # can then be used as a separator.\n  $sep_address = undef;  # May be filled in by MapSymbolsWithNM()\n  my $nm_symbols = {};\n  MapSymbolsWithNM($image, $offset, $pclist, $nm_symbols);\n  # TODO(csilvers): only add '-i' if addr2line supports it.\n  if (defined($sep_address)) {\n    # Only add \" -i\" to addr2line if the binary supports it.\n    # addr2line --help returns 0, but not if it sees an unknown flag first.\n    if (system(\"$cmd -i --help >/dev/null 2>&1\") == 0) {\n      $cmd .= \" -i\";\n    } else {\n      $sep_address = undef;   # no need for sep_address if we don't support -i\n    }\n  }\n\n  # Make file with all PC values with intervening 'sep_address' so\n  # that we can reliably detect the end of inlined function list\n  open(ADDRESSES, \">$main::tmpfile_sym\") || error(\"$main::tmpfile_sym: $!\\n\");\n  if ($debug) { print(\"---- $image ---\\n\"); }\n  for (my $i = 0; $i <= $#{$pclist}; $i++) {\n    # addr2line always reads hex addresses, and does not need '0x' prefix.\n    if ($debug) { printf STDERR (\"%s\\n\", $pclist->[$i]); }\n    printf ADDRESSES (\"%s\\n\", AddressSub($pclist->[$i], $offset));\n    if (defined($sep_address)) {\n      printf ADDRESSES (\"%s\\n\", $sep_address);\n    }\n  }\n  close(ADDRESSES);\n  if ($debug) {\n    print(\"----\\n\");\n    system(\"cat $main::tmpfile_sym\");\n    print(\"----\\n\");\n    system(\"$cmd <$main::tmpfile_sym\");\n    print(\"----\\n\");\n  }\n\n  open(SYMBOLS, \"$cmd <$main::tmpfile_sym |\") || error(\"$cmd: $!\\n\");\n  my $count = 0;   # Index in pclist\n  while (<SYMBOLS>) {\n    # Read fullfunction and filelineinfo from next pair of lines\n    s/\\r?\\n$//g;\n    my $fullfunction = $_;\n    $_ = <SYMBOLS>;\n    s/\\r?\\n$//g;\n    my $filelinenum = $_;\n\n    if (defined($sep_address) && $fullfunction eq $sep_symbol) {\n      # Terminating marker for data for this address\n      $count++;\n      next;\n    }\n\n    $filelinenum =~ s|\\\\|/|g; # turn windows-style paths into unix-style paths\n\n    my $pcstr = $pclist->[$count];\n    my $function = ShortFunctionName($fullfunction);\n    if ($fullfunction eq '??') {\n      # See if nm found a symbol\n      my $nms = $nm_symbols->{$pcstr};\n      if (defined($nms)) {\n        $function = $nms->[0];\n        $fullfunction = $nms->[2];\n      }\n    }\n\n    # Prepend to accumulated symbols for pcstr\n    # (so that caller comes before callee)\n    my $sym = $symbols->{$pcstr};\n    if (!defined($sym)) {\n      $sym = [];\n      $symbols->{$pcstr} = $sym;\n    }\n    unshift(@{$sym}, $function, $filelinenum, $fullfunction);\n    if ($debug) { printf STDERR (\"%s => [%s]\\n\", $pcstr, join(\" \", @{$sym})); }\n    if (!defined($sep_address)) {\n      # Inlining is off, se this entry ends immediately\n      $count++;\n    }\n  }\n  close(SYMBOLS);\n}\n\n# Use nm to map the list of referenced PCs to symbols.  Return true iff we\n# are able to read procedure information via nm.\nsub MapSymbolsWithNM {\n  my $image = shift;\n  my $offset = shift;\n  my $pclist = shift;\n  my $symbols = shift;\n\n  # Get nm output sorted by increasing address\n  my $symbol_table = GetProcedureBoundaries($image, \".\");\n  if (!%{$symbol_table}) {\n    return 0;\n  }\n  # Start addresses are already the right length (8 or 16 hex digits).\n  my @names = sort { $symbol_table->{$a}->[0] cmp $symbol_table->{$b}->[0] }\n    keys(%{$symbol_table});\n\n  if ($#names < 0) {\n    # No symbols: just use addresses\n    foreach my $pc (@{$pclist}) {\n      my $pcstr = \"0x\" . $pc;\n      $symbols->{$pc} = [$pcstr, \"?\", $pcstr];\n    }\n    return 0;\n  }\n\n  # Sort addresses so we can do a join against nm output\n  my $index = 0;\n  my $fullname = $names[0];\n  my $name = ShortFunctionName($fullname);\n  foreach my $pc (sort { $a cmp $b } @{$pclist}) {\n    # Adjust for mapped offset\n    my $mpc = AddressSub($pc, $offset);\n    while (($index < $#names) && ($mpc ge $symbol_table->{$fullname}->[1])){\n      $index++;\n      $fullname = $names[$index];\n      $name = ShortFunctionName($fullname);\n    }\n    if ($mpc lt $symbol_table->{$fullname}->[1]) {\n      $symbols->{$pc} = [$name, \"?\", $fullname];\n    } else {\n      my $pcstr = \"0x\" . $pc;\n      $symbols->{$pc} = [$pcstr, \"?\", $pcstr];\n    }\n  }\n  return 1;\n}\n\nsub ShortFunctionName {\n  my $function = shift;\n  while ($function =~ s/\\([^()]*\\)(\\s*const)?//g) { }   # Argument types\n  while ($function =~ s/<[^<>]*>//g)  { }    # Remove template arguments\n  $function =~ s/^.*\\s+(\\w+::)/$1/;          # Remove leading type\n  return $function;\n}\n\n##### Miscellaneous #####\n\n# Find the right versions of the above object tools to use.  The\n# argument is the program file being analyzed, and should be an ELF\n# 32-bit or ELF 64-bit executable file.  The location of the tools\n# is determined by considering the following options in this order:\n#   1) --tools option, if set\n#   2) PPROF_TOOLS environment variable, if set\n#   3) the environment\nsub ConfigureObjTools {\n  my $prog_file = shift;\n\n  # Check for the existence of $prog_file because /usr/bin/file does not\n  # predictably return error status in prod.\n  (-e $prog_file)  || error(\"$prog_file does not exist.\\n\");\n\n  # Follow symlinks (at least for systems where \"file\" supports that)\n  my $file_type = `/usr/bin/file -L $prog_file 2>/dev/null || /usr/bin/file $prog_file`;\n  if ($file_type =~ /64-bit/) {\n    # Change $address_length to 16 if the program file is ELF 64-bit.\n    # We can't detect this from many (most?) heap or lock contention\n    # profiles, since the actual addresses referenced are generally in low\n    # memory even for 64-bit programs.\n    $address_length = 16;\n  }\n\n  if ($file_type =~ /MS Windows/) {\n    # For windows, we provide a version of nm and addr2line as part of\n    # the opensource release, which is capable of parsing\n    # Windows-style PDB executables.  It should live in the path, or\n    # in the same directory as pprof.\n    $obj_tool_map{\"nm_pdb\"} = \"nm-pdb\";\n    $obj_tool_map{\"addr2line_pdb\"} = \"addr2line-pdb\";\n  }\n\n  if ($file_type =~ /Mach-O/) {\n    # OS X uses otool to examine Mach-O files, rather than objdump.\n    $obj_tool_map{\"otool\"} = \"otool\";\n    $obj_tool_map{\"addr2line\"} = \"false\";  # no addr2line\n    $obj_tool_map{\"objdump\"} = \"false\";  # no objdump\n  }\n\n  # Go fill in %obj_tool_map with the pathnames to use:\n  foreach my $tool (keys %obj_tool_map) {\n    $obj_tool_map{$tool} = ConfigureTool($obj_tool_map{$tool});\n  }\n}\n\n# Returns the path of a caller-specified object tool.  If --tools or\n# PPROF_TOOLS are specified, then returns the full path to the tool\n# with that prefix.  Otherwise, returns the path unmodified (which\n# means we will look for it on PATH).\nsub ConfigureTool {\n  my $tool = shift;\n  my $path;\n\n  # --tools (or $PPROF_TOOLS) is a comma separated list, where each\n  # item is either a) a pathname prefix, or b) a map of the form\n  # <tool>:<path>.  First we look for an entry of type (b) for our\n  # tool.  If one is found, we use it.  Otherwise, we consider all the\n  # pathname prefixes in turn, until one yields an existing file.  If\n  # none does, we use a default path.\n  my $tools = $main::opt_tools || $ENV{\"PPROF_TOOLS\"} || \"\";\n  if ($tools =~ m/(,|^)\\Q$tool\\E:([^,]*)/) {\n    $path = $2;\n    # TODO(csilvers): sanity-check that $path exists?  Hard if it's relative.\n  } elsif ($tools ne '') {\n    foreach my $prefix (split(',', $tools)) {\n      next if ($prefix =~ /:/);    # ignore \"tool:fullpath\" entries in the list\n      if (-x $prefix . $tool) {\n        $path = $prefix . $tool;\n        last;\n      }\n    }\n    if (!$path) {\n      error(\"No '$tool' found with prefix specified by \" .\n            \"--tools (or \\$PPROF_TOOLS) '$tools'\\n\");\n    }\n  } else {\n    # ... otherwise use the version that exists in the same directory as\n    # pprof.  If there's nothing there, use $PATH.\n    $0 =~ m,[^/]*$,;     # this is everything after the last slash\n    my $dirname = $`;    # this is everything up to and including the last slash\n    if (-x \"$dirname$tool\") {\n      $path = \"$dirname$tool\";\n    } else { \n      $path = $tool;\n    }\n  }\n  if ($main::opt_debug) { print STDERR \"Using '$path' for '$tool'.\\n\"; }\n  return $path;\n}\n\nsub cleanup {\n  unlink($main::tmpfile_sym);\n  unlink(keys %main::tempnames);\n\n  # We leave any collected profiles in $HOME/pprof in case the user wants\n  # to look at them later.  We print a message informing them of this.\n  if ((scalar(@main::profile_files) > 0) &&\n      defined($main::collected_profile)) {\n    if (scalar(@main::profile_files) == 1) {\n      print STDERR \"Dynamically gathered profile is in $main::collected_profile\\n\";\n    }\n    print STDERR \"If you want to investigate this profile further, you can do:\\n\";\n    print STDERR \"\\n\";\n    print STDERR \"  pprof \\\\\\n\";\n    print STDERR \"    $main::prog \\\\\\n\";\n    print STDERR \"    $main::collected_profile\\n\";\n    print STDERR \"\\n\";\n  }\n}\n\nsub sighandler {\n  cleanup();\n  exit(1);\n}\n\nsub error {\n  my $msg = shift;\n  print STDERR $msg;\n  cleanup();\n  exit(1);\n}\n\n\n# Run $nm_command and get all the resulting procedure boundaries whose\n# names match \"$regexp\" and returns them in a hashtable mapping from\n# procedure name to a two-element vector of [start address, end address]\nsub GetProcedureBoundariesViaNm {\n  my $nm_command = shift;\n  my $regexp = shift;\n\n  my $symbol_table = {};\n  open(NM, \"$nm_command |\") || error(\"$nm_command: $!\\n\");\n  my $last_start = \"0\";\n  my $routine = \"\";\n  while (<NM>) {\n    s/\\r//g;         # turn windows-looking lines into unix-looking lines\n    if (m/^\\s*([0-9a-f]+) (.) (..*)/) {\n      my $start_val = $1;\n      my $type = $2;\n      my $this_routine = $3;\n\n      # It's possible for two symbols to share the same address, if\n      # one is a zero-length variable (like __start_google_malloc) or\n      # one symbol is a weak alias to another (like __libc_malloc).\n      # In such cases, we want to ignore all values except for the\n      # actual symbol, which in nm-speak has type \"T\".  The logic\n      # below does this, though it's a bit tricky: what happens when\n      # we have a series of lines with the same address, is the first\n      # one gets queued up to be processed.  However, it won't\n      # *actually* be processed until later, when we read a line with\n      # a different address.  That means that as long as we're reading\n      # lines with the same address, we have a chance to replace that\n      # item in the queue, which we do whenever we see a 'T' entry --\n      # that is, a line with type 'T'.  If we never see a 'T' entry,\n      # we'll just go ahead and process the first entry (which never\n      # got touched in the queue), and ignore the others.\n      if ($start_val eq $last_start && $type =~ /t/i) {\n        # We are the 'T' symbol at this address, replace previous symbol.\n        $routine = $this_routine;\n        next;\n      } elsif ($start_val eq $last_start) {\n        # We're not the 'T' symbol at this address, so ignore us.\n        next;\n      }\n\n      if ($this_routine eq $sep_symbol) {\n        $sep_address = HexExtend($start_val);\n      }\n\n      # Tag this routine with the starting address in case the image\n      # has multiple occurrences of this routine.  We use a syntax\n      # that resembles template paramters that are automatically\n      # stripped out by ShortFunctionName()\n      $this_routine .= \"<$start_val>\";\n\n      if (defined($routine) && $routine =~ m/$regexp/) {\n        $symbol_table->{$routine} = [HexExtend($last_start),\n                                     HexExtend($start_val)];\n      }\n      $last_start = $start_val;\n      $routine = $this_routine;\n    } elsif (m/^Loaded image name: (.+)/) {\n      # The win32 nm workalike emits information about the binary it is using.\n      if ($main::opt_debug) { print STDERR \"Using Image $1\\n\"; }\n    } elsif (m/^PDB file name: (.+)/) {\n      # The win32 nm workalike emits information about the pdb it is using.\n      if ($main::opt_debug) { print STDERR \"Using PDB $1\\n\"; }\n    }\n  }\n  close(NM);\n  # Handle the last line in the nm output.  Unfortunately, we don't know\n  # how big this last symbol is, because we don't know how big the file\n  # is.  For now, we just give it a size of 0.\n  # TODO(csilvers): do better here.\n  if (defined($routine) && $routine =~ m/$regexp/) {\n    $symbol_table->{$routine} = [HexExtend($last_start),\n                                 HexExtend($last_start)];\n  }\n  return $symbol_table;\n}\n\n# Gets the procedure boundaries for all routines in \"$image\" whose names\n# match \"$regexp\" and returns them in a hashtable mapping from procedure\n# name to a two-element vector of [start address, end address].\n# Will return an empty map if nm is not installed or not working properly.\nsub GetProcedureBoundaries {\n  my $image = shift;\n  my $regexp = shift;\n\n  # For libc libraries, the copy in /usr/lib/debug contains debugging symbols\n  my $debugging = DebuggingLibrary($image);\n  if ($debugging) {\n    $image = $debugging;\n  }\n\n  my $nm = $obj_tool_map{\"nm\"};\n  my $cppfilt = $obj_tool_map{\"c++filt\"};\n\n  # nm can fail for two reasons: 1) $image isn't a debug library; 2) nm\n  # binary doesn't support --demangle.  In addition, for OS X we need\n  # to use the -f flag to get 'flat' nm output (otherwise we don't sort\n  # properly and get incorrect results).  Unfortunately, GNU nm uses -f\n  # in an incompatible way.  So first we test whether our nm supports\n  # --demangle and -f.\n  my $demangle_flag = \"\";\n  my $cppfilt_flag = \"\";\n  if (system(\"$nm --demangle $image >/dev/null 2>&1\") == 0) {\n    # In this mode, we do \"nm --demangle <foo>\"\n    $demangle_flag = \"--demangle\";\n    $cppfilt_flag = \"\";\n  } elsif (system(\"$cppfilt $image >/dev/null 2>&1\") == 0) {\n    # In this mode, we do \"nm <foo> | c++filt\"\n    $cppfilt_flag = \" | $cppfilt\";\n  };\n  my $flatten_flag = \"\";\n  if (system(\"$nm -f $image >/dev/null 2>&1\") == 0) {\n    $flatten_flag = \"-f\";\n  }\n\n  # Finally, in the case $imagie isn't a debug library, we try again with\n  # -D to at least get *exported* symbols.  If we can't use --demangle,\n  # we use c++filt instead, if it exists on this system.\n  my @nm_commands = (\"$nm -n $flatten_flag $demangle_flag\" .\n                     \" $image 2>/dev/null $cppfilt_flag\",\n                     \"$nm -D -n $flatten_flag $demangle_flag\" .\n                     \" $image 2>/dev/null $cppfilt_flag\",\n                     # 6nm is for Go binaries\n\t\t     \"6nm $image 2>/dev/null | sort\",\n                     );\n\n  # If the executable is an MS Windows PDB-format executable, we'll\n  # have set up obj_tool_map(\"nm_pdb\").  In this case, we actually\n  # want to use both unix nm and windows-specific nm_pdb, since\n  # PDB-format executables can apparently include dwarf .o files.\n  if (exists $obj_tool_map{\"nm_pdb\"}) {\n    my $nm_pdb = $obj_tool_map{\"nm_pdb\"};\n    push(@nm_commands, \"$nm_pdb --demangle $image 2>/dev/null\");\n  }\n\n  foreach my $nm_command (@nm_commands) {\n    my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);\n    return $symbol_table if (%{$symbol_table});\n  }\n  my $symbol_table = {};\n  return $symbol_table;\n}\n\n\n# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.\n# To make them more readable, we add underscores at interesting places.\n# This routine removes the underscores, producing the canonical representation\n# used by pprof to represent addresses, particularly in the tested routines.\nsub CanonicalHex {\n  my $arg = shift;\n  return join '', (split '_',$arg);\n}\n\n\n# Unit test for AddressAdd:\nsub AddressAddUnitTest {\n  my $test_data_8 = shift;\n  my $test_data_16 = shift;\n  my $error_count = 0;\n  my $fail_count = 0;\n  my $pass_count = 0;\n  # print STDERR \"AddressAddUnitTest: \", 1+$#{$test_data_8}, \" tests\\n\";\n\n  # First a few 8-nibble addresses.  Note that this implementation uses\n  # plain old arithmetic, so a quick sanity check along with verifying what\n  # happens to overflow (we want it to wrap):\n  $address_length = 8;\n  foreach my $row (@{$test_data_8}) {\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"@{$row}\\n\"; }\n    my $sum = AddressAdd ($row->[0], $row->[1]);\n    if ($sum ne $row->[2]) {\n      printf STDERR \"ERROR: %s != %s + %s = %s\\n\", $sum,\n             $row->[0], $row->[1], $row->[2];\n      ++$fail_count;\n    } else {\n      ++$pass_count;\n    }\n  }\n  printf STDERR \"AddressAdd 32-bit tests: %d passes, %d failures\\n\",\n         $pass_count, $fail_count;\n  $error_count = $fail_count;\n  $fail_count = 0;\n  $pass_count = 0;\n\n  # Now 16-nibble addresses.\n  $address_length = 16;\n  foreach my $row (@{$test_data_16}) {\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"@{$row}\\n\"; }\n    my $sum = AddressAdd (CanonicalHex($row->[0]), CanonicalHex($row->[1]));\n    my $expected = join '', (split '_',$row->[2]);\n    if ($sum ne CanonicalHex($row->[2])) {\n      printf STDERR \"ERROR: %s != %s + %s = %s\\n\", $sum,\n             $row->[0], $row->[1], $row->[2];\n      ++$fail_count;\n    } else {\n      ++$pass_count;\n    }\n  }\n  printf STDERR \"AddressAdd 64-bit tests: %d passes, %d failures\\n\",\n         $pass_count, $fail_count;\n  $error_count += $fail_count;\n\n  return $error_count;\n}\n\n\n# Unit test for AddressSub:\nsub AddressSubUnitTest {\n  my $test_data_8 = shift;\n  my $test_data_16 = shift;\n  my $error_count = 0;\n  my $fail_count = 0;\n  my $pass_count = 0;\n  # print STDERR \"AddressSubUnitTest: \", 1+$#{$test_data_8}, \" tests\\n\";\n\n  # First a few 8-nibble addresses.  Note that this implementation uses\n  # plain old arithmetic, so a quick sanity check along with verifying what\n  # happens to overflow (we want it to wrap):\n  $address_length = 8;\n  foreach my $row (@{$test_data_8}) {\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"@{$row}\\n\"; }\n    my $sum = AddressSub ($row->[0], $row->[1]);\n    if ($sum ne $row->[3]) {\n      printf STDERR \"ERROR: %s != %s - %s = %s\\n\", $sum,\n             $row->[0], $row->[1], $row->[3];\n      ++$fail_count;\n    } else {\n      ++$pass_count;\n    }\n  }\n  printf STDERR \"AddressSub 32-bit tests: %d passes, %d failures\\n\",\n         $pass_count, $fail_count;\n  $error_count = $fail_count;\n  $fail_count = 0;\n  $pass_count = 0;\n\n  # Now 16-nibble addresses.\n  $address_length = 16;\n  foreach my $row (@{$test_data_16}) {\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"@{$row}\\n\"; }\n    my $sum = AddressSub (CanonicalHex($row->[0]), CanonicalHex($row->[1]));\n    if ($sum ne CanonicalHex($row->[3])) {\n      printf STDERR \"ERROR: %s != %s - %s = %s\\n\", $sum,\n             $row->[0], $row->[1], $row->[3];\n      ++$fail_count;\n    } else {\n      ++$pass_count;\n    }\n  }\n  printf STDERR \"AddressSub 64-bit tests: %d passes, %d failures\\n\",\n         $pass_count, $fail_count;\n  $error_count += $fail_count;\n\n  return $error_count;\n}\n\n\n# Unit test for AddressInc:\nsub AddressIncUnitTest {\n  my $test_data_8 = shift;\n  my $test_data_16 = shift;\n  my $error_count = 0;\n  my $fail_count = 0;\n  my $pass_count = 0;\n  # print STDERR \"AddressIncUnitTest: \", 1+$#{$test_data_8}, \" tests\\n\";\n\n  # First a few 8-nibble addresses.  Note that this implementation uses\n  # plain old arithmetic, so a quick sanity check along with verifying what\n  # happens to overflow (we want it to wrap):\n  $address_length = 8;\n  foreach my $row (@{$test_data_8}) {\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"@{$row}\\n\"; }\n    my $sum = AddressInc ($row->[0]);\n    if ($sum ne $row->[4]) {\n      printf STDERR \"ERROR: %s != %s + 1 = %s\\n\", $sum,\n             $row->[0], $row->[4];\n      ++$fail_count;\n    } else {\n      ++$pass_count;\n    }\n  }\n  printf STDERR \"AddressInc 32-bit tests: %d passes, %d failures\\n\",\n         $pass_count, $fail_count;\n  $error_count = $fail_count;\n  $fail_count = 0;\n  $pass_count = 0;\n\n  # Now 16-nibble addresses.\n  $address_length = 16;\n  foreach my $row (@{$test_data_16}) {\n    if ($main::opt_debug and $main::opt_test) { print STDERR \"@{$row}\\n\"; }\n    my $sum = AddressInc (CanonicalHex($row->[0]));\n    if ($sum ne CanonicalHex($row->[4])) {\n      printf STDERR \"ERROR: %s != %s + 1 = %s\\n\", $sum,\n             $row->[0], $row->[4];\n      ++$fail_count;\n    } else {\n      ++$pass_count;\n    }\n  }\n  printf STDERR \"AddressInc 64-bit tests: %d passes, %d failures\\n\",\n         $pass_count, $fail_count;\n  $error_count += $fail_count;\n\n  return $error_count;\n}\n\n\n# Driver for unit tests.\n# Currently just the address add/subtract/increment routines for 64-bit.\nsub RunUnitTests {\n  my $error_count = 0;\n\n  # This is a list of tuples [a, b, a+b, a-b, a+1]\n  my $unit_test_data_8 = [\n    [qw(aaaaaaaa 50505050 fafafafa 5a5a5a5a aaaaaaab)],\n    [qw(50505050 aaaaaaaa fafafafa a5a5a5a6 50505051)],\n    [qw(ffffffff aaaaaaaa aaaaaaa9 55555555 00000000)],\n    [qw(00000001 ffffffff 00000000 00000002 00000002)],\n    [qw(00000001 fffffff0 fffffff1 00000011 00000002)],\n  ];\n  my $unit_test_data_16 = [\n    # The implementation handles data in 7-nibble chunks, so those are the\n    # interesting boundaries.\n    [qw(aaaaaaaa 50505050\n        00_000000f_afafafa 00_0000005_a5a5a5a 00_000000a_aaaaaab)],\n    [qw(50505050 aaaaaaaa\n        00_000000f_afafafa ff_ffffffa_5a5a5a6 00_0000005_0505051)],\n    [qw(ffffffff aaaaaaaa\n        00_000001a_aaaaaa9 00_0000005_5555555 00_0000010_0000000)],\n    [qw(00000001 ffffffff\n        00_0000010_0000000 ff_ffffff0_0000002 00_0000000_0000002)],\n    [qw(00000001 fffffff0\n        00_000000f_ffffff1 ff_ffffff0_0000011 00_0000000_0000002)],\n\n    [qw(00_a00000a_aaaaaaa 50505050\n        00_a00000f_afafafa 00_a000005_a5a5a5a 00_a00000a_aaaaaab)],\n    [qw(0f_fff0005_0505050 aaaaaaaa\n        0f_fff000f_afafafa 0f_ffefffa_5a5a5a6 0f_fff0005_0505051)],\n    [qw(00_000000f_fffffff 01_800000a_aaaaaaa\n        01_800001a_aaaaaa9 fe_8000005_5555555 00_0000010_0000000)],\n    [qw(00_0000000_0000001 ff_fffffff_fffffff\n        00_0000000_0000000 00_0000000_0000002 00_0000000_0000002)],\n    [qw(00_0000000_0000001 ff_fffffff_ffffff0\n        ff_fffffff_ffffff1 00_0000000_0000011 00_0000000_0000002)],\n  ];\n\n  $error_count += AddressAddUnitTest($unit_test_data_8, $unit_test_data_16);\n  $error_count += AddressSubUnitTest($unit_test_data_8, $unit_test_data_16);\n  $error_count += AddressIncUnitTest($unit_test_data_8, $unit_test_data_16);\n  if ($error_count > 0) {\n    print STDERR $error_count, \" errors: FAILED\\n\";\n  } else {\n    print STDERR \"PASS\\n\";\n  }\n  exit ($error_count);\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/profile-handler.cc",
    "content": "// Copyright (c) 2009, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//         Nabeel Mian\n//\n// Implements management of profile timers and the corresponding signal handler.\n\n#include \"config.h\"\n#include \"profile-handler.h\"\n\n#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))\n\n#include <stdio.h>\n#include <errno.h>\n#include <sys/time.h>\n\n#include <list>\n#include <string>\n\n#include \"base/dynamic_annotations.h\"\n#include \"base/logging.h\"\n#include \"base/spinlock.h\"\n#include \"maybe_threads.h\"\n\nusing std::list;\nusing std::string;\n\n// This structure is used by ProfileHandlerRegisterCallback and\n// ProfileHandlerUnregisterCallback as a handle to a registered callback.\nstruct ProfileHandlerToken {\n  // Sets the callback and associated arg.\n  ProfileHandlerToken(ProfileHandlerCallback cb, void* cb_arg)\n      : callback(cb),\n        callback_arg(cb_arg) {\n  }\n\n  // Callback function to be invoked on receiving a profile timer interrupt.\n  ProfileHandlerCallback callback;\n  // Argument for the callback function.\n  void* callback_arg;\n};\n\n// This class manages profile timers and associated signal handler. This is a\n// a singleton.\nclass ProfileHandler {\n public:\n  // Registers the current thread with the profile handler. On systems which\n  // have a separate interval timer for each thread, this function starts the\n  // timer for the current thread.\n  //\n  // The function also attempts to determine whether or not timers are shared by\n  // all threads in the process.  (With LinuxThreads, and with NPTL on some\n  // Linux kernel versions, each thread has separate timers.)\n  //\n  // Prior to determining whether timers are shared, this function will\n  // unconditionally start the timer.  However, if this function determines\n  // that timers are shared, then it will stop the timer if no callbacks are\n  // currently registered.\n  void RegisterThread();\n\n  // Registers a callback routine to receive profile timer ticks. The returned\n  // token is to be used when unregistering this callback and must not be\n  // deleted by the caller. Registration of the first callback enables the\n  // SIGPROF handler (or SIGALRM if using ITIMER_REAL).\n  ProfileHandlerToken* RegisterCallback(ProfileHandlerCallback callback,\n                                        void* callback_arg);\n\n  // Unregisters a previously registered callback. Expects the token returned\n  // by the corresponding RegisterCallback routine. Unregistering the last\n  // callback disables the SIGPROF handler (or SIGALRM if using ITIMER_REAL).\n  void UnregisterCallback(ProfileHandlerToken* token)\n      NO_THREAD_SAFETY_ANALYSIS;\n\n  // Unregisters all the callbacks, stops the timer if shared, disables the\n  // SIGPROF (or SIGALRM) handler and clears the timer_sharing_ state.\n  void Reset();\n\n  // Gets the current state of profile handler.\n  void GetState(ProfileHandlerState* state);\n\n  // Initializes and returns the ProfileHandler singleton.\n  static ProfileHandler* Instance();\n\n private:\n  ProfileHandler();\n  ~ProfileHandler();\n\n  // Largest allowed frequency.\n  static const int32 kMaxFrequency = 4000;\n  // Default frequency.\n  static const int32 kDefaultFrequency = 100;\n\n  // ProfileHandler singleton.\n  static ProfileHandler* instance_;\n\n  // pthread_once_t for one time initialization of ProfileHandler singleton.\n  static pthread_once_t once_;\n\n  // Initializes the ProfileHandler singleton via GoogleOnceInit.\n  static void Init();\n\n  // The number of SIGPROF (or SIGALRM for ITIMER_REAL) interrupts received.\n  int64 interrupts_ GUARDED_BY(signal_lock_);\n\n  // SIGPROF/SIGALRM interrupt frequency, read-only after construction.\n  int32 frequency_;\n\n  // ITIMER_PROF (which uses SIGPROF), or ITIMER_REAL (which uses SIGALRM)\n  int timer_type_;\n\n  // Counts the number of callbacks registered.\n  int32 callback_count_ GUARDED_BY(control_lock_);\n\n  // Whether or not the threading system provides interval timers that are\n  // shared by all threads in a process.\n  enum {\n    // No timer initialization attempted yet.\n    TIMERS_UNTOUCHED,\n    // First thread has registered and set timer.\n    TIMERS_ONE_SET,\n    // Timers are shared by all threads.\n    TIMERS_SHARED,\n    // Timers are separate in each thread.\n    TIMERS_SEPARATE\n  } timer_sharing_ GUARDED_BY(control_lock_);\n\n  // This lock serializes the registration of threads and protects the\n  // callbacks_ list below.\n  // Locking order:\n  // In the context of a signal handler, acquire signal_lock_ to walk the\n  // callback list. Otherwise, acquire control_lock_, disable the signal\n  // handler and then acquire signal_lock_.\n  SpinLock control_lock_ ACQUIRED_BEFORE(signal_lock_);\n  SpinLock signal_lock_;\n\n  // Holds the list of registered callbacks. We expect the list to be pretty\n  // small. Currently, the cpu profiler (base/profiler) and thread module\n  // (base/thread.h) are the only two components registering callbacks.\n  // Following are the locking requirements for callbacks_:\n  // For read-write access outside the SIGPROF handler:\n  //  - Acquire control_lock_\n  //  - Disable SIGPROF handler.\n  //  - Acquire signal_lock_\n  // For read-only access in the context of SIGPROF handler\n  // (Read-write access is *not allowed* in the SIGPROF handler)\n  //  - Acquire signal_lock_\n  // For read-only access outside SIGPROF handler:\n  //  - Acquire control_lock_\n  typedef list<ProfileHandlerToken*> CallbackList;\n  typedef CallbackList::iterator CallbackIterator;\n  CallbackList callbacks_ GUARDED_BY(signal_lock_);\n\n  // Starts the interval timer.  If the thread library shares timers between\n  // threads, this function starts the shared timer. Otherwise, this will start\n  // the timer in the current thread.\n  void StartTimer() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);\n\n  // Stops the interval timer. If the thread library shares timers between\n  // threads, this fucntion stops the shared timer. Otherwise, this will stop\n  // the timer in the current thread.\n  void StopTimer() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);\n\n  // Returns true if the profile interval timer is enabled in the current\n  // thread.  This actually checks the kernel's interval timer setting.  (It is\n  // used to detect whether timers are shared or separate.)\n  bool IsTimerRunning() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);\n\n  // Sets the timer interrupt signal handler.\n  void EnableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);\n\n  // Disables (ignores) the timer interrupt signal.\n  void DisableHandler() EXCLUSIVE_LOCKS_REQUIRED(control_lock_);\n\n  // SIGPROF/SIGALRM handler. Iterate over and call all the registered callbacks.\n  static void SignalHandler(int sig, siginfo_t* sinfo, void* ucontext);\n\n  DISALLOW_COPY_AND_ASSIGN(ProfileHandler);\n};\n\nProfileHandler* ProfileHandler::instance_ = NULL;\npthread_once_t ProfileHandler::once_ = PTHREAD_ONCE_INIT;\n\nconst int32 ProfileHandler::kMaxFrequency;\nconst int32 ProfileHandler::kDefaultFrequency;\n\n// If we are LD_PRELOAD-ed against a non-pthreads app, then\n// pthread_once won't be defined.  We declare it here, for that\n// case (with weak linkage) which will cause the non-definition to\n// resolve to NULL.  We can then check for NULL or not in Instance.\nextern \"C\" int pthread_once(pthread_once_t *, void (*)(void))\n    ATTRIBUTE_WEAK;\n\nvoid ProfileHandler::Init() {\n  instance_ = new ProfileHandler();\n}\n\nProfileHandler* ProfileHandler::Instance() {\n  if (pthread_once) {\n    pthread_once(&once_, Init);\n  }\n  if (instance_ == NULL) {\n    // This will be true on systems that don't link in pthreads,\n    // including on FreeBSD where pthread_once has a non-zero address\n    // (but doesn't do anything) even when pthreads isn't linked in.\n    Init();\n    assert(instance_ != NULL);\n  }\n  return instance_;\n}\n\nProfileHandler::ProfileHandler()\n    : interrupts_(0),\n      callback_count_(0),\n      timer_sharing_(TIMERS_UNTOUCHED) {\n  SpinLockHolder cl(&control_lock_);\n\n  timer_type_ = (getenv(\"CPUPROFILE_REALTIME\") ? ITIMER_REAL : ITIMER_PROF);\n\n  // Get frequency of interrupts (if specified)\n  char junk;\n  const char* fr = getenv(\"CPUPROFILE_FREQUENCY\");\n  if (fr != NULL && (sscanf(fr, \"%u%c\", &frequency_, &junk) == 1) &&\n      (frequency_ > 0)) {\n    // Limit to kMaxFrequency\n    frequency_ = (frequency_ > kMaxFrequency) ? kMaxFrequency : frequency_;\n  } else {\n    frequency_ = kDefaultFrequency;\n  }\n\n  // Ignore signals until we decide to turn profiling on.  (Paranoia;\n  // should already be ignored.)\n  DisableHandler();\n}\n\nProfileHandler::~ProfileHandler() {\n  Reset();\n}\n\nvoid ProfileHandler::RegisterThread() {\n  SpinLockHolder cl(&control_lock_);\n\n  // We try to detect whether timers are being shared by setting a\n  // timer in the first call to this function, then checking whether\n  // it's set in the second call.\n  //\n  // Note that this detection method requires that the first two calls\n  // to RegisterThread must be made from different threads.  (Subsequent\n  // calls will see timer_sharing_ set to either TIMERS_SEPARATE or\n  // TIMERS_SHARED, and won't try to detect the timer sharing type.)\n  //\n  // Also note that if timer settings were inherited across new thread\n  // creation but *not* shared, this approach wouldn't work.  That's\n  // not an issue for any Linux threading implementation, and should\n  // not be a problem for a POSIX-compliant threads implementation.\n  switch (timer_sharing_) {\n    case TIMERS_UNTOUCHED:\n      StartTimer();\n      timer_sharing_ = TIMERS_ONE_SET;\n      break;\n    case TIMERS_ONE_SET:\n      // If the timer is running, that means that the main thread's\n      // timer setup is seen in this (second) thread -- and therefore\n      // that timers are shared.\n      if (IsTimerRunning()) {\n        timer_sharing_ = TIMERS_SHARED;\n        // If callback is already registered, we have to keep the timer\n        // running.  If not, we disable the timer here.\n        if (callback_count_ == 0) {\n          StopTimer();\n        }\n      } else {\n        timer_sharing_ = TIMERS_SEPARATE;\n        StartTimer();\n      }\n      break;\n    case TIMERS_SHARED:\n      // Nothing needed.\n      break;\n    case TIMERS_SEPARATE:\n      StartTimer();\n      break;\n  }\n}\n\nProfileHandlerToken* ProfileHandler::RegisterCallback(\n    ProfileHandlerCallback callback, void* callback_arg) {\n  ProfileHandlerToken* token = new ProfileHandlerToken(callback, callback_arg);\n\n  SpinLockHolder cl(&control_lock_);\n  DisableHandler();\n  {\n    SpinLockHolder sl(&signal_lock_);\n    callbacks_.push_back(token);\n  }\n  // Start the timer if timer is shared and this is a first callback.\n  if ((callback_count_ == 0) && (timer_sharing_ == TIMERS_SHARED)) {\n    StartTimer();\n  }\n  ++callback_count_;\n  EnableHandler();\n  return token;\n}\n\nvoid ProfileHandler::UnregisterCallback(ProfileHandlerToken* token) {\n  SpinLockHolder cl(&control_lock_);\n  for (CallbackIterator it = callbacks_.begin(); it != callbacks_.end();\n       ++it) {\n    if ((*it) == token) {\n      RAW_CHECK(callback_count_ > 0, \"Invalid callback count\");\n      DisableHandler();\n      {\n        SpinLockHolder sl(&signal_lock_);\n        delete *it;\n        callbacks_.erase(it);\n      }\n      --callback_count_;\n      if (callback_count_ > 0) {\n        EnableHandler();\n      } else if (timer_sharing_ == TIMERS_SHARED) {\n        StopTimer();\n      }\n      return;\n    }\n  }\n  // Unknown token.\n  RAW_LOG(FATAL, \"Invalid token\");\n}\n\nvoid ProfileHandler::Reset() {\n  SpinLockHolder cl(&control_lock_);\n  DisableHandler();\n  {\n    SpinLockHolder sl(&signal_lock_);\n    CallbackIterator it = callbacks_.begin();\n    while (it != callbacks_.end()) {\n      CallbackIterator tmp = it;\n      ++it;\n      delete *tmp;\n      callbacks_.erase(tmp);\n    }\n  }\n  callback_count_ = 0;\n  if (timer_sharing_ == TIMERS_SHARED) {\n    StopTimer();\n  }\n  timer_sharing_ = TIMERS_UNTOUCHED;\n}\n\nvoid ProfileHandler::GetState(ProfileHandlerState* state) {\n  SpinLockHolder cl(&control_lock_);\n  DisableHandler();\n  {\n    SpinLockHolder sl(&signal_lock_);  // Protects interrupts_.\n    state->interrupts = interrupts_;\n  }\n  if (callback_count_ > 0) {\n    EnableHandler();\n  }\n  state->frequency = frequency_;\n  state->callback_count = callback_count_;\n}\n\nvoid ProfileHandler::StartTimer() {\n  struct itimerval timer;\n  timer.it_interval.tv_sec = 0;\n  timer.it_interval.tv_usec = 1000000 / frequency_;\n  timer.it_value = timer.it_interval;\n  setitimer(timer_type_, &timer, 0);\n}\n\nvoid ProfileHandler::StopTimer() {\n  struct itimerval timer;\n  memset(&timer, 0, sizeof timer);\n  setitimer(timer_type_, &timer, 0);\n}\n\nbool ProfileHandler::IsTimerRunning() {\n  struct itimerval current_timer;\n  RAW_CHECK(0 == getitimer(timer_type_, &current_timer), \"getitimer\");\n  return (current_timer.it_value.tv_sec != 0 ||\n          current_timer.it_value.tv_usec != 0);\n}\n\nvoid ProfileHandler::EnableHandler() {\n  struct sigaction sa;\n  sa.sa_sigaction = SignalHandler;\n  sa.sa_flags = SA_RESTART | SA_SIGINFO;\n  sigemptyset(&sa.sa_mask);\n  const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);\n  RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, \"sigprof (enable)\");\n}\n\nvoid ProfileHandler::DisableHandler() {\n  struct sigaction sa;\n  sa.sa_handler = SIG_IGN;\n  sa.sa_flags = SA_RESTART;\n  sigemptyset(&sa.sa_mask);\n  const int signal_number = (timer_type_ == ITIMER_PROF ? SIGPROF : SIGALRM);\n  RAW_CHECK(sigaction(signal_number, &sa, NULL) == 0, \"sigprof (disable)\");\n}\n\nvoid ProfileHandler::SignalHandler(int sig, siginfo_t* sinfo, void* ucontext) {\n  int saved_errno = errno;\n  RAW_CHECK(instance_ != NULL, \"ProfileHandler is not initialized\");\n  {\n    SpinLockHolder sl(&instance_->signal_lock_);\n    ++instance_->interrupts_;\n    for (CallbackIterator it = instance_->callbacks_.begin();\n         it != instance_->callbacks_.end();\n         ++it) {\n      (*it)->callback(sig, sinfo, ucontext, (*it)->callback_arg);\n    }\n  }\n  errno = saved_errno;\n}\n\n// The sole purpose of this class is to initialize the ProfileHandler singleton\n// when the global static objects are created. Note that the main thread will\n// be registered at this time.\nclass ProfileHandlerInitializer {\n public:\n  ProfileHandlerInitializer() {\n    ProfileHandler::Instance()->RegisterThread();\n  }\n\n private:\n  DISALLOW_COPY_AND_ASSIGN(ProfileHandlerInitializer);\n};\n// ProfileHandlerInitializer singleton\nstatic ProfileHandlerInitializer profile_handler_initializer;\n\nextern \"C\" void ProfileHandlerRegisterThread() {\n  ProfileHandler::Instance()->RegisterThread();\n}\n\nextern \"C\" ProfileHandlerToken* ProfileHandlerRegisterCallback(\n    ProfileHandlerCallback callback, void* callback_arg) {\n  return ProfileHandler::Instance()->RegisterCallback(callback, callback_arg);\n}\n\nextern \"C\" void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {\n  ProfileHandler::Instance()->UnregisterCallback(token);\n}\n\nextern \"C\" void ProfileHandlerReset() {\n  return ProfileHandler::Instance()->Reset();\n}\n\nextern \"C\" void ProfileHandlerGetState(ProfileHandlerState* state) {\n  ProfileHandler::Instance()->GetState(state);\n}\n\n#else  // OS_CYGWIN\n\n// ITIMER_PROF doesn't work under cygwin.  ITIMER_REAL is available, but doesn't\n// work as well for profiling, and also interferes with alarm().  Because of\n// these issues, unless a specific need is identified, profiler support is\n// disabled under Cygwin.\nextern \"C\" void ProfileHandlerRegisterThread() {\n}\n\nextern \"C\" ProfileHandlerToken* ProfileHandlerRegisterCallback(\n    ProfileHandlerCallback callback, void* callback_arg) {\n  return NULL;\n}\n\nextern \"C\" void ProfileHandlerUnregisterCallback(ProfileHandlerToken* token) {\n}\n\nextern \"C\" void ProfileHandlerReset() {\n}\n\nextern \"C\" void ProfileHandlerGetState(ProfileHandlerState* state) {\n}\n\n#endif  // OS_CYGWIN\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/profile-handler.h",
    "content": "/* Copyright (c) 2009, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Nabeel Mian\n *\n * This module manages the cpu profile timers and the associated interrupt\n * handler. When enabled, all registered threads in the program are profiled.\n * (Note: if using linux 2.4 or earlier, you must use the Thread class, in\n * google3/thread, to ensure all threads are profiled.)\n *\n * Any component interested in receiving a profile timer interrupt can do so by\n * registering a callback. All registered callbacks must be async-signal-safe.\n *\n * Note: This module requires the sole ownership of ITIMER_PROF timer and the\n * SIGPROF signal.\n */\n\n#ifndef BASE_PROFILE_HANDLER_H_\n#define BASE_PROFILE_HANDLER_H_\n\n#include \"config.h\"\n#include <signal.h>\n#ifdef COMPILER_MSVC\n#include \"conflict-signal.h\"\n#endif\n#include \"base/basictypes.h\"\n\n/* All this code should be usable from within C apps. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Forward declaration. */\nstruct ProfileHandlerToken;\n\n/*\n * Callback function to be used with ProfilefHandlerRegisterCallback. This\n * function will be called in the context of SIGPROF signal handler and must\n * be async-signal-safe. The first three arguments are the values provided by\n * the SIGPROF signal handler. We use void* to avoid using ucontext_t on\n * non-POSIX systems.\n *\n * Requirements:\n * - Callback must be async-signal-safe.\n * - None of the functions in ProfileHandler are async-signal-safe. Therefore,\n *   callback function *must* not call any of the ProfileHandler functions.\n * - Callback is not required to be re-entrant. At most one instance of\n *   callback can run at a time.\n *\n * Notes:\n * - The SIGPROF signal handler saves and restores errno, so the callback\n *   doesn't need to.\n * - Callback code *must* not acquire lock(s) to serialize access to data shared\n *   with the code outside the signal handler (callback must be\n *   async-signal-safe). If such a serialization is needed, follow the model\n *   used by profiler.cc:\n *\n *   When code other than the signal handler modifies the shared data it must:\n *   - Acquire lock.\n *   - Unregister the callback with the ProfileHandler.\n *   - Modify shared data.\n *   - Re-register the callback.\n *   - Release lock.\n *   and the callback code gets a lockless, read-write access to the data.\n */\ntypedef void (*ProfileHandlerCallback)(int sig, siginfo_t* sig_info,\n                                       void* ucontext, void* callback_arg);\n\n/*\n * Registers a new thread with profile handler and should be called only once\n * per thread. The main thread is registered at program startup. This routine\n * is called by the Thread module in google3/thread whenever a new thread is\n * created. This function is not async-signal-safe.\n */\nvoid ProfileHandlerRegisterThread();\n\n/*\n * Registers a callback routine. This callback function will be called in the\n * context of SIGPROF handler, so must be async-signal-safe. The returned token\n * is to be used when unregistering this callback via\n * ProfileHandlerUnregisterCallback. Registering the first callback enables\n * the SIGPROF signal handler. Caller must not free the returned token. This\n * function is not async-signal-safe.\n */\nProfileHandlerToken* ProfileHandlerRegisterCallback(\n    ProfileHandlerCallback callback, void* callback_arg);\n\n/*\n * Unregisters a previously registered callback. Expects the token returned\n * by the corresponding ProfileHandlerRegisterCallback and asserts that the\n * passed token is valid. Unregistering the last callback disables the SIGPROF\n * signal handler. It waits for the currently running callback to\n * complete before returning. This function is not async-signal-safe.\n */\nvoid ProfileHandlerUnregisterCallback(ProfileHandlerToken* token);\n\n/*\n * FOR TESTING ONLY\n * Unregisters all the callbacks, stops the timers (if shared) and disables the\n * SIGPROF handler. All the threads, including the main thread, need to be\n * re-registered after this call. This function is not async-signal-safe.\n */\nvoid ProfileHandlerReset();\n\n/*\n * Stores profile handler's current state. This function is not\n * async-signal-safe.\n */\nstruct ProfileHandlerState {\n  int32 frequency;  /* Profiling frequency */\n  int32 callback_count;  /* Number of callbacks registered */\n  int64 interrupts;  /* Number of interrupts received */\n};\nvoid ProfileHandlerGetState(struct ProfileHandlerState* state);\n\n#ifdef __cplusplus\n}  /* extern \"C\" */\n#endif\n\n#endif  /* BASE_PROFILE_HANDLER_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/profiledata.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// ---\n// Author: Sanjay Ghemawat\n//         Chris Demetriou (refactoring)\n//\n// Collect profiling data.\n\n#include <config.h>\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#include <sys/time.h>\n#include <string.h>\n#include <fcntl.h>\n\n#include \"profiledata.h\"\n\n#include \"base/logging.h\"\n#include \"base/sysinfo.h\"\n\n// All of these are initialized in profiledata.h.\nconst int ProfileData::kMaxStackDepth;\nconst int ProfileData::kAssociativity;\nconst int ProfileData::kBuckets;\nconst int ProfileData::kBufferLength;\n\nProfileData::Options::Options()\n    : frequency_(1) {\n}\n\n// This function is safe to call from asynchronous signals (but is not\n// re-entrant).  However, that's not part of its public interface.\nvoid ProfileData::Evict(const Entry& entry) {\n  const int d = entry.depth;\n  const int nslots = d + 2;     // Number of slots needed in eviction buffer\n  if (num_evicted_ + nslots > kBufferLength) {\n    FlushEvicted();\n    assert(num_evicted_ == 0);\n    assert(nslots <= kBufferLength);\n  }\n  evict_[num_evicted_++] = entry.count;\n  evict_[num_evicted_++] = d;\n  memcpy(&evict_[num_evicted_], entry.stack, d * sizeof(Slot));\n  num_evicted_ += d;\n}\n\nProfileData::ProfileData()\n    : hash_(0),\n      evict_(0),\n      num_evicted_(0),\n      out_(-1),\n      count_(0),\n      evictions_(0),\n      total_bytes_(0),\n      fname_(0),\n      start_time_(0) {\n}\n\nbool ProfileData::Start(const char* fname,\n                        const ProfileData::Options& options) {\n  if (enabled()) {\n    return false;\n  }\n\n  // Open output file and initialize various data structures\n  int fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n  if (fd < 0) {\n    // Can't open outfile for write\n    return false;\n  }\n\n  start_time_ = time(NULL);\n  fname_ = strdup(fname);\n\n  // Reset counters\n  num_evicted_ = 0;\n  count_       = 0;\n  evictions_   = 0;\n  total_bytes_ = 0;\n\n  hash_ = new Bucket[kBuckets];\n  evict_ = new Slot[kBufferLength];\n  memset(hash_, 0, sizeof(hash_[0]) * kBuckets);\n\n  // Record special entries\n  evict_[num_evicted_++] = 0;                     // count for header\n  evict_[num_evicted_++] = 3;                     // depth for header\n  evict_[num_evicted_++] = 0;                     // Version number\n  CHECK_NE(0, options.frequency());\n  int period = 1000000 / options.frequency();\n  evict_[num_evicted_++] = period;                // Period (microseconds)\n  evict_[num_evicted_++] = 0;                     // Padding\n\n  out_ = fd;\n\n  return true;\n}\n\nProfileData::~ProfileData() {\n  Stop();\n}\n\n// Dump /proc/maps data to fd.  Copied from heap-profile-table.cc.\n#define NO_INTR(fn)  do {} while ((fn) < 0 && errno == EINTR)\n\nstatic void FDWrite(int fd, const char* buf, size_t len) {\n  while (len > 0) {\n    ssize_t r;\n    NO_INTR(r = write(fd, buf, len));\n    RAW_CHECK(r >= 0, \"write failed\");\n    buf += r;\n    len -= r;\n  }\n}\n\nstatic void DumpProcSelfMaps(int fd) {\n  ProcMapsIterator::Buffer iterbuf;\n  ProcMapsIterator it(0, &iterbuf);   // 0 means \"current pid\"\n\n  uint64 start, end, offset;\n  int64 inode;\n  char *flags, *filename;\n  ProcMapsIterator::Buffer linebuf;\n  while (it.Next(&start, &end, &flags, &offset, &inode, &filename)) {\n    int written = it.FormatLine(linebuf.buf_, sizeof(linebuf.buf_),\n                                start, end, flags, offset, inode, filename,\n                                0);\n    FDWrite(fd, linebuf.buf_, written);\n  }\n}\n\nvoid ProfileData::Stop() {\n  if (!enabled()) {\n    return;\n  }\n\n  // Move data from hash table to eviction buffer\n  for (int b = 0; b < kBuckets; b++) {\n    Bucket* bucket = &hash_[b];\n    for (int a = 0; a < kAssociativity; a++) {\n      if (bucket->entry[a].count > 0) {\n        Evict(bucket->entry[a]);\n      }\n    }\n  }\n\n  if (num_evicted_ + 3 > kBufferLength) {\n    // Ensure there is enough room for end of data marker\n    FlushEvicted();\n  }\n\n  // Write end of data marker\n  evict_[num_evicted_++] = 0;         // count\n  evict_[num_evicted_++] = 1;         // depth\n  evict_[num_evicted_++] = 0;         // end of data marker\n  FlushEvicted();\n\n  // Dump \"/proc/self/maps\" so we get list of mapped shared libraries\n  DumpProcSelfMaps(out_);\n\n  Reset();\n  fprintf(stderr, \"PROFILE: interrupts/evictions/bytes = %d/%d/%\" PRIuS \"\\n\",\n          count_, evictions_, total_bytes_);\n}\n\nvoid ProfileData::Reset() {\n  if (!enabled()) {\n    return;\n  }\n\n  // Don't reset count_, evictions_, or total_bytes_ here.  They're used\n  // by Stop to print information about the profile after reset, and are\n  // cleared by Start when starting a new profile.\n  close(out_);\n  delete[] hash_;\n  hash_ = 0;\n  delete[] evict_;\n  evict_ = 0;\n  num_evicted_ = 0;\n  free(fname_);\n  fname_ = 0;\n  start_time_ = 0;\n\n  out_ = -1;\n}\n\n// This function is safe to call from asynchronous signals (but is not\n// re-entrant).  However, that's not part of its public interface.\nvoid ProfileData::GetCurrentState(State* state) const {\n  if (enabled()) {\n    state->enabled = true;\n    state->start_time = start_time_;\n    state->samples_gathered = count_;\n    int buf_size = sizeof(state->profile_name);\n    strncpy(state->profile_name, fname_, buf_size);\n    state->profile_name[buf_size-1] = '\\0';\n  } else {\n    state->enabled = false;\n    state->start_time = 0;\n    state->samples_gathered = 0;\n    state->profile_name[0] = '\\0';\n  }\n}\n\n// This function is safe to call from asynchronous signals (but is not\n// re-entrant).  However, that's not part of its public interface.\nvoid ProfileData::FlushTable() {\n  if (!enabled()) {\n    return;\n  }\n\n  // Move data from hash table to eviction buffer\n  for (int b = 0; b < kBuckets; b++) {\n    Bucket* bucket = &hash_[b];\n    for (int a = 0; a < kAssociativity; a++) {\n      if (bucket->entry[a].count > 0) {\n        Evict(bucket->entry[a]);\n        bucket->entry[a].depth = 0;\n        bucket->entry[a].count = 0;\n      }\n    }\n  }\n\n  // Write out all pending data\n  FlushEvicted();\n}\n\nvoid ProfileData::Add(int depth, const void* const* stack) {\n  if (!enabled()) {\n    return;\n  }\n\n  if (depth > kMaxStackDepth) depth = kMaxStackDepth;\n  RAW_CHECK(depth > 0, \"ProfileData::Add depth <= 0\");\n\n  // Make hash-value\n  Slot h = 0;\n  for (int i = 0; i < depth; i++) {\n    Slot slot = reinterpret_cast<Slot>(stack[i]);\n    h = (h << 8) | (h >> (8*(sizeof(h)-1)));\n    h += (slot * 31) + (slot * 7) + (slot * 3);\n  }\n\n  count_++;\n\n  // See if table already has an entry for this trace\n  bool done = false;\n  Bucket* bucket = &hash_[h % kBuckets];\n  for (int a = 0; a < kAssociativity; a++) {\n    Entry* e = &bucket->entry[a];\n    if (e->depth == depth) {\n      bool match = true;\n      for (int i = 0; i < depth; i++) {\n        if (e->stack[i] != reinterpret_cast<Slot>(stack[i])) {\n          match = false;\n          break;\n        }\n      }\n      if (match) {\n        e->count++;\n        done = true;\n        break;\n      }\n    }\n  }\n\n  if (!done) {\n    // Evict entry with smallest count\n    Entry* e = &bucket->entry[0];\n    for (int a = 1; a < kAssociativity; a++) {\n      if (bucket->entry[a].count < e->count) {\n        e = &bucket->entry[a];\n      }\n    }\n    if (e->count > 0) {\n      evictions_++;\n      Evict(*e);\n    }\n\n    // Use the newly evicted entry\n    e->depth = depth;\n    e->count = 1;\n    for (int i = 0; i < depth; i++) {\n      e->stack[i] = reinterpret_cast<Slot>(stack[i]);\n    }\n  }\n}\n\n// This function is safe to call from asynchronous signals (but is not\n// re-entrant).  However, that's not part of its public interface.\nvoid ProfileData::FlushEvicted() {\n  if (num_evicted_ > 0) {\n    const char* buf = reinterpret_cast<char*>(evict_);\n    size_t bytes = sizeof(evict_[0]) * num_evicted_;\n    total_bytes_ += bytes;\n    FDWrite(out_, buf, bytes);\n  }\n  num_evicted_ = 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/profiledata.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// ---\n// Author: Sanjay Ghemawat\n//         Chris Demetriou (refactoring)\n//\n// Collect profiling data.\n//\n// The profile data file format is documented in\n// doc/cpuprofile-fileformat.html\n\n\n#ifndef BASE_PROFILEDATA_H_\n#define BASE_PROFILEDATA_H_\n\n#include <config.h>\n#include <time.h>   // for time_t\n#include <stdint.h>\n#include \"base/basictypes.h\"\n\n// A class that accumulates profile samples and writes them to a file.\n//\n// Each sample contains a stack trace and a count.  Memory usage is\n// reduced by combining profile samples that have the same stack trace\n// by adding up the associated counts.\n//\n// Profile data is accumulated in a bounded amount of memory, and will\n// flushed to a file as necessary to stay within the memory limit.\n//\n// Use of this class assumes external synchronization.  The exact\n// requirements of that synchronization are that:\n//\n//  - 'Add' may be called from asynchronous signals, but is not\n//    re-entrant.\n//\n//  - None of 'Start', 'Stop', 'Reset', 'Flush', and 'Add' may be\n//    called at the same time.\n//\n//  - 'Start', 'Stop', or 'Reset' should not be called while 'Enabled'\n//     or 'GetCurrent' are running, and vice versa.\n//\n// A profiler which uses asyncronous signals to add samples will\n// typically use two locks to protect this data structure:\n//\n//  - A SpinLock which is held over all calls except for the 'Add'\n//    call made from the signal handler.\n//\n//  - A SpinLock which is held over calls to 'Start', 'Stop', 'Reset',\n//    'Flush', and 'Add'.  (This SpinLock should be acquired after\n//    the first SpinLock in all cases where both are needed.)\nclass ProfileData {\n public:\n  struct State {\n    bool     enabled;             // Is profiling currently enabled?\n    time_t   start_time;          // If enabled, when was profiling started?\n    char     profile_name[1024];  // Name of file being written, or '\\0'\n    int      samples_gathered;    // Number of samples gathered to far (or 0)\n  };\n\n  class Options {\n   public:\n    Options();\n\n    // Get and set the sample frequency.\n    int frequency() const {\n      return frequency_;\n    }\n    void set_frequency(int frequency) {\n      frequency_ = frequency;\n    }\n\n   private:\n    int      frequency_;                  // Sample frequency.\n  };\n\n  static const int kMaxStackDepth = 64;  // Max stack depth stored in profile\n\n  ProfileData();\n  ~ProfileData();\n\n  // If data collection is not already enabled start to collect data\n  // into fname.  Parameters related to this profiling run are specified\n  // by 'options'.\n  //\n  // Returns true if data collection could be started, otherwise (if an\n  // error occurred or if data collection was already enabled) returns\n  // false.\n  bool Start(const char *fname, const Options& options);\n\n  // If data collection is enabled, stop data collection and write the\n  // data to disk.\n  void Stop();\n\n  // Stop data collection without writing anything else to disk, and\n  // discard any collected data.\n  void Reset();\n\n  // If data collection is enabled, record a sample with 'depth'\n  // entries from 'stack'.  (depth must be > 0.)  At most\n  // kMaxStackDepth stack entries will be recorded, starting with\n  // stack[0].\n  //\n  // This function is safe to call from asynchronous signals (but is\n  // not re-entrant).\n  void Add(int depth, const void* const* stack);\n\n  // If data collection is enabled, write the data to disk (and leave\n  // the collector enabled).\n  void FlushTable();\n\n  // Is data collection currently enabled?\n  bool enabled() const { return out_ >= 0; }\n\n  // Get the current state of the data collector.\n  void GetCurrentState(State* state) const;\n\n private:\n  static const int kAssociativity = 4;          // For hashtable\n  static const int kBuckets = 1 << 10;          // For hashtable\n  static const int kBufferLength = 1 << 18;     // For eviction buffer\n\n  // Type of slots: each slot can be either a count, or a PC value\n  typedef uintptr_t Slot;\n\n  // Hash-table/eviction-buffer entry (a.k.a. a sample)\n  struct Entry {\n    Slot count;                  // Number of hits\n    Slot depth;                  // Stack depth\n    Slot stack[kMaxStackDepth];  // Stack contents\n  };\n\n  // Hash table bucket\n  struct Bucket {\n    Entry entry[kAssociativity];\n  };\n\n  Bucket*       hash_;          // hash table\n  Slot*         evict_;         // evicted entries\n  int           num_evicted_;   // how many evicted entries?\n  int           out_;           // fd for output file.\n  int           count_;         // How many samples recorded\n  int           evictions_;     // How many evictions\n  size_t        total_bytes_;   // How much output\n  char*         fname_;         // Profile file name\n  time_t        start_time_;    // Start time, or 0\n\n  // Move 'entry' to the eviction buffer.\n  void Evict(const Entry& entry);\n\n  // Write contents of eviction buffer to disk.\n  void FlushEvicted();\n\n  DISALLOW_COPY_AND_ASSIGN(ProfileData);\n};\n\n#endif  // BASE_PROFILEDATA_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/profiler.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//         Chris Demetriou (refactoring)\n//\n// Profile current program by sampling stack-trace every so often\n\n#include \"config.h\"\n#include \"getpc.h\"      // should be first to get the _GNU_SOURCE dfn\n#include <signal.h>\n#include <assert.h>\n#include <stdio.h>\n#include <errno.h>\n#include <string.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>  // for getpid()\n#endif\n#if defined(HAVE_SYS_UCONTEXT_H)\n#include <sys/ucontext.h>\n#elif defined(HAVE_UCONTEXT_H)\n#include <ucontext.h>\n#elif defined(HAVE_CYGWIN_SIGNAL_H)\n#include <cygwin/signal.h>\ntypedef ucontext ucontext_t;\n#else\ntypedef int ucontext_t;   // just to quiet the compiler, mostly\n#endif\n#include <sys/time.h>\n#include <string>\n#include <google/profiler.h>\n#include <google/stacktrace.h>\n#include \"base/commandlineflags.h\"\n#include \"base/logging.h\"\n#include \"base/googleinit.h\"\n#include \"base/spinlock.h\"\n#include \"base/sysinfo.h\"             /* for GetUniquePathFromEnv, etc */\n#include \"profiledata.h\"\n#include \"profile-handler.h\"\n#ifdef HAVE_CONFLICT_SIGNAL_H\n#include \"conflict-signal.h\"          /* used on msvc machines */\n#endif\n\nusing std::string;\n\n// Collects up all profile data.  This is a singleton, which is\n// initialized by a constructor at startup.\nclass CpuProfiler {\n public:\n  CpuProfiler();\n  ~CpuProfiler();\n\n  // Start profiler to write profile info into fname\n  bool Start(const char* fname, const ProfilerOptions* options);\n\n  // Stop profiling and write the data to disk.\n  void Stop();\n\n  // Write the data to disk (and continue profiling).\n  void FlushTable();\n\n  bool Enabled();\n\n  void GetCurrentState(ProfilerState* state);\n\n  static CpuProfiler instance_;\n\n private:\n  // This lock implements the locking requirements described in the ProfileData\n  // documentation, specifically:\n  //\n  // lock_ is held all over all collector_ method calls except for the 'Add'\n  // call made from the signal handler, to protect against concurrent use of\n  // collector_'s control routines. Code other than signal handler must\n  // unregister the signal handler before calling any collector_ method.\n  // 'Add' method in the collector is protected by a guarantee from\n  // ProfileHandle that only one instance of prof_handler can run at a time.\n  SpinLock      lock_;\n  ProfileData   collector_;\n\n  // Filter function and its argument, if any.  (NULL means include all\n  // samples).  Set at start, read-only while running.  Written while holding\n  // lock_, read and executed in the context of SIGPROF interrupt.\n  int           (*filter_)(void*);\n  void*         filter_arg_;\n\n  // Opaque token returned by the profile handler. To be used when calling\n  // ProfileHandlerUnregisterCallback.\n  ProfileHandlerToken* prof_handler_token_;\n\n  // Sets up a callback to receive SIGPROF interrupt.\n  void EnableHandler();\n\n  // Disables receiving SIGPROF interrupt.\n  void DisableHandler();\n\n  // Signal handler that records the interrupted pc in the profile data.\n  static void prof_handler(int sig, siginfo_t*, void* signal_ucontext,\n                           void* cpu_profiler);\n};\n\n// Profile data structure singleton: Constructor will check to see if\n// profiling should be enabled.  Destructor will write profile data\n// out to disk.\nCpuProfiler CpuProfiler::instance_;\n\n// Initialize profiling: activated if getenv(\"CPUPROFILE\") exists.\nCpuProfiler::CpuProfiler()\n    : prof_handler_token_(NULL) {\n  // TODO(cgd) Move this code *out* of the CpuProfile constructor into a\n  // separate object responsible for initialization. With ProfileHandler there\n  // is no need to limit the number of profilers.\n  char fname[PATH_MAX];\n  if (!GetUniquePathFromEnv(\"CPUPROFILE\", fname)) {\n    return;\n  }\n  // We don't enable profiling if setuid -- it's a security risk\n#ifdef HAVE_GETEUID\n  if (getuid() != geteuid())\n    return;\n#endif\n\n  if (!Start(fname, NULL)) {\n    RAW_LOG(FATAL, \"Can't turn on cpu profiling for '%s': %s\\n\",\n            fname, strerror(errno));\n  }\n}\n\nbool CpuProfiler::Start(const char* fname, const ProfilerOptions* options) {\n  SpinLockHolder cl(&lock_);\n\n  if (collector_.enabled()) {\n    return false;\n  }\n\n  ProfileHandlerState prof_handler_state;\n  ProfileHandlerGetState(&prof_handler_state);\n\n  ProfileData::Options collector_options;\n  collector_options.set_frequency(prof_handler_state.frequency);\n  if (!collector_.Start(fname, collector_options)) {\n    return false;\n  }\n\n  filter_ = NULL;\n  if (options != NULL && options->filter_in_thread != NULL) {\n    filter_ = options->filter_in_thread;\n    filter_arg_ = options->filter_in_thread_arg;\n  }\n\n  // Setup handler for SIGPROF interrupts\n  EnableHandler();\n\n  return true;\n}\n\nCpuProfiler::~CpuProfiler() {\n  Stop();\n}\n\n// Stop profiling and write out any collected profile data\nvoid CpuProfiler::Stop() {\n  SpinLockHolder cl(&lock_);\n\n  if (!collector_.enabled()) {\n    return;\n  }\n\n  // Unregister prof_handler to stop receiving SIGPROF interrupts before\n  // stopping the collector.\n  DisableHandler();\n\n  // DisableHandler waits for the currently running callback to complete and\n  // guarantees no future invocations. It is safe to stop the collector.\n  collector_.Stop();\n}\n\nvoid CpuProfiler::FlushTable() {\n  SpinLockHolder cl(&lock_);\n\n  if (!collector_.enabled()) {\n    return;\n  }\n\n  // Unregister prof_handler to stop receiving SIGPROF interrupts before\n  // flushing the profile data.\n  DisableHandler();\n\n  // DisableHandler waits for the currently running callback to complete and\n  // guarantees no future invocations. It is safe to flush the profile data.\n  collector_.FlushTable();\n\n  EnableHandler();\n}\n\nbool CpuProfiler::Enabled() {\n  SpinLockHolder cl(&lock_);\n  return collector_.enabled();\n}\n\nvoid CpuProfiler::GetCurrentState(ProfilerState* state) {\n  ProfileData::State collector_state;\n  {\n    SpinLockHolder cl(&lock_);\n    collector_.GetCurrentState(&collector_state);\n  }\n\n  state->enabled = collector_state.enabled;\n  state->start_time = static_cast<time_t>(collector_state.start_time);\n  state->samples_gathered = collector_state.samples_gathered;\n  int buf_size = sizeof(state->profile_name);\n  strncpy(state->profile_name, collector_state.profile_name, buf_size);\n  state->profile_name[buf_size-1] = '\\0';\n}\n\nvoid CpuProfiler::EnableHandler() {\n  RAW_CHECK(prof_handler_token_ == NULL, \"SIGPROF handler already registered\");\n  prof_handler_token_ = ProfileHandlerRegisterCallback(prof_handler, this);\n  RAW_CHECK(prof_handler_token_ != NULL, \"Failed to set up SIGPROF handler\");\n}\n\nvoid CpuProfiler::DisableHandler() {\n  RAW_CHECK(prof_handler_token_ != NULL, \"SIGPROF handler is not registered\");\n  ProfileHandlerUnregisterCallback(prof_handler_token_);\n  prof_handler_token_ = NULL;\n}\n\n// Signal handler that records the pc in the profile-data structure. We do no\n// synchronization here.  profile-handler.cc guarantees that at most one\n// instance of prof_handler() will run at a time. All other routines that\n// access the data touched by prof_handler() disable this signal handler before\n// accessing the data and therefore cannot execute concurrently with\n// prof_handler().\nvoid CpuProfiler::prof_handler(int sig, siginfo_t*, void* signal_ucontext,\n                               void* cpu_profiler) {\n  CpuProfiler* instance = static_cast<CpuProfiler*>(cpu_profiler);\n\n  if (instance->filter_ == NULL ||\n      (*instance->filter_)(instance->filter_arg_)) {\n    void* stack[ProfileData::kMaxStackDepth];\n\n    // The top-most active routine doesn't show up as a normal\n    // frame, but as the \"pc\" value in the signal handler context.\n    stack[0] = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));\n\n    // We skip the top two stack trace entries (this function and one\n    // signal handler frame) since they are artifacts of profiling and\n    // should not be measured.  Other profiling related frames may be\n    // removed by \"pprof\" at analysis time.  Instead of skipping the top\n    // frames, we could skip nothing, but that would increase the\n    // profile size unnecessarily.\n    int depth = GetStackTraceWithContext(stack + 1, arraysize(stack) - 1,\n                                         2, signal_ucontext);\n    depth++;  // To account for pc value in stack[0];\n\n    instance->collector_.Add(depth, stack);\n  }\n}\n\n#if !(defined(__CYGWIN__) || defined(__CYGWIN32__))\n\nextern \"C\" PERFTOOLS_DLL_DECL void ProfilerRegisterThread() {\n  ProfileHandlerRegisterThread();\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void ProfilerFlush() {\n  CpuProfiler::instance_.FlushTable();\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL int ProfilingIsEnabledForAllThreads() {\n  return CpuProfiler::instance_.Enabled();\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL int ProfilerStart(const char* fname) {\n  return CpuProfiler::instance_.Start(fname, NULL);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL int ProfilerStartWithOptions(\n    const char *fname, const ProfilerOptions *options) {\n  return CpuProfiler::instance_.Start(fname, options);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void ProfilerStop() {\n  CpuProfiler::instance_.Stop();\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void ProfilerGetCurrentState(\n    ProfilerState* state) {\n  CpuProfiler::instance_.GetCurrentState(state);\n}\n\n#else  // OS_CYGWIN\n\n// ITIMER_PROF doesn't work under cygwin.  ITIMER_REAL is available, but doesn't\n// work as well for profiling, and also interferes with alarm().  Because of\n// these issues, unless a specific need is identified, profiler support is\n// disabled under Cygwin.\nextern \"C\" void ProfilerRegisterThread() { }\nextern \"C\" void ProfilerFlush() { }\nextern \"C\" int ProfilingIsEnabledForAllThreads() { return 0; }\nextern \"C\" int ProfilerStart(const char* fname) { return 0; }\nextern \"C\" int ProfilerStartWithOptions(const char *fname,\n                                        const ProfilerOptions *options) {\n  return 0;\n}\nextern \"C\" void ProfilerStop() { }\nextern \"C\" void ProfilerGetCurrentState(ProfilerState* state) {\n  memset(state, 0, sizeof(*state));\n}\n\n#endif  // OS_CYGWIN\n\n// DEPRECATED routines\nextern \"C\" PERFTOOLS_DLL_DECL void ProfilerEnable() { }\nextern \"C\" PERFTOOLS_DLL_DECL void ProfilerDisable() { }\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/raw_printer.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: sanjay@google.com (Sanjay Ghemawat)\n\n#include <config.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include \"raw_printer.h\"\n#include \"base/logging.h\"\n\nnamespace base {\n\nRawPrinter::RawPrinter(char* buf, int length)\n    : base_(buf),\n      ptr_(buf),\n      limit_(buf + length - 1) {\n  RAW_DCHECK(length > 0, \"\");\n  *ptr_ = '\\0';\n  *limit_ = '\\0';\n}\n\nvoid RawPrinter::Printf(const char* format, ...) {\n  if (limit_ > ptr_) {\n    va_list ap;\n    va_start(ap, format);\n    int avail = limit_ - ptr_;\n    // We pass avail+1 to vsnprintf() since that routine needs room\n    // to store the trailing \\0.\n    const int r = vsnprintf(ptr_, avail+1, format, ap);\n    va_end(ap);\n    if (r < 0) {\n      // Perhaps an old glibc that returns -1 on truncation?\n      ptr_ = limit_;\n    } else if (r > avail) {\n      // Truncation\n      ptr_ = limit_;\n    } else {\n      ptr_ += r;\n    }\n  }\n}\n\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/raw_printer.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// A printf() wrapper that writes into a fixed length buffer.\n// Useful in low-level code that does not want to use allocating\n// routines like StringPrintf().\n//\n// The implementation currently uses vsnprintf().  This seems to\n// be fine for use in many low-level contexts, but we may need to\n// rethink this decision if we hit a problem with it calling\n// down into malloc() etc.\n\n#ifndef BASE_RAW_PRINTER_H_\n#define BASE_RAW_PRINTER_H_\n\n#include <config.h>\n#include \"base/basictypes.h\"\n\nnamespace base {\n\nclass RawPrinter {\n public:\n  // REQUIRES: \"length > 0\"\n  // Will printf any data added to this into \"buf[0,length-1]\" and\n  // will arrange to always keep buf[] null-terminated.\n  RawPrinter(char* buf, int length);\n\n  // Return the number of bytes that have been appended to the string\n  // so far.  Does not count any bytes that were dropped due to overflow.\n  int length() const { return (ptr_ - base_); }\n\n  // Return the number of bytes that can be added to this.\n  int space_left() const { return (limit_ - ptr_); }\n\n  // Format the supplied arguments according to the \"format\" string\n  // and append to this.  Will silently truncate the output if it does\n  // not fit.\n  void Printf(const char* format, ...)\n#ifdef HAVE___ATTRIBUTE__\n  __attribute__ ((__format__ (__printf__, 2, 3)))\n#endif\n;\n\n private:\n  // We can write into [ptr_ .. limit_-1].\n  // *limit_ is also writable, but reserved for a terminating \\0\n  // in case we overflow.\n  //\n  // Invariants: *ptr_ == \\0\n  // Invariants: *limit_ == \\0\n  char* base_;          // Initial pointer\n  char* ptr_;           // Where should we write next\n  char* limit_;         // One past last non-\\0 char we can write\n\n  DISALLOW_COPY_AND_ASSIGN(RawPrinter);\n};\n\n}\n\n#endif  // BASE_RAW_PRINTER_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/sampler.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// All Rights Reserved.\n//\n// Author: Daniel Ford\n\n#include \"sampler.h\"\n\n#include <algorithm>  // For min()\n#include <cmath>\n\nusing std::min;\n\n// The approximate gap in bytes between sampling actions.\n// I.e., we take one sample approximately once every\n// tcmalloc_sample_parameter bytes of allocation\n// i.e. about once every 512KB if value is 1<<19.\n#ifdef NO_TCMALLOC_SAMPLES\nDEFINE_int64(tcmalloc_sample_parameter, 0,\n             \"Unused: code is compiled with NO_TCMALLOC_SAMPLES\");\n#else\nDEFINE_int64(tcmalloc_sample_parameter,\n             EnvToInt64(\"TCMALLOC_SAMPLE_PARAMETER\", 0),\n             \"The approximate gap in bytes between sampling actions. \"\n             \"This must be between 1 and 2^58.\");\n#endif\n\nnamespace tcmalloc {\n\n// Statics for Sampler\ndouble Sampler::log_table_[1<<kFastlogNumBits];\n\n// Populate the lookup table for FastLog2.\n// This approximates the log2 curve with a step function.\n// Steps have height equal to log2 of the mid-point of the step.\nvoid Sampler::PopulateFastLog2Table() {\n  for (int i = 0; i < (1<<kFastlogNumBits); i++) {\n    log_table_[i] = (log(1.0 + static_cast<double>(i+0.5)/(1<<kFastlogNumBits))\n                     / log(2.0));\n  }\n}\n\nint Sampler::GetSamplePeriod() {\n  return FLAGS_tcmalloc_sample_parameter;\n}\n\n// Run this before using your sampler\nvoid Sampler::Init(uint32_t seed) {\n  // Initialize PRNG\n  if (seed != 0) {\n    rnd_ = seed;\n  } else {\n    rnd_ = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this));\n    if (rnd_ == 0) {\n      rnd_ = 1;\n    }\n  }\n  // Step it forward 20 times for good measure\n  for (int i = 0; i < 20; i++) {\n    rnd_ = NextRandom(rnd_);\n  }\n  // Initialize counter\n  bytes_until_sample_ = PickNextSamplingPoint();\n}\n\n// Initialize the Statics for the Sampler class\nvoid Sampler::InitStatics() {\n  PopulateFastLog2Table();\n}\n\n// Generates a geometric variable with the specified mean (512K by default).\n// This is done by generating a random number between 0 and 1 and applying\n// the inverse cumulative distribution function for an exponential.\n// Specifically: Let m be the inverse of the sample period, then\n// the probability distribution function is m*exp(-mx) so the CDF is\n// p = 1 - exp(-mx), so\n// q = 1 - p = exp(-mx)\n// log_e(q) = -mx\n// -log_e(q)/m = x\n// log_2(q) * (-log_e(2) * 1/m) = x\n// In the code, q is actually in the range 1 to 2**26, hence the -26 below\nsize_t Sampler::PickNextSamplingPoint() {\n  rnd_ = NextRandom(rnd_);\n  // Take the top 26 bits as the random number\n  // (This plus the 1<<58 sampling bound give a max possible step of\n  // 5194297183973780480 bytes.)\n  const uint64_t prng_mod_power = 48;  // Number of bits in prng\n  // The uint32_t cast is to prevent a (hard-to-reproduce) NAN\n  // under piii debug for some binaries.\n  double q = static_cast<uint32_t>(rnd_ >> (prng_mod_power - 26)) + 1.0;\n  // Put the computed p-value through the CDF of a geometric.\n  // For faster performance (save ~1/20th exec time), replace\n  // min(0.0, FastLog2(q) - 26)  by  (Fastlog2(q) - 26.000705)\n  // The value 26.000705 is used rather than 26 to compensate\n  // for inaccuracies in FastLog2 which otherwise result in a\n  // negative answer.\n  return static_cast<size_t>(min(0.0, (FastLog2(q) - 26)) * (-log(2.0)\n                             * FLAGS_tcmalloc_sample_parameter) + 1);\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/sampler.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// All Rights Reserved.\n//\n// Author: Daniel Ford\n\n#ifndef TCMALLOC_SAMPLER_H_\n#define TCMALLOC_SAMPLER_H_\n\n#include \"config.h\"\n#include \"common.h\"\n#include \"static_vars.h\"\n\nnamespace tcmalloc {\n\n//-------------------------------------------------------------------\n// Sampler to decide when to create a sample trace for an allocation\n// Not thread safe: Each thread should have it's own sampler object.\n// Caller must use external synchronization if used\n// from multiple threads.\n//\n// With 512K average sample step (the default):\n//  the probability of sampling a 4K allocation is about 0.00778\n//  the probability of sampling a 1MB allocation is about 0.865\n//  the probability of sampling a 1GB allocation is about 1.00000\n// In general, the probablity of sampling is an allocation of size X\n// given a flag value of Y (default 1M) is:\n//  1 - e^(-X/Y)\n//\n// With 128K average sample step:\n//  the probability of sampling a 1MB allocation is about 0.99966\n//  the probability of sampling a 1GB allocation is about 1.0\n//  (about 1 - 2**(-26))\n// With 1M average sample step:\n//  the probability of sampling a 4K allocation is about 0.00390\n//  the probability of sampling a 1MB allocation is about 0.632\n//  the probability of sampling a 1GB allocation is about 1.0\n//\n// The sampler works by representing memory as a long stream from\n// which allocations are taken. Some of the bytes in this stream are\n// marked and if an allocation includes a marked byte then it is\n// sampled. Bytes are marked according to a Poisson point process\n// with each byte being marked independently with probability\n// p = 1/tcmalloc_sample_parameter.  This makes the probability\n// of sampling an allocation of X bytes equal to the CDF of\n// a geometric with mean tcmalloc_sample_parameter. (ie. the\n// probability that at least one byte in the range is marked). This\n// is accurately given by the CDF of the corresponding exponential\n// distribution : 1 - e^(X/tcmalloc_sample_parameter_)\n// Independence of the byte marking ensures independence of\n// the sampling of each allocation.\n//\n// This scheme is implemented by noting that, starting from any\n// fixed place, the number of bytes until the next marked byte\n// is geometrically distributed. This number is recorded as\n// bytes_until_sample_.  Every allocation subtracts from this\n// number until it is less than 0. When this happens the current\n// allocation is sampled.\n//\n// When an allocation occurs, bytes_until_sample_ is reset to\n// a new independtly sampled geometric number of bytes. The\n// memoryless property of the point process means that this may\n// be taken as the number of bytes after the end of the current\n// allocation until the next marked byte. This ensures that\n// very large allocations which would intersect many marked bytes\n// only result in a single call to PickNextSamplingPoint.\n//-------------------------------------------------------------------\n\nclass PERFTOOLS_DLL_DECL Sampler {\n public:\n  // Initialize this sampler.\n  // Passing a seed of 0 gives a non-deterministic\n  // seed value given by casting the object (\"this\")\n  void Init(uint32_t seed);\n  void Cleanup();\n\n  // Record allocation of \"k\" bytes.  Return true iff allocation\n  // should be sampled\n  bool SampleAllocation(size_t k);\n\n  // Generate a geometric with mean 512K (or FLAG_tcmalloc_sample_parameter)\n  size_t PickNextSamplingPoint();\n\n  // Initialize the statics for the Sampler class\n  static void InitStatics();\n\n  // Returns the current sample period\n  int GetSamplePeriod();\n\n  // The following are public for the purposes of testing\n  static uint64_t NextRandom(uint64_t rnd_);  // Returns the next prng value\n  static double FastLog2(const double & d);  // Computes Log2(x) quickly\n  static void PopulateFastLog2Table();  // Populate the lookup table\n\n private:\n  size_t        bytes_until_sample_;    // Bytes until we sample next\n  uint64_t      rnd_;                   // Cheap random number generator\n\n  // Statics for the fast log\n  // Note that this code may not depend on anything in //util\n  // hence the duplication of functionality here\n  static const int kFastlogNumBits = 10;\n  static const int kFastlogMask = (1 << kFastlogNumBits) - 1;\n  static double log_table_[1<<kFastlogNumBits];  // Constant\n};\n\ninline bool Sampler::SampleAllocation(size_t k) {\n  if (bytes_until_sample_ < k) {\n    bytes_until_sample_ = PickNextSamplingPoint();\n    return true;\n  } else {\n    bytes_until_sample_ -= k;\n    return false;\n  }\n}\n\n// Inline functions which are public for testing purposes\n\n// Returns the next prng value.\n// pRNG is: aX+b mod c with a = 0x5DEECE66D, b =  0xB, c = 1<<48\n// This is the lrand64 generator.\ninline uint64_t Sampler::NextRandom(uint64_t rnd) {\n  const uint64_t prng_mult = 0x5DEECE66DLL;\n  const uint64_t prng_add = 0xB;\n  const uint64_t prng_mod_power = 48;\n  const uint64_t prng_mod_mask =\n                ~((~static_cast<uint64_t>(0)) << prng_mod_power);\n  return (prng_mult * rnd + prng_add) & prng_mod_mask;\n}\n\n// Adapted from //util/math/fastmath.[h|cc] by Noam Shazeer\n// This mimics the VeryFastLog2 code in those files\ninline double Sampler::FastLog2(const double & d) {\n  ASSERT(d>0);\n  COMPILE_ASSERT(sizeof(d) == sizeof(uint64_t), DoubleMustBe64Bits);\n  uint64_t x;\n  memcpy(&x, &d, sizeof(x));   // we depend on the compiler inlining this\n  const uint32_t x_high = x >> 32;\n  const uint32_t y = x_high >> (20 - kFastlogNumBits) & kFastlogMask;\n  const int32_t exponent = ((x_high >> 20) & 0x7FF) - 1023;\n  return exponent + log_table_[y];\n}\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_SAMPLER_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/solaris/libstdc++.la",
    "content": "# libstdc++.la - a libtool library file\n# Generated by ltmain.sh - GNU libtool 1.4a-GCC3.0 (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes)\n#\n# Please DO NOT delete this file!\n# It is necessary for linking the library.\n\n# ---\n# NOTE: This file lives in /usr/sfw/lib on Solaris 10.  Unfortunately,\n# due to an apparent bug in the Solaris 10 6/06 release,\n# /usr/sfw/lib/libstdc++.la is empty.  Below is the correct content,\n# according to\n#    http://forum.java.sun.com/thread.jspa?threadID=5073150\n# By passing LDFLAGS='-Lsrc/solaris' to configure, make will pick up\n# this copy of the file rather than the empty copy in /usr/sfw/lib.\n#\n# Also see\n#   http://www.technicalarticles.org/index.php/Compiling_MySQL_5.0_on_Solaris_10\n#\n# Note: this is for 32-bit systems.  If you have a 64-bit system,\n# uncomment the appropriate dependency_libs line below.\n# ----\n\n# The name that we can dlopen(3).\ndlname='libstdc++.so.6'\n\n# Names of this library.\nlibrary_names='libstdc++.so.6.0.3 libstdc++.so.6 libstdc++.so'\n\n# The name of the static archive.\nold_library='libstdc++.a'\n\n# Libraries that this one depends upon.\n# 32-bit version:\ndependency_libs='-lc -lm -L/usr/sfw/lib -lgcc_s'\n# 64-bit version:\n#dependency_libs='-L/lib/64 -lc -lm -L/usr/sfw/lib/64 -lgcc_s'\n\n# Version information for libstdc++.\ncurrent=6\nage=0\nrevision=3\n\n# Is this an already installed library?\ninstalled=yes\n\n# Files to dlopen/dlpreopen\ndlopen=''\ndlpreopen=''\n\n# Directory that this library needs to be installed in:\nlibdir='/usr/sfw/lib'\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/span.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#include <config.h>\n#include \"span.h\"\n\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>\n#endif\n\n#include \"static_vars.h\"\n\nnamespace tcmalloc {\n\n#ifdef SPAN_HISTORY\nvoid Event(Span* span, char op, int v = 0) {\n  span->history[span->nexthistory] = op;\n  span->value[span->nexthistory] = v;\n  span->nexthistory++;\n  if (span->nexthistory == sizeof(span->history)) span->nexthistory = 0;\n}\n#endif\n\nSpan* NewSpan(PageID p, Length len) {\n  Span* result = Static::span_allocator()->New();\n  memset(result, 0, sizeof(*result));\n  result->start = p;\n  result->length = len;\n#ifdef SPAN_HISTORY\n  result->nexthistory = 0;\n#endif\n  return result;\n}\n\nvoid DeleteSpan(Span* span) {\n#ifndef NDEBUG\n  // In debug mode, trash the contents of deleted Spans\n  memset(span, 0x3f, sizeof(*span));\n#endif\n  Static::span_allocator()->Delete(span);\n}\n\nvoid DLL_Init(Span* list) {\n  list->next = list;\n  list->prev = list;\n}\n\nvoid DLL_Remove(Span* span) {\n  span->prev->next = span->next;\n  span->next->prev = span->prev;\n  span->prev = NULL;\n  span->next = NULL;\n}\n\nint DLL_Length(const Span* list) {\n  int result = 0;\n  for (Span* s = list->next; s != list; s = s->next) {\n    result++;\n  }\n  return result;\n}\n\n#if 0  // This isn't used.  If that changes, rewrite to use TCMalloc_Printer.\nvoid DLL_Print(const char* label, const Span* list) {\n  MESSAGE(\"%-10s %p:\", label, list);\n  for (const Span* s = list->next; s != list; s = s->next) {\n    MESSAGE(\" <%p,%\"PRIuPTR\",%\"PRIuPTR\">\", s, s->start, s->length);\n  }\n  MESSAGE(\"%s\\n\", \"\");  // %s is to get around a compiler error.\n}\n#endif\n\nvoid DLL_Prepend(Span* list, Span* span) {\n  ASSERT(span->next == NULL);\n  ASSERT(span->prev == NULL);\n  span->next = list->next;\n  span->prev = list;\n  list->next->prev = span;\n  list->next = span;\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/span.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// A Span is a contiguous run of pages.\n\n#ifndef TCMALLOC_SPAN_H_\n#define TCMALLOC_SPAN_H_\n\n#include <config.h>\n#include \"common.h\"\n\nnamespace tcmalloc {\n\n// Information kept for a span (a contiguous run of pages).\nstruct Span {\n  PageID        start;          // Starting page number\n  Length        length;         // Number of pages in span\n  Span*         next;           // Used when in link list\n  Span*         prev;           // Used when in link list\n  void*         objects;        // Linked list of free objects\n  unsigned int  refcount : 16;  // Number of non-free objects\n  unsigned int  sizeclass : 8;  // Size-class for small objects (or 0)\n  unsigned int  location : 2;   // Is the span on a freelist, and if so, which?\n  unsigned int  sample : 1;     // Sampled object?\n\n#undef SPAN_HISTORY\n#ifdef SPAN_HISTORY\n  // For debugging, we can keep a log events per span\n  int nexthistory;\n  char history[64];\n  int value[64];\n#endif\n\n  // What freelist the span is on: IN_USE if on none, or normal or returned\n  enum { IN_USE, ON_NORMAL_FREELIST, ON_RETURNED_FREELIST };\n};\n\n#ifdef SPAN_HISTORY\nvoid Event(Span* span, char op, int v = 0);\n#else\n#define Event(s,o,v) ((void) 0)\n#endif\n\n// Allocator/deallocator for spans\nSpan* NewSpan(PageID p, Length len);\nvoid DeleteSpan(Span* span);\n\n// -------------------------------------------------------------------------\n// Doubly linked list of spans.\n// -------------------------------------------------------------------------\n\n// Initialize *list to an empty list.\nvoid DLL_Init(Span* list);\n\n// Remove 'span' from the linked list in which it resides, updating the\n// pointers of adjacent Spans and setting span's next and prev to NULL.\nvoid DLL_Remove(Span* span);\n\n// Return true iff \"list\" is empty.\ninline bool DLL_IsEmpty(const Span* list) {\n  return list->next == list;\n}\n\n// Add span to the front of list.\nvoid DLL_Prepend(Span* list, Span* span);\n\n// Return the length of the linked list. O(n)\nint DLL_Length(const Span* list);\n\n// Print the contents of the list to stderr.\n#if 0  // This isn't used.\nvoid DLL_Print(const char* label, const Span* list);\n#endif\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_SPAN_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stack_trace_table.cc",
    "content": "// Copyright (c) 2009, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Andrew Fikes\n\n#include <config.h>\n#include \"base/spinlock.h\"\n#include \"common.h\"\n#include \"static_vars.h\"\n#include \"stack_trace_table.h\"\n\nnamespace tcmalloc {\n\nbool StackTraceTable::Bucket::KeyEqual(uintptr_t h,\n                                       const StackTrace& t) const {\n  const bool eq = (this->hash == h && this->trace.depth == t.depth);\n  for (int i = 0; eq && i < t.depth; ++i) {\n    if (this->trace.stack[i] != t.stack[i]) {\n      return false;\n    }\n  }\n  return eq;\n}\n\nStackTraceTable::StackTraceTable()\n    : error_(false),\n      depth_total_(0),\n      bucket_total_(0),\n      table_(new Bucket*[kHashTableSize]()) {\n  memset(table_, 0, kHashTableSize * sizeof(Bucket*));\n}\n\nStackTraceTable::~StackTraceTable() {\n  delete[] table_;\n}\n\nvoid StackTraceTable::AddTrace(const StackTrace& t) {\n  if (error_) {\n    return;\n  }\n\n  // Hash function borrowed from base/heap-profile-table.cc\n  uintptr_t h = 0;\n  for (int i = 0; i < t.depth; ++i) {\n    h += reinterpret_cast<uintptr_t>(t.stack[i]);\n    h += h << 10;\n    h ^= h >> 6;\n  }\n  h += h << 3;\n  h ^= h >> 11;\n\n  const int idx = h % kHashTableSize;\n\n  Bucket* b = table_[idx];\n  while (b != NULL && !b->KeyEqual(h, t)) {\n    b = b->next;\n  }\n  if (b != NULL) {\n    b->count++;\n    b->trace.size += t.size;  // keep cumulative size\n  } else {\n    depth_total_ += t.depth;\n    bucket_total_++;\n    b = Static::bucket_allocator()->New();\n    if (b == NULL) {\n      MESSAGE(\"tcmalloc: could not allocate bucket\", sizeof(*b));\n      error_ = true;\n    } else {\n      b->hash = h;\n      b->trace = t;\n      b->count = 1;\n      b->next = table_[idx];\n      table_[idx] = b;\n    }\n  }\n}\n\nvoid** StackTraceTable::ReadStackTracesAndClear() {\n  if (error_) {\n    return NULL;\n  }\n\n  // Allocate output array\n  const int out_len = bucket_total_ * 3 + depth_total_ + 1;\n  void** out = new void*[out_len];\n  if (out == NULL) {\n    MESSAGE(\"tcmalloc: allocation failed for stack traces\\n\",\n            out_len * sizeof(*out));\n    return NULL;\n  }\n\n  // Fill output array\n  int idx = 0;\n  for (int i = 0; i < kHashTableSize; ++i) {\n    Bucket* b = table_[i];\n    while (b != NULL) {\n      out[idx++] = reinterpret_cast<void*>(static_cast<uintptr_t>(b->count));\n      out[idx++] = reinterpret_cast<void*>(b->trace.size);  // cumulative size\n      out[idx++] = reinterpret_cast<void*>(b->trace.depth);\n      for (int d = 0; d < b->trace.depth; ++d) {\n        out[idx++] = b->trace.stack[d];\n      }\n      b = b->next;\n    }\n  }\n  out[idx++] = static_cast<uintptr_t>(0);\n  ASSERT(idx == out_len);\n\n  // Clear state\n  error_ = false;\n  depth_total_ = 0;\n  bucket_total_ = 0;\n  SpinLockHolder h(Static::pageheap_lock());\n  for (int i = 0; i < kHashTableSize; ++i) {\n    Bucket* b = table_[i];\n    while (b != NULL) {\n      Bucket* next = b->next;\n      Static::bucket_allocator()->Delete(b);\n      b = next;\n    }\n    table_[i] = NULL;\n  }\n\n  return out;\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stack_trace_table.h",
    "content": "// Copyright (c) 2009, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Andrew Fikes\n//\n// Utility class for coalescing sampled stack traces.  Not thread-safe.\n\n#ifndef TCMALLOC_STACK_TRACE_TABLE_H_\n#define TCMALLOC_STACK_TRACE_TABLE_H_\n\n#include <config.h>\n#include \"common.h\"\n\nnamespace tcmalloc {\n\nclass PERFTOOLS_DLL_DECL StackTraceTable {\n public:\n  // REQUIRES: L < pageheap_lock\n  StackTraceTable();\n  ~StackTraceTable();\n\n  // Adds stack trace \"t\" to table.\n  //\n  // REQUIRES: L >= pageheap_lock\n  void AddTrace(const StackTrace& t);\n\n  // Returns stack traces formatted per MallocExtension guidelines.\n  // May return NULL on error.  Clears state before returning.\n  //\n  // REQUIRES: L < pageheap_lock\n  void** ReadStackTracesAndClear();\n\n  // Exposed for PageHeapAllocator\n  struct Bucket {\n    // Key\n    uintptr_t hash;\n    StackTrace trace;\n\n    // Payload\n    int count;\n    Bucket* next;\n\n    bool KeyEqual(uintptr_t h, const StackTrace& t) const;\n  };\n\n  // For testing\n  int depth_total() const { return depth_total_; }\n  int bucket_total() const { return bucket_total_; }\n\n private:\n  static const int kHashTableSize = 1 << 14; // => table_ is 128k\n\n  bool error_;\n  int depth_total_;\n  int bucket_total_;\n  Bucket** table_;\n};\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_STACK_TRACE_TABLE_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Produce stack trace.\n//\n// There are three different ways we can try to get the stack trace:\n//\n// 1) Our hand-coded stack-unwinder.  This depends on a certain stack\n//    layout, which is used by gcc (and those systems using a\n//    gcc-compatible ABI) on x86 systems, at least since gcc 2.95.\n//    It uses the frame pointer to do its work.\n//\n// 2) The libunwind library.  This is still in development, and as a\n//    separate library adds a new dependency, abut doesn't need a frame\n//    pointer.  It also doesn't call malloc.\n//\n// 3) The gdb unwinder -- also the one used by the c++ exception code.\n//    It's obviously well-tested, but has a fatal flaw: it can call\n//    malloc() from the unwinder.  This is a problem because we're\n//    trying to use the unwinder to instrument malloc().\n//\n// Note: if you add a new implementation here, make sure it works\n// correctly when GetStackTrace() is called with max_depth == 0.\n// Some code may do that.\n\n#include <config.h>\n#include <google/stacktrace.h>\n#include \"stacktrace_config.h\"\n\n#if defined(STACKTRACE_INL_HEADER)\n\n#define IS_STACK_FRAMES 0\n#define IS_WITH_CONTEXT 0\n#define GET_STACK_TRACE_OR_FRAMES \\\n   GetStackTrace(void **result, int max_depth, int skip_count)\n#include STACKTRACE_INL_HEADER\n#undef IS_STACK_FRAMES\n#undef IS_WITH_CONTEXT\n#undef GET_STACK_TRACE_OR_FRAMES\n\n#define IS_STACK_FRAMES 1\n#define IS_WITH_CONTEXT 0\n#define GET_STACK_TRACE_OR_FRAMES \\\n  GetStackFrames(void **result, int *sizes, int max_depth, int skip_count)\n#include STACKTRACE_INL_HEADER\n#undef IS_STACK_FRAMES\n#undef IS_WITH_CONTEXT\n#undef GET_STACK_TRACE_OR_FRAMES\n\n#define IS_STACK_FRAMES 0\n#define IS_WITH_CONTEXT 1\n#define GET_STACK_TRACE_OR_FRAMES \\\n  GetStackTraceWithContext(void **result, int max_depth, \\\n                           int skip_count, const void *ucp)\n#include STACKTRACE_INL_HEADER\n#undef IS_STACK_FRAMES\n#undef IS_WITH_CONTEXT\n#undef GET_STACK_TRACE_OR_FRAMES\n\n#define IS_STACK_FRAMES 1\n#define IS_WITH_CONTEXT 1\n#define GET_STACK_TRACE_OR_FRAMES \\\n  GetStackFramesWithContext(void **result, int *sizes, int max_depth, \\\n                            int skip_count, const void *ucp)\n#include STACKTRACE_INL_HEADER\n#undef IS_STACK_FRAMES\n#undef IS_WITH_CONTEXT\n#undef GET_STACK_TRACE_OR_FRAMES\n\n#elif 0\n// This is for the benefit of code analysis tools that may have\n// trouble with the computed #include above.\n# include \"base/stacktrace_x86-inl.h\"\n# include \"base/stacktrace_libunwind-inl.h\"\n# include \"base/stacktrace_generic-inl.h\"\n# include \"base/stacktrace_powerpc-inl.h\"\n# include \"base/stacktrace_win32-inl.h\"\n#else\n# error Cannot calculate stack trace: will need to write for your environment\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_config.h",
    "content": "// Copyright (c) 2009, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Paul Pluzhnikov\n//\n// Figure out which unwinder to use on a given platform.\n//\n// Defines STACKTRACE_INL_HEADER to the *-inl.h containing\n// actual unwinder implementation.\n//\n// Defines STACKTRACE_SKIP_CONTEXT_ROUTINES if a separate\n// GetStack{Trace,Frames}WithContext should not be provided.\n//\n// This header is \"private\" to stacktrace.cc and\n// stacktrace_with_context.cc.\n//\n// DO NOT include it into any other files.\n\n#ifndef BASE_STACKTRACE_CONFIG_H_\n#define BASE_STACKTRACE_CONFIG_H_\n\n// First, the i386 and x86_64 case.\n#if (defined(__i386__) || defined(__x86_64__)) && __GNUC__ >= 2\n# if !defined(NO_FRAME_POINTER)\n#   define STACKTRACE_INL_HEADER \"stacktrace_x86-inl.h\"\n#   define STACKTRACE_SKIP_CONTEXT_ROUTINES 1\n# elif defined(HAVE_LIBUNWIND_H)  // a proxy for having libunwind installed\n#   define STACKTRACE_INL_HEADER \"stacktrace_libunwind-inl.h\"\n#   define STACKTRACE_USES_LIBUNWIND 1\n# elif defined(__linux)\n#   error Cannnot calculate stack trace: need either libunwind or frame-pointers (see INSTALL file)\n# else\n#   error Cannnot calculate stack trace: need libunwind (see INSTALL file)\n# endif\n\n// The PowerPC case\n#elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2\n# if !defined(NO_FRAME_POINTER)\n#   define STACKTRACE_INL_HEADER \"stacktrace_powerpc-inl.h\"\n# else\n#   define STACKTRACE_INL_HEADER \"stacktrace_generic-inl.h\"\n# endif\n\n// The Windows case -- probably cygwin and mingw will use one of the\n// x86-includes above, but if not, we can fall back to windows intrinsics.\n#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)\n# define STACKTRACE_INL_HEADER \"stacktrace_win32-inl.h\"\n\n#endif  // all the cases\n#endif  // BASE_STACKTRACE_CONFIG_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_generic-inl.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Portable implementation - just use glibc\n//\n// Note:  The glibc implementation may cause a call to malloc.\n// This can cause a deadlock in HeapProfiler.\n\n#ifndef BASE_STACKTRACE_GENERIC_INL_H_\n#define BASE_STACKTRACE_GENERIC_INL_H_\n// Note: this file is included into stacktrace.cc more than once.\n// Anything that should only be defined once should be here:\n\n#include <execinfo.h>\n#include <string.h>\n#include \"google/stacktrace.h\"\n#endif  // BASE_STACKTRACE_GENERIC_INL_H_\n\n// Note: this part of the file is included several times.\n// Do not put globals below.\n\n// The following 4 functions are generated from the code below:\n//   GetStack{Trace,Frames}()\n//   GetStack{Trace,Frames}WithContext()\n//\n// These functions take the following args:\n//   void** result: the stack-trace, as an array\n//   int* sizes: the size of each stack frame, as an array\n//               (GetStackFrames* only)\n//   int max_depth: the size of the result (and sizes) array(s)\n//   int skip_count: how many stack pointers to skip before storing in result\n//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)\nint GET_STACK_TRACE_OR_FRAMES {\n  static const int kStackLength = 64;\n  void * stack[kStackLength];\n  int size;\n\n  size = backtrace(stack, kStackLength);\n  skip_count++;  // we want to skip the current frame as well\n  int result_count = size - skip_count;\n  if (result_count < 0)\n    result_count = 0;\n  if (result_count > max_depth)\n    result_count = max_depth;\n  for (int i = 0; i < result_count; i++)\n    result[i] = stack[i + skip_count];\n\n#if IS_STACK_FRAMES\n  // No implementation for finding out the stack frame sizes yet.\n  memset(sizes, 0, sizeof(*sizes) * result_count);\n#endif\n\n  return result_count;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_libunwind-inl.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Arun Sharma\n//\n// Produce stack trace using libunwind\n\n#ifndef BASE_STACKTRACE_LIBINWIND_INL_H_\n#define BASE_STACKTRACE_LIBINWIND_INL_H_\n// Note: this file is included into stacktrace.cc more than once.\n// Anything that should only be defined once should be here:\n\n// We only need local unwinder.\n#define UNW_LOCAL_ONLY\n\nextern \"C\" {\n#include <assert.h>\n#include <string.h>   // for memset()\n#include <libunwind.h>\n}\n#include \"google/stacktrace.h\"\n#include \"base/logging.h\"\n\n// Sometimes, we can try to get a stack trace from within a stack\n// trace, because libunwind can call mmap (maybe indirectly via an\n// internal mmap based memory allocator), and that mmap gets trapped\n// and causes a stack-trace request.  If were to try to honor that\n// recursive request, we'd end up with infinite recursion or deadlock.\n// Luckily, it's safe to ignore those subsequent traces.  In such\n// cases, we return 0 to indicate the situation.\nstatic __thread int recursive;\n\n#endif  // BASE_STACKTRACE_LIBINWIND_INL_H_\n\n// Note: this part of the file is included several times.\n// Do not put globals below.\n\n// The following 4 functions are generated from the code below:\n//   GetStack{Trace,Frames}()\n//   GetStack{Trace,Frames}WithContext()\n//\n// These functions take the following args:\n//   void** result: the stack-trace, as an array\n//   int* sizes: the size of each stack frame, as an array\n//               (GetStackFrames* only)\n//   int max_depth: the size of the result (and sizes) array(s)\n//   int skip_count: how many stack pointers to skip before storing in result\n//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)\nint GET_STACK_TRACE_OR_FRAMES {\n  void *ip;\n  int n = 0;\n  unw_cursor_t cursor;\n  unw_context_t uc;\n#if IS_STACK_FRAMES\n  unw_word_t sp = 0, next_sp = 0;\n#endif\n\n  if (recursive) {\n    return 0;\n  }\n  ++recursive;\n\n  unw_getcontext(&uc);\n  int ret = unw_init_local(&cursor, &uc);\n  assert(ret >= 0);\n  skip_count++;         // Do not include current frame\n\n  while (skip_count--) {\n    if (unw_step(&cursor) <= 0) {\n      goto out;\n    }\n#if IS_STACK_FRAMES\n    if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp)) {\n      goto out;\n    }\n#endif\n  }\n\n  while (n < max_depth) {\n    if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0) {\n      break;\n    }\n#if IS_STACK_FRAMES\n    sizes[n] = 0;\n#endif\n    result[n++] = ip;\n    if (unw_step(&cursor) <= 0) {\n      break;\n    }\n#if IS_STACK_FRAMES\n    sp = next_sp;\n    if (unw_get_reg(&cursor, UNW_REG_SP, &next_sp) , 0) {\n      break;\n    }\n    sizes[n - 1] = next_sp - sp;\n#endif\n  }\nout:\n  --recursive;\n  return n;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_powerpc-inl.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// Produce stack trace.  I'm guessing (hoping!) the code is much like\n// for x86.  For apple machines, at least, it seems to be; see\n//    http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html\n//    http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK\n// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882\n\n#ifndef BASE_STACKTRACE_POWERPC_INL_H_\n#define BASE_STACKTRACE_POWERPC_INL_H_\n// Note: this file is included into stacktrace.cc more than once.\n// Anything that should only be defined once should be here:\n\n#include <stdint.h>   // for uintptr_t\n#include <stdlib.h>   // for NULL\n#include <google/stacktrace.h>\n\n// Given a pointer to a stack frame, locate and return the calling\n// stackframe, or return NULL if no stackframe can be found. Perform sanity\n// checks (the strictness of which is controlled by the boolean parameter\n// \"STRICT_UNWINDING\") to reduce the chance that a bad pointer is returned.\ntemplate<bool STRICT_UNWINDING>\nstatic void **NextStackFrame(void **old_sp) {\n  void **new_sp = (void **) *old_sp;\n\n  // Check that the transition from frame pointer old_sp to frame\n  // pointer new_sp isn't clearly bogus\n  if (STRICT_UNWINDING) {\n    // With the stack growing downwards, older stack frame must be\n    // at a greater address that the current one.\n    if (new_sp <= old_sp) return NULL;\n    // Assume stack frames larger than 100,000 bytes are bogus.\n    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;\n  } else {\n    // In the non-strict mode, allow discontiguous stack frames.\n    // (alternate-signal-stacks for example).\n    if (new_sp == old_sp) return NULL;\n    // And allow frames upto about 1MB.\n    if ((new_sp > old_sp)\n        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;\n  }\n  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;\n  return new_sp;\n}\n\n// This ensures that GetStackTrace stes up the Link Register properly.\nvoid StacktracePowerPCDummyFunction() __attribute__((noinline));\nvoid StacktracePowerPCDummyFunction() { __asm__ volatile(\"\"); }\n#endif  // BASE_STACKTRACE_POWERPC_INL_H_\n\n// Note: this part of the file is included several times.\n// Do not put globals below.\n\n// The following 4 functions are generated from the code below:\n//   GetStack{Trace,Frames}()\n//   GetStack{Trace,Frames}WithContext()\n//\n// These functions take the following args:\n//   void** result: the stack-trace, as an array\n//   int* sizes: the size of each stack frame, as an array\n//               (GetStackFrames* only)\n//   int max_depth: the size of the result (and sizes) array(s)\n//   int skip_count: how many stack pointers to skip before storing in result\n//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)\nint GET_STACK_TRACE_OR_FRAMES {\n  void **sp;\n  // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)\n  // and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a\n  // different asm syntax.  I don't know quite the best way to discriminate\n  // systems using the old as from the new one; I've gone with __APPLE__.\n  // TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2\n#ifdef __APPLE__\n  __asm__ volatile (\"mr %0,r1\" : \"=r\" (sp));\n#else\n  __asm__ volatile (\"mr %0,1\" : \"=r\" (sp));\n#endif\n\n  // On PowerPC, the \"Link Register\" or \"Link Record\" (LR), is a stack\n  // entry that holds the return address of the subroutine call (what\n  // instruction we run after our function finishes).  This is the\n  // same as the stack-pointer of our parent routine, which is what we\n  // want here.  While the compiler will always(?) set up LR for\n  // subroutine calls, it may not for leaf functions (such as this one).\n  // This routine forces the compiler (at least gcc) to push it anyway.\n  StacktracePowerPCDummyFunction();\n\n#if IS_STACK_FRAMES\n  // Note we do *not* increment skip_count here for the SYSV ABI.  If\n  // we did, the list of stack frames wouldn't properly match up with\n  // the list of return addresses.  Note this means the top pc entry\n  // is probably bogus for linux/ppc (and other SYSV-ABI systems).\n#else\n  // The LR save area is used by the callee, so the top entry is bogus.\n  skip_count++;\n#endif\n\n  int n = 0;\n  while (sp && n < max_depth) {\n#if IS_STACK_FRAMES\n    // The GetStackFrames routine is called when we are in some\n    // informational context (the failure signal handler for example).\n    // Use the non-strict unwinding rules to produce a stack trace\n    // that is as complete as possible (even if it contains a few bogus\n    // entries in some rare cases).\n    void **next_sp = NextStackFrame<false>(sp);\n#else\n    void **next_sp = NextStackFrame<true>(sp);\n#endif\n\n    if (skip_count > 0) {\n      skip_count--;\n    } else {\n      // PowerPC has 3 main ABIs, which say where in the stack the\n      // Link Register is.  For DARWIN and AIX (used by apple and\n      // linux ppc64), it's in sp[2].  For SYSV (used by linux ppc),\n      // it's in sp[1].\n#if defined(_CALL_AIX) || defined(_CALL_DARWIN)\n      result[n++] = *(sp+2);\n#elif defined(_CALL_SYSV)\n      result[n++] = *(sp+1);\n#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))\n      // This check is in case the compiler doesn't define _CALL_AIX/etc.\n      result[n++] = *(sp+2);\n#elif defined(__linux)\n      // This check is in case the compiler doesn't define _CALL_SYSV.\n      result[n++] = *(sp+1);\n#else\n#error Need to specify the PPC ABI for your archiecture.\n#endif\n\n#if IS_STACK_FRAME\n      if (next_sp > sp) {\n        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;\n      } else {\n        // A frame-size of 0 is used to indicate unknown frame size.\n        sizes[n] = 0;\n      }\n#endif\n    }\n    sp = next_sp;\n  }\n  return n;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_win32-inl.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// ---\n// Produces a stack trace for Windows.  Normally, one could use\n// stacktrace_x86-inl.h or stacktrace_x86_64-inl.h -- and indeed, that\n// should work for binaries compiled using MSVC in \"debug\" mode.\n// However, in \"release\" mode, Windows uses frame-pointer\n// optimization, which makes getting a stack trace very difficult.\n//\n// There are several approaches one can take.  One is to use Windows\n// intrinsics like StackWalk64.  These can work, but have restrictions\n// on how successful they can be.  Another attempt is to write a\n// version of stacktrace_x86-inl.h that has heuristic support for\n// dealing with FPO, similar to what WinDbg does (see\n// http://www.nynaeve.net/?p=97).\n//\n// The solution we've ended up doing is to call the undocumented\n// windows function RtlCaptureStackBackTrace, which probably doesn't\n// work with FPO but at least is fast, and doesn't require a symbol\n// server.\n//\n// This code is inspired by a patch from David Vitek:\n//   http://code.google.com/p/google-perftools/issues/detail?id=83\n\n#ifndef BASE_STACKTRACE_WIN32_INL_H_\n#define BASE_STACKTRACE_WIN32_INL_H_\n// Note: this file is included into stacktrace.cc more than once.\n// Anything that should only be defined once should be here:\n\n#include \"config.h\"\n#include <windows.h>    // for GetProcAddress and GetModuleHandle\n#include <assert.h>\n\ntypedef USHORT NTAPI RtlCaptureStackBackTrace_Function(\n    IN ULONG frames_to_skip,\n    IN ULONG frames_to_capture,\n    OUT PVOID *backtrace,\n    OUT PULONG backtrace_hash);\n\n// Load the function we need at static init time, where we don't have\n// to worry about someone else holding the loader's lock.\nstatic RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =\n   (RtlCaptureStackBackTrace_Function*)\n   GetProcAddress(GetModuleHandleA(\"ntdll.dll\"), \"RtlCaptureStackBackTrace\");\n\nPERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,\n                                     int skip_count) {\n  if (!RtlCaptureStackBackTrace_fn) {\n    // TODO(csilvers): should we log an error here?\n    return 0;     // can't find a stacktrace with no function to call\n  }\n  return (int)RtlCaptureStackBackTrace_fn(skip_count + 2, max_depth,\n                                          result, 0);\n}\n\nPERFTOOLS_DLL_DECL int GetStackFrames(void** /* pcs */,\n                                      int* /* sizes */,\n                                      int /* max_depth */,\n                                      int /* skip_count */) {\n  assert(0 == \"Not yet implemented\");\n  return 0;\n}\n\n#endif  // BASE_STACKTRACE_WIN32_INL_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_x86-inl.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Produce stack trace\n\n#ifndef BASE_STACKTRACE_X86_INL_H_\n#define BASE_STACKTRACE_X86_INL_H_\n// Note: this file is included into stacktrace.cc more than once.\n// Anything that should only be defined once should be here:\n\n#include \"config.h\"\n#include <stdlib.h>   // for NULL\n#include <assert.h>\n#if defined(HAVE_SYS_UCONTEXT_H)\n#include <sys/ucontext.h>\n#elif defined(HAVE_UCONTEXT_H)\n#include <ucontext.h>  // for ucontext_t\n#elif defined(HAVE_CYGWIN_SIGNAL_H)\n// cygwin/signal.h has a buglet where it uses pthread_attr_t without\n// #including <pthread.h> itself.  So we have to do it.\n# ifdef HAVE_PTHREAD\n# include <pthread.h>\n# endif\n#include <cygwin/signal.h>\ntypedef ucontext ucontext_t;\n#endif\n#ifdef HAVE_STDINT_H\n#include <stdint.h>   // for uintptr_t\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h> // for msync\n#include \"base/vdso_support.h\"\n#endif\n\n#include \"google/stacktrace.h\"\n\n#if defined(__linux__) && defined(__i386__) && defined(__ELF__) && defined(HAVE_MMAP)\n// Count \"push %reg\" instructions in VDSO __kernel_vsyscall(),\n// preceeding \"syscall\" or \"sysenter\".\n// If __kernel_vsyscall uses frame pointer, answer 0.\n//\n// kMaxBytes tells how many instruction bytes of __kernel_vsyscall\n// to analyze before giving up. Up to kMaxBytes+1 bytes of\n// instructions could be accessed.\n//\n// Here are known __kernel_vsyscall instruction sequences:\n//\n// SYSENTER (linux-2.6.26/arch/x86/vdso/vdso32/sysenter.S).\n// Used on Intel.\n//  0xffffe400 <__kernel_vsyscall+0>:       push   %ecx\n//  0xffffe401 <__kernel_vsyscall+1>:       push   %edx\n//  0xffffe402 <__kernel_vsyscall+2>:       push   %ebp\n//  0xffffe403 <__kernel_vsyscall+3>:       mov    %esp,%ebp\n//  0xffffe405 <__kernel_vsyscall+5>:       sysenter\n//\n// SYSCALL (see linux-2.6.26/arch/x86/vdso/vdso32/syscall.S).\n// Used on AMD.\n//  0xffffe400 <__kernel_vsyscall+0>:       push   %ebp\n//  0xffffe401 <__kernel_vsyscall+1>:       mov    %ecx,%ebp\n//  0xffffe403 <__kernel_vsyscall+3>:       syscall\n//\n// i386 (see linux-2.6.26/arch/x86/vdso/vdso32/int80.S)\n//  0xffffe400 <__kernel_vsyscall+0>:       int $0x80\n//  0xffffe401 <__kernel_vsyscall+1>:       ret\n//\nstatic const int kMaxBytes = 10;\n\n// We use assert()s instead of DCHECK()s -- this is too low level\n// for DCHECK().\n\nstatic int CountPushInstructions(const unsigned char *const addr) {\n  int result = 0;\n  for (int i = 0; i < kMaxBytes; ++i) {\n    if (addr[i] == 0x89) {\n      // \"mov reg,reg\"\n      if (addr[i + 1] == 0xE5) {\n        // Found \"mov %esp,%ebp\".\n        return 0;\n      }\n      ++i;  // Skip register encoding byte.\n    } else if (addr[i] == 0x0F &&\n               (addr[i + 1] == 0x34 || addr[i + 1] == 0x05)) {\n      // Found \"sysenter\" or \"syscall\".\n      return result;\n    } else if ((addr[i] & 0xF0) == 0x50) {\n      // Found \"push %reg\".\n      ++result;\n    } else if (addr[i] == 0xCD && addr[i + 1] == 0x80) {\n      // Found \"int $0x80\"\n      assert(result == 0);\n      return 0;\n    } else {\n      // Unexpected instruction.\n      assert(0 == \"unexpected instruction in __kernel_vsyscall\");\n      return 0;\n    }\n  }\n  // Unexpected: didn't find SYSENTER or SYSCALL in\n  // [__kernel_vsyscall, __kernel_vsyscall + kMaxBytes) interval.\n  assert(0 == \"did not find SYSENTER or SYSCALL in __kernel_vsyscall\");\n  return 0;\n}\n#endif\n\n// Given a pointer to a stack frame, locate and return the calling\n// stackframe, or return NULL if no stackframe can be found. Perform sanity\n// checks (the strictness of which is controlled by the boolean parameter\n// \"STRICT_UNWINDING\") to reduce the chance that a bad pointer is returned.\ntemplate<bool STRICT_UNWINDING, bool WITH_CONTEXT>\nstatic void **NextStackFrame(void **old_sp, const void *uc) {\n  void **new_sp = (void **) *old_sp;\n\n#if defined(__linux__) && defined(__i386__) && defined(HAVE_VDSO_SUPPORT)\n  if (WITH_CONTEXT && uc != NULL) {\n    // How many \"push %reg\" instructions are there at __kernel_vsyscall?\n    // This is constant for a given kernel and processor, so compute\n    // it only once.\n    static int num_push_instructions = -1;  // Sentinel: not computed yet.\n    // Initialize with sentinel value: __kernel_rt_sigreturn can not possibly\n    // be there.\n    static const unsigned char *kernel_rt_sigreturn_address = NULL;\n    static const unsigned char *kernel_vsyscall_address = NULL;\n    if (num_push_instructions == -1) {\n      base::VDSOSupport vdso;\n      if (vdso.IsPresent()) {\n        base::VDSOSupport::SymbolInfo rt_sigreturn_symbol_info;\n        base::VDSOSupport::SymbolInfo vsyscall_symbol_info;\n        if (!vdso.LookupSymbol(\"__kernel_rt_sigreturn\", \"LINUX_2.5\",\n                               STT_FUNC, &rt_sigreturn_symbol_info) ||\n            !vdso.LookupSymbol(\"__kernel_vsyscall\", \"LINUX_2.5\",\n                               STT_FUNC, &vsyscall_symbol_info) ||\n            rt_sigreturn_symbol_info.address == NULL ||\n            vsyscall_symbol_info.address == NULL) {\n          // Unexpected: 32-bit VDSO is present, yet one of the expected\n          // symbols is missing or NULL.\n          assert(0 == \"VDSO is present, but doesn't have expected symbols\");\n          num_push_instructions = 0;\n        } else {\n          kernel_rt_sigreturn_address =\n              reinterpret_cast<const unsigned char *>(\n                  rt_sigreturn_symbol_info.address);\n          kernel_vsyscall_address =\n              reinterpret_cast<const unsigned char *>(\n                  vsyscall_symbol_info.address);\n          num_push_instructions =\n              CountPushInstructions(kernel_vsyscall_address);\n        }\n      } else {\n        num_push_instructions = 0;\n      }\n    }\n    if (num_push_instructions != 0 && kernel_rt_sigreturn_address != NULL &&\n        old_sp[1] == kernel_rt_sigreturn_address) {\n      const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);\n      // This kernel does not use frame pointer in its VDSO code,\n      // and so %ebp is not suitable for unwinding.\n      void **const reg_ebp =\n          reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_EBP]);\n      const unsigned char *const reg_eip =\n          reinterpret_cast<unsigned char *>(ucv->uc_mcontext.gregs[REG_EIP]);\n      if (new_sp == reg_ebp &&\n          kernel_vsyscall_address <= reg_eip &&\n          reg_eip - kernel_vsyscall_address < kMaxBytes) {\n        // We \"stepped up\" to __kernel_vsyscall, but %ebp is not usable.\n        // Restore from 'ucv' instead.\n        void **const reg_esp =\n            reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_ESP]);\n        // Check that alleged %esp is not NULL and is reasonably aligned.\n        if (reg_esp &&\n            ((uintptr_t)reg_esp & (sizeof(reg_esp) - 1)) == 0) {\n          // Check that alleged %esp is actually readable. This is to prevent\n          // \"double fault\" in case we hit the first fault due to e.g. stack\n          // corruption.\n          //\n          // page_size is linker-initalized to avoid async-unsafe locking\n          // that GCC would otherwise insert (__cxa_guard_acquire etc).\n          static int page_size;\n          if (page_size == 0) {\n            // First time through.\n            page_size = getpagesize();\n          }\n          void *const reg_esp_aligned =\n              reinterpret_cast<void *>(\n                  (uintptr_t)(reg_esp + num_push_instructions - 1) &\n                  ~(page_size - 1));\n          if (msync(reg_esp_aligned, page_size, MS_ASYNC) == 0) {\n            // Alleged %esp is readable, use it for further unwinding.\n            new_sp = reinterpret_cast<void **>(\n                reg_esp[num_push_instructions - 1]);\n          }\n        }\n      }\n    }\n  }\n#endif\n\n  // Check that the transition from frame pointer old_sp to frame\n  // pointer new_sp isn't clearly bogus\n  if (STRICT_UNWINDING) {\n    // With the stack growing downwards, older stack frame must be\n    // at a greater address that the current one.\n    if (new_sp <= old_sp) return NULL;\n    // Assume stack frames larger than 100,000 bytes are bogus.\n    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;\n  } else {\n    // In the non-strict mode, allow discontiguous stack frames.\n    // (alternate-signal-stacks for example).\n    if (new_sp == old_sp) return NULL;\n    // And allow frames upto about 1MB.\n    if ((new_sp > old_sp)\n        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;\n  }\n  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;\n#ifdef __i386__\n  // On 64-bit machines, the stack pointer can be very close to\n  // 0xffffffff, so we explicitly check for a pointer into the\n  // last two pages in the address space\n  if ((uintptr_t)new_sp >= 0xffffe000) return NULL;\n#endif\n#ifdef HAVE_MMAP\n  if (!STRICT_UNWINDING) {\n    // Lax sanity checks cause a crash on AMD-based machines with\n    // VDSO-enabled kernels.\n    // Make an extra sanity check to insure new_sp is readable.\n    // Note: NextStackFrame<false>() is only called while the program\n    //       is already on its last leg, so it's ok to be slow here.\n    static int page_size = getpagesize();\n    void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));\n    if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1)\n      return NULL;\n  }\n#endif\n  return new_sp;\n}\n\n#endif  // BASE_STACKTRACE_X86_INL_H_\n\n// Note: this part of the file is included several times.\n// Do not put globals below.\n\n// The following 4 functions are generated from the code below:\n//   GetStack{Trace,Frames}()\n//   GetStack{Trace,Frames}WithContext()\n//\n// These functions take the following args:\n//   void** result: the stack-trace, as an array\n//   int* sizes: the size of each stack frame, as an array\n//               (GetStackFrames* only)\n//   int max_depth: the size of the result (and sizes) array(s)\n//   int skip_count: how many stack pointers to skip before storing in result\n//   void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)\n\nint GET_STACK_TRACE_OR_FRAMES {\n  void **sp;\n#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || __llvm__\n  // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8.\n  // It's always correct on llvm, and the techniques below aren't (in\n  // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),\n  // so we also prefer __builtin_frame_address when running under llvm.\n  sp = reinterpret_cast<void**>(__builtin_frame_address(0));\n#elif defined(__i386__)\n  // Stack frame format:\n  //    sp[0]   pointer to previous frame\n  //    sp[1]   caller address\n  //    sp[2]   first argument\n  //    ...\n  // NOTE: This will break under llvm, since result is a copy and not in sp[2]\n  sp = (void **)&result - 2;\n#elif defined(__x86_64__)\n  unsigned long rbp;\n  // Move the value of the register %rbp into the local variable rbp.\n  // We need 'volatile' to prevent this instruction from getting moved\n  // around during optimization to before function prologue is done.\n  // An alternative way to achieve this\n  // would be (before this __asm__ instruction) to call Noop() defined as\n  //   static void Noop() __attribute__ ((noinline));  // prevent inlining\n  //   static void Noop() { asm(\"\"); }  // prevent optimizing-away\n  __asm__ volatile (\"mov %%rbp, %0\" : \"=r\" (rbp));\n  // Arguments are passed in registers on x86-64, so we can't just\n  // offset from &result\n  sp = (void **) rbp;\n#else\n# error Using stacktrace_x86-inl.h on a non x86 architecture!\n#endif\n\n  int n = 0;\n  while (sp && n < max_depth) {\n    if (*(sp+1) == reinterpret_cast<void *>(0)) {\n      // In 64-bit code, we often see a frame that\n      // points to itself and has a return address of 0.\n      break;\n    }\n#if !IS_WITH_CONTEXT\n    const void *const ucp = NULL;\n#endif\n    void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp);\n    if (skip_count > 0) {\n      skip_count--;\n    } else {\n      result[n] = *(sp+1);\n#if IS_STACK_FRAMES\n      if (next_sp > sp) {\n        sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;\n      } else {\n        // A frame-size of 0 is used to indicate unknown frame size.\n        sizes[n] = 0;\n      }\n#endif\n      n++;\n    }\n    sp = next_sp;\n  }\n  return n;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/stacktrace_x86_64-inl.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Arun Sharma\n//\n// Produce stack trace using libgcc\n\nextern \"C\" {\n#include <stdlib.h> // for NULL\n#include <unwind.h> // ABI defined unwinder\n#include <string.h> // for memset\n}\n#include \"google/stacktrace.h\"\n\ntypedef struct {\n  void **result;\n  int max_depth;\n  int skip_count;\n  int count;\n} trace_arg_t;\n\n\n// Workaround for the malloc() in _Unwind_Backtrace() issue.\nstatic _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) {\n  return _URC_NO_REASON;\n}\n\n\n// This code is not considered ready to run until\n// static initializers run so that we are guaranteed\n// that any malloc-related initialization is done.\nstatic bool ready_to_run = false;\nclass StackTraceInit {\n public:\n   StackTraceInit() {\n     // Extra call to force initialization\n     _Unwind_Backtrace(nop_backtrace, NULL);\n     ready_to_run = true;\n   }\n};\n\nstatic StackTraceInit module_initializer;  // Force initialization\n\nstatic _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {\n  trace_arg_t *targ = (trace_arg_t *) opq;\n\n  if (targ->skip_count > 0) {\n    targ->skip_count--;\n  } else {\n    targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);\n  }\n\n  if (targ->count == targ->max_depth)\n    return _URC_END_OF_STACK;\n\n  return _URC_NO_REASON;\n}\n\n// If you change this function, also change GetStackFrames below.\nint GetStackTrace(void** result, int max_depth, int skip_count) {\n  if (!ready_to_run)\n    return 0;\n\n  trace_arg_t targ;\n\n  skip_count += 1;         // Do not include the \"GetStackTrace\" frame\n\n  targ.result = result;\n  targ.max_depth = max_depth;\n  targ.skip_count = skip_count;\n  targ.count = 0;\n\n  _Unwind_Backtrace(GetOneFrame, &targ);\n\n  return targ.count;\n}\n\n// If you change this function, also change GetStackTrace above:\n//\n// This GetStackFrames routine shares a lot of code with GetStackTrace\n// above. This code could have been refactored into a common routine,\n// and then both GetStackTrace/GetStackFrames could call that routine.\n// There are two problems with that:\n//\n// (1) The performance of the refactored-code suffers substantially - the\n//     refactored needs to be able to record the stack trace when called\n//     from GetStackTrace, and both the stack trace and stack frame sizes,\n//     when called from GetStackFrames - this introduces enough new\n//     conditionals that GetStackTrace performance can degrade by as much\n//     as 50%.\n//\n// (2) Whether the refactored routine gets inlined into GetStackTrace and\n//     GetStackFrames depends on the compiler, and we can't guarantee the\n//     behavior either-way, even with \"__attribute__ ((always_inline))\"\n//     or \"__attribute__ ((noinline))\". But we need this guarantee or the\n//     frame counts may be off by one.\n//\n// Both (1) and (2) can be addressed without this code duplication, by\n// clever use of template functions, and by defining GetStackTrace and\n// GetStackFrames as macros that expand to these template functions.\n// However, this approach comes with its own set of problems - namely,\n// macros and  preprocessor trouble - for example,  if GetStackTrace\n// and/or GetStackFrames is ever defined as a member functions in some\n// class, we are in trouble.\nint GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {\n  if (!ready_to_run)\n    return 0;\n\n  trace_arg_t targ;\n\n  skip_count += 1;         // Do not include the \"GetStackFrames\" frame\n\n  targ.result = pcs;\n  targ.max_depth = max_depth;\n  targ.skip_count = skip_count;\n  targ.count = 0;\n\n  _Unwind_Backtrace(GetOneFrame, &targ);\n\n  // No implementation for finding out the stack frame sizes yet.\n  memset(sizes, 0, sizeof(*sizes) * targ.count);\n\n  return targ.count;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/static_vars.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Ken Ashcraft <opensource@google.com>\n\n#include \"static_vars.h\"\n#include \"sampler.h\"  // for the init function\n\nnamespace tcmalloc {\n\nSpinLock Static::pageheap_lock_(SpinLock::LINKER_INITIALIZED);\nSizeMap Static::sizemap_;\nCentralFreeListPadded Static::central_cache_[kNumClasses];\nPageHeapAllocator<Span> Static::span_allocator_;\nPageHeapAllocator<StackTrace> Static::stacktrace_allocator_;\nSpan Static::sampled_objects_;\nPageHeapAllocator<StackTraceTable::Bucket> Static::bucket_allocator_;\nStackTrace* Static::growth_stacks_ = NULL;\nchar Static::pageheap_memory_[sizeof(PageHeap)];\n\nvoid Static::InitStaticVars() {\n  sizemap_.Init();\n  span_allocator_.Init();\n  span_allocator_.New(); // Reduce cache conflicts\n  span_allocator_.New(); // Reduce cache conflicts\n  stacktrace_allocator_.Init();\n  bucket_allocator_.Init();\n  // Do a bit of sanitizing: make sure central_cache is aligned properly\n  CHECK_CONDITION((sizeof(central_cache_[0]) % 64) == 0);\n  for (int i = 0; i < kNumClasses; ++i) {\n    central_cache_[i].Init(i);\n  }\n  new ((void*)pageheap_memory_) PageHeap;\n  DLL_Init(&sampled_objects_);\n  Sampler::InitStatics();\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/static_vars.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Ken Ashcraft <opensource@google.com>\n//\n// Static variables shared by multiple classes.\n\n#ifndef TCMALLOC_STATIC_VARS_H_\n#define TCMALLOC_STATIC_VARS_H_\n\n#include <config.h>\n#include \"base/spinlock.h\"\n#include \"central_freelist.h\"\n#include \"common.h\"\n#include \"page_heap.h\"\n#include \"page_heap_allocator.h\"\n#include \"span.h\"\n#include \"stack_trace_table.h\"\n\nnamespace tcmalloc {\n\nclass Static {\n public:\n  // Linker initialized, so this lock can be accessed at any time.\n  static SpinLock* pageheap_lock() { return &pageheap_lock_; }\n\n  // Must be called before calling any of the accessors below.\n  static void InitStaticVars();\n\n  // Central cache -- an array of free-lists, one per size-class.\n  // We have a separate lock per free-list to reduce contention.\n  static CentralFreeListPadded* central_cache() { return central_cache_; }\n\n  static SizeMap* sizemap() { return &sizemap_; }\n\n  //////////////////////////////////////////////////////////////////////\n  // In addition to the explicit initialization comment, the variables below\n  // must be protected by pageheap_lock.\n\n  // Page-level allocator.\n  static PageHeap* pageheap() {\n    return reinterpret_cast<PageHeap*>(pageheap_memory_);\n  }\n\n  static PageHeapAllocator<Span>* span_allocator() { return &span_allocator_; }\n\n  static PageHeapAllocator<StackTrace>* stacktrace_allocator() {\n    return &stacktrace_allocator_;\n  }\n\n  static StackTrace* growth_stacks() { return growth_stacks_; }\n  static void set_growth_stacks(StackTrace* s) { growth_stacks_ = s; }\n\n  // State kept for sampled allocations (/pprof/heap support)\n  static Span* sampled_objects() { return &sampled_objects_; }\n  static PageHeapAllocator<StackTraceTable::Bucket>* bucket_allocator() {\n    return &bucket_allocator_;\n  }\n\n private:\n  static SpinLock pageheap_lock_;\n\n  // These static variables require explicit initialization.  We cannot\n  // count on their constructors to do any initialization because other\n  // static variables may try to allocate memory before these variables\n  // can run their constructors.\n\n  static SizeMap sizemap_;\n  static CentralFreeListPadded central_cache_[kNumClasses];\n  static PageHeapAllocator<Span> span_allocator_;\n  static PageHeapAllocator<StackTrace> stacktrace_allocator_;\n  static Span sampled_objects_;\n  static PageHeapAllocator<StackTraceTable::Bucket> bucket_allocator_;\n\n  // Linked list of stack traces recorded every time we allocated memory\n  // from the system.  Useful for finding allocation sites that cause\n  // increase in the footprint of the system.  The linked list pointer\n  // is stored in trace->stack[kMaxStackDepth-1].\n  static StackTrace* growth_stacks_;\n\n  // PageHeap uses a constructor for initialization.  Like the members above,\n  // we can't depend on initialization order, so pageheap is new'd\n  // into this buffer.\n  static char pageheap_memory_[sizeof(PageHeap)];\n};\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_STATIC_VARS_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/symbolize.cc",
    "content": "// Copyright (c) 2009, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// This forks out to pprof to do the actual symbolizing.  We might\n// be better off writing our own in C++.\n\n#include \"config.h\"\n#include \"symbolize.h\"\n#include <stdlib.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>   // for write()\n#endif\n#ifdef HAVE_SYS_SOCKET_H\n#include <sys/socket.h>   // for socketpair() -- needed by Symbolize\n#endif\n#ifdef HAVE_SYS_WAIT_H\n#include <sys/wait.h>   // for wait() -- needed by Symbolize\n#endif\n#ifdef HAVE_POLL_H\n#include <poll.h>\n#endif\n#include <string>\n#include \"base/commandlineflags.h\"\n#include \"base/sysinfo.h\"\n\nusing std::string;\nusing tcmalloc::DumpProcSelfMaps;   // from sysinfo.h\n\n\nDEFINE_string(symbolize_pprof,\n              EnvToString(\"PPROF_PATH\", \"pprof\"),\n              \"Path to pprof to call for reporting function names.\");\n\n// heap_profile_table_pprof may be referenced after destructors are\n// called (since that's when leak-checking is done), so we make\n// a more-permanent copy that won't ever get destroyed.\nstatic string* g_pprof_path = new string(FLAGS_symbolize_pprof);\n\nvoid SymbolTable::Add(const void* addr) {\n  symbolization_table_[addr] = \"\";\n}\n\nconst char* SymbolTable::GetSymbol(const void* addr) {\n  return symbolization_table_[addr];\n}\n\n// Updates symbolization_table with the pointers to symbol names corresponding\n// to its keys. The symbol names are stored in out, which is allocated and\n// freed by the caller of this routine.\n// Note that the forking/etc is not thread-safe or re-entrant.  That's\n// ok for the purpose we need -- reporting leaks detected by heap-checker\n// -- but be careful if you decide to use this routine for other purposes.\nint SymbolTable::Symbolize() {\n#if !defined(HAVE_UNISTD_H)  || !defined(HAVE_SYS_SOCKET_H) || !defined(HAVE_SYS_WAIT_H)\n  return 0;\n#elif !defined(HAVE_PROGRAM_INVOCATION_NAME)\n  return 0;   // TODO(csilvers): get argv[0] somehow\n#else\n  // All this work is to do two-way communication.  ugh.\n  extern char* program_invocation_name;  // gcc provides this\n  int *child_in = NULL;   // file descriptors\n  int *child_out = NULL;  // for now, we don't worry about child_err\n  int child_fds[5][2];    // socketpair may be called up to five times below\n\n  // The client program may close its stdin and/or stdout and/or stderr\n  // thus allowing socketpair to reuse file descriptors 0, 1 or 2.\n  // In this case the communication between the forked processes may be broken\n  // if either the parent or the child tries to close or duplicate these\n  // descriptors. The loop below produces two pairs of file descriptors, each\n  // greater than 2 (stderr).\n  for (int i = 0; i < 5; i++) {\n    if (socketpair(AF_UNIX, SOCK_STREAM, 0, child_fds[i]) == -1) {\n      for (int j = 0; j < i; j++) {\n        close(child_fds[j][0]);\n        close(child_fds[j][1]);\n        return 0;\n      }\n    } else {\n      if ((child_fds[i][0] > 2) && (child_fds[i][1] > 2)) {\n        if (child_in == NULL) {\n          child_in = child_fds[i];\n        } else {\n          child_out = child_fds[i];\n          for (int j = 0; j < i; j++) {\n            if (child_fds[j] == child_in) continue;\n            close(child_fds[j][0]);\n            close(child_fds[j][1]);\n          }\n          break;\n        }\n      }\n    }\n  }\n\n  switch (fork()) {\n    case -1: {  // error\n      close(child_in[0]);\n      close(child_in[1]);\n      close(child_out[0]);\n      close(child_out[1]);\n      return 0;\n    }\n    case 0: {  // child\n      close(child_in[1]);   // child uses the 0's, parent uses the 1's\n      close(child_out[1]);  // child uses the 0's, parent uses the 1's\n      close(0);\n      close(1);\n      if (dup2(child_in[0], 0) == -1) _exit(1);\n      if (dup2(child_out[0], 1) == -1) _exit(2);\n      // Unset vars that might cause trouble when we fork\n      unsetenv(\"CPUPROFILE\");\n      unsetenv(\"HEAPPROFILE\");\n      unsetenv(\"HEAPCHECK\");\n      unsetenv(\"PERFTOOLS_VERBOSE\");\n      execlp(g_pprof_path->c_str(), g_pprof_path->c_str(),\n             \"--symbols\", program_invocation_name, NULL);\n      _exit(3);  // if execvp fails, it's bad news for us\n    }\n    default: {  // parent\n      close(child_in[0]);   // child uses the 0's, parent uses the 1's\n      close(child_out[0]);  // child uses the 0's, parent uses the 1's\n#ifdef HAVE_POLL_H\n      // For maximum safety, we check to make sure the execlp\n      // succeeded before trying to write.  (Otherwise we'll get a\n      // SIGPIPE.)  For systems without poll.h, we'll just skip this\n      // check, and trust that the user set PPROF_PATH correctly!\n      struct pollfd pfd = { child_in[1], POLLOUT, 0 };\n      if (!poll(&pfd, 1, 0) || !(pfd.revents & POLLOUT) ||\n          (pfd.revents & (POLLHUP|POLLERR))) {\n        return 0;\n      }\n#endif\n      DumpProcSelfMaps(child_in[1]);  // what pprof expects on stdin\n\n      // Allocate 24 bytes = (\"0x\" + 8 bytes + \"\\n\" + overhead) for each\n      // address to feed to pprof.\n      const int kOutBufSize = 24 * symbolization_table_.size();\n      char *pprof_buffer = new char[kOutBufSize];\n      int written = 0;\n      for (SymbolMap::const_iterator iter = symbolization_table_.begin();\n           iter != symbolization_table_.end(); ++iter) {\n        written += snprintf(pprof_buffer + written, kOutBufSize - written,\n                 // pprof expects format to be 0xXXXXXX\n                 \"0x%\"PRIxPTR\"\\n\", reinterpret_cast<uintptr_t>(iter->first));\n      }\n      write(child_in[1], pprof_buffer, strlen(pprof_buffer));\n      close(child_in[1]);             // that's all we need to write\n\n      const int kSymbolBufferSize = kSymbolSize * symbolization_table_.size();\n      int total_bytes_read = 0;\n      delete[] symbol_buffer_;\n      symbol_buffer_ = new char[kSymbolBufferSize];\n      memset(symbol_buffer_, '\\0', kSymbolBufferSize);\n      while (1) {\n        int bytes_read = read(child_out[1], symbol_buffer_ + total_bytes_read,\n                              kSymbolBufferSize - total_bytes_read);\n        if (bytes_read < 0) {\n          close(child_out[1]);\n          return 0;\n        } else if (bytes_read == 0) {\n          close(child_out[1]);\n          wait(NULL);\n          break;\n        } else {\n          total_bytes_read += bytes_read;\n        }\n      }\n      // We have successfully read the output of pprof into out.  Make sure\n      // the last symbol is full (we can tell because it ends with a \\n).\n      if (total_bytes_read == 0 || symbol_buffer_[total_bytes_read - 1] != '\\n')\n        return 0;\n      // make the symbolization_table_ values point to the output vector\n      SymbolMap::iterator fill = symbolization_table_.begin();\n      int num_symbols = 0;\n      const char *current_name = symbol_buffer_;\n      for (int i = 0; i < total_bytes_read; i++) {\n        if (symbol_buffer_[i] == '\\n') {\n          fill->second = current_name;\n          symbol_buffer_[i] = '\\0';\n          current_name = symbol_buffer_ + i + 1;\n          fill++;\n          num_symbols++;\n        }\n      }\n      return num_symbols;\n    }\n  }\n  return 0;  // shouldn't be reachable\n#endif\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/symbolize.h",
    "content": "// Copyright (c) 2009, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n\n#ifndef TCMALLOC_SYMBOLIZE_H_\n#define TCMALLOC_SYMBOLIZE_H_\n\n#include \"config.h\"\n#ifdef HAVE_STDINT_H\n#include <stdint.h>  // for uintptr_t\n#endif\n#include <stddef.h>  // for NULL\n#include <map>\n\nusing std::map;\n\n// SymbolTable encapsulates the address operations necessary for stack trace\n// symbolization. A common use-case is to Add() the addresses from one or\n// several stack traces to a table, call Symbolize() once and use GetSymbol()\n// to get the symbol names for pretty-printing the stack traces.\nclass SymbolTable {\n public:\n  SymbolTable()\n    : symbol_buffer_(NULL) {}\n  ~SymbolTable() {\n    delete[] symbol_buffer_;\n  }\n\n  // Adds an address to the table. This may overwrite a currently known symbol\n  // name, so Add() should not generally be called after Symbolize().\n  void Add(const void* addr);\n\n  // Returns the symbol name for addr, if the given address was added before\n  // the last successful call to Symbolize(). Otherwise may return an empty\n  // c-string.\n  const char* GetSymbol(const void* addr);\n\n  // Obtains the symbol names for the addresses stored in the table and returns\n  // the number of addresses actually symbolized.\n  int Symbolize();\n\n private:\n  typedef map<const void*, const char*> SymbolMap;\n\n  // An average size of memory allocated for a stack trace symbol.\n  static const int kSymbolSize = 1024;\n\n  // Map from addresses to symbol names.\n  SymbolMap symbolization_table_;\n\n  // Pointer to the buffer that stores the symbol names.\n  char *symbol_buffer_;\n};\n\n#endif  // TCMALLOC_SYMBOLIZE_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/system-alloc.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n\n#include <config.h>\n#include <stddef.h>  // for NULL\n#if defined HAVE_STDINT_H\n#include <stdint.h>\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>\n#else\n#include <sys/types.h>\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#include <fcntl.h>    // for open()\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#endif\n#include <errno.h>\n#include \"common.h\"\n#include \"system-alloc.h\"\n#include \"internal_logging.h\"\n#include \"base/logging.h\"\n#include \"base/commandlineflags.h\"\n#include \"base/spinlock.h\"\n\n// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old\n// form of the name instead.\n#ifndef MAP_ANONYMOUS\n# define MAP_ANONYMOUS MAP_ANON\n#endif\n\n// Solaris has a bug where it doesn't declare madvise() for C++.\n//    http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0\n#if defined(__sun) && defined(__SVR4)\n# include <sys/types.h>    // for caddr_t\n  extern \"C\" { extern int madvise(caddr_t, size_t, int); }\n#endif\n\n// Set kDebugMode mode so that we can have use C++ conditionals\n// instead of preprocessor conditionals.\n#ifdef NDEBUG\nstatic const bool kDebugMode = false;\n#else\nstatic const bool kDebugMode = true;\n#endif\n\n// Anonymous namespace to avoid name conflicts on \"CheckAddressBits\".\nnamespace {\n\n// Check that no bit is set at position ADDRESS_BITS or higher.\ntemplate <int ADDRESS_BITS> bool CheckAddressBits(uintptr_t ptr) {\n  return (ptr >> ADDRESS_BITS) == 0;\n}\n\n// Specialize for the bit width of a pointer to avoid undefined shift.\ntemplate <> bool CheckAddressBits<8 * sizeof(void*)>(uintptr_t ptr) {\n  return true;\n}\n\n}  // Anonymous namespace to avoid name conflicts on \"CheckAddressBits\".\n\nCOMPILE_ASSERT(kAddressBits <= 8 * sizeof(void*),\n               address_bits_larger_than_pointer_size);\n\n// Structure for discovering alignment\nunion MemoryAligner {\n  void*  p;\n  double d;\n  size_t s;\n} CACHELINE_ALIGNED;\n\nstatic SpinLock spinlock(SpinLock::LINKER_INITIALIZED);\n\n#if defined(HAVE_MMAP) || defined(MADV_DONTNEED)\n// Page size is initialized on demand (only needed for mmap-based allocators)\nstatic size_t pagesize = 0;\n#endif\n\n// Configuration parameters.\n\nDEFINE_int32(malloc_devmem_start,\n             EnvToInt(\"TCMALLOC_DEVMEM_START\", 0),\n             \"Physical memory starting location in MB for /dev/mem allocation.\"\n             \"  Setting this to 0 disables /dev/mem allocation\");\nDEFINE_int32(malloc_devmem_limit,\n             EnvToInt(\"TCMALLOC_DEVMEM_LIMIT\", 0),\n             \"Physical memory limit location in MB for /dev/mem allocation.\"\n             \"  Setting this to 0 means no limit.\");\nDEFINE_bool(malloc_skip_sbrk,\n            EnvToBool(\"TCMALLOC_SKIP_SBRK\", false),\n            \"Whether sbrk can be used to obtain memory.\");\nDEFINE_bool(malloc_skip_mmap,\n            EnvToBool(\"TCMALLOC_SKIP_MMAP\", false),\n            \"Whether mmap can be used to obtain memory.\");\n\n// static allocators\nclass SbrkSysAllocator : public SysAllocator {\npublic:\n  SbrkSysAllocator() : SysAllocator() {\n  }\n  void* Alloc(size_t size, size_t *actual_size, size_t alignment);\n  void DumpStats(TCMalloc_Printer* printer);\n};\nstatic char sbrk_space[sizeof(SbrkSysAllocator)];\n\nclass MmapSysAllocator : public SysAllocator {\npublic:\n  MmapSysAllocator() : SysAllocator() {\n  }\n  void* Alloc(size_t size, size_t *actual_size, size_t alignment);\n  void DumpStats(TCMalloc_Printer* printer);\n};\nstatic char mmap_space[sizeof(MmapSysAllocator)];\n\nclass DevMemSysAllocator : public SysAllocator {\npublic:\n  DevMemSysAllocator() : SysAllocator() {\n  }\n  void* Alloc(size_t size, size_t *actual_size, size_t alignment);\n  void DumpStats(TCMalloc_Printer* printer);\n};\nstatic char devmem_space[sizeof(DevMemSysAllocator)];\n\nstatic const int kStaticAllocators = 3;\n// kMaxDynamicAllocators + kStaticAllocators;\nstatic const int kMaxAllocators = 5;\nstatic SysAllocator *allocators[kMaxAllocators];\n\nbool RegisterSystemAllocator(SysAllocator *a, int priority) {\n  SpinLockHolder lock_holder(&spinlock);\n\n  // No two allocators should have a priority conflict, since the order\n  // is determined at compile time.\n  CHECK_CONDITION(allocators[priority] == NULL);\n  allocators[priority] = a;\n  return true;\n}\n\n\nvoid* SbrkSysAllocator::Alloc(size_t size, size_t *actual_size,\n                              size_t alignment) {\n#ifndef HAVE_SBRK\n  failed_ = true;\n  return NULL;\n#else\n  // Check if we should use sbrk allocation.\n  // FLAGS_malloc_skip_sbrk starts out as false (its uninitialized\n  // state) and eventually gets initialized to the specified value.  Note\n  // that this code runs for a while before the flags are initialized.\n  // That means that even if this flag is set to true, some (initial)\n  // memory will be allocated with sbrk before the flag takes effect.\n  if (FLAGS_malloc_skip_sbrk) {\n    return NULL;\n  }\n\n  // sbrk will release memory if passed a negative number, so we do\n  // a strict check here\n  if (static_cast<ptrdiff_t>(size + alignment) < 0) return NULL;\n\n  // This doesn't overflow because TCMalloc_SystemAlloc has already\n  // tested for overflow at the alignment boundary.\n  size = ((size + alignment - 1) / alignment) * alignment;\n\n  // \"actual_size\" indicates that the bytes from the returned pointer\n  // p up to and including (p + actual_size - 1) have been allocated.\n  if (actual_size) {\n    *actual_size = size;\n  }\n\n  // Check that we we're not asking for so much more memory that we'd\n  // wrap around the end of the virtual address space.  (This seems\n  // like something sbrk() should check for us, and indeed opensolaris\n  // does, but glibc does not:\n  //    http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/sys/sbrk.c?a=true\n  //    http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/libc/misc/sbrk.c?rev=1.1.2.1&content-type=text/plain&cvsroot=glibc\n  // Without this check, sbrk may succeed when it ought to fail.)\n  if (reinterpret_cast<intptr_t>(sbrk(0)) + size < size) {\n    failed_ = true;\n    return NULL;\n  }\n\n  void* result = sbrk(size);\n  if (result == reinterpret_cast<void*>(-1)) {\n    failed_ = true;\n    return NULL;\n  }\n\n  // Is it aligned?\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);\n  if ((ptr & (alignment-1)) == 0)  return result;\n\n  // Try to get more memory for alignment\n  size_t extra = alignment - (ptr & (alignment-1));\n  void* r2 = sbrk(extra);\n  if (reinterpret_cast<uintptr_t>(r2) == (ptr + size)) {\n    // Contiguous with previous result\n    return reinterpret_cast<void*>(ptr + extra);\n  }\n\n  // Give up and ask for \"size + alignment - 1\" bytes so\n  // that we can find an aligned region within it.\n  result = sbrk(size + alignment - 1);\n  if (result == reinterpret_cast<void*>(-1)) {\n    failed_ = true;\n    return NULL;\n  }\n  ptr = reinterpret_cast<uintptr_t>(result);\n  if ((ptr & (alignment-1)) != 0) {\n    ptr += alignment - (ptr & (alignment-1));\n  }\n  return reinterpret_cast<void*>(ptr);\n#endif  // HAVE_SBRK\n}\n\nvoid SbrkSysAllocator::DumpStats(TCMalloc_Printer* printer) {\n  printer->printf(\"SbrkSysAllocator: failed_=%d\\n\", failed_);\n}\n\nvoid* MmapSysAllocator::Alloc(size_t size, size_t *actual_size,\n                              size_t alignment) {\n#ifndef HAVE_MMAP\n  failed_ = true;\n  return NULL;\n#else\n  // Check if we should use mmap allocation.\n  // FLAGS_malloc_skip_mmap starts out as false (its uninitialized\n  // state) and eventually gets initialized to the specified value.  Note\n  // that this code runs for a while before the flags are initialized.\n  // Chances are we never get here before the flags are initialized since\n  // sbrk is used until the heap is exhausted (before mmap is used).\n  if (FLAGS_malloc_skip_mmap) {\n    return NULL;\n  }\n\n  // Enforce page alignment\n  if (pagesize == 0) pagesize = getpagesize();\n  if (alignment < pagesize) alignment = pagesize;\n  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;\n  if (aligned_size < size) {\n    return NULL;\n  }\n  size = aligned_size;\n\n  // \"actual_size\" indicates that the bytes from the returned pointer\n  // p up to and including (p + actual_size - 1) have been allocated.\n  if (actual_size) {\n    *actual_size = size;\n  }\n\n  // Ask for extra memory if alignment > pagesize\n  size_t extra = 0;\n  if (alignment > pagesize) {\n    extra = alignment - pagesize;\n  }\n\n  // Note: size + extra does not overflow since:\n  //            size + alignment < (1<<NBITS).\n  // and        extra <= alignment\n  // therefore  size + extra < (1<<NBITS)\n  void* result = mmap(NULL, size + extra,\n                      PROT_READ|PROT_WRITE,\n                      MAP_PRIVATE|MAP_ANONYMOUS,\n                      -1, 0);\n  if (result == reinterpret_cast<void*>(MAP_FAILED)) {\n    failed_ = true;\n    return NULL;\n  }\n\n  // Adjust the return memory so it is aligned\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);\n  size_t adjust = 0;\n  if ((ptr & (alignment - 1)) != 0) {\n    adjust = alignment - (ptr & (alignment - 1));\n  }\n\n  // Return the unused memory to the system\n  if (adjust > 0) {\n    munmap(reinterpret_cast<void*>(ptr), adjust);\n  }\n  if (adjust < extra) {\n    munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);\n  }\n\n  ptr += adjust;\n  return reinterpret_cast<void*>(ptr);\n#endif  // HAVE_MMAP\n}\n\nvoid MmapSysAllocator::DumpStats(TCMalloc_Printer* printer) {\n  printer->printf(\"MmapSysAllocator: failed_=%d\\n\", failed_);\n}\n\nvoid* DevMemSysAllocator::Alloc(size_t size, size_t *actual_size,\n                                size_t alignment) {\n#ifndef HAVE_MMAP\n  failed_ = true;\n  return NULL;\n#else\n  static bool initialized = false;\n  static off_t physmem_base;  // next physical memory address to allocate\n  static off_t physmem_limit; // maximum physical address allowed\n  static int physmem_fd;      // file descriptor for /dev/mem\n\n  // Check if we should use /dev/mem allocation.  Note that it may take\n  // a while to get this flag initialized, so meanwhile we fall back to\n  // the next allocator.  (It looks like 7MB gets allocated before\n  // this flag gets initialized -khr.)\n  if (FLAGS_malloc_devmem_start == 0) {\n    // NOTE: not a devmem_failure - we'd like TCMalloc_SystemAlloc to\n    // try us again next time.\n    return NULL;\n  }\n\n  if (!initialized) {\n    physmem_fd = open(\"/dev/mem\", O_RDWR);\n    if (physmem_fd < 0) {\n      failed_ = true;\n      return NULL;\n    }\n    physmem_base = FLAGS_malloc_devmem_start*1024LL*1024LL;\n    physmem_limit = FLAGS_malloc_devmem_limit*1024LL*1024LL;\n    initialized = true;\n  }\n\n  // Enforce page alignment\n  if (pagesize == 0) pagesize = getpagesize();\n  if (alignment < pagesize) alignment = pagesize;\n  size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;\n  if (aligned_size < size) {\n    return NULL;\n  }\n  size = aligned_size;\n\n  // \"actual_size\" indicates that the bytes from the returned pointer\n  // p up to and including (p + actual_size - 1) have been allocated.\n  if (actual_size) {\n    *actual_size = size;\n  }\n\n  // Ask for extra memory if alignment > pagesize\n  size_t extra = 0;\n  if (alignment > pagesize) {\n    extra = alignment - pagesize;\n  }\n\n  // check to see if we have any memory left\n  if (physmem_limit != 0 &&\n      ((size + extra) > (physmem_limit - physmem_base))) {\n    failed_ = true;\n    return NULL;\n  }\n\n  // Note: size + extra does not overflow since:\n  //            size + alignment < (1<<NBITS).\n  // and        extra <= alignment\n  // therefore  size + extra < (1<<NBITS)\n  void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,\n                      MAP_SHARED, physmem_fd, physmem_base);\n  if (result == reinterpret_cast<void*>(MAP_FAILED)) {\n    failed_ = true;\n    return NULL;\n  }\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);\n\n  // Adjust the return memory so it is aligned\n  size_t adjust = 0;\n  if ((ptr & (alignment - 1)) != 0) {\n    adjust = alignment - (ptr & (alignment - 1));\n  }\n\n  // Return the unused virtual memory to the system\n  if (adjust > 0) {\n    munmap(reinterpret_cast<void*>(ptr), adjust);\n  }\n  if (adjust < extra) {\n    munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);\n  }\n\n  ptr += adjust;\n  physmem_base += adjust + size;\n\n  return reinterpret_cast<void*>(ptr);\n#endif  // HAVE_MMAP\n}\n\nvoid DevMemSysAllocator::DumpStats(TCMalloc_Printer* printer) {\n  printer->printf(\"DevMemSysAllocator: failed_=%d\\n\", failed_);\n}\n\nstatic bool system_alloc_inited = false;\nvoid InitSystemAllocators(void) {\n  // This determines the order in which system allocators are called\n  int i = kMaxDynamicAllocators;\n  allocators[i++] = new (devmem_space) DevMemSysAllocator();\n\n  // In 64-bit debug mode, place the mmap allocator first since it\n  // allocates pointers that do not fit in 32 bits and therefore gives\n  // us better testing of code's 64-bit correctness.  It also leads to\n  // less false negatives in heap-checking code.  (Numbers are less\n  // likely to look like pointers and therefore the conservative gc in\n  // the heap-checker is less likely to misinterpret a number as a\n  // pointer).\n  if (kDebugMode && sizeof(void*) > 4) {\n    allocators[i++] = new (mmap_space) MmapSysAllocator();\n    allocators[i++] = new (sbrk_space) SbrkSysAllocator();\n  } else {\n    allocators[i++] = new (sbrk_space) SbrkSysAllocator();\n    allocators[i++] = new (mmap_space) MmapSysAllocator();\n  }\n}\n\nvoid* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,\n                           size_t alignment) {\n  // Discard requests that overflow\n  if (size + alignment < size) return NULL;\n\n  SpinLockHolder lock_holder(&spinlock);\n\n  if (!system_alloc_inited) {\n    InitSystemAllocators();\n    system_alloc_inited = true;\n  }\n\n  // Enforce minimum alignment\n  if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner);\n\n  // Try twice, once avoiding allocators that failed before, and once\n  // more trying all allocators even if they failed before.\n  for (int i = 0; i < 2; i++) {\n    for (int j = 0; j < kMaxAllocators; j++) {\n      SysAllocator *a = allocators[j];\n      if (a == NULL) continue;\n      if (a->usable_ && !a->failed_) {\n        void* result = a->Alloc(size, actual_size, alignment);\n        if (result != NULL) {\n          if (actual_size) {\n            CheckAddressBits<kAddressBits>(\n                reinterpret_cast<uintptr_t>(result) + *actual_size - 1);\n          } else {\n            CheckAddressBits<kAddressBits>(\n                reinterpret_cast<uintptr_t>(result) + size - 1);\n          }\n          return result;\n        }\n      }\n    }\n\n    // nothing worked - reset failed_ flags and try again\n    for (int j = 0; j < kMaxAllocators; j++) {\n      SysAllocator *a = allocators[j];\n      if (a == NULL) continue;\n      a->failed_ = false;\n    }\n  }\n  return NULL;\n}\n\nvoid TCMalloc_SystemRelease(void* start, size_t length) {\n#ifdef MADV_DONTNEED\n  if (FLAGS_malloc_devmem_start) {\n    // It's not safe to use MADV_DONTNEED if we've been mapping\n    // /dev/mem for heap memory\n    return;\n  }\n  if (pagesize == 0) pagesize = getpagesize();\n  const size_t pagemask = pagesize - 1;\n\n  size_t new_start = reinterpret_cast<size_t>(start);\n  size_t end = new_start + length;\n  size_t new_end = end;\n\n  // Round up the starting address and round down the ending address\n  // to be page aligned:\n  new_start = (new_start + pagesize - 1) & ~pagemask;\n  new_end = new_end & ~pagemask;\n\n  ASSERT((new_start & pagemask) == 0);\n  ASSERT((new_end & pagemask) == 0);\n  ASSERT(new_start >= reinterpret_cast<size_t>(start));\n  ASSERT(new_end <= end);\n\n  if (new_end > new_start) {\n    // Note -- ignoring most return codes, because if this fails it\n    // doesn't matter...\n    while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start,\n                   MADV_DONTNEED) == -1 &&\n           errno == EAGAIN) {\n      // NOP\n    }\n  }\n#endif\n}\n\nvoid DumpSystemAllocatorStats(TCMalloc_Printer* printer) {\n  for (int j = 0; j < kMaxAllocators; j++) {\n    SysAllocator *a = allocators[j];\n    if (a == NULL) continue;\n    if (a->usable_) {\n      a->DumpStats(printer);\n    }\n  }\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/system-alloc.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Routine that uses sbrk/mmap to allocate memory from the system.\n// Useful for implementing malloc.\n\n#ifndef TCMALLOC_SYSTEM_ALLOC_H_\n#define TCMALLOC_SYSTEM_ALLOC_H_\n\n#include <config.h>\n#include \"internal_logging.h\"\n\n// REQUIRES: \"alignment\" is a power of two or \"0\" to indicate default alignment\n//\n// Allocate and return \"N\" bytes of zeroed memory.\n//\n// If actual_bytes is NULL then the returned memory is exactly the\n// requested size.  If actual bytes is non-NULL then the allocator\n// may optionally return more bytes than asked for (i.e. return an\n// entire \"huge\" page if a huge page allocator is in use).\n//\n// The returned pointer is a multiple of \"alignment\" if non-zero. The\n// returned pointer will always be aligned suitably for holding a\n// void*, double, or size_t. In addition, if this platform defines\n// CACHELINE_ALIGNED, the return pointer will always be cacheline\n// aligned.\n//\n// Returns NULL when out of memory.\nextern void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes,\n                                  size_t alignment = 0);\n\n// This call is a hint to the operating system that the pages\n// contained in the specified range of memory will not be used for a\n// while, and can be released for use by other processes or the OS.\n// Pages which are released in this way may be destroyed (zeroed) by\n// the OS.  The benefit of this function is that it frees memory for\n// use by the system, the cost is that the pages are faulted back into\n// the address space next time they are touched, which can impact\n// performance.  (Only pages fully covered by the memory region will\n// be released, partial pages will not.)\nextern void TCMalloc_SystemRelease(void* start, size_t length);\n\n// Interface to a pluggable system allocator.\nclass SysAllocator {\n public:\n  SysAllocator() \n    : usable_(true), \n      failed_(false) {\n  };\n  virtual ~SysAllocator() {};\n\n  virtual void* Alloc(size_t size, size_t *actual_size, size_t alignment) = 0;\n\n  // Populate the map with whatever properties the specified allocator finds\n  // useful for debugging (such as number of bytes allocated and whether the\n  // allocator has failed).  The callee is responsible for any necessary\n  // locking (and avoiding deadlock).\n  virtual void DumpStats(TCMalloc_Printer* printer) = 0;\n\n  // So the allocator can be turned off at compile time\n  bool usable_;\n\n  // Did this allocator fail? If so, we don't need to retry more than twice.\n  bool failed_;\n};\n\n// Register a new system allocator. The priority determines the order in\n// which the allocators will be invoked. Allocators with numerically lower\n// priority are tried first. To keep things simple, the priority of various\n// allocators is known at compile time.\n//\n// Valid range of priorities: [0, kMaxDynamicAllocators)\n//\n// Please note that we can't use complex data structures and cause\n// recursive calls to malloc within this function. So all data structures\n// are statically allocated.\n//\n// Returns true on success. Does nothing on failure.\nextern PERFTOOLS_DLL_DECL bool RegisterSystemAllocator(SysAllocator *allocator,\n                                                       int priority);\n\n// Number of SysAllocators known to call RegisterSystemAllocator\nstatic const int kMaxDynamicAllocators = 2;\n\n// Retrieve the current state of various system allocators.\nextern PERFTOOLS_DLL_DECL void DumpSystemAllocatorStats(TCMalloc_Printer* printer);\n\n#endif /* TCMALLOC_SYSTEM_ALLOC_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tcmalloc.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n//\n// A malloc that uses a per-thread cache to satisfy small malloc requests.\n// (The time for malloc/free of a small object drops from 300 ns to 50 ns.)\n//\n// See doc/tcmalloc.html for a high-level\n// description of how this malloc works.\n//\n// SYNCHRONIZATION\n//  1. The thread-specific lists are accessed without acquiring any locks.\n//     This is safe because each such list is only accessed by one thread.\n//  2. We have a lock per central free-list, and hold it while manipulating\n//     the central free list for a particular size.\n//  3. The central page allocator is protected by \"pageheap_lock\".\n//  4. The pagemap (which maps from page-number to descriptor),\n//     can be read without holding any locks, and written while holding\n//     the \"pageheap_lock\".\n//  5. To improve performance, a subset of the information one can get\n//     from the pagemap is cached in a data structure, pagemap_cache_,\n//     that atomically reads and writes its entries.  This cache can be\n//     read and written without locking.\n//\n//     This multi-threaded access to the pagemap is safe for fairly\n//     subtle reasons.  We basically assume that when an object X is\n//     allocated by thread A and deallocated by thread B, there must\n//     have been appropriate synchronization in the handoff of object\n//     X from thread A to thread B.  The same logic applies to pagemap_cache_.\n//\n// THE PAGEID-TO-SIZECLASS CACHE\n// Hot PageID-to-sizeclass mappings are held by pagemap_cache_.  If this cache\n// returns 0 for a particular PageID then that means \"no information,\" not that\n// the sizeclass is 0.  The cache may have stale information for pages that do\n// not hold the beginning of any free()'able object.  Staleness is eliminated\n// in Populate() for pages with sizeclass > 0 objects, and in do_malloc() and\n// do_memalign() for all other relevant pages.\n//\n// PAGEMAP\n// -------\n// Page map contains a mapping from page id to Span.\n//\n// If Span s occupies pages [p..q],\n//      pagemap[p] == s\n//      pagemap[q] == s\n//      pagemap[p+1..q-1] are undefined\n//      pagemap[p-1] and pagemap[q+1] are defined:\n//         NULL if the corresponding page is not yet in the address space.\n//         Otherwise it points to a Span.  This span may be free\n//         or allocated.  If free, it is in one of pageheap's freelist.\n//\n// TODO: Bias reclamation to larger addresses\n// TODO: implement mallinfo/mallopt\n// TODO: Better testing\n//\n// 9/28/2003 (new page-level allocator replaces ptmalloc2):\n// * malloc/free of small objects goes from ~300 ns to ~50 ns.\n// * allocation of a reasonably complicated struct\n//   goes from about 1100 ns to about 300 ns.\n\n#include <config.h>\n#include <new>\n#include <stdio.h>\n#include <stddef.h>\n#if defined HAVE_STDINT_H\n#include <stdint.h>\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>\n#else\n#include <sys/types.h>\n#endif\n#if defined(HAVE_MALLOC_H) && defined(HAVE_STRUCT_MALLINFO)\n#include <malloc.h>                        // for struct mallinfo\n#endif\n#include <string.h>\n#ifdef HAVE_PTHREAD\n#include <pthread.h>\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#include <errno.h>\n#include <stdarg.h>\n#include <algorithm>\n#include <limits>\n#include <google/tcmalloc.h>\n#include \"base/commandlineflags.h\"\n#include \"base/basictypes.h\"               // gets us PRIu64\n#include \"base/sysinfo.h\"\n#include \"base/spinlock.h\"\n#include \"common.h\"\n#include \"malloc_hook-inl.h\"\n#include <google/malloc_hook.h>\n#include <google/malloc_extension.h>\n#include \"central_freelist.h\"\n#include \"internal_logging.h\"\n#include \"linked_list.h\"\n#include \"maybe_threads.h\"\n#include \"page_heap.h\"\n#include \"page_heap_allocator.h\"\n#include \"pagemap.h\"\n#include \"span.h\"\n#include \"static_vars.h\"\n#include \"system-alloc.h\"\n#include \"tcmalloc_guard.h\"\n#include \"thread_cache.h\"\n\n#if (defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)) && !defined(WIN32_OVERRIDE_ALLOCATORS)\n# define WIN32_DO_PATCHING 1\n#endif\n\nusing STL_NAMESPACE::max;\nusing STL_NAMESPACE::numeric_limits;\nusing STL_NAMESPACE::vector;\nusing tcmalloc::AlignmentForSize;\nusing tcmalloc::PageHeap;\nusing tcmalloc::PageHeapAllocator;\nusing tcmalloc::SizeMap;\nusing tcmalloc::Span;\nusing tcmalloc::StackTrace;\nusing tcmalloc::Static;\nusing tcmalloc::ThreadCache;\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    // I guess we're not on a glibc system\n# define __THROW   // __THROW is just an optimization, so ok to make it \"\"\n#endif\n\nDECLARE_int64(tcmalloc_sample_parameter);\nDECLARE_double(tcmalloc_release_rate);\n\n// For windows, the printf we use to report large allocs is\n// potentially dangerous: it could cause a malloc that would cause an\n// infinite loop.  So by default we set the threshold to a huge number\n// on windows, so this bad situation will never trigger.  You can\n// always set TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD manually if you\n// want this functionality.\n#ifdef _WIN32\nconst int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 62;\n#else\nconst int64 kDefaultLargeAllocReportThreshold = static_cast<int64>(1) << 30;\n#endif\nDEFINE_int64(tcmalloc_large_alloc_report_threshold,\n             EnvToInt64(\"TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD\",\n                        kDefaultLargeAllocReportThreshold),\n             \"Allocations larger than this value cause a stack \"\n             \"trace to be dumped to stderr.  The threshold for \"\n             \"dumping stack traces is increased by a factor of 1.125 \"\n             \"every time we print a message so that the threshold \"\n             \"automatically goes up by a factor of ~1000 every 60 \"\n             \"messages.  This bounds the amount of extra logging \"\n             \"generated by this flag.  Default value of this flag \"\n             \"is very large and therefore you should see no extra \"\n             \"logging unless the flag is overridden.  Set to 0 to \"\n             \"disable reporting entirely.\");\n\n\n// We already declared these functions in tcmalloc.h, but we have to\n// declare them again to give them an ATTRIBUTE_SECTION: we want to\n// put all callers of MallocHook::Invoke* in this module into\n// ATTRIBUTE_SECTION(google_malloc) section, so that\n// MallocHook::GetCallerStackTrace can function accurately.\n#ifndef _WIN32   // windows doesn't have attribute_section, so don't bother\nextern \"C\" {\n  void* tc_malloc(size_t size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void tc_free(void* ptr) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void* tc_realloc(void* ptr, size_t size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void* tc_calloc(size_t nmemb, size_t size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void tc_cfree(void* ptr) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n\n  void* tc_memalign(size_t __alignment, size_t __size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  int tc_posix_memalign(void** ptr, size_t align, size_t size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void* tc_valloc(size_t __size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void* tc_pvalloc(size_t __size) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n\n  void tc_malloc_stats(void) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  int tc_mallopt(int cmd, int value) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n#ifdef HAVE_STRUCT_MALLINFO\n  struct mallinfo tc_mallinfo(void) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n#endif\n\n  void* tc_new(size_t size)\n      ATTRIBUTE_SECTION(google_malloc);\n  void tc_delete(void* p) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void* tc_newarray(size_t size)\n      ATTRIBUTE_SECTION(google_malloc);\n  void tc_deletearray(void* p) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n\n  // And the nothrow variants of these:\n  void* tc_new_nothrow(size_t size, const std::nothrow_t&) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void* tc_newarray_nothrow(size_t size, const std::nothrow_t&) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  // Surprisingly, standard C++ library implementations use a\n  // nothrow-delete internally.  See, eg:\n  // http://www.dinkumware.com/manuals/?manual=compleat&page=new.html\n  void tc_delete_nothrow(void* ptr, const std::nothrow_t&) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n  void tc_deletearray_nothrow(void* ptr, const std::nothrow_t&) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n\n  // Some non-standard extensions that we support.\n\n  // This is equivalent to\n  //    OS X: malloc_size()\n  //    glibc: malloc_usable_size()\n  //    Windows: _msize()\n  size_t tc_malloc_size(void* p) __THROW\n      ATTRIBUTE_SECTION(google_malloc);\n}  // extern \"C\"\n#endif  // #ifndef _WIN32\n\n// Override the libc functions to prefer our own instead.  This comes\n// first so code in tcmalloc.cc can use the overridden versions.  One\n// exception: in windows, by default, we patch our code into these\n// functions (via src/windows/patch_function.cc) rather than override\n// them.  In that case, we don't want to do this overriding here.\n#if !defined(WIN32_DO_PATCHING) && !defined(TCMALLOC_FOR_DEBUGALLOCATION)\n\n#if defined(__GNUC__) && !defined(__MACH__)\n  // Potentially faster variants that use the gcc alias extension.\n  // FreeBSD does support aliases, but apparently not correctly. :-(\n  // NOTE: we make many of these symbols weak, but do so in the makefile\n  //       (via objcopy -W) and not here.  That ends up being more portable.\n# define ALIAS(x) __attribute__ ((alias (x)))\nvoid* operator new(size_t size) throw (std::bad_alloc) ALIAS(\"tc_new\");\nvoid operator delete(void* p) __THROW            ALIAS(\"tc_delete\");\nvoid* operator new[](size_t size) throw (std::bad_alloc) ALIAS(\"tc_newarray\");\nvoid operator delete[](void* p) __THROW          ALIAS(\"tc_deletearray\");\nvoid* operator new(size_t size, const std::nothrow_t&) __THROW\n                                                 ALIAS(\"tc_new_nothrow\");\nvoid* operator new[](size_t size, const std::nothrow_t&) __THROW\n                                                 ALIAS(\"tc_newarray_nothrow\");\nvoid operator delete(void* size, const std::nothrow_t&) __THROW\n                                                 ALIAS(\"tc_delete_nothrow\");\nvoid operator delete[](void* size, const std::nothrow_t&) __THROW\n                                                ALIAS(\"tc_deletearray_nothrow\");\nextern \"C\" {\n  void* malloc(size_t size) __THROW              ALIAS(\"tc_malloc\");\n  void  free(void* ptr) __THROW                  ALIAS(\"tc_free\");\n  void* realloc(void* ptr, size_t size) __THROW  ALIAS(\"tc_realloc\");\n  void* calloc(size_t n, size_t size) __THROW    ALIAS(\"tc_calloc\");\n  void  cfree(void* ptr) __THROW                 ALIAS(\"tc_cfree\");\n  void* memalign(size_t align, size_t s) __THROW ALIAS(\"tc_memalign\");\n  void* valloc(size_t size) __THROW              ALIAS(\"tc_valloc\");\n  void* pvalloc(size_t size) __THROW             ALIAS(\"tc_pvalloc\");\n  int posix_memalign(void** r, size_t a, size_t s) __THROW\n      ALIAS(\"tc_posix_memalign\");\n  void malloc_stats(void) __THROW                ALIAS(\"tc_malloc_stats\");\n  int mallopt(int cmd, int value) __THROW        ALIAS(\"tc_mallopt\");\n#ifdef HAVE_STRUCT_MALLINFO\n  struct mallinfo mallinfo(void) __THROW         ALIAS(\"tc_mallinfo\");\n#endif\n  size_t malloc_size(void* p) __THROW            ALIAS(\"tc_malloc_size\");\n  size_t malloc_usable_size(void* p) __THROW     ALIAS(\"tc_malloc_size\");\n}   // extern \"C\"\n#else  // #if defined(__GNUC__) && !defined(__MACH__)\n// Portable wrappers\nvoid* operator new(size_t size)                  { return tc_new(size);       }\nvoid operator delete(void* p) __THROW            { tc_delete(p);              }\nvoid* operator new[](size_t size)                { return tc_newarray(size);  }\nvoid operator delete[](void* p) __THROW          { tc_deletearray(p);         }\nvoid* operator new(size_t size, const std::nothrow_t& nt) __THROW {\n  return tc_new_nothrow(size, nt);\n}\nvoid* operator new[](size_t size, const std::nothrow_t& nt) __THROW {\n  return tc_newarray_nothrow(size, nt);\n}\nvoid operator delete(void* ptr, const std::nothrow_t& nt) __THROW {\n  return tc_delete_nothrow(ptr, nt);\n}\nvoid operator delete[](void* ptr, const std::nothrow_t& nt) __THROW {\n  return tc_deletearray_nothrow(ptr, nt);\n}\nextern \"C\" {\n  void* malloc(size_t s) __THROW                 { return tc_malloc(s);       }\n  void  free(void* p) __THROW                    { tc_free(p);                }\n  void* realloc(void* p, size_t s) __THROW       { return tc_realloc(p, s);   }\n  void* calloc(size_t n, size_t s) __THROW       { return tc_calloc(n, s);    }\n  void  cfree(void* p) __THROW                   { tc_cfree(p);               }\n  void* memalign(size_t a, size_t s) __THROW     { return tc_memalign(a, s);  }\n  void* valloc(size_t s) __THROW                 { return tc_valloc(s);       }\n  void* pvalloc(size_t s) __THROW                { return tc_pvalloc(s);      }\n  int posix_memalign(void** r, size_t a, size_t s) __THROW {\n    return tc_posix_memalign(r, a, s);\n  }\n  void malloc_stats(void) __THROW                { tc_malloc_stats();         }\n  int mallopt(int cmd, int v) __THROW            { return tc_mallopt(cmd, v); }\n#ifdef HAVE_STRUCT_MALLINFO\n  struct mallinfo mallinfo(void) __THROW         { return tc_mallinfo();      }\n#endif\n  size_t malloc_size(void* p) __THROW            { return tc_malloc_size(p); }\n  size_t malloc_usable_size(void* p) __THROW     { return tc_malloc_size(p); }\n}  // extern \"C\"\n#endif  // #if defined(__GNUC__)\n\n// Some library routines on RedHat 9 allocate memory using malloc()\n// and free it using __libc_free() (or vice-versa).  Since we provide\n// our own implementations of malloc/free, we need to make sure that\n// the __libc_XXX variants (defined as part of glibc) also point to\n// the same implementations.\n#ifdef __GLIBC__       // only glibc defines __libc_*\nextern \"C\" {\n#ifdef ALIAS\n  void* __libc_malloc(size_t size)               ALIAS(\"tc_malloc\");\n  void  __libc_free(void* ptr)                   ALIAS(\"tc_free\");\n  void* __libc_realloc(void* ptr, size_t size)   ALIAS(\"tc_realloc\");\n  void* __libc_calloc(size_t n, size_t size)     ALIAS(\"tc_calloc\");\n  void  __libc_cfree(void* ptr)                  ALIAS(\"tc_cfree\");\n  void* __libc_memalign(size_t align, size_t s)  ALIAS(\"tc_memalign\");\n  void* __libc_valloc(size_t size)               ALIAS(\"tc_valloc\");\n  void* __libc_pvalloc(size_t size)              ALIAS(\"tc_pvalloc\");\n  int __posix_memalign(void** r, size_t a, size_t s) ALIAS(\"tc_posix_memalign\");\n#else  // #ifdef ALIAS\n  void* __libc_malloc(size_t size)               { return malloc(size);       }\n  void  __libc_free(void* ptr)                   { free(ptr);                 }\n  void* __libc_realloc(void* ptr, size_t size)   { return realloc(ptr, size); }\n  void* __libc_calloc(size_t n, size_t size)     { return calloc(n, size);    }\n  void  __libc_cfree(void* ptr)                  { cfree(ptr);                }\n  void* __libc_memalign(size_t align, size_t s)  { return memalign(align, s); }\n  void* __libc_valloc(size_t size)               { return valloc(size);       }\n  void* __libc_pvalloc(size_t size)              { return pvalloc(size);      }\n  int __posix_memalign(void** r, size_t a, size_t s) {\n    return posix_memalign(r, a, s);\n  }\n#endif  // #ifdef ALIAS\n}   // extern \"C\"\n#endif  // ifdef __GLIBC__\n\n#undef ALIAS\n\n#endif  // #ifndef(WIN32_DO_PATCHING) && ndef(TCMALLOC_FOR_DEBUGALLOCATION)\n\n\n// ----------------------- IMPLEMENTATION -------------------------------\n\nstatic int tc_new_mode = 0;  // See tc_set_new_mode().\n\n// Routines such as free() and realloc() catch some erroneous pointers\n// passed to them, and invoke the below when they do.  (An erroneous pointer\n// won't be caught if it's within a valid span or a stale span for which\n// the pagemap cache has a non-zero sizeclass.) This is a cheap (source-editing\n// required) kind of exception handling for these routines.\nnamespace {\nvoid InvalidFree(void* ptr) {\n  CRASH(\"Attempt to free invalid pointer: %p\\n\", ptr);\n}\n\nsize_t InvalidGetSizeForRealloc(void* old_ptr) {\n  CRASH(\"Attempt to realloc invalid pointer: %p\\n\", old_ptr);\n  return 0;\n}\n\nsize_t InvalidGetAllocatedSize(void* ptr) {\n  CRASH(\"Attempt to get the size of an invalid pointer: %p\\n\", ptr);\n  return 0;\n}\n}  // unnamed namespace\n\n// Extract interesting stats\nstruct TCMallocStats {\n  uint64_t thread_bytes;      // Bytes in thread caches\n  uint64_t central_bytes;     // Bytes in central cache\n  uint64_t transfer_bytes;    // Bytes in central transfer cache\n  uint64_t metadata_bytes;    // Bytes alloced for metadata\n  PageHeap::Stats pageheap;   // Stats from page heap\n};\n\n// Get stats into \"r\".  Also get per-size-class counts if class_count != NULL\nstatic void ExtractStats(TCMallocStats* r, uint64_t* class_count) {\n  r->central_bytes = 0;\n  r->transfer_bytes = 0;\n  for (int cl = 0; cl < kNumClasses; ++cl) {\n    const int length = Static::central_cache()[cl].length();\n    const int tc_length = Static::central_cache()[cl].tc_length();\n    const size_t size = static_cast<uint64_t>(\n        Static::sizemap()->ByteSizeForClass(cl));\n    r->central_bytes += (size * length);\n    r->transfer_bytes += (size * tc_length);\n    if (class_count) class_count[cl] = length + tc_length;\n  }\n\n  // Add stats from per-thread heaps\n  r->thread_bytes = 0;\n  { // scope\n    SpinLockHolder h(Static::pageheap_lock());\n    ThreadCache::GetThreadStats(&r->thread_bytes, class_count);\n    r->metadata_bytes = tcmalloc::metadata_system_bytes();\n    r->pageheap = Static::pageheap()->stats();\n  }\n}\n\n// WRITE stats to \"out\"\nstatic void DumpStats(TCMalloc_Printer* out, int level) {\n  TCMallocStats stats;\n  uint64_t class_count[kNumClasses];\n  ExtractStats(&stats, (level >= 2 ? class_count : NULL));\n\n  static const double MB = 1048576.0;\n\n  const uint64_t virtual_memory_used = (stats.pageheap.system_bytes\n                                        + stats.metadata_bytes);\n  const uint64_t physical_memory_used = (virtual_memory_used\n                                         - stats.pageheap.unmapped_bytes);\n  const uint64_t bytes_in_use_by_app = (physical_memory_used\n                                        - stats.metadata_bytes\n                                        - stats.pageheap.free_bytes\n                                        - stats.central_bytes\n                                        - stats.transfer_bytes\n                                        - stats.thread_bytes);\n\n  out->printf(\n      \"------------------------------------------------\\n\"\n      \"MALLOC:   %12\" PRIu64 \" (%7.1f MB) Bytes in use by application\\n\"\n      \"MALLOC: + %12\" PRIu64 \" (%7.1f MB) Bytes in page heap freelist\\n\"\n      \"MALLOC: + %12\" PRIu64 \" (%7.1f MB) Bytes in central cache freelist\\n\"\n      \"MALLOC: + %12\" PRIu64 \" (%7.1f MB) Bytes in transfer cache freelist\\n\"\n      \"MALLOC: + %12\" PRIu64 \" (%7.1f MB) Bytes in thread cache freelists\\n\"\n      \"MALLOC: + %12\" PRIu64 \" (%7.1f MB) Bytes in malloc metadata\\n\"\n      \"MALLOC:   ------------\\n\"\n      \"MALLOC: = %12\" PRIu64 \" (%7.1f MB) Actual memory used (physical + swap)\\n\"\n      \"MALLOC: + %12\" PRIu64 \" (%7.1f MB) Bytes released to OS (aka unmapped)\\n\"\n      \"MALLOC:   ------------\\n\"\n      \"MALLOC: = %12\" PRIu64 \" (%7.1f MB) Virtual address space used\\n\"\n      \"MALLOC:\\n\"\n      \"MALLOC:   %12\" PRIu64 \"              Spans in use\\n\"\n      \"MALLOC:   %12\" PRIu64 \"              Thread heaps in use\\n\"\n      \"MALLOC:   %12\" PRIu64 \"              Tcmalloc page size\\n\"\n      \"------------------------------------------------\\n\"\n      \"Call ReleaseFreeMemory() to release freelist memory to the OS\"\n      \" (via madvise()).\\n\"\n      \"Bytes released to the OS take up virtual address space\"\n      \" but no physical memory.\\n\",\n      bytes_in_use_by_app, bytes_in_use_by_app / MB,\n      stats.pageheap.free_bytes, stats.pageheap.free_bytes / MB,\n      stats.central_bytes, stats.central_bytes / MB,\n      stats.transfer_bytes, stats.transfer_bytes / MB,\n      stats.thread_bytes, stats.thread_bytes / MB,\n      stats.metadata_bytes, stats.metadata_bytes / MB,\n      physical_memory_used, physical_memory_used / MB,\n      stats.pageheap.unmapped_bytes, stats.pageheap.unmapped_bytes / MB,\n      virtual_memory_used, virtual_memory_used / MB,\n      uint64_t(Static::span_allocator()->inuse()),\n      uint64_t(ThreadCache::HeapsInUse()),\n      uint64_t(kPageSize));\n\n  if (level >= 2) {\n    out->printf(\"------------------------------------------------\\n\");\n    out->printf(\"Size class breakdown\\n\");\n    out->printf(\"------------------------------------------------\\n\");\n    uint64_t cumulative = 0;\n    for (int cl = 0; cl < kNumClasses; ++cl) {\n      if (class_count[cl] > 0) {\n        uint64_t class_bytes =\n            class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);\n        cumulative += class_bytes;\n        out->printf(\"class %3d [ %8\" PRIuS \" bytes ] : \"\n                \"%8\" PRIu64 \" objs; %5.1f MB; %5.1f cum MB\\n\",\n                cl, Static::sizemap()->ByteSizeForClass(cl),\n                class_count[cl],\n                class_bytes / MB,\n                cumulative / MB);\n      }\n    }\n\n    SpinLockHolder h(Static::pageheap_lock());\n    Static::pageheap()->Dump(out);\n\n    out->printf(\"------------------------------------------------\\n\");\n    DumpSystemAllocatorStats(out);\n  }\n}\n\nstatic void PrintStats(int level) {\n  const int kBufferSize = 16 << 10;\n  char* buffer = new char[kBufferSize];\n  TCMalloc_Printer printer(buffer, kBufferSize);\n  DumpStats(&printer, level);\n  write(STDERR_FILENO, buffer, strlen(buffer));\n  delete[] buffer;\n}\n\nstatic void** DumpHeapGrowthStackTraces() {\n  // Count how much space we need\n  int needed_slots = 0;\n  {\n    SpinLockHolder h(Static::pageheap_lock());\n    for (StackTrace* t = Static::growth_stacks();\n         t != NULL;\n         t = reinterpret_cast<StackTrace*>(\n             t->stack[tcmalloc::kMaxStackDepth-1])) {\n      needed_slots += 3 + t->depth;\n    }\n    needed_slots += 100;            // Slop in case list grows\n    needed_slots += needed_slots/8; // An extra 12.5% slop\n  }\n\n  void** result = new void*[needed_slots];\n  if (result == NULL) {\n    MESSAGE(\"tcmalloc: allocation failed for stack trace slots\",\n            needed_slots * sizeof(*result));\n    return NULL;\n  }\n\n  SpinLockHolder h(Static::pageheap_lock());\n  int used_slots = 0;\n  for (StackTrace* t = Static::growth_stacks();\n       t != NULL;\n       t = reinterpret_cast<StackTrace*>(\n           t->stack[tcmalloc::kMaxStackDepth-1])) {\n    ASSERT(used_slots < needed_slots);  // Need to leave room for terminator\n    if (used_slots + 3 + t->depth >= needed_slots) {\n      // No more room\n      break;\n    }\n\n    result[used_slots+0] = reinterpret_cast<void*>(static_cast<uintptr_t>(1));\n    result[used_slots+1] = reinterpret_cast<void*>(t->size);\n    result[used_slots+2] = reinterpret_cast<void*>(t->depth);\n    for (int d = 0; d < t->depth; d++) {\n      result[used_slots+3+d] = t->stack[d];\n    }\n    used_slots += 3 + t->depth;\n  }\n  result[used_slots] = reinterpret_cast<void*>(static_cast<uintptr_t>(0));\n  return result;\n}\n\nstatic void IterateOverRanges(void* arg, MallocExtension::RangeFunction func) {\n  PageID page = 1;  // Some code may assume that page==0 is never used\n  bool done = false;\n  while (!done) {\n    // Accumulate a small number of ranges in a local buffer\n    static const int kNumRanges = 16;\n    static base::MallocRange ranges[kNumRanges];\n    int n = 0;\n    {\n      SpinLockHolder h(Static::pageheap_lock());\n      while (n < kNumRanges) {\n        if (!Static::pageheap()->GetNextRange(page, &ranges[n])) {\n          done = true;\n          break;\n        } else {\n          uintptr_t limit = ranges[n].address + ranges[n].length;\n          page = (limit + kPageSize - 1) >> kPageShift;\n          n++;\n        }\n      }\n    }\n\n    for (int i = 0; i < n; i++) {\n      (*func)(arg, &ranges[i]);\n    }\n  }\n}\n\n// TCMalloc's support for extra malloc interfaces\nclass TCMallocImplementation : public MallocExtension {\n private:\n  // ReleaseToSystem() might release more than the requested bytes because\n  // the page heap releases at the span granularity, and spans are of wildly\n  // different sizes.  This member keeps track of the extra bytes bytes\n  // released so that the app can periodically call ReleaseToSystem() to\n  // release memory at a constant rate.\n  // NOTE: Protected by Static::pageheap_lock().\n  size_t extra_bytes_released_;\n\n public:\n  TCMallocImplementation()\n      : extra_bytes_released_(0) {\n  }\n\n  virtual void GetStats(char* buffer, int buffer_length) {\n    ASSERT(buffer_length > 0);\n    TCMalloc_Printer printer(buffer, buffer_length);\n\n    // Print level one stats unless lots of space is available\n    if (buffer_length < 10000) {\n      DumpStats(&printer, 1);\n    } else {\n      DumpStats(&printer, 2);\n    }\n  }\n\n  // We may print an extra, tcmalloc-specific warning message here.\n  virtual void GetHeapSample(MallocExtensionWriter* writer) {\n    if (FLAGS_tcmalloc_sample_parameter == 0) {\n      const char* const kWarningMsg =\n          \"%warn\\n\"\n          \"%warn This heap profile does not have any data in it, because\\n\"\n          \"%warn the application was run with heap sampling turned off.\\n\"\n          \"%warn To get useful data from GetHeapSample(), you must\\n\"\n          \"%warn set the environment variable TCMALLOC_SAMPLE_PARAMETER to\\n\"\n          \"%warn a positive sampling period, such as 524288.\\n\"\n          \"%warn\\n\";\n      writer->append(kWarningMsg, strlen(kWarningMsg));\n    }\n    MallocExtension::GetHeapSample(writer);\n  }\n\n  virtual void** ReadStackTraces(int* sample_period) {\n    tcmalloc::StackTraceTable table;\n    {\n      SpinLockHolder h(Static::pageheap_lock());\n      Span* sampled = Static::sampled_objects();\n      for (Span* s = sampled->next; s != sampled; s = s->next) {\n        table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects));\n      }\n    }\n    *sample_period = ThreadCache::GetCache()->GetSamplePeriod();\n    return table.ReadStackTracesAndClear(); // grabs and releases pageheap_lock\n  }\n\n  virtual void** ReadHeapGrowthStackTraces() {\n    return DumpHeapGrowthStackTraces();\n  }\n\n  virtual void Ranges(void* arg, RangeFunction func) {\n    IterateOverRanges(arg, func);\n  }\n\n  virtual bool GetNumericProperty(const char* name, size_t* value) {\n    ASSERT(name != NULL);\n\n    if (strcmp(name, \"generic.current_allocated_bytes\") == 0) {\n      TCMallocStats stats;\n      ExtractStats(&stats, NULL);\n      *value = stats.pageheap.system_bytes\n               - stats.thread_bytes\n               - stats.central_bytes\n               - stats.transfer_bytes\n               - stats.pageheap.free_bytes\n               - stats.pageheap.unmapped_bytes;\n      return true;\n    }\n\n    if (strcmp(name, \"generic.heap_size\") == 0) {\n      TCMallocStats stats;\n      ExtractStats(&stats, NULL);\n      *value = stats.pageheap.system_bytes;\n      return true;\n    }\n\n    if (strcmp(name, \"tcmalloc.slack_bytes\") == 0) {\n      // Kept for backwards compatibility.  Now defined externally as:\n      //    pageheap_free_bytes + pageheap_unmapped_bytes.\n      SpinLockHolder l(Static::pageheap_lock());\n      PageHeap::Stats stats = Static::pageheap()->stats();\n      *value = stats.free_bytes + stats.unmapped_bytes;\n      return true;\n    }\n\n    if (strcmp(name, \"tcmalloc.pageheap_free_bytes\") == 0) {\n      SpinLockHolder l(Static::pageheap_lock());\n      *value = Static::pageheap()->stats().free_bytes;\n      return true;\n    }\n\n    if (strcmp(name, \"tcmalloc.pageheap_unmapped_bytes\") == 0) {\n      SpinLockHolder l(Static::pageheap_lock());\n      *value = Static::pageheap()->stats().unmapped_bytes;\n      return true;\n    }\n\n    if (strcmp(name, \"tcmalloc.max_total_thread_cache_bytes\") == 0) {\n      SpinLockHolder l(Static::pageheap_lock());\n      *value = ThreadCache::overall_thread_cache_size();\n      return true;\n    }\n\n    if (strcmp(name, \"tcmalloc.current_total_thread_cache_bytes\") == 0) {\n      TCMallocStats stats;\n      ExtractStats(&stats, NULL);\n      *value = stats.thread_bytes;\n      return true;\n    }\n\n    return false;\n  }\n\n  virtual bool SetNumericProperty(const char* name, size_t value) {\n    ASSERT(name != NULL);\n\n    if (strcmp(name, \"tcmalloc.max_total_thread_cache_bytes\") == 0) {\n      SpinLockHolder l(Static::pageheap_lock());\n      ThreadCache::set_overall_thread_cache_size(value);\n      return true;\n    }\n\n    return false;\n  }\n\n  virtual void MarkThreadIdle() {\n    ThreadCache::BecomeIdle();\n  }\n\n  virtual void MarkThreadBusy();  // Implemented below\n\n  virtual void ReleaseToSystem(size_t num_bytes) {\n    SpinLockHolder h(Static::pageheap_lock());\n    if (num_bytes <= extra_bytes_released_) {\n      // We released too much on a prior call, so don't release any\n      // more this time.\n      extra_bytes_released_ = extra_bytes_released_ - num_bytes;\n      return;\n    }\n    num_bytes = num_bytes - extra_bytes_released_;\n    // num_bytes might be less than one page.  If we pass zero to\n    // ReleaseAtLeastNPages, it won't do anything, so we release a whole\n    // page now and let extra_bytes_released_ smooth it out over time.\n    Length num_pages = max<Length>(num_bytes >> kPageShift, 1);\n    size_t bytes_released = Static::pageheap()->ReleaseAtLeastNPages(\n        num_pages) << kPageShift;\n    if (bytes_released > num_bytes) {\n      extra_bytes_released_ = bytes_released - num_bytes;\n    } else {\n      // The PageHeap wasn't able to release num_bytes.  Don't try to\n      // compensate with a big release next time.  Specifically,\n      // ReleaseFreeMemory() calls ReleaseToSystem(LONG_MAX).\n      extra_bytes_released_ = 0;\n    }\n  }\n\n  virtual void SetMemoryReleaseRate(double rate) {\n    FLAGS_tcmalloc_release_rate = rate;\n  }\n\n  virtual double GetMemoryReleaseRate() {\n    return FLAGS_tcmalloc_release_rate;\n  }\n  virtual size_t GetEstimatedAllocatedSize(size_t size) {\n    if (size <= kMaxSize) {\n      const size_t cl = Static::sizemap()->SizeClass(size);\n      const size_t alloc_size = Static::sizemap()->ByteSizeForClass(cl);\n      return alloc_size;\n    } else {\n      return tcmalloc::pages(size) << kPageShift;\n    }\n  }\n\n  // This just calls GetSizeWithCallback, but because that's in an\n  // unnamed namespace, we need to move the definition below it in the\n  // file.\n  virtual size_t GetAllocatedSize(void* ptr);\n\n  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {\n    static const char* kCentralCacheType = \"tcmalloc.central\";\n    static const char* kTransferCacheType = \"tcmalloc.transfer\";\n    static const char* kThreadCacheType = \"tcmalloc.thread\";\n    static const char* kPageHeapType = \"tcmalloc.page\";\n    static const char* kPageHeapUnmappedType = \"tcmalloc.page_unmapped\";\n    static const char* kLargeSpanType = \"tcmalloc.large\";\n    static const char* kLargeUnmappedSpanType = \"tcmalloc.large_unmapped\";\n\n    v->clear();\n\n    // central class information\n    int64 prev_class_size = 0;\n    for (int cl = 1; cl < kNumClasses; ++cl) {\n      size_t class_size = Static::sizemap()->ByteSizeForClass(cl);\n      MallocExtension::FreeListInfo i;\n      i.min_object_size = prev_class_size + 1;\n      i.max_object_size = class_size;\n      i.total_bytes_free =\n          Static::central_cache()[cl].length() * class_size;\n      i.type = kCentralCacheType;\n      v->push_back(i);\n\n      // transfer cache\n      i.total_bytes_free =\n          Static::central_cache()[cl].tc_length() * class_size;\n      i.type = kTransferCacheType;\n      v->push_back(i);\n\n      prev_class_size = Static::sizemap()->ByteSizeForClass(cl);\n    }\n\n    // Add stats from per-thread heaps\n    uint64_t class_count[kNumClasses];\n    memset(class_count, 0, sizeof(class_count));\n    {\n      SpinLockHolder h(Static::pageheap_lock());\n      uint64_t thread_bytes = 0;\n      ThreadCache::GetThreadStats(&thread_bytes, class_count);\n    }\n\n    prev_class_size = 0;\n    for (int cl = 1; cl < kNumClasses; ++cl) {\n      MallocExtension::FreeListInfo i;\n      i.min_object_size = prev_class_size + 1;\n      i.max_object_size = Static::sizemap()->ByteSizeForClass(cl);\n      i.total_bytes_free =\n          class_count[cl] * Static::sizemap()->ByteSizeForClass(cl);\n      i.type = kThreadCacheType;\n      v->push_back(i);\n    }\n\n    // append page heap info\n    int64 page_count_normal[kMaxPages];\n    int64 page_count_returned[kMaxPages];\n    int64 span_count_normal;\n    int64 span_count_returned;\n    {\n      SpinLockHolder h(Static::pageheap_lock());\n      Static::pageheap()->GetClassSizes(page_count_normal,\n                                        page_count_returned,\n                                        &span_count_normal,\n                                        &span_count_returned);\n    }\n\n    // spans: mapped\n    MallocExtension::FreeListInfo span_info;\n    span_info.type = kLargeSpanType;\n    span_info.max_object_size = (numeric_limits<size_t>::max)();\n    span_info.min_object_size = kMaxPages << kPageShift;\n    span_info.total_bytes_free = span_count_normal << kPageShift;\n    v->push_back(span_info);\n\n    // spans: unmapped\n    span_info.type = kLargeUnmappedSpanType;\n    span_info.total_bytes_free = span_count_returned << kPageShift;\n    v->push_back(span_info);\n\n    for (int s = 1; s < kMaxPages; s++) {\n      MallocExtension::FreeListInfo i;\n      i.max_object_size = (s << kPageShift);\n      i.min_object_size = ((s - 1) << kPageShift);\n\n      i.type = kPageHeapType;\n      i.total_bytes_free = (s << kPageShift) * page_count_normal[s];\n      v->push_back(i);\n\n      i.type = kPageHeapUnmappedType;\n      i.total_bytes_free = (s << kPageShift) * page_count_returned[s];\n      v->push_back(i);\n    }\n  }\n};\n\n// The constructor allocates an object to ensure that initialization\n// runs before main(), and therefore we do not have a chance to become\n// multi-threaded before initialization.  We also create the TSD key\n// here.  Presumably by the time this constructor runs, glibc is in\n// good enough shape to handle pthread_key_create().\n//\n// The constructor also takes the opportunity to tell STL to use\n// tcmalloc.  We want to do this early, before construct time, so\n// all user STL allocations go through tcmalloc (which works really\n// well for STL).\n//\n// The destructor prints stats when the program exits.\nstatic int tcmallocguard_refcount = 0;  // no lock needed: runs before main()\nTCMallocGuard::TCMallocGuard() {\n  if (tcmallocguard_refcount++ == 0) {\n#ifdef HAVE_TLS    // this is true if the cc/ld/libc combo support TLS\n    // Check whether the kernel also supports TLS (needs to happen at runtime)\n    tcmalloc::CheckIfKernelSupportsTLS();\n#endif\n#ifdef WIN32_DO_PATCHING\n    // patch the windows VirtualAlloc, etc.\n    PatchWindowsFunctions();    // defined in windows/patch_functions.cc\n#endif\n    tc_free(tc_malloc(1));\n    ThreadCache::InitTSD();\n    tc_free(tc_malloc(1));\n    // Either we, or debugallocation.cc, or valgrind will control memory\n    // management.  We register our extension if we're the winner.\n#ifdef TCMALLOC_FOR_DEBUGALLOCATION\n    // Let debugallocation register its extension.\n#else\n    if (RunningOnValgrind()) {\n      // Let Valgrind uses its own malloc (so don't register our extension).\n    } else {\n      MallocExtension::Register(new TCMallocImplementation);\n    }\n#endif\n  }\n}\n\nTCMallocGuard::~TCMallocGuard() {\n  if (--tcmallocguard_refcount == 0) {\n    const char* env = getenv(\"MALLOCSTATS\");\n    if (env != NULL) {\n      int level = atoi(env);\n      if (level < 1) level = 1;\n      PrintStats(level);\n    }\n  }\n}\n#ifndef WIN32_OVERRIDE_ALLOCATORS\nstatic TCMallocGuard module_enter_exit_hook;\n#endif\n\n//-------------------------------------------------------------------\n// Helpers for the exported routines below\n//-------------------------------------------------------------------\n\nstatic inline bool CheckCachedSizeClass(void *ptr) {\n  PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;\n  size_t cached_value = Static::pageheap()->GetSizeClassIfCached(p);\n  return cached_value == 0 ||\n      cached_value == Static::pageheap()->GetDescriptor(p)->sizeclass;\n}\n\nstatic inline void* CheckedMallocResult(void *result) {\n  ASSERT(result == NULL || CheckCachedSizeClass(result));\n  return result;\n}\n\nstatic inline void* SpanToMallocResult(Span *span) {\n  Static::pageheap()->CacheSizeClass(span->start, 0);\n  return\n      CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));\n}\n\nstatic void* DoSampledAllocation(size_t size) {\n  // Grab the stack trace outside the heap lock\n  StackTrace tmp;\n  tmp.depth = GetStackTrace(tmp.stack, tcmalloc::kMaxStackDepth, 1);\n  tmp.size = size;\n\n  SpinLockHolder h(Static::pageheap_lock());\n  // Allocate span\n  Span *span = Static::pageheap()->New(tcmalloc::pages(size == 0 ? 1 : size));\n  if (span == NULL) {\n    return NULL;\n  }\n\n  // Allocate stack trace\n  StackTrace *stack = Static::stacktrace_allocator()->New();\n  if (stack == NULL) {\n    // Sampling failed because of lack of memory\n    return span;\n  }\n\n  *stack = tmp;\n  span->sample = 1;\n  span->objects = stack;\n  tcmalloc::DLL_Prepend(Static::sampled_objects(), span);\n\n  return SpanToMallocResult(span);\n}\n\nnamespace {\n\n// Copy of FLAGS_tcmalloc_large_alloc_report_threshold with\n// automatic increases factored in.\nstatic int64_t large_alloc_threshold =\n  (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold\n   ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);\n\nstatic void ReportLargeAlloc(Length num_pages, void* result) {\n  StackTrace stack;\n  stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);\n\n  static const int N = 1000;\n  char buffer[N];\n  TCMalloc_Printer printer(buffer, N);\n  printer.printf(\"tcmalloc: large alloc %llu bytes == %p @ \",\n                 static_cast<unsigned long long>(num_pages) << kPageShift,\n                 result);\n  for (int i = 0; i < stack.depth; i++) {\n    printer.printf(\" %p\", stack.stack[i]);\n  }\n  printer.printf(\"\\n\");\n  write(STDERR_FILENO, buffer, strlen(buffer));\n}\n\ninline void* cpp_alloc(size_t size, bool nothrow);\ninline void* do_malloc(size_t size);\n\n// TODO(willchan): Investigate whether or not lining this much is harmful to\n// performance.\n// This is equivalent to do_malloc() except when tc_new_mode is set to true.\n// Otherwise, it will run the std::new_handler if set.\ninline void* do_malloc_or_cpp_alloc(size_t size) {\n  return tc_new_mode ? cpp_alloc(size, true) : do_malloc(size);\n}\n\nvoid* cpp_memalign(size_t align, size_t size);\nvoid* do_memalign(size_t align, size_t size);\n\ninline void* do_memalign_or_cpp_memalign(size_t align, size_t size) {\n  return tc_new_mode ? cpp_memalign(align, size) : do_memalign(align, size);\n}\n\n// Must be called with the page lock held.\ninline bool should_report_large(Length num_pages) {\n  const int64 threshold = large_alloc_threshold;\n  if (threshold > 0 && num_pages >= (threshold >> kPageShift)) {\n    // Increase the threshold by 1/8 every time we generate a report.\n    // We cap the threshold at 8GB to avoid overflow problems.\n    large_alloc_threshold = (threshold + threshold/8 < 8ll<<30\n                             ? threshold + threshold/8 : 8ll<<30);\n    return true;\n  }\n  return false;\n}\n\n// Helper for do_malloc().\ninline void* do_malloc_pages(ThreadCache* heap, size_t size) {\n  void* result;\n  bool report_large;\n\n  Length num_pages = tcmalloc::pages(size);\n  size = num_pages << kPageShift;\n\n  if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {\n    result = DoSampledAllocation(size);\n\n    SpinLockHolder h(Static::pageheap_lock());\n    report_large = should_report_large(num_pages);\n  } else {\n    SpinLockHolder h(Static::pageheap_lock());\n    Span* span = Static::pageheap()->New(num_pages);\n    result = (span == NULL ? NULL : SpanToMallocResult(span));\n    report_large = should_report_large(num_pages);\n  }\n\n  if (report_large) {\n    ReportLargeAlloc(num_pages, result);\n  }\n  return result;\n}\n\ninline void* do_malloc(size_t size) {\n  void* ret = NULL;\n\n  // The following call forces module initialization\n  ThreadCache* heap = ThreadCache::GetCache();\n  if (size <= kMaxSize) {\n    size_t cl = Static::sizemap()->SizeClass(size);\n    size = Static::sizemap()->class_to_size(cl);\n\n    if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {\n      ret = DoSampledAllocation(size);\n    } else {\n      // The common case, and also the simplest.  This just pops the\n      // size-appropriate freelist, after replenishing it if it's empty.\n      ret = CheckedMallocResult(heap->Allocate(size, cl));\n    }\n  } else {\n    ret = do_malloc_pages(heap, size);\n  }\n  if (ret == NULL) errno = ENOMEM;\n  return ret;\n}\n\ninline void* do_calloc(size_t n, size_t elem_size) {\n  // Overflow check\n  const size_t size = n * elem_size;\n  if (elem_size != 0 && size / elem_size != n) return NULL;\n\n  void* result = do_malloc_or_cpp_alloc(size);\n  if (result != NULL) {\n    memset(result, 0, size);\n  }\n  return result;\n}\n\nstatic inline ThreadCache* GetCacheIfPresent() {\n  void* const p = ThreadCache::GetCacheIfPresent();\n  return reinterpret_cast<ThreadCache*>(p);\n}\n\n// This lets you call back to a given function pointer if ptr is invalid.\n// It is used primarily by windows code which wants a specialized callback.\ninline void do_free_with_callback(void* ptr, void (*invalid_free_fn)(void*)) {\n  if (ptr == NULL) return;\n  ASSERT(Static::pageheap() != NULL);  // Should not call free() before malloc()\n  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;\n  Span* span = NULL;\n  size_t cl = Static::pageheap()->GetSizeClassIfCached(p);\n\n  if (cl == 0) {\n    span = Static::pageheap()->GetDescriptor(p);\n    if (!span) {\n      // span can be NULL because the pointer passed in is invalid\n      // (not something returned by malloc or friends), or because the\n      // pointer was allocated with some other allocator besides\n      // tcmalloc.  The latter can happen if tcmalloc is linked in via\n      // a dynamic library, but is not listed last on the link line.\n      // In that case, libraries after it on the link line will\n      // allocate with libc malloc, but free with tcmalloc's free.\n      (*invalid_free_fn)(ptr);  // Decide how to handle the bad free request\n      return;\n    }\n    cl = span->sizeclass;\n    Static::pageheap()->CacheSizeClass(p, cl);\n  }\n  if (cl != 0) {\n    ASSERT(!Static::pageheap()->GetDescriptor(p)->sample);\n    ThreadCache* heap = GetCacheIfPresent();\n    if (heap != NULL) {\n      heap->Deallocate(ptr, cl);\n    } else {\n      // Delete directly into central cache\n      tcmalloc::SLL_SetNext(ptr, NULL);\n      Static::central_cache()[cl].InsertRange(ptr, ptr, 1);\n    }\n  } else {\n    SpinLockHolder h(Static::pageheap_lock());\n    ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0);\n    ASSERT(span != NULL && span->start == p);\n    if (span->sample) {\n      tcmalloc::DLL_Remove(span);\n      Static::stacktrace_allocator()->Delete(\n          reinterpret_cast<StackTrace*>(span->objects));\n      span->objects = NULL;\n    }\n    Static::pageheap()->Delete(span);\n  }\n}\n\n// The default \"do_free\" that uses the default callback.\ninline void do_free(void* ptr) {\n  return do_free_with_callback(ptr, &InvalidFree);\n}\n\ninline size_t GetSizeWithCallback(void* ptr,\n                                  size_t (*invalid_getsize_fn)(void*)) {\n  if (ptr == NULL)\n    return 0;\n  const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;\n  size_t cl = Static::pageheap()->GetSizeClassIfCached(p);\n  if (cl != 0) {\n    return Static::sizemap()->ByteSizeForClass(cl);\n  } else {\n    Span *span = Static::pageheap()->GetDescriptor(p);\n    if (span == NULL) {  // means we do not own this memory\n      return (*invalid_getsize_fn)(ptr);\n    } else if (span->sizeclass != 0) {\n      Static::pageheap()->CacheSizeClass(p, span->sizeclass);\n      return Static::sizemap()->ByteSizeForClass(span->sizeclass);\n    } else {\n      return span->length << kPageShift;\n    }\n  }\n}\n\n// This lets you call back to a given function pointer if ptr is invalid.\n// It is used primarily by windows code which wants a specialized callback.\ninline void* do_realloc_with_callback(\n    void* old_ptr, size_t new_size,\n    void (*invalid_free_fn)(void*),\n    size_t (*invalid_get_size_fn)(void*)) {\n  // Get the size of the old entry\n  const size_t old_size = GetSizeWithCallback(old_ptr, invalid_get_size_fn);\n\n  // Reallocate if the new size is larger than the old size,\n  // or if the new size is significantly smaller than the old size.\n  // We do hysteresis to avoid resizing ping-pongs:\n  //    . If we need to grow, grow to max(new_size, old_size * 1.X)\n  //    . Don't shrink unless new_size < old_size * 0.Y\n  // X and Y trade-off time for wasted space.  For now we do 1.25 and 0.5.\n  const int lower_bound_to_grow = old_size + old_size / 4;\n  const int upper_bound_to_shrink = old_size / 2;\n  if ((new_size > old_size) || (new_size < upper_bound_to_shrink)) {\n    // Need to reallocate.\n    void* new_ptr = NULL;\n\n    if (new_size > old_size && new_size < lower_bound_to_grow) {\n      new_ptr = do_malloc_or_cpp_alloc(lower_bound_to_grow);\n    }\n    if (new_ptr == NULL) {\n      // Either new_size is not a tiny increment, or last do_malloc failed.\n      new_ptr = do_malloc_or_cpp_alloc(new_size);\n    }\n    if (new_ptr == NULL) {\n      return NULL;\n    }\n    MallocHook::InvokeNewHook(new_ptr, new_size);\n    memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));\n    MallocHook::InvokeDeleteHook(old_ptr);\n    // We could use a variant of do_free() that leverages the fact\n    // that we already know the sizeclass of old_ptr.  The benefit\n    // would be small, so don't bother.\n    do_free_with_callback(old_ptr, invalid_free_fn);\n    return new_ptr;\n  } else {\n    // We still need to call hooks to report the updated size:\n    MallocHook::InvokeDeleteHook(old_ptr);\n    MallocHook::InvokeNewHook(old_ptr, new_size);\n    return old_ptr;\n  }\n}\n\ninline void* do_realloc(void* old_ptr, size_t new_size) {\n  return do_realloc_with_callback(old_ptr, new_size,\n                                  &InvalidFree, &InvalidGetSizeForRealloc);\n}\n\n// For use by exported routines below that want specific alignments\n//\n// Note: this code can be slow for alignments > 16, and can\n// significantly fragment memory.  The expectation is that\n// memalign/posix_memalign/valloc/pvalloc will not be invoked very\n// often.  This requirement simplifies our implementation and allows\n// us to tune for expected allocation patterns.\nvoid* do_memalign(size_t align, size_t size) {\n  ASSERT((align & (align - 1)) == 0);\n  ASSERT(align > 0);\n  if (size + align < size) return NULL;         // Overflow\n\n  // Fall back to malloc if we would already align this memory access properly.\n  if (align <= AlignmentForSize(size)) {\n    void* p = do_malloc(size);\n    ASSERT((reinterpret_cast<uintptr_t>(p) % align) == 0);\n    return p;\n  }\n\n  if (Static::pageheap() == NULL) ThreadCache::InitModule();\n\n  // Allocate at least one byte to avoid boundary conditions below\n  if (size == 0) size = 1;\n\n  if (size <= kMaxSize && align < kPageSize) {\n    // Search through acceptable size classes looking for one with\n    // enough alignment.  This depends on the fact that\n    // InitSizeClasses() currently produces several size classes that\n    // are aligned at powers of two.  We will waste time and space if\n    // we miss in the size class array, but that is deemed acceptable\n    // since memalign() should be used rarely.\n    int cl = Static::sizemap()->SizeClass(size);\n    while (cl < kNumClasses &&\n           ((Static::sizemap()->class_to_size(cl) & (align - 1)) != 0)) {\n      cl++;\n    }\n    if (cl < kNumClasses) {\n      ThreadCache* heap = ThreadCache::GetCache();\n      size = Static::sizemap()->class_to_size(cl);\n      return CheckedMallocResult(heap->Allocate(size, cl));\n    }\n  }\n\n  // We will allocate directly from the page heap\n  SpinLockHolder h(Static::pageheap_lock());\n\n  if (align <= kPageSize) {\n    // Any page-level allocation will be fine\n    // TODO: We could put the rest of this page in the appropriate\n    // TODO: cache but it does not seem worth it.\n    Span* span = Static::pageheap()->New(tcmalloc::pages(size));\n    return span == NULL ? NULL : SpanToMallocResult(span);\n  }\n\n  // Allocate extra pages and carve off an aligned portion\n  const Length alloc = tcmalloc::pages(size + align);\n  Span* span = Static::pageheap()->New(alloc);\n  if (span == NULL) return NULL;\n\n  // Skip starting portion so that we end up aligned\n  Length skip = 0;\n  while ((((span->start+skip) << kPageShift) & (align - 1)) != 0) {\n    skip++;\n  }\n  ASSERT(skip < alloc);\n  if (skip > 0) {\n    Span* rest = Static::pageheap()->Split(span, skip);\n    Static::pageheap()->Delete(span);\n    span = rest;\n  }\n\n  // Skip trailing portion that we do not need to return\n  const Length needed = tcmalloc::pages(size);\n  ASSERT(span->length >= needed);\n  if (span->length > needed) {\n    Span* trailer = Static::pageheap()->Split(span, needed);\n    Static::pageheap()->Delete(trailer);\n  }\n  return SpanToMallocResult(span);\n}\n\n// Helpers for use by exported routines below:\n\ninline void do_malloc_stats() {\n  PrintStats(1);\n}\n\ninline int do_mallopt(int cmd, int value) {\n  return 1;     // Indicates error\n}\n\n#ifdef HAVE_STRUCT_MALLINFO\ninline struct mallinfo do_mallinfo() {\n  TCMallocStats stats;\n  ExtractStats(&stats, NULL);\n\n  // Just some of the fields are filled in.\n  struct mallinfo info;\n  memset(&info, 0, sizeof(info));\n\n  // Unfortunately, the struct contains \"int\" field, so some of the\n  // size values will be truncated.\n  info.arena     = static_cast<int>(stats.pageheap.system_bytes);\n  info.fsmblks   = static_cast<int>(stats.thread_bytes\n                                    + stats.central_bytes\n                                    + stats.transfer_bytes);\n  info.fordblks  = static_cast<int>(stats.pageheap.free_bytes +\n                                    stats.pageheap.unmapped_bytes);\n  info.uordblks  = static_cast<int>(stats.pageheap.system_bytes\n                                    - stats.thread_bytes\n                                    - stats.central_bytes\n                                    - stats.transfer_bytes\n                                    - stats.pageheap.free_bytes\n                                    - stats.pageheap.unmapped_bytes);\n\n  return info;\n}\n#endif  // HAVE_STRUCT_MALLINFO\n\nstatic SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED);\n\ninline void* cpp_alloc(size_t size, bool nothrow) {\n  for (;;) {\n    void* p = do_malloc(size);\n#ifdef PREANSINEW\n    return p;\n#else\n    if (p == NULL) {  // allocation failed\n      // Get the current new handler.  NB: this function is not\n      // thread-safe.  We make a feeble stab at making it so here, but\n      // this lock only protects against tcmalloc interfering with\n      // itself, not with other libraries calling set_new_handler.\n      std::new_handler nh;\n      {\n        SpinLockHolder h(&set_new_handler_lock);\n        nh = std::set_new_handler(0);\n        (void) std::set_new_handler(nh);\n      }\n#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)\n      if (nh) {\n        // Since exceptions are disabled, we don't really know if new_handler\n        // failed.  Assume it will abort if it fails.\n        (*nh)();\n        continue;\n      }\n      return 0;\n#else\n      // If no new_handler is established, the allocation failed.\n      if (!nh) {\n        if (nothrow) return 0;\n        throw std::bad_alloc();\n      }\n      // Otherwise, try the new_handler.  If it returns, retry the\n      // allocation.  If it throws std::bad_alloc, fail the allocation.\n      // if it throws something else, don't interfere.\n      try {\n        (*nh)();\n      } catch (const std::bad_alloc&) {\n        if (!nothrow) throw;\n        return p;\n      }\n#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)\n    } else {  // allocation success\n      return p;\n    }\n#endif  // PREANSINEW\n  }\n}\n\nvoid* cpp_memalign(size_t align, size_t size) {\n  for (;;) {\n    void* p = do_memalign(align, size);\n#ifdef PREANSINEW\n    return p;\n#else\n    if (p == NULL) {  // allocation failed\n      // Get the current new handler.  NB: this function is not\n      // thread-safe.  We make a feeble stab at making it so here, but\n      // this lock only protects against tcmalloc interfering with\n      // itself, not with other libraries calling set_new_handler.\n      std::new_handler nh;\n      {\n        SpinLockHolder h(&set_new_handler_lock);\n        nh = std::set_new_handler(0);\n        (void) std::set_new_handler(nh);\n      }\n#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)\n      if (nh) {\n        // Since exceptions are disabled, we don't really know if new_handler\n        // failed.  Assume it will abort if it fails.\n        (*nh)();\n        continue;\n      }\n      return 0;\n#else\n      // If no new_handler is established, the allocation failed.\n      if (!nh)\n        return 0;\n\n      // Otherwise, try the new_handler.  If it returns, retry the\n      // allocation.  If it throws std::bad_alloc, fail the allocation.\n      // if it throws something else, don't interfere.\n      try {\n        (*nh)();\n      } catch (const std::bad_alloc&) {\n        return p;\n      }\n#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)\n    } else {  // allocation success\n      return p;\n    }\n#endif  // PREANSINEW\n  }\n}\n\n}  // end unnamed namespace\n\n// As promised, the definition of this function, declared above.\nsize_t TCMallocImplementation::GetAllocatedSize(void* ptr) {\n  return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);\n}\n\nvoid TCMallocImplementation::MarkThreadBusy() {\n  // Allocate to force the creation of a thread cache, but avoid\n  // invoking any hooks.\n  do_free(do_malloc(0));\n}\n\n//-------------------------------------------------------------------\n// Exported routines\n//-------------------------------------------------------------------\n\nextern \"C\" PERFTOOLS_DLL_DECL const char* tc_version(\n    int* major, int* minor, const char** patch) __THROW {\n  if (major) *major = TC_VERSION_MAJOR;\n  if (minor) *minor = TC_VERSION_MINOR;\n  if (patch) *patch = TC_VERSION_PATCH;\n  return TC_VERSION_STRING;\n}\n\n// CAVEAT: The code structure below ensures that MallocHook methods are always\n//         called from the stack frame of the invoked allocation function.\n//         heap-checker.cc depends on this to start a stack trace from\n//         the call to the (de)allocation function.\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW {\n  void* result = do_malloc_or_cpp_alloc(size);\n  MallocHook::InvokeNewHook(result, size);\n  return result;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  do_free(ptr);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_calloc(size_t n,\n                                              size_t elem_size) __THROW {\n  void* result = do_calloc(n, elem_size);\n  MallocHook::InvokeNewHook(result, n * elem_size);\n  return result;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  do_free(ptr);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_realloc(void* old_ptr,\n                                               size_t new_size) __THROW {\n  if (old_ptr == NULL) {\n    void* result = do_malloc_or_cpp_alloc(new_size);\n    MallocHook::InvokeNewHook(result, new_size);\n    return result;\n  }\n  if (new_size == 0) {\n    MallocHook::InvokeDeleteHook(old_ptr);\n    do_free(old_ptr);\n    return NULL;\n  }\n  return do_realloc(old_ptr, new_size);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_new(size_t size) {\n  void* p = cpp_alloc(size, false);\n  // We keep this next instruction out of cpp_alloc for a reason: when\n  // it's in, and new just calls cpp_alloc, the optimizer may fold the\n  // new call into cpp_alloc, which messes up our whole section-based\n  // stacktracing (see ATTRIBUTE_SECTION, above).  This ensures cpp_alloc\n  // isn't the last thing this fn calls, and prevents the folding.\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&) __THROW {\n  void* p = cpp_alloc(size, true);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW {\n  MallocHook::InvokeDeleteHook(p);\n  do_free(p);\n}\n\n// Standard C++ library implementations define and use this\n// (via ::operator delete(ptr, nothrow)).\n// But it's really the same as normal delete, so we just do the same thing.\nextern \"C\" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) __THROW {\n  MallocHook::InvokeDeleteHook(p);\n  do_free(p);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) {\n  void* p = cpp_alloc(size, false);\n  // We keep this next instruction out of cpp_alloc for a reason: when\n  // it's in, and new just calls cpp_alloc, the optimizer may fold the\n  // new call into cpp_alloc, which messes up our whole section-based\n  // stacktracing (see ATTRIBUTE_SECTION, above).  This ensures cpp_alloc\n  // isn't the last thing this fn calls, and prevents the folding.\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)\n    __THROW {\n  void* p = cpp_alloc(size, true);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW {\n  MallocHook::InvokeDeleteHook(p);\n  do_free(p);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) __THROW {\n  MallocHook::InvokeDeleteHook(p);\n  do_free(p);\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_memalign(size_t align,\n                                                size_t size) __THROW {\n  void* result = do_memalign_or_cpp_memalign(align, size);\n  MallocHook::InvokeNewHook(result, size);\n  return result;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL int tc_posix_memalign(\n    void** result_ptr, size_t align, size_t size) __THROW {\n  if (((align % sizeof(void*)) != 0) ||\n      ((align & (align - 1)) != 0) ||\n      (align == 0)) {\n    return EINVAL;\n  }\n\n  void* result = do_memalign_or_cpp_memalign(align, size);\n  MallocHook::InvokeNewHook(result, size);\n  if (result == NULL) {\n    return ENOMEM;\n  } else {\n    *result_ptr = result;\n    return 0;\n  }\n}\n\nstatic size_t pagesize = 0;\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) __THROW {\n  // Allocate page-aligned object of length >= size bytes\n  if (pagesize == 0) pagesize = getpagesize();\n  void* result = do_memalign_or_cpp_memalign(pagesize, size);\n  MallocHook::InvokeNewHook(result, size);\n  return result;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) __THROW {\n  // Round up size to a multiple of pagesize\n  if (pagesize == 0) pagesize = getpagesize();\n  if (size == 0) {     // pvalloc(0) should allocate one page, according to\n    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html\n  }\n  size = (size + pagesize - 1) & ~(pagesize - 1);\n  void* result = do_memalign_or_cpp_memalign(pagesize, size);\n  MallocHook::InvokeNewHook(result, size);\n  return result;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW {\n  do_malloc_stats();\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW {\n  return do_mallopt(cmd, value);\n}\n\n#ifdef HAVE_STRUCT_MALLINFO\nextern \"C\" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW {\n  return do_mallinfo();\n}\n#endif\n\nextern \"C\" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW {\n  return GetSizeWithCallback(ptr, &InvalidGetAllocatedSize);\n}\n\n// This function behaves similarly to MSVC's _set_new_mode.\n// If flag is 0 (default), calls to malloc will behave normally.\n// If flag is 1, calls to malloc will behave like calls to new,\n// and the std_new_handler will be invoked on failure.\n// Returns the previous mode.\nextern \"C\" PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW {\n  int old_mode = tc_new_mode;\n  tc_new_mode = flag;\n  return old_mode;\n}\n\n\n// Override __libc_memalign in libc on linux boxes specially.\n// They have a bug in libc that causes them to (very rarely) allocate\n// with __libc_memalign() yet deallocate with free() and the\n// definitions above don't catch it.\n// This function is an exception to the rule of calling MallocHook method\n// from the stack frame of the allocation function;\n// heap-checker handles this special case explicitly.\n#ifndef TCMALLOC_FOR_DEBUGALLOCATION\nstatic void *MemalignOverride(size_t align, size_t size, const void *caller)\n    __THROW ATTRIBUTE_SECTION(google_malloc);\n\nstatic void *MemalignOverride(size_t align, size_t size, const void *caller)\n    __THROW {\n  void* result = do_memalign_or_cpp_memalign(align, size);\n  MallocHook::InvokeNewHook(result, size);\n  return result;\n}\nvoid *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;\n#endif  // #ifndef TCMALLOC_FOR_DEBUGALLOCATION\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tcmalloc.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein <opensource@google.com>\n//\n// Some obscure memory-allocation routines may not be declared on all\n// systems.  In those cases, we'll just declare them ourselves.\n// This file is meant to be used only internally, for unittests.\n\n#include <config.h>\n\n#ifndef _XOPEN_SOURCE\n# define _XOPEN_SOURCE 600  // for posix_memalign\n#endif\n#include <stdlib.h>         // for posix_memalign\n// FreeBSD has malloc.h, but complains if you use it\n#if defined(HAVE_MALLOC_H) && !defined(__FreeBSD__)\n#include <malloc.h>         // for memalign, valloc, pvalloc\n#endif\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    // I guess we're not on a glibc system\n# define __THROW   // __THROW is just an optimization, so ok to make it \"\"\n#endif\n\n#if !HAVE_CFREE_SYMBOL\nextern \"C\" void cfree(void* ptr) __THROW;\n#endif\n#if !HAVE_POSIX_MEMALIGN_SYMBOL\nextern \"C\" int posix_memalign(void** ptr, size_t align, size_t size) __THROW;\n#endif\n#if !HAVE_MEMALIGN_SYMBOL\nextern \"C\" void* memalign(size_t __alignment, size_t __size) __THROW;\n#endif\n#if !HAVE_VALLOC_SYMBOL\nextern \"C\" void* valloc(size_t __size) __THROW;\n#endif\n#if !HAVE_PVALLOC_SYMBOL\nextern \"C\" void* pvalloc(size_t __size) __THROW;\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tcmalloc_guard.h",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// We expose the TCMallocGuard class -- which initializes the tcmalloc\n// allocator -- so classes that need to be sure tcmalloc is loaded\n// before they do stuff -- notably heap-profiler -- can.  To use this\n// create a static TCMallocGuard instance at the top of a file where\n// you need tcmalloc to be initialized before global constructors run.\n\n#ifndef TCMALLOC_TCMALLOC_GUARD_H_\n#define TCMALLOC_TCMALLOC_GUARD_H_\n\nclass TCMallocGuard {\n public:\n  TCMallocGuard();\n  ~TCMallocGuard();\n};\n\n#endif  // TCMALLOC_TCMALLOC_GUARD_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/addressmap_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n\n#include <stdlib.h>   // for rand()\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <utility>\n#include \"addressmap-inl.h\"\n#include \"base/logging.h\"\n#include \"base/commandlineflags.h\"\n\nDEFINE_int32(iters, 20, \"Number of test iterations\");\nDEFINE_int32(N, 100000,  \"Number of elements to test per iteration\");\n\nusing std::pair;\nusing std::make_pair;\nusing std::vector;\nusing std::set;\nusing std::random_shuffle;\n\nstruct UniformRandomNumberGenerator {\n  size_t Uniform(size_t max_size) {\n    if (max_size == 0)\n      return 0;\n    return rand() % max_size;   // not a great random-number fn, but portable\n  }\n};\nstatic UniformRandomNumberGenerator rnd;\n\n\n// pair of associated value and object size\ntypedef pair<int, size_t> ValueT;\n\nstruct PtrAndSize {\n  char* ptr;\n  size_t size;\n  PtrAndSize(char* p, size_t s) : ptr(p), size(s) {}\n};\n\nsize_t SizeFunc(const ValueT& v) { return v.second; }\n\nstatic void SetCheckCallback(const void* ptr, ValueT* val,\n                             set<pair<const void*, int> >* check_set) {\n  check_set->insert(make_pair(ptr, val->first));\n}\n\nint main(int argc, char** argv) {\n  // Get a bunch of pointers\n  const int N = FLAGS_N;\n  static const int kMaxRealSize = 49;\n  // 100Mb to stress not finding previous object (AddressMap's cluster is 1Mb):\n  static const size_t kMaxSize = 100*1000*1000;\n  vector<PtrAndSize> ptrs_and_sizes;\n  for (int i = 0; i < N; ++i) {\n    size_t s = rnd.Uniform(kMaxRealSize);\n    ptrs_and_sizes.push_back(PtrAndSize(new char[s], s));\n  }\n\n  for (int x = 0; x < FLAGS_iters; ++x) {\n    RAW_LOG(INFO, \"Iteration %d/%d...\\n\", x, FLAGS_iters);\n\n    // Permute pointers to get rid of allocation order issues\n    random_shuffle(ptrs_and_sizes.begin(), ptrs_and_sizes.end());\n\n    AddressMap<ValueT> map(malloc, free);\n    const ValueT* result;\n    const void* res_p;\n\n    // Insert a bunch of entries\n    for (int i = 0; i < N; ++i) {\n      char* p = ptrs_and_sizes[i].ptr;\n      CHECK(!map.Find(p));\n      int offs = rnd.Uniform(ptrs_and_sizes[i].size);\n      CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));\n      map.Insert(p, make_pair(i, ptrs_and_sizes[i].size));\n      CHECK(result = map.Find(p));\n      CHECK_EQ(result->first, i);\n      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));\n      CHECK_EQ(res_p, p);\n      CHECK_EQ(result->first, i);\n      map.Insert(p, make_pair(i + N, ptrs_and_sizes[i].size));\n      CHECK(result = map.Find(p));\n      CHECK_EQ(result->first, i + N);\n    }\n\n    // Delete the even entries\n    for (int i = 0; i < N; i += 2) {\n      void* p = ptrs_and_sizes[i].ptr;\n      ValueT removed;\n      CHECK(map.FindAndRemove(p, &removed));\n      CHECK_EQ(removed.first, i + N);\n    }\n\n    // Lookup the odd entries and adjust them\n    for (int i = 1; i < N; i += 2) {\n      char* p = ptrs_and_sizes[i].ptr;\n      CHECK(result = map.Find(p));\n      CHECK_EQ(result->first, i + N);\n      int offs = rnd.Uniform(ptrs_and_sizes[i].size);\n      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));\n      CHECK_EQ(res_p, p);\n      CHECK_EQ(result->first, i + N);\n      map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));\n      CHECK(result = map.Find(p));\n      CHECK_EQ(result->first, i + 2*N);\n    }\n\n    // Insert even entries back\n    for (int i = 0; i < N; i += 2) {\n      char* p = ptrs_and_sizes[i].ptr;\n      int offs = rnd.Uniform(ptrs_and_sizes[i].size);\n      CHECK(!map.FindInside(&SizeFunc, kMaxSize, p + offs, &res_p));\n      map.Insert(p, make_pair(i + 2*N, ptrs_and_sizes[i].size));\n      CHECK(result = map.Find(p));\n      CHECK_EQ(result->first, i + 2*N);\n      CHECK(result = map.FindInside(&SizeFunc, kMaxRealSize, p + offs, &res_p));\n      CHECK_EQ(res_p, p);\n      CHECK_EQ(result->first, i + 2*N);\n    }\n\n    // Check all entries\n    set<pair<const void*, int> > check_set;\n    map.Iterate(SetCheckCallback, &check_set);\n    CHECK_EQ(check_set.size(), N);\n    for (int i = 0; i < N; ++i) {\n      void* p = ptrs_and_sizes[i].ptr;\n      check_set.erase(make_pair(p, i + 2*N));\n      CHECK(result = map.Find(p));\n      CHECK_EQ(result->first, i + 2*N);\n    }\n    CHECK_EQ(check_set.size(), 0);\n  }\n\n  for (int i = 0; i < N; ++i) {\n    delete[] ptrs_and_sizes[i].ptr;\n  }\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/atomicops_unittest.cc",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat\n */\n\n#include <stdio.h>\n#include \"base/logging.h\"\n#include \"base/atomicops.h\"\n\n#define GG_ULONGLONG(x)  static_cast<uint64>(x)\n\ntemplate <class AtomicType>\nstatic void TestAtomicIncrement() {\n  // For now, we just test single threaded execution\n\n  // use a guard value to make sure the NoBarrier_AtomicIncrement doesn't go\n  // outside the expected address bounds.  This is in particular to\n  // test that some future change to the asm code doesn't cause the\n  // 32-bit NoBarrier_AtomicIncrement doesn't do the wrong thing on 64-bit\n  // machines.\n  struct {\n    AtomicType prev_word;\n    AtomicType count;\n    AtomicType next_word;\n  } s;\n\n  AtomicType prev_word_value, next_word_value;\n  memset(&prev_word_value, 0xFF, sizeof(AtomicType));\n  memset(&next_word_value, 0xEE, sizeof(AtomicType));\n\n  s.prev_word = prev_word_value;\n  s.count = 0;\n  s.next_word = next_word_value;\n\n  ASSERT_EQ(1, base::subtle::NoBarrier_AtomicIncrement(&s.count, 1));\n  ASSERT_EQ(1, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(3, base::subtle::NoBarrier_AtomicIncrement(&s.count, 2));\n  ASSERT_EQ(3, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(6, base::subtle::NoBarrier_AtomicIncrement(&s.count, 3));\n  ASSERT_EQ(6, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(3, base::subtle::NoBarrier_AtomicIncrement(&s.count, -3));\n  ASSERT_EQ(3, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(1, base::subtle::NoBarrier_AtomicIncrement(&s.count, -2));\n  ASSERT_EQ(1, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(0, base::subtle::NoBarrier_AtomicIncrement(&s.count, -1));\n  ASSERT_EQ(0, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(-1, base::subtle::NoBarrier_AtomicIncrement(&s.count, -1));\n  ASSERT_EQ(-1, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(-5, base::subtle::NoBarrier_AtomicIncrement(&s.count, -4));\n  ASSERT_EQ(-5, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n\n  ASSERT_EQ(0, base::subtle::NoBarrier_AtomicIncrement(&s.count, 5));\n  ASSERT_EQ(0, s.count);\n  ASSERT_EQ(prev_word_value, s.prev_word);\n  ASSERT_EQ(next_word_value, s.next_word);\n}\n\n\n#define NUM_BITS(T) (sizeof(T) * 8)\n\n\ntemplate <class AtomicType>\nstatic void TestCompareAndSwap() {\n  AtomicType value = 0;\n  AtomicType prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 1);\n  ASSERT_EQ(1, value);\n  ASSERT_EQ(0, prev);\n\n  // Use test value that has non-zero bits in both halves, more for testing\n  // 64-bit implementation on 32-bit platforms.\n  const AtomicType k_test_val = (GG_ULONGLONG(1) <<\n                                 (NUM_BITS(AtomicType) - 2)) + 11;\n  value = k_test_val;\n  prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 5);\n  ASSERT_EQ(k_test_val, value);\n  ASSERT_EQ(k_test_val, prev);\n\n  value = k_test_val;\n  prev = base::subtle::NoBarrier_CompareAndSwap(&value, k_test_val, 5);\n  ASSERT_EQ(5, value);\n  ASSERT_EQ(k_test_val, prev);\n}\n\n\ntemplate <class AtomicType>\nstatic void TestAtomicExchange() {\n  AtomicType value = 0;\n  AtomicType new_value = base::subtle::NoBarrier_AtomicExchange(&value, 1);\n  ASSERT_EQ(1, value);\n  ASSERT_EQ(0, new_value);\n\n  // Use test value that has non-zero bits in both halves, more for testing\n  // 64-bit implementation on 32-bit platforms.\n  const AtomicType k_test_val = (GG_ULONGLONG(1) <<\n                                 (NUM_BITS(AtomicType) - 2)) + 11;\n  value = k_test_val;\n  new_value = base::subtle::NoBarrier_AtomicExchange(&value, k_test_val);\n  ASSERT_EQ(k_test_val, value);\n  ASSERT_EQ(k_test_val, new_value);\n\n  value = k_test_val;\n  new_value = base::subtle::NoBarrier_AtomicExchange(&value, 5);\n  ASSERT_EQ(5, value);\n  ASSERT_EQ(k_test_val, new_value);\n}\n\n\ntemplate <class AtomicType>\nstatic void TestAtomicIncrementBounds() {\n  // Test increment at the half-width boundary of the atomic type.\n  // It is primarily for testing at the 32-bit boundary for 64-bit atomic type.\n  AtomicType test_val = GG_ULONGLONG(1) << (NUM_BITS(AtomicType) / 2);\n  AtomicType value = test_val - 1;\n  AtomicType new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1);\n  ASSERT_EQ(test_val, value);\n  ASSERT_EQ(value, new_value);\n\n  base::subtle::NoBarrier_AtomicIncrement(&value, -1);\n  ASSERT_EQ(test_val - 1, value);\n}\n\n// This is a simple sanity check that values are correct. Not testing\n// atomicity\ntemplate <class AtomicType>\nstatic void TestStore() {\n  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);\n  const AtomicType kVal2 = static_cast<AtomicType>(-1);\n\n  AtomicType value;\n\n  base::subtle::NoBarrier_Store(&value, kVal1);\n  ASSERT_EQ(kVal1, value);\n  base::subtle::NoBarrier_Store(&value, kVal2);\n  ASSERT_EQ(kVal2, value);\n\n  base::subtle::Acquire_Store(&value, kVal1);\n  ASSERT_EQ(kVal1, value);\n  base::subtle::Acquire_Store(&value, kVal2);\n  ASSERT_EQ(kVal2, value);\n\n  base::subtle::Release_Store(&value, kVal1);\n  ASSERT_EQ(kVal1, value);\n  base::subtle::Release_Store(&value, kVal2);\n  ASSERT_EQ(kVal2, value);\n}\n\n// This is a simple sanity check that values are correct. Not testing\n// atomicity\ntemplate <class AtomicType>\nstatic void TestLoad() {\n  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);\n  const AtomicType kVal2 = static_cast<AtomicType>(-1);\n\n  AtomicType value;\n\n  value = kVal1;\n  ASSERT_EQ(kVal1, base::subtle::NoBarrier_Load(&value));\n  value = kVal2;\n  ASSERT_EQ(kVal2, base::subtle::NoBarrier_Load(&value));\n\n  value = kVal1;\n  ASSERT_EQ(kVal1, base::subtle::Acquire_Load(&value));\n  value = kVal2;\n  ASSERT_EQ(kVal2, base::subtle::Acquire_Load(&value));\n\n  value = kVal1;\n  ASSERT_EQ(kVal1, base::subtle::Release_Load(&value));\n  value = kVal2;\n  ASSERT_EQ(kVal2, base::subtle::Release_Load(&value));\n}\n\ntemplate <class AtomicType>\nstatic void TestAtomicOps() {\n  TestCompareAndSwap<AtomicType>();\n  TestAtomicExchange<AtomicType>();\n  TestAtomicIncrementBounds<AtomicType>();\n  TestStore<AtomicType>();\n  TestLoad<AtomicType>();\n}\n\nint main(int argc, char** argv) {\n  TestAtomicIncrement<AtomicWord>();\n  TestAtomicIncrement<Atomic32>();\n\n  TestAtomicOps<AtomicWord>();\n  TestAtomicOps<Atomic32>();\n\n  // I've commented the Atomic64 tests out for now, because Atomic64\n  // doesn't work on x86 systems that are not compiled to support mmx\n  // registers.  Since I want this project to be as portable as\n  // possible -- that is, not to assume we've compiled for mmx or even\n  // that the processor supports it -- and we don't actually use\n  // Atomic64 anywhere, I've commented it out of the test for now.\n  // (Luckily, if we ever do use Atomic64 by accident, we'll get told\n  // via a compiler error rather than some obscure runtime failure, so\n  // this course of action is safe.)\n  // If we ever *do* want to enable this, try adding -msse (or -mmmx?)\n  // to the CXXFLAGS in Makefile.am.\n#if 0 and defined(BASE_HAS_ATOMIC64)\n  TestAtomicIncrement<base::subtle::Atomic64>();\n  TestAtomicOps<base::subtle::Atomic64>();\n#endif\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/debugallocation_test.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Fred Akalin\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <vector>\n#include \"google/malloc_extension.h\"\n#include \"base/logging.h\"\n\nusing std::vector;\n\nvector<void (*)()> g_testlist;  // the tests to run\n\n#define TEST(a, b)                                      \\\n  struct Test_##a##_##b {                               \\\n    Test_##a##_##b() { g_testlist.push_back(&Run); }    \\\n    static void Run();                                  \\\n  };                                                    \\\n  static Test_##a##_##b g_test_##a##_##b;               \\\n  void Test_##a##_##b::Run()\n\n\nstatic int RUN_ALL_TESTS() {\n  vector<void (*)()>::const_iterator it;\n  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {\n    (*it)();   // The test will error-exit if there's a problem.\n  }\n  fprintf(stderr, \"\\nPassed %d tests\\n\\nPASS\\n\",\n          static_cast<int>(g_testlist.size()));\n  return 0;\n}\n\n// The death tests are meant to be run from a shell-script driver, which\n// passes in an integer saying which death test to run.  We store that\n// test-to-run here, and in the macro use a counter to see when we get\n// to that test, so we can run it.\nstatic int test_to_run = 0;     // set in main() based on argv\nstatic int test_counter = 0;    // incremented every time the macro is called\n#define IF_DEBUG_EXPECT_DEATH(statement, regex) do {    \\\n  if (test_counter++ == test_to_run) {                  \\\n    fprintf(stderr, \"Expected regex:%s\\n\", regex);      \\\n    statement;                                          \\\n  }                                                     \\\n} while (false)\n\n// This flag won't be compiled in in opt mode.\nDECLARE_int32(max_free_queue_size);\n\n// Test match as well as mismatch rules:\nTEST(DebugAllocationTest, DeallocMismatch) {\n  // malloc can be matched only by free\n  // new can be matched only by delete and delete(nothrow)\n  // new[] can be matched only by delete[] and delete[](nothrow)\n  // new(nothrow) can be matched only by delete and delete(nothrow)\n  // new(nothrow)[] can be matched only by delete[] and delete[](nothrow)\n\n  // Allocate with malloc.\n  {\n    int* x = static_cast<int*>(malloc(sizeof(*x)));\n    IF_DEBUG_EXPECT_DEATH(delete x, \"mismatch.*being dealloc.*delete\");\n    IF_DEBUG_EXPECT_DEATH(delete [] x, \"mismatch.*being dealloc.*delete *[[]\");\n    // Should work fine.\n    free(x);\n  }\n\n  // Allocate with new.\n  {\n    int* x = new int;\n    int* y = new int;\n    IF_DEBUG_EXPECT_DEATH(free(x), \"mismatch.*being dealloc.*free\");\n    IF_DEBUG_EXPECT_DEATH(delete [] x, \"mismatch.*being dealloc.*delete *[[]\");\n    delete x;\n    ::operator delete(y, std::nothrow);\n  }\n\n  // Allocate with new[].\n  {\n    int* x = new int[1];\n    int* y = new int[1];\n    IF_DEBUG_EXPECT_DEATH(free(x), \"mismatch.*being dealloc.*free\");\n    IF_DEBUG_EXPECT_DEATH(delete x, \"mismatch.*being dealloc.*delete\");\n    delete [] x;\n    ::operator delete[](y, std::nothrow);\n  }\n\n  // Allocate with new(nothrow).\n  {\n    int* x = new(std::nothrow) int;\n    int* y = new(std::nothrow) int;\n    IF_DEBUG_EXPECT_DEATH(free(x), \"mismatch.*being dealloc.*free\");\n    IF_DEBUG_EXPECT_DEATH(delete [] x, \"mismatch.*being dealloc.*delete *[[]\");\n    delete x;\n    ::operator delete(y, std::nothrow);\n  }\n\n  // Allocate with new(nothrow)[].\n  {\n    int* x = new(std::nothrow) int[1];\n    int* y = new(std::nothrow) int[1];\n    IF_DEBUG_EXPECT_DEATH(free(x), \"mismatch.*being dealloc.*free\");\n    IF_DEBUG_EXPECT_DEATH(delete x, \"mismatch.*being dealloc.*delete\");\n    delete [] x;\n    ::operator delete[](y, std::nothrow);\n  }\n}\n\nTEST(DebugAllocationTest, DoubleFree) {\n  int* pint = new int;\n  delete pint;\n  IF_DEBUG_EXPECT_DEATH(delete pint, \"has been already deallocated\");\n}\n\nTEST(DebugAllocationTest, StompBefore) {\n  int* pint = new int;\n#ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it\n  pint[-1] = 5;\n  IF_DEBUG_EXPECT_DEATH(delete pint, \"a word before object\");\n#endif\n}\n\nTEST(DebugAllocationTest, StompAfter) {\n  int* pint = new int;\n#ifndef NDEBUG   // don't stomp memory if we're not in a position to detect it\n  pint[1] = 5;\n  IF_DEBUG_EXPECT_DEATH(delete pint, \"a word after object\");\n#endif\n}\n\nTEST(DebugAllocationTest, FreeQueueTest) {\n  // Verify that the allocator doesn't return blocks that were recently freed.\n  int* x = new int;\n  int* old_x = x;\n  delete x;\n  x = new int;\n  #if 1\n    // This check should not be read as a universal guarantee of behavior.  If\n    // other threads are executing, it would be theoretically possible for this\n    // check to fail despite the efforts of debugallocation.cc to the contrary.\n    // It should always hold under the controlled conditions of this unittest,\n    // however.\n    EXPECT_NE(x, old_x);  // Allocator shouldn't return recently freed blocks\n  #else\n    // The below check passes, but since it isn't *required* to pass, I've left\n    // it commented out.\n    // EXPECT_EQ(x, old_x);\n  #endif\n  old_x = NULL;  // avoid breaking opt build with an unused variable warning.\n  delete x;\n}\n\nTEST(DebugAllocationTest, DanglingPointerWriteTest) {\n  // This test can only be run if debugging.\n  //\n  // If not debugging, the 'new' following the dangling write might not be\n  // safe.  When debugging, we expect the (trashed) deleted block to be on the\n  // list of recently-freed blocks, so the following 'new' will be safe.\n#if 1\n  int* x = new int;\n  delete x;\n  int poisoned_x_value = *x;\n  *x = 1;  // a dangling write.\n\n  char* s = new char[FLAGS_max_free_queue_size];\n  // When we delete s, we push the storage that was previously allocated to x\n  // off the end of the free queue.  At that point, the write to that memory\n  // will be detected.\n  IF_DEBUG_EXPECT_DEATH(delete [] s, \"Memory was written to after being freed.\");\n\n  // restore the poisoned value of x so that we can delete s without causing a\n  // crash.\n  *x = poisoned_x_value;\n  delete [] s;\n#endif\n}\n\nTEST(DebugAllocationTest, DanglingWriteAtExitTest) {\n  int *x = new int;\n  delete x;\n  int old_x_value = *x;\n  *x = 1;\n  // verify that dangling writes are caught at program termination if the\n  // corrupted block never got pushed off of the end of the free queue.\n  IF_DEBUG_EXPECT_DEATH(exit(0), \"Memory was written to after being freed.\");\n  *x = old_x_value;  // restore x so that the test can exit successfully.\n}\n\nTEST(DebugAllocationTest, StackTraceWithDanglingWriteAtExitTest) {\n  int *x = new int;\n  delete x;\n  int old_x_value = *x;\n  *x = 1;\n  // verify that we also get a stack trace when we have a dangling write.\n  // The \" @ \" is part of the stack trace output.\n  IF_DEBUG_EXPECT_DEATH(exit(0), \" @ .* main\");\n  *x = old_x_value;  // restore x so that the test can exit successfully.\n}\n\nstatic size_t CurrentlyAllocatedBytes() {\n  size_t value;\n  CHECK(MallocExtension::instance()->GetNumericProperty(\n            \"generic.current_allocated_bytes\", &value));\n  return value;\n}\n\nTEST(DebugAllocationTest, CurrentlyAllocated) {\n  // Clear the free queue\n#if 1\n  FLAGS_max_free_queue_size = 0;\n  // Force a round-trip through the queue management code so that the\n  // new size is seen and the queue of recently-freed blocks is flushed.\n  free(malloc(1));\n  FLAGS_max_free_queue_size = 1048576;\n#endif\n\n  // Free something and check that it disappears from allocated bytes\n  // immediately.\n  char* p = new char[1000];\n  size_t after_malloc = CurrentlyAllocatedBytes();\n  delete[] p;\n  size_t after_free = CurrentlyAllocatedBytes();\n  EXPECT_LE(after_free, after_malloc - 1000);\n}\n\nTEST(DebugAllocationTest, GetAllocatedSizeTest) {\n#if 1\n  // When debug_allocation is in effect, GetAllocatedSize should return\n  // exactly requested size, since debug_allocation doesn't allow users\n  // to write more than that.\n  for (int i = 0; i < 10; ++i) {\n    void *p = malloc(i);\n    EXPECT_EQ(i, MallocExtension::instance()->GetAllocatedSize(p));\n    free(p);\n  }\n#endif\n  void* a = malloc(1000);\n  EXPECT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);\n  // This is just a sanity check.  If we allocated too much, alloc is broken\n  EXPECT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);\n  EXPECT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000);\n  free(a);\n}\n\nTEST(DebugAllocationTest, HugeAlloc) {\n  // This must not be a const variable so it doesn't form an\n  // integral-constant-expression which can be *statically* rejected by the\n  // compiler as too large for the allocation.\n  size_t kTooBig = ~static_cast<size_t>(0);\n  void* a = NULL;\n\n#ifndef NDEBUG\n\n  a = malloc(kTooBig);\n  EXPECT_EQ(NULL, a);\n\n  // kAlsoTooBig is small enough not to get caught by debugallocation's check,\n  // but will still fall through to tcmalloc's check. This must also be\n  // a non-const variable. See kTooBig for more details.\n  size_t kAlsoTooBig = kTooBig - 1024;\n\n  a = malloc(kAlsoTooBig);\n  EXPECT_EQ(NULL, a);\n#endif\n}\n\nint main(int argc, char** argv) {\n  // If you run without args, we run the non-death parts of the test.\n  // Otherwise, argv[1] should be a number saying which death-test\n  // to run.  We will output a regexp we expect the death-message\n  // to include, and then run the given death test (which hopefully\n  // will produce that error message).  If argv[1] > the number of\n  // death tests, we will run only the non-death parts.  One way to\n  // tell when you are done with all tests is when no 'expected\n  // regexp' message is printed for a given argv[1].\n  if (argc < 2) {\n    test_to_run = -1;   // will never match\n  } else {\n    test_to_run = atoi(argv[1]);\n  }\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/debugallocation_test.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2009, Google Inc.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n#\n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# ---\n# Author: Craig Silverstein\n\nBINDIR=\"${BINDIR:-.}\"\n\nif [ \"x$1\" = \"x-h\" -o \"x$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir]\"\n  echo \"       By default, unittest_dir=$BINDIR\"\n  exit 1\nfi\n\nDEBUGALLOCATION_TEST=\"${1:-$BINDIR/debugallocation_test}\"\n\nnum_failures=0\n\n# Run the i-th death test and make sure the test has the expected\n# regexp.  We can depend on the first line of the output being\n#    Expected regex:<regex>\n# Evaluates to \"done\" if we are not actually a death-test (so $1 is\n# too big a number, and we can stop).  Evaluates to \"\" otherwise.\n# Increments num_failures if the death test does not succeed.\nOneDeathTest() {\n  \"$DEBUGALLOCATION_TEST\" \"$1\" 2>&1 | {\n    regex_line='dummy'\n    # Normally the regex_line is the first line of output, but not\n    # always (if tcmalloc itself does any logging to stderr).\n    while test -n \"$regex_line\"; do\n      read regex_line\n      regex=`expr \"$regex_line\" : \"Expected regex:\\(.*\\)\"`\n      test -n \"$regex\" && break   # found the regex line\n    done\n    test -z \"$regex\" && echo \"done\" || grep \"$regex\" 2>&1\n  }\n}\n\ndeath_test_num=0   # which death test to run\nwhile /bin/true; do\n  echo -n \"Running death test $death_test_num...\"\n  output=\"`OneDeathTest $death_test_num`\"\n  case $output in\n     # Empty string means grep didn't find anything.\n     \"\")      echo \"FAILED\"; num_failures=`expr $num_failures + 1`;;\n     \"done\"*) echo \"done with death tests\"; break;;\n     # Any other string means grep found something, like it ought to.\n     *)       echo \"OK\";;\n  esac\n  death_test_num=`expr $death_test_num + 1`\ndone\n\n# Test the non-death parts of the test too\necho -n \"Running non-death tests...\"\nif \"$DEBUGALLOCATION_TEST\"; then\n  echo \"OK\"\nelse\n  echo \"FAILED\"\n  num_failures=`expr $num_failures + 1`\nfi\n\nif [ \"$num_failures\" = 0 ]; then\n  echo \"PASS\"\nelse\n  echo \"Failed with $num_failures failures\"\nfi\nexit $num_failures\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/frag_unittest.cc",
    "content": "// Copyright (c) 2003, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Test speed of handling fragmented heap\n\n#include \"config_for_unittests.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#ifdef HAVE_SYS_RESOURCE_H\n#include <sys/time.h>           // for struct timeval\n#include <sys/resource.h>       // for getrusage\n#endif\n#ifdef _WIN32\n#include <windows.h>            // for GetTickCount()\n#endif\n#include <vector>\n#include \"base/logging.h\"\n#include \"common.h\"\n#include <google/malloc_extension.h>\n\nusing std::vector;\n\nint main(int argc, char** argv) {\n  // Make kAllocSize larger than tcmalloc page size.\n  static const int kAllocSize = 9 << kPageShift;\n  // Allocate 400MB in total.\n  static const int kTotalAlloc = 400 << 20;\n  static const int kAllocIterations = kTotalAlloc / kAllocSize;\n\n  // Allocate lots of objects\n  vector<char*> saved(kAllocIterations);\n  for (int i = 0; i < kAllocIterations; i++) {\n    saved[i] = new char[kAllocSize];\n  }\n\n  // Free alternating ones to fragment heap\n  size_t free_bytes = 0;\n  for (int i = 0; i < saved.size(); i += 2) {\n    delete[] saved[i];\n    free_bytes += kAllocSize;\n  }\n\n  // Check that slack is within 10% of expected\n  size_t slack;\n  MallocExtension::instance()->GetNumericProperty(\"tcmalloc.slack_bytes\",\n                                                  &slack);\n  CHECK_GT(double(slack), 0.9*free_bytes);\n  CHECK_LT(double(slack), 1.1*free_bytes);\n\n  // Dump malloc stats\n  static const int kBufSize = 1<<20;\n  char* buffer = new char[kBufSize];\n  MallocExtension::instance()->GetStats(buffer, kBufSize);\n  VLOG(1, \"%s\", buffer);\n  delete[] buffer;\n\n  // Now do timing tests\n  for (int i = 0; i < 5; i++) {\n    static const int kIterations = 100000;\n#ifdef HAVE_SYS_RESOURCE_H\n    struct rusage r;\n    getrusage(RUSAGE_SELF, &r);    // figure out user-time spent on this\n    struct timeval tv_start = r.ru_utime;\n#elif defined(_WIN32)\n    long long int tv_start = GetTickCount();\n#else\n# error No way to calculate time on your system\n#endif\n\n    for (int i = 0; i < kIterations; i++) {\n      size_t s;\n      MallocExtension::instance()->GetNumericProperty(\"tcmalloc.slack_bytes\",\n                                                      &s);\n    }\n\n#ifdef HAVE_SYS_RESOURCE_H\n    getrusage(RUSAGE_SELF, &r);\n    struct timeval tv_end = r.ru_utime;\n    int64 sumsec = static_cast<int64>(tv_end.tv_sec) - tv_start.tv_sec;\n    int64 sumusec = static_cast<int64>(tv_end.tv_usec) - tv_start.tv_usec;\n#elif defined(_WIN32)\n    long long int tv_end = GetTickCount();\n    int64 sumsec = (tv_end - tv_start) / 1000;\n    // Resolution in windows is only to the millisecond, alas\n    int64 sumusec = ((tv_end - tv_start) % 1000) * 1000;\n#else\n# error No way to calculate time on your system\n#endif\n    fprintf(stderr, \"getproperty: %6.1f ns/call\\n\",\n            (sumsec * 1e9 + sumusec * 1e3) / kIterations);\n  }\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/getpc_test.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// This verifies that GetPC works correctly.  This test uses a minimum\n// of Google infrastructure, to make it very easy to port to various\n// O/Ses and CPUs and test that GetPC is working.\n\n#include \"config.h\"\n#include \"getpc.h\"        // should be first to get the _GNU_SOURCE dfn\n#include <stdio.h>\n#include <stdlib.h>\n#include <signal.h>\n#include <sys/time.h>     // for setitimer\n\n// Needs to be volatile so compiler doesn't try to optimize it away\nstatic volatile void* getpc_retval = NULL;    // what GetPC returns\nstatic volatile bool prof_handler_called = false;\n\nstatic void prof_handler(int sig, siginfo_t*, void* signal_ucontext) {\n  if (!prof_handler_called)\n    getpc_retval = GetPC(*reinterpret_cast<ucontext_t*>(signal_ucontext));\n  prof_handler_called = true;  // only store the retval once\n}\n\nstatic void RoutineCallingTheSignal() {\n  struct sigaction sa;\n  sa.sa_sigaction = prof_handler;\n  sa.sa_flags = SA_RESTART | SA_SIGINFO;\n  sigemptyset(&sa.sa_mask);\n  if (sigaction(SIGPROF, &sa, NULL) != 0) {\n    perror(\"sigaction\");\n    exit(1);\n  }\n\n  struct itimerval timer;\n  timer.it_interval.tv_sec = 0;\n  timer.it_interval.tv_usec = 1000;\n  timer.it_value = timer.it_interval;\n  setitimer(ITIMER_PROF, &timer, 0);\n\n  // Now we need to do some work for a while, that doesn't call any\n  // other functions, so we can be guaranteed that when the SIGPROF\n  // fires, we're the routine executing.\n  int r = 0;\n  for (int i = 0; !prof_handler_called; ++i) {\n    for (int j = 0; j < i; j++) {\n      r ^= i;\n      r <<= 1;\n      r ^= j;\n      r >>= 1;\n    }\n  }\n\n  // Now make sure the above loop doesn't get optimized out\n  srand(r);\n}\n\n// This is an upper bound of how many bytes the instructions for\n// RoutineCallingTheSignal might be.  There's probably a more\n// principled way to do this, but I don't know how portable it would be.\n// (The function is 372 bytes when compiled with -g on Mac OS X 10.4.\n// I can imagine it would be even bigger in 64-bit architectures.)\nconst int kRoutineSize = 512 * sizeof(void*)/4;    // allow 1024 for 64-bit\n\nint main(int argc, char** argv) {\n  RoutineCallingTheSignal();\n\n  // Annoyingly, C++ disallows casting pointer-to-function to\n  // pointer-to-object, so we use a C-style cast instead.\n  char* expected = (char*)&RoutineCallingTheSignal;\n  char* actual = (char*)getpc_retval;\n\n  // For ia64, ppc64, and parisc64, the function pointer is actually\n  // a struct.  For instance, ia64's dl-fptr.h:\n  //   struct fdesc {          /* An FDESC is a function descriptor.  */\n  //      ElfW(Addr) ip;      /* code entry point */\n  //      ElfW(Addr) gp;      /* global pointer */\n  //   };\n  // We want the code entry point.\n#if defined(__ia64) || defined(__ppc64)     // NOTE: ppc64 is UNTESTED\n  expected = ((char**)expected)[0];         // this is \"ip\"\n#endif\n\n  if (actual < expected || actual > expected + kRoutineSize) {\n    printf(\"Test FAILED: actual PC: %p, expected PC: %p\\n\", actual, expected);\n    return 1;\n  } else {\n    printf(\"PASS\\n\");\n    return 0;\n  }\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/heap-checker-death_unittest.sh",
    "content": "#!/bin/sh\n# Copyright (c) 2005, Google Inc.\n# All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n# \n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# ---\n# Author: Maxim Lifantsev\n#\n# Run the heap checker unittest in a mode where it is supposed to crash and\n# return an error if it doesn't.\n\n# We expect BINDIR to be set in the environment.\n# If not, we set it to some reasonable value.\nBINDIR=\"${BINDIR:-.}\"\n\nif [ \"x$1\" = \"x-h\" -o \"x$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir]\"\n  echo \"       By default, unittest_dir=$BINDIR\"\n  exit 1\nfi\n\nEXE=\"${1:-$BINDIR}/heap-checker_unittest\"\nTMPDIR=\"/tmp/heap_check_death_info\"\n\nALARM() {\n  # You need perl to run pprof, so I assume it's installed\n  perl -e '\n    $timeout=$ARGV[0]; shift;\n    $retval = 255;   # the default retval, for the case where we timed out\n    eval {           # need to run in an eval-block to trigger during system()\n      local $SIG{ALRM} = sub { die \"alarm\\n\" };  # \\n is required!\n      alarm $timeout;\n      $retval = system(@ARGV);\n      # Make retval bash-style: exit status, or 128+n if terminated by signal n\n      $retval = ($retval & 127) ? (128 + $retval) : ($retval >> 8);\n      alarm 0;\n    };\n    exit $retval;  # return system()-retval, or 255 if system() never returned\n' \"$@\"\n}\n\n# $1: timeout for alarm;\n# $2: regexp of expected exit code(s);\n# $3: regexp to match a line in the output;\n# $4: regexp to not match a line in the output;\n# $5+ args to pass to $EXE\nTest() {\n  # Note: make sure these varnames don't conflict with any vars outside Test()!\n  timeout=\"$1\"\n  shift\n  expected_ec=\"$1\"\n  shift\n  expected_regexp=\"$1\"\n  shift\n  unexpected_regexp=\"$1\"\n  shift\n\n  echo -n \"Testing $EXE with $@ ... \"\n  output=\"$TMPDIR/output\"\n  ALARM $timeout env \"$@\" $EXE > \"$output\" 2>&1\n  actual_ec=$?\n  ec_ok=$(expr \"$actual_ec\" : \"$expected_ec$\" >/dev/null || echo false)\n  matches_ok=$(test -z \"$expected_regexp\" || \\\n               grep -q \"$expected_regexp\" \"$output\" || echo false)\n  negmatches_ok=$(test -z \"$unexpected_regexp\" || \\\n                  ! grep -q \"$unexpected_regexp\" \"$output\" || echo false)\n  if $ec_ok && $matches_ok && $negmatches_ok; then\n    echo \"PASS\"\n    return 0  # 0: success\n  fi\n  # If we get here, we failed.  Now we just need to report why\n  echo \"FAIL\"\n  if [ $actual_ec -eq 255 ]; then  # 255 == SIGTERM due to $ALARM\n    echo \"Test was taking unexpectedly long time to run and so we aborted it.\"\n    echo \"Try the test case manually or raise the timeout from $timeout\"\n    echo \"to distinguish test slowness from a real problem.\"\n  else\n    $ec_ok || \\\n      echo \"Wrong exit code: expected: '$expected_ec'; actual: $actual_ec\"\n    $matches_ok || \\\n      echo \"Output did not match '$expected_regexp'\"\n    $negmatches_ok || \\\n      echo \"Output unexpectedly matched '$unexpected_regexp'\"\n  fi\n  echo \"Output from failed run:\"\n  echo \"---\"\n  cat \"$output\"\n  echo \"---\"\n  return 1  # 1: failure\n}\n\nTMPDIR=/tmp/heap_check_death_info\nrm -rf $TMPDIR || exit 1\nmkdir $TMPDIR || exit 2\n\nexport HEAPCHECK=strict       # default mode\n\n# These invocations should pass (0 == PASS):\n\n# This tests that turning leak-checker off dynamically works fine\nTest 120 0 \"^PASS$\" \"\" HEAPCHECK=\"\" || exit 1\n\n# This disables threads so we can cause leaks reliably and test finding them\nTest 120 0 \"^PASS$\" \"\" HEAP_CHECKER_TEST_NO_THREADS=1 || exit 2\n\n# Test that --test_cancel_global_check works\nTest 20 0 \"Canceling .* whole-program .* leak check$\" \"\" \\\n  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 3\nTest 20 0 \"Canceling .* whole-program .* leak check$\" \"\" \\\n  HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 4\n\n# Test that very early log messages are present and controllable:\nEARLY_MSG=\"Starting tracking the heap$\"\n\nTest 60 0 \"$EARLY_MSG\" \"\" \\\n  HEAPCHECK=\"\" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \\\n  PERFTOOLS_VERBOSE=10 || exit 5\nTest 60 0 \"MemoryRegionMap Init$\" \"\" \\\n  HEAPCHECK=\"\" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \\\n  PERFTOOLS_VERBOSE=11 || exit 6\nTest 60 0 \"\" \"$EARLY_MSG\" \\\n  HEAPCHECK=\"\" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \\\n  PERFTOOLS_VERBOSE=-11 || exit 7\n\n# These invocations should fail with very high probability,\n# rather than return 0 or hang (1 == exit(1), 134 == abort(), 139 = SIGSEGV):\n\nTest 60 1 \"Exiting .* because of .* leaks$\" \"\" \\\n  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 8\nTest 60 1 \"Exiting .* because of .* leaks$\" \"\" \\\n  HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 9\n\n# Test that we produce a reasonable textual leak report.\nTest 60 1 \"MakeALeak\" \"\" \\\n          HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECK_TEST_NO_THREADS=1 \\\n  || exit 10\n\n# Test that very early log messages are present and controllable:\nTest 60 1 \"Starting tracking the heap$\" \"\" \\\n  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 PERFTOOLS_VERBOSE=10 \\\n  || exit 11\nTest 60 1 \"\" \"Starting tracking the heap\" \\\n  HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 PERFTOOLS_VERBOSE=-10 \\\n  || exit 12\n\ncd /    # so we're not in TMPDIR when we delete it\nrm -rf $TMPDIR\n\necho \"PASS\"\n\nexit 0\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/heap-checker_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Maxim Lifantsev\n//\n// Running:\n// ./heap-checker_unittest\n//\n// If the unittest crashes because it can't find pprof, try:\n// PPROF_PATH=/usr/local/someplace/bin/pprof ./heap-checker_unittest\n//\n// To test that the whole-program heap checker will actually cause a leak, try:\n// HEAPCHECK_TEST_LEAK= ./heap-checker_unittest\n// HEAPCHECK_TEST_LOOP_LEAK= ./heap-checker_unittest\n//\n// Note: Both of the above commands *should* abort with an error message.\n\n// CAVEAT: Do not use vector<> and string on-heap objects in this test,\n// otherwise the test can sometimes fail for tricky leak checks\n// when we want some allocated object not to be found live by the heap checker.\n// This can happen with memory allocators like tcmalloc that can allocate\n// heap objects back to back without any book-keeping data in between.\n// What happens is that end-of-storage pointers of a live vector\n// (or a string depending on the STL implementation used)\n// can happen to point to that other heap-allocated\n// object that is not reachable otherwise and that\n// we don't want to be reachable.\n//\n// The implication of this for real leak checking\n// is just one more chance for the liveness flood to be inexact\n// (see the comment in our .h file).\n\n#include \"config_for_unittests.h\"\n#ifdef HAVE_POLL_H\n#include <poll.h>\n#endif\n#if defined HAVE_STDINT_H\n#include <stdint.h>             // to get uint16_t (ISO naming madness)\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>           // another place uint16_t might be defined\n#endif\n#include <sys/types.h>\n#include <stdlib.h>\n#include <errno.h>              // errno\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>             // for sleep(), geteuid()\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h>\n#endif\n#include <fcntl.h>              // for open(), close()\n// FreeBSD has malloc.h, but complains if you use it\n#if defined(HAVE_MALLOC_H) && !defined(__FreeBSD__)\n#include <malloc.h>\n#endif\n\n#ifdef HAVE_EXECINFO_H\n#include <execinfo.h>           // backtrace\n#endif\n#ifdef HAVE_GRP_H\n#include <grp.h>                // getgrent, getgrnam\n#endif\n#ifdef HAVE_PWD_H\n#include <pwd.h>\n#endif\n\n#include <iostream>             // for cout\n#include <iomanip>              // for hex\n#include <set>\n#include <map>\n#include <list>\n#include <memory>\n#include <vector>\n#include <string>\n\n#include \"base/googleinit.h\"\n#include \"base/logging.h\"\n#include \"base/commandlineflags.h\"\n#include \"base/thread_lister.h\"\n#include <google/heap-checker.h>\n#include \"memory_region_map.h\"\n#include <google/malloc_extension.h>\n#include <google/stacktrace.h>\n\n// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old\n// form of the name instead.\n#ifndef MAP_ANONYMOUS\n# define MAP_ANONYMOUS MAP_ANON\n#endif\n\nusing namespace std;\n\n// ========================================================================= //\n\n// TODO(maxim): write a shell script to test that these indeed crash us\n//              (i.e. we do detect leaks)\n//              Maybe add more such crash tests.\n\nDEFINE_bool(test_leak,\n            EnvToBool(\"HEAP_CHECKER_TEST_TEST_LEAK\", false),\n            \"If should cause a leak crash\");\nDEFINE_bool(test_loop_leak,\n            EnvToBool(\"HEAP_CHECKER_TEST_TEST_LOOP_LEAK\", false),\n            \"If should cause a looped leak crash\");\nDEFINE_bool(test_register_leak,\n            EnvToBool(\"HEAP_CHECKER_TEST_TEST_REGISTER_LEAK\", false),\n            \"If should cause a leak crash by hiding a pointer \"\n            \"that is only in a register\");\nDEFINE_bool(test_cancel_global_check,\n            EnvToBool(\"HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK\", false),\n            \"If should test HeapLeakChecker::CancelGlobalCheck \"\n            \"when --test_leak or --test_loop_leak are given; \"\n            \"the test should not fail then\");\nDEFINE_bool(maybe_stripped,\n            EnvToBool(\"HEAP_CHECKER_TEST_MAYBE_STRIPPED\", true),\n            \"If we think we can be a stripped binary\");\nDEFINE_bool(interfering_threads,\n            EnvToBool(\"HEAP_CHECKER_TEST_INTERFERING_THREADS\", true),\n            \"If we should use threads trying \"\n            \"to interfere with leak checking\");\nDEFINE_bool(hoarding_threads,\n            EnvToBool(\"HEAP_CHECKER_TEST_HOARDING_THREADS\", true),\n            \"If threads (usually the manager thread) are known \"\n            \"to retain some old state in their global buffers, \"\n            \"so that it's hard to force leaks when threads are around\");\n            // TODO(maxim): Chage the default to false\n            // when the standard environment used NTPL threads:\n            // they do not seem to have this problem.\nDEFINE_bool(no_threads,\n            EnvToBool(\"HEAP_CHECKER_TEST_NO_THREADS\", false),\n            \"If we should not use any threads\");\n            // This is used so we can make can_create_leaks_reliably true\n            // for any pthread implementation and test with that.\n\nDECLARE_int64(heap_check_max_pointer_offset);   // heap-checker.cc\nDECLARE_string(heap_check);  // in heap-checker.cc\n\n#define WARN_IF(cond, msg)   LOG_IF(WARNING, cond, msg)\n\n// This is an evil macro!  Be very careful using it...\n#undef VLOG          // and we start by evilling overriding logging.h VLOG\n#define VLOG(lvl)    if (FLAGS_verbose >= (lvl))  cout << \"\\n\"\n// This is, likewise, evil\n#define LOGF         VLOG(INFO)\n\nstatic void RunHeapBusyThreads();  // below\n\n\nclass Closure {\n public:\n  virtual ~Closure() { }\n  virtual void Run() = 0;\n};\n\nclass Callback0 : public Closure {\n public:\n  typedef void (*FunctionSignature)();\n\n  inline Callback0(FunctionSignature f) : f_(f) {}\n  virtual void Run() { (*f_)(); delete this; }\n\n private:\n  FunctionSignature f_;\n};\n\ntemplate <class P1> class Callback1 : public Closure {\n public:\n  typedef void (*FunctionSignature)(P1);\n\n  inline Callback1<P1>(FunctionSignature f, P1 p1) : f_(f), p1_(p1) {}\n  virtual void Run() { (*f_)(p1_); delete this; }\n\n private:\n  FunctionSignature f_;\n  P1 p1_;\n};\n\ntemplate <class P1, class P2> class Callback2 : public Closure {\n public:\n  typedef void (*FunctionSignature)(P1,P2);\n\n  inline Callback2<P1,P2>(FunctionSignature f, P1 p1, P2 p2) : f_(f), p1_(p1), p2_(p2) {}\n  virtual void Run() { (*f_)(p1_, p2_); delete this; }\n\n private:\n  FunctionSignature f_;\n  P1 p1_;\n  P2 p2_;\n};\n\ninline Callback0* NewCallback(void (*function)()) {\n  return new Callback0(function);\n}\n\ntemplate <class P1>\ninline Callback1<P1>* NewCallback(void (*function)(P1), P1 p1) {\n  return new Callback1<P1>(function, p1);\n}\n\ntemplate <class P1, class P2>\ninline Callback2<P1,P2>* NewCallback(void (*function)(P1,P2), P1 p1, P2 p2) {\n  return new Callback2<P1,P2>(function, p1, p2);\n}\n\n\n// Set to true at end of main, so threads know.  Not entirely thread-safe!,\n// but probably good enough.\nstatic bool g_have_exited_main = false;\n\n// If we can reliably create leaks (i.e. make leaked object\n// really unreachable from any global data).\nstatic bool can_create_leaks_reliably = false;\n\n// We use a simple allocation wrapper\n// to make sure we wipe out the newly allocated objects\n// in case they still happened to contain some pointer data\n// accidentally left by the memory allocator.\nstruct Initialized { };\nstatic Initialized initialized;\nvoid* operator new(size_t size, const Initialized&) {\n  // Below we use \"p = new(initialized) Foo[1];\" and  \"delete[] p;\"\n  // instead of \"p = new(initialized) Foo;\"\n  // when we need to delete an allocated object.\n  void* p = malloc(size);\n  memset(p, 0, size);\n  return p;\n}\nvoid* operator new[](size_t size, const Initialized&) {\n  char* p = new char[size];\n  memset(p, 0, size);\n  return p;\n}\n\nstatic void DoWipeStack(int n);  // defined below\nstatic void WipeStack() { DoWipeStack(20); }\n\nstatic void Pause() {\n  poll(NULL, 0, 77);  // time for thread activity in HeapBusyThreadBody\n\n  // Indirectly test malloc_extension.*:\n  CHECK(MallocExtension::instance()->VerifyAllMemory());\n  int blocks;\n  size_t total;\n  int histogram[kMallocHistogramSize];\n  if (MallocExtension::instance()\n       ->MallocMemoryStats(&blocks, &total, histogram)  &&  total != 0) {\n    VLOG(3) << \"Malloc stats: \" << blocks << \" blocks of \"\n            << total << \" bytes\";\n    for (int i = 0; i < kMallocHistogramSize; ++i) {\n      if (histogram[i]) {\n        VLOG(3) << \"  Malloc histogram at \" << i << \" : \" << histogram[i];\n      }\n    }\n  }\n  WipeStack();  // e.g. MallocExtension::VerifyAllMemory\n                // can leave pointers to heap objects on stack\n}\n\n// Make gcc think a pointer is \"used\"\ntemplate <class T>\nstatic void Use(T** foo) {\n  VLOG(2) << \"Dummy-using \" << static_cast<void*>(*foo) << \" at \" << foo;\n}\n\n// Arbitrary value, but not such that xor'ing with it is likely\n// to map one valid pointer to another valid pointer:\nstatic const uintptr_t kHideMask =\n  static_cast<uintptr_t>(0xF03A5F7BF03A5F7BLL);\n\n// Helpers to hide a pointer from live data traversal.\n// We just xor the pointer so that (with high probability)\n// it's not a valid address of a heap object anymore.\n// Both Hide and UnHide must be executed within RunHidden() below\n// to prevent leaving stale data on active stack that can be a pointer\n// to a heap object that is not actually reachable via live variables.\n// (UnHide might leave heap pointer value for an object\n//  that will be deallocated but later another object\n//  can be allocated at the same heap address.)\ntemplate <class T>\nstatic void Hide(T** ptr) {\n  // we cast values, not dereferenced pointers, so no aliasing issues:\n  *ptr = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask);\n  VLOG(2) << \"hid: \" << static_cast<void*>(*ptr);\n}\n\ntemplate <class T>\nstatic void UnHide(T** ptr) {\n  VLOG(2) << \"unhiding: \" << static_cast<void*>(*ptr);\n  // we cast values, not dereferenced pointers, so no aliasing issues:\n  *ptr = reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask);\n}\n\nstatic void LogHidden(const char* message, const void* ptr) {\n  LOGF << message << \" : \"\n       << ptr << \" ^ \" << reinterpret_cast<void*>(kHideMask) << endl;\n}\n\n// volatile to fool the compiler against inlining the calls to these\nvoid (*volatile run_hidden_ptr)(Closure* c, int n);\nvoid (*volatile wipe_stack_ptr)(int n);\n\nstatic void DoRunHidden(Closure* c, int n) {\n  if (n) {\n    VLOG(10) << \"Level \" << n << \" at \" << &n;\n    (*run_hidden_ptr)(c, n-1);\n    (*wipe_stack_ptr)(n);\n    sleep(0);  // undo -foptimize-sibling-calls\n  } else {\n    c->Run();\n  }\n}\n\n/*static*/ void DoWipeStack(int n) {\n  VLOG(10) << \"Wipe level \" << n << \" at \" << &n;\n  if (n) {\n    const int sz = 30;\n    volatile int arr[sz];\n    for (int i = 0; i < sz; ++i) arr[i] = 0;\n    (*wipe_stack_ptr)(n-1);\n    sleep(0);  // undo -foptimize-sibling-calls\n  }\n}\n\n// This executes closure c several stack frames down from the current one\n// and then makes an effort to also wipe out the stack data that was used by\n// the closure.\n// This way we prevent leak checker from finding any temporary pointers\n// of the closure execution on the stack and deciding that\n// these pointers (and the pointed objects) are still live.\nstatic void RunHidden(Closure* c) {\n  DoRunHidden(c, 15);\n  DoWipeStack(20);\n}\n\nstatic void DoAllocHidden(size_t size, void** ptr) {\n  void* p = new(initialized) char[size];\n  Hide(&p);\n  Use(&p);  // use only hidden versions\n  VLOG(2) << \"Allocated hidden \" << p << \" at \" << &p;\n  *ptr = p;  // assign the hidden versions\n}\n\nstatic void* AllocHidden(size_t size) {\n  void* r;\n  RunHidden(NewCallback(DoAllocHidden, size, &r));\n  return r;\n}\n\nstatic void DoDeAllocHidden(void** ptr) {\n  Use(ptr);  // use only hidden versions\n  void* p = *ptr;\n  VLOG(2) << \"Deallocating hidden \" << p;\n  UnHide(&p);\n  delete [] reinterpret_cast<char*>(p);\n}\n\nstatic void DeAllocHidden(void** ptr) {\n  RunHidden(NewCallback(DoDeAllocHidden, ptr));\n  *ptr = NULL;\n  Use(ptr);\n}\n\nvoid PreventHeapReclaiming(size_t size) {\n#ifdef NDEBUG\n  if (true) {\n    static void** no_reclaim_list = NULL;\n    CHECK(size >= sizeof(void*));\n    // We can't use malloc_reclaim_memory flag in opt mode as debugallocation.cc\n    // is not used. Instead we allocate a bunch of heap objects that are\n    // of the same size as what we are going to leak to ensure that the object\n    // we are about to leak is not at the same address as some old allocated\n    // and freed object that might still have pointers leading to it.\n    for (int i = 0; i < 100; ++i) {\n      void** p = reinterpret_cast<void**>(new(initialized) char[size]);\n      p[0] = no_reclaim_list;\n      no_reclaim_list = p;\n    }\n  }\n#endif\n}\n\nstatic bool RunSilent(HeapLeakChecker* check,\n                      bool (HeapLeakChecker::* func)()) {\n  // By default, don't print the 'we detected a leak' message in the\n  // cases we're expecting a leak (we still print when --v is >= 1).\n  // This way, the logging output is less confusing: we only print\n  // \"we detected a leak\", and how to diagnose it, for *unexpected* leaks.\n  int32 old_FLAGS_verbose = FLAGS_verbose;\n  if (!VLOG_IS_ON(1))             // not on a verbose setting\n    FLAGS_verbose = FATAL;        // only log fatal errors\n  const bool retval = (check->*func)();\n  FLAGS_verbose = old_FLAGS_verbose;\n  return retval;\n}\n\n#define RUN_SILENT(check, func)  RunSilent(&(check), &HeapLeakChecker::func)\n\nenum CheckType { SAME_HEAP, NO_LEAKS };\n\nstatic void VerifyLeaks(HeapLeakChecker* check, CheckType type,\n                        int leaked_bytes, int leaked_objects) {\n  WipeStack();  // to help with can_create_leaks_reliably\n  const bool no_leaks =\n    type == NO_LEAKS ? RUN_SILENT(*check, BriefNoLeaks)\n                     : RUN_SILENT(*check, BriefSameHeap);\n  if (can_create_leaks_reliably) {\n    // these might still fail occasionally, but it should be very rare\n    CHECK_EQ(no_leaks, false);\n    CHECK_EQ(check->BytesLeaked(), leaked_bytes);\n    CHECK_EQ(check->ObjectsLeaked(), leaked_objects);\n  } else {\n    WARN_IF(no_leaks != false,\n            \"Expected leaks not found: \"\n            \"Some liveness flood must be too optimistic\");\n  }\n}\n\n// not deallocates\nstatic void TestHeapLeakCheckerDeathSimple() {\n  HeapLeakChecker check(\"death_simple\");\n  void* foo = AllocHidden(100 * sizeof(int));\n  Use(&foo);\n  void* bar = AllocHidden(300);\n  Use(&bar);\n  LogHidden(\"Leaking\", foo);\n  LogHidden(\"Leaking\", bar);\n  Pause();\n  VerifyLeaks(&check, NO_LEAKS, 300 + 100 * sizeof(int), 2);\n  DeAllocHidden(&foo);\n  DeAllocHidden(&bar);\n}\n\nstatic void MakeDeathLoop(void** arr1, void** arr2) {\n  PreventHeapReclaiming(2 * sizeof(void*));\n  void** a1 = new(initialized) void*[2];\n  void** a2 = new(initialized) void*[2];\n  a1[1] = reinterpret_cast<void*>(a2);\n  a2[1] = reinterpret_cast<void*>(a1);\n  Hide(&a1);\n  Hide(&a2);\n  Use(&a1);\n  Use(&a2);\n  VLOG(2) << \"Made hidden loop at \" << &a1 << \" to \" << arr1;\n  *arr1 = a1;\n  *arr2 = a2;\n}\n\n// not deallocates two objects linked together\nstatic void TestHeapLeakCheckerDeathLoop() {\n  HeapLeakChecker check(\"death_loop\");\n  void* arr1;\n  void* arr2;\n  RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));\n  Use(&arr1);\n  Use(&arr2);\n  LogHidden(\"Leaking\", arr1);\n  LogHidden(\"Leaking\", arr2);\n  Pause();\n  VerifyLeaks(&check, NO_LEAKS, 4 * sizeof(void*), 2);\n  DeAllocHidden(&arr1);\n  DeAllocHidden(&arr2);\n}\n\n// deallocates more than allocates\nstatic void TestHeapLeakCheckerDeathInverse() {\n  void* bar = AllocHidden(250 * sizeof(int));\n  Use(&bar);\n  LogHidden(\"Pre leaking\", bar);\n  Pause();\n  HeapLeakChecker check(\"death_inverse\");\n  void* foo = AllocHidden(100 * sizeof(int));\n  Use(&foo);\n  LogHidden(\"Leaking\", foo);\n  DeAllocHidden(&bar);\n  Pause();\n  VerifyLeaks(&check, SAME_HEAP,\n              100 * static_cast<int64>(sizeof(int)),\n              1);\n  DeAllocHidden(&foo);\n}\n\n// deallocates more than allocates\nstatic void TestHeapLeakCheckerDeathNoLeaks() {\n  void* foo = AllocHidden(100 * sizeof(int));\n  Use(&foo);\n  void* bar = AllocHidden(250 * sizeof(int));\n  Use(&bar);\n  HeapLeakChecker check(\"death_noleaks\");\n  DeAllocHidden(&bar);\n  CHECK_EQ(check.BriefNoLeaks(), true);\n  DeAllocHidden(&foo);\n}\n\n// have less objecs\nstatic void TestHeapLeakCheckerDeathCountLess() {\n  void* bar1 = AllocHidden(50 * sizeof(int));\n  Use(&bar1);\n  void* bar2 = AllocHidden(50 * sizeof(int));\n  Use(&bar2);\n  LogHidden(\"Pre leaking\", bar1);\n  LogHidden(\"Pre leaking\", bar2);\n  Pause();\n  HeapLeakChecker check(\"death_count_less\");\n  void* foo = AllocHidden(100 * sizeof(int));\n  Use(&foo);\n  LogHidden(\"Leaking\", foo);\n  DeAllocHidden(&bar1);\n  DeAllocHidden(&bar2);\n  Pause();\n  VerifyLeaks(&check, SAME_HEAP,\n              100 * sizeof(int),\n              1);\n  DeAllocHidden(&foo);\n}\n\n// have more objecs\nstatic void TestHeapLeakCheckerDeathCountMore() {\n  void* foo = AllocHidden(100 * sizeof(int));\n  Use(&foo);\n  LogHidden(\"Pre leaking\", foo);\n  Pause();\n  HeapLeakChecker check(\"death_count_more\");\n  void* bar1 = AllocHidden(50 * sizeof(int));\n  Use(&bar1);\n  void* bar2 = AllocHidden(50 * sizeof(int));\n  Use(&bar2);\n  LogHidden(\"Leaking\", bar1);\n  LogHidden(\"Leaking\", bar2);\n  DeAllocHidden(&foo);\n  Pause();\n  VerifyLeaks(&check, SAME_HEAP,\n              100 * sizeof(int),\n              2);\n  DeAllocHidden(&bar1);\n  DeAllocHidden(&bar2);\n}\n\nstatic void TestHiddenPointer() {\n  int i;\n  void* foo = &i;\n  HiddenPointer<void> p(foo);\n  CHECK_EQ(foo, p.get());\n\n  // Confirm pointer doesn't appear to contain a byte sequence\n  // that == the pointer.  We don't really need to test that\n  // the xor trick itself works, as without it nothing in this\n  // test suite would work.  See the Hide/Unhide/*Hidden* set\n  // of helper methods.\n  CHECK_NE(foo, *reinterpret_cast<void**>(&p));\n}\n\n// simple tests that deallocate what they allocated\nstatic void TestHeapLeakChecker() {\n  { HeapLeakChecker check(\"trivial\");\n    int foo = 5;\n    int* p = &foo;\n    Use(&p);\n    Pause();\n    CHECK(check.BriefSameHeap());\n  }\n  Pause();\n  { HeapLeakChecker check(\"simple\");\n    void* foo = AllocHidden(100 * sizeof(int));\n    Use(&foo);\n    void* bar = AllocHidden(200 * sizeof(int));\n    Use(&bar);\n    DeAllocHidden(&foo);\n    DeAllocHidden(&bar);\n    Pause();\n    CHECK(check.BriefSameHeap());\n  }\n}\n\n// no false positives\nstatic void TestHeapLeakCheckerNoFalsePositives() {\n  { HeapLeakChecker check(\"trivial_p\");\n    int foo = 5;\n    int* p = &foo;\n    Use(&p);\n    Pause();\n    CHECK(check.BriefSameHeap());\n  }\n  Pause();\n  { HeapLeakChecker check(\"simple_p\");\n    void* foo = AllocHidden(100 * sizeof(int));\n    Use(&foo);\n    void* bar = AllocHidden(200 * sizeof(int));\n    Use(&bar);\n    DeAllocHidden(&foo);\n    DeAllocHidden(&bar);\n    Pause();\n    CHECK(check.SameHeap());\n  }\n}\n\n// test that we detect leaks when we have same total # of bytes and\n// objects, but different individual object sizes\nstatic void TestLeakButTotalsMatch() {\n  void* bar1 = AllocHidden(240 * sizeof(int));\n  Use(&bar1);\n  void* bar2 = AllocHidden(160 * sizeof(int));\n  Use(&bar2);\n  LogHidden(\"Pre leaking\", bar1);\n  LogHidden(\"Pre leaking\", bar2);\n  Pause();\n  HeapLeakChecker check(\"trick\");\n  void* foo1 = AllocHidden(280 * sizeof(int));\n  Use(&foo1);\n  void* foo2 = AllocHidden(120 * sizeof(int));\n  Use(&foo2);\n  LogHidden(\"Leaking\", foo1);\n  LogHidden(\"Leaking\", foo2);\n  DeAllocHidden(&bar1);\n  DeAllocHidden(&bar2);\n  Pause();\n\n  // foo1 and foo2 leaked\n  VerifyLeaks(&check, NO_LEAKS, (280+120)*sizeof(int), 2);\n\n  DeAllocHidden(&foo1);\n  DeAllocHidden(&foo2);\n}\n\n// no false negatives from pprof\nstatic void TestHeapLeakCheckerDeathTrick() {\n  void* bar1 = AllocHidden(240 * sizeof(int));\n  Use(&bar1);\n  void* bar2 = AllocHidden(160 * sizeof(int));\n  Use(&bar2);\n  HeapLeakChecker check(\"death_trick\");\n  DeAllocHidden(&bar1);\n  DeAllocHidden(&bar2);\n  void* foo1 = AllocHidden(280 * sizeof(int));\n  Use(&foo1);\n  void* foo2 = AllocHidden(120 * sizeof(int));\n  Use(&foo2);\n  // TODO(maxim): use the above if we make pprof work in automated test runs\n  if (!FLAGS_maybe_stripped) {\n    CHECK_EQ(RUN_SILENT(check, SameHeap), false);\n      // pprof checking should catch the leak\n  } else {\n    WARN_IF(RUN_SILENT(check, SameHeap) != false,\n            \"death_trick leak is not caught; \"\n            \"we must be using a stripped binary\");\n  }\n  DeAllocHidden(&foo1);\n  DeAllocHidden(&foo2);\n}\n\n// simple leak\nstatic void TransLeaks() {\n  AllocHidden(1 * sizeof(char));\n}\n\n// range-based disabling using Disabler\nstatic void ScopedDisabledLeaks() {\n  HeapLeakChecker::Disabler disabler;\n  AllocHidden(3 * sizeof(int));\n  TransLeaks();\n  malloc(10);  // Direct leak\n}\n\n// have different disabled leaks\nstatic void* RunDisabledLeaks(void* a) {\n  ScopedDisabledLeaks();\n  return a;\n}\n\n// have different disabled leaks inside of a thread\nstatic void ThreadDisabledLeaks() {\n  if (FLAGS_no_threads)  return;\n  pthread_t tid;\n  pthread_attr_t attr;\n  CHECK_EQ(pthread_attr_init(&attr), 0);\n  CHECK_EQ(pthread_create(&tid, &attr, RunDisabledLeaks, NULL), 0);\n  void* res;\n  CHECK_EQ(pthread_join(tid, &res), 0);\n}\n\n// different disabled leaks (some in threads)\nstatic void TestHeapLeakCheckerDisabling() {\n  HeapLeakChecker check(\"disabling\");\n\n  RunDisabledLeaks(NULL);\n  RunDisabledLeaks(NULL);\n  ThreadDisabledLeaks();\n  RunDisabledLeaks(NULL);\n  ThreadDisabledLeaks();\n  ThreadDisabledLeaks();\n\n  Pause();\n\n  CHECK(check.SameHeap());\n}\n\ntypedef set<int> IntSet;\n\nstatic int some_ints[] = { 1, 2, 3, 21, 22, 23, 24, 25 };\n\nstatic void DoTestSTLAlloc() {\n  IntSet* x = new(initialized) IntSet[1];\n  *x = IntSet(some_ints, some_ints + 6);\n  for (int i = 0; i < 1000; i++) {\n    x->insert(i*3);\n  }\n  delete [] x;\n}\n\n// Check that normal STL usage does not result in a leak report.\n// (In particular we test that there's no complex STL's own allocator\n// running on top of our allocator with hooks to heap profiler\n// that can result in false leak report in this case.)\nstatic void TestSTLAlloc() {\n  HeapLeakChecker check(\"stl\");\n  RunHidden(NewCallback(DoTestSTLAlloc));\n  CHECK_EQ(check.BriefSameHeap(), true);\n}\n\nstatic void DoTestSTLAllocInverse(IntSet** setx) {\n  IntSet* x = new(initialized) IntSet[1];\n  *x = IntSet(some_ints, some_ints + 3);\n  for (int i = 0; i < 100; i++) {\n    x->insert(i*2);\n  }\n  Hide(&x);\n  *setx = x;\n}\n\nstatic void FreeTestSTLAllocInverse(IntSet** setx) {\n  IntSet* x = *setx;\n  UnHide(&x);\n  delete [] x;\n}\n\n// Check that normal leaked STL usage *does* result in a leak report.\n// (In particular we test that there's no complex STL's own allocator\n// running on top of our allocator with hooks to heap profiler\n// that can result in false absence of leak report in this case.)\nstatic void TestSTLAllocInverse() {\n  HeapLeakChecker check(\"death_inverse_stl\");\n  IntSet* x;\n  RunHidden(NewCallback(DoTestSTLAllocInverse, &x));\n  LogHidden(\"Leaking\", x);\n  if (can_create_leaks_reliably) {\n    WipeStack();  // to help with can_create_leaks_reliably\n    // these might still fail occasionally, but it should be very rare\n    CHECK_EQ(RUN_SILENT(check, BriefNoLeaks), false);\n    CHECK_GE(check.BytesLeaked(), 100 * sizeof(int));\n    CHECK_GE(check.ObjectsLeaked(), 100);\n      // assumes set<>s are represented by some kind of binary tree\n      // or something else allocating >=1 heap object per set object\n  } else {\n    WARN_IF(RUN_SILENT(check, BriefNoLeaks) != false,\n            \"Expected leaks not found: \"\n            \"Some liveness flood must be too optimistic\");\n  }\n  RunHidden(NewCallback(FreeTestSTLAllocInverse, &x));\n}\n\ntemplate<class Alloc>\nstatic void DirectTestSTLAlloc(Alloc allocator, const char* name) {\n  HeapLeakChecker check((string(\"direct_stl-\") + name).c_str());\n  static const int kSize = 1000;\n  typename Alloc::pointer ptrs[kSize];\n  for (int i = 0; i < kSize; ++i) {\n    typename Alloc::pointer p = allocator.allocate(i*3+1);\n    HeapLeakChecker::IgnoreObject(p);\n    // This will crash if p is not known to heap profiler:\n    // (i.e. STL's \"allocator\" does not have a direct hook to heap profiler)\n    HeapLeakChecker::UnIgnoreObject(p);\n    ptrs[i] = p;\n  }\n  for (int i = 0; i < kSize; ++i) {\n    allocator.deallocate(ptrs[i], i*3+1);\n    ptrs[i] = NULL;\n  }\n  CHECK(check.BriefSameHeap());  // just in case\n}\n\nstatic struct group* grp = NULL;\nstatic const int kKeys = 50;\nstatic pthread_key_t key[kKeys];\n\nstatic void KeyFree(void* ptr) {\n  delete [] reinterpret_cast<char*>(ptr);\n}\n\nstatic bool key_init_has_run = false;\n\nstatic void KeyInit() {\n  for (int i = 0; i < kKeys; ++i) {\n    CHECK_EQ(pthread_key_create(&key[i], KeyFree), 0);\n    VLOG(2) << \"pthread key \" << i << \" : \" << key[i];\n  }\n  key_init_has_run = true;   // needed for a sanity-check\n}\n\n// force various C library static and thread-specific allocations\nstatic void TestLibCAllocate() {\n  CHECK(key_init_has_run);\n  for (int i = 0; i < kKeys; ++i) {\n    void* p = pthread_getspecific(key[i]);\n    if (NULL == p) {\n      if (i == 0) {\n        // Test-logging inside threads which (potentially) creates and uses\n        // thread-local data inside standard C++ library:\n        VLOG(0) << \"Adding pthread-specifics for thread \" << pthread_self()\n                << \" pid \" << getpid();\n      }\n      p = new(initialized) char[77 + i];\n      VLOG(2) << \"pthread specific \" << i << \" : \" << p;\n      pthread_setspecific(key[i], p);\n    }\n  }\n\n  strerror(errno);\n  const time_t now = time(NULL);\n  ctime(&now);\n#ifdef HAVE_EXECINFO_H\n  void *stack[1];\n  backtrace(stack, 1);\n#endif\n#ifdef HAVE_GRP_H\n  gid_t gid = getgid();\n  getgrgid(gid);\n  if (grp == NULL)  grp = getgrent();  // a race condition here is okay\n  getgrnam(grp->gr_name);\n#endif\n#ifdef HAVE_PWD_H\n  getpwuid(geteuid());\n#endif\n}\n\n// Continuous random heap memory activity to try to disrupt heap checking.\nstatic void* HeapBusyThreadBody(void* a) {\n  const int thread_num = reinterpret_cast<intptr_t>(a);\n  VLOG(0) << \"A new HeapBusyThread \" << thread_num;\n  TestLibCAllocate();\n\n  int user = 0;\n  // Try to hide ptr from heap checker in a CPU register:\n  // Here we are just making a best effort to put the only pointer\n  // to a heap object into a thread register to test\n  // the thread-register finding machinery in the heap checker.\n#if defined(__i386__) && defined(__GNUC__)\n  register int** ptr asm(\"esi\");\n#elif defined(__x86_64__) && defined(__GNUC__)\n  register int** ptr asm(\"r15\");\n#else\n  register int** ptr;\n#endif\n  ptr = NULL;\n  typedef set<int> Set;\n  Set s1;\n  while (1) {\n    // TestLibCAllocate() calls libc functions that don't work so well\n    // after main() has exited.  So we just don't do the test then.\n    if (!g_have_exited_main)\n      TestLibCAllocate();\n\n    if (ptr == NULL) {\n      ptr = new(initialized) int*[1];\n      *ptr = new(initialized) int[1];\n    }\n    set<int>* s2 = new(initialized) set<int>[1];\n    s1.insert(random());\n    s2->insert(*s1.begin());\n    user += *s2->begin();\n    **ptr += user;\n    if (random() % 51 == 0) {\n      s1.clear();\n      if (random() % 2 == 0) {\n        s1.~Set();\n        new(&s1) Set;\n      }\n    }\n    VLOG(3) << pthread_self() << \" (\" << getpid() << \"): in wait: \"\n            << ptr << \", \" << *ptr << \"; \" << s1.size();\n    VLOG(2) << pthread_self() << \" (\" << getpid() << \"): in wait, ptr = \"\n            << reinterpret_cast<void*>(\n                 reinterpret_cast<uintptr_t>(ptr) ^ kHideMask)\n            << \"^\" << reinterpret_cast<void*>(kHideMask);\n    if (FLAGS_test_register_leak  &&  thread_num % 5 == 0) {\n      // Hide the register \"ptr\" value with an xor mask.\n      // If one provides --test_register_leak flag, the test should\n      // (with very high probability) crash on some leak check\n      // with a leak report (of some x * sizeof(int) + y * sizeof(int*) bytes)\n      // pointing at the two lines above in this function\n      // with \"new(initialized) int\" in them as the allocators\n      // of the leaked objects.\n      // CAVEAT: We can't really prevent a compiler to save some\n      // temporary values of \"ptr\" on the stack and thus let us find\n      // the heap objects not via the register.\n      // Hence it's normal if for certain compilers or optimization modes\n      // --test_register_leak does not cause a leak crash of the above form\n      // (this happens e.g. for gcc 4.0.1 in opt mode).\n      ptr = reinterpret_cast<int **>(\n          reinterpret_cast<uintptr_t>(ptr) ^ kHideMask);\n      // busy loop to get the thread interrupted at:\n      for (int i = 1; i < 10000000; ++i)  user += (1 + user * user * 5) / i;\n      ptr = reinterpret_cast<int **>(\n          reinterpret_cast<uintptr_t>(ptr) ^ kHideMask);\n    } else {\n      poll(NULL, 0, random() % 100);\n    }\n    VLOG(2) << pthread_self() << \": continuing\";\n    if (random() % 3 == 0) {\n      delete [] *ptr;\n      delete [] ptr;\n      ptr = NULL;\n    }\n    delete [] s2;\n  }\n  return a;\n}\n\nstatic void RunHeapBusyThreads() {\n  KeyInit();\n  if (!FLAGS_interfering_threads || FLAGS_no_threads)  return;\n\n  const int n = 17;  // make many threads\n\n  pthread_t tid;\n  pthread_attr_t attr;\n  CHECK_EQ(pthread_attr_init(&attr), 0);\n  // make them and let them run\n  for (int i = 0; i < n; ++i) {\n    VLOG(0) << \"Creating extra thread \" << i + 1;\n    CHECK(pthread_create(&tid, &attr, HeapBusyThreadBody,\n                         reinterpret_cast<void*>(i)) == 0);\n  }\n\n  Pause();\n  Pause();\n}\n\n// ========================================================================= //\n\n// This code section is to test that objects that are reachable from global\n// variables are not reported as leaks\n// as well as that (Un)IgnoreObject work for such objects fine.\n\n// An object making functions:\n// returns a \"weird\" pointer to a new object for which\n// it's worth checking that the object is reachable via that pointer.\ntypedef void* (*ObjMakerFunc)();\nstatic list<ObjMakerFunc> obj_makers;  // list of registered object makers\n\n// Helper macro to register an object making function\n// 'name' is an identifier of this object maker,\n// 'body' is its function body that must declare\n//        pointer 'p' to the nex object to return.\n// Usage example:\n//   REGISTER_OBJ_MAKER(trivial, int* p = new(initialized) int;)\n#define REGISTER_OBJ_MAKER(name, body) \\\n  void* ObjMaker_##name##_() { \\\n    VLOG(1) << \"Obj making \" << #name; \\\n    body; \\\n    return p; \\\n  } \\\n  static ObjMakerRegistrar maker_reg_##name##__(&ObjMaker_##name##_);\n// helper class for REGISTER_OBJ_MAKER\nstruct ObjMakerRegistrar {\n  ObjMakerRegistrar(ObjMakerFunc obj_maker) { obj_makers.push_back(obj_maker); }\n};\n\n// List of the objects/pointers made with all the obj_makers\n// to test reachability via global data pointers during leak checks.\nstatic list<void*>* live_objects = new list<void*>;\n  // pointer so that it does not get destructed on exit\n\n// Exerciser for one ObjMakerFunc.\nstatic void TestPointerReach(ObjMakerFunc obj_maker) {\n  HeapLeakChecker::IgnoreObject(obj_maker());  // test IgnoreObject\n\n  void* obj = obj_maker();\n  HeapLeakChecker::IgnoreObject(obj);\n  HeapLeakChecker::UnIgnoreObject(obj);  // test UnIgnoreObject\n  HeapLeakChecker::IgnoreObject(obj);  // not to need deletion for obj\n\n  live_objects->push_back(obj_maker());  // test reachability at leak check\n}\n\n// Test all ObjMakerFunc registred via REGISTER_OBJ_MAKER.\nstatic void TestObjMakers() {\n  for (list<ObjMakerFunc>::const_iterator i = obj_makers.begin();\n       i != obj_makers.end(); ++i) {\n    TestPointerReach(*i);\n    TestPointerReach(*i);  // a couple more times would not hurt\n    TestPointerReach(*i);\n  }\n}\n\n// A dummy class to mimic allocation behavior of string-s.\ntemplate<class T>\nstruct Array {\n  Array() {\n    size = 3 + random() % 30;\n    ptr = new(initialized) T[size];\n  }\n  ~Array() { delete [] ptr; }\n  Array(const Array& x) {\n    size = x.size;\n    ptr = new(initialized) T[size];\n    for (size_t i = 0; i < size; ++i) {\n      ptr[i] = x.ptr[i];\n    }\n  }\n  void operator=(const Array& x) {\n    delete [] ptr;\n    size = x.size;\n    ptr = new(initialized) T[size];\n    for (size_t i = 0; i < size; ++i) {\n      ptr[i] = x.ptr[i];\n    }\n  }\n  void append(const Array& x) {\n    T* p = new(initialized) T[size + x.size];\n    for (size_t i = 0; i < size; ++i) {\n      p[i] = ptr[i];\n    }\n    for (size_t i = 0; i < x.size; ++i) {\n      p[size+i] = x.ptr[i];\n    }\n    size += x.size;\n    delete [] ptr;\n    ptr = p;\n  }\n private:\n  size_t size;\n  T* ptr;\n};\n\n// to test pointers to objects, built-in arrays, string, etc:\nREGISTER_OBJ_MAKER(plain, int* p = new(initialized) int;)\nREGISTER_OBJ_MAKER(int_array_1, int* p = new(initialized) int[1];)\nREGISTER_OBJ_MAKER(int_array, int* p = new(initialized) int[10];)\nREGISTER_OBJ_MAKER(string, Array<char>* p = new(initialized) Array<char>();)\nREGISTER_OBJ_MAKER(string_array,\n                   Array<char>* p = new(initialized) Array<char>[5];)\nREGISTER_OBJ_MAKER(char_array, char* p = new(initialized) char[5];)\nREGISTER_OBJ_MAKER(appended_string,\n  Array<char>* p = new Array<char>();\n  p->append(Array<char>());\n)\nREGISTER_OBJ_MAKER(plain_ptr, int** p = new(initialized) int*;)\nREGISTER_OBJ_MAKER(linking_ptr,\n  int** p = new(initialized) int*;\n  *p = new(initialized) int;\n)\n\n// small objects:\nREGISTER_OBJ_MAKER(0_sized, void* p = malloc(0);)  // 0-sized object (important)\nREGISTER_OBJ_MAKER(1_sized, void* p = malloc(1);)\nREGISTER_OBJ_MAKER(2_sized, void* p = malloc(2);)\nREGISTER_OBJ_MAKER(3_sized, void* p = malloc(3);)\nREGISTER_OBJ_MAKER(4_sized, void* p = malloc(4);)\n\nstatic int set_data[] = { 1, 2, 3, 4, 5, 6, 7, 21, 22, 23, 24, 25, 26, 27 };\nstatic set<int> live_leak_set(set_data, set_data+7);\nstatic const set<int> live_leak_const_set(set_data, set_data+14);\n\nREGISTER_OBJ_MAKER(set,\n  set<int>* p = new(initialized) set<int>(set_data, set_data + 13);\n)\n\nclass ClassA {\n public:\n  explicit ClassA(int a) : ptr(NULL) { }\n  mutable char* ptr;\n};\nstatic const ClassA live_leak_mutable(1);\n\ntemplate<class C>\nclass TClass {\n public:\n  explicit TClass(int a) : ptr(NULL) { }\n  mutable C val;\n  mutable C* ptr;\n};\nstatic const TClass<Array<char> > live_leak_templ_mutable(1);\n\nclass ClassB {\n public:\n  ClassB() { }\n  char b[7];\n  virtual void f() { }\n  virtual ~ClassB() { }\n};\n\nclass ClassB2 {\n public:\n  ClassB2() { }\n  char b2[11];\n  virtual void f2() { }\n  virtual ~ClassB2() { }\n};\n\nclass ClassD1 : public ClassB {\n  char d1[15];\n  virtual void f() { }\n};\n\nclass ClassD2 : public ClassB2 {\n  char d2[19];\n  virtual void f2() { }\n};\n\nclass ClassD : public ClassD1, public ClassD2 {\n  char d[3];\n  virtual void f() { }\n  virtual void f2() { }\n};\n\n// to test pointers to objects of base subclasses:\n\nREGISTER_OBJ_MAKER(B,  ClassB*  p = new(initialized) ClassB;)\nREGISTER_OBJ_MAKER(D1, ClassD1* p = new(initialized) ClassD1;)\nREGISTER_OBJ_MAKER(D2, ClassD2* p = new(initialized) ClassD2;)\nREGISTER_OBJ_MAKER(D,  ClassD*  p = new(initialized) ClassD;)\n\nREGISTER_OBJ_MAKER(D1_as_B,  ClassB*  p = new(initialized) ClassD1;)\nREGISTER_OBJ_MAKER(D2_as_B2, ClassB2* p = new(initialized) ClassD2;)\nREGISTER_OBJ_MAKER(D_as_B,   ClassB*  p = new(initialized)  ClassD;)\nREGISTER_OBJ_MAKER(D_as_D1,  ClassD1* p = new(initialized) ClassD;)\n// inside-object pointers:\nREGISTER_OBJ_MAKER(D_as_B2,  ClassB2* p = new(initialized) ClassD;)\nREGISTER_OBJ_MAKER(D_as_D2,  ClassD2* p = new(initialized) ClassD;)\n\nclass InterfaceA {\n public:\n  virtual void A() = 0;\n  virtual ~InterfaceA() { }\n protected:\n  InterfaceA() { }\n};\n\nclass InterfaceB {\n public:\n  virtual void B() = 0;\n  virtual ~InterfaceB() { }\n protected:\n  InterfaceB() { }\n};\n\nclass InterfaceC : public InterfaceA {\n public:\n  virtual void C() = 0;\n  virtual ~InterfaceC() { }\n protected:\n  InterfaceC() { }\n};\n\nclass ClassMltD1 : public ClassB, public InterfaceB, public InterfaceC {\n public:\n  char d1[11];\n  virtual void f() { }\n  virtual void A() { }\n  virtual void B() { }\n  virtual void C() { }\n};\n\nclass ClassMltD2 : public InterfaceA, public InterfaceB, public ClassB {\n public:\n  char d2[15];\n  virtual void f() { }\n  virtual void A() { }\n  virtual void B() { }\n};\n\n// to specifically test heap reachability under\n// inerface-only multiple inheritance (some use inside-object pointers):\nREGISTER_OBJ_MAKER(MltD1,       ClassMltD1* p = new(initialized) ClassMltD1;)\nREGISTER_OBJ_MAKER(MltD1_as_B,  ClassB*     p = new(initialized) ClassMltD1;)\nREGISTER_OBJ_MAKER(MltD1_as_IA, InterfaceA* p = new(initialized) ClassMltD1;)\nREGISTER_OBJ_MAKER(MltD1_as_IB, InterfaceB* p = new(initialized) ClassMltD1;)\nREGISTER_OBJ_MAKER(MltD1_as_IC, InterfaceC* p = new(initialized) ClassMltD1;)\n\nREGISTER_OBJ_MAKER(MltD2,       ClassMltD2* p = new(initialized) ClassMltD2;)\nREGISTER_OBJ_MAKER(MltD2_as_B,  ClassB*     p = new(initialized) ClassMltD2;)\nREGISTER_OBJ_MAKER(MltD2_as_IA, InterfaceA* p = new(initialized) ClassMltD2;)\nREGISTER_OBJ_MAKER(MltD2_as_IB, InterfaceB* p = new(initialized) ClassMltD2;)\n\n// to mimic UnicodeString defined in third_party/icu,\n// which store a platform-independent-sized refcount in the first\n// few bytes and keeps a pointer pointing behind the refcount.\nREGISTER_OBJ_MAKER(unicode_string,\n  char* p = new char[sizeof(uint32) * 10];\n  p += sizeof(uint32);\n)\n// similar, but for platform-dependent-sized refcount\nREGISTER_OBJ_MAKER(ref_counted,\n  char* p = new char[sizeof(int) * 20];\n  p += sizeof(int);\n)\n\nstruct Nesting {\n  struct Inner {\n    Nesting* parent;\n    Inner(Nesting* p) : parent(p) {}\n  };\n  Inner i0;\n  char n1[5];\n  Inner i1;\n  char n2[11];\n  Inner i2;\n  char n3[27];\n  Inner i3;\n  Nesting() : i0(this), i1(this), i2(this), i3(this) {}\n};\n\n// to test inside-object pointers pointing at objects nested into heap objects:\nREGISTER_OBJ_MAKER(nesting_i0, Nesting::Inner* p = &((new Nesting())->i0);)\nREGISTER_OBJ_MAKER(nesting_i1, Nesting::Inner* p = &((new Nesting())->i1);)\nREGISTER_OBJ_MAKER(nesting_i2, Nesting::Inner* p = &((new Nesting())->i2);)\nREGISTER_OBJ_MAKER(nesting_i3, Nesting::Inner* p = &((new Nesting())->i3);)\n\n// allocate many objects reachable from global data\nstatic void TestHeapLeakCheckerLiveness() {\n  live_leak_mutable.ptr = new(initialized) char[77];\n  live_leak_templ_mutable.ptr = new(initialized) Array<char>();\n  live_leak_templ_mutable.val = Array<char>();\n\n  TestObjMakers();\n}\n\n// ========================================================================= //\n\n// Get address (PC value) following the mmap call into addr_after_mmap_call\nstatic void* Mmapper(uintptr_t* addr_after_mmap_call) {\n  void* r = mmap(NULL, 100, PROT_READ|PROT_WRITE,\n                 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n  // Get current PC value into addr_after_mmap_call\n  void* stack[1];\n  CHECK_EQ(GetStackTrace(stack, 1, 0), 1);\n  *addr_after_mmap_call = reinterpret_cast<uintptr_t>(stack[0]);\n  sleep(0);  // undo -foptimize-sibling-calls\n  return r;\n}\n\n// to trick complier into preventing inlining\nstatic void* (*mmapper_addr)(uintptr_t* addr) = &Mmapper;\n\n// TODO(maxim): copy/move this to memory_region_map_unittest\n// TODO(maxim): expand this test to include mmap64, mremap and sbrk calls.\nstatic void VerifyMemoryRegionMapStackGet() {\n  uintptr_t caller_addr_limit;\n  void* addr = (*mmapper_addr)(&caller_addr_limit);\n  uintptr_t caller = 0;\n  { MemoryRegionMap::LockHolder l;\n    for (MemoryRegionMap::RegionIterator\n           i = MemoryRegionMap::BeginRegionLocked();\n           i != MemoryRegionMap::EndRegionLocked(); ++i) {\n      if (i->start_addr == reinterpret_cast<uintptr_t>(addr)) {\n        CHECK_EQ(caller, 0);\n        caller = i->caller();\n      }\n    }\n  }\n  // caller must point into Mmapper function:\n  if (!(reinterpret_cast<uintptr_t>(mmapper_addr) <= caller  &&\n        caller < caller_addr_limit)) {\n    LOGF << std::hex << \"0x\" << caller\n         << \" does not seem to point into code of function Mmapper at \"\n         << \"0x\" << reinterpret_cast<uintptr_t>(mmapper_addr)\n         << \"! Stack frame collection must be off in MemoryRegionMap!\";\n    LOG(FATAL, \"\\n\");\n  }\n  munmap(addr, 100);\n}\n\nstatic void* Mallocer(uintptr_t* addr_after_malloc_call) {\n  void* r = malloc(100);\n  sleep(0);  // undo -foptimize-sibling-calls\n  // Get current PC value into addr_after_malloc_call\n  void* stack[1];\n  CHECK_EQ(GetStackTrace(stack, 1, 0), 1);\n  *addr_after_malloc_call = reinterpret_cast<uintptr_t>(stack[0]);\n  return r;\n}\n\n// to trick complier into preventing inlining\nstatic void* (*mallocer_addr)(uintptr_t* addr) = &Mallocer;\n\n// non-static for friendship with HeapProfiler\n// TODO(maxim): expand this test to include\n// realloc, calloc, memalign, valloc, pvalloc, new, and new[].\nextern void VerifyHeapProfileTableStackGet() {\n  uintptr_t caller_addr_limit;\n  void* addr = (*mallocer_addr)(&caller_addr_limit);\n  uintptr_t caller =\n    reinterpret_cast<uintptr_t>(HeapLeakChecker::GetAllocCaller(addr));\n  // caller must point into Mallocer function:\n  if (!(reinterpret_cast<uintptr_t>(mallocer_addr) <= caller  &&\n        caller < caller_addr_limit)) {\n    LOGF << std::hex << \"0x\" << caller\n         << \" does not seem to point into code of function Mallocer at \"\n         << \"0x\" << reinterpret_cast<uintptr_t>(mallocer_addr)\n         << \"! Stack frame collection must be off in heap profiler!\";\n    LOG(FATAL, \"\\n\");\n  }\n  free(addr);\n}\n\n// ========================================================================= //\n\nstatic void MakeALeak(void** arr) {\n  PreventHeapReclaiming(10 * sizeof(int));\n  void* a = new(initialized) int[10];\n  Hide(&a);\n  *arr = a;\n}\n\n// Helper to do 'return 0;' inside main(): insted we do 'return Pass();'\nstatic int Pass() {\n  fprintf(stdout, \"PASS\\n\");\n  g_have_exited_main = true;\n  return 0;\n}\n\nint main(int argc, char** argv) {\n  run_hidden_ptr = DoRunHidden;\n  wipe_stack_ptr = DoWipeStack;\n  if (!HeapLeakChecker::IsActive()) {\n    CHECK_EQ(FLAGS_heap_check, \"\");\n    LOG(WARNING, \"HeapLeakChecker got turned off; we won't test much...\");\n  } else {\n    VerifyMemoryRegionMapStackGet();\n    VerifyHeapProfileTableStackGet();\n  }\n\n  KeyInit();\n\n  // glibc 2.4, on x86_64 at least, has a lock-ordering bug, which\n  // means deadlock is possible when one thread calls dl_open at the\n  // same time another thread is calling dl_iterate_phdr.  libunwind\n  // calls dl_iterate_phdr, and TestLibCAllocate calls dl_open (or the\n  // various syscalls in it do), at least the first time it's run.\n  // To avoid the deadlock, we run TestLibCAllocate once before getting\n  // multi-threaded.\n  // TODO(csilvers): once libc is fixed, or libunwind can work around it,\n  //                 get rid of this early call.  We *want* our test to\n  //                 find potential problems like this one!\n  TestLibCAllocate();\n\n  if (FLAGS_interfering_threads) {\n    RunHeapBusyThreads();  // add interference early\n  }\n  TestLibCAllocate();\n\n  LOGF << \"In main(): heap_check=\" << FLAGS_heap_check << endl;\n\n  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good\n\n  if (FLAGS_test_leak) {\n    void* arr;\n    RunHidden(NewCallback(MakeALeak, &arr));\n    Use(&arr);\n    LogHidden(\"Leaking\", arr);\n    if (FLAGS_test_cancel_global_check)  HeapLeakChecker::CancelGlobalCheck();\n    return Pass();\n      // whole-program leak-check should (with very high probability)\n      // catch the leak of arr (10 * sizeof(int) bytes)\n      // (when !FLAGS_test_cancel_global_check)\n  }\n\n  if (FLAGS_test_loop_leak) {\n    void* arr1;\n    void* arr2;\n    RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));\n    Use(&arr1);\n    Use(&arr2);\n    LogHidden(\"Loop leaking\", arr1);\n    LogHidden(\"Loop leaking\", arr2);\n    if (FLAGS_test_cancel_global_check)  HeapLeakChecker::CancelGlobalCheck();\n    return Pass();\n      // whole-program leak-check should (with very high probability)\n      // catch the leak of arr1 and arr2 (4 * sizeof(void*) bytes)\n      // (when !FLAGS_test_cancel_global_check)\n  }\n\n  if (FLAGS_test_register_leak) {\n    // make us fail only where the .sh test expects:\n    Pause();\n    for (int i = 0; i < 100; ++i) {  // give it some time to crash\n      CHECK(HeapLeakChecker::NoGlobalLeaks());\n      Pause();\n    }\n    return Pass();\n  }\n\n  TestHeapLeakCheckerLiveness();\n\n  HeapLeakChecker heap_check(\"all\");\n\n  TestHiddenPointer();\n\n  TestHeapLeakChecker();\n  Pause();\n  TestLeakButTotalsMatch();\n  Pause();\n\n  TestHeapLeakCheckerDeathSimple();\n  Pause();\n  TestHeapLeakCheckerDeathLoop();\n  Pause();\n  TestHeapLeakCheckerDeathInverse();\n  Pause();\n  TestHeapLeakCheckerDeathNoLeaks();\n  Pause();\n  TestHeapLeakCheckerDeathCountLess();\n  Pause();\n  TestHeapLeakCheckerDeathCountMore();\n  Pause();\n\n  TestHeapLeakCheckerDeathTrick();\n  Pause();\n\n  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good\n\n  TestHeapLeakCheckerNoFalsePositives();\n  Pause();\n\n  TestHeapLeakCheckerDisabling();\n  Pause();\n\n  TestSTLAlloc();\n  Pause();\n  TestSTLAllocInverse();\n  Pause();\n\n  // Test that various STL allocators work.  Some of these are redundant, but\n  // we don't know how STL might change in the future.  For example,\n  // http://wiki/Main/StringNeStdString.\n#define DTSL(a) { DirectTestSTLAlloc(a, #a); \\\n                  Pause(); }\n  DTSL(std::allocator<char>());\n  DTSL(std::allocator<int>());\n  DTSL(std::string().get_allocator());\n  DTSL(string().get_allocator());\n  DTSL(vector<int>().get_allocator());\n  DTSL(vector<double>().get_allocator());\n  DTSL(vector<vector<int> >().get_allocator());\n  DTSL(vector<string>().get_allocator());\n  DTSL((map<string, string>().get_allocator()));\n  DTSL((map<string, int>().get_allocator()));\n  DTSL(set<char>().get_allocator());\n#undef DTSL\n\n  TestLibCAllocate();\n  Pause();\n\n  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good\n\n  Pause();\n\n  if (!FLAGS_maybe_stripped) {\n    CHECK(heap_check.SameHeap());\n  } else {\n    WARN_IF(heap_check.SameHeap() != true,\n            \"overall leaks are caught; we must be using a stripped binary\");\n  }\n\n  CHECK(HeapLeakChecker::NoGlobalLeaks());  // so far, so good\n\n  return Pass();\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/heap-checker_unittest.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2005, Google Inc.\n# All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n# \n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# ---\n# Author: Craig Silverstein\n#\n# Runs the heap-checker unittest with various environment variables.\n# This is necessary because we turn on features like the heap profiler\n# and heap checker via environment variables.  This test makes sure\n# they all play well together.\n\n# We expect BINDIR and PPROF_PATH to be set in the environment.\n# If not, we set them to some reasonable values\nBINDIR=\"${BINDIR:-.}\"\nPPROF_PATH=\"${PPROF_PATH:-$BINDIR/src/pprof}\"\n\nif [ \"x$1\" = \"x-h\" -o \"$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir] [path to pprof]\"\n  echo \"       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH\"\n  exit 1\nfi\n\nHEAP_CHECKER=\"${1:-$BINDIR}/heap-checker_unittest\"\nPPROF_PATH=\"${2:-$PPROF_PATH}\"\n\nTMPDIR=/tmp/heap_check_info\nrm -rf $TMPDIR || exit 2\nmkdir $TMPDIR || exit 3\n\n# $1: value of heap-check env. var.\nrun_check() {\n    export PPROF_PATH=\"$PPROF_PATH\"\n    [ -n \"$1\" ] && export HEAPCHECK=\"$1\" || unset HEAPPROFILE\n\n    echo -n \"Testing $HEAP_CHECKER with HEAPCHECK=$1 ... \"\n    if $HEAP_CHECKER > $TMPDIR/output 2>&1; then\n      echo \"OK\"\n    else\n      echo \"FAILED\"\n      echo \"Output from the failed run:\"\n      echo \"----\"\n      cat $TMPDIR/output\n      echo \"----\"      \n      exit 4\n    fi\n\n    # If we set HEAPPROFILE, then we expect it to actually have emitted\n    # a profile.  Check that it did.\n    if [ -n \"$HEAPPROFILE\" ]; then\n      [ -e \"$HEAPPROFILE.0001.heap\" ] || exit 5\n    fi\n}\n\nrun_check \"\"\nrun_check \"local\"\nrun_check \"normal\"\nrun_check \"strict\"\n\nrm -rf $TMPDIR      # clean up\n\necho \"PASS\"\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/heap-profiler_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// A small program that just exercises our heap profiler by allocating\n// memory and letting the heap-profiler emit a profile.  We don't test\n// threads (TODO).  By itself, this unittest tests that the heap-profiler\n// doesn't crash on simple programs, but its output can be analyzed by\n// another testing script to actually verify correctness.  See, eg,\n// heap-profiler_unittest.sh.\n\n#include \"config_for_unittests.h\"\n#include <stdlib.h>\n#include <stdio.h>\n#include <fcntl.h>                  // for mkdir()\n#include <sys/stat.h>               // for mkdir() on freebsd and os x\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>                 // for fork()\n#endif\n#include <sys/wait.h>               // for wait()\n#include <string>\n#include \"base/basictypes.h\"\n#include \"base/logging.h\"\n#include <google/heap-profiler.h>\n\nusing std::string;\n\nstatic const int kMaxCount = 100000;\nint* g_array[kMaxCount];              // an array of int-vectors\n\nstatic ATTRIBUTE_NOINLINE void Allocate(int start, int end, int size) {\n  for (int i = start; i < end; ++i) {\n    if (i < kMaxCount)\n      g_array[i] = new int[size];\n  }\n}\n\nstatic ATTRIBUTE_NOINLINE void Allocate2(int start, int end, int size) {\n  for (int i = start; i < end; ++i) {\n    if (i < kMaxCount)\n      g_array[i] = new int[size];\n  }\n}\n\nstatic void Deallocate(int start, int end) {\n  for (int i = start; i < end; ++i) {\n    delete[] g_array[i];\n    g_array[i] = 0;\n  }\n}\n\nstatic void TestHeapProfilerStartStopIsRunning() {\n  // If you run this with whole-program heap-profiling on, than\n  // IsHeapProfilerRunning should return true.\n  if (!IsHeapProfilerRunning()) {\n    const char* tmpdir = getenv(\"TMPDIR\");\n    if (tmpdir == NULL)\n      tmpdir = \"/tmp\";\n    mkdir(tmpdir, 0755);     // if necessary\n    HeapProfilerStart((string(tmpdir) + \"/start_stop\").c_str());\n    CHECK(IsHeapProfilerRunning());\n\n    Allocate(0, 40, 100);\n    Deallocate(0, 40);\n\n    HeapProfilerStop();\n    CHECK(!IsHeapProfilerRunning());\n  }\n}\n\nstatic void TestDumpHeapProfiler() {\n  // If you run this with whole-program heap-profiling on, than\n  // IsHeapProfilerRunning should return true.\n  if (!IsHeapProfilerRunning()) {\n    const char* tmpdir = getenv(\"TMPDIR\");\n    if (tmpdir == NULL)\n      tmpdir = \"/tmp\";\n    mkdir(tmpdir, 0755);     // if necessary\n    HeapProfilerStart((string(tmpdir) + \"/dump\").c_str());\n    CHECK(IsHeapProfilerRunning());\n\n    Allocate(0, 40, 100);\n    Deallocate(0, 40);\n\n    char* output = GetHeapProfile();\n    free(output);\n    HeapProfilerStop();\n  }\n}\n\n\nint main(int argc, char** argv) {\n  if (argc > 2 || (argc == 2 && argv[1][0] == '-')) {\n    printf(\"USAGE: %s [number of children to fork]\\n\", argv[0]);\n    exit(0);\n  }\n  int num_forks = 0;\n  if (argc == 2) {\n    num_forks = atoi(argv[1]);\n  }\n\n  TestHeapProfilerStartStopIsRunning();\n  TestDumpHeapProfiler();\n\n  Allocate(0, 40, 100);\n  Deallocate(0, 40);\n\n  Allocate(0, 40, 100);\n  Allocate(0, 40, 100);\n  Allocate2(40, 400, 1000);\n  Allocate2(400, 1000, 10000);\n  Deallocate(0, 1000);\n\n  Allocate(0, 100, 100000);\n  Deallocate(0, 10);\n  Deallocate(10, 20);\n  Deallocate(90, 100);\n  Deallocate(20, 90);\n\n  while (num_forks-- > 0) {\n    switch (fork()) {\n      case -1:\n        printf(\"FORK failed!\\n\");\n        return 1;\n      case 0:             // child\n        return execl(argv[0], argv[0], NULL);   // run child with no args\n      default:\n        wait(NULL);       // we'll let the kids run one at a time\n    }\n  }\n\n  printf(\"DONE.\\n\");\n\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/heap-profiler_unittest.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2005, Google Inc.\n# All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n# \n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# ---\n# Author: Craig Silverstein\n#\n# Runs the heap-profiler unittest and makes sure the profile looks appropriate.\n#\n# We run under the assumption that if $HEAP_PROFILER is run with --help,\n# it prints a usage line of the form\n#   USAGE: <actual executable being run> [...]\n#\n# This is because libtool sometimes turns the 'executable' into a\n# shell script which runs an actual binary somewhere else.\n\n# We expect BINDIR and PPROF_PATH to be set in the environment.\n# If not, we set them to some reasonable values\nBINDIR=\"${BINDIR:-.}\"\nPPROF_PATH=\"${PPROF_PATH:-$BINDIR/src/pprof}\"\n\nif [ \"x$1\" = \"x-h\" -o \"x$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir] [path to pprof]\"\n  echo \"       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH\"\n  exit 1\nfi\n\nHEAP_PROFILER=\"${1:-$BINDIR}/heap-profiler_unittest\"\nPPROF=\"${2:-$PPROF_PATH}\"\nTEST_TMPDIR=/tmp/heap_profile_info\n\n# It's meaningful to the profiler, so make sure we know its state\nunset HEAPPROFILE\n\nrm -rf \"$TEST_TMPDIR\"\nmkdir \"$TEST_TMPDIR\" || exit 2\n\nnum_failures=0\n\n# Given one profile (to check the contents of that profile) or two\n# profiles (to check the diff between the profiles), and a function\n# name, verify that the function name takes up at least 90% of the\n# allocated memory.  The function name is actually specified first.\nVerifyMemFunction() {\n  function=\"$1\"\n  shift\n\n  # get program name.  Note we have to unset HEAPPROFILE so running\n  # help doesn't overwrite existing profiles.\n  exec=`unset HEAPPROFILE; $HEAP_PROFILER --help | awk '{print $2; exit;}'`\n\n  if [ $# = 2 ]; then\n    [ -f \"$1\" ] || { echo \"Profile not found: $1\"; exit 1; }\n    [ -f \"$2\" ] || { echo \"Profile not found: $2\"; exit 1; }\n    $PPROF --base=\"$1\" $exec \"$2\" >\"$TEST_TMPDIR/output.pprof\" 2>&1\n  else\n    [ -f \"$1\" ] || { echo \"Profile not found: $1\"; exit 1; }\n    $PPROF $exec \"$1\" >\"$TEST_TMPDIR/output.pprof\" 2>&1\n  fi\n\n  cat \"$TEST_TMPDIR/output.pprof\" \\\n      | tr -d % | awk '$6 ~ /^'$function'$/ && $2 > 90 {exit 1;}'\n  if [ $? != 1 ]; then\n    echo\n    echo \"--- Test failed for $function: didn't account for 90% of executable memory\"\n    echo \"--- Program output:\"\n    cat \"$TEST_TMPDIR/output\"\n    echo \"--- pprof output:\"\n    cat \"$TEST_TMPDIR/output.pprof\"\n    echo \"---\"\n    num_failures=`expr $num_failures + 1`\n  fi\n}\n\nVerifyOutputContains() {\n  text=\"$1\"\n\n  if ! grep \"$text\" \"$TEST_TMPDIR/output\" >/dev/null 2>&1; then\n    echo \"--- Test failed: output does not contain '$text'\"\n    echo \"--- Program output:\"\n    cat \"$TEST_TMPDIR/output\"\n    echo \"---\"\n    num_failures=`expr $num_failures + 1`\n  fi\n}\n\nHEAPPROFILE=\"$TEST_TMPDIR/test\"\nHEAP_PROFILE_INUSE_INTERVAL=\"10240\"   # need this to be 10Kb\nHEAP_PROFILE_ALLOCATION_INTERVAL=\"$HEAP_PROFILE_INUSE_INTERVAL\"\nHEAP_PROFILE_DEALLOCATION_INTERVAL=\"$HEAP_PROFILE_INUSE_INTERVAL\"\nexport HEAPPROFILE\nexport HEAP_PROFILE_INUSE_INTERVAL\nexport HEAP_PROFILE_ALLOCATION_INTERVAL\nexport HEAP_PROFILE_DEALLOCATION_INTERVAL\n\n# We make the unittest run a child process, to test that the child\n# process doesn't try to write a heap profile as well and step on the\n# parent's toes.  If it does, we expect the parent-test to fail.\n$HEAP_PROFILER 1 >$TEST_TMPDIR/output 2>&1     # run program, with 1 child proc\n\nVerifyMemFunction Allocate2 \"$HEAPPROFILE.1329.heap\"\nVerifyMemFunction Allocate \"$HEAPPROFILE.1448.heap\" \"$HEAPPROFILE.1548.heap\"\n\n# Check the child process got to emit its own profile as well.\nVerifyMemFunction Allocate2 \"$HEAPPROFILE\"_*.1329.heap\nVerifyMemFunction Allocate \"$HEAPPROFILE\"_*.1448.heap \"$HEAPPROFILE\"_*.1548.heap\n\n# Make sure we logged both about allocating and deallocating memory\nVerifyOutputContains \"62 MB allocated\"\nVerifyOutputContains \"62 MB freed\"\n\n# Now try running without --heap_profile specified, to allow\n# testing of the HeapProfileStart/Stop functionality.\n$HEAP_PROFILER >\"$TEST_TMPDIR/output2\" 2>&1\n\nrm -rf $TMPDIR      # clean up\n\nif [ $num_failures = 0 ]; then\n  echo \"PASS\"\nelse\n  echo \"Tests finished with $num_failures failures\"\nfi\nexit $num_failures\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/low_level_alloc_unittest.cc",
    "content": "/* Copyright (c) 2006, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n// A test for low_level_alloc.cc\n\n#include <stdio.h>\n#include <map>\n#include \"base/low_level_alloc.h\"\n#include \"base/logging.h\"\n#include <google/malloc_hook.h>\n\nusing std::map;\n\n// a block of memory obtained from the allocator\nstruct BlockDesc {\n  char *ptr;      // pointer to memory\n  int len;        // number of bytes\n  int fill;       // filled with data starting with this\n};\n\n// Check that the pattern placed in the block d\n// by RandomizeBlockDesc is still there.\nstatic void CheckBlockDesc(const BlockDesc &d) {\n  for (int i = 0; i != d.len; i++) {\n    CHECK((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff));\n  }\n}\n\n// Fill the block \"*d\" with a pattern\n// starting with a random byte.\nstatic void RandomizeBlockDesc(BlockDesc *d) {\n  d->fill = rand() & 0xff;\n  for (int i = 0; i != d->len; i++) {\n    d->ptr[i] = (d->fill + i) & 0xff;\n  }\n}\n\n// Use to indicate to the malloc hooks that\n// this calls is from LowLevelAlloc.\nstatic bool using_low_level_alloc = false;\n\n// n times, toss a coin, and based on the outcome\n// either allocate a new block or deallocate an old block.\n// New blocks are placed in a map with a random key\n// and initialized with RandomizeBlockDesc().\n// If keys conflict, the older block is freed.\n// Old blocks are always checked with CheckBlockDesc()\n// before being freed.  At the end of the run,\n// all remaining allocated blocks are freed.\n// If use_new_arena is true, use a fresh arena, and then delete it.\n// If call_malloc_hook is true and user_arena is true,\n// allocations and deallocations are reported via the MallocHook\n// interface.\nstatic void Test(bool use_new_arena, bool call_malloc_hook, int n) {\n  typedef map<int, BlockDesc> AllocMap;\n  AllocMap allocated;\n  AllocMap::iterator it;\n  BlockDesc block_desc;\n  int rnd;\n  LowLevelAlloc::Arena *arena = 0;\n  if (use_new_arena) {\n    int32 flags = call_malloc_hook?  LowLevelAlloc::kCallMallocHook :  0;\n    arena = LowLevelAlloc::NewArena(flags, LowLevelAlloc::DefaultArena());\n  }\n  for (int i = 0; i != n; i++) {\n    if (i != 0 && i % 10000 == 0) {\n      printf(\".\");\n      fflush(stdout);\n    }\n\n    switch(rand() & 1) {      // toss a coin\n    case 0:     // coin came up heads: add a block\n      using_low_level_alloc = true;\n      block_desc.len = rand() & 0x3fff;\n      block_desc.ptr =\n        reinterpret_cast<char *>(\n                        arena == 0\n                        ? LowLevelAlloc::Alloc(block_desc.len)\n                        : LowLevelAlloc::AllocWithArena(block_desc.len, arena));\n      using_low_level_alloc = false;\n      RandomizeBlockDesc(&block_desc);\n      rnd = rand();\n      it = allocated.find(rnd);\n      if (it != allocated.end()) {\n        CheckBlockDesc(it->second);\n        using_low_level_alloc = true;\n        LowLevelAlloc::Free(it->second.ptr);\n        using_low_level_alloc = false;\n        it->second = block_desc;\n      } else {\n        allocated[rnd] = block_desc;\n      }\n      break;\n    case 1:     // coin came up tails: remove a block\n      it = allocated.begin();\n      if (it != allocated.end()) {\n        CheckBlockDesc(it->second);\n        using_low_level_alloc = true;\n        LowLevelAlloc::Free(it->second.ptr);\n        using_low_level_alloc = false;\n        allocated.erase(it);\n      }\n      break;\n    }\n  }\n  // remove all remaniing blocks\n  while ((it = allocated.begin()) != allocated.end()) {\n    CheckBlockDesc(it->second);\n    using_low_level_alloc = true;\n    LowLevelAlloc::Free(it->second.ptr);\n    using_low_level_alloc = false;\n    allocated.erase(it);\n  }\n  if (use_new_arena) {\n    CHECK(LowLevelAlloc::DeleteArena(arena));\n  }\n}\n\n// used for counting allocates and frees\nstatic int32 allocates;\nstatic int32 frees;\nstatic MallocHook::NewHook old_alloc_hook;\nstatic MallocHook::DeleteHook old_free_hook;\n\n// called on each alloc if kCallMallocHook specified\nstatic void AllocHook(const void *p, size_t size) {\n  if (using_low_level_alloc) {\n    allocates++;\n  }\n  if (old_alloc_hook != 0) {\n    (*old_alloc_hook)(p, size);\n  }\n}\n\n// called on each free if kCallMallocHook specified\nstatic void FreeHook(const void *p) {\n  if (using_low_level_alloc) {\n    frees++;\n  }\n  if (old_free_hook != 0) {\n    (*old_free_hook)(p);\n  }\n}\n\nint main(int argc, char *argv[]) {\n  // This is needed by maybe_threads_unittest.sh, which parses argv[0]\n  // to figure out what directory low_level_alloc_unittest is in.\n  if (argc != 1) {\n    fprintf(stderr, \"USAGE: %s\\n\", argv[0]);\n    return 1;\n  }\n\n  old_alloc_hook = MallocHook::SetNewHook(AllocHook);\n  old_free_hook = MallocHook::SetDeleteHook(FreeHook);\n  CHECK_EQ(allocates, 0);\n  CHECK_EQ(frees, 0);\n  Test(false, false, 50000);\n  CHECK_NE(allocates, 0);   // default arena calls hooks\n  CHECK_NE(frees, 0);\n  for (int i = 0; i != 16; i++) {\n    bool call_hooks = ((i & 1) == 1);\n    allocates = 0;\n    frees = 0;\n    Test(true, call_hooks, 15000);\n    if (call_hooks) {\n      CHECK_GT(allocates, 5000); // arena calls hooks\n      CHECK_GT(frees, 5000);\n    } else {\n      CHECK_EQ(allocates, 0);    // arena doesn't call hooks\n      CHECK_EQ(frees, 0);\n    }\n  }\n  printf(\"\\nPASS\\n\");\n  CHECK_EQ(MallocHook::SetNewHook(old_alloc_hook), AllocHook);\n  CHECK_EQ(MallocHook::SetDeleteHook(old_free_hook), FreeHook);\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/malloc_extension_c_test.c",
    "content": "/* Copyright (c) 2009, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Craig Silverstein\n *\n * This tests the c shims: malloc_extension_c.h and malloc_hook_c.h.\n * Mostly, we'll just care that these shims compile under gcc\n * (*not* g++!)\n *\n * NOTE: this is C code, not C++ code!\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stddef.h>   /* for size_t */\n#include <google/malloc_extension_c.h>\n#include <google/malloc_hook_c.h>\n\n#define FAIL(msg) do {                          \\\n  fprintf(stderr, \"FATAL ERROR: %s\\n\", msg);    \\\n  exit(1);                                      \\\n} while (0)\n\nstatic int g_new_hook_calls = 0;\nstatic int g_delete_hook_calls = 0;\n\nvoid TestNewHook(const void* ptr, size_t size) {\n  g_new_hook_calls++;\n}\n\nvoid TestDeleteHook(const void* ptr) {\n  g_delete_hook_calls++;\n}\n\nvoid TestMallocHook(void) {\n  /* TODO(csilvers): figure out why we get:\n   * E0100 00:00:00.000000  7383 malloc_hook.cc:244] RAW: google_malloc section is missing, thus InHookCaller is broken!\n   */\n#if 0\n  void* result[5];\n\n  if (MallocHook_GetCallerStackTrace(result, sizeof(result)/sizeof(*result),\n                                     0) < 2) {  /* should have this and main */\n    FAIL(\"GetCallerStackTrace failed\");\n  }\n#endif\n\n  MallocHook_SetNewHook(&TestNewHook);\n  MallocHook_SetDeleteHook(&TestDeleteHook);\n  free(malloc(10));\n  free(malloc(20));\n  if (g_new_hook_calls != 2) {\n    FAIL(\"Wrong number of calls to the new hook\");\n  }\n  if (g_delete_hook_calls != 2) {\n    FAIL(\"Wrong number of calls to the delete hook\");\n  }\n}\n\nvoid TestMallocExtension(void) {\n  int blocks;\n  size_t total;\n  int hist[64];\n  char buffer[200];\n  char* x = (char*)malloc(10);\n\n  MallocExtension_VerifyAllMemory();\n  MallocExtension_VerifyMallocMemory(x);\n  MallocExtension_MallocMemoryStats(&blocks, &total, hist);\n  MallocExtension_GetStats(buffer, sizeof(buffer));\n  if (!MallocExtension_GetNumericProperty(\"generic.current_allocated_bytes\",\n                                          &total)) {\n    FAIL(\"GetNumericProperty failed for generic.current_allocated_bytes\");\n  }\n  if (total < 10) {\n    FAIL(\"GetNumericProperty had bad return for generic.current_allocated_bytes\");\n  }\n  if (!MallocExtension_GetNumericProperty(\"generic.current_allocated_bytes\",\n                                          &total)) {\n    FAIL(\"GetNumericProperty failed for generic.current_allocated_bytes\");\n  }\n  MallocExtension_MarkThreadIdle();\n  MallocExtension_MarkThreadBusy();\n  MallocExtension_ReleaseToSystem(1);\n  MallocExtension_ReleaseFreeMemory();\n  if (MallocExtension_GetEstimatedAllocatedSize(10) < 10) {\n    FAIL(\"GetEstimatedAllocatedSize returned a bad value (too small)\");\n  }\n  if (MallocExtension_GetAllocatedSize(x) < 10) {\n    FAIL(\"GetEstimatedAllocatedSize returned a bad value (too small)\");\n  }\n\n  free(x);\n}\n\nint main(int argc, char** argv) {\n  TestMallocHook();\n  TestMallocExtension();\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/malloc_extension_test.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// Simple test of malloc_extension.  Includes test of C shims.\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#include <sys/types.h>\n#include \"base/logging.h\"\n#include <google/malloc_extension.h>\n#include <google/malloc_extension_c.h>\n\nusing STL_NAMESPACE::vector;\n\nint main(int argc, char** argv) {\n  void* a = malloc(1000);\n\n  size_t cxx_bytes_used, c_bytes_used;\n  ASSERT_TRUE(MallocExtension::instance()->GetNumericProperty(\n      \"generic.current_allocated_bytes\", &cxx_bytes_used));\n  ASSERT_TRUE(MallocExtension_GetNumericProperty(\n      \"generic.current_allocated_bytes\", &c_bytes_used));\n  ASSERT_GT(cxx_bytes_used, 1000);\n  ASSERT_EQ(cxx_bytes_used, c_bytes_used);\n\n  ASSERT_TRUE(MallocExtension::instance()->VerifyAllMemory());\n  ASSERT_TRUE(MallocExtension_VerifyAllMemory());\n\n  ASSERT_GE(MallocExtension::instance()->GetAllocatedSize(a), 1000);\n  // This is just a sanity check.  If we allocated too much, tcmalloc is broken\n  ASSERT_LE(MallocExtension::instance()->GetAllocatedSize(a), 5000);\n  ASSERT_GE(MallocExtension::instance()->GetEstimatedAllocatedSize(1000), 1000);\n\n  for (int i = 0; i < 10; ++i) {\n    void *p = malloc(i);\n    ASSERT_GE(MallocExtension::instance()->GetAllocatedSize(p),\n             MallocExtension::instance()->GetEstimatedAllocatedSize(i));\n    free(p);\n  }\n\n  // Check the c-shim version too.\n  ASSERT_GE(MallocExtension_GetAllocatedSize(a), 1000);\n  ASSERT_LE(MallocExtension_GetAllocatedSize(a), 5000);\n  ASSERT_GE(MallocExtension_GetEstimatedAllocatedSize(1000), 1000);\n\n  free(a);\n\n  printf(\"DONE\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/markidle_unittest.cc",
    "content": "// Copyright (c) 2003, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// MallocExtension::MarkThreadIdle() testing\n#include <stdio.h>\n\n#include \"config_for_unittests.h\"\n#include \"base/logging.h\"\n#include <google/malloc_extension.h>\n#include \"tests/testutil.h\"   // for RunThread()\n\n// Helper routine to do lots of allocations\nstatic void TestAllocation() {\n  static const int kNum = 100;\n  void* ptr[kNum];\n  for (int size = 8; size <= 65536; size*=2) {\n    for (int i = 0; i < kNum; i++) {\n      ptr[i] = malloc(size);\n    }\n    for (int i = 0; i < kNum; i++) {\n      free(ptr[i]);\n    }\n  }\n}\n\n// Routine that does a bunch of MarkThreadIdle() calls in sequence\n// without any intervening allocations\nstatic void MultipleIdleCalls() {\n  for (int i = 0; i < 4; i++) {\n    MallocExtension::instance()->MarkThreadIdle();\n  }\n}\n\n// Routine that does a bunch of MarkThreadIdle() calls in sequence\n// with intervening allocations\nstatic void MultipleIdleNonIdlePhases() {\n  for (int i = 0; i < 4; i++) {\n    TestAllocation();\n    MallocExtension::instance()->MarkThreadIdle();\n  }\n}\n\n// Get current thread cache usage\nstatic size_t GetTotalThreadCacheSize() {\n  size_t result;\n  CHECK(MallocExtension::instance()->GetNumericProperty(\n            \"tcmalloc.current_total_thread_cache_bytes\",\n            &result));\n  return result;\n}\n\n// Check that MarkThreadIdle() actually reduces the amount\n// of per-thread memory.\nstatic void TestIdleUsage() {\n  const size_t original = GetTotalThreadCacheSize();\n\n  TestAllocation();\n  const size_t post_allocation = GetTotalThreadCacheSize();\n  CHECK_GT(post_allocation, original);\n\n  MallocExtension::instance()->MarkThreadIdle();\n  const size_t post_idle = GetTotalThreadCacheSize();\n  CHECK_LE(post_idle, original);\n\n  // Log after testing because logging can allocate heap memory.\n  VLOG(0, \"Original usage: %\"PRIuS\"\\n\", original);\n  VLOG(0, \"Post allocation: %\"PRIuS\"\\n\", post_allocation);\n  VLOG(0, \"Post idle: %\"PRIuS\"\\n\", post_idle);\n}\n\nint main(int argc, char** argv) {\n  RunThread(&TestIdleUsage);\n  RunThread(&TestAllocation);\n  RunThread(&MultipleIdleCalls);\n  RunThread(&MultipleIdleNonIdlePhases);\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/maybe_threads_unittest.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2007, Google Inc.\n# All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n# \n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# ---\n# Author: Craig Silverstein\n#\n# maybe_threads.cc was written to allow LD_PRELOAD=libtcmalloc.so to\n# work even on binaries that were not linked with pthreads.  This\n# unittest tests that, by running low_level_alloc_unittest with an\n# LD_PRELOAD.  (low_level_alloc_unittest was chosen because it doesn't\n# link in tcmalloc.)\n#\n# We assume all the .so files are in the same directory as both\n# addressmap_unittest and profiler1_unittest.  The reason we need\n# profiler1_unittest is because it's instrumented to show the directory\n# it's \"really\" in when run without any args.  In practice this will either\n# be BINDIR, or, when using libtool, BINDIR/.lib.\n\n# We expect BINDIR to be set in the environment.\n# If not, we set them to some reasonable values.\nBINDIR=\"${BINDIR:-.}\"\n\nif [ \"x$1\" = \"x-h\" -o \"x$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir]\"\n  echo \"       By default, unittest_dir=$BINDIR\"\n  exit 1\nfi\n\nUNITTEST_DIR=${1:-$BINDIR}\n\n# Figure out the \"real\" unittest directory.  Also holds the .so files.\nUNITTEST_DIR=`$UNITTEST_DIR/low_level_alloc_unittest --help 2>&1 \\\n              | awk '{print $2; exit;}' \\\n              | xargs dirname`\n\n# Figure out where libtcmalloc lives.   It should be in UNITTEST_DIR,\n# but with libtool it might be in a subdir.\nif [ -r \"$UNITTEST_DIR/libtcmalloc_minimal.so\" ]; then\n  LIB_PATH=\"$UNITTEST_DIR/libtcmalloc_minimal.so\"\nelif [ -r \"$UNITTEST_DIR/.libs/libtcmalloc_minimal.so\" ]; then\n  LIB_PATH=\"$UNITTEST_DIR/.libs/libtcmalloc_minimal.so\"\nelif [ -r \"$UNITTEST_DIR/libtcmalloc_minimal.dylib\" ]; then   # for os x\n  LIB_PATH=\"$UNITTEST_DIR/libtcmalloc_minimal.dylib\"\nelif [ -r \"$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib\" ]; then\n  LIB_PATH=\"$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib\"\nelse\n  echo \"Cannot run $0: cannot find libtcmalloc_minimal.so\"\n  exit 2\nfi\n\nLD_PRELOAD=\"$LIB_PATH\" $UNITTEST_DIR/low_level_alloc_unittest\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/memalign_unittest.cc",
    "content": "// Copyright (c) 2004, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Check memalign related routines.\n//\n// We can't really do a huge amount of checking, but at the very\n// least, the following code checks that return values are properly\n// aligned, and that writing into the objects works.\n\n#include \"config_for_unittests.h\"\n\n// Complicated ordering requirements.  tcmalloc.h defines (indirectly)\n// _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.\n// unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,\n// at least on Mac OS X, in order to define getpagesize.  The solution\n// is to #include unistd.h first.  This is safe because unistd.h\n// doesn't sub-include stdlib.h, so we'll still get posix_memalign\n// when we #include stdlib.h.  Blah.\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>        // for getpagesize()\n#endif\n#include \"tcmalloc.h\"      // must come early, to pick up posix_memalign\n#include <stdlib.h>        // defines posix_memalign\n#include <stdio.h>         // for the printf at the end\n#ifdef HAVE_STDINT_H\n#include <stdint.h>        // for uintptr_t\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>        // for getpagesize()\n#endif\n#ifdef HAVE_MALLOC_H\n#include <malloc.h>\n#endif\n#include \"base/basictypes.h\"\n#include \"base/logging.h\"\n#include \"tests/testutil.h\"\n\n\n// Return the next interesting size/delta to check.  Returns -1 if no more.\nstatic int NextSize(int size) {\n  if (size < 100) {\n    return size+1;\n  } else if (size < 1048576) {\n    // Find next power of two\n    int power = 1;\n    while (power < size) {\n      power <<= 1;\n    }\n\n    // Yield (power-1, power, power+1)\n    if (size < power-1) {\n      return power-1;\n    } else if (size == power-1) {\n      return power;\n    } else {\n      assert(size == power);\n      return power+1;\n    }\n  } else {\n    return -1;\n  }\n}\n\n// Shortform for cast\nstatic uintptr_t Number(void* p) {\n  return reinterpret_cast<uintptr_t>(p);\n}\n\n// Check alignment\nstatic void CheckAlignment(void* p, int align) {\n  if ((Number(p) & (align-1)) != 0)\n    LOG(FATAL, \"wrong alignment; wanted 0x%x; got %p\\n\", align, p);\n}\n\n// Fill a buffer of the specified size with a predetermined pattern\nstatic void Fill(void* p, int n, char seed) {\n  unsigned char* buffer = reinterpret_cast<unsigned char*>(p);\n  for (int i = 0; i < n; i++) {\n    buffer[i] = ((seed + i) & 0xff);\n  }\n}\n\n// Check that the specified buffer has the predetermined pattern\n// generated by Fill()\nstatic bool Valid(const void* p, int n, char seed) {\n  const unsigned char* buffer = reinterpret_cast<const unsigned char*>(p);\n  for (int i = 0; i < n; i++) {\n    if (buffer[i] != ((seed + i) & 0xff)) {\n      return false;\n    }\n  }\n  return true;\n}\n\nint main(int argc, char** argv) {\n  SetTestResourceLimit();\n\n  // Try allocating data with a bunch of alignments and sizes\n  for (int a = 1; a < 1048576; a *= 2) {\n    for (int s = 0; s != -1; s = NextSize(s)) {\n      void* ptr = memalign(a, s);\n      CheckAlignment(ptr, a);\n      Fill(ptr, s, 'x');\n      CHECK(Valid(ptr, s, 'x'));\n      free(ptr);\n\n      if ((a >= sizeof(void*)) && ((a & (a-1)) == 0)) {\n        CHECK(posix_memalign(&ptr, a, s) == 0);\n        CheckAlignment(ptr, a);\n        Fill(ptr, s, 'y');\n        CHECK(Valid(ptr, s, 'y'));\n        free(ptr);\n      }\n    }\n  }\n\n  {\n    // Check various corner cases\n    void* p1 = memalign(1<<20, 1<<19);\n    void* p2 = memalign(1<<19, 1<<19);\n    void* p3 = memalign(1<<21, 1<<19);\n    CheckAlignment(p1, 1<<20);\n    CheckAlignment(p2, 1<<19);\n    CheckAlignment(p3, 1<<21);\n    Fill(p1, 1<<19, 'a');\n    Fill(p2, 1<<19, 'b');\n    Fill(p3, 1<<19, 'c');\n    CHECK(Valid(p1, 1<<19, 'a'));\n    CHECK(Valid(p2, 1<<19, 'b'));\n    CHECK(Valid(p3, 1<<19, 'c'));\n    free(p1);\n    free(p2);\n    free(p3);\n  }\n\n  {\n    // posix_memalign\n    void* ptr;\n    CHECK(posix_memalign(&ptr, 0, 1) == EINVAL);\n    CHECK(posix_memalign(&ptr, sizeof(void*)/2, 1) == EINVAL);\n    CHECK(posix_memalign(&ptr, sizeof(void*)+1, 1) == EINVAL);\n    CHECK(posix_memalign(&ptr, 4097, 1) == EINVAL);\n\n    // Grab some memory so that the big allocation below will definitely fail.\n    void* p_small = malloc(4*1048576);\n    CHECK(p_small != NULL);\n\n    // Make sure overflow is returned as ENOMEM\n    const size_t zero = 0;\n    static const size_t kMinusNTimes = 10;\n    for ( size_t i = 1; i < kMinusNTimes; ++i ) {\n      int r = posix_memalign(&ptr, 1024, zero - i);\n      CHECK(r == ENOMEM);\n    }\n\n    free(p_small);\n  }\n\n  const int pagesize = getpagesize();\n  {\n    // valloc\n    for (int s = 0; s != -1; s = NextSize(s)) {\n      void* p = valloc(s);\n      CheckAlignment(p, pagesize);\n      Fill(p, s, 'v');\n      CHECK(Valid(p, s, 'v'));\n      free(p);\n    }\n  }\n\n  {\n    // pvalloc\n    for (int s = 0; s != -1; s = NextSize(s)) {\n      void* p = pvalloc(s);\n      CheckAlignment(p, pagesize);\n      int alloc_needed = ((s + pagesize - 1) / pagesize) * pagesize;\n      Fill(p, alloc_needed, 'x');\n      CHECK(Valid(p, alloc_needed, 'x'));\n      free(p);\n    }\n  }\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/packed-cache_test.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Geoff Pike\n\n#include <stdio.h>\n#include \"base/logging.h\"\n#include \"packed-cache-inl.h\"\n\nstatic const int kHashbits = PackedCache<64, uint64>::kHashbits;\n\n// A basic sanity test.\nvoid PackedCacheTest_basic() {\n  PackedCache<32, uint32> cache(0);\n  CHECK_EQ(cache.GetOrDefault(0, 1), 0);\n  cache.Put(0, 17);\n  CHECK(cache.Has(0));\n  CHECK_EQ(cache.GetOrDefault(0, 1), 17);\n  cache.Put(19, 99);\n  CHECK(cache.Has(0) && cache.Has(19));\n  CHECK_EQ(cache.GetOrDefault(0, 1), 17);\n  CHECK_EQ(cache.GetOrDefault(19, 1), 99);\n  // Knock <0, 17> out by using a conflicting key.\n  cache.Put(1 << kHashbits, 22);\n  CHECK(!cache.Has(0));\n  CHECK_EQ(cache.GetOrDefault(0, 1), 1);\n  CHECK_EQ(cache.GetOrDefault(1 << kHashbits, 1), 22);\n}\n\nint main(int argc, char **argv) {\n  PackedCacheTest_basic();\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/page_heap_test.cc",
    "content": "// Copyright 2009 Google Inc. All Rights Reserved.\n// Author: fikes@google.com (Andrew Fikes)\n\n#include <stdio.h>\n#include \"config_for_unittests.h\"\n#include \"base/logging.h\"\n#include \"common.h\"\n#include \"page_heap.h\"\n\nnamespace {\n\nstatic void CheckStats(const tcmalloc::PageHeap* ph,\n                       uint64_t system_pages,\n                       uint64_t free_pages,\n                       uint64_t unmapped_pages) {\n  tcmalloc::PageHeap::Stats stats = ph->stats();\n  EXPECT_EQ(system_pages, stats.system_bytes >> kPageShift);\n  EXPECT_EQ(free_pages, stats.free_bytes >> kPageShift);\n  EXPECT_EQ(unmapped_pages, stats.unmapped_bytes >> kPageShift);\n}\n\nstatic void TestPageHeap_Stats() {\n  tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();\n\n  // Empty page heap\n  CheckStats(ph, 0, 0, 0);\n\n  // Allocate a span 's1'\n  tcmalloc::Span* s1 = ph->New(256);\n  CheckStats(ph, 256, 0, 0);\n\n  // Split span 's1' into 's1', 's2'.  Delete 's2'\n  tcmalloc::Span* s2 = ph->Split(s1, 128);\n  Length s2_len = s2->length;\n  ph->Delete(s2);\n  CheckStats(ph, 256, 128, 0);\n\n  // Unmap deleted span 's2'\n  EXPECT_EQ(s2_len, ph->ReleaseAtLeastNPages(1));\n  CheckStats(ph, 256, 0, 128);\n\n  // Delete span 's1'\n  ph->Delete(s1);\n  CheckStats(ph, 256, 128, 128);\n\n  delete ph;\n}\n\n}  // namespace\n\nint main(int argc, char **argv) {\n  TestPageHeap_Stats();\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/pagemap_unittest.cc",
    "content": "// Copyright (c) 2003, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#if defined HAVE_STDINT_H\n#include <stdint.h>             // to get intptr_t\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>           // another place intptr_t might be defined\n#endif\n#include <sys/types.h>\n#include <vector>\n#include \"base/logging.h\"\n#include \"pagemap.h\"\n\nusing std::vector;\n\nstatic void Permute(vector<intptr_t>* elements) {\n  if (elements->empty())\n    return;\n  const size_t num_elements = elements->size();\n  for (size_t i = num_elements - 1; i > 0; --i) {\n    const size_t newpos = rand() % (i + 1);\n    const intptr_t tmp = (*elements)[i];   // swap\n    (*elements)[i] = (*elements)[newpos];\n    (*elements)[newpos] = tmp;\n  }\n}\n\n// Note: we leak memory every time a map is constructed, so do not\n// create too many maps.\n\n// Test specified map type\ntemplate <class Type>\nvoid TestMap(int limit, bool limit_is_below_the_overflow_boundary) {\n  RAW_LOG(INFO, \"Running test with %d iterations...\\n\", limit);\n\n  { // Test sequential ensure/assignment\n    Type map(malloc);\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {\n      map.Ensure(i, 1);\n      map.set(i, (void*)(i+1));\n      CHECK_EQ(map.get(i), (void*)(i+1));\n    }\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {\n      CHECK_EQ(map.get(i), (void*)(i+1));\n    }\n  }\n\n  { // Test bulk Ensure\n    Type map(malloc);\n    map.Ensure(0, limit);\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {\n      map.set(i, (void*)(i+1));\n      CHECK_EQ(map.get(i), (void*)(i+1));\n    }\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {\n      CHECK_EQ(map.get(i), (void*)(i+1));\n    }\n  }\n\n  // Test that we correctly notice overflow\n  {\n    Type map(malloc);\n    CHECK_EQ(map.Ensure(limit, limit+1), limit_is_below_the_overflow_boundary);\n  }\n\n  { // Test randomized accesses\n    srand(301);   // srand isn't great, but it's portable\n    vector<intptr_t> elements;\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) elements.push_back(i);\n    Permute(&elements);\n\n    Type map(malloc);\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {\n      map.Ensure(elements[i], 1);\n      map.set(elements[i], (void*)(elements[i]+1));\n      CHECK_EQ(map.get(elements[i]), (void*)(elements[i]+1));\n    }\n    for (intptr_t i = 0; i < static_cast<intptr_t>(limit); i++) {\n      CHECK_EQ(map.get(i), (void*)(i+1));\n    }\n  }\n}\n\n// REQUIRES: BITS==10, i.e., valid range is [0,1023].\n// Representations for different types will end up being:\n//    PageMap1: array[1024]\n//    PageMap2: array[32][32]\n//    PageMap3: array[16][16][4]\ntemplate <class Type>\nvoid TestNext(const char* name) {\n  RAW_LOG(ERROR, \"Running NextTest %s\\n\", name);\n  Type map(malloc);\n  char a, b, c, d, e;\n\n  // When map is empty\n  CHECK(map.Next(0) == NULL);\n  CHECK(map.Next(5) == NULL);\n  CHECK(map.Next(1<<30) == NULL);\n\n  // Add a single value\n  map.Ensure(40, 1);\n  map.set(40, &a);\n  CHECK(map.Next(0) == &a);\n  CHECK(map.Next(39) == &a);\n  CHECK(map.Next(40) == &a);\n  CHECK(map.Next(41) == NULL);\n  CHECK(map.Next(1<<30) == NULL);\n\n  // Add a few values\n  map.Ensure(41, 1);\n  map.Ensure(100, 3);\n  map.set(41, &b);\n  map.set(100, &c);\n  map.set(101, &d);\n  map.set(102, &e);\n  CHECK(map.Next(0) == &a);\n  CHECK(map.Next(39) == &a);\n  CHECK(map.Next(40) == &a);\n  CHECK(map.Next(41) == &b);\n  CHECK(map.Next(42) == &c);\n  CHECK(map.Next(63) == &c);\n  CHECK(map.Next(64) == &c);\n  CHECK(map.Next(65) == &c);\n  CHECK(map.Next(99) == &c);\n  CHECK(map.Next(100) == &c);\n  CHECK(map.Next(101) == &d);\n  CHECK(map.Next(102) == &e);\n  CHECK(map.Next(103) == NULL);\n}\n\nint main(int argc, char** argv) {\n  TestMap< TCMalloc_PageMap1<10> > (100, true);\n  TestMap< TCMalloc_PageMap1<10> > (1 << 10, false);\n  TestMap< TCMalloc_PageMap2<20> > (100, true);\n  TestMap< TCMalloc_PageMap2<20> > (1 << 20, false);\n  TestMap< TCMalloc_PageMap3<20> > (100, true);\n  TestMap< TCMalloc_PageMap3<20> > (1 << 20, false);\n\n  TestNext< TCMalloc_PageMap1<10> >(\"PageMap1\");\n  TestNext< TCMalloc_PageMap2<10> >(\"PageMap2\");\n  TestNext< TCMalloc_PageMap3<10> >(\"PageMap3\");\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/profile-handler_unittest.cc",
    "content": "// Copyright 2009 Google Inc. All Rights Reserved.\n// Author: Nabeel Mian (nabeelmian@google.com)\n//         Chris Demetriou (cgd@google.com)\n//\n// This file contains the unit tests for profile-handler.h interface.\n\n#include \"config.h\"\n#include \"profile-handler.h\"\n\n#include <assert.h>\n#include <pthread.h>\n#include <sys/time.h>\n#include <time.h>\n#include \"base/logging.h\"\n#include \"base/simple_mutex.h\"\n\n// Some helpful macros for the test class\n#define TEST_F(cls, fn)    void cls :: fn()\n\nnamespace {\n\n// TODO(csilvers): error-checking on the pthreads routines\nclass Thread {\n public:\n  Thread() : joinable_(false) { }\n  void SetJoinable(bool value) { joinable_ = value; }\n  void Start() {\n    pthread_attr_t attr;\n    pthread_attr_init(&attr);\n    pthread_attr_setdetachstate(&attr, joinable_ ? PTHREAD_CREATE_JOINABLE\n                                                 : PTHREAD_CREATE_DETACHED);\n    pthread_create(&thread_, &attr, &DoRun, this);\n    pthread_attr_destroy(&attr);\n  }\n  void Join()  {\n    assert(joinable_);\n    pthread_join(thread_, NULL);\n  }\n  virtual void Run() = 0;\n private:\n  static void* DoRun(void* cls) {\n    ProfileHandlerRegisterThread();\n    reinterpret_cast<Thread*>(cls)->Run();\n    return NULL;\n  }\n  pthread_t thread_;\n  bool joinable_;\n};\n\n// Sleep interval in nano secs. ITIMER_PROF goes off only afer the specified CPU\n// time is consumed. Under heavy load this process may no get scheduled in a\n// timely fashion. Therefore, give enough time (20x of ProfileHandle timer\n// interval 10ms (100Hz)) for this process to accumulate enought CPU time to get\n// a profile tick.\nint kSleepInterval = 200000000;\n\n// Sleep interval in nano secs. To ensure that if the timer has expired it is\n// reset.\nint kTimerResetInterval = 5000000;\n\n// Whether each thread has separate timers.\nstatic bool timer_separate_ = false;\nstatic int timer_type_ = ITIMER_PROF;\nstatic int signal_number_ = SIGPROF;\n\n// Delays processing by the specified number of nano seconds. 'delay_ns'\n// must be less than the number of nano seconds in a second (1000000000).\nvoid Delay(int delay_ns) {\n  static const int kNumNSecInSecond = 1000000000;\n  EXPECT_LT(delay_ns, kNumNSecInSecond);\n  struct timespec delay = { 0, delay_ns };\n  nanosleep(&delay, 0);\n}\n\n// Checks whether the profile timer is enabled for the current thread.\nbool IsTimerEnabled() {\n  itimerval current_timer;\n  EXPECT_EQ(0, getitimer(timer_type_, &current_timer));\n  if ((current_timer.it_value.tv_sec == 0) &&\n      (current_timer.it_value.tv_usec != 0)) {\n    // May be the timer has expired. Sleep for a bit and check again.\n    Delay(kTimerResetInterval);\n    EXPECT_EQ(0, getitimer(timer_type_, &current_timer));\n  }\n  return (current_timer.it_value.tv_sec != 0 ||\n          current_timer.it_value.tv_usec != 0);\n}\n\nclass VirtualTimerGetterThread : public Thread {\n public:\n  VirtualTimerGetterThread() {\n    memset(&virtual_timer_, 0, sizeof virtual_timer_);\n  }\n  struct itimerval virtual_timer_;\n\n private:\n  void Run() {\n    CHECK_EQ(0, getitimer(ITIMER_VIRTUAL, &virtual_timer_));\n  }\n};\n\n// This function checks whether the timers are shared between thread. This\n// function spawns a thread, so use it carefully when testing thread-dependent\n// behaviour.\nstatic bool threads_have_separate_timers() {\n  struct itimerval new_timer_val;\n\n  // Enable the virtual timer in the current thread.\n  memset(&new_timer_val, 0, sizeof new_timer_val);\n  new_timer_val.it_value.tv_sec = 1000000;  // seconds\n  CHECK_EQ(0, setitimer(ITIMER_VIRTUAL, &new_timer_val, NULL));\n\n  // Spawn a thread, get the virtual timer's value there.\n  VirtualTimerGetterThread thread;\n  thread.SetJoinable(true);\n  thread.Start();\n  thread.Join();\n\n  // Disable timer here.\n  memset(&new_timer_val, 0, sizeof new_timer_val);\n  CHECK_EQ(0, setitimer(ITIMER_VIRTUAL, &new_timer_val, NULL));\n\n  bool target_timer_enabled = (thread.virtual_timer_.it_value.tv_sec != 0 ||\n                               thread.virtual_timer_.it_value.tv_usec != 0);\n  if (!target_timer_enabled) {\n    LOG(INFO, \"threads have separate timers\");\n    return true;\n  } else {\n    LOG(INFO, \"threads have shared timers\");\n    return false;\n  }\n}\n\n// Dummy worker thread to accumulate cpu time.\nclass BusyThread : public Thread {\n public:\n  BusyThread() : stop_work_(false) {\n  }\n\n  // Setter/Getters\n  bool stop_work() {\n    MutexLock lock(&mu_);\n    return stop_work_;\n  }\n  void set_stop_work(bool stop_work) {\n    MutexLock lock(&mu_);\n    stop_work_ = stop_work;\n  }\n\n private:\n  // Protects stop_work_ below.\n  Mutex mu_;\n  // Whether to stop work?\n  bool stop_work_;\n\n  // Do work until asked to stop.\n  void Run() {\n    while (!stop_work()) {\n    }\n    // If timers are separate, check that timer is enabled for this thread.\n    EXPECT_TRUE(!timer_separate_ || IsTimerEnabled());\n  }\n};\n\nclass NullThread : public Thread {\n private:\n  void Run() {\n    // If timers are separate, check that timer is enabled for this thread.\n    EXPECT_TRUE(!timer_separate_ || IsTimerEnabled());\n  }\n};\n\n// Signal handler which tracks the profile timer ticks.\nstatic void TickCounter(int sig, siginfo_t* sig_info, void *vuc,\n                        void* tick_counter) {\n  int* counter = static_cast<int*>(tick_counter);\n  ++(*counter);\n}\n\n// This class tests the profile-handler.h interface.\nclass ProfileHandlerTest {\n protected:\n\n  // Determines whether threads have separate timers.\n  static void SetUpTestCase() {\n    timer_type_ = (getenv(\"CPUPROFILE_REALTIME\") ? ITIMER_REAL : ITIMER_PROF);\n    signal_number_ = (getenv(\"CPUPROFILE_REALTIME\") ? SIGALRM : SIGPROF);\n\n    timer_separate_ = threads_have_separate_timers();\n    Delay(kTimerResetInterval);\n  }\n\n  // Sets up the profile timers and SIGPROF/SIGALRM handler in a known state.\n  // It does the following:\n  // 1. Unregisters all the callbacks, stops the timer (if shared) and\n  //    clears out timer_sharing state in the ProfileHandler. This clears\n  //    out any state left behind by the previous test or during module\n  //    initialization when the test program was started.\n  // 2. Spawns two threads which will be registered with the ProfileHandler.\n  //    At this time ProfileHandler knows if the timers are shared.\n  // 3. Starts a busy worker thread to accumulate CPU usage.\n  virtual void SetUp() {\n    // Reset the state of ProfileHandler between each test. This unregisters\n    // all callbacks, stops timer (if shared) and clears timer sharing state.\n    ProfileHandlerReset();\n    EXPECT_EQ(0, GetCallbackCount());\n    VerifyDisabled();\n    // ProfileHandler requires at least two threads to be registerd to determine\n    // whether timers are shared.\n    RegisterThread();\n    RegisterThread();\n    // Now that two threads are started, verify that the signal handler is\n    // disabled and the timers are correctly enabled/disabled.\n    VerifyDisabled();\n    // Start worker to accumulate cpu usage.\n    StartWorker();\n  }\n\n  virtual void TearDown() {\n    ProfileHandlerReset();\n    // Stops the worker thread.\n    StopWorker();\n  }\n\n  // Starts a no-op thread that gets registered with the ProfileHandler. Waits\n  // for the thread to stop.\n  void RegisterThread() {\n    NullThread t;\n    t.SetJoinable(true);\n    t.Start();\n    t.Join();\n  }\n\n  // Starts a busy worker thread to accumulate cpu time. There should be only\n  // one busy worker running. This is required for the case where there are\n  // separate timers for each thread.\n  void StartWorker() {\n    busy_worker_ = new BusyThread();\n    busy_worker_->SetJoinable(true);\n    busy_worker_->Start();\n    // Wait for worker to start up and register with the ProfileHandler.\n    // TODO(nabeelmian) This may not work under very heavy load.\n    Delay(kSleepInterval);\n  }\n\n  // Stops the worker thread.\n  void StopWorker() {\n    busy_worker_->set_stop_work(true);\n    busy_worker_->Join();\n    delete busy_worker_;\n  }\n\n  // Checks whether SIGPROF/SIGALRM signal handler is enabled.\n  bool IsSignalEnabled() {\n    struct sigaction sa;\n    CHECK_EQ(sigaction(signal_number_, NULL, &sa), 0);\n    return ((sa.sa_handler == SIG_IGN) || (sa.sa_handler == SIG_DFL)) ?\n        false : true;\n  }\n\n  // Gets the number of callbacks registered with the ProfileHandler.\n  uint32 GetCallbackCount() {\n    ProfileHandlerState state;\n    ProfileHandlerGetState(&state);\n    return state.callback_count;\n  }\n\n  // Gets the current ProfileHandler interrupt count.\n  uint64 GetInterruptCount() {\n    ProfileHandlerState state;\n    ProfileHandlerGetState(&state);\n    return state.interrupts;\n  }\n\n  // Verifies that a callback is correctly registered and receiving\n  // profile ticks.\n  void VerifyRegistration(const int& tick_counter) {\n    // Check the callback count.\n    EXPECT_GT(GetCallbackCount(), 0);\n    // Check that the profile timer is enabled.\n    EXPECT_TRUE(IsTimerEnabled());\n    // Check that the signal handler is enabled.\n    EXPECT_TRUE(IsSignalEnabled());\n    uint64 interrupts_before = GetInterruptCount();\n    // Sleep for a bit and check that tick counter is making progress.\n    int old_tick_count = tick_counter;\n    Delay(kSleepInterval);\n    int new_tick_count = tick_counter;\n    EXPECT_GT(new_tick_count, old_tick_count);\n    uint64 interrupts_after = GetInterruptCount();\n    EXPECT_GT(interrupts_after, interrupts_before);\n  }\n\n  // Verifies that a callback is not receiving profile ticks.\n  void VerifyUnregistration(const int& tick_counter) {\n    // Sleep for a bit and check that tick counter is not making progress.\n    int old_tick_count = tick_counter;\n    Delay(kSleepInterval);\n    int new_tick_count = tick_counter;\n    EXPECT_EQ(old_tick_count, new_tick_count);\n    // If no callbacks, signal handler and shared timer should be disabled.\n    if (GetCallbackCount() == 0) {\n      EXPECT_FALSE(IsSignalEnabled());\n      if (timer_separate_) {\n        EXPECT_TRUE(IsTimerEnabled());\n      } else {\n        EXPECT_FALSE(IsTimerEnabled());\n      }\n    }\n  }\n\n  // Verifies that the SIGPROF/SIGALRM interrupt handler is disabled and the\n  // timer, if shared, is disabled. Expects the worker to be running.\n  void VerifyDisabled() {\n    // Check that the signal handler is disabled.\n    EXPECT_FALSE(IsSignalEnabled());\n    // Check that the callback count is 0.\n    EXPECT_EQ(0, GetCallbackCount());\n    // Check that the timer is disabled if shared, enabled otherwise.\n    if (timer_separate_) {\n      EXPECT_TRUE(IsTimerEnabled());\n    } else {\n      EXPECT_FALSE(IsTimerEnabled());\n    }\n    // Verify that the ProfileHandler is not accumulating profile ticks.\n    uint64 interrupts_before = GetInterruptCount();\n    Delay(kSleepInterval);\n    uint64 interrupts_after = GetInterruptCount();\n    EXPECT_EQ(interrupts_before, interrupts_after);\n  }\n\n  // Registers a callback and waits for kTimerResetInterval for timers to get\n  // reset.\n  ProfileHandlerToken* RegisterCallback(void* callback_arg) {\n    ProfileHandlerToken* token = ProfileHandlerRegisterCallback(\n        TickCounter, callback_arg);\n    Delay(kTimerResetInterval);\n    return token;\n  }\n\n  // Unregisters a callback and waits for kTimerResetInterval for timers to get\n  // reset.\n  void UnregisterCallback(ProfileHandlerToken* token) {\n    ProfileHandlerUnregisterCallback(token);\n    Delay(kTimerResetInterval);\n  }\n\n  // Busy worker thread to accumulate cpu usage.\n  BusyThread* busy_worker_;\n\n private:\n  // The tests to run\n  void RegisterUnregisterCallback();\n  void MultipleCallbacks();\n  void Reset();\n  void RegisterCallbackBeforeThread();\n\n public:\n#define RUN(test)  do {                         \\\n    printf(\"Running %s\\n\", #test);              \\\n    ProfileHandlerTest pht;                     \\\n    pht.SetUp();                                \\\n    pht.test();                                 \\\n    pht.TearDown();                             \\\n} while (0)\n\n  static int RUN_ALL_TESTS() {\n    SetUpTestCase();\n    RUN(RegisterUnregisterCallback);\n    RUN(MultipleCallbacks);\n    RUN(Reset);\n    RUN(RegisterCallbackBeforeThread);\n    printf(\"Done\\n\");\n    return 0;\n  }\n};\n\n// Verifies ProfileHandlerRegisterCallback and\n// ProfileHandlerUnregisterCallback.\nTEST_F(ProfileHandlerTest, RegisterUnregisterCallback) {\n  int tick_count = 0;\n  ProfileHandlerToken* token = RegisterCallback(&tick_count);\n  VerifyRegistration(tick_count);\n  UnregisterCallback(token);\n  VerifyUnregistration(tick_count);\n}\n\n// Verifies that multiple callbacks can be registered.\nTEST_F(ProfileHandlerTest, MultipleCallbacks) {\n  // Register first callback.\n  int first_tick_count;\n  ProfileHandlerToken* token1 = RegisterCallback(&first_tick_count);\n  // Check that callback was registered correctly.\n  VerifyRegistration(first_tick_count);\n  EXPECT_EQ(1, GetCallbackCount());\n\n  // Register second callback.\n  int second_tick_count;\n  ProfileHandlerToken* token2 = RegisterCallback(&second_tick_count);\n  // Check that callback was registered correctly.\n  VerifyRegistration(second_tick_count);\n  EXPECT_EQ(2, GetCallbackCount());\n\n  // Unregister first callback.\n  UnregisterCallback(token1);\n  VerifyUnregistration(first_tick_count);\n  EXPECT_EQ(1, GetCallbackCount());\n  // Verify that second callback is still registered.\n  VerifyRegistration(second_tick_count);\n\n  // Unregister second callback.\n  UnregisterCallback(token2);\n  VerifyUnregistration(second_tick_count);\n  EXPECT_EQ(0, GetCallbackCount());\n\n  // Verify that the signal handler and timers are correctly disabled.\n  VerifyDisabled();\n}\n\n// Verifies ProfileHandlerReset\nTEST_F(ProfileHandlerTest, Reset) {\n  // Verify that the profile timer interrupt is disabled.\n  VerifyDisabled();\n  int first_tick_count;\n  RegisterCallback(&first_tick_count);\n  VerifyRegistration(first_tick_count);\n  EXPECT_EQ(1, GetCallbackCount());\n\n  // Register second callback.\n  int second_tick_count;\n  RegisterCallback(&second_tick_count);\n  VerifyRegistration(second_tick_count);\n  EXPECT_EQ(2, GetCallbackCount());\n\n  // Reset the profile handler and verify that callback were correctly\n  // unregistered and timer/signal are disabled.\n  ProfileHandlerReset();\n  VerifyUnregistration(first_tick_count);\n  VerifyUnregistration(second_tick_count);\n  VerifyDisabled();\n}\n\n// Verifies that ProfileHandler correctly handles a case where a callback was\n// registered before the second thread started.\nTEST_F(ProfileHandlerTest, RegisterCallbackBeforeThread) {\n  // Stop the worker.\n  StopWorker();\n  // Unregister all existing callbacks, stop the timer (if shared), disable\n  // the signal handler and reset the timer sharing state in the Profile\n  // Handler.\n  ProfileHandlerReset();\n  EXPECT_EQ(0, GetCallbackCount());\n  VerifyDisabled();\n\n  // Start the worker. At this time ProfileHandler doesn't know if timers are\n  // shared as only one thread has registered so far.\n  StartWorker();\n  // Register a callback and check that profile ticks are being delivered.\n  int tick_count;\n  RegisterCallback(&tick_count);\n  EXPECT_EQ(1, GetCallbackCount());\n  VerifyRegistration(tick_count);\n\n  // Register a second thread and verify that timer and signal handler are\n  // correctly enabled.\n  RegisterThread();\n  EXPECT_EQ(1, GetCallbackCount());\n  EXPECT_TRUE(IsTimerEnabled());\n  EXPECT_TRUE(IsSignalEnabled());\n}\n\n}  // namespace\n\nint main(int argc, char** argv) {\n  return ProfileHandlerTest::RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/profiledata_unittest.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// ---\n// Author: Chris Demetriou\n//\n// This file contains the unit tests for the ProfileData class.\n\n#if defined HAVE_STDINT_H\n#include <stdint.h>             // to get uintptr_t\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>           // another place uintptr_t might be defined\n#endif\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <fcntl.h>\n#include <string.h>\n#include <string>\n\n#include \"profiledata.h\"\n\n#include \"base/commandlineflags.h\"\n#include \"base/logging.h\"\n\nusing std::string;\n\n// Some helpful macros for the test class\n#define TEST_F(cls, fn)    void cls :: fn()\n\nnamespace {\n\ntemplate<typename T> class scoped_array {\n public:\n  scoped_array(T* data) : data_(data) { }\n  ~scoped_array() { delete[] data_; }\n  T* get() { return data_; }\n  T& operator[](int i) { return data_[i]; }\n private:\n  T* const data_;\n};\n\n// Re-runs fn until it doesn't cause EINTR.\n#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)\n\n// Read up to \"count\" bytes from file descriptor \"fd\" into the buffer\n// starting at \"buf\" while handling short reads and EINTR.  On\n// success, return the number of bytes read.  Otherwise, return -1.\nstatic ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {\n  CHECK_GE(fd, 0);\n  char *buf0 = reinterpret_cast<char *>(buf);\n  ssize_t num_bytes = 0;\n  while (num_bytes < count) {\n    ssize_t len;\n    NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes));\n    if (len < 0) {  // There was an error other than EINTR.\n      return -1;\n    }\n    if (len == 0) {  // Reached EOF.\n      break;\n    }\n    num_bytes += len;\n  }\n  CHECK(num_bytes <= count);\n  return num_bytes;\n}\n\n// Thin wrapper around a file descriptor so that the file descriptor\n// gets closed for sure.\nstruct FileDescriptor {\n  const int fd_;\n  explicit FileDescriptor(int fd) : fd_(fd) {}\n  ~FileDescriptor() {\n    if (fd_ >= 0) {\n      NO_INTR(close(fd_));\n    }\n  }\n  int get() { return fd_; }\n};\n\n// must be the same as with ProfileData::Slot.\ntypedef uintptr_t ProfileDataSlot;\n\n// Quick and dirty function to make a number into a void* for use in a\n// sample.\ninline void* V(intptr_t x) { return reinterpret_cast<void*>(x); }\n\n// String returned by ProfileDataChecker helper functions to indicate success.\nconst char kNoError[] = \"\";\n\nclass ProfileDataChecker {\n public:\n  ProfileDataChecker() {\n    const char* tmpdir = getenv(\"TMPDIR\");\n    if (tmpdir == NULL)\n      tmpdir = \"/tmp\";\n    mkdir(tmpdir, 0755);     // if necessary\n    filename_ = string(tmpdir) + \"/profiledata_unittest.tmp\";\n  }\n\n  string filename() const { return filename_; }\n\n  // Checks the first 'num_slots' profile data slots in the file\n  // against the data pointed to by 'slots'.  Returns kNoError if the\n  // data matched, otherwise returns an indication of the cause of the\n  // mismatch.\n  string Check(const ProfileDataSlot* slots, int num_slots) {\n    return CheckWithSkips(slots, num_slots, NULL, 0);\n  }\n\n  // Checks the first 'num_slots' profile data slots in the file\n  // against the data pointed to by 'slots', skipping over entries\n  // described by 'skips' and 'num_skips'.\n  //\n  // 'skips' must be a sorted list of (0-based) slot numbers to be\n  // skipped, of length 'num_skips'.  Note that 'num_slots' includes\n  // any skipped slots, i.e., the first 'num_slots' profile data slots\n  // will be considered, but some may be skipped.\n  //\n  // Returns kNoError if the data matched, otherwise returns an\n  // indication of the cause of the mismatch.\n  string CheckWithSkips(const ProfileDataSlot* slots, int num_slots,\n                        const int* skips, int num_skips);\n\n  // Validate that a profile is correctly formed.  The profile is\n  // assumed to have been created by the same kind of binary (e.g.,\n  // same slot size, same endian, etc.) as is validating the profile.\n  //\n  // Returns kNoError if the profile appears valid, otherwise returns\n  // an indication of the problem with the profile.\n  string ValidateProfile();\n\n private:\n  string filename_;\n};\n\nstring ProfileDataChecker::CheckWithSkips(const ProfileDataSlot* slots,\n                                          int num_slots, const int* skips,\n                                          int num_skips) {\n  FileDescriptor fd(open(filename_.c_str(), O_RDONLY));\n  if (fd.get() < 0)\n    return \"file open error\";\n\n  scoped_array<ProfileDataSlot> filedata(new ProfileDataSlot[num_slots]);\n  size_t expected_bytes = num_slots * sizeof filedata[0];\n  ssize_t bytes_read = ReadPersistent(fd.get(), filedata.get(), expected_bytes);\n  if (expected_bytes != bytes_read)\n    return \"file too small\";\n\n  for (int i = 0; i < num_slots; i++) {\n    if (num_skips > 0 && *skips == i) {\n      num_skips--;\n      skips++;\n      continue;\n    }\n    if (slots[i] != filedata[i])\n      return \"data mismatch\";\n  }\n  return kNoError;\n}\n\nstring ProfileDataChecker::ValidateProfile() {\n  FileDescriptor fd(open(filename_.c_str(), O_RDONLY));\n  if (fd.get() < 0)\n    return \"file open error\";\n\n  struct stat statbuf;\n  if (fstat(fd.get(), &statbuf) != 0)\n    return \"fstat error\";\n  if (statbuf.st_size != static_cast<ssize_t>(statbuf.st_size))\n    return \"file impossibly large\";\n  ssize_t filesize = statbuf.st_size;\n\n  scoped_array<char> filedata(new char[filesize]);\n  if (ReadPersistent(fd.get(), filedata.get(), filesize) != filesize)\n    return \"read of whole file failed\";\n\n  // Must have enough data for the header and the trailer.\n  if (filesize < (5 + 3) * sizeof(ProfileDataSlot))\n    return \"not enough data in profile for header + trailer\";\n\n  // Check the header\n  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[0] != 0)\n    return \"error in header: non-zero count\";\n  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[1] != 3)\n    return \"error in header: num_slots != 3\";\n  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[2] != 0)\n    return \"error in header: non-zero format version\";\n  // Period (slot 3) can have any value.\n  if (reinterpret_cast<ProfileDataSlot*>(filedata.get())[4] != 0)\n    return \"error in header: non-zero padding value\";\n  ssize_t cur_offset = 5 * sizeof(ProfileDataSlot);\n\n  // While there are samples, skip them.  Each sample consists of\n  // at least three slots.\n  bool seen_trailer = false;\n  while (!seen_trailer) {\n    if (cur_offset > filesize - 3 * sizeof(ProfileDataSlot))\n      return \"truncated sample header\";\n    ProfileDataSlot* sample =\n        reinterpret_cast<ProfileDataSlot*>(filedata.get() + cur_offset);\n    ProfileDataSlot slots_this_sample = 2 + sample[1];\n    ssize_t size_this_sample = slots_this_sample * sizeof(ProfileDataSlot);\n    if (cur_offset > filesize - size_this_sample)\n      return \"truncated sample\";\n\n    if (sample[0] == 0 && sample[1] == 1 && sample[2] == 0) {\n      seen_trailer = true;\n    } else {\n      if (sample[0] < 1)\n        return \"error in sample: sample count < 1\";\n      if (sample[1] < 1)\n        return \"error in sample: num_pcs < 1\";\n      for (int i = 2; i < slots_this_sample; i++) {\n        if (sample[i] == 0)\n          return \"error in sample: NULL PC\";\n      }\n    }\n    cur_offset += size_this_sample;\n  }\n\n  // There must be at least one line in the (text) list of mapped objects,\n  // and it must be terminated by a newline.  Note, the use of newline\n  // here and below Might not be reasonable on non-UNIX systems.\n  if (cur_offset >= filesize)\n    return \"no list of mapped objects\";\n  if (filedata[filesize - 1] != '\\n')\n    return \"profile did not end with a complete line\";\n\n  while (cur_offset < filesize) {\n    char* line_start = filedata.get() + cur_offset;\n\n    // Find the end of the line, and replace it with a NUL for easier\n    // scanning.\n    char* line_end = strchr(line_start, '\\n');\n    *line_end = '\\0';\n\n    // Advance past any leading space.  It's allowed in some lines,\n    // but not in others.\n    bool has_leading_space = false;\n    char* line_cur = line_start;\n    while (*line_cur == ' ') {\n      has_leading_space = true;\n      line_cur++;\n    }\n\n    bool found_match = false;\n\n    // Check for build lines.\n    if (!found_match) {\n      found_match = (strncmp(line_cur, \"build=\", 6) == 0);\n      // Anything may follow \"build=\", and leading space is allowed.\n    }\n\n    // A line from ProcMapsIterator::FormatLine, of the form:\n    //\n    // 40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so\n    //\n    // Leading space is not allowed.  The filename may be omitted or\n    // may consist of multiple words, so we scan only up to the\n    // space before the filename.\n    if (!found_match) {\n      int chars_scanned = -1;\n      sscanf(line_cur, \"%*x-%*x %*c%*c%*c%*c %*x %*x:%*x %*d %n\",\n             &chars_scanned);\n      found_match = (chars_scanned > 0 && !has_leading_space);\n    }\n\n    // A line from DumpAddressMap, of the form:\n    //\n    // 40000000-40015000: /lib/ld-2.3.2.so\n    //\n    // Leading space is allowed.  The filename may be omitted or may\n    // consist of multiple words, so we scan only up to the space\n    // before the filename.\n    if (!found_match) {\n      int chars_scanned = -1;\n      sscanf(line_cur, \"%*x-%*x: %n\", &chars_scanned);\n      found_match = (chars_scanned > 0);\n    }\n\n    if (!found_match)\n      return \"unrecognized line in text section\";\n\n    cur_offset += (line_end - line_start) + 1;\n  }\n\n  return kNoError;\n}\n\nclass ProfileDataTest {\n protected:\n  void ExpectStopped() {\n    EXPECT_FALSE(collector_.enabled());\n  }\n\n  void ExpectRunningSamples(int samples) {\n    ProfileData::State state;\n    collector_.GetCurrentState(&state);\n    EXPECT_TRUE(state.enabled);\n    EXPECT_EQ(samples, state.samples_gathered);\n  }\n\n  void ExpectSameState(const ProfileData::State& before,\n                       const ProfileData::State& after) {\n    EXPECT_EQ(before.enabled, after.enabled);\n    EXPECT_EQ(before.samples_gathered, after.samples_gathered);\n    EXPECT_EQ(before.start_time, after.start_time);\n    EXPECT_STREQ(before.profile_name, after.profile_name);\n  }\n\n  ProfileData        collector_;\n  ProfileDataChecker checker_;\n\n private:\n  // The tests to run\n  void OpsWhenStopped();\n  void StartStopEmpty();\n  void StartStopNoOptionsEmpty();\n  void StartWhenStarted();\n  void StartStopEmpty2();\n  void CollectOne();\n  void CollectTwoMatching();\n  void CollectTwoFlush();\n  void StartResetRestart();\n\n public:\n#define RUN(test)  do {                         \\\n    printf(\"Running %s\\n\", #test);              \\\n    ProfileDataTest pdt;                        \\\n    pdt.test();                                 \\\n} while (0)\n\n  static int RUN_ALL_TESTS() {\n    RUN(OpsWhenStopped);\n    RUN(StartStopEmpty);\n    RUN(StartWhenStarted);\n    RUN(StartStopEmpty2);\n    RUN(CollectOne);\n    RUN(CollectTwoMatching);\n    RUN(CollectTwoFlush);\n    RUN(StartResetRestart);\n    return 0;\n  }\n};\n\n// Check that various operations are safe when stopped.\nTEST_F(ProfileDataTest, OpsWhenStopped) {\n  ExpectStopped();\n  EXPECT_FALSE(collector_.enabled());\n\n  // Verify that state is disabled, all-empty/all-0\n  ProfileData::State state_before;\n  collector_.GetCurrentState(&state_before);\n  EXPECT_FALSE(state_before.enabled);\n  EXPECT_EQ(0, state_before.samples_gathered);\n  EXPECT_EQ(0, state_before.start_time);\n  EXPECT_STREQ(\"\", state_before.profile_name);\n\n  // Safe to call stop again.\n  collector_.Stop();\n\n  // Safe to call FlushTable.\n  collector_.FlushTable();\n\n  // Safe to call Add.\n  const void *trace[] = { V(100), V(101), V(102), V(103), V(104) };\n  collector_.Add(arraysize(trace), trace);\n\n  ProfileData::State state_after;\n  collector_.GetCurrentState(&state_after);\n\n  ExpectSameState(state_before, state_after);\n}\n\n// Start and Stop, collecting no samples.  Verify output contents.\nTEST_F(ProfileDataTest, StartStopEmpty) {\n  const int frequency = 1;\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    0, 1, 0                             // binary trailer\n  };\n\n  ExpectStopped();\n  ProfileData::Options options;\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\n// Start and Stop with no options, collecting no samples.  Verify\n// output contents.\nTEST_F(ProfileDataTest, StartStopNoOptionsEmpty) {\n  // We're not requesting a specific period, implementation can do\n  // whatever it likes.\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 0 /* skipped */, 0,        // binary header\n    0, 1, 0                             // binary trailer\n  };\n  int slots_to_skip[] = { 3 };\n\n  ExpectStopped();\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(),\n                               ProfileData::Options()));\n  ExpectRunningSamples(0);\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.CheckWithSkips(slots, arraysize(slots),\n                                              slots_to_skip,\n                                              arraysize(slots_to_skip)));\n}\n\n// Start after already started.  Should return false and not impact\n// collected data or state.\nTEST_F(ProfileDataTest, StartWhenStarted) {\n  const int frequency = 1;\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    0, 1, 0                             // binary trailer\n  };\n\n  ProfileData::Options options;\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n\n  ProfileData::State state_before;\n  collector_.GetCurrentState(&state_before);\n\n  options.set_frequency(frequency * 2);\n  CHECK(!collector_.Start(\"foobar\", options));\n\n  ProfileData::State state_after;\n  collector_.GetCurrentState(&state_after);\n  ExpectSameState(state_before, state_after);\n\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\n// Like StartStopEmpty, but uses a different file name and frequency.\nTEST_F(ProfileDataTest, StartStopEmpty2) {\n  const int frequency = 2;\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    0, 1, 0                             // binary trailer\n  };\n\n  ExpectStopped();\n  ProfileData::Options options;\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\nTEST_F(ProfileDataTest, CollectOne) {\n  const int frequency = 2;\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    1, 5, 100, 101, 102, 103, 104,      // our sample\n    0, 1, 0                             // binary trailer\n  };\n\n  ExpectStopped();\n  ProfileData::Options options;\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n\n  const void *trace[] = { V(100), V(101), V(102), V(103), V(104) };\n  collector_.Add(arraysize(trace), trace);\n  ExpectRunningSamples(1);\n\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\nTEST_F(ProfileDataTest, CollectTwoMatching) {\n  const int frequency = 2;\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    2, 5, 100, 201, 302, 403, 504,      // our two samples\n    0, 1, 0                             // binary trailer\n  };\n\n  ExpectStopped();\n  ProfileData::Options options;\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n\n  for (int i = 0; i < 2; ++i) {\n    const void *trace[] = { V(100), V(201), V(302), V(403), V(504) };\n    collector_.Add(arraysize(trace), trace);\n    ExpectRunningSamples(i + 1);\n  }\n\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\nTEST_F(ProfileDataTest, CollectTwoFlush) {\n  const int frequency = 2;\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    1, 5, 100, 201, 302, 403, 504,      // first sample (flushed)\n    1, 5, 100, 201, 302, 403, 504,      // second identical sample\n    0, 1, 0                             // binary trailer\n  };\n\n  ExpectStopped();\n  ProfileData::Options options;\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n\n  const void *trace[] = { V(100), V(201), V(302), V(403), V(504) };\n\n  collector_.Add(arraysize(trace), trace);\n  ExpectRunningSamples(1);\n  collector_.FlushTable();\n\n  collector_.Add(arraysize(trace), trace);\n  ExpectRunningSamples(2);\n\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\n// Start then reset, verify that the result is *not* a valid profile.\n// Then start again and make sure the result is OK.\nTEST_F(ProfileDataTest, StartResetRestart) {\n  ExpectStopped();\n  ProfileData::Options options;\n  options.set_frequency(1);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n  collector_.Reset();\n  ExpectStopped();\n  // We expect the resulting file to be empty.  This is a minimal test\n  // of ValidateProfile.\n  EXPECT_NE(kNoError, checker_.ValidateProfile());\n\n  struct stat statbuf;\n  EXPECT_EQ(0, stat(checker_.filename().c_str(), &statbuf));\n  EXPECT_EQ(0, statbuf.st_size);\n\n  const int frequency = 2;  // Different frequency than used above.\n  ProfileDataSlot slots[] = {\n    0, 3, 0, 1000000 / frequency, 0,    // binary header\n    0, 1, 0                             // binary trailer\n  };\n\n  options.set_frequency(frequency);\n  EXPECT_TRUE(collector_.Start(checker_.filename().c_str(), options));\n  ExpectRunningSamples(0);\n  collector_.Stop();\n  ExpectStopped();\n  EXPECT_EQ(kNoError, checker_.ValidateProfile());\n  EXPECT_EQ(kNoError, checker_.Check(slots, arraysize(slots)));\n}\n\n}  // namespace\n\nint main(int argc, char** argv) {\n  int rc = ProfileDataTest::RUN_ALL_TESTS();\n  printf(\"%s\\n\", rc == 0 ? \"PASS\" : \"FAIL\");\n  return rc;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/profiler_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// Does some simple arithmetic and a few libc routines, so we can profile it.\n// Define WITH_THREADS to add pthread functionality as well (otherwise, btw,\n// the num_threads argument to this program is ingored).\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>                 // for fork()\n#endif\n#include <sys/wait.h>               // for wait()\n#include \"google/profiler.h\"\n#include \"base/simple_mutex.h\"\n#include \"tests/testutil.h\"\n\nstatic int result = 0;\nstatic int g_iters = 0;   // argv[1]\n\nMutex mutex(Mutex::LINKER_INITIALIZED);\n\nstatic void test_other_thread() {\n#ifndef NO_THREADS\n  ProfilerRegisterThread();\n\n  int i, m;\n  char b[128];\n  MutexLock ml(&mutex);\n  for (m = 0; m < 1000000; ++m) {          // run millions of times\n    for (i = 0; i < g_iters; ++i ) {\n      result ^= i;\n    }\n    snprintf(b, sizeof(b), \"%d\", result);  // get some libc action\n  }\n#endif\n}\n\nstatic void test_main_thread() {\n  int i, m;\n  char b[128];\n  MutexLock ml(&mutex);\n  for (m = 0; m < 1000000; ++m) {          // run millions of times\n    for (i = 0; i < g_iters; ++i ) {\n      result ^= i;\n    }\n    snprintf(b, sizeof(b), \"%d\", result);  // get some libc action\n  }\n}\n\nint main(int argc, char** argv) {\n  if ( argc <= 1 ) {\n    fprintf(stderr, \"USAGE: %s <iters> [num_threads] [filename]\\n\", argv[0]);\n    fprintf(stderr, \"   iters: How many million times to run the XOR test.\\n\");\n    fprintf(stderr, \"   num_threads: how many concurrent threads.\\n\");\n    fprintf(stderr, \"                0 or 1 for single-threaded mode,\\n\");\n    fprintf(stderr, \"                -# to fork instead of thread.\\n\");\n    fprintf(stderr, \"   filename: The name of the output profile.\\n\");\n    fprintf(stderr, (\"             If you don't specify, set CPUPROFILE \"\n                     \"in the environment instead!\\n\"));\n    return 1;\n  }\n\n  g_iters = atoi(argv[1]);\n  int num_threads = 1;\n  const char* filename = NULL;\n  if (argc > 2) {\n    num_threads = atoi(argv[2]);\n  }\n  if (argc > 3) {\n    filename = argv[3];\n  }\n\n  if (filename) {\n    ProfilerStart(filename);\n  }\n\n  test_main_thread();\n\n  ProfilerFlush();                           // just because we can\n\n  // The other threads, if any, will run only half as long as the main thread\n  RunManyThreads(test_other_thread, num_threads);\n\n  // Or maybe they asked to fork.  The fork test is only interesting\n  // when we use CPUPROFILE to name, so check for that\n#ifdef HAVE_UNISTD_H\n  for (; num_threads < 0; ++num_threads) {   // -<num_threads> to fork\n    if (filename) {\n      printf(\"FORK test only makes sense when no filename is specified.\\n\");\n      return 2;\n    }\n    switch (fork()) {\n      case -1:\n        printf(\"FORK failed!\\n\");\n        return 1;\n      case 0:             // child\n        return execl(argv[0], argv[0], argv[1], NULL);\n      default:\n        wait(NULL);       // we'll let the kids run one at a time\n    }\n  }\n#endif\n\n  test_main_thread();\n\n  if (filename) {\n    ProfilerStop();\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/profiler_unittest.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2005, Google Inc.\n# All rights reserved.\n# \n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n# \n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n# \n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n# ---\n# Author: Craig Silverstein\n#\n# Runs the 4 profiler unittests and makes sure their profiles look\n# appropriate.  We expect two commandline args, as described below.\n#\n# We run under the assumption that if $PROFILER1 is run with no\n# arguments, it prints a usage line of the form\n#   USAGE: <actual executable being run> [...]\n#\n# This is because libtool sometimes turns the 'executable' into a\n# shell script which runs an actual binary somewhere else.\n\n# We expect BINDIR and PPROF_PATH to be set in the environment.\n# If not, we set them to some reasonable values\nBINDIR=\"${BINDIR:-.}\"\nPPROF_PATH=\"${PPROF_PATH:-$BINDIR/src/pprof}\"\n\nif [ \"x$1\" = \"x-h\" -o \"x$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir] [path to pprof]\"\n  echo \"       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH\"\n  exit 1\nfi\n\nTMPDIR=/tmp/profile_info\n\nUNITTEST_DIR=${1:-$BINDIR}\nPPROF=${2:-$PPROF_PATH}\n\n# We test the sliding-window functionality of the cpu-profile reader\n# by using a small stride, forcing lots of reads.\nPPROF_FLAGS=\"--test_stride=128\"\n\nPROFILER1=\"$UNITTEST_DIR/profiler1_unittest\"\nPROFILER2=\"$UNITTEST_DIR/profiler2_unittest\"\nPROFILER3=\"$UNITTEST_DIR/profiler3_unittest\"\nPROFILER4=\"$UNITTEST_DIR/profiler4_unittest\"\n\n# Unfortunately, for us, libtool can replace executables with a shell\n# script that does some work before calling the 'real' executable\n# under a different name.  We need the 'real' executable name to run\n# pprof on it.  We've constructed all the binaries used in this\n# unittest so when they are called with no arguments, they report\n# their argv[0], which is the real binary name.\nRealname() {\n  \"$1\" 2>&1 | awk '{print $2; exit;}'\n}\n\nPROFILER1_REALNAME=`Realname \"$PROFILER1\"`\nPROFILER2_REALNAME=`Realname \"$PROFILER2\"`\nPROFILER3_REALNAME=`Realname \"$PROFILER3\"`\nPROFILER4_REALNAME=`Realname \"$PROFILER4\"`\n\n# It's meaningful to the profiler, so make sure we know its state\nunset CPUPROFILE\n\nrm -rf \"$TMPDIR\"\nmkdir \"$TMPDIR\" || exit 2\n\nnum_failures=0\n\nRegisterFailure() {\n  num_failures=`expr $num_failures + 1`\n}\n\n# Takes two filenames representing profiles, with their executable scripts,\n# and a multiplier, and verifies that the 'contentful' functions in\n# each profile take the same time (possibly scaled by the given\n# multiplier).  It used to be \"same\" meant within 50%, after adding an \n# noise-reducing X units to each value.  But even that would often\n# spuriously fail, so now it's \"both non-zero\".  We're pretty forgiving.\nVerifySimilar() {\n  prof1=\"$TMPDIR/$1\"\n  exec1=\"$2\"\n  prof2=\"$TMPDIR/$3\"\n  exec2=\"$4\"\n  mult=\"$5\"\n\n  # We are careful not to put exec1 and exec2 in quotes, because if\n  # they are the empty string, it means we want to use the 1-arg\n  # version of pprof.\n  mthread1=`\"$PPROF\" $PPROF_FLAGS $exec1 \"$prof1\" | grep test_main_thread | awk '{print $1}'`\n  mthread2=`\"$PPROF\" $PPROF_FLAGS $exec2 \"$prof2\" | grep test_main_thread | awk '{print $1}'`\n  mthread1_plus=`expr $mthread1 + 5`\n  mthread2_plus=`expr $mthread2 + 5`\n  if [ -z \"$mthread1\" ] || [ -z \"$mthread2\" ] || \\\n     [ \"$mthread1\" -le 0 -o \"$mthread2\" -le 0 ]\n#    || [ `expr $mthread1_plus \\* $mult` -gt `expr $mthread2_plus \\* 2` -o \\\n#         `expr $mthread1_plus \\* $mult \\* 2` -lt `expr $mthread2_plus` ]\n  then\n    echo\n    echo \">>> profile on $exec1 vs $exec2 with multiplier $mult failed:\"\n    echo \"Actual times (in profiling units) were '$mthread1' vs. '$mthread2'\"\n    echo\n    RegisterFailure\n  fi\n}\n\n# Takes two filenames representing profiles, and optionally their\n# executable scripts (these may be empty if the profiles include\n# symbols), and verifies that the two profiles are identical.\nVerifyIdentical() {\n  prof1=\"$TMPDIR/$1\"\n  exec1=\"$2\"\n  prof2=\"$TMPDIR/$3\"\n  exec2=\"$4\"\n\n  # We are careful not to put exec1 and exec2 in quotes, because if\n  # they are the empty string, it means we want to use the 1-arg\n  # version of pprof.\n  \"$PPROF\" $PPROF_FLAGS $exec1 \"$prof1\" > \"$TMPDIR/out1\"\n  \"$PPROF\" $PPROF_FLAGS $exec2 \"$prof2\" > \"$TMPDIR/out2\"\n  diff=`diff \"$TMPDIR/out1\" \"$TMPDIR/out2\"`\n\n  if [ ! -z \"$diff\" ]; then\n    echo\n    echo \">>> profile doesn't match, args: $exec1 $prof1 vs. $exec2 $prof2\"\n    echo \">>> Diff:\"\n    echo \"$diff\"\n    echo\n    RegisterFailure\n  fi\n}\n\n# Takes a filename representing a profile, with its executable,\n# and a multiplier, and verifies that the main-thread function takes\n# the same amount of time as the other-threads function (possibly scaled\n# by the given multiplier).  Figuring out the multiplier can be tricky,\n# since by design the main thread runs twice as long as each of the\n# 'other' threads!  It used to be \"same\" meant within 50%, after adding an \n# noise-reducing X units to each value.  But even that would often\n# spuriously fail, so now it's \"both non-zero\".  We're pretty forgiving.\nVerifyAcrossThreads() {\n  prof1=\"$TMPDIR/$1\"\n  # We need to run the script with no args to get the actual exe name\n  exec1=\"$2\"\n  mult=\"$3\"\n\n  # We are careful not to put exec1 in quotes, because if it is the\n  # empty string, it means we want to use the 1-arg version of pprof.\n  mthread=`$PPROF $PPROF_FLAGS $exec1 \"$prof1\" | grep test_main_thread | awk '{print $1}'`\n  othread=`$PPROF $PPROF_FLAGS $exec1 \"$prof1\" | grep test_other_thread | awk '{print $1}'`\n  if [ -z \"$mthread\" ] || [ -z \"$othread\" ] || \\\n     [ \"$mthread\" -le 0 -o \"$othread\" -le 0 ]\n#    || [ `expr $mthread \\* $mult \\* 3` -gt `expr $othread \\* 10` -o \\\n#         `expr $mthread \\* $mult \\* 10` -lt `expr $othread \\* 3` ]\n  then\n    echo\n    echo \">>> profile on $exec1 (main vs thread) with multiplier $mult failed:\"\n    echo \"Actual times (in profiling units) were '$mthread' vs. '$othread'\"\n    echo\n    RegisterFailure\n  fi\n}\n\necho\necho \">>> WARNING <<<\"\necho \"This test looks at timing information to determine correctness.\"\necho \"If your system is loaded, the test may spuriously fail.\"\necho \"If the test does fail with an 'Actual times' error, try running again.\"\necho\n\n# profiler1 is a non-threaded version\n\"$PROFILER1\" 50 1 \"$TMPDIR/p1\" || RegisterFailure\n\"$PROFILER1\" 100 1 \"$TMPDIR/p2\" || RegisterFailure\nVerifySimilar p1 \"$PROFILER1_REALNAME\" p2 \"$PROFILER1_REALNAME\" 2\n\n# Verify the same thing works if we statically link\n\"$PROFILER2\" 50 1 \"$TMPDIR/p3\" || RegisterFailure\n\"$PROFILER2\" 100 1 \"$TMPDIR/p4\" || RegisterFailure\nVerifySimilar p3 \"$PROFILER2_REALNAME\" p4 \"$PROFILER2_REALNAME\" 2\n\n# Verify the same thing works if we specify via CPUPROFILE\nCPUPROFILE=\"$TMPDIR/p5\" \"$PROFILER2\" 50 || RegisterFailure\nCPUPROFILE=\"$TMPDIR/p6\" \"$PROFILER2\" 100 || RegisterFailure\nVerifySimilar p5 \"$PROFILER2_REALNAME\" p6 \"$PROFILER2_REALNAME\" 2\n\nCPUPROFILE=\"$TMPDIR/p5b\" \"$PROFILER3\" 30 || RegisterFailure\nCPUPROFILE=\"$TMPDIR/p5c\" \"$PROFILER3\" 60 || RegisterFailure\nVerifySimilar p5b \"$PROFILER3_REALNAME\" p5c \"$PROFILER3_REALNAME\" 2\n\n# Now try what happens when we use threads\n\"$PROFILER3\" 30 2 \"$TMPDIR/p7\" || RegisterFailure\n\"$PROFILER3\" 60 2 \"$TMPDIR/p8\" || RegisterFailure\nVerifySimilar p7 \"$PROFILER3_REALNAME\" p8 \"$PROFILER3_REALNAME\" 2\n\n\"$PROFILER4\" 30 2 \"$TMPDIR/p9\" || RegisterFailure\n\"$PROFILER4\" 60 2 \"$TMPDIR/p10\" || RegisterFailure\nVerifySimilar p9 \"$PROFILER4_REALNAME\" p10 \"$PROFILER4_REALNAME\" 2\n\n# More threads!\n\"$PROFILER4\" 25 3 \"$TMPDIR/p9\" || RegisterFailure\n\"$PROFILER4\" 50 3 \"$TMPDIR/p10\" || RegisterFailure\nVerifySimilar p9 \"$PROFILER4_REALNAME\" p10 \"$PROFILER4_REALNAME\" 2\n\n# Compare how much time the main thread takes compared to the other threads\n# Recall the main thread runs twice as long as the other threads, by design.\n\"$PROFILER4\" 20 4 \"$TMPDIR/p11\" || RegisterFailure\nVerifyAcrossThreads p11 \"$PROFILER4_REALNAME\" 2\n\n# Test symbol save and restore\n\"$PROFILER1\" 50 1 \"$TMPDIR/p12\" || RegisterFailure\n\"$PPROF\" $PPROF_FLAGS \"$PROFILER1_REALNAME\" \"$TMPDIR/p12\" --raw \\\n    >\"$TMPDIR/p13\" 2>/dev/null || RegisterFailure\nVerifyIdentical p12 \"$PROFILER1_REALNAME\" p13 \"\" || RegisterFailure\n\n\"$PROFILER3\" 30 2 \"$TMPDIR/p14\" || RegisterFailure\n\"$PPROF\" $PPROF_FLAGS \"$PROFILER3_REALNAME\" \"$TMPDIR/p14\" --raw \\\n    >\"$TMPDIR/p15\" 2>/dev/null || RegisterFailure\nVerifyIdentical p14 \"$PROFILER3_REALNAME\" p15 \"\" || RegisterFailure\n\n# Test using ITIMER_REAL instead of ITIMER_PROF.\nenv CPUPROFILE_REALTIME=1 \"$PROFILER3\" 30 2 \"$TMPDIR/p16\" || RegisterFailure\nenv CPUPROFILE_REALTIME=1 \"$PROFILER3\" 60 2 \"$TMPDIR/p17\" || RegisterFailure\nVerifySimilar p16 \"$PROFILER3_REALNAME\" p17 \"$PROFILER3_REALNAME\" 2\n\n\n# Make sure that when we have a process with a fork, the profiles don't\n# clobber each other\nCPUPROFILE=\"$TMPDIR/pfork\" \"$PROFILER1\" 1 -2 || RegisterFailure\nn=`ls $TMPDIR/pfork* | wc -l`\nif [ $n != 3 ]; then\n  echo \"FORK test FAILED: expected 3 profiles (for main + 2 children), found $n\"\n  num_failures=`expr $num_failures + 1`\nfi\n\nrm -rf \"$TMPDIR\"      # clean up\n\necho \"Tests finished with $num_failures failures\"\nexit $num_failures\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/raw_printer_test.cc",
    "content": "// Copyright 2009 Google Inc. All Rights Reserved.\n// Author: sanjay@google.com (Sanjay Ghemawat)\n\n#include \"raw_printer.h\"\n#include <stdio.h>\n#include <string>\n#include \"base/logging.h\"\n\nusing std::string;\n\n#define TEST(a, b)  void TEST_##a##_##b()\n#define RUN_TEST(a, b)  TEST_##a##_##b()\n\nTEST(RawPrinter, Empty) {\n  char buffer[1];\n  base::RawPrinter printer(buffer, arraysize(buffer));\n  CHECK_EQ(0, printer.length());\n  CHECK_EQ(string(\"\"), buffer);\n  CHECK_EQ(0, printer.space_left());\n  printer.Printf(\"foo\");\n  CHECK_EQ(string(\"\"), string(buffer));\n  CHECK_EQ(0, printer.length());\n  CHECK_EQ(0, printer.space_left());\n}\n\nTEST(RawPrinter, PartiallyFilled) {\n  char buffer[100];\n  base::RawPrinter printer(buffer, arraysize(buffer));\n  printer.Printf(\"%s %s\", \"hello\", \"world\");\n  CHECK_EQ(string(\"hello world\"), string(buffer));\n  CHECK_EQ(11, printer.length());\n  CHECK_LT(0, printer.space_left());\n}\n\nTEST(RawPrinter, Truncated) {\n  char buffer[3];\n  base::RawPrinter printer(buffer, arraysize(buffer));\n  printer.Printf(\"%d\", 12345678);\n  CHECK_EQ(string(\"12\"), string(buffer));\n  CHECK_EQ(2, printer.length());\n  CHECK_EQ(0, printer.space_left());\n}\n\nTEST(RawPrinter, ExactlyFilled) {\n  char buffer[12];\n  base::RawPrinter printer(buffer, arraysize(buffer));\n  printer.Printf(\"%s %s\", \"hello\", \"world\");\n  CHECK_EQ(string(\"hello world\"), string(buffer));\n  CHECK_EQ(11, printer.length());\n  CHECK_EQ(0, printer.space_left());\n}\n\nint main(int argc, char **argv) {\n  RUN_TEST(RawPrinter, Empty);\n  RUN_TEST(RawPrinter, PartiallyFilled);\n  RUN_TEST(RawPrinter, Truncated);\n  RUN_TEST(RawPrinter, ExactlyFilled);\n  printf(\"PASS\\n\");\n  return 0;   // 0 means success\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/realloc_unittest.cc",
    "content": "// Copyright (c) 2004, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Test realloc() functionality\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <algorithm>   // for min()\n#include \"base/logging.h\"\n\nusing std::min;\n\n// Fill a buffer of the specified size with a predetermined pattern\nstatic void Fill(unsigned char* buffer, int n) {\n  for (int i = 0; i < n; i++) {\n    buffer[i] = (i & 0xff);\n  }\n}\n\n// Check that the specified buffer has the predetermined pattern\n// generated by Fill()\nstatic bool Valid(unsigned char* buffer, int n) {\n  for (int i = 0; i < n; i++) {\n    if (buffer[i] != (i & 0xff)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// Return the next interesting size/delta to check.  Returns -1 if no more.\nstatic int NextSize(int size) {\n  if (size < 100) {\n    return size+1;\n  } else if (size < 100000) {\n    // Find next power of two\n    int power = 1;\n    while (power < size) {\n      power <<= 1;\n    }\n\n    // Yield (power-1, power, power+1)\n    if (size < power-1) {\n      return power-1;\n    } else if (size == power-1) {\n      return power;\n    } else {\n      assert(size == power);\n      return power+1;\n    }\n  } else {\n    return -1;\n  }\n}\n\nint main(int argc, char** argv) {\n  for (int src_size = 0; src_size >= 0; src_size = NextSize(src_size)) {\n    for (int dst_size = 0; dst_size >= 0; dst_size = NextSize(dst_size)) {\n      unsigned char* src = (unsigned char*) malloc(src_size);\n      Fill(src, src_size);\n      unsigned char* dst = (unsigned char*) realloc(src, dst_size);\n      CHECK(Valid(dst, min(src_size, dst_size)));\n      Fill(dst, dst_size);\n      CHECK(Valid(dst, dst_size));\n      if (dst != NULL) free(dst);\n    }\n  }\n\n  // Now make sure realloc works correctly even when we overflow the\n  // packed cache, so some entries are evicted from the cache.\n  // The cache has 2^12 entries, keyed by page number.\n  const int kNumEntries = 1 << 14;\n  int** p = (int**)malloc(sizeof(*p) * kNumEntries);\n  int sum = 0;\n  for (int i = 0; i < kNumEntries; i++) {\n    p[i] = (int*)malloc(8192);   // no page size is likely to be bigger\n    p[i][1000] = i;              // use memory deep in the heart of p\n  }\n  for (int i = 0; i < kNumEntries; i++) {\n    p[i] = (int*)realloc(p[i], 9000);\n  }\n  for (int i = 0; i < kNumEntries; i++) {\n    sum += p[i][1000];\n    free(p[i]);\n  }\n  CHECK_EQ(kNumEntries/2 * (kNumEntries - 1), sum);  // assume kNE is even\n  free(p);\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/sampler_test.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// All Rights Reserved.\n//\n// Author: Daniel Ford\n//\n// Checks basic properties of the sampler\n\n#include \"config_for_unittests.h\"\n#include <stdlib.h>        // defines posix_memalign\n#include <stdio.h>         // for the printf at the end\n#if defined HAVE_STDINT_H\n#include <stdint.h>             // to get uintptr_t\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>           // another place uintptr_t might be defined\n#endif\n#include <sys/types.h>\n#include <iostream>\n#include <algorithm>\n#include <vector>\n#include <string>\n#include <cmath>\n#include \"base/logging.h\"\n#include \"base/commandlineflags.h\"\n#include \"sampler.h\"       // The Sampler class being tested\n\nusing std::sort;\nusing std::min;\nusing std::max;\nusing std::vector;\nusing std::abs;\n\nvector<void (*)()> g_testlist;  // the tests to run\n\n#define TEST(a, b)                                      \\\n  struct Test_##a##_##b {                               \\\n    Test_##a##_##b() { g_testlist.push_back(&Run); }    \\\n    static void Run();                                  \\\n  };                                                    \\\n  static Test_##a##_##b g_test_##a##_##b;               \\\n  void Test_##a##_##b::Run()\n\n\nstatic int RUN_ALL_TESTS() {\n  vector<void (*)()>::const_iterator it;\n  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {\n    (*it)();   // The test will error-exit if there's a problem.\n  }\n  fprintf(stderr, \"\\nPassed %d tests\\n\\nPASS\\n\", (int)g_testlist.size());\n  return 0;\n}\n\n#undef LOG   // defined in base/logging.h\n// Ideally, we'd put the newline at the end, but this hack puts the\n// newline at the end of the previous log message, which is good enough :-)\n#define LOG(level)  std::cerr << \"\\n\"\n\nstatic std::string StringPrintf(const char* format, ...) {\n  char buf[256];   // should be big enough for all logging\n  va_list ap;\n  va_start(ap, format);\n  vsnprintf(buf, sizeof(buf), format, ap);\n  va_end(ap);\n  return buf;\n}\n\nnamespace {\ntemplate<typename T> class scoped_array {\n public:\n  scoped_array(T* p) : p_(p) { }\n  ~scoped_array() { delete[] p_; }\n  const T* get() const { return p_; }\n  T* get() { return p_; }\n  T& operator[](int i) { return p_[i]; }\n private:\n  T* p_;\n};\n}\n\n// Note that these tests are stochastic.\n// This mean that the chance of correct code passing the test is,\n// in the case of 5 standard deviations:\n// kSigmas=5:    ~99.99994267%\n// in the case of 4 standard deviations:\n// kSigmas=4:    ~99.993666%\nstatic const double kSigmas = 4;\nstatic const size_t kSamplingInterval = 512*1024;\n\n// Tests that GetSamplePeriod returns the expected value\n// which is 1<<19\nTEST(Sampler, TestGetSamplePeriod) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  uint64_t sample_period;\n  sample_period = sampler.GetSamplePeriod();\n  CHECK_GT(sample_period, 0);\n}\n\n// Tests of the quality of the random numbers generated\n// This uses the Anderson Darling test for uniformity.\n// See \"Evaluating the Anderson-Darling Distribution\" by Marsaglia\n// for details.\n\n// Short cut version of ADinf(z), z>0 (from Marsaglia)\n// This returns the p-value for Anderson Darling statistic in\n// the limit as n-> infinity. For finite n, apply the error fix below.\ndouble AndersonDarlingInf(double z) {\n  if (z < 2) {\n    return exp(-1.2337141 / z) / sqrt(z) * (2.00012 + (0.247105 -\n                (0.0649821 - (0.0347962 - (0.011672 - 0.00168691\n                * z) * z) * z) * z) * z);\n  }\n  return exp( - exp(1.0776 - (2.30695 - (0.43424 - (0.082433 -\n                    (0.008056 - 0.0003146 * z) * z) * z) * z) * z));\n}\n\n// Corrects the approximation error in AndersonDarlingInf for small values of n\n// Add this to AndersonDarlingInf to get a better approximation\n// (from Marsaglia)\ndouble AndersonDarlingErrFix(int n, double x) {\n  if (x > 0.8) {\n    return (-130.2137 + (745.2337 - (1705.091 - (1950.646 -\n            (1116.360 - 255.7844 * x) * x) * x) * x) * x) / n;\n  }\n  double cutoff = 0.01265 + 0.1757 / n;\n  double t;\n  if (x < cutoff) {\n    t = x / cutoff;\n    t = sqrt(t) * (1 - t) * (49 * t - 102);\n    return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n;\n  } else {\n    t = (x - cutoff) / (0.8 - cutoff);\n    t = -0.00022633 + (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864\n          * t) * t) * t) * t) * t;\n    return t * (0.04213 + 0.01365 / n) / n;\n  }\n}\n\n// Returns the AndersonDarling p-value given n and the value of the statistic\ndouble AndersonDarlingPValue(int n, double z) {\n  double ad = AndersonDarlingInf(z);\n  double errfix = AndersonDarlingErrFix(n, ad);\n  return ad + errfix;\n}\n\ndouble AndersonDarlingStatistic(int n, double* random_sample) {\n  double ad_sum = 0;\n  for (int i = 0; i < n; i++) {\n    ad_sum += (2*i + 1) * log(random_sample[i] * (1 - random_sample[n-1-i]));\n  }\n  double ad_statistic = - n - 1/static_cast<double>(n) * ad_sum;\n  return ad_statistic;\n}\n\n// Tests if the array of doubles is uniformly distributed.\n// Returns the p-value of the Anderson Darling Statistic\n// for the given set of sorted random doubles\n// See \"Evaluating the Anderson-Darling Distribution\" by\n// Marsaglia and Marsaglia for details.\ndouble AndersonDarlingTest(int n, double* random_sample) {\n  double ad_statistic = AndersonDarlingStatistic(n, random_sample);\n  LOG(INFO) << StringPrintf(\"AD stat = %f, n=%d\\n\", ad_statistic, n);\n  double p = AndersonDarlingPValue(n, ad_statistic);\n  return p;\n}\n\n// Test the AD Test. The value of the statistic should go to zero as n->infty\n// Not run as part of regular tests\nvoid ADTestTest(int n) {\n  scoped_array<double> random_sample(new double[n]);\n  for (int i = 0; i < n; i++) {\n    random_sample[i] = (i+0.01)/n;\n  }\n  sort(random_sample.get(), random_sample.get() + n);\n  double ad_stat = AndersonDarlingStatistic(n, random_sample.get());\n  LOG(INFO) << StringPrintf(\"Testing the AD test. n=%d, ad_stat = %f\",\n                            n, ad_stat);\n}\n\n// Print the CDF of the distribution of the Anderson-Darling Statistic\n// Used for checking the Anderson-Darling Test\n// Not run as part of regular tests\nvoid ADCDF() {\n  for (int i = 1; i < 40; i++) {\n    double x = i/10.0;\n    LOG(INFO) << \"x= \" << x << \"  adpv= \"\n              << AndersonDarlingPValue(100, x) << \", \"\n              << AndersonDarlingPValue(1000, x);\n  }\n}\n\n// Testing that NextRandom generates uniform\n// random numbers.\n// Applies the Anderson-Darling test for uniformity\nvoid TestNextRandom(int n) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  uint64_t x = 1;\n  // This assumes that the prng returns 48 bit numbers\n  uint64_t max_prng_value = static_cast<uint64_t>(1)<<48;\n  // Initialize\n  for (int i = 1; i <= 20; i++) {  // 20 mimics sampler.Init()\n    x = sampler.NextRandom(x);\n  }\n  scoped_array<uint64_t> int_random_sample(new uint64_t[n]);\n  // Collect samples\n  for (int i = 0; i < n; i++) {\n    int_random_sample[i] = x;\n    x = sampler.NextRandom(x);\n  }\n  // First sort them...\n  sort(int_random_sample.get(), int_random_sample.get() + n);\n  scoped_array<double> random_sample(new double[n]);\n  // Convert them to uniform randoms (in the range [0,1])\n  for (int i = 0; i < n; i++) {\n    random_sample[i] = static_cast<double>(int_random_sample[i])/max_prng_value;\n  }\n  // Now compute the Anderson-Darling statistic\n  double ad_pvalue = AndersonDarlingTest(n, random_sample.get());\n  LOG(INFO) << StringPrintf(\"pvalue for AndersonDarlingTest \"\n                            \"with n= %d is p= %f\\n\", n, ad_pvalue);\n  CHECK_GT(min(ad_pvalue, 1 - ad_pvalue), 0.0001);\n  //           << StringPrintf(\"prng is not uniform, %d\\n\", n);\n}\n\n\nTEST(Sampler, TestNextRandom_MultipleValues) {\n  TestNextRandom(10);  // Check short-range correlation\n  TestNextRandom(100);\n  TestNextRandom(1000);\n  TestNextRandom(10000);  // Make sure there's no systematic error\n}\n\n// Tests that PickNextSamplePeriod generates\n// geometrically distributed random numbers.\n// First converts to uniforms then applied the\n// Anderson-Darling test for uniformity.\nvoid TestPickNextSample(int n) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  scoped_array<uint64_t> int_random_sample(new uint64_t[n]);\n  int sample_period = sampler.GetSamplePeriod();\n  int ones_count = 0;\n  for (int i = 0; i < n; i++) {\n    int_random_sample[i] = sampler.PickNextSamplingPoint();\n    CHECK_GE(int_random_sample[i], 1);\n    if (int_random_sample[i] == 1) {\n      ones_count += 1;\n    }\n    CHECK_LT(ones_count, 4); // << \" out of \" << i << \" samples.\";\n  }\n  // First sort them...\n  sort(int_random_sample.get(), int_random_sample.get() + n);\n  scoped_array<double> random_sample(new double[n]);\n  // Convert them to uniform random numbers\n  // by applying the geometric CDF\n  for (int i = 0; i < n; i++) {\n    random_sample[i] = 1 - exp(-static_cast<double>(int_random_sample[i])\n                           / sample_period);\n  }\n  // Now compute the Anderson-Darling statistic\n  double geom_ad_pvalue = AndersonDarlingTest(n, random_sample.get());\n  LOG(INFO) << StringPrintf(\"pvalue for geometric AndersonDarlingTest \"\n                             \"with n= %d is p= %f\\n\", n, geom_ad_pvalue);\n  CHECK_GT(min(geom_ad_pvalue, 1 - geom_ad_pvalue), 0.0001);\n      //          << \"PickNextSamplingPoint does not produce good \"\n      //             \"geometric/exponential random numbers\\n\";\n}\n\nTEST(Sampler, TestPickNextSample_MultipleValues) {\n  TestPickNextSample(10);  // Make sure the first few are good (enough)\n  TestPickNextSample(100);\n  TestPickNextSample(1000);\n  TestPickNextSample(10000);  // Make sure there's no systematic error\n}\n\n\n// This is superceeded by the Anderson-Darling Test\n// and it not run now.\n// Tests how fast nearby values are spread out with  LRand64\n// The purpose of this code is to determine how many\n// steps to apply to the seed during initialization\nvoid TestLRand64Spread() {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  uint64_t current_value;\n  printf(\"Testing LRand64 Spread\\n\");\n  for (int i = 1; i < 10; i++) {\n    printf(\"%d \", i);\n    current_value = i;\n    for (int j = 1; j < 100; j++) {\n      current_value = sampler.NextRandom(current_value);\n    }\n    LOG(INFO) << current_value;\n  }\n}\n\n\n// Test for Fastlog2 code\n// We care about the percentage error because we're using this\n// for choosing step sizes, so \"close\" is relative to the size of\n// the step we would get if we used the built-in log function\nTEST(Sampler, FastLog2) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  double max_ratio_error = 0;\n  for (double d = -1021.9; d < 1; d+= 0.13124235) {\n    double e = pow(2.0, d);\n    double truelog = log(e) / log(2.0);  // log_2(e)\n    double fastlog = sampler.FastLog2(e);\n    max_ratio_error = max(max_ratio_error,\n                          max(truelog/fastlog-1, fastlog/truelog-1));\n    CHECK_LE(max_ratio_error, 0.01);\n        //        << StringPrintf(\"d = %f, e=%f, truelog = %f, fastlog= %f\\n\",\n        //                        d, e, truelog, fastlog);\n  }\n  LOG(INFO) << StringPrintf(\"Fastlog2: max_ratio_error = %f\\n\",\n                            max_ratio_error);\n}\n\n// Futher tests\n\nbool CheckMean(size_t mean, int num_samples) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  size_t total = 0;\n  for (int i = 0; i < num_samples; i++) {\n    total += sampler.PickNextSamplingPoint();\n  }\n  double empirical_mean = total / static_cast<double>(num_samples);\n  double expected_sd = mean / pow(num_samples * 1.0, 0.5);\n  return(abs(mean-empirical_mean) < expected_sd * kSigmas);\n}\n\n// Prints a sequence so you can look at the distribution\nvoid OutputSequence(int sequence_length) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  size_t next_step;\n  for (int i = 0; i< sequence_length; i++) {\n    next_step = sampler.PickNextSamplingPoint();\n    LOG(INFO) << next_step;\n  }\n}\n\n\ndouble StandardDeviationsErrorInSample(\n              int total_samples, int picked_samples,\n              int alloc_size, int sampling_interval) {\n  double p = 1 - exp(-(static_cast<double>(alloc_size) / sampling_interval));\n  double expected_samples = total_samples * p;\n  double sd = pow(p*(1-p)*total_samples, 0.5);\n  return((picked_samples - expected_samples) / sd);\n}\n\nTEST(Sampler, LargeAndSmallAllocs_CombinedTest) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  int counter_big = 0;\n  int counter_small = 0;\n  int size_big = 129*8*1024+1;\n  int size_small = 1024*8;\n  int num_iters = 128*4*8;\n  // Allocate in mixed chunks\n  for (int i = 0; i < num_iters; i++) {\n    if (sampler.SampleAllocation(size_big)) {\n      counter_big += 1;\n    }\n    for (int i = 0; i < 129; i++) {\n      if (sampler.SampleAllocation(size_small)) {\n        counter_small += 1;\n      }\n    }\n  }\n  // Now test that there are the right number of each\n  double large_allocs_sds =\n     StandardDeviationsErrorInSample(num_iters, counter_big,\n                                     size_big, kSamplingInterval);\n  double small_allocs_sds =\n     StandardDeviationsErrorInSample(num_iters*129, counter_small,\n                                     size_small, kSamplingInterval);\n  LOG(INFO) << StringPrintf(\"large_allocs_sds = %f\\n\", large_allocs_sds);\n  LOG(INFO) << StringPrintf(\"small_allocs_sds = %f\\n\", small_allocs_sds);\n  CHECK_LE(abs(large_allocs_sds), kSigmas);\n  CHECK_LE(abs(small_allocs_sds), kSigmas);\n}\n\n// Tests whether the mean is about right over 1000 samples\nTEST(Sampler, IsMeanRight) {\n  CHECK(CheckMean(kSamplingInterval, 1000));\n}\n\n// This flag is for the OldSampler class to use\nconst int64 FLAGS_mock_tcmalloc_sample_parameter = 1<<19;\n\n// A cut down and slightly refactored version of the old Sampler\nclass OldSampler {\n public:\n  void Init(uint32_t seed);\n  void Cleanup() {}\n\n  // Record allocation of \"k\" bytes.  Return true iff allocation\n  // should be sampled\n  bool SampleAllocation(size_t k);\n\n  // Generate a geometric with mean 1M (or FLAG value)\n  void PickNextSample(size_t k);\n\n  // Initialize the statics for the Sample class\n  static void InitStatics() {\n    sample_period = 1048583;\n  }\n  size_t bytes_until_sample_;\n\n private:\n  uint32_t rnd_;                   // Cheap random number generator\n  static uint64_t sample_period;\n  // Should be a prime just above a power of 2:\n  // 2, 5, 11, 17, 37, 67, 131, 257,\n  // 521, 1031, 2053, 4099, 8209, 16411,\n  // 32771, 65537, 131101, 262147, 524309, 1048583,\n  // 2097169, 4194319, 8388617, 16777259, 33554467\n};\n\n// Statics for OldSampler\nuint64_t OldSampler::sample_period;\n\nvoid OldSampler::Init(uint32_t seed) {\n  // Initialize PRNG -- run it for a bit to get to good values\n  if (seed != 0) {\n    rnd_ = seed;\n  } else {\n    rnd_ = 12345;\n  }\n  bytes_until_sample_ = 0;\n  for (int i = 0; i < 100; i++) {\n    PickNextSample(sample_period * 2);\n  }\n};\n\n// A cut-down version of the old PickNextSampleRoutine\nvoid OldSampler::PickNextSample(size_t k) {\n  // Make next \"random\" number\n  // x^32+x^22+x^2+x^1+1 is a primitive polynomial for random numbers\n  static const uint32_t kPoly = (1 << 22) | (1 << 2) | (1 << 1) | (1 << 0);\n  uint32_t r = rnd_;\n  rnd_ = (r << 1) ^ ((static_cast<int32_t>(r) >> 31) & kPoly);\n\n  // Next point is \"rnd_ % (sample_period)\".  I.e., average\n  // increment is \"sample_period/2\".\n  const int flag_value = FLAGS_mock_tcmalloc_sample_parameter;\n  static int last_flag_value = -1;\n\n  if (flag_value != last_flag_value) {\n    // There should be a spinlock here, but this code is\n    // for benchmarking only.\n    sample_period = 1048583;\n    last_flag_value = flag_value;\n  }\n\n  bytes_until_sample_ += rnd_ % sample_period;\n\n  if (k > (static_cast<size_t>(-1) >> 2)) {\n    // If the user has asked for a huge allocation then it is possible\n    // for the code below to loop infinitely.  Just return (note that\n    // this throws off the sampling accuracy somewhat, but a user who\n    // is allocating more than 1G of memory at a time can live with a\n    // minor inaccuracy in profiling of small allocations, and also\n    // would rather not wait for the loop below to terminate).\n    return;\n  }\n\n  while (bytes_until_sample_ < k) {\n    // Increase bytes_until_sample_ by enough average sampling periods\n    // (sample_period >> 1) to allow us to sample past the current\n    // allocation.\n    bytes_until_sample_ += (sample_period >> 1);\n  }\n\n  bytes_until_sample_ -= k;\n}\n\ninline bool OldSampler::SampleAllocation(size_t k) {\n  if (bytes_until_sample_ < k) {\n    PickNextSample(k);\n    return true;\n  } else {\n    bytes_until_sample_ -= k;\n    return false;\n  }\n}\n\n// This checks that the stated maximum value for the\n// tcmalloc_sample_parameter flag never overflows bytes_until_sample_\nTEST(Sampler, bytes_until_sample_Overflow_Underflow) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  uint64_t one = 1;\n  // sample_parameter = 0;  // To test the edge case\n  uint64_t sample_parameter_array[4] = {0, 1, one<<19, one<<58};\n  for (int i = 0; i < 4; i++) {\n    uint64_t sample_parameter = sample_parameter_array[i];\n    LOG(INFO) << \"sample_parameter = \" << sample_parameter;\n    double sample_scaling = - log(2.0) * sample_parameter;\n    // Take the top 26 bits as the random number\n    // (This plus the 1<<26 sampling bound give a max step possible of\n    // 1209424308 bytes.)\n    const uint64_t prng_mod_power = 48;  // Number of bits in prng\n\n    // First, check the largest_prng value\n    uint64_t largest_prng_value = (static_cast<uint64_t>(1)<<48) - 1;\n    double q = (largest_prng_value >> (prng_mod_power - 26)) + 1.0;\n    LOG(INFO) << StringPrintf(\"q = %f\\n\", q);\n    LOG(INFO) << StringPrintf(\"FastLog2(q) = %f\\n\", sampler.FastLog2(q));\n    LOG(INFO) << StringPrintf(\"log2(q) = %f\\n\", log(q)/log(2.0));\n    // Replace min(sampler.FastLog2(q) - 26, 0.0) with\n    // (sampler.FastLog2(q) - 26.000705) when using that optimization\n    uint64_t smallest_sample_step\n        = static_cast<uint64_t>(min(sampler.FastLog2(q) - 26, 0.0)\n                                * sample_scaling + 1);\n    LOG(INFO) << \"Smallest sample step is \" << smallest_sample_step;\n    uint64_t cutoff = static_cast<uint64_t>(10)\n                      * (sample_parameter/(one<<24) + 1);\n    LOG(INFO) << \"Acceptable value is < \" << cutoff;\n    // This checks that the answer is \"small\" and positive\n    CHECK_LE(smallest_sample_step, cutoff);\n\n    // Next, check with the smallest prng value\n    uint64_t smallest_prng_value = 0;\n    q = (smallest_prng_value >> (prng_mod_power - 26)) + 1.0;\n    LOG(INFO) << StringPrintf(\"q = %f\\n\", q);\n    // Replace min(sampler.FastLog2(q) - 26, 0.0) with\n    // (sampler.FastLog2(q) - 26.000705) when using that optimization\n    uint64_t largest_sample_step\n        = static_cast<uint64_t>(min(sampler.FastLog2(q) - 26, 0.0)\n                                * sample_scaling + 1);\n    LOG(INFO) << \"Largest sample step is \" << largest_sample_step;\n    CHECK_LE(largest_sample_step, one<<63);\n    CHECK_GE(largest_sample_step, smallest_sample_step);\n  }\n}\n\n\n// Test that NextRand is in the right range.  Unfortunately, this is a\n// stochastic test which could miss problems.\nTEST(Sampler, NextRand_range) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  uint64_t one = 1;\n  // The next number should be (one << 48) - 1\n  uint64_t max_value = (one << 48) - 1;\n  uint64_t x = (one << 55);\n  int n = 22;  // 27;\n  LOG(INFO) << \"Running sampler.NextRandom 1<<\" << n << \" times\";\n  for (int i = 1; i <= (1<<n); i++) {  // 20 mimics sampler.Init()\n    x = sampler.NextRandom(x);\n    CHECK_LE(x, max_value);\n  }\n}\n\n// Tests certain arithmetic operations to make sure they compute what we\n// expect them too (for testing across different platforms)\nTEST(Sampler, arithmetic_1) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  uint64_t rnd;  // our 48 bit random number, which we don't trust\n  const uint64_t prng_mod_power = 48;\n  uint64_t one = 1;\n  rnd = one;\n  uint64_t max_value = (one << 48) - 1;\n  for (int i = 1; i <= (1>>27); i++) {  // 20 mimics sampler.Init()\n    rnd = sampler.NextRandom(rnd);\n    CHECK_LE(rnd, max_value);\n    double q = (rnd >> (prng_mod_power - 26)) + 1.0;\n    CHECK_GE(q, 0); // << rnd << \"  \" << prng_mod_power;\n  }\n  // Test some potentially out of bounds value for rnd\n  for (int i = 1; i <= 66; i++) {\n    rnd = one << i;\n    double q = (rnd >> (prng_mod_power - 26)) + 1.0;\n    LOG(INFO) << \"rnd = \" << rnd << \" i=\" << i << \" q=\" << q;\n    CHECK_GE(q, 0);\n    //        << \" rnd=\" << rnd << \"  i=\" << i << \" prng_mod_power\" << prng_mod_power;\n  }\n}\n\nvoid test_arithmetic(uint64_t rnd) {\n  const uint64_t prng_mod_power = 48;  // Number of bits in prng\n  uint64_t shifted_rnd = rnd >> (prng_mod_power - 26);\n  CHECK_GE(shifted_rnd, 0);\n  CHECK_LT(shifted_rnd, (1<<26));\n  LOG(INFO) << shifted_rnd;\n  LOG(INFO) << static_cast<double>(shifted_rnd);\n  CHECK_GE(static_cast<double>(static_cast<uint32_t>(shifted_rnd)), 0);\n      //      << \" rnd=\" << rnd << \"  srnd=\" << shifted_rnd;\n  CHECK_GE(static_cast<double>(shifted_rnd), 0);\n      //      << \" rnd=\" << rnd << \"  srnd=\" << shifted_rnd;\n  double q = static_cast<double>(shifted_rnd) + 1.0;\n  CHECK_GT(q, 0);\n}\n\n// Tests certain arithmetic operations to make sure they compute what we\n// expect them too (for testing across different platforms)\n// know bad values under with -c dbg --cpu piii for _some_ binaries:\n// rnd=227453640600554\n// shifted_rnd=54229173\n// (hard to reproduce)\nTEST(Sampler, arithmetic_2) {\n  uint64_t rnd = 227453640600554LL;\n  test_arithmetic(rnd);\n}\n\n\n// It's not really a test, but it's good to know\nTEST(Sample, size_of_class) {\n  tcmalloc::Sampler sampler;\n  sampler.Init(1);\n  LOG(INFO) << \"Size of Sampler class is: \" << sizeof(tcmalloc::Sampler);\n  LOG(INFO) << \"Size of Sampler object is: \" << sizeof(sampler);\n}\n\n// Make sure sampling is enabled, or the tests won't work right.\nDECLARE_int64(tcmalloc_sample_parameter);\n\nint main(int argc, char **argv) {\n  if (FLAGS_tcmalloc_sample_parameter == 0)\n    FLAGS_tcmalloc_sample_parameter = 524288;\n  return RUN_ALL_TESTS();\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/sampling_test.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// This tests ReadStackTraces and ReadGrowthStackTraces.  It does this\n// by doing a bunch of allocations and then calling those functions.\n// A driver shell-script can call this, and then call pprof, and\n// verify the expected output.  The output is written to\n// argv[1].heap and argv[1].growth\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string>\n#include \"base/logging.h\"\n#include <google/malloc_extension.h>\n\nusing std::string;\n\nextern \"C\" void* AllocateAllocate() ATTRIBUTE_NOINLINE;\n\nextern \"C\" void* AllocateAllocate() {\n  // The VLOG's are mostly to discourage inlining\n  VLOG(1, \"Allocating some more\");\n  void* p = malloc(10000);\n  VLOG(1, \"Done allocating\");\n  return p;\n}\n\nstatic void WriteStringToFile(const string& s, const string& filename) {\n  FILE* fp = fopen(filename.c_str(), \"w\");\n  fwrite(s.data(), 1, s.length(), fp);\n  fclose(fp);\n}\n\nint main(int argc, char** argv) {\n  if (argc < 2) {\n    fprintf(stderr, \"USAGE: %s <base of output files>\\n\", argv[0]);\n    exit(1);\n  }\n  for (int i = 0; i < 8000; i++) {\n    AllocateAllocate();\n  }\n\n  string s;\n  MallocExtension::instance()->GetHeapSample(&s);\n  WriteStringToFile(s, string(argv[1]) + \".heap\");\n\n  s.clear();\n  MallocExtension::instance()->GetHeapGrowthStacks(&s);\n  WriteStringToFile(s, string(argv[1]) + \".growth\");\n\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/sampling_test.sh",
    "content": "#!/bin/sh\n\n# Copyright (c) 2008, Google Inc.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n#\n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n# ---\n# Author: Craig Silverstein\n#\n# This is a test that tcmalloc creates, and pprof reads, sampling data\n# correctly: both for the heap profile (ReadStackTraces) and for\n# growth in the heap sized (ReadGrowthStackTraces).\n\nBINDIR=\"${BINDIR:-.}\"\nPPROF_PATH=\"${PPROF_PATH:-$BINDIR/src/pprof}\"\n\nif [ \"x$1\" = \"x-h\" -o \"x$1\" = \"x--help\" ]; then\n  echo \"USAGE: $0 [unittest dir] [path to pprof]\"\n  echo \"       By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH\"\n  exit 1\nfi\n\nSAMPLING_TEST=\"${1:-$BINDIR/sampling_test}\"\nPPROF=\"${2:-$PPROF_PATH}\"\nOUTDIR=\"/tmp/sampling_test_dir\"\n\n# libtool is annoying, and puts the actual executable in a different\n# directory, replacing the seeming-executable with a shell script.\n# We use the error output of sampling_test to indicate its real location\nSAMPLING_TEST_BINARY=`\"$SAMPLING_TEST\" 2>&1 | awk '/USAGE/ {print $2; exit;}'`\n\n# A kludge for cygwin.  Unfortunately, 'test -f' says that 'foo' exists\n# even when it doesn't, and only foo.exe exists.  Other unix utilities\n# (like nm) need you to say 'foo.exe'.  We use one such utility, cat, to\n# see what the *real* binary name is.\nif ! cat \"$SAMPLING_TEST_BINARY\" >/dev/null 2>&1; then\n  SAMPLING_TEST_BINARY=\"$SAMPLING_TEST_BINARY\".exe\nfi\n\ndie() {    # runs the command given as arguments, and then dies.\n    echo \"FAILED.  Output from $@\"\n    echo \"----\"\n    \"$@\"\n    echo \"----\"\n    exit 1\n}\n\nrm -rf \"$OUTDIR\" || die \"Unable to delete $OUTDIR\"\nmkdir \"$OUTDIR\" || die \"Unable to create $OUTDIR\"\n\n# This puts the output into out.heap and out.growth.  It allocates\n# 8*10^7 bytes of memory, which is 76M.  Because we sample, the\n# estimate may be a bit high or a bit low: we accept anything from\n# 50M to 99M.\n\"$SAMPLING_TEST\" \"$OUTDIR/out\"\n\necho \"Testing heap output...\"\n\"$PPROF\" --text \"$SAMPLING_TEST_BINARY\" \"$OUTDIR/out.heap\" \\\n   | grep '[5-9][0-9]\\.[0-9][ 0-9.%]*_*AllocateAllocate' >/dev/null \\\n   || die \"$PPROF\" --text \"$SAMPLING_TEST_BINARY\" \"$OUTDIR/out.heap\"\necho \"OK\"\n\necho \"Testing growth output...\"\n\"$PPROF\" --text \"$SAMPLING_TEST_BINARY\" \"$OUTDIR/out.growth\" \\\n   | grep '[5-9][0-9]\\.[0-9][ 0-9.%]*_*AllocateAllocate' >/dev/null \\\n   || die \"$PPROF\" --text \"$SAMPLING_TEST_BINARY\" \"$OUTDIR/out.growth\"\necho \"OK\"\n\necho \"PASS\"\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/stack_trace_table_test.cc",
    "content": "// Copyright 2009 Google Inc. All Rights Reserved.\n// Author: fikes@google.com (Andrew Fikes)\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>   // for puts()\n#include \"stack_trace_table.h\"\n#include \"base/logging.h\"\n#include \"base/spinlock.h\"\n#include \"static_vars.h\"\n\n#undef ARRAYSIZE   // may be defined on, eg, windows\n#define ARRAYSIZE(a)  ( sizeof(a) / sizeof(*(a)) )\n\nstatic void CheckTracesAndReset(tcmalloc::StackTraceTable* table,\n                        const uintptr_t* expected, int len) {\n  void** entries = table->ReadStackTracesAndClear();\n  for (int i = 0; i < len; ++i) {\n    CHECK_EQ(reinterpret_cast<uintptr_t>(entries[i]), expected[i]);\n  }\n  delete[] entries;\n}\n\nstatic void AddTrace(tcmalloc::StackTraceTable* table,\n                     const tcmalloc::StackTrace& t) {\n  // Normally we'd need this lock, but since the test is single-threaded\n  // we don't.  I comment it out on windows because the DLL-decl thing\n  // is really annoying in this case.\n#ifndef _MSC_VER\n  SpinLockHolder h(tcmalloc::Static::pageheap_lock());\n#endif\n  table->AddTrace(t);\n}\n\nint main(int argc, char **argv) {\n  tcmalloc::StackTraceTable table;\n\n  // Empty table\n  CHECK_EQ(table.depth_total(), 0);\n  CHECK_EQ(table.bucket_total(), 0);\n  static const uintptr_t k1[] = {0};\n  CheckTracesAndReset(&table, k1, ARRAYSIZE(k1));\n\n  tcmalloc::StackTrace t1;\n  t1.size = static_cast<uintptr_t>(1024);\n  t1.depth = static_cast<uintptr_t>(2);\n  t1.stack[0] = reinterpret_cast<void*>(1);\n  t1.stack[1] = reinterpret_cast<void*>(2);\n\n\n  tcmalloc::StackTrace t2;\n  t2.size = static_cast<uintptr_t>(512);\n  t2.depth = static_cast<uintptr_t>(2);\n  t2.stack[0] = reinterpret_cast<void*>(2);\n  t2.stack[1] = reinterpret_cast<void*>(1);\n\n  // Table w/ just t1\n  AddTrace(&table, t1);\n  CHECK_EQ(table.depth_total(), 2);\n  CHECK_EQ(table.bucket_total(), 1);\n  static const uintptr_t k2[] = {1, 1024, 2, 1, 2, 0};\n  CheckTracesAndReset(&table, k2, ARRAYSIZE(k2));\n\n  // Table w/ t1, t2\n  AddTrace(&table, t1);\n  AddTrace(&table, t2);\n  CHECK_EQ(table.depth_total(), 4);\n  CHECK_EQ(table.bucket_total(), 2);\n  static const uintptr_t k3[] = {1, 1024, 2, 1, 2, 1,  512, 2, 2, 1, 0};\n  CheckTracesAndReset(&table, k3, ARRAYSIZE(k3));\n\n  // Table w/ 2 x t1, 1 x t2\n  AddTrace(&table, t1);\n  AddTrace(&table, t2);\n  AddTrace(&table, t1);\n  CHECK_EQ(table.depth_total(), 4);\n  CHECK_EQ(table.bucket_total(), 2);\n  static const uintptr_t k4[] = {2, 2048, 2, 1, 2, 1,  512, 2, 2, 1, 0};\n  CheckTracesAndReset(&table, k4, ARRAYSIZE(k4));\n\n  // Same stack as t1, but w/ different size\n  tcmalloc::StackTrace t3;\n  t3.size = static_cast<uintptr_t>(2);\n  t3.depth = static_cast<uintptr_t>(2);\n  t3.stack[0] = reinterpret_cast<void*>(1);\n  t3.stack[1] = reinterpret_cast<void*>(2);\n\n  // Table w/ t1, t3\n  AddTrace(&table, t1);\n  AddTrace(&table, t3);\n  CHECK_EQ(table.depth_total(), 2);\n  CHECK_EQ(table.bucket_total(), 1);\n  static const uintptr_t k5[] = {2, 1026, 2, 1, 2, 0};\n  CheckTracesAndReset(&table, k5, ARRAYSIZE(k5));\n\n  puts(\"PASS\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/stacktrace_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#include \"config_for_unittests.h\"\n#ifdef HAVE_EXECINFO_H\n#include <execinfo.h>\n#endif\n#include <stdio.h>\n#include <stdlib.h>\n#include \"base/commandlineflags.h\"\n#include \"base/logging.h\"\n#include <google/stacktrace.h>\n\nnamespace {\n\n// Obtain a backtrace, verify that the expected callers are present in the\n// backtrace, and maybe print the backtrace to stdout.\n\n// The sequence of functions whose return addresses we expect to see in the\n// backtrace.\nconst int BACKTRACE_STEPS = 6;\n\nstruct AddressRange {\n  const void *start, *end;\n};\n\n// Expected function [start,end] range.\nAddressRange expected_range[BACKTRACE_STEPS];\n\n#if __GNUC__\n// Using GCC extension: address of a label can be taken with '&&label'.\n// Start should be a label somewhere before recursive call, end somewhere\n// after it.\n#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \\\n  do {                                                                   \\\n    (prange)->start = &&start_label;                                     \\\n    (prange)->end = &&end_label;                                         \\\n    CHECK_LT((prange)->start, (prange)->end);                            \\\n  } while (0)\n// This macro expands into \"unmovable\" code (opaque to GCC), and that\n// prevents GCC from moving a_label up or down in the code.\n// Without it, there is no code following the 'end' label, and GCC\n// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before\n// the recursive call.\n#define DECLARE_ADDRESS_LABEL(a_label)                                   \\\n  a_label: do { __asm__ __volatile__(\"\"); } while (0)\n// Gcc 4.4.0 may split function into multiple chunks, and the chunk\n// performing recursive call may end up later in the code then the return\n// instruction (this actually happens with FDO).\n// Adjust function range from __builtin_return_address.\n#define ADJUST_ADDRESS_RANGE_FROM_RA(prange)                             \\\n  do {                                                                   \\\n    void *ra = __builtin_return_address(0);                              \\\n    CHECK_LT((prange)->start, ra);                                       \\\n    if (ra > (prange)->end) {                                            \\\n      printf(\"Adjusting range from %p..%p to %p..%p\\n\",                  \\\n             (prange)->start, (prange)->end,                             \\\n             (prange)->start, ra);                                       \\\n      (prange)->end = ra;                                                \\\n    }                                                                    \\\n  } while (0)\n#else\n// Assume the Check* functions below are not longer than 256 bytes.\n#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \\\n  do {                                                                   \\\n    (prange)->start = reinterpret_cast<const void *>(&fn);               \\\n    (prange)->end = reinterpret_cast<const char *>(&fn) + 256;           \\\n  } while (0)\n#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0)\n#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)\n#endif  // __GNUC__\n\n//-----------------------------------------------------------------------//\n\nvoid CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)\n{\n  CHECK_GE(ret_addr, range.start);\n  CHECK_LE(ret_addr, range.end);\n}\n\n//-----------------------------------------------------------------------//\n\nvoid ATTRIBUTE_NOINLINE CheckStackTrace(int);\nvoid ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {\n  const int STACK_LEN = 10;\n  void *stack[STACK_LEN];\n  int size;\n\n  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);\n  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);\n  DECLARE_ADDRESS_LABEL(start);\n  size = GetStackTrace(stack, STACK_LEN, 0);\n  printf(\"Obtained %d stack frames.\\n\", size);\n  CHECK_GE(size, 1);\n  CHECK_LE(size, STACK_LEN);\n\n#ifdef HAVE_EXECINFO_H\n  {\n    char **strings = backtrace_symbols(stack, size);\n    printf(\"Obtained %d stack frames.\\n\", size);\n    for (int i = 0; i < size; i++)\n      printf(\"%s %p\\n\", strings[i], stack[i]);\n    printf(\"CheckStackTrace() addr: %p\\n\", &CheckStackTrace);\n    free(strings);\n  }\n#endif\n\n  for (int i = 0; i < BACKTRACE_STEPS; i++) {\n    printf(\"Backtrace %d: expected: %p..%p  actual: %p ... \",\n           i, expected_range[i].start, expected_range[i].end, stack[i]);\n    fflush(stdout);\n    CheckRetAddrIsInFunction(stack[i], expected_range[i]);\n    printf(\"OK\\n\");\n  }\n  DECLARE_ADDRESS_LABEL(end);\n}\n\n//-----------------------------------------------------------------------//\n\n/* Dummy functions to make the backtrace more interesting. */\nvoid ATTRIBUTE_NOINLINE CheckStackTrace4(int i) {\n  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]);\n  INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]);\n  DECLARE_ADDRESS_LABEL(start);\n  for (int j = i; j >= 0; j--)\n    CheckStackTraceLeaf();\n  DECLARE_ADDRESS_LABEL(end);\n}\nvoid ATTRIBUTE_NOINLINE CheckStackTrace3(int i) {\n  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]);\n  INIT_ADDRESS_RANGE(CheckStackTrace3, start, end, &expected_range[2]);\n  DECLARE_ADDRESS_LABEL(start);\n  for (int j = i; j >= 0; j--)\n    CheckStackTrace4(j);\n  DECLARE_ADDRESS_LABEL(end);\n}\nvoid ATTRIBUTE_NOINLINE CheckStackTrace2(int i) {\n  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]);\n  INIT_ADDRESS_RANGE(CheckStackTrace2, start, end, &expected_range[3]);\n  DECLARE_ADDRESS_LABEL(start);\n  for (int j = i; j >= 0; j--)\n    CheckStackTrace3(j);\n  DECLARE_ADDRESS_LABEL(end);\n}\nvoid ATTRIBUTE_NOINLINE CheckStackTrace1(int i) {\n  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]);\n  INIT_ADDRESS_RANGE(CheckStackTrace1, start, end, &expected_range[4]);\n  DECLARE_ADDRESS_LABEL(start);\n  for (int j = i; j >= 0; j--)\n    CheckStackTrace2(j);\n  DECLARE_ADDRESS_LABEL(end);\n}\nvoid ATTRIBUTE_NOINLINE CheckStackTrace(int i) {\n  INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]);\n  DECLARE_ADDRESS_LABEL(start);\n  for (int j = i; j >= 0; j--)\n    CheckStackTrace1(j);\n  DECLARE_ADDRESS_LABEL(end);\n}\n\n}  // namespace\n//-----------------------------------------------------------------------//\n\nint main(int argc, char ** argv) {\n  CheckStackTrace(0);\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/system-alloc_unittest.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Arun Sharma\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#if defined HAVE_STDINT_H\n#include <stdint.h>             // to get uintptr_t\n#elif defined HAVE_INTTYPES_H\n#include <inttypes.h>           // another place uintptr_t might be defined\n#endif\n#include <sys/types.h>\n#include <algorithm>\n#include \"base/logging.h\"\n#include \"common.h\"\n#include \"system-alloc.h\"\n\nclass ArraySysAllocator : public SysAllocator {\npublic:\n  // Was this allocator invoked at least once?\n  bool invoked_;\n\n  ArraySysAllocator() : SysAllocator() {\n    ptr_ = 0;\n    invoked_ = false;\n  }\n\n  void* Alloc(size_t size, size_t *actual_size, size_t alignment) {\n    invoked_ = true;\n    void *result = &array_[ptr_];\n    uintptr_t ptr = reinterpret_cast<uintptr_t>(result);\n\n    if (actual_size) {\n      *actual_size = size;\n    }\n\n    // Try to get more memory for alignment\n    size_t extra = alignment - (ptr & (alignment-1));\n    size += extra;\n    CHECK_LT(ptr_ + size, kArraySize);\n\n    if ((ptr & (alignment-1)) != 0) {\n      ptr += alignment - (ptr & (alignment-1));\n    }\n\n    ptr_ += size;\n    return reinterpret_cast<void *>(ptr);\n  }\n\n  void DumpStats(TCMalloc_Printer* printer) {\n  }\n\nprivate:\n  static const int kArraySize = 8 * 1024 * 1024;\n  char array_[kArraySize];\n  // We allocate the next chunk from here\n  int ptr_;\n\n};\nconst int ArraySysAllocator::kArraySize;\nArraySysAllocator a;\n\nstatic void TestBasicInvoked() {\n  RegisterSystemAllocator(&a, 0);\n\n  // An allocation size that is likely to trigger the system allocator.\n  // XXX: this is implementation specific.\n  char *p = new char[1024 * 1024];\n  delete [] p;\n\n  // Make sure that our allocator was invoked.\n  CHECK(a.invoked_);\n}\n\n#if 0  // could port this to various OSs, but won't bother for now\nTEST(AddressBits, CpuVirtualBits) {\n  // Check that kAddressBits is as least as large as either the number of bits\n  // in a pointer or as the number of virtual bits handled by the processor.\n  // To be effective this test must be run on each processor model.\n  const int kPointerBits = 8 * sizeof(void*);\n  const int kImplementedVirtualBits = NumImplementedVirtualBits();\n\n  CHECK_GE(kAddressBits, min(kImplementedVirtualBits, kPointerBits));\n}\n#endif\n\nint main(int argc, char** argv) {\n  TestBasicInvoked();\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/tcmalloc_large_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Michael Chastain\n//\n// This is a unit test for large allocations in malloc and friends.\n// \"Large\" means \"so large that they overflow the address space\".\n// For 32 bits, this means allocations near 2^32 bytes and 2^31 bytes.\n// For 64 bits, this means allocations near 2^64 bytes and 2^63 bytes.\n\n#include <stddef.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <set>\n\n#include \"base/logging.h\"\n\nusing std::set;\n\n// Alloc a size that should always fail.\n\nvoid TryAllocExpectFail(size_t size) {\n  void* p1 = malloc(size);\n  CHECK(p1 == NULL);\n\n  void* p2 = malloc(1);\n  CHECK(p2 != NULL);\n\n  void* p3 = realloc(p2, size);\n  CHECK(p3 == NULL);\n\n  free(p2);\n}\n\n// Alloc a size that might work and might fail.\n// If it does work, touch some pages.\n\nvoid TryAllocMightFail(size_t size) {\n  unsigned char* p = static_cast<unsigned char*>(malloc(size));\n  if ( p != NULL ) {\n    unsigned char volatile* vp = p;  // prevent optimizations\n    static const size_t kPoints = 1024;\n\n    for ( size_t i = 0; i < kPoints; ++i ) {\n      vp[i * (size / kPoints)] = static_cast<unsigned char>(i);\n    }\n\n    for ( size_t i = 0; i < kPoints; ++i ) {\n      CHECK(vp[i * (size / kPoints)] == static_cast<unsigned char>(i));\n    }\n\n    vp[size-1] = 'M';\n    CHECK(vp[size-1] == 'M');\n  }\n\n  free(p);\n}\n\nint main (int argc, char** argv) {\n  // Allocate some 0-byte objects.  They better be unique.\n  // 0 bytes is not large but it exercises some paths related to\n  // large-allocation code.\n  {\n    static const int kZeroTimes = 1024;\n    printf(\"Test malloc(0) x %d\\n\", kZeroTimes);\n    set<char*> p_set;\n    for ( int i = 0; i < kZeroTimes; ++i ) {\n      char* p = new char;\n      CHECK(p != NULL);\n      CHECK(p_set.find(p) == p_set.end());\n      p_set.insert(p_set.end(), p);\n    }\n    // Just leak the memory.\n  }\n\n  // Grab some memory so that some later allocations are guaranteed to fail.\n  printf(\"Test small malloc\\n\");\n  void* p_small = malloc(4*1048576);\n  CHECK(p_small != NULL);\n\n  // Test sizes up near the maximum size_t.\n  // These allocations test the wrap-around code.\n  printf(\"Test malloc(0 - N)\\n\");\n  const size_t zero = 0;\n  static const size_t kMinusNTimes = 16384;\n  for ( size_t i = 1; i < kMinusNTimes; ++i ) {\n    TryAllocExpectFail(zero - i);\n  }\n\n  // Test sizes a bit smaller.\n  // The small malloc above guarantees that all these return NULL.\n  printf(\"Test malloc(0 - 1048576 - N)\\n\");\n  static const size_t kMinusMBMinusNTimes = 16384;\n  for ( size_t i = 0; i < kMinusMBMinusNTimes; ++i) {\n    TryAllocExpectFail(zero - 1048576 - i);\n  }\n\n  // Test sizes at half of size_t.\n  // These might or might not fail to allocate.\n  printf(\"Test malloc(max/2 +- N)\\n\");\n  static const size_t kHalfPlusMinusTimes = 64;\n  const size_t half = (zero - 2) / 2 + 1;\n  for ( size_t i = 0; i < kHalfPlusMinusTimes; ++i) {\n    TryAllocMightFail(half - i);\n    TryAllocMightFail(half + i);\n  }\n\n  printf(\"PASS\\n\");\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/tcmalloc_unittest.cc",
    "content": "// Copyright (c) 2005, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Unittest for the TCMalloc implementation.\n//\n// * The test consists of a set of threads.\n// * Each thread maintains a set of allocated objects, with\n//   a bound on the total amount of data in the set.\n// * Each allocated object's contents are generated by\n//   hashing the object pointer, and a generation count\n//   in the object.  This allows us to easily check for\n//   data corruption.\n// * At any given step, the thread can do any of the following:\n//     a. Allocate an object\n//     b. Increment an object's generation count and update\n//        its contents.\n//     c. Pass the object to another thread\n//     d. Free an object\n//   Also, at the end of every step, object(s) are freed to maintain\n//   the memory upper-bound.\n//\n// If this test is compiled with -DDEBUGALLOCATION, then we don't\n// run some tests that test the inner workings of tcmalloc and\n// break on debugallocation: that certain allocations are aligned\n// in a certain way (even though no standard requires it), and that\n// realloc() tries to minimize copying (which debug allocators don't\n// care about).\n\n#include \"config_for_unittests.h\"\n// Complicated ordering requirements.  tcmalloc.h defines (indirectly)\n// _POSIX_C_SOURCE, which it needs so stdlib.h defines posix_memalign.\n// unistd.h, on the other hand, requires _POSIX_C_SOURCE to be unset,\n// at least on FreeBSD, in order to define sbrk.  The solution\n// is to #include unistd.h first.  This is safe because unistd.h\n// doesn't sub-include stdlib.h, so we'll still get posix_memalign\n// when we #include stdlib.h.  Blah.\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>        // for testing sbrk hooks\n#endif\n#include \"tcmalloc.h\"      // must come early, to pick up posix_memalign\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#if defined HAVE_STDINT_H\n#include <stdint.h>        // for intptr_t\n#endif\n#include <sys/types.h>     // for size_t\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>         // for open; used with mmap-hook test\n#endif\n#ifdef HAVE_MMAP\n#include <sys/mman.h>      // for testing mmap hooks\n#endif\n#ifdef HAVE_MALLOC_H\n#include <malloc.h>        // defines pvalloc/etc on cygwin\n#endif\n#include <assert.h>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <new>\n#include \"base/logging.h\"\n#include \"base/simple_mutex.h\"\n#include \"google/malloc_hook.h\"\n#include \"google/malloc_extension.h\"\n#include \"google/tcmalloc.h\"\n#include \"thread_cache.h\"\n#include \"tests/testutil.h\"\n\n// Windows doesn't define pvalloc and a few other obsolete unix\n// functions; nor does it define posix_memalign (which is not obsolete).\n#if defined(_MSC_VER) || defined(__MINGW32__)\n# define cfree free         // don't bother to try to test these obsolete fns\n# define valloc malloc\n# define pvalloc malloc\n// I'd like to map posix_memalign to _aligned_malloc, but _aligned_malloc\n// must be paired with _aligned_free (not normal free), which is too\n// invasive a change to how we allocate memory here.  So just bail\n# include <errno.h>\n# define memalign(alignment, size)         malloc(size)\n# define posix_memalign(pptr, align, size) ((*(pptr)=malloc(size)) ? 0 : ENOMEM)\n#endif\n\n// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old\n// form of the name instead.\n#ifndef MAP_ANONYMOUS\n# define MAP_ANONYMOUS MAP_ANON\n#endif\n\n#define LOGSTREAM   stdout\n\nusing std::vector;\nusing std::string;\n\nDECLARE_double(tcmalloc_release_rate);\nDECLARE_int32(max_free_queue_size);     // in debugallocation.cc\nDECLARE_int64(tcmalloc_sample_parameter);\n\nnamespace testing {\n\nstatic const int FLAGS_numtests = 50000;\nstatic const int FLAGS_log_every_n_tests = 50000; // log exactly once\n\n// Testing parameters\nstatic const int FLAGS_lgmaxsize = 16;   // lg() of the max size object to alloc\nstatic const int FLAGS_numthreads = 10;  // Number of threads\nstatic const int FLAGS_threadmb = 4;     // Max memory size allocated by thread\nstatic const int FLAGS_lg_max_memalign = 18; // lg of max alignment for memalign\n\nstatic const double FLAGS_memalign_min_fraction = 0;    // min expected%\nstatic const double FLAGS_memalign_max_fraction = 0.4;  // max expected%\nstatic const double FLAGS_memalign_max_alignment_ratio = 6;  // alignment/size\n\n// Weights of different operations\nstatic const int FLAGS_allocweight = 50;    // Weight for picking allocation\nstatic const int FLAGS_freeweight = 50;     // Weight for picking free\nstatic const int FLAGS_updateweight = 10;   // Weight for picking update\nstatic const int FLAGS_passweight = 1;      // Weight for passing object\n\nstatic const int kSizeBits = 8 * sizeof(size_t);\nstatic const size_t kMaxSize = ~static_cast<size_t>(0);\nstatic const size_t kMaxSignedSize = ((size_t(1) << (kSizeBits-1)) - 1);\n\nstatic const size_t kNotTooBig = 100000;\nstatic const size_t kTooBig = kMaxSize;\n\nstatic int news_handled = 0;\n\n// Global array of threads\nclass TesterThread;\nstatic TesterThread** threads;\n\n// To help with generating random numbers\nclass TestHarness {\n private:\n  // Information kept per type\n  struct Type {\n    string      name;\n    int         type;\n    int         weight;\n  };\n\n public:\n  TestHarness(int seed)\n      : types_(new vector<Type>), total_weight_(0), num_tests_(0) {\n    srandom(seed);\n  }\n  ~TestHarness() {\n    delete types_;\n  }\n\n  // Add operation type with specified weight.  When starting a new\n  // iteration, an operation type is picked with probability\n  // proportional to its weight.\n  //\n  // \"type\" must be non-negative.\n  // \"weight\" must be non-negative.\n  void AddType(int type, int weight, const char* name);\n\n  // Call this to get the type of operation for the next iteration.\n  // It returns a random operation type from the set of registered\n  // operations.  Returns -1 if tests should finish.\n  int PickType();\n\n  // If n == 0, returns the next pseudo-random number in the range [0 .. 0]\n  // If n != 0, returns the next pseudo-random number in the range [0 .. n)\n  int Uniform(int n) {\n    if (n == 0) {\n      return random() * 0;\n    } else {\n      return random() % n;\n    }\n  }\n  // Pick \"base\" uniformly from range [0,max_log] and then return\n  // \"base\" random bits.  The effect is to pick a number in the range\n  // [0,2^max_log-1] with bias towards smaller numbers.\n  int Skewed(int max_log) {\n    const int base = random() % (max_log+1);\n    return random() % (1 << base);\n  }\n\n private:\n  vector<Type>*         types_;         // Registered types\n  int                   total_weight_;  // Total weight of all types\n  int                   num_tests_;     // Num tests run so far\n};\n\nvoid TestHarness::AddType(int type, int weight, const char* name) {\n  Type t;\n  t.name = name;\n  t.type = type;\n  t.weight = weight;\n  types_->push_back(t);\n  total_weight_ += weight;\n}\n\nint TestHarness::PickType() {\n  if (num_tests_ >= FLAGS_numtests) return -1;\n  num_tests_++;\n\n  assert(total_weight_ > 0);\n  // This is a little skewed if total_weight_ doesn't divide 2^31, but it's close\n  int v = Uniform(total_weight_);\n  int i;\n  for (i = 0; i < types_->size(); i++) {\n    v -= (*types_)[i].weight;\n    if (v < 0) {\n      break;\n    }\n  }\n\n  assert(i < types_->size());\n  if ((num_tests_ % FLAGS_log_every_n_tests) == 0) {\n    fprintf(LOGSTREAM, \"  Test %d out of %d: %s\\n\",\n            num_tests_, FLAGS_numtests, (*types_)[i].name.c_str());\n  }\n  return (*types_)[i].type;\n}\n\nclass AllocatorState : public TestHarness {\n public:\n  explicit AllocatorState(int seed) : TestHarness(seed) {\n    CHECK_GE(FLAGS_memalign_max_fraction, 0);\n    CHECK_LE(FLAGS_memalign_max_fraction, 1);\n    CHECK_GE(FLAGS_memalign_min_fraction, 0);\n    CHECK_LE(FLAGS_memalign_min_fraction, 1);\n    double delta = FLAGS_memalign_max_fraction - FLAGS_memalign_min_fraction;\n    CHECK_GE(delta, 0);\n    memalign_fraction_ = (Uniform(10000)/10000.0 * delta +\n                          FLAGS_memalign_min_fraction);\n    //fprintf(LOGSTREAM, \"memalign fraction: %f\\n\", memalign_fraction_);\n  }\n  virtual ~AllocatorState() {}\n\n  // Allocate memory.  Randomly choose between malloc() or posix_memalign().\n  void* alloc(size_t size) {\n    if (Uniform(100) < memalign_fraction_ * 100) {\n      // Try a few times to find a reasonable alignment, or fall back on malloc.\n      for (int i = 0; i < 5; i++) {\n        size_t alignment = 1 << Uniform(FLAGS_lg_max_memalign);\n        if (alignment >= sizeof(intptr_t) &&\n            (size < sizeof(intptr_t) ||\n             alignment < FLAGS_memalign_max_alignment_ratio * size)) {\n          void *result = reinterpret_cast<void*>(static_cast<intptr_t>(0x1234));\n          int err = posix_memalign(&result, alignment, size);\n          if (err != 0) {\n            CHECK_EQ(err, ENOMEM);\n          }\n          return err == 0 ? result : NULL;\n        }\n      }\n    }\n    return malloc(size);\n  }\n\n private:\n  double memalign_fraction_;\n};\n\n\n// Info kept per thread\nclass TesterThread {\n private:\n  // Info kept per allocated object\n  struct Object {\n    char*       ptr;                    // Allocated pointer\n    int         size;                   // Allocated size\n    int         generation;             // Generation counter of object contents\n  };\n\n  Mutex                 lock_;          // For passing in another thread's obj\n  int                   id_;            // My thread id\n  AllocatorState        rnd_;           // For generating random numbers\n  vector<Object>        heap_;          // This thread's heap\n  vector<Object>        passed_;        // Pending objects passed from others\n  size_t                heap_size_;     // Current heap size\n  int                   locks_ok_;      // Number of OK TryLock() ops\n  int                   locks_failed_;  // Number of failed TryLock() ops\n\n  // Type of operations\n  enum Type { ALLOC, FREE, UPDATE, PASS };\n\n  // ACM minimal standard random number generator.  (re-entrant.)\n  class ACMRandom {\n    int32 seed_;\n   public:\n    explicit ACMRandom(int32 seed) { seed_ = seed; }\n    int32 Next() {\n      const int32 M = 2147483647L;   // 2^31-1\n      const int32 A = 16807;\n      // In effect, we are computing seed_ = (seed_ * A) % M, where M = 2^31-1\n      uint32 lo = A * (int32)(seed_ & 0xFFFF);\n      uint32 hi = A * (int32)((uint32)seed_ >> 16);\n      lo += (hi & 0x7FFF) << 16;\n      if (lo > M) {\n        lo &= M;\n        ++lo;\n      }\n      lo += hi >> 15;\n      if (lo > M) {\n        lo &= M;\n        ++lo;\n      }\n      return (seed_ = (int32) lo);\n    }\n  };\n\n public:\n  TesterThread(int id)\n    : id_(id),\n      rnd_(id+1),\n      heap_size_(0),\n      locks_ok_(0),\n      locks_failed_(0) {\n  }\n\n  virtual ~TesterThread() {\n    if (FLAGS_verbose)\n      fprintf(LOGSTREAM, \"Thread %2d: locks %6d ok; %6d trylocks failed\\n\",\n              id_, locks_ok_, locks_failed_);\n    if (locks_ok_ + locks_failed_ >= 1000) {\n      CHECK_LE(locks_failed_, locks_ok_ / 2);\n    }\n  }\n\n  virtual void Run() {\n    rnd_.AddType(ALLOC,  FLAGS_allocweight,   \"allocate\");\n    rnd_.AddType(FREE,   FLAGS_freeweight,    \"free\");\n    rnd_.AddType(UPDATE, FLAGS_updateweight,  \"update\");\n    rnd_.AddType(PASS,   FLAGS_passweight,    \"pass\");\n\n    while (true) {\n      AcquirePassedObjects();\n\n      switch (rnd_.PickType()) {\n        case ALLOC:   AllocateObject(); break;\n        case FREE:    FreeObject();     break;\n        case UPDATE:  UpdateObject();   break;\n        case PASS:    PassObject();     break;\n        case -1:      goto done;\n        default:      assert(NULL == \"Unknown type\");\n      }\n\n      ShrinkHeap();\n    }\n\n done:\n    DeleteHeap();\n  }\n\n  // Allocate a new object\n  void AllocateObject() {\n    Object object;\n    object.size = rnd_.Skewed(FLAGS_lgmaxsize);\n    object.ptr = static_cast<char*>(rnd_.alloc(object.size));\n    CHECK(object.ptr);\n    object.generation = 0;\n    FillContents(&object);\n    heap_.push_back(object);\n    heap_size_ += object.size;\n  }\n\n  // Mutate a random object\n  void UpdateObject() {\n    if (heap_.empty()) return;\n    const int index = rnd_.Uniform(heap_.size());\n    CheckContents(heap_[index]);\n    heap_[index].generation++;\n    FillContents(&heap_[index]);\n  }\n\n  // Free a random object\n  void FreeObject() {\n    if (heap_.empty()) return;\n    const int index = rnd_.Uniform(heap_.size());\n    Object object = heap_[index];\n    CheckContents(object);\n    free(object.ptr);\n    heap_size_ -= object.size;\n    heap_[index] = heap_[heap_.size()-1];\n    heap_.pop_back();\n  }\n\n  // Delete all objects in the heap\n  void DeleteHeap() {\n    while (!heap_.empty()) {\n      FreeObject();\n    }\n  }\n\n  // Free objects until our heap is small enough\n  void ShrinkHeap() {\n    while (heap_size_ > FLAGS_threadmb << 20) {\n      assert(!heap_.empty());\n      FreeObject();\n    }\n  }\n\n  // Pass a random object to another thread\n  void PassObject() {\n    // Pick object to pass\n    if (heap_.empty()) return;\n    const int index = rnd_.Uniform(heap_.size());\n    Object object = heap_[index];\n    CheckContents(object);\n\n    // Pick thread to pass\n    const int tid = rnd_.Uniform(FLAGS_numthreads);\n    TesterThread* thread = threads[tid];\n\n    if (thread->lock_.TryLock()) {\n      // Pass the object\n      locks_ok_++;\n      thread->passed_.push_back(object);\n      thread->lock_.Unlock();\n      heap_size_ -= object.size;\n      heap_[index] = heap_[heap_.size()-1];\n      heap_.pop_back();\n    } else {\n      locks_failed_++;\n    }\n  }\n\n  // Grab any objects passed to this thread by another thread\n  void AcquirePassedObjects() {\n    // We do not create unnecessary contention by always using\n    // TryLock().  Plus we unlock immediately after swapping passed\n    // objects into a local vector.\n    vector<Object> copy;\n    { // Locking scope\n      if (!lock_.TryLock()) {\n        locks_failed_++;\n        return;\n      }\n      locks_ok_++;\n      swap(copy, passed_);\n      lock_.Unlock();\n    }\n\n    for (int i = 0; i < copy.size(); ++i) {\n      const Object& object = copy[i];\n      CheckContents(object);\n      heap_.push_back(object);\n      heap_size_ += object.size;\n    }\n  }\n\n  // Fill object contents according to ptr/generation\n  void FillContents(Object* object) {\n    ACMRandom r(reinterpret_cast<intptr_t>(object->ptr) & 0x7fffffff);\n    for (int i = 0; i < object->generation; ++i) {\n      r.Next();\n    }\n    const char c = static_cast<char>(r.Next());\n    memset(object->ptr, c, object->size);\n  }\n\n  // Check object contents\n  void CheckContents(const Object& object) {\n    ACMRandom r(reinterpret_cast<intptr_t>(object.ptr) & 0x7fffffff);\n    for (int i = 0; i < object.generation; ++i) {\n      r.Next();\n    }\n\n    // For large objects, we just check a prefix/suffix\n    const char expected = static_cast<char>(r.Next());\n    const int limit1 = object.size < 32 ? object.size : 32;\n    const int start2 = limit1 > object.size - 32 ? limit1 : object.size - 32;\n    for (int i = 0; i < limit1; ++i) {\n      CHECK_EQ(object.ptr[i], expected);\n    }\n    for (int i = start2; i < object.size; ++i) {\n      CHECK_EQ(object.ptr[i], expected);\n    }\n  }\n};\n\nstatic void RunThread(int thread_id) {\n  threads[thread_id]->Run();\n}\n\nstatic void TryHugeAllocation(size_t s, AllocatorState* rnd) {\n  void* p = rnd->alloc(s);\n  CHECK(p == NULL);   // huge allocation s should fail!\n}\n\nstatic void TestHugeAllocations(AllocatorState* rnd) {\n  // Check that asking for stuff tiny bit smaller than largest possible\n  // size returns NULL.\n  for (size_t i = 0; i < 70000; i += rnd->Uniform(20)) {\n    TryHugeAllocation(kMaxSize - i, rnd);\n  }\n  // Asking for memory sizes near signed/unsigned boundary (kMaxSignedSize)\n  // might work or not, depending on the amount of virtual memory.\n#ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs\n  for (size_t i = 0; i < 100; i++) {\n    void* p = NULL;\n    p = rnd->alloc(kMaxSignedSize + i);\n    if (p) free(p);    // if: free(NULL) is not necessarily defined\n    p = rnd->alloc(kMaxSignedSize - i);\n    if (p) free(p);\n  }\n#endif\n\n  // Check that ReleaseFreeMemory has no visible effect (aka, does not\n  // crash the test):\n  MallocExtension* inst = MallocExtension::instance();\n  CHECK(inst);\n  inst->ReleaseFreeMemory();\n}\n\nstatic void TestCalloc(size_t n, size_t s, bool ok) {\n  char* p = reinterpret_cast<char*>(calloc(n, s));\n  if (FLAGS_verbose)\n    fprintf(LOGSTREAM, \"calloc(%\"PRIxS\", %\"PRIxS\"): %p\\n\", n, s, p);\n  if (!ok) {\n    CHECK(p == NULL);  // calloc(n, s) should not succeed\n  } else {\n    CHECK(p != NULL);  // calloc(n, s) should succeed\n    for (int i = 0; i < n*s; i++) {\n      CHECK(p[i] == '\\0');\n    }\n    free(p);\n  }\n}\n\n// This makes sure that reallocing a small number of bytes in either\n// direction doesn't cause us to allocate new memory.\nstatic void TestRealloc() {\n#ifndef DEBUGALLOCATION  // debug alloc doesn't try to minimize reallocs\n  // When sampling, we always allocate in units of page-size, which\n  // makes reallocs of small sizes do extra work (thus, failing these\n  // checks).  Since sampling is random, we turn off sampling to make\n  // sure that doesn't happen to us here.\n  const int64 old_sample_parameter = FLAGS_tcmalloc_sample_parameter;\n  FLAGS_tcmalloc_sample_parameter = 0;   // turn off sampling\n\n  int start_sizes[] = { 100, 1000, 10000, 100000 };\n  int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 };\n\n  for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) {\n    void* p = malloc(start_sizes[s]);\n    CHECK(p);\n    // The larger the start-size, the larger the non-reallocing delta.\n    for (int d = 0; d < (s+1) * 2; ++d) {\n      void* new_p = realloc(p, start_sizes[s] + deltas[d]);\n      CHECK(p == new_p);  // realloc should not allocate new memory\n    }\n    // Test again, but this time reallocing smaller first.\n    for (int d = 0; d < s*2; ++d) {\n      void* new_p = realloc(p, start_sizes[s] - deltas[d]);\n      CHECK(p == new_p);  // realloc should not allocate new memory\n    }\n    free(p);\n  }\n  FLAGS_tcmalloc_sample_parameter = old_sample_parameter;\n#endif\n}\n\nstatic void TestNewHandler() throw (std::bad_alloc) {\n  ++news_handled;\n  throw std::bad_alloc();\n}\n\nstatic void TestOneNew(void* (*func)(size_t)) {\n  // success test\n  try {\n    void* ptr = (*func)(kNotTooBig);\n    if (0 == ptr) {\n      fprintf(LOGSTREAM, \"allocation should not have failed.\\n\");\n      abort();\n    }\n  } catch (...) {\n    fprintf(LOGSTREAM, \"allocation threw unexpected exception.\\n\");\n    abort();\n  }\n\n  // failure test\n  // we should always receive a bad_alloc exception\n  try {\n    (*func)(kTooBig);\n    fprintf(LOGSTREAM, \"allocation should have failed.\\n\");\n    abort();\n  } catch (const std::bad_alloc&) {\n    // correct\n  } catch (...) {\n    fprintf(LOGSTREAM, \"allocation threw unexpected exception.\\n\");\n    abort();\n  }\n}\n\nstatic void TestNew(void* (*func)(size_t)) {\n  news_handled = 0;\n\n  // test without new_handler:\n  std::new_handler saved_handler = std::set_new_handler(0);\n  TestOneNew(func);\n\n  // test with new_handler:\n  std::set_new_handler(TestNewHandler);\n  TestOneNew(func);\n  if (news_handled != 1) {\n    fprintf(LOGSTREAM, \"new_handler was not called.\\n\");\n    abort();\n  }\n  std::set_new_handler(saved_handler);\n}\n\nstatic void TestOneNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {\n  // success test\n  try {\n    void* ptr = (*func)(kNotTooBig, std::nothrow);\n    if (0 == ptr) {\n      fprintf(LOGSTREAM, \"allocation should not have failed.\\n\");\n      abort();\n    }\n  } catch (...) {\n    fprintf(LOGSTREAM, \"allocation threw unexpected exception.\\n\");\n    abort();\n  }\n\n  // failure test\n  // we should always receive a bad_alloc exception\n  try {\n    if ((*func)(kTooBig, std::nothrow) != 0) {\n      fprintf(LOGSTREAM, \"allocation should have failed.\\n\");\n      abort();\n    }\n  } catch (...) {\n    fprintf(LOGSTREAM, \"nothrow allocation threw unexpected exception.\\n\");\n    abort();\n  }\n}\n\nstatic void TestNothrowNew(void* (*func)(size_t, const std::nothrow_t&)) {\n  news_handled = 0;\n\n  // test without new_handler:\n  std::new_handler saved_handler = std::set_new_handler(0);\n  TestOneNothrowNew(func);\n\n  // test with new_handler:\n  std::set_new_handler(TestNewHandler);\n  TestOneNothrowNew(func);\n  if (news_handled != 1) {\n    fprintf(LOGSTREAM, \"nothrow new_handler was not called.\\n\");\n    abort();\n  }\n  std::set_new_handler(saved_handler);\n}\n\n\n// These are used as callbacks by the sanity-check.  Set* and Reset*\n// register the hook that counts how many times the associated memory\n// function is called.  After each such call, call Verify* to verify\n// that we used the tcmalloc version of the call, and not the libc.\n// Note the ... in the hook signature: we don't care what arguments\n// the hook takes.\n#define MAKE_HOOK_CALLBACK(hook_type)                                   \\\n  static int g_##hook_type##_calls = 0;                                 \\\n  static void IncrementCallsTo##hook_type(...) {                        \\\n    g_##hook_type##_calls++;                                            \\\n  }                                                                     \\\n  static void Verify##hook_type##WasCalled() {                          \\\n    CHECK_GT(g_##hook_type##_calls, 0);                                 \\\n    g_##hook_type##_calls = 0;  /* reset for next call */               \\\n  }                                                                     \\\n  static MallocHook::hook_type g_old_##hook_type;                       \\\n  static void Set##hook_type() {                                        \\\n    g_old_##hook_type = MallocHook::Set##hook_type(                     \\\n     (MallocHook::hook_type)&IncrementCallsTo##hook_type);              \\\n  }                                                                     \\\n  static void Reset##hook_type() {                                      \\\n    CHECK_EQ(MallocHook::Set##hook_type(g_old_##hook_type),             \\\n             (MallocHook::hook_type)&IncrementCallsTo##hook_type);      \\\n  }\n\n// We do one for each hook typedef in malloc_hook.h\nMAKE_HOOK_CALLBACK(NewHook);\nMAKE_HOOK_CALLBACK(DeleteHook);\nMAKE_HOOK_CALLBACK(MmapHook);\nMAKE_HOOK_CALLBACK(MremapHook);\nMAKE_HOOK_CALLBACK(MunmapHook);\nMAKE_HOOK_CALLBACK(SbrkHook);\n\nstatic void TestAlignmentForSize(int size) {\n  fprintf(LOGSTREAM, \"Testing alignment of malloc(%d)\\n\", size);\n  static const int kNum = 100;\n  void* ptrs[kNum];\n  for (int i = 0; i < kNum; i++) {\n    ptrs[i] = malloc(size);\n    uintptr_t p = reinterpret_cast<uintptr_t>(ptrs[i]);\n    CHECK((p % sizeof(void*)) == 0);\n    CHECK((p % sizeof(double)) == 0);\n\n    // Must have 16-byte alignment for large enough objects\n    if (size >= 16) {\n      CHECK((p % 16) == 0);\n    }\n  }\n  for (int i = 0; i < kNum; i++) {\n    free(ptrs[i]);\n  }\n}\n\nstatic void TestMallocAlignment() {\n  for (int lg = 0; lg < 16; lg++) {\n    TestAlignmentForSize((1<<lg) - 1);\n    TestAlignmentForSize((1<<lg) + 0);\n    TestAlignmentForSize((1<<lg) + 1);\n  }\n}\n\nstatic void TestHugeThreadCache() {\n  fprintf(LOGSTREAM, \"==== Testing huge thread cache\\n\");\n  // More than 2^16 to cause integer overflow of 16 bit counters.\n  static const int kNum = 70000;\n  char** array = new char*[kNum];\n  for (int i = 0; i < kNum; ++i) {\n    array[i] = new char[10];\n  }\n  for (int i = 0; i < kNum; ++i) {\n    delete[] array[i];\n  }\n  delete[] array;\n}\n\nnamespace {\n\nstruct RangeCallbackState {\n  uintptr_t ptr;\n  base::MallocRange::Type expected_type;\n  size_t min_size;\n  bool matched;\n};\n\nstatic void RangeCallback(void* arg, const base::MallocRange* r) {\n  RangeCallbackState* state = reinterpret_cast<RangeCallbackState*>(arg);\n  if (state->ptr >= r->address &&\n      state->ptr < r->address + r->length) {\n    CHECK_EQ(r->type, state->expected_type);\n    CHECK_GE(r->length, state->min_size);\n    state->matched = true;\n  }\n}\n\n// Check that at least one of the callbacks from Ranges() contains\n// the specified address with the specified type, and has size\n// >= min_size.\nstatic void CheckRangeCallback(void* ptr, base::MallocRange::Type type,\n                               size_t min_size) {\n  RangeCallbackState state;\n  state.ptr = reinterpret_cast<uintptr_t>(ptr);\n  state.expected_type = type;\n  state.min_size = min_size;\n  state.matched = false;\n  MallocExtension::instance()->Ranges(&state, RangeCallback);\n  CHECK(state.matched);\n}\n\n}\n\nstatic void TestRanges() {\n  static const int MB = 1048576;\n  void* a = malloc(MB);\n  void* b = malloc(MB);\n  CheckRangeCallback(a, base::MallocRange::INUSE, MB);\n  CheckRangeCallback(b, base::MallocRange::INUSE, MB);\n  free(a);\n  CheckRangeCallback(a, base::MallocRange::FREE, MB);\n  CheckRangeCallback(b, base::MallocRange::INUSE, MB);\n  MallocExtension::instance()->ReleaseFreeMemory();\n  CheckRangeCallback(a, base::MallocRange::UNMAPPED, MB);\n  CheckRangeCallback(b, base::MallocRange::INUSE, MB);\n  free(b);\n  CheckRangeCallback(a, base::MallocRange::UNMAPPED, MB);\n  CheckRangeCallback(b, base::MallocRange::FREE, MB);\n}\n\n#ifndef DEBUGALLOCATION\nstatic size_t GetUnmappedBytes() {\n  size_t bytes;\n  CHECK(MallocExtension::instance()->GetNumericProperty(\n      \"tcmalloc.pageheap_unmapped_bytes\", &bytes));\n  return bytes;\n}\n#endif\n\nstatic void TestReleaseToSystem() {\n  // Debug allocation mode adds overhead to each allocation which\n  // messes up all the equality tests here.  I just disable the\n  // teset in this mode.  TODO(csilvers): get it to work for debugalloc?\n#ifndef DEBUGALLOCATION\n  const double old_tcmalloc_release_rate = FLAGS_tcmalloc_release_rate;\n  FLAGS_tcmalloc_release_rate = 0;\n\n  static const int MB = 1048576;\n  void* a = malloc(MB);\n  void* b = malloc(MB);\n  MallocExtension::instance()->ReleaseFreeMemory();\n  size_t starting_bytes = GetUnmappedBytes();\n\n  // Calling ReleaseFreeMemory() a second time shouldn't do anything.\n  MallocExtension::instance()->ReleaseFreeMemory();\n  EXPECT_EQ(starting_bytes, GetUnmappedBytes());\n\n  // ReleaseToSystem shouldn't do anything either.\n  MallocExtension::instance()->ReleaseToSystem(MB);\n  EXPECT_EQ(starting_bytes, GetUnmappedBytes());\n\n  free(a);\n\n  // The span to release should be 1MB.\n  MallocExtension::instance()->ReleaseToSystem(MB/2);\n  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());\n\n  // Should do nothing since the previous call released too much.\n  MallocExtension::instance()->ReleaseToSystem(MB/4);\n  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());\n\n  free(b);\n\n  // Use up the extra MB/4 bytes from 'a' and also release 'b'.\n  MallocExtension::instance()->ReleaseToSystem(MB/2);\n  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());\n\n  // Should do nothing since the previous call released too much.\n  MallocExtension::instance()->ReleaseToSystem(MB/2);\n  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());\n\n  // Nothing else to release.\n  MallocExtension::instance()->ReleaseFreeMemory();\n  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());\n\n  a = malloc(MB);\n  free(a);\n  EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());\n\n  // Releasing less than a page should still trigger a release.\n  MallocExtension::instance()->ReleaseToSystem(1);\n  EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());\n\n  FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate;\n#endif   // #ifndef DEBUGALLOCATION\n}\n\nbool g_no_memory = false;\nstd::new_handler g_old_handler = NULL;\nstatic void OnNoMemory() {\n  g_no_memory = true;\n  std::set_new_handler(g_old_handler);\n}\n\nstatic void TestSetNewMode() {\n  int old_mode = tc_set_new_mode(1);\n\n  // DebugAllocation will try to catch huge allocations.  We need to avoid this\n  // by requesting a smaller malloc block, that still can't be satisfied.\n  const size_t kHugeRequest = kTooBig - 1024;\n\n  g_old_handler = std::set_new_handler(&OnNoMemory);\n  g_no_memory = false;\n  void* ret = malloc(kHugeRequest);\n  EXPECT_EQ(NULL, ret);\n  EXPECT_TRUE(g_no_memory);\n\n  g_old_handler = std::set_new_handler(&OnNoMemory);\n  g_no_memory = false;\n  ret = calloc(1, kHugeRequest);\n  EXPECT_EQ(NULL, ret);\n  EXPECT_TRUE(g_no_memory);\n\n  g_old_handler = std::set_new_handler(&OnNoMemory);\n  g_no_memory = false;\n  ret = realloc(NULL, kHugeRequest);\n  EXPECT_EQ(NULL, ret);\n  EXPECT_TRUE(g_no_memory);\n\n  // Not really important, but must be small enough such that kAlignment +\n  // kHugeRequest does not overflow.\n  const int kAlignment = 1 << 5;\n\n  g_old_handler = std::set_new_handler(&OnNoMemory);\n  g_no_memory = false;\n  ret = memalign(kAlignment, kHugeRequest);\n  EXPECT_EQ(NULL, ret);\n  EXPECT_TRUE(g_no_memory);\n\n  g_old_handler = std::set_new_handler(&OnNoMemory);\n  g_no_memory = false;\n  EXPECT_EQ(ENOMEM,\n            posix_memalign(&ret, kAlignment, kHugeRequest));\n  EXPECT_EQ(NULL, ret);\n  EXPECT_TRUE(g_no_memory);\n\n  tc_set_new_mode(old_mode);\n}\n\nstatic int RunAllTests(int argc, char** argv) {\n  // Optional argv[1] is the seed\n  AllocatorState rnd(argc > 1 ? atoi(argv[1]) : 100);\n\n  SetTestResourceLimit();\n\n  // TODO(odo):  This test has been disabled because it is only by luck that it\n  // does not result in fragmentation.  When tcmalloc makes an allocation which\n  // spans previously unused leaves of the pagemap it will allocate and fill in\n  // the leaves to cover the new allocation.  The leaves happen to be 256MiB in\n  // the 64-bit build, and with the sbrk allocator these allocations just\n  // happen to fit in one leaf by luck.  With other allocators (mmap,\n  // memfs_malloc when used with small pages) the allocations generally span\n  // two leaves and this results in a very bad fragmentation pattern with this\n  // code.  The same failure can be forced with the sbrk allocator just by\n  // allocating something on the order of 128MiB prior to starting this test so\n  // that the test allocations straddle a 256MiB boundary.\n\n  // TODO(csilvers): port MemoryUsage() over so the test can use that\n#if 0\n# include <unistd.h>      // for getpid()\n  // Allocate and deallocate blocks of increasing sizes to check if the alloc\n  // metadata fragments the memory. (Do not put other allocations/deallocations\n  // before this test, it may break).\n  {\n    size_t memory_usage = MemoryUsage(getpid());\n    fprintf(LOGSTREAM, \"Testing fragmentation\\n\");\n    for ( int i = 200; i < 240; ++i ) {\n      int size = i << 20;\n      void *test1 = rnd.alloc(size);\n      CHECK(test1);\n      for ( int j = 0; j < size; j += (1 << 12) ) {\n        static_cast<char*>(test1)[j] = 1;\n      }\n      free(test1);\n    }\n    // There may still be a bit of fragmentation at the beginning, until we\n    // reach kPageMapBigAllocationThreshold bytes so we check for\n    // 200 + 240 + margin.\n    CHECK_LT(MemoryUsage(getpid()), memory_usage + (450 << 20) );\n  }\n#endif\n\n  // Check that empty allocation works\n  fprintf(LOGSTREAM, \"Testing empty allocation\\n\");\n  {\n    void* p1 = rnd.alloc(0);\n    CHECK(p1 != NULL);\n    void* p2 = rnd.alloc(0);\n    CHECK(p2 != NULL);\n    CHECK(p1 != p2);\n    free(p1);\n    free(p2);\n  }\n\n  // This code stresses some of the memory allocation via STL.\n  // It may call operator delete(void*, nothrow_t).\n  fprintf(LOGSTREAM, \"Testing STL use\\n\");\n  {\n    std::vector<int> v;\n    v.push_back(1);\n    v.push_back(2);\n    v.push_back(3);\n    v.push_back(0);\n    std::stable_sort(v.begin(), v.end());\n  }\n\n  // Test each of the memory-allocation functions once, just as a sanity-check\n  fprintf(LOGSTREAM, \"Sanity-testing all the memory allocation functions\\n\");\n  {\n    // We use new-hook and delete-hook to verify we actually called the\n    // tcmalloc version of these routines, and not the libc version.\n    SetNewHook();      // defined as part of MAKE_HOOK_CALLBACK, above\n    SetDeleteHook();   // ditto\n\n    void* p1 = malloc(10);\n    VerifyNewHookWasCalled();\n    // Also test the non-standard tc_malloc_size\n    size_t actual_p1_size = tc_malloc_size(p1);\n    CHECK_GE(actual_p1_size, 10);\n    CHECK_LT(actual_p1_size, 100000);   // a reasonable upper-bound, I think\n    free(p1);\n    VerifyDeleteHookWasCalled();\n\n\n    p1 = calloc(10, 2);\n    VerifyNewHookWasCalled();\n    p1 = realloc(p1, 30);\n    VerifyNewHookWasCalled();\n    VerifyDeleteHookWasCalled();\n    cfree(p1);  // synonym for free\n    VerifyDeleteHookWasCalled();\n\n    CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0);\n    VerifyNewHookWasCalled();\n    free(p1);\n    VerifyDeleteHookWasCalled();\n\n    p1 = memalign(sizeof(p1) * 2, 50);\n    VerifyNewHookWasCalled();\n    free(p1);\n    VerifyDeleteHookWasCalled();\n\n    // Windows has _aligned_malloc.  Let's test that that's captured too.\n#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED_MALLOC)\n    p1 = _aligned_malloc(sizeof(p1) * 2, 64);\n    VerifyNewHookWasCalled();\n    _aligned_free(p1);\n    VerifyDeleteHookWasCalled();\n#endif\n\n    p1 = valloc(60);\n    VerifyNewHookWasCalled();\n    free(p1);\n    VerifyDeleteHookWasCalled();\n\n    p1 = pvalloc(70);\n    VerifyNewHookWasCalled();\n    free(p1);\n    VerifyDeleteHookWasCalled();\n\n    char* p2 = new char;\n    VerifyNewHookWasCalled();\n    delete p2;\n    VerifyDeleteHookWasCalled();\n\n    p2 = new char[100];\n    VerifyNewHookWasCalled();\n    delete[] p2;\n    VerifyDeleteHookWasCalled();\n\n    p2 = new(std::nothrow) char;\n    VerifyNewHookWasCalled();\n    delete p2;\n    VerifyDeleteHookWasCalled();\n\n    p2 = new(std::nothrow) char[100];\n    VerifyNewHookWasCalled();\n    delete[] p2;\n    VerifyDeleteHookWasCalled();\n\n    // Another way of calling operator new\n    p2 = static_cast<char*>(::operator new(100));\n    VerifyNewHookWasCalled();\n    ::operator delete(p2);\n    VerifyDeleteHookWasCalled();\n\n    // Try to call nothrow's delete too.  Compilers use this.\n    p2 = static_cast<char*>(::operator new(100, std::nothrow));\n    VerifyNewHookWasCalled();\n    ::operator delete(p2, std::nothrow);\n    VerifyDeleteHookWasCalled();\n\n    // Test mmap too: both anonymous mmap and mmap of a file\n    // Note that for right now we only override mmap on linux\n    // systems, so those are the only ones for which we check.\n    SetMmapHook();\n    SetMremapHook();\n    SetMunmapHook();\n#if defined(HAVE_MMAP) && defined(__linux) && \\\n       (defined(__i386__) || defined(__x86_64__))\n    int size = 8192*2;\n    p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE,\n              -1, 0);\n    VerifyMmapHookWasCalled();\n    p1 = mremap(p1, size, size/2, 0);\n    VerifyMremapHookWasCalled();\n    size /= 2;\n    munmap(p1, size);\n    VerifyMunmapHookWasCalled();\n\n    int fd = open(\"/dev/zero\", O_RDONLY);\n    CHECK_GE(fd, 0);   // make sure the open succeeded\n    p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);\n    VerifyMmapHookWasCalled();\n    munmap(p1, 8192);\n    VerifyMunmapHookWasCalled();\n    close(fd);\n#else   // this is just to quiet the compiler: make sure all fns are called\n    IncrementCallsToMmapHook();\n    IncrementCallsToMunmapHook();\n    IncrementCallsToMremapHook();\n    VerifyMmapHookWasCalled();\n    VerifyMremapHookWasCalled();\n    VerifyMunmapHookWasCalled();\n#endif\n\n    // Test sbrk\n    SetSbrkHook();\n#if defined(HAVE_SBRK) && defined(__linux) && \\\n       (defined(__i386__) || defined(__x86_64__))\n    p1 = sbrk(8192);\n    VerifySbrkHookWasCalled();\n    p1 = sbrk(-8192);\n    VerifySbrkHookWasCalled();\n    // However, sbrk hook should *not* be called with sbrk(0)\n    p1 = sbrk(0);\n    CHECK_EQ(g_SbrkHook_calls, 0);\n#else   // this is just to quiet the compiler: make sure all fns are called\n    IncrementCallsToSbrkHook();\n    VerifySbrkHookWasCalled();\n#endif\n\n    // Reset the hooks to what they used to be.  These are all\n    // defined as part of MAKE_HOOK_CALLBACK, above.\n    ResetNewHook();\n    ResetDeleteHook();\n    ResetMmapHook();\n    ResetMremapHook();\n    ResetMunmapHook();\n    ResetSbrkHook();\n  }\n\n  // Check that \"lots\" of memory can be allocated\n  fprintf(LOGSTREAM, \"Testing large allocation\\n\");\n  {\n    const int mb_to_allocate = 100;\n    void* p = rnd.alloc(mb_to_allocate << 20);\n    CHECK(p != NULL);  // could not allocate\n    free(p);\n  }\n\n  TestMallocAlignment();\n\n  // Check calloc() with various arguments\n  fprintf(LOGSTREAM, \"Testing calloc\\n\");\n  TestCalloc(0, 0, true);\n  TestCalloc(0, 1, true);\n  TestCalloc(1, 1, true);\n  TestCalloc(1<<10, 0, true);\n  TestCalloc(1<<20, 0, true);\n  TestCalloc(0, 1<<10, true);\n  TestCalloc(0, 1<<20, true);\n  TestCalloc(1<<20, 2, true);\n  TestCalloc(2, 1<<20, true);\n  TestCalloc(1000, 1000, true);\n\n  TestCalloc(kMaxSize, 2, false);\n  TestCalloc(2, kMaxSize, false);\n  TestCalloc(kMaxSize, kMaxSize, false);\n\n  TestCalloc(kMaxSignedSize, 3, false);\n  TestCalloc(3, kMaxSignedSize, false);\n  TestCalloc(kMaxSignedSize, kMaxSignedSize, false);\n\n  // Test that realloc doesn't always reallocate and copy memory.\n  fprintf(LOGSTREAM, \"Testing realloc\\n\");\n  TestRealloc();\n\n  fprintf(LOGSTREAM, \"Testing operator new(nothrow).\\n\");\n  TestNothrowNew(&::operator new);\n  fprintf(LOGSTREAM, \"Testing operator new[](nothrow).\\n\");\n  TestNothrowNew(&::operator new[]);\n  fprintf(LOGSTREAM, \"Testing operator new.\\n\");\n  TestNew(&::operator new);\n  fprintf(LOGSTREAM, \"Testing operator new[].\\n\");\n  TestNew(&::operator new[]);\n\n  // Create threads\n  fprintf(LOGSTREAM, \"Testing threaded allocation/deallocation (%d threads)\\n\",\n          FLAGS_numthreads);\n  threads = new TesterThread*[FLAGS_numthreads];\n  for (int i = 0; i < FLAGS_numthreads; ++i) {\n    threads[i] = new TesterThread(i);\n  }\n\n  // This runs all the tests at the same time, with a 1M stack size each\n  RunManyThreadsWithId(RunThread, FLAGS_numthreads, 1<<20);\n\n  for (int i = 0; i < FLAGS_numthreads; ++i) delete threads[i];    // Cleanup\n\n  // Do the memory intensive tests after threads are done, since exhausting\n  // the available address space can make pthread_create to fail.\n\n  // Check that huge allocations fail with NULL instead of crashing\n  fprintf(LOGSTREAM, \"Testing huge allocations\\n\");\n  TestHugeAllocations(&rnd);\n\n  // Check that large allocations fail with NULL instead of crashing\n#ifndef DEBUGALLOCATION    // debug allocation takes forever for huge allocs\n  fprintf(LOGSTREAM, \"Testing out of memory\\n\");\n  for (int s = 0; ; s += (10<<20)) {\n    void* large_object = rnd.alloc(s);\n    if (large_object == NULL) break;\n    free(large_object);\n  }\n#endif\n\n  TestHugeThreadCache();\n  TestRanges();\n  TestReleaseToSystem();\n  TestSetNewMode();\n\n  return 0;\n}\n\n}\n\nusing testing::RunAllTests;\n\nint main(int argc, char** argv) {\n#ifdef DEBUGALLOCATION    // debug allocation takes forever for huge allocs\n  FLAGS_max_free_queue_size = 0;  // return freed blocks to tcmalloc immediately\n#endif\n\n  RunAllTests(argc, argv);\n\n  // Test tc_version()\n  fprintf(LOGSTREAM, \"Testing tc_version()\\n\");\n  int major;\n  int minor;\n  const char* patch;\n  char mmp[64];\n  const char* human_version = tc_version(&major, &minor, &patch);\n  snprintf(mmp, sizeof(mmp), \"%d.%d%s\", major, minor, patch);\n  CHECK(!strcmp(PACKAGE_STRING, human_version));\n  CHECK(!strcmp(PACKAGE_VERSION, mmp));\n\n  fprintf(LOGSTREAM, \"PASS\\n\");\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/testutil.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n//\n// A few routines that are useful for multiple tests in this directory.\n\n#include \"config_for_unittests.h\"\n#include <stdlib.h>           // for NULL, abort()\n// On FreeBSD, if you #include <sys/resource.h>, you have to get stdint first.\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n#ifdef HAVE_SYS_RESOURCE_H\n#include <sys/resource.h>\n#endif\n#include \"tests/testutil.h\"\n\n\n// When compiled 64-bit and run on systems with swap several unittests will end\n// up trying to consume all of RAM+swap, and that can take quite some time.  By\n// limiting the address-space size we get sufficient coverage without blowing\n// out job limits.\nvoid SetTestResourceLimit() {\n#ifdef HAVE_SYS_RESOURCE_H\n  // The actual resource we need to set varies depending on which flavour of\n  // unix.  On Linux we need RLIMIT_AS because that covers the use of mmap.\n  // Otherwise hopefully RLIMIT_RSS is good enough.  (Unfortunately 64-bit\n  // and 32-bit headers disagree on the type of these constants!)\n#ifdef RLIMIT_AS\n#define USE_RESOURCE RLIMIT_AS\n#else\n#define USE_RESOURCE RLIMIT_RSS\n#endif\n\n  // Restrict the test to 1GiB, which should fit comfortably well on both\n  // 32-bit and 64-bit hosts, and executes in ~1s.\n  const rlim_t kMaxMem = 1<<30;\n\n  struct rlimit rlim;\n  if (getrlimit(USE_RESOURCE, &rlim) == 0) {\n    if (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > kMaxMem) {\n      rlim.rlim_cur = kMaxMem;\n      setrlimit(USE_RESOURCE, &rlim); // ignore result\n    }\n  }\n#endif  /* HAVE_SYS_RESOURCE_H */\n}\n\n\nstruct FunctionAndId {\n  void (*ptr_to_function)(int);\n  int id;\n};\n\n#if defined(NO_THREADS) || !(defined(HAVE_PTHREAD) || defined(_WIN32))\n\nextern \"C\" void RunThread(void (*fn)()) {\n  (*fn)();\n}\n\nextern \"C\" void RunManyThreads(void (*fn)(), int count) {\n  // I guess the best we can do is run fn sequentially, 'count' times\n  for (int i = 0; i < count; i++)\n    (*fn)();\n}\n\nextern \"C\" void RunManyThreadsWithId(void (*fn)(int), int count, int) {\n  for (int i = 0; i < count; i++)\n    (*fn)(i);    // stacksize doesn't make sense in a non-threaded context\n}\n\n#elif defined(_WIN32)\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */\n#endif\n#include <windows.h>\n\nextern \"C\" {\n  // This helper function has the signature that pthread_create wants.\n  DWORD WINAPI RunFunctionInThread(LPVOID ptr_to_ptr_to_fn) {\n    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    // runs fn\n    return 0;\n  }\n\n  DWORD WINAPI RunFunctionInThreadWithId(LPVOID ptr_to_fnid) {\n    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);\n    (*fn_and_id->ptr_to_function)(fn_and_id->id);   // runs fn\n    return 0;\n  }\n\n  void RunManyThreads(void (*fn)(), int count) {\n    DWORD dummy;\n    HANDLE* hThread = new HANDLE[count];\n    for (int i = 0; i < count; i++) {\n      hThread[i] = CreateThread(NULL, 0, RunFunctionInThread, &fn, 0, &dummy);\n      if (hThread[i] == NULL)  ExitProcess(i);\n    }\n    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);\n    for (int i = 0; i < count; i++) {\n      CloseHandle(hThread[i]);\n    }\n    delete[] hThread;\n  }\n\n  void RunThread(void (*fn)()) {\n    RunManyThreads(fn, 1);\n  }\n\n  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {\n    DWORD dummy;\n    HANDLE* hThread = new HANDLE[count];\n    FunctionAndId* fn_and_ids = new FunctionAndId[count];\n    for (int i = 0; i < count; i++) {\n      fn_and_ids[i].ptr_to_function = fn;\n      fn_and_ids[i].id = i;\n      hThread[i] = CreateThread(NULL, stacksize, RunFunctionInThreadWithId,\n                                &fn_and_ids[i], 0, &dummy);\n      if (hThread[i] == NULL)  ExitProcess(i);\n    }\n    WaitForMultipleObjects(count, hThread, TRUE, INFINITE);\n    for (int i = 0; i < count; i++) {\n      CloseHandle(hThread[i]);\n    }\n    delete[] fn_and_ids;\n    delete[] hThread;\n  }\n}\n\n#else  // not NO_THREADS, not !HAVE_PTHREAD, not _WIN32\n\n#include <pthread.h>\n\n#define SAFE_PTHREAD(fncall)  do { if ((fncall) != 0) abort(); } while (0)\n\nextern \"C\" {\n  // This helper function has the signature that pthread_create wants.\n  static void* RunFunctionInThread(void *ptr_to_ptr_to_fn) {\n    (**static_cast<void (**)()>(ptr_to_ptr_to_fn))();    // runs fn\n    return NULL;\n  }\n\n  static void* RunFunctionInThreadWithId(void *ptr_to_fnid) {\n    FunctionAndId* fn_and_id = static_cast<FunctionAndId*>(ptr_to_fnid);\n    (*fn_and_id->ptr_to_function)(fn_and_id->id);   // runs fn\n    return NULL;\n  }\n\n  // Run a function in a thread of its own and wait for it to finish.\n  // This is useful for tcmalloc testing, because each thread is\n  // handled separately in tcmalloc, so there's interesting stuff to\n  // test even if the threads are not running concurrently.\n  void RunThread(void (*fn)()) {\n    pthread_t thr;\n    // Even though fn is on the stack, it's safe to pass a pointer to it,\n    // because we pthread_join immediately (ie, before RunInThread exits).\n    SAFE_PTHREAD(pthread_create(&thr, NULL, RunFunctionInThread, &fn));\n    SAFE_PTHREAD(pthread_join(thr, NULL));\n  }\n\n  void RunManyThreads(void (*fn)(), int count) {\n    pthread_t* thr = new pthread_t[count];\n    for (int i = 0; i < count; i++) {\n      SAFE_PTHREAD(pthread_create(&thr[i], NULL, RunFunctionInThread, &fn));\n    }\n    for (int i = 0; i < count; i++) {\n      SAFE_PTHREAD(pthread_join(thr[i], NULL));\n    }\n    delete[] thr;\n  }\n\n  void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize) {\n    pthread_attr_t attr;\n    pthread_attr_init(&attr);\n    pthread_attr_setstacksize(&attr, stacksize);\n\n    pthread_t* thr = new pthread_t[count];\n    FunctionAndId* fn_and_ids = new FunctionAndId[count];\n    for (int i = 0; i < count; i++) {\n      fn_and_ids[i].ptr_to_function = fn;\n      fn_and_ids[i].id = i;\n      SAFE_PTHREAD(pthread_create(&thr[i], &attr,\n                                  RunFunctionInThreadWithId, &fn_and_ids[i]));\n    }\n    for (int i = 0; i < count; i++) {\n      SAFE_PTHREAD(pthread_join(thr[i], NULL));\n    }\n    delete[] fn_and_ids;\n    delete[] thr;\n\n    pthread_attr_destroy(&attr);\n  }\n}\n\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/testutil.h",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Craig Silverstein\n\n#ifndef TCMALLOC_TOOLS_TESTUTIL_H_\n#define TCMALLOC_TOOLS_TESTUTIL_H_\n\n// Run a function in a thread of its own and wait for it to finish.\n// The function you pass in must have the signature\n//    void MyFunction();\nextern \"C\" void RunThread(void (*fn)());\n\n// Run a function X times, in X threads, and wait for them all to finish.\n// The function you pass in must have the signature\n//    void MyFunction();\nextern \"C\" void RunManyThreads(void (*fn)(), int count);\n\n// The 'advanced' version: run a function X times, in X threads, and\n// wait for them all to finish.  Give them all the specified stack-size.\n// (If you're curious why this takes a stacksize and the others don't,\n// it's because the one client of this fn wanted to specify stacksize. :-) )\n// The function you pass in must have the signature\n//    void MyFunction(int idx);\n// where idx is the index of the thread (which of the X threads this is).\nextern \"C\" void RunManyThreadsWithId(void (*fn)(int), int count, int stacksize);\n\n// When compiled 64-bit and run on systems with swap several unittests will end\n// up trying to consume all of RAM+swap, and that can take quite some time.  By\n// limiting the address-space size we get sufficient coverage without blowing\n// out job limits.\nvoid SetTestResourceLimit();\n\n#endif  // TCMALLOC_TOOLS_TESTUTIL_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/tests/thread_dealloc_unittest.cc",
    "content": "// Copyright (c) 2004, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat\n//\n// Check that we do not leak memory when cycling through lots of threads.\n\n#include \"config_for_unittests.h\"\n#include <stdio.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>    // for sleep()\n#endif\n#include \"base/logging.h\"\n#include <google/malloc_extension.h>\n#include \"tests/testutil.h\"   // for RunThread()\n\n// Size/number of objects to allocate per thread (1 MB per thread)\nstatic const int kObjectSize = 1024;\nstatic const int kNumObjects = 1024;\n\n// Number of threads to create and destroy\nstatic const int kNumThreads = 1000;\n\n// Allocate lots of stuff\nstatic void AllocStuff() {\n  void** objects = new void*[kNumObjects];\n  for (int i = 0; i < kNumObjects; i++) {\n    objects[i] = malloc(kObjectSize);\n  }\n  for (int i = 0; i < kNumObjects; i++) {\n    free(objects[i]);\n  }\n  delete[] objects;\n}\n\nint main(int argc, char** argv) {\n  static const int kDisplaySize = 1048576;\n  char* display = new char[kDisplaySize];\n\n  for (int i = 0; i < kNumThreads; i++) {\n    RunThread(&AllocStuff);\n\n    if (((i+1) % 200) == 0) {\n      fprintf(stderr, \"Iteration: %d of %d\\n\", (i+1), kNumThreads);\n      MallocExtension::instance()->GetStats(display, kDisplaySize);\n      fprintf(stderr, \"%s\\n\", display);\n    }\n  }\n  delete[] display;\n\n  printf(\"PASS\\n\");\n#ifdef HAVE_UNISTD_H\n  sleep(1);     // Prevent exit race problem with glibc\n#endif\n  return 0;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/third_party/valgrind.h",
    "content": "/* -*- c -*-\n   ----------------------------------------------------------------\n\n   Notice that the following BSD-style license applies to this one\n   file (valgrind.h) only.  The rest of Valgrind is licensed under the\n   terms of the GNU General Public License, version 2, unless\n   otherwise indicated.  See the COPYING file in the source\n   distribution for details.\n\n   ----------------------------------------------------------------\n\n   This file is part of Valgrind, a dynamic binary instrumentation\n   framework.\n\n   Copyright (C) 2000-2008 Julian Seward.  All rights reserved.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n   1. Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n\n   2. The origin of this software must not be misrepresented; you must \n      not claim that you wrote the original software.  If you use this \n      software in a product, an acknowledgment in the product \n      documentation would be appreciated but is not required.\n\n   3. Altered source versions must be plainly marked as such, and must\n      not be misrepresented as being the original software.\n\n   4. The name of the author may not be used to endorse or promote \n      products derived from this software without specific prior written \n      permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n   ----------------------------------------------------------------\n\n   Notice that the above BSD-style license applies to this one file\n   (valgrind.h) only.  The entire rest of Valgrind is licensed under\n   the terms of the GNU General Public License, version 2.  See the\n   COPYING file in the source distribution for details.\n\n   ---------------------------------------------------------------- \n*/\n\n\n/* This file is for inclusion into client (your!) code.\n\n   You can use these macros to manipulate and query Valgrind's \n   execution inside your own programs.\n\n   The resulting executables will still run without Valgrind, just a\n   little bit more slowly than they otherwise would, but otherwise\n   unchanged.  When not running on valgrind, each client request\n   consumes very few (eg. 7) instructions, so the resulting performance\n   loss is negligible unless you plan to execute client requests\n   millions of times per second.  Nevertheless, if that is still a\n   problem, you can compile with the NVALGRIND symbol defined (gcc\n   -DNVALGRIND) so that client requests are not even compiled in.  */\n\n#ifndef __VALGRIND_H\n#define __VALGRIND_H\n\n#include <stdarg.h>\n\n/* Nb: this file might be included in a file compiled with -ansi.  So\n   we can't use C++ style \"//\" comments nor the \"asm\" keyword (instead\n   use \"__asm__\"). */\n\n/* Derive some tags indicating what the target platform is.  Note\n   that in this file we're using the compiler's CPP symbols for\n   identifying architectures, which are different to the ones we use\n   within the rest of Valgrind.  Note, __powerpc__ is active for both\n   32 and 64-bit PPC, whereas __powerpc64__ is only active for the\n   latter (on Linux, that is). */\n#undef PLAT_x86_linux\n#undef PLAT_amd64_linux\n#undef PLAT_ppc32_linux\n#undef PLAT_ppc64_linux\n#undef PLAT_ppc32_aix5\n#undef PLAT_ppc64_aix5\n\n#if !defined(_AIX) && defined(__i386__)\n#  define PLAT_x86_linux 1\n#elif !defined(_AIX) && defined(__x86_64__)\n#  define PLAT_amd64_linux 1\n#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)\n#  define PLAT_ppc32_linux 1\n#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)\n#  define PLAT_ppc64_linux 1\n#elif defined(_AIX) && defined(__64BIT__)\n#  define PLAT_ppc64_aix5 1\n#elif defined(_AIX) && !defined(__64BIT__)\n#  define PLAT_ppc32_aix5 1\n#endif\n\n\n/* If we're not compiling for our target platform, don't generate\n   any inline asms.  */\n#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \\\n    && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \\\n    && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)\n#  if !defined(NVALGRIND)\n#    define NVALGRIND 1\n#  endif\n#endif\n\n\n/* ------------------------------------------------------------------ */\n/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */\n/* in here of use to end-users -- skip to the next section.           */\n/* ------------------------------------------------------------------ */\n\n#if defined(NVALGRIND)\n\n/* Define NVALGRIND to completely remove the Valgrind magic sequence\n   from the compiled code (analogous to NDEBUG's effects on\n   assert()) */\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n   {                                                              \\\n      (_zzq_rlval) = (_zzq_default);                              \\\n   }\n\n#else  /* ! NVALGRIND */\n\n/* The following defines the magic code sequences which the JITter\n   spots and handles magically.  Don't look too closely at them as\n   they will rot your brain.\n\n   The assembly code sequences for all architectures is in this one\n   file.  This is because this file must be stand-alone, and we don't\n   want to have multiple files.\n\n   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default\n   value gets put in the return slot, so that everything works when\n   this is executed not under Valgrind.  Args are passed in a memory\n   block, and so there's no intrinsic limit to the number that could\n   be passed, but it's currently five.\n   \n   The macro args are: \n      _zzq_rlval    result lvalue\n      _zzq_default  default value (result returned when running on real CPU)\n      _zzq_request  request code\n      _zzq_arg1..5  request params\n\n   The other two macros are used to support function wrapping, and are\n   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the\n   guest's NRADDR pseudo-register and whatever other information is\n   needed to safely run the call original from the wrapper: on\n   ppc64-linux, the R2 value at the divert point is also needed.  This\n   information is abstracted into a user-visible type, OrigFn.\n\n   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the\n   guest, but guarantees that the branch instruction will not be\n   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:\n   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a\n   complete inline asm, since it needs to be combined with more magic\n   inline asm stuff to be useful.\n*/\n\n/* ------------------------- x86-linux ------------------------- */\n\n#if defined(PLAT_x86_linux)\n\ntypedef\n   struct { \n      unsigned int nraddr; /* where's the code? */\n   }\n   OrigFn;\n\n#define __SPECIAL_INSTRUCTION_PREAMBLE                            \\\n                     \"roll $3,  %%edi ; roll $13, %%edi\\n\\t\"      \\\n                     \"roll $29, %%edi ; roll $19, %%edi\\n\\t\"\n\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n  { volatile unsigned int _zzq_args[6];                           \\\n    volatile unsigned int _zzq_result;                            \\\n    _zzq_args[0] = (unsigned int)(_zzq_request);                  \\\n    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \\\n    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \\\n    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \\\n    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \\\n    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %EDX = client_request ( %EAX ) */         \\\n                     \"xchgl %%ebx,%%ebx\"                          \\\n                     : \"=d\" (_zzq_result)                         \\\n                     : \"a\" (&_zzq_args[0]), \"0\" (_zzq_default)    \\\n                     : \"cc\", \"memory\"                             \\\n                    );                                            \\\n    _zzq_rlval = _zzq_result;                                     \\\n  }\n\n#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \\\n  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \\\n    volatile unsigned int __addr;                                 \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %EAX = guest_NRADDR */                    \\\n                     \"xchgl %%ecx,%%ecx\"                          \\\n                     : \"=a\" (__addr)                              \\\n                     :                                            \\\n                     : \"cc\", \"memory\"                             \\\n                    );                                            \\\n    _zzq_orig->nraddr = __addr;                                   \\\n  }\n\n#define VALGRIND_CALL_NOREDIR_EAX                                 \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* call-noredir *%EAX */                     \\\n                     \"xchgl %%edx,%%edx\\n\\t\"\n#endif /* PLAT_x86_linux */\n\n/* ------------------------ amd64-linux ------------------------ */\n\n#if defined(PLAT_amd64_linux)\n\ntypedef\n   struct { \n      unsigned long long int nraddr; /* where's the code? */\n   }\n   OrigFn;\n\n#define __SPECIAL_INSTRUCTION_PREAMBLE                            \\\n                     \"rolq $3,  %%rdi ; rolq $13, %%rdi\\n\\t\"      \\\n                     \"rolq $61, %%rdi ; rolq $51, %%rdi\\n\\t\"\n\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n  { volatile unsigned long long int _zzq_args[6];                 \\\n    volatile unsigned long long int _zzq_result;                  \\\n    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \\\n    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \\\n    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \\\n    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \\\n    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \\\n    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %RDX = client_request ( %RAX ) */         \\\n                     \"xchgq %%rbx,%%rbx\"                          \\\n                     : \"=d\" (_zzq_result)                         \\\n                     : \"a\" (&_zzq_args[0]), \"0\" (_zzq_default)    \\\n                     : \"cc\", \"memory\"                             \\\n                    );                                            \\\n    _zzq_rlval = _zzq_result;                                     \\\n  }\n\n#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \\\n  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \\\n    volatile unsigned long long int __addr;                       \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %RAX = guest_NRADDR */                    \\\n                     \"xchgq %%rcx,%%rcx\"                          \\\n                     : \"=a\" (__addr)                              \\\n                     :                                            \\\n                     : \"cc\", \"memory\"                             \\\n                    );                                            \\\n    _zzq_orig->nraddr = __addr;                                   \\\n  }\n\n#define VALGRIND_CALL_NOREDIR_RAX                                 \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* call-noredir *%RAX */                     \\\n                     \"xchgq %%rdx,%%rdx\\n\\t\"\n#endif /* PLAT_amd64_linux */\n\n/* ------------------------ ppc32-linux ------------------------ */\n\n#if defined(PLAT_ppc32_linux)\n\ntypedef\n   struct { \n      unsigned int nraddr; /* where's the code? */\n   }\n   OrigFn;\n\n#define __SPECIAL_INSTRUCTION_PREAMBLE                            \\\n                     \"rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\\n\\t\"  \\\n                     \"rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\\n\\t\"\n\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n                                                                  \\\n  {          unsigned int  _zzq_args[6];                          \\\n             unsigned int  _zzq_result;                           \\\n             unsigned int* _zzq_ptr;                              \\\n    _zzq_args[0] = (unsigned int)(_zzq_request);                  \\\n    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \\\n    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \\\n    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \\\n    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \\\n    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \\\n    _zzq_ptr = _zzq_args;                                         \\\n    __asm__ volatile(\"mr 3,%1\\n\\t\" /*default*/                    \\\n                     \"mr 4,%2\\n\\t\" /*ptr*/                        \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = client_request ( %R4 ) */           \\\n                     \"or 1,1,1\\n\\t\"                               \\\n                     \"mr %0,3\"     /*result*/                     \\\n                     : \"=b\" (_zzq_result)                         \\\n                     : \"b\" (_zzq_default), \"b\" (_zzq_ptr)         \\\n                     : \"cc\", \"memory\", \"r3\", \"r4\");               \\\n    _zzq_rlval = _zzq_result;                                     \\\n  }\n\n#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \\\n  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \\\n    unsigned int __addr;                                          \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR */                     \\\n                     \"or 2,2,2\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (__addr)                              \\\n                     :                                            \\\n                     : \"cc\", \"memory\", \"r3\"                       \\\n                    );                                            \\\n    _zzq_orig->nraddr = __addr;                                   \\\n  }\n\n#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* branch-and-link-to-noredir *%R11 */       \\\n                     \"or 3,3,3\\n\\t\"\n#endif /* PLAT_ppc32_linux */\n\n/* ------------------------ ppc64-linux ------------------------ */\n\n#if defined(PLAT_ppc64_linux)\n\ntypedef\n   struct { \n      unsigned long long int nraddr; /* where's the code? */\n      unsigned long long int r2;  /* what tocptr do we need? */\n   }\n   OrigFn;\n\n#define __SPECIAL_INSTRUCTION_PREAMBLE                            \\\n                     \"rotldi 0,0,3  ; rotldi 0,0,13\\n\\t\"          \\\n                     \"rotldi 0,0,61 ; rotldi 0,0,51\\n\\t\"\n\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n                                                                  \\\n  {          unsigned long long int  _zzq_args[6];                \\\n    register unsigned long long int  _zzq_result __asm__(\"r3\");   \\\n    register unsigned long long int* _zzq_ptr __asm__(\"r4\");      \\\n    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \\\n    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \\\n    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \\\n    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \\\n    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \\\n    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \\\n    _zzq_ptr = _zzq_args;                                         \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = client_request ( %R4 ) */           \\\n                     \"or 1,1,1\"                                   \\\n                     : \"=r\" (_zzq_result)                         \\\n                     : \"0\" (_zzq_default), \"r\" (_zzq_ptr)         \\\n                     : \"cc\", \"memory\");                           \\\n    _zzq_rlval = _zzq_result;                                     \\\n  }\n\n#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \\\n  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \\\n    register unsigned long long int __addr __asm__(\"r3\");         \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR */                     \\\n                     \"or 2,2,2\"                                   \\\n                     : \"=r\" (__addr)                              \\\n                     :                                            \\\n                     : \"cc\", \"memory\"                             \\\n                    );                                            \\\n    _zzq_orig->nraddr = __addr;                                   \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR_GPR2 */                \\\n                     \"or 4,4,4\"                                   \\\n                     : \"=r\" (__addr)                              \\\n                     :                                            \\\n                     : \"cc\", \"memory\"                             \\\n                    );                                            \\\n    _zzq_orig->r2 = __addr;                                       \\\n  }\n\n#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* branch-and-link-to-noredir *%R11 */       \\\n                     \"or 3,3,3\\n\\t\"\n\n#endif /* PLAT_ppc64_linux */\n\n/* ------------------------ ppc32-aix5 ------------------------- */\n\n#if defined(PLAT_ppc32_aix5)\n\ntypedef\n   struct { \n      unsigned int nraddr; /* where's the code? */\n      unsigned int r2;  /* what tocptr do we need? */\n   }\n   OrigFn;\n\n#define __SPECIAL_INSTRUCTION_PREAMBLE                            \\\n                     \"rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\\n\\t\"  \\\n                     \"rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\\n\\t\"\n\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n                                                                  \\\n  {          unsigned int  _zzq_args[7];                          \\\n    register unsigned int  _zzq_result;                           \\\n    register unsigned int* _zzq_ptr;                              \\\n    _zzq_args[0] = (unsigned int)(_zzq_request);                  \\\n    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \\\n    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \\\n    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \\\n    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \\\n    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \\\n    _zzq_args[6] = (unsigned int)(_zzq_default);                  \\\n    _zzq_ptr = _zzq_args;                                         \\\n    __asm__ volatile(\"mr 4,%1\\n\\t\"                                \\\n                     \"lwz 3, 24(4)\\n\\t\"                           \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = client_request ( %R4 ) */           \\\n                     \"or 1,1,1\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (_zzq_result)                         \\\n                     : \"b\" (_zzq_ptr)                             \\\n                     : \"r3\", \"r4\", \"cc\", \"memory\");               \\\n    _zzq_rlval = _zzq_result;                                     \\\n  }\n\n#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \\\n  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \\\n    register unsigned int __addr;                                 \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR */                     \\\n                     \"or 2,2,2\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (__addr)                              \\\n                     :                                            \\\n                     : \"r3\", \"cc\", \"memory\"                       \\\n                    );                                            \\\n    _zzq_orig->nraddr = __addr;                                   \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR_GPR2 */                \\\n                     \"or 4,4,4\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (__addr)                              \\\n                     :                                            \\\n                     : \"r3\", \"cc\", \"memory\"                       \\\n                    );                                            \\\n    _zzq_orig->r2 = __addr;                                       \\\n  }\n\n#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* branch-and-link-to-noredir *%R11 */       \\\n                     \"or 3,3,3\\n\\t\"\n\n#endif /* PLAT_ppc32_aix5 */\n\n/* ------------------------ ppc64-aix5 ------------------------- */\n\n#if defined(PLAT_ppc64_aix5)\n\ntypedef\n   struct { \n      unsigned long long int nraddr; /* where's the code? */\n      unsigned long long int r2;  /* what tocptr do we need? */\n   }\n   OrigFn;\n\n#define __SPECIAL_INSTRUCTION_PREAMBLE                            \\\n                     \"rotldi 0,0,3  ; rotldi 0,0,13\\n\\t\"          \\\n                     \"rotldi 0,0,61 ; rotldi 0,0,51\\n\\t\"\n\n#define VALGRIND_DO_CLIENT_REQUEST(                               \\\n        _zzq_rlval, _zzq_default, _zzq_request,                   \\\n        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \\\n                                                                  \\\n  {          unsigned long long int  _zzq_args[7];                \\\n    register unsigned long long int  _zzq_result;                 \\\n    register unsigned long long int* _zzq_ptr;                    \\\n    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \\\n    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \\\n    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \\\n    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \\\n    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \\\n    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \\\n    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \\\n    _zzq_ptr = _zzq_args;                                         \\\n    __asm__ volatile(\"mr 4,%1\\n\\t\"                                \\\n                     \"ld 3, 48(4)\\n\\t\"                            \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = client_request ( %R4 ) */           \\\n                     \"or 1,1,1\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (_zzq_result)                         \\\n                     : \"b\" (_zzq_ptr)                             \\\n                     : \"r3\", \"r4\", \"cc\", \"memory\");               \\\n    _zzq_rlval = _zzq_result;                                     \\\n  }\n\n#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \\\n  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \\\n    register unsigned long long int __addr;                       \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR */                     \\\n                     \"or 2,2,2\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (__addr)                              \\\n                     :                                            \\\n                     : \"r3\", \"cc\", \"memory\"                       \\\n                    );                                            \\\n    _zzq_orig->nraddr = __addr;                                   \\\n    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* %R3 = guest_NRADDR_GPR2 */                \\\n                     \"or 4,4,4\\n\\t\"                               \\\n                     \"mr %0,3\"                                    \\\n                     : \"=b\" (__addr)                              \\\n                     :                                            \\\n                     : \"r3\", \"cc\", \"memory\"                       \\\n                    );                                            \\\n    _zzq_orig->r2 = __addr;                                       \\\n  }\n\n#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \\\n                     __SPECIAL_INSTRUCTION_PREAMBLE               \\\n                     /* branch-and-link-to-noredir *%R11 */       \\\n                     \"or 3,3,3\\n\\t\"\n\n#endif /* PLAT_ppc64_aix5 */\n\n/* Insert assembly code for other platforms here... */\n\n#endif /* NVALGRIND */\n\n\n/* ------------------------------------------------------------------ */\n/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */\n/* ugly.  It's the least-worst tradeoff I can think of.               */\n/* ------------------------------------------------------------------ */\n\n/* This section defines magic (a.k.a appalling-hack) macros for doing\n   guaranteed-no-redirection macros, so as to get from function\n   wrappers to the functions they are wrapping.  The whole point is to\n   construct standard call sequences, but to do the call itself with a\n   special no-redirect call pseudo-instruction that the JIT\n   understands and handles specially.  This section is long and\n   repetitious, and I can't see a way to make it shorter.\n\n   The naming scheme is as follows:\n\n      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}\n\n   'W' stands for \"word\" and 'v' for \"void\".  Hence there are\n   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,\n   and for each, the possibility of returning a word-typed result, or\n   no result.\n*/\n\n/* Use these to write the name of your wrapper.  NOTE: duplicates\n   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */\n\n#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \\\n   _vgwZU_##soname##_##fnname\n\n#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \\\n   _vgwZZ_##soname##_##fnname\n\n/* Use this macro from within a wrapper function to collect the\n   context (address and possibly other info) of the original function.\n   Once you have that you can then use it in one of the CALL_FN_\n   macros.  The type of the argument _lval is OrigFn. */\n#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)\n\n/* Derivatives of the main macros below, for calling functions\n   returning void. */\n\n#define CALL_FN_v_v(fnptr)                                        \\\n   do { volatile unsigned long _junk;                             \\\n        CALL_FN_W_v(_junk,fnptr); } while (0)\n\n#define CALL_FN_v_W(fnptr, arg1)                                  \\\n   do { volatile unsigned long _junk;                             \\\n        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)\n\n#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \\\n   do { volatile unsigned long _junk;                             \\\n        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)\n\n#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \\\n   do { volatile unsigned long _junk;                             \\\n        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)\n\n/* ------------------------- x86-linux ------------------------- */\n\n#if defined(PLAT_x86_linux)\n\n/* These regs are trashed by the hidden call.  No need to mention eax\n   as gcc can already see that, plus causes gcc to bomb. */\n#define __CALLER_SAVED_REGS /*\"eax\"*/ \"ecx\", \"edx\"\n\n/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned\n   long) == 4. */\n\n#define CALL_FN_W_v(lval, orig)                                   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[1];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      __asm__ volatile(                                           \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_W(lval, orig, arg1)                             \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[2];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $4, %%esp\\n\"                                       \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $8, %%esp\\n\"                                       \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[4];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $12, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[5];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $16, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[6];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $20, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[7];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $24, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7)                            \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[8];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 28(%%eax)\\n\\t\"                                    \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $28, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[9];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 32(%%eax)\\n\\t\"                                    \\\n         \"pushl 28(%%eax)\\n\\t\"                                    \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $32, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8,arg9)                  \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[10];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      __asm__ volatile(                                           \\\n         \"pushl 36(%%eax)\\n\\t\"                                    \\\n         \"pushl 32(%%eax)\\n\\t\"                                    \\\n         \"pushl 28(%%eax)\\n\\t\"                                    \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $36, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[11];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      _argvec[10] = (unsigned long)(arg10);                       \\\n      __asm__ volatile(                                           \\\n         \"pushl 40(%%eax)\\n\\t\"                                    \\\n         \"pushl 36(%%eax)\\n\\t\"                                    \\\n         \"pushl 32(%%eax)\\n\\t\"                                    \\\n         \"pushl 28(%%eax)\\n\\t\"                                    \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $40, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \\\n                                  arg6,arg7,arg8,arg9,arg10,      \\\n                                  arg11)                          \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[12];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      _argvec[10] = (unsigned long)(arg10);                       \\\n      _argvec[11] = (unsigned long)(arg11);                       \\\n      __asm__ volatile(                                           \\\n         \"pushl 44(%%eax)\\n\\t\"                                    \\\n         \"pushl 40(%%eax)\\n\\t\"                                    \\\n         \"pushl 36(%%eax)\\n\\t\"                                    \\\n         \"pushl 32(%%eax)\\n\\t\"                                    \\\n         \"pushl 28(%%eax)\\n\\t\"                                    \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $44, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \\\n                                  arg6,arg7,arg8,arg9,arg10,      \\\n                                  arg11,arg12)                    \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[13];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      _argvec[10] = (unsigned long)(arg10);                       \\\n      _argvec[11] = (unsigned long)(arg11);                       \\\n      _argvec[12] = (unsigned long)(arg12);                       \\\n      __asm__ volatile(                                           \\\n         \"pushl 48(%%eax)\\n\\t\"                                    \\\n         \"pushl 44(%%eax)\\n\\t\"                                    \\\n         \"pushl 40(%%eax)\\n\\t\"                                    \\\n         \"pushl 36(%%eax)\\n\\t\"                                    \\\n         \"pushl 32(%%eax)\\n\\t\"                                    \\\n         \"pushl 28(%%eax)\\n\\t\"                                    \\\n         \"pushl 24(%%eax)\\n\\t\"                                    \\\n         \"pushl 20(%%eax)\\n\\t\"                                    \\\n         \"pushl 16(%%eax)\\n\\t\"                                    \\\n         \"pushl 12(%%eax)\\n\\t\"                                    \\\n         \"pushl 8(%%eax)\\n\\t\"                                     \\\n         \"pushl 4(%%eax)\\n\\t\"                                     \\\n         \"movl (%%eax), %%eax\\n\\t\"  /* target->%eax */            \\\n         VALGRIND_CALL_NOREDIR_EAX                                \\\n         \"addl $48, %%esp\\n\"                                      \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#endif /* PLAT_x86_linux */\n\n/* ------------------------ amd64-linux ------------------------ */\n\n#if defined(PLAT_amd64_linux)\n\n/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */\n\n/* These regs are trashed by the hidden call. */\n#define __CALLER_SAVED_REGS /*\"rax\",*/ \"rcx\", \"rdx\", \"rsi\",       \\\n                            \"rdi\", \"r8\", \"r9\", \"r10\", \"r11\"\n\n/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned\n   long) == 8. */\n\n/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_\n   macros.  In order not to trash the stack redzone, we need to drop\n   %rsp by 128 before the hidden call, and restore afterwards.  The\n   nastyness is that it is only by luck that the stack still appears\n   to be unwindable during the hidden call - since then the behaviour\n   of any routine using this macro does not match what the CFI data\n   says.  Sigh.\n\n   Why is this important?  Imagine that a wrapper has a stack\n   allocated local, and passes to the hidden call, a pointer to it.\n   Because gcc does not know about the hidden call, it may allocate\n   that local in the redzone.  Unfortunately the hidden call may then\n   trash it before it comes to use it.  So we must step clear of the\n   redzone, for the duration of the hidden call, to make it safe.\n\n   Probably the same problem afflicts the other redzone-style ABIs too\n   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is\n   self describing (none of this CFI nonsense) so at least messing\n   with the stack pointer doesn't give a danger of non-unwindable\n   stack. */\n\n#define CALL_FN_W_v(lval, orig)                                   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[1];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_W(lval, orig, arg1)                             \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[2];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[4];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[5];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[6];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[7];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7)                            \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[8];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"pushq 56(%%rax)\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $8, %%rsp\\n\"                                       \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[9];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"pushq 64(%%rax)\\n\\t\"                                    \\\n         \"pushq 56(%%rax)\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $16, %%rsp\\n\"                                      \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8,arg9)                  \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[10];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"pushq 72(%%rax)\\n\\t\"                                    \\\n         \"pushq 64(%%rax)\\n\\t\"                                    \\\n         \"pushq 56(%%rax)\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $24, %%rsp\\n\"                                      \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[11];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      _argvec[10] = (unsigned long)(arg10);                       \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"pushq 80(%%rax)\\n\\t\"                                    \\\n         \"pushq 72(%%rax)\\n\\t\"                                    \\\n         \"pushq 64(%%rax)\\n\\t\"                                    \\\n         \"pushq 56(%%rax)\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $32, %%rsp\\n\"                                      \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10,arg11)     \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[12];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      _argvec[10] = (unsigned long)(arg10);                       \\\n      _argvec[11] = (unsigned long)(arg11);                       \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"pushq 88(%%rax)\\n\\t\"                                    \\\n         \"pushq 80(%%rax)\\n\\t\"                                    \\\n         \"pushq 72(%%rax)\\n\\t\"                                    \\\n         \"pushq 64(%%rax)\\n\\t\"                                    \\\n         \"pushq 56(%%rax)\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $40, %%rsp\\n\"                                      \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                arg7,arg8,arg9,arg10,arg11,arg12) \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[13];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)(arg1);                         \\\n      _argvec[2] = (unsigned long)(arg2);                         \\\n      _argvec[3] = (unsigned long)(arg3);                         \\\n      _argvec[4] = (unsigned long)(arg4);                         \\\n      _argvec[5] = (unsigned long)(arg5);                         \\\n      _argvec[6] = (unsigned long)(arg6);                         \\\n      _argvec[7] = (unsigned long)(arg7);                         \\\n      _argvec[8] = (unsigned long)(arg8);                         \\\n      _argvec[9] = (unsigned long)(arg9);                         \\\n      _argvec[10] = (unsigned long)(arg10);                       \\\n      _argvec[11] = (unsigned long)(arg11);                       \\\n      _argvec[12] = (unsigned long)(arg12);                       \\\n      __asm__ volatile(                                           \\\n         \"subq $128,%%rsp\\n\\t\"                                    \\\n         \"pushq 96(%%rax)\\n\\t\"                                    \\\n         \"pushq 88(%%rax)\\n\\t\"                                    \\\n         \"pushq 80(%%rax)\\n\\t\"                                    \\\n         \"pushq 72(%%rax)\\n\\t\"                                    \\\n         \"pushq 64(%%rax)\\n\\t\"                                    \\\n         \"pushq 56(%%rax)\\n\\t\"                                    \\\n         \"movq 48(%%rax), %%r9\\n\\t\"                               \\\n         \"movq 40(%%rax), %%r8\\n\\t\"                               \\\n         \"movq 32(%%rax), %%rcx\\n\\t\"                              \\\n         \"movq 24(%%rax), %%rdx\\n\\t\"                              \\\n         \"movq 16(%%rax), %%rsi\\n\\t\"                              \\\n         \"movq 8(%%rax), %%rdi\\n\\t\"                               \\\n         \"movq (%%rax), %%rax\\n\\t\"  /* target->%rax */            \\\n         VALGRIND_CALL_NOREDIR_RAX                                \\\n         \"addq $48, %%rsp\\n\"                                      \\\n         \"addq $128,%%rsp\\n\\t\"                                    \\\n         : /*out*/   \"=a\" (_res)                                  \\\n         : /*in*/    \"a\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#endif /* PLAT_amd64_linux */\n\n/* ------------------------ ppc32-linux ------------------------ */\n\n#if defined(PLAT_ppc32_linux)\n\n/* This is useful for finding out about the on-stack stuff:\n\n   extern int f9  ( int,int,int,int,int,int,int,int,int );\n   extern int f10 ( int,int,int,int,int,int,int,int,int,int );\n   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );\n   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );\n\n   int g9 ( void ) {\n      return f9(11,22,33,44,55,66,77,88,99);\n   }\n   int g10 ( void ) {\n      return f10(11,22,33,44,55,66,77,88,99,110);\n   }\n   int g11 ( void ) {\n      return f11(11,22,33,44,55,66,77,88,99,110,121);\n   }\n   int g12 ( void ) {\n      return f12(11,22,33,44,55,66,77,88,99,110,121,132);\n   }\n*/\n\n/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */\n\n/* These regs are trashed by the hidden call. */\n#define __CALLER_SAVED_REGS                                       \\\n   \"lr\", \"ctr\", \"xer\",                                            \\\n   \"cr0\", \"cr1\", \"cr2\", \"cr3\", \"cr4\", \"cr5\", \"cr6\", \"cr7\",        \\\n   \"r0\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\",   \\\n   \"r11\", \"r12\", \"r13\"\n\n/* These CALL_FN_ macros assume that on ppc32-linux, \n   sizeof(unsigned long) == 4. */\n\n#define CALL_FN_W_v(lval, orig)                                   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[1];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_W(lval, orig, arg1)                             \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[2];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[4];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[5];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[6];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[7];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7)                            \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[8];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      _argvec[7] = (unsigned long)arg7;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 9,28(11)\\n\\t\"                                       \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[9];                          \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      _argvec[7] = (unsigned long)arg7;                           \\\n      _argvec[8] = (unsigned long)arg8;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 9,28(11)\\n\\t\"                                       \\\n         \"lwz 10,32(11)\\n\\t\" /* arg8->r10 */                      \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8,arg9)                  \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[10];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      _argvec[7] = (unsigned long)arg7;                           \\\n      _argvec[8] = (unsigned long)arg8;                           \\\n      _argvec[9] = (unsigned long)arg9;                           \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"addi 1,1,-16\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,8(1)\\n\\t\"                                         \\\n         /* args1-8 */                                            \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 9,28(11)\\n\\t\"                                       \\\n         \"lwz 10,32(11)\\n\\t\" /* arg8->r10 */                      \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"addi 1,1,16\\n\\t\"                                        \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[11];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      _argvec[7] = (unsigned long)arg7;                           \\\n      _argvec[8] = (unsigned long)arg8;                           \\\n      _argvec[9] = (unsigned long)arg9;                           \\\n      _argvec[10] = (unsigned long)arg10;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"addi 1,1,-16\\n\\t\"                                       \\\n         /* arg10 */                                              \\\n         \"lwz 3,40(11)\\n\\t\"                                       \\\n         \"stw 3,12(1)\\n\\t\"                                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,8(1)\\n\\t\"                                         \\\n         /* args1-8 */                                            \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 9,28(11)\\n\\t\"                                       \\\n         \"lwz 10,32(11)\\n\\t\" /* arg8->r10 */                      \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"addi 1,1,16\\n\\t\"                                        \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10,arg11)     \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[12];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      _argvec[7] = (unsigned long)arg7;                           \\\n      _argvec[8] = (unsigned long)arg8;                           \\\n      _argvec[9] = (unsigned long)arg9;                           \\\n      _argvec[10] = (unsigned long)arg10;                         \\\n      _argvec[11] = (unsigned long)arg11;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"addi 1,1,-32\\n\\t\"                                       \\\n         /* arg11 */                                              \\\n         \"lwz 3,44(11)\\n\\t\"                                       \\\n         \"stw 3,16(1)\\n\\t\"                                        \\\n         /* arg10 */                                              \\\n         \"lwz 3,40(11)\\n\\t\"                                       \\\n         \"stw 3,12(1)\\n\\t\"                                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,8(1)\\n\\t\"                                         \\\n         /* args1-8 */                                            \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 9,28(11)\\n\\t\"                                       \\\n         \"lwz 10,32(11)\\n\\t\" /* arg8->r10 */                      \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"addi 1,1,32\\n\\t\"                                        \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                arg7,arg8,arg9,arg10,arg11,arg12) \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[13];                         \\\n      volatile unsigned long _res;                                \\\n      _argvec[0] = (unsigned long)_orig.nraddr;                   \\\n      _argvec[1] = (unsigned long)arg1;                           \\\n      _argvec[2] = (unsigned long)arg2;                           \\\n      _argvec[3] = (unsigned long)arg3;                           \\\n      _argvec[4] = (unsigned long)arg4;                           \\\n      _argvec[5] = (unsigned long)arg5;                           \\\n      _argvec[6] = (unsigned long)arg6;                           \\\n      _argvec[7] = (unsigned long)arg7;                           \\\n      _argvec[8] = (unsigned long)arg8;                           \\\n      _argvec[9] = (unsigned long)arg9;                           \\\n      _argvec[10] = (unsigned long)arg10;                         \\\n      _argvec[11] = (unsigned long)arg11;                         \\\n      _argvec[12] = (unsigned long)arg12;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"addi 1,1,-32\\n\\t\"                                       \\\n         /* arg12 */                                              \\\n         \"lwz 3,48(11)\\n\\t\"                                       \\\n         \"stw 3,20(1)\\n\\t\"                                        \\\n         /* arg11 */                                              \\\n         \"lwz 3,44(11)\\n\\t\"                                       \\\n         \"stw 3,16(1)\\n\\t\"                                        \\\n         /* arg10 */                                              \\\n         \"lwz 3,40(11)\\n\\t\"                                       \\\n         \"stw 3,12(1)\\n\\t\"                                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,8(1)\\n\\t\"                                         \\\n         /* args1-8 */                                            \\\n         \"lwz 3,4(11)\\n\\t\"   /* arg1->r3 */                       \\\n         \"lwz 4,8(11)\\n\\t\"                                        \\\n         \"lwz 5,12(11)\\n\\t\"                                       \\\n         \"lwz 6,16(11)\\n\\t\"  /* arg4->r6 */                       \\\n         \"lwz 7,20(11)\\n\\t\"                                       \\\n         \"lwz 8,24(11)\\n\\t\"                                       \\\n         \"lwz 9,28(11)\\n\\t\"                                       \\\n         \"lwz 10,32(11)\\n\\t\" /* arg8->r10 */                      \\\n         \"lwz 11,0(11)\\n\\t\"  /* target->r11 */                    \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"addi 1,1,32\\n\\t\"                                        \\\n         \"mr %0,3\"                                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[0])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#endif /* PLAT_ppc32_linux */\n\n/* ------------------------ ppc64-linux ------------------------ */\n\n#if defined(PLAT_ppc64_linux)\n\n/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */\n\n/* These regs are trashed by the hidden call. */\n#define __CALLER_SAVED_REGS                                       \\\n   \"lr\", \"ctr\", \"xer\",                                            \\\n   \"cr0\", \"cr1\", \"cr2\", \"cr3\", \"cr4\", \"cr5\", \"cr6\", \"cr7\",        \\\n   \"r0\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\",   \\\n   \"r11\", \"r12\", \"r13\"\n\n/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned\n   long) == 8. */\n\n#define CALL_FN_W_v(lval, orig)                                   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+0];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1] = (unsigned long)_orig.r2;                       \\\n      _argvec[2] = (unsigned long)_orig.nraddr;                   \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_W(lval, orig, arg1)                             \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+1];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+2];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+3];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+4];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+5];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+6];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7)                            \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+7];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+8];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\" /* restore tocptr */                      \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8,arg9)                  \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+9];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"addi 1,1,-128\\n\\t\"  /* expand stack frame */            \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\\n\\t\" /* restore tocptr */                  \\\n         \"addi 1,1,128\"     /* restore frame */                   \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+10];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"addi 1,1,-128\\n\\t\"  /* expand stack frame */            \\\n         /* arg10 */                                              \\\n         \"ld  3,80(11)\\n\\t\"                                       \\\n         \"std 3,120(1)\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\\n\\t\" /* restore tocptr */                  \\\n         \"addi 1,1,128\"     /* restore frame */                   \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10,arg11)     \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+11];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      _argvec[2+11] = (unsigned long)arg11;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"addi 1,1,-144\\n\\t\"  /* expand stack frame */            \\\n         /* arg11 */                                              \\\n         \"ld  3,88(11)\\n\\t\"                                       \\\n         \"std 3,128(1)\\n\\t\"                                       \\\n         /* arg10 */                                              \\\n         \"ld  3,80(11)\\n\\t\"                                       \\\n         \"std 3,120(1)\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\\n\\t\" /* restore tocptr */                  \\\n         \"addi 1,1,144\"     /* restore frame */                   \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                arg7,arg8,arg9,arg10,arg11,arg12) \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+12];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      _argvec[2+11] = (unsigned long)arg11;                       \\\n      _argvec[2+12] = (unsigned long)arg12;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"std 2,-16(11)\\n\\t\"  /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"addi 1,1,-144\\n\\t\"  /* expand stack frame */            \\\n         /* arg12 */                                              \\\n         \"ld  3,96(11)\\n\\t\"                                       \\\n         \"std 3,136(1)\\n\\t\"                                       \\\n         /* arg11 */                                              \\\n         \"ld  3,88(11)\\n\\t\"                                       \\\n         \"std 3,128(1)\\n\\t\"                                       \\\n         /* arg10 */                                              \\\n         \"ld  3,80(11)\\n\\t\"                                       \\\n         \"std 3,120(1)\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\\n\\t\" /* restore tocptr */                  \\\n         \"addi 1,1,144\"     /* restore frame */                   \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#endif /* PLAT_ppc64_linux */\n\n/* ------------------------ ppc32-aix5 ------------------------- */\n\n#if defined(PLAT_ppc32_aix5)\n\n/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */\n\n/* These regs are trashed by the hidden call. */\n#define __CALLER_SAVED_REGS                                       \\\n   \"lr\", \"ctr\", \"xer\",                                            \\\n   \"cr0\", \"cr1\", \"cr2\", \"cr3\", \"cr4\", \"cr5\", \"cr6\", \"cr7\",        \\\n   \"r0\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\",   \\\n   \"r11\", \"r12\", \"r13\"\n\n/* Expand the stack frame, copying enough info that unwinding\n   still works.  Trashes r3. */\n\n#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \\\n         \"addi 1,1,-\" #_n_fr \"\\n\\t\"                               \\\n         \"lwz  3,\" #_n_fr \"(1)\\n\\t\"                               \\\n         \"stw  3,0(1)\\n\\t\"\n\n#define VG_CONTRACT_FRAME_BY(_n_fr)                               \\\n         \"addi 1,1,\" #_n_fr \"\\n\\t\"\n\n/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned\n   long) == 4. */\n\n#define CALL_FN_W_v(lval, orig)                                   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+0];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1] = (unsigned long)_orig.r2;                       \\\n      _argvec[2] = (unsigned long)_orig.nraddr;                   \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_W(lval, orig, arg1)                             \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+1];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+2];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+3];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+4];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+5];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\" /* arg2->r4 */                       \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+6];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7)                            \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+7];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz  9, 28(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+8];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz  9, 28(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"lwz 10, 32(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8,arg9)                  \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+9];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,56(1)\\n\\t\"                                        \\\n         /* args1-8 */                                            \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz  9, 28(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"lwz 10, 32(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(64)                                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+10];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \\\n         /* arg10 */                                              \\\n         \"lwz 3,40(11)\\n\\t\"                                       \\\n         \"stw 3,60(1)\\n\\t\"                                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,56(1)\\n\\t\"                                        \\\n         /* args1-8 */                                            \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz  9, 28(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"lwz 10, 32(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(64)                                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10,arg11)     \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+11];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      _argvec[2+11] = (unsigned long)arg11;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \\\n         /* arg11 */                                              \\\n         \"lwz 3,44(11)\\n\\t\"                                       \\\n         \"stw 3,64(1)\\n\\t\"                                        \\\n         /* arg10 */                                              \\\n         \"lwz 3,40(11)\\n\\t\"                                       \\\n         \"stw 3,60(1)\\n\\t\"                                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,56(1)\\n\\t\"                                        \\\n         /* args1-8 */                                            \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz  9, 28(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"lwz 10, 32(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(72)                                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                arg7,arg8,arg9,arg10,arg11,arg12) \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+12];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      _argvec[2+11] = (unsigned long)arg11;                       \\\n      _argvec[2+12] = (unsigned long)arg12;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"stw  2,-8(11)\\n\\t\"  /* save tocptr */                   \\\n         \"lwz  2,-4(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \\\n         /* arg12 */                                              \\\n         \"lwz 3,48(11)\\n\\t\"                                       \\\n         \"stw 3,68(1)\\n\\t\"                                        \\\n         /* arg11 */                                              \\\n         \"lwz 3,44(11)\\n\\t\"                                       \\\n         \"stw 3,64(1)\\n\\t\"                                        \\\n         /* arg10 */                                              \\\n         \"lwz 3,40(11)\\n\\t\"                                       \\\n         \"stw 3,60(1)\\n\\t\"                                        \\\n         /* arg9 */                                               \\\n         \"lwz 3,36(11)\\n\\t\"                                       \\\n         \"stw 3,56(1)\\n\\t\"                                        \\\n         /* args1-8 */                                            \\\n         \"lwz  3, 4(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"lwz  4, 8(11)\\n\\t\"  /* arg2->r4 */                      \\\n         \"lwz  5, 12(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"lwz  6, 16(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"lwz  7, 20(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"lwz  8, 24(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"lwz  9, 28(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"lwz 10, 32(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"lwz 11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"lwz 2,-8(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(72)                                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#endif /* PLAT_ppc32_aix5 */\n\n/* ------------------------ ppc64-aix5 ------------------------- */\n\n#if defined(PLAT_ppc64_aix5)\n\n/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */\n\n/* These regs are trashed by the hidden call. */\n#define __CALLER_SAVED_REGS                                       \\\n   \"lr\", \"ctr\", \"xer\",                                            \\\n   \"cr0\", \"cr1\", \"cr2\", \"cr3\", \"cr4\", \"cr5\", \"cr6\", \"cr7\",        \\\n   \"r0\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\", \"r9\", \"r10\",   \\\n   \"r11\", \"r12\", \"r13\"\n\n/* Expand the stack frame, copying enough info that unwinding\n   still works.  Trashes r3. */\n\n#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \\\n         \"addi 1,1,-\" #_n_fr \"\\n\\t\"                               \\\n         \"ld   3,\" #_n_fr \"(1)\\n\\t\"                               \\\n         \"std  3,0(1)\\n\\t\"\n\n#define VG_CONTRACT_FRAME_BY(_n_fr)                               \\\n         \"addi 1,1,\" #_n_fr \"\\n\\t\"\n\n/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned\n   long) == 8. */\n\n#define CALL_FN_W_v(lval, orig)                                   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+0];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1] = (unsigned long)_orig.r2;                       \\\n      _argvec[2] = (unsigned long)_orig.nraddr;                   \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_W(lval, orig, arg1)                             \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+1];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld 2,-16(11)\\n\\t\" /* restore tocptr */                  \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+2];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+3];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+4];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+5];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+6];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7)                            \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+7];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8)                       \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+8];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \\\n                                 arg7,arg8,arg9)                  \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+9];                        \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(128)                                \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10)           \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+10];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \\\n         /* arg10 */                                              \\\n         \"ld  3,80(11)\\n\\t\"                                       \\\n         \"std 3,120(1)\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(128)                                \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                  arg7,arg8,arg9,arg10,arg11)     \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+11];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      _argvec[2+11] = (unsigned long)arg11;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \\\n         /* arg11 */                                              \\\n         \"ld  3,88(11)\\n\\t\"                                       \\\n         \"std 3,128(1)\\n\\t\"                                       \\\n         /* arg10 */                                              \\\n         \"ld  3,80(11)\\n\\t\"                                       \\\n         \"std 3,120(1)\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(144)                                \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \\\n                                arg7,arg8,arg9,arg10,arg11,arg12) \\\n   do {                                                           \\\n      volatile OrigFn        _orig = (orig);                      \\\n      volatile unsigned long _argvec[3+12];                       \\\n      volatile unsigned long _res;                                \\\n      /* _argvec[0] holds current r2 across the call */           \\\n      _argvec[1]   = (unsigned long)_orig.r2;                     \\\n      _argvec[2]   = (unsigned long)_orig.nraddr;                 \\\n      _argvec[2+1] = (unsigned long)arg1;                         \\\n      _argvec[2+2] = (unsigned long)arg2;                         \\\n      _argvec[2+3] = (unsigned long)arg3;                         \\\n      _argvec[2+4] = (unsigned long)arg4;                         \\\n      _argvec[2+5] = (unsigned long)arg5;                         \\\n      _argvec[2+6] = (unsigned long)arg6;                         \\\n      _argvec[2+7] = (unsigned long)arg7;                         \\\n      _argvec[2+8] = (unsigned long)arg8;                         \\\n      _argvec[2+9] = (unsigned long)arg9;                         \\\n      _argvec[2+10] = (unsigned long)arg10;                       \\\n      _argvec[2+11] = (unsigned long)arg11;                       \\\n      _argvec[2+12] = (unsigned long)arg12;                       \\\n      __asm__ volatile(                                           \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \\\n         \"std  2,-16(11)\\n\\t\" /* save tocptr */                   \\\n         \"ld   2,-8(11)\\n\\t\"  /* use nraddr's tocptr */           \\\n         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \\\n         /* arg12 */                                              \\\n         \"ld  3,96(11)\\n\\t\"                                       \\\n         \"std 3,136(1)\\n\\t\"                                       \\\n         /* arg11 */                                              \\\n         \"ld  3,88(11)\\n\\t\"                                       \\\n         \"std 3,128(1)\\n\\t\"                                       \\\n         /* arg10 */                                              \\\n         \"ld  3,80(11)\\n\\t\"                                       \\\n         \"std 3,120(1)\\n\\t\"                                       \\\n         /* arg9 */                                               \\\n         \"ld  3,72(11)\\n\\t\"                                       \\\n         \"std 3,112(1)\\n\\t\"                                       \\\n         /* args1-8 */                                            \\\n         \"ld   3, 8(11)\\n\\t\"  /* arg1->r3 */                      \\\n         \"ld   4, 16(11)\\n\\t\" /* arg2->r4 */                      \\\n         \"ld   5, 24(11)\\n\\t\" /* arg3->r5 */                      \\\n         \"ld   6, 32(11)\\n\\t\" /* arg4->r6 */                      \\\n         \"ld   7, 40(11)\\n\\t\" /* arg5->r7 */                      \\\n         \"ld   8, 48(11)\\n\\t\" /* arg6->r8 */                      \\\n         \"ld   9, 56(11)\\n\\t\" /* arg7->r9 */                      \\\n         \"ld  10, 64(11)\\n\\t\" /* arg8->r10 */                     \\\n         \"ld  11, 0(11)\\n\\t\"  /* target->r11 */                   \\\n         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \\\n         \"mr 11,%1\\n\\t\"                                           \\\n         \"mr %0,3\\n\\t\"                                            \\\n         \"ld  2,-16(11)\\n\\t\" /* restore tocptr */                 \\\n         VG_CONTRACT_FRAME_BY(144)                                \\\n         VG_CONTRACT_FRAME_BY(512)                                \\\n         : /*out*/   \"=r\" (_res)                                  \\\n         : /*in*/    \"r\" (&_argvec[2])                            \\\n         : /*trash*/ \"cc\", \"memory\", __CALLER_SAVED_REGS          \\\n      );                                                          \\\n      lval = (__typeof__(lval)) _res;                             \\\n   } while (0)\n\n#endif /* PLAT_ppc64_aix5 */\n\n\n/* ------------------------------------------------------------------ */\n/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */\n/*                                                                    */\n/* ------------------------------------------------------------------ */\n\n/* Some request codes.  There are many more of these, but most are not\n   exposed to end-user view.  These are the public ones, all of the\n   form 0x1000 + small_number.\n\n   Core ones are in the range 0x00000000--0x0000ffff.  The non-public\n   ones start at 0x2000.\n*/\n\n/* These macros are used by tools -- they must be public, but don't\n   embed them into other programs. */\n#define VG_USERREQ_TOOL_BASE(a,b) \\\n   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))\n#define VG_IS_TOOL_USERREQ(a, b, v) \\\n   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))\n\n/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! \n   This enum comprises an ABI exported by Valgrind to programs\n   which use client requests.  DO NOT CHANGE THE ORDER OF THESE\n   ENTRIES, NOR DELETE ANY -- add new ones at the end. */\ntypedef\n   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,\n          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,\n\n          /* These allow any function to be called from the simulated\n             CPU but run on the real CPU.  Nb: the first arg passed to\n             the function is always the ThreadId of the running\n             thread!  So CLIENT_CALL0 actually requires a 1 arg\n             function, etc. */\n          VG_USERREQ__CLIENT_CALL0 = 0x1101,\n          VG_USERREQ__CLIENT_CALL1 = 0x1102,\n          VG_USERREQ__CLIENT_CALL2 = 0x1103,\n          VG_USERREQ__CLIENT_CALL3 = 0x1104,\n\n          /* Can be useful in regression testing suites -- eg. can\n             send Valgrind's output to /dev/null and still count\n             errors. */\n          VG_USERREQ__COUNT_ERRORS = 0x1201,\n\n          /* These are useful and can be interpreted by any tool that\n             tracks malloc() et al, by using vg_replace_malloc.c. */\n          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,\n          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,\n          /* Memory pool support. */\n          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,\n          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,\n          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,\n          VG_USERREQ__MEMPOOL_FREE     = 0x1306,\n          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,\n          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,\n          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,\n          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,\n\n          /* Allow printfs to valgrind log. */\n          VG_USERREQ__PRINTF           = 0x1401,\n          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,\n\n          /* Stack support. */\n          VG_USERREQ__STACK_REGISTER   = 0x1501,\n          VG_USERREQ__STACK_DEREGISTER = 0x1502,\n          VG_USERREQ__STACK_CHANGE     = 0x1503\n   } Vg_ClientRequest;\n\n#if !defined(__GNUC__)\n#  define __extension__ /* */\n#endif\n\n/* Returns the number of Valgrinds this code is running under.  That\n   is, 0 if running natively, 1 if running under Valgrind, 2 if\n   running under Valgrind which is running under another Valgrind,\n   etc. */\n#define RUNNING_ON_VALGRIND  __extension__                        \\\n   ({unsigned int _qzz_res;                                       \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \\\n                               VG_USERREQ__RUNNING_ON_VALGRIND,   \\\n                               0, 0, 0, 0, 0);                    \\\n    _qzz_res;                                                     \\\n   })\n\n\n/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +\n   _qzz_len - 1].  Useful if you are debugging a JITter or some such,\n   since it provides a way to make sure valgrind will retranslate the\n   invalidated area.  Returns no value. */\n#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__DISCARD_TRANSLATIONS,  \\\n                               _qzz_addr, _qzz_len, 0, 0, 0);     \\\n   }\n\n\n/* These requests are for getting Valgrind itself to print something.\n   Possibly with a backtrace.  This is a really ugly hack. */\n\n#if defined(NVALGRIND)\n\n#  define VALGRIND_PRINTF(...)\n#  define VALGRIND_PRINTF_BACKTRACE(...)\n\n#else /* NVALGRIND */\n\n/* Modern GCC will optimize the static routine out if unused,\n   and unused attribute will shut down warnings about it.  */\nstatic int VALGRIND_PRINTF(const char *format, ...)\n   __attribute__((format(__printf__, 1, 2), __unused__));\nstatic int\nVALGRIND_PRINTF(const char *format, ...)\n{\n   unsigned long _qzz_res;\n   va_list vargs;\n   va_start(vargs, format);\n   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,\n                              (unsigned long)format, (unsigned long)vargs, \n                              0, 0, 0);\n   va_end(vargs);\n   return (int)_qzz_res;\n}\n\nstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)\n   __attribute__((format(__printf__, 1, 2), __unused__));\nstatic int\nVALGRIND_PRINTF_BACKTRACE(const char *format, ...)\n{\n   unsigned long _qzz_res;\n   va_list vargs;\n   va_start(vargs, format);\n   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,\n                              (unsigned long)format, (unsigned long)vargs, \n                              0, 0, 0);\n   va_end(vargs);\n   return (int)_qzz_res;\n}\n\n#endif /* NVALGRIND */\n\n\n/* These requests allow control to move from the simulated CPU to the\n   real CPU, calling an arbitary function.\n   \n   Note that the current ThreadId is inserted as the first argument.\n   So this call:\n\n     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)\n\n   requires f to have this signature:\n\n     Word f(Word tid, Word arg1, Word arg2)\n\n   where \"Word\" is a word-sized type.\n\n   Note that these client requests are not entirely reliable.  For example,\n   if you call a function with them that subsequently calls printf(),\n   there's a high chance Valgrind will crash.  Generally, your prospects of\n   these working are made higher if the called function does not refer to\n   any global variables, and does not refer to any libc or other functions\n   (printf et al).  Any kind of entanglement with libc or dynamic linking is\n   likely to have a bad outcome, for tricky reasons which we've grappled\n   with a lot in the past.\n*/\n#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \\\n   __extension__                                                  \\\n   ({unsigned long _qyy_res;                                      \\\n    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \\\n                               VG_USERREQ__CLIENT_CALL0,          \\\n                               _qyy_fn,                           \\\n                               0, 0, 0, 0);                       \\\n    _qyy_res;                                                     \\\n   })\n\n#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \\\n   __extension__                                                  \\\n   ({unsigned long _qyy_res;                                      \\\n    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \\\n                               VG_USERREQ__CLIENT_CALL1,          \\\n                               _qyy_fn,                           \\\n                               _qyy_arg1, 0, 0, 0);               \\\n    _qyy_res;                                                     \\\n   })\n\n#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \\\n   __extension__                                                  \\\n   ({unsigned long _qyy_res;                                      \\\n    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \\\n                               VG_USERREQ__CLIENT_CALL2,          \\\n                               _qyy_fn,                           \\\n                               _qyy_arg1, _qyy_arg2, 0, 0);       \\\n    _qyy_res;                                                     \\\n   })\n\n#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \\\n   __extension__                                                  \\\n   ({unsigned long _qyy_res;                                      \\\n    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \\\n                               VG_USERREQ__CLIENT_CALL3,          \\\n                               _qyy_fn,                           \\\n                               _qyy_arg1, _qyy_arg2,              \\\n                               _qyy_arg3, 0);                     \\\n    _qyy_res;                                                     \\\n   })\n\n\n/* Counts the number of errors that have been recorded by a tool.  Nb:\n   the tool must record the errors with VG_(maybe_record_error)() or\n   VG_(unique_error)() for them to be counted. */\n#define VALGRIND_COUNT_ERRORS                                     \\\n   __extension__                                                  \\\n   ({unsigned int _qyy_res;                                       \\\n    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \\\n                               VG_USERREQ__COUNT_ERRORS,          \\\n                               0, 0, 0, 0, 0);                    \\\n    _qyy_res;                                                     \\\n   })\n\n/* Mark a block of memory as having been allocated by a malloc()-like\n   function.  `addr' is the start of the usable block (ie. after any\n   redzone) `rzB' is redzone size if the allocator can apply redzones;\n   use '0' if not.  Adding redzones makes it more likely Valgrind will spot\n   block overruns.  `is_zeroed' indicates if the memory is zeroed, as it is\n   for calloc().  Put it immediately after the point where a block is\n   allocated. \n   \n   If you're using Memcheck: If you're allocating memory via superblocks,\n   and then handing out small chunks of each superblock, if you don't have\n   redzones on your small blocks, it's worth marking the superblock with\n   VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are\n   detected.  But if you can put redzones on, it's probably better to not do\n   this, so that messages for small overruns are described in terms of the\n   small block rather than the superblock (but if you have a big overrun\n   that skips over a redzone, you could miss an error this way).  See\n   memcheck/tests/custom_alloc.c for an example.\n\n   WARNING: if your allocator uses malloc() or 'new' to allocate\n   superblocks, rather than mmap() or brk(), this will not work properly --\n   you'll likely get assertion failures during leak detection.  This is\n   because Valgrind doesn't like seeing overlapping heap blocks.  Sorry.\n\n   Nb: block must be freed via a free()-like function specified\n   with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */\n#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MALLOCLIKE_BLOCK,      \\\n                               addr, sizeB, rzB, is_zeroed, 0);   \\\n   }\n\n/* Mark a block of memory as having been freed by a free()-like function.\n   `rzB' is redzone size;  it must match that given to\n   VALGRIND_MALLOCLIKE_BLOCK.  Memory not freed will be detected by the leak\n   checker.  Put it immediately after the point where the block is freed. */\n#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__FREELIKE_BLOCK,        \\\n                               addr, rzB, 0, 0, 0);               \\\n   }\n\n/* Create a memory pool. */\n#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__CREATE_MEMPOOL,        \\\n                               pool, rzB, is_zeroed, 0, 0);       \\\n   }\n\n/* Destroy a memory pool. */\n#define VALGRIND_DESTROY_MEMPOOL(pool)                            \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__DESTROY_MEMPOOL,       \\\n                               pool, 0, 0, 0, 0);                 \\\n   }\n\n/* Associate a piece of memory with a memory pool. */\n#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MEMPOOL_ALLOC,         \\\n                               pool, addr, size, 0, 0);           \\\n   }\n\n/* Disassociate a piece of memory from a memory pool. */\n#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MEMPOOL_FREE,          \\\n                               pool, addr, 0, 0, 0);              \\\n   }\n\n/* Disassociate any pieces outside a particular range. */\n#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MEMPOOL_TRIM,          \\\n                               pool, addr, size, 0, 0);           \\\n   }\n\n/* Resize and/or move a piece associated with a memory pool. */\n#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MOVE_MEMPOOL,          \\\n                               poolA, poolB, 0, 0, 0);            \\\n   }\n\n/* Resize and/or move a piece associated with a memory pool. */\n#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MEMPOOL_CHANGE,        \\\n                               pool, addrA, addrB, size, 0);      \\\n   }\n\n/* Return 1 if a mempool exists, else 0. */\n#define VALGRIND_MEMPOOL_EXISTS(pool)                             \\\n   ({unsigned int _qzz_res;                                       \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__MEMPOOL_EXISTS,        \\\n                               pool, 0, 0, 0, 0);                 \\\n    _qzz_res;                                                     \\\n   })\n\n/* Mark a piece of memory as being a stack. Returns a stack id. */\n#define VALGRIND_STACK_REGISTER(start, end)                       \\\n   ({unsigned int _qzz_res;                                       \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__STACK_REGISTER,        \\\n                               start, end, 0, 0, 0);              \\\n    _qzz_res;                                                     \\\n   })\n\n/* Unmark the piece of memory associated with a stack id as being a\n   stack. */\n#define VALGRIND_STACK_DEREGISTER(id)                             \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__STACK_DEREGISTER,      \\\n                               id, 0, 0, 0, 0);                   \\\n   }\n\n/* Change the start and end address of the stack id. */\n#define VALGRIND_STACK_CHANGE(id, start, end)                     \\\n   {unsigned int _qzz_res;                                        \\\n    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \\\n                               VG_USERREQ__STACK_CHANGE,          \\\n                               id, start, end, 0, 0);             \\\n   }\n\n\n#undef PLAT_x86_linux\n#undef PLAT_amd64_linux\n#undef PLAT_ppc32_linux\n#undef PLAT_ppc64_linux\n#undef PLAT_ppc32_aix5\n#undef PLAT_ppc64_aix5\n\n#endif   /* __VALGRIND_H */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/thread_cache.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Ken Ashcraft <opensource@google.com>\n\n#include <config.h>\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>\n#endif\n#include <algorithm>   // for min and max\n#include \"thread_cache.h\"\n#include \"maybe_threads.h\"\n\nusing std::min;\nusing std::max;\n\nDEFINE_int64(tcmalloc_max_total_thread_cache_bytes,\n             EnvToInt64(\"TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES\",\n                        kDefaultOverallThreadCacheSize),\n             \"Bound on the total amount of bytes allocated to \"\n             \"thread caches.  This bound is not strict, so it is possible \"\n             \"for the cache to go over this bound in certain circumstances. \");\n\nnamespace tcmalloc {\n\nstatic bool phinited = false;\n\nvolatile size_t ThreadCache::per_thread_cache_size_ = kMaxThreadCacheSize;\nsize_t ThreadCache::overall_thread_cache_size_ = kDefaultOverallThreadCacheSize;\nssize_t ThreadCache::unclaimed_cache_space_ = kDefaultOverallThreadCacheSize;\nPageHeapAllocator<ThreadCache> threadcache_allocator;\nThreadCache* ThreadCache::thread_heaps_ = NULL;\nint ThreadCache::thread_heap_count_ = 0;\nThreadCache* ThreadCache::next_memory_steal_ = NULL;\n#ifdef HAVE_TLS\n__thread ThreadCache* ThreadCache::threadlocal_heap_\n# ifdef HAVE___ATTRIBUTE__\n   __attribute__ ((tls_model (\"initial-exec\")))\n# endif\n   ;\n#endif\nbool ThreadCache::tsd_inited_ = false;\npthread_key_t ThreadCache::heap_key_;\n\n#if defined(HAVE_TLS)\nbool kernel_supports_tls = false;      // be conservative\n# if !HAVE_DECL_UNAME   // if too old for uname, probably too old for TLS\n    void CheckIfKernelSupportsTLS() {\n      kernel_supports_tls = false;\n    }\n# else\n#   include <sys/utsname.h>    // DECL_UNAME checked for <sys/utsname.h> too\n    void CheckIfKernelSupportsTLS() {\n      struct utsname buf;\n      if (uname(&buf) != 0) {   // should be impossible\n        MESSAGE(\"uname failed assuming no TLS support (errno=%d)\\n\", errno);\n        kernel_supports_tls = false;\n      } else if (strcasecmp(buf.sysname, \"linux\") == 0) {\n        // The linux case: the first kernel to support TLS was 2.6.0\n        if (buf.release[0] < '2' && buf.release[1] == '.')    // 0.x or 1.x\n          kernel_supports_tls = false;\n        else if (buf.release[0] == '2' && buf.release[1] == '.' &&\n                 buf.release[2] >= '0' && buf.release[2] < '6' &&\n                 buf.release[3] == '.')                       // 2.0 - 2.5\n          kernel_supports_tls = false;\n        else\n          kernel_supports_tls = true;\n      } else {        // some other kernel, we'll be optimisitic\n        kernel_supports_tls = true;\n      }\n      // TODO(csilvers): VLOG(1) the tls status once we support RAW_VLOG\n    }\n#  endif  // HAVE_DECL_UNAME\n#endif    // HAVE_TLS\n\nvoid ThreadCache::Init(pthread_t tid) {\n  size_ = 0;\n\n  max_size_ = 0;\n  IncreaseCacheLimitLocked();\n  if (max_size_ == 0) {\n    // There isn't enough memory to go around.  Just give the minimum to\n    // this thread.\n    max_size_ = kMinThreadCacheSize;\n\n    // Take unclaimed_cache_space_ negative.\n    unclaimed_cache_space_ -= kMinThreadCacheSize;\n    ASSERT(unclaimed_cache_space_ < 0);\n  }\n\n  next_ = NULL;\n  prev_ = NULL;\n  tid_  = tid;\n  in_setspecific_ = false;\n  for (size_t cl = 0; cl < kNumClasses; ++cl) {\n    list_[cl].Init();\n  }\n\n  uint32_t sampler_seed;\n  memcpy(&sampler_seed, &tid, sizeof(sampler_seed));\n  sampler_.Init(sampler_seed);\n}\n\nvoid ThreadCache::Cleanup() {\n  // Put unused memory back into central cache\n  for (int cl = 0; cl < kNumClasses; ++cl) {\n    if (list_[cl].length() > 0) {\n      ReleaseToCentralCache(&list_[cl], cl, list_[cl].length());\n    }\n  }\n}\n\n// Remove some objects of class \"cl\" from central cache and add to thread heap.\n// On success, return the first object for immediate use; otherwise return NULL.\nvoid* ThreadCache::FetchFromCentralCache(size_t cl, size_t byte_size) {\n  FreeList* list = &list_[cl];\n  ASSERT(list->empty());\n  const int batch_size = Static::sizemap()->num_objects_to_move(cl);\n\n  const int num_to_move = min<int>(list->max_length(), batch_size);\n  void *start, *end;\n  int fetch_count = Static::central_cache()[cl].RemoveRange(\n      &start, &end, num_to_move);\n\n  ASSERT((start == NULL) == (fetch_count == 0));\n  if (--fetch_count >= 0) {\n    size_ += byte_size * fetch_count;\n    list->PushRange(fetch_count, SLL_Next(start), end);\n  }\n\n  // Increase max length slowly up to batch_size.  After that,\n  // increase by batch_size in one shot so that the length is a\n  // multiple of batch_size.\n  if (list->max_length() < batch_size) {\n    list->set_max_length(list->max_length() + 1);\n  } else {\n    // Don't let the list get too long.  In 32 bit builds, the length\n    // is represented by a 16 bit int, so we need to watch out for\n    // integer overflow.\n    int new_length = min<int>(list->max_length() + batch_size,\n                              kMaxDynamicFreeListLength);\n    // The list's max_length must always be a multiple of batch_size,\n    // and kMaxDynamicFreeListLength is not necessarily a multiple\n    // of batch_size.\n    new_length -= new_length % batch_size;\n    ASSERT(new_length % batch_size == 0);\n    list->set_max_length(new_length);\n  }\n  return start;\n}\n\nvoid ThreadCache::ListTooLong(FreeList* list, size_t cl) {\n  const int batch_size = Static::sizemap()->num_objects_to_move(cl);\n  ReleaseToCentralCache(list, cl, batch_size);\n\n  // If the list is too long, we need to transfer some number of\n  // objects to the central cache.  Ideally, we would transfer\n  // num_objects_to_move, so the code below tries to make max_length\n  // converge on num_objects_to_move.\n\n  if (list->max_length() < batch_size) {\n    // Slow start the max_length so we don't overreserve.\n    list->set_max_length(list->max_length() + 1);\n  } else if (list->max_length() > batch_size) {\n    // If we consistently go over max_length, shrink max_length.  If we don't\n    // shrink it, some amount of memory will always stay in this freelist.\n    list->set_length_overages(list->length_overages() + 1);\n    if (list->length_overages() > kMaxOverages) {\n      ASSERT(list->max_length() > batch_size);\n      list->set_max_length(list->max_length() - batch_size);\n      list->set_length_overages(0);\n    }\n  }\n}\n\n// Remove some objects of class \"cl\" from thread heap and add to central cache\nvoid ThreadCache::ReleaseToCentralCache(FreeList* src, size_t cl, int N) {\n  ASSERT(src == &list_[cl]);\n  if (N > src->length()) N = src->length();\n  size_t delta_bytes = N * Static::sizemap()->ByteSizeForClass(cl);\n\n  // We return prepackaged chains of the correct size to the central cache.\n  // TODO: Use the same format internally in the thread caches?\n  int batch_size = Static::sizemap()->num_objects_to_move(cl);\n  while (N > batch_size) {\n    void *tail, *head;\n    src->PopRange(batch_size, &head, &tail);\n    Static::central_cache()[cl].InsertRange(head, tail, batch_size);\n    N -= batch_size;\n  }\n  void *tail, *head;\n  src->PopRange(N, &head, &tail);\n  Static::central_cache()[cl].InsertRange(head, tail, N);\n  size_ -= delta_bytes;\n}\n\n// Release idle memory to the central cache\nvoid ThreadCache::Scavenge() {\n  // If the low-water mark for the free list is L, it means we would\n  // not have had to allocate anything from the central cache even if\n  // we had reduced the free list size by L.  We aim to get closer to\n  // that situation by dropping L/2 nodes from the free list.  This\n  // may not release much memory, but if so we will call scavenge again\n  // pretty soon and the low-water marks will be high on that call.\n  //int64 start = CycleClock::Now();\n  for (int cl = 0; cl < kNumClasses; cl++) {\n    FreeList* list = &list_[cl];\n    const int lowmark = list->lowwatermark();\n    if (lowmark > 0) {\n      const int drop = (lowmark > 1) ? lowmark/2 : 1;\n      ReleaseToCentralCache(list, cl, drop);\n\n      // Shrink the max length if it isn't used.  Only shrink down to\n      // batch_size -- if the thread was active enough to get the max_length\n      // above batch_size, it will likely be that active again.  If\n      // max_length shinks below batch_size, the thread will have to\n      // go through the slow-start behavior again.  The slow-start is useful\n      // mainly for threads that stay relatively idle for their entire\n      // lifetime.\n      const int batch_size = Static::sizemap()->num_objects_to_move(cl);\n      if (list->max_length() > batch_size) {\n        list->set_max_length(\n            max<int>(list->max_length() - batch_size, batch_size));\n      }\n    }\n    list->clear_lowwatermark();\n  }\n\n  IncreaseCacheLimit();\n\n//   int64 finish = CycleClock::Now();\n//   CycleTimer ct;\n//   MESSAGE(\"GC: %.0f ns\\n\", ct.CyclesToUsec(finish-start)*1000.0);\n}\n\nvoid ThreadCache::IncreaseCacheLimit() {\n  SpinLockHolder h(Static::pageheap_lock());\n  IncreaseCacheLimitLocked();\n}\n\nvoid ThreadCache::IncreaseCacheLimitLocked() {\n  if (unclaimed_cache_space_ > 0) {\n    // Possibly make unclaimed_cache_space_ negative.\n    unclaimed_cache_space_ -= kStealAmount;\n    max_size_ += kStealAmount;\n    return;\n  }\n  // Don't hold pageheap_lock too long.  Try to steal from 10 other\n  // threads before giving up.  The i < 10 condition also prevents an\n  // infinite loop in case none of the existing thread heaps are\n  // suitable places to steal from.\n  for (int i = 0; i < 10;\n       ++i, next_memory_steal_ = next_memory_steal_->next_) {\n    // Reached the end of the linked list.  Start at the beginning.\n    if (next_memory_steal_ == NULL) {\n      ASSERT(thread_heaps_ != NULL);\n      next_memory_steal_ = thread_heaps_;\n    }\n    if (next_memory_steal_ == this ||\n        next_memory_steal_->max_size_ <= kMinThreadCacheSize) {\n      continue;\n    }\n    next_memory_steal_->max_size_ -= kStealAmount;\n    max_size_ += kStealAmount;\n\n    next_memory_steal_ = next_memory_steal_->next_;\n    return;\n  }\n}\n\nint ThreadCache::GetSamplePeriod() {\n  return sampler_.GetSamplePeriod();\n}\n\nvoid ThreadCache::InitModule() {\n  SpinLockHolder h(Static::pageheap_lock());\n  if (!phinited) {\n    Static::InitStaticVars();\n    threadcache_allocator.Init();\n    phinited = 1;\n  }\n}\n\nvoid ThreadCache::InitTSD() {\n  ASSERT(!tsd_inited_);\n  perftools_pthread_key_create(&heap_key_, DestroyThreadCache);\n  tsd_inited_ = true;\n\n  // We may have used a fake pthread_t for the main thread.  Fix it.\n  pthread_t zero;\n  memset(&zero, 0, sizeof(zero));\n  SpinLockHolder h(Static::pageheap_lock());\n  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {\n    if (h->tid_ == zero) {\n      h->tid_ = pthread_self();\n    }\n  }\n}\n\nThreadCache* ThreadCache::CreateCacheIfNecessary() {\n  // Initialize per-thread data if necessary\n  ThreadCache* heap = NULL;\n  {\n    SpinLockHolder h(Static::pageheap_lock());\n\n    // Early on in glibc's life, we cannot even call pthread_self()\n    pthread_t me;\n    if (!tsd_inited_) {\n      memset(&me, 0, sizeof(me));\n    } else {\n      me = pthread_self();\n    }\n\n    // This may be a recursive malloc call from pthread_setspecific()\n    // In that case, the heap for this thread has already been created\n    // and added to the linked list.  So we search for that first.\n    for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {\n      if (h->tid_ == me) {\n        heap = h;\n        break;\n      }\n    }\n\n    if (heap == NULL) heap = NewHeap(me);\n  }\n\n  // We call pthread_setspecific() outside the lock because it may\n  // call malloc() recursively.  We check for the recursive call using\n  // the \"in_setspecific_\" flag so that we can avoid calling\n  // pthread_setspecific() if we are already inside pthread_setspecific().\n  if (!heap->in_setspecific_ && tsd_inited_) {\n    heap->in_setspecific_ = true;\n    perftools_pthread_setspecific(heap_key_, heap);\n#ifdef HAVE_TLS\n    // Also keep a copy in __thread for faster retrieval\n    threadlocal_heap_ = heap;\n#endif\n    heap->in_setspecific_ = false;\n  }\n  return heap;\n}\n\nThreadCache* ThreadCache::NewHeap(pthread_t tid) {\n  // Create the heap and add it to the linked list\n  ThreadCache *heap = threadcache_allocator.New();\n  heap->Init(tid);\n  heap->next_ = thread_heaps_;\n  heap->prev_ = NULL;\n  if (thread_heaps_ != NULL) {\n    thread_heaps_->prev_ = heap;\n  } else {\n    // This is the only thread heap at the momment.\n    ASSERT(next_memory_steal_ == NULL);\n    next_memory_steal_ = heap;\n  }\n  thread_heaps_ = heap;\n  thread_heap_count_++;\n  return heap;\n}\n\nvoid ThreadCache::BecomeIdle() {\n  if (!tsd_inited_) return;              // No caches yet\n  ThreadCache* heap = GetThreadHeap();\n  if (heap == NULL) return;             // No thread cache to remove\n  if (heap->in_setspecific_) return;    // Do not disturb the active caller\n\n  heap->in_setspecific_ = true;\n  perftools_pthread_setspecific(heap_key_, NULL);\n#ifdef HAVE_TLS\n  // Also update the copy in __thread\n  threadlocal_heap_ = NULL;\n#endif\n  heap->in_setspecific_ = false;\n  if (GetThreadHeap() == heap) {\n    // Somehow heap got reinstated by a recursive call to malloc\n    // from pthread_setspecific.  We give up in this case.\n    return;\n  }\n\n  // We can now get rid of the heap\n  DeleteCache(heap);\n}\n\nvoid ThreadCache::DestroyThreadCache(void* ptr) {\n  // Note that \"ptr\" cannot be NULL since pthread promises not\n  // to invoke the destructor on NULL values, but for safety,\n  // we check anyway.\n  if (ptr == NULL) return;\n#ifdef HAVE_TLS\n  // Prevent fast path of GetThreadHeap() from returning heap.\n  threadlocal_heap_ = NULL;\n#endif\n  DeleteCache(reinterpret_cast<ThreadCache*>(ptr));\n}\n\nvoid ThreadCache::DeleteCache(ThreadCache* heap) {\n  // Remove all memory from heap\n  heap->Cleanup();\n\n  // Remove from linked list\n  SpinLockHolder h(Static::pageheap_lock());\n  if (heap->next_ != NULL) heap->next_->prev_ = heap->prev_;\n  if (heap->prev_ != NULL) heap->prev_->next_ = heap->next_;\n  if (thread_heaps_ == heap) thread_heaps_ = heap->next_;\n  thread_heap_count_--;\n\n  if (next_memory_steal_ == heap) next_memory_steal_ = heap->next_;\n  if (next_memory_steal_ == NULL) next_memory_steal_ = thread_heaps_;\n  unclaimed_cache_space_ += heap->max_size_;\n\n  threadcache_allocator.Delete(heap);\n}\n\nvoid ThreadCache::RecomputePerThreadCacheSize() {\n  // Divide available space across threads\n  int n = thread_heap_count_ > 0 ? thread_heap_count_ : 1;\n  size_t space = overall_thread_cache_size_ / n;\n\n  // Limit to allowed range\n  if (space < kMinThreadCacheSize) space = kMinThreadCacheSize;\n  if (space > kMaxThreadCacheSize) space = kMaxThreadCacheSize;\n\n  double ratio = space / max<double>(1, per_thread_cache_size_);\n  size_t claimed = 0;\n  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {\n    // Increasing the total cache size should not circumvent the\n    // slow-start growth of max_size_.\n    if (ratio < 1.0) {\n        h->max_size_ = static_cast<size_t>(h->max_size_ * ratio);\n    }\n    claimed += h->max_size_;\n  }\n  unclaimed_cache_space_ = overall_thread_cache_size_ - claimed;\n  per_thread_cache_size_ = space;\n  //  TCMalloc_MESSAGE(__FILE__, __LINE__, \"Threads %d => cache size %8d\\n\", n, int(space));\n}\n\nvoid ThreadCache::Print(TCMalloc_Printer* out) const {\n  for (int cl = 0; cl < kNumClasses; ++cl) {\n    out->printf(\"      %5\" PRIuS \" : %4\" PRIuS \" len; %4d lo; %4\"PRIuS\n                \" max; %4\"PRIuS\" overages;\\n\",\n                Static::sizemap()->ByteSizeForClass(cl),\n                list_[cl].length(),\n                list_[cl].lowwatermark(),\n                list_[cl].max_length(),\n                list_[cl].length_overages());\n  }\n}\n\nvoid ThreadCache::PrintThreads(TCMalloc_Printer* out) {\n  size_t actual_limit = 0;\n  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {\n    h->Print(out);\n    actual_limit += h->max_size_;\n  }\n  out->printf(\"ThreadCache overall: %\"PRIuS \", unclaimed: %\"PRIuS\n              \", actual: %\"PRIuS\"\\n\",\n              overall_thread_cache_size_, unclaimed_cache_space_, actual_limit);\n}\n\nvoid ThreadCache::GetThreadStats(uint64_t* total_bytes, uint64_t* class_count) {\n  for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {\n    *total_bytes += h->Size();\n    if (class_count) {\n      for (int cl = 0; cl < kNumClasses; ++cl) {\n        class_count[cl] += h->freelist_length(cl);\n      }\n    }\n  }\n}\n\nvoid ThreadCache::set_overall_thread_cache_size(size_t new_size) {\n  // Clip the value to a reasonable range\n  if (new_size < kMinThreadCacheSize) new_size = kMinThreadCacheSize;\n  if (new_size > (1<<30)) new_size = (1<<30);     // Limit to 1GB\n  overall_thread_cache_size_ = new_size;\n\n  RecomputePerThreadCacheSize();\n}\n\n}  // namespace tcmalloc\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/thread_cache.h",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// ---\n// Author: Sanjay Ghemawat <opensource@google.com>\n\n#ifndef TCMALLOC_THREAD_CACHE_H_\n#define TCMALLOC_THREAD_CACHE_H_\n\n#include <config.h>\n#ifdef HAVE_PTHREAD\n#include <pthread.h>\n#endif\n#include \"common.h\"\n#include \"linked_list.h\"\n#include \"maybe_threads.h\"\n#include \"page_heap_allocator.h\"\n#include \"sampler.h\"\n#include \"static_vars.h\"\n\nnamespace tcmalloc {\n\n// Even if we have support for thread-local storage in the compiler\n// and linker, the OS may not support it.  We need to check that at\n// runtime.  Right now, we have to keep a manual set of \"bad\" OSes.\n#if defined(HAVE_TLS)\nextern bool kernel_supports_tls;   // defined in thread_cache.cc\nvoid CheckIfKernelSupportsTLS();\ninline bool KernelSupportsTLS() {\n  return kernel_supports_tls;\n}\n#endif    // HAVE_TLS\n\n//-------------------------------------------------------------------\n// Data kept per thread\n//-------------------------------------------------------------------\n\nclass ThreadCache {\n public:\n  // All ThreadCache objects are kept in a linked list (for stats collection)\n  ThreadCache* next_;\n  ThreadCache* prev_;\n\n  void Init(pthread_t tid);\n  void Cleanup();\n\n  // Accessors (mostly just for printing stats)\n  int freelist_length(size_t cl) const { return list_[cl].length(); }\n\n  // Total byte size in cache\n  size_t Size() const { return size_; }\n\n  // Allocate an object of the given size and class. The size given\n  // must be the same as the size of the class in the size map.\n  void* Allocate(size_t size, size_t cl);\n  void Deallocate(void* ptr, size_t size_class);\n\n  void Scavenge();\n  void Print(TCMalloc_Printer* out) const;\n\n  int GetSamplePeriod();\n\n  // Record allocation of \"k\" bytes.  Return true iff allocation\n  // should be sampled\n  bool SampleAllocation(size_t k);\n\n  static void         InitModule();\n  static void         InitTSD();\n  static ThreadCache* GetThreadHeap();\n  static ThreadCache* GetCache();\n  static ThreadCache* GetCacheIfPresent();\n  static ThreadCache* CreateCacheIfNecessary();\n  static void         BecomeIdle();\n\n  // Return the number of thread heaps in use.\n  static inline int HeapsInUse();\n\n  // Writes to total_bytes the total number of bytes used by all thread heaps.\n  // class_count must be an array of size kNumClasses.  Writes the number of\n  // items on the corresponding freelist.  class_count may be NULL.\n  // The storage of both parameters must be zero intialized.\n  // REQUIRES: Static::pageheap_lock is held.\n  static void GetThreadStats(uint64_t* total_bytes, uint64_t* class_count);\n\n  // Write debugging statistics to 'out'.\n  // REQUIRES: Static::pageheap_lock is held.\n  static void PrintThreads(TCMalloc_Printer* out);\n\n  // Sets the total thread cache size to new_size, recomputing the\n  // individual thread cache sizes as necessary.\n  // REQUIRES: Static::pageheap lock is held.\n  static void set_overall_thread_cache_size(size_t new_size);\n  static size_t overall_thread_cache_size() {\n    return overall_thread_cache_size_;\n  }\n\n private:\n  class FreeList {\n   private:\n    void*    list_;       // Linked list of nodes\n\n#ifdef _LP64\n    // On 64-bit hardware, manipulating 16-bit values may be slightly slow.\n    uint32_t length_;      // Current length.\n    uint32_t lowater_;     // Low water mark for list length.\n    uint32_t max_length_;  // Dynamic max list length based on usage.\n    // Tracks the number of times a deallocation has caused\n    // length_ > max_length_.  After the kMaxOverages'th time, max_length_\n    // shrinks and length_overages_ is reset to zero.\n    uint32_t length_overages_;\n#else\n    // If we aren't using 64-bit pointers then pack these into less space.\n    uint16_t length_;\n    uint16_t lowater_;\n    uint16_t max_length_;\n    uint16_t length_overages_;\n#endif\n\n   public:\n    void Init() {\n      list_ = NULL;\n      length_ = 0;\n      lowater_ = 0;\n      max_length_ = 1;\n      length_overages_ = 0;\n    }\n\n    // Return current length of list\n    size_t length() const {\n      return length_;\n    }\n\n    // Return the maximum length of the list.\n    size_t max_length() const {\n      return max_length_;\n    }\n\n    // Set the maximum length of the list.  If 'new_max' > length(), the\n    // client is responsible for removing objects from the list.\n    void set_max_length(size_t new_max) {\n      max_length_ = new_max;\n    }\n\n    // Return the number of times that length() has gone over max_length().\n    size_t length_overages() const {\n      return length_overages_;\n    }\n\n    void set_length_overages(size_t new_count) {\n      length_overages_ = new_count;\n    }\n\n    // Is list empty?\n    bool empty() const {\n      return list_ == NULL;\n    }\n\n    // Low-water mark management\n    int lowwatermark() const { return lowater_; }\n    void clear_lowwatermark() { lowater_ = length_; }\n\n    void Push(void* ptr) {\n      SLL_Push(&list_, ptr);\n      length_++;\n    }\n\n    void* Pop() {\n      ASSERT(list_ != NULL);\n      length_--;\n      if (length_ < lowater_) lowater_ = length_;\n      return SLL_Pop(&list_);\n    }\n\n    void PushRange(int N, void *start, void *end) {\n      SLL_PushRange(&list_, start, end);\n      length_ += N;\n    }\n\n    void PopRange(int N, void **start, void **end) {\n      SLL_PopRange(&list_, N, start, end);\n      ASSERT(length_ >= N);\n      length_ -= N;\n      if (length_ < lowater_) lowater_ = length_;\n    }\n  };\n\n  // Gets and returns an object from the central cache, and, if possible,\n  // also adds some objects of that size class to this thread cache.\n  void* FetchFromCentralCache(size_t cl, size_t byte_size);\n\n  // Releases some number of items from src.  Adjusts the list's max_length\n  // to eventually converge on num_objects_to_move(cl).\n  void ListTooLong(FreeList* src, size_t cl);\n\n  // Releases N items from this thread cache.\n  void ReleaseToCentralCache(FreeList* src, size_t cl, int N);\n\n  // Increase max_size_ by reducing unclaimed_cache_space_ or by\n  // reducing the max_size_ of some other thread.  In both cases,\n  // the delta is kStealAmount.\n  void IncreaseCacheLimit();\n  // Same as above but requires Static::pageheap_lock() is held.\n  void IncreaseCacheLimitLocked();\n\n  // If TLS is available, we also store a copy of the per-thread object\n  // in a __thread variable since __thread variables are faster to read\n  // than pthread_getspecific().  We still need pthread_setspecific()\n  // because __thread variables provide no way to run cleanup code when\n  // a thread is destroyed.\n  // We also give a hint to the compiler to use the \"initial exec\" TLS\n  // model.  This is faster than the default TLS model, at the cost that\n  // you cannot dlopen this library.  (To see the difference, look at\n  // the CPU use of __tls_get_addr with and without this attribute.)\n  // Since we don't really use dlopen in google code -- and using dlopen\n  // on a malloc replacement is asking for trouble in any case -- that's\n  // a good tradeoff for us.\n#ifdef HAVE_TLS\n  static __thread ThreadCache* threadlocal_heap_\n# ifdef HAVE___ATTRIBUTE__\n   __attribute__ ((tls_model (\"initial-exec\")))\n# endif\n   ;\n#endif\n\n  // Thread-specific key.  Initialization here is somewhat tricky\n  // because some Linux startup code invokes malloc() before it\n  // is in a good enough state to handle pthread_keycreate().\n  // Therefore, we use TSD keys only after tsd_inited is set to true.\n  // Until then, we use a slow path to get the heap object.\n  static bool tsd_inited_;\n  static pthread_key_t heap_key_;\n\n  // Linked list of heap objects.  Protected by Static::pageheap_lock.\n  static ThreadCache* thread_heaps_;\n  static int thread_heap_count_;\n\n  // A pointer to one of the objects in thread_heaps_.  Represents\n  // the next ThreadCache from which a thread over its max_size_ should\n  // steal memory limit.  Round-robin through all of the objects in\n  // thread_heaps_.  Protected by Static::pageheap_lock.\n  static ThreadCache* next_memory_steal_;\n\n  // Overall thread cache size.  Protected by Static::pageheap_lock.\n  static size_t overall_thread_cache_size_;\n\n  // Global per-thread cache size.  Writes are protected by\n  // Static::pageheap_lock.  Reads are done without any locking, which should be\n  // fine as long as size_t can be written atomically and we don't place\n  // invariants between this variable and other pieces of state.\n  static volatile size_t per_thread_cache_size_;\n\n  // Represents overall_thread_cache_size_ minus the sum of max_size_\n  // across all ThreadCaches.  Protected by Static::pageheap_lock.\n  static ssize_t unclaimed_cache_space_;\n\n  // This class is laid out with the most frequently used fields\n  // first so that hot elements are placed on the same cache line.\n\n  size_t        size_;                  // Combined size of data\n  size_t        max_size_;              // size_ > max_size_ --> Scavenge()\n\n  // We sample allocations, biased by the size of the allocation\n  Sampler       sampler_;               // A sampler\n\n  FreeList      list_[kNumClasses];     // Array indexed by size-class\n\n  pthread_t     tid_;                   // Which thread owns it\n  bool          in_setspecific_;        // In call to pthread_setspecific?\n\n  // Allocate a new heap. REQUIRES: Static::pageheap_lock is held.\n  static ThreadCache* NewHeap(pthread_t tid);\n\n  // Use only as pthread thread-specific destructor function.\n  static void DestroyThreadCache(void* ptr);\n\n  static void DeleteCache(ThreadCache* heap);\n  static void RecomputePerThreadCacheSize();\n\n  // Ensure that this class is cacheline-aligned. This is critical for\n  // performance, as false sharing would negate many of the benefits\n  // of a per-thread cache.\n} CACHELINE_ALIGNED;\n\n// Allocator for thread heaps\n// This is logically part of the ThreadCache class, but MSVC, at\n// least, does not like using ThreadCache as a template argument\n// before the class is fully defined.  So we put it outside the class.\nextern PageHeapAllocator<ThreadCache> threadcache_allocator;\n\ninline int ThreadCache::HeapsInUse() {\n  return threadcache_allocator.inuse();\n}\n\ninline bool ThreadCache::SampleAllocation(size_t k) {\n  return sampler_.SampleAllocation(k);\n}\n\ninline void* ThreadCache::Allocate(size_t size, size_t cl) {\n  ASSERT(size <= kMaxSize);\n  ASSERT(size == Static::sizemap()->ByteSizeForClass(cl));\n\n  FreeList* list = &list_[cl];\n  if (list->empty()) {\n    return FetchFromCentralCache(cl, size);\n  }\n  size_ -= size;\n  return list->Pop();\n}\n\ninline void ThreadCache::Deallocate(void* ptr, size_t cl) {\n  FreeList* list = &list_[cl];\n  size_ += Static::sizemap()->ByteSizeForClass(cl);\n  ssize_t size_headroom = max_size_ - size_ - 1;\n  list->Push(ptr);\n  ssize_t list_headroom =\n      static_cast<ssize_t>(list->max_length()) - list->length();\n\n  // There are two relatively uncommon things that require further work.\n  // In the common case we're done, and in that case we need a single branch\n  // because of the bitwise-or trick that follows.\n  if ((list_headroom | size_headroom) < 0) {\n    if (list_headroom < 0) {\n      ListTooLong(list, cl);\n    }\n    if (size_ >= max_size_) Scavenge();\n  }\n}\n\ninline ThreadCache* ThreadCache::GetThreadHeap() {\n#ifdef HAVE_TLS\n  // __thread is faster, but only when the kernel supports it\n  if (KernelSupportsTLS())\n    return threadlocal_heap_;\n#endif\n  return reinterpret_cast<ThreadCache *>(\n      perftools_pthread_getspecific(heap_key_));\n}\n\ninline ThreadCache* ThreadCache::GetCache() {\n  ThreadCache* ptr = NULL;\n  if (!tsd_inited_) {\n    InitModule();\n  } else {\n    ptr = GetThreadHeap();\n  }\n  if (ptr == NULL) ptr = CreateCacheIfNecessary();\n  return ptr;\n}\n\n// In deletion paths, we do not try to create a thread-cache.  This is\n// because we may be in the thread destruction code and may have\n// already cleaned up the cache for this thread.\ninline ThreadCache* ThreadCache::GetCacheIfPresent() {\n  if (!tsd_inited_) return NULL;\n  return GetThreadHeap();\n}\n\n}  // namespace tcmalloc\n\n#endif  // TCMALLOC_THREAD_CACHE_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/addr2line-pdb.c",
    "content": "/* Copyright (c) 2008, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: David Vitek\n *\n * Dump function addresses using Microsoft debug symbols.  This works\n * on PDB files.  Note that this program will download symbols to\n * c:\\websymbols without asking.\n */\n\n#define WIN32_LEAN_AND_MEAN\n#define _CRT_SECURE_NO_WARNINGS\n#define _CRT_SECURE_NO_DEPRECATE\n\n#include <stdio.h>\n#include <stdlib.h>\n\n#include <windows.h>\n#include <dbghelp.h>\n\n#define SEARCH_CAP (1024*1024)\n#define WEBSYM \"SRV*c:\\\\websymbols*http://msdl.microsoft.com/download/symbols\"\n\nvoid usage() {\n  fprintf(stderr, \"usage: \"\n          \"addr2line-pdb [-f|--functions] [-C|--demangle] [-e filename]\\n\");\n  fprintf(stderr, \"(Then list the hex addresses on stdin, one per line)\\n\");\n}\n\nint main(int argc, char *argv[]) {\n  DWORD  error;\n  HANDLE process;\n  ULONG64 module_base;\n  int i;\n  char* search;\n  char buf[256];   /* Enough to hold one hex address, I trust! */\n  int rv = 0;\n  /* We may add SYMOPT_UNDNAME if --demangle is specified: */\n  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES;\n  char* filename = \"a.out\";         /* The default if -e isn't specified */\n  int print_function_name = 0;      /* Set to 1 if -f is specified */\n\n  for (i = 1; i < argc; i++) {\n    if (strcmp(argv[i], \"--functions\") == 0 || strcmp(argv[i], \"-f\") == 0) {\n      print_function_name = 1;\n    } else if (strcmp(argv[i], \"--demangle\") == 0 ||\n               strcmp(argv[i], \"-C\") == 0) {\n      symopts |= SYMOPT_UNDNAME;\n    } else if (strcmp(argv[i], \"-e\") == 0) {\n      if (i + 1 >= argc) {\n        fprintf(stderr, \"FATAL ERROR: -e must be followed by a filename\\n\");\n        return 1;\n      }\n      filename = argv[i+1];\n      i++;     /* to skip over filename too */\n    } else if (strcmp(argv[i], \"--help\") == 0) {\n      usage();\n      exit(0);\n    } else {\n      usage();\n      exit(1);\n    }\n  }\n\n  process = GetCurrentProcess();\n\n  if (!SymInitialize(process, NULL, FALSE)) {\n    error = GetLastError();\n    fprintf(stderr, \"SymInitialize returned error : %d\\n\", error);\n    return 1;\n  }\n\n  search = malloc(SEARCH_CAP);\n  if (SymGetSearchPath(process, search, SEARCH_CAP)) {\n    if (strlen(search) + sizeof(\";\" WEBSYM) > SEARCH_CAP) {\n      fprintf(stderr, \"Search path too long\\n\");\n      SymCleanup(process);\n      return 1;\n    }\n    strcat(search, \";\" WEBSYM);\n  } else {\n    error = GetLastError();\n    fprintf(stderr, \"SymGetSearchPath returned error : %d\\n\", error);\n    rv = 1;                   /* An error, but not a fatal one */\n    strcpy(search, WEBSYM);   /* Use a default value */\n  }\n  if (!SymSetSearchPath(process, search)) {\n    error = GetLastError();\n    fprintf(stderr, \"SymSetSearchPath returned error : %d\\n\", error);\n    rv = 1;                   /* An error, but not a fatal one */\n  }\n\n  SymSetOptions(symopts);\n  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);\n  if (!module_base) {\n    /* SymLoadModuleEx failed */\n    error = GetLastError();\n    fprintf(stderr, \"SymLoadModuleEx returned error : %d for %s\\n\",\n            error, filename);\n    SymCleanup(process);\n    return 1;\n  }\n\n  buf[sizeof(buf)-1] = '\\0';  /* Just to be safe */\n  while (fgets(buf, sizeof(buf)-1, stdin)) {\n    /* GNU addr2line seems to just do a strtol and ignore any\n     * weird characters it gets, so we will too.\n     */\n    unsigned __int64 addr = _strtoui64(buf, NULL, 16);\n    ULONG64 buffer[(sizeof(SYMBOL_INFO) +\n                    MAX_SYM_NAME*sizeof(TCHAR) +\n                    sizeof(ULONG64) - 1)\n                   / sizeof(ULONG64)];\n    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;\n    IMAGEHLP_LINE64 line;\n    DWORD dummy;\n    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);\n    pSymbol->MaxNameLen = MAX_SYM_NAME;\n    if (print_function_name) {\n      if (SymFromAddr(process, (DWORD64)addr, NULL, pSymbol)) {\n        printf(\"%s\\n\", pSymbol->Name);\n      } else {\n        printf(\"??\\n\");\n      }\n    }\n    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);\n    if (SymGetLineFromAddr64(process, (DWORD64)addr, &dummy, &line)) {\n      printf(\"%s:%d\\n\", line.FileName, (int)line.LineNumber);\n    } else {\n      printf(\"??:0\\n\");\n    }\n  }\n  SymUnloadModule64(process, module_base);\n  SymCleanup(process);\n  return rv;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/get_mangled_names.cc",
    "content": "// Copyright (c) 2008, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n// \n// ---\n// Author: Craig Silverstein (opensource@google.com)\n\n// When you are porting perftools to a new compiler or architecture\n// (win64 vs win32) for instance, you'll need to change the mangled\n// symbol names for operator new and friends at the top of\n// patch_functions.cc.  This file helps you do that.\n//\n// It does this by defining these functions with the proper signature.\n// All you need to do is compile this file and the run dumpbin on it.\n// (See http://msdn.microsoft.com/en-us/library/5x49w699.aspx for more\n// on dumpbin).  To do this in MSVC, use the MSVC commandline shell:\n//    http://msdn.microsoft.com/en-us/library/ms235639(VS.80).aspx)\n//\n// The run:\n//    cl /c get_mangled_names.cc\n//    dumpbin /symbols get_mangled_names.obj\n//\n// It will print out the mangled (and associated unmangled) names of\n// the 8 symbols you need to put at the top of patch_functions.cc\n\n#include <sys/types.h>   // for size_t\n#include <new>           // for nothrow_t\n\nstatic char m;   // some dummy memory so new doesn't return NULL.\n\nvoid* operator new(size_t size) { return &m; }\nvoid operator delete(void* p) throw() { }\nvoid* operator new[](size_t size) { return &m; }\nvoid operator delete[](void* p) throw() { }\n\nvoid* operator new(size_t size, const std::nothrow_t&) throw() { return &m; }\nvoid operator delete(void* p, const std::nothrow_t&) throw() { }\nvoid* operator new[](size_t size, const std::nothrow_t&) throw() { return &m; }\nvoid operator delete[](void* p, const std::nothrow_t&) throw() { }\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/google/tcmalloc.h",
    "content": "/* Copyright (c) 2003, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Sanjay Ghemawat <opensource@google.com>\n *         .h file by Craig Silverstein <opensource@google.com>\n */\n\n#ifndef TCMALLOC_TCMALLOC_H_\n#define TCMALLOC_TCMALLOC_H_\n\n// Define the version number so folks can check against it\n#define TC_VERSION_MAJOR  1\n#define TC_VERSION_MINOR  4\n#define TC_VERSION_PATCH  \"\"\n#define TC_VERSION_STRING \"google-perftools 1.4\"\n\n// __THROW is defined in glibc systems.  It means, counter-intuitively,\n// \"This function will never throw an exception.\"  It's an optional\n// optimization tool, but we may need to use it to match glibc prototypes.\n#ifndef __THROW    /* I guess we're not on a glibc system */\n# define __THROW   /* __THROW is just an optimization, so ok to make it \"\" */\n#endif\n\n\n#include <stdlib.h>   // for struct mallinfo, if it's defined\n\n// Annoying stuff for windows -- makes sure clients can import these functions\n#ifndef PERFTOOLS_DLL_DECL\n# ifdef _WIN32\n#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)\n# else\n#   define PERFTOOLS_DLL_DECL\n# endif\n#endif\n\n#ifdef __cplusplus\n#include <new>          // for std::nothrow_t\n\nextern \"C\" {\n#endif\n  // Returns a human-readable version string.  If major, minor,\n  // and/or patch are not NULL, they are set to the major version,\n  // minor version, and patch-code (a string, usually \"\").\n  PERFTOOLS_DLL_DECL const char* tc_version(int* major, int* minor,\n                                            const char** patch) __THROW;\n\n  PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW;\n\n  PERFTOOLS_DLL_DECL void* tc_memalign(size_t __alignment,\n                                       size_t __size) __THROW;\n  PERFTOOLS_DLL_DECL int tc_posix_memalign(void** ptr,\n                                           size_t align, size_t size) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_valloc(size_t __size) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t __size) __THROW;\n\n  PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW;\n  PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW;\n#if 0\n  PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW;\n#endif\n\n  // This is an alias for MallocExtension::instance()->GetAllocatedSize().\n  // It is equivalent to\n  //    OS X: malloc_size()\n  //    glibc: malloc_usable_size()\n  //    Windows: _msize()\n  PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW;\n\n#ifdef __cplusplus\n  PERFTOOLS_DLL_DECL int tc_set_new_mode(int flag) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_new(size_t size);\n  PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,\n                                          const std::nothrow_t&) __THROW;\n  PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;\n  PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,\n                                            const std::nothrow_t&) __THROW;\n  PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);\n  PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,\n                                               const std::nothrow_t&) __THROW;\n  PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;\n  PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,\n                                                 const std::nothrow_t&) __THROW;\n}\n#endif\n\n#endif  // #ifndef TCMALLOC_TCMALLOC_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/ia32_modrm_map.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Table of relevant information about how to decode the ModR/M byte.\n * Based on information in the IA-32 Intel Architecture\n * Software Developers Manual Volume 2: Instruction Set Reference.\n */\n\n#include \"mini_disassembler.h\"\n#include \"mini_disassembler_types.h\"\n\nnamespace sidestep {\n\nconst ModrmEntry MiniDisassembler::s_ia16_modrm_map_[] = {\n// mod == 00\n  /* r/m == 000 */ { false, false, OS_ZERO },\n  /* r/m == 001 */ { false, false, OS_ZERO },\n  /* r/m == 010 */ { false, false, OS_ZERO },\n  /* r/m == 011 */ { false, false, OS_ZERO },\n  /* r/m == 100 */ { false, false, OS_ZERO },\n  /* r/m == 101 */ { false, false, OS_ZERO },\n  /* r/m == 110 */ { true, false, OS_WORD },\n  /* r/m == 111 */ { false, false, OS_ZERO }, \n// mod == 01\n  /* r/m == 000 */ { true, false, OS_BYTE },\n  /* r/m == 001 */ { true, false, OS_BYTE },\n  /* r/m == 010 */ { true, false, OS_BYTE },\n  /* r/m == 011 */ { true, false, OS_BYTE },\n  /* r/m == 100 */ { true, false, OS_BYTE },\n  /* r/m == 101 */ { true, false, OS_BYTE },\n  /* r/m == 110 */ { true, false, OS_BYTE },\n  /* r/m == 111 */ { true, false, OS_BYTE }, \n// mod == 10\n  /* r/m == 000 */ { true, false, OS_WORD },\n  /* r/m == 001 */ { true, false, OS_WORD },\n  /* r/m == 010 */ { true, false, OS_WORD },\n  /* r/m == 011 */ { true, false, OS_WORD },\n  /* r/m == 100 */ { true, false, OS_WORD },\n  /* r/m == 101 */ { true, false, OS_WORD },\n  /* r/m == 110 */ { true, false, OS_WORD },\n  /* r/m == 111 */ { true, false, OS_WORD }, \n// mod == 11\n  /* r/m == 000 */ { false, false, OS_ZERO },\n  /* r/m == 001 */ { false, false, OS_ZERO },\n  /* r/m == 010 */ { false, false, OS_ZERO },\n  /* r/m == 011 */ { false, false, OS_ZERO },\n  /* r/m == 100 */ { false, false, OS_ZERO },\n  /* r/m == 101 */ { false, false, OS_ZERO },\n  /* r/m == 110 */ { false, false, OS_ZERO },\n  /* r/m == 111 */ { false, false, OS_ZERO }\n};\n\nconst ModrmEntry MiniDisassembler::s_ia32_modrm_map_[] = {\n// mod == 00\n  /* r/m == 000 */ { false, false, OS_ZERO },\n  /* r/m == 001 */ { false, false, OS_ZERO },\n  /* r/m == 010 */ { false, false, OS_ZERO },\n  /* r/m == 011 */ { false, false, OS_ZERO },\n  /* r/m == 100 */ { false, true, OS_ZERO },\n  /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 110 */ { false, false, OS_ZERO },\n  /* r/m == 111 */ { false, false, OS_ZERO }, \n// mod == 01\n  /* r/m == 000 */ { true, false, OS_BYTE },\n  /* r/m == 001 */ { true, false, OS_BYTE },\n  /* r/m == 010 */ { true, false, OS_BYTE },\n  /* r/m == 011 */ { true, false, OS_BYTE },\n  /* r/m == 100 */ { true, true, OS_BYTE },\n  /* r/m == 101 */ { true, false, OS_BYTE },\n  /* r/m == 110 */ { true, false, OS_BYTE },\n  /* r/m == 111 */ { true, false, OS_BYTE }, \n// mod == 10\n  /* r/m == 000 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 001 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 010 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 011 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 100 */ { true, true, OS_DOUBLE_WORD },\n  /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 110 */ { true, false, OS_DOUBLE_WORD },\n  /* r/m == 111 */ { true, false, OS_DOUBLE_WORD }, \n// mod == 11\n  /* r/m == 000 */ { false, false, OS_ZERO },\n  /* r/m == 001 */ { false, false, OS_ZERO },\n  /* r/m == 010 */ { false, false, OS_ZERO },\n  /* r/m == 011 */ { false, false, OS_ZERO },\n  /* r/m == 100 */ { false, false, OS_ZERO },\n  /* r/m == 101 */ { false, false, OS_ZERO },\n  /* r/m == 110 */ { false, false, OS_ZERO },\n  /* r/m == 111 */ { false, false, OS_ZERO },\n};\n\n};  // namespace sidestep\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/ia32_opcode_map.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Opcode decoding maps.  Based on the IA-32 Intel Architecture\n * Software Developers Manual Volume 2: Instruction Set Reference.  Idea\n * for how to lay out the tables in memory taken from the implementation\n * in the Bastard disassembly environment.\n */\n\n#include \"mini_disassembler.h\"\n\nnamespace sidestep {\n\n/*\n* This is the first table to be searched; the first field of each\n* Opcode in the table is either 0 to indicate you're in the\n* right table, or an index to the correct table, in the global\n* map g_pentiumOpcodeMap\n*/\nconst Opcode s_first_opcode_byte[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF */ { 1, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x10 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x11 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x12 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x13 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x14 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x15 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x16 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x17 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x18 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x19 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1E */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1F */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x20 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x21 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x22 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x23 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x24 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x25 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x26 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x27 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"daa\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x28 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x29 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"das\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x30 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x31 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x32 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x33 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x34 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x35 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x36 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x37 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"aaa\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x38 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x39 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"aas\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x40 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x41 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x42 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x43 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x44 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x45 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x46 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x47 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x48 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x49 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x50 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x51 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x52 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x53 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x54 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x55 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x56 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x57 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x58 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x59 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x60 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"pushad\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x61 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"popad\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x62 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_A, AM_NOT_USED, \"bound\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x63 */ { 0, IT_GENERIC, AM_E | OT_W, AM_G | OT_W, AM_NOT_USED, \"arpl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x64 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x65 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x66 */ { 0, IT_PREFIX_OPERAND, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x67 */ { 0, IT_PREFIX_ADDRESS, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x68 */ { 0, IT_GENERIC, AM_I | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x69 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_V, \"imul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6A */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I |  OT_B, \"imul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6C */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"insb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6D */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"insd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6E */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X | OT_B, AM_NOT_USED, \"outsb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X | OT_V, AM_NOT_USED, \"outsb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x70 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x71 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jno\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x72 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x73 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jnc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x74 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x75 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jnz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x76 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jbe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x77 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"ja\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x78 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"js\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x79 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jns\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7A */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jpe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7B */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jpo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7C */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7D */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jge\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7E */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jle\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7F */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x80 */ { 2, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x81 */ { 3, IT_REFERENCE, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x82 */ { 4, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x83 */ { 5, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x84 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x85 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x86 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x87 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x88 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x89 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8C */ { 0, IT_GENERIC, AM_E | OT_W, AM_S | OT_W, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8D */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, \"lea\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8E */ { 0, IT_GENERIC, AM_S | OT_W, AM_E | OT_W, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8F */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x90 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"nop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x91 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x92 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x93 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x94 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x95 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x96 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x97 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"xchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x98 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"cwde\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x99 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"cdq\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9A */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, \"callf\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9B */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"wait\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"pushfd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"popfd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9E */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"sahf\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"lahf\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_O | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_O | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA2 */ { 0, IT_GENERIC, AM_O | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA3 */ { 0, IT_GENERIC, AM_O | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA4 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, \"movsb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA5 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, \"movsd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA6 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, \"cmpsb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA7 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, \"cmpsd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAA */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"stosb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAB */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, \"stosd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X| OT_B, AM_NOT_USED, \"lodsb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X| OT_V, AM_NOT_USED, \"lodsd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAE */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_Y | OT_B, AM_NOT_USED, \"scasb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_Y | OT_V, AM_NOT_USED, \"scasd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB1 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB2 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB3 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC0 */ { 6, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC1 */ { 7, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC2 */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, \"ret\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC3 */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"ret\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC4 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, \"les\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, \"lds\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC8 */ { 0, IT_GENERIC, AM_I | OT_W, AM_I | OT_B, AM_NOT_USED, \"enter\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"leave\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCA */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, \"retf\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCB */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"retf\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"int3\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCD */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, \"int\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCE */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"into\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCF */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"iret\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD0 */ { 8, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD1 */ { 9, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD2 */ { 10, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD3 */ { 11, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD4 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, \"aam\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD5 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, \"aad\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"xlat\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  \n  // The following 8 lines would be references to the FPU tables, but we currently\n  // do not support the FPU instructions in this disassembler.\n  \n  /* 0xD8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xDA */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xDB */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xDC */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xDD */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xDE */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xDF */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  \n  \n  /* 0xE0 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"loopnz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE1 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"loopz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE2 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"loop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE3 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jcxz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"in\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, \"in\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE6 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"out\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE7 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"out\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE8 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"call\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE9 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xEA */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, \"jmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xEB */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, \"jmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xEC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_REGISTER | OT_W, AM_NOT_USED, \"in\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xED */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_W, AM_NOT_USED, \"in\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xEE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_B, AM_NOT_USED, \"out\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xEF */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_V, AM_NOT_USED, \"out\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF0 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"lock:\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF2 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"repne:\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF3 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"rep:\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF4 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"hlt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"cmc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF6 */ { 12, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF7 */ { 13, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"clc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"stc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xFA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"cli\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xFB */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"sti\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xFC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"cld\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xFD */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"std\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xFE */ { 14, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xFF */ { 15, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f[] = {\n  /* 0x0 */ { 16, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 17, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, \"lar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, \"lsl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"clts\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"invd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"wbinvd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"ud2\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xE */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x10 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"movups\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"movsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"movss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"movupd\" } },\n  /* 0x11 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, \"movups\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_W | OT_SD, AM_V | OT_SD, AM_NOT_USED, \"movsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_W | OT_SS, AM_V | OT_SS, AM_NOT_USED, \"movss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, \"movupd\" } },\n  /* 0x12 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movlps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movhlps\" },  // only one of ...\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movhlps\" },  // ...these two is correct, Intel doesn't specify which\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_S, AM_NOT_USED, \"movlpd\" } },\n  /* 0x13 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, \"movlps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, \"movlpd\" } },\n  /* 0x14 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, \"unpcklps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, \"unpcklpd\" } },\n  /* 0x15 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, \"unpckhps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, \"unpckhpd\" } },\n  /* 0x16 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, \"movhps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movlhps\" },  // only one of...\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movlhps\" },  // ...these two is correct, Intel doesn't specify which\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, \"movhpd\" } },\n  /* 0x17 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movhps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movhpd\" } },\n  /* 0x18 */ { 18, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x19 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1C */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x20 */ { 0, IT_GENERIC, AM_R | OT_D, AM_C | OT_D, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x21 */ { 0, IT_GENERIC, AM_R | OT_D, AM_D | OT_D, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x22 */ { 0, IT_GENERIC, AM_C | OT_D, AM_R | OT_D, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x23 */ { 0, IT_GENERIC, AM_D | OT_D, AM_R | OT_D, AM_NOT_USED, \"mov\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x24 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x25 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x26 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x27 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x28 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"movaps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"movapd\" } },\n  /* 0x29 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, \"movaps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, \"movapd\" } },\n  /* 0x2A */ { 0, IT_GENERIC, AM_V | OT_PS, AM_Q | OT_Q, AM_NOT_USED, \"cvtpi2ps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_E | OT_D, AM_NOT_USED, \"cvtsi2sd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_E | OT_D, AM_NOT_USED, \"cvtsi2ss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_Q | OT_DQ, AM_NOT_USED, \"cvtpi2pd\" } },\n  /* 0x2B */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, \"movntps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, \"movntpd\" } },\n  /* 0x2C */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, \"cvttps2pi\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, \"cvttsd2si\" },\n    /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, \"cvttss2si\" },\n    /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, \"cvttpd2pi\" } },\n  /* 0x2D */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, \"cvtps2pi\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, \"cvtsd2si\" },\n    /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, \"cvtss2si\" },\n    /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, \"cvtpd2pi\" } },\n  /* 0x2E */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"ucomiss\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"ucomisd\" } },\n  /* 0x2F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_SS, AM_NOT_USED, \"comiss\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"comisd\" } },\n  /* 0x30 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"wrmsr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x31 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"rdtsc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x32 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"rdmsr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x33 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"rdpmc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x34 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"sysenter\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x35 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"sysexit\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x36 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x37 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x38 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x39 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"movnti\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x40 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x41 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovno\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x42 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x43 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovnc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x44 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x45 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovnz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x46 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovbe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x47 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmova\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x48 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovs\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x49 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovns\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4A */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovpe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovpo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4D */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovge\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4E */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovle\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4F */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"cmovg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x50 */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PS, AM_NOT_USED, \"movmskps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PD, AM_NOT_USED, \"movmskpd\" } },\n  /* 0x51 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"sqrtps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"sqrtsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"sqrtss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"sqrtpd\" } },\n  /* 0x52 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"rsqrtps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"rsqrtss\" },\n    /* 66h */ { 0 } },\n  /* 0x53 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"rcpps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"rcpss\" },\n    /* 66h */ { 0 } },\n  /* 0x54 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"andps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"andpd\" } },\n  /* 0x55 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"andnps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"andnpd\" } },\n  /* 0x56 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"orps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"orpd\" } },\n  /* 0x57 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"xorps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"xorpd\" } },\n  /* 0x58 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"addps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"addsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"addss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"addpd\" } },\n  /* 0x59 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"mulps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"mulsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"mulss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"mulpd\" } },\n  /* 0x5A */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PS, AM_NOT_USED, \"cvtps2pd\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"cvtsd2ss\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"cvtss2sd\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PD, AM_NOT_USED, \"cvtpd2ps\" } },\n  /* 0x5B */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_DQ, AM_NOT_USED, \"cvtdq2ps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, \"cvttps2dq\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, \"cvtps2dq\" } },\n  /* 0x5C */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"subps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"subsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"subss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"subpd\" } },\n  /* 0x5D */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"minps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"minsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"minss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"minpd\" } },\n  /* 0x5E */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"divps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"divsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"divss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"divpd\" } },\n  /* 0x5F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, \"maxps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, \"maxsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, \"maxss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, \"maxpd\" } },\n  /* 0x60 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"punpcklbw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"punpcklbw\" } },\n  /* 0x61 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"punpcklwd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"punpcklwd\" } },\n  /* 0x62 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"punpckldq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"punpckldq\" } },\n  /* 0x63 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"packsswb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"packsswb\" } },\n  /* 0x64 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"pcmpgtb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pcmpgtb\" } },\n  /* 0x65 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"pcmpgtw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pcmpgtw\" } },\n  /* 0x66 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"pcmpgtd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pcmpgtd\" } },\n  /* 0x67 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"packuswb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"packuswb\" } },\n  /* 0x68 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"punpckhbw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, \"punpckhbw\" } },\n  /* 0x69 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"punpckhwd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, \"punpckhwd\" } },\n  /* 0x6A */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"punpckhdq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, \"punpckhdq\" } },\n  /* 0x6B */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"packssdw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, \"packssdw\" } },\n  /* 0x6C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"not used without prefix\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"punpcklqdq\" } },\n  /* 0x6D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"not used without prefix\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"punpcklqdq\" } },\n  /* 0x6E */ { 0, IT_GENERIC, AM_P | OT_D, AM_E | OT_D, AM_NOT_USED, \"movd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_NOT_USED, \"movd\" } },\n  /* 0x6F */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, \"movq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"movdqu\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"movdqa\" } },\n  /* 0x70 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_I |  OT_B, \"pshuf\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, \"pshuflw\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, \"pshufhw\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, \"pshufd\" } },\n  /* 0x71 */ { 19, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x72 */ { 20, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x73 */ { 21, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x74 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pcmpeqb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pcmpeqb\" } },\n  /* 0x75 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pcmpeqw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pcmpeqw\" } },\n  /* 0x76 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pcmpeqd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pcmpeqd\" } },\n  /* 0x77 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"emms\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  \n  // The following six opcodes are escapes into the MMX stuff, which this disassembler does not support.\n  /* 0x78 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x79 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7A */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7B */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7C */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7D */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  \n  /* 0x7E */ { 0, IT_GENERIC, AM_E | OT_D, AM_P | OT_D, AM_NOT_USED, \"movd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, \"movq\" },\n    /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_DQ, AM_NOT_USED, \"movd\" } },\n  /* 0x7F */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_P | OT_Q, AM_NOT_USED, \"movq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, \"movdqu\" },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, \"movdqa\" } },\n  /* 0x80 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x81 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jno\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x82 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x83 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jnc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x84 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x85 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jnz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x86 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jbe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x87 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"ja\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x88 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"js\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x89 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jns\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8A */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jpe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8B */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jpo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8C */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8D */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jge\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8E */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jle\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x8F */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, \"jg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x90 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"seto\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x91 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setno\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x92 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x93 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setnc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x94 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x95 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setnz\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x96 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setbe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x97 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"seta\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x98 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"sets\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x99 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setns\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9A */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setpe\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9B */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setpo\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9C */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9D */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setge\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9E */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setle\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x9F */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"setg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"cpuid\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"bt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, \"shld\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, \"shld\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA6 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA7 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, \"pop\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"rsm\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"bts\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAC */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, \"shrd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAD */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, \"shrd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAE */ { 22, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xAF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"imul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"cmpxchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"cmpxchg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB2 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, \"lss\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"btr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB4 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, \"lfs\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB5 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, \"lgs\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB6 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, \"movzx\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB7 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, \"movzx\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xB9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"ud1\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBA */ { 23, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, \"btc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBC */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"bsf\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBD */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, \"bsr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBE */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, \"movsx\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xBF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, \"movsx\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, \"xadd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"xadd\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC2 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, \"cmpps\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_I | OT_B, \"cmpsd\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W  | OT_SS, AM_I | OT_B, \"cmpss\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, \"cmppd\" } },\n  /* 0xC3 */ { 0, IT_GENERIC, AM_E | OT_D, AM_G | OT_D, AM_NOT_USED, \"movnti\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_E | OT_D, AM_I | OT_B, \"pinsrw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_I | OT_B, \"pinsrw\" } },\n  /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_I | OT_B, \"pextrw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_I | OT_B, \"pextrw\" } },\n  /* 0xC6 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, \"shufps\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, \"shufpd\" } },\n  /* 0xC7 */ { 24, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC8 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xC9 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCA */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCB */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCC */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCD */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCE */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xCF */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"bswap\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xD1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psrlw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psrlw\" } },\n  /* 0xD2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psrld\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psrld\" } },\n  /* 0xD3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psrlq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psrlq\" } },\n  /* 0xD4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddq\" } },\n  /* 0xD5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmullw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmullw\" } },\n  /* 0xD6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"unused without prefix\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_P | OT_Q, AM_W | OT_Q, AM_NOT_USED, \"movdq2q\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_Q | OT_Q, AM_NOT_USED, \"movq2dq\" },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movq\" } },\n  /* 0xD7 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_NOT_USED, \"pmovmskb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_NOT_USED, \"pmovmskb\" } },\n  /* 0xD8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubusb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubusb\" } },\n  /* 0xD9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubusw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubusw\" } },\n  /* 0xDA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pminub\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pminub\" } },\n  /* 0xDB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pand\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pand\" } },\n  /* 0xDC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddusb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddusb\" } },\n  /* 0xDD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddusw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddusw\" } },\n  /* 0xDE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmaxub\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmaxub\" } },\n  /* 0xDF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pandn\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pandn\" } },\n  /* 0xE0 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pavgb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pavgb\" } },\n  /* 0xE1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psraw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psrqw\" } },\n  /* 0xE2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psrad\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psrad\" } },\n  /* 0xE3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pavgw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pavgw\" } },\n  /* 0xE4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmulhuw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmulhuw\" } },\n  /* 0xE5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmulhuw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmulhw\" } },\n  /* 0xE6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"not used without prefix\", true,\n    /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, \"cvtpd2dq\" },\n    /* F3h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_DQ, AM_NOT_USED, \"cvtdq2pd\" },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, \"cvttpd2dq\" } },\n  /* 0xE7 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, \"movntq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, \"movntdq\" } },\n  /* 0xE8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubsb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubsb\" } },\n  /* 0xE9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubsw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubsw\" } },\n  /* 0xEA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pminsw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pminsw\" } },\n  /* 0xEB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"por\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"por\" } },\n  /* 0xEC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddsb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddsb\" } },\n  /* 0xED */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddsw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddsw\" } },\n  /* 0xEE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmaxsw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmaxsw\" } },\n  /* 0xEF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pxor\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pxor\" } },\n  /* 0xF0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0xF1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psllw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psllw\" } },\n  /* 0xF2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pslld\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pslld\" } },\n  /* 0xF3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psllq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psllq\" } },\n  /* 0xF4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmuludq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmuludq\" } },\n  /* 0xF5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"pmaddwd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"pmaddwd\" } },\n  /* 0xF6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psadbw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psadbw\" } },\n  /* 0xF7 */ { 0, IT_GENERIC, AM_P | OT_PI, AM_Q | OT_PI, AM_NOT_USED, \"maskmovq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"maskmovdqu\" } },\n  /* 0xF8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubb\" } },\n  /* 0xF9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubw\" } },\n  /* 0xFA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubd\" } },\n  /* 0xFB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"psubq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"psubq\" } },\n  /* 0xFC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddb\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddb\" } },\n  /* 0xFD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddw\" } },\n  /* 0xFE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, \"paddd\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, \"paddd\" } },\n  /* 0xFF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f00[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"sldt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"str\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"lldt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"ltr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"verr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"verw\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f01[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, \"sgdt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, \"sidt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, \"lgdt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, \"lidt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"smsw\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, \"lmsw\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_M | OT_B, AM_NOT_USED, AM_NOT_USED, \"invlpg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f18[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, AM_NOT_USED, \"prefetch\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"prefetch\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"prefetch\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, \"prefetch\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f71[] = {\n  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psrlw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psrlw\" } },\n  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psraw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psraw\" } },\n  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psllw\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psllw\" } },\n  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f72[] = {\n  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psrld\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psrld\" } },\n  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psrad\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psrad\" } },\n  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"pslld\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"pslld\" } },\n  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0f73[] = {\n  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psrlq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psrlq\" } },\n  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, \"psllq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"psllq\" } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"pslldq\", true,\n    /* F2h */ { 0 },\n    /* F3h */ { 0 },\n    /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, \"pslldq\" } },\n};\n\nconst Opcode s_opcode_byte_after_0fae[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"fxsave\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"fxrstor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"ldmxcsr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"stmxcsr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"lfence\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"mfence\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, \"clflush/sfence\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n};\n\nconst Opcode s_opcode_byte_after_0fba[] = {\n  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"bt\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"bts\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"btr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"btc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_0fc7[] = {\n  /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_Q, AM_NOT_USED, AM_NOT_USED, \"cmpxch8b\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_80[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_81[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_82[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_83[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"add\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"or\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"adc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"sbb\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"and\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"sub\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"xor\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"cmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_c0[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"rol\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"ror\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"rcl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"rcr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"shl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"shr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"sal\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"sar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_c1[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"rol\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"ror\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"rcl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"rcr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"shl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"shr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"sal\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, \"sar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_d0[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"rol\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"ror\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"rcl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"rcr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"shl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"shr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"sal\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, \"sar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_d1[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"rol\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"ror\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"rcl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"rcr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"shl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"shr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"sal\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, \"sar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_d2[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"rol\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"ror\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"rcl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"rcr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"shl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"shr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"sal\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, \"sar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_d3[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"rol\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"ror\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"rcl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"rcr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"shl\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"shr\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"sal\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, \"sar\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_f6[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"not\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"neg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, \"mul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, \"imul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, \"div\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, \"idiv\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_f7[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, \"test\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"not\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"neg\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, \"mul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, \"imul\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, \"div\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, \"idiv\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_fe[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\nconst Opcode s_opcode_byte_after_ff[] = {\n  /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"inc\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"dec\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x2 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"call\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x3 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, \"call\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x4 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"jmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x5 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, \"jmp\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, \"push\", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },\n  /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }\n};\n\n/*\n* A table of all the other tables, containing some extra information, e.g.\n* how to mask out the byte we're looking at.\n*/\nconst OpcodeTable MiniDisassembler::s_ia32_opcode_map_[]={\n  // One-byte opcodes and jumps to larger\n  /*  0 */ {s_first_opcode_byte, 0, 0xff, 0, 0xff},\n  // Two-byte opcodes (second byte)\n  /*  1 */ {s_opcode_byte_after_0f, 0, 0xff, 0, 0xff},\n  // Start of tables for opcodes using ModR/M bits as extension\n  /*  2 */ {s_opcode_byte_after_80, 3, 0x07, 0, 0x07},\n  /*  3 */ {s_opcode_byte_after_81, 3, 0x07, 0, 0x07}, \n  /*  4 */ {s_opcode_byte_after_82, 3, 0x07, 0, 0x07}, \n  /*  5 */ {s_opcode_byte_after_83, 3, 0x07, 0, 0x07}, \n  /*  6 */ {s_opcode_byte_after_c0, 3, 0x07, 0, 0x07}, \n  /*  7 */ {s_opcode_byte_after_c1, 3, 0x07, 0, 0x07}, \n  /*  8 */ {s_opcode_byte_after_d0, 3, 0x07, 0, 0x07}, \n  /*  9 */ {s_opcode_byte_after_d1, 3, 0x07, 0, 0x07}, \n  /* 10 */ {s_opcode_byte_after_d2, 3, 0x07, 0, 0x07}, \n  /* 11 */ {s_opcode_byte_after_d3, 3, 0x07, 0, 0x07}, \n  /* 12 */ {s_opcode_byte_after_f6, 3, 0x07, 0, 0x07}, \n  /* 13 */ {s_opcode_byte_after_f7, 3, 0x07, 0, 0x07}, \n  /* 14 */ {s_opcode_byte_after_fe, 3, 0x07, 0, 0x01}, \n  /* 15 */ {s_opcode_byte_after_ff, 3, 0x07, 0, 0x07}, \n  /* 16 */ {s_opcode_byte_after_0f00, 3, 0x07, 0, 0x07}, \n  /* 17 */ {s_opcode_byte_after_0f01, 3, 0x07, 0, 0x07}, \n  /* 18 */ {s_opcode_byte_after_0f18, 3, 0x07, 0, 0x07}, \n  /* 19 */ {s_opcode_byte_after_0f71, 3, 0x07, 0, 0x07}, \n  /* 20 */ {s_opcode_byte_after_0f72, 3, 0x07, 0, 0x07}, \n  /* 21 */ {s_opcode_byte_after_0f73, 3, 0x07, 0, 0x07}, \n  /* 22 */ {s_opcode_byte_after_0fae, 3, 0x07, 0, 0x07}, \n  /* 23 */ {s_opcode_byte_after_0fba, 3, 0x07, 0, 0x07}, \n  /* 24 */ {s_opcode_byte_after_0fc7, 3, 0x07, 0, 0x01}\n};\n\n};  // namespace sidestep\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/mingw.h",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Craig Silverstein\n *\n * MinGW is an interesting mix of unix and windows.  We use a normal\n * configure script, but still need the windows port.h to define some\n * stuff that MinGW doesn't support, like pthreads.\n */\n\n#ifndef GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_\n#define GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_\n\n#ifdef __MINGW32__\n\n// Older version of the mingw msvcrt don't define _aligned_malloc\n#if __MSVCRT_VERSION__ < 0x0700\n# define PERFTOOLS_NO_ALIGNED_MALLOC 1\n#endif\n\n// This must be defined before the windows.h is included.  We need at\n// least 0x0400 for mutex.h to have access to TryLock, and at least\n// 0x0501 for patch_functions.cc to have access to GetModuleHandleEx.\n// (This latter is an optimization we could take out if need be.)\n#ifndef _WIN32_WINNT\n# define _WIN32_WINNT 0x0501\n#endif\n\n#include \"windows/port.h\"\n\n#define HAVE_SNPRINTF 1\n\n// Some mingw distributions have a pthreads wrapper, but it doesn't\n// work as well as native windows spinlocks (at least for us).  So\n// pretend the pthreads wrapper doesn't exist, even when it does.\n#undef HAVE_PTHREAD\n\n#endif  /* __MINGW32__ */\n\n#endif  /* GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/mini_disassembler.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Implementation of MiniDisassembler.\n */\n\n#include \"mini_disassembler.h\"\n\nnamespace sidestep {\n\nMiniDisassembler::MiniDisassembler(bool operand_default_is_32_bits,\n                                   bool address_default_is_32_bits)\n    : operand_default_is_32_bits_(operand_default_is_32_bits),\n      address_default_is_32_bits_(address_default_is_32_bits) {\n  Initialize();\n}\n\nMiniDisassembler::MiniDisassembler()\n    : operand_default_is_32_bits_(true),\n      address_default_is_32_bits_(true) {\n  Initialize();\n}\n\nInstructionType MiniDisassembler::Disassemble(\n    unsigned char* start_byte,\n    unsigned int& instruction_bytes) {\n  // Clean up any state from previous invocations.\n  Initialize();\n\n  // Start by processing any prefixes.\n  unsigned char* current_byte = start_byte;\n  unsigned int size = 0;\n  InstructionType instruction_type = ProcessPrefixes(current_byte, size);\n\n  if (IT_UNKNOWN == instruction_type)\n    return instruction_type;\n\n  current_byte += size;\n  size = 0;\n\n  // Invariant: We have stripped all prefixes, and the operand_is_32_bits_\n  // and address_is_32_bits_ flags are correctly set.\n\n  instruction_type = ProcessOpcode(current_byte, 0, size);\n\n  // Check for error processing instruction\n  if ((IT_UNKNOWN == instruction_type_) || (IT_UNUSED == instruction_type_)) {\n    return IT_UNKNOWN;\n  }\n\n  current_byte += size;\n\n  // Invariant: operand_bytes_ indicates the total size of operands\n  // specified by the opcode and/or ModR/M byte and/or SIB byte.\n  // pCurrentByte points to the first byte after the ModR/M byte, or after\n  // the SIB byte if it is present (i.e. the first byte of any operands\n  // encoded in the instruction).\n\n  // We get the total length of any prefixes, the opcode, and the ModR/M and\n  // SIB bytes if present, by taking the difference of the original starting\n  // address and the current byte (which points to the first byte of the\n  // operands if present, or to the first byte of the next instruction if\n  // they are not).  Adding the count of bytes in the operands encoded in\n  // the instruction gives us the full length of the instruction in bytes.\n  instruction_bytes += operand_bytes_ + (current_byte - start_byte);\n\n  // Return the instruction type, which was set by ProcessOpcode().\n  return instruction_type_;\n}\n\nvoid MiniDisassembler::Initialize() {\n  operand_is_32_bits_ = operand_default_is_32_bits_;\n  address_is_32_bits_ = address_default_is_32_bits_;\n  operand_bytes_ = 0;\n  have_modrm_ = false;\n  should_decode_modrm_ = false;\n  instruction_type_ = IT_UNKNOWN;\n  got_f2_prefix_ = false;\n  got_f3_prefix_ = false;\n  got_66_prefix_ = false;\n}\n\nInstructionType MiniDisassembler::ProcessPrefixes(unsigned char* start_byte,\n                                                  unsigned int& size) {\n  InstructionType instruction_type = IT_GENERIC;\n  const Opcode& opcode = s_ia32_opcode_map_[0].table_[*start_byte];\n\n  switch (opcode.type_) {\n    case IT_PREFIX_ADDRESS:\n      address_is_32_bits_ = !address_default_is_32_bits_;\n      goto nochangeoperand;\n    case IT_PREFIX_OPERAND:\n      operand_is_32_bits_ = !operand_default_is_32_bits_;\n      nochangeoperand:\n    case IT_PREFIX:\n\n      if (0xF2 == (*start_byte))\n        got_f2_prefix_ = true;\n      else if (0xF3 == (*start_byte))\n        got_f3_prefix_ = true;\n      else if (0x66 == (*start_byte))\n        got_66_prefix_ = true;\n\n      instruction_type = opcode.type_;\n      size ++;\n      // we got a prefix, so add one and check next byte\n      ProcessPrefixes(start_byte + 1, size);\n    default:\n      break;   // not a prefix byte\n  }\n\n  return instruction_type;\n}\n\nInstructionType MiniDisassembler::ProcessOpcode(unsigned char* start_byte,\n                                                unsigned int table_index,\n                                                unsigned int& size) {\n  const OpcodeTable& table = s_ia32_opcode_map_[table_index];   // Get our table\n  unsigned char current_byte = (*start_byte) >> table.shift_;\n  current_byte = current_byte & table.mask_;  // Mask out the bits we will use\n\n  // Check whether the byte we have is inside the table we have.\n  if (current_byte < table.min_lim_ || current_byte > table.max_lim_) {\n    instruction_type_ = IT_UNKNOWN;\n    return instruction_type_;\n  }\n\n  const Opcode& opcode = table.table_[current_byte];\n  if (IT_UNUSED == opcode.type_) {\n    // This instruction is not used by the IA-32 ISA, so we indicate\n    // this to the user.  Probably means that we were pointed to\n    // a byte in memory that was not the start of an instruction.\n    instruction_type_ = IT_UNUSED;\n    return instruction_type_;\n  } else if (IT_REFERENCE == opcode.type_) {\n    // We are looking at an opcode that has more bytes (or is continued\n    // in the ModR/M byte).  Recursively find the opcode definition in\n    // the table for the opcode's next byte.\n    size++;\n    ProcessOpcode(start_byte + 1, opcode.table_index_, size);\n    return instruction_type_;\n  }\n\n  const SpecificOpcode* specific_opcode = (SpecificOpcode*)&opcode;\n  if (opcode.is_prefix_dependent_) {\n    if (got_f2_prefix_ && opcode.opcode_if_f2_prefix_.mnemonic_ != 0) {\n      specific_opcode = &opcode.opcode_if_f2_prefix_;\n    } else if (got_f3_prefix_ && opcode.opcode_if_f3_prefix_.mnemonic_ != 0) {\n      specific_opcode = &opcode.opcode_if_f3_prefix_;\n    } else if (got_66_prefix_ && opcode.opcode_if_66_prefix_.mnemonic_ != 0) {\n      specific_opcode = &opcode.opcode_if_66_prefix_;\n    }\n  }\n\n  // Inv: The opcode type is known.\n  instruction_type_ = specific_opcode->type_;\n\n  // Let's process the operand types to see if we have any immediate\n  // operands, and/or a ModR/M byte.\n\n  ProcessOperand(specific_opcode->flag_dest_);\n  ProcessOperand(specific_opcode->flag_source_);\n  ProcessOperand(specific_opcode->flag_aux_);\n\n  // Inv: We have processed the opcode and incremented operand_bytes_\n  // by the number of bytes of any operands specified by the opcode\n  // that are stored in the instruction (not registers etc.).  Now\n  // we need to return the total number of bytes for the opcode and\n  // for the ModR/M or SIB bytes if they are present.\n\n  if (table.mask_ != 0xff) {\n    if (have_modrm_) {\n      // we're looking at a ModR/M byte so we're not going to\n      // count that into the opcode size\n      ProcessModrm(start_byte, size);\n      return IT_GENERIC;\n    } else {\n      // need to count the ModR/M byte even if it's just being\n      // used for opcode extension\n      size++;\n      return IT_GENERIC;\n    }\n  } else {\n    if (have_modrm_) {\n      // The ModR/M byte is the next byte.\n      size++;\n      ProcessModrm(start_byte + 1, size);\n      return IT_GENERIC;\n    } else {\n      size++;\n      return IT_GENERIC;\n    }\n  }\n}\n\nbool MiniDisassembler::ProcessOperand(int flag_operand) {\n  bool succeeded = true;\n  if (AM_NOT_USED == flag_operand)\n    return succeeded;\n\n  // Decide what to do based on the addressing mode.\n  switch (flag_operand & AM_MASK) {\n    // No ModR/M byte indicated by these addressing modes, and no\n    // additional (e.g. immediate) parameters.\n    case AM_A: // Direct address\n    case AM_F: // EFLAGS register\n    case AM_X: // Memory addressed by the DS:SI register pair\n    case AM_Y: // Memory addressed by the ES:DI register pair\n    case AM_IMPLICIT: // Parameter is implicit, occupies no space in\n                       // instruction\n      break;\n\n    // There is a ModR/M byte but it does not necessarily need\n    // to be decoded.\n    case AM_C: // reg field of ModR/M selects a control register\n    case AM_D: // reg field of ModR/M selects a debug register\n    case AM_G: // reg field of ModR/M selects a general register\n    case AM_P: // reg field of ModR/M selects an MMX register\n    case AM_R: // mod field of ModR/M may refer only to a general register\n    case AM_S: // reg field of ModR/M selects a segment register\n    case AM_T: // reg field of ModR/M selects a test register\n    case AM_V: // reg field of ModR/M selects a 128-bit XMM register\n      have_modrm_ = true;\n      break;\n\n    // In these addressing modes, there is a ModR/M byte and it needs to be\n    // decoded. No other (e.g. immediate) params than indicated in ModR/M.\n    case AM_E: // Operand is either a general-purpose register or memory,\n                 // specified by ModR/M byte\n    case AM_M: // ModR/M byte will refer only to memory\n    case AM_Q: // Operand is either an MMX register or memory (complex\n                 // evaluation), specified by ModR/M byte\n    case AM_W: // Operand is either a 128-bit XMM register or memory (complex\n                 // eval), specified by ModR/M byte\n      have_modrm_ = true;\n      should_decode_modrm_ = true;\n      break;\n\n    // These addressing modes specify an immediate or an offset value\n    // directly, so we need to look at the operand type to see how many\n    // bytes.\n    case AM_I: // Immediate data.\n    case AM_J: // Jump to offset.\n    case AM_O: // Operand is at offset.\n      switch (flag_operand & OT_MASK) {\n        case OT_B: // Byte regardless of operand-size attribute.\n          operand_bytes_ += OS_BYTE;\n          break;\n        case OT_C: // Byte or word, depending on operand-size attribute.\n          if (operand_is_32_bits_)\n            operand_bytes_ += OS_WORD;\n          else\n            operand_bytes_ += OS_BYTE;\n          break;\n        case OT_D: // Doubleword, regardless of operand-size attribute.\n          operand_bytes_ += OS_DOUBLE_WORD;\n          break;\n        case OT_DQ: // Double-quadword, regardless of operand-size attribute.\n          operand_bytes_ += OS_DOUBLE_QUAD_WORD;\n          break;\n        case OT_P: // 32-bit or 48-bit pointer, depending on operand-size\n                     // attribute.\n          if (operand_is_32_bits_)\n            operand_bytes_ += OS_48_BIT_POINTER;\n          else\n            operand_bytes_ += OS_32_BIT_POINTER;\n          break;\n        case OT_PS: // 128-bit packed single-precision floating-point data.\n          operand_bytes_ += OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING;\n          break;\n        case OT_Q: // Quadword, regardless of operand-size attribute.\n          operand_bytes_ += OS_QUAD_WORD;\n          break;\n        case OT_S: // 6-byte pseudo-descriptor.\n          operand_bytes_ += OS_PSEUDO_DESCRIPTOR;\n          break;\n        case OT_SD: // Scalar Double-Precision Floating-Point Value\n        case OT_PD: // Unaligned packed double-precision floating point value\n          operand_bytes_ += OS_DOUBLE_PRECISION_FLOATING;\n          break;\n        case OT_SS:\n          // Scalar element of a 128-bit packed single-precision\n          // floating data.\n          // We simply return enItUnknown since we don't have to support\n          // floating point\n          succeeded = false;\n          break;\n        case OT_V: // Word or doubleword, depending on operand-size attribute.\n          if (operand_is_32_bits_)\n            operand_bytes_ += OS_DOUBLE_WORD;\n          else\n            operand_bytes_ += OS_WORD;\n          break;\n        case OT_W: // Word, regardless of operand-size attribute.\n          operand_bytes_ += OS_WORD;\n          break;\n\n        // Can safely ignore these.\n        case OT_A: // Two one-word operands in memory or two double-word\n                     // operands in memory\n        case OT_PI: // Quadword MMX technology register (e.g. mm0)\n        case OT_SI: // Doubleword integer register (e.g., eax)\n          break;\n\n        default:\n          break;\n      }\n      break;\n\n    default:\n      break;\n  }\n\n  return succeeded;\n}\n\nbool MiniDisassembler::ProcessModrm(unsigned char* start_byte,\n                                    unsigned int& size) {\n  // If we don't need to decode, we just return the size of the ModR/M\n  // byte (there is never a SIB byte in this case).\n  if (!should_decode_modrm_) {\n    size++;\n    return true;\n  }\n\n  // We never care about the reg field, only the combination of the mod\n  // and r/m fields, so let's start by packing those fields together into\n  // 5 bits.\n  unsigned char modrm = (*start_byte);\n  unsigned char mod = modrm & 0xC0; // mask out top two bits to get mod field\n  modrm = modrm & 0x07; // mask out bottom 3 bits to get r/m field\n  mod = mod >> 3; // shift the mod field to the right place\n  modrm = mod | modrm; // combine the r/m and mod fields as discussed\n  mod = mod >> 3; // shift the mod field to bits 2..0\n\n  // Invariant: modrm contains the mod field in bits 4..3 and the r/m field\n  // in bits 2..0, and mod contains the mod field in bits 2..0\n\n  const ModrmEntry* modrm_entry = 0;\n  if (address_is_32_bits_)\n    modrm_entry = &s_ia32_modrm_map_[modrm];\n  else\n    modrm_entry = &s_ia16_modrm_map_[modrm];\n\n  // Invariant: modrm_entry points to information that we need to decode\n  // the ModR/M byte.\n\n  // Add to the count of operand bytes, if the ModR/M byte indicates\n  // that some operands are encoded in the instruction.\n  if (modrm_entry->is_encoded_in_instruction_)\n    operand_bytes_ += modrm_entry->operand_size_;\n\n  // Process the SIB byte if necessary, and return the count\n  // of ModR/M and SIB bytes.\n  if (modrm_entry->use_sib_byte_) {\n    size++;\n    return ProcessSib(start_byte + 1, mod, size);\n  } else {\n    size++;\n    return true;\n  }\n}\n\nbool MiniDisassembler::ProcessSib(unsigned char* start_byte,\n                                  unsigned char mod,\n                                  unsigned int& size) {\n  // get the mod field from the 2..0 bits of the SIB byte\n  unsigned char sib_base = (*start_byte) & 0x07;\n  if (0x05 == sib_base) {\n    switch (mod) {\n    case 0x00: // mod == 00\n    case 0x02: // mod == 10\n      operand_bytes_ += OS_DOUBLE_WORD;\n      break;\n    case 0x01: // mod == 01\n      operand_bytes_ += OS_BYTE;\n      break;\n    case 0x03: // mod == 11\n      // According to the IA-32 docs, there does not seem to be a disp\n      // value for this value of mod\n    default:\n      break;\n    }\n  }\n\n  size++;\n  return true;\n}\n\n};  // namespace sidestep\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/mini_disassembler.h",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Definition of MiniDisassembler.\n */\n\n#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_\n#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_\n\n#include <windows.h>\n#include \"mini_disassembler_types.h\"\n\n// compatibility shim\n#include \"base/logging.h\"\n#define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)\n#define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)\n\nnamespace sidestep {\n\n// This small disassembler is very limited\n// in its functionality, and in fact does only the bare minimum required by the\n// preamble patching utility.  It may be useful for other purposes, however.\n//\n// The limitations include at least the following:\n//  -# No support for coprocessor opcodes, MMX, etc.\n//  -# No machine-readable identification of opcodes or decoding of\n//     assembly parameters. The name of the opcode (as a string) is given,\n//     however, to aid debugging.\n//\n// You may ask what this little disassembler actually does, then?  The answer is\n// that it does the following, which is exactly what the patching utility needs:\n//  -# Indicates if opcode is a jump (any kind) or a return (any kind)\n//     because this is important for the patching utility to determine if\n//     a function is too short or there are jumps too early in it for it\n//     to be preamble patched.\n//  -# The opcode length is always calculated, so that the patching utility\n//     can figure out where the next instruction starts, and whether it\n//     already has enough instructions to replace with the absolute jump\n//     to the patching code.\n//\n// The usage is quite simple; just create a MiniDisassembler and use its\n// Disassemble() method.\n//\n// If you would like to extend this disassembler, please refer to the\n// IA-32 Intel Architecture Software Developers Manual Volume 2:\n// Instruction Set Reference for information about operand decoding\n// etc.\nclass MiniDisassembler {\n public:\n\n  // Creates a new instance and sets defaults.\n  //\n  // @param operand_default_32_bits If true, the default operand size is\n  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.\n  // @param address_default_32_bits If true, the default address size is\n  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.\n  MiniDisassembler(bool operand_default_32_bits,\n                   bool address_default_32_bits);\n\n  // Equivalent to MiniDisassembler(true, true);\n  MiniDisassembler();\n\n  // Attempts to disassemble a single instruction starting from the\n  // address in memory it is pointed to.\n  //\n  // @param start Address where disassembly should start.\n  // @param instruction_bytes Variable that will be <b>incremented</b> by\n  // the length in bytes of the instruction.\n  // @return enItJump, enItReturn or enItGeneric on success.  enItUnknown\n  // if unable to disassemble, enItUnused if this seems to be an unused\n  // opcode. In the last two (error) cases, cbInstruction will be set\n  // to 0xffffffff.\n  //\n  // @post This instance of the disassembler is ready to be used again,\n  // with unchanged defaults from creation time.\n  InstructionType Disassemble(unsigned char* start, unsigned int& instruction_bytes);\n\n private:\n\n  // Makes the disassembler ready for reuse.\n  void Initialize();\n\n  // Sets the flags for address and operand sizes.\n  // @return Number of prefix bytes.\n  InstructionType ProcessPrefixes(unsigned char* start, unsigned int& size);\n\n  // Sets the flag for whether we have ModR/M, and increments\n  // operand_bytes_ if any are specifies by the opcode directly.\n  // @return Number of opcode bytes.\n  InstructionType ProcessOpcode(unsigned char* start,\n                                unsigned int table,\n                                unsigned int& size);\n\n  // Checks the type of the supplied operand.  Increments\n  // operand_bytes_ if it directly indicates an immediate etc.\n  // operand.  Asserts have_modrm_ if the operand specifies\n  // a ModR/M byte.\n  bool ProcessOperand(int flag_operand);\n\n  // Increments operand_bytes_ by size specified by ModR/M and\n  // by SIB if present.\n  // @return 0 in case of error, 1 if there is just a ModR/M byte,\n  // 2 if there is a ModR/M byte and a SIB byte.\n  bool ProcessModrm(unsigned char* start, unsigned int& size);\n\n  // Processes the SIB byte that it is pointed to.\n  // @param start Pointer to the SIB byte.\n  // @param mod The mod field from the ModR/M byte.\n  // @return 1 to indicate success (indicates 1 SIB byte)\n  bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int& size);\n\n  // The instruction type we have decoded from the opcode.\n  InstructionType instruction_type_;\n\n  // Counts the number of bytes that is occupied by operands in\n  // the current instruction (note: we don't care about how large\n  // operands stored in registers etc. are).\n  unsigned int operand_bytes_;\n\n  // True iff there is a ModR/M byte in this instruction.\n  bool have_modrm_;\n\n  // True iff we need to decode the ModR/M byte (sometimes it just\n  // points to a register, we can tell by the addressing mode).\n  bool should_decode_modrm_;\n\n  // Current operand size is 32 bits if true, 16 bits if false.\n  bool operand_is_32_bits_;\n\n  // Default operand size is 32 bits if true, 16 bits if false.\n  bool operand_default_is_32_bits_;\n\n  // Current address size is 32 bits if true, 16 bits if false.\n  bool address_is_32_bits_;\n\n  // Default address size is 32 bits if true, 16 bits if false.\n  bool address_default_is_32_bits_;\n\n  // Huge big opcode table based on the IA-32 manual, defined\n  // in Ia32OpcodeMap.cc\n  static const OpcodeTable s_ia32_opcode_map_[];\n\n  // Somewhat smaller table to help with decoding ModR/M bytes\n  // when 16-bit addressing mode is being used.  Defined in\n  // Ia32ModrmMap.cc\n  static const ModrmEntry s_ia16_modrm_map_[];\n\n  // Somewhat smaller table to help with decoding ModR/M bytes\n  // when 32-bit addressing mode is being used.  Defined in\n  // Ia32ModrmMap.cc\n  static const ModrmEntry s_ia32_modrm_map_[];\n\n  // Indicators of whether we got certain prefixes that certain\n  // silly Intel instructions depend on in nonstandard ways for\n  // their behaviors.\n  bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_;\n};\n\n};  // namespace sidestep\n\n#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/mini_disassembler_types.h",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Several simple types used by the disassembler and some of the patching\n * mechanisms.\n */\n\n#ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_\n#define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_\n\nnamespace sidestep {\n\n// Categories of instructions that we care about\nenum InstructionType {\n  // This opcode is not used\n  IT_UNUSED,\n  // This disassembler does not recognize this opcode (error)\n  IT_UNKNOWN,\n  // This is not an instruction but a reference to another table\n  IT_REFERENCE,\n  // This byte is a prefix byte that we can ignore\n  IT_PREFIX,\n  // This is a prefix byte that switches to the nondefault address size\n  IT_PREFIX_ADDRESS,\n  // This is a prefix byte that switches to the nondefault operand size\n  IT_PREFIX_OPERAND,\n  // A jump or call instruction\n  IT_JUMP,\n  // A return instruction\n  IT_RETURN,\n  // Any other type of instruction (in this case we don't care what it is)\n  IT_GENERIC,\n};\n\n// Lists IA-32 operand sizes in multiples of 8 bits\nenum OperandSize {\n  OS_ZERO = 0,\n  OS_BYTE = 1,\n  OS_WORD = 2,\n  OS_DOUBLE_WORD = 4,\n  OS_QUAD_WORD = 8,\n  OS_DOUBLE_QUAD_WORD = 16,\n  OS_32_BIT_POINTER = 32/8,\n  OS_48_BIT_POINTER = 48/8,\n  OS_SINGLE_PRECISION_FLOATING = 32/8,\n  OS_DOUBLE_PRECISION_FLOATING = 64/8,\n  OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,\n  OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,\n  OS_PSEUDO_DESCRIPTOR = 6\n};\n\n// Operand addressing methods from the IA-32 manual.  The enAmMask value\n// is a mask for the rest.  The other enumeration values are named for the\n// names given to the addressing methods in the manual, e.g. enAm_D is for\n// the D addressing method.\n//\n// The reason we use a full 4 bytes and a mask, is that we need to combine\n// these flags with the enOperandType to store the details\n// on the operand in a single integer.\nenum AddressingMethod {\n  AM_NOT_USED = 0,        // This operand is not used for this instruction\n  AM_MASK = 0x00FF0000,  // Mask for the rest of the values in this enumeration\n  AM_A = 0x00010000,    // A addressing type\n  AM_C = 0x00020000,    // C addressing type\n  AM_D = 0x00030000,    // D addressing type\n  AM_E = 0x00040000,    // E addressing type\n  AM_F = 0x00050000,    // F addressing type\n  AM_G = 0x00060000,    // G addressing type\n  AM_I = 0x00070000,    // I addressing type\n  AM_J = 0x00080000,    // J addressing type\n  AM_M = 0x00090000,    // M addressing type\n  AM_O = 0x000A0000,    // O addressing type\n  AM_P = 0x000B0000,    // P addressing type\n  AM_Q = 0x000C0000,    // Q addressing type\n  AM_R = 0x000D0000,    // R addressing type\n  AM_S = 0x000E0000,    // S addressing type\n  AM_T = 0x000F0000,    // T addressing type\n  AM_V = 0x00100000,    // V addressing type\n  AM_W = 0x00110000,    // W addressing type\n  AM_X = 0x00120000,    // X addressing type\n  AM_Y = 0x00130000,    // Y addressing type\n  AM_REGISTER = 0x00140000,  // Specific register is always used as this op\n  AM_IMPLICIT = 0x00150000,  // An implicit, fixed value is used\n};\n\n// Operand types from the IA-32 manual. The enOtMask value is\n// a mask for the rest. The rest of the values are named for the\n// names given to these operand types in the manual, e.g. enOt_ps\n// is for the ps operand type in the manual.\n//\n// The reason we use a full 4 bytes and a mask, is that we need\n// to combine these flags with the enAddressingMethod to store the details\n// on the operand in a single integer.\nenum OperandType {\n  OT_MASK = 0xFF000000,\n  OT_A = 0x01000000,\n  OT_B = 0x02000000,\n  OT_C = 0x03000000,\n  OT_D = 0x04000000,\n  OT_DQ = 0x05000000,\n  OT_P = 0x06000000,\n  OT_PI = 0x07000000,\n  OT_PS = 0x08000000,  // actually unsupported for (we don't know its size)\n  OT_Q = 0x09000000,\n  OT_S = 0x0A000000,\n  OT_SS = 0x0B000000,\n  OT_SI = 0x0C000000,\n  OT_V = 0x0D000000,\n  OT_W = 0x0E000000,\n  OT_SD = 0x0F000000,  // scalar double-precision floating-point value\n  OT_PD = 0x10000000,  // double-precision floating point\n  // dummy \"operand type\" for address mode M - which doesn't specify\n  // operand type\n  OT_ADDRESS_MODE_M = 0x80000000\n};\n\n// Everything that's in an Opcode (see below) except the three\n// alternative opcode structs for different prefixes.\nstruct SpecificOpcode {\n  // Index to continuation table, or 0 if this is the last\n  // byte in the opcode.\n  int table_index_;\n\n  // The opcode type\n  InstructionType type_;\n\n  // Description of the type of the dest, src and aux operands,\n  // put together from an enOperandType flag and an enAddressingMethod\n  // flag.\n  int flag_dest_;\n  int flag_source_;\n  int flag_aux_;\n\n  // We indicate the mnemonic for debugging purposes\n  const char* mnemonic_;\n};\n\n// The information we keep in our tables about each of the different\n// valid instructions recognized by the IA-32 architecture.\nstruct Opcode {\n  // Index to continuation table, or 0 if this is the last\n  // byte in the opcode.\n  int table_index_;\n\n  // The opcode type\n  InstructionType type_;\n\n  // Description of the type of the dest, src and aux operands,\n  // put together from an enOperandType flag and an enAddressingMethod\n  // flag.\n  int flag_dest_;\n  int flag_source_;\n  int flag_aux_;\n\n  // We indicate the mnemonic for debugging purposes\n  const char* mnemonic_;\n\n  // Alternative opcode info if certain prefixes are specified.\n  // In most cases, all of these are zeroed-out.  Only used if\n  // bPrefixDependent is true.\n  bool is_prefix_dependent_;\n  SpecificOpcode opcode_if_f2_prefix_;\n  SpecificOpcode opcode_if_f3_prefix_;\n  SpecificOpcode opcode_if_66_prefix_;\n};\n\n// Information about each table entry.\nstruct OpcodeTable {\n  // Table of instruction entries\n  const Opcode* table_;\n  // How many bytes left to shift ModR/M byte <b>before</b> applying mask\n  unsigned char shift_;\n  // Mask to apply to byte being looked at before comparing to table\n  unsigned char mask_;\n  // Minimum/maximum indexes in table.\n  unsigned char min_lim_;\n  unsigned char max_lim_;\n};\n\n// Information about each entry in table used to decode ModR/M byte.\nstruct ModrmEntry {\n  // Is the operand encoded as bytes in the instruction (rather than\n  // if it's e.g. a register in which case it's just encoded in the\n  // ModR/M byte)\n  bool is_encoded_in_instruction_;\n\n  // Is there a SIB byte?  In this case we always need to decode it.\n  bool use_sib_byte_;\n\n  // What is the size of the operand (only important if it's encoded\n  // in the instruction)?\n  OperandSize operand_size_;\n};\n\n};  // namespace sidestep\n\n#endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/nm-pdb.c",
    "content": "/* Copyright (c) 2008, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: David Vitek\n *\n * Dump function addresses using Microsoft debug symbols.  This works\n * on PDB files.  Note that this program will download symbols to\n * c:\\websymbols without asking.\n */\n\n#define WIN32_LEAN_AND_MEAN\n#define _CRT_SECURE_NO_WARNINGS\n#define _CRT_SECURE_NO_DEPRECATE\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>   // for _strdup\n\n#include <windows.h>\n#include <dbghelp.h>\n\n// Unfortunately, there is no versioning info in dbghelp.h so I can\n// tell whether it has an old-style (circa VC7.1) IMAGEHLP_MODULE64\n// struct, with only a few fields, or a new-style (circa VC8)\n// IMAGEHLP_MODULE64, with lots of fields.  These fields are just used\n// for debugging, so it's fine to just assume the smaller struct, but\n// for most people, using a modern MSVC, the full struct is available.\n// If you are one of those people and would like this extra debugging\n// info, you can uncomment the line below.\n//#define VC8_OR_ABOVE\n\n#define SEARCH_CAP (1024*1024)\n#define WEBSYM \"SRV*c:\\\\websymbols*http://msdl.microsoft.com/download/symbols\"\n\ntypedef struct {\n  char *name;\n  ULONG64 addr;\n  ULONG flags;\n} SYM;\n\ntypedef struct {\n  ULONG64 module_base;\n  SYM *syms;\n  DWORD syms_len;\n  DWORD syms_cap;\n} SYM_CONTEXT;\n\nstatic int sym_cmp(const void *_s1, const void *_s2) {\n  const SYM *s1 = (const SYM *)_s1;\n  const SYM *s2 = (const SYM *)_s2;\n\n  if (s1->addr < s2->addr)\n    return -1;\n  if (s1->addr > s2->addr)\n    return 1;\n  return 0;\n}\n\nstatic BOOL CALLBACK EnumSymProc(PSYMBOL_INFO symbol_info,\n                                 ULONG symbol_size,\n                                 PVOID user_context) {\n  SYM_CONTEXT *ctx = (SYM_CONTEXT*)user_context;\n  if (symbol_info->Address < ctx->module_base ||\n      (symbol_info->Flags & SYMFLAG_TLSREL)) {\n    return TRUE;\n  }\n  if (ctx->syms_len == ctx->syms_cap) {\n    if (!ctx->syms_cap)\n      ctx->syms_cap++;\n    ctx->syms_cap *= 2;\n    ctx->syms = realloc(ctx->syms, sizeof(ctx->syms[0]) * ctx->syms_cap);\n  }\n  ctx->syms[ctx->syms_len].name = _strdup(symbol_info->Name);\n  ctx->syms[ctx->syms_len].addr = symbol_info->Address;\n  ctx->syms[ctx->syms_len].flags = symbol_info->Flags;\n  ctx->syms_len++;\n  return TRUE;\n}\n\nstatic void MaybePrint(const char* var, const char* description) {\n  if (var[0])\n    printf(\"%s: %s\\n\", description, var);\n}\n\nstatic void PrintAvailability(BOOL var, const char *description) {\n  printf(\"s: %s\\n\", description, (var ? \"Available\" : \"Not available\"));\n}\n\nstatic void ShowSymbolInfo(HANDLE process, ULONG64 module_base) {\n  /* Get module information. */\n  IMAGEHLP_MODULE64 module_info;\n  BOOL getmoduleinfo_rv;\n  printf(\"Load Address: %I64x\\n\", module_base);\n  memset(&module_info, 0, sizeof(module_info));\n  module_info.SizeOfStruct = sizeof(module_info);\n  getmoduleinfo_rv = SymGetModuleInfo64(process, module_base, &module_info);\n  if (!getmoduleinfo_rv)  {\n    printf(\"Error: SymGetModuleInfo64() failed. Error code: %u\\n\",\n           GetLastError());\n    return;\n  }\n  /* Display information about symbols, based on kind of symbol. */\n  switch (module_info.SymType)  {\n    case SymNone:\n      printf((\"No symbols available for the module.\\n\"));\n      break;\n    case SymExport:\n      printf((\"Loaded symbols: Exports\\n\"));\n      break;\n    case SymCoff:\n      printf((\"Loaded symbols: COFF\\n\"));\n      break;\n    case SymCv:\n      printf((\"Loaded symbols: CodeView\\n\"));\n      break;\n    case SymSym:\n      printf((\"Loaded symbols: SYM\\n\"));\n      break;\n    case SymVirtual:\n      printf((\"Loaded symbols: Virtual\\n\"));\n      break;\n    case SymPdb:\n      printf((\"Loaded symbols: PDB\\n\"));\n      break;\n    case SymDia:\n      printf((\"Loaded symbols: DIA\\n\"));\n      break;\n    case SymDeferred:\n      printf((\"Loaded symbols: Deferred\\n\"));  /* not actually loaded */\n      break;\n    default:\n      printf((\"Loaded symbols: Unknown format.\\n\"));\n      break;\n  }\n\n  MaybePrint(\"Image name\", module_info.ImageName);\n  MaybePrint(\"Loaded image name\", module_info.LoadedImageName);\n#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */\n  MaybePrint(\"PDB file name\", module_info.LoadedPdbName);\n  if (module_info.PdbUnmatched || module_info.DbgUnmatched)  {\n    /* This can only happen if the debug information is contained in a\n     * separate file (.DBG or .PDB)\n     */\n    printf((\"Warning: Unmatched symbols.\\n\"));\n  }\n#endif\n\n  /* Contents */\n#ifdef VC8_OR_ABOVE   /* TODO(csilvers): figure out how to tell */\n  PrintAvailability(\"Line numbers\", module_info.LineNumbers);\n  PrintAvailability(\"Global symbols\", module_info.GlobalSymbols);\n  PrintAvailability(\"Type information\", module_info.TypeInfo);\n#endif\n}\n\nvoid usage() {\n  fprintf(stderr, \"usage: nm-pdb [-C|--demangle] <module or filename>\\n\");\n}\n\nint main(int argc, char *argv[]) {\n  DWORD  error;\n  HANDLE process;\n  ULONG64 module_base;\n  SYM_CONTEXT ctx;\n  int i;\n  char* search;\n  char* filename = NULL;\n  int rv = 0;\n  /* We may add SYMOPT_UNDNAME if --demangle is specified: */\n  DWORD symopts = SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG;\n\n  for (i = 1; i < argc; i++) {\n    if (strcmp(argv[i], \"--demangle\") == 0 || strcmp(argv[i], \"-C\") == 0) {\n      symopts |= SYMOPT_UNDNAME;\n    } else if (strcmp(argv[i], \"--help\") == 0) {\n      usage();\n      exit(0);\n    } else {\n      break;\n    }\n  }\n  if (i != argc - 1) {\n    usage();\n    exit(1);\n  }\n  filename = argv[i];\n\n  process = GetCurrentProcess();\n\n  if (!SymInitialize(process, NULL, FALSE)) {\n    error = GetLastError();\n    fprintf(stderr, \"SymInitialize returned error : %d\\n\", error);\n    return 1;\n  }\n\n  search = malloc(SEARCH_CAP);\n  if (SymGetSearchPath(process, search, SEARCH_CAP)) {\n    if (strlen(search) + sizeof(\";\" WEBSYM) > SEARCH_CAP) {\n      fprintf(stderr, \"Search path too long\\n\");\n      SymCleanup(process);\n      return 1;\n    }\n    strcat(search, \";\" WEBSYM);\n  } else {\n    error = GetLastError();\n    fprintf(stderr, \"SymGetSearchPath returned error : %d\\n\", error);\n    rv = 1;                   /* An error, but not a fatal one */\n    strcpy(search, WEBSYM);   /* Use a default value */\n  }\n  if (!SymSetSearchPath(process, search)) {\n    error = GetLastError();\n    fprintf(stderr, \"SymSetSearchPath returned error : %d\\n\", error);\n    rv = 1;                   /* An error, but not a fatal one */\n }\n\n  SymSetOptions(symopts);\n  module_base = SymLoadModuleEx(process, NULL, filename, NULL, 0, 0, NULL, 0);\n  if (!module_base) {\n    /* SymLoadModuleEx failed */\n    error = GetLastError();\n    fprintf(stderr, \"SymLoadModuleEx returned error : %d for %s\\n\",\n            error, filename);\n    SymCleanup(process);\n    return 1;\n  }\n\n  ShowSymbolInfo(process, module_base);\n\n  memset(&ctx, 0, sizeof(ctx));\n  ctx.module_base = module_base;\n  if (!SymEnumSymbols(process, module_base, NULL, EnumSymProc, &ctx)) {\n    error = GetLastError();\n    fprintf(stderr, \"SymEnumSymbols returned error: %d\\n\", error);\n    rv = 1;\n  } else {\n    DWORD j;\n    qsort(ctx.syms, ctx.syms_len, sizeof(ctx.syms[0]), sym_cmp);\n    for (j = 0; j < ctx.syms_len; j++) {\n      printf(\"%016I64x X %s\\n\", ctx.syms[j].addr, ctx.syms[j].name);\n    }\n    /* In a perfect world, maybe we'd clean up ctx's memory? */\n  }\n  SymUnloadModule64(process, module_base);\n  SymCleanup(process);\n  return rv;\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/override_functions.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// ---\n// Author: Mike Belshe\n// \n// To link tcmalloc into a EXE or DLL statically without using the patching\n// facility, we can take a stock libcmt and remove all the allocator functions.\n// When we relink the EXE/DLL with the modified libcmt and tcmalloc, a few\n// functions are missing.  This file contains the additional overrides which\n// are required in the VS2005 libcmt in order to link the modified libcmt.\n//\n// See also\n// http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b\n\n#include <config.h>\n\n#ifndef _WIN32\n# error You should only be including this file in a windows environment!\n#endif\n\n#ifndef WIN32_OVERRIDE_ALLOCATORS\n# error This file is intended for use when overriding allocators\n#endif\n\n#include \"tcmalloc.cc\"\n\nextern \"C\" void* _recalloc(void* p, size_t n, size_t size) {\n  void* result = realloc(p, n * size);\n  memset(result, 0, n * size);\n  return result;\n}\n\nextern \"C\" void* _calloc_impl(size_t n, size_t size) {\n  return calloc(n, size);\n}\n\nextern \"C\" size_t _msize(void* p) {\n  return MallocExtension::instance()->GetAllocatedSize(p);\n}\n\nextern \"C\" intptr_t _get_heap_handle() {\n  return 0;\n}\n\n// The CRT heap initialization stub.\nextern \"C\" int _heap_init() {\n  // We intentionally leak this object.  It lasts for the process\n  // lifetime.  Trying to teardown at _heap_term() is so late that\n  // you can't do anything useful anyway.\n  new TCMallocGuard();\n  return 1;\n}\n\n// The CRT heap cleanup stub.\nextern \"C\" void _heap_term() {\n}\n\nextern \"C\" int _set_new_mode(int flag) {\n  return tc_set_new_mode(flag);\n}\n\n#ifndef NDEBUG\n#undef malloc\n#undef free\n#undef calloc\nint _CrtDbgReport(int, const char*, int, const char*, const char*, ...) {\n  return 0;\n}\n\nint _CrtDbgReportW(int, const wchar_t*, int, const wchar_t*, const wchar_t*, ...) {\n  return 0;\n}\n\nint _CrtSetReportMode(int, int) {\n  return 0;\n}\n\nextern \"C\" void* _malloc_dbg(size_t size, int , const char*, int) {\n  return malloc(size);\n}\n\nextern \"C\" void _free_dbg(void* ptr, int) {\n  free(ptr);\n}\n\nextern \"C\" void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {\n  return calloc(n, size);\n}\n#endif  // NDEBUG\n\n// We set this to 1 because part of the CRT uses a check of _crtheap != 0\n// to test whether the CRT has been initialized.  Once we've ripped out\n// the allocators from libcmt, we need to provide this definition so that\n// the rest of the CRT is still usable.\nextern \"C\" void* _crtheap = reinterpret_cast<void*>(1);\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/patch_functions.cc",
    "content": "// Copyright (c) 2007, Google Inc.\n// All rights reserved.\n// \n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n// \n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n// \n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// ---\n// Author: Craig Silverstein\n//\n// The main purpose of this file is to patch the libc allocation\n// routines (malloc and friends, but also _msize and other\n// windows-specific libc-style routines).  However, we also patch\n// windows routines to do accounting.  We do better at the former than\n// the latter.  Here are some comments from Paul Pluzhnikov about what\n// it might take to do a really good job patching windows routines to\n// keep track of memory usage:\n//\n// \"You should intercept at least the following:\n//     HeapCreate HeapDestroy HeapAlloc HeapReAlloc HeapFree\n//     RtlCreateHeap RtlDestroyHeap RtlAllocateHeap RtlFreeHeap\n//     malloc calloc realloc free\n//     malloc_dbg calloc_dbg realloc_dbg free_dbg\n// Some of these call the other ones (but not always), sometimes\n// recursively (i.e. HeapCreate may call HeapAlloc on a different\n// heap, IIRC).\"\n//\n// Since Paul didn't mention VirtualAllocEx, he may not have even been\n// considering all the mmap-like functions that windows has (or he may\n// just be ignoring it because he's seen we already patch it).  Of the\n// above, we do not patch the *_dbg functions, and of the windows\n// functions, we only patch HeapAlloc and HeapFree.\n//\n// The *_dbg functions come into play with /MDd, /MTd, and /MLd,\n// probably.  It may be ok to just turn off tcmalloc in those cases --\n// if the user wants the windows debug malloc, they probably don't\n// want tcmalloc!  We should also test with all of /MD, /MT, and /ML,\n// which we're not currently doing.\n\n// TODO(csilvers): try to do better here?  Paul does conclude:\n//                 \"Keeping track of all of this was a nightmare.\"\n\n#ifndef _WIN32\n# error You should only be including windows/patch_functions.cc in a windows environment!\n#endif\n\n#include <config.h>\n\n#ifdef WIN32_OVERRIDE_ALLOCATORS\n#error This file is intended for patching allocators - use override_functions.cc instead.\n#endif\n\n// We use psapi.  Non-MSVC systems will have to link this in themselves.\n#ifdef _MSC_VER\n#pragma comment(lib, \"Psapi.lib\")\n#endif\n\n// Make sure we always use the 'old' names of the psapi functions.\n#ifndef PSAPI_VERSION\n#define PSAPI_VERSION 1\n#endif\n\n#include <windows.h>\n#include <stdio.h>\n#include <malloc.h>       // for _msize and _expand\n#include <Psapi.h>        // for EnumProcessModules, GetModuleInformation, etc.\n#include <set>\n#include <map>\n#include <vector>\n#include <base/logging.h>\n#include \"base/spinlock.h\"\n#include \"google/malloc_hook.h\"\n#include \"malloc_hook-inl.h\"\n#include \"preamble_patcher.h\"\n\n// The maximum number of modules we allow to be in one executable\nconst int kMaxModules = 8182;\n\n// These are hard-coded, unfortunately. :-( They are also probably\n// compiler specific.  See get_mangled_names.cc, in this directory,\n// for instructions on how to update these names for your compiler.\nconst char kMangledNew[] = \"??2@YAPAXI@Z\";\nconst char kMangledNewArray[] = \"??_U@YAPAXI@Z\";\nconst char kMangledDelete[] = \"??3@YAXPAX@Z\";\nconst char kMangledDeleteArray[] = \"??_V@YAXPAX@Z\";\nconst char kMangledNewNothrow[] = \"??2@YAPAXIABUnothrow_t@std@@@Z\";\nconst char kMangledNewArrayNothrow[] = \"??_U@YAPAXIABUnothrow_t@std@@@Z\";\nconst char kMangledDeleteNothrow[] = \"??3@YAXPAXABUnothrow_t@std@@@Z\";\nconst char kMangledDeleteArrayNothrow[] = \"??_V@YAXPAXABUnothrow_t@std@@@Z\";\n\n// This is an unused but exported symbol that we can use to tell the\n// MSVC linker to bring in libtcmalloc, via the /INCLUDE linker flag.\n// Without this, the linker will likely decide that libtcmalloc.dll\n// doesn't add anything to the executable (since it does all its work\n// through patching, which the linker can't see), and ignore it\n// entirely.  (The name 'tcmalloc' is already reserved for a\n// namespace.  I'd rather export a variable named \"_tcmalloc\", but I\n// couldn't figure out how to get that to work.  This function exports\n// the symbol \"__tcmalloc\".)\nextern \"C\" PERFTOOLS_DLL_DECL void _tcmalloc();\nvoid _tcmalloc() { }\n\nnamespace {    // most everything here is in an unnamed namespace\n\ntypedef void (*GenericFnPtr)();\n\nusing sidestep::PreamblePatcher;\n\nstruct ModuleEntryCopy;   // defined below\n\n// These functions are how we override the memory allocation\n// functions, just like tcmalloc.cc and malloc_hook.cc do.\n\n// This is information about the routines we're patching, for a given\n// module that implements libc memory routines.  A single executable\n// can have several libc implementations running about (in different\n// .dll's), and we need to patch/unpatch them all.  This defines\n// everything except the new functions we're patching in, which\n// are defined in LibcFunctions, below.\nclass LibcInfo {\n public:\n  LibcInfo() {\n    memset(this, 0, sizeof(*this));  // easiest way to initialize the array\n  }\n\n  bool patched() const { return is_valid(); }\n  void set_is_valid(bool b) { is_valid_ = b; }\n  // According to http://msdn.microsoft.com/en-us/library/ms684229(VS.85).aspx:\n  // \"The load address of a module (lpBaseOfDll) is the same as the HMODULE\n  // value.\"\n  HMODULE hmodule() const {\n    return reinterpret_cast<HMODULE>(const_cast<void*>(module_base_address_));\n  }\n\n  // Populates all the windows_fn_[] vars based on our module info.\n  // Returns false if windows_fn_ is all NULL's, because there's\n  // nothing to patch.  Also populates the rest of the module_entry\n  // info, such as the module's name.\n  bool PopulateWindowsFn(const ModuleEntryCopy& module_entry);\n\n protected:\n  void CopyFrom(const LibcInfo& that) {\n    if (this == &that)\n      return;\n    this->is_valid_ = that.is_valid_;\n    memcpy(this->windows_fn_, that.windows_fn_, sizeof(windows_fn_));\n    this->module_base_address_ = that.module_base_address_;\n    this->module_base_size_ = that.module_base_size_;\n  }\n\n  enum {\n    kMalloc, kFree, kRealloc, kCalloc,\n    kNew, kNewArray, kDelete, kDeleteArray,\n    kNewNothrow, kNewArrayNothrow, kDeleteNothrow, kDeleteArrayNothrow,\n    // These are windows-only functions from malloc.h\n    k_Msize, k_Expand,\n    kNumFunctions\n  };\n\n  // I'd like to put these together in a struct (perhaps in the\n  // subclass, so we can put in perftools_fn_ as well), but vc8 seems\n  // to have a bug where it doesn't initialize the struct properly if\n  // we try to take the address of a function that's not yet loaded\n  // from a dll, as is the common case for static_fn_.  So we need\n  // each to be in its own array. :-(\n  static const char* const function_name_[kNumFunctions];\n\n  // This function is only used when statically linking the binary.\n  // In that case, loading malloc/etc from the dll (via\n  // PatchOneModule) won't work, since there are no dlls.  Instead,\n  // you just want to be taking the address of malloc/etc directly.\n  // In the common, non-static-link case, these pointers will all be\n  // NULL, since this initializer runs before msvcrt.dll is loaded.\n  static const GenericFnPtr static_fn_[kNumFunctions];\n\n  // This is the address of the function we are going to patch\n  // (malloc, etc).  Other info about the function is in the\n  // patch-specific subclasses, below.\n  GenericFnPtr windows_fn_[kNumFunctions];\n\n  // This is set to true when this structure is initialized (because\n  // we're patching a new library) and set to false when it's\n  // uninitialized (because we've freed that library).\n  bool is_valid_;\n\n  const void *module_base_address_;\n  size_t module_base_size_;\n\n public:\n  // These shouldn't have to be public, since only subclasses of\n  // LibcInfo need it, but they do.  Maybe something to do with\n  // templates.  Shrug.  I hide them down here so users won't see\n  // them. :-)  (OK, I also need to define ctrgProcAddress late.)\n  bool is_valid() const { return is_valid_; }\n  GenericFnPtr windows_fn(int ifunction) const {\n    return windows_fn_[ifunction];\n  }\n  // These three are needed by ModuleEntryCopy.\n  static const int ctrgProcAddress = kNumFunctions;\n  static GenericFnPtr static_fn(int ifunction) {\n    return static_fn_[ifunction];\n  }\n  static const char* const function_name(int ifunction) {\n    return function_name_[ifunction];\n  }\n};\n\n// Template trickiness: logically, a LibcInfo would include\n// Windows_malloc_, origstub_malloc_, and Perftools_malloc_: for a\n// given module, these three go together.  And in fact,\n// Perftools_malloc_ may need to call origstub_malloc_, which means we\n// either need to change Perftools_malloc_ to take origstub_malloc_ as\n// an arugment -- unfortunately impossible since it needs to keep the\n// same API as normal malloc -- or we need to write a different\n// version of Perftools_malloc_ for each LibcInfo instance we create.\n// We choose the second route, and use templates to implement it (we\n// could have also used macros).  So to get multiple versions\n// of the struct, we say \"struct<1> var1; struct<2> var2;\".  The price\n// we pay is some code duplication, and more annoying, each instance\n// of this var is a separate type.\ntemplate<int> class LibcInfoWithPatchFunctions : public LibcInfo {\n public:\n  // me_info should have had PopulateWindowsFn() called on it, so the\n  // module_* vars and windows_fn_ are set up.\n  bool Patch(const LibcInfo& me_info);\n  void Unpatch();\n\n private:\n  // This holds the original function contents after we patch the function.\n  // This has to be defined static in the subclass, because the perftools_fns\n  // reference origstub_fn_.\n  static GenericFnPtr origstub_fn_[kNumFunctions];\n\n  // This is the function we want to patch in\n  static const GenericFnPtr perftools_fn_[kNumFunctions];\n\n  static void* Perftools_malloc(size_t size) __THROW;\n  static void Perftools_free(void* ptr) __THROW;\n  static void* Perftools_realloc(void* ptr, size_t size) __THROW;\n  static void* Perftools_calloc(size_t nmemb, size_t size) __THROW;\n  static void* Perftools_new(size_t size);\n  static void* Perftools_newarray(size_t size);\n  static void Perftools_delete(void *ptr);\n  static void Perftools_deletearray(void *ptr);\n  static void* Perftools_new_nothrow(size_t size,\n                                     const std::nothrow_t&) __THROW;\n  static void* Perftools_newarray_nothrow(size_t size,\n                                          const std::nothrow_t&) __THROW;\n  static void Perftools_delete_nothrow(void *ptr,\n                                       const std::nothrow_t&) __THROW;\n  static void Perftools_deletearray_nothrow(void *ptr,\n                                            const std::nothrow_t&) __THROW;\n  static size_t Perftools__msize(void *ptr) __THROW;\n  static void* Perftools__expand(void *ptr, size_t size) __THROW;\n  // malloc.h also defines these functions:\n  //   _aligned_malloc, _aligned_free,\n  //   _recalloc, _aligned_offset_malloc, _aligned_realloc, _aligned_recalloc\n  //   _aligned_offset_realloc, _aligned_offset_recalloc, _malloca, _freea\n  // But they seem pretty obscure, and I'm fine not overriding them for now.\n  // It may be they all call into malloc/free anyway.\n};\n\n// This is a subset of MODDULEENTRY32, that we need for patching.\nstruct ModuleEntryCopy {\n  LPVOID  modBaseAddr;     // the same as hmodule\n  DWORD   modBaseSize;\n  // This is not part of MODDULEENTRY32, but is needed to avoid making\n  // windows syscalls while we're holding patch_all_modules_lock (see\n  // lock-inversion comments at patch_all_modules_lock definition, below).\n  GenericFnPtr rgProcAddresses[LibcInfo::ctrgProcAddress];\n\n  ModuleEntryCopy() {\n    modBaseAddr = NULL;\n    modBaseSize = 0;\n    for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++)\n      rgProcAddresses[i] = LibcInfo::static_fn(i);\n  }\n  ModuleEntryCopy(const MODULEINFO& mi) {\n    this->modBaseAddr = mi.lpBaseOfDll;\n    this->modBaseSize = mi.SizeOfImage;\n    LPVOID modEndAddr = (char*)mi.lpBaseOfDll + mi.SizeOfImage;\n    for (int i = 0; i < sizeof(rgProcAddresses)/sizeof(*rgProcAddresses); i++) {\n      FARPROC target = ::GetProcAddress(\n          reinterpret_cast<const HMODULE>(mi.lpBaseOfDll),\n          LibcInfo::function_name(i));\n      // Sometimes a DLL forwards a function to a function in another\n      // DLL.  We don't want to patch those forwarded functions --\n      // they'll get patched when the other DLL is processed.\n      if (target >= modBaseAddr && target < modEndAddr)\n        rgProcAddresses[i] = (GenericFnPtr)target;\n      else\n        rgProcAddresses[i] = (GenericFnPtr)NULL;\n    }\n  }\n};\n\n// This class is easier because there's only one of them.\nclass WindowsInfo {\n public:\n  void Patch();\n  void Unpatch();\n\n private:\n  // TODO(csilvers): should we be patching GlobalAlloc/LocalAlloc instead,\n  //                 for pre-XP systems?\n  enum {\n    kHeapAlloc, kHeapFree, kVirtualAllocEx, kVirtualFreeEx,\n    kMapViewOfFileEx, kUnmapViewOfFile, kLoadLibraryExW, kFreeLibrary,\n    kNumFunctions\n  };\n\n  struct FunctionInfo {\n    const char* const name;          // name of fn in a module (eg \"malloc\")\n    GenericFnPtr windows_fn;         // the fn whose name we call (&malloc)\n    GenericFnPtr origstub_fn;        // original fn contents after we patch\n    const GenericFnPtr perftools_fn; // fn we want to patch in\n  };\n\n  static FunctionInfo function_info_[kNumFunctions];\n\n  // A Windows-API equivalent of malloc and free\n  static LPVOID WINAPI Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,\n                                           DWORD_PTR dwBytes);\n  static BOOL WINAPI Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,\n                                        LPVOID lpMem);\n  // A Windows-API equivalent of mmap and munmap, for \"anonymous regions\"\n  static LPVOID WINAPI Perftools_VirtualAllocEx(HANDLE process, LPVOID address,\n                                                SIZE_T size, DWORD type,\n                                                DWORD protect);\n  static BOOL WINAPI Perftools_VirtualFreeEx(HANDLE process, LPVOID address,\n                                             SIZE_T size, DWORD type);\n  // A Windows-API equivalent of mmap and munmap, for actual files\n  static LPVOID WINAPI Perftools_MapViewOfFileEx(HANDLE hFileMappingObject,\n                                                 DWORD dwDesiredAccess,\n                                                 DWORD dwFileOffsetHigh,\n                                                 DWORD dwFileOffsetLow,\n                                                 SIZE_T dwNumberOfBytesToMap,\n                                                 LPVOID lpBaseAddress);\n  static BOOL WINAPI Perftools_UnmapViewOfFile(LPCVOID lpBaseAddress);\n  // We don't need the other 3 variants because they all call this one. */\n  static HMODULE WINAPI Perftools_LoadLibraryExW(LPCWSTR lpFileName,\n                                                 HANDLE hFile,\n                                                 DWORD dwFlags);\n  static BOOL WINAPI Perftools_FreeLibrary(HMODULE hLibModule);\n};\n\n// If you run out, just add a few more to the array.  You'll also need\n// to update the switch statement in PatchOneModule(), and the list in\n// UnpatchWindowsFunctions().\n// main_executable and main_executable_windows are two windows into\n// the same executable.  One is responsible for patching the libc\n// routines that live in the main executable (if any) to use tcmalloc;\n// the other is responsible for patching the windows routines like\n// HeapAlloc/etc to use tcmalloc.\nstatic LibcInfoWithPatchFunctions<0> main_executable;\nstatic LibcInfoWithPatchFunctions<1> libc1;\nstatic LibcInfoWithPatchFunctions<2> libc2;\nstatic LibcInfoWithPatchFunctions<3> libc3;\nstatic LibcInfoWithPatchFunctions<4> libc4;\nstatic LibcInfoWithPatchFunctions<5> libc5;\nstatic LibcInfoWithPatchFunctions<6> libc6;\nstatic LibcInfoWithPatchFunctions<7> libc7;\nstatic LibcInfoWithPatchFunctions<8> libc8;\nstatic LibcInfo* g_module_libcs[] = {\n  &libc1, &libc2, &libc3, &libc4, &libc5, &libc6, &libc7, &libc8\n};\nstatic WindowsInfo main_executable_windows;\n\nconst char* const LibcInfo::function_name_[] = {\n  \"malloc\", \"free\", \"realloc\", \"calloc\",\n  kMangledNew, kMangledNewArray, kMangledDelete, kMangledDeleteArray,\n  // Ideally we should patch the nothrow versions of new/delete, but\n  // at least in msvcrt, nothrow-new machine-code is of a type we\n  // can't patch.  Since these are relatively rare, I'm hoping it's ok\n  // not to patch them.  (NULL name turns off patching.)\n  NULL,  // kMangledNewNothrow,\n  NULL,  // kMangledNewArrayNothrow,\n  NULL,  // kMangledDeleteNothrow,\n  NULL,  // kMangledDeleteArrayNothrow,\n  \"_msize\", \"_expand\",\n};\n\n// For mingw, I can't patch the new/delete here, because the\n// instructions are too small to patch.  Luckily, they're so small\n// because all they do is call into malloc/free, so they still end up\n// calling tcmalloc routines, and we don't actually lose anything\n// (except maybe some stacktrace goodness) by not patching.\nconst GenericFnPtr LibcInfo::static_fn_[] = {\n  (GenericFnPtr)&::malloc,\n  (GenericFnPtr)&::free,\n  (GenericFnPtr)&::realloc,\n  (GenericFnPtr)&::calloc,\n#ifdef __MINGW32__\n  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,\n#else\n  (GenericFnPtr)(void*(*)(size_t))&::operator new,\n  (GenericFnPtr)(void*(*)(size_t))&::operator new[],\n  (GenericFnPtr)(void(*)(void*))&::operator delete,\n  (GenericFnPtr)(void(*)(void*))&::operator delete[],\n  (GenericFnPtr)\n  (void*(*)(size_t, struct std::nothrow_t const &))&::operator new,\n  (GenericFnPtr)\n  (void*(*)(size_t, struct std::nothrow_t const &))&::operator new[],\n  (GenericFnPtr)\n  (void(*)(void*, struct std::nothrow_t const &))&::operator delete,\n  (GenericFnPtr)\n  (void(*)(void*, struct std::nothrow_t const &))&::operator delete[],\n#endif\n  (GenericFnPtr)&::_msize,\n  (GenericFnPtr)&::_expand,\n};\n\ntemplate<int T> GenericFnPtr LibcInfoWithPatchFunctions<T>::origstub_fn_[] = {\n  // This will get filled in at run-time, as patching is done.\n};\n\ntemplate<int T>\nconst GenericFnPtr LibcInfoWithPatchFunctions<T>::perftools_fn_[] = {\n  (GenericFnPtr)&Perftools_malloc,\n  (GenericFnPtr)&Perftools_free,\n  (GenericFnPtr)&Perftools_realloc,\n  (GenericFnPtr)&Perftools_calloc,\n  (GenericFnPtr)&Perftools_new,\n  (GenericFnPtr)&Perftools_newarray,\n  (GenericFnPtr)&Perftools_delete,\n  (GenericFnPtr)&Perftools_deletearray,\n  (GenericFnPtr)&Perftools_new_nothrow,\n  (GenericFnPtr)&Perftools_newarray_nothrow,\n  (GenericFnPtr)&Perftools_delete_nothrow,\n  (GenericFnPtr)&Perftools_deletearray_nothrow,\n  (GenericFnPtr)&Perftools__msize,\n  (GenericFnPtr)&Perftools__expand,\n};\n\n/*static*/ WindowsInfo::FunctionInfo WindowsInfo::function_info_[] = {\n  { \"HeapAlloc\", NULL, NULL, (GenericFnPtr)&Perftools_HeapAlloc },\n  { \"HeapFree\", NULL, NULL, (GenericFnPtr)&Perftools_HeapFree },\n  { \"VirtualAllocEx\", NULL, NULL, (GenericFnPtr)&Perftools_VirtualAllocEx },\n  { \"VirtualFreeEx\", NULL, NULL, (GenericFnPtr)&Perftools_VirtualFreeEx },\n  { \"MapViewOfFileEx\", NULL, NULL, (GenericFnPtr)&Perftools_MapViewOfFileEx },\n  { \"UnmapViewOfFile\", NULL, NULL, (GenericFnPtr)&Perftools_UnmapViewOfFile },\n  { \"LoadLibraryExW\", NULL, NULL, (GenericFnPtr)&Perftools_LoadLibraryExW },\n  { \"FreeLibrary\", NULL, NULL, (GenericFnPtr)&Perftools_FreeLibrary },\n};\n\nbool LibcInfo::PopulateWindowsFn(const ModuleEntryCopy& module_entry) {\n  // First, store the location of the function to patch before\n  // patching it.  If none of these functions are found in the module,\n  // then this module has no libc in it, and we just return false.\n  for (int i = 0; i < kNumFunctions; i++) {\n    if (!function_name_[i])     // we can turn off patching by unsetting name\n      continue;\n    // The ::GetProcAddress calls were done in the ModuleEntryCopy\n    // constructor, so we don't have to make any windows calls here.\n    const GenericFnPtr fn = module_entry.rgProcAddresses[i];\n    if (fn) {\n      windows_fn_[i] = PreamblePatcher::ResolveTarget(fn);\n    }\n  }\n\n  // Some modules use the same function pointer for new and new[].  If\n  // we find that, set one of the pointers to NULL so we don't double-\n  // patch.  Same may happen with new and nothrow-new, or even new[]\n  // and nothrow-new.  It's easiest just to check each fn-ptr against\n  // every other.\n  for (int i = 0; i < kNumFunctions; i++) {\n    for (int j = i+1; j < kNumFunctions; j++) {\n      if (windows_fn_[i] == windows_fn_[j]) {\n        // We NULL the later one (j), so as to minimize the chances we\n        // NULL kFree and kRealloc.  See comments below.  This is fragile!\n        windows_fn_[j] = NULL;\n      }\n    }\n  }\n\n  // There's always a chance that our module uses the same function\n  // as another module that we've already loaded.  In that case, we\n  // need to set our windows_fn to NULL, to avoid double-patching.\n  for (int ifn = 0; ifn < kNumFunctions; ifn++) {\n    for (int imod = 0;\n         imod < sizeof(g_module_libcs)/sizeof(*g_module_libcs);  imod++) {\n      if (g_module_libcs[imod]->is_valid() &&\n          this->windows_fn(ifn) == g_module_libcs[imod]->windows_fn(ifn)) {\n        windows_fn_[ifn] = NULL;\n      }\n    }\n  }\n\n  bool found_non_null = false;\n  for (int i = 0; i < kNumFunctions; i++) {\n    if (windows_fn_[i])\n      found_non_null = true;\n  }\n  if (!found_non_null)\n    return false;\n\n  // It's important we didn't NULL out windows_fn_[kFree] or [kRealloc].\n  // The reason is, if those are NULL-ed out, we'll never patch them\n  // and thus never get an origstub_fn_ value for them, and when we\n  // try to call origstub_fn_[kFree/kRealloc] in Perftools_free and\n  // Perftools_realloc, below, it will fail.  We could work around\n  // that by adding a pointer from one patch-unit to the other, but we\n  // haven't needed to yet.\n  CHECK(windows_fn_[kFree]);\n  CHECK(windows_fn_[kRealloc]);\n\n  // OK, we successfully populated.  Let's store our member information.\n  module_base_address_ = module_entry.modBaseAddr;\n  module_base_size_ = module_entry.modBaseSize;\n  return true;\n}\n\ntemplate<int T>\nbool LibcInfoWithPatchFunctions<T>::Patch(const LibcInfo& me_info) {\n  CopyFrom(me_info);   // copies the module_entry and the windows_fn_ array\n  for (int i = 0; i < kNumFunctions; i++) {\n    if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) {\n      // if origstub_fn_ is not NULL, it's left around from a previous\n      // patch.  We need to set it to NULL for the new Patch call.\n      // Since we've patched Unpatch() not to delete origstub_fn_ (it\n      // causes problems in some contexts, though obviously not this\n      // one), we should delete it now, before setting it to NULL.\n      // NOTE: casting from a function to a pointer is contra the C++\n      //       spec.  It's not safe on IA64, but is on i386.  We use\n      //       a C-style cast here to emphasize this is not legal C++.\n      delete[] (char*)(origstub_fn_[i]);\n      origstub_fn_[i] = NULL;   // Patch() will fill this in\n      CHECK_EQ(sidestep::SIDESTEP_SUCCESS,\n               PreamblePatcher::Patch(windows_fn_[i], perftools_fn_[i],\n                                      &origstub_fn_[i]));\n    }\n  }\n  set_is_valid(true);\n  return true;\n}\n\ntemplate<int T>\nvoid LibcInfoWithPatchFunctions<T>::Unpatch() {\n  // We have to cast our GenericFnPtrs to void* for unpatch.  This is\n  // contra the C++ spec; we use C-style casts to empahsize that.\n  for (int i = 0; i < kNumFunctions; i++) {\n    if (windows_fn_[i])\n      CHECK_EQ(sidestep::SIDESTEP_SUCCESS,\n               PreamblePatcher::Unpatch((void*)windows_fn_[i],\n                                        (void*)perftools_fn_[i],\n                                        (void*)origstub_fn_[i]));\n  }\n  set_is_valid(false);\n}\n\nvoid WindowsInfo::Patch() {\n  HMODULE hkernel32 = ::GetModuleHandleA(\"kernel32\");\n  CHECK_NE(hkernel32, NULL);\n\n  // Unlike for libc, we know these exist in our module, so we can get\n  // and patch at the same time.\n  for (int i = 0; i < kNumFunctions; i++) {\n    function_info_[i].windows_fn = (GenericFnPtr)\n        ::GetProcAddress(hkernel32, function_info_[i].name);\n    // If origstub_fn is not NULL, it's left around from a previous\n    // patch.  We need to set it to NULL for the new Patch call.\n    // Since we've patched Unpatch() not to delete origstub_fn_ (it\n    // causes problems in some contexts, though obviously not this\n    // one), we should delete it now, before setting it to NULL.\n    // NOTE: casting from a function to a pointer is contra the C++\n    //       spec.  It's not safe on IA64, but is on i386.  We use\n    //       a C-style cast here to emphasize this is not legal C++.\n    delete[] (char*)(function_info_[i].origstub_fn);\n    function_info_[i].origstub_fn = NULL;  // Patch() will fill this in\n    CHECK_EQ(sidestep::SIDESTEP_SUCCESS,\n             PreamblePatcher::Patch(function_info_[i].windows_fn,\n                                    function_info_[i].perftools_fn,\n                                    &function_info_[i].origstub_fn));\n  }\n}\n\nvoid WindowsInfo::Unpatch() {\n  // We have to cast our GenericFnPtrs to void* for unpatch.  This is\n  // contra the C++ spec; we use C-style casts to empahsize that.\n  for (int i = 0; i < kNumFunctions; i++) {\n    CHECK_EQ(sidestep::SIDESTEP_SUCCESS,\n             PreamblePatcher::Unpatch((void*)function_info_[i].windows_fn,\n                                      (void*)function_info_[i].perftools_fn,\n                                      (void*)function_info_[i].origstub_fn));\n  }\n}\n\n// You should hold the patch_all_modules_lock when calling this.\nvoid PatchOneModuleLocked(const LibcInfo& me_info) {\n  // If we don't already have info on this module, let's add it.  This\n  // is where we're sad that each libcX has a different type, so we\n  // can't use an array; instead, we have to use a switch statement.\n  // Patch() returns false if there were no libc functions in the module.\n  for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) {\n    if (!g_module_libcs[i]->is_valid()) {   // found an empty spot to add!\n      switch (i) {\n        case 0: libc1.Patch(me_info); return;\n        case 1: libc2.Patch(me_info); return;\n        case 2: libc3.Patch(me_info); return;\n        case 3: libc4.Patch(me_info); return;\n        case 4: libc5.Patch(me_info); return;\n        case 5: libc6.Patch(me_info); return;\n        case 6: libc7.Patch(me_info); return;\n        case 7: libc8.Patch(me_info); return;\n      }\n    }\n  }\n  printf(\"PERFTOOLS ERROR: Too many modules containing libc in this executable\\n\");\n}\n\nvoid PatchMainExecutableLocked() {\n  if (main_executable.patched())\n    return;    // main executable has already been patched\n  ModuleEntryCopy fake_module_entry;   // make a fake one to pass into Patch()\n  // No need to call PopulateModuleEntryProcAddresses on the main executable.\n  main_executable.PopulateWindowsFn(fake_module_entry);\n  main_executable.Patch(main_executable);\n}\n\n// This lock is subject to a subtle and annoying lock inversion\n// problem: it may interact badly with unknown internal windows locks.\n// In particular, windows may be holding a lock when it calls\n// LoadLibraryExW and FreeLibrary, which we've patched.  We have those\n// routines call PatchAllModules, which acquires this lock.  If we\n// make windows system calls while holding this lock, those system\n// calls may need the internal windows locks that are being held in\n// the call to LoadLibraryExW, resulting in deadlock.  The solution is\n// to be very careful not to call *any* windows routines while holding\n// patch_all_modules_lock, inside PatchAllModules().\nstatic SpinLock patch_all_modules_lock(SpinLock::LINKER_INITIALIZED);\n\n// last_loaded: The set of modules that were loaded the last time\n// PatchAllModules was called.  This is an optimization for only\n// looking at modules that were added or removed from the last call.\nstatic std::set<HMODULE> *g_last_loaded;\n\n// Iterates over all the modules currently loaded by the executable,\n// according to windows, and makes sure they're all patched.  Most\n// modules will already be in loaded_modules, meaning we have already\n// loaded and either patched them or determined they did not need to\n// be patched.  Others will not, which means we need to patch them\n// (if necessary).  Finally, we have to go through the existing\n// g_module_libcs and see if any of those are *not* in the modules\n// currently loaded by the executable.  If so, we need to invalidate\n// them.  Returns true if we did any work (patching or invalidating),\n// false if we were a noop.  May update loaded_modules as well.\n// NOTE: you must hold the patch_all_modules_lock to access loaded_modules.\nbool PatchAllModules() {\n  std::vector<ModuleEntryCopy> modules;\n  bool made_changes = false;\n\n  const HANDLE hCurrentProcess = GetCurrentProcess();\n  DWORD num_modules = 0;\n  HMODULE hModules[kMaxModules];  // max # of modules we support in one process\n  if (!::EnumProcessModules(hCurrentProcess, hModules, sizeof(hModules),\n                            &num_modules)) {\n    num_modules = 0;\n  }\n  // EnumProcessModules actually set the bytes written into hModules,\n  // so we need to divide to make num_modules actually be a module-count.\n  num_modules /= sizeof(*hModules);\n  if (num_modules >= kMaxModules) {\n    printf(\"PERFTOOLS ERROR: Too many modules in this executable to try\"\n           \" to patch them all (if you need to, raise kMaxModules in\"\n           \" patch_functions.cc).\\n\");\n    num_modules = kMaxModules;\n  }\n\n  // Now we handle the unpatching of modules we have in g_module_libcs\n  // but that were not found in EnumProcessModules.  We need to\n  // invalidate them.  To speed that up, we store the EnumProcessModules\n  // output in a set.\n  // At the same time, we prepare for the adding of new modules, by\n  // removing from hModules all the modules we know we've already\n  // patched (or decided don't need to be patched).  At the end,\n  // hModules will hold only the modules that we need to consider patching.\n  std::set<HMODULE> currently_loaded_modules;\n  {\n    SpinLockHolder h(&patch_all_modules_lock);\n    if (!g_last_loaded)  g_last_loaded = new std::set<HMODULE>;\n    // At the end of this loop, currently_loaded_modules contains the\n    // full list of EnumProcessModules, and hModules just the ones we\n    // haven't handled yet.\n    for (int i = 0; i < num_modules; ) {\n      currently_loaded_modules.insert(hModules[i]);\n      if (g_last_loaded->count(hModules[i]) > 0) {\n        hModules[i] = hModules[--num_modules];  // replace element i with tail\n      } else {\n        i++;                                    // keep element i\n      }\n    }\n    // Now we do the unpatching/invalidation.\n    for (int i = 0; i < sizeof(g_module_libcs)/sizeof(*g_module_libcs); i++) {\n      if (g_module_libcs[i]->patched() &&\n          currently_loaded_modules.count(g_module_libcs[i]->hmodule()) == 0) {\n        // Means g_module_libcs[i] is no longer loaded (no me32 matched).\n        // We could call Unpatch() here, but why bother?  The module\n        // has gone away, so nobody is going to call into it anyway.\n        g_module_libcs[i]->set_is_valid(false);\n        made_changes = true;\n      }\n    }\n    // Update the loaded module cache.\n    g_last_loaded->swap(currently_loaded_modules);\n  }\n\n  // Now that we know what modules are new, let's get the info we'll\n  // need to patch them.  Note this *cannot* be done while holding the\n  // lock, since it needs to make windows calls (see the lock-inversion\n  // comments before the definition of patch_all_modules_lock).\n  MODULEINFO mi;\n  for (int i = 0; i < num_modules; i++) {\n    if (::GetModuleInformation(hCurrentProcess, hModules[i], &mi, sizeof(mi)))\n      modules.push_back(ModuleEntryCopy(mi));\n  }\n\n  // Now we can do the patching of new modules.\n  {\n    SpinLockHolder h(&patch_all_modules_lock);\n    for (std::vector<ModuleEntryCopy>::iterator it = modules.begin();\n         it != modules.end(); ++it) {\n      LibcInfo libc_info;\n      if (libc_info.PopulateWindowsFn(*it)) { // true==module has libc routines\n        PatchOneModuleLocked(libc_info);\n        made_changes = true;\n      }\n    }\n\n    // Now that we've dealt with the modules (dlls), update the main\n    // executable.  We do this last because PatchMainExecutableLocked\n    // wants to look at how other modules were patched.\n    if (!main_executable.patched()) {\n      PatchMainExecutableLocked();\n      made_changes = true;\n    }\n  }\n  // TODO(csilvers): for this to be reliable, we need to also take\n  // into account if we *would* have patched any modules had they not\n  // already been loaded.  (That is, made_changes should ignore\n  // g_last_loaded.)\n  return made_changes;\n}\n\n\n}  // end unnamed namespace\n\n// ---------------------------------------------------------------------\n// Now that we've done all the patching machinery, let's actually\n// define the functions we're patching in.  Mostly these are\n// simple wrappers around the do_* routines in tcmalloc.cc.\n//\n// In fact, we #include tcmalloc.cc to get at the tcmalloc internal\n// do_* functions, the better to write our own hook functions.\n// U-G-L-Y, I know.  But the alternatives are, perhaps, worse.  This\n// also lets us define _msize(), _expand(), and other windows-specific\n// functions here, using tcmalloc internals, without polluting\n// tcmalloc.cc.\n// -------------------------------------------------------------------\n\n// TODO(csilvers): refactor tcmalloc.cc into two files, so I can link\n// against the file with do_malloc, and ignore the one with malloc.\n#include \"tcmalloc.cc\"\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_malloc(size_t size) __THROW {\n  void* result = do_malloc_or_cpp_alloc(size);\n  MallocHook::InvokeNewHook(result, size);\n  return result;\n}\n\ntemplate<int T>\nvoid LibcInfoWithPatchFunctions<T>::Perftools_free(void* ptr) __THROW {\n  MallocHook::InvokeDeleteHook(ptr);\n  // This calls the windows free if do_free decides ptr was not\n  // allocated by tcmalloc.  Note it calls the origstub_free from\n  // *this* templatized instance of LibcInfo.  See \"template\n  // trickiness\" above.\n  do_free_with_callback(ptr, (void (*)(void*))origstub_fn_[kFree]);\n}\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_realloc(\n    void* old_ptr, size_t new_size) __THROW {\n  if (old_ptr == NULL) {\n    void* result = do_malloc_or_cpp_alloc(new_size);\n    MallocHook::InvokeNewHook(result, new_size);\n    return result;\n  }\n  if (new_size == 0) {\n    MallocHook::InvokeDeleteHook(old_ptr);\n    do_free_with_callback(old_ptr,\n                          (void (*)(void*))origstub_fn_[kFree]);\n    return NULL;\n  }\n  return do_realloc_with_callback(\n      old_ptr, new_size,\n      (void (*)(void*))origstub_fn_[kFree],\n      (size_t (*)(void*))origstub_fn_[k_Msize]);\n}\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_calloc(\n    size_t n, size_t elem_size) __THROW {\n  void* result = do_calloc(n, elem_size);\n  MallocHook::InvokeNewHook(result, n * elem_size);\n  return result;\n}\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_new(size_t size) {\n  void* p = cpp_alloc(size, false);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_newarray(size_t size) {\n  void* p = cpp_alloc(size, false);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\ntemplate<int T>\nvoid LibcInfoWithPatchFunctions<T>::Perftools_delete(void *p) {\n  MallocHook::InvokeDeleteHook(p);\n  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree]);\n}\n\ntemplate<int T>\nvoid LibcInfoWithPatchFunctions<T>::Perftools_deletearray(void *p) {\n  MallocHook::InvokeDeleteHook(p);\n  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree]);\n}\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_new_nothrow(\n    size_t size, const std::nothrow_t&) __THROW {\n  void* p = cpp_alloc(size, true);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools_newarray_nothrow(\n    size_t size, const std::nothrow_t&) __THROW {\n  void* p = cpp_alloc(size, true);\n  MallocHook::InvokeNewHook(p, size);\n  return p;\n}\n\ntemplate<int T>\nvoid LibcInfoWithPatchFunctions<T>::Perftools_delete_nothrow(\n    void *p, const std::nothrow_t&) __THROW {\n  MallocHook::InvokeDeleteHook(p);\n  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree]);\n}\n\ntemplate<int T>\nvoid LibcInfoWithPatchFunctions<T>::Perftools_deletearray_nothrow(\n    void *p, const std::nothrow_t&) __THROW {\n  MallocHook::InvokeDeleteHook(p);\n  do_free_with_callback(p, (void (*)(void*))origstub_fn_[kFree]);\n}\n\n\n// _msize() lets you figure out how much space is reserved for a\n// pointer, in Windows.  Even if applications don't call it, any DLL\n// with global constructors will call (transitively) something called\n// __dllonexit_lk in order to make sure the destructors get called\n// when the dll unloads.  And that will call msize -- horrible things\n// can ensue if this is not hooked.  Other parts of libc may also call\n// this internally.\n\ntemplate<int T>\nsize_t LibcInfoWithPatchFunctions<T>::Perftools__msize(void* ptr) __THROW {\n  return GetSizeWithCallback(ptr, (size_t (*)(void*))origstub_fn_[k_Msize]);\n}\n\n// We need to define this because internal windows functions like to\n// call into it(?).  _expand() is like realloc but doesn't move the\n// pointer.  We punt, which will cause callers to fall back on realloc.\ntemplate<int T>\nvoid* LibcInfoWithPatchFunctions<T>::Perftools__expand(void *ptr,\n                                                       size_t size) __THROW {\n  return NULL;\n}\n\nLPVOID WINAPI WindowsInfo::Perftools_HeapAlloc(HANDLE hHeap, DWORD dwFlags,\n                                               DWORD_PTR dwBytes) {\n  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD_PTR))\n                   function_info_[kHeapAlloc].origstub_fn)(\n                       hHeap, dwFlags, dwBytes);\n  MallocHook::InvokeNewHook(result, dwBytes);\n  return result;\n}\n\nBOOL WINAPI WindowsInfo::Perftools_HeapFree(HANDLE hHeap, DWORD dwFlags,\n                                            LPVOID lpMem) {\n  MallocHook::InvokeDeleteHook(lpMem);\n  return ((BOOL (WINAPI *)(HANDLE, DWORD, LPVOID))\n          function_info_[kHeapFree].origstub_fn)(\n              hHeap, dwFlags, lpMem);\n}\n\nLPVOID WINAPI WindowsInfo::Perftools_VirtualAllocEx(HANDLE process,\n                                                    LPVOID address,\n                                                    SIZE_T size, DWORD type,\n                                                    DWORD protect) {\n  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD))\n                   function_info_[kVirtualAllocEx].origstub_fn)(\n                       process, address, size, type, protect);\n  // VirtualAllocEx() seems to be the Windows equivalent of mmap()\n  MallocHook::InvokeMmapHook(result, address, size, protect, type, -1, 0);\n  return result;\n}\n\nBOOL WINAPI WindowsInfo::Perftools_VirtualFreeEx(HANDLE process, LPVOID address,\n                                                 SIZE_T size, DWORD type) {\n  MallocHook::InvokeMunmapHook(address, size);\n  return ((BOOL (WINAPI *)(HANDLE, LPVOID, SIZE_T, DWORD))\n          function_info_[kVirtualFreeEx].origstub_fn)(\n              process, address, size, type);\n}\n\nLPVOID WINAPI WindowsInfo::Perftools_MapViewOfFileEx(\n    HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,\n    DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) {\n  // For this function pair, you always deallocate the full block of\n  // data that you allocate, so NewHook/DeleteHook is the right API.\n  LPVOID result = ((LPVOID (WINAPI *)(HANDLE, DWORD, DWORD, DWORD,\n                                      SIZE_T, LPVOID))\n                   function_info_[kMapViewOfFileEx].origstub_fn)(\n                       hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,\n                       dwFileOffsetLow, dwNumberOfBytesToMap, lpBaseAddress);\n  MallocHook::InvokeNewHook(result, dwNumberOfBytesToMap);\n  return result;\n}\n\nBOOL WINAPI WindowsInfo::Perftools_UnmapViewOfFile(LPCVOID lpBaseAddress) {\n  MallocHook::InvokeDeleteHook(lpBaseAddress);\n  return ((BOOL (WINAPI *)(LPCVOID))\n          function_info_[kUnmapViewOfFile].origstub_fn)(\n              lpBaseAddress);\n}\n\n// g_load_map holds a copy of windows' refcount for how many times\n// each currently loaded module has been loaded and unloaded.  We use\n// it as an optimization when the same module is loaded more than\n// once: as long as the refcount stays above 1, we don't need to worry\n// about patching because it's already patched.  Likewise, we don't\n// need to unpatch until the refcount drops to 0.  load_map is\n// maintained in LoadLibraryExW and FreeLibrary, and only covers\n// modules explicitly loaded/freed via those interfaces.\nstatic std::map<HMODULE, int>* g_load_map = NULL;\n\nHMODULE WINAPI WindowsInfo::Perftools_LoadLibraryExW(LPCWSTR lpFileName,\n                                                     HANDLE hFile,\n                                                     DWORD dwFlags) {\n  HMODULE rv;\n  // Check to see if the modules is already loaded, flag 0 gets a\n  // reference if it was loaded.  If it was loaded no need to call\n  // PatchAllModules, just increase the reference count to match\n  // what GetModuleHandleExW does internally inside windows.\n  if (::GetModuleHandleExW(0, lpFileName, &rv)) {\n    return rv;\n  } else {\n    // Not already loaded, so load it.\n    rv = ((HMODULE (WINAPI *)(LPCWSTR, HANDLE, DWORD))\n                  function_info_[kLoadLibraryExW].origstub_fn)(\n                      lpFileName, hFile, dwFlags);\n    // This will patch any newly loaded libraries, if patching needs\n    // to be done.\n    PatchAllModules();\n\n    return rv;\n  }\n}\n\nBOOL WINAPI WindowsInfo::Perftools_FreeLibrary(HMODULE hLibModule) {\n  BOOL rv = ((BOOL (WINAPI *)(HMODULE))\n             function_info_[kFreeLibrary].origstub_fn)(hLibModule);\n\n  // Check to see if the module is still loaded by passing the base\n  // address and seeing if it comes back with the same address.  If it\n  // is the same address it's still loaded, so the FreeLibrary() call\n  // was a noop, and there's no need to redo the patching.\n  HMODULE owner = NULL;\n  BOOL result = ::GetModuleHandleExW(\n      (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |\n       GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),\n      (LPCWSTR)hLibModule,\n      &owner);\n  if (result && owner == hLibModule)\n    return rv;\n\n  PatchAllModules();    // this will fix up the list of patched libraries\n  return rv;\n}\n\n\n// ---------------------------------------------------------------------\n// PatchWindowsFunctions()\n//    This is the function that is exposed to the outside world.\n//    It should be called before the program becomes multi-threaded,\n//    since main_executable_windows.Patch() is not thread-safe.\n// ---------------------------------------------------------------------\n\nvoid PatchWindowsFunctions() {\n  // This does the libc patching in every module, and the main executable.\n  PatchAllModules();\n  main_executable_windows.Patch();\n}\n\n#if 0\n// It's possible to unpatch all the functions when we are exiting.\n\n// The idea is to handle properly windows-internal data that is\n// allocated before PatchWindowsFunctions is called.  If all\n// destruction happened in reverse order from construction, then we\n// could call UnpatchWindowsFunctions at just the right time, so that\n// that early-allocated data would be freed using the windows\n// allocation functions rather than tcmalloc.  The problem is that\n// windows allocates some structures lazily, so it would allocate them\n// late (using tcmalloc) and then try to deallocate them late as well.\n// So instead of unpatching, we just modify all the tcmalloc routines\n// so they call through to the libc rountines if the memory in\n// question doesn't seem to have been allocated with tcmalloc.  I keep\n// this unpatch code around for reference.\n\nvoid UnpatchWindowsFunctions() {\n  // We need to go back to the system malloc/etc at global destruct time,\n  // so objects that were constructed before tcmalloc, using the system\n  // malloc, can destroy themselves using the system free.  This depends\n  // on DLLs unloading in the reverse order in which they load!\n  //\n  // We also go back to the default HeapAlloc/etc, just for consistency.\n  // Who knows, it may help avoid weird bugs in some situations.\n  main_executable_windows.Unpatch();\n  main_executable.Unpatch();\n  if (libc1.is_valid()) libc1.Unpatch();\n  if (libc2.is_valid()) libc2.Unpatch();\n  if (libc3.is_valid()) libc3.Unpatch();\n  if (libc4.is_valid()) libc4.Unpatch();\n  if (libc5.is_valid()) libc5.Unpatch();\n  if (libc6.is_valid()) libc6.Unpatch();\n  if (libc7.is_valid()) libc7.Unpatch();\n  if (libc8.is_valid()) libc8.Unpatch();\n}\n#endif\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/port.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Craig Silverstein\n */\n\n#ifndef _WIN32\n# error You should only be including windows/port.cc in a windows environment!\n#endif\n\n#define NOMINMAX       // so std::max, below, compiles correctly\n#include <config.h>\n#include <string.h>    // for strlen(), memset(), memcmp()\n#include <assert.h>\n#include <stdarg.h>    // for va_list, va_start, va_end\n#include <windows.h>\n#include \"port.h\"\n#include \"base/logging.h\"\n#include \"base/spinlock.h\"\n#include \"system-alloc.h\"\n\n// -----------------------------------------------------------------------\n// Basic libraries\n\n// These call the windows _vsnprintf, but always NUL-terminate.\nint safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {\n  if (size == 0)        // not even room for a \\0?\n    return -1;          // not what C99 says to do, but what windows does\n  str[size-1] = '\\0';\n  return _vsnprintf(str, size-1, format, ap);\n}\n\n#ifndef HAVE_SNPRINTF\nint snprintf(char *str, size_t size, const char *format, ...) {\n  va_list ap;\n  va_start(ap, format);\n  const int r = vsnprintf(str, size, format, ap);\n  va_end(ap);\n  return r;\n}\n#endif\n\nint getpagesize() {\n  static int pagesize = 0;\n  if (pagesize == 0) {\n    SYSTEM_INFO system_info;\n    GetSystemInfo(&system_info);\n    pagesize = std::max(system_info.dwPageSize,\n                        system_info.dwAllocationGranularity);\n  }\n  return pagesize;\n}\n\nextern \"C\" PERFTOOLS_DLL_DECL void* __sbrk(ptrdiff_t increment) {\n  LOG(FATAL, \"Windows doesn't implement sbrk!\\n\");\n  return NULL;\n}\n\n// We need to write to 'stderr' without having windows allocate memory.\n// The safest way is via a low-level call like WriteConsoleA().  But\n// even then we need to be sure to print in small bursts so as to not\n// require memory allocation.\nextern \"C\" PERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len) {\n  // Looks like windows allocates for writes of >80 bytes\n  for (int i = 0; i < len; i += 80) {\n    write(STDERR_FILENO, buf + i, std::min(80, len - i));\n  }\n}\n\n\n// -----------------------------------------------------------------------\n// Threads code\n\nbool CheckIfKernelSupportsTLS() {\n  // TODO(csilvers): return true (all win's since win95, at least, support this)\n  return false;\n}\n\n// Windows doesn't support pthread_key_create's destr_function, and in\n// fact it's a bit tricky to get code to run when a thread exits.  This\n// is cargo-cult magic from http://www.codeproject.com/threads/tls.asp.\n// This code is for VC++ 7.1 and later; VC++ 6.0 support is possible\n// but more busy-work -- see the webpage for how to do it.  If all\n// this fails, we could use DllMain instead.  The big problem with\n// DllMain is it doesn't run if this code is statically linked into a\n// binary (it also doesn't run if the thread is terminated via\n// TerminateThread, which if we're lucky this routine does).\n\n// Force a reference to _tls_used to make the linker create the TLS directory\n// if it's not already there (that is, even if __declspec(thread) is not used).\n// Force a reference to p_thread_callback_tcmalloc and p_process_term_tcmalloc\n// to prevent whole program optimization from discarding the variables.\n#ifdef _MSC_VER\n#pragma comment(linker, \"/INCLUDE:__tls_used\")\n#pragma comment(linker, \"/INCLUDE:_p_thread_callback_tcmalloc\")\n#pragma comment(linker, \"/INCLUDE:_p_process_term_tcmalloc\")\n#endif\n\n// When destr_fn eventually runs, it's supposed to take as its\n// argument the tls-value associated with key that pthread_key_create\n// creates.  (Yeah, it sounds confusing but it's really not.)  We\n// store the destr_fn/key pair in this data structure.  Because we\n// store this in a single var, this implies we can only have one\n// destr_fn in a program!  That's enough in practice.  If asserts\n// trigger because we end up needing more, we'll have to turn this\n// into an array.\nstruct DestrFnClosure {\n  void (*destr_fn)(void*);\n  pthread_key_t key_for_destr_fn_arg;\n};\n\nstatic DestrFnClosure destr_fn_info;   // initted to all NULL/0.\n\nstatic int on_process_term(void) {\n  if (destr_fn_info.destr_fn) {\n    void *ptr = TlsGetValue(destr_fn_info.key_for_destr_fn_arg);\n    // This shouldn't be necessary, but in Release mode, Windows\n    // sometimes trashes the pointer in the TLS slot, so we need to\n    // remove the pointer from the TLS slot before the thread dies.\n    TlsSetValue(destr_fn_info.key_for_destr_fn_arg, NULL);\n    if (ptr)  // pthread semantics say not to call if ptr is NULL\n      (*destr_fn_info.destr_fn)(ptr);\n  }\n  return 0;\n}\n\nstatic void NTAPI on_tls_callback(HINSTANCE h, DWORD dwReason, PVOID pv) {\n  if (dwReason == DLL_THREAD_DETACH) {   // thread is being destroyed!\n    on_process_term();\n  }\n}\n\n#ifdef _MSC_VER\n\n// extern \"C\" suppresses C++ name mangling so we know the symbol names\n// for the linker /INCLUDE:symbol pragmas above.\nextern \"C\" {\n// This tells the linker to run these functions.\n#pragma data_seg(push, old_seg)\n#pragma data_seg(\".CRT$XLB\")\nvoid (NTAPI *p_thread_callback_tcmalloc)(\n    HINSTANCE h, DWORD dwReason, PVOID pv) = on_tls_callback;\n#pragma data_seg(\".CRT$XTU\")\nint (*p_process_term_tcmalloc)(void) = on_process_term;\n#pragma data_seg(pop, old_seg)\n}  // extern \"C\"\n\n#else  // #ifdef _MSC_VER  [probably msys/mingw]\n\n// We have to try the DllMain solution here, because we can't use the\n// msvc-specific pragmas.\nBOOL WINAPI DllMain(HINSTANCE h, DWORD dwReason, PVOID pv) {\n  if (dwReason == DLL_THREAD_DETACH)\n    on_tls_callback(h, dwReason, pv);\n  else if (dwReason == DLL_PROCESS_DETACH)\n    on_process_term();\n  return TRUE;\n}\n\n#endif  // #ifdef _MSC_VER\n\npthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)) {\n  // Semantics are: we create a new key, and then promise to call\n  // destr_fn with TlsGetValue(key) when the thread is destroyed\n  // (as long as TlsGetValue(key) is not NULL).\n  pthread_key_t key = TlsAlloc();\n  if (destr_fn) {   // register it\n    // If this assert fails, we'll need to support an array of destr_fn_infos\n    assert(destr_fn_info.destr_fn == NULL);\n    destr_fn_info.destr_fn = destr_fn;\n    destr_fn_info.key_for_destr_fn_arg = key;\n  }\n  return key;\n}\n\n\n// -----------------------------------------------------------------------\n// These functions replace system-alloc.cc\n\n// This is mostly like MmapSysAllocator::Alloc, except it does these weird\n// munmap's in the middle of the page, which is forbidden in windows.\nextern void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,\n                                  size_t alignment) {\n  // Align on the pagesize boundary\n  const int pagesize = getpagesize();\n  if (alignment < pagesize) alignment = pagesize;\n  size = ((size + alignment - 1) / alignment) * alignment;\n\n  // Safest is to make actual_size same as input-size.\n  if (actual_size) {\n    *actual_size = size;\n  }\n\n  // Ask for extra memory if alignment > pagesize\n  size_t extra = 0;\n  if (alignment > pagesize) {\n    extra = alignment - pagesize;\n  }\n\n  void* result = VirtualAlloc(0, size + extra,\n                              MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);\n  if (result == NULL)\n    return NULL;\n\n  // Adjust the return memory so it is aligned\n  uintptr_t ptr = reinterpret_cast<uintptr_t>(result);\n  size_t adjust = 0;\n  if ((ptr & (alignment - 1)) != 0) {\n    adjust = alignment - (ptr & (alignment - 1));\n  }\n\n  ptr += adjust;\n  return reinterpret_cast<void*>(ptr);\n}\n\nvoid TCMalloc_SystemRelease(void* start, size_t length) {\n  // TODO(csilvers): should I be calling VirtualFree here?\n}\n\nbool RegisterSystemAllocator(SysAllocator *allocator, int priority) {\n  return false;   // we don't allow registration on windows, right now\n}\n\nvoid DumpSystemAllocatorStats(TCMalloc_Printer* printer) {\n  // We don't dump stats on windows, right now\n}\n\n\n// -----------------------------------------------------------------------\n// These functions rework existing functions of the same name in the\n// Google codebase.\n\n// A replacement for HeapProfiler::CleanupOldProfiles.\nvoid DeleteMatchingFiles(const char* prefix, const char* full_glob) {\n  WIN32_FIND_DATAA found;  // that final A is for Ansi (as opposed to Unicode)\n  HANDLE hFind = FindFirstFileA(full_glob, &found);   // A is for Ansi\n  if (hFind != INVALID_HANDLE_VALUE) {\n    const int prefix_length = strlen(prefix);\n    do {\n      const char *fname = found.cFileName;\n      if ((strlen(fname) >= prefix_length) &&\n          (memcmp(fname, prefix, prefix_length) == 0)) {\n        RAW_VLOG(0, \"Removing old heap profile %s\\n\", fname);\n        // TODO(csilvers): we really need to unlink dirname + fname\n        _unlink(fname);\n      }\n    } while (FindNextFileA(hFind, &found) != FALSE);  // A is for Ansi\n    FindClose(hFind);\n  }\n}\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/port.h",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Craig Silverstein\n *\n * These are some portability typedefs and defines to make it a bit\n * easier to compile this code under VC++.\n *\n * Several of these are taken from glib:\n *    http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html\n */\n\n#ifndef GOOGLE_BASE_WINDOWS_H_\n#define GOOGLE_BASE_WINDOWS_H_\n\n// You should never include this file directly, but always include it\n// from either config.h (MSVC) or mingw.h (MinGW/msys).\n#if !defined(GOOGLE_PERFTOOLS_WINDOWS_CONFIG_H_) && \\\n    !defined(GOOGLE_PERFTOOLS_WINDOWS_MINGW_H_)\n# error \"port.h should only be included from config.h or mingw.h\"\n#endif\n\n#ifdef _WIN32\n\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */\n#endif\n#include <windows.h>\n#include <io.h>              /* because we so often use open/close/etc */\n#include <process.h>         /* for _getpid */\n#include <stdarg.h>          /* for va_list */\n#include <stdio.h>           /* need this to override stdio's (v)snprintf */\n\n// 4018: signed/unsigned mismatch is common (and ok for signed_i < unsigned_i)\n// 4244: otherwise we get problems when substracting two size_t's to an int\n// 4288: VC++7 gets confused when a var is defined in a loop and then after it\n// 4267: too many false positives for \"conversion gives possible data loss\"\n// 4290: it's ok windows ignores the \"throw\" directive\n// 4996: Yes, we're ok using \"unsafe\" functions like vsnprintf and getenv()\n#ifdef _MSC_VER\n#pragma warning(disable:4018 4244 4288 4267 4290 4996)\n#endif\n\n// ----------------------------------- BASIC TYPES\n\n#ifndef HAVE_STDINT_H\n#ifndef HAVE___INT64    /* we need to have all the __intX names */\n# error  Do not know how to set up type aliases.  Edit port.h for your system.\n#endif\n\ntypedef __int8 int8_t;\ntypedef __int16 int16_t;\ntypedef __int32 int32_t;\ntypedef __int64 int64_t;\ntypedef unsigned __int8 uint8_t;\ntypedef unsigned __int16 uint16_t;\ntypedef unsigned __int32 uint32_t;\ntypedef unsigned __int64 uint64_t;\n#endif  // #ifndef HAVE_STDINT_H\n\n// I guess MSVC's <types.h> doesn't include ssize_t by default?\n#ifdef _MSC_VER\ntypedef intptr_t ssize_t;\n#endif\n\n// ----------------------------------- THREADS\n\n#ifndef HAVE_PTHREAD   // not true for MSVC, but may be true for MSYS\ntypedef DWORD pthread_t;\ntypedef DWORD pthread_key_t;\ntypedef LONG pthread_once_t;\nenum { PTHREAD_ONCE_INIT = 0 };   // important that this be 0! for SpinLock\n#define pthread_self  GetCurrentThreadId\n#define pthread_equal(pthread_t_1, pthread_t_2)  ((pthread_t_1)==(pthread_t_2))\n\n#ifdef __cplusplus\n// This replaces maybe_threads.{h,cc}\nextern pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*));  // in port.cc\n#define perftools_pthread_key_create(pkey, destr_fn)  \\\n  *(pkey) = PthreadKeyCreate(destr_fn)\ninline void* perftools_pthread_getspecific(DWORD key) {\n  DWORD err = GetLastError();\n  void* rv = TlsGetValue(key);\n  if (err) SetLastError(err);\n  return rv;\n}\n#define perftools_pthread_setspecific(key, val) \\\n  TlsSetValue((key), (val))\n// NOTE: this is Win2K and later.  For Win98 we could use a CRITICAL_SECTION...\n#define perftools_pthread_once(once, init)  do {                \\\n  if (InterlockedCompareExchange(once, 1, 0) == 0) (init)();    \\\n} while (0)\n#endif  // __cplusplus\n#endif  // HAVE_PTHREAD\n\n// __declspec(thread) isn't usable in a dll opened via LoadLibrary().\n// But it doesn't work to LoadLibrary() us anyway, because of all the\n// things we need to do before main()!  So this kind of TLS is safe for us.\n#define __thread __declspec(thread)\n\n// This code is obsolete, but I keep it around in case we are ever in\n// an environment where we can't or don't want to use google spinlocks\n// (from base/spinlock.{h,cc}).  In that case, uncommenting this out,\n// and removing spinlock.cc from the build, should be enough to revert\n// back to using native spinlocks.\n#if 0\n// Windows uses a spinlock internally for its mutexes, making our life easy!\n// However, the Windows spinlock must always be initialized, making life hard,\n// since we want LINKER_INITIALIZED.  We work around this by having the\n// linker initialize a bool to 0, and check that before accessing the mutex.\n// This replaces spinlock.{h,cc}, and all the stuff it depends on (atomicops)\n#ifdef __cplusplus\nclass SpinLock {\n public:\n  SpinLock() : initialize_token_(PTHREAD_ONCE_INIT) {}\n  // Used for global SpinLock vars (see base/spinlock.h for more details).\n  enum StaticInitializer { LINKER_INITIALIZED };\n  explicit SpinLock(StaticInitializer) : initialize_token_(PTHREAD_ONCE_INIT) {\n    perftools_pthread_once(&initialize_token_, InitializeMutex);\n  }\n\n  // It's important SpinLock not have a destructor: otherwise we run\n  // into problems when the main thread has exited, but other threads\n  // are still running and try to access a main-thread spinlock.  This\n  // means we leak mutex_ (we should call DeleteCriticalSection()\n  // here).  However, I've verified that all SpinLocks used in\n  // perftools have program-long scope anyway, so the leak is\n  // perfectly fine.  But be aware of this for the future!\n\n  void Lock() {\n    // You'd thionk this would be unnecessary, since we call\n    // InitializeMutex() in our constructor.  But sometimes Lock() can\n    // be called before our constructor is!  This can only happen in\n    // global constructors, when this is a global.  If we live in\n    // bar.cc, and some global constructor in foo.cc calls a routine\n    // in bar.cc that calls this->Lock(), then Lock() may well run\n    // before our global constructor does.  To protect against that,\n    // we do this check.  For SpinLock objects created after main()\n    // has started, this pthread_once call will always be a noop.\n    perftools_pthread_once(&initialize_token_, InitializeMutex);\n    EnterCriticalSection(&mutex_);\n  }\n  void Unlock() {\n    LeaveCriticalSection(&mutex_);\n  }\n\n  // Used in assertion checks: assert(lock.IsHeld()) (see base/spinlock.h).\n  inline bool IsHeld() const {\n    // This works, but probes undocumented internals, so I've commented it out.\n    // c.f. http://msdn.microsoft.com/msdnmag/issues/03/12/CriticalSections/\n    //return mutex_.LockCount>=0 && mutex_.OwningThread==GetCurrentThreadId();\n    return true;\n  }\n private:\n  void InitializeMutex() { InitializeCriticalSection(&mutex_); }\n\n  pthread_once_t initialize_token_;\n  CRITICAL_SECTION mutex_;\n};\n\nclass SpinLockHolder {  // Acquires a spinlock for as long as the scope lasts\n private:\n  SpinLock* lock_;\n public:\n  inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); }\n  inline ~SpinLockHolder() { lock_->Unlock(); }\n};\n#endif  // #ifdef __cplusplus\n\n// This keeps us from using base/spinlock.h's implementation of SpinLock.\n#define BASE_SPINLOCK_H_ 1\n\n#endif  // #if 0\n\n// This replaces testutil.{h,cc}\nextern PERFTOOLS_DLL_DECL void RunInThread(void (*fn)());\nextern PERFTOOLS_DLL_DECL void RunManyInThread(void (*fn)(), int count);\nextern PERFTOOLS_DLL_DECL void RunManyInThreadWithId(void (*fn)(int), int count,\n                                                     int stacksize);\n\n\n// ----------------------------------- MMAP and other memory allocation\n\n#ifndef HAVE_MMAP   // not true for MSVC, but may be true for msys\n#define MAP_FAILED  0\n#define MREMAP_FIXED  2  // the value in linux, though it doesn't really matter\n// These, when combined with the mmap invariants below, yield the proper action\n#define PROT_READ      PAGE_READWRITE\n#define PROT_WRITE     PAGE_READWRITE\n#define MAP_ANONYMOUS  MEM_RESERVE\n#define MAP_PRIVATE    MEM_COMMIT\n#define MAP_SHARED     MEM_RESERVE   // value of this #define is 100% arbitrary\n\n// VirtualAlloc is only a replacement for mmap when certain invariants are kept\n#define mmap(start, length, prot, flags, fd, offset)                          \\\n  ( (start) == NULL && (fd) == -1 && (offset) == 0 &&                         \\\n    (prot) == (PROT_READ|PROT_WRITE) && (flags) == (MAP_PRIVATE|MAP_ANONYMOUS)\\\n      ? VirtualAlloc(0, length, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)     \\\n      : NULL )\n\n#define munmap(start, length)   (VirtualFree(start, 0, MEM_RELEASE) ? 0 : -1)\n#endif  // HAVE_MMAP\n\n// We could maybe use VirtualAlloc for sbrk as well, but no need\n#define sbrk(increment)  ( (void*)-1 )   // sbrk returns -1 on failure\n\n\n// ----------------------------------- STRING ROUTINES\n\n// We can't just use _vsnprintf and _snprintf as drop-in-replacements,\n// because they don't always NUL-terminate. :-(  We also can't use the\n// name vsnprintf, since windows defines that (but not snprintf (!)).\nextern PERFTOOLS_DLL_DECL int snprintf(char *str, size_t size,\n                                       const char *format, ...);\nextern PERFTOOLS_DLL_DECL int safe_vsnprintf(char *str, size_t size,\n                                             const char *format, va_list ap);\n#define vsnprintf(str, size, format, ap)  safe_vsnprintf(str, size, format, ap)\n\n#define PRIx64  \"I64x\"\n#define SCNx64  \"I64x\"\n#define PRId64  \"I64d\"\n#define SCNd64  \"I64d\"\n#define PRIu64  \"I64u\"\n#ifdef _WIN64\n# define PRIuPTR \"llu\"\n# define PRIxPTR \"llx\"\n#else\n# define PRIuPTR \"lu\"\n# define PRIxPTR \"lx\"\n#endif\n\n// ----------------------------------- FILE IO\n#ifndef PATH_MAX\n#define PATH_MAX 1024\n#endif\n#ifndef __MINGW32__\nenum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };\n#endif\n#define getcwd    _getcwd\n#define access    _access\n#define open      _open\n#define read      _read\n#define write     _write\n#define lseek     _lseek\n#define close     _close\n#define popen     _popen\n#define pclose    _pclose\n#define mkdir(dirname, mode)  _mkdir(dirname)\n#ifndef O_RDONLY\n#define O_RDONLY  _O_RDONLY\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n#endif\nPERFTOOLS_DLL_DECL void WriteToStderr(const char* buf, int len);\n\n// ----------------------------------- SYSTEM/PROCESS\ntypedef int pid_t;\n#define getpid  _getpid\n#define getppid() (0)\n\n// Handle case when poll is used to simulate sleep.\n#define poll(r, w, t) \\\n  do {                \\\n    assert(r == 0);   \\\n    assert(w == 0);   \\\n    Sleep(t);         \\\n  } while(0)\n\nextern PERFTOOLS_DLL_DECL int getpagesize();   // in port.cc\n\n// ----------------------------------- OTHER\n\n#define srandom  srand\n#define random   rand\n#define sleep(t) Sleep(t * 1000)\n\nstruct timespec {\n  int tv_sec;\n  int tv_nsec;\n};\n\n#define nanosleep(tm_ptr, ignored)  \\\n  Sleep((tm_ptr)->tv_sec * 1000 + (tm_ptr)->tv_nsec / 1000000)\n\n#ifndef __MINGW32__\n#define strtoq   _strtoi64\n#define strtouq  _strtoui64\n#define strtoll  _strtoi64\n#define strtoull _strtoui64\n#define atoll    _atoi64\n#endif\n\n#define __THROW throw()\n\n// ----------------------------------- TCMALLOC-SPECIFIC\n\n// tcmalloc.cc calls this so we can patch VirtualAlloc() et al.\nextern PERFTOOLS_DLL_DECL void PatchWindowsFunctions();\n\n// ----------------------------------- BUILD-SPECIFIC\n\n// windows/port.h defines compatibility APIs for several .h files, which\n// we therefore shouldn't be #including directly.  This hack keeps us from\n// doing so.  TODO(csilvers): do something more principled.\n#define GOOGLE_MAYBE_THREADS_H_ 1\n\n\n#endif  /* _WIN32 */\n\n#endif  /* GOOGLE_BASE_WINDOWS_H_ */\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/preamble_patcher.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Implementation of PreamblePatcher\n */\n\n#include \"preamble_patcher.h\"\n\n#include \"mini_disassembler.h\"\n\n// compatibility shims\n#include \"base/logging.h\"\n\n// Definitions of assembly statements we need\n#define ASM_JMP32REL 0xE9\n#define ASM_INT3 0xCC\n#define ASM_JMP32ABS_0 0xFF\n#define ASM_JMP32ABS_1 0x25\n#define ASM_JMP8REL 0xEB\n\nnamespace sidestep {\n\n// Handle a special case that we see with functions that point into an\n// IAT table (including functions linked statically into the\n// application): these function already starts with ASM_JMP32*.  For\n// instance, malloc() might be implemented as a JMP to __malloc().\n// This function follows the initial JMPs for us, until we get to the\n// place where the actual code is defined.  If we get to STOP_BEFORE,\n// we return the address before stop_before.\nvoid* PreamblePatcher::ResolveTargetImpl(unsigned char* target,\n                                         unsigned char* stop_before) {\n  if (target == NULL)\n    return NULL;\n  while (1) {\n    unsigned char* new_target;\n    if (target[0] == ASM_JMP32REL) {\n      // target[1-4] holds the place the jmp goes to, but it's\n      // relative to the next instruction.\n      int relative_offset;   // Windows guarantees int is 4 bytes\n      SIDESTEP_ASSERT(sizeof(relative_offset) == 4);\n      memcpy(reinterpret_cast<void*>(&relative_offset),\n             reinterpret_cast<void*>(target + 1), 4);\n      new_target = target + 5 + relative_offset;\n    } else if (target[0] == ASM_JMP8REL) {\n      // Visual Studio 7.1 implements new[] as an 8 bit jump to new\n      signed char relative_offset;\n      memcpy(reinterpret_cast<void*>(&relative_offset),\n             reinterpret_cast<void*>(target + 1), 1);\n      new_target = target + 2 + relative_offset;\n    } else if (target[0] == ASM_JMP32ABS_0 &&\n               target[1] == ASM_JMP32ABS_1) {\n      // Visual studio seems to sometimes do it this way instead of the\n      // previous way.  Not sure what the rules are, but it was happening\n      // with operator new in some binaries.\n      void **new_target_v;\n      SIDESTEP_ASSERT(sizeof(new_target) == 4);\n      memcpy(&new_target_v, reinterpret_cast<void*>(target + 2), 4);\n      new_target = reinterpret_cast<unsigned char*>(*new_target_v);\n    } else {\n      break;\n    }\n    if (new_target == stop_before)\n      break;\n    target = new_target;\n  }\n  return target;\n}\n\n// Special case scoped_ptr to avoid dependency on scoped_ptr below.\nclass DeleteUnsignedCharArray {\n public:\n  DeleteUnsignedCharArray(unsigned char* array) : array_(array) {\n  }\n\n  ~DeleteUnsignedCharArray() {\n    if (array_) {\n      delete [] array_;\n    }\n  }\n\n  unsigned char* Release() {\n    unsigned char* temp = array_;\n    array_ = NULL;\n    return temp;\n  }\n\n private:\n  unsigned char* array_;\n};\n\nSideStepError PreamblePatcher::RawPatchWithStubAndProtections(\n    void* target_function, void *replacement_function,\n    unsigned char* preamble_stub, unsigned long stub_size,\n    unsigned long* bytes_needed) {\n  // We need to be able to write to a process-local copy of the first\n  // MAX_PREAMBLE_STUB_SIZE bytes of target_function\n  DWORD old_target_function_protect = 0;\n  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),\n                                    MAX_PREAMBLE_STUB_SIZE,\n                                    PAGE_EXECUTE_READWRITE,\n                                    &old_target_function_protect);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false && \"Failed to make page containing target function \"\n                    \"copy-on-write.\");\n    return SIDESTEP_ACCESS_DENIED;\n  }\n\n  SideStepError error_code = RawPatchWithStub(target_function,\n                                              replacement_function,\n                                              preamble_stub,\n                                              stub_size,\n                                              bytes_needed);\n\n  // Restore the protection of the first MAX_PREAMBLE_STUB_SIZE bytes of\n  // pTargetFunction to what they were before we started goofing around.\n  // We do this regardless of whether the patch succeeded or not.\n  succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),\n                               MAX_PREAMBLE_STUB_SIZE,\n                               old_target_function_protect,\n                               &old_target_function_protect);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false &&\n                    \"Failed to restore protection to target function.\");\n    // We must not return an error here because the function has\n    // likely actually been patched, and returning an error might\n    // cause our client code not to unpatch it.  So we just keep\n    // going.\n  }\n\n  if (SIDESTEP_SUCCESS != error_code) {  // Testing RawPatchWithStub, above\n    SIDESTEP_ASSERT(false);\n    return error_code;\n  }\n\n  // Flush the instruction cache to make sure the processor doesn't execute the\n  // old version of the instructions (before our patch).\n  //\n  // FlushInstructionCache is actually a no-op at least on\n  // single-processor XP machines.  I'm not sure why this is so, but\n  // it is, yet I want to keep the call to the API here for\n  // correctness in case there is a difference in some variants of\n  // Windows/hardware.\n  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),\n                                      target_function,\n                                      MAX_PREAMBLE_STUB_SIZE);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false && \"Failed to flush instruction cache.\");\n    // We must not return an error here because the function has actually\n    // been patched, and returning an error would likely cause our client\n    // code not to unpatch it.  So we just keep going.\n  }\n\n  return SIDESTEP_SUCCESS;\n}\n\nSideStepError PreamblePatcher::RawPatch(void* target_function,\n                                        void* replacement_function,\n                                        void** original_function_stub) {\n  if (!target_function || !replacement_function || !original_function_stub ||\n      (*original_function_stub) || target_function == replacement_function) {\n    SIDESTEP_ASSERT(false && \"Preconditions not met\");\n    return SIDESTEP_INVALID_PARAMETER;\n  }\n\n  // @see MAX_PREAMBLE_STUB_SIZE for an explanation of how we arrives at\n  // this size\n  unsigned char* preamble_stub = new unsigned char[MAX_PREAMBLE_STUB_SIZE];\n  if (!preamble_stub) {\n    SIDESTEP_ASSERT(false && \"Unable to allocate preamble-stub.\");\n    return SIDESTEP_INSUFFICIENT_BUFFER;\n  }\n\n  // Frees the array at end of scope.\n  DeleteUnsignedCharArray guard_preamble_stub(preamble_stub);\n\n  // Change the protection of the newly allocated preamble stub to\n  // PAGE_EXECUTE_READWRITE. This is required to work with DEP (Data\n  // Execution Prevention) which will cause an exception if code is executed\n  // from a page on which you do not have read access.\n  DWORD old_stub_protect = 0;\n  BOOL succeeded = ::VirtualProtect(preamble_stub, MAX_PREAMBLE_STUB_SIZE,\n                                    PAGE_EXECUTE_READWRITE, &old_stub_protect);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false &&\n                    \"Failed to make page preamble stub read-write-execute.\");\n    return SIDESTEP_ACCESS_DENIED;\n  }\n\n  SideStepError error_code = RawPatchWithStubAndProtections(\n      target_function, replacement_function, preamble_stub,\n      MAX_PREAMBLE_STUB_SIZE, NULL);\n\n  if (SIDESTEP_SUCCESS != error_code) {\n    SIDESTEP_ASSERT(false);\n    return error_code;\n  }\n\n  // Flush the instruction cache to make sure the processor doesn't execute the\n  // old version of the instructions (before our patch).\n  //\n  // FlushInstructionCache is actually a no-op at least on\n  // single-processor XP machines.  I'm not sure why this is so, but\n  // it is, yet I want to keep the call to the API here for\n  // correctness in case there is a difference in some variants of\n  // Windows/hardware.\n  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),\n                                      target_function,\n                                      MAX_PREAMBLE_STUB_SIZE);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false && \"Failed to flush instruction cache.\");\n    // We must not return an error here because the function has actually\n    // been patched, and returning an error would likely cause our client\n    // code not to unpatch it.  So we just keep going.\n  }\n\n  SIDESTEP_LOG(\"PreamblePatcher::RawPatch successfully patched.\");\n\n  // detach the scoped pointer so the memory is not freed\n  *original_function_stub =\n      reinterpret_cast<void*>(guard_preamble_stub.Release());\n  return SIDESTEP_SUCCESS;\n}\n\nSideStepError PreamblePatcher::Unpatch(void* target_function,\n                                       void* replacement_function,\n                                       void* original_function_stub) {\n  SIDESTEP_ASSERT(target_function && replacement_function &&\n                  original_function_stub);\n  if (!target_function || !replacement_function ||\n      !original_function_stub) {\n    return SIDESTEP_INVALID_PARAMETER;\n  }\n\n  // We disassemble the preamble of the _stub_ to see how many bytes we\n  // originally copied to the stub.\n  MiniDisassembler disassembler;\n  unsigned int preamble_bytes = 0;\n  while (preamble_bytes < 5) {\n    InstructionType instruction_type =\n        disassembler.Disassemble(\n            reinterpret_cast<unsigned char*>(original_function_stub) +\n            preamble_bytes,\n            preamble_bytes);\n    if (IT_GENERIC != instruction_type) {\n      SIDESTEP_ASSERT(false &&\n                      \"Should only have generic instructions in stub!!\");\n      return SIDESTEP_UNSUPPORTED_INSTRUCTION;\n    }\n  }\n\n  // Before unpatching, target_function should be a JMP to\n  // replacement_function.  If it's not, then either it's an error, or\n  // we're falling into the case where the original instruction was a\n  // JMP, and we patched the jumped_to address rather than the JMP\n  // itself.  (For instance, if malloc() is just a JMP to __malloc(),\n  // we patched __malloc() and not malloc().)\n  unsigned char* target = reinterpret_cast<unsigned char*>(target_function);\n  target = reinterpret_cast<unsigned char*>(\n      ResolveTargetImpl(\n          target, reinterpret_cast<unsigned char*>(replacement_function)));\n  // We should end at the function we patched.  When we patch, we insert\n  // a ASM_JMP32REL instruction, so look for that as a sanity check.\n  if (target[0] != ASM_JMP32REL) {\n    SIDESTEP_ASSERT(false &&\n                    \"target_function does not look like it was patched.\");\n    return SIDESTEP_INVALID_PARAMETER;\n  }\n\n  // We need to be able to write to a process-local copy of the first\n  // MAX_PREAMBLE_STUB_SIZE bytes of target_function\n  DWORD old_target_function_protect = 0;\n  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),\n                                    MAX_PREAMBLE_STUB_SIZE,\n                                    PAGE_EXECUTE_READWRITE,\n                                    &old_target_function_protect);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false && \"Failed to make page containing target function \"\n                    \"copy-on-write.\");\n    return SIDESTEP_ACCESS_DENIED;\n  }\n\n  // Replace the first few bytes of the original function with the bytes we\n  // previously moved to the preamble stub.\n  memcpy(reinterpret_cast<void*>(target),\n         original_function_stub, preamble_bytes);\n\n  // Stub is now useless so delete it.\n  // [csilvers: Commented out for perftools because it causes big problems\n  //  when we're unpatching malloc.  We just let this live on as a  leak.]\n  //delete [] reinterpret_cast<unsigned char*>(original_function_stub);\n\n  // Restore the protection of the first MAX_PREAMBLE_STUB_SIZE bytes of\n  // target to what they were before we started goofing around.\n  succeeded = ::VirtualProtect(reinterpret_cast<void*>(target),\n                               MAX_PREAMBLE_STUB_SIZE,\n                               old_target_function_protect,\n                               &old_target_function_protect);\n\n  // Flush the instruction cache to make sure the processor doesn't execute the\n  // old version of the instructions (before our patch).\n  //\n  // See comment on FlushInstructionCache elsewhere in this file.\n  succeeded = ::FlushInstructionCache(::GetCurrentProcess(),\n                                      target,\n                                      MAX_PREAMBLE_STUB_SIZE);\n  if (!succeeded) {\n    SIDESTEP_ASSERT(false && \"Failed to flush instruction cache.\");\n    return SIDESTEP_UNEXPECTED;\n  }\n\n  SIDESTEP_LOG(\"PreamblePatcher::Unpatch successfully unpatched.\");\n  return SIDESTEP_SUCCESS;\n}\n\n};  // namespace sidestep\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/preamble_patcher.h",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Definition of PreamblePatcher\n */\n\n#ifndef GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_\n#define GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_\n\n#include <windows.h>\n\n// compatibility shim\n#include \"base/logging.h\"\n#define SIDESTEP_ASSERT(cond)  RAW_DCHECK(cond, #cond)\n#define SIDESTEP_LOG(msg)      RAW_VLOG(1, msg)\n\n// Maximum size of the preamble stub. We overwrite at least the first 5\n// bytes of the function. Considering the worst case scenario, we need 4\n// bytes + the max instruction size + 5 more bytes for our jump back to\n// the original code. With that in mind, 32 is a good number :)\n#define MAX_PREAMBLE_STUB_SIZE    (32)\n\nnamespace sidestep {\n\n// Possible results of patching/unpatching\nenum SideStepError {\n  SIDESTEP_SUCCESS = 0,\n  SIDESTEP_INVALID_PARAMETER,\n  SIDESTEP_INSUFFICIENT_BUFFER,\n  SIDESTEP_JUMP_INSTRUCTION,\n  SIDESTEP_FUNCTION_TOO_SMALL,\n  SIDESTEP_UNSUPPORTED_INSTRUCTION,\n  SIDESTEP_NO_SUCH_MODULE,\n  SIDESTEP_NO_SUCH_FUNCTION,\n  SIDESTEP_ACCESS_DENIED,\n  SIDESTEP_UNEXPECTED,\n};\n\n#define SIDESTEP_TO_HRESULT(error)                      \\\n  MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)\n\n// Implements a patching mechanism that overwrites the first few bytes of\n// a function preamble with a jump to our hook function, which is then\n// able to call the original function via a specially-made preamble-stub\n// that imitates the action of the original preamble.\n//\n// NOTE:  This patching mechanism should currently only be used for\n// non-production code, e.g. unit tests, because it is not threadsafe.\n// See the TODO in preamble_patcher_with_stub.cc for instructions on what\n// we need to do before using it in production code; it's fairly simple\n// but unnecessary for now since we only intend to use it in unit tests.\n//\n// To patch a function, use either of the typesafe Patch() methods.  You\n// can unpatch a function using Unpatch().\n//\n// Typical usage goes something like this:\n// @code\n// typedef int (*MyTypesafeFuncPtr)(int x);\n// MyTypesafeFuncPtr original_func_stub;\n// int MyTypesafeFunc(int x) { return x + 1; }\n// int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); }\n// \n// void MyPatchInitializingFunction() {\n//   original_func_stub = PreamblePatcher::Patch(\n//              MyTypesafeFunc, HookMyTypesafeFunc);\n//   if (!original_func_stub) {\n//     // ... error handling ...\n//   }\n//\n//   // ... continue - you have patched the function successfully ...\n// }\n// @endcode\n//\n// Note that there are a number of ways that this method of patching can\n// fail.  The most common are:\n//    - If there is a jump (jxx) instruction in the first 5 bytes of\n//    the function being patched, we cannot patch it because in the\n//    current implementation we do not know how to rewrite relative\n//    jumps after relocating them to the preamble-stub.  Note that\n//    if you really really need to patch a function like this, it\n//    would be possible to add this functionality (but at some cost).\n//    - If there is a return (ret) instruction in the first 5 bytes\n//    we cannot patch the function because it may not be long enough\n//    for the jmp instruction we use to inject our patch.\n//    - If there is another thread currently executing within the bytes\n//    that are copied to the preamble stub, it will crash in an undefined\n//    way.\n//\n// If you get any other error than the above, you're either pointing the\n// patcher at an invalid instruction (e.g. into the middle of a multi-\n// byte instruction, or not at memory containing executable instructions)\n// or, there may be a bug in the disassembler we use to find\n// instruction boundaries.\n//\n// NOTE:  In optimized builds, when you have very trivial functions that\n// the compiler can reason do not have side effects, the compiler may\n// reuse the result of calling the function with a given parameter, which\n// may mean if you patch the function in between your patch will never get\n// invoked.  See preamble_patcher_test.cc for an example.\nclass PreamblePatcher {\n public:\n\n  // This is a typesafe version of RawPatch(), identical in all other\n  // ways than it takes a template parameter indicating the type of the\n  // function being patched.\n  //\n  // @param T The type of the function you are patching. Usually\n  // you will establish this type using a typedef, as in the following\n  // example:\n  // @code\n  // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT);\n  // MessageBoxPtr original = NULL;\n  // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original);\n  // @endcode\n  template <class T>\n  static SideStepError Patch(T target_function,\n                             T replacement_function,\n                             T* original_function_stub) {\n    // NOTE: casting from a function to a pointer is contra the C++\n    //       spec.  It's not safe on IA64, but is on i386.  We use\n    //       a C-style cast here to emphasize this is not legal C++.\n    return RawPatch((void*)(target_function),\n                    (void*)(replacement_function),\n                    (void**)(original_function_stub));\n  }\n\n  // Patches a named function imported from the named module using\n  // preamble patching.  Uses RawPatch() to do the actual patching\n  // work.\n  //\n  // @param T The type of the function you are patching.  Must\n  // exactly match the function you specify using module_name and\n  // function_name.\n  //\n  // @param module_name The name of the module from which the function\n  // is being imported.  Note that the patch will fail if this module\n  // has not already been loaded into the current process.\n  //\n  // @param function_name The name of the function you wish to patch.\n  //\n  // @param replacement_function Your replacement function which\n  // will be called whenever code tries to call the original function.\n  //\n  // @param original_function_stub Pointer to memory that should receive a\n  // pointer that can be used (e.g. in the replacement function) to call the\n  // original function, or NULL to indicate failure.\n  //\n  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS\n  // indicates success.\n  template <class T>\n  static SideStepError Patch(LPCTSTR module_name,\n                             LPCSTR function_name,\n                             T replacement_function,\n                             T* original_function_stub) {\n    SIDESTEP_ASSERT(module_name && function_name);\n    if (!module_name || !function_name) {\n      SIDESTEP_ASSERT(false &&\n                      \"You must specify a module name and function name.\");\n      return SIDESTEP_INVALID_PARAMETER;\n    }\n    HMODULE module = ::GetModuleHandle(module_name);\n    SIDESTEP_ASSERT(module != NULL);\n    if (!module) {\n      SIDESTEP_ASSERT(false && \"Invalid module name.\");\n      return SIDESTEP_NO_SUCH_MODULE;\n    }\n    FARPROC existing_function = ::GetProcAddress(module, function_name);\n    if (!existing_function) {\n      SIDESTEP_ASSERT(\n          false && \"Did not find any function with that name in the module.\");\n      return SIDESTEP_NO_SUCH_FUNCTION;\n    }\n    // NOTE: casting from a function to a pointer is contra the C++\n    //       spec.  It's not safe on IA64, but is on i386.  We use\n    //       a C-style cast here to emphasize this is not legal C++.\n    return RawPatch((void*)existing_function, (void*)replacement_function,\n                    (void**)(original_function_stub));\n  }\n\n  // Patches a function by overwriting its first few bytes with\n  // a jump to a different function.  This is the \"worker\" function\n  // for each of the typesafe Patch() functions.  In most cases,\n  // it is preferable to use the Patch() functions rather than\n  // this one as they do more checking at compile time.\n  //\n  // @param target_function A pointer to the function that should be\n  // patched.\n  //\n  // @param replacement_function A pointer to the function that should\n  // replace the target function.  The replacement function must have\n  // exactly the same calling convention and parameters as the original\n  // function.\n  //\n  // @param original_function_stub Pointer to memory that should receive a\n  // pointer that can be used (e.g. in the replacement function) to call the\n  // original function, or NULL to indicate failure.\n  //\n  // @param original_function_stub Pointer to memory that should receive a\n  // pointer that can be used (e.g. in the replacement function) to call the\n  // original function, or NULL to indicate failure.\n  //\n  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS\n  // indicates success.\n  //\n  // @note The preamble-stub (the memory pointed to by\n  // *original_function_stub) is allocated on the heap, and (in\n  // production binaries) never destroyed, resulting in a memory leak.  This\n  // will be the case until we implement safe unpatching of a method.\n  // However, it is quite difficult to unpatch a method (because other\n  // threads in the process may be using it) so we are leaving it for now.\n  // See however UnsafeUnpatch, which can be used for binaries where you\n  // know only one thread is running, e.g. unit tests.\n  static SideStepError RawPatch(void* target_function,\n                                void* replacement_function,\n                                void** original_function_stub);\n\n  // Unpatches target_function and deletes the stub that previously could be\n  // used to call the original version of the function.\n  //\n  // DELETES the stub that is passed to the function.\n  //\n  // @param target_function Pointer to the target function which was\n  // previously patched, i.e. a pointer which value should match the value\n  // of the symbol prior to patching it.\n  //\n  // @param replacement_function Pointer to the function target_function\n  // was patched to.\n  //\n  // @param original_function_stub Pointer to the stub returned when\n  // patching, that could be used to call the original version of the\n  // patched function.  This function will also delete the stub, which after\n  // unpatching is useless.\n  //\n  // If your original call was\n  //    Patch(VirtualAlloc, MyVirtualAlloc, &origptr)\n  // then to undo it you would call\n  //    Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);\n  //\n  // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS\n  // indicates success.\n  static SideStepError Unpatch(void* target_function,\n                               void* replacement_function,\n                               void* original_function_stub);\n\n  // A helper routine when patching, which follows jmp instructions at\n  // function addresses, to get to the \"actual\" function contents.\n  // This allows us to identify two functions that are at different\n  // addresses but actually resolve to the same code.\n  //\n  // @param target_function Pointer to a function.\n  //\n  // @return Either target_function (the input parameter), or if\n  // target_function's body consists entirely of a JMP instruction,\n  // the address it JMPs to (or more precisely, the address at the end\n  // of a chain of JMPs).\n  template <class T>\n  static T ResolveTarget(T target_function) {\n    return (T)ResolveTargetImpl((unsigned char*)target_function, NULL);\n  }\n\n private:\n  // Patches a function by overwriting its first few bytes with\n  // a jump to a different function.  This is similar to the RawPatch\n  // function except that it uses the stub allocated by the caller\n  // instead of allocating it.\n  //\n  // We call VirtualProtect to make the\n  // target function writable at least for the duration of the call.\n  //\n  // @param target_function A pointer to the function that should be\n  // patched.\n  //\n  // @param replacement_function A pointer to the function that should\n  // replace the target function.  The replacement function must have\n  // exactly the same calling convention and parameters as the original\n  // function.\n  //\n  // @param preamble_stub A pointer to a buffer where the preamble stub\n  // should be copied. The size of the buffer should be sufficient to\n  // hold the preamble bytes.\n  //\n  // @param stub_size Size in bytes of the buffer allocated for the\n  // preamble_stub\n  //\n  // @param bytes_needed Pointer to a variable that receives the minimum\n  // number of bytes required for the stub.  Can be set to NULL if you're\n  // not interested.\n  //\n  // @return An error code indicating the result of patching.\n  static SideStepError RawPatchWithStubAndProtections(\n      void* target_function,\n      void *replacement_function,\n      unsigned char* preamble_stub,\n      unsigned long stub_size,\n      unsigned long* bytes_needed);\n\n  // A helper function used by RawPatchWithStubAndProtections -- it\n  // does everything but the VirtualProtect work.  Defined in\n  // preamble_patcher_with_stub.cc.\n  //\n  // @param target_function A pointer to the function that should be\n  // patched.\n  //\n  // @param replacement_function A pointer to the function that should\n  // replace the target function.  The replacement function must have\n  // exactly the same calling convention and parameters as the original\n  // function.\n  //\n  // @param preamble_stub A pointer to a buffer where the preamble stub\n  // should be copied. The size of the buffer should be sufficient to\n  // hold the preamble bytes.\n  //\n  // @param stub_size Size in bytes of the buffer allocated for the\n  // preamble_stub\n  //\n  // @param bytes_needed Pointer to a variable that receives the minimum\n  // number of bytes required for the stub.  Can be set to NULL if you're\n  // not interested.\n  //\n  // @return An error code indicating the result of patching.\n  static SideStepError RawPatchWithStub(void* target_function,\n                                        void *replacement_function,\n                                        unsigned char* preamble_stub,\n                                        unsigned long stub_size,\n                                        unsigned long* bytes_needed);\n\n\n  // A helper routine when patching, which follows jmp instructions at\n  // function addresses, to get to the \"actual\" function contents.\n  // This allows us to identify two functions that are at different\n  // addresses but actually resolve to the same code.\n  //\n  // @param target_function Pointer to a function.\n  //\n  // @param stop_before If, when following JMP instructions from\n  // target_function, we get to the address stop, we return\n  // immediately, the address that jumps to stop_before.\n  //\n  // @return Either target_function (the input parameter), or if\n  // target_function's body consists entirely of a JMP instruction,\n  // the address it JMPs to (or more precisely, the address at the end\n  // of a chain of JMPs).\n  static void* ResolveTargetImpl(unsigned char* target_function,\n                                 unsigned char* stop_before);\n};\n\n};  // namespace sidestep\n\n#endif  // GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_\n"
  },
  {
    "path": "distro/google-perftools-1.7/src/windows/preamble_patcher_with_stub.cc",
    "content": "/* Copyright (c) 2007, Google Inc.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n * \n *     * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *     * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n *     * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * ---\n * Author: Joi Sigurdsson\n *\n * Implementation of PreamblePatcher\n */\n\n#include \"preamble_patcher.h\"\n\n#include \"mini_disassembler.h\"\n\n// Definitions of assembly statements we need\n#define ASM_JMP32REL 0xE9\n#define ASM_INT3 0xCC\n\nnamespace sidestep {\n\nSideStepError PreamblePatcher::RawPatchWithStub(\n    void* target_function,\n    void *replacement_function,\n    unsigned char* preamble_stub,\n    unsigned long stub_size,\n    unsigned long* bytes_needed) {\n  if ((NULL == target_function) ||\n      (NULL == replacement_function) ||\n      (NULL == preamble_stub)) {\n    SIDESTEP_ASSERT(false &&\n                    \"Invalid parameters - either pTargetFunction or \"\n                    \"pReplacementFunction or pPreambleStub were NULL.\");\n    return SIDESTEP_INVALID_PARAMETER;\n  }\n\n  // TODO(V7:joi) Siggi and I just had a discussion and decided that both\n  // patching and unpatching are actually unsafe.  We also discussed a\n  // method of making it safe, which is to freeze all other threads in the\n  // process, check their thread context to see if their eip is currently\n  // inside the block of instructions we need to copy to the stub, and if so\n  // wait a bit and try again, then unfreeze all threads once we've patched.\n  // Not implementing this for now since we're only using SideStep for unit\n  // testing, but if we ever use it for production code this is what we\n  // should do.\n  //\n  // NOTE: Stoyan suggests we can write 8 or even 10 bytes atomically using\n  // FPU instructions, and on newer processors we could use cmpxchg8b or\n  // cmpxchg16b. So it might be possible to do the patching/unpatching\n  // atomically and avoid having to freeze other threads.  Note though, that\n  // doing it atomically does not help if one of the other threads happens\n  // to have its eip in the middle of the bytes you change while you change\n  // them.\n\n  // First, deal with a special case that we see with functions that\n  // point into an IAT table (including functions linked statically\n  // into the application): these function already starts with\n  // ASM_JMP32REL.  For instance, malloc() might be implemented as a\n  // JMP to __malloc().  In that case, we replace the destination of\n  // the JMP (__malloc), rather than the JMP itself (malloc).  This\n  // way we get the correct behavior no matter how malloc gets called.\n  void *new_target = ResolveTarget(target_function);\n  if (new_target != target_function) {   // we're in the IAT case\n    // I'd like to just say \"target = new_target\", but I can't,\n    // because the new target will need to have its protections set.\n    return RawPatchWithStubAndProtections(new_target, replacement_function,\n                                          preamble_stub, stub_size,\n                                          bytes_needed);\n  }\n  unsigned char* target = reinterpret_cast<unsigned char*>(new_target);\n\n  // Let's disassemble the preamble of the target function to see if we can\n  // patch, and to see how much of the preamble we need to take.  We need 5\n  // bytes for our jmp instruction, so let's find the minimum number of\n  // instructions to get 5 bytes.\n  MiniDisassembler disassembler;\n  unsigned int preamble_bytes = 0;\n  while (preamble_bytes < 5) {\n    InstructionType instruction_type =\n        disassembler.Disassemble(target + preamble_bytes, preamble_bytes);\n    if (IT_JUMP == instruction_type) {\n      SIDESTEP_ASSERT(false &&\n                      \"Unable to patch because there is a jump instruction \"\n                      \"in the first 5 bytes.\");\n      return SIDESTEP_JUMP_INSTRUCTION;\n    } else if (IT_RETURN == instruction_type) {\n      SIDESTEP_ASSERT(false &&\n                      \"Unable to patch because function is too short\");\n      return SIDESTEP_FUNCTION_TOO_SMALL;\n    } else if (IT_GENERIC != instruction_type) {\n      SIDESTEP_ASSERT(false &&\n                      \"Disassembler encountered unsupported instruction \"\n                      \"(either unused or unknown\");\n      return SIDESTEP_UNSUPPORTED_INSTRUCTION;\n    }\n  }\n\n  if (NULL != bytes_needed)\n    *bytes_needed = preamble_bytes + 5;\n\n  // Inv: cbPreamble is the number of bytes (at least 5) that we need to take\n  // from the preamble to have whole instructions that are 5 bytes or more\n  // in size total. The size of the stub required is cbPreamble + size of\n  // jmp (5)\n  if (preamble_bytes + 5 > stub_size) {\n    SIDESTEP_ASSERT(false);\n    return SIDESTEP_INSUFFICIENT_BUFFER;\n  }\n\n  // First, copy the preamble that we will overwrite.\n  memcpy(reinterpret_cast<void*>(preamble_stub),\n         reinterpret_cast<void*>(target), preamble_bytes);\n\n  // Now, make a jmp instruction to the rest of the target function (minus the\n  // preamble bytes we moved into the stub) and copy it into our preamble-stub.\n  // find address to jump to, relative to next address after jmp instruction\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4244)\n#endif\n  int relative_offset_to_target_rest\n      = ((reinterpret_cast<unsigned char*>(target) + preamble_bytes) -\n         (preamble_stub + preamble_bytes + 5));\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n  // jmp (Jump near, relative, displacement relative to next instruction)\n  preamble_stub[preamble_bytes] = ASM_JMP32REL;\n  // copy the address\n  memcpy(reinterpret_cast<void*>(preamble_stub + preamble_bytes + 1),\n         reinterpret_cast<void*>(&relative_offset_to_target_rest), 4);\n\n  // Inv: preamble_stub points to assembly code that will execute the\n  // original function by first executing the first cbPreamble bytes of the\n  // preamble, then jumping to the rest of the function.\n\n  // Overwrite the first 5 bytes of the target function with a jump to our\n  // replacement function.\n  // (Jump near, relative, displacement relative to next instruction)\n  target[0] = ASM_JMP32REL;\n\n  // Find offset from instruction after jmp, to the replacement function.\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4244)\n#endif\n  int offset_to_replacement_function =\n      reinterpret_cast<unsigned char*>(replacement_function) -\n      reinterpret_cast<unsigned char*>(target) - 5;\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n  // complete the jmp instruction\n  memcpy(reinterpret_cast<void*>(target + 1),\n         reinterpret_cast<void*>(&offset_to_replacement_function), 4);\n  // Set any remaining bytes that were moved to the preamble-stub to INT3 so\n  // as not to cause confusion (otherwise you might see some strange\n  // instructions if you look at the disassembly, or even invalid\n  // instructions). Also, by doing this, we will break into the debugger if\n  // some code calls into this portion of the code.  If this happens, it\n  // means that this function cannot be patched using this patcher without\n  // further thought.\n  if (preamble_bytes > 5) {\n    memset(reinterpret_cast<void*>(target + 5), ASM_INT3, preamble_bytes - 5);\n  }\n\n  // Inv: The memory pointed to by target_function now points to a relative\n  // jump instruction that jumps over to the preamble_stub.  The preamble\n  // stub contains the first stub_size bytes of the original target\n  // function's preamble code, followed by a relative jump back to the next\n  // instruction after the first cbPreamble bytes.\n\n  return SIDESTEP_SUCCESS;\n}\n\n};  // namespace sidestep\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/addr2line-pdb/addr2line-pdb.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"addr2line-pdb\"\r\n\tProjectGUID=\"{81CA712E-90B8-4AE5-9E89-5B436578D6DA}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"dbghelp.lib\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/addr2line-pdb.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/addr2line-pdb.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"dbghelp.lib\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/addr2line-pdb.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\addr2line-pdb.c\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/addressmap_unittest/addressmap_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"addressmap_unittest\"\r\n\tProjectGUID=\"{32EECEB6-7D18-477E-BC7A-30CE98457A88}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/addressmap_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/addressmap_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/addressmap_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\addressmap_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.c\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\sysinfo.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\addressmap-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\basictypes.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\commandlineflags.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-arm-gcc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-linuxppc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-macosx.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_linux-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_posix-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\cycleclock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/frag_unittest/frag_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"frag_unittest\"\r\n\tProjectGUID=\"{24754725-DE0D-4214-8979-324247AAD78E}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/frag_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/frag_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/frag_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\frag_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"libtcmalloc_minimal\"\r\n\tProjectGUID=\"{55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBTCMALLOC_MINIMAL_EXPORTS\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"1\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/libtcmalloc_minimal-debug.dll\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/libtcmalloc_minimal.pdb\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tImportLibrary=\"$(OutDir)/libtcmalloc_minimal-debug.lib\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBTCMALLOC_MINIMAL_EXPORTS\"\r\n\t\t\t\tRuntimeLibrary=\"0\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/libtcmalloc_minimal.dll\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tImportLibrary=\"$(OutDir)/libtcmalloc_minimal.lib\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\central_freelist.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.c\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\heap-profile-table.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\symbolize.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\ia32_modrm_map.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\ia32_opcode_map.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\common.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\internal_logging.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\low_level_alloc.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_extension.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_hook.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\memory_region_map.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\mini_disassembler.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\sampler.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\patch_functions.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\preamble_patcher.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\preamble_patcher_with_stub.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\raw_printer.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\span.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stack_trace_table.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\static_vars.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\sysinfo.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\thread_cache.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\addressmap-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\basictypes.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\central_freelist.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\commandlineflags.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\googleinit.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\heap-checker.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\heap-profile-table.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\symbolize.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\heap-profiler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\common.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\internal_logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\linked_list.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\low_level_alloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-arm-gcc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-linuxppc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-macosx.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_linux-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_posix-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_extension.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_hook.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_hook-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\memory_region_map.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\mini_disassembler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\mini_disassembler_types.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\mutex.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\packed-cache-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap_allocator.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\pagemap.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\preamble_patcher.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\profiler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\raw_printer.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\sampler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\span.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\stacktrace.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace_config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stack_trace_table.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\static_vars.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\stl_allocator.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\sysinfo.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\system-alloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tcmalloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\thread_annotations.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\thread_cache.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"low_level_alloc_unittest\"\r\n\tProjectGUID=\"{A765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/low_level_alloc_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/low_level_alloc_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/low_level_alloc_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.c\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\sysinfo.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\low_level_alloc.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\low_level_alloc_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_hook.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\basictypes.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\commandlineflags.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-arm-gcc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-linuxppc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-macosx.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_linux-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_posix-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\cycleclock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\low_level_alloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_hook.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_hook-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace_win32-inl.h.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\stacktrace.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\stacktrace_config.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/malloc_extension_test/malloc_extension_test.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"malloc_extension_test\"\r\n\tProjectGUID=\"{3765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/malloc_extension_test.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/malloc_extension_test.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/malloc_extension_test.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{3FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\malloc_extension_test.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{33995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_extension.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_extension_c.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/markidle_unittest/markidle_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"markidle_unittest\"\r\n\tProjectGUID=\"{4AF7E21D-9D0A-410C-A7DB-7D21DA5166C0}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/markidle_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/markidle_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/markidle_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\markidle_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/nm-pdb/nm-pdb.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"nm-pdb\"\r\n\tProjectGUID=\"{3A559C75-FD26-4300-B86B-165FD43EE1CE}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"dbghelp.lib\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/nm-pdb.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/nm-pdb.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tAdditionalDependencies=\"dbghelp.lib\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/nm-pdb.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\nm-pdb.c\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/packed-cache_test/packed-cache_test.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"packed-cache_test\"\r\n\tProjectGUID=\"{605D3CED-B530-424E-B7D2-2A31F14FD570}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/packed-cache_test.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/packed-cache_test.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/packed-cache_test.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\packed-cache_test.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-arm-gcc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-linuxppc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-macosx.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_linux-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_posix-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\cycleclock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\basictypes.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\commandlineflags.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\packed-cache-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/page_heap_test/page_heap_test.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"page_heap_test\"\r\n\tProjectGUID=\"{9765198D-5305-4AB0-9A21-A0CD8201EB2B}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/page_heap_test.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/page_heap_test.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/page_heap_test.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{9FC737F1-C7A5-4376-A066-2A32D752A2FE}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\page_heap_test.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFE}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\common.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/pagemap_unittest/pagemap_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"pagemap_unittest\"\r\n\tProjectGUID=\"{9765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/pagemap_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/pagemap_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/pagemap_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{9FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\pagemap_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\pagemap.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/realloc_unittest/realloc_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"realloc_unittest\"\r\n\tProjectGUID=\"{4765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/realloc_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/realloc_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/realloc_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\realloc_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{43995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/sampler_test/sampler_test.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"sampler_test\"\r\n\tProjectGUID=\"{B765198D-5305-4AB0-9A21-A0CD8201EB2A}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/sampler_test.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/sampler_test.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/sampler_test.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{BFC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\sampler_test.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{B3995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\commandlineflags.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/stack_trace_table_test/stack_trace_table_test.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"stack_trace_table_test\"\r\n\tProjectGUID=\"{A4754725-DE0D-4214-8979-324247AAD78E}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/stack_trace_table_test.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/stack_trace_table_test.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/stack_trace_table_test.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{AFC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\stack_trace_table_test.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{A3995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stack_trace_table.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"tcmalloc_minimal_large_unittest\"\r\n\tProjectGUID=\"{2D8B9599-C74C-4298-B723-6CF6077563E3}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/tcmalloc_minimal_large_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/tcmalloc_minimal_large_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/tcmalloc_minimal_large_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\tcmalloc_large_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"tcmalloc_minimal_unittest\"\r\n\tProjectGUID=\"{7CC73D97-C057-43A6-82EF-E6B567488D02}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/tcmalloc_minimal_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/tcmalloc_minimal_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/tcmalloc_minimal_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\tcmalloc_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"thread_dealloc_unittest\"\r\n\tProjectGUID=\"{6CFFBD0F-09E3-4282-A711-0564451FDF74}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/thread_dealloc_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/thread_dealloc_unittest.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/thread_dealloc_unittest.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n                                ForceSymbolReferences=\"__tcmalloc\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\thread_dealloc_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/google-perftools-1.7/vsprojects/tmu-static/tmu-static.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"7.10\"\r\n\tName=\"tcmalloc_minimal_unittest-static\"\r\n\tProjectGUID=\"{8F708DCB-7EE4-4BA0-81AA-A52A0BA73B74}\"\r\n\tKeyword=\"Win32Proj\">\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"/>\r\n\t</Platforms>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_DEBUG;_CONSOLE\"\r\n\t\t\t\tMinimalRebuild=\"TRUE\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"5\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/tcmalloc_minimal_unittest-static.exe\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/tcmalloc_minimal_unittest-static.pdb\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"1\"\r\n\t\t\tCharacterSet=\"2\">\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;NDEBUG;_CONSOLE\"\r\n\t\t\t\tRuntimeLibrary=\"4\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tOutputFile=\"$(OutDir)/tcmalloc_minimal_unittest-static.exe\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tGenerateDebugInformation=\"TRUE\"\r\n\t\t\t\tSubSystem=\"1\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedWrapperGeneratorTool\"/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAuxiliaryManagedWrapperGeneratorTool\"/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Source Files\"\r\n\t\t\tFilter=\"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\central_freelist.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\dynamic_annotations.c\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\heap-profile-table.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\symbolize.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\ia32_modrm_map.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\ia32_opcode_map.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\common.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\internal_logging.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\low_level_alloc.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_extension.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_hook.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\memory_region_map.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\mini_disassembler.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\sampler.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\patch_functions.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\preamble_patcher.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\preamble_patcher_with_stub.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\raw_printer.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\span.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stack_trace_table.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\static_vars.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\sysinfo.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows;..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\tcmalloc_unittest.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\thread_cache.cc\">\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Debug|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"3\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t\t<FileConfiguration\r\n\t\t\t\t\tName=\"Release|Win32\">\r\n\t\t\t\t\t<Tool\r\n\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\t\t\tAdditionalOptions=\"/D PERFTOOLS_DLL_DECL=\"\r\n\t\t\t\t\t\tAdditionalIncludeDirectories=\"..\\..\\src\\windows; ..\\..\\src\"\r\n\t\t\t\t\t\tRuntimeLibrary=\"2\"/>\r\n\t\t\t\t</FileConfiguration>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Header Files\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\">\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\addressmap-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\basictypes.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\central_freelist.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\commandlineflags.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\config_for_unittests.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\googleinit.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\heap-checker.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\heap-profile-table.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\symbolize.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\heap-profiler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\common.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\internal_logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\linked_list.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\logging.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\low_level_alloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-arm-gcc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-linuxppc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-macosx.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_internal.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_linux-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_posix-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\spinlock_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_extension.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\malloc_hook.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\malloc_hook-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\atomicops-internals-x86-msvc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\memory_region_map.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\mini_disassembler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\mini_disassembler_types.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\mutex.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\packed-cache-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\page_heap_allocator.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\pagemap.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\port.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\windows\\preamble_patcher.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\profiler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\span.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\stacktrace.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\google\\stacktrace_config.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stacktrace_win32-inl.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\raw_printer.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\sampler.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\stack_trace_table.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\static_vars.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\stl_allocator.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\sysinfo.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\system-alloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tcmalloc.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\tests\\testutil.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\base\\thread_annotations.h\">\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\src\\thread_cache.h\">\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Resource Files\"\r\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx\"\r\n\t\t\tUniqueIdentifier=\"{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}\">\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "distro/installer",
    "content": "#!/bin/sh\n# Simple bootstrap script for the installer. This script uses the bundled\n# Ruby interpreter binary whenever possible, and falls back to the system's\n# Ruby interpreter if no suitable bundled Ruby interpreter exists.\ndir=`dirname \"$0\"`\ncd \"$dir\"\n\nunset GEM_HOME\nunset GEM_PATH\nunset RUBYOPT\n\nplatform=\"`uname`-`uname -m`\"\nif (ruby -e '') 2>/dev/null; then\n\texec ruby installer.rb \"$@\"\nelse\n\t#echo \"Using 'runtime/$platform/ruby'\"\n\tif (\"runtime/$platform/ruby\" -e '') 2>/dev/null; then\n\t\texec \"runtime/$platform/ruby\" installer.rb \"$@\"\n\telse\n\t\techo \"*** ERROR: Ruby is not installed ***\" >&2\n\t\techo \"The Ruby Enterprise Edition installer is written in Ruby. This source tarball bundles precompiled versions of Ruby for many platforms for the purpose of running this installer, but unfortunately we did not include a precompiled Ruby binary for the current platform. So please install Ruby manually, then run this installer again.\" >&2\n\t\texit 10\n\tfi\nfi\n"
  },
  {
    "path": "distro/installer.rb",
    "content": "#!/usr/bin/env ruby\nrequire \"#{File.dirname(__FILE__)}/optparse\"\nrequire \"#{File.dirname(__FILE__)}/dependencies\"\n\nclass Installer\n\tinclude RubyEnterpriseEdition\n\n\tROOT = File.expand_path(File.dirname(__FILE__))\n\tPASSENGER_WEBSITE = \"http://www.modrails.com\"\n\tEMM_RUBY_WEBSITE = \"http://www.rubyenterpriseedition.com\"\n\tREQUIRED_DEPENDENCIES = [\n\t\t# Don't forget to update the dependency list in the manual too.\n\t\tDependencies::CC,\n\t\tDependencies::CXX,\n\t\tDependencies::Make,\n\t\tDependencies::Patch,\n\t\tDependencies::Zlib_Dev,\n\t\tDependencies::OpenSSL_Dev,\n\t\tDependencies::Readline_Dev\n\t]\n\n\tdef start(options = {})\n\t\tDir.chdir(ROOT)\n\t\t@version = File.read(\"version.txt\")\n\t\t@auto_install_prefix = options[:prefix]\n\t\t@destdir = strip_trailing_slashes(options[:destdir])\n\t\t@install_useful_gems = options[:install_useful_gems]\n\t\t@use_tcmalloc = options[:tcmalloc]\n\t\t@fast_threading = options[:fast_threading]\n\t\tif !options[:extra_configure_args].empty?\n\t\t\t@extra_configure_args = options[:extra_configure_args].join(\" \")\n\t\tend\n\n\t\tif RUBY_PLATFORM =~ /darwin/\n\t\t\tENV['PATH'] = \"#{ENV['PATH']}:/usr/local/mysql/bin\"\n\t\tend\n\n\t\tshow_welcome_screen\n\t\tcheck_dependencies || exit(1)\n\t\task_installation_prefix\n\n\t\tsteps = []\n\t\tif tcmalloc_supported?\n\t\t\tsteps += [\n\t\t\t  :configure_tcmalloc,\n\t\t\t  :compile_tcmalloc,\n\t\t\t  :install_tcmalloc\n\t\t\t]\n\t\tend\n\t\tsteps += [\n\t\t  :configure_ruby,\n\t\t  :compile_system_allocator,\n\t\t  :compile_ruby,\n\t\t  :install_ruby]\n\t\tsteps += [:install_dev_docs] if options[:install_dev_docs]\n\t\tsteps += [\n\t\t  :install_ree_specific_binaries,\n\t\t  :install_rubygems,\n\t\t  :install_iconv\n\t\t]\n\t\tsteps.each do |step|\n\t\t\tif !self.send(step)\n\t\t\t\texit 1\n\t\t\tend\n\t\tend\n\t\tinstall_useful_libraries\n\t\tshow_finalization_screen\n\tensure\n\t\treset_terminal_colors\n\tend\n\nprivate\n\tdef show_welcome_screen\n\t\tcolor_puts \"<banner>Welcome to the Ruby Enterprise Edition installer</banner>\"\n\t\tcolor_puts \"This installer will help you install Ruby Enterprise Edition #{@version}.\"\n\t\tcolor_puts \"Don't worry, none of your system files will be touched if you don't want them\"\n\t\tcolor_puts \"to, so there is no risk that things will screw up.\"\n\t\tputs\n\t\tcolor_puts \"You can expect this from the installation process:\"\n\t\tputs\n\t\tcolor_puts \"  <b>1.</b> Ruby Enterprise Edition will be compiled and optimized for speed for this\"\n\t\tcolor_puts \"     system.\"\n\t\tcolor_puts \"  <b>2.</b> Ruby on Rails will be installed for Ruby Enterprise Edition.\"\n\t\tcolor_puts \"  <b>3.</b> You will learn how to tell Phusion Passenger to use Ruby Enterprise\"\n\t\tcolor_puts \"     Edition instead of regular Ruby.\"\n\t\tputs\n\t\tcolor_puts \"<b>Press Enter to continue, or Ctrl-C to abort.</b>\"\n\t\twait\n\tend\n\n\tdef check_dependencies\n\t\tmissing_dependencies = []\n\t\tcolor_puts \"<banner>Checking for required software...</banner>\"\n\t\tputs\n\t\tREQUIRED_DEPENDENCIES.each do |dep|\n\t\t\tcolor_print \" * #{dep.name}... \"\n\t\t\tresult = dep.check\n\t\t\tif result.found?\n\t\t\t\tif result.found_at\n\t\t\t\t\tcolor_puts \"<green>found at #{result.found_at}</green>\"\n\t\t\t\telse\n\t\t\t\t\tcolor_puts \"<green>found</green>\"\n\t\t\t\tend\n\t\t\telse\n\t\t\t\tcolor_puts \"<red>not found</red>\"\n\t\t\t\tmissing_dependencies << dep\n\t\t\tend\n\t\tend\n\n\t\tif missing_dependencies.empty?\n\t\t\treturn true\n\t\telse\n\t\t\tputs\n\t\t\tcolor_puts \"<red>Some required software is not installed.</red>\"\n\t\t\tcolor_puts \"But don't worry, this installer will tell you how to install them.\\n\"\n\t\t\tcolor_puts \"<b>Press Enter to continue, or Ctrl-C to abort.</b>\"\n\t\t\twait\n\n\t\t\tline\n\t\t\tcolor_puts \"<banner>Installation instructions for required software</banner>\"\n\t\t\tputs\n\t\t\tmissing_dependencies.each do |dep|\n\t\t\t\tprint_dependency_installation_instructions(dep)\n\t\t\t\tputs\n\t\t\tend\n\t\t\treturn false\n\t\tend\n\tend\n\n\tdef print_dependency_installation_instructions(dep)\n\t\tcolor_puts \" * To install <yellow>#{dep.name}</yellow>:\"\n\t\tif !dep.install_command.nil?\n\t\t\tcolor_puts \"   Please run <b>#{dep.install_command}</b> as root.\"\n\t\telsif !dep.install_instructions.nil?\n\t\t\tcolor_puts \"   \" << dep.install_instructions\n\t\telsif !dep.website.nil?\n\t\t\tcolor_puts \"   Please download it from <b>#{dep.website}</b>\"\n\t\t\tif !dep.website_comments.nil?\n\t\t\t\tcolor_puts \"   (#{dep.website_comments})\"\n\t\t\tend\n\t\telse\n\t\t\tcolor_puts \"   Search Google.\"\n\t\tend\n\tend\n\n\tdef strip_trailing_slashes(data)\n\t\tif data.nil?\n\t\t\treturn nil\n\t\telse\n\t\t\tresult = data.sub(/\\/+$/, '')\n\t\t\tif result.empty? && !data.empty?\n\t\t\t\treturn '/'\n\t\t\telse\n\t\t\t\treturn result\n\t\t\tend\n\t\tend\n\tend\n\n\tdef ask_installation_prefix\n\t\tline\n\t\tcolor_puts \"<banner>Target directory</banner>\"\n\t\tputs\n\t\t@old_prefix = File.read(\"source/.prefix.txt\") rescue nil\n\t\tif @auto_install_prefix\n\t\t\t@prefix = @auto_install_prefix\n\t\t\tputs \"Auto-installing to: #{@prefix}\"\n\t\telse\n\t\t\tputs \"Where would you like to install Ruby Enterprise Edition to?\"\n\t\t\tputs \"(All Ruby Enterprise Edition files will be put inside that directory.)\"\n\t\t\tputs\n\t\t\t@prefix = query_directory(@old_prefix || \"/opt/ruby-enterprise-#{@version}\")\n\t\tend\n\t\t@prefix = strip_trailing_slashes(@prefix)\n\t\t@prefix_changed = @prefix != @old_prefix\n\t\tFile.open(\"source/.prefix.txt\", \"w\") do |f|\n\t\t\tf.write(@prefix)\n\t\tend\n\n\t\tif @destdir && !@destdir =~ /\\/$/\n\t\t\t@destdir += \"/\"\n\t\tend\n\n\t\tENV['CPATH'] = \"#{@destdir}#{@prefix}/include:/usr/include:/usr/local/include:#{ENV['CPATH']}\"\n\t\tENV['LD_LIBRARY_PATH'] = \"#{@destdir}#{@prefix}/lib:#{ENV['LD_LIBRARY_PATH']}\"\n\t\tENV['DYLD_LIBRARY_PATH'] = \"#{@destdir}#{@prefix}/lib:#{ENV['DYLD_LIBRARY_PATH']}\"\n\tend\n\n\tdef configure_tcmalloc\n\t\treturn configure_autoconf_package('source/distro/google-perftools-1.7',\n\t\t\t'the memory allocator for Ruby Enterprise Edition',\n\t\t\t'--disable-dependency-tracking')\n\tend\n\n\tdef compile_tcmalloc\n\t\tDir.chdir('source/distro/google-perftools-1.7') do\n\t\t\treturn sh(\"make libtcmalloc_minimal.la\")\n\t\tend\n\tend\n\n\tdef install_tcmalloc\n\t\treturn install_autoconf_package('source/distro/google-perftools-1.7',\n\t\t  'the memory allocator for Ruby Enterprise Edition') do\n\t\t\tsh(\"mkdir\", \"-p\", \"#{@destdir}#{@prefix}/lib\") &&\n\t\t\t# Remove existing .so files so that the copy operation doesn't\n\t\t\t# overwrite the existing files in-place. Overwriting shared\n\t\t\t# libraries in-place can cause existing processes that use\n\t\t\t# those libraries to crash.\n\t\t\tsh(\"rm -rf '#{@destdir}#{@prefix}/lib'/libtcmalloc_minimal*.#{PlatformInfo::LIBEXT}*\") &&\n\t\t\tsh(\"cp -Rpf .libs/libtcmalloc_minimal*.#{PlatformInfo::LIBEXT}* '#{@destdir}#{@prefix}/lib/'\")\n\t\tend\n\tend\n\n\tdef configure_ruby\n\t\treturn configure_autoconf_package('source', 'Ruby Enterprise Edition',\n\t\t\t\"#{@extra_configure_args} \" <<\n\t\t\t\"CFLAGS='-g -O2 #{ENV['CFLAGS']}'\")\n\tend\n\n\tdef compile_system_allocator\n\t\tif platform_uses_two_level_namespace_for_dynamic_libraries?\n\t\t\tDir.chdir(\"source\") do\n\t\t\t\t@using_system_allocator_library = true\n\t\t\t\t# On platforms that use a two-level symbol namespace for\n\t\t\t\t# dynamic libraries (most notably MacOS X), integrating\n\t\t\t\t# tcmalloc requires a special library. See system_allocator.c\n\t\t\t\t# for more information.\n\t\t\t\tENV['DYLD_LIBRARY_PATH'] = \"#{ROOT}/source:#{ENV['DYLD_LIBRARY_PATH']}\"\n\t\t\t\treturn sh(\"#{PlatformInfo::CC} #{ENV['CFLAGS']} #{ENV['LDFLAGS']} -dynamiclib system_allocator.c -install_name @rpath/libsystem_allocator.dylib -o libsystem_allocator.dylib\")\n\t\t\tend\n\t\telse\n\t\t\treturn true\n\t\tend\n\tend\n\n\tdef compile_ruby\n\t\tDir.chdir(\"source\") do\n\t\t\tif fast_threading_patch_applied?\n\t\t\t\tif !@fast_threading\n\t\t\t\t\tsh \"patch -p1 -R < ../fast-threading.patch\"\n\t\t\t\tend\n\t\t\telse\n\t\t\t\tif @fast_threading\n\t\t\t\t\tsh \"patch -p1 < ../fast-threading.patch\"\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# No idea why, but sometimes 'make' fails unless we do this.\n\t\t\tsh(\"mkdir -p .ext/common\")\n\n\t\t\tmakefile = File.read('Makefile')\n\t\t\tif makefile !~ /\\$\\(PRELIBS\\)/\n\t\t\t\tmakefile.sub!(/^LIBS = (.*)$/, 'LIBS = $(PRELIBS) \\1')\n\t\t\t\tFile.open('Makefile', 'w') do |f|\n\t\t\t\t\tf.write(makefile)\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tprelibs = \"-Wl,\"\n\t\t\tif PlatformInfo.solaris_ld?\n\t\t\t\tprelibs << \"-R#{@prefix}/lib\"\n\t\t\telse\n\t\t\t\tprelibs << \"-rpath,#{@prefix}/lib\"\n\t\t\tend\n\t\t\tprelibs << \" -L#{@destdir}#{@prefix}/lib\"\n\t\t\tif tcmalloc_supported?\n\t\t\t\tprelibs << \" -ltcmalloc_minimal \"\n\t\t\tend\n\t\t\tif platform_uses_two_level_namespace_for_dynamic_libraries?\n\t\t\t\tprelibs << \" -lsystem_allocator\"\n\t\t\tend\n\t\t\tif RUBY_PLATFORM =~ /freebsd/\n\t\t\t\t# On FreeBSD the Ruby interpreter must be linked to\n\t\t\t\t# pthread, otherwise native extensions that are linked\n\t\t\t\t# to pthread won't load properly.\n\t\t\t\tprelibs << \" -lpthread\"\n\t\t\tend\n\t\t\tFile.open(\"make.sh\", \"w\") do |f|\n\t\t\t\tf.write(\"#!/bin/bash\\n\")\n\t\t\t\tf.write(\"exec make PRELIBS='#{prelibs}' \\\"$@\\\"\")\n\t\t\t\tf.chmod(0755)\n\t\t\tend\n\t\t\treturn sh(\"make PRELIBS='#{prelibs}'\")\n\t\tend\n\tend\n\n\tdef install_ruby\n\t\tif install_autoconf_package('source', 'Ruby Enterprise Edition')\n\t\t\t# Some installed files may have wrong permissions\n\t\t\t# (not world-readable). So we fix this.\n\t\t\tif sh(\"chmod -R g+r,o+r,o-w #{@destdir}#{@prefix}/lib/ruby\")\n\t\t\t\tif @using_system_allocator_library &&\n\t\t\t\t   !sh(\"install source/libsystem_allocator.dylib #{@destdir}#{@prefix}/lib/\")\n\t\t\t\t\treturn false\n\t\t\t\telse\n\t\t\t\t\treturn true\n\t\t\t\tend\n\t\t\telse\n\t\t\t\treturn false\n\t\t\tend\n\t\telse\n\t\t\treturn false\n\t\tend\n\tend\n\n\tdef install_ree_specific_binaries\n\t\tFile.open(\"#{@destdir}#{@prefix}/bin/ree-version\", 'w') do |f|\n\t\t\tf.puts(\"#!/bin/sh\")\n\t\t\tf.puts(\"echo 'Ruby Enterprise Edition version #{@version}'\")\n\t\tend\n\t\tsystem(\"chmod +x '#{@destdir}#{@prefix}/bin/ree-version'\")\n\tend\n\n\tdef install_rubygems\n\t\t# We might be installing into a fakeroot, so add the fakeroot's library\n\t\t# search paths to RUBYLIB so that gem installation will work.\n\t\tbasedir = \"#{@destdir}#{@prefix}/lib/ruby\"\n\t\tlibdir = \"#{basedir}/1.8\"\n\t\tarchname = File.basename(File.dirname(Dir[\"#{libdir}/*/thread.#{PlatformInfo::RUBYLIBEXT}\"].first))\n\t\textlibdir = \"#{libdir}/#{archname}\"\n\t\tsite_libdir = \"#{basedir}/site_ruby/1.8\"\n\t\tsite_extlibdir = \"#{site_libdir}/#{archname}\"\n\t\tENV['RUBYLIB'] = \"#{libdir}:#{extlibdir}:#{site_libdir}:#{site_extlibdir}\"\n\n\t\tDir.chdir(\"rubygems\") do\n\t\t\tline\n\t\t\tcolor_puts \"<banner>Installing RubyGems...</banner>\"\n\t\t\tif !sh(\"#{@destdir}#{@prefix}/bin/ruby\", \"setup.rb\", \"--no-ri\", \"--no-rdoc\")\n\t\t\t\tputs \"*** Cannot install RubyGems\"\n\t\t\t\treturn false\n\t\t\tend\n\t\tend\n\t\treturn true\n\tend\n\n\tdef install_iconv\n\t\t# On some systems, most notably FreeBSD, the iconv extension isn't\n\t\t# correctly installed. So here we do it manually.\n\t\tDir.chdir('source/ext/iconv') do\n\t\t\t# On FreeBSD, iconv.h is in /usr/local/include when installed\n\t\t\t# via ports. For some reason they thought it's a good idea\n\t\t\t# to not have GCC look in /usr/local/include by default.\n\t\t\t# *Sigh*, let's fix this.\n\t\t\tif !File.exist?(\"/usr/include/iconv.h\") && File.exist?(\"/usr/local/include/iconv.h\")\n\t\t\t\targs = [\"--with-iconv-dir=/usr/local\"]\n\t\t\telse\n\t\t\t\targs = []\n\t\t\tend\n\n\t\t\tif !sh(\"#{@destdir}#{@prefix}/bin/ruby\", \"extconf.rb\", *args) ||\n\t\t\t   # 'make clean' must be run, because sometimes 'make'\n\t\t\t   # thinks iconv.so is already compiled even though it\n\t\t\t   # isn't.\n\t\t\t   !sh(\"make clean\") ||\n\t\t\t   !sh(\"make\") ||\n\t\t\t   # For some reason DESTDIR is not necessary here;\n\t\t\t   # not sure why.\n\t\t\t   !sh(\"make install\")\n\t\t\t\tputs \"*** Cannot install the iconv extension\"\n\t\t\t\treturn false\n\t\t\tend\n\t\tend\n\t\treturn true\n\tend\n\n\tdef install_dev_docs\n\t\tDir.chdir(\"source\") do\n\t\t\tcolor_puts \"<banner>Installing developer documentation...</banner>\"\n\t\t\tif !system(\"make install-doc DESTDIR='#{@destdir}'\")\n\t\t\t\treturn false\n\t\t\tend\n\t\tend\n\t\treturn true\n\tend\n\n\tdef install_useful_libraries\n\t\tline\n\t\tcolor_puts \"<banner>Installing useful libraries...</banner>\"\n\t\tgem = \"#{@destdir}#{@prefix}/bin/ruby #{@destdir}#{@prefix}/bin/gem\"\n\n\t\tmysql_config = PlatformInfo.find_command('mysql_config')\n\t\tif mysql_config\n\t\t\tmysql_gem = \"mysql -- --with-mysql-config='#{mysql_config}'\"\n\t\telse\n\t\t\tmysql_gem = \"mysql\"\n\t\tend\n\n\t\tgem_names = []\n\t\tif @install_useful_gems\n\t\t\tgem_names += [\"passenger\", \"rake\", \"rails\", \"fastthread\",\n\t\t\t              \"rack\", mysql_gem, \"sqlite3-ruby\", \"pg\"]\n\t\tend\n\t\tfailed_gems = []\n\n\t\tif sh(\"#{gem} sources --update\")\n\t\t\tgem_names.each do |gem_name|\n\t\t\t\tcolor_puts \"\\n<b>Installing #{gem_name}...</b>\"\n\t\t\t\tif !sh(\"#{gem} install -r --no-rdoc --no-ri --no-update-sources --backtrace #{gem_name}\")\n\t\t\t\t\tfailed_gems << gem_name\n\t\t\t\tend\n\t\t\tend\n\t\telse\n\t\t\tfailed_gems = gem_names\n\t\tend\n\n\t\tif !failed_gems.empty?\n\t\t\tline\n\t\t\tcolor_puts \"<banner>Warning: some libraries could not be installed</banner>\"\n\t\t\tcolor_puts \"The following gems could not be installed, probably because of an Internet\"\n\t\t\tcolor_puts \"connection error:\"\n\t\t\tputs\n\t\t\tfailed_gems.each do |gem_name|\n\t\t\t\tcolor_puts \" <b>* #{gem_name}</b>\"\n\t\t\tend\n\t\t\tputs\n\t\t\tcolor_puts \"These gems are not required, i.e. Ruby Enterprise Edition will work fine without them. But most people use Ruby Enterprise Edition in combination with Phusion Passenger and Ruby on Rails, which do require one or more of the aforementioned gems, so you may want to install them later.\"\n\t\t\tputs\n\t\t\tcolor_puts \"To install the aforementioned gems, please use the following commands:\"\n\t\t\tfailed_gems.each do |gem_name|\n\t\t\t\tcolor_puts \"  <yellow>* #{gem} install #{gem_name}</yellow>\"\n\t\t\tend\n\t\t\tputs\n\t\t\tcolor_puts \"<b>Press ENTER to show the next screen.</b>\"\n\t\t\twait\n\t\tend\n\n\t\t# Fix the shebang lines of scripts in 'bin' folder.\n\t\tfix_shebang_lines(\"#{@destdir}#{@prefix}/bin\", \"#{@prefix}/bin/ruby\")\n\t\tDir.chdir(\"#{@destdir}#{@prefix}/lib/ruby/gems/1.8/gems\") do\n\t\t\tif !Dir[\"sqlite3-ruby*\"].empty?\n\t\t\t\t# The sqlite3-ruby gem installs files with wrong\n\t\t\t\t# permissions. We fix this.\n\t\t\t\tsh \"chmod -R g+r,o+r,o-w sqlite3-ruby*\"\n\t\t\tend\n\t\tend\n\tend\n\n\tdef show_finalization_screen\n\t\tline\n\t\tcolor_puts \"<banner>Ruby Enterprise Edition is successfully installed!</banner>\"\n\t\tcolor_puts \"If want to use <yellow>Phusion Passenger (#{PASSENGER_WEBSITE})</yellow> in combination\"\n\t\tcolor_puts \"with Ruby Enterprise Edition, then you must reinstall Phusion Passenger against\"\n\t\tcolor_puts \"Ruby Enterprise Edition, as follows:\"\n\t\tputs\n\t\tcolor_puts \"  <b>#{@prefix}/bin/passenger-install-apache2-module</b>\"\n\t\tputs\n\t\tcolor_puts \"Make sure you don't forget to paste the Apache configuration directives that\"\n\t\tcolor_puts \"the installer gives you.\"\n\t\tputs\n\t\tputs\n\t\tcolor_puts \"If you ever want to uninstall Ruby Enterprise Edition, simply remove this\"\n\t\tcolor_puts \"directory:\"\n\t\tputs\n\t\tcolor_puts \"  <b>#{@prefix}</b>\"\n\t\tputs\n\t\tcolor_puts \"If you have any questions, feel free to visit our website:\"\n\t\tputs\n\t\tcolor_puts \"  <b>#{EMM_RUBY_WEBSITE}</b>\"\n\t\tputs\n\t\tcolor_puts \"Enjoy Ruby Enterprise Edition, a product of <yellow>Phusion (www.phusion.nl)</yellow> :-)\"\n\tend\n\nprivate\n\tDEFAULT_TERMINAL_COLORS = \"\\e[0m\\e[37m\\e[40m\"\n\n\tdef color_puts(message)\n\t\tputs substitute_color_tags(message)\n\tend\n\n\tdef color_print(message)\n\t\tprint substitute_color_tags(message)\n\tend\n\n\tdef substitute_color_tags(data)\n\t\tdata = data.gsub(%r{<b>(.*?)</b>}m, \"\\e[1m\\\\1#{DEFAULT_TERMINAL_COLORS}\")\n\t\tdata.gsub!(%r{<red>(.*?)</red>}m, \"\\e[1m\\e[31m\\\\1#{DEFAULT_TERMINAL_COLORS}\")\n\t\tdata.gsub!(%r{<green>(.*?)</green>}m, \"\\e[1m\\e[32m\\\\1#{DEFAULT_TERMINAL_COLORS}\")\n\t\tdata.gsub!(%r{<yellow>(.*?)</yellow>}m, \"\\e[1m\\e[33m\\\\1#{DEFAULT_TERMINAL_COLORS}\")\n\t\tdata.gsub!(%r{<banner>(.*?)</banner>}m, \"\\e[33m\\e[44m\\e[1m\\\\1#{DEFAULT_TERMINAL_COLORS}\")\n\t\treturn data\n\tend\n\n\tdef reset_terminal_colors\n\t\tSTDOUT.write(\"\\e[0m\")\n\t\tSTDOUT.flush\n\tend\n\n\tdef line\n\t\tputs \"--------------------------------------------\"\n\tend\n\n\tdef wait\n\t\tif !@auto_install_prefix\n\t\t\tSTDIN.readline\n\t\tend\n\trescue Interrupt\n\t\texit 2\n\tend\n\n\tdef query_directory(default = \"\")\n\t\twhile true\n\t\t\tSTDOUT.write(\"[#{default}] : \")\n\t\t\tSTDOUT.flush\n\t\t\tinput = STDIN.readline.strip\n\t\t\tif input.empty?\n\t\t\t\treturn default\n\t\t\telsif input !~ /^\\//\n\t\t\t\tcolor_puts \"<red>Please specify an absolute directory.</red>\"\n\t\t\telsif input =~ /\\s/\n\t\t\t\tcolor_puts \"<red>The directory name may not contain spaces.</red>\"\n\t\t\telse\n\t\t\t\treturn input\n\t\t\tend\n\t\tend\n\trescue Interrupt, EOFError\n\t\texit 2\n\tend\n\n\tdef tcmalloc_supported?\n\t\treturn @use_tcmalloc &&\n\t\t       RUBY_PLATFORM !~ /solaris/ &&\n\t\t       RUBY_PLATFORM !~ /openbsd/ &&\n\t\t       RUBY_PLATFORM !~ /arm/ &&\n\t\t       # tcmalloc has issues on Snow Leopard, but works fine on Leopard.\n\t\t       (RUBY_PLATFORM !~ /darwin/ || osx_kernel_major_release_version <= 9)\n\tend\n\n\tdef osx_kernel_major_release_version\n\t\trelease = `uname -r`.strip\n\t\trelease.gsub!(/\\..*/, '')\n\t\treturn release.to_i\n\tend\n\n\tdef platform_uses_two_level_namespace_for_dynamic_libraries?\n\t\treturn RUBY_PLATFORM =~ /darwin/\n\tend\n\n\tdef sh(*command)\n\t\tputs command.join(' ')\n\t\treturn system(*command)\n\tend\n\n\tdef configure_autoconf_package(dir, name, configure_options = nil)\n\t\tline\n\t\tcolor_puts \"<banner>Compiling and optimizing #{name}</banner>\"\n\t\tcolor_puts \"In the mean time, feel free to grab a cup of coffee.\\n\\n\"\n\t\tDir.chdir(dir) do\n\t\t\t# If nothing has been compiled yet, then set the timestamps of the files\n\t\t\t# to some time in the past. I think the \"/\" directory's timestamp is\n\t\t\t# guaranteed to be in the past.\n\t\t\t# This prevents 'configure' and 'make' from thinking that the 'configure'\n\t\t\t# script must be regenerated, for computers that have the clock wrongly\n\t\t\t# configured or computers that are in a different time zone than the\n\t\t\t# computer the REE tarball was created on.\n\t\t\tif Dir[\"*.o\"].empty?\n\t\t\t\tsystem(\"touch -r / *\")\n\t\t\t\tif File.directory?(\"m4\")\n\t\t\t\t\tsystem(\"touch -r / m4/*\")\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tif @prefix_changed || !File.exist?(\"Makefile\")\n\t\t\t\tif !sh(\"./configure --prefix=#{@prefix} #{configure_options}\")\n\t\t\t\t\treturn false\n\t\t\t\tend\n\t\t\telse\n\t\t\t\tcolor_puts \"<green>It looks like the source is already configured.</green>\"\n\t\t\t\tcolor_puts \"<green>Skipping configure script...</green>\"\n\t\t\tend\n\t\t\treturn true\n\t\tend\n\tend\n\n\tdef install_autoconf_package(dir, name)\n\t\tDir.chdir(dir) do\n\t\t\tif block_given?\n\t\t\t\tresult = yield\n\t\t\telse\n\t\t\t\tresult = sh(\"make install DESTDIR='#{@destdir}'\")\n\t\t\tend\n\t\t\tif result\n\t\t\t\treturn true\n\t\t\telse\n\t\t\t\tputs\n\t\t\t\tline\n\t\t\t\tcolor_puts \"<red>Cannot install #{name}</red>\"\n\t\t\t\tputs\n\t\t\t\tcolor_puts \"This installer was able to compile #{name}, but could not \" <<\n\t\t\t\t\t\"install the files to <b>#{@destdir}#{@prefix}</b>.\"\n\t\t\t\tputs\n\t\t\t\tif Process.uid == 0\n\t\t\t\t\tcolor_puts \"This installer probably doesn't have permission \" <<\n\t\t\t\t\t\t\"to write to that folder, even though it's running as \" <<\n\t\t\t\t\t\t\"root. Please fix the permissions, and re-run this installer.\"\n\t\t\t\telse\n\t\t\t\t\tcolor_puts \"This installer probably doesn't have permission to \" <<\n\t\t\t\t\t\t\"write to that folder, because it's running as \" <<\n\t\t\t\t\t\t\"<b>#{`whoami`.strip}</b>. Please re-run this installer \" <<\n\t\t\t\t\t\t\"as <b>root</b>.\"\n\t\t\t\tend\n\t\t\t\treturn false\n\t\t\tend\n\t\tend\n\tend\n\n\t# Fix the shebang lines of Ruby scripts.\n\tdef fix_shebang_lines(dir, new_shebang_line)\n\t\tDir.foreach(dir) do |basename|\n\t\t\tnext if basename =~ /^\\./\n\t\t\tfilename = File.join(dir, basename)\n\t\t\tbegin\n\t\t\t\tnext if !File.executable?(filename)\n\t\t\t\trest = nil\n\t\t\t\tFile.open(filename, 'rb') do |f|\n\t\t\t\t\tshebang = f.readline\n\t\t\t\t\tif shebang =~ /ruby/\n\t\t\t\t\t\tputs \"Updating #{filename}...\"\n\t\t\t\t\t\trest = f.read\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tif rest\n\t\t\t\t\ttempfile = \"#{filename}.tmp.#{Process.pid}\"\n\t\t\t\t\tFile.open(tempfile, 'w') do |f|\n\t\t\t\t\t\tf.write(\"#!#{new_shebang_line}\\n\")\n\t\t\t\t\t\tf.write(rest)\n\t\t\t\t\tend\n\t\t\t\t\tFile.chmod(File.stat(filename).mode, tempfile)\n\t\t\t\t\tFile.rename(tempfile, filename)\n\t\t\t\t\trest.replace(\"\")\n\t\t\t\tend\n\t\t\trescue SystemCallError, IOError => e\n\t\t\t\tSTDERR.puts \"*** ERROR: #{e}\"\n\t\t\tend\n\t\tend\n\tend\n\n\tdef fast_threading_patch_applied?\n\t\tFile.read(\"eval.c\") =~ /PROT_EMPTY/\n\tend\nend\n\noptions = { :tcmalloc => true, :install_dev_docs => true, :install_useful_gems => true, :extra_configure_args => [] }\nparser = OptionParser.new do |opts|\n\tnewline = \"\\n#{' ' * 37}\"\n\n\topts.banner = \"Usage: installer [options]\"\n\topts.separator(\"\")\n\n\topts.on(\"-a\", \"--auto PREFIX\", String,\n\t        \"Configure Ruby with prefix PREFIX and#{newline}\" <<\n\t        \"install it without any user interaction.\") do |dir|\n\t\toptions[:prefix] = dir\n\tend\n\topts.on(\"--destdir DIR\", String,\n\t        \"Install everthing under the given#{newline}\" <<\n\t        \"destination directory. Used when building#{newline}\" <<\n\t        \"packages for Ruby Enterprise Edition.\") do |dir|\n\t\toptions[:destdir] = dir\n\tend\n\topts.on(\"-c\", \"--configure-arg ARG\", String,\n\t        \"Pass an extra argument to the Ruby#{newline}\" <<\n\t        \"configure script. You can specify this#{newline}\" <<\n\t        \"option multiple times to pass multiple#{newline}\" <<\n\t        \"arguments.\") do |arg|\n\t\toptions[:extra_configure_args] << arg\n\tend\n\topts.on(\"--dont-install-useful-gems\",\n\t        \"Do not install a few useful gems that are#{newline}\" <<\n\t        \"normally installed as well: passenger,#{newline}\" <<\n\t        \"rails, mysql, etc.\") do\n\t\toptions[:install_useful_gems] = false\n\tend\n\topts.on(\"--no-tcmalloc\", \"Do not install tcmalloc support.\") do\n\t\toptions[:tcmalloc] = false\n\tend\n\topts.on(\"--no-dev-docs\", \"Do not install Ruby developer#{newline}documentation.\") do\n\t\toptions[:install_dev_docs] = false\n\tend\n\topts.on(\"--fast-threading\", \"Enable zero-copy context switching#{newline}\" <<\n\t                            \"(experimental)\") do\n\t\toptions[:fast_threading] = true\n\tend\n\topts.on(\"-h\", \"--help\", \"Show this message.\") do\n\t\tputs opts\n\t\texit\n\tend\nend\nbegin\n\tparser.parse!\nrescue OptionParser::ParseError => e\n\tputs e\n\tputs\n\tputs \"Please see '--help' for valid options.\"\n\texit 1\nend\n\nInstaller.new.start(options)\n"
  },
  {
    "path": "distro/optparse.rb",
    "content": "#\n# optparse.rb - command-line option analysis with the OptionParser class.\n# \n# Author:: Nobu Nakada\n# Documentation:: Nobu Nakada and Gavin Sinclair.\n#\n# See OptionParser for documentation. \n#\n\n\n# == Developer Documentation (not for RDoc output) \n# \n# === Class tree\n#\n# - OptionParser:: front end\n# - OptionParser::Switch:: each switches\n# - OptionParser::List:: options list\n# - OptionParser::ParseError:: errors on parsing\n#   - OptionParser::AmbiguousOption\n#   - OptionParser::NeedlessArgument\n#   - OptionParser::MissingArgument\n#   - OptionParser::InvalidOption\n#   - OptionParser::InvalidArgument\n#     - OptionParser::AmbiguousArgument\n#\n# === Object relationship diagram\n#\n#   +--------------+\n#   | OptionParser |<>-----+\n#   +--------------+       |                      +--------+\n#                          |                    ,-| Switch |\n#        on_head -------->+---------------+    /  +--------+\n#        accept/reject -->| List          |<|>-\n#                         |               |<|>-  +----------+\n#        on ------------->+---------------+    `-| argument |\n#                           :           :        |  class   |\n#                         +---------------+      |==========|\n#        on_tail -------->|               |      |pattern   |\n#                         +---------------+      |----------|\n#   OptionParser.accept ->| DefaultList   |      |converter |\n#                reject   |(shared between|      +----------+\n#                         | all instances)|\n#                         +---------------+\n#\n# == OptionParser\n#\n# === Introduction\n#\n# OptionParser is a class for command-line option analysis.  It is much more\n# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented\n# solution.\n#\n# === Features\n# \n# 1. The argument specification and the code to handle it are written in the\n#    same place.\n# 2. It can output an option summary; you don't need to maintain this string\n#    separately.\n# 3. Optional and mandatory arguments are specified very gracefully.\n# 4. Arguments can be automatically converted to a specified class.\n# 5. Arguments can be restricted to a certain set.\n#\n# All of these features are demonstrated in the examples below.\n#\n# === Minimal example\n#\n#   require 'optparse'\n#\n#   options = {}\n#   OptionParser.new do |opts|\n#     opts.banner = \"Usage: example.rb [options]\"\n#\n#     opts.on(\"-v\", \"--[no-]verbose\", \"Run verbosely\") do |v|\n#       options[:verbose] = v\n#     end\n#   end.parse!\n#\n#   p options\n#   p ARGV\n#\n# === Complete example\n#\n# The following example is a complete Ruby program.  You can run it and see the\n# effect of specifying various options.  This is probably the best way to learn\n# the features of +optparse+.\n#\n#   require 'optparse'\n#   require 'optparse/time'\n#   require 'ostruct'\n#   require 'pp'\n#   \n#   class OptparseExample\n#   \n#     CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]\n#     CODE_ALIASES = { \"jis\" => \"iso-2022-jp\", \"sjis\" => \"shift_jis\" }\n#   \n#     #\n#     # Return a structure describing the options.\n#     #\n#     def self.parse(args)\n#       # The options specified on the command line will be collected in *options*.\n#       # We set default values here.\n#       options = OpenStruct.new\n#       options.library = []\n#       options.inplace = false\n#       options.encoding = \"utf8\"\n#       options.transfer_type = :auto\n#       options.verbose = false\n#       \n#       opts = OptionParser.new do |opts|\n#         opts.banner = \"Usage: example.rb [options]\"\n#       \n#         opts.separator \"\"\n#         opts.separator \"Specific options:\"\n#       \n#         # Mandatory argument.\n#         opts.on(\"-r\", \"--require LIBRARY\",\n#                 \"Require the LIBRARY before executing your script\") do |lib|\n#           options.library << lib\n#         end\n#       \n#         # Optional argument; multi-line description.\n#         opts.on(\"-i\", \"--inplace [EXTENSION]\",\n#                 \"Edit ARGV files in place\",\n#                 \"  (make backup if EXTENSION supplied)\") do |ext|\n#           options.inplace = true\n#           options.extension = ext || ''\n#           options.extension.sub!(/\\A\\.?(?=.)/, \".\")  # Ensure extension begins with dot.\n#         end\n#       \n#         # Cast 'delay' argument to a Float.\n#         opts.on(\"--delay N\", Float, \"Delay N seconds before executing\") do |n|\n#           options.delay = n\n#         end\n#       \n#         # Cast 'time' argument to a Time object.\n#         opts.on(\"-t\", \"--time [TIME]\", Time, \"Begin execution at given time\") do |time|\n#           options.time = time\n#         end\n#       \n#         # Cast to octal integer.\n#         opts.on(\"-F\", \"--irs [OCTAL]\", OptionParser::OctalInteger,\n#                 \"Specify record separator (default \\\\0)\") do |rs|\n#           options.record_separator = rs\n#         end\n#       \n#         # List of arguments.\n#         opts.on(\"--list x,y,z\", Array, \"Example 'list' of arguments\") do |list|\n#           options.list = list\n#         end\n#       \n#         # Keyword completion.  We are specifying a specific set of arguments (CODES\n#         # and CODE_ALIASES - notice the latter is a Hash), and the user may provide\n#         # the shortest unambiguous text.\n#         code_list = (CODE_ALIASES.keys + CODES).join(',')\n#         opts.on(\"--code CODE\", CODES, CODE_ALIASES, \"Select encoding\",\n#                 \"  (#{code_list})\") do |encoding|\n#           options.encoding = encoding\n#         end\n#       \n#         # Optional argument with keyword completion.\n#         opts.on(\"--type [TYPE]\", [:text, :binary, :auto],\n#                 \"Select transfer type (text, binary, auto)\") do |t|\n#           options.transfer_type = t\n#         end\n#       \n#         # Boolean switch.\n#         opts.on(\"-v\", \"--[no-]verbose\", \"Run verbosely\") do |v|\n#           options.verbose = v\n#         end\n#       \n#         opts.separator \"\"\n#         opts.separator \"Common options:\"\n#       \n#         # No argument, shows at tail.  This will print an options summary.\n#         # Try it and see!\n#         opts.on_tail(\"-h\", \"--help\", \"Show this message\") do\n#           puts opts\n#           exit\n#         end\n#       \n#         # Another typical switch to print the version.\n#         opts.on_tail(\"--version\", \"Show version\") do\n#           puts OptionParser::Version.join('.')\n#           exit\n#         end\n#       end\n#       \n#       opts.parse!(args)\n#       options\n#     end  # parse()\n#   \n#   end  # class OptparseExample\n#   \n#   options = OptparseExample.parse(ARGV)\n#   pp options\n#\n# === Further documentation\n#\n# The above examples should be enough to learn how to use this class.  If you\n# have any questions, email me (gsinclair@soyabean.com.au) and I will update\n# this document.\n#\nclass OptionParser\n  # :stopdoc:\n  RCSID = %w$Id: optparse.rb 11798 2007-02-20 06:53:16Z knu $[1..-1].each {|s| s.freeze}.freeze\n  Version = (RCSID[1].split('.').collect {|s| s.to_i}.extend(Comparable).freeze if RCSID[1])\n  LastModified = (Time.gm(*RCSID[2, 2].join('-').scan(/\\d+/).collect {|s| s.to_i}) if RCSID[2])\n  Release = RCSID[2]\n\n  NoArgument = [NO_ARGUMENT = :NONE, nil].freeze\n  RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze\n  OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze\n  # :startdoc:\n\n  #\n  # Keyword completion module.  This allows partial arguments to be specified\n  # and resolved against a list of acceptable values.\n  #\n  module Completion\n    def complete(key, icase = false, pat = nil)\n      pat ||= Regexp.new('\\A' + Regexp.quote(key).gsub(/\\w+\\b/, '\\&\\w*'),\n                         icase)\n      canon, sw, k, v, cn = nil\n      candidates = []\n      each do |k, *v|\n        (if Regexp === k\n           kn = nil\n           k === key\n         else\n           kn = defined?(k.id2name) ? k.id2name : k\n           pat === kn\n         end) or next\n        v << k if v.empty?\n        candidates << [k, v, kn]\n      end\n      candidates = candidates.sort_by {|k, v, kn| kn.size}\n      if candidates.size == 1\n        canon, sw, * = candidates[0]\n      elsif candidates.size > 1\n        canon, sw, cn = candidates.shift\n        candidates.each do |k, v, kn|\n          next if sw == v\n          if String === cn and String === kn\n            if cn.rindex(kn, 0)\n              canon, sw, cn = k, v, kn\n              next\n            elsif kn.rindex(cn, 0)\n              next\n            end\n          end\n          throw :ambiguous, key\n        end\n      end\n      if canon\n        block_given? or return key, *sw\n        yield(key, *sw)\n      end\n    end\n\n    def convert(opt = nil, val = nil, *)\n      val\n    end\n  end\n\n\n  #\n  # Map from option/keyword string to object with completion.\n  #\n  class OptionMap < Hash\n    include Completion\n  end\n\n\n  #\n  # Individual switch class.  Not important to the user.\n  #\n  # Defined within Switch are several Switch-derived classes: NoArgument,\n  # RequiredArgument, etc. \n  #\n  class Switch\n    attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block\n\n    #\n    # Guesses argument style from +arg+.  Returns corresponding\n    # OptionParser::Switch class (OptionalArgument, etc.).\n    #\n    def self.guess(arg)\n      case arg\n      when \"\"\n        t = self\n      when /\\A=?\\[/\n        t = Switch::OptionalArgument\n      when /\\A\\s+\\[/\n        t = Switch::PlacedArgument\n      else\n        t = Switch::RequiredArgument\n      end\n      self >= t or incompatible_argument_styles(arg, t)\n      t\n    end\n\n    def self.incompatible_argument_styles(arg, t)\n      raise ArgumentError, \"#{arg}: incompatible argument styles\\n  #{self}, #{t}\"\n    end\n\n    def self.pattern\n      NilClass\n    end\n\n    def initialize(pattern = nil, conv = nil,\n                   short = nil, long = nil, arg = nil,\n                   desc = ([] if short or long), block = Proc.new)\n      raise if Array === pattern\n      @pattern, @conv, @short, @long, @arg, @desc, @block =\n        pattern, conv, short, long, arg, desc, block\n    end\n\n    #\n    # Parses +arg+ and returns rest of +arg+ and matched portion to the\n    # argument pattern. Yields when the pattern doesn't match substring.\n    #\n    def parse_arg(arg)\n      pattern or return nil, arg\n      unless m = pattern.match(arg)\n        yield(InvalidArgument, arg)\n        return arg, nil\n      end\n      if String === m\n        m = [s = m]\n      else\n        m = m.to_a\n        s = m[0]\n        return nil, m unless String === s\n      end\n      raise InvalidArgument, arg unless arg.rindex(s, 0)\n      return nil, m if s.length == arg.length\n      yield(InvalidArgument, arg) # didn't match whole arg\n      return arg[s.length..-1], m\n    end\n    private :parse_arg\n\n    #\n    # Parses argument, converts and returns +arg+, +block+ and result of\n    # conversion. Yields at semi-error condition instead of raising an\n    # exception.\n    #\n    def conv_arg(arg, val = nil)\n      if conv\n        val = conv.call(*val)\n      else\n        val = proc {|val| val}.call(*val)\n      end\n      return arg, block, val\n    end\n    private :conv_arg\n\n    #\n    # Produces the summary text. Each line of the summary is yielded to the\n    # block (without newline).\n    #\n    # +sdone+::  Already summarized short style options keyed hash.\n    # +ldone+::  Already summarized long style options keyed hash.\n    # +width+::  Width of left side (option part). In other words, the right\n    #            side (description part) starts after +width+ columns.\n    # +max+::    Maximum width of left side -> the options are filled within\n    #            +max+ columns.\n    # +indent+:: Prefix string indents all summarized lines.\n    #\n    def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = \"\")\n      sopts, lopts, s = [], [], nil\n      @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short\n      @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long\n      return if sopts.empty? and lopts.empty? # completely hidden\n\n      left = [sopts.join(', ')]\n      right = desc.dup\n\n      while s = lopts.shift\n        l = left[-1].length + s.length\n        l += arg.length if left.size == 1 && arg\n        l < max or left << ''\n        left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s\n      end\n\n      left[0] << arg if arg\n      mlen = left.collect {|s| s.length}.max.to_i\n      while mlen > width and l = left.shift\n        mlen = left.collect {|s| s.length}.max.to_i if l.length == mlen\n        yield(indent + l)\n      end\n\n      while begin l = left.shift; r = right.shift; l or r end\n        l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?\n        yield(indent + l)\n      end\n\n      self\n    end\n\n    def add_banner(to)  # :nodoc:\n      unless @short or @long\n        s = desc.join\n        to << \" [\" + s + \"]...\" unless s.empty?\n      end\n      to\n    end\n\n    def match_nonswitch?(str) # :nodoc:\n      @pattern =~ str unless @short or @long\n    end\n\n    #\n    # Main name of the switch.\n    #\n    def switch_name\n      (long.first || short.first).sub(/\\A-+(?:\\[no-\\])?/, '')\n    end\n\n    #\n    # Switch that takes no arguments.\n    #\n    class NoArgument < self\n\n      #\n      # Raises an exception if any arguments given.\n      #\n      def parse(arg, argv)\n        yield(NeedlessArgument, arg) if arg\n        conv_arg(arg)\n      end\n\n      def self.incompatible_argument_styles(*)\n      end\n\n      def self.pattern\n        Object\n      end\n    end\n\n    #\n    # Switch that takes an argument.\n    #\n    class RequiredArgument < self\n\n      #\n      # Raises an exception if argument is not present.\n      #\n      def parse(arg, argv)\n        unless arg\n          raise MissingArgument if argv.empty?\n          arg = argv.shift\n        end\n        conv_arg(*parse_arg(arg) {|*exc| raise(*exc)})\n      end\n    end\n\n    #\n    # Switch that can omit argument.\n    #\n    class OptionalArgument < self\n\n      #\n      # Parses argument if given, or uses default value.\n      #\n      def parse(arg, argv, &error)\n        if arg\n          conv_arg(*parse_arg(arg, &error))\n        else\n          conv_arg(arg)\n        end\n      end\n    end\n\n    #\n    # Switch that takes an argument, which does not begin with '-'.\n    #\n    class PlacedArgument < self\n\n      #\n      # Returns nil if argument is not present or begins with '-'.\n      #\n      def parse(arg, argv, &error)\n        if !(val = arg) and (argv.empty? or /\\A-/ =~ (val = argv[0]))\n          return nil, block, nil\n        end\n        opt = (val = parse_arg(val, &error))[1]\n        val = conv_arg(*val)\n        if opt and !arg\n          argv.shift\n        else\n          val[0] = nil\n        end\n        val\n      end\n    end\n  end\n\n  #\n  # Simple option list providing mapping from short and/or long option\n  # string to OptionParser::Switch and mapping from acceptable argument to\n  # matching pattern and converter pair. Also provides summary feature.\n  #\n  class List\n    # Map from acceptable argument types to pattern and converter pairs.\n    attr_reader :atype\n    \n    # Map from short style option switches to actual switch objects.\n    attr_reader :short\n    \n    # Map from long style option switches to actual switch objects.\n    attr_reader :long\n    \n    # List of all switches and summary string.\n    attr_reader :list\n\n    #\n    # Just initializes all instance variables.\n    #\n    def initialize\n      @atype = {}\n      @short = OptionMap.new\n      @long = OptionMap.new\n      @list = []\n    end\n\n    #\n    # See OptionParser.accept.\n    #\n    def accept(t, pat = /.*/nm, &block)\n      if pat\n        pat.respond_to?(:match) or raise TypeError, \"has no `match'\"\n      else\n        pat = t if t.respond_to?(:match)\n      end\n      unless block\n        block = pat.method(:convert).to_proc if pat.respond_to?(:convert)\n      end\n      @atype[t] = [pat, block]\n    end\n\n    #\n    # See OptionParser.reject.\n    #\n    def reject(t)\n      @atype.delete(t)\n    end\n\n    #\n    # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.\n    #\n    # +sw+::     OptionParser::Switch instance to be added.\n    # +sopts+::  Short style option list.\n    # +lopts+::  Long style option list.\n    # +nlopts+:: Negated long style options list.\n    #\n    def update(sw, sopts, lopts, nsw = nil, nlopts = nil)\n      o = nil\n      sopts.each {|o| @short[o] = sw} if sopts\n      lopts.each {|o| @long[o] = sw} if lopts\n      nlopts.each {|o| @long[o] = nsw} if nsw and nlopts\n      used = @short.invert.update(@long.invert)\n      @list.delete_if {|o| Switch === o and !used[o]}\n    end\n    private :update\n\n    #\n    # Inserts +switch+ at the head of the list, and associates short, long\n    # and negated long options. Arguments are:\n    # \n    # +switch+::      OptionParser::Switch instance to be inserted.\n    # +short_opts+::  List of short style options.\n    # +long_opts+::   List of long style options.\n    # +nolong_opts+:: List of long style options with \"no-\" prefix.\n    #\n    #   prepend(switch, short_opts, long_opts, nolong_opts)\n    #\n    def prepend(*args)\n      update(*args)\n      @list.unshift(args[0])\n    end\n\n    #\n    # Appends +switch+ at the tail of the list, and associates short, long\n    # and negated long options. Arguments are:\n    # \n    # +switch+::      OptionParser::Switch instance to be inserted.\n    # +short_opts+::  List of short style options.\n    # +long_opts+::   List of long style options.\n    # +nolong_opts+:: List of long style options with \"no-\" prefix.\n    #\n    #   append(switch, short_opts, long_opts, nolong_opts)\n    #\n    def append(*args)\n      update(*args)\n      @list.push(args[0])\n    end\n\n    #\n    # Searches +key+ in +id+ list. The result is returned or yielded if a\n    # block is given. If it isn't found, nil is returned.\n    #\n    def search(id, key)\n      if list = __send__(id)\n        val = list.fetch(key) {return nil}\n        block_given? ? yield(val) : val\n      end\n    end\n\n    #\n    # Searches list +id+ for +opt+ and the optional patterns for completion\n    # +pat+. If +icase+ is true, the search is case insensitive. The result\n    # is returned or yielded if a block is given. If it isn't found, nil is\n    # returned.\n    #\n    def complete(id, opt, icase = false, *pat, &block)\n      __send__(id).complete(opt, icase, *pat, &block)\n    end\n\n    #\n    # Iterates over each option, passing the option to the +block+.\n    #\n    def each_option(&block)\n      list.each(&block)\n    end\n\n    #\n    # Creates the summary table, passing each line to the +block+ (without\n    # newline). The arguments +args+ are passed along to the summarize\n    # method which is called on every option.\n    #\n    def summarize(*args, &block)\n      list.each do |opt|\n        if opt.respond_to?(:summarize) # perhaps OptionParser::Switch\n          opt.summarize(*args, &block)\n        elsif !opt or opt.empty?\n          yield(\"\")\n        else\n          opt.each(&block)\n        end\n      end\n    end\n\n    def add_banner(to)  # :nodoc:\n      list.each do |opt|\n        if opt.respond_to?(:add_banner)\n          opt.add_banner(to)\n        end\n      end\n      to\n    end\n  end\n\n  #\n  # Hash with completion search feature. See OptionParser::Completion.\n  #\n  class CompletingHash < Hash\n    include Completion\n\n    #\n    # Completion for hash key.\n    #\n    def match(key)\n      return key, *fetch(key) {\n        raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}\n      }\n    end\n  end\n\n  # :stopdoc:\n\n  #\n  # Enumeration of acceptable argument styles. Possible values are:\n  #\n  # NO_ARGUMENT::       The switch takes no arguments. (:NONE)\n  # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)\n  # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)\n  #\n  # Use like --switch=argument (long style) or -Xargument (short style). For\n  # short style, only portion matched to argument pattern is dealed as\n  # argument.\n  #\n  ArgumentStyle = {}\n  NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}\n  RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}\n  OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}\n  ArgumentStyle.freeze\n\n  #\n  # Switches common used such as '--', and also provides default\n  # argument classes\n  #\n  DefaultList = List.new\n  DefaultList.short['-'] = Switch::NoArgument.new {}\n  DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}\n\n  #\n  # Default options for ARGV, which never appear in option summary.\n  #\n  Officious = {}\n\n  #\n  # --help\n  # Shows option summary.\n  #\n  Officious['help'] = proc do |parser|\n    Switch::NoArgument.new do\n      puts parser.help\n      exit\n    end\n  end\n\n  #\n  # --version\n  # Shows version string if Version is defined.\n  #\n  Officious['version'] = proc do |parser|\n    Switch::OptionalArgument.new do |pkg|\n      if pkg\n        begin\n          require 'optparse/version'\n        rescue LoadError\n        else\n          show_version(*pkg.split(/,/)) or\n            abort(\"#{parser.program_name}: no version found in package #{pkg}\")\n          exit\n        end\n      end\n      v = parser.ver or abort(\"#{parser.program_name}: version unknown\")\n      puts v\n      exit\n    end\n  end\n\n  # :startdoc:\n\n  #\n  # Class methods\n  #\n\n  #\n  # Initializes a new instance and evaluates the optional block in context\n  # of the instance. Arguments +args+ are passed to #new, see there for\n  # description of parameters.\n  # \n  # This method is *deprecated*, its behavior corresponds to the older #new\n  # method.\n  #\n  def self.with(*args, &block)\n    opts = new(*args)\n    opts.instance_eval(&block)\n    opts\n  end\n\n  #\n  # Returns an incremented value of +default+ according to +arg+.\n  #\n  def self.inc(arg, default = nil)\n    case arg\n    when Integer\n      arg.nonzero?\n    when nil\n      default.to_i + 1\n    end\n  end\n  def inc(*args)\n    self.class.inc(*args)\n  end\n\n  #\n  # Initializes the instance and yields itself if called with a block.\n  #\n  # +banner+:: Banner message.\n  # +width+::  Summary width.\n  # +indent+:: Summary indent.\n  #\n  def initialize(banner = nil, width = 32, indent = ' ' * 4)\n    @stack = [DefaultList, List.new, List.new]\n    @program_name = nil\n    @banner = banner\n    @summary_width = width\n    @summary_indent = indent\n    @default_argv = ARGV\n    add_officious\n    yield self if block_given?\n  end\n\n  def add_officious  # :nodoc:\n    list = base()\n    Officious.each do |opt, block|\n      list.long[opt] ||= block.call(self)\n    end\n  end\n\n  #\n  # Terminates option parsing. Optional parameter +arg+ is a string pushed\n  # back to be the first non-option argument.\n  #\n  def terminate(arg = nil)\n    self.class.terminate(arg)\n  end\n  def self.terminate(arg = nil)\n    throw :terminate, arg\n  end\n\n  @stack = [DefaultList]\n  def self.top() DefaultList end\n\n  #\n  # Directs to accept specified class +t+. The argument string is passed to\n  # the block in which it should be converted to the desired class.\n  #\n  # +t+::   Argument class specifier, any object including Class.\n  # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.\n  #\n  #   accept(t, pat, &block)\n  #\n  def accept(*args, &blk) top.accept(*args, &blk) end\n  #\n  # See #accept.\n  #\n  def self.accept(*args, &blk) top.accept(*args, &blk) end\n\n  #\n  # Directs to reject specified class argument.\n  #\n  # +t+:: Argument class speficier, any object including Class.\n  #\n  #   reject(t)\n  #\n  def reject(*args, &blk) top.reject(*args, &blk) end\n  #\n  # See #reject.\n  #\n  def self.reject(*args, &blk) top.reject(*args, &blk) end\n\n  #\n  # Instance methods\n  #\n\n  # Heading banner preceding summary.\n  attr_writer :banner\n\n  # Program name to be emitted in error message and default banner,\n  # defaults to $0.\n  attr_writer :program_name\n\n  # Width for option list portion of summary. Must be Numeric.\n  attr_accessor :summary_width\n\n  # Indentation for summary. Must be String (or have + String method).\n  attr_accessor :summary_indent\n\n  # Strings to be parsed in default.\n  attr_accessor :default_argv\n\n  #\n  # Heading banner preceding summary.\n  #\n  def banner\n    unless @banner\n      @banner = \"Usage: #{program_name} [options]\"\n      visit(:add_banner, @banner)\n    end\n    @banner\n  end\n\n  #\n  # Program name to be emitted in error message and default banner, defaults\n  # to $0.\n  #\n  def program_name\n    @program_name || File.basename($0, '.*')\n  end\n\n  # for experimental cascading :-)\n  alias set_banner banner=\n  alias set_program_name program_name=\n  alias set_summary_width summary_width=\n  alias set_summary_indent summary_indent=\n\n  # Version\n  attr_writer :version\n  # Release code\n  attr_writer :release\n\n  #\n  # Version\n  #\n  def version\n    @version || (defined?(::Version) && ::Version)\n  end\n\n  #\n  # Release code\n  #\n  def release\n    @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)\n  end\n\n  #\n  # Returns version string from program_name, version and release.\n  #\n  def ver\n    if v = version\n      str = \"#{program_name} #{[v].join('.')}\"\n      str << \" (#{v})\" if v = release\n      str\n    end\n  end\n\n  def warn(mesg = $!)\n    super(\"#{program_name}: #{mesg}\")\n  end\n\n  def abort(mesg = $!)\n    super(\"#{program_name}: #{mesg}\")\n  end\n\n  #\n  # Subject of #on / #on_head, #accept / #reject\n  #\n  def top\n    @stack[-1]\n  end\n\n  #\n  # Subject of #on_tail.\n  #\n  def base\n    @stack[1]\n  end\n\n  #\n  # Pushes a new List.\n  #\n  def new\n    @stack.push(List.new)\n    if block_given?\n      yield self\n    else\n      self\n    end\n  end\n\n  #\n  # Removes the last List.\n  #\n  def remove\n    @stack.pop\n  end\n\n  #\n  # Puts option summary into +to+ and returns +to+. Yields each line if\n  # a block is given.\n  #\n  # +to+:: Output destination, which must have method <<. Defaults to [].\n  # +width+:: Width of left side, defaults to @summary_width.\n  # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.\n  # +indent+:: Indentation, defaults to @summary_indent.\n  #\n  def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)\n    visit(:summarize, {}, {}, width, max, indent, &(blk || proc {|l| to << l + $/}))\n    to\n  end\n\n  #\n  # Returns option summary string.\n  #\n  def help; summarize(banner.to_s.sub(/\\n?\\z/, \"\\n\")) end\n  alias to_s help\n\n  #\n  # Returns option summary list.\n  #\n  def to_a; summarize(banner.to_a.dup) end\n\n  #\n  # Checks if an argument is given twice, in which case an ArgumentError is\n  # raised. Called from OptionParser#switch only.\n  #\n  # +obj+:: New argument.\n  # +prv+:: Previously specified argument.\n  # +msg+:: Exception message.\n  #\n  def notwice(obj, prv, msg)\n    unless !prv or prv == obj\n      begin\n        raise ArgumentError, \"argument #{msg} given twice: #{obj}\"\n      rescue\n        $@[0, 2] = nil\n        raise\n      end\n    end\n    obj\n  end\n  private :notwice\n\n  #\n  # Creates an OptionParser::Switch from the parameters. The parsed argument\n  # value is passed to the given block, where it can be processed.\n  #\n  # See at the beginning of OptionParser for some full examples.\n  #\n  # +opts+ can include the following elements:\n  #\n  # [Argument style:]\n  #   One of the following:\n  #     :NONE, :REQUIRED, :OPTIONAL\n  #\n  # [Argument pattern:]\n  #   Acceptable option argument format, must be pre-defined with\n  #   OptionParser.accept or OptionParser#accept, or Regexp. This can appear\n  #   once or assigned as String if not present, otherwise causes an\n  #   ArgumentError. Examples:\n  #     Float, Time, Array\n  #\n  # [Possible argument values:]\n  #   Hash or Array.\n  #     [:text, :binary, :auto]\n  #     %w[iso-2022-jp shift_jis euc-jp utf8 binary]\n  #     { \"jis\" => \"iso-2022-jp\", \"sjis\" => \"shift_jis\" }\n  #\n  # [Long style switch:]\n  #   Specifies a long style switch which takes a mandatory, optional or no\n  #   argument. It's a string of the following form:\n  #     \"--switch=MANDATORY\" or \"--switch MANDATORY\"\n  #     \"--switch[=OPTIONAL]\"\n  #     \"--switch\"\n  #\n  # [Short style switch:]\n  #   Specifies short style switch which takes a mandatory, optional or no\n  #   argument. It's a string of the following form:\n  #     \"-xMANDATORY\"\n  #     \"-x[OPTIONAL]\"\n  #     \"-x\"\n  #   There is also a special form which matches character range (not full\n  #   set of regural expression):\n  #     \"-[a-z]MANDATORY\"\n  #     \"-[a-z][OPTIONAL]\" \n  #     \"-[a-z]\"\n  #\n  # [Argument style and description:]\n  #   Instead of specifying mandatory or optional orguments directly in the\n  #   switch parameter, this separate parameter can be used.\n  #     \"=MANDATORY\"\n  #     \"=[OPTIONAL]\"\n  #\n  # [Description:]\n  #   Description string for the option.\n  #     \"Run verbosely\"\n  # \n  # [Handler:]\n  #   Handler for the parsed argument value. Either give a block or pass a\n  #   Proc or Method as an argument.\n  #\n  def make_switch(opts, block = nil)\n    short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []\n    ldesc, sdesc, desc, arg = [], [], []\n    default_style = Switch::NoArgument\n    default_pattern = nil\n    klass = nil\n    o = nil\n    n, q, a = nil\n\n    opts.each do |o|\n      # argument class\n      next if search(:atype, o) do |pat, c|\n        klass = notwice(o, klass, 'type')\n        if not_style and not_style != Switch::NoArgument\n          not_pattern, not_conv = pat, c\n        else\n          default_pattern, conv = pat, c\n        end\n      end\n\n      # directly specified pattern(any object possible to match)\n      if !(String === o) and o.respond_to?(:match)\n        pattern = notwice(o, pattern, 'pattern')\n        conv = (pattern.method(:convert).to_proc if pattern.respond_to?(:convert))\n        next\n      end\n\n      # anything others\n      case o\n      when Proc, Method\n        block = notwice(o, block, 'block')\n      when Array, Hash\n        case pattern\n        when CompletingHash\n        when nil\n          pattern = CompletingHash.new\n          conv = (pattern.method(:convert).to_proc if pattern.respond_to?(:convert))\n        else\n          raise ArgumentError, \"argument pattern given twice\"\n        end\n        o.each {|(o, *v)| pattern[o] = v.fetch(0) {o}}\n      when Module\n        raise ArgumentError, \"unsupported argument type: #{o}\"\n      when *ArgumentStyle.keys\n        style = notwice(ArgumentStyle[o], style, 'style')\n      when /^--no-([^\\[\\]=\\s]*)(.+)?/\n        q, a = $1, $2\n        o = notwice(a ? Object : TrueClass, klass, 'type')\n        not_pattern, not_conv = search(:atype, o) unless not_style\n        not_style = (not_style || default_style).guess(arg = a) if a\n        default_style = Switch::NoArgument\n        default_pattern, conv = search(:atype, FalseClass) unless default_pattern\n        ldesc << \"--no-#{q}\"\n        long << 'no-' + (q = q.downcase)\n        nolong << q\n      when /^--\\[no-\\]([^\\[\\]=\\s]*)(.+)?/\n        q, a = $1, $2\n        o = notwice(a ? Object : TrueClass, klass, 'type')\n        if a\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        ldesc << \"--[no-]#{q}\"\n        long << (o = q.downcase)\n        not_pattern, not_conv = search(:atype, FalseClass) unless not_style\n        not_style = Switch::NoArgument\n        nolong << 'no-' + o\n      when /^--([^\\[\\]=\\s]*)(.+)?/\n        q, a = $1, $2\n        if a\n          o = notwice(NilClass, klass, 'type')\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        ldesc << \"--#{q}\"\n        long << (o = q.downcase)\n      when /^-(\\[\\^?\\]?(?:[^\\\\\\]]|\\\\.)*\\])(.+)?/\n        q, a = $1, $2\n        o = notwice(Object, klass, 'type')\n        if a\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        sdesc << \"-#{q}\"\n        short << Regexp.new(q)\n      when /^-(.)(.+)?/\n        q, a = $1, $2\n        if a\n          o = notwice(NilClass, klass, 'type')\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        sdesc << \"-#{q}\"\n        short << q\n      when /^=/\n        style = notwice(default_style.guess(arg = o), style, 'style')\n        default_pattern, conv = search(:atype, Object) unless default_pattern\n      else\n        desc.push(o)\n      end\n    end\n\n    default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern\n    if !(short.empty? and long.empty?)\n      s = (style || default_style).new(pattern || default_pattern,\n                                       conv, sdesc, ldesc, arg, desc, block)\n    elsif !block\n      raise ArgumentError, \"no switch given\" if style or pattern\n      s = desc\n    else\n      short << pattern\n      s = (style || default_style).new(pattern,\n                                       conv, nil, nil, arg, desc, block)\n    end\n    return s, short, long,\n      (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),\n      nolong\n  end\n\n  def define(*opts, &block)\n    top.append(*(sw = make_switch(opts, block)))\n    sw[0]\n  end\n\n  #\n  # Add option switch and handler. See #make_switch for an explanation of\n  # parameters.\n  #\n  def on(*opts, &block)\n    define(*opts, &block)\n    self\n  end\n  alias def_option define\n\n  def define_head(*opts, &block)\n    top.prepend(*(sw = make_switch(opts, block)))\n    sw[0]\n  end\n\n  #\n  # Add option switch like with #on, but at head of summary.\n  #\n  def on_head(*opts, &block)\n    define_head(*opts, &block)\n    self\n  end\n  alias def_head_option define_head\n\n  def define_tail(*opts, &block)\n    base.append(*(sw = make_switch(opts, block)))\n    sw[0]\n  end\n\n  #\n  # Add option switch like with #on, but at tail of summary.\n  #\n  def on_tail(*opts, &block)\n    define_tail(*opts, &block)\n    self\n  end\n  alias def_tail_option define_tail\n\n  #\n  # Add separator in summary.\n  #\n  def separator(string)\n    top.append(string, nil, nil)\n  end\n\n  #\n  # Parses command line arguments +argv+ in order. When a block is given,\n  # each non-option argument is yielded.\n  #\n  # Returns the rest of +argv+ left unparsed.\n  #\n  def order(*argv, &block)\n    argv = argv[0].dup if argv.size == 1 and Array === argv[0]\n    order!(argv, &block)\n  end\n\n  #\n  # Same as #order, but removes switches destructively.\n  #\n  def order!(argv = default_argv, &nonopt)\n    parse_in_order(argv, &nonopt)\n  end\n\n  def parse_in_order(argv = default_argv, setter = nil, &nonopt)  # :nodoc:\n    opt, arg, sw, val, rest = nil\n    nonopt ||= proc {|arg| throw :terminate, arg}\n    argv.unshift(arg) if arg = catch(:terminate) {\n      while arg = argv.shift\n        case arg\n        # long option\n        when /\\A--([^=]*)(?:=(.*))?/nm\n          opt, rest = $1, $2\n          begin\n            sw, = complete(:long, opt, true)\n          rescue ParseError\n            raise $!.set_option(arg, true)\n          end\n          begin\n            opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}\n            val = cb.call(val) if cb\n            setter.call(sw.switch_name, val) if setter\n          rescue ParseError\n            raise $!.set_option(arg, rest)\n          end\n\n        # short option\n        when /\\A-(.)((=).*|.+)?/nm\n          opt, has_arg, eq, val, rest = $1, $3, $3, $2, $2\n          begin\n            sw, = search(:short, opt)\n            unless sw\n              begin\n                sw, = complete(:short, opt)\n                # short option matched.\n                val = arg.sub(/\\A-/, '')\n                has_arg = true\n              rescue InvalidOption\n                # if no short options match, try completion with long\n                # options.\n                sw, = complete(:long, opt)\n                eq ||= !rest\n              end\n            end\n          rescue ParseError\n            raise $!.set_option(arg, true)\n          end\n          begin\n            opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}\n            raise InvalidOption, arg if has_arg and !eq and arg == \"-#{opt}\"\n            argv.unshift(opt) if opt and (opt = opt.sub(/\\A-*/, '-')) != '-'\n            val = cb.call(val) if cb\n            setter.call(sw.switch_name, val) if setter\n          rescue ParseError\n            raise $!.set_option(arg, arg.length > 2)\n          end\n\n        # non-option argument\n        else\n          catch(:prune) do\n            visit(:each_option) do |sw|\n              sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)\n            end\n            nonopt.call(arg)\n          end\n        end\n      end\n\n      nil\n    }\n\n    visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}\n\n    argv\n  end\n  private :parse_in_order\n\n  #\n  # Parses command line arguments +argv+ in permutation mode and returns\n  # list of non-option arguments.\n  #\n  def permute(*argv)\n    argv = argv[0].dup if argv.size == 1 and Array === argv[0]\n    permute!(argv)\n  end\n\n  #\n  # Same as #permute, but removes switches destructively.\n  #\n  def permute!(argv = default_argv)\n    nonopts = []\n    arg = nil\n    order!(argv) {|arg| nonopts << arg}\n    argv[0, 0] = nonopts\n    argv\n  end\n\n  #\n  # Parses command line arguments +argv+ in order when environment variable\n  # POSIXLY_CORRECT is set, and in permutation mode otherwise.\n  #\n  def parse(*argv)\n    argv = argv[0].dup if argv.size == 1 and Array === argv[0]\n    parse!(argv)\n  end\n\n  #\n  # Same as #parse, but removes switches destructively.\n  #\n  def parse!(argv = default_argv)\n    if ENV.include?('POSIXLY_CORRECT')\n      order!(argv)\n    else\n      permute!(argv)\n    end\n  end\n\n  #\n  # Wrapper method for getopts.rb.\n  #\n  #   params = ARGV.getopts(\"ab:\", \"foo\", \"bar:\")\n  #   # params[:a] = true   # -a\n  #   # params[:b] = \"1\"    # -b1\n  #   # params[:foo] = \"1\"  # --foo\n  #   # params[:bar] = \"x\"  # --bar x\n  #\n  def getopts(*args)\n    argv = Array === args.first ? args.shift : default_argv\n    single_options, *long_options = *args\n\n    result = {}\n\n    single_options.scan(/(.)(:)?/) do |opt, val|\n      if val\n        result[opt] = nil\n        define(\"-#{opt} VAL\")\n      else\n        result[opt] = false\n        define(\"-#{opt}\")\n      end\n    end if single_options\n\n    long_options.each do |arg|\n      opt, val = arg.split(':', 2)\n      if val\n        result[opt] = val.empty? ? nil : val\n        define(\"--#{opt} VAL\")\n      else\n        result[opt] = false\n        define(\"--#{opt}\")\n      end\n    end\n\n    parse_in_order(argv, result.method(:[]=))\n    result\n  end\n\n  #\n  # See #getopts.\n  #\n  def self.getopts(*args)\n    new.getopts(*args)\n  end\n\n  #\n  # Traverses @stack, sending each element method +id+ with +args+ and\n  # +block+.\n  #\n  def visit(id, *args, &block)\n    el = nil\n    @stack.reverse_each do |el|\n      el.send(id, *args, &block)\n    end\n    nil\n  end\n  private :visit\n\n  #\n  # Searches +key+ in @stack for +id+ hash and returns or yields the result.\n  #\n  def search(id, key)\n    block_given = block_given?\n    visit(:search, id, key) do |k|\n      return block_given ? yield(k) : k\n    end\n  end\n  private :search\n\n  #\n  # Completes shortened long style option switch and returns pair of\n  # canonical switch and switch descriptor OptionParser::Switch.\n  #\n  # +id+::    Searching table.\n  # +opt+::   Searching key.\n  # +icase+:: Search case insensitive if true.\n  # +pat+::   Optional pattern for completion.\n  #\n  def complete(typ, opt, icase = false, *pat)\n    if pat.empty?\n      search(typ, opt) {|sw| return [sw, opt]} # exact match or...\n    end\n    raise AmbiguousOption, catch(:ambiguous) {\n      visit(:complete, typ, opt, icase, *pat) {|opt, *sw| return sw}\n      raise InvalidOption, opt\n    }\n  end\n  private :complete\n\n  #\n  # Loads options from file names as +filename+. Does nothing when the file\n  # is not present. Returns whether successfully loaded.\n  #\n  # +filename+ defaults to basename of the program without suffix in a\n  # directory ~/.options.\n  #\n  def load(filename = nil)\n    begin\n      filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')\n    rescue\n      return false\n    end\n    begin\n      parse(*IO.readlines(filename).each {|s| s.chomp!})\n      true\n    rescue Errno::ENOENT, Errno::ENOTDIR\n      false\n    end\n  end\n\n  #\n  # Parses environment variable +env+ or its uppercase with splitting like a\n  # shell.\n  #\n  # +env+ defaults to the basename of the program.\n  #\n  def environment(env = File.basename($0, '.*'))\n    env = ENV[env] || ENV[env.upcase] or return\n    parse(*Shellwords.shellwords(env))\n  end\n\n  #\n  # Acceptable argument classes\n  #\n\n  #\n  # Any string and no conversion. This is fall-back.\n  #\n  accept(Object) {|s,|s or s.nil?}\n\n  accept(NilClass) {|s,|s}\n\n  #\n  # Any non-empty string, and no conversion.\n  #\n  accept(String, /.+/nm) {|s,*|s}\n\n  #\n  # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal\n  # for 0x, and decimal for others; with optional sign prefix. Converts to\n  # Integer.\n  #\n  decimal = '\\d+(?:_\\d+)*'\n  binary = 'b[01]+(?:_[01]+)*'\n  hex = 'x[\\da-f]+(?:_[\\da-f]+)*'\n  octal = \"0(?:[0-7]*(?:_[0-7]+)*|#{binary}|#{hex})\"\n  integer = \"#{octal}|#{decimal}\"\n  accept(Integer, %r\"\\A[-+]?(?:#{integer})\"io) {|s,| Integer(s) if s}\n\n  #\n  # Float number format, and converts to Float.\n  #\n  float = \"(?:#{decimal}(?:\\\\.(?:#{decimal})?)?|\\\\.#{decimal})(?:E[-+]?#{decimal})?\"\n  floatpat = %r\"\\A[-+]?#{float}\"io\n  accept(Float, floatpat) {|s,| s.to_f if s}\n\n  #\n  # Generic numeric format, converts to Integer for integer format, Float\n  # for float format.\n  #\n  accept(Numeric, %r\"\\A[-+]?(?:#{octal}|#{float})\"io) {|s,| eval(s) if s}\n\n  #\n  # Decimal integer format, to be converted to Integer.\n  #\n  DecimalInteger = /\\A[-+]?#{decimal}/io\n  accept(DecimalInteger) {|s,| s.to_i if s}\n\n  #\n  # Ruby/C like octal/hexadecimal/binary integer format, to be converted to\n  # Integer.\n  #\n  OctalInteger = /\\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))/io\n  accept(OctalInteger) {|s,| s.oct if s}\n\n  #\n  # Decimal integer/float number format, to be converted to Integer for\n  # integer format, Float for float format.\n  #\n  DecimalNumeric = floatpat     # decimal integer is allowed as float also.\n  accept(DecimalNumeric) {|s,| eval(s) if s}\n\n  #\n  # Boolean switch, which means whether it is present or not, whether it is\n  # absent or not with prefix no-, or it takes an argument\n  # yes/no/true/false/+/-.\n  #\n  yesno = CompletingHash.new\n  %w[- no false].each {|el| yesno[el] = false}\n  %w[+ yes true].each {|el| yesno[el] = true}\n  yesno['nil'] = false          # shoud be nil?\n  accept(TrueClass, yesno) {|arg, val| val == nil or val}\n  #\n  # Similar to TrueClass, but defaults to false.\n  #\n  accept(FalseClass, yesno) {|arg, val| val != nil and val}\n\n  #\n  # List of strings separated by \",\".\n  #\n  accept(Array) do |s,|\n    if s\n      s = s.split(',').collect {|s| s unless s.empty?}\n    end\n    s\n  end\n\n  #\n  # Regular expression with options.\n  #\n  accept(Regexp, %r\"\\A/((?:\\\\.|[^\\\\])*)/([[:alpha:]]+)?\\z|.*\") do |all, s, o|\n    f = 0\n    if o\n      f |= Regexp::IGNORECASE if /i/ =~ o\n      f |= Regexp::MULTILINE if /m/ =~ o\n      f |= Regexp::EXTENDED if /x/ =~ o\n      k = o.delete(\"^imx\")\n    end\n    Regexp.new(s || all, f, k)\n  end\n\n  #\n  # Exceptions\n  #\n\n  #\n  # Base class of exceptions from OptionParser.\n  #\n  class ParseError < RuntimeError\n    # Reason which caused the error.\n    Reason = 'parse error'.freeze\n\n    def initialize(*args)\n      @args = args\n      @reason = nil\n    end\n\n    attr_reader :args\n    attr_writer :reason\n\n    #\n    # Pushes back erred argument(s) to +argv+.\n    #\n    def recover(argv)\n      argv[0, 0] = @args\n      argv\n    end\n\n    def set_option(opt, eq)\n      if eq\n        @args[0] = opt\n      else\n        @args.unshift(opt)\n      end\n      self\n    end\n\n    #\n    # Returns error reason. Override this for I18N.\n    #\n    def reason\n      @reason || self.class::Reason\n    end\n\n    def inspect\n      \"#<#{self.class.to_s}: #{args.join(' ')}>\"\n    end\n\n    #\n    # Default stringizing method to emit standard error message.\n    #\n    def message\n      reason + ': ' + args.join(' ')\n    end\n\n    alias to_s message\n  end\n\n  #\n  # Raises when ambiguously completable string is encountered.\n  #\n  class AmbiguousOption < ParseError\n    const_set(:Reason, 'ambiguous option'.freeze)\n  end\n\n  #\n  # Raises when there is an argument for a switch which takes no argument.\n  #\n  class NeedlessArgument < ParseError\n    const_set(:Reason, 'needless argument'.freeze)\n  end\n\n  #\n  # Raises when a switch with mandatory argument has no argument.\n  #\n  class MissingArgument < ParseError\n    const_set(:Reason, 'missing argument'.freeze)\n  end\n\n  #\n  # Raises when switch is undefined.\n  #\n  class InvalidOption < ParseError\n    const_set(:Reason, 'invalid option'.freeze)\n  end\n\n  #\n  # Raises when the given argument does not match required format.\n  #\n  class InvalidArgument < ParseError\n    const_set(:Reason, 'invalid argument'.freeze)\n  end\n\n  #\n  # Raises when the given argument word can't be completed uniquely.\n  #\n  class AmbiguousArgument < InvalidArgument\n    const_set(:Reason, 'ambiguous argument'.freeze)\n  end\n\n  #\n  # Miscellaneous\n  #\n\n  #\n  # Extends command line arguments array (ARGV) to parse itself.\n  #\n  module Arguable\n\n    #\n    # Sets OptionParser object, when +opt+ is +false+ or +nil+, methods\n    # OptionParser::Arguable#options and OptionParser::Arguable#options= are\n    # undefined. Thus, there is no ways to access the OptionParser object\n    # via the receiver object.\n    #\n    def options=(opt)\n      unless @optparse = opt\n        class << self\n          undef_method(:options)\n          undef_method(:options=)\n        end\n      end\n    end\n\n    #\n    # Actual OptionParser object, automatically created if nonexistent.\n    #\n    # If called with a block, yields the OptionParser object and returns the\n    # result of the block. If an OptionParser::ParseError exception occurs\n    # in the block, it is rescued, a error message printed to STDERR and\n    # +nil+ returned.\n    #\n    def options\n      @optparse ||= OptionParser.new\n      @optparse.default_argv = self\n      block_given? or return @optparse\n      begin\n        yield @optparse\n      rescue ParseError\n        @optparse.warn $!\n        nil\n      end\n    end\n\n    #\n    # Parses +self+ destructively in order and returns +self+ containing the\n    # rest arguments left unparsed.\n    #\n    def order!(&blk) options.order!(self, &blk) end\n\n    #\n    # Parses +self+ destructively in permutation mode and returns +self+\n    # containing the rest arguments left unparsed.\n    #\n    def permute!() options.permute!(self) end\n\n    #\n    # Parses +self+ destructively and returns +self+ containing the\n    # rest arguments left unparsed.\n    #\n    def parse!() options.parse!(self) end\n\n    #\n    # Substitution of getopts is possible as follows. Also see\n    # OptionParser#getopts.\n    #\n    #   def getopts(*args)\n    #     ($OPT = ARGV.getopts(*args)).each do |opt, val|\n    #       eval \"$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val\"\n    #     end\n    #   rescue OptionParser::ParseError\n    #   end\n    #\n    def getopts(*args)\n      options.getopts(self, *args)\n    end\n\n    #\n    # Initializes instance variable.\n    #\n    def self.extend_object(obj)\n      super\n      obj.instance_eval {@optparse = nil}\n    end\n    def initialize(*args)\n      super\n      @optparse = nil\n    end\n  end\n\n  #\n  # Acceptable argument classes. Now contains DecimalInteger, OctalInteger\n  # and DecimalNumeric. See Acceptable argument classes (in source code).\n  #\n  module Acceptables\n    const_set(:DecimalInteger, OptionParser::DecimalInteger)\n    const_set(:OctalInteger, OptionParser::OctalInteger)\n    const_set(:DecimalNumeric, OptionParser::DecimalNumeric)\n  end\nend\n\n# ARGV is arguable by OptionParser\nARGV.extend(OptionParser::Arguable)\n\nif $0 == __FILE__\n  Version = OptionParser::Version\n  ARGV.options {|q|\n    q.parse!.empty? or puts \"what's #{ARGV.join(' ')}?\"\n  } or abort(ARGV.options.to_s)\nend\n"
  },
  {
    "path": "distro/platform_info.rb",
    "content": "# This module autodetects various platform-specific information, and\n# provides that information through constants.\nmodule PlatformInfo\nprivate\n\tdef self.env_defined?(name)\n\t\treturn !ENV[name].nil? && !ENV[name].empty?\n\tend\n\t\n\tdef self.determine_gem_command\n\t\tgem_exe_in_path = find_command(\"gem\")\n\t\tcorrect_gem_exe = File.dirname(RUBY) + \"/gem\"\n\t\tif gem_exe_in_path.nil? || gem_exe_in_path == correct_gem_exe\n\t\t\treturn \"gem\"\n\t\telse\n\t\t\treturn correct_gem_exe\n\t\tend\n\tend\n\n\tdef self.find_apxs2\n\t\tif env_defined?(\"APXS2\")\n\t\t\treturn ENV[\"APXS2\"]\n\t\tend\n\t\t['apxs2', 'apxs'].each do |name|\n\t\t\tcommand = find_command(name)\n\t\t\tif !command.nil?\n\t\t\t\treturn command\n\t\t\tend\n\t\tend\n\t\treturn nil\n\tend\n\t\n\tdef self.determine_apache2_bindir\n\t\tif APXS2.nil?\n\t\t\treturn nil\n\t\telse\n\t\t\treturn `#{APXS2} -q BINDIR 2>/dev/null`.strip\n\t\tend\n\tend\n\t\n\tdef self.determine_apache2_sbindir\n\t\tif APXS2.nil?\n\t\t\treturn nil\n\t\telse\n\t\t\treturn `#{APXS2} -q SBINDIR`.strip\n\t\tend\n\tend\n\t\n\tdef self.find_apache2_executable(*possible_names)\n\t\t[APACHE2_BINDIR, APACHE2_SBINDIR].each do |bindir|\n\t\t\tif bindir.nil?\n\t\t\t\tnext\n\t\t\tend\n\t\t\tpossible_names.each do |name|\n\t\t\t\tfilename = \"#{bindir}/#{name}\"\n\t\t\t\tif File.file?(filename) && File.executable?(filename)\n\t\t\t\t\treturn filename\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\t\treturn nil\n\tend\n\t\n\tdef self.find_apache2ctl\n\t\treturn find_apache2_executable('apache2ctl', 'apachectl')\n\tend\n\t\n\tdef self.find_httpd\n\t\tif env_defined?('HTTPD')\n\t\t\treturn ENV['HTTPD']\n\t\telsif APXS2.nil?\n\t\t\t[\"apache2\", \"httpd2\", \"apache\", \"httpd\"].each do |name|\n\t\t\t\tcommand = find_command(name)\n\t\t\t\tif !command.nil?\n\t\t\t\t\treturn command\n\t\t\t\tend\n\t\t\tend\n\t\t\treturn nil\n\t\telse\n\t\t\treturn find_apache2_executable(`#{APXS2} -q TARGET`.strip)\n\t\tend\n\tend\n\t\n\tdef self.determine_apxs2_flags\n\t\tif APXS2.nil?\n\t\t\treturn nil\n\t\telse\n\t\t\tflags = `#{APXS2} -q CFLAGS`.strip << \" -I\" << `#{APXS2} -q INCLUDEDIR`\n\t\t\tflags.strip!\n\t\t\tflags.gsub!(/-O\\d? /, '')\n\t\t\treturn flags\n\t\tend\n\tend\n\t\n\tdef self.find_apr_config\n\t\tif env_defined?('APR_CONFIG')\n\t\t\tapr_config = ENV['APR_CONFIG']\n\t\telsif RUBY_PLATFORM =~ /darwin/ && HTTPD == \"/usr/sbin/httpd\"\n\t\t\t# If we're on MacOS X, and we're compiling against the\n\t\t\t# default provided Apache, then we'll want to query the\n\t\t\t# correct 'apr-1-config' command. However, that command\n\t\t\t# is not in $PATH by default. Instead, it lives in\n\t\t\t# /Developer/SDKs/MacOSX*sdk/usr/bin.\n\t\t\tsdk_dir = Dir[\"/Developer/SDKs/MacOSX*sdk\"].sort.last\n\t\t\tif sdk_dir\n\t\t\t\tapr_config = \"#{sdk_dir}/usr/bin/apr-1-config\"\n\t\t\t\tif !File.executable?(apr_config)\n\t\t\t\t\tapr_config = nil\n\t\t\t\tend\n\t\t\tend\n\t\telse\n\t\t\tapr_config = find_command('apr-1-config')\n\t\t\tif apr_config.nil?\n\t\t\t\tapr_config = find_command('apr-config')\n\t\t\tend\n\t\tend\n\t\treturn apr_config\n\tend\n\t\n\tdef self.determine_apr_info\n\t\tif APR_CONFIG.nil?\n\t\t\treturn nil\n\t\telse\n\t\t\tflags = `#{APR_CONFIG} --cppflags --includes`.strip\n\t\t\tlibs = `#{APR_CONFIG} --link-ld`.strip\n\t\t\tflags.gsub!(/-O\\d? /, '')\n\t\t\treturn [flags, libs]\n\t\tend\n\tend\n\t\n\tdef self.determine_multi_arch_flags\n\t\tif RUBY_PLATFORM =~ /darwin/ && !HTTPD.nil?\n\t\t\tarchitectures = []\n\t\t\t`file \"#{HTTPD}\"`.split(\"\\n\").grep(/for architecture/).each do |line|\n\t\t\t\tline =~ /for architecture (.*?)\\)/\n\t\t\t\tarchitectures << \"-arch #{$1}\"\n\t\t\tend\n\t\t\treturn architectures.join(' ')\n\t\telse\n\t\t\treturn \"\"\n\t\tend\n\tend\n\t\n\tdef self.determine_library_extension\n\t\tif RUBY_PLATFORM =~ /darwin/\n\t\t\treturn \"bundle\"\n\t\telse\n\t\t\treturn \"so\"\n\t\tend\n\tend\n\t\n\tdef self.read_file(filename)\n\t\treturn File.read(filename)\n\trescue\n\t\treturn \"\"\n\tend\n\t\n\tdef self.determine_libext\n\t\tif RUBY_PLATFORM =~ /darwin/\n\t\t\treturn \"dylib\"\n\t\telse\n\t\t\treturn \"so\"\n\t\tend\n\tend\n\t\n\tdef self.determine_ruby_libext\n\t\tif RUBY_PLATFORM =~ /darwin/\n\t\t\treturn \"bundle\"\n\t\telse\n\t\t\treturn \"so\"\n\t\tend\n\tend\n\t\n\tdef self.determine_linux_distro\n\t\tif RUBY_PLATFORM !~ /linux/\n\t\t\treturn nil\n\t\tend\n\t\tlsb_release = read_file(\"/etc/lsb-release\")\n\t\tif lsb_release =~ /Ubuntu/\n\t\t\treturn :ubuntu\n\t\telsif File.exist?(\"/etc/debian_version\")\n\t\t\treturn :debian\n\t\telsif File.exist?(\"/etc/redhat-release\")\n\t\t\tredhat_release = read_file(\"/etc/redhat-release\")\n\t\t\tif redhat_release =~ /CentOS/\n\t\t\t\treturn :centos\n\t\t\telsif redhat_release =~ /Fedora/  # is this correct?\n\t\t\t\treturn :fedora\n\t\t\telse\n\t\t\t\t# On official RHEL distros, the content is in the form of\n\t\t\t\t# \"Red Hat Enterprise Linux Server release 5.1 (Tikanga)\"\n\t\t\t\treturn :rhel\n\t\t\tend\n\t\telsif File.exist?(\"/etc/suse-release\")\n\t\t\treturn :suse\n\t\telsif File.exist?(\"/etc/gentoo-release\")\n\t\t\treturn :gentoo\n\t\telse\n\t\t\treturn :unknown\n\t\tend\n\t\t# TODO: Slackware, Mandrake/Mandriva\n\tend\n\t\n\tdef self.determine_c_compiler\n\t\treturn ENV['CC'] || find_command('gcc') || find_command('cc')\n\tend\n\t\n\tdef self.determine_cxx_compiler\n\t\treturn ENV['CXX'] || find_command('g++') || find_command('c++')\n\tend\n\t\n\t# Returns true if the Solaris version of ld is in use.\n\tdef self.solaris_ld?\n\t\tld_version = `ld -V 2>&1`\n\t\treturn !!ld_version.index(\"Solaris\")\n\tend\n\npublic\n\t# Check whether the specified command is in $PATH, and return its\n\t# absolute filename. Returns nil if the command is not found.\n\t#\n\t# This function exists because system('which') doesn't always behave\n\t# correctly, for some weird reason.\n\tdef self.find_command(name)\n\t\tENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|\n\t\t\tpath = File.join(directory, name.to_s)\n\t\t\tif File.executable?(path)\n\t\t\t\treturn path\n\t\t\tend\n\t\tend\n\t\treturn nil\n\tend\n\t\n\tCC = determine_c_compiler\n\tCXX = determine_cxx_compiler\n\tLIBEXT = determine_libext\n\tRUBYLIBEXT = determine_ruby_libext\n\n\t# An identifier for the current Linux distribution. nil if the operating system is not Linux.\n\tLINUX_DISTRO = determine_linux_distro\nend\n"
  },
  {
    "path": "distro/tasks.rb",
    "content": "verbose true\n\nVENDOR_RUBY_VERSION = begin\n\tdata = File.read(\"version.h\")\n\tdata =~ /RUBY_VERSION \"(.*)\"/\n\t$1\nend\nREE_VERSION = begin\n\tdata = File.read(\"version.c\")\n\tdata =~ /REE_VERSION \"(.*)\"/\n\t$1\nend\nDISTDIR = \"ruby-enterprise-#{VENDOR_RUBY_VERSION}-#{REE_VERSION}\"\nRUBYGEMS_URL = \"http://rubyforge.org/frs/download.php/70696/rubygems-1.3.7.tgz\"\nRUBYGEMS_PACKAGE = RUBYGEMS_URL.sub(/.*\\//, '')\n\ndef create_fakeroot\n\tdistdir = \"/tmp/r8ee-test\"\n\tcreate_distdir(distdir)\n\tsh \"rm -rf fakeroot\"\n\tsh \"mkdir fakeroot\"\n\tfakeroot = File.expand_path(\"fakeroot\")\n\tsh \"#{distdir}/installer --auto='/usr/local' --destdir='#{fakeroot}' #{ENV['ARGS']}\"\n\tputs \"*** Ruby Enterprise Edition has been installed to #{fakeroot}\"\nend\n\n# Check whether the specified command is in $PATH, and return its\n# absolute filename. Returns nil if the command is not found.\n#\n# This function exists because system('which') doesn't always behave\n# correctly, for some weird reason.\ndef find_command(name)\n\tENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|\n\t\tpath = File.join(directory, name.to_s)\n\t\tif File.executable?(path)\n\t\t\treturn path\n\t\tend\n\tend\n\treturn nil\nend\n\ndef download(url)\n\tif find_command('wget')\n\t\tsh \"wget\", RUBYGEMS_URL\n\telse\n\t\tsh \"curl\", \"-O\", \"-L\", RUBYGEMS_URL\n\tend\nend\n\ndef create_distdir(distdir = DISTDIR, sudo = false)\n\tif sudo\n\t\tsh \"sudo rm -rf #{distdir}\"\n\telse\n\t\tsh \"rm -rf #{distdir}\"\n\tend\n\tsh \"mkdir #{distdir}\"\n\t\n\tsh \"mkdir #{distdir}/source\"\n\tsh \"git archive HEAD | tar -C #{distdir}/source -xf -\"\n\tsh \"cp distro/*.rb #{distdir}/\"\n\tDir.chdir(\"#{distdir}/source\") do\n\t\tsh \"autoconf\"\n\t\tsh 'rm', '-rf', 'autom4te.cache'\n\t\tsh 'bison', '-y', '-o', 'parse.c', 'parse.y'\n\tend\n\t\n\tsh \"git diff copy_on_write..zero_copy_context_switch > #{distdir}/fast-threading.patch\"\n\t\n\tsh \"cp distro/installer distro/installer.rb distro/platform_info.rb \" <<\n\t\t\"distro/dependencies.rb distro/optparse.rb #{distdir}/\"\n\tsh \"cd #{distdir} && ln -s source/distro/runtime .\"\n\tFile.open(\"#{distdir}/version.txt\", \"w\") do |f|\n\t\tf.write(\"#{VENDOR_RUBY_VERSION}-#{REE_VERSION}\")\n\tend\n\t\n\tif !File.exist?(\"distro/#{RUBYGEMS_PACKAGE}\")\n\t\tDir.chdir(\"distro\") do\n\t\t\tdownload(RUBYGEMS_URL)\n\t\tend\n\tend\n\trubygems_package = File.expand_path(\"distro/#{RUBYGEMS_PACKAGE}\")\n\tDir.chdir(distdir) do\n\t\tsh \"tar\", \"xzf\", rubygems_package\n\t\tsh \"mv rubygems* rubygems\"\n\tend\nend\n\n# Returns the disk usage of the given directory, in KB.\ndef disk_usage(dir)\n\tif RUBY_PLATFORM =~ /linux/\n\t\toptions = \"-a -k --apparent-size --max-depth=0\"\n\telse\n\t\toptions = \"-k -d 0\"\n\tend\n\treturn `du #{options} \\\"#{dir}\\\"`.strip.to_i\nend\n\n\ndesc \"Create a distribution directory\"\ntask :distdir do\n\tcreate_distdir\nend\n\ndesc \"Create a distribution package\"\ntask :package do\n\tcreate_distdir\n\tENV['GZIP'] = '--best'\n\tsh \"tar -czf #{DISTDIR}.tar.gz #{DISTDIR}\"\n\tsh \"rm -rf #{DISTDIR}\"\nend\n\ndesc \"Test the installer script. Pass extra arguments to the installer with ARGS.\"\ntask :test_installer do\n\tdistdir = \"/tmp/r8ee-test\"\n\tcreate_distdir(distdir, ENV['SUDO'])\n\tsh \"ln -sf `pwd`/distro/installer.rb #{distdir}/installer.rb\"\n\tcommand = \"#{distdir}/installer --no-dev-docs #{ENV['ARGS']}\"\n\tif ENV['SUDO']\n\t\tcommand = \"sudo #{command}\"\n\tend\n\tsh command\nend\n\ndesc \"Auto-install into a fake root directory\"\ntask :fakeroot do\n\tcreate_fakeroot\nend\n\ndesc \"Create a Debian package. Set SKIP_FAKEROOT=1 if you want to bypass fakeroot recreation.\"\ntask 'package:debian' do\n\tcreate_fakeroot if ENV['SKIP_FAKEROOT'].nil? || ENV['SKIP_FAKEROOT'].empty?\n\tsh \"rm -rf fakeroot/DEBIAN\"\n\tsh \"cp -R distro/debian fakeroot/DEBIAN\"\n\t\n\tinstalled_size = disk_usage(\"fakeroot\")\n\traw_arch = `uname -m`.strip\n\tarch = case raw_arch\n\twhen /^i.86$/\n\t\t\"i386\"\n\twhen /^x86_64/\n\t\t\"amd64\"\n\telse\n\t\traw_arch\n\tend\n\t\n\trequire 'erb'\n\ttemplate = ERB.new(File.read(\"fakeroot/DEBIAN/control\"))\n\tFile.open(\"fakeroot/DEBIAN/control\", \"w\") do |f|\n\t\tf.write(template.result(binding))\n\tend\n\t\n\tsh \"fakeroot dpkg -b fakeroot ruby-enterprise_#{VENDOR_RUBY_VERSION}-#{REE_VERSION}_#{arch}.deb\"\nend\n\ndesc \"Generate the documentation HTML\"\nfile 'distro/documentation.html' => 'distro/documentation.txt' do\n\tsh \"asciidoc -a toc -a numbered -a toclevels=3 -a icons distro/documentation.txt\"\nend\n\ndesc \"Change shebang lines for Ruby scripts to '#!/usr/bin/env ruby'\"\ntask :fix_shebang do\n\tif ENV['dir'].nil?\n\t\tSTDERR.write(\"Usage: rake fix_shebang dir=<SOME DIRECTORY>\\n\")\n\t\texit 1\n\tend\n\tDir.chdir(ENV['dir']) do\n\t\tsh \"sed -i 's|^#!.*$|#!/usr/bin/env ruby|' *\"\n\tend\nend\n"
  },
  {
    "path": "distruby.rb",
    "content": "#!./miniruby\n\nif RUBY_PATCHLEVEL.zero?\n\tdirname = sprintf 'ruby-%s', RUBY_VERSION\n\ttagname = dirname.gsub /ruby-(\\d)\\.(\\d)\\.(\\d)/, 'v\\1_\\2_\\3'\nelse\n\tdirname = sprintf 'ruby-%s-p%u', RUBY_VERSION, RUBY_PATCHLEVEL\n\ttagname = dirname.gsub /ruby-(\\d)\\.(\\d)\\.(\\d)-p/, 'v\\1_\\2_\\3_'\nend\ntgzname = dirname + '.tar.gz'\ntbzname = dirname + '.tar.bz2'\nzipname = dirname + '.zip'\nrepos   = 'http://svn.ruby-lang.org/repos/ruby/tags/' + tagname\n\nSTDERR.puts 'exporting sources...'\nsystem 'svn',  'export',  '-q', repos, dirname\nDir.chdir dirname do\n\tSTDERR.puts 'generating configure...'\n\tsystem 'autoconf'\n\tsystem 'rm', '-rf', 'autom4te.cache'\n\n\tSTDERR.puts 'generating parse.c...'\n\tsystem 'bison', '-y', '-o', 'parse.c', 'parse.y'\nend\n\nSTDERR.puts 'generating tarballs...'\nENV['GZIP'] = '-9'\nsystem 'tar', 'chofzp', tgzname, dirname\nsystem 'tar', 'chojfp', tbzname, dirname\nsystem 'zip', '-q9r', zipname, dirname\n\nrequire 'digest/md5'\nrequire 'digest/sha2'\nfor name in [tgzname, tbzname, zipname] do\n\topen name, 'rb' do |fp|\n\t\tstr = fp.read\n\t\tmd5 = Digest::MD5.hexdigest str\n\t\tsha = Digest::SHA256.hexdigest str\n\t\tprintf \"MD5(%s)= %s\\nSHA256(%s)= %s\\nSIZE(%s)= %s\\n\\n\",\n\t\t\t\t name, md5,\n\t\t\t\t name, sha,\n\t\t\t\t name, str.size\n\tend\nend\n\n\n\n# \f\n# Local Variables:\n# mode: ruby\n# code: utf-8\n# indent-tabs-mode: t\n# tab-width: 3\n# ruby-indent-level: 3\n# fill-column: 79\n# default-justification: full\n# End:\n# vi: ts=3 sw=3\n\n"
  },
  {
    "path": "djgpp/GNUmakefile.in",
    "content": "include Makefile\nVPATH = $(srcdir) $(srcdir)/missing\n"
  },
  {
    "path": "djgpp/README.djgpp",
    "content": "* How to compile and install on djgpp\n\nThis is what you need to do to compile and install Ruby:\n\n  1. Run configure.bat, which will generate config.h and Makefile\n     (GNU sed required).\n     Message like this is normal:\n       sed.exe: can't read 123456789: No such file or directory (ENOENT)\n\n  2. Edit defines.h if you need.  Probably this step will not need.\n\n  3. Remove comment mark(#) before the module names from ext/Setup.dj (or\n     add module names if not present).\n\n  4. Run make.\n\n  5. Optionally, run 'make test' to check whether the compiled Ruby\n     interpreter works well.  If you see the message \"test succeeded\",\n     your ruby works as it should (hopefully).\n\n  6. Run 'make install'\n"
  },
  {
    "path": "djgpp/config.hin",
    "content": "\n#define PACKAGE_NAME \"\"\n#define PACKAGE_TARNAME \"\"\n#define PACKAGE_VERSION \"\"\n#define PACKAGE_STRING \"\"\n#define PACKAGE_BUGREPORT \"\"\n#define USE_BUILTIN_FRAME_ADDRESS 1\n#define STDC_HEADERS 1\n#define HAVE_SYS_TYPES_H 1\n#define HAVE_SYS_STAT_H 1\n#define HAVE_STDLIB_H 1\n#define HAVE_STRING_H 1\n#define HAVE_MEMORY_H 1\n#define HAVE_STRINGS_H 1\n#define HAVE_UNISTD_H 1\n#define HAVE_LONG_LONG 1\n#define HAVE_OFF_T 1\n#define SIZEOF_INT 4\n#define SIZEOF_SHORT 2\n#define SIZEOF_LONG 4\n#define SIZEOF_LONG_LONG 8\n#define SIZEOF___INT64 0\n#define SIZEOF_OFF_T 4\n#define SIZEOF_VOIDP 4\n#define SIZEOF_FLOAT 4\n#define SIZEOF_DOUBLE 8\n#define HAVE_PROTOTYPES 1\n#define TOKEN_PASTE(x,y) x##y\n#define HAVE_STDARG_PROTOTYPES 1\n#define NORETURN(x) x __attribute__ ((noreturn))\n#define HAVE_DECL_SYS_NERR 1\n#define HAVE_DIRENT_H 1\n#define STDC_HEADERS 1\n#define HAVE_SYS_WAIT_H 1\n#define HAVE_STDLIB_H 1\n#define HAVE_STRING_H 1\n#define HAVE_UNISTD_H 1\n#define HAVE_LIMITS_H 1\n#define HAVE_SYS_FILE_H 1\n#define HAVE_SYS_IOCTL_H 1\n#define HAVE_FCNTL_H 1\n#define HAVE_SYS_FCNTL_H 1\n#define HAVE_SYS_TIME_H 1\n#define HAVE_SYS_TIMES_H 1\n#define HAVE_SYS_PARAM_H 1\n#define HAVE_PWD_H 1\n#define HAVE_UTIME_H 1\n#define HAVE_MEMORY_H 1\n#define HAVE_DIRECT_H 1\n#define HAVE_SYS_RESOURCE_H 1\n#define HAVE_STRUCT_STAT_ST_BLKSIZE 1\n#define HAVE_ST_BLKSIZE 1\n#define HAVE_STRUCT_STAT_ST_RDEV 1\n#define HAVE_ST_RDEV 1\n#define GETGROUPS_T gid_t\n#define RETSIGTYPE void\n#define HAVE_ALLOCA 1\n#define HAVE_DUP2 1\n#define HAVE_MEMMOVE 1\n#define HAVE_MKDIR 1\n#define HAVE_STRCASECMP 1\n#define HAVE_STRNCASECMP 1\n#define HAVE_STRERROR 1\n#define HAVE_STRFTIME 1\n#define HAVE_STRCHR 1\n#define HAVE_STRSTR 1\n#define HAVE_STRTOUL 1\n#define HAVE_ISINF 1\n#define HAVE_ISNAN 1\n#define HAVE_FINITE 1\n#define HAVE_HYPOT 1\n#define HAVE_ACOSH 1\n#define HAVE_FMOD 1\n#define HAVE_WAITPID 1\n#define HAVE_FSYNC 1\n#define HAVE_TRUNCATE 1\n#define HAVE_CHSIZE 1\n#define HAVE_TIMES 1\n#define HAVE_UTIMES 1\n#define HAVE_FCNTL 1\n#define HAVE_SYMLINK 1\n#define HAVE_SETITIMER 1\n#define HAVE_PAUSE 1\n#define HAVE_GETPGRP 1\n#define HAVE_SETPGID 1\n#define HAVE_GETGROUPS 1\n#define HAVE_GETRLIMIT 1\n#define HAVE_SIGPROCMASK 1\n#define HAVE_SIGACTION 1\n#define HAVE_SETSID 1\n#define HAVE_TELLDIR 1\n#define HAVE_SEEKDIR 1\n#define HAVE_MKTIME 1\n#define HAVE_COSH 1\n#define HAVE_SINH 1\n#define HAVE_TANH 1\n#define HAVE_STRUCT_TM_TM_ZONE 1\n#define HAVE_TM_ZONE 1\n#define HAVE_STRUCT_TM_TM_GMTOFF 1\n#define POSIX_SIGNAL 1\n#define GETPGRP_VOID 1\n#define SETPGRP_VOID 1\n#define RSHIFT(x,y) ((x)>>(int)y)\n#define FILE_COUNT _cnt\n#define FILE_READPTR _ptr\n#define NEED_IO_FLUSH_BETWEEN_RW 1\n#define DEFAULT_KCODE KCODE_NONE\n#define DLEXT \".so\"\n#define RUBY_LIB \"/lib/ruby/@MAJOR@.@MINOR@\"\n#define RUBY_SITE_LIB \"/lib/ruby/site_ruby\"\n#define RUBY_SITE_LIB2 \"/lib/ruby/site_ruby/@MAJOR@.@MINOR@\"\n#define RUBY_PLATFORM \"i386-msdosdjgpp\"\n#define RUBY_ARCHLIB \"/lib/ruby/@MAJOR@.@MINOR@/i386-msdosdjgpp\"\n#define RUBY_SITE_ARCHLIB \"/lib/ruby/site_ruby/@MAJOR@.@MINOR@/i386-msdosdjgpp\"\n"
  },
  {
    "path": "djgpp/config.sed",
    "content": "/^SHELL/s,/bin/sh,$(COMSPEC),\n;s%/bin/rm%rm%\n;s%|| true%%\n;/\\/dev\\/null/ {\n;s,/dev/null 2>&1, nul,\n;s,2> /dev/null,,\n;}\n;/^config.status/ {\n;    N;N;N;N;N;d\n;}\n:t\n  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b\ns,@srcdir@,.,g;t t\ns,@top_srcdir@,..,;t t\ns,@PATH_SEPARATOR@,:,;t t\ns,@PACKAGE_NAME@,,;t t\ns,@PACKAGE_TARNAME@,,;t t\ns,@PACKAGE_VERSION@,,;t t\ns,@PACKAGE_STRING@,,;t t\ns,@PACKAGE_BUGREPORT@,,;t t\ns,@exec_prefix@,${prefix},;t t\ns,@prefix@,/dev/env/DJDIR,;t t\ns%@program_transform_name@%s,^,,%;t t\ns,@bindir@,${exec_prefix}/bin,;t t\ns,@sbindir@,${exec_prefix}/sbin,;t t\ns,@libexecdir@,${exec_prefix}/libexec,;t t\ns,@datadir@,${prefix}/share,;t t\ns,@sysconfdir@,${prefix}/etc,;t t\ns,@sharedstatedir@,${prefix}/com,;t t\ns,@localstatedir@,${prefix}/var,;t t\ns,@libdir@,${exec_prefix}/lib,;t t\ns,@includedir@,${prefix}/include,;t t\ns,@oldincludedir@,/usr/include,;t t\ns,@infodir@,${prefix}/info,;t t\ns,@mandir@,${prefix}/man,;t t\ns,@build_alias@,i586-pc-msdosdjgpp,;t t\ns,@host_alias@,i586-pc-msdosdjgpp,;t t\ns,@target_alias@,i386-msdosdjgpp,;t t\ns,@DEFS@,,;t t\ns,@ECHO_C@,,;t t\ns,@ECHO_N@,-n,;t t\ns,@ECHO_T@,,;t t\ns,@LIBS@,-lm ,;t t\ns,@MAJOR@,1,;t t\ns,@MINOR@,7,;t t\ns,@TEENY@,3,;t t\ns,@build@,i586-pc-msdosdjgpp,;t t\ns,@build_cpu@,i586,;t t\ns,@build_vendor@,pc,;t t\ns,@build_os@,msdosdjgpp,;t t\ns,@host@,i586-pc-msdosdjgpp,;t t\ns,@host_cpu@,i586,;t t\ns,@host_vendor@,pc,;t t\ns,@host_os@,msdosdjgpp,;t t\ns,@target@,i386-pc-msdosdjgpp,;t t\ns,@target_cpu@,i386,;t t\ns,@target_vendor@,pc,;t t\ns,@target_os@,msdosdjgpp,;t t\ns,@CC@,gcc,;t t\ns,@ac_ct_CC@,,;t t\ns,@CFLAGS@,-Os,;t t\ns,@LDFLAGS@,,;t t\ns,@CPPFLAGS@,,;t t\ns,@EXEEXT@,.exe,;t t\ns,@OBJEXT@,o,;t t\ns,@CPP@,gcc -E,;t t\ns,@EGREP@,grep -E,;t t\ns,@GNU_LD@,yes,;t t\ns,@CPPOUTFILE@,-o conftest.i,;t t\ns,@OUTFLAG@,-o ,;t t\ns,@YACC@,bison -y,;t t\ns,@RANLIB@,ranlib,;t t\ns,@ac_ct_RANLIB@,,;t t\ns,@AR@,ar,;t t\ns,@ac_ct_AR@,,;t t\ns,@NM@,,;t t\ns,@ac_ct_NM@,,;t t\ns,@WINDRES@,,;t t\ns,@ac_ct_WINDRES@,,;t t\ns,@DLLWRAP@,,;t t\ns,@ac_ct_DLLWRAP@,,;t t\ns,@LN_S@,ln -s,;t t\ns,@SET_MAKE@,,;t t\ns,@LIBOBJS@,crypt.o flock.o vsnprintf.o,;t t\ns,@ALLOCA@,,;t t\ns,@XCFLAGS@,,;t t\ns,@XLDFLAGS@, -L.,;t t\ns,@DLDFLAGS@,,;t t\ns,@STATIC@,,;t t\ns,@CCDLFLAGS@,,;t t\ns,@LDSHARED@,ld,;t t\ns,@DLEXT@,so,;t t\ns,@DLEXT2@,,;t t\ns,@LIBEXT@,a,;t t\ns,@LINK_SO@,,;t t\ns,@LIBPATHFLAG@, -L%s,;t t\ns,@STRIP@,strip,;t t\ns,@EXTSTATIC@,,;t t\ns,@setup@,Setup.dj,;t t\ns,@MINIRUBY@,./miniruby,;t t\ns,@PREP@,,;t t\ns,@ARCHFILE@,,;t t\ns,@LIBRUBY_LDSHARED@,ld,;t t\ns,@LIBRUBY_DLDFLAGS@,,;t t\ns,@RUBY_INSTALL_NAME@,ruby,;t t\ns,@rubyw_install_name@,,;t t\ns,@RUBYW_INSTALL_NAME@,,;t t\ns,@RUBY_SO_NAME@,$(RUBY_INSTALL_NAME),;t t\ns,@LIBRUBY_A@,lib$(RUBY_INSTALL_NAME).a,;t t\ns,@LIBRUBY_SO@,lib$(RUBY_SO_NAME).so.$(MAJOR).$(MINOR).$(TEENY),;t t\ns,@LIBRUBY_ALIASES@,lib$(RUBY_SO_NAME).so,;t t\ns,@LIBRUBY@,$(LIBRUBY_A),;t t\ns,@LIBRUBYARG@,-l$(RUBY_INSTALL_NAME),;t t\ns,@SOLIBS@,,;t t\ns,@DLDLIBS@,-lc,;t t\ns,@ENABLE_SHARED@,no,;t t\ns,@MAINLIBS@,,;t t\ns,@COMMON_LIBS@,,;t t\ns,@COMMON_MACROS@,,;t t\ns,@COMMON_HEADERS@,,;t t\ns,@EXPORT_PREFIX@,,;t t\ns,@MAKEFILES@,Makefile,;t t\ns,@arch@,i386-msdosdjgpp,;t t\ns,@sitearch@,i386-msdosdjgpp,;t t\ns,@sitedir@,${prefix}/lib/ruby/site_ruby,;t t\ns,@configure_args@,,;t t\n/^,THIS_IS_DUMMY_PATTERN_/i\\\nac_given_srcdir=.\n"
  },
  {
    "path": "djgpp/configure.bat",
    "content": "@echo off\r\nif exist configure.bat cd ..\r\nif exist djgpp\\version.sed goto exist\r\n  sed -n -f djgpp\\mkver.sed < version.h > djgpp\\version.sed\r\n:exist\r\nset _conv_=-f djgpp\\config.sed -f djgpp\\version.sed\r\nsed %_conv_% < Makefile.in > Makefile\r\nsed %_conv_% < djgpp\\config.hin > config.h\r\necho LFN check > 12345678\r\nsed -n /LFN/d 123456789 > nul\r\nif errorlevel 2 goto LFN\r\n    copy missing\\vsnprintf.c missing\\vsnprint.c > nul\r\n    copy djgpp\\config.sed config.sta > nul\r\ngoto end\r\n:LFN\r\n    copy djgpp\\config.sed config.status > nul\r\n:end\r\nset _conv_=\r\ndel 12345678\r\necho Now you must run a make.\r\n"
  },
  {
    "path": "djgpp/mkver.sed",
    "content": "/RUBY_VERSION /s/^.*\\([0-9][0-9]*\\)\\.\\([0-9][0-9]*\\)\\.\\([0-9][0-9]*\\).*$/s,@MAJOR@,\\1,;s,@MINOR@,\\2,;s,@TEENY@,\\3,/p\n"
  },
  {
    "path": "dln.c",
    "content": "/**********************************************************************\n\n  dln.c -\n\n  $Author$\n  $Date$\n  created at: Tue Jan 18 17:05:06 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"dln.h\"\n\n#ifdef HAVE_STDLIB_H\n# include <stdlib.h>\n#endif\n\n#ifdef __CHECKER__\n#undef HAVE_DLOPEN\n#undef USE_DLN_A_OUT\n#undef USE_DLN_DLOPEN\n#endif\n\n#ifdef USE_DLN_A_OUT\nchar *dln_argv0;\n#endif\n\n#if defined(HAVE_ALLOCA_H)\n#include <alloca.h>\n#endif\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#else\n# include <strings.h>\n#endif\n\n#ifndef xmalloc\nvoid *xmalloc();\nvoid *xcalloc();\nvoid *xrealloc();\n#endif\n\n#include <stdio.h>\n#if defined(_WIN32) || defined(__VMS)\n#include \"missing/file.h\"\n#endif\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#ifndef S_ISDIR\n#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)\n#endif\n\n#ifdef HAVE_SYS_PARAM_H\n# include <sys/param.h>\n#endif\n#ifndef MAXPATHLEN\n# define MAXPATHLEN 1024\n#endif\n\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\n\n#ifndef _WIN32\nchar *getenv();\n#endif\n\n#if defined(__VMS)\n#pragma builtins\n#include <dlfcn.h>\n#endif\n\n#ifdef __MACOS__\n# include <TextUtils.h>\n# include <CodeFragments.h>\n# include <Aliases.h>\n# include \"macruby_private.h\"\n#endif\n\n#if defined(__APPLE__) && defined(__MACH__)   /* Mac OS X */\n# if defined(HAVE_DLOPEN)\n   /* Mac OS X with dlopen (10.3 or later) */\n#  define MACOSX_DLOPEN\n# else\n#  define MACOSX_DYLD\n# endif\n#endif\n\n#ifdef __BEOS__\n# include <image.h>\n#endif\n\n#ifndef NO_DLN_LOAD\n\n#if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(_AIX) && !defined(MACOSX_DYLD) && !defined(_UNICOSMP)\n/* dynamic load with dlopen() */\n# define USE_DLN_DLOPEN\n#endif\n\n#ifndef FUNCNAME_PATTERN\n# if defined(__hp9000s300) ||  (defined(__NetBSD__) && !defined(__ELF__)) || defined(__BORLANDC__) || (defined(__FreeBSD__) && !defined(__ELF__)) || (defined(__OpenBSD__) && !defined(__ELF__)) || defined(NeXT) || defined(__WATCOMC__) || defined(MACOSX_DYLD)\n#  define FUNCNAME_PATTERN \"_Init_%s\"\n# else\n#  define FUNCNAME_PATTERN \"Init_%s\"\n# endif\n#endif\n\nstatic int\ninit_funcname_len(buf, file)\n    char **buf;\n    const char *file;\n{\n    char *p;\n    const char *slash;\n    int len;\n\n    /* Load the file as an object one */\n    for (slash = file-1; *file; file++) /* Find position of last '/' */\n#ifdef __MACOS__\n\tif (*file == ':') slash = file;\n#else\n\tif (*file == '/') slash = file;\n#endif\n\n    len = strlen(FUNCNAME_PATTERN) + strlen(slash + 1);\n    *buf = xmalloc(len);\n    snprintf(*buf, len, FUNCNAME_PATTERN, slash + 1);\n    for (p = *buf; *p; p++) {         /* Delete suffix if it exists */\n\tif (*p == '.') {\n\t    *p = '\\0'; break;\n\t}\n    }\n    return p - *buf;\n}\n\n#define init_funcname(buf, file) do {\\\n    int len = init_funcname_len(buf, file);\\\n    char *tmp = ALLOCA_N(char, len+1);\\\n    if (!tmp) {\\\n\tfree(*buf);\\\n\trb_memerror();\\\n    }\\\n    strcpy(tmp, *buf);\\\n    free(*buf);\\\n    *buf = tmp;\\\n} while (0)\n\n#ifdef USE_DLN_A_OUT\n\n#ifndef LIBC_NAME\n# define LIBC_NAME \"libc.a\"\n#endif\n\n#ifndef DLN_DEFAULT_LIB_PATH\n#  define DLN_DEFAULT_LIB_PATH \"/lib:/usr/lib:/usr/local/lib:.\"\n#endif\n\n#include <errno.h>\n\nstatic int dln_errno;\n\n#define DLN_ENOEXEC\tENOEXEC\t/* Exec format error */\n#define DLN_ECONFL\t1201\t/* Symbol name conflict */\n#define DLN_ENOINIT\t1202\t/* No initializer given */\n#define DLN_EUNDEF\t1203\t/* Undefine symbol remains */\n#define DLN_ENOTLIB\t1204\t/* Not a library file */\n#define DLN_EBADLIB\t1205\t/* Malformed library file */\n#define DLN_EINIT\t1206\t/* Not initialized */\n\nstatic int dln_init_p = 0;\n\n#include <ar.h>\n#include <a.out.h>\n#ifndef N_COMM\n# define N_COMM 0x12\n#endif\n#ifndef N_MAGIC\n# define N_MAGIC(x) (x).a_magic\n#endif\n\n#define INVALID_OBJECT(h) (N_MAGIC(h) != OMAGIC)\n\n#include \"util.h\"\n#include \"st.h\"\n\nstatic st_table *sym_tbl;\nstatic st_table *undef_tbl;\n\nstatic int load_lib();\n\nstatic int\nload_header(fd, hdrp, disp)\n    int fd;\n    struct exec *hdrp;\n    long disp;\n{\n    int size;\n\n    lseek(fd, disp, 0);\n    size = read(fd, hdrp, sizeof(struct exec));\n    if (size == -1) {\n\tdln_errno = errno;\n\treturn -1;\n    }\n    if (size != sizeof(struct exec) || N_BADMAG(*hdrp)) {\n\tdln_errno = DLN_ENOEXEC;\n\treturn -1;\n    }\n    return 0;\n}\n\n#if defined(sequent)\n#define RELOC_SYMBOL(r)\t\t\t((r)->r_symbolnum)\n#define RELOC_MEMORY_SUB_P(r)\t\t((r)->r_bsr)\n#define RELOC_PCREL_P(r)\t\t((r)->r_pcrel || (r)->r_bsr)\n#define RELOC_TARGET_SIZE(r)\t\t((r)->r_length)\n#endif\n\n/* Default macros */\n#ifndef RELOC_ADDRESS\n#define RELOC_ADDRESS(r)\t\t((r)->r_address)\n#define RELOC_EXTERN_P(r)\t\t((r)->r_extern)\n#define RELOC_SYMBOL(r)\t\t\t((r)->r_symbolnum)\n#define RELOC_MEMORY_SUB_P(r)\t\t0\n#define RELOC_PCREL_P(r)\t\t((r)->r_pcrel)\n#define RELOC_TARGET_SIZE(r)\t\t((r)->r_length)\n#endif\n\n#if defined(sun) && defined(sparc)\n/* Sparc (Sun 4) macros */\n#  undef relocation_info\n#  define relocation_info reloc_info_sparc\n#  define R_RIGHTSHIFT(r)\t(reloc_r_rightshift[(r)->r_type])\n#  define R_BITSIZE(r) \t\t(reloc_r_bitsize[(r)->r_type])\n#  define R_LENGTH(r)\t\t(reloc_r_length[(r)->r_type])\nstatic int reloc_r_rightshift[] = {\n  0, 0, 0, 0, 0, 0, 2, 2, 10, 0, 0, 0, 0, 0, 0,\n};\nstatic int reloc_r_bitsize[] = {\n  8, 16, 32, 8, 16, 32, 30, 22, 22, 22, 13, 10, 32, 32, 16,\n};\nstatic int reloc_r_length[] = {\n  0, 1, 2, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n};\n#  define R_PCREL(r) \\\n    ((r)->r_type >= RELOC_DISP8 && (r)->r_type <= RELOC_WDISP22)\n#  define R_SYMBOL(r) ((r)->r_index)\n#endif\n\n#if defined(sequent)\n#define R_SYMBOL(r)\t\t((r)->r_symbolnum)\n#define R_MEMORY_SUB(r)\t\t((r)->r_bsr)\n#define R_PCREL(r)\t\t((r)->r_pcrel || (r)->r_bsr)\n#define R_LENGTH(r)\t\t((r)->r_length)\n#endif\n\n#ifndef R_SYMBOL\n#  define R_SYMBOL(r) \t\t((r)->r_symbolnum)\n#  define R_MEMORY_SUB(r)\t0\n#  define R_PCREL(r)  \t\t((r)->r_pcrel)\n#  define R_LENGTH(r) \t\t((r)->r_length)\n#endif\n\nstatic struct relocation_info *\nload_reloc(fd, hdrp, disp)\n     int fd;\n     struct exec *hdrp;\n     long disp;\n{\n    struct relocation_info *reloc;\n    int size;\n\n    lseek(fd, disp + N_TXTOFF(*hdrp) + hdrp->a_text + hdrp->a_data, 0);\n    size = hdrp->a_trsize + hdrp->a_drsize;\n    reloc = (struct relocation_info*)xmalloc(size);\n    if (reloc == NULL) {\n\tdln_errno = errno;\n\treturn NULL;\n    }\n\n    if (read(fd, reloc, size) !=  size) {\n\tdln_errno = errno;\n\tfree(reloc);\n\treturn NULL;\n    }\n\n    return reloc;\n}\n\nstatic struct nlist *\nload_sym(fd, hdrp, disp)\n    int fd;\n    struct exec *hdrp;\n    long disp;\n{\n    struct nlist * buffer;\n    struct nlist * sym;\n    struct nlist * end;\n    long displ;\n    int size;\n\n    lseek(fd, N_SYMOFF(*hdrp) + hdrp->a_syms + disp, 0);\n    if (read(fd, &size, sizeof(int)) != sizeof(int)) {\n\tgoto err_noexec;\n    }\n\n    buffer = (struct nlist*)xmalloc(hdrp->a_syms + size);\n    if (buffer == NULL) {\n\tdln_errno = errno;\n\treturn NULL;\n    }\n\n    lseek(fd, disp + N_SYMOFF(*hdrp), 0);\n    if (read(fd, buffer, hdrp->a_syms + size) != hdrp->a_syms + size) {\n\tfree(buffer);\n\tgoto err_noexec;\n    }\n\n    sym = buffer;\n    end = sym + hdrp->a_syms / sizeof(struct nlist);\n    displ = (long)buffer + (long)(hdrp->a_syms);\n\n    while (sym < end) {\n\tsym->n_un.n_name = (char*)sym->n_un.n_strx + displ;\n\tsym++;\n    }\n    return buffer;\n\n  err_noexec:\n    dln_errno = DLN_ENOEXEC;\n    return NULL;\n}\n\nstatic st_table *\nsym_hash(hdrp, syms)\n    struct exec *hdrp;\n    struct nlist *syms;\n{\n    st_table *tbl;\n    struct nlist *sym = syms;\n    struct nlist *end = syms + (hdrp->a_syms / sizeof(struct nlist));\n\n    tbl = st_init_strtable();\n    if (tbl == NULL) {\n\tdln_errno = errno;\n\treturn NULL;\n    }\n\n    while (sym < end) {\n\tst_insert(tbl, sym->n_un.n_name, sym);\n\tsym++;\n    }\n    return tbl;\n}\n\nstatic int\ndln_init(prog)\n    const char *prog;\n{\n    char *file;\n    int fd;\n    struct exec hdr;\n    struct nlist *syms;\n\n    if (dln_init_p == 1) return 0;\n\n    file = dln_find_exe(prog, NULL);\n    if (file == NULL || (fd = open(file, O_RDONLY)) < 0) {\n\tdln_errno = errno;\n\treturn -1;\n    }\n\n    if (load_header(fd, &hdr, 0) == -1) return -1;\n    syms = load_sym(fd, &hdr, 0);\n    if (syms == NULL) {\n\tclose(fd);\n\treturn -1;\n    }\n    sym_tbl = sym_hash(&hdr, syms);\n    if (sym_tbl == NULL) {\t/* file may be start with #! */\n\tchar c = '\\0';\n\tchar buf[MAXPATHLEN];\n\tchar *p;\n\n\tfree(syms);\n\tlseek(fd, 0L, 0);\n\tif (read(fd, &c, 1) == -1) {\n\t    dln_errno = errno;\n\t    return -1;\n\t}\n\tif (c != '#') goto err_noexec;\n\tif (read(fd, &c, 1) == -1) {\n\t    dln_errno = errno;\n\t    return -1;\n\t}\n\tif (c != '!') goto err_noexec;\n\n\tp = buf;\n\t/* skip forwarding spaces */\n\twhile (read(fd, &c, 1) == 1) {\n\t    if (c == '\\n') goto err_noexec;\n\t    if (c != '\\t' && c != ' ') {\n\t\t*p++ = c;\n\t\tbreak;\n\t    }\n\t}\n\t/* read in command name */\n\twhile (read(fd, p, 1) == 1) {\n\t    if (*p == '\\n' || *p == '\\t' || *p == ' ') break;\n\t    p++;\n\t    if (p-buf >= MAXPATHLEN) {\n\t\tdln_errno = ENAMETOOLONG;\n\t\treturn -1;\n\t    }\n\t}\n\t*p = '\\0';\n\n\treturn dln_init(buf);\n    }\n    dln_init_p = 1;\n    undef_tbl = st_init_strtable();\n    close(fd);\n    return 0;\n\n  err_noexec:\n    close(fd);\n    dln_errno = DLN_ENOEXEC;\n    return -1;\n}\n\nstatic long\nload_text_data(fd, hdrp, bss, disp)\n    int fd;\n    struct exec *hdrp;\n    int bss;\n    long disp;\n{\n    int size;\n    unsigned char* addr;\n\n    lseek(fd, disp + N_TXTOFF(*hdrp), 0);\n    size = hdrp->a_text + hdrp->a_data;\n\n    if (bss == -1) size += hdrp->a_bss;\n    else if (bss > 1) size += bss;\n\n    addr = (unsigned char*)xmalloc(size);\n    if (addr == NULL) {\n\tdln_errno = errno;\n\treturn 0;\n    }\n\n    if (read(fd, addr, size) !=  size) {\n\tdln_errno = errno;\n\tfree(addr);\n\treturn 0;\n    }\n\n    if (bss == -1) {\n\tmemset(addr +  hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss);\n    }\n    else if (bss > 0) {\n\tmemset(addr +  hdrp->a_text + hdrp->a_data, 0, bss);\n    }\n\n    return (long)addr;\n}\n\nstatic int\nundef_print(key, value)\n    char *key, *value;\n{\n    fprintf(stderr, \"  %s\\n\", key);\n    return ST_CONTINUE;\n}\n\nstatic void\ndln_print_undef()\n{\n    fprintf(stderr, \" Undefined symbols:\\n\");\n    st_foreach(undef_tbl, undef_print, NULL);\n}\n\nstatic void\ndln_undefined()\n{\n    if (undef_tbl->num_entries > 0) {\n\tfprintf(stderr, \"dln: Calling undefined function\\n\");\n\tdln_print_undef();\n\trb_exit(1);\n    }\n}\n\nstruct undef {\n    char *name;\n    struct relocation_info reloc;\n    long base;\n    char *addr;\n    union {\n\tchar c;\n\tshort s;\n\tlong l;\n    } u;\n};\n\nstatic st_table *reloc_tbl = NULL;\nstatic void\nlink_undef(name, base, reloc)\n    const char *name;\n    long base;\n    struct relocation_info *reloc;\n{\n    static int u_no = 0;\n    struct undef *obj;\n    char *addr = (char*)(reloc->r_address + base);\n\n    obj = (struct undef*)xmalloc(sizeof(struct undef));\n    obj->name = strdup(name);\n    obj->reloc = *reloc;\n    obj->base = base;\n    switch (R_LENGTH(reloc)) {\n      case 0:\t\t/* byte */\n\tobj->u.c = *addr;\n\tbreak;\n      case 1:\t\t/* word */\n\tobj->u.s = *(short*)addr;\n\tbreak;\n      case 2:\t\t/* long */\n\tobj->u.l = *(long*)addr;\n\tbreak;\n    }\n    if (reloc_tbl == NULL) {\n\treloc_tbl = st_init_numtable();\n    }\n    st_insert(reloc_tbl, u_no++, obj);\n}\n\nstruct reloc_arg {\n    const char *name;\n    long value;\n};\n\nstatic int\nreloc_undef(no, undef, arg)\n    int no;\n    struct undef *undef;\n    struct reloc_arg *arg;\n{\n    int datum;\n    char *address;\n#if defined(sun) && defined(sparc)\n    unsigned int mask = 0;\n#endif\n\n    if (strcmp(arg->name, undef->name) != 0) return ST_CONTINUE;\n    address = (char*)(undef->base + undef->reloc.r_address);\n    datum = arg->value;\n\n    if (R_PCREL(&(undef->reloc))) datum -= undef->base;\n#if defined(sun) && defined(sparc)\n    datum += undef->reloc.r_addend;\n    datum >>= R_RIGHTSHIFT(&(undef->reloc));\n    mask = (1 << R_BITSIZE(&(undef->reloc))) - 1;\n    mask |= mask -1;\n    datum &= mask;\n    switch (R_LENGTH(&(undef->reloc))) {\n      case 0:\n\t*address = undef->u.c;\n\t*address &= ~mask;\n\t*address |= datum;\n\tbreak;\n      case 1:\n\t*(short *)address = undef->u.s;\n\t*(short *)address &= ~mask;\n\t*(short *)address |= datum;\n\tbreak;\n      case 2:\n\t*(long *)address = undef->u.l;\n\t*(long *)address &= ~mask;\n\t*(long *)address |= datum;\n\tbreak;\n    }\n#else\n    switch (R_LENGTH(&(undef->reloc))) {\n      case 0:\t\t/* byte */\n\tif (R_MEMORY_SUB(&(undef->reloc)))\n\t    *address = datum - *address;\n\telse *address = undef->u.c + datum;\n\tbreak;\n      case 1:\t\t/* word */\n\tif (R_MEMORY_SUB(&(undef->reloc)))\n\t    *(short*)address = datum - *(short*)address;\n\telse *(short*)address = undef->u.s + datum;\n\tbreak;\n      case 2:\t\t/* long */\n\tif (R_MEMORY_SUB(&(undef->reloc)))\n\t    *(long*)address = datum - *(long*)address;\n\telse *(long*)address = undef->u.l + datum;\n\tbreak;\n    }\n#endif\n    free(undef->name);\n    free(undef);\n    return ST_DELETE;\n}\n\nstatic void\nunlink_undef(name, value)\n    const char *name;\n    long value;\n{\n    struct reloc_arg arg;\n\n    arg.name = name;\n    arg.value = value;\n    st_foreach(reloc_tbl, reloc_undef, &arg);\n}\n\n#ifdef N_INDR\nstruct indr_data {\n    char *name0, *name1;\n};\n\nstatic int\nreloc_repl(no, undef, data)\n    int no;\n    struct undef *undef;\n    struct indr_data *data;\n{\n    if (strcmp(data->name0, undef->name) == 0) {\n\tfree(undef->name);\n\tundef->name = strdup(data->name1);\n    }\n    return ST_CONTINUE;\n}\n#endif\n\nstatic int\nload_1(fd, disp, need_init)\n    int fd;\n    long disp;\n    const char *need_init;\n{\n    static const char *libc = LIBC_NAME;\n    struct exec hdr;\n    struct relocation_info *reloc = NULL;\n    long block = 0;\n    long new_common = 0; /* Length of new common */\n    struct nlist *syms = NULL;\n    struct nlist *sym;\n    struct nlist *end;\n    int init_p = 0;\n\n    if (load_header(fd, &hdr, disp) == -1) return -1;\n    if (INVALID_OBJECT(hdr)) {\n\tdln_errno = DLN_ENOEXEC;\n\treturn -1;\n    }\n    reloc = load_reloc(fd, &hdr, disp);\n    if (reloc == NULL) return -1;\n\n    syms = load_sym(fd, &hdr, disp);\n    if (syms == NULL) {\n\tfree(reloc);\n\treturn -1;\n    }\n\n    sym = syms;\n    end = syms + (hdr.a_syms / sizeof(struct nlist));\n    while (sym < end) {\n\tstruct nlist *old_sym;\n\tint value = sym->n_value;\n\n#ifdef N_INDR\n\tif (sym->n_type == (N_INDR | N_EXT)) {\n\t    char *key = sym->n_un.n_name;\n\n\t    if (st_lookup(sym_tbl, sym[1].n_un.n_name, &old_sym)) {\n\t\tif (st_delete(undef_tbl, (st_data_t*)&key, NULL)) {\n\t\t    unlink_undef(key, old_sym->n_value);\n\t\t    free(key);\n\t\t}\n\t    }\n\t    else {\n\t\tstruct indr_data data;\n\n\t\tdata.name0 = sym->n_un.n_name;\n\t\tdata.name1 = sym[1].n_un.n_name;\n\t\tst_foreach(reloc_tbl, reloc_repl, &data);\n\n\t\tst_insert(undef_tbl, strdup(sym[1].n_un.n_name), NULL);\n\t\tif (st_delete(undef_tbl, (st_data_t*)&key, NULL)) {\n\t\t    free(key);\n\t\t}\n\t    }\n\t    sym += 2;\n\t    continue;\n\t}\n#endif\n\tif (sym->n_type == (N_UNDF | N_EXT)) {\n\t    if (st_lookup(sym_tbl, sym->n_un.n_name, &old_sym) == 0) {\n\t\told_sym = NULL;\n\t    }\n\n\t    if (value) {\n\t\tif (old_sym) {\n\t\t    sym->n_type = N_EXT | N_COMM;\n\t\t    sym->n_value = old_sym->n_value;\n\t\t}\n\t\telse {\n\t\t    int rnd =\n\t\t\tvalue >= sizeof(double) ? sizeof(double) - 1\n\t\t\t    : value >= sizeof(long) ? sizeof(long) - 1\n\t\t\t\t: sizeof(short) - 1;\n\n\t\t    sym->n_type = N_COMM;\n\t\t    new_common += rnd;\n\t\t    new_common &= ~(long)rnd;\n\t\t    sym->n_value = new_common;\n\t\t    new_common += value;\n\t\t}\n\t    }\n\t    else {\n\t\tif (old_sym) {\n\t\t    sym->n_type = N_EXT | N_COMM;\n\t\t    sym->n_value = old_sym->n_value;\n\t\t}\n\t\telse {\n\t\t    sym->n_value = (long)dln_undefined;\n\t\t    st_insert(undef_tbl, strdup(sym->n_un.n_name), NULL);\n\t\t}\n\t    }\n\t}\n\tsym++;\n    }\n\n    block = load_text_data(fd, &hdr, hdr.a_bss + new_common, disp);\n    if (block == 0) goto err_exit;\n\n    sym = syms;\n    while (sym < end) {\n\tstruct nlist *new_sym;\n\tchar *key;\n\n\tswitch (sym->n_type) {\n\t  case N_COMM:\n\t    sym->n_value += hdr.a_text + hdr.a_data;\n\t  case N_TEXT|N_EXT:\n\t  case N_DATA|N_EXT:\n\n\t    sym->n_value += block;\n\n\t    if (st_lookup(sym_tbl, sym->n_un.n_name, &new_sym) != 0\n\t\t&& new_sym->n_value != (long)dln_undefined) {\n\t\tdln_errno = DLN_ECONFL;\n\t\tgoto err_exit;\n\t    }\n\n\t    key = sym->n_un.n_name;\n\t    if (st_delete(undef_tbl, (st_data_t*)&key, NULL) != 0) {\n\t\tunlink_undef(key, sym->n_value);\n\t\tfree(key);\n\t    }\n\n\t    new_sym = (struct nlist*)xmalloc(sizeof(struct nlist));\n\t    *new_sym = *sym;\n\t    new_sym->n_un.n_name = strdup(sym->n_un.n_name);\n\t    st_insert(sym_tbl, new_sym->n_un.n_name, new_sym);\n\t    break;\n\n\t  case N_TEXT:\n\t  case N_DATA:\n\t    sym->n_value += block;\n\t    break;\n\t}\n\tsym++;\n    }\n\n    /*\n     * First comes the text-relocation\n     */\n    {\n\tstruct relocation_info * rel = reloc;\n\tstruct relocation_info * rel_beg = reloc +\n\t    (hdr.a_trsize/sizeof(struct relocation_info));\n\tstruct relocation_info * rel_end = reloc +\n\t    (hdr.a_trsize+hdr.a_drsize)/sizeof(struct relocation_info);\n\n\twhile (rel < rel_end) {\n\t    char *address = (char*)(rel->r_address + block);\n\t    long datum = 0;\n#if defined(sun) && defined(sparc)\n\t    unsigned int mask = 0;\n#endif\n\n\t    if(rel >= rel_beg)\n\t\taddress += hdr.a_text;\n\n\t    if (rel->r_extern) { /* Look it up in symbol-table */\n\t\tsym = &(syms[R_SYMBOL(rel)]);\n\t\tswitch (sym->n_type) {\n\t\t  case N_EXT|N_UNDF:\n\t\t    link_undef(sym->n_un.n_name, block, rel);\n\t\t  case N_EXT|N_COMM:\n\t\t  case N_COMM:\n\t\t    datum = sym->n_value;\n\t\t    break;\n\t\t  default:\n\t\t    goto err_exit;\n\t\t}\n\t    } /* end.. look it up */\n\t    else { /* is static */\n\t\tswitch (R_SYMBOL(rel)) { \n\t\t  case N_TEXT:\n\t\t  case N_DATA:\n\t\t    datum = block;\n\t\t    break;\n\t\t  case N_BSS:\n\t\t    datum = block +  new_common;\n\t\t    break;\n\t\t  case N_ABS:\n\t\t    break;\n\t\t}\n\t    } /* end .. is static */\n\t    if (R_PCREL(rel)) datum -= block;\n\n#if defined(sun) && defined(sparc)\n\t    datum += rel->r_addend;\n\t    datum >>= R_RIGHTSHIFT(rel);\n\t    mask = (1 << R_BITSIZE(rel)) - 1;\n\t    mask |= mask -1;\n\t    datum &= mask;\n\n\t    switch (R_LENGTH(rel)) {\n\t      case 0:\n\t\t*address &= ~mask;\n\t\t*address |= datum;\n\t\tbreak;\n\t      case 1:\n\t\t*(short *)address &= ~mask;\n\t\t*(short *)address |= datum;\n\t\tbreak;\n\t      case 2:\n\t\t*(long *)address &= ~mask;\n\t\t*(long *)address |= datum;\n\t\tbreak;\n\t    }\n#else\n\t    switch (R_LENGTH(rel)) {\n\t      case 0:\t\t/* byte */\n\t\tif (datum < -128 || datum > 127) goto err_exit;\n\t\t*address += datum;\n\t\tbreak;\n\t      case 1:\t\t/* word */\n\t\t*(short *)address += datum;\n\t\tbreak;\n\t      case 2:\t\t/* long */\n\t\t*(long *)address += datum;\n\t\tbreak;\n\t    }\n#endif\n\t    rel++;\n\t}\n    }\n\n    if (need_init) {\n\tint len;\n\tchar **libs_to_be_linked = 0;\n\tchar *buf;\n\n\tif (undef_tbl->num_entries > 0) {\n\t    if (load_lib(libc) == -1) goto err_exit;\n\t}\n\n\tinit_funcname(&buf, need_init);\n\tlen = strlen(buf);\n\n\tfor (sym = syms; sym<end; sym++) {\n\t    char *name = sym->n_un.n_name;\n\t    if (name[0] == '_' && sym->n_value >= block) {\n\t\tif (strcmp(name+1, \"dln_libs_to_be_linked\") == 0) {\n\t\t    libs_to_be_linked = (char**)sym->n_value;\n\t\t}\n\t\telse if (strcmp(name+1, buf) == 0) {\n\t\t    init_p = 1;\n\t\t    ((int (*)())sym->n_value)();\n\t\t}\n\t    }\n\t}\n\tif (libs_to_be_linked && undef_tbl->num_entries > 0) {\n\t    while (*libs_to_be_linked) {\n\t\tload_lib(*libs_to_be_linked);\n\t\tlibs_to_be_linked++;\n\t    }\n\t}\n    }\n    free(reloc);\n    free(syms);\n    if (need_init) {\n\tif (init_p == 0) {\n\t    dln_errno = DLN_ENOINIT;\n\t    return -1;\n\t}\n\tif (undef_tbl->num_entries > 0) {\n\t    if (load_lib(libc) == -1) goto err_exit;\n\t    if (undef_tbl->num_entries > 0) {\n\t\tdln_errno = DLN_EUNDEF;\n\t\treturn -1;\n\t    }\n\t}\n    }\n    return 0;\n\n  err_exit:\n    if (syms) free(syms);\n    if (reloc) free(reloc);\n    if (block) free((char*)block);\n    return -1;\n}\n\nstatic int target_offset;\nstatic int\nsearch_undef(key, value, lib_tbl)\n    const char *key;\n    int value;\n    st_table *lib_tbl;\n{\n    long offset;\n\n    if (st_lookup(lib_tbl, key, &offset) == 0) return ST_CONTINUE;\n    target_offset = offset;\n    return ST_STOP;\n}\n\nstruct symdef {\n    int rb_str_index;\n    int lib_offset;\n};\n\nchar *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;\n\nstatic int\nload_lib(lib)\n    const char *lib;\n{\n    char *path, *file;\n    char armagic[SARMAG];\n    int fd, size;\n    struct ar_hdr ahdr;\n    st_table *lib_tbl = NULL;\n    int *data, nsym;\n    struct symdef *base;\n    char *name_base;\n\n    if (dln_init_p == 0) {\n\tdln_errno = DLN_ENOINIT;\n\treturn -1;\n    }\n\n    if (undef_tbl->num_entries == 0) return 0;\n    dln_errno = DLN_EBADLIB;\n\n    if (lib[0] == '-' && lib[1] == 'l') {\n\tlong len = strlen(lib) + 4;\n\tchar *p = alloca(len);\n\tsnprintf(p, len, \"lib%s.a\", lib+2);\n\tlib = p;\n    }\n\n    /* library search path: */\n    /* look for environment variable DLN_LIBRARY_PATH first. */\n    /* then variable dln_librrb_ary_path. */\n    /* if path is still NULL, use \".\" for path. */\n    path = getenv(\"DLN_LIBRARY_PATH\");\n    if (path == NULL) path = dln_librrb_ary_path;\n\n    file = dln_find_file(lib, path);\n    fd = open(file, O_RDONLY);\n    if (fd == -1) goto syserr;\n    size = read(fd, armagic, SARMAG);\n    if (size == -1) goto syserr;\n\n    if (size != SARMAG) {\n\tdln_errno = DLN_ENOTLIB;\n\tgoto badlib;\n    }\n    size = read(fd, &ahdr, sizeof(ahdr));\n    if (size == -1) goto syserr;\n    if (size != sizeof(ahdr) || sscanf(ahdr.ar_size, \"%d\", &size) != 1) {\n\tgoto badlib;\n    }\n\n    if (strncmp(ahdr.ar_name, \"__.SYMDEF\", 9) == 0) {\n\t/* make hash table from __.SYMDEF */\n\n\tlib_tbl = st_init_strtable();\n\tdata = (int*)xmalloc(size);\n\tif (data == NULL) goto syserr;\n\tsize = read(fd, data, size);\n\tnsym = *data / sizeof(struct symdef);\n\tbase = (struct symdef*)(data + 1);\n\tname_base = (char*)(base + nsym) + sizeof(int);\n\twhile (nsym > 0) {\n\t    char *name = name_base + base->rb_str_index;\n\n\t    st_insert(lib_tbl, name, base->lib_offset + sizeof(ahdr));\n\t    nsym--;\n\t    base++;\n\t}\n\tfor (;;) {\n\t    target_offset = -1;\n\t    st_foreach(undef_tbl, search_undef, lib_tbl);\n\t    if (target_offset == -1) break;\n\t    if (load_1(fd, target_offset, 0) == -1) {\n\t\tst_free_table(lib_tbl);\n\t\tfree(data);\n\t\tgoto badlib;\n\t    }\n\t    if (undef_tbl->num_entries == 0) break;\n\t}\n\tfree(data);\n\tst_free_table(lib_tbl);\n    }\n    else {\n\t/* linear library, need to scan (FUTURE) */\n\n\tfor (;;) {\n\t    int offset = SARMAG;\n\t    int found = 0;\n\t    struct exec hdr;\n\t    struct nlist *syms, *sym, *end;\n\n\t    while (undef_tbl->num_entries > 0) {\n\t\tfound = 0;\n\t\tlseek(fd, offset, 0);\n\t\tsize = read(fd, &ahdr, sizeof(ahdr));\n\t\tif (size == -1) goto syserr;\n\t\tif (size == 0) break;\n\t\tif (size != sizeof(ahdr)\n\t\t    || sscanf(ahdr.ar_size, \"%d\", &size) != 1) {\n\t\t    goto badlib;\n\t\t}\n\t\toffset += sizeof(ahdr);\n\t\tif (load_header(fd, &hdr, offset) == -1)\n\t\t    goto badlib;\n\t\tsyms = load_sym(fd, &hdr, offset);\n\t\tif (syms == NULL) goto badlib;\n\t\tsym = syms;\n\t\tend = syms + (hdr.a_syms / sizeof(struct nlist));\n\t\twhile (sym < end) {\n\t\t    if (sym->n_type == N_EXT|N_TEXT\n\t\t\t&& st_lookup(undef_tbl, sym->n_un.n_name, NULL)) {\n\t\t\tbreak;\n\t\t    }\n\t\t    sym++;\n\t\t}\n\t\tif (sym < end) {\n\t\t    found++;\n\t\t    free(syms);\n\t\t    if (load_1(fd, offset, 0) == -1) {\n\t\t\tgoto badlib;\n\t\t    }\n\t\t}\n\t\toffset += size;\n\t\tif (offset & 1) offset++;\n\t    }\n\t    if (found) break;\n\t}\n    }\n    close(fd);\n    return 0;\n\n  syserr:\n    dln_errno = errno;\n  badlib:\n    if (fd >= 0) close(fd);\n    return -1;\n}\n\nstatic int\nload(file)\n    const char *file;\n{\n    int fd;\n    int result;\n\n    if (dln_init_p == 0) {\n\tif (dln_init(dln_argv0) == -1) return -1;\n    }\n    result = strlen(file);\n    if (file[result-1] == 'a') {\n\treturn load_lib(file);\n    }\n\n    fd = open(file, O_RDONLY);\n    if (fd == -1) {\n\tdln_errno = errno;\n\treturn -1;\n    }\n    result = load_1(fd, 0, file);\n    close(fd);\n\n    return result;\n}\n\nvoid*\ndln_sym(name)\n    const char *name;\n{\n    struct nlist *sym;\n\n    if (st_lookup(sym_tbl, name, &sym))\n\treturn (void*)sym->n_value;\n    return NULL;\n}\n\n#endif /* USE_DLN_A_OUT */\n\n#ifdef USE_DLN_DLOPEN\n# if defined(__NetBSD__) && defined(__NetBSD_Version__) && __NetBSD_Version__ < 105000000\n#  include <nlist.h>\n#  include <link.h>\n# else\n#  include <dlfcn.h>\n# endif\n#endif\n\n#ifdef __hpux\n#include <errno.h>\n#include \"dl.h\"\n#endif\n\n#if defined(_AIX)\n#include <ctype.h>\t/* for isdigit()\t*/\n#include <errno.h>\t/* for global errno\t*/\n#include <sys/ldr.h>\n#endif\n\n#ifdef NeXT\n#if NS_TARGET_MAJOR < 4\n#include <mach-o/rld.h>\n#else\n#include <mach-o/dyld.h>\n#ifndef NSLINKMODULE_OPTION_BINDNOW\n#define NSLINKMODULE_OPTION_BINDNOW 1\n#endif\n#endif\n#else\n#ifdef MACOSX_DYLD\n#include <mach-o/dyld.h>\n#endif\n#endif\n\n#if defined _WIN32 && !defined __CYGWIN__\n#include <windows.h>\n#endif\n\n#ifdef _WIN32_WCE\n#undef FormatMessage\n#define FormatMessage FormatMessageA\n#undef LoadLibrary\n#define LoadLibrary LoadLibraryA\n#undef GetProcAddress\n#define GetProcAddress GetProcAddressA\n#endif\n\nstatic const char *\ndln_strerror()\n{\n#ifdef USE_DLN_A_OUT\n    char *strerror();\n\n    switch (dln_errno) {\n      case DLN_ECONFL:\n\treturn \"Symbol name conflict\";\n      case DLN_ENOINIT:\n\treturn \"No initializer given\";\n      case DLN_EUNDEF:\n\treturn \"Unresolved symbols\";\n      case DLN_ENOTLIB:\n\treturn \"Not a library file\";\n      case DLN_EBADLIB:\n\treturn \"Malformed library file\";\n      case DLN_EINIT:\n\treturn \"Not initialized\";\n      default:\n\treturn strerror(dln_errno);\n    }\n#endif\n\n#ifdef USE_DLN_DLOPEN\n    return (char*)dlerror();\n#endif\n\n#if defined _WIN32 && !defined __CYGWIN__\n    static char message[1024];\n    int error = GetLastError();\n    char *p = message;\n    p += sprintf(message, \"%d: \", error);\n    FormatMessage(\n\tFORMAT_MESSAGE_FROM_SYSTEM\t | FORMAT_MESSAGE_IGNORE_INSERTS,\n\tNULL,\n\terror,\n\tMAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n\tp,\n\tsizeof message - strlen(message),\n\tNULL);\n\n    for (p = message; *p; p++) {\n\tif (*p == '\\n' || *p == '\\r')\n\t    *p = ' ';\n    }\n    return message;\n#endif\n}\n\n\n#if defined(_AIX) && ! defined(_IA64)\nstatic void\naix_loaderror(const char *pathname)\n{\n    char *message[8], errbuf[1024];\n    int i,j;\n\n    struct errtab { \n\tint errnum;\n\tchar *errstr;\n    } load_errtab[] = {\n\t{L_ERROR_TOOMANY,\t\"too many errors, rest skipped.\"},\n\t{L_ERROR_NOLIB,\t\t\"can't load library:\"},\n\t{L_ERROR_UNDEF,\t\t\"can't find symbol in library:\"},\n\t{L_ERROR_RLDBAD,\n\t     \"RLD index out of range or bad relocation type:\"},\n\t{L_ERROR_FORMAT,\t\"not a valid, executable xcoff file:\"},\n\t{L_ERROR_MEMBER,\n\t     \"file not an archive or does not contain requested member:\"},\n\t{L_ERROR_TYPE,\t\t\"symbol table mismatch:\"},\n\t{L_ERROR_ALIGN,\t\t\"text alignment in file is wrong.\"},\n\t{L_ERROR_SYSTEM,\t\"System error:\"},\n\t{L_ERROR_ERRNO,\t\tNULL}\n    };\n\n#define LOAD_ERRTAB_LEN\t(sizeof(load_errtab)/sizeof(load_errtab[0]))\n#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)\n\n    snprintf(errbuf, 1024, \"load failed - %s \", pathname);\n\n    if (!loadquery(1, &message[0], sizeof(message))) \n\tERRBUF_APPEND(strerror(errno));\n    for(i = 0; message[i] && *message[i]; i++) {\n\tint nerr = atoi(message[i]);\n\tfor (j=0; j<LOAD_ERRTAB_LEN; j++) {\n           if (nerr == load_errtab[i].errnum && load_errtab[i].errstr)\n\t\tERRBUF_APPEND(load_errtab[i].errstr);\n\t}\n\twhile (isdigit(*message[i])) message[i]++; \n\tERRBUF_APPEND(message[i]);\n\tERRBUF_APPEND(\"\\n\");\n    }\n    errbuf[strlen(errbuf)-1] = '\\0';\t/* trim off last newline */\n    rb_loaderror(errbuf);\n    return;\n}\n#endif\n\n#if defined(__VMS)\n#include <starlet.h>\n#include <rms.h>\n#include <stsdef.h>\n#include <unixlib.h>\n#include <descrip.h>\n#include <lib$routines.h>\n\nstatic char *vms_filespec;\nstatic int vms_fileact(char *filespec, int type);\nstatic long vms_fisexh(long *sigarr, long *mecarr);\n#endif\n\n#endif /* NO_DLN_LOAD */\n\nvoid*\ndln_load(file)\n    const char *file;\n{\n#ifdef NO_DLN_LOAD\n    rb_raise(rb_eLoadError, \"this executable file can't load extension libraries\");\n#else\n\n#if !defined(_AIX) && !defined(NeXT)\n    const char *error = 0;\n#define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error))\n#endif\n\n#if defined _WIN32 && !defined __CYGWIN__\n    HINSTANCE handle;\n    char winfile[MAXPATHLEN];\n    void (*init_fct)();\n    char *buf;\n\n    if (strlen(file) >= MAXPATHLEN) rb_loaderror(\"filename too long\");\n\n    /* Load the file as an object one */\n    init_funcname(&buf, file);\n\n    strcpy(winfile, file);\n\n    /* Load file */\n    if ((handle = LoadLibrary(winfile)) == NULL) {\n\terror = dln_strerror();\n\tgoto failed;\n    }\n\n    if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {\n\trb_loaderror(\"%s - %s\\n%s\", dln_strerror(), buf, file);\n    }\n\n    /* Call the init code */\n    (*init_fct)();\n    return handle;\n#else\n#ifdef USE_DLN_A_OUT\n    if (load(file) == -1) {\n\terror = dln_strerror();\n\tgoto failed;\n    }\n    return 0;\n#else\n\n    char *buf;\n    /* Load the file as an object one */\n    init_funcname(&buf, file);\n\n#ifdef USE_DLN_DLOPEN\n#define DLN_DEFINED\n    {\n\tvoid *handle;\n\tvoid (*init_fct)();\n\n#ifndef RTLD_LAZY\n# define RTLD_LAZY 1\n#endif\n#ifdef __INTERIX\n# undef RTLD_GLOBAL\n#endif\n#ifndef RTLD_GLOBAL\n# define RTLD_GLOBAL 0\n#endif\n\n\t/* Load file */\n\tif ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {\n\t    error = dln_strerror();\n\t    goto failed;\n\t}\n\n\tinit_fct = (void(*)())dlsym(handle, buf);\n\tif (init_fct == NULL) {\n\t    error = DLN_ERROR();\n\t    dlclose(handle);\n\t    goto failed;\n\t}\n\t/* Call the init code */\n\t(*init_fct)();\n\n\treturn handle;\n    }\n#endif /* USE_DLN_DLOPEN */\n\n#ifdef __hpux\n#define DLN_DEFINED\n    {\n\tshl_t lib = NULL;\n\tint flags;\n\tvoid (*init_fct)();\n\n\tflags = BIND_DEFERRED;\n\tlib = shl_load(file, flags, 0);\n\tif (lib == NULL) {\n\t    extern int errno;\n\t    rb_loaderror(\"%s - %s\", strerror(errno), file);\n\t}\n\tshl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct);\n\tif (init_fct == NULL) {\n\t    shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);\n\t    if (init_fct == NULL) {\n\t\terrno = ENOSYM;\n\t\trb_loaderror(\"%s - %s\", strerror(ENOSYM), file);\n\t    }\n\t}\n\t(*init_fct)();\n\treturn (void*)lib;\n    }\n#endif /* hpux */\n\n#if defined(_AIX) && ! defined(_IA64)\n#define DLN_DEFINED\n    {\n\tvoid (*init_fct)();\n\n\tinit_fct = (void(*)())load((char*)file, 1, 0);\n\tif (init_fct == NULL) {\n\t    aix_loaderror(file);\n\t}\n\tif (loadbind(0, (void*)dln_load, (void*)init_fct) == -1) {\n\t    aix_loaderror(file);\n\t}\n\t(*init_fct)();\n\treturn (void*)init_fct;\n    }\n#endif /* _AIX */\n\n#if defined(NeXT) || defined(MACOSX_DYLD)\n#define DLN_DEFINED\n/*----------------------------------------------------\n   By SHIROYAMA Takayuki Psi@fortune.nest.or.jp\n \n   Special Thanks...\n    Yu tomoak-i@is.aist-nara.ac.jp,\n    Mi hisho@tasihara.nest.or.jp,\n    sunshine@sunshineco.com,\n    and... Miss ARAI Akino(^^;)\n ----------------------------------------------------*/\n#if defined(NeXT) && (NS_TARGET_MAJOR < 4)/* NeXTSTEP rld functions */\n\n    {\n        NXStream* s;\n\tunsigned long init_address;\n\tchar *object_files[2] = {NULL, NULL};\n\n\tvoid (*init_fct)();\n\t\n\tobject_files[0] = (char*)file;\n\t\n\ts = NXOpenFile(2,NX_WRITEONLY);\n\n\t/* Load object file, if return value ==0 ,  load failed*/\n\tif(rld_load(s, NULL, object_files, NULL) == 0) {\n\t    NXFlush(s);\n\t    NXClose(s);\n\t    rb_loaderror(\"Failed to load %.200s\", file);\n\t}\n\n\t/* lookup the initial function */\n\tif(rld_lookup(s, buf, &init_address) == 0) {\n\t    NXFlush(s);\n\t    NXClose(s);\n\t    rb_loaderror(\"Failed to lookup Init function %.200s\", file);\n\t}\n\n\tNXFlush(s);\n\tNXClose(s);\n\n\t/* Cannot call *init_address directory, so copy this value to\n\t   funtion pointer */\n\tinit_fct = (void(*)())init_address;\n\t(*init_fct)();\n\treturn (void*)init_address;\n    }\n#else/* OPENSTEP dyld functions */\n    {\n\tint dyld_result;\n\tNSObjectFileImage obj_file; /* handle, but not use it */\n\t/* \"file\" is module file name .\n\t   \"buf\" is pointer to initial function name with \"_\" . */\n\n\tvoid (*init_fct)();\n\n\n\tdyld_result = NSCreateObjectFileImageFromFile(file, &obj_file);\n\n\tif (dyld_result != NSObjectFileImageSuccess) {\n\t    rb_loaderror(\"Failed to load %.200s\", file);\n\t}\n\n\tNSLinkModule(obj_file, file, NSLINKMODULE_OPTION_BINDNOW);\n\n\t/* lookup the initial function */\n\tif(!NSIsSymbolNameDefined(buf)) {\n\t    rb_loaderror(\"Failed to lookup Init function %.200s\",file);\n\t}\t\n\tinit_fct = NSAddressOfSymbol(NSLookupAndBindSymbol(buf));\n\t(*init_fct)();\n\n\treturn (void*)init_fct;\n    }\n#endif /* rld or dyld */\n#endif\n\n#ifdef __BEOS__\n# define DLN_DEFINED\n    {\n      status_t err_stat;  /* BeOS error status code */\n      image_id img_id;    /* extention module unique id */\n      void (*init_fct)(); /* initialize function for extention module */\n\n      /* load extention module */\n      img_id = load_add_on(file);\n      if (img_id <= 0) {\n\trb_loaderror(\"Failed to load %.200s\", file);\n      }\n      \n      /* find symbol for module initialize function. */\n      /* The Be Book KernelKit Images section described to use\n\t B_SYMBOL_TYPE_TEXT for symbol of function, not\n\t B_SYMBOL_TYPE_CODE. Why ? */\n      /* strcat(init_fct_symname, \"__Fv\"); */  /* parameter nothing. */\n      /* \"__Fv\" dont need! The Be Book Bug ? */\n      err_stat = get_image_symbol(img_id, buf,\n\t\t\t\t  B_SYMBOL_TYPE_TEXT, (void **)&init_fct);\n\n      if (err_stat != B_NO_ERROR) {\n\tchar real_name[MAXPATHLEN];\n\n\tstrcpy(real_name, buf);\n\tstrcat(real_name, \"__Fv\");\n        err_stat = get_image_symbol(img_id, real_name,\n\t\t\t\t    B_SYMBOL_TYPE_TEXT, (void **)&init_fct);\n      }\n\n      if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {\n\tunload_add_on(img_id);\n\trb_loaderror(\"Failed to lookup Init function %.200s\", file);\n      }\n      else if (B_NO_ERROR != err_stat) {\n\tchar errmsg[] = \"Internal of BeOS version. %.200s (symbol_name = %s)\";\n\tunload_add_on(img_id);\n\trb_loaderror(errmsg, strerror(err_stat), buf);\n      }\n\n      /* call module initialize function. */\n      (*init_fct)();\n      return (void*)img_id;\n    }\n#endif /* __BEOS__*/\n\n#ifdef __MACOS__   /* Mac OS 9 or before */\n# define DLN_DEFINED\n    {\n      OSErr err;\n      FSSpec libspec;\n      CFragConnectionID connID;\n      Ptr mainAddr;\n      char errMessage[1024];\n      Boolean isfolder, didsomething;\n      Str63 fragname;\n      Ptr symAddr;\n      CFragSymbolClass class;\n      void (*init_fct)();\n      char fullpath[MAXPATHLEN];\n\n      strcpy(fullpath, file);\n\n      /* resolve any aliases to find the real file */\n      c2pstr(fullpath);\n      (void)FSMakeFSSpec(0, 0, fullpath, &libspec);\n      err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);\n      if (err) {\n\t  rb_loaderror(\"Unresolved Alias - %s\", file);\n      }\n\n      /* Load the fragment (or return the connID if it is already loaded */\n      fragname[0] = 0;\n      err = GetDiskFragment(&libspec, 0, 0, fragname, \n\t\t\t    kLoadCFrag, &connID, &mainAddr,\n\t\t\t    errMessage);\n      if (err) {\n\t  p2cstr(errMessage);\n\t  rb_loaderror(\"%s - %s\",errMessage , file);\n      }\n\n      /* Locate the address of the correct init function */\n      c2pstr(buf);\n      err = FindSymbol(connID, buf, &symAddr, &class);\n      if (err) {\n\t  rb_loaderror(\"Unresolved symbols - %s\" , file);\n      }\n      init_fct = (void (*)())symAddr;\n      (*init_fct)();\n      return (void*)init_fct;\n    }\n#endif /* __MACOS__ */\n\n#if defined(__VMS)\n#define DLN_DEFINED\n    {\n\tlong status;\n\tvoid (*init_fct)();\n\tchar *fname, *p1, *p2;\n\n\t$DESCRIPTOR(fname_d, \"\");\n\t$DESCRIPTOR(image_d, \"\");\n\t$DESCRIPTOR(buf_d, \"\");\n\n\tdecc$to_vms(file, vms_fileact, 0, 0);\n\n\tfname = (char *)__alloca(strlen(file)+1);\n\tstrcpy(fname,file);\n\tif (p1 = strrchr(fname,'/'))\n\t    fname = p1 + 1;\n\tif (p2 = strrchr(fname,'.'))\n\t    *p2 = '\\0';\n\n\tfname_d.dsc$w_length  = strlen(fname);\n\tfname_d.dsc$a_pointer = fname;\n\timage_d.dsc$w_length  = strlen(vms_filespec);\n\timage_d.dsc$a_pointer = vms_filespec;\n\tbuf_d.dsc$w_length    = strlen(buf);\n\tbuf_d.dsc$a_pointer   = buf;\n\n\tlib$establish(vms_fisexh);\n\n\tstatus = lib$find_image_symbol (\n\t\t     &fname_d,\n\t\t     &buf_d, \n\t\t     &init_fct, \n\t\t     &image_d);\n\n\tlib$establish(0);\n\n\tif (status == RMS$_FNF) {\n\t    error = dln_strerror();\n\t    goto failed;\n\t} else if (!$VMS_STATUS_SUCCESS(status)) {\n\t    error = DLN_ERROR();\n\t    goto failed;\n\t}\n\n\t/* Call the init code */\n\t(*init_fct)();\n\n\treturn 1;\n    }\n#endif /* __VMS */\n\n#ifndef DLN_DEFINED\n    rb_notimplement();\n#endif\n\n#endif /* USE_DLN_A_OUT */\n#endif\n#if !defined(_AIX) && !defined(NeXT)\n  failed:\n    rb_loaderror(\"%s - %s\", error, file);\n#endif\n\n#endif /* NO_DLN_LOAD */\n    return 0;\t\t\t/* dummy return */\n}\n\nstatic char *dln_find_1();\n\nchar *\ndln_find_exe(fname, path)\n    const char *fname;\n    const char *path;\n{\n    if (!path) {\n\tpath = getenv(PATH_ENV);\n    }\n\n    if (!path) {\n#if defined(MSDOS) || defined(_WIN32) || defined(__human68k__) || defined(__MACOS__)\n\tpath = \"/usr/local/bin;/usr/ucb;/usr/bin;/bin;.\";\n#else\n\tpath = \"/usr/local/bin:/usr/ucb:/usr/bin:/bin:.\";\n#endif\n    }\n    return dln_find_1(fname, path, 1);\n}\n\nchar *\ndln_find_file(fname, path)\n    const char *fname;\n    const char *path;\n{\n#ifndef __MACOS__\n    if (!path) path = \".\";\n    return dln_find_1(fname, path, 0);\n#else\n    if (!path) path = \".\";\n    return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, 0));\n#endif\n}\n\nstatic char fbuf[MAXPATHLEN];\n\nstatic char *\ndln_find_1(fname, path, exe_flag)\n    const char *fname;\n    const char *path;\n    int exe_flag;\t\t/* non 0 if looking for executable. */\n{\n    register const char *dp;\n    register const char *ep;\n    register char *bp;\n    struct stat st;\n#ifdef __MACOS__\n    const char* mac_fullpath;\n#endif\n\n    if (!fname) return (char *)fname;\n    if (fname[0] == '/') return (char *)fname;\n    if (strncmp(\"./\", fname, 2) == 0 || strncmp(\"../\", fname, 3) == 0)\n      return (char *)fname;\n    if (exe_flag && strchr(fname, '/')) return (char *)fname;\n#ifdef DOSISH\n    if (fname[0] == '\\\\') return (char *)fname;\n# ifdef DOSISH_DRIVE_LETTER\n    if (strlen(fname) > 2 && fname[1] == ':') return (char *)fname;\n# endif\n    if (strncmp(\".\\\\\", fname, 2) == 0 || strncmp(\"..\\\\\", fname, 3) == 0)\n      return (char *)fname;\n    if (exe_flag && strchr(fname, '\\\\')) return (char *)fname;\n#endif\n\n    for (dp = path;; dp = ++ep) {\n\tregister int l;\n\tint i;\n\tint fspace;\n\n\t/* extract a component */\n\tep = strchr(dp, PATH_SEP[0]);\n\tif (ep == NULL)\n\t    ep = dp+strlen(dp);\n\n\t/* find the length of that component */\n\tl = ep - dp;\n\tbp = fbuf;\n\tfspace = sizeof fbuf - 2;\n\tif (l > 0) {\n\t    /*\n\t    **\tIf the length of the component is zero length,\n\t    **\tstart from the current directory.  If the\n\t    **\tcomponent begins with \"~\", start from the\n\t    **\tuser's $HOME environment variable.  Otherwise\n\t    **\ttake the path literally.\n\t    */\n\n\t    if (*dp == '~' && (l == 1 ||\n#if defined(DOSISH)\n\t\t\t       dp[1] == '\\\\' || \n#endif\n\t\t\t       dp[1] == '/')) {\n\t\tchar *home;\n\n\t\thome = getenv(\"HOME\");\n\t\tif (home != NULL) {\n\t\t    i = strlen(home);\n\t\t    if ((fspace -= i) < 0)\n\t\t\tgoto toolong;\n\t\t    memcpy(bp, home, i);\n\t\t    bp += i;\n\t\t}\n\t\tdp++;\n\t\tl--;\n\t    }\n\t    if (l > 0) {\n\t\tif ((fspace -= l) < 0)\n\t\t    goto toolong;\n\t\tmemcpy(bp, dp, l);\n\t\tbp += l;\n\t    }\n\n\t    /* add a \"/\" between directory and filename */\n\t    if (ep[-1] != '/')\n\t\t*bp++ = '/';\n\t}\n\n\t/* now append the file name */\n\ti = strlen(fname);\n\tif ((fspace -= i) < 0) {\n\t  toolong:\n\t    fprintf(stderr, \"openpath: pathname too long (ignored)\\n\");\n\t    *bp = '\\0';\n\t    fprintf(stderr, \"\\tDirectory \\\"%s\\\"\\n\", fbuf);\n\t    fprintf(stderr, \"\\tFile \\\"%s\\\"\\n\", fname);\n\t    goto next;\n\t}\n\tmemcpy(bp, fname, i + 1);\n\n#if defined(DOSISH)\n\tif (exe_flag) {\n\t    static const char extension[][5] = {\n#if defined(MSDOS)\n\t\t\".com\", \".exe\", \".bat\",\n#if defined(DJGPP)\n\t\t\".btm\", \".sh\", \".ksh\", \".pl\", \".sed\",\n#endif\n#elif defined(__EMX__) || defined(_WIN32)\n\t\t\".exe\", \".com\", \".cmd\", \".bat\",\n/* end of __EMX__ or _WIN32 */\n#else\n\t\t\".r\", \".R\", \".x\", \".X\", \".bat\", \".BAT\",\n/* __human68k__ */\n#endif\n\t    };\n\t    int j;\n\n\t    for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {\n\t\tif (fspace < strlen(extension[j])) {\n\t\t    fprintf(stderr, \"openpath: pathname too long (ignored)\\n\");\n\t\t    fprintf(stderr, \"\\tDirectory \\\"%.*s\\\"\\n\", (int) (bp - fbuf), fbuf);\n\t\t    fprintf(stderr, \"\\tFile \\\"%s%s\\\"\\n\", fname, extension[j]);\n\t\t    continue;\n\t\t}\n\t\tstrcpy(bp + i, extension[j]);\n#ifndef __MACOS__\n\t\tif (stat(fbuf, &st) == 0)\n\t\t    return fbuf;\n#else\n\t\tif (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf))\n\t\t    return mac_fullpath;\n\n#endif\n\t    }\n\t    goto next;\n\t}\n#endif /* MSDOS or _WIN32 or __human68k__ or __EMX__ */\n\n#ifndef __MACOS__\n\tif (stat(fbuf, &st) == 0) {\n\t    if (exe_flag == 0) return fbuf;\n\t    /* looking for executable */\n\t    if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0)\n\t\treturn fbuf;\n\t}\n#else\n\tif (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) {\n\t    if (exe_flag == 0) return mac_fullpath;\n\t    /* looking for executable */\n\t    if (stat(mac_fullpath, &st) == 0) {\n\t\tif (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0)\n\t\t    return mac_fullpath;\n\t    }\n\t}\n#endif\n\n      next:\n\t/* if not, and no other alternatives, life is bleak */\n\tif (*ep == '\\0') {\n\t    return NULL;\n\t}\n\n\t/* otherwise try the next component in the search path */\n    }\n}\n\n#if defined(__VMS)\n\n/* action routine for decc$to_vms */\nstatic int vms_fileact(char *filespec, int type)\n{\n    if (vms_filespec)\n\tfree(vms_filespec);\n    vms_filespec = malloc(strlen(filespec)+1);\n    strcpy(vms_filespec, filespec);\n    return 1;\n}\n\n/* exception handler for LIB$FIND_IMAGE_SYMBOL */\nstatic long vms_fisexh(long *sigarr, long *mecarr)\n{\n    sys$unwind(1, 0);\n    return 1;\n}\n\n#endif /* __VMS */\n"
  },
  {
    "path": "dln.h",
    "content": "/**********************************************************************\n\n  dln.h -\n\n  $Author$\n  $Date$\n  created at: Wed Jan 19 16:53:09 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef DLN_H\n#define DLN_H\n\n#ifdef __cplusplus\n# ifndef  HAVE_PROTOTYPES\n#  define HAVE_PROTOTYPES 1\n# endif\n# ifndef  HAVE_STDARG_PROTOTYPES\n#  define HAVE_STDARG_PROTOTYPES 1\n# endif\n#endif\n\n#undef _\n#ifdef HAVE_PROTOTYPES\n# define _(args) args\n#else\n# define _(args) ()\n#endif\n\nchar *dln_find_exe _((const char*,const char*));\nchar *dln_find_file _((const char*,const char*));\n\n#ifdef USE_DLN_A_OUT\nextern char *dln_argv0;\n#endif\n\nvoid *dln_load _((const char*));\n#endif\n"
  },
  {
    "path": "dmydln.c",
    "content": "#define NO_DLN_LOAD 1\n#include \"dln.c\"\n"
  },
  {
    "path": "dmyext.c",
    "content": "void\nInit_ext()\n{\n}\n"
  },
  {
    "path": "doc/ChangeLog-1.8.0",
    "content": "Mon Aug  4 17:21:19 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (class_instance_method_list): methods defined in\n\t  singleton class and extended modules should be included.\n\t  [ruby-dev:21119]\n\nMon Aug  4 13:05:57 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (method_proc): should specify YIELD_FUNC_SVALUE.\n\t  [ruby-dev:21107]\n\n\t* marshal.c (w_object): should not call w_extended for USRMARSHAL\n\t  dump. [ruby-dev:21106]\n\nMon Aug  4 10:42:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit/ui/console/testrunner.rb: Flushed io in the\n\t  Console::TestRunner so that it will output immediately.\n\nMon Aug  4 10:27:22 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* util.h: remove unnecessary parentheses.  [ruby-dev:20879]\n\nMon Aug  4 10:00:47 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (receive_responses): raise exception to\n\tclient_thread. Thanks to William Webber.\n\nMon Aug  4 09:22:53 2003  William Webber <wew@williamwebber.com>\n\n\t* lib/net/imap.rb: convert RD to RDoc.\n\nMon Aug  4 02:34:05 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_utime): never use utime() of C runtime.\n\t  [ruby-talk:77782]\n\nSun Aug  3 23:56:50 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_call_super): should propagate previous block for\n\t  super call.  [ruby-talk:77884]\n\nSun Aug  3 22:07:47 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkentry.rb: support 'validatecommand' option of \n\t  TkEntry/TkSpinbox widget\n\n\t* ext/tk/sample/{demos-en,demos-jp}/spin.rb: add\n\nSun Aug  3 19:25:28 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (call_trace_func): clear exception flag temporarily.\n\t  [ruby-dev:21090]\n\nSun Aug  3 18:03:44 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* regex.h (re_mbctab): should refer to RUBY_EXPORT.  [ruby-ext:02199]\n\n\t* lib/un.h (help): new.  % ruby -run -e help cp\n\nSun Aug  3 08:53:06 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/{demos-en,demos-jp}/image3.rb: add \n\n\t* ext/tk/lib/tkcanvas.rb: bug fix on Tk object ID management\n\n\t* ext/tk/lib/tktext.rb: ditto\n\nSun Aug  3 02:55:52 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* process.c: modify macro to detect 'MacOS X' [ruby-talk:77849]\n\n\t* ext/tcltklib/lib/tcltk.rb: bug fix ( NOT MAINTAINED : only\n\t  for running 'line2.rb' demo. )\n\nSun Aug  3 02:45:06 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* numeric.c (flo_to_s): get rid of buffer overflow.\n\nSat Aug  2 23:51:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (appendline): clearerr(3) before raising exception, since\n\t  exception may be captured by rescue. [ruby-talk:77794]\n\nSat Aug  2 09:58:13 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix --- TkGrid failed to treat \n\t  RELATIVE PLACEMENT\n\n\t* ext/tk/sample/demos-en/, demos-jp/: add or modify some\n\t  widget demo scripts\n\nSat Aug  2 20:59:38 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick/https.rb: change an option name.\n\t  :SSLCertStore -> :SSLCertificateStore.\n\nSat Aug  2 19:18:40 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: respond_to? needs 2nd argument.\n\t  Thanks Jim Bob.  [ruby-talk:77796]\n\nSat Aug  2 15:11:54 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb (--no-undefined): annoying option removed.\n\nSat Aug  2 14:53:55 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* lib/mkmf.rb (pkg_config): get configuration by pkg-config.  [new]\n\n\t* ext/openssl/extconf.rb: use pkg_config.\n\nSat Aug  2 13:45:17 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c: add \"#pragma weak\" for __libc_ia64_register_backing_store_base.\n\t  [ruby-dev:21072]\n\nSat Aug  2 14:02:39 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* variable.c (classname): find regular class name if not set.\n\t  [ruby-dev:20496]\n\nSat Aug  2 09:58:13 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix --- forgot to entry a widget class \n\t  name of 'labelframe' widget\n\n\t* ext/tk/sample/{demos-en,demos-jp}/{labelframe.rb,paned1.rb,\n\t  paned2.rb,spin.rb}: add demo-scripts to the JP/EN widget demos\n\nSat Aug  2 05:04:30 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkentry.rb: bug fix of TkEntry#delete\n\n\t* ext/tk/samples/: bug fix of some widget demos\n\n\t* ext/tk/lib/tk.rb: support <TkVariable object> == <Symbol>\n\n\t* ext/tk/lib/*.rb: freeze some object for security reason\n\nSat Aug  2 03:30:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_obj_singleton_methods): should not go up to\n\t  ancestors unless the recursive flag is set. [ruby-list:38007]\n\n\t* eval.c (rb_yield_0): expand [] to nil if avalue is set.\n\t   [ruby-dev:21058]\n\n\t* hash.c (env_each_key): use env_keys to avoid environment modify\n\t  on the fly.\n\n\t* hash.c (env_each_value): use env_values for safety.\n\n\t* hash.c (env_each): allocate environment array first.\n\nFri Aug  2 03:20:00 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* lib/yaml/store.rb (YAML::Store#initialize): filename is first\n\t  argument.  Thanks Kent Dahl.\n\nSat Aug  2 00:49:31 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: refine document.\n\nFri Aug  1 23:57:45 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* gc.c (rb_gc_mark_locations): no need to swap arguments.\n\n\t* gc.c (STACK_LENGTH): insufficient for growing up stack\n\t  architectures.\n\n\t* gc.c (rb_gc, Init_stack) ditto.\n\nFri Aug  1 23:33:36 2003  Masatoshi Seki  <mas@snow.local.>\n\n\t* rubytest.rb: set dldpath on darwin.\n\nFri Aug  1 23:07:38 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: convert RD to RDoc. Thanks William Webber.\n\t  [ruby-doc:456]\n\nFri Aug  1 19:48:56 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_emitter_write_m): forgot to declare\n\t  \"self\", making it default to \"int\".\n\n\t* ext/syck/rubyext.c (syck_emitter_simple_write): ditto.\n\n\t* gc.c (rb_gc): should mark backing store region on IA64.\n\nFri Aug  1 18:51:10 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* process.c: bug fix --- preprocessor errors occur on OpenBSD-current\n\nFri Aug  1 17:13:23 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/openssl/extconf.rb: should replace literally.\n\nFri Aug  1 16:22:57 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (rb_io_check_readable, rb_io_check_writable): ensure not\n\t  closed at first.\n\n\t* io.c (rb_io_getline): check readable always.  (ruby-bugs:PR#1069)\n\n\t* io.c (rb_io_each_byte): ditto.\n\nFri Aug  1 16:02:46 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* io.c (READ_DATA_PENDING_PTR): cast to get rid of warnings.\n\n\t* ext/socket/socket.c (unix_send_io, unix_recv_io): ditto.\n\nFri Aug  1 15:53:24 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (isInternalCmd): shouldn't return if find end of str.\n\t  [ruby-talk:77678]\n\nFri Aug  1 13:45:14 2003  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* eval.c (rb_call_super): propagate previous block if a block is\n\t  given.  [ruby-talk:77577]\n\nFri Aug  1 09:54:38 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_fill): array length may be changed during the\n\t  block execution. [ruby-talk:77579]\n\n\t* array.c (rb_ary_zip): ditto.\n\n\t* array.c (rb_ary_fill): ditto.\n\n\t* hash.c (env_reject_bang): length may be changed during the block\n\t  execution.\n\n\t* hash.c (env_clear): ditto.\n\nFri Aug  1 04:58:55 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix --- forget to eval given block to \n\t  TkRoot.new method\n\n\t* ext/tk/sample/tkoptdb-safeTk.rb: new sample script\n\nFri Aug  1 00:52:58 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (Init_stack): IA64 requires STACK_LEVEL_MAX to be less than\n\t  magic number when optimizer turned on, regardless of rlimit\n\t  values.\n\nThu Jul 31 23:44:00 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb: import erb-2.0.4b4.\n\nThu Jul 31 23:04:45 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/sample/resource.en, ext/tk/sample/resource.jp: \n\t  wrong resource file format\n\n\t* ext/tk/lib/tk.rb: add Tk::Encoding.{encoding_convertfrom, \n\t  encoding_convertto}\n\n\t* ext/tk/lib/tk.rb: add TkOptionDB.read_with_encoding to read \n\t  non-utf8 resource file\n\nThu Jul 31 23:02:47 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/etc/etc.c: revert getenv()'s prototype. use it only when _WIN32\n\t  is not defined.\n\nThu Jul 31 20:52:40 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: (IMPORTANT BUG FIX) scan of event keywords\n\t  doesn't work on recent versions of Tck/Tk\n\n\t* ext/tk/lib/tk.rb: initialize error of instance variable on \n\t  TkComposite\n\n\t* ext/tk/lib/multi-tk.rb: initialize error on encoding-system on \n\t  MultiTkIp\n\n\t* ext/tk/lib/tk.rb: trouble on destroying widgets\n\n\t* ext/tk/sample/demos-en/, demos-jp/: add JP and EN version of \n\t  Ruby/Tk widget demos\n\nThu Jul 31 15:25:12 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* array.c (rb_ary_collect): must get length of array for each\n\t  iteration. reported on [ruby-talk:77500], and fixed by\n\t  K.Sasada <ko1@namikilab.tuat.ac.jp> on [ruby-talk:77504]\n\nThu Jul 31 14:11:54 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: move gmake specific features\n\t  into GNUmakefile.\n\nThu Jul 31 12:36:11 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* bin/erb, lib/erb.rb: add explicit trim mode.\n\nThu Jul 31 04:59:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (rb_num_coerce_relop): export function.\n\nThu Jul 31 08:18:00 2003  Nathaniel Talbott  <ntalbott@ruby-lang.org>\n\n\t* lib/test/unit.rb: A useful return code is now set if tests fail when\n\t  running automatically using the Console::TestRunner.\n\nThu Jul 31 07:59:18 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: wrap the command-proc of TkScale --- pass \n\t  the numeric object to the proc\n\n\t* ext/tk/lib/tk.rb: better support for widgets created on \n\t  Tk interpreter (without Ruby)\n\n\t* ext/tk/lib/multi-tk.rb: a little more stable on Multiple Tk \n\t  interpreters running\n\nThu Jul 31 00:17:19 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (return_code): obsolete.\n\n\t* lib/net/ftp.rb (last_response_code): new method. lastresp is now\n\t  alias to last_response_code.\n\n\t* lib/net/ftp.rb (last_response): new method.\n\nWed Jul 30 23:55:44 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): check has been dropped. \"_dump must return\n\t  string.\" [ruby-dev:21024]\n\nWed Jul 30 22:35:19 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (dir_config): allow multiple directories separated\n\t  by File::PATH_SEPARATOR.\n\n\t* lib/mkmf.rb (create_makefile): DLDFLAGS include $LDFLAGS again.\n\t  [ruby-talk:76894]\n\n\t* lib/mkmf.rb (init_mkmf): not default $LDFLAGS to LDFLAGS for\n\t  ruby itself, but default $DLDFLAGS to DLDFLAGS.\n\nWed Jul 30 16:17:06 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): marshal_dump should not take any\n\t  argument.\n\nWed Jul 30 15:54:04 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_sslctx_initialize): should initialize\n\t  instance variables. [ruby-talk:77362]\n\nWed Jul 30 15:39:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (proc_options): -F set compiled regular expression to $;.\n\t  [ruby-talk:77381]\n\n\t* string.c (Init_String): no setter type check for $;\n\nWed Jul 30 15:10:02 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* error.c (rb_raise): snprintf() termination moved to\n\t  win32/win32.c.\n\n\t* win32/win32.c (valid_filename, str_grow): unused.\n\n\t* win32/win32.c (NTLoginName, ChildRecord): make static.\n\n\t* win32/win32.c (CreateChild): argument check.\n\n\t* win32/win32.c (kill): should not call CloseHandle() when\n\t  OpenProcess() failed.\n\n\t* win32/win32.c (rb_w32_vsnprintf, rb_w32_snprintf): ensure buffer\n\t  terminated.  [ruby-talk:69672]\n\nWed Jul 30 10:54:10 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (get): fix wrong argument name. Thanks to William\n\t  Webber.\n\nWed Jul 30 10:31:37 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/iconv/iconv.c (iconv_convert): append unchanged portion\n\t  after overflow.  [ruby-dev:21006]\n\n\t* ext/iconv/extconf.rb: check if iconv() 2nd argument is const.\n\nWed Jul 30 09:31:55 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (os2-emx): renamed from os2_emx, add flags to\n\t  CFLAGS and LDFLAGS, and remove lib prefix.  [ruby-dev:20993]\n\n\t* file.c (rb_file_s_rename): retry with removing new file on\n\t  DOSISH.  [ruby-dev:21007]\n\n\t* ext/socket/extconf.rb (sendmsg, recvmsg): check functions.\n\n\t* ext/socket/socket.c (unix_send_io, unix_recv_io): raise\n\t  NotImplementedError unless system calls are available.\n\n\t* ext/socket/socket.c (sock_initialize): rename from sock_init()\n\t  to get rid of conflict with OS/2 socket library.\n\nWed Jul 30 07:23:14 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkentry.rb: fix lack of methods for TkEntry\n\n\t* ext/tk/lib/multi-tk.rb, ext/tk/lib/tk.rb, \n\t  ext/tk/lib/tkdialog.rb, ext/tk/lib/tkentry.rb, \n\t  ext/tk/sample/safe-tk.rb, ext/tk/sample/tktimer2.rb: bug fix\n\n\t* ext/tk/lib/multi-tk.rb: MultiTkIp.new_* accept a block to \n\t  eval under the new interpreter\n\nWed Jul 30 04:36:30 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c, \n\t  ext/tk/lib/tk.rb, ext/tk/lib/tkafter.rb: additional check of \n\t  Tk interpreters' status for a little more safety\n\nWed Jul 30 02:37:12 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): if object responds to 'marshal_dump',\n\t  Marshal.dump uses it to dump object.  unlike '_dump',\n\t  marshal_dump returns any kind of object.\n\n\t* marshal.c (r_object0): restore instance by calling\n\t  'marshal_load' method.  unlike '_load', it's an instance\n\t  method, to handle cyclic reference.\n\n\t* marshal.c (marshal_load): all objects read from file should be\n\t  tainted. [ruby-core:01325]\n\nWed Jul 30 01:47:51 2003  Hugh Sasse  <hgs@dmu.ac.uk>\n\n\t* lib/timeout.rb (Timeout::timeout): execute immediately if sec is\n\t  zero.\n\nWed Jul 30 01:36:18 2003  Aron Griffis  <ruby-talk@griffis1.net>\n\n\t* ext/socket/socket.c (socks_init): typo fixed. [ruby-talk:77232]\n\nWed Jul 30 00:48:43 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/extconf.rb: the default value for --enable-socks is\n\t  taken from ENV[\"SOCKS_SERVER\"]. [ruby-talk:77232]\n\n\t* ruby.c (proc_options): add -W option. -W0 to shut up all warning\n\t  messages. [ruby-talk:77227]\n\n\t* error.c (rb_warn): no message will be printed if the value of\n\t  $VERBOSE is \"nil\", i.e. perfect silence.\n\n\t* ruby.c (verbose_setter): $VERBOSE value is either true, false,\n\t  or nil.\n\n\t* io.c (Init_IO): no \"read\" check for $stdin.  in addition some\n\t  function names has been changed.\n\nTue Jul 29 23:10:19 2003  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* regex.c (re_match_exec): incorrect multibyte match.\n\nTue Jul 29 22:36:50 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb (send0): do taint check only when $SAFE > 0\n\nTue Jul 29 19:20:34 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils.rb (install): support preserve timestamp.\n\n\t* instruby.rb (install): use FileUtils::install preserve mode.\n\n\t* lib/un.rb: new.  % ruby -run -e cp -- -p foo bar\n\n\t* lib/mkmf.rb: use un.rb instead of ftools.rb.\n\n\t* MANIFEST: add lib/un.rb.\n\n\t* ext/extmk.rb (INSTALL_PROG, INSTALL_DATA): modify verbose messages.\n\nTue Jul 29 18:55:22 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: unify coding style.\n\n\t* lib/net/http.rb: ditto.\n\nTue Jul 29 17:27:59 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ruby.h (LLONG_MIN): fix typo.\n\nTue Jul 29 16:38:44 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/net/smtp.rb (Net::SMTP::send0): add taint check.\n\nTue Jul 29 15:41:02 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* instruby.rb (install): preserve the timestamp for Mac OS X ranlib\n\t  problem.\n\nTue Jul 29 01:14:51 2003  Rick Ohnemus  <rick_ohnemus@acm.org>\n\n\t* ruby.h (LLONG_MIN): wrong value.\n\nMon Jul 28 22:57:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_getc): $stdin may not be IO. [ruby-dev:20973]\n\nTue Jul 29 16:20:36 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: bug fix and \n\t  change mainloop_abort_on_no_widget_cmd => mainloop_abort_on_exception\n\t  ( to avoid thread timing trouble on accessing destroyed widgets )\n\n\t* ext/tk/lib/multi-tk.rb: change default mode of \n\t  mainloop_abort_on_exception on multi-tk.rb\n\n\t* ext/tk/lib/multi-tk.rb: fix a bug of the procedure for \n\t  'Delete' button on the safe-Tk frmae\n\nTue Jul 29 12:22:28 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/token.c: prefixed many constants and definitions\n\t  with YAML_ to avoid name clash.\n\n\t* ext/syck/gram.c: ditto.\n\n\t* ext/syck/gram.h: ditto.\n\nTue Jul 29 12:15:37 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/etc/etc.c: add real prototype to getenv().\n\n\t* win32/win32.h: add arguments to definitions of functions if possible.\n\nTue Jul 29 08:05:30 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb, ext/tk/lib/tkdialog.rb, ext/tk/lib/tktext.rb, \n\t  ext/tk/sample/tkbiff.rb, ext/tk/sample/tkdialog.rb, \n\t  ext/tk/sample/tkform.rb: bug fix ( tested with Ruby/Tk widget demo )\n\nTue Jul 29 04:22:08 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/syck.h: Added 'syck' yacc prefixes.\n\n\t* ext/syck/gram.c: ditto.\n\n\t* ext/syck/token.c: ditto.\n\n\t* ext/syck: Added ruby.h reference to source files.\n\nTue Jul 29 03:53:28 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/lib/net/https.rb (use_ssl=): raise ProtocolError if\n\t  connection is set up already.\n\nTue Jul 29 01:45:32 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: use RTEST()\n\nTue Jul 29 01:24:32 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: bug fix\n\n\t* ext/tk/lib/multi-tk.rb: bug fix and pack options are pssed\n\t  to the safeTk container\n\n\t* ext/tk/sample/safe-tk.rb: add example for pack options of \n\t  safeTk container\n\nMon Jul 28 23:23:08 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (Init_File): IO should include File::Const.\n\t  [ruby-dev:20964]\n\nMon Jul 28 18:53:03 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/openssl/extconf.rb: check again after pkg-config for MinGW on\n\t  Cygwin.\n\nMon Jul 28 15:32:04 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_gets): only \"gets\" should set $_.\n\n\t* ext/stringio/stringio.c (strio_getline): should not set $_ here.\n\n\t* io.c (argf_to_s): argf.to_s returns \"ARGF\".\n\n\t* io.c (set_defout_var, set_deferr_var): make $defout and $deferr\n\t  obsolete.\n\n\t* io.c (set_input_var, set_output_var): allow $stdin, $stdout,\n\t  $stderr not to be instance of IO.\n\n\t* io.c (rb_f_readline): forward method to current_file. gets,\n\t  readline, readlines, getc, readchar, tell, seek, pos=, rewind,\n\t  fileno, to_io, eof, each_line, each_byte, binmode, and closed?\n\t  as well.\n\n\t* io.c (argf_forward): utility function to forward method to\n\t  current_file.\n\nMon Jul 28 06:10:13 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: bug fix\n\n\t* ext/lib/tk/multi-tk.rb: bug fix\n\n\t* ext/lib/tk/multi-tk.rb: add methods depend on Tcl's 'interp' command\n\n\t* ext/lib/tk/multi-tk.rb: suppot safe-level control of each interpreter\n\nMon Jul 28 03:08:47 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: each() should return self.\n\nMon Jul 28 01:35:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_chomp_bang): defer rb_str_modify() to actual\n\t  modify point.  other methods, replace, tr, delete, squeeze,\n\t  lstrip, and rstrip as well.\n\n\t* string.c (rb_str_rstrip_bang): remove trailing '\\0' at the end\n\t  of string.\n\n\t* string.c (rb_str_lstrip_bang): do not strip '\\0' from the left.\n\nSun Jul 27 21:16:30 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/openssl/extconf.rb: better support MinGW.  add\n\t  dir_config(\"kerberos\") and with_config(\"pkg-config\").\n\n\t* mkconfig.rb: initialize global variables to avoid warnings.\n\nSun Jul 27 19:35:06 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: add some methods to support\n\t  multiple interpreters (low level)\n\n\t* ext/tk/lib/multi-tk.rb: new library to support multiple Tk \n\t  interpreters (high level)\n\n\t* ext/tcltklib/demo/safeTk.rb: new sample of safeTk interpreter\n\n\t* ext/tk/sample/safe-tk.rb: new sample of multi-tk.rb\n\n\t* ext/tk/lib/tk.rb: bug fix and add feature to supprt multi-tk\n\n\t* ext/tk/lib/tkafter.rb: ditto\n\nSun Jul 27 14:43:37 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/debug.rb: fix breakpoint parameter parsing/checking.\n\t  (?:(file|class):)(line_number|method)\n\nSun Jul 27 10:21:28 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/unix.rb: add UNIXFileOwner, UNIXFileGroup.\n\nSun Jul 27 03:10:43 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (io_reopen): avoid dup2() equal handles not to close itself and\n\t  to get rid of a msvcrt bug.  [ruby-dev:20919]\n\nSun Jul 27 00:37:16 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/tmpdir.rb: use GetWindowsDirectory, not GetSystemDirectory.\n\t  [ruby-talk:77073]\n\nSat Jul 26 21:25:21 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* io.c (rb_fdopen): set errno if it's zero on win32 platforms.\n\n\t* ext/openssl/ossl_ssl.c (TO_SOCKET): define special version when\n\t  _WIN32 is defined. this is ruby's problem, not OpenSSL.\n\n\t* win32/win32.c: remove some old comments.\n\nSat Jul 26 14:26:57 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/tk/lib/tk.rb (TkCore::chooseDirectory): back up wrongly\n\t  removed method.\n\nSat Jul 26 14:14:12 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/stringio/stringio.c: includes Enumerable as well as IO.\n\t  [ruby-talk:77058]\n\nSat Jul 26 07:00:53 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb: fix % line.\n\nSat Jul 26 05:31:09 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ossl.h: fix comment.\n\n\t* ext/openssl/ossl.c (ossl_debug): should enable if no va-args\n\t  macro supplied.\n\nSat Jul 26 04:04:36 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: refine va-args macro detection.\n\t  [ruby-talk:76983]\n\nSat Jul 26 01:33:51 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/openssl/ossl_ssl.c (ossl_ssl_setup): need to pass the real\n\t  socket to SSL_get_fd on native win32 platforms.\n\nSat Jul 26 01:20:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_const_missing): \"const_missing\" should not\n\t  appear in the caller(); add call frame adjustment.\n\n\t* eval.c (rb_method_missing): simplify call frame adjustment.\n\nFri Jul 26 00:04:25 2003  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* ext/openssl/sample: add samples.\n\t  - cert2text.rb: dump certificate file as text.\n\t  - crlstore.rb: CRL store implementation.  Fetch CRL via HTTP when\n\t    http-access2 is installed.\n\t  - certstore.rb: certificate store implementation.\n\t  - cert_store_view.rb: certificate store viewer with FXRuby.  Uses\n\t    c_rehash.rb, crlstore.rb and certstore.rb.\n\nFri Jul 25 16:43:03 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: add TclTkIp#create_slave, \n\t  TclTkIp#_make_safe and TclTkIp#safe?\n\n\t* ext/tcltklib/MANUAL.euc: modify descriptions\n\n\t* ext/tk/lib/tk.rb: bug fix [ruby-talk:76980] and modify to \n\t  support multi Tk IPs\n\n\t* ext/tk/lib/tkafter.rb: modify to support multi Tk IPs\n\nFri Jul 25 15:47:39 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: add check for BN_rand_range() and\n\t  BN_pseudo_rand_range().\n\n\t* ext/openssl/ossl_bn.c (ossl_bn_s_rand_range): should raise \n\t  NotImplementedError if BN_rand_range() wan not defined.\n\n\t* ext/openssl/ossl_bn.c (ossl_bn_s_pseudo_rand_range): should raise \n\t  NotImplementedError if BN_pseudo_rand_range() wan not defined.\n\n\t* ext/openssl/ossl_pkcs7.c (ossl_pkcs7_s_encrypt): avoid compiler\n\t  warning for OpenSSL-0.9.6.\n\n\t* ext/openssl/ossl_pkcs7.c (ossl_pkcs7si_initialize): ditto.\n\nFri Jul 25 14:34:55 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (tcp_s_gethostbyname): was using\n\t  uninitialized size_t value. [ruby-talk:76946]\n\nFri Jul 25 13:38:38 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* re.c (rb_reg_options_m): use rb_reg_options() to mask internal\n\t  flags.\n\n\t* re.c (rb_reg_initialize_m): allow nil as third argument and\n\t  ignore, and mask code flags if the argument is given.\n\t  [ruby-dev:20885]\n\n\t* re.c (rb_reg_options): get common flags directly.\n\nFri Jul 25 03:52:21 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* lib/yaml/dbm.rb: replace indexes with values_at.\n\nFri Jul 25 02:55:59 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: add check for libsocket and libnsl.\n\n\t* ext/openssl/extconf.rb: use pkg-config to build CFLAGS and LDFLAGS.\n\nFri Jul 25 01:27:59 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/emitter.c (syck_emitter_flush): accepts count\n\t  of bytes to flush.  anchor offsets now functional.\n\n\t* ext/syck/syck.h (syck_emitter_flush): ditto.\n\n\t* ext/syck/rubyext.c: ditto.\n\n\t* ext/syck/token.c: URI escaping now supported.\n\nThu Jul 24 16:41:31 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (have_type): check if a type is defined.\n\n\t* lib/mkmf.rb (check_sizeof): check size of a type.\n\n\t* ext/dbm/extconf.rb: check if type DBM is defined.\n\t  [ruby-talk:76693]\n\nThu Jul 24 16:18:40 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ChangeLog (add-log-time-format): \"%c\" contains timezone on\n\t  XEmacs.\n\nThu Jul 24 16:05:22 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (AC_C_VOLATILE): check if volatile works.\n\n\t* defines.h (volatile): removed.\n\n\t* eval.c (rb_thread_group): Thread#group.  [new]\n\nThu Jul 24 15:50:42 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/extconf.rb: add check for win32 OpenSSL libraries.\n\n\t* ext/openssl/extconf.rb: add check for __VA_ARGS__.\n\n\t* ext/openssl/ossl.h: avoid non C99 compiler errors.\n\nThu Jul 24 13:32:56 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (thgroup_add): no warning for terminated threads.\n\nThu Jul 24 13:09:26 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pathname.rb: added.\n\nThu Jul 24 11:21:10 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/io/wait/extconf.rb: removed unnecessary backward\n\t  compatibility stuff.\n\nThu Jul 24 11:09:10 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/openssl/extconf.rb: revert use of dir_config.\n\nThu Jul 24 09:58:32 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/Win32API/lib/win32/resolv.rb: added.\n\n\t* lib/resolv.rb: support Win32 platforms. based on Tietew's work\n\t  [ruby-dev:15573].\n\nThu Jul 24 04:05:46 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl/ssl.h: undef X509_NAME and PKCS7_SIGNER_INFO to\n\t  avoid name confliction on mswin32.\n\n\t* ext/openssl/ssl.c (ossl_protect_obj2bio): avoid VC++ warnings\n\t  in function prototype.\n\n\t* ext/openssl/ssl.c (ossl_protect_membio2str): ditto.\n\n\t* ext/openssl/ssl.c (ossl_protect_x509_ary2sk): ditto.\n\nThu Jul 24 03:44:04 2003  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* ext/openssl/extconf.rb: cut check for OpenSSL version\n\nThu Jul 24 03:41:30 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/tcltklib/tcltklib.c (ip_init): need at least one statement after\n\t  label.\n\nThu Jul 24 01:48:03 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::[]): should return StringIO (or\n\t  Tempfile) for multipart/form.\n\n\t* variable.c (rb_define_const): give warning for non constant\n\t  name. [ruby-core:01287]\n\nThu Jul 24 01:51:08 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* lib/webrick: imported.\n\n\t* MANIFEST: added webrick files.\n\nThu Jul 24 01:32:04 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/tmpdir.rb (tmpdir): new method.  remove TMPDIR.\n\t  use GetSystemWindowsDirectory(GetSystemDirectory), not GetTempPath.\n\nThu Jul 24 01:08:43 2003  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/openssl: imported.\n\nWed Jul 23 23:06:59 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (DOSISH): better Cygwin support.\n\nWed Jul 23 19:13:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_split_m): the receiver may be empty string.\n\nWed Jul 23 18:43:00 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/erb.rb: import erb-2.0.4b1.\n\nWed Jul 23 18:21:52 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/io/wait: imported.\n\nWed Jul 23 16:07:35 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* process.c: unify indentation\n\n\t* configure.in: add --enable-setreuid option\n\n\t* ext/tcltklib/tcltklib.c: TclTkIp.new accepts 'ip-name' and 'options'\n\n\t* ext/tk/lib/tk.rb: support arguments of TclTkIp.new\n\n\t* ext/tk/lib/tk*.rb: preparations for multi-Tk interpreter support\n\nWed Jul 23 15:49:01 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_lstrip_bang): strip NUL along with white\n\t  spaces. [ruby-talk:76659]\n\n\t* string.c (rb_str_rstrip_bang): ditto.\n\nWed Jul 23 14:19:17 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (log_src, checking_for, create_header):\n\t  Logging.message is printf like format.\n\nWed Jul 23 10:11:15 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/iconv/iconv.c (check_iconv): check if Iconv instance.\n\n\t* ext/iconv/iconv.c (iconv_convert): stringify argument.\n\nWed Jul 23 02:39:46 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* process.c: add a module for raw syscalls to control UID/GID\n\n\t* process.c: add modules for portable UID/GID control\n\nTue Jul 22 19:16:40 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/iconv/iconv.c (iconv_failure_initialize): limit\n\t  inspect message.  [ruby-dev:20785]\n\n\t* ext/iconv/iconv.c (rb_str_derive): share with original\n\t  string if possible.  [ruby-dev:20785]\n\nTue Jul 22 17:22:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_const_missing): new method. [ruby-core:00441]\n\n\t* variable.c (rb_const_get_at): allow \"const_missing\" hook.\n\n\t* variable.c (rb_const_get_0): ditto.\n\n\t* eval.c (method_missing): rename from rb_undefined to clarify.\n\n\t* eval.c (ruby_finalize_0): update exit status if any of END proc\n\t  raises SystemExit. [ruby-core:01256]\n\n\t* signal.c (rb_trap_exit): wrap rb_eval_cmd\n\n\t* eval.c (rb_exec_end_proc): reduce rb_protect().\n\nTue Jul 22 17:15:57 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* MANIFEST (lib/cgi/session/pstore.rb, lib/yaml/baseemitter.rb):\n\t  added.\n\nTue Jul 22 10:52:19 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* lib/tmpdir.rb: remove charcters after \"\\000\" and regularize path.\n\nTue Jul 22 02:22:45 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_equal): should not use rb_equal().\n\n\t* string.c (rb_str_equal): should return nil for non string\n\t  operand to conform comparable convention. [ruby-dev:20759]\n\nTue Jul 22 00:19:19 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tmpdir.rb: new library to get temporary directory path,\n\t  using GetTempPath on Win32 environment.\n\n\t* lib/tempfile.rb: now uses tmpdir.rb.\n\n\t* lib/cgi/session.rb, ib/drb/unix.rb: ditto.\n\nMon Jul 21 01:53:43 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_string_value_cstr): check null byte in the string\n\t  before retrieving C ptr.  accessed via macro StringValueCStr.\n\n\t* file.c: use StringValueCStr to retrieve paths to system calls.\n\n\t* file.c (sys_fail2): raise error for two operand system calls\n\t  such as rename, link, symlink.  (ruby-bugs PR#1047)\n\nSun Jul 20 11:03:25 2003  UENO Katsuhiro  <katsu@blue.sky.or.jp>\n\n\t* ext/zlib/zlib.c (gzfile_read_header): gz->z.input may be nil after\n\t  finishing reading a gzip header.\n\nSat Jul 19 22:25:47 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_match2): add warning to \"~string\".\n\t  [ruby-list:37751]\n\n\t* lib/net/ftp.rb (Net::FTP::open): takes block.  suggested by Gavin\n\t  Sinclair in [ruby-core:01237].\n\nSat Jul 19 19:03:24 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/stdlib.c: add bsearch().\n\nSat Jul 19 12:34:45 2003  David Black  <dblack@superlink.net>\n\n\t* lib/scanf.rb: import.\n\nSat Jul 19 11:27:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/xmlrpc: import.\n\n\t* eval.c (thgroup_add): should return group for terminated thread\n\t  case.\n\n\t* eval.c (thgroup_add): do not raise ThreadError on terminated\n\t  thread addition for compatibility.  just warning.\n\nSat Jul 19 04:50:56 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/iconv/charset_alias.rb, ext/iconv/extconf.rb: make wrapper\n\t  script which maps charset names.  [ruby-dev:20625]\n\n\t* ext/iconv/iconv.c (charset_map): charset name map.\n\n\t* ext/iconv/iconv.c (iconv_dfree): no exception while\n\t  finalization.\n\n\t* ext/iconv/iconv.c (iconv_s_conv): new method Iconv.conv.\n\t  [ruby-dev:20588]\n\nSat Jul 19 03:09:18 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/Win32API/lib/win32/registry.rb (Win32::Registry::Error):\n\t  inherit StandardError instead of SystemCallError.\n\nSat Jul 19 02:00:39 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_attr): extra calls of method_added.  [ruby-talk:76361]\n\nFri Jul 18 18:44:22 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (init_mkmf): clear $INSTALLFILES.  [ruby-dev:20727]\n\nFri Jul 18 17:34:39 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (rm_f): use FileUtils.\n\n\t* lib/mkmf.rb (modified?): return mtime of the target if\n\t  it exists and newer than times.\n\n\t* lib/mkmf.rb (install_files): add a current directory\n\t  file even if it does not exist yet.\n\n\t* lib/mkmf.rb (configuration): do not add $LDFLAGS to\n\t  DLDFLAGS.\n\n\t* ext/extmk.rb (extmake): check whether Makefile is newer\n\t  than depend and MANIFEST.\n\nFri Jul 18 14:57:19 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (make_cmdvector): recognize quote within string.\n\t  based on Nobu's patch ([ruby-win32:450]). [ruby-talk:75853]\n\nFri Jul 18 13:04:36 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_missing): VCALL is called only for LOCAL_ID.  no\n\t  check required.\n\n\t* parse.y (primary): primary:tFID generates NODE_FCALL.\n\t  [ruby-dev:20641]\n\nThu Jul 17 18:50:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (match_captures): rename from \"groups\".\n\nThu Jul 17 17:57:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_clear_cache_by_class): check both klass and origin.\n\nThu Jul 17 13:46:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_init): set ruby_running to true after\n\t  initialization.\n\nThu Jul 17 13:42:53 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ftools.rb (File::makedirs): do not handle \"//\" as a directory.\n\nThu Jul 17 06:40:28 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: recover and fix typo : Tk.chooseDirectory \n\t  (Tk8.4 feature)\n\nWed Jul 16 16:23:58 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_proc_new): call svalue_to_avalue for yield argument.\n\nWed Jul 16 00:31:00 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_disable_super, rb_enable_super): deprecate.\n\n\t* eval.c (thgroup_s_alloc): re-implement group struct.\n\n\t* eval.c (thgroup_add): add check for enclose and frozen status.\n\nTue Jul 15 19:50:49 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_add_method, rb_alias): need to clear cache by\n\t  ID when method defined in parent class is cached for\n\t  grand child classes.  [ruby-dev:20672]\n\nTue Jul 15 14:38:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/matrix.rb: remove elements conversion to_f, to_i, to_r.\n\n\t* lib/cgi/session/pstore.rb: add new file.\n\nTue Jul 15 03:30:41 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c (syck_mark_emitter): forgot to rb_gc_mark the \n\t  outgoing IO object.\n\nSun Jul 13 14:55:36 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* process.c (proc_getgroups, proc_setmaxgroups): fix typo.\n\nSat Jul 12 17:01:28 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* struct.c (struct_entry): add prototype to avoid VC++ warnings.\n\nSat Jul 12 04:43:57 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/emitter.c: new emitter code.\n\n\t* ext/syck/rubyext.c: Emitter class.\n\n\t* lib/yaml.rb: Load Syck emitter, if available.\n\n\t* lib/yaml/stream.rb: ditto.\n\n\t* lib/yaml/baseemitter.rb: underlying class for all emitters.\n\n\t* lib/yaml/rubytypes.rb: use BaseEmitter abstraction.\n\n\t* lib/yaml/emitter.rb: ditto.\n\nSat Jul 12 04:23:13 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_undef): need to clear cache for inherited class.\n\t  (rubicon/builtin/TestModulePrivate.rb:test_undef_method)\n\nSat Jul 12 01:21:54 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (avalue_to_svalue): typo.\n\n\t* eval.c (rb_load): rb_prohibit_interrupt must not underflow.\n\n\t* parse.y (NODE_STRTERM, tokadd_string, parse_string): moved\n\t  string nest level from a static variable to NODE_STRTERM, to\n\t  preserve it from word to word in %W/%w.\n\nFri Jul 11 22:37:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (aix): needs ruby.imp even with gcc.\n\t  (ruby-bugs:PR#1007)\n\nFri Jul 11 18:37:37 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* instruby.rb: do not handle directories. [ruby-dev:20613]\n\nFri Jul 11 16:09:09 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_strtod): exp should be less than MDMAXEXPT.\n\nFri Jul 11 07:17:47 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: not create a Tcl/Tk interpreter if already \n\t  defined TkCore::INTERP\n\n\t* ext/tk/lib/tk.rb: bugfix on TkWindow#configure\n\nThu Jul 10 14:42:02 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* math.c (math_log): nan takes a dummy argument on Cygwin 1.5.0.\n\nWed Jul  9 23:50:46 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* regex.c (mbctab_sjis): 0x80 is not shift jis first byte.\n\t  [ruby-dev:20516]\n\nWed Jul  9 15:38:28 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* instruby.rb: do not install shared libraries as man pages.\n\n\t* mkconfig.rb: support text-mount on Cygwin.\n\nWed Jul  9 11:09:57 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* re.c (match_entry): add prototype to avoid VC++ warnings.\n\nWed Jul  9 03:48:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): put rb_load_file() in a thread critical\n\t  section. [ruby-dev:20490]\n\n\t* eval.c (compile): put rb_compile_string() in a thread critical\n\t  section.\n\nTue Jul  8 02:35:41 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_const_get_0): should not warn if constant is not\n\t  defined. (ruby-bugs-ja PR#509)\n\n\t* bignum.c (rb_big2dbl): give a warning on overflow.\n\t  (ruby-bugs-ja PR#510)\n\n\t* util.c (ruby_strtod): change MDMAXEXPT from 511 to 308.\n\n\t* pack.c (utf8_to_uv): long is sufficient.  LONG_LONG is not\n\t  required.\n\nTue Jul  8 01:43:16 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* bignum.c (rb_big2str): support 32 bit (without `long long' type)\n\t  machines. (ruby-bugs-ja PR#512)\n\nMon Jul  7 10:22:46 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb (gdbm_compat, qdbm): add check for gdbm_compat\n\t  and qdbm.\n\nMon Jul  7 01:34:49 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call_super): k->super maybe NULL if klass is Kernel.\n\t   [ruby-dev:20519]\n\n\t* gc.c (obj_free): clear method cache when freeing class/module.\n\nSat Jul  5  23:32:06 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_remove_method): allow \"remove_method\" to accept\n\t  multiple arguments.\n\nSat Jul  5 00:22:59 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* node.h (NEW_NODE): cast arguments to rb_node_newnode().\n\nFri Jul  4 21:48:44 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/syck/rubyext.c, ext/syck/syck.c, ext/syck/syck.h,\n\t  ext/syck/token.c: C++ style comments are not allowed.\n\t  (ruby-bugs:PR#1008)\n\nThu Jul  3 23:41:30 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/timeout.rb: add optional exception argument for compatibility\n\t  function.\n\nThu Jul  3 14:22:46 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_values_at): extract common procedure from\n\t  rb_ary_values_at.  follow DRY principle.\n\n\t* re.c (match_values_at): values_at should understand ranges.\n\n\t* struct.c (rb_struct_values_at): ditto.\n\n\t* struct.c (inspect_struct): inspect format changed; add \"struct \"\n\t  at the top.\n\n\t* sprintf.c (rb_f_sprintf): \"%p\" specifier for inspect output.\n\t  (RCR#69)\n\n\t* eval.c (rb_mod_undef_method): allow \"undef_method\" to accept\n\t  multiple arguments. (RCR#146)\n\n\t* lib/timeout.rb: put timeout in Timeout module. (RCR#121)\n\t  [ruby-talk:61028]\n\n\t* re.c (match_groups): new method added. (RCR#139)\n\n\t* variable.c (rb_mod_const_of): should exclude constant defined\n\t  in Object, unless retrieving constants of Object.\n\nThu Jul  3 12:13:05 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (VPATH): convert from Windows form to Unix form on \n\t  MinGW.  This fixes the build with GNU make 3.80-1 for Cygwin.\n\nWed Jul  2 23:27:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_new4): do not allocate new string if original\n\t  is frozen or already have copy-on-write entry. [ruby-talk:74940]\n\nWed Jul  2 13:22:39 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_shared_replace): clear flags before copy.\n\n\t* string.c (rb_str_replace): ditto.\n\n\t* eval.c (rb_yield_0): override visibility mode for module_eval\n\t  etc. (ruby-bugs-ja PR#505)\n\nWed Jul  2 11:45:34 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: synchronize document with source code.\n\n\t* lib/net/pop.rb: ditto.\n\nWed Jul  2 11:39:50 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: unify SMTP and SMTPCommand.\n\n\t* lib/net/smtp.rb: new exception class SMTPError.\n\n\t* lib/net/smtp.rb: new exception class SMTPAuthenticationError.\n\n\t* lib/net/smtp.rb: new exception class SMTPServerBusy.\n\n\t* lib/net/smtp.rb: new exception class SMTPSyntaxError.\n\n\t* lib/net/smtp.rb: new exception class SMTPFatalError.\n\n\t* lib/net/smtp.rb: new exception class SMTPUnknownError.\n\n\t* lib/net/smtp.rb: change critical section protect algorithm.\n\n\t* lib/net/smtp.rb (SMTP#do_start): check authentication args\n\t  before all.\n\n\t* lib/net/smtp.rb: new method send_message (alias send_mail).\n\n\t* lib/net/smtp.rb: new method open_message_stream (alias ready).\n\n\t* lib/net/pop.rb: POPBadResponse is a POPError.\n\n\t* lib/net/pop.rb (POPMail#pop): ban ReadAdapter.\n\n\t* lib/net/pop.rb (POPMail#top): ditto.\n\n\t* lib/net/pop.rb (POP3Command): change critical section protect\n\t  algorithm.\n\n\t* lib/net/pop.rb (POP3Command#auth): USER and PASS should be one\n\t  critical block.\n\n\t* lib/net/pop.rb (POP3Command#retr): ban `dest' argument using\n\t  iterator.\n\n\t* lib/net/pop.rb (POP3Command#top): ditto.\n\n\t* lib/net/protocol.rb: #read_message_to -> #each_message_chunk\n\n\t* lib/net/protocol.rb: #D -> #LOG\n\n\t* lib/net/protocol.rb: #D_off -> #LOG_off\n\n\t* lib/net/protocol.rb: #D_on -> #LOG_on\n\nWed Jul  2 11:10:47 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: set old class aliases for backward\n\t  compatibility. [ruby-talk:74863]\n\n\t* lib/net/protocol.rb: ditto.\n\nWed Jul  2 01:32:40 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/net/pop.rb (Net::POP3#start): typofix.\n\nTue Jul  1 22:08:19 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: TkWindow include TkWinfo\n\n\t* ext/tk/lib/tk.rb: treat unknown widget classes as subclasses\n\t  of TkWindow\n\nTue Jul  1 19:02:12 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* parse.y (rb_intern): should use mbclen instead of mblen.\n\nTue Jul  1 10:36:19 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* class.c (rb_define_class, rb_define_module): also set constant under\n\t  Object.  [ruby-dev:20445]\n\n\t* object.c (boot_defclass): ditto.\n\n\t* variable.c (rb_const_get_at, rb_const_get_0, rb_mod_const_at,\n\t  rb_const_defined, mod_av_set, rb_const_assign): toplevel constants\n\t  are now under Object, rb_class_tbl remains for GC.\n\nMon Jun 30 17:53:06 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (mnew): ignore metaclasses have no influence, for rklass.\n\t  [ruby-talk:74706]\n\nSun Jun 29 06:59:07 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb/drb.rb, lib/drb/invokemethod.rb: import drb-2.0.4\n\t  (use LocalJumpError#reason)\n\nSat Jun 28 12:28:54 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (rb_cv_stack_grow_dir): check stack growing direction.\n\n\t* eval.c (rb_thread_restore_context): prior configuration macro.\n\n\t* gc.c (ruby_stack_length): always return the address of lower edge.\n\n\t* gc.c (rb_gc_mark_locations): remove margin.  [ruby-dev:20462]\n\n\t* gc.c (rb_gc, Init_stack): prior configuration macro.\n\n\t* gc.c (Init_stack): add safety margin.\n\nFri Jun 27 14:41:22 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (rb_str_split_m): remove white spaces on the head of\n\t  the last element, when limit is specified.  [ruby-talk:74506]\n\nFri Jun 27 03:24:54 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (io_fflush): need to check if closed after thread switch.\n\t  [ruby-dev:20351]\n\n\t* io.c (fptr_finalize): ditto.\n\n\t* string.c (rb_str_rindex_m): fixed wrong fix.  should move backward\n\t  first only when matching from the end.\n\nThu Jun 26 21:34:49 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* class.c (class_instance_method_list): get rid of warning about\n\t  arguement type mismatch, and inline method_list().\n\t  [ruby-core:01198]\n\nWed Jun 25 14:40:33 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add and modify methods --- \n\t  TkWidget.database_class, TkWidget.database_classname, \n          TkWidget#database_class, TkWidget#database_classname \n\n\t* ext/tk/lib/tk.rb: instances of a subclass of TkToplevel or \n\t  TkFrame are created with \":class=>subclass\" option as default.\n\n\t* ext/tk/sample/tkoptdb.rb: add a new part\n\nWed Jun 25 12:52:58 2003  Matthew Dempsky  <jivera@flame.org>\n\n\t* class.c (rb_generic_class_instance_methods): merge argument\n\t  check (and warning) into one function; following DRY principle.\n\t  [ruby-core:01193]\n\nWed Jun 25 05:49:10 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: add widget destroy hook binding to TkBindTag::ALL\n\n\t* ext/tk/lib/tkcanvas.rb: Although requiring manual control of GC, \n\t  memory eating problem of TkCanvas Items is fixed.\n\n\t* ext/tk/lib/tktext.rb: add some methods and bug fix\n\nWed Jun 25 00:14:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (autoload_delete): should delete Qundef from iv_tbl.\n\t  (ruby-bugs-ja PR#504)\n\nTue Jun 24 16:46:07 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix on TkToplevel, TkFrame,\n\t  TkPanedwindow, TkOptionDB\n\n\t* ext/tk/lib/tk.rb: TkOptionDB --- make it more secure to use procs \n\t  defined on resourceDB\n\n\t* ext/tk/sample/tkoptdb.rb, resource.ja, resource.en: \n\t  sample script how to use TkOptionDB.\n\nTue Jun 24 14:22:41 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* lib/yaml/types.rb: replaced Kernel::Hash reference with Object::Hash\n\t  from [ruby-talk:74270]\n\nTue Jun 24 17:59:30 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_yield_0): show yielded block position not only yielding\n\t  point.  [ruby-dev:20441]\n\nTue Jun 24 16:47:07 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (HTTPHeader#proxy_basic_auth): missing `@'.\n\t  Thanks Douglas Koszerek. (ruby-bugs:PR975)\n\nTue Jun 24 14:31:17 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* config.guess: have wrongly returned \"alphaev56-unknown-linux-\"\n\t  on Linux/Alpha. [ruby-dev:20434]\n\nTue Jun 24 04:54:46 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* configure.in: always add -mieee for gcc/alpha. [ruby-dev:20429]\n\nTue Jun 24 02:40:09 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* array.c (rb_ary_unshift_m): need to check number of arguments.\n\t  [ruby-talk:74189]\n\nMon Jun 23 23:59:56 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* io.c (io_close): missing prototype. [ruby-dev:20422]\n\n\t* ext/socket/socket.c (bsock_do_not_rev_lookup_set): ditto.\n\n\t* ext/win32ole/win32ole.c (foletype_guid, foletype_progid): ditto.\n\n\t* error.c (syserr_initialize): length argument of sprintf() is an\n\t  int.\n\nMon Jun 23 23:28:14 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* MANIFEST: add wince files.\n\n\t* ext/tk/MANIFEST: add sample/tkmenubutton.rb.\n\nMon Jun 23 17:40:58 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dir.c (find_dirsep): get rid of warnings.\n\n\t* eval.c (error_print): temporary value might be disposed by GC.\n\n\t* hash.c (env_has_value, env_index): should not increment NULL.\n\n\t* io.c (io_read, rb_io_sysread): not read when length is 0.\n\n\t* io.c (rb_io_reopen): ensure initialized IO.\n\n\t* io.c (rb_io_init_copy): sychronize file pointer.\n\n\t* io.c (rb_io_s_pipe): make exception proof.\n\n\t* string.c (rb_str_rindex_m): Fixnum 0 matched end of string.\n\nMon Jun 23 16:18:12 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (rb_open_file): initialize flags.\n\n\t* time.c (time_arg): initialize v[6] even when argc is 10 to\n\t  avoid valgrind error.\n\nMon Jun 23 14:22:44 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix on TkRoot and TkToplevel\n\nMon Jun 23 08:24:01 2003  Florian Frank  <flori@nixe.ping.de>\n\n\t* string.c (rb_str_upto): generate sequence according to \"succ\"\n\t  order.  formerly check was done by dictionary order.\n\t  [ruby-talk:74138]\n\nMon Jun 23 00:27:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_string_value): fill constant empty string along\n\t  with setting ELTS_SHARED if str->ptr is NULL. [ruby-core:01179]\n\n\t* string.c (rb_string_value_ptr): ditto.\n\n\t* string.c (rb_check_string_type): ditto.\n\nSun Jun 22 23:42:20 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (str_gsub): move END(0) check before mbclen2().\n\n\t* string.c (scan_once): reduce END(0) check.\n\n\t* io.c (rb_io_initialize): accept fixnum mode.\n\n\t* eval.c (error_print): replace strchr() by memchr(), einfo may\n\t  contain \"\\0\".\n\n\t* pack.c (pack_unpack): range check for \"@\" move; initialize check\n\t  for \"m\".\n\n\t* error.c (syserr_initialize): avoid buffer overflow.\n\n\t* file.c (rb_file_s_readlink): expand buffer until readlink\n\t  succeed.\n\nSun Jun 22 16:17:02 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: TkRoot.new and TkToplevel.new accept Wm \n\t  commands as elements\n\n\t* ext/tk/lib/tk.rb: TkMenu --- add some methods\n\n\t* ext/tk/lib/tk.rb: TkOptionMenubutton --- bug fix\n\n\t* ext/tk/sample/tkmenubutton.rb: sample of TkMenubutton and \n\t  TkOptionMenubutton\n\nSat Jun 21 23:15:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): should not propagate distination tag if\n\t  tag is already handled in this level. (ruby-bugs-ja PR#501)\n\n\t* object.c (str_to_id): check for empty string before intern. \n\t  [ruby-talk:74006]\n\nSat Jun 21 13:56:09 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/Makefile.sub: undefine HAVE__SETJMP.\n\n\t* wince/resource.rb: include winver.h in wince3.0.\n\nSat Jun 21 12:55:17 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: TkRoot.new and TkToplevel.new accept Wm commands \n\t  as elements of a hash argument. \n\n\t* ext/tk/sample/tktimer2.rb: add comments about the usage of a \n\t  TkTimer object.\n\nSat Jun 21 08:47:22 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk*.rb: remove direct-accesses to TkComm::INTERP and\n\t  TkComm::INITIALIZE_TARGETS\n\n\t* ext/tk/lib/tk*.rb: use TkINTERP_SETUP_SCRIPTS constant for setting \n\t  up the interpreter\n\n\t* ext/tcltklib/tcltklib.c: support to create a safe interpreter \n\t  with safe-Tk\n\nFri Jun 20 23:28:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): should not propagate TAG_BREAK and\n\t  TAG_RETURN from orphan Proc object. [ruby-core:01148]\n\nFri Jun 20 15:04:28 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* defines.h (PATH_ENV): name of PATH environment. [new]. \n\n\t* defines.h (ENV_IGNORECASE): define for case insensitive platforms\n\t  to access environment variables.\n\n\t* dln.c (dln_find_exe): use PATH_ENV instead of \"PATH\".\n\n\t* hash.c (env_delete, rb_f_getenv, env_fetch, rb_env_path_tainted,\n\t  env_aset): ditto.\n\n\t* ruby.c (proc_options): ditto.\n\nFri Jun 20 14:52:46 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: Tk interpreter returns TAINTED strings.\n\nFri Jun 20 03:09:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (new_yield): distinguish \"yield 1,2\" and \"yield [1,2]\". \n\t  [ruby-dev:20360]\n\n\t* eval.c (rb_eval): support new_yield() change.\n\n\t* variable.c (rb_const_get_0): warn for Foo::BAR when BAR is a\n\t  toplevel constant (i.e. a constant defined under Object).\n\t  [ruby-list:36935]\n\n\t* parse.y (no_blockarg): separate no block argument check and\n\t  ret_args argument processing. \n\nFri Jun 20 00:45:19 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>\n\n\t* lib/csv.rb: import csv module.\n\nThu Jun 19 22:51:41 2003  Masatoshi SEKI  <m_seki@mva.biglobe.ne.jp>\n\n\t* lib/drb.rb, lib/drb/drb.rb, lib/drb/eq.rb, \n\t  lib/drb/extserv.rb, lib/drb/extservm.rb, lib/drb/gw.rb, \n\t  lib/drb/invokemethod.rb, lib/drb/observer.rb, \n\t  lib/drb/timeridconv.rb, lib/drb/unix.rb: import drb-2.0.4b3\n\nThu Jun 19 16:14:43 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_do_one_event): change default\n\t  value of the argument\n\n\t* ext/tcltklib/tcltklib.c (lib_do_one_event): returns true/false\n\n\t* ext/tcltklib/tcltklib.c: add TclTkLib::EventFlag::NONE ( == 0 )\n\n\t* ext/tcltklib/tcltklib.c: add set_no_event_wait() and \n\t  get_no_event_wait()\n\n\t* ext/tcltklib/MANUAL.euc: modify\n\n\t* ext/tcltklib/README.euc: ditto\n\n\t* ext/tk/lib/tk.rb: change default value of TkCore.do_one_event \n\t  argument\n\n\t* ext/tk/lib/tk.rb: add TkCore.set_no_event_wait(wait) and \n\t  TkCore.get_no_event_wait\n\n\t* ext/tk/lib/tk.rb: add Tk.exit ( == destroy root widget )\n\n\t* ext/tk/lib/tkafter.rb: rename TkAfter => TkTimer (TkAfter is\n\t  an alias name)\n\n\t* ext/tk/lib/tkafter.rb: set_callback returns self\n\n\t* ext/tk/lib/tkafter.rb: continue() raises an exception, if already \n\t  running or no procedure.\n\n\t* ext/tk/lib/tkafter.rb: skip() raises an exception, if not running.\n\n\t* ext/tk/sample/tktimer2.rb: new sample for TkTimer class.\n\nThu Jun 19 16:13:54 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* rubytest.rb: add library path to include standard libraries.\n\nThu Jun 19 13:13:10 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* hash.c (env_delete, rb_f_getenv, env_fetch): case insensitive to\n\t  access environment variables on DOSISH platforms.\n\nThu Jun 19 00:51:47 2003  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* range.c (rb_range_beg_len): out_of_range check after adjusting\n\t  end point. [ruby-dev:20370]\n\nWed Jun 18 23:59:11 2003  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* parse.y (call_args): the first argument to arg_cancat() should\n\t  be NODE_LIST. [ruby-core:01151]\n\nWed Jun 18 23:41:27 2003  Marc Cartright  <marc@isri.unlv.edu>\n\n\t* ext/zlib/zlib.c (zstream_run): In a particular situation,\n\t  deflate/inflate will return Z_BUF_ERROR, even though another call\n\t  is required by the zlib library.\n\nWed Jun 18 19:46:21 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb: bug fix\n\n\t* ext/tk/lib/tk.rb: rename 'no_create' option to 'without_creating'\n\n\t* ext/tk/lib/tk.rb: add TkWindow#pack_in, TkWindow#grid_in, \n\t  TkWindow#place_in\n\n\t* ext/tk/lib/tk.rb: add TkWindow#bind_class and TkWindow#database_class\n\n\t* ext/tk/lib/tk.rb: add TkBindTag.new_by_name and TkDatabaseClass \n\t  for binding to database class\n\n\t* ext/tk/lib/tk.rb: check varname whether already exsist or not. \n\t  (TkVarAccess.new)\n\n\t* ext/tk/lib/tk.rb: TkTextWin#bbox returns an array of four numbers\n\n\t* ext/tk/lib/tk.rb: autoload TkDialog2, TkWarning2\n\n\t* ext/tk/lib/tk.rb: scan event callback arguments and convert\n\t  to proper type\n\n\t* ext/tk/lib/tk.rb: TkBindTag.new accepts a block\n\n\t* ext/tk/lib/tk.rb: If given taglist, TkWindow#bindtags(taglist) \n\t  returns taglist\n\n\t* ext/tk/lib/tk.rb: add TkWindow#bindtags=(taglist)\n\n\t* ext/tk/lib/tk.rb: Tk.focue and Tk.focus_lastfor return nil \n\t  if there is no target widget.\n\n\t* ext/tk/lib/tk.rb: Tk::Wm.client returns the argument string \n\t  when setting name\n\n\t* ext/tk/lib/tk.rb: TkGrid.columnconfiginfo and rowconfiginfo \n\t  given a slot return a number.\n\n\t* ext/tk/lib/tk.rb: TkWindow.grid_columnconfiginfo and \n\t  grid_rowconfiginfo --- ditto\n\n\t* ext/tk/lib/tk.rb: rename and define alias :: TkOption ==> TkOptionDB\n\n\t* ext/tk/lib/tk.rb: define alias :: TkTimer ==> TkAfter\n\n\t* ext/tk/lib/tk.rb: some instance methods change from public to private\n\n\t* ext/tk/lib/tk.rb: some TkComm methods change to module functions\n\n\t* ext/tk/lib/tk.rb: add support for -displayof option to some \n\t  TkWinfo methods\n\n\t* ext/tk/lib/tk.rb: bind, bind_append and bind_remove --- \n\t  returns the target of event-binding\n\n\t* ext/tk/lib/tk.rb: add Tk8.4 features\n\n\t* ext/tk/lib/tk.rb: add TkPaneWindow\n\n\t* ext/tk/lib/tkdialog.rb: bug fix\n\n\t* ext/tk/lib/tkdialog.rb: some methods return self\n\n\t* ext/tk/lib/tkdialog.rb: add TkTextMark#+(mod) and TkTextMark#-(mod)\n\n\t* ext/tk/lib/tkdialog.rb: add some methods\n\n\t* ext/tk/lib/tkcanvas.rb: bug fix and some methods return self\n\n\t* ext/tk/lib/tkentry.rb: some methods return self\n\n\t* ext/tk/lib/tkentry.rb: TkEntry#bbox returns an array of four numbers\n\n\t* ext/tk/lib/tkentry.rb: scan validatecommand arguments and \n\t  convert to proper type\n\n\t* ext/tk/lib/tkbgerror.rb: support to define a error handler by user\n\n\t* ext/tcltklib/tcltklib.c: [ruby-talk:60759]\n\nWed Jun 18 13:50:06 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should dispatch based on ID type.\n\nWed Jun 18 12:53:42 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (rb_yield_0): should restore scope_vmode during yield.\n\t  [ruby-dev:20361]\n\nWed Jun 18 01:13:36 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c (rb_syck_load_handler): merge key implemented.\n\n\t* ext/syck/rubyext.c (transfer_find_i): removed use of String#=~ in favor\n\t    of Regexp#match.\n\n\t* lib/yaml.rb: YAML::try_implicit returns.\n\n\t* lib/yaml/rubytypes.rb: Regexps added for type matching.\n\n\t* lib/yaml/emitter.rb: fix String + nil error.\n\nTue Jun 17 17:01:08 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/gram.c: added grammar for certain empty sequence entries.\n\n\t* ext/syck/handler.c, ext/syck/syck.c, ext/syck/syck.h: track bad anchors.\n\n\t* ext/syck/token.c: added pause token, tag possible circular references.\n\n\t* lib/yaml/rubytypes.rb: parsing YMD time as Date instance.\n\n\t* ext/syck/rubyext.c: ditto. DomainType, PrivateType, BadAlias classes.\n\nTue Jun 17 21:28:27 2003  Ariff Abdullah <skywizard@time.net.my>\n\n\t* win32/win32.c (rb_w32_opendir): need to set errno. [ruby-talk:73761]\n\nMon Jun 16 19:01:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c: remove rb_cBlock.\n\nMon Jun 16 18:06:33 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* numeric.c (rb_fix2uint): renamed from rb_fix2int on IA64.\n\nMon Jun 16 17:02:57 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (proc_invoke): format the message for localjump_error().\n\nMon Jun 16 16:23:56 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/dl/dl.c (rb_dl_callback): use rb_block_proc() instead of\n\t  rb_block_new().\n\n\t* ext/win32ole/win32ole.c (ev_on_event): ditto.\n\nMon Jun 16 16:06:47 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_alloc): re-unification of Block and Proc.  Block\n\t  class is no longer available.\n\nMon Jun 16 14:43:14 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* bcc32/Makefile.sub: undefine HAVE_GETGROUPS.\n\nSat Jun 14 16:58:41 2003  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* regex.c (calculate_must_string): should handle option_set\n\t  properly. [ruby-talk:73481]\n\n\t* regex.c (re_compile_fastmap): a bug in flag manipulation.\n\t  [ruby-talk:73549]\n\nSat Jun 14 17:59:59 2003  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* eval.c (method_arity): should handle NODE_BMETHOD and\n\t  NODE_DMETHOD. [ruby-core:01138]\n\nFri Jun 13 09:24:39 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (storebinary): seek correctly. Thanks, William Webber.\n\n\t* lib/net/ftp.rb (putbinaryfile): rescue FTPPermError.\n\nThu Jun 12 22:13:13 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb : add 'no_create' option to widget\n\t  initialize method. \n\n\t* ext/tk/MANIFEST : forgot to commit when added tkmacpkg.rb\n\t  and tkwinpkg.rb\n\n\t* ext/tk/lib/README : ditto.\n\nThu Jun 12 21:14:11 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tk.rb : widget configure returns self (for method\n\t  call chain)\n\n\t* ext/tk/lib/tkmacpkg.rb : Mac resource (not new but not\n\t  included until now)\n\n\t* ext/tk/lib/tkwinpkg.rb : Win DDE and registry (not new but not \n\t  included until now)\n\nTue Jun 10 14:26:30 2003  why the lucky stiff  <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/token.c: preserve newlines prepended to a block.\n\n\t* ext/syck/implicit.c (syck_match_implicit): added !merge and !default.\n\n\t* lib/yaml/constants.rb: remove '\\z' escape.\n\n\t* lib/yaml/emitter.rb: ensure reset of @seq_map shortcut flag.\n\n\t* lib/yaml/encoding.rb: remove Unicode translation methods.\n\n\t* lib/yaml/rubytypes.rb: improved round-tripping of Strings.\n\t  [ruby-core:1134]\n\nTue Jun 10 01:07:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/irb.rb (IRB::Irb::eval_input): warn and exit if $SAFE >=3\n\t  after input evaluation.\n\n\t* lib/irb.rb (IRB::Irb::eval_input): untaint input string.  now\n\t  irb works for levels 1 and 2.\n\nMon Jun  9 19:02:33 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in: checks presence of grp.h and setgroups().\n\n\t* process.c (proc_getgroups, proc_setgroups): raise\n\t  NotImplementedError unless available.  [ruby-talk:73014]\n\nMon Jun  9 18:09:11 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: fixed 100% CPU problem of Tk.mainloop\n\nMon Jun  9 15:50:24 2003  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: renewal Tk.mainloop\n\nSun Jun  8 13:37:21 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/setup.mak: set SUBSYSTEM in each platform.\n\n\t* wince/stdlib.c: fix mblen() bug.\n\nSat Jun  7 22:22:03 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/syck/rubyext.c (syck_loader_transfer): should not use\n\t  rb_cProc directly, since type_proc may be Proc, Block, or\n\t  Method.\n\n\t* parse.y (value_expr0): class and module statements should not be\n\t  warned for \"void value expression\". [ruby-talk:72989]\n\nSat Jun  7 01:46:41 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (add_final): should determine type by respond_to?\n\n\t* gc.c (define_final): ditto.\n\n\t* io.c (rb_io_ctl): should not depend on respond_to?\n\n\t* range.c (range_step): rb_check_string_type().\n\nFri Jun  6 20:29:14 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (error_print): needs to be exception proof.\n\n\t* eval.c (error_handle, rb_longjmp): bails out when exception\n\t  reentered.  (ruby-bugs-ja:PR#487), [ruby-core:01119],\n\t  [ruby-core:01122]\n\n\t* eval.c (Init_Proc): pre-allocates critical error objects.\n\nFri Jun  6 20:29:14 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (cmd_brace_block, do_block, brace_block): initialize block\n\t  variables at the beginning of the block.  [ruby-talk:72521]\n\nFri Jun  6 18:49:11 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_setgroups): new functions.\n\nFri Jun  6 18:33:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (define_final): eliminate rb_f_lambda() call.\n\n\t* class.c (rb_scan_args): ditto.\n\n\t* signal.c (sig_trap): ditto.\n\n\t* hash.c (rb_hash_initialize): ditto.\n\n\t* variable.c (rb_f_trace_var): ditto.\n\n\t* ext/dl/dl.c (rb_dl_callback): ditto.\n\n\t* ext/win32ole/win32ole.c (ev_on_event): ditto.\n\nFri Jun  6 16:10:01 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: define Net::HTTPResponse#to_ary for backward\n\t  compatibility.  [ruby-talk:72927]\n\n\t* lib/net/protocol.rb: add warning.\n\nFri Jun  6 13:30:57 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_cleanup): $SAFE is turned off in the finalization.\n\t  Each END proc should preserve its own $SAFE level. [ruby-core:01119]\n\n\t* marshal.c (marshal_load): remove unused variable \"hash\".\n\t  [ruby-core:01120]\n\n\t* hash.c (env_str_new): freeze strings from ENV. [ruby-talk:72860]\n\n\t* array.c (rb_ary_first): optional argument to retrieve first n\n\t  elements.\n\n\t* array.c (rb_ary_last): optional argument to retrieve last n\n\t  elements.\n\nThu Jun  5 21:31:55 2003  Takaaki Uematsu <uema2x@jcom.home.ne.jp>\n\n\t* wince/stdlib.c: add mblen().\n\nThu Jun  5 18:33:46 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/curses/curses.c (window_s_allocate,curses_finalize):\n\t  avoid VC++ warnings.\n\nThu Jun  5 17:44:11 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c (syck_parser_mark): was a bit heavy on the GC.\n\n\t* lib/yaml.rb (YAML::transfer): added.\n\nThu Jun  5 16:11:50 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub, wince/Makefile.sub\n\t  (MISSING): link with missing/erf.c.\n\n\t* missing.h (erf, erfc): fix prototype.\n\n\t* missing/erf.c: new. [ruby-list:37753]\n\nThu Jun  5 15:09:06 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* math.c (math_erf,math_erfc): new function. [ruby-list:37753]\n\nThu Jun  5 14:49:43 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c: using GC nodes caused segfault. [ruby-core:1071]\n\nThu Jun  5 13:48:57 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/token.c: directives choked on a period.\n\n\t* ext/syck/gram.y: anchors work above a collection. [ruby-core:1071]\n\n\t* ext/syck/handler.c, ext/syck/syck.c: ensure a fresh strtable between\n\t  parser iterations.\n\nWed Jun  4 12:06:59 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_finalize): no longer need to turn off $DEBUG in the\n\t  finalizer. (ruby-bugs-ja PR#473)\n\nTue Jun  3 22:20:49 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call_super): should search superclass method based on\n\t  orig_func, not last_func.\n\nTue Jun  3 09:59:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call_super): inheritance line adjustment moved from\n\t  rb_call(). [ruby-core:01113]\n\n\t* eval.c (rb_eval): use rb_call_super() to follow DRY principle.\n\nMon Jun  2 02:20:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (push_values_at): Array#values_at should work with\n\t  ranges too.\n\n\t* range.c (rb_range_beg_len): length calculation was wrong.\n\n\t* eval.c (rb_call): should set T_ICLASS in the frame->last_class.\n\t  [ruby-core:01110]\n\nSun Jun  1 21:50:01 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: should not use def file, use ld with\n\t  --export-all-symbols option on Cygwin/MinGW.\n\n\t* defines.h: ditto.\n\n\t* cygwin/GNUmakefile.in: ditto.\n\n\t* ext/digest/defs.h: avoid warnings on Cygwin.\n\nSun Jun 01 13:33:49 2003 Takaaki Uematsu <uema2x@jcom.home.ne.jp>\n\n\t* wince/string_wce.c: add strpbrk() for hpcpro support.\n\n\t* wince/setup.mak: add hpcpro(CE2.11) & armv4t(CE.NET) support.\n\n\t* wince/resource.rb: ditto.\n\n\t* wince/Makefile.sub: ditto.\n\nSun Jun  1 10:38:28 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* variable.c (rb_autoload_load): autoloaded constants under a module\n\t  belong to the module.  [ruby-core:01094], [ruby-dev:20309]\n\nSat May 31 04:36:54 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (rb_intern): should handle multibyte name.\n\nFri May 30 23:18:01 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c (rb_syck_mktime): seconds calculated wrong.\n\n\t* ext/syck/gram.c: flexibility to anchors and transfer methods on\n\t  collections.\n\n\t* ext/syck/token.c: hex escapes.\n\n\t* lib/yaml/basenode.rb: YamlNode references changed to YAML::BaseNode.\n\nFri May 30 22:28:04 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* numeric.c (rb_num2uint, rb_fix2int): new function to convert\n\t  values over INT_MAX.  [ruby-core:01099]\n\n\t* ruby.h (NUM2UINT, FIX2INT): ditto.\n\nFri May 30 15:01:05 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/token.c: preserve any indentation past an explicit\n\t  indentation.\n\nFri May 30 14:55:44 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_Array): exclude Kernel#to_a instead of Object#to_a.\n\t (ruby-bugs-ja:PR#483)\n\n\t* lib/optparse.rb (OptionParser::Switch#parse_arg): not splat.\n\n\t* lib/optparse.rb (OptionParser::Switch#conv_arg): splat if no\n\t  conversion supplied.\n\n\t* lib/optparse.rb (OptionParser::Switch::PlacedArgument#parse):\n\t  override next switch after argument conversion.\n\nFri May 30 14:41:34 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/handler.c, ext/syck/syck.h: removed syck_fold_format().\n\n\t* ext/syck/gram.c: flexibility for aliases and anchors.\n\n\t* ext/syck/token.c: folding now handled in the tokenizer.\n\nFri May 30 06:21:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* variable.c (rb_autoload_load): should delete autoloaded\n\t  symbol itself before load.  [ruby-core:01097]\n\n\t* variable.c (rb_mod_remove_const): must not return Qundef.\n\nThu May 29 14:59:10 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (_CRTIMP): redefine _CRTIMP on MinGW.\n\n\t* configure.in: remove '-D__USE_CRTIMP' from XCFLAGS on MinGW.\n\n\t* win32/win32.c (NtMakeCmdVector): handle quotes only if not instring.\n\nThu May 29 09:11:01 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (ev_const_defined, ev_const_get), variable.c\n\t  (rb_const_get_at, rb_const_get, rb_mod_remove_const): use Qundef\n\t  as autoload marker.  [ruby-dev:18103], [ruby-dev:18184]\n\n\t* eval.c (rb_mod_autoload, rb_mod_autoload_p): new method;\n\t  Module#autoload, Module#autoload?.\n\n\t* variable.c (rb_autoload, rb_autoload_load, rb_autoload_p):\n\t  manage autoload constants per classes/modules.\n\n\t* variable.c (rb_const_defined_at, rb_const_defined): return false\n\t  for autoloading constants.\n\n\t* class.c (rb_define_class, rb_define_module), eval.c (rb_eval),\n\t  variable.c (rb_mod_const_at, rb_const_assign): removed autoload\n\t  stuff.\n\n\t* intern.h: prototypes; rb_autoload, rb_autoload_load,\n\t  rb_autoload_p.\n\n\t* lib/optparse.rb (OptionParser::Switch::PlacedArgument::parse):\n\t  do not treat unmatched argument as an option.\n\nWed May 28 08:44:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_syscall): type dispatch should be based on\n\t  rb_check_string_type(), not FIXNUM_P(), because values may be a\n\t  bignum.  [ruby-talk:72257]\n\nTue May 27 20:33:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c, util.c: removed duplicated includes/defines.\n\n\t* ext/socket/socket.c (sock_addrinfo): get rid of SEGV at NULL ptr\n\t  String.  increase buffer size for 64bit platforms.\n\nTue May 27 02:34:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): should pass the current klass value to\n\t  block_invoke, which may be called via \"super\". [ruby-core:01077]\n\n\t* eval.c (block_invoke): now takes 4th argument \"klass\".\n\n\t* eval.c (block_alloc): should propagate BLOCK_PROC to\n\t  ruby_block.\n\nMon May 26 23:51:38 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_object0): should not use \"yield\" method, use \"call\"\n\t  instead. (ruby-bugs-ja PR#476)\n\nMon May 26 21:39:46 2003  MoonWolf  <moonwolf@moonwolf.com>\n\n\t* lib/mkmf.rb, lib/optparse.rb, lib/tracer.rb: use Method#to_block\n\t  instead of deprecated Method#to_proc.  (ruby-bugs-ja:PR#477)\n\nMon May 26 21:21:20 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (OptionParser::Switch::parse,\n\t  OptionParser::order): use {Block,Proc}#call instead of deprecated\n\t  #yield.\n\nMon May 26 16:39:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (Init_Proc): Block/Proc separation. [huge change]\n\n\t* eval.c (block_arity): returns exact arity number for Procs out\n\t  of methods. also gives 1 for {|a|..}.\n\n\t* string.c (rb_str_match): revert use of String#index for\n\t  invocation like string =~ string.\n\n\t* eval.c (rb_Array): move Object#to_a exclusion hack from\n\t  splat_value().  need to be in eval.c for a while.\n\nSun May 25 23:48:21 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bignum.c (rb_quad_pack): should negate negative bignum.\n\t  (ruby-bugs-ja:PR#474)\n\nSun May 25 03:27:25 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: support LOGIN authentication, based on\n\t  the patch by Kazuhiko Izawa. [ruby-talk:78981]\n\nSat May 24 18:19:51 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/Makefile.sub: add eMbedded Visual C++ 4.0 support.\n\n\t* wince/resource.rb: ditto.\n\n\t* wince/setup.mak: ditto.\n\n\t* wince/configure.bat: ditto.\n\n\t* wince/mkexports.rb: delete japanese comments.\n\nFri May 23 18:34:05 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_longjmp): get rid of reentering while debug warning.\n\t  (ruby-bugs-ja:PR473)\n\nFri May 23 15:16:16 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* pack.c (pack_unpack): sign-extend if sizeof long is bigger than\n\t  32.  (ruby-bugs-ja:PR#472)\n\nFri May 23 14:19:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_finalize): turn off ruby_debug flag before calling\n\t  at_exit procs and finalizers. (ruby-bugs-ja:PR473)\n\n\t* ext/tcltklib/tcltklib.c (lib_mainloop_core): OK to block if\n\t  there's no other thread. (ruby-bugs:PR#861)\n\nThu May 22 18:07:46 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/token.c: single- and double-quoted root-level fix.\n\n\t* lib/yaml.rb (YAML::object_maker): can create object attributes (such as\n\t  found in Exception class)\n\n\t* lib/yaml/rubytypes.rb: roundtripping of Exception and subclasses.\n\nFri May 23 01:26:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_clone): defer copying freezing state after\n\t  calling initialize_copy().  [ruby-dev:20276]\n\nThu May 22 17:12:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (run_final): use rb_thread_critical instead of DEFER_INTS.\n\t  [ruby-dev:20272]\n\n\t* marshal.c: try to make ArgumentError and TypeError consistent.\n\t  [ruby-core:01068]\n\nThu May 22 15:46:37 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_define_alloc_func): need not to disable\n\t  rb_call_super() for allocation functions. [ruby-core:1065]\n\nThu May 22 06:21:33 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c (rb_syck_err_handler): raise ArgumentError on\n\t  malformed YAML.\n\n\t* lib/yaml/rubytypes.rb: String#to_yaml was missing space indicators at\n\t  the end of a line.\n\nThu May 22 05:43:24 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c (syck_parser_load): root-level false was returning\n\t  nil.\n\n\t* ext/syck/token.c: root-level transfer method bug.\n\n\t* ext/syck/gram.c: root-level empty gave a parse error.\n\n\t* lib/yaml/rubytypes.rb: Symbol#to_yaml generating method call error.\n\nThu May 22 02:46:38 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): splat NODE_RESTARY.  [ruby-dev:20268]\n\n\t* eval.c (rb_thread_fd_close): raise for writing threads.\n\t  [ruby-dev:20269]\n\n\t* io.c (rb_io_close, io_reopen): ditto.\n\n\t* io.c (io_reopen): keep stdio objects for stdin, stdout,\n\t  and stderr.  [ruby-dev:19442]\n\nThu May 22 01:11:15 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (strings, word_list): must create new instance always.\n\t  http://yowaken.dip.jp/tdiary/20030521.html#p02\n\n\t* parse.y (yylex): slight optimization.\n\nWed May 21 23:07:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_sys_fail): should not specify errno explicitly.\n\t  [ruby-dev:20264]\n\nWed May 21 20:51:47 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* Makefile.in, bcc32/Makefile.sub, win32/Makefile.sub,\n\t  wince/Makefile.sub: update dependencies.\n\nWed May 21 17:44:16 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (syserr_initialize): prohibit specifying errno for\n\t  subclasses of SystemCallError.  in addition, if initialize is\n\t  called for SystenCallError instance, its class be changed.\n\t  [ruby-dev:20257]\n\n\t* gc.c (run_final): to protect thread context switch, finalizers\n\t  are wrapped in DEFER_INTS/ENABLE_INTS.\n\nWed May 21 13:26:08 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb: get rid of warnings.\n\nTue May 20 18:59:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_save_context): prohibit rb_gc_force_recycle()\n\t  on thread saved ruby_dyna_vars. [ruby-dev:20236]\n\nTue May 20 17:39:15 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (init_copy): call initialize_copy at the end of copy\n\t  process.\n\nTue May 20 17:15:55 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* error.c (syserr_initialize): use Errno constants as default\n\t  errno for subclasses.  [ruby-dev:20241]\n\nTue May 20 15:26:25 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* st.h: define ST_DATA_T_DEFINED for portability.\n\n\t* ext/syck/syck.h: add typedef, st_data_t for Ruby 1.6.\n\n\t* ext/syck/syck.c (syck_st_free_nodes): return int.\n\n\t* ext/syck/syck.c (syck_add_sym): cast the data to st_data_t\n\t  to avoid error on bcc32.\n\n\t* ext/syck/syck.c (syck_lookup_sym): ditto.\n\n\t* ext/syck/syck.c (syck_free_parser): NULL is not integer.\n\nTue May 20 13:29:04 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (kill): set errno after calling raise().\n\nTue May 20 10:51:26 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_f_missing): create exception instance by ordinal\n\t  method.  [ruby-dev:20033]\n\n\t* error.c (rb_name_error, rb_sys_fail): ditto.\n\n\t* error.c (exc_to_s, exit_status, name_err_name,\n\t  nometh_err_args, syserr_errno, syserr_eqq): access\n\t  attributes.\n\n\t* error.c (name_err_initialize, nometh_err_initialize,\n\t  syserr_initialize): initialize attributes.\n\nTue May 20 10:26:56 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): give warning for multiple values for a\n\t  block parameter.\n\n\t* eval.c (rb_yield_values): a function to yield multiple values.\n\n\t* array.c (sort_1): use rb_yield_values.\n\n\t* enum.c (min_ii, max_ii): ditto.\n\n\t* hash.c (rb_hash_update_block_i, delete_if_i, select_i,\n\t  each_pair_i, env_each, env_reject_bang, env_select,\n\t  env_update_i): ditto.\n\n\t* struct.c (rb_struct_each_pair): ditto.\n\n\t* eval.c (top_include): should include module in the current self,\n\t  not ruby_top_self. [ruby-dev:20198]\n\n\t* eval.c (top_include): stop inclusion to ruby_wrapper; give\n\t  warning.\n\nMon May 19 18:54:30 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/token.c, ext/syck/implicit.c: expanded character set to\n\t  allow UTF-8, other Ruby encodings.\n\nMon May 19 16:47:00 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/syck.c, ext/syck/syck.h, ext/syck/token.c, ext/syck/gram.c:\n\t  count line numbers only if line pointer has increased.\n\nTue May 20 00:45:40 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (push_braces): do not push_braces() unless rbrace is found.\n\t  (ruby-bugs-ja:PR#469)\n\nTue May 20 00:09:41 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/pty/pty.c (pty_finalize_syswait): join (using Thread#value)\n\t  before detach pid. [ruby-talk:71519]\n\nMon May 19 23:02:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (PUSH_FRAME): save outer ruby_block. [ruby-list:37677],\n\t  [ruby-dev:20202]\n\n\t* eval.c (BEGIN_CALLARGS): restore outer block by using\n\t  ruby_block->outer.\n\n\t* eval.c (block_pass): do not alter block->prev, but block->outer.\n\n\t* array.c (get_inspect_tbl): warning on wrong condition.\n\nMon May 19 16:13:57 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* class.c: add #include \"version.h\".\n\n\t* hash.c: ditto.\n\n\t* string.c: ditto.\n\nMon May 19 15:33:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (localjump_xvalue): renamed exitstatus to exit_value\n\t  since it's not exit \"status\" after all.\n\n\t* eval.c (localjump_error): add reason to LocalJumpError.\n\n\t* compar.c (rb_cmpint): raise error via rb_cmperr(), if cmp value\n\t  is nil. now take new 2 arguments.\n\n\t* time.c (time_cmp): 2003-05-16 fix was incomplete.\n\t  (ruby-bugs-ja:PR#458)\n\nMon May 19 14:42:50 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_cmp): stupid comparison fixed.\n\n\t* io.c (Init_IO): ARGF.path added (alias to ARGF.filename).\n\t  [ruby-dev:20197]\n\nMon May 19 13:58:03 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (init_copy): rename copy_object as initialize_copy,\n\t  since it works as copy constructor.\n\n\t* eval.c (rb_add_method): initialize_copy should always be\n\t  private, like initialize.\n\nMon May 19 13:51:50 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* re.c (rb_reg_quote): \\n \\r \\f \\v quoting was wrong.\n\t  [ruby-dev:20203]\n\n\t* re.c (rb_reg_quote): rb_reg_quote(\" \") should be \"\\\\ \", not\n\t  \"\\\\s\".\n\nMon May 19 08:08:51 2003  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb: use warn() instead of $stderr.puts().\n\n\t* sample/cal.rb: ditto.\n\nSat May 17 12:02:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (get_inspect_tbl): check whether inspect_tbl value is a\n\t  valid array. (ruby-bugs-ja PR#65)\n\n\t* array.c (inspect_ensure,rb_protect_inspect,rb_inspecting_p):\n\t  use get_inspect_tbl().\n\nSat May 17 11:50:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_abort): call exit(1) if exception is raised.  This\n\t  patch was made by Nobuyoshi Nakada <nobu.nokada@softhome.net> on\n\t  2002-05-30.  (ruby-bugs-ja PR#236)\n\n\t* signal.c: disable Ruby's interrupt handler at the beginning.\n\t  (ruby-bugs-ja PR#236)\n\nSat May 17 02:17:42 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/rational.rb (Integer::denominator): fixed typo.\n\t  (ruby-bugs-ja:PR#466)\n\nSat May 17 00:18:11 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/socket/socket.c (ruby_connect): connect() after EINPROGRESS\n\t  returns EINVAL on some platforms, need to check true error\n\t  status.  [ruby-core:01037]\n\nSat May 17 00:21:51 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_class_allocate_instance): singleton class check\n\t  moved to rb_obj_alloc(). (ruby-bugs-ja PR#345)\n\nFri May 16 23:55:50 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_quote): should escape white space characters,\n\t  \\t, \\f, \\n, \\r. (ruby-bugs-ja PR#231)\n\nFri May 16 12:40:40 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): chain previous block to the pushing block.\n\t  [ruby-list:37677]\n\n\t* time.c (time_cmp): does not compare with numbers for\n\t  interchangeability. (ruby-bugs-ja:PR#458)\n\nThu May 15 21:55:54 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/gram.c: fixes to one-line documents and end of stream\n\t  documents.\n\n\t* ext/syck/syck.c, ext/syck/syck.h: add root_on_error to parser\n\t  struct, specifying the symbol to be returned on a parse error.\n\nThu May 15 18:44:31 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb (OpenURI::Redirect#initialize): call super to\n\t  initialize mesg.\n\n\t* lib/open-uri.rb (OpenURI::Meta#charset): call block to guess charset\n\t  if block is given and charset is not given.\n\nThu May 15 16:55:16 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_le): returns nil if two classes/modules are not\n\t  in class-superclass relationship.\n\n\t* object.c (rb_mod_cmp): uses new rb_mod_le() behavior.\n\nThu May 15 07:45:30 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/rubyext.c, ext/syck/implicit.c: timestamp repairs to\n\t  timezone and milliseconds.\n\n\t* ext/syck/syck.c (syck_parser_reset_levels): duplicate string literal\n\t  to avoid warning.\n\nThu May 15 13:26:48 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_class_instance_methods): default will be changed in\n\t  1.8.1.\n\n\t* io.c (set_stdio): better message.\n\nThu May 15 13:18:11 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (set_stdio): $stdin, $stdout, $stderr now became read-only.\n\n\t* variable.c (readonly_setter): message changed.\n\nThu May 15 09:50:51 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/syck/syck.c (syck_parser_pop_level): add prototype.\n\n\t* ext/syck/syck.c (syck_strndup): should return value.\n\nThu May 15 09:32:25 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (kill): fix typo and add signal 0 support.\n\nWed May 14 20:09:26 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/gram.c: sequence-in-map shortcut, transfer methods on\n\t  sequence-in-sequence, memory leak in mapping merge.\n\n\t* ext/syck/syck.c: memory leak in domain anchoring.\n\n\t* lib/yaml/rubytypes.rb, lib/yaml/types.rb: eliminated 1.6.x code.\n\nWed May 14 19:56:43 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/syck/rubyext.c: add prototypes to avoid VC++ warnings.\n\nWed May 14 12:23:46 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (Net::HTTP#start): should check whether HTTP\n\t  session is opened before finishing. (ruby-bugs-ja:PR#463)\n\nWed May 14 09:12:55 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: reduce warning. (ruby-bugs-ja:PR#462)\n\nTue May 13 22:31:04 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* lib/yaml/rubytypes.rb, lib/yaml/types.rb: using Object#object_id\n\t  rather than deprecated Object#id.\n\n\t* ext/syck/token.c: changed ASCII escapes to octal notation.\n\n\t* ext/Setup*: added entries for static linking of Syck extension.\n\nTue May 13 20:31:58 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: add '--Wl,--enable-auto-import' to DLDFLAGS\n\t  on Cygwin/MinGW.\n\n\t* configure.in: add '-D__USE_CRTIMP' to XCFLAGS on MinGW.\n\n\t* ext/syck/handler.c: add proper casts.\n\n\t* ext/syck/syck.c: ditto.\n\nTue May 13 17:58:08 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define\n\t  HAVE_FSYNC.\n\n\t* win32/win32.h (fsync): define as _commit().\n\nTue May 13 15:35:35 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match_exec): \\Z changed to be consistent with new $\n\t  (endbuf) behavior.\n\nTue May 13 14:48:07 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (error_pos): use $deferr for output instead of stderr\n\t  directly.\n\n\t* eval.c (error_print,error_handle,rb_longjmp,rb_thread_schedule):\n\t  ditto.\n\nTue May 13 06:34:19 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* lib/yaml/rubytypes.rb: object and struct loading\n\n\t* lib/yaml.rb: YAML::detect_implicit will discover typing for a Ruby\n\t  string\n\n\t* ext/syck/: Fixed portable comments, misuse of NULL and methods without\n\t  return VALUEs.\n\nMon May 12 18:08:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (Init_IO): new variable $deferr which is default output\n\t  port of error messages.\n\n\t* io.c (rb_warn_m): new method \"warn\". [new]\n\n\t* error.c (warn_print): use $deferr.\n\n\t* error.c (rb_bug): ditto.\n\n\t* error.c (err_append): ditto.\n\nSun May 11 13:50:12 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb: refine to_s test.\n\n\t* lib/pp.rb (PP::ObjectMixin#pretty_print): refine to_s handling.\n\nSun May 11 06:32:13 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/implicit.c, ext/syck/rubyext.c: transfer methods applied to\n\t  native loading\n\n\t* ext/syck/token.c: fix for transfer methods on same indentation as nested\n\t  mapping\n\n\t* lib/yaml/rubytypes.rb: all type names in lowercase\n\nSat May 10 19:55:18 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ext/syck/gram.c ext/syck/handler.c ext/syck/implicit.c\n\t  ext/syck/node.c ext/syck/rubyext.c ext/syck/syck.c\n\t  ext/syck/syck.h ext/syck/token.c: updated to Syck 0.27\n\n\t* lib/yaml/loader.rb: new YAML::Loader class\n\n\t* lib/yaml.rb: loading of type families leverages YAML::DefaultLoader\n\nSat May 10 19:00:08 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/string.c: file removed.\n\n\t* wince/stdlib.c: file added.\n\nSat May 10 16:17:02 2003  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (decode_utf7): new method.\n\n\t* lib/net/imap.rb (encode_utf7): new method.\n\nFri May  9 21:25:50 2003  why the lucky stiff <ruby-cvs@whytheluckystiff.net>\n\n\t* ruby/ext/syck, ruby/lib/yaml: Initial checkin of YAML substances.\n\nFri May  9 16:38:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_reopen): It should be possible to reopen closed IO.\n\t  [ruby-talk:70941]\n\n\t* io.c (rb_io_reopen): inherit original file mode unless specified.\n\nThu May  8 18:44:09 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc): check odd alignment stack on m68k machines.\n\nThu May  8 12:56:04 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* compar.c (rb_cmperr): raise comparison failure.\n\n\t* intern.h: prototype; rb_cmperr\n\n\t* numeric.c (flo_gt, flo_ge, flo_lt, flo_le, fix_gt, fix_ge,\n\t  fix_lt, fix_le): should fail unless the argument is comparable.\n\t  (ruby-bugs-ja:PR#456)\n\n\t* numeric.c (int_upto, int_downto): should fail unless the\n\t  argument is comparable.  (ruby-bugs-ja:PR#454)\n\nWed May  7 13:30:11 2003  Masahiro TANAKA  <masa@ir.isas.ac.jp>\n\n\t* numeric.c (num_step): better error treatment of float values.\n\nTue May  6 17:51:54 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb: rename method: POP3#mail_size -> n_mails\n\n\t* lib/net/pop.rb: rename method: POP3#bytes -> n_bytes\n\nTue May  6 17:21:01 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/bigdecimal/.cvsignore: new file.\n\n\t* ext/zlib/.cvsignore: new file.\n\nTue May  6 14:39:36 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_methods): list singleton methods if recur\n\t  argument is false;  list all methods otherwise.\n\nMon May  5 21:19:25 2003  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* ext/gdbm/gdbm.c (fgdbm_values_at): new method to replace\n\t  select(index..).\n\n\t* ext/sdbm/init.c (fsdbm_values_at): ditto.\n\n\t* ext/dbm/dbm.c (fdbm_values_at): ditto.\n\n\t* ext/dbm/dbm.c (DBM::VERSION): defined.\n\n\t* ext/gdbm/testgdbm.rb: replace select with values_at.\n\n\t* ext/sdbm/testsdbm.rb: ditto.\n\n\t* ext/dbm/testdbm.rb: ditto.\n\n\t* ext/dbm/testdbm.rb (setup): DBM.open(path, 0400) cause EACCESS\n\t  on Berkeley DB[234].\n\nMon May  5 22:57:07 2003  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* sample/cal.rb: use values_at instead of select.\n\n\t* sample/biorhythm.rb: ditto.\n\nMon May  5 18:59:45 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* sample/test.rb: substitute 'select' with 'values_at'.\n\n\t* lib/date.rb: ditto.\n\n\t* lib/parsedate.rb: ditto.\n\nMon May  5 00:46:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_values_at): new method to replace select(index..).\n\n\t* hash.c (rb_hash_values_at,env_values_at): ditto.\n\n\t* re.c (match_values_at): ditto.\n\n\t* struct.c (rb_struct_values_at): ditto.\n\n\t* re.c (match_select): add iterator behavior.\n\nSun May  4 19:08:53 2003  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date/format.rb: synchronized with date2 3.3.2.\n\nSun May  4 15:21:18 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: ESMTP -> SMTP transition wrongly fails.\n\nSun May  4 15:06:37 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb: APOP did not work.  [ruby-dev:20149]\n\nSat May  3 21:14:29 2003  Johan Holmberg  <holmberg@iar.se>\n\n\t* ext/curses/curses.c, ext/digest/sha2/sha2.c, ext/iconv/iconv.c,\n\t  ext/racc/cparse/cparse.c: include \"ruby.h\" at the top to shut up\n\t  \"_FILE_OFFSET_BITS redefined\" warning on Solaris.\n\nSat May  3 11:00:12 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_class_protected_instance_methods): now gives\n\t  warnings to show migration path.  The default will be reversed\n\t  on Jan 2004.\n\nSat May  3 00:58:53 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_methods): now accepts recurse parameter.\n\n\t* lib/delegate.rb (Delegator::initialize): instance_methods\n\t  etc. now recurse by default.  need to specify false.\n\nSat May  3 00:22:00 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: reintroduce Protocol.protocol_param.\n\n\t* lib/net/http.rb: ditto.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/smtp.rb: ditto.\n\nFri May  2 23:29:53 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: remove Protocol class.\n\n\t* lib/net/smtp.rb (SMTP): ditto.\n\n\t* lib/net/pop.rb (POP3): ditto.\n\n\t* lib/net/http.rb (HTTP): ditto.\n\n\t* lib/net/protocol.rb: remove Command class.\n\n\t* lib/net/smtp.rb (SMTPCommand): ditto.\n\n\t* lib/net/pop.rb (POP3Command): ditto.\n\n\t* lib/net/pop.rb: remove APOPCommand class.\n\n\t* lib/net/protocol.rb: remove Code class and its all subclasses.\n\n\t* lib/net/protocol.rb: remove Response class and its all\n\t  subclasses.\n\n\t* lib/net/pop.rb (POPMail): new method unique_id (alias uidl).\n\nFri May  2 18:17:37 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* compar.c (cmp_gt): raises ArgumentError when \"<=>\" give nil.\n\t  inspired by discussion on comp.lang.python.\n\nFri May  2 17:37:01 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi/session.rb (CGI::Session::initialize): updated to\n\t  support 2003-04-23 change in cgi.rb [ruby-core:1002]\n\nFri May  2 17:21:02 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (method_list): classify methods based on nearest\n\t  visibility. [ruby-dev:20127]\n\n\t* class.c (rb_class_instance_methods): recurse by default.  other\n\t  method listing methods as well.\n\nFri May  2 09:38:06 2003  Warren Brown  <wkb@airmail.net>\n\n\t* string.c (rb_str_ljust): now takes optional argument to specify\n\t  pad string. [ruby-talk:70482]\n\n\t* string.c (rb_str_rjust): ditto.\n\n\t* string.c (rb_str_center): ditto.\n\n\t* string.c (rb_str_justify): utility function.\n\nFri May  2 04:10:59 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_add_method): call singleton_method_added or\n\t  method_added for every method definition (after ruby_running).\n\t  [ruby-talk:70471]\n\n\t* array.c (rb_ary_reverse_bang): Array#reverse! should not return\n\t  nil even for arrays sized less than 2.\n\nThu May  1 23:18:01 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_eof): should not block after reading all argument\n\t  files. (ruby-bugs-ja PR#449)\n\nFri May  2 15:10:41 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: use hashes to pass options.\n\n\t* lib/fileutils.rb: new option mkdir(:mode), mkdir_p(:mode).\n\n\t* instruby.rb: follow fileutils.rb feature change.\n\nThu May  1 08:24:00 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match_exec): $ _always_ matches at the end of string.\n\nWed Apr 30 14:12:00 2003  wanowa.kimura@nifty.ne.jp (kimura wataru)\n\n\t* net/imap.rb: support THREAD extension.\n\nSun Apr 27 23:13:20 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (rb_str_to_i): disallow negative radix.\n\t  [ruby-dev:20087]\n\nSat Apr 26 23:34:42 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (open_args): warning message changed to \"don't put space\n\t  before argument parentheses\".\n\nSat Apr 26 14:25:00 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* wince/ : files removed.\n\t           (config, dll.mak, exe.mak, mswince-ruby17.def,\n\t            io.c, process.c, signal.c, string.c, time.c)\n\n\t* wince/ : files added.\n\t           (assert.c, Makefile.sub, mkexports.rb, io_wce.c,\n\t            process_wce.c, signal_wce.c, string_wce.c,\n\t            time_wce.c)\n\n\t* wince/configure.bat : like mswin32 style.\n\n\t* wince/direct.c : remove \"static\" at _currentdir.\n\n\t* wince/io.h : change definition.\n\n\t* wince/stdio.c : _fdopen -> fdopen.\n\n\t* wince/process.h : add _P_OVERLAY.\n\n\t* wince/time.h : change definition.\n\n\t* wince/wincemain.c : add wce_SetCurrentDir.\n\n\t* wince/wince.c : add wce_SetCurrentDir and wce_fopen.\n\t                  fix GetModuleFileNameA to return correct \"lpFileName\".\n\n\t* wince/wince.h : remove #ifdef.\n\n\t* wince/sys/utime.h, utime.c : rename _utime to utime.\n\n\t* wince/sys/stat.c : expand relative directory in stat.\n\nSat Apr 26 06:33:04 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_read): ARGF.read() should read all argument files.\n\nFri Apr 25 18:46:00 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* gc.c: STACK_LEVEL_MAX=65535 on mswince.\n\nFri Apr 25 18:40:07 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_read): read should not span two files. [ruby-dev:20073]\n\nFri Apr 25 18:19:03 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (splat_value): split splat_value() and avalue_splat().\n\n\t* io.c: there's no way to set non-IO value to current_file, thus\n\t  no need for argf_forward().\n\nFri Apr 25 02:03:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): Proc#yield should pass through retry and\n\t  break like keyword yield. [ruby-talk:70034]\n\n\t* eval.c (proc_invoke): orphan Proc now raises LocalJumpError for\n\t  break and retry again.\n\n\t* eval.c (rb_eval): ARGSCAT should splat the argument.\n\n\t* eval.c (splat_value): splat operation function.\n\nThu Apr 24 23:37:02 2003  Dave Thomas  <dave@thomases.com>\n\n\t* lib/matrix.rb (Matrix#minor):  Used Range#size, which no longer\n\t  exists.\n\n\t* lib/complex.rb (new!): Complex.new had been made private, but\n\t  Kernel#Complex called it. Re-exposed as new!.\n\n\t* lib/matrix.rb (Matrix.row_vector): Fix method name typo\n\nThu Apr 24 19:40:02 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb: add -Wl,--no-undefined to LDSHARED only\n\t  if GNU ld is 2.11 or later.\n\nWed Apr 23 14:05:40 2003  Dave Thomas <dave@pragprog.com>\n\n\t* lib/ipaddr.rb (include?): Support non-IPAddr parameters.\n\t  [ruby-core:00980]\n\nWed Apr 23 13:31:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI::QueryExtension::[]): always return Value\n\t  object.\n\nWed Apr 23 08:39:27 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/zlib/extconf.rb: bccwin32 is win32 too.\n\nTue Apr 22 20:58:00 2003  Takaaki Uematsu  <uema2x@jcom.home.ne.jp>\n\n\t* ruby.c: don't call VirtualQuery in ruby_init_loadpath()\n\t  on mswince.\n\nTue Apr 22 19:08:53 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (save_mantissa, load_mantissa): for interoperability\n\t  should count cut-down bit from topmost.\n\nTue Apr 22 09:20:40 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg_ambiguous): hopefully better message.\n\n\t* lib/cgi.rb (CGI::QueryExtension::initialize_query): to_ary\n\t  removed.\n\nTue Apr 22 06:06:22 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb (Resolv::DNS::Resource#hash): use XOR to accumulate\n\t  hash value.\n\n\t* lib/tsort.rb (TSort#each_strongly_connected_component): don't use\n\t  block argument.\n\t  (each_strongly_connected_component_from): ditto.\n\nMon Apr 21 21:59:48 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c: one more digit for decimal point.  [ruby-talk:69808]\n\nMon Apr 21 21:25:59 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* numeric.c (flo_is_finite_p): use finite() if available.\n\n\t* win32/win32.h (isinf, isnan): define as macro.\n\t  [ruby-win32:00533]\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub: no longer use\n\t  missing/isinf.c, missing/isnan.c.\n\nMon Apr 21 18:36:28 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bignum.c (rb_cstr_to_inum): unnecessarily long buffer was used\n\t  for radix 9.  [ruby-dev:20057]\n\nMon Apr 21 17:44:34 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (block_append, value_expr0, assign_in_cond,\n\t  warn_unless_e_option, warning_unless_e_option, range_op,\n\t  cond0): adjust line number in warning.\n\nMon Apr 21 00:47:42 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* sample/test.rb: avoid the MSVCRT *printf problem(float).\n\t  [ruby-dev:20037]\n\nMon Apr 21 00:11:15 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (w_float): append least mantissa bits to get rid\n\t  of roundoff problem.  [ruby-talk:69518]\n\n\t* marshal.c (r_object0): load least mantissa bits.\n\nSun Apr 20 23:24:25 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (NtInitialize): set the floating-point control word\n\t  on bcc32.\n\n\t* win32/win32.h, bcc32/Makefile.sub: use missing/isinf.c, should not\n\t  use _finite() because it returns 0 if NaN.\n\nSun Apr 20 03:09:30 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* parse.y (void_expr0): node might become NULL after calling\n\t  remove_begin().\n\nSat Apr 19 21:55:10 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Setup*: Add zlib and remove bogus and obsolete entries.\n\nSat Apr 19 14:47:07 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc): use rb_gc_mark_maybe() to mark registered C\n\t  addresses.  C variables may not hold valid reference to Ruby\n\t  objects. [ruby-core:00975]\n\nSat Apr 19 00:56:13 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (rb_struct_eql): should compare values with \"eql?\".\n\nFri Apr 18 23:29:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_check): <=> returns nil for invalid values;\n\t  should check.\n\nFri Apr 18 15:26:50 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* error.c (rb_raise): workaround for some implementations of\n\t  vsnprintf.\n\nFri Apr 18 02:23:42 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): should not set RE_OPTIMIZE_ANCHOR,\n\t  if anychar_repeat is enclosed by parentheses.\n\nFri Apr 18 01:49:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* util.c (ruby_strtod): improved conversion accuracy.\n\nThu Apr 17 14:39:23 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/dbm/dbm.c (each_pair): add prototype to avoid VC++ warnings.\n\n\t* ext/readline/readline.c (Init_readline): follow readline 4.2\n\t  prototype.\n\nThu Apr 17 14:22:36 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (cond0): warn only range literals whose both side are\n\t  literals.  [ruby-core:00964]\n\nThu Apr 17 11:10:59 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/readline/readline.c: add the defined operator for bcc32.\n\nWed Apr 16 00:14:06 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-special-char-p): should test at the\n\t  point if no argument.  fixed by Michael Scholz\n\t  <scholz-micha@gmx.de>.\n\nTue Apr 15 19:35:08 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: rm_r should raise Errno::ENOENT if file\n\t  does not exist ([ruby-core:958]).  Thanks Johan Holmberg.\n\nTue Apr 15 19:12:21 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* struct.c (rb_struct_hash): new methods Struct#hash, Struct#eql?.\n\t  (ruby-bugs:PR#758)\n\nTue Apr 15 16:05:11 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* numeric.c (rb_fix2str): buffer was insufficient.\n\t  (ruby-bugs-ja:PR#431)\n\nMon Apr 14 19:45:56 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (file_expand_path): root must follow buf when\n\t  reallocated.  [ruby-talk:69339], [ruby-dev:20025]\n\nMon Apr 14 03:22:33 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* rubyio.h (struct OpenFile): add noraise flag to finalizer.\n\n\t* io.c (Init_IO): define $/, $-0, and $\\ as string-only\n\t  variables.\n\n\t* string.c (rb_str_split_m): does not generate empty string if\n\t  the receiver is empty.\n\n\t* io.c (fptr_finalize): should raise error on EBADF for readable\n\t  IOs as well.\n\nMon Apr 14 15:54:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bignum.c (rb_cstr_to_inum, rb_big2str): allow 2-36 as radix.\n\n\t* numeric.c (rb_fix2str): ditto.\n\n\t* string.c (rb_str_to_i): ditto.\n\nSun Apr 13 03:20:31 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (try_func): remove COMMON_HEADERS at first for\n\t  performance.\n\nSat Apr 12 20:59:40 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-beginning-of-arg): substitute\n\t  ruby-backward-arg.\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): fixed wrong\n\t  indentation in brace block and parentheses.\n\n\t* misc/ruby-mode.el (ruby-forward-sexp, ruby-backward-sexp):\n\t  support special char literal, and negative arguments.\n\nSat Apr 12 17:52:47 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_stat): use rb_check_convert_type() to retrieve IO.\n\nFri Apr 11 19:00:14 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (rb_w32_stat): check arguments.  [ruby-dev:20007]\n\t  [ruby-win32:535]\n\nFri Apr 11 15:56:08 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* numeric.c (coerce_rescue): prevent inspected String from GC.\n\n\t* numeric.c (flo_eq, rb_dbl_cmp, flo_gt, flo_ge, flo_lt, flo_le,\n\t  flo_eql): correct NaN comparison.  (ruby-bugs:PR#744)\n\n\t* sample/test.rb: NaN comparison test.\n\nFri Apr 11 14:48:47 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_stat): dereference using StringValuePtr().\n\n\t* file.c (rb_file_s_stat): use rb_stat(). [ruby-dev:20007]\n\nFri Apr 11 10:51:08 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/benchmark.rb (Benchmark::bm): get rid of warning.\n\t  [ruby-talk:69124]\n\nFri Apr 11 02:41:35 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (set_stdin): assigned value must respond to \"read\" and\n\t  \"getc\".\n\n\t* io.c (set_outfile): assigned value must respond to \"write\".\n\t  (ruby-bugs-ja:PR#425)\n\nThu Apr 10 21:12:19 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb: Exception line was accidentaly removed.\n\t  [ruby-dev:19989]\n\nThu Apr 10 18:42:13 2003  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* array.c (rb_ary_times): added some checks for request size.\n\nThu Apr 10 03:22:38 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_name): always return empty string for\n\t  anonymous class/module.  (ruby-bugs-ja PR#424)\n\n\t* config.sub: stop forcing addition of -gnu to -linux.\n\n\t* variable.c (classname): refactoring.\n\n\t* variable.c (rb_class_path): __tmp__classpath__ handling moved\n\t  from classname().\n\nThu Apr 10 01:52:24 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_obj_is_method): indefinite return value.\n\nThu Apr 10 00:39:32 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* regex.c (re_compile_pattern): /[\\--\\-]/ was warned.  warn /]/.\n\n\t* mkconfig.rb: escape `]' in regexp.\n\nThu Apr 10 00:27:07 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* time.c (time_strftime): RSTRING(format)->ptr might become NULL.\n\nWed Apr  9 23:54:50 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_obj_remove_instance_variable): better message.\n\t  [ruby-talk:68987]\n\n\t* variable.c (rb_mod_remove_const): ditto.\n\n\t* object.c (rb_obj_ivar_get): ditto.\n\n\t* object.c (rb_obj_ivar_set): ditto.\n\n\t* parse.y (yylex): ditto.\n\nWed Apr  9 21:51:20 2003  Dave Thomas  <Dave@Thomases.com>\n\n\t* eval.c (rb_mod_define_method): Allow UnboundMethod as\n\t  parameter.\n\nWed Apr  9 18:30:58 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (top_include): include module to wrapper module if\n\t  wrapper is present. experimental.  [ruby-list:37539]\n\nWed Apr  9 17:24:21 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc_mark_children): introduce this function again; this\n\t  is required when stack was very tight. [ruby-talk:68916]\n\nWed Apr  9 15:49:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bigdivmod): small typo.\n\nWed Apr  9 15:35:04 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/readline/readline.c: include <unistd.h> only when\n\t  HAVE_UNISTD_H is defined.\n\nWed Apr  9 14:05:00 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (w_object): preserve extended module on struct.\n\t  (ruby-bugs-ja:PR#422)\n\nWed Apr  9 03:43:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (BIGZEROP): macro to determine if x is a bignum zero.\n\nTue Apr  8 11:49:31 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (Init_Proc): make Method and UnboundMethod independent.\n\t  They are like instance and its class. [ruby-core:00941]\n\n\t* parse.y (yylex): disallow global variables like \"$1ve\".\n\t  [ruby-core:00945]\n\n\t* marshal.c (marshal_dump): Marshal.dump(0, false) should cause an\n\t  error. (ruby-bugs-ja PR#421)\n\n\t* regex.c (re_compile_pattern): warn if '-' is the edge of\n\t  character range.\n\nMon Apr  7 15:49:09 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_s_unpack_sockaddr_in): remove struct\n\t  size check.  getnameinfo(3) can handle. [ruby-dev:19967]\n\nMon Apr  7 01:33:31 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_read): do not call rb_sys_fail() when required data\n\t  length is zero. (ruby-bugs-ja PR#420)\n\n\t* eval.c (umethod_proc): should raise TypeError, instead of\n\t  returning error causing Proc.  Following the principle of \"fail\n\t  early\".  [ruby-core:00927]\n\nSun Apr  6 18:29:21 2003  UENO Katsuhiro  <katsu@blue.sky.or.jp>\n\n\t* ext/zlib/zlib.c: the return value of GzipReader#getc must be\n\t  unsigned.\n\nSun Apr  6 00:35:37 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* sample/exyacc.rb: use Regexp in gsub!.\n\nSat Apr  5 23:41:28 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): small but serious typo.\n\nSat Apr  5 04:23:05 2003  Warren Brown  <wkb@airmail.net>\n\n\t* sprintf.c (rb_f_sprintf): was decrementing width even if there\n\t  is no sign character.\n\nSat Apr  5 01:41:28 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (backtrace): skip internal allocator frame.\n\t  (ruby-bugs-ja PR#416)\n\nFri Apr  4 10:53:22 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (assign): should prepare mrhs by svalue_to_mrhs().\n\nWed Apr  2 15:11:23 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* README.EXT, README.EXT.ja (3.3): clarified -1 as free for\n\t  Data_Wrap_Struct().  [ruby-dev:19881]\n\nMon Mar 31 11:11:36 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_missing): use \"inspect\" for T_OBJECT as well.\n\nMon Mar 31 10:50:48 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (env_reject_bang): untaint key string.\n\n\t* hash.c (env_delete_m): execute block only if deleting key does\n\t  not exist.\n\nSat Mar 29 17:54:46 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): do not call rb_str_buf_cat() with NULL ptr,\n\t  which causes SEGV; jump to grow instead. [ruby-dev:19944]\n\nSat Mar 29 15:19:48 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* instruby.rb, ext/extmk.rb, lib/benchmark.rb, lib/cgi.rb,\n\t  lib/debug.rb, lib/getoptlong.rb, lib/optparse.rb, lib/time.rb,\n\t  lib/date/format.rb, lib/irb/ruby-lex.rb lib/uri/common.rb: revert\n\t  escape for `-' in character class.\n\nSat Mar 29 09:48:35 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (avalue_to_svalue): use rb_check_array_type() again.\n\t  Clarify how \"to_ary\" and \"to_a\" work. [ruby-talk:68155]\n\n\t* eval.c (svalue_to_avalue): ditto.\n\n\t* eval.c (svalue_to_mrhs): ditto.\n\n\t* eval.c (rb_eval): unary splat to use to_a, but we need a hack to\n\t  exclude Object#to_a until it's removed.\n\n\t* object.c (rb_Array): check obj.respond_to?(\"to_a\").  Currently\n\t  all object respond_to \"to_a\", but Object#to_a will be removed.\n\n\t* range.c (Init_Range): undefine to_ary.\n\n\t* re.c (Init_Regexp): ditto.\n\nSat Mar 29 09:47:52 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* MANIFEST (ext/aix_mksym.rb): remove obsolete file.\n\nFri Mar 29 06:21:24 2003  UENO Katsuhiro  <katsu@blue.sky.or.jp>\n\n\t* ext/zlib: merge from rough.\n\nFri Mar 28 19:33:39 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* variable.c (rb_class_path): hold temporary class path in a\n\t  instance variable to get rid of GC.  [ruby-dev:19932]\n\n\t* variable.c (classname): remove temporary class path when exact\n\t  name found.\n\nFri Mar 28 18:29:23 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): do not warn if \"-\" is at the top\n\t  or last of character class.\n\nThu Mar 27 12:10:15 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* regex.c (re_compile_pattern): fix [:name:] handling.\n\t  /[\\[:digit:]]/ was treated as /[[:digit:]]/.\n\t  /[[:-@]/ was treated as /[\\[:\\-@]/.\n\t  /[%-[:digit:]]/ was treated as /[%-\\[:digit:]\\]/.\n\nThu Mar 27 03:26:40 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (rb_str_capitalize_bang): check length before upcase\n\t  first character.  (ruby-bugs:PR#697)\n\nWed Mar 26 20:25:10 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dln.c (dln_find_1): break if path list end, even for too long\n\t  path names.  (ruby-bugs-ja:PR#412)\n\nWed Mar 26 13:19:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (avalue_splat): new function to do unary * (splat)\n\t  operator.\n\n\t* eval.c (avalue_to_svalue,svalue_to_avalue,svalue_to_mrhs): do\n\t  not use implicit \"to_ary\" conversion.\n\n\t* ext/curses/curses.c (GetWINDOW,GetMOUSE): add taint check.\n\n\t* ext/curses/curses.c (curses_init_screen): ditto.\n\n\t* ext/curses/curses.c (window_initialize): ditto.\n\n\t* gc.c (os_each_obj): prohibit ObjectSpace#each_object in safe\n\t  mode ($SAFE >= 4).\n\nTue Mar 25 23:26:02 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* signal.c (trap): return \"DEFAULT\" and \"IGNORE\" respectively for\n\t  previous sighandler SIG_DFL and SIG_IGN. [ruby-talk:67860]\n\nTue Mar 25 12:24:15 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): call avalue_to_mrhs() to assign block\n\t  parameter |a|. [ruby-dev:19897]\n\n\t* ruby.c (ruby_set_argv): freeze argument strings.\n\nTue Mar 25 12:01:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_initialize): should check rb_secure(4).\n\n\t* dir.c (dir_s_getwd): should check rb_secure(4).\n\n\t* object.c (rb_obj_infect): function version of OBJ_INFECT().\n\n\t* eval.c (rb_secure_update): new function to check object update.\n\nTue Mar 25 10:18:05 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: should infect also return values of\n\t  #inspect.\n\n\t* ext/strscan/strscan.c: use snprintf() instead of sprintf().\n\nMon Mar 24 16:55:04 2003  Takaaki Tateishi <ttate@ttsky.net>\n\n\t* ext/dl/dl.c: added rb_secure(4). (Thanks to Minero Aoki)\n\n\t* ext/dl/sym.c: ditto.\n\n\t* ext/dl/ptr.c: ditto.\n\nMon Mar 24 00:09:02 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (block_append): warn unused literal.\n\nSun Mar 23 22:22:04 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/jcode.rb (tr!, delete!, szueeze!): add empty string checking.\n\nSun Mar 23 19:54:53 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): use free() if dfree is -1.\n\nSat Mar 22 15:50:29 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c (make_time_t): try search_time_t if mktime/timegm is failed.\n\nSat Mar 22 13:26:33 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/optparse.rb, lib/jcode.rb, ext/tk/lib/tk.rb: reorder character\n\t  class /[\\]\\[]/ to /[\\[\\]]/ for readability.\n\nSat Mar 22 12:44:15 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/date/format.rb, lib/uri/common.rb: escape `[', `]', `-' in\n\t  character class in regexp to avoid warning.\n\nSat Mar 22 07:39:32 2003  Ulf Betlehem  <flu@iki.fi>\n\n\t* io.c (rb_io_fread): may lose data on nonblocking read.\n\nFri Mar 21 23:40:41 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* regex.c (re_compile_pattern): fix previous change.\n\n\t* instruby.rb, ext/extmk.rb, ext/tk/lib/tk.rb, lib/benchmark.rb,\n\t  lib/cgi.rb, lib/debug.rb, lib/getoptlong.rb, lib/jcode.rb,\n\t  lib/optparse.rb, lib/time.rb, lib/date/format.rb,\n\t  lib/irb/ruby-lex.rb: escape `[', `]', `-' in character class in\n\t  regexp to avoid warning.\n\nFri Mar 21 23:23:45 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): give warning for unescaped square\n\t  brackets and minus in character class. [ruby-dev:19868]\n\nFri Mar 21 18:12:20 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (bmcall): missing type.\n\nFri Mar 21 01:29:35 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): copy sign bits only if value is\n\t  negative.\n\n\t* missing.h: include <stdarg.h> or <varargs.h> if HAVE_VSNPRINTF\n\t  is not defined.\n\nThu Mar 20 18:31:37 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (OptionParser#order!): follow recent change\n\t  of proc argument.\n\nThu Mar 20 16:12:53 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (flo_to_s): change format specifier to \"%.15g\" to\n\t  avoid unnecessary 9s (e.g. 99.59999999999999). (ruby-bugs-ja PR#406)\n\nThu Mar 20 16:03:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (stmt, primary): get rid of SEGV at empty or invalid\n\t  condition.  (ruby-bugs-ja:PR#410)\n\n\t* parse.y (cond_negative): negate condition node when NODE_NOT.\n\nThu Mar 20 10:45:29 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* eval.c (bmcall): add volatile to avoid GC problem.\n\nThu Mar 20 10:10:49 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (load_dyna): clear ruby_errinfo. (ruby-bugs-ja PR#409)\n\nWed Mar 19 23:05:30 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>\n\n\t* lib/tracer.rb (trace_func): save and recover Thread.critical state.\n\t  Fixed by Fukumoto Atsushi <fukumoto@imasy.or.jp> [ruby-dev:19830]\n\nWed Mar 19 02:55:46 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): make str empty if given. (ruby-bugs-ja PR#408)\n\n\t* io.c (io_read): ditto.\n\n\t* io.c (rb_io_sysread): ditto.\n\nTue Mar 18 18:24:03 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c: do not override min and max.\n\nSun Mar 16 12:29:55 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (object_address_group): use to_s instead of name\n\t  to get name of class.\n\nFri Mar 14 08:53:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (remove_sign_bits): octal left most digit for negative\n\t  numbers may be '3'. (ruby-bugs-ja PR#407)\n\n\t* sprintf.c (rb_f_sprintf): should prefix sign bits if bignum is\n\t  negative, using sign_bits().\n\nWed Mar 12 16:48:19 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (prep_stdio): set binmode only if the file descriptor\n\t  is not connected to a terminal on Cygwin.\n\nWed Mar 12 11:23:49 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (avalue_to_mrhs): split argument passing and assignment\n\t  conversion.\n\n\t* eval.c (svalue_to_mrhs): ditto.\n\n\t* eval.c (avalue_to_svalue): avalue_to_svalue([[1,2]]) should be\n\t  [[1,2]], not [1,2] to wrap-around.\n\nTue Mar 11 21:00:59 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: Digest string wrongly included '\\n' when user\n\t  name is too long (ruby-bugs-ja:PR#404).\n\nTue Mar 11 20:07:01 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: speeding up by avoiding extra flush.\n\t  (suggested by Brian Candler <B.Candler@pobox.com> [ruby-talk:66516])\n\nTue Mar 11 04:30:12 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (massign): remove unnecessary array unpacking; it should\n\t  be handled before massign() by svalue_to_mrhs().\n\n\t* eval.c (svalue_to_mrhs): '*a = v' value conversion to avalue\n\t  (i.e. [1] => [[1]], [1,2] => [1,2]).\n\n\t* eval.c (rb_eval): use svalue_to_mrhs.\n\n\t* eval.c (rb_yield_0): ditto.\n\n\t* eval.c (proc_invoke): break from \"Proc#yield\" is legal.\n\nMon Mar 10 23:19:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_find_file): need world writable directory check for\n\t  relative paths too.\n\nMon Mar 10 11:23:00 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_find_file): world writable directory check if\n\t  $SAFE >= 1 (was $SAFE >= 2).\n\nMon Mar 10 01:59:47 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb: do not dispatch LIST when a mailbox is empty.\n\n\t* lib/net/pop.rb: merge the 'STAT' patch from Frank S.Fejes\n\t  <frank@oopdreams.com>, with modifications (listed below).\n\n\t* lib/net/pop.rb: new method Net::POP#mail_size.\n\n\t* lib/net/pop.rb: new method Net::POP#bytes.\n\n\t* lib/net/pop.rb: new method Net::POPCommand#stat.\n\nSun Mar  9 19:30:25 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils.rb (mkdir, mkdir_p): revert.\n\n\t* instruby.rb (umask): umask 0022, not 0.\n\nSun Mar  9 17:09:40 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils.rb (mkdir, mkdir_p): set mode to 0755.\n\n\t* Makefile.in (fake.rb): set ALT_SEPARATOR to the default value.\n\nSat Mar  8 11:30:59 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (massign): fix a bug not to expand in assignment to sole\n\t  lhs.  [ruby-dev:19766]\n\nFri Mar  7 21:57:25 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (Kernel.pp): module function.\n\t  (MatchData#pretty_print): new method.\n\nFri Mar  7 20:27:19 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/tcltklib/extconf.rb (find_tcl, find_tk): return true if\n\t  non-versioned found.  [ruby-dev:19759]\n\nFri Mar  7 15:05:35 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb: add QDBM support.\n\nFri Mar  7 12:59:39 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (massign): deal with sole lhs, assign rest args from\n\t  converted array.  [ruby-dev:19751]\n\nFri Mar  7 03:31:36 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (dsym): :\"symbol string\" style should not contain `\\0'.\n\n\t* process.c (proc_detach): new method Process.detach(pid) which\n\t  create background watcher thread to issue waitpid. [new]\n\n\t* process.c (rb_detach_process): utility function to detach\n\t  process from C code.\n\n\t* ext/pty/pty.c (pty_finalize_syswait): terminate watcher thread,\n\t  and detach child process (by creating new idle waitpid watcher\n\t  thread).\n\n\t* ext/pty/pty.c (pty_syswait): may lost signal stopped child.\n\nFri Mar  7 00:30:33 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/Win32API/Win32API.c: no longer use inline-asms.\n\n\t* ext/Win32API/extconf.rb: no need to add gcc options.\n\nThu Mar  6 13:02:10 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (reswords): fix reswords list.\n\nWed Mar  5 12:13:21 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: better YACC support on HP-UX.\n\nWed Mar  5 05:55:20 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cat): remove ptr NULL check and MEMZERO(). ptr\n\t  must be non NULL.\n\nTue Mar  4 23:12:07 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in, bcc32/Makefile.sub, win32/Makefile.sub: define\n\t  RUBY_EXPORT to export symbols.\n\n\t* defines.h: use RUBY_EXTERN instead of EXTERN.\n\n\t* intern.h, re.h, ruby.h, rubysig.h: ditto.\n\n\t* win32/win32.h: remove EXTERN definition.\n\nTue Mar  4 17:54:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_aref): raise TypeError if index is a symbol.\n\t  [ruby-list:37217]\n\n\t* array.c (rb_ary_aset): ditto.\n\nTue Nov 13 14:39:11 2001  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* missing/strftime.c: HP-UX support.\n\nTue Mar  4 15:08:08 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: better HP-UX support.\n\n\t* missing/strftime.c: ditto.\n\nTue Mar  4 10:11:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_popen): do not call rb_io_close() directly, call\n\t  \"close\" method instead. [ruby-dev:19717]\n\n\t* io.c (rb_io_s_open): ditto.\n\n\t* hash.c (rb_any_hash): remove DEFER_INTS.  all do_hash() calls in\n\t  st.c are at the top of functions.  No reentrant problem.\n\nTue Mar  4 01:19:21 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dl/MANIFEST: Exclude .cvsignore. [found by: eban]\n\nTue Mar  4 01:17:08 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Win32API/MANIFEST: Belatedly add lib/win32/registry.rb.\n\t  [found by: eban]\n\nTue Mar  4 00:33:04 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* MANIFEST: Belatedly add Test::Unit files.  D'oh!\n\nSun Mar  2 09:51:47 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (w_nbyte): should output always via rb_io_write().\n\n\t* marshal.c (dump_ensure): ditto.\n\n\t* marshal.c (marshal_dump): should call \"binmode\" method, if it\n\t  responds to.\n\n\t* marshal.c (r_byte): should input always via \"getc\" method.\n\n\t* marshal.c (r_bytes0): should input always via \"read\" method.\n\n\t* marshal.c (marshal_load): need not to set up FILE* fp;\n\nMon Mar  3 11:29:04 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): parse 'lhs = a rescue b' as 'lhs=(a rescue b)'.\n\nMon Mar  3 02:53:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fread): should not clearerr() if there's no filled\n\t  buffer (i.e. rb_io_fread() returning zero).\n\nMon Mar  3 01:42:35 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-expr-beg): escaped char syntax.\n\n\t* misc/ruby-mode.el (ruby-parse-partial): ditto.\n\n\t* misc/ruby-mode.el (ruby-parse-partial): no deep indent for\n\t  block.\n\n\t* misc/ruby-mode.el (ruby-backward-arg): skip arguments backward.\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): too deep indentation.\n\nFri Feb 28 23:50:32 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (map_errno): map OS error to errno. [new]\n\n\t* win32/win32.c (pipe_exec, CreateChild, poll_child_status, waitpid,\n\t  kill, link, rb_w32_rename, unixtime_to_filetime, rb_w32_utime): use\n\t  map_errno() instead of using GetLastError() directly.\n\n\t* win32/win32.c (rb_w32_select, rb_w32_accept, rb_w32_bind,\n\t  rb_w32_connect, rb_w32_getpeername, rb_w32_getsockname,\n\t  rb_w32_getsockopt, rb_w32_ioctlsocket, rb_w32_listen, rb_w32_recv,\n\t  rb_w32_recvfrom, rb_w32_send, rb_w32_sendto, rb_w32_setsockopt,\n\t  rb_w32_shutdown, rb_w32_socket, rb_w32_gethostbyaddr,\n\t  rb_w32_gethostbyname, rb_w32_gethostname, rb_w32_getprotobyname,\n\t  rb_w32_getprotobynumber, rb_w32_getservbyname, rb_w32_getservbyport,\n\t  rb_w32_fclose, rb_w32_close): map winsock error to errno.\n\nFri Feb 28 22:54:10 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (flock): supports larger files, and maps error\n\t  code.\n\n\t* win32/win32.c (rb_w32_asynchronize): returns errno from child\n\t  thread.\n\n\t* win32/win32.c (rb_w32_fclose, rb_w32_close): ensures unlocked.\n\nWed Feb 26 17:38:16 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: replace Kernel.open as well.\n\nTue Feb 25 23:03:08 2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\n\t* lib/debug.rb (DEBUGGER__::Context#debug_command): bp filename must\n\t  be the basename of it.  [ruby-talk:65644]\n\nMon Feb 24 17:49:35 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (yycompile): zero clear ruby_eval_tree_begin if\n\t  compilation failed.\n\nMon Feb 24 08:06:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_new): need no MEMZERO().\n\nSun Feb 23 17:57:06 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils (fu_stream_blksize): wrong logical condition.\n\t  (and -> or).\n\nSat Feb 22 03:12:56 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_gt): use rb_num_coerce_cmp() instead of\n\t  rb_num_coerce_bin.\n\n\t* numeric.c (fix_ge, fix_lt, fix_le): ditto.\n\n\t* numeric.c (flo_gt, flo_ge, flo_lt, flo_le): ditto.\n\nSat Feb 22 02:45:20 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_create): may called from place higher than\n\t  rb_gc_stack_start.\n\n\t* gc.c (Init_stack): update rb_gc_stack_start if it is lower (or\n\t  higher if stack grows down) than the previous value.\n\nFri Feb 21 21:03:41 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: new method FileUtils#copy_stream.\n\n\t* lib/fileutils.rb: new method FileUtils#compare_file.\n\n\t* lib/fileutils.rb: new method FileUtils#compare_stream.\n\n\t* lib/fileutils.rb: new method FileUtils#rmtree (alias of rm_rf).\n\nFri Feb 21 17:19:27 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (rb_f_require): do not need to abort if a DLEXT file\n\t  is not found.\n\nFri Feb 21 13:39:25 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cmp_m): should use LONG2NUM().\n\nFri Feb 21 12:45:50 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cmp_m): two small bugs fixed.\n\nFri Feb 21 08:03:09 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc_mark): inline rb_gc_mark_children().\n\n\t* gc.c (gc_sweep): new tactics to increase malloc_limit mildly.\n\nFri Feb 21 05:16:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cmp_m): return nil if str2 does not respond to\n\t  both \"to_str\" and \"<=>\".\n\n\t* compar.c (cmp_gt): return nil if \"<=>\" returns nil (means\n\t  incomparable).\n\n\t* compar.c (cmp_ge, cmp_lt, cmp_le): ditto.\n\n\t* compar.c (cmp_between): use RTEST(), since cmp_lt and cmp_gt may\n\t  return nil.\n\nThu Feb 20 19:05:51 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): main thread swapped by fork() may\n\t  terminate rb_thread_start_0() successfully. call ruby_stop(0);\n\t  this change was suggested by Rudi Cilibrasi\n\t  <cilibrar@drachma.ugcs.caltech.edu>.\n\nThu Feb 20 18:44:51 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (file_expand_path): fix wrong behavior for root file.\n\t  expand_path(\"..\", \"//machine/share\") => \"//machine/share\"\n\t  expand_path(\"..\", \"c:/a\") => \"c:/\"\n\t  expand_path(\"..\", \"/a\") => \"/\"\n\nThu Feb 20 18:11:01 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (file_expand_path): should not upward beyond share name.\n\nThu Feb 20 15:45:33 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* missing.h (strtoul): fix prototype of strtoul.\n\nThu Feb 20 10:11:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (clhs): allow \"Foo::Bar = x\".\n\nThu Feb 20 04:07:06 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (primary): \"self[n]=x\" can be legal even when \"[]=\" is\n\t  private.  changes submitted in [ruby-talk:63982]\n\n\t* parse.y (aryset): ditto.\n\n\t* parse.y (attrset): \"self.foo=x\" can be legal even when \"foo=\"\n\t  is private.\n\n\t* eval.c (is_defined): private \"[]=\" and \"foo=\" support.\n\n\t* eval.c (rb_eval, assign): ditto.\n\nThu Feb 20 03:58:34 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): \"foo=\" should not always be public.\n\nThu Feb 20 01:23:59 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_restore_context): inhibit interrupts in\n\t  critical section while context switching.  [ruby-talk:64785]\n\nWed Feb 19 18:27:42 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* node.h (nd_cpath): nested class/module declaration.\n\t  [EXPERIMENTAL]\n\n\t* eval.c (rb_eval): ditto.\n\n\t* gc.c (rb_gc_mark_children): ditto.\n\n\t* parse.y (cpath): ditto.\n\nTue Feb 18 21:39:27 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): should not report uninitialized warning by\n\t  attribute reader method.\n\n\t* variable.c (rb_attr_get): new function to get instance variable\n\t  without uninitialized warning.\n\n\t* io.c (argf_to_io): should prefetch argv.\n\nTue Feb 18 00:13:50 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-comment-column): customize comment\n\t  column.  [new]\n\n\t* misc/ruby-mode.el (ruby-deep-indent-paren): deep indentation\n\t  parentheses.  [new]\n\n\t* misc/ruby-mode.el (ruby-expr-beg): fix for / after $?.\n\n\t* misc/ruby-mode.el (ruby-parse-partial, ruby-calculate-indent):\n\t  deep indentation support.\n\n\t* misc/ruby-mode.el (ruby-forward-sexp, ruby-backward-sexp):\n\t  move forward/backward across one balanced expression.  [new]\n\n\t* misc/ruby-mode.el (ruby-indent-exp): indent balanced\n\t  expression.  [new]\n\n\t* misc/ruby-mode.el (ruby-electric-brace): indent before\n\t  show matching parenthesis.  (contributed by NABEYA Kenichi)\n\nMon Feb 17 14:36:56 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (rb_w32_opendir, rb_w32_utime): need parens.\n\nMon Feb 17 14:13:25 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (link): implement with CreateHardLink().\n\n\t* win32/win32.c, win32/win32.h (rb_w32_utime): enable utime() to\n\t  directory if on NT. [new] (ruby-bugs-ja:PR#393)\n\nMon Feb 17 13:28:51 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (file_expand_path): strip last slash when path is\n\t  root.\n\nSun Feb 16 19:22:31 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (file_expand_path): buffer might be reallocated while\n\t  expanding default directory.\n\n\t* file.c (file_expand_path): default directory was being\n\t  ignored if path was full path with no drive letter, under\n\t  DOSISH.\n\nSun Feb 16 03:14:33 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (prep_stdio, Init_io): always set binmode on Cygwin.\n\nSat Feb 15 01:01:45 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (file_expand_path): fix surplus path separators while\n\t  expanding at root directory.  [ruby-dev:19572]\n\nFri Feb 14 14:25:24 2003  akira yamada  <akira@arika.org>\n\n\t* lib/uri/generic.rb, lib/uri/ldap.rb, lib/uri/mailto.ldap: all foo=()\n\t  returns arguments passed by caller.\n\n\t* lib/uri/generic.rb (Generic#to_str, Generic#to_s): removed to_str.\n\t  Suggested by Tanaka Akira <akr@m17n.org> at [ruby-dev:19475].\n\n\t* lib/uri/generic.rb (Generic#==): should not generate an URI object\n\t  from argument. Suggested by Tanaka Akira <akr@m17n.org> at\n\t  [ruby-dev:19475].\n\nThu Feb 13 11:54:50 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ruby.c (ruby_init_loadpath): ensures buffer terminated\n\t  before use strncpy().\n\n\t* ruby.c (proc_options): avoid SEGV at -S with no arguments.\n\t  script argument is in effect only when -e is not given.\n\t  (ruby-bugs-ja:PR#391)\n\nThu Feb 13 01:30:10 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_schedule): current thread may be dead when\n\t  deadlock.  (ruby-bugs:PR#588)\n\nThu Feb 13 00:28:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_step): step might be float 0 < x < 1.\n\n\t* eval.c (rb_thread_schedule): pause if no runnable thread when\n\t  there's only one thread.\n\nThu Feb 13 00:09:47 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (strrdirsep): ignore trailing directory separators.\n\n\t* file.c (rb_file_s_expand_path): File.expand_path(\".\",\"/\") should\n\t  return \"/\".  (ruby-bugs-ja:PR#389)\n\n\t* file.c (rb_file_s_basename): also ignore trailing directory\n\t  separators, in compliance with SUSv3.  (ruby-bugs-ja:PR#390)\n\n\t* file.c (rb_file_s_dirname, rb_file_s_extname): ditto.\n\n\t* file.c (rb_file_s_dirname): append \".\" if drive only.\n\n\t* file.c (rb_file_s_split): get rid of converting twice.\n\nMon Feb 10 20:55:15 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb (parse_args): add '-n' to $mflags BEFORE \"--\".\n\t  do not add DESTDIR if already included in $mflags.\n\nMon Feb 10 19:54:30 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (FileUtils#uptodate?): use mtime for\n\t  comparison.\n\nMon Feb 10 10:14:26 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_to_a): return value should be an Array if the\n\t  receiver is an instance of subclass of Array.\n\n\t* string.c (rb_str_to_s): return value should be a String if the\n\t  receiver is an instance of subclass of String.\n\nMon Feb 10 03:33:42 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (rb_file_sysopen): rb_file_sysopen_internal() needs four\n\t  arguments.\n\nSun Feb  9 15:16:04 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* intern.h (HAVE_RB_DEFINE_ALLOC_FUNC, RB_CVAR_SET_4ARGS):\n\t  define to 1.\n\n\t* ruby.h (NORETURN_STYLE_NEW): ditto.\n\nSun Feb  9 12:28:18 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (init_mkmf): add libdir to LIBPATH unless cross\n\t  compiling.\n\nSun Feb  9 08:34:45 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: 4xx raises Net::ProtoServerError, 5xx raises\n\t  Net::ProtoFatalError (for backward compatibility).\n\nSun Feb  9 07:07:26 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: new method FileUtils.pwd (really).\n\n\t* lib/fileutils.rb: FileUtils.pwd, cmp, identical?, uptodate? does\n\t  not accept any option.\n\nSat Feb  8 18:35:30 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-forward-string): fixed void variable\n\t  error.\n\nSat Feb  8 16:23:11 2003  NABEYA Kenichi  <kenichi@nabeya.com>\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords): method name can\n\t  be delimited by tab.\n\nSat Feb  8 03:57:32 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/irb/workspace.rb, lib/irb/ext/math-mode.rb,\n\t  lib/irb/ext/multi-irb.rb, lib/irb/lc/error.rb,\n\t  lib/irb/lc/help-message, lib/irb/lc/ja/error.rb,\n\t  lib/shell/command-processor.rb, lib/shell/error.rb,\n\t  lib/shell/filter.rb: Fix typos and grammos. [approved by: keiju]\n\nSat Feb  8 03:34:28 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* intern.h (HAVE_RB_DEFINE_ALLOC_FUNC): New boolean macro to make\n\t  it easier to write extensions that work with both ~1.6 and 1.8~.\n\n\t* intern.h (RB_CVAR_SET_4ARGS): Ditto.\n\n\t* ruby.h (NORETURN_STYLE_NEW): Ditto.\n\nSat Feb  8 00:47:24 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call): calls method_missing when superclass method\n\t  does not exist.\n\n\t* eval.c (rb_f_missing): now handles \"no super\" case.\n\n\t* object.c (rb_obj_ivar_get): Object#instance_variable_get: new\n\t  method to get instance variable value without eval(). [new]\n\n\t* object.c (rb_obj_ivar_set): Object#instance_variable_set: new\n\t  method to set instance variable value without eval(). [new]\n\nFri Feb  7 15:35:21 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* intern.h, re.c (rb_memsearch): returns long.\n\n\t* string.c (rb_str_index): should return offset position.\n\nFri Feb  7 15:30:15 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (proc_invoke): should propagate self to super\n\t  methods.  [ruby-dev:19510]\n\nThu Feb  6 19:04:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_initialize_m): should not preset \"kcode\" unless\n\t  encoding is explicitly specified.\n\nThu Feb  6 19:01:32 2003  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: new method FileUtils.pwd.\n\n\t* lib/fileutils.rb: default label is ''.\n\n\t* lib/fileutils.rb: using module_eval again, to avoid ruby's bug.\n\n\t* lib/fileutils.rb: fix wrong examples in rdoc.\n\nThu Feb  6 17:43:56 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/complex.rb (Complex#==): should not raise error by type\n\t  mismatch.\n\n\t* lib/rational.rb (Rational#==): ditto.\n\nThu Feb  6 11:44:40 2003  MoonWolf  <moonwolf@moonwolf.com>\n\n\t* re.c (rb_reg_initialize_m): 3rd argument was ignored.\n\nThu Feb  6 01:09:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_count): return 0 for empty string (was\n\t  returning nil).\n\nWed Feb  5 19:41:37 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: dispatch code restructured to make it openable\n\t  that has `open' method.\n\n\t* lib/open-uri.rb: Location: field may has a relative URI.\n\t  pointed out by erik eriksson <ee@opera.com>.\n\nWed Feb  5 17:11:02 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): no .<digit> float literal anymore.\n\nTue Feb  4 16:11:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_equal): a == b is true when b is non T_ARRAY\n\t  object, if b has \"to_ary\" and b == a.\n\n\t* hash.c (rb_hash_equal): a == b is true when b is non T_HASH\n\t  object, if b has \"to_hash\" and b == a.\n\n\t* string.c (rb_str_equal): a == b is true when b is non T_STRING\n\t  object, if b has \"to_str\" and b == a.\n\nMon Feb  3 23:46:48 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_getline): should not increment lineno at EOF.\n\nMon Feb  3 16:49:19 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (Init_Object): default Object#=== now calls \"==\"\n\t  internally.\n\n\t* re.c (rb_reg_initialize_m): should honor option status of\n\t  original regexp.\n\n\t* array.c (rb_ary_equal): ary2 should be T_ARRAY (no to_ary\n\t  conversion).\n\n\t* array.c (rb_ary_eql): ditto.\n\n\t* string.c (rb_str_equal): str2 should be T_STRING (no to_str\n\t  conversion).\n\nMon Feb  3 16:32:52 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* re.c (rb_memsearch): a little improvement.\n\nMon Feb  3 13:18:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_memsearch): algorithm body of String#index.\n\n\t* error.c (Init_Exception): \"to_str\" removed.\n\n\t* eval.c (eval): should not rely on Exception#to_str\n\n\t* eval.c (compile_error): ditto.\n\n\t* error.c (err_append): ditto.\n\nSat Feb  1 23:56:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_merge): Hash#merge, non destructive \"update\".\n\t  now there's also Hash#merge! which is an alias to \"update\".\n\nFri Jan 31 14:16:59 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_index): search using Karp-Rabin algorithm.\n\nFri Jan 31 12:45:11 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_obj_classname): new function.\n\n\t* string.c (rb_str_dup): should preserve original's class (but not\n\t  hidden singleton class).\n\n\t* string.c (rb_str_substr): ditto.\n\n\t* parse.y: backout EXPR_CMDARG removal.\n\nFri Jan 31 09:40:07 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (OptionParser::List::accept): default\n\t  pattern must not be nil.\n\n\t* lib/optparse.rb (OptionParser::make_switch): NoArgument doesn't\n\t  override other styles.\n\nThu Jan 30 16:46:43 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (OptionParser::Switch::PlacedArgument): added.\n\t  if the next argument doesn't start with '-', use it as the\n\t  value.\n\n\t* lib/optparse.rb (OptionParser::make_switch): fixed a bug of\n\t  pattern.\n\n\t* lib/optparse.rb (Array): no need to guard.\n\nThu Jan 30 08:27:19 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (rb_file_s_expand_path): removed a sludge.\n\nWed Jan 29 03:24:39 2003  Michal Rokos  <michal@rokos.homeip.net>\n\n\t* dir.c (glob_helper): memory leak fixed.\n\nTue Jan 28 04:45:03 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* instruby.rb (parse_args), ext/extmk.rb (parse_args): Prepend a\n\t  hyphen to the first argument of MAKEFLAGS only if appropriate.\n\t  Remove wrong comments.\n\nMon Jan 27 03:30:06 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* error.c (get_syserror): use snprintf() instead of sprintf(). pointed\n\t  out by knu.\n\nMon Jan 27 02:06:38 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* error.c (get_syserror): some Windows' errno have 5 digits. pointed\n\t  out by znz.\n\nSun Jan 26 19:23:10 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* instruby.rb ($mflags.set?): Check $make instead of $nmake, since\n\t  there is no such a variable.\n\n\t* instruby.rb ($mflags.set?), ext/extmk.rb ($mflags.set?): Return\n\t  false if unmatched.\n\nSun Jan 26 19:08:30 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/shellwords.rb: Embed rdoc style comments.\n\n\t* lib/shellwords.rb (shellwords): Use String#lstrip!.\n\n\t* lib/shellwords.rb (shellwords): Recognize an object that\n\t  responds to to_str() by using String.new().\n\nSun Jan 26 17:53:04 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* instruby.rb (parse_args), ext/extmk.rb (parse_args): Detect -n\n\t  and emulate a dry run.  Use 'make' in case no --make argument is\n\t  given.\n\nSun Jan 26 07:18:42 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* instruby.rb: re-define individual methods verbosely rather than\n\t  including FileUtils::Verbose, in order to suppress messages from\n\t  FileUtils#cmp.\n\n\t* instruby.rb (makedirs): make same directory only once even if\n\t  dryrun.\n\n\t* lib/fileutils.rb (FileUtils::Verbose, FileUtils::NoWrite):\n\t  re-define methods with define_method instead of module_eval.\n\nSun Jan 26 03:37:18 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* instruby.rb, ext/extmk.rb, Makefile.in, win32/Makefile.sub,\n\t  bcc32/Makefile.sub: Replace the complicated MFLAGS/MAKEFLAGS\n\t  parser with something plain and comprehensible.  This fixes a\n\t  bug where make flags were wrongly reordered and the resulted\n\t  command line often did not make sense especially when BSD make\n\t  is used with extra arguments given.  Tested with FreeBSD and\n\t  Linux by me and mswin32, bccwin32 and mingw by usa.\n\nFri Jan 24 18:15:33 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y: tMINUS should have lower precedence than tPOW.\n\nFri Jan 24 05:12:55 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-font-lock-syntactic-keywords): deal\n\t  with escaped $ and ? at the end of strings.  [ruby-talk:62297]\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords): added defined?.\n\nThu Jan 23 17:25:04 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): do not warn discarding already undefined\n\t  method.\n\n\t* lib/rational.rb: undef quo before replacing.\n\nThu Jan 23 15:49:57 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (arg): missing arguments.\n\nThu Jan 23 14:56:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/rational.rb: modified to support \"quo\".\n\n\t* numeric.c (num_quo): should return most exact quotient value,\n\t  i.e. float by default, rational if available.\n\n\t* numeric.c (num_div): \"div\" should return x.divmod(x)[0].\n\nThu Jan 23 13:24:18 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_arg): was accessing garbage argv value.\n\nThu Jan 23 06:37:01 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* instruby.rb: should not contain destdir in shebang line.\n\nWed Jan 22 23:19:57 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (pipe_exec): remove unnecessary SetStdHandle().\n\nWed Jan 22 20:20:59 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): syntaxify tPOW negative number hack.\n\n\t* parse.y (negate_lit): new function to negate literal numeric\n\t  values in compile time.\n\nWed Jan 22 15:36:54 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match_exec): charset info may be stored in MBC\n\t  region when $KCODE != NONE.\n\nWed Jan 22 14:22:53 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (set_syserr): should preserve duplicated error names.\n\nTue Jan 21 20:29:31 2003  Michal Rokos  <michal@rokos.homeip.net>\n\n\t* mkmf.rb: make possible to add files to clean and distclean targets\n\nTue Jan 21 18:05:25 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bcc32/Makefile.sub (LIBRUBY_A): link dmyext.\n\nTue Jan 21 16:59:18 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* instruby.rb: use real interpreter pathname at shebang line.\n\t  [ruby-dev:19370]\n\nTue Jan 21 16:22:32 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): put back old ** behavior for negative number\n\t  right operand.\n\nTue Jan 21 14:46:12 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb: Use Test::Unit.\n\n\t* lib/prettyprint.rb: Ditto\n\n\t* lib/time.rb: Ditto\n\n\t* lib/tsort.rb: Ditto\n\nTue Jan 21 04:15:50 2003  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb: Use redefined `to_s' as well as `inspect'.\n\t  Useless `pretty_print' methods removed.\n\t  (PP::ObjectMixin#pretty_print_inspect): new method.\n\nMon Jan 20 21:48:43 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in (MANTYPE): Detect if the system's nroff(1) groks\n\t  mdoc.  Provide a new option --with-mantype={doc|man} in case the\n\t  check does not work as expected.\n\n\t* Makefile.in (MANTYPE): Define MANTYPE and pass it to\n\t  instruby.rb.\n\n\t* instruby.rb: Convert mdoc manpages to man for systems which\n\t  nroff(1) does not grok mdoc.\n\nMon Jan 20 21:25:18 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/tempfile.rb (self.open): If a block is given, call it with\n\t  tempfile as an argument and automatically close the tempfile\n\t  when the block terminates.\n\nMon Jan 20 21:02:50 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* mdoc2man.rb: Properly put nested braces, parentheses and angles.\n\n\t* mdoc2man.rb: Add support for .An and .Aq/.Ao/.Ac.\n\n\t* mdoc2man.rb: Add support for .Dl.\n\n\t* mdoc2man.rb: Make .Pf macro actually work.\n\n\t* mdoc2man.rb: Properly handle .Os.\n\n\t* mdoc2man.rb: Correctly omit spaces around punctuation\n\t  characters.\n\nMon Jan 20 19:43:41 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* mdoc2man.rb: Make this work as a library.\n\nMon Jan 20 18:22:40 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_f_require): purge too many goto's.\n\nMon Jan 20 17:50:05 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* mdoc2man.rb (parse_macro): Understand .Ux.\n\nMon Jan 20 17:32:56 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* mdoc2man.rb: New file.  A mdoc to man converter ported from\n\t  Perl.\n\nMon Jan 20 15:40:15 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.1: Properly close .Bl with .El.\n\nMon Jan 20 04:14:17 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (egrep_cpp): use inspect to show options.\n\n\t* lib/mkmf.rb (dir_config): prior configured directories to\n\t  defaults.\n\n\t* lib/mkmf.rb (dir_config): extract first word to determine\n\t  make command type.\n\nMon Jan 20 02:15:53 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/aix_mksym.rb: no longer used.\n\nMon Jan 20 00:17:16 2003  Matt Armstrong  <matt@lickey.com>\n\n\t* file.c (eaccess): under windows, make eaccess() just call\n\t  access(). [ruby-core:716], [ruby-bugs:PR#556]\n\nSun Jan 19 23:08:18 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/shellwords.rb (shellwords): A backslash ('\\') in single\n\t  quotes should not be regarded as meta character.  This bug or\n\t  maybe feature was inherited from Perl's shellwords.pl.\n\nSun Jan 19 14:01:12 2003  UENO Katsuhiro  <unnie@blue.sky.or.jp>\n\n\t* regex.c (is_in_list): should work well with UTF-8.\n\n\t* regex.c (re_match_exec): ditto.\n\nSat Jan 18 14:53:49 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bignum.c (rb_cstr_to_inum): should not erase all 0s, but\n\t  squeeze into one.  [ruby-dev:19377]\n\nFri Jan 17 03:33:42 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* sprintf.c (rb_f_sprintf): Fix a bug caused by an uninitialized\n\t  variable v, that a bignum unexpectedly gets converted into a\n\t  string with its higher figures all filled with ./f/7/1,\n\t  depending on the base.  This bug seems to have been introduced\n\t  in rev.1.27.\n\n\t* sprintf.c (rb_f_sprintf): Use switch instead of a sequence of\n\t  else-if's.\n\nWed Jan 15 15:18:38 2003  moumar  <moumar@netcourrier.com>\n\n\t* configure.in (ARCHFILE): set even unless --enable-shared on\n\t  AIX.  [ruby-talk:61466]\n\n\t* marshal.c (math.h): should be included after ruby.h on AIX.\n\t  [ruby-talk:61366]\n\nTue Jan 14 21:47:56 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_f_require): do not search adding .rb/.so suffixes if\n\t  the suffix specified.  [ruby-dev:18702]\n\t  http://moonrock.jp/~don/d/200211.html#d08_t1\n\nTue Jan 14 18:36:41 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_all): now works without block.\n\n\t* enum.c (enum_any): ditto.\n\nTue Jan 14 01:21:32 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (next_argv): not always set binmode.\n\nMon Jan 13 20:45:19 2003  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* parse.y (list_append): avoid O(n) search using node->nd_next->nd_end.\n\n\t* parse.y (list_concat): ditto.\n\n\t* eval.c (rb_eval): NODE_ARRY nd_end adoption.\n\nMon Jan 13 02:22:11 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/dl/lib/dl/win32.rb: eliminate unnecessary \"A\" adding.\n\nSun Jan 12 16:07:17 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (next_argv): inherit binmode from $defout.\n\nSat Jan 11 22:50:47 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/dl/lib/dl/win32.rb: compatibility improvement.\n\nSat Jan 11 01:44:16 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (RUBY_CHECK_IO_NEED): added more tests.\n\n\t* io.c (rb_io_check_readable): seek after synchronized write.\n\nFri Jan 10 01:23:45 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-font-lock-syntactic-keywords): syntax\n\t  classes are not allowed inside character classes.\n\t  [ruby-talk:60996]\n\nThu Jan  9 23:28:01 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in: AC_MSG_FAILURE is a new macro in 2.54b or later.\n\nThu Jan  9 17:05:24 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (RUBY_CHECK_IO_NEED): check whether fseek() and\n\t  fflush() are needed.\n\n\t* io.c (flush_before_seek): flush write stream only.\n\n\t* io.c (rb_io_check_readable): seek instead of flush if the last\n\t  operation was write.\n\n\t* io.c (rb_io_check_writable): seek instead of flush if the last\n\t  operation was read.\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub: needs to seek between\n\t  R/W.\n\nThu Jan  9 16:31:51 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should not discard nested NODE_BLOCK.\n\nThu Jan  9 15:12:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (stmt): NODE_NOT elimination for if/unless/while/until node.\n\n\t* parse.y (primary): ditto.\n\nThu Jan  9 13:26:18 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* st.h, st.c: Back out the introduction of st_*_func_t.  Some\n\t  compilers complain about function type mismatch.\n\nThu Jan  9 02:10:44 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): reduce recursive rb_eval() call by using sort\n\t  of continuation passing style.\n\nWed Jan  8 17:10:32 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/Win32API/lib/win32/registry.rb: added. [new]\n\nWed Jan  8 15:54:05 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c: remove ruby_last_node and assignments seems to be\n\t  unnecessary\n\n\t* intern.h: debug does not run if ID_ALLOCATOR is zero.\n\nWed Jan  8 15:04:11 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_each): treat fixnums specially to boost.\n\n\t* numeric.c (num_step): remove rb_scan_args() for small speedup.\n\nTue Jan  7 17:56:08 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (svalue_to_avalue): should return converted array.\n\nTue Jan  7 07:48:01 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_f_local_variables): skip $_, $~ and flip states in\n\t  dynamic variables.  [ruby-core:00681]\n\nTue Jan  7 02:46:29 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (env_clear): new Hash compatible method.\n\n\t* hash.c (env_shift, env_invert, env_replace, env_update): ditto.\n\nMon Jan  6 23:36:29 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* st.h, st.c: Introduce new conventional typedef's, st_data_t,\n\t  st_compare_func_t, st_hash_func_t and st_each_func_t.\n\n\t* st.h, st.c: Do explicit function declarations and do not rely on\n\t  implicit declarations.\n\n\t* class.c, eval.c, gc.c, hash.c, marshal.c, parse.y, variable.c:\n\t  Add proper casts to avoid warnings.\n\nMon Jan  6 20:44:43 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* intern.h (rb_check_array_type): Declare rb_check_array_type().\n\n\t* ext/digest/md5/md5ossl.c: Include stdio.h for sprintf() and\n\t  string.h for memcmp().\n\n\t* ext/dl/ptr.c: Include ctype.h for isdigit().\n\nMon Jan  6 18:43:17 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* file.c: improve DOSISH drive letter support.\n\nMon Jan  6 18:31:45 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils.rb (ln): add ' -f' in the verbose message.\n\n\t* lib/fileutils.rb (cp_r): add 'p' in the verbose message.\n\nMon Jan  6 16:44:52 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_join): dispatch based on \"to_str\".\n\n\t* array.c (rb_ary_times, rb_ary_equal): ditto.\n\nMon Jan  6 13:26:35 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* process.c (proc_exec_v): follow to proc_spawn_v(). call do_aspawn()\n\t  on Win32.\n\n\t* process.c (rb_proc_exec): call do_spawn() on Win32.\n\n\t* win32/win32.c, win32/win32.h (do_spawn, do_aspawn): add mode flag.\n\n\t* process.c (proc_spawn_v, rb_f_system): follow above change.\n\nMon Jan  6 05:11:15 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/extmk.rb: make $0 normal variable.\n\nMon Jan  6 02:32:46 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* struct.c (make_struct): needs meta class.\n\nSun Jan  5 22:54:05 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/fileutils.rb (ln): `argv' is not a argument.\n\nSun Jan  5 17:44:37 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/extmk.rb (extmake): set $0 temporarily while loading\n\t  extconf.rb.\n\nSun Jan  5 14:46:46 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* instruby.rb: need paren in regexp(make -n install).\n\n\t* ext/extmk.rb (sysquote): do not need to quote on mswin/bccwin/mingw.\n\n\t* ext/extmk.rb ($mflags): uniq items and remove '-' and '--'.\n\t  move options to the lead.\n\n\t* lib/fileutils.rb (install): model on the real install\n\t  command(message).\n\nSun Jan  5 09:36:46 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ruby.c (ruby_init_loadpath): under Windows, get the module\n\t  path from an internal address instead of hard coded library\n\t  name.\n\n\t* cygwin/GNUmakefile.in, bcc32/Makefile.sub,\n\t  win32/Makefile.sub (CPPFLAGS): removed LIBRUBY_SO macro.\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub (config.h): no longer\n\t  depends on makefiles.\n\nSun Jan  5 04:17:05 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* gc.c (SET_STACK_END): Issue a FLUSH_REGISTER_WINDOWS here too.\n\t  This fixes make test on FreeBSD/sparc64.\n\nSun Jan  5 03:43:47 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* defines.h (FLUSH_REGISTER_WINDOWS): Make the flushw call an\n\t  inline function so it can be used as an expression.\n\n\t* eval.c (EXEC_TAG, THREAD_SAVE_CONTEXT): Consistently call\n\t  FLUSH_REGISTER_WINDOWS before calling setjmp(). (I suspect that\n\t  every setjmp() implementation should take care of register\n\t  windows, though)\n\nSun Jan  5 03:12:32 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* file.c (utimbuf): use utimbuf instead of _utimbuf if defined _WIN32.\n\n\t* win32/Makefile.sub (LIBS): use oldnames.lib.\n\n\t* win32/win32.c (rb_w32_getcwd): follow above change.\n\n\t* win32/win32.h: ditto.\n\n\t* wince/direct.c, wince/direct.h (getcwd): ditto.\n\n\t* wince/io.h: ditto.\n\n\t* wince/string.c, wince/wince.h (stricmp, strnicmp): ditto.\n\nSat Jan  4 15:18:50 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* process.c (rb_proc_exec): use same logic as DJGPP on win32 ports.\n\n\t* process.c (rb_f_system): ditto.\n\n\t* win32/win32.c, win32/win32.h (do_aspawn): [new]. for arrayed\n\t  arguments.\n\n\t* win32/win32.c (CreateChild): add new argument for real filename of\n\t  executing process.\n\n\t* win32/win32.c (NtHasRedirection, pipe_exec): follow above change.\n\nSat Jan  4 14:29:52 2003  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* configure.in: set rb_cv_need_io_flush_between_seek=yes.\n\n\t* win32/Makefile.sub (config.h): define NEED_IO_FLUSH_BETWEE_SEEK.\n\t  (pointed out by moriq [ruby-dev:19299])\n\nSat Jan  4 03:12:14 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (umethod_bind): exact class match is not required.  relax\n\t  the restriction to subclasses.\n\nSat Jan  4 01:33:40 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (rb_file_s_lchmod): get rid of gcc-3 -O3 warning.\n\nFri Jan  3 22:26:07 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* process.c (rb_proc_times): need to initialize first.\n\nFri Jan  3 01:10:17 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): call \"inherited\" before executing class body.\n\n\t* class.c (rb_define_class): call \"inherited\" after defining the\n\t  constant.\n\n\t* class.c (rb_define_class_under): ditto.\n\nThu Jan  2 19:37:30 2003  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (massign): expand first element if RHS is an array and\n\t  its size is 1, and LHS has concrete assignment target (i.e. LHS\n\t  has target(s) other than *var).\n\n\t* eval.c (massign): avoid unnecessary avalue/svalue conversion.\n\n\t* eval.c (rb_yield_0): ditto\n\n\t* array.c (rb_ary_update): do not allocate unused array if rpl is\n\t  nil (i.e. merely removing elements).\n\nThu Jan  2 13:55:08 2003  Mathieu Bouchard  <matju@sympatico.ca>\n\n\t* io.c (io_read): should resize supplied string if it's shorter\n\t  than expected.\n\nThu Jan  2 11:01:20 2003  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (bmcall): arguments should be an array.\n\nWed Jan  1 18:18:45 2003  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: better DJGPP support. add GNUmakefile.\n\n\t* djgpp/GNUmakefile: new.\n\nWed Jan  1 04:16:18 2003  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* node.h (struct RNode): Change argc from int to long.  Otherwise\n\t  NEW_CFUNC() sets argc to a wrong value on platforms where\n\t  sizeof(int) != sizeof(long) and the byte order is big-endian.\n\t  This fixes breakage on FreeBSD/sparc64.\n\nTue Dec 31 23:22:50 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (massign): removed awkward conversion between yvalue,\n\t  mvalue, etc.\n\n\t* eval.c (rb_yield_0): new parameter added to tell whether val is\n\t  an array value or not.\n\n\t* parse.y (yield_args): restructuring: new nodes: NODE_RESTARY2,\n\t  NODE_SVALUE; removed node: NODE_RESTARGS.\n\nTue Dec 31 21:13:51 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* Makefile.in, {win32,bcc32}/Makefile.sub: add new target:\n\t  what-where, no-install.\n\n\t* mkconfig.rb: add const: CROSS_COMPILING.\n\n\t* ext/extmk.rb: no-install support.  add MAKEDIRS macro.\n\n\t* lib/mkmf.rb: add !ifdef .. !endif for Borland make.\n\n\t* process.c: improve DJGPP support.  system \"ls\", \"-l\".\n\nTue Dec 31 20:16:37 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/socket/addrinfo.h (NI_MAXHOST): Define NI_MAXHOST and\n\t  NI_MAXSERV only if they are not defined yet.  This fixes build\n\t  on such platforms as OpenBSD.\n\nTue Dec 31 20:07:49 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/tcltklib/extconf.rb (find_tcl, find_tk): Look for both\n\t  lib{tcl,tk}M.N and lib{tcl,tk}MN on all platforms.  *BSD have\n\t  Tcl/Tk libraries named this way.\n\nTue Dec 31 19:48:21 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in: Improve OpenBSD support. [obtained from: OpenBSD\n\t  ports]\n\n\t* dln.c (FUNCNAME_PATTERN): Ditto.\n\nTue Dec 31 19:21:02 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* array.c (rb_ary_transpose): Properly declare ary as a VALUE.\n\n\t* file.c (rb_file_s_chmod): Do not directly cast an int to void *\n\t  to avoid a warning.\n\n\t* defines.h (FLUSH_REGISTER_WINDOWS): Add support for\n\t  FreeBSD/sparc64.  miniruby still coredumps in a different place,\n\t  though.\n\nTue Dec 31 07:47:15 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (parse_string): readjusted.\n\n\t* parse.y (heredoc_identifier): readjusted.\n\n\t* parse.y (here_document): make EOL codes of single-quoted\n\t  here-documents consistent.\n\n\t* parse.y (yylex): reduced unnecessary conditionals.\n\nTue Dec 31 04:49:51 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.1: mdoc'ify.\n\nTue Dec 31 01:30:29 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* parse.y (yylex): do not accept \" __END__\\n\".  ([ruby-dev:19245])\n\nMon Dec 30 21:10:59 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* parse.y (yylex): use strncmp instead of strcmp.\n\t  accept \"__END__\\r\\n\".  ([ruby-dev:19241])\n\nMon Dec 30 20:32:14 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc_mark_frame): should mark frame->node.\n\nMon Dec 30 19:10:30 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/extmk.rb: split --make argument contains options, assume\n\t  the first word of --make-flags is always options even unless\n\t  preceded by -, and ignore letter-case of options if nmake.\n\n\t* instruby.rb: extract -n option also from --make and\n\t  --make-flags.\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub: not prepend - to\n\t  $(MFLAGS)\n\nMon Dec 30 16:44:14 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (rb_str_substr): should share the shared string if\n\t  present, instead of the original string.  (ruby-bugs:PR#528)\n\nMon Dec 30 05:10:00 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/socket/socket.c (tcp_svr_init): local host to\n\t  init_inetsock() is VALUE but not pointer.\n\n\t* ext/socket/socket.c (sock_s_unpack_sockaddr_in): get rid of\n\t  gcc-3 -O3 warning.\n\nSun Dec 29 23:45:53 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* gc.c (gc_sweep): adjust GC trigger.\n\n\t* dln.c (init_funcname_len): get rid of gcc-3 -O3 warning.\n\n\t* eval.c (copy_node_scope): ditto.\n\n\t* hash.c (rb_hash_foreach, delete_if_i, select_i, each_value_i,\n\t  each_key_i, each_pair_i, envix): ditto.\n\n\t* range.c (range_each_func): ditto.\n\n\t* file.c (rb_file_s_chmod): ditto.\n\nSun Dec 29 15:30:37 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_parseargs): should not inherit ftools.rb's\n\t  misfeature.\n\nSun Dec 29 05:08:13 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* lib/fileutils.rb (cmp): return false if file size differs.\n\nSat Dec 28 19:21:24 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* instruby.rb: remove junk args.\n\n\t* lib/mkmf.rb (create_makefile): remove a trouble library\n\t  before making a shared library.\n\n\t* win32/Makefile.sub: invoke instruby.rb with the --make-flags option.\n\nSat Dec 28 03:09:58 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI#[]): improvement. thanks to Kazuhiro NISHIYAMA\n\t  <zn@mbf.nifty.com>\n\nSat Dec 28 00:34:03 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* {win32,bcc32}/Makefile.sub: remove `=' from --make-flags options.\n\t  nmake quotes args if included `=' in args.\n\n\t* instruby.rb: use getopts.rb.\n\n\t* ext/dbm/extconf.rb (-DDBM_HDR): substitute ' with \" to avoid\n\t  a error on Win32.\n\n\t* ext/gdbm/gdbm.c: add prototypes to avoid VC++ warnings.\n\nFri Dec 27 21:41:57 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bcc32/setup.mak, win32/setup.mak(-prologue-): move srcdir from\n\t  CPP input or UNC path will be removed as a comment.\n\nFri Dec 27 17:55:00 2002  Takaaki Uematsu  <mail@uema2.cjb.net>\n\n\t* wince/config, wince/configure.bat: replace 1.7 with 1.8\n\t  in macros.\n\nFri Dec 27 13:28:14 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* instruby.rb: fileutils.rb accepts only one argument.\n\nFri Dec 27 13:23:29 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb (fu_parseargs): reject illegal options\n\t  correctly.\n\n\t* lib/fileutils.rb (uptodate?): parameter declaration was wrong.\n\n\t* lib/fileutils.rb: change coding styles.\n\nFri Dec 27 09:25:22 2002  ABE Shigeru  <shiger-a@nifty.com>\n\n\t* process.c (rb_proc_times): avoid WindowsXP crash using volatile\n\t  variables.\n\nFri Dec 27 02:56:58 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* instruby.rb: check only `-' option, and use fileutils instead of\n\t  ftools.\n\nFri Dec 27 02:45:17 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/net/telnet.rb: Telnet#print not add \"\\n\".\n\n\t* lib/cgi.rb: cgi['key'] is equal cgi['key'][0]\n\nThu Dec 26 22:33:18 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb (create_makefile): check only `-' option.\n\n\t* configure.in: cleanups for MinGW. remove -D__NO_ISOCEXT in $CFLAGS.\n\n\t* win32/win32.h: prototypes for isinf, isnan are not needed on MinGW.\n\nThu Dec 26 19:22:00 2002  YOSHIDA Kazuhiro <moriq@moriq.com>\n\n\t* win32/setup.mak (-prologue-): moved srcdir macro definition.\n\t  [ruby-win32:420].\n\nWed Dec 25 18:26:44 2002  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* regex.c (re_match): fixed wrong \\G behavior.  (ruby-bugs-ja:PR#377)\n\nWed Dec 25 16:41:16 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match_exec): fix odd \\G behavior based on the patch\n\t  from Nobu.\n\nWed Dec 25 11:05:11 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bcc32/setup.mak (-generic-): removed garbages.\n\nWed Dec 25 10:36:20 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub (RUBY_SO_NAME, config.h):\n\t  use $(MAJOR) and $(MINOR). based on Nobu's patch. [ruby-win32:413]\n\n\t* bcc32/setup.mak, win32/setup.mak (-prologue-): define MAJOR, MINOR\n\t  and TEENY from version.h. based on Nobu's patch. [ruby-win32:413]\n\n\t* win32/Makefile.sub (config.h): add HAVE_FLOAT_H.\n\n\t* win32/Makefile.sub (parse.obj): depend on win32/win32.h.\n\nTue Dec 24 23:49:16 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/irb/completion.rb: Use Object#class rather than Object#type.\n\nTue Dec 24 23:37:40 2002  TADA Tadashi <sho@spc.gr.jp>\n\n\t* lib/cgi.rb (Cookie::parse), lib/cgi-lib.rb (initialize): Do not\n\t  pass to split() a bare string longer than 2 characters as\n\t  separator.\n\nTue Dec 24 19:19:24 2002  Tietew <tietew@tietew.net>\n\n\t* numeric.c (DBL_MAX_10_EXP): fix typo. [ruby-dev:19175]\n\nTue Dec 24 17:02:46 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_undefined): use NoMethodError instead of fatal.\n\nTue Dec 24 02:12:45 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/README: Synchronize with reality.\n\nTue Dec 24 02:05:51 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* MANIFEST, lib/README, lib/ipaddr.rb: Add ipaddr.rb from rough.\n\nSun Dec 22 04:07:47 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/dbm/dbm.c (fdbm_alloc): allocator takes only one argument.\n\nSun Dec 22 02:49:25 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* array.c (ary_alloc), dir.c (dir_s_alloc), eval.c (thgroup_s_alloc),\n\t  file.c (rb_stat_s_alloc), hash.c (hash_alloc), io.c (io_alloc),\n\t  object.c (rb_module_s_alloc, rb_class_allocate_instance),\n\t  re.c (match_alloc, rb_reg_s_alloc), string.c (str_alloc),\n\t  time.c (time_s_alloc), ext/digest/digest.c (rb_digest_base_alloc),\n\t  ext/tcltklib/tcltklib.c (ip_alloc),\n\t  ext/win32ole/win32ole.c (fole_s_allocate, fev_s_allocate)\n\t  : add prototype to get rid of VC++ warnings.\n\n\t* ext/sdbm/init.c (fsdbm_alloc): allocator takes only one argument.\n\nSun Dec 22 00:36:43 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): accept pure ruby libraries.\n\nSat Dec 21 23:59:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (ins_methods_i): should not show ID_ALLOCATOR.\n\n\t* class.c (ins_methods_prot_i): ditto.\n\n\t* class.c (ins_methods_priv_i): ditto.\n\n\t* class.c (ins_methods_pub_i): ditto.\n\n\t* eval.c (call_trace_func): ditto.\n\n\t* eval.c (rb_undefined): ditto.\n\nSat Dec 21 07:27:24 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-parse-partial): keywords must not be\n\t  preceded by @ or $.\n\nFri Dec 20 20:29:04 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/curses/curses.c, ext/dbm/dbm.c, ext/digest/digest.c,\n\t  ext/dl/handle.c, ext/dl/ptr.c, ext/dl/sym.c, ext/gdbm/gdbm.c,\n\t  ext/iconv/iconv.c, ext/sdbm/init.c, ext/stringio/stringio.c,\n\t  ext/strscan/strscan.c, ext/tcltklib/tcltklib.c,\n\t  ext/win32ole/win32ole.c: use rb_define_alloc_func().\n\nFri Dec 20 18:29:04 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (rb_io_fwrite): separated from io_write().\n\n\t* marshal.c (w_byten): use rb_io_fwrite() to support non-blocking\n\t  IO, and added error check.\n\n\t* rubyio.h: prototypes; rb_io_fwrite\n\nFri Dec 20 17:40:59 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (Init_Object): should not remove Class#allocate.\n\n\t* lib/profiler.rb: separate profiling functions, without\n\t  trace_func and at_exit setting.\n\nFri Dec 20 16:20:04 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (do_block): split \"do\" block and tLBRACE_ARG block.\n\n\t* parse.y (cmd_brace_block): new tLBRACE_ARG block rule\n\n\t* parse.y (command): can take optional cmd_brace_block; use %prec\n\t  to resolve shift/reduce conflict. (ruby-bugs-ja PR#372)\n\n\t* eval.c (ruby_finalize): trace_func should be cleared here (after\n\t  executing exit procs and finalizers).\n\n\t* eval.c (rb_define_alloc_func): new allocation framework, based\n\t  on Nobu's work [ruby-dev:19116].  \"allocate\" method is no longer\n\t  used for object allocation.\n\nFri Dec 20 05:06:49 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/README, lib/cgi/ftplib.rb, lib/telnet.rb: Delete ftplib.rb\n\t  and telnet.rb.  It has been quite some time sinc they were\n\t  obsoleted and made to emit warnings.\n\nFri Dec 20 04:58:22 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/tempfile.rb: Embed Rdoc style comments.\n\n\t* lib/tempfile.rb: Add length as an alias for size.\n\nFri Dec 20 03:57:32 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/tempfile.rb: Add Tempfile#close!() as a shorthand for\n\t  Tempfile#close(true).\n\n\t* lib/tempfile.rb: Add Tempfile#{unlink,delete}().\n\nFri Dec 20 03:53:01 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/README, lib/cgi/final.rb, lib/cgi/session.rb: Delete\n\t  final.rb, which was obsoleted long ago.\n\nFri Dec 20 00:16:06 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* re.c (rb_reg_match_pre, rb_reg_match_post, match_to_a,\n\t  match_select): return instances of same class as the original\n\t  string.  [ruby-dev:19119]\n\nThu Dec 19 22:55:49 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* numeric.c (DBL_EPSILON): fix typo.\n\nThu Dec 19 22:35:20 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (assign): avoid [BUG] at multiple attribute assignment.\n\nThu Dec 19 01:00:09 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_step): use DBL_EPSILON.\n\n\t* array.c (rb_check_array_type): new function: return an array\n\t  (convert if possible), or nil.\n\n\t* string.c (rb_check_string_type): new function: return a string\n\t  (convert if possible), or nil.\n\n\t* numeric.c (rb_dbl_cmp): returns nil if values are not\n\t  comparable.\n\n\t* numeric.c (fix_cmp,flo_cmp): use rb_num_coerce_cmp()\n\n\t* bignum.c (rb_big_cmp): ditto.\n\n\t* numeric.c (rb_num_coerce_cmp): new coercing function for \"<=>\",\n\t  which does not raise TypeError.\n\n\t* numeric.c (do_coerce): can be suppress exception now.\n\n\t* object.c (rb_mod_cmp): should return nil for non class/module\n\t  objects.\n\nThu Dec 19 04:21:10 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/open-uri.rb: add a missing ||. (found by: ruby -wc)\n\nWed Dec 18 17:53:05 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_eqq): return false if the argument is not a\n\t  string.  now returns boolean value.\n\n\t* class.c (rb_include_module): argument should be T_MODULE, not\n\t  T_class, nor T_ICLASS.\n\nWed Dec 18 03:52:55 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (rb_str_new4): handle tail shared string.\n\t  (ruby-bugs-ja:PR#370)\n\n\t* string.c (rb_str_dup_frozen): ditto.\n\nTue Dec 17 21:08:29 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* node.h (NODE_ATTRASGN): new node, assignment to attribute.\n\t  [ruby-core:00637].\n\n\t* eval.c (is_defined, rb_eval): ditto.\n\n\t* parse.y (attrset, node_assign): ditto.\n\n\t* string.c (rb_str_substr): tail sharing.  [ruby-core:00650]\n\n\t* re.c (rb_reg_nth_match): ditto.\n\nTue Dec 17 16:52:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): \"defined?\" should return \"assignment\" for\n\t  attribute assignment (e.g. a.foo=b) and indexed assignment\n\t  (e.g. a[2] = 44).\n\n\t* parse.y (aryset): use NODE_ATTRASGN.\n\nTue Dec 17 04:03:45 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/open-uri.rb: new file.\n\nTue Dec 17 00:28:19 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* file.c (utimbuf): need to define for VC++.\n\nMon Dec 16 15:53:20 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (nextc): get rid of overrun.  (pointed out by akr\n\t  [ruby-list:36773])\n\nSun Dec 15 21:16:44 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (init_mkmf): add $(topdir) to $LIBPATH if $extmk.\n\t  remove adding $(archdir) to $LIBPATH.\n\nSat Dec 15 12:15:00 2002  Takaaki Uematsu <mail@uema2.cjb.net>\n\n\t* configure.in, defines.h, dir.c, dir.h, dln.c, error.c,\n\t  eval.c, file.c, hash.c, io.c, main.c, missing.c,\n\t  process.c, ruby.c, rubysig.h, signal.c, st.c, util.c, util.h,\n\t  bcc/Makefile.sub, win32/Makefile.sub, win32/win32.h,\n\t  ext/Win32API/Win32API.c, ext/socket/getaddrinfo.c,\n\t  ext/socket/getnameinfo.c, ext/socket/socket.c,\n\t  ext/tcltklib/stubs.c\n\t  : replace \"NT\" with \"_WIN32\", add DOSISH_DRIVE_LETTER\n\t* wince/exe.mak : delete \\r at the end of lines.\n\t* wince/mswince-ruby17.def : delete rb_obj_become\n\nSun Dec 15 11:43:26 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (dispose_string): dispose String object.\n\n\t* parse.y (heredoc_restore, here_document): fix memory leak.\n\nSat Dec 14 14:25:00 2002  Takaaki Uematsu <mail@uema2.cjb.net>\n\n\t* wince/sys : add stat.c, stat.h, timeb.c, timeb.h,\n\t\t      types.h, utime.c, utime.h\n\t* wince/dll.mak : object file name changed.\n\t* wince/io.c : add empty dup2().\n\t* wince/io.h : add dup2 definition.\n\nSat Dec 14 01:51:29 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb (rb_check): support for GNU dbm 1.8.3.\n\t  (-with-dbm-type=gdbm_compat). link against -lgdbm_compat\n\t  and -lgdbm.\n\nFri Dec 13 23:42:16 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb (db_check): check existence of the function\n\t  in the specified library before checking it in libc.\n\nFri Dec 13 17:15:49 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (generic_ivar_get): should always warn uninitialized\n\t  instance variables.\n\nFri Dec 13 12:33:22 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (expr): rescue clause was ignored.\n\nThu Dec 12 18:19:14 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (RUBY_PROG_GNU_LD): add $CFLAGS, $CPPFLAGS, $LDFLAGS\n\t  to the option of $CC.\n\n\t* configure.in: set LIBRUBYARG to '-l$(RUBY_SO_NAME)' if the\n\t  target os is cygwin and --disable-shared option is supplied.\n\n\t* lib/mkmf.rb (init_mkmf): expand config[\"LIBRUBY\"] and\n\t  config[\"LIBRUBY_A\"].  don't link $LIBRUBYARG_STATIC if\n\t  --disable-shared option is supplied.\n\n\t* configure.in (RUBY_CPPOUTFILE): should be a better message.\n\n\t* ext/Win32API/extconf.rb: join with a space.\n\nThu Dec 12 17:27:19 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_hash): define Regexp#hash to make regexps to be\n\t  hash keys.\n\n\t* re.c (Init_Regexp): define Regexp#eql? (alias to Regexp#==).\n\nThu Dec 12 16:26:31 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (r_object0): singleton class instance can't be loaded.\n\t  (ruby-bugs-ja:PR#366)\n\nWed Dec 11 23:35:43 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb (create_makefile): -no-undefined -> --no-undefined.\n\nWed Dec 11 17:54:59 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_read): takes optional second argument to specify a\n\t  string to be written.  the string should not be frozen.\n\n\t* io.c (rb_io_sysread): ditto.\n\nWed Dec 11 11:30:28 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/digest/digest.c (rb_digest_base_copy): renamed \"become\".\n\n\t* ext/stringio/stringio.c (strio_copy): ditto.\n\nWed Dec 11 00:45:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/getoptlong.rb (GetoptLong::Error): provide a common ancestor\n\t  for GetoptLong error classes (RCR#129).\n\nTue Dec 10 17:42:39 2002  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* re.c (rb_reg_copy_object): fixed memory leak.\n\nTue Dec 10 17:30:35 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* pack.c (utf8_limits): fix the limit of 4 bytes UTF-8 sequence.\n\nTue Dec 10 12:01:15 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (mnew): original class of method defined in module should\n\t  be the module not intermediate class.  [ruby-dev:19040]\n\nTue Dec 10 01:16:52 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): preceding \"..\" for negative numbers\n\t  still left;  removed.\n\n\t* sprintf.c (rb_f_sprintf): should not prepend '0' if width > prec\n\t  for example \"%5.3d\".\n\nSat Dec  7 18:14:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (Init_process): add Process.exit and Process.abort\n\n\t* pack.c (utf8_to_uv): raise ArgumentError for malformed/redundant\n\t  UTF-8 sequences.\n\nFri Dec  6 03:46:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (last_status_set): add pid attribute to Process::Status.\n\nWed Dec  4 17:31:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (uv_to_utf8): limit maximum length of the encoded string\n\t  to 6 bytes, even when the platform supports 8 bytes long integers.\n\n\t* pack.c (utf8_to_uv): do not decode sequences longer than 6 bytes.\n\n\t* object.c (copy_object): use \"copy_object\" method, not \"become\".\n\nWed Dec  4 16:37:11 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (copy_object): copy finalizers as well if any.\n\n\t* gc.c (rb_gc_copy_finalizer): new function to copy finalizers.\n\nTue Dec  3 01:13:41 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (PP.singleline_pp): new method.\n\nSun Dec  1 23:04:03 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (OptionParser::new): same as OptionParser#on but\n\t  returns new OptionParser::switch.\n\nSun Dec  1 22:43:29 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (rb_w32_stat): empty path is invalid, and return\n\t  ENOENT rather than EBADF in such case.  [ruby-talk:57177]\n\nFri Nov 29 18:01:48 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (utf8_to_uv): added checks for malformed or redundant\n\t  UTF-8 sequences.\n\nThu Nov 28 12:08:30 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb: Avoid the use of \"clean::\" in favor of \"clean:\" in\n\t  order not to let make(1) choke if there is another dependency on\n\t  the target added in a depend file.\n\nThu Nov 28 02:40:42 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb: Make sure to dig the destination directory before\n\t  installing a file there.  Formerly \"make install\" could fail\n\t  depending on make(1)'s mood of the moment, especially when -jN\n\t  is given.\n\nWed Nov 27 17:39:38 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syslog/syslog.c: Cut redundancy.\n\n\t* ext/syslog/syslog.c: Do not leak ident.\n\nWed Nov 27 17:25:29 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syslog/syslog.c, ext/syslog/test.rb: Syslog.close should\n\t  raise RuntimeError when not opened.\n\n\t* ext/syslog/syslog.c, ext/syslog/test.rb:\n\t  Syslog.{ident,options,facility,mask} should all return nil when\n\t  not opened.\n\n\t* ext/syslog/syslog.c, ext/syslog/test.rb: Change back the output\n\t  format of inspect().\n\nWed Nov 27 16:25:43 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/test.rb: Switch from RUnit to Test::Unit.\n\nWed Nov 27 16:14:12 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syslog/syslog.c: Fix a problem where Syslog.ident was not\n\t  marked and could thus be GC'd.\n\nWed Nov 27 16:11:53 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syslog/test.rb: Switch from RUnit to Test::Unit.\n\n\t* ext/syslog/test.rb: The output format of inspect() is slightly\n\t  altered.\n\nWed Nov 27 06:43:26 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* error.c (exit_initialize): add SystemExit#initialize to set\n\t  instance variable status.  (ruby-bugs-ja:PR#362)\n\t  Now accepts status as optional first argument.\n\n\t* eval.c (error_handle): now SystemExit have status always.\n\n\t* eval.c (system_exit): just instantiate SystemExit without raise.\n\n\t* eval.c (rb_thread_start_0): initialize SystemExit properly.\n\nTue Nov 26 10:17:04 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dln.c (init_funcname_len): remove MAXPATHLEN dependency.\n\nMon Nov 25 19:55:38 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb (extmake): return true if not dynamic and not static.\n\nMon Nov 25 01:08:40 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dln.c: revert and add the MAXPATHLEN definition on mswin32/mingw32.\n\nSun Nov 24 20:36:53 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dln.c: move the MAXPATHLEN definition in front.\n\nFri Nov 22 22:55:01 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (rb_f_sprintf): preceding \"..\" for negative\n\t  hexadecimal numbers should not appear if prec (e.g. %.4) is\n\t  specified.\n\n\t* pack.c (NUM2I32): support platforms which does not have 32bit\n\t  integers (e.g. Cray).\n\nFri Nov 22 19:20:36 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* instruby.rb: Install batch files on Windows. [Submitted by usa]\n\nFri Nov 22 18:31:46 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_add_method): node may be NULL.\n\nThu Nov 21 20:53:06 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: changes coding style.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/protocol.rb: ditto.\n\nThu Nov 21 20:17:08 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: changes coding style.\n\nThu Nov 21 20:04:06 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: should not overwrite Host: header.\n\t  (This patch is contributed by sean@ruby-lang.org)\n\nThu Nov 21 20:01:33 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: support Proxy-Authorization.\n\t  (This patch is contributed by Alexander Bokovoy)\n\nThu Nov 21 11:03:39 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_find_file_ext): should not terminate searching with\n\t  empty path, just ignore.\n\n\t* dir.c: remove <sys/parm.h> inclusion.\n\nWed Nov 20 02:07:12 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* compar.c (cmp_eq,cmp_gt,cmp_ge,cmp_lt,cmp_le): check using\n\t  rb_cmpint().\n\n\t* error.c (init_syserr): remove sys_nerr dependency.\n\nWed Nov 20 01:52:21 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_cmp): added to satisfy Comparable assumption.\n\n\t* eval.c (rb_add_method): \"initialize\" should be public if it is a\n\t  singleton method.\n\nTue Nov 19 22:37:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match): avoid dereferencing if size == 0.\n\t  (ruby-bugs-ja:PR#360)\n\nTue Nov 19 20:40:39 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_cmp): should return nil if an operand is not a\n\t  number nor time. (ruby-bugs-ja:PR#359)\n\n\t* file.c (rb_stat_cmp): should return nil if an operand is not\n\t  File::Stat.\n\nTue Nov 19 14:35:09 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_zip): iterates over items in the receiver.\n\t  zipped with nil if argument arrays are shorter.  if arrays are\n\t  longer, left items are ignored.  now works with blocks.\n\n\t* enum.c (zip_i): changed for new behavior.\n\n\t* array.c (rb_ary_transpose): added. [new]\n\nTue Nov 19 05:12:21 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* instruby.rb: Do not install various working files under bin/.\n\nTue Nov 19 05:07:39 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* instruby.rb: not rewrite installed scripts when dry-run mode.\n\n\t* lib/ostruct.rb (OpenStruct::initialize): should symbolize keys\n\t  instead of values.\n\nTue Nov 19 02:24:10 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* instruby.rb: Rewrite installed scripts' shebang lines.\n\n\t* instruby.rb: Use File.join() where appropriate.\n\nTue Nov 19 01:53:35 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* bin/irb: Moved from sample/irb.rb.\n\n\t* instruby.rb: Install script files under bin/ with ruby's program\n\t  prefix and suffix.\n\nMon Nov 18 02:13:36 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/tempfile.rb: Make this library thread safe.\n\n\t* lib/tempfile.rb: Do not pick a name which was once used and is\n\t  still scheduled for removal.\n\n\t* lib/tempfile.rb: A lock file need not and must not be scheduled\n\t  for removal.\n\n\t* lib/tempfile.rb: Compare Max_try with the number of mkdir\n\t  failures instead of the suffix counter.\n\n\t* lib/tempfile.rb: Overall cleanup and add some important notices.\n\nSun Nov 17 22:57:31 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (dsym): garbage returned.  (ruby-bugs-ja:PR#358)\n\nFri Nov 15 07:40:08 2002  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* observer.rb: raise NoMethodError instead of NameError.\n\t  [ruby-dev:18788]\n\n\t* ostruct.rb: ditto.  fix a bug in inspect which called String#+ with\n\t  Symbol.  [ruby-dev:18788]\n\n\t* profile.rb: illegal use of Array#sort!.  replaced it with non-bang\n\t  method.  [ruby-dev:18792]\n\nThu Nov 14 22:40:29 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (LIBRUBY_A): append -static.  [ruby-dev:18689]\n\n\t* configure.in (LIBRUBYARG_STATIC, LIBRUBYARG_SHARED): linker\n\t  argument to link static/shared library respectively.\n\n\t* Makefile.in (LIBRUBYARG_STATIC, LIBRUBYARG_SHARED): added.\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub: ditto.\n\n\t* instruby.rb (LIBRUBY_A): install to libdir.\n\n\t* lib/mkmf.rb (link_command): link static library of ruby, or\n\t  try_run fails unless LIBRUBY_SO is installed.  [ruby-dev:18646]\n\n\t* eval.c (call_trace_func): toplevel caller was missing.\n\t  [ruby-dev:18754]\n\n\t* eval.c (proc_to_s): adjust created line number.\n\n\t* parse.y (primary, do_block, brace_block): adjust line number of\n\t  block to beginning line, instead of the first statement inside\n\t  the block.\n\nThu Nov 14 08:23:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* math.c (math_acos): check errno after operation.  ditto for\n\t  asin, acosh, atanh, log, log10 and sqrt.\n\n\t* eval.c (rb_add_method): initialize should always be private.\n\n\t* parse.y (expr): add rescue modifier rule.\n\n\t* parse.y (command_call): return, break and next with argument is\n\t  now part of this rule.\n\nWed Nov 13 16:22:38 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (DLDFLAGS): removed -Wl,-no-undefined to\n\t  ext/extmk.rb, in order to allow references to symbols in other\n\t  extension libraries for mkmf.rb.  [ruby-dev:18724]\n\n\t* ext/extmk.rb (extmake): ditto.\n\n\t* ext/extmk.rb (extmake): exit when make failed.\n\nSun Nov 10 03:46:18 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: retire contain?() and add superset?(),\n\t  proper_superset?() subset?(), and proper_subset?().\n\t  [obtained from: Jason Voegele's set.rb]\n\n\t* lib/set.rb: define several aliases: union() for |(),\n\t  difference() for -(), and intersection() for &().\n\t  [obtained from: Jason Voegele's set.rb]\n\n\t* lib/set.rb: deal with a s/id/object_id/ leftover.\n\nSat Nov  9 16:06:57 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/tcltklib/stubs.c: should include \"util.h\" for ruby_strdup.\n\nSat Nov  9 11:39:45 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c: remove ENABLE_TRACE/DISABLE_TRACE to trace child nodes of\n\t  c-call. [ruby-dev:18699]\n\nFri Nov  8 04:16:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): \"a\" in \"a /5\" should be considered as a local\n\t  variable. [experimental]\n\nThu Nov  7 09:51:37 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_yield_0): should enable trace for non-cfunc nodes.\n\t  [ruby-dev:18645]\n\n\t* eval.c (blk_orphan): a block created in a different thread is\n\t  orphan.  [ruby-dev:17471]\n\nWed Nov  6 16:57:06 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_define_method): do not set NOEX_CFUNC if klass is\n\t  really a module, whose methods must be safe for reciever's type.\n\n\t* eval.c (rb_eval): nosuper should not be inherited unless the\n\t  overwritten method is an undef placeholder.\n\nTue Nov  5 00:46:04 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb: Properly pass the given target to\n\t  make(1). [pointed out by eban]\n\nMon Nov  4 20:03:53 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* instruby.rb, lib/mkmf.rb: use CONFIG[\"ENABLE_SHARED\"] instead of\n\t  checking whether CONFIG[\"configure-args\"] includes \"--enable-shared\".\n\nMon Nov  4 16:49:14 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (primary): allow 'when'-less case statement; persuaded\n\t  by Sean Chittenden.\n\nMon Nov  4 06:28:09 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* Makefile.in, ext/extmk.rb, bcc32/Makefile.sub,\n\t  win32/Makefile.sub: Introduce better command line syntax\n\t  (--make/--make-flags/--extstatic) to extmk.rb and instruby.rb.\n\t  Previously such command as 'make -j3 install' with pmake doesn't\n\t  fail.  Formerly extmk.rb was receiving \"make -j 3 -j 3\" via the\n\t  command line arguments and just ended up recognizing the first\n\t  \"3\" as destdir. [with help of usa]\n\nMon Nov  4 03:59:51 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/getopts.rb: Do not choke on characters that cannot be used\n\t  in a variable name.  Replace them with `_'.  Define a hash named\n\t  $OPT for convenience.\n\nSat Nov  2 00:38:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (Init_Object): added Object#object_id, new name for\n\t  Object#id. [new]\n\n\t* object.c (rb_obj_id_obsolete): give warning for Object#id.\n\n\t* numeric.c (fix_intern): added Fixnum#to_sym. [new]\n\n\t* object.c (sym_to_sym): rename from Symbol#intern\n\nFri Nov  1 14:21:06 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_zip): added Enumerable#zip. [new]\n\n\t* array.c (rb_ary_zip): added Array#zip.\n\nThu Oct 31 20:10:18 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (init_syserr): remove sys_nerr dependency.\n\nThu Oct 31 09:31:51 2002  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (rb_export_method): undef'ed method visibility should not\n\t  be changed.\n\nWed Oct 30 17:00:47 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_public_method_defined, etc.): new methods:\n\t  public_method_defined?, private_method_defined?,\n\t  protected_method_defined?\n\n\t* object.c (rb_obj_public_methods): new method\n\t  Object#public_methods.\n\n\t* class.c (ins_methods_i): Object#methods should list both public\n\t  and protected methods.\n\n\t* class.c (rb_class_public_instance_methods): new method\n\t  Module#public_instance_methods.\n\nWed Oct 30 06:29:00 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c, file.c, gc.c, io.c, object.c, ruby.c, ruby.h, struct.c,\n\t  ext/socket/socket.c: differentiate long and int; use proper\n\t  printf type specifiers and do casts where appropriate.\n\nWed Oct 30 04:07:33 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (error_print, rb_longjmp, rb_thread_schedule): flush\n\t  error message.  [ruby-dev:18582]\n\n\t* eval.c (ruby_cleanup): added.  just clean up without exit.\n\t  [ruby-dev:18582]\n\n\t* eval.c (ruby_exec): added.  execute main evaluation tree without\n\t  exit.  [ruby-dev:18582]\n\n\t* intern.h: prototypes; ruby_cleanup, ruby_exec\n\nTue Oct 29 02:00:08 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/extmk.rb (extmake): use dummy_makefile to create dummy\n\t  Makefile.\n\n\t* lib/mkmf.rb (find_executable0): EXEEXT is optional.\n\n\t* lib/mkmf.rb (dummy_makefile): make dummy Makefile content.\n\n\t* lib/mkmf.rb (create_makefile): define EXTLIB replacing -l.\n\n\t* lib/mkmf.rb ($bccwin): detect Borland make by help message.\n\n\t* lib/mkmf.rb (CLEANINGS): common rules to clean.\n\nMon Oct 28 01:27:17 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* djgpp/config.sed (@program_transform_name@): use `%', not `,'.\n\nSun Oct 27 22:59:50 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* ext/extmk.rb(78) : The unnecessary error when installing by bccwin32\n\t                     is controlled.\n\n\t* lib/mkmf.rb(773) : Also in the case of bccwin32, the path was added.\n\nSun Oct 27 17:07:25 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* djgpp/*: sync with the latest.\n\n\t* ext/extmk.rb, lib/mkmf.rb: flush $stdout.\n\n\t* io.c (READ_DATA_PENDING_COUNT, READ_DATA_PENDING_PTR):\n\t  undef these macros on DJGPP.\n\nSat Oct 26 10:11:47 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* node.h (nd_type): cast the value to int.\n\nSat Oct 26 04:27:35 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dbm/dbm.c (fdbm_indexes, fdbm_select): add a missing\n\t  argument and prevent coredump when a nonexistent key is\n\t  specified.\n\n\t* ext/sdbm/init.c (fsdbm_indexes, fsdbm_select): ditto.\n\nSat Oct 26 03:28:43 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* eval.c, gc.c: use a common set of alloca() #ifdef's.  This fixes\n\t  the build with Intel C Compiler for Linux.\n\n\t* eval.c (rb_f_require): declare old_func with a real type, not\n\t  just type modifiers.\n\nFri Oct 25 02:55:01 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* string.c (rb_str_split_m): RSTRING(str)->ptr might become NULL.\n\t  [ruby-dev:18581]\n\nThu Oct 24 21:57:02 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (LIBPATHFLAG): avoid $ substitution.\n\t  [ruby-dev:18577]\n\n\t* ext/extmk.rb (extmake): expand $srcdir.\n\n\t* ext/win32ole/extconf.rb: should not override $CFLAGS, but\n\t  append.\n\n\t* lib/mkmf.rb (config_string): use given config hash.\n\n\t* bcc32/Makefile.sub (.rc.res): directory part may be empty in\n\t  Borland make.\n\nThu Oct 24 03:38:07 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb (create_makefile): site-install target for backward\n\t  compatibility.\n\n\t* lib/mkmf.rb (init_mkmf): libdir prior to topdir.\n\n\t* configure.in (LIBPATHFLAG): should escape $.  [ruby-dev:18572]\n\n\t* mkconfig.rb: never substitute escaped $$.\n\n\t* instruby.rb: not install LIBRUBY_SO unless enable-shared.\n\t  [ruby-dev:18569]\n\nWed Oct 23 19:16:06 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): added NODE_DSYM, symbol literal with\n\t  interpolation.\n\n\t* node.h: ditto.\n\n\t* intern.h: prototypes; rb_is_junk_id, rb_str_dump, rb_str_intern\n\n\t* object.c (sym_inspect): escape and quote for non-alphanumeric\n\t  symbols.\n\n\t* parse.y (dsym, tokadd_string, yylex): extended symbol literals.\n\n\t* parse.y (rb_is_junk_id): added.\n\n\t* string.c (rb_str_dump, rb_str_intern) : make extern.\n\n\t* lib/mkmf.rb (create_makefile): deffile should be removed by\n\t  distclean, not clean.\n\nTue Oct 22 23:56:41 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (init_mkmf): add dir_config(\"opt\").\n\nTue Oct 22 19:44:03 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/configure.bat : The command line when calling setup.mak is\n\t                        corrected.\n\n\t* bcc32/readme.bcc32 : It follows up about the option of configure.bat.\n\nTue Oct 22 15:23:19 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* instruby.rb: add dryrun mode.\n\n\t* ext/extmk.rb (extmake): add install: target to dummy Makefile.\n\n\t* ext/extmk.rb (extmake): avoid Borland make's quirk behavior.\n\n\t* lib/mkmf.rb (link_command): opt is not a makefile macro.\n\n\t* bcc32/Makefile.sub ($(LIBRUBY_SO) $(LIBRUBY)): EXTOBJS were not\n\t  linked.\n\n\t* bcc32/Makefile.sub (ext/extinit.obj): missing.\n\n\t* bcc32/Makefile.sub (TRY_LINK): options have to place before any\n\t  non-option arguments.\n\n\t* win32/Makefile.sub (TRY_LINK): need -link and -libpath options.\n\n\t* bcc32/Makefile.sub, win32/Makefile.sub (RANLIB): logical\n\t  operator never work with command.com.\n\nTue Oct 22 00:59:59 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (RUBY_CPPOUTFILE): fix cache file bug.\n\n\t* lib/mkmf.rb (link_command): put 'opt' after conftest.c for\n\t  static linking.\n\nMon Oct 21 22:53:02 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (XCFLAGS): CFLAGS to compile ruby itself.\n\n\t* configure.in (LIBEXT): suffix for static libraries.\n\n\t* configure.in (LIBPATHFLAG): switch template to specify library\n\t  path.\n\n\t* configure.in (LINK_SO): command to link shared objects.\n\n\t* configure.in (DEFFILE, ARCHFILE): miscellaneous system dependent\n\t  files.\n\n\t* configure.in (EXPORT_PREFIX): prefix to exported symbols on\n\t  Windows.\n\n\t* configure.in (COMMON_LIBS, COMMON_MACROS, COMMON_HEADERS):\n\t  libraries, macros and headers used in common.\n\n\t* configure.in (RUBYW_INSTALL_NAME, rubyw_install_name): GUI mode\n\t  executable name.\n\n\t* Makefile.in (CFLAGS): append XCFLAGS.\n\n\t* Makefile.in (PREP): miscellaneous system dependent files.\n\n\t* Makefile.in (ruby.imp, ext/extinit.o): moved from ext/extmk.rb.\n\n\t* Makefile.in (fake.rb): CROSS_COMPILING keeps building platform.\n\n\t* Makefile.in (MAKEFILES): depend on *.in and config.status.\n\n\t* Makefile.in (parse.c): replace \"y.tab.c\" with actual name for\n\t  byacc.\n\n\t* ext/extmk.rb, lib/mkmf.rb: integrated.\n\n\t* ext/extmk.rb: propagate MFLAGS.\n\n\t* ext/extmk.rb (extmake): make dummy Makefile to clean even if no\n\t  Makefile is made.\n\n\t* lib/mkmf.rb (older): accept multiple file names and Time\n\t  objects.\n\n\t* lib/mkmf.rb (xsystem): split and quote.\n\n\t* lib/mkmf.rb (cpp_include): make include directives.\n\n\t* lib/mkmf.rb (try_func): try whether specified function is\n\t  available.\n\n\t* lib/mkmf.rb (install_files): default to site-install.\n\n\t* lib/mkmf.rb (checking_for): added.\n\n\t* lib/mkmf.rb (find_executable0): just find executable file with\n\t  no message.\n\n\t* lib/mkmf.rb (create_header): output header file is variable.\n\n\t* lib/mkmf.rb (create_makefile): separate sections.\n\n\t* lib/mkmf.rb (init_mkmf): initialize global variables.\n\n\t* win32/Makefile.sub, bcc32/Makefile.sub (CPP, AR): added.\n\n\t* bcc32/Makefile.sub (ARCH): fixed to i386.\n\n\t* win32/Makefile.sub, bcc32/Makefile.sub (miniruby): should not\n\t  link EXTOBJS.\n\n\t* ext/dl/extconf.rb: use try_cpp to cross compile.\n\n\t* ext/dl/extconf.rb: not modify files in source directory.\n\nFri Oct 18 23:11:21 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (value_expr0): allow return/break/next/redo/retry in rhs\n\t  of logical operator.  [ruby-dev:18534]\n\n\t* parse.y (remove_begin): eliminate useless NODE_BEGIN.\n\t  [ruby-dev:18535]\n\nFri Oct 18 01:02:44 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* hash.c, eval.c: Use (*_NSGetEnviron()) instead of environ on\n\t  Darwin for namespace cleanness.  [ruby-core:00537]\n\n\t* dln.c (dln_load): Fix Darwin support that has been disabled and\n\t  switch to using it on Darwin instead of the system dlopen().\n\t  [ruby-core:00541]\n\nThu Oct 17 19:17:56 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (w_byten): added; write n bytes from s to arg.\n\n\t* marshal.c (dump): flush buffered data.\n\n\t* marshal.c (marshal_dump, r_byte, r_bytes0, marshal_load): unify\n\t  marshaling I/O.  [ruby-talk:53368]\n\nThu Oct 17 12:58:24 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: stat.blksize might be 0/nil.\n\n\t* lib/fileutils.rb: change coding style.\n\nWed Oct 16 22:35:53 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* sprintf.c (rb_f_sprintf): disallow mixed usage of numbered and\n\t  unnumbered arguments.  [ruby-dev:18531]\n\t  get rid of memory leak at exception.  [ruby-core:00460]\n\nWed Oct 16 13:36:29 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* variable.c (rb_global_entry): not add global entry until\n\t  initialized to avoid accessing it while GC.  [ruby-dev:18514]\n\n\t* variable.c (rb_alias_variable): ditto.\n\nWed Oct 16 01:03:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_str_to_dbl): RString ptr might be NULL.\n\n\t* object.c (rb_cstr_to_dbl): p pointer might be NULL.\n\n\t* bignum.c (rb_str_to_inum): RString ptr might be NULL.\n\n\t* bignum.c (rb_cstr_to_inum): str pointer might be NULL.\n\nSat Oct 12 23:44:11 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (rb_w32_putc): wrong condition to fill or flush on\n\t  bccwin32.  [ruby-win32:408]\n\nFri Oct 11 15:58:06 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): rescue modifier is now an operator with\n\t  precedence right below assignments. i.e. \"a = b rescue c\" now\n\t  parsed as \"a = (b rescue c)\", not as \"(a = b) rescue c\". [new]\n\t  [experimental]\n\nFri Oct 11 06:05:30 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (rb_w32_fclose, rb_w32_close): use closesocket()\n\t  for socket.  [ruby-win32:382]\n\n\t* win32/win32.c (StartSockets): set NtSocketsInitialized.\n\n\t* win32/win32.h: prototypes; rb_w32_fclose, rb_w32_close\n\nFri Oct 11 00:24:57 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* gc.c (ruby_xmalloc, ruby_xrealloc): restrict total allocation\n\t  size according to memories consumed by live objects.\n\t  [ruby-dev:18482]\n\n\t* gc.c (gc_sweep): estimate how live objects consume memories.\n\nThu Oct 10 17:26:12 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/tcltklib/stubs.c (ruby_tcltk_stubs): fix memory leak.\n\t  [ruby-dev:18478]\n\nThu Oct 10 15:20:18 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/weakref.rb (WeakRef::@@final): use Hash#delete.\n\n\t* lib/weakref.rb (WeakRef::__getobj__): examine if alive or not by\n\t  ID_REV_MAP to deal with recycled object.  [ruby-dev:18472]\n\n\t* lib/weakref.rb (WeakRef::weakref_alive?): ditto.\n\nWed Oct  9 07:11:25 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* gc.c (gc_sweep): also adjust heaps_limits when free unused heap\n\t  page.  [ruby-core:00526]\n\n\t* io.c (io_fflush): condition to retry can occur.\n\n\t* io.c (io_write): returned 0 wrongly if no error occurred.\n\nTue Oct  8 14:19:07 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (io_write): must check returned value from fwrite() before\n\t  test with ferror().  (ruby-bugs-ja:PR#350)\n\nTue Oct  8 10:55:23 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/prettyprint.rb (PrettyPrint.singleline_format): new method.\n\nMon Oct  7 16:43:07 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bigdivrem): bignum zero's len should not be 0.\n\nMon Oct  7 15:36:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bigdivmod): wrong condition check for Bignum zero.\n\n\t* bignum.c (Init_Bignum): need to add Bignum#div.\n\nSun Oct  6 00:49:15 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (rb_load): should not pass blocks to the loaded file.\n\t  [ruby-dev:18458]\n\nFri Oct  4 20:25:38 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_interrupt, rb_thread_signal_raise): no need to\n\t  save dead thread context. (same as [ruby-dev:18322])\n\t  (ruby-bugs-ja:PR#349)\n\nFri Oct  4 13:05:58 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (RUBY_PROG_GNU_LD): check whether the linker is GNU ld.\n\n\t* ext/extmk.rb (create_makefile): add -Wl,-no-undefined to $DLDFLAGS\n\t  on Linux if GNU ld is used and --enable-shared is specified.\n\nFri Oct  4 02:21:16 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_rshift): num should be initialized by carry\n\t  bits if x is negative.\n\n\t* bignum.c (bigdivmod): len for bignum zero is 1, not 0.\n\nThu Oct  3 20:22:11 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bcc32/mkexports.rb: to work on cygwin via telnet.\n\t  [ruby-win32:358]\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke): requires command name\n\t  argument.  [ruby-dev:18438]\n\n\t* eval.c (ruby_init, ruby_options): Init_stack() with local\n\t  location.  (ruby-bugs-ja:PR#277)\n\n\t* eval.c (rb_call0): disable trace call.  [ruby-dev:18074]\n\n\t* eval.c (eval, rb_load): enable trace call.  [ruby-dev:18074]\n\n\t* eval.c (rb_f_require): set source file name for extension\n\t  libraries.  [ruby-dev:18445]\n\n\t* gc.c (Init_stack): prefer address of argument rather than local\n\t  variable to initialize rb_gc_stack_start.\n\n\t* ruby.c (translate_char): translate a character in a string;\n\t  DOSISH only.  [ruby-dev:18274]\n\n\t* ruby.c (ruby_init_loadpath): added argv[0] handling under\n\t  Human68K.  [ruby-dev:18274]\n\n\t* ruby.c (proc_options): translate directory separator in $0 to\n\t  '/'.  [ruby-dev:18274]\n\nThu Oct  3 00:27:26 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/delegate.rb (Delegator::initialize): use Object#class\n\t  instead of deprecated Object#type.\n\nWed Oct  2 23:32:48 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* configure.in (RUBY_CHECK_IO_NEED_FLUSH): check whether fflush()\n\t  is needed.\n\n\t* io.c (flush_before_seek): flush before seek if buffered data\n\t  may remain.\n\n\t* io.c (rb_io_check_readable): flush if the last operation was\n\t  write.\n\n\t* io.c (rb_io_check_writable): flush if the last operation was\n\t  read.\n\n\t* rubyio.h (FMODE_RBUF): added.\n\nWed Oct  2 23:09:20 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (rb_io_wait_readable): handle retryable errors.\n\n\t* io.c (rb_io_wait_writable): ditto.\n\n\t* ext/socket/socket.c (bsock_send): ditto.\n\n\t* ext/socket/socket.c (s_recvfrom): ditto.\n\n\t* ext/socket/socket.c (s_accept): ditto.\n\n\t* ext/socket/socket.c (udp_send): ditto.\n\n\t* ext/socket/getaddrinfo.c (afdl): made private structures constant.\n\n\t* rubyio.h: prototype; rb_io_wait_readable(), rb_io_wait_writable().\n\nWed Oct  2 13:03:58 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: set ac_cv_func_setitimer to \"no\" on Cygwin.\n\nWed Oct  2 10:59:29 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_sweep): free unused heap page to reduce process size if\n\t  possible.\n\n\t* object.c (rb_obj_type): deprecated Object#type; use Object#class.\n\nTue Oct  1 23:48:32 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/socket/socket.c (init_sock): no need for special finalizer,\n\t  socket descriptor is no longer duplicated in 1.7.\n\t  [ruby-talk:50732]\n\n\t* win32/win32.c, win32/win32.h (rb_w32_fddup, rb_w32_fdclose):\n\t  delete.\n\nMon Sep 30 20:29:10 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (rb_io_inspect): not need to raise IOError for closed\n\t  stream.  [ruby-talk:51871]\n\nMon Sep 30 03:48:15 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_check): need no Fixnum check.\n\nSun Sep 29 18:30:24 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (rb_w32_open_osfhandle): adjust\n\t  rb_w32_open_osfhandle() with _open_osfhandle().\n\n\t* win32/win32.c (rb_w32_accept, rb_w32_socket): return -1 on\n\t  error.\n\n\t* win32/win32.h: should use file descriptor instead of SOCKET.\n\nSun Sep 29 06:33:03 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (is_socket, rb_w32_select, rb_w32_accept, rb_w32_bind,\n\t  rb_w32_connect, rb_w32_getpeername, rb_w32_getsockname,\n\t  rb_w32_getsockopt, rb_w32_ioctlsocket, rb_w32_listen, rb_w32_recv,\n\t  rb_w32_recvfrom, rb_w32_send, rb_w32_sendto, rb_w32_setsockopt,\n\t  rb_w32_shutdown, rb_w32_socket, rb_w32_gethostbyaddr,\n\t  rb_w32_gethostbyname, rb_w32_gethostname, rb_w32_getprotobyname,\n\t  rb_w32_getprotobynumber, rb_w32_getservbyname, rb_w32_getservbyport):\n\t  need to protect WSAGetLastError() by RUBY_CRITICAL. [ruby-talk:51778]\n\nSat Sep 28 20:06:36 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* keywords: add braces around initializers.\n\nSat Sep 28 13:19:29 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* hash.c (rb_hash_become): should check self-assignment after\n\t  conversion.\n\nSat Sep 28 10:40:44 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_become): Hash#become should check added\n\t  self-assignment.\n\n\t* class.c (rb_make_metaclass): metaclass of a superclass may be\n\t  NULL at boot time.\n\nSat Sep 28 09:50:03 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* ext/extmk.rb: The condition judgment without necessity was deleted.\n\nFri Sep 27 18:40:42 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_deadlock): more verbose message at deadlock.\n\n\t* eval.c (rb_thread_schedule): ditto.\n\n\t* eval.c (rb_thread_join): ditto.\n\nFri Sep 27 13:24:35 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): Class#inherited should be called after the\n\t  execution of the class body.\n\nFri Sep 27 02:41:53 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/sha1: Use OpenSSL's SHA1 engine if available.  It is\n\t  much faster than what we have now (sha1.[ch]).  Add a knob\n\t  (--with-bundled-sha1) to extconf.rb which makes it use the\n\t  bundled one anyway.\n\nFri Sep 27 02:25:14 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/rmd160: Use OpenSSL's RMD160 engine if available.  It\n\t  is much faster than what we have now (rmd160.[ch]).  Add a knob\n\t  (--with-bundled-rmd160) to extconf.rb which makes it use the\n\t  bundled one anyway.\n\nFri Sep 27 01:23:39 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/md5: Use OpenSSL's MD5 engine if available.  It is\n\t  much faster than what we have now (md5.[ch]).  Add a knob\n\t  (--with-bundled-md5) to extconf.rb which makes it use the\n\t  bundled one anyway.\n\nThu Sep 26 22:44:21 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/digest.c (rb_digest_base_s_digest): Fix a double\n\t  free() bug mingled with allocation framework deployment.\n\n\t* ext/digest/digest.c (rb_digest_base_s_hexdigest): Get rid of\n\t  redundant struct allocation.\n\nThu Sep 26 09:52:52 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (primary): remove \"return outside of method\" check at\n\t  compile time.\n\nWed Sep 25 23:51:29 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dir.c (glob_helper): must not closedir() when exception raised\n\t  while globbing \"**\".\n\n\t* marshal.c (w_uclass): unused variable.\n\n\t* re.c (match_clone): unused.\n\n\t* regex.c (re_compile_pattern): get rid of implicit promotion from\n\t  plain char to int.\n\nWed Sep 25 17:46:46 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* lib/mkmf.rb (libpathflag): restore ENV['LIB'] when some error\n\t  occurred.\n\nWed Sep 25 16:14:51 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match): p1 may exceed pend limit.\n\nMon Sep 23 23:22:43 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_call0): must not clear ruby_current_node, or\n\t  backtrace cannot be generated.\n\n\t* intern.h (ruby_yyparse): rather than yyparse().\n\n\t* parse.y (yylex): nextc() returns -1 at end of input, not 0.\n\n\t* parse.y (newline_node): reduce duplicated newline node.\n\n\t* parse.y (literal_concat): get rid of warning.\n\n\t* parse.y (new_evstr): fixed junk code.\n\nMon Sep 23 19:57:52 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (RUBY_MINGW32): new macro. check for the MinGW\n\t  compiler environment.\n\n\t* lib/mkmf.rb: refactoring.\n\nMon Sep 23 08:27:11 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* io.c (appendline): forget to terminate with nul.\n\nMon Sep 23 02:46:29 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_run): should set toplevel visibility again here.\n\n\t* eval.c (rb_eval): should not rely on ruby_class == rb_cObject\n\t  check.   Besides allow implicit publicity for attribute set\n\t  methods.\n\n\t* parse.y (primary): need not to check class_nest, just set\n\t  whether method is an attrset or not.\n\nSun Sep 22 21:49:42 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (call_trace_func): should not call trace function while\n\t  compilation.\n\n\t* eval.c (rb_call0): also inside c-func.\n\n\t* parse.y (yycompile): ditto.\n\n\t* ruby.c (require_libraries): preserve source file/line for each\n\t  require.\n\nSun Sep 22 17:08:11 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* string.c (rb_str_each_line): p might be at the top of the\n\t  string.\n\nSat Sep 21 23:28:28 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_make_metaclass): class of metaclass should be\n\t  metaclass of superclass, unless class itself is a metaclass;\n\t  class of metaclass of metaclass should point back to self.\n\t  eh, confusing, isn't it.\n\n\t* class.c (rb_singleton_class): check if its class is singleton\n\t  AND attached to self.\n\nSat Sep 21 22:23:41 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_raise): no need to save dead thread context.\n\t  [ruby-dev:18322]\n\nFri Sep 20 23:02:01 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (block_append): eliminate unused literal nodes.\n\n\t* parse.y (literal_concat): refined literal concatenation.\n\nFri Sep 20 19:43:40 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: Merge rough/lib/set.rb rev.1.5-1.15.\n\nWed Sep 18 12:41:16 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should define class/module under ruby_cbase.\n\n\t* eval.c (rb_eval): should set class/module path based on\n\t  ruby_cbase, not ruby_class.\n\n\t* eval.c (module_setup): use ruby_cbase instead of ruby_class.\n\nTue Sep 17 21:06:04 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_die): put thread dead state.\n\n\t* eval.c (rb_thread_atfork): free stack buffer at fork too.\n\nTue Sep 17 01:13:31 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_nesting): load wrapping module should appear in\n\t  Module#nesting list. (ruby-bugs-ja:PR#328)\n\n\t* eval.c (rb_thread_remove): free stack buffer on remove.\n\nTue Sep 17 00:58:35 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* io.c: add parameter prototype.\n\n\t* re.c: ditto.\n\nSun Sep 15 21:14:22 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* win32/win32.c (rb_w32_opendir, rb_w32_stat): Corresponds to\n\t  the unjust path containing \".\n\nSun Sep 15 19:48:55 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (OUTFLAG, CPPOUTFILE): moved from lib/mkmf.rb.\n\t  check whether ${CPP} accepts the -o option.\n\n\t* win32/Makefile.sub (OUTFLAG, CPPOUTFILE): ditto.\n\n\t* bcc32/Makefile.sub (OUTFLAG, CPPOUTFILE): ditto.\n\n\t* djgpp/config.sed (OUTFLAG, CPPOUTFILE): ditto.\n\n\t* lib/mkmf.rb (OUTFLAG, CPPOUTFILE): use CONFIG.\n\t  make easy to understand log.\n\n\t* mkconfig.rb (val): should not strip.\n\nSat Sep 14 20:13:42 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* error.c(rb_sys_fail): remove case EPIPE on bcc32 .\n\nFri Sep 13 23:39:49 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dir.c (glob_func_caller): add prototype to get rid of warning.\n\nFri Sep 13 18:35:12 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): avoid uninitialized global/class variable\n\t  warnings at `||='.  [ruby-dev:18278]\n\n\t* parse.y (stmt, arg): ditto\n\nFri Sep 13 13:28:04 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb ($INSTALLFILES): avoid warning when $VERBOSE mode.\n\nThu Sep 12 23:20:10 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/setup.mak    : Control of a message.\n\n\t* bcc32/makefile.sub : include resource.\n\nThu Sep 12 18:10:03 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dir.c (glob_helper): fixed freeing buffer.  (ruby-bugs-ja:PR#332)\n\n\t* dir.c (glob_helper): should pass matched path.  (ruby-bugs-ja:PR#333)\n\nThu Sep 12 00:09:32 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_trap_eval): preserve thread status and so on.\n\t  [ruby-talk:40337], [ruby-core:00019]\n\nWed Sep 11 21:25:52 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* pp.rb (ARGF.pretty_print): implemented.\n\t  (PP.pp): arguments reordered.\n\nWed Sep 11 18:55:38 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (proc_to_s): refined format.  [ruby-dev:18215]\n\nWed Sep 11 17:47:17 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c, win32/win32.h (rb_w32_getpid): negate pid under Win9x.\n\t  [ruby-dev:18262]\n\nWed Sep 11 12:58:57 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* string.c (get_pat): Add an extra argument \"quote\".\n\n\t* string.c (rb_str_match_m): Do not bother to convert if a regexp\n\t  is given.\n\nWed Sep 11 11:33:40 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub: remove unnecessary `.dll' from filename of\n\t  dll's resource file.\n\n\t* cygwin/GNUmakefile.in: ditto. [ruby-dev:17103]\n\n\t* win32/Makefile.sub: ditto. [ruby-dev:17103]\n\n\t* win32/resource.rb: ditto. [ruby-dev:17103]\n\nWed Sep 11 09:59:46 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (rb_io_wait_readable): added.\n\n\t* io.c (rb_io_wait_writable): added.\n\n\t* io.c (io_read_retryable): added.\n\n\t* io.c (io_write): retry on EINTR, ERESTART and EWOULDBLOCK.\n\t  [ruby-dev:17855], [ruby-dev:17878], [ruby-core:00444]\n\n\t* io.c (rb_io_fread): ditto.\n\n\t* io.c (read_all): ditto.\n\n\t* io.c (appendline): ditto.\n\n\t* io.c (rb_io_each_byte): ditto.\n\n\t* io.c (rb_io_getc): ditto.\n\nWed Sep 11 09:29:24 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (ext): make directory `ext' on compile dir.\n\t  [ruby-dev:18255]\n\nWed Sep 11 00:41:10 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_mod_define_method): initialize orig_func too.\n\t  (ruby-bugs-ja:PR#330)\n\nWed Sep 11 00:01:32 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (glob_helper): prevent memory leak using rb_protect().\n\n\t* string.c (rb_str_associate): no need to check freeze flag.\n\n\t* string.c (rb_str_resize): should honor STR_ASSOC flag on\n\t  resize.\n\n\t* string.c (rb_str_resize): proper STR_ASSOC handling.  pointed\n\t  out by Michal Rokos.\n\n\t* string.c (rb_str_buf_cat): ditto.\n\n\t* string.c (rb_str_cat): ditto.\n\n\t* string.c (rb_str_buf_append): ditto.\n\n\t* string.c (rb_str_append): ditto.\n\nTue Sep 10 23:35:46 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (nextc): restore line number after here documents.\n\t  (ruby-bugs-ja:PR#331)\n\n\t* parse.y (heredoc_restore): ditto.\n\nTue Sep 10 18:26:52 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb, lib/mkmf.rb ($INCFLAGS): new var for -I$(topdir).\n\n\t* lib/mkmf.rb: add #define WIN32_LEAN_AND_MEAN to improve compile\n\t  times.\n\nTue Sep 10 17:16:14 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (miniruby): shouldn't link $(EXTOBJS).\n\t  [ruby-dev:17059]\n\n\t* win32/Makefile.sub ($(LIBRUBY_A), $(LIBRUBY)): avoid lib.exe's\n\t  warning. [ruby-dev:17059]\n\n\t* win32/Makefile.sub: remove unnecessary rules. [ruby-dev:17059]\n\n\t* win32/configure.bat, win32/setup.mak, win32/README.win32: enable to\n\t  pass some arguments to configure. [ruby-dev:17059]\n\nMon Sep  9 23:43:33 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.h (S_I?USR): define only if not mingw32.\n\nMon Sep  9 11:21:04 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/stringio/stringio.c (strio_set_string): reinitialize\n\t  properly.\n\n\t* ext/stringio/stringio.c (strio_become): added self-assign check\n\t  and experimental auto-conversion to StringIO.\n\n\t* ext/stringio/stringio.c (strio_reopen): added.\n\n\nSun Sep  8 21:29:25 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* time.c (time_free): prototype; struct time_object -> void *.\n\t  avoid GCC warnings.\n\n\t* lib/mkmf.rb, ext/extmk.rb ($LINK, $CPP): move to lib/mkmf.rb.\n\nSun Sep  8 19:02:28 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* time.c: prototype; time_free() to avoid VC++ warnings.\n\n\t* ext/tcltklib/tcltklib.c: prototype; invoke_queue_handler() to avoid\n\t  VC++ warning.\n\n\t* win32/win32.c (rb_w32_stat): remove S_IWGRP and S_IWOTH bits from\n\t  st_mode.\n\n\t* win32/win32.h (S_I*): define if not defined.\n\nSun Sep  8 14:38:31 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: modify program_prefix only if specified\n\t  --program-prefix.\n\n\t* configure.in: don't generate ext/extmk.rb.\n\n\t* Makefile.in: execute directly $(srcdir)/ext/extmk.rb.\n\t  remove -Cext option, \"Dir::chdir 'ext'\" in ext/extmk.rb.\n\n\t* {win32,bccwin32}/Makefile.sub: ditto.\n\n\t* instruby.rb: ditto.\n\n\t* ext/extmk.rb: renamed from ext/extmk.rb.in.\n\n\t* lib/mkmf.rb (module Logging): create log files (mkmf.log)\n\t  in each extension module directories.\n\n\t* ext/extmk.rb: ditto.\n\n\t* lib/mkmf.rb (macro_defined?): new method.\n\n\t* ext/.cvsignore: remove extmk.rb.\n\n\t* ext/*/.cvsignore: add \"*.def\".\n\n\t* lib/mkmf.rb (have_struct_member): moved from ext/socket/extconf.rb.\n\n\t* ext/socket/extconf.rb: use macro_defined? instead of egrep_cpp.\n\n\t* ext/etc/extconf.rb: use have_struct_member.\n\n\t* ext/etc/etc.c: add prefix HAVE_ST_ to PW_ macros.\n\nSun Sep  8 14:36:40 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/configure.bat : Control of a message.\n\t* bcc32/makefile.sub  : @(sitearch) typo.\n\t* ext/extmk.rb.in     : [bccwin32] libdir is added to a library path.\n\t* lib/mkmf.rb         : ditto.\n\nSat Sep  7 23:32:56 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp\n\t  alist for error message from ruby.\n\n\t* misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs.\n\n\t* misc/inf-ruby.el (ruby-send-region): compilation-parse-errors\n\t  doesn't parse first line, so insert separators before each\n\t  evaluations.\n\nSat Sep  7 19:46:57 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: Disallow Set.new(false).  Add even more tests.\n\t  [Submitted by: \"Christoph\" <chr_news@gmx.net>]\n\nSat Sep  7 19:23:56 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: Fix a bug in flatten()'s recursive set detection.\n\t  [Submitted by: \"Christoph\" <chr_news@gmx.net>]  Some tests\n\t  against the bug are added.\n\n\t* lib/set.rb: Resurrect the test suite by putting it after\n\t  __END__ and executing `eval DATA.read'.\n\nSat Sep  7 08:41:39 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (rb_gc_mark_parser): ruby_eval_tree is marked in eval.c.\n\nFri Sep  6 20:01:38 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/mkmf.rb ($CC): command to compile C source.\n\n\t* lib/mkmf.rb (logging): added.\n\n\t* lib/mkmf.rb (try_compile): added.\n\n\t* lib/mkmf.rb (egrep_cpp): use internal grep when pattern is\n\t  Regexp, otherwise use external egrep command but get rid of\n\t  pipe of command.com.\n\n\t* lib/mkmf.rb (have_func): local variable should be volatile not\n\t  to be eliminated by optimization.\n\n\t* lib/mkmf.rb (create_makefile): link with CONFIG[\"LIBS\"].\n\n\t* lib/mkmf.rb (create_makefile): emit .SUFFIXES:.\n\nFri Sep  6 12:11:22 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (rb_gc_mark_parser): should mark ALL global variables\n\t  defined in parse.y.\n\nFri Sep  6 01:15:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (ruby_xmalloc): remove MALLOC_LIMIT to avoid frequent\n\t  garbage collection.\n\nFri Sep  6 11:47:37 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (rb_gc_mark_parser): should mark global variables\n\t  defined in parse.y.\n\nFri Sep  6 10:34:32 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* io.c (rb_io_puts): RSTRING(line)->ptr might be NULL.\n\nFri Sep  6 10:26:37 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y: should not put non-NODE-VALUEs in the semantic stack.\n\nFri Sep  6 05:48:26 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* file.c (rb_path_check): nothing to check under DOSISH.\n\t  [ruby-list:35772]\n\nFri Sep  6 05:03:50 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* gc.c (rb_gc): should mark parser.\n\n\t* parse.y (rb_gc_mark_parser): new function.\n\n\t* intern.h (rb_gc_mark_parser): added.\n\nThu Sep  5 18:32:32 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_path2class): should not use rb_eval_string().\n\nThu Sep  5 17:18:22 2002  Michal Rokos  <michal@ruby-lang.org>\n\n\t* dln.c: fix memory leak in dln_load (ruby-core:405) and\n\t  in load_1 (ruby-core:407)\n\nThu Sep  5 15:43:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_extended): should allow marshaling of object which\n\t  is extended by named module.\n\n\t* class.c (rb_make_metaclass): super may be T_ICLASS, need to skip.\n\nThu Sep  5 13:09:22 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): overriding false constant with class/module\n\t  definition should be error.  (PR#327)\n\nThu Sep  5 01:24:26 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* extmk.rb (create_makefile): add macro MAKEDIRS, INSTALL_PROG,\n\t  INSTALL_DATA.\n\n\t* extmk.rb (create_makefile): support for building to any directory.\n\n\t* extmk.rb (xsystem): move to mkmf.rb.\n\n\t* mkmf.rb (xsystem): support for extmk.rb\n\n\t* mkmf.rb ($CPP): remove '-E' option.  add CPPFLAGS.\n\nWed Sep  4 16:15:17 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: ==(o) should be aware of all the Set variant\n\t  instances, not just those of its subclasses. [Submitted by:\n\t  \"Christoph\" <chr_news@gmx.net>]\n\n\t* lib/set.rb: - Fix eql?(). [ditto]\n\nWed Sep  4 15:23:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_make_metaclass): obj.meta.super.meta should be equal\n\t  to obj.meta.meta.super (ruby-bugs-ja:PR#324).\n\nWed Sep  4 05:10:16 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* parse.y (yylex): the warning message \"invalid\n\t  character syntax\" was never issued (ruby-bugs-ja:PR#323).\n\nWed Sep  4 01:08:45 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_bytes): do not use alloca (ruby-bugs:PR#382).\n\nTue Sep  3 17:12:59 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* extmk.rb: require mkmf.rb.  remove duplicate methods.\n\t  use Config::CONFIG[\"FOO\"] instead of @FOO@.\n\n\t* mkmf.rb: support for extmk.rb.\n\nMon Sep  2 23:01:50 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* re.c (rb_reg_search): MatchData must be rb_cMatch.\n\t  (ruby-bugs-ja:PR#319)\n\nMon Sep  2 21:21:46 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* gc.c (gc_sweep): does reclaim nodes in also compile time, if we\n\t  can.\n\n\t* ruby.c (load_file): omit GC if we can.\n\n\t* parse.y (ruby_parser_stack_on_heap): new function.\n\n\t* intern.h (ruby_parser_stack_on_heap): added.\n\nMon Sep  2 18:45:07 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_copy_generic_ivar): remove old generic instance\n\t  variable table if it exists.\n\nSun Sep  1 15:54:33 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* config.guess: fixed for Linux/PPC.\n\nSat Aug 31 09:38:12 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_make_metaclass): metaclass of a metaclass is a\n\t  metaclass itself.\n\nFri Aug 30 22:45:16 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/set.rb: Added.\n\nFri Aug 30 20:58:54 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* ext/Win32API/Win32API.c (Win32API_Call): typo.\n\nFri Aug 30 19:45:52 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* variable.c (rb_const_assign): st_delete() takes pointer to key.\n\nFri Aug 30 19:40:28 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/Win32API/Win32API.c (Win32API_Call): RSTRING()->ptr may be\n\t  NULL.\n\n\t* ext/nkf/nkf.c (rb_nkf_guess): ditto.\n\n\t* ext/readline/readline.c (readline_s_set_completion_append_character):\n\t  ditto.\n\n\t* ext/socket/socket.c (sock_s_getaddrinfo, sock_s_getnameinfo):\n\t  ditto.\n\n\t* ext/tcltklib/tcltklib.c (ip_toUTF8, ip_fromUTF8): ditto.\n\nFri Aug 30 01:32:17 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_singleton_class): superclass of a metaclass\n\t  should be a metaclass of superclass.\n\n\t* range.c (range_eq): two instances must belong to a same class to\n\t  be equal.\n\n\t* range.c (range_eql): ditto.\n\n\t* io.c (rb_io_taint_check): frozen check added.\n\n\t* file.c (rb_stat_become): frozen check added.\n\n\t* object.c (rb_obj_become): ditto.\n\n\t* re.c (rb_reg_become): ditto.\n\n\t* struct.c (rb_struct_become): ditto.\n\n\t* time.c (time_become): ditto.\n\n\t* array.c (rb_ary_become): should call rb_ary_modify().\n\n\t* hash.c (rb_hash_become): should call rb_hash_modify().\n\n\t* compar.c (cmp_equal): should not use NUM2LONG(), since <=> may\n\t  return bignum.\n\n\t* compar.c (cmp_gt, cmp_ge, cmp_lt, cmp_le, cmp_between): ditto.\n\nThu Aug 29 23:34:42 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/MakeFile.sub (sitearch): add.\n\nThu Aug 29 13:36:42 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (read_all): should use off_t instead of long.\n\nThu Aug 29 00:55:55 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* marshal.c (r_object): yield loaded objects, not intermediates.\n\t  (ruby-bugs-ja:PR#296)\n\nThu Aug 29 00:06:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_become): should not free ptr if it's shared.\n\n\t* eval.c (rb_alias): prohibit making an alias named \"allocate\" if\n\t  klass is a metaclass.\n\nWed Aug 28 23:59:15 2002  Michal Rokos  <michal@ruby-lang.org>\n\n\t* signal.c: remove #ifdef SIGINT for struct signals.\n\n\t* variable.c: get rid of fix length buffer in rb_class_path.\n\nWed Aug 28 23:34:32 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (appendline): data was lost when raw mode.\n\nWed Aug 28 22:57:34 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_string_value_ptr): StringValuePtr() should never\n\t  return NULL pointer.\n\nWed Aug 28 19:12:46 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/stringio/stringio.c (strio_initialize): RSTRING(mode)->ptr\n\t  can be NULL.\n\n\t* ext/stringio/stringio.c (strio_ungetc): fix buffer overflow.\n\nWed Aug 28 18:19:55 2002  Michal Rokos  <michal@ruby-lang.org>\n\n\t* file.c: fix memory leak in rb_stat_init.\n\nWed Aug 28 17:45:03 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/win32.c (kill): negate pid under Win9x.\n\nWed Aug 28 16:36:40 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (ar): don't check ar twice.\n\nWed Aug 28 15:00:29 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_delete_bang): should check if str->ptr is 0.\n\n\t* string.c (rb_str_squeeze_bang): ditto.\n\n\t* string.c (rb_str_count): ditto.\n\n\t* string.c (rb_str_lstrip_bang): ditto.\n\n\t* string.c (rb_str_rstrip_bang): ditto.\n\n\t* string.c (rb_str_intern): ditto.\n\nWed Aug 28 11:37:35 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.h: define SIGINT and SIGKILL if not defined.\n\n\t* win32/win32.c: remove definition of SIGINT and SIGKILL.\n\nTue Aug 27 19:50:27 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ruby.c (require_libraries): prevent ruby_sourcefile from GC.\n\nTue Aug 27 15:03:35 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_find_file): $LOAD_PATH must not be empty.\n\n\t* file.c (rb_find_file_ext): ditto.\n\nTue Aug 27 02:35:21 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_eq): class check should be based on range.class,\n\t  instead of Range to work with Range.dup.\n\n\t* range.c (range_eql): ditto.\n\nMon Aug 26 18:17:56 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_mod_dup): need to preserve metaclass and flags.\n\nMon Aug 26 10:44:18 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* object.c (rb_cstr_to_dbl): had a buffer overrun.\n\nSun Aug 25 20:10:32 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI#form): fix ruby-bugs-ja:PR#280, add default action.\n\nSat Aug 24 15:32:16 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (call_trace_func): restore source file/line, as trace\n\t  function installed in required library with -r option can be\n\t  called while parsing.  (ruby-bugs:PR#372)\n\n\t* eval.c (module_setup): unused variable.  [ruby-core:00358]\n\nSat Aug 24 14:59:02 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_class): integrate singleton check into a function\n\t  to follow DRY principle.\n\n\t* marshal.c (w_uclass): should check singleton method.\n\n\t* object.c (rb_obj_dup): dmark and dfree functions must be match\n\t  for T_DATA type.\n\n\t* object.c (rb_obj_dup): class of the duped object must be match\n\t  to the class of the original.\n\nSat Aug 24 13:57:28 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb (Time.rfc2822, Time#rfc2822): preserve localtimeness.\n\n\t* lib/pp.rb: pretty_print_cycled is renamed to pretty_print_cycle.\n\nFri Aug 23 23:59:57 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (method_call): check receiver is defined.\n\n\t* eval.c (umethod_call): removed.\n\nFri Aug 23 23:39:17 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_quote): do not escape \\t, \\f, \\r, \\n, for they are\n\t  not regular expression metacharacters.\n\n\t* time.c (time_s_alloc): use time_free instead of free (null check,\n\t  also serves for type mark).\n\n\t* time.c (time_s_at): check dfree function too.\n\nFri Aug 23 17:06:48 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: RUBY_SO_NAME is msvcrt-rubyXX on mswin32/mingw32.\n\n\t* configure.in (sitearch): new var.\n\n\t* mkconfig.rb, lib/mkmf.rb (sitearch): ditto.\n\n\t* win32/Makefile.sub, win32/setup.mak (sitearch): ditto.\n\n\t* instruby.rb: ditto.\n\nWed Aug 21 16:53:00 2002  Michal Rokos  <michal@ruby-lang.org>\n\n\t* *.c: int, long types cleanup.\n\n\t* parse.y: ditto.\n\n\t* re.h, regex.h, ruby.h: ditto.\n\nWed Aug 21 16:43:19 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_cleanup): should not modify the global\n\t  variable curr_thread.\n\nWed Aug 21 16:14:26 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: set ac_cv_func__setjmp to \"no\" on Cygwin.\n\n\t* configure.in: set ac_cv_func_crypt to \"no\" on MinGW.\n\nTue Aug 20 21:47 2002  KONISHI Hiromasa  <konishih@fd6.so-net.ne.jp>\n\n\t* io.c          (rb_io_fread): remove case EPIPE on bcc32 .\n\n\t* win32/win32.c (rb_w32_getc): clear EPIPE error on bcc32.\n\nTue Aug 20 19:39:03 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (rb_file_s_expand_path): accept drive letter on Cygwin.\n\n\t* file.c (is_absolute_path): ditto.\n\nTue Aug 20 12:12:25 2002  Tietew <tietew@tietew.net>\n\n\t* io.c (rb_io_putc): output via rb_io_write().\n\nMon Aug 19 19:01:55 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition\n\t  conflicted with ruby-insert-end.\n\n\t* misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode.\n\n\t* misc/inf-ruby.el (ruby-send-region): send as here document to\n\t  adjust source file/line.  [ruby-talk:47113], [ruby-dev:17965]\n\n\t* misc/inf-ruby.el (ruby-send-terminator): added to make unique\n\t  terminator.\n\nMon Aug 19 17:08:19 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_initialize_m): frozen check should be moved here\n\t  from rb_reg_initialize().\n\nMon Aug 19 15:38:44 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (sort_2): comparison should be done as signed long.\n\n\t* array.c (sort_2): should return int, not VALUE.\n\nMon Aug 19 12:38:33 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_save_context, rb_thread_restore_context):\n\t  save/restore SEH chain on MS-Windows at thread switch.\n\t  [ruby-win32:273]\n\n\t* eval.c (win32_get_exception_list, win32_set_exception_list):\n\t  added.\n\nSat Aug 17 23:01:25 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (sort_2): *a - *b may overflow.\n\nSat Aug 17 00:25:08 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (ary_new): len*sizeof(VALUE) may be a positive value.\n\n\t* array.c (rb_ary_initialize): ditto.\n\nFri Aug 16 15:58:16 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (NOFILE): define NOFILE as 64 if not defined.\n\n\t* signal.c (sighandler_t): rename to sh_t on dietlibc.\n\nFri Aug 16 15:37:04 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bignum.c (rb_cstr_to_inum): new decimal and octal string.\n\nFri Aug 16 13:17:11 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_class_allocate_instance): move singleton class\n\t  check from rb_obj_alloc().\n\nFri Aug 16 11:47:24 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (rb_io_fread): renamed from io_fread and made extern.\n\n\t* marshal.c (r_bytes0): check if successfully read, use\n\t  rb_io_fread() instead of fread() to be preemptive.\n\t  (ruby-bugs-ja:PR#294, 295)\n\n\t* rubyio.h (rb_io_fread): added.\n\nFri Aug 16 07:57:26 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (compile_error): must not clear ruby_sourcefile here.\n\t  (ruby-bugs:PR#364).\n\n\t* eval.c (rb_longjmp): set ruby_sourcefile before making\n\t  backtrace.\n\nThu Aug 15 20:38:58 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (ruby_current_node) : added to set sourceline on demand.\n\n\t* eval.c (error_pos, error_print, rb_longjmp, assign): set source\n\t  file/line.\n\n\t* eval.c (rb_eval): store current node instead of file/line, and\n\t  preserve it at return.\n\n\t* eval.c (module_setup): ditto.\n\n\t* eval.c (struct thread): store node instead of file/line.\n\n\t* eval.c (rb_thread_raise): ditto.\n\n\t* intern.h (ruby_current_node): added.\n\n\t* intern.h (ruby_set_current_source): added.\n\n\t* parse.y (stmt, arg): not fix position of assignment.\n\n\t* parse.y (node_assign): ditto.\n\n\t* parse.y (yycompile): clear current node.\n\nThu Aug 15 00:48:46 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_initialize): should not modify frozen Regexp.\n\nTue Aug 13 18:33:18 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/tcltklib/tcltklib.c (ip_init): allocation framework.\n\nTue Aug 13 15:32:14 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_replace): should copy ifnone.\n\n\t* hash.c (rb_hash_dup): should preserve HASH_PROC_DEFAULT and\n\t  HASH_DELETED flags.\n\n\t* hash.c (rb_hash_shift): shift from empty hash should not return\n\t  its default proc.\n\n\t* hash.c (rb_hash_default_proc): new method. [new]\n\nTue Aug 13 00:37:11 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_aref): no need for Bignum check.\n\n\t* array.c (rb_ary_aset): explicit Bignum check removed.\n\n\t* numeric.c (fix_aref): normalize bignum before bit-op.\n\n\t* bignum.c (rb_big_rand): max may be Bignum zero.\n\n\t* bignum.c (rb_cstr_to_inum): should normalize bignums, to avoid\n\t  returning fixable bignum value.\n\n\t* bignum.c (rb_uint2big): there should be no zero sized bignum.\n\nMon Aug 12 23:45:28 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/extmk.rb.in: extmake() that works properly for both tkutil\n\t  (tk/tkutil.so) and digest/sha1.\n\nMon Aug 12 22:29:35 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.c (set_arg0): Correct the position of #endif.\n\nMon Aug 12 17:25:06 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_equal): should check HASH_PROC_DEFAULT too.\n\nMon Aug 12 16:15:37 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* bignum.c (rb_big_cmp): raise for NaN.  (ruby-bugs-ja:PR#284).\n\nSun Aug 11 09:34:07 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): set line number from all nodes.\n\n\t* eval.c (proc_to_s): show source file/line if available.\n\n\t* marshal.c (r_object): register TYPE_BIGNUM regardless real type.\n\nSat Aug 10 23:47:16 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_cmp): use dbl2big() for Floats, instead of\n\t  big2dbl().\n\n\t* bignum.c (Init_Bignum): rb_big_zero_p() removed.  There may be\n\t  Bignum zero.\n\nFri Aug  9 13:31:40 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/Win32API/extconf.rb: check existence of <windows.h>.\n\nThu Aug  8 09:37:02 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (NilClass): must provide conversion block.\n\n\t* lib/optparse.rb (String): ditto.\n\nThu Aug  8 00:45:15 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): new argument added for original method name.\n\t  preserve original method name in frame->orig_func.\n\n\t* eval.c (is_defined): use frame->orig_func, not last_func.\n\n\t* eval.c (rb_eval): ditto.\n\n\t* eval.c (method_call): supply data->oid also to rb_call0().\n\n\t* object.c (rb_class_allocate_instance): call rb_obj_alloc() when\n\t  called from alias, thus invoke original \"allocate\".\n\n\t* eval.c (remove_method): removing allocate from classes should\n\t  cause NameError.\n\nWed Aug  7 22:12:54 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/optparse.rb (OptionParser::Completion::convert): returned\n\t  all values not first one.\n\n\t* lib/optparse.rb (OptionParser::Switch::parse): return values as\n\t  is.\n\n\t* lib/optparse.rb (OptionParser::order): ditto.\n\n\t* lib/optparse/time.rb: prior time.rb.\n\n\t* lib/optparse/uri.rb: require standard uri module.  thanks to\n\t  Minero Aoki.\n\nWed Aug  7 09:51:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_equal): should check default values.\n\nWed Aug  7 08:44:32 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/racc/cparse/cparse.c: reduce goto.\n\nTue Aug  6 15:19:39 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* string.c (rb_str_rindex): must return -1 if unmatched.\n\nMon Aug  5 22:41:18 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* MANIFEST: add lib/racc/parser.rb.\n\n\t* ext/racc/cparse/cparse.c: code refine.\n\n\t* ext/racc/cparse/MANIFEST: add depend.\n\nSun Aug  4 22:30:50 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/curses/curses.c: follow allocation framework.\n\nSat Aug  3 21:23:56 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): set constant in cbase scope.\n\n\t* eval.c (assign): ditto.\n\nFri Aug  2 09:12:32 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: follow allocation framework.\n\nFri Aug  2 01:21:52 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (s_recvfrom): update RSTRING len.\n\nThu Aug  1 17:47:15 2002  Tachino Nobuhiro <tachino@jp.fujitsu.com>\n\n\t* parse.y (tokadd_string): ignore backslashed spaces in %w.\n\nThu Aug  1 14:14:15 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_find): do not use rb_eval_cmd(); should not accept\n\t  a string for if_none.\n\nWed Jul 31 14:11:43 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_undef): undef should be done for klass, not ruby_class.\n\nTue Jul 30 19:48:51 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-accurate-end-of-block): restrict search\n\t  region.\n\n\t* misc/ruby-mode.el (ruby-parse-partial): reversed wrong patch.\n\nTue Jul 30 17:21:13 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-accurate-end-of-block): incomplete block\n\t  caused infinite loop.\n\n\t* misc/ruby-mode.el (ruby-parse-partial): returns nil unless\n\t  delimiters found.\n\nTue Jul 30 15:24:07 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/tcltklib/stubs.c (ruby_tcltk_stubs): win32_getenv returns\n\t  the same address always, so allocate string by ruby_strdup.\n\n\t* win32/win32.c: prototype; rb_w32_open_osfhandle().\n\nTue Jul 30 09:11:07 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (rb_thread_join_m): add parameter type declaration.\n\nTue Jul 30 08:37:11 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (localjump_error): add parameter type declaration.\n\nMon Jul 29 16:00:54 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in: always use File.expand_path for $top_srcdir.\n\nSat Jul 27 23:07:52 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_to_int): default to_int implementation for every\n\t  numeric class.\n\nSat Jul 27 08:09:03 2002  Booker C. Bense  <bbense@slac.stanford.edu>\n\n\t* re.c (rb_reg_quote): initial part of the string was never copied\n\t  to the quoted string.\n\nFri Jul 26 23:03:53 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): no need to convert to string twice.\n\nFri Jul 26 18:32:37 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-expr-beg): wrong indent at modifiers\n\t  after ?.\n\nFri Jul 26 16:01:16 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in (create_makefile): use Regexp in gsub.\n\n\t* sample/mkproto.rb: ditto and fix bug.\n\nFri Jul 26 14:31:06 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* random.c: replace with Mersenne Twister RNG.\n\nFri Jul 26 12:14:48 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (yylex): modify to accept a code like \"m (a){...}\".\n\nThu Jul 25 09:05:02 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-delimiter): include here document.\n\n\t* misc/ruby-mode.el (ruby-deep-arglist): skips spaces after\n\t  parenthesis when 'space.\n\n\t* misc/ruby-mode.el (ruby-imenu-create-index): fix for nested\n\t  classes.\n\n\t* misc/ruby-mode.el (ruby-accurate-end-of-block): added.  scan a\n\t  block in the order.\n\n\t* misc/ruby-mode.el (ruby-expr-beg): support for here document.\n\n\t* misc/ruby-mode.el (ruby-parse-partial): splitted from\n\t  ruby-parse-region.\n\n\t* misc/ruby-mode.el (ruby-move-to-block): skips RD style comments.\n\nWed Jul 24 09:47:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (jump_tag_but_local_jump): preserve retval in\n\t  LocalJumpError exceptions.\n\n\t* parse.y (command): no more check for \"super outside of method\".\n\n\t* eval.c (rb_mod_define_method): should set last_class and\n\t  last_func in the block->frame.\n\nMon Jul 22 17:23:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (error_handle): should handle TAG_THROW as well.\n\nFri Jul 19 10:52:32 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): new decimal notation '0d4567'.\n\nThu Jul 18 11:52:02 2002  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (set_socket): new method.\n\nThu Jul 18 06:51:24 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (yylex): fix typo.\n\nWed Jul 17 18:41:28 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): new octal notation '0o777'.\n\nMon Jul 15 18:36:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (string_content): every string_content node should\n\t  return string only.  use NODE_EVSTR to coercing.\n\n\t* eval.c (rb_eval): NODE_EVSTR support.\n\nMon Jul 15 10:35:35 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (heredoc_identifier): fix typo.\n\nSat Jul 13 09:30:04 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (literal_concat_string): wrong optimization.\n\nSat Jul 13 01:25:38 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/resolv.rb (Resolv::DNS::open, close): new.\n\n\t* lib/optparse.rb, lib/optparse: import.\n\nFri Jul 12 06:34:05 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: rename HTTP.get_uri get_response.\n\n\t* lib/net/http.rb: HTTP.get_print accepts URI objects.\n\n\t* lib/net/http.rb: HTTP.get had not work with URI objects.\n\nFri Jul 12 02:15:58 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* string.c (rb_str_match): fix for string match.\n\nFri Jul 12 00:02:50 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/stringio/stringio.c (strio_gets_internal): fixed for record\n\t  separator longer than 1.\n\nThu Jul 11 17:59:20 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_quote): avoid unnecessary string allocation.\n\n\t* string.c (get_pat): quote metacharacters before compiling a\n\t  string into a regex.\n\n\t* string.c (rb_str_split_m): special treatment of strings of size\n\t  1, but AWK emulation.  now uses get_pat().\n\n\t* string.c (rb_str_match_m): quote metacharacters.\n\n\t* string.c (rb_str_match2): ditto.\n\nThu Jul 11 12:59:23 2002  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/resolv.rb: untaint strings read from /etc/hosts and\n\t  /etc/resolv.conf to prevent SecurityError when $SAFE==1.\n\nThu Jul 11 09:00:43 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_slice_bang): if there's no corresponding\n\t  substring, slice! should return nil without exception.\n\nTue Jul  9 20:03:55 2002 Keiju Ishitsuka <keiju@ishitsuka.com>\n\n\t* irb 0.9\n\nSat Jul  6 07:35:02 2002  Jamie Herre  <jfh@gettysgroup.com>\n\n\t* array.c (rb_ary_insert): type fixed.\n\nFri Jul  5 09:17:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_split_m): accept separator value nil as well.\n\nFri Jul  5 08:59:15 2002  Michal Rokos <michal@ruby-lang.org>\n\n\t* enum.c: Fix bug in enum_sort_by and some code indents\n\nFri Jul  5 05:00:40 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI#initialize): improvement for mod_ruby.\n\t  thanks to Sean Chittenden <sean@ruby-lang.org>, Shugo Maeda\n\t  <shugo@modruby.net>\n\nFri Jul  5 00:10:09 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_become): was leaking memory.\n\nThu Jul  4 23:43:26 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y: remove useless function str_extend_p().\n\nWed Jul  3 14:26:40 2002  Sean Chittenden  <sean@ruby-lang.org>\n\n\t* lib/net/ftp.rb (get): new method.\n\n\t* lib/net/ftp.rb (putt): ditto.\n\n\t* lib/net/ftp.rb (binary): ditto.\n\n\t* lib/net/ftp.rb (binary=): ditto.\n\nWed Jul  3 13:57:53 2002  Sean Chittenden  <sean@ruby-lang.org>\n\n\t* lib/net/ftp.rb (getbinaryfile): the second argument (localfile)\n\t  is now optional.\n\n\t* lib/net/ftp.rb (gettextfile): ditto.\n\nWed Jul  3 13:45:42 2002  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb: use &block and yield for speed.\n\nWed Jul  3 02:32:31 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI#initialize): improvement for mod_ruby.\n\nTue Jul  2 14:53:10 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_include_module): should not alter other\n\t  classes/modules by inclusion.  by this fix, local order may not\n\t  be preserved for some cases.\n\n\t* class.c (include_class_new): module may be T_ICLASS; retrieve\n\t  original module information.\n\nTue Jul  2 14:13:11 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb (CGI#header): accept any type as value.\n\nSun Jun 30 17:05:29 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (seekdir, telldir): add ac_cv_func_telldir=yes,\n\t  ac_cv_func_seekdir=yes for MinGW.\n\nSat Jun 29 01:43:32 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* io.c (pipe_finalize, pipe_popen): two-way pipe support for win32.\n\n\t* win32/win32.c (ChildRecord, FindFreeChildSlot): ditto.\n\n\t* win32/win32.c, win32/win32.h (pipe_exec): new function for two-way\n\t  pipe support for win32.\n\n\t* win32/win32.c, win32/win32.h (FindPipedChildSlot, rb_w32_popen,\n\t  rb_w32_pclose): removed functions for two-way pipe support for win32.\n\nFri Jun 28 23:49:34 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* pack.c (pack_unpack): change names of local variables because their\n\t  names are overlapped.\n\nFri Jun 28 17:54:07 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb: fix object address.\n\nThu Jun 27 23:55:50 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/win32.c (rb_w32_stat): fix buffer overflow. (ruby-bugs:PR#329)\n\nThu Jun 27 20:57:45 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/prettyprint.rb, lib/pp.rb: convenience methods added.\n\nThu Jun 27 15:22:18 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/prettyprint.rb: re-implemented for incremental output to handle\n\t  huge data.  API is changed a bit.\n\n\t* lib/pp.rb: adapt new pretty printing API.\n\nThu Jun 27 08:28:18 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (literal_concat_string): non-string last expression in\n\t  #{} was ignored when followed by literal.\n\nThu Jun 27 03:42:04 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_expr_str): need to process backslashes properly.\n\nWed Jun 26 17:33:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_any_to_a): declare Object#to_a to be obsolete.\n\n\t* object.c (rb_Array): do not convert nil into [] automagically.\n\nWed Jun 26 15:40:00 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (words, qwords): word list literal rules.\n\n\t* parse.y (parse_string): ditto.\n\n\t* parse.y (yylex): %W: word list literal with interpolation. [new]\n\nTue Jun 25 18:53:34 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (string1, xstring, regexp): moved lex_strnest\n\t  initialization to string_contents/xstring_contents.\n\nTue Jun 25 19:24:38 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* dln.c: remove definition rb_loaderror().\n\nTue Jun 25 00:34:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_Integer): use \"to_int\" instead of\n\t  \"to_i\". [experimental]\n\n\t* object.c (nil_to_f): new method.\n\n\t* object.c (rb_Integer): Symbols and nil should cause error.\n\n\t* object.c (rb_Float): nil should cause error.\n\nTue Jun 25 00:21:00 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* dln.c: remark definition rb_loaderror().\n\nTue Jun 25 00:14:07 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (string_dvar): allow back references in interpolation.\n\nMon Jun 24 16:32:31 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_eval): NODE_EVSTR is no longer used.\n\n\t* eval.c (eval): not enforce to make assigned variables dynamic.\n\n\t* parse.y (string): split rules to strings/xstring/regexp to allow\n\t  arbitrary statements inside string interpolation.\n\n\t* parse.y (here_document): splitted into three phases.\n\n\t* parse.y (literall_append, literal_concat): added.\n\t  append/concatenate string literals.\n\n\t* sample/test.rb (valid_syntax): adjust line number for BEGIN.\n\n\t* lib/mkmf.rb (create_makefile): get rid of nested string.\n\n\t* lib/mkmf.rb (install_rb): site-install didn't work properly.\n\nSun Jun 23 00:19:10 2002  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb, sample/cal.rb, sample/goodfriday.rb:\n\t  updated to the new version (based on date2 3.3).\n\nSat Jun 22 14:41:33 2002  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* ext/socket/socket.c (sock_addrinfo): make all 3 versions of\n\t  getaddrinfo happy.  [ruby-core:00184]\n\nFri Jun 21 18:49:58 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): __END__ should not be effective within\n\t  string literals.\n\nThu Jun 20 21:09:37 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/readline/readline.c (readline_readline): get rid of\n\t  libreadline's bug. (ruby-bugs-ja:PR#268)\n\nThu Jun 20 17:10:27 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ftool.rb (BUFSIZE): tuning, set buffer length to 8192.\n\n\t* configure.in (__NO_ISOCEXT): add for mingw-runtime 2.0-2.\n\n\t* configure.in (__MSVCRT__): removed because it is defined\n\t  in the GCC specs.\n\nWed Jun 19 14:46:18 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb, lib/mkmf.rb (xsystem): open the log file if xsystem\n\t  is called.\n\nWed Jun 19 01:01:13 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (here_document): should be aware of __END__ within here\n\t  documents.\n\nWed Jun 19 00:50:50 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (yylex): ? followed by successive word characters is\n\t  ternary operator not numeric literal.\n\n\t* parse.y (yylex): commands after break/next/rescue can take\n\t  arguments.  (ruby-bugs-ja:PR#265)\n\nTue Jun 18 19:20:16 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/mkexports.rb: remove unnecessary exports. (ruby-dev:17418)\n\nTue Jun 18 12:50:17 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (yylex): should pushback proper char after '<<'.\n\n\t* parse.y (range_op, cond0, cond): get rid of doubled warnings.\n\n\t* parse.y (value_expr): reduce recursion level.\n\n\t* parse.y (logop): ditto.\n\nMon Jun 17 11:11:34 2002  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* string.c (rb_str_crypt): result need not be tainted always.\n\nMon Jun 17 10:51:37 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dln.c (dln_load): need to preserve dln_strerror() result,\n\t  calling other dl family can clear it.\n\nSat Jun 15 22:56:37 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): obsolete '?<whitespace>'; use '?\\s', '?\\n',\n\t  etc, instead.\n\nSat Jun 15 18:51:13 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* dir.c (glob_helper): Use lstat() instead of stat() so it catches\n\t  a dead symlink.  Given a dead symlink named \"a\", Dir.glob(\"?\")\n\t  did catch it but Dir.glob(\"a\") somehow didn't.\n\nSat Jun 15 01:59:05 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): no here document after a dot.\n\n\t* parse.y (yylex): should have set lex_state after '`'.\n\n\t* parse.y (yylex): should have set lex_state properly after\n\t  tOP_ASGN.\n\nFri Jun 14 21:01:48 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/mkexports.rb: insert sleep(1) for win9x.\n\n\t* bcc32/configure.bat: change return code LF -> CRLF for win9x.\n\n\t* win32/win32.c: fix rb_w32_open_osfhandle()\n\nFri Jun 14 15:22:19 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (read_escape): deny zero-width hexadecimal character.\n\t  (ruby-bugs-ja:PR#260)\n\n\t* parse.y (tokadd_escape): ditto.\n\n\t* regex.c (re_compile_pattern): ditto.\n\nFri Jun 14 00:49:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big2dbl): return canonical HUGE_VAL for infinity.\n\nThu Jun 13 09:43:37 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (svalue_to_avalue): v may be Qundef.  This fix was\n\t  suggested by Guy Decoux.\n\nThu Jun 13 00:33:49 2002  takuma ozawa  <metal@mine.ne.jp>\n\n\t* hash.c (rb_hash_s_create): use rb_hash_aset() instead of calling\n\t  st_insert() directly, to dup&freeze string keys.\n\nThu Jun 13 00:12:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): proper error message for \"@@0\".\n\n\t* parse.y (yylex): paren to parse_string() must be zero for\n\t  unparenthesized strings.\n\n\t* parse.y (str_extend): broken string when unterminated \"#{\".\n\n\t* enum.c (enum_sort_by): had a bug in 1 element enumeration.\n\nWed Jun 12 18:04:44 2002  akira yamada  <akira@arika.org>\n\n\t* uri/common.rb (REGEXP::PATTERN::X_ABS_URI): 'file:/foo' is valid.\n\n\t* uri/generic.rb (Generic#xxx=): should return substituted value.\n\t  (ruby-dev:16728.)\n\n\t* test/generic.rb (test_set_component): added tests for the above\n\t  change.\n\nWed Jun 12 02:38:00 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (stmt): fix typo.\n\nWed Jun 12 01:10:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): 'do' should return kDO_BLOCK on EXPR_ENDARG.\n\n\t* parse.y (singleton): \"def (()).a end\" dumped core.\n\n\t* parse.y (range_op): node may be null.\n\n\t* parse.y (match_gen): ditto.\n\nTue Jun 11 19:20:34 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (LIBRUBY): rename to lib$(LIBRUBY_SO).a on Cygwin/MinGW.\n\n\t* configure.in, cygwin/GNUmakefile: use dllwrap when --disable-shared\n\t  is specified.\n\nTue Jun 11 17:12:04 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): void value check for \"..\", \"...\", \"!\", and \"not\".\n\n\t* parse.y (match_gen): void value check for \"=~\".\n\n\t* parse.y (value_expr): check NODE_AND and NODE_OR recursively.\n\n\t* parse.y (cond0): void value check added for conditionals.\n\nTue Jun 11 13:18:47 2002  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/ftp.rb (noop): new method.\n\n\t* lib/net/ftp.rb (site): ditto.\n\nTue Jun 11 13:15:41 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* bcc32/Makefile.sub: set PROCESSOR_LEVEL to 6 if it's too big value.\n\n\t* win32/Makefile.sub: ditto.\n\nTue Jun 11 12:37:46 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* bcc32/configure.bat fix.\n\nTue Jun 11 10:18:23 2002  KONISHI Hiromasa <konishih@fd6.so-net.ne.jp>\n\n\t* new platform [bccwin32] merged.\n\t  - create new folder bcc32\n\t  - modify any files for bccwin32\n\t      error.c, file.c, hash.c, io.c, instruby.rb,\n\t      ext/extmk.rb.in,\n\t      lib/mkmf.rb, lib/ftools.rb,\n\t      ext/digest/defs.h,\n\t      ext/dl/depend, ext/dl/dl.c, ext/dl/sym.c, ext/dl/extconf.rb,\n\t      ext/socket/extconf.rb,\n\t      ext/pty/extconf.rb,\n\t      ext/tcltklib/extconf.rb\n\t      ext/Win32API/Win32API.c,\n\t      win32/dir.h, win32/win32.c, win32/win32.h, win32/resource.rb\n\nMon Jun 10 19:02:19 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* numeric.c (fix_lshift): negative shift count means right shift.\n\t  (ruby-bugs-ja:PR#248)\n\n\t* numeric.c (fix_rshift): return -1 when left side operand is\n\t  negative. (ruby-bugs-ja:PR#247)\n\n\t* parse.y (yylex): `0_' should be an error. (ruby-bugs-ja:PR#249)\n\nMon Jun 10 01:53:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): ruby_frame->last_func may be null, if it's\n\t  called outside of a method.\n\n\t* parse.y (arg): use INT2NUM, not INT2FIX for tUMINUS.\n\n\t* parse.y (arg): unnecessary negative tPOW treatment.\n\n\t* parse.y (tokadd_escape): wrong backslash escapement.\n\nSun Jun  9 17:40:41 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: change the callback mechanism.\n\nSat Jun  8 00:48:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (stmt,arg): too much void value check.\n\n\t* parse.y (stmt,arg): need to check void value on rules which does\n\t  not use node_assign().\n\nThu Jun  6 19:50:39 2002  KONISHI Hiromasa <H_Konishi@ruby-lang.org>\n\n\t* sample/biorhythm.rb (getPosiiton,etc)\n\t  fix at changing Date module ( Date is changed Fixnum to Rational )\n\nThu Jun  6 17:42:39 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (ipaddr): need not to taint hostnames.\n\nThu Jun  6 12:04:30 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (config.status): use sub! instead of []= because\n\t  []= causes exception.\n\nThu Jun  6 11:42:15 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* lib/thread.rb (Queue::pop): get rid of race condition.\n\nWed Jun  5 01:56:47 2002  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: Stop the running zombi-eventloop when\n\t  mainloop_watchdog is killed.\n\nTue Jun  4 23:09:24 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_include): should be based on \"<=>\", whereas\n\t  member? still is based on \"each\".\n\n\t* range.c (range_min,range_max): redefine methods based on \"<=>\".\n\nTue Jun  4 18:28:37 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/extconf.rb: The IPv6 stack of Cygwin is still incomplete.\n\n\t* ext/Win32API/extconf.rb: refactoring.\n\nTue Jun  4 07:03:33 2002  Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkfont.rb:  Fix bugs on TkFont.init_widget_font for Tk8.x.\n\n\t* ext/tk/lib/tkafter.rb: Add self to 1st argument of interval- \n\t  and loop-proc\n\t  TkAfter#current_interval returns an interval (sleep) time value\n\t  TkAfter#current_args returns an array of arguments\n\t  TkAfter#return_value returns a return value of last loop-proc\n\n\t* ext/tk/lib/tk*.rb: Allow to use Symbols for parameters.\n\n\t* ext/tk/lib/tkcanvas.rb: (TkcItem) Add 'coords' parameter to the \n\t  canvas item constructor (for new notation of constructor).\n\n\t* ext/tcltklib/tcltklib.c: New 'mainloop' and 'mainloop_watchdog'.\n\n\t* ext/tk/lib/tk.rb: (Tk.restart) Add 'app-name' paramater and\n\t  'use' parameter.\n\n\t* ext/tk/lib/tk.rb: Add new parameter 'widgetname' to the widget\n\t  constructor to support effective use of Resource Database. \n\n\t* ext/tk/lib/tk.rb: TkOption::get always returns a tainted string.\n\nTue Jun  4 00:45:50 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/socket/addrinfo.h: typo.\n\n\t* ext/socket/getaddrinfo.c (gai_strerror): make literals const.\n\n\t* ext/socket/socket.c (init_inetsock): ensures resources are\n\t  freed at exceptions.\n\n\t* ext/socket/socket.c (init_unixsock): ditto.\n\n\t* ext/socket/socket.c (udp_connect): ditto.\n\nMon Jun  3 20:39:51 2002  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole/extconf.rb : change PLATFORM with RUBY_PLATFORM.\n\nMon Jun  3 07:07:07 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (here_document): check if identifier is terminated.\n\t  (ruby-bugs-ja:PR#239)\n\n\t* parse.y (yylex): should pushback proper char after '**'.\n\t  (ruby-bugs-ja:PR#240)\n\nMon Jun  3 05:56:17 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_aset): should raise error if an indexing string\n\t  is not found in the receiver.\n\n\t* sprintf.c (rb_f_sprintf): \"%d\" should convert objects into\n\t  integers using Integer().\n\nSat Jun  1 19:20:07 2002  Masaki Suketa  <masaki.suketa@nifty.ne.jp>\n\n\t* ext/win32ole: merge from rough.\n\nFri May 31 17:11:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/tempfile.rb (Tempfile::size): added.\n\nThu May 30 12:52:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_step): iteration done using \"+\" if elements are\n\t  Numeric.  Otherwise using \"succ\".\n\n\t* range.c (range_each): iteration done using \"succ\".  If the\n\t  elements does not respond to \"succ\", raise TypeError.  As a\n\t  result, all Enumerable methods, e.g. collect, require elements\n\t  to respond to \"succ\".\n\n\t* range.c (range_member): comparison done using \"each\", if\n\t  elements are non-Numeric or no-\"succ\" objects.  Otherwise\n\t  compare using \"<=>\".\n\n\t* range.c (Init_Range): remove \"size\" and \"length\".\n\nThu May 30 09:16:36 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb: if StringIO is usable then use it.\n\nWed May 29 18:55:47 2002  KONISHI Hiromasa <H_Konishi@ruby-lang.org>\n\n\t* function renames my* and win32_* to rb_w32_* in win32/win32.c\n\t  fixed files win32/win32.c, win32/win32.h, win32/dir.h,\n\t              hash.c, rubysig.h, signal.c, ext/socket/socket.c\n\nWed May 29 17:32:55 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* time.c (tmcmp, search_time_t): activate unless HAVE_TIMEGM.\n\nWed May 29 13:45:15 2002  Wakou Aoyama  <wakou@ruby-lang.org>\n\n\t* lib/cgi.rb: not use const if GET, HEAD. check multipart form head.\n\nTue May 28 17:56:02 2002  Sean Chittenden  <sean@ruby-lang.org>\n\n\t* parse.y: yyparse #defines moved from intern.h\n\n\t* ruby.c (proc_options): access prefixed \"ruby_yydebug\".\n\n\t* applied modifies to pacify some of gcc -Wall warnings.\n\nTue May 28 14:07:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): no more ugly hack for \"**\", so that \"-2**2\" to be\n\t  parsed as \"(-2)**2\", whereas \"- 2**2\" or \"-(2)**2\" to be parsed\n\t  as \"-(2**2)\".\n\n\t* parse.y (yylex): '-2' to be literal fixnum. [new]\n\nTue May 28 12:13:37 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (scope_node): trick to keep the node has a scope.\n\n\t* eval.c (rb_eval): NODE_EVSTR: write back local_tbl to the node.\n\n\t* eval.c (rb_eval): NODE_SCOPE: hold the scope node in ruby_scope.\n\n\t* eval.c (module_setup): ditto.\n\n\t* eval.c (rb_call0): ditto.\n\n\t* node.h (NEW_DASGN, NEW_DASGN_CURR): remove surplus semicolons.\n\nFri May 24 09:06:29 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_arg): nil test against v[6] (usec).\n\nThu May 23 16:39:21 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ruby.c (proc_options): option parsing problem.\n\t  (ruby-bugs-ja:PR#233)\n\nThu May 23 09:13:56 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (proc_options): removed \"-*-\" support for #! line.\n\n\t* io.c (rb_io_s_sysopen): new method to get a raw file\n\t  descriptor. [new]\n\n\t* ext/socket/socket.c (tcp_sysaccept): new method to return an\n\t  accepted socket fd (integer). [new]\n\n\t* ext/socket/socket.c (unix_sysaccept,sock_sysaccept): ditto.\n\nWed May 22 21:26:47 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ruby.c (proc_options): -T consumes digits only.\n\nWed May 22 20:18:31 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: need not link vsnprintf.o on MinGW.\n\nWed May 22 18:34:23 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* parse.y (yylex): Here-document label ate '-'.\n\nTue May 21 13:25:18 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords): symbols end with\n\t  '_'.\n\nTue May 21 04:48:37 2002  Sean Chittenden <sean@chittenden.org>\n\n\t* lib/cgi-lib.rb: Checking for constant MOD_RUBY instead of\n\t  environment variable. Remove a mod_ruby warning and use\n\t  Apache::request.headers_out[] instead.\n\nTue May 21 01:16:46 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (bodystmt): ensure clause was executed on else clause\n\t  without rescue clause.\n\nTue May 21 00:20:25 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl/ptr.c: rename PtrData::alloc to PtrData::malloc.\n\n\t* ext/dl/lib/dl/struct.c: rename Struct#alloc to Struct#malloc.\n\nMon May 20 14:29:14 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (Init_Object): should do exact match for Module#==.\n\n\t* compar.c (cmp_eq): returns 'false' if <=> returns 'nil'.\n\n\t* compar.c (cmp_gt,cmp_ge,cmp_lt,cmp_le,cmp_between): ditto.\n\nMon May 20 13:28:52 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* io.c (rb_io_clone): writing stream was not copied properly.\n\nSat May 18 21:38:11 2002  Tadayoshi Funaba  <tadf@dotrb.org>\n\n\t* lib/date.rb, lib/date/format.rb, lib/parsedate.rb:\n\t  updated to the new version (based on date2 3.2.1).\n\nSat May 18 21:18:00 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (config.h): add VC++4/5 support about noreturn\n\t  directive.\n\nSat May 18 02:16:41 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): should propagate taintedness.\n\n\t* pack.c (pack_unpack): ditto.\n\nFri May 17 16:16:19 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* sample/test.rb: use eval instead of './miniruby -c',\n\t  in order to check a syntax error.\n\nThu May 16 14:46:34 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_select): cleanup conditional compilation.\n\nWed May 15 06:13:35 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): need to preserve errno before\n\t  calling rb_trap_exec().\n\n\t* regex.c (calculate_must_string): a bug in charset/charset_not\n\t  parsing.\n\nTue May 14 18:17:44 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* win32/Makefile.sub: config.h inlined.  and catch up with the\n\t  latest change.\n\n\t* win32/config.h.in: no longer used.\n\nTue May 14 14:49:05 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* gc.c (is_pointer_to_heap): avoid GCC 3.1 warnings.\n\n\t* missing/strftime.c (timezone): it should take no argument on Cygwin.\n\nTue May 14 03:07:35 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_clear_cache_by_class): new function.\n\n\t* eval.c (set_method_visibility): should have clear cache for\n\t  updated visibility.\n\nMon May 13 14:38:33 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* djgpp/config.hin, djgpp/config.sed: catch up with the latest change.\n\nMon May 13 01:59:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (flo_to_s): default format precision to be \"%.16g\".\n\n\t* util.c (ruby_strtod): use own strtod(3) implementation to avoid\n\t  locale hell.  Due to this change \"0xff\".to_f no longer returns 255.0\n\nSun May 12 03:01:08 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* missing.h: add for missing/*.c.\n\n\t* ruby.h: add `#include \"missing.h\"'.\n\n\t* Makefile.in: add the dependency of missing.h by gcc -MM.\n\n\t* MANIFEST: add missing.h\n\nSat May 11 23:24:52 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: enable dl's stack emulation for constructing function call.\n\nSat May 11 10:52:09 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* dir.c (glob_helper): remove escaping backslashes.\n\nSat May 11 02:46:43 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (avalue_to_yvalue): new function to distinguish yvalue\n\t  (no-arg == Qundef) from svalue (no-arg == Qnil).\n\n\t* eval.c (rb_yield_0): use avalue_to_yvalue().\n\n\t* eval.c (assign): warn if val == Qundef where it means rhs is\n\t  void (e.g. yield without value or call without argument).\n\nFri May 10 19:00:47 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* parse.y (here_document): preserve line number begins here\n\t  document.\n\nFri May 10 01:55:44 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_thread_join): added an argument to limit time to wait\n\t  the thread.\n\n\t* eval.c (rb_thread_join_m): new. and added optional argument.\n\nWed May  8 23:48:40 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (value_expr): need not to warn for WHILE and UNTIL,\n\t  since they can have return value (via valued break).\n\nTue May  7 17:13:40 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: forgot to add '-Wl,' to the gcc option on Cygwin/MinGW.\n\nTue May  7 15:41:33 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/iconv/iconv.c (iconv_try): should initialize exceptions\n\t  properly. (ruby-bugs-ja:PR#232)\n\nTue May  7 15:28:03 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (rb_yield_0): The destination of the goto jump was wrong.\n\nTue May  7 09:17:51 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* eval.c (superclass): undesirable \"unexpected return\" when the\n\t  superclass is not a Class.\n\nSun May  5 06:53:45 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb: exclude topdir from the system configuration\n\t  section and prevent it from being overridden.\n\nFri May  3 20:19:00 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: add #include <errno.h> in AC_CHECK_DECLS().\n\n\t* win32/config.h.in: define HAVE_DECL_SYS_NERR.\n\nThu May  2 23:42:40 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_s_quote): # also should be quoted.\n\nThu May  2 18:27:13 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: use 'do...end' instead of '{}' for\n\t  Borland make.\n\nThu May  2 08:01:56 2002  Chris Thomas  <kenshin@apple.com>\n\n\t* error.c: use HAVE_DECL_SYS_NERR instead of platform names.\n\nTue Apr 30 09:23:05 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_step): better iteration condition for float\n\t  values;  suggested by Masahiro TANAKA <masa@ir.isas.ac.jp>.\n\nTue Apr 30 05:59:42 2002  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* range.c (range_step): step (for Range#step method) <= 0 makes no\n\t  sense, thus ArgError will be raised.\n\n\t* range.c (range_each): Range#each method is special case for\n\t  Range#step(1)\n\nMon Apr 29 18:46:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_find_file): load must be done from an absolute path if\n\t  $SAFE >= 4.\n\nSun Apr 28 17:01:56 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (insert): fix prototype for ANSI C.\n\nFri Apr 26 13:47:15 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_partition): new method. [new]\n\nFri Apr 26 13:41:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_s_quote): quote whitespaces for /x cases.\n\nFri Apr 26 06:48:23 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl/ptr.c (cary2ary): missing break in switch statements.\n\nFri Apr 26 09:35:47 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_proc_new): make Proc from C function. [new]\n\n\t* intern.h (rb_proc_new): prototype.\n\nWed Apr 24 14:56:46 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (proc_to_proc): return self. [new]\n\n\t* eval.c (block_pass): no need to convert if block is Proc.\n\nWed Apr 24 14:21:41 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: set size of the initial stack from\n\t  2MB to 32MB on MinGW/Cygwin.\n\nWed Apr 24 14:06:35 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_step): try to reduce residual on Float operations.\n\nWed Apr 24 06:48:31 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* io.c (rb_io_mode_flags): both 'r+b' and 'rb+' should be allowed.\n\n\t* io.c (rb_io_mode_modenum): ditto.\n\nWed Apr 24 01:16:14 2002  Nobuyoshi Nakada  <nobu@ruby-lang.org>\n\n\t* ext/stringio/stringio.c (strio_mark): must check if ptr is NULL\n\t  first.  [ruby-talk:38873]\n\n\t* lib/mkmf.rb (create_makefile): should print depend file when\n\t  make is other than nmake.\n\nWed Apr 24 00:37:12 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/extmk.rb.in (create_makefile): use `{$(srcdir)}' directive instead\n\t  of `$(srcdir)/' when including depend file.\n\n\t* lib/mkmf.rb (create_makefile): add `{$(srcdir)}' when including depend\n\t  file.\n\nTue Apr 23 12:58:18 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_memerror): rename from mem_error, and exported.\n\n\t* gc.c (Init_GC): pre-allocate NoMemoryError instance.\n\n\t* object.c (convert_type): error message changed from \"failed to\n\t  convert\" to \"cannot convert\", since it does not try to convert\n\t  if an object does not respond to the converting method.\n\nMon Apr 22 09:31:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): convert Method to Proc using\n\t  rb_check_convert_type().\n\n\t* object.c (rb_check_convert_type): always convert T_DATA\n\n\t* eval.c (rb_thread_cleanup): should not terminate main_thread by\n\t  Fatal error.\n\n\t* regex.c (is_in_list): need to not exclude NUL and NEWLINE.\n\nSat Apr 20 00:19:13 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_expr_str): wrong backslash escapement.\n\n\t* re.c (rb_reg_expr_str): do not escape embedded space\n\t  characters.\n\nFri Apr 19 22:03:40 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub: add -DNT to $CFLAGS instead of $CPPFLAGS.\n\n\t* win32/setup.mak: ditto.\n\nFri Apr 19 17:24:22 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): T_DATA process patch from Joel VanderWerf\n\t  <vjoel@PATH.Berkeley.EDU>.  This is temporary hack; it remains\n\t  undocumented, and it will be removed when marshaling is\n\t  re-designed.\n\n\t* marshal.c (r_object): ditto.\n\nFri Apr 19 17:10:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_step): Integer#step is moved to Numeric#step;\n\t  Fixnum#step is merged into this method.\n\n\t* numeric.c (int_dotimes): Fixnum#times is merged.\n\n\t* numeric.c (int_upto): Fixnum#upto is merged.\n\n\t* numeric.c (int_downto): Fixnum#downto is merged.\n\nFri Apr 19 16:22:55 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/extconf.rb: include <windows.h>, <winsock.h> on _WIN32.\n\n\t* win32/win32.c: include <mswsock.h> on __MINGW32__.\n\n\t* configure.in: cleanup for autoconf 2.5x.\n\n\t* configure.in: use gcc -shared instead of dllwrap on Cygwin/MinGW.\n\n\t* ext/extmk.rb, lib/mkmf.rb: get rid of \"--def=\".\n\nFri Apr 19 14:57:44 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* re.c (rb_reg_to_s): remove redundant shy group.\n\nFri Apr 19 01:08:20 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_cleanup): current thread may be THREAD_STOPPED,\n\t  for example when terminated from signal handler.\n\nThu Apr 18 19:03:15 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): remove /p support.\n\n\t* regex.h: ditto.\n\n\t* parse.y (parse_regx): ditto.\n\nThu Apr 18 17:01:43 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl/ptr.c (rb_dlptr_cast): removed.\n\nThu Apr 18 17:01:43 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* re.c (rb_reg_to_s): new function for Regexp#to_s.\n\nWed Apr 17 23:55:34 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Setup*, ext/bigfloat/*: Back out the import of BigFloat in\n\t  favor of its forthcoming successor, BigDecimal.\n\nWed Apr 17 16:53:33 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_expr_str): should treat backslash specially in\n\t  escaping.\n\nWed Apr 17 08:16:41 2002  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* io.c: complete off_t handling; missing argument for\n\t  fptr_finalize(); polished rb_scan_args call.\n\nWed Apr 17 00:01:59 2002  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* dir.c: wrap multi-statement macro by do { } while (0)\n\n\t* eval.c, numeric,c, sprintf.c, util.c: ditto.\n\nTue Apr 16 08:59:50 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (assign): convert mrhs to mvalue.\n\nMon Apr 15 18:12:57 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_eq): check `y == x' if y is neither Fixnum,\n\t  Bignum, nor Float.\n\nMon Apr 15 09:27:31 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_unpack): should treat 'U' in character unit, not in\n\t  byte unit.\n\n\t* error.c (exc_initialize): should clear backtrace information.\n\nSat Apr 13 23:42:43 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fptr_cleanup): should close IO created by IO.new(fd).\n\n\t* rubyio.h: remove FMODE_FDOPEN\n\nFri Apr 12 12:54:04 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub: use missing/acosh.c.\n\n\t* win32/config.h.in: define HAVE_COSH, HAVE_SINH, and HAVE_TANH.\n\nFri Apr 12 02:58:55 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* struct.c (rb_struct_select): fix typo.\n\nFri Apr 12 00:34:17 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* MANIFEST (missing/acosh.c): added.\n\n\t* Makefile.in (missing/acosh.c): ditto.\n\n\t* Makefile.in (missing/fileblocks.c): ditto.\n\n\t* configure.in (AC_REPLACE_FUNCS): check acosh() on behalf of\n\t  inverse hyperbolic functions, asinh() and atanh().\n\n\t* missing/acosh.c: added for acosh(), asinh() and atanh().\n\nThu Apr 11 20:01:44 2002  Masahiro Tomita  <tommy@tmtm.org>\n\n\t* io.c (io_write): check error if written data is less than\n\t  specified size to detect EPIPE.\n\nThu Apr 11 19:10:37 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (remain_size): IO#read returns \"\" if file.size == 0.\n\n\t* random.c (rand_init): add check for initstate(3).\n\n\t* configure.in: ditto.\n\nThu Apr 11 09:31:19 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl/ptr.c: raise() -> rb_raise(). (Thanks Tetsuya Watanabe)\n\n\t* ext/dl/sym.c: ditto.\n\nThu Apr 11 07:57:48 2002  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* eval.c (assign): ruby_verbose should be surrounded by RTEST().\n\n\t* object.c (rb_str2cstr): ditto.\n\n\t* parse.y (void_expr): ditto.\n\n\t* parse.y (void_stmts): ditto.\n\n\t* variable.c (rb_ivar_get): ditto.\n\n\t* variable.c (rb_cvar_set): ditto.\n\n\t* variable.c (rb_cvar_get): ditto.\n\nThu Apr 11 07:02:31 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: Add dl.txt instead of README and README.html.\n\nThu Apr 11 01:55:52 2002  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi/session.rb: support for multipart form.\n\nWed Apr 10 18:42:23 2002  Tachino Nobuhiro <tachino@jp.fujitsu.com>\n\n\t* dir.c (glob_helper): should have proceed link when link->path\n\t  was non existing symbolic link.\n\nWed Apr 10 17:30:19 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_obj_remove_instance_variable): raise NameError if\n\t  specified instance variable is not defined.\n\n\t* variable.c (generic_ivar_remove): modified to check ivar\n\t  existence.\n\nWed Apr 10 14:16:45 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords): fontify symbols for\n\t  unary operators and aset.\n\nTue Apr  9 13:40:31 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/mkmf.rb (try_link0): need expand macro in command, sync with\n\t  ext/extmk.rb.in.\n\n\t* lib/mkmf.rb (try_cpp): ditto.\n\n\t* lib/mkmf.rb (egrep_cpp): ditto.\n\nTue Apr  9 12:44:59 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/stringio/stringio.c (check_modifiable): performance\n\t  improvement.  avoid calling rb_str_modify() twice.\n\n\t* ext/stringio/stringio.c (strio_ungetc): ditto.\n\n\t* ext/stringio/stringio.c (strio_putc): ditto.\n\n\t* ext/stringio/stringio.c (strio_write): ditto, and use\n\t  rb_str_cat() as possible.\n\nTue Apr  9 05:17:48 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* re.c (match_select): fix index references and make\n\t  MatchData#select actually work.\n\nTue Apr  9 00:20:52 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_s_extname): new method based on the proposal\n\t  (and patch) from Mike Hall. [new]\n\nMon Apr  8 04:50:51 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (error_handle): default to 1 unless status is set.\n\n\t* eval.c (ruby_options): guard error_handle() with PROT_NONE.\n\n\t* eval.c (ruby_stop): ditto.\n\nMon Apr  8 01:22:24 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* math.c (math_acosh): added. [new]\n\n\t* math.c (math_asinh): ditto.\n\n\t* math.c (math_atanh): ditto.\n\n\t* struct.c (rb_struct_each_pair): method added. [new]\n\nSat Apr  6 02:04:49 2002  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* class.c (rb_singleton_class): wrong condition; was creating\n\t  unnecessary singleton class.\n\nSat Apr  6 01:09:41 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* sprintf.c (remove_sign_bits): simplifies the condition.\n\n\t* bignum.c (get2comp): calculate proper carry over.\n\nFri Apr  5 05:07:28 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: Add dl/struct.rb.\n\nThu Apr  4 14:08:52 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl/lib/dl/import.rb: Get rid of ineffective\n\t  encoding/decoding procedures.\n\nThu Apr  4 01:08:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (int_step): step may be a float less than 1.\n\nWed Apr  3 20:42:34 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: Merge Nakada's patch.\n\n\t* ext/dl/dl.h: define StringValuePtr for ruby-1.6.\n\nWed Apr  3 15:37:24 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: Add dl/types.rb.\n\nWed Apr  3 01:54:10 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/extmk.rb.in (enable_config): follow lib/mkmf.rb.\n\nTue Apr  2 19:59:13 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* ext/dl: Merge from rough.\n\nTue Apr  2 15:17:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* Makefile.in (CPPFLAGS): remove @includedir@.\n\n\t* lib/mkmf.rb (create_makefile): ditto.\n\n\t* ext/extmk.rb.in (create_makefile): ditto.\n\nTue Apr  2 15:09:05 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_addrinfo): should clear addrinfo hints.\n\nMon Apr  1 23:48:12 2002  Takaaki Tateishi <ttate@kt.jaist.ac.jp>\n\n\t* lib/mkmf.rb: install any files using $INSTALLFILES.\n\t  (see also [ruby-dev:16683])\n\nMon Apr  1 17:25:50 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fptr_cleanup): need flush even when io will not be\n\t  closed.\n\n\t* io.c (rb_io_initialize): was calling wrong function\n\t  rb_io_mode_flags().\n\nMon Apr  1 16:52:00 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/sdbm/init.c (each_pair): moved prototype before the\n\t  definition.\n\n\t* ext/racc/cparse/cparse.c (call_scaniter): ditto.\n\nMon Apr  1 15:11:40 2002  NAKAMURA Usaku <usa@ruby-lang.org>\n\n\t* ext/racc/cparse/cparse.c: prototype; call_scaniter().\n\n\t* ext/sdbm/init.c: prototype; each_pair().\n\n\t* ext/tcltklib/tcltklib.c: prototypes; _timer_for_tcl() and ip_ruby(),\n\t  Nobu's patch at [ruby-dev:14483].\n\nMon Apr  1 10:56:40 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (match_setter): it's OK to assign nil to $~.\n\nMon Apr  1 03:55:46 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fptr_cleanup): do not close IO created by for_fd().\n\n\t* io.c (rb_io_initialize): mark IO created by for_fd\n\n\t* ext/socket/socket.c (bsock_s_for_fd): ditto.\n\nFri Mar 29 20:21:58 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/mkmf.rb (create_makefile): default FLAGS to empty strings.\n\nFri Mar 29 16:36:52 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/mkmf.rb (arg_config): should use Shellwords::shellwords like\n\t  ext/extmk.rb.in.\n\n\t* lib/mkmf.rb (enable_config): default had priority over command\n\t  line options and configure_args.\n\n\t* lib/mkmf.rb: support autoconf 2.53 style variables from\n\t  environment.\n\n\t* lib/mkmf.rb: add directory options.\n\nFri Mar 29 15:49:29 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/README.win32: follow recent changes.\n\nFri Mar 29 14:44:05 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_fflush): DRY patch from /Christoph applied.\n\nThu Mar 28 18:58:13 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (config.status): reflect user defined $CC in\n\t  config.status.\n\nThu Mar 28 18:03:51 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/strscan.c: add taint check.\n\n\t* ext/strscan/strscan.c: #getch/#get_byte should set regexp\n\t  registers.\n\n\t* ext/strscan/strscan.c: remove useless #include directive.\n\n\t* ext/strscan/strscan.c: refactor struct strscanner.\n\nThu Mar 28 14:51:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_addrinfo): should specify socktype\n\t  from outside.\n\nWed Mar 27 17:04:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_binmode): should call next_argv() to initialize ARGF.\n\n\t* io.c (argf_filename): ditto.\n\n\t* io.c (argf_file): ditto.\n\nWed Mar 27 14:47:32 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (READ_DATA_PENDING): configure.in has supported for uClibc,\n\t  so remove uClibc stuff.\n\nWed Mar 27 13:14:43 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_sysseek): new method based on a patch from Aristarkh\n\t  A Zagorodnikov <xm@bolotov-team.ru>. [new]\n\n\t* io.c (READ_DATA_PENDING): use !feof(fp) for default behavior.\n\nTue Mar 26 20:28:50 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: HTTP.get accepts URI.\n\n\t* lib/net/http.rb: new method HTTP.get_uri.\n\n\t* lib/net/http.rb: add some HTTP 1.1 response codes.\n\nTue Mar 26 20:25:28 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* doc/net/protocol.rd.ja, smtp.rd.ja, pop.rd.ja: removed.\n\n\t* MANIFEST: remove doc/net/* entries.\n\nTue Mar 26 18:45:15 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (FILE_READPTR): check bufread instead of bufend\n\t  for uClibc.\n\n\t* ext/extmk.rb.in (arg_config): should use Shellwords::shellwords.\n\nTue Mar 26 01:56:33 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (primary): while/until statement modifiers to \"begin\"\n\t  statement now work as \"do .. while\" even when begin statement\n\t  has \"rescue\" or \"ensure\" [new].\n\n\t* parse.y (bodystmt): rescue/ensure is allowed at every bodies,\n\t  i.e. method bodies, begin bodies, class bodies[new], and module\n\t  bodies[new].\n\nMon Mar 25 22:10:04 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_addrinfo): should specify ai_socktype\n\t  for getaddrinfo hints.\n\nMon Mar 25 17:18:48 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* dir.c (rb_push_glob): local variable 'maxnest' was\n\t  uninitialized.\n\nMon Mar 25 16:53:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_abort): embed aborting message into exception\n\t  object [new].\n\n\t* eval.c (terminate_process): utility function for exit and abort.\n\nTue Mar 26 14:04:47 2002  okabe katsuyuki <HGC02147@nifty.ne.jp>\n\n\t* win32/mkexports.rb: support VC++.NET.\n\nTue Mar 26 14:00:17 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/bigfloat/bigfloat.c: Fix the initializer's function name\n\t  according to the new library name. (pointed out by nobu)\n\nTue Mar 26 11:12:01 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/fileutils.rb: new file.\n\nTue Mar 26 03:23:50 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (pp): return nil like p.\n\nTue Mar 26 01:48:01 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/bigfloat/extconf.rb: Downcase the library name. (BigFloat.so\n\t  -> bigfloat.so)\n\n\t* ext/bigfloat/bigfloat.c (BigFloat_inspect): Alter the inspect\n\t  format not to look like an array. (pointed out by akr)\n\n\t* ext/bigfloat/bigfloat.c (BigFloat_hash): Implement BigFloat#hash.\n\n\t* ext/bigfloat/bigfloat.c (BigFloat_dump, BigFloat_load):\n\t  Support marshaling.\n\nTue Mar 26 00:38:11 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* configure.in (FILE_READPTR): check _p for 4.4BSD.\n\nMon Mar 25 23:39:25 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* configure.in (FILE_READPTR): new.  for IO#gets improvement.\n\n\t* io.c (READ_DATA_PENDING_PTR): ditto.\n\n\t* io.c (remain_size): separated from read_all().\n\n\t* io.c (read_all): argument changed.\n\n\t* io.c (appendline): new.  get a line and append to string.\n\n\t* io.c (swallow): new.  swallow continuous line delimiters.\n\n\t* io.c (rb_io_getline_fast): add delimiter argument.\n\n\t* io.c (rb_io_getline): performance improvement.\n\nMon Mar 25 19:30:25 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in (arg_config): get rid of single quotes\n\t  for autoconf 2.53.\n\nMon Mar 25 17:49:41 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* regex.c (mbc_startpos_func): VC6 seems to be unable to\n\t  understand forward declaration for static variables.\n\n\t* dir.c (rb_push_glob): local variable 'maxnest' was\n\t  uninitialized.\n\nMon Mar 25 13:24:20 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (bsock_do_not_rev_lookup_set): should not be\n\t  allowed when $SAFE > 3.\n\n\t* eval.c (rb_thread_ready): THREAD_TO_KILL threads should not turn\n\t  into THREAD_RUNNABLE on wakeup.\n\n\t* eval.c (rb_thread_list): THREAD_TO_KILL threads should be in the\n\t  list.\n\n\t* eval.c (thgroup_list): ditto; by moving gid clearance from\n\t  rb_thread_cleanup().\n\nMon Mar 25 11:06:19 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* dln.c (dln_argv0): unused unless USE_DLN_A_OUT.\n\n\t* regex.c (mbc_startpos_func): should be static.\n\nSun Mar 24 12:19:09 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* dir.c (fnmatch): \"*/bar\" (with FNM_PATHNAME flag) does not\n\t  match \"foo/bar\".\n\nSun Mar 24 00:46:05 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* util.c (push_element): avoid warning for djgpp.\n\nSat Mar 23 01:50:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (read_all): files on /proc filesystem with zero stat size,\n\t  may have contents.\n\nFri Mar 22 18:07:29 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (tcp_s_gethostbyname): refactored.\n\n\t* ext/socket/socket.c (sock_s_gethostbyname): ditto.\n\nFri Mar 22 16:46:54 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/extmk.rb.in: replace mkdir with mkpath to compile racc/cparse.\n\nFri Mar 22 16:22:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* the VMS support patch submitted by Akiyoshi, Masamichi\n\t  <Masamichi.Akiyoshi@jp.compaq.com> is merged.\n\nFri Mar 22 16:27:24 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/racc/parser.rb: new file.\n\n\t* ext/racc/MANIFEST, cparse.c, depend, extconf.rb: new files.\n\n\t* lib/README: add racc/parser.rb.\n\n\t* ext/Setup*: add racc/cparse.\n\nFri Mar 22 15:04:03 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (exec_under): changing ruby_class is OK, but should not\n\t  alter cbase.\n\n\t* eval.c (yield_under_i): ditto.\n\nFri Mar 22 15:44:38 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* ext/strscan/MANIFEST, strscan.c, depend, extconf.rb: new files.\n\n\t* ext/Setup*: add strscan entry.\n\nFri Mar 22 14:32:14 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: Protocol#start should return self.\n\nFri Mar 22 14:14:21 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb: fix arguments to create exceptions.\n\t  Patch from matt@lickey.com.  (ruby-bugs:PR#278)\n\nFri Mar 22 13:51:11 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/bigfloat/.cvsignore, ext/bigfloat/MANIFEST: BigFloat 1.1.8\n\t  has been imported.  Add .cvsignore and MANIFEST.\n\nFri Mar 22 04:07:55 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* sprintf.c (rb_f_printf): discard meaningless prefix \"..\" for '%u'.\n\nThu Mar 21 01:11:37 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/Makefile.sub (config.status): fix install path (prefix).\n\nThu Mar 21 01:03:05 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/configsub.rb: latest autoconf style support.\n\nWed Mar 20 22:16:25 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* mkconfig.rb: close duplicated $stdout before renaming rbconfig.rb.\n\nWed Mar 20 21:54:17 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* win32/Makefile.sub: made variables configurable.\n\n\t* win32/Makefile.sub (config.h): updates RUBY_PLATFORM from\n\t  Makefile.\n\n\t* win32/Makefile.sub (config.status): ditto. and use recent\n\t  autoconf format.\n\n\t* win32/Makefile.sub (clean): separate ext and local clean up.\n\n\t* win32/Makefile.sub (distclean): ditto.\n\n\t* win32/config.status.in: no longer used.\n\nWed Mar 20 20:12:35 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* variable.c (rb_const_list): a temporary table must be freed.\n\nWed Mar 20 19:44:09 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* mkconfig.rb: don't touch rbconfig.rb if there is a trouble.\n\nWed Mar 20 16:05:37 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): should check receiver only once.\n\n\t* eval.c (is_defined): should handle NODE_NEWLINE.\n\nWed Mar 20 11:29:25 2002  Aristarkh A Zagorodnikov  <xm@xml-objects.com>\n\n\t* file.c (rb_file_s_expand_path): memory leak fixed.\n\nWed Mar 20 00:36:43 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* util.c (ruby_getcwd): the content of buf is uncertain and must\n\t  not be printed when getcwd(buf, size) has failed.\n\nMon Mar 18 22:19:52 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/stringio/stringio.c (check_modifiable): wrong declaration.\n\nMon Mar 18 18:04:05 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/digest: add depend file.\n\n\t* ext/digest/md5: ditto.\n\n\t* ext/digest/rmd160: ditto.\n\n\t* ext/digest/sha1: ditto.\n\n\t* ext/digest/sha2: ditto.\n\n\t* ext/iconv/MANIFEST: ditto.\n\n\t* ext/stringio/MANIFEST: ditto.\n\n\t* ext/syslog: ditto.\n\nMon Mar 18 17:18:06 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_f_abort): should not bypass cleanup.\n\n\t* ext/stringio/stringio.c (check_modifiable): void function.\n\nMon Mar 18 12:52:01 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/iconv/extconf.rb: workaround for GNU libiconv.\n\nMon Mar 18 10:55:03 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (parse_string): part of multi-byte sequence must not\n\t  match to paren.\n\n\t* parse.y (parse_qstring): ditto.\n\n\t* parse.y (parse_quotedwords): ditto.\n\n\t* parse.y (str_extend): handle multi-byte characters.\n\nMon Mar 18 10:31:20 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* enum.c (enum_find): catch a value before recycle.\n\n\t* enum.c (enum_all): ditto.\n\n\t* enum.c (enum_any): ditto.\n\n\t* enum.c (enum_min): ditto.\n\n\t* enum.c (enum_max): ditto.\n\nSun Mar 17 20:08:04 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/iconv/depend: added.\n\n\t* ext/stringio/depend: added.\n\nSat Mar 16 22:43:53 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* missing/fileblocks.c: add for autoconf.\n\nSat Mar 16 15:30:40 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_search): should clear last_match if pos is out of\n\t  string range.\n\n\t* string.c (rb_str_index_m): ditto.\n\n\t* string.c (rb_str_rindex): ditto.\n\nSat Mar 16 09:04:58 2002  Koji Arai <JCA02266@nifty.ne.jp>\n\n\t* enum.c (enum_inject): use the first iterated element as the\n\t  initial value when omitted.\n\n\t* enum.c (inject_i): ditto.\n\n\t* enum.c (Init_Enumerable): Enumerable#inject now takes variable\n\t  count arguments.\n\nFri Mar 15 19:47:31 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* win32/win32.c (StartSockets): remove duplicated lines.\n\nFri Mar 15 17:44:08 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* bignum.c, intern.h (rb_ull2big, rb_ll2big, rb_ull2inum, rb_ll2inum,\n\t  big2ull, rb_big2ull, rb_big2ll): use LONG_LONG macro instead of\n\t  long long.\n\n\t* numeric.c, intern.h, ruby.h (rb_num2ll, rb_num2ull): ditto.\n\n\t* ruby.h: use _I64_MAX and _I64_MIN if they are defined (for VC++).\n\nFri Mar 15 14:02:43 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/iconv/iconv.c: fixed document, Iconv#new is no longer an\n\t  iterator. thanks to Tanaka Akira <akr@m17n.org>.\n\nThu Mar 14 22:17:45 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/iconv: imported.\n\nThu Mar 14 16:42:37 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_define_class): should handle autoload.\n\n\t* class.c (rb_define_module): ditto.\n\nThu Mar 14 16:18:12 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: autoconf 2.53 support. use AC_LIBOBJ.\n\nThu Mar 14 00:29:12 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_match): should clear $~ if operand is nil.\n\n\t* re.c (rb_reg_match2): ditto.\n\nThu Mar 14 12:32:59 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/stringio/stringio.c: fixed frozen string bug.  ungetc no\n\t  longer raises on readonly stream unless modifies actually.\n\nThu Mar 14 08:57:41 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* dir.c (rb_push_glob): avoid SEGV when a block given.\n\nThu Mar 14 00:16:02 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* string.c (rb_str_subpat_set): must make str independent after\n\t  rb_reg_search() matched.\n\nWed Mar 13 19:05:15 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* dir.c: FNM_PERIOD is obsoleted and FNM_DOTMATCH is introduced\n\t  instead, which has the opposite meaning of FNM_PERIOD.\n\n\t* dir.c: Dir::glob now accepts optional FNM_* flags via the second\n\t  argument, whereas Dir::[] doesn't.\n\nWed Mar 13 18:36:55 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/getopts.rb: single_options can be nil[*], and is not not\n\t  optional. ([*]Pointed out by gotoken)\n\nWed Mar 13 17:23:46 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure: merge Jonathan Baker's large file support patch\n\t  [ruby-talk:35316], with read_all patch in [ruby-talk:35470].\n\nWed Mar 13 04:06:48 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_abort): optional message argument that be printed\n\t  on termination.\n\nTue Mar 12 17:12:06 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb: don't complete domains for absolute FQNs.\n\nMon Mar 11 23:08:48 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/tsort.rb: new file.\n\nMon Mar 11 21:03:37 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/stringio: new.\n\nMon Mar 11 18:03:37 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): '\\0111' should be '\\011' plus '1',\n\t  since octal literals are formed by three digits at most.\n\nMon Mar 11 14:44:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): module inclusion using extend() should\n\t  also be detected.\n\n\t* eval.c (rb_eval_cmd): cbase should not be NULL; it should be\n\t  either ruby_wrapper or Object.\n\nSun Mar 10 02:18:22 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* enum.c (enum_each_with_index): should return self.\n\n\t* process.c (proc_setpgrp): should return value for non-void function.\n\n\t* process.c (proc_getpgid): should raise exception if getpgid() return -1.\n\n\t* string.c (rb_str_ljust): should return a duplicated string.\n\n\t* string.c (rb_str_rjust): ditto.\n\n\t* string.c (rb_str_center): ditto.\n\nSat Mar  9 08:45:58 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/extconf.rb (have_struct_member): don't print checked\n\t  result.\n\nFri Mar  8 12:19:15 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/resolv.rb: use its own thread group for background threads.\n\nFri Mar  8 02:21:32 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (cvar_cbase): utility function to find innermost non\n\t  singleton cbase.\n\n\t* eval.c (is_defined): adopt new cvar behavior.\n\n\t* eval.c (rb_eval): ditto.\n\n\t* eval.c (assign): ditto.\n\nThu Mar  7 20:08:25 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* gc.c (rb_source_filename): added. holds unique strings for file\n\t  names with GC space.\n\n\t* gc.c (rb_gc_mark): mark source file name.\n\n\t* gc.c (gc_sweep): ditto.\n\n\t* gc.c (Init_GC): initialize source file name table.\n\n\t* intern.h (rb_source_filename): added.\n\n\t* eval.c (rb_eval_string): use rb_source_filename().\n\n\t* parse.y (yycompile): ditto.\n\n\t* ruby.c (proc_options): ditto.\n\n\t* ruby.c (load_file): ditto.\n\n\t* ruby.c (ruby_script): ditto.\n\n\t* ruby.c (ruby_prog_init): ditto.\n\nWed Mar  6 17:58:08 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dln.c (dln_load): use LoadLibrary instead of LoadLibraryEx.\n\nWed Mar  6 16:50:37 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_mod_clone): should not call rb_obj_clone(), since\n\t  Module does not provide \"allocate\".\n\n\t* class.c (rb_singleton_class): should create new singleton class\n\t  if obj is a class or module and attached object is different,\n\t  which means metaclass of singleton class is sought.\n\n\t* time.c (time_s_alloc): now follows allocation framework.\n\nTue Mar  5 05:56:29 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/getopts.rb: Rewrite to fix some bugs and complete features.\n\t  - Accept options with the colon in the first argument;\n\t    getopts(\"a:bcd:\") is equivalent to getopts(\"bc\", \"a:\", \"d:\").\n\t  - Do not discard the argument that caused an error.\n\t  - Do not discard '-', which commonly stands for stdin or stdout.\n\t  - Allow specifying a long option with a value using '='.\n\t    (command --long-option=value)\n\t  - Stop reading options when it meets a non-option argument.\n\nMon Mar  4 13:19:18 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in (dir_config): Sync with mkmf.rb: Fix a bug where\n\t  --with-xx-{include,lib} is ignored when --with-xx-dir is\n\t  specified.\n\nMon Mar  4 00:09:55 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should initialize outer class variables from\n\t  methods in singleton class definitions.\n\n\t* eval.c (assign): ditto.\n\nFri Mar  1 11:29:10 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/{addinfo.h,getaddrinfo.c} (gai_strerror): add const\n\t  qualifier only for uClibc.\n\nFri Mar  1 11:22:51 2002  Amos Gouaux  <amos+ruby@utdallas.edu>\n\n\t* lib/net/imap.rb: added document.\n\n\t* lib/net/imap.rb (getquotaroot): new method.\n\n\t* lib/net/imap.rb (setacl): remove the rights if the rights\n\t  parameter is nil.\n\n\t* lib/net/imap.rb (getacl): return an array of MailboxACLItem.\n\nFri Mar  1 06:25:49 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/extconf.rb (have_struct_member): new method.\n\t  check msg_control and msg_accrights in struct msghdr.  check\n\t  sys/uio.h.\n\n\t* ext/socket/socket.c: include sys/uio.h if available.\n\t  (thread_read_select): new function.\n\t  (unix_send_io): ditto.\n\t  (unix_recv_io): ditto.\n\t  (unix_s_socketpair): ditto.\n\t  (Init_socket): define UNIXSocket#send_io, UNIXSocket#recv_io,\n\t  UNIXSocket.socketpair and UNIXSocket.pair.\n\n\t* dln.c (dln_load): fix typo.\n\nWed Feb 27 16:30:50 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_include): load modules in argument order.\n\n\t* st.c (st_init_table_with_size): num_bins should be prime numbers\n\t  (no decrement).\n\n\t* st.c (rehash): ditto.\n\nWed Feb 27 13:18:49 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* io.c (READ_DATA_PENDING): uClibc support.\n\n\t* random.c (rand_init): ditto.\n\n\t* ext/socket/{addinfo.h,getaddrinfo.c} (gai_strerror): ditto.\n\nWed Feb 27 07:05:17 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/sha2/sha2.c: Merge from rough.  Fix a couple of\n\t  off-by-one errors in Aaron Gifford's code.\n\n\t  Obtained from:  KAME via FreeBSD\n\t  KAME PR:        393\n\t  FreeBSD PR:     kern/34242\n\nWed Feb 27 03:36:47 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* ext/dbm/dbm.c (fdbm_select): 1.7 behavior.\n\n\t* ext/gdbm/gdbm.c (fgdbm_select): ditto.\n\n\t* ext/sdbm/sdbm.c (fsdbm_select): ditto.\n\n\t* ext/dbm/dbm.c (fdbm_delete): adopt Hash#delete behavior.\n\n\t* ext/sdbm/sdbm.c (fsdbm_delete): ditto.\n\n\t* ext/gdbm/gdbm.c: need not to dup key to the block.\n\n\t* ext/sdbm/sdbm.c : replace RuntimeError with SDBMError.\n\nTue Feb 26 21:34:07 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* bignum.c (rb_big_2comp): void function cannot return any value.\n\nTue Feb 26 16:52:12 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_missing): NoMethod error messages for true, false,\n\t  nil must respond visibility like for other objects.\n\nTue Feb 26 15:41:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): call trace_func for if/while conditions.\n\n\t* marshal.c (r_object): separate r_regist from proc calling.\n\nTue Feb 26 11:25:50 2002  akira yamada  <akira@arika.org>\n\n\t* lib/uri/generic.rb: merge0 should return [oth, oth] if oth is\n\t  absolute URI.\n\n\t* lib/uri/generic.rb: registry part must not be allowed for any\n\t  schemes for the Internet. (RFC2396, section 3.2.2 and 3.2.1.)\n\nMon Feb 25 21:22:41 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syslog/syslog.c: Merge from rough.  Use SafeStringValue().\n\nMon Feb 25 21:12:08 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/syslog/syslog.c: Merge from rough.  Turn Syslog into a\n\t  module keeping backward compatibility intact.\n\nMon Feb 25 19:35:48 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* sample/test.rb (system): test with scripts under the source\n\t  directory.\n\nMon Feb 25 15:14:01 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (method_inspect): should not dump core for unbound\n\t  singleton methods.\n\n\t* object.c (rb_mod_to_s): better description.\n\nMon Feb 25 13:32:13 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/shell.rb (Shell::expand_path): relative to @cwd.\n\nMon Feb 25 06:30:11 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* hash.c (env_select): should path the assoc list.\n\nSun Feb 24 17:20:22 2002  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/*/*.h: Merge from rough.\n\t  - Avoid namespace pollution. (MD5_* -> rb_Digest_MD5_*, etc.)\n\nSat Feb 23 21:12:13 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_syswait): thread kludge; should be fixed to\n\t  support native thread.\n\nFri Feb 22 21:20:53 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: set read_timeout dynamically.\n\n\t* lib/net/http.rb: @@newimpl is always true in the main trunk.\n\n\t* lib/net/http.rb: HTTP.port -> default_port\n\n\t* lib/net/http.rb: HTTPResponse.read_response_status ->\n\t  read_status_line\n\nFri Feb 22 19:56:15 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/config.status.in: set LIBRUBY_SO.\n\nFri Feb 22 03:34:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (get2comp): need to specify to carry or not.\n\n\t* io.c (rb_io_inspect): embed path info.\n\nFri Feb 22 11:30:01 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/prettyprint.rb: FillGroup implemented.\n\nThu Feb 21 21:40:18 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* ext/extmk.rb.in (create_makefile): remove unnecessary -L option from\n\t  LIBS macro.\n\nThu Feb 21 02:49:12 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* pack.c (pack_pack): wrong # comment treatment.\n\n\t* pack.c (pack_unpack): ditto.\n\nWed Feb 20 15:15:03 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* intern.h: prototypes; rb_io_addstr(), rb_io_printf(),\n\t  rb_io_print(), rb_io_puts()\n\n\t* io.c (rb_io_addstr): make extern.\n\n\t* io.c (rb_io_printf): ditto.\n\n\t* io.c (rb_io_print): ditto.\n\n\t* io.c (rb_io_puts): ditto.\n\nWed Feb 20 13:41:35 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* io.c (rb_io_close): return Qnil.\n\nWed Feb 20 12:41:59 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_any_cmp): should handle Qundef in keys.\n\n\t* eval.c (remove_method): should not remove a empty method to\n\t  implement \"undef\".\n\n\t* eval.c (rb_eval): should allow singleton class def for\n\t  true/false/nil.\n\nTue Feb 19 21:43:32 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: rename Protocol.port to default_port.\n\n\t* lib/net/smtp.rb: ditto.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/http.rb: ditto.\n\n\t* lib/net/protocol.rb: rename BufferedSocket class to\n\t  InternetMessageIO.\n\n\t* lib/net/smtp.rb: ditto.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/http.rb: ditto.\n\n\t* lib/net/protocol.rb: rename InternetMessageIO#write_pendstr to\n\t  write_message.\n\n\t* lib/net/smtp.rb: ditto.\n\n\t* lib/net/protocol.rb: new method\n\t  InternetMessageIO#through_message.\n\n\t* lib/net/smtp.rb: ditto.\n\n\t* lib/net/protocol.rb: rename InternetMessageIO#read_pendstr to\n\t  read_message_to.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/protocol.rb: rename InternetMessageIO#read_pendlist to\n\t  each_list_item\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/protocol.rb: Now block size is 1024.\n\n\t* lib/net/smtp.rb: new methods SMTP#esmtp? and #esmtp=.\n\n\t* lib/net/http.rb: Using singleton method syntax instead of\n\t  singleton class clause, to avoid behavior change of class\n\t  variables in ruby 1.7.\n\n\t* lib/net/http.rb: HTTPResponse class does not inherit from\n\t  Net::Response.\n\n\t* lib/net/http.rb: divide HTTP#connecting into\n\t  {begin,end}_transport.\n\n\t* lib/net/http.rb: unused class Accumulator removed.\n\n\t* lib/net/http.rb: Net::HTTP reads response. not HTTPRequest.\n\n\t* lib/net/http.rb: proxy related class-instance-variables are not\n\t  initialized correctly.\n\nTue Feb 19 20:20:12 2002  Ed Sinjiashvili  <edsin@swes.saren.ru>\n\n\t* parse.y (str_extend): backslash escape was done wrong.\n\nTue Feb 19 17:10:25 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (path_check_1): do not fail on world writable *parent*\n\t  directories too.\n\nTue Feb 19 15:51:41 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (path_check_1): do not warn on world writable *parent*\n\t  directories.\n\n\t* class.c (rb_include_module): should preserve ancestor order in\n\t  the included class/module.\n\nTue Feb 19 14:45:32 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (path_check_1): should check directory sticky bits.\n\n\t* process.c (security): need not to warn twice.\n\n\t* marshal.c (r_object): complete restoration before calling\n\t  r_regist().\n\nTue Feb 19 14:24:36 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): operators in the \"op\" rule should make\n\t  lex_state EXPR_ARG on EXPR_FNAME and EXPR_DOT.\n\nTue Feb 19 13:38:10 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval_string_wrap): should hide the toplevel local\n\t  variable bindings by PUSH_SCOPE().\n\nTue Feb 19 13:21:51 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* regex.c: fix prototypes of xmalloc(), xcalloc() and xrealloc().\n\nTue Feb 19 13:16:08 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* io.c (rb_io_ungetc): don't fail pushed EOF back.\n\nMon Feb 18 20:48:40 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* pack.c (pack_pack): avoid infinite loop at comment.\n\n\t* pack.c (pack_unpack): ditto.\n\nMon Feb 18 14:06:28 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* misc/ruby-mode.el (ruby-block-hanging-re): rescue block was too\n\t  indented.\n\nMon Feb 18 13:56:44 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (expr_value, arg_value, primary_value): value_expr()\n\t  check in place.\n\n\t* eval.c (block_pass): \"&nil\" should clear block given.\n\nMon Feb 18 02:05:56 2002  Wolfgang Jahrling <wolfgang@pro-linux.de>\n\n\t* dir.c (push_braces): remove MAXPATHLEN dependency.\n\n\t* dir.c (dir_s_globd): ditto.\n\n\t* dln.c (init_funcname): ditto.\n\n\t* dln.c (load_1): ditto.\n\n\t* dln.c (dln_load): ditto.\n\n\t* configure.in: add GNU/Hurd switches.\n\nFri Feb 15 17:44:26 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): allows comment in template strings.\n\n\t* pack.c (pack_unpack): ditto.\n\nSun Feb 17 23:41:37 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* mkconfig.rb (Config::expand): expand ${} too.\n\n\t* ext/extmk.rb.in (try_link0): expand command.\n\n\t* ext/extmk.rb.in (try_cpp): ditto.\n\n\t* ext/extmk.rb.in (extmake): default $LIBPATH to $libdir\n\nSun Feb 17 21:39:24 2002  Tetsuya Watanabe  <tetsuya.watanabe@nifty.com>\n\n\t* ext/digest/md5/md5init.c (Init_md5): rb_cvar_declare() is\n\t  replaced by rb_cvar_set().\n\n\t* ext/digest/rmd160/rmd160init.c (Init_rmd160): ditto.\n\n\t* ext/digest/sha1/sha1init.c (Init_sha1): ditto.\n\n\t* ext/digest/sha2/sha2init.c (Init_sha2): ditto.\n\nSun Feb 17 18:10:09 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* class.c (rb_define_class): warn unless superclass is specified\n\t  explicitly.\n\n\t* class.c (rb_define_class_under): ditto.\n\nThu Feb 16 02:11:08 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords): fontify\n\t  instance/class/global variables start with '_'.\n\nFri Feb 15 14:40:38 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): replace rb_cvar_declare() by rb_cvar_set().\n\n\t* eval.c (assign): ditto.\n\n\t* variable.c (rb_cvar_set): 4th argument (warn) added; define new\n\t  class variable if it's not defined yet.\n\n\t* variable.c (rb_cvar_declare): removed.\n\nFri Feb 15 13:36:58 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_rshift): should properly convert the negative\n\t  value to 2's compliment.\n\nThu Feb 14 17:38:35 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y: avoid SEGV at OP_ASIGN to pseudo variable.\n\nThu Feb 14 14:13:16 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* struct.c (Init_Struct): should undefine \"allocate\" for Struct\n\t  class (it's redefined in the subclasses).\n\nWed Feb 13 17:58:12 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (stmt): local variable declaration order was changed\n\t  since 1.6\n\n\t* parse.y (arg): ditto.\n\n\t* pack.c (pack_pack): add templates 'q' and 'Q'.\n\n\t* pack.c (pack_unpack): ditto.\n\n\t* bignum.c (rb_quad_pack): new utility function.\n\n\t* bignum.c (rb_quad_unpack): ditto.\n\nTue Feb 12 01:21:34 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (assignable): should emit CVASGN within the method\n\t  body.\n\nMon Feb 11 06:13:53 2002  Matt Armstrong  <matt@lickey.com>\n\n\t* dir.c (dir_s_glob): should not warn even if no match found.\n\nMon Feb 11 04:25:54 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): clean up class variable behavior.\n\n\t* eval.c (assign): ditto.\n\n\t* eval.c (is_defined): ditto.\n\n\t* variable.c (rb_mod_class_variables): need not to call rb_cvar_singleton().\n\n\t* variable.c (rb_cvar_singleton): removed.\n\nMon Feb 11 00:10:41 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* regex.c (re_compile_fastmap): skip begpos.\n\nSun Feb 10 16:52:53 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ruby.c (load_file): avoid SEGV on '#' only input.\n\nFri Feb  8 23:07:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): singleton check should be moved from yycompile\n\t  to here.\n\n\t* eval.c (is_defined): check should be added here too.\n\nFri Feb  8 05:31:48 2002  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: HTTP.Proxy should use self for proxy-class's\n\t  super class.\n\n\t* lib/net/http.rb: initialize HTTP.proxy_port by HTTP.port.\n\nFri Feb  8 01:27:33 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yycompile): should inherit \"in_single\" if eval happened\n\t  in a singleton method.\n\n\t* eval.c (rb_eval): class variables from singleton methods defined\n\t  within singleton class statement should work like ones defined\n\t  by singleton def statements.\n\nThu Feb  7 13:44:08 2002  akira yamada  <akira@arika.org>\n\n\t* uri/common.rb (URI::join): new method.\n\n\t* uri/generic.rb (Generic#merge): URI.parse(\"http://a/\")+\"b\" should\n\t  return \"http://a/b\" but it returned \"http://a//b\".\n\n\t* uri/generic.rb (Generic#check_path): corrected error message,\n\t  @path -> v\n\nThu Feb  7 00:18:43 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_write): flag when buffered write is done.\n\n\t* io.c (fptr_finalize): do not raise error on EBADF if write\n\t  buffer is empty.\n\nWed Feb  6 17:18:54 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* configure.in: keep old config.h unless changed.\n\nWed Feb  6 13:28:53 2002  Amos Gouaux  <amos+ruby@utdallas.edu>\n\n\t* lib/net/imap.rb: OpenSSL support.\n\n\t* lib/net/imap.rb (setquota): unset quota if the second argument\n\t  is nil.\n\nWed Feb  6 13:05:11 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_readlines): avoid calling GetOpenFile() repeatedly.\n\n\t* io.c (rb_io_each_line): ditto.\n\n\t* io.c (argf_getline): ditto.\n\n\t* process.c: should include <time.h> to get proper CLK_TCK.\n\nWed Feb  6 02:10:30 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* io.c (fptr_finalize): ignore EBADF when f and f2 use same\n\t  descriptor.\n\nTue Feb  5 16:17:20 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (fptr_finalize): should raise error when fclose fails.\n\n\t* eval.c (method_inspect): proper output format to distinguish\n\t  methods and singleton methods.\n\nMon Feb  4 22:44:58 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (rb_file_s_expand_path): should terminate.\n\nMon Feb  4 15:38:29 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_class_real): should not follow ICLASS link\n\n\t* variable.c (classname): should follow ICLASS link explicitly.\n\n\t* eval.c (rb_call): ditto.\n\nFri Feb  1 19:10:04 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* intern.h: prototypes for new functions; rb_cstr_to_inum(),\n\t  rb_str_to_inum(), rb_cstr_to_dbl(), rb_str_to_dbl()\n\n\t* bignum.c (rb_cstr_to_inum): changed from rb_cstr2inum(), and\n\t  added argument badcheck to be consistent with parser. [new]\n\n\t* bignum.c (rb_str_to_inum): ditto.\n\n\t* bignum.c (rb_cstr2inum): wrapper of rb_cstr_to_inum() now.\n\n\t* bignum.c (rb_str2inum): ditto.\n\n\t* object.c (rb_cstr_to_dbl): float number parser. [new]\n\n\t* object.c (rb_str_to_dbl): ditto.\n\n\t* object.c (rb_Float): use rb_cstr_to_dbl() for strict check.\n\n\t* object.c (rb_Integer): use rb_str_to_inum() for strict check.\n\n\t* string.c (rb_str_to_f): use rb_str_to_dbl() with less check.\n\n\t* string.c (rb_str_to_i): use rb_str_to_inum() with less check.\n\n\t* string.c (rb_str_hex): ditto.\n\n\t* string.c (rb_str_oct): ditto.\n\n\t* sprintf.c (rb_f_sprintf): ditto.\n\n\t* time.c (obj2long): ditto.\n\n\t* parse.y (yylex): use rb_cstr_to_inum() for strict check.\n\nFri Feb  1 17:46:39 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* regex.c (mbc_startpos): become macro.\n\n\t* regex.c (euc_startpos): added for improvement.\n\n\t* regex.c (sjis_startpos): ditto.\n\n\t* regex.c (utf8_startpos): ditto.\n\nFri Feb  1 00:03:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_stat_inspect): print dev, rdev in hexadecimal.\n\nThu Jan 31 20:45:33 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/mkmf.rb (dir_config): prior --with flag.\n\n\t* lib/mkmf.rb (arg_config): avoid special variables for\n\t  font-lock-mode.\n\nThu Jan 31 13:22:36 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb (File::Stat#pretty_print): print rdev_major and rdev_minor.\n\nWed Jan 30 15:58:04 2002  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* regex.c (re_adjust_startpos): fix for SJIS and UTF-8.\n\n\t* regex.c (mbc_startpos): ditto.\n\nWed Jan 30 13:37:05 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (rb_reg_search): should set regs.allocated.\n\nWed Jan 30 02:25:38 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* regex.c (re_adjust_startpos): search start of multibyte\n\t  backward.\n\n\t* regex.c (mbc_startpos): ditto.\n\nTue Jan 29 17:59:20 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* file.c: `major' and `minor' macro needs sys/mkdev.h on SunOS 5.x.\n\n\t* configure.in: add check for `sys/mkdev.h'.\n\n\t* lib/pp.rb: don't print a mode File::Stat as decimal number.\n\nMon Jan 28 19:16:58 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* array.c (rb_ary_fill): shouldn't yield unless block given.\n\nMon Jan 28 18:33:18 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (yylex): strict check for numbers.\n\nMon Jan 28 18:01:01 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_stat_rdev_major): added. [new]\n\n\t* file.c (rb_stat_rdev_minor): added. [new]\n\n\t* file.c (rb_stat_inspect): print mode in octal.\n\nMon Jan 28 13:29:41 2002  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (is_defined): defined?(Foo::Baz) should check constants\n\t  only, no methods.\n\n\t* eval.c (is_defined): should not dump core on defined?(a::b)\n\t  where a is not a class nor a module.\n\nMon Jan 28 02:50:12 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (Init_Object): remove dup and clone from TrueClass,\n\t  FalseClass, and NilClass.\n\n\t* array.c (rb_ary_fill): Array#fill takes block to get the value to\n\t  fill.\n\nSat Jan 26 20:05:18 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_to_i): to_i(0) auto-detects base radix.\n\n\t* array.c (rb_ary_initialize): fill by the block evaluation value\n\t  if block is given.\n\nFri Jan 25 17:48:43 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in (solaris): add '-shared' only for GNU ld.\n\nFri Jan 25 17:16:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_include_module): detect cyclic module inclusion.\n\nFri Jan 25 02:17:56 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_cleanup): need not to free thread stacks at\n\t  process termination.\n\n\t* array.c (rb_ary_fetch): use the block to get the default value\n\t  if the block is given.\n\n\t* eval.c (rb_thread_schedule): should check time only if BOTH\n\t  WAIT_SELECT and WAIT_TIME.\n\nThu Jan 24 11:49:05 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (umethod_bind): should update rklass field.\n\n\t* hash.c (rb_hash_update): if a block is given, yields [key,\n\t  value1, value2] to the block to resolve conflict.\n\nThu Jan 24 05:42:01 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* string.c (rb_str_split_m): no need to consider KANJI\n\t  characters, if the length of separator is 1 (byte).\n\nWed Jan 23 16:07:31 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (Init_Array): remove Array#filter.\n\nWed Jan 23 13:27:44 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_yield_0): restore source file/line after yield.\n\nWed Jan 23 02:00:14 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_initialize): should accept zero argument.\n\n\t* object.c (rb_mod_cmp): should raise ArgumentError if\n\t  inheritance/inclusion relation between two classes/modules is\n\t  not defined. [new]\n\nTue Jan 22 17:45:23 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fsync): new method. [new]\n\nMon Jan 21 22:57:18 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* signal.c (ruby_signal): must define sighandler_t for every\n\t  occasion.\n\nMon Jan 21 08:25:30 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_stop): should not trace error handler.\n\n\t* signal.c (install_sighandler): do not install sighandler unless\n\t  the old value is SIG_DFL.\n\n\t* io.c (io_write): should not raise exception on O_NONBLOCK io.\n\n\t* dir.c (dir_set_pos): seek should return dir, pos= should not.\n\nSat Jan 19 02:31:45 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): need not to clear method cache for NODE_CLASS,\n\t  NODE_SCLASS.\n\n\t* gc.c (obj_free): need not to clear method cache on class/module\n\t  finalization.\n\nFri Jan 18 23:38:03 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_fetch): index out of range raises exception\n\t  unless optional second argument is specified.\n\nFri Jan 18 17:32:09 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_s_new): block check moved from initialize to this\n\t  method.\n\n\t* io.c (rb_io_s_open): open should call initialize too. IO#for_fd\n\t  also calls initialize. [new]\n\nFri Jan 18 10:26:33 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_sys_fail): replace INT2FIX() by INT2NUM() since\n\t  errno value may not fit in Fixnum size on Hurd.\n\n\t* error.c (set_syserr): ditto.\n\nFri Jan 18 10:12:00 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (tcp_svr_s_open): fix typo.\n\nFri Jan 18 02:27:48 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_s_glob): returns nil if block given.\n\n\t* io.c (rb_io_each_byte): should return self.\n\n\t* io.c (rb_io_close_m): close check added.\n\n\t* dir.c (dir_seek): should return pos.\n\nFri Jan 18 01:21:53 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (fixpos): orig may be (NODE*)1, which should not be\n\t  dereferenced.\n\nThu Jan 17 16:21:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): allow \"retry\" from within argument passed\n\t  block. [new]\n\n\t* eval.c (localjump_error): should preserve exit status in the\n\t  exception object. [new]\n\n\t* eval.c (proc_invoke): should raise exception for \"break\" if it's\n\t  yielding, not calling. [new]\n\n\t* eval.c (block_pass): should NOT raise exception for \"break\". [new]\n\n\t* eval.c (block_pass): should allow block argument relay even in\n\t  the tainted mode.\n\nThu Jan 17 04:51:48 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c: support subclassing by proper \"initialize\"\n\t  calling convention. [new]\n\nWed Jan 16 18:25:08 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.c: primes should be primes.\n\nWed Jan 16 12:29:14 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/timeout.rb (timeout): new optional argument to specify an\n\t  exception class.\n\n\t* lib/resolv.rb: use Resolv::ResolvTimeout for internal timeout to\n\t  avoid problem with timeout of application.\n\nWed Jan 16 11:12:30 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* object.c (rb_Float): remove underscores between digits.\n\n\t* bignum.c (rb_cstr2inum): reject prefix followed by spaces only.\n\n\t* class.c (rb_class_inherited): should use Object when no super\n\t  class.\n\nTue Jan 15 01:11:44 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): method defined? check should honor\n\t  protected too.\n\nMon Jan 14 13:06:02 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): should not pass tainted block, if $SAFE > 0.\n\nSun Jan 13 09:31:41 2002  Koji Arai  <jca02266@nifty.ne.jp>\n\n\t* variable.c (rb_mod_remove_cvar): should pass the char*.\n\nFri Jan 11 05:06:25 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* class.c (rb_make_metaclass): [new]\n\n\t* class.c (rb_define_class_id): use rb_make_metaclass(), don't\n\t  call Class#inherited hook.\n\n\t* class.c (rb_class_inherited): [new]\n\n\t* class.c (rb_define_class): call Class#inherited hook here.\n\n\t* class.c (rb_define_class_under): ditto after class path is set.\n\n\t* class.c (rb_singleton_class): use rb_make_metaclass().\n\n\t* eval.c (rb_eval): same as rb_define_class_under().\n\n\t* intern.h: prototypes of rb_make_metaclass() and\n\t  rb_class_inherited().\n\n\t* object.c (rb_class_s_new): use rb_make_metaclass() and\n\t  rb_class_inherited().\n\n\t* object.c (Init_Object): use rb_make_metaclass().\n\n\t* struct.c (make_struct): use rb_class_inherited().\n\nThu Jan 10 19:15:15 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_add_method): should clear cache by id always.\n\n\t* eval.c (rb_disable_super): no longer need to clear cache before\n\t  rb_add_method().\n\n\t* eval.c (rb_export_method): ditto.\n\n\t* eval.c (rb_attr): ditto.\n\n\t* eval.c (rb_undef): ditto.\n\n\t* eval.c (rb_eval): ditto.\n\n\t* eval.c (rb_mod_modfunc): ditto.\n\n\t* eval.c (rb_mod_define_method): ditto.\n\nThu Jan 10 11:42:47 2002  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/resource.rb: Modify copyright in resource script.\n\nThu Jan 10 07:15:44 2002  takuma ozawa  <metal@mine.ne.jp>\n\n\t* re.c (match_select): should propagate taintness.\n\nThu Jan 10 00:54:57 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_set_default): Hash#default= should return the\n\t  new value.\n\nWed Jan  9 20:21:09 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): indentation after\n\t  comment at beginning of buffer failed.\n\n\t* misc/ruby-mode.el (font-lock-defaults): unless XEmacs, set\n\t  font-lock variables in ruby-mode-hook.\n\nTue Jan  8 15:56:20 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_to_i): accepts optional base argument. [new]\n\n\t* numeric.c (rb_fix2str): should not handle negative fixnum values\n\t  int32 via calling sprintf() directly.\n\nTue Jan  8 15:54:02 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_add_method): clear replaced method from the cache.\n\nMon Jan  7 12:38:47 2002  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb (Time#xmlschema): new optional argument\n\t  fractional_seconds to specify a number of digits of\n\t  fractional part of the time.\n\nSat Jan  5 13:18:11 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* range.c (range_member): beginning check was\n\t  wrong. [ruby-talk:30252]\n\nSat Jan  5 03:07:34 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_new2): NULL pointer check added.\n\nSat Jan  5 00:19:12 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (yycompile): strdup()'ed twice.\n\nFri Jan  4 18:29:10 2002  Michal Rokos  <m.rokos@sh.cvut.cz>\n\n\t* class.c (rb_define_module_under): should locate predefined\n\t  module using rb_const_defined_at().\n\nFri Jan  4 17:23:49 2002  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* misc/ruby-mode.el (ruby-forward-string): forward a string. [new]\n\n\t* misc/ruby-mode.el (ruby-parse-region): handle nested parentheses\n\t  in a string and terminators in #{}.\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): ditto.\n\nWed Jan  2 23:34:25 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): add -I. to CPPFLAGS.\n\n\t* lib/mkmf.rb (create_makefile): srcdir support(.def and depend file).\n\nWed Jan  2 11:51:56 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_f_system): abandon vfork.\n\n\t* io.c (pipe_open): ditto.\n\nTue Jan  1 02:16:48 2002  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/curses/extconf.rb: add dir_config.\n\n\t* Makefile.in (fake.rb): set RUBY_VERSION.\n\nMon Dec 31 14:20:46 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (yycompile): always store copy of filename.\n\n\t* parse.y (rb_compile_file): no longer need to strdup() here.\n\nMon Dec 31 05:26:40 2001  Ferris McCormick  <fmccor@inforead.com>\n\n\t* defines.h: sparc linux needs different FLUSH_REGISTER_WINDOWS\n\nMon Dec 31 04:27:28 2001  Minero Aoki  <aamine@mx.edit.ne.jp>\n\n\t* lib/net/protocol.rb: Protocol#start returns the return value of\n\t  block.\n\n\t* lib/net/protocol.rb: set timeout limit by default.\n\n\t* lib/net/protocol.rb: new methods WriteAdapter#write, puts,\n\t  print, printf.\n\n\t* lib/net/http.rb: rename HTTP#get2 to request_get, post2 to\n\t  request_post ...\n\n\t* lib/net/smtp.rb: should not resolve HELO domain automatically.\n\nSun Dec 30 00:59:16 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb (have_library): accept -lm\n\t  unconditionally on mswin32/mingw32.\n\nSat Dec 29 01:55:42 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_search): abandon stclass optimization.\n\nFri Dec 28 14:39:05 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* array.c (rb_cmpint): fixed typo.\n\nThu Dec 27 18:43:04 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* bignum.c (rb_cstr2inum): deny \"0_\".\n\nThu Dec 27 01:54:02 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* bignum.c (rb_cstr2inum): allow \"0\\n\" and so on.\n\nWed Dec 26 19:24:21 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_invalid_str): utility function to show inspect()'ed\n\t  string.\n\n\t* bignum.c (rb_cstr2inum): prints invalid strings in inspect()'ed\n\t  format.\n\n\t* object.c (rb_Float): ditto.\n\nWed Dec 26 02:41:29 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_convert_type): no longer use rb_rescue().\n\nTue Dec 25 18:32:16 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* re.c (rb_reg_search): initialize taint status of match object.\n\nTue Dec 25 02:37:49 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/pp.rb, lib/prettyprint.rb: new files.\n\nTue Dec 25 02:11:17 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_convert_type): check method response check before\n\t  invoking rb_rescue().\n\n\t* object.c (rb_check_convert_type): ditto.\n\nMon Dec 24 02:37:40 2001  Le Wang  <lewang@bigfoot.com>\n\n\t* misc/ruby-mode.el (ruby-font-lock-syntactic-keywords):\n\t  fix font-lock problem [ruby-talk:29296].\n\nSat Dec 22 22:52:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_timeval): wrong cast to time_t.\n\n\t* time.c (time_plus): ditto.\n\nFri Dec 21 20:33:34 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* parse.y (str_extend): make up \"#$;\" handling.\n\nFri Dec 21 16:18:17 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* dln.h, ruby.h, util.h: enable prototypes in C++.\n\nFri Dec 21 15:12:41 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_plus): result should not be negative unless\n\t  NEGATIVE_TIME_T is defined.\n\n\t* time.c (time_new_internal): should check tv_sec overflow too.\n\n\t* time.c (time_timeval): should check time_t range when time is\n\t  initialized from float.\n\n\t* time.c (time_plus): uses modf(3).\n\nFri Dec 21 03:15:52 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_mod_define_method): must not convert Method to Proc.\n\nFri Dec 21 01:17:57 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/mkmf.rb (with_destdir): new.\n\n\t* lib/mkmf.rb: prefix target directories with $(DESTDIR) all.\n\n\t* lib/mkmf.rb: no need to mkdir $(libdir)\n\nThu Dec 20 14:08:20 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: rename Net::Socket to Net::BufferedSocket\n\nThu Dec 20 13:51:52 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* variable.c (rb_cvar_set): add frozen class/module check.\n\n\t* variable.c (rb_cvar_declare): add frozen class/module check.\n\nThu Dec 20 01:01:50 2001  takuma ozawa  <metal@mine.ne.jp>\n\n\t* re.c (match_to_a): should propagate taint.\n\n\t* re.c (rb_reg_s_quote): ditto.\n\nWed Dec 19 16:58:29 2001  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/readline/readline.c: new methods\n\t  Readline::basic_word_break_characters,\n\t  Readline::basic_word_break_characters=,\n\t  Readline::completer_word_break_characters,\n\t  Readline::completer_word_break_characters=,\n\t  Readline::basic_quote_characters,\n\t  Readline::basic_quote_characters=,\n\t  Readline::completer_quote_characters,\n\t  Readline::completer_quote_characters=,\n\t  Readline::filename_quote_characters,\n\t  Readline::filename_quote_characters=.\n\nWed Dec 19 14:05:00 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_define_method): define_method should follow\n\t  default method visibility.\n\n\t* eval.c (rb_attr): should warn if the default method visibility\n\t  is \"module_function\" (can be error).\n\n\t* eval.c (rb_mod_define_method): should define class/module method\n\t  also if the visibility is \"module_function\".\n\n\t* eval.c (rb_mod_define_method): should call hook method\n\t  \"method_added\", and \"singleton_method_added\".\n\nWed Dec 19 11:42:13 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* string.c: use RESIZE_CAPA for capacity change.\n\nWed Dec 19 03:08:40 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/time.rb: date.rb is not required anymore.\n\n\t* lib/resolv.rb: fix document.  refine IPv6 regex.\n\nTue Dec 18 23:24:53 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (Init_socket): add listen method to\n\t  TCPServer and UNIXServer.\n\nTue Dec 18 17:54:53 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* sample/test.rb: Hash#indexes -> Hash#select.\n\nTue Dec 18 01:02:13 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): should not select a thread which is\n\t  not yet initialized.\n\nMon Dec 17 18:53:49 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* string.c (rb_str_replace): swap arguments of OBJ_INFECT.\n\nMon Dec 17 16:52:20 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* intern.h: add prototypes.\n\t  rb_gc_enable(), rb_gc_disable(), rb_gc_start(), rb_str_new5()\n\t  rb_str_buf_append(), rb_str_buf_cat(), rb_str_buf_cat2(),\n\t  rb_str_dup_frozen()\n\n\t* ruby.h: added declaration.\n\t  rb_defout, rb_stdin, rb_stdout, rb_stderr, ruby_errinfo\n\n\t* rubyio.h: changed double include guard macro to RUBYIO_H.\n\n\t* array.c (inspect_call): make static.\n\n\t* eval.c (dvar_asgn): ditto.\n\n\t* io.c (rb_io_close_read): ditto.\n\n\t* lex.c (rb_reserved_word): ditto.\n\n\t* ruby.c: (req_list_head, req_list_last): ditto.\n\n\t* ruby.c (require_libraries): ditto.\n\nMon Dec 17 15:41:24 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_plus): wrong boundary check.\n\n\t* time.c (time_minus): ditto.\n\nMon Dec 17 15:19:32 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c: new method `gmtoff', `gmt_offset' and `utc_offset'.\n\t  (time_utc_offset): new function.\n\t  (Init_Time): bind above methods to `time_utc_offset'.\n\n\t* time.c: 64bit time_t support.\n\t  (time_s_at): use NUM2LONG instead of NUM2INT for tv_sec.\n\t  (time_arg): initialize tm_isdst correctly.\n\t  use long to initialize tm_year.\n\t  (search_time_t): renamed from `make_time_t'.\n\t  (make_time_t): call `timegm' and `mktime' instead of `search_time_t'\n\t  if available.\n\t  (time_to_i): use LONG2NUM instead of INT2NUM.\n\t  (time_localtime): check localtime failure.\n\t  (time_gmtime): check gmtime failure.\n\t  (time_year): use LONG2NUM instead of INT2FIX.\n\t  (time_to_a): use long for tm_year.\n\t  (time_dump): check tm_year which is not representable with 17bit.\n\t  (time_load): initialize tm_isdst.\n\n\t* configure.in: check existence of `mktime' and `timegm'.\n\t  check existence of tm_gmtoff field of struct tm.\n\t  fix negative time_t for 64bit time_t.\n\n\t* missing/strftime.c: fix overflow by tm_year + 1900.\n\n\t* lib/time.rb: use Time#utc_offset.\n\nMon Dec 17 00:02:04 2001  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* variable.c (find_class_path): should initialize iv_tbl if it's\n\t  NULL.\n\nFri Dec 14 04:23:36 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb: new method Net::POP3.APOP\n\n\t* lib/net/http.rb: set default Content-Type to\n\t  x-www-form-urlencoded (causes warning)\n\n\t* lib/net/protocol.rb: remove Net::NetPrivate module.\n\n\t* lib/net/smtp.rb: ditto.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/http.rb: ditto.\n\nFri Dec 14 00:16:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_define_class): should return the existing class if\n\t  the class is already defined and its superclass is identical to\n\t  the specified superclass.\n\n\t* class.c (rb_define_class_under): ditto.\n\n\t* class.c (rb_define_module): should return the existing module if\n\t  the module is already defined.\n\nThu Dec 13 09:52:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_new_internal): avoid loop to calculate negative\n\t  div, mod.\n\n\t* time.c (time_cmp): should handle Bignums.\n\nTue Dec 11 17:39:16 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* array.c (rb_ary_pop): should ELTS_SHARED flag check before\n\t  REALLOC.\n\nTue Dec 11 12:45:28 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_match_m): should convert an argument into\n\t  regexp if it's a string.\n\nTue Dec 11 03:40:23 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_select): Array#select(n,m,...) now works like\n\t  Array#indexes(n,m,..). [new, experimental]\n\n\t* hash.c (rb_hash_select): ditto.\n\n\t* hash.c (env_select): ditto.\n\n\t* re.c (match_select): ditto.\n\n\t* struct.c (rb_struct_select): ditto.\n\nTue Dec 11 03:17:19 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* object.c (rb_class_real): follow included modules.\n\nMon Dec 10 23:37:51 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* util.h: change prototype of ruby_qsort() to accord with its\n\t  definition.\n\nMon Dec 10 20:30:01 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* gc.c (STR_ASSOC): use FL_USER3 instead of FL_USER2.\n\nMon Dec 10 17:40:02 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* parse.y (str_extend): make up pushback call.\n\nMon Dec 10 02:09:28 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_modify): should copy the internal buffer if the\n\t  modifying buffer is shared.\n\n\t* array.c (ary_make_shared): make an internal buffer of an array\n\t  to be shared.\n\n\t* array.c (rb_ary_shift): avoid sliding an internal buffer by\n\t  using shared buffer.\n\n\t* array.c (rb_ary_subseq): avoid copying the buffer.\n\nMon Dec 10 01:06:56 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (gettable): should freeze __FILE__ string.\n\nSun Dec  9 18:06:26 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: calls on_connect before conn_command\n\nSat Dec  8 23:27:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_puts): old behavior restored.  rationale: a) if you\n\t  want to call to_s for arrays, you can just call print a, \"\\n\".\n\t  b) to_s wastes memory if array (and sum of its contents) is\n\t  huge.  c) now any object that has to_ary is treated as an array,\n\t  using rb_check_convert_type().\n\nSat Dec  8 22:40:38 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_initialize): now accepts a block to calculate\n\t  the default value. [new]\n\n\t* hash.c (rb_hash_aref): call \"default\" method to get the value\n\t  corresponding to the non existing key.\n\n\t* hash.c (rb_hash_default): get the default value based on the\n\t  block given to 'new'.  Now it takes an optional \"key\" argument.\n\t  \"default\" became the method to get the value for non existing\n\t  key.  Users may override \"default\" method to change the hash\n\t  behavior.\n\n\t* hash.c (rb_hash_set_default): clear the flag if a block is given\n\t  to 'new'\n\nSat Dec  8 02:29:54 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (Init_Object): undef Data.allocate, left Data.new.\n\nFri Dec  7 19:12:14 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/smtp.rb: SMTP.new requires at least one arg.\n\n\t* lib/net/pop.rb: POP.new requires at least one arg.\n\n\t* lib/net/pop.rb: uses \"raise *Error.new\" instead of simple raise.\n\n\t* lib/net/http.rb: HTTP.new requires at least one arg.\n\n\t* lib/net/http.rb: changes implicit start algorithm.\n\nFri Dec  7 15:49:39 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* ext/extmk.rb.in: ignore adding -Wl,-R to DLDFLAGS when the directory\n\t  is $topdir.\n\nFri Dec  7 13:58:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/curses/curses.c (window_scrollok): use RTEST().\n\n\t* ext/curses/curses.c (window_idlok): ditto.\n\n\t* ext/curses/curses.c (window_keypad): ditto.\n\n\t* ext/curses/curses.c (window_idlok): idlok() may return void on\n\t  some platforms; so don't use return value.\n\n\t* ext/curses/curses.c (window_scrollok): ditto for consistency.\n\n\t* ext/curses/curses.c: replace FIX2INT() by typechecking NUM2INT().\n\nFri Dec  7 09:51:00 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (str_extend): should not process immature #$x and\n\t  #@x interpolation, e.g #@#@ etc.\n\nFri Dec  7 03:21:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_sort_by): sort_by does not have to be stable always.\n\n\t* enum.c (enum_sort_by): call qsort directly to gain performance.\n\nThu Dec  6 18:52:28 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* ext/extmk.rb.in: add -Wl,-R flags to DLDFLAGS on netbsdelf.\n\n\t* lib/mkmf.rb: ditto.\n\nThu Dec  6 09:15:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* util.c (ruby_qsort): ruby_qsort(qs6) is now native thread safe.\n\n\t* error.c (rb_sys_fail): it must be a bug if it's called when\n\t  errno == 0.\n\nWed Dec  5 23:36:56 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (WC2MBC1ST): should not pass through > 0x80 number in UTF-8.\n\nWed Dec  5 20:05:18 2001  Florian Frank  <flori@ping.de>\n\n\t* ext/socket/socket.c (bsock_send): should raise EWOULDBLOCK\n\t  exception.\n\n\t* ext/socket/socket.c (s_recvfrom): ditto.\n\n\t* ext/socket/socket.c (s_accept): ditto.\n\n\t* ext/socket/socket.c (udp_send): ditto.\n\nTue Dec  4 17:43:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h (DUPSETUP): new SETUP macro for duplication.\n\n\t* time.c (time_dup): implement in Time class using DUPSETUP.\n\n\t* time.c (time_getlocaltime): new method;  probably requires\n\t  better name than getlocaltime. [new,experimental]\n\n\t* time.c (time_getgmtime): ditto.\n\n\t* array.c (rb_ary_dup): uses DUPSETUP.\n\n\t* string.c (rb_str_dup): uses DUPSETUP.  now properly copies\n\t  instance variables too.\n\nTue Dec  4 03:49:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_fread): EAGAIN/EWOULDBLOCK should not terminate and\n\t  throw away the input.\n\n\t* time.c (time_new_internal): underflow adjustment must not use\n\t  negative div/mod.\n\n\t* time.c (time_cmp): should consider tv_usec on non Fixnum number\n\t  comparison.\nSun Dec  9 23:00:54 2001  Keiju Ishitsuka <keiju@ishitsuka.com>\n\t* matrix.rb: Vector#* bug. reported from Massimiliano Mirra\n\t  <info@chromatic-harp.com>.\n\nSun Dec  9 22:15:59 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* enum.c (enum_sort_by): should replace with last elements.\n\nMon Dec  3 16:06:57 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/extconf.rb: remove -L/usr/local/lib.\n\n\t* configure.in: add -Wl,-export-dynamic on NetBSD.\n\nMon Dec  3 16:04:16 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* configure.in: not use X11BASE, since it's not always set.\n\nMon Dec  3 13:53:49 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c (rb_strftime): buffer length condition was wrong.\n\n\t* time.c (time_strftime): should backup buf to the original\n\t  buffer.\n\nMon Dec  3 09:59:08 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_plus): must detect result overflow.\n\n\t* time.c (time_minus): ditto.\n\n\t* time.c (time_new_internal): round usec overflow and underflow\n\t  here.\n\n\t* time.c (time_plus): move operand overflow/underflow check to\n\t  time_new_internal().\n\n\t* time.c (time_minus): ditto.\n\n\t* time.c (time_cmp): should consider tv_usec too.\n\nMon Dec  3 03:32:22 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* configure.in: apply patch from NetBSD's pkgsrc (patch-aa).\n\nSun Dec  2 22:01:52 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: use GCC, not without_gcc. remove without_gcc.\n\n\t* ext/curses/extconf.rb: check for curses.h.\n\n\t* ext/dbm/extconf.rb: check if $CFLAGS includes DBM_HDR.\n\nSat Dec  1 12:13:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_gmtime): time_modify() should be called even if tm\n\t  struct is not calculated yet.\n\nFri Nov 30 17:02:55 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: set target_cpu to i386 on cygwin and mingw32.\n\n\t* configure.in: default --enable-shared to yes on cygwin and mingw32.\n\nFri Nov 30 00:25:28 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* README.EXT: Appendix B is duplicated.\n\n\t* README.EXT.ja: ditto.\n\nThu Nov 29 00:28:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_equal): object with to_str must be treated as a\n\t  string.\n\nWed Nov 28 18:46:28 2001  Ville Mattila  <mulperi@iki.fi>\n\n\t* eval.c (rb_thread_select): should subtract timeofday() from\n\t  limit, not reverse.\n\nWed Nov 28 16:03:28 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* util.c (scan_hex): x is not a hexadecimal digit.\n\nWed Nov 28 13:38:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): should treat the case that\n\t  select(2) returns 0, if a thread is under both WAIT_SELECT and\n\t  WAIT_TIME.  Jakub Travnik <J.Travnik@sh.cvut.cz> actually fixed\n\t  this bug.\n\nTue Nov 27 02:15:25 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_float): must distinguish -0.0 from 0.0.\n\nMon Nov 26 20:57:24 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Setup*, ext/syslog/*: import the \"syslog\" module from the\n\t  rough ruby project.\n\nMon Nov 26 16:14:42 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* gc.c (gc_mark_all): tweak mark order for little bit better scan.\n\n\t* gc.c (rb_gc_mark): ditto.\n\n\t* gc.c (rb_gc): ditto.\n\nMon Nov 26 16:54:59 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/win32.c (mypopen): fixed that mypclose() didn't really close\n\t  pipe.\n\n\t* win32/win32.c (CreateChild): set STARTF_USESTDHANDLES flag only\n\t  when some handles are passed.\n\nMon Nov 26 16:31:28 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (sort_by_i): slight performance boost.\n\nSun Nov 25 21:02:18 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* parse.y (str_extend): change types of second and third arguments\n\t  from char to int.\n\nThu Nov 22 20:15:28 2001  TAMURA Takashi  <sheepman@tcn.zaq.ne.jp>\n\n\t* gc.c (gc_mark_rest): should call gc_mark_children(), not gc_mark().\n\n\t* gc.c (rb_gc_mark): may cause infinite loop.\n\nThu Nov 22 00:28:13 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (str_extend): should check nesting parentheses in #{}.\n\nWed Nov 21 12:22:52 2001  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/cgi.rb: CGI#header: do not set Apache.request.status for\n\t  Location: if Apache.request.status is already set.\n\nWed Nov 21 02:24:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (pst_wstopsig): returns nil unless WIFSTOPPED() is\n\t  non-zero.\n\n\t* process.c (pst_wtermsig): returns nil unless WIFSIGNALED() is\n\t  non-zero.\n\n\t* process.c (pst_wexitstatus): returns nil unless WIFEXITED() is\n\t  non-zero.\n\nWed Nov 21 00:17:54 2001  Ville Mattila  <mulperi@iki.fi>\n\n\t* eval.c (rb_thread_select): tv_sec and tv_usec should not be\n\t  negative.\n\n\t* signal.c (posix_signal): do not set SA_RESTART for SIGVTALRM.\n\nTue Nov 20 21:09:22 2001  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* parse.y (call_args2): block_arg may follow the first argument in\n\t  call_args2.\n\nTue Nov 20 02:01:15 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (stack_check): should avoid stack length check during\n\t  raising SystemStackError exception.\n\nTue Nov 20 01:07:13 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (str_extend): should not terminate string interpolation\n\t  with newlines in here-docs and newline terminated strings.\n\nMon Nov 19 17:58:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_modfunc): should follow NODE_ZSUPER link; based\n\t  on Guy Decoux's patch in [ruby-talk:25478].\n\nMon Nov 19 16:09:33 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* string.c (rb_str_succ): there was buffer overrun.\n\nMon Nov 19 14:14:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (str_extend): term can be any character.\n\nMon Nov 19 04:58:42 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb (header): support for Apache. thanks to\n\t  Shugo Maeda <shugo@ruby-lang.org>.\n\nSun Nov 18 19:37:55 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y: needless conditionals.\n\n\t* parse.y (parse_regx): parse error at unterminated regex /#{.\n\t  (ruby-bugs-ja:PR#142)\n\nSat Nov 17 12:37:39 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_unpack): should give length to utf8_to_uv().\n\n\t* pack.c (utf8_to_uv): add length check.\n\nSat Nov 17 01:41:52 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* massages: replace \"wrong #\" by \"wrong number\".\n\n\t* marshal.c (w_float): output Infinity and NaN explicitly.\n\n\t* marshal.c (r_object): support new explicit float format.\n\n\t* eval.c (rb_thread_wait_for): select may cause ERESTART on\n\t  Solaris.\n\n\t* eval.c (rb_thread_select): ditto.\n\nThu Nov 15 15:29:39 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* array.c (rb_ary_join): non-nil separator must be converted to\n\t  String.  and separators' total length was wrong.\n\nThu Nov 15 03:37:17 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* hash.c (ruby_setenv): remove USE_WIN32_RTL_ENV block since it's\n\t  obsoleted.\n\n\t* win32/win32.c, win32/win32.h: sort out #if 0 - #endif or others.\n\nThu Nov 15 00:07:12 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_to_s): if rb_output_fs is nil, insert newlines\n\t  between array elements (use rb_default_rs as newline literal)\n\t  [experimental].\n\nWed Nov 14 15:16:23 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* gc.c (init_mark_stack): no need to clear mark_stack.\n\n\t* gc.c (gc_mark_all): need to handle finalizer mark.\n\n\t* gc.c (gc_mark_rest): use MEMCPY instead of memcpy.\n\n\t* gc.c (rb_gc_mark): earlier const check to avoid pusing special\n\t  constants into mark stack.\n\nWed Nov 14 01:12:07 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* win32/win32.c (waitpid): fix wait count.\n\n\t* win32/win32.c (poll_child_status): rename from wait_child().\n\nWed Nov 14 01:33:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_to_s): 'to_s' now takes optional argument to\n\t  specify radix. [new]\n\n\t* bignum.c (rb_big_to_s): ditto. [new]\n\nTue Nov 13 19:50:30 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: do not override CC if set.\n\nTue Nov 13 16:49:16 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/win32.c (mypopen): return error status instead of calling\n\t  rb_sys_fail().\n\n\t* win32/win32.c (do_spawn): ditto.\n\nTue Nov 13 14:39:11 2001  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* signal.c (sighandle): should not re-register sighandler if\n\t  POSIX_SIGNAL is defined.\n\nTue Nov 13 12:55:59 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/win32.c (do_spawn): use CreateChild() instead of calling\n\t  CreateProcess() directly. Original patches comes from Patrick Cheng.\n\n\t* win32/win32.c (mypopen): ditto.\n\n\t* win32/win32.c (mypclose): use rb_syswait() instead of waiting in this\n\t  function.\n\n\t* win32/win32.c (waitpid): use wait_child() instead of _cwait().\n\n\t* win32/win32.c (CreateChild): added. [new]\n\n\t* win32/win32.c (wait_child): added. [new]\n\n\t* win32/win32.c (FindFirstChildSlot): added. [new]\n\n\t* win32/win32.c (FindChildSlot): added. [new]\n\n\t* win32/win32.c (FindPipedChildSlot): added. [new]\n\n\t* win32/win32.c (CloseChildHandle): added. [new]\n\n\t* win32/win32.c (FindFreeChildSlot): added. [new]\n\nTue Nov 13 12:38:12 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* hash.c (envix): use GET_ENVIRON and FREE_ENVIRON to get environment\n\t  variables list.\n\n\t* hash.c (env_keys): ditto.\n\n\t* hash.c (env_each_key): ditto.\n\n\t* hash.c (env_values): ditto.\n\n\t* hash.c (env_keys): ditto.\n\n\t* hash.c (env_each_value): ditto.\n\n\t* hash.c (env_each): ditto.\n\n\t* hash.c (env_inspect): ditto.\n\n\t* hash.c (env_to_a): ditto.\n\n\t* hash.c (env_size): ditto.\n\n\t* hash.c (env_empty_p): ditto.\n\n\t* hash.c (env_has_value): ditto.\n\n\t* hash.c (env_index): ditto.\n\n\t* hash.c (env_to_hash): ditto.\n\n\t* win32/win32.c (win32_getenv): use static buffer.\n\n\t* win32/win32.c, win32/win32.h (win32_get_environ): get environment\n\t  variables list. [new]\n\n\t* win32/win32.c, win32/win32.h (win32_free_environ): free environment\n\t  variables list. [new]\n\nMon Nov 12 16:48:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (error_print): errat array may be empty.\n\nMon Nov 12 01:30:37 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval_cmd): should not upgrade safe level unless\n\t  explicitly specified by argument newly added.\n\n\t* signal.c (sig_trap): should not allow tainted trap closure.\n\n\t* variable.c (rb_f_trace_var): should not allow trace_var on safe\n\t  level higher than 3.\n\n\t* variable.c (rb_f_trace_var): should not allow tainted trace\n\t  closure.\n\nSun Nov 11 00:12:23 2001  TAMURA Takashi  <sheepman@tcn.zaq.ne.jp>\n\n\t* gc.c: do not use static stack until system stack overflows.\n\nSat Nov 10 03:57:09 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): should call Exception#exception instead of\n\t  calling rb_exc_new3() directly.\n\n\t* error.c (exc_exception): set \"mesg\" directly to the clone.  it\n\t  might be better to set mesg via some method for flexibility.\n\nSat Nov 10 00:14:24 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (cvar_override_check): should print original module\n\t  name, if 'a' is T_ICLASS.\n\n\t* parse.y (yylex): float '1_.0' should not be allowed.\n\n\t* variable.c (var_getter): should care about var as Qfalse\n\t  (ruby-bugs#PR199).\n\nFri Nov  9 13:50:06 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/config.status.in: make CFLAGS same as Makefile's one.\n\nThu Nov  8 20:20:37 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_trap_eval): avoid annoying warning with signal.\n\t  [ruby-talk:23225]\n\n\t* eval.c (rb_call0): adjust caller source file/line while\n\t  evaluating optional arguments.\n\nThu Nov  8 18:41:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (cmpint): <=> or block for {min,max} may return bignum.\n\n\t* array.c (sort_1): use rb_compint.\n\n\t* array.c (sort_2): ditto.\n\n\t* enum.c (min_ii): ditto.\n\n\t* enum.c (min_ii): ditto.\n\n\t* enum.c (max_i): ditto.\n\n\t* enum.c (max_ii): ditto.\n\nThu Nov  8 18:21:02 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (path_check_1): forgot to initialize 'p'.\n\nThu Nov  8 14:52:15 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* mkconfig.rb: use String#dump to generate Ruby string literal.\n\nThu Nov  8 15:46:54 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_eql): should override 'eql?'\n\n\t* array.c (rb_ary_hash): should override 'hash' too.\n\nTue Nov  6 14:38:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (security): always give warning for insecure PATH.\n\n\t* dir.c (my_getcwd): do not rely on MAXPATHLEN.\n\n\t* file.c (rb_file_s_readlink): ditto.\n\n\t* file.c (path_check_1): ditto.\n\nTue Nov  6 14:17:14 2001  Amos Gouaux <amos+ruby@utdallas.edu>\n\n\t* lib/net/imap.rb (getquota_response): use astring for mailbox\n\t  names.\n\n\t* lib/net/imap.rb (getacl_response): ditto.\n\nMon Nov  5 17:09:55 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): should not call rb_f_block_given_p().\n\nSat Nov  3 23:33:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_chomp_bang): should terminate string by NUL.\n\nSat Nov  3 22:28:51 2001  Keiju Ishitsuka <keiju@ishitsuka.com>\n\n\t* matrix.rb (Matrix#column_vectors, Matrix#row_vectors): ditto bug.\n\t  this bug report and fix by tsutomu@nucba.ac.jp.\n\n\t* forwardable.rb: change raise to Kernel::raise\n\nSat Nov  3 10:11:57 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): better error message.\n\nThu Nov  1 14:08:42 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_aref): idx may be a Bignum.\n\n\t* numeric.c (fix_aref): negative index must return zero.\n\nThu Nov  1 13:23:50 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (gc_mark_children): should NOT treat last element of\n\t  structs and arrays specially.\n\nWed Oct 31 16:59:25 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (exec_under): should initialize ruby_frame->self;\n\nWed Oct 31 15:09:28 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (POP_VARS): should not set DVAR_DONT_RECYCLE if _old\n\t  ruby_vars is already force_recycled.\n\nWed Oct 31 10:28:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc): handles mark stack overflow.\n\n\t* gc.c (PUSH_MARK): use static mark stack, no more recursion.\n\nWed Oct 31 02:44:06 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: CGI::Cookie::parse(): Ignore duplicate keys caused by\n\t  Netscape bug.\n\nTue Oct 30 18:21:51 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* win32/mkexports.rb: follow the change of rb_io_puts().\n\nTue Oct 30 14:04:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_chomp_bang): do smart chomp if $/ == '\\n'. [new]\n\n\t* io.c (rb_io_puts): don't treat Array specially.\n\n\t* bignum.c (rb_big_cmp): should convert bignum to float.\n\n\t* eval.c (rb_f_eval): can't modify untainted binding.\n\nMon Oct 29 16:08:30 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): should preserve p0 value.\n\nMon Oct 29 14:56:44 2001  Usaku Nakamura <usa@ruby-lang.org>\n\n\t* intern.h (rb_protect_inspect): follow the change of array.c.\n\n\t* eval.c (rb_exec_end_proc): follow the change of rb_protect().\n\n\t* eval.c (method_proc, umethod_proc, rb_catch): cast the first\n\t  parameter of rb_iterate() to avoid VC++ warning.\n\n\t* range.c (range_step): ditto.\n\n\t* ext/sdbm/init.c (fsdbm_update, fsdbm_replace): ditto.\n\nMon Oct 29 07:57:31 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (str_extend): should allow interpolation of $-x.\n\n\t* variable.c (rb_cvar_set): empty iv_tbl may cause infinite loop.\n\n\t* variable.c (rb_cvar_get): ditto.\n\n\t* variable.c (cvar_override_check): ditto.\n\nSat Oct 27 23:01:19 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_eq): convert Bignum to Float, instead of\n\t  reverse.\n\nFri Oct 26 06:19:29 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_localtime): getting tm should not be prohibited for\n\t  frozen time objects.\n\n\t* time.c (time_gmtime): ditto.\n\n\t* version.c (Init_version): freeze RUBY_VERSION,\n\t  RUBY_RELEASE_DATE, and RUBY_PLATFORM.\n\n\t* file.c (Init_File): freeze File::SEPARATOR, ALT_SEPARATOR and\n\t  PATH_SEPARATOR.\n\n\t* file.c (rb_stat_cmp): should check operand type before calling\n\t  get_stat().\n\nThu Oct 25 10:28:15 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval_cmd): should not invoke \"call\" with a block on\n\t  any occasion.\n\nWed Oct 24 03:25:31 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_aref): idx may be a Bignum.\n\nTue Oct 23 01:21:19 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (proc_invoke): fix self switching in Proc#call\n\t  (ruby-bugs-ja#PR108) and GC failure.  use Qundef instead of 0\n\t  to direct not switching self.\n\n\t* eval.c (call_trace_func): ditto.\n\n\t* eval.c (call_end_proc): ditto.\n\n\t* eval.c (proc_call): ditto.\n\n\t* eval.c (proc_yield): ditto.\n\nTue Oct 23 01:15:43 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* variable.c (rb_global_entry): reconstruct global variable\n\t  aliasing (sharing global_entry->var with other global_entry).\n\n\t* variable.c (undef_getter): ditto.\n\n\t* variable.c (undef_setter): ditto.\n\n\t* variable.c (val_setter): ditto.\n\n\t* variable.c (mark_global_entry): ditto.\n\n\t* variable.c (rb_define_hooked_variable): ditto.\n\n\t* variable.c (rb_f_trace_var): ditto.\n\n\t* variable.c (remove_trace): ditto.\n\n\t* variable.c (rb_f_untrace_var): ditto.\n\n\t* variable.c (rb_gvar_get): ditto.\n\n\t* variable.c (trace_en): ditto.\n\n\t* variable.c (rb_gvar_set): ditto.\n\n\t* variable.c (rb_gvar_defined): ditto.\n\n\t* variable.c (rb_alias_variable): ditto.\n\nMon Oct 22 18:53:55 2001  Masahiro Tanaka  <masa@stars.gsfc.nasa.gov>\n\n\t* numeric.c (num_remainder): a bug in Numeric#remainder.\n\nMon Oct 22 15:21:55 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_exec_end_proc): END might be called within END\n\t  block.\n\n\t* class.c (rb_mod_clone): should not copy class name, since clone\n\t  should remain anonymous.\n\nFri Oct 19 23:40:37 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* variable.c (remove_trace): should not access already freed area.\n\n\t* variable.c (rb_f_untrace_var): fix memory leak.\n\nFri Oct 19 17:55:14 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* marshal.c (w_uclass): cloned class is not user\n\t  class. (ruby-bugs-ja#PR103)\n\n\t* marshal.c (r_object): Struct subclass couldn't\n\t  load. (ruby-bugs-ja#PR104)\n\nWed Oct 17 14:12:50 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* variable.c (alias_fixup): added. ad hoc support for ordinary\n\t  global variable aliasing. when original entry is set, make the\n\t  alias to refer directly as possible.\n\n\t* variable.c (alias_getter, alias_setter): ditto.\n\n\t* variable.c (rb_alias_variable): ditto. and no need to mark alias\n\t  variables.\n\n\t* variable.c (rb_gvar_defined): refer the original entry of an alias.\n\nTue Oct 16 23:29:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): self in a block given to define_method now be\n\t  switched to the receiver of the method.\n\n\t* eval.c (proc_invoke): added new parameter to allow self\n\t  switching.\n\nTue Oct 16 21:38:15 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_f_missing): check stack level with rb_stack_check().\n\n\t* eval.c (rb_call0): ditto.\n\n\t* eval.c, intern.h (rb_stack_check): added. [new]\n\nTue Oct 16 13:18:47 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* object.c (rb_mod_initialize): optional block with\n\t  Module.new. [new] (from 2001-10-10)\n\nTue Oct 16 00:07:06 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (yylex): disallow alpha-numeric and mbchar for\n\t  terminator of %string.\n\nMon Oct 15 18:00:05 2001  Pit Capitain  <pit@capitain.de>\n\n\t* string.c (rb_str_index): wrong increment for non alphanumeric\n\t  string.\n\nMon Oct 15 05:23:02 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* sprintf.c (rb_f_sprintf): support \"%B\".\n\nWed Oct 10 03:11:47 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_stat_clone): should copy internal data too.\n\n\t* numeric.c (num_clone): Numeric should not be copied by clone.\n\n\t* object.c (rb_obj_clone): should check immediate values.\n\n\t* parse.y (command): `yield' should take command_args.\n\n\t* parse.y (parse_quotedwords): %w(...) is not a string.\n\nTue Oct  9 18:40:35 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* process.c (Init_process): activate the case NT.\n\nTue Oct  9 17:08:00 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (thread_status_name): separated from\n\t  rb_thread_inspect(). return string expression for thread status.\n\n\t* eval.c (rb_thread_status, rb_thread_inspect): use\n\t  thread_status_name().\n\n\t* eval.c (rb_thread_priority_set): return the priority not but\n\t  self.\n\nSat Oct  6 23:07:08 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): NODE_MATCH3 was confusing left and right. sigh.\n\nFri Oct  5 15:19:46 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_unique): should not dump anonymous class.\n\nFri Oct  5 11:59:13 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (proc_s_new): revived.\n\n\t* eval.c (Init_Proc): define Proc.new instead of Proc.allocate to\n\t  inhibit from creating uninitialized Proc.\n\nThu Oct  4 14:11:03 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): EALREADY is the equivalent\n\t  for EINPROGRESS in ws2_32.lib.\n\nWed Oct  3 20:11:06 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* re.c (rb_reg_s_alloc): avoid infinite recursion.\n\nWed Oct  3 16:49:49 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/gdbm/gdbm.c (rb_gdbm_fetch): str is a VALUE now.\n\nWed Oct  3 13:32:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_object): better allocation type check for\n\t  TYPE_UCLASS. usage of allocation framework is disabled for now.\n\n\t* variable.c (rb_class_path): Module may have subclass.\n\n\t* string.c (rb_str_update): should maintain original negative\n\t  offset.\n\n\t* string.c (rb_str_subpat_set): ditto\n\n\t* string.c (rb_str_aset): ditto.\n\n\t* re.c (rb_reg_nth_match): should check negative nth.\n\n\t* re.c (rb_reg_nth_defined): ditto.\n\nTue Oct  2 19:12:47 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ftools.rb (catname): allow trailing '/' for the destination.\n\nTue Oct  2 18:31:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should override existing class.\n\nTue Oct  2 17:08:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_alloc): general instance allocation framework.\n\t  use of NEWOBJ() is deprecated except within 'allocate' method.\n\nTue Oct  2 08:04:52 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* marshal.c (r_object): TYPE_UCLASS check should be inversed.\n\nMon Oct  1 19:18:54 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* ext/socket/socket.c (unix_addr): getsockname(2) may result len = 0.\n\n\t* ext/socket/socket.c (unix_peeraddr): getpeername(2) may result\n\t  len = 0.\n\nMon Oct  1 09:59:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_subpat_set): support function for new argument\n\t  pattern String#[re,offset] = val. [new]\n\nSat Sep 29 02:30:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (POP_BLOCK): rb_gc_force_recycle() was called too much.\n\t  Should not be called if SCOPE_DONT_RECYCLE is set.\n\nWed Sep 26 22:21:52 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_aref_m): new argument pattern\n\t  String#[re,offset]. [new]\n\nWed Sep 26 19:02:39 2001  Guy Decoux  <ts@moulon.inra.fr>\n\n\t* parse.y: allow 'primary[] = arg'\n\nTue Sep 25 10:46:42 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* win32/win32.c (isInternalCmd): check return value of NtMakeCmdVector\n\t  (Tietew <tietew@tietew.net>'s patch).\n\nMon Sep 24 00:55:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_substr): should return an instance of\n\t  receiver's class.\n\n\t* string.c (rb_str_succ): ditto.\n\n\t* array.c (rb_ary_subseq): ditto.\n\n\t* array.c (rb_ary_initialize): Array.new([1,2,3]) => [1,2,3]. [new]\n\nSat Sep 22 22:16:08 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_reverse): should return an instance of\n\t  receiver's class.\n\n\t* string.c (rb_str_times): ditto.\n\n\t* array.c (rb_ary_times): ditto\n\n\t* string.c (str_gsub): ditto.\n\n\t* string.c (rb_str_ljust): ditto.\n\n\t* string.c (rb_str_rjust): ditto.\n\n\t* string.c (rb_str_center): ditto.\n\nSat Sep 22 12:13:39 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (eval): retrieves file, line information from binding.\n\nThu Sep 20 21:25:00 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (MATCH_DATA): access via rb_svar().\n\nThu Sep 20 15:20:00 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c, intern.h (rb_svar): return reference to special variable\n\t  from local variable index. [new]\n\n\t* eval.c (rb_eval): use rb_svar() for NODE_FLIP{2,3}.\n\n\t* parse.y (rb_(backref|lastline)_(get|set)): access via rb_svar().\n\n\t* eval.c (proc_invoke): push dynamic variables.\n\n\t* eval.c (rb_thread_yield): push special variables as dynamic\n\t  variables($_, $~ and FLIP states).\n\nThu Sep 20 15:20:00 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* intern.h, parse.y (rb_is_local_id): return true if the ID is\n\t  local symbol. [new]\n\n\t* parse.y (internal_id): make new ID for internal use. [new]\n\n\t* parse.y (cond0): allocate internal ID for NODE_FLIP{2,3}.\n\n\t* eval.c (rb_f_local_variables): use rb_is_local_id() to select\n\t  visible local variables.\n\nThu Sep 20 15:20:00 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_thread_start_0): SCOPE_SHARED is removed.\n\n\t* eval.c, intern.h (rb_thread_scope_shared_p): removed. special\n\t  variables are no longer shared by threads.\n\n\t* re.c (rb_reg_search): MATCHDATA is no longer shared by threads.\n\nTue Sep 18 11:44:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_init): String.new() => \"\" [new]\n\nTue Sep 11 20:53:56 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_path): new method.\n\n\t* dir.c (dir_initialize): wrap DIR into struct, along with path\n\t  information.\n\nSat Sep  8 07:13:42 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/net/telnet.rb: waitfor(): improvement. thanks to\n\t  nobu.nakada@nifty.ne.jp\n\nSat Sep  8 04:34:17 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_restore_context): save current value of\n\t  lastline and lastmatch in the thread struct for later restore.\n\n\t* eval.c (rb_thread_save_context): restore lastline and lastmatch.\n\nFri Sep  7 11:27:56 2001  akira yamada  <akira@ruby-lang.org>\n\n\t* numeric.c (flo_to_s): should handle negative float value.\n\nFri Sep  7 09:44:44 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/net/telnet.rb: waitfor(): bug fix.\n\nFri Sep  7 07:11:34 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: CGI#doctype(): bug fix (html4Fr).\n\n\t* lib/net/telnet.rb, lib/cgi.rb: remove VERSION, RELEASE_DATE,\n\t  VERSION_CODE, RELEASE_CODE. please use REVISION.\n\n\t* lib/cgi.rb: CGI#header(): bug fix.\n\n\t* lib/net/telnet.rb, lib/cgi.rb: concat --> +=\n\nThu Sep  6 17:38:18 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* dir.c (dir_s_chdir): raise if environment variable HOME/LOGDIR\n\t  not set.\n\n\t* dir.c (glob_helper): avoid infinite loop on a file name with\n\t  wildcard characters. (ruby-bugs#PR177)\n\nThu Sep  6 14:25:15 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/digest.c (rb_digest_base_s_hexdigest): remove a debug\n\t  print.\n\nThu Sep  6 13:56:14 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/digest.c (rb_digest_base_s_digest,\n\t  rb_digest_base_s_hexdigest): ensure that a string is given.\n\nThu Sep  6 13:28:51 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/jcode.rb (_regexp_quote): fix quote handling, again.\n\nThu Sep  6 07:28:56 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (rb_find_file_ext): add const qualifiers to ext.\n\n\t* intern.h (rb_find_file_ext): ditto.\n\nThu Sep  6 07:16:14 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/socket/socket.c (Init_socket): remove duplicating constants.\n\nThu Sep  6 03:15:24 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_include_module): should check whole ancestors to\n\t  avoid duplicate module inclusion.\n\nWed Sep  5 20:02:27 2001  Shin'ya Adzumi  <adzumi@denpa.org>\n\n\t* string.c (trnext): should check backslash before updating \"now\"\n\t  position.\n\nWed Sep  5 17:41:11 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/jcode.rb (_regexp_quote): fix quote handling.\n\nTue Sep  4 01:03:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (Init_Regexp): to_s to be alias to inspect.\n\nMon Sep  3 22:46:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): should support 'keyword='.\n\nMon Sep  3 20:26:08 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* intern.h (rb_find_file_ext): changed from rb_find_file_noext().\n\nMon Sep  3 15:12:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (proc_options): should not adjust argc/argv if -e option\n\t  is supplied.\n\nMon Sep  3 14:11:17 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* error.c: unbreak the build on *BSD with gcc 3.0.1 by removing\n\t  the conflicting declaration of sys_nerr for *BSD.\n\nSat Sep  1 18:50:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (proc_options): should not alter origargv[].\n\n\t* ruby.c (set_arg0): long strings for $0 dumped core.\n\nSat Sep  1 09:50:54 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ruby.c (set_arg0): prevent SEGV when val is longer than the\n\t  original arguments.\n\n\t* ruby.c (ruby_process_options): initialize total length of\n\t  original arguments at first.\n\nSat Sep  1 14:05:28 2001  Brian F. Feldman  <green@FreeBSD.org>\n\n\t* ruby.c (set_arg0): use setprogtitle() if it's available.\n\nSat Sep  1 03:49:11 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_popen): accept integer flags as mode.\n\nFri Aug 31 19:46:05 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (rb_find_file_ext): extension table can be supplied from\n\t  outside.  renamed.\n\n\t* eval.c (rb_f_require): replace rb_find_file_noext by\n\t  rb_find_file_ext.\n\nFri Aug 31 19:26:55 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_provided): should also check feature without\n\t  extension.\n\nFri Aug 31 13:06:33 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (flo_to_s): do not rely on decimal point to be '.'\n\nWed Aug 29 02:18:53 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): ternary ? can be followed by newline.\n\nTue Aug 28 00:40:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_require): should check static linked libraries\n\t  before raising exception.\n\nFri Aug 24 15:17:40 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_equal): check identity equality first.\n\n\t* string.c (rb_str_equal): ditto.\n\n\t* struct.c (rb_struct_equal): ditto.\n\nFri Aug 24 14:38:17 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* dln.c (dln_strerror): fix a bug that sometimes made null message on\n\t  win32 (Tietew <tietew@tietew.net>'s patch).\n\n\t* win32/win32.c (mystrerror): ditto.\n\nFri Aug 24 03:15:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (Init_Numeric): undef Integer::new.\n\nFri Aug 24 00:46:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): NODE_WHILE should update result for each\n\t  conditional evaluation.\n\n\t* eval.c (rb_eval): NODE_UNTIL should return last evaluated value\n\t  (or value given to break).\n\nThu Aug 23 21:59:38 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* enum.c (sort_by_i): fix typo.\n\nThu Aug 23 10:10:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): should not dump core for \"defined?(())\".\n\n\t* eval.c (umethod_bind): recv can be an instance of descender of\n\t  oklass if oklass is a Module.\n\nWed Aug 22 23:20:03 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_equal): check identity equality first.\n\nWed Aug 22 19:58:59 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (intersect_fds): counts intersecting fds.\n\n\t* eval.c (rb_thread_schedule): only fds requested by\n\t  each thread count as select_value.\n\nTue Aug 21 22:28:09 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (group_member): should check real gid only.\n\n\t* file.c (eaccess): do not cache euid, since effective euid may be\n\t  changed via Process.euid=().\n\n\t* file.c (eaccess): return -1 unless every specified access mode\n\t  is permitted.\n\nTue Aug 21 16:09:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): while/until returns the value which is given\n\t  to break.\n\n\t* parse.y (value_expr): using while/until/class/def as an\n\t  expression is now gives a warning, not an error.\n\nTue Aug 21 11:56:02 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_eqq): should compare strings based on magical\n\t  increment (using String#upto), not dictionary order.\n\nMon Aug 20 19:53:16 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/digest/sha2/extconf.rb: fix support for cross-compiling.\n\n\t* mkconfig.rb: fix support for autoconf 2.52.\n\nMon Aug 20 17:24:15 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_sort_by): new method for Schewartzian transformed\n\t  stable sort.\n\nMon Aug 20 16:09:05 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (mod_av_set): detect constant overriding for built-in\n\t  classes/modules.\n\nMon Aug 20 15:14:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (tokadd_escape): escaped backslashes too much.\n\nMon Aug 20 13:24:08 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_step): 'iter' here should be an array.\n\nMon Aug 20 12:43:08 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): should retrieve __member__ data from\n\t  non-singleton class.\n\nSat Aug 18 23:11:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_cvar_get): class variable override check added.\n\n\t* variable.c (rb_cvar_set): ditto\n\n\t* variable.c (rb_cvar_declare): ditto.\n\nFri Aug 17 12:13:48 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/protocol.rb: Protocol.new requires at least one arg.\n\n\t* lib/net/smtp.rb: ditto.\n\n\t* lib/net/pop.rb: ditto.\n\n\t* lib/net/http.rb: ditto.\n\nFri Aug 17 00:49:51 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (parse_regx): handle backslash escaping of delimiter here.\n\nThu Aug 16 23:03:40 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* io.c: prevent recursive malloc calls on NEC UX/4800.\n\n\t* ext/socket/socket.c: ditto.\n\nThu Aug 16 13:54:04 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (s_recvfrom): fix typo.\n\nThu Aug 16 09:53:28 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* ext/socket/socket.c (s_recvfrom): avoid VC++6 warning.\n\nThu Aug 16 03:50:33 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* win32/win32.c (NtCmdGlob): avoid VC++ warning.\n\n\t* lib/mkmf.rb: add -I$(srcdir) to CPPFLAGS.\n\nWed Aug 15 04:59:15 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/*/extconf.rb: really fix so that they build from any\n\t  directory.\n\nWed Aug 15 04:04:02 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/sha2/extconf.rb: fix so that they build from any\n\t  directory.\n\nWed Aug 15 01:59:19 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/defs.h: Define NO_UINT64_T instead of emitting an\n\t  error to fail.\n\n\t* ext/digest/sha2/extconf.rb: Do not exit on error, and utilize\n\t  NO_UINT64_T to detect if the system has a 64bit integer type.\n\nTue Aug 14 21:14:07 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/digest/sha2/extconf.rb: do not create Makefile when no 64bit\n\t  integer type is detected.\n\nTue Aug 14 17:09:12 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_step): new method.\n\nTue Aug 14 11:49:00 2001  TOYOFUKU Chikanobu  <toyofuku@juice.or.jp>\n\n\t* string.c (rb_str_cmp): remove needless conditional.\n\nTue Aug 14 03:23:25 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* string.c (rb_str_lstrip_bang) `return Qnil' was missing.\n\nMon Aug 13 14:16:46 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* bignum.c, marshal.c: Detypo: s/SIZEOF_ING/SIZEOF_INT/.\n\nSun Aug 12 15:01:58 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* string.c (rb_str_cat): fix buffer overflow.\n\n\t* string.c (rb_str_append): nothing to append actually when `str2'\n\t  is empty.\n\nSat Aug 11 14:43:47 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* array.c (rb_inspecting_p): initialize inspect_key if it is\n\t  not initialized yet.\n\nFri Aug 10 22:14:37 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (cond0): operands of logical operators are not treated\n\t  as conditional expression anymore, but propagate conditional\n\t  status if used in conditionals.\n\nTue Aug  7 09:10:32 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* win32/win32.h: fix problems with BC++ (ruby-bugs#PR161).\n\nMon Aug  6 23:47:46 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* pack.c (pack_pack): associates p/P strings once at last\n\t  (reverted to 1.26).\n\n\t* string.c (rb_str_associate): associates an Array at once, not\n\t  but a String. realloc's when str_buf.\n\nMon Aug  6 17:01:33 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_gc_mark_threads): should mark ruby_cref.\n\nMon Aug  6 14:31:37 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* numeric.c (num_divmod): fix typo.\n\nMon Aug  6 03:29:03 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_lstrip_bang): new method.\n\n\t* string.c (rb_str_rstrip_bang): new method.\n\nMon Aug  6 00:35:03 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* struct.c (rb_struct_modify): should check frozen and taint\n\t  status.\n\nSun Aug  5 19:28:39 2001  Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>\n\n\t* string.c (rb_str_associate): should consider STR_ASSOC too.\n\nSun Aug  5 07:46:18 2001  Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_undefined): do not recurse if method_missing is\n\t  undefined.\n\nThu Aug  2 21:37:32 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_waitpid): now all arguments are optional.\n\n\t* process.c (Init_process): waitpid is now alias to wait.\n\n\t* process.c (Init_process): waitpid2 is now alias to wait2.\n\n\t* process.c (rb_waitpid): made public.\n\n\t* ext/pty/pty.c (pty_getpty): avoid disturbing SIGCHLD using\n\t  thread and rb_waitpid.\n\nThu Aug  2 11:23:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_getpgrp): now takes no argument on all\n\t  platforms.\n\n\t* process.c (proc_setpgrp): ditto.\n\nThu Aug  2 01:29:42 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (strrdirsep): removed meaningless code.\n\n\t* file.c (rb_file_s_expand_path): reverted to 1.66.\n\nWed Aug  1 16:17:47 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/socket/socket.c (sock_s_pack_sockaddr_in): added\n\t  Socket::pack_sockaddr_in(). [new]\n\n\t* ext/socket/socket.c (sock_s_pack_sockaddr_un): added\n\t  Socket::pack_sockaddr_un(). [new]\n\n\t* ext/socket/socket.c (sock_s_pack_sockaddr_in): added\n\t  Socket::unpack_sockaddr_in(). [new]\n\n\t* ext/socket/socket.c (sock_s_pack_sockaddr_un): added\n\t  Socket::unpack_sockaddr_un(). [new]\n\nWed Aug  1 15:42:16 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* eval.c (ruby_run): avoid VC++ warning.\n\nTue Jul 31 17:30:53 2001  Usaku Nakamura  <usa@ruby-lang.org>\n\n\t* marshal.c (Init_marshal): fix typos.\n\nTue Jul 31 15:16:39 2001  Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>\n\n\t* process.c (last_status_set): nothing returned, should be void.\n\n\t* ext/socket/socket.c (load_addr_info): ditto.\n\nTue Jul 31 12:11:42 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (Init_marshal): new constant Marshal::MAJOR_VERSION\n\t  and Marshal::MINOR_VERSION.\n\nTue Jul 31 07:18:04 2001  Nobuyoshi Nakada <nobu.nokada@softhome.net>\n\n\t* file.c (rb_file_s_expand_path): scans per path element not per\n\t  byte/character, including fix of [ruby-talk:18152] and\n\t  multi-byte pathname support.\n\nTue Jul 31 11:52:10 2001  akira yamada  <akira@ruby-lang.org>\n\n\t* marshal.c (marshal_load): ruby_verbose test should be wrapped by\n\t  RTEST().\n\nMon Jul 30 17:54:23 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_index): should return nil (not the default\n\t  value) if value is not in the hash.\n\nMon Jul 30 12:55:47 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (num_div): new method added.  alias to '/' which\n\t  should be preserved even if '/' is redefined (e.g. by\n\t  mathn). [new]\n\nMon Jul 30 11:12:14 2001  Amos Gouaux <amos+ruby@utdallas.edu>\n\n\t* lib/net/imap.rb: added new commands for managing folder quotas\n\t  and folder ACLs.\n\nMon Jul 30 03:19:53 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_cstr2inum): \"0 ff\".hex should return 0, not 255.\n\nFri Jul 27 22:29:41 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (rb_file_s_expand_path): fixed using CharNext().\n\nFri Jul 27 18:07:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_provided): extension should be guessed using\n\t  rb_find_file_noext().\n\n\t* eval.c (rb_f_require): should call rb_feature_p() after\n\t  extension completion.\n\nFri Jul 27 16:25:52 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): add CHECK_INTS before next, redo, retry to\n\t  avoid potential uninterruptable infinite loop.\n\nThu Jul 26 11:27:12 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (rb_find_file_noext, rb_find_file): fix tilde expansion\n\t  problem.\n\nWed Jul 25 17:54:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_s_expand_path): use CharNext() to expand.\n\nWed Jul 25 17:16:26 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* intern.h: add some missing function prototypes.\n\nWed Jul 25 15:50:05 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* file.c (rb_file_s_expand_path): should not expand \".\" and \"..\"\n\t  not following dirsep.\n\nWed Jul 25 12:15:32 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (rb_find_file_noext): should update f by expanded path.\n\n\t* file.c (rb_find_file): ditto.\n\nTue Jul 24 23:10:47 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (strrdirsep): multi-byte pathname and DOSish separator\n\t  support. originally comes from Patrick Cheng. [new]\n\n\t* file.c (rb_file_s_basename, rb_file_s_dirname): use\n\t  strrdirsep(). comes from Patrick Cheng.\n\n\t* file.c (is_absolute_path): restricted in DOSish absolute path\n\t  with drive letter, and UNC support. originally comes from\n\t  Patrick Cheng.\n\n\t* file.c (getcwd): define macro using getwd() unless provided.\n\nTue Jul 24 19:23:15 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: dig the target subdirectory for\n\t  lib/* files properly in case of create_makefile(\"dir/name\").\n\nMon Jul 23 00:26:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_provide_feature): should not tweak extension used for\n\t  loading.\n\nSun Jul 22 21:16:43 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: introduce a couple of new make\n\t  variables: CLEANFILES and DISTCLEANFILES.  They'd typically be\n\t  defined in a file \"depend\".\n\nSat Jul 21 09:40:10 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* io.c (io_fread): use fread(3) if PENDING_COUNT is available.\n\nFri Jul 20 22:55:01 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* gc.c (ruby_xrealloc): fix a dangling bug which led memory\n\t  reallocation to fail even though the second try after a GC\n\t  succeeds.\n\nFri Jul 20 03:00:46 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* class.c (rb_mod_include_p): Module#include? added. [new]\n\nFri Jul 20 01:05:50 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (ignorecase_setter): give warning on modifying $=.\n\n\t* string.c (rb_str_casecmp): new method. [new]\n\n\t* string.c (rb_str_eql): separated from rb_str_equal(), make it\n\t  always be case sensitive. [new]\n\n\t* string.c (rb_str_hash): made it always be case sensitive.\n\nThu Jul 19 13:03:15 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_f_require): should not include path in $\" value\n\n\t* file.c (rb_find_file): should return 0 explicitly on failure.\n\nTue Jul 17 11:44:40 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* ruby.h: enable volatile directive with VC++.\n\n\t* regex.c: ditto.\n\nTue Jul 17 06:01:12 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* doc/net/smtp.rd.ja, pop.rd.ja, http.rd.ja: new files.\n\n\t* MANIFEST: add doc/net/{http,pop,smtp}.rd.ja.\n\nTue Jul 17 11:22:01 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (NUM_FAILURE_ITEMS): was confusing NUM_REG_ITEMS and\n\t  NUM_NONREG_ITEMS, which have happened to be same value.\n\nTue Jul 17 11:08:34 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* ext/extmk.rb.in: modify RM macro because command.com/cmd.exe don't\n\t  recognize single quotation as quote character.\n\n\t* lib/mkmf.rb: ditto.\n\nTue Jul 17 01:38:15 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_class_new): subclass check moved to this function.\n\n\t* class.c (rb_class_boot): check less version of rb_class_new().\n\nMan Jul 16 13:21:30 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* file.c (file_load_ok): fix typo.\n\nMon Jul 16 12:58:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_invoke): should preserve iter status for embedded\n\t  frame in the block.\n\nMon Jul 16 00:04:39 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_s_expand_path): may overrun buffer on stack.\n\nSun Jul 15 01:38:28 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* string.c (rb_str_insert): forgot to call rb_str_modify().\n\nSat Jul 14 12:26:30 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/digest/*/extconf.rb: fix so that they build from any\n\t  directory.\n\nSat Jul 14 06:20:17 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/net/http.rb: HTTP#proxy? did not worked.\n\nSat Jul 14 02:56:19 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in: support multi-level ext/ directories.\n\t  (e.g. you can have ext/foo, ext/foo/bar and ext/foo/baz)\n\nSat Jul 14 02:55:02 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/.cvsignore: let cvs ignore extinit.c.\n\nFri Jul 13 23:47:35 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_search): should consider reverse search.\n\nFri Jul 13 22:26:09 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb: use File::split to split a target into a prefix and\n\t  a module name.  This also works around a just found bug of\n\t  String#rindex.\n\n\t* ext/extmk.rb.in: ditto.\n\nFri Jul 13 02:36:10 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* dir.c (dir_s_chdir): warn only when invoked from multiple\n\t  threads or block is not given.\n\nThu Jul 12 15:11:48 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): workaround for the setup of\n\t  Cygwin socket(EALREADY).\n\nMon Jul  9 16:49:30 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in: modify RM macro.\n\n\t* lib/mkmf.rb: ditto.\n\nSun Jul  8 20:52:02 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ruby.h: fix a wrong function name: rb_iglob() -> rb_globi().\n\nSun Jul  8 16:04:35 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: rename HTTP#request_by_name to send_request.\n\n\t* lib/net/protocol.rb (ProtoSocket#read): modify typo.\n\nSat Jul  7 17:45:35 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_convert_type): should use rb_rescue(), not rb_rescue2().\n\n\t* range.c (range_init): ditto.\n\nFri Jul  6 18:01:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_dup): copies (actually does not free)\n\t  generic_ivar on dupif original owns them.\n\nFri Jul  6 02:15:06 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/tempfile.rb: a tempfile must be created with mode 0600.\n\nThu Jul  5 20:28:53 2001  Tietew <tietew@tietew.net>\n\n\t* string.c (rb_str_each_line): should propagate taint mark.\n\n\t* ext/nkf/nkf.c (rb_nkf_kconv): ditto.\n\nFri Jul  6 14:54:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_require): revamp for simpler implementation.\n\n\t* file.c (rb_find_file_noext): use String object, instead of\n\t  passing char* around.\n\n\t* file.c (rb_find_file): ditto.\n\nThu Jul  5 22:01:02 2001  Mitsuhiro Kondo  <kondo@nik-prt.co.jp>\n\n\t* dln.c (dln_load): should use NSLINKMODULE_OPTION_BINDNOW.\n\nThu Jul  5 13:44:03 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (load_file): local variables 'c' remain uninitialized on\n\t  xflag.\n\nThu Jul  5 10:00:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_match): prefetched escaped character too early.\n\nWed Jul  4 08:58:30 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): add argument check for attr_readers.\n\nWed Jul  4 04:22:44 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (HTTP#request_by_name): arg order changes.\n\nWed Jul  4 04:07:36 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb (HTTP#request_by_name): bug fix.\n\n\t* lib/net/http.rb: does not write Connection: by default.\n\n\t* lib/net/protocol.rb: \"start\" for started protocol is an error.\n\n\t* lib/net/protocol.rb: \"finish\" for finished protocol is an error.\n\nWed Jul  4 03:17:31 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/http.rb: new method HTTP#request_by_name (test)\n\n\t* lib/net/http.rb: new class HTTPGenericRequest\n\nTue Jul  3 23:58:29 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb: distclean should remove mkmf.log as well.\n\nTue Jul  3 18:35:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval_string_wrap): should push frame (and adjust\n\t  cbase) before wrapped eval.\n\n\t* eval.c (rb_eval_cmd): ditto.\n\n\t* eval.c (eval): should update ruby_class always after all.\n\nTue Jul  3 14:56:27 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* eval.c (block_pass): do not change wrapper information.\n\n\t* eval.c (rb_yield_0):  preserve wrapper information.\n\nTue Jul  3 08:59:50 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* error.c (rb_name_error): raise NameError instead of LoadError.\n\nMon Jul  2 17:22:00 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (exc_exception): clone the receiver exception instead of\n\t  creating brand new exception object of the receiver.\n\nMon Jul  2 09:53:12 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval_string_wrap): extend new ruby_top_self, not\n\t  original self.\n\n\t* eval.c (rb_eval_cmd): respect ruby_wrapper if set.\n\n\t* eval.c (eval): do not update ruby_class unless scope is not\n\t  provided.\n\nSun Jul  1 10:51:15 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* eval.c (eval): preserve wrapper information.\n\n\t* eval.c (proc_invoke): ditto.\n\n\t* eval.c (block_pass): ditto.\n\nSat Jun 30 02:55:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (void_expr): too much warnings for void context\n\t  (e.g. foo[1] that can be mere Proc call).\n\nFri Jun 29 17:23:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_name_error): new function to raise NameError with\n\t  name attribute set.\n\n\t* eval.c (rb_f_missing): set name and args in the exception\n\t  object. [new]\n\n\t* error.c (name_name): NameError#name - new method.\n\n\t* error.c (nometh_args): NoMethodError#args - new method.\n\nFri Jun 29 15:29:31 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lex.c (rb_reserved_word): lex_state after tRESCUE should be\n\t  EXPR_MID.\n\nThu Jun 28 00:21:28 2001  Keiju Ishitsuka <keiju@ishitsuka.com>\n\n\t* lib/matrix.rb: resolve 'ruby -w' warnings.\n\n\t* lib/irb/locale.rb: resolve 'ruby -w' warnings.\n\n\t* lib/irb/multi-irb.rb: resolve 'ruby -w' warnings.\n\n\t* lib/irb/ruby-lex.rb: fix problem for \"\\\\M-\\\\...\" and \"\\\\C-\\\\...\"\n\t  and resolve 'ruby -w' warnings.\n\n\t* lib/irb/ruby-token.rb: fix typo\n\n\t* lib/shell/command-processor.rb: resolve 'ruby -w' warnings.\n\nWed Jun 27 08:53:26 2001  Minero Aoki  <aamine@loveruby.net>\n\n\t* lib/net/pop.rb: new methods POP3.auth_only, POP3#auth_only\n\n\t* lib/net/http.rb: HTTP.Proxy returns self if ADDRESS is nil.\n\n\t* lib/net/protocol.rb: new method ProtocolError#response\n\n\t* lib/net/protocol.rb,smtp.rb,pop.rb,http.rb: add document.\n\nTue Jun 26 18:42:42 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (add_heap): allocation size of the heap unit is doubled for\n\t  each allocation.\n\nMon Jun 25 09:54:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (isdelim): space, tab, and newline are no longer\n\t  delimiters for glob patterns.\n\nSat Jun 23 22:28:52 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (svalue_to_avalue): new conversion scheme between single\n\t  value and array values.\n\n\t* eval.c (avalue_to_svalue): ditto.\n\n\t* eval.c (rb_eval): REXPAND now uses avalue_to_svalue(), return\n\t  and yield too.\n\n\t* eval.c (rb_yield_0): use avalue_to_svalue().\n\n\t* eval.c (proc_invoke): Proc#call gives avaules, whereas\n\t  Proc#yield gives mvalues.\n\n\t* eval.c (bmcall): convert given value (svalue) to avalue.\n\nSat Jun 23 18:28:52 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/readline/readline.c (readline_event): a non-void function\n\t  should return a value.\n\nFri Jun 22 23:17:28 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/socket/socket.c (ruby_connect): workaround for the setup of\n\t  Cygwin socket.\n\nFri Jun 22 23:11:17 2001 Keiju Ishitsuka <keiju@ishitsuka.com>\n\n\t* lib/irb/locale.rb: fix for require \"kconv\" problem\n\nFri Jun 22 18:08:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): no mvalue_to_svalue conversion here.\n\n\t* eval.c (massign): takes svalue, convert it to mvalue inside.\n\n\t* eval.c (rb_eval): parameters for yield/return are always\n\t  svalues now.\n\n\t* eval.c (svalue_to_mvalue): more strict conversion.\n\n\t* eval.c (mvalue_to_svalue): ditto.\n\nFri Jun 22 17:12:23 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.c (new_size): prime hash size enabled.\n\n\t* ext/socket/socket.c (Init_socket): SO_* constants added.\n\nTue Jun 19 22:24:07 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* gc.c (rb_setjmp): avoid GCC 3.0 warnings.\n\nTue Jun 19 18:19:30 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/readline/readline.c: add new methods:\n\t  Readline::completion_append_character and\n\t  Readline::completion_append_character=.\n\nTue Jun 19 16:29:50 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (svalue_to_mvalue): new function to convert from svalue\n\t  to mvalue. [experimental]\n\n\t* eval.c (mvalue_to_svalue): new function to convert from mvalue\n\t  to svalue.\n\n\t* eval.c (rb_eval): use mvalue_to_svalue().\n\n\t* eval.c (rb_yield_0): use mvalue_to_svalue().\n\n\t* eval.c (proc_invoke): proper mvalue handling.\n\nMon Jun 18 17:38:50 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_require): searches \".rb\" and \".so\" at the same\n\t  time.  previous behavior (search \".rb\", then \".so\") has a\n\t  security risk (ruby-bugs#PR140).\n\n\t* array.c (rb_ary_to_ary): new function to replace internal\n\t  rb_Array(), which never calls to_a, but to_ary (rb_Array() might\n\t  call both). [new]\n\nMon Jun 18 00:43:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (PUSH_FAILURE_POINT): push option status again.\n\n\t* regex.c (re_compile_pattern): avoid pushing unnecessary\n\t  option_set.\n\nSat Jun 16 10:58:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): tainted string is OK if wrapped *and*\n\t  $SAFE >= 4.\n\nThu Jun 14 16:27:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): should not nail down higher blocks\n\t  before preserving original context (i.e. should not alter\n\t  original context).\n\nWed Jun 13 19:34:59 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* dir.c (Init_Dir): add a new method File::fnmatch? along with\n\t  File::Constants::FNM_*.  While I am here, FNM_NOCASE is renamed\n\t  to FNM_CASEFOLD which is commonly used by *BSD and GNU libc.\n\nWed Jun 13 09:33:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_yield): new method equivalent to Proc#call but no\n\t  check for number of arguments. [new]\n\nTue Jun 12 14:21:28 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* lib/mkmf.rb: target_prefix is only for installation, not for\n\t  build.\n\nTue Jun 12 00:41:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (method_eq): new method Method#==. [new]\n\nMon Jun 11 14:29:41 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* confgure.in: add RUBY_CANONICAL_BUILD.\n\nSun Jun 10 17:31:47 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* gc.c (STR_NO_ORIG): STR_NO_ORIG value was different between\n\t  string.c and gc.c\n\nSat Jun  9 22:10:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should convert *non-array at the end of\n\t  arguments by using Array().\n\nSat Jun  9 17:04:30 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* hash.c (ruby_setenv): readline library leaves their environment\n\t  strings uncopied.  \"free\" check revised.\n\nSat Jun  9 16:31:03 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* ext/extmk.rb.in: Use -F and -T for mswin32 because cl.exe doesn't\n\t  support -o officially and cl.exe considers that *.cc and *.cxx are\n\t  OBJs.\n\n\t* lib/mkmf.rb: ditto.\n\n\t* win32/Makefile.sub: Use del instead of rm.\n\t  All these changes are derived from Nobuyoshi Nakada's patch.\n\t  Thanks.\n\nFri Jun  8 22:37:40 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (Init_stack): avoid __builtin_frame_address(2) to retrieve\n\t  stack bottom line.\n\nFri Jun  8 18:14:12 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* st.c (numhash): should shuffle bits by dividing by prime number.\n\nFri Jun  8 17:05:21 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): multiple assignment behavior fixed, which\n\t  results \"*a = nil\" makes \"a == []\" now.\n\nFri Jun  8 15:25:09 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_require): should set SCOPE_PUBLIC before calling\n\t  dln_load().\n\nThu Jun  7 17:28:00 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): exclude kDO_BLOCK too much by false condition.\n\nWed Jun  6 23:02:36 2001  Keiju Ishitsuka  <keiju@ishitsuka.com>\n\n\t* lib/sync.rb: bug fix if obj.initialize has parameters when\n\t  obj.extend(Sync_m)\n\n\t* lib/mutex_m.rb: modified bit\n\nWed Jun  6 16:11:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): should check if tainted even when wrap is\n\t  specified.\n\nWed Jun  6 14:34:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (mrhs_basic): \"*arg\" should always be expanded by REXPAND.\n\n\t* regex.c (re_compile_pattern): too much optimization for the\n\t  cases like /(.|a)b/.\n\nTue Jun  5 23:58:43 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (fc_i): removed vast string allocation.\n\nTue Jun  5 16:45:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (Init_Exception): NameError went under StandardError,\n\t  and NoMethodError went under NameError.\n\nTue Jun  5 16:40:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (rb_intern): non identifier symbols should be\n\t  categorized as ID_JUNK. [new]\n\nTue Jun  5 16:15:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_const_at): use hash table as internal\n\t  data. [new]\n\n\t* variable.c (rb_mod_const_of): ditto.\n\n\t* variable.c (rb_const_list): new function to convert internal\n\t  data (hash table) to array of strings.\n\n\t* eval.c (rb_mod_s_constants): data handling scheme has changed.\n\nTue Jun  5 15:16:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_add_method): should not call rb_secure(), for\n\t  last_func may not be set.\n\n\t* io.c (rb_io_ctl): ioctl should accept any integer within C long\n\t  range.\n\nTue Jun  5 13:41:13 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/etc/extconf.rb: use egrep_cpp.\n\nTue Jun  5 12:44:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (r_object): wrong type check for modules.\n\n\t* marshal.c (w_object): should not dump anonymous classes/modules.\n\nTue Jun  5 01:19:34 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_open_file): use rb_file_sysopen_internal() if the 3rd\n\t  argument (permission flags) is given. [new, should be backported?]\n\n\t* io.c (rb_io_mode_binmode): mode string (e.g. \"r+\") to flags to\n\t  open(2).\n\nMon Jun  4 23:55:54 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): NODE_REXPAND expand an array of 1 element as\n\t  the element itself. [new, should be backported?]\n\n\t* parse.y (ret_args): should treat \"*[a]\" in rhs expression as\n\t  \"a\", not \"[a]\".\n\nMon Jun  4 04:14:53 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/shellwords.rb: don't destroy argument.\n\nSat Jun  2 23:23:05 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): should push option modifier at the\n\t  right place.\n\nSat Jun  2 23:05:20 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/cgi/session.rb: don't use module_function for Class.\n\nSat Jun  2 00:02:22 2001  Keiju Ishitsuka <keiju@ishitsuka.com>\n\n\t* irb messages: fix typos.\n\nFri Jun  1 17:26:24 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* hash.c (replace_i): ignore when key == Qundef.\n\nFri Jun  1 16:50:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (call_args2): confusion with list_append() and\n\t  list_concat() was fixed.\n\nFri Jun  1 15:01:40 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): fixed 'print CGI::bar() {}, \"\\n\"' syntax\n\t  breakage, adding new lex_state status.  sigh. [new]\n\nFri Jun  1 11:21:04 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: use waitpid on mingw32.\n\n\t* ext/dbm/extconf.rb: include <ndbm.h>, not <gdbm.h>.\n\nThu May 31 18:34:57 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* file.c (rb_file_s_unlink): should not allow if $SAFE >= 2.\n\nThu May 31 17:23:25 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (Init_Range): define \"to_ary\".\n\nThu May 31 13:30:25 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* mkconfig.rb, ext/configsub.rb: VERSION -> RUBY_VERSION.\n\nThu May 31 08:00:58 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* win32/dir.h: re-add.\n\nThu May 31 01:25:59 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in: default --with-libc_r to `no' until the problem is\n\t  fixed. (FreeBSD only)\n\nTue May 29 17:24:23 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* ruby.c (proc_options): unexpected SecurityError happens when -T4.\n\nTue May 29 18:46:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): * \\1 .. \\9 should be\n\t  backreferences always.\n\n\t* regex.c (re_match): backreferences corresponding to\n\t  unclosed/unmatched parentheses should fail always.\n\nTue May 29 16:35:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cat): use rb_str_buf_cat() if possible. [new]\n\n\t* string.c (rb_str_append): ditto.\n\n\t* string.c (rb_str_buf_cat): remove unnecessary check (type,\n\t  taint, modify) to gain performance.\n\n\t* string.c (rb_str_buf_append): ditto.\n\n\t* string.c (rb_str_buf_finish): removed.\n\nTue May 29 02:05:55 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_buf_new): buffering string function. [new]\n\n\t* string.c (rb_str_buf_append): ditto.\n\n\t* string.c (rb_str_buf_cat): ditto.\n\n\t* string.c (rb_str_buf_finish): ditto.\n\nMon May 28 23:20:43 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: remove unnecessary AC_CANONICAL_BUILD\n\n\t* defines.h: #define HAVE_SETITIMER on Cygwin(bug fixed).\n\n\t* ruby.c: use relative path from LIBRUBY_SO.\n\n\t* ruby.c: don't use -mwin32 option on Cygwin.\n\n\t* cygwin/GNUmakefile.in: ditto.\n\n\t* ext/sdbm/_sdbm: ditto.\n\n\t* ext/tcltklib/extconf.rb: ditto.\n\n\t* ext/tcltklib/stubs.c: ditto.\n\nMon May 28 22:12:01 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/extconf.rb.in: make the priority of the make rule of .c\n\t  higher than .C .\n\nMon May 28 13:22:19 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c (make_time_t): local time adjustment revised.\n\nMon May 28 02:20:38 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* dir.c (glob_helper): teach has_magic() to handle flags and get\n\t  glob_helper to properly support FNM_NOESCAPE.\n\n\t* dir.c (fnmatch): fix a bug when FNM_PATHNAME and FNM_PERIOD are\n\t  specified at the same time.\n\nSat May 26 09:55:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y: accomplish extended syntax described in [ruby-talk:14525]\n\t  using tSPC token. [new, experimental]\n\nSat May 26 07:05:45 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* MANIFEST: add win32/dir.h .\n\nFri May 25 20:03:51 2001  Pascal Rigaux  <pixel@mandrakesoft.com>\n\n\t* dln.c (dln_find_1): should exclude directories in executable\n\t  file lookup.\n\nFri May 25 18:00:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_obj_singleton_methods): list methods in extended\n\t  modules if optional argument is true. [new]\n\nFri May 25 14:19:25 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* string.c (rb_str_replace): add taint status infection\n\t  (OBJ_INFECT()).\n\n\t* string.c (rb_str_crypt): ditto.\n\n\t* string.c (rb_str_ljust): ditto.\n\n\t* string.c (rb_str_rjust): ditto.\n\n\t* string.c (rb_str_center): ditto.\n\nFri May 25 05:39:03 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/sha1/sha1-ruby.c (sha1_hexdigest): fix buffer overflow.  The\n\t  buffer for a SHA-1 hexdigest needs to be 41 bytes in length.\n\nFri May 25 01:47:39 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* MANIFEST: update the entries I forgot to add or remove.\n\nFri May 25 00:57:25 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/sha1/sha1-ruby.c (sha1_new): separate initialize() from\n\t  new().\n\n\t* ext/md5/md5init.c (md5i_new): ditto.\n\nFri May 25 00:53:41 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/dbm/extconf.rb: fix support for *BSD and set $CFLAGS\n\t  properly.\n\nThu May 24 16:10:33 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_member): check based on \"<=>\" comparison. [new]\n\n\t* range.c (range_check): add \"succ\" check if first end is not a\n\t  numeric.\n\n\t* range.c (range_eqq): comparison should based on \"<=>\".\n\n\t* range.c (range_each): ditto.\n\nThu May 24 16:08:21 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* mkconfig.rb: autoconf 2.50 support.\n\nThu May 24 14:23:35 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): need argument adjustment for C defined\n\t  blocks too.\n\nThu May 24 01:11:30 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb: header search added. [new]\n\nWed May 23 02:58:21 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* time.c (make_time_t): fix ad-hoc local time adjustment, using\n\t  binary tree search.\n\nTue May 22 17:10:35 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* variable.c (rb_alias_variable): should not allow variable\n\t  aliasing if $SAFE >= 4.\n\nTue May 22 02:37:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (expr): \"break\" and \"next\" to take optional expression,\n\t  which is used as a value for termination. [new, experimental]\n\n\t* eval.c (rb_eval): \"break\" can give value to terminating method.\n\n\t* eval.c (rb_eval): \"break\" and \"next\" to take optional expression.\n\n\t* eval.c (rb_yield_0): \"next\" can give value to terminating \"yield\".\n\n\t* eval.c (rb_iterate): \"break\" can give value to terminating method.\n\n\t* eval.c (proc_call): ditto.\n\nMon May 21 13:15:25 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big2str): t should be protected from GC.\n\nSat May 19 09:29:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (rb_proc_times): need not to check return value from\n\t  times(2).\n\nFri May 18 05:36:08 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in (xsystem): backout the previous fix which was\n\t  bogus.\n\nFri May 18 05:19:55 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/mkmf.rb (xsystem): make a temporary fix to get $(...) macros\n\t  properly expanded on a command execution.\n\n\t* ext/extmk.rb.in (xsystem): ditto.\n\nFri May 18 03:45:55 2001  Brian F. Feldman  <green@FreeBSD.org>\n\n\t* lib/mkmf.rb: unbreak \"make install\".  lib/* must be installed\n\t  under $rubylibdir, not under $libdir.\n\nFri May 18 01:28:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (expr): break, next, redo, retry are moved from primary.\n\nFri May 18 01:11:02 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* ext/sha1/sha1-ruby.c (sha1_new): get rid of an unneeded\n\t  rb_obj_call_init() call.\n\nFri May 18 01:03:55 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* ext/sha1/sha1.txt, ext/sha1/sha1.txt.jp: fix typos.\n\nThu May 17 19:17:11 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/shell.rb, lib/shell/process-controller.rb,\n\t  lib/shell/command-processor.rb: translate Japanese comments into\n\t  English.\n\nThu May 17 19:07:14 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* doc/shell.rd.jp: RD'ify and make some fixes.\n\n\t* doc/shell.rd: RD'ify, delete Japanese leftovers, make overall\n\t  English fixes, and sync with doc/shell.rd.jp.\n\nThu May 17 17:35:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_call0): address of local_vars might change during eval.\n\nThu May 17 07:27:09 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/md5/md5.txt.jp, ext/sha1/sha1.txt.jp:\n\t  s/SuperClass/Superclass/.\n\nThu May 17 07:21:44 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/Setup.dj, ext/Setup.emx, ext/Setup.nt, ext/Setup.x68:\n\t  compile sha1 in as well as md5.\n\n\t* ext/Setup: put sha1 in a comment.\n\nThu May 17 07:16:38 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/sha1/sha1.txt.jp: add the Japanese version derived from\n\t  ext/md5/md5.txt.jp.\n\n\t* ext/sha1/sha1.txt: revise the copyright info and reduce the\n\t  difference from ext/md5/md5.txt.\n\n\t* ext/md5/md5.txt: reduce the difference from ext/sha1/sha1.txt.\n\nThu May 17 07:11:35 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/sha1/extconf.rb, ext/sha1/sha1.c: use WORDS_BIGENDIAN to\n\t  detect the platform's endian.\n\nThu May 17 06:31:30 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/md5/md5.txt: make wording fixes, and mention the newly added\n\t  method: \"<<\".\n\n\t* ext/md5/md5.txt.jp: ditto.\n\nWed May 16 18:05:52 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/md5/md5init.c: add an instance method \"<<\" as an alias for\n\t  \"update\". (inspired by Steve Coltrin's ruby-sha1)\n\nTue May 15 17:46:37 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_and): should not push frozen key string.\n\n\t* array.c (rb_ary_or): ditto.\n\nTue May 15 02:18:23 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/thread.rb: rescue ThreadError in case the thread is dead\n\t  just before calling Thread#run.\n\nMon May 14 13:50:22 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): should save context before raising\n\t  deadlock, saved context for current thread might be obsolete.\n\n\t* time.c (make_time_t): non DST timezone shift supported (hopefully).\n\n\t* time.c (make_time_t): strict range detection for negative time_t.\n\nMon May 14 11:54:20 2001  Tanaka Akira  <akr@m17n.org>\n\n\t* signal.c: SIGINFO added.\n\nMon May 14 08:57:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_ensure): should not SEGV when prot_tag is NULL.\n\nSun May 13 23:51:14 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* win32/resource.rb: Modify copyright in resource script.\n\nSun May 13 14:03:33 2001  Okada Jun  <yun@be-in.org>\n\n\t* lib/thread.rb: fix Queue#pop and SizedQueue#max= to avoid\n\t  deadlock.\n\nSat May 12 15:43:55 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* win32/win32.c (kill): add support of signal 9 on mswin32/mingw32.\n\nFri May 11 15:09:52 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.h (rb_string_value): add volatile to avoid compiler warning.\n\n\t* string.c (rb_string_value): ditto.\n\nFri May 11 03:35:33 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* README.EXT: Document find_library(), with_config() and\n\t  dir_config().\n\nFri May 11 03:34:20 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* README.EXT.jp: Remove the description of find_header() because\n\t  such a function does not actually exist.\n\n\t* README.EXT.jp: Update the description of dir_config().\n\nFri May 11 02:42:05 2001  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* README, README.jp: Fix CVS access and mailing lists info.\n\nFri May 11 02:00:44 2001  Ryo HAYASAKA  <ryoh@jaist.ac.jp>\n\n\t* bignum.c (bigdivrem): access boundary bug.\n\nThu May 10 02:40:47 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): prohibit dumping out singleton classes.\n\n\t* object.c (rb_mod_to_s): distinguish singleton classes.\n\n\t* variable.c (rb_class2name): it's ok to reveal NilClass,\n\t  TrueClass, FalseClass.\n\nWed May  9 14:38:33 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (rb_yield_0): preserve and restore ruby_cref as well.\n\nTue May  8 18:28:19 2001  Keiju Ishitsuka  <keiju@ishitsuka.com>\n\n\t* lib/irb.rb lib/irb/multi-irb.rb lib/irb/ruby-lex.rb\n\t  lib/irb/version.rb resolve ctrl-c problem\n\nTue May  8 17:12:43 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (is_defined): core dumped during instance_eval for\n\t  special constants.\n\n\t* eval.c (rb_eval): ditto.\n\nTue May  8 08:52:57 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* doc/forwardable.rd, doc/forwardable.rd.jp: Hit `=begin' and\n\t  `=end' in proper places so rd2 can format them without a problem.\n\n\t* doc/irb/irb-tools.rd.jp, doc/irb/irb.rd, doc/irb/irb.rd.jp:\n\t  ditto.\n\nTue May  8 08:38:53 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* doc/forwardable.rd, doc/forwardable.rd.jp, lib/forwardable.rb:\n\t  Import forwardable 1.1.\n\nTue May  8 08:34:33 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* doc/irb/irb-tools.rd.jp, doc/irb/irb.rd.jp: Convert from JIS to\n\t  EUC.\n\nTue May  8 03:46:39 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* sample/rbc.rb: Obsoleted by IRB.\n\nMon May  7 15:58:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): \"||=\" should not warn for uninitialized instance\n\t  variables.\n\n\t* eval.c (rb_eval): ditto.\n\n\t* eval.c (eval): preserve and restore ruby_cref as well.\n\nMon May  7 15:45:48 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/ftools.rb (syscopy): chmod destination file only if\n\t  it does not exist.\n\nMon May  7 14:35:57 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_is_instance_of): takes only class/module as an\n\t  argument.\n\nSun May  6 16:27:29 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* eval.c (is_defined): rb_reg_nth_defined() may return Qnil.\n\nThu May  3 03:15:06 2001  SHIROYAMA Takayuki <psi@fortune.nest.or.jp>\n\n\t* configure.in: get --enable-shared to work on MacOS X.\n\n\t* Makefile.in: make $(LIBRUBY_SO) depend on miniruby properly.\n\t  Now `make -jN' should work without a problem.\n\nThu May  3 02:07:45 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* win32/config.h.in: add SIZEOF___INT64 definition.\n\nWed May  2 20:39:35 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dir.c (rb_glob, rb_globi): remove unnecessary FNM_PATHNAME.\n\nWed May  2 11:46:13 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (block_pass): should not downgrade safe level.\n\nWed May  2 03:07:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/dbm/extconf.rb: allow specifying dbm-type explicitly.\n\n\t* ext/dbm/extconf.rb: avoid gdbm if possible, because it leaks\n\t  memory, whereas gdbm.so doesn't.  potential incompatibility.\n\nWed May  2 02:02:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_insert): new method.\n\nTue May  1 17:55:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): lex_state after RESCUE_MOD should be EXPR_BEG.\n\nTue May  1 16:23:03 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_insert): new method.\n\n\t* array.c (rb_ary_update): new utility function.\n\nTue May  1 03:24:05 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* lib/irb/completion.rb, lib/irb/frame.rb, lib/irb/xmp.rb,\n\t  doc/irb/irb-tools.rd.jp: Merge from irb-tools 0.7.1.\n\nTue May  1 03:07:17 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* sample/irb.rb, lib/irb.rb, lib/irb/*, doc/irb/*: Merge from irb\n\t  0.7.3.\n\n\t* instruby.rb: Install help-message's too.\n\n\t* lib/irb/main.rb: This file is not needed anymore.\n\nFri Apr 27 09:27:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (set_outfile): should check if closed before assignment.\n\nThu Apr 26 22:36:11 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in:  don't use tzname on Cygwin 1.3.1+.\n\n\t* configure.in: add -mieee/-ieee to CFLAGS on OSF1/Alpha\n\t  to disable \"DIVISION BY ZERO\" exception.\n\nThu Apr 26 22:30:43 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should preserve value of ruby_errinfo.\n\nThu Apr 26 10:36:09 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): infinite sleep should not cause\n\t  dead lock.\n\nWed Apr 25 16:40:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_flatten_bang): proper recursive detection.\n\nWed Apr 25 15:36:15 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (yield_under): need not to prohibit at safe level 4.\n\nWed Apr 25 15:22:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): p/P packs nil into NULL.\n\n\t* pack.c (pack_unpack): p/P unpacks NULL into nil.\n\nTue Apr 24 15:35:32 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): size check for P template.\n\n\t* ruby.c (set_arg0): wrong predicate when new $0 value is bigger\n\t  than original space.\n\nTue Apr 24 15:18:49 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: (dir_config) do not add the\n\t  specified include directory if already included in $CPPFLAGS.\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: (dir_config) return a more useful\n\t  value, [include_dir, lib_dir].\n\nMon Apr 23 14:43:59 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (id2ref): should use NUM2ULONG()\n\n\t* object.c (rb_mod_const_get): check whether name is a class\n\t  variable name.\n\n\t* object.c (rb_mod_const_set): ditto.\n\n\t* object.c (rb_mod_const_defined): ditto.\n\nSat Apr 21 22:33:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_float): precision changed to \"%.16g\"\n\nSat Apr 21 22:07:58 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* eval.c (rb_call0): wrong retry behavior.\n\nFri Apr 20 19:12:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (fix_aref): a bug on long>int architecture.\n\nFri Apr 20 14:57:15 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (rb_eval_string_wrap): should restore ruby_wrapper.\n\nSun Apr 22 17:44:37 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: add -mieee to CFLAGS on Linux/Alpha\n\t  to disable \"DIVISION BY ZERO\" exception.\n\n\t* configure.in: remove -ansi on OSF/1.\n\nWed Apr 18 04:37:51 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: CGI::Cookie: no use PATH_INFO.\n\nWed Apr 18 00:24:40 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): char class at either edge of range\n\t  should be invalid.\n\nTue Apr 17 17:33:55 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (handle_rescue): use === to compare exception match.\n\n\t* error.c (syserr_eqq): comparison between SytemCallErrors should\n\t  based on their error numbers.\n\nTue Apr 17 16:54:39 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (safe_getter): should use INT2NUM().\n\nTue Apr 17 15:12:56 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big2long): 2**31 cannot fit in 31 bit long.\n\nSat Apr 14 22:46:43 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* regex.c (calculate_must_string): wrong length calculation.\n\nSat Apr 14 13:37:32 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* win32/config.status.in: no longer use missing/alloca.c.\n\n\t* win32/Makefile.sub: ditto.\n\nFri Apr 13 12:40:48 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (rb_thread_start_0): fixed memory leak.\n\nFri Apr 13 16:41:18 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (none): should clear cmdarg_stack too.\n\nFri Apr 13 06:19:29 2001  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* io.c (rb_fopen): use setvbuf() to avoid recursive malloc() on\n\t  some platforms.\n\nWed Apr 11 23:36:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_stat_dev): device functions should honor stat field\n\t  types (except long long such as dev_t).\n\nWed Apr 11 18:07:53 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (rb_mod_nesting): should not push nil for nesting array.\n\n\t* eval.c (rb_mod_s_constants): should not search array by\n\t  rb_mod_const_at() for nil (happens for singleton class).\n\nWed Apr 11 13:29:26 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_singleton_class_attached): should modify iv_tbl by\n\t  itself, no longer use rb_iv_set() to avoid freeze check error.\n\n\t* variable.c (rb_const_get): error message \"uninitialized constant\n\t  Foo at Bar::Baz\" instead of \"uninitialized constantBar::Baz::Foo\".\n\nTue Apr 10 17:52:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_included): new hook called from rb_mod_include().\n\nTue Apr 10 02:24:40 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* io.c (opt_i_set): should strdup() inplace_edit string.\n\nMon Apr  9 23:29:54 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (exec_under): need to push cref too.\n\nMon Apr  9 15:20:21 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_missing): raise NameError for \"undefined local\n\t  variable or method\".\n\n\t* error.c (Init_Exception): new exception NoMethodError.\n\t  NameError moved under ScriptError again.\n\n\t* eval.c (rb_f_missing): use NoMethodError instead of NameError.\n\nMon Apr  9 12:05:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (Init_File): should redefine \"new\" class method.\n\nMon Apr  9 11:56:52 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: fix typo.\n\nFri Apr  6 01:46:35 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (PUSH_CREF): sharing cref node was problematic.  maintain\n\t  runtime cref list instead.\n\n\t* eval.c (rb_eval): copy defn node before registering.\n\n\t* eval.c (rb_load): clear ruby_cref before loading.\n\nThu Apr  5 22:40:12 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_const_get): no recursion to show full class path\n\t  for modules.\n\n\t* eval.c (rb_set_safe_level): should set safe level in curr_thread\n\t  as well.\n\n\t* eval.c (safe_setter): ditto.\n\nThu Apr  5 13:46:06 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* object.c (rb_obj_is_instance_of): nil belongs to false, not true.\n\nThu Apr  5 02:19:03 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (make_time_t): proper (I hope) daylight saving time\n\t  handling for both US and Europe.  I HATE DST!\n\n\t* eval.c (rb_thread_wait_for): non blocked signal interrupt should\n\t  stop the interval.\n\nWed Apr  4 03:47:03 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_eq): class check added.\n\n\t* eval.c (proc_eq): typo fixed (\"return\" was omitted).\n\n\t* error.c (Init_Exception): move NameError under StandardError.\n\n\t* class.c (rb_mod_clone): should copy method bodies too.\n\n\t* bignum.c (bigdivrem): should trim trailing zero bdigits of\n\t  remainder, even if dd == 0.\n\n\t* file.c (check3rdbyte): safe string check moved here.\n\nTue Apr  3 09:56:20 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in (create_makefile): create def file only if\n\t  it does not yet exist.\n\n\t* lib/mkmf.rb: ditto.\n\nTue Apr  3 00:05:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (make_time_t): remove HAVE_TM_ZONE code since it\n\t  sometimes reports wrong time.\n\n\t* time.c (make_time_t): remove unnecessary range check for\n\t  platforms where negative time_t is available.\n\nMon Apr  2 16:52:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_waitall): should push Process::Status instead of\n\t  Fixnum status.\n\n\t* process.c (waitall_each): should add all entries in pid_tbl.\n\t  these changes are inspired by Koji Arai.  Thanks.\n\n\t* process.c (proc_wait): should not iterate if pid_tbl is 0.\n\n\t* process.c (proc_waitall): ditto.\n\nMon Apr  2 14:25:49 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/monitor.rb (wait): ensure reentrance.\n\n\t* lib/monitor.rb (wait): fix timeout support.\n\nMon Apr  2 12:40:45 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (media_subtype): return subtype.\n\nMon Apr  2 12:01:15 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb (flag_list): capitalize flags.\n\nMon Apr  2 01:32:38 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* Makefile.in: Introduce MAINLIBS.\n\n\t* configure.in: Link libc_r against the ruby executable on\n\t  FreeBSD, which is the first attempt to work around a certain\n\t  problem regarding pthread on FreeBSD.  It should make ruby/libruby\n\t  happy when it loads an extension to a library compiled and linked\n\t  with -pthread.  Note, however, that libruby is _not_ linked with\n\t  libc_r so as not to mess up pthread unfriendly stuff including\n\t  apache+mod_ruby and vim6+ruby_interp.\n\nMon Apr  2 01:16:24 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c: use ruby's opendir on mingw32.\n\n\t* win32/dir.h, dir.c, Makefile: ditto.\n\nSun Apr  1 23:26:14 2001  TOYOFUKU Chikanobu  <toyofuku@juice.or.jp>\n\n\t* numeric.c (flodivmod): a bug in no fmod case.\n\nSun Apr  1 18:36:14 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* process.c (pst_wifsignaled): should apply WIFSIGNALED for status\n\t  (int), not st (VALUE).\n\nSat Mar 31 04:47:55 2001  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: add document and example code.\n\nSat Mar 31 03:24:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (Init_IO): value of $/ and $\\ are no longer restricted to\n\t  strings.  type checks are done on demand.\n\n\t* class.c (rb_include_module): module inclusion should be check\n\t  taints.\n\n\t* ruby.h (STR2CSTR): replace to StringType() and StringTypePtr().\n\n\t* ruby.h (rb_str2cstr): ditto.\n\nFri Mar 30 23:37:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): should not copy toplevel local variables.  It\n\t  cause variable/method ambiguity.  Thanks to L. Peter Deutsch.\n\nFri Mar 30 22:56:56 2001  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: rename ContinueRequest to ContinuationRequest.\n\nFri Mar 30 12:51:19 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_include_module): freeze check at first.\n\nThu Mar 29 17:05:09 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_attr): sprintf() and rb_intern() moved into\n\t  conditional body.\n\nWed Mar 28 23:43:00 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: add C++ rules in addition to C\n\t  rules for the mswin32 platforms.\n\nWed Mar 28 19:29:21 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: move C++ rules to the right place.\n\nWed Mar 28 17:39:04 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_str2cstr): warn if string contains \\0 and length\n\t  value is ignored.\n\nWed Mar 28 15:00:31 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* class.c (rb_singleton_class_clone): should copy class constant\n\t  table as well.\n\nWed Mar 28 14:23:23 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* class.c (rb_include_module): sometimes cache was mistakenly left\n\t  uncleared - based on the patch by K.Kosako.\n\n\t* ruby.h: all Check_SafeStr()'s are replaced by SafeStr() to\n\t  ensure 'to_str' be always effective.\n\nWed Mar 28 09:52:33 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/Makefile.sub: disable global optimization.\n\nTue Mar 27 15:00:54 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (rb_mod_define_method): should have clear method cache.\n\n\t* eval.c (rb_mod_define_method): should have raised exception for\n\t  type error.\n\nTue Mar 27 14:48:17 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h: changed \"extern INLINE\" to \"static inline\".\n\nMon Mar 26 23:19:33 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* time.c (rb_strftime): check whether strftime returns empty string.\n\nMon Mar 26 21:16:56 2001  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: supports response handlers and multiple commands.\n\nMon Mar 26 17:21:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c: remove TMP_PROTECT_END to prevent C_ALLOCA crash.\n\nMon Mar 26 14:04:41 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/Win32API/Win32API.c: remove Init_win32api().\n\nSun Mar 25 16:52:48 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* file.c (rb_file_flock): do not trap EINTR.\n\n\t* missing/flock.c (flock): returns the value from lockf(2)\n\t  directly.\n\nSat Mar 24 23:44:50 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ev_const_defined): should ignore toplevel cbase (Object).\n\n\t* eval.c (ev_const_get): ditto.\n\nFri Mar 23 17:37:52 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ext/md5/md5.h: replace by independent md5 implementation\n\t  contributed by L. Peter Deutsch (thanks).\n\n\t* ext/md5/md5init.c: adopted to Deutsch's md5 implementation.\n\nFri Mar 23 17:26:19 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_unpack): string from P/p should be tainted.\n\nFri Mar 23 12:18:44 2001  SHIROYAMA Takayuki  <psi@fortune.nest.or.jp>\n\n\t* ext/curses/curses.c: curses on Mac OS X public beta does not\n\t  have _maxx etc.\n\nFri Mar 23 10:50:31 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_object): should truncate trailing zero short for\n\t  bignums.\n\nFri Mar 23 09:49:02 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (sym_intern): new method.\n\nThu Mar 22 22:15:45 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/Win32API/extconf.rb: add -fno-omit-frame-pointer.\n\nThu Mar 22 18:17:36 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_nesting): should not include Object at the\n\t  toplevel.\n\nThu Mar 22 17:43:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h: better inline function support.\n\n\t* configure.in (NO_C_INLINE): check if inline is available for the\n\t  C compiler.\n\nMon Mar 19 11:03:10 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* marshal.c (r_object): len calculation patch was wrong for\n\t  machines SIZEOF_BDIGITS == SIZEOF_SHORT.\n\n\t* gc.c: alloca prototype reorganized for C_ALLOCA machine.\n\nWed Mar 21 23:07:45 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (win32_stat): WinNT/2k \"//host/share\" support.\n\nWed Mar 21 08:05:35 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* win32/dir.h: replace missing/dir.h .\n\n\t* win32/win32.h: ditto.\n\n\t* win32/win32.c: ditto.\n\nWed Mar 21 01:26:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (id2ref): sometimes confused symbol and reference.\n\nTue Mar 20 23:09:33 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (win32_stat): UNC support.\n\n\t* dir.c (extract_path): fix \"./*\" problem.\n\nTue Mar 20 15:10:00 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (glob_helper): breaks loop after calling recursive\n\t  glob_helper; all wild cards should be consumed; no need for\n\t  further match.\n\n\t* dir.c (dir_s_glob): gives warning if no match found.\n\nTue Mar 20 14:13:45 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* object.c (sym_inspect): did allocate extra byte space.\n\nMon Mar 19 19:14:47 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* marshal.c (shortlen): shortlen should return number of bytes\n\t  written.\n\nMon Mar 19 16:52:23 2001  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* eval.c (ev_const_defined): need not to check if cbase->nd_class\n\t  is rb_cObject.\n\n\t* eval.c (ev_const_get): ditto.\n\nMon Mar 19 17:11:20 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_zone): return \"UTC\" for UTC time objects.\n\nMon Mar 19 16:27:32 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (THREAD_ALLOC): flags should be initialized.\n\n\t* signal.c (rb_f_kill): should use FIX2INT, not FIX2UINT.\n\nMon Mar 19 10:55:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (glob_helper): replace lstat() by stat() to follow symlink\n\t  in the case like 'symlink/*'.\n\n\t* dir.c (glob_helper): gave warning too much.\n\nSun Mar 18 08:58:18 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: // === '' --> //.match('')\n\n\t* lib/cgi.rb: cgi#header(): improvement for mod_ruby.\n\n\t* lib/cgi.rb: cgi#rfc1123date(): improvement.\n\t  thanks to TADA Tadashi <sho@spc.gr.jp>.\n\n\t* lib/cgi.rb: cgi#rfc1123date(): document bug fix.\n\t  thanks to Kazuhiro NISHIYAMA <zn@mbf.nifty.com>.\n\n\t* lib/cgi.rb: cgi#header(): bug fix.\n\t  thanks to IWATSUKI Hiroyuki <don@na.rim.or.jp>.\n\nSat Mar 17 11:11:24 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (glob_helper): * should follow symlink, whereas ** should\n\t  not follow.\n\nThu Mar 15 01:28:02 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_s_chdir): block form of Dir.chdir. (RCR#U016).\n\nFri Mar 16 17:14:17 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* configure.in: Set SOLIBS properly for all ELF and\n\t  FreeBSD/NetBSD/OpenBSD a.out platforms so that the shlib\n\t  dependencies are recorded in the libruby shlib.\n\nWed Mar 14 16:41:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_schedule): raise FATAL just once to\n\t  THREAD_TO_KILL.\n\nWed Mar 14 10:41:34 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): 0 (= Qfalse) is a valid value, so that\n\t  default self should be checked by klass == 0.\n\n\t* bignum.c (rb_cstr2inum): should disallow '++1', '+-1', etc.\n\nTue Mar 13 17:51:09 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ev_const_defined): add new parameter self for special\n\t  const fallback.\n\n\t* eval.c (ev_const_get): ditto.\n\nTue Mar 13 16:39:45 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dir.c (rb_glob_helper): fix drive letter handling on DOSISH.\n\nTue Mar 13 14:54:39 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: add HTTPRequest#basic_auth.\n\n\t* lib/net/smtp.rb: raise if only account or password is given.\n\n\t* lib/net/protocol.rb: WriteAdapter#<< returns self.\n\nTue Mar 13 14:41:16 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_seek_m): wrong calling sequence of rb_io_seek().\n\nTue Mar 13 09:14:19 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (cond0): no special treatment of string literal in\n\t  condition.\n\nMon Mar 12 18:59:38 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): save/restore $libs and $LIBPATH.\n\nSun Mar 11 18:13:34 2001  Masahiro Tanaka  <masa@stars.gsfc.nasa.gov>\n\n\t* math.c: add acos, asin, atan, conh, sinh, tanh and hypot to Math.\n\n\t* configure.in: check hypot availability.\n\n\t* missing/hypot.c: public domain rewrite of hypot.\n\nSun Mar 11 13:21:04 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* parse.y (warn_unless_e_option): warning condition was wrong.\n\n\t* parse.y (warning_unless_e_option): ditto.\n\nSun Mar 11 00:55:31 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (install_rb): fix handling of destination path.\n\nSat Mar 10 22:56:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_all): new method 'all?', which returns true if\n\t  block returns true for all elements.\n\n\t* enum.c (enum_any): new method 'any?', which returns true if\n\t  block returns true for any of elements.\n\nSat Mar 10 02:34:18 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* math.c (math_log, math_log10): use nan() instead of 0.0/0.0 on Cygwin.\n\nFri Mar  9 09:56:19 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (marshal_load): do not give warning unless explicitly\n\t  set to verbose.\n\nFri Mar  9 02:07:53 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_exit): give string value \"exit\" to SystemExit.\n\n\t* ruby.c (proc_options): -v should not print version if\n\t  proc_options called via moreswitches().\n\nThu Mar  8 17:45:19 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb: one write(2) per one line.\n\nWed Mar  7 14:26:11 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* math.c (math_log, math_log10): should return NaN if x < 0.0\n\t  on Cygwin.\n\nThu Mar  7 10:31:26 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (stmt): while/until modifier must work for empty body.\n\nTue Mar  6 22:53:58 2001  Kazuhiro Yoshida   <moriq.kazuhiro@nifty.ne.jp>\n\n\t* ruby.c (ruby_set_argv): clear ARGV contents before adding args.\n\nTue Mar  6 10:50:29 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (primary): rescue and ensure clauses should be allowed\n\t  to appear in singleton method body.\n\nMon Mar  5 17:25:13 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_eq): compare Procs using blocktag equality.\n\n\t* eval.c (proc_to_s): stringify according to block tag address.\n\nMon Mar  5 17:19:56 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (gettimeofday): use GetLocalTime() instead of ftime()\n\t  for high-resolution timing.\n\nSun Mar  4 17:01:09 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* string.c (trnext): support backslash escape in String#tr.\n\nSat Mar  3 16:15:16 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): push cbase if ruby_cbase != ruby_class, for\n\t  example in the case NODE_DEFN/NODE_DEFS are called within\n\t  module_eval.\n\nWed Feb 28 11:02:41 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_delete_bang): delete! should take at least 1\n\t  argument.\n\n\t* ruby.c (load_file): add rb_gc() after loading to avoid\n\t  extraordinary memory growth.\n\nWed Feb 28 05:01:40 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* dir.c (rb_glob_helper): \"./foo\" should match \"foo\", not \"./foo\".\n\nTue Feb 27 16:38:15 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ev_const_get): retrieve Object's constant if no current\n\t  class is available (e.g. defining singleton class for Fixnums).\n\n\t* eval.c (ev_const_defined): check Object's constant if no current\n\t  class is available (e.g. defining singleton class for Fixnums).\n\n\t* time.c (time_timeval): negative time interval should not be\n\t  allowed.\n\n\t* eval.c (proc_call): ignore block to `call' always, despite of\n\t  being orphan or not.\n\nWed Feb 27 10:16:32 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_yield_0): should check based on rb_block_given_p()\n\t  and rb_f_block_given_p().\n\nTue Feb 27 04:13:45 2001 Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* configure.in (frame-address): --enable-frame-address to allow\n\t  __builtin_frame_address() to be used.\n\n\t* eval.c (stack_length): use __builtin_frame_address() based on\n\t  the macro USE_BUILTIN_FRAME_ADDRESS.\n\n\t* gc.c (rb_gc): ditto.\n\n\t* gc.c (Init_stack): ditto.\n\nMon Feb 26 16:20:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (proc_options): call ruby_show_version() just once.\n\n\t* dir.c (dir_s_open): returns the value from a block (if given).\n\nMon Feb 26 14:29:04 2001  Akinori MUSHA  <knu@iDaemons.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: add C++ rules in addition to C\n\t  rules.\n\nMon Feb 26 00:04:52 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_call): should not modify ruby_block->frame.iter\n\t  based on ruby_frame->iter altered by PUSH_ITER().\n\nMon Feb 26 05:27:52 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/net/telnet.rb: #telnetmode(), #binmode(): bug fix.\n\t  thanks to nobu.nakada@nifty.ne.jp.\n\nMon Feb 26 04:55:50 2001  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: CGI#form(): bug fix.\n\t  thanks to MoonWolf <moonwolf@moonwolf.com>.\n\n\t* lib/cgi.rb: CGI#rfc1123_date(): improvement.\n\t  thanks to Tomoyasu Akita <genzo-@dm4lab.to>.\n\n\t* lib/cgi.rb: CGI#header(): improvement for mod_ruby.\n\t  thanks to Shugo Maeda <shugo@ruby-lang.org>.\n\nSun Feb 25 02:45:30 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* file.c (rb_file_s_rename): avoid Cygwin's bug.\n\nSat Feb 24 23:32:55 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_fd_close): should save current context before\n\t  raising exception.\n\nSat Feb 24 22:14:00 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c (myrename): fix error handling.\n\nSat Feb 24 13:58:48 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: always close connection on request without\n\t  body.\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: change copyright.\n\nSat Feb 24 03:15:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (set_stdin): preserve original stdin.\n\n\t* io.c (set_outfile): preserve original stdout/stderr.\n\nFri Feb 23 08:28:58 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb: clear read buffer after reopen.\n\n\t* lib/net/protocol.rb: refactoring.\n\n\t* lib/net/http.rb: split module HTTPHeader from HTTPResponse.\n\nTue Feb 20 23:45:35 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* process.c: add W* macro if not available.\n\nTue Feb 20 16:37:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in: add check for negative time_t for gmtime(3).\n\n\t* time.c (time_new_internal): no positive check if gmtime(3) can\n\t  handle negative time_t.\n\n\t* time.c (time_timeval): ditto.\n\n\t* bignum.c (rb_big2long): should not raise RangeError for Bignum\n\t  LONG_MIN value.\n\nMon Feb 19 17:46:37 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_substr): \"a\"[1,2] should return \"\"; need\n\t  rubicon upgrade.\n\nMon Feb 19 12:10:36 2001  Triet H. Lai  <thlai@mail.usyd.edu.au>\n\n\t* error.c (rb_sys_warning): new function to give warning with\n\t  strerror() message.\n\n\t* dir.c (rb_glob_helper): better error handling, along with\n\t  performance tune.\n\nMon Feb 19 01:55:43 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (secure_visibility): visibility check for untainted modules.\n\nMon Feb 19 00:29:29 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* signal.c (sigpipe): sighandler which does nothing.\n\n\t* signal.c (trap): set sigpipe function for SIGPIPE.\n\n\t* signal.c (Init_signal): default SIGPIPE handler should be\n\t  sigpipe function.\n\nSun Feb 18 15:42:38 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/curses/extconf.rb: add dir_config.\n\n\t* missing/flock.c: use fcntl(2) instead of lockf(2).\n\nSun Feb 18 05:46:03 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: Response#range_length was not debugged.\n\nSun Feb 18 04:02:03 2001  Yasushi Shoji  <yashi@yashi.com>\n\n\t* array.c (rb_ary_subseq): wrong boundary check.\n\nSun Feb 18 00:09:50 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* win32/win32.c: make file I/O faster on mswin32/mingw32.\n\n\t* win32/win32.h: ditto.\n\n\t* rubysig.h: ditto.\n\nSat Feb 17 23:32:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (cond0): integer literal in condition should not be\n\t  compared to lineno ($.).\n\nFri Feb 16 01:44:56 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (set_outfile): f should be the FILE* from the assigning value.\n\n\t* ext/socket/socket.c (tcp_s_open): should not give default value\n\t  to local_host.\n\n\t* time.c (time_s_times): move to Process::times.\n\n\t* file.c (rb_file_s_lchmod): new method File::lchmod.\n\n\t* file.c (rb_file_s_lchown): new method File::lchown.\n\nThu Feb 15 11:33:49 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/cgi/session.rb (close): fixed reversed condition.\n\nThu Feb 15 08:34:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_waitall): new method based on a patch from Brian\n\t  Fundakowski Feldman <green@green.dyndns.org>.\n\n\t* process.c (last_status_set): objectify $? value (Process::Status).\n\nWed Feb 14 17:28:24 2001  Shugo Maeda <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: supports unknown resp_text_code.\n\nWed Feb 14 00:44:17 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* dir.c (dir_s_glob): support backslash escape of metacharacters\n\t  and delimiters.\n\n\t* dir.c (remove_backslases): remove backslashes from path before\n\t  calling stat(2).\n\n\t* dir.c (dir_s_glob): call rb_yield directly (via push_pattern) if\n\t  block is given to the method.\n\n\t* dir.c (push_pattern): do not call rb_ary_push; yield directly.\n\n\t* eval.c (blk_copy_prev): reduced ALLOC_N too much.\n\n\t* eval.c (frame_dup): ditto.\n\nTue Feb 13 23:05:38 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dir.c (lstat): should use rb_sys_stat if lstat(2) is not\n\t  available.\n\nTue Feb 13 08:43:10 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_ctl): do not call ioctl/fcntl for f2, if f and f2\n\t  have same fileno.\n\nTue Feb 13 01:13:43 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_load): raise LocalJumpError if unexpected local jumps\n\t  appear during load.\n\n\t* ext/socket/socket.c (bsock_close_read): don't call rb_thread_fd_close();\n\t  it's supposed to be called by io_io_close().\n\n\t* ext/socket/socket.c (bsock_close_read): do not modify f and f2.\n\n\t* ext/socket/socket.c (bsock_close_write): ditto.\n\n\t* ext/socket/socket.c (sock_new): avoid dup(2) on sockets.\n\n\t* parse.y (primary): preserve and clear in_single and in_def using\n\t  stack to prevent nested method errors in singleton class bodies.\n\nSun Feb 11 16:00:30 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (stack_length): use __builtin_frame_address() only if\n\t  GCC and i386 CPU.\n\n\t* gc.c (rb_gc, Init_stack): ditto.\n\n\t* configure.in: add ac_cv_func_getpgrp_void=yes on DJGPP.\n\nSat Feb 10 23:43:49 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* hash.c (rb_any_hash): dumped core on machines sizeof(int) != sizeof(long).\n\nSat Feb 10 23:07:15 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_s_for_fd): IO::for_fd(fd) - new method.\n\n\t* regex.c (PREV_IS_A_LETTER): should not treat c>0x7f as a word\n\t  character if -Kn.\n\nSat Feb 10 00:00:30 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* win32/win32.c (win32_stat): replace stat to enable when pathname\n\t  ends with '/' or '\\' for mswin32 on Win9X / Win2k.\n\n\t* win32/win32.h: ditto.\n\n\t* ruby.h: ditto.\n\n\t* dir.c (rb_glob_helper): ditto.\n\n\t* file.c (rb_stat, rb_file_s_stat, eaccess, check3rdbyte): ditto.\n\nFri Feb  9 22:54:57 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.c (ruby_init_loadpath): convert '\\\\' to '/'\n\t  before finding executable file path.\n\nFri Feb  9 17:41:53 2001  Triet H. Lai  <thlai@mail.usyd.edu.au>\n\n\t* dir.c (rb_glob_helper): do not follow symbolic links.\n\nThu Feb  8 21:27:24 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/mkmf.rb (install_rb): fix handling of relative path.\n\n\t* lib/mkmf.rb (create_makefile): add srcdir.\n\nThu Feb  8 02:22:09 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: join HTTPReadResponse into HTTPResponse again.\n\n\t* lib/net/http.rb: move http_version() from HTTPRequest to\n\t  HTTPResponse.\n\n\t* lib/net/protocol.rb: refactoring.\n\nWed Feb  7 16:27:27 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: split HTTPResponse into HTTPReadResponse\n\t  module.\n\n\t* lib/net/protocol.rb: add Net::net_private.\n\n\t* lib/net/protocol.rb: Socket#reopen takes arg, open_timeout.\n\nWed Feb  7 16:05:22 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (parse_quotedwords): %w should allow parenthesis escape.\n\nWed Feb  7 00:57:42 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (parse_qstring): %q should allow terminator escape.\n\n\t* re.c (rb_reg_options): new method to give an option values.\n\n\t* parse.y (cond0): disable special treating of integer literal in\n\t  conditional unless option -e is supplied.  changes current\n\t  behavior.  experimental.\n\n\t* parse.y (cond0): give warning for string/integer literals and\n\t  dot operators in conditionals unless option -e is supplied.\n\n\t* re.c (rb_reg_equal): all option flags should be same to be equal.\n\nTue Feb  6 21:30:44 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: call on_connect() on re-opening socket.\n\n\t* lib/net/pop.rb: also POP3 can use APOP auth.\n\nTue Feb  6 20:19:10 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: add HTTP#request.\n\n\t* lib/net/http.rb: take HTTP 1.0 server into account (incomplete).\n\n\t* lib/net/protocol.rb: timeout for open/read.\n\n\t* lib/net/protocol.rb: add Protocol#on_connect,on_disconnect.\n\nMon Feb  5 23:15:46 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (Init_Exception): make Interrupt a subclass of\n\t  SignalException.\n\nMon Feb 5 00:39:06 2001  KANEKO Naoshi  <wbs01621@mail.wbs.ne.jp>\n\n\t* dir.c: use ISXXX() instead of isxxx().\n\n\t* dln.c (aix_loaderror): ditto.\n\n\t* file.c (rb_file_s_expand_path): ditto.\n\n\t* string.c (rb_str_upcase_bang): ditto.\n\n\t* win32/win32.c (do_spawn): ditto.\n\n\t* win32/win32.c (NtMakeCmdVector): ditto.\n\n\t* win32/win32.c (opendir): ditto.\n\nSat Feb  3 14:44:53 2001  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* configure.in (AC_C_INLINE): check inline attribute.\n\n\t* gc.c (is_pointer_to_heap): use inline rather than __inline__.\n\n\t* pack.c (hex2num): ditto.\n\n\t* ruby.h (rb_class_of, rb_type, rb_special_const_p): ditto.\n\n\t* util.c (rb_class_of, rb_type, rb_special_const_p): defined in\n\t  ruby.h.\n\nFri Feb  2 16:14:51 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_sort_bang): returns self, even if its length is\n\t  less than 2.\n\n\t* eval.c (POP_VARS): propagate DVAR_DONT_RECYCLE, if\n\t  SCOPE_DONT_RECYCLE of ruby_scope is set.\n\nWed Jan 31 22:27:29 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: gcc-2.95.2-7(Cygwin) support.\n\t  add -mwin32 if available.\n\n\t* cygwin/GNUmakefile: ditto.\n\nTue Jan 30 17:56:48 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_fetch): new method.\n\nMon Jan 29 17:36:19 2001  TOYOFUKU Chikanobu  <toyofuku@juice.or.jp>\n\n\t* eval.c (rb_eval): nd_iter evaluation should be wrapped by\n\t  BEGIN_CALLARGS and END_CALLARGS.\n\nMon Jan 29 14:25:39 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): return from block jumps directory to\n\t  block invoker.\n\nMon Jan 29 01:40:27 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (str_independent): should not clear str->orig here.\n\t  it's too early.\n\nFri Jan 26 01:42:40 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y: clarify do ambiguity, bit more complex but natural\n\t  from my point of view.\n\nWed Jan 24 14:58:08 2001  Akinori MUSHA  <knu@ruby-lang.org>\n\n\t* lib/cgi.rb: fix the problem that when running under mod_ruby\n\t  header() outputs only one Set-Cookie line.\n\nWed Jan 24 01:45:49 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (POP_BLOCK_TAG): call rb_gc_force_recycle() if block has\n\t  not been objectified.\n\n\t* eval.c (rb_callcc): should nail down block->tag history to avoid\n\t  rb_gc_force_recycle().\n\nTue Jan 23 18:51:57 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): should finalize objects in\n\t  deferred_final_list too.\n\nTue Jan 23 16:10:12 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (os_live_obj): do not list terminated object.\n\n\t* gc.c (os_obj_of): ditto.\n\n\t* gc.c (rb_gc_mark): support new T_BLKTAG tag.\n\n\t* gc.c (obj_free): ditto.\n\n\t* eval.c (new_blktag): creation of new block tag, which holds\n\t  destination of global jump and orphan status.\n\n\t* eval.c (block_pass): break from orphan Proc object will raise a\n\t  LocalJumpError exception.\n\nMon Jan 22 16:33:16 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* mkconfig.rb: autoconf 2.49 support.\n\nMon Jan 22 00:32:44 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (block_pass): behavior consistency with proc_call(). do\n\t  not propagate `break'.\n\nSat Jan 20 03:54:00 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): fixed serious syntax misbehavior.  do's\n\t  preceding was too high.  a block in `foo bar do .. end' should\n\t  be passed to `foo', not `bar'.\n\n\t* parse.y (block_call): syntax restructure.\n\nThu Jan 18 04:28:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_s_read): new method to call IO#read from\n\t  pathname.  In addition, it accepts third optional argument to\n\t  specify starting point.\n\nWed Jan 17 13:28:26 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: remove DEFS definition.\n\n\t* mkconfig.rb: ditto.\n\n\t* win32/config.status.in: ditto.\n\nTue Jan 16 17:00:50 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb: ignore EOFError for read.\n\n\t* lib/net/http.rb: user specified header was not used.\n\nMon Jan 15 16:00:07 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_unpack): should check associated pointer packed by\n\t  pack(\"P\").  Thus pointers can be retrieved only from pointer\n\t  packed strings.  restriction added.\n\nSun Jan 14 21:49:28 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* sprintf.c (rb_f_sprintf): simple typo.  binary base should be 2,\n\t  not '2'.\n\n\t* re.c (rb_reg_s_last_match): should explicitly return nth match.\n\nSun Jan 14 18:21:30 2001  Usaku Nakamura  <usa@osb.att.ne.jp>\n\n\t* win32/config.status.in: add some field.\n\n\t* win32/win32.c (isInternalCmd): ignore case for shell's internal\n\t  command.\n\n\t* win32/win32.c (do_spawn): recognize quoted command line.\n\nSun Jan 14 04:10:27 2001  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb (adding): too few \"yield\" in case of arg is\n\t  not String/File.\n\n\t* lib/net/http.rb: add http request object.\n\nSat Jan 13 19:39:30 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* re.c (rb_reg_desc): separate RE_OPTION_MULTILINE\n\n\t* re.c (rb_reg_options): add RE_OPTION_{POSIXLINE,RE_OPTION_MULTILINE,\n\t  RE_OPTION_EXTENDED}\n\nThu Jan 11 10:45:04 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.h, win32/config.h.in: move NORETURN from win32.h\n\t  to config.h.in.\n\n\t* win32/config.h.in (inline): renamed from INLINE.\n\n\t* djgpp/config.hin (INLINE): removed.\n\nThu Jan 11 06:45:55 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_dup): should propagate FL_SINGLETON.\n\n\t* object.c (inspect_obj): handles the case of no instance variable.\n\nWed Jan 10 16:15:08 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.h: NORETURN macro is changed for VC++ 6.0.\n\n\t* eval.c, intern.h: ditto.\n\n\t* djgpp/config.hin, win32/win32.h: ditto.\n\n\t* configure.in: ditto.\n\nWed Jan 10 13:54:53 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* process.c (proc_setuid): use setresuid() if available.\n\n\t* process.c (proc_setgid): use setresgid() if available.\n\n\t* configure.in: ditto.\n\nWed Jan 10 01:50:45 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* configure.in (AC_C_INLINE): check inline attribute.\n\n\t* string.c (rb_str_reverse_bang): forgot to call rb_str_modify().\n\nTue Jan  9 17:41:40 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_taint): check frozen status before modifying\n\t  taint status.\n\n\t* object.c (rb_obj_untaint): ditto.\n\nTue Jan  9 16:22:14 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* enum.c (enum_inject): new method.\n\nTue Jan  9 02:16:42 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): clear klass member of\n\t  terminating object.\n\n\t* eval.c (rb_call): raise exception for terminated object.\n\nMon Jan  8 21:24:37 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bigdivrem): t2 might be too big for signed long; do\n\t  not use rb_int2big(), but rb_uint2big().\n\nMon Jan  8 21:35:10 2001  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* file.c (path_check_1): should restore modified path.\n\nMon Jan  8 03:09:58 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_load_fail): new func to report LoadError.\n\n\t* ruby.c (load_file): use rb_load_fail.\n\nSat Jan  6 00:17:18 2001  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* pack.c (pack_pack): avoid infinite loop(pack 'm2').\n\nFri Jan  5 01:02:17 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_finalize): should enclosed by PUSH_TAG/POP_TAG.\n\n\t* gc.c (rb_gc_mark): link 2 of NODE_IFUNC should not be explicitly\n\t  marked.  it may contain non object pointer.\n\nTue Jan  2 00:20:06 2001  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* re.c (reg_s_last_match): Regexp::last_match(nth) returns nth\n\t  substring of the match  (alternative for $& and $<digit>).\n\nSun Dec 31 01:39:16 2000  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* eval.c (rb_mod_define_method): wrong comparison for blocks.\n\nSat Dec 30 19:28:50 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (id2ref): should handle Symbol too.\n\n\t* gc.c (id2ref): should print original ptr value\n\nSat Dec 30 03:14:22 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_iterate): NODE_CFUNC does not protect its data\n\t  (nd_tval), so create new node NODE_IFUNC for iteration C\n\t  function.\n\n\t* eval.c (rb_yield_0): use NODE_IFUNC.\n\n\t* gc.c (rb_gc_mark): support NODE_IFUNC.\n\nFri Dec 29 11:41:55 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (mem_error): prohibit recursive mem_error().\n\t  (ruby-bugs-ja:PR#36)\n\nFri Dec 29 11:05:41 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_fd_writable): should not switch context if\n\t  rb_thread_critical is set.\n\n\t* eval.c (rb_thread_wait_fd): ditto.\n\n\t* eval.c (rb_thread_wait_for): ditto.\n\n\t* eval.c (rb_thread_select): ditto.\n\n\t* eval.c (rb_thread_join): join during critical section causes\n\t  deadlock.\n\nFri Dec 29 00:38:46 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* m17n.c: new file - core functions of M17N.\n\nTue Dec 26 18:46:41 2000  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* lib/debug.rb: Avoid thread deadlock in debugging stopped thread.\n\n\t* lib/debug.rb: Uncleared 'finish' state.\n\nTue Dec 26 16:53:55 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): remove dvar node by rb_gc_force_recycle()\n\t  more eagerly.\n\n\t* eval.c (rb_f_binding): recycling should be stopped for outer\n\t  scope too.\n\n\t* eval.c (proc_new): ditto.\n\nTue Dec 26 15:45:35 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_inspect): should treat multibyte characters\n\t  properly.\n\nMon Dec 25 17:49:08 2000  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* string.c (rb_str_replace_m): unexpected string share happens if\n\t  replace is done for associated (STR_NO_ORIG) string.\n\nTue Dec 26 15:01:53 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_f_p): should not call rb_io_flush() if rb_defout is not\n\t  a IO (T_FILE).\n\nMon Dec 25 15:52:39 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.6.2 released.\n\nMon Dec 25 05:11:04 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: version 2.1.2 (some bug fixes).\n\n\t* lib/cgi.rb: Regexp::last_match[1] --> $1\n\n\t* lib/net/telnet.rb: ditto.\n\nMon Dec 25 04:43:02 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: does not send HEAD on closing socket.\n\nMon Dec 25 00:44:48 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_any_cmp): should use rb_str_cmp() if TYPE == T_STRING\n\t  and CLASS_OF == rb_cString.\n\n\t* string.c (rb_str_new4): should copy class of original too.\n\nMon Dec 25 00:04:54 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_thread_schedule): initial value of `max' changed to -1.\n\nMon Dec 25 00:16:14 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_replace_m): copy-on-write replace.\n\n\t* parse.y (yylex): should handle => after identifier as well as ==\n\t  and =~.\n\nSat Dec 23 23:55:57 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_cstr2inum): Integer(\"\") should not return 0.\n\nSat Dec 23 11:55:57 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_and): Array#& should preserve original order.\n\nSat Dec 23 03:44:16 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb: set @closed false in Socket#reopen.\n\n\t* lib/net/pop.rb: add POP3.foreach, delete_all.\n\n\t* lib/net/pop.rb: add POP3#delete_all.\n\n\t* lib/net/http.rb: add HTTP.version_1_1, version_1_2\n\n\t* lib/net/http.rb: refactoring.\n\nFri Dec 22 23:11:12 2000  Ueno Katsuhiro  <unnie@blue.sky.or.jp>\n\n\t* eval.c (rb_feature_p): ext might be null.\n\nFri Dec 22 17:04:12 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* win32/win32.c (myselect): avoid busy loop by adjusting fd_count.\n\nFri Dec 22 15:07:55 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_cstr2inum): prefix like '0x' had removed too much.\n\nThu Dec 21 13:01:46 2000  Tanaka Akira  <akr@m17n.org>\n\n\t* lib/net/ftp.rb (makeport): don't use TCPsocket.getaddress.\n\nWed Dec 20 12:00:15 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_lshift): should cast up to BDIGIT_DBL.\n\n\t* parse.y (yylex): disallow trailing '_' for numeric literals.\n\n\t* bignum.c (rb_cstr2inum): allow `_' within converting string.\n\n\t* eval.c (specific_eval): should take no argument if block is\n\t  supplied.\n\nTue Dec 19 13:44:50 2000  K.Kosako  <kosako@sofnec.co.jp>\n\n\t* io.c (rb_f_p): should flush rb_defout, not stdout.\n\nTue Dec 19 00:57:10 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_minus): usec might overflow. (ruby-bugs-ja:PR#35)\n\n\t* eval.c (rb_obj_extend): Object#extend should take at least one\n\t  argument.\n\n\t* parse.y (mrhs_basic): should check value_expr($3), not $1.\n\nMon Dec 18 23:18:39 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* util.c (mblen, __crt0_glob_function): add for multibyte\n\t  on DJGPP 2.03.\n\nMon Dec 18 18:10:30 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_plus): usec might underflow (ruby-bugs-ja:#PR33).\n\nMon Dec 18 08:11:20 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (rb_hash_set_default): should call rb_hash_modify().\n\nSat Dec 16 02:58:26 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* eval.c (rb_eval): should clear ruby_errinfo on retry.\n\n\t* eval.c (rb_rescue2): ditto.\n\nThu Dec 14 13:06:18 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* class.c (rb_include_module): prohibit frozen class/module.\n\n\t* eval.c (rb_frozen_class_p): make external.\n\n\t* intern.h (rb_frozen_class_p): prototyped.\n\n\t* intern.h (rb_undef): prototyped not but rb_undef_method()\n\t  which is also in ruby.h.\n\nThu Dec 14 09:20:26 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: support -T1 on ruby 1.6.2\n\n\t* lib/cgi.rb: $1 --> Regexp::last_match[1]\n\n\t* lib/net/telnet.rb: ditto.\n\nWed Dec 13 23:27:06 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): handles case statement without expr, which\n\t  looks for any TRUE (non nil, non false) when expression.\n\n\t* parse.y (primary): case expression should not be compstmt, but\n\t  mere expr.\n\n\t* parse.y (primary): case without following expression is now\n\t  separated rule.\n\nWed Dec 13 12:41:27 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ruby.c (proc_options): accept \"--^M\" for DOS line endings.\n\nTue Dec 12 15:45:42 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (newline_node): cancel newline unification.\n\nMon Dec 11 23:01:57 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): supports cases `?' precedes EOF and newline.\n\nMon Dec 11 12:11:25 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (call_end_proc): some frame members were left\n\t  uninitialized.\n\nMon Dec 11 01:14:58 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_fptr_finalize): do not fclose stdin, stdout and\n\t  stderr at exit.\n\nSat Dec  9 17:34:48 2000  Tachino Nobuhiro <tachino@open.nm.fujitsu.co.jp>\n\n\t* time.c (time_cmp): should check with kind_of?, not instance_of?\n\n\t* time.c (time_eql): ditto.\n\n\t* time.c (time_minus): ditto.\n\nFri Dec  8 17:23:25 2000  Tachino Nobuhiro <tachino@open.nm.fujitsu.co.jp>\n\n\t* sprintf.c (rb_f_sprintf): proper string precision treat.\n\nFri Dec  8 10:44:05 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_remove_cvar): Module#remove_class_variable\n\t  added.\n\nThu Dec  7 17:35:51 2000  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* eval.c (stack_length): don't use __builtin_frame_address() on alpha.\n\nWed Dec  6 18:07:13 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* djgpp/config.sed, win32/Makefile.sub: typo.\n\n\t* eval.c (rb_mod_define_method): avoid VC4.0 warnings.\n\nWed Dec  6 13:38:08 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_and): tuning, make hash from shorter operand.\n\nWed Dec  6 01:28:50 2000  SHIROYAMA Takayuki  <psi@fortune.nest.or.jp>\n\n\t* gc.c (rb_gc): __builtin_frame_address() should not be used on\n\t  MacOS X.\n\n\t* gc.c (Init_stack): ditto.\n\nMon Dec  4 13:44:01 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* lib/jcode.rb: consider multibyte. not /n.\n\nMon Dec  4 09:49:36 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_inspect): output whole string contents. no more `...'\n\n\t* string.c (rb_str_dump): should propagate taintness.\n\n\t* hash.c (env_inspect): hash like human readable output.\n\n\t* variable.c (rb_ivar_get): prohibiting instance variable access\n\t  is too much restriction.\n\n\t* class.c (method_list): retrieving information should not be\n\t  restricted where $SAFE=4.\n\n\t* class.c (rb_obj_singleton_methods): ditto.\n\n\t* eval.c (rb_thread_priority): ditto.\n\n\t* eval.c (rb_thread_local_aref): ditto.\n\n\t* variable.c (rb_obj_instance_variables): ditto.\n\n\t* variable.c (rb_mod_const_at): ditto.\n\n\t* variable.c (rb_mod_class_variables): ditto.\n\n\t* eval.c (rb_exec_end_proc): end_proc should be preserved.\n\nSat Dec  2 22:32:43 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): || should accept exactly zero argument.\n\n\t* parse.y (stmt): multiple right hand side for single assignment\n\t  (e.g. a = 1,2) is allowed.\n\nWed Nov 29 07:55:29 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (w_long): dumping long should be smaller than 32bit max.\n\n\t* marshal.c (w_long): shorter long format for small integers(-123..122).\n\n\t* marshal.c (r_long): ditto.\n\nTue Nov 28 18:10:51 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_mod_define_method): quick hack to implement\n\t  on-the-fly method definition.  experimental.\n\nMon Nov 27 17:00:35 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should not redefine builtin classes/modules\n\t  from within wrapped load.\n\nMon Nov 27 08:57:33 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (call_end_proc): should be isolated from outer block.\n\nMon Nov 27 00:10:08 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_ctl): call ioctl/fcntl for fptr->f2 too.\n\n\t* process.c (rb_f_fork): call rb_thread_atfork() after creating\n\t  child process.\n\n\t* eval.c (rb_thread_atfork): kill all other threads immediately,\n\t  then turn the current thread into the main thread.\n\nSat Nov 25 23:12:22 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (ruby_run): move calling point of rb_trap_exit after\n\t  cleaning up threads.\n\n\t* eval.c (ruby_finalize): new function to call EXIT trap, END\n\t  procs and GC finalizers.\n\n\t* eval.c (rb_exec_end_proc): prevent recursion.\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): ditto.\n\n\t* signal.c (rb_trap_exit): ditto. made static.\n\n\t* process.c (rb_f_fork): should swallow all exceptions from block\n\t  execution.\n\n\t* process.c (fork_rescue): should call ruby_finalize().\n\n\t* parse.y (yycompile): rb_gc() removed.  I don't remember why I put\n\t  this here.  test code?\n\nFri Nov 24 22:03:48 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (EXCL): exclusive information is now stored in an\n\t  instance variable.  this enables proper marshal dump.\n\n\t* process.c (proc_waitpid): should clear rb_last_status ($?) if\n\t  no pid was given by waitpid(2).\n\nThu Nov 23 01:35:38 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* process.c (proc_waitpid2): returns nil if no pid found.\n\nWed Nov 22 23:45:15 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* range.c (range_eq): new method.  Compares start and end of range\n\t  respectively.\n\nWed Nov 22 11:01:32 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_class_variables): should honor singleton\n\t  class variable rule defined yesterday.\n\nTue Nov 21 23:24:14 2000  Mitsuteru S Nakao  <nakao@kuicr.kyoto-u.ac.jp>\n\n\t* numeric.c (flodivmod): missing second operand (typo).\n\nTue Nov 21 03:39:41 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (marshal_load): marshal format compatibility check\n\t  revised.   greater minor revision is UPWARD compatible;\n\t  downward compatibility is not assured.\n\n\t* eval.c (is_defined): clarify class variable behavior for\n\t  singleton classes.  class variables within singleton class\n\t  should be treated like within singleton method.\n\nMon Nov 20 13:45:21 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): set ruby_sourceline before evaluating\n\t  exceptions.\n\n\t* gc.c (gc_sweep): defer finalization in GC during compilation or\n\t  interrupt prohibit section.\n\n\t* gc.c (gc_sweep): mark all nodes before sweeping if GC happened\n\t  during compilation.\n\n\t* eval.c (rb_eval): should treat class variables specially in a\n\t  method defined in the singleton class.\n\nMon Nov 20 10:20:21 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dir.c, win32/win32.c, ruby.h: add rb_iglob().\n\nMon Nov 20 00:18:16 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_subseq): should return nil for outbound start\n\t  index.\n\n\t* marshal.c (marshal_load): show format versions explicitly when\n\t  format version mismatch happens.\n\nSun Nov 19 06:13:24 2000  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* marshal.c: use long for string/array length.\n\n\t* pack.c (swaps): use bit-or(|) instead of plus(+).\n\n\t* pack.c (swapl): ditto.\n\nSat Nov 18 15:18:16 2000  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* array.c (rb_ary_replace): array size should be in long.\n\n\t* array.c (rb_ary_concat): ditto.\n\n\t* array.c (rb_ary_hash): ditto.\n\nSat Nov 18 14:07:20 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: Socket#readline() reads until \"\\n\", not \"\\r\\n\"\n\nFri Nov 17 14:55:18 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* string.c (rb_str_succ): output should be NUL terminated.\n\nFri Nov 17 02:54:15 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_close): need not to flush before closing.\n\n\t* eval.c (rb_thread_join): should preserve last thread status when\n\t  THREAD_TO_KILL.\n\n\t* eval.c (rb_thread_stop): ditto.\n\n\t* io.c (io_fflush): wrap fflush by TRAP_BEG, TRAP_END.\n\n\t* eval.c (rb_eval): method defined within singleton class\n\t  definition should behave like singleton method about class\n\t  variables.\n\n\t* eval.c (is_defined): ditto.\n\nThu Nov 16 23:06:07 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: can call {old,new}_implementation any times.\n\n\t* lib/net/http.rb: HTTP#connecting, receive ->\n\t  common_oper, connecting.\n\n\t* lib/net/http.rb: output warning if u_header includes\n\t  duplicated header.\n\n\t* lib/net/http.rb: not check Connection:/Proxy-Connection;\n\t  always read until eof.\n\n\t* lib/net/protocol.rb: detects and catches \"break\" from block.\n\nThu Nov 16 16:32:45 2000  Masahiro Tanaka  <masa@stars.gsfc.nasa.gov>\n\n\t* bignum.c (bigdivrem): should have incremented ny first.\n\nThu Nov 16 14:58:00 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/socket/socket.c (sock_new): duplicates file descriptor\n\t  with myfddup() on mswin32/mingw32.\n\n\t* win32/win32.h: uses system original fdopen().\n\n\t* win32/win32.c (myfddup): newly added instead of myfdopen().\n\n\t* win32/win32.c (mybind, myconnect, mygetsockname, mygetsockopt,\n\t  mylisten, mysetsockopt): now accept file descriptor only, not\n\t  SOCKET.\n\n\t* win32/win32.c (myaccept, mysocket): return file descriptor,\n\t  instead of SOCKET.\n\nThu Nov 16 10:23:24 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (massign): too strict check for nameless rest argument.\n\n\t* eval.c (method_arity): mere * should return -1.\n\n\t* eval.c (intersect_fds): should check all FDs in the fd_set.\n\nWed Nov 15 19:33:20 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_attr): should clear method cache before calling hook.\n\n\t* eval.c (rb_eval): ditto.\n\n\t* eval.c (rb_mod_modfunc): ditto.\n\nMon Nov 13 22:44:52 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (rb_bug): print version to stderr.\n\nMon Nov 13 19:02:08 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* win32/win32.c, io.c, process.c: the exit status of program must be\n\t  multiplied 256 on mswin32 and msdosdjgpp(system(), ``).\n\nSat Nov 11 22:57:38 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (arg): uniformed treatment of -a**b, where a is a\n\t  number literal;  hacky but behavior appears more consistent.\n\n\t* parse.y (newline_node): reduce newline node (one per line).\n\n\t* random.c (rb_f_srand): should be prohibited in safe level\n\t  greater than 4.\n\nSat Nov 11 22:37:36 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* rubysig.h: do not use rb_trap_immediate on win32.\n\n\t* rubysig.h: new macros, ATOMIC_TEST, ATOMIC_SET, ATOMIC_INC,\n\t  ATOMIC_DEC, RUBY_CRITICAL and new definition of TRAP_BEG,\n\t  TRAP_END.\n\n\t* gc.c (ruby_xmalloc): should wrap malloc() by RUBY_CRITICAL.\n\n\t* signal.c (sighandle): better win32 sig handling.\n\n\t* win32/win32.c (flock): better implementation.\n\n\t* win32/win32.c (myselect): ditto.\n\n\t* win32/win32.c (myaccept): ditto.\n\n\t* win32/win32.c (waitpid): ditto.\n\n\t* win32/win32.c (myrename): ditto.\n\n\t* win32/win32.c (wait_events): support function for win32 signal\n\t  handling.\n\nSat Nov 11 08:34:18 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.31.\n\n\t* lib/net/http.rb: initializes header in HTTP, not HTTPCommand.\n\n\t* lib/net/protocol.rb, http.rb: rewrites proxy code.\n\nFri Nov 10 16:15:53 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (rb_num2long): use to_int, not to_i.\n\n\t* error.c: T_SYMBOL was misplaced by T_UNDEF.\n\n\t* parse.y (yylex): eval(\"^\") caused infinite loop.\n\nThu Nov  9 14:22:13 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (rb_io_taint_check): should check IO taintness; no\n\t  operation for untainted IO should be allowed in the sandbox.\n\n\t* rubyio.h (GetOpenFile): check IO taintness inside using\n\t  rb_io_taint_check().\n\nWed Nov  8 03:08:53 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (io_fflush): ensure fflush(3) would not block by calling\n\t  rb_thread_fd_writable().\n\nTue Nov  7 20:29:56 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.30.\n\n\t* lib/net/protocol.rb, smtp.rb: Command#critical_ok -> error_ok\n\n\t* lib/net/http.rb: reads header when also \"100 Continue\".\n\nTue Nov  7 04:32:19 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (bigdivrem): use bit shift to make y's MSB set.\n\nMon Nov  6  1:22:49 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* error.c (warn_print): do not use err_append(), to ensure output\n\t  to stderr.\n\n\t* error.c (rb_warn): use warn_print() instead of err_print().\n\n\t* error.c (rb_warning): ditto.\n\n\t* error.c (rb_bug): ditto.\n\n\t* eval.c (rb_load): re-raise exceptions during load.\n\n\t* time.c (make_time_t): remove useless adjust\n\nThu Nov  2 18:01:16 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* random.c (rb_f_rand): half-baked float support fixed.  This fix\n\t  was originally proposed by K.Kosako <kosako@sofnec.co.jp>.\n\nTue Oct 31 17:27:17 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c: change digit size to `long|int' if long long is\n\t  available.\n\n\t* marshal.c (w_object): support `long|int' digits.\n\n\t* marshal.c (r_object): ditto.\n\nSat Oct 28 23:54:22 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): allow =end at the end of file (without a\n\t  newline at the end).\n\nFri Oct 27 10:00:27 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_cstr2inum): should ignore trailing white spaces.\n\n\t* bignum.c (rb_str2inum): string may not have sentinel NUL.\n\nFri Oct 27 02:37:22 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_cstr2inum): wrongly assigned base to c before\n\t  badcheck check.\n\nThu Oct 26 02:42:50 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb: Command#critical_ok\n\n\t* lib/net/smtp.rb: clear critical flag before go to SMTP\n\nWed Oct 25 12:30:19 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_concat): replacing array might be the receiver\n\t  itself.  do not call rb_ary_push_m.\n\n\t* array.c (rb_ary_replace): replacing array might be the receiver\n\t  itself.  use memmove.\n\nFri Oct 20 07:56:23 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): ARGSPUSH should not modify args array.\n\nThu Oct 19 14:58:17 2000  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* pack.c (NUM2U32): should use NUM2ULONG().\n\nTue Oct 17 17:30:34 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* eval.c (error_print): ruby_sourcefile may be NULL.\n\nTue Oct 17 16:36:28 2000  Wes Nakamura  <wknaka@pobox.com>\n\n\t* pack.c (NATINT_U32): wrong use of sizeof.\n\nTue Oct 17 12:48:20 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* eval.c (rb_abort): nil check against ruby_errinfo.\n\n\t* eval.c (rb_thread_schedule): use FOREACH_THREAD_FROM instead of\n\t  FOREACH_THREAD, since curr_thread may be removed from thread ring.\n\n\t* eval.c (THREAD_ALLOC): errinfo should be Qnil.\n\n\t* eval.c (rb_callcc): th->prev,th->next are now already\n\t  initialized in THREAD_ALLOC.\n\nMon Oct 16 15:37:33 2000  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>\n\n\t* eval.c (rb_thread_inspect): tag size was shorter than required.\n\n\t* object.c (rb_obj_inspect): ditto.\n\nMon Oct 16 14:25:18 2000  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* object.c (sym_inspect): used `name' before initialization.\n\nMon Oct 16 14:06:00 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* pack.c (pack_pack): use NATINT_U32 for 'l', 'L', and 'N'.\n\n\t* pack.c (I32,U32): 32 bit sized integer.\n\n\t* pack.c (OFF16,OFF32B): big endian offset for network byteorder.\n\nMon Oct 16 06:39:32 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: hex-alpha is not [a-h] but [a-f].\n\nMon Oct 16 01:02:02 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): should not abort on exception if\n\t  $SAFE >= 4.\n\n\t* parse.y (sym): symbols for class variable names.\n\nSun Oct 15 01:49:18 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_flock): should accept interrupt.\n\n\t* process.c (rb_waitpid): ditto.\n\n\t* process.c (rb_waitpid): ditto.\n\n\t* process.c (proc_wait): ditto.\n\n\t* process.c (proc_waitpid2): wrong recursion.\n\nSat Oct 14 03:32:13 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_alloc): should not link a new thread in the\n\t  live thread ring before initialization.\n\nFri Oct 13 17:08:09 2000  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* lib/net/imap.rb: new file.\n\nThu Oct 12 18:56:28 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/pop.rb: POP3#reset\n\n\t* lib/net/http.rb: a code for \"Switch Protocol\" was wrongly 100.\n\nThu Oct 12 01:23:38 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: bug fix: CGI::html(): PRETTY option didn't work.\n\nThu Oct 12 00:03:02 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (sym_inspect): should adjust string length.\n\n\t* struct.c (rb_struct_to_s): ditto.\n\n\t* struct.c (rb_struct_inspect): ditto.\n\nWed Oct 11 22:15:47 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* eval.c (rb_thread_inspect): should adjust string length.\n\n\t* object.c (rb_any_to_s): ditto.\n\n\t* object.c (rb_obj_inspect): ditto.\n\nWed Oct 11 18:13:50 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_start_0): should check insecure exit.\n\nWed Oct 11 14:29:51 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb: 2nd arg for ProtocolError#initialize is\n\t  optional.\n\n\t* lib/net/http.rb: code refining.\n\nWed Oct 11 11:13:03 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (primary): setter method (e.g. foo=) should always be\n\t  public.\n\n\t* eval.c (rb_thread_raise): should not raise SecurityError if\n\t  exception raised by the interpreter.\n\n\t* eval.c (rb_thread_cleanup): skip all THREAD_KILLED threads\n\t  before FOREACH_THREAD.\n\nTue Oct 10 16:11:54 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* dln.c (dln_load): remove unused code for Cygwin.\n\nTue Oct 10 09:49:23 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (Init_File): FileTest.size should return 0 (not nil) for\n\t  empty files.\n\nSun Oct  8 13:20:26 2000  Guy Decoux  <decoux@moulon.inra.fr>\n\n\t* eval.c (POP_SCOPE): not just set SCOPE_DONT_RECYCLE, but do\n\t  scope_dup().\n\nSat Oct  7 15:10:50 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_reverse_bang): unnecessary ALLOCA_N() was\n\t  removed.\n\nFri Oct  6 14:50:24 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* ext/extmk.rb.in, lib/mkmf.rb: remove \"DESTDIR =\".\n\n\t* Makefile.in, win32/Makefile.sub, ruby.1: renamed -X to -C.\n\nFri Oct  6 12:50:52 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* array.c (rb_ary_plus): use to_ary(), not Check_Type().\n\n\t* array.c (rb_ary_concat): ditto.\n\n\t* gc.c (rb_gc): use __builtin_frame_address() for gcc.\n\n\t* eval.c (stack_length): ditto.\n\n\t* parse.y (assign_in_cond): stop warning till some better warning\n\t  condition will be found.\n\nThu Oct  5 18:02:39 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_obj_dup): should have propagated taint flag.\n\t  (ruby-bugs:#PR64,65)\n\nWed Oct  4 00:26:11 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (proc_arity): proc{|a|}'s arity should be -1.\n\nMon Oct  2 05:28:58 2000  akira yamada  <akira@ruby-lang.org>\n\n\t* string.c (trnext): minus at the end of pattern.\n\nSun Oct  1 00:43:34 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* configure.in: exp-name was wrong on cygwin and mingw32.\n\nThu Sep 28 14:57:09 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_compile_pattern): should try must_string calculation\n\t  every time.\n\nTue Sep 19 23:47:44 2000  SHIROYAMA Takayuki  <psi@fortune.nest.or.jp>\n\n\t* configure.in, config.guess, config.sub: MacOS X support.\n\nWed Sep 27 18:40:05 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.6.1 released.\n\nWed Sep 27 16:13:05 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* mkconfig.rb: variables should be expanded only if /\\$\\{?\\w+\\}?/.\n\nTue Sep 26 18:09:51 2000  WATANABE Hirofumi  <eban@ruby-lang.org>\n\n\t* string.c: include <math.h>\n\nTue Sep 26 15:59:50 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* object.c (rb_mod_dup): metaclasses of class/module should not be\n\t  cleared by rb_obj_dup.\n\nTue Sep 26 02:44:54 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (GC_MALLOC_LIMIT): size extended.\n\n\t* regex.c (DOUBLE_STACK): use machine's stack region for regex\n\t  stack if its size is small enough.\n\nMon Sep 25 18:13:07 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c: include <defines.h>.\n\n\t* eval.c (rb_add_method): cache mismatch by method\n\t  definition. need to clear_cache_by_id every time.\n\nMon Sep 25 13:31:45 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/win32.c (NtCmdGlob): substitute '\\\\' with '/'.\n\nMon Sep 25 00:35:01 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* defines.h: #undef HAVE_SETITIMER on cygwin.\n\nSun Sep 24 03:01:53 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, http.rb: typo.\n\nSat Sep 23 07:33:20 2000  Aleksi Niemela  <aleksi.niemela@cinnober.com>\n\n\t* regex.c (re_compile_pattern): nicer regexp error messages for\n\t  invalid patterns.\n\nSat Sep 23 03:06:25 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_autoload_load): should not require already\n\t  provided features.\n\nFri Sep 22 15:46:21 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/http.rb: too early parameter expansion in string.\n\nFri Sep 22 13:58:51 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/extmk.rb.in: don't use default $:\n\nFri Sep 22 13:42:50 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* regex.c (PUSH_FAILURE_COUNT): avoid casting warning on alpha.\n\n\t* regex.c (PUSH_FAILURE_POINT): ditto.\n\nFri Sep 22 10:16:21 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/config.h.in: add HAVE_TELLDIR, HAVE_SEEKDIR\n\nThu Sep 21 19:04:34 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/extmk.rb, lib/mkmf.rb (install_rb): check whether libdir is\n\t  directory or not.\n\nThu Sep 21 17:23:05 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* file.c (rb_file_s_symlink): use HAVE_SYMLINK.\n\n\t* file.c (rb_file_s_readlink): use HAVE_READLINK.\n\n\t* dir.c (dir_tell): use HAVE_TELLDIR.\n\n\t* dir.c (dir_seek): use HAVE_SEEKDIR.\n\n\t* configure.in (AC_CHECK_FUNCS): lstat, symlink, readlink,\n\t  telldir, seekdir checks added.\n\n\t* file.c (lstat): should use stat(2) if lstat(2) is not\n\t  available.\n\nThu Sep 21 15:59:23 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.29.\n\n\t* lib/net/http.rb: HTTPReadAdapter -> HTTPResponseReceiver\n\n\t* lib/net/http.rb (connecting): response is got in receive()\n\nThu Sep 21 15:49:07 2000  Wayne Scott  <wscott@ichips.intel.com>\n\n\t* lib/find.rb (find): should not follow symbolic links;\n\t  tuned performance too.\n\nWed Sep 20 23:21:38 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.c (load_file): two Ctrl-D was required to stop ruby at the\n\t  beginning of stdin script read.\n\nWed Sep 20 14:01:45 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_provided): detect infinite load loop.\n\n\t* eval.c (rb_provided): too weak filename comparison.\n\n\t* eval.c (rb_thread_alloc): avoid recycling still referenced\n\t  dvar structures.\n\n\t* eval.c (rb_callcc): ditto.\n\n\t* eval.c (THREAD_ALLOC): fill dyna_vars field by ruby_dyna_vars.\n\nTue Sep 19 17:47:03 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* stable version 1.6.0 released.\n\nTue Sep 19 16:24:52 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* marshal.c (Init_marshal): provide marshal.so no more.\n\nTue Sep 19 14:01:01 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in, win32/setup.mak: include version number\n\t  in RUBY_SO_NAME.\n\nTue Sep 19 13:07:47 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): was confusing $~ and $_.\n\nTue Sep 19 13:06:53 2000  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* signal.c (rb_f_kill): signum may be a negative number, should be\n\t  treated by signed number.\n\nTue Sep 19 01:14:56 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_provide): better feature handling.\n\n\t* eval.c (rb_f_require): loading ruby library may be partial\n\t  state.  checks in rb_thread_loading is integrated.\n\n\t* eval.c (rb_provided): better thread awareness.\n\n\t* lib/irb/frame.rb: 6 (not 5) parameters for trace_func proc.\n\n\t* eval.c (error_print): should print error position even if\n\t  get_backtrace() failed.\n\nSat Sep 16 03:29:59 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_f_require): rb_provided() was called too early; does\n\t  not work well with threads.\n\n\t* parse.y (ensure): should distinguish empty ensure and non\n\t  existing ensure.\n\n\t* file.c (Init_File): extending File by class of FileTest was\n\t  serious mistake.\n\nThu Sep 14 02:46:54 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_yield): array strip should be done in this\n\t  function.\n\nWed Sep 13 17:01:03 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* bignum.c (rb_big_eq): incomplete value comparison of bignums.\n\nWed Sep 13 06:39:54 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_mod_class_variables): Module#class_variables added.\n\nWed Sep 13 06:09:26 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: bug fix: CGI::header(): output status header.\n\nWed Sep 13 01:09:12 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (yylex): allow global variables like '$__a'.\n\nTue Sep 12 22:28:43 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/socket/extconf.rb: avoid using terrible <netinet/tcp.h>\n\t  on cygwin 1.1.5.\n\nTue Sep 12 16:01:58 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* array.c (rb_ary_unshift_m): typo.\n\nTue Sep 12 15:37:55 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): stripped array too much, should remove just\n\t  for proc_call().\n\nTue Sep 12 07:05:24 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: version 2.0.0: require ruby1.5.4 or later.\n\n\t* lib/net/telnet.rb: version 1.6.0\n\nTue Sep 12 03:26:07 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (massign): use to_ary to get an array if available.\n\n\t* object.c (rb_Array): ditto.\n\nMon Sep 11 14:24:47 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* hash.c (ruby_setenv): should not free the element of\n\t  origenvironment.\n\n\t* parse.y (command_call): kYIELD moved to this rule to allow\n\t  'a = yield b'. (ruby-bugs-ja:#PR15)\n\nMon Sep 11 01:27:54 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_yield_0): proc#call([]) should pass single value to\n\t  the block.\n\n\t* eval.c (callargs): reduce array allocation.\n\n\t* eval.c (massign): precise check for argument number.\n\nFri Sep  8 10:05:17 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (STR_NO_ORIG): should be FL_USER2.\n\nThu Sep  7 14:17:51 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* string.c (rb_str_cat): should work even for concatenating same\n\t  string.\n\nWed Sep  6 17:06:38 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_cvar_declare): should check superclass's class\n\t  variable first.\n\nWed Sep  6 10:42:02 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* misc/ruby-mode.el (ruby-calculate-indent): shift continuing line\n\t  if previous line ends with modifier keyword.\n\n\t* misc/ruby-mode.el (ruby-parse-region): should not give up if\n\t  modifiers are at the end of line.\n\n\t* misc/ruby-mode.el (ruby-expr-beg): indented wrongly if modified\n\t  statement was size 1.\n\nWed Sep  6 10:41:19 2000  Kenichi Komiya  <kom@mail1.accsnet.ne.jp>\n\n\t* misc/ruby-mode.el (ruby-parse-region): modifier was not handled\n\t  well on emacs19.\n\nTue Sep  5 17:10:12 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_to_s): fixed zone string UTC for utc time object.\n\nTue Sep  5 00:26:06 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* regex.c (re_search): range worked wrongly on bm_search().\n\nMon Sep  4 13:40:40 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: renamed libruby.a to libruby.{cygwin,mingw32}.a\n\t  on cygwin and mingw32.\n\nSun Sep  3 23:44:04 2000  Noriaki Harada  <tenmei@maoh.office.ne.jp>\n\n\t* io.c (NO_SAFE_RENAME): for BeOS too.\n\nSun Sep  3 11:31:53 2000  Takaaki Tateishi  <ttate@jaist.ac.jp>\n\n\t* parse.y (rescue): no assignment was done if rescue body was\n\t  empty.\n\nSat Sep  2 10:52:21 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (call_args,aref_args): block_call can be the last\n\t  argument.\n\n\t* parse.y (COND_PUSH,COND_POP): maintain condition stack to allow\n\t  kDO2 in parentheses in while/until/for conditions.\n\n\t* parse.y (yylex): generate kDO2 for EXPR_ARG outside of\n\t  while/until/for condition.\n\nFri Sep  1 10:36:29 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (aref_args,opt_call_args): add block_call to allow a\n\t  method without parentheses and with block as a last argument.\n\n\t* hash.c (rb_hash_sort): should not return nil.\n\n\t* re.c (match_aref): should use rb_reg_nth_match().\n\n\t* eval.c (POP_SCOPE): recycled scopes too much\n\n\t* eval.c (Init_eval): extend room for stack allowance.\n\n\t* eval.c (POP_SCOPE): frees scope too much.\n\nThu Aug 31 14:28:39 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* gc.c (rb_gc_mark): T_SCOPE condition must be more precise.\n\n\t* eval.c (scope_dup): should not make all duped scope orphan.\n\nThu Aug 31 10:11:47 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (stmt): allow stmt_rhs to be right hand side of multiple\n\t  assignment.\n\n\t* time.c (rb_time_timeval): type error should not mention the word\n\t  'interval'.\n\nWed Aug 30 23:21:20 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* numeric.c (rb_num2long): use rb_Integer() instead of independent\n\t  convert routine.\n\n\t* eval.c (rb_rescue2): now takes arbitrary number of exception types.\n\n\t* object.c (rb_convert_type): use rb_rescue2 now to handle NameError.\n\n\t* object.c (rb_convert_type): better error message.\n\nWed Aug 30 17:09:14 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): AlphaNT support.\n\nWed Aug 30 14:19:07 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (node_assign): should support NODE_CVASGN2 too.\n\nWed Aug 30 11:31:47 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): add the\n\t  arguments checking.\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): add taint\n\t  checking. allow String object in the third argument.\n\nWed Aug 30 10:29:40 2000  Masahiro Tomita  <tommy@tmtm.org>\n\n\t* io.c (rb_f_p): flush output buffer.\n\nTue Aug 29 16:29:15 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* parse.y (assignable): remove NODE_CVASGN3.\n\n\t* parse.y (gettable): remove NODE_CVAR3.\n\nTue Aug 29 02:02:14 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* lib/mkmf.rb (create_makefile): handles create_makefile(\"a/b\").\n\n\t* ext/extmk.rb.in (create_makefile): ditto\n\nMon Aug 28 18:43:54 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): now handles class variables.\n\n\t* eval.c (rb_eval): class variable behavior revisited.\n\n\t* parse.y (assignable): ditto.\n\n\t* parse.y (gettable): ditto.\n\n\t* regex.c (PUSH_FAILURE_COUNT): push/pop interval count on failure\n\t  stack.  this fix is inspired by the Emacs21 patch from Stefan\n\t  Monnier <monnier@cs.yale.edu>.\n\nFri Aug 25 15:24:39 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* variable.c (rb_cvar_get): should not follow __attached__.\n\n\t* variable.c (rb_cvar_set): ditto.\n\n\t* variable.c (rb_cvar_declare): ditto.\n\n\t* variable.c (mod_av_set): second class variable assignment at the\n\t  toplevel should not give warning.\n\nFri Aug 25 01:18:36 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (next_argv): prepare path for open file.\n\n\t* string.c (rb_str_setter): moved from io.c.\n\n\t* io.c (next_argv): filename should be \"-\" for refreshed ARGF.\n\nThu Aug 24 15:27:39 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/socket/socketport.h: use `extern int h_errno' if needed.\n\nSat Aug 19 01:34:02 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/sdbm/_sdbm.c (sdbm_prep): flags should be or-ed by O_BINARY on\n\t  Win32 too.\n\n\t* ext/sdbm/_sdbm.c (makroom): fill hole with 0 on Win32 too.\n\nFri Aug 18 13:23:59 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_eval): should preserve and clear $! value before\n\t  compilation.\n\n\t* eval.c (eval): ditto.\n\nFri Aug 18 11:06:19 2000  Shugo Maeda  <shugo@ruby-lang.org>\n\n\t* ext/socket/socket.c (s_accept): start GC on EMFILE/ENFILE.\n\nThu Aug 17 16:04:48 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (is_defined): should clear ruby_errinfo.\n\nThu Aug 17 04:26:31 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.27.\n\n\t* lib/net/protocol.rb: writing methods returns written byte size.\n\n\t* lib/net/smtp.rb: send_mail accepts many destinations.\n\nWed Aug 16 00:43:47 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* time.c (time_s_times): use CLK_TCK for HZ if it's defined.\n\nTue Aug 15 17:30:59 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (frame_dup): should set flag FRAME_MALLOC after\n\t  argv allocation.\n\n\t* eval.c (blk_free): should not free argv if GC was called before\n\t  frame_dup.\n\nTue Aug 15 16:08:40 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: add ac_cv_func_times=yes for mingw32.\n\n\t* win32/win32.c (mytimes): typo.\n\nTue Aug 15 01:45:28 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* io.c (argf_eof): should return true at the end of ARGF without\n\t  checking stdout if arguments are given.\n\nMon Aug 14 10:34:32 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_thread_status): status should return false for normal\n\t  termination, nil for termination by exception.\n\nFri Aug 11 15:43:46 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_undef): give warning for undefining __id__, __send__.\n\nThu Aug 10 08:05:03 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_callcc): returned current thread instead of\n\t  continuation wrongly.\n\nThu Aug 10 05:40:28 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/extmk.rb.in: $CPPFLAGS should be initialized.\n\n\t* ext/tcltklib/depend: add stubs.o.\n\n\t* ext/tcltklib/extconf.rb: use $CPPFLAGS instead of $CFLAGS.\n\nWed Aug  9 16:31:48 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* eval.c (rb_callcc): thread status for continuations must be\n\t  THREAD_KILLED, otherwise thread_free() breaks other threads.\n\nWed Aug  9 13:24:25 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/win32.[ch]: emulate rename(2).\n\nTue Aug  8 14:01:46 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/tcltklib/tcltklib.c: support --enable-tcltk_stubs\n\n\t* ext/tcltklib/extconf.rb: ditto.\n\n\t* ext/tcltklib/stubs.c: created. examine candidate shared libraries.\n\nMon Aug  7 13:59:12 2000  Yukihiro Matsumoto  <matz@ruby-lang.org>\n\n\t* ruby.h (CLONESETUP): should copy flags before any potential\n\t  object allocation.\n\n\t* regex.c (re_match): check for stack depth was needed.\n\nSat Aug  5 16:43:43 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* djgpp/*: convert DOS line endings to UNIX style.\n\n\t* djgpp/config.status: rename to config.sed for SFN.\n\n\t* lib/ftools.rb (compare, safe_unlink, chmod): avoid warnings.\n\n\t* lib/ftools.rb (move): typo. not `tpath', but `to'.\n\nFri Aug  4 23:26:48 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (proc_call): gives warning if a block is supplied.\n\n\t* eval.c (rb_eval): no warning for discarding if an alias for the\n\t  method is already made.\n\nFri Aug  4 16:32:29 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_reject_bang): returns nil if no element removed.\n\n\t* hash.c (rb_hash_reject_bang): returns nil if no element removed.\n\nThu Aug  3 19:44:26 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_fd_writable): should return integer value.\n\n\t* array.c (rb_ary_assoc): search array element whose length is\n\t  longer than 0 (not 1).\n\nWed Aug  2 18:27:47 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_wait_fd): prohibit thread context switch\n\t  during compilation.\n\n\t* eval.c (rb_cont_call): prohibit Continuation#call across threads.\n\nWed Aug  2 08:22:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (rb_gc): clear malloc_memories to zero, to avoid potential\n\t  super frequent GC invocation. (ruby-bugs:#PR48)\n\n\t* gc.c (rb_gc): only add_heap() if GC trigger condition is\n\t  satisfied.\n\nTue Aug  1 16:41:58 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (proc_options): global load path setting moved from\n\t  ruby_prog_init().\n\n\t* ruby.c (incpush): renamed.  push path entry at the END of the\n\t  load path array.  This makes -I directories sorted in order in\n\t  the arguments.\n\nSat Jul 29 23:42:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (dir_each): should check whether dir is closed during the\n\t  block execution. (ruby-bugs:#PR47)\n\nSat Jul 29 21:57:30 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ruby.c (rubylib_mangle): provide another buffer for the result.\n\nWed Jul 26 10:09:01 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: set SOLIBS to LIBS on Cygwin.\n\n\t* configure.in: LIBRUBY_SO='$(RUBY_INSTALL_NAME)'.$target_os.dll\n\t  on cygwin and mingw32. ruby-cygwin.dll is bad. why?\n\nWed Jul 26 10:04:03 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (gc_sweep): avoid full scan during compilation.\n\n\t* gc.c (rb_gc): add heap during no gc period (including\n\t  compilation).\n\nTue Jul 25 19:03:04 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* cygwin/GNUmakefile: use puts instead of print, because\n\t  Cygwin DLL's behavior is changed(or bug?).\n\n\t* configure.in: LIBRUBY_SO='$(RUBY_INSTALL_NAME)'-$target_os.dll\n\t  on cygwin and mingw32.\n\n\t* cygwin/GNUmakefile: ditto.\n\n\t* Makefile.in: $(SOLIBS) should be put after dmyext.@OBJEXT@.\n\n\t* instruby.rb: install $(LIBRUBY) to libdir\n\t  if $(LIBRUBY) != $(LIBRUBY_A_).\n\nTue Jul 25 15:16:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_p): redirect to $defout.\n\nMon Jul 24 18:52:55 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/win32.c (win32_getenv): should remove `static'.\n\n\t* ruby.c (rubylib_mangle): support \"/hoge;/foo\"\n\nMon Jul 24 10:28:55 2000  GOTO Kentaro  <gotoken@math.sci.hokudai.ac.jp>\n\n\t* string.c (rb_str_count): raise exception if no argument is\n\t  given.\n\nSun Jul 23 12:55:04 2000  Dave Thomas  <Dave@Thomases.com>\n\n\t* string.c (rb_str_rindex): Support negative end position.\n\nFri Jul 21 17:35:01 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (aref_args): command_call now be permitted as\n\t  aref_args.\n\n\t* process.c (proc_getpriority): getpriority(2) may return valid\n\t  negative number.  use errno to detect error.\n\n\t* marshal.c (dump_ensure): dumped string should be tainted if\n\t  any among target objects is tainted.\n\n\t* marshal.c (r_regist): restored object should be tainted if and\n\t  only if the source is a file or a tainted string.\n\nWed Jul 19 15:14:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (bigdivrem): should use rb_int2big(), not rb_uint2big().\n\nTue Jul 18 14:58:30 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (ruby_options): should treat SystemExit etc. properly.\n\n\t* parse.y (yycompile): should check compile_for_eval, not\n\t  ruby_in_eval.\n\nMon Jul 17 04:29:50 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/mkmf.rb: converts extension of $objs into $OBJEXT.\n\nSun Jul 16 03:02:34 2000  Dave Thomas <dave@thomases.com>\n\n\t* lib/weakref.rb: Change to use new ObjectSpace calls.\n\nSat Jul 15 21:59:58 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): should not redefine __id__ nor __send__.\n\n\t* gc.c (define_final): integrate final.rb features into the\n\t  interpreter.  define_finalizer and undefine_finalizer was\n\t  added to ObjectSpace.  plus, add_finalizer, remove_finalizer,\n\t  and call_finalizer are deprecated now.\n\nSat Jul 15 01:32:34 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_mod_method): implements unbound method.\n\n\t* eval.c (Init_eval): should prohibit `module_function' for class\n\t  Class.\n\nFri Jul 14 17:19:59 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* cygwin/GNUmakefile.in: use miniruby instead of sed.\n\nFri Jul 14 12:49:50 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (argf_eof): need to check stdin, when next_p == -1.\n\n\t* io.c (read_all): use io_fread() instead of fread(3).\n\n\t* io.c (io_reopen): should clearerr FILE if fd < 3.\n\n\t* re.c (rb_reg_match_m): the result is exported, so it should be\n\t  declared as busy.\n\n\t* eval.c (rb_eval): should preserve errinfo even if return, break,\n\t  etc. is called in rescue clause.\n\n\t* instruby.rb: install irb too.\n\nWed Jul 12 15:32:57 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_const_get): constants for builtin classes must\n\t  have higher priority than constants from included modules at\n\t  Object class.\n\n\t* bignum.c (bigdivrem): small embarrassing typo.\n\nWed Jul 12 15:06:28 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): use rb_const_get_at().\n\n\t* variable.c (top_const_get): retrieve toplevel constants only,\n\t  not ones of Object (and its included modules) in general.\n\nWed Jul 12 15:04:11 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.26.\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb:\n\t  add module Net::NetPrivate and its inner classes\n\t  {Read,Write}Adapter, Command, Socket,\n\t  SMTPCommand, POP3Command, APOPCommand, HTTPCommand\n\nWed Jul 12 13:10:30 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (bigdivrem): defer bignorm().\n\n\t* bignum.c (bignorm): accepts accidental fixnums.\n\nTue Jul 11 16:54:17 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): `@<digit>' is no longer a valid instance\n\t  variable name.\n\nTue Jul 11 01:51:50 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (rb_big_divmod): should not use Integer(float) for\n\t  the right operand.\n\n\t* bignum.c (rb_big_remainder): ditto.\n\n\t* bignum.c (rb_big_modulo): ditto.\n\nMon Jul 10 15:27:16 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* io.c (pipe_finalize): should set rb_last_status when pclose().\n\nMon Jul 10 09:07:54 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* error.c (rb_bug): print version number and such too.\n\nSat Jul  8 23:08:40 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_start_0): should copy previous scopes to\n\t  prevent rb_gc_force_recycle().\n\nFri Jul  7 23:36:36 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/addrinfo.h: move IN_EXPERIMENTAL and IN_LOOPBACKNET\n\t  definitions to ext/socket/sockport.h.\n\n\t* ext/socket/extconf.rb: add getservbyport() and arpa/inet.h check.\n\n\t* ext/socket/getaddrinfo.c (getaddrinfo): SOCK_RAW may not be\n\t  defined (ex. BeOS, Palm OS 2.x or before).\n\n\t* ext/socket/getnameinfo.c (getnameinfo): getservbyport() may not\n\t  exist (ex. BeOS, Palm OS).\n\n\t* ext/socket/sockport.h: add IN_EXPERIMENTAL, IN_CLASSA_NSHIFT,\n\t  IN_LOOPBACKNET, AF_UNSPEC, PF_UNSPEC and PF_INET.\n\nFri Jul  7 03:30:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (aref_args): should allow Hash[:a=>2] etc.\n\n\t* numeric.c (fix_aref): convert index by NUM2INT, not FIX2INT.\n\t  (ruby-bugs:#PR37)\n\n\t* time.c (time_localtime): should prohibit for frozen time.\n\n\t* time.c (time_gmtime): ditto.\n\nThu Jul  6 19:12:12 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_file_s_open): should not terminate fptr; just clear it.\n\n\t* ruby.c (proc_options): should not call require_libraries()\n\t  twice.\n\n\t* ruby.c (require_libraries): clear req_list_head.next after\n\t  execution.\n\nThu Jul  6 13:51:57 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* object.c (rb_to_id): name may not be symbol nor fixnum.\n\n\t* struct.c (rb_struct_s_def): name may be nil.\n\nThu Jul  6 02:09:06 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (bigdivrem): new function to return remainder.\n\n\t* numeric.c (fixdivmod): now returns modulo, not remainder.\n\n\t* numeric.c (flodivmod): ditto.\n\n\t* bignum.c (bigdivmod): ditto.\n\n\t* numeric.c (num_modulo): new method; alias to '%'.\n\nThu Jul  6 00:51:43 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/win32.c (NtCmdGlob): patterns should be separated and\n\t  NUL terminated.\n\nWed Jul  5 22:27:56 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* cygwin/GNUmakefile: use ruby.def to make rubycw.dll.\n\n\t* ext/extmk.rb.in: create target.def.\n\n\t* lib/mkmf.rb: ditto.\n\nWed Jul  5 09:47:14 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_arg): Time::local, Time::gm now take 7th optional\n\t  argument for usec.\n\n\t* numeric.c (num_ceil, etc): default ceil, floor, round, truncate\n\t  implementation for Numeric, using `to_f'.\n\n\t* io.c (rb_io_reopen): clear fptr->path after free() to prevent\n\t  potential GC crash.\n\n\t* io.c (rb_file_s_open): terminate fptr unless null.\n\n\t* io.c (rb_file_initialize): ditto.\n\n\t* lib/tempfile.rb: specify FILE::CREAT|File::EXCL to open for\n\t  better security.\n\n\t* numeric.c (flo_truncate): new method.\n\nWed Jul  5 01:02:53 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/extmk.rb.in: join ' ' -> join(' ').\n\n\t* lib/mkmf.rb: ditto.\n\nTue Jul  4 13:51:29 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/dbm/dbm.c: add methods added to Hash in 1.5.x.\n\n\t* ext/gdbm/gdbm.c: ditto.\n\n\t* ext/sdbm/init.c: ditto.\n\n\t* eval.c (proc_call): args may be Qundef (means no argument), do\n\t  not call TYPE() for args.\n\nTue Jul  4 13:20:56 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/extmk.rb.in: make command line must be single-quoted.\n\t  $(RUBY_INSTALL_NAME) is command substitution in the POSIX sh.\n\nTue Jul  4 13:16:02 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* util.c (rb_type): should add T_UNDEF.\n\nTue Jul  4 09:30:35 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (here_document): supports EOF right after terminator.\n\n\t* random.c (rb_f_rand): argument is now optional (rand(max=0)).\n\nTue Jul  4 01:50:49 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/ruby.def: remove ruby_mktemp.\n\nTue Jul  4 01:27:13 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_rescue2): new function to rescue arbitrary exception.\n\n\t* numeric.c (do_coerce): should catch NameError explicitly.\n\nTue Jul  4 00:15:23 2000  Dave Thomas  <Dave@thomases.com>\n\n\t* numeric.c (Init_Numeric): forgot to register Numeric#remainder.\n\nMon Jul  3 23:46:56 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/win32.c (myselect, myaccept): disable interrupt while\n\t  executing accept() or select() to avoid Ctrl-C causes\n\t  \"unknown software exception (0xc0000029)\".\n\nMon Jul  3 18:35:41 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* lib/mkmf.rb: use null device if it exists for cross-compiling.\n\nMon Jul  3 18:19:51 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.26.\n\n\t* lib/net/protocol.rb (finish): do nothing unless active.\n\n\t* lib/net/http.rb: HTTP#{get,post}2 again (for new impl).\n\nMon Jul  3 16:47:22 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* cygwin/GNUmakefile: librubys.a -> lib$(RUBY_INSTALL_NAME)s.a\n\n\t* configure.in: use AC_CANONICAL_{HOST,TARGET,BUILD}.\n\nMon Jul  3 13:15:02 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (fix_divmod): x * d + m = y where d, m = x.divmod(y).\n\n\t* bignum.c (rb_big_divmod): ditto.\n\n\t* numeric.c (fixdivmod): does not depend C's undefined %\n\t  behavior.  adopt to fmod(3m) behavior.\n\n\t* numeric.c (flo_mod): modulo now reserves fmod(3m) behavior.\n\n\t* numeric.c (num_remainder): 'deprecated' warning.\n\nMon Jul  3 10:27:28 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: use AC_CANONICAL_SYSTEM.\n\nSun Jul  2 21:17:37 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: support without --enable-shared for cygwin/mingw32.\n\n\t* cygwin/GNUmakefile: ditto.\n\n\t* ext/extmk.rb.in: use null device if it exists for cross-compiling.\n\n\t* lib/mkmf.rb: ditto.\n\n\t* util.c (ruby_mktemp): remove unused ruby_mktemp().\n\nSun Jul  2 14:18:04 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* eval.c (TMP_PROTECT_END): tmp__protect_tmp may be NULL.\n\nSun Jul  2 03:37:50 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.25.\n\n\t* lib/net/protocol.rb (each_crlf_line): beg = 0 is needed in adding{}\n\n\t* lib/net/smtp.rb: allow String for to_addr of SMTP#sendmail\n\nSat Jul  1 15:22:35 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (fix_rshift): should handle shift value more than\n\t  sizeof(long).\n\nSat Jul  1 15:22:35 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): the value from RTEST() is not valid Ruby\n\t  object.  result should be either true or false.\n\nSat Jul  1 09:30:06 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* re.c (rb_reg_initialize): was freeing invalid pointer.\n\nSat Jul  1 03:25:56 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (call_args): command_call can be the last argument of\n\t  call_args.  It had to be the only argument.\n\n\t* re.c (rb_reg_s_quote): should not dump core even for unsane mbc\n\t  string.\n\nFri Jun 30 01:36:20 2000  Aleksi Niemela  <aleksi.niemela@cinnober.com>\n\n\t* parse.y (f_norm_arg): better, nicer error message.\n\nThu Jun 29 07:45:33 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (udp_send): destination may be packed\n\t  struct sockaddr.\n\n\t* object.c (rb_Integer): Integer(nil) should be invalid, on the\n\t  other hand, nil.to_i is OK.\n\nWed Jun 28 17:26:06 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (ip_recvfrom): udp_recvfrom and tcp_recvfrom\n\t  is merged and moved to IPSocket#recvfrom.\n\n\t* ext/socket/socket.c (sock_s_getaddrinfo): family can be a\n\t  strings such as \"AF_INET\" etc.\n\n\t* ruby.c (require_libraries): . and RUBYLIB added to $load_path\n\t  just before -r procedure.\n\n\t* ruby.c (proc_options): -e, - did not exec -r.\n\nWed Jun 28 14:52:28 2000  Koga Youichirou <y-koga@mms.mt.nec.co.jp>\n\n\t* config.sub: NetBSD/hpcmips support.\n\nWed Jun 28 10:11:06 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c: gc trigger threshold changed; GC_NEWOBJ_LIMIT removed,\n\t  FREE_MIN is increased to 4096.\n\nTue Jun 27 22:39:28 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.24.\n\n\t* lib/net/protocol.rb: modified each_crlf_line again.\n\n\t* lib/net/protocol.rb: do_write_beg,do_write_end -> writing{}\n\t  do_write_do -> do_write\n\n\t* lib/net/http.rb: can make proxy connection by passing\n\t  addresses to HTTP.new, start.\n\n\t* lib/net/http.rb: HTTP.new_implementation, old_implementation:\n\t  can use 1.2 implementation of head, get, post, put.\n\t  (see document)\n\nTue Jun 27 12:05:10 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32.c (myfdclr): new function.\n\n\t* win32.h: add FD_CLR.\n\nMon Jun 26 23:41:41 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ruby.h: add cast for ANSI style.\n\n\t* gc.c (rb_data_object_alloc): use RUBY_DATA_FUNC.\n\nMon Jun 26 22:20:03 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/win32.c (is_socket, extract_file_fd): New function.\n\n\t* win32/win32.c (myfdopen): use is_socket().\n\n\t* win32/win32.c (myselect): return non socket files immediately\n\t  if file and socket handles are mixed.\n\nMon Jun 26 16:21:30 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_schedule): wait_for cleared too early.\n\nMon Jun 26 09:15:31 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c: remove obsolete 'F', 'D' specifiers.\n\nSun Jun 25 00:55:03 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/socket.c (sock_s_getnameinfo): `res' would not\n\t  be assigned if TYPE(sa) == T_STRING.\n\nSat Jun 24 14:36:29 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* config*.dj, configure.bat, top.sed: move to djgpp/.\n\nSat Jun 24 02:34:17 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (load_file): call require_libraries() here to let\n\t  debug.rb work properly.\n\nFri Jun 23 22:34:51 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* bignum.c (rb_big_lshift): reorder xds assignment to avoid\n\t  reusing `x' as `len' by VC++ 6.0 SP3 compiler with -Ox switch.\n\nFri Jun 23 01:11:27 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_substr): should return empty string (\"\"),\n\t  if beg == str.size and len == zero, mostly for convenience and\n\t  backward compatibility.\n\n\t* parse.y (new_super): should tweak block_pass node for super too.\n\n\t* string.c (rb_str_split_m): last split element should not be nil,\n\t  but \"\" when limit is specified.\n\nThu Jun 22 17:27:46 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_substr): str[n,m] now returns nil when n equals\n\t  to str.size.\n\nThu Jun 22 13:49:02 2000  Uechi Yasumasa <uechi@ryucom.ne.jp>\n\n\t* lib/net/ftp.rb: support resuming.\n\nThu Jun 22 13:37:19 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* eval.c (rb_thread_sleep_forever): merge pause() macro.\n\nWed Jun 21 08:49:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): should not raise exception just by defining\n\t  singleton class.\n\nWed Jun 21 01:18:03 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.h: two macros RUBY_DATA_FUNC and RUBY_METHOD_FUNC are added\n\t  to make writing C++ extensions easier.\n\n\t* array.c (rb_ary_dup): internal classes should not be shared by dup.\n\n\t* hash.c (rb_hash_dup): ditto.\n\n\t* object.c (rb_obj_dup): ditto.\n\n\t* string.c (rb_str_dup): ditto.\n\n\t* error.c (Init_Exception): renamed NotImplementError to\n\t  NotImplementedError.\n\nTue Jun 20 16:22:38 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (make_time_t): bug in DST boundary.\n\nTue Jun 20 10:54:19 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: add eval sitedir.\n\nTue Jun 20 06:14:43 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: change: version syntax. old: x.yz, now: x.y.z\n\n\t* lib/net/telnet.rb: ditto.\n\nTue Jun 20 00:37:45 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_kcode_m): Regexp#kcode returns nil for code unfixed\n\t  regexp object.\n\n\t* bignum.c (bigdivmod): bignum zero check was wrong.\n\nMon Jun 19 10:48:28 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_cvar_set): forgot to add security check for class\n\t  variable assignment.\n\nSun Jun 18 22:49:13 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: single quoted sitedir.\n\n\t* mkconfig.rb: add DESTDIR for cross-compiling.\n\n\t* lib/mkmf.rb: add DESTDIR.\n\n\t* ruby.c (load_file): force binmode if fname includes \".exe\"\n\t  on DOSISH.\n\nSat Jun 17 23:22:17 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (rb_f_sprintf): should ignore negative precision given\n\t  by <%.*>.\n\n\t* sprintf.c (rb_f_sprintf): should allow zero precision.\n\nSat Jun 17 03:13:29 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_localtime): avoid unnecessary call of localtime.\n\n\t* time.c (time_gmtime): avoid unnecessary call of gmtime.\n\n\t* process.c (proc_wait2): new method.\n\n\t* process.c (proc_waitpid): second argument made optional.\n\n\t* process.c (proc_waitpid2): new method.\n\nSat Jun 17 00:05:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_clone): should initialize member fields.\n\nFri Jun 16 22:49:34 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_rewind): set lineno to zero.\n\nFri Jun 16 22:47:47 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.23.\n\n\t* lib/net/protocol.rb: too many CRLF in last line.\n\nFri Jun 16 21:23:59 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: add pause(2) checking.\n\n\t* eval.c: define pause() if missing.\n\nFri Jun 16 18:41:58 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* process.c (proc_setsid): BSD-style setpgrp() don't return\n\t  process group ID, but 0 or -1.\n\nFri Jun 16 16:23:35 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* file.c (rb_stat_inspect): gives detailed information;\n\t  compatibility with ruby-1.4.x.\n\nFri Jun 16 05:18:45 2000  Yasuhiro Fukuma  <yasuf@bsdclub.org>\n\n\t* configure.in: FreeBSD: do not link dummy libxpg4 which was\n\t  merged into libc.\n\nFri Jun 16 03:17:36 2000  Satoshi Nojo  <nojo@t-samukawa.or.jp>\n\n\t* ext/dbm/dbm.c (fdbm_length): use GetDBM. empty?, [] too.\n\n\t* ext/gdbm/gdbm.c (fgdbm_length): ditto.\n\n\t* ext/sdbm/init.c (fsdbm_length): ditto.\n\nFri Jun 16 01:57:31 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_sleep_forever): pause(2) instead of sleep(3).\n\nThu Jun 15 10:46:36 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_sub_bang): should propagate taintness from\n\t  replacement string.\n\nWed Jun 14 17:01:41 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* rubytest.rb: add CONFIG['EXEEXT'] to the executable file name.\n\nWed Jun 14 14:50:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_f_sub): assign to $_ only if modification happens.\n\n\t* string.c (rb_f_gsub): ditto.\n\n\t* string.c (rb_f_chop): ditto.\n\n\t* string.c (rb_f_chomp): ditto.\n\n\t* io.c (io_reopen): preserve file position by ftell/fseek, if io\n\t  is a seekable.\n\n\t* eval.c (method_arity): wrong arity number for the methods with\n\t  optional arguments.\n\n\t* time.c (make_time_t): opposite timezone shift (should be negative).\n\nWed Jun 14 14:07:38 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* io.c: typo(ig/if).\n\n\t* re.c: typo(re/reg). add rb_reg_check().\n\n\t* time.c: remove unneeded declare(daylight, timezone).\n\n\t* configure.in: add include <time.h> when daylight checking.\n\nWed Jun 14 11:36:52 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* marshal.c (r_object): modified for symbols.\n\n\t* marshal.c (w_object): ditto.\n\nWed Jun 14 10:04:58 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_memcmp): should compare according to ruby_ignorecase.\n\n\t* string.c (rb_str_cmp): use rb_memcmp.\n\n\t* string.c (rb_str_index): ditto.\n\n\t* string.c (rb_str_rindex): ditto.\n\n\t* string.c (rb_str_each_line): ditto.\n\nWed Jun 14 04:58:53 2000  Dave Thomas  <dave@thomases.com>\n\n\t* io.c (rb_io_set_lineno): should have returned VALUE, not\n\t  integer.\n\nWed Jun 14 09:29:42 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_dup): dup should always propagate taintness.\n\nWed Jun 14 00:50:14 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: read_multipart(): if no content body then raise EOFError.\n\nTue Jun 13 11:46:17 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* process.c (proc_setsid): try implement it using setpgrp() and\n\t  ioctl(fd, TIOCNOTTY, NULL).\n\n\t* re.c (rb_reg_prepare_re): magic variable $= should affect regex\n\t  pattern match.\n\n\t* time.c (make_time_t): use tm.tm_gmtoff if possible.\n\n\t* time.c (time_zone): use tm.tm_zone if available.\n\nTue Jun 13 01:50:57 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.22.\n\n\t* lib/net/http.rb: HTTPResponse#body returns body.\n\nMon Jun 12 23:41:54 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in (daylight): avoid GCC optimization.\n\nMon Jun 12 19:02:27 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: cygwin has strange timezone.\n\n\t* time.c (time_zone): use tzname and daylight.\n\nSat Jun 10 23:10:32 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_seek): whence is optional, default is SEEK_SET.\n\nFri Jun  9 17:00:29 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.21.\n\n\t* lib/net/http.rb: exception is raised with response object.\n\nFri Jun  9 15:11:35 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (make_time_t): supports daylight saving time.\n\n\t* eval.c (rb_thread_safe_level): should retrieve current $SAFE\n\t  value if a thread is the current thread.\n\nThu Jun  8 14:25:45 2000  Hiroshi Igarashi  <iga@ruby-lang.org>\n\n\t* lib/mkmf.rb: add target `distclean' in Makefile for extlib.\n\t  target `clean' doesn't remove Makefile.\n\nThu Jun  8 13:34:03 2000  Dave Thomas  <dave@thomases.com>\n\n\t* numeric.c: add nan?, infinite?, and finite? to Float\n\nThu Jun  8 00:31:04 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* regex.h: export re_mbctab properly on cygwin.\n\n\t* dln.c: use dlopen instead of LoadLibrary on cygwin.\n\nThu Jun  8 13:41:34 2000  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* file.c (rb_file_s_basename): might dump core.\n\nTue Jun  6 03:29:12 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (dir_foreach): now returns nil for consistency.\n\n\t* bignum.c (bigdivmod): modulo by small numbers was wrong.\n\nMon Jun  5 00:18:08 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* bignum.c: avoid conflict with USHORT on mingw32.\n\nMon Jun  5 00:13:35 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* eval.c (rb_thread_schedule): =/== typo.\n\nSun Jun  4 03:17:36 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: improve: CGI::pretty()\n\nSun Jun  4 02:01:10 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* lib/mkmf.rb: do not need to add -L$(topdir) in --enable-shared case.\n\nSat Jun  3 13:50:06 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (rb_id2name): should support constant attrset\n\t  identifiers.\n\n\t* bignum.c (rb_big_eq): Bignum#== should not raise exception.\n\nFri Jun  2 11:24:48 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_popen): open with a block returns the value from the\n\t  block.  old behavior was back.\n\nFri Jun  2 00:42:31 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\n\t* eval.c (rb_thread_cleanup): should clear priority for thread\n\t  termination.\n\nThu Jun  1 22:39:41 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.20.\n\n\t* lib/net/http.rb: wrongly closed the socket twice\n\t  when no Content-Length: was given.\n\nThu Jun  1 00:59:15 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_yield_0): convert Qundef to [].\n\nWed May 31 20:45:59 2000  Dave Thomas  <Dave@Thomases.com>\n\n\t* string.c (rb_str_slice_bang): wrong argument number.\n\nWed May 31 12:37:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_exec_end_proc): print error message from END procs.\n\nWed May 31 04:06:41 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: change: CGI#out() if \"HEAD\" == REQUEST_METHOD then\n\t  output only HTTP header.\n\nWed May 31 01:54:21 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_schedule): set main_thread->status to\n\t  THREAD_TO_KILL, before raising deadlock error.\n\n\t* eval.c (rb_thread_deadlock): if curr_thread == main_thread, do\n\t  not call rb_thread_restore_context()\n\nTue May 30 23:33:41 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* lib/mkmf.rb (create_makefile): add $(TARGET).ilk and *.pdb\n\t  to cleanup files for mswin32.\n\nMon May 29 10:41:10 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (rb_file_s_basename): should propagate taintness.\n\nSun May 28 21:37:13 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* eval.c: bug fix: DLEXT2.\n\nSun May 28 19:21:43 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* win32/win32.c: use ruby's glob.\n\n\t* dir.c: \"glob\" exported and renamed to \"rb_glob\".\n\n\t* ruby.h: ditto.\n\n\t* main.c: turn off command line mingw32's globbing.\n\nWed May 25 22:25:13 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/extmk.rb.in: use \"ftools\" instead of \"rm -f\".\n\n\t* lib/mkmf.rb: ditto.\n\nThu May 25 22:01:32 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* defines.h: mswin32: remove obsolete USHORT definition.\n\n\t* re.h: mswin32: use EXTERN instead of extern.\n\n\t* regex.h: mswin32: export re_mbctab properly.\n\n\t* win32/ruby.def: add ruby_ignorecase and regex.c's exports.\n\nThu May 25 21:28:44 2000  Minero Aoki <aamine@dp.u-netsurf.ne.jp>\n\n\t* re.c (rb_reg_expr_str): escape un-printable character.\n\nThu May 25 01:35:15 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (tokadd_escape): forgot to add `\\x' to hexadecimal\n\t  escape sequences.\n\n\t* object.c (rb_obj_dup): dup for normal object (T_OBJECT) copies\n\t  instance variables only.\n\nWed May 24 23:49:47 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (rb_mod_initialize): should provide initialize.\n\nWed May 24 23:17:50 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/Makefile: remove unnecessary mv and rm command call.\n\nWed May 24 21:01:04 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/pty/pty.c: use \"\" instead of <> to include ruby.h and rubyio.h\n\t  for BeOS (PowerPC).\n\n\t* file.c (rb_find_file): should check dln_find_file() result.\n\n\t* win32/ruby.def: add rb_block_given_p.\n\nWed May 24 16:32:45 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_popen): popen does not take 3rd argument anymore.\n\n\t* re.c (rb_reg_desc): re may be zero, check before dereferencing.\n\nWed May 24 16:03:06 2000  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/cgi.rb: bug fix: CGI::escape(), CGI::Cookie::new()\n\n\t* lib/net/telnet.rb: improve: binmode(), telnetmode() interface\n\nWed May 24 13:12:31 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* misc/ruby-mode.el (ruby-parse-region): support `while .. do'\n\t  etc. But corresponding keywords must be at the beginning of\n\t  line.\n\nTue May 23 23:50:12 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_initialize_m): wrong kcode value.\n\n\t* re.c (rb_reg_s_new): forgot to initialize re->ptr.\n\nTue May 23 08:36:24 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): forgot to restore old option\n\t  status by (?ix-ix).\n\n\t* regex.c (re_compile_fastmap): anychar may match newline if\n\t  RE_OPTION_MULTILINE or RE_OPTION_POSIXLINE is set.\n\nMon May 22 22:45:06 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.19.\n\n\t* lib/net/http.rb: do not use Regexp \"p\" option.\n\nMon May 22 21:56:43 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* struct.c (rb_struct_getmember): should use ID2SYM, not INT2NUM.\n\nMon May 22 15:07:37 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (rb_find_file): should check if the file really exists.\n\nMon May 22 09:08:12 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_popen): _exit(0) after processing block under the\n\t  child process.\n\n\t* io.c (rb_io_popen): flush stdout/stderr before subprocess\n\t  termination.\n\n\t* eval.c (rb_check_safe_str): insert rb_secure(4); operation\n\t  requires untainted string should be prohibited in level 4.\n\nSun May 21 21:17:00 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: add Setup.dj for djgpp cross-compiling.\n\n\t* Setup.dj: add readline.\n\n\t* instruby.rb: copy win32/win32.h to archlibdir on mingw32.\n\nSun May 21 20:58:08 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* pack.c: fix OFF16 and OFF32 definitions for Alpha and IRIX64.\n\nSun May 21 17:31:37 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* instruby.rb: support \"make install\" for cross-compiling.\n\n\t* ext/extmk.rb.in: ditto.\n\nSun May 21 14:22:49 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* Makefile.in: rename prep.rb to fake.rb.\n\n\t* configure.in: ditto.\n\nSat May 20 23:29:14 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (dir_s_new): does not take block; \"open\" does.\n\n\t* io.c (rb_io_s_new): ditto.\n\nFri May 19 07:44:26 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (dir_s_open): Dir#open does not returns closed Dir if a\n\t  block is given to the method.\n\n\t* re.c (rb_reg_initialize_m): Regexp::new calls initialize now.\n\n\t* string.c (Init_String): String#delete_at removed.\n\n\t* string.c (rb_str_aset_m): should have checked argc != 2.\n\n\t* eval.c (rb_thread_schedule): select(2) was called too many.\n\n\t* regex.c (re_compile_pattern): a bug in (?m) support.  Pointed\n\t  out by Dave Thomas <Dave@thomases.com>.\n\nThu May 18 23:55:26 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* dln.c (search_undef): st_lookup()'s 3rd parameter should be\n\t  a pointer of the variable which has the same size and alignment\n\t  as `char *'.\n\n\t* marshal.c (w_symbol, w_object): ditto.\n\n\t* parse.y (rb_intern): ditto.\n\nThu May 18 18:00:35 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.18.\n\n\t* lib/net/protocol.rb: Net::Version was removed.\n\n\t* lib/net/smtp.rb: use Socket.gethostname to get local host name.\n\nThu May 18 13:34:57 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (ruby_connect): should not have replaced\n\t  thread_write_select() by rb_thread_fd_writable().\n\nThu May 18 09:01:25 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* configure.in, ext/extmk.rb.in, lib/mkmf.rb: remove BeOS R3 support.\n\t  Make a shared library (libruby.so) only if the --enable-shared\n\t  option is specified.\n\n\t* instruby.rb: no longer use libruby.so.LIB and import.h.\n\n\t* io.c: fix READ_DATA_PENDING definition for BeOS (PowerPC).\n\nWed May 17 14:14:23 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_new_1): use /m instead of /p.\n\nWed May 17 02:22:03 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_polling): wait 0.06 second to let other\n\t  processes run.\n\n\t* process.c (rb_waitpid): avoid busy wait using rb_thread_polling.\n\n\t* file.c (rb_thread_flock): ditto.\n\n\t* parse.y (expr): avoid calling value_expr() twice.\n\nWed May 17 00:45:57 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* io.c (rb_io_binmode): should check PLATFORMs, not O_BINARY, sigh...\n\nWed May 17 00:40:15 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/config.h: add DLEXT2, now DLEXT on mswin32 is \"so\".\n\n\t* win32/config.status: ditto.\n\n\t* win32/ruby.def: add symbol \"rb_big_divmod\".\n\nTue May 16 19:45:32 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* intern.h: use EXTERN instead of extern.\n\n\t* win32/ruby.def: add rb_defout, rb_stdout, ruby_errinfo,\n\t  ruby_sourceline, ruby_sourcefile to work with eruby\n\t  reported by Hiroshi Saito <HiroshiSaito@pob.org>.\n\t  Export both ruby_xmalloc and xmalloc etc.\n\nTue May 16 17:00:05 2000  Masaki Fukushima  <fukusima@goto.info.waseda.ac.jp>\n\n\t* eval.c (rb_thread_select): should check whether fds are null.\n\nTue May 16 11:51:31 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (pipe_open): synchronize subprocess stdout/stderr.\n\nMon May 15 15:38:09 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.h: exported symbols should be for xmalloc etc. are now\n\t  prefixed by 'ruby_', e.g. ruby_xmalloc().\n\n\t* eval.c (rb_thread_select): remove busy wait for select.\n\n\t* dir.c (glob): trailing path may be null, e.g. glob(\"**\").\n\nMon May 15 14:48:41 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* io.c (rb_io_pid): new method; returns nil if no process attached\n\t  to the IO.\n\nMon May 15 01:18:20 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_s_popen): _exit after Proc execution.\n\nSun May 14 18:05:59 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* Makefile.in: missing/nt.c -> win32/win32.c\n\n\t* configure.in: bug fix; static linking on mingw32.\n\n\t* cygwin/GNUmakefile.in: remove VPATH.\n\n\t* ext/extmk.rb.in: Makefile set binmode with mingw32 on cygwin32.\n\n\t* lib/mkmf.rb: ditto.\n\n\t* win32/config.h: undef HAVE_SYS_FILE_H.\n\nSun May 14 02:02:48 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* lib/irb/ruby-lex.rb: '/' should be escaped in character class.\n\nSun May 14 00:54:43 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in, ...: support mingw32.\n\n\t* defines.h: ditto. undef EXTERN for tcl/tk on cygwin.\n\n\t* ext/*/extconf.rb: replace PLATFORM with RUBY_PLATFORM.\n\n\t* ext/socket/sockport.h: define IN_MULTICAST for missing IN_MULTICAST.\n\n\t* ext/tcltklib/tcltklib.c: remove declaration of rb_argv0.\n\n\t* file.c: should check S_IXGRP, S_ISGID, not NT.\n\n\t* io.c (rb_io_binmode): should check _IOBIN, O_BINARY, not PLATFORMs.\n\nSat May 13 14:21:15 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* io.c (rb_io_s_popen): should check whether a block is given.\n\nFri May 12 17:33:44 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): charset_not should not exclude\n\t  newline from matching set.\n\nThu May 11 22:51:05 2000  Ryunosuke Ohshima  <ryu@jaist.ac.jp>\n\n\t* pack.c (pack_pack): Bignum support.\n\n\t* pack.c (pack_unpack): ditto.\n\nThu May 11 21:19:29 2000  Hiroshi Igarashi  <iga@ruby-lang.org>\n\n\t* intern.h: add missing declarations of ruby API functions.\n\n\t* ruby.h: fix function name in declarations.\n\nThu May 11 22:29:25 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/md5/depend: add $(topdir)/config.h dependency to md5c.o.\n\n\t* ext/md5/extconf.rb: new file to add -DHAVE_CONFIG_H flag for Alpha.\n\nThu May 11 10:55:52 2000  Ryunosuke Ohshima  <ryu@jaist.ac.jp>\n\n\t* pack.c (pack_pack): packing BER compressed integer by `w'.\n\n\t* pack.c (pack_unpack): unpacking BER.\n\nThu May 11 00:37:55 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (parse_regx): remove in_brack.\n\nWed May 10 12:51:18 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (proc_options): move adding RUBYLIB and \".\" to the load\n\t  path after #! line parsing.\n\n\t* parse.y (parse_regx): should parse backslash escape like `\\c['\n\t  here to avoid causing `unterminated regexp' error.\n\nWed May 10 00:19:53 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* MANIFEST, beos/GNUmakefile.in, configure.in: no longer need\n\t  beos/GNUmakefile.in to support BeOS R4.5.2 (Intel) as a result\n\t  of eban's Makefile.in change.\n\n\t* io.c: NOFILE is already defined on BeOS R4.5 (Intel) or later.\n\n\t* lib/matrix.rb: remove debug print.\n\n\t* regex.c: don't use nested comment.\n\nTue May  9 17:08:43 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (massign): no longer convert nil into empty array.\n\n\t* io.c (rb_io_s_popen): optional 3rd argument to give proc, which\n\t  will be executed in spawned child process.\n\nMon May  8 23:47:39 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* eval.c (rb_callcc): prev & next should be initialized to zero.\n\nMon May  8 23:17:36 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dln.c (dln_init): remove possible buffer overrun.  This is\n\t  suggested by Aleksi Niemela <aleksi.niemela@cinnober.com>.\n\n\t* dln.c (init_funcname): ditto.\n\nSat May  6 23:35:47 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (lhs): should allow `obj.Attr = 5' type expression.\n\nSat May  6 15:46:08 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/socket/extconf.rb: add a new configure option to force use\n\t  of the WIDE Project's getaddrinfo(): --enbale-wide-getaddrinfo.\n\nFri May  5 21:19:22 2000  MOROHOSHI Akihiko  <moro@remus.dti.ne.jp>\n\n\t* parse.y (yylex): allow '$1foo' and such.\n\nFri May  5 17:57:24 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.17.\n\n\t* lib/net/http.rb: write also port number in Host: field.\n\n\t* lib/net/http.rb: see Proxy-Connection: to decide socket connection.\n\nFri May  5 03:25:15 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_fastmap): charset_not for multibyte\n\t  characters excluded too many characters.\n\nTue May  2 13:23:43 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_schedule): little bit more impartial context\n\t  switching.\n\nTue May  2 09:50:03 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* configure.in: add DLDLIBS to set platform specific library\n\t  for extensions.\n\n\t* ext/extmk.rb.in: use @DLDLIBS@ instead of RUBY_PLATFORM choice.\n\n\t* lib/mkmf.rb: use CONFIG[\"DLDLIBS\"] instead of RUBY_PLATFORM choice.\n\n\t* config_s.dj: add @DLDLIBS@.\n\n\t* win32/config.status: ditto.\n\n\t* win32/ruby.def: regular maintenance.\n\nMon May  1 23:42:44 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in, eval.c: add DLEXT2. now DLEXT on Cygwin is \"so\".\n\n\t* defines.h: use dllimport, dllexport for Cygwin 1.1.x.\n\n\t* ruby.h: ditto.\n\n\t* cygwin/GNUmakefile.in: ditto.\n\n\t* ext/Win32API/Win32API.c: directly \"call\" in asm statement for\n\t  gcc 2.95.x or newer.\n\nSat Apr 29 04:58:12 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* array.c (rb_ary_unshift_m): performance improvement.\n\nFri Apr 28 00:19:22 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* array.c (rb_ary_unshift_m): takes items to push.\n\nWed Apr 26 15:23:02 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_succ): insert carrying character just before\n\t  the leftmost alpha numeric character.\n\n\t* string.c (rb_str_succ): proper behavior for \"\".succ and \"\\377\".succ.\n\n\t* string.c (rb_str_succ): use realloc and memmove.\n\nTue Apr 25 18:28:45 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.16.\n\n\t* lib/net/smtp.rb: add SMTP AUTH\n\nTue Apr 25 14:30:13 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_gets_internal): shortcut when rs == rb_default_rs.\n\nSat Apr 22 23:14:41 2000  SHIROYAMA Takayuki  <psi@fortune.nest.or.jp>\n\n\t* configure.in: MacOS X support.\n\nSat Apr 22 16:37:10 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.15.\n\n\t* lib/net/http.rb:  closing socket by watching both\n\t  user header and server response\n\nFri Apr 21 21:44:34 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* io.c (rb_io_s_pipe): should set FMODE_SYNC.\n\nThu Apr 20 16:59:22 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (massign): `*lvalue = false' should assign `[false]' to\n\t  lvalue.\n\nWed Apr 19 08:35:08 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (rb_singleton_class): generate singleton class for\n\t  special constants: nil, true, false.\n\nWed Apr 19 02:09:30 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (rb_singleton_class): singleton method for nil, true,\n\t  false is possible now.\n\n\t* eval.c (rb_eval): ditto.\n\nTue Apr 18 18:54:25 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.14.\n\n\t* lib/net/http.rb: new method HTTP#head2.\n\n\t* lib/net/http.rb: get2/post2 does not raise exceptions.\n\nMon Apr 17 15:16:31 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_close): to detect some exceptional status, writable\n\t  IO should be flushed before close;\n\nSat Apr 15 18:29:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_collect_bang): Array#filter renamed.\n\nFri Apr 14 19:47:11 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.13.\n\n\t* lib/net/pop.rb: accept illegal timestamp\n\n\t* lib/net/http.rb: when body was chunked, does not set Content-Length:\n\nTue Apr 11 21:14:42 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* config_s.dj: add @sitedir@.\n\t* configure.in: add --with-sitedir=DIR option.\n\t* instruby.rb: use CONFIG[\"sitedir\"].\n\t* lib/mkmf.rb: support 'make site-install'.\n\t* win32/config.status: add @sitedir@.\n\nTue Apr 11 16:25:15 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (rb_big_2comp): unnecessary lvalue cast removed.\n\nTue Apr 11 02:25:53 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (env_fetch): new method.\n\n\t* marshal.c (marshal_dump): accepts depth = nil for unlimited depth.\n\nSun Apr  9 20:49:19 2000  Dave Thomas  <Dave@Thomases.com>\n\n\t* parse.y (str_extend): Allow class variables to be expanded.\n\nFri Apr  7 02:03:54 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* error.c (rb_sys_fail): escape non-printable characters.\n\nThu Apr  6 20:10:47 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/extmk.rb.in (create_makefile): BeOS --program-suffix support.\n\t* lib/mkmf.rb (create_makefile): ditto.\n\nThu Apr  6 09:55:26 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* error.c (rb_sys_fail): need rb_exc_new2() call on BeOS.\n\nMon Apr  3 17:22:27 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_reopen): support tempfile.\n\n\t* eval.c (catch_i): should supply argument.\n\nSat Apr  1 22:50:28 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (r_object): wrong symbol restoration.\n\nSat Apr  1 21:30:53 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* io.c (rb_io_printf, rb_f_printf): should use rb_io_write.\n\nSat Apr  1 00:16:05 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): should be clear flags\n\t  before calling finalizers.\n\n\t* eval.c (specific_eval): can be called without SecurityError, if\n\t  $SAFE >= 4.\n\n\t* object.c (sym_inspect): inspect gives \":sym\", to_s gives \"sym\".\n\nFri Mar 31 22:07:04 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.12.\n\n\t* lib/net/protocol.rb:  update Net::Protocol::Proxy#connect\n\n\t* lib/net/protocol.rb:  ReplyCode is not a class\n\n\t* lib/net/http.rb: header value format was change:\n\t  values do not include header name\n\n\t* lib/net/http.rb: header is not a Hash, but HTTPResponse\n\nThu Mar 30 12:19:44 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* enum.c (enum_find): rb_eval_cmd() should be called with array.\n\nTue Mar 28 13:57:05 2000  Clemens Hintze  <c.hintze@gmx.net>\n\n\t* ext/dbm/dbm.c (fdbm_invert): should return new hash.\n\n\t* ext/gdbm/gdbm.c (fgdbm_invert): ditto.\n\nTue Mar 28 00:58:03 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.11.\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: does not\n\t  dispatch any commands while dispatching command.\n\n\t* lib/net/protocol.rb: failed to get error class of\n\t  inherited ReplyCode\n\n\t* lib/net/http.rb: change feature of \"get2\", \"post2\"\n\nMon Mar 27 01:34:58 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.10.\n\n\t* lib/net/http.rb: return value of 'head' was wrong.\n\nSun Mar 26 17:47:35 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.9.\n\n\t* lib/net/smtp.rb: SMTP#do_ready wrongly took no arguments\n\nSat Mar 25 23:21:10 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (w_object): symbols should be converted to ID before\n\t  dumping out.\n\nFri Mar 24 18:26:51 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (test_check): should have checked exact number of arguments.\n\nFri Mar 24 21:02:11 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* signal.c (trap): should treat some symbols as the signal.\n\nFri Mar 24 06:58:03 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.8.\n\n\t* lib/net/http.rb:  post, get2, post2, get_body\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: separate\n\t  Command/Socket documentation.\n\nThu Mar 23 02:26:14 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_fptr_finalize): fptr may be null.\n\n\t* io.c (rb_io_s_new): now calls `initialize'.\n\n\t* io.c (rb_io_initialize): actual open done in this method.\n\n\t* io.c (rb_file_initialize): ditto.\n\n\t* eval.c (rb_eval): class variables in singleton class definition\n\t  is now handled properly (I hope).\n\nWed Mar 22 21:49:36 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* st.c (st_delete_safe): skip already deleted entry.\n\n\t* hash.c (rb_hash_delete): modify brace miss.\n\nWed Mar 22 08:53:58 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (exec_under): do not push cbase if ruby_cbase == under.\n\n\t* node.h (NEW_CREF0): preserve cbase nesting.\n\nTue Mar 21 12:57:50 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (rb_class_s_new): Class::new should call `inherited'.\n\nSat Mar 18 12:36:09 2000  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* eval.c (rb_backtrace, make_backtrace): removed unused variable\n\t  `lev'.\n\n\t* eval.c (rb_attr): calls `method_added' at attribute definition.\n\n\t* eval.c (rb_mod_modfunc): calls `singleton_method_added' while\n\t  `module_function'.\n\n\t* eval.c (rb_eval): parameter to `method_added' and\n\t  `singleton_method_added' is Symbol.\n\n\t* eval.c (Init_eval): caches IDs for `method_added' and\n\t  `singleton_method_added'.\n\nSat Mar 18 11:25:10 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (rescue): allows `rescue Error in foo'.  experimental.\n\t  which is better this or preparing alias `exception' for `$!'?\n\nFri Mar 17 15:02:45 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_autoload_id): defining new autoload should be\n\t  prohibited for $SAFE > 4.\n\n\t* variable.c (rb_autoload_load): autoload should be possible for\n\t  $SAFE > 4.\n\n\t* eval.c (call_trace_func): should handle T_ICLASS properly.\n\nFri Mar 17 14:34:30 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_gsub): forgot to initialize str->orig.\n\nFri Mar 17 01:24:59 2000  Dave Thomas  <Dave@thomases.com>\n\n\t* string.c (rb_str_clone): forgot to copy str->orig if STR_NO_ORIG\n\t  is set by Array#pack.\n\nWed Mar 15 21:25:04 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* array.c (rb_ary_join): 'result' is always duplicated\n\t  before concat string.\n\nWed Mar 15 17:26:05 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_hash_s_create): unexpected recursive call removed.\n\t  this bug was found by Satoshi Nojo <nojo@t-samukawa.or.jp>.\n\nWed Mar 15 13:12:39 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (Init_Thread): Thread.join removed finally.\n\n\t* string.c (rb_str_chomp_bang): forgot to call rb_str_modify().\n\nMon Mar 13 16:12:13 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (block_pass): distinguish real orphan block and still\n\t  on-stack block passed by block argument.\n\nMon Mar 13 00:20:25 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (f_norm_arg): proper error message when constant comes\n\t  in formal argument list.  this message is suggested by Muvaw\n\t  Pnazte <bugathlon@yahoo.com>.\n\n\t* eval.c (rb_f_raise): proper error message when the first\n\t  argument is not an exception class/object.\n\n\t* string.c (rb_str_dup): dup now postpone buffer copy as long as\n\t  possible.  performance improved by lazy copying.\n\nSun Mar 12 13:58:52 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* signal.c (rb_f_kill): should treat some symbols as the signal.\n\nSat Mar 11 22:03:03 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_gsub): performance tune by avoiding buffer copy.\n\n\t* eval.c (rb_f_missing): check if argv[0] is ID.\n\nSat Mar 11 15:49:41 2000  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* struct.c (rb_struct_aref): struct aref by symbol.\n\nSat Mar 11 05:07:11 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* process.c (proc_setpriority): should return 0, not nil.\n\n\t* process.c (proc_setpgid): ditto.\n\nFri Mar 10 18:14:54 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (path_check_1): confusing buf and path.  this bug found\n\t  by <decoux@moulon.inra.fr>.\n\nFri Mar 10 09:37:49 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* MANIFEST: add beos/GNUmakefile.in.\n\t* configure.in: support BeOS R4.5.2 (Intel).\n\t* beos/GNUmakefile.in: new file to support BeOS R4.5.2 (Intel).\n\nThu Mar  9 11:13:32 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_fastmap): fixed embarrassing brace bug.\n\nThu Mar  9 01:36:32 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* missing/flock.c: emulate missing flock() with fcntl().\n\nThu Mar  9 00:29:35 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (sym_to_s): returns \":sym\".\n\n\t* object.c (sym_id2name): separated from to_s; returns \"sym\".\n\nWed Mar  8 19:16:19 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.7.\n\n\t* lib/net/http.rb (connecting): returns header\n\nWed Mar  8 02:08:43 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y: escape expansion too early.\n\n\t* string.c (rb_f_scan): Kernel#scan added.\n\n\t* regex.c (re_compile_pattern): support \\cX et al.\n\nTue Mar  7 01:44:27 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (set_stdin): simplified procedure, allows $stdin = DATA;\n\t  experimental.\n\n\t* io.c (set_outfile): ditto.\n\n\t* re.c (Init_Regexp): new method Regexp#last_match added; it's an\n\t  alternative for $~.\n\n\t* configure.in (DEFAULT_KCODE): KCODE_NONE should be the default.\n\n\t* dir.c (dir_s_rmdir): should return 0 on success.\n\n\t* signal.c: remove CWGUSI support.\n\nMon Mar  6 12:28:37 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (w_symbol): support symbol object.\n\n\t* util.c: make symbol as separated class.\n\n\t* error.c (Init_Exception): new exception RangeError.\n\n\t* ext/socket/socket.c (ip_addrsetup): should check length of hostname.\n\n\t* ext/socket/socket.c (ip_addrsetup): check newline at the end of\n\t  hostname.  These fixes suggested by Muvaw Pnazte <bugathlon@yahoo.com>.\n\nSun Mar  5 20:35:45 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): should call\n\t  LoadLibrary() everytime and should assign the hdll to Win32API\n\t  object(protect the hdll from GC).\n\nSun Mar  5 18:49:06 2000  Nakada.Nobuyoshi  <nobu.nokada@softhome.net>\n\n\t* misc/ruby-mode.el (ruby-parse-region): not treat method `begin'\n\t  and `end' as reserved words.\n\n\t* misc/ruby-mode.el (ruby-font-lock-docs): ignore after `=begin'\n\t  and `=end'.\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords, hilit-set-mode-patterns):\n\t  added `yield' to keywords.\n\n\t* misc/ruby-mode.el (ruby-font-lock-keywords, hilit-set-mode-patterns):\n\t  matches keywords at end of buffer.\n\nSun Mar  5 18:08:53 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.6.\n\n\t* lib/net/http.rb:  allow to omit 'start'\n\nTue Feb 29 01:08:26 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* range.c (range_initialize): initialization done in `initialize';\n\t  `initialize' should not be called more than once.\n\n\t* object.c (Init_Object): default `initialize' should take zero\n\t  argument.\n\n\t* time.c (time_s_new): call `initialize' in Time::new.\n\nSat Feb 26 22:39:31 2000  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* string.c (rb_str_times): fix String#* with huge string.\n\nSat Feb 26 00:14:59 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (dir_s_new): call `initialize' in Dir::new.\n\nFri Feb 25 23:01:49 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ruby.h: export ruby_safe_level by EXTERN for mswin32.\n\t* win32/ruby.def: regular maintenance.\n\nFri Feb 25 22:12:46 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_reopen): IO#reopen should accept path as well.\n\n\t* string.c (rb_str_s_new): call `initialize' in String::new.\n\n\t* hash.c (rb_hash_s_new): call `initialize' in Hash::new.\n\n\t* array.c (rb_ary_s_new): call `initialize' in Array::new.\n\nFri Feb 25 12:50:20 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_start_timer): interval changed to 10ms from 50ms.\n\nFri Feb 25 06:42:26 2000  GOTOU Yuuzou  <gotoyuzo@notwork.org>\n\n\t* ext/socket/socket.c (ip_addrsetup): hostp should remain NULL if\n\t  host is nil.\n\nThu Feb 24 16:53:47 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_schedule): priority check for sleep expired\n\t  threads needed.\n\nWed Feb 23 14:22:32 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_join): forgot to initialize a local variable\n\t  `taint'.\n\nTue Feb 22 07:40:55 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (Init_Regexp): renamed to MatchData, old name MatchingData\n\t  remain as alias.\n\nTue Feb 22 00:20:21 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/protocol.rb, smtp.rb, pop.rb, http.rb: 1.1.5.\n\n\t* lib/net/session.rb: rename to protocol.rb\n\n\t* lib/net/protocol.rb: ProtocolSocket -> Net::Socket\n\n\t* lib/net/protocol.rb: Net::Socket#write, write_pendstr\n\t  can take block\n\n\t* lib/net/smtp.rb: new methods SMTP#ready SMTPCommand#write_mail\n\n\t* lib/net/pop.rb: POPMail#pop can take block\n\nSat Feb 19 23:58:51 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): pop_loop should not pop at forward jump.\n\nFri Feb 18 17:15:40 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (method_clone): method objects are now clonable.\n\nFri Feb 18 00:27:34 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_shared_variable_declare): shared variable (aka\n\t  class/module variable) introduced.  prefix `@@'. experimental.\n\n\t* class.c (rb_scan_args): new format char '&'.\n\nThu Feb 17 19:09:05 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/win32.c (mypopen): don't close handle if it is not assigned.\n\t* win32/win32.c (my_open_osfhandle): support O_NOINHERIT flag.\n\t* win32/win32.c (win32_getcwd): rename getcwd to win32_getcwd\n\t  in order to avoid using the C/C++ runtime DLL's getcwd.\n\t  Use CharNext() to process directory name.\n\t* win32/win32.h: map getcwd to win32_getcwd.\n\nWed Feb 16 00:32:49 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (method_arity): nd_rest is -1 for no rest argument.\n\n\t* process.c (proc_waitpid): returns nil when waitpid(2) returns 0.\n\nTue Feb 15 01:47:00 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* process.c (rb_f_waitpid): pid_t should be signed.\n\nMon Feb 14 13:59:01 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): yylex yields wrong tokens for `:foo=~expr'.\n\n\t* ruby.c (load_file): exit if reading file is empty.\n\nMon Feb 14 03:34:52 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): `foo.bar=1' should be <foo><.><bar><=><1>,\n\t  not <foo><.><bar=><1>.\n\n\t* eval.c (rb_thread_restore_context): process according to\n\t  RESTORE_* is moved after longjmp().\n\n\t* eval.c (thread_switch): new function to process RESTORE_*.\n\nSun Feb 13 16:19:49 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ruby.c (require_libraries): don't access freed memory.\n\n\t* ruby.c (add_modules): ditto.\n\nFri Feb 11 12:06:22 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (parse_quotedwords): %w() need to split not only by mere\n\t  spaces, but by all whitespaces.\n\nThu Feb 10 02:12:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_index_m): did not support negative offset.\n\nWed Feb  9 21:54:26 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/getaddrinfo.c: gcc --traditional support.\n\t  Rearrange headers to work AC_C_CONST.\n\t* ext/socket/getnameinfo.c: ditto.\n\t* ext/socket/socket.c: mswin32: use double instead of long long.\n\nWed Feb  9 16:30:41 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (num_coerce): should return [y, x].\n\nWed Feb  9 11:07:30 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (ruby_prog_init): loadpath structure changed.\n\nTue Feb  8 02:07:33 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): optimize for \\G at top.\n\n\t* regex.c (re_compile_pattern): \\G introduced.\n\n\t* regex.c (re_match): ditto.\n\n\t* string.c (str_sub_bang): old behavior restored: bang method\n\t  returns nil if string not changed.\n\n\t* regex.c (re_compile_pattern): support independent subexpression\n\t  `(?>pattern)'.\n\n\t* regex.c (re_match): ditto.\n\nMon Feb  7 15:51:08 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): now understands interrupts under Ruby.\n\nMon Feb  7 07:51:52 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_uniq_bang): always return an Array.\n\n\t* array.c (rb_ary_compact_bang): ditto.\n\n\t* array.c (rb_ary_flatten_bang): ditto.\n\n\t* hash.c (rb_hash_reject): returns a Hash, not an Array.\n\n\t* hash.c (env_reject): ditto.\n\nFri Feb  4 10:20:25 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (scan_once): scan now leaves information about the last\n\t  successful pattern match in $&.\n\n\t* io.c (rb_io_close): should not check closed IO.\n\nFri Feb  4 05:44:01 2000  Kentaro Inagaki  <inagaki@tg.rim.or.jp>\n\n\t* ext/socket/socket.c (s_recv): TRAP_BEG after retry entry.\n\nWed Feb  2 22:33:45 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (rb_thread_start): receives argument from outside, like\n\t  `Thread::start(1,2,3){|a,b,c| ... }'.\n\nWed Feb  2 22:14:40 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_regsub): should check regs->num_regs.\n\n\t* re.c (rb_reg_search): remove matchcache, use static struct\n\t  re_register instead.\n\n\t* re.c (match_getter): avoid cloning match data.\n\nWed Feb  2 17:12:15 2000  Dave Thomas  <Dave@Thomases.com>\n\n\t* samples/eval.rb: Rescue new ScriptError exception\n\nWed Feb  2 02:06:07 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_gsub_bang): gsub! now leaves information about the\n\t  last successful pattern match in $&.\n\nMon Jan 31 15:24:58 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_sub_bang): bang method returns string always.\n\t  experimental.\n\nSun Jan 30 17:58:09 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* eval.c: arrange to use setitimer(2) for BOW, DJGPP\n\n\t* defines.h: ditto. use random(3) on cygwin b20.1.\n\nSun Jan 30 17:20:16 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* eval.c: use getrlimit(2) on DJGPP.\n\nThu Jan 27 01:27:10 2000  GOTO Kentaro  <gotoken@math.sci.hokudai.ac.jp>\n\n\t* dir.c (glob): glob pattern \"/*\" did not match.\n\nWed Jan 26 22:30:47 2000  Shigeo Kobayashi  <shigeo@tinyforest.gr.jp>\n\n\t* numeric.c (flo_modulo): wrong result for negative modulo.\n\nWed Jan 26 02:01:57 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (test_c): should use S_ISCHR.\n\n\t* file.c (rb_stat_c): ditto.\n\n\t* string.c (rb_str_each_line): should propagate tainting.\n\nTue Jan 25 04:01:34 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (rb_obj_freeze): all objects made freezable.\n\nTue Jan 25 00:37:01 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: use AC_CHECK_TOOL for cross compiling.\n\nMon Jan 24 19:01:54 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* array.c (rb_protect_inspect): should be checked by id of\n\t  objects; not by object themselves.\n\nMon Jan 24 18:48:08 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* eval.c (rb_eval): too many warnings;  warned on every method\n\t  overriding.  should be on method discarding.\n\nMon Jan 24 02:56:44 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): -2.abs should be `(-2).abs' to accomplish the\n\t  principle of less surprise.  `+2' too.\n\n\t* eval.c (rb_eval): when defining class is already there, and\n\t  superclass differ, throw away the old class.\n\n\t* variable.c (rb_const_set): gives warning again on constant\n\t  redefinition.\n\n\t* error.c (Init_Exception): SyntaxError, NameError, LoadError and\n\t  NotImplementError are subclasses of ScriptError<Exception, not\n\t  StandardError.  experimental.\n\nSat Jan 22 00:00:41 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (parse_quotedwords): no longer use `String#split'.\n\t  and enable space escape within quoted word list.\n\t  e.g. %w(a\\ b\\ c abc) => [\"a b c\", \"abc\"].\n\n\t* string.c (rb_str_slice_bang): new method `slice!'.\n\nFri Jan 21 21:56:08 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb, http.rb: 1.1.4.\n\n\t* lib/net/http.rb: can receive messages which have\n\t  no Content-Length:.\n\nFri Jan 21 16:15:59 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thgroup_s_new): new class ThreadGroup.\n\nTue Jan 18 12:24:28 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* struct.c (Init_Struct): remove Struct's own hash and eql?.\n\nSat Jan 15 22:21:08 2000  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* eval.c (search_method): argument klass may be 0.\n\nSat Jan 15 15:03:46 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* enum.c (enum_index): remove this method.\n\n\t* enum.c: remove use of pointers to local variables. find,\n\t  find_all, min, max, index, member?, each_with_index,\n\n\t* eval.c (massign): multiple assignment does not use to_a anymore.\n\t  experimental.\n\nFri Jan 14 12:22:04 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_replace): use memmove instead of memcpy for\n\t  overwrapping strings (e.g. a[1] = a).\n\nThu Jan 13 11:12:40 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (arg_add): use new node, ARGSPUSH.\n\nMon Jan 10 18:32:28 2000  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* marshal.c (w_object): forgot an argument to call w_ivar().\n\nSun Jan  9 18:13:51 2000  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* random.c: first was not defined unless HAVE_RANDOM.\n\nSat Jan  8 19:02:49 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_sysread): raise IOError for buffered IO.\n\n\t* ext/socket/socket.c (s_recv): ditto.\n\nFri Jan  7 00:59:29 2000  Masahiro Tomita  <tommy@tmtm.org>\n\n\t* io.c (io_fread): TRAP_BEG/TRAP_END added around getc().\n\nThu Jan  6 00:39:54 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* random.c (rb_f_rand): should be initialized unless srand is\n\t  called before.\n\nWed Jan  5 16:59:34 2000  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb, http.rb: 1.1.3.\n\n\t* lib/net/session.rb: Session -> Protocol, ...\n\n\t* lib/net/http.rb: HTTPCommand implementation was changed.\n\nWed Jan  5 02:14:46 2000  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* parse.y: Fix SEGV on empty parens with UMINUS or UPLUS.\n\nTue Jan  4 22:25:54 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (stmt): `() while cond' dumped core.\n\nTue Jan  4 06:04:14 2000  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* configure.in: modify for cross-compiling.\n\t  use target_* instead of host_*.\n\t  use AC_CANONICAL_TARGET.\n\n\t* Makefile.in: ditto.\n\n\t* cygwin/GNUmakefile.in: ditto.\n\nSat Jan  1 13:26:14 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_yield_0): force_recycle ruby_dyna_vars to gain\n\t  performance.\n\n\t* array.c (rb_ary_delete_at_m): takes same argument pattern with\n\t  rb_ary_aref.\n\nSat Jan  1 10:12:26 2000  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ruby.h,util.c (rb_special_const_p): peep hole optimization.\n\n\t* ruby.h,util.c (rb_test_false_or_nil): removed.\n\n\t* ruby.h (RTEST, SPECIAL_CONST_P): peep hole optimization.\n\n\t* ruby.h (FL_ABLE, FL_SET, FL_UNSET, FL_REVERSE): made expressions\n\t  not statements.\n\n\t* ruby.h (OBJ_INFECT): newly added macro which copies taint from\n\t  `s' to `x'.\n\nSat Jan  1 02:04:18 2000  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_safe_level): new method.\n\n\t* eval.c (rb_yield_0): recycle dyna_var_map to reduce object\n\t  allocation.\n\nFri Dec 31 00:52:48 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c: thread independent trace_func not needed.\n\nThu Dec 30 14:47:31 1999  akira yamada  <akira@ruby-lang.org>\n\n\t* configure.in: specifies -soname in LIBRUBY_DLDFLAGS on linux\n\t  platforms.\n\nThu Dec 30 10:51:27 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c,io.c,hash,c,re.c,string.c: `_m' suffix instead of\n\t  `_method' for wrapper functions to implement method,\n\t  e.g. `rb_str_join_m()'.\n\nThu Dec 30 02:08:02 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (rb_cstr2inum): non-numeric format check added.\n\t  currently it works only with base == 0 (i.e. Integer()).\n\n\t* bignum.c (rb_str2inum): now takes VALUE to 1st argument.  null\n\t  byte check added.\n\n\t* array.c (rb_ary_replace): unless replacement is an array,\n\t  replacement shall be converted to array by `[replacement]', not\n\t  by `replacement.to_a'.\n\n\t* array.c (rb_ary_plus): right operand must be an array.\n\n\t* array.c (rb_ary_concat): argument must be an array.\n\nMon Dec 27 12:35:47 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/socket.c (sock_finalize): mswin32: fix socket handle leak.\n\n\t* win32/win32.c (myfdclose): ditto.\n\nSun Dec 26 23:15:13 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/win32.c (mypopen): raise catchable error instead of rb_fatal.\n\t* win32/win32.c (mypclose): fix process handle leak.\n\nSun Dec 26 16:17:11 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/Win32API/Win32API.c (Win32API_initialize): use UINT2NUM\n\t  instead of INT2NUM to set __dll__ and __proc__.\n\nSat Dec 25 00:08:59 1999  KANEKO Naoshi  <wbs01621@mail.wbs.ne.jp>\n\n\t* ext/Win32API/Win32API.c (Win32API_Call): remove 'dword ptr'\n\t  from _asm.\n\nFri Dec 24 10:26:47 1999  Koji Oda  <oda@bsd1.qnes.nec.co.jp>\n\n\t* win32/win32.h: use \"C++\" linkage.\n\nFri Dec 24 02:00:57 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (THREAD_ALLOC): should initialize th->trace.\n\nFri Dec 24 00:43:39 1999  KANEKO Naoshi  <wbs01621@mail.wbs.ne.jp>\n\n\t* io.c (pipe_open): check for `fptr->f == NULL'.\n\t* win32/win32.c (mypopen): STDERR does not work during ` function.\n\nWed Dec 22 22:50:40 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb, http.rb: 1.1.2.\n\n\t* lib/net/http.rb: HTTP support is enhanced a little\n\n\t* lib/net/http.rb: support proxy\n\nTue Dec 21 17:21:28 1999  Koji Oda  <oda@bsd1.qnes.nec.co.jp>\n\n\t* ext/socket/socket.c (sock_finalize): mswin32: fix FILE* leak.\n\nTue Dec 21 05:33:56 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb, http.rb: 1.1.1.\n\n\t* lib/net/http.rb: support HTTP chunk\n\nMon Dec 20 19:08:12 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (rb_file_s_expand_path): handle dir separator correctly.\n\nSun Dec 19 22:56:31 1999  KANEKO Naoshi  <wbs01621@mail.wbs.ne.jp>\n\n\t* lib/find.rb: support dosish root directory.\n\t* win32/Makefile: ditto.\n\t* win32/config.status: ditto.\n\t* win32/win32.c (opendir): ditto.\n\t* win32/win32.c (opendir): use CharPrev() to get last character\n\t  of the directory name.\n\nSat Dec 18 03:00:01 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (path_check_1): check should be done by absolute path.\n\n\t* marshal.c (r_ivar): should restore generic_ivar too.\n\n\t* marshal.c (w_ivar): should dump generic_ivar too.\n\nFri Dec 17 22:46:46 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb, http.rb: 1.1.0.\n\n\t* lib/net/http.rb: test release\n\n\t* lib/net/session.rb: support class swapping\n\n\t* lib/net/session.rb: Socket#flush_rbuf\n\n\t* lib/net/session.rb: doquote -> Net.quote\n\nFri Dec 17 19:27:43 1999  IWAMURO Motonori  <iwa@mmp.fujitsu.co.jp>\n\n\t* eval.c (rb_load): should initialize ruby_frame->last_class.\n\nWed Dec 15 01:35:29 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (proc_options): option to change directory changed to\n\t  `-C' like tar.\n\n\t* ruby.c (proc_options): argv boundary check for `-X'.\n\nMon Dec 13 15:15:31 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_adjust_startpos): separate startpos adjustment\n\t  because of major performance drawback.\n\n\t* class.c (rb_singleton_class): tainted status of the singleton\n\t  class must be synchronized with the object.\n\n\t* eval.c (rb_thread_schedule): implement thread priority.\n\nSat Dec 11 03:34:38 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (mark_hashentry): key should be VALUE, not ID.\n\n\t* io.c (argf_eof): should check next_p too.\n\nThu Dec  9 18:09:13 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* error.c (exc_set_backtrace): forgot to declare a VALUE argument.\n\nThu Dec  9 14:19:31 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (rb_obj_taint): explicit tainting must be prohibited at\n\t  level 4 to prevent polluting trusted object by untrusted code.\n\n\t* file.c: file operations (stat, lstat, chmod, chown, umask,\n\t  truncate, flock) are prohibited in level 2 (was level 4).\n\nWed Dec  8 11:48:23 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_f_require): prohibiting require() in the secure mode\n\t  cause serious autoloading error.\n\n\t* variable.c (rb_obj_instance_variables): don't need to prohibit\n\t  to get list of instance variable names of untainted objects.\n\n\t* variable.c (rb_ivar_get): don't need to prohibit to get instance\n\t  variables of untainted objects.\n\n\t* variable.c (rb_mod_remove_const): should prohibit constant\n\t  removals too.\n\nWed Dec  8 09:23:01 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): should try autoloading before defining\n\t  class/module at the toplevel.\n\nTue Dec  7 22:15:30 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* configure.in: Modified rb_cv_rshift_sign detect routine and\n\t  more simple/fast RSHIFT() for hpux-10.x.\n\nTue Dec  7 11:16:30 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (Init_eval): calculate stack limit from rlimit where\n\t  getrlimit(2) is available.\n\nTue Dec  7 09:57:33 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* file.c (rb_file_ftype): should have removed mode_t.\n\nMon Dec  6 15:55:30 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* numeric.c (fix_rshift): Fix -1 >> 32 returned 0 (should be -1).\n\n\t* numeric.c (fix_rshift): Fix  1 >> -1 returned 0 (should be 2).\n\nMon Dec  6 11:47:23 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (rb_f_sprintf): formatted string must be tainted if\n\t  any of parameters is a tainted string.\n\n\t* file.c (rb_file_s_expand_path): expanded file path need not to\n\t  be tainted always.\n\nSun Dec  5 20:25:29 1999  Katsuhiro Ueno  <unnie@blue.sky.or.jp>\n\n\t* eval.c (Init_Proc): simple typo.\n\n\t* gc.c (add_heap): sizeof(RVALUE*), not sizeof(RVALUE).\n\nSat Dec  4 01:40:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): adjust startpos for multibyte match unless\n\t  the first pattern is forced byte match.\n\n\t* bignum.c (rb_big_rand): should not use rand/random where drand48\n\t  may be available.  RANDOM_NUMBER should be provided from outside.\n\nFri Dec  3 09:54:59 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (moreswitches): there may be trailing garbage at #!\n\t  line.\n\n\t* eval.c (rb_f_require): should check require 'feature.o' too.\n\nThu Dec  2 11:58:15 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* eval.c (rb_thread_loading): should maintain loading_tbl.\n\nThu Dec  2 10:21:43 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_loading_done): wrong parameter to st_delete().\n\nWed Dec  1 11:24:06 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ruby.c (process_sflag): process -s properly (should not force `--').\n\nWed Dec  1 09:47:33 1999  Kazunori NISHI  <kazunori@swlab.csce.kyushu-u.ac.jp>\n\n\t* string.c (rb_str_split_method): should increment end too.\n\nTue Nov 30 18:00:45 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c: MARSHAL_MINOR incremented; format version is 4.2.\n\n\t* marshal.c (w_object): distinguish class and module.\n\n\t* marshal.c (w_object): save hash's default value.\n\n\t* marshal.c (r_object): restore hash's default value.\n\nTue Nov 30 01:46:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_source): generated source string must be tainted if\n\t  regex is tainted.\n\n\t* file.c (rb_file_s_basename): basename should not be tainted\n\t  unless the original path is tainted.\n\n\t* file.c (rb_file_s_dirname): ditto.\n\nMon Nov 29 20:42:13 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c (stat_new): Struct::Stat -> File::Stat; Stat is no longer\n\t  a Struct.\n\nMon Nov 29 15:28:52 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_path2class): evaluated value from path should be\n\t  module or class.\n\nFri Nov 26 18:12:49 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_exec_end_proc): should remove only end_procs defined\n\t  within load wrapper.\n\n\t* eval.c (rb_load): save and restore ruby_wrapper around loading.\n\n\t* eval.c (rb_mark_end_proc): mark end procs registered by END{} or\n\t  at_exit{}.\n\n\t* eval.c (rb_set_end_proc): should not call rb_global_variable()\n\t  on heap address;  it crashed mod_ruby.\n\nMon Nov 22 14:07:24 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ruby.c (proc_options): variable e_script should be visited by\n\t  garbage collector.\n\nSat Nov 20 10:10:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (inspect_i): value may be nil, check revised.\n\nFri Nov 19 18:06:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (glob): recursive wildcard match by `**' ala zsh.\n\nFri Nov 19 11:44:26 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* variable.c: was returning void value.\n\nFri Nov 19 03:57:22 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* file.c: add methods Stat struct class to reduce stat(2).\n\nThu Nov 18 16:18:27 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/pstore.rb: mutual lock by flock(2).\n\nThu Nov 18 11:44:13 1999  Masahiro Tomita  <tommy@tmtm.org>\n\n\t* io.c (read_all): should check bytes too.\n\nWed Nov 17 02:40:40 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (Init_IO): $defout (alias of $>) added.\n\nTue Nov 16 09:47:14 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/pstore.rb: add mutual lock using symlink.\n\nMon Nov 15 16:50:34 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* enum.c (enum_grep): non matching grep returns an empty array, no\n\t  longer returns nil.\n\n\t* enum.c (enum_grep): grep with block returns collection of\n\t  evaluated values of block over matched elements.\n\nMon Nov 15 04:50:33 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* re.c (rb_reg_source): should not call rb_reg_expr_str()\n\t  everytime.\n\nSat Nov 13 07:34:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_mod_constants): traverse superclasses to collect\n\t  constants.\n\n\t* eval.c (assign): modified for shared variables.\n\n\t* eval.c (rb_eval): search nested scope, then superclasses to\n\t  assign shared variables within methods.\n\n\t* eval.c (rb_eval): remove warnings from constants modification,\n\t  because they are no longer constants.\n\n\t* parse.y (node_assign): modified for shared variables.\n\n\t* parse.y (assignable): allow constant assignment in methods;\n\t  constants should be called `shared variable'.\n\nFri Nov 12 23:52:19 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* process.c (rb_f_system): argument check for NT, __EMX__, DJGPP.\n\nWed Nov 10 21:54:11 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* hash.c (rb_any_cmp): Fixed return without value.\n\nWed Nov 10 17:57:06 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c: incorporate <yasuf@big.or.jp>'s sprintf patch at\n\t  [ruby-dev:7754].\n\nWed Nov 10 08:28:53 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_call0): supply class parameter for each invocation.\n\nTue Nov  9 13:21:04 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* configure.in: AC_MINIX move to before AC_EXEEXT and AC_OBJEXT.\n\nMon Nov  8 19:52:29 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* configure.in: Renamed AC_CHAR_UNSIGNED to AC_C_CHAR_UNSIGNED.\n\n\t* configure.in: Added default to AC_CHECK_SIZEOF().\n\nMon Nov  8 14:28:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (stmt): rescue modifier added to the syntax.\n\n\t* keywords: kRESCUE_MOD added.\n\n\t* eval.c (rb_f_eval): fake outer scope when eval() called without\n\t  bindings.\n\n\t* eval.c (rb_f_binding): should copy last_class in the outer frame too.\n\nSun Nov  7 18:31:04 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* eval.c (is_defined): last_class may be 0.\n\nSat Nov  6 19:26:55 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* Makefile.in: Added depend entry make parse.@OBJEXT@ from parse.c\n\t  for UCB make\n\nThu Nov  4 17:41:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): \\< (wordbeg), \\> (wordend) disabled.\n\nWed Nov  3 08:52:57 1999  Masaki Fukushima  <fukusima@goto.info.waseda.ac.jp>\n\n\t* io.c (Init_IO): forgot to use INT2FIX() around SEEK_SET, etc.\n\nWed Nov  3 00:25:20 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_split_method): use mbclen2() to handle kcode\n\t  option of regexp objects.\n\nMon Nov  1 14:22:15 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* eval.c (rb_eval): reduce recursive calls to rb_eval()\n\t  case of ||= and &&= .\n\nSun Oct 31 13:12:42 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* regex.c (re_compile_pattern): wrong [\\W] match.\n\nFri Oct 29 16:57:30 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/nkf/lib/kconv.rb: new String methods (kconv, tojis, toeuc,\n\t  tosjis).\n\n\t* time.c (time_s_at): now accepts optional second argument to\n\t  specify micro second.\n\nThu Oct 28 13:35:40 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_split_method): should be mbchar aware with\n\t  single char separators.\n\nWed Oct 27 12:57:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* random.c (rb_f_srand): random seed should be unsigned.\n\nTue Oct 26 23:58:15 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_collect): collect for better performance.\n\nTue Oct 26 19:20:54 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* marshal.c (r_object): should register class/module objects.\n\nSat Oct 23 15:59:39 1999  Takaaki Tateishi  <ttate@jaist.ac.jp>\n\n\t* process.c (rb_f_system): should require at least one argument.\n\nSat Oct 23 12:42:44 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* enum.c (enum_collect): collect without block will collect\n\t  elements in enumerable.\n\nThu Oct 21 16:14:19 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (moreswitches): function to process string option;\n\t  the name is stolen from perl (not implementation).\n\n\t* ruby.c (proc_options): use RUBYOPT environment variable to\n\t  retrieve the default options.\n\n\t* dir.c (fnmatch): use eban's fnmatch; do not depend on system's\n\t  fnmatch (which may have portability problem) anymore.\n\nWed Oct 20 15:14:24 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (marshal_load): should protect the generated object\n\t  table (arg->data) from GC.\n\nMon Oct 18 16:15:52 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/nkf/nkf.c (rb_nkf_kconv): output should be NUL terminated.\n\nMon Oct 18 09:03:01 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb: 1.0.3\n\n\t* lib/net/pop.rb: new methods POP3Command#uidl, POPMail#uidl.\n\nSun Oct 17 03:35:33 1999  Masaki Fukushima  <fukusima@goto.info.waseda.ac.jp>\n\n\t* array.c (rb_ary_pop): forgot some freeze checks.\n\nSat Oct 16 12:57:53 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* array.c (rb_ary_sort): always returns the copied array.\n\nFri Oct 15 22:50:41 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* error.c (sys_nerr): on CYGWIN, it is _sys_nerr.\n\nFri Oct 15 01:32:31 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* io.c (rb_io_ctl) :need to use NUM2ULONG, not NUM2INT.\n\n\t* ext/Win32API/Win32API.c (Win32API_Call): need to use NUM2ULONG,\n\t  not NUM2INT.\n\nFri Oct 15 00:22:30 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (Init_Regexp): super class of the MatchingData, which was\n\t  Data, to be Object.\n\n\t* eval.c (ruby_run): evaluate required libraries before load &\n\t  compiling the script.\n\n\t* parse.y (lex_getline): retrieve a line from the stream, saving\n\t  lines in the table in debug mode.\n\n\t* eval.c (call_trace_func): treat the case ruby_sourcefile is null.\n\nThu Oct 14 02:00:10 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (string): compile time string concatenation.\n\nWed Oct 13 07:28:09 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb: 1.0.2\n\n\t* lib/net/session.rb: new method Session#set_pipe.\n\n\t* lib/net/session.rb, smtp.rb, pop.rb: add RD documentation.\n\nWed Oct 13 02:17:05 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* array.c (rb_ary_plus): remove recursion.\n\n\t* array.c (rb_ary_sort_bang): detect modify attempt.\n\nWed Oct 13 02:17:05 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (block_pass): should copy block to prevent modifications.\n\t  tag in the structure should be updated from latest prot_tag.\n\n\t* eval.c (proc_s_new): tag in struct BLOCK should not point into\n\t  unused stack.\n\n\t* dir.c (dir_s_glob): iterate over generated matching filenames if\n\t  the block is given to the method.\n\n\t* array.c (rb_ary_at): new methods; at, first, last.\n\n\t* hash.c (rb_hash_fetch): raises exception unless the default\n\t  value is supplied.\n\n\t* hash.c (rb_hash_s_create): need not remove nil from value.\n\n\t* hash.c (rb_hash_aset): setting value to nil does not remove key\n\t  anymore.\n\nTue Oct 12 22:29:04 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_read): length may be 0 or negative.\n\nTue Oct 12 13:26:27 1999  Jun-ichiro itojun Hagino  <itojun@itojun.org>\n\n\t* signal.c (posix_signal): RETSIGTYPE may be void.\n\nTue Oct 12 03:28:03 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* array.c (rb_ary_delete_at): allows negative position.\n\nMon Oct 11 17:42:25 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (rb_intern): should generate distinct ID_ATTRSET symbols\n\t  for the name with multiple `='s at the end.\n\n\t* Makefile.in (CPPFLAGS): separate cpp flags from CFLAGS.\n\nMon Oct 11 07:27:05 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): should not execute the `else' clause on the\n\t  case the exceptions are handled by the `rescue' clause.\n\n\t* signal.c (Init_signal): ignore SIGPIPE by default.\n\nWed Oct  6 17:13:19 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* ruby.c (addpath): rubylib_mangled_path() modified.\n\nMon Oct  4 12:42:32 1999  Kazuhiko Izawa  <izawa@erec.che.tohoku.ac.jp>\n\n\t* pack.c (pack_unpack): % in printf format should be %%.\n\nMon Oct  4 10:01:40 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_obj_instance_variables): should always return\n\t  array for all object can have instance variables now.\n\nMon Oct  4 00:08:34 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (OFF16): need to adjust pointer address to pack/unpack on\n\t  64bit machines.\n\nSun Oct  3 03:05:59 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* time.c (time_arg): mktime y2k problem.\n\nSun Sep 26 16:54:45 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* parse.y (here_document): `\\r' handling for here documents.\n\nWed Sep 22 09:20:11 1999  Masahiro Tomita  <tommy@tmtm.org>\n\n\t* ext/socket/socket.c: SOCKS5 support.\n\nWed Sep 22 07:33:23 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb: 1.0.1\n\n\t* lib/net/pop.rb: APOP did not work.\n\n\t* lib/net/pop.rb: modify the way to make APOP challenge.\n\nWed Sep 22 00:35:30 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_include): should return boolean value.\n\n\t* regex.c (re_compile_fastmap): wrong comparison with mbc.\n\n\t* eval.c (specific_eval): default sourcefile name should be\n\t  \"(eval)\" for module_eval etc.\n\nWed Sep 22 00:06:07 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/Makefile: update rules.\n\n\t* io.c (io_fread): should not assign in char, it maybe -1.\n\nTue Sep 21 23:57:54 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (call_trace_func): should not propagate retval in\n\t  trace_func.\n\nMon Sep 20 21:35:39 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/win32.c (myselect): assume non socket files are always\n\t  readable/writable.\n\nMon Sep 20 01:08:02 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_fread): should not block other threads.\n\n\t* io.c (rb_io_synchronized): renamed from rb_io_unbuffered(); do\n\t  not call setbuf(NULL) anymore.\n\nSat Sep 18 13:45:43 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* stable version 1.4.2 released.\n\nFri Sep 17 23:24:17 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* eval.c (rb_f_missing): dumped core if no argument given.\n\nFri Sep 17 23:21:06 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* win32/win32.c (myselect): translate WSAEINTR, WSAENOTSOCK into\n\t  UNIX errno constants.\n\nFri Sep 17 00:52:27 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (arg): assignable() may return 0.\n\nThu Sep 16 20:46:23 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* eval.c (rb_eval): was doubly evaluating the return expression.\n\nThu Sep 16 18:40:08 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* stable version 1.4.1 released.\n\nThu Sep 16 11:33:22 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* string.c (rb_str_match): should return nil.\n\nWed Sep 15 22:46:37 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_s_quote): should quote `-' too.\n\nTue Sep 14 15:23:22 1999  Nobuyoshi Nakada  <nobu.nakada@nifty.ne.jp>\n\n\t* parse.y (yylex): no need to ignore `\\r' here.\n\n\t* parse.y (nextc): strip `\\r' from text.\n\n\t* parse.y (nextc): support `__END__\\r\\n' type terminator.\n\nMon Sep 13 10:49:19 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* eval.c (rb_eval): needless RTEST(ruby_verbose) removed.\n\nMon Sep 13 09:10:11 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/net/session.rb, smtp.rb, pop.rb: 1.0.0\n\nWed Sep  8 11:37:38 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* time.c (make_time_t): bit more strict comparison.\n\nTue Sep  7 00:50:56 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* range.c (range_each): use rb_str_upto() for strings.\n\n\t* string.c (rb_str_upto): set upper limit by comparing curr <= end.\n\n\t* range.c (range_each): should check equality to handle magic\n\t  increment.\n\nMon Sep  6 22:43:33 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): break/next/redo available within -n/-p loop.\n\nFri Sep  3 11:14:31 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* compar.c (cmp_equal): should not raise exception; protect by\n\t  rb_rescue().\n\nThu Sep  2 05:23:05 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* file.c (rb_file_s_expand_path): use dirsep, instead of character\n\t  literal '/'.\n\n\t* file.c (rb_file_s_expand_path): reduce multiple dirsep at the top.\n\nWed Sep  1 00:28:27 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_call): call rb_undefined() if a method appears not to\n\t  be exist explicitly from cache.\n\n\t* eval.c (rb_method_boundp): check method cache before calling\n\t  rb_get_method_body().\n\n\t* eval.c (rb_get_method_body): store method non-existence\n\t  information in the cache.\n\n\t* random.c (rb_f_srand): use getpid(2) to generate seed.\n\n\t* regex.c (re_match): do not apply partial mbc match for\n\t  charset_not.\n\n\t* regex.c (re_compile_pattern): put extended literal prefix (0xff)\n\t  only before numeric literals, not before all >0x80 char.\n\n\t* regex.c (re_compile_pattern): put numeric literal in extended\n\t  charset region, not normal charset bits.\n\n\t* regex.c (re_compile_fastmap): calculate fastmap for charset and\n\t  charset_not to treat numeric literal (e.g. \\246) specially.\n\nFri Aug 28 17:32:55 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* eval.c (rb_eval): should set return value (nil) explicitly if a\n\t  value is omitted for return statement.\n\nSun Aug 26 20:26:40 2001  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ext/readline/readline.c: restore terminal mode\n\t  even if readline() interrupted.\n\n\t* ext/readline/readline.c: returned string need to\n\t  be tainted.\n\n\t* ext/readline/readline.c: fixed memory leak.\n\n\t* ext/readline/readline.c: allow negative index.\n\n\t* ext/readline/readline.c: added Readline::HISTORY.size\n\t  same as Readline::HISTORY.length\n\n\t* ext/readline/readline.c: allow conditional parsing\n\t  of the ~/.inputrc file by `$if Ruby'.\n\n\t* ext/readline/extconf.rb: check whether the\n\t  libreadline has the variable `rl_completion_append_character'\n\t  (this feature was implemented from GNU readline 2.1).\n\nThu Aug 26 15:06:11 1999  Masaki Fukushima  <fukusima@goto.info.waseda.ac.jp>\n\n\t* gc.c (rb_gc): local variables may be placed beyond stack_end, so\n\t  use an address from alloca(1) on non C_ALLOCA platforms.\n\nThu Aug 26 01:24:17 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (rb_f_sprintf): \"%%\" is legal, but \"%3.14%\" is not.\n\nMon Aug 23 00:00:54 1999  Tsukada Takuya  <tsukada@fminn.nagano.nagano.jp>\n\n\t* regex.c (re_compile_fastmap): wrong macro caused memory leak.\n\nSat Aug 21 11:30:51 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (ADJ): should not adjust addresses to data on heap.\n\nFri Aug 20 20:50:58 1999  Kenji Nagasawa  <kenn@hma.att.ne.jp>\n\n\t* defines.h (PATH_SEP): path separator is \";\" for OS/2.\n\nThu Aug 19 10:50:43 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* gc.c (rb_gc): add volatile to avoid GCC optimize bug(?).\n\nWed Aug 18 23:48:10 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* due to disk trouble, some change records were lost.  several\n\t  modification made to eval.c, gc.c, io.c, pack.c,\n\t  ext/extmk.rb.in, and lib/mkmf.rb.\n\nFri Aug 13 15:41:39 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* stable version 1.4.0 released.\n\nFri Aug 13 03:16:07 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (argf_forward): since $stdout may be non-IO, ARGF.file is\n\t  not guaranteed to be IO.  check and forwarding added to every ARGF\n\t  method.\n\n\t* io.c (set_outfile): $stdout/$stderr may not be IO now.\n\n\t* io.c (set_stdin): $stdin may not be IO now.\n\n\t* range.c (rb_range_beg_len): round `end' to length as documented.\n\n\t* io.c (Init_IO): preserve original stdin/stdout/stderr.\n\nThu Aug 12 13:44:33 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (Init_load): require receives 1 argument.\n\n\t* eval.c (frame_dup): should clear tmp to avoid dangling\n\t  references.\n\nWed Aug 11 13:33:13 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* eval.c (rb_eval): no automatic aggregate initialization.\n\n\t* eval.c (module_setup): ditto.\n\nWed Aug 11 18:18:41 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* eval.c (yield_under_i): automatic aggregate initialization is an\n\t  ANSI feature.\n\nWed Aug 11 10:10:02 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): parse `[].length==0' as `([].length)==0', not\n\t  `([].length=)=0'\n\n\t* parse.y (yylex): parse `[].length!=0' as `([].length)!=0', not\n\t  `([].length!)=0'\n\n\t* parse.y (peek): peek-in lexical buffer.\n\nWed Aug 11 00:34:05 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): bug on backward jump adjustment concerning\n\t  stop_paren.\n\nTue Aug 10 14:54:25 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/nkf/nkf.c (rb_nkf_guess): binary detection was wrong.\n\nTue Aug 10 00:07:36 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_clone): should use CLONESETUP().\n\nMon Aug  9 23:57:07 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.h (CLONESETUP): should have copied generic instance\n\t  variables too.\n\nMon Aug  9 10:46:54 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/extconf.rb: add check for <arpa/nameser.h> and\n\t  <resolv.h>.\n\nSat Aug  7 13:19:06 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* numeric.c (flo_cmp): comparing NaN should not return value.\n\t  raises FloatDomainError.\n\nSat Aug  7 03:09:08 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (blk_free): free copied frames too.\n\n\t* eval.c (frame_dup): should copy previous frames from stack to\n\t  heap to preserve frame information.\n\nFri Aug  6 15:01:07 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.3.7 - version 1.4 beta\n\n\t* ext/socket/socket.c (s_recv): UDPsocket#recvfrom now returns\n\t  IPsocket#addr information.\n\n\t* array.c (rb_ary_subary): ary[-3,3] should not return nil.\n\nThu Aug  5 10:58:01 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_mark): protect old ruby_frame from GC during it\n\t  replaced by eval().\n\n\t* eval.c (eval): do not modify frame.prev; binding should preserve\n\t  information about calling() too.\n\n\t* eval.c (rb_yield_0): no arity check for mere yield; but only for\n\t  Proc#call.\n\nTue Aug  3 22:07:13 1999  Kazuhiro HIWADA  <hiwada@kuee.kyoto-u.ac.jp>\n\n\t* object.c (rb_mod_clone): should check if iv_tbl, m_tbl are\n\t  initialized.\n\nTue Aug  3 19:03:02 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_any_cmp): use rb_with_disable_interrupt() to ensure\n\t  clearance of rb_prohibit_interrupt even on failure.\n\n\t* eval.c (rb_with_disable_interrupt): new function added.\n\nSat Jul 31 23:23:44 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_create_0): set THREAD_RAISED flag on thread\n\t  termination by exception.\n\n\t* eval.c (rb_thread_join): `$!' may not be nil for the threads\n\t  created in rescue clause.\n\n\t* eval.c (rb_thread_status): ditto.\n\n\t* eval.c (rb_thread_join): should re-raise exception for already\n\t  dead threads too.\n\nFri Jul 30 17:56:54 1999  GOTO Kentaro  <gotoken@math.sci.hokudai.ac.jp>\n\n\t* object.c (rb_mod_ge): wrong comparison.\n\nFri Jul 30 12:15:44 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/tcltklib/extconf.rb: win32 support.\n\n\t* lib/mkmf.rb: use append_library().\n\n\t* ext/extmk.rb.in: ditto.\n\nFri Jul 30 02:11:48 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_delete): should return nil for deleting non\n\t  existing item.\n\n\t* io.c (rb_io_close): call rb_sys_wait() on explicit close.\n\n\t* io.c (rb_io_fptr_close): do not call rb_sys_wait() on finalize.\n\n\t* eval.c (yield_under_i): cbase context should be maintained for\n\t  Module#module_eval().  suggested by <inaba@st.rim.or.jp>.\n\nWed Jul 28 01:18:28 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* Makefile.in: add -I$(hdrdir)/lib to install using ftools.\n\n\t* util.c: use HAVE_FCNTL_H, not HAVE_FCNTL\n\nWed Jul 28 18:24:45 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.3.6 - version 1.4 alpha\n\nTue Jul 27 09:38:08 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* eval.c (rb_eval): reduce recursive rb_eval() calls by\n\t  NODE_BLOCKs.\n\nTue Jul 27 01:20:40 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* file.c (rb_file_s_expand_path): drive letter patch.\n\nMon Jul 26 02:36:31 1999  Shugo Maeda  <shugo@netlab.co.jp>\n\n\t* eval.c (rb_load): should clear ruby_nerr.\n\n\t* eval.c (rb_thread_join): oldbt should not be empty to unshift.\n\nSun Jul 25 12:09:16 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* dir.c (push_braces): should treat nested braces.\n\nFri Jul 23 02:49:49 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_hash_clear): dummy argument added; suggested by\n\t  <eguchi@shizuokanet.ne.jp>.  thanks.\n\nThu Jul 22 19:37:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_join): get_backtrace() may return Qnil.\n\t  typecheck added.\n\nTue Jul 20 14:36:43 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* range.c (range_each): do not treat String specially (for future\n\t  override).\n\nTue Jul 20 02:28:34 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_gets): $_ should be nil, when get returns nil.\n\n\t* io.c (rb_f_gets): ditto.\n\nMon Jul 19 17:13:09 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_fastmap): should continue fastmap compile\n\t  for anychar_repeat, for it's repeat anyway.\n\nMon Jul 26 13:33:45 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* lib/jcode.rb: replaced by faster code.\n\nMon Jul 19 01:57:28 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/mkmf.rb: no longer use install program.\n\n\t* ext/extmk.rb.in: use miniruby to install programs.\n\nSat Jul 17 00:06:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (ipaddr): don't do reverse lookup if\n\t  attribute do_not_reverse_lookup is set for socket classes.\n\t  Experimental.  Note this is a global attribute.\n\nFri Jul 16 22:18:29 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_eof): use feof() to check EOF already met.\n\n\t* io.c (read_all): should return nil at EOF.\n\nFri Jul 16 13:39:42 1999  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/telnet.rb: version 0.231.\n\nFri Jul 16 10:58:22 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* regex.c (re_match): debug print removed.\n\nFri Jul 16 09:58:15 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* many files: clean up unused variables found by gcc -Wall.\n\n\t* lib/mkmf.rb: better cygwin support etc.\n\n\t* ext/extmk.rb.in: ditto.\n\n\t* instruby.rb: ditto.\n\nFri Jul 16 01:37:50 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* string.c (rb_str_squeeze_bang): the type of local variable `c'\n\t  should be int, not char.\n\n\t* string.c (rb_str_reverse): should always return copy.\n\nThu Jul 15 23:25:57 1999  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* lib/debug.rb: better display & frame treatment.\n\nThu Jul 15 21:16:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_each): returns self for normal termination;\n\t  returns nil for break.\n\n\t* string.c: non bang methods (e.g. String#sub) should always\n\t  return copy of the receiver.\n\nThu Jul 15 21:09:15 1999  Masaki Fukushima  <fukusima@goto.info.waseda.ac.jp>\n\n\t* eval.c (find_file): do not add empty string to the path.\n\n\t* configure.in (with-search-path): should not add empty string if\n\t  the option is not supplied.\n\nThu Jul 15 17:49:08 1999  Ryo HAYASAKA  <hayasaka@univ21.u-aizu.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c: move `#include \"ruby.h\"' forward.\n\nThu Jul 15 16:54:16 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.3.5 - version 1.4 alpha\n\nWed Jul 14 23:45:33 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* eval.c (ruby_init): initialize for the first time only.\n\nTue Jul 13 00:15:19 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_hash_index): re-defined; method to retrieve a key\n\t  from the value.\n\n\t* hash.c (Init_Hash): member? should be re-defined for Hash.\n\nTue Jul 12 13:54:51 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* io.c (rb_file_sysopen): wrong number of argument.\n\nMon Jul 12 11:52:35 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_f_missing): class name included in message.\n\n\t* eval.c (print_undef): better error message.\n\nSun Jul 11 05:36:17 1999  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* lib/debug.rb: patch to show proper position.\n\nFri Jul  9 23:56:14 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* dln.c (dln_find_1): path conv. moved to conv_to_posix_path.\n\n\t* dln.c (conv_to_posix_path): path conv. should be done.\n\nFri Jul  9 10:26:47 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* random.c (RANDOM_NUMBER): should place parentheses.\n\nFri Jul  8 11:00:51 1999  Shugo Maeda  <shugo@netlab.co.jp>\n\n\t* numeric.c (fix_div): division may be out of fixnum range.\n\n\t* bignum.c (bigdivmod): proper sign calculation to result.\n\nWed Jul  7 18:27:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* st.c (st_delete_safe): was modifying wrong slot.\n\nMon Jul  5 13:17:46 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (rb_gc_call_finalizer_at_exit): close all files at exit.\n\nFri Jul  2 18:00:21 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* lib/Mail/README: Mail-0.3.0 added to the distribution.\n\nFri Jul  2 01:45:32 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_fastmap): avoid allocation of register\n\t  variables for each invocation of re_match().  Suggested by\n\t  Zasukhin Ruslan <ruslan@paradigmasoft.com>.  Thanks.\n\nTue Jun 29 20:39:24 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ext/tk/lib/tk.rb (TkVariable): bug fix; should value type check\n\t  be added?\n\n\t* string.c (rb_str_each_line): a bug in paragraph mode.\n\n\t* ruby.c (load_file): shifted too much to skip #!.\n\nTue Jun 29 06:50:21 1999  Wakou Aoyama  <wakou@fsinet.or.jp>\n\n\t* lib/CGI.rb: 0.30 - cleanup release, incompatible.\n\n\t* lib/telnet.rb: 0.22 - timeout added.\n\nTue Jun 29 10:49:25 1999  SHIROYAMA Takayuki  <psi@fortune.nest.or.jp>\n\n\t* configure.in: better Rhapsody support.\n\n\t* lib/mkmf.rb: Rhapsody/NEXTSTEP support.\n\nTue Jun 29 01:42:13 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/pty/pty.c (chld_changed): should use POSIX.1 style wait.\n\nMon Jun 28 21:07:36 1999  KIMURA Koichi  <kbk@kt.rim.or.jp>\n\n\t* ext/extmk.rb.nt: wrong result for have_library().\n\nMon Jun 28 15:24:05 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* missing/isinf.c: OSF/1 raises SIGFPE on one()/zero().\n\n\t* regex.c (re_search): should search til EOS, for patterns may\n\t  match beyond the end of range.\n\nMon Jun 28 12:49:12 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_f_select): should not accept Time objects as an\n\t  argument for it is time interval.\n\n\t* process.c (rb_f_sleep): ditto.\n\n\t* file.c (test_s): should return nil for false condition.\n\nMon Jun 28 12:23:52 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* bignum.c (rb_dbl2big): typo.\n\n\t* file.c (rb_f_test): ditto.\n\n\t* string.c (rb_str_crypt): wrong message.\n\nSun Jun 27 19:50:11 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* eval.c (rb_f_exit): should have treat signed integer status, not\n\t  VALUE.\n\n\t* process.c (rb_f_exit_bang): should work like exit().\n\nSun Jun 27 16:21:32 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* string.c (rb_str_rindex): wrong position to search.\n\nSat Jun 26 04:05:30 1999  Takaaki Tateishi  <ttate@jaist.ac.jp>\n\n\t* configure.in (configure_args): --with-search-path to specify\n\t  additional ruby search path.\n\n\t* ruby.c (ruby_prog_init): additional search path.\n\nFri Jun 25 13:09:12 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (pack_unpack): needed to initialize natint.\n\n\t* regex.c (re_compile_pattern): add start_paren to avoid too much\n\t  finalization on maybe_finalize_jump.\n\nFri Jun 25 13:07:20 1999  Koji Oda  <oda@bsd1.qnes.nec.co.jp>\n\n\t* missing/isinf.c: include \"config.h\" added.\n\nFri Jun 25 07:25:05 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* lib/mkmf.rb: initialize $(topdir).\n\n\t* ext/extmk.rb.in (install_rb): install lib/*.rb properly.\n\n\t* configure.in (linux): specifies -rpath on --enable-shared.\n\n\t* configure.in (aix): ruby.imp must reside in $(topdir).\n\nThu Jun 24 19:11:29 1999  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* parse.y (rb_str_extend): multi-byte identifier in expression\n\t  interpolation in strings.\n\n\t* parse.y (yylex): support multi-byte char identifiers.\n\nThu Jun 24 15:27:13 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (f_arg): check duplicate argument names.\n\n\t* gc.c (rb_gc_mark): marking wrong member for NODE_ARGS.\n\n\t* string.c (rb_str_rindex): POSITION specifies start point, not\n\t  end point.\n\nThu Jun 24 13:00:17 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (print_mbc): wrong boundary.\n\n\t* pack.c (uv_to_utf8): raises ArgError for too big value.\n\nThu Jun 24 11:02:51 1999  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* pack.c (uv_to_utf8): mask needed.\n\nWed Jun 23 21:03:56 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* ruby.h (struct RFile): remove iv_tbl from struct. instance\n\t  variables are handled as generic ivs.\n\nWed Jun 23 22:06:26 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* pack.c (utf8_to_uv): pack to 7 bytes sequence.\n\n\t* pack.c (uv_to_utf8): wrong boundary.\n\n\t* pack.c (pack_unpack): should treat as unsigned long.\n\nWed Jun 23 15:10:11 1999  Inaba Hiroto  <inaba@sdd.tokyo-sc.toshiba.co.jp>\n\n\t* parse.y (parse_string): failed to parse nested braces.\n\n\t* parse.y (parse_regx): nested braces within #{} available.\n\nWed Jun 23 11:18:38 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (slow_search): wrong shift width for mbcs.\n\n\t* eval.c (rb_thread_save_context): should not clear th->locals.\n\nWed Jun 23 02:06:14 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): UMINUS binds too tight with digits. changed so\n\t  that -2**2 => -4.\n\n\t* parse.y (close_paren): `do' for expr termination now works it\n\t  used to be.\n\nWed Jun 22 18:26:42 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* pack.c (pack_pack): should initialize local variable `j'.\n\nWed Jun 22 15:24:59 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* parse.y (here_document): a bug for multiline heredoc.\n\nTue Jun 22 15:06:36 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/socket/socket.c (ruby_socket): forgot to return fd\n\t  explicitly.\n\nTue Jun 22 13:34:12 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* rubyio.h (MakeOpenFile): should initialize member `iv_tbl'.\n\nWed Jun 22 10:35:51 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* io.c (rb_io_gets_internal): getc(3) may not set errno on\n\t  interrupt.\n\nMon Jun 21 22:39:28 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (call_required_libraries): ruby_sourceline should be\n\t  cleared before loading libraries.\n\n\t* io.c (set_stdin): do not use reopen(), so that we don't need to\n\t  dup original stdin before assigning $stdin.\n\nMon Jun 21 18:04:27 1999  Ryo HAYASAKA  <hayasaka@univ21.u-aizu.ac.jp>\n\n\t* ext/dbm/dbm.c: include <cdefs.h> for solaris 2.6.\n\nMon Jun 21 15:59:47 1999  Nobuyoshi Nakada  <nobu.nokada@softhome.net>\n\n\t* ext/socket/socket.c (ip_addrsetup): forgot to put `else'.\n\nMon Jun 21 15:38:37 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (fptr_finalize): remove rb_syswait() invocation to avoid\n\t  wait4(2) within GC.  rb_syswait() moved to rb_io_fptr_close().\n\nMon Jun 21 12:05:59 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* dir.c (dir_s_glob): remove MAXPATHLEN restriction.\n\n\t* ext/md5/md5init.c (md5_hexdigest): should have used \"%02x\".\n\nSun Jun 20 19:50:38 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* string.c (rb_str_each_line): should have checked string\n\t  boundary.\n\nSat Jun 19 22:24:12 1999  Kenji Nagasawa  <kenn@hma.att.ne.jp>\n\n\t* OS/2 patch improved.\n\nFri Jun 18 08:30:17 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (r_byte): add data length check.\n\n\t* ext/tcltklib/tcltklib.c (_timer_for_tcl): was doing busy-wait.\n\nTue Jun 15 10:01:21 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* configure.in: remove trailing slash from interpreter embedded\n\t  shared library path.\n\n\t* configure.in (INSTALL_DLLIB): install shared lib with 0555.\n\n\t* instruby.rb: changed mode for shared library into 0555.\n\nFri Jun 11 23:27:00 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* ext/etc/etc.c (etc_passwd): should return nil, not exception for\n\t  call after last passwd entry.\n\nFri Jun 11 15:21:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (rb_gc_mark_locations): add safety margin 1.\n\n\t* eval.c (ruby_run): should protect toplevel node tree.\n\n\t* ext/etc/etc.c (etc_group): dumps core if there's no more group.\n\nFri Jun 11 01:50:25 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (ruby_run): Init_stack() was called too late; local\n\t  variables happened to be higher (or lower) than stack_start.\n\nThu Jun 10 16:41:48 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c: do not call `initialize' for IO objects.  So with Array,\n\t  Hash, Range, and Time objects.\n\n\t* ext/curses/curses.c (curses_getch): made thread aware using\n\t  rb_read_check().\n\n\t* ext/curses/curses.c (window_getch): ditto.\n\n\t* ext/curses/curses.c (curses_getstr): made (partially) thread\n\t  aware using rb_read_check().\n\n\t* ext/curses/curses.c (window_getstr): ditto.\n\n\t* io.c (rb_read_check): new function to help making something\n\t  (like extension libraries) thread aware.\n\n\t* eval.c (is_defined): `defined? super' should be true even for\n\t  private superclass methods.\n\nFri Jun 10 13:42:10 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* pack.c (pack_pack): template `Z' should be allowed.\n\nWed Jun  9 13:26:38 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_loading): modified to avoid nested race\n\t  condition of require().\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke): queue invocation on non\n\t  main threads.\n\n\t* ext/tcltklib/tcltklib.c (lib_mainloop): flush invocation\n\t  queues periodically.\n\n\t* version.c (ruby_show_version): now print the message to stdout.\n\n\t* version.c (ruby_show_copyright): ditto.\n\nTue Jun  8 00:00:34 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (pack_unpack): append sentinel (NUL) to the string.\n\n\t* ext/md5/md5init.c (md5_hexdigest): new method to obtain\n\t  printable hash string.\n\n\t* ext/md5/md5init.c (md5_update): should return self.\n\n\t* pack.c (pack_pack): undocumented template 'U' for UTF8.\n\n\t* pack.c (pack_unpack): ditto.\n\n\t* marshal.c (r_byte): should replace getc() with rb_getc().\n\n\t* io.c (rb_getc): getc() replacement uses READ_DATA_PENDING() and\n\t  rb_thread_wait_fd().\n\nMon Jun  7 23:23:38 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (rb_mod_clone): should call CLOSESETUP().\n\n\t* eval.c (bind_clone): should call CLONESETUP() for new clone.\n\nSat Jun  5 10:32:40 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_oct): binary (e.g. 0b10111) support.\n\n\t* variable.c (rb_const_set): raise warning, not exception.\n\n\t* parse.y (yycompile): initialize parser internal variables.\n\n\t* parse.y (close_paren): set lex_state to EXPR_PAREN after closing\n\t  parenthesis.\n\n\t* parse.y (yylex): returns kDO for `do' right after method_call.\n\nThu Jun  3 11:05:30 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* regex.c (read_backslash): should decode \\b within class.\n\nThu Jun  3 01:06:18 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* dln.c (dln_load): AIX improvement (aix_findmain removed).\n\nWed Jun  2 00:41:31 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (pack_unpack): new undocumented template Z which strips\n\t  stuff after first null.\n\n\t* pack.c (pack_pack): should preserve specified length of the\n\t  resulting string.\n\nTue Jun  1 15:29:33 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (ruby_socket): retry after GC, if socket(2)\n\t  failed on EMFILE or ENFILE.\n\n\t* ext/socket/socket.c (sock_s_socketpair): ditto.\n\n\t* eval.c (module_setup): need to add PUSH_VAR/POP_VAR to clear\n\t  dyna vars link list.\n\n\t* version.h (RUBY_RELEASE_CODE): integer macro constant for source\n\t  version detection.\n\nSun May 30 22:19:12 1999  Kenji Nagasawa  <kenn@tcp-ip.or.jp>\n\n\t* ext/socket/socket.c: emx/gcc 0.9d now fixes things about\n\t  AF_UNIX.\n\n\t* process.c: OS/2 EMX kludge.\n\n\t* Makefile.in (strncasecmp.o): added dependency.\n\nMon May 31 16:06:28 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.3.4 - preliminary release for 1.4\n\nMon May 31 15:57:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_fptr_close): close on IO which main_thread is\n\t  waiting cause serious exception, that vanishes the actual fd\n\t  closing.  Invocation of rb_thread_fd_close() is deferred\n\t  a little.\n\nSat May 29 18:27:13 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* regex.c (re_match): stack boundary check needed.\n\nSat May 29 12:27:00 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke): proper ref count management\n\t  to avoid leak.  I HATE REF COUNTING!!\n\n\t* eval.c (ruby_run): moved ruby_require_libraries() to handle `-r'\n\t  from ruby_options() to avoid stack corruption for threads\n\t  created in libraries.\n\nSat May 29 02:22:12 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_yield_0): when `for' appeared in blocks, it\n\t  introduced new scope for local variables.\n\nFri May 28 17:16:49 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_squeeze_bang): squeeze AND of the arguments.\n\t  UNDOCUMENTED.\n\n\t* string.c (rb_str_count): new UNDOCUMENTED method.\n\n\t* string.c (rb_str_delete_bang): delete AND of the arg ranges.\n\t  UNDOCUMENTED FEATURE for 1.3.x.\n\n\t* ext/socket/socket.c (setipaddr): re-wrote using ip_addrsetup().\n\n\t* ext/socket/socket.c (ip_addrsetup): decode symbolic address\n\t  <broadcast>.\n\nThu May 27 12:27:42 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (tr_trans): should handle NUL (\\0) within strings.\n\nTue May 25 16:45:11 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_f_syscall): syscall may return values other than zero\n\t  on success.\n\n\t* regex.c (re_match): handle empty loop properly (hopefully).\n\n\t* regex.c (re_match): remove empty group check, because it does\n\t  not help non-grouping parentheses (?:..).\n\n\t* regex.c (re_compile_fastmap): treating try_next, finalize_push\n\t  wrong way.\n\n\t* regex.c: remove some obsolete functions such as\n\t  group_match_null_string_p().\n\nMon May 24 14:47:54 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (read_backslash): read backslash by regex.\n\nSun May 23 19:44:58 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ext/pty/pty.c (getDevice): portability patch.\n\nFri May 21 23:01:26 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/getaddrinfo.c (GET_AI): should set error code.\n\nThu May 20 03:43:44 1999  Jun-ichiro itojun Hagino  <itojun@itojun.org>\n\n\t* ext/socket/socket.c: you should use sockaddr_storage to handle\n\t  IPv6 addresses.\n\n\t* ext/socket/getaddrinfo.c (getaddrinfo): prevent retrieving\n\t  AF_INET6 address if hints.ai_flags == AI_PASSIVE.\n\nWed May 19 12:27:07 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (exec_end_proc): should protect exceptions.\n\n\t* gc.c (run_final): ditto.\n\n\t* parse.y (f_rest_arg): allow just * for rest arg.\n\n\t* parse.y (mlhs_basic): allow * without formal argument.\n\n\t* regex.c (re_match): the variable `part' should be initialized.\n\nTue May 18 15:25:45 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): a bug in range adjustment.\n\nTue May 18 11:35:59 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* dln.c (conv_to_posix_path): path_len argument added.\n\nMon May 17 12:26:31 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (fix_rev): should treat Fixnum as signed long.\n\n\t* eval.c (massign): add strict number check for yield (and call).\n\n\t* eval.c (proc_arity): new method to return number of arguments.\n\n\t* eval.c (method_arity): new method to return number of arguments.\n\n\t* parse.y (read_escape): char may be unsigned.\n\n\t* string.c (rb_str_succ): ditto.\n\n\t* string.c (tr_trans): ditto.\n\n\t* object.c (Init_Object): methods `&', `|', `^' are added to nil.\n\n\t* range.c (rb_range_beg_len): it should be OK for [0..-len-1].\n\n\t* regex.c (re_search): search for byte literal within mbcs.\n\n\t* regex.c (is_in_list): parsh\n\n\t* regex.c (re_compile_fastmap): should have not alter the loop\n\t  variable `j' if TRASLATE_P().\n\n\t* regex.c (re_compile_pattern): escaped characters should be read\n\t  by PATFETCH_RAW(c).\n\nSat May 15 11:23:51 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): endline2 (\\Z) should not match at the point\n\t  between a newline and end-of-line, like endline ($).\n\n\t* class.c (include_class_new): should initialize iv_tbl to share\n\t  between module and iclass.\n\nFri May 14 08:50:27 1999  Akira Endo  <akendo@t3.rim.or.jp>\n\n\t* regex.c (re_compile_fastmap): it should be k != 0 to skip.\n\nFri May 14 12:46:56 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_load): a bug in old marshal format support.\n\n\t* instruby.rb: make site_ruby directory.\n\nFri May 14 10:18:02 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* regex.c (re_match): a bug in inline `.*' etc.\n\nFri May 14 09:58:46 1999  Minero Aoki  <aamine@dp.u-netsurf.ne.jp>\n\n\t* ruby.c (addpath): should have specified string length.\n\nThu May 13 10:40:44 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval_string_wrap): new function.\n\n\t* regex.c (re_compile_pattern): POSIX line match should alter\n\t  behavior for `^' and `$' to begbuf and endbuf2 respectively.\n\n\t* ext/pty/pty.c: un-ANSI-fy function arguments.\n\nWed May 12 14:19:38 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* struct.c (iv_get): in case of inheritance of generated struct\n\t  class, __member__ and __size__ should also be inherited.\n\t  Thanks for Pros Yeboah <yeboah@tu-harburg.de>.\n\n\t* io.c (rb_f_gets_internal): should check number of arguments\n\t  before checking rb_rs == rb_default_rs.  Thanks for Koji Arai\n\t  <JCA02266@nifty.ne.jp>.\n\nTue May 11 08:29:28 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): .?, .+ did not work.\n\nMon May 10 00:59:33 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/jcode.rb: forgot to squeeze on reverse (complement) case.\n\n\t* string.c (tr_squeeze): should not set modify flag to be honest,\n\t  if the string is not modified.\n\n\t* signal.c (Init_signal): SIGTERM should not be handled.\n\n\t* regex.c (re_match): seeking for longest match is now optional,\n\t  which can be set using RE_OPTION_POSIXMATCH.  This satisfies\n\t  POSIX longest match as much as Emacs's posix-* functions, which\n\t  are known to be incomplete.\n\nSun May  9 13:04:01 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/socket.c (sock_s_getaddrinfo): conversion from\n\t  Fixnums to C integers needed.\n\nSun May  9 11:51:43 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* range.c (range_eqq): reverse condition.\n\n\t* range.c (range_s_new): default should be end inclusive.\n\nSat May  8 03:27:51 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (thread_connect): replace nasty\n\t  rb_thread_fd_writable() with rb_thread_select().\n\nFri May  7 20:49:00 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* ext/socket/getaddrinfo.c (inet_pton): wrong parameter to\n\t  inet_aton().\n\n\t* ext/socket/addrinfo.h (__P): silly cut and paste typo.\n\nFri May  7 17:03:57 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* dir.c (glob): removed GPL'ed glob.c completely.\n\nFri May  7 08:17:19 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/sdbm/extconf.rb: sdbm extension added to the distribution.\n\nFri May  7 01:42:20 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (tcp_s_gethostbyname): avoid using struct\n\t  sockaddr_storage.\n\nThu May  6 13:21:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_indexes): should not use rb_ary_concat().\n\nThu May  4 12:34:18 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* parse.y (parse_string): there should be newline escape by\n\t  backslashes in strings.\n\n\t* parse.y (parse_qstring): ditto.\n\nMon May  3 04:37:20 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ext/tcltklib/extconf.rb: better search for libX11.\n\n\t* range.c (range_s_new): embarrassing =/== typo.\n\n\t* re.c (Init_Regexp): failed to set default kcode.\n\nMon May  3 02:39:55 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* ext/socket/socket.c (open_inet): typo (res and res0).\n\nTue May  4 02:07:49 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* mkconfig.rb: leave undefined $(VARIABLE) unexpanded in the\n\t  Config::CONFIG hash table.\n\nMon May  3 09:37:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): expand exactn{n} at compile time.\n\t  handles stop_paren specially.\n\n\t* regex.c (re_compile_pattern): expand x{n} at compile time.\n\n\t* regex.c (re_search): posix line match should be checked.\n\n\t* regex.c (re_search): a bug in anchor condition.\n\nFri Apr 30 18:57:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.3.3\n\n\t* string.c (rb_str_rindex): position should be END point, not\n\t  START point.\n\n\t* re.c (rb_reg_search): pos means end point on reverse now.\n\n\t* array.c (rb_ary_s_create): should clear ary->ptr to avoid\n\t  potential gc crash.\n\nFri Apr 30 15:24:58 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/addrinfo.h: compatibility hack for ipv4.\n\n\t* ext/socket/socket.c: itojun's ipv6 patches applied.\n\n\t* ext/socket/extconf.rb: detect ipv6 features based on itojun's\n\t  ipv6 patches.\n\n\t* ext/extmk.rb.in (enable_config): can handle --enable-xxx now.\n\n\t* lib/mkmf.rb (enable_config): ditto.\n\nFri Apr 30 05:22:23 1999  Shugo Maeda  <shugo@netlab.co.jp>\n\n\t* string.c (rb_str_aset): last index should not append.\n\nThu Apr 29 18:55:31 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* dln.c (conv_to_posix_path): remove const from args.\n\n\t* ruby.c (rubylib_mangle): remove Fatal(), the obsolete function.\n\nTue Apr 27 14:11:45 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (fname): lazy workaround for keywords did not work well.\n\n\t* ext/extmk.rb.in: `--with-xxx=yyy' argument configuration.\n\n\t* lib/mkmf.rb: ditto.\n\n\t* misc/ruby-mode.el: forgot to handle $`.\n\n\t* ext/extmk.rb.in: better AIX link support proposed by\n\t  <komatsu@sarion.co.jp>.\n\nMon Apr 26 16:46:59 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/extmk.rb.in: AIX shared library support modified.\n\n\t* ext/aix_mksym.rb: ditto.\n\n\t* configure.in: ditto.\n\n\t* sprintf.c (rb_f_sprintf): should allocate proper sized buffer\n\t  for float numbers.\n\nSat Apr 24 00:00:16 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (operation): syntax like `a.[]=(1,2)' is allowed.\n\nFri Apr 23 23:54:09 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (argf_binmode): binmode method added to ARGF.\n\nFri Apr 23 13:55:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_f_chomp): should assign the result to $_.  or maybe\n\t  sub/gsub/chop/chomp should NOT assign $_ altogether.\n\nThu Apr 22 16:50:54 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_callcc): call scope_dup() for all scopes in\n\t  the interpreter stack.\n\nTue Apr 20 11:24:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_dump): `#' should be escaped.\n\nTue Apr 20 02:32:42 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (parse_regx): option /p for posix match added.\n\n\t* re.c (rb_reg_desc): did not print options properly.\n\n\t* io.c (rb_file_s_open): initialize was called twice.\n\nMon Apr 19 18:56:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* configure.in (DEFAULT_KCODE): can specify default code for\n\t  $KCODE by --with-default-kcode=(euc|sjis|utf8|none).\n\n\t* regex.c (IS_A_LETTER): a byte sequence shorter than mbc should\n\t  not match with \\w etc.\n\nMon Apr 19 13:49:11 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (eval): should restore ruby_dyna_vars.\n\nFri Apr 16 21:40:43 1999  Nobuyoshi Nakada  <gea02117@nifty.ne.jp>\n\n\t* io.c (f_backquote): pipe_open may return nil.\n\n\t* io.c (f_open): rb_io_open may return nil.\n\n\t* io.c (io_s_foreach): ditto.\n\n\t* io.c (io_s_readlines): ditto.\n\n\t* io.c (io_defset): wrong message.\n\nFri Apr 16 15:09:20 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (rb_str2inum): strtoul() returns long, not int.\n\n\t* eval.c (rb_load): size of VALUE and ID may be different.\n\n\t* util.c (mmprepare): int is too small to cast from pointers.\n\n\t* config.guess: avoid 'linux-gnu' for alpha-unknown-linux.\n\nThu Apr 15 23:46:20 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ruby.c (rubylib_mangle): mangle path by RUBYLIB_PREFIX.\n\nWed Apr 14 23:52:51 1999  SHIROYAMA Takayuki  <psi@fortune.nest.or.jp>\n\n\t* node.h (NODE_LMASK): should be long to avoid overflow.\n\nWed Apr 14 13:14:35 1999  Katsuyuki Komatsu  <komatsu@sarion.co.jp>\n\n\t* dln.c: AIX dynamic link.\n\n\t* ext/aix_ld.rb: ditto.\n\nWed Apr 14 12:19:09 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/thread.rb: Queue#{enq,deq} added.\n\nTue Apr 13 17:43:56 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_hash_s_create): Hash::[] acts more like casting.\n\nTue Apr 13 00:33:52 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_stdio_set): warning for assignment to the variables\n\t  $std{in,out,err}.\n\nMon Apr 12 23:12:32 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_reopen): check for reopening same IO.\n\nFri Apr  9 17:45:11 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (rb_compile_string): bug for nested eval().\n\n\t* regex.c (re_match): should pop non-greedy stack items on\n\t  failure, after best_regs are fixed.\n\nThu Apr  8 17:30:40 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (PACK_LENGTH_ADJUST): need to adjust for `*' length.\n\nTue Apr  6 23:28:44 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (void_check): add void context checks.\n\nMon Apr  5 12:23:42 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_s_at): should copy gmt-mode.\n\n\t* eval.c (eval_node): preserve ruby_eval_tree.\n\nFri Apr  2 14:00:34 1999  NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n\n\t* lib/debug.rb: wrong command interpreting.\n\nFri Apr  2 11:46:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.3.2\n\nFri Apr  2 10:40:04 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_s_pipe): forgot to define IO::pipe.\n\nThu Apr  1 14:40:46 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (assign): modified for rhs change.\n\n\t* parse.y (stmt): unparenthesisized method calls can be right hand\n\t  side expression of the assignment.\n\nSat Mar 27 22:42:47 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ext/nkf/nkf.c (rb_nkf_kconv): check size output_ctr before\n\t  decrement.\n\nThu Mar 25 09:11:03 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_s_at): preserve gmt-mode for result.\n\n\t* parse.y (rb_compile_string): do not use cur_mid, use\n\t  compile_for_eval instead.\n\n\t* st.c (PTR_NOT_EQUAL): wrong logical condition.\n\nWed Mar 24 13:06:43 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yycompile): should clear cur_mid after compilation.\n\n\t* io.c (next_argv): need to check type for ARGV.shift.\n\n\t* eval.c (blk_copy_prev): need to preserve outer scope as well as\n\t  outer frames.\n\n\t* parse.y (rb_compile_string): return can appear within eval().\n\nTue Mar 23 10:15:07 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* configure.in: AC_C_CONST check added.\n\nTue Mar 23 02:07:35 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_plus): preserve gmt-mode for result.\n\nMon Mar 22 01:32:37 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): adjust line numbers before expression\n\t  interpolation within strings.\n\n\t* eval.c (rb_eval): defined? returns nil for false condition.\n\n\t* numeric.c (num_nonzero_p): returns nil for false condition.\n\nSat Mar 20 13:07:43 1999  Keiju Ishitsuka  <keiju@rational.com>\n\n\t* lib/weakref.rb: avoid leak for two weakrefs for one object.\n\nFri Mar 19 11:26:45 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* eval.c (ruby_run): needed to eval END{} on exit.\n\n\t* eval.c (rb_exit): ditto.\n\nFri Mar 19 02:17:27 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* signal.c (Init_signal): handles terminating signals HUP, TERM,\n\t  QUIT, PIPE, etc.\n\nThu Mar 18 15:47:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (rb_big_and): bug in sign calculation.\n\n\t* bignum.c (rb_big_or): ditto.\n\n\t* io.c (rb_f_select): forgot to use to_io to retrieve IO, after\n\t  calling select(2).\n\nTue Mar 16 19:54:31 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/extmk.rb.in: static linking cause infinite make loop.\n\nTue Mar 16 18:50:04 1999  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* ext/socket/socket.c (tcp_s_gethostbyname): typo, not NUM2INT(),\n\t  but INT2NUM().\n\n\t* ext/socket/socket.c (mkhostent): ditto.\n\nTue Mar 16 12:31:44 1999  Ryo HAYASAKA  <hayasaka@cheer.u-aizu.ac.jp>\n\n\t* file.c (utime_internal): suppress warning by const.\n\n\t* time.c (time_gmtime): ditto.\n\nTue Mar 16 10:23:05 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_clone): Time object can be cloned.\n\nTue Mar 16 03:13:10 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ruby.c (load_file): argv[argc] should be NULL.\n\nMon Mar 15 22:12:08 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* sprintf.c (rb_f_sprintf): typo in arg_num check at exit.\n\nMon Mar 15 16:42:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_dup): dup2 should copy class too.\n\nMon Mar 15 15:12:53 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* lib/mkmf.rb: install program relative path check.\n\nMon Mar 15 14:05:25 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_s_new): 2nd argument is now option.\n\t  Regexp::EXTENDED can be specified.\n\nFri Mar 12 10:47:49 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_index): str.index(\"\") should always match at\n\t  offset point.\n\n\t* string.c (rb_str_upto): can specify end point exclusion.\n\n\t* string.c (rb_str_index): negative offset.\n\n\t* regex.c (re_match): begline should not match at the point\n\t  between a newline and end-of-string.  endline neither.\n\n\t* regex.c (re_compile_pattern): context_indep_anchors .\n\n\t* parse.y (parse_regx): need not to push backslashes before\n\t  escaped characters.\n\n\t* eval.c (rb_thread_join): re-raises exception within target.\n\nFri Mar 12 01:09:36 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* ext/readline/readline.c (readline_s_vi_editing_mode): wrong\n\t  number of arguments.\n\nFri Mar 12 02:12:50 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (PACK_ITEM_ADJUST): \"a\".unpack(\"C3\") => [97, nil, nil]\n\nThu Mar 11 18:23:50 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* ext/socket/socket.c (Init_socket): UDPsocket was omitted.\n\nThu Mar 11 16:43:30 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (PACK_LENGTH_ADJUST): push fixed number of items per\n\t  template to result array.\n\n\t* pack.c (pack_unpack): I/N/C etc. push nil in the array for \"\".\n\nTue Mar  9 00:19:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (ruby_unsetenv): use ruby_setenv(name, 0).\n\n\t* hash.c (env_delete): ditto.\n\n\t* string.c (rb_str_upto): do not check `beg<end' to generate\n\t  strings for the pattern like \"a\".upto(\"#a\").\n\n\t* range.c (range_each): treat strings as special case.\n\n\t* range.c (range_each): no longer use upto for generic cases.\n\nSun Mar  7 14:21:32 1999  IKARASHI Akira  <ikarashi@itlb.te.noda.sut.ac.jp>\n\n\t* string.c (rb_str_index): wrong end point calculation.\n\nSat Mar  6 02:19:12 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (match_index): MatchingData#index(n) added.\n\n\t* array.c (rb_ary_subseq): ary[n..-1] returns an sub-array unless\n\t  n is too small negative index.\n\n\t* re.c (rb_reg_match_method): Regexp#match(str) added.\n\n\t* array.c (rb_ary_indexes): understands ranges as indexes.\n\n\t* re.c (match_size): MatchingData#size added.\n\nFri Mar  5 01:04:57 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_fill): modified for range.\n\n\t* array.c (rb_ary_aset): a[n..m] revisited.\n\nThu Mar  4 14:23:29 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_subseq): a[n..m] revisited.\n\n\t* parse.y (method_call): allow Const::method{}.\n\n\t* array.c (rb_ary_replace_method): should replace original array.\n\nThu Mar  4 02:30:22 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* configure.in: remove --disable-thread, thread feature is no\n\t  longer optional.\n\nThu Mar  4 00:32:17 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* parse.y (read_escape): wrong arguments for scan_oct,scan_hex.\n\nWed Mar  3 11:51:53 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (Init_socket): rename class names as\n\t  TCPsocket -> TCPSocket etc.\n\nTue Mar  2 19:46:42 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* configure.in (LDSHARED): use gcc -Wl,-G for solaris with gcc.\n\nTue Mar  2 17:04:19 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): backslashes do not concatenate comment lines\n\t  anymore.\n\nMon Mar  1 14:05:12 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_call0): adjust argv for optional arguments.  super\n\t  without arguments emit superclass method with the value from\n\t  optional arguments.  enabled as experiment.\n\nSun Feb 28 14:04:07 1999  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* parse.y (nextc): backslash at the eof cause infinite loop\n\nSun Feb 28 11:01:26 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* time.c (make_time_t): month range check added.\n\nSat Feb 27 02:36:05 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (Init_Regexp): add escape as alias of quote.\n\n\t* re.c (rb_reg_s_quote): char-code can be specified now.\n\nFri Feb 26 18:45:36 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* eval.c (error_print): bug for error message with newlines.\n\nFri Feb 26 12:00:04 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (make_time_t): future check modified to allow 1969-12-31\n\t  at certain timezone.\n\n\t* time.c (time_arg): year >= 1000 should be past.\n\n\t* version.c (Init_version): constant RELEASE_DATE added.\n\nFri Feb 26 01:08:30 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_substr): returns nil for out-of-range access.\n\n\t* array.c (rb_ary_subseq): returns nil for out-of-range access.\n\n\t* array.c (rb_ary_store): negative index message has changed.\n\n\t* string.c (rb_str_aset): reallocation needed.\n\n\t* string.c (rb_str_aset): allow char append to the string.\n\nThu Feb 25 23:30:17 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* time.c (time_load): tm_year should be packed in 17 bits, not 18.\n\nThu Feb 25 12:50:25 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* missing/dup2.c: replaced by public domain version.\n\n\t* time.c (make_time_t): add `future check' in loops.\n\n\t* object.c (rb_num2dbl): forbid implicit conversion from nil, or\n\t  strings.  thus `Time.now + str' should raise error.\n\n\t* object.c (rb_Float): convert nil into 0.0.\n\n\t* object.c (rb_Integer): conversion method improved.\n\nThu Feb 25 03:27:50 1999  Shugo Maeda  <shugo@netlab.co.jp>\n\n\t* eval.c (rb_call): should handle T_ICLASS properly.\n\nThu Feb 25 00:04:00 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* error.c (Init_Exception): global function Exception() removed.\n\n\t* variable.c (rb_class2name): returns \"nil\"/\"true\"/\"false\" for them.\n\n\t* time.c (time_dump): time marshaling format compressed size from\n\t  11 bytes to 8 bytes.  thanx to tadf@kt.rim.or.jp.\n\n\t* eval.c (rb_obj_call_init): should specify arguments explicitly.\n\nWed Feb 24 15:43:28 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): comment concatenation requires preceding space\n\t  before backslash at the end of line.\n\n\t* io.c (rb_f_pipe): global pipe is obsolete now.\n\n\t* object.c (Init_Object): remove true.to_i, false.to_i.\n\nTue Feb 23 14:21:41 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): warn if identifier! immediately followed by `='.\n\nTue Feb 23 12:32:41 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* eval.c (rb_load): tilde expansion moved to find_file.\n\n\t* eval.c (find_file): tilde expansion added.\n\nTue Feb 23 10:50:20 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (require_method): require can handle multiple fnames.\n\n\t* hash.c (rb_hash_foreach_iter): hash key may be nil.\n\nMon Feb 22 17:44:02 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): should not pop failure point on success for\n\t  non-greedy matches.\n\n\t* io.c (Init_IO): remove global_functions getc, readchar, ungetc,\n\t  seek, tell, rewind.\n\nSat Feb 20 22:54:26 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (rb_num2long): no implicit conversion from boolean.\n\nSat Feb 20 09:58:42 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* numeric.c (flo_to_s): portable Infinity and NaN support.\n\nSat Feb 20 07:13:31 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* io.c (rb_file_sysopen): forgot to initialize a local variable.\n\nFri Feb 19 23:05:07 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_subseq): range check changed.\n\n\t* marshal.c: increment MARSHAL_MINOR for Time format change.\n\n\t* time.c (time_old_load): support old marshal format.\n\n\t* time.c (time_load): changed for new format Y/M/D/h/m/s/usec.\n\n\t* time.c (time_dump): marshal dump format has changed.\n\nFri Feb 19 00:25:57 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_arg): should reject \"sep\\0\" and such.\n\n\t* time.c (time_plus): Time#+ should not receive Time object\n\t  operand.\n\n\t* string.c (rb_str_substr): negative length raises exception now.\n\n\t* array.c (beg_len): if end == -1, it points end of the array.\n\n\t* array.c (rb_ary_subseq): negative length raises exception now.\n\nThu Feb 18 20:57:04 1999  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* time.c (rb_strftime): strftime() may return 0 on success too.\n\n\t* time.c (time_strftime): `\\0' within format string should not be\n\t  omitted in the result.\n\n\t* time.c (rb_strftime): zero length format.\n\n\t* time.c (time_to_a): yday start with 1 now.\n\n\t* time.c (time_zone): support for long timezone name.\n\n\t* time.c (time_yday): yday start with 1 now.\n\n\t* time.c (time_minus): minus calculation was wrong.\n\n\t* time.c (time_minus): sec, usec should be at least `long', maybe\n\t  they should be `time_t'.\n\n\t* time.c (time_plus): addition with float was wrong.\n\n\t* time.c (time_to_s): support for long timezone name.\n\n\t* time.c (time_gm_or_local): too far future check moved.\n\n\t* time.c (time_arg): treat 2 digit year as 69-99 => 1969-1999,\n\t  00-68 => 2000-2068\n\nThu Feb 18 03:56:47 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* missing/fnmatch.c: moved to missing directory.\n\nWed Feb 17 16:22:26 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* struct.c (rb_struct_alloc): actual initialization now be done in\n\t  `initialize'.\n\nWed Feb 17 09:47:15 1999  okabe katsuyuki  <hgc02147@nifty.ne.jp>\n\n\t* regex.c (re_search): use mbclen() instead of ismbchar().\n\n\t* re.c (rb_reg_s_quote): should handle mbchars properly.\n\nWed Feb 17 01:25:26 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): stop comment concatenation by backslash follows\n\t  after >= 0x80 char.  may cause problem with Latin chars.\n\n\t* eval.c (error_print): exception in rb_obj_as_string() caused\n\t  SEGV. protect it by PUSH_TAG/POP_TAG.\n\n\t* error.c (exc_exception): `Exception#exception' should return self.\n\nWed Feb 17 01:12:22 1999  Hirotaka Ichikawa  <hirotaka.ichikawa@tosmec.toshiba.co.jp>\n\n\t* configure.in: BeOS patch.\n\nTue Feb 16 14:25:00 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): should reallocate mbc space for\n\t  character class unless current_mbctype is ASCII.\n\nMon Feb 15 15:48:30 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* configure.in: specify `-Wl,-E' only for GNU ld.\n\nMon Feb 15 11:43:22 1999  GOTO Kentaro  <gotoken@math.sci.hokudai.ac.jp>\n\n\t* array.c (rb_inspecting_p): should return Qfalse.\n\nSun Feb 14 22:36:40 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* sprintf.c (rb_f_sprintf): `%G' was omitted.\n\nSun Feb 14 12:47:48 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* numeric.c (Init_Numeric): allow divide by zero on FreeBSD.\n\n\t* numeric.c (Init_Numeric): FloatDomainError added.\n\n\t* configure.in (AC_REPLACE_FUNCS): add checks for functions\n\t  isinf, isnan, and finite.\n\nSat Feb 13 01:24:16 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_create_0): should protect th->thread.\n\nFri Feb 12 16:16:47 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* string.c (rb_str_inspect): wrong mbc position.\n\nFri Feb 12 16:21:17 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_fd_close):\n\n\t* io.c (rb_io_fptr_close): tell scheduler that fd is closed.\n\n\t* io.c (rb_io_reopen): ditto.\n\n\t* io.c (READ_CHECK): check if closed after thread context switch.\n\n\t* ext/socket/socket.c (bsock_close_read): do not check\n\t  the return value from shutdown(2).\n\n\t* ext/socket/socket.c (bsock_close_write): ditto.\n\n\t* ext/socket/socket.c (sock_new): need to dup(fd) for close_read\n\t  and close_write.\n\n\t* parse.y (here_document): handle newlines within #{}.\n\n\t* regex.h: should replace symbols for ruby.\n\nFri Feb 12 00:46:28 1999  Shugo Maeda  <shugo@netlab.co.jp>\n\n\t* marshal.c (r_object): should update the method name in message.\n\n\t* marshal.c (w_object): limit should be converted into Fixnum.\n\nWed Feb 10 15:20:03 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): empty pattern should not cause infinite\n\t  pattern match loop.\n\n\t* regex.c (re_compile_pattern): RE_OPTIMIZE_ANCHOR for /.*/, not\n\t  for /(.|\\n)/.\n\n\t* numeric.c (fix_pow): `fixnum**nil' should raise TypeError.\n\n\t* bignum.c (rb_big_pow): need to normalize results.\n\nWed Feb 10 01:42:41 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* numeric.c (fix_pow): `(5**1).type' should be Integer.\n\nTue Feb  9 01:22:49 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): do not ignore newlines in mbchars.\n\n\t* io.c (rb_file_s_open): mode can be specified by flags like\n\t  open(2), e.g. File::open(path, File::CREAT|File::WRONLY).\n\n\t* io.c (rb_f_open): bit-wise mode flags for pipes\n\n\t* io.c (Init_IO): bit flags for open.\n\nSat Feb  6 22:56:21 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_sub_bang): should not overwrite match data by\n\t  regexp match within the block.\n\n\t* string.c (rb_str_gsub_bang): ditto.\n\nSat Feb  6 03:06:17 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (match_getter): accessing $~ without matching caused SEGV.\n\nFri Feb  5 22:11:08 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* parse.y (yylex): binary literal support, like 0b01001.\n\n\t* parse.y (yylex): octal numbers can contain `_'s.\n\n\t* parse.y (yylex): warns if non-octal number follows immediately\n\t  after octal literal.\n\n\t* parse.y (yylex): now need at least one digit after prefix such\n\t  as 0x, or 0b.\n\n\t* bignum.c (rb_str2inum): recognize binary numbers like 0b0101.\n\nFri Feb  5 03:26:56 1999  Yasuhiro Fukuma  <yasuf@big.or.jp>\n\n\t* ruby.c (proc_options): -e without program prints error.\n\nFri Feb  5 00:01:50 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (terms): needed to clear heredoc_end.\n\n\t* numeric.c (flo_div): allow float division by zero.\n\nThu Feb  4 11:56:24 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* missing/strtod.c: for compatibility.\n\n\t* configure.in (strtod): add strtod compatible check.\n\n\t* numeric.c (rb_num2long): missing/vsnprintf.c does not support\n\t  floating points.\n\n\t* numeric.c (flo_to_s): ditto.\n\nWed Feb  3 23:02:12 1999  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* regex.c (re_compile_pattern): use ismbchar() to get next char.\n\n\t* regex.c (re_search): wrong mbchar shift.\n\n\t* re.c (rb_reg_search): needed to reset $KCODE after match.\n\n\t* regex.c (re_compile_fastmap): mbchars should match with \\w.\n\nWed Feb  3 22:35:12 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* parse.y (yylex): too big float raise warning, not error.\n\nTue Feb  2 23:41:42 1999  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* regex.c (re_match): wrong boundary.\n\n\t* regex.c (IS_A_LETTER): re_mbctab[c] may not be 1 for mbc.\n\n\t* regex.c (re_search): mbchar support for shifting ranges.\n\n\t* regex.c (MBC2WC): wrong conversion.\n\nWed Feb  3 15:03:16 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (parse_regx): need to escape parens if terminators are\n\t  not any kind of parenthesis.\n\n\t* parse.y (parse_qstring): ditto.\n\n\t* parse.y (parse_string): ditto.\n\nTue Feb  2 17:11:26 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* string.c (rb_str_gsub_bang): too small realloc condition.\n\nMon Feb  1 10:01:17 1999  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* parse.y (yylex): range check for the float literal.\n\nSat Jan 30 18:34:16 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (usage): -h option to show brief command description.\n\nSat Jan 30 08:45:16 1999  IKARASHI Akira  <ikarashi@itlb.te.noda.sut.ac.jp>\n\n\t* lib/cgi-lib.rb: cookie support added.\n\nSat Jan 30 13:38:24 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): mbchars should match with \\w\n\t  within character class.  Was matching with \\W.\n\n\t* regex.c (re_match): \\w should match with multi byte characters,\n\t  not its first byte.\n\nSat Jan 30 10:06:41 1999  Yoshida Masato  <yoshidam@yoshidam.net>\n\n\t* re.c (rb_reg_s_new): UTF-8 flag handle (/u, /U).\n\n\t* re.c (rb_kcode): $KCODE handle for UTF-8.\n\nSat Jan 30 01:51:16 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_delete_if): RTEST() missing.\n\n\t* hash.c (delete_if_i): ditto.\n\n\t* enum.c (Init_Enumerable): select (=find_all), detect (=find)\n\t  added as aliases.\n\nFri Jan 29 21:32:19 1999  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* hash.c (rb_f_setenv): SEGV caused by small typo.\n\nFri Jan 29 00:15:58 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/parsedate.rb (parsedate): support date format like\n\t  23-Feb-93, which is required by HTTP/1.1.\n\n\t* variable.c (find_class_path): avoid calling rb_iv_set().\n\n\t* eval.c (backtrace): do not need to modify $SAFE internally.\n\n\t* variable.c (classname): inline __classid__ access.\n\n\t* eval.c (THREAD_ALLOC): needed to initialize wrapper.\n\n\t* lib/ftools.rb (makedirs): allows slash at the end of the path.\n\n\t* numeric.c (rb_fix_induced_from): ensure result to be Fixnum.\n\nThu Jan 28 17:31:43 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (flo_to_s): float format changed to \"%16.10g\".\n\nThu Jan 28 02:13:11 1999  Yoshinori Toki  <toki@freedom.ne.jp>\n\n\t* array.c (rb_ary_store): expand allocated buffer by 3/2.\n\nWed Jan 27 17:50:02 1999  Kazuhiro HIWADA  <hiwada@kuee.kyoto-u.ac.jp>\n\n\t* bignum.c (dbl2big): raised error if double is too big to cast\n\t  into long.  check added.\n\nWed Jan 27 03:16:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_mod_const_at): can't list constants of the\n\t  untainted objects in safe mode.\n\n\t* class.c (method_list): can't list methods of untainted objects\n\t  in safe mode.\n\nTue Jan 26 02:40:41 1999  GOTO Kentaro  <gotoken@math.sci.hokudai.ac.jp>\n\n\t* prec.c: Precision support for numbers.\n\nThu Jan 21 19:08:14 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_f_raise): calls `exception' method, not `new'.\n\n\t* error.c (exc_exception): renamed from `new'.\n\nWed Jan 20 03:39:48 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yycompile): rb_in_compile renamed to ruby_in_compile.\n\n\t* ruby.c (load_file): define DATA if __END__ appeared in script.\n\nTue Jan 19 14:57:51 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (here_document): need to protect lex_lastline.\n\n\t* parse.y (yylex): disable %//, %'', %``.\n\nTue Jan 19 05:01:16 1999  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* array.c (beg_len): round range value too much.\n\nMon Jan 18 13:02:27 1999  Kuroda Jun  <jkuro@dwe.co.jp>\n\n\t* hash.c (env_keys): strchr() may return NULL.\n\nMon Jan 18 17:51:47 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* instruby.rb (wdir): install libruby.a in archdir.\n\n\t* lib/ftools.rb (install): removes file before installing.\n\nMon Jan 18 16:55:31 1999  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* eval.c (rb_callcc): experimental continuation support.\n\nSun Jan 17 19:45:37 1999  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* pack.c (pack_pack): nil packing caused SEGV.\n\nSat Jan 16 13:18:03 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_concat): character (fixnum) can be append to\n\t  strings\n\n\t* array.c (rb_ary_unshift): unshift returns array.\n\nSat Jan 16 01:39:19 1999  Yoshida Masato  <yoshidam@tau.bekkoame.ne.jp>\n\n\t* string.c (rb_str_split_method): UTF-8 support.\n\n\t* regex.c: UTF-8 support.\n\nThu Jan 14 00:42:55 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_gsub_bang): forget to add offset for null match.\n\n\t* eval.c (rb_thread_local_aset): can't modify in tainted mode.\n\n\t* hash.c (env_each_key): avoid generating temporary array.\n\nWed Jan 13 23:58:50 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_f_setenv): name and value can be tainted.\n\nWed Jan  6 02:42:08 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (Init_Bignum): forgot to define Bignum#===.\n\n\t* gc.c (gc_sweep): if add_heap() is called during GC, objects on\n\t  allocated heap page(s) are not marked, should not be recycled.\n\n\t* gc.c (gc_sweep): should refer latest freelist.\n\n\t* gc.c (id2ref): modified to support performance patch.\n\n\t* object.c (rb_obj_id): performance patch (no bignum for id).\n\nTue Jan  5 01:56:18 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* config.guess: merge up-to-date from autoconf 2.12.\n\n\t* array.c (rb_ary_join): avoid calling rb_protect_inspect() till\n\t  it is really needed.\n\n\t* object.c (rb_obj_inspect): show detailed information for the\n\t  instance variables (infinite loop can avoid now).\n\n\t* struct.c (rb_struct_inspect): avoid infinite loop.\n\nSun Jan  3 01:37:58 1999  Takao KAWAMURA  <kawamura@ike.tottori-u.ac.jp>\n\n\t* misc/ruby-mode.el (ruby-end-of-defun): moved too much.\n\n\t* misc/ruby-mode.el (ruby-mode-variables): set paragraph-separator\n\t  for the mode.\n\n\t* misc/ruby-mode.el: proper font-lock for `def' and `nil' etc.\n\nSat Jan  2 17:09:06 1999  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_jump_tag): new api to invoke JUMP_TAG.  tag values\n\t  can obtained from rb_eval_string_protect()/rb_load_protect().\n\n\t* eval.c (rb_rescue): now catches all exceptions but SystemExit.\n\n\t* eval.c (rb_eval_string_protect): eval string with protection.\n\n\t* eval.c (rb_load_protect): load file with protection.\n\n\t* io.c (rb_io_puts): avoid infinite loop for cyclic arrays.\n\n\t* eval.c (rb_thread_local_aref): thread local hash tables.\n\n\t* object.c (rb_equal): check exact equal before calling `=='.\n\nThu Dec 31 22:28:53 1998  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* eval.c (rb_f_require): feature names should be provided with\n\t  DLEXT extension.\n\n\t* marshal.c (Init_marshal): need to provide `marshal.so'.\n\nWed Dec 30 02:29:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (classname): do not call rb_ivar_set().\n\n\t* eval.c (ruby_run): finalizers were called too early.\n\nFri Dec 25 12:19:30 1998  Fukuda Masaki  <fukuda@wni.co.jp>\n\n\t* gc.c (rb_gc_mark): should not return on FL_EXIVAR.\n\nFri Dec 25 11:56:51 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (gc_mark): proper scanning for temporary region.\n\n\t* eval.c (TMP_ALLOC): protection for C_ALLOCA was broken.\n\nThu Dec 24 18:26:04 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* development version 1.3 released.\n\nThu Dec 24 00:17:00 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_load): top self should be set properly.\n\n\t* variable.c (classname): check __classpath__ if it is defined.\n\n\t* variable.c (classname): invalid warning at -v with static linked\n\t  ruby interpreter.\n\n\t* eval.c (is_defined): modified for expr::Const support.\n\n\t* eval.c (rb_eval): invoke method expr::Const if expr is not class\n\t  nor module.\n\n\t* parse.y (primary): enable expr::identifier as method\n\t  invocation.\n\nWed Dec 23 03:04:36 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): avoid too many loop pops for (?:..).\n\nTue Dec 22 18:01:08 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental version 1.1d1 released.\n\nMon Dec 21 01:33:03 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (TMP_PROTECT): add volatile to ensure GC protection.\n\n\t* string.c (rb_str_gsub_bang): calculate buffer size properly.\n\n\t* parse.y (lex_get_str): needed to return Qnil at EOS.\n\n\t* eval.c (find_file): check policy modified, raise exception\n\t  immediately for tainted load_path.\n\n\t* hash.c (rb_f_setenv): do not depend on setenv() nor putenv().\n\nThu Dec 17 06:29:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/tk/tkutil.c (tk_s_new): use rb_obj_instance_eval(), instead\n\t  of rb_yield_0().\n\n\t* eval.c (rb_f_require): forgot to call find_file in some cases.\n\n\t* eval.c (rb_f_require): `require \"feature.so\"' to load dynamic\n\t  libraries.  old `require \"feature.o\"' is still OK.\n\n\t* eval.c (rb_eval): yield without value dumped core.\n\nWed Dec 16 16:28:31 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental version 1.1d0 (pre1.2) released.\n\nWed Dec 16 10:43:34 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): bound check before calling re_match().\n\nTue Dec 15 13:59:01 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* error.c (exc_to_s): returns class name for unset mesg.\n\n\t* error.c (exc_initialize): do not initialize @mesg by \"\".\n\n\t* parse.y (nextc): __END__ should handle CR+LF newlines.\n\nWed Dec  9 13:37:12 1998  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* pack.c (encodes): use buffering for B-encoding.\n\n\t* pack.c (pack_pack): Q-encoding by 'M'.\n\nTue Dec  8 14:10:00 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (generic_ivar_get): any object can have instance\n\t  variables now.  great improvement.\n\n\t* variable.c (rb_name_class): do not set __classpath__ by default,\n\t  use __classid__ instead.\n\nMon Dec  7 22:08:22 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.h (struct RFile): IO objects can have instance variables now.\n\n\t* parse.y (primary): allows `def obj::foo; .. end'.\n\nMon Dec  7 18:24:50 1998  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* ruby.c (set_arg0): $0 support for HP-UX.\n\nMon Dec  7 01:30:28 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* dln.c (dln_strerror): better error messages on win32.\n\nSat Dec  5 23:27:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (here_document): indentable here-doc delimiter by\n\t  `<<-'.  Proposed by Clemens <c.hintze@gmx.net>.  Thanks.\n\nThu Dec  3 16:50:17 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/extmk.rb.in (realclean): trouble on install.\n\nSun Nov 29 22:25:39 1998  Takaaki Tateishi  <ttate@jaist.ac.jp>\n\n\t* process.c (f_exec): check number of argument.\n\nThu Nov 26 17:27:30 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c9 released.\n\nWed Nov 25 13:07:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_dup): do not copy additional data (STR_NO_ORIG).\n\n\t* parse.y (yycompile): reduce known memory leak (hard to remove).\n\nWed Nov 25 03:41:21 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* st.c (st_init_table_with_size): round size up to prime number.\n\nSat Nov 21 23:27:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (rb_hash_aset): reduce copying key strings.\n\n\t* gc.c (looks_pointerp): declare as inline function if possible.\n\n\t* st.c (PTR_NOT_EQUAL): compare hash values first before calling\n\t  comparing function.\n\n\t* st.c (ADD_DIRECT): save hash value in entries to reduce hash\n\t  calculation.\n\n\t* string.c (rb_str_gsub_bang): avoid rb_scan_args() to speed-up.\n\n\t* string.c (rb_str_sub_bang): ditto.\n\nSat Nov 21 18:44:06 1998  Masaki Fukushima  <fukusima@goto.info.waseda.ac.jp>\n\n\t* time.c (time_s_now): had memory leak.\n\n\t* ext/md5/md5init.c (md5_new): had memory leak.\n\n\t* ext/md5/md5init.c (md5_clone): ditto.\n\nFri Nov 20 23:23:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/delegate.rb: do not propagate hash and eql?.\n\nThu Nov 19 01:40:52 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sample/ruby-mode.el (ruby-expr-beg): failed to find reserved\n\t  word boundary.\n\n\t* eval.c (rb_eval): avoid calling `concat' method.  calls\n\t  rb_ary_concat() directly for efficiency.\n\n\t* eval.c (rb_eval): actual rest arguments extended arrays too much.\n\nWed Nov 18 14:30:24 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (rb_define_global_function): global functions now be\n\t  module function of the Kernel.\n\nWed Nov 18 10:48:09 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (read_all): SEGV on large files.\n\nTue Nov 17 18:11:20 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c8 released.\n\nTue Nov 17 16:58:47 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (arg): assignment to attribute name start with capital\n\t  should be allowed.\n\n\t* eval.c (thread_alloc): needed to mark terminated threads too.\n\nTue Nov 17 12:33:48 1998  Motoyuki Kasahara  <m-kasahr@sra.co.jp>\n\n\t* ext/extmk.rb.in (create_makefile): Set `libdir' to `@libdir@',\n\t  Set `pkglibdir' to `$libdir/$(RUBY_INSTALL_NAME)'.\n\nTue Nov 17 10:30:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (f_sprintf): %l%%c -> %%l%c\n\nTue Nov 17 01:08:50 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (ret_args): distinguish `a' and `*a' for the arguments\n\t  of yield and return.\n\n\t* eval.c (rb_eval): flip3 should work like sed.\n\n\t* eval.c (rb_eval): flip{2,3} now have independent state for each\n\t  scope to work fine with thread.\n\nMon Nov 16 23:26:29 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (primary): exec else clause if no exception raised.\n\nSun Nov 15 15:44:07 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* ext/extmk.rb.in (install): bug in target.\n\nSat Nov 14 11:02:05 1998  Motoyuki Kasahara  <m-kasahr@sra.co.jp>\n\n\t* Makefile.in (install): Give the argument `$(DESTDIR)' to\n\t  `instruby.rb'.\n\n\t* instruby.rb: Recognize ARG[0] as `destdir'.\n\n\t* instruby.rb: Give the argument `destdir' to `extmk.rb'.\n\n\t* ext/extmk.rb.in: Recognize ARG[1] as `$destdir'.\n\n\t* instruby.rb: Create the installation directories (bindir, libdir,\n\t  archdir, pkglibdir, archdir, and mandir) under `destdir', and\n\t  install all files under there.\n\n\t* ext/extmk.rb.in: Likewise.\n\nSat Nov 14 10:56:55 1998  Motoyuki Kasahara  <m-kasahr@sra.co.jp>\n\n\t* instruby.rb: Add the variable `pkglibdir'.\n\n\t* instruby.rb: Set the variable `libdir' to `$(libdir)', not\n\t  `$(libdir)/$(ruby_install_name)'. `libruby.so' and `libruby.so.LIB'\n\t  are installed at `libdir'.\n\n\t* instruby.rb: Set the variable `archdir' to `$(pkglibdir)/$(arch)'.\n\nFri Nov 13 19:43:29 1998  KIMURA Koichi  <kbk@kt.rim.or.jp>\n\n\t* missing/nt.c (SafeFree): wrong free offset.\n\nThu Nov 12 20:11:53 1998  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* sample/ruby-mode.el: wrong highlight.\n\n\t* parse.y (parse_regx): newline in regexp was ignored.\n\nWed Nov 11 10:54:57 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (here_document): <<'FOO' should not escape anything.\n\n\t* parse.y (here_document): bare << here-doc available, even though\n\t  it's deprecated.\n\n\t* file.c (rb_file_s_readlink): return value should be tainted.\n\n\t* ext/etc/etc.c (setup_passwd): information (eg. GCOS name) should\n\t  be tainted (modified at Perl Conference).\n\nTue Nov 10 00:22:11 1998  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* configure.in: elf support for FreeBSD 3.x\n\nTue Nov 10 00:05:43 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): here document available in eval.\n\nMon Nov  9 17:55:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c7 released.\n\nFri Nov  6 19:25:27 1998  Takao KAWAMURA  <kawamura@ike.tottori-u.ac.jp>\n\n\t* sample/ruby-mode.el: font-lock patch.\n\nThu Nov  5 15:42:22 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sample/README, lib/README: simple description for each file.\n\nWed Nov  4 18:14:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (assign): attribute assignment should be called as public.\n\nTue Nov  3 23:36:39 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_dump): dumps core for negative char value.\n\n\t* regex.c (re_compile_pattern): out of boundary access for empty\n\t  regexp.\n\nMon Nov  2 22:54:01 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_aset): `str[str]' replaces first match.\n\nMon Nov  2 18:24:33 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_create): was accessing modified status.\n\nSun Nov  1 01:18:52 1998  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* gc.c (xrealloc): size 0 needs round up to 1.\n\nSat Oct 31 23:18:34 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_split_method): negative LIMIT means number of\n\t  split fields are unlimited, as in perl.\n\n\t* string.c (rb_str_split_method): if LIMIT is unspecified,\n\t  trailing null fields are stripped.\n\nSat Oct 31 04:16:14 1998  Inaba Hiroto  <inaba@st.rim.or.jp>\n\n\t* string.c (str_aref): regexp index SEGVed.\n\nFri Oct 30 14:33:47 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (reg_match): returns nil for unmatch.\n\n\t* dir.c (dir_entries): new method.\n\n\t* eval.c (block_pass): do not push block, substitute it.\n\nFri Oct 30 01:28:52 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* range.c (range_check): avoid <=> check for Fixnums.\n\n\t* array.c (rb_ary_aset): accept negative index.\n\nWed Oct 28 22:00:54 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): access out of boundary fixed.\n\nWed Oct 28 11:37:42 1998  TAMITO  <tommy@valley.ne.jp>\n\n\t* io.c (f_select): fd number comparison bug.\n\nTue Oct 27 23:07:11 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sample/ruby-mode.el (ruby-parse-region): forgot to support %w()\n\t  style array literal.\n\n\t* eval.c (rb_eval): unused block raises warning.\n\nMon Oct 26 09:37:53 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (dvar_asgn_push): dvar pushed too many times if\n\t  variable-in-block first appear in loops.\n\nSun Oct 25 22:59:27 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (set_list_bits): was using wrong offset.\n\nThu Oct 22 00:07:11 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_obj_method): method retrieved from tainted object\n\t  should be tainted too.\n\n\t* eval.c (method_call): safe_level should be restored during\n\t  Method#call.\n\nWed Oct 21 14:21:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (Init_IO): new constants IO::SEEK_{SET,CUR,END}.\n\n\t* io.c (rb_f_ungetc): ungetc pushes a char back into STDIN.\n\nMon Oct 19 11:50:00 1998  Motoyuki Kasahara  <m-kasahr@sra.co.jp>\n\n\t* ext/extmk.rb: Load '@top_srcdir@/lib/find.rb', not\n\t  '../lib/find.rb'.\n\n\t* ext/extmk.rb: Distinguish between `top_srcdir' and `topdir'.\n\n\t* Makefile.in (CFLAGS): Add `-I.'.\n\n\t* Makefile.in (lex.c): Give `@srcdir@/keywords' to gperf, not\n\t  `keywords'.\n\n\t* instruby.rb: Use `CONFIG[\"bindir\"]', instead of `prefix + \"/bin\"'.\n\n\t* instruby.rb: Use `CONFIG[\"libdir\"]', instead of `prefix + \"/lib\"'.\n\n\t* instruby.rb Use `CONFIG[\"mandir\"]', instead of `prefix + \"/man\"'.\n\n\t* instruby.rb (wdir): Add the variable to preserve the current\n\t  working directory.\n\n\t* instruby.rb: Chdir to wdir before install `config.h' and\n\t  `rbconfig.rb'.\n\nMon Oct 19 10:07:01 1998  EGUCHI Osamu  <eguchi@shizuokanet.ne.jp>\n\n\t* eval.c (rb_eval): reduce recursive calls to rb_eval().\n\nFri Oct 16 15:31:45 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_new_internal): timeval must be positive.\n\nThu Oct 15 13:54:48 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (arg): local variables can be accessed within right side\n\t  expression in assignment, notably in blocks.\n\nWed Oct 14 00:18:33 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (Init_Array): Array#=== is now for equal check, not\n\t  inclusion check.\n\n\t* parse.y (when_args): `when a, *b' style new syntax for array\n\t  expansion in `case'.\n\nTue Oct 13 14:30:32 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (rb_obj_untaint): taint marks can be unset.\n\n\t* eval.c (rb_eval): taint propagation for embedded strings.\n\nMon Oct 12 13:27:15 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_call0): check stack depth more frequently.\n\nMon Oct 12 08:08:30 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_p): can print even in secure mode.\n\nSun Oct 11 22:50:13 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (rb_const_set): taint check for modification.\n\n\t* variable.c (rb_ivar_set): taint check for modification.\n\n\t* string.c (rb_str_modify): taint check for modification.\n\n\t* hash.c (rb_hash_modify): taint check for modification.\n\n\t* array.c (rb_ary_modify): taint check for modification.\n\n\t* ruby.h (FL_TAINT): taint for all objects, not only strings.\n\nFri Oct  9 17:01:14 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (read_all): read() returns \"\" at immediate EOF.\n\n\t* io.c (io_read): read(nil) read all until EOF.\n\nThu Oct  8 13:32:13 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_dump): marshal can dump Time object now.\n\n\t* marshal.c (Init_marshal): rename marshal methods `_dump_to' to\n\t  `_dump', `_load_from' to `_load'.\n\n\t* parse.y (rb_intern): \"+=\".intern generates proper symbol.\n\nMon Oct  5 18:31:53 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c6 released.\n\nFri Oct  2 14:22:33 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): `/\\s*(--)$/ =~ \"- --\"' did not match,\n\t  because of wrong optimize condition.\n\nMon Oct  1 01:55:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (rb_intern): should not raise exceptions.\n\n\t* parse.y (yylex): symbol like `:foo?=' should not be allowed.\n\n\t* ext/extmk.rb.in: makes *.a for static link modules.\n\nWed Sep 30 14:13:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_start): supports making a subclass of the\n\t  Thread class.\n\nTue Sep 29 17:46:01 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_thread_join): join is now an instance method.\n\nFri Sep 25 12:01:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): `@foo!' should be an error.\n\nThu Sep 24 14:55:06 1998  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* ext/etc/etc.c (Init_etc): wrong field definition.\n\nThu Sep 17 17:09:05 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_reopen): was creating FILE* for wrong fd.\n\nTue Sep 15 05:28:11 1998  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* regex.c (re_compile_pattern): forgot to fixup for the pattern\n\t  like (?=(A)|(B)).\n\nTue Sep 15 01:06:08 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (rb_io_gets_internal): do not set $_ by default, only\n\t  gets/readline set the variable.\n\n\t* eval.c (rb_f_load): load toplevel class is set to anonymous\n\t  module if safe_level >= 5, to encapsulate modification.\n\n\t* eval.c (rb_f_load): set frame properly.\n\n\t* string.c (rb_str_each_line): do not set $_.\n\nMon Sep 14 14:42:27 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): beginning and end of the string, do not\n\t  automatically match `\\b'.\n\n\t* string.c (scan_once): consume at least on character.\n\n\t* regex.c (re_search): wrong behavior for negative range.\n\nSat Sep 12 21:21:26 1998  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* regex.c (re_search): range value should be maintained.\n\nThu Sep 10 10:55:00 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (backref_error): yyerror does not understand formats.\n\nTue Sep  8 18:05:33 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c5 released.\n\nTue Sep  8 10:03:39 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_each_line): wrong line splitting with newline at\n\t  top of the string.\n\n\t* string.c: non bang methods return copied string.\n\n\t* eval.c (f_END): needed to initialize frame->argc;\n\nFri Sep  4 11:27:40 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (bigadd): proper sign combination.\n\n\t* regex.c (re_search): wrong return value for \\A.\n\nThu Sep  3 14:08:14 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c4 released.\n\nTue Sep  1 10:47:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (slow_search): do not compare llen and blen.  llen may\n\t  be longer than blen, if little contains 0xff.\n\n\t* regex.c (mbctab_euc): set 0x8e as multibyte character.\n\n\t* string.c (str_inspect): mask character for octal output.\n\nMon Aug 31 15:32:41 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): use calculated offset if exactn is the\n\t  first opcode in the compiled regexp.\n\n\t* regex.c (bm_search): use Boyer-Moore search for simple search.\n\n\t* regex.c (must_instr): wrong length check if pattern includes\n\t  byte escape by 0xff.\n\n\t* regex.c (re_compile_pattern): need not to check current_mbctype.\n\nSat Aug 29 16:31:40 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_check_safe_str): avoid calling rb_id2name() in normal\n\t  cases to speed-up.\n\n\t* eval.c (thread_raise): do not save context of terminated thread.\n\n\t* regex.c (re_compile_pattern): mask \\nnn over 256.\n\nSat Aug 29 02:09:46 1998  Koji Arai  <JCA02266@nifty.ne.jp>\n\n\t* sprintf.c (f_sprintf): wrong buffer size check.\n\nFri Aug 28 01:57:04 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): accepts (?ix-ix) and (?ix-ix:...).\n\nFri Aug 28 12:25:33 1998  Hiroshi Igarashi  <igarashi@ueda.info.waseda.ac.jp>\n\n\t* ruby.c (ruby_require_modules): load modules in appearing order.\n\nFri Aug 28 01:57:04 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): accepts (?ix-ix) and (?ix-ix:...).\n\nThu Aug 27 12:54:28 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c3 released.\n\nWed Aug 26 14:40:56 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): check whether ruby_class is properly set,\n\t  before accessing it.\n\n\t* eval.c (rb_obj_instance_eval): ruby_class should be Qnil for\n\t  special objects like Fixnums.\n\n\t* ext/tkutil/tkutil.c (Init_tkutil): removes calls to\n\t  rb_yield_0().  used instance_eval() instead in the tk.rb.\n\nWed Aug 26 11:47:00 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): pop non-greedy stack elements on success.\n\nWed Aug 26 09:25:35 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ruby.h: add #define environ for cygwin32.\n\nTue Aug 25 08:57:41 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (rb_ary_sort_bang): temporarily freeze sorting array.\n\nMon Aug 24 18:46:44 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* dln.c (dln_find_1): path check was too strict.\n\nMon Aug 24 15:28:11 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* parse.y (f_arglist): opt_nl added after f_args.\n\nFri Aug 21 01:06:01 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c: grand renaming on socket.c.\n\n\t* ext/socket/socket.c (inet_aton): supply inet_aton for those\n\t  systems that do not have it.\n\n\t* ext/socket/socket.c (setipaddr): use inet_aton instead of\n\t  inet_addr.\n\n\t* ext/socket/socket.c (tcp_s_gethostbyname): new method: works\n\t  like Socket.gethostbyname but returning array contains ip-addrs\n\t  as octet decimal string format like \"127.0.0.1\".\n\n\t* ext/socket/socket.c (mkhostent): return format changed to\n\t  [host, aliases, type, ipaddr..]  as documented.\n\nWed Aug 19 00:31:09 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_ctl): forgot to place TRAP_END at right position.\n\nFri Aug 14 11:01:47 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (call_trace_func): save __FILE__, __LINE__ before\n\t  executing trace_func, since trace function should not corrupt\n\t  line number information.\n\nThu Aug 13 15:09:02 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (ary_s_new): was marking unallocated region on GC.\n\nTue Aug 11 11:57:35 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c2 released.\n\nMon Aug 10 14:05:30 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* process.c (f_system): removed fflush(stdin).\n\nFri Aug  7 17:44:44 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* error.c (err_snprintf): replace sprintf for fixed sized buffer,\n\t  with snprintf to avoid buffer over-run.  For systems which does\n\t  dot provide snprintf, missing/snprintf.c added.\n\nWed Aug  5 00:47:35 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (rb_reg_search): recycle match object.\n\nMon Aug  3 09:17:55 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (rb_str_gsub_bang): do not allocate temporary string.\n\n\t* string.c (rb_str_sub_bang): use inline replace.\n\nWed Jul 29 00:36:08 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (hash_s_new): the default value can be specified.\n\n\t* hash.c (hash_default): method to set the default value.\n\n\t* hash.c (hash_aref): now returns the default value.\n\nTue Jul 28 13:03:25 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (ary_s_new): argument to specify initial value is added.\n\n\t* array.c (ary_s_new): specifies size, not capacity.\n\nMon Jul 27 12:39:34 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_replace): zero fill for expansion gap.\n\n\t* regex.c (mbctab_euc): set flags on for 0xA1-0xFE.  suggested by\n\t  <inaba@st.rim.or.jp>.\n\n\t* string.c (str_inspect): consider current_mbctype.\n\nSun Jul 26 15:37:11 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* array.c (ary_s_new): Array.new(1<<30) dumps core.\n\nFri Jul 24 13:40:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c1 released.\n\nFri Jul 24 02:10:22 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (r_bytes2): allocated buffer size was too short.\n\n\t* marshal.c (w_object): saves all options, not only casefold flag.\n\n\t* re.c (reg_clone): now copies options properly.\n\n\t* re.c (reg_get_kcode): code number was wrong.\n\nThu Jul 23 13:11:32 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_attr): argument should be symbol or string.\n\nWed Jul 22 11:59:34 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (calculate_must_string): wrong offset added.\n\nWed Jul 22 11:59:59 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* st.c (rehash): still had a GC problem.  fixed.\n\nTue Jul 21 13:19:30 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (gc_mark_threads): crashed on GC before thread allocation.\n\n\t* st.c (rehash): GC during rehash caused SEGV.\n\nTue Jul 21 01:25:10 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (f_sprintf): integer formatter totally re-written.\n\n\t* sprintf.c (remove_sign_bits): support uppercase hexadecimal.\n\nSat Jul 18 00:14:13 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (f_sprintf): proper sign position for %X and %O.\n\nFri Jul 17 14:10:20 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1c0 released.\n\nFri Jul 17 08:01:49 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* process.c (f_exec): Check_SafeStr() added.\n\n\t* process.c (f_system): Check_SafeStr() moved before fork().\n\nThu Jul 16 22:58:48 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (scan_once): substrings to the block should not be\n\t  tainted.  use reg_nth_match(), not str_substr().\n\n\t* string.c (str_substr): needed to transfer taint.\n\nThu Jul 16 16:15:57 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* gc.c (xmalloc): object allocation count added to GC trigger.\n\n\t* eval.c (thread_save_context): avoid marking uninitialized stack\n\t  in thread_mark.  GC may be triggered by REALLOC_N().\n\nWed Jul 15 15:11:57 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_31.\n\nWed Jul 15 15:05:27 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_create): exit() and abort() in threads now\n\t  forwarded to main_thread.\n\nTue Jul 14 14:03:47 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (obj_instance_variables): list names that is not\n\t  instance variables.\n\n\t* gc.c (GC_MALLOC_LIMIT): choose smaller limit value.\n\nMon Jul 13 12:39:38 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (str2cstr): should not return NULL.\n\nFri Jul 10 11:51:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (gettable): needed to add dyna_in_block() check.\n\nThu Jul  9 17:38:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_30.\n\nThu Jul  9 16:01:48 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sprintf.c (fmt_setup): format specifier for long needed.\n\n\t* sprintf.c (f_sprintf): ditto.\n\n\t* numeric.c (fix2str): ditto.\n\n\t* eval.c (thread_create): no more ITIMER_REAL.\n\n\t* eval.c (thread_create): thread finalization needed before\n\t  aborting thread if thread_abort is set.\n\nWed Jul  8 18:17:33 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (big_pow): abandon power by bignum (too big).\n\nTue Jul  7 13:58:43 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_catch): add C level catch/throw feature.\n\nMon Jul  6 15:18:09 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (arg): proper return values for `||=' and `&&='.\n\nFri Jul  3 16:05:11 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_29.\n\nFri Jul  3 11:20:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (r_byte): byte should not extend sign bit.\n\n\t* numeric.c (fix_mul): use FIX2LONG() instead of FIX2INT() for\n\t  64bit architectures.\n\n\t* marshal.c (r_bytes): remove weird casting between pointer and int.\n\n\t* process.c (proc_setsid): new method Process#setsid().\n\nThu Jul  2 12:49:21 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* marshal.c (w_object): remove `write_bignum' label for 64bit\n\t  architectures.\n\n\t* marshal.c (r_bytes): needs int, not long.\n\nWed Jul  1 14:21:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (flo_plus): should not allow addition with strings.\n\nWed Jul  1 13:09:01 1998  Keiju ISHITSUKA  <keiju@rational.com>\n\n\t* numeric.c (num_uminus): wrong coerce direction.\n\nTue Jun 30 10:13:44 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (f_p): accepts arbitrary number of arguments.\n\n\t* eval.c (rb_yield_0): there's some case that iterator_p() returns\n\t  true even if the_block was not set.  check added.\n\nTue Jun 30 01:05:20 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (BEGIN_CALLARGS): adjust the_block before evaluating the\n\t  receiver's value and the arguments.\n\nFri Jun 26 18:02:50 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_28.\n\nFri Jun 26 11:01:26 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* string.c (str_aset_method): needed to convert to string.\n\nThu Jun 25 02:05:50 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): optimize for `.*' at beginning of the\n\t  pattern.\n\n\t* regex.c (re_search): optimize for character class repeat at\n\t  beginning of the pattern.\n\n\t* regex.c (re_compile_pattern): detect optimization potential for\n\t  the compiled patterns.\n\nThu Jun 25 00:02:26 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* re.c (reg_s_new): flag value was wrong.\n\nWed Jun 24 23:45:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_search): wrong anchor handling for reverse search.\n\nWed Jun 24 02:18:57 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (mlhs): `((a,b)),c = [[1,2]],3' assigns a=1,b=2,c=3.\n\nTue Jun 23 11:46:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): `&&=' and `||=' added.\n\nSat Jun 20 02:53:50 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (assignable): nesting local variables should have higher\n\t  priority than normal local variables for assignment too.\n\nFri Jun 19 18:28:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_27.\n\nFri Jun 19 14:34:49 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (assign): support hack for nested multiple assignment.\n\n\t* parse.y (mlhs): nested multiple assignment.\n\n\t* eval.c (rb_eval): in-block variables now honors static scope.\n\n\t* configure.in: RSHIFT check moved to configure.\n\nThu Jun 18 16:46:04 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_26.\n\nThu Jun 18 13:37:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (file_s_ftype): uses lstat(2) instead of stat(2).\n\n\t* dir.c (dir_s_glob): there can be buffer overrun, check added.\n\n\t* eval.c (f_binding): handles in-block variables declared after\n\t  binding's generation.\n\n\t* numeric.c (flo_floor): floor, ceil, round added to Float.\n\nWed Jun 17 11:20:00 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (gettable): nesting local variables should have higher\n\t  priority than normal local variables.\n\nTue Jun 16 12:30:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (str2inum): handles `+ddd'.\n\n\t* struct.c (make_struct): name parameter can be nil for unnamed\n\t  structures.\n\nMon Jun 15 16:30:10 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (class_s_inherited): prohibiting to make subclass of\n\t  class Class.\n\n\t* object.c (module_s_new): support for making subclass of Module.\n\n\t* parse.y (yycompile): clear eval_tree before compiling.\n\nFri Jun 12 17:58:18 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (eval): write back the_dyna_var into the block.\n\nThu Jun 11 18:19:18 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_25.\n\n\t* eval.c (dvar_add_compiling): register dyna_var at compile time.\n\n\t* regex.c (re_compile_pattern): RE_DUP_MAX iteration is too big.\n\nWed Jun 10 15:12:04 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_eof): do not block other threads.\n\n\t* signal.c (trap): reserve SIGALRM for thread.\n\n\t* eval.c (thread_create): use ITIMER_REAL also to avoid system\n\t  call blocking.\n\n\t* io.c (f_syscall): add TRAP_BEG, TRAP_END around system calls.\n\n\t* io.c (io_ctl): add TRAP_BEG, TRAP_END around system calls.\n\n\t* enum.c (enum_collect): did not collect false values.\n\n\t* array.c (ary_new2): forgot to initialize capa field.\n\nTue Jun  9 18:36:15 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* string.c (str_split_method): split dumped core for \"\\xff\".\n\nTue Jun  9 16:22:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_24.\n\nTue Jun  9 16:04:07 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/kconv/kconv.c (kconv_guess): more precise decision for EUC,\n\t  using jless algorithm (3 sequential EUC hiragana characters).\n\nTue Jun  9 15:12:44 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/kconv/kconv.c (kconv_guess): wrong guess for EUC as SJIS in\n\t  some cases (0xe0 - 0xef).\n\n\t* gc.c (xmalloc): insert size check for big (negative in signed)\n\t  allocation size.\n\nTue Jun  9 02:54:51 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/parsedate.rb: wday moved to the last in the return values.\n\nMon Jun  8 10:40:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_split_method): split dumped core for \"\\0\".\n\nSat Jun  6 22:50:52 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (calculate_must_string): wrong condition for\n\t  {start,stop}_nowidth.\n\n\t* regex.c (re_match): various features imported from GNU regex.c\n\t  0.12, such as nested grouping, avoiding infinite loop with empty\n\t  match, etc.\n\n\t* regex.c (register_info_type): now use union.\n\n\t* regex.c (re_search): more precise anchor(^) check.\n\nWed Jun  3 18:07:54 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (reg_raise): check rb_in_compile, not rb_in_eval.\n\nMon Jun  1 05:26:06 1998  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* string.c (trnext): casting to signed char* needed.\n\nTue Jun  2 16:00:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c (udp_addrsetup): error check enhanced.\n\n\t* ext/socket/socket.c (sock_s_getservbyaname): use strtoul(), if\n\t  possible.\n\nSat May 30 07:10:02 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (reg_prepare_re): no more needless regular expression\n\t  recompile on casefold conditions.\n\nThu May 28 18:02:55 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (nil_plus): no more `+' method for nil.\n\nWed May 27 17:33:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (hash_fetch): new method.\n\n\t* regex.c (re_search): check whether translate table is set.\n\nTue May 26 11:39:50 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_23.\n\n\t* parse.y (yylex): no UPLUS/UMINUS for 1st argument if\n\t  parenthesises are omitted.\n\nTue May 26 01:09:55 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): (?XI) for turns off the\n\t  corresponding option.\n\nMon May 25 12:38:56 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): inline i option (?i).\n\n\t* regex.c (re_compile_pattern): inline x option (?x).\n\n\t* regex.c (re_compile_pattern): x option for regexp.\n\n\t* dir.c (dir_s_open): returns block's evaluated value.\n\n\t* io.c (f_open): returns block's evaluated value.\n\n\t* ext/curses/curses.c (curses_addstr): nil argument caused SEGV.\n\nFri May 22 11:52:45 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): push mark on (?:), so that\n\t  laststart check for {a,b} can be done.\n\nThu May 21 17:31:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_match): wrong match (too non-greedy) for `{a,b}?'.\n\n\t* io.c (io_lineno): new method IO#lineno, IO#lineno=.\n\nWed May 20 06:04:43 1998  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* BeOS patch.\n\nWed May 20 16:32:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (BIGDN): use RSHIFT(), instead of mere `>>'.\n\nTue May 19 16:36:26 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_22.\n\nTue May 19 16:31:57 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (assignable): specification changed for in-block\n\t  variable definition.\n\n\t* eval.c (dyna_var_asgn): error in in-block variables' compile\n\t  time definition.\n\n\t* parse.y (str_extend): wrong nesting detection.\n\nTue May 19 09:47:55 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* numeric.c (num2int): re-defined (extensions may use this).\n\nMon May 18 16:40:50 1998  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* error.c (get_syserr): BeOS support.\n\n\t* configure.in: modified for BeOS.\n\n\t* string.c (str_dump): do not call isascii().\n\n\t* sprintf.c (remove_sign_bits): forgot to initialize end pointer.\n\n\t* glob.c: #include <alloca.h> added.\n\nMon May 18 14:52:21 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_21.\n\nMon May 18 03:27:57 1998  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* file.c (file_s_expand_path): optional second argument\n\t  `default_directory' added.\n\nSat May 16 22:06:52 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* error.c (RAISE_ERROR): wrong error message\n\nFri May 15 14:43:25 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_20.\n\nThu May 14 14:44:21 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* sun4 cc patches for intern.h and regex.h.\n\nThu May 14 14:03:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* random.c (RANDOM_MAX): guessing proper maximum value for random\n\t  numbers.\n\n\t* random.c (f_rand): use drand48 if possible.\n\nWed May 13 19:05:20 1998  MAEDA shugo  <shugo@aianet.ne.jp>\n\n\t* BeOS patches for io.c, error.c and config.guess.\n\nWed May 13 14:56:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_19.\n\n\t* most of the Mac and BeOS patches merged, except path separators.\n\n\t* error.c (err_append): generated SyntaxError was String.\n\n\t* ruby.h: xxx2INT, xxx2UINT checks values as int, not long.\n\n\t* ruby.h: remove typedef's. INT, UINT, UCHAR, USHORT.\n\nTue May 12 17:38:00 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_18.\n\nTue May 12 11:38:08 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* error.c (syserr_errno): returns errno of the SystemCallError.\n\n\t* error.c (rb_sys_fail): saves errno in the Exception.\n\n\t* error.c (set_syserr): no need to protect syserr_list.\n\n\t* error.c (rb_sys_fail): no more bufsize limit.\n\n\t* error.c (set_syserr): integer value of errno can be accessed by\n\t  Errno::EXXX::Errno.\n\nSun May 10 03:10:33 1998  WATANABE Tetsuya  <tetsu@jpn.hp.com>\n\n\t* io.c (io_tell etc.): moved from File class to IO class.\n\nFri May  8 12:26:37 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (pack_unpack): should be unsigned int (was signed int).\n\nThu May  7 16:34:10 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* pack.c (pack_pack): `V', `N' uses newly created NUM2UINT().\n\n\t* ruby.h (NUM2UINT): new macro.\n\n\t* bignum.c (big2uint): try to convert bignum into UINT.\n\n\t* re.c (reg_match): needed to return false for match with nil.\n\n\t* gc.c (obj_free): wrong condition to free string.\n\nWed May  6 21:08:08 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ruby.c (ruby_process_options): modified for DJGPP.\n\nWed May  6 15:48:03 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_17.\n\nWed May  6 01:37:39 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c: remove global variable `errat'.\n\n\t* eval.c (rb_longjmp): embed error position information in the\n\t  exception object.\n\nSat May  2 12:20:02 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (reg_search): supports reverse search.\n\n\t* string.c (str_index_method): does update $~ etc.\n\n\t* eval.c (f_load): needed to clear the_dyna_vars.\n\n\t* eval.c (dyna_var_asgn): do not push dyna_var, which is id == 0.\n\n\t* error.c (Init_Exception): NotImplementError is no longer\n\t  StandardError, which is not handled by default rescue.\n\nFri May  1 00:35:51 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (proc_options): `-d' turns on verbose flag too.\n\n\t* error.c (exception): last argument may be the superclass of the\n\t  defining exception(s).\n\n\t* io.c (Init_IO): EOFError is now subclass of the IOError.\n\n\t* io.c (Init_IO): forgot to define IOError.\n\n\t* error.c (Init_Exception): old Exception class renamed to\n\t  StandardError.  Exception now replaces old GlobalExit.\n\n\t* error.c (Init_Exception): Exception is now the root of the\n\t  Global Exits.  There's no longer GlobalExit class.\n\n\t* util.c (ruby_mktemp): check TMP, TMPDIR first.\n\nThu Apr 30 01:08:35 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/tk.rb: call 'unknown', if proc not defined.\n\n\t* eval.c (handle_rescue): default rescue handles `Exceptional' not\n\t  only the instance of the `Exception's.\n\n\t* eval.c (f_raise): exception can be any object.\n\n\t* time.c (time_gm_or_local): call time_gmtime or time_localtime.\n\n\t* eval.c (f_raise): raises TypeError if the class which is not a\n\t  subclass of String is specified (checked in exc_new()).\n\n\t* error.c (exc_new): need to check whether invalid class (not a\n\t  subclass of String) is specified.\n\nWed Apr 29 21:05:44 1998  WATANABE Hirofumi  <eban@os.rim.or.jp>\n\n\t* ruby.c (proc_options): option '-e' via tempfile.\n\nTue Apr 28 15:27:58 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_16.\n\nTue Apr 28 00:07:38 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (obj_is_proc): type check predicate.\n\n\t* eval.c (obj_is_block): ditto.\n\nMon Apr 27 16:59:17 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/gtk/gtk.c (Init_gtk): use timeout, not idle to avoid\n\t  consuming CPU too much.\n\n\t* lib/tk.rb: use tcltklib#_invoke instead of `_eval'.\n\nMon Apr 27 16:59:17 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (ary_sort): use dup, not clone.\n\nMon Apr 27 13:46:27 1998  Tadahiro Maebashi  <maebashi@iij.ad.jp>\n\n\t* ext/tcltklib/tcltklib.c (ip_invoke): invoke tcl command\n\t  directly.  need not worry about escaping tcl characters.\n\nMon Apr 27 12:04:43 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* random.c (f_rand): do not call srand() implicitly.\n\nFri Apr 24 14:35:45 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_15.\n\n\t* parse.y (assignable): dyna_var_asgn actually defines nested\n\t  local variables in outer context.\n\n\t* random.c (f_rand): call srand(), if it has not called yet.\n\n\t* random.c (f_srand): use tv_usec as the default seed.\n\n\t* eval.c (rb_eval): values of nested local variables should be\n\t  independent.\n\n\t* eval.c (rb_yield_0): local variables wrong nested conditions.\n\nWed Apr 22 23:27:17 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (select_get_io): get IO object by `to_io'.\n\n\t* io.c (io_to_io): method to retrieve IO object, from delegating\n\t  object for example.\n\nWed Apr 22 16:52:37 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_14.\n\n\t* string.c (str_modify): check for embedded pointer reference.\n\n\t* gc.c (obj_free): ditto.\n\n\t* pack.c (pack_pack): p/P template to embed pointers.\n\nWed Apr 22 00:07:10 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* array.c (ary_rindex): embarrassing typo.\n\nTue Apr 21 12:31:48 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_13.\n\n\t* configure.in (RUBY_LIB): supports --program-{prefix,suffix}.\n\n\t* array.c (ary_rindex): new method.\n\n\t* io.c (io_binmode): should return self.\n\nTue Apr 21 08:23:04 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* parse.y (here_document): calling parse_string with wrong\n\t  arguments.\n\n\t* struct.c (struct_aset): problem member assignment with name.\n\nMon Apr 20 14:47:49 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_12.\n\n\t* time.c (time_arg): args may be string (support for reduced\n\t  implicit type conversion).\n\n\t* lib/base64.rb: changed to use pack/unpack with `m' template.\n\nMon Apr 20 06:23:20 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (mod_remove_const): new method.\n\nSat Apr 18 03:53:27 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (hash_each_with_index): removed.  use Enumerable's\n\t  each_with_index instead.\n\n\t* class.c (rb_include_module): check for super modules, since\n\t  module's included modules may be changed.\n\nFri Apr 17 21:50:47 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* marshal.c (r_long): r_byte() may return signed byte.\n\nFri Apr 17 11:58:30 1998  NAGAI Hidetoshi  <nagai@dumbo.ai.kyutech.ac.jp>\n\n\t* ext/tcltklib/tcltklib.c (lib_mainloop): thread and interrupt check.\n\nFri Apr 17 11:06:30 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (find_file): try to fopen() to check whether file exists.\n\n\t* ruby.c (load_file): ditto.\n\n\t* struct.c (struct_aset): struct member can be set by member name.\n\nFri Apr 17 00:47:19 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/extmk.rb.in: added m68k-human support\n\n\t* file.c (LOCK_SH): defines moved.\n\n\t* array.c (ary_flatten_bang): simplified loop.\n\nThu Apr 16 16:52:01 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_11.\n\n\t* lib/tk.rb: thread support (experimental - maybe slow).\n\n\t* eval.c (rb_longjmp): trace event on exception in raising\n\t  context, just before raising exception.\n\n\t* struct.c (struct_s_members): forgot to check singletons.\n\n\t* struct.c (struct_aref): members can be accessed by names too.\n\n\t* array.c (ary_flatten): new method.\n\n\t* eval.c (rb_longjmp): prints exception information with `-d'.\n\n\t* object.c (any_to_s): remove class name restriction.\n\nThu Apr 16 01:38:02 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (thread_flock): do not block other threads.\n\n\t* eval.c (thread_trap_eval): signals are now delivered to the\n\t  current thread again.  In case that the current thread is dead,\n\t  signals are forwarded to the main thread.\n\n\t* string.c (str_new4): need not to duplicate frozen strings.\n\nWed Apr 15 08:33:47 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* struct.c (struct_inspect): remove restriction for struct names.\n\nWed Apr 15 02:55:02 1998  Kazuya 'Sharl' Masuda  <sharl@www.ufo.co.jp>\n\n\t* x68 patches to config.sub, ext/extmk.rb.in\n\nWed Apr 15 01:22:56 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_dup_frozen): do not duplicate frozen strings.\n\n\t* parse.y (yylex): allow nested parenthesises.\n\n\t* io.c (obj_displayln): prints newline after `display'ing the\n\t  receiver.\n\n\t* io.c (io_puts): avoid generating \"\\n\" each time.  use RS_default\n\t  instead.\n\n\t* io.c (f_p): ditto.\n\nTue Apr 14 22:18:17 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* struct.c (struct_aref): should not subtract negative index.\n\nTue Apr 14 11:34:50 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_10.\n\n\t* parse.y: token names prefixed by `t'.\n\n\t* struct.c (struct_s_def): supports subclassing of Struct.\n\n\t* io.c (io_s_new): supports subclassing of IO.\n\nMon Apr 13 11:07:39 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (f_binding): need to restore method name.\n\n\t* eval.c (rb_call0): raises SystemStackError, not Fatal.\n\n\t* io.c (obj_display): same as `print self'.\n\n\t* io.c (f_p): can now be called in the method form.\n\n\t* re.c (reg_regsub): needed to be mbchar aware.\n\nMon Apr 13 13:18:32 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_trap_eval): all signals delivered to main_thread.\n\nMon Apr 13 12:47:03 1998  TAKAHASHI Masayoshi  <maki@inac.co.jp>\n\n\t* re.c (kcode_set_option): did not set SJIS on SJIS condition.\n\nSun Apr 12 22:14:07 1998  Kazunori NISHI  <kazunori@swlab.csce.kyushu-u.ac.jp>\n\n\t* array.c (ary_uniq_bang): should be `==', not `='. embarrassing.\n\nSat Apr 11 02:13:30 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (ary_subseq): SEGVed for `[][1,1]'.\n\nFri Apr 10 21:29:06 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* array.c (ary_subseq): add check for beg larger than array length.\n\nWed Apr  8 17:24:11 1998  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* dir.c (dir_s_open): can be called with block (like IO#open).\n\n\t* dir.c (dir_s_chdir): print directory path on error.\n\n\t* dir.c (dir_s_chroot): ditto\n\n\t* dir.c (Init_Dir): needed to override `new'.\n\nThu Apr  9 18:24:58 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_09.\n\n\t* string.c (str_cmp): do not depend on sentinel at the end of the\n\t  strings.\n\n\t* string.c (str_chomp_bang): forgot to set the sentinel.\n\nWed Apr  8 00:59:13 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* bignum.c (big2int): converted int may be too big to fit in\n\t  signed int.\n\n\t* parse.y (arg): `foo += 1' should not cause an error.\n\n\t* variable.c (rb_const_defined): returned false even if the\n\t  constant is defined at the top level.\n\n\t* eval.c (f_local_variables): dyna_var->id may be null.  should\n\t  have checked before calling str_new2().\n\nTue Apr  7 01:15:15 1998  Kaneko Naoshi  <wbs01621@mail.wbs.or.jp>\n\n\t* re.c (reg_regsub): need to check string boundary.\n\nTue Apr  7 19:19:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_cmp): returns either 1, 0, -1.\n\n\t* array.c (ary_cmp): should check array length, too\n\nTue Apr  7 18:50:16 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_08.\n\nTue Apr  7 18:31:27 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* instruby.rb (mandir): dll installation for cygwin32\n\nTue Apr  7 01:16:45 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* config.sub (maybe_os): TOWNS support?\n\n\t* config.guess: too strict check for libc versions on linuxes.\n\n\t* experimental release 1.1b9_07.\n\n\t* array.c (ary_cmp): compare each element using `<=>'.\n\n\t* hash.c (hash_each_with_index): yields [value, key] pair.\n\n\t* class.c (class_protected_instance_methods): list protected\n\t  method names.\n\n\t* class.c (ins_methods_i): exclude protected methods.\n\n\t* eval.c (PUSH_BLOCK): dynamic variables can be accessed from\n\t  eval() with bindings.\n\nMon Apr  6 14:49:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_yield): must return evaluated value.\n\nFri Apr  3 13:07:29 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_schedule): context switch bypassed on wrong\n\t  conditions.\n\n\t* variable.c (rb_name_class): set classname by id before String\n\t  class is initialized (1.0 behavior restored).\n\nFri Apr  3 11:25:45 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (num2int): no implicit conversion from string.\n\n\t* numeric.c (num2int): check whether `to_i' returns an Integer.\n\n\t* numeric.c (num_zero_p): new method.\n\n\t* numeric.c (num_nonzero_p): new method.  returns the receiver if\n\t  it's not zero.\n\n\t* eval.c (obj_instance_eval): the_class should be the object's\n\t  singleton class.\n\n\t* error.c (exc_s_new): message is converted into a string.\n\nThu Apr  2 18:31:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (obj_call_init): every object call `initialize'.\n\nWed Apr  1 08:51:53 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* parse.y (stmt): UNTIL_MOD should be for stmt, not only for expr.\n\nWed Apr  1 01:20:31 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (true_and): boolean operators &, | and ^.\n\nTue Mar 31 13:23:58 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (ary_compact_bang): returns nil, if it does not modify\n\t  the array like String's bang methods.\n\n\t* array.c (ary_uniq_bang): new method to remove duplicate items.\n\n\t* eval.c (bind_s_new): new method.\n\n\t* numeric.c (num2int): raise exception if Fixnums too big to\n\t  convert into `int' in case that sizeof(int) < sizeof(INT).\n\n\t* string.c (str_center): SEGV on negative width.\n\n\t* eval.c (eval): forgot to set sourcefile.\n\nMon Mar 30 11:12:29 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (f_test): raises exception for unknown command.\n\n\t* eval.c (Init_eval): `class_eval': alias to the module_eval.\n\nMon Mar 30 18:50:42 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* string.c (str_capitalize_bang): did not check string modification.\n\n\t* string.c (str_delete_bang): wrong conversion.\n\n\t* string.c (str_intern): typo in error message.\n\nMon Mar 30 01:44:13 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (obj_instance_eval): accepts block as evaluation body.\n\t  No compilation needed each time.\n\n\t* eval.c (mod_module_eval): ditto\n\n\t* file.c (file_s_umask): umask did not return old values, if no\n\t  argument given.\n\nSun Mar 29 00:54:23 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (f_throw): nil returned always.\n\nSat Mar 28 20:40:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_06.\n\nSat Mar 28 16:07:11 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* io.c (io_closed): should not cause exception for closed IO.\n\n\t* string.c (str_tr): returned nil for success.\n\nSat Mar 28 00:47:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (f_local_variables): new method to return an array of\n\t  local variable names.\n\n\t* variable.c (obj_instance_variables): now returns an array of\n\t  variable names, as described in the reference.\n\n\t* eval.c (rb_attr): honors default method visibility of the\n\t  current scope.\n\nFri Mar 27 13:49:27 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_05.\n\n\t* ruby.c (ruby_prog_init): `site_ruby' added to load_path.\n\n\t* ruby.c (ruby_prog_init): load-path order changed.  Paths in\n\t  the RUBYLIB environment variable comes first in non-tainted\n\t  mode.\n\nThu Mar 26 11:51:09 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_call): new feature: `protected' methods.\n\n\t* string.c (str_dump): new method.\n\n\t* eval.c (block_pass): block argument can be nil, which means no\n\t  block is supplied for the method.\n\nWed Mar 25 21:20:13 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* string.c (str_reverse_bang): string copied to wrong place.\n\nWed Mar 25 08:12:07 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (flo_modulo): caused SEGV if left operand is not a\n\t  float value.\n\n\t* eval.c (f_eval): optional third and fourth argument to specify\n\t  file-name and line-number.\n\n\t* eval.c (eval): file-name and line-number set properly.\n\n\t* parse.y (assign_in_cond): literal assignment is now warning, not\n\t  compile error.\n\n\t* error.c (Warn): Warn() always print message, OTOH Waring()\n\t  prints when verbose flag is set.\n\nTue Mar 24 12:50:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (ruby_prog_init): `.' should come last in the load-path.\n\n\t* eval.c (Init_eval): `__send__', alias for `send'.\n\nMon Mar 23 12:44:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_chomp_bang): now takes `rs' as an argument.\n\n\t* eval.c (thread_free): main_thread should not be freed.\n\nFri Mar 20 16:40:34 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_chomp_bang): chomp! (and other ! methods) returns\n\t  nil if it does not modify the string.\n\n\t* string.c (str_sub_iter_s): should check last pattern since it\n\t  may be matched to null.\n\nThu Mar 19 13:48:55 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_04.\n\n\t* parse.y (yylex): `10e0.9' should cause syntax error.\n\nWed Mar 18 17:46:31 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (load_file): new file object constant DATA.  Only\n\t  available for the script from the file.\n\n\t* regex.c (re_match): forwarding failure point popped too much.\n\nTue Mar 17 18:23:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* math.c (math_frexp): newly added.\n\n\t* math.c (math_ldexp): ditto.\n\n\t* bignum.c (bigdivmod): calculates modulo.\n\n\t* numeric.c (fix_remainder): returns reminder, formerly introduced\n\t  as modulo.\n\n\t* numeric.c (fix_modulo): calculates proper `modulo'.\n\n\t* bignum.c (bigdivmod): wrong sign for reminder.\n\nMon Mar 16 17:07:28 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_03.\n\nMon Mar 16 16:33:53 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* io.c (pipe_finalize): needed to add pipe_finalize to pipes on\n\t  cygwin32.\n\nMon Mar 16 14:11:06 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (ins_methods_i): needed to consider NOEX_UNDEF.\n\nMon Mar 16 13:23:53 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* io.c (io_check_closed): check for `fptr->f2 == NULL'.\n\n\t* io.c (io_fptr_close): ditto.\n\nMon Mar 16 11:49:25 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (pipe_atexit): free()ing referencing pipe_list.\n\n\t* range.c (range_length): returns zero, if the first is greater\n\t  than the last.\n\n\t* signal.c (trap_restore_mask): restore signal mask before raising\n\t  exceptions and throws.\n\nFri Mar 13 13:49:24 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_02.\n\n\t* object.c (mod_clone): need to dups constants and instance\n\t  variables.\n\n\t* eval.c (rb_eval): forgot to initialize body for NODE_DEFS.\n\n\t* eval.c (rb_eval): retrieve self from calling frame, since self\n\t  changes sometimes.\n\n\t* env.h (FRAME): need to save self in the calling frame.\n\n\t* io.c (f_gets_method): rs should be initialized by RS.\n\nThu Mar 12 15:33:57 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* experimental release 1.1b9_01.\n\n\t* range.c (range_s_new): check values by `first <= last'.\n\n\t* parse.y (lastline_set): fixed offset for $_ and $~ in the local\n\t  variable space.\n\nWed Mar 11 02:14:17 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_gets): handle normal case specially for speed.\n\n\t* eval.c (rb_disable_super): function to disable superclass's\n\t  method explicitly.\n\n\t* eval.c (rb_eval): inherits previous method definition's\n\t  NOEX_UNDEF-ness, if exists.\n\n\t* class.c (rb_define_method): disables superclass's overriding\n\t  method by default.\n\nWed Mar 11 01:40:48 1998  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* numeric.c (flo_gt,etc.): do not depend on `<=>', to handle NaN.\n\nTue Mar 10 00:03:24 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (load_file): understands multiple options in #! line.\n\n\t* regex.c (re_compile_pattern): support for [:alpha:] etc.\n\nMon Mar  9 16:53:51 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.h (GetOpenFile): embed io_check_closed in GetOpenFile.\n\n\t* sprintf.c (f_sprintf): zero padding failed for negative\n\t  integers.\n\n\t* sprintf.c (remove_sign_bits): failed to remove some bits.\n\nSat Mar  7 21:51:46 1998  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* class.c (ins_methods_i): body may be NULL for some case.\n\nFri Mar  6 17:23:07 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (mbcinit): table driven mbchar detection.\n\n\t* object.c (obj_alloc): check for allocating instance for the\n\t  primitive classes (mostly perfect).\n\n\t* ext/curses/curses.c (curses_finalize): restore original state at\n\t  interpreter termination.\n\n\t* ext/curses/curses.c (curses_addstr): forgot to check argument\n\t  type (caused SEGV).  now uses STR2CSTR() macro.\n\nThu Mar  5 13:47:39 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (block_pass): accepts method object as block args.\n\n\t* eval.c (f_missing): use any_to_s() for stringify.\n\nWed Mar  4 01:39:52 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (block_arg): new syntax - block argument in the\n\t  calling arglist.\n\n\t* eval.c (rb_call): no module search. simplified a lot.\n\n\t* eval.c (rb_eval): block arg support.\n\n\t* parse.y (f_block_arg): new syntax - block argument in the\n\t  formal arglist.\n\nTue Mar  3 14:20:15 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (obj_method): returns bound method object.\n\n\t* eval.c (rb_call): argument check for empty methods.\n\n\t* ruby.h (NUM2CHR): new macro, originally from curses module.\n\nTue Mar  3 13:03:35 1998  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* io.c (io_putc): new method.\n\nTue Mar  3 11:21:28 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_inspect): more strict charcode detection.\n\n\t* eval.c (thread_stop): stopping only thread raises ThreadError\n\t  exception.\n\nTue Mar  3 08:04:56 1998  Tadayoshi Funaba  <tadf@kt.rim.or.jp>\n\n\t* struct.c (struct_alloc): incomplete struct initialization made\n\t  GC to access unallocated addresses.\n\nMon Mar  2 16:28:27 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (thread_stop_method): remove Thread#stop.\n\nFri Feb 27 18:16:26 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b9 released.\n\nFri Feb 27 09:36:35 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (hash_delete_nil): needed to compare value to nil, since\n\t  nil is the valid key for hashes.\n\n\t* hash.c (hash_foreach_iter): rehashing causes IndexError.\n\n\t* hash.c (hash_foreach_iter): rehash check by pointer comparison.\n\nThu Feb 26 17:22:13 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (fname): convert reswords into symbols.\n\n\t* parse.y (reswords): reserved words are now embedded in the\n\t  syntax (sigh).\n\n\t* parse.y: now reserved words can be method names safely.\n\nWed Feb 25 15:50:07 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (mod_module_eval): clear the_scope's PRIVATE flag before\n\t  calling eval().\n\n\t* gc.c (gc_call_finalizer_at_exit): run finalizers before any data\n\t  object being freed.\n\n\t* eval.c (rb_eval): needed to keep prot_tag->retval before\n\t  evaluating the ensure clause.\n\nTue Feb 24 11:16:32 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): reserved words can be appear as method names at\n\t  right after 'def' and `.'(dot), like foo.next.\n\n\t* eval.c (return_check): checks for return out of thread (formerly\n\t  done in return_value).\n\n\t* eval.c (POP_TAG): copy retval to outer level.\n\n\t* eval.c (return_value): just set retval, no check, no unwinding.\n\n\t* parse.y (nextc): line continuation by backslash at end of line.\n\n\t* regex.c (re_compile_pattern): forgot to clear pending_exact on\n\t  closing parentheses.\n\n\t* parse.y (assignable): should not assign dyna_var to true, if it\n\t  is already defined.\n\nMon Feb 23 14:35:03 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (obj_is_kind_of): no longer accepts true/false/nil.\n\n\t* object.c ({true,false,nil}_to_i): can be converted into integers.\n\nMon Feb 23 12:11:51 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (reg_s_quote): needed to be mbchar aware.\n\n\t* eval.c (proc_s_new): wrong iter mark.\n\nSat Feb 21 22:59:30 1998  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* io.c (f_syscall): no argument check.\n\nFri Feb 20 10:17:51 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b8 released.\n\n\t* ext/kconv/kconv.c (kconv_kconv): default output code now be\n\t  determined according to the value of $KCODE.\n\n\t* re.c (rb_get_kcode): can retrieve $KCODE from C code.\n\n\t* parse.y (stmt): if/unless modifiers returns nil, if condition is\n\t  not established.\n\nThu Feb 19 11:06:47 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/kconv/kconv.c (kconv_kconv): charcode can be specified by\n\t  code name (JIS, SJIS, EUC like value of $KCODE).\n\n\t* regex.c (re_compile_pattern): forgot to fixup_jump for (?:..).\n\n\t* regex.c (re_compile_pattern): needed to clear pending_exact on\n\t  non-registering grouping (?:...).\n\nWed Feb 18 19:54:21 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (here_document): needed to set lex_state to EXPR_END.\n\nWed Feb 18 18:45:10 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* patches for cygwin32 applied.\n\nWed Feb 18 00:41:31 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_sub_s): needed to be mbchar aware to increment one\n\t  character.\n\n\t* regex.c (re_match): \\Z matches newline just before the end of\n\t  the string.\n\nTue Feb 17 00:04:32 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_arg): Time.gm and Time.local now understands\n\t  Time#to_a format.\n\n\t* string.c (str_sub_s): replace happened twice for null pattern.\n\n\t* regex.c (re_search): null pattern should not match after newline\n\t  at the end of string.\n\n\t* time.c (time_isdst): now returns boolean value.\n\n\t* error.c (rb_check_type): treat special constants in messages.\n\n\t* parse.y (yylex): new form `::Const' to see toplevel constants.\n\n\t* parse.y (cond): SEGV on `if ()'.\n\n\t* gc.c (obj_free): some data needed explicit free().\n\nMon Feb 16 23:55:40 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (blk_free): release duplicated block informations.\n\n\t* eval.c (blk_copy_prev): duplicate outer block information into\n\t  the heap, when proc/binding created.\n\nMon Feb 16 14:38:25 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_mon): now 1 for January and so on.\n\n\t* time.c (time_year): year in 19xx (no + 1900 needed anymore).\n\nMon Feb 16 13:28:33 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): need to fetch mbchar's second byte\n\t  without translation.\n\nMon Feb 16 12:29:27 1998  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* eval.c (f_pass_block): pass iterator block to other method.\n\nFri Feb 13 08:16:11 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (parse_regx): handle \\s before read_escape().\n\n\t* parse.y (read_escape): `\\s' in strings as space.\n\nTue Feb 10 17:29:08 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b7 released.\n\n\t* string.c (str_aset): string insertion by `str[n] = str2'.\n\n\t* string.c (str_oct): does recognize `0x'.\n\n\t* sprintf.c (f_sprintf): use base 10 for conversion from string to\n\t  integer.\n\nMon Feb  9 14:51:56 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* numeric.c (do_coerce): proper error message.\n\n\t* string.c (str_sum): bug - masked by wrong value. (sigh..)\n\nSat Feb  7 15:11:14 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_empty): new method\n\nFri Feb  6 01:42:15 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c (time_asctime): use asctime(3), not strftime(3).\n\nThu Feb  5 18:58:46 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_fptr_close): do not free path on close().\n\n\t* array.c (ary_filter): new method.\n\n\t* enum.c (enum_each_with_index): new method.\n\nThu Feb  5 14:10:35 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (primary): singleton class def can be appeared inside\n\t  method bodies.\n\n\t* hash.c (hash_replace): replace content.\n\n\t* string.c (str_replace_method): replace content.\n\n\t* array.c (ary_replace_method): replace elements.\n\n\t* string.c (str_succ_bang): String#succ!\n\nThu Feb  5 18:20:30 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* string.c (str_upcase_bang): multi byte character support.\n\nWed Feb  4 13:55:26 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (ary_reverse): SEGV on empty array reverse.\n\nTue Feb  3 12:24:07 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (match_to_a): non matching element should be nil.\n\n\t* ruby.c (ruby_load_script): load script after all initialization.\n\n\t* bignum.c (str2inum): need to interpret prefix `0' of `0x'.\n\nTue Feb  3 10:00:18 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* numeric.c (fix_rshift): use `sizeof(INT)*8' instead of 32.\n\nMon Feb  2 14:09:24 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (set_arg0): grab environment region too.\n\nThu Jan 29 18:36:25 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* process.c (rb_proc_exec): check `sh' to be exist.\n\nThu Jan 29 18:18:19 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_stdio_set): assignment to $stdin or $stdout does\n\t  reopen() as well as $stderr.\n\nThu Jan 29 14:18:40 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (mod_ancestors): should not include singleton classes.\n\n\t* object.c (obj_type): should not return internal class.\n\n\t* io.c (io_reopen): unwillingly closes stdio streams.\n\nThu Jan 29 11:50:35 1998  Toshihiko SHIMOKAWA  <toshi@csce.kyushu-u.ac.jp>\n\n\t* ext/socket/socket.c (udp_addrsetup): forgot to use htons().\n\nTue Jan 27 23:15:24 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* keywords: __FILE__, __LINE__ are available again.\n\nFri Jan 23 14:19:28 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b6 released.\n\n\t* object.c (mod_to_s): need to duplicate classpath.\n\n\t* error.c (exc_inspect): need to duplicate classpath.\n\nThu Jan 22 00:37:47 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.h (STR2CSTR): new macro to retrieve char*.\n\n\t* class.c (rb_define_method): `initialize' should always be\n\t  private, even if it defined by C extensions.\n\n\t* eval.c (rb_eval): `initialize' should always be private.\n\nThu Jan 22 16:21:08 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): some singleton class def cause SEGV.\n\n\t* eval.c (TMP_ALLOC): replace ALLOCA_N, where thread context\n\t  switch may happen.\n\nWed Jan 21 01:43:42 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (PUSH_FRAME): do not use ALLOCA_N().  crash on some\n\t  platforms that use missing/alloca.c.\n\n\t* regex.c (re_compile_pattern): too many pops for non register\n\t  subexpr.\n\n\t* parse.y (yylex): open parentheses after identifiers are argument\n\t  list, even if whitespaces have seen.\n\nTue Jan 20 15:19:59 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (terms): quoted word list by %w(a b c).\n\n\t* ext/tcltklib/extconf.rb: more accurate check for tcl/tk libs.\n\n\t* file.c (rb_stat): most of the FileTest methods (and function\n\t  `test') accept File objects as the argument.\n\nTue Jan 19 18:19:24 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/extmk.rb.in (install): there should be no newline after install:\n\n\t* re.c (MIN): renamed from min().  there's a local variable named\n\t  min in the file, so that some cpp will raise an error.\n\nMon Jan 19 16:30:05 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b5 released.\n\n\t* process.c (rb_syswait): no exception raised.\n\nFri Jan 16 00:43:43 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.h (CLONESETUP): copies its singleton classes too.\n\n\t* class.c (singleton_class_attached): saves binded object in the\n\t  singleton classes.\n\n\t* eval.c (rb_eval): calls singleton_method_added even in the\n\t  singleton class clauses.\n\nFri Jan 15 23:22:43 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ruby.c (proc_options): -S does not recognize PATH.\n\nThu Jan 15 02:03:12 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_clear_cache_by_id): clear only affected cache\n\t  entries.\n\nWed Jan 14 02:14:48 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c: new UDP/IP socket classes.\n\nTue Jan 13 10:00:18 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_cmp): ignorecase($=) works wrong.\n\nFri Jan  9 13:19:55 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b4 released.\n\n\t* eval.c (f_missing): class name omitted from the error message.\n\n\t* error.c (exc_inspect): description changed.\n\n\t* string.c (Init_String): GlobalExit's superclass did not filled,\n\t  since GlobalExit created earlier than String.\n\nThu Jan  8 12:10:09 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (aryset): expr in the brackets can be null.\n\nWed Jan  7 21:13:56 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_reopen): keep stderr unclosed.\n\n\t* io.c (io_errset): keep stderr unclosed.\n\nTue Jan  6 00:27:43 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y: syntax modified for `while expr do .. end' etc.\n\n\t* process.c (f_exec,f_system): can supply arbitrary name for the\n\t  new process.\n\nMon Jan  5 16:59:13 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* file.c (file_s_basename): removes any extension by \".*\".\n\nSun Jan  4 19:36:22 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* parse.y (yylex): needed to update lex_p (reading point).\n\nSat Jan  3 19:14:14 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* class.c,object.c: duplicate defines mKernel and cFinxnum.\n\nFri Jan  2 20:38:59 1998  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/curses/curses.c (NUM2CHAR): uses the first character for\n\t  string arguments.\n\n\t* array.c (ary_fill): did not extend array for ranges.\n\n\t* array.c (beg_len): did not return end pos bigger than size.\n\nFri Jan  2 02:09:16 1998  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* dir.c (dir_s_chdir): bug in nil check.\n\n\t* array.c (ary_fill): bug in nil check.\n\nTue Dec 30 11:46:23 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* hash.c (env_path_tainted): checks directories in PATH\n\t  environment variable are not world writable.\n\n\t* ruby.c (load_file): invoke specified interpreter if the #! line\n\t  does not contain the word `ruby'.\n\nFri Dec 26 03:26:41 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (uscore_get): type information included in the error\n\t  message.\n\n\t* variable.c (f_untrace_var): does not free trace-data within\n\t  trace procedure.\n\nThu Dec 25 02:50:29 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b3 released.\n\n\t* ruby.h: inlining some functions on gcc 2.x\n\nTue Dec 23 02:47:33 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): public/private information kept in the current\n\t  scope, to remove undesired state from the class/module.\n\n\t* time.c (time_strftime): remove hidden limit of 100 bytes of\n\t  result string, using malloc'ed buffer.\n\n\t* hash.c (hash_update): merges the contents of another hash,\n\t  overriding existing keys.\n\n\t* regex.c (must_instr): totally re-written.\n\n\t* io.c (read_all): try to allocate proper sized buffer using\n\t  fstat(2) for speedup.\n\nSat Dec 20 00:27:28 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (must_instr): need to skip 2 bytes for mbchars.\n\nFri Dec 19 01:18:29 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b2 released.\n\n\t* eval.c (check_errat): check and convert (if necessary) traceback\n\t  information before assigning to the variable $@.\n\n\t* eval.c (f_raise): optional third argument to specify traceback\n\t  information.\n\n\t* io.c (f_open): prevent infinite recursive call.\n\nThu Dec 18 19:33:47 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_rindex): now accepts regexp as index.\n\nThu Dec 18 18:42:50 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/socket/extconf.rb: modified to detect win32 socket lib.\n\nThu Dec 18 00:25:03 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* re.c (reg_equal): checks for source and casefold and kcode matching.\n\n\t* marshal.c: became built-in module.\n\n\t* ext/marshal/marshal.c (r_object): displays struct name for\n\t  non-compatible struct.\n\n\t* string.c (str_index_method): now searches character (fixnum) in\n\t  the string.\n\n\t* string.c (str_include): redefine `include?'.\n\n\t* regex.c (re_match): start_nowidth saves current stack position\n\t  to stop_nowidth.\n\n\t* regex.c (re_compile_pattern): add space to stop_nowidth to save\n\t  runtime stack position.\n\nTue Dec 16 14:57:43 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (scan_once): wrong exception for regexp that match with\n\t  null string (use substr instead of subseq).\n\nSat Dec 13 00:13:32 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (expr): remove bare assocs from expr rule.\n\n\t* rbconfig.rb: renamed from config.rb (it was too generic name).\n\nFri Dec 12 00:50:25 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (expr): warns if BEGIN or END appear in the method\n\t  bodies.\n\n\t* string.c (str_match): calls y =~ x if y is neither String nor\n\t  Regexp so that eregex.rb works.\n\n\t* eval.c (f_at_exit): to register end proc.\n\n\t* class.c (rb_define_module_function): define 'function' method\n\t  for the Module, not private method.\n\n\t* class.c (rb_define_function): function to define `function' method.\n\n\t* eval.c (rb_eval): inherit visibility from superclass's method\n\t  except when it is set to `function'\n\n\t* eval.c (rb_eval): new visibility status `function'.\n\n\t* parse.y (yycompile): do not clear eval_tree. thus enable multiple\n\t  command line script by option `-e'.\n\n\t* eval.c (rb_eval): END execute just once.\n\n\t* parse.y (expr): BEGIN/END built in the syntax.\n\nThu Dec 11 13:14:35 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (mod_le): Module (or Class) comparison.\n\n\t* eval.c (rb_remove_method): raises NameError if named method does\n\t  not exist.\n\n\t* ext/curses/curses.c: remove CHECK macro for BSD curses.\n\nThu Dec 11 12:44:01 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* pack.c: sun4 cc patch\n\nWed Dec 10 15:21:36 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/marshal/marshal.c (marshal_load): can supply evolution proc\n\t  object as optional second argument.\n\n\t* re.c (reg_source): get source string of the regular expression.\n\nTue Dec  9 10:05:17 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b1 released.\n\n\t* parse.y (tokadd): token buffer overrun.\n\n\t* ruby.c (ruby_prog_init): forgot to protect rb_argv0 from gc.\n\n\t* eval.c (ruby_run): call finalizers at process termination.\n\n\t* gc.c (gc_call_finalizer_at_exit): call free proc for every Data\n\t  Wrapper, and finalizer for specified objects at termination.\n\n\t* version.c (show_version): version format changed.\n\n\t* regex.c (re_match): wrong match with non-greedy if they appear\n\t  more than once in regular expressions.\n\n\t* sample/ruby-mode.el (ruby-expr-beg): forgot to handle modifiers.\n\nMon Dec  8 19:00:15 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_puts): just put a newline if no argument given.\n\n\t* ext/tcltklib/tcltklib.c (lib_mainloop): thread-aware tk handle\n\t  when $tk_thread_safe is set.\n\n\t* ext/tcltklib/tcltklib.c (lib_mainloop): use Tcl_DoOneEvent()\n\t  instead of Tk_MainLoop().\n\nMon Dec  6 07:11:16 1997  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* io.c (io_puts): core dumped without any argument.\n\nFri Dec  5 18:17:17 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (mod_remove_method): remove (not undef) a method from the\n\t  class/module.\n\n\t* variable.c (obj_remove_instance_variable): method to remove\n\t  instance variables.\n\nThu Dec  4 13:50:29 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1b0 released.\n\n\t* string.c (str_aref): called str_index for regexp.\n\nMon Dec  1 15:24:41 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* compar.c (cmp_between): wrong comparison made.\n\nWed Nov 26 18:18:05 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* lib/mkmf.rb: generate Makefile for extension modules out of ruby\n\t  source tree. use like `ruby -r mkmf extconf.rb'.\n\n\t* numeric.c (fix2str): enlarge buffer to prevent overflow on some\n\t  machines.\n\n\t* parse.y (here_document): wrong line number generated after here-doc.\n\nFri Nov 21 13:17:12 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (yylex): skip multibyte characters in comments.\n\nWed Nov 19 17:19:20 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (nil_to_a): nil.to_a => [].\n\n\t* parse.y (call_args): wrong node generation.\n\nTue Nov 18 10:13:08 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* array.c (Init_Array): Array#=== works as Array#include?\n\n\t* regex.c (re_compile_pattern): insert initialize code for jump_n,\n\t  before entering loops.\n\n\t* re.c (reg_search): does not save registers unless $& etc appear\n\t  in the script.\n\nMon Nov 17 13:01:43 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (is_defined): add defined? check for receivers and\n\t  arguments for calls.\n\n\t* re.c (reg_search): cache last match object.\n\n\t* re.c (match_aref): $[0] etc. are available.\n\nSat Nov 15 00:11:36 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* io.c (io_s_popen): \"rb\" detection\n\nFri Nov 14 18:28:40 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (scan_once): returns whole match if the pattern does\n\t  not contain any parentheses.\n\nThu Nov 13 14:39:06 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (str_sub): returns copy of the receiver string, even if\n\t  any substitution occurred.\n\n\t* regex.c (re_compile_pattern): no-width match by (?=..), (?!..).\n\nWed Nov 12 13:44:47 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* time.c: remove coerce from Time class.\n\n\t* regex.c (re_match): non-greedy match by ??, *? +?, {n,m}?.\n\nMon Nov 10 11:24:51 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): non-registering parens (?:..).\n\n\t* regex.c (re_compile_pattern): new meta character \\< (wordbeg)\n\t  and \\> (wordend).\n\n\t* regex.c (re_compile_pattern): embedded comment for regular\n\t  expression by (?#...).\n\nFri Nov  7 16:58:24 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* regex.c (re_compile_pattern): perl5 regexp \\A and \\Z available.\n\n\t* regex.c (re_compile_pattern): can expand compile stack dynamically.\n\n\t* regex.c (PUSH_FAILURE_POINT): wrong compare condition.\n\nWed Nov  2 16:00:00 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* string.c (str_sub_s): \"\".sub! \"\", \"\" => \"\\000\"\n\nFri Oct 31 15:52:10 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (assoc): keyword assoc like {fg->\"black\"}.\n\nThu Oct 30 17:33:38 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_println): print with newline, which is not affected by\n\t  the values of $/ and $\\.\n\nThu Oct 30 16:54:01 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* string.c (str_chop_bang): \"\".chop caused SEGV.\n\n\t* string.c (str_chomp_bang): method to chop out last newline.\n\nMon Oct 27 13:49:13 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/extmk.rb.in: library may have pathname contains `.'\n\n\t* eval.c (rb_rescue): should not protect SystemError.\n\nFri Oct 24 10:58:53 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_s_with_open_stream): ensures to close stream.\n\nThu Oct 23 11:17:44 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_errset): value of $stderr can be changed (to any IO\n\t  object).\n\n\t* io.c (next_argv): $< can be anything that responds to `write'.\n\n\t* file.c (file_s_with_open_file): ensures to close file.\n\n\t* error.c (exception): create error under the current class/module.\n\n\t* range.c (range_eqq): fixnum check for last needed too.\n\nWed Oct 22 12:52:30 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/socket/socket.c: Socket::Constants added.\n\n\t* file.c: File::Constants added for inclusion.\n\n\t* array.c (ary_join): call ary_join() recursively for the 1st\n\t  array element.\n\nMon Oct 20 12:18:29 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ruby.c (load_file): wrong condition for #! check with -x.\n\n\t* file.c (file_s_dirname): did return \"\" for \"/a\".\n\nFri Oct 17 14:29:09 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c: now works on alpha-linux.\n\n\t* bignum.c (bigadd): some undefined side effect order assumed.\n\nWed Oct 15 17:49:24 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* intern.h: function prototypes added.\n\nMon Oct 13 16:54:18 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (rb_define_class_id): call superclass's `inherited'\n\t  method when making subclasses.\n\n\t* parse.y (nextc): clear lex_lastline at the end of file.\n\n\t* object.c (Init_Object): need to undef Class#append_features.\n\n\t* eval.c (rb_eval): no warning on extending classes or modules.\n\nThu Oct  9 11:17:50 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (error_print): the exception name follows after the error\n\t  message.\n\n\t* eval.c (compile_error): error message slightly changed.\n\n\t* parse.y (nextc): script parsing will be terminated by __END__ at\n\t  beginning of line.\n\n\t* eval.c (compile_error): `__END__' is no longer a keyword.\n\n\t* parse.y (nextc): protect lastline read from script stream.\n\nTue Oct  7 14:06:06 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha9 released.\n\n\t* eval.c (mod_append_features): renamed from extend_class.\n\n\t* eval.c (rb_eval): defining method calls `method_added'.\n\n\t* eval.c (ruby_options): exception while processing options must\n\t  terminate the interpreter.\n\n\t* error.c (Init_Exception): wrong method configuration.  `new'\n\t  should have been a singleton method.\n\nMon Oct  6 18:55:38 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/kconv/kconv.c (kconv_guess): code to guess character code\n\t  from string.\n\nMon Oct  6 18:38:17 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* pack.c: now encode/decode base64 by `m' template.\n\nFri Oct  3 10:51:10 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* MANIFEST: needed to include lex.c in the distribution.\n\n\t* eval.c (ruby_options): f_require() called too early.\n\n\t* eval.c (rb_provide): module extensions should always be `.o'.\n\nThu Oct  2 11:38:31 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha8 released.\n\n\t* ext/marshal/marshal.c (r_object): remove temporal regist for\n\t  structs. (caused problem if structs form cycles.)\n\n\t* parse.y (match_gen): static binding for match(=~) calls\n\t  with regexp literals.\n\nWed Oct  1 15:26:55 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c: protect retval in struct tag from GC for C_ALLOCA.\n\n\t* eval.c: no more pointer value from setjmp/longjmp.\n\nWed Oct  1 14:01:49 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/marshal/marshal.c (w_byte): argument must be char.\n\nWed Oct  1 10:30:22 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (mod_const_at): global constants now belongs to the\n\t  class Object.\n\n\t* object.c (Init_Object): new global constant NIL.\n\n\t* ext/marshal/marshal.c (marshal_dump): try to set binmode.\n\n\t* ext/marshal/marshal.c (r_object): forgot to re-regist structs in\n\t  the object table.\n\n\t* eval.c (ruby_options): call Init_ext() before any require()\n\t  calls by `-r'.\n\nFri Sep 30 14:29:22 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/marshal/marshal.c (w_object): marshal dumped core.\n\nTue Sep 30 10:27:39 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sample/test.rb: bignum test suits added.\n\n\t* eval.c (rb_eval): new pseudo variable `true' and `false'.\n\n\t* parse.y: new keywords `true' and `false' added.\n\nMon Sep 29 13:37:58 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (forbid_setid): forbid some options in suid mode.\n\n\t* ruby.h (NUM2DBL): new macro to convert into doubles.\n\nMon Sep 27 09:53:48 1997  EGUCHI Osamu  <eguchi@shizuokanet.or.jp>\n\n\t* bignum.c: modified for speeding.\n\nFri Sep 26 18:27:59 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* sample/from.rb: some extensions.\n\nMon Sep 29 13:15:56 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (lhs): no more syntax error on `obj.CONSTANT = value'.\n\nFri Sep 26 14:41:46 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (ruby_run): deferred calling Init_ext() just before eval_node.\n\nFri Sep 26 13:27:24 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* io.c (io_isatty): forgot to return TRUE value.\n\nFri Sep 25 11:10:58 1997  EGUCHI Osamu  <eguchi@shizuokanet.or.jp>\n\n\t* eval.c: use _setjmp/_longjmp instead of setjmp/longjmp on some\n\t  platforms.\n\nWed Sep 24 17:43:13 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* string.c (Init_String): String#taint and String#taint? added.\n\n\t* class.c (mod_ancestors): ancestors include the class itself.\n\nWed Sep 24 00:57:00 1997  Katsuyuki Okabe  <HGC02147@niftyserve.or.jp>\n\n\t* X68000 patch.\n\nTue Sep 23 20:42:30 1997  EGUCHI Osamu  <eguchi@shizuokanet.or.jp>\n\n\t* parse.y (node_newnode): SEGV on null node setup.\n\nMon Sep 22 11:22:46 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (ruby_prog_init): wrong safe condition check.\n\nSun Sep 21 14:46:02 1997  MAEDA shugo  <shugo@po.aianet.ne.jp>\n\n\t* error.c (exc_inspect): garbage added to classpath.\n\nFri Sep 19 11:49:23 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (newtok): forgot to adjust buffer size when shrinking\n\t  the token buffer.\n\n\t* enum.c (enum_find): rb_eval_cmd() does not return value.\n\n\t* io.c (pipe_open): close fds on pipe exec. fcntl(fd, F_SETFD, 1)\n\t  no longer used.\n\nTue Sep 16 17:54:25 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* file.c (f_test): problem if wrong command specified.\n\n\t* ruby.c (ruby_prog_init): close stdaux and stdprn for MSDOS.\n\n\t* ruby.c (ruby_prog_init): should not add path from environment\n\t  variable, if ruby is running under setuid.\n\n\t* process.c (init_ids): check suid check for setuid/seteuid etc.\n\nMon Sep 15 00:42:04 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* regex.c (re_compile_pattern): \\w{3} and \\W{3} did not work.\n\nThu Sep 11 10:31:48 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha7 released.\n\n\t* ext/socket/socket.c (sock_new): no setbuf() for NT.\n\n\t* io.c (rb_fopen,rb_fdopen): set close-on-exec for every fd.\n\nWed Sep 10 15:55:31 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ext/marshal/marshal.c (r_bytes0): extra big length check.\n\nTue Sep  9 16:27:14 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (pipe_fptr_atexit): clean up popen()'ed fptr.\n\n\t* error.c (set_syserr): some system has error code that is bigger\n\t  than sys_nerr. grrr.\n\nMon Sep  8 18:33:33 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* io.c (io_s_new): dereferenced nil for optional mode.\n\nFri Sep  5 10:26:03 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (class_instance_methods): do not include methods which\n\t  are changed to private in subclasses.\n\nThu Sep  4 12:38:53 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* variable.c (f_global_variables): list name of the global\n\t  variables.\n\n\t* object.c (obj_id): returns unique integer.\n\nWed Sep  3 14:05:16 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha6 released.\n\n\t* eval.c (mod_s_constants): context sensitive constant list.\n\n\t* variable.c (mod_constants): no more `all' option.\n\n\t* variable.c (mod_const_of): the values for autoload classes are\n\t  their name strings.\n\n\t* class.c (class_instance_methods): no special treatment for\n\t  singleton classes.\n\n\t* object.c (obj_singleton_methods): returns list of singleton\n\t  method names.\n\n\t* parse.y (yylex): no here document after `class' keyword.\n\n\t* eval.c (f_load): expand path if fname begins with `~'.\n\nTue Sep  2 13:19:48 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (ins_methods_i): do not list undef'ed methods.\n\nMon Sep  1 13:42:48 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha5 released.\n\n\t* object.c (mod_attr_reader): create methods to define attribute\n\t  reader/write/accessor.\n\n\t* class.c (rb_define_attr): always defines accessors.\n\n\t* eval.c (rb_call): alias occurred in the module body caused SEGV.\n\n\t* parse.y: did not generate here document strings properly.\n\nMon Sep  1 11:43:57 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* parse.y (yylex): heredoc dropped an extra character.\n\nFri Aug 29 11:10:21 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* class.c (class_instance_methods): same method names should not\n\t  appear more than once.\n\n\t* parse.y (yylex): spaces can follow =begin/=end.\n\n\t* variable.c (find_class_path): look for class_tbl also for\n\t  unnamed fundamental classes, such as Object, String, etc.\n\n\t* variable.c (rb_name_class): can't name class before String class\n\t  is initialized.\n\n\t* inits.c (rb_call_inits): unrecognized dependency from GC to\n\t  Array.\n\n\t* variable.c (find_class_path): could not find class if Object's\n\t  iv_tbl is NULL.\n\nThu Aug 28 13:12:05 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha4 released.\n\n\t* variable.c (mod_constants): wrong condition for singleton\n\t  class.\n\n\t* parse.y (yylex): revised `=begin' skip code.\n\n\t* parse.y (here_document): forgot to free(eos).\n\n\t* parse.y (yylex): spaces after `<<' prohibited for here\n\t  documents to avoid confusing with operator `<<'.\n\n\t* eval.c (is_defined): separated from rb_eval().\n\nWed Aug 27 11:32:42 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha3 released.\n\n\t* variable.c (mod_name): returns name of the class/module.\n\n\t* parse.y (here_document): finally here document available now.\n\n\t* variable.c (fc_i): some classes/modules does not have iv_tbl.\n\n\t* variable.c (find_class_path): avoid infinite loop.\n\nTue Aug 26 13:43:47 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (rb_eval): undef'ing non-existing method will raise\n\t  NameError exception.\n\n\t* object.c (class_s_new): needed to create metaclass too.\n\n\t* eval.c (error_print): no class name print for anonymous class.\n\n\t* eval.c (rb_longjmp): proper exception raised if raise() called\n\t  without arguments, with $! or $@ set.\n\n\t* object.c (Init_Object): superclass()'s method argument setting\n\t  was wrong again.\n\n\t* class.c (mod_ancestors): list superclasses and included modules\n\t  in priority order.\n\nMon Aug 25 11:53:11 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha2 released.\n\n\t* sample/ruby-mode.el (ruby-parse-region): auto-indent now\n\t  supports \"\\\\\" in the strings.\n\n\t* struct.c (struct_getmember): new API to get member value from C\n\t  language side.\n\nSat Aug 23 21:39:05 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* parse.y (assignable): remove unnecessary local variable\n\t  initialize by nil.\n\nFri Aug 22 14:26:40 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (error_print): modified exception print format.\n\nThu Aug 21 16:10:58 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* sample/ruby-mode.el (ruby-calculate-indent): wrong indent level\n\t  calculated with keyword operators.\n\nThu Aug 21 11:36:58 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* parse.y (arg): ary[0] += 1 cause SEGV\n\nWed Aug 20 17:28:50 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* ruby.c (ruby_process_options): require() all modules after\n\t  processing all options\n\n\t* process.c (rb_proc_exec): more security checks added.\n\n\t* process.c (rb_proc_exec): insecure path on exec.\n\n\t* hash.c (f_getenv): PATH modification security check.\n\nTue Aug 19 00:15:38 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha1 released.\n\n\t* eval.c (mod_eval): work as normal eval() if second binding\n\t  argument given.\n\n\t* eval.c (rb_call): did not raise ArgumentError if too many\n\t  arguments more than optional arguments (without rest arg).\n\n\t* eval.c (rb_eval): did not work well for op_asgn2 (attribute\n\t  self assignment).\n\n\t* eval.c (Init_Thread): returns main thread.\n\nMon Aug 18 09:25:56 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* object.c (inspect_i): did not display T_DATA instance variables.\n\n\t* parse.y: provides more accurate line number information.\n\n\t* eval.c (thread_value): include value's backtrace information in\n\t  the variable `$@'.\n\n\t* eval.c (f_abort): print backtrace and exit.\n\nSat Aug 16 00:17:44 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (class_new_instance): do not make instance from virtual\n\t  classes.\n\n\t* object.c (class_s_new): do not make subclass of singleton class.\n\nFri Aug 15 15:49:46 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* eval.c (call_trace_func): block context switch in the trace\n\t  function.\n\n\t* eval.c (rb_eval): clear method cache at class extension.\n\n\t* object.c (obj_type): returns object's class even if it defines\n\t  singleton methods.\n\nFri Aug 15 19:40:43 1997  WATANABE Hirofumi  <watanabe@ase.ptg.sony.co.jp>\n\n\t* ext/socket/socket.c (Init_socket): small typo caused SEGV.\n\nWed Aug 13 17:51:46 1997  Yukihiro Matsumoto  <matz@netlab.co.jp>\n\n\t* version 1.1 alpha0 released.\n\nLocal variables:\nadd-log-time-format: (lambda ()\n  (let* ((time (current-time))\n  \t (diff (+ (cadr time) 32400))\n\t  (lo (% diff 65536))\n\t  (hi  (+ (car time) (/ diff 65536))))\n    (format-time-string \"%a %b %e %H:%M:%S %Y\" (list hi lo) t)))\nindent-tabs-mode: t\ntab-width: 8\nend:\n"
  },
  {
    "path": "doc/NEWS-1.8.0",
    "content": "= command line options\n\n: -W option\n\n  new option to specify warning level. -W0 to shut up warnings, -W1 for normal level,\n  -W2 for verbose level.  -w equals to -W2.\n\n= language syntax\n\n: arbitrary delimited string array\n\n  %W(...) notation, word list literal like %w(...) with the\n  exception that #{} interpolation is allowed.\n\n: arbitrary delimited symbol literl\n\n  :\"foo\", :\"foo#{bar}\", etc.\n\n: expression interpolation in strings\n\n  Now arbitrary statements are allowed inside #{} interpolation\n  without escapes.  In other hand, they can no longer access to\n  variables defined in eval.\n\n: negative number literals\n\n  Digits preceded minus sign is a literal integer.\n\n: array expansion\n\n  Fixed with the following behavior:\n\n    a = *[1]\n    p a #=> [1]\n\n  Now 1-element array in rhs is expanded properly.\n\n    a = *[1]\n    p a #=> 1\n\n: break and next\n\n  Extended to take an optional expression, which is used as a value\n  for termination.\n\n: direct assignment to Foo::Bar is allowed\n\n  also, you can define \"class Foo::Bar; end\".\n\n= language core\n\n: $stdin, $stdout, $stderr\n\n  can be assignable again.  the original stdio are preserved as STDIN,\n  STDOUT, STDERR.\n\n: $VERBOSE now has 3 levels\n\n  nil - silence, false - medium (default), true - verbose\n\n: allocation framework\n\n  any instance of class can be allocated by class.allocate,\n  (except for a few classes).\n\n: comparison of exception classes in a rescue clause\n\n  changed to use Module#=== for comparing $! with the exception\n  class specified in each rescue clause.\n\n  as the previous behavior was to use kind_of?, the effect is limited\n  to the SystemCallError case.  SystemCallError.=== has been newly\n  defined to return true when the two have the same errno.  With this\n  change, SystemCallError's with the same errno, such as Errno::EAGAIN\n  and Errno::EWOULDBLOCK, can both be rescued by listing just one of\n  them.\n\n: constants lookup\n\n  improved at the performance of searching by using an internal hash\n  table.\n\n  calls const_missing method of the class/module, if constant is not\n  found in the look up path.\n\n: expression parenthesis in the first argument\n\n  altered to get the following code (note the space after p):\n\n    p (\"xx\"*2).to_i\n\n  Interpreted as:\n\n    p ((\"xx\"*2).to_i)\n\n  Instead of:\n\n    (p(\"xx\"*2)).to_i\n\n: implicit comparison in conditional expressions\n\n  Obsoleted except when it is used in -e.\n\n  : between Range and $.\n      Use explicit comparison instead.\n\n  : between Regexp and $_\n      Use the unary method ~/re/ instead.\n\n: to_str\n\n  added to get objects which define to_str() treated as String's.\n\n  now almost all the built-in methods try each argument with to_str()\n  when they expect it to be a String.\n\n    foo = Object.new\n    class <<foo\n      def to_str\n        \"foo\"\n      end\n    end\n    p File.open(foo)\n    => -:7:in `open': wrong argument type Object (expected String) (TypeError)\n       ruby 1.6.4 (2001-04-19) [i586-linux]\n    => -:7:in `open': No such file or directory - \"foo\" (Errno::ENOENT)\n       ruby 1.7.0 (2001-05-02) [i586-linux]\n\n: multiple assignment behavior\n\n  Fixed so that \"*a = nil\" results in \"a == []\".\n\n= changes in core class library\n\n: open\n\n  Extended so that when the third argument is permission flags it\n  calls open(2) instead of fopen(3).\n\n: sprintf\n\n  new format specifier \"%p\" is available.\n\n: lambda and proc\n\n  Proc object returns from these methods has the following attributes:\n\n  * strict argument number check\n  * break and return terminates the proc execution.\n\n: warn(message)\n\n  a method to give warnings.\n\n: abort()\n\n  takes optional terminate message argument.\n\n: Object#initialize_copy\n\n  copy constructor for clone and dup.\n\n: Object#instance_variable_set, Object#instance_variable_get\n\n  added.\n\n: Object#singleton_method_removed\n: Object#singleton_method_undefined\n\n  Added.\n\n: Array#transpose\n\n  added.\n\n: Array#fetch(index [, default])\n\n  Added.  If a default value isn't given, raises index error if index\n  is out of range.\n\n: Array#insert(n, other, ...)\n\n  Added. [ruby-talk:14289]\n\n  This is much the same as (({ary[n,0] = [other,...]})) except\n  returing self.\n\n    ary = [0,1,2,3]\n    ary[2, 0] = [4, 5, 6]\n    p ary\n\n    ary = [0,1,2,3]\n    ary.insert(2, 4, 5, 6)\n    p ary\n\n: Array#sort!\n\n  Changed to always return self without checking whether the sequence\n  of the elements was modified or not.\n\n  Beware that this behavior is not guaranteed to continue in the\n  future.  Do not rely on its return value. [ruby-dev:12506]\n\n: Array#filter\n\n  Previously deprecated, now removed.  Use Array#collect!.\n\n: Array#pack, String#unpack\n\n  Allows comment in template strings.\n\n: Array#pack, String#unpack\n\n  New templates 'q' and 'Q' for 64bit integer (signed and unsigned respectively).\n\n: Array#new\n\n  Now takes block to fill initial values.  E.g.\n\n\tArray.new(10) { |i| i + 1 }\n\t=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n: Array#fill\n\n  Takes block to get the values to fill.\n\n: Array#fetch\n\n  Takes block to get the default value.\n\n: Array#zip\n\n  added.\n\n: Hash#update\n\n  Takes block to resolve key conflict.\n\n: Hash#merge and Hash#merge!\n\n  update hash.  Hash#merge! is a synonym of Hash#update.\n\n: String#split\n\n  if \"sep\" argument is a string, regular expression meta characters\n  are escaped internally.\n\n: String#rstrip\n\n  chop off NULs at the end of strings.\n\n: String#to_i\n\n  Now accepts optional base argument.\n\n\t\"101\".to_i(10) => 101\n\t\"101\".to_i(2)  => 5\n\t\"101\".to_i(8)  => 65\n\t\"101\".to_i(16) => 257\n\n  A base argument of 0 guesses at the base.\n\n\t\"101\".to_i(0)   => 101\n\t\"0b101\".to_i(0) => 5\n\t\"0101\".to_i(0)  => 65\n\t\"0x101\".to_i(0) => 257\n\n: String#[regexp, nth]\n\n  Extended to accepts optional second argument.\n\n  It tries match between self and REGEXP, then returns the\n  content of the NTH regexp register.\n\n: String#casecmp\n\n  Added.  This is a case insensitive version of String#<=>.\n\n: String#chomp\n\n  If $/ == \"\\n\", chops off last newlines (any of \\n, \\r, \\r\\n).\n\n: String#eql?\n\n  Changed to be always case sensitive.\n\n: String#insert(n, other)\n\n  Added.\n\n  This is much the same as (({str[n, 0] = other})) except returing\n  self.\n\n: String#lstrip, rstrip, lstrip!, rstrip!\n\n  Added.  These strip only left or right part of a string.\n\n: String#match\n\n  Added.\n\n: String/Array methods\n\n  Returns an instance of receivers class.\n\n: String.new\n\n  The first argument becomes optional.\n\n: Symbol#intern\n\n  Added.\n\n: Symbol.all_symbols\n\n  Added. [ruby-dev:12921]\n\n: IO\n\n  64bit off_t support by Janathan Baker.\n\n: IO#read\n: IO#sysread\n\n  takes optinal second argument for read buffer.\n\n: IO::sysopen\n\n  New method to get a raw file descriptor.\n\n: IO#sysseek\n\n  Added.\n\n: IO#fsync\n\n  new method that copies all in-memory parts of a file to disk and\n  waits until the device reports that all parts are on stable storage.\n  Implemented with fsync(2) or equivalent.\n\n: IO.open\n\n  Made public.  Can only associate an IO object with a file number\n  like IO.new and IO.for_fd, but can take a block.\n\n: IO.for_fd\n\n  Added as a synonym for IO.new.\n\n: IO.read\n\n  Added.  Like IO.readlines, except it returns the entire file as a\n  string.  [ruby-talk:9460]\n\n: File#fnmatch, File::Constants::FNM_*\n\n  Added.  Refer to the fnmatch(3) manpage for details.\n\n  Localism is FNM_DOTMATCH which has the opposite meaning of the\n  commonly known FNM_PERIOD, which does not exist in Ruby.\n\n  e.g.\n\n    # exclude files matching \"*.bak\" case-insensitively.\n    files.reject! {|fn| File.fnmatch?(\"*.bak\", fn, File::FNM_CASEFOLD) }\n\n: File.lchmod\n: File.lchown\n\n  Added.\n\n: File.open, IO.open\n\n  File mode can be specified by flags like open(2),\n  e.g. File::open(path, File::CREAT|File::WRONLY).\n\n: Regexp#options\n\n  Added.\n\n: Regexp.last_match(n)\n\n  Extended to take an optional argument.\n\n: MatchData#captures\n\n  added.\n\n: Dir#path\n\n  Added.\n\n: Dir.chdir\n\n  Extended to take a block.\n\n: Dir.glob\n\n  Made to support meta-character escaping by a backslash.  Wildcards\n  and spaces may now be escaped using a backslash.\n\n: Dir.open\n\n  Changed to return what the block returns when a block is given, just\n  as File.open does. (It always returned (({nil})) in 1.6 and\n  prior)\n\n: Dir.chdir\n\n  Changed to warn only when invoked from multiple threads or no block\n  is given. [ruby-dev:13823]\n\n    Dir.chdir('foo') {\n      Dir.chdir('bar') {   # previously warned\n        puts Dir.pwd\n      }\n    }\n\n: Dir#pos=\n\n  Returns the new position instead of self.\n\n: Dir::glob\n\n  Now accepts optional FNM_* flags via the second argument, whereas\n  Dir::[] doesn't.\n\n    Dir.glob(\"makefile\", File::FNM_CASEFOLD) #=> ['Makefile', 'makefile']\n\n: Class#inherited\n\n  Method is called when Class is inherited by another class.\n\n\tclass A; end\n\tdef A.inherited(by)\n          puts \"A inherited by #{by.inspect}\"\n        end\n        class B < A; end\n\n        Prints out \"A inherited by B\"\n\n: Module#include?\n\n  Added. [ruby-dev:13941] \n\n: Module#included\n\n  Added.  This is a hook called after Module#append_feature.\n\n: Module#method_removed\n: Module#method_undefined\n\n  Added.\n\n: Module.new, Class.new\n\n  Extended to take block.\n\n: Time\n\n  Extended to accept a negative time_t. (Only when the platform\n  supports it)\n\n    p Time.at(-1)\n    => Thu Jan 01 08:59:59 JST 1970\n\n: Time#to_a\n: Time#zone\n\n  Made to return \"UTC\" under gmtime.  It used to return a platform\n  dependent value, typically \"GMT\", in 1.6 and prior.\n\n: Marshal to use marshal_dump and marshal_load\n\n  if a dumping object responds to 'marshal_dump', Marshal.dump calls\n  it, and dumps object returned.  Marshal.load allocates a new instance\n  using \"allocate\", then calls its \"marshal_load\" with dumped data.\n  Marshal format version is now 4.8 (was 4.6 in 1.6.8).\n\n: Marshal\n\n  Fixed not to dump anonymous classes/modules.\n\n  Fixed with loading modules.\n\n: Thread#group\n\n  new method to get belonging  ThreadGroup.\n\n: Thread#terminate\n\n  synonym of Thread#exit\n\n: Thread#join\n\n  Optional argument limits maximum time to wait the thread in second.\n  And returns nil if timed out.\n\n: ThreagGroup#enclose\n\n  prohibits thread movement from/to enclosed groups.\n\n: Range#step([step=1])\n\n  Added.\n\n: SystemCallError\n\n  SystemCallError's \"===\" match (used in rescue also) is now based on its errno.\n\n: Interrupt\n\n  Made a subclass of SignalException. (It was a subclass of\n  Exception in 1.6 and prior)\n\n: NameError and NoMethodError\n\n  Moved and now NoMethodError < NameError < StandardError.\n\n: NoMethodError\n\n  Added. [ruby-dev:12763]\n\n: NotImplementError\n\n  Finally obsoleted.  Use NotImplementedError.\n\n: SystemCallError.===\n\n  Added. (See the \"Comparison of exception classes in a rescue clause\"\n  paragraph above) [ruby-dev:12670]\n\n: SystemExit#status\n\n  Added.\n\n: Proc#==\n\n  Added.\n\n: Method#==\n\n  Added.\n\n: UnboundMethod is no longer subclass of Method\n\n  class hierarchy changed. \n\n: Enumerable#all?\n: Enumerable#any?\n: Enumerable#inject\n: Enumerable#sort_by\n\n  Added.\n\n: Math.acos(x)\n: Math.asin(x)\n: Math.atan(x)\n: Math.cosh(x)\n: Math.hypot(x,y)\n: Math.sinh(x)\n: Math.tanh(x)\n\n  Added.\n\n: Process.abort\n: Process.exit\n\n  synonym of Kernel#abort, and Kernel#exit respectively.\n\n: Process::detach(pid)\n\n  new method to detach child process.  child process will be \"wait\"ed\n  automagically.\n\n: Process.times\n\n  Moved from Time.times. (Time.times still remains but emits a\n  warning)\n\n: Process.waitall\n\n  Added.\n\n: Process::Status\n\n  Added.  (({$?})) is now an instance of this class.\n\n: Process::UID, Process::GID, Process::Sys,\n\n  Added.\n\n: Signal\n\n  Added. This module has module functions Signal.trap and Signal.list.\n\n= changes in bundled libraries\n\n: lib/cgi.rb\n\n  cgi[name] returns CGI::QueryExtension::Value that wraps string\n  value, no longer array.\n\n: lib/timeout\n\n  timeout \"function\" wrapped in Timeout module.\n\n: TCPServer#accept, UNIXServer#accept, Socket#accept\n\n  New methods to return an accepted socket fd.\n\n: Date and DateTime\n\n  lib/date.rb now provides both Date and DateTime.\n\n  Some methods have been renamed.  But the old names are still alive.\n\n  Some new methods have been added (Date::parse, Date#strftime, etc.).\n\n  Date#mjd now returns the chronological modified Julian day number.\n\n  All facilities about tjd have been removed.\n\n: Curses\n\n  Updated.  New methods and constants for using the mouse, character\n  attributes, colors and key codes have been added.\n\n: Net::HTTP\n\n  New version of Net::HTTP has introduced seriously incompatible\n  changes. For details, see document embedded in net/http.rb itself.\n\n: Socket.pack_sockaddr_in, Socket.unpack_sockaddr_in\n\n  Added.  Utility for direct Socket access.\n\n: Socket.pack_sockaddr_un, Socket.unpack_sockaddr_un\n\n  Added.  Utility for direct Socket access.\n\n: TCPServer#listen, UNIXServer#listen\n\n  Added.\n\n: TCPSocket.new\n: TCPSocket.open\n\n  Extended to take an address and a port number for the local side in\n  optional 3rd and 4th arguments.\n\n= newly bundled library\n\n: ext/bigdecimal\n\n  variable precision decimal number \n\n: ext/dl\n\n  an interface to the dynamic linker.\n\n: ext/enumerator\n\n  a helper module for the Enumerable interface.\n\n: ext/io/wait\n\n  IO wait methods.\n\n: ext/iconv\n\n  wrapper library of (({iconv})).\n\n: ext/openssl\n\n  OpenSSL for Ruby\n\n: ext/racc/cparse\n\n  Racc runtime library in C. (Racc is a parser generator for ruby)\n\n: ext/stringio\n\n  Pseudo (({IO})) class from/to (({String})).\n\n: ext/strscan\n\n  Fast string scanner library.\n\n: ext/syck\n\n  fast YAML parser.\n\n: lib/abbrev\n\n  creates an abbreviation table from a list\n\n: lib/benchmark\n\n  Ruby scripts benchmarker\n\n: lib/cgi/session/pstore\n\n  cgi/session back-end using pstore \n\n: lib/csv\n\n  reads/writes CSV files.\n\n: lib/date/format\n\n  strftime for Date class\n\n: lib/drb\n\n  dRuby or distributed Ruby\n\n: lib/fileutils\n\n  file utility library.\n\n: lib/generator\n\n  converts an internal iterator to an external iterator\n\n: lib/gserver\n\n  generic server used by xmlrpc\n\n: lib/ipaddr\n\n  manipulates IP address.\n\n: lib/multi-tk\n\n  to allow safe Tk, etc.\n\n: lib/open-uri\n\n  easy-to-use wrapper for net/http and net/ftp\n\n: lib/optparse\n\n  command line options utility library\n\n: lib/pathname\n\n  handles pathname in OO manner.\n\n: lib/pp\n\n  prettyprinter for Ruby objects\n\n: lib/prettyprint\n\n  implements prettyprint algorithm.\n\n: lib/profiler\n\n  library to implement -r \"profile\"\n\n: lib/racc/parser\n\n  RACC parser generator runtime in Ruby.\n\n: lib/scanf\n\n  scan string and retrieve object with format\n\n: lib/set\n\n  Set class\n\n: lib/runit\n\n  RubyUnit compatible layer for test/unit\n\n: lib/test/unit\n\n  unit testing framework for Ruby\n\n: lib/tmpdir\n\n  get temporary directory path.\n\n: lib/tsort\n\n  topological sorting library.\n\n: lib/rexml\n\n  REXML XML library\n\n: lib/webrick\n\n  generic internet server kit\n\n: lib/xmlrpc\n\n  simple RPC via XML\n\n: lib/un\n\n  used like 'ruby -run -e cp -- -p foo bar'.  neat, isn't it?\n\n: lib/win32/registry\n\n  win32/registry is registry accessor\n\n: lib/yaml\n\n  YAML Ain't Mark-up Language\n\n= removed libraries\n\n: lib/ftplib\n\n  use net/ftp instead.\n\n: lib/telnet\n\n  use net/telnet instead.\n\n= new port\n\n: WindowsCE port\n: Win32 BCC\n\n= interpreter implementation\n\n: garbage collector\n\n  faster, but uses more memory for the worst case.\n\n: string concatenation\n\n  faster by avoiding too frequent realloc(3).\n"
  },
  {
    "path": "doc/forwardable.rd",
    "content": " -- forwardable.rb\n\t\t\t\t\t\t\n                                                $Release Version: 1.1 $\n                                                $Revision$\n                                                $Date$\n\t\t\t\t\t\tOriginal version by Tosh\n\n=begin\n\n= Forwardable\n\nA Module to define delegations for selected methods to a class.\n\n== Usage\n\nUsing through extending the class.\n  \n  class Foo\n    extend Forwardable\n\n    def_delegators(\"@out\", \"printf\", \"print\")\n    def_delegators(:@in, :gets)\n    def_delegator(:@contents, :[], \"content_at\")\n  end\n  f = Foo.new\n  f.printf ...\n  f.gets\n  f.content_at(1)\n\n== Methods\n\n--- Forwardable#def_instance_delegators(accessor, *methods)\n\n      adding the delegations for each method of ((|methods|)) to\n      ((|accessor|)).\n\n--- Forwardable#def_instance_delegator(accessor, method, ali = method)\n      \n      adding the delegation for ((|method|)) to ((|accessor|)). When\n      you give optional argument ((|ali|)), ((|ali|)) is used as the\n      name of the delegation method, instead of ((|method|)).\n\n--- Forwardable#def_delegators(accessor, *methods)\n\n      the alias of ((|Forwardable#def_instance_delegators|)).\n\n--- Forwardable#def_delegator(accessor, method, ali = method)\n      \n      the alias of ((|Forwardable#def_instance_delegator|)).\n\n= SingleForwardable\n\na Module to define delegations for selected methods to an object.\n\n== Usage\n\nUsing through extending the object.\n\n  g = Goo.new\n  g.extend SingleForwardable\n  g.def_delegator(\"@out\", :puts)\n  g.puts ...\n\n== Methods\n\n--- SingleForwardable#def_singleton_delegators(accessor, *methods)\n\n      adding the delegations for each method of ((|methods|)) to\n      ((|accessor|)).\n\n--- SingleForwardable#def_singleton_delegator(accessor, method, ali = method)\n\n      adding the delegation for ((|method|)) to ((|accessor|)). When\n      you give optional argument ((|ali|)), ((|ali|)) is used as the\n      name of the delegation method, instead of ((|method|)).\n\n--- SingleForwardable#def_delegators(accessor, *methods)\n\n      the alias of ((|SingleForwardable#def_instance_delegators|)).\n\n--- SingleForwardable#def_delegator(accessor, method, ali = method)\n\n      the alias of ((|SingleForwardable#def_instance_delegator|)).\n=end\n"
  },
  {
    "path": "doc/forwardable.rd.ja",
    "content": "  -- forwatable.rb\n                                                $Release Version: 1.1 $\n                                                $Revision$\n                                                $Date$\n\n=begin\n= Forwardable\n\n饹Ф᥽åɤΰѾǽޤ.\n\n== Ȥ\n\n饹ФextendƻȤޤ. \n  \n  class Foo\n    extend Forwardable\n\n    def_delegators(\"@out\", \"printf\", \"print\")\n    def_delegators(:@in, :gets)\n    def_delegator(:@contents, :[], \"content_at\")\n  end\n  f = Foo.new\n  f.printf ...\n  f.gets\n  f.content_at(1)\n\n== ᥽å\n\n--- Forwardable#def_instance_delegators(accessor, *methods)\n\n      ((|methods|))Ϥ줿᥽åɤΥꥹȤ((|accessor|))Ѿ\n      褦ˤޤ.\n\n--- Forwardable#def_instance_delegator(accessor, method, ali = method)\n\n      ((||method|))Ϥ줿᥽åɤ((|accessor|))˰Ѿ褦ˤ\n      ޤ. ((|ali|))ȤϤ줿Ȥ, ᥽å((|ali|))Ƥ\n      줿Ȥˤ, ((|accessor|))Ф((|method|))ƤӽФޤ.\n\n--- Forwardable#def_delegators(accessor, *methods)\n\n      ((|Forwardable#def_instance_delegators|))̾Ǥ.\n\n--- Forwardable#def_delegator(accessor, method, ali = method)\n\n      ((|Forwardable#def_instance_delegator|))̾Ǥ.\n\n= SingleForwardable\n\n֥ȤФ, ᥽åɤΰѾǽޤ.\n\n== Ȥ\n\n֥ȤФ((|extend|))ƻȤޤ. \n\n  g = Goo.new\n  g.extend SingleForwardable\n  g.def_delegator(\"@out\", :puts)\n  g.puts ...\n\n== ᥽å\n\n--- SingleForwardable#def_singleton_delegators(accessor, *methods)\n\n      ((|methods|))Ϥ줿᥽åɤΥꥹȤ((|accessor|))˰Ѿ\n      褦ˤޤ.\n\n--- SingleForwardable#def_singleton_delegator(accessor, method, ali = method)\n\n      ((|method|))Ϥ줿᥽åɤ((|accessor|))˰Ѿ褦ˤ\n      . ((|ali|))ȤϤ줿Ȥ, ᥽å((|ali|))ƤФ\n      Ȥˤ, ((|accessor|))Ф((|method|))ƤӽФޤ.\n\n--- SingleForwardable#def_delegators(accessor, *methods)\n\n      ((|SingleForwardable#def_singleton_delegators|))̾Ǥ.\n\n--- SingleForwardable#def_delegator(accessor, method, ali = method)\n\n      ((|SingleForwardable#def_singleton_delegator|))̾Ǥ.\n=end\n"
  },
  {
    "path": "doc/irb/irb-tools.rd.ja",
    "content": "irbϢޤޥɤȥ饤֥\n\t\t\t\t$Release Version: 0.7.1 $\n\t\t\t   \t$Revision$\n\t\t\t   \t$Date$\n\t\t\t   \tby Keiju ISHITSUKA(Nihon Rational Co.,Ltd.)\n\n=begin\n\n:ޥ:\n* rtags\t\t-- ruby tags command\n\n:ؿ饤֥:\n* xmp\t\t-- irb version of gotoken xmp-function\n\n:饹饤֥:\n* frame.rb      -- frame tracer\n* completion.rb -- irb completor\n\n= rtags\n\nrtagsemacsڤviѤ, TAGեĤ륳ޥɤǤ.\n\n== Ȥ\n\n   rtags [-vi] file....\n\nȥǥ쥯ȥemacsѤTAGSե뤬Ǥޤ. -viץ\nĤˤviѤtagsեޤ.\n\nemacsξ, ̾etags.elΤޤ޻Ȥޤ. ǽʤΤ,\n\n* 饹\n* ᥽å\n* ðۥ᥽å\n* alias\n* attr줿(ѥ᡼ܥ뤫ʸƥ˸¤)\n* attr_XXX줿(ѥ᡼ܥ뤫ʸƥ˸¤)\n\nǤ.\n\nCʤɤǻȤäƤΤȰ㤦Τ, ץ꡼˴ؤʬ,\n\nؿ̾,\n\n  ؿ̾(\n\n饹,\n\n  ::饹̾::....::饹̾\n\n᥽åɤ,\n\n  ::饹̾::....::饹̾#᥽å̾\n\nðۥ᥽å(饹᥽å)\n\n  ::饹̾::....::饹̾.᥽å̾\n\nǥץ꡼ԤʤȤǤ.\n\n= xmp.rb\n\nȤxmpξ̸ߴСǤ. , ˽ŤΤǤȤxmp\nбǤʤ, ѤɤǤ礦.\n\n== Ȥ\n\n=== ؿȤƻȤ.\n\n    require \"irb/xmp\"\n    xmp <<END\n    foo = 1\n    foo\n    END\n    ---\n    foo = 1\n        ==>1\n    foo\n\t==>1\n\n=== XMP󥹥󥹤Ѥ.\n\nξ, XMPƥȾĤΤ, ѿͤʤɤݻƤ\nޤ.\n\n  require \"irb/xmp\"\n  xmp = XMP.new\n  xmp.puts <<END\n  foo = 1\n  foo\n  END\n  xmp.puts <<END\n  foo\n  END\n  ===\n  foo = 1\n      ==>1\n  foo\n      ==>1\n  foo\n      ==>1\n\n== ƥȤ˴ؤ\n\nXMP᥽åɷΥƥȤ, ƤӽФΥƥȤɾޤ.\nŪ˥ƥȤꤹȤΥƥȤɾޤ.\n\n:\n\n  xmp \"foo\", an_binding\n\n::\nޥåɤˤбƤޤ.\n\n= frame.rb\n߼¹Υե졼갷Υ饹Ǥ. \n\n* IRB::Frame.top(n = 0)\n  夫nܤΥƥȤФޤ. n0Ǿ̤ˤʤޤ.\n* IRB::Frame.bottom(n = 0)\n  nܤΥƥȤФޤ. n0ǲ̤ˤʤޤ.\n* IRB::Frame.sender\n  ˤʤäƤ륪֥ȤФޤ. Ȥ, Υ᥽\n  ɤƤӽФ¦selfΤȤǤ.\n\n::\nset_trace_funcѤRubyμ¹Ԥȥ졼Ƥޤ. ޥåɤ\nбƤޤ.\n\n= completion.rb\nirbcompletionǽ󶡤ΤǤ. \n\n== Ȥ\n\n   % irb -r irb/completion\n\nȤ뤫, ~/.irbrc \n\n   require \"irb/completion\"\n\nƤ. irb¹ require \"irb/completion\" Ƥ褤Ǥ.\n\nirb¹ (TAB) 򲡤ȥץ졼󤷤ޤ.\n\nȥåץ٥(TAB)򲡤Ȥ٤Ƥιʸ, 饹, ᥽åɤθ䤬\nޤ. 䤬ͣʤд䴰ޤ.\n\n  irb(main):001:0> in    \n  in                    inspect               instance_eval\n  include               install_alias_method  instance_of?\n  initialize            install_aliases       instance_variables\n  irb(main):001:0> inspect\n  \"main\"\n  irb(main):002:0> foo = Object.new\n  #<Object:0x4027146c>\n\n  ((|ѿ̾.|))θ(TAB)򲡤, Υ֥ȤΥ᥽åɰǤ\n  .\n\n  irb(main):003:0> foo.\n  foo.==                  foo.frozen?             foo.protected_methods\n  foo.===                 foo.hash                foo.public_methods\n  foo.=~                  foo.id                  foo.respond_to?\n  foo.__id__              foo.inspect             foo.send\n  foo.__send__            foo.instance_eval       foo.singleton_methods\n  foo.class               foo.instance_of?        foo.taint\n  foo.clone               foo.instance_variables  foo.tainted?\n  foo.display             foo.is_a?               foo.to_a\n  foo.dup                 foo.kind_of?            foo.to_s\n  foo.eql?                foo.method              foo.type\n  foo.equal?              foo.methods             foo.untaint\n  foo.extend              foo.nil?                \n  foo.freeze              foo.private_methods     \n\n=end\n\n% Begin Emacs Environment\n% Local Variables:\n% mode: text\n% comment-column: 0\n% comment-start: \"%\"\n% comment-end: \"\\n\"\n% End:\n%\n\n"
  },
  {
    "path": "doc/irb/irb.rd",
    "content": "irb -- interactive ruby\n\t\t$Release Version: 0.9 $\n\t\t$Revision$\n\t\t$Date$\n\t\tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n\t\tby gotoken-san who is original translater from japanese version\n\n=begin\n= What is irb?\n\nirb stands for `interactive ruby'. irb is a tool to execute interactively\nruby expressions read from stdin. \n\n= Invoking\n\n  % irb\n\n= Usage\n\nUse of irb is easy if you know ruby.  Executing irb, prompts are \ndisplayed as follows. Then, enter expression of ruby. A input is\nexecuted when it is syntacticaly completed. \n\n  dim% irb\n  irb(main):001:0> 1+2\n  3\n  irb(main):002:0> class Foo\n  irb(main):003:1>  def foo\n  irb(main):004:2>    print 1\n  irb(main):005:2>  end\n  irb(main):006:1> end\n  nil\n  irb(main):007:0> \n\nAnd, Readline extesion module can be used with irb. Using Readline\nis the standard default action if Readline is installed. \n\n= Command line option\n\n  irb.rb [options] file_name opts\n  options:\n  -f\t\t    suppress read ~/.irbrc \n  -m\t\t    bc mode (fraction or matrix are available)\n  -d                set $DEBUG  to true (same as `ruby -d')\n  -Kc\t\t    same as `ruby -Kc'\n  -r load-module    same as `ruby -r'\n  --verbose\t    command input is echoed(default)\n  --noverbose\t    command input isn't echoed\n  --echo\t    commands are echoed immediately before execution(default)\n  --noecho\t    commands aren't echoed immediately before execution\n  --inspect\t    uses `inspect' for output (the default except bc mode)\n  --noinspect\t    doesn't uses inspect for output\n  --readline\t    uses Readline extension module\n  --noreadline\t    doesn't use Readline extension module\n  --prompt prompt-mode\n  --prompt-mode prompt-mode\n\t\t    switches prompt mode. Pre-defined prompt modes are\n\t\t    `default', `simple', `xmp' and `inf-ruby'\n\t\t\t    \n  --inf-ruby-mode   uses prompt appreciate for inf-ruby-mode on emacs. \n\t\t    Suppresses --readline. \n  --simple-prompt   simple prompt mode\n  --noprompt\t    no prompt\n  --tracer\t    display trace for each execution of commands.\n  --back-trace-limit n\n\t\t    displayes backtrace top n and tail n. The default\n\t\t    value is 16. \n  --irb_debug n\t    sets internal debug level to n (It shouldn't be used)\n  -v, --version\t    prints the version of irb\n\n= Configurations\n\nirb reads `~/.irbrc' when it is invoked. If `~/.irbrb' doesn't exist\nirb try to read in the order `.irbrc', `irb.rc', `_irbrc' then `$irbrc'. \n\nThe following is altanative to the command line option. To use them\ntype as follows in an irb session. \n\n  IRB.conf[:IRB_NAME]=\"irb\"\n  IRB.conf[:MATH_MODE]=false\n  IRB.conf[:USE_TRACER]=false\n  IRB.conf[:USE_LOADER]=false\n  IRB.conf[:IGNORE_SIGINT]=true\n  IRB.conf[:IGNORE_EOF]=false\n  IRB.conf[:INSPECT_MODE]=nil\n  IRB.conf[:IRB_RC] = nil\n  IRB.conf[:BACK_TRACE_LIMIT]=16\n  IRB.conf[:USE_LOADER] = false\n  IRB.conf[:USE_READLINE] = nil\n  IRB.conf[:USE_TRACER] = false\n  IRB.conf[:IGNORE_SIGINT] = true\n  IRB.conf[:IGNORE_EOF] = false\n  IRB.conf[:PROMPT_MODE] = :DEFALUT\n  IRB.conf[:PROMPT] = {...}\n  IRB.conf[:DEBUG_LEVEL]=0\n  IRB.conf[:VERBOSE]=true\n\n== Customizing prompt\n\nTo costomize the prompt you set a variable\n\n  IRB.conf[:PROMPT]\n\nFor example, describe as follows in `.irbrc'. \n\n  IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode\n    :PROMPT_I => nil,\t\t  # normal prompt\n    :PROMPT_S => nil,\t\t  # prompt for continuated strings\n    :PROMPT_C => nil,\t\t  # prompt for continuated statement\n    :RETURN => \"    ==>%s\\n\"\t  # format to return value\n  }\n\nThen, invoke irb with the above prompt mode by\n\n  % irb --prompt my-prompt\n\nOr add the following in `.irbrc'. \n\n  IRB.conf[:PROMPT_MODE] = :MY_PROMPT\n\nConstants PROMPT_I, PROMPT_S and PROMPT_C specifies the format. \nIn the prompt specification, some special strings are available. \n\n  %N\tcommand name which is running\n  %m\tto_s of main object (self)\n  %M\tinspect of main object (self)\n  %l\ttype of string(\", ', /, ]), `]' is inner %w[...]\n  %NNi\tindent level. NN is degits and means as same as printf(\"%NNd\"). \n        It can be ommited\n  %NNn\tline number. \n  %%    %\n\nFor instance, the default prompt mode is defined as follows:\n\nIRB.conf[:PROMPT_MODE][:DEFAULT] = {\n      :PROMPT_I => \"%N(%m):%03n:%i> \",\n      :PROMPT_S => \"%N(%m):%03n:%i%l \",\n      :PROMPT_C => \"%N(%m):%03n:%i* \",\n      :RETURN => \"%s\\n\"\n} \n\nRETURN is used to printf. \n\n== Configurating subirb\n\nThe command line option or IRB.conf specify the default behavior of\n(sub)irb. On the other hand, each conf of in the next sction `6. Command' \nis used to individually configurate (sub)irb. \n\nIf proc is set to IRB.conf[:IRB_RC], its subirb will be invoked after\nexecution of that proc under giving the context of irb as its\naregument. By this mechanism each subirb can be configurated. \n\n= Command\n\nFor irb commands, both simple name and `irb_'-prefixed name are prepared. \n\n--- exit, quit, irb_exit\t\n    Quits (sub)irb. \n\n--- conf, irb_context\n    Displays current configuration. Modifing the configuration is\n    achieved by sending message to `conf'. \n\n--- conf.eval_history = N\n    Sets execution result history.\n    N is a integer or nil. If N > 0, the number of historys is N. \n    If N == 0, the number of historys is unlimited. If N is nill,\n    execution result history isn't used(default).\n\n--- conf.back_trace_limit\n    Sets display lines of backtrace as top n and tail n. \n    The default value is 16.\n    \n--- conf.debug_level = N\n    Sets debug level of irb. \n\n--- conf.ignore_eof = true/false\n    Whether ^D (control-d) will be ignored or not. \n    If false is set, ^D means quit. \n\n--- conf.ignore_sigint= true/false\n    Whether ^C (control-c) will be ignored or not. \n    If false is set, ^D means quit.  If true, \n      during input:   cancel inputing then return to top level. \n      during execute: abondon current execution. \n\n--- conf.inf_ruby_mode = true/false\n    Whether inf-ruby-mode or not. The default value is false.\n\n--- conf.inspect_mode = true/false/nil\n    Specifies inspect mode. \n    true:  display inspect\n    false: display to_s\n    nil:   inspect mode in non math mode, \n           non inspect mode in math mode. \n\n--- conf.math_mode\n    Whether bc mode or not. \n\n--- conf.use_loader = true/false\n    Whether irb's own file reader method is used when load/require or not. \n    This mode is globaly affected (irb wide). \n\n--- conf.prompt_c\n    prompt for a continuating statement (e.g, immediately after of `if')\n\n--- conf.prompt_i\n    standard prompt\n\n--- conf.prompt_s\n    prompt for a continuating string\n\n--- conf.rc\n    Whether ~/.irbrc is read or not. \n\n--- conf.use_prompt = true/false\n    Prompting or not. \n\n--- conf.use_readline = true/false/nil\n    Whether readline is used or not. \n    true: uses \n    false: doen't use\n    nil: intends to use readline except for inf-ruby-mode (default)\n#\n#--- conf.verbose=T/F\n#    Whether verbose messages are display or not. \n\n--- cws, chws, irb_change_workspace [obj]\n    obj will be self. If obj is omitted, self will be home-object, or\n    the main object of first started irb.\n\n--- pushws, irb_pushws, irb_push_workspace [obj]\n    same as UNIX-shell command pushd.\n\n--- popws, irb_popws, irb_pop_workspace\n    same as UNIX-shell command popd\n\n--- irb [obj]\n    Invoke subirb. If obj is given, obj will be self. \n\n--- jobs, irb_jobs\n    List of subirb\n\n--- fg n, irb_fg n\n    Switch into specified subirb. The following is candidates of n:\n\n      irb number\n      thhread\n      irb object\n      self(obj which is specified of irb obj)\n\n--- kill n, irb_kill n\n    Kill subirb. The means of n is as same as the case of irb_fg. \n\n--- souce, irb_source  path\n    This is a like UNIX-shell command source. evaluate script in path\n    on current context.\n\n--- irb_load path, prev\n    irb-version of Ruby's load.\n\n= System variable\n\n--- _  The latest value of evaluation (it is local)\n--- __ The history of evaluation values.\n    __[line_no] return an evaluation value of line number<line_no>. If\n    line_no is a negative, return value before -<line_no> from latest\n    value.\n\n= Session Example\n\n  dim% ruby irb.rb\n  irb(main):001:0> irb                        # invoke subirb\n  irb#1(main):001:0> jobs                     # list of subirbs\n  #0->irb on main (#<Thread:0x400fb7e4> : stop)\n  #1->irb#1 on main (#<Thread:0x40125d64> : running)\n  nil\n  irb#1(main):002:0> fg 0                     # switch job\n  nil\n  irb(main):002:0> class Foo;end\n  nil\n  irb(main):003:0> irb Foo                    # invoke subirb which has the \n\t\t\t\t\t      #              context of Foo\n  irb#2(Foo):001:0> def foo                   # define Foo#foo\n  irb#2(Foo):002:1>   print 1\n  irb#2(Foo):003:1> end\n  nil\n  irb#2(Foo):004:0> fg 0                      # switch job\n  nil\n  irb(main):004:0> jobs                       # list of job\n  #0->irb on main (#<Thread:0x400fb7e4> : running)\n  #1->irb#1 on main (#<Thread:0x40125d64> : stop)\n  #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)\n  nil\n  irb(main):005:0> Foo.instance_methods       # Foo#foo is defined asurely\n  [\"foo\"]\n  irb(main):006:0> fg 2                       # switch job\n  nil\n  irb#2(Foo):005:0> def bar                   # define Foo#bar\n  irb#2(Foo):006:1>  print \"bar\"\n  irb#2(Foo):007:1> end\n  nil\n  irb#2(Foo):010:0>  Foo.instance_methods\n  [\"bar\", \"foo\"]\n  irb#2(Foo):011:0> fg 0                      \n  nil\n  irb(main):007:0> f = Foo.new\n  #<Foo:0x4010af3c>\n  irb(main):008:0> irb f                      # invoke subirb which has the\n\t\t\t\t\t      #  context of f (instance of Foo)\n  irb#3(#<Foo:0x4010af3c>):001:0> jobs\n  #0->irb on main (#<Thread:0x400fb7e4> : stop)\n  #1->irb#1 on main (#<Thread:0x40125d64> : stop)\n  #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)\n  #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)\n  nil\n  irb#3(#<Foo:0x4010af3c>):002:0> foo         # evaluate f.foo\n  1nil\n  irb#3(#<Foo:0x4010af3c>):003:0> bar         # evaluate f.bar\n  barnil\n  irb#3(#<Foo:0x4010af3c>):004:0> kill 1, 2, 3# kill job\n  nil\n  irb(main):009:0> jobs\n  #0->irb on main (#<Thread:0x400fb7e4> : running)\n  nil\n  irb(main):010:0> exit                       # exit\n  dim% \n\n= Restrictions\n\nBecause irb evaluates the inputs immediately after the imput is\nsyntactically completed, irb gives slight different result than\ndirectly use ruby. Known difference is pointed out here. \n\n\n== Declaration of the local variable\n\nThe following causes an error in ruby:\n\n  eval \"foo = 0\"\n  foo\n  --\n  -:2: undefined local variable or method `foo' for #<Object:0x40283118> (NameError)\n  ---\n  NameError\n\nThough, the above will successfully done by irb. \n\n  >> eval \"foo = 0\"\n => 0\n >> foo\n => 0\n\nRuby evaluates a code after reading entire of code and determination\nof the scope of local variables. On the other hand, irb do\nimmediately. More precisely, irb evaluate at first\n\n  evel \"foo = 0\" \n\nthen foo is defined on this timing. It is because of this\nincompatibility.\n\nIf you'd like to detect those differences, begin...end can be used:\n\n  >> begin\n  ?>   eval \"foo = 0\"\n  >>   foo\n  >> end\n  NameError: undefined local variable or method `foo' for #<Object:0x4013d0f0>\n  (irb):3\n  (irb_local_binding):1:in `eval'\n\n== Here-document\n\nImplementation of Here-document is incomplete. \n\n== Symbol\n\nIrb can not always recognize a symbol as to be Symbol. Concretely, an\nexpression have completed, however Irb regard it as continuation line.\n\n=end\n\n% Begin Emacs Environment\n% Local Variables:\n% mode: text\n% comment-column: 0\n% comment-start: \"%\"\n% comment-end: \"\\n\"\n% End:\n%\n"
  },
  {
    "path": "doc/irb/irb.rd.ja",
    "content": "irb -- interactive ruby\n\t\t\t\t$Release Version: 0.9.5 $\n\t\t\t   \t$Revision$\n\t\t\t   \t$Date$\n\t\t\t   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n=begin\n= irbȤ?\n\nirbinteractive rubyάǤ. rubyμɸϤñ/¹Ԥ\nΥġǤ.\n\n= ư\n\n  % irb\n\nǹԤʤޤ. \n\n= Ȥ\n\nirbλȤ, RubyΤäƤФäƴñǤ. Ūˤ irb \nޥɤ¹ԤǤ. irb¹Ԥ, ʲΤ褦ʥץ\nȤɽƤޤ. , rubyμƲ. 뤷Ǽ¹\nޤ.\n\n  dim% irb\n  irb(main):001:0> 1+2\n  3\n  irb(main):002:0> class Foo\n  irb(main):003:1>  def foo\n  irb(main):004:2>    print 1\n  irb(main):005:2>  end\n  irb(main):006:1> end\n  nil\n  irb(main):007:0> \n\nޤ, irbReadline⥸塼ˤбƤޤ. Readline⥸塼뤬\n󥹥ȡ뤵Ƥˤ, ȤΤɸưˤʤޤ.\n\n= ޥɥץ\n\n  irb.rb [options] file_name opts\n  options:\n  -f\t\t    ~/.irbrc ɤ߹ޤʤ.\n  -m\t\t    bc⡼(ʬ, η׻Ǥ)\n  -d                $DEBUG trueˤ(ruby -d Ʊ)\n  -Kc\t\t    ruby -KcƱ\n  -r load-module    ruby -r Ʊ.\n  --verbose\t    줫¹ԤԤɽ(ǥե)\n  --noverbose\t    줫¹ԤԤɽʤ\n  --echo\t    ¹Է̤ɽ(ǥե)\n  --noecho\t    ¹Է̤ɽʤ\n  --inspect\t    ̽ϤinspectѤ(bc⡼ɰʳϥǥե). \n  --noinspect\t    ̽ϤinspectѤʤ.\n  --readline\t    readline饤֥Ѥ.\n  --noreadline\t    readline饤֥Ѥʤ. ǥեȤư,\n\t\t    inf-ruby-modeʳreadline饤֥Ѥ褦\n\t\t    Ȥ. \n  --prompt prompt-mode\n  --prompt-mode prompt-mode\n\t\t    ץץȥ⡼ɤؤޤ. Ƥ\n\t\t    ץȥ⡼ɤ, default, simple, xmp, inf-ruby\n\t\t    ѰդƤޤ. ǥեȤdefaultץץȥ⡼\n\t\t    ɤˤʤäƤޤ.\n\t\t\t    \n  --inf-ruby-mode   emacsinf-ruby-modeѤΥץץɽԤʤ. \n\t\t    ˻꤬ʤ¤, readline饤֥ϻȤʤʤ.\n  --simple-prompt\n\t\t    ˥ץʥץץȤѤ⡼ɤǤ.\n  --noprompt\t    ץץɽԤʤʤ.\n  --tracer\t    ޥɼ¹Ի˥ȥ졼Ԥʤ.\n  --back-trace-limit n\n\t\t    Хåȥ졼ɽХåȥ졼Ƭ n, \n\t\t    nԤʤ. ǥեȤ16 \n  --irb_debug n\t    irbΥǥХåǥХå٥nꤹ(Ѥ\n\t\t    ̵Ǥ礦).\n  -v, --version\t    irbΥСɽ\n\n= ե졼\n\nirbư``~/.irbrc''ɤ߹ߤޤ. ⤷¸ߤʤ,\n``.irbrc'', ``irb.rc'', ``_irbrc'', ``$irbrc''νloadߤޤ.\n\nץꤹ, ʲΥޥɤǤǥեȤư\nǤޤ.\n\n  IRB.conf[:IRB_NAME]=\"irb\"\n  IRB.conf[:MATH_MODE]=false\n  IRB.conf[:USE_TRACER]=false\n  IRB.conf[:USE_LOADER]=false\n  IRB.conf[:IGNORE_SIGINT]=true\n  IRB.conf[:IGNORE_EOF]=false\n  IRB.conf[:INSPECT_MODE]=nil\n  IRB.conf[:IRB_RC] = nil\n  IRB.conf[:BACK_TRACE_LIMIT]=16\n  IRB.conf[:USE_LOADER] = false\n  IRB.conf[:USE_READLINE] = nil\n  IRB.conf[:USE_TRACER] = false\n  IRB.conf[:IGNORE_SIGINT] = true\n  IRB.conf[:IGNORE_EOF] = false\n  IRB.conf[:PROMPT_MODE] = :DEFALUT\n  IRB.conf[:PROMPT] = {...}\n  IRB.conf[:DEBUG_LEVEL]=0\n  IRB.conf[:VERBOSE]=true\n\n== ץץȤ\n\nץץȤ򥫥ޥˤ, \n\n   IRB.conf[:PROMPT]\n\nѤޤ. 㤨, .irbrcǲΤ褦ʼ򵭽Ҥޤ:\n\n   IRB.conf[:PROMPT][:MY_PROMPT] = { # ץץȥ⡼ɤ̾\n     :PROMPT_I => nil,\t\t  # ̾Υץץ\n     :PROMPT_N => nil,\t\t  # ³ԤΥץץ\n     :PROMPT_S => nil,\t\t  # ʸʤɤη³ԤΥץץ\n     :PROMPT_C => nil,\t\t  # ³ƤΥץץ\n     :RETURN => \"    ==>%s\\n\"\t  # ꥿Υץץ\n   }\n\nץץȥ⡼ɤꤷˤ,\n\n  irb --prompt my-prompt\n\nǤΥץץȥ⡼ɤǵưޤ. ޤ, .irbrc˲򵭽ҤƤ\nOKǤ.\n\n  IRB.conf[:PROMPT_MODE] = :MY_PROMPT\n\nPROMPT_I, PROMPT_N, PROMPT_S, PROMPT_C, եޥåȤꤷޤ.\n\n  %N\tưƤ륳ޥ̾Ϥ.\n  %m\tmain֥(self)to_sǽϤ.\n  %M\tmain֥(self)inspectƽϤ.\n  %l\tʸΥפɽ(\", ', /, ], `]'%wλ)\n  %NNi\tǥȤΥ٥ɽ. NNϿprintf%NNdƱ. \n\tάǽ\n  %NNn\tֹɽޤ.\n  %%    %\n\n㤨, ǥեȤΥץץȥ⡼ɤ:\n\n  IRB.conf[:PROMPT_MODE][:DEFAULT] = {\n      :PROMPT_I => \"%N(%m):%03n:%i> \",\n      :PROMPT_N => \"%N(%m):%03n:%i> \",\n      :PROMPT_S => \"%N(%m):%03n:%i%l \",\n      :PROMPT_C => \"%N(%m):%03n:%i* \",\n      :RETURN => \"%s\\n\"\n  } \n\nȤʤäƤޤ.\n\nRETURN, ߤΤȤprintfǤ. ͤѤ뤫Τޤ.\n\n== irb\n\nޥɥ饤󥪥ץ󤪤IRB.conf()irbưΥǥեȤ\nΤ, `5. ޥ'ˤconfǸ̤()irb꤬\n褦ˤʤäƤޤ.\n\nIRB.conf[:IRB_RC]procꤵƤ, irbưˤ\nprocirbΥƥȤȤƸƤӽФޤ. ˤäƸ̤Υ\nirbȤѤ뤳ȤǤ褦ˤʤޤ.\n\n\n= ޥ\n\nirbĥޥɤ, ñ̾Ƭ`irb_'Ĥ̾ξ\nޤ. , ñ̾override줿ΤǤ.\n\n--- exit, quit, irb_exit\t\n    λ. \n    irbξ, Υirbλ.\n\n--- conf, irb_context\n    irbθߤɽ. ѹ, conf˥å뤳\n    ȤˤäƹԤʤ. \n\n--- conf.eval_history = N\n    ¹Է̤Υҥȥ굡ǽ.\n    nnnil nn>0 ǤФοҥȥˤ롣nn==0λ\n    ̵¤˵롢nilȥҥȥ굡ǽϤ(ǥե). \n\n--- Conf.back_trace_limit\n    Хåȥ졼ɽХåȥ졼Ƭn, nԤʤ.\n    ǥեȤ16\n    \n--- conf.debug_level = N\n    irbѤΥǥХå٥\n\n--- conf.ignore_eof = true/false\n    ^DϤ줿ưꤹ. trueλ^D̵뤹, false\n    irbλ. \n\n--- conf.ignore_sigint= true/false\n    ^CϤ줿ưꤹ. false, irbλ. true\n    ưϰʲΤ褦ˤʤ:\n      : ޤϤΤ򥭥󥻥뤷ȥåץ٥. \n      ¹: ¹Ԥߤ.\n\n--- conf.inf_ruby_mode = true/false\n    inf-ruby-modeѤΥץץɽԤʤ. ǥեȤfalse.\n\n--- conf.inspect_mode = true/false/nil\n    󥹥ڥȥ⡼ɤꤹ.\n    true: 󥹥ڥȤɽ.\n    false: ̾printɽ.\n    nil: ̾⡼ɤǤ, inspect modeȤʤ, math⡼ɤλ, non\n\t inspect modeȤʤ.   \n\n--- conf.math_mode\n    ȤΤ. bc⡼(ʬ, η׻Ǥޤ)ɤ?\n\n--- conf.use_loader = true/false\n    load/requireirbfileɤ߹ߵǽѤ⡼ɤΥå(ǥե\n    ȤѤʤ). Υ⡼ɤIRBΤȿǤ.\n\n--- conf.prompt_c\n    ifľʤ, Ԥ³ƤΥץץ.\n\n--- conf.prompt_i\n    ̾Υץץ.\n\n--- conf.prompt_s\n    ʸʤɤɽץץ.\n\n--- conf.rc\n    ~/.irbrcɤ߹ɤ?\n\n--- conf.use_prompt = true/false\n    ץץɽ뤫ɤ? ǥեȤǤϥץץȤɽ.\n\n--- conf.use_readline = true/false/nil\n    readlineȤɤ?\n    true: readlineȤ.\n    false: readlineȤʤ.\n    nil: (ǥե)inf-ruby-modeʳreadline饤֥Ѥ\n         Ȥ.  \n#\n#--- conf.verbose=T/F\n#    irb餤ʥåϤ뤫?\n\n--- cws, chws, irb_cws, irb_chws, irb_change_workspace [obj]\n    objselfȤ. objά줿Ȥ, home workspace, ʤ\n    irbưȤmain objectselfȤ.\n\n--- pushws, irb_pushws, irb_push_workspace [obj]\n    UNIX륳ޥɤpushdƱ.\n\n--- popws, irb_popws, irb_pop_workspace\n    UNIX륳ޥɤpopdƱ.\n\n--- irb [obj]\n    irbΩ. objꤵ줿, objselfȤ.\n\n--- jobs, irb_jobs\n    irbΥꥹ\n\n--- fg n, irb_fg n\n    ꤷirb˥å. n, ΤΤꤹ.\n\n      irbֹ\n      å\n      irb֥\n      self(irb objǵưobj)\n\n--- kill n, irb_kill n\n      irbkill. nfgƱ.\n\n--- souce, irb_source  path\n    UNIX륳ޥɤsourceȻƤ. ߤδĶpathΥ\n    ץȤɾ.\n\n--- irb_load path, prev\n\n    Rubyloadirb.\n\n= ƥѿ\n\n--- _  \n    η׻μ¹Է̤ФƤ(ѿ).\n--- __ \n    ¹Է̤ФƤ.\n    __[line_no]ǡιԤǼ¹Ԥ̤뤳ȤǤ. line_no\n    ˤϡǿη̤-line_noη̤뤳ȤǤ.\n\n=  \n\nʲΤ褦ʴǤ.\n\n  dim% ruby irb.rb\n  irb(main):001:0> irb                        # irbΩ\n  irb#1(main):001:0> jobs                     # irbΥꥹ\n  #0->irb on main (#<Thread:0x400fb7e4> : stop)\n  #1->irb#1 on main (#<Thread:0x40125d64> : running)\n  nil\n  irb#1(main):002:0> fg 0                     # jobΥå\n  nil\n  irb(main):002:0> class Foo;end\n  nil\n  irb(main):003:0> irb Foo                    # Foo򥳥ƥȤirb\n\t\t\t\t\t      # Ω\n  irb#2(Foo):001:0> def foo                   # Foo#foo\n  irb#2(Foo):002:1>   print 1\n  irb#2(Foo):003:1> end\n  nil\n  irb#2(Foo):004:0> fg 0                      # job򥹥å\n  nil\n  irb(main):004:0> jobs                       # jobΥꥹ\n  #0->irb on main (#<Thread:0x400fb7e4> : running)\n  #1->irb#1 on main (#<Thread:0x40125d64> : stop)\n  #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)\n  nil\n  irb(main):005:0> Foo.instance_methods       # Foo#foo\n\t\t\t\t\t      # Ƥ\n  [\"foo\"]\n  irb(main):006:0> fg 2                       # job򥹥å\n  nil\n  irb#2(Foo):005:0> def bar                   # Foo#bar\n  irb#2(Foo):006:1>  print \"bar\"\n  irb#2(Foo):007:1> end\n  nil\n  irb#2(Foo):010:0>  Foo.instance_methods\n  [\"bar\", \"foo\"]\n  irb#2(Foo):011:0> fg 0                      \n  nil\n  irb(main):007:0> f = Foo.new\n  #<Foo:0x4010af3c>\n  irb(main):008:0> irb f                      # FooΥ󥹥󥹤irb\n\t\t\t\t\t      # Ω.\n  irb#3(#<Foo:0x4010af3c>):001:0> jobs\n  #0->irb on main (#<Thread:0x400fb7e4> : stop)\n  #1->irb#1 on main (#<Thread:0x40125d64> : stop)\n  #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)\n  #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)\n  nil\n  irb#3(#<Foo:0x4010af3c>):002:0> foo         # f.fooμ¹\n  nil\n  irb#3(#<Foo:0x4010af3c>):003:0> bar         # f.barμ¹\n  barnil\n  irb#3(#<Foo:0x4010af3c>):004:0> kill 1, 2, 3# jobkill\n  nil\n  irb(main):009:0> jobs\n  #0->irb on main (#<Thread:0x400fb7e4> : running)\n  nil\n  irb(main):010:0> exit                       # λ\n  dim% \n\n= Ѿ\n\nirb, ɾǤ(Ĥ)Ǥ༡¹ԤԤʤޤ. \n, rubyľܻȤä, 㴳ۤʤưԤʤ礬ޤ.\n\n餫ˤʤäƤޤ.\n\n== ѿ\n\nrubyǤ, ʲΥץϥ顼ˤʤޤ.\n\n  eval \"foo = 0\"\n  foo\n  --\n  -:2: undefined local variable or method `foo' for #<Object:0x40283118> (NameError)\n  ---\n  NameError\n\nȤ, irbѤ\n\n  >> eval \"foo = 0\"\n  => 0\n  >> foo\n  => 0\n\nȤʤ, 顼򵯤ޤ. , rubyǽ˥ץΤ򥳥\nѥ뤷ƥѿꤹ뤫Ǥ. Ф, irbϼ¹Բǽ\nʤ(Ĥ)ȼưŪɾƤ뤫Ǥ. 嵭Ǥ, \n\n  evel \"foo = 0\" \n\nԤʤäɾԤʤ, λѿ뤿,  \nѿfooƤ뤫Ǥ.\n\nΤ褦rubyirbưΰ㤤褷, begin...endǳä\nХåŪ˼¹ԤƲ:\n\n  >> begin\n  ?>   eval \"foo = 0\"\n  >>   foo\n  >> end\n  NameError: undefined local variable or method `foo' for #<Object:0x4013d0f0>\n  (irb):3\n  (irb_local_binding):1:in `eval'\n\n== ҥɥ\n\nߤΤȤҥɥȤμԴǤ. \n\n== ܥ\n\nܥǤ뤫ɤȽǤְ㤨뤳Ȥޤ. Ūˤϼλ\nƤΤ˷³ԤȸʤȤޤ.\n\n=end\n\n% Begin Emacs Environment\n% Local Variables:\n% mode: text\n% comment-column: 0\n% comment-start: \"%\"\n% comment-end: \"\\n\"\n% End:\n%\n\n"
  },
  {
    "path": "doc/shell.rd",
    "content": " -- shell.rb\n\t\t\t\t$Release Version: 0.6.0 $\n\t\t\t   \t$Revision$\n\t\t\t   \t$Date$\n\t\t\t   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n\n=begin\n\n= What's shell.rb?\n\nIt realizes a wish to do execution of commands with filters and pipes\nlike sh/csh by using just native facilities of ruby.\n\n= Main classes\n\n== Shell\n\nEvery shell object has its own current working directory, and executes\neach command as if it stands in the directory.\n\n--- Shell#cwd\n--- Shell#dir\n--- Shell#getwd\n--- Shell#pwd\n\n      Returns the current directory\n\n--- Shell#system_path\n\n      Returns the command search path in an array\n\n--- Shell#umask\n\n      Returns the umask\n\n== Filter\n\nAny result of command exection is a Filter.  Filter include\nEnumerable, therefore a Filter object can use all Enumerable\nfacilities.\n\n= Main methods\n\n== Command definitions\n\nIn order to execute a command on your OS, you need to define it as a\nShell method.\n\nAlternatively, you can execute any command via Shell#system even if it\nis not defined.\n\n--- Shell.def_system_command(command, path = command)\n\n      Defines a command.  Registers <path> as a Shell method\n      <command>.\n\n      ex)\n      Shell.def_system_command \"ls\"\n        Defines ls.\n\n      Shell.def_system_command \"sys_sort\", \"sort\"\n        Defines sys_sort as sort.\n\n--- Shell.undef_system_command(command)\n\n      Undefines a commmand\n\n--- Shell.alias_command(ali, command, *opts) {...}\n\n      Aliases a command.\n\n      ex)\n        Shell.alias_command \"lsC\", \"ls\", \"-CBF\", \"--show-control-chars\"\n        Shell.alias_command(\"lsC\", \"ls\"){|*opts| [\"-CBF\", \"--show-control-chars\", *opts]}\n\n--- Shell.unalias_command(ali)\n\n      Unaliases a command.\n\n--- Shell.install_system_commands(pre = \"sys_\")\n\n      Defines all commands in the default_system_path as Shell method,\n      all with <pre> prefixed to their names.\n\n== Creation\n\n--- Shell.new\n\n      Creates a Shell object which current directory is set to the\n      process current directory.\n\n--- Shell.cd(path)\n\n      Creates a Shell object which current directory is set to\n      <path>.\n\n== Process management\n\n--- Shell#jobs\n\n      Returns a list of scheduled jobs.\n\n--- Shell#kill sig, job\n\n      Sends a signal <sig> to <job>.\n\n== Current directory operations\n\n--- Shell#cd(path, &block)\n--- Shell#chdir\n\n      Changes the current directory to <path>.  If a block is given,\n      it restores the current directory when the block ends.\n\n--- Shell#pushd(path = nil, &block)\n--- Shell#pushdir\n\n      Pushes the current directory to the directory stack, changing\n      the current directory to <path>.  If <path> is omitted, it\n      exchanges its current directory and the top of its directory\n      stack.  If a block is given, it restores the current directory\n      when the block ends.\n\n--- Shell#popd\n--- Shell#popdir\n\n      Pops a directory from the directory stack, and sets the current\n      directory to it.\n\n== File and directory operations\n\n--- Shell#foreach(path = nil, &block)\n\n      Same as:\n        File#foreach (when path is a file)\n        Dir#foreach (when path is a directory)\n\n--- Shell#open(path, mode)\n\n      Same as:\n        File#open (when path is a file)\n        Dir#open (when path is a directory)\n\n--- Shell#unlink(path)\n\n      Same as:\n        Dir#open (when path is a file)\n        Dir#unlink (when path is a directory)\n\n--- Shell#test(command, file1, file2)\n--- Shell#[command, file1, file2]\n\n      Same as test().\n      ex)\n          sh[?e, \"foo\"]\n          sh[:e, \"foo\"]\n          sh[\"e\", \"foo\"]\n          sh[:exists?, \"foo\"]\n          sh[\"exists?\", \"foo\"]\n\n--- Shell#mkdir(*path)\n\n      Same as Dir.mkdir (with multiple directories allowed)\n\n--- Shell#rmdir(*path)\n\n      Same as Dir.rmdir (with multiple directories allowed)\n\n== Command execution\n\n--- System#system(command, *opts)\n\n      Executes <command> with <opts>.\n\n      ex)\n        print sh.system(\"ls\", \"-l\")\n        sh.system(\"ls\", \"-l\") | sh.head > STDOUT\n\n--- System#rehash\n\n      Does rehash.\n\n--- Shell#transact &block\n\n      Executes a block as self.\n      ex)\n        sh.transact{system(\"ls\", \"-l\") | head > STDOUT}\n\n--- Shell#out(dev = STDOUT, &block)\n\n      Does transact, with redirecting the result output to <dev>.\n\n== Internal commands\n\n--- Shell#echo(*strings)\n--- Shell#cat(*files)\n--- Shell#glob(patten)\n--- Shell#tee(file)\n\n      Return Filter objects, which are results of their execution.\n\n--- Filter#each &block\n\n      Iterates a block for each line of it.\n\n--- Filter#<(src)\n\n      Inputs from <src>, which is either a string of a file name or an\n      IO.\n\n--- Filter#>(to)\n\n      Outputs to <to>, which is either a string of a file name or an\n      IO.\n\n--- Filter#>>(to)\n\n      Appends the ouput to <to>, which is either a string of a file\n      name or an IO.\n\n--- Filter#|(filter)\n\n      Processes a pipeline.\n\n--- Filter#+(filter)\n\n      (filter1 + filter2) outputs filter1, and then outputs filter2.\n\n--- Filter#to_a\n--- Filter#to_s\n\n== Built-in commands\n\n--- Shell#atime(file)\n--- Shell#basename(file, *opt)\n--- Shell#chmod(mode, *files)\n--- Shell#chown(owner, group, *file)\n--- Shell#ctime(file)\n--- Shell#delete(*file)\n--- Shell#dirname(file)\n--- Shell#ftype(file)\n--- Shell#join(*file)\n--- Shell#link(file_from, file_to)\n--- Shell#lstat(file)\n--- Shell#mtime(file)\n--- Shell#readlink(file)\n--- Shell#rename(file_from, file_to)\n--- Shell#split(file)\n--- Shell#stat(file)\n--- Shell#symlink(file_from, file_to)\n--- Shell#truncate(file, length)\n--- Shell#utime(atime, mtime, *file)\n\n      Equivalent to the class methods of File with the same names.\n\n--- Shell#blockdev?(file)\n--- Shell#chardev?(file)\n--- Shell#directory?(file)\n--- Shell#executable?(file)\n--- Shell#executable_real?(file)\n--- Shell#exist?(file)/Shell#exists?(file)\n--- Shell#file?(file)\n--- Shell#grpowned?(file)\n--- Shell#owned?(file)\n--- Shell#pipe?(file)\n--- Shell#readable?(file)\n--- Shell#readable_real?(file)\n--- Shell#setgid?(file)\n--- Shell#setuid?(file)\n--- Shell#size(file)/Shell#size?(file)\n--- Shell#socket?(file)\n--- Shell#sticky?(file)\n--- Shell#symlink?(file)\n--- Shell#writable?(file)\n--- Shell#writable_real?(file)\n--- Shell#zero?(file)\n\n      Equivalent to the class methods of FileTest with the same names.\n\n--- Shell#syscopy(filename_from, filename_to)\n--- Shell#copy(filename_from, filename_to)\n--- Shell#move(filename_from, filename_to)\n--- Shell#compare(filename_from, filename_to)\n--- Shell#safe_unlink(*filenames)\n--- Shell#makedirs(*filenames)\n--- Shell#install(filename_from, filename_to, mode)\n\n      Equivalent to the class methods of FileTools with the same\n      names.\n\n      And also, there are some aliases for convenience:\n\n--- Shell#cmp\t<- Shell#compare\n--- Shell#mv\t<- Shell#move\n--- Shell#cp\t<- Shell#copy\n--- Shell#rm_f\t<- Shell#safe_unlink\n--- Shell#mkpath\t<- Shell#makedirs\n\n= Samples\n\n== ex1\n\n  sh = Shell.cd(\"/tmp\")\n  sh.mkdir \"shell-test-1\" unless sh.exists?(\"shell-test-1\")\n  sh.cd(\"shell-test-1\")\n  for dir in [\"dir1\", \"dir3\", \"dir5\"]\n    if !sh.exists?(dir)\n      sh.mkdir dir\n      sh.cd(dir) do\n\tf = sh.open(\"tmpFile\", \"w\")\n\tf.print \"TEST\\n\"\n\tf.close\n      end\n      print sh.pwd\n    end\n  end\n\n== ex2\n\n  sh = Shell.cd(\"/tmp\")\n  sh.transact do\n    mkdir \"shell-test-1\" unless exists?(\"shell-test-1\")\n    cd(\"shell-test-1\")\n    for dir in [\"dir1\", \"dir3\", \"dir5\"]\n      if !exists?(dir)\n\tmkdir dir\n\tcd(dir) do\n\t  f = open(\"tmpFile\", \"w\")\n\t  f.print \"TEST\\n\"\n\t  f.close\n\tend\n\tprint pwd\n      end\n    end\n  end\n\n== ex3\n\n  sh.cat(\"/etc/printcap\") | sh.tee(\"tee1\") > \"tee2\"\n  (sh.cat < \"/etc/printcap\") | sh.tee(\"tee11\") > \"tee12\"\n  sh.cat(\"/etc/printcap\") | sh.tee(\"tee1\") >> \"tee2\"\n  (sh.cat < \"/etc/printcap\") | sh.tee(\"tee11\") >> \"tee12\"\n\n== ex4\n\n  print sh.cat(\"/etc/passwd\").head.collect{|l| l =~ /keiju/}\n\n=end\n"
  },
  {
    "path": "doc/shell.rd.ja",
    "content": " -- shell.rb\n\t\t\t\t$Release Version: 0.6.0 $\n\t\t\t   \t$Revision$\n\t\t\t   \t$Date$\n\t\t\t   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n\n=begin\n\n= Ū\n\nrubysh/cshΤ褦˥ޥɤμ¹Եڤӥե륿󥰤ڤ˹Ԥ.\nsh/cshʸrubyεǽѤƼ¸.\n\n= ʥ饹\n\n== Shell\n\nShell֥Ȥϥȥǥ쥯ȥ, ޥɼ¹ԤϤ\nХѥˤʤޤ.\n\n--- Shell#cwd\n--- Shell#dir\n--- Shell#getwd\n--- Shell#pwd\n\n      ȥǥ쥯ȥ֤\n\n--- Shell#system_path\n\n      ޥɥѥ֤\n\n--- Shell#umask\n\n      umask֤\n\n== Filter\n\nޥɤμ¹Է̤Ϥ٤FilterȤƤޤ. Enumerableinclude\nƤޤ.\n\n= ʥ᥽åɰ\n\n== ޥ\n\nOSΥޥɤ¹ԤˤϤޤ, ShellΥ᥽åɤȤޤ.\n\n) ޥɤʤȤľܼ¹ԤǤShell#systemޥɤ⤢ޤ.\n\n--- Shell.def_system_command(command, path = command)\n\n      ShellΥ᥽åɤȤcommandϿޤ. \n\n      )\n      Shell.def_system_command \"ls\"\n        ls \n\n      Shell.def_system_command \"sys_sort\", \"sort\"\n        sortޥɤsys_sortȤ\n\n--- Shell.undef_system_command(command)\n\n      commandޤ.\n\n--- Shell.alias_command(ali, command, *opts) {...}\n\n      commandalias򤷤ޤ. \n\n      )\n        Shell.alias_command \"lsC\", \"ls\", \"-CBF\", \"--show-control-chars\"\n        Shell.alias_command(\"lsC\", \"ls\"){|*opts| [\"-CBF\", \"--show-control-chars\", *opts]}\n\n--- Shell.unalias_command(ali)\n\n      commandaliasޤ.\n\n--- Shell.install_system_commands(pre = \"sys_\")\n\n      system_pathˤƤμ¹ԲǽեShell. ᥽\n      ̾ϸΥե̾ƬpreĤΤȤʤ.\n\n== \n\n--- Shell.new\n\n      ץΥȥǥ쥯ȥ򥫥ȥǥ쥯ȥȤShell\n      ֥Ȥޤ.\n\n--- Shell.cd(path)\n\n      path򥫥ȥǥ쥯ȥȤShell֥Ȥޤ.\n\n== ץ\n\n--- Shell#jobs\n\n      塼󥰤Ƥjobΰ֤.\n\n--- Shell#kill sig, job\n\n      job˥ʥsig\n\n== ȥǥ쥯ȥ\n\n--- Shell#cd(path, &block)\n--- Shell#chdir\n\n      ȥǥ쥯ȥpathˤ. ƥ졼ȤƸƤФ줿Ȥˤ\n      ֥å¹Τߥȥǥ쥯ȥѹ.\n\n--- Shell#pushd(path = nil, &block)\n--- Shell#pushdir\n\n      ȥǥ쥯ȥǥ쥯ȥꥹåˤĤ, ȥǥ쥯\n      ȥpathˤ. pathά줿Ȥˤ, ȥǥ쥯ȥ\n      ǥ쥯ȥꥹåΥȥåפ򴹤. ƥ졼ȤƸƤФ줿\n      ˤ, ֥å¹Τpushd.\n\n--- Shell#popd\n--- Shell#popdir\n\n      ǥ쥯ȥꥹåݥåפ, 򥫥ȥǥ쥯ȥˤ.\n\n== ե/ǥ쥯ȥ\n\n--- Shell#foreach(path = nil, &block)\n\n      pathեʤ, File#foreach\n      pathǥ쥯ȥʤ, Dir#foreach\n\n--- Shell#open(path, mode)\n\n      pathեʤ, File#open\n      pathǥ쥯ȥʤ, Dir#open\n\n--- Shell#unlink(path)\n\n      pathեʤ, File#unlink\n      pathǥ쥯ȥʤ, Dir#unlink\n\n--- Shell#test(command, file1, file2)\n--- Shell#[command, file1, file2]\n\n      եƥȴؿtestƱ. \n      )\n          sh[?e, \"foo\"]\n          sh[:e, \"foo\"]\n          sh[\"e\", \"foo\"]\n          sh[:exists?, \"foo\"]\n          sh[\"exists?\", \"foo\"]\n\n--- Shell#mkdir(*path)\n\n      Dir.mkdirƱ(ʣ)\n\n--- Shell#rmdir(*path)\n\n      Dir.rmdirƱ(ʣ)\n\n== ޥɼ¹\n\n--- System#system(command, *opts)\n\n      command¹Ԥ.\n      )\n        print sh.system(\"ls\", \"-l\")\n        sh.system(\"ls\", \"-l\") | sh.head > STDOUT\n\n--- System#rehash\n\n      ϥå夹\n\n--- Shell#transact &block\n\n      ֥åǤshellselfȤƼ¹Ԥ.\n      )\n        sh.transact{system(\"ls\", \"-l\") | head > STDOUT}\n\n--- Shell#out(dev = STDOUT, &block)\n\n      transactƤӽФη̤dev˽Ϥ.\n\n== ޥ\n\n--- Shell#echo(*strings)\n--- Shell#cat(*files)\n--- Shell#glob(patten)\n--- Shell#tee(file)\n\n      ϼ¹Ԥ, ƤȤFilter֥Ȥ֤ޤ. \n\n--- Filter#each &block\n\n      ե륿ΰԤĤblockϤ.\n\n--- Filter#<(src)\n\n      srcե륿ϤȤ. src, ʸʤХե, IOǤ\n      Ф򤽤ΤޤϤȤ.\n\n--- Filter#>(to)\n\n      srcե륿νϤȤ. to, ʸʤХե, IOǤ\n      Ф򤽤Τޤ޽ϤȤ.\n\n--- Filter#>>(to)\n\n      srcե륿ɲä. to, ʸʤХե, IOǤ\n      򤽤Τޤ޽ϤȤ.\n\n--- Filter#|(filter)\n\n      ѥ׷\n\n--- Filter#+(filter)\n\n      filter1 + filter2  filter1νϤθ, filter2νϤԤ.\n\n--- Filter#to_a\n--- Filter#to_s\n\n== ȹߥޥ\n\n--- Shell#atime(file)\n--- Shell#basename(file, *opt)\n--- Shell#chmod(mode, *files)\n--- Shell#chown(owner, group, *file)\n--- Shell#ctime(file)\n--- Shell#delete(*file)\n--- Shell#dirname(file)\n--- Shell#ftype(file)\n--- Shell#join(*file)\n--- Shell#link(file_from, file_to)\n--- Shell#lstat(file)\n--- Shell#mtime(file)\n--- Shell#readlink(file)\n--- Shell#rename(file_from, file_to)\n--- Shell#split(file)\n--- Shell#stat(file)\n--- Shell#symlink(file_from, file_to)\n--- Shell#truncate(file, length)\n--- Shell#utime(atime, mtime, *file)\n\n      File饹ˤƱ̾Υ饹᥽åɤƱǤ.\n\n--- Shell#blockdev?(file)\n--- Shell#chardev?(file)\n--- Shell#directory?(file)\n--- Shell#executable?(file)\n--- Shell#executable_real?(file)\n--- Shell#exist?(file)/Shell#exists?(file)\n--- Shell#file?(file)\n--- Shell#grpowned?(file)\n--- Shell#owned?(file)\n--- Shell#pipe?(file)\n--- Shell#readable?(file)\n--- Shell#readable_real?(file)\n--- Shell#setgid?(file)\n--- Shell#setuid?(file)\n--- Shell#size(file)/Shell#size?(file)\n--- Shell#socket?(file)\n--- Shell#sticky?(file)\n--- Shell#symlink?(file)\n--- Shell#writable?(file)\n--- Shell#writable_real?(file)\n--- Shell#zero?(file)\n\n      FileTest饹ˤƱ̾Υ饹᥽åɤƱǤ.\n\n--- Shell#syscopy(filename_from, filename_to)\n--- Shell#copy(filename_from, filename_to)\n--- Shell#move(filename_from, filename_to)\n--- Shell#compare(filename_from, filename_to)\n--- Shell#safe_unlink(*filenames)\n--- Shell#makedirs(*filenames)\n--- Shell#install(filename_from, filename_to, mode)\n\n      FileTools饹ˤƱ̾Υ饹᥽åɤƱǤ.\n\n      ¾, ʲΤΤꥢƤޤ.\n\n--- Shell#cmp\t<- Shell#compare\n--- Shell#mv\t<- Shell#move\n--- Shell#cp\t<- Shell#copy\n--- Shell#rm_f\t<- Shell#safe_unlink\n--- Shell#mkpath\t<- Shell#makedirs\n\n= ץ\n\n== ex1\n\n  sh = Shell.cd(\"/tmp\")\n  sh.mkdir \"shell-test-1\" unless sh.exists?(\"shell-test-1\")\n  sh.cd(\"shell-test-1\")\n  for dir in [\"dir1\", \"dir3\", \"dir5\"]\n    if !sh.exists?(dir)\n      sh.mkdir dir\n      sh.cd(dir) do\n\tf = sh.open(\"tmpFile\", \"w\")\n\tf.print \"TEST\\n\"\n\tf.close\n      end\n      print sh.pwd\n    end\n  end\n\n== ex2\n\n  sh = Shell.cd(\"/tmp\")\n  sh.transact do\n    mkdir \"shell-test-1\" unless exists?(\"shell-test-1\")\n    cd(\"shell-test-1\")\n    for dir in [\"dir1\", \"dir3\", \"dir5\"]\n      if !exists?(dir)\n\tmkdir dir\n\tcd(dir) do\n\t  f = open(\"tmpFile\", \"w\")\n\t  f.print \"TEST\\n\"\n\t  f.close\n\tend\n\tprint pwd\n      end\n    end\n  end\n\n== ex3\n\n  sh.cat(\"/etc/printcap\") | sh.tee(\"tee1\") > \"tee2\"\n  (sh.cat < \"/etc/printcap\") | sh.tee(\"tee11\") > \"tee12\"\n  sh.cat(\"/etc/printcap\") | sh.tee(\"tee1\") >> \"tee2\"\n  (sh.cat < \"/etc/printcap\") | sh.tee(\"tee11\") >> \"tee12\"\n\n== ex4\n\n  print sh.cat(\"/etc/passwd\").head.collect{|l| l =~ /keiju/}\n\n=end\n"
  },
  {
    "path": "enum.c",
    "content": "/**********************************************************************\n\n  enum.c -\n\n  $Author$\n  $Date$\n  created at: Fri Oct  1 15:15:19 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"node.h\"\n#include \"util.h\"\n\nVALUE rb_mEnumerable;\nstatic ID id_each, id_eqq, id_cmp, id_size;\n\nstruct iter_method_arg {\n    VALUE obj;\n    ID mid;\n    int argc;\n    VALUE *argv;\n};\n\nstatic VALUE iterate_method _((VALUE obj));\nstatic VALUE\niterate_method(obj)\n    VALUE obj;\n{\n    struct iter_method_arg *arg;\n\n    arg = (struct iter_method_arg *)obj;\n    return rb_funcall2(arg->obj, arg->mid, arg->argc, arg->argv);\n}\n\nVALUE\nrb_block_call(obj, mid, argc, argv, bl_proc, data2)\n    VALUE obj;\n    ID mid;\n    int argc;\n    VALUE *argv;\n    VALUE (*bl_proc) (ANYARGS);\n    VALUE data2;\n{\n    struct iter_method_arg arg;\n\n    arg.obj = obj;\n    arg.mid = mid;\n    arg.argc = argc;\n    arg.argv = argv;\n    return rb_iterate(iterate_method, (VALUE)&arg, bl_proc, data2);\n}\n\nVALUE\nrb_each(obj)\n    VALUE obj;\n{\n    return rb_funcall(obj, id_each, 0, 0);\n}\n\nstatic VALUE\ngrep_i(i, arg)\n    VALUE i, *arg;\n{\n    if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {\n\trb_ary_push(arg[1], i);\n    }\n    return Qnil;\n}\n\nstatic VALUE\ngrep_iter_i(i, arg)\n    VALUE i, *arg;\n{\n    if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {\n\trb_ary_push(arg[1], rb_yield(i));\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.grep(pattern)                   => array\n *     enum.grep(pattern) {| obj | block }  => array\n *\n *  Returns an array of every element in <i>enum</i> for which\n *  <code>Pattern === element</code>. If the optional <em>block</em> is\n *  supplied, each matching element is passed to it, and the block's\n *  result is stored in the output array.\n *\n *     (1..100).grep 38..44   #=> [38, 39, 40, 41, 42, 43, 44]\n *     c = IO.constants\n *     c.grep(/SEEK/)         #=> [\"SEEK_END\", \"SEEK_SET\", \"SEEK_CUR\"]\n *     res = c.grep(/SEEK/) {|v| IO.const_get(v) }\n *     res                    #=> [2, 0, 1]\n *\n */\n\nstatic VALUE\nenum_grep(obj, pat)\n    VALUE obj, pat;\n{\n    VALUE ary = rb_ary_new();\n    VALUE arg[2];\n\n    arg[0] = pat;\n    arg[1] = ary;\n\n    rb_iterate(rb_each, obj, rb_block_given_p() ? grep_iter_i : grep_i, (VALUE)arg);\n\n    return ary;\n}\n\nstatic VALUE count_i _((VALUE, VALUE));\nstatic VALUE\ncount_i(i, memop)\n    VALUE i, memop;\n{\n    VALUE *memo = (VALUE*)memop;\n\n    if (rb_equal(i, memo[1])) {\n\tmemo[0]++;\n    }\n    return Qnil;\n}\n\nstatic VALUE count_iter_i _((VALUE, VALUE));\nstatic VALUE\ncount_iter_i(i, memop)\n    VALUE i, memop;\n{\n    VALUE *memo = (VALUE*)memop;\n\n    if (RTEST(rb_yield(i))) {\n\tmemo[0]++;\n    }\n    return Qnil;\n}\n\nstatic VALUE count_all_i _((VALUE, VALUE));\nstatic VALUE\ncount_all_i(i, memop)\n    VALUE i, memop;\n{\n    VALUE *memo = (VALUE*)memop;\n\n    memo[0]++;\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.count                   => int\n *     enum.count(item)             => int\n *     enum.count {| obj | block }  => int\n *\n *  Returns the number of items in <i>enum</i>, where #size is called\n *  if it responds to it, otherwise the items are counted through\n *  enumeration.  If an argument is given, counts the number of items\n *  in <i>enum</i>, for which equals to <i>item</i>.  If a block is\n *  given, counts the number of elements yielding a true value.\n *\n *     ary = [1, 2, 4, 2]\n *     ary.count             # => 4\n *     ary.count(2)          # => 2\n *     ary.count{|x|x%2==0}  # => 3\n *\n */\n\nstatic VALUE\nenum_count(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE memo[2];\t/* [count, condition value] */\n    rb_block_call_func *func;\n\n    if (argc == 0) {\n\tif (rb_block_given_p()) {\n\t    func = count_iter_i;\n\t}\n\telse {\n\t    if (rb_respond_to(obj, id_size)) {\n\t\treturn rb_funcall(obj, id_size, 0, 0);\n\t    }\n\t    func = count_all_i;\n\t}\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &memo[1]);\n\tif (rb_block_given_p()) {\n\t    rb_warn(\"given block not used\");\n\t}\n        func = count_i;\n    }\n\n    memo[0] = 0;\n    rb_block_call(obj, id_each, 0, 0, func, (VALUE)&memo);\n    return INT2NUM(memo[0]);\n}\n\nstatic VALUE\nfind_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    if (RTEST(rb_yield(i))) {\n\t*memo = i;\n\trb_iter_break();\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.detect(ifnone = nil) {| obj | block }  => obj or nil\n *     enum.find(ifnone = nil)   {| obj | block }  => obj or nil\n *\n *  Passes each entry in <i>enum</i> to <em>block</em>. Returns the\n *  first for which <em>block</em> is not <code>false</code>.  If no\n *  object matches, calls <i>ifnone</i> and returns its result when it\n *  is specified, or returns <code>nil</code>\n *\n *     (1..10).detect  {|i| i % 5 == 0 and i % 7 == 0 }   #=> nil\n *     (1..100).detect {|i| i % 5 == 0 and i % 7 == 0 }   #=> 35\n *\n */\n\nstatic VALUE\nenum_find(argc, argv, obj)\n    int argc;\n    VALUE* argv;\n    VALUE obj;\n{\n    VALUE memo = Qundef;\n    VALUE if_none;\n\n    rb_scan_args(argc, argv, \"01\", &if_none);\n    RETURN_ENUMERATOR(obj, argc, argv);\n    rb_iterate(rb_each, obj, find_i, (VALUE)&memo);\n    if (memo != Qundef) {\n\treturn memo;\n    }\n    if (!NIL_P(if_none)) {\n\treturn rb_funcall(if_none, rb_intern(\"call\"), 0, 0);\n    }\n    return Qnil;\n}\n\nstatic VALUE find_index_i _((VALUE, VALUE));\nstatic VALUE\nfind_index_i(i, memop)\n    VALUE i;\n    VALUE memop;\n{\n    VALUE *memo = (VALUE*)memop;\n\n    if (rb_equal(i, memo[2])) {\n\tmemo[0] = UINT2NUM(memo[1]);\n\trb_iter_break();\n    }\n    memo[1]++;\n    return Qnil;\n}\n\nstatic VALUE find_index_iter_i _((VALUE, VALUE));\nstatic VALUE\nfind_index_iter_i(i, memop)\n    VALUE i;\n    VALUE memop;\n{\n    VALUE *memo = (VALUE*)memop;\n\n    if (RTEST(rb_yield(i))) {\n\tmemo[0] = UINT2NUM(memo[1]);\n\trb_iter_break();\n    }\n    memo[1]++;\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.find_index(value)            => int or nil\n *     enum.find_index {| obj | block }  => int or nil\n *\n *  Compares each entry in <i>enum</i> with <em>value</em> or passes\n *  to <em>block</em>.  Returns the index for the first for which the\n *  evaluated value is non-false.  If no object matches, returns\n *  <code>nil</code>\n *\n *     (1..10).find_index  {|i| i % 5 == 0 and i % 7 == 0 }   #=> nil\n *     (1..100).find_index {|i| i % 5 == 0 and i % 7 == 0 }   #=> 34\n *     (1..100).find_index(50)                                #=> 49\n *\n */\n\nstatic VALUE\nenum_find_index(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE memo[3];\t/* [return value, current index, condition value] */\n    rb_block_call_func *func;\n\n    if (argc == 0) {\n        RETURN_ENUMERATOR(obj, 0, 0);\n        func = find_index_iter_i;\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &memo[2]);\n\tif (rb_block_given_p()) {\n\t    rb_warn(\"given block not used\");\n\t}\n        func = find_index_i;\n    }\n\n    memo[0] = Qnil;\n    memo[1] = 0;\n    rb_block_call(obj, id_each, 0, 0, func, (VALUE)memo);\n    return memo[0];\n}\n\nstatic VALUE\nfind_all_i(i, ary)\n    VALUE i, ary;\n{\n    if (RTEST(rb_yield(i))) {\n\trb_ary_push(ary, i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.find_all {| obj | block }  => array\n *     enum.select   {| obj | block }  => array\n *\n *  Returns an array containing all elements of <i>enum</i> for which\n *  <em>block</em> is not <code>false</code> (see also\n *  <code>Enumerable#reject</code>).\n *\n *     (1..10).find_all {|i|  i % 3 == 0 }   #=> [3, 6, 9]\n *\n */\n\nstatic VALUE\nenum_find_all(obj)\n    VALUE obj;\n{\n    VALUE ary = rb_ary_new();\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n    rb_iterate(rb_each, obj, find_all_i, ary);\n\n    return ary;\n}\n\nstatic VALUE\nreject_i(i, ary)\n    VALUE i, ary;\n{\n    if (!RTEST(rb_yield(i))) {\n\trb_ary_push(ary, i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.reject {| obj | block }  => array\n *\n *  Returns an array for all elements of <i>enum</i> for which\n *  <em>block</em> is false (see also <code>Enumerable#find_all</code>).\n *\n *     (1..10).reject {|i|  i % 3 == 0 }   #=> [1, 2, 4, 5, 7, 8, 10]\n *\n */\n\nstatic VALUE\nenum_reject(obj)\n    VALUE obj;\n{\n    VALUE ary = rb_ary_new();\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n    rb_iterate(rb_each, obj, reject_i, ary);\n\n    return ary;\n}\n\nstatic VALUE\ncollect_i(i, ary)\n    VALUE i, ary;\n{\n    rb_ary_push(ary, rb_yield(i));\n\n    return Qnil;\n}\n\nstatic VALUE\ncollect_all(i, ary)\n    VALUE i, ary;\n{\n    rb_ary_push(ary, i);\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.collect {| obj | block }  => array\n *     enum.map     {| obj | block }  => array\n *\n *  Returns a new array with the results of running <em>block</em> once\n *  for every element in <i>enum</i>.\n *\n *     (1..4).collect {|i| i*i }   #=> [1, 4, 9, 16]\n *     (1..4).collect { \"cat\"  }   #=> [\"cat\", \"cat\", \"cat\", \"cat\"]\n *\n */\n\nstatic VALUE\nenum_collect(obj)\n    VALUE obj;\n{\n    VALUE ary = rb_ary_new();\n\n    rb_iterate(rb_each, obj, rb_block_given_p() ? collect_i : collect_all, ary);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     enum.to_a      =>    array\n *     enum.entries   =>    array\n *\n *  Returns an array containing the items in <i>enum</i>.\n *\n *     (1..7).to_a                       #=> [1, 2, 3, 4, 5, 6, 7]\n *     { 'a'=>1, 'b'=>2, 'c'=>3 }.to_a   #=> [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n */\nstatic VALUE\nenum_to_a(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE ary = rb_ary_new();\n\n    rb_block_call(obj, id_each, argc, argv, collect_all, ary);\n\n    return ary;\n}\n\nstatic VALUE inject_i _((VALUE, VALUE));\nstatic VALUE\ninject_i(i, p)\n    VALUE i;\n    VALUE p;\n{\n    VALUE *memo = (VALUE *)p;\n    if (memo[0] == Qundef) {\n\tmemo[0] = i;\n    }\n    else {\n\tmemo[0] = rb_yield_values(2, memo[0], i);\n    }\n    return Qnil;\n}\n\nstatic VALUE inject_op_i _((VALUE, VALUE));\nstatic VALUE\ninject_op_i(i, p)\n    VALUE i;\n    VALUE p;\n{\n    VALUE *memo = (VALUE *)p;\n\n    if (memo[0] == Qundef) {\n\tmemo[0] = i;\n    }\n    else {\n\tmemo[0] = rb_funcall(memo[0], (ID)memo[1], 1, i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.inject(initial, sym) => obj\n *     enum.inject(sym)          => obj\n *     enum.inject(initial) {| memo, obj | block }  => obj\n *     enum.inject          {| memo, obj | block }  => obj\n *\n *     enum.reduce(initial, sym) => obj\n *     enum.reduce(sym)          => obj\n *     enum.reduce(initial) {| memo, obj | block }  => obj\n *     enum.reduce          {| memo, obj | block }  => obj\n *\n *  Combines all elements of <i>enum</i> by applying a binary\n *  operation, specified by a block or a symbol that names a\n *  method or operator.\n *\n *  If you specify a block, then for each element in <i>enum<i>\n *  the block is passed an accumulator value (<i>memo</i>) and the element.\n *  If you specify a symbol instead, then each element in the collection\n *  will be passed to the named method of <i>memo</i>.\n *  In either case, the result becomes the new value for <i>memo</i>.\n *  At the end of the iteration, the final value of <i>memo</i> is the\n *  return value fo the method.\n *\n *  If you do not explicitly specify an <i>initial</i> value for <i>memo</i>,\n *  then uses the first element of collection is used as the initial value\n *  of <i>memo</i>.\n *\n *  Examples:\n *\n *     # Sum some numbers\n *     (5..10).reduce(:+)                            #=> 45\n *     # Same using a block and inject\n *     (5..10).inject {|sum, n| sum + n }            #=> 45\n *     # Multiply some numbers\n *     (5..10).reduce(1, :*)                         #=> 151200\n *     # Same using a block\n *     (5..10).inject(1) {|product, n| product * n } #=> 151200\n *     # find the longest word\n *     longest = %w{ cat sheep bear }.inject do |memo,word|\n *        memo.length > word.length ? memo : word\n *     end\n *     longest                                       #=> \"sheep\"\n *\n */\nstatic VALUE\nenum_inject(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE memo[2];\n    rb_block_call_func *iter = inject_i;\n\n    switch (rb_scan_args(argc, argv, \"02\", &memo[0], &memo[1])) {\n      case 0:\n\tmemo[0] = Qundef;\n\tbreak;\n      case 1:\n\tif (rb_block_given_p()) {\n\t    break;\n\t}\n\tmemo[1] = (VALUE)rb_to_id(memo[0]);\n\tmemo[0] = Qundef;\n\titer = inject_op_i;\n\tbreak;\n      case 2:\n\tif (rb_block_given_p()) {\n\t    rb_warning(\"given block not used\");\n\t}\n\tmemo[1] = (VALUE)rb_to_id(memo[1]);\n\titer = inject_op_i;\n\tbreak;\n    }\n    rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo);\n    if (memo[0] == Qundef) return Qnil;\n    return memo[0];\n}\n\nstatic VALUE\npartition_i(i, ary)\n    VALUE i, *ary;\n{\n    if (RTEST(rb_yield(i))) {\n\trb_ary_push(ary[0], i);\n    }\n    else {\n\trb_ary_push(ary[1], i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.partition {| obj | block }  => [ true_array, false_array ]\n *\n *  Returns two arrays, the first containing the elements of\n *  <i>enum</i> for which the block evaluates to true, the second\n *  containing the rest.\n *\n *     (1..6).partition {|i| (i&1).zero?}   #=> [[2, 4, 6], [1, 3, 5]]\n *\n */\n\nstatic VALUE\nenum_partition(obj)\n    VALUE obj;\n{\n    VALUE ary[2];\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    ary[0] = rb_ary_new();\n    ary[1] = rb_ary_new();\n    rb_iterate(rb_each, obj, partition_i, (VALUE)ary);\n\n    return rb_assoc_new(ary[0], ary[1]);\n}\n\nstatic VALUE\ngroup_by_i(i, hash)\n    VALUE i;\n    VALUE hash;\n{\n    VALUE group = rb_yield(i);\n    VALUE values;\n\n    values = rb_hash_aref(hash, group);\n    if (NIL_P(values)) {\n\tvalues = rb_ary_new3(1, i);\n\trb_hash_aset(hash, group, values);\n    }\n    else {\n\trb_ary_push(values, i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.group_by {| obj | block }  => a_hash\n *\n *  Returns a hash, which keys are evaluated result from the\n *  block, and values are arrays of elements in <i>enum</i>\n *  corresponding to the key.\n *\n *     (1..6).group_by {|i| i%3}   #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}\n *\n */\n\nstatic VALUE\nenum_group_by(obj)\n    VALUE obj;\n{\n    VALUE hash;\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    hash = rb_hash_new();\n    rb_block_call(obj, id_each, 0, 0, group_by_i, hash);\n\n    return hash;\n}\n\nstatic VALUE\nfirst_i(i, ary)\n    VALUE i;\n    VALUE *ary;\n{\n    if (NIL_P(ary[0])) {\n\tary[1] = i;\n\trb_iter_break();\n    }\n    else {\n\tlong n = NUM2LONG(ary[0]);\n\n\trb_ary_push(ary[1], i);\n\tn--;\n\tif (n <= 0) {\n\t    rb_iter_break();\n\t}\n\tary[0] = INT2NUM(n);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.first      -> obj or nil\n *     enum.first(n)   -> an_array\n *\n *  Returns the first element, or the first +n+ elements, of the enumerable.\n *  If the enumerable is empty, the first form returns <code>nil</code>, and the\n *  second form returns an empty array.\n *\n */\n\nstatic VALUE\nenum_first(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE n, ary[2];\n\n    if (argc == 0) {\n\tary[0] = ary[1] = Qnil;\n    }\n    else {\n\tlong len;\n\trb_scan_args(argc, argv, \"01\", &n);\n\tlen = NUM2LONG(n);\n\tif (len == 0) return rb_ary_new2(0);\n\tary[0] = INT2NUM(len);\n\tary[1] = rb_ary_new2(len);\n    }\n    rb_block_call(obj, id_each, 0, 0, first_i, (VALUE)ary);\n\n    return ary[1];\n}\n\n\n/*\n *  call-seq:\n *     enum.sort                     => array\n *     enum.sort {| a, b | block }   => array\n *\n *  Returns an array containing the items in <i>enum</i> sorted,\n *  either according to their own <code><=></code> method, or by using\n *  the results of the supplied block. The block should return -1, 0, or\n *  +1 depending on the comparison between <i>a</i> and <i>b</i>. As of\n *  Ruby 1.8, the method <code>Enumerable#sort_by</code> implements a\n *  built-in Schwartzian Transform, useful when key computation or\n *  comparison is expensive..\n *\n *     %w(rhea kea flea).sort         #=> [\"flea\", \"kea\", \"rhea\"]\n *     (1..10).sort {|a,b| b <=> a}   #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]\n */\n\nstatic VALUE\nenum_sort(obj)\n    VALUE obj;\n{\n    return rb_ary_sort(enum_to_a(0, 0, obj));\n}\n\nstatic VALUE\nsort_by_i(i, ary)\n    VALUE i, ary;\n{\n    VALUE v;\n    NODE *memo;\n\n    v = rb_yield(i);\n    if (RBASIC(ary)->klass) {\n\trb_raise(rb_eRuntimeError, \"sort_by reentered\");\n    }\n    memo = NEW_NODE_EDEN(NODE_MEMO, v, i, 0);\n    rb_ary_push(ary, (VALUE)memo);\n    return Qnil;\n}\n\nstatic int\nsort_by_cmp(aa, bb, data)\n    NODE **aa, **bb;\n    void *data;\n{\n    VALUE a = aa[0]->u1.value;\n    VALUE b = bb[0]->u1.value;\n    VALUE ary = (VALUE)data;\n\n    if (RBASIC(ary)->klass) {\n\trb_raise(rb_eRuntimeError, \"sort_by reentered\");\n    }\n    return rb_cmpint(rb_funcall(a, id_cmp, 1, b), a, b);\n}\n\n/*\n *  call-seq:\n *     enum.sort_by {| obj | block }    => array\n *\n *  Sorts <i>enum</i> using a set of keys generated by mapping the\n *  values in <i>enum</i> through the given block.\n *\n *     %w{ apple pear fig }.sort_by {|word| word.length}\n                    #=> [\"fig\", \"pear\", \"apple\"]\n *\n *  The current implementation of <code>sort_by</code> generates an\n *  array of tuples containing the original collection element and the\n *  mapped value. This makes <code>sort_by</code> fairly expensive when\n *  the keysets are simple\n *\n *     require 'benchmark'\n *     include Benchmark\n *\n *     a = (1..100000).map {rand(100000)}\n *\n *     bm(10) do |b|\n *       b.report(\"Sort\")    { a.sort }\n *       b.report(\"Sort by\") { a.sort_by {|a| a} }\n *     end\n *\n *  <em>produces:</em>\n *\n *     user     system      total        real\n *     Sort        0.180000   0.000000   0.180000 (  0.175469)\n *     Sort by     1.980000   0.040000   2.020000 (  2.013586)\n *\n *  However, consider the case where comparing the keys is a non-trivial\n *  operation. The following code sorts some files on modification time\n *  using the basic <code>sort</code> method.\n *\n *     files = Dir[\"*\"]\n *     sorted = files.sort {|a,b| File.new(a).mtime <=> File.new(b).mtime}\n *     sorted   #=> [\"mon\", \"tues\", \"wed\", \"thurs\"]\n *\n *  This sort is inefficient: it generates two new <code>File</code>\n *  objects during every comparison. A slightly better technique is to\n *  use the <code>Kernel#test</code> method to generate the modification\n *  times directly.\n *\n *     files = Dir[\"*\"]\n *     sorted = files.sort { |a,b|\n *       test(?M, a) <=> test(?M, b)\n *     }\n *     sorted   #=> [\"mon\", \"tues\", \"wed\", \"thurs\"]\n *\n *  This still generates many unnecessary <code>Time</code> objects. A\n *  more efficient technique is to cache the sort keys (modification\n *  times in this case) before the sort. Perl users often call this\n *  approach a Schwartzian Transform, after Randal Schwartz. We\n *  construct a temporary array, where each element is an array\n *  containing our sort key along with the filename. We sort this array,\n *  and then extract the filename from the result.\n *\n *     sorted = Dir[\"*\"].collect { |f|\n *        [test(?M, f), f]\n *     }.sort.collect { |f| f[1] }\n *     sorted   #=> [\"mon\", \"tues\", \"wed\", \"thurs\"]\n *\n *  This is exactly what <code>sort_by</code> does internally.\n *\n *     sorted = Dir[\"*\"].sort_by {|f| test(?M, f)}\n *     sorted   #=> [\"mon\", \"tues\", \"wed\", \"thurs\"]\n */\n\nstatic VALUE\nenum_sort_by(obj)\n    VALUE obj;\n{\n    VALUE ary;\n    long i;\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    if (TYPE(obj) == T_ARRAY) {\n\tary  = rb_ary_new2(RARRAY(obj)->len);\n    }\n    else {\n\tary = rb_ary_new();\n    }\n    RBASIC(ary)->klass = 0;\n    rb_iterate(rb_each, obj, sort_by_i, ary);\n    if (RARRAY(ary)->len > 1) {\n\tqsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE),\n\t      sort_by_cmp, (void *)ary);\n    }\n    if (RBASIC(ary)->klass) {\n\trb_raise(rb_eRuntimeError, \"sort_by reentered\");\n    }\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\tRARRAY(ary)->ptr[i] = RNODE(RARRAY(ary)->ptr[i])->u2.value;\n    }\n    RBASIC(ary)->klass = rb_cArray;\n    return ary;\n}\n\nstatic VALUE\nall_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    if (!RTEST(i)) {\n\t*memo = Qfalse;\n\trb_iter_break();\n    }\n    return Qnil;\n}\n\nstatic VALUE\nall_iter_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    return all_i(rb_yield(i), memo);\n}\n\n/*\n *  call-seq:\n *     enum.all? [{|obj| block } ]   => true or false\n *\n *  Passes each element of the collection to the given block. The method\n *  returns <code>true</code> if the block never returns\n *  <code>false</code> or <code>nil</code>. If the block is not given,\n *  Ruby adds an implicit block of <code>{|obj| obj}</code> (that is\n *  <code>all?</code> will return <code>true</code> only if none of the\n *  collection members are <code>false</code> or <code>nil</code>.)\n *\n *     %w{ ant bear cat}.all? {|word| word.length >= 3}   #=> true\n *     %w{ ant bear cat}.all? {|word| word.length >= 4}   #=> false\n *     [ nil, true, 99 ].all?                             #=> false\n *\n */\n\nstatic VALUE\nenum_all(obj)\n    VALUE obj;\n{\n    VALUE result = Qtrue;\n\n    rb_iterate(rb_each, obj, rb_block_given_p() ? all_iter_i : all_i, (VALUE)&result);\n    return result;\n}\n\nstatic VALUE\nany_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    if (RTEST(i)) {\n\t*memo = Qtrue;\n\trb_iter_break();\n    }\n    return Qnil;\n}\n\nstatic VALUE\nany_iter_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    return any_i(rb_yield(i), memo);\n}\n\n/*\n *  call-seq:\n *     enum.any? [{|obj| block } ]   => true or false\n *\n *  Passes each element of the collection to the given block. The method\n *  returns <code>true</code> if the block ever returns a value other\n *  than <code>false</code> or <code>nil</code>. If the block is not\n *  given, Ruby adds an implicit block of <code>{|obj| obj}</code> (that\n *  is <code>any?</code> will return <code>true</code> if at least one\n *  of the collection members is not <code>false</code> or\n *  <code>nil</code>.\n *\n *     %w{ ant bear cat}.any? {|word| word.length >= 3}   #=> true\n *     %w{ ant bear cat}.any? {|word| word.length >= 4}   #=> true\n *     [ nil, true, 99 ].any?                             #=> true\n *\n */\n\nstatic VALUE\nenum_any(obj)\n    VALUE obj;\n{\n    VALUE result = Qfalse;\n\n    rb_iterate(rb_each, obj, rb_block_given_p() ? any_iter_i : any_i, (VALUE)&result);\n    return result;\n}\n\nstatic VALUE\none_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    if (RTEST(i)) {\n\tif (*memo == Qundef) {\n\t    *memo = Qtrue;\n\t}\n\telse if (*memo == Qtrue) {\n\t    *memo = Qfalse;\n\t    rb_iter_break();\n\t}\n    }\n    return Qnil;\n}\n\nstatic VALUE\none_iter_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    return one_i(rb_yield(i), memo);\n}\n\n/*\n *  call-seq:\n *     enum.one? [{|obj| block }]   => true or false\n *\n *  Passes each element of the collection to the given block. The method\n *  returns <code>true</code> if the block returns <code>true</code>\n *  exactly once. If the block is not given, <code>one?</code> will return\n *  <code>true</code> only if exactly one of the collection members is\n *  true.\n *\n *     %w{ant bear cat}.one? {|word| word.length == 4}   #=> true\n *     %w{ant bear cat}.one? {|word| word.length > 4}    #=> false\n *     %w{ant bear cat}.one? {|word| word.length < 4}    #=> false\n *     [ nil, true, 99 ].one?                            #=> false\n *     [ nil, true, false ].one?                         #=> true\n *\n */\n\nstatic VALUE\nenum_one(obj)\n    VALUE obj;\n{\n    VALUE result = Qundef;\n\n    rb_block_call(obj, id_each, 0, 0, rb_block_given_p() ? one_iter_i : one_i, (VALUE)&result);\n    if (result == Qundef) return Qfalse;\n    return result;\n}\n\nstatic VALUE\nnone_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    if (RTEST(i)) {\n\t*memo = Qfalse;\n\trb_iter_break();\n    }\n    return Qnil;\n}\n\nstatic VALUE\nnone_iter_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    return none_i(rb_yield(i), memo);\n}\n\n/*\n *  call-seq:\n *     enum.none? [{|obj| block }]   => true or false\n *\n *  Passes each element of the collection to the given block. The method\n *  returns <code>true</code> if the block never returns <code>true</code>\n *  for all elements. If the block is not given, <code>none?</code> will return\n *  <code>true</code> only if none of the collection members is true.\n *\n *     %w{ant bear cat}.none? {|word| word.length == 5}  #=> true\n *     %w{ant bear cat}.none? {|word| word.length >= 4}  #=> false\n *     [].none?                                          #=> true\n *     [nil].none?                                       #=> true\n *     [nil,false].none?                                 #=> true\n */\nstatic VALUE\nenum_none(obj)\n    VALUE obj;\n{\n    VALUE result = Qtrue;\n\n    rb_block_call(obj, id_each, 0, 0, rb_block_given_p() ? none_iter_i : none_i, (VALUE)&result);\n    return result;\n}\n\nstatic VALUE\nmin_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE cmp;\n\n    if (*memo == Qundef) {\n\t*memo = i;\n    }\n    else {\n\tcmp = rb_funcall(i, id_cmp, 1, *memo);\n\tif (rb_cmpint(cmp, i, *memo) < 0) {\n\t    *memo = i;\n\t}\n    }\n    return Qnil;\n}\n\nstatic VALUE\nmin_ii(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE cmp;\n\n    if (*memo == Qundef) {\n\t*memo = i;\n    }\n    else {\n\tcmp = rb_yield_values(2, i, *memo);\n\tif (rb_cmpint(cmp, i, *memo) < 0) {\n\t    *memo = i;\n\t}\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     enum.min                    => obj\n *     enum.min {| a,b | block }   => obj\n *\n *  Returns the object in <i>enum</i> with the minimum value. The\n *  first form assumes all objects implement <code>Comparable</code>;\n *  the second uses the block to return <em>a <=> b</em>.\n *\n *     a = %w(albatross dog horse)\n *     a.min                                  #=> \"albatross\"\n *     a.min {|a,b| a.length <=> b.length }   #=> \"dog\"\n */\n\nstatic VALUE\nenum_min(obj)\n    VALUE obj;\n{\n    VALUE result = Qundef;\n\n    rb_iterate(rb_each, obj, rb_block_given_p() ? min_ii : min_i, (VALUE)&result);\n    if (result == Qundef) return Qnil;\n    return result;\n}\n\n/*\n *  call-seq:\n *     enum.max                    => obj\n *     enum.max {| a,b | block }   => obj\n *\n *  Returns the object in <i>enum</i> with the maximum value. The\n *  first form assumes all objects implement <code>Comparable</code>;\n *  the second uses the block to return <em>a <=> b</em>.\n *\n *     a = %w(albatross dog horse)\n *     a.max                                  #=> \"horse\"\n *     a.max {|a,b| a.length <=> b.length }   #=> \"albatross\"\n */\n\nstatic VALUE\nmax_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE cmp;\n\n    if (*memo == Qundef) {\n\t*memo = i;\n    }\n    else {\n\tcmp = rb_funcall(i, id_cmp, 1, *memo);\n\tif (rb_cmpint(cmp, i, *memo) > 0) {\n\t    *memo = i;\n\t}\n    }\n    return Qnil;\n}\n\nstatic VALUE\nmax_ii(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE cmp;\n\n    if (*memo == Qundef) {\n\t*memo = i;\n    }\n    else {\n\tcmp = rb_yield_values(2, i, *memo);\n\tif (rb_cmpint(cmp, i, *memo) > 0) {\n\t    *memo = i;\n\t}\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.max                   => obj\n *     enum.max {|a,b| block }    => obj\n *\n *  Returns the object in _enum_ with the maximum value. The\n *  first form assumes all objects implement <code>Comparable</code>;\n *  the second uses the block to return <em>a <=> b</em>.\n *\n *     a = %w(albatross dog horse)\n *     a.max                                  #=> \"horse\"\n *     a.max {|a,b| a.length <=> b.length }   #=> \"albatross\"\n */\n\nstatic VALUE\nenum_max(obj)\n    VALUE obj;\n{\n    VALUE result = Qundef;\n\n    rb_iterate(rb_each, obj, rb_block_given_p() ? max_ii : max_i, (VALUE)&result);\n    if (result == Qundef) return Qnil;\n    return result;\n}\n\nstatic VALUE\nminmax_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    int n;\n\n    if (memo[0] == Qundef) {\n\tmemo[0] = i;\n\tmemo[1] = i;\n    }\n    else {\n\tn = rb_cmpint(rb_funcall(i, id_cmp, 1, memo[0]), i, memo[0]);\n\tif (n < 0) {\n\t    memo[0] = i;\n\t}\n\tn = rb_cmpint(rb_funcall(i, id_cmp, 1, memo[1]), i, memo[1]);\n\tif (n > 0) {\n\t    memo[1] = i;\n\t}\n    }\n    return Qnil;\n}\n\nstatic VALUE\nminmax_ii(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    int n;\n\n    if (memo[0] == Qundef) {\n\tmemo[0] = i;\n\tmemo[1] = i;\n    }\n    else {\n\tVALUE ary = memo[2];\n\n\tRARRAY(ary)->ptr[0] = i;\n\tRARRAY(ary)->ptr[1] = memo[0];\n\tn = rb_cmpint(rb_yield(ary), i, memo[0]);\n\tif (n < 0) {\n\t    memo[0] = i;\n\t}\n\tRARRAY(ary)->ptr[0] = i;\n\tRARRAY(ary)->ptr[1] = memo[1];\n\tn = rb_cmpint(rb_yield(ary), i, memo[1]);\n\tif (n > 0) {\n\t    memo[1] = i;\n\t}\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.minmax                   => [min,max]\n *     enum.minmax {|a,b| block }    => [min,max]\n *\n *  Returns two elements array which contains the minimum and the\n *  maximum value in the enumerable.  The first form assumes all\n *  objects implement <code>Comparable</code>; the second uses the\n *  block to return <em>a <=> b</em>.\n *\n *     a = %w(albatross dog horse)\n *     a.minmax                                  #=> [\"albatross\", \"horse\"]\n *     a.minmax {|a,b| a.length <=> b.length }   #=> [\"dog\", \"albatross\"]\n */\n\nstatic VALUE\nenum_minmax(obj)\n    VALUE obj;\n{\n    VALUE result[3];\n    VALUE ary = rb_ary_new3(2, Qnil, Qnil);\n\n    result[0] = Qundef;\n    if (rb_block_given_p()) {\n\tresult[2] = ary;\n\trb_block_call(obj, id_each, 0, 0, minmax_ii, (VALUE)result);\n    }\n    else {\n\trb_block_call(obj, id_each, 0, 0, minmax_i, (VALUE)result);\n    }\n    if (result[0] != Qundef) {\n        RARRAY(ary)->ptr[0] = result[0];\n        RARRAY(ary)->ptr[1] = result[1];\n    }\n    return ary;\n}\n\nstatic VALUE\nmin_by_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE v;\n\n    v = rb_yield(i);\n    if (memo[0] == Qundef) {\n\tmemo[0] = v;\n\tmemo[1] = i;\n    }\n    else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo[0]), v, memo[0]) < 0) {\n\tmemo[0] = v;\n\tmemo[1] = i;\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.min_by {| obj| block }   => obj\n *\n *  Returns the object in <i>enum</i> that gives the minimum\n *  value from the given block.\n *\n *     a = %w(albatross dog horse)\n *     a.min_by {|x| x.length }   #=> \"dog\"\n */\n\nstatic VALUE\nenum_min_by(obj)\n    VALUE obj;\n{\n    VALUE memo[2];\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    memo[0] = Qundef;\n    memo[1] = Qnil;\n    rb_block_call(obj, id_each, 0, 0, min_by_i, (VALUE)memo);\n    return memo[1];\n}\n\nstatic VALUE\nmax_by_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE v;\n\n    v = rb_yield(i);\n    if (memo[0] == Qundef) {\n\tmemo[0] = v;\n\tmemo[1] = i;\n    }\n    else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo[0]), v, memo[0]) > 0) {\n\tmemo[0] = v;\n\tmemo[1] = i;\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.max_by {| obj| block }   => obj\n *\n *  Returns the object in <i>enum</i> that gives the maximum\n *  value from the given block.\n *\n *     a = %w(albatross dog horse)\n *     a.max_by {|x| x.length }   #=> \"albatross\"\n */\n\nstatic VALUE\nenum_max_by(obj)\n    VALUE obj;\n{\n    VALUE memo[2];\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    memo[0] = Qundef;\n    memo[1] = Qnil;\n    rb_block_call(obj, id_each, 0, 0, max_by_i, (VALUE)memo);\n    return memo[1];\n}\n\nstatic VALUE\nminmax_by_i(i, memo)\n    VALUE i;\n    VALUE *memo;\n{\n    VALUE v;\n\n    v = rb_yield(i);\n    if (memo[0] == Qundef) {\n\tmemo[0] = v;\n\tmemo[1] = v;\n\tmemo[2] = i;\n\tmemo[3] = i;\n    }\n    else {\n\tif (rb_cmpint(rb_funcall(v, id_cmp, 1, memo[0]), v, memo[0]) < 0) {\n\t    memo[0] = v;\n\t    memo[2] = i;\n\t}\n\tif (rb_cmpint(rb_funcall(v, id_cmp, 1, memo[1]), v, memo[1]) > 0) {\n\t    memo[1] = v;\n\t    memo[3] = i;\n\t}\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.minmax_by {| obj| block }   => [min, max]\n *\n *  Returns two elements array array containing the objects in\n *  <i>enum</i> that gives the minimum and maximum values respectively\n *  from the given block.\n *\n *     a = %w(albatross dog horse)\n *     a.minmax_by {|x| x.length }   #=> [\"dog\", \"albatross\"]\n */\n\nstatic VALUE\nenum_minmax_by(obj)\n    VALUE obj;\n{\n    VALUE memo[4];\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    memo[0] = Qundef;\n    memo[1] = Qundef;\n    memo[2] = Qnil;\n    memo[3] = Qnil;\n    rb_block_call(obj, id_each, 0, 0, minmax_by_i, (VALUE)memo);\n    return rb_assoc_new(memo[2], memo[3]);\n}\n\nstatic VALUE\nmember_i(item, memo)\n    VALUE item;\n    VALUE *memo;\n{\n    if (rb_equal(item, memo[0])) {\n\tmemo[1] = Qtrue;\n\trb_iter_break();\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.include?(obj)     => true or false\n *     enum.member?(obj)      => true or false\n *\n *  Returns <code>true</code> if any member of <i>enum</i> equals\n *  <i>obj</i>. Equality is tested using <code>==</code>.\n *\n *     IO.constants.include? \"SEEK_SET\"          #=> true\n *     IO.constants.include? \"SEEK_NO_FURTHER\"   #=> false\n *\n */\n\nstatic VALUE\nenum_member(obj, val)\n    VALUE obj, val;\n{\n    VALUE memo[2];\n\n    memo[0] = val;\n    memo[1] = Qfalse;\n    rb_iterate(rb_each, obj, member_i, (VALUE)memo);\n    return memo[1];\n}\n\nstatic VALUE\neach_with_index_i(val, memo)\n    VALUE val;\n    VALUE *memo;\n{\n    rb_yield_values(2, val, INT2FIX(*memo));\n    ++*memo;\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.each_with_index {|obj, i| block }  -> enum\n *\n *  Calls <em>block</em> with two arguments, the item and its index, for\n *  each item in <i>enum</i>.\n *\n *     hash = Hash.new\n *     %w(cat dog wombat).each_with_index {|item, index|\n *       hash[item] = index\n *     }\n *     hash   #=> {\"cat\"=>0, \"wombat\"=>2, \"dog\"=>1}\n *\n */\n\nstatic VALUE\nenum_each_with_index(obj)\n    VALUE obj;\n{\n    VALUE memo;\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n\n    memo = 0;\n    rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&memo);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     enum.reverse_each {|item| block } \n *  \n *  Traverses <i>enum</i> in reverse order.\n */\n\nstatic VALUE\nenum_reverse_each(int argc, VALUE *argv, VALUE obj)\n{\n    VALUE ary;\n    long i;\n\n    RETURN_ENUMERATOR(obj, argc, argv);\n\n    ary = enum_to_a(argc, argv, obj);\n\n    for (i = RARRAY_LEN(ary); --i >= 0; ) {\n\trb_yield(RARRAY_PTR(ary)[i]);\n    }\n\n    return obj;\n}\n\n\nstatic VALUE\nzip_i(val, memo)\n    VALUE val;\n    VALUE *memo;\n{\n    VALUE result = memo[0];\n    VALUE args = memo[1];\n    int idx = memo[2]++;\n    VALUE tmp;\n    int i;\n\n    tmp = rb_ary_new2(RARRAY(args)->len + 1);\n    rb_ary_store(tmp, 0, val);\n    for (i=0; i<RARRAY(args)->len; i++) {\n\trb_ary_push(tmp, rb_ary_entry(RARRAY(args)->ptr[i], idx));\n    }\n    if (rb_block_given_p()) {\n\trb_yield(tmp);\n    }\n    else {\n\trb_ary_push(result, tmp);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.zip(arg, ...)                   => array\n *     enum.zip(arg, ...) {|arr| block }    => nil\n *\n *  Converts any arguments to arrays, then merges elements of\n *  <i>enum</i> with corresponding elements from each argument. This\n *  generates a sequence of <code>enum#size</code> <em>n</em>-element\n *  arrays, where <em>n</em> is one more that the count of arguments. If\n *  the size of any argument is less than <code>enum#size</code>,\n *  <code>nil</code> values are supplied. If a block given, it is\n *  invoked for each output array, otherwise an array of arrays is\n *  returned.\n *\n *     a = [ 4, 5, 6 ]\n *     b = [ 7, 8, 9 ]\n *\n *     (1..3).zip(a, b)      #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]\n *     \"cat\\ndog\".zip([1])   #=> [[\"cat\\n\", 1], [\"dog\", nil]]\n *     (1..3).zip            #=> [[1], [2], [3]]\n *\n */\n\nstatic VALUE\nenum_zip(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    int i;\n    VALUE result;\n    VALUE memo[3];\n\n    for (i=0; i<argc; i++) {\n\targv[i] = rb_convert_type(argv[i], T_ARRAY, \"Array\", \"to_a\");\n    }\n    result = rb_block_given_p() ? Qnil : rb_ary_new();\n    memo[0] = result;\n    memo[1] = rb_ary_new4(argc, argv);\n    memo[2] = 0;\n    rb_iterate(rb_each, obj, zip_i, (VALUE)memo);\n\n    return result;\n}\n\nstatic VALUE\ntake_i(i, arg)\n    VALUE i;\n    VALUE *arg;\n{\n    rb_ary_push(arg[0], i);\n    if (--arg[1] == 0) rb_iter_break();\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.take(n)               => array\n *\n *  Returns first n elements from <i>enum</i>.\n *\n *     a = [1, 2, 3, 4, 5, 0]\n *     a.take(3)             # => [1, 2, 3]\n *\n */\n\nstatic VALUE\nenum_take(obj, n)\n    VALUE obj;\n    VALUE n;\n{\n    VALUE args[2];\n    long len = NUM2LONG(n);\n\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"attempt to take negative size\");\n    }\n\n    if (len == 0) return rb_ary_new2(0);\n    args[1] = len;\n    args[0] = rb_ary_new();\n    rb_block_call(obj, id_each, 0, 0, take_i, (VALUE)args);\n    return args[0];\n}\n\n\nstatic VALUE\ntake_while_i(i, ary)\n    VALUE i;\n    VALUE *ary;\n{\n    if (!RTEST(rb_yield(i))) rb_iter_break();\n    rb_ary_push(*ary, i);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.take_while {|arr| block }   => array\n *\n *  Passes elements to the block until the block returns nil or false,\n *  then stops iterating and returns an array of all prior elements.\n *\n *     a = [1, 2, 3, 4, 5, 0]\n *     a.take_while {|i| i < 3 }   # => [1, 2]\n *\n */\n\nstatic VALUE\nenum_take_while(obj)\n    VALUE obj;\n{\n    VALUE ary;\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n    ary = rb_ary_new();\n    rb_block_call(obj, id_each, 0, 0, take_while_i, (VALUE)&ary);\n    return ary;\n}\n\nstatic VALUE\ndrop_i(i, arg)\n    VALUE i;\n    VALUE *arg;\n{\n    if (arg[1] == 0) {\n\trb_ary_push(arg[0], i);\n    }\n    else {\n\targ[1]--;\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.drop(n)               => array\n *\n *  Drops first n elements from <i>enum</i>, and returns rest elements\n *  in an array.\n *\n *     a = [1, 2, 3, 4, 5, 0]\n *     a.drop(3)             # => [4, 5, 0]\n *\n */\n\nstatic VALUE\nenum_drop(obj, n)\n    VALUE obj;\n    VALUE n;\n{\n    VALUE args[2];\n    long len = NUM2LONG(n);\n\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"attempt to drop negative size\");\n    }\n\n    args[1] = len;\n    args[0] = rb_ary_new();\n    rb_block_call(obj, id_each, 0, 0, drop_i, (VALUE)args);\n    return args[0];\n}\n\n\nstatic VALUE\ndrop_while_i(i, args)\n    VALUE i;\n    VALUE *args;\n{\n    if (!args[1] && !RTEST(rb_yield(i))) {\n\targs[1] = Qtrue;\n    }\n    if (args[1]) {\n\trb_ary_push(args[0], i);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.drop_while {|arr| block }   => array\n *\n *  Drops elements up to, but not including, the first element for\n *  which the block returns nil or false and returns an array\n *  containing the remaining elements.\n *\n *     a = [1, 2, 3, 4, 5, 0]\n *     a.drop_while {|i| i < 3 }   # => [3, 4, 5, 0]\n *\n */\n\nstatic VALUE\nenum_drop_while(obj)\n    VALUE obj;\n{\n    VALUE args[2];\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n    args[0] = rb_ary_new();\n    args[1] = Qfalse;\n    rb_block_call(obj, id_each, 0, 0, drop_while_i, (VALUE)args);\n    return args[0];\n}\n\nstatic VALUE\ncycle_i(i, ary)\n    VALUE i;\n    VALUE ary;\n{\n    rb_ary_push(ary, i);\n    rb_yield(i);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     enum.cycle {|obj| block }\n *     enum.cycle(n) {|obj| block }\n *\n *  Calls <i>block</i> for each element of <i>enum</i> repeatedly _n_\n *  times or forever if none or nil is given.  If a non-positive\n *  number is given or the collection is empty, does nothing.  Returns\n *  nil if the loop has finished without getting interrupted.\n *\n *  Enumerable#cycle saves elements in an internal array so changes\n *  to <i>enum</i> after the first pass have no effect.\n *\n *     a = [\"a\", \"b\", \"c\"]\n *     a.cycle {|x| puts x }  # print, a, b, c, a, b, c,.. forever.\n *     a.cycle(2) {|x| puts x }  # print, a, b, c, a, b, c.\n *\n */\n\nstatic VALUE\nenum_cycle(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE ary;\n    VALUE nv = Qnil;\n    long n, i, len;\n\n    rb_scan_args(argc, argv, \"01\", &nv);\n\n    RETURN_ENUMERATOR(obj, argc, argv);\n    if (NIL_P(nv)) {\n        n = -1;\n    }\n    else {\n        n = NUM2LONG(nv);\n        if (n <= 0) return Qnil;\n    }\n    ary = rb_ary_new();\n    RBASIC(ary)->klass = 0;\n    rb_block_call(obj, id_each, 0, 0, cycle_i, ary);\n    len = RARRAY(ary)->len;\n    if (len == 0) return Qnil;\n    while (n < 0 || 0 < --n) {\n        for (i=0; i<len; i++) {\n            rb_yield(RARRAY(ary)->ptr[i]);\n        }\n    }\n    return Qnil;\t\t/* not reached */\n}\n\n/*\n *  The <code>Enumerable</code> mixin provides collection classes with\n *  several traversal and searching methods, and with the ability to\n *  sort. The class must provide a method <code>each</code>, which\n *  yields successive members of the collection. If\n *  <code>Enumerable#max</code>, <code>#min</code>, or\n *  <code>#sort</code> is used, the objects in the collection must also\n *  implement a meaningful <code><=></code> operator, as these methods\n *  rely on an ordering between members of the collection.\n */\n\nvoid\nInit_Enumerable()\n{\n    rb_mEnumerable = rb_define_module(\"Enumerable\");\n\n    rb_define_method(rb_mEnumerable, \"to_a\", enum_to_a, -1);\n    rb_define_method(rb_mEnumerable, \"entries\", enum_to_a, -1);\n\n    rb_define_method(rb_mEnumerable, \"sort\", enum_sort, 0);\n    rb_define_method(rb_mEnumerable, \"sort_by\", enum_sort_by, 0);\n    rb_define_method(rb_mEnumerable, \"grep\", enum_grep, 1);\n    rb_define_method(rb_mEnumerable, \"count\", enum_count, -1);\n    rb_define_method(rb_mEnumerable, \"find\", enum_find, -1);\n    rb_define_method(rb_mEnumerable, \"detect\", enum_find, -1);\n    rb_define_method(rb_mEnumerable, \"find_index\", enum_find_index, -1);\n    rb_define_method(rb_mEnumerable, \"find_all\", enum_find_all, 0);\n    rb_define_method(rb_mEnumerable, \"select\", enum_find_all, 0);\n    rb_define_method(rb_mEnumerable, \"reject\", enum_reject, 0);\n    rb_define_method(rb_mEnumerable, \"collect\", enum_collect, 0);\n    rb_define_method(rb_mEnumerable, \"map\", enum_collect, 0);\n    rb_define_method(rb_mEnumerable, \"inject\", enum_inject, -1);\n    rb_define_method(rb_mEnumerable, \"reduce\", enum_inject, -1);\n    rb_define_method(rb_mEnumerable, \"partition\", enum_partition, 0);\n    rb_define_method(rb_mEnumerable, \"group_by\", enum_group_by, 0);\n    rb_define_method(rb_mEnumerable, \"first\", enum_first, -1);\n    rb_define_method(rb_mEnumerable, \"all?\", enum_all, 0);\n    rb_define_method(rb_mEnumerable, \"any?\", enum_any, 0);\n    rb_define_method(rb_mEnumerable, \"one?\", enum_one, 0);\n    rb_define_method(rb_mEnumerable, \"none?\", enum_none, 0);\n    rb_define_method(rb_mEnumerable, \"min\", enum_min, 0);\n    rb_define_method(rb_mEnumerable, \"max\", enum_max, 0);\n    rb_define_method(rb_mEnumerable, \"minmax\", enum_minmax, 0);\n    rb_define_method(rb_mEnumerable, \"min_by\", enum_min_by, 0);\n    rb_define_method(rb_mEnumerable, \"max_by\", enum_max_by, 0);\n    rb_define_method(rb_mEnumerable, \"minmax_by\", enum_minmax_by, 0);\n    rb_define_method(rb_mEnumerable, \"member?\", enum_member, 1);\n    rb_define_method(rb_mEnumerable, \"include?\", enum_member, 1);\n    rb_define_method(rb_mEnumerable, \"each_with_index\", enum_each_with_index, 0);\n    rb_define_method(rb_mEnumerable, \"enum_with_index\", enum_each_with_index, 0);\n    rb_define_method(rb_mEnumerable, \"reverse_each\", enum_reverse_each, -1);\n    rb_define_method(rb_mEnumerable, \"zip\", enum_zip, -1);\n    rb_define_method(rb_mEnumerable, \"take\", enum_take, 1);\n    rb_define_method(rb_mEnumerable, \"take_while\", enum_take_while, 0);\n    rb_define_method(rb_mEnumerable, \"drop\", enum_drop, 1);\n    rb_define_method(rb_mEnumerable, \"drop_while\", enum_drop_while, 0);\n    rb_define_method(rb_mEnumerable, \"cycle\", enum_cycle, -1);\n\n    id_eqq  = rb_intern(\"===\");\n    id_each = rb_intern(\"each\");\n    id_cmp  = rb_intern(\"<=>\");\n    id_size = rb_intern(\"size\");\n}\n\n"
  },
  {
    "path": "enumerator.c",
    "content": "/************************************************\n\n  enumerator.c - provides Enumerator class\n\n  $Author$\n\n  Copyright (C) 2001-2003 Akinori MUSHA\n\n  $Idaemons: /home/cvs/rb/enumerator/enumerator.c,v 1.1.1.1 2001/07/15 10:12:48 knu Exp $\n  $RoughId: enumerator.c,v 1.6 2003/07/27 11:03:24 nobu Exp $\n  $Id$\n\n************************************************/\n\n#include \"ruby.h\"\n\n/*\n * Document-class: Enumerable::Enumerator\n *\n * A class which provides a method `each' to be used as an Enumerable\n * object.\n */\nVALUE rb_cEnumerator;\nstatic VALUE sym_each;\n\nVALUE rb_eStopIteration;\n\nstruct enumerator {\n    VALUE obj;\n    ID    meth;\n    VALUE proc;\n    VALUE args;\n    rb_block_call_func *iter;\n};\n\nstatic void enumerator_mark _((void *));\nstatic void\nenumerator_mark(p)\n    void *p;\n{\n    struct enumerator *ptr = p;\n    rb_gc_mark(ptr->obj);\n    rb_gc_mark(ptr->args);\n}\n\nstatic struct enumerator *\nenumerator_ptr(obj)\n    VALUE obj;\n{\n    struct enumerator *ptr;\n\n    Data_Get_Struct(obj, struct enumerator, ptr);\n    if (RDATA(obj)->dmark != enumerator_mark) {\n\trb_raise(rb_eTypeError,\n\t\t \"wrong argument type %s (expected Enumerable::Enumerator)\",\n\t\t rb_obj_classname(obj));\n    }\n    if (!ptr || ptr->obj == Qundef) {\n\trb_raise(rb_eArgError, \"uninitialized enumerator\");\n    }\n    return ptr;\n}\n\n/*\n *  call-seq:\n *    obj.to_enum(method = :each, *args)\n *    obj.enum_for(method = :each, *args)\n *\n *  Returns Enumerable::Enumerator.new(self, method, *args).\n *\n *  e.g.:\n *\n *     str = \"xyz\"\n *\n *     enum = str.enum_for(:each_byte)\n *     a = enum.map {|b| '%02x' % b } #=> [\"78\", \"79\", \"7a\"]\n *\n *     # protects an array from being modified\n *     a = [1, 2, 3]\n *     some_method(a.to_enum)\n *\n */\nstatic VALUE\nobj_to_enum(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE meth = sym_each;\n\n    if (argc > 0) {\n\t--argc;\n\tmeth = *argv++;\n    }\n    return rb_enumeratorize(obj, meth, argc, argv);\n}\n\nstatic VALUE\neach_slice_i(val, memo)\n    VALUE val;\n    VALUE *memo;\n{\n    VALUE ary = memo[0];\n    VALUE v = Qnil;\n    long size = (long)memo[1];\n\n    rb_ary_push(ary, val);\n\n    if (RARRAY_LEN(ary) == size) {\n\tv = rb_yield(ary);\n\tmemo[0] = rb_ary_new2(size);\n    }\n\n    return v;\n}\n\n/*\n *  call-seq:\n *    e.each_slice(n) {...}\n *    e.each_slice(n)\n *\n *  Iterates the given block for each slice of <n> elements.  If no\n *  block is given, returns an enumerator.\n *\n *  e.g.:\n *      (1..10).each_slice(3) {|a| p a}\n *      # outputs below\n *      [1, 2, 3]\n *      [4, 5, 6]\n *      [7, 8, 9]\n *      [10]\n *\n */\nstatic VALUE\nenum_each_slice(obj, n)\n    VALUE obj, n;\n{\n    long size = NUM2LONG(n);\n    VALUE args[2], ary;\n\n    if (size <= 0) rb_raise(rb_eArgError, \"invalid slice size\");\n    RETURN_ENUMERATOR(obj, 1, &n);\n    args[0] = rb_ary_new2(size);\n    args[1] = (VALUE)size;\n\n    rb_block_call(obj, SYM2ID(sym_each), 0, 0, each_slice_i, (VALUE)args);\n\n    ary = args[0];\n    if (RARRAY_LEN(ary) > 0) rb_yield(ary);\n\n    return Qnil;\n}\n\nstatic VALUE\neach_cons_i(val, memo)\n    VALUE val;\n    VALUE *memo;\n{\n    VALUE ary = memo[0];\n    VALUE v = Qnil;\n    long size = (long)memo[1];\n\n    if (RARRAY_LEN(ary) == size) {\n\trb_ary_shift(ary);\n    }\n    rb_ary_push(ary, val);\n    if (RARRAY_LEN(ary) == size) {\n\tv = rb_yield(rb_ary_dup(ary));\n    }\n    return v;\n}\n\n/*\n *  call-seq:\n *    each_cons(n) {...}\n *    each_cons(n)\n *\n *  Iterates the given block for each array of consecutive <n>\n *  elements.  If no block is given, returns an enumerator.a\n *\n *  e.g.:\n *      (1..10).each_cons(3) {|a| p a}\n *      # outputs below\n *      [1, 2, 3]\n *      [2, 3, 4]\n *      [3, 4, 5]\n *      [4, 5, 6]\n *      [5, 6, 7]\n *      [6, 7, 8]\n *      [7, 8, 9]\n *      [8, 9, 10]\n *\n */\nstatic VALUE\nenum_each_cons(obj, n)\n    VALUE obj, n;\n{\n    long size = NUM2LONG(n);\n    VALUE args[2];\n\n    if (size <= 0) rb_raise(rb_eArgError, \"invalid size\");\n    RETURN_ENUMERATOR(obj, 1, &n);\n    args[0] = rb_ary_new2(size);\n    args[1] = (VALUE)size;\n\n    rb_block_call(obj, SYM2ID(sym_each), 0, 0, each_cons_i, (VALUE)args);\n\n    return Qnil;\n}\n\nstatic VALUE enumerator_allocate _((VALUE));\nstatic VALUE\nenumerator_allocate(klass)\n    VALUE klass;\n{\n    struct enumerator *ptr;\n    VALUE enum_obj;\n\n    enum_obj = Data_Make_Struct(klass, struct enumerator,\n\t\t\t\tenumerator_mark, -1, ptr);\n    ptr->obj = Qundef;\n\n    return enum_obj;\n}\n\nstatic VALUE enumerator_each_i _((VALUE, VALUE));\nstatic VALUE\nenumerator_each_i(v, enum_obj)\n    VALUE v;\n    VALUE enum_obj;\n{\n    return rb_yield(v);\n}\n\nstatic VALUE\nenumerator_init(enum_obj, obj, meth, argc, argv)\n    VALUE enum_obj;\n    VALUE obj;\n    VALUE meth;\n    int argc;\n    VALUE *argv;\n{\n    struct enumerator *ptr;\n\n    Data_Get_Struct(enum_obj, struct enumerator, ptr);\n\n    if (!ptr) {\n\trb_raise(rb_eArgError, \"unallocated enumerator\");\n    }\n\n    ptr->obj  = obj;\n    ptr->meth = rb_to_id(meth);\n    ptr->iter = enumerator_each_i;\n    if (argc) ptr->args = rb_ary_new4(argc, argv);\n\n    return enum_obj;\n}\n\n/*\n *  call-seq:\n *    Enumerable::Enumerator.new(obj, method = :each, *args)\n *\n *  Creates a new Enumerable::Enumerator object, which is to be\n *  used as an Enumerable object using the given object's given\n *  method with the given arguments.\n *\n *  Use of this method is discouraged.  Use Kernel#enum_for() instead.\n */\nstatic VALUE\nenumerator_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE recv, meth = sym_each;\n\n    if (argc == 0)\n\trb_raise(rb_eArgError, \"wrong number of argument (0 for 1)\");\n    recv = *argv++;\n    if (--argc) {\n\tmeth = *argv++;\n\t--argc;\n    }\n    return enumerator_init(obj, recv, meth, argc, argv);\n}\n\n/* :nodoc: */\nstatic VALUE\nenumerator_init_copy(obj, orig)\n    VALUE obj;\n    VALUE orig;\n{\n    struct enumerator *ptr0, *ptr1;\n\n    ptr0 = enumerator_ptr(orig);\n\n    Data_Get_Struct(obj, struct enumerator, ptr1);\n\n    if (!ptr1) {\n\trb_raise(rb_eArgError, \"unallocated enumerator\");\n    }\n\n    ptr1->obj  = ptr0->obj;\n    ptr1->meth = ptr0->meth;\n    ptr1->iter = ptr0->iter;\n    ptr1->args = ptr0->args;\n\n    return obj;\n}\n\nVALUE\nrb_enumeratorize(obj, meth, argc, argv)\n    VALUE obj;\n    VALUE meth;\n    int argc;\n    VALUE *argv;\n{\n    return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv);\n}\n\n/*\n *  call-seq:\n *    enum.each {...}\n *\n *  Iterates the given block using the object and the method specified\n *  in the first place.  If no block is given, returns self.\n *\n */\nstatic VALUE\nenumerator_each(obj)\n    VALUE obj;\n{\n    struct enumerator *e;\n    int argc = 0;\n    VALUE *argv = 0;\n\n    if (!rb_block_given_p()) return obj;\n    e = enumerator_ptr(obj);\n    if (e->args) {\n\targc = RARRAY_LEN(e->args);\n\targv = RARRAY_PTR(e->args);\n    }\n    return rb_block_call(e->obj, e->meth, argc, argv, e->iter, (VALUE)e);\n}\n\nstatic VALUE\nenumerator_with_index_i(val, memo)\n    VALUE val;\n    VALUE *memo;\n{\n    val = rb_yield_values(2, val, INT2FIX(*memo));\n    ++*memo;\n    return val;\n}\n\n/*\n *  call-seq:\n *    e.with_index {|(*args), idx| ... }\n *    e.with_index\n *\n *  Iterates the given block for each elements with an index, which\n *  start from 0.  If no block is given, returns an enumerator.\n *\n */\nstatic VALUE\nenumerator_with_index(obj)\n    VALUE obj;\n{\n    struct enumerator *e = enumerator_ptr(obj);\n    VALUE memo = 0;\n    int argc = 0;\n    VALUE *argv = 0;\n\n    RETURN_ENUMERATOR(obj, 0, 0);\n    if (e->args) {\n\targc = RARRAY_LEN(e->args);\n\targv = RARRAY_PTR(e->args);\n    }\n    return rb_block_call(e->obj, e->meth, argc, argv,\n\t\t\t enumerator_with_index_i, (VALUE)&memo);\n}\n\n/*\n * call-seq:\n *   e.next   => object\n *\n * Returns the next object in the enumerator, and move the internal\n * position forward.  When the position reached at the end, internal\n * position is rewinded then StopIteration is raised.\n *\n * Note that enumeration sequence by next method does not affect other\n * non-external enumeration methods, unless underlying iteration\n * methods itself has side-effect, e.g. IO#each_line.\n *\n * Caution: Calling this method causes the \"generator\" library to be\n * loaded.\n */\n\nstatic VALUE\nenumerator_next(obj)\n    VALUE obj;\n{\n    rb_require(\"generator\");\n    return rb_funcall(obj, rb_intern(\"next\"), 0, 0);\n}\n\n/*\n * call-seq:\n *   e.rewind   => e\n *\n * Rewinds the enumeration sequence by the next method.\n */\n\nstatic VALUE\nenumerator_rewind(obj)\n    VALUE obj;\n{\n    rb_require(\"generator\");\n    return rb_funcall(obj, rb_intern(\"rewind\"), 0, 0);\n}\n\nvoid\nInit_Enumerator()\n{\n    rb_define_method(rb_mKernel, \"to_enum\", obj_to_enum, -1);\n    rb_define_method(rb_mKernel, \"enum_for\", obj_to_enum, -1);\n\n    rb_define_method(rb_mEnumerable, \"each_slice\", enum_each_slice, 1);\n    rb_define_method(rb_mEnumerable, \"enum_slice\", enum_each_slice, 1);\n    rb_define_method(rb_mEnumerable, \"each_cons\", enum_each_cons, 1);\n    rb_define_method(rb_mEnumerable, \"enum_cons\", enum_each_cons, 1);\n\n    rb_cEnumerator = rb_define_class_under(rb_mEnumerable, \"Enumerator\", rb_cObject);\n    rb_include_module(rb_cEnumerator, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cEnumerator, enumerator_allocate);\n    rb_define_method(rb_cEnumerator, \"initialize\", enumerator_initialize, -1);\n    rb_define_method(rb_cEnumerator, \"initialize_copy\", enumerator_init_copy, 1);\n    rb_define_method(rb_cEnumerator, \"each\", enumerator_each, 0);\n    rb_define_method(rb_cEnumerator, \"each_with_index\", enumerator_with_index, 0);\n    rb_define_method(rb_cEnumerator, \"with_index\", enumerator_with_index, 0);\n    rb_define_method(rb_cEnumerator, \"next\", enumerator_next, 0);\n    rb_define_method(rb_cEnumerator, \"rewind\", enumerator_rewind, 0);\n\n    rb_eStopIteration   = rb_define_class(\"StopIteration\", rb_eIndexError);\n\n    sym_each\t \t= ID2SYM(rb_intern(\"each\"));\n\n    rb_provide(\"enumerator.so\");\t/* for backward compatibility */\n}\n"
  },
  {
    "path": "env.h",
    "content": "/**********************************************************************\n\n  env.h -\n\n  $Author$\n  $Date$\n  created at: Mon Jul 11 11:53:03 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef ENV_H\n#define ENV_H\n\nextern struct FRAME {\n    VALUE self;\n    int argc;\n    ID last_func;\n    ID orig_func;\n    VALUE last_class;\n    struct FRAME *prev;\n    struct FRAME *tmp;\n    struct RNode *node;\n#ifdef GC_DEBUG\n    source_position_t* source_pos;\n#endif\n    int iter;\n    int flags;\n    unsigned long uniq;\n} *ruby_frame;\n\nvoid rb_gc_mark_frame _((struct FRAME *));\n\n#ifdef GC_DEBUG\nvoid gc_debug_get_frame_source_pos(struct FRAME* frame);\n#endif\n\n#define FRAME_DMETH  1\n#define FRAME_FUNC   2\n\nextern struct SCOPE {\n    struct RBasic super;\n    ID *local_tbl;\n    VALUE *local_vars;\n    int flags;\n} *ruby_scope;\n\n#define SCOPE_ALLOCA  0\n#define SCOPE_MALLOC  1\n#define SCOPE_NOSTACK 2\n#define SCOPE_DONT_RECYCLE 4\n#define SCOPE_CLONE   8\n\nextern int ruby_in_eval;\n\nextern VALUE ruby_class;\n\nstruct RVarmap {\n    struct RBasic super;\n    ID id;\n    VALUE val;\n    struct RVarmap *next;\n};\nextern struct RVarmap *ruby_dyna_vars;\n\n#endif /* ENV_H */\n"
  },
  {
    "path": "error.c",
    "content": "/**********************************************************************\n\n  error.c -\n\n  $Author$\n  $Date$\n  created at: Mon Aug  9 16:11:34 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"env.h\"\n#include \"st.h\"\n\n#include <stdio.h>\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n#ifdef HAVE_STDLIB_H\n#include <stdlib.h>\n#endif\n#ifndef EXIT_SUCCESS\n#define EXIT_SUCCESS 0\n#endif\n\nextern const char *ruby_description;\n\nint ruby_nerrs;\n\nstatic int\nerr_position(buf, len)\n    char *buf;\n    long len;\n{\n    ruby_set_current_source();\n    if (!ruby_sourcefile) {\n\treturn 0;\n    }\n    else if (ruby_sourceline == 0) {\n\treturn snprintf(buf, len, \"%s: \", ruby_sourcefile);\n    }\n    else {\n\treturn snprintf(buf, len, \"%s:%d: \", ruby_sourcefile, ruby_sourceline);\n    }\n}\n\nstatic void\nerr_snprintf(buf, len, fmt, args)\n    char *buf;\n    long len;\n    const char *fmt;\n    va_list args;\n{\n    long n;\n\n    n = err_position(buf, len);\n    if (len > n) {\n\tvsnprintf((char*)buf+n, len-n, fmt, args);\n    }\n}\n\nstatic void err_append _((const char*));\nstatic void\nerr_print(fmt, args)\n    const char *fmt;\n    va_list args;\n{\n    char buf[BUFSIZ];\n\n    err_snprintf(buf, BUFSIZ, fmt, args);\n    err_append(buf);\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_compile_error(const char *fmt, ...)\n#else\nrb_compile_error(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n\n    va_init_list(args, fmt);\n    err_print(fmt, args);\n    va_end(args);\n    ruby_nerrs++;\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_compile_error_append(const char *fmt, ...)\n#else\nrb_compile_error_append(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n    char buf[BUFSIZ];\n\n    va_init_list(args, fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n    err_append(buf);\n}\n\nstatic void\nwarn_print(fmt, args)\n    const char *fmt;\n    va_list args;\n{\n    char buf[BUFSIZ];\n    int len;\n\n    err_snprintf(buf, BUFSIZ, fmt, args);\n    len = strlen(buf);\n    buf[len++] = '\\n';\n    rb_write_error2(buf, len);\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_warn(const char *fmt, ...)\n#else\nrb_warn(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    char buf[BUFSIZ];\n    va_list args;\n\n    if (NIL_P(ruby_verbose)) return;\n\n    snprintf(buf, BUFSIZ, \"warning: %s\", fmt);\n\n    va_init_list(args, fmt);\n    warn_print(buf, args);\n    va_end(args);\n}\n\n/* rb_warning() reports only in verbose mode */\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_warning(const char *fmt, ...)\n#else\nrb_warning(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    char buf[BUFSIZ];\n    va_list args;\n\n    if (!RTEST(ruby_verbose)) return;\n\n    snprintf(buf, BUFSIZ, \"warning: %s\", fmt);\n\n    va_init_list(args, fmt);\n    warn_print(buf, args);\n    va_end(args);\n}\n\n/*\n * call-seq:\n *    warn(msg)   => nil\n *\n * Display the given message (followed by a newline) on STDERR unless\n * warnings are disabled (for example with the <code>-W0</code> flag).\n */\n\nstatic VALUE\nrb_warn_m(self, mesg)\n    VALUE self, mesg;\n{\n    if (!NIL_P(ruby_verbose)) {\n\trb_io_write(rb_stderr, mesg);\n\trb_io_write(rb_stderr, rb_default_rs);\n    }\n    return Qnil;\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_bug(const char *fmt, ...)\n#else\nrb_bug(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    char buf[BUFSIZ];\n    va_list args;\n    FILE *out = stderr;\n    int len = err_position(buf, BUFSIZ);\n\n    if (fwrite(buf, 1, len, out) == len ||\n\tfwrite(buf, 1, len, (out = stdout)) == len) {\n\tfputs(\"[BUG] \", out);\n\tva_init_list(args, fmt);\n\tvfprintf(out, fmt, args);\n\tva_end(args);\n\tfprintf(out, \"\\n%s\\n\\n\", ruby_description);\n    }\n    abort();\n}\n\nstatic struct types {\n    int type;\n    const char *name;\n} builtin_types[] = {\n    {T_NIL,\t\"nil\"},\n    {T_OBJECT,\t\"Object\"},\n    {T_CLASS,\t\"Class\"},\n    {T_ICLASS,\t\"iClass\"},\t/* internal use: mixed-in module holder */\n    {T_MODULE,\t\"Module\"},\n    {T_FLOAT,\t\"Float\"},\n    {T_STRING,\t\"String\"},\n    {T_REGEXP,\t\"Regexp\"},\n    {T_ARRAY,\t\"Array\"},\n    {T_FIXNUM,\t\"Fixnum\"},\n    {T_HASH,\t\"Hash\"},\n    {T_STRUCT,\t\"Struct\"},\n    {T_BIGNUM,\t\"Bignum\"},\n    {T_FILE,\t\"File\"},\n    {T_TRUE,\t\"true\"},\n    {T_FALSE,\t\"false\"},\n    {T_SYMBOL,\t\"Symbol\"},\t/* :symbol */\n    {T_DATA,\t\"Data\"},\t/* internal use: wrapped C pointers */\n    {T_MATCH,\t\"MatchData\"},\t/* data of $~ */\n    {T_VARMAP,\t\"Varmap\"},\t/* internal use: dynamic variables */\n    {T_SCOPE,\t\"Scope\"},\t/* internal use: variable scope */\n    {T_NODE,\t\"Node\"},\t/* internal use: syntax tree node */\n    {T_UNDEF,\t\"undef\"},\t/* internal use: #undef; should not happen */\n    {-1,\t0}\n};\n\nvoid\nrb_check_type(x, t)\n    VALUE x;\n    int t;\n{\n    struct types *type = builtin_types;\n\n    if (x == Qundef) {\n\trb_bug(\"undef leaked to the Ruby space\");\n    }\n\n    if (TYPE(x) != t) {\n\twhile (type->type >= 0) {\n\t    if (type->type == t) {\n\t\tconst char *etype;\n\n\t\tif (NIL_P(x)) {\n\t\t    etype = \"nil\";\n\t\t}\n\t\telse if (FIXNUM_P(x)) {\n\t\t    etype = \"Fixnum\";\n\t\t}\n\t\telse if (SYMBOL_P(x)) {\n\t\t    etype = \"Symbol\";\n\t\t}\n\t\telse if (rb_special_const_p(x)) {\n\t\t    etype = RSTRING(rb_obj_as_string(x))->ptr;\n\t\t}\n\t\telse {\n\t\t    etype = rb_obj_classname(x);\n\t\t}\n\t\trb_raise(rb_eTypeError, \"wrong argument type %s (expected %s)\",\n\t\t\t etype, type->name);\n\t    }\n\t    type++;\n\t}\n\trb_bug(\"unknown type 0x%x\", t);\n    }\n}\n\n/* exception classes */\n#include <errno.h>\n\nVALUE rb_eException;\nVALUE rb_eSystemExit;\nVALUE rb_eInterrupt;\nVALUE rb_eSignal;\nVALUE rb_eFatal;\nVALUE rb_eStandardError;\nVALUE rb_eRuntimeError;\nVALUE rb_eTypeError;\nVALUE rb_eArgError;\nVALUE rb_eIndexError;\nVALUE rb_eRangeError;\nVALUE rb_eNameError;\nVALUE rb_eNoMethodError;\nVALUE rb_eSecurityError;\nVALUE rb_eNotImpError;\nVALUE rb_eNoMemError;\nVALUE rb_cNameErrorMesg;\n\nVALUE rb_eScriptError;\nVALUE rb_eSyntaxError;\nVALUE rb_eLoadError;\n\nVALUE rb_eSystemCallError;\nVALUE rb_mErrno;\n\nVALUE\nrb_exc_new(etype, ptr, len)\n    VALUE etype;\n    const char *ptr;\n    long len;\n{\n    return rb_funcall(etype, rb_intern(\"new\"), 1, rb_str_new(ptr, len));\n}\n\nVALUE\nrb_exc_new2(etype, s)\n    VALUE etype;\n    const char *s;\n{\n    return rb_exc_new(etype, s, strlen(s));\n}\n\nVALUE\nrb_exc_new3(etype, str)\n    VALUE etype, str;\n{\n    StringValue(str);\n    return rb_funcall(etype, rb_intern(\"new\"), 1, str);\n}\n\n/*\n * call-seq:\n *    Exception.new(msg = nil)   =>  exception\n *\n *  Construct a new Exception object, optionally passing in\n *  a message.\n */\n\nstatic VALUE\nexc_initialize(argc, argv, exc)\n    int argc;\n    VALUE *argv;\n    VALUE exc;\n{\n    VALUE arg;\n\n    rb_scan_args(argc, argv, \"01\", &arg);\n    rb_iv_set(exc, \"mesg\", arg);\n    rb_iv_set(exc, \"bt\", Qnil);\n\n    return exc;\n}\n\n/*\n *  Document-method: exception\n *\n *  call-seq:\n *     exc.exception(string) -> an_exception or exc\n *\n *  With no argument, or if the argument is the same as the receiver,\n *  return the receiver. Otherwise, create a new\n *  exception object of the same class as the receiver, but with a\n *  message equal to <code>string.to_str</code>.\n *\n */\n\nstatic VALUE\nexc_exception(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE exc;\n\n    if (argc == 0) return self;\n    if (argc == 1 && self == argv[0]) return self;\n    exc = rb_obj_clone(self);\n    exc_initialize(argc, argv, exc);\n\n    return exc;\n}\n\n/*\n * call-seq:\n *   exception.to_s   =>  string\n *\n * Returns exception's message (or the name of the exception if\n * no message is set).\n */\n\nstatic VALUE\nexc_to_s(exc)\n    VALUE exc;\n{\n    VALUE mesg = rb_attr_get(exc, rb_intern(\"mesg\"));\n\n    if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));\n    if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);\n    return mesg;\n}\n\n/*\n * call-seq:\n *   exception.message   =>  string\n *   exception.to_str    =>  string\n *\n * Returns the result of invoking <code>exception.to_s</code>.\n * Normally this returns the exception's message or name. By\n * supplying a to_str method, exceptions are agreeing to\n * be used where Strings are expected.\n */\n\nstatic VALUE\nexc_to_str(exc)\n    VALUE exc;\n{\n    return rb_funcall(exc, rb_intern(\"to_s\"), 0, 0);\n}\n\n/*\n * call-seq:\n *   exception.inspect   => string\n *\n * Return this exception's class name an message\n */\n\nstatic VALUE\nexc_inspect(exc)\n    VALUE exc;\n{\n    VALUE str, klass;\n\n    klass = CLASS_OF(exc);\n    exc = rb_obj_as_string(exc);\n    if (RSTRING(exc)->len == 0) {\n\treturn rb_str_dup(rb_class_name(klass));\n    }\n\n    str = rb_str_buf_new2(\"#<\");\n    klass = rb_class_name(klass);\n    rb_str_buf_append(str, klass);\n    rb_str_buf_cat(str, \": \", 2);\n    rb_str_buf_append(str, exc);\n    rb_str_buf_cat(str, \">\", 1);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     exception.backtrace    => array\n *\n *  Returns any backtrace associated with the exception. The backtrace\n *  is an array of strings, each containing either ``filename:lineNo: in\n *  `method''' or ``filename:lineNo.''\n *\n *     def a\n *       raise \"boom\"\n *     end\n *\n *     def b\n *       a()\n *     end\n *\n *     begin\n *       b()\n *     rescue => detail\n *       print detail.backtrace.join(\"\\n\")\n *     end\n *\n *  <em>produces:</em>\n *\n *     prog.rb:2:in `a'\n *     prog.rb:6:in `b'\n *     prog.rb:10\n*/\n\nstatic VALUE\nexc_backtrace(exc)\n    VALUE exc;\n{\n    static ID bt;\n\n    if (!bt) bt = rb_intern(\"bt\");\n    return rb_attr_get(exc, bt);\n}\n\nVALUE\nrb_check_backtrace(bt)\n    VALUE bt;\n{\n    long i;\n    static const char err[] = \"backtrace must be Array of String\";\n\n    if (!NIL_P(bt)) {\n\tint t = TYPE(bt);\n\n\tif (t == T_STRING) return rb_ary_new3(1, bt);\n\tif (t != T_ARRAY) {\n\t    rb_raise(rb_eTypeError, err);\n\t}\n\tfor (i=0;i<RARRAY(bt)->len;i++) {\n\t    if (TYPE(RARRAY(bt)->ptr[i]) != T_STRING) {\n\t\trb_raise(rb_eTypeError, err);\n\t    }\n\t}\n    }\n    return bt;\n}\n\n/*\n *  call-seq:\n *     exc.set_backtrace(array)   =>  array\n *\n *  Sets the backtrace information associated with <i>exc</i>. The\n *  argument must be an array of <code>String</code> objects in the\n *  format described in <code>Exception#backtrace</code>.\n *\n */\n\nstatic VALUE\nexc_set_backtrace(exc, bt)\n    VALUE exc;\n    VALUE bt;\n{\n    return rb_iv_set(exc, \"bt\", rb_check_backtrace(bt));\n}\n\n/*\n * call-seq:\n *   SystemExit.new(status=0)   => system_exit\n *\n * Create a new +SystemExit+ exception with the given status.\n */\n\nstatic VALUE\nexit_initialize(argc, argv, exc)\n    int argc;\n    VALUE *argv;\n    VALUE exc;\n{\n    VALUE status = INT2FIX(EXIT_SUCCESS);\n    if (argc > 0 && FIXNUM_P(argv[0])) {\n\tstatus = *argv++;\n\t--argc;\n    }\n    rb_call_super(argc, argv);\n    rb_iv_set(exc, \"status\", status);\n    return exc;\n}\n\n\n/*\n * call-seq:\n *   system_exit.status   => fixnum\n *\n * Return the status value associated with this system exit.\n */\n\nstatic VALUE\nexit_status(exc)\n    VALUE exc;\n{\n    return rb_attr_get(exc, rb_intern(\"status\"));\n}\n\n\n/*\n * call-seq:\n *   system_exit.success?  => true or false\n *\n * Returns +true+ if exiting successful, +false+ if not.\n */\n\nstatic VALUE\nexit_success_p(exc)\n    VALUE exc;\n{\n    VALUE status = rb_attr_get(exc, rb_intern(\"status\"));\n    if (NIL_P(status)) return Qtrue;\n    if (status == INT2FIX(EXIT_SUCCESS)) return Qtrue;\n    return Qfalse;\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_name_error(ID id, const char *fmt, ...)\n#else\nrb_name_error(id, fmt, va_alist)\n    ID id;\n    const char *fmt;\n    va_dcl\n#endif\n{\n    VALUE exc, argv[2];\n    va_list args;\n    char buf[BUFSIZ];\n\n    va_init_list(args, fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n\n    argv[0] = rb_str_new2(buf);\n    argv[1] = ID2SYM(id);\n    exc = rb_class_new_instance(2, argv, rb_eNameError);\n    rb_exc_raise(exc);\n}\n\n/*\n * call-seq:\n *   NameError.new(msg [, name])  => name_error\n *\n * Construct a new NameError exception. If given the <i>name</i>\n * parameter may subsequently be examined using the <code>NameError.name</code>\n * method.\n */\n\nstatic VALUE\nname_err_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE name;\n\n    name = (argc > 1) ? argv[--argc] : Qnil;\n    rb_call_super(argc, argv);\n    rb_iv_set(self, \"name\", name);\n    return self;\n}\n\n/*\n *  call-seq:\n *    name_error.name    =>  string or nil\n *\n *  Return the name associated with this NameError exception.\n */\n\nstatic VALUE\nname_err_name(self)\n    VALUE self;\n{\n    return rb_attr_get(self, rb_intern(\"name\"));\n}\n\n/*\n * call-seq:\n *  name_error.to_s   => string\n *\n * Produce a nicely-formated string representing the +NameError+.\n */\n\nstatic VALUE\nname_err_to_s(exc)\n    VALUE exc;\n{\n    VALUE mesg = rb_attr_get(exc, rb_intern(\"mesg\")), str = mesg;\n\n    if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));\n    StringValue(str);\n    if (str != mesg) {\n\trb_iv_set(exc, \"mesg\", mesg = str);\n    }\n    if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);\n    return mesg;\n}\n\n/*\n * call-seq:\n *   NoMethodError.new(msg, name [, args])  => no_method_error\n *\n * Construct a NoMethodError exception for a method of the given name\n * called with the given arguments. The name may be accessed using\n * the <code>#name</code> method on the resulting object, and the\n * arguments using the <code>#args</code> method.\n */\n\nstatic VALUE\nnometh_err_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE args = (argc > 2) ? argv[--argc] : Qnil;\n    name_err_initialize(argc, argv, self);\n    rb_iv_set(self, \"args\", args);\n    return self;\n}\n\n/* :nodoc: */\nstatic void\nname_err_mesg_mark(ptr)\n    VALUE *ptr;\n{\n    rb_gc_mark_locations(ptr, ptr+3);\n}\n\n/* :nodoc: */\nstatic VALUE\nname_err_mesg_new(obj, mesg, recv, method)\n    VALUE obj, mesg, recv, method;\n{\n    VALUE *ptr = ALLOC_N(VALUE, 3);\n\n    ptr[0] = mesg;\n    ptr[1] = recv;\n    ptr[2] = method;\n    return Data_Wrap_Struct(rb_cNameErrorMesg, name_err_mesg_mark, -1, ptr);\n}\n\n/* :nodoc: */\nstatic VALUE\nname_err_mesg_to_str(obj)\n    VALUE obj;\n{\n    VALUE *ptr, mesg;\n    Data_Get_Struct(obj, VALUE, ptr);\n\n    mesg = ptr[0];\n    if (NIL_P(mesg)) return Qnil;\n    else {\n\tconst char *desc = 0;\n\tVALUE d = 0, args[3];\n\n\tobj = ptr[1];\n\tswitch (TYPE(obj)) {\n\t  case T_NIL:\n\t    desc = \"nil\";\n\t    break;\n\t  case T_TRUE:\n\t    desc = \"true\";\n\t    break;\n\t  case T_FALSE:\n\t    desc = \"false\";\n\t    break;\n\t  default:\n\t    d = rb_protect(rb_inspect, obj, 0);\n\t    if (NIL_P(d) || RSTRING(d)->len > 65) {\n\t\td = rb_any_to_s(obj);\n\t    }\n\t    desc = RSTRING(d)->ptr;\n\t    break;\n\t}\n\tif (desc && desc[0] != '#') {\n\t    d = rb_str_new2(desc);\n\t    rb_str_cat2(d, \":\");\n\t    rb_str_cat2(d, rb_obj_classname(obj));\n\t}\n\targs[0] = mesg;\n\targs[1] = ptr[2];\n\targs[2] = d;\n\tmesg = rb_f_sprintf(3, args);\n    }\n    if (OBJ_TAINTED(obj)) OBJ_TAINT(mesg);\n    return mesg;\n}\n\n/* :nodoc: */\nstatic VALUE\nname_err_mesg_load(klass, str)\n    VALUE klass, str;\n{\n    return str;\n}\n\n/*\n * call-seq:\n *   no_method_error.args  => obj\n *\n * Return the arguments passed in as the third parameter to\n * the constructor.\n */\n\nstatic VALUE\nnometh_err_args(self)\n    VALUE self;\n{\n    return rb_attr_get(self, rb_intern(\"args\"));\n}\n\nvoid\nrb_invalid_str(str, type)\n    const char *str, *type;\n{\n    VALUE s = rb_str_inspect(rb_str_new2(str));\n\n    rb_raise(rb_eArgError, \"invalid value for %s: %s\", type, RSTRING(s)->ptr);\n}\n\n/*\n *  Document-module: Errno\n *\n *  Ruby exception objects are subclasses of <code>Exception</code>.\n *  However, operating systems typically report errors using plain\n *  integers. Module <code>Errno</code> is created dynamically to map\n *  these operating system errors to Ruby classes, with each error\n *  number generating its own subclass of <code>SystemCallError</code>.\n *  As the subclass is created in module <code>Errno</code>, its name\n *  will start <code>Errno::</code>.\n *\n *  The names of the <code>Errno::</code> classes depend on\n *  the environment in which Ruby runs. On a typical Unix or Windows\n *  platform, there are <code>Errno</code> classes such as\n *  <code>Errno::EACCES</code>, <code>Errno::EAGAIN</code>,\n *  <code>Errno::EINTR</code>, and so on.\n *\n *  The integer operating system error number corresponding to a\n *  particular error is available as the class constant\n *  <code>Errno::</code><em>error</em><code>::Errno</code>.\n *\n *     Errno::EACCES::Errno   #=> 13\n *     Errno::EAGAIN::Errno   #=> 11\n *     Errno::EINTR::Errno    #=> 4\n *\n *  The full list of operating system errors on your particular platform\n *  are available as the constants of <code>Errno</code>.\n *\n *     Errno.constants   #=> E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL, ...\n */\n\nstatic st_table *syserr_tbl;\n\nstatic VALUE\nset_syserr(n, name)\n    int n;\n    const char *name;\n{\n    VALUE error;\n\n    if (!st_lookup(syserr_tbl, n, &error)) {\n\terror = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);\n\trb_define_const(error, \"Errno\", INT2NUM(n));\n\tst_add_direct(syserr_tbl, n, error);\n    }\n    else {\n\trb_define_const(rb_mErrno, name, error);\n    }\n    return error;\n}\n\nstatic VALUE\nget_syserr(n)\n    int n;\n{\n    VALUE error;\n\n    if (!st_lookup(syserr_tbl, n, &error)) {\n\tchar name[8];\t/* some Windows' errno have 5 digits. */\n\n\tsnprintf(name, sizeof(name), \"E%03d\", n);\n\terror = set_syserr(n, name);\n    }\n    return error;\n}\n\n/*\n * call-seq:\n *   SystemCallError.new(msg, errno)  => system_call_error_subclass\n *\n * If _errno_ corresponds to a known system error code, constructs\n * the appropriate <code>Errno</code> class for that error, otherwise\n * constructs a generic <code>SystemCallError</code> object. The\n * error number is subsequently available via the <code>errno</code>\n * method.\n */\n\nstatic VALUE\nsyserr_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n#if !defined(_WIN32) && !defined(__VMS)\n    char *strerror();\n#endif\n    const char *err;\n    VALUE mesg, error;\n    VALUE klass = rb_obj_class(self);\n\n    if (klass == rb_eSystemCallError) {\n\trb_scan_args(argc, argv, \"11\", &mesg, &error);\n\tif (argc == 1 && FIXNUM_P(mesg)) {\n\t    error = mesg; mesg = Qnil;\n\t}\n\tif (!NIL_P(error) && st_lookup(syserr_tbl, NUM2LONG(error), &klass)) {\n\t    /* change class */\n\t    if (TYPE(self) != T_OBJECT) { /* insurance to avoid type crash */\n\t\trb_raise(rb_eTypeError, \"invalid instance type\");\n\t    }\n\t    RBASIC(self)->klass = klass;\n\t}\n    }\n    else {\n\trb_scan_args(argc, argv, \"01\", &mesg);\n\terror = rb_const_get(klass, rb_intern(\"Errno\"));\n    }\n    if (!NIL_P(error)) err = strerror(NUM2LONG(error));\n    else err = \"unknown error\";\n    if (!NIL_P(mesg)) {\n\tVALUE str = mesg;\n\tsize_t len;\n\n\tStringValue(str);\n\tlen = strlen(err)+RSTRING(str)->len+3;\n\tmesg = rb_str_new(0, len);\n\tsnprintf(RSTRING(mesg)->ptr, len+1, \"%s - %.*s\", err,\n\t\t(int)RSTRING(str)->len, RSTRING(str)->ptr);\n\trb_str_resize(mesg, strlen(RSTRING(mesg)->ptr));\n    }\n    else {\n\tmesg = rb_str_new2(err);\n    }\n    rb_call_super(1, &mesg);\n    rb_iv_set(self, \"errno\", error);\n    return self;\n}\n\n/*\n * call-seq:\n *   system_call_error.errno   => fixnum\n *\n * Return this SystemCallError's error number.\n */\n\nstatic VALUE\nsyserr_errno(self)\n    VALUE self;\n{\n    return rb_attr_get(self, rb_intern(\"errno\"));\n}\n\n/*\n * call-seq:\n *   system_call_error === other  => true or false\n *\n * Return +true+ if the receiver is a generic +SystemCallError+, or\n * if the error numbers _self_ and _other_ are the same.\n */\n\n\nstatic VALUE\nsyserr_eqq(self, exc)\n    VALUE self, exc;\n{\n    VALUE num, e;\n    ID en = rb_intern(\"errno\");\n\n    if (!rb_obj_is_kind_of(exc, rb_eSystemCallError)) {\n\tif (!rb_respond_to(exc, en)) return Qfalse;\n    }\n    else if (self == rb_eSystemCallError) return Qtrue;\n\n    num = rb_attr_get(exc, en);\n    if (NIL_P(num)) {\n\tnum = rb_funcall(exc, en, 0, 0);\n    }\n    e = rb_const_get(self, rb_intern(\"Errno\"));\n    if (FIXNUM_P(num) ? num == e : rb_equal(num, e))\n\treturn Qtrue;\n    return Qfalse;\n}\n\n/*\n *  Descendents of class <code>Exception</code> are used to communicate\n *  between <code>raise</code> methods and <code>rescue</code>\n *  statements in <code>begin/end</code> blocks. <code>Exception</code>\n *  objects carry information about the exception---its type (the\n *  exception's class name), an optional descriptive string, and\n *  optional traceback information. Programs may subclass\n *  <code>Exception</code> to add additional information.\n */\n\nvoid\nInit_Exception()\n{\n    rb_eException   = rb_define_class(\"Exception\", rb_cObject);\n    rb_define_singleton_method(rb_eException, \"exception\", rb_class_new_instance, -1);\n    rb_define_method(rb_eException, \"exception\", exc_exception, -1);\n    rb_define_method(rb_eException, \"initialize\", exc_initialize, -1);\n    rb_define_method(rb_eException, \"to_s\", exc_to_s, 0);\n    rb_define_method(rb_eException, \"to_str\", exc_to_str, 0);\n    rb_define_method(rb_eException, \"message\", exc_to_str, 0);\n    rb_define_method(rb_eException, \"inspect\", exc_inspect, 0);\n    rb_define_method(rb_eException, \"backtrace\", exc_backtrace, 0);\n    rb_define_method(rb_eException, \"set_backtrace\", exc_set_backtrace, 1);\n\n    rb_eSystemExit  = rb_define_class(\"SystemExit\", rb_eException);\n    rb_define_method(rb_eSystemExit, \"initialize\", exit_initialize, -1);\n    rb_define_method(rb_eSystemExit, \"status\", exit_status, 0);\n    rb_define_method(rb_eSystemExit, \"success?\", exit_success_p, 0);\n\n    rb_eFatal  \t    = rb_define_class(\"fatal\", rb_eException);\n    rb_eSignal      = rb_define_class(\"SignalException\", rb_eException);\n    rb_eInterrupt   = rb_define_class(\"Interrupt\", rb_eSignal);\n\n    rb_eStandardError = rb_define_class(\"StandardError\", rb_eException);\n    rb_eTypeError     = rb_define_class(\"TypeError\", rb_eStandardError);\n    rb_eArgError      = rb_define_class(\"ArgumentError\", rb_eStandardError);\n    rb_eIndexError    = rb_define_class(\"IndexError\", rb_eStandardError);\n    rb_eRangeError    = rb_define_class(\"RangeError\", rb_eStandardError);\n    rb_eNameError     = rb_define_class(\"NameError\", rb_eStandardError);\n    rb_define_method(rb_eNameError, \"initialize\", name_err_initialize, -1);\n    rb_define_method(rb_eNameError, \"name\", name_err_name, 0);\n    rb_define_method(rb_eNameError, \"to_s\", name_err_to_s, 0);\n    rb_cNameErrorMesg = rb_define_class_under(rb_eNameError, \"message\", rb_cData);\n    rb_define_singleton_method(rb_cNameErrorMesg, \"!\", name_err_mesg_new, 3);\n    rb_define_method(rb_cNameErrorMesg, \"to_str\", name_err_mesg_to_str, 0);\n    rb_define_method(rb_cNameErrorMesg, \"_dump\", name_err_mesg_to_str, 1);\n    rb_define_singleton_method(rb_cNameErrorMesg, \"_load\", name_err_mesg_load, 1);\n    rb_eNoMethodError = rb_define_class(\"NoMethodError\", rb_eNameError);\n    rb_define_method(rb_eNoMethodError, \"initialize\", nometh_err_initialize, -1);\n    rb_define_method(rb_eNoMethodError, \"args\", nometh_err_args, 0);\n\n    rb_eScriptError = rb_define_class(\"ScriptError\", rb_eException);\n    rb_eSyntaxError = rb_define_class(\"SyntaxError\", rb_eScriptError);\n    rb_eLoadError   = rb_define_class(\"LoadError\", rb_eScriptError);\n    rb_eNotImpError = rb_define_class(\"NotImplementedError\", rb_eScriptError);\n\n    rb_eRuntimeError = rb_define_class(\"RuntimeError\", rb_eStandardError);\n    rb_eSecurityError = rb_define_class(\"SecurityError\", rb_eStandardError);\n    rb_eNoMemError = rb_define_class(\"NoMemoryError\", rb_eException);\n\n    syserr_tbl = st_init_numtable();\n    rb_eSystemCallError = rb_define_class(\"SystemCallError\", rb_eStandardError);\n    rb_define_method(rb_eSystemCallError, \"initialize\", syserr_initialize, -1);\n    rb_define_method(rb_eSystemCallError, \"errno\", syserr_errno, 0);\n    rb_define_singleton_method(rb_eSystemCallError, \"===\", syserr_eqq, 1);\n\n    rb_mErrno = rb_define_module(\"Errno\");\n\n    rb_define_global_function(\"warn\", rb_warn_m, 1);\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_raise(VALUE exc, const char *fmt, ...)\n#else\nrb_raise(exc, fmt, va_alist)\n    VALUE exc;\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n    char buf[BUFSIZ];\n\n    va_init_list(args,fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n    rb_exc_raise(rb_exc_new2(exc, buf));\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_loaderror(const char *fmt, ...)\n#else\nrb_loaderror(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n    char buf[BUFSIZ];\n\n    va_init_list(args, fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n    rb_exc_raise(rb_exc_new2(rb_eLoadError, buf));\n}\n\nvoid\nrb_notimplement()\n{\n    rb_raise(rb_eNotImpError,\n\t     \"%s() function is unimplemented on this machine\",\n\t     rb_id2name(ruby_frame->last_func));\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_fatal(const char *fmt, ...)\n#else\nrb_fatal(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n    char buf[BUFSIZ];\n\n    va_init_list(args, fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n\n    ruby_in_eval = 0;\n    rb_exc_fatal(rb_exc_new2(rb_eFatal, buf));\n}\n\nvoid\nrb_sys_fail(mesg)\n    const char *mesg;\n{\n    int n = errno;\n    VALUE arg;\n\n    errno = 0;\n    if (n == 0) {\n\trb_bug(\"rb_sys_fail(%s) - errno == 0\", mesg ? mesg : \"\");\n    }\n\n    arg = mesg ? rb_str_new2(mesg) : Qnil;\n    rb_exc_raise(rb_class_new_instance(1, &arg, get_syserr(n)));\n}\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_sys_warning(const char *fmt, ...)\n#else\nrb_sys_warning(fmt, va_alist)\n     const char *fmt;\n     va_dcl\n#endif\n{\n     char buf[BUFSIZ];\n     va_list args;\n     int errno_save;\n\n     errno_save = errno;\n\n     if (!RTEST(ruby_verbose)) return;\n\n     snprintf(buf, BUFSIZ, \"warning: %s\", fmt);\n     snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), \": %s\", strerror(errno_save));\n\n     va_init_list(args, fmt);\n     warn_print(buf, args);\n     va_end(args);\n     errno = errno_save;\n}\n\nvoid\nrb_load_fail(path)\n    const char *path;\n{\n    rb_loaderror(\"%s -- %s\", strerror(errno), path);\n}\n\nvoid\nrb_error_frozen(what)\n    const char *what;\n{\n    rb_raise(rb_eTypeError, \"can't modify frozen %s\", what);\n}\n\nvoid\nrb_check_frozen(obj)\n    VALUE obj;\n{\n    if (OBJ_FROZEN(obj)) rb_error_frozen(rb_obj_classname(obj));\n}\n\nvoid\nInit_syserr()\n{\n#ifdef EPERM\n    set_syserr(EPERM, \"EPERM\");\n#endif\n#ifdef ENOENT\n    set_syserr(ENOENT, \"ENOENT\");\n#endif\n#ifdef ESRCH\n    set_syserr(ESRCH, \"ESRCH\");\n#endif\n#ifdef EINTR\n    set_syserr(EINTR, \"EINTR\");\n#endif\n#ifdef EIO\n    set_syserr(EIO, \"EIO\");\n#endif\n#ifdef ENXIO\n    set_syserr(ENXIO, \"ENXIO\");\n#endif\n#ifdef E2BIG\n    set_syserr(E2BIG, \"E2BIG\");\n#endif\n#ifdef ENOEXEC\n    set_syserr(ENOEXEC, \"ENOEXEC\");\n#endif\n#ifdef EBADF\n    set_syserr(EBADF, \"EBADF\");\n#endif\n#ifdef ECHILD\n    set_syserr(ECHILD, \"ECHILD\");\n#endif\n#ifdef EAGAIN\n    set_syserr(EAGAIN, \"EAGAIN\");\n#endif\n#ifdef ENOMEM\n    set_syserr(ENOMEM, \"ENOMEM\");\n#endif\n#ifdef EACCES\n    set_syserr(EACCES, \"EACCES\");\n#endif\n#ifdef EFAULT\n    set_syserr(EFAULT, \"EFAULT\");\n#endif\n#ifdef ENOTBLK\n    set_syserr(ENOTBLK, \"ENOTBLK\");\n#endif\n#ifdef EBUSY\n    set_syserr(EBUSY, \"EBUSY\");\n#endif\n#ifdef EEXIST\n    set_syserr(EEXIST, \"EEXIST\");\n#endif\n#ifdef EXDEV\n    set_syserr(EXDEV, \"EXDEV\");\n#endif\n#ifdef ENODEV\n    set_syserr(ENODEV, \"ENODEV\");\n#endif\n#ifdef ENOTDIR\n    set_syserr(ENOTDIR, \"ENOTDIR\");\n#endif\n#ifdef EISDIR\n    set_syserr(EISDIR, \"EISDIR\");\n#endif\n#ifdef EINVAL\n    set_syserr(EINVAL, \"EINVAL\");\n#endif\n#ifdef ENFILE\n    set_syserr(ENFILE, \"ENFILE\");\n#endif\n#ifdef EMFILE\n    set_syserr(EMFILE, \"EMFILE\");\n#endif\n#ifdef ENOTTY\n    set_syserr(ENOTTY, \"ENOTTY\");\n#endif\n#ifdef ETXTBSY\n    set_syserr(ETXTBSY, \"ETXTBSY\");\n#endif\n#ifdef EFBIG\n    set_syserr(EFBIG, \"EFBIG\");\n#endif\n#ifdef ENOSPC\n    set_syserr(ENOSPC, \"ENOSPC\");\n#endif\n#ifdef ESPIPE\n    set_syserr(ESPIPE, \"ESPIPE\");\n#endif\n#ifdef EROFS\n    set_syserr(EROFS, \"EROFS\");\n#endif\n#ifdef EMLINK\n    set_syserr(EMLINK, \"EMLINK\");\n#endif\n#ifdef EPIPE\n    set_syserr(EPIPE, \"EPIPE\");\n#endif\n#ifdef EDOM\n    set_syserr(EDOM, \"EDOM\");\n#endif\n#ifdef ERANGE\n    set_syserr(ERANGE, \"ERANGE\");\n#endif\n#ifdef EDEADLK\n    set_syserr(EDEADLK, \"EDEADLK\");\n#endif\n#ifdef ENAMETOOLONG\n    set_syserr(ENAMETOOLONG, \"ENAMETOOLONG\");\n#endif\n#ifdef ENOLCK\n    set_syserr(ENOLCK, \"ENOLCK\");\n#endif\n#ifdef ENOSYS\n    set_syserr(ENOSYS, \"ENOSYS\");\n#endif\n#ifdef ENOTEMPTY\n    set_syserr(ENOTEMPTY, \"ENOTEMPTY\");\n#endif\n#ifdef ELOOP\n    set_syserr(ELOOP, \"ELOOP\");\n#endif\n#ifdef EWOULDBLOCK\n    set_syserr(EWOULDBLOCK, \"EWOULDBLOCK\");\n#endif\n#ifdef ENOMSG\n    set_syserr(ENOMSG, \"ENOMSG\");\n#endif\n#ifdef EIDRM\n    set_syserr(EIDRM, \"EIDRM\");\n#endif\n#ifdef ECHRNG\n    set_syserr(ECHRNG, \"ECHRNG\");\n#endif\n#ifdef EL2NSYNC\n    set_syserr(EL2NSYNC, \"EL2NSYNC\");\n#endif\n#ifdef EL3HLT\n    set_syserr(EL3HLT, \"EL3HLT\");\n#endif\n#ifdef EL3RST\n    set_syserr(EL3RST, \"EL3RST\");\n#endif\n#ifdef ELNRNG\n    set_syserr(ELNRNG, \"ELNRNG\");\n#endif\n#ifdef EUNATCH\n    set_syserr(EUNATCH, \"EUNATCH\");\n#endif\n#ifdef ENOCSI\n    set_syserr(ENOCSI, \"ENOCSI\");\n#endif\n#ifdef EL2HLT\n    set_syserr(EL2HLT, \"EL2HLT\");\n#endif\n#ifdef EBADE\n    set_syserr(EBADE, \"EBADE\");\n#endif\n#ifdef EBADR\n    set_syserr(EBADR, \"EBADR\");\n#endif\n#ifdef EXFULL\n    set_syserr(EXFULL, \"EXFULL\");\n#endif\n#ifdef ENOANO\n    set_syserr(ENOANO, \"ENOANO\");\n#endif\n#ifdef EBADRQC\n    set_syserr(EBADRQC, \"EBADRQC\");\n#endif\n#ifdef EBADSLT\n    set_syserr(EBADSLT, \"EBADSLT\");\n#endif\n#ifdef EDEADLOCK\n    set_syserr(EDEADLOCK, \"EDEADLOCK\");\n#endif\n#ifdef EBFONT\n    set_syserr(EBFONT, \"EBFONT\");\n#endif\n#ifdef ENOSTR\n    set_syserr(ENOSTR, \"ENOSTR\");\n#endif\n#ifdef ENODATA\n    set_syserr(ENODATA, \"ENODATA\");\n#endif\n#ifdef ETIME\n    set_syserr(ETIME, \"ETIME\");\n#endif\n#ifdef ENOSR\n    set_syserr(ENOSR, \"ENOSR\");\n#endif\n#ifdef ENONET\n    set_syserr(ENONET, \"ENONET\");\n#endif\n#ifdef ENOPKG\n    set_syserr(ENOPKG, \"ENOPKG\");\n#endif\n#ifdef EREMOTE\n    set_syserr(EREMOTE, \"EREMOTE\");\n#endif\n#ifdef ENOLINK\n    set_syserr(ENOLINK, \"ENOLINK\");\n#endif\n#ifdef EADV\n    set_syserr(EADV, \"EADV\");\n#endif\n#ifdef ESRMNT\n    set_syserr(ESRMNT, \"ESRMNT\");\n#endif\n#ifdef ECOMM\n    set_syserr(ECOMM, \"ECOMM\");\n#endif\n#ifdef EPROTO\n    set_syserr(EPROTO, \"EPROTO\");\n#endif\n#ifdef EMULTIHOP\n    set_syserr(EMULTIHOP, \"EMULTIHOP\");\n#endif\n#ifdef EDOTDOT\n    set_syserr(EDOTDOT, \"EDOTDOT\");\n#endif\n#ifdef EBADMSG\n    set_syserr(EBADMSG, \"EBADMSG\");\n#endif\n#ifdef EOVERFLOW\n    set_syserr(EOVERFLOW, \"EOVERFLOW\");\n#endif\n#ifdef ENOTUNIQ\n    set_syserr(ENOTUNIQ, \"ENOTUNIQ\");\n#endif\n#ifdef EBADFD\n    set_syserr(EBADFD, \"EBADFD\");\n#endif\n#ifdef EREMCHG\n    set_syserr(EREMCHG, \"EREMCHG\");\n#endif\n#ifdef ELIBACC\n    set_syserr(ELIBACC, \"ELIBACC\");\n#endif\n#ifdef ELIBBAD\n    set_syserr(ELIBBAD, \"ELIBBAD\");\n#endif\n#ifdef ELIBSCN\n    set_syserr(ELIBSCN, \"ELIBSCN\");\n#endif\n#ifdef ELIBMAX\n    set_syserr(ELIBMAX, \"ELIBMAX\");\n#endif\n#ifdef ELIBEXEC\n    set_syserr(ELIBEXEC, \"ELIBEXEC\");\n#endif\n#ifdef EILSEQ\n    set_syserr(EILSEQ, \"EILSEQ\");\n#endif\n#ifdef ERESTART\n    set_syserr(ERESTART, \"ERESTART\");\n#endif\n#ifdef ESTRPIPE\n    set_syserr(ESTRPIPE, \"ESTRPIPE\");\n#endif\n#ifdef EUSERS\n    set_syserr(EUSERS, \"EUSERS\");\n#endif\n#ifdef ENOTSOCK\n    set_syserr(ENOTSOCK, \"ENOTSOCK\");\n#endif\n#ifdef EDESTADDRREQ\n    set_syserr(EDESTADDRREQ, \"EDESTADDRREQ\");\n#endif\n#ifdef EMSGSIZE\n    set_syserr(EMSGSIZE, \"EMSGSIZE\");\n#endif\n#ifdef EPROTOTYPE\n    set_syserr(EPROTOTYPE, \"EPROTOTYPE\");\n#endif\n#ifdef ENOPROTOOPT\n    set_syserr(ENOPROTOOPT, \"ENOPROTOOPT\");\n#endif\n#ifdef EPROTONOSUPPORT\n    set_syserr(EPROTONOSUPPORT, \"EPROTONOSUPPORT\");\n#endif\n#ifdef ESOCKTNOSUPPORT\n    set_syserr(ESOCKTNOSUPPORT, \"ESOCKTNOSUPPORT\");\n#endif\n#ifdef EOPNOTSUPP\n    set_syserr(EOPNOTSUPP, \"EOPNOTSUPP\");\n#endif\n#ifdef EPFNOSUPPORT\n    set_syserr(EPFNOSUPPORT, \"EPFNOSUPPORT\");\n#endif\n#ifdef EAFNOSUPPORT\n    set_syserr(EAFNOSUPPORT, \"EAFNOSUPPORT\");\n#endif\n#ifdef EADDRINUSE\n    set_syserr(EADDRINUSE, \"EADDRINUSE\");\n#endif\n#ifdef EADDRNOTAVAIL\n    set_syserr(EADDRNOTAVAIL, \"EADDRNOTAVAIL\");\n#endif\n#ifdef ENETDOWN\n    set_syserr(ENETDOWN, \"ENETDOWN\");\n#endif\n#ifdef ENETUNREACH\n    set_syserr(ENETUNREACH, \"ENETUNREACH\");\n#endif\n#ifdef ENETRESET\n    set_syserr(ENETRESET, \"ENETRESET\");\n#endif\n#ifdef ECONNABORTED\n    set_syserr(ECONNABORTED, \"ECONNABORTED\");\n#endif\n#ifdef ECONNRESET\n    set_syserr(ECONNRESET, \"ECONNRESET\");\n#endif\n#ifdef ENOBUFS\n    set_syserr(ENOBUFS, \"ENOBUFS\");\n#endif\n#ifdef EISCONN\n    set_syserr(EISCONN, \"EISCONN\");\n#endif\n#ifdef ENOTCONN\n    set_syserr(ENOTCONN, \"ENOTCONN\");\n#endif\n#ifdef ESHUTDOWN\n    set_syserr(ESHUTDOWN, \"ESHUTDOWN\");\n#endif\n#ifdef ETOOMANYREFS\n    set_syserr(ETOOMANYREFS, \"ETOOMANYREFS\");\n#endif\n#ifdef ETIMEDOUT\n    set_syserr(ETIMEDOUT, \"ETIMEDOUT\");\n#endif\n#ifdef ECONNREFUSED\n    set_syserr(ECONNREFUSED, \"ECONNREFUSED\");\n#endif\n#ifdef EHOSTDOWN\n    set_syserr(EHOSTDOWN, \"EHOSTDOWN\");\n#endif\n#ifdef EHOSTUNREACH\n    set_syserr(EHOSTUNREACH, \"EHOSTUNREACH\");\n#endif\n#ifdef EALREADY\n    set_syserr(EALREADY, \"EALREADY\");\n#endif\n#ifdef EINPROGRESS\n    set_syserr(EINPROGRESS, \"EINPROGRESS\");\n#endif\n#ifdef ESTALE\n    set_syserr(ESTALE, \"ESTALE\");\n#endif\n#ifdef EUCLEAN\n    set_syserr(EUCLEAN, \"EUCLEAN\");\n#endif\n#ifdef ENOTNAM\n    set_syserr(ENOTNAM, \"ENOTNAM\");\n#endif\n#ifdef ENAVAIL\n    set_syserr(ENAVAIL, \"ENAVAIL\");\n#endif\n#ifdef EISNAM\n    set_syserr(EISNAM, \"EISNAM\");\n#endif\n#ifdef EREMOTEIO\n    set_syserr(EREMOTEIO, \"EREMOTEIO\");\n#endif\n#ifdef EDQUOT\n    set_syserr(EDQUOT, \"EDQUOT\");\n#endif\n}\n\nstatic void\nerr_append(s)\n    const char *s;\n{\n    extern VALUE ruby_errinfo;\n\n    if (ruby_in_eval) {\n\tif (NIL_P(ruby_errinfo)) {\n\t    ruby_errinfo = rb_exc_new2(rb_eSyntaxError, s);\n\t}\n\telse {\n\t    VALUE str = rb_obj_as_string(ruby_errinfo);\n\n\t    rb_str_cat2(str, \"\\n\");\n\t    rb_str_cat2(str, s);\n\t    ruby_errinfo = rb_exc_new3(rb_eSyntaxError, str);\n\t}\n    }\n    else {\n\trb_write_error(s);\n\trb_write_error(\"\\n\");\n    }\n}\n"
  },
  {
    "path": "eval.c",
    "content": "/**********************************************************************\n\n  eval.c -\n\n  $Author$\n  $Date$\n  created at: Thu Jun 10 14:22:17 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"node.h\"\n#include \"env.h\"\n#include \"util.h\"\n#include \"rubysig.h\"\n\n#ifdef HAVE_STDLIB_H\n#include <stdlib.h>\n#endif\n#ifndef EXIT_SUCCESS\n#define EXIT_SUCCESS 0\n#endif\n#ifndef EXIT_FAILURE\n#define EXIT_FAILURE 1\n#endif\n\n#include <stdio.h>\n\n#include \"st.h\"\n#include \"dln.h\"\n\n#ifdef GC_DEBUG\nRUBY_EXTERN int gc_debug_dump;\n#endif\n\n#ifdef __APPLE__\n#include <crt_externs.h>\n#endif\n\n/* Make alloca work the best possible way.  */\n#ifdef __GNUC__\n# ifndef atarist\n#  ifndef alloca\n#   define alloca __builtin_alloca\n#  endif\n# endif /* atarist */\n#else\n# ifdef HAVE_ALLOCA_H\n#  include <alloca.h>\n# else\n#  ifndef _AIX\n#   ifndef alloca /* predefined by HP cc +Olibcalls */\nvoid *alloca ();\n#   endif\n#  endif /* AIX */\n# endif /* HAVE_ALLOCA_H */\n#endif /* __GNUC__ */\n\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n\n#ifndef HAVE_STRING_H\nchar *strrchr _((const char*,const char));\n#endif\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#include <time.h>\n#include <sys/mman.h>\n\n#if defined(HAVE_FCNTL_H) || defined(_WIN32)\n#include <fcntl.h>\n#elif defined(HAVE_SYS_FCNTL_H)\n#include <sys/fcntl.h>\n#endif\n#ifdef __CYGWIN__\n#include <io.h>\n#endif\n\n#if defined(__BEOS__) && !defined(BONE)\n#include <net/socket.h>\n#endif\n\n#ifdef __MACOS__\n#include \"macruby_private.h\"\n#endif\n\n#ifdef __VMS\n#include \"vmsruby_private.h\"\n#endif\n\n#ifdef USE_CONTEXT\n\nNORETURN(static void rb_jump_context(rb_jmpbuf_t, int));\nstatic inline void\nrb_jump_context(env, val)\n    rb_jmpbuf_t env;\n    int val;\n{\n    env->status = val;\n    setcontext(&env->context);\n    abort();                    /* ensure noreturn */\n}\n/*\n * PRE_GETCONTEXT and POST_GETCONTEXT is a magic for getcontext, gcc,\n * IA64 register stack and SPARC register window combination problem.\n *\n * Assume following code sequence.\n *\n * 1. set a register in the register stack/window such as r32/l0.\n * 2. call getcontext.\n * 3. use the register.\n * 4. update the register for other use.\n * 5. call setcontext indirectly (or directly).\n *\n * This code should be run as 1->2->3->4->5->3->4.\n * But after second getcontext return (second 3),\n * the register is broken (updated).\n * It's because getcontext/setcontext doesn't preserve the content of the\n * register stack/window.\n *\n * setjmp also doesn't preserve the content of the register stack/window.\n * But it has not the problem because gcc knows setjmp may return twice.\n * gcc detects setjmp and generates setjmp safe code.\n *\n * So setjmp calls before and after the getcontext call makes the code\n * somewhat safe.\n * It fix the problem on IA64.\n * It is not required that setjmp is called at run time, since the problem is\n * register usage.\n *\n * Since the magic setjmp is not enough for SPARC,\n * inline asm is used to prohibit registers in register windows.\n *\n * Since the problem is fixed at gcc 4.0.3, the magic is applied only for\n * prior versions of gcc.\n * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957\n * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22127\n */\n#  define GCC_VERSION_BEFORE(major, minor, patchlevel) \\\n    (defined(__GNUC__) && !defined(__INTEL_COMPILER) && \\\n     ((__GNUC__ < (major)) ||  \\\n      (__GNUC__ == (major) && __GNUC_MINOR__ < (minor)) || \\\n      (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ < (patchlevel))))\n#  if GCC_VERSION_BEFORE(4,0,3) && (defined(sparc) || defined(__sparc__))\n#    ifdef __pic__\n/*\n * %l7 is excluded for PIC because it is PIC register.\n * http://lists.freebsd.org/pipermail/freebsd-sparc64/2006-January/003739.html\n */\n#      define PRE_GETCONTEXT \\\n         ({ __asm__ volatile (\"\" : : :  \\\n            \"%o0\", \"%o1\", \"%o2\", \"%o3\", \"%o4\", \"%o5\", \"%o7\", \\\n            \"%l0\", \"%l1\", \"%l2\", \"%l3\", \"%l4\", \"%l5\", \"%l6\", \\\n            \"%i0\", \"%i1\", \"%i2\", \"%i3\", \"%i4\", \"%i5\", \"%i7\"); })\n#    else\n#      define PRE_GETCONTEXT \\\n         ({ __asm__ volatile (\"\" : : :  \\\n            \"%o0\", \"%o1\", \"%o2\", \"%o3\", \"%o4\", \"%o5\", \"%o7\", \\\n            \"%l0\", \"%l1\", \"%l2\", \"%l3\", \"%l4\", \"%l5\", \"%l6\", \"%l7\", \\\n            \"%i0\", \"%i1\", \"%i2\", \"%i3\", \"%i4\", \"%i5\", \"%i7\"); })\n#    endif\n#    define POST_GETCONTEXT PRE_GETCONTEXT\n#  elif GCC_VERSION_BEFORE(4,0,3) && defined(__ia64)\nstatic jmp_buf function_call_may_return_twice_jmp_buf;\nint function_call_may_return_twice_false_1 = 0;\nint function_call_may_return_twice_false_2 = 0;\n#    define PRE_GETCONTEXT \\\n       (function_call_may_return_twice_false_1 ? \\\n        setjmp(function_call_may_return_twice_jmp_buf) : \\\n        0)\n#    define POST_GETCONTEXT \\\n       (function_call_may_return_twice_false_2 ? \\\n        setjmp(function_call_may_return_twice_jmp_buf) : \\\n        0)\n#  elif defined(__FreeBSD__) && __FreeBSD__ < 7\n/*\n * workaround for FreeBSD/i386 getcontext/setcontext bug.\n * clear the carry flag by (0 ? ... : ...).\n * FreeBSD PR 92110 http://www.freebsd.org/cgi/query-pr.cgi?pr=92110\n * [ruby-dev:28263]\n */\nstatic int volatile freebsd_clear_carry_flag = 0;\n#    define PRE_GETCONTEXT \\\n       (freebsd_clear_carry_flag ? (freebsd_clear_carry_flag = 0) : 0)\n#  endif\n#  ifndef PRE_GETCONTEXT\n#    define PRE_GETCONTEXT 0\n#  endif\n#  ifndef POST_GETCONTEXT\n#    define POST_GETCONTEXT 0\n#  endif\n#  define ruby_longjmp(env, val) rb_jump_context(env, val)\n#  define ruby_setjmp(just_before_setjmp, j) ((j)->status = 0, \\\n     (just_before_setjmp), \\\n     PRE_GETCONTEXT, \\\n     getcontext(&(j)->context), \\\n     POST_GETCONTEXT, \\\n     (j)->status)\n#else\n#  define ruby_setjmp(just_before_setjmp, env) \\\n     ((just_before_setjmp), RUBY_SETJMP(env))\n#  define ruby_longjmp(env,val) RUBY_LONGJMP(env,val)\n#  ifdef __CYGWIN__\nint _setjmp(), _longjmp();\n#  endif\n#endif\n\n#include <sys/types.h>\n#include <signal.h>\n#include <errno.h>\n\n#if defined(__VMS)\n#pragma nostandard\n#endif\n\n#ifdef HAVE_SYS_SELECT_H\n#include <sys/select.h>\n#endif\n\n#include <sys/stat.h>\n\nVALUE rb_cProc;\nVALUE rb_cBinding;\nstatic VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE));\nstatic VALUE rb_f_binding _((VALUE));\nNOINLINE(static void rb_f_END _((void)));\nstatic VALUE rb_f_block_given_p _((void));\nstatic VALUE block_pass _((VALUE,NODE*));\nstatic void eval_check_tick _((void));\n\nVALUE rb_cMethod;\nstatic VALUE method_call _((int, VALUE*, VALUE));\nVALUE rb_cUnboundMethod;\nstatic VALUE umethod_bind _((VALUE, VALUE));\nstatic VALUE rb_mod_define_method _((int, VALUE*, VALUE));\nNORETURN(static void rb_raise_jump _((VALUE)));\nstatic VALUE rb_make_exception _((int argc, VALUE *argv));\n\nstatic int scope_vmode;\n#define SCOPE_PUBLIC    0\n#define SCOPE_PRIVATE   1\n#define SCOPE_PROTECTED 2\n#define SCOPE_MODFUNC   5\n#define SCOPE_MASK      7\n#define SCOPE_SET(f)  (scope_vmode=(f))\n#define SCOPE_TEST(f) (scope_vmode&(f))\n\nVALUE (*ruby_sandbox_save)_((rb_thread_t));\nVALUE (*ruby_sandbox_restore)_((rb_thread_t));\nNODE* ruby_current_node;\n\nvoid\nruby_set_current_source()\n{\n    if (ruby_current_node) {\n        ruby_sourcefile = ruby_current_node->nd_file;\n        ruby_sourceline = nd_line(ruby_current_node);\n    }\n}\n\nint ruby_safe_level = 0;\n/* safe-level:\n   0 - strings from streams/environment/ARGV are tainted (default)\n   1 - no dangerous operation by tainted value\n   2 - process/file operations prohibited\n   3 - all generated objects are tainted\n   4 - no global (non-tainted) variable modification/no direct output\n*/\n\nstatic VALUE safe_getter _((void));\nstatic void safe_setter _((VALUE val));\n\nvoid\nrb_secure(level)\n    int level;\n{\n    if (level <= ruby_safe_level) {\n        if (ruby_frame->last_func) {\n            rb_raise(rb_eSecurityError, \"Insecure operation `%s' at level %d\",\n                     rb_id2name(ruby_frame->last_func), ruby_safe_level);\n        }\n        else {\n            rb_raise(rb_eSecurityError, \"Insecure operation at level %d\", ruby_safe_level);\n        }\n    }\n}\n\nvoid\nrb_secure_update(obj)\n    VALUE obj;\n{\n    if (!OBJ_TAINTED(obj)) rb_secure(4);\n}\n\nvoid\nrb_check_safe_obj(x)\n    VALUE x;\n{\n    if (ruby_safe_level > 0 && OBJ_TAINTED(x)){\n        if (ruby_frame->last_func) {\n            rb_raise(rb_eSecurityError, \"Insecure operation - %s\",\n                     rb_id2name(ruby_frame->last_func));\n        }\n        else {\n            rb_raise(rb_eSecurityError, \"Insecure operation: -r\");\n        }\n    }\n    rb_secure(4);\n}\n\nvoid\nrb_check_safe_str(x)\n    VALUE x;\n{\n    rb_check_safe_obj(x);\n    if (TYPE(x)!= T_STRING) {\n        rb_raise(rb_eTypeError, \"wrong argument type %s (expected String)\",\n                 rb_obj_classname(x));\n    }\n}\n\nNORETURN(static void print_undef _((VALUE, ID)));\nstatic void\nprint_undef(klass, id)\n    VALUE klass;\n    ID id;\n{\n    rb_name_error(id, \"undefined method `%s' for %s `%s'\",\n                  rb_id2name(id),\n                  (TYPE(klass) == T_MODULE) ? \"module\" : \"class\",\n                  rb_class2name(klass));\n}\n\nstatic ID removed, singleton_removed, undefined, singleton_undefined;\n\n#define CACHE_SIZE 0x800\n#define CACHE_MASK 0x7ff\n#define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)\n\nstruct cache_entry {            /* method hash table. */\n    ID mid;                     /* method's id */\n    ID mid0;                    /* method's original id */\n    VALUE klass;                /* receiver's class */\n    VALUE origin;               /* where method defined  */\n    NODE *method;\n    int noex;\n};\n\nstatic struct cache_entry cache[CACHE_SIZE];\nstatic int ruby_running = 0;\n\nvoid\nrb_clear_cache()\n{\n   struct cache_entry *ent, *end;\n\n    if (!ruby_running) return;\n    ent = cache; end = ent + CACHE_SIZE;\n    while (ent < end) {\n        ent->mid = 0;\n        ent++;\n    }\n}\n\nstatic void\nrb_clear_cache_for_undef(klass, id)\n    VALUE klass;\n    ID id;\n{\n    struct cache_entry *ent, *end;\n\n    if (!ruby_running) return;\n    ent = cache; end = ent + CACHE_SIZE;\n    while (ent < end) {\n        if (ent->mid == id &&\n            (ent->klass == klass ||\n             RCLASS(ent->origin)->m_tbl == RCLASS(klass)->m_tbl)) {\n            ent->mid = 0;\n        }\n        ent++;\n    }\n}\n\nstatic void\nrb_clear_cache_by_id(id)\n    ID id;\n{\n    struct cache_entry *ent, *end;\n\n    if (!ruby_running) return;\n    ent = cache; end = ent + CACHE_SIZE;\n    while (ent < end) {\n        if (ent->mid == id) {\n            ent->mid = 0;\n        }\n        ent++;\n    }\n}\n\nvoid\nrb_clear_cache_by_class(klass)\n    VALUE klass;\n{\n    struct cache_entry *ent, *end;\n\n    if (!ruby_running) return;\n    ent = cache; end = ent + CACHE_SIZE;\n    while (ent < end) {\n        if (ent->klass == klass || ent->origin == klass) {\n            ent->mid = 0;\n        }\n        ent++;\n    }\n}\n\nstatic ID init, eqq, each, aref, aset, match, missing;\nstatic ID added, singleton_added;\nstatic ID __id__, __send__, respond_to;\n\n#define NOEX_TAINTED 8\n#define NOEX_SAFE(n) ((n) >> 4)\n#define NOEX_WITH(n, v) ((n) | (v) << 4)\n#define NOEX_WITH_SAFE(n) NOEX_WITH(n, ruby_safe_level)\n\nvoid\nrb_add_method(klass, mid, node, noex)\n    VALUE klass;\n    ID mid;\n    NODE *node;\n    int noex;\n{\n    NODE *body;\n\n    if (NIL_P(klass)) klass = rb_cObject;\n    if (ruby_safe_level >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {\n        rb_raise(rb_eSecurityError, \"Insecure: can't define method\");\n    }\n    if (!FL_TEST(klass, FL_SINGLETON) &&\n        node && nd_type(node) != NODE_ZSUPER &&\n        (mid == rb_intern(\"initialize\" )|| mid == rb_intern(\"initialize_copy\"))) {\n        noex = NOEX_PRIVATE | noex;\n    }\n    else if (FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) == NODE_CFUNC &&\n             mid == rb_intern(\"allocate\")) {\n        rb_warn(\"defining %s.allocate is deprecated; use rb_define_alloc_func()\",\n                rb_class2name(rb_iv_get(klass, \"__attached__\")));\n        mid = ID_ALLOCATOR;\n    }\n    if (OBJ_FROZEN(klass)) rb_error_frozen(\"class/module\");\n    rb_clear_cache_by_id(mid);\n    body = NEW_METHOD(node, NOEX_WITH_SAFE(noex));\n    st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);\n    if (node && mid != ID_ALLOCATOR && ruby_running) {\n        if (FL_TEST(klass, FL_SINGLETON)) {\n            rb_funcall(rb_iv_get(klass, \"__attached__\"), singleton_added, 1, ID2SYM(mid));\n        }\n        else {\n            rb_funcall(klass, added, 1, ID2SYM(mid));\n        }\n    }\n}\n\nvoid\nrb_define_alloc_func(klass, func)\n    VALUE klass;\n    VALUE (*func) _((VALUE));\n{\n    Check_Type(klass, T_CLASS);\n    rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0),\n                  NOEX_PRIVATE);\n}\n\nvoid\nrb_undef_alloc_func(klass)\n    VALUE klass;\n{\n    Check_Type(klass, T_CLASS);\n    rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);\n}\n\nNODE*\nsearch_method(klass, id, origin)\n    VALUE klass, *origin;\n    ID id;\n{\n    st_data_t body;\n\n    if (!klass) return 0;\n    while (!st_lookup(RCLASS(klass)->m_tbl, id, &body)) {\n        klass = RCLASS(klass)->super;\n        if (!klass) return 0;\n    }\n\n    if (origin) *origin = klass;\n    return (NODE *)body;\n}\n\nstatic NODE*\nrb_get_method_body(klassp, idp, noexp)\n    VALUE *klassp;\n    ID *idp;\n    int *noexp;\n{\n    ID id = *idp;\n    VALUE klass = *klassp;\n    VALUE origin = 0;\n    NODE * volatile body;\n    struct cache_entry *ent;\n\n    if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) {\n        /* store empty info in cache */\n        ent = cache + EXPR1(klass, id);\n        ent->klass  = klass;\n        ent->origin = klass;\n        ent->mid = ent->mid0 = id;\n        ent->noex   = 0;\n        ent->method = 0;\n\n        return 0;\n    }\n\n    if (ruby_running) {\n        /* store in cache */\n        ent = cache + EXPR1(klass, id);\n        ent->klass  = klass;\n        ent->noex   = body->nd_noex;\n        if (noexp) *noexp = body->nd_noex;\n        body = body->nd_body;\n        if (nd_type(body) == NODE_FBODY) {\n            ent->mid = id;\n            *klassp = body->nd_orig;\n            ent->origin = body->nd_orig;\n            *idp = ent->mid0 = body->nd_mid;\n            body = ent->method = body->nd_head;\n        }\n        else {\n            *klassp = origin;\n            ent->origin = origin;\n            ent->mid = ent->mid0 = id;\n            ent->method = body;\n        }\n    }\n    else {\n        if (noexp) *noexp = body->nd_noex;\n        body = body->nd_body;\n        if (nd_type(body) == NODE_FBODY) {\n            *klassp = body->nd_orig;\n            *idp = body->nd_mid;\n            body = body->nd_head;\n        }\n        else {\n            *klassp = origin;\n        }\n    }\n\n    return body;\n}\n\nNODE*\nrb_method_node(klass, id)\n    VALUE klass;\n    ID id;\n{\n    int noex;\n\n    return rb_get_method_body(&klass, &id, &noex);\n}\n\nstatic void\nremove_method(klass, mid)\n    VALUE klass;\n    ID mid;\n{\n    st_data_t data;\n    NODE *body = 0;\n\n    if (klass == rb_cObject) {\n        rb_secure(4);\n    }\n    if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {\n        rb_raise(rb_eSecurityError, \"Insecure: can't remove method\");\n    }\n    if (OBJ_FROZEN(klass)) rb_error_frozen(\"class/module\");\n    if (mid == __id__ || mid == __send__ || mid == init) {\n        rb_warn(\"removing `%s' may cause serious problem\", rb_id2name(mid));\n    }\n    if (st_lookup(RCLASS(klass)->m_tbl, mid, &data)) {\n        body = (NODE *)data;\n        if (!body || !body->nd_body) body = 0;\n        else {\n            st_delete(RCLASS(klass)->m_tbl, &mid, &data);\n        }\n    }\n    if (!body) {\n        rb_name_error(mid, \"method `%s' not defined in %s\",\n                      rb_id2name(mid), rb_class2name(klass));\n    }\n    rb_clear_cache_for_undef(klass, mid);\n    if (FL_TEST(klass, FL_SINGLETON)) {\n        rb_funcall(rb_iv_get(klass, \"__attached__\"), singleton_removed, 1, ID2SYM(mid));\n    }\n    else {\n        rb_funcall(klass, removed, 1, ID2SYM(mid));\n    }\n}\n\nvoid\nrb_remove_method(klass, name)\n    VALUE klass;\n    const char *name;\n{\n    remove_method(klass, rb_intern(name));\n}\n\n/*\n *  call-seq:\n *     remove_method(symbol)   => self\n *\n *  Removes the method identified by _symbol_ from the current\n *  class. For an example, see <code>Module.undef_method</code>.\n */\n\nstatic VALUE\nrb_mod_remove_method(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n        remove_method(mod, rb_to_id(argv[i]));\n    }\n    return mod;\n}\n\n#undef rb_disable_super\n#undef rb_enable_super\n\nvoid\nrb_disable_super(klass, name)\n    VALUE klass;\n    const char *name;\n{\n    /* obsolete - no use */\n}\n\nvoid\nrb_enable_super(klass, name)\n    VALUE klass;\n    const char *name;\n{\n    rb_warn(\"rb_enable_super() is obsolete\");\n}\n\nstatic void\nrb_export_method(klass, name, noex)\n    VALUE klass;\n    ID name;\n    ID noex;\n{\n    NODE *body;\n    VALUE origin;\n\n    if (klass == rb_cObject) {\n        rb_secure(4);\n    }\n    body = search_method(klass, name, &origin);\n    if (!body && TYPE(klass) == T_MODULE) {\n        body = search_method(rb_cObject, name, &origin);\n    }\n    if (!body || !body->nd_body) {\n        print_undef(klass, name);\n    }\n    if (body->nd_noex != noex) {\n        if (klass == origin) {\n            body->nd_noex = noex;\n        }\n        else {\n            rb_add_method(klass, name, NEW_ZSUPER(), noex);\n        }\n    }\n}\n\nint\nrb_method_boundp(klass, id, ex)\n    VALUE klass;\n    ID id;\n    int ex;\n{\n    struct cache_entry *ent;\n    int noex;\n\n    /* is it in the method cache? */\n    ent = cache + EXPR1(klass, id);\n    if (ent->mid == id && ent->klass == klass) {\n        if (ex && (ent->noex & NOEX_PRIVATE))\n            return Qfalse;\n        if (!ent->method) return Qfalse;\n        return Qtrue;\n    }\n    if (rb_get_method_body(&klass, &id, &noex)) {\n        if (ex && (noex & NOEX_PRIVATE))\n            return Qfalse;\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\nvoid\nrb_attr(klass, id, read, write, ex)\n    VALUE klass;\n    ID id;\n    int read, write, ex;\n{\n    const char *name;\n    char *buf;\n    ID attriv;\n    int noex;\n    size_t len;\n\n    if (!ex) noex = NOEX_PUBLIC;\n    else {\n        if (SCOPE_TEST(SCOPE_PRIVATE)) {\n            noex = NOEX_PRIVATE;\n            rb_warning((scope_vmode == SCOPE_MODFUNC) ?\n                       \"attribute accessor as module_function\" :\n                       \"private attribute?\");\n        }\n        else if (SCOPE_TEST(SCOPE_PROTECTED)) {\n            noex = NOEX_PROTECTED;\n        }\n        else {\n            noex = NOEX_PUBLIC;\n        }\n    }\n\n    if (!rb_is_local_id(id) && !rb_is_const_id(id)) {\n        rb_name_error(id, \"invalid attribute name `%s'\", rb_id2name(id));\n    }\n    name = rb_id2name(id);\n    if (!name) {\n        rb_raise(rb_eArgError, \"argument needs to be symbol or string\");\n    }\n    GC_DEBUG_SET_SOURCE\n    len = strlen(name)+2;\n    buf = ALLOCA_N(char,len);\n    snprintf(buf, len, \"@%s\", name);\n    attriv = rb_intern(buf);\n    if (read) {\n        rb_add_method(klass, id, NEW_IVAR(attriv), noex);\n    }\n    if (write) {\n        rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex);\n    }\n}\n\nVALUE ruby_errinfo = Qnil;\nextern NODE *ruby_eval_tree_begin;\nextern NODE *ruby_eval_tree;\nextern int ruby_nerrs;\n\nVALUE rb_eLocalJumpError;\nVALUE rb_eSysStackError;\n\nextern VALUE ruby_top_self;\n\nstruct FRAME *ruby_frame;\nstruct SCOPE *ruby_scope;\nstatic struct FRAME *top_frame;\nstatic struct SCOPE *top_scope;\n\nstatic unsigned long frame_unique = 0;\n\n#ifdef GC_DEBUG\n#define CREATE_FRAME_SOURCE_POS(pframe) \\\n    gc_debug_get_frame_source_pos(pframe);\n#define CREATE_FRAME_SOURCE_POS_FOR_PUSH(pframe) \\\n    _frame.self = 0; \\\n    _frame.last_func = 0; \\\n    _frame.orig_func = 0; \\\n    _frame.last_class = 0; \\\n    CREATE_FRAME_SOURCE_POS(pframe);\n#else\n#define CREATE_FRAME_SOURCE_POS(pframe)\n#define CREATE_FRAME_SOURCE_POS_FOR_PUSH(pframe)\n#endif\n\n#define PUSH_FRAME() do { \\\n    volatile struct FRAME _frame; \\\n    _frame.prev = ruby_frame; \\\n    _frame.node = ruby_current_node; \\\n    _frame.iter = ruby_iter->iter; \\\n    _frame.tmp  = 0; \\\n    _frame.argc = 0; \\\n    _frame.flags = 0; \\\n    _frame.uniq = frame_unique++; \\\n    CREATE_FRAME_SOURCE_POS_FOR_PUSH((struct FRAME *)&_frame) \\\n    ruby_frame = &_frame;\n\n#define POP_FRAME() \\\n    ruby_current_node = _frame.node; \\\n    ruby_frame = _frame.prev; \\\n} while (0)\n\nstruct BLOCK {\n    NODE *var;\n    NODE *body;\n    VALUE self;\n    struct FRAME frame;\n    struct SCOPE *scope;\n    VALUE klass;\n    NODE *cref;\n    int iter;\n    int vmode;\n    int flags;\n    int uniq;\n    struct RVarmap *dyna_vars;\n    VALUE orig_thread;\n    VALUE wrapper;\n    VALUE block_obj;\n    struct BLOCK *outer;\n    struct BLOCK *prev;\n};\n\n#define BLOCK_D_SCOPE 1\n#define BLOCK_LAMBDA  2\n\nstatic struct BLOCK *ruby_block;\nstatic unsigned long block_unique = 1;\n\n#define PUSH_BLOCK(v,b) do {            \\\n    struct BLOCK _block;                \\\n    _block.var = (v);                   \\\n    _block.body = (b);                  \\\n    _block.self = self;                 \\\n    _block.frame = *ruby_frame;         \\\n    _block.klass = ruby_class;          \\\n    _block.cref = ruby_cref;            \\\n    _block.frame.node = ruby_current_node;\\\n    _block.scope = ruby_scope;          \\\n    _block.prev = ruby_block;           \\\n    CREATE_FRAME_SOURCE_POS(&_block.frame);     \\\n    _block.outer = ruby_block;          \\\n    _block.iter = ruby_iter->iter;      \\\n    _block.vmode = scope_vmode;         \\\n    _block.flags = BLOCK_D_SCOPE;       \\\n    _block.dyna_vars = ruby_dyna_vars;  \\\n    _block.wrapper = ruby_wrapper;      \\\n    _block.block_obj = 0;               \\\n    _block.uniq = (b)?block_unique++:0; \\\n    if (b) {                            \\\n        prot_tag->blkid = _block.uniq;  \\\n    }                                   \\\n    ruby_block = &_block\n\n#define POP_BLOCK() \\\n   ruby_block = _block.prev; \\\n} while (0)\n\nstruct RVarmap *ruby_dyna_vars;\n#define PUSH_VARS() do { \\\n    struct RVarmap * volatile _old; \\\n    _old = ruby_dyna_vars; \\\n    ruby_dyna_vars = 0\n\n#define POP_VARS() \\\n    if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) {\\\n        if (RBASIC(_old)->flags) /* unless it's already recycled */ \\\n            FL_SET(_old, DVAR_DONT_RECYCLE); \\\n    }\\\n    ruby_dyna_vars = _old; \\\n} while (0)\n\n#define DVAR_DONT_RECYCLE FL_USER2\n\n#define DMETHOD_P() (ruby_frame->flags & FRAME_DMETH)\n\nstatic struct RVarmap*\nnew_dvar(id, value, prev)\n    ID id;\n    VALUE value;\n    struct RVarmap *prev;\n{\n    NEWOBJ(vars, struct RVarmap);\n    OBJSETUP(vars, 0, T_VARMAP);\n    vars->id = id;\n    vars->val = value;\n    vars->next = prev;\n\n    return vars;\n}\n\nVALUE\nrb_dvar_defined(id)\n    ID id;\n{\n    struct RVarmap *vars = ruby_dyna_vars;\n\n    while (vars) {\n        if (vars->id == id) return Qtrue;\n        vars = vars->next;\n    }\n    return Qfalse;\n}\n\nVALUE\nrb_dvar_curr(id)\n    ID id;\n{\n    struct RVarmap *vars = ruby_dyna_vars;\n\n    while (vars) {\n        if (vars->id == 0) break;\n        if (vars->id == id) return Qtrue;\n        vars = vars->next;\n    }\n    return Qfalse;\n}\n\nVALUE\nrb_dvar_ref(id)\n    ID id;\n{\n    struct RVarmap *vars = ruby_dyna_vars;\n\n    while (vars) {\n        if (vars->id == id) {\n            return vars->val;\n        }\n        vars = vars->next;\n    }\n    return Qnil;\n}\n\nvoid\nrb_dvar_push(id, value)\n    ID id;\n    VALUE value;\n{\n    ruby_dyna_vars = new_dvar(id, value, ruby_dyna_vars);\n}\n\nstatic void\ndvar_asgn_internal(id, value, curr)\n    ID id;\n    VALUE value;\n    int curr;\n{\n    int n = 0;\n    struct RVarmap *vars = ruby_dyna_vars;\n\n    while (vars) {\n        if (curr && vars->id == 0) {\n            /* first null is a dvar header */\n            n++;\n            if (n == 2) break;\n        }\n        if (vars->id == id) {\n            vars->val = value;\n            return;\n        }\n        vars = vars->next;\n    }\n    if (!ruby_dyna_vars) {\n        ruby_dyna_vars = new_dvar(id, value, 0);\n    }\n    else {\n        vars = new_dvar(id, value, ruby_dyna_vars->next);\n        ruby_dyna_vars->next = vars;\n    }\n}\n\nstatic inline void\ndvar_asgn(id, value)\n    ID id;\n    VALUE value;\n{\n    dvar_asgn_internal(id, value, 0);\n}\n\nstatic inline void\ndvar_asgn_curr(id, value)\n    ID id;\n    VALUE value;\n{\n    dvar_asgn_internal(id, value, 1);\n}\n\nVALUE *\nrb_svar(cnt)\n    int cnt;\n{\n    struct RVarmap *vars = ruby_dyna_vars;\n    ID id;\n\n    if (!ruby_scope->local_tbl) return NULL;\n    if ((ID)cnt >= ruby_scope->local_tbl[0]) return NULL;\n    id = ruby_scope->local_tbl[cnt+1];\n    while (vars) {\n        if (vars->id == id) return &vars->val;\n        vars = vars->next;\n    }\n    if (ruby_scope->local_vars == 0) return NULL;\n    return &ruby_scope->local_vars[cnt];\n}\n\nstruct iter {\n    int iter;\n    struct iter *prev;\n};\nstatic struct iter *ruby_iter;\n\n#define ITER_NOT 0\n#define ITER_PRE 1\n#define ITER_CUR 2\n#define ITER_PAS 3\n\n#define PUSH_ITER(i) do {               \\\n    struct iter _iter;                  \\\n    _iter.prev = ruby_iter;             \\\n    _iter.iter = (i);                   \\\n    ruby_iter = &_iter\n\n#define POP_ITER()                      \\\n    ruby_iter = _iter.prev;             \\\n} while (0)\n\nstruct tag {\n    rb_jmpbuf_t buf;\n    struct FRAME *frame;\n    struct iter *iter;\n    VALUE tag;\n    VALUE retval;\n    struct SCOPE *scope;\n    VALUE dst;\n    struct tag *prev;\n    int blkid;\n};\nstatic struct tag *prot_tag;\n\n#define PUSH_TAG(ptag) do {             \\\n    struct tag _tag;                    \\\n    _tag.retval = Qnil;                 \\\n    _tag.frame = ruby_frame;            \\\n    _tag.iter = ruby_iter;              \\\n    _tag.prev = prot_tag;               \\\n    _tag.scope = ruby_scope;            \\\n    _tag.tag = ptag;                    \\\n    _tag.dst = 0;                       \\\n    _tag.blkid = 0;                     \\\n    prot_tag = &_tag\n\n#define PROT_EMPTY   Qfalse     /* 0 */\n#define PROT_THREAD Qtrue       /* 2 */\n#define PROT_FUNC   INT2FIX(0)  /* 1 */\n#define PROT_LOOP   INT2FIX(1)  /* 3 */\n#define PROT_LAMBDA INT2FIX(2)  /* 5 */\n#define PROT_YIELD  INT2FIX(3)  /* 7 */\n\n#if STACK_WIPE_SITES & 0x42\n#ifdef __GNUC__\nstatic inline int wipeAfter(int) __attribute__((always_inline));\n#endif\nstatic inline int wipeAfter(int status)\n{\n  rb_gc_wipe_stack();\n  return status;\n}\n#else\n#define wipeAfter(status) status\n#endif\n#if STACK_WIPE_SITES & 2\n#define wipeAfterTag(status) wipeAfter(status)\n#else\n#define wipeAfterTag(status) status\n#endif\n\n#define EXEC_TAG_0()  ruby_setjmp(((void)0), prot_tag->buf)\n#define EXEC_TAG()    wipeAfterTag(EXEC_TAG_0())\n\n#define JUMP_TAG(st) do {               \\\n    ruby_frame = prot_tag->frame;       \\\n    ruby_iter = prot_tag->iter;         \\\n    ruby_longjmp(prot_tag->buf,(st));   \\\n} while (0)\n\n#define POP_TAG()                       \\\n    prot_tag = _tag.prev;               \\\n} while (0)\n\n#define TAG_DST() (_tag.dst == (VALUE)ruby_frame->uniq)\n\n#define TAG_RETURN      0x1\n#define TAG_BREAK       0x2\n#define TAG_NEXT        0x3\n#define TAG_RETRY       0x4\n#define TAG_REDO        0x5\n#define TAG_RAISE       0x6\n#define TAG_THROW       0x7\n#define TAG_FATAL       0x8\n#define TAG_MASK        0xf\n\nVALUE ruby_class;\nstatic VALUE ruby_wrapper;      /* security wrapper */\n\n#define PUSH_CLASS(c) do {              \\\n    volatile VALUE _class = ruby_class; \\\n    ruby_class = (c)\n\n#define POP_CLASS() ruby_class = _class; \\\n} while (0)\n\nNODE *ruby_cref = 0;\nNODE *ruby_top_cref;\n#define PUSH_CREF(c) ruby_cref = NEW_CREF(c,ruby_cref)\n#define POP_CREF() ruby_cref = ruby_cref->nd_next\n\n#define PUSH_SCOPE() do {               \\\n    volatile int _vmode = scope_vmode;  \\\n    struct SCOPE * volatile _old;       \\\n    NEWOBJ(_scope, struct SCOPE);       \\\n    OBJSETUP(_scope, 0, T_SCOPE);       \\\n    _scope->local_tbl = 0;              \\\n    _scope->local_vars = 0;             \\\n    _scope->flags = 0;                  \\\n    _old = ruby_scope;                  \\\n    ruby_scope = _scope;                \\\n    scope_vmode = SCOPE_PUBLIC\n\nrb_thread_t rb_curr_thread;\nrb_thread_t rb_main_thread;\n#define main_thread rb_main_thread\n#define curr_thread rb_curr_thread\n\n\n#ifndef STACK_FREE_SAFE_DEBUG\n#define STACK_FREE_SAFE_DEBUG 0\n#endif\n\n#if STACK_FREE_SAFE_DEBUG\n#define stack_free_safe(TH,MSG) _stack_free_safe(TH,MSG)\n#else\n#define stack_free_safe(TH,MSG) _stack_free_safe(TH)\n#endif\n\n\nstatic void stack_free_safe_all_dead_threads();\n\nstatic void scope_dup _((struct SCOPE *));\n\n#define POP_SCOPE()                     \\\n    if (ruby_scope->flags & SCOPE_DONT_RECYCLE) {\\\n        if (_old) scope_dup(_old);      \\\n    }                                   \\\n    if (!(ruby_scope->flags & SCOPE_MALLOC)) {\\\n        ruby_scope->local_vars = 0;     \\\n        ruby_scope->local_tbl  = 0;     \\\n        if (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) && \\\n            ruby_scope != top_scope) {  \\\n            rb_gc_force_recycle((VALUE)ruby_scope);\\\n        }                               \\\n    }                                   \\\n    ruby_scope->flags |= SCOPE_NOSTACK; \\\n    ruby_scope = _old;                  \\\n    scope_vmode = _vmode;               \\\n} while (0)\n\nstatic VALUE rb_eval _((VALUE,NODE*));\nstatic VALUE eval _((VALUE,VALUE,volatile VALUE,const char* volatile,int));\nstatic NODE *compile _((VALUE, const char*, int));\n\nstatic VALUE rb_yield_0\n               _((volatile VALUE, volatile VALUE, VALUE, int, volatile int));\n\n#if STACK_WIPE_SITES & 0x20\n#define wipeBeforeYield()  rb_gc_wipe_stack()\n#else\n#define wipeBeforeYield()  (void)0\n#endif\n\n#define YIELD_LAMBDA_CALL 1\n#define YIELD_PROC_CALL   2\n#define YIELD_PUBLIC_DEF  4\n#define YIELD_FUNC_AVALUE 1\n#define YIELD_FUNC_SVALUE 2\n#define YIELD_FUNC_LAMBDA 3\n\nstatic VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int,VALUE));\nstatic VALUE module_setup _((VALUE,NODE *volatile));\n\nstatic VALUE massign _((VALUE,NODE*,VALUE,int));\nstatic void assign _((VALUE,NODE*,VALUE,int));\n\ntypedef struct event_hook {\n    rb_event_hook_func_t func;\n    rb_event_t events;\n    struct event_hook *next;\n} rb_event_hook_t;\n\nstatic rb_event_hook_t *event_hooks;\n\n#define EXEC_EVENT_HOOK(event, node, self, id, klass) \\\n    do { \\\n        rb_event_hook_t *hook = event_hooks; \\\n        rb_event_hook_func_t hook_func; \\\n        rb_event_t events; \\\n        \\\n        while (hook) { \\\n            hook_func = hook->func; \\\n            events = hook->events; \\\n            hook = hook->next; \\\n            if (events & event) \\\n                (*hook_func)(event, node, self, id, klass); \\\n        } \\\n    } while (0)\n\nstatic VALUE trace_func = 0;\nstatic int tracing = 0;\nstatic void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE));\n\nstatic void\n#ifdef HAVE_STDARG_PROTOTYPES\nwarn_printf(const char *fmt, ...)\n#else\nwarn_printf(fmt, va_alist)\n    const char *fmt;\n    va_dcl\n#endif\n{\n    char buf[BUFSIZ];\n    va_list args;\n\n    va_init_list(args, fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n    rb_write_error(buf);\n}\n\n#define warn_print(x) rb_write_error(x)\n#define warn_print2(x,l) rb_write_error2(x,l)\n\nstatic void\nerror_pos()\n{\n    ruby_set_current_source();\n    if (ruby_sourcefile) {\n        if (ruby_frame->last_func) {\n            warn_printf(\"%s:%d:in `%s'\", ruby_sourcefile, ruby_sourceline,\n                        rb_id2name(ruby_frame->orig_func));\n        }\n        else if (ruby_sourceline == 0) {\n            warn_printf(\"%s\", ruby_sourcefile);\n        }\n        else {\n            warn_printf(\"%s:%d\", ruby_sourcefile, ruby_sourceline);\n        }\n    }\n}\n\nVALUE rb_check_backtrace(VALUE);\n\nstatic VALUE\nget_backtrace(info)\n    VALUE info;\n{\n    if (NIL_P(info)) return Qnil;\n    info = rb_funcall(info, rb_intern(\"backtrace\"), 0);\n    if (NIL_P(info)) return Qnil;\n    return rb_check_backtrace(info);\n}\n\nstatic void\nset_backtrace(info, bt)\n    VALUE info, bt;\n{\n    rb_funcall(info, rb_intern(\"set_backtrace\"), 1, bt);\n}\n\nstatic void\nerror_print()\n{\n    VALUE errat;\n    volatile VALUE eclass, e;\n    const char * einfo;\n    long elen;\n\n    if (NIL_P(ruby_errinfo)) return;\n\n    PUSH_TAG(PROT_EMPTY);\n    errat = EXEC_TAG() ? Qnil : get_backtrace(ruby_errinfo);\n    if (EXEC_TAG()) goto error;\n    if (NIL_P(errat)){\n        ruby_set_current_source();\n        if (ruby_sourcefile)\n            warn_printf(\"%s:%d\", ruby_sourcefile, ruby_sourceline);\n        else\n            warn_printf(\"%d\", ruby_sourceline);\n    }\n    else if (RARRAY(errat)->len == 0) {\n        error_pos();\n    }\n    else {\n        VALUE mesg = RARRAY(errat)->ptr[0];\n\n        if (NIL_P(mesg)) error_pos();\n        else {\n            warn_print2(RSTRING(mesg)->ptr, RSTRING(mesg)->len);\n        }\n    }\n\n    eclass = CLASS_OF(ruby_errinfo);\n    if (EXEC_TAG() == 0) {\n        e = rb_funcall(ruby_errinfo, rb_intern(\"message\"), 0, 0);\n        StringValue(e);\n        einfo = RSTRING(e)->ptr;\n        elen = RSTRING(e)->len;\n    }\n    else {\n        einfo = \"\";\n        elen = 0;\n    }\n    if (EXEC_TAG()) goto error;\n    if (eclass == rb_eRuntimeError && elen == 0) {\n        warn_print(\": unhandled exception\\n\");\n    }\n    else {\n        VALUE epath;\n\n        epath = rb_class_name(eclass);\n        if (elen == 0) {\n            warn_print(\": \");\n            warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);\n            warn_print(\"\\n\");\n        }\n        else {\n            char *tail  = 0;\n            long len = elen;\n\n            if (RSTRING(epath)->ptr[0] == '#') epath = 0;\n            if ((tail = memchr(einfo, '\\n', elen)) != 0) {\n                len = tail - einfo;\n                tail++;         /* skip newline */\n            }\n            warn_print(\": \");\n            warn_print2(einfo, len);\n            if (epath) {\n                warn_print(\" (\");\n                warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);\n                warn_print(\")\\n\");\n            }\n            if (tail && elen>len+1) {\n                warn_print2(tail, elen-len-1);\n                if (einfo[elen-1] != '\\n') warn_print2(\"\\n\", 1);\n            }\n        }\n    }\n\n    if (!NIL_P(errat)) {\n        long i;\n        struct RArray *ep = RARRAY(errat);\n        int truncate = eclass == rb_eSysStackError;\n\n#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)\n#define TRACE_HEAD 8\n#define TRACE_TAIL 5\n\n        ep = RARRAY(errat);\n        for (i=1; i<ep->len; i++) {\n            if (TYPE(ep->ptr[i]) == T_STRING) {\n                warn_printf(\"\\tfrom %s\\n\", RSTRING(ep->ptr[i])->ptr);\n            }\n            if (truncate && i == TRACE_HEAD && ep->len > TRACE_MAX) {\n                warn_printf(\"\\t ... %ld levels...\\n\",\n                        ep->len - TRACE_HEAD - TRACE_TAIL);\n                i = ep->len - TRACE_TAIL;\n            }\n        }\n    }\n  error:\n    POP_TAG();\n}\n\n#if defined(__APPLE__)\n#define environ (*_NSGetEnviron())\n#elif !defined(_WIN32) && !defined(__MACOS__) || defined(_WIN32_WCE)\nextern char **environ;\n#endif\nchar **rb_origenviron;\n\nvoid rb_call_inits _((void));\nvoid Init_stack _((VALUE*));\nvoid Init_heap _((void));\nvoid Init_ext _((void));\n\n#ifdef HAVE_NATIVETHREAD\nstatic rb_nativethread_t ruby_thid;\nint\nis_ruby_native_thread() {\n    return NATIVETHREAD_EQUAL(ruby_thid, NATIVETHREAD_CURRENT());\n}\n\n# ifdef HAVE_NATIVETHREAD_KILL\nvoid\nruby_native_thread_kill(sig)\n    int sig;\n{\n    NATIVETHREAD_KILL(ruby_thid, sig);\n}\n# endif\n#endif\n\nvoid Init_sym _((void));\nvoid Init_source_filenames _((void));\nvoid Init_source_positions _((void));\n\n#ifdef GC_DEBUG\n#define SET_GC_DEBUG_SOURCEFUNC(x) \\\n        ID old_ruby_sourcefunc = ruby_sourcefunc; \\\n    ruby_sourcefunc = rb_intern(x);\n#define RESET_GC_DEBUG_SOURCEFUNC \\\n    ruby_sourcefunc = old_ruby_sourcefunc;\n#else\n#define SET_GC_DEBUG_SOURCEFUNC(x)\n#define RESET_GC_DEBUG_SOURCEFUNC\n#endif\n\nvoid\nruby_init()\n{\n    static int initialized = 0;\n    static struct FRAME frame;\n    static struct iter iter;\n    int state;\n\n    if (initialized)\n        return;\n    initialized = 1;\n#ifdef HAVE_NATIVETHREAD\n    ruby_thid = NATIVETHREAD_CURRENT();\n#endif\n\n    ruby_frame = top_frame = &frame;\n    ruby_iter = &iter;\n\n#ifdef __MACOS__\n    rb_origenviron = 0;\n#else\n    rb_origenviron = environ;\n#endif\n\n    Init_stack((void*)&state);\n    Init_heap();\n    Init_sym();\n    Init_source_filenames();\n    ruby_current_node = 0;\n#ifdef GC_DEBUG\n    if (GC_DEBUG_ON && gc_debug_dump) {\n        Init_source_positions();\n    }\n    SET_GC_DEBUG_SOURCEFUNC(\"<ruby_init>\")\n#endif\n    PUSH_SCOPE();\n    ruby_scope->local_vars = 0;\n    ruby_scope->local_tbl  = 0;\n    top_scope = ruby_scope;\n    /* default visibility is private at toplevel */\n    SCOPE_SET(SCOPE_PRIVATE);\n\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        rb_call_inits();\n        ruby_class = rb_cObject;\n        ruby_frame->self = ruby_top_self;\n        ruby_top_cref = NEW_CREF(rb_cObject, 0);\n        ruby_cref = ruby_top_cref;\n        rb_define_global_const(\"TOPLEVEL_BINDING\", rb_f_binding(ruby_top_self));\n#ifdef __MACOS__\n        _macruby_init();\n#elif defined(__VMS)\n        _vmsruby_init();\n#endif\n        ruby_prog_init();\n        ALLOW_INTS;\n    }\n    POP_TAG();\n    if (state) {\n        error_print();\n        exit(EXIT_FAILURE);\n    }\n    POP_SCOPE();\n    ruby_scope = top_scope;\n    top_scope->flags &= ~SCOPE_NOSTACK;\n    RESET_GC_DEBUG_SOURCEFUNC\n    ruby_running = 1;\n}\n\nstatic VALUE\neval_tree(self, node)\n    VALUE self;\n    NODE *node;\n{\n    NODE *beg_tree = ruby_eval_tree_begin;\n\n    ruby_eval_tree_begin = 0;\n    if (beg_tree) {\n        rb_eval(self, beg_tree);\n    }\n\n    if (!node) return Qnil;\n    return rb_eval(self, node);\n}\n\nint ruby_in_eval;\n\nstatic void rb_thread_cleanup _((void));\nstatic void rb_thread_wait_other_threads _((void));\n\nstatic int thread_no_ensure _((void));\n\nstatic VALUE exception_error;\nstatic VALUE sysstack_error;\n\nstatic int\nsysexit_status(err)\n    VALUE err;\n{\n    VALUE st = rb_iv_get(err, \"status\");\n    return NUM2INT(st);\n}\n\nstatic int\nerror_handle(ex)\n    int ex;\n{\n    int status = EXIT_FAILURE;\n    rb_thread_t th = curr_thread;\n\n    if (rb_thread_set_raised(th))\n        return EXIT_FAILURE;\n    switch (ex & TAG_MASK) {\n      case 0:\n        status = EXIT_SUCCESS;\n        break;\n\n      case TAG_RETURN:\n        error_pos();\n        warn_print(\": unexpected return\\n\");\n        break;\n      case TAG_NEXT:\n        error_pos();\n        warn_print(\": unexpected next\\n\");\n        break;\n      case TAG_BREAK:\n        error_pos();\n        warn_print(\": unexpected break\\n\");\n        break;\n      case TAG_REDO:\n        error_pos();\n        warn_print(\": unexpected redo\\n\");\n        break;\n      case TAG_RETRY:\n        error_pos();\n        warn_print(\": retry outside of rescue clause\\n\");\n        break;\n      case TAG_THROW:\n        if (prot_tag && prot_tag->frame && prot_tag->frame->node) {\n            NODE *tag = prot_tag->frame->node;\n            warn_printf(\"%s:%d: uncaught throw\\n\",\n                    tag->nd_file, nd_line(tag));\n        }\n        else {\n            error_pos();\n            warn_printf(\": unexpected throw\\n\");\n        }\n        break;\n      case TAG_RAISE:\n      case TAG_FATAL:\n        if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {\n            status = sysexit_status(ruby_errinfo);\n        }\n        else if (rb_obj_is_instance_of(ruby_errinfo, rb_eSignal)) {\n            /* no message when exiting by signal */\n        }\n        else {\n            error_print();\n        }\n        break;\n      default:\n        rb_bug(\"Unknown longjmp status %d\", ex);\n        break;\n    }\n    rb_thread_reset_raised(th);\n    return status;\n}\n\nvoid\nruby_options(argc, argv)\n    int argc;\n    char **argv;\n{\n    int state;\n    ruby_current_node = 0;\n    SET_GC_DEBUG_SOURCEFUNC(\"<ruby_options>\")\n    Init_stack((void*)&state);\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        ruby_process_options(argc, argv);\n    }\n    else {\n        trace_func = 0;\n        tracing = 0;\n        exit(error_handle(state));\n    }\n    POP_TAG();\n    RESET_GC_DEBUG_SOURCEFUNC\n}\n\nvoid rb_exec_end_proc _((void));\n\nstatic void\nruby_finalize_0()\n{\n    PUSH_TAG(PROT_EMPTY);\n    if (EXEC_TAG() == 0) {\n        rb_trap_exit();\n    }\n    POP_TAG();\n    rb_exec_end_proc();\n}\n\nstatic void\nruby_finalize_1()\n{\n    signal(SIGINT, SIG_DFL);\n    ruby_errinfo = 0;\n    rb_gc_call_finalizer_at_exit();\n    trace_func = 0;\n    tracing = 0;\n}\n\nvoid\nruby_finalize()\n{\n    ruby_finalize_0();\n    ruby_finalize_1();\n}\n\nint\nruby_cleanup(exArg)\n    int exArg;\n{\n    int state;\n    volatile VALUE errs[2];\n    unsigned nerr;\n    volatile int ex = exArg;\n\n    errs[1] = ruby_errinfo;\n    ruby_safe_level = 0;\n    Init_stack((void *)&state);\n    SET_GC_DEBUG_SOURCEFUNC(\"<ruby_cleanup>\")\n    ruby_finalize_0();\n    errs[0] = ruby_errinfo;\n    PUSH_TAG(PROT_EMPTY);\n    PUSH_ITER(ITER_NOT);\n    if ((state = EXEC_TAG()) == 0) {\n        rb_thread_cleanup();\n        rb_thread_wait_other_threads();\n    }\n    else if (ex == 0) {\n        ex = state;\n    }\n    POP_ITER();\n    ruby_errinfo = errs[1];\n    ex = error_handle(ex);\n    ruby_finalize_1();\n    POP_TAG();\n    RESET_GC_DEBUG_SOURCEFUNC\n\n    for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) {\n        VALUE err = errs[nerr];\n\n        if (!RTEST(err)) continue;\n\n        if (rb_obj_is_kind_of(err, rb_eSystemExit)) {\n            return sysexit_status(err);\n        }\n        else if (rb_obj_is_kind_of(err, rb_eSignal)) {\n            VALUE sig = rb_iv_get(err, \"signo\");\n            ruby_default_signal(NUM2INT(sig));\n        }\n        else if (ex == 0) {\n            ex = 1;\n        }\n    }\n\n#if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1\n    switch (ex) {\n#if EXIT_SUCCESS != 0\n      case 0: return EXIT_SUCCESS;\n#endif\n#if EXIT_FAILURE != 1\n      case 1: return EXIT_FAILURE;\n#endif\n    }\n#endif\n\n    return ex;\n}\n\nstatic int\nruby_exec_internal()\n{\n    int state;\n\n    SET_GC_DEBUG_SOURCEFUNC(\"<ruby_exec_internal>\");\n    PUSH_TAG(PROT_EMPTY);\n    PUSH_ITER(ITER_NOT);\n    /* default visibility is private at toplevel */\n    SCOPE_SET(SCOPE_PRIVATE);\n    if ((state = EXEC_TAG()) == 0) {\n        eval_tree(ruby_top_self, ruby_eval_tree);\n    }\n    POP_ITER();\n    POP_TAG();\n    RESET_GC_DEBUG_SOURCEFUNC\n    return state;\n}\n\nvoid\nruby_stop(ex)\n    int ex;\n{\n    exit(ruby_cleanup(ex));\n}\n\nint\nruby_exec()\n{\n    volatile NODE *tmp;\n\n    Init_stack((void*)&tmp);\n    return ruby_exec_internal();\n}\n\nvoid\nruby_run()\n{\n    int state;\n    static int ex;\n\n    if (ruby_nerrs > 0) exit(EXIT_FAILURE);\n    state = ruby_exec();\n    if (state && !ex) ex = state;\n    ruby_stop(ex);\n}\n\nstatic void\ncompile_error(at)\n    const char *at;\n{\n    VALUE str;\n\n    ruby_nerrs = 0;\n    str = rb_str_buf_new2(\"compile error\");\n    if (at) {\n        rb_str_buf_cat2(str, \" in \");\n        rb_str_buf_cat2(str, at);\n    }\n    rb_str_buf_cat(str, \"\\n\", 1);\n    if (!NIL_P(ruby_errinfo)) {\n        rb_str_append(str, rb_obj_as_string(ruby_errinfo));\n    }\n    rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));\n}\n\nVALUE\nrb_eval_string(str)\n    const char *str;\n{\n    VALUE v;\n    NODE *oldsrc = ruby_current_node;\n\n    ruby_current_node = 0;\n    ruby_sourcefile = rb_source_filename(\"(eval)\");\n    SET_GC_DEBUG_SOURCEFUNC(\"<rb_eval_string>\")\n    v = eval(ruby_top_self, rb_str_new2(str), Qnil, 0, 0);\n    ruby_current_node = oldsrc;\n    RESET_GC_DEBUG_SOURCEFUNC\n    return v;\n}\n\nVALUE\nrb_eval_string_protect(str, state)\n    const char *str;\n    int *state;\n{\n    return rb_protect((VALUE (*)_((VALUE)))rb_eval_string, (VALUE)str, state);\n}\n\nVALUE\nrb_eval_string_wrap(str, state)\n    const char *str;\n    int *state;\n{\n    int status;\n    VALUE self = ruby_top_self;\n    VALUE wrapper = ruby_wrapper;\n    VALUE val;\n\n    PUSH_CLASS(ruby_wrapper = rb_module_new());\n    ruby_top_self = rb_obj_clone(ruby_top_self);\n    rb_extend_object(ruby_top_self, ruby_wrapper);\n    PUSH_FRAME();\n    ruby_frame->last_func = 0;\n    ruby_frame->last_class = 0;\n    ruby_frame->self = self;\n    PUSH_CREF(ruby_wrapper);\n    PUSH_SCOPE();\n\n    val = rb_eval_string_protect(str, &status);\n    ruby_top_self = self;\n\n    POP_SCOPE();\n    POP_FRAME();\n    POP_CLASS();\n    ruby_wrapper = wrapper;\n    if (state) {\n        *state = status;\n    }\n    else if (status) {\n        JUMP_TAG(status);\n    }\n    return val;\n}\n\nNORETURN(static void localjump_error(const char*, VALUE, int));\nstatic void\nlocaljump_error(mesg, value, reason)\n    const char *mesg;\n    VALUE value;\n    int reason;\n{\n    VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);\n    ID id;\n\n    rb_iv_set(exc, \"@exit_value\", value);\n    switch (reason) {\n      case TAG_BREAK:\n        id = rb_intern(\"break\"); break;\n      case TAG_REDO:\n        id = rb_intern(\"redo\"); break;\n      case TAG_RETRY:\n        id = rb_intern(\"retry\"); break;\n      case TAG_NEXT:\n        id = rb_intern(\"next\"); break;\n      case TAG_RETURN:\n        id = rb_intern(\"return\"); break;\n      default:\n        id = rb_intern(\"noreason\"); break;\n    }\n    rb_iv_set(exc, \"@reason\", ID2SYM(id));\n    rb_exc_raise(exc);\n}\n\n/*\n * call_seq:\n *   local_jump_error.exit_value  => obj\n *\n * Returns the exit value associated with this +LocalJumpError+.\n */\nstatic VALUE\nlocaljump_xvalue(exc)\n    VALUE exc;\n{\n    return rb_iv_get(exc, \"@exit_value\");\n}\n\n/*\n * call-seq:\n *    local_jump_error.reason   => symbol\n *\n * The reason this block was terminated:\n * :break, :redo, :retry, :next, :return, or :noreason.\n */\n\nstatic VALUE\nlocaljump_reason(exc)\n    VALUE exc;\n{\n    return rb_iv_get(exc, \"@reason\");\n}\n\nNORETURN(static void jump_tag_but_local_jump _((int,VALUE)));\nstatic void\njump_tag_but_local_jump(state, val)\n    int state;\n    VALUE val;\n{\n\n    if (val == Qundef) val = prot_tag->retval;\n    switch (state) {\n      case 0:\n        break;\n      case TAG_RETURN:\n        localjump_error(\"unexpected return\", val, state);\n        break;\n      case TAG_BREAK:\n        localjump_error(\"unexpected break\", val, state);\n        break;\n      case TAG_NEXT:\n        localjump_error(\"unexpected next\", val, state);\n        break;\n      case TAG_REDO:\n        localjump_error(\"unexpected redo\", Qnil, state);\n        break;\n      case TAG_RETRY:\n        localjump_error(\"retry outside of rescue clause\", Qnil, state);\n        break;\n      default:\n        break;\n    }\n    JUMP_TAG(state);\n}\n\nVALUE\nrb_eval_cmd(cmd, arg, level)\n    VALUE cmd, arg;\n    int level;\n{\n    int state;\n    VALUE val;\n    struct SCOPE * volatile saved_scope;\n    volatile int safe = ruby_safe_level;\n\n    if (OBJ_TAINTED(cmd)) {\n        level = 4;\n    }\n    if (TYPE(cmd) != T_STRING) {\n        PUSH_ITER(ITER_NOT);\n        PUSH_TAG(PROT_EMPTY);\n        ruby_safe_level = level;\n        if ((state = EXEC_TAG()) == 0) {\n            val = rb_funcall2(cmd, rb_intern(\"call\"), RARRAY(arg)->len, RARRAY(arg)->ptr);\n        }\n        ruby_safe_level = safe;\n        POP_TAG();\n        POP_ITER();\n        if (state) JUMP_TAG(state);\n        return val;\n    }\n\n    saved_scope = ruby_scope;\n    ruby_scope = top_scope;\n    PUSH_FRAME();\n    ruby_frame->last_func = 0;\n    ruby_frame->last_class = 0;\n    ruby_frame->self = ruby_top_self;\n    PUSH_CREF(ruby_wrapper ? ruby_wrapper : rb_cObject);\n\n    ruby_safe_level = level;\n\n    PUSH_TAG(PROT_EMPTY);\n    val = (state = EXEC_TAG()) ? Qnil : eval(ruby_top_self, cmd, Qnil, 0, 0);\n    if (ruby_scope->flags & SCOPE_DONT_RECYCLE)\n        scope_dup(saved_scope);\n    ruby_scope = saved_scope;\n    ruby_safe_level = safe;\n    POP_TAG();\n    POP_FRAME();\n\n    if (state) jump_tag_but_local_jump(state, val);\n    return val;\n}\n\n#define ruby_cbase (ruby_cref->nd_clss)\n\nstatic VALUE\nev_const_defined(cref, id, self)\n    NODE *cref;\n    ID id;\n    VALUE self;\n{\n    NODE *cbase = cref;\n    VALUE result;\n\n    while (cbase && cbase->nd_next) {\n        struct RClass *klass = RCLASS(cbase->nd_clss);\n\n        if (!NIL_P(klass)) {\n            if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) {\n                if (result == Qundef && NIL_P(rb_autoload_p((VALUE)klass, id))) {\n                    return Qfalse;\n                }\n                return Qtrue;\n            }\n        }\n        cbase = cbase->nd_next;\n    }\n    return rb_const_defined(cref->nd_clss, id);\n}\n\nNOINLINE(static VALUE ev_const_get _((NODE *cref, ID id, VALUE self)));\nNOINLINE(static void eval_cvar_set _((NODE *node, VALUE result, int warn)));\nNOINLINE(static void eval_cdecl _((VALUE self, NODE *node, VALUE value)));\n\nstatic VALUE\nev_const_get(cref, id, self)\n    NODE *cref;\n    ID id;\n    VALUE self;\n{\n    NODE *cbase = cref;\n    VALUE result;\n\n    while (cbase && cbase->nd_next) {\n        VALUE klass = cbase->nd_clss;\n\n        if (!NIL_P(klass)) {\n            while (RCLASS(klass)->iv_tbl &&\n                   st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {\n                if (result == Qundef) {\n                    if (!RTEST(rb_autoload_load(klass, id))) break;\n                    continue;\n                }\n                return result;\n            }\n        }\n        cbase = cbase->nd_next;\n    }\n    return rb_const_get(NIL_P(cref->nd_clss) ? CLASS_OF(self): cref->nd_clss, id);\n}\n\nstatic VALUE\ncvar_cbase()\n{\n    NODE *cref = ruby_cref;\n\n    while (cref && cref->nd_next && (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) {\n        cref = cref->nd_next;\n        if (!cref->nd_next) {\n            rb_warn(\"class variable access from toplevel singleton method\");\n        }\n    }\n    if (NIL_P(cref->nd_clss)) {\n        rb_raise(rb_eTypeError, \"no class variables available\");\n    }\n    return cref->nd_clss;\n}\n\n/*\n *  call-seq:\n *     Module.nesting    => array\n *\n *  Returns the list of +Modules+ nested at the point of call.\n *\n *     module M1\n *       module M2\n *         $a = Module.nesting\n *       end\n *     end\n *     $a           #=> [M1::M2, M1]\n *     $a[0].name   #=> \"M1::M2\"\n */\n\nstatic VALUE\nrb_mod_nesting()\n{\n    NODE *cbase = ruby_cref;\n    VALUE ary = rb_ary_new();\n\n    while (cbase && cbase->nd_next) {\n        if (!NIL_P(cbase->nd_clss)) rb_ary_push(ary, cbase->nd_clss);\n        cbase = cbase->nd_next;\n    }\n    if (ruby_wrapper && RARRAY(ary)->len == 0) {\n        rb_ary_push(ary, ruby_wrapper);\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     Module.constants   => array\n *\n *  Returns an array of the names of all constants defined in the\n *  system. This list includes the names of all modules and classes.\n *\n *     p Module.constants.sort[1..5]\n *\n *  <em>produces:</em>\n *\n *     [\"ARGV\", \"ArgumentError\", \"Array\", \"Bignum\", \"Binding\"]\n */\n\nstatic VALUE\nrb_mod_s_constants()\n{\n    NODE *cbase = ruby_cref;\n    void *data = 0;\n\n    while (cbase) {\n        if (!NIL_P(cbase->nd_clss)) {\n            data = rb_mod_const_at(cbase->nd_clss, data);\n        }\n        cbase = cbase->nd_next;\n    }\n\n    if (!NIL_P(ruby_cbase)) {\n        data = rb_mod_const_of(ruby_cbase, data);\n    }\n    return rb_const_list(data);\n}\n\nvoid\nrb_frozen_class_p(klass)\n    VALUE klass;\n{\n    const char *desc = \"something(?!)\";\n\n    if (OBJ_FROZEN(klass)) {\n        if (FL_TEST(klass, FL_SINGLETON))\n            desc = \"object\";\n        else {\n            switch (TYPE(klass)) {\n              case T_MODULE:\n              case T_ICLASS:\n                desc = \"module\"; break;\n              case T_CLASS:\n                desc = \"class\"; break;\n            }\n        }\n        rb_error_frozen(desc);\n    }\n}\n\nvoid\nrb_undef(klass, id)\n    VALUE klass;\n    ID id;\n{\n    VALUE origin;\n    NODE *body;\n\n    if (ruby_cbase == rb_cObject && klass == rb_cObject) {\n        rb_secure(4);\n    }\n    if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {\n        rb_raise(rb_eSecurityError, \"Insecure: can't undef `%s'\", rb_id2name(id));\n    }\n    rb_frozen_class_p(klass);\n    if (id == __id__ || id == __send__ || id == init) {\n        rb_warn(\"undefining `%s' may cause serious problem\", rb_id2name(id));\n    }\n    body = search_method(klass, id, &origin);\n    if (!body || !body->nd_body) {\n        const char *s0 = \" class\";\n        VALUE c = klass;\n\n        if (FL_TEST(c, FL_SINGLETON)) {\n            VALUE obj = rb_iv_get(klass, \"__attached__\");\n\n            switch (TYPE(obj)) {\n              case T_MODULE:\n              case T_CLASS:\n                c = obj;\n                s0 = \"\";\n            }\n        }\n        else if (TYPE(c) == T_MODULE) {\n            s0 = \" module\";\n        }\n        rb_name_error(id, \"undefined method `%s' for%s `%s'\",\n                      rb_id2name(id),s0,rb_class2name(c));\n    }\n    rb_add_method(klass, id, 0, NOEX_PUBLIC);\n    if (FL_TEST(klass, FL_SINGLETON)) {\n        rb_funcall(rb_iv_get(klass, \"__attached__\"),\n                   singleton_undefined, 1, ID2SYM(id));\n    }\n    else {\n        rb_funcall(klass, undefined, 1, ID2SYM(id));\n    }\n}\n\n/*\n *  call-seq:\n *     undef_method(symbol)    => self\n *\n *  Prevents the current class from responding to calls to the named\n *  method. Contrast this with <code>remove_method</code>, which deletes\n *  the method from the particular class; Ruby will still search\n *  superclasses and mixed-in modules for a possible receiver.\n *\n *     class Parent\n *       def hello\n *         puts \"In parent\"\n *       end\n *     end\n *     class Child < Parent\n *       def hello\n *         puts \"In child\"\n *       end\n *     end\n *\n *\n *     c = Child.new\n *     c.hello\n *\n *\n *     class Child\n *       remove_method :hello  # remove from child, still in parent\n *     end\n *     c.hello\n *\n *\n *     class Child\n *       undef_method :hello   # prevent any calls to 'hello'\n *     end\n *     c.hello\n *\n *  <em>produces:</em>\n *\n *     In child\n *     In parent\n *     prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)\n */\n\nstatic VALUE\nrb_mod_undef_method(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_undef(mod, rb_to_id(argv[i]));\n    }\n    return mod;\n}\n\nvoid\nrb_alias(klass, name, def)\n    VALUE klass;\n    ID name, def;\n{\n    VALUE origin = 0;\n    NODE *orig, *body, *node;\n    VALUE singleton = 0;\n    st_data_t data;\n\n    rb_frozen_class_p(klass);\n    if (name == def) return;\n    if (klass == rb_cObject) {\n        rb_secure(4);\n    }\n    orig = search_method(klass, def, &origin);\n    if (!orig || !orig->nd_body) {\n        if (TYPE(klass) == T_MODULE) {\n            orig = search_method(rb_cObject, def, &origin);\n        }\n    }\n    if (!orig || !orig->nd_body) {\n        print_undef(klass, def);\n    }\n    if (FL_TEST(klass, FL_SINGLETON)) {\n        singleton = rb_iv_get(klass, \"__attached__\");\n    }\n    body = orig->nd_body;\n    orig->nd_cnt++;\n    if (nd_type(body) == NODE_FBODY) { /* was alias */\n        def = body->nd_mid;\n        origin = body->nd_orig;\n        body = body->nd_head;\n    }\n\n    rb_clear_cache_by_id(name);\n    if (RTEST(ruby_verbose) && st_lookup(RCLASS(klass)->m_tbl, name, &data)) {\n        node = (NODE *)data;\n        if (node->nd_cnt == 0 && node->nd_body) {\n            rb_warning(\"discarding old %s\", rb_id2name(name));\n        }\n    }\n    st_insert(RCLASS(klass)->m_tbl, name,\n              (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin),\n                                    NOEX_WITH_SAFE(orig->nd_noex)));\n\n    if (!ruby_running) return;\n\n    if (singleton) {\n        rb_funcall(singleton, singleton_added, 1, ID2SYM(name));\n    }\n    else {\n        rb_funcall(klass, added, 1, ID2SYM(name));\n    }\n}\n\n/*\n *  call-seq:\n *     alias_method(new_name, old_name)   => self\n *\n *  Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can\n *  be used to retain access to methods that are overridden.\n *\n *     module Mod\n *       alias_method :orig_exit, :exit\n *       def exit(code=0)\n *         puts \"Exiting with code #{code}\"\n *         orig_exit(code)\n *       end\n *     end\n *     include Mod\n *     exit(99)\n *\n *  <em>produces:</em>\n *\n *     Exiting with code 99\n */\n\nstatic VALUE\nrb_mod_alias_method(mod, newname, oldname)\n    VALUE mod, newname, oldname;\n{\n    rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));\n    return mod;\n}\n\nNODE *\nrb_copy_node_scope(node, rval)\n    NODE *node;\n    NODE *rval;\n{\n    NODE *copy;\n\n    GC_DEBUG_SET_SOURCE\n    copy=NEW_NODE(NODE_SCOPE,0,rval,node->nd_next);\n\n    if (node->nd_tbl) {\n        copy->nd_tbl = ALLOC_N(ID, node->nd_tbl[0]+1);\n        MEMCPY(copy->nd_tbl, node->nd_tbl, ID, node->nd_tbl[0]+1);\n    }\n    else {\n        copy->nd_tbl = 0;\n    }\n    return copy;\n}\n\n#ifdef C_ALLOCA\n# define TMP_PROTECT NODE * volatile tmp__protect_tmp=0\n# define TMP_ALLOC(n)                                                   \\\n    (tmp__protect_tmp = NEW_NODE(NODE_ALLOCA,                           \\\n                                 ALLOC_N(VALUE,n),tmp__protect_tmp,n),  \\\n     (void*)tmp__protect_tmp->nd_head)\n#else\n# define TMP_PROTECT typedef int foobazzz\n# define TMP_ALLOC(n) ALLOCA_N(VALUE,n)\n#endif\n\n#define SETUP_ARGS0(anode,extra) do {\\\n    NODE *n = anode;\\\n    if (!n) {\\\n        argc = 0;\\\n        argv = 0;\\\n    }\\\n    else if (nd_type(n) == NODE_ARRAY) {\\\n        argc=anode->nd_alen;\\\n        if (argc > 0) {\\\n            int i;\\\n            n = anode;\\\n            argv = TMP_ALLOC(argc+extra);\\\n            for (i=0;i<argc;i++) {\\\n                argv[i] = rb_eval(self,n->nd_head);\\\n                n=n->nd_next;\\\n            }\\\n        }\\\n        else {\\\n            argc = 0;\\\n            argv = 0;\\\n        }\\\n    }\\\n    else {\\\n        VALUE args = rb_eval(self,n);\\\n        if (TYPE(args) != T_ARRAY)\\\n            args = rb_ary_to_ary(args);\\\n        argc = RARRAY(args)->len;\\\n        argv = TMP_ALLOC(argc+extra);\\\n        MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\\\n    }\\\n} while (0)\n\n#define SETUP_ARGS(anode) SETUP_ARGS0(anode,0)\n\n#define BEGIN_CALLARGS do {\\\n    struct BLOCK *tmp_block = ruby_block;\\\n    int tmp_iter = ruby_iter->iter;\\\n    switch (tmp_iter) {\\\n      case ITER_PRE:\\\n        if (ruby_block) ruby_block = ruby_block->outer;\\\n      case ITER_PAS:\\\n        tmp_iter = ITER_NOT;\\\n    }\\\n    PUSH_ITER(tmp_iter)\n\n#define END_CALLARGS \\\n    ruby_block = tmp_block;\\\n    POP_ITER();\\\n} while (0)\n\n#define MATCH_DATA *rb_svar(node->nd_cnt)\n\nstatic const char* is_defined _((VALUE, NODE*, char*));\n\nstatic const char*\narg_defined(self, node, buf, type)\n    VALUE self;\n    NODE *node;\n    char *buf;\n    char *type;\n{\n    int argc;\n    int i;\n\n    if (!node) return type;     /* no args */\n    if (nd_type(node) == NODE_ARRAY) {\n        argc=node->nd_alen;\n        if (argc > 0) {\n            for (i=0;i<argc;i++) {\n                if (!is_defined(self, node->nd_head, buf))\n                    return 0;\n                node = node->nd_next;\n            }\n        }\n    }\n    else if (!is_defined(self, node, buf)) {\n        return 0;\n    }\n    return type;\n}\n\nstatic const char*\nis_defined(self, node, buf)\n    VALUE self;\n    NODE *node;\n    char *buf;\n{\n    VALUE val;\n    int state;\n\n  again:\n    if (!node) return \"expression\";\n    switch (nd_type(node)) {\n      case NODE_SUPER:\n      case NODE_ZSUPER:\n        if (ruby_frame->last_func == 0) return 0;\n        else if (ruby_frame->last_class == 0) return 0;\n        val = ruby_frame->last_class;\n        if (rb_method_boundp(RCLASS(val)->super, ruby_frame->orig_func, 0)) {\n            if (nd_type(node) == NODE_SUPER) {\n                return arg_defined(self, node->nd_args, buf, \"super\");\n            }\n            return \"super\";\n        }\n        break;\n\n      case NODE_VCALL:\n      case NODE_FCALL:\n        val = self;\n        goto check_bound;\n\n      case NODE_ATTRASGN:\n        val = self;\n        if (node->nd_recv == (NODE *)1) goto check_bound;\n      case NODE_CALL:\n        PUSH_TAG(PROT_EMPTY);\n        if ((state = EXEC_TAG()) == 0) {\n            val = rb_eval(self, node->nd_recv);\n        }\n        POP_TAG();\n        if (state) {\n            ruby_errinfo = Qnil;\n            return 0;\n        }\n      check_bound:\n        {\n            int call = nd_type(node)==NODE_CALL;\n\n            val = CLASS_OF(val);\n            if (call) {\n                int noex;\n                ID id = node->nd_mid;\n\n                if (!rb_get_method_body(&val, &id, &noex))\n                    break;\n                if ((noex & NOEX_PRIVATE))\n                    break;\n                if ((noex & NOEX_PROTECTED) &&\n                    !rb_obj_is_kind_of(self, rb_class_real(val)))\n                    break;\n            }\n            else if (!rb_method_boundp(val, node->nd_mid, call))\n                break;\n            return arg_defined(self, node->nd_args, buf,\n                               nd_type(node) == NODE_ATTRASGN ?\n                               \"assignment\" : \"method\");\n        }\n        break;\n\n      case NODE_MATCH2:\n      case NODE_MATCH3:\n        return \"method\";\n\n      case NODE_YIELD:\n        if (rb_block_given_p()) {\n            return \"yield\";\n        }\n        break;\n\n      case NODE_SELF:\n        return \"self\";\n\n      case NODE_NIL:\n        return \"nil\";\n\n      case NODE_TRUE:\n        return \"true\";\n\n      case NODE_FALSE:\n        return \"false\";\n\n      case NODE_ATTRSET:\n      case NODE_OP_ASGN1:\n      case NODE_OP_ASGN2:\n      case NODE_OP_ASGN_OR:\n      case NODE_OP_ASGN_AND:\n      case NODE_MASGN:\n      case NODE_LASGN:\n      case NODE_DASGN:\n      case NODE_DASGN_CURR:\n      case NODE_GASGN:\n      case NODE_IASGN:\n      case NODE_CDECL:\n      case NODE_CVDECL:\n      case NODE_CVASGN:\n        return \"assignment\";\n\n      case NODE_LVAR:\n        return \"local-variable\";\n      case NODE_DVAR:\n        return \"local-variable(in-block)\";\n\n      case NODE_GVAR:\n        if (rb_gvar_defined(node->nd_entry)) {\n            return \"global-variable\";\n        }\n        break;\n\n      case NODE_IVAR:\n        if (rb_ivar_defined(self, node->nd_vid)) {\n            return \"instance-variable\";\n        }\n        break;\n\n      case NODE_CONST:\n        if (ev_const_defined(ruby_cref, node->nd_vid, self)) {\n            return \"constant\";\n        }\n        break;\n\n      case NODE_CVAR:\n        if (rb_cvar_defined(cvar_cbase(), node->nd_vid)) {\n            return \"class variable\";\n        }\n        break;\n\n      case NODE_COLON2:\n        PUSH_TAG(PROT_EMPTY);\n        if ((state = EXEC_TAG()) == 0) {\n            val = rb_eval(self, node->nd_head);\n        }\n        POP_TAG();\n        if (state) {\n            ruby_errinfo = Qnil;\n            return 0;\n        }\n        else {\n            switch (TYPE(val)) {\n              case T_CLASS:\n              case T_MODULE:\n                if (rb_const_defined_from(val, node->nd_mid))\n                    return \"constant\";\n                break;\n              default:\n                if (rb_method_boundp(CLASS_OF(val), node->nd_mid, 1)) {\n                    return \"method\";\n                }\n            }\n        }\n        break;\n\n      case NODE_COLON3:\n        if (rb_const_defined_from(rb_cObject, node->nd_mid)) {\n            return \"constant\";\n        }\n        break;\n\n      case NODE_NTH_REF:\n        if (RTEST(rb_reg_nth_defined(node->nd_nth, MATCH_DATA))) {\n            sprintf(buf, \"$%d\", (int)node->nd_nth);\n            return buf;\n        }\n        break;\n\n      case NODE_BACK_REF:\n        if (RTEST(rb_reg_nth_defined(0, MATCH_DATA))) {\n            sprintf(buf, \"$%c\", (char)node->nd_nth);\n            return buf;\n        }\n        break;\n\n      case NODE_NEWLINE:\n        node = node->nd_next;\n        goto again;\n\n      default:\n        PUSH_TAG(PROT_EMPTY);\n        if ((state = EXEC_TAG()) == 0) {\n            rb_eval(self, node);\n        }\n        POP_TAG();\n        if (!state) {\n            return \"expression\";\n        }\n        ruby_errinfo = Qnil;\n        break;\n    }\n    return 0;\n}\n\nstatic int handle_rescue _((VALUE,NODE*));\n\nstatic void blk_free();\n\nstatic VALUE\nrb_obj_is_proc(proc)\n    VALUE proc;\n{\n    if (TYPE(proc) == T_DATA && RDATA(proc)->dfree == (RUBY_DATA_FUNC)blk_free) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\nvoid\nrb_add_event_hook(func, events)\n    rb_event_hook_func_t func;\n    rb_event_t events;\n{\n    rb_event_hook_t *hook;\n\n    hook = ALLOC(rb_event_hook_t);\n    hook->func = func;\n    hook->events = events;\n    hook->next = event_hooks;\n    event_hooks = hook;\n}\n\nint\nrb_remove_event_hook(func)\n    rb_event_hook_func_t func;\n{\n    rb_event_hook_t *prev, *hook;\n\n    prev = NULL;\n    hook = event_hooks;\n    while (hook) {\n        if (hook->func == func) {\n            if (prev) {\n                prev->next = hook->next;\n            }\n            else {\n                event_hooks = hook->next;\n            }\n            xfree(hook);\n            return 0;\n        }\n        prev = hook;\n        hook = hook->next;\n    }\n    return -1;\n}\n\n/*\n *  call-seq:\n *     set_trace_func(proc)    => proc\n *     set_trace_func(nil)     => nil\n *\n *  Establishes _proc_ as the handler for tracing, or disables\n *  tracing if the parameter is +nil+. _proc_ takes up\n *  to six parameters: an event name, a filename, a line number, an\n *  object id, a binding, and the name of a class. _proc_ is\n *  invoked whenever an event occurs. Events are: <code>c-call</code>\n *  (call a C-language routine), <code>c-return</code> (return from a\n *  C-language routine), <code>call</code> (call a Ruby method),\n *  <code>class</code> (start a class or module definition),\n *  <code>end</code> (finish a class or module definition),\n *  <code>line</code> (execute code on a new line), <code>raise</code>\n *  (raise an exception), and <code>return</code> (return from a Ruby\n *  method). Tracing is disabled within the context of _proc_.\n *\n *      class Test\n *      def test\n *        a = 1\n *        b = 2\n *      end\n *      end\n *\n *      set_trace_func proc { |event, file, line, id, binding, classname|\n *         printf \"%8s %s:%-2d %10s %8s\\n\", event, file, line, id, classname\n *      }\n *      t = Test.new\n *      t.test\n *\n *        line prog.rb:11               false\n *      c-call prog.rb:11        new    Class\n *      c-call prog.rb:11 initialize   Object\n *    c-return prog.rb:11 initialize   Object\n *    c-return prog.rb:11        new    Class\n *        line prog.rb:12               false\n *        call prog.rb:2        test     Test\n *        line prog.rb:3        test     Test\n *        line prog.rb:4        test     Test\n *      return prog.rb:4        test     Test\n */\n\n\nstatic VALUE\nset_trace_func(obj, trace)\n    VALUE obj, trace;\n{\n    rb_event_hook_t *hook;\n\n    rb_secure(4);\n    if (NIL_P(trace)) {\n        trace_func = 0;\n        rb_remove_event_hook(call_trace_func);\n        return Qnil;\n    }\n    if (!rb_obj_is_proc(trace)) {\n        rb_raise(rb_eTypeError, \"trace_func needs to be Proc\");\n    }\n    trace_func = trace;\n    for (hook = event_hooks; hook; hook = hook->next) {\n        if (hook->func == call_trace_func)\n            return trace;\n    }\n    rb_add_event_hook(call_trace_func, RUBY_EVENT_ALL);\n    return trace;\n}\n\nstatic const char *\nget_event_name(rb_event_t event)\n{\n    switch (event) {\n      case RUBY_EVENT_LINE:\n        return \"line\";\n      case RUBY_EVENT_CLASS:\n        return \"class\";\n      case RUBY_EVENT_END:\n        return \"end\";\n      case RUBY_EVENT_CALL:\n        return \"call\";\n      case RUBY_EVENT_RETURN:\n        return \"return\";\n      case RUBY_EVENT_C_CALL:\n        return \"c-call\";\n      case RUBY_EVENT_C_RETURN:\n        return \"c-return\";\n      case RUBY_EVENT_RAISE:\n        return \"raise\";\n      default:\n        return \"unknown\";\n    }\n}\n\nstatic void\ncall_trace_func(event, node, self, id, klass)\n    rb_event_t event;\n    NODE *node;\n    VALUE self;\n    ID id;\n    VALUE klass;\n{\n    int state;\n    volatile int raised;\n    struct FRAME *prev;\n    NODE * volatile node_save;\n    VALUE srcfile;\n    const char *event_name;\n    volatile rb_thread_t th = curr_thread;\n\n    if (!trace_func) return;\n    if (tracing) return;\n    if (ruby_in_compile) return;\n    if (id == ID_ALLOCATOR) return;\n\n    if (!(node_save = ruby_current_node)) {\n        node_save = NEW_NEWLINE(0);\n    }\n    tracing = 1;\n    prev = ruby_frame;\n    PUSH_FRAME();\n    *ruby_frame = *prev;\n    ruby_frame->prev = prev;\n    ruby_frame->iter = 0;       /* blocks not available anyway */\n\n    if (node) {\n        ruby_current_node = node;\n        ruby_frame->node = node;\n        ruby_sourcefile = node->nd_file;\n        ruby_sourceline = nd_line(node);\n    }\n    if (klass) {\n        if (TYPE(klass) == T_ICLASS) {\n            klass = RBASIC(klass)->klass;\n        }\n        else if (FL_TEST(klass, FL_SINGLETON)) {\n            klass = rb_iv_get(klass, \"__attached__\");\n        }\n    }\n    PUSH_TAG(PROT_EMPTY);\n    raised = rb_thread_reset_raised(th);\n    if ((state = EXEC_TAG()) == 0) {\n        srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:\"(ruby)\");\n        event_name = get_event_name(event);\n        proc_invoke(trace_func, rb_ary_new3(6, rb_str_new2(event_name),\n                                            srcfile,\n                                            INT2FIX(ruby_sourceline),\n                                            id?ID2SYM(id):Qnil,\n                                            self?rb_f_binding(self):Qnil,\n                                            klass),\n                    Qundef, 0);\n    }\n    if (raised) rb_thread_set_raised(th);\n    POP_TAG();\n    POP_FRAME();\n\n    tracing = 0;\n    ruby_current_node = node_save;\n    GC_DEBUG_SET_SOURCE\n    if (state) JUMP_TAG(state);\n}\n\nstatic VALUE\navalue_to_svalue(v)\n    VALUE v;\n{\n    VALUE tmp, top;\n\n    tmp = rb_check_array_type(v);\n    if (NIL_P(tmp)) {\n        return v;\n    }\n    if (RARRAY(tmp)->len == 0) {\n        return Qundef;\n    }\n    if (RARRAY(tmp)->len == 1) {\n        top = rb_check_array_type(RARRAY(tmp)->ptr[0]);\n        if (NIL_P(top)) {\n            return RARRAY(tmp)->ptr[0];\n        }\n        if (RARRAY(top)->len > 1) {\n            return v;\n        }\n        return top;\n    }\n    return tmp;\n}\n\nstatic VALUE\nsvalue_to_avalue(v)\n    VALUE v;\n{\n    VALUE tmp, top;\n\n    if (v == Qundef) return rb_ary_new2(0);\n    tmp = rb_check_array_type(v);\n    if (NIL_P(tmp)) {\n        return rb_ary_new3(1, v);\n    }\n    if (RARRAY(tmp)->len == 1) {\n        top = rb_check_array_type(RARRAY(tmp)->ptr[0]);\n        if (!NIL_P(top) && RARRAY(top)->len > 1) {\n            return tmp;\n        }\n        return rb_ary_new3(1, v);\n    }\n    return tmp;\n}\n\nstatic VALUE\nsvalue_to_mrhs(v, lhs)\n    VALUE v;\n    NODE *lhs;\n{\n    VALUE tmp;\n\n    if (v == Qundef) return rb_ary_new2(0);\n    tmp = rb_check_array_type(v);\n    if (NIL_P(tmp)) {\n        return rb_ary_new3(1, v);\n    }\n    /* no lhs means splat lhs only */\n    if (!lhs) {\n        return rb_ary_new3(1, v);\n    }\n    return tmp;\n}\n\nstatic VALUE\navalue_splat(v)\n    VALUE v;\n{\n    if (RARRAY(v)->len == 0) {\n        return Qundef;\n    }\n    if (RARRAY(v)->len == 1) {\n        return RARRAY(v)->ptr[0];\n    }\n    return v;\n}\n\n#if 1\nVALUE\nrb_Array(val)\n    VALUE val;\n{\n    VALUE tmp = rb_check_array_type(val);\n\n    if (NIL_P(tmp)) {\n        /* hack to avoid invoke Object#to_a */\n        VALUE origin;\n        ID id = rb_intern(\"to_a\");\n\n        if (search_method(CLASS_OF(val), id, &origin) &&\n            RCLASS(origin)->m_tbl != RCLASS(rb_mKernel)->m_tbl) { /* exclude Kernel#to_a */\n            val = rb_funcall(val, id, 0);\n            if (TYPE(val) != T_ARRAY) {\n                rb_raise(rb_eTypeError, \"`to_a' did not return Array\");\n            }\n            return val;\n        }\n        else {\n            return rb_ary_new3(1, val);\n        }\n    }\n    return tmp;\n}\n#endif\n\nstatic VALUE\nsplat_value(v)\n    VALUE v;\n{\n    if (NIL_P(v)) return rb_ary_new3(1, Qnil);\n    return rb_Array(v);\n}\n\nstatic VALUE\nclass_prefix(self, cpath)\n    VALUE self;\n    NODE *cpath;\n{\n    if (!cpath) {\n        rb_bug(\"class path missing\");\n    }\n    if (cpath->nd_head) {\n        VALUE c = rb_eval(self, cpath->nd_head);\n        switch (TYPE(c)) {\n          case T_CLASS:\n          case T_MODULE:\n            break;\n          default:\n            rb_raise(rb_eTypeError, \"%s is not a class/module\",\n                     RSTRING(rb_obj_as_string(c))->ptr);\n        }\n        return c;\n    }\n    else if (nd_type(cpath) == NODE_COLON2) {\n        return ruby_cbase;\n    }\n    else if (ruby_wrapper) {\n        return ruby_wrapper;\n    }\n    else {\n        return rb_cObject;\n    }\n}\n\n#define return_value(v) do {\\\n  if ((prot_tag->retval = (v)) == Qundef) {\\\n    prot_tag->retval = Qnil;\\\n  }\\\n} while (0)\n\nNORETURN(static void return_jump _((VALUE)));\nNORETURN(static void break_jump _((VALUE)));\nNORETURN(static void next_jump _((VALUE)));\nNORETURN(static void unknown_node _((NODE *)));\n\nstatic void\nunknown_node(node)\n    NODE *node;\n{\n    ruby_current_node = 0;\n    if (node->flags == 0) {\n        rb_bug(\"terminated node (0x%lx)\", node);\n    }\n    else if (BUILTIN_TYPE(node) != T_NODE) {\n        rb_bug(\"not a node 0x%02lx (0x%lx)\", BUILTIN_TYPE(node), node);\n    }\n    else {\n        rb_bug(\"unknown node type %d (0x%lx)\", nd_type(node), node);\n    }\n}\n\n/*\n *  functions factored out of rb_eval() to reduce its stack frame size\n */\n#define eval_node_0(n,retType, self, node)  \\\nNOINLINE(static retType TOKEN_PASTE(eval_,n) _((self, node)));\\\nstatic retType TOKEN_PASTE(eval_,n)(self, node)\n\n#define eval_node(n,retType) \\\n  eval_node_0(n,retType, VALUE self, NODE *node)\n#define eval_node_volatile(n,retType) \\\n  eval_node_0(n,retType, volatile VALUE self, NODE * volatile node)\n\neval_node(match2, VALUE)\n{\n    VALUE l = rb_eval(self,node->nd_recv);\n    VALUE r = rb_eval(self,node->nd_value);\n    return rb_reg_match(l, r);\n}\n\neval_node(match3, VALUE)\n{\n  VALUE r = rb_eval(self,node->nd_recv);\n  VALUE l = rb_eval(self,node->nd_value);\n  return TYPE(l) == T_STRING ? rb_reg_match(r, l) : rb_funcall(l, match, 1, r);\n}\n\n\neval_node_volatile(opt_n, void)\n{\n  int state;\n  PUSH_TAG(PROT_LOOP);\n  switch (state = EXEC_TAG()) {\n    case TAG_NEXT:\n      state = 0;\n    case 0:\n      while (!NIL_P(rb_gets())) {\n        opt_n_redo:\n          rb_eval(self, node->nd_body);\n      }\n      break;\n\n    case TAG_REDO:\n      state = 0;\n      goto opt_n_redo;\n\n    case TAG_BREAK:\n      state = 0;\n    default:\n      break;\n  }\n  POP_TAG();\n  if (state) JUMP_TAG(state);\n}\n\n\neval_node(when, NODE*)\n{\n  do {\n      NODE *tag = node->nd_head;\n      while (tag) {\n          EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,\n                          ruby_frame->last_func,\n                          ruby_frame->last_class);\n          if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {\n              VALUE v = rb_eval(self, tag->nd_head->nd_head);\n              long i;\n\n              if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);\n              for (i=0; i<RARRAY(v)->len; i++) {\n                  if (RTEST(RARRAY(v)->ptr[i])) return node->nd_body;\n              }\n              tag = tag->nd_next;\n              continue;\n          }\n          if (RTEST(rb_eval(self, tag->nd_head))) return node->nd_body;\n          tag = tag->nd_next;\n      }\n  } while ((node = node->nd_next) && nd_type(node) == NODE_WHEN);\n  return node;\n}\n\n\neval_node(case, NODE*)\n{\n  VALUE val = rb_eval(self, node->nd_head);\n  node = node->nd_body;\n  while (node) {\n      NODE *tag;\n\n      if (nd_type(node) != NODE_WHEN) break;\n      tag = node->nd_head;\n      while (tag) {\n          EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,\n                          ruby_frame->last_func,\n                          ruby_frame->last_class);\n          if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {\n              VALUE v = rb_eval(self, tag->nd_head->nd_head);\n              long i;\n\n              if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);\n              for (i=0; i<RARRAY(v)->len; i++) {\n                  if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val)))\n                      return node->nd_body;\n              }\n              tag = tag->nd_next;\n              continue;\n          }\n          if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val)))\n              return node->nd_body;\n          tag = tag->nd_next;\n      }\n      node = node->nd_next;\n  }\n  return node;\n}\n\n\neval_node_volatile(while, VALUE)\n{\n  int state;\n  VALUE result;\n  PUSH_TAG(PROT_LOOP);\n  switch (state = EXEC_TAG()) {\n    case 0:\n      if (!(node->nd_state) || RTEST(rb_eval(self, node->nd_cond))) {\n        do {\n          while_redo:\n#if STACK_WIPE_SITES & 0x10\n            rb_gc_wipe_stack();\n#endif\n            rb_eval(self, node->nd_body);\n          while_next:\n            ;\n        } while (RTEST(rb_eval(self, node->nd_cond)));\n      }  /* fall thru */\n    default:\n      result=Qnil;\n      break;\n\n    case TAG_REDO:\n      state = 0;\n      goto while_redo;\n    case TAG_NEXT:\n      state = 0;\n      goto while_next;\n    case TAG_BREAK:\n      if (TAG_DST()) {\n          state = 0;\n          result = prot_tag->retval;\n      }\n  }\n  POP_TAG();\n  if (state) JUMP_TAG(state);\n  return result;\n}\n\n\neval_node_volatile(until, VALUE)\n{\n  int state;\n  VALUE result;\n  PUSH_TAG(PROT_LOOP);\n  switch (state = EXEC_TAG()) {\n    case 0:\n      if (!(node->nd_state) || !RTEST(rb_eval(self, node->nd_cond))) {\n        do {\n          until_redo:\n  #if STACK_WIPE_SITES & 0x10\n            rb_gc_wipe_stack();\n  #endif\n            rb_eval(self, node->nd_body);\n          until_next:\n            ;\n        } while (!RTEST(rb_eval(self, node->nd_cond)));\n      }  /* fall thru */\n    default:\n      result=Qnil;\n      break;\n\n    case TAG_REDO:\n      state = 0;\n      goto until_redo;\n    case TAG_NEXT:\n      state = 0;\n      goto until_next;\n    case TAG_BREAK:\n      if (TAG_DST()) {\n          state = 0;\n          result = prot_tag->retval;\n      }\n  }\n  POP_TAG();\n  if (state) JUMP_TAG(state);\n  return result;\n}\n\n\neval_node_volatile(iter, VALUE)\n{\n  int state;\n  VALUE result;\n\n  PUSH_TAG(PROT_LOOP);\n  PUSH_BLOCK(node->nd_var, node->nd_body);\n\n  state = EXEC_TAG();\n  switch (state) {\n    case TAG_RETRY:\n      state = 0;  /* fall thru to case 0 */\n    case 0:\n      PUSH_ITER(ITER_PRE);\n      if (nd_type(node) == NODE_ITER) {\n          result = rb_eval(self, node->nd_iter);\n      }\n      else {\n          _block.flags &= ~BLOCK_D_SCOPE;\n          BEGIN_CALLARGS;\n          result = rb_eval(self, node->nd_iter);\n          END_CALLARGS;\n          ruby_current_node = (NODE *)node;\n          GC_DEBUG_SET_SOURCE\n          result = rb_call(CLASS_OF(result),result,each,0,0,0,self);\n      }\n      POP_ITER();\n      break;\n\n    case TAG_BREAK:\n      if (TAG_DST()) {\n        result = prot_tag->retval;\n        state = 0;\n      }\n  }\n  POP_BLOCK();\n  POP_TAG();\n  if (state) JUMP_TAG(state);\n  return result;\n}\n\n\neval_node_volatile(rescue, VALUE)\n{\n    volatile VALUE e_info = ruby_errinfo;\n    volatile int rescuing = 0;\n    int state;\n    VALUE result;\n\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n      retry_entry:\n        result = rb_eval(self, node->nd_head);\n    }\n    else if (rescuing) {\n        if (rescuing < 0) {\n            /* in rescue argument, just reraise */\n            result = Qnil;\n        }\n        else if (state == TAG_RETRY) {\n            rescuing = state = 0;\n            ruby_errinfo = e_info;\n            goto retry_entry;\n        }\n        else if (state != TAG_RAISE) {\n            result = prot_tag->retval;\n        }\n    }\n    else if (state == TAG_RAISE) {\n        NODE *resq = node->nd_resq;\n\n        rescuing = -1;\n        while (resq) {\n            ruby_current_node = resq;\n            if (handle_rescue(self, resq)) {\n                state = 0;\n                rescuing = 1;\n                result = rb_eval(self, resq->nd_body);\n                break;\n            }\n            resq = resq->nd_head; /* next rescue */\n        }\n    }\n    else {\n        result = prot_tag->retval;\n    }\n    POP_TAG();\n    if (state != TAG_RAISE) ruby_errinfo = e_info;\n    if (state) {\n        JUMP_TAG(state);\n    }\n    /* no exception raised */\n    if (!rescuing && node->nd_else) { /* else clause given */\n        result = Qundef;  /* caller must eval this! */\n    }\n    return result;\n}\n\n\neval_node_volatile(ensure, VALUE)\n{\n  int state;\n  VALUE result;\n\n  PUSH_TAG(PROT_EMPTY);\n  if ((state = EXEC_TAG()) == 0) {\n      result = rb_eval(self, node->nd_head);\n  }\n  POP_TAG();\n  if (node->nd_ensr && !thread_no_ensure()) {\n      VALUE retval = prot_tag->retval; /* save retval */\n      VALUE errinfo = ruby_errinfo;\n\n      rb_eval(self, node->nd_ensr);\n      return_value(retval);\n      ruby_errinfo = errinfo;\n  }\n  if (state) JUMP_TAG(state);\n  return result;\n}\n\n\neval_node(dot, VALUE)\n{\n  VALUE beg = rb_eval(self, node->nd_beg);\n  VALUE end = rb_eval(self, node->nd_end);\n  return rb_range_new(beg, end, nd_type(node) == NODE_DOT3);\n}\n\n\neval_node(flip2, VALUE)\n{\n  VALUE *flip = rb_svar(node->nd_cnt);\n  if (!flip) rb_bug(\"unexpected local variable\");\n  if (!RTEST(*flip)) {\n    if (!RTEST(rb_eval(self, node->nd_beg)))\n      return Qfalse;\n    *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue;\n  }\n  else if (RTEST(rb_eval(self, node->nd_end)))\n    *flip = Qfalse;\n  return Qtrue;\n}\n\n\neval_node(flip3, VALUE)\n{\n  VALUE *flip = rb_svar(node->nd_cnt);\n  if (!flip) rb_bug(\"unexpected local variable\");\n  if (!RTEST(*flip))\n    return *flip = (RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse);\n  if (RTEST(rb_eval(self, node->nd_end)))\n    *flip = Qfalse;\n  return Qtrue;\n}\n\n\neval_node(attrasgn, VALUE)\n{\n  VALUE recv;\n  int argc; VALUE *argv; /* used in SETUP_ARGS */\n  int scope;\n  TMP_PROTECT;\n\n  BEGIN_CALLARGS;\n  if (node->nd_recv == (NODE *)1) {\n      recv = self;\n      scope = 1;\n  }\n  else {\n      recv = rb_eval(self, node->nd_recv);\n      scope = 0;\n  }\n  SETUP_ARGS(node->nd_args);\n  END_CALLARGS;\n\n  ruby_current_node = node;\n  GC_DEBUG_SET_SOURCE\n  rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope,self);\n  return argv[argc-1];\n}\n\n\neval_node(call, VALUE)\n{\n  VALUE recv;\n  int argc; VALUE *argv; /* used in SETUP_ARGS */\n  TMP_PROTECT;\n\n  BEGIN_CALLARGS;\n  recv = rb_eval(self, node->nd_recv);\n  SETUP_ARGS(node->nd_args);\n  END_CALLARGS;\n\n  ruby_current_node = node;\n  GC_DEBUG_SET_SOURCE\n  return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0,self);\n}\n\n\neval_node(fcall, VALUE)\n{\n  int argc; VALUE *argv; /* used in SETUP_ARGS */\n  TMP_PROTECT;\n\n  BEGIN_CALLARGS;\n  SETUP_ARGS(node->nd_args);\n  END_CALLARGS;\n\n  ruby_current_node = node;\n  GC_DEBUG_SET_SOURCE\n  return rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1,self);\n}\n\n\neval_node(super, VALUE)\n{\n  int argc; VALUE *argv; /* used in SETUP_ARGS */\n  TMP_PROTECT;\n\n  if (ruby_frame->last_class == 0) {\n      if (ruby_frame->last_func) {\n          rb_name_error(ruby_frame->last_func,\n                        \"superclass method `%s' disabled\",\n                        rb_id2name(ruby_frame->orig_func));\n      }\n      else {\n          rb_raise(rb_eNoMethodError, \"super called outside of method\");\n      }\n  }\n  if (nd_type(node) == NODE_ZSUPER) {\n      argc = ruby_frame->argc;\n      if (argc && DMETHOD_P()) {\n          if (TYPE(RBASIC(ruby_scope)->klass) != T_ARRAY ||\n              RARRAY(RBASIC(ruby_scope)->klass)->len != argc) {\n              rb_raise(rb_eRuntimeError,\n                       \"super: specify arguments explicitly\");\n          }\n          argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr;\n      }\n      else if (!ruby_scope->local_vars) {\n          argc = 0;\n          argv = 0;\n      }\n      else {\n          argv = ruby_scope->local_vars + 2;\n      }\n  }\n  else {\n      BEGIN_CALLARGS;\n      SETUP_ARGS(node->nd_args);\n      END_CALLARGS;\n      ruby_current_node = node;\n  }\n\n  GC_DEBUG_SET_SOURCE\n  return rb_call_super(argc, argv);\n}\n\neval_node_volatile(scope, VALUE)\n{\n  int state;\n  VALUE result;\n  struct FRAME frame;\n  NODE * volatile saved_cref = 0;\n\n  frame = *ruby_frame;\n  frame.tmp = ruby_frame;\n  ruby_frame = &frame;\n\n  PUSH_SCOPE();\n  PUSH_TAG(PROT_EMPTY);\n  if (node->nd_rval) {\n      saved_cref = ruby_cref;\n      ruby_cref = (NODE*)node->nd_rval;\n  }\n  if (node->nd_tbl) {\n      VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1);\n      *vars++ = (VALUE)node;\n      ruby_scope->local_vars = vars;\n      rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);\n      ruby_scope->local_tbl = node->nd_tbl;\n  }\n  else {\n      ruby_scope->local_vars = 0;\n      ruby_scope->local_tbl  = 0;\n  }\n  if ((state = EXEC_TAG()) == 0) {\n      result = rb_eval(self, node->nd_next);\n  }\n  POP_TAG();\n  POP_SCOPE();\n  ruby_frame = frame.tmp;\n  if (saved_cref)\n      ruby_cref = saved_cref;\n  if (state) JUMP_TAG(state);\n  return result;\n}\n\neval_node(op_asgn1, VALUE)\n{\n  int argc; VALUE *argv; /* used in SETUP_ARGS */\n  VALUE recv, val, tmp;\n  NODE *rval;\n  TMP_PROTECT;\n\n  recv = rb_eval(self, node->nd_recv);\n  rval = node->nd_args->nd_head;\n  SETUP_ARGS0(node->nd_args->nd_body, 1);\n  val = rb_funcall3(recv, aref, argc, argv);\n  switch (node->nd_mid) {\n  case 0: /* OR */\n    if (RTEST(val)) return val;\n    val = rb_eval(self, rval);\n    break;\n  case 1: /* AND */\n    if (!RTEST(val)) return val;\n    val = rb_eval(self, rval);\n    break;\n  default:\n    tmp = rb_eval(self, rval);\n    val = rb_funcall3(val, node->nd_mid, 1, &tmp);\n  }\n  argv[argc] = val;\n  rb_funcall2(recv, aset, argc+1, argv);\n  return val;\n}\n\n\neval_node(op_asgn2, VALUE)\n{\n  ID id = node->nd_next->nd_vid;\n  VALUE recv, val, tmp;\n\n  recv = rb_eval(self, node->nd_recv);\n  val = rb_funcall3(recv, id, 0, 0);\n  switch (node->nd_next->nd_mid) {\n  case 0: /* OR */\n    if (RTEST(val)) return val;\n    val = rb_eval(self, node->nd_value);\n    break;\n  case 1: /* AND */\n    if (!RTEST(val)) return val;\n    val = rb_eval(self, node->nd_value);\n    break;\n  default:\n    tmp = rb_eval(self, node->nd_value);\n    val = rb_funcall3(val, node->nd_next->nd_mid, 1, &tmp);\n  }\n\n  rb_funcall2(recv, node->nd_next->nd_aid, 1, &val);\n  return val;\n}\n\n\neval_node(hash, VALUE)\n{\n  NODE *list;\n  VALUE hash = rb_hash_new();\n  VALUE key, val;\n\n  list = node->nd_head;\n  while (list) {\n      key = rb_eval(self, list->nd_head);\n      list = list->nd_next;\n      if (list == 0)\n          rb_bug(\"odd number list for Hash\");\n      val = rb_eval(self, list->nd_head);\n      list = list->nd_next;\n      rb_hash_aset(hash, key, val);\n  }\n  return hash;\n}\n\n\neval_node(array, VALUE)\n{\n  VALUE ary;\n  long i;\n\n  i = node->nd_alen;\n  ary = rb_ary_new2(i);\n  for (i=0;node;node=node->nd_next) {\n      RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head);\n      RARRAY(ary)->len = i;\n  }\n  return ary;\n}\n\n\neval_node(slit, VALUE)\n{\n  VALUE str, str2;\n  NODE *list = node->nd_next;\n\n  str = rb_str_new3(node->nd_lit);\n  while (list) {\n      if (list->nd_head) {\n          switch (nd_type(list->nd_head)) {\n            case NODE_STR:\n              str2 = list->nd_head->nd_lit;\n              break;\n            default:\n              str2 = rb_eval(self, list->nd_head);\n              break;\n          }\n          rb_str_append(str, str2);\n          OBJ_INFECT(str, str2);\n      }\n      list = list->nd_next;\n  }\n  switch (nd_type(node)) {\n    case NODE_DREGX:\n      str2 = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,\n                          node->nd_cflag);\n      RB_GC_GUARD(str);  /* ensure str is not GC'd in rb_reg_new */\n      return str2;\n    case NODE_DREGX_ONCE:       /* regexp expand once */\n      str2 = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,\n                          node->nd_cflag);\n      nd_set_type(node, NODE_LIT);\n      RB_GC_GUARD(str);  /* ensure str is not GC'd in rb_reg_new */\n      maybe_add_to_longlife_recent_allocations(node);\n      return node->nd_lit = str2;\n    case NODE_LIT:\n      /* other thread may replace NODE_DREGX_ONCE to NODE_LIT */\n      return Qundef;\n    case NODE_DXSTR:\n      return rb_funcall(self, '`', 1, str);\n    case NODE_DSYM:\n      return rb_str_intern(str);\n  }\n  return str;\n}\n\n\neval_node(defn, void)\n{\n  NODE *body,  *defn;\n  VALUE origin = 0;\n  int noex;\n\n  if (NIL_P(ruby_class)) {\n      rb_raise(rb_eTypeError, \"no class/module to add method\");\n  }\n  if (ruby_class == rb_cObject && node->nd_mid == init) {\n      rb_warn(\"redefining Object#initialize may cause infinite loop\");\n  }\n  if (node->nd_mid == __id__ || node->nd_mid == __send__) {\n      rb_warn(\"redefining `%s' may cause serious problem\",\n              rb_id2name(node->nd_mid));\n  }\n  rb_frozen_class_p(ruby_class);\n  body = search_method(ruby_class, node->nd_mid, &origin);\n  if (body){\n      if (RTEST(ruby_verbose) && ruby_class == origin && body->nd_cnt == 0 && body->nd_body) {\n          rb_warning(\"method redefined; discarding old %s\", rb_id2name(node->nd_mid));\n      }\n  }\n\n  if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) {\n      noex = NOEX_PRIVATE;\n  }\n  else if (SCOPE_TEST(SCOPE_PROTECTED)) {\n      noex = NOEX_PROTECTED;\n  }\n  else {\n      noex = NOEX_PUBLIC;\n  }\n  if (body && origin == ruby_class && body->nd_body == 0) {\n      noex |= NOEX_NOSUPER;\n  }\n\n  defn = rb_copy_node_scope(node->nd_defn, ruby_cref);\n  rb_add_method(ruby_class, node->nd_mid, defn, noex);\n  if (scope_vmode == SCOPE_MODFUNC) {\n      rb_add_method(rb_singleton_class(ruby_class),\n                    node->nd_mid, defn, NOEX_PUBLIC);\n  }\n}\n\n\neval_node(defs, void)\n{\n  VALUE recv = rb_eval(self, node->nd_recv);\n  VALUE klass;\n  NODE *body = 0, *defn;\n  st_data_t data;\n\n  if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) {\n      rb_raise(rb_eSecurityError, \"Insecure: can't define singleton method\");\n  }\n  if (FIXNUM_P(recv) || SYMBOL_P(recv)) {\n      rb_raise(rb_eTypeError,\n               \"can't define singleton method \\\"%s\\\" for %s\",\n               rb_id2name(node->nd_mid),\n               rb_obj_classname(recv));\n  }\n\n  if (OBJ_FROZEN(recv)) rb_error_frozen(\"object\");\n  klass = rb_singleton_class(recv);\n  if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &data)) {\n      body = (NODE *)data;\n      if (ruby_safe_level >= 4) {\n          rb_raise(rb_eSecurityError, \"redefining method prohibited\");\n      }\n      if (RTEST(ruby_verbose)) {\n          rb_warning(\"redefine %s\", rb_id2name(node->nd_mid));\n      }\n  }\n  defn = rb_copy_node_scope(node->nd_defn, ruby_cref);\n  rb_add_method(klass, node->nd_mid, defn,\n                NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0));\n}\n\n\neval_node(class, VALUE)\n{\n    VALUE super, klass, tmp, cbase;\n    ID cname;\n    int gen = Qfalse;\n\n    cbase = class_prefix(self, node->nd_cpath);\n    cname = node->nd_cpath->nd_mid;\n\n    if (NIL_P(ruby_cbase)) {\n        rb_raise(rb_eTypeError, \"no outer class/module\");\n    }\n    if (node->nd_super) {\n       super = rb_eval(self, node->nd_super);\n       rb_check_inheritable(super);\n    }\n    else {\n        super = 0;\n    }\n\n    if (rb_const_defined_at(cbase, cname)) {\n        klass = rb_const_get_at(cbase, cname);\n        if (TYPE(klass) != T_CLASS) {\n            rb_raise(rb_eTypeError, \"%s is not a class\",\n                     rb_id2name(cname));\n        }\n        if (super) {\n            tmp = rb_class_real(RCLASS(klass)->super);\n            if (tmp != super) {\n                rb_raise(rb_eTypeError, \"superclass mismatch for class %s\",\n                         rb_id2name(cname));\n            }\n            super = 0;\n        }\n        if (ruby_safe_level >= 4) {\n            rb_raise(rb_eSecurityError, \"extending class prohibited\");\n        }\n    }\n    else {\n        if (!super) super = rb_cObject;\n        klass = rb_define_class_id(cname, super);\n        rb_set_class_path(klass, cbase, rb_id2name(cname));\n        rb_const_set(cbase, cname, klass);\n        gen = Qtrue;\n    }\n    if (ruby_wrapper) {\n        rb_extend_object(klass, ruby_wrapper);\n        rb_include_module(klass, ruby_wrapper);\n    }\n    if (super && gen) {\n        rb_class_inherited(super, klass);\n    }\n    return module_setup(klass, node);\n}\n\n\neval_node(module, VALUE)\n{\n  VALUE module, cbase;\n  ID cname;\n\n  if (NIL_P(ruby_cbase)) {\n      rb_raise(rb_eTypeError, \"no outer class/module\");\n  }\n  cbase = class_prefix(self, node->nd_cpath);\n  cname = node->nd_cpath->nd_mid;\n  if (rb_const_defined_at(cbase, cname)) {\n      module = rb_const_get_at(cbase, cname);\n      if (TYPE(module) != T_MODULE) {\n          rb_raise(rb_eTypeError, \"%s is not a module\",\n                   rb_id2name(cname));\n      }\n      if (ruby_safe_level >= 4) {\n          rb_raise(rb_eSecurityError, \"extending module prohibited\");\n      }\n  }\n  else {\n      module = rb_define_module_id(cname);\n      rb_set_class_path(module, cbase, rb_id2name(cname));\n      rb_const_set(cbase, cname, module);\n  }\n  if (ruby_wrapper) {\n      rb_extend_object(module, ruby_wrapper);\n      rb_include_module(module, ruby_wrapper);\n  }\n\n  return module_setup(module, node);\n}\n\n\neval_node(sclass, VALUE)\n{\n  VALUE klass, result;\n\n  result = rb_eval(self, node->nd_recv);\n  if (FIXNUM_P(result) || SYMBOL_P(result)) {\n      rb_raise(rb_eTypeError, \"no virtual class for %s\",\n               rb_obj_classname(result));\n  }\n  if (ruby_safe_level >= 4 && !OBJ_TAINTED(result))\n      rb_raise(rb_eSecurityError, \"Insecure: can't extend object\");\n  klass = rb_singleton_class(result);\n\n  if (ruby_wrapper) {\n      rb_extend_object(klass, ruby_wrapper);\n      rb_include_module(klass, ruby_wrapper);\n  }\n\n  return module_setup(klass, node);\n}\n\n\neval_node(defined, VALUE)\n{\n    char buf[20];\n    const char *desc = is_defined(self, node->nd_head, buf);\n    return desc ? rb_str_new2(desc) : Qnil;\n}\n\n\nstatic void\neval_cvar_set(node, result, warn)\n  NODE *node;\n  VALUE result;\n  int warn;\n{\n  rb_cvar_set(cvar_cbase(), node->nd_vid, result, warn);\n}\n\n\nstatic void\neval_cdecl(self, node, result)\n  VALUE self, result;\n  NODE *node;\n{\n  if (node->nd_vid == 0)\n      rb_const_set(class_prefix(self, node->nd_else),\n                          node->nd_else->nd_mid, result);\n  else\n      rb_const_set(ruby_cbase, node->nd_vid, result);\n}\n\n\nstatic VALUE\nrb_eval(self, node)\n  VALUE self;\n  NODE * node;\n{\n  VALUE result;\n\nagain:\n  eval_check_tick();\n  result = Qnil;\n  if (node) {\n    ruby_current_node = node;\n    switch (nd_type(node)) {\n      case NODE_BLOCK:\n        while (node->nd_next) {\n            rb_eval(self, node->nd_head);\n            node = node->nd_next;\n        }\n        node = node->nd_head;\n        goto again;\n\n      case NODE_POSTEXE:\n        rb_f_END();\n        nd_set_type(node, NODE_NIL); /* exec just once */\n        break;\n\n        /* begin .. end without clauses */\n      case NODE_BEGIN:\n        node = node->nd_body;\n        goto again;\n\n        /* nodes for speed-up(default match) */\n      case NODE_MATCH:\n        result = rb_reg_match2(node->nd_lit);\n        break;\n\n        /* nodes for speed-up(literal match) */\n      case NODE_MATCH2:\n        result = eval_match2(self, node);\n        break;\n\n        /* nodes for speed-up(literal match) */\n      case NODE_MATCH3:\n        result = eval_match3(self,node);\n        break;\n\n        /* node for speed-up(top-level loop for -n/-p) */\n      case NODE_OPT_N:\n        eval_opt_n(self, node);\n        break;\n\n      case NODE_SELF:\n        result = self;\n        break;\n\n      case NODE_NIL:\n        break;\n\n      case NODE_TRUE:\n        result = Qtrue;\n        break;\n\n      case NODE_FALSE:\n        result = Qfalse;\n        break;\n\n      case NODE_IF:\n        if (RTEST(rb_eval(self, node->nd_cond))) {\n            EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,\n                            ruby_frame->last_func,\n                            ruby_frame->last_class);\n            node = node->nd_body;\n        }\n        else {\n            EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,\n                            ruby_frame->last_func,\n                            ruby_frame->last_class);\n            node = node->nd_else;\n        }\n        goto again;\n\n      case NODE_WHEN:\n        if (node = eval_when(self, node)) goto again;\n        break;\n\n      case NODE_CASE:\n        if (node = eval_case(self, node)) goto again;\n        break;\n\n      case NODE_WHILE:\n        result = eval_while(self,node);\n        break;\n\n      case NODE_UNTIL:\n        result = eval_until(self,node);\n        break;\n\n      case NODE_BLOCK_PASS:\n        result = block_pass(self, node);\n        break;\n\n      case NODE_ITER:\n      case NODE_FOR:\n        result = eval_iter(self, node);\n        break;\n\n      case NODE_BREAK:\n        break_jump(rb_eval(self, node->nd_stts));\n        break;\n\n      case NODE_NEXT:\n        next_jump(rb_eval(self, node->nd_stts));\n        break;\n\n      case NODE_REDO:\n        JUMP_TAG(TAG_REDO);\n        break;\n\n      case NODE_RETRY:\n        JUMP_TAG(TAG_RETRY);\n        break;\n\n      case NODE_SPLAT:\n        result = splat_value(rb_eval(self, node->nd_head));\n        break;\n\n      case NODE_TO_ARY:\n        result = rb_ary_to_ary(rb_eval(self, node->nd_head));\n        break;\n\n      case NODE_SVALUE:\n        result = avalue_splat(rb_eval(self, node->nd_head));\n        if (result == Qundef) result = Qnil;\n        break;\n\n      case NODE_YIELD:\n        if (node->nd_head) {\n            result = rb_eval(self, node->nd_head);\n            ruby_current_node = node;\n        }\n        else {\n            result = Qundef;    /* no arg */\n        }\n        GC_DEBUG_SET_SOURCE\n        result = rb_yield_0(result, 0, 0, 0, node->nd_state);\n        break;\n\n      case NODE_RESCUE:\n        result = eval_rescue(self,node);\n        if (result == Qundef) {  /* handle else clause w/o recursion */\n          node = node->nd_else;\n          goto again;\n        }\n        break;\n\n      case NODE_ENSURE:\n        result = eval_ensure(self,node);\n        break;\n\n      case NODE_AND:\n        result = rb_eval(self, node->nd_1st);\n        if (!RTEST(result)) break;\n        node = node->nd_2nd;\n        goto again;\n\n      case NODE_OR:\n        result = rb_eval(self, node->nd_1st);\n        if (RTEST(result)) break;\n        node = node->nd_2nd;\n        goto again;\n\n      case NODE_NOT:\n        result = RTEST(rb_eval(self, node->nd_body)) ? Qfalse : Qtrue;\n        break;\n\n      case NODE_DOT2:\n      case NODE_DOT3:\n        result = eval_dot(self,node);\n        break;\n\n      case NODE_FLIP2:          /* like AWK */\n        result = eval_flip2(self,node);\n        break;\n\n      case NODE_FLIP3:          /* like SED */\n        result = eval_flip3(self,node);\n        break;\n\n      case NODE_RETURN:\n        return_jump(rb_eval(self, node->nd_stts));\n        break;\n\n      case NODE_ARGSCAT:\n        result = rb_eval(self, node->nd_head);\n        result = rb_ary_concat(result, splat_value(rb_eval(self, node->nd_body)));\n        break;\n\n      case NODE_ARGSPUSH:\n        result = rb_ary_dup(rb_eval(self, node->nd_head));\n        result = rb_ary_push(result, rb_eval(self, node->nd_body));\n        break;\n\n      case NODE_ATTRASGN:\n        result = eval_attrasgn(self,node);\n        break;\n\n      case NODE_CALL:\n        result = eval_call(self,node);\n        break;\n\n      case NODE_FCALL:\n        result = eval_fcall(self,node);\n        break;\n\n      case NODE_VCALL:\n        GC_DEBUG_SET_SOURCE\n        result = rb_call(CLASS_OF(self),self,node->nd_mid,0,0,2,self);\n        break;\n\n      case NODE_SUPER:\n      case NODE_ZSUPER:\n        result = eval_super(self,node);\n        break;\n\n      case NODE_SCOPE:\n        result = eval_scope(self,node);\n        break;\n\n      case NODE_OP_ASGN1:\n        result = eval_op_asgn1(self,node);\n        break;\n\n      case NODE_OP_ASGN2:\n        result = eval_op_asgn2(self,node);\n        break;\n\n      case NODE_OP_ASGN_AND:\n        result = rb_eval(self, node->nd_head);\n        if (!RTEST(result)) break;\n        node = node->nd_value;\n        goto again;\n\n      case NODE_OP_ASGN_OR:\n        if ((node->nd_aid && !is_defined(self, node->nd_head, 0)) ||\n            !RTEST(result = rb_eval(self, node->nd_head))) {\n            node = node->nd_value;\n            goto again;\n        }\n        break;\n\n      case NODE_MASGN:\n        result = massign(self, node, rb_eval(self, node->nd_value), 0);\n        break;\n\n      case NODE_LASGN:\n        if (ruby_scope->local_vars == 0)\n            rb_bug(\"unexpected local variable assignment\");\n        result = rb_eval(self, node->nd_value);\n        ruby_scope->local_vars[node->nd_cnt] = result;\n        break;\n\n      case NODE_DASGN:\n        result = rb_eval(self, node->nd_value);\n        dvar_asgn(node->nd_vid, result);\n        break;\n\n      case NODE_DASGN_CURR:\n        result = rb_eval(self, node->nd_value);\n        dvar_asgn_curr(node->nd_vid, result);\n        break;\n\n      case NODE_GASGN:\n        ruby_in_longlife_context++;\n        result = rb_eval(self, node->nd_value);\n        rb_gvar_set(node->nd_entry, result);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_IASGN:\n        result = rb_eval(self, node->nd_value);\n        rb_ivar_set(self, node->nd_vid, result);\n        break;\n\n      case NODE_CDECL:\n        ruby_in_longlife_context++;\n        result = rb_eval(self, node->nd_value);\n        eval_cdecl(self, node, result);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_CVDECL:\n        if (NIL_P(ruby_cbase)) {\n            rb_raise(rb_eTypeError, \"no class/module to define class variable\");\n        }\n        ruby_in_longlife_context++;\n        result = rb_eval(self, node->nd_value);\n        eval_cvar_set(node, result, Qtrue);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_CVASGN:\n        ruby_in_longlife_context++;\n        result = rb_eval(self, node->nd_value);\n        eval_cvar_set(node, result, Qfalse);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_LVAR:\n        if (ruby_scope->local_vars == 0) {\n            rb_bug(\"unexpected local variable\");\n        }\n        result = ruby_scope->local_vars[node->nd_cnt];\n        break;\n\n      case NODE_DVAR:\n        result = rb_dvar_ref(node->nd_vid);\n        break;\n\n      case NODE_GVAR:\n        result = rb_gvar_get(node->nd_entry);\n        break;\n\n      case NODE_IVAR:\n        result = rb_ivar_get(self, node->nd_vid);\n        break;\n\n      case NODE_CONST:\n        result = ev_const_get(ruby_cref, node->nd_vid, self);\n        break;\n\n      case NODE_CVAR:\n        result = rb_cvar_get(cvar_cbase(), node->nd_vid);\n        break;\n\n      case NODE_BLOCK_ARG:\n        if (ruby_scope->local_vars == 0)\n            rb_bug(\"unexpected block argument\");\n        if (rb_block_given_p()) {\n            result = rb_block_proc();\n            ruby_scope->local_vars[node->nd_cnt] = result;\n        }\n        else {\n            result = Qnil;\n        }\n        break;\n\n      case NODE_COLON2:\n        result = rb_eval(self, node->nd_head);\n        if (rb_is_const_id(node->nd_mid)) {\n            switch (TYPE(result)) {\n              case T_CLASS:\n              case T_MODULE:\n                result = rb_const_get_from(result, node->nd_mid);\n                break;\n              default:\n                rb_raise(rb_eTypeError, \"%s is not a class/module\",\n                         RSTRING(rb_obj_as_string(result))->ptr);\n                break;\n            }\n        }\n        else\n            result = rb_funcall(result, node->nd_mid, 0, 0);\n        break;\n\n      case NODE_COLON3:\n        result = rb_const_get_from(rb_cObject, node->nd_mid);\n        break;\n\n      case NODE_NTH_REF:\n        result = rb_reg_nth_match(node->nd_nth, MATCH_DATA);\n        break;\n\n      case NODE_BACK_REF:\n        switch (node->nd_nth) {\n          case '&':\n            result = rb_reg_last_match(MATCH_DATA);\n            break;\n          case '`':\n            result = rb_reg_match_pre(MATCH_DATA);\n            break;\n          case '\\'':\n            result = rb_reg_match_post(MATCH_DATA);\n            break;\n          case '+':\n            result = rb_reg_match_last(MATCH_DATA);\n            break;\n          default:\n            rb_bug(\"unexpected back-ref\");\n        }\n        break;\n\n      case NODE_HASH:\n        result = eval_hash(self,node);\n        break;\n\n      case NODE_ZARRAY:         /* zero length list */\n        result = rb_ary_new();\n        break;\n\n      case NODE_ARRAY:\n        result = eval_array(self,node);\n        break;\n\n      case NODE_STR:\n        result = rb_str_new3(node->nd_lit);\n        break;\n\n      case NODE_EVSTR:\n        result = rb_obj_as_string(rb_eval(self, node->nd_body));\n        break;\n\n      case NODE_DSTR:\n      case NODE_DXSTR:\n      case NODE_DREGX:\n      case NODE_DREGX_ONCE:\n      case NODE_DSYM:\n        result = eval_slit(self, node);\n        if (result == Qundef) goto again;\n        break;\n\n      case NODE_XSTR:\n        result = rb_funcall(self, '`', 1, rb_str_new3(node->nd_lit));\n        break;\n\n      case NODE_LIT:\n        result = node->nd_lit;\n        break;\n\n      case NODE_DEFN:\n        if (node->nd_defn)\n          eval_defn(self,node);\n        break;\n\n      case NODE_DEFS:\n        if (node->nd_defn)\n          eval_defs(self,node);\n        break;\n\n      case NODE_UNDEF:\n        if (NIL_P(ruby_class)) {\n            rb_raise(rb_eTypeError, \"no class to undef method\");\n        }\n        rb_undef(ruby_class, rb_to_id(rb_eval(self, node->u2.node)));\n        break;\n\n      case NODE_ALIAS:\n        if (NIL_P(ruby_class)) {\n            rb_raise(rb_eTypeError, \"no class to make alias\");\n        }\n        rb_alias(ruby_class, rb_to_id(rb_eval(self, node->u1.node)),\n                             rb_to_id(rb_eval(self, node->u2.node)));\n        break;\n\n      case NODE_VALIAS:\n        rb_alias_variable(node->u1.id, node->u2.id);\n        break;\n\n      case NODE_CLASS:\n        result = eval_class(self,node);\n        break;\n\n      case NODE_MODULE:\n        result = eval_module(self,node);\n        break;\n\n      case NODE_SCLASS:\n        result = eval_sclass(self,node);\n        break;\n\n      case NODE_DEFINED:\n        result = eval_defined(self,node);\n        break;\n\n      case NODE_NEWLINE:\n        EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,\n                        ruby_frame->last_func,\n                        ruby_frame->last_class);\n        node = node->nd_next;\n        goto again;\n\n      default:\n        unknown_node(node);\n    }\n  }\n  return result;\n}\n\nstatic VALUE\nmodule_setup(module, n)\n    VALUE module;\n    NODE * volatile n;\n{\n    NODE *node = n->nd_body;\n    int state;\n    struct FRAME frame;\n    VALUE result;\n    TMP_PROTECT;\n\n    frame = *ruby_frame;\n    frame.tmp = ruby_frame;\n    ruby_frame = &frame;\n\n    PUSH_CLASS(module);\n    PUSH_SCOPE();\n    PUSH_VARS();\n\n    if (node->nd_tbl) {\n        VALUE *vars = TMP_ALLOC(node->nd_tbl[0]+1);\n        *vars++ = (VALUE)node;\n        ruby_scope->local_vars = vars;\n        rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);\n        ruby_scope->local_tbl = node->nd_tbl;\n    }\n    else {\n        ruby_scope->local_vars = 0;\n        ruby_scope->local_tbl  = 0;\n    }\n\n    PUSH_CREF(module);\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        EXEC_EVENT_HOOK(RUBY_EVENT_CLASS, n, ruby_cbase,\n                        ruby_frame->last_func, ruby_frame->last_class);\n        result = rb_eval(ruby_cbase, node->nd_next);\n    }\n    POP_TAG();\n    POP_CREF();\n    POP_VARS();\n    POP_SCOPE();\n    POP_CLASS();\n\n    ruby_frame = frame.tmp;\n    EXEC_EVENT_HOOK(RUBY_EVENT_END, n, 0,\n                    ruby_frame->last_func, ruby_frame->last_class);\n    if (state) JUMP_TAG(state);\n\n    return result;\n}\n\nstatic NODE *basic_respond_to = 0;\n\nint\nrb_obj_respond_to(obj, id, priv)\n    VALUE obj;\n    ID id;\n    int priv;\n{\n    VALUE klass = CLASS_OF(obj);\n\n    if (rb_method_node(klass, respond_to) == basic_respond_to) {\n        return rb_method_boundp(klass, id, !priv);\n    }\n    else {\n        VALUE args[2];\n        int n = 0;\n        args[n++] = ID2SYM(id);\n        if (priv) args[n++] = Qtrue;\n        return RTEST(rb_funcall2(obj, respond_to, n, args));\n    }\n}\n\nint\nrb_respond_to(obj, id)\n    VALUE obj;\n    ID id;\n{\n    return rb_obj_respond_to(obj, id, Qfalse);\n}\n\n/*\n *  call-seq:\n *     obj.respond_to?(symbol, include_private=false) => true or false\n *\n *  Returns +true+> if _obj_ responds to the given\n *  method. Private methods are included in the search only if the\n *  optional second parameter evaluates to +true+.\n */\n\nstatic VALUE\nobj_respond_to(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE mid, priv;\n    ID id;\n\n    rb_scan_args(argc, argv, \"11\", &mid, &priv);\n    id = rb_to_id(mid);\n    if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     mod.method_defined?(symbol)    => true or false\n *\n *  Returns +true+ if the named method is defined by\n *  _mod_ (or its included modules and, if _mod_ is a class,\n *  its ancestors). Public and protected methods are matched.\n *\n *     module A\n *       def method1()  end\n *     end\n *     class B\n *       def method2()  end\n *     end\n *     class C < B\n *       include A\n *       def method3()  end\n *     end\n *\n *     A.method_defined? :method1    #=> true\n *     C.method_defined? \"method1\"   #=> true\n *     C.method_defined? \"method2\"   #=> true\n *     C.method_defined? \"method3\"   #=> true\n *     C.method_defined? \"method4\"   #=> false\n */\n\nstatic VALUE\nrb_mod_method_defined(mod, mid)\n    VALUE mod, mid;\n{\n    return rb_method_boundp(mod, rb_to_id(mid), 1);\n}\n\n#define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))\n\n/*\n *  call-seq:\n *     mod.public_method_defined?(symbol)   => true or false\n *\n *  Returns +true+ if the named public method is defined by\n *  _mod_ (or its included modules and, if _mod_ is a class,\n *  its ancestors).\n *\n *     module A\n *       def method1()  end\n *     end\n *     class B\n *       protected\n *       def method2()  end\n *     end\n *     class C < B\n *       include A\n *       def method3()  end\n *     end\n *\n *     A.method_defined? :method1           #=> true\n *     C.public_method_defined? \"method1\"   #=> true\n *     C.public_method_defined? \"method2\"   #=> false\n *     C.method_defined? \"method2\"          #=> true\n */\n\nstatic VALUE\nrb_mod_public_method_defined(mod, mid)\n    VALUE mod, mid;\n{\n    ID id = rb_to_id(mid);\n    int noex;\n\n    if (rb_get_method_body(&mod, &id, &noex)) {\n        if (VISI_CHECK(noex, NOEX_PUBLIC))\n            return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     mod.private_method_defined?(symbol)    => true or false\n *\n *  Returns +true+ if the named private method is defined by\n *  _ mod_ (or its included modules and, if _mod_ is a class,\n *  its ancestors).\n *\n *     module A\n *       def method1()  end\n *     end\n *     class B\n *       private\n *       def method2()  end\n *     end\n *     class C < B\n *       include A\n *       def method3()  end\n *     end\n *\n *     A.method_defined? :method1            #=> true\n *     C.private_method_defined? \"method1\"   #=> false\n *     C.private_method_defined? \"method2\"   #=> true\n *     C.method_defined? \"method2\"           #=> false\n */\n\nstatic VALUE\nrb_mod_private_method_defined(mod, mid)\n    VALUE mod, mid;\n{\n    ID id = rb_to_id(mid);\n    int noex;\n\n    if (rb_get_method_body(&mod, &id, &noex)) {\n        if (VISI_CHECK(noex, NOEX_PRIVATE))\n            return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     mod.protected_method_defined?(symbol)   => true or false\n *\n *  Returns +true+ if the named protected method is defined\n *  by _mod_ (or its included modules and, if _mod_ is a\n *  class, its ancestors).\n *\n *     module A\n *       def method1()  end\n *     end\n *     class B\n *       protected\n *       def method2()  end\n *     end\n *     class C < B\n *       include A\n *       def method3()  end\n *     end\n *\n *     A.method_defined? :method1              #=> true\n *     C.protected_method_defined? \"method1\"   #=> false\n *     C.protected_method_defined? \"method2\"   #=> true\n *     C.method_defined? \"method2\"             #=> true\n */\n\nstatic VALUE\nrb_mod_protected_method_defined(mod, mid)\n    VALUE mod, mid;\n{\n    ID id = rb_to_id(mid);\n    int noex;\n\n    if (rb_get_method_body(&mod, &id, &noex)) {\n        if (VISI_CHECK(noex, NOEX_PROTECTED))\n            return Qtrue;\n    }\n    return Qfalse;\n}\n\nNORETURN(static VALUE terminate_process _((int, VALUE)));\nstatic VALUE\nterminate_process(status, mesg)\n    int status;\n    VALUE mesg;\n{\n    VALUE args[2];\n    args[0] = INT2NUM(status);\n    args[1] = mesg;\n\n    rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));\n}\n\nvoid\nrb_exit(status)\n    int status;\n{\n    if (prot_tag) {\n        terminate_process(status, rb_str_new(\"exit\", 4));\n    }\n    ruby_finalize();\n    exit(status);\n}\n\n\n/*\n *  call-seq:\n *     exit(integer=0)\n *     Kernel::exit(integer=0)\n *     Process::exit(integer=0)\n *\n *  Initiates the termination of the Ruby script by raising the\n *  <code>SystemExit</code> exception. This exception may be caught. The\n *  optional parameter is used to return a status code to the invoking\n *  environment.\n *\n *     begin\n *       exit\n *       puts \"never get here\"\n *     rescue SystemExit\n *       puts \"rescued a SystemExit exception\"\n *     end\n *     puts \"after begin block\"\n *\n *  <em>produces:</em>\n *\n *     rescued a SystemExit exception\n *     after begin block\n *\n *  Just prior to termination, Ruby executes any <code>at_exit</code> functions\n *  (see Kernel::at_exit) and runs any object finalizers (see\n *  ObjectSpace::define_finalizer).\n *\n *     at_exit { puts \"at_exit function\" }\n *     ObjectSpace.define_finalizer(\"string\",  proc { puts \"in finalizer\" })\n *     exit\n *\n *  <em>produces:</em>\n *\n *     at_exit function\n *     in finalizer\n */\n\nVALUE\nrb_f_exit(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE status;\n    int istatus;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"01\", &status) == 1) {\n        switch (status) {\n          case Qtrue:\n            istatus = EXIT_SUCCESS;\n            break;\n          case Qfalse:\n            istatus = EXIT_FAILURE;\n            break;\n          default:\n            istatus = NUM2INT(status);\n#if EXIT_SUCCESS != 0\n            if (istatus == 0) istatus = EXIT_SUCCESS;\n#endif\n            break;\n        }\n    }\n    else {\n        istatus = EXIT_SUCCESS;\n    }\n    rb_exit(istatus);\n    return Qnil;                /* not reached */\n}\n\n\n/*\n *  call-seq:\n *     abort\n *     Kernel::abort\n *     Process::abort\n *\n *  Terminate execution immediately, effectively by calling\n *  <code>Kernel.exit(1)</code>. If _msg_ is given, it is written\n *  to STDERR prior to terminating.\n */\n\nVALUE\nrb_f_abort(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    rb_secure(4);\n    if (argc == 0) {\n        if (!NIL_P(ruby_errinfo)) {\n            error_print();\n        }\n        rb_exit(EXIT_FAILURE);\n    }\n    else {\n        VALUE mesg;\n\n        rb_scan_args(argc, argv, \"1\", &mesg);\n        StringValue(mesg);\n        rb_io_puts(1, &mesg, rb_stderr);\n        terminate_process(EXIT_FAILURE, mesg);\n    }\n    return Qnil;                /* not reached */\n}\n\nvoid\nrb_iter_break()\n{\n    break_jump(Qnil);\n}\n\nNORETURN(static void rb_longjmp _((volatile int, volatile VALUE)));\nstatic VALUE make_backtrace _((void));\n\nstatic void\nrb_longjmp(tag, mesg)\n    volatile int tag;\n    volatile VALUE mesg;\n{\n    VALUE at;\n    volatile rb_thread_t th = curr_thread;\n\n    if (rb_thread_set_raised(th)) {\n        ruby_errinfo = exception_error;\n        JUMP_TAG(TAG_FATAL);\n    }\n    if (NIL_P(mesg)) mesg = ruby_errinfo;\n    if (NIL_P(mesg)) {\n        mesg = rb_exc_new(rb_eRuntimeError, 0, 0);\n    }\n\n    ruby_set_current_source();\n    if (ruby_sourcefile && !NIL_P(mesg)) {\n        at = get_backtrace(mesg);\n        if (NIL_P(at) && !rb_thread_raised_p(th, RAISED_NOMEMORY)) {\n            at = make_backtrace();\n            if (OBJ_FROZEN(mesg)) {\n                mesg = rb_obj_dup(mesg);\n            }\n            set_backtrace(mesg, at);\n        }\n    }\n    if (!NIL_P(mesg)) {\n        ruby_errinfo = mesg;\n    }\n\n    if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)\n        && !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {\n        VALUE e = ruby_errinfo;\n        int status;\n\n        PUSH_TAG(PROT_EMPTY);\n        if ((status = EXEC_TAG()) == 0) {\n            StringValue(e);\n            warn_printf(\"Exception `%s' at %s:%d - %s\\n\",\n                        rb_obj_classname(ruby_errinfo),\n                        ruby_sourcefile, ruby_sourceline,\n                        RSTRING(e)->ptr);\n        }\n        POP_TAG();\n        if (status == TAG_FATAL && ruby_errinfo == exception_error) {\n            ruby_errinfo = mesg;\n        }\n        else if (status) {\n            rb_thread_reset_raised(th);\n            JUMP_TAG(status);\n        }\n    }\n\n    rb_trap_restore_mask();\n    if (tag != TAG_FATAL) {\n        EXEC_EVENT_HOOK(RUBY_EVENT_RAISE, ruby_current_node,\n                        ruby_frame->self,\n                        ruby_frame->last_func,\n                        ruby_frame->last_class);\n    }\n    if (!prot_tag) {\n        error_print();\n    }\n    rb_thread_raised_clear(th);\n    JUMP_TAG(tag);\n}\n\nvoid\nrb_exc_jump(mesg)\n    VALUE mesg;\n{\n    rb_thread_raised_clear(rb_curr_thread);\n    ruby_errinfo = mesg;\n    JUMP_TAG(TAG_RAISE);\n}\n\nvoid\nrb_exc_raise(mesg)\n    VALUE mesg;\n{\n    mesg = rb_make_exception(1, &mesg);\n    rb_longjmp(TAG_RAISE, mesg);\n}\n\nvoid\nrb_exc_fatal(mesg)\n    VALUE mesg;\n{\n    mesg = rb_make_exception(1, &mesg);\n    rb_longjmp(TAG_FATAL, mesg);\n}\n\nvoid\nrb_interrupt()\n{\n    static const char fmt[1] = {'\\0'};\n    rb_raise(rb_eInterrupt, fmt);\n}\n\n/*\n *  call-seq:\n *     raise\n *     raise(string)\n *     raise(exception [, string [, array]])\n *     fail\n *     fail(string)\n *     fail(exception [, string [, array]])\n *\n *  With no arguments, raises the exception in <code>$!</code> or raises\n *  a <code>RuntimeError</code> if <code>$!</code> is +nil+.\n *  With a single +String+ argument, raises a\n *  +RuntimeError+ with the string as a message. Otherwise,\n *  the first parameter should be the name of an +Exception+\n *  class (or an object that returns an +Exception+ object when sent\n *  an +exception+ message). The optional second parameter sets the\n *  message associated with the exception, and the third parameter is an\n *  array of callback information. Exceptions are caught by the\n *  +rescue+ clause of <code>begin...end</code> blocks.\n *\n *     raise \"Failed to create socket\"\n *     raise ArgumentError, \"No parameters\", caller\n */\n\nstatic VALUE\nrb_f_raise(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    rb_raise_jump(rb_make_exception(argc, argv));\n    return Qnil;                /* not reached */\n}\n\nstatic VALUE\nrb_make_exception(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE mesg;\n    ID exception;\n    int n;\n\n    mesg = Qnil;\n    switch (argc) {\n      case 0:\n        mesg = Qnil;\n        break;\n      case 1:\n        if (NIL_P(argv[0])) break;\n        if (TYPE(argv[0]) == T_STRING) {\n            mesg = rb_exc_new3(rb_eRuntimeError, argv[0]);\n            break;\n        }\n        n = 0;\n        goto exception_call;\n\n      case 2:\n      case 3:\n        n = 1;\n      exception_call:\n        exception = rb_intern(\"exception\");\n        if (!rb_respond_to(argv[0], exception)) {\n            rb_raise(rb_eTypeError, \"exception class/object expected\");\n        }\n        mesg = rb_funcall(argv[0], exception, n, argv[1]);\n        break;\n      default:\n        rb_raise(rb_eArgError, \"wrong number of arguments\");\n        break;\n    }\n    if (argc > 0) {\n        if (!rb_obj_is_kind_of(mesg, rb_eException))\n            rb_raise(rb_eTypeError, \"exception object expected\");\n        if (argc>2)\n            set_backtrace(mesg, argv[2]);\n    }\n\n    return mesg;\n}\n\nstatic void\nrb_raise_jump(mesg)\n    VALUE mesg;\n{\n    if (ruby_frame != top_frame) {\n        PUSH_FRAME();           /* fake frame */\n        *ruby_frame = *_frame.prev->prev;\n        rb_longjmp(TAG_RAISE, mesg);\n        POP_FRAME();\n    }\n    rb_longjmp(TAG_RAISE, mesg);\n}\n\nvoid\nrb_jump_tag(tag)\n    int tag;\n{\n    JUMP_TAG(tag);\n}\n\nint\nrb_block_given_p()\n{\n    if (ruby_frame->iter == ITER_CUR && ruby_block)\n        return Qtrue;\n    return Qfalse;\n}\n\nint\nrb_iterator_p()\n{\n    return rb_block_given_p();\n}\n\n/*\n *  call-seq:\n *     block_given?   => true or false\n *     iterator?      => true or false\n *\n *  Returns <code>true</code> if <code>yield</code> would execute a\n *  block in the current context. The <code>iterator?</code> form\n *  is mildly deprecated.\n *\n *     def try\n *       if block_given?\n *         yield\n *       else\n *         \"no block\"\n *       end\n *     end\n *     try                  #=> \"no block\"\n *     try { \"hello\" }      #=> \"hello\"\n *     try do \"hello\" end   #=> \"hello\"\n */\n\n\nstatic VALUE\nrb_f_block_given_p()\n{\n    if (ruby_frame->prev && ruby_frame->prev->iter == ITER_CUR && ruby_block)\n        return Qtrue;\n    return Qfalse;\n}\n\nVALUE rb_eThreadError;\n\nNORETURN(static void proc_jump_error(int, VALUE));\nstatic void\nproc_jump_error(state, result)\n    int state;\n    VALUE result;\n{\n    char mesg[32];\n    const char *statement;\n\n    switch (state) {\n      case TAG_BREAK:\n        statement = \"break\"; break;\n      case TAG_RETURN:\n        statement = \"return\"; break;\n      case TAG_RETRY:\n        statement = \"retry\"; break;\n      default:\n        statement = \"local-jump\"; break; /* should not happen */\n    }\n    snprintf(mesg, sizeof mesg, \"%s from proc-closure\", statement);\n    localjump_error(mesg, result, state);\n}\n\nstatic void\nreturn_jump(retval)\n    VALUE retval;\n{\n    struct tag *tt = prot_tag;\n    int yield = Qfalse;\n\n    if (retval == Qundef) retval = Qnil;\n    while (tt) {\n        if (tt->tag == PROT_YIELD) {\n            yield = Qtrue;\n            tt = tt->prev;\n        }\n        if (tt->tag == PROT_FUNC && tt->frame->uniq == ruby_frame->uniq) {\n            tt->dst = (VALUE)ruby_frame->uniq;\n            tt->retval = retval;\n            JUMP_TAG(TAG_RETURN);\n        }\n        if (tt->tag == PROT_LAMBDA && !yield) {\n            tt->dst = (VALUE)tt->frame->uniq;\n            tt->retval = retval;\n            JUMP_TAG(TAG_RETURN);\n        }\n        if (tt->tag == PROT_THREAD) {\n            rb_raise(rb_eThreadError, \"return can't jump across threads\");\n        }\n        tt = tt->prev;\n    }\n    localjump_error(\"unexpected return\", retval, TAG_RETURN);\n}\n\nstatic void\nbreak_jump(retval)\n    VALUE retval;\n{\n    struct tag *tt = prot_tag;\n\n    if (retval == Qundef) retval = Qnil;\n    while (tt) {\n        switch (tt->tag) {\n          case PROT_THREAD:\n          case PROT_YIELD:\n          case PROT_LOOP:\n          case PROT_LAMBDA:\n            tt->dst = (VALUE)tt->frame->uniq;\n            tt->retval = retval;\n            JUMP_TAG(TAG_BREAK);\n            break;\n          case PROT_FUNC:\n            tt = 0;\n            continue;\n          default:\n            break;\n        }\n        tt = tt->prev;\n    }\n    localjump_error(\"unexpected break\", retval, TAG_BREAK);\n}\n\nstatic void\nnext_jump(retval)\n    VALUE retval;\n{\n    struct tag *tt = prot_tag;\n\n    if (retval == Qundef) retval = Qnil;\n    while (tt) {\n        switch (tt->tag) {\n          case PROT_THREAD:\n          case PROT_YIELD:\n          case PROT_LOOP:\n          case PROT_LAMBDA:\n          case PROT_FUNC:\n            tt->dst = (VALUE)tt->frame->uniq;\n            tt->retval = retval;\n            JUMP_TAG(TAG_NEXT);\n            break;\n          default:\n            break;\n        }\n        tt = tt->prev;\n    }\n    localjump_error(\"unexpected next\", retval, TAG_NEXT);\n}\n\nvoid\nrb_need_block()\n{\n    if (!rb_block_given_p()) {\n        localjump_error(\"no block given\", Qnil, 0);\n    }\n}\n\nstatic VALUE\nrb_yield_0(val, self, klass, flags, avalue)\n    volatile VALUE val, self;\n    VALUE klass;\n    int flags;\n    volatile int avalue;\n{\n    NODE *var, *volatile node;\n    volatile VALUE result = Qnil;\n    volatile VALUE old_cref;\n    volatile VALUE old_wrapper;\n    struct BLOCK * volatile block;\n    struct SCOPE * volatile old_scope;\n    volatile int old_vmode;\n    struct FRAME frame;\n    NODE *cnode = ruby_current_node;\n    volatile int lambda = flags & YIELD_LAMBDA_CALL;\n    int state;\n\n    rb_need_block();\n\n    PUSH_VARS();\n    block = ruby_block;\n    frame = block->frame;\n    frame.prev = ruby_frame;\n    frame.node = cnode;\n    CREATE_FRAME_SOURCE_POS(&frame);\n    ruby_frame = &(frame);\n    old_cref = (VALUE)ruby_cref;\n    ruby_cref = block->cref;\n    old_wrapper = ruby_wrapper;\n    ruby_wrapper = block->wrapper;\n    old_scope = ruby_scope;\n    ruby_scope = block->scope;\n    old_vmode = scope_vmode;\n    scope_vmode = (flags & YIELD_PUBLIC_DEF) ? SCOPE_PUBLIC : block->vmode;\n    ruby_block = block->prev;\n    if (block->flags & BLOCK_D_SCOPE) {\n        /* put place holder for dynamic (in-block) local variables */\n        ruby_dyna_vars = new_dvar(0, 0, block->dyna_vars);\n    }\n    else {\n        /* FOR does not introduce new scope */\n        ruby_dyna_vars = block->dyna_vars;\n    }\n    PUSH_CLASS(klass ? klass : block->klass);\n    if (!klass) {\n        self = block->self;\n    }\n    node = block->body;\n    var = block->var;\n\n    if (var) {\n        PUSH_TAG(PROT_EMPTY);\n        if ((state = EXEC_TAG()) == 0) {\n            NODE *bvar = NULL;\n          block_var:\n            if (var == (NODE*)1) { /* no parameter || */\n                if (lambda && RARRAY(val)->len != 0) {\n                    rb_raise(rb_eArgError, \"wrong number of arguments (%ld for 0)\",\n                             RARRAY(val)->len);\n                }\n            }\n            else if (var == (NODE*)2) {\n                if (TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {\n                    rb_raise(rb_eArgError, \"wrong number of arguments (%ld for 0)\",\n                             RARRAY(val)->len);\n                }\n            }\n            else if (!bvar && nd_type(var) == NODE_BLOCK_PASS) {\n                bvar = var->nd_body;\n                var = var->nd_args;\n                goto block_var;\n            }\n            else if (nd_type(var) == NODE_MASGN) {\n                if (!avalue) {\n                    val = svalue_to_mrhs(val, var->nd_head);\n                }\n                massign(self, var, val, lambda);\n            }\n            else {\n                int len = 0;\n                if (avalue) {\n                    len = RARRAY(val)->len;\n                    if (len == 0) {\n                        goto zero_arg;\n                    }\n                    if (len == 1) {\n                        val = RARRAY(val)->ptr[0];\n                    }\n                    else {\n                        goto multi_values;\n                    }\n                }\n                else if (val == Qundef) {\n                  zero_arg:\n                    val = Qnil;\n                  multi_values:\n                    {\n                        ruby_current_node = var;\n                        rb_warn(\"multiple values for a block parameter (%d for 1)\\n\\tfrom %s:%d\",\n                                len, cnode->nd_file, nd_line(cnode));\n                        ruby_current_node = cnode;\n                    }\n                }\n                assign(self, var, val, lambda);\n            }\n            if (bvar) {\n                VALUE blk;\n                if (flags & YIELD_PROC_CALL)\n                    blk = block->block_obj;\n                else\n                    blk = rb_block_proc();\n                assign(self, bvar, blk, 0);\n            }\n        }\n        POP_TAG();\n        if (state) goto pop_state;\n    }\n    if (!node) {\n        state = 0;\n        goto pop_state;\n    }\n    ruby_current_node = node;\n\n    PUSH_ITER(block->iter);\n    PUSH_TAG(lambda ? PROT_EMPTY : PROT_YIELD);\n    switch (state = EXEC_TAG()) {\n      case TAG_REDO:\n        state = 0;\n        CHECK_INTS;\n      case 0:\n        if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {\n          switch (node->nd_state) {\n            case YIELD_FUNC_LAMBDA:\n              if (!avalue) {\n                  val = (val == Qundef) ? rb_ary_new2(0) : rb_ary_new3(1, val);\n              }\n              break;\n            case YIELD_FUNC_AVALUE:\n              if (!avalue) {\n                  val = svalue_to_avalue(val);\n              }\n              break;\n            default:\n              if (avalue) {\n                  val = avalue_to_svalue(val);\n              }\n              if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE)\n                  val = Qnil;\n            }\n            result = (*node->nd_cfnc)(val, node->nd_tval, self);\n         }else\n            result = rb_eval(self, node);\n          break;\n        case TAG_NEXT:\n          if (!lambda) {\n              state = 0;\n              result = prot_tag->retval;\n          }\n          break;\n        case TAG_BREAK:\n          if (TAG_DST()) {\n              result = prot_tag->retval;\n          }\n          else {\n              lambda = Qtrue;   /* just pass TAG_BREAK */\n          }\n        default:\n          break;\n    }\n    POP_TAG();\n    POP_ITER();\n  pop_state:\n    POP_CLASS();\n    if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&\n        !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {\n        struct RVarmap *vars = ruby_dyna_vars;\n\n        if (ruby_dyna_vars->id == 0) {\n            vars = ruby_dyna_vars->next;\n            rb_gc_force_recycle((VALUE)ruby_dyna_vars);\n            while (vars && vars->id != 0 && vars != block->dyna_vars) {\n                struct RVarmap *tmp = vars->next;\n                rb_gc_force_recycle((VALUE)vars);\n                vars = tmp;\n            }\n        }\n    }\n    POP_VARS();\n    ruby_block = block;\n    ruby_frame = ruby_frame->prev;\n    ruby_cref = (NODE*)old_cref;\n    ruby_wrapper = old_wrapper;\n    if (ruby_scope->flags & SCOPE_DONT_RECYCLE)\n        scope_dup(old_scope);\n    ruby_scope = old_scope;\n    scope_vmode = old_vmode;\n    switch (state) {\n      case 0:\n        break;\n      case TAG_BREAK:\n        if (!lambda) {\n            struct tag *tt = prot_tag;\n\n            while (tt) {\n                if (tt->tag == PROT_LOOP && tt->blkid == ruby_block->uniq) {\n                    tt->dst = (VALUE)tt->frame->uniq;\n                    tt->retval = result;\n                    JUMP_TAG(TAG_BREAK);\n                }\n                tt = tt->prev;\n            }\n            proc_jump_error(TAG_BREAK, result);\n        }\n        /* fall through */\n      default:\n        JUMP_TAG(state);\n        break;\n    }\n    ruby_current_node = cnode;\n    return result;\n}\n\nVALUE\nrb_yield(val)\n    VALUE val;\n{\n    wipeBeforeYield();\n    return rb_yield_0(val, 0, 0, 0, Qfalse);\n}\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_yield_values(int n, ...)\n#else\nrb_yield_values(n, va_alist)\n    int n;\n    va_dcl\n#endif\n{\n    va_list args;\n    VALUE ary;\n\n    if (n == 0) {\n        return rb_yield_0(Qundef, 0, 0, 0, Qfalse);\n    }\n    ary = rb_ary_new2(n);\n    va_init_list(args, n);\n    while (n--) {\n        rb_ary_push(ary, va_arg(args, VALUE));\n    }\n    va_end(args);\n    return rb_yield_0(ary, 0, 0, 0, Qtrue);\n}\n\nVALUE\nrb_yield_splat(values)\n    VALUE values;\n{\n    int avalue = Qfalse;\n\n    if (TYPE(values) == T_ARRAY) {\n        if (RARRAY(values)->len == 0) {\n            values = Qundef;\n        }\n        else {\n            avalue = Qtrue;\n        }\n    }\n    return rb_yield_0(values, 0, 0, 0, avalue);\n}\n\nstatic VALUE\nloop_i()\n{\n    for (;;) {\n        wipeBeforeYield();\n        rb_yield_0(Qundef, 0, 0, 0, Qfalse);\n        CHECK_INTS;\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     loop {|| block }\n *\n *  Repeatedly executes the block.\n *\n *     loop do\n *       print \"Input: \"\n *       line = gets\n *       break if !line or line =~ /^qQ/\n *       # ...\n *     end\n *\n *  StopIteration raised in the block breaks the loop.\n */\n\nstatic VALUE\nrb_f_loop()\n{\n    rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);\n    return Qnil;                /* dummy */\n}\n\nstatic VALUE\nmassign(self, node, val, pcall)\n    VALUE self;\n    NODE *node;\n    VALUE val;\n    int pcall;\n{\n    NODE *list;\n    long i = 0, len;\n\n    len = RARRAY(val)->len;\n    list = node->nd_head;\n    for (; list && i<len; i++) {\n        assign(self, list->nd_head, RARRAY(val)->ptr[i], pcall);\n        list = list->nd_next;\n    }\n    if (pcall && list) goto arg_error;\n    if (node->nd_args) {\n        if ((long)(node->nd_args) == -1) {\n            /* no check for mere `*' */\n        }\n        else if (!list && i<len) {\n            assign(self, node->nd_args, rb_ary_new4(len-i, RARRAY(val)->ptr+i), pcall);\n        }\n        else {\n            assign(self, node->nd_args, rb_ary_new2(0), pcall);\n        }\n    }\n    else if (pcall && i < len) {\n        goto arg_error;\n    }\n\n    while (list) {\n        i++;\n        assign(self, list->nd_head, Qnil, pcall);\n        list = list->nd_next;\n    }\n    return val;\n\n  arg_error:\n    while (list) {\n        i++;\n        list = list->nd_next;\n    }\n    rb_raise(rb_eArgError, \"wrong number of arguments (%ld for %ld)\", len, i);\n}\n\nstatic void\nassign(self, lhs, val, pcall)\n    VALUE self;\n    NODE *lhs;\n    VALUE val;\n    int pcall;\n{\n    ruby_current_node = lhs;\n    if (val == Qundef) {\n        rb_warning(\"assigning void value\");\n        val = Qnil;\n    }\n    switch (nd_type(lhs)) {\n      case NODE_GASGN:\n        ruby_in_longlife_context++;\n        rb_gvar_set(lhs->nd_entry, val);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_IASGN:\n        rb_ivar_set(self, lhs->nd_vid, val);\n        break;\n\n      case NODE_LASGN:\n        if (ruby_scope->local_vars == 0)\n            rb_bug(\"unexpected local variable assignment\");\n        ruby_scope->local_vars[lhs->nd_cnt] = val;\n        break;\n\n      case NODE_DASGN:\n        dvar_asgn(lhs->nd_vid, val);\n        break;\n\n      case NODE_DASGN_CURR:\n        dvar_asgn_curr(lhs->nd_vid, val);\n        break;\n\n      case NODE_CDECL:\n        ruby_in_longlife_context++;\n        if (lhs->nd_vid == 0) {\n            rb_const_set(class_prefix(self, lhs->nd_else), lhs->nd_else->nd_mid, val);\n        }\n        else {\n            rb_const_set(ruby_cbase, lhs->nd_vid, val);\n        }\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_CVDECL:\n        ruby_in_longlife_context++;\n        if (RTEST(ruby_verbose) && FL_TEST(ruby_cbase, FL_SINGLETON)) {\n            rb_warn(\"declaring singleton class variable\");\n        }\n        rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qtrue);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_CVASGN:\n        ruby_in_longlife_context++;\n        rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qfalse);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_MASGN:\n        ruby_in_longlife_context++;\n        massign(self, lhs, svalue_to_mrhs(val, lhs->nd_head), pcall);\n        ruby_in_longlife_context--;\n        break;\n\n      case NODE_CALL:\n      case NODE_ATTRASGN:\n        {\n            VALUE recv;\n            int scope;\n            if (lhs->nd_recv == (NODE *)1) {\n                recv = self;\n                scope = 1;\n            }\n            else {\n                recv = rb_eval(self, lhs->nd_recv);\n                scope = 0;\n            }\n            if (!lhs->nd_args) {\n                /* attr set */\n                ruby_current_node = lhs;\n                GC_DEBUG_SET_SOURCE\n                rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, scope, self);\n            }\n            else {\n                /* array set */\n                VALUE args;\n\n                args = rb_eval(self, lhs->nd_args);\n                rb_ary_push(args, val);\n                ruby_current_node = lhs;\n                GC_DEBUG_SET_SOURCE\n                rb_call(CLASS_OF(recv), recv, lhs->nd_mid,\n                        RARRAY(args)->len, RARRAY(args)->ptr, scope, self);\n            }\n        }\n        break;\n\n      default:\n        rb_bug(\"bug in variable assignment\");\n        break;\n    }\n}\n\nVALUE\nrb_iterate(it_proc, data1, bl_proc, data2)\n    VALUE (* volatile it_proc) _((VALUE)), (*bl_proc)(ANYARGS);\n    volatile VALUE data1;\n    VALUE data2;\n{\n    int state;\n    VALUE retval;\n    NODE *node = NEW_IFUNC(bl_proc, data2);\n    VALUE self = ruby_top_self;\n\n    PUSH_TAG(PROT_LOOP);\n    PUSH_BLOCK(0, node);\n    PUSH_ITER(ITER_PRE);\n    state = EXEC_TAG();\n    if (state == 0) {\n  iter_retry:\n        retval = (*it_proc)(data1);\n    }\n    else if (state == TAG_BREAK && TAG_DST()) {\n        retval = prot_tag->retval;\n        state = 0;\n    }\n    else if (state == TAG_RETRY) {\n        state = 0;\n        goto iter_retry;\n    }\n    POP_ITER();\n    POP_BLOCK();\n    POP_TAG();\n\n    if (state) JUMP_TAG(state);\n    return retval;\n}\n\nstatic int\nhandle_rescue(self, node)\n    VALUE self;\n    NODE *node;\n{\n    int argc; VALUE *argv; /* used in SETUP_ARGS */\n    TMP_PROTECT;\n\n    if (!node->nd_args) {\n        return rb_obj_is_kind_of(ruby_errinfo, rb_eStandardError);\n    }\n\n    BEGIN_CALLARGS;\n    SETUP_ARGS(node->nd_args);\n    END_CALLARGS;\n\n    while (argc--) {\n        if (!rb_obj_is_kind_of(argv[0], rb_cModule)) {\n            rb_raise(rb_eTypeError, \"class or module required for rescue clause\");\n        }\n        if (RTEST(rb_funcall(*argv, eqq, 1, ruby_errinfo))) return 1;\n        argv++;\n    }\n    return 0;\n}\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_rescue2(VALUE (* volatile b_proc)(ANYARGS), volatile VALUE data1,\n           VALUE (* volatile r_proc)(ANYARGS), volatile VALUE data2, ...)\n#else\nrb_rescue2(b_proc, data1, r_proc, data2, va_alist)\n    VALUE (* volatile b_proc)(ANYARGS), (* volatile r_proc)(ANYARGS);\n    volatile VALUE data1, data2;\n    va_dcl\n#endif\n{\n    int state;\n    VALUE result;\n    volatile VALUE e_info = ruby_errinfo;\n    volatile int handle = Qfalse;\n    VALUE eclass;\n    va_list args;\n\n    PUSH_TAG(PROT_EMPTY);\n    switch (state = EXEC_TAG()) {\n      case TAG_RETRY:\n        if (!handle) break;\n        handle = Qfalse;\n        state = 0;\n        ruby_errinfo = Qnil;\n      case 0:\n        result = (*b_proc)(data1);\n        break;\n      case TAG_RAISE:\n        if (handle) break;\n        handle = Qfalse;\n        va_init_list(args, data2);\n        while ((eclass = va_arg(args, VALUE)) != 0) {\n            if (rb_obj_is_kind_of(ruby_errinfo, eclass)) {\n                handle = Qtrue;\n                break;\n            }\n        }\n        va_end(args);\n\n        if (handle) {\n            state = 0;\n            if (r_proc) {\n                result = (*r_proc)(data2, ruby_errinfo);\n            }\n            else {\n                result = Qnil;\n            }\n            ruby_errinfo = e_info;\n        }\n    }\n    POP_TAG();\n    if (state) JUMP_TAG(state);\n\n    return result;\n}\n\nVALUE\nrb_rescue(b_proc, data1, r_proc, data2)\n    VALUE (*b_proc)(), (*r_proc)();\n    VALUE data1, data2;\n{\n    return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError, (VALUE)0);\n}\n\nstatic VALUE cont_protect;\n\nVALUE\nrb_protect(proc, data, state)\n    VALUE (*proc) _((VALUE));\n    VALUE data;\n    int * volatile state;\n{\n    VALUE result;\n    int status;\n\n    PUSH_TAG(PROT_EMPTY);\n    cont_protect = (VALUE)NEW_NODE_EDEN(NODE_MEMO, cont_protect, 0, 0);\n    if ((status = EXEC_TAG()) == 0) {\n        result = (*proc)(data);\n    }\n    cont_protect = ((NODE *)cont_protect)->u1.value;\n    POP_TAG();\n    if (state) {\n        *state = status;\n    }\n    return status ? Qnil : result;\n}\n\nVALUE\nrb_ensure(b_proc, data1, e_proc, data2)\n    VALUE (*b_proc)();\n    VALUE data1;\n    VALUE (* volatile e_proc)();\n    volatile VALUE data2;\n{\n    int state;\n    VALUE result;\n    VALUE retval;\n\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        result = (*b_proc)(data1);\n    }\n    POP_TAG();\n    if (prot_tag) retval = prot_tag->retval;  /* save retval */\n    if (!thread_no_ensure()) {\n        (*e_proc)(data2);\n    }\n    if (prot_tag) return_value(retval);\n    if (state) JUMP_TAG(state);\n    return result;\n}\n\nVALUE\nrb_with_disable_interrupt(proc, data)\n    VALUE (*proc)();\n    VALUE data;\n{\n    VALUE result;\n    int status;\n\n    DEFER_INTS;\n    {\n        int thr_critical = rb_thread_critical;\n\n        rb_thread_critical = Qtrue;\n        PUSH_TAG(PROT_EMPTY);\n        if ((status = EXEC_TAG()) == 0) {\n            result = (*proc)(data);\n        }\n        POP_TAG();\n        rb_thread_critical = thr_critical;\n    }\n    ENABLE_INTS;\n    if (status) JUMP_TAG(status);\n\n    return result;\n}\n\nstatic void\nstack_check()\n{\n    rb_thread_t th = rb_curr_thread;\n\n    if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) && ruby_stack_check()) {\n        rb_thread_raised_set(th, RAISED_STACKOVERFLOW);\n        rb_exc_raise(sysstack_error);\n    }\n}\n\nstatic void\neval_check_tick()\n{\n    static int tick;\n    if ((++tick & 0xff) == 0) {\n        CHECK_INTS;             /* better than nothing */\n        stack_check();\n    }\n}\n\nstatic int last_call_status;\n\n#define CSTAT_PRIV  1\n#define CSTAT_PROT  2\n#define CSTAT_VCALL 4\n#define CSTAT_SUPER 8\n\n/*\n *  call-seq:\n *     obj.method_missing(symbol [, *args] )   => result\n *\n *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.\n *  <i>symbol</i> is the symbol for the method called, and <i>args</i>\n *  are any arguments that were passed to it. By default, the interpreter\n *  raises an error when this method is called. However, it is possible\n *  to override the method to provide more dynamic behavior.\n *  The example below creates\n *  a class <code>Roman</code>, which responds to methods with names\n *  consisting of roman numerals, returning the corresponding integer\n *  values.\n *\n *     class Roman\n *       def romanToInt(str)\n *         # ...\n *       end\n *       def method_missing(methId)\n *         str = methId.id2name\n *         romanToInt(str)\n *       end\n *     end\n *\n *     r = Roman.new\n *     r.iv      #=> 4\n *     r.xxiii   #=> 23\n *     r.mm      #=> 2000\n */\n\nstatic VALUE\nrb_method_missing(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    ID id;\n    VALUE exc = rb_eNoMethodError;\n    const char *format = 0;\n    NODE *cnode = ruby_current_node;\n\n    if (argc == 0 || !SYMBOL_P(argv[0])) {\n        rb_raise(rb_eArgError, \"no id given\");\n    }\n\n    stack_check();\n\n    id = SYM2ID(argv[0]);\n\n    if (last_call_status & CSTAT_PRIV) {\n        format = \"private method `%s' called for %s\";\n    }\n    else if (last_call_status & CSTAT_PROT) {\n        format = \"protected method `%s' called for %s\";\n    }\n    else if (last_call_status & CSTAT_VCALL) {\n        format = \"undefined local variable or method `%s' for %s\";\n        exc = rb_eNameError;\n    }\n    else if (last_call_status & CSTAT_SUPER) {\n        format = \"super: no superclass method `%s' for %s\";\n    }\n    if (!format) {\n        format = \"undefined method `%s' for %s\";\n    }\n\n    ruby_current_node = cnode;\n    {\n        int n = 0;\n        VALUE args[3];\n\n        args[n++] = rb_funcall(rb_const_get(exc, rb_intern(\"message\")), '!',\n                               3, rb_str_new2(format), obj, argv[0]);\n        args[n++] = argv[0];\n        if (exc == rb_eNoMethodError) {\n            args[n++] = rb_ary_new4(argc-1, argv+1);\n        }\n        exc = rb_class_new_instance(n, args, exc);\n        ruby_frame = ruby_frame->prev; /* pop frame for \"method_missing\" */\n        rb_exc_raise(exc);\n    }\n\n    return Qnil;                /* not reached */\n}\n\nstatic VALUE\nmethod_missing(obj, id, argc, argv, call_status)\n    VALUE obj;\n    ID    id;\n    int   argc;\n    const VALUE *argv;\n    int   call_status;\n{\n    VALUE *nargv;\n\n    last_call_status = call_status;\n\n    if (id == missing) {\n        PUSH_FRAME();\n        rb_method_missing(argc, argv, obj);\n        POP_FRAME();\n    }\n    else if (id == ID_ALLOCATOR) {\n        rb_raise(rb_eTypeError, \"allocator undefined for %s\", rb_class2name(obj));\n    }\n    if (argc < 0) {\n        VALUE tmp;\n\n        argc = -argc-1;\n        tmp = splat_value(argv[argc]);\n        nargv = ALLOCA_N(VALUE, argc + RARRAY(tmp)->len + 1);\n        MEMCPY(nargv+1, argv, VALUE, argc);\n        MEMCPY(nargv+1+argc, RARRAY(tmp)->ptr, VALUE, RARRAY(tmp)->len);\n        argc += RARRAY(tmp)->len;\n    }\n    else {\n        nargv = ALLOCA_N(VALUE, argc+1);\n        MEMCPY(nargv+1, argv, VALUE, argc);\n    }\n    nargv[0] = ID2SYM(id);\n    return rb_funcall2(obj, missing, argc+1, nargv);\n}\n\nstatic inline VALUE\ncall_cfunc(func, recv, len, argc, argv)\n    VALUE (*func)();\n    VALUE recv;\n    int len, argc;\n    VALUE *argv;\n{\n    if (len >= 0 && argc != len) {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for %d)\",\n                 argc, len);\n    }\n\n    switch (len) {\n      case -2:\n        return (*func)(recv, rb_ary_new4(argc, argv));\n        break;\n      case -1:\n        return (*func)(argc, argv, recv);\n        break;\n      case 0:\n        return (*func)(recv);\n        break;\n      case 1:\n        return (*func)(recv, argv[0]);\n        break;\n      case 2:\n        return (*func)(recv, argv[0], argv[1]);\n        break;\n      case 3:\n        return (*func)(recv, argv[0], argv[1], argv[2]);\n        break;\n      case 4:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);\n        break;\n      case 5:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);\n        break;\n      case 6:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5]);\n        break;\n      case 7:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6]);\n        break;\n      case 8:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7]);\n        break;\n      case 9:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8]);\n        break;\n      case 10:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8], argv[9]);\n        break;\n      case 11:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);\n        break;\n      case 12:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8], argv[9],\n                       argv[10], argv[11]);\n        break;\n      case 13:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],\n                       argv[11], argv[12]);\n        break;\n      case 14:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],\n                       argv[11], argv[12], argv[13]);\n        break;\n      case 15:\n        return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],\n                       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],\n                       argv[11], argv[12], argv[13], argv[14]);\n        break;\n      default:\n        rb_raise(rb_eArgError, \"too many arguments (%d)\", len);\n        break;\n    }\n    return Qnil;                /* not reached */\n}\n\nstatic VALUE\nrb_call0(klass, recv, id, oid, argc, argv, body, flags)\n    volatile VALUE klass, recv;\n    volatile ID    id;\n    ID    oid;\n    int argc;\n    VALUE *argv;\n    NODE *body;\n    int flags;\n{\n    NODE *b2;           /* OK */\n    VALUE result;\n    int itr;\n    TMP_PROTECT;\n    volatile int safe = -1;\n\n    if (NOEX_SAFE(flags) > ruby_safe_level && NOEX_SAFE(flags) > 2) {\n        rb_raise(rb_eSecurityError, \"calling insecure method: %s\",\n                 rb_id2name(id));\n    }\n    switch (ruby_iter->iter) {\n      case ITER_PRE:\n      case ITER_PAS:\n        itr = ITER_CUR;\n        break;\n      case ITER_CUR:\n      default:\n        itr = ITER_NOT;\n        break;\n    }\n\n    eval_check_tick();\n    if (argc < 0) {\n        VALUE tmp;\n        VALUE *nargv;\n\n        argc = -argc-1;\n        tmp = splat_value(argv[argc]);\n        nargv = TMP_ALLOC(argc + RARRAY(tmp)->len);\n        MEMCPY(nargv, argv, VALUE, argc);\n        MEMCPY(nargv+argc, RARRAY(tmp)->ptr, VALUE, RARRAY(tmp)->len);\n        argc += RARRAY(tmp)->len;\n        argv = nargv;\n    }\n    PUSH_ITER(itr);\n    PUSH_FRAME();\n\n    ruby_frame->last_func = id;\n    ruby_frame->orig_func = oid;\n    ruby_frame->last_class = (flags & NOEX_NOSUPER)?0:klass;\n    ruby_frame->self = recv;\n    ruby_frame->argc = argc;\n    ruby_frame->flags = 0;\n\n    switch (nd_type(body)) {\n      case NODE_CFUNC:\n        {\n            int len = body->nd_argc;\n\n            if (len < -2) {\n                rb_bug(\"bad argc (%d) specified for `%s(%s)'\",\n                       len, rb_class2name(klass), rb_id2name(id));\n            }\n            if (event_hooks) {\n                int state;\n\n                EXEC_EVENT_HOOK(RUBY_EVENT_C_CALL, ruby_current_node,\n                                recv, id, klass);\n                PUSH_TAG(PROT_FUNC);\n                if ((state = EXEC_TAG()) == 0) {\n                    result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);\n                }\n                POP_TAG();\n                ruby_current_node = ruby_frame->node;\n                EXEC_EVENT_HOOK(RUBY_EVENT_C_RETURN, ruby_current_node,\n                                recv, id, klass);\n                if (state) JUMP_TAG(state);\n            }\n            else {\n                result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);\n            }\n        }\n        break;\n\n        /* for attr get/set */\n      case NODE_IVAR:\n        if (argc != 0) {\n            rb_raise(rb_eArgError, \"wrong number of arguments (%d for 0)\", argc);\n        }\n        result = rb_attr_get(recv, body->nd_vid);\n        break;\n\n      case NODE_ATTRSET:\n        if (argc != 1)\n            rb_raise(rb_eArgError, \"wrong number of arguments (%d for 1)\", argc);\n        result = rb_ivar_set(recv, body->nd_vid, argv[0]);\n        break;\n\n      case NODE_ZSUPER:\n        result = rb_call_super(argc, argv);\n        break;\n\n      case NODE_DMETHOD:\n        result = method_call(argc, argv, umethod_bind(body->nd_cval, recv));\n        break;\n\n      case NODE_BMETHOD:\n        ruby_frame->flags |= FRAME_DMETH;\n        if (event_hooks) {\n            struct BLOCK *data;\n            Data_Get_Struct(body->nd_cval, struct BLOCK, data);\n            EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);\n        }\n        result = proc_invoke(body->nd_cval, rb_ary_new4(argc,argv), recv,klass);\n        if (event_hooks) {\n            EXEC_EVENT_HOOK(RUBY_EVENT_RETURN,\n                            ruby_current_node, recv, id, klass);\n        }\n        break;\n\n      case NODE_SCOPE:\n        {\n            int state;\n            VALUE *local_vars;  /* OK */\n            NODE * volatile saved_cref = 0;\n\n            PUSH_SCOPE();\n            if (body->nd_rval) {\n                saved_cref = ruby_cref;\n                ruby_cref = (NODE*)body->nd_rval;\n            }\n            PUSH_CLASS(ruby_cbase);\n            if (body->nd_tbl) {\n                local_vars = TMP_ALLOC(body->nd_tbl[0]+1);\n                *local_vars++ = (VALUE)body;\n                rb_mem_clear(local_vars, body->nd_tbl[0]);\n                ruby_scope->local_tbl = body->nd_tbl;\n                ruby_scope->local_vars = local_vars;\n            }\n            else {\n                local_vars = ruby_scope->local_vars = 0;\n                ruby_scope->local_tbl  = 0;\n            }\n            b2 = body = body->nd_next;\n\n            if (NOEX_SAFE(flags) > ruby_safe_level) {\n                safe = ruby_safe_level;\n                ruby_safe_level = NOEX_SAFE(flags);\n            }\n            PUSH_VARS();\n            PUSH_TAG(PROT_FUNC);\n            if ((state = EXEC_TAG()) == 0) {\n                NODE *node = 0;\n                int i, nopt = 0;\n\n                if (nd_type(body) == NODE_ARGS) {\n                    node = body;\n                    body = 0;\n                }\n                else if (nd_type(body) == NODE_BLOCK) {\n                    node = body->nd_head;\n                    body = body->nd_next;\n                }\n                if (node) {\n                    if (nd_type(node) != NODE_ARGS) {\n                        rb_bug(\"no argument-node\");\n                    }\n\n                    i = node->nd_cnt;\n                    if (i > argc) {\n                        rb_raise(rb_eArgError,\n                                 \"wrong number of arguments (%d for %d)\",\n                                 argc, i);\n                    }\n                    if (!node->nd_rest) {\n                        NODE *optnode = node->nd_opt;\n\n                        nopt = i;\n                        while (optnode) {\n                            nopt++;\n                            optnode = optnode->nd_next;\n                        }\n                        if (nopt < argc) {\n                            rb_raise(rb_eArgError,\n                                     \"wrong number of arguments (%d for %d)\",\n                                     argc, nopt);\n                        }\n                    }\n                    if (local_vars) {\n                        if (i > 0) {\n                            /* +2 for $_ and $~ */\n                            MEMCPY(local_vars+2, argv, VALUE, i);\n                        }\n                    }\n                    argv += i; argc -= i;\n                    if (node->nd_opt) {\n                        NODE *opt = node->nd_opt;\n\n                        while (opt && argc) {\n                            assign(recv, opt->nd_head, *argv, 1);\n                            argv++; argc--;\n                            ++i;\n                            opt = opt->nd_next;\n                        }\n                        if (opt) {\n                            rb_eval(recv, opt);\n                            while (opt) {\n                                opt = opt->nd_next;\n                                ++i;\n                            }\n                        }\n                    }\n                    if (!node->nd_rest) {\n                        i = nopt;\n                    }\n                    else {\n                        VALUE v;\n\n                        if (argc > 0) {\n                            v = rb_ary_new4(argc,argv);\n                            i = -i - 1;\n                        }\n                        else {\n                            v = rb_ary_new2(0);\n                        }\n                        assign(recv, node->nd_rest, v, 1);\n                    }\n                    ruby_frame->argc = i;\n                }\n                if (event_hooks) {\n                    EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass);\n                }\n                result = rb_eval(recv, body);\n            }\n            else if (state == TAG_RETURN && TAG_DST()) {\n                result = prot_tag->retval;\n                state = 0;\n            }\n            POP_TAG();\n            if (event_hooks) {\n                EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node,\n                                recv, id, klass);\n            }\n            POP_VARS();\n            POP_CLASS();\n            POP_SCOPE();\n            ruby_cref = saved_cref;\n            if (safe >= 0) ruby_safe_level = safe;\n            switch (state) {\n              case 0:\n                break;\n\n              case TAG_BREAK:\n              case TAG_RETURN:\n                JUMP_TAG(state);\n                break;\n\n              case TAG_RETRY:\n                if (rb_block_given_p()) JUMP_TAG(state);\n                /* fall through */\n              default:\n                jump_tag_but_local_jump(state, result);\n                break;\n            }\n        }\n        break;\n\n      default:\n        unknown_node(body);\n    }\n    POP_FRAME();\n    POP_ITER();\n    return result;\n}\n\nstatic VALUE\nrb_call(klass, recv, mid, argc, argv, scope, self)\n    VALUE klass, recv;\n    ID    mid;\n    int argc;                   /* OK */\n    const VALUE *argv;          /* OK */\n    int scope;\n    VALUE self;\n{\n    NODE  *body;                /* OK */\n    int    noex;\n    ID     id = mid;\n    struct cache_entry *ent;\n\n    if (!klass) {\n        rb_raise(rb_eNotImpError, \"method `%s' called on terminated object (0x%lx)\",\n                 rb_id2name(mid), recv);\n    }\n    /* is it in the method cache? */\n    ent = cache + EXPR1(klass, mid);\n    if (ent->mid == mid && ent->klass == klass) {\n        if (!ent->method)\n            goto nomethod;\n        klass = ent->origin;\n        id    = ent->mid0;\n        noex  = ent->noex;\n        body  = ent->method;\n    }\n    else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {\n      nomethod:\n        if (scope == 3) {\n            return method_missing(recv, mid, argc, argv, CSTAT_SUPER);\n        }\n        return method_missing(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);\n    }\n\n    if (mid != missing && scope == 0) {\n        /* receiver specified form for private method */\n        if (noex & NOEX_PRIVATE)\n            return method_missing(recv, mid, argc, argv, CSTAT_PRIV);\n\n        /* self must be kind of a specified form for protected method */\n        if (noex & NOEX_PROTECTED) {\n            VALUE defined_class = klass;\n\n            if (self == Qundef) self = ruby_frame->self;\n            if (TYPE(defined_class) == T_ICLASS) {\n                defined_class = RBASIC(defined_class)->klass;\n            }\n            if (!rb_obj_is_kind_of(self, rb_class_real(defined_class)))\n                return method_missing(recv, mid, argc, argv, CSTAT_PROT);\n        }\n    }\n\n    return rb_call0(klass, recv, mid, id, argc, argv, body, noex);\n}\n\nVALUE\nrb_apply(recv, mid, args)\n    VALUE recv;\n    ID mid;\n    VALUE args;\n{\n    int argc;\n    VALUE *argv;\n\n    argc = RARRAY(args)->len; /* Assigns LONG, but argc is INT */\n    argv = ALLOCA_N(VALUE, argc);\n    MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\n    return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1, Qundef);\n}\n\n/*\n *  call-seq:\n *     obj.send(symbol [, args...])        => obj\n *     obj.__send__(symbol [, args...])    => obj\n *\n *  Invokes the method identified by _symbol_, passing it any\n *  arguments specified. You can use <code>\\_\\_send__</code> if the name\n *  +send+ clashes with an existing method in _obj_.\n *\n *     class Klass\n *       def hello(*args)\n *         \"Hello \" + args.join(' ')\n *       end\n *     end\n *     k = Klass.new\n *     k.send :hello, \"gentle\", \"readers\"   #=> \"Hello gentle readers\"\n */\n\nstatic VALUE\nrb_f_send(argc, argv, recv)\n    int argc;\n    VALUE *argv;\n    VALUE recv;\n{\n    VALUE vid;\n\n    if (argc == 0) rb_raise(rb_eArgError, \"no method name given\");\n\n    vid = *argv++; argc--;\n    PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);\n    vid = rb_call(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, 1, Qundef);\n    POP_ITER();\n\n    return vid;\n}\n\nstatic VALUE\nvafuncall(recv, mid, n, ar)\n    VALUE recv;\n    ID mid;\n    int n;\n    va_list *ar;\n{\n    VALUE *argv;\n\n    if (n > 0) {\n        long i;\n\n        argv = ALLOCA_N(VALUE, n);\n\n        for (i=0;i<n;i++) {\n            argv[i] = va_arg(*ar, VALUE);\n        }\n        va_end(*ar);\n    }\n    else {\n        argv = 0;\n    }\n\n    return rb_call(CLASS_OF(recv), recv, mid, n, argv, 1, Qundef);\n}\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_funcall(VALUE recv, ID mid, int n, ...)\n#else\nrb_funcall(recv, mid, n, va_alist)\n    VALUE recv;\n    ID mid;\n    int n;\n    va_dcl\n#endif\n{\n    va_list ar;\n    va_init_list(ar, n);\n\n    return vafuncall(recv, mid, n, &ar);\n}\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_funcall_rescue(VALUE recv, ID mid, int n, ...)\n#else\nrb_funcall_rescue(recv, mid, n, va_alist)\n    VALUE recv;\n    ID mid;\n    int n;\n    va_dcl\n#endif\n{\n    VALUE result;\n    int status;\n    va_list ar;\n\n    va_init_list(ar, n);\n\n    PUSH_TAG(PROT_EMPTY);\n    if ((status = EXEC_TAG()) == 0) {\n        result = vafuncall(recv, mid, n, &ar);\n    }\n    POP_TAG();\n    switch (status) {\n      case 0:\n        return result;\n      case TAG_RAISE:\n        return Qundef;\n      default:\n        JUMP_TAG(status);\n    }\n}\n\nVALUE\nrb_funcall2(recv, mid, argc, argv)\n    VALUE recv;\n    ID mid;\n    int argc;\n    const VALUE *argv;\n{\n    return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1, Qundef);\n}\n\nVALUE\nrb_funcall3(recv, mid, argc, argv)\n    VALUE recv;\n    ID mid;\n    int argc;\n    const VALUE *argv;\n{\n    return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 0, Qundef);\n}\n\nVALUE\nrb_call_super(argc, argv)\n    int argc;\n    const VALUE *argv;\n{\n    VALUE result, self, klass;\n\n    if (ruby_frame->last_class == 0) {\n        rb_name_error(ruby_frame->last_func, \"calling `super' from `%s' is prohibited\",\n                      rb_id2name(ruby_frame->orig_func));\n    }\n\n    self = ruby_frame->self;\n    klass = ruby_frame->last_class;\n    if (RCLASS(klass)->super == 0) {\n        return method_missing(self, ruby_frame->orig_func, argc, argv, CSTAT_SUPER);\n    }\n\n    PUSH_ITER(ruby_iter->iter ? ITER_PRE : ITER_NOT);\n    result = rb_call(RCLASS(klass)->super, self, ruby_frame->orig_func, argc, argv, 3, Qundef);\n    POP_ITER();\n\n    return result;\n}\n\nstatic VALUE\nbacktrace(lev)\n    int lev;\n{\n    struct FRAME *frame = ruby_frame;\n    char buf[BUFSIZ];\n    VALUE ary;\n    NODE *n;\n\n    ary = rb_ary_new();\n    if (frame->last_func == ID_ALLOCATOR) {\n        frame = frame->prev;\n    }\n    if (lev < 0) {\n        ruby_set_current_source();\n        if (frame->last_func) {\n            snprintf(buf, BUFSIZ, \"%s:%d:in `%s'\",\n                     ruby_sourcefile, ruby_sourceline,\n                     rb_id2name(frame->last_func));\n        }\n        else if (ruby_sourceline == 0) {\n            snprintf(buf, BUFSIZ, \"%s\", ruby_sourcefile);\n        }\n        else {\n            snprintf(buf, BUFSIZ, \"%s:%d\", ruby_sourcefile, ruby_sourceline);\n        }\n        rb_ary_push(ary, rb_str_new2(buf));\n        if (lev < -1) return ary;\n    }\n    else {\n        while (lev-- > 0) {\n            frame = frame->prev;\n            if (!frame) {\n                ary = Qnil;\n                break;\n            }\n        }\n    }\n    for (; frame && (n = frame->node); frame = frame->prev) {\n        if (frame->prev && frame->prev->last_func) {\n            if (frame->prev->node == n) {\n                if (frame->prev->last_func == frame->last_func) continue;\n            }\n            snprintf(buf, BUFSIZ, \"%s:%d:in `%s'\",\n                     n->nd_file, nd_line(n),\n                     rb_id2name(frame->prev->last_func));\n        }\n        else {\n            snprintf(buf, BUFSIZ, \"%s:%d\", n->nd_file, nd_line(n));\n        }\n        rb_ary_push(ary, rb_str_new2(buf));\n    }\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     caller(start=1)    => array\n *\n *  Returns the current execution stack---an array containing strings in\n *  the form ``<em>file:line</em>'' or ``<em>file:line: in\n *  `method'</em>''. The optional _start_ parameter\n *  determines the number of initial stack entries to omit from the\n *  result.\n *\n *     def a(skip)\n *       caller(skip)\n *     end\n *     def b(skip)\n *       a(skip)\n *     end\n *     def c(skip)\n *       b(skip)\n *     end\n *     c(0)   #=> [\"prog:2:in `a'\", \"prog:5:in `b'\", \"prog:8:in `c'\", \"prog:10\"]\n *     c(1)   #=> [\"prog:5:in `b'\", \"prog:8:in `c'\", \"prog:11\"]\n *     c(2)   #=> [\"prog:8:in `c'\", \"prog:12\"]\n *     c(3)   #=> [\"prog:13\"]\n */\n\nstatic VALUE\nrb_f_caller(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE level;\n    int lev;\n\n    rb_scan_args(argc, argv, \"01\", &level);\n\n    if (NIL_P(level)) lev = 1;\n    else lev = NUM2INT(level);\n    if (lev < 0) rb_raise(rb_eArgError, \"negative level (%d)\", lev);\n\n    return backtrace(lev);\n}\n\nvoid\nrb_backtrace()\n{\n    long i;\n    VALUE ary;\n\n    ary = backtrace(-1);\n    for (i=0; i<RARRAY(ary)->len; i++) {\n        printf(\"\\tfrom %s\\n\", RSTRING(RARRAY(ary)->ptr[i])->ptr);\n    }\n}\n\nstatic VALUE\nmake_backtrace()\n{\n    return backtrace(-1);\n}\n\nID\nrb_frame_last_func()\n{\n    return ruby_frame->last_func;\n}\n\nID\nrb_frame_this_func()\n{\n    return ruby_frame->orig_func;\n}\n\nstatic NODE*\ncompile(src, file, line)\n    VALUE src;\n    const char *file;\n    int line;\n{\n    NODE *node;\n    int critical;\n\n    ruby_nerrs = 0;\n    StringValue(src);\n    critical = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n    node = rb_compile_string(file, src, line);\n    rb_thread_critical = critical;\n\n    if (ruby_nerrs == 0) return node;\n    return 0;\n}\n\nstatic VALUE\neval(self, src, scope, file, line)\n    VALUE self, src;\n    volatile VALUE scope;\n    const char * volatile file;\n    int line;\n{\n    struct BLOCK *data = NULL;\n    VALUE result;\n    struct SCOPE * volatile old_scope;\n    struct BLOCK * volatile old_block;\n    struct RVarmap * volatile old_dyna_vars;\n    VALUE volatile old_cref;\n    int volatile old_vmode;\n    volatile VALUE old_wrapper;\n    struct FRAME frame;\n    NODE * volatile nodesave = ruby_current_node;\n    volatile int iter = ruby_frame->iter;\n    volatile int safe = ruby_safe_level;\n    int state;\n\n    if (!NIL_P(scope)) {\n        if (!rb_obj_is_proc(scope)) {\n            rb_raise(rb_eTypeError, \"wrong argument type %s (expected Proc/Binding)\",\n                     rb_obj_classname(scope));\n        }\n\n        Data_Get_Struct(scope, struct BLOCK, data);\n        /* PUSH BLOCK from data */\n        frame = data->frame;\n        frame.tmp = ruby_frame; /* gc protection */\n        ruby_frame = &(frame);\n        old_scope = ruby_scope;\n        ruby_scope = data->scope;\n        old_block = ruby_block;\n        ruby_block = data->prev;\n        old_dyna_vars = ruby_dyna_vars;\n        ruby_dyna_vars = data->dyna_vars;\n        old_vmode = scope_vmode;\n        scope_vmode = data->vmode;\n        old_cref = (VALUE)ruby_cref;\n        ruby_cref = data->cref;\n        old_wrapper = ruby_wrapper;\n        ruby_wrapper = data->wrapper;\n        if ((file == 0 || (line == 1 && strcmp(file, \"(eval)\") == 0)) && data->frame.node) {\n            file = data->frame.node->nd_file;\n            if (!file) file = \"__builtin__\";\n            line = nd_line(data->frame.node);\n        }\n\n        self = data->self;\n        ruby_frame->iter = data->iter;\n    }\n    else {\n        if (ruby_frame->prev) {\n            ruby_frame->iter = ruby_frame->prev->iter;\n        }\n    }\n    if (file == 0) {\n        ruby_set_current_source();\n        file = ruby_sourcefile;\n        line = ruby_sourceline;\n    }\n    PUSH_CLASS(data ? data->klass : ruby_class);\n    ruby_in_eval++;\n    if (TYPE(ruby_class) == T_ICLASS) {\n        ruby_class = RBASIC(ruby_class)->klass;\n    }\n    SET_GC_DEBUG_SOURCEFUNC(\"<eval>\")\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        NODE *node;\n\n        ruby_safe_level = 0;\n        result = ruby_errinfo;\n        ruby_errinfo = Qnil;\n        node = compile(src, file, line);\n        ruby_safe_level = safe;\n        if (ruby_nerrs > 0) {\n            compile_error(0);\n        }\n        if (!NIL_P(result)) ruby_errinfo = result;\n        result = eval_tree(self, node);\n    }\n    POP_TAG();\n    RESET_GC_DEBUG_SOURCEFUNC\n    POP_CLASS();\n    ruby_in_eval--;\n    if (!NIL_P(scope)) {\n        int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE;\n\n        ruby_wrapper = old_wrapper;\n        ruby_cref  = (NODE*)old_cref;\n        ruby_frame = frame.tmp;\n        ruby_scope = old_scope;\n        ruby_block = old_block;\n        ruby_dyna_vars = old_dyna_vars;\n        data->vmode = scope_vmode; /* write back visibility mode */\n        scope_vmode = old_vmode;\n        if (dont_recycle) {\n            struct tag *tag;\n            struct RVarmap *vars;\n\n            scope_dup(ruby_scope);\n            for (tag=prot_tag; tag; tag=tag->prev) {\n                scope_dup(tag->scope);\n            }\n            for (vars = ruby_dyna_vars; vars; vars = vars->next) {\n                FL_SET(vars, DVAR_DONT_RECYCLE);\n            }\n        }\n    }\n    else {\n        ruby_frame->iter = iter;\n    }\n    ruby_current_node = nodesave;\n    ruby_set_current_source();\n    if (state) {\n        if (state == TAG_RAISE) {\n            if (strcmp(file, \"(eval)\") == 0) {\n                VALUE mesg, errat, bt2;\n                ID id_mesg;\n\n                id_mesg = rb_intern(\"mesg\");\n                errat = get_backtrace(ruby_errinfo);\n                mesg = rb_attr_get(ruby_errinfo, id_mesg);\n                if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&\n                    (bt2 = backtrace(-2), RARRAY_LEN(bt2) > 0)) {\n                    if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {\n                        if (OBJ_FROZEN(mesg)) {\n                            VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), \": \", 2);\n                            rb_ivar_set(ruby_errinfo, id_mesg, rb_str_append(m, mesg));\n                        }\n                        else {\n                            rb_str_update(mesg, 0, 0, rb_str_new2(\": \"));\n                            rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]);\n                        }\n                    }\n                    RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0];\n                }\n            }\n            rb_exc_raise(ruby_errinfo);\n        }\n        JUMP_TAG(state);\n    }\n\n    return result;\n}\n\n/*\n *  call-seq:\n *     eval(string [, binding [, filename [,lineno]]])  => obj\n *\n *  Evaluates the Ruby expression(s) in <em>string</em>. If\n *  <em>binding</em> is given, the evaluation is performed in its\n *  context. The binding may be a <code>Binding</code> object or a\n *  <code>Proc</code> object. If the optional <em>filename</em> and\n *  <em>lineno</em> parameters are present, they will be used when\n *  reporting syntax errors.\n *\n *     def getBinding(str)\n *       return binding\n *     end\n *     str = \"hello\"\n *     eval \"str + ' Fred'\"                      #=> \"hello Fred\"\n *     eval \"str + ' Fred'\", getBinding(\"bye\")   #=> \"bye Fred\"\n */\n\nstatic VALUE\nrb_f_eval(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE src, scope, vfile, vline;\n    const char *file = NULL;\n    int line = 0;\n\n    rb_scan_args(argc, argv, \"13\", &src, &scope, &vfile, &vline);\n    if (ruby_safe_level >= 4) {\n        StringValue(src);\n        if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {\n            rb_raise(rb_eSecurityError, \"Insecure: can't modify trusted binding\");\n        }\n    }\n    else {\n        SafeStringValue(src);\n    }\n    if (argc >= 3) {\n        StringValue(vfile);\n    }\n    if (argc >= 4) {\n        line = NUM2INT(vline);\n    }\n\n    if (!NIL_P(vfile)) file = RSTRING(vfile)->ptr;\n    if (NIL_P(scope) && ruby_frame->prev) {\n        struct FRAME *prev;\n        VALUE val;\n\n        prev = ruby_frame;\n        PUSH_FRAME();\n        *ruby_frame = *prev->prev;\n        ruby_frame->prev = prev;\n        val = eval(self, src, scope, file, line);\n        POP_FRAME();\n\n        return val;\n    }\n    return eval(self, src, scope, file, line);\n}\n\n/* function to call func under the specified class/module context */\nstatic VALUE\nexec_under(func, under, cbase, args)\n    VALUE (*func)();\n    VALUE under;\n    volatile VALUE cbase;\n    void *args;\n{\n    VALUE val;\n    int state;\n    volatile int mode;\n    struct FRAME *f = ruby_frame;\n\n    PUSH_CLASS(under);\n    PUSH_FRAME();\n    ruby_frame->self = f->self;\n    ruby_frame->last_func = f->last_func;\n    ruby_frame->orig_func = f->orig_func;\n    ruby_frame->last_class = f->last_class;\n    ruby_frame->argc = f->argc;\n    if (cbase) {\n        PUSH_CREF(cbase);\n    }\n\n    mode = scope_vmode;\n    SCOPE_SET(SCOPE_PUBLIC);\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        val = (*func)(args);\n    }\n    POP_TAG();\n    if (cbase) POP_CREF();\n    SCOPE_SET(mode);\n    POP_FRAME();\n    POP_CLASS();\n    if (state) JUMP_TAG(state);\n\n    return val;\n}\n\nstatic VALUE\neval_under_i(args)\n    VALUE *args;\n{\n    struct FRAME *f = ruby_frame;\n\n    if (f && (f = f->prev) && (f = f->prev)) {\n        ruby_frame = f;\n    }\n    return eval(args[0], args[1], Qnil, (char*)args[2], (int)args[3]);\n}\n\n/* string eval under the class/module context */\nstatic VALUE\neval_under(under, self, src, file, line)\n    VALUE under, self, src;\n    const char *file;\n    int line;\n{\n    VALUE args[4];\n\n    if (ruby_safe_level >= 4) {\n        StringValue(src);\n    }\n    else {\n        SafeStringValue(src);\n    }\n    args[0] = self;\n    args[1] = src;\n    args[2] = (VALUE)file;\n    args[3] = (VALUE)line;\n    return exec_under(eval_under_i, under, under, args);\n}\n\nstatic VALUE\nyield_under_i(self)\n    VALUE self;\n{\n    return rb_yield_0(self, self, ruby_class, YIELD_PUBLIC_DEF, Qfalse);\n}\n\nstatic VALUE\nyield_args_under_i(vinfo)\n    VALUE vinfo;\n{\n    VALUE *info = (VALUE *)vinfo;\n\n    return rb_yield_0(info[0], info[1], ruby_class, YIELD_PUBLIC_DEF, Qtrue);\n}\n\n/* block eval under the class/module context */\nstatic VALUE\nyield_under(under, self, args)\n    VALUE under, self, args;\n{\n    if (args == Qundef) {\n        return exec_under(yield_under_i, under, 0, self);\n    }\n    else {\n        VALUE info[2] = { args, self };\n\n        return exec_under(yield_args_under_i, under, 0, (VALUE)info);\n    }\n}\n\nstatic VALUE\nspecific_eval(argc, argv, klass, self)\n    int argc;\n    VALUE *argv;\n    VALUE klass, self;\n{\n    if (rb_block_given_p()) {\n        if (argc > 0) {\n            rb_raise(rb_eArgError, \"wrong number of arguments (%d for 0)\", argc);\n        }\n        return yield_under(klass, self, Qundef);\n    }\n    else {\n        const char *file = \"(eval)\";\n        int   line = 1;\n\n        if (argc == 0) {\n            rb_raise(rb_eArgError, \"block not supplied\");\n        }\n        else {\n            if (ruby_safe_level >= 4) {\n                StringValue(argv[0]);\n            }\n            else {\n                SafeStringValue(argv[0]);\n            }\n            if (argc > 3) {\n                rb_raise(rb_eArgError, \"wrong number of arguments: %s(src) or %s{..}\",\n                         rb_id2name(ruby_frame->last_func),\n                         rb_id2name(ruby_frame->last_func));\n            }\n            if (argc > 2) line = NUM2INT(argv[2]);\n            if (argc > 1) {\n                file = StringValuePtr(argv[1]);\n            }\n        }\n        return eval_under(klass, self, argv[0], file, line);\n    }\n}\n\n/*\n *  call-seq:\n *     obj.instance_eval(string [, filename [, lineno]] )   => obj\n *     obj.instance_eval {| | block }                       => obj\n *\n *  Evaluates a string containing Ruby source code, or the given block,\n *  within the context of the receiver (_obj_). In order to set the\n *  context, the variable +self+ is set to _obj_ while\n *  the code is executing, giving the code access to _obj_'s\n *  instance variables. In the version of <code>instance_eval</code>\n *  that takes a +String+, the optional second and third\n *  parameters supply a filename and starting line number that are used\n *  when reporting compilation errors.\n *\n *     class Klass\n *       def initialize\n *         @secret = 99\n *       end\n *     end\n *     k = Klass.new\n *     k.instance_eval { @secret }   #=> 99\n */\n\nVALUE\nrb_obj_instance_eval(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE klass, result;\n\n    if (SPECIAL_CONST_P(self)) {\n        klass = Qnil;\n    }\n    else {\n        klass = rb_singleton_class(self);\n    }\n    result = specific_eval(argc, argv, klass, self);\n\n    return result;\n}\n\n/*\n *  call-seq:\n *     obj.instance_exec(arg...) {|var...| block }                       => obj\n *\n *  Executes the given block within the context of the receiver\n *  (_obj_). In order to set the context, the variable +self+ is set\n *  to _obj_ while the code is executing, giving the code access to\n *  _obj_'s instance variables.  Arguments are passed as block parameters.\n *\n *     class KlassWithSecret\n *       def initialize\n *         @secret = 99\n *       end\n *     end\n *     k = KlassWithSecret.new\n *     k.instance_exec(5) {|x| @secret+x }   #=> 104\n */\n\nVALUE\nrb_obj_instance_exec(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE klass;\n\n    if (SPECIAL_CONST_P(self)) {\n        klass = Qnil;\n    }\n    else {\n        klass = rb_singleton_class(self);\n    }\n    return yield_under(klass, self, rb_ary_new4(argc, argv));\n}\n\n/*\n *  call-seq:\n *     mod.class_eval(string [, filename [, lineno]])  => obj\n *     mod.module_eval {|| block }                     => obj\n *\n *  Evaluates the string or block in the context of _mod_. This can\n *  be used to add methods to a class. <code>module_eval</code> returns\n *  the result of evaluating its argument. The optional _filename_\n *  and _lineno_ parameters set the text for error messages.\n *\n *     class Thing\n *     end\n *     a = %q{def hello() \"Hello there!\" end}\n *     Thing.module_eval(a)\n *     puts Thing.new.hello()\n *     Thing.module_eval(\"invalid code\", \"dummy\", 123)\n *\n *  <em>produces:</em>\n *\n *     Hello there!\n *     dummy:123:in `module_eval': undefined local variable\n *         or method `code' for Thing:Class\n */\n\nVALUE\nrb_mod_module_eval(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    return specific_eval(argc, argv, mod, mod);\n}\n\n/*\n *  call-seq:\n *     mod.module_exec(arg...) {|var...| block }       => obj\n *     mod.class_exec(arg...) {|var...| block }        => obj\n *\n *  Evaluates the given block in the context of the class/module.\n *  The method defined in the block will belong to the receiver.\n *\n *     class Thing\n *     end\n *     Thing.class_exec{\n *       def hello() \"Hello there!\" end\n *     }\n *     puts Thing.new.hello()\n *\n *  <em>produces:</em>\n *\n *     Hello there!\n */\n\nVALUE\nrb_mod_module_exec(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    return yield_under(mod, mod, rb_ary_new4(argc, argv));\n}\n\nVALUE rb_load_path;\n\nNORETURN(static void load_failed _((VALUE)));\n\nvoid\nrb_load(fname, wrap)\n    VALUE fname;\n    int wrap;\n{\n    VALUE tmp;\n    int state;\n    volatile int prohibit_int = rb_prohibit_interrupt;\n    volatile ID last_func;\n    volatile VALUE wrapper = ruby_wrapper;\n    VALUE self = ruby_top_self;\n    NODE *volatile last_node;\n    NODE *volatile saved_cref = ruby_cref;\n\n    if (wrap && ruby_safe_level >= 4) {\n        StringValue(fname);\n    }\n    else {\n        SafeStringValue(fname);\n    }\n    fname = rb_str_new4(fname);\n    tmp = rb_find_file(fname);\n    if (!tmp) {\n        load_failed(fname);\n    }\n    fname = tmp;\n\n    ruby_errinfo = Qnil;        /* ensure */\n    PUSH_VARS();\n    PUSH_CLASS(ruby_wrapper);\n    ruby_cref = ruby_top_cref;\n    if (!wrap) {\n        rb_secure(4);           /* should alter global state */\n        ruby_class = rb_cObject;\n        ruby_wrapper = 0;\n    }\n    else {\n        /* load in anonymous module as toplevel */\n        ruby_class = ruby_wrapper = rb_module_new();\n        self = rb_obj_clone(ruby_top_self);\n        rb_extend_object(self, ruby_wrapper);\n        PUSH_CREF(ruby_wrapper);\n    }\n    PUSH_ITER(ITER_NOT);\n    PUSH_FRAME();\n    ruby_frame->last_func = 0;\n    ruby_frame->last_class = 0;\n    ruby_frame->self = self;\n    PUSH_SCOPE();\n    /* default visibility is private at loading toplevel */\n    SCOPE_SET(SCOPE_PRIVATE);\n    PUSH_TAG(PROT_EMPTY);\n    state = EXEC_TAG();\n    last_func = ruby_frame->last_func;\n    last_node = ruby_current_node;\n    if (!ruby_current_node && ruby_sourcefile) {\n        last_node = NEW_NEWLINE(0);\n    }\n    ruby_current_node = 0;\n    if (state == 0) {\n        NODE *node;\n        int critical;\n\n        DEFER_INTS;\n        ruby_in_eval++;\n        critical = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n        rb_load_file(RSTRING(fname)->ptr);\n        ruby_in_eval--;\n        node = ruby_eval_tree;\n        rb_thread_critical = critical;\n        ALLOW_INTS;\n        if (ruby_nerrs == 0) {\n            eval_tree(self, node);\n        }\n    }\n    ruby_frame->last_func = last_func;\n    ruby_current_node = last_node;\n    ruby_sourcefile = 0;\n    ruby_set_current_source();\n    if (ruby_scope->flags == SCOPE_ALLOCA && ruby_class == rb_cObject) {\n        if (ruby_scope->local_tbl) /* toplevel was empty */\n            free(ruby_scope->local_tbl);\n    }\n    POP_TAG();\n    rb_prohibit_interrupt = prohibit_int;\n    ruby_cref = saved_cref;\n    POP_SCOPE();\n    POP_FRAME();\n    POP_ITER();\n    POP_CLASS();\n    POP_VARS();\n    ruby_wrapper = wrapper;\n    if (ruby_nerrs > 0) {\n        ruby_nerrs = 0;\n        rb_exc_raise(ruby_errinfo);\n    }\n    if (state) jump_tag_but_local_jump(state, Qundef);\n    if (!NIL_P(ruby_errinfo))   /* exception during load */\n        rb_exc_raise(ruby_errinfo);\n}\n\nvoid\nrb_load_protect(fname, wrap, state)\n    VALUE fname;\n    int wrap;\n    int * volatile state;\n{\n    int status;\n\n    PUSH_TAG(PROT_EMPTY);\n    if ((status = EXEC_TAG()) == 0) {\n        rb_load(fname, wrap);\n    }\n    POP_TAG();\n    if (state) *state = status;\n}\n\n/*\n *  call-seq:\n *     load(filename, wrap=false)   => true\n *\n *  Loads and executes the Ruby\n *  program in the file _filename_. If the filename does not\n *  resolve to an absolute path, the file is searched for in the library\n *  directories listed in <code>$:</code>. If the optional _wrap_\n *  parameter is +true+, the loaded script will be executed\n *  under an anonymous module, protecting the calling program's global\n *  namespace. In no circumstance will any local variables in the loaded\n *  file be propagated to the loading environment.\n */\n\n\nstatic VALUE\nrb_f_load(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE fname, wrap;\n\n    rb_scan_args(argc, argv, \"11\", &fname, &wrap);\n    rb_load(fname, RTEST(wrap));\n    return Qtrue;\n}\n\nVALUE ruby_dln_librefs;\nstatic VALUE rb_features;\nstatic st_table *loading_tbl;\n\n#define IS_SOEXT(e) (strcmp(e, \".so\") == 0 || strcmp(e, \".o\") == 0)\n#ifdef DLEXT2\n#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0 || strcmp(e, DLEXT2) == 0)\n#else\n#define IS_DLEXT(e) (strcmp(e, DLEXT) == 0)\n#endif\n\n\nstatic const char *const loadable_ext[] = {\n    \".rb\", DLEXT,\n#ifdef DLEXT2\n    DLEXT2,\n#endif\n    0\n};\n\nstatic int rb_feature_p _((const char **, const char *, int));\nstatic int search_required _((VALUE, VALUE *, VALUE *));\n\nstatic int\nrb_feature_p(ftptr, ext, rb)\n    const char **ftptr, *ext;\n    int rb;\n{\n    VALUE v;\n    const char *f, *e, *feature = *ftptr;\n    long i, len, elen;\n\n    if (ext) {\n        len = ext - feature;\n        elen = strlen(ext);\n    }\n    else {\n        len = strlen(feature);\n        elen = 0;\n    }\n    for (i = 0; i < RARRAY_LEN(rb_features); ++i) {\n        v = RARRAY_PTR(rb_features)[i];\n        f = StringValuePtr(v);\n        if (RSTRING_LEN(v) < len || strncmp(f, feature, len) != 0)\n            continue;\n        if (!*(e = f + len)) {\n            if (ext) continue;\n            *ftptr = 0;\n            return 'u';\n        }\n        if (*e != '.') continue;\n        if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {\n            *ftptr = 0;\n            return 's';\n        }\n        if ((rb || !ext) && (strcmp(e, \".rb\") == 0)) {\n            *ftptr = 0;\n            return 'r';\n        }\n    }\n    if (loading_tbl) {\n        if (st_lookup(loading_tbl, (st_data_t)feature, (st_data_t *)ftptr)) {\n            if (!ext) return 'u';\n            return strcmp(ext, \".rb\") ? 's' : 'r';\n        }\n        else {\n            char *buf;\n\n            if (ext && *ext) return 0;\n            buf = ALLOCA_N(char, len + DLEXT_MAXLEN + 1);\n            MEMCPY(buf, feature, char, len);\n            for (i = 0; (e = loadable_ext[i]) != 0; i++) {\n                strncpy(buf + len, e, DLEXT_MAXLEN + 1);\n                if (st_lookup(loading_tbl, (st_data_t)buf, (st_data_t *)ftptr)) {\n                    return i ? 's' : 'r';\n                }\n            }\n        }\n    }\n    return 0;\n}\n#define rb_feature_p(feature, ext, rb) rb_feature_p(&feature, ext, rb)\n\nint\nrb_provided(feature)\n    const char *feature;\n{\n    const char *ext = strrchr(feature, '.');\n\n    if (ext && !strchr(ext, '/')) {\n        if (strcmp(\".rb\", ext) == 0) {\n            if (rb_feature_p(feature, ext, Qtrue)) return Qtrue;\n            return Qfalse;\n        }\n        else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {\n            if (rb_feature_p(feature, ext, Qfalse)) return Qtrue;\n            return Qfalse;\n        }\n    }\n    if (rb_feature_p(feature, feature + strlen(feature), Qtrue))\n        return Qtrue;\n\n    return Qfalse;\n}\n\nstatic void\nrb_provide_feature(feature)\n    VALUE feature;\n{\n    rb_ary_push(rb_features, feature);\n}\n\nvoid\nrb_provide(feature)\n    const char *feature;\n{\n    rb_provide_feature(rb_str_new2(feature));\n}\n\nstatic char *\nload_lock(ftptr)\n    const char *ftptr;\n{\n    st_data_t th;\n\n    if (!loading_tbl ||\n        !st_lookup(loading_tbl, (st_data_t)ftptr, &th))\n    {\n        /* loading ruby library should be serialized. */\n        if (!loading_tbl) {\n            loading_tbl = st_init_strtable();\n        }\n        /* partial state */\n        ftptr = ruby_strdup(ftptr);\n        st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)curr_thread);\n        return (char *)ftptr;\n    }\n    do {\n        rb_thread_t owner = (rb_thread_t)th;\n        if (owner == curr_thread) return 0;\n        rb_thread_join(owner->thread, -1.0);\n    } while (st_lookup(loading_tbl, (st_data_t)ftptr, &th));\n    return 0;\n}\n\nstatic void\nload_unlock(const char *ftptr)\n{\n    if (ftptr) {\n        st_data_t key = (st_data_t)ftptr;\n\n        if (st_delete(loading_tbl, &key, 0)) {\n            free((char *)key);\n        }\n    }\n}\n\n/*\n *  call-seq:\n *     require(string)    => true or false\n *\n *  Ruby tries to load the library named _string_, returning\n *  +true+ if successful. If the filename does not resolve to\n *  an absolute path, it will be searched for in the directories listed\n *  in <code>$:</code>. If the file has the extension ``.rb'', it is\n *  loaded as a source file; if the extension is ``.so'', ``.o'', or\n *  ``.dll'', or whatever the default shared library extension is on\n *  the current platform, Ruby loads the shared library as a Ruby\n *  extension. Otherwise, Ruby tries adding ``.rb'', ``.so'', and so on\n *  to the name. The name of the loaded feature is added to the array in\n *  <code>$\"</code>. A feature will not be loaded if it's name already\n *  appears in <code>$\"</code>. However, the file name is not converted\n *  to an absolute path, so that ``<code>require 'a';require\n *  './a'</code>'' will load <code>a.rb</code> twice.\n *\n *     require \"my-library.rb\"\n *     require \"db-driver\"\n */\n\nVALUE\nrb_f_require(obj, fname)\n    VALUE obj, fname;\n{\n    return rb_require_safe(fname, ruby_safe_level);\n}\n\nstatic int\nsearch_required(fname, featurep, path)\n    VALUE fname, *featurep, *path;\n{\n    VALUE tmp;\n    const char *ext, *ftptr;\n    int type;\n\n    *featurep = fname;\n    *path = 0;\n    ext = strrchr(ftptr = RSTRING_PTR(fname), '.');\n    if (ext && !strchr(ext, '/')) {\n        if (strcmp(\".rb\", ext) == 0) {\n            if (rb_feature_p(ftptr, ext, Qtrue)) {\n                if (ftptr) *path = rb_str_new2(ftptr);\n                return 'r';\n            }\n            if ((*path = rb_find_file(fname)) != 0) return 'r';\n            return 0;\n        }\n        else if (IS_SOEXT(ext)) {\n            if (rb_feature_p(ftptr, ext, Qfalse)) {\n                if (ftptr) *path = rb_str_new2(ftptr);\n                return 's';\n            }\n            tmp = rb_str_new(RSTRING_PTR(fname), ext-RSTRING_PTR(fname));\n            *featurep = tmp;\n#ifdef DLEXT2\n            OBJ_FREEZE(tmp);\n            if (rb_find_file_ext(&tmp, loadable_ext+1)) {\n                *featurep = tmp;\n                *path = rb_find_file(tmp);\n                return 's';\n            }\n#else\n            rb_str_cat2(tmp, DLEXT);\n            OBJ_FREEZE(tmp);\n            if ((*path = rb_find_file(tmp)) != 0) {\n                return 's';\n            }\n#endif\n        }\n        else if (IS_DLEXT(ext)) {\n            if (rb_feature_p(ftptr, ext, Qfalse)) {\n                if (ftptr) *path = rb_str_new2(ftptr);\n                return 's';\n            }\n            if ((*path = rb_find_file(fname)) != 0) return 's';\n        }\n    }\n    tmp = fname;\n    type = rb_find_file_ext(&tmp, loadable_ext);\n    *featurep = tmp;\n    switch (type) {\n      case 0:\n        type = rb_feature_p(ftptr, 0, Qfalse);\n        if (type && ftptr) *path = rb_str_new2(ftptr);\n        return type;\n\n      default:\n        ext = strrchr(ftptr = RSTRING(tmp)->ptr, '.');\n        if (!rb_feature_p(ftptr, ext, !--type))\n            *path = rb_find_file(tmp);\n        else if (ftptr)\n            *path = rb_str_new2(ftptr);\n    }\n    return type ? 's' : 'r';\n}\n\nstatic void\nload_failed(fname)\n    VALUE fname;\n{\n    rb_raise(rb_eLoadError, \"no such file to load -- %s\", RSTRING(fname)->ptr);\n}\n\nVALUE\nrb_require_safe(fname, safe)\n    VALUE fname;\n    int safe;\n{\n    VALUE result;\n    volatile VALUE errinfo = ruby_errinfo;\n    int state;\n    struct {\n        NODE *node;\n        ID func;\n        int vmode, safe;\n    } volatile saved;\n    char *volatile ftptr = 0;\n\n    if (OBJ_TAINTED(fname)) {\n        rb_check_safe_obj(fname);\n    }\n    StringValue(fname);\n    fname = rb_str_new4(fname);\n    saved.vmode = scope_vmode;\n    saved.node = ruby_current_node;\n    saved.func = ruby_frame->last_func;\n    saved.safe = ruby_safe_level;\n    PUSH_TAG(PROT_EMPTY);\n    if ((state = EXEC_TAG()) == 0) {\n        VALUE feature, path;\n        long handle;\n        int found;\n\n        ruby_safe_level = safe;\n        found = search_required(fname, &feature, &path);\n        if (found) {\n            if (!path || !(ftptr = load_lock(RSTRING_PTR(feature)))) {\n                result = Qfalse;\n            }\n            else {\n                ruby_safe_level = 0;\n                switch (found) {\n                  case 'r':\n                    rb_load(path, 0);\n                    break;\n\n                  case 's':\n                    ruby_current_node = 0;\n                    ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);\n                    ruby_sourceline = 0;\n                    ruby_frame->last_func = 0;\n                    SCOPE_SET(SCOPE_PUBLIC);\n                    handle = (long)dln_load(RSTRING(path)->ptr);\n                    rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));\n                    break;\n                }\n                rb_provide_feature(feature);\n                result = Qtrue;\n            }\n        }else\n          result = Qnil;\n    }\n    POP_TAG();\n    ruby_current_node = saved.node;\n    ruby_set_current_source();\n    ruby_frame->last_func = saved.func;\n    SCOPE_SET(saved.vmode);\n    ruby_safe_level = saved.safe;\n    load_unlock(ftptr);\n    if (state) JUMP_TAG(state);\n    if (NIL_P(result)) {\n        load_failed(fname);\n    }\n    ruby_errinfo = errinfo;\n\n    return result;\n}\n\nVALUE\nrb_require(fname)\n    const char *fname;\n{\n    VALUE fn = rb_str_new2(fname);\n    OBJ_FREEZE(fn);\n    return rb_require_safe(fn, ruby_safe_level);\n}\n\nvoid\nruby_init_ext(name, init)\n    const char *name;\n    void (*init) _((void));\n{\n    ruby_current_node = 0;\n    ruby_sourcefile = rb_source_filename(name);\n    ruby_sourceline = 0;\n    ruby_frame->last_func = 0;\n    ruby_frame->orig_func = 0;\n    SCOPE_SET(SCOPE_PUBLIC);\n    if (load_lock(name)) {\n        (*init)();\n        rb_provide(name);\n        load_unlock(name);\n    }\n}\n\nstatic void\nsecure_visibility(self)\n    VALUE self;\n{\n    if (ruby_safe_level >= 4 && !OBJ_TAINTED(self)) {\n        rb_raise(rb_eSecurityError, \"Insecure: can't change method visibility\");\n    }\n}\n\nstatic void\nset_method_visibility(self, argc, argv, ex)\n    VALUE self;\n    int argc;\n    VALUE *argv;\n    ID ex;\n{\n    int i;\n\n    secure_visibility(self);\n    for (i=0; i<argc; i++) {\n        rb_export_method(self, rb_to_id(argv[i]), ex);\n    }\n    rb_clear_cache_by_class(self);\n}\n\n/*\n *  call-seq:\n *     public                 => self\n *     public(symbol, ...)    => self\n *\n *  With no arguments, sets the default visibility for subsequently\n *  defined methods to public. With arguments, sets the named methods to\n *  have public visibility.\n */\n\nstatic VALUE\nrb_mod_public(argc, argv, module)\n    int argc;\n    VALUE *argv;\n    VALUE module;\n{\n    secure_visibility(module);\n    if (argc == 0) {\n        SCOPE_SET(SCOPE_PUBLIC);\n    }\n    else {\n        set_method_visibility(module, argc, argv, NOEX_PUBLIC);\n    }\n    return module;\n}\n\n/*\n *  call-seq:\n *     protected                => self\n *     protected(symbol, ...)   => self\n *\n *  With no arguments, sets the default visibility for subsequently\n *  defined methods to protected. With arguments, sets the named methods\n *  to have protected visibility.\n */\n\nstatic VALUE\nrb_mod_protected(argc, argv, module)\n    int argc;\n    VALUE *argv;\n    VALUE module;\n{\n    secure_visibility(module);\n    if (argc == 0) {\n        SCOPE_SET(SCOPE_PROTECTED);\n    }\n    else {\n        set_method_visibility(module, argc, argv, NOEX_PROTECTED);\n    }\n    return module;\n}\n\n/*\n *  call-seq:\n *     private                 => self\n *     private(symbol, ...)    => self\n *\n *  With no arguments, sets the default visibility for subsequently\n *  defined methods to private. With arguments, sets the named methods\n *  to have private visibility.\n *\n *     module Mod\n *       def a()  end\n *       def b()  end\n *       private\n *       def c()  end\n *       private :a\n *     end\n *     Mod.private_instance_methods   #=> [\"a\", \"c\"]\n */\n\nstatic VALUE\nrb_mod_private(argc, argv, module)\n    int argc;\n    VALUE *argv;\n    VALUE module;\n{\n    secure_visibility(module);\n    if (argc == 0) {\n        SCOPE_SET(SCOPE_PRIVATE);\n    }\n    else {\n        set_method_visibility(module, argc, argv, NOEX_PRIVATE);\n    }\n    return module;\n}\n\n/*\n *  call-seq:\n *     mod.public_class_method(symbol, ...)    => mod\n *\n *  Makes a list of existing class methods public.\n */\n\nstatic VALUE\nrb_mod_public_method(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     mod.private_class_method(symbol, ...)   => mod\n *\n *  Makes existing class methods private. Often used to hide the default\n *  constructor <code>new</code>.\n *\n *     class SimpleSingleton  # Not thread safe\n *       private_class_method :new\n *       def SimpleSingleton.create(*args, &block)\n *         @me = new(*args, &block) if ! @me\n *         @me\n *       end\n *     end\n */\n\nstatic VALUE\nrb_mod_private_method(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     public\n *     public(symbol, ...)\n *\n *  With no arguments, sets the default visibility for subsequently\n *  defined methods to public. With arguments, sets the named methods to\n *  have public visibility.\n */\n\nstatic VALUE\ntop_public(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_mod_public(argc, argv, rb_cObject);\n}\n\nstatic VALUE\ntop_private(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_mod_private(argc, argv, rb_cObject);\n}\n\n/*\n *  call-seq:\n *     module_function(symbol, ...)    => self\n *\n *  Creates module functions for the named methods. These functions may\n *  be called with the module as a receiver, and also become available\n *  as instance methods to classes that mix in the module. Module\n *  functions are copies of the original, and so may be changed\n *  independently. The instance-method versions are made private. If\n *  used with no arguments, subsequently defined methods become module\n *  functions.\n *\n *     module Mod\n *       def one\n *         \"This is one\"\n *       end\n *       module_function :one\n *     end\n *     class Cls\n *       include Mod\n *       def callOne\n *         one\n *       end\n *     end\n *     Mod.one     #=> \"This is one\"\n *     c = Cls.new\n *     c.callOne   #=> \"This is one\"\n *     module Mod\n *       def one\n *         \"This is the new one\"\n *       end\n *     end\n *     Mod.one     #=> \"This is one\"\n *     c.callOne   #=> \"This is the new one\"\n */\n\nstatic VALUE\nrb_mod_modfunc(argc, argv, module)\n    int argc;\n    VALUE *argv;\n    VALUE module;\n{\n    int i;\n    ID id;\n    NODE *body;\n\n    if (TYPE(module) != T_MODULE) {\n        rb_raise(rb_eTypeError, \"module_function must be called for modules\");\n    }\n\n    secure_visibility(module);\n    if (argc == 0) {\n        SCOPE_SET(SCOPE_MODFUNC);\n        return module;\n    }\n\n    set_method_visibility(module, argc, argv, NOEX_PRIVATE);\n    for (i=0; i<argc; i++) {\n        VALUE m = module;\n\n        id = rb_to_id(argv[i]);\n        for (;;) {\n            body = search_method(m, id, &m);\n            if (body == 0) {\n                body = search_method(rb_cObject, id, &m);\n            }\n            if (body == 0 || body->nd_body == 0) {\n                print_undef(module, id);\n            }\n            if (nd_type(body->nd_body) != NODE_ZSUPER) {\n                break;          /* normal case: need not to follow 'super' link */\n            }\n            m = RCLASS(m)->super;\n            if (!m) break;\n        }\n        rb_add_method(rb_singleton_class(module), id, body->nd_body, NOEX_PUBLIC);\n    }\n    return module;\n}\n\n/*\n *  call-seq:\n *     append_features(mod)   => mod\n *\n *  When this module is included in another, Ruby calls\n *  <code>append_features</code> in this module, passing it the\n *  receiving module in _mod_. Ruby's default implementation is\n *  to add the constants, methods, and module variables of this module\n *  to _mod_ if this module has not already been added to\n *  _mod_ or one of its ancestors. See also <code>Module#include</code>.\n */\n\nstatic VALUE\nrb_mod_append_features(module, include)\n    VALUE module, include;\n{\n    switch (TYPE(include)) {\n      case T_CLASS:\n      case T_MODULE:\n        break;\n      default:\n        Check_Type(include, T_CLASS);\n        break;\n    }\n    rb_include_module(include, module);\n\n    return module;\n}\n\n/*\n *  call-seq:\n *     include(module, ...)    => self\n *\n *  Invokes <code>Module.append_features</code> on each parameter in turn.\n */\n\nstatic VALUE\nrb_mod_include(argc, argv, module)\n    int argc;\n    VALUE *argv;\n    VALUE module;\n{\n    int i;\n\n    for (i=0; i<argc; i++) Check_Type(argv[i], T_MODULE);\n    while (argc--) {\n        rb_funcall(argv[argc], rb_intern(\"append_features\"), 1, module);\n        rb_funcall(argv[argc], rb_intern(\"included\"), 1, module);\n    }\n    return module;\n}\n\nvoid\nrb_obj_call_init(obj, argc, argv)\n    VALUE obj;\n    int argc;\n    VALUE *argv;\n{\n    PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);\n    rb_funcall2(obj, init, argc, argv);\n    POP_ITER();\n}\n\nvoid\nrb_extend_object(obj, module)\n    VALUE obj, module;\n{\n    rb_include_module(rb_singleton_class(obj), module);\n}\n\n/*\n *  call-seq:\n *     extend_object(obj)    => obj\n *\n *  Extends the specified object by adding this module's constants and\n *  methods (which are added as singleton methods). This is the callback\n *  method used by <code>Object#extend</code>.\n *\n *     module Picky\n *       def Picky.extend_object(o)\n *         if String === o\n *           puts \"Can't add Picky to a String\"\n *         else\n *           puts \"Picky added to #{o.class}\"\n *           super\n *         end\n *       end\n *     end\n *     (s = Array.new).extend Picky  # Call Object.extend\n *     (s = \"quick brown fox\").extend Picky\n *\n *  <em>produces:</em>\n *\n *     Picky added to Array\n *     Can't add Picky to a String\n */\n\nstatic VALUE\nrb_mod_extend_object(mod, obj)\n    VALUE mod, obj;\n{\n    rb_extend_object(obj, mod);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     obj.extend(module, ...)    => obj\n *\n *  Adds to _obj_ the instance methods from each module given as a\n *  parameter.\n *\n *     module Mod\n *       def hello\n *         \"Hello from Mod.\\n\"\n *       end\n *     end\n *\n *     class Klass\n *       def hello\n *         \"Hello from Klass.\\n\"\n *       end\n *     end\n *\n *     k = Klass.new\n *     k.hello         #=> \"Hello from Klass.\\n\"\n *     k.extend(Mod)   #=> #<Klass:0x401b3bc8>\n *     k.hello         #=> \"Hello from Mod.\\n\"\n */\n\nstatic VALUE\nrb_obj_extend(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    int i;\n\n    if (argc == 0) {\n        rb_raise(rb_eArgError, \"wrong number of arguments (0 for 1)\");\n    }\n    for (i=0; i<argc; i++) Check_Type(argv[i], T_MODULE);\n    while (argc--) {\n        rb_funcall(argv[argc], rb_intern(\"extend_object\"), 1, obj);\n        rb_funcall(argv[argc], rb_intern(\"extended\"), 1, obj);\n    }\n    return obj;\n}\n\n/*\n *  call-seq:\n *     include(module, ...)   => self\n *\n *  Invokes <code>Module.append_features</code>\n *  on each parameter in turn. Effectively adds the methods and constants\n *  in each module to the receiver.\n */\n\nstatic VALUE\ntop_include(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    rb_secure(4);\n    if (ruby_wrapper) {\n        rb_warning(\"main#include in the wrapped load is effective only in wrapper module\");\n        return rb_mod_include(argc, argv, ruby_wrapper);\n    }\n    return rb_mod_include(argc, argv, rb_cObject);\n}\n\nVALUE rb_f_trace_var();\nVALUE rb_f_untrace_var();\n\nstatic void\nerrinfo_setter(val, id, var)\n    VALUE val;\n    ID id;\n    VALUE *var;\n{\n    if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {\n        rb_raise(rb_eTypeError, \"assigning non-exception to $!\");\n    }\n    *var = val;\n}\n\nstatic VALUE\nerrat_getter(id)\n    ID id;\n{\n    return get_backtrace(ruby_errinfo);\n}\n\nstatic void\nerrat_setter(val, id, var)\n    VALUE val;\n    ID id;\n    VALUE *var;\n{\n    if (NIL_P(ruby_errinfo)) {\n        rb_raise(rb_eArgError, \"$! not set\");\n    }\n    set_backtrace(ruby_errinfo, val);\n}\n\n/*\n *  call-seq:\n *     local_variables    => array\n *\n *  Returns the names of the current local variables.\n *\n *     fred = 1\n *     for i in 1..10\n *        # ...\n *     end\n *     local_variables   #=> [\"fred\", \"i\"]\n */\n\nstatic VALUE\nrb_f_local_variables()\n{\n    ID *tbl;\n    int n, i;\n    VALUE ary = rb_ary_new();\n    struct RVarmap *vars;\n\n    tbl = ruby_scope->local_tbl;\n    if (tbl) {\n        n = *tbl++;\n        for (i=2; i<n; i++) {   /* skip first 2 ($_ and $~) */\n            if (!rb_is_local_id(tbl[i])) continue; /* skip flip states */\n            rb_ary_push(ary, rb_str_new2(rb_id2name(tbl[i])));\n        }\n    }\n\n    vars = ruby_dyna_vars;\n    while (vars) {\n        if (vars->id && rb_is_local_id(vars->id)) { /* skip $_, $~ and flip states */\n            rb_ary_push(ary, rb_str_new2(rb_id2name(vars->id)));\n        }\n        vars = vars->next;\n    }\n\n    return ary;\n}\n\nstatic VALUE rb_f_catch _((VALUE,VALUE));\nNORETURN(static VALUE rb_f_throw _((int,VALUE*)));\n\nstruct end_proc_data {\n    void (*func)();\n    VALUE data;\n    int safe;\n    struct end_proc_data *next;\n};\n\nstatic struct end_proc_data *end_procs, *ephemeral_end_procs, *tmp_end_procs;\n\nvoid\nrb_set_end_proc(func, data)\n    void (*func) _((VALUE));\n    VALUE data;\n{\n    struct end_proc_data *link = ALLOC(struct end_proc_data);\n    struct end_proc_data **list;\n\n    if (ruby_wrapper) list = &ephemeral_end_procs;\n    else              list = &end_procs;\n    link->next = *list;\n    link->func = func;\n    link->data = data;\n    link->safe = ruby_safe_level;\n    *list = link;\n}\n\nvoid\nrb_mark_end_proc()\n{\n    struct end_proc_data *link;\n\n    link = end_procs;\n    while (link) {\n        rb_gc_mark(link->data);\n        link = link->next;\n    }\n    link = ephemeral_end_procs;\n    while (link) {\n        rb_gc_mark(link->data);\n        link = link->next;\n    }\n    link = tmp_end_procs;\n    while (link) {\n        rb_gc_mark(link->data);\n        link = link->next;\n    }\n}\n\nstatic void call_end_proc _((VALUE data));\n\nstatic void\ncall_end_proc(data)\n    VALUE data;\n{\n    PUSH_ITER(ITER_NOT);\n    PUSH_FRAME();\n    ruby_frame->self = ruby_frame->prev->self;\n    ruby_frame->node = 0;\n    ruby_frame->last_func = 0;\n    ruby_frame->last_class = 0;\n    proc_invoke(data, rb_ary_new2(0), Qundef, 0);\n    POP_FRAME();\n    POP_ITER();\n}\n\nstatic void\nrb_f_END()\n{\n    PUSH_FRAME();\n    ruby_frame->argc = 0;\n    ruby_frame->iter = ITER_CUR;\n    rb_set_end_proc(call_end_proc, rb_block_proc());\n    POP_FRAME();\n}\n\n/*\n *  call-seq:\n *     at_exit { block } -> proc\n *\n *  Converts _block_ to a +Proc+ object (and therefore\n *  binds it at the point of call) and registers it for execution when\n *  the program exits. If multiple handlers are registered, they are\n *  executed in reverse order of registration.\n *\n *     def do_at_exit(str1)\n *       at_exit { print str1 }\n *     end\n *     at_exit { puts \"cruel world\" }\n *     do_at_exit(\"goodbye \")\n *     exit\n *\n *  <em>produces:</em>\n *\n *     goodbye cruel world\n */\n\nstatic VALUE\nrb_f_at_exit()\n{\n    VALUE proc;\n\n    if (!rb_block_given_p()) {\n        rb_raise(rb_eArgError, \"called without a block\");\n    }\n    proc = rb_block_proc();\n    rb_set_end_proc(call_end_proc, proc);\n    return proc;\n}\n\nvoid\nrb_exec_end_proc()\n{\n    struct end_proc_data *tmp, *volatile link;\n    int status;\n    volatile int safe = ruby_safe_level;\n\n    while (ephemeral_end_procs) {\n        tmp_end_procs = link = ephemeral_end_procs;\n        ephemeral_end_procs = 0;\n        while (link) {\n            PUSH_TAG(PROT_EMPTY);\n            if ((status = EXEC_TAG()) == 0) {\n                ruby_safe_level = link->safe;\n                (*link->func)(link->data);\n            }\n            POP_TAG();\n            if (status) {\n                error_handle(status);\n            }\n            tmp = link;\n            tmp_end_procs = link = link->next;\n            free(tmp);\n        }\n    }\n    while (end_procs) {\n        tmp_end_procs = link = end_procs;\n        end_procs = 0;\n        while (link) {\n            PUSH_TAG(PROT_EMPTY);\n            if ((status = EXEC_TAG()) == 0) {\n                ruby_safe_level = link->safe;\n                (*link->func)(link->data);\n            }\n            POP_TAG();\n            if (status) {\n                error_handle(status);\n            }\n            tmp = link;\n            tmp_end_procs = link = link->next;\n            free(tmp);\n        }\n    }\n    ruby_safe_level = safe;\n}\n\n/*\n *  call-seq:\n *     __method__         => symbol\n *\n *  Returns the name of the current method as a Symbol.\n *  If called from inside of an aliased method it will return the original\n *  nonaliased name.\n *  If called outside of a method, it returns <code>nil</code>.\n *\n *    def foo\n *      __method__\n *    end\n *    alias bar foo\n *\n *    foo                # => :foo\n *    bar                # => :foo\n *\n */\n\nstatic VALUE\nrb_f_method_name()\n{\n    struct FRAME* prev = ruby_frame->prev;\n    if (prev && prev->orig_func) {\n        return ID2SYM(prev->orig_func);\n    }\n    else {\n        return Qnil;\n    }\n}\n\n/* Hash (Thread => Backtrace) used to collect backtrace for each threads. */\nstatic VALUE backtrace_for_each_thread;\n\nstatic int backtrace_level_for_each_thread;\n\nstatic VALUE\nswitch_thread_context_to_collect_backtrace(rb_thread_t next);\n\nstatic VALUE\nrb_f_caller_for_all_threads();\n\nvoid\nInit_eval()\n{\n    init = rb_intern(\"initialize\");\n    eqq = rb_intern(\"===\");\n    each = rb_intern(\"each\");\n\n    aref = rb_intern(\"[]\");\n    aset = rb_intern(\"[]=\");\n    match = rb_intern(\"=~\");\n    missing = rb_intern(\"method_missing\");\n    added = rb_intern(\"method_added\");\n    singleton_added = rb_intern(\"singleton_method_added\");\n    removed = rb_intern(\"method_removed\");\n    singleton_removed = rb_intern(\"singleton_method_removed\");\n    undefined = rb_intern(\"method_undefined\");\n    singleton_undefined = rb_intern(\"singleton_method_undefined\");\n\n    __id__ = rb_intern(\"__id__\");\n    __send__ = rb_intern(\"__send__\");\n\n    rb_global_variable((void *)&top_scope);\n    rb_global_variable((void *)&ruby_eval_tree_begin);\n\n    rb_global_variable((void *)&ruby_eval_tree);\n    rb_global_variable((void *)&ruby_dyna_vars);\n\n    rb_define_virtual_variable(\"$@\", errat_getter, errat_setter);\n    rb_define_hooked_variable(\"$!\", &ruby_errinfo, 0, errinfo_setter);\n\n    rb_define_global_function(\"eval\", rb_f_eval, -1);\n    rb_define_global_function(\"iterator?\", rb_f_block_given_p, 0);\n    rb_define_global_function(\"block_given?\", rb_f_block_given_p, 0);\n    rb_define_global_function(\"method_missing\", rb_method_missing, -1);\n    rb_define_global_function(\"loop\", rb_f_loop, 0);\n\n    rb_define_method(rb_mKernel, \"respond_to?\", obj_respond_to, -1);\n    respond_to   = rb_intern(\"respond_to?\");\n    rb_global_variable((void *)&basic_respond_to);\n    basic_respond_to = rb_method_node(rb_cObject, respond_to);\n\n    rb_define_global_function(\"raise\", rb_f_raise, -1);\n    rb_define_global_function(\"fail\", rb_f_raise, -1);\n\n    rb_define_global_function(\"caller\", rb_f_caller, -1);\n    rb_define_global_function(\"caller_for_all_threads\", rb_f_caller_for_all_threads, -1);\n\n    rb_define_global_function(\"exit\", rb_f_exit, -1);\n    rb_define_global_function(\"abort\", rb_f_abort, -1);\n\n    rb_define_global_function(\"at_exit\", rb_f_at_exit, 0);\n\n    rb_define_global_function(\"catch\", rb_f_catch, 1);\n    rb_define_global_function(\"throw\", rb_f_throw, -1);\n    rb_define_global_function(\"global_variables\", rb_f_global_variables, 0); /* in variable.c */\n    rb_define_global_function(\"local_variables\", rb_f_local_variables, 0);\n\n    rb_define_global_function(\"__method__\", rb_f_method_name, 0);\n\n    rb_define_method(rb_mKernel, \"send\", rb_f_send, -1);\n    rb_define_method(rb_mKernel, \"__send__\", rb_f_send, -1);\n    rb_define_method(rb_mKernel, \"instance_eval\", rb_obj_instance_eval, -1);\n    rb_define_method(rb_mKernel, \"instance_exec\", rb_obj_instance_exec, -1);\n\n    rb_define_private_method(rb_cModule, \"append_features\", rb_mod_append_features, 1);\n    rb_define_private_method(rb_cModule, \"extend_object\", rb_mod_extend_object, 1);\n    rb_define_private_method(rb_cModule, \"include\", rb_mod_include, -1);\n    rb_define_private_method(rb_cModule, \"public\", rb_mod_public, -1);\n    rb_define_private_method(rb_cModule, \"protected\", rb_mod_protected, -1);\n    rb_define_private_method(rb_cModule, \"private\", rb_mod_private, -1);\n    rb_define_private_method(rb_cModule, \"module_function\", rb_mod_modfunc, -1);\n    rb_define_method(rb_cModule, \"method_defined?\", rb_mod_method_defined, 1);\n    rb_define_method(rb_cModule, \"public_method_defined?\", rb_mod_public_method_defined, 1);\n    rb_define_method(rb_cModule, \"private_method_defined?\", rb_mod_private_method_defined, 1);\n    rb_define_method(rb_cModule, \"protected_method_defined?\", rb_mod_protected_method_defined, 1);\n    rb_define_method(rb_cModule, \"public_class_method\", rb_mod_public_method, -1);\n    rb_define_method(rb_cModule, \"private_class_method\", rb_mod_private_method, -1);\n    rb_define_method(rb_cModule, \"module_eval\", rb_mod_module_eval, -1);\n    rb_define_method(rb_cModule, \"module_exec\", rb_mod_module_exec, -1);\n    rb_define_method(rb_cModule, \"class_eval\", rb_mod_module_eval, -1);\n    rb_define_method(rb_cModule, \"class_exec\", rb_mod_module_exec, -1);\n\n    rb_undef_method(rb_cClass, \"module_function\");\n\n    rb_define_private_method(rb_cModule, \"remove_method\", rb_mod_remove_method, -1);\n    rb_define_private_method(rb_cModule, \"undef_method\", rb_mod_undef_method, -1);\n    rb_define_private_method(rb_cModule, \"alias_method\", rb_mod_alias_method, 2);\n    rb_define_private_method(rb_cModule, \"define_method\", rb_mod_define_method, -1);\n\n    rb_define_singleton_method(rb_cModule, \"nesting\", rb_mod_nesting, 0);\n    rb_define_singleton_method(rb_cModule, \"constants\", rb_mod_s_constants, 0);\n\n    rb_define_singleton_method(ruby_top_self, \"include\", top_include, -1);\n    rb_define_singleton_method(ruby_top_self, \"public\", top_public, -1);\n    rb_define_singleton_method(ruby_top_self, \"private\", top_private, -1);\n\n    rb_define_method(rb_mKernel, \"extend\", rb_obj_extend, -1);\n\n    rb_define_global_function(\"trace_var\", rb_f_trace_var, -1); /* in variable.c */\n    rb_define_global_function(\"untrace_var\", rb_f_untrace_var, -1); /* in variable.c */\n\n    rb_define_global_function(\"set_trace_func\", set_trace_func, 1);\n    rb_global_variable(&trace_func);\n\n    rb_define_virtual_variable(\"$SAFE\", safe_getter, safe_setter);\n}\n\n/*\n *  call-seq:\n *     mod.autoload(name, filename)   => nil\n *\n *  Registers _filename_ to be loaded (using <code>Kernel::require</code>)\n *  the first time that _name_ (which may be a <code>String</code> or\n *  a symbol) is accessed in the namespace of _mod_.\n *\n *     module A\n *     end\n *     A.autoload(:B, \"b\")\n *     A::B.doit            # autoloads \"b\"\n */\n\nstatic VALUE\nrb_mod_autoload(mod, sym, file)\n    VALUE mod;\n    VALUE sym;\n    VALUE file;\n{\n    ID id = rb_to_id(sym);\n\n    Check_SafeStr(file);\n    rb_autoload(mod, id, RSTRING(file)->ptr);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     mod.autoload?(name)   => String or nil\n *\n *  Returns _filename_ to be loaded if _name_ is registered as\n *  +autoload+ in the namespace of _mod_.\n *\n *     module A\n *     end\n *     A.autoload(:B, \"b\")\n *     A.autoload?(:B)            # => \"b\"\n */\n\nstatic VALUE\nrb_mod_autoload_p(mod, sym)\n    VALUE mod, sym;\n{\n    return rb_autoload_p(mod, rb_to_id(sym));\n}\n\n/*\n *  call-seq:\n *     autoload(module, filename)   => nil\n *\n *  Registers _filename_ to be loaded (using <code>Kernel::require</code>)\n *  the first time that _module_ (which may be a <code>String</code> or\n *  a symbol) is accessed.\n *\n *     autoload(:MyModule, \"/usr/local/lib/modules/my_module.rb\")\n */\n\nstatic VALUE\nrb_f_autoload(obj, sym, file)\n    VALUE obj;\n    VALUE sym;\n    VALUE file;\n{\n    if (NIL_P(ruby_cbase)) {\n        rb_raise(rb_eTypeError, \"no class/module for autoload target\");\n    }\n    return rb_mod_autoload(ruby_cbase, sym, file);\n}\n\n/*\n *  call-seq:\n *     autoload(module, filename)   => nil\n *\n *  Registers _filename_ to be loaded (using <code>Kernel::require</code>)\n *  the first time that _module_ (which may be a <code>String</code> or\n *  a symbol) is accessed.\n *\n *     autoload(:MyModule, \"/usr/local/lib/modules/my_module.rb\")\n */\n\nstatic VALUE\nrb_f_autoload_p(obj, sym)\n    VALUE obj;\n    VALUE sym;\n{\n    /* use ruby_cbase as same as rb_f_autoload. */\n    if (NIL_P(ruby_cbase)) {\n        return Qfalse;\n    }\n    return rb_mod_autoload_p(ruby_cbase, sym);\n}\n\nvoid\nInit_load()\n{\n    rb_define_readonly_variable(\"$:\", &rb_load_path);\n    rb_define_readonly_variable(\"$-I\", &rb_load_path);\n    rb_define_readonly_variable(\"$LOAD_PATH\", &rb_load_path);\n    rb_load_path = rb_ary_new();\n\n    rb_define_readonly_variable(\"$\\\"\", &rb_features);\n    rb_define_readonly_variable(\"$LOADED_FEATURES\", &rb_features);\n    rb_features = rb_ary_new();\n\n    rb_define_global_function(\"load\", rb_f_load, -1);\n    rb_define_global_function(\"require\", rb_f_require, 1);\n    rb_define_method(rb_cModule, \"autoload\",  rb_mod_autoload,   2);\n    rb_define_method(rb_cModule, \"autoload?\", rb_mod_autoload_p, 1);\n    rb_define_global_function(\"autoload\",  rb_f_autoload,   2);\n    rb_define_global_function(\"autoload?\", rb_f_autoload_p, 1);\n    rb_global_variable(&ruby_wrapper);\n\n    rb_global_variable(&ruby_dln_librefs);\n    ruby_dln_librefs = rb_ary_new();\n}\n\nstatic void\nscope_dup(scope)\n    struct SCOPE *scope;\n{\n    ID *tbl;\n    VALUE *vars;\n\n    scope->flags |= SCOPE_DONT_RECYCLE;\n    if (scope->flags & SCOPE_MALLOC) return;\n\n    if (scope->local_tbl) {\n        tbl = scope->local_tbl;\n        vars = ALLOC_N(VALUE, tbl[0]+1);\n        *vars++ = scope->local_vars[-1];\n        MEMCPY(vars, scope->local_vars, VALUE, tbl[0]);\n        scope->local_vars = vars;\n        scope->flags |= SCOPE_MALLOC;\n    }\n}\n\nstatic void\nblk_mark(data)\n    struct BLOCK *data;\n{\n    while (data) {\n        rb_gc_mark_frame(&data->frame);\n        rb_gc_mark((VALUE)data->scope);\n        rb_gc_mark((VALUE)data->var);\n        rb_gc_mark((VALUE)data->body);\n        rb_gc_mark((VALUE)data->self);\n        rb_gc_mark((VALUE)data->dyna_vars);\n        rb_gc_mark((VALUE)data->cref);\n        rb_gc_mark(data->wrapper);\n        rb_gc_mark(data->block_obj);\n        data = data->prev;\n    }\n}\n\nstatic void\nframe_free(frame)\n    struct FRAME *frame;\n{\n    struct FRAME *tmp;\n\n    frame = frame->prev;\n    while (frame) {\n        tmp = frame;\n        frame = frame->prev;\n        free(tmp);\n    }\n}\n\nstatic void\nblk_free(data)\n    struct BLOCK *data;\n{\n    void *tmp;\n\n    while (data) {\n        frame_free(&data->frame);\n        tmp = data;\n        data = data->prev;\n        free(tmp);\n    }\n}\n\nstatic void\nframe_dup(frame)\n    struct FRAME *frame;\n{\n    struct FRAME *tmp;\n\n    for (;;) {\n        frame->tmp = 0;         /* should not preserve tmp */\n        if (!frame->prev) break;\n        tmp = ALLOC(struct FRAME);\n        *tmp = *frame->prev;\n        frame->prev = tmp;\n        frame = tmp;\n    }\n}\n\n\nstatic void\nblk_copy_prev(block)\n    struct BLOCK *block;\n{\n    struct BLOCK *tmp;\n    struct RVarmap* vars;\n\n    while (block->prev) {\n        tmp = ALLOC_N(struct BLOCK, 1);\n        MEMCPY(tmp, block->prev, struct BLOCK, 1);\n        scope_dup(tmp->scope);\n        frame_dup(&tmp->frame);\n\n        for (vars = tmp->dyna_vars; vars; vars = vars->next) {\n            if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;\n            FL_SET(vars, DVAR_DONT_RECYCLE);\n        }\n\n        block->prev = tmp;\n        block = tmp;\n    }\n}\n\n\nstatic void\nblk_dup(dup, orig)\n    struct BLOCK *dup, *orig;\n{\n    MEMCPY(dup, orig, struct BLOCK, 1);\n    frame_dup(&dup->frame);\n\n    if (dup->iter) {\n        blk_copy_prev(dup);\n    }\n    else {\n        dup->prev = 0;\n    }\n}\n\n/*\n * MISSING: documentation\n */\n\nstatic VALUE\nproc_clone(self)\n    VALUE self;\n{\n    struct BLOCK *orig, *data;\n    VALUE bind;\n\n    Data_Get_Struct(self, struct BLOCK, orig);\n    bind = Data_Make_Struct(rb_obj_class(self),struct BLOCK,blk_mark,blk_free,data);\n    CLONESETUP(bind, self);\n    blk_dup(data, orig);\n\n    return bind;\n}\n\n/*\n * MISSING: documentation\n */\n\n#define PROC_TSHIFT (FL_USHIFT+1)\n#define PROC_TMASK  (FL_USER1|FL_USER2|FL_USER3)\n#define PROC_TMAX   (PROC_TMASK >> PROC_TSHIFT)\n\nstatic int proc_get_safe_level(VALUE);\n\nstatic VALUE\nproc_dup(self)\n    VALUE self;\n{\n    struct BLOCK *orig, *data;\n    VALUE bind;\n    int safe = proc_get_safe_level(self);\n\n    Data_Get_Struct(self, struct BLOCK, orig);\n    bind = Data_Make_Struct(rb_obj_class(self),struct BLOCK,blk_mark,blk_free,data);\n    blk_dup(data, orig);\n    if (safe > PROC_TMAX) safe = PROC_TMAX;\n    FL_SET(bind, (safe << PROC_TSHIFT) & PROC_TMASK);\n\n    return bind;\n}\n\nVALUE\nrb_block_dup(self, klass, cref)\n    VALUE self, klass, cref;\n{\n    struct BLOCK *block;\n    VALUE obj = proc_dup(self);\n    Data_Get_Struct(obj, struct BLOCK, block);\n    block->klass = klass;\n    block->cref = NEW_NODE(nd_type(block->cref), cref, block->cref->u2.node,\n                           block->cref->u3.node);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     binding -> a_binding\n *\n *  Returns a +Binding+ object, describing the variable and\n *  method bindings at the point of call. This object can be used when\n *  calling +eval+ to execute the evaluated command in this\n *  environment. Also see the description of class +Binding+.\n *\n *     def getBinding(param)\n *       return binding\n *     end\n *     b = getBinding(\"hello\")\n *     eval(\"param\", b)   #=> \"hello\"\n */\n\nstatic VALUE\nrb_f_binding(self)\n    VALUE self;\n{\n    struct BLOCK *data, *p;\n    struct RVarmap *vars;\n    VALUE bind;\n\n    PUSH_BLOCK(0,0);\n    bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);\n    *data = *ruby_block;\n\n    data->orig_thread = rb_thread_current();\n    data->wrapper = ruby_wrapper;\n    data->iter = rb_f_block_given_p();\n    frame_dup(&data->frame);\n    if (ruby_frame->prev) {\n        data->frame.last_func = ruby_frame->prev->last_func;\n        data->frame.last_class = ruby_frame->prev->last_class;\n        data->frame.orig_func = ruby_frame->prev->orig_func;\n    }\n\n    if (data->iter) {\n        blk_copy_prev(data);\n    }\n    else {\n        data->prev = 0;\n    }\n\n    for (p = data; p; p = p->prev) {\n        for (vars = p->dyna_vars; vars; vars = vars->next) {\n            if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;\n            FL_SET(vars, DVAR_DONT_RECYCLE);\n        }\n    }\n    scope_dup(data->scope);\n    POP_BLOCK();\n\n    return bind;\n}\n\n/*\n *  call-seq:\n *     binding.eval(string [, filename [,lineno]])  => obj\n *\n *  Evaluates the Ruby expression(s) in <em>string</em>, in the\n *  <em>binding</em>'s context.  If the optional <em>filename</em> and\n *  <em>lineno</em> parameters are present, they will be used when\n *  reporting syntax errors.\n *\n *     def getBinding(param)\n *       return binding\n *     end\n *     b = getBinding(\"hello\")\n *     b.eval(\"param\")   #=> \"hello\"\n */\n\nstatic VALUE\nbind_eval(argc, argv, bindval)\n    int argc;\n    VALUE *argv;\n    VALUE bindval;\n{\n    VALUE args[4];\n\n    rb_scan_args(argc, argv, \"12\", &args[0], &args[2], &args[3]);\n    args[1] = bindval;\n    return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */);\n}\n\n#define SAFE_LEVEL_MAX PROC_TMASK\n\nstatic void\nproc_save_safe_level(data)\n    VALUE data;\n{\n    int safe = ruby_safe_level;\n    if (safe > PROC_TMAX) safe = PROC_TMAX;\n    FL_SET(data, (safe << PROC_TSHIFT) & PROC_TMASK);\n}\n\nstatic int\nproc_get_safe_level(data)\n    VALUE data;\n{\n    return (RBASIC(data)->flags & PROC_TMASK) >> PROC_TSHIFT;\n}\n\nstatic void\nproc_set_safe_level(data)\n    VALUE data;\n{\n    ruby_safe_level = proc_get_safe_level(data);\n}\n\nstatic VALUE\nproc_alloc(klass, proc)\n    VALUE klass;\n    int proc;\n{\n    volatile VALUE block;\n    struct BLOCK *data, *p;\n    struct RVarmap *vars;\n\n    if (!rb_block_given_p() && !rb_f_block_given_p()) {\n        rb_raise(rb_eArgError, \"tried to create Proc object without a block\");\n    }\n    if (proc && !rb_block_given_p()) {\n        rb_warn(\"tried to create Proc object without a block\");\n    }\n\n    if (!proc && ruby_block->block_obj && CLASS_OF(ruby_block->block_obj) == klass) {\n        return ruby_block->block_obj;\n    }\n    block = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data);\n    *data = *ruby_block;\n\n    data->orig_thread = rb_thread_current();\n    data->wrapper = ruby_wrapper;\n    data->iter = data->prev?Qtrue:Qfalse;\n    data->block_obj = block;\n    frame_dup(&data->frame);\n    if (data->iter) {\n        blk_copy_prev(data);\n    }\n    else {\n        data->prev = 0;\n    }\n\n    for (p = data; p; p = p->prev) {\n        for (vars = p->dyna_vars; vars; vars = vars->next) {\n            if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;\n            FL_SET(vars, DVAR_DONT_RECYCLE);\n        }\n    }\n    scope_dup(data->scope);\n    proc_save_safe_level(block);\n    if (proc) {\n        data->flags |= BLOCK_LAMBDA;\n    }\n    else {\n        ruby_block->block_obj = block;\n    }\n\n    return block;\n}\n\n/*\n *  call-seq:\n *     Proc.new {|...| block } => a_proc\n *     Proc.new                => a_proc\n *\n *  Creates a new <code>Proc</code> object, bound to the current\n *  context. <code>Proc::new</code> may be called without a block only\n *  within a method with an attached block, in which case that block is\n *  converted to the <code>Proc</code> object.\n *\n *     def proc_from\n *       Proc.new\n *     end\n *     proc = proc_from { \"hello\" }\n *     proc.call   #=> \"hello\"\n */\n\nstatic VALUE\nproc_s_new(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE block = proc_alloc(klass, Qfalse);\n\n    rb_obj_call_init(block, argc, argv);\n    return block;\n}\n\nVALUE\nrb_block_proc()\n{\n    return proc_alloc(rb_cProc, Qfalse);\n}\n\nVALUE\nrb_f_lambda()\n{\n    rb_warn(\"rb_f_lambda() is deprecated; use rb_block_proc() instead\");\n    return proc_alloc(rb_cProc, Qtrue);\n}\n\n/*\n * call-seq:\n *   proc   { |...| block }  => a_proc\n *   lambda { |...| block }  => a_proc\n *\n * Equivalent to <code>Proc.new</code>, except the resulting Proc objects\n * check the number of parameters passed when called.\n */\n\nstatic VALUE\nproc_lambda()\n{\n    return proc_alloc(rb_cProc, Qtrue);\n}\n\nstatic int\nblock_orphan(data)\n    struct BLOCK *data;\n{\n    if (data->scope->flags & SCOPE_NOSTACK) {\n        return 1;\n    }\n    if (data->orig_thread != rb_thread_current()) {\n        return 1;\n    }\n    return 0;\n}\n\nstatic VALUE\nproc_invoke(proc, args, self, klass)\n    VALUE proc, args;           /* OK */\n    VALUE self, klass;\n{\n    struct BLOCK * volatile old_block;\n    struct BLOCK _block;\n    struct BLOCK *data;\n    volatile VALUE result = Qundef;\n    int state;\n    volatile int safe = ruby_safe_level;\n    volatile VALUE old_wrapper = ruby_wrapper;\n    volatile int pcall;\n    int avalue = Qtrue;\n    VALUE tmp = args;\n    VALUE bvar = Qnil;\n\n    if (rb_block_given_p() && ruby_frame->last_func) {\n        if (klass != ruby_frame->last_class)\n            klass = rb_obj_class(proc);\n        bvar = rb_block_proc();\n    }\n\n    Data_Get_Struct(proc, struct BLOCK, data);\n    pcall = (data->flags & BLOCK_LAMBDA) ? YIELD_LAMBDA_CALL : 0;\n    if (!pcall && RARRAY(args)->len == 1) {\n        avalue = Qfalse;\n        args = RARRAY(args)->ptr[0];\n    }\n\n    PUSH_VARS();\n    ruby_wrapper = data->wrapper;\n    ruby_dyna_vars = data->dyna_vars;\n    /* PUSH BLOCK from data */\n    old_block = ruby_block;\n    _block = *data;\n    _block.block_obj = bvar;\n    if (self != Qundef) _block.frame.self = self;\n    if (klass) _block.frame.last_class = klass;\n    _block.frame.argc = RARRAY(tmp)->len;\n    _block.frame.flags = ruby_frame->flags;\n    if (_block.frame.argc && DMETHOD_P()) {\n        NEWOBJ(scope, struct SCOPE);\n        OBJSETUP(scope, tmp, T_SCOPE);\n        scope->local_tbl = _block.scope->local_tbl;\n        scope->local_vars = _block.scope->local_vars;\n        scope->flags |= SCOPE_CLONE | (_block.scope->flags & SCOPE_MALLOC);\n        _block.scope = scope;\n    }\n    /* modify current frame */\n    ruby_block = &_block;\n    PUSH_ITER(ITER_CUR);\n    ruby_frame->iter = ITER_CUR;\n    PUSH_TAG(pcall ? PROT_LAMBDA : PROT_EMPTY);\n    state = EXEC_TAG();\n    if (state == 0) {\n        proc_set_safe_level(proc);\n        result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0,\n                            pcall | YIELD_PROC_CALL, avalue);\n    }\n    else if (TAG_DST()) {\n        result = prot_tag->retval;\n    }\n    POP_TAG();\n    POP_ITER();\n    ruby_block = old_block;\n    ruby_wrapper = old_wrapper;\n    POP_VARS();\n    ruby_safe_level = safe;\n\n    switch (state) {\n      case 0:\n        break;\n      case TAG_RETRY:\n        proc_jump_error(TAG_RETRY, Qnil); /* xxx */\n        JUMP_TAG(state);\n        break;\n      case TAG_NEXT:\n      case TAG_BREAK:\n        if (!pcall && result != Qundef) {\n            proc_jump_error(state, result);\n        }\n      case TAG_RETURN:\n        if (result != Qundef) {\n            if (pcall) break;\n            return_jump(result);\n        }\n      default:\n        JUMP_TAG(state);\n    }\n    return result;\n}\n\n/* CHECKME: are the argument checking semantics correct? */\n\n/*\n *  call-seq:\n *     prc.call(params,...)   => obj\n *     prc[params,...]        => obj\n *\n *  Invokes the block, setting the block's parameters to the values in\n *  <i>params</i> using something close to method calling semantics.\n *  Generates a warning if multiple values are passed to a proc that\n *  expects just one (previously this silently converted the parameters\n *  to an array).\n *\n *  For procs created using <code>Kernel.proc</code>, generates an\n *  error if the wrong number of parameters\n *  are passed to a proc with multiple parameters. For procs created using\n *  <code>Proc.new</code>, extra parameters are silently discarded.\n *\n *  Returns the value of the last expression evaluated in the block. See\n *  also <code>Proc#yield</code>.\n *\n *     a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}\n *     a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]\n *     a_proc[9, 1, 2, 3]        #=> [9, 18, 27]\n *     a_proc = Proc.new {|a,b| a}\n *     a_proc.call(1,2,3)\n *\n *  <em>produces:</em>\n *\n *     prog.rb:5: wrong number of arguments (3 for 2) (ArgumentError)\n *      from prog.rb:4:in `call'\n *      from prog.rb:5\n */\n\nVALUE\nrb_proc_call(proc, args)\n    VALUE proc, args;           /* OK */\n{\n    return proc_invoke(proc, args, Qundef, 0);\n}\n\nstatic VALUE bmcall _((VALUE, VALUE));\nstatic VALUE method_arity _((VALUE));\n\n/*\n *  call-seq:\n *     prc.arity -> fixnum\n *\n *  Returns the number of arguments that would not be ignored. If the block\n *  is declared to take no arguments, returns 0. If the block is known\n *  to take exactly n arguments, returns n. If the block has optional\n *  arguments, return -n-1, where n is the number of mandatory\n *  arguments. A <code>proc</code> with no argument declarations\n *  is the same a block declaring <code>||</code> as its arguments.\n *\n *     Proc.new {}.arity          #=>  0\n *     Proc.new {||}.arity        #=>  0\n *     Proc.new {|a|}.arity       #=>  1\n *     Proc.new {|a,b|}.arity     #=>  2\n *     Proc.new {|a,b,c|}.arity   #=>  3\n *     Proc.new {|*a|}.arity      #=> -1\n *     Proc.new {|a,*b|}.arity    #=> -2\n */\n\nstatic VALUE\nproc_arity(proc)\n    VALUE proc;\n{\n    struct BLOCK *data;\n    NODE *var, *list;\n    int n;\n\n    Data_Get_Struct(proc, struct BLOCK, data);\n    var = data->var;\n    if (var == 0) {\n        if (data->body && nd_type(data->body) == NODE_IFUNC &&\n            data->body->nd_cfnc == bmcall) {\n            return method_arity(data->body->nd_tval);\n        }\n        return INT2FIX(-1);\n    }\n    if (var == (NODE*)1) return INT2FIX(0);\n    if (var == (NODE*)2) return INT2FIX(0);\n    if (nd_type(var) == NODE_BLOCK_ARG) {\n        var = var->nd_args;\n        if (var == (NODE*)1) return INT2FIX(0);\n        if (var == (NODE*)2) return INT2FIX(0);\n    }\n    switch (nd_type(var)) {\n      default:\n        return INT2FIX(1);\n      case NODE_MASGN:\n        list = var->nd_head;\n        n = 0;\n        while (list) {\n            n++;\n            list = list->nd_next;\n        }\n        if (var->nd_args) return INT2FIX(-n-1);\n        return INT2FIX(n);\n    }\n}\n\n/*\n * call-seq:\n *   prc == other_proc   =>  true or false\n *\n * Return <code>true</code> if <i>prc</i> is the same object as\n * <i>other_proc</i>, or if they are both procs with the same body.\n */\n\nstatic VALUE\nproc_eq(self, other)\n    VALUE self, other;\n{\n    struct BLOCK *data, *data2;\n\n    if (self == other) return Qtrue;\n    if (TYPE(other) != T_DATA) return Qfalse;\n    if (RDATA(other)->dmark != (RUBY_DATA_FUNC)blk_mark) return Qfalse;\n    if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;\n    Data_Get_Struct(self, struct BLOCK, data);\n    Data_Get_Struct(other, struct BLOCK, data2);\n    if (data->body != data2->body) return Qfalse;\n    if (data->var != data2->var) return Qfalse;\n    if (data->scope != data2->scope) return Qfalse;\n    if (data->dyna_vars != data2->dyna_vars) return Qfalse;\n    if (data->flags != data2->flags) return Qfalse;\n\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *   prc.to_s   => string\n *\n * Shows the unique identifier for this proc, along with\n * an indication of where the proc was defined.\n */\n\nstatic VALUE\nproc_to_s(self)\n    VALUE self;\n{\n    struct BLOCK *data;\n    NODE *node;\n    const char *cname = rb_obj_classname(self);\n    const int w = (sizeof(VALUE) * CHAR_BIT) / 4;\n    long len = strlen(cname)+6+w; /* 6:tags 16:addr */\n    VALUE str;\n\n    Data_Get_Struct(self, struct BLOCK, data);\n    if ((node = data->frame.node) || (node = data->body)) {\n        len += strlen(node->nd_file) + 2 + (SIZEOF_LONG*CHAR_BIT-NODE_LSHIFT)/3;\n        str = rb_str_new(0, len);\n        snprintf(RSTRING(str)->ptr, len+1,\n                 \"#<%s:0x%.*lx@%s:%d>\", cname, w, (VALUE)data->body,\n                 node->nd_file, nd_line(node));\n    }\n    else {\n        str = rb_str_new(0, len);\n        snprintf(RSTRING(str)->ptr, len+1,\n                 \"#<%s:0x%.*lx>\", cname, w, (VALUE)data->body);\n    }\n    RSTRING(str)->len = strlen(RSTRING(str)->ptr);\n    if (OBJ_TAINTED(self)) OBJ_TAINT(str);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     prc.to_proc -> prc\n *\n *  Part of the protocol for converting objects to <code>Proc</code>\n *  objects. Instances of class <code>Proc</code> simply return\n *  themselves.\n */\n\nstatic VALUE\nproc_to_self(self)\n    VALUE self;\n{\n    return self;\n}\n\n/*\n *  call-seq:\n *     prc.binding    => binding\n *\n *  Returns the binding associated with <i>prc</i>. Note that\n *  <code>Kernel#eval</code> accepts either a <code>Proc</code> or a\n *  <code>Binding</code> object as its second parameter.\n *\n *     def fred(param)\n *       proc {}\n *     end\n *\n *     b = fred(99)\n *     eval(\"param\", b.binding)   #=> 99\n *     eval(\"param\", b)           #=> 99\n */\n\nstatic VALUE\nproc_binding(proc)\n    VALUE proc;\n{\n    struct BLOCK *orig, *data;\n    VALUE bind;\n\n    Data_Get_Struct(proc, struct BLOCK, orig);\n    bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);\n    MEMCPY(data, orig, struct BLOCK, 1);\n    frame_dup(&data->frame);\n\n    if (data->iter) {\n        blk_copy_prev(data);\n    }\n    else {\n        data->prev = 0;\n    }\n\n    return bind;\n}\n\nstatic VALUE\nblock_pass(self, node)\n    VALUE self;\n    NODE *node;\n{\n    VALUE proc = rb_eval(self, node->nd_body);  /* OK */\n    VALUE b;\n    struct BLOCK * volatile old_block;\n    struct BLOCK _block;\n    struct BLOCK *data;\n    VALUE result;\n    int state;\n    volatile int orphan;\n    volatile int safe = ruby_safe_level;\n\n    if (NIL_P(proc)) {\n        PUSH_ITER(ITER_NOT);\n        result = rb_eval(self, node->nd_iter);\n        POP_ITER();\n        return result;\n    }\n    if (!rb_obj_is_proc(proc)) {\n        b = rb_check_convert_type(proc, T_DATA, \"Proc\", \"to_proc\");\n        if (!rb_obj_is_proc(b)) {\n            rb_raise(rb_eTypeError, \"wrong argument type %s (expected Proc)\",\n                     rb_obj_classname(proc));\n        }\n        proc = b;\n    }\n\n    if (ruby_safe_level >= 1 && OBJ_TAINTED(proc) &&\n        ruby_safe_level > proc_get_safe_level(proc)) {\n        rb_raise(rb_eSecurityError, \"Insecure: tainted block value\");\n    }\n\n    if (ruby_block && ruby_block->block_obj == proc) {\n        PUSH_ITER(ITER_PAS);\n        result = rb_eval(self, node->nd_iter);\n        POP_ITER();\n        return result;\n    }\n\n    Data_Get_Struct(proc, struct BLOCK, data);\n    orphan = block_orphan(data);\n\n    /* PUSH BLOCK from data */\n    old_block = ruby_block;\n    _block = *data;\n    _block.outer = ruby_block;\n    if (orphan) _block.uniq = block_unique++;\n    ruby_block = &_block;\n    PUSH_ITER(ITER_PRE);\n    if (ruby_frame->iter == ITER_NOT)\n        ruby_frame->iter = ITER_PRE;\n\n    PUSH_TAG(PROT_LOOP);\n    state = EXEC_TAG();\n    switch (state) {\n      case TAG_RETRY:\n        state = 0;\n      case 0:\n        proc_set_safe_level(proc);\n        if (safe > ruby_safe_level)\n            ruby_safe_level = safe;\n        result = rb_eval(self, node->nd_iter);\n        break;\n      case TAG_BREAK:\n        result = Qnil;\n        if (TAG_DST()) {\n          result = prot_tag->retval;\n          state = 0;\n        }\n        break;\n      default:\n        result = Qnil;\n    }\n    POP_TAG();\n    POP_ITER();\n    ruby_block = old_block;\n    ruby_safe_level = safe;\n\n    switch (state) {/* escape from orphan block */\n      case 0:\n        break;\n      case TAG_RETURN:\n        if (orphan) {\n            proc_jump_error(state, prot_tag->retval);\n        }\n      default:\n        JUMP_TAG(state);\n    }\n\n    return result;\n}\n\nstruct METHOD {\n    VALUE klass, rklass;\n    VALUE recv;\n    ID id, oid;\n    int safe_level;\n    NODE *body;\n};\n\nstatic void\nbm_mark(data)\n    struct METHOD *data;\n{\n    rb_gc_mark(data->rklass);\n    rb_gc_mark(data->klass);\n    rb_gc_mark(data->recv);\n    rb_gc_mark((VALUE)data->body);\n}\n\nstatic VALUE\nmnew(klass, obj, id, mklass)\n    VALUE klass, obj, mklass;\n    ID id;\n{\n    VALUE method;\n    NODE *body;\n    int noex;\n    struct METHOD *data;\n    VALUE rklass = klass;\n    ID oid = id;\n\n  again:\n    if ((body = rb_get_method_body(&klass, &oid, &noex)) == 0) {\n        print_undef(rklass, id);\n    }\n\n    if (nd_type(body) == NODE_ZSUPER) {\n        klass = RCLASS(klass)->super;\n        goto again;\n    }\n\n    while (rklass != klass &&\n           (FL_TEST(rklass, FL_SINGLETON) || TYPE(rklass) == T_ICLASS)) {\n        rklass = RCLASS(rklass)->super;\n    }\n    if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass;\n    method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data);\n    data->klass = klass;\n    data->recv = obj;\n    data->id = id;\n    data->body = body;\n    data->rklass = rklass;\n    data->oid = oid;\n    data->safe_level = NOEX_WITH_SAFE(noex);\n    OBJ_INFECT(method, klass);\n\n    return method;\n}\n\n\n/**********************************************************************\n *\n * Document-class : Method\n *\n *  Method objects are created by <code>Object#method</code>, and are\n *  associated with a particular object (not just with a class). They\n *  may be used to invoke the method within the object, and as a block\n *  associated with an iterator. They may also be unbound from one\n *  object (creating an <code>UnboundMethod</code>) and bound to\n *  another.\n *\n *     class Thing\n *       def square(n)\n *         n*n\n *       end\n *     end\n *     thing = Thing.new\n *     meth  = thing.method(:square)\n *\n *     meth.call(9)                 #=> 81\n *     [ 1, 2, 3 ].collect(&meth)   #=> [1, 4, 9]\n *\n */\n\n/*\n * call-seq:\n *   meth == other_meth  => true or false\n *\n * Two method objects are equal if that are bound to the same\n * object and contain the same body.\n */\n\n\nstatic VALUE\nmethod_eq(method, other)\n    VALUE method, other;\n{\n    struct METHOD *m1, *m2;\n\n    if (TYPE(other) != T_DATA || RDATA(other)->dmark != (RUBY_DATA_FUNC)bm_mark)\n        return Qfalse;\n    if (CLASS_OF(method) != CLASS_OF(other))\n        return Qfalse;\n\n    Data_Get_Struct(method, struct METHOD, m1);\n    Data_Get_Struct(other, struct METHOD, m2);\n\n    if (m1->klass != m2->klass || m1->rklass != m2->rklass ||\n        m1->recv != m2->recv || m1->body != m2->body)\n        return Qfalse;\n\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     meth.unbind    => unbound_method\n *\n *  Dissociates <i>meth</i> from it's current receiver. The resulting\n *  <code>UnboundMethod</code> can subsequently be bound to a new object\n *  of the same class (see <code>UnboundMethod</code>).\n */\n\nstatic VALUE\nmethod_unbind(obj)\n    VALUE obj;\n{\n    VALUE method;\n    struct METHOD *orig, *data;\n\n    Data_Get_Struct(obj, struct METHOD, orig);\n    method = Data_Make_Struct(rb_cUnboundMethod, struct METHOD, bm_mark, free, data);\n    data->klass = orig->klass;\n    data->recv = Qundef;\n    data->id = orig->id;\n    data->body = orig->body;\n    data->rklass = orig->rklass;\n    data->oid = orig->oid;\n    OBJ_INFECT(method, obj);\n\n    return method;\n}\n\n/*\n *  call-seq:\n *     meth.receiver    => object\n *\n *  Returns the bound receiver of the method object.\n */\n\nstatic VALUE\nmethod_receiver(obj)\n    VALUE obj;\n{\n    struct METHOD *data;\n\n    Data_Get_Struct(obj, struct METHOD, data);\n    return data->recv;\n}\n\n/*\n *  call-seq:\n *     meth.name    => string\n *\n *  Returns the name of the method.\n */\n\nstatic VALUE\nmethod_name(obj)\n    VALUE obj;\n{\n    struct METHOD *data;\n\n    Data_Get_Struct(obj, struct METHOD, data);\n    return rb_str_new2(rb_id2name(data->id));\n}\n\n/*\n *  call-seq:\n *     meth.owner    => class_or_module\n *\n *  Returns the class or module that defines the method.\n */\n\nstatic VALUE\nmethod_owner(obj)\n    VALUE obj;\n{\n    struct METHOD *data;\n\n    Data_Get_Struct(obj, struct METHOD, data);\n    return data->klass;\n}\n\n/*\n *  call-seq:\n *     obj.method(sym)    => method\n *\n *  Looks up the named method as a receiver in <i>obj</i>, returning a\n *  <code>Method</code> object (or raising <code>NameError</code>). The\n *  <code>Method</code> object acts as a closure in <i>obj</i>'s object\n *  instance, so instance variables and the value of <code>self</code>\n *  remain available.\n *\n *     class Demo\n *       def initialize(n)\n *         @iv = n\n *       end\n *       def hello()\n *         \"Hello, @iv = #{@iv}\"\n *       end\n *     end\n *\n *     k = Demo.new(99)\n *     m = k.method(:hello)\n *     m.call   #=> \"Hello, @iv = 99\"\n *\n *     l = Demo.new('Fred')\n *     m = l.method(\"hello\")\n *     m.call   #=> \"Hello, @iv = Fred\"\n */\n\nVALUE\nrb_obj_method(obj, vid)\n    VALUE obj;\n    VALUE vid;\n{\n    return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod);\n}\n\n/*\n *  call-seq:\n *     mod.instance_method(symbol)   => unbound_method\n *\n *  Returns an +UnboundMethod+ representing the given\n *  instance method in _mod_.\n *\n *     class Interpreter\n *       def do_a() print \"there, \"; end\n *       def do_d() print \"Hello \";  end\n *       def do_e() print \"!\\n\";     end\n *       def do_v() print \"Dave\";    end\n *       Dispatcher = {\n *        ?a => instance_method(:do_a),\n *        ?d => instance_method(:do_d),\n *        ?e => instance_method(:do_e),\n *        ?v => instance_method(:do_v)\n *       }\n *       def interpret(string)\n *         string.each_byte {|b| Dispatcher[b].bind(self).call }\n *       end\n *     end\n *\n *\n *     interpreter = Interpreter.new\n *     interpreter.interpret('dave')\n *\n *  <em>produces:</em>\n *\n *     Hello there, Dave!\n */\n\nstatic VALUE\nrb_mod_method(mod, vid)\n    VALUE mod;\n    VALUE vid;\n{\n    return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod);\n}\n\n/*\n * MISSING: documentation\n */\n\nstatic VALUE\nmethod_clone(self)\n    VALUE self;\n{\n    VALUE clone;\n    struct METHOD *orig, *data;\n\n    Data_Get_Struct(self, struct METHOD, orig);\n    clone = Data_Make_Struct(CLASS_OF(self),struct METHOD, bm_mark, free, data);\n    CLONESETUP(clone, self);\n    *data = *orig;\n\n    return clone;\n}\n\nVALUE\nrb_method_dup(self, klass, cref)\n    VALUE self;\n    VALUE klass;\n    VALUE cref;\n{\n    VALUE clone;\n    struct METHOD *orig, *data;\n\n    Data_Get_Struct(self, struct METHOD, orig);\n    clone = Data_Make_Struct(CLASS_OF(self),struct METHOD, bm_mark, free, data);\n    *data = *orig;\n    data->rklass = klass;\n    if (data->body->nd_rval) {\n        NODE *tmp = NEW_NODE(nd_type(data->body->u2.node), cref,\n                             data->body->u2.node->u2.node,\n                             data->body->u2.node->u3.node);\n        data->body = NEW_NODE(nd_type(data->body), data->body->u1.node, tmp,\n                              data->body->u3.node);\n    }\n    return clone;\n}\n\n/*\n *  call-seq:\n *     meth.call(args, ...)    => obj\n *     meth[args, ...]         => obj\n *\n *  Invokes the <i>meth</i> with the specified arguments, returning the\n *  method's return value.\n *\n *     m = 12.method(\"+\")\n *     m.call(3)    #=> 15\n *     m.call(20)   #=> 32\n */\n\nstatic VALUE\nmethod_call(argc, argv, method)\n    int argc;\n    VALUE *argv;\n    VALUE method;\n{\n    VALUE result = Qnil;        /* OK */\n    struct METHOD *data;\n    int safe;\n\n    Data_Get_Struct(method, struct METHOD, data);\n    if (data->recv == Qundef) {\n        rb_raise(rb_eTypeError, \"can't call unbound method; bind first\");\n    }\n    if (OBJ_TAINTED(method)) {\n        safe = NOEX_WITH(data->safe_level, 4)|NOEX_TAINTED;\n    }\n    else {\n        safe = data->safe_level;\n    }\n    PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);\n    result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,safe);\n    POP_ITER();\n    return result;\n}\n\n/**********************************************************************\n *\n * Document-class: UnboundMethod\n *\n *  Ruby supports two forms of objectified methods. Class\n *  <code>Method</code> is used to represent methods that are associated\n *  with a particular object: these method objects are bound to that\n *  object. Bound method objects for an object can be created using\n *  <code>Object#method</code>.\n *\n *  Ruby also supports unbound methods; methods objects that are not\n *  associated with a particular object. These can be created either by\n *  calling <code>Module#instance_method</code> or by calling\n *  <code>unbind</code> on a bound method object. The result of both of\n *  these is an <code>UnboundMethod</code> object.\n *\n *  Unbound methods can only be called after they are bound to an\n *  object. That object must be be a kind_of? the method's original\n *  class.\n *\n *     class Square\n *       def area\n *         @side * @side\n *       end\n *       def initialize(side)\n *         @side = side\n *       end\n *     end\n *\n *     area_un = Square.instance_method(:area)\n *\n *     s = Square.new(12)\n *     area = area_un.bind(s)\n *     area.call   #=> 144\n *\n *  Unbound methods are a reference to the method at the time it was\n *  objectified: subsequent changes to the underlying class will not\n *  affect the unbound method.\n *\n *     class Test\n *       def test\n *         :original\n *       end\n *     end\n *     um = Test.instance_method(:test)\n *     class Test\n *       def test\n *         :modified\n *       end\n *     end\n *     t = Test.new\n *     t.test            #=> :modified\n *     um.bind(t).call   #=> :original\n *\n */\n\n/*\n *  call-seq:\n *     umeth.bind(obj) -> method\n *\n *  Bind <i>umeth</i> to <i>obj</i>. If <code>Klass</code> was the class\n *  from which <i>umeth</i> was obtained,\n *  <code>obj.kind_of?(Klass)</code> must be true.\n *\n *     class A\n *       def test\n *         puts \"In test, class = #{self.class}\"\n *       end\n *     end\n *     class B < A\n *     end\n *     class C < B\n *     end\n *\n *\n *     um = B.instance_method(:test)\n *     bm = um.bind(C.new)\n *     bm.call\n *     bm = um.bind(B.new)\n *     bm.call\n *     bm = um.bind(A.new)\n *     bm.call\n *\n *  <em>produces:</em>\n *\n *     In test, class = C\n *     In test, class = B\n *     prog.rb:16:in `bind': bind argument must be an instance of B (TypeError)\n *      from prog.rb:16\n */\n\nstatic VALUE\numethod_bind(method, recv)\n    VALUE method, recv;\n{\n    struct METHOD *data, *bound;\n    VALUE rklass = CLASS_OF(recv);\n\n    Data_Get_Struct(method, struct METHOD, data);\n    if (data->rklass != rklass) {\n        if (FL_TEST(data->rklass, FL_SINGLETON)) {\n            rb_raise(rb_eTypeError, \"singleton method bound for a different object\");\n        }\n        if (TYPE(data->rklass) == T_MODULE) {\n            st_table *m_tbl = RCLASS(data->rklass)->m_tbl;\n            while (RCLASS(rklass)->m_tbl != m_tbl) {\n                rklass = RCLASS(rklass)->super;\n                if (!rklass) goto not_instace;\n            }\n        }\n        else if (!rb_obj_is_kind_of(recv, data->rklass)) {\n          not_instace:\n            rb_raise(rb_eTypeError, \"bind argument must be an instance of %s\",\n                     rb_class2name(data->rklass));\n        }\n    }\n\n    method = Data_Make_Struct(rb_cMethod,struct METHOD,bm_mark,free,bound);\n    *bound = *data;\n    bound->recv = recv;\n    bound->rklass = rklass;\n\n    return method;\n}\n\n/*\n *  call-seq:\n *     meth.arity    => fixnum\n *\n *  Returns an indication of the number of arguments accepted by a\n *  method. Returns a nonnegative integer for methods that take a fixed\n *  number of arguments. For Ruby methods that take a variable number of\n *  arguments, returns -n-1, where n is the number of required\n *  arguments. For methods written in C, returns -1 if the call takes a\n *  variable number of arguments.\n *\n *     class C\n *       def one;    end\n *       def two(a); end\n *       def three(*a);  end\n *       def four(a, b); end\n *       def five(a, b, *c);    end\n *       def six(a, b, *c, &d); end\n *     end\n *     c = C.new\n *     c.method(:one).arity     #=> 0\n *     c.method(:two).arity     #=> 1\n *     c.method(:three).arity   #=> -1\n *     c.method(:four).arity    #=> 2\n *     c.method(:five).arity    #=> -3\n *     c.method(:six).arity     #=> -3\n *\n *     \"cat\".method(:size).arity      #=> 0\n *     \"cat\".method(:replace).arity   #=> 1\n *     \"cat\".method(:squeeze).arity   #=> -1\n *     \"cat\".method(:count).arity     #=> -1\n */\n\nstatic VALUE\nmethod_arity(method)\n    VALUE method;\n{\n    struct METHOD *data;\n    NODE *body;\n    int n;\n\n    Data_Get_Struct(method, struct METHOD, data);\n\n    body = data->body;\n    switch (nd_type(body)) {\n      case NODE_CFUNC:\n        if (body->nd_argc < 0) return INT2FIX(-1);\n        return INT2FIX(body->nd_argc);\n      case NODE_ZSUPER:\n        return INT2FIX(-1);\n      case NODE_ATTRSET:\n        return INT2FIX(1);\n      case NODE_IVAR:\n        return INT2FIX(0);\n      case NODE_BMETHOD:\n        return proc_arity(body->nd_cval);\n      case NODE_DMETHOD:\n        return method_arity(body->nd_cval);\n      case NODE_SCOPE:\n        body = body->nd_next;   /* skip NODE_SCOPE */\n        if (nd_type(body) == NODE_BLOCK)\n            body = body->nd_head;\n        if (!body) return INT2FIX(0);\n        n = body->nd_cnt;\n        if (body->nd_opt || body->nd_rest)\n            n = -n-1;\n        return INT2FIX(n);\n      default:\n        rb_raise(rb_eArgError, \"invalid node 0x%x\", nd_type(body));\n   }\n}\n\n/*\n *  call-seq:\n *   meth.to_s      =>  string\n *   meth.inspect   =>  string\n *\n *  Show the name of the underlying method.\n *\n *    \"cat\".method(:count).inspect   #=> \"#<Method: String#count>\"\n */\n\nstatic VALUE\nmethod_inspect(method)\n    VALUE method;\n{\n    struct METHOD *data;\n    VALUE str;\n    const char *s;\n    const char *sharp = \"#\";\n\n    Data_Get_Struct(method, struct METHOD, data);\n    str = rb_str_buf_new2(\"#<\");\n    s = rb_obj_classname(method);\n    rb_str_buf_cat2(str, s);\n    rb_str_buf_cat2(str, \": \");\n\n    if (FL_TEST(data->klass, FL_SINGLETON)) {\n        VALUE v = rb_iv_get(data->klass, \"__attached__\");\n\n        if (data->recv == Qundef) {\n            rb_str_buf_append(str, rb_inspect(data->klass));\n        }\n        else if (data->recv == v) {\n            rb_str_buf_append(str, rb_inspect(v));\n            sharp = \".\";\n        }\n        else {\n            rb_str_buf_append(str, rb_inspect(data->recv));\n            rb_str_buf_cat2(str, \"(\");\n            rb_str_buf_append(str, rb_inspect(v));\n            rb_str_buf_cat2(str, \")\");\n            sharp = \".\";\n        }\n    }\n    else {\n        rb_str_buf_cat2(str, rb_class2name(data->rklass));\n        if (data->rklass != data->klass) {\n            rb_str_buf_cat2(str, \"(\");\n            rb_str_buf_cat2(str, rb_class2name(data->klass));\n            rb_str_buf_cat2(str, \")\");\n        }\n    }\n    rb_str_buf_cat2(str, sharp);\n    rb_str_buf_cat2(str, rb_id2name(data->id));\n    rb_str_buf_cat2(str, \">\");\n\n    return str;\n}\n\nstatic VALUE\nmproc(method)\n    VALUE method;\n{\n    VALUE proc;\n\n    /* emulate ruby's method call */\n    PUSH_ITER(ITER_CUR);\n    PUSH_FRAME();\n    _frame.last_class = 0;\n    proc = rb_block_proc();\n    POP_FRAME();\n    POP_ITER();\n\n    return proc;\n}\n\nstatic VALUE\nbmcall(args, method)\n    VALUE args, method;\n{\n    VALUE a = svalue_to_avalue(args);\n    VALUE ret = method_call(RARRAY(a)->len, RARRAY(a)->ptr, method);\n    RB_GC_GUARD(a);  /* ensure a is not GC'd during method_call */\n    return ret;\n}\n\nVALUE\nrb_proc_new(func, val)\n    VALUE (*func)(ANYARGS);     /* VALUE yieldarg[, VALUE procarg] */\n    VALUE val;\n{\n    struct BLOCK *data;\n    VALUE proc = rb_iterate((VALUE(*)_((VALUE)))mproc, 0, func, val);\n\n    Data_Get_Struct(proc, struct BLOCK, data);\n    data->body->nd_state = YIELD_FUNC_LAMBDA;\n    data->flags |= BLOCK_LAMBDA;\n    return proc;\n}\n\n/*\n *  call-seq:\n *     meth.to_proc    => prc\n *\n *  Returns a <code>Proc</code> object corresponding to this method.\n */\n\nstatic VALUE\nmethod_proc(method)\n    VALUE method;\n{\n    VALUE proc;\n    struct METHOD *mdata;\n    struct BLOCK *bdata;\n\n    proc = rb_iterate((VALUE(*)_((VALUE)))mproc, 0, bmcall, method);\n    Data_Get_Struct(method, struct METHOD, mdata);\n    Data_Get_Struct(proc, struct BLOCK, bdata);\n    bdata->body->nd_file = mdata->body->nd_file;\n    nd_set_line(bdata->body, nd_line(mdata->body));\n    bdata->body->nd_state = YIELD_FUNC_SVALUE;\n\n    return proc;\n}\n\nstatic VALUE\nrb_obj_is_method(m)\n    VALUE m;\n{\n    if (TYPE(m) == T_DATA && RDATA(m)->dmark == (RUBY_DATA_FUNC)bm_mark) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     define_method(symbol, method)     => new_method\n *     define_method(symbol) { block }   => proc\n *\n *  Defines an instance method in the receiver. The _method_\n *  parameter can be a +Proc+ or +Method+ object.\n *  If a block is specified, it is used as the method body. This block\n *  is evaluated using <code>instance_eval</code>, a point that is\n *  tricky to demonstrate because <code>define_method</code> is private.\n *  (This is why we resort to the +send+ hack in this example.)\n *\n *     class A\n *       def fred\n *         puts \"In Fred\"\n *       end\n *       def create_method(name, &block)\n *         self.class.send(:define_method, name, &block)\n *       end\n *       define_method(:wilma) { puts \"Charge it!\" }\n *     end\n *     class B < A\n *       define_method(:barney, instance_method(:fred))\n *     end\n *     a = B.new\n *     a.barney\n *     a.wilma\n *     a.create_method(:betty) { p self }\n *     a.betty\n *\n *  <em>produces:</em>\n *\n *     In Fred\n *     Charge it!\n *     #<B:0x401b39e8>\n */\n\nstatic VALUE\nrb_mod_define_method(argc, argv, mod)\n    int argc;\n    VALUE *argv;\n    VALUE mod;\n{\n    ID id;\n    VALUE body;\n    NODE *node;\n    int noex;\n\n    if (argc == 1) {\n        id = rb_to_id(argv[0]);\n        body = proc_lambda();\n    }\n    else if (argc == 2) {\n        id = rb_to_id(argv[0]);\n        body = argv[1];\n        if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) {\n            rb_raise(rb_eTypeError, \"wrong argument type %s (expected Proc/Method)\",\n                     rb_obj_classname(body));\n        }\n    }\n    else {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 1)\", argc);\n    }\n    GC_DEBUG_SET_SOURCE\n    if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) {\n        node = NEW_DMETHOD(method_unbind(body));\n    }\n    else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) {\n        struct BLOCK *block;\n\n        body = proc_clone(body);\n        Data_Get_Struct(body, struct BLOCK, block);\n        block->frame.last_func = id;\n        block->frame.orig_func = id;\n        block->frame.last_class = mod;\n        node = NEW_BMETHOD(body);\n    }\n    else {\n        /* type error */\n        rb_raise(rb_eTypeError, \"wrong argument type (expected Proc/Method)\");\n    }\n\n    noex = NOEX_PUBLIC;\n    if (ruby_cbase == mod) {\n        if (SCOPE_TEST(SCOPE_PRIVATE)) {\n            noex = NOEX_PRIVATE;\n        }\n        else if (SCOPE_TEST(SCOPE_PROTECTED)) {\n            noex = NOEX_PROTECTED;\n        }\n    }\n    rb_add_method(mod, id, node, noex);\n    return body;\n}\n\n\n#ifdef MBARI_API\n/*\n * call-seq:\n *    meth.__file__  => String\n *\n * returns the filename containing this method's definition\n *\n * raises ArgumentError if method has no associated ruby source code\n *\n * <i>Only available when MBARI_API extentions are enabled at build time</i>\n */\n\nstatic VALUE\nmethod_source_file_name(VALUE method)\n{\n    struct METHOD *data;\n    NODE *node;\n\n    Data_Get_Struct(method, struct METHOD, data);\n    if (node = data->body) {\n      const char *filename = node->nd_file;\n      if (filename)\n        return rb_str_new2(filename);\n    }\n    rb_raise(rb_eArgError, \"native Method\");\n}\n\n/*\n * call-seq:\n *    meth.__line__  => Fixnum\n *\n * returns the starting line number of this method\n *\n * raises ArgumentError if method has no associated ruby source code\n *\n * <i>Only available when MBARI_API extentions are enabled at build time</i>\n */\n\nstatic VALUE\nmethod_source_line(VALUE method)\n{\n    struct METHOD *data;\n    NODE *node;\n\n    Data_Get_Struct(method, struct METHOD, data);\n    if (node = data->body) {\n      int lineno = nd_line(node);\n      if (lineno)\n        return INT2FIX(nd_line(node));\n    }\n    rb_raise(rb_eArgError, \"native Method\");\n}\n\n\n/*\n * call-seq:\n *    prc.__file__  => String\n *\n * returns the filename where this proc is defined\n *\n * raises ArgumentError if proc has no associated ruby source\n *\n * <i>Only available when MBARI_API extentions are enabled at build time</i>\n */\n\nstatic VALUE\nproc_source_file_name(VALUE block)\n{\n    struct BLOCK *data;\n    const char *filename;\n    NODE *node;\n\n    Data_Get_Struct(block, struct BLOCK, data);\n    if ((node = data->frame.node) || (node = data->body))\n      return rb_str_new2(node->nd_file);\n    rb_raise(rb_eArgError, \"native Proc\");\n}\n\n\n/*\n * call-seq:\n *    prc.__line__  => Fixnum\n *\n * returns the starting line number of this proc\n *\n * raises ArgumentError if proc has no associated ruby source code\n *\n * <i>Only available when MBARI_API extentions are enabled at build time</i>\n */\n\nstatic VALUE\nproc_source_line(VALUE block)\n{\n    struct BLOCK *data;\n    NODE *node;\n\n    Data_Get_Struct(block, struct BLOCK, data);\n    if ((node = data->frame.node) || (node = data->body))\n      return INT2FIX( nd_line(node) );\n    rb_raise(rb_eArgError, \"native Proc\");\n}\n\n#endif  /* MBARI_API */\n\n\n/*\n *  <code>Proc</code> objects are blocks of code that have been bound to\n *  a set of local variables. Once bound, the code may be called in\n *  different contexts and still access those variables.\n *\n *     def gen_times(factor)\n *       return Proc.new {|n| n*factor }\n *     end\n *\n *     times3 = gen_times(3)\n *     times5 = gen_times(5)\n *\n *     times3.call(12)               #=> 36\n *     times5.call(5)                #=> 25\n *     times3.call(times5.call(4))   #=> 60\n *\n */\n\nvoid\nInit_Proc()\n{\n    rb_eLocalJumpError = rb_define_class(\"LocalJumpError\", rb_eStandardError);\n    rb_define_method(rb_eLocalJumpError, \"exit_value\", localjump_xvalue, 0);\n    rb_define_method(rb_eLocalJumpError, \"reason\", localjump_reason, 0);\n\n    rb_global_variable(&exception_error);\n    exception_error = rb_exc_new3(rb_eFatal,\n                                  rb_obj_freeze(rb_str_new2(\"exception reentered\")));\n    OBJ_TAINT(exception_error);\n    OBJ_FREEZE(exception_error);\n\n    rb_eSysStackError = rb_define_class(\"SystemStackError\", rb_eStandardError);\n    rb_global_variable(&sysstack_error);\n    sysstack_error = rb_exc_new3(rb_eSysStackError,\n                                 rb_obj_freeze(rb_str_new2(\"stack level too deep\")));\n    OBJ_TAINT(sysstack_error);\n    OBJ_FREEZE(sysstack_error);\n\n    rb_cProc = rb_define_class(\"Proc\", rb_cObject);\n    rb_undef_alloc_func(rb_cProc);\n    rb_define_singleton_method(rb_cProc, \"new\", proc_s_new, -1);\n\n    rb_define_method(rb_cProc, \"clone\", proc_clone, 0);\n    rb_define_method(rb_cProc, \"dup\", proc_dup, 0);\n    rb_define_method(rb_cProc, \"call\", rb_proc_call, -2);\n    rb_define_method(rb_cProc, \"arity\", proc_arity, 0);\n    rb_define_method(rb_cProc, \"[]\", rb_proc_call, -2);\n    rb_define_method(rb_cProc, \"==\", proc_eq, 1);\n    rb_define_method(rb_cProc, \"to_s\", proc_to_s, 0);\n    rb_define_method(rb_cProc, \"to_proc\", proc_to_self, 0);\n    rb_define_method(rb_cProc, \"binding\", proc_binding, 0);\n\n    rb_define_global_function(\"proc\", proc_lambda, 0);\n    rb_define_global_function(\"lambda\", proc_lambda, 0);\n\n    rb_cMethod = rb_define_class(\"Method\", rb_cObject);\n    rb_undef_alloc_func(rb_cMethod);\n    rb_undef_method(CLASS_OF(rb_cMethod), \"new\");\n    rb_define_method(rb_cMethod, \"==\", method_eq, 1);\n    rb_define_method(rb_cMethod, \"clone\", method_clone, 0);\n    rb_define_method(rb_cMethod, \"call\", method_call, -1);\n    rb_define_method(rb_cMethod, \"[]\", method_call, -1);\n    rb_define_method(rb_cMethod, \"arity\", method_arity, 0);\n    rb_define_method(rb_cMethod, \"inspect\", method_inspect, 0);\n    rb_define_method(rb_cMethod, \"to_s\", method_inspect, 0);\n    rb_define_method(rb_cMethod, \"to_proc\", method_proc, 0);\n    rb_define_method(rb_cMethod, \"receiver\", method_receiver, 0);\n    rb_define_method(rb_cMethod, \"name\", method_name, 0);\n    rb_define_method(rb_cMethod, \"owner\", method_owner, 0);\n    rb_define_method(rb_cMethod, \"unbind\", method_unbind, 0);\n    rb_define_method(rb_mKernel, \"method\", rb_obj_method, 1);\n\n    rb_cUnboundMethod = rb_define_class(\"UnboundMethod\", rb_cObject);\n    rb_undef_alloc_func(rb_cUnboundMethod);\n    rb_undef_method(CLASS_OF(rb_cUnboundMethod), \"new\");\n    rb_define_method(rb_cUnboundMethod, \"==\", method_eq, 1);\n    rb_define_method(rb_cUnboundMethod, \"clone\", method_clone, 0);\n    rb_define_method(rb_cUnboundMethod, \"arity\", method_arity, 0);\n    rb_define_method(rb_cUnboundMethod, \"inspect\", method_inspect, 0);\n    rb_define_method(rb_cUnboundMethod, \"to_s\", method_inspect, 0);\n    rb_define_method(rb_cUnboundMethod, \"name\", method_name, 0);\n    rb_define_method(rb_cUnboundMethod, \"owner\", method_owner, 0);\n    rb_define_method(rb_cUnboundMethod, \"bind\", umethod_bind, 1);\n    rb_define_method(rb_cModule, \"instance_method\", rb_mod_method, 1);\n\n#ifdef MBARI_API\n    rb_define_method(rb_cUnboundMethod, \"__file__\", method_source_file_name, 0);\n    rb_define_method(rb_cUnboundMethod, \"__line__\", method_source_line, 0);\n    rb_define_method(rb_cProc, \"__file__\", proc_source_file_name, 0);\n    rb_define_method(rb_cProc, \"__line__\", proc_source_line, 0);\n    rb_define_method(rb_cMethod, \"__file__\", method_source_file_name, 0);\n    rb_define_method(rb_cMethod, \"__line__\", method_source_line, 0);\n#endif\n}\n\n/*\n *  Objects of class <code>Binding</code> encapsulate the execution\n *  context at some particular place in the code and retain this context\n *  for future use. The variables, methods, value of <code>self</code>,\n *  and possibly an iterator block that can be accessed in this context\n *  are all retained. Binding objects can be created using\n *  <code>Kernel#binding</code>, and are made available to the callback\n *  of <code>Kernel#set_trace_func</code>.\n *\n *  These binding objects can be passed as the second argument of the\n *  <code>Kernel#eval</code> method, establishing an environment for the\n *  evaluation.\n *\n *     class Demo\n *       def initialize(n)\n *         @secret = n\n *       end\n *       def getBinding\n *         return binding()\n *       end\n *     end\n *\n *     k1 = Demo.new(99)\n *     b1 = k1.getBinding\n *     k2 = Demo.new(-3)\n *     b2 = k2.getBinding\n *\n *     eval(\"@secret\", b1)   #=> 99\n *     eval(\"@secret\", b2)   #=> -3\n *     eval(\"@secret\")       #=> nil\n *\n *  Binding objects have no class-specific methods.\n *\n */\n\nvoid\nInit_Binding()\n{\n    rb_cBinding = rb_define_class(\"Binding\", rb_cObject);\n    rb_undef_alloc_func(rb_cBinding);\n    rb_undef_method(CLASS_OF(rb_cBinding), \"new\");\n    rb_define_method(rb_cBinding, \"clone\", proc_clone, 0);\n    rb_define_method(rb_cBinding, \"dup\", proc_dup, 0);\n    rb_define_method(rb_cBinding, \"eval\", bind_eval, -1);\n    rb_define_global_function(\"binding\", rb_f_binding, 0);\n}\n\n/* Windows SEH refers data on the stack. */\n#undef SAVE_WIN32_EXCEPTION_LIST\n#if defined _WIN32 || defined __CYGWIN__\n#if defined __CYGWIN__\ntypedef unsigned long DWORD;\n#endif\n\nstatic inline DWORD\nwin32_get_exception_list()\n{\n    DWORD p;\n# if defined _MSC_VER\n#   ifdef _M_IX86\n#   define SAVE_WIN32_EXCEPTION_LIST\n#   if _MSC_VER >= 1310\n      /* warning: unsafe assignment to fs:0 ... this is ok */\n#     pragma warning(disable: 4733)\n#   endif\n    __asm mov eax, fs:[0];\n    __asm mov p, eax;\n#   endif\n# elif defined __GNUC__\n#   ifdef __i386__\n#   define SAVE_WIN32_EXCEPTION_LIST\n    __asm__(\"movl %%fs:0,%0\" : \"=r\"(p));\n#   endif\n# elif defined __BORLANDC__\n#   define SAVE_WIN32_EXCEPTION_LIST\n    __emit__(0x64, 0xA1, 0, 0, 0, 0); /* mov eax, fs:[0] */\n    p = _EAX;\n# endif\n    return p;\n}\n\nstatic inline void\nwin32_set_exception_list(p)\n    DWORD p;\n{\n# if defined _MSC_VER\n#   ifdef _M_IX86\n    __asm mov eax, p;\n    __asm mov fs:[0], eax;\n#   endif\n# elif defined __GNUC__\n#   ifdef __i386__\n    __asm__(\"movl %0,%%fs:0\" :: \"r\"(p));\n#   endif\n# elif defined __BORLANDC__\n    _EAX = p;\n    __emit__(0x64, 0xA3, 0, 0, 0, 0); /* mov fs:[0], eax */\n# endif\n}\n\n#if !defined SAVE_WIN32_EXCEPTION_LIST && !defined _WIN32_WCE\n# error unsupported platform\n#endif\n#endif\n\nint rb_thread_pending = 0;\n\nVALUE rb_cThread;\nstatic unsigned int rb_thread_stack_size;\n\nextern VALUE rb_last_status;\n\n#define WAIT_FD         (1<<0)\n#define WAIT_SELECT     (1<<1)\n#define WAIT_TIME       (1<<2)\n#define WAIT_JOIN       (1<<3)\n#define WAIT_PID        (1<<4)\n#define WAIT_DONE       (1<<5)\n\n/* +infty, for this purpose */\n#define DELAY_INFTY 1E30\n\n#if !defined HAVE_PAUSE\n# if defined _WIN32 && !defined __CYGWIN__\n#  define pause() Sleep(INFINITE)\n# else\n#  define pause() sleep(0x7fffffff)\n# endif\n#endif\n\n#define THREAD_TERMINATING 0x400 /* persistent flag */\n#define THREAD_NO_ENSURE   0x800 /* persistent flag */\n#define THREAD_FLAGS_MASK 0xfc00 /* mask for persistent flags */\n\n#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;\n#define END_FOREACH_FROM(f,x) } while (x != f)\n\n#define FOREACH_THREAD(x) FOREACH_THREAD_FROM(curr_thread,x)\n#define END_FOREACH(x)    END_FOREACH_FROM(curr_thread,x)\n\nstruct thread_status_t {\n    NODE *node;\n\n    int tracing;\n    VALUE errinfo;\n    VALUE last_status;\n    VALUE last_line;\n    VALUE last_match;\n\n    int safe;\n\n    enum rb_thread_status status;\n    int wait_for;\n    int fd;\n    fd_set readfds;\n    fd_set writefds;\n    fd_set exceptfds;\n    int select_value;\n    double delay;\n    rb_thread_t join;\n};\n\n#define THREAD_COPY_STATUS(src, dst) (void)(    \\\n    (dst)->node = (src)->node,                  \\\n                                                \\\n    (dst)->tracing = (src)->tracing,            \\\n    (dst)->errinfo = (src)->errinfo,            \\\n    (dst)->last_status = (src)->last_status,    \\\n    (dst)->last_line = (src)->last_line,        \\\n    (dst)->last_match = (src)->last_match,      \\\n                                                \\\n    (dst)->safe = (src)->safe,                  \\\n                                                \\\n    (dst)->status = (src)->status,              \\\n    (dst)->wait_for = (src)->wait_for,          \\\n    (dst)->fd = (src)->fd,                      \\\n    (dst)->readfds = (src)->readfds,            \\\n    (dst)->writefds = (src)->writefds,          \\\n    (dst)->exceptfds = (src)->exceptfds,        \\\n    (dst)->select_value = (src)->select_value,  \\\n    (dst)->delay = (src)->delay,                \\\n    (dst)->join = (src)->join,                  \\\n    0)\n\nint\nrb_thread_set_raised(th)\n    rb_thread_t th;\n{\n    if (th->flags & RAISED_EXCEPTION) {\n        return 1;\n    }\n    th->flags |= RAISED_EXCEPTION;\n    return 0;\n}\n\nint\nrb_thread_reset_raised(th)\n    rb_thread_t th;\n{\n    if (!(th->flags & RAISED_EXCEPTION)) {\n        return 0;\n    }\n    th->flags &= ~RAISED_EXCEPTION;\n    return 1;\n}\n\nstatic int\nthread_no_ensure()\n{\n    return ((curr_thread->flags & THREAD_NO_ENSURE) == THREAD_NO_ENSURE);\n}\n\nstatic void rb_thread_ready _((rb_thread_t));\n\nstatic VALUE run_trap_eval _((VALUE));\nstatic VALUE\nrun_trap_eval(arg)\n    VALUE arg;\n{\n    VALUE *p = (VALUE *)arg;\n    return rb_eval_cmd(p[0], p[1], (int)p[2]);\n}\n\nstatic VALUE\nrb_trap_eval(cmd, sig, safe)\n    VALUE cmd;\n    int sig, safe;\n{\n    int state;\n    VALUE val = Qnil;           /* OK */\n    volatile struct thread_status_t save;\n    VALUE arg[3];\n\n    arg[0] = cmd;\n    arg[1] = rb_ary_new3(1, INT2FIX(sig));\n    arg[2] = (VALUE)safe;\n    THREAD_COPY_STATUS(curr_thread, &save);\n    rb_thread_ready(curr_thread);\n    PUSH_ITER(ITER_NOT);\n    val = rb_protect(run_trap_eval, (VALUE)&arg, &state);\n    POP_ITER();\n    THREAD_COPY_STATUS(&save, curr_thread);\n\n    if (state) {\n        rb_trap_immediate = 0;\n        rb_thread_ready(curr_thread);\n        JUMP_TAG(state);\n    }\n\n    if (curr_thread->status == THREAD_STOPPED) {\n        rb_thread_schedule();\n    }\n    errno = EINTR;\n\n    return val;\n}\n\nstatic const char *\nthread_status_name(status)\n    enum rb_thread_status status;\n{\n    switch (status) {\n      case THREAD_RUNNABLE:\n        return \"run\";\n      case THREAD_STOPPED:\n        return \"sleep\";\n      case THREAD_TO_KILL:\n        return \"aborting\";\n      case THREAD_KILLED:\n        return \"dead\";\n      default:\n        return \"unknown\";\n    }\n}\n\n/* $SAFE accessor */\nvoid\nrb_set_safe_level(level)\n    int level;\n{\n    if (level > ruby_safe_level) {\n        if (level > SAFE_LEVEL_MAX) level = SAFE_LEVEL_MAX;\n        ruby_safe_level = level;\n        curr_thread->safe = level;\n    }\n}\n\nstatic VALUE\nsafe_getter()\n{\n    return INT2NUM(ruby_safe_level);\n}\n\nstatic void\nsafe_setter(val)\n    VALUE val;\n{\n    int level = NUM2INT(val);\n\n    if (level < ruby_safe_level) {\n        rb_raise(rb_eSecurityError, \"tried to downgrade safe level from %d to %d\",\n                 ruby_safe_level, level);\n    }\n    if (level > SAFE_LEVEL_MAX) level = SAFE_LEVEL_MAX;\n    ruby_safe_level = level;\n    curr_thread->safe = level;\n}\n\n/* Return the current time as a floating-point number */\nstatic double\ntimeofday()\n{\n    struct timeval tv;\n#ifdef CLOCK_MONOTONIC\n    struct timespec tp;\n\n    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {\n        return (double)tp.tv_sec + (double)tp.tv_nsec * 1e-9;\n    }\n#endif\n    gettimeofday(&tv, NULL);\n    return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;\n}\n\n#define STACK(addr) (th->stk_pos<(VALUE*)(addr) && (VALUE*)(addr)<th->stk_pos+th->stk_len)\n#define ADJ(addr) (void*)(STACK(addr)?(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr):(VALUE*)(addr))\nstatic void\nthread_mark(th)\n    rb_thread_t th;\n{\n    struct FRAME *frame;\n    struct BLOCK *block;\n\n    rb_gc_mark(th->result);\n    rb_gc_mark(th->thread);\n    if (th->join) rb_gc_mark(th->join->thread);\n\n    if (curr_thread == th) {\n      rb_gc_mark(ruby_class);\n      rb_gc_mark(ruby_wrapper);\n      rb_gc_mark((VALUE)ruby_cref);\n      rb_gc_mark((VALUE)ruby_scope);\n      rb_gc_mark((VALUE)ruby_dyna_vars);\n    } else {\n      rb_gc_mark(th->klass);\n      rb_gc_mark(th->wrapper);\n      rb_gc_mark((VALUE)th->cref);\n      rb_gc_mark((VALUE)th->scope);\n      rb_gc_mark((VALUE)th->dyna_vars);\n    }\n\n    rb_gc_mark(th->errinfo);\n    rb_gc_mark(th->last_status);\n    rb_gc_mark(th->last_line);\n    rb_gc_mark(th->last_match);\n    rb_mark_tbl(th->locals);\n    rb_gc_mark(th->thgroup);\n    rb_gc_mark_maybe(th->sandbox);\n\n    /* mark data in copied stack */\n    if (th == main_thread) return;\n    if (th->status == THREAD_KILLED) return;\n    if (th->stk_len == 0) return;  /* stack not active, no need to mark. */\n    if (th->stk_ptr && th != curr_thread) {\n      rb_gc_mark_locations(th->stk_pos, th->stk_base);\n#if defined(THINK_C) || defined(__human68k__)\n        rb_gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2);\n#endif\n#ifdef __ia64\n        if (th->bstr_ptr) {\n            rb_gc_mark_locations(th->bstr_ptr, th->bstr_ptr+th->bstr_len);\n        }\n#endif\n    }\n\n    if (curr_thread == th)\n      frame = ruby_frame;\n    else\n      frame = th->frame;\n\n    while (frame && frame != top_frame) {\n        rb_gc_mark_frame(frame);\n        if (frame->tmp) {\n            struct FRAME *tmp = frame->tmp;\n            while (tmp && tmp != top_frame) {\n                rb_gc_mark_frame(tmp);\n                tmp = tmp->prev;\n            }\n        }\n        frame = frame->prev;\n    }\n\n    if (curr_thread == th)\n      block = ruby_block;\n    else\n      block = th->block;\n\n    while (block) {\n        rb_gc_mark_frame(&block->frame);\n        block = block->prev;\n    }\n}\n\nstatic int\nmark_loading_thread(key, value, lev)\n    ID key;\n    VALUE value;\n    int lev;\n{\n    rb_gc_mark(((rb_thread_t)value)->thread);\n    return ST_CONTINUE;\n}\n\nvoid\nrb_gc_mark_threads()\n{\n    rb_thread_t th;\n\n    /* static global mark */\n    rb_gc_mark((VALUE)ruby_cref);\n\n    if (!curr_thread) return;\n    rb_gc_mark(main_thread->thread);\n    rb_gc_mark(curr_thread->thread);\n    FOREACH_THREAD_FROM(main_thread, th) {\n        switch (th->status) {\n          case THREAD_TO_KILL:\n          case THREAD_RUNNABLE:\n            break;\n          case THREAD_STOPPED:\n            if (th->wait_for) break;\n          default:\n            continue;\n        }\n        rb_gc_mark(th->thread);\n    } END_FOREACH_FROM(main_thread, th);\n    if (loading_tbl) st_foreach(loading_tbl, mark_loading_thread, 0);\n}\n\nvoid\nrb_gc_abort_threads()\n{\n    rb_thread_t th;\n\n    if (!main_thread)\n        return;\n\n    FOREACH_THREAD_FROM(main_thread, th) {\n        if (rb_gc_is_thread_marked(th->thread)) continue;\n        if (th->status == THREAD_STOPPED) {\n            th->status = THREAD_TO_KILL;\n            rb_gc_mark(th->thread);\n        }\n    } END_FOREACH_FROM(main_thread, th);\n}\n\nstatic inline void\nstack_free(th)\n    rb_thread_t th;\n{\n    if (th->stk_ptr) {\n      munmap(th->stk_ptr, th->stk_size);\n      th->stk_ptr = 0;\n    }\n#ifdef __ia64\n    if (th->bstr_ptr) {\n      free(th->bstr_ptr);\n      th->bstr_ptr = 0;\n    }\n#endif\n}\n\n#define THREAD_DATA(threadObject)  ((rb_thread_t)RDATA(threadObject)->data)\n\nstatic void\nthread_free(th)\n    rb_thread_t th;\n{\n    stack_free(th);\n    if (th->locals) st_free_table(th->locals);\n    if (th->status != THREAD_KILLED) {\n        if (th->prev) th->prev->next = th->next;\n        if (th->next) th->next->prev = th->prev;\n    }\n    if (th != main_thread) free(th);\n}\n\nstatic rb_thread_t\nrb_thread_check(data)\n    VALUE data;\n{\n    if (TYPE(data) != T_DATA || RDATA(data)->dmark != (RUBY_DATA_FUNC)thread_mark) {\n        rb_raise(rb_eTypeError, \"wrong argument type %s (expected Thread)\",\n                 rb_obj_classname(data));\n    }\n    return THREAD_DATA(data);\n}\n\nstatic VALUE rb_thread_raise _((int, VALUE*, rb_thread_t));\n\nstatic VALUE th_raise_exception;\nstatic NODE *th_raise_node;\nstatic VALUE th_cmd;\nstatic int   th_sig, th_safe;\n\n#define RESTORE_NORMAL          1\n#define RESTORE_FATAL           2\n#define RESTORE_INTERRUPT       3\n#define RESTORE_TRAP            4\n#define RESTORE_RAISE           5\n#define RESTORE_SIGNAL          6\n#define RESTORE_EXIT            7\n#define RESTORE_BACKTRACE       8\n\nextern VALUE *rb_gc_stack_start;\n#ifdef __ia64\nextern VALUE *rb_gc_register_stack_start;\n#endif\n\nstatic void\nrb_thread_save_context(th)\n    rb_thread_t th;\n{\n    VALUE *pos;\n    size_t len;\n    static VALUE tval;\n\n    len = ruby_stack_length(&pos);\n    th->stk_len = len;\n    th->stk_pos = pos;\n    th->frame = ruby_frame;\n    th->scope = ruby_scope;\n    ruby_scope->flags |= SCOPE_DONT_RECYCLE;\n    th->klass = ruby_class;\n    th->wrapper = ruby_wrapper;\n    th->cref = ruby_cref;\n    th->dyna_vars = ruby_dyna_vars;\n    th->block = ruby_block;\n    th->flags &= THREAD_FLAGS_MASK;\n    th->flags |= (rb_trap_immediate<<8) | scope_vmode;\n    th->iter = ruby_iter;\n    th->tag = prot_tag;\n    th->tracing = tracing;\n    th->errinfo = ruby_errinfo;\n    th->last_status = rb_last_status;\n    tval = rb_lastline_get();\n    rb_lastline_set(th->last_line);\n    th->last_line = tval;\n    tval = rb_backref_get();\n    rb_backref_set(th->last_match);\n    th->last_match = tval;\n    th->safe = ruby_safe_level;\n\n    th->node = ruby_current_node;\n    if (ruby_sandbox_save != NULL) {\n        ruby_sandbox_save(th);\n    }\n}\n\nstatic int\nrb_thread_switch(n)\n    int n;\n{\n#if STACK_WIPE_SITES & 1\n    rb_gc_wipe_stack();\n#endif\n    rb_trap_immediate = (curr_thread->flags&0x100)?1:0;\n    switch (n) {\n      case 0:\n        return 0;\n      case RESTORE_FATAL:\n        JUMP_TAG(TAG_FATAL);\n        break;\n      case RESTORE_INTERRUPT:\n        rb_interrupt();\n        break;\n      case RESTORE_TRAP:\n        rb_trap_eval(th_cmd, th_sig, th_safe);\n        break;\n      case RESTORE_RAISE:\n        ruby_frame->last_func = 0;\n        ruby_current_node = th_raise_node;\n        rb_raise_jump(th_raise_exception);\n        break;\n      case RESTORE_SIGNAL:\n        rb_thread_signal_raise(th_sig);\n        break;\n      case RESTORE_EXIT:\n        ruby_errinfo = th_raise_exception;\n        ruby_current_node = th_raise_node;\n        if (!rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {\n            terminate_process(EXIT_FAILURE, ruby_errinfo);\n        }\n        rb_exc_raise(th_raise_exception);\n        break;\n      case RESTORE_BACKTRACE:\n        rb_hash_aset(backtrace_for_each_thread, curr_thread->thread,\n                     backtrace(backtrace_level_for_each_thread));\n        if (curr_thread != main_thread) {\n            switch_thread_context_to_collect_backtrace(curr_thread->next);\n        } else {\n                /* Circled back to main thread, cycle is complete. */\n        }\n        break;\n      case RESTORE_NORMAL:\n      default:\n        break;\n    }\n    return 1;\n}\n\n#define THREAD_SAVE_CONTEXT(th) (rb_thread_switch( wipeAfter(\\\n                  ruby_setjmp(rb_thread_save_context(th), (th)->context))))\n\nNORETURN(static void rb_thread_restore_context _((rb_thread_t,int)));\nNORETURN(NOINLINE(static void rb_thread_restore_context_0(rb_thread_t,int)));\nNORETURN(NOINLINE(static void stack_extend(rb_thread_t, int)));\n\nstatic void\nrb_thread_restore_context_0(rb_thread_t th, int exit)\n{\n    static rb_thread_t tmp;\n    static int ex;\n    static VALUE tval;\n\n    /* Free any dead thread's stk_ptr. */\n    stack_free_safe_all_dead_threads();\n\n    rb_trap_immediate = 0;      /* inhibit interrupts from here */\n    if (ruby_sandbox_restore != NULL) {\n        ruby_sandbox_restore(th);\n    }\n    ruby_frame = th->frame;\n    ruby_scope = th->scope;\n    ruby_class = th->klass;\n    ruby_wrapper = th->wrapper;\n    ruby_cref = th->cref;\n    ruby_dyna_vars = th->dyna_vars;\n    ruby_block = th->block;\n    scope_vmode = th->flags&SCOPE_MASK;\n    ruby_iter = th->iter;\n    prot_tag = th->tag;\n    tracing = th->tracing;\n    ruby_errinfo = th->errinfo;\n    rb_last_status = th->last_status;\n    ruby_safe_level = th->safe;\n\n    ruby_current_node = th->node;\n\n#ifdef SAVE_WIN32_EXCEPTION_LIST\n    win32_set_exception_list(th->win32_exception_list);\n#endif\n    tmp = th;\n    ex = exit;\n\n    tval = rb_lastline_get();\n    rb_lastline_set(tmp->last_line);\n    tmp->last_line = tval;\n    tval = rb_backref_get();\n    rb_backref_set(tmp->last_match);\n    tmp->last_match = tval;\n\n    ruby_longjmp(tmp->context, ex);\n}\n\n#ifdef __ia64\n#define C(a) rse_##a##0, rse_##a##1, rse_##a##2, rse_##a##3, rse_##a##4\n#define E(a) rse_##a##0= rse_##a##1= rse_##a##2= rse_##a##3= rse_##a##4\nstatic volatile int C(a), C(b), C(c), C(d), C(e);\nstatic volatile int C(f), C(g), C(h), C(i), C(j);\nstatic volatile int C(k), C(l), C(m), C(n), C(o);\nstatic volatile int C(p), C(q), C(r), C(s), C(t);\nint rb_dummy_false = 0;\nNORETURN(NOINLINE(static void register_stack_extend(rb_thread_t, int, VALUE *)));\nstatic void\nregister_stack_extend(rb_thread_t th, int exit, VALUE *curr_bsp)\n{\n    if (rb_dummy_false) {\n        /* use registers as much as possible */\n        E(a) = E(b) = E(c) = E(d) = E(e) =\n        E(f) = E(g) = E(h) = E(i) = E(j) =\n        E(k) = E(l) = E(m) = E(n) = E(o) =\n        E(p) = E(q) = E(r) = E(s) = E(t) = 0;\n        E(a) = E(b) = E(c) = E(d) = E(e) =\n        E(f) = E(g) = E(h) = E(i) = E(j) =\n        E(k) = E(l) = E(m) = E(n) = E(o) =\n        E(p) = E(q) = E(r) = E(s) = E(t) = 0;\n    }\n    if (curr_bsp < th->bstr_pos+th->bstr_len) {\n        register_stack_extend(th, exit, (VALUE*)rb_ia64_bsp());\n    }\n    stack_extend(th, exit);\n}\n#undef C\n#undef E\n#endif\n\nstatic void\nstack_extend(rb_thread_t th, int exit)\n{\n#define STACK_PAD_SIZE 1024\n    volatile VALUE space[STACK_PAD_SIZE];\n\n#if !STACK_GROW_DIRECTION\n    if (space < rb_gc_stack_start) {\n        /* Stack grows downward */\n#endif\n#if STACK_GROW_DIRECTION <= 0\n        if (space > th->stk_pos) {\n# ifdef HAVE_ALLOCA\n            (volatile void *)ALLOCA_N(VALUE, &space[0] - th->stk_pos);\n# else\n            stack_extend(th, exit);\n# endif\n        }\n#endif\n#if !STACK_GROW_DIRECTION\n    }\n    else {\n        /* Stack grows upward */\n#endif\n#if STACK_GROW_DIRECTION >= 0\n        if (&space[STACK_PAD_SIZE] < th->stk_pos + th->stk_len) {\n# ifdef HAVE_ALLOCA\n            (volatile void *)ALLOCA_N(VALUE, th->stk_pos +\n                                      th->stk_len - &space[STACK_PAD_SIZE]);\n# else\n            stack_extend(th, exit);\n# endif\n        }\n#endif\n#if !STACK_GROW_DIRECTION\n    }\n#endif\n    rb_thread_restore_context_0(th, exit);\n}\n#ifdef __ia64\n#define stack_extend(th, exit) register_stack_extend(th, exit, (VALUE*)rb_ia64_bsp())\n#endif\n\nstatic void\nrb_thread_restore_context(th, exit)\n    rb_thread_t th;\n    int exit;\n{\n    if (!th->stk_ptr && th != main_thread) rb_bug(\"unsaved context\");\n    rb_thread_restore_context_0(th, exit);\n}\n\nstatic void\nrb_thread_ready(th)\n    rb_thread_t th;\n{\n    th->wait_for = 0;\n    if (th->status != THREAD_TO_KILL) {\n        th->status = THREAD_RUNNABLE;\n    }\n}\n\nstatic\nrb_thread_t dead_thread_needs_stack_free = 0;\n\nstatic\nint dead_threads_need_stack_free = 0;\n\nstatic int\n_stack_free_safe (th\n#if STACK_FREE_SAFE_DEBUG\n                 , msg\n#endif\n                 )\n    rb_thread_t th;\n#if STACK_FREE_SAFE_DEBUG\n    const char *msg;\n#endif\n{\n    if ( th->status == THREAD_KILLED && th->stk_ptr ) {\n        void *sp = (void*) &th;\n#if STACK_FREE_SAFE_DEBUG\n        fprintf(stderr, \"\\n%s: stack_free_safe(%p): sp (%p): stk [%p, %p): \",\n                msg, th, sp, th->stk_ptr, th->stk_ptr + th->stk_size);\n#endif\n        if ( (void*) th->stk_ptr <= sp && sp < (void*) (th->stk_ptr + th->stk_size) ) {\n#if STACK_FREE_SAFE_DEBUG\n            fprintf(stderr, \"  cannot call stack_free(), yet. \\n\");\n            fflush(stderr);\n#endif\n            dead_thread_needs_stack_free = th;\n            ++ dead_threads_need_stack_free;\n        } else {\n#if STACK_FREE_SAFE_DEBUG\n            fprintf(stderr, \"  calling stack_free(). \\n\");\n            fflush(stderr);\n#endif\n            if ( dead_thread_needs_stack_free == th )\n                dead_thread_needs_stack_free = 0;\n            stack_free(th);\n            return 1; /* stack freed. */\n        }\n    }\n    return 0; /* stack not freed */\n}\n\nstatic void\nrb_thread_die(th)\n    rb_thread_t th;\n{\n    th->thgroup = 0;\n    th->status = THREAD_KILLED;\n    stack_free_safe(th, \"rb_thread_die\");\n}\n\nstatic void\nrb_thread_remove(th)\n    rb_thread_t th;\n{\n    if (th->status == THREAD_KILLED) return;\n\n    rb_thread_ready(th);\n    rb_thread_die(th);\n    th->prev->next = th->next;\n    th->next->prev = th->prev;\n\n#if defined(_THREAD_SAFE) || defined(HAVE_SETITIMER)\n    /* if this is the last ruby thread, stop timer signals */\n    if (th->next == th->prev && th->next == main_thread) {\n        rb_thread_stop_timer();\n    }\n#endif\n}\n\nstatic int\nrb_thread_dead(th)\n    rb_thread_t th;\n{\n    return th->status == THREAD_KILLED;\n}\n\nvoid\nrb_thread_fd_close(fd)\n    int fd;\n{\n    rb_thread_t th;\n\n    FOREACH_THREAD(th) {\n        if (((th->wait_for & WAIT_FD) && fd == th->fd) ||\n            ((th->wait_for & WAIT_SELECT) && (fd < th->fd) &&\n             (FD_ISSET(fd, &th->readfds) ||\n              FD_ISSET(fd, &th->writefds) ||\n              FD_ISSET(fd, &th->exceptfds)))) {\n            VALUE exc = rb_exc_new2(rb_eIOError, \"stream closed\");\n            rb_thread_raise(1, &exc, th);\n        }\n    }\n    END_FOREACH(th);\n}\n\nNORETURN(static void rb_thread_main_jump _((VALUE, int)));\nstatic void\nrb_thread_main_jump(err, tag)\n    VALUE err;\n    int tag;\n{\n    curr_thread = main_thread;\n    th_raise_exception = err;\n    th_raise_node = ruby_current_node;\n    rb_thread_restore_context(main_thread, tag);\n}\n\nNORETURN(static void rb_thread_deadlock _((void)));\nstatic void\nrb_thread_deadlock()\n{\n    char msg[21+SIZEOF_LONG*2];\n    VALUE e;\n\n    sprintf(msg, \"Thread(0x%lx): deadlock\", curr_thread->thread);\n    e = rb_exc_new2(rb_eFatal, msg);\n    if (curr_thread == main_thread) {\n        rb_exc_raise(e);\n    }\n    rb_thread_main_jump(e, RESTORE_RAISE);\n}\n\nstatic void\ncopy_fds(dst, src, max)\n    fd_set *dst, *src;\n    int max;\n{\n    int n = 0;\n    int i;\n\n    for (i=0; i<=max; i++) {\n        if (FD_ISSET(i, src)) {\n            n = i;\n            FD_SET(i, dst);\n        }\n    }\n}\n\nstatic int\nmatch_fds(dst, src, max)\n    fd_set *dst, *src;\n    int max;\n{\n    int i;\n\n    for (i=0; i<=max; i++) {\n        if (FD_ISSET(i, src) && FD_ISSET(i, dst)) {\n            return Qtrue;\n        }\n    }\n    return Qfalse;\n}\n\nstatic int\nintersect_fds(src, dst, max)\n    fd_set *src, *dst;\n    int max;\n{\n    int i, n = 0;\n\n    for (i=0; i<=max; i++) {\n        if (FD_ISSET(i, dst)) {\n            if (FD_ISSET(i, src)) {\n                /* Wake up only one thread per fd. */\n                FD_CLR(i, src);\n                n++;\n            }\n            else {\n                FD_CLR(i, dst);\n            }\n        }\n    }\n    return n;\n}\n\nstatic int\nfind_bad_fds(dst, src, max)\n    fd_set *dst, *src;\n    int max;\n{\n    int i, test = Qfalse;\n\n    for (i=0; i<=max; i++) {\n        if (FD_ISSET(i, src) && !FD_ISSET(i, dst)) {\n            FD_CLR(i, src);\n            test = Qtrue;\n        }\n    }\n    return test;\n}\n\nvoid\nrb_thread_schedule()\n{\n    rb_thread_t next;           /* OK */\n    rb_thread_t th;\n    rb_thread_t curr;\n    int found = 0;\n\n    struct timeval *delay_ptr;\n    double delay, now;  /* OK */\n    int n, max;\n    int need_select = 0;\n    int select_timeout = 0;\n\n#ifdef HAVE_NATIVETHREAD\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on rb_thread_schedule()\");\n    }\n#endif\n    rb_thread_pending = 0;\n    if (curr_thread == curr_thread->next\n        && curr_thread->status == THREAD_RUNNABLE)\n        return;\n\n    next = 0;\n    curr = curr_thread;         /* starting thread */\n\n    while (curr->status == THREAD_KILLED) {\n        curr = curr->prev;\n    }\n\n  again:\n    max = -1;\n    FD_ZERO(&curr->scratch_readfds);\n    FD_ZERO(&curr->scratch_writefds);\n    FD_ZERO(&curr->scratch_exceptfds);\n    bzero(&curr->scratch_delay_tv, sizeof(struct timeval));\n    delay = DELAY_INFTY;\n    now = -1.0;\n\n    FOREACH_THREAD_FROM(curr, th) {\n        th->wait_for &= ~WAIT_DONE;\n        if (!found && th->status <= THREAD_RUNNABLE) {\n            found = 1;\n        }\n        if (th->status != THREAD_STOPPED) continue;\n        if (th->wait_for & WAIT_JOIN) {\n            if (rb_thread_dead(th->join)) {\n                th->wait_for = 0;\n                th->status = THREAD_RUNNABLE;\n                found = 1;\n            }\n        }\n        if (th->wait_for & WAIT_FD) {\n            FD_SET(th->fd, &curr->scratch_readfds);\n            if (max < th->fd) max = th->fd;\n            need_select = 1;\n        }\n        if (th->wait_for & WAIT_SELECT) {\n            copy_fds(&curr->scratch_readfds, &th->readfds, th->fd);\n            copy_fds(&curr->scratch_writefds, &th->writefds, th->fd);\n            copy_fds(&curr->scratch_exceptfds, &th->exceptfds, th->fd);\n            if (max < th->fd) max = th->fd;\n            need_select = 1;\n            if (th->wait_for & WAIT_TIME) {\n                select_timeout = 1;\n            }\n            th->select_value = 0;\n        }\n        if (th->wait_for & WAIT_TIME) {\n            double th_delay;\n\n            if (now < 0.0) now = timeofday();\n            th_delay = th->delay - now;\n            if (th_delay <= 0.0) {\n                if (th->wait_for & WAIT_SELECT) {\n                    need_select = 1;\n                }\n                else {\n                    th->status = THREAD_RUNNABLE;\n                }\n                found = 1;\n            }\n            else if (th_delay < delay) {\n                delay = th_delay;\n                need_select = 1;\n            }\n            else if (th->delay == DELAY_INFTY) {\n                need_select = 1;\n            }\n        }\n    }\n    END_FOREACH_FROM(curr, th);\n\n    /* Do the select if needed */\n    if (need_select) {\n        /* Convert delay to a timeval */\n        /* If a thread is runnable, just poll */\n        if (found) {\n            th->scratch_delay_tv.tv_sec = 0;\n            th->scratch_delay_tv.tv_usec = 0;\n            delay_ptr = &curr->scratch_delay_tv;\n        }\n        else if (delay == DELAY_INFTY) {\n            delay_ptr = 0;\n        }\n        else {\n            th->scratch_delay_tv.tv_sec = delay;\n            th->scratch_delay_tv.tv_usec = (delay - (double)th->scratch_delay_tv.tv_sec)*1e6;\n            delay_ptr = &curr->scratch_delay_tv;\n        }\n\n        n = select(max+1, &curr->scratch_readfds, &curr->scratch_writefds, &curr->scratch_exceptfds, delay_ptr);\n        if (n < 0) {\n            int e = errno;\n\n            if (rb_trap_pending) rb_trap_exec();\n            if (e == EINTR) goto again;\n#ifdef ERESTART\n            if (e == ERESTART) goto again;\n#endif\n            if (e == EBADF) {\n                int badfd = -1;\n                int fd;\n                int dummy;\n                for (fd = 0; fd <= max; fd++) {\n                    if ((FD_ISSET(fd, &curr->scratch_readfds) ||\n                         FD_ISSET(fd, &curr->scratch_writefds) ||\n                         FD_ISSET(fd, &curr->scratch_exceptfds)) &&\n#ifndef _WIN32\n                        fcntl(fd, F_GETFD, &dummy) == -1 &&\n#else\n                        rb_w32_get_osfhandle(fd) == -1 &&\n#endif\n                        errno == EBADF) {\n                        badfd = fd;\n                        break;\n                    }\n                }\n                if (badfd != -1) {\n                    FOREACH_THREAD_FROM(curr, th) {\n                        if (th->wait_for & WAIT_FD) {\n                            if (th->fd == badfd) {\n                                found = 1;\n                                th->status = THREAD_RUNNABLE;\n                                th->fd = 0;\n                                break;\n                            }\n                        }\n                        if (th->wait_for & WAIT_SELECT) {\n                            if (FD_ISSET(badfd, &th->readfds) ||\n                                FD_ISSET(badfd, &th->writefds) ||\n                                FD_ISSET(badfd, &th->exceptfds)) {\n                                found = 1;\n                                th->status = THREAD_RUNNABLE;\n                                th->select_value = -EBADF;\n                                break;\n                            }\n                        }\n                    }\n                    END_FOREACH_FROM(curr, th);\n                }\n            }\n            else {\n                FOREACH_THREAD_FROM(curr, th) {\n                    if (th->wait_for & WAIT_SELECT) {\n                        int v = 0;\n\n                        v |= find_bad_fds(&curr->scratch_readfds, &th->readfds, th->fd);\n                        v |= find_bad_fds(&curr->scratch_writefds, &th->writefds, th->fd);\n                        v |= find_bad_fds(&curr->scratch_exceptfds, &th->exceptfds, th->fd);\n                        if (v) {\n                            th->select_value = n;\n                            n = max;\n                        }\n                    }\n                }\n                END_FOREACH_FROM(curr, th);\n            }\n        }\n        if (select_timeout && n == 0) {\n            if (now < 0.0) now = timeofday();\n            FOREACH_THREAD_FROM(curr, th) {\n                if (((th->wait_for&(WAIT_SELECT|WAIT_TIME)) == (WAIT_SELECT|WAIT_TIME)) &&\n                    th->delay <= now) {\n                    th->status = THREAD_RUNNABLE;\n                    th->wait_for = 0;\n                    th->select_value = 0;\n                    found = 1;\n                    intersect_fds(&curr->scratch_readfds, &th->readfds, max);\n                    intersect_fds(&curr->scratch_writefds, &th->writefds, max);\n                    intersect_fds(&curr->scratch_exceptfds, &th->exceptfds, max);\n                }\n            }\n            END_FOREACH_FROM(curr, th);\n        }\n        if (n > 0) {\n            now = -1.0;\n            /* Some descriptors are ready.\n             * The corresponding threads are runnable as next.\n             * Mark them with WAIT_DONE.\n             * Don't change the status to runnable here because\n             * threads which don't run next should not be changed.\n             */\n            FOREACH_THREAD_FROM(curr, th) {\n                if ((th->wait_for&WAIT_FD) && FD_ISSET(th->fd, &curr->scratch_readfds)) {\n                    th->wait_for |= WAIT_DONE;\n                    found = 1;\n                }\n                if ((th->wait_for&WAIT_SELECT) &&\n                    (match_fds(&curr->scratch_readfds, &th->readfds, max) ||\n                     match_fds(&curr->scratch_writefds, &th->writefds, max) ||\n                     match_fds(&curr->scratch_exceptfds, &th->exceptfds, max))) {\n                    th->wait_for |= WAIT_DONE;\n                    found = 1;\n                }\n            }\n            END_FOREACH_FROM(curr, th);\n        }\n        /* The delays for some of the threads should have expired.\n           Go through the loop once more, to check the delays. */\n        if (!found && delay != DELAY_INFTY)\n            goto again;\n    }\n\n    FOREACH_THREAD_FROM(curr, th) {\n        if (th->status == THREAD_TO_KILL) {\n            next = th;\n            break;\n        }\n        if ((th->status == THREAD_RUNNABLE || (th->wait_for & WAIT_DONE)) && th->stk_ptr) {\n            if (!next || next->priority < th->priority) {\n                next = th;\n            }\n        }\n    }\n    END_FOREACH_FROM(curr, th);\n\n    if (next && (next->wait_for & WAIT_DONE)) {\n        next->status = THREAD_RUNNABLE;\n        if (next->wait_for&WAIT_FD) {\n            next->fd = 0;\n        }\n        else { /* next->wait_for&WAIT_SELECT */\n            n = intersect_fds(&curr->scratch_readfds, &next->readfds, max) +\n                intersect_fds(&curr->scratch_writefds, &next->writefds, max) +\n                intersect_fds(&curr->scratch_exceptfds, &next->exceptfds, max);\n            next->select_value = n;\n        }\n        next->wait_for = 0;\n    }\n\n    if (!next) {\n        /* raise fatal error to main thread */\n        curr_thread->node = ruby_current_node;\n        if (curr->next == curr) {\n            TRAP_BEG;\n            pause();\n            TRAP_END;\n        }\n        FOREACH_THREAD_FROM(curr, th) {\n            int wait_for = th->wait_for & ~WAIT_DONE;\n            warn_printf(\"deadlock 0x%lx: %s:\",\n                        th->thread, thread_status_name(th->status));\n            if (wait_for & WAIT_FD) warn_printf(\"F(%d)\", th->fd);\n            if (wait_for & WAIT_SELECT) warn_printf(\"S\");\n            if (wait_for & WAIT_TIME) warn_printf(\"T(%f)\", th->delay);\n            if (wait_for & WAIT_JOIN)\n                warn_printf(\"J(0x%lx)\", th->join ? th->join->thread : 0);\n            if (wait_for & WAIT_PID) warn_printf(\"P\");\n            if (!wait_for) warn_printf(\"-\");\n            warn_printf(\" %s - %s:%d\\n\",\n                        th==main_thread ? \"(main)\" : \"\",\n                        th->node->nd_file, nd_line(th->node));\n        }\n        END_FOREACH_FROM(curr, th);\n        next = main_thread;\n        rb_thread_ready(next);\n        next->status = THREAD_TO_KILL;\n        if (!rb_thread_dead(curr_thread)) {\n            rb_thread_save_context(curr_thread);\n        }\n        rb_thread_deadlock();\n    }\n    next->wait_for = 0;\n    if (next->status == THREAD_RUNNABLE && next == curr_thread) {\n        return;\n    }\n\n    /* context switch */\n    if (curr == curr_thread) {\n        if (THREAD_SAVE_CONTEXT(curr)) {\n            return;\n        }\n    }\n\n    curr_thread = next;\n    if (next->status == THREAD_TO_KILL) {\n        if (!(next->flags & THREAD_TERMINATING)) {\n            next->flags |= THREAD_TERMINATING;\n            /* terminate; execute ensure-clause if any */\n            rb_thread_restore_context(next, RESTORE_FATAL);\n        }\n    }\n    rb_thread_restore_context(next, RESTORE_NORMAL);\n}\n\nvoid\nrb_thread_wait_fd(fd)\n    int fd;\n{\n    if (rb_thread_critical) return;\n    if (ruby_in_compile) return;\n    if (curr_thread == curr_thread->next) return;\n    if (curr_thread->status == THREAD_TO_KILL) return;\n\n    curr_thread->status = THREAD_STOPPED;\n    curr_thread->fd = fd;\n    curr_thread->wait_for = WAIT_FD;\n    rb_thread_schedule();\n}\n\nint\nrb_thread_fd_writable(fd)\n    int fd;\n{\n    if (rb_thread_critical) return Qtrue;\n    if (curr_thread == curr_thread->next) return Qtrue;\n    if (curr_thread->status == THREAD_TO_KILL) return Qtrue;\n    if (curr_thread->status == THREAD_KILLED) return Qtrue;\n\n    curr_thread->status = THREAD_STOPPED;\n    FD_ZERO(&curr_thread->readfds);\n    FD_ZERO(&curr_thread->writefds);\n    FD_SET(fd, &curr_thread->writefds);\n    FD_ZERO(&curr_thread->exceptfds);\n    curr_thread->fd = fd+1;\n    curr_thread->wait_for = WAIT_SELECT;\n    rb_thread_schedule();\n    return Qfalse;\n}\n\nvoid\nrb_thread_wait_for(time)\n    struct timeval time;\n{\n    double date;\n\n    if (rb_thread_critical ||\n        curr_thread == curr_thread->next ||\n        curr_thread->status == THREAD_TO_KILL) {\n        int n;\n        int thr_critical = rb_thread_critical;\n#ifndef linux\n        double d, limit;\n        limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;\n#endif\n        for (;;) {\n            rb_thread_critical = Qtrue;\n            TRAP_BEG;\n            n = select(0, 0, 0, 0, &time);\n            rb_thread_critical = thr_critical;\n            TRAP_END;\n            if (n == 0) return;\n            if (n < 0) {\n                switch (errno) {\n                  case EINTR:\n#ifdef ERESTART\n                  case ERESTART:\n#endif\n                    break;\n                  default:\n                    rb_sys_fail(\"sleep\");\n                }\n            }\n#ifndef linux\n            d = limit - timeofday();\n\n            time.tv_sec = (int)d;\n            time.tv_usec = (int)((d - (int)d)*1e6);\n            if (time.tv_usec < 0) {\n                time.tv_usec += (long)1e6;\n                time.tv_sec -= 1;\n            }\n            if (time.tv_sec < 0) return;\n#endif\n        }\n    }\n\n    date = timeofday() + (double)time.tv_sec + (double)time.tv_usec*1e-6;\n    curr_thread->status = THREAD_STOPPED;\n    curr_thread->delay = date;\n    curr_thread->wait_for = WAIT_TIME;\n    rb_thread_schedule();\n}\n\nvoid rb_thread_sleep_forever _((void));\n\nint\nrb_thread_alone()\n{\n    return curr_thread == curr_thread->next;\n}\n\nint\nrb_thread_select(max, read, write, except, timeout)\n    int max;\n    fd_set *read, *write, *except;\n    struct timeval *timeout;\n{\n#ifndef linux\n    double limit;\n#endif\n    int n;\n\n    if (!read && !write && !except) {\n        if (!timeout) {\n            rb_thread_sleep_forever();\n            return 0;\n        }\n        rb_thread_wait_for(*timeout);\n        return 0;\n    }\n\n#ifndef linux\n    if (timeout) {\n        limit = timeofday()+\n            (double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;\n    }\n#endif\n\n    if (rb_thread_critical ||\n        curr_thread == curr_thread->next ||\n        curr_thread->status == THREAD_TO_KILL) {\n#ifndef linux\n        struct timeval tv, *tvp = timeout;\n\n        if (timeout) {\n            tv = *timeout;\n            tvp = &tv;\n        }\n#else\n        struct timeval *const tvp = timeout;\n#endif\n        for (;;) {\n            TRAP_BEG;\n            n = select(max, read, write, except, tvp);\n            TRAP_END;\n            if (n < 0) {\n                switch (errno) {\n                  case EINTR:\n#ifdef ERESTART\n                  case ERESTART:\n#endif\n#ifndef linux\n                    if (timeout) {\n                        double d = limit - timeofday();\n\n                        tv.tv_sec = (unsigned int)d;\n                        tv.tv_usec = (long)((d-(double)tv.tv_sec)*1e6);\n                        if (tv.tv_sec < 0)  tv.tv_sec = 0;\n                        if (tv.tv_usec < 0) tv.tv_usec = 0;\n                    }\n#endif\n                    continue;\n                  default:\n                    break;\n                }\n            }\n            return n;\n        }\n    }\n\n    curr_thread->status = THREAD_STOPPED;\n    if (read) curr_thread->readfds = *read;\n    else FD_ZERO(&curr_thread->readfds);\n    if (write) curr_thread->writefds = *write;\n    else FD_ZERO(&curr_thread->writefds);\n    if (except) curr_thread->exceptfds = *except;\n    else FD_ZERO(&curr_thread->exceptfds);\n    curr_thread->fd = max;\n    curr_thread->wait_for = WAIT_SELECT;\n    if (timeout) {\n        curr_thread->delay = timeofday() +\n            (double)timeout->tv_sec + (double)timeout->tv_usec*1e-6;\n        curr_thread->wait_for |= WAIT_TIME;\n    }\n    rb_thread_schedule();\n    if (read) *read = curr_thread->readfds;\n    if (write) *write = curr_thread->writefds;\n    if (except) *except = curr_thread->exceptfds;\n    if (curr_thread->select_value < 0) {\n        errno = -curr_thread->select_value;\n        return -1;\n    }\n    return curr_thread->select_value;\n}\n\nstatic int rb_thread_join0 _((rb_thread_t, double));\nint rb_thread_join _((VALUE, double));\n\nstatic int\nrb_thread_join0(th, limit)\n    rb_thread_t th;\n    double limit;\n{\n    enum rb_thread_status last_status = THREAD_RUNNABLE;\n\n    if (rb_thread_critical) rb_thread_deadlock();\n    if (!rb_thread_dead(th)) {\n        if (th == curr_thread)\n            rb_raise(rb_eThreadError, \"thread 0x%lx tried to join itself\",\n                     th->thread);\n        if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread)\n            rb_raise(rb_eThreadError, \"Thread#join: deadlock 0x%lx - mutual join(0x%lx)\",\n                     curr_thread->thread, th->thread);\n        if (curr_thread->status == THREAD_TO_KILL)\n            last_status = THREAD_TO_KILL;\n        if (limit == 0) return Qfalse;\n        curr_thread->status = THREAD_STOPPED;\n        curr_thread->join = th;\n        curr_thread->wait_for = WAIT_JOIN;\n        curr_thread->delay = timeofday() + limit;\n        if (limit < DELAY_INFTY) curr_thread->wait_for |= WAIT_TIME;\n        rb_thread_schedule();\n        curr_thread->status = last_status;\n        if (!rb_thread_dead(th)) return Qfalse;\n    }\n\n    if (!NIL_P(th->errinfo) && (th->flags & RAISED_EXCEPTION)) {\n        VALUE oldbt = get_backtrace(th->errinfo);\n        VALUE errat = make_backtrace();\n        VALUE errinfo = rb_obj_dup(th->errinfo);\n\n        if (TYPE(oldbt) == T_ARRAY && RARRAY(oldbt)->len > 0) {\n            rb_ary_unshift(errat, rb_ary_entry(oldbt, 0));\n        }\n        set_backtrace(errinfo, errat);\n        rb_exc_raise(errinfo);\n    }\n\n    return Qtrue;\n}\n\nint\nrb_thread_join(thread, limit)\n    VALUE thread;\n    double limit;\n{\n    if (limit < 0) limit = DELAY_INFTY;\n    return rb_thread_join0(THREAD_DATA(thread), limit);\n}\n\nvoid\nrb_thread_set_join(thread, join)\n    VALUE thread, join;\n{\n    rb_thread_t th = rb_thread_check(thread);\n    rb_thread_t jth = rb_thread_check(join);\n    if ( (th->wait_for & WAIT_JOIN) == 0) {\n       rb_bug( \"Internal consistency failure! Expected thread to already be in waiting to join state %0x, was in %0x\", WAIT_JOIN, th->wait_for);\n    }\n\n    if (th->join != curr_thread) {\n       rb_bug( \"Internal consistency failure! Should only invoke rb_thread_set_join from a mutex unlock. Thread join aiming at %0x which something other than current thread %0x\", th->join, curr_thread);\n    }\n\n    th->join = jth;\n}\n\n\n/*\n *  call-seq:\n *     thr.join          => thr\n *     thr.join(limit)   => thr\n *\n *  The calling thread will suspend execution and run <i>thr</i>. Does not\n *  return until <i>thr</i> exits or until <i>limit</i> seconds have passed. If\n *  the time limit expires, <code>nil</code> will be returned, otherwise\n *  <i>thr</i> is returned.\n *\n *  Any threads not joined will be killed when the main program exits.  If\n *  <i>thr</i> had previously raised an exception and the\n *  <code>abort_on_exception</code> and <code>$DEBUG</code> flags are not set\n *  (so the exception has not yet been processed) it will be processed at this\n *  time.\n *\n *     a = Thread.new { print \"a\"; sleep(10); print \"b\"; print \"c\" }\n *     x = Thread.new { print \"x\"; Thread.pass; print \"y\"; print \"z\" }\n *     x.join # Let x thread finish, a will be killed on exit.\n *\n *  <em>produces:</em>\n *\n *     axyz\n *\n *  The following example illustrates the <i>limit</i> parameter.\n *\n *     y = Thread.new { 4.times { sleep 0.1; puts 'tick... ' }}\n *     puts \"Waiting\" until y.join(0.15)\n *\n *  <em>produces:</em>\n *\n *     tick...\n *     Waiting\n *     tick...\n *     Waitingtick...\n *\n *\n *     tick...\n */\n\nstatic VALUE\nrb_thread_join_m(argc, argv, thread)\n    int argc;\n    VALUE *argv;\n    VALUE thread;\n{\n    VALUE limit;\n    double delay = DELAY_INFTY;\n\n    rb_scan_args(argc, argv, \"01\", &limit);\n    if (!NIL_P(limit)) delay = rb_num2dbl(limit);\n    if (!rb_thread_join0(THREAD_DATA(thread), delay))\n        return Qnil;\n    return thread;\n}\n\n\n/*\n *  call-seq:\n *     Thread.current   => thread\n *\n *  Returns the currently executing thread.\n *\n *     Thread.current   #=> #<Thread:0x401bdf4c run>\n */\n\nVALUE\nrb_thread_current()\n{\n    return curr_thread->thread;\n}\n\n\n/*\n *  call-seq:\n *     Thread.main   => thread\n *\n *  Returns the main thread for the process.\n *\n *     Thread.main   #=> #<Thread:0x401bdf4c run>\n */\n\nVALUE\nrb_thread_main()\n{\n    return main_thread->thread;\n}\n\n\n/*\n *  call-seq:\n *     Thread.list   => array\n *\n *  Returns an array of <code>Thread</code> objects for all threads that are\n *  either runnable or stopped.\n *\n *     Thread.new { sleep(200) }\n *     Thread.new { 1000000.times {|i| i*i } }\n *     Thread.new { Thread.stop }\n *     Thread.list.each {|t| p t}\n *\n *  <em>produces:</em>\n *\n *     #<Thread:0x401b3e84 sleep>\n *     #<Thread:0x401b3f38 run>\n *     #<Thread:0x401b3fb0 sleep>\n *     #<Thread:0x401bdf4c run>\n */\n\nVALUE\nrb_thread_list()\n{\n    rb_thread_t th;\n    VALUE ary = rb_ary_new();\n\n    FOREACH_THREAD(th) {\n        switch (th->status) {\n          case THREAD_RUNNABLE:\n          case THREAD_STOPPED:\n          case THREAD_TO_KILL:\n            rb_ary_push(ary, th->thread);\n          default:\n            break;\n        }\n    }\n    END_FOREACH(th);\n\n    return ary;\n}\n\n\n/*\n *  call-seq:\n *     thr.wakeup   => thr\n *\n *  Marks <i>thr</i> as eligible for scheduling (it may still remain blocked on\n *  I/O, however). Does not invoke the scheduler (see <code>Thread#run</code>).\n *\n *     c = Thread.new { Thread.stop; puts \"hey!\" }\n *     c.wakeup\n *\n *  <em>produces:</em>\n *\n *     hey!\n */\n\nVALUE\nrb_thread_wakeup(thread)\n    VALUE thread;\n{\n    if (!RTEST(rb_thread_wakeup_alive(thread)))\n        rb_raise(rb_eThreadError, \"killed thread\");\n    return thread;\n}\n\nVALUE\nrb_thread_wakeup_alive(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (th->status == THREAD_KILLED)\n        return Qnil;\n    rb_thread_ready(th);\n\n    return thread;\n}\n\n\n/*\n *  call-seq:\n *     thr.run   => thr\n *\n *  Wakes up <i>thr</i>, making it eligible for scheduling. If not in a critical\n *  section, then invokes the scheduler.\n *\n *     a = Thread.new { puts \"a\"; Thread.stop; puts \"c\" }\n *     Thread.pass\n *     puts \"Got here\"\n *     a.run\n *     a.join\n *\n *  <em>produces:</em>\n *\n *     a\n *     Got here\n *     c\n */\n\nVALUE\nrb_thread_run(thread)\n    VALUE thread;\n{\n    rb_thread_wakeup(thread);\n    if (!rb_thread_critical) rb_thread_schedule();\n\n    return thread;\n}\n\n\nstatic void\nrb_kill_thread(th, flags)\n    rb_thread_t th;\n    int flags;\n{\n    if (th != curr_thread && th->safe < 4) {\n        rb_secure(4);\n    }\n    if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED)\n        return;\n    if (th == th->next || th == main_thread) rb_exit(EXIT_SUCCESS);\n\n    rb_thread_ready(th);\n    th->flags |= flags;\n    th->status = THREAD_TO_KILL;\n    if (!rb_thread_critical) rb_thread_schedule();\n}\n\n\n/*\n *  call-seq:\n *     thr.exit        => thr\n *     thr.kill        => thr\n *     thr.terminate   => thr\n *\n *  Terminates <i>thr</i> and schedules another thread to be run, returning\n *  the terminated <code>Thread</code>.  If this is the main thread, or the\n *  last thread, exits the process.\n */\n\nVALUE\nrb_thread_kill(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    rb_kill_thread(th, 0);\n    return thread;\n}\n\n\n/*\n *  call-seq:\n *     thr.exit!        => thr\n *     thr.kill!        => thr\n *     thr.terminate!   => thr\n *\n *  Terminates <i>thr</i> without calling ensure clauses and schedules\n *  another thread to be run, returning the terminated <code>Thread</code>.\n *  If this is the main thread, or the last thread, exits the process.\n *\n *  See <code>Thread#exit</code> for the safer version.\n */\n\nstatic VALUE\nrb_thread_kill_bang(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n    rb_kill_thread(th, THREAD_NO_ENSURE);\n    return thread;\n}\n\n/*\n *  call-seq:\n *     Thread.kill(thread)   => thread\n *\n *  Causes the given <em>thread</em> to exit (see <code>Thread::exit</code>).\n *\n *     count = 0\n *     a = Thread.new { loop { count += 1 } }\n *     sleep(0.1)       #=> 0\n *     Thread.kill(a)   #=> #<Thread:0x401b3d30 dead>\n *     count            #=> 93947\n *     a.alive?         #=> false\n */\n\nstatic VALUE\nrb_thread_s_kill(obj, th)\n    VALUE obj, th;\n{\n    return rb_thread_kill(th);\n}\n\n\n/*\n *  call-seq:\n *     Thread.exit   => thread\n *\n *  Terminates the currently running thread and schedules another thread to be\n *  run. If this thread is already marked to be killed, <code>exit</code>\n *  returns the <code>Thread</code>. If this is the main thread, or the last\n *  thread, exit the process.\n */\n\nstatic VALUE\nrb_thread_exit()\n{\n    return rb_thread_kill(curr_thread->thread);\n}\n\n\n/*\n *  call-seq:\n *     Thread.pass   => nil\n *\n *  Invokes the thread scheduler to pass execution to another thread.\n *\n *     a = Thread.new { print \"a\"; Thread.pass;\n *                      print \"b\"; Thread.pass;\n *                      print \"c\" }\n *     b = Thread.new { print \"x\"; Thread.pass;\n *                      print \"y\"; Thread.pass;\n *                      print \"z\" }\n *     a.join\n *     b.join\n *\n *  <em>produces:</em>\n *\n *     axbycz\n */\n\nstatic VALUE\nrb_thread_pass()\n{\n    rb_thread_schedule();\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Thread.stop   => nil\n *\n *  Stops execution of the current thread, putting it into a ``sleep'' state,\n *  and schedules execution of another thread. Resets the ``critical'' condition\n *  to <code>false</code>.\n *\n *     a = Thread.new { print \"a\"; Thread.stop; print \"c\" }\n *     Thread.pass\n *     print \"b\"\n *     a.run\n *     a.join\n *\n *  <em>produces:</em>\n *\n *     abc\n */\n\nVALUE\nrb_thread_stop()\n{\n    enum rb_thread_status last_status = THREAD_RUNNABLE;\n\n    rb_thread_critical = 0;\n    if (curr_thread == curr_thread->next) {\n        rb_raise(rb_eThreadError, \"stopping only thread\\n\\tnote: use sleep to stop forever\");\n    }\n    if (curr_thread->status == THREAD_TO_KILL)\n        last_status = THREAD_TO_KILL;\n    curr_thread->status = THREAD_STOPPED;\n    rb_thread_schedule();\n    curr_thread->status = last_status;\n\n    return Qnil;\n}\n\nstruct timeval rb_time_timeval();\n\nvoid\nrb_thread_polling()\n{\n    if (curr_thread != curr_thread->next) {\n        curr_thread->status = THREAD_STOPPED;\n        curr_thread->delay = timeofday() + (double)0.06;\n        curr_thread->wait_for = WAIT_TIME;\n        rb_thread_schedule();\n    }\n}\n\nvoid\nrb_thread_sleep(sec)\n    int sec;\n{\n    if (curr_thread == curr_thread->next) {\n        TRAP_BEG;\n        sleep(sec);\n        TRAP_END;\n        return;\n    }\n    rb_thread_wait_for(rb_time_timeval(INT2FIX(sec)));\n}\n\nvoid\nrb_thread_sleep_forever()\n{\n    int thr_critical = rb_thread_critical;\n    if (curr_thread == curr_thread->next ||\n        curr_thread->status == THREAD_TO_KILL) {\n        rb_thread_critical = Qtrue;\n        TRAP_BEG;\n        pause();\n        rb_thread_critical = thr_critical;\n        TRAP_END;\n        return;\n    }\n\n    curr_thread->delay = DELAY_INFTY;\n    curr_thread->wait_for = WAIT_TIME;\n    curr_thread->status = THREAD_STOPPED;\n    rb_thread_schedule();\n}\n\n\n/*\n *  call-seq:\n *     thr.priority   => integer\n *\n *  Returns the priority of <i>thr</i>. Default is inherited from the\n *  current thread which creating the new thread, or zero for the\n *  initial main thread; higher-priority threads will run before\n *  lower-priority threads.\n *\n *     Thread.current.priority   #=> 0\n */\n\nstatic VALUE\nrb_thread_priority(thread)\n    VALUE thread;\n{\n    return INT2NUM(THREAD_DATA(thread)->priority);\n}\n\n\n/*\n *  call-seq:\n *     thr.priority= integer   => thr\n *\n *  Sets the priority of <i>thr</i> to <i>integer</i>. Higher-priority threads\n *  will run before lower-priority threads.\n *\n *     count1 = count2 = 0\n *     a = Thread.new do\n *           loop { count1 += 1 }\n *         end\n *     a.priority = -1\n *\n *     b = Thread.new do\n *           loop { count2 += 1 }\n *         end\n *     b.priority = -2\n *     sleep 1   #=> 1\n *     Thread.critical = 1\n *     count1    #=> 622504\n *     count2    #=> 5832\n */\n\nstatic VALUE\nrb_thread_priority_set(thread, prio)\n    VALUE thread, prio;\n{\n    rb_thread_t th;\n\n    rb_secure(4);\n    th = THREAD_DATA(thread);\n\n    th->priority = NUM2INT(prio);\n    rb_thread_schedule();\n    return prio;\n}\n\n\n/*\n *  call-seq:\n *     thr.safe_level   => integer\n *\n *  Returns the safe level in effect for <i>thr</i>. Setting thread-local safe\n *  levels can help when implementing sandboxes which run insecure code.\n *\n *     thr = Thread.new { $SAFE = 3; sleep }\n *     Thread.current.safe_level   #=> 0\n *     thr.safe_level              #=> 3\n */\n\nstatic VALUE\nrb_thread_safe_level(thread)\n    VALUE thread;\n{\n    rb_thread_t th;\n\n    th = THREAD_DATA(thread);\n    if (th == curr_thread) {\n        return INT2NUM(ruby_safe_level);\n    }\n    return INT2NUM(th->safe);\n}\n\nstatic int ruby_thread_abort;\nstatic VALUE thgroup_default;\n\n\n/*\n *  call-seq:\n *     Thread.abort_on_exception   => true or false\n *\n *  Returns the status of the global ``abort on exception'' condition.  The\n *  default is <code>false</code>. When set to <code>true</code>, or if the\n *  global <code>$DEBUG</code> flag is <code>true</code> (perhaps because the\n *  command line option <code>-d</code> was specified) all threads will abort\n *  (the process will <code>exit(0)</code>) if an exception is raised in any\n *  thread. See also <code>Thread::abort_on_exception=</code>.\n */\n\nstatic VALUE\nrb_thread_s_abort_exc()\n{\n    return ruby_thread_abort?Qtrue:Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     Thread.abort_on_exception= boolean   => true or false\n *\n *  When set to <code>true</code>, all threads will abort if an exception is\n *  raised. Returns the new state.\n *\n *     Thread.abort_on_exception = true\n *     t1 = Thread.new do\n *       puts  \"In new thread\"\n *       raise \"Exception from thread\"\n *     end\n *     sleep(1)\n *     puts \"not reached\"\n *\n *  <em>produces:</em>\n *\n *     In new thread\n *     prog.rb:4: Exception from thread (RuntimeError)\n *      from prog.rb:2:in `initialize'\n *      from prog.rb:2:in `new'\n *      from prog.rb:2\n */\n\nstatic VALUE\nrb_thread_s_abort_exc_set(self, val)\n    VALUE self, val;\n{\n    rb_secure(4);\n    ruby_thread_abort = RTEST(val);\n    return val;\n}\n\n\n/*\n *  call-seq:\n *     thr.abort_on_exception   => true or false\n *\n *  Returns the status of the thread-local ``abort on exception'' condition for\n *  <i>thr</i>. The default is <code>false</code>. See also\n *  <code>Thread::abort_on_exception=</code>.\n */\n\nstatic VALUE\nrb_thread_abort_exc(thread)\n    VALUE thread;\n{\n    return THREAD_DATA(thread)->abort?Qtrue:Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     thr.abort_on_exception= boolean   => true or false\n *\n *  When set to <code>true</code>, causes all threads (including the main\n *  program) to abort if an exception is raised in <i>thr</i>. The process will\n *  effectively <code>exit(0)</code>.\n */\n\nstatic VALUE\nrb_thread_abort_exc_set(thread, val)\n    VALUE thread, val;\n{\n    rb_secure(4);\n    THREAD_DATA(thread)->abort = RTEST(val);\n    return val;\n}\n\n\n/*\n *  call-seq:\n *     thr.group   => thgrp or nil\n *\n *  Returns the <code>ThreadGroup</code> which contains <i>thr</i>, or nil if\n *  the thread is not a member of any group.\n *\n *     Thread.main.group   #=> #<ThreadGroup:0x4029d914>\n */\n\nVALUE\nrb_thread_group(thread)\n    VALUE thread;\n{\n    VALUE group = THREAD_DATA(thread)->thgroup;\n    if (!group) {\n        group = Qnil;\n    }\n    return group;\n}\n\n#ifdef __ia64\n# define IA64_INIT(x) x\n#else\n# define IA64_INIT(x)\n#endif\n\n#define THREAD_ALLOC(th) do {\\\n    th = ALLOC(struct rb_thread);\\\n\\\n    th->next = 0;\\\n    th->prev = 0;\\\n\\\n    th->status = THREAD_RUNNABLE;\\\n    th->result = 0;\\\n    th->flags = 0;\\\n\\\n    th->stk_ptr = 0;\\\n    th->stk_len = 0;\\\n    th->stk_size = 0;\\\n    th->stk_max = 0;\\\n    th->wait_for = 0;\\\n    th->gc_stack_end = (VALUE *) STACK_GROW_DIRECTION;\\\n    IA64_INIT(th->bstr_ptr = 0);\\\n    IA64_INIT(th->bstr_len = 0);\\\n    IA64_INIT(th->bstr_max = 0);\\\n    FD_ZERO(&th->readfds);\\\n    FD_ZERO(&th->writefds);\\\n    FD_ZERO(&th->exceptfds);\\\n    th->delay = 0.0;\\\n    th->join = 0;\\\n\\\n    th->frame = 0;\\\n    th->scope = 0;\\\n    th->klass = 0;\\\n    th->wrapper = 0;\\\n    th->cref = ruby_cref;\\\n    th->dyna_vars = ruby_dyna_vars;\\\n    th->block = 0;\\\n    th->iter = 0;\\\n    th->tag = 0;\\\n    th->tracing = 0;\\\n    th->errinfo = Qnil;\\\n    th->last_status = 0;\\\n    th->last_line = 0;\\\n    th->last_match = Qnil;\\\n    th->abort = 0;\\\n    th->priority = 0;\\\n    th->thgroup = thgroup_default;\\\n    th->locals = 0;\\\n    th->thread = 0;\\\n    if (curr_thread == 0) {\\\n        th->sandbox = Qnil;\\\n    } else {\\\n        th->sandbox = curr_thread->sandbox;\\\n    }\\\n} while (0)\n\nstatic rb_thread_t\nrb_thread_alloc(klass)\n    VALUE klass;\n{\n    rb_thread_t th;\n    struct RVarmap *vars;\n\n    THREAD_ALLOC(th);\n    th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th);\n\n    /* if main_thread != NULL, then this is NOT the main thread, so\n     * we create a heap-stack\n     */\n    if (main_thread) {\n      /* Allocate stack, don't forget to add 1 extra word because of the MATH below */\n      unsigned int pagesize = getpagesize();\n      unsigned int total_size = rb_thread_stack_size + pagesize + sizeof(int);\n      void *stack_area = NULL;\n\n      stack_area = mmap(NULL, total_size, PROT_READ | PROT_WRITE | PROT_EXEC,\n                        MAP_PRIVATE | MAP_ANON, -1, 0);\n\n      if (stack_area == MAP_FAILED) {\n        rb_memerror();\n        fprintf(stderr, \"Thread stack allocation failed %d!\\n\", getpid());\n      }\n\n      th->stk_ptr = th->stk_pos = stack_area;\n      th->stk_size = total_size;\n\n      if (mprotect(th->stk_ptr, pagesize, PROT_NONE) == -1) {\n        fprintf(stderr, \"Failed to create thread guard region: %s\\n\", strerror(errno));\n        rb_memerror();\n      }\n\n      th->guard = th->stk_ptr + (pagesize/sizeof(VALUE *));\n\n      /* point stk_base at the top of the stack */\n      /* ASSUMPTIONS:\n       * 1.) The address returned by malloc is \"suitably aligned\" for anything on this system\n       * 2.) Adding a value that is \"aligned\" for this platform should not unalign the address\n       *     returned from malloc.\n       * 3.) Don't push anything on to the stack, otherwise it'll get unaligned.\n       * 4.) x86_64 ABI says aligned AFTER arguments have been pushed. You *must* then do a call[lq]\n       *     or push[lq] something else on to the stack if you inted to do a ret.\n       */\n      th->stk_base = th->stk_ptr + ((total_size - sizeof(int))/sizeof(VALUE *));\n      th->stk_len = rb_thread_stack_size;\n    } else {\n      th->stk_ptr = th->stk_pos = rb_gc_stack_start;\n    }\n\n    for (vars = th->dyna_vars; vars; vars = vars->next) {\n        if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;\n        FL_SET(vars, DVAR_DONT_RECYCLE);\n    }\n    return th;\n}\n\nstatic int thread_init;\n\n#if defined(POSIX_SIGNAL)\n#define CATCH_VTALRM() posix_signal(SIGVTALRM, catch_timer)\n#else\n#define CATCH_VTALRM() signal(SIGVTALRM, catch_timer)\n#endif\n\n#if defined(_THREAD_SAFE)\nstatic void\ncatch_timer(sig)\n    int sig;\n{\n#if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)\n    signal(sig, catch_timer);\n#endif\n    /* cause EINTR */\n}\n\n#define PER_NANO 1000000000\n\nstatic struct timespec *\nget_ts(struct timespec *to, long ns)\n{\n    struct timeval tv;\n\n#ifdef CLOCK_REALTIME\n    if (clock_gettime(CLOCK_REALTIME, to) != 0)\n#endif\n    {\n        gettimeofday(&tv, NULL);\n        to->tv_sec = tv.tv_sec;\n        to->tv_nsec = tv.tv_usec * 1000;\n    }\n    if ((to->tv_nsec += ns) >= PER_NANO) {\n        to->tv_sec += to->tv_nsec / PER_NANO;\n        to->tv_nsec %= PER_NANO;\n    }\n    return to;\n}\n\nstatic struct timer_thread {\n    pthread_cond_t cond;\n    pthread_mutex_t lock;\n    pthread_t thread;\n} time_thread = {PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER};\n\nstatic int timer_stopping;\n\n#define safe_mutex_lock(lock) \\\n    pthread_mutex_lock(lock); \\\n    pthread_cleanup_push((void (*)_((void *)))pthread_mutex_unlock, lock)\n\nstatic void*\nthread_timer(dummy)\n    void *dummy;\n{\n    struct timer_thread *running = ((void **)dummy)[0];\n    pthread_cond_t *start = ((void **)dummy)[1];\n    struct timespec to;\n    int err;\n\n    sigset_t all_signals;\n\n    sigfillset(&all_signals);\n    pthread_sigmask(SIG_BLOCK, &all_signals, 0);\n\n    safe_mutex_lock(&running->lock);\n    pthread_cond_signal(start);\n\n#define WAIT_FOR_10MS() \\\n    pthread_cond_timedwait(&running->cond, &running->lock, get_ts(&to, PER_NANO/100))\n    while ((err = WAIT_FOR_10MS()) == EINTR || err == ETIMEDOUT) {\n      if (timer_stopping)\n        break;\n\n        if (!rb_thread_critical) {\n            rb_thread_pending = 1;\n            if (rb_trap_immediate) {\n                pthread_kill(ruby_thid, SIGVTALRM);\n            }\n        }\n    }\n\n    pthread_cleanup_pop(1);\n\n    return NULL;\n}\n\nvoid\nrb_thread_start_timer()\n{\n    void *args[2];\n    static pthread_cond_t start = PTHREAD_COND_INITIALIZER;\n\n    if (thread_init) return;\n    if (rb_thread_alone()) return;\n    CATCH_VTALRM();\n    args[0] = &time_thread;\n    args[1] = &start;\n    safe_mutex_lock(&time_thread.lock);\n    if (pthread_create(&time_thread.thread, 0, thread_timer, args) == 0) {\n        thread_init = 1;\n#if !defined(__NetBSD__) && !defined(__APPLE__) && !defined(linux)\n        pthread_atfork(0, 0, rb_thread_stop_timer);\n#endif\n        pthread_cond_wait(&start, &time_thread.lock);\n    }\n    pthread_cleanup_pop(1);\n}\n\nvoid\nrb_thread_stop_timer()\n{\n    if (!thread_init) return;\n    safe_mutex_lock(&time_thread.lock);\n    timer_stopping = 1;\n    pthread_cond_signal(&time_thread.cond);\n    thread_init = 0;\n    pthread_cleanup_pop(1);\n    pthread_join(time_thread.thread, NULL);\n    timer_stopping = 0;\n}\n#elif defined(HAVE_SETITIMER)\nstatic void\ncatch_timer(sig)\n    int sig;\n{\n#if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)\n    signal(sig, catch_timer);\n#endif\n    if (!rb_thread_critical) {\n        rb_thread_pending = 1;\n    }\n    /* cause EINTR */\n}\n\nvoid\nrb_thread_start_timer()\n{\n    struct itimerval tval;\n\n    if (thread_init) return;\n    if (rb_thread_alone()) return;\n    CATCH_VTALRM();\n    tval.it_interval.tv_sec = 0;\n    tval.it_interval.tv_usec = 10000;\n    tval.it_value = tval.it_interval;\n    setitimer(ITIMER_VIRTUAL, &tval, NULL);\n    thread_init = 1;\n}\n\nvoid\nrb_thread_stop_timer()\n{\n    struct itimerval tval;\n\n    if (!thread_init) return;\n    tval.it_interval.tv_sec = 0;\n    tval.it_interval.tv_usec = 0;\n    tval.it_value = tval.it_interval;\n    setitimer(ITIMER_VIRTUAL, &tval, NULL);\n    thread_init = 0;\n}\n#else  /* !(_THREAD_SAFE || HAVE_SETITIMER) */\nint rb_thread_tick = THREAD_TICK;\n#endif\n\nstruct thread_start_args {\n  VALUE (*fn)();\n  void *arg;\n  rb_thread_t th;\n} new_th;\n\nstatic VALUE\nrb_thread_start_2();\n\n#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)\n#define START_TIMER() (thread_init ? (void)0 : rb_thread_start_timer())\n#define STOP_TIMER() (rb_thread_stop_timer())\n#else\n#define START_TIMER() ((void)0)\n#define STOP_TIMER() ((void)0)\n#endif\n\nstatic VALUE\nrb_thread_start_0(fn, arg, th)\n    VALUE (*fn)();\n    void *arg;\n    rb_thread_t th;\n{\n    volatile VALUE thread = th->thread;\n\n    if (OBJ_FROZEN(curr_thread->thgroup)) {\n        rb_raise(rb_eThreadError,\n                 \"can't start a new thread (frozen ThreadGroup)\");\n    }\n\n    if (THREAD_SAVE_CONTEXT(curr_thread)) {\n        return thread;\n    }\n\n    new_th.fn = fn;\n    new_th.arg = arg;\n    new_th.th = th;\n\n#if defined(__i386__)\n    __asm__ __volatile__ (\"movl %0, %%esp\\n\\t\"\n                          \"calll *%1\\n\"\n                          :: \"r\" (th->stk_base),\n                             \"r\" (rb_thread_start_2));\n#elif defined(__x86_64__)\n    __asm__ __volatile__ (\"movq %0, %%rsp\\n\\t\"\n                          \"callq *%1\\n\"\n                          :: \"r\" (th->stk_base),\n                             \"r\" (rb_thread_start_2));\n#else\n    #error unsupported architecture!\n#endif\n    /* NOTREACHED */\n    return 0;\n}\n\nstatic VALUE\nrb_thread_start_2()\n{\n   volatile rb_thread_t th = new_th.th;\n   volatile rb_thread_t th_save = th;\n   volatile VALUE thread = th->thread;\n   struct BLOCK *volatile saved_block = 0;\n   enum rb_thread_status status;\n   int state;\n   struct tag *tag, *new_tag, *prev_tag;\n   struct RVarmap *vars;\n   struct FRAME dummy_frame;\n\n   if (!th->next) {\n        /* merge in thread list */\n        th->prev = curr_thread;\n        curr_thread->next->prev = th;\n        th->next = curr_thread->next;\n        curr_thread->next = th;\n        th->priority = curr_thread->priority;\n        th->thgroup = curr_thread->thgroup;\n   }\n   curr_thread = th;\n\n   dummy_frame = *ruby_frame;\n   dummy_frame.prev = top_frame;\n   ruby_frame = &dummy_frame;\n\n   if (ruby_block) {            /* should nail down higher blocks */\n        struct BLOCK dummy;\n\n        dummy.prev = ruby_block;\n        blk_copy_prev(&dummy);\n        saved_block = ruby_block = dummy.prev;\n    }\n    START_TIMER();\n\n    scope_dup(ruby_scope);\n    prev_tag = NULL;\n    tag = prot_tag;\n    while (tag) {\n        new_tag = alloca(sizeof(struct tag));\n        memcpy(new_tag, tag, sizeof(struct tag));\n\n        if (prev_tag)\n            prev_tag->prev = new_tag;\n        else\n            prot_tag = new_tag;\n\n        prev_tag = new_tag;\n        tag = tag->prev;\n    }\n\n    PUSH_TAG(PROT_THREAD);\n    if ((state = EXEC_TAG()) == 0) {\n        if (THREAD_SAVE_CONTEXT(th) == 0) {\n            th->result = (*new_th.fn)(new_th.arg, th);\n        }\n        th = th_save;\n    }\n    else if (TAG_DST()) {\n        th = th_save;\n        th->result = prot_tag->retval;\n    }\n    POP_TAG();\n    status = th->status;\n\n    if (th == main_thread) ruby_stop(state);\n    rb_thread_remove(th);\n\n    if (saved_block) {\n        blk_free(saved_block);\n    }\n\n    if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {\n        th->flags |= RAISED_EXCEPTION;\n        if (state == TAG_FATAL) {\n            /* fatal error within this thread, need to stop whole script */\n            main_thread->errinfo = ruby_errinfo;\n            rb_thread_cleanup();\n        }\n        else if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {\n            if (th->safe >= 4) {\n                char buf[32];\n\n                sprintf(buf, \"Insecure exit at level %d\", th->safe);\n                th->errinfo = rb_exc_new2(rb_eSecurityError, buf);\n            }\n            else {\n                /* delegate exception to main_thread */\n                rb_thread_main_jump(ruby_errinfo, RESTORE_RAISE);\n            }\n        }\n        else if (th->safe < 4 && (ruby_thread_abort || th->abort || RTEST(ruby_debug))) {\n            /* exit on main_thread */\n            error_print();\n            rb_thread_main_jump(ruby_errinfo, RESTORE_EXIT);\n        }\n        else {\n            th->errinfo = ruby_errinfo;\n        }\n    }\n    rb_thread_schedule();\n    ruby_stop(0);               /* last thread termination */\n    return 0;                   /* not reached */\n}\n\nVALUE\nrb_thread_create(fn, arg)\n    VALUE (*fn)();\n    void *arg;\n{\n    Init_stack((void *)&arg);\n    return rb_thread_start_0(fn, arg, rb_thread_alloc(rb_cThread));\n}\n\nstatic VALUE\nrb_thread_yield(arg, th)\n    VALUE arg;\n    rb_thread_t th;\n{\n    const ID *tbl;\n\n    scope_dup(ruby_block->scope);\n\n    tbl = ruby_scope->local_tbl;\n    if (tbl) {\n        int n = *tbl++;\n        for (tbl += 2, n -= 2; n > 0; --n) { /* skip first 2 ($_ and $~) */\n            ID id = *tbl++;\n            if (id != 0 && !rb_is_local_id(id))  /* push flip states */\n                rb_dvar_push(id, Qfalse);\n        }\n    }\n    rb_dvar_push('_', Qnil);\n    rb_dvar_push('~', Qnil);\n    ruby_block->dyna_vars = ruby_dyna_vars;\n\n    return rb_yield_0(arg, 0, 0, YIELD_LAMBDA_CALL, Qtrue);\n}\n\n/*\n *  call-seq:\n *     Thread.new([arg]*) {|args| block }   => thread\n *\n *  Creates and runs a new thread to execute the instructions given in\n *  <i>block</i>. Any arguments passed to <code>Thread::new</code> are passed\n *  into the block.\n *\n *     x = Thread.new { sleep 0.1; print \"x\"; print \"y\"; print \"z\" }\n *     a = Thread.new { print \"a\"; print \"b\"; sleep 0.2; print \"c\" }\n *     x.join # Let the threads finish before\n *     a.join # main thread exits...\n *\n *  <em>produces:</em>\n *\n *     abxyzc\n */\n\nstatic VALUE\nrb_thread_s_new(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    rb_thread_t th = rb_thread_alloc(klass);\n    volatile VALUE *pos;\n\n    pos = th->stk_pos;\n    rb_obj_call_init(th->thread, argc, argv);\n    if (th->stk_pos == 0) {\n        rb_raise(rb_eThreadError, \"uninitialized thread - check `%s#initialize'\",\n                 rb_class2name(klass));\n    }\n\n    return th->thread;\n}\n\n\n/*\n *  call-seq:\n *     Thread.new([arg]*) {|args| block }   => thread\n *\n *  Creates and runs a new thread to execute the instructions given in\n *  <i>block</i>. Any arguments passed to <code>Thread::new</code> are passed\n *  into the block.\n *\n *     x = Thread.new { sleep 0.1; print \"x\"; print \"y\"; print \"z\" }\n *     a = Thread.new { print \"a\"; print \"b\"; sleep 0.2; print \"c\" }\n *     x.join # Let the threads finish before\n *     a.join # main thread exits...\n *\n *  <em>produces:</em>\n *\n *     abxyzc\n */\n\nstatic VALUE\nrb_thread_initialize(thread, args)\n    VALUE thread, args;\n{\n    rb_thread_t th;\n\n    if (!rb_block_given_p()) {\n        rb_raise(rb_eThreadError, \"must be called with a block\");\n    }\n    th = THREAD_DATA(thread);\n    if (th->stk_max) {\n        NODE *node = th->node;\n        if (!node) {\n            rb_raise(rb_eThreadError, \"already initialized thread\");\n        }\n        rb_raise(rb_eThreadError, \"already initialized thread - %s:%d\",\n                 node->nd_file, nd_line(node));\n    }\n    return rb_thread_start_0(rb_thread_yield, args, th);\n}\n\n\n/*\n *  call-seq:\n *     Thread.start([args]*) {|args| block }   => thread\n *     Thread.fork([args]*) {|args| block }    => thread\n *\n *  Basically the same as <code>Thread::new</code>. However, if class\n *  <code>Thread</code> is subclassed, then calling <code>start</code> in that\n *  subclass will not invoke the subclass's <code>initialize</code> method.\n */\n\nstatic VALUE\nrb_thread_start(klass, args)\n    VALUE klass, args;\n{\n    if (!rb_block_given_p()) {\n        rb_raise(rb_eThreadError, \"must be called with a block\");\n    }\n    return rb_thread_start_0(rb_thread_yield, args, rb_thread_alloc(klass));\n}\n\n\n/*\n *  call-seq:\n *     thr.value   => obj\n *\n *  Waits for <i>thr</i> to complete (via <code>Thread#join</code>) and returns\n *  its value.\n *\n *     a = Thread.new { 2 + 2 }\n *     a.value   #=> 4\n */\n\nstatic VALUE\nrb_thread_value(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    while (!rb_thread_join0(th, DELAY_INFTY));\n\n    return th->result;\n}\n\n\n/*\n *  call-seq:\n *     thr.status   => string, false or nil\n *\n *  Returns the status of <i>thr</i>: ``<code>sleep</code>'' if <i>thr</i> is\n *  sleeping or waiting on I/O, ``<code>run</code>'' if <i>thr</i> is executing,\n *  ``<code>aborting</code>'' if <i>thr</i> is aborting, <code>false</code> if\n *  <i>thr</i> terminated normally, and <code>nil</code> if <i>thr</i>\n *  terminated with an exception.\n *\n *     a = Thread.new { raise(\"die now\") }\n *     b = Thread.new { Thread.stop }\n *     c = Thread.new { Thread.exit }\n *     d = Thread.new { sleep }\n *     Thread.critical = true\n *     d.kill                  #=> #<Thread:0x401b3678 aborting>\n *     a.status                #=> nil\n *     b.status                #=> \"sleep\"\n *     c.status                #=> false\n *     d.status                #=> \"aborting\"\n *     Thread.current.status   #=> \"run\"\n */\n\nstatic VALUE\nrb_thread_status(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (rb_thread_dead(th)) {\n        if (!NIL_P(th->errinfo) && (th->flags & RAISED_EXCEPTION))\n            return Qnil;\n        return Qfalse;\n    }\n\n    return rb_str_new2(thread_status_name(th->status));\n}\n\n\n/*\n *  call-seq:\n *     thr.alive?   => true or false\n *\n *  Returns <code>true</code> if <i>thr</i> is running or sleeping.\n *\n *     thr = Thread.new { }\n *     thr.join                #=> #<Thread:0x401b3fb0 dead>\n *     Thread.current.alive?   #=> true\n *     thr.alive?              #=> false\n */\n\nVALUE\nrb_thread_alive_p(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (rb_thread_dead(th)) return Qfalse;\n    return Qtrue;\n}\n\n\n/*\n *  call-seq:\n *     thr.stop?   => true or false\n *\n *  Returns <code>true</code> if <i>thr</i> is dead or sleeping.\n *\n *     a = Thread.new { Thread.stop }\n *     b = Thread.current\n *     a.stop?   #=> true\n *     b.stop?   #=> false\n */\n\nstatic VALUE\nrb_thread_stop_p(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (rb_thread_dead(th)) return Qtrue;\n    if (th->status == THREAD_STOPPED) return Qtrue;\n    return Qfalse;\n}\n\nstatic void\nrb_thread_wait_other_threads()\n{\n    rb_thread_t th;\n    int found;\n\n    /* wait other threads to terminate */\n    while (curr_thread != curr_thread->next) {\n        found = 0;\n        FOREACH_THREAD(th) {\n            if (th != curr_thread && th->status != THREAD_STOPPED) {\n                found = 1;\n                break;\n            }\n        }\n        END_FOREACH(th);\n        if (!found) return;\n        rb_thread_schedule();\n    }\n}\n\nstatic void\nstack_free_safe_all_dead_threads()\n{\n    if ( dead_threads_need_stack_free ) {\n        rb_thread_t curr, th;\n        int left = dead_threads_need_stack_free;\n\n#if STACK_FREE_SAFE_DEBUG\n        fprintf(stderr, \"\\nstack_free_safe_all_dead_threads(): %d\\n\", dead_threads_need_stack_free);\n        fflush(stderr);\n#endif\n\n        /* stack_free_safe() will increment this flag if stack_free_safe(th) cannot call stack_free(). */\n        dead_threads_need_stack_free = 0;\n\n        /*\n        ** Check the last known dead thread that needs stack_free().\n        ** That thread might have been rb_thread_remove()'ed from the thread ring.\n        ** Otherwise, start after current thread's stk_ptr, it should not be freeable anyway.\n        */\n        if ( th = dead_thread_needs_stack_free ) {\n            if ( stack_free_safe(th, \"stack_free_safe_all_dead_threads\") )\n                if ( -- left <= 0 ) return;\n        }\n\n        curr = curr_thread;\n        FOREACH_THREAD_FROM(curr, th) {\n            if ( stack_free_safe(th, \"stack_free_safe_all_dead_threads\") )\n                if ( -- left <= 0 ) return;\n        }\n        END_FOREACH_FROM(curr, th);\n    }\n}\n\nstatic void\nrb_thread_cleanup()\n{\n    rb_thread_t curr, th;\n\n    curr = curr_thread;\n    while (curr->status == THREAD_KILLED) {\n        curr = curr->prev;\n    }\n\n    FOREACH_THREAD_FROM(curr, th) {\n        if (th->status != THREAD_KILLED) {\n            rb_thread_ready(th);\n            if (th != main_thread) {\n                th->thgroup = 0;\n                th->priority = 0;\n                th->status = THREAD_TO_KILL;\n                RDATA(th->thread)->dfree = NULL;\n            }\n        }\n    }\n    END_FOREACH_FROM(curr, th);\n}\n\n/*\n * call-seq:\n *    Thread.stack_size    => fixnum\n *\n * Returns the thread stack size in bytes\n */\nstatic VALUE\nrb_thread_stacksize_get()\n{\n  return INT2FIX(rb_thread_stack_size);\n}\n\n/*\n * call-seq:\n *    Thread.stack_size= fixnum => Qnil\n *\n * Sets the global thread stacksize and returns Qnil.\n */\nstatic VALUE\nrb_thread_stacksize_set(obj, val)\n     VALUE obj;\n     VALUE val;\n{\n\n  unsigned int size = FIX2UINT(val);\n\n  /* 16byte alignment works for both x86 and x86_64 */\n  if (size & (~0xf)) {\n    size += 0x10;\n    size = size & (~0xf);\n  }\n\n  rb_thread_stack_size = size;\n\n  return Qnil;\n}\n\nint rb_thread_critical;\n\n\n/*\n *  call-seq:\n *     Thread.critical   => true or false\n *\n *  Returns the status of the global ``thread critical'' condition.\n */\n\nstatic VALUE\nrb_thread_critical_get()\n{\n    return rb_thread_critical?Qtrue:Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     Thread.critical= boolean   => true or false\n *\n *  Sets the status of the global ``thread critical'' condition and returns\n *  it. When set to <code>true</code>, prohibits scheduling of any existing\n *  thread. Does not block new threads from being created and run. Certain\n *  thread operations (such as stopping or killing a thread, sleeping in the\n *  current thread, and raising an exception) may cause a thread to be scheduled\n *  even when in a critical section.  <code>Thread::critical</code> is not\n *  intended for daily use: it is primarily there to support folks writing\n *  threading libraries.\n */\n\nstatic VALUE\nrb_thread_critical_set(obj, val)\n    VALUE obj, val;\n{\n    rb_thread_critical = RTEST(val);\n    return val;\n}\n\nvoid\nrb_thread_interrupt()\n{\n    rb_thread_critical = 0;\n    rb_thread_ready(main_thread);\n    if (curr_thread == main_thread) {\n        rb_interrupt();\n    }\n    if (!rb_thread_dead(curr_thread)) {\n        if (THREAD_SAVE_CONTEXT(curr_thread)) {\n            return;\n        }\n    }\n    curr_thread = main_thread;\n    rb_thread_restore_context(curr_thread, RESTORE_INTERRUPT);\n}\n\nvoid\nrb_thread_signal_raise(sig)\n    int sig;\n{\n    rb_thread_critical = 0;\n    if (curr_thread == main_thread) {\n        VALUE argv[1];\n\n        rb_thread_ready(curr_thread);\n        argv[0] = INT2FIX(sig);\n        rb_exc_raise(rb_class_new_instance(1, argv, rb_eSignal));\n    }\n    rb_thread_ready(main_thread);\n    if (!rb_thread_dead(curr_thread)) {\n        if (THREAD_SAVE_CONTEXT(curr_thread)) {\n            return;\n        }\n    }\n    th_sig = sig;\n    curr_thread = main_thread;\n    rb_thread_restore_context(curr_thread, RESTORE_SIGNAL);\n}\n\nvoid\nrb_thread_trap_eval(cmd, sig, safe)\n    VALUE cmd;\n    int sig, safe;\n{\n    rb_thread_critical = 0;\n    if (curr_thread == main_thread) {\n        rb_trap_eval(cmd, sig, safe);\n        return;\n    }\n    if (!rb_thread_dead(curr_thread)) {\n        if (THREAD_SAVE_CONTEXT(curr_thread)) {\n            return;\n        }\n    }\n    th_cmd = cmd;\n    th_sig = sig;\n    th_safe = safe;\n    curr_thread = main_thread;\n    rb_thread_restore_context(curr_thread, RESTORE_TRAP);\n}\n\nvoid\nrb_thread_signal_exit()\n{\n    VALUE args[2];\n\n    rb_thread_critical = 0;\n    if (curr_thread == main_thread) {\n        rb_thread_ready(curr_thread);\n        rb_exit(EXIT_SUCCESS);\n    }\n    args[0] = INT2NUM(EXIT_SUCCESS);\n    args[1] = rb_str_new2(\"exit\");\n    rb_thread_ready(main_thread);\n    if (!rb_thread_dead(curr_thread)) {\n        if (THREAD_SAVE_CONTEXT(curr_thread)) {\n            return;\n        }\n    }\n    rb_thread_main_jump(rb_class_new_instance(2, args, rb_eSystemExit),\n                        RESTORE_EXIT);\n}\n\nstatic VALUE\nrb_thread_raise(argc, argv, th)\n    int argc;\n    VALUE *argv;\n    rb_thread_t th;\n{\n    volatile rb_thread_t th_save = th;\n    VALUE exc;\n\n    if (!th->next) {\n        rb_raise(rb_eArgError, \"unstarted thread\");\n    }\n    if (rb_thread_dead(th)) return Qnil;\n    exc = rb_make_exception(argc, argv);\n    if (curr_thread == th) {\n        rb_raise_jump(exc);\n    }\n\n    if (!rb_thread_dead(curr_thread)) {\n        if (THREAD_SAVE_CONTEXT(curr_thread)) {\n            return th_save->thread;\n        }\n    }\n\n    rb_thread_ready(th);\n    curr_thread = th;\n\n    th_raise_exception = exc;\n    th_raise_node = ruby_current_node;\n    rb_thread_restore_context(curr_thread, RESTORE_RAISE);\n    return Qnil;                /* not reached */\n}\n\n\n/*\n *  call-seq:\n *     thr.raise(exception)\n *\n *  Raises an exception (see <code>Kernel::raise</code>) from <i>thr</i>. The\n *  caller does not have to be <i>thr</i>.\n *\n *     Thread.abort_on_exception = true\n *     a = Thread.new { sleep(200) }\n *     a.raise(\"Gotcha\")\n *\n *  <em>produces:</em>\n *\n *     prog.rb:3: Gotcha (RuntimeError)\n *      from prog.rb:2:in `initialize'\n *      from prog.rb:2:in `new'\n *      from prog.rb:2\n */\n\nstatic VALUE\nrb_thread_raise_m(argc, argv, thread)\n    int argc;\n    VALUE *argv;\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (ruby_safe_level > th->safe) {\n        rb_secure(4);\n    }\n    rb_thread_raise(argc, argv, th);\n    return Qnil;                /* not reached */\n}\n\nVALUE\nrb_thread_local_aref(thread, id)\n    VALUE thread;\n    ID id;\n{\n    rb_thread_t th;\n    VALUE val;\n\n    th = THREAD_DATA(thread);\n    if (ruby_safe_level >= 4 && th != curr_thread) {\n        rb_raise(rb_eSecurityError, \"Insecure: thread locals\");\n    }\n    if (!th->locals) return Qnil;\n    if (st_lookup(th->locals, id, &val)) {\n        return val;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *      thr[sym]   => obj or nil\n *\n *  Attribute Reference---Returns the value of a thread-local variable, using\n *  either a symbol or a string name. If the specified variable does not exist,\n *  returns <code>nil</code>.\n *\n *     a = Thread.new { Thread.current[\"name\"] = \"A\"; Thread.stop }\n *     b = Thread.new { Thread.current[:name]  = \"B\"; Thread.stop }\n *     c = Thread.new { Thread.current[\"name\"] = \"C\"; Thread.stop }\n *     Thread.list.each {|x| puts \"#{x.inspect}: #{x[:name]}\" }\n *\n *  <em>produces:</em>\n *\n *     #<Thread:0x401b3b3c sleep>: C\n *     #<Thread:0x401b3bc8 sleep>: B\n *     #<Thread:0x401b3c68 sleep>: A\n *     #<Thread:0x401bdf4c run>:\n */\n\nstatic VALUE\nrb_thread_aref(thread, id)\n    VALUE thread, id;\n{\n    return rb_thread_local_aref(thread, rb_to_id(id));\n}\n\nVALUE\nrb_thread_local_aset(thread, id, val)\n    VALUE thread;\n    ID id;\n    VALUE val;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (ruby_safe_level >= 4 && th != curr_thread) {\n        rb_raise(rb_eSecurityError, \"Insecure: can't modify thread locals\");\n    }\n    if (OBJ_FROZEN(thread)) rb_error_frozen(\"thread locals\");\n\n    if (!th->locals) {\n        th->locals = st_init_numtable();\n    }\n    if (NIL_P(val)) {\n        st_delete(th->locals, (st_data_t*)&id, 0);\n        return Qnil;\n    }\n    st_insert(th->locals, id, val);\n\n    return val;\n}\n\n\n/*\n *  call-seq:\n *      thr[sym] = obj   => obj\n *\n *  Attribute Assignment---Sets or creates the value of a thread-local variable,\n *  using either a symbol or a string. See also <code>Thread#[]</code>.\n */\n\nstatic VALUE\nrb_thread_aset(thread, id, val)\n    VALUE thread, id, val;\n{\n    return rb_thread_local_aset(thread, rb_to_id(id), val);\n}\n\n\n/*\n *  call-seq:\n *     thr.key?(sym)   => true or false\n *\n *  Returns <code>true</code> if the given string (or symbol) exists as a\n *  thread-local variable.\n *\n *     me = Thread.current\n *     me[:oliver] = \"a\"\n *     me.key?(:oliver)    #=> true\n *     me.key?(:stanley)   #=> false\n */\n\nstatic VALUE\nrb_thread_key_p(thread, id)\n    VALUE thread, id;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n\n    if (!th->locals) return Qfalse;\n    if (st_lookup(th->locals, rb_to_id(id), 0))\n        return Qtrue;\n    return Qfalse;\n}\n\nstatic int\nthread_keys_i(key, value, ary)\n    ID key;\n    VALUE value, ary;\n{\n    rb_ary_push(ary, ID2SYM(key));\n    return ST_CONTINUE;\n}\n\n\n/*\n *  call-seq:\n *     thr.keys   => array\n *\n *  Returns an an array of the names of the thread-local variables (as Symbols).\n *\n *     thr = Thread.new do\n *       Thread.current[:cat] = 'meow'\n *       Thread.current[\"dog\"] = 'woof'\n *     end\n *     thr.join   #=> #<Thread:0x401b3f10 dead>\n *     thr.keys   #=> [:dog, :cat]\n */\n\nstatic VALUE\nrb_thread_keys(thread)\n    VALUE thread;\n{\n    rb_thread_t th = THREAD_DATA(thread);\n    VALUE ary = rb_ary_new();\n\n    if (th->locals) {\n        st_foreach(th->locals, thread_keys_i, ary);\n    }\n    return ary;\n}\n\n/*\n * call-seq:\n *   thr.inspect   => string\n *\n * Dump the name, id, and status of _thr_ to a string.\n */\n\nstatic VALUE\nrb_thread_inspect(thread)\n    VALUE thread;\n{\n    const char *cname = rb_obj_classname(thread);\n    rb_thread_t th = THREAD_DATA(thread);\n    const char *status = thread_status_name(th->status);\n    VALUE str;\n    size_t len = strlen(cname)+7+16+9+1;\n\n    str = rb_str_new(0, len); /* 7:tags 16:addr 9:status 1:nul */\n    snprintf(RSTRING(str)->ptr, len, \"#<%s:0x%lx %s>\", cname, thread, status);\n    RSTRING(str)->len = strlen(RSTRING(str)->ptr);\n    OBJ_INFECT(str, thread);\n\n    return str;\n}\n\nvoid\nrb_thread_atfork()\n{\n    rb_thread_t th;\n\n    if (rb_thread_alone()) return;\n    FOREACH_THREAD(th) {\n        if (th != curr_thread) {\n            rb_thread_die(th);\n        }\n    }\n    END_FOREACH(th);\n    main_thread = curr_thread;\n    curr_thread->next = curr_thread;\n    curr_thread->prev = curr_thread;\n    STOP_TIMER();\n}\n\nstatic inline void\ncc_purge(cc)\n    rb_thread_t cc;\n{  /* free continuation's stack if it has just died */\n  if (cc->thread != Qnil && THREAD_DATA(cc->thread)->status == THREAD_KILLED) {\n    cc->thread = Qnil;\n    rb_thread_die(cc);  /* can't possibly activate this stack */\n  }\n}\n\nstatic void\ncc_mark(cc)\n    rb_thread_t cc;\n{\n    /* mark this continuation's stack only if its parent thread is still alive */\n    cc_purge(cc);\n    thread_mark(cc);\n}\n\n\n/*\n *  Document-class: Continuation\n *\n *  Continuation objects are generated by\n *  <code>Kernel#callcc</code>. They hold a return address and execution\n *  context, allowing a nonlocal return to the end of the\n *  <code>callcc</code> block from anywhere within a program.\n *  Continuations are somewhat analogous to a structured version of C's\n *  <code>setjmp/longjmp</code> (although they contain more state, so\n *  you might consider them closer to threads).\n *\n *  For instance:\n *\n *     arr = [ \"Freddie\", \"Herbie\", \"Ron\", \"Max\", \"Ringo\" ]\n *     callcc{|$cc|}\n *     puts(message = arr.shift)\n *     $cc.call unless message =~ /Max/\n *\n *  <em>produces:</em>\n *\n *     Freddie\n *     Herbie\n *     Ron\n *     Max\n *\n *  This (somewhat contrived) example allows the inner loop to abandon\n *  processing early:\n *\n *     callcc {|cont|\n *       for i in 0..4\n *         print \"\\n#{i}: \"\n *         for j in i*5...(i+1)*5\n *           cont.call() if j == 17\n *           printf \"%3d\", j\n *         end\n *       end\n *     }\n *     print \"\\n\"\n *\n *  <em>produces:</em>\n *\n *     0:   0  1  2  3  4\n *     1:   5  6  7  8  9\n *     2:  10 11 12 13 14\n *     3:  15 16\n */\n\nVALUE rb_cCont;\n\n\nstatic rb_thread_t prep4callcc(void)\n{\n  rb_thread_t th;\n  struct tag *tag;\n  struct RVarmap *vars;\n\n  THREAD_ALLOC(th);\n  /* must finish th initialization before any possible gc */\n  th->thread = curr_thread->thread;    /* brent@mbari.org */\n  th->thgroup = cont_protect;\n\n  scope_dup(ruby_scope);\n  for (tag=prot_tag; tag; tag=tag->prev) {\n      if (tag->tag == PROT_THREAD) break;\n      scope_dup(tag->scope);\n  }\n\n  for (vars = ruby_dyna_vars; vars; vars = vars->next) {\n      if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;\n      FL_SET(vars, DVAR_DONT_RECYCLE);\n  }\n  return th;\n}\n\n\n/*\n *  call-seq:\n *     callcc {|cont| block }   =>  obj\n *\n *  Generates a <code>Continuation</code> object, which it passes to the\n *  associated block. Performing a <em>cont</em><code>.call</code> will\n *  cause the <code>callcc</code> to return (as will falling through the\n *  end of the block). The value returned by the <code>callcc</code> is\n *  the value of the block, or the value passed to\n *  <em>cont</em><code>.call</code>. See class <code>Continuation</code>\n *  for more details. Also see <code>Kernel::throw</code> for\n *  an alternative mechanism for unwinding a call stack.\n */\n\nstatic VALUE\nrb_callcc(self)\n    VALUE self;\n{\n    volatile rb_thread_t th = prep4callcc();\n    return THREAD_SAVE_CONTEXT(th) ?\n      th->result\n          :\n      rb_yield(Data_Wrap_Struct(rb_cCont, cc_mark, thread_free, th));\n}\n\n\n/*\n *  call-seq:\n *     cont.call(args, ...)\n *     cont[args, ...]\n *\n *  Invokes the continuation. The program continues from the end of the\n *  <code>callcc</code> block. If no arguments are given, the original\n *  <code>callcc</code> returns <code>nil</code>. If one argument is\n *  given, <code>callcc</code> returns it. Otherwise, an array\n *  containing <i>args</i> is returned.\n *\n *     callcc {|cont|  cont.call }           #=> nil\n *     callcc {|cont|  cont.call 1 }         #=> 1\n *     callcc {|cont|  cont.call 1, 2, 3 }   #=> [1, 2, 3]\n */\n\nstatic VALUE\nrb_cont_call(argc, argv, cont)\n    int argc;\n    VALUE *argv;\n    VALUE cont;\n{\n    rb_thread_t th = THREAD_DATA(cont);\n\n    if (th->thread != curr_thread->thread) {\n        rb_raise(rb_eRuntimeError, \"continuation called across threads\");\n    }\n    if (th->thgroup != cont_protect) {\n        rb_raise(rb_eRuntimeError, \"continuation called across trap\");\n    }\n    switch (argc) {\n      case 0:\n        th->result = Qnil;\n        break;\n      case 1:\n        th->result = argv[0];\n        break;\n      default:\n        th->result = rb_ary_new4(argc, argv);\n        break;\n    }\n\n    rb_thread_restore_context(th, RESTORE_NORMAL);\n    return Qnil;\n}\n\n#ifdef MBARI_API\n/*\n *  call-seq:\n *     cont.thread\n *\n *  Returns the thread on which this continuation can be called\n *  or nil if that thread has died\n *\n *     t = Thread.new {callcc{|c| $x=c}; sleep 5}\n *     sleep 1\n *     $x.thread                             #=> t\n *     sleep 10\n *     $x.thread                             #=> nil\n *\n *  <i>Only available when MBARI_API extentions are enabled at build time</i>\n */\nstatic VALUE\nrb_cont_thread(cont)\n  VALUE cont;\n{\n  rb_thread_t th = THREAD_DATA(cont);\n  cc_purge(th);\n  return th->thread;\n}\n#endif\n\n\nstruct thgroup {\n    int enclosed;\n    VALUE group;\n};\n\n\n/*\n * Document-class: ThreadGroup\n *\n *  <code>ThreadGroup</code> provides a means of keeping track of a number of\n *  threads as a group. A <code>Thread</code> can belong to only one\n *  <code>ThreadGroup</code> at a time; adding a thread to a new group will\n *  remove it from any previous group.\n *\n *  Newly created threads belong to the same group as the thread from which they\n *  were created.\n */\n\nstatic VALUE thgroup_s_alloc _((VALUE));\nstatic VALUE\nthgroup_s_alloc(klass)\n    VALUE klass;\n{\n    VALUE group;\n    struct thgroup *data;\n\n    group = Data_Make_Struct(klass, struct thgroup, 0, free, data);\n    data->enclosed = 0;\n    data->group = group;\n\n    return group;\n}\n\n\n/*\n *  call-seq:\n *     thgrp.list   => array\n *\n *  Returns an array of all existing <code>Thread</code> objects that belong to\n *  this group.\n *\n *     ThreadGroup::Default.list   #=> [#<Thread:0x401bdf4c run>]\n */\n\nstatic VALUE\nthgroup_list(group)\n    VALUE group;\n{\n    struct thgroup *data;\n    rb_thread_t th;\n    VALUE ary;\n\n    Data_Get_Struct(group, struct thgroup, data);\n    ary = rb_ary_new();\n\n    FOREACH_THREAD(th) {\n        if (th->thgroup == data->group) {\n            rb_ary_push(ary, th->thread);\n        }\n    }\n    END_FOREACH(th);\n\n    return ary;\n}\n\n\n/*\n *  call-seq:\n *     thgrp.enclose   => thgrp\n *\n *  Prevents threads from being added to or removed from the receiving\n *  <code>ThreadGroup</code>. New threads can still be started in an enclosed\n *  <code>ThreadGroup</code>.\n *\n *     ThreadGroup::Default.enclose        #=> #<ThreadGroup:0x4029d914>\n *     thr = Thread::new { Thread.stop }   #=> #<Thread:0x402a7210 sleep>\n *     tg = ThreadGroup::new               #=> #<ThreadGroup:0x402752d4>\n *     tg.add thr\n *\n *  <em>produces:</em>\n *\n *     ThreadError: can't move from the enclosed thread group\n */\n\nstatic VALUE\nthgroup_enclose(group)\n    VALUE group;\n{\n    struct thgroup *data;\n\n    Data_Get_Struct(group, struct thgroup, data);\n    data->enclosed = 1;\n\n    return group;\n}\n\n\n/*\n *  call-seq:\n *     thgrp.enclosed?   => true or false\n *\n *  Returns <code>true</code> if <em>thgrp</em> is enclosed. See also\n *  ThreadGroup#enclose.\n */\n\nstatic VALUE\nthgroup_enclosed_p(group)\n    VALUE group;\n{\n    struct thgroup *data;\n\n    Data_Get_Struct(group, struct thgroup, data);\n    if (data->enclosed) return Qtrue;\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     thgrp.add(thread)   => thgrp\n *\n *  Adds the given <em>thread</em> to this group, removing it from any other\n *  group to which it may have previously belonged.\n *\n *     puts \"Initial group is #{ThreadGroup::Default.list}\"\n *     tg = ThreadGroup.new\n *     t1 = Thread.new { sleep }\n *     t2 = Thread.new { sleep }\n *     puts \"t1 is #{t1}\"\n *     puts \"t2 is #{t2}\"\n *     tg.add(t1)\n *     puts \"Initial group now #{ThreadGroup::Default.list}\"\n *     puts \"tg group now #{tg.list}\"\n *\n *  <em>produces:</em>\n *\n *     Initial group is #<Thread:0x401bdf4c>\n *     t1 is #<Thread:0x401b3c90>\n *     t2 is #<Thread:0x401b3c18>\n *     Initial group now #<Thread:0x401b3c18>#<Thread:0x401bdf4c>\n *     tg group now #<Thread:0x401b3c90>\n */\n\nstatic VALUE\nthgroup_add(group, thread)\n    VALUE group, thread;\n{\n    rb_thread_t th;\n    struct thgroup *data;\n\n    rb_secure(4);\n    th = rb_thread_check(thread);\n\n    if (OBJ_FROZEN(group)) {\n      rb_raise(rb_eThreadError, \"can't move to the frozen thread group\");\n    }\n    Data_Get_Struct(group, struct thgroup, data);\n    if (data->enclosed) {\n        rb_raise(rb_eThreadError, \"can't move to the enclosed thread group\");\n    }\n\n    if (!th->thgroup) {\n        return Qnil;\n    }\n    if (OBJ_FROZEN(th->thgroup)) {\n        rb_raise(rb_eThreadError, \"can't move from the frozen thread group\");\n    }\n    Data_Get_Struct(th->thgroup, struct thgroup, data);\n    if (data->enclosed) {\n        rb_raise(rb_eThreadError, \"can't move from the enclosed thread group\");\n    }\n\n    th->thgroup = group;\n    return group;\n}\n\n\n/* variables for recursive traversals */\nstatic ID recursive_key;\n\nstatic VALUE\nrecursive_check(hash, obj)\n    VALUE hash;\n    VALUE obj;\n{\n    if (NIL_P(hash) || TYPE(hash) != T_HASH) {\n        return Qfalse;\n    }\n    else {\n        VALUE list = rb_hash_aref(hash, ID2SYM(rb_frame_last_func()));\n\n        if (NIL_P(list) || TYPE(list) != T_HASH)\n            return Qfalse;\n        if (NIL_P(rb_hash_lookup(list, obj)))\n            return Qfalse;\n        return Qtrue;\n    }\n}\n\nstatic VALUE\nrecursive_push(hash, obj)\n    VALUE hash;\n    VALUE obj;\n{\n    VALUE list, sym;\n\n    sym = ID2SYM(rb_frame_last_func());\n    if (NIL_P(hash) || TYPE(hash) != T_HASH) {\n        hash = rb_hash_new();\n        rb_thread_local_aset(rb_thread_current(), recursive_key, hash);\n        list = Qnil;\n    }\n    else {\n        list = rb_hash_aref(hash, sym);\n    }\n    if (NIL_P(list) || TYPE(list) != T_HASH) {\n        list = rb_hash_new();\n        rb_hash_aset(hash, sym, list);\n    }\n    rb_hash_aset(list, obj, Qtrue);\n    return hash;\n}\n\nstatic void\nrecursive_pop(hash, obj)\n    VALUE hash;\n    VALUE obj;\n{\n    VALUE list, sym;\n\n    sym = ID2SYM(rb_frame_last_func());\n    if (NIL_P(hash) || TYPE(hash) != T_HASH) {\n        VALUE symname;\n        VALUE thrname;\n        symname = rb_inspect(sym);\n        thrname = rb_inspect(rb_thread_current());\n\n        rb_raise(rb_eTypeError, \"invalid inspect_tbl hash for %s in %s\",\n                 StringValuePtr(symname), StringValuePtr(thrname));\n    }\n    list = rb_hash_aref(hash, sym);\n    if (NIL_P(list) || TYPE(list) != T_HASH) {\n        VALUE symname = rb_inspect(sym);\n        VALUE thrname = rb_inspect(rb_thread_current());\n        rb_raise(rb_eTypeError, \"invalid inspect_tbl list for %s in %s\",\n                 StringValuePtr(symname), StringValuePtr(thrname));\n    }\n    rb_hash_delete(list, obj);\n}\n\nVALUE\nrb_exec_recursive(func, obj, arg)\n    VALUE (*func) _((VALUE, VALUE, int));\n    VALUE obj;\n    VALUE arg;\n{\n    volatile VALUE hash =\n      rb_thread_local_aref(rb_thread_current(), recursive_key);\n    volatile VALUE objid = rb_obj_id(obj);\n\n    if (recursive_check(hash, objid)) {\n        return (*func) (obj, arg, Qtrue);\n    }\n    else {\n        VALUE result;\n        int state;\n\n        hash = recursive_push(hash, objid);\n        PUSH_TAG(PROT_EMPTY);\n        result = (state = EXEC_TAG()) ? Qundef : (*func) (obj, arg, Qfalse);\n        POP_TAG();\n        recursive_pop(hash, objid);\n        if (state)\n            JUMP_TAG(state);\n        return result;\n    }\n}\n\n\n/*\n *  +Thread+ encapsulates the behavior of a thread of\n *  execution, including the main thread of the Ruby script.\n *\n *  In the descriptions of the methods in this class, the parameter _sym_\n *  refers to a symbol, which is either a quoted string or a\n *  +Symbol+ (such as <code>:name</code>).\n */\n\nvoid\nInit_Thread()\n{\n    VALUE cThGroup;\n\n    rb_thread_stack_size = (1024 * 1024);\n\n    recursive_key = rb_intern(\"__recursive_key__\");\n    rb_eThreadError = rb_define_class(\"ThreadError\", rb_eStandardError);\n    rb_cThread = rb_define_class(\"Thread\", rb_cObject);\n    rb_undef_alloc_func(rb_cThread);\n\n    rb_define_singleton_method(rb_cThread, \"new\", rb_thread_s_new, -1);\n    rb_define_method(rb_cThread, \"initialize\", rb_thread_initialize, -2);\n    rb_define_singleton_method(rb_cThread, \"start\", rb_thread_start, -2);\n    rb_define_singleton_method(rb_cThread, \"fork\", rb_thread_start, -2);\n\n    rb_define_singleton_method(rb_cThread, \"stop\", rb_thread_stop, 0);\n    rb_define_singleton_method(rb_cThread, \"kill\", rb_thread_s_kill, 1);\n    rb_define_singleton_method(rb_cThread, \"exit\", rb_thread_exit, 0);\n    rb_define_singleton_method(rb_cThread, \"pass\", rb_thread_pass, 0);\n    rb_define_singleton_method(rb_cThread, \"current\", rb_thread_current, 0);\n    rb_define_singleton_method(rb_cThread, \"main\", rb_thread_main, 0);\n    rb_define_singleton_method(rb_cThread, \"list\", rb_thread_list, 0);\n\n    rb_define_singleton_method(rb_cThread, \"critical\", rb_thread_critical_get, 0);\n    rb_define_singleton_method(rb_cThread, \"critical=\", rb_thread_critical_set, 1);\n\n    rb_define_singleton_method(rb_cThread, \"abort_on_exception\", rb_thread_s_abort_exc, 0);\n    rb_define_singleton_method(rb_cThread, \"abort_on_exception=\", rb_thread_s_abort_exc_set, 1);\n\n    rb_define_singleton_method(rb_cThread, \"stack_size\", rb_thread_stacksize_get, 0);\n    rb_define_singleton_method(rb_cThread, \"stack_size=\", rb_thread_stacksize_set, 1);\n\n    rb_define_method(rb_cThread, \"run\", rb_thread_run, 0);\n    rb_define_method(rb_cThread, \"wakeup\", rb_thread_wakeup, 0);\n    rb_define_method(rb_cThread, \"kill\", rb_thread_kill, 0);\n    rb_define_method(rb_cThread, \"terminate\", rb_thread_kill, 0);\n    rb_define_method(rb_cThread, \"exit\", rb_thread_kill, 0);\n    rb_define_method(rb_cThread, \"kill!\", rb_thread_kill_bang, 0);\n    rb_define_method(rb_cThread, \"terminate!\", rb_thread_kill_bang, 0);\n    rb_define_method(rb_cThread, \"exit!\", rb_thread_kill_bang, 0);\n    rb_define_method(rb_cThread, \"value\", rb_thread_value, 0);\n    rb_define_method(rb_cThread, \"status\", rb_thread_status, 0);\n    rb_define_method(rb_cThread, \"join\", rb_thread_join_m, -1);\n    rb_define_method(rb_cThread, \"alive?\", rb_thread_alive_p, 0);\n    rb_define_method(rb_cThread, \"stop?\", rb_thread_stop_p, 0);\n    rb_define_method(rb_cThread, \"raise\", rb_thread_raise_m, -1);\n\n    rb_define_method(rb_cThread, \"abort_on_exception\", rb_thread_abort_exc, 0);\n    rb_define_method(rb_cThread, \"abort_on_exception=\", rb_thread_abort_exc_set, 1);\n\n    rb_define_method(rb_cThread, \"priority\", rb_thread_priority, 0);\n    rb_define_method(rb_cThread, \"priority=\", rb_thread_priority_set, 1);\n    rb_define_method(rb_cThread, \"safe_level\", rb_thread_safe_level, 0);\n    rb_define_method(rb_cThread, \"group\", rb_thread_group, 0);\n\n    rb_define_method(rb_cThread, \"[]\", rb_thread_aref, 1);\n    rb_define_method(rb_cThread, \"[]=\", rb_thread_aset, 2);\n    rb_define_method(rb_cThread, \"key?\", rb_thread_key_p, 1);\n    rb_define_method(rb_cThread, \"keys\", rb_thread_keys, 0);\n\n    rb_define_method(rb_cThread, \"inspect\", rb_thread_inspect, 0);\n\n    rb_cCont = rb_define_class(\"Continuation\", rb_cObject);\n    rb_undef_alloc_func(rb_cCont);\n    rb_undef_method(CLASS_OF(rb_cCont), \"new\");\n    rb_define_method(rb_cCont, \"call\", rb_cont_call, -1);\n    rb_define_method(rb_cCont, \"[]\", rb_cont_call, -1);\n#ifdef MBARI_API\n    rb_define_method(rb_cCont, \"thread\", rb_cont_thread, 0);\n#endif\n    /* rb_define_global_function(\"callcc\", rb_callcc, 0); */\n    rb_global_variable(&cont_protect);\n\n    cThGroup = rb_define_class(\"ThreadGroup\", rb_cObject);\n    rb_define_alloc_func(cThGroup, thgroup_s_alloc);\n    rb_define_method(cThGroup, \"list\", thgroup_list, 0);\n    rb_define_method(cThGroup, \"enclose\", thgroup_enclose, 0);\n    rb_define_method(cThGroup, \"enclosed?\", thgroup_enclosed_p, 0);\n    rb_define_method(cThGroup, \"add\", thgroup_add, 1);\n    rb_global_variable(&thgroup_default);\n    thgroup_default = rb_obj_alloc(cThGroup);\n    rb_define_const(cThGroup, \"Default\", thgroup_default);\n\n    /* allocate main thread */\n    main_thread = rb_thread_alloc(rb_cThread);\n    curr_thread = main_thread->prev = main_thread->next = main_thread;\n}\n\n/*\n *  call-seq:\n *     catch(symbol) {| | block }  > obj\n *\n *  +catch+ executes its block. If a +throw+ is\n *  executed, Ruby searches up its stack for a +catch+ block\n *  with a tag corresponding to the +throw+'s\n *  _symbol_. If found, that block is terminated, and\n *  +catch+ returns the value given to +throw+. If\n *  +throw+ is not called, the block terminates normally, and\n *  the value of +catch+ is the value of the last expression\n *  evaluated. +catch+ expressions may be nested, and the\n *  +throw+ call need not be in lexical scope.\n *\n *     def routine(n)\n *       puts n\n *       throw :done if n <= 0\n *       routine(n-1)\n *     end\n *\n *\n *     catch(:done) { routine(3) }\n *\n *  <em>produces:</em>\n *\n *     3\n *     2\n *     1\n *     0\n */\n\nstatic VALUE\nrb_f_catch(dmy, tag)\n    VALUE dmy;\n    volatile VALUE tag;\n{\n    int state;\n    VALUE val;\n\n    tag = ID2SYM(rb_to_id(tag));\n    PUSH_TAG(tag);\n    if ((state = wipeAfter(EXEC_TAG_0())) == 0) {\n        val = rb_yield_0(tag, 0, 0, 0, Qfalse);\n    }\n    else if (state == TAG_THROW && tag == prot_tag->dst) {\n        val = prot_tag->retval;\n        state = 0;\n    }\n    POP_TAG();\n    if (state) JUMP_TAG(state);\n\n    return val;\n}\n\nstatic VALUE\ncatch_i(tag)\n    VALUE tag;\n{\n    return rb_funcall(Qnil, rb_intern(\"catch\"), 1, tag);\n}\n\nVALUE\nrb_catch(tag, func, data)\n    const char *tag;\n    VALUE (*func)();\n    VALUE data;\n{\n    return rb_iterate((VALUE(*)_((VALUE)))catch_i, ID2SYM(rb_intern(tag)), func, data);\n}\n\n/*\n *  call-seq:\n *     throw(symbol [, obj])\n *\n *  Transfers control to the end of the active +catch+ block\n *  waiting for _symbol_. Raises +NameError+ if there\n *  is no +catch+ block for the symbol. The optional second\n *  parameter supplies a return value for the +catch+ block,\n *  which otherwise defaults to +nil+. For examples, see\n *  <code>Kernel::catch</code>.\n */\n\nstatic VALUE\nrb_f_throw(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE tag, value;\n    struct tag *tt = prot_tag;\n\n    rb_scan_args(argc, argv, \"11\", &tag, &value);\n    tag = ID2SYM(rb_to_id(tag));\n\n    while (tt) {\n        if (tt->tag == tag) {\n            tt->dst = tag;\n            tt->retval = value;\n            break;\n        }\n        if (tt->tag == PROT_THREAD) {\n            rb_raise(rb_eThreadError, \"uncaught throw `%s' in thread 0x%lx\",\n                     rb_id2name(SYM2ID(tag)),\n                     curr_thread);\n        }\n        tt = tt->prev;\n    }\n    if (!tt) {\n        rb_name_error(SYM2ID(tag), \"uncaught throw `%s'\", rb_id2name(SYM2ID(tag)));\n    }\n#if STACK_WIPE_SITES & 0x800\n    rb_gc_update_stack_extent();\n#endif\n    rb_trap_restore_mask();\n    JUMP_TAG(TAG_THROW);\n#ifndef __GNUC__\n    return Qnil;                /* not reached */\n#endif\n}\n\nvoid\nrb_throw(tag, val)\n    const char *tag;\n    VALUE val;\n{\n    VALUE argv[2];\n\n    argv[0] = ID2SYM(rb_intern(tag));\n    argv[1] = val;\n    rb_f_throw(2, argv);\n}\n\nstatic VALUE\nswitch_thread_context_to_collect_backtrace(rb_thread_t next)\n{\n    if (THREAD_SAVE_CONTEXT(curr_thread)) {\n        return Qnil;\n    }\n    curr_thread = next;\n    rb_thread_restore_context(next, RESTORE_BACKTRACE);\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     caller_for_all_threads(start=1)    => array\n *\n *  Returns the current execution stack for all threads\n *  ---a hash whose keys are thread instances and values\n *  the thread caller backtrace.\n *\n *  Backtraces are array of hashes indicating location on the\n *  stack. Hash keys include ``<em>:line</em>'' or ``<em>:file</em>''\n *  and ``<em>:method'</em>''.\n *\n *  The optional _start_ parameter\n *  determines the number of initial stack entries to omit from the\n *  result.\n *\n *     def a(skip)\n *       caller_for_all_threads(skip)\n *     end\n *     def b(skip)\n *       a(skip)\n *     end\n *     def c(skip)\n *       b(skip)\n *     end\n *     c(0)   #=> [\"prog:2:in `a'\", \"prog:5:in `b'\", \"prog:8:in `c'\", \"prog:10\"]\n *     c(1)   #=> [\"prog:5:in `b'\", \"prog:8:in `c'\", \"prog:11\"]\n *     c(2)   #=> [\"prog:8:in `c'\", \"prog:12\"]\n *     c(3)   #=> [\"prog:13\"]\n */\nstatic VALUE\nrb_f_caller_for_all_threads(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    volatile int critical;\n    VALUE level;\n        VALUE result;\n\n    rb_scan_args(argc, argv, \"01\", &level);\n    backtrace_level_for_each_thread = NIL_P(level) ? 0 : NUM2INT(level);\n        if (backtrace_level_for_each_thread < 0) {\n                rb_raise(rb_eArgError, \"negative level (%d)\", backtrace_level_for_each_thread);\n        }\n\n        critical = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n    backtrace_for_each_thread = rb_hash_new();\n    switch_thread_context_to_collect_backtrace(main_thread->next);\n\n        result = backtrace_for_each_thread;\n        backtrace_for_each_thread = Qnil;\n        backtrace_for_each_thread = 0;\n\n        rb_thread_critical = critical;\n    return result;\n}\n"
  },
  {
    "path": "ext/.cvsignore",
    "content": "extinit.c\n*.log\n"
  },
  {
    "path": "ext/.document",
    "content": "# Add files to this as they become documented\n\nenumerator/enumerator.c\niconv/iconv.c\nnkf/lib/kconv.rb\nnkf/nkf.c\nsocket/socket.c\nstringio/stringio.c\nstrscan/strscan.c\nwin32ole\nzlib/zlib.c\n"
  },
  {
    "path": "ext/Setup",
    "content": "#option nodynamic\n\n#Win32API\n#bigdecimal\n#curses\n#dbm\n#digest\n#digest/md5\n#digest/rmd160\n#digest/sha1\n#digest/sha2\n#dl\n#enumerator\n#etc\n#fcntl\n#gdbm\n#iconv\n#io/wait\n#nkf\n#pty\n#openssl\n#racc/cparse\n#rational\n#readline\n#sdbm\n#socket\n#stringio\n#strscan\n#syck\n#syslog\n#tcltklib\n#thread\n#tk\n#trace\n#win32ole\n#zlib\n"
  },
  {
    "path": "ext/Setup.atheos",
    "content": "option nodynamic\n\n#Win32API\nbigdecimal\ncurses\ndbm\ndigest\ndigest/md5\ndigest/rmd160\ndigest/sha1\ndigest/sha2\ndl\nenumerator\netc\nfcntl\ngdbm\niconv\nio/wait\nnkf\npty\n#openssl\nracc/parse\nrational\nreadline\nsdbm\nsocket\nstringio\nstrscan\nsyck\nsyslog\n#tcltklib\nthread\n#tk\n#win32ole\nzlib\n"
  },
  {
    "path": "ext/Setup.dj",
    "content": "option nodynamic\n\n#Win32API\nbigdecimal\ncurses\ndbm\ndigest\ndigest/md5\ndigest/rmd160\ndigest/sha1\ndigest/sha2\n#dl\netc\nenumerator\nfcntl\ngdbm\n#iconv\n#io/wait\nnkf\n#pty\n#openssl\nracc/cparse\nrational\nreadline\nsdbm\n#socket\nstringio\nstrscan\nsyck\n#syslog\n#tcltklib\nthread\n#tk\n#win32ole\nzlib\n"
  },
  {
    "path": "ext/Setup.emx",
    "content": "option nodynamic\n\n#Win32API\nbigdecimal\ncurses\n#dbm\ndigest\ndigest/md5\ndigest/rmd160\ndigest/sha1\ndigest/sha2\n#dl\nenumerator\netc\nfcntl\n#gdbm\n#iconv\n#io/wait\nnkf\n#pty\n#openssl\nracc/cparse\nrational\n#readline\n#sdbm\nsocket\nstringio\nstrscan\n#syck\n#syslog\n#tcltklib\nthread\n#tk\n#win32ole\n#zlib\n"
  },
  {
    "path": "ext/Setup.nt",
    "content": "#option nodynamic\n\nWin32API\nbigdecimal\n#curses\n#dbm\ndigest\ndigest/md5\ndigest/rmd160\ndigest/sha1\ndigest/sha2\ndl\nenumerator\netc\nfcntl\n#gdbm\n#iconv\n#io/wait\nnkf\n#pty\n#openssl\nracc/cparse\nrational\n#readline\nsdbm\nsocket\nstringio\nstrscan\nsyck\n#syslog\n#tcltklib\nthread\n#tk\nwin32ole\n#zlib\n"
  },
  {
    "path": "ext/Setup.x68",
    "content": "option nodynamic\n\n#Win32API\nbigdecimal\n#curses\ndbm\ndigest\ndigest/md5\ndigest/rmd160\ndigest/sha1\ndigest/sha2\n#dl\n#etc\nenumerator\nfcntl\n#gdbm\n#iconv\n#io/wait\nnkf\n#pty\n#openssl\nracc/cparse\nrational\n#readline\n#sdbm\n#socket\nstringio\nstrscan\n#syck\n#syslog\n#tcltklib\nthread\n#tk\n#win32ole\n#zlib\n"
  },
  {
    "path": "ext/Win32API/.cvsignore",
    "content": "Makefile\n*.log\n*.def\n"
  },
  {
    "path": "ext/Win32API/Win32API.c",
    "content": "/*\n  Win32API - Ruby Win32 API Import Facility\n*/\n\n#if !defined _MSC_VER && !defined _WIN32\n#define  WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#include <stdio.h>\n#endif\n\n#define _T_VOID     0\n#define _T_NUMBER   1\n#define _T_POINTER  2\n#define _T_INTEGER  3\n\n#include \"ruby.h\"\n\ntypedef struct {\n    HANDLE dll;\n    HANDLE proc;\n    VALUE dllname;\n    VALUE import;\n    VALUE export;\n} Win32API;\n\nstatic void\nWin32API_FreeLibrary(hdll)\n    HINSTANCE hdll;\n{\n    FreeLibrary(hdll);\n}\n\nstatic VALUE\nWin32API_initialize(self, dllname, proc, import, export)\n    VALUE self;\n    VALUE dllname;\n    VALUE proc;\n    VALUE import;\n    VALUE export;\n{\n    HANDLE hproc;\n    HINSTANCE hdll;\n    VALUE str;\n    VALUE a_import;\n    VALUE *ptr;\n    char *s;\n    int i;\n    int len;\n    int ex = _T_VOID;\n\n    SafeStringValue(dllname);\n    SafeStringValue(proc);\n    hdll = LoadLibrary(RSTRING(dllname)->ptr);\n    if (!hdll)\n\trb_raise(rb_eRuntimeError, \"LoadLibrary: %s\\n\", RSTRING(dllname)->ptr);\n    rb_iv_set(self, \"__hdll__\", Data_Wrap_Struct(rb_cData, 0, Win32API_FreeLibrary, (void*)hdll));\n    hproc = (HANDLE)GetProcAddress(hdll, RSTRING(proc)->ptr);\n    if (!hproc) {\n\tstr = rb_str_new3(proc);\n\tstr = rb_str_cat(str, \"A\", 1);\n\thproc = (HANDLE)GetProcAddress(hdll, RSTRING(str)->ptr);\n\tif (!hproc)\n\t    rb_raise(rb_eRuntimeError, \"GetProcAddress: %s or %s\\n\",\n\t\tRSTRING(proc)->ptr, RSTRING(str)->ptr);\n    }\n    rb_iv_set(self, \"__dll__\", UINT2NUM((unsigned long)hdll));\n    rb_iv_set(self, \"__dllname__\", dllname);\n    rb_iv_set(self, \"__proc__\", UINT2NUM((unsigned long)hproc));\n\n    a_import = rb_ary_new();\n    switch (TYPE(import)) {\n    case T_NIL:\n\tbreak;\n    case T_ARRAY:\n\tptr = RARRAY(import)->ptr;\n\tfor (i = 0, len = RARRAY(import)->len; i < len; i++) {\n\t    SafeStringValue(ptr[i]);\n\t    switch (*(char *)RSTRING(ptr[i])->ptr) {\n\t    case 'N': case 'n': case 'L': case 'l':\n\t\trb_ary_push(a_import, INT2FIX(_T_NUMBER));\n\t\tbreak;\n\t    case 'P': case 'p':\n\t\trb_ary_push(a_import, INT2FIX(_T_POINTER));\n\t\tbreak;\n\t    case 'I': case 'i':\n\t\trb_ary_push(a_import, INT2FIX(_T_INTEGER));\n\t\tbreak;\n\t    }\n\t}\n        break;\n    default:\n\tSafeStringValue(import);\n\ts = RSTRING(import)->ptr;\n\tfor (i = 0, len = RSTRING(import)->len; i < len; i++) {\n\t    switch (*s++) {\n\t    case 'N': case 'n': case 'L': case 'l':\n\t\trb_ary_push(a_import, INT2FIX(_T_NUMBER));\n\t\tbreak;\n\t    case 'P': case 'p':\n\t\trb_ary_push(a_import, INT2FIX(_T_POINTER));\n\t\tbreak;\n\t    case 'I': case 'i':\n\t\trb_ary_push(a_import, INT2FIX(_T_INTEGER));\n\t\tbreak;\n\t    }\n\t}\n        break;\n    }\n\n    if (16 < RARRAY(a_import)->len) {\n\trb_raise(rb_eRuntimeError, \"too many parameters: %ld\\n\", RARRAY(a_import)->len);\n    }\n\n    rb_iv_set(self, \"__import__\", a_import);\n\n    if (NIL_P(export)) {\n\tex = _T_VOID;\n    } else {\n\tSafeStringValue(export);\n\tswitch (*RSTRING(export)->ptr) {\n        case 'V': case 'v':\n\t    ex = _T_VOID;\n\t    break;\n\tcase 'N': case 'n': case 'L': case 'l':\n\t    ex = _T_NUMBER;\n\t    break;\n\tcase 'P': case 'p':\n\t    ex = _T_POINTER;\n\t    break;\n\tcase 'I': case 'i':\n\t    ex = _T_INTEGER;\n\t    break;\n\t}\n    }\n    rb_iv_set(self, \"__export__\", INT2FIX(ex));\n\n    return Qnil;\n}\n\n#ifdef _MSC_VER\n#pragma optimize(\"g\", off)\n#endif\nstatic VALUE\nWin32API_Call(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE args;\n    unsigned long ret;\n    int i;\n    struct {\n\tunsigned long params[16];\n    } param;\n#define params param.params\n\n    VALUE obj_proc = rb_iv_get(obj, \"__proc__\");\n    VALUE obj_import = rb_iv_get(obj, \"__import__\");\n    VALUE obj_export = rb_iv_get(obj, \"__export__\");\n    FARPROC ApiFunction = (FARPROC)NUM2ULONG(obj_proc);\n    int items = rb_scan_args(argc, argv, \"0*\", &args);\n    int nimport = RARRAY(obj_import)->len;\n\n\n    if (items != nimport)\n\trb_raise(rb_eRuntimeError, \"wrong number of parameters: expected %d, got %d\",\n\t    nimport, items);\n\n    for (i = 0; i < nimport; i++) {\n\tunsigned long lParam = 0;\n\tswitch (FIX2INT(rb_ary_entry(obj_import, i))) {\n\t    VALUE str;\n\tcase _T_NUMBER:\n\tcase _T_INTEGER:\n\tdefault:\n\t    lParam = NUM2ULONG(rb_ary_entry(args, i));\n\t    break;\n\tcase _T_POINTER:\n\t    str = rb_ary_entry(args, i);\n\t    if (NIL_P(str)) {\n\t\tlParam = 0;\n\t    } else if (FIXNUM_P(str)) {\n\t\tlParam = NUM2ULONG(str);\n\t    } else {\n\t\tStringValue(str);\n\t\trb_str_modify(str);\n\t\tlParam = (unsigned long)StringValuePtr(str);\n\t    }\n\t    break;\n\t}\n\tparams[i] = lParam;\n    }\n\n    ret = ApiFunction(param);\n\n    switch (FIX2INT(obj_export)) {\n    case _T_NUMBER:\n    case _T_INTEGER:\n\treturn INT2NUM(ret);\n    case _T_POINTER:\n\treturn rb_str_new2((char *)ret);\n    case _T_VOID:\n    default:\n\treturn INT2NUM(0);\n    }\n}\n\nvoid\nInit_Win32API()\n{\n    VALUE cWin32API = rb_define_class(\"Win32API\", rb_cObject);\n    rb_define_method(cWin32API, \"initialize\", Win32API_initialize, 4);\n    rb_define_method(cWin32API, \"call\", Win32API_Call, -1);\n    rb_define_alias(cWin32API,  \"Call\", \"call\");\n}\n"
  },
  {
    "path": "ext/Win32API/depend",
    "content": "Win32API.o : Win32API.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/Win32API/extconf.rb",
    "content": "require 'mkmf'\n\ndir_config(\"win32\")\nif have_header(\"windows.h\") and have_library(\"kernel32\")\n  create_makefile(\"Win32API\")\nend\n"
  },
  {
    "path": "ext/Win32API/getch.rb",
    "content": "require 'Win32API'\n\ngetch = Win32API.new(\"crtdll\", \"_getch\", [], 'L')\n\nputs getch.Call.chr\n"
  },
  {
    "path": "ext/Win32API/lib/win32/registry.rb",
    "content": "=begin\n= Win32 Registry I/F\nwin32/registry is registry accessor library for Win32 platform.\nIt uses Win32API to call Win32 Registry APIs.\n\n== example\n  Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\\foo') do |reg|\n    value = reg['foo']                               # read a value\n    value = reg['foo', Win32::Registry::REG_SZ]      # read a value with type\n    type, value = reg.read('foo')                    # read a value\n    reg['foo'] = 'bar'                               # write a value\n    reg['foo', Win32::Registry::REG_SZ] = 'bar'      # write a value with type\n    reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value\n    \n    reg.each_value { |name, type, data| ... }        # Enumerate values\n    reg.each_key { |key, wtime| ... }                # Enumerate subkeys\n    \n    reg.delete_value(name)                         # Delete a value\n    reg.delete_key(name)                           # Delete a subkey\n    reg.delete_key(name, true)                     # Delete a subkey recursively\n  end\n\n= Reference\n\n== Win32::Registry class\n\n=== including modules\n\n* Enumerable\n* Registry::Constants\n\n=== class methods\n--- Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)\n--- Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |reg| ... }\n    Open the registry key ((|subkey|)) under ((|key|)).\n    ((|key|)) is Win32::Registry object of parent key.\n    You can use predefined key HKEY_* (see ((<constants>)))\n    \n    ((|desired|)) and ((|opt|)) is access mask and key option.\n    For detail, see ((<MSDN Library|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/regopenkeyex.asp>)).\n    \n    If block is given, the key is closed automatically.\n\n--- Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)\n--- Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |reg| ... }\n    Create or open the registry key ((|subkey|)) under ((|key|)).\n    You can use predefined key HKEY_* (see ((<constants>)))\n    \n    If subkey is already exists, key is opened and Registry#((<created?>))\n    method will return false.\n    \n    If block is given, the key is closed automatically.\n\n--- Registry.expand_environ(str)\n    Replace (({%\\w+%})) into the environment value of ((|str|)).\n    This method is used for REG_EXPAND_SZ.\n    \n    For detail, see ((<ExpandEnvironmentStrings|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/expandenvironmentstrings.asp>)) Win32 API.\n\n--- Registry.type2name(type)\n    Convert registry type value to readable string.\n\n--- Registry.wtime2time(wtime)\n    Convert 64-bit FILETIME integer into Time object.\n\n--- Registry.time2wtime(time)\n    Convert Time object or Integer object into 64-bit FILETIME.\n\n=== instance methods\n--- open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)\n    Same as (({Win32::((<Registry.open>))(self, subkey, desired, opt)}))\n\n--- create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)\n    Same as (({Win32::((<Registry.create>))(self, subkey, desired, opt)}))\n\n--- close\n    Close key.\n    \n    After closed, most method raises error.\n\n--- read(name, *rtype)\n    Read a registry value named ((|name|)) and return array of\n    [ ((|type|)), ((|data|)) ].\n    When name is nil, the `default' value is read.\n    \n    ((|type|)) is value type. (see ((<Win32::Registry::Constants module>)))\n    ((|data|)) is value data, its class is:\n    :REG_SZ, REG_EXPAND_SZ\n       String\n    :REG_MULTI_SZ\n       Array of String\n    :REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD\n       Integer\n    :REG_BINARY\n       String (contains binary data)\n    \n    When ((|rtype|)) is specified, the value type must be included by\n    ((|rtype|)) array, or TypeError is raised.\n\n--- self[name, *rtype]\n    Read a registry value named ((|name|)) and return its value data.\n    The class of value is same as ((<read>)) method returns.\n    \n    If the value type is REG_EXPAND_SZ, returns value data whose environment\n    variables are replaced.\n    If the value type is neither REG_SZ, REG_MULTI_SZ, REG_DWORD,\n    REG_DWORD_BIG_ENDIAN, nor REG_QWORD, TypeError is raised.\n    \n    The meaning of ((|rtype|)) is same as ((<read>)) method.\n\n--- read_s(name)\n--- read_i(name)\n--- read_bin(name)\n    Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin)\n    registry value named ((|name|)).\n    \n    If the values type does not match, TypeError is raised.\n\n--- read_s_expand(name)\n    Read a REG_SZ or REG_EXPAND_SZ registry value named ((|name|)).\n    \n    If the value type is REG_EXPAND_SZ, environment variables are replaced.\n    Unless the value type is REG_SZ or REG_EXPAND_SZ, TypeError is raised.\n\n--- write(name, type, data)\n    Write ((|data|)) to a registry value named ((|name|)).\n    When name is nil, write to the `default' value.\n    \n    ((|type|)) is type value. (see ((<Registry::Constants module>)))\n    Class of ((|data|)) must be same as which ((<read>))\n    method returns.\n\n--- self[name, wtype = nil] = value\n    Write ((|value|)) to a registry value named ((|name|)).\n    \n    If ((|wtype|)) is specified, the value type is it.\n    Otherwise, the value type is depend on class of ((|value|)):\n    :Integer\n      REG_DWORD\n    :String\n      REG_SZ\n    :Array\n      REG_MULTI_SZ\n\n--- write_s(name, value)\n--- write_i(name, value)\n--- write_bin(name, value)\n    Write ((|value|)) to a registry value named ((|name|)).\n    \n    The value type is REG_SZ(write_s), REG_DWORD(write_i), or\n    REG_BINARY(write_bin).\n\n--- each { |name, type, value| ... }\n--- each_value { |name, type, value| ... }\n    Enumerate values.\n\n--- each_key { |subkey, wtime| ... }\n    Enumerate subkeys.\n    \n    ((|subkey|)) is String which contains name of subkey.\n    ((|wtime|)) is last write time as FILETIME (64-bit integer).\n    (see ((<Registry.wtime2time>)))\n\n--- delete(name)\n--- delete_value(name)\n    Delete a registry value named ((|name|)).\n    We can not delete the `default' value.\n\n--- delete_key(name, recursive = false)\n    Delete a subkey named ((|name|)) and all its values.\n    \n    If ((|recursive|)) is false, the subkey must not have subkeys.\n    Otherwise, this method deletes all subkeys and values recursively.\n\n--- flush\n    Write all the attributes into the registry file.\n\n--- created?\n    Returns if key is created ((*newly*)).\n    (see ((<Registry.create>)))\n\n--- open?\n    Returns if key is not closed.\n\n--- hkey\n    Returns key handle value.\n\n--- parent\n    Win32::Registry object of parent key, or nil if predefeined key.\n\n--- keyname\n    Same as ((|subkey|)) value of ((<Registry.open>)) or\n    ((<Registry.create>)) method.\n\n--- disposition\n    Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY).\n\n--- name\n--- to_s\n    Full path of key such as (({'HKEY_CURRENT_USER\\SOFTWARE\\foo\\bar'})).\n\n--- info\n    Returns key information as Array of:\n    :num_keys\n      The number of subkeys.\n    :max_key_length\n      Maximum length of name of subkeys.\n    :num_values\n      The number of values.\n    :max_value_name_length\n      Maximum length of name of values.\n    :max_value_length\n      Maximum length of value of values.\n    :descriptor_length\n      Length of security descriptor.\n    :wtime\n      Last write time as FILETIME(64-bit integer)\n    \n    For detail, see ((<RegQueryInfoKey|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/regqueryinfokey.asp>)) Win32 API.\n\n--- num_keys\n--- max_key_length\n--- num_values\n--- max_value_name_length\n--- max_value_length\n--- descriptor_length\n--- wtime\n    Returns an item of key information.\n\n=== constants\n--- HKEY_CLASSES_ROOT\n--- HKEY_CURRENT_USER\n--- HKEY_LOCAL_MACHINE\n--- HKEY_PERFORMANCE_DATA\n--- HKEY_CURRENT_CONFIG\n--- HKEY_DYN_DATA\n    Win32::Registry object whose key is predefined key.\n    For detail, see ((<MSDN Library|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/predefined_keys.asp>)).\n\n== Win32::Registry::Constants module\n\nFor detail, see ((<MSDN Library|URL:http://msdn.microsoft.com/library/en-us/sysinfo/base/registry.asp>)).\n\n--- HKEY_*\n    Predefined key ((*handle*)).\n    These are Integer, not Win32::Registry.\n\n--- REG_*\n    Registry value type.\n\n--- KEY_*\n    Security access mask.\n\n--- KEY_OPTIONS_*\n    Key options.\n\n--- REG_CREATED_NEW_KEY\n--- REG_OPENED_EXISTING_KEY\n    If the key is created newly or opened existing key.\n    See also Registry#((<disposition>)) method.\n\n=end\n\nrequire 'Win32API'\n\nmodule Win32\n  class Registry\n    module Constants\n      HKEY_CLASSES_ROOT = 0x80000000\n      HKEY_CURRENT_USER = 0x80000001\n      HKEY_LOCAL_MACHINE = 0x80000002\n      HKEY_USERS = 0x80000003\n      HKEY_PERFORMANCE_DATA = 0x80000004\n      HKEY_PERFORMANCE_TEXT = 0x80000050\n      HKEY_PERFORMANCE_NLSTEXT = 0x80000060\n      HKEY_CURRENT_CONFIG = 0x80000005\n      HKEY_DYN_DATA = 0x80000006\n      \n      REG_NONE = 0\n      REG_SZ = 1\n      REG_EXPAND_SZ = 2\n      REG_BINARY = 3\n      REG_DWORD = 4\n      REG_DWORD_LITTLE_ENDIAN = 4\n      REG_DWORD_BIG_ENDIAN = 5\n      REG_LINK = 6\n      REG_MULTI_SZ = 7\n      REG_RESOURCE_LIST = 8\n      REG_FULL_RESOURCE_DESCRIPTOR = 9\n      REG_RESOURCE_REQUIREMENTS_LIST = 10\n      REG_QWORD = 11\n      REG_QWORD_LITTLE_ENDIAN = 11\n      \n      STANDARD_RIGHTS_READ = 0x00020000\n      STANDARD_RIGHTS_WRITE = 0x00020000\n      KEY_QUERY_VALUE = 0x0001\n      KEY_SET_VALUE = 0x0002\n      KEY_CREATE_SUB_KEY = 0x0004\n      KEY_ENUMERATE_SUB_KEYS = 0x0008\n      KEY_NOTIFY = 0x0010\n      KEY_CREATE_LINK = 0x0020\n      KEY_READ = STANDARD_RIGHTS_READ |\n        KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY\n      KEY_WRITE = STANDARD_RIGHTS_WRITE |\n        KEY_SET_VALUE | KEY_CREATE_SUB_KEY\n      KEY_EXECUTE = KEY_READ\n      KEY_ALL_ACCESS = KEY_READ | KEY_WRITE | KEY_CREATE_LINK\n      \n      REG_OPTION_RESERVED = 0x0000\n      REG_OPTION_NON_VOLATILE = 0x0000\n      REG_OPTION_VOLATILE = 0x0001\n      REG_OPTION_CREATE_LINK = 0x0002\n      REG_OPTION_BACKUP_RESTORE = 0x0004\n      REG_OPTION_OPEN_LINK = 0x0008\n      REG_LEGAL_OPTION = REG_OPTION_RESERVED |\n        REG_OPTION_NON_VOLATILE | REG_OPTION_CREATE_LINK |\n        REG_OPTION_BACKUP_RESTORE | REG_OPTION_OPEN_LINK\n      \n      REG_CREATED_NEW_KEY = 1\n      REG_OPENED_EXISTING_KEY = 2\n      \n      REG_WHOLE_HIVE_VOLATILE = 0x0001\n      REG_REFRESH_HIVE = 0x0002\n      REG_NO_LAZY_FLUSH = 0x0004\n      REG_FORCE_RESTORE = 0x0008\n      \n      MAX_KEY_LENGTH = 514\n      MAX_VALUE_LENGTH = 32768\n    end\n    include Constants\n    include Enumerable\n    \n    #\n    # Error\n    #\n    class Error < ::StandardError\n      FormatMessageA = Win32API.new('kernel32.dll', 'FormatMessageA', 'LPLLPLP', 'L')\n      def initialize(code)\n        @code = code\n        msg = \"\\0\" * 1024\n        len = FormatMessageA.call(0x1200, 0, code, 0, msg, 1024, 0)\n        super msg[0, len].tr(\"\\r\", '').chomp\n      end\n      attr_reader :code\n    end\n    \n    #\n    # Predefined Keys\n    #\n    class PredefinedKey < Registry\n      def initialize(hkey, keyname)\n        @hkey = hkey\n        @parent = nil\n        @keyname = keyname\n        @disposition = REG_OPENED_EXISTING_KEY\n      end\n      \n      # Predefined keys cannot be closed\n      def close\n        raise Error.new(5) ## ERROR_ACCESS_DENIED\n      end\n      \n      # Fake class for Registry#open, Registry#create\n      def class\n        Registry\n      end\n      \n      # Make all\n      Constants.constants.grep(/^HKEY_/) do |c|\n        Registry.const_set c, new(Constants.const_get(c), c)\n      end\n    end\n    \n    #\n    # Win32 APIs\n    #\n    module API\n      [\n        %w/RegOpenKeyExA    LPLLP        L/,\n        %w/RegCreateKeyExA  LPLLLLPPP    L/,\n        %w/RegEnumValueA    LLPPPPPP     L/,\n        %w/RegEnumKeyExA    LLPPLLLP     L/,\n        %w/RegQueryValueExA LPLPPP       L/,\n        %w/RegSetValueExA   LPLLPL       L/,\n        %w/RegDeleteValue   LP           L/,\n        %w/RegDeleteKey     LP           L/,\n        %w/RegFlushKey      L            L/,\n        %w/RegCloseKey      L            L/,\n        %w/RegQueryInfoKey  LPPPPPPPPPPP L/,\n      ].each do |fn|\n        const_set fn[0].intern, Win32API.new('advapi32.dll', *fn)\n      end\n      \n      module_function\n      \n      def check(result)\n        raise Error, result, caller(2) if result != 0\n      end\n      \n      def packdw(dw)\n        [dw].pack('V')\n      end\n      \n      def unpackdw(dw)\n        dw += [0].pack('V')\n        dw.unpack('V')[0]\n      end\n      \n      def packqw(qw)\n        [ qw & 0xFFFFFFFF, qw >> 32 ].pack('VV')\n      end\n      \n      def unpackqw(qw)\n        qw = qw.unpack('VV')\n        (qw[1] << 32) | qw[0]\n      end\n      \n      def OpenKey(hkey, name, opt, desired)\n        result = packdw(0)\n        check RegOpenKeyExA.call(hkey, name, opt, desired, result)\n        unpackdw(result)\n      end\n      \n      def CreateKey(hkey, name, opt, desired)\n        result = packdw(0)\n        disp = packdw(0)\n        check RegCreateKeyExA.call(hkey, name, 0, 0, opt, desired,\n                                   0, result, disp)\n        [ unpackdw(result), unpackdw(disp) ]\n      end\n      \n      def EnumValue(hkey, index)\n        name = ' ' * Constants::MAX_KEY_LENGTH\n        size = packdw(Constants::MAX_KEY_LENGTH)\n        check RegEnumValueA.call(hkey, index, name, size, 0, 0, 0, 0)\n        name[0, unpackdw(size)]\n      end\n      \n      def EnumKey(hkey, index)\n        name = ' ' * Constants::MAX_KEY_LENGTH\n        size = packdw(Constants::MAX_KEY_LENGTH)\n        wtime = ' ' * 8\n        check RegEnumKeyExA.call(hkey, index, name, size, 0, 0, 0, wtime)\n        [ name[0, unpackdw(size)], unpackqw(wtime) ]\n      end\n      \n      def QueryValue(hkey, name)\n        type = packdw(0)\n        size = packdw(0)\n        check RegQueryValueExA.call(hkey, name, 0, type, 0, size)\n        data = ' ' * unpackdw(size)\n        check RegQueryValueExA.call(hkey, name, 0, type, data, size)\n        [ unpackdw(type), data[0, unpackdw(size)] ]\n      end\n      \n      def SetValue(hkey, name, type, data, size)\n        check RegSetValueExA.call(hkey, name, 0, type, data, size)\n      end\n      \n      def DeleteValue(hkey, name)\n        check RegDeleteValue.call(hkey, name)\n      end\n      \n      def DeleteKey(hkey, name)\n        check RegDeleteKey.call(hkey, name)\n      end\n      \n      def FlushKey(hkey)\n        check RegFlushKey.call(hkey)\n      end\n      \n      def CloseKey(hkey)\n        check RegCloseKey.call(hkey)\n      end\n      \n      def QueryInfoKey(hkey)\n        subkeys = packdw(0)\n        maxsubkeylen = packdw(0)\n        values = packdw(0)\n        maxvaluenamelen = packdw(0)\n        maxvaluelen = packdw(0)\n        secdescs = packdw(0)\n        wtime = ' ' * 8\n        check RegQueryInfoKey.call(hkey, 0, 0, 0, subkeys, maxsubkeylen, 0,\n          values, maxvaluenamelen, maxvaluelen, secdescs, wtime)\n        [ unpackdw(subkeys), unpackdw(maxsubkeylen), unpackdw(values),\n          unpackdw(maxvaluenamelen), unpackdw(maxvaluelen),\n          unpackdw(secdescs), unpackqw(wtime) ]\n      end\n    end\n    \n    #\n    # utility functions\n    #\n    def self.expand_environ(str)\n      str.gsub(/%([^%]+)%/) { ENV[$1] || ENV[$1.upcase] || $& }\n    end\n    \n    @@type2name = { }\n    %w[\n      REG_NONE REG_SZ REG_EXPAND_SZ REG_BINARY REG_DWORD\n      REG_DWORD_BIG_ENDIAN REG_LINK REG_MULTI_SZ\n      REG_RESOURCE_LIST REG_FULL_RESOURCE_DESCRIPTOR\n      REG_RESOURCE_REQUIREMENTS_LIST REG_QWORD\n    ].each do |type|\n      @@type2name[Constants.const_get(type)] = type\n    end\n    \n    def self.type2name(type)\n      @@type2name[type] || type.to_s\n    end\n    \n    def self.wtime2time(wtime)\n      Time.at((wtime - 116444736000000000) / 10000000)\n    end\n    \n    def self.time2wtime(time)\n      time.to_i * 10000000 + 116444736000000000\n    end\n    \n    #\n    # constructors\n    #\n    private_class_method :new\n    \n    def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)\n      subkey = subkey.chomp('\\\\')\n      newkey = API.OpenKey(hkey.hkey, subkey, opt, desired)\n      obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY)\n      if block_given?\n        begin\n          yield obj\n        ensure\n          obj.close\n        end\n      else\n        obj\n      end\n    end\n    \n    def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)\n      newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired)\n      obj = new(newkey, hkey, subkey, disp)\n      if block_given?\n        begin\n          yield obj\n        ensure\n          obj.close\n        end\n      else\n        obj\n      end\n    end\n    \n    #\n    # finalizer\n    #\n    @@final = proc { |hkey| proc { API.CloseKey(hkey[0]) if hkey[0] } }\n    \n    #\n    # initialize\n    #\n    def initialize(hkey, parent, keyname, disposition)\n      @hkey = hkey\n      @parent = parent\n      @keyname = keyname\n      @disposition = disposition\n      @hkeyfinal = [ hkey ]\n      ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal)\n    end\n    attr_reader :hkey, :parent, :keyname, :disposition\n    \n    #\n    # attributes\n    #\n    def created?\n      @disposition == REG_CREATED_NEW_KEY\n    end\n    \n    def open?\n      !@hkey.nil?\n    end\n    \n    def name\n      parent = self\n      name = @keyname\n      while parent = parent.parent\n        name = parent.keyname + '\\\\' + name\n      end\n      name\n    end\n    \n    def inspect\n      \"\\#<Win32::Registry key=#{name.inspect}>\"\n    end\n    \n    #\n    # marshalling\n    #\n    def _dump(depth)\n      raise TypeError, \"can't dump Win32::Registry\"\n    end\n    \n    #\n    # open/close\n    #\n    def open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk)\n      self.class.open(self, subkey, desired, opt, &blk)\n    end\n    \n    def create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk)\n      self.class.create(self, subkey, desired, opt, &blk)\n    end\n    \n    def close\n      API.CloseKey(@hkey)\n      @hkey = @parent = @keyname = nil\n      @hkeyfinal[0] = nil\n    end\n    \n    #\n    # iterator\n    #\n    def each_value\n      index = 0\n      while true\n        begin\n          subkey = API.EnumValue(@hkey, index)\n        rescue Error\n          break\n        end\n        begin\n          type, data = read(subkey)\n        rescue Error\n          next\n        end\n        yield subkey, type, data\n        index += 1\n      end\n      index\n    end\n    alias each each_value\n    \n    def each_key\n      index = 0\n      while true\n        begin\n          subkey, wtime = API.EnumKey(@hkey, index)\n        rescue Error\n          break\n        end\n        yield subkey, wtime\n        index += 1\n      end\n      index\n    end\n    \n    def keys\n      keys_ary = []\n      each_key { |key,| keys_ary << key }\n      keys_ary\n    end\n    \n    #\n    # reader\n    #\n    def read(name, *rtype)\n      type, data = API.QueryValue(@hkey, name)\n      unless rtype.empty? or rtype.include?(type)\n        raise TypeError, \"Type mismatch (expect #{rtype.inspect} but #{type} present)\"\n      end\n      case type\n      when REG_SZ, REG_EXPAND_SZ\n        [ type, data.chop ]\n      when REG_MULTI_SZ\n        [ type, data.split(/\\0/) ]\n      when REG_BINARY\n        [ type, data ]\n      when REG_DWORD\n        [ type, API.unpackdw(data) ]\n      when REG_DWORD_BIG_ENDIAN\n        [ type, data.unpack('N')[0] ]\n      when REG_QWORD\n        [ type, API.unpackqw(data) ]\n      else\n        raise TypeError, \"Type #{type} is not supported.\"\n      end\n    end\n    \n    def [](name, *rtype)\n      type, data = read(name, *rtype)\n      case type\n      when REG_SZ, REG_DWORD, REG_QWORD, REG_MULTI_SZ\n        data\n      when REG_EXPAND_SZ\n        Registry.expand_environ(data)\n      else\n        raise TypeError, \"Type #{type} is not supported.\"\n      end\n    end\n    \n    def read_s(name)\n      read(name, REG_SZ)[1]\n    end\n    \n    def read_s_expand(name)\n      type, data = read(name, REG_SZ, REG_EXPAND_SZ)\n      if type == REG_EXPAND_SZ\n        Registry.expand_environ(data)\n      else\n        data\n      end\n    end\n    \n    def read_i(name)\n      read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1]\n    end\n    \n    def read_bin(name)\n      read(name, REG_BINARY)[1]\n    end\n    \n    #\n    # writer\n    #\n    def write(name, type, data)\n      case type\n      when REG_SZ, REG_EXPAND_SZ\n        data = data.to_s + \"\\0\"\n      when REG_MULTI_SZ\n        data = data.to_a.join(\"\\0\") + \"\\0\\0\"\n      when REG_BINARY\n        data = data.to_s\n      when REG_DWORD\n        data = API.packdw(data.to_i)\n      when REG_DWORD_BIG_ENDIAN\n        data = [data.to_i].pack('N')\n      when REG_QWORD\n        data = API.packqw(data.to_i)\n      else\n        raise TypeError, \"Unsupported type #{type}\"\n      end\n      API.SetValue(@hkey, name, type, data, data.length)\n    end\n    \n    def []=(name, rtype, value = nil)\n      if value\n        write name, rtype, value\n      else\n        case value = rtype\n        when Integer\n          write name, REG_DWORD, value\n        when String\n          write name, REG_SZ, value\n        when Array\n          write name, REG_MULTI_SZ, value\n        else\n          raise TypeError, \"Unexpected type #{value.class}\"\n        end\n      end\n      value\n    end\n    \n    def write_s(name, value)\n      write name, REG_SZ, value.to_s\n    end\n    \n    def write_i(name, value)\n      write name, REG_DWORD, value.to_i\n    end\n    \n    def write_bin(name, value)\n      write name, REG_BINARY, value.to_s\n    end\n    \n    #\n    # delete\n    #\n    def delete_value(name)\n      API.DeleteValue(@hkey, name)\n    end\n    alias delete delete_value\n    \n    def delete_key(name, recursive = false)\n      if recursive\n        open(name, KEY_ALL_ACCESS) do |reg|\n          reg.keys.each do |key|\n            begin\n              reg.delete_key(key, true)\n            rescue Error\n              #\n            end\n          end\n        end\n        API.DeleteKey(@hkey, name)\n      else\n        begin\n          API.EnumKey @hkey, 0\n        rescue Error\n          return API.DeleteKey(@hkey, name)\n        end\n        raise Error.new(5) ## ERROR_ACCESS_DENIED\n      end\n    end\n    \n    #\n    # flush\n    #\n    def flush\n      API.FlushKey @hkey\n    end\n    \n    #\n    # key information\n    #\n    def info\n      API.QueryInfoKey(@hkey)\n    end\n    %w[\n      num_keys max_key_length\n      num_values max_value_name_length max_value_length\n      descriptor_length wtime\n    ].each_with_index do |s, i|\n      eval <<-__END__\n        def #{s}\n          info[#{i}]\n        end\n      __END__\n    end\n  end\nend\n"
  },
  {
    "path": "ext/Win32API/lib/win32/resolv.rb",
    "content": "=begin\n= Win32 DNS and DHCP I/F\n\n=end\n\nrequire 'win32/registry'\n\nmodule Win32\n  module Resolv\n    API = Registry::API\n    \n    def self.get_hosts_path\n      path = get_hosts_dir\n      path = File.expand_path('hosts', path)\n      File.exist?(path) ? path : nil\n    end\n    \n    def self.get_resolv_info\n      search, nameserver = get_info\n      if search.empty?\n        search = nil\n      else\n        search.delete(\"\")\n        search.uniq!\n      end\n      if nameserver.empty?\n        nameserver = nil\n      else\n        nameserver.delete(\"\")\n        nameserver.delete(\"0.0.0.0\")\n        nameserver.uniq!\n      end\n      [ search, nameserver ]\n    end\n\ngetv = Win32API.new('kernel32.dll', 'GetVersionExA', 'P', 'L')\ninfo = [ 148, 0, 0, 0, 0 ].pack('V5') + \"\\0\" * 128\ngetv.call(info)\nif info.unpack('V5')[4] == 2  # VER_PLATFORM_WIN32_NT\n#====================================================================\n# Windows NT\n#====================================================================\n  module_eval <<-'__EOS__', __FILE__, __LINE__+1\n    TCPIP_NT = 'SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters'\n    \n    class << self\n      private\n      def get_hosts_dir\n        Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|\n          reg.read_s_expand('DataBasePath')\n        end\n      end\n      \n      def get_info\n        search = nil\n        nameserver = []\n        Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT) do |reg|\n          begin\n            slist = reg.read_s('SearchList')\n            search = slist.split(/,\\s*/) unless slist.empty?\n          rescue Registry::Error\n          end\n          \n          if add_search = search.nil?\n            search = []\n            begin\n              nvdom = reg.read_s('NV Domain')\n              unless nvdom.empty?\n                @search = [ nvdom ]\n                if reg.read_i('UseDomainNameDevolution') != 0\n                  if /^[\\w\\d]+\\./ =~ nvdom\n                    devo = $'\n                  end\n                end\n              end\n            rescue Registry::Error\n            end\n          end\n          \n          reg.open('Interfaces') do |reg|\n            reg.each_key do |iface,|\n              reg.open(iface) do |regif|\n                begin\n                  [ 'NameServer', 'DhcpNameServer' ].each do |key|\n                    ns = regif.read_s(key)\n                    unless ns.empty?\n                      nameserver.concat(ns.split(/[,\\s]\\s*/))\n                      break\n                    end\n                  end\n                rescue Registry::Error\n                end\n                \n                if add_search\n                  begin\n                    [ 'Domain', 'DhcpDomain' ].each do |key|\n                      dom = regif.read_s(key)\n                      unless dom.empty?\n                        search.concat(dom.split(/,\\s*/))\n                        break\n                      end\n                    end\n                  rescue Registry::Error\n                  end\n                end\n              end\n            end\n          end\n          search << devo if add_search and devo\n        end\n        [ search.uniq, nameserver.uniq ]\n      end\n    end\n  __EOS__\nelse\n#====================================================================\n# Windows 9x\n#====================================================================\n  module_eval <<-'__EOS__', __FILE__, __LINE__+1\n    TCPIP_9X = 'SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP'\n    DHCP_9X = 'SYSTEM\\CurrentControlSet\\Services\\VxD\\DHCP'\n    WINDOWS = 'Software\\Microsoft\\Windows\\CurrentVersion'\n    \n    class << self\n   #   private\n      \n      def get_hosts_dir\n        Registry::HKEY_LOCAL_MACHINE.open(WINDOWS) do |reg|\n          reg.read_s_expand('SystemRoot')\n        end\n      end\n      \n      def get_info\n        search = []\n        nameserver = []\n        begin\n          Registry::HKEY_LOCAL_MACHINE.open(TCPIP_9X) do |reg|\n            if reg.read_s(\"EnableDNS\") == \"1\"\n              domain = reg.read_s(\"Domain\")\n              ns = reg.read_s(\"NameServer\")\n              slist = reg.read_s(\"SearchList\")\n              search << domain unless domain.empty?\n              search.concat(slist.split(/,\\s*/))\n              nameserver.concat(ns.split(/[,\\s]\\s*/))\n            end\n          end\n        rescue Registry::Error\n        end\n        \n        dhcpinfo = get_dhcpinfo\n        search.concat(dhcpinfo[0])\n        nameserver.concat(dhcpinfo[1])\n        [ search, nameserver ]\n      end\n      \n      def get_dhcpinfo\n        macaddrs = {}\n        ipaddrs = {}\n        WsControl.get_iflist.each do |index, macaddr, *ipaddr|\n          macaddrs[macaddr] = 1\n          ipaddr.each { |ipaddr| ipaddrs[ipaddr] = 1 }\n        end\n        iflist = [ macaddrs, ipaddrs ]\n        \n        search = []\n        nameserver = []\n        version = -1\n        Registry::HKEY_LOCAL_MACHINE.open(DHCP_9X) do |reg|\n          begin\n            version = API.unpackdw(reg.read_bin(\"Version\"))\n          rescue Registry::Error\n          end\n          \n          reg.each_key do |key,|\n            catch(:not_used) do\n              reg.open(key) do |regdi|\n                dom, ns = get_dhcpinfo_key(version, regdi, iflist)\n                search << dom if dom\n                nameserver.concat(ns) if ns\n              end\n            end\n          end\n        end\n        [ search, nameserver ]\n      end\n      \n      def get_dhcpinfo_95(reg)\n        dhcp = reg.read_bin(\"DhcpInfo\")\n        [\n          API.unpackdw(dhcp[4..7]),\n          API.unpackdw(dhcp[8..11]),\n          1,\n          dhcp[45..50],\n          reg.read_bin(\"OptionInfo\"),\n        ]\n      end\n      \n      def get_dhcpinfo_98(reg)\n        [\n          API.unpackdw(reg.read_bin(\"DhcpIPAddress\")),\n          API.unpackdw(reg.read_bin(\"DhcpSubnetMask\")),\n          API.unpackdw(reg.read_bin(\"HardwareType\")),\n          reg.read_bin(\"HardwareAddress\"),\n          reg.read_bin(\"OptionInfo\"),\n        ]\n      end\n      \n      def get_dhcpinfo_key(version, reg, iflist)\n        info = case version\n               when 1\n                 get_dhcpinfo_95(reg)\n               when 2\n                 get_dhcpinfo_98(reg)\n               else\n                 begin\n                   get_dhcpinfo_98(reg)\n                 rescue Registry::Error\n                   get_dhcpinfo_95(reg)\n                 end\n               end\n        ipaddr, netmask, hwtype, macaddr, opt = info\n        throw :not_used unless\n          ipaddr and ipaddr != 0 and\n          netmask and netmask != 0 and\n          macaddr and macaddr.size == 6 and\n          hwtype == 1 and\n          iflist[0][macaddr] and iflist[1][ipaddr]\n        \n        size = opt.size\n        idx = 0\n        while idx <= size\n          opttype = opt[idx]\n          optsize = opt[idx + 1]\n          optval  = opt[idx + 2, optsize]\n          case opttype\n          when 0xFF    ## term\n            break\n          when 0x0F    ## domain\n            domain = optval.chomp(\"\\0\")\n          when 0x06    ## dns\n            nameserver = optval.scan(/..../).collect { |addr|\n              \"%d.%d.%d.%d\" % addr.unpack('C4')\n            }\n          end\n          idx += optsize + 2\n        end\n        [ domain, nameserver ]\n      rescue Registry::Error\n        throw :not_used\n      end\n    end\n    \n    module WsControl\n      WsControl = Win32API.new('wsock32.dll', 'WsControl', 'LLPPPP', 'L')\n      WSAGetLastError = Win32API.new('wsock32.dll', 'WSAGetLastError', 'V', 'L')\n      \n      MAX_TDI_ENTITIES = 512\n      IPPROTO_TCP = 6\n      WSCTL_TCP_QUERY_INFORMATION = 0\n      INFO_CLASS_GENERIC = 0x100\n      INFO_CLASS_PROTOCOL = 0x200\n      INFO_TYPE_PROVIDER = 0x100\n      ENTITY_LIST_ID = 0\n      GENERIC_ENTITY = 0\n      CL_NL_ENTITY = 0x301\n      IF_ENTITY = 0x200\n      ENTITY_TYPE_ID = 1\n      CL_NL_IP = 0x303\n      IF_MIB = 0x202\n      IF_MIB_STATS_ID = 1\n      IP_MIB_ADDRTABLE_ENTRY_ID = 0x102\n      \n      def self.wsctl(tei_entity, tei_instance,\n                     toi_class, toi_type, toi_id,\n                     buffsize)\n        reqinfo = [\n                  ## TDIEntityID\n                    tei_entity, tei_instance,\n                  ## TDIObjectID\n                    toi_class, toi_type, toi_id,\n                  ## TCP_REQUEST_INFORMATION_EX\n                    \"\"\n                  ].pack('VVVVVa16')\n        reqsize = API.packdw(reqinfo.size)\n        buff = \"\\0\" * buffsize\n        buffsize = API.packdw(buffsize)\n        result = WsControl.call(\n                   IPPROTO_TCP,\n                   WSCTL_TCP_QUERY_INFORMATION,\n                   reqinfo, reqsize,\n                   buff, buffsize)\n        if result != 0\n          raise RuntimeError, \"WsControl failed.(#{result})\"\n        end\n        [ buff, API.unpackdw(buffsize) ]\n      end\n      private_class_method :wsctl\n      \n      def self.get_iflist\n        # Get TDI Entity List\n        entities, size =\n          wsctl(GENERIC_ENTITY, 0,\n                INFO_CLASS_GENERIC,\n                INFO_TYPE_PROVIDER,\n                ENTITY_LIST_ID,\n                MAX_TDI_ENTITIES * 8)  # sizeof(TDIEntityID)\n        entities = entities[0, size].\n                     scan(/.{8}/).\n                     collect { |e| e.unpack('VV') }\n\n        # Get MIB Interface List\n        iflist = []\n        ifcount = 0\n        entities.each do |entity, instance|\n          if( (entity & IF_ENTITY)>0 )\n            ifcount += 1\n            etype, = wsctl(entity, instance,\n                           INFO_CLASS_GENERIC,\n                           INFO_TYPE_PROVIDER,\n                           ENTITY_TYPE_ID,\n                           4)\n            if( (API.unpackdw(etype) & IF_MIB)==IF_MIB )\n              ifentry, = wsctl(entity, instance,\n                               INFO_CLASS_PROTOCOL,\n                               INFO_TYPE_PROVIDER,\n                               IF_MIB_STATS_ID,\n                               21 * 4 + 8 + 130)  # sizeof(IFEntry)\n              iflist << [\n                API.unpackdw(ifentry[0,4]),\n                ifentry[20, 6]\n              ]\n            end\n          end\n        end\n        \n        # Get IP Addresses\n        entities.each do |entity, instance|\n          if entity == CL_NL_ENTITY\n            etype, = wsctl(entity, instance,\n                           INFO_CLASS_GENERIC,\n                           INFO_TYPE_PROVIDER,\n                           ENTITY_TYPE_ID,\n                           4)\n            if API.unpackdw(etype) == CL_NL_IP\n              ipentries, = wsctl(entity, instance,\n                                 INFO_CLASS_PROTOCOL,\n                                 INFO_TYPE_PROVIDER,\n                                 IP_MIB_ADDRTABLE_ENTRY_ID,\n                                 24 * (ifcount+1))  # sizeof(IPAddrEntry)\n              ipentries.scan(/.{24}/) do |ipentry|\n                ipaddr, index = ipentry.unpack('VV')\n                if ifitem = iflist.assoc(index)\n                  ifitem << ipaddr\n                end\n              end\n            end\n          end\n        end\n        iflist\n      end\n    end\n  __EOS__\nend\n#====================================================================\n  end\nend\n"
  },
  {
    "path": "ext/Win32API/point.rb",
    "content": "require 'Win32API'\n\ngetCursorPos = Win32API.new(\"user32\", \"GetCursorPos\", ['P'], 'V')\n\nlpPoint = \" \" * 8 # store two LONGs\ngetCursorPos.Call(lpPoint)\nx, y = lpPoint.unpack(\"LL\") # get the actual values\n\nprint \"x: \", x, \"\\n\"\nprint \"y: \", y, \"\\n\"\n\nods = Win32API.new(\"kernel32\", \"OutputDebugString\", ['P'], 'V')\nods.Call(\"Hello, World\\n\");\n\nGetDesktopWindow = Win32API.new(\"user32\", \"GetDesktopWindow\", [], 'L')\nGetActiveWindow = Win32API.new(\"user32\", \"GetActiveWindow\", [], 'L')\nSendMessage = Win32API.new(\"user32\", \"SendMessage\", ['L'] * 4, 'L')\nSendMessage.Call GetDesktopWindow.Call, 274, 0xf140, 0\n"
  },
  {
    "path": "ext/bigdecimal/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/bigdecimal/README",
    "content": "\n  Ruby BIGDECIMAL(Variable Precision) extension library.\n  Copyright (C) 1999  by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)\n\nBigDecimal is copyrighted free software by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.\nYou can redistribute it and/or modify it under either the terms of the GPL\n(see COPYING file), or the conditions below:\n\n  1. You may make and give away verbatim copies of the source form of the\n     software without restriction, provided that you duplicate all of the\n     original copyright notices and associated disclaimers.\n\n  2. You may modify your copy of the software in any way, provided that\n     you do at least ONE of the following:\n\n       a) place your modifications in the Public Domain or otherwise\n          make them Freely Available, such as by posting said\n\t  modifications to Usenet or an equivalent medium, or by allowing\n\t  the author to include your modifications in the software.\n\n       b) use the modified software only within your corporation or\n          organization.\n\n       c) rename any non-standard executables so the names do not conflict\n\t  with standard executables, which must also be provided.\n\n       d) make other distribution arrangements with the author.\n\n  3. You may distribute the software in object code or executable\n     form, provided that you do at least ONE of the following:\n\n       a) distribute the executables and library files of the software,\n\t  together with instructions (in the manual page or equivalent)\n\t  on where to get the original distribution.\n\n       b) accompany the distribution with the machine-readable source of\n\t  the software.\n\n       c) give non-standard executables non-standard names, with\n          instructions on where to get the original software distribution.\n\n       d) make other distribution arrangements with the author.\n\n  4. You may modify and include the part of the software into any other\n     software (possibly commercial).\n\n  5. THIS SOFTWARE IS PROVIDED \"AS IS\" AND WITHOUT ANY EXPRESS OR\n     IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED\n     WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR\n     PURPOSE.\n\n* The Author\n\nFeel free to send comments and bug reports to the author.  Here is the \nauthor's latest mail address:\n\n  shigeo@tinyforest.gr.jp\n\n-------------------------------------------------------\ncreated at: Thu Dec 22 1999\n"
  },
  {
    "path": "ext/bigdecimal/bigdecimal.c",
    "content": "/*\n *\n * Ruby BigDecimal(Variable decimal precision) extension library.\n *\n * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)\n *\n * You may distribute under the terms of either the GNU General Public\n * License or the Artistic License, as specified in the README file\n * of this BigDecimal distribution.\n *\n *  NOTE: Change log in this source removed to reduce source code size. \n *        See rev. 1.25 if needed.\n *\n */\n\n#include \"ruby.h\"\n#include <ctype.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <float.h>\n#include <math.h>\n#include \"math.h\"\n#include \"version.h\"\n \n/* #define ENABLE_NUMERIC_STRING */\n\nVALUE rb_cBigDecimal;\n\n#include \"bigdecimal.h\"\n\n/* MACRO's to guard objects from GC by keeping them in stack */\n#define ENTER(n) volatile VALUE vStack[n];int iStack=0\n#define PUSH(x)  vStack[iStack++] = (unsigned long)(x);\n#define SAVE(p)  PUSH(p->obj);\n#define GUARD_OBJ(p,y) {p=y;SAVE(p);}\n\n/*\n * ================== Ruby Interface part ==========================\n */\n#define DoSomeOne(x,y) rb_num_coerce_bin(x,y)\n\n#if 0\n/* BigDecimal provides arbitrary-precision floating point decimal arithmetic.\n *\n * Copyright (C) 2002 by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.\n * You may distribute under the terms of either the GNU General Public\n * License or the Artistic License, as specified in the README file\n * of the BigDecimal distribution.\n *\n * Documented by mathew <meta@pobox.com>.\n *\n * = Introduction\n *\n * Ruby provides built-in support for arbitrary precision integer arithmetic.\n * For example:\n *\n * 42**13   ->   1265437718438866624512\n *\n * BigDecimal provides similar support for very large or very accurate floating\n * point numbers.\n *\n * Decimal arithmetic is also useful for general calculation, because it\n * provides the correct answers people expect--whereas normal binary floating\n * point arithmetic often introduces subtle errors because of the conversion\n * between base 10 and base 2. For example, try:\n *\n *   sum = 0\n *   for i in (1..10000)\n *     sum = sum + 0.0001\n *   end\n *   print sum\n *\n * and contrast with the output from:\n *\n *   require 'bigdecimal'\n *\n *   sum = BigDecimal.new(\"0\")\n *   for i in (1..10000)\n *     sum = sum + BigDecimal.new(\"0.0001\")\n *   end\n *   print sum\n *\n * Similarly:\n *\n * (BigDecimal.new(\"1.2\") - BigDecimal(\"1.0\")) == BigDecimal(\"0.2\") -> true\n *\n * (1.2 - 1.0) == 0.2 -> false\n *\n * = Special features of accurate decimal arithmetic\n *\n * Because BigDecimal is more accurate than normal binary floating point\n * arithmetic, it requires some special values.\n *\n * == Infinity\n *\n * BigDecimal sometimes needs to return infinity, for example if you divide\n * a value by zero.\n *\n * BigDecimal.new(\"1.0\") / BigDecimal.new(\"0.0\")  -> infinity\n *\n * BigDecimal.new(\"-1.0\") / BigDecimal.new(\"0.0\")  -> -infinity\n *\n * You can represent infinite numbers to BigDecimal using the strings\n * 'Infinity', '+Infinity' and '-Infinity' (case-sensitive)\n *\n * == Not a Number\n *\n * When a computation results in an undefined value, the special value NaN\n * (for 'not a number') is returned.\n *\n * Example:\n *\n * BigDecimal.new(\"0.0\") / BigDecimal.new(\"0.0\") -> NaN\n *\n * You can also create undefined values.  NaN is never considered to be the\n * same as any other value, even NaN itself:\n *\n * n = BigDecimal.new('NaN')\n *\n * n == 0.0 -> nil\n *\n * n == n -> nil\n *\n * == Positive and negative zero\n *\n * If a computation results in a value which is too small to be represented as\n * a BigDecimal within the currently specified limits of precision, zero must\n * be returned.\n *\n * If the value which is too small to be represented is negative, a BigDecimal\n * value of negative zero is returned. If the value is positive, a value of\n * positive zero is returned.\n *\n * BigDecimal.new(\"1.0\") / BigDecimal.new(\"-Infinity\") -> -0.0\n *\n * BigDecimal.new(\"1.0\") / BigDecimal.new(\"Infinity\") -> 0.0\n *\n * (See BigDecimal.mode for how to specify limits of precision.)\n *\n * Note that -0.0 and 0.0 are considered to be the same for the purposes of\n * comparison.\n *\n * Note also that in mathematics, there is no particular concept of negative \n * or positive zero; true mathematical zero has no sign.\n */\nvoid\nInit_BigDecimal()\n{\n    /* This is a #if-ed out function to fool Rdoc into documenting the class. */\n    /* The real init function is Init_bigdecimal() further down. */\n}\n#endif\n\n/*\n * Returns the BigDecimal version number.\n *\n * Ruby 1.8.0 returns 1.0.0.\n * Ruby 1.8.1 thru 1.8.3 return 1.0.1.\n */\nstatic VALUE\nBigDecimal_version(VALUE self)\n{\n    /*\n     * 1.0.0: Ruby 1.8.0\n     * 1.0.1: Ruby 1.8.1\n    */\n    return rb_str_new2(\"1.0.1\");\n}\n\n/*\n *   VP routines used in BigDecimal part \n */\nstatic unsigned short VpGetException(void);\nstatic void  VpSetException(unsigned short f);\nstatic void  VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v);\nstatic int   VpLimitRound(Real *c,U_LONG ixDigit);\n\n/*\n *  **** BigDecimal part ****\n */\n\nstatic void\nBigDecimal_delete(Real *pv)\n{\n    VpFree(pv);\n}\n\nstatic VALUE\nToValue(Real *p)\n{\n    if(VpIsNaN(p)) {\n        VpException(VP_EXCEPTION_NaN,\"Computation results to 'NaN'(Not a Number)\",0);\n    } else if(VpIsPosInf(p)) {\n        VpException(VP_EXCEPTION_INFINITY,\"Computation results to 'Infinity'\",0);\n    } else if(VpIsNegInf(p)) {\n        VpException(VP_EXCEPTION_INFINITY,\"Computation results to '-Infinity'\",0);\n    }\n    return p->obj;\n}\n\nstatic Real *\nGetVpValue(VALUE v, int must)\n{\n    Real *pv;\n    VALUE bg;\n    char szD[128];\n\n    switch(TYPE(v))\n    {\n    case T_DATA:\n        if(RDATA(v)->dfree ==(void *) BigDecimal_delete) {\n            Data_Get_Struct(v, Real, pv);\n            return pv;\n        } else {\n            goto SomeOneMayDoIt;\n        }\n        break;\n    case T_FIXNUM:\n        sprintf(szD, \"%ld\", FIX2LONG(v));\n        return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);\n\n#ifdef ENABLE_NUMERIC_STRING\n    case T_STRING:\n        SafeStringValue(v);\n        return VpCreateRbObject(strlen(RSTRING_PTR(v)) + VpBaseFig() + 1,\n                                RSTRING_PTR(v));\n#endif /* ENABLE_NUMERIC_STRING */\n\n    case T_BIGNUM:\n        bg = rb_big2str(v, 10);\n        return VpCreateRbObject(strlen(RSTRING_PTR(bg)) + VpBaseFig() + 1,\n                                RSTRING_PTR(bg));\n    default:\n        goto SomeOneMayDoIt;\n    }\n\nSomeOneMayDoIt:\n    if(must) {\n        rb_raise(rb_eTypeError, \"%s can't be coerced into BigDecimal\",\n                    rb_special_const_p(v)?\n                    RSTRING_PTR(rb_inspect(v)):\n                    rb_obj_classname(v)\n                );\n    }\n    return NULL; /* NULL means to coerce */\n}\n\n/* call-seq:\n * BigDecimal.double_fig\n *\n * The BigDecimal.double_fig class method returns the number of digits a\n * Float number is allowed to have. The result depends upon the CPU and OS\n * in use.\n */\nstatic VALUE\nBigDecimal_double_fig(VALUE self)\n{\n    return INT2FIX(VpDblFig());\n}\n\n/* call-seq:\n * precs\n *\n * Returns an Array of two Integer values.\n *\n * The first value is the current number of significant digits in the \n * BigDecimal. The second value is the maximum number of significant digits\n * for the BigDecimal.\n */\nstatic VALUE\nBigDecimal_prec(VALUE self)\n{\n    ENTER(1);\n    Real *p;\n    VALUE obj;\n\n    GUARD_OBJ(p,GetVpValue(self,1));\n    obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()),\n\t\t       INT2NUM(p->MaxPrec*VpBaseFig()));\n    return obj;\n}\n\nstatic VALUE\nBigDecimal_hash(VALUE self)\n{\n    ENTER(1);\n    Real *p;\n    U_LONG hash,i;\n\n    GUARD_OBJ(p,GetVpValue(self,1));\n    hash = (U_LONG)p->sign;\n    /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */\n    if(hash==2) {\n        for(i = 0; i < p->Prec;i++) {\n            hash = 31 * hash + p->frac[i];\n            hash ^= p->frac[i];\n        }\n        hash += p->exponent;\n    }\n    return INT2FIX(hash);\n}\n\nstatic VALUE\nBigDecimal_dump(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real *vp;\n    char *psz;\n    VALUE dummy;\n    volatile VALUE dump;\n\n    rb_scan_args(argc, argv, \"01\", &dummy);\n    GUARD_OBJ(vp,GetVpValue(self,1));\n    dump = rb_str_new(0,VpNumOfChars(vp,\"E\")+50);\n    psz = RSTRING_PTR(dump);\n    sprintf(psz,\"%lu:\",VpMaxPrec(vp)*VpBaseFig());\n    VpToString(vp, psz+strlen(psz), 0, 0);\n    rb_str_resize(dump, strlen(psz));\n    return dump;\n}\n\n/*\n * Internal method used to provide marshalling support. See the Marshal module.\n */\nstatic VALUE\nBigDecimal_load(VALUE self, VALUE str)\n{\n    ENTER(2);\n    Real *pv;\n    unsigned char *pch;\n    unsigned char ch;\n    unsigned long m=0;\n\n    SafeStringValue(str);\n    pch = (unsigned char *)RSTRING_PTR(str);\n    /* First get max prec */\n    while((*pch)!=(unsigned char)'\\0' && (ch=*pch++)!=(unsigned char)':') {\n        if(!ISDIGIT(ch)) {\n            rb_raise(rb_eTypeError, \"load failed: invalid character in the marshaled string\");\n        }\n        m = m*10 + (unsigned long)(ch-'0');\n    }\n    if(m>VpBaseFig()) m -= VpBaseFig();\n    GUARD_OBJ(pv,VpNewRbClass(m,(char *)pch,self));\n    m /= VpBaseFig();\n    if(m && pv->MaxPrec>m) pv->MaxPrec = m+1;\n    return ToValue(pv);\n}\n\n /* call-seq:\n  * BigDecimal.mode(mode, value)\n  *\n  * Controls handling of arithmetic exceptions and rounding. If no value\n  * is supplied, the current value is returned.\n  *\n  * Six values of the mode parameter control the handling of arithmetic\n  * exceptions:\n  *\n  * BigDecimal::EXCEPTION_NaN\n  * BigDecimal::EXCEPTION_INFINITY\n  * BigDecimal::EXCEPTION_UNDERFLOW\n  * BigDecimal::EXCEPTION_OVERFLOW\n  * BigDecimal::EXCEPTION_ZERODIVIDE\n  * BigDecimal::EXCEPTION_ALL\n  *\n  * For each mode parameter above, if the value set is false, computation \n  * continues after an arithmetic exception of the appropriate type. \n  * When computation continues, results are as follows:\n  *\n  * EXCEPTION_NaN:: NaN\n  * EXCEPTION_INFINITY:: +infinity or -infinity\n  * EXCEPTION_UNDERFLOW:: 0\n  * EXCEPTION_OVERFLOW:: +infinity or -infinity\n  * EXCEPTION_ZERODIVIDE:: +infinity or -infinity\n  *\n  * One value of the mode parameter controls the rounding of numeric values:\n  * BigDecimal::ROUND_MODE. The values it can take are:\n  *\n  * ROUND_UP:: round away from zero\n  * ROUND_DOWN:: round towards zero (truncate)\n  * ROUND_HALF_UP:: round up if the appropriate digit >= 5, otherwise truncate (default)\n  * ROUND_HALF_DOWN:: round up if the appropriate digit >= 6, otherwise truncate\n  * ROUND_HALF_EVEN:: round towards the even neighbor (Banker's rounding)\n  * ROUND_CEILING:: round towards positive infinity (ceil)\n  * ROUND_FLOOR:: round towards negative infinity (floor)\n  *\n  */\nstatic VALUE\nBigDecimal_mode(int argc, VALUE *argv, VALUE self)\n{\n    VALUE which;\n    VALUE val;\n    unsigned long f,fo;\n \n    if(rb_scan_args(argc,argv,\"11\",&which,&val)==1) val = Qnil;\n\n    Check_Type(which, T_FIXNUM);\n    f = (unsigned long)FIX2INT(which);\n\n    if(f&VP_EXCEPTION_ALL) {\n        /* Exception mode setting */\n        fo = VpGetException();\n        if(val==Qnil) return INT2FIX(fo);\n        if(val!=Qfalse && val!=Qtrue) {\n            rb_raise(rb_eTypeError, \"second argument must be true or false\");\n            return Qnil; /* Not reached */\n        }\n        if(f&VP_EXCEPTION_INFINITY) {\n            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):\n                           (fo&(~VP_EXCEPTION_INFINITY))));\n        }\n        if(f&VP_EXCEPTION_NaN) {\n            VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):\n                           (fo&(~VP_EXCEPTION_NaN))));\n        }\n        fo = VpGetException();\n        return INT2FIX(fo);\n    }\n    if(VP_ROUND_MODE==f) {\n        /* Rounding mode setting */\n        fo = VpGetRoundMode();\n        if(val==Qnil) return INT2FIX(fo);\n        Check_Type(val, T_FIXNUM);\n        if(!VpIsRoundMode(FIX2INT(val))) {\n            rb_raise(rb_eTypeError, \"invalid rounding mode\");\n            return Qnil;\n        }\n        fo = VpSetRoundMode((unsigned long)FIX2INT(val));\n        return INT2FIX(fo);\n    }\n    rb_raise(rb_eTypeError, \"first argument for BigDecimal#mode invalid\");\n    return Qnil;\n}\n\nstatic U_LONG\nGetAddSubPrec(Real *a, Real *b)\n{\n    U_LONG mxs;\n    U_LONG mx = a->Prec;\n    S_INT d;\n\n    if(!VpIsDef(a) || !VpIsDef(b)) return (-1L);\n    if(mx < b->Prec) mx = b->Prec;\n    if(a->exponent!=b->exponent) {\n        mxs = mx;\n        d = a->exponent - b->exponent;\n        if(d<0) d = -d;\n        mx = mx+(U_LONG)d;\n        if(mx<mxs) {\n            return VpException(VP_EXCEPTION_INFINITY,\"Exponent overflow\",0);\n        }\n    }\n    return mx;\n}\n\nstatic S_INT\nGetPositiveInt(VALUE v)\n{\n    S_INT n;\n    Check_Type(v, T_FIXNUM);\n    n = FIX2INT(v);\n    if(n < 0) {\n        rb_raise(rb_eArgError, \"argument must be positive\");\n    }\n    return n;\n}\n\nVP_EXPORT Real *\nVpNewRbClass(U_LONG mx, char *str, VALUE klass)\n{\n    Real *pv = VpAlloc(mx,str);\n    pv->obj = (VALUE)Data_Wrap_Struct(klass, 0, BigDecimal_delete, pv);\n    return pv;\n}\n\nVP_EXPORT Real *\nVpCreateRbObject(U_LONG mx, const char *str)\n{\n    Real *pv = VpAlloc(mx,str);\n    pv->obj = (VALUE)Data_Wrap_Struct(rb_cBigDecimal, 0, BigDecimal_delete, pv);\n    return pv;\n}\n\n/* Returns True if the value is Not a Number */\nstatic VALUE\nBigDecimal_IsNaN(VALUE self)\n{\n    Real *p = GetVpValue(self,1);\n    if(VpIsNaN(p))  return Qtrue;\n    return Qfalse;\n}\n\n/* Returns True if the value is infinite */\nstatic VALUE\nBigDecimal_IsInfinite(VALUE self)\n{\n    Real *p = GetVpValue(self,1);\n    if(VpIsPosInf(p)) return INT2FIX(1);\n    if(VpIsNegInf(p)) return INT2FIX(-1);\n    return Qnil;\n}\n\n/* Returns True if the value is finite (not NaN or infinite) */\nstatic VALUE\nBigDecimal_IsFinite(VALUE self)\n{\n    Real *p = GetVpValue(self,1);\n    if(VpIsNaN(p)) return Qfalse;\n    if(VpIsInf(p)) return Qfalse;\n    return Qtrue;\n}\n\n/* Returns the value as an integer (Fixnum or Bignum).\n *\n * If the BigNumber is infinity or NaN, returns nil.\n */\nstatic VALUE\nBigDecimal_to_i(VALUE self)\n{\n    ENTER(5);\n    int e,n,i,nf;\n    U_LONG v,b,j;\n    volatile VALUE str;\n    char *psz,*pch;\n    Real *p;\n\n    GUARD_OBJ(p,GetVpValue(self,1));\n\n    /* Infinity or NaN not converted. */\n    if(VpIsNaN(p)) {\n       VpException(VP_EXCEPTION_NaN,\"Computation results to 'NaN'(Not a Number)\",0);\n       return Qnil;\n    } else if(VpIsPosInf(p)) {\n       VpException(VP_EXCEPTION_INFINITY,\"Computation results to 'Infinity'\",0);\n       return Qnil;\n    } else if(VpIsNegInf(p)) {\n       VpException(VP_EXCEPTION_INFINITY,\"Computation results to '-Infinity'\",0);\n       return Qnil;\n    }\n\n    e = VpExponent10(p);\n    if(e<=0) return INT2FIX(0);\n    nf = VpBaseFig();\n    if(e<=nf) {\n        e = VpGetSign(p)*p->frac[0];\n        return INT2FIX(e);\n    }\n    str = rb_str_new(0, e+nf+2);\n    psz = RSTRING_PTR(str);\n\n    n = (e+nf-1)/nf;\n    pch = psz;\n    if(VpGetSign(p)<0) *pch++ = '-';\n    for(i=0;i<n;++i) {\n        b = VpBaseVal()/10;\n        if(i>=(int)p->Prec) {\n            while(b) {\n                *pch++ = '0';\n                b /= 10;\n            }\n            continue;\n        }\n        v = p->frac[i];\n        while(b) {\n            j = v/b;\n            *pch++ = (char)(j + '0');\n            v -= j*b;\n            b /= 10;\n        }\n    }\n    *pch++ = 0;\n    return rb_cstr2inum(psz,10);\n}\n\nstatic VALUE\nBigDecimal_induced_from(VALUE self, VALUE x)\n{\n    Real *p = GetVpValue(x,1);\n    return p->obj;\n}\n\n/* Returns a new Float object having approximately the same value as the\n * BigDecimal number. Normal accuracy limits and built-in errors of binary\n * Float arithmetic apply.\n */\nstatic VALUE\nBigDecimal_to_f(VALUE self)\n{\n    ENTER(1);\n    Real *p;\n    double d;\n    S_LONG e;\n    char *buf;\n    volatile VALUE str;\n\n    GUARD_OBJ(p,GetVpValue(self,1));\n    if(VpVtoD(&d, &e, p)!=1) return rb_float_new(d);\n    if (e > DBL_MAX_10_EXP) goto erange;\n    str = rb_str_new(0, VpNumOfChars(p,\"E\"));\n    buf = RSTRING_PTR(str);\n    VpToString(p, buf, 0, 0);\n    errno = 0;\n    d = strtod(buf, 0);\n    if(errno == ERANGE) {\n      erange:\n       VpException(VP_EXCEPTION_OVERFLOW,\"BigDecimal to Float conversion\",0);\n       if(d>0.0) d = VpGetDoublePosInf();\n       else      d = VpGetDoubleNegInf();\n    }\n    return rb_float_new(d);\n}\n\n/* The coerce method provides support for Ruby type coercion. It is not\n * enabled by default.\n * \n * This means that binary operations like + * / or - can often be performed \n * on a BigDecimal and an object of another type, if the other object can\n * be coerced into a BigDecimal value.\n *\n * e.g.\n * a = BigDecimal.new(\"1.0\")\n * b = a / 2.0  -> 0.5\n *\n * Note that coercing a String to a BigDecimal is not supported by default;\n * it requires a special compile-time option when building Ruby.\n */\nstatic VALUE\nBigDecimal_coerce(VALUE self, VALUE other)\n{\n    ENTER(2);\n    VALUE obj;\n    Real *b;\n    if(TYPE(other) == T_FLOAT) {\n       obj = rb_assoc_new(other, BigDecimal_to_f(self));\n    } else {\n       GUARD_OBJ(b,GetVpValue(other,1));\n       obj = rb_assoc_new(b->obj, self);\n    }\n    return obj;\n}\n\nstatic VALUE\nBigDecimal_uplus(VALUE self)\n{\n    return self;\n}\n\n /* call-seq:\n  * add(value, digits)\n  *\n  * Add the specified value. \n  *\n  * e.g.\n  *   c = a.add(b,n)\n  *   c = a + b\n  *\n  * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.\n  */\nstatic VALUE\nBigDecimal_add(VALUE self, VALUE r)\n{\n    ENTER(5);\n    Real *c, *a, *b;\n    U_LONG mx;\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) return DoSomeOne(self,r);\n    SAVE(b);\n    if(VpIsNaN(b)) return b->obj;\n    if(VpIsNaN(a)) return a->obj;\n    mx = GetAddSubPrec(a,b);\n    if(mx==(-1L)) {\n        GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, \"0\"));\n        VpAddSub(c, a, b, 1);\n    } else {\n        GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), \"0\"));\n        if(!mx) {\n            VpSetInf(c,VpGetSign(a));\n        } else {\n            VpAddSub(c, a, b, 1);\n        }\n    }\n    return ToValue(c);\n}\n\n /* call-seq:\n  * sub(value, digits)\n  *\n  * Subtract the specified value. \n  *\n  * e.g.\n  *   c = a.sub(b,n)\n  *   c = a - b\n  *\n  * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.\n  */\nstatic VALUE\nBigDecimal_sub(VALUE self, VALUE r)\n{\n    ENTER(5);\n    Real *c, *a, *b;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) return DoSomeOne(self,r);\n    SAVE(b);\n\n    if(VpIsNaN(b)) return b->obj;\n    if(VpIsNaN(a)) return a->obj;\n\n    mx = GetAddSubPrec(a,b);\n    if(mx==(-1L)) {\n        GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, \"0\"));\n        VpAddSub(c, a, b, -1);\n    } else {\n        GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), \"0\"));\n        if(!mx) {\n            VpSetInf(c,VpGetSign(a));\n        } else {\n            VpAddSub(c, a, b, -1);\n        }\n    }\n    return ToValue(c);\n}\n\nstatic VALUE\nBigDecimalCmp(VALUE self, VALUE r,char op)\n{\n    ENTER(5);\n    S_INT e;\n    Real *a, *b;\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) {\n\tswitch(op)\n\t{\n\tcase '*': return rb_num_coerce_cmp(self,r); /* any op */\n\tcase '=': return RTEST(rb_num_coerce_cmp(self,r)) ? Qtrue : Qfalse;\n\tdefault: return rb_num_coerce_relop(self,r);\n\t}\n    }\n    SAVE(b);\n    e = VpComp(a, b);\n    if(e==999) return (op == '*') ? Qnil : Qfalse;\n    switch(op)\n    {\n    case '*': return   INT2FIX(e); /* any op */\n    case '=': if(e==0) return Qtrue ; return Qfalse;\n    case 'G': if(e>=0) return Qtrue ; return Qfalse;\n    case '>': if(e> 0) return Qtrue ; return Qfalse;\n    case 'L': if(e<=0) return Qtrue ; return Qfalse;\n    case '<': if(e< 0) return Qtrue ; return Qfalse;\n    }\n    rb_bug(\"Undefined operation in BigDecimalCmp()\");\n}\n\n/* Returns True if the value is zero. */\nstatic VALUE\nBigDecimal_zero(VALUE self)\n{\n    Real *a = GetVpValue(self,1);\n    return VpIsZero(a) ? Qtrue : Qfalse;\n}\n\n/* Returns True if the value is non-zero. */\nstatic VALUE\nBigDecimal_nonzero(VALUE self)\n{\n    Real *a = GetVpValue(self,1);\n    return VpIsZero(a) ? Qnil : self;\n}\n\n/* The comparison operator.\n * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b.\n */\nstatic VALUE\nBigDecimal_comp(VALUE self, VALUE r)\n{\n    return BigDecimalCmp(self, r, '*');\n}\n\n/*\n * Tests for value equality; returns true if the values are equal.\n *\n * The == and === operators and the eql? method have the same implementation \n * for BigDecimal.\n *\n * Values may be coerced to perform the comparison:\n *\n * BigDecimal.new('1.0') == 1.0  -> true\n */\nstatic VALUE\nBigDecimal_eq(VALUE self, VALUE r)\n{\n    return BigDecimalCmp(self, r, '=');\n}\n\n/* call-seq:\n * a < b\n *\n * Returns true if a is less than b. Values may be coerced to perform the\n * comparison (see ==, coerce).\n */\nstatic VALUE\nBigDecimal_lt(VALUE self, VALUE r)\n{\n    return BigDecimalCmp(self, r, '<');\n}\n\n/* call-seq:\n * a <= b\n *\n * Returns true if a is less than or equal to b. Values may be coerced to \n * perform the comparison (see ==, coerce).\n */\nstatic VALUE\nBigDecimal_le(VALUE self, VALUE r)\n{\n    return BigDecimalCmp(self, r, 'L');\n}\n\n/* call-seq:\n * a > b\n *\n * Returns true if a is greater than b.  Values may be coerced to \n * perform the comparison (see ==, coerce).\n */\nstatic VALUE\nBigDecimal_gt(VALUE self, VALUE r)\n{\n    return BigDecimalCmp(self, r, '>');\n}\n\n/* call-seq:\n * a >= b\n *\n * Returns true if a is greater than or equal to b. Values may be coerced to \n * perform the comparison (see ==, coerce)\n */\nstatic VALUE\nBigDecimal_ge(VALUE self, VALUE r)\n{\n    return BigDecimalCmp(self, r, 'G');\n}\n\nstatic VALUE\nBigDecimal_neg(VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    GUARD_OBJ(a,GetVpValue(self,1));\n    GUARD_OBJ(c,VpCreateRbObject(a->Prec *(VpBaseFig() + 1), \"0\"));\n    VpAsgn(c, a, -1);\n    return ToValue(c);\n}\n\n /* call-seq:\n  * mult(value, digits)\n  *\n  * Multiply by the specified value. \n  *\n  * e.g.\n  *   c = a.mult(b,n)\n  *   c = a * b\n  *\n  * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.\n  */\nstatic VALUE\nBigDecimal_mult(VALUE self, VALUE r)\n{\n    ENTER(5);\n    Real *c, *a, *b;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) return DoSomeOne(self,r);\n    SAVE(b);\n\n    mx = a->Prec + b->Prec;\n    GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), \"0\"));\n    VpMult(c, a, b);\n    return ToValue(c);\n}\n\nstatic VALUE\nBigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)\n/* For c = self.div(r): with round operation */\n{\n    ENTER(5);\n    Real *a, *b;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) return DoSomeOne(self,r);\n    SAVE(b);\n    *div = b;\n    mx =(a->MaxPrec + b->MaxPrec + 1) * VpBaseFig();\n    GUARD_OBJ((*c),VpCreateRbObject(mx, \"#0\"));\n    GUARD_OBJ((*res),VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), \"#0\"));\n    VpDivd(*c, *res, a, b);\n    return (VALUE)0;\n}\n\n /* call-seq:\n  * div(value, digits)\n  * quo(value)\n  *\n  * Divide by the specified value. \n  *\n  * e.g.\n  *   c = a.div(b,n)\n  *\n  * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.\n  * \n  * If digits is 0, the result is the same as the / operator. If not, the\n  * result is an integer BigDecimal, by analogy with Float#div.\n  *\n  * The alias quo is provided since div(value, 0) is the same as computing\n  * the quotient; see divmod.\n  */\nstatic VALUE\nBigDecimal_div(VALUE self, VALUE r)\n/* For c = self/r: with round operation */\n{\n    ENTER(5);\n    Real *c=NULL, *res=NULL, *div = NULL;\n    r = BigDecimal_divide(&c, &res, &div, self, r);\n    if(r!=(VALUE)0) return r; /* coerced by other */\n    SAVE(c);SAVE(res);SAVE(div);\n    /* a/b = c + r/b */\n    /* c xxxxx\n       r 00000yyyyy  ==> (y/b)*BASE >= HALF_BASE\n     */\n    /* Round */\n    if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */\n       VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);\n    }\n    return ToValue(c);\n}\n\n/*\n * %: mod = a%b = a - (a.to_f/b).floor * b\n * div = (a.to_f/b).floor\n */\nstatic VALUE\nBigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)\n{\n    ENTER(8);\n    Real *c=NULL, *d=NULL, *res=NULL;\n    Real *a, *b;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) return DoSomeOne(self,r);\n    SAVE(b);\n\n    if(VpIsNaN(a) || VpIsNaN(b)) goto NaN;\n    if(VpIsInf(a) || VpIsInf(b)) goto NaN;\n    if(VpIsZero(b))              goto NaN;\n    if(VpIsZero(a)) {\n       GUARD_OBJ(c,VpCreateRbObject(1, \"0\"));\n       GUARD_OBJ(d,VpCreateRbObject(1, \"0\"));\n       *div = d;\n       *mod = c;\n       return (VALUE)0;\n    }\n\n    mx = a->Prec;\n    if(mx<b->Prec) mx = b->Prec;\n    mx =(mx + 1) * VpBaseFig();\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    GUARD_OBJ(res,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), \"#0\"));\n    VpDivd(c, res, a, b);\n    mx = c->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(d,VpCreateRbObject(mx, \"0\"));\n    VpActiveRound(d,c,VP_ROUND_DOWN,0);\n    VpMult(res,d,b);\n    VpAddSub(c,a,res,-1);\n    if(!VpIsZero(c) && (VpGetSign(a)*VpGetSign(b)<0)) {\n        VpAddSub(res,d,VpOne(),-1);\n        VpAddSub(d  ,c,b,       1);\n        *div = res;\n        *mod = d;\n    } else {\n        *div = d;\n        *mod = c;\n    }\n    return (VALUE)0;\n\nNaN:\n    GUARD_OBJ(c,VpCreateRbObject(1, \"NaN\"));\n    GUARD_OBJ(d,VpCreateRbObject(1, \"NaN\"));\n    *div = d;\n    *mod = c;\n    return (VALUE)0;\n}\n\n/* call-seq:\n * a % b\n * a.modulo(b)\n *\n * Returns the modulus from dividing by b. See divmod.\n */\nstatic VALUE\nBigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */\n{\n    ENTER(3);\n    VALUE obj;\n    Real *div=NULL, *mod=NULL;\n\n    obj = BigDecimal_DoDivmod(self,r,&div,&mod);\n    if(obj!=(VALUE)0) return obj;\n    SAVE(div);SAVE(mod);\n    return ToValue(mod);\n}\n\nstatic VALUE\nBigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)\n{\n    ENTER(10);\n    U_LONG mx;\n    Real *a=NULL, *b=NULL, *c=NULL, *res=NULL, *d=NULL, *rr=NULL, *ff=NULL;\n    Real *f=NULL;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    b = GetVpValue(r,0);\n    if(!b) return DoSomeOne(self,r);\n    SAVE(b);\n\n    mx  =(a->MaxPrec + b->MaxPrec) *VpBaseFig();\n    GUARD_OBJ(c  ,VpCreateRbObject(mx, \"0\"));\n    GUARD_OBJ(res,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), \"#0\"));\n    GUARD_OBJ(rr ,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), \"#0\"));\n    GUARD_OBJ(ff ,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), \"#0\"));\n\n    VpDivd(c, res, a, b);\n\n    mx = c->Prec *(VpBaseFig() + 1);\n\n    GUARD_OBJ(d,VpCreateRbObject(mx, \"0\"));\n    GUARD_OBJ(f,VpCreateRbObject(mx, \"0\"));\n\n    VpActiveRound(d,c,VP_ROUND_DOWN,0); /* 0: round off */\n\n    VpFrac(f, c);\n    VpMult(rr,f,b);\n    VpAddSub(ff,res,rr,1);\n\n    *dv = d;\n    *rv = ff;\n    return (VALUE)0;\n}\n\n/* Returns the remainder from dividing by the value.\n *\n * If the values divided are of the same sign, the remainder is the same as\n * the modulus (see divmod).\n *\n * Otherwise, the remainder is the modulus minus the value divided by.\n */\nstatic VALUE\nBigDecimal_remainder(VALUE self, VALUE r) /* remainder */\n{\n    VALUE  f;\n    Real  *d,*rv=0;\n    f = BigDecimal_divremain(self,r,&d,&rv);\n    if(f!=(VALUE)0) return f;\n    return ToValue(rv);\n}\n\n/* Divides by the specified value, and returns the quotient and modulus\n * as BigDecimal numbers. The quotient is rounded towards negative infinity.\n *\n * For example:\n *\n * require 'bigdecimal'\n *\n * a = BigDecimal.new(\"42\")\n * b = BigDecimal.new(\"9\")\n *\n * q,m = a.divmod(b)\n *\n * c = q * b + m\n *\n * a == c  -> true\n *\n * The quotient q is (a/b).floor, and the modulus is the amount that must be \n * added to q * b to get a.\n */\nstatic VALUE\nBigDecimal_divmod(VALUE self, VALUE r)\n{\n    ENTER(5);\n    VALUE obj;\n    Real *div=NULL, *mod=NULL;\n\n    obj = BigDecimal_DoDivmod(self,r,&div,&mod);\n    if(obj!=(VALUE)0) return obj;\n    SAVE(div);SAVE(mod);\n    obj = rb_assoc_new(ToValue(div), ToValue(mod));\n    return obj;\n}\n\nstatic VALUE\nBigDecimal_div2(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    VALUE b,n;\n    int na = rb_scan_args(argc,argv,\"11\",&b,&n);\n    if(na==1) { /* div in Float sense */\n       VALUE obj;\n       Real *div=NULL;\n       Real *mod;\n       obj = BigDecimal_DoDivmod(self,b,&div,&mod);\n       if(obj!=(VALUE)0) return obj;\n       return ToValue(div);\n    } else {    /* div in BigDecimal sense */\n       U_LONG ix = (U_LONG)GetPositiveInt(n);\n       if(ix==0) return BigDecimal_div(self,b);\n       else {\n          Real *res=NULL;\n          Real *av=NULL, *bv=NULL, *cv=NULL;\n          U_LONG mx = (ix+VpBaseFig()*2);\n          U_LONG pl = VpSetPrecLimit(0);\n\n          GUARD_OBJ(cv,VpCreateRbObject(mx,\"0\"));\n          GUARD_OBJ(av,GetVpValue(self,1));\n          GUARD_OBJ(bv,GetVpValue(b,1));\n          mx = av->Prec + bv->Prec + 2;\n          if(mx <= cv->MaxPrec) mx = cv->MaxPrec+1;\n          GUARD_OBJ(res,VpCreateRbObject((mx * 2  + 2)*VpBaseFig(), \"#0\"));\n          VpDivd(cv,res,av,bv);\n          VpSetPrecLimit(pl);\n          VpLeftRound(cv,VpGetRoundMode(),ix);\n          return ToValue(cv);\n       }\n    }\n}\n\nstatic VALUE\nBigDecimal_add2(VALUE self, VALUE b, VALUE n)\n{\n    ENTER(2);\n    Real   *cv;\n    U_LONG mx = (U_LONG)GetPositiveInt(n);\n    if(mx==0) return BigDecimal_add(self,b);\n    else {\n       U_LONG pl = VpSetPrecLimit(0);\n       VALUE   c = BigDecimal_add(self,b);\n       VpSetPrecLimit(pl);\n       GUARD_OBJ(cv,GetVpValue(c,1));\n       VpLeftRound(cv,VpGetRoundMode(),mx);\n       return ToValue(cv);\n    }\n}\n\nstatic VALUE\nBigDecimal_sub2(VALUE self, VALUE b, VALUE n)\n{\n    ENTER(2);\n    Real *cv;\n    U_LONG mx = (U_LONG)GetPositiveInt(n);\n    if(mx==0) return BigDecimal_sub(self,b);\n    else {\n       U_LONG pl = VpSetPrecLimit(0);\n       VALUE   c = BigDecimal_sub(self,b);\n       VpSetPrecLimit(pl);\n       GUARD_OBJ(cv,GetVpValue(c,1));\n       VpLeftRound(cv,VpGetRoundMode(),mx);\n       return ToValue(cv);\n    }\n}\n\nstatic VALUE\nBigDecimal_mult2(VALUE self, VALUE b, VALUE n)\n{\n    ENTER(2);\n    Real *cv;\n    U_LONG mx = (U_LONG)GetPositiveInt(n);\n    if(mx==0) return BigDecimal_mult(self,b);\n    else {\n       U_LONG pl = VpSetPrecLimit(0);\n       VALUE   c = BigDecimal_mult(self,b);\n       VpSetPrecLimit(pl);\n       GUARD_OBJ(cv,GetVpValue(c,1));\n       VpLeftRound(cv,VpGetRoundMode(),mx);\n       return ToValue(cv);\n    }\n}\n\n/* Returns the absolute value.\n *\n * BigDecimal('5').abs -> 5\n *\n * BigDecimal('-3').abs -> 3\n */\nstatic VALUE\nBigDecimal_abs(VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpAsgn(c, a, 1);\n    VpChangeSign(c,(S_INT)1);\n    return ToValue(c);\n}\n\n/* call-seq:\n * sqrt(n)\n *\n * Returns the square root of the value.\n *\n * If n is specified, returns at least that many significant digits.\n */\nstatic VALUE\nBigDecimal_sqrt(VALUE self, VALUE nFig)\n{\n    ENTER(5);\n    Real *c, *a;\n    S_INT mx, n;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n\n    n = GetPositiveInt(nFig) + VpDblFig() + 1;\n    if(mx <= n) mx = n;\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpSqrt(c, a);\n    return ToValue(c);\n}\n\n/* Return the integer part of the number.\n */\nstatic VALUE\nBigDecimal_fix(VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpActiveRound(c,a,VP_ROUND_DOWN,0); /* 0: round off */\n    return ToValue(c);\n}\n\n/* call-seq:\n * round(n,mode)\n *\n * Round to the nearest 1 (by default), returning the result as a BigDecimal.\n *\n * BigDecimal('3.14159').round -> 3\n *\n * BigDecimal('8.7').round -> 9\n *\n * If n is specified and positive, the fractional part of the result has no\n * more than that many digits. \n *\n * If n is specified and negative, at least that many digits to the left of the\n * decimal point will be 0 in the result.\n *\n * BigDecimal('3.14159').round(3) -> 3.142\n *\n * BigDecimal('13345.234').round(-2) -> 13300.0\n *\n * The value of the optional mode argument can be used to determine how \n * rounding is performed; see BigDecimal.mode.\n */\nstatic VALUE\nBigDecimal_round(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real   *c, *a;\n    int    iLoc = 0;\n    U_LONG mx;\n    VALUE  vLoc;\n    VALUE  vRound;\n    U_LONG pl;\n\n    int    sw = VpGetRoundMode();\n\n    int na = rb_scan_args(argc,argv,\"02\",&vLoc,&vRound);\n    switch(na) {\n    case 0:\n        iLoc = 0;\n        break;\n    case 1:\n        Check_Type(vLoc, T_FIXNUM);\n        iLoc = FIX2INT(vLoc);\n        break;\n    case 2:\n        Check_Type(vLoc, T_FIXNUM);\n        iLoc = FIX2INT(vLoc);\n        Check_Type(vRound, T_FIXNUM);\n        sw   = FIX2INT(vRound);\n        if(!VpIsRoundMode(sw)) {\n            rb_raise(rb_eTypeError, \"invalid rounding mode\");\n            return Qnil;\n        }\n        break;\n    }\n\n    pl = VpSetPrecLimit(0);\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpSetPrecLimit(pl);\n    VpActiveRound(c,a,sw,iLoc);\n    return ToValue(c);\n}\n\n/* call-seq:\n * truncate(n)\n *\n * Truncate to the nearest 1, returning the result as a BigDecimal.\n *\n * BigDecimal('3.14159').truncate -> 3\n *\n * BigDecimal('8.7').truncate -> 8\n *\n * If n is specified and positive, the fractional part of the result has no\n * more than that many digits. \n *\n * If n is specified and negative, at least that many digits to the left of the\n * decimal point will be 0 in the result.\n *\n * BigDecimal('3.14159').truncate(3) -> 3.141\n *\n * BigDecimal('13345.234').truncate(-2) -> 13300.0\n */\nstatic VALUE\nBigDecimal_truncate(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    int iLoc;\n    U_LONG mx;\n    VALUE vLoc;\n    U_LONG pl = VpSetPrecLimit(0);\n\n    if(rb_scan_args(argc,argv,\"01\",&vLoc)==0) {\n        iLoc = 0;\n    } else {\n        Check_Type(vLoc, T_FIXNUM);\n        iLoc = FIX2INT(vLoc);\n    }\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpSetPrecLimit(pl);\n    VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */\n    return ToValue(c);\n}\n\n/* Return the fractional part of the number.\n */\nstatic VALUE\nBigDecimal_frac(VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    U_LONG mx;\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpFrac(c, a);\n    return ToValue(c);\n}\n\n/* call-seq:\n * floor(n)\n *\n * Return the largest integer less than or equal to the value, as a BigDecimal.\n *\n * BigDecimal('3.14159').floor -> 3\n *\n * BigDecimal('-9.1').floor -> -10\n *\n * If n is specified and positive, the fractional part of the result has no\n * more than that many digits.  \n *\n * If n is specified and negative, at least that\n * many digits to the left of the decimal point will be 0 in the result.\n *\n * BigDecimal('3.14159').floor(3) -> 3.141\n *\n * BigDecimal('13345.234').floor(-2) -> 13300.0\n */\nstatic VALUE\nBigDecimal_floor(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    U_LONG mx;\n    int iLoc;\n    VALUE vLoc;\n    U_LONG pl = VpSetPrecLimit(0);\n\n    if(rb_scan_args(argc,argv,\"01\",&vLoc)==0) {\n        iLoc = 0;\n    } else {\n        Check_Type(vLoc, T_FIXNUM);\n        iLoc = FIX2INT(vLoc);\n    }\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpSetPrecLimit(pl);\n    VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);\n    return ToValue(c);\n}\n\n/* call-seq:\n * ceil(n)\n *\n * Return the smallest integer greater than or equal to the value, as a BigDecimal.\n *\n * BigDecimal('3.14159').ceil -> 4\n *\n * BigDecimal('-9.1').ceil -> -9\n *\n * If n is specified and positive, the fractional part of the result has no\n * more than that many digits.  \n *\n * If n is specified and negative, at least that\n * many digits to the left of the decimal point will be 0 in the result.\n *\n * BigDecimal('3.14159').ceil(3) -> 3.142\n *\n * BigDecimal('13345.234').ceil(-2) -> 13400.0\n */\nstatic VALUE\nBigDecimal_ceil(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real *c, *a;\n    U_LONG mx;\n    int iLoc;\n    VALUE vLoc;\n    U_LONG pl = VpSetPrecLimit(0);\n\n    if(rb_scan_args(argc,argv,\"01\",&vLoc)==0) {\n        iLoc = 0;\n    } else {\n        Check_Type(vLoc, T_FIXNUM);\n        iLoc = FIX2INT(vLoc);\n    }\n\n    GUARD_OBJ(a,GetVpValue(self,1));\n    mx = a->Prec *(VpBaseFig() + 1);\n    GUARD_OBJ(c,VpCreateRbObject(mx, \"0\"));\n    VpSetPrecLimit(pl);\n    VpActiveRound(c,a,VP_ROUND_CEIL,iLoc);\n    return ToValue(c);\n}\n\n/* call-seq:\n * to_s(s)\n *\n * Converts the value to a string.\n *\n * The default format looks like  0.xxxxEnn.\n *\n * The optional parameter s consists of either an integer; or an optional '+'\n * or ' ', followed by an optional number, followed by an optional 'E' or 'F'.\n *\n * If there is a '+' at the start of s, positive values are returned with\n * a leading '+'.\n *\n * A space at the start of s returns positive values with a leading space.\n *\n * If s contains a number, a space is inserted after each group of that many \n * fractional digits.\n *\n * If s ends with an 'E', engineering notation (0.xxxxEnn) is used.\n *\n * If s ends with an 'F', conventional floating point notation is used.\n *\n * Examples:\n *\n * BigDecimal.new('-123.45678901234567890').to_s('5F') -> '-123.45678 90123 45678 9'\n *\n * BigDecimal.new('123.45678901234567890').to_s('+8F') -> '+123.45678901 23456789'\n *\n * BigDecimal.new('123.45678901234567890').to_s(' F') -> ' 123.4567890123456789'\n */\nstatic VALUE\nBigDecimal_to_s(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    int   fmt=0;   /* 0:E format */\n    int   fPlus=0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */\n    Real  *vp;\n    volatile VALUE str;\n    char  *psz;\n    char   ch;\n    U_LONG nc;\n    S_INT  mc = 0;\n    VALUE  f;\n\n    GUARD_OBJ(vp,GetVpValue(self,1));\n    \n    if(rb_scan_args(argc,argv,\"01\",&f)==1) {\n        if(TYPE(f)==T_STRING) {\n            SafeStringValue(f);\n            psz = RSTRING_PTR(f);\n            if(*psz==' ') {\n                fPlus = 1; psz++;\n            } else if(*psz=='+') {\n                fPlus = 2; psz++;\n            }\n            while((ch=*psz++)!=0) {\n                if(ISSPACE(ch)) continue;\n                if(!ISDIGIT(ch)) {\n                    if(ch=='F' || ch=='f') fmt = 1; /* F format */\n                    break;\n                }\n                mc = mc * 10 + ch - '0';\n            }\n        } else {\n            mc  = GetPositiveInt(f);\n        }\n    }\n    if(fmt) {\n        nc = VpNumOfChars(vp,\"F\");\n    } else {\n        nc = VpNumOfChars(vp,\"E\");\n    }\n    if(mc>0) nc += (nc + mc - 1) / mc + 1;\n\n    str = rb_str_new(0, nc);\n    psz = RSTRING_PTR(str);\n\n    if(fmt) {\n        VpToFString(vp, psz, mc, fPlus);\n    } else {\n        VpToString (vp, psz, mc, fPlus);\n    }\n    rb_str_resize(str, strlen(psz));\n    return str;\n}\n\n/* Splits a BigDecimal number into four parts, returned as an array of values.\n *\n * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0\n * if the BigDecimal is Not a Number.\n *\n * The second value is a string representing the significant digits of the\n * BigDecimal, with no leading zeros.\n *\n * The third value is the base used for arithmetic (currently always 10) as an\n * Integer.\n *\n * The fourth value is an Integer exponent.\n *\n * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the \n * string of significant digits with no leading zeros, and n is the exponent.\n *\n * From these values, you can translate a BigDecimal to a float as follows:\n *\n *   sign, significant_digits, base, exponent = a.split\n *   f = sign * \"0.#{significant_digits}\".to_f * (base ** exponent)\n *\n * (Note that the to_f method is provided as a more convenient way to translate \n * a BigDecimal to a Float.)\n */\nstatic VALUE\nBigDecimal_split(VALUE self)\n{\n    ENTER(5);\n    Real *vp;\n    VALUE obj,str;\n    S_LONG e;\n    S_LONG s;\n    char *psz1;\n\n    GUARD_OBJ(vp,GetVpValue(self,1));\n    str = rb_str_new(0, VpNumOfChars(vp,\"E\"));\n    psz1 = RSTRING_PTR(str);\n    VpSzMantissa(vp,psz1);\n    s = 1;\n    if(psz1[0]=='-') {\n\tint len = strlen(psz1+1);\n\n\tmemmove(psz1, psz1+1, len);\n\tpsz1[len] = '\\0';\n        s = -1;\n    }\n    if(psz1[0]=='N') s=0; /* NaN */\n    e = VpExponent10(vp);\n    obj  = rb_ary_new2(4);\n    rb_ary_push(obj, INT2FIX(s));\n    rb_ary_push(obj, str);\n    rb_str_resize(str, strlen(psz1));\n    rb_ary_push(obj, INT2FIX(10));\n    rb_ary_push(obj, INT2NUM(e));\n    return obj;\n}\n\n/* Returns the exponent of the BigDecimal number, as an Integer.\n *\n * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string\n * of digits with no leading zeros, then n is the exponent.\n */\nstatic VALUE\nBigDecimal_exponent(VALUE self)\n{\n    S_LONG e = VpExponent10(GetVpValue(self,1));\n    return INT2NUM(e);\n}\n\n/* Returns debugging information about the value as a string of comma-separated\n * values in angle brackets with a leading #:\n *\n * BigDecimal.new(\"1234.5678\").inspect ->\n * \"#<BigDecimal:b7ea1130,'0.12345678E4',8(12)>\"\n *\n * The first part is the address, the second is the value as a string, and\n * the final part ss(mm) is the current number of significant digits and the\n * maximum number of significant digits, respectively.\n */\nstatic VALUE\nBigDecimal_inspect(VALUE self)\n{\n    ENTER(5);\n    Real *vp;\n    volatile VALUE obj;\n    unsigned int nc;\n    char *psz, *tmp;\n\n    GUARD_OBJ(vp,GetVpValue(self,1));\n    nc = VpNumOfChars(vp,\"E\");\n    nc +=(nc + 9) / 10;\n\n    obj = rb_str_new(0, nc+256);\n    psz = RSTRING_PTR(obj);\n    sprintf(psz,\"#<BigDecimal:%lx,'\",self);\n    tmp = psz + strlen(psz);\n    VpToString(vp, tmp, 10, 0);\n    tmp += strlen(tmp);\n    sprintf(tmp,\"',%lu(%lu)>\",VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig());\n    rb_str_resize(obj, strlen(psz));\n    return obj;\n}\n\n/* call-seq:\n * power(n)\n *\n * Returns the value raised to the power of n. Note that n must be an Integer.\n *\n * Also available as the operator **\n */\nstatic VALUE\nBigDecimal_power(VALUE self, VALUE p)\n{\n    ENTER(5);\n    Real *x, *y;\n    S_LONG mp, ma, n;\n\n    Check_Type(p, T_FIXNUM);\n    n = FIX2INT(p);\n    ma = n;\n    if(ma < 0)  ma = -ma;\n    if(ma == 0) ma = 1;\n\n    GUARD_OBJ(x,GetVpValue(self,1));\n    if(VpIsDef(x)) {\n        mp = x->Prec *(VpBaseFig() + 1);\n        GUARD_OBJ(y,VpCreateRbObject(mp *(ma + 1), \"0\"));\n    } else {\n        GUARD_OBJ(y,VpCreateRbObject(1, \"0\"));\n    }\n    VpPower(y, x, n);\n    return ToValue(y);\n}\n\nstatic VALUE\nBigDecimal_global_new(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real *pv;\n    S_LONG mf;\n    VALUE  nFig;\n    VALUE  iniValue;\n\n    if(rb_scan_args(argc,argv,\"11\",&iniValue,&nFig)==1) {\n        mf = 0;\n    } else {\n        mf = GetPositiveInt(nFig);\n    }\n    SafeStringValue(iniValue);\n    GUARD_OBJ(pv,VpCreateRbObject(mf, RSTRING_PTR(iniValue)));\n    return ToValue(pv);\n}\n\n /* call-seq:\n  * new(initial, digits)\n  *\n  * Create a new BigDecimal object.\n  *\n  * initial:: The initial value, as a String. Spaces are ignored, unrecognized characters terminate the value.\n  *\n  * digits:: The number of significant digits, as a Fixnum. If omitted or 0, the number of significant digits is determined from the initial value.\n  *\n  * The actual number of significant digits used in computation is usually\n  * larger than the specified number.\n  */\nstatic VALUE\nBigDecimal_new(int argc, VALUE *argv, VALUE self)\n{\n    ENTER(5);\n    Real *pv;\n    S_LONG mf;\n    VALUE  nFig;\n    VALUE  iniValue;\n\n    if(rb_scan_args(argc,argv,\"11\",&iniValue,&nFig)==1) {\n        mf = 0;\n    } else {\n        mf = GetPositiveInt(nFig);\n    }\n    SafeStringValue(iniValue);\n    GUARD_OBJ(pv,VpNewRbClass(mf, RSTRING_PTR(iniValue),self));\n    return ToValue(pv);\n}\n\n /* call-seq:\n  * BigDecimal.limit(digits)\n  *\n  * Limit the number of significant digits in newly created BigDecimal \n  * numbers to the specified value. Rounding is performed as necessary, \n  * as specified by BigDecimal.mode.\n  *\n  * A limit of 0, the default, means no upper limit.\n  *\n  * The limit specified by this method takes priority over any limit \n  * specified to instance methods such as ceil, floor, truncate, or round.\n  */\nstatic VALUE\nBigDecimal_limit(int argc, VALUE *argv, VALUE self)\n{\n    VALUE  nFig;\n    VALUE  nCur = INT2NUM(VpGetPrecLimit());\n\n    if(rb_scan_args(argc,argv,\"01\",&nFig)==1) {\n        int nf;\n        if(nFig==Qnil) return nCur;\n        Check_Type(nFig, T_FIXNUM);\n        nf = FIX2INT(nFig);\n        if(nf<0) {\n            rb_raise(rb_eArgError, \"argument must be positive\");\n        }\n        VpSetPrecLimit(nf);\n    }\n    return nCur;\n}\n\n/* Returns the sign of the value.\n *\n * Returns a positive value if > 0, a negative value if < 0, and a \n * zero if == 0.\n *\n * The specific value returned indicates the type and sign of the BigDecimal, \n * as follows:\n *\n * BigDecimal::SIGN_NaN:: value is Not a Number\n * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0\n * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0\n * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +infinity\n * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -infinity\n * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive\n * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative\n */\nstatic VALUE\nBigDecimal_sign(VALUE self)\n{ /* sign */\n    int s = GetVpValue(self,1)->sign;\n    return INT2FIX(s);\n}\n\nvoid\nInit_bigdecimal(void)\n{\n    /* Initialize VP routines */\n    VpInit((U_LONG)0);\n\n    /* Class and method registration */\n    rb_cBigDecimal = rb_define_class(\"BigDecimal\",rb_cNumeric);\n\n    /* Global function */\n    rb_define_global_function(\"BigDecimal\", BigDecimal_global_new, -1);\n\n    /* Class methods */\n    rb_define_singleton_method(rb_cBigDecimal, \"new\", BigDecimal_new, -1);\n    rb_define_singleton_method(rb_cBigDecimal, \"mode\", BigDecimal_mode, -1);\n    rb_define_singleton_method(rb_cBigDecimal, \"limit\", BigDecimal_limit, -1);\n    rb_define_singleton_method(rb_cBigDecimal, \"double_fig\", BigDecimal_double_fig, 0);\n    rb_define_singleton_method(rb_cBigDecimal, \"induced_from\",BigDecimal_induced_from, 1);\n    rb_define_singleton_method(rb_cBigDecimal, \"_load\", BigDecimal_load, 1);\n    rb_define_singleton_method(rb_cBigDecimal, \"ver\", BigDecimal_version, 0);\n\n    /* Constants definition */\n\n    /* \n     * Base value used in internal calculations.  On a 32 bit system, BASE \n     * is 10000, indicating that calculation is done in groups of 4 digits.  \n     * (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't\n     * guarantee that two groups could always be multiplied together without \n     * overflow.) \n     */\n    rb_define_const(rb_cBigDecimal, \"BASE\", INT2FIX((S_INT)VpBaseVal()));\n\n    /* Exceptions */\n\n    /*\n     * 0xff: Determines whether overflow, underflow or zero divide result in \n     * an exception being thrown. See BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"EXCEPTION_ALL\",INT2FIX(VP_EXCEPTION_ALL));\n\n    /* \n     * 0x02: Determines what happens when the result of a computation is not a \n     * number (NaN). See BigDecimal.mode. \n     */\n    rb_define_const(rb_cBigDecimal, \"EXCEPTION_NaN\",INT2FIX(VP_EXCEPTION_NaN));\n\n    /* \n     * 0x01: Determines what happens when the result of a computation is\n     * infinity.  See BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"EXCEPTION_INFINITY\",INT2FIX(VP_EXCEPTION_INFINITY));\n\n    /* \n     * 0x04: Determines what happens when the result of a computation is an\n     * underflow (a result too small to be represented). See BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"EXCEPTION_UNDERFLOW\",INT2FIX(VP_EXCEPTION_UNDERFLOW));\n\n    /* \n     * 0x01: Determines what happens when the result of a computation is an\n     * underflow (a result too large to be represented). See BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"EXCEPTION_OVERFLOW\",INT2FIX(VP_EXCEPTION_OVERFLOW));\n\n    /* \n     * 0x01: Determines what happens when a division by zero is performed.\n     * See BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"EXCEPTION_ZERODIVIDE\",INT2FIX(VP_EXCEPTION_ZERODIVIDE));\n\n    /* \n     * 0x100: Determines what happens when a result must be rounded in order to\n     * fit in the appropriate number of significant digits. See\n     * BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"ROUND_MODE\",INT2FIX(VP_ROUND_MODE));\n\n    /* 1: Indicates that values should be rounded away from zero. See\n     * BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"ROUND_UP\",INT2FIX(VP_ROUND_UP));\n\n    /* 2: Indicates that values should be rounded towards zero. See\n     * BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"ROUND_DOWN\",INT2FIX(VP_ROUND_DOWN));\n\n    /* 3: Indicates that digits >= 5 should be rounded up, others rounded down.\n     * See BigDecimal.mode. */\n    rb_define_const(rb_cBigDecimal, \"ROUND_HALF_UP\",INT2FIX(VP_ROUND_HALF_UP));\n\n    /* 4: Indicates that digits >= 6 should be rounded up, others rounded down.\n     * See BigDecimal.mode.\n     */\n    rb_define_const(rb_cBigDecimal, \"ROUND_HALF_DOWN\",INT2FIX(VP_ROUND_HALF_DOWN));\n    /* 5: Round towards +infinity. See BigDecimal.mode. */\n    rb_define_const(rb_cBigDecimal, \"ROUND_CEILING\",INT2FIX(VP_ROUND_CEIL));\n\n    /* 6: Round towards -infinity. See BigDecimal.mode. */\n    rb_define_const(rb_cBigDecimal, \"ROUND_FLOOR\",INT2FIX(VP_ROUND_FLOOR));\n\n    /* 7: Round towards the even neighbor. See BigDecimal.mode. */\n    rb_define_const(rb_cBigDecimal, \"ROUND_HALF_EVEN\",INT2FIX(VP_ROUND_HALF_EVEN));\n\n    /* 0: Indicates that a value is not a number. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_NaN\",INT2FIX(VP_SIGN_NaN));\n\n    /* 1: Indicates that a value is +0. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_POSITIVE_ZERO\",INT2FIX(VP_SIGN_POSITIVE_ZERO));\n\n    /* -1: Indicates that a value is -0. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_NEGATIVE_ZERO\",INT2FIX(VP_SIGN_NEGATIVE_ZERO));\n\n    /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_POSITIVE_FINITE\",INT2FIX(VP_SIGN_POSITIVE_FINITE));\n\n    /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_NEGATIVE_FINITE\",INT2FIX(VP_SIGN_NEGATIVE_FINITE));\n\n    /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_POSITIVE_INFINITE\",INT2FIX(VP_SIGN_POSITIVE_INFINITE));\n\n    /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */\n    rb_define_const(rb_cBigDecimal, \"SIGN_NEGATIVE_INFINITE\",INT2FIX(VP_SIGN_NEGATIVE_INFINITE));\n\n    /* instance methods */\n    rb_define_method(rb_cBigDecimal, \"precs\", BigDecimal_prec, 0);\n\n    rb_define_method(rb_cBigDecimal, \"add\", BigDecimal_add2, 2);\n    rb_define_method(rb_cBigDecimal, \"sub\", BigDecimal_sub2, 2);\n    rb_define_method(rb_cBigDecimal, \"mult\", BigDecimal_mult2, 2);\n    rb_define_method(rb_cBigDecimal, \"div\",BigDecimal_div2, -1);\n    rb_define_method(rb_cBigDecimal, \"hash\", BigDecimal_hash, 0);\n    rb_define_method(rb_cBigDecimal, \"to_s\", BigDecimal_to_s, -1);\n    rb_define_method(rb_cBigDecimal, \"to_i\", BigDecimal_to_i, 0);\n    rb_define_method(rb_cBigDecimal, \"to_int\", BigDecimal_to_i, 0);\n    rb_define_method(rb_cBigDecimal, \"split\", BigDecimal_split, 0);\n    rb_define_method(rb_cBigDecimal, \"+\", BigDecimal_add, 1);\n    rb_define_method(rb_cBigDecimal, \"-\", BigDecimal_sub, 1);\n    rb_define_method(rb_cBigDecimal, \"+@\", BigDecimal_uplus, 0);\n    rb_define_method(rb_cBigDecimal, \"-@\", BigDecimal_neg, 0);\n    rb_define_method(rb_cBigDecimal, \"*\", BigDecimal_mult, 1);\n    rb_define_method(rb_cBigDecimal, \"/\", BigDecimal_div, 1);\n    rb_define_method(rb_cBigDecimal, \"quo\", BigDecimal_div, 1);\n    rb_define_method(rb_cBigDecimal, \"%\", BigDecimal_mod, 1);\n    rb_define_method(rb_cBigDecimal, \"modulo\", BigDecimal_mod, 1);\n    rb_define_method(rb_cBigDecimal, \"remainder\", BigDecimal_remainder, 1);\n    rb_define_method(rb_cBigDecimal, \"divmod\", BigDecimal_divmod, 1);\n    /* rb_define_method(rb_cBigDecimal, \"dup\", BigDecimal_dup, 0); */\n    rb_define_method(rb_cBigDecimal, \"to_f\", BigDecimal_to_f, 0);\n    rb_define_method(rb_cBigDecimal, \"abs\", BigDecimal_abs, 0);\n    rb_define_method(rb_cBigDecimal, \"sqrt\", BigDecimal_sqrt, 1);\n    rb_define_method(rb_cBigDecimal, \"fix\", BigDecimal_fix, 0);\n    rb_define_method(rb_cBigDecimal, \"round\", BigDecimal_round, -1);\n    rb_define_method(rb_cBigDecimal, \"frac\", BigDecimal_frac, 0);\n    rb_define_method(rb_cBigDecimal, \"floor\", BigDecimal_floor, -1);\n    rb_define_method(rb_cBigDecimal, \"ceil\", BigDecimal_ceil, -1);\n    rb_define_method(rb_cBigDecimal, \"power\", BigDecimal_power, 1);\n    rb_define_method(rb_cBigDecimal, \"**\", BigDecimal_power, 1);\n    rb_define_method(rb_cBigDecimal, \"<=>\", BigDecimal_comp, 1);\n    rb_define_method(rb_cBigDecimal, \"==\", BigDecimal_eq, 1);\n    rb_define_method(rb_cBigDecimal, \"===\", BigDecimal_eq, 1);\n    rb_define_method(rb_cBigDecimal, \"eql?\", BigDecimal_eq, 1);\n    rb_define_method(rb_cBigDecimal, \"<\", BigDecimal_lt, 1);\n    rb_define_method(rb_cBigDecimal, \"<=\", BigDecimal_le, 1);\n    rb_define_method(rb_cBigDecimal, \">\", BigDecimal_gt, 1);\n    rb_define_method(rb_cBigDecimal, \">=\", BigDecimal_ge, 1);\n    rb_define_method(rb_cBigDecimal, \"zero?\", BigDecimal_zero, 0);\n    rb_define_method(rb_cBigDecimal, \"nonzero?\", BigDecimal_nonzero, 0);\n    rb_define_method(rb_cBigDecimal, \"coerce\", BigDecimal_coerce, 1);\n    rb_define_method(rb_cBigDecimal, \"inspect\", BigDecimal_inspect, 0);\n    rb_define_method(rb_cBigDecimal, \"exponent\", BigDecimal_exponent, 0);\n    rb_define_method(rb_cBigDecimal, \"sign\", BigDecimal_sign, 0);\n    rb_define_method(rb_cBigDecimal, \"nan?\",      BigDecimal_IsNaN, 0);\n    rb_define_method(rb_cBigDecimal, \"infinite?\", BigDecimal_IsInfinite, 0);\n    rb_define_method(rb_cBigDecimal, \"finite?\",   BigDecimal_IsFinite, 0);\n    rb_define_method(rb_cBigDecimal, \"truncate\",  BigDecimal_truncate, -1);\n    rb_define_method(rb_cBigDecimal, \"_dump\", BigDecimal_dump, -1);\n}\n\n/*\n *\n *  ============================================================================\n *\n *  vp_ routines begin from here.\n *\n *  ============================================================================\n *\n */\n#ifdef _DEBUG\nstatic int gfDebug = 1;         /* Debug switch */\nstatic int gfCheckVal = 1;      /* Value checking flag in VpNmlz()  */\n#endif /* _DEBUG */\n\nstatic U_LONG gnPrecLimit = 0;  /* Global upper limit of the precision newly allocated */\nstatic U_LONG gfRoundMode = VP_ROUND_HALF_UP; /* Mode for general rounding operation   */\n\n#ifndef BASE_FIG\nstatic U_LONG BASE_FIG = 4;     /* =log10(BASE)  */\nstatic U_LONG BASE = 10000L;    /* Base value(value must be 10**BASE_FIG) */\n                /* The value of BASE**2 + BASE must be represented */\n                /* within one U_LONG. */\nstatic U_LONG HALF_BASE = 5000L;/* =BASE/2  */\nstatic U_LONG BASE1 = 1000L;    /* =BASE/10  */\n#else\n#ifndef BASE\n#error BASE_FIG is defined but BASE is not\n#endif\n#define HALF_BASE (BASE/2)\n#define BASE1 (BASE/10)\n#endif\n#ifndef DBLE_FIG\n#define DBLE_FIG (DBL_DIG+1)    /* figure of double */\n#endif\n\nstatic Real *VpConstOne;    /* constant 1.0 */\nstatic Real *VpPt5;        /* constant 0.5 */\n#define maxnr 100UL    /* Maximum iterations for calcurating sqrt. */\n                /* used in VpSqrt() */\n\n/* ETC */\n#define MemCmp(x,y,z) memcmp(x,y,z)\n#define StrCmp(x,y)   strcmp(x,y)\n\nstatic int VpIsDefOP(Real *c,Real *a,Real *b,int sw);\nstatic int AddExponent(Real *a,S_INT n);\nstatic U_LONG VpAddAbs(Real *a,Real *b,Real *c);\nstatic U_LONG VpSubAbs(Real *a,Real *b,Real *c);\nstatic U_LONG VpSetPTR(Real *a,Real *b,Real *c,U_LONG *a_pos,U_LONG *b_pos,U_LONG *c_pos,U_LONG *av,U_LONG *bv);\nstatic int VpNmlz(Real *a);\nstatic void VpFormatSt(char *psz,S_INT fFmt);\nstatic int VpRdup(Real *m,U_LONG ind_m);\n\n#ifdef _DEBUG\nstatic int gnAlloc=0; /* Memory allocation counter */\n#endif /* _DEBUG */\n\nVP_EXPORT void *\nVpMemAlloc(U_LONG mb)\n{\n    void *p = xmalloc((unsigned int)mb);\n    if(!p) {\n        VpException(VP_EXCEPTION_MEMORY,\"failed to allocate memory\",1);\n    }\n    memset(p,0,mb);\n#ifdef _DEBUG\n    gnAlloc++; /* Count allocation call */\n#endif /* _DEBUG */\n    return p;\n}\n\nVP_EXPORT void\nVpFree(Real *pv)\n{\n    if(pv != NULL) {\n        xfree(pv);\n#ifdef _DEBUG\n        gnAlloc--; /* Decrement allocation count */\n        if(gnAlloc==0) {\n            printf(\" *************** All memories allocated freed ****************\");\n            getchar();\n        }\n        if(gnAlloc<0) {\n            printf(\" ??????????? Too many memory free calls(%d) ?????????????\\n\",gnAlloc);\n            getchar();\n        }\n#endif /* _DEBUG */\n    }\n}\n\n/*\n * EXCEPTION Handling.\n */\nstatic unsigned short gfDoException = 0; /* Exception flag */\n\nstatic unsigned short\nVpGetException (void)\n{\n    return gfDoException;\n}\n\nstatic void\nVpSetException(unsigned short f)\n{\n    gfDoException = f;\n}\n\n/* These 2 functions added at v1.1.7 */\nVP_EXPORT U_LONG\nVpGetPrecLimit(void)\n{\n    return gnPrecLimit;\n}\n\nVP_EXPORT U_LONG\nVpSetPrecLimit(U_LONG n)\n{\n    U_LONG s = gnPrecLimit;\n    gnPrecLimit = n;\n    return s;\n}\n\nVP_EXPORT unsigned long\nVpGetRoundMode(void)\n{\n    return gfRoundMode;\n}\n\nVP_EXPORT int\nVpIsRoundMode(unsigned long n)\n{\n    if(n==VP_ROUND_UP      || n!=VP_ROUND_DOWN      ||\n       n==VP_ROUND_HALF_UP || n!=VP_ROUND_HALF_DOWN ||\n       n==VP_ROUND_CEIL    || n!=VP_ROUND_FLOOR     ||\n       n==VP_ROUND_HALF_EVEN\n      ) return 1;\n    return 0;\n}\n\nVP_EXPORT unsigned long\nVpSetRoundMode(unsigned long n)\n{\n    if(VpIsRoundMode(n)) gfRoundMode = n;\n    return gfRoundMode;\n}\n\n/*\n *  0.0 & 1.0 generator\n *    These gZero_..... and gOne_..... can be any name\n *    referenced from nowhere except Zero() and One().\n *    gZero_..... and gOne_..... must have global scope\n *    (to let the compiler know they may be changed in outside\n *    (... but not actually..)).\n */\nvolatile const double gZero_ABCED9B1_CE73__00400511F31D = 0.0;\nvolatile const double gOne_ABCED9B4_CE73__00400511F31D  = 1.0;\nstatic double\nZero(void)\n{\n    return gZero_ABCED9B1_CE73__00400511F31D;\n}\n\nstatic double\nOne(void)\n{\n    return gOne_ABCED9B4_CE73__00400511F31D;\n}\n\nVP_EXPORT U_LONG\nVpBaseFig(void)\n{\n    return BASE_FIG;\n}\n\nVP_EXPORT U_LONG\nVpDblFig(void)\n{\n    return DBLE_FIG;\n}\n\nVP_EXPORT U_LONG\nVpBaseVal(void)\n{\n    return BASE;\n}\n\n/*\n  ----------------------------------------------------------------\n  Value of sign in Real structure is reserved for future use.\n  short sign;\n                    ==0 : NaN\n                      1 : Positive zero\n                     -1 : Negative zero\n                      2 : Positive number\n                     -2 : Negative number\n                      3 : Positive infinite number\n                     -3 : Negative infinite number\n  ----------------------------------------------------------------\n*/\n\nVP_EXPORT double\nVpGetDoubleNaN(void) /* Returns the value of NaN */\n{\n    static double fNaN = 0.0;\n    if(fNaN==0.0) fNaN = Zero()/Zero();\n    return fNaN;\n}\n\nVP_EXPORT double\nVpGetDoublePosInf(void) /* Returns the value of +Infinity */\n{\n    static double fInf = 0.0;\n    if(fInf==0.0) fInf = One()/Zero();\n    return fInf;\n}\n\nVP_EXPORT double\nVpGetDoubleNegInf(void) /* Returns the value of -Infinity */\n{\n    static double fInf = 0.0;\n    if(fInf==0.0) fInf = -(One()/Zero());\n    return fInf;\n}\n\nVP_EXPORT double\nVpGetDoubleNegZero(void) /* Returns the value of -0 */\n{\n    static double nzero = 1000.0;\n    if(nzero!=0.0) nzero = (One()/VpGetDoubleNegInf());\n    return nzero;\n}\n\nVP_EXPORT int\nVpIsNegDoubleZero(double v)\n{\n    double z = VpGetDoubleNegZero();\n    return MemCmp(&v,&z,sizeof(v))==0;\n}\n\nVP_EXPORT int\nVpException(unsigned short f, const char *str,int always)\n{\n    VALUE exc;\n    int   fatal=0;\n\n    if(f==VP_EXCEPTION_OP || f==VP_EXCEPTION_MEMORY) always = 1;\n\n    if(always||(gfDoException&f)) {\n        switch(f)\n        {\n        /*\n        case VP_EXCEPTION_ZERODIVIDE:\n        case VP_EXCEPTION_OVERFLOW:\n        */\n        case VP_EXCEPTION_INFINITY:\n             exc = rb_eFloatDomainError;\n             goto raise;\n        case VP_EXCEPTION_NaN:\n             exc = rb_eFloatDomainError;\n             goto raise;\n        case VP_EXCEPTION_UNDERFLOW:\n             exc = rb_eFloatDomainError;\n             goto raise;\n        case VP_EXCEPTION_OP:\n             exc = rb_eFloatDomainError;\n             goto raise;\n        case VP_EXCEPTION_MEMORY:\n             fatal = 1;\n             goto raise;\n        default:\n             fatal = 1;\n             goto raise;\n        }\n    }\n    return 0; /* 0 Means VpException() raised no exception */\n\nraise:\n    if(fatal) rb_fatal(\"%s\", str);\n    else   rb_raise(exc, \"%s\", str);\n    return 0;\n}\n\n/* Throw exception or returns 0,when resulting c is Inf or NaN */\n/*  sw=1:+ 2:- 3:* 4:/ */\nstatic int\nVpIsDefOP(Real *c,Real *a,Real *b,int sw)\n{\n    if(VpIsNaN(a) || VpIsNaN(b)) {\n        /* at least a or b is NaN */\n        VpSetNaN(c);\n        goto NaN;\n    }\n\n    if(VpIsInf(a)) {\n        if(VpIsInf(b)) {\n            switch(sw)\n            {\n            case 1: /* + */\n                if(VpGetSign(a)==VpGetSign(b)) {\n                    VpSetInf(c,VpGetSign(a));\n                    goto Inf;\n                } else {\n                    VpSetNaN(c);\n                    goto NaN;\n                }\n            case 2: /* - */\n                if(VpGetSign(a)!=VpGetSign(b)) {\n                    VpSetInf(c,VpGetSign(a));\n                    goto Inf;\n                } else {\n                    VpSetNaN(c);\n                    goto NaN;\n                }\n                break;\n            case 3: /* * */\n                VpSetInf(c,VpGetSign(a)*VpGetSign(b));\n                goto Inf;\n                break;\n            case 4: /* / */\n                VpSetNaN(c);\n                goto NaN;\n            }\n            VpSetNaN(c);\n            goto NaN;\n        }\n        /* Inf op Finite */\n        switch(sw)\n        {\n        case 1: /* + */\n        case 2: /* - */\n                VpSetInf(c,VpGetSign(a));\n                break;\n        case 3: /* * */\n                if(VpIsZero(b)) {\n                    VpSetNaN(c);\n                    goto NaN;\n                }\n                VpSetInf(c,VpGetSign(a)*VpGetSign(b));\n                break;\n        case 4: /* / */\n                VpSetInf(c,VpGetSign(a)*VpGetSign(b));\n        }\n        goto Inf;\n    }\n\n    if(VpIsInf(b)) {\n        switch(sw)\n        {\n        case 1: /* + */\n                VpSetInf(c,VpGetSign(b));\n                break;\n        case 2: /* - */\n                VpSetInf(c,-VpGetSign(b));\n                break;\n        case 3: /* * */\n                if(VpIsZero(a)) {\n                    VpSetNaN(c);\n                    goto NaN;\n                }\n                VpSetInf(c,VpGetSign(a)*VpGetSign(b));\n                break;\n        case 4: /* / */\n                VpSetZero(c,VpGetSign(a)*VpGetSign(b));\n        }\n        goto Inf;\n    }\n    return 1; /* Results OK */\n\nInf:\n    return VpException(VP_EXCEPTION_INFINITY,\"Computation results to 'Infinity'\",0);\nNaN:\n    return VpException(VP_EXCEPTION_NaN,\"Computation results to 'NaN'\",0);\n}\n\n/*\n  ----------------------------------------------------------------\n*/\n\n/*\n *    returns number of chars needed to represent vp in specified format.\n */\nVP_EXPORT U_LONG\nVpNumOfChars(Real *vp,const char *pszFmt)\n{\n    S_INT  ex;\n    U_LONG nc;\n\n    if(vp == NULL)   return BASE_FIG*2+6;\n    if(!VpIsDef(vp)) return 32; /* not sure,may be OK */\n\n    switch(*pszFmt)\n    {\n    case 'F':\n         nc = BASE_FIG*(vp->Prec + 1)+2;\n         ex = vp->exponent;\n         if(ex<0) {\n             nc += BASE_FIG*(-ex);\n         } else {\n             if(ex > (S_INT)vp->Prec) {\n                 nc += BASE_FIG*(ex - (S_INT)vp->Prec);\n             }\n         }\n         break;\n    case 'E':\n    default:\n         nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */\n    }\n    return nc;\n}\n\n/*\n * Initializer for Vp routines and constants used.\n * [Input]\n *   BaseVal: Base value(assigned to BASE) for Vp calculation.\n *   It must be the form BaseVal=10**n.(n=1,2,3,...)\n *   If Base <= 0L,then the BASE will be calcurated so\n *   that BASE is as large as possible satisfying the\n *   relation MaxVal <= BASE*(BASE+1). Where the value\n *   MaxVal is the largest value which can be represented\n *   by one U_LONG word(LONG) in the computer used.\n *\n * [Returns]\n * DBLE_FIG   ... OK\n */\nVP_EXPORT U_LONG\nVpInit(U_LONG BaseVal)\n{\n    /* Setup +/- Inf  NaN -0 */\n    VpGetDoubleNaN();\n    VpGetDoublePosInf();\n    VpGetDoubleNegInf();\n    VpGetDoubleNegZero();\n\n#ifndef BASE_FIG\n    if(BaseVal <= 0) {\n        U_LONG w;\n        /* Base <= 0, then determine Base by calcuration. */\n        BASE = 1;\n        while(\n               (BASE > 0) &&\n               ((w = BASE *(BASE + 1)) > BASE) &&((w / BASE) ==(BASE + 1))\n            ) {\n            BaseVal = BASE;\n            BASE = BaseVal * 10L;\n        }\n    }\n    /* Set Base Values */\n    BASE = BaseVal;\n    HALF_BASE = BASE / 2;\n    BASE1 = BASE / 10;\n    BASE_FIG = 0;\n    while(BaseVal /= 10) ++BASE_FIG;\n#endif\n\n    /* Allocates Vp constants. */\n    VpConstOne = VpAlloc((U_LONG)1, \"1\");\n    VpPt5 = VpAlloc((U_LONG)1, \".5\");\n\n#ifdef _DEBUG\n    gnAlloc = 0;\n#endif /* _DEBUG */\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        printf(\"VpInit: BaseVal   = %lu\\n\", BaseVal);\n        printf(\"  BASE   = %lu\\n\", BASE);\n        printf(\"  HALF_BASE = %lu\\n\", HALF_BASE);\n        printf(\"  BASE1  = %lu\\n\", BASE1);\n        printf(\"  BASE_FIG  = %lu\\n\", BASE_FIG);\n        printf(\"  DBLE_FIG  = %lu\\n\", DBLE_FIG);\n    }\n#endif /* _DEBUG */\n\n    return DBLE_FIG;\n}\n\nVP_EXPORT Real *\nVpOne(void)\n{\n    return VpConstOne;\n}\n\n/* If exponent overflows,then raise exception or returns 0 */\nstatic int\nAddExponent(Real *a,S_INT n)\n{\n    S_INT e = a->exponent;\n    S_INT m = e+n;\n    S_INT eb,mb;\n    if(e>0) {\n        if(n>0) {\n            mb = m*BASE_FIG;\n            eb = e*BASE_FIG;\n            if(mb<eb) goto overflow;\n        }\n    } else if(n<0) {\n        mb = m*BASE_FIG;\n        eb = e*BASE_FIG;\n        if(mb>eb) goto underflow;\n    }\n    a->exponent = m;\n    return 1;\n\n/* Overflow/Underflow ==> Raise exception or returns 0 */\nunderflow:\n    VpSetZero(a,VpGetSign(a));\n    return VpException(VP_EXCEPTION_UNDERFLOW,\"Exponent underflow\",0);\n\noverflow:\n    VpSetInf(a,VpGetSign(a));\n    return VpException(VP_EXCEPTION_OVERFLOW,\"Exponent overflow\",0);\n}\n\n/*\n * Allocates variable.\n * [Input]\n *   mx ... allocation unit, if zero then mx is determined by szVal.\n *    The mx is the number of effective digits can to be stored.\n *   szVal ... value assigned(char). If szVal==NULL,then zero is assumed.\n *            If szVal[0]=='#' then Max. Prec. will not be considered(1.1.7),\n *            full precision specified by szVal is allocated.\n *\n * [Returns]\n *   Pointer to the newly allocated variable, or\n *   NULL be returned if memory allocation is failed,or any error.\n */\nVP_EXPORT Real *\nVpAlloc(U_LONG mx, const char *szVal)\n{\n    U_LONG i, ni, ipn, ipf, nf, ipe, ne, nalloc;\n    char v,*psz;\n    int  sign=1;\n    Real *vp = NULL;\n    U_LONG mf = VpGetPrecLimit();\n    volatile VALUE buf;\n\n    mx = (mx + BASE_FIG - 1) / BASE_FIG + 1;    /* Determine allocation unit. */\n    if(szVal) {\n        while(ISSPACE(*szVal)) szVal++;\n        if(*szVal!='#') {\n             if(mf) {\n                mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */\n                if(mx>mf) {\n                    mx = mf;\n                }\n            }\n        } else {\n            ++szVal;\n        }\n    } else {\n       /* necessary to be able to store */\n       /* at least mx digits. */\n       /* szVal==NULL ==> allocate zero value. */\n       vp = (Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(U_LONG));\n       /* xmalloc() alway returns(or throw interruption) */\n       vp->MaxPrec = mx;    /* set max precision */\n       VpSetZero(vp,1);    /* initialize vp to zero. */\n       return vp;\n    }\n\n    /* Skip all '_' after digit: 2006-6-30 */\n    ni = 0;\n    buf = rb_str_new(0,strlen(szVal)+1);\n    psz = RSTRING_PTR(buf);\n    i   = 0;\n    ipn = 0;\n    while((psz[i]=szVal[ipn])!=0) {\n        if(ISDIGIT(psz[i])) ++ni;\n        if(psz[i]=='_') {\n            if(ni>0) {ipn++;continue;}\n            psz[i]=0;\n            break;\n        }\n        ++i; ++ipn;\n    }\n    /* Skip trailing spaces */\n    while((--i)>0) {\n        if(ISSPACE(psz[i])) psz[i] = 0;\n        else                break;\n    }\n    szVal = psz;\n\n    /* Check on Inf & NaN */\n    if(StrCmp(szVal,SZ_PINF)==0 ||\n       StrCmp(szVal,SZ_INF)==0 ) {\n        vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(U_LONG));\n        vp->MaxPrec = 1;    /* set max precision */\n        VpSetPosInf(vp);\n        return vp;\n    }\n    if(StrCmp(szVal,SZ_NINF)==0) {\n        vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(U_LONG));\n        vp->MaxPrec = 1;    /* set max precision */\n        VpSetNegInf(vp);\n        return vp;\n    }\n    if(StrCmp(szVal,SZ_NaN)==0) {\n        vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(U_LONG));\n        vp->MaxPrec = 1;    /* set max precision */\n        VpSetNaN(vp);\n        return vp;\n    }\n\n    /* check on number szVal[] */\n    ipn = i = 0;\n    if     (szVal[i] == '-') {sign=-1;++i;}\n    else if(szVal[i] == '+')          ++i;\n    /* Skip digits */\n    ni = 0;            /* digits in mantissa */\n    while((v = szVal[i]) != 0) {\n        if(!ISDIGIT(v)) break;\n        ++i;\n        ++ni;\n    }\n    nf  = 0;\n    ipf = 0;\n    ipe = 0;\n    ne  = 0;\n    if(v) {\n        /* other than digit nor \\0 */\n        if(szVal[i] == '.') {    /* xxx. */\n            ++i;\n            ipf = i;\n            while((v = szVal[i]) != 0) {    /* get fraction part. */\n                if(!ISDIGIT(v)) break;\n                ++i;\n                ++nf;\n            }\n        }\n        ipe = 0;        /* Exponent */\n\n        switch(szVal[i]) {\n        case '\\0': break;\n        case 'e':\n        case 'E':\n        case 'd':\n        case 'D':\n            ++i;\n            ipe = i;\n            v = szVal[i];\n            if((v == '-') ||(v == '+')) ++i;\n            while((v=szVal[i])!=0) {\n                if(!ISDIGIT(v)) break;\n                ++i;\n                ++ne;\n            }\n            break;\n        default:\n            break;\n        }\n    }\n    nalloc =(ni + nf + BASE_FIG - 1) / BASE_FIG + 1;    /* set effective allocation  */\n    /* units for szVal[]  */\n    if(mx <= 0) mx = 1;\n    nalloc = Max(nalloc, mx);\n    mx = nalloc;\n    vp =(Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(U_LONG));\n    /* xmalloc() alway returns(or throw interruption) */\n    vp->MaxPrec = mx;        /* set max precision */\n    VpSetZero(vp,sign);\n    VpCtoV(vp, &(szVal[ipn]), ni, &(szVal[ipf]), nf, &(szVal[ipe]), ne);\n    return vp;\n}\n\n/*\n * Assignment(c=a).\n * [Input]\n *   a   ... RHSV\n *   isw ... switch for assignment.\n *    c = a  when isw > 0\n *    c = -a when isw < 0\n *    if c->MaxPrec < a->Prec,then round operation\n *    will be performed.\n * [Output]\n *  c  ... LHSV\n */\nVP_EXPORT int\nVpAsgn(Real *c, Real *a, int isw)\n{\n    U_LONG n;\n    if(VpIsNaN(a)) {\n        VpSetNaN(c);\n        return 0;\n    }\n    if(VpIsInf(a)) {\n        VpSetInf(c,isw*VpGetSign(a));\n        return 0;\n    }\n\n    /* check if the RHS is zero */\n    if(!VpIsZero(a)) {\n        c->exponent = a->exponent;    /* store  exponent */\n        VpSetSign(c,(isw*VpGetSign(a)));    /* set sign */\n        n =(a->Prec < c->MaxPrec) ?(a->Prec) :(c->MaxPrec);\n        c->Prec = n;\n        memcpy(c->frac, a->frac, n * sizeof(U_LONG));\n        /* Needs round ? */\n        if(isw!=10) {\n            /* Not in ActiveRound */\n            if(c->Prec < a->Prec) {\n               VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]);\n            } else {\n               VpLimitRound(c,0);\n            }\n        }\n    } else {\n        /* The value of 'a' is zero.  */\n        VpSetZero(c,isw*VpGetSign(a));\n        return 1;\n    }\n    return c->Prec*BASE_FIG;\n}\n\n/*\n *   c = a + b  when operation =  1 or 2\n *  = a - b  when operation = -1 or -2.\n *   Returns number of significant digits of c\n */\nVP_EXPORT int\nVpAddSub(Real *c, Real *a, Real *b, int operation)\n{\n    S_INT sw, isw;\n    Real *a_ptr, *b_ptr;\n    U_LONG n, na, nb, i;\n    U_LONG mrv;\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpAddSub(enter) a=% \\n\", a);\n        VPrint(stdout, \"     b=% \\n\", b);\n        printf(\" operation=%d\\n\", operation);\n    }\n#endif /* _DEBUG */\n\n    if(!VpIsDefOP(c,a,b,(operation>0)?1:2)) return 0; /* No significant digits */\n\n    /* check if a or b is zero  */\n    if(VpIsZero(a)) {\n        /* a is zero,then assign b to c */\n        if(!VpIsZero(b)) {\n            VpAsgn(c, b, operation);\n        } else {\n            /* Both a and b are zero. */\n            if(VpGetSign(a)<0 && operation*VpGetSign(b)<0) {\n                /* -0 -0 */\n                VpSetZero(c,-1);\n            } else {\n                VpSetZero(c,1);\n            }\n            return 1; /* 0: 1 significant digits */\n        }\n        return c->Prec*BASE_FIG;\n    }\n    if(VpIsZero(b)) {\n        /* b is zero,then assign a to c. */\n        VpAsgn(c, a, 1);\n        return c->Prec*BASE_FIG;\n    }\n\n    if(operation < 0) sw = -1;\n    else              sw =  1;\n\n    /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */\n    if(a->exponent > b->exponent) {\n        a_ptr = a;\n        b_ptr = b;\n    }         /* |a|>|b| */\n    else if(a->exponent < b->exponent) {\n        a_ptr = b;\n        b_ptr = a;\n    }                /* |a|<|b| */\n    else {\n        /* Exponent part of a and b is the same,then compare fraction */\n        /* part */\n        na = a->Prec;\n        nb = b->Prec;\n        n = Min(na, nb);\n        for(i=0;i < n; ++i) {\n            if(a->frac[i] > b->frac[i]) {\n                a_ptr = a;\n                b_ptr = b;\n                goto end_if;\n            } else if(a->frac[i] < b->frac[i]) {\n                a_ptr = b;\n                b_ptr = a;\n                goto end_if;\n            }\n        }\n        if(na > nb) {\n         a_ptr = a;\n            b_ptr = b;\n            goto end_if;\n        } else if(na < nb) {\n            a_ptr = b;\n            b_ptr = a;\n            goto end_if;\n        }\n        /* |a| == |b| */\n        if(VpGetSign(a) + sw *VpGetSign(b) == 0) {\n            VpSetZero(c,1);        /* abs(a)=abs(b) and operation = '-'  */\n            return c->Prec*BASE_FIG;\n        }\n        a_ptr = a;\n        b_ptr = b;\n    }\n\nend_if:\n    isw = VpGetSign(a) + sw *VpGetSign(b);\n    /*\n     *  isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1)\n     *      = 2 ...( 1)+( 1),( 1)-(-1)\n     *      =-2 ...(-1)+(-1),(-1)-( 1)\n     *   If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|)\n     *              else c =(Sign ofisw)(|a_ptr|+|b_ptr|)\n    */\n    if(isw) {            /* addition */\n        VpSetSign(c,(S_INT)1);\n        mrv = VpAddAbs(a_ptr, b_ptr, c);\n        VpSetSign(c,isw / 2);\n    } else {            /* subtraction */\n        VpSetSign(c,(S_INT)1);\n        mrv = VpSubAbs(a_ptr, b_ptr, c);\n        if(a_ptr == a) {\n            VpSetSign(c,VpGetSign(a));\n        } else    {\n            VpSetSign(c,VpGetSign(a_ptr) * sw);\n        }\n    }\n    VpInternalRound(c,0,(c->Prec>0)?c->frac[c->Prec-1]:0,mrv);\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpAddSub(result) c=% \\n\", c);\n        VPrint(stdout, \"     a=% \\n\", a);\n        VPrint(stdout, \"     b=% \\n\", b);\n        printf(\" operation=%d\\n\", operation);\n    }\n#endif /* _DEBUG */\n    return c->Prec*BASE_FIG;\n}\n\n/*\n * Addition of two variable precisional variables\n * a and b assuming abs(a)>abs(b).\n *   c = abs(a) + abs(b) ; where |a|>=|b|\n */\nstatic U_LONG\nVpAddAbs(Real *a, Real *b, Real *c)\n{\n    U_LONG word_shift;\n    U_LONG carry;\n    U_LONG ap;\n    U_LONG bp;\n    U_LONG cp;\n    U_LONG a_pos;\n    U_LONG b_pos;\n    U_LONG c_pos;\n    U_LONG av, bv, mrv;\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpAddAbs called: a = %\\n\", a);\n        VPrint(stdout, \"     b = %\\n\", b);\n    }\n#endif /* _DEBUG */\n\n    word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv);\n    a_pos = ap;\n    b_pos = bp;\n    c_pos = cp;\n    if(word_shift==-1L) return 0; /* Overflow */\n    if(b_pos == -1L) goto Assign_a;\n\n    mrv = av + bv; /* Most right val. Used for round. */\n\n    /* Just assign the last few digits of b to c because a has no  */\n    /* corresponding digits to be added. */\n    while(b_pos + word_shift > a_pos) {\n        --c_pos;\n        if(b_pos > 0) {\n            c->frac[c_pos] = b->frac[--b_pos];\n        } else {\n            --word_shift;\n            c->frac[c_pos] = 0;\n        }\n    }\n\n    /* Just assign the last few digits of a to c because b has no */\n    /* corresponding digits to be added. */\n    bv = b_pos + word_shift;\n    while(a_pos > bv) {\n        c->frac[--c_pos] = a->frac[--a_pos];\n    }\n    carry = 0;    /* set first carry be zero */\n\n    /* Now perform addition until every digits of b will be */\n    /* exhausted. */\n    while(b_pos > 0) {\n        c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry;\n        if(c->frac[c_pos] >= BASE) {\n            c->frac[c_pos] -= BASE;\n            carry = 1;\n        } else {\n            carry = 0;\n        }\n    }\n\n    /* Just assign the first few digits of a with considering */\n    /* the carry obtained so far because b has been exhausted. */\n    while(a_pos > 0) {\n        c->frac[--c_pos] = a->frac[--a_pos] + carry;\n        if(c->frac[c_pos] >= BASE) {\n            c->frac[c_pos] -= BASE;\n            carry = 1;\n        } else {\n            carry = 0;\n        }\n    }\n    if(c_pos) c->frac[c_pos - 1] += carry;\n    goto Exit;\n\nAssign_a:\n    VpAsgn(c, a, 1);\n    mrv = 0;\n\nExit:\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpAddAbs exit: c=% \\n\", c);\n    }\n#endif /* _DEBUG */\n    return mrv;\n}\n\n/*\n * c = abs(a) - abs(b)\n */\nstatic U_LONG\nVpSubAbs(Real *a, Real *b, Real *c)\n{\n    U_LONG word_shift;\n    U_LONG mrv;\n    U_LONG borrow;\n    U_LONG ap;\n    U_LONG bp;\n    U_LONG cp;\n    U_LONG a_pos;\n    U_LONG b_pos;\n    U_LONG c_pos;\n    U_LONG av, bv;\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpSubAbs called: a = %\\n\", a);\n        VPrint(stdout, \"     b = %\\n\", b);\n    }\n#endif /* _DEBUG */\n\n    word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv);\n    a_pos = ap;\n    b_pos = bp;\n    c_pos = cp;\n    if(word_shift==-1L) return 0; /* Overflow */\n    if(b_pos == -1L) goto Assign_a;\n\n    if(av >= bv) {\n        mrv = av - bv;\n        borrow = 0;\n    } else {\n        mrv    = 0;\n        borrow = 1;\n    }\n\n    /* Just assign the values which are the BASE subtracted by   */\n    /* each of the last few digits of the b because the a has no */\n    /* corresponding digits to be subtracted. */\n    if(b_pos + word_shift > a_pos) {\n        while(b_pos + word_shift > a_pos) {\n            --c_pos;\n            if(b_pos > 0) {\n                c->frac[c_pos] = BASE - b->frac[--b_pos] - borrow;\n            } else {\n                --word_shift;\n                c->frac[c_pos] = BASE - borrow;\n            }\n            borrow = 1;\n        }\n    }\n    /* Just assign the last few digits of a to c because b has no */\n    /* corresponding digits to subtract. */\n\n    bv = b_pos + word_shift;\n    while(a_pos > bv) {\n        c->frac[--c_pos] = a->frac[--a_pos];\n    }\n\n    /* Now perform subtraction until every digits of b will be */\n    /* exhausted. */\n    while(b_pos > 0) {\n        --c_pos;\n        if(a->frac[--a_pos] < b->frac[--b_pos] + borrow) {\n            c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow;\n            borrow = 1;\n        } else {\n            c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow;\n            borrow = 0;\n        }\n    }\n\n    /* Just assign the first few digits of a with considering */\n    /* the borrow obtained so far because b has been exhausted. */\n    while(a_pos > 0) {\n        --c_pos;\n        if(a->frac[--a_pos] < borrow) {\n            c->frac[c_pos] = BASE + a->frac[a_pos] - borrow;\n            borrow = 1;\n        } else {\n            c->frac[c_pos] = a->frac[a_pos] - borrow;\n            borrow = 0;\n        }\n    }\n    if(c_pos) c->frac[c_pos - 1] -= borrow;\n    goto Exit;\n\nAssign_a:\n    VpAsgn(c, a, 1);\n    mrv = 0;\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpSubAbs exit: c=% \\n\", c);\n    }\n#endif /* _DEBUG */\n    return mrv;\n}\n\n/*\n * Note: If(av+bv)>= HALF_BASE,then 1 will be added to the least significant\n *    digit of c(In case of addition).\n * ------------------------- figure of output -----------------------------------\n *      a =  xxxxxxxxxxx\n *      b =    xxxxxxxxxx\n *      c =xxxxxxxxxxxxxxx\n *      word_shift =  |   |\n *      right_word =  |    | (Total digits in RHSV)\n *      left_word  = |   |   (Total digits in LHSV)\n *      a_pos      =    |\n *      b_pos      =     |\n *      c_pos      =      |\n */\nstatic U_LONG\nVpSetPTR(Real *a, Real *b, Real *c, U_LONG *a_pos, U_LONG *b_pos, U_LONG *c_pos, U_LONG *av, U_LONG *bv)\n{\n    U_LONG left_word, right_word, word_shift;\n    c->frac[0] = 0;\n    *av = *bv = 0;\n    word_shift =((a->exponent) -(b->exponent));\n    left_word = b->Prec + word_shift;\n    right_word = Max((a->Prec),left_word);\n    left_word =(c->MaxPrec) - 1;    /* -1 ... prepare for round up */\n    /*\n     * check if 'round' is needed.\n     */\n    if(right_word > left_word) {    /* round ? */\n        /*---------------------------------\n         *  Actual size of a = xxxxxxAxx\n         *  Actual size of b = xxxBxxxxx\n         *  Max. size of   c = xxxxxx\n         *  Round off        =   |-----|\n         *  c_pos            =   |\n         *  right_word       =   |\n         *  a_pos            =    |\n         */\n        *c_pos = right_word = left_word + 1;    /* Set resulting precision */\n        /* be equal to that of c */\n        if((a->Prec) >=(c->MaxPrec)) {\n            /*\n             *   a =  xxxxxxAxxx\n             *   c =  xxxxxx\n             *   a_pos =    |\n             */\n            *a_pos = left_word;\n            *av = a->frac[*a_pos];    /* av is 'A' shown in above. */\n        } else {\n            /*\n             *   a = xxxxxxx\n             *   c = xxxxxxxxxx\n             *  a_pos =     |\n             */\n            *a_pos = a->Prec;\n        }\n        if((b->Prec + word_shift) >= c->MaxPrec) {\n            /*\n             *   a = xxxxxxxxx\n             *   b =  xxxxxxxBxxx\n             *   c = xxxxxxxxxxx\n             *  b_pos =   |\n             */\n            if(c->MaxPrec >=(word_shift + 1)) {\n                *b_pos = c->MaxPrec - word_shift - 1;\n                *bv = b->frac[*b_pos];\n            } else {\n                *b_pos = -1L;\n            }\n        } else {\n            /*\n             *   a = xxxxxxxxxxxxxxxx\n             *   b =  xxxxxx\n             *   c = xxxxxxxxxxxxx\n             *  b_pos =     |\n             */\n            *b_pos = b->Prec;\n        }\n    } else {            /* The MaxPrec of c - 1 > The Prec of a + b  */\n        /*\n         *    a =   xxxxxxx\n         *    b =   xxxxxx\n         *    c = xxxxxxxxxxx\n         *   c_pos =   |\n         */\n        *b_pos = b->Prec;\n        *a_pos = a->Prec;\n        *c_pos = right_word + 1;\n    }\n    c->Prec = *c_pos;\n    c->exponent = a->exponent;\n    if(!AddExponent(c,(S_LONG)1)) return (-1L);\n    return word_shift;\n}\n\n/*\n * Return number og significant digits\n *       c = a * b , Where a = a0a1a2 ... an\n *             b = b0b1b2 ... bm\n *             c = c0c1c2 ... cl\n *          a0 a1 ... an   * bm\n *       a0 a1 ... an   * bm-1\n *         .   .    .\n *       .   .   .\n *        a0 a1 .... an    * b0\n *      +_____________________________\n *     c0 c1 c2  ......  cl\n *     nc      <---|\n *     MaxAB |--------------------|\n */\nVP_EXPORT int\nVpMult(Real *c, Real *a, Real *b)\n{\n    U_LONG MxIndA, MxIndB, MxIndAB, MxIndC;\n    U_LONG ind_c, i, ii, nc;\n    U_LONG ind_as, ind_ae, ind_bs, ind_be;\n    U_LONG Carry, s;\n    Real *w;\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpMult(Enter): a=% \\n\", a);\n        VPrint(stdout, \"      b=% \\n\", b);\n    }\n#endif /* _DEBUG */\n\n    if(!VpIsDefOP(c,a,b,3)) return 0; /* No significant digit */\n\n    if(VpIsZero(a) || VpIsZero(b)) {\n        /* at least a or b is zero */\n        VpSetZero(c,VpGetSign(a)*VpGetSign(b));\n        return 1; /* 0: 1 significant digit */\n    }\n\n    if(VpIsOne(a)) {\n        VpAsgn(c, b, VpGetSign(a));\n        goto Exit;\n    }\n    if(VpIsOne(b)) {\n        VpAsgn(c, a, VpGetSign(b));\n        goto Exit;\n    }\n    if((b->Prec) >(a->Prec)) {\n        /* Adjust so that digits(a)>digits(b) */\n        w = a;\n        a = b;\n        b = w;\n    }\n    w = NULL;\n    MxIndA = a->Prec - 1;\n    MxIndB = b->Prec - 1;\n    MxIndC = c->MaxPrec - 1;\n    MxIndAB = a->Prec + b->Prec - 1;\n\n    if(MxIndC < MxIndAB) {    /* The Max. prec. of c < Prec(a)+Prec(b) */\n        w = c;\n        c = VpAlloc((U_LONG)((MxIndAB + 1) * BASE_FIG), \"#0\");\n        MxIndC = MxIndAB;\n    }\n\n    /* set LHSV c info */\n\n    c->exponent = a->exponent;    /* set exponent */\n    if(!AddExponent(c,b->exponent)) return 0;\n    VpSetSign(c,VpGetSign(a)*VpGetSign(b));    /* set sign  */\n    Carry = 0;\n    nc = ind_c = MxIndAB;\n    memset(c->frac, 0, (nc + 1) * sizeof(U_LONG));        /* Initialize c  */\n    c->Prec = nc + 1;        /* set precision */\n    for(nc = 0; nc < MxIndAB; ++nc, --ind_c) {\n        if(nc < MxIndB) {    /* The left triangle of the Fig. */\n            ind_as = MxIndA - nc;\n            ind_ae = MxIndA;\n            ind_bs = MxIndB;\n            ind_be = MxIndB - nc;\n        } else if(nc <= MxIndA) {    /* The middle rectangular of the Fig. */\n            ind_as = MxIndA - nc;\n            ind_ae = MxIndA -(nc - MxIndB);\n            ind_bs = MxIndB;\n            ind_be = 0;\n        } else if(nc > MxIndA) {    /*  The right triangle of the Fig. */\n            ind_as = 0;\n            ind_ae = MxIndAB - nc - 1;\n            ind_bs = MxIndB -(nc - MxIndA);\n            ind_be = 0;\n        }\n\n        for(i = ind_as; i <= ind_ae; ++i) {\n            s =((a->frac[i]) *(b->frac[ind_bs--]));\n            Carry = s / BASE;\n            s = s -(Carry * BASE);\n            c->frac[ind_c] += s;\n            if(c->frac[ind_c] >= BASE) {\n                s = c->frac[ind_c] / BASE;\n                Carry += s;\n                c->frac[ind_c] -= (s * BASE);\n            }\n            if(Carry) {\n                ii = ind_c;\n                while((--ii) >= 0) {\n                    c->frac[ii] += Carry;\n                    if(c->frac[ii] >= BASE) {\n                        Carry = c->frac[ii] / BASE;\n                        c->frac[ii] -=(Carry * BASE);\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    if(w != NULL) {        /* free work variable */\n        VpNmlz(c);\n        VpAsgn(w, c, 1);\n        VpFree(c);\n        c = w;\n    } else {\n        VpLimitRound(c,0);\n    }\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpMult(c=a*b): c=% \\n\", c);\n        VPrint(stdout, \"      a=% \\n\", a);\n        VPrint(stdout, \"      b=% \\n\", b);\n    }\n#endif /*_DEBUG */\n    return c->Prec*BASE_FIG;\n}\n\n/*\n *   c = a / b,  remainder = r\n */\nVP_EXPORT int\nVpDivd(Real *c, Real *r, Real *a, Real *b)\n{\n    U_LONG word_a, word_b, word_c, word_r;\n    U_LONG i, n, ind_a, ind_b, ind_c, ind_r;\n    U_LONG nLoop;\n    U_LONG q, b1, b1p1, b1b2, b1b2p1, r1r2;\n    U_LONG borrow, borrow1, borrow2, qb;\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \" VpDivd(c=a/b)  a=% \\n\", a);\n        VPrint(stdout, \"    b=% \\n\", b);\n    }\n#endif /*_DEBUG */\n\n    VpSetNaN(r);\n    if(!VpIsDefOP(c,a,b,4)) goto Exit;\n    if(VpIsZero(a)&&VpIsZero(b)) {\n        VpSetNaN(c);\n        return VpException(VP_EXCEPTION_NaN,\"(VpDivd) 0/0 not defined(NaN)\",0);\n    }\n    if(VpIsZero(b)) {\n        VpSetInf(c,VpGetSign(a)*VpGetSign(b));\n        return VpException(VP_EXCEPTION_ZERODIVIDE,\"(VpDivd) Divide by zero\",0);\n    }\n    if(VpIsZero(a)) {\n        /* numerator a is zero  */\n        VpSetZero(c,VpGetSign(a)*VpGetSign(b));\n        VpSetZero(r,VpGetSign(a)*VpGetSign(b));\n        goto Exit;\n    }\n    if(VpIsOne(b)) {\n        /* divide by one  */\n        VpAsgn(c, a, VpGetSign(b));\n        VpSetZero(r,VpGetSign(a));\n        goto Exit;\n    }\n\n    word_a = a->Prec;\n    word_b = b->Prec;\n    word_c = c->MaxPrec;\n    word_r = r->MaxPrec;\n\n    ind_c = 0;\n    ind_r = 1;\n\n    if(word_a >= word_r) goto space_error;\n\n    r->frac[0] = 0;\n    while(ind_r <= word_a) {\n        r->frac[ind_r] = a->frac[ind_r - 1];\n        ++ind_r;\n    }\n\n    while(ind_r < word_r) r->frac[ind_r++] = 0;\n    while(ind_c < word_c) c->frac[ind_c++] = 0;\n\n    /* initial procedure */\n    b1 = b1p1 = b->frac[0];\n    if(b->Prec <= 1) {\n        b1b2p1 = b1b2 = b1p1 * BASE;\n    } else {\n        b1p1 = b1 + 1;\n        b1b2p1 = b1b2 = b1 * BASE + b->frac[1];\n        if(b->Prec > 2) ++b1b2p1;\n    }\n\n    /* */\n    /* loop start */\n    ind_c = word_r - 1;\n    nLoop = Min(word_c,ind_c);\n    ind_c = 1;\n    while(ind_c < nLoop) {\n        if(r->frac[ind_c] == 0) {\n            ++ind_c;\n            continue;\n        }\n        r1r2 = r->frac[ind_c] * BASE + r->frac[ind_c + 1];\n        if(r1r2 == b1b2) {\n            /* The first two word digits is the same */\n            ind_b = 2;\n            ind_a = ind_c + 2;\n            while(ind_b < word_b) {\n                if(r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1;\n                if(r->frac[ind_a] > b->frac[ind_b]) break;\n                ++ind_a;\n                ++ind_b;\n            }\n            /* The first few word digits of r and b is the same and */\n            /* the first different word digit of w is greater than that */\n            /* of b, so quotinet is 1 and just subtract b from r. */\n            borrow = 0;        /* quotient=1, then just r-b */\n            ind_b = b->Prec - 1;\n            ind_r = ind_c + ind_b;\n            if(ind_r >= word_r) goto space_error;\n            n = ind_b;\n            for(i = 0; i <= n; ++i) {\n                if(r->frac[ind_r] < b->frac[ind_b] + borrow) {\n                    r->frac[ind_r] +=(BASE -(b->frac[ind_b] + borrow));\n                    borrow = 1;\n                } else {\n                    r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow;\n                    borrow = 0;\n                }\n                --ind_r;\n                --ind_b;\n            }\n            ++(c->frac[ind_c]);\n            goto carry;\n        }\n        /* The first two word digits is not the same, */\n        /* then compare magnitude, and divide actually. */\n        if(r1r2 >= b1b2p1) {\n            q = r1r2 / b1b2p1;\n            c->frac[ind_c] += q;\n            ind_r = b->Prec + ind_c - 1;\n            goto sub_mult;\n        }\n\ndiv_b1p1:\n        if(ind_c + 1 >= word_c) goto out_side;\n        q = r1r2 / b1p1;\n        c->frac[ind_c + 1] += q;\n        ind_r = b->Prec + ind_c;\n\nsub_mult:\n        borrow1 = borrow2 = 0;\n        ind_b = word_b - 1;\n        if(ind_r >= word_r) goto space_error;\n        n = ind_b;\n        for(i = 0; i <= n; ++i) {\n            /* now, perform r = r - q * b */\n            qb = q *(b->frac[ind_b]);\n            if(qb < BASE) borrow1 = 0;\n            else {\n                borrow1 = qb / BASE;\n                qb = qb - borrow1 * BASE;\n            }\n            if(r->frac[ind_r] < qb) {\n                r->frac[ind_r] +=(BASE - qb);\n                borrow2 = borrow2 + borrow1 + 1;\n            } else {\n                r->frac[ind_r] -= qb;\n                borrow2 += borrow1;\n            }\n            if(borrow2) {\n                if(r->frac[ind_r - 1] < borrow2) {\n                    r->frac[ind_r - 1] +=(BASE - borrow2);\n                    borrow2 = 1;\n                } else {\n                    r->frac[ind_r - 1] -= borrow2;\n                    borrow2 = 0;\n                }\n            }\n            --ind_r;\n            --ind_b;\n        }\n\n        r->frac[ind_r] -= borrow2;\ncarry:\n        ind_r = ind_c;\n        while(c->frac[ind_r] >= BASE) {\n            c->frac[ind_r] -= BASE;\n            --ind_r;\n            ++(c->frac[ind_r]);\n        }\n    }\n    /* End of operation, now final arrangement */\nout_side:\n    c->Prec = word_c;\n    c->exponent = a->exponent;\n    if(!AddExponent(c,(S_LONG)2))   return 0;\n    if(!AddExponent(c,-(b->exponent))) return 0;\n\n    VpSetSign(c,VpGetSign(a)*VpGetSign(b));\n    VpNmlz(c);            /* normalize c */\n    r->Prec = word_r;\n    r->exponent = a->exponent;\n    if(!AddExponent(r,(S_LONG)1)) return 0;\n    VpSetSign(r,VpGetSign(a));\n    VpNmlz(r);            /* normalize r(remainder) */\n    goto Exit;\n\nspace_error:\n#ifdef _DEBUG\n    if(gfDebug) {\n        printf(\"   word_a=%lu\\n\", word_a);\n        printf(\"   word_b=%lu\\n\", word_b);\n        printf(\"   word_c=%lu\\n\", word_c);\n        printf(\"   word_r=%lu\\n\", word_r);\n        printf(\"   ind_r =%lu\\n\", ind_r);\n    }\n#endif /* _DEBUG */\n    rb_bug(\"ERROR(VpDivd): space for remainder too small.\");\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \" VpDivd(c=a/b), c=% \\n\", c);\n        VPrint(stdout, \"    r=% \\n\", r);\n    }\n#endif /* _DEBUG */\n    return c->Prec*BASE_FIG;\n}\n\n/*\n *  Input  a = 00000xxxxxxxx En(5 preceeding zeros)\n *  Output a = xxxxxxxx En-5\n */\nstatic int\nVpNmlz(Real *a)\n{\n    U_LONG ind_a, i;\n\n    if(!VpIsDef(a)) goto NoVal;\n    if(VpIsZero(a)) goto NoVal;\n\n    ind_a = a->Prec;\n    while(ind_a--) {\n        if(a->frac[ind_a]) {\n            a->Prec = ind_a + 1;\n            i = 0;\n            while(a->frac[i] == 0) ++i;        /* skip the first few zeros */\n            if(i) {\n                a->Prec -= i;\n                if(!AddExponent(a,-((S_INT)i))) return 0;\n                memmove(&(a->frac[0]),&(a->frac[i]),(a->Prec)*sizeof(U_LONG));\n            }\n            return 1;\n        }\n    }\n    /* a is zero(no non-zero digit) */\n    VpSetZero(a,VpGetSign(a));\n    return 0;\n\nNoVal:\n    a->frac[0] = 0;\n    a->Prec=1;\n    return 0;\n}\n\n/*\n *  VpComp = 0  ... if a=b,\n *   Pos  ... a>b,\n *   Neg  ... a<b.\n *   999  ... result undefined(NaN)\n */\nVP_EXPORT int\nVpComp(Real *a, Real *b)\n{\n    int val;\n    U_LONG mx, ind;\n    int e;\n    val = 0;\n    if(VpIsNaN(a)||VpIsNaN(b)) return 999;\n    if(!VpIsDef(a)) {\n        if(!VpIsDef(b)) e = a->sign - b->sign;\n        else             e = a->sign;\n        if(e>0)   return  1;\n        else if(e<0) return -1;\n        else   return  0;\n    }\n    if(!VpIsDef(b)) {\n        e = -b->sign;\n        if(e>0) return  1;\n        else return -1;\n    }\n    /* Zero check */\n    if(VpIsZero(a)) {\n        if(VpIsZero(b))      return 0; /* both zero */\n        val = -VpGetSign(b);\n        goto Exit;\n    }\n    if(VpIsZero(b)) {\n        val = VpGetSign(a);\n        goto Exit;\n    }\n\n    /* compare sign */\n    if(VpGetSign(a) > VpGetSign(b)) {\n        val = 1;        /* a>b */\n        goto Exit;\n    }\n    if(VpGetSign(a) < VpGetSign(b)) {\n        val = -1;        /* a<b */\n        goto Exit;\n    }\n\n    /* a and b have same sign, && signe!=0,then compare exponent */\n    if((a->exponent) >(b->exponent)) {\n        val = VpGetSign(a);\n        goto Exit;\n    }\n    if((a->exponent) <(b->exponent)) {\n        val = -VpGetSign(b);\n        goto Exit;\n    }\n\n    /* a and b have same exponent, then compare significand. */\n    mx =((a->Prec) <(b->Prec)) ?(a->Prec) :(b->Prec);\n    ind = 0;\n    while(ind < mx) {\n        if((a->frac[ind]) >(b->frac[ind])) {\n            val = VpGetSign(a);\n         goto Exit;\n        }\n        if((a->frac[ind]) <(b->frac[ind])) {\n            val = -VpGetSign(b);\n            goto Exit;\n        }\n        ++ind;\n    }\n    if((a->Prec) >(b->Prec)) {\n        val = VpGetSign(a);\n    } else if((a->Prec) <(b->Prec)) {\n        val = -VpGetSign(b);\n    }\n\nExit:\n    if  (val> 1) val =  1;\n    else if(val<-1) val = -1;\n\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \" VpComp a=%\\n\", a);\n        VPrint(stdout, \"  b=%\\n\", b);\n        printf(\"  ans=%d\\n\", val);\n    }\n#endif /* _DEBUG */\n    return (int)val;\n}\n\n#ifdef _DEBUG\n/*\n *    cntl_chr ... ASCIIZ Character, print control characters\n *     Available control codes:\n *      %  ... VP variable. To print '%', use '%%'.\n *      \\n ... new line\n *      \\b ... backspace\n *           ... tab\n *     Note: % must must not appear more than once\n *    a  ... VP variable to be printed\n */\nVP_EXPORT int\nVPrint(FILE *fp, char *cntl_chr, Real *a)\n{\n    U_LONG i, j, nc, nd, ZeroSup;\n    U_LONG n, m, e, nn;\n\n    /* Check if NaN & Inf. */\n    if(VpIsNaN(a)) {\n        fprintf(fp,SZ_NaN);\n        return 8;\n    }\n    if(VpIsPosInf(a)) {\n        fprintf(fp,SZ_INF);\n        return 8;\n    }\n    if(VpIsNegInf(a)) {\n        fprintf(fp,SZ_NINF);\n        return 9;\n    }\n    if(VpIsZero(a)) {\n        fprintf(fp,\"0.0\");\n        return 3;\n    }\n\n    j = 0;\n    nd = nc = 0;        /*  nd : number of digits in fraction part(every 10 digits, */\n    /*    nd<=10). */\n    /*  nc : number of caracters printed  */\n    ZeroSup = 1;        /* Flag not to print the leading zeros as 0.00xxxxEnn */\n    while(*(cntl_chr + j)) {\n        if((*(cntl_chr + j) == '%') &&(*(cntl_chr + j + 1) != '%')) {\n         nc = 0;\n         if(!VpIsZero(a)) {\n                if(VpGetSign(a) < 0) {\n                    fprintf(fp, \"-\");\n                    ++nc;\n                }\n                nc += fprintf(fp, \"0.\");\n                n = a->Prec;\n                for(i=0;i < n;++i) {\n\t\t    m = BASE1;\n                    e = a->frac[i];\n                    while(m) {\n                        nn = e / m;\n                        if((!ZeroSup) || nn) {\n                            nc += fprintf(fp, \"%lu\", nn);    /* The reading zero(s) */\n                            /* as 0.00xx will not */\n                            /* be printed. */\n                            ++nd;\n                            ZeroSup = 0;    /* Set to print succeeding zeros */\n                        }\n                        if(nd >= 10) {    /* print ' ' after every 10 digits */\n                            nd = 0;\n                            nc += fprintf(fp, \" \");\n                        }\n                        e = e - nn * m;\n                        m /= 10;\n                    }\n                }\n                nc += fprintf(fp, \"E%ld\", VpExponent10(a));\n            } else {\n                nc += fprintf(fp, \"0.0\");\n            }\n        } else {\n            ++nc;\n            if(*(cntl_chr + j) == '\\\\') {\n                switch(*(cntl_chr + j + 1)) {\n                case 'n':\n                    fprintf(fp, \"\\n\");\n                    ++j;\n                    break;\n                case 't':\n                    fprintf(fp, \"\\t\");\n                    ++j;\n                 break;\n                case 'b':\n                    fprintf(fp, \"\\n\");\n                    ++j;\n                    break;\n                default:\n                    fprintf(fp, \"%c\", *(cntl_chr + j));\n                    break;\n                }\n            } else {\n                fprintf(fp, \"%c\", *(cntl_chr + j));\n                if(*(cntl_chr + j) == '%') ++j;\n            }\n        }\n        j++;\n    }\n    return (int)nc;\n}\n#endif /* _DEBUG */\n\nstatic void\nVpFormatSt(char *psz,S_INT fFmt)\n{\n    U_LONG ie;\n    U_LONG i;\n    S_INT nf = 0;\n    char ch;\n\n    if(fFmt<=0) return;\n\n    ie = strlen(psz);\n    for(i = 0; i < ie; ++i) {\n        ch = psz[i];\n        if(!ch) break;\n        if(ISSPACE(ch) || ch=='-' || ch=='+') continue;\n        if(ch == '.')                { nf = 0;continue;}\n        if(ch == 'E') break;\n        nf++;\n        if(nf > fFmt) {\n            memmove(psz + i + 1, psz + i, ie - i + 1);\n            ++ie;\n            nf = 0;\n            psz[i] = ' ';\n        }\n    }\n}\n\nVP_EXPORT S_LONG\nVpExponent10(Real *a)\n{\n    S_LONG ex;\n    U_LONG n;\n\n    if(!VpHasVal(a)) return 0;\n\n    ex =(a->exponent) * BASE_FIG;\n    n = BASE1;\n    while((a->frac[0] / n) == 0) {\n         --ex;\n         n /= 10;\n    }\n    return ex;\n}\n\nVP_EXPORT void\nVpSzMantissa(Real *a,char *psz)\n{\n    U_LONG i, ZeroSup;\n    U_LONG n, m, e, nn;\n\n    if(VpIsNaN(a)) {\n        sprintf(psz,SZ_NaN);\n        return;\n    }\n    if(VpIsPosInf(a)) {\n        sprintf(psz,SZ_INF);\n        return;\n    }\n    if(VpIsNegInf(a)) {\n        sprintf(psz,SZ_NINF);\n        return;\n    }\n\n    ZeroSup = 1;        /* Flag not to print the leading zeros as 0.00xxxxEnn */\n    if(!VpIsZero(a)) {\n        if(VpGetSign(a) < 0) *psz++ = '-';\n        n = a->Prec;\n        for(i=0;i < n;++i) {\n            m = BASE1;\n            e = a->frac[i];\n            while(m) {\n                nn = e / m;\n                if((!ZeroSup) || nn) {\n                    sprintf(psz, \"%lu\", nn);    /* The reading zero(s) */\n                    psz += strlen(psz);\n                    /* as 0.00xx will be ignored. */\n                    ZeroSup = 0;    /* Set to print succeeding zeros */\n                }\n                e = e - nn * m;\n                m /= 10;\n            }\n        }\n        *psz = 0;\n        while(psz[-1]=='0') *(--psz) = 0;\n    } else {\n        if(VpIsPosZero(a)) sprintf(psz, \"0\");\n        else      sprintf(psz, \"-0\");\n    }\n}\n\nVP_EXPORT int\nVpToSpecialString(Real *a,char *psz,int fPlus)\n/* fPlus =0:default, =1: set ' ' before digits , =2: set '+' before digits. */\n{\n    if(VpIsNaN(a)) {\n        sprintf(psz,SZ_NaN);\n        return 1;\n    }\n\n    if(VpIsPosInf(a)) {\n        if(fPlus==1) {\n           *psz++ = ' ';\n        } else if(fPlus==2) {\n           *psz++ = '+';\n        }\n        sprintf(psz,SZ_INF);\n        return 1;\n    }\n    if(VpIsNegInf(a)) {\n        sprintf(psz,SZ_NINF);\n        return 1;\n    }\n    if(VpIsZero(a)) {\n        if(VpIsPosZero(a)) {\n            if(fPlus==1)      sprintf(psz, \" 0.0\");\n            else if(fPlus==2) sprintf(psz, \"+0.0\");\n            else              sprintf(psz, \"0.0\");\n        } else    sprintf(psz, \"-0.0\");\n        return 1;\n    }\n    return 0;\n}\n\nVP_EXPORT void\nVpToString(Real *a,char *psz,int fFmt,int fPlus)\n/* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */\n{\n    U_LONG i, ZeroSup;\n    U_LONG n, m, e, nn;\n    char *pszSav = psz;\n    S_LONG ex;\n\n    if(VpToSpecialString(a,psz,fPlus)) return;\n\n    ZeroSup = 1;    /* Flag not to print the leading zeros as 0.00xxxxEnn */\n\n    if(VpGetSign(a) < 0) *psz++ = '-';\n    else if(fPlus==1)    *psz++ = ' ';\n    else if(fPlus==2)    *psz++ = '+';\n\n    *psz++ = '0';\n    *psz++ = '.';\n    n = a->Prec;\n    for(i=0;i < n;++i) {\n        m = BASE1;\n        e = a->frac[i];\n        while(m) {\n            nn = e / m;\n            if((!ZeroSup) || nn) {\n                sprintf(psz, \"%lu\", nn);    /* The reading zero(s) */\n                psz += strlen(psz);\n                /* as 0.00xx will be ignored. */\n                ZeroSup = 0;    /* Set to print succeeding zeros */\n            }\n            e = e - nn * m;\n            m /= 10;\n        }\n    }\n    ex =(a->exponent) * BASE_FIG;\n    n = BASE1;\n    while((a->frac[0] / n) == 0) {\n        --ex;\n        n /= 10;\n    }\n    while(psz[-1]=='0') *(--psz) = 0;\n    sprintf(psz, \"E%ld\", ex);\n    if(fFmt) VpFormatSt(pszSav, fFmt);\n}\n\nVP_EXPORT void\nVpToFString(Real *a,char *psz,int fFmt,int fPlus)\n/* fPlus =0:default,=1: set ' ' before digits ,set '+' before digits. */\n{\n    U_LONG i;\n    U_LONG n, m, e, nn;\n    char *pszSav = psz;\n    S_LONG ex;\n\n    if(VpToSpecialString(a,psz,fPlus)) return;\n\n    if(VpGetSign(a) < 0) *psz++ = '-';\n    else if(fPlus==1)    *psz++ = ' ';\n    else if(fPlus==2)    *psz++ = '+';\n\n    n  = a->Prec;\n    ex = a->exponent;\n    if(ex<=0) {\n       *psz++ = '0';*psz++ = '.';\n       while(ex<0) {\n          for(i=0;i<BASE_FIG;++i) *psz++ = '0';\n          ++ex;\n       }\n       ex = -1;\n    }\n\n    for(i=0;i < n;++i) {\n       --ex;\n       if(i==0 && ex >= 0) {\n           sprintf(psz, \"%lu\", a->frac[i]);\n           psz += strlen(psz);\n       } else {\n           m = BASE1;\n           e = a->frac[i];\n           while(m) {\n               nn = e / m;\n               *psz++ = (char)(nn + '0');\n               e = e - nn * m;\n               m /= 10;\n           }\n       }\n       if(ex == 0) *psz++ = '.';\n    }\n    while(--ex>=0) {\n       m = BASE;\n       while(m/=10) *psz++ = '0';\n       if(ex == 0) *psz++ = '.';\n    }\n    *psz = 0;\n    while(psz[-1]=='0') *(--psz) = 0;\n    if(psz[-1]=='.') sprintf(psz, \"0\");\n    if(fFmt) VpFormatSt(pszSav, fFmt);\n}\n\n/*\n *  [Output]\n *   a[]  ... variable to be assigned the value.\n *  [Input]\n *   int_chr[]  ... integer part(may include '+/-').\n *   ni   ... number of characters in int_chr[],not including '+/-'.\n *   frac[]  ... fraction part.\n *   nf   ... number of characters in frac[].\n *   exp_chr[]  ... exponent part(including '+/-').\n *   ne   ... number of characters in exp_chr[],not including '+/-'.\n */\nVP_EXPORT int\nVpCtoV(Real *a, const char *int_chr, U_LONG ni, const char *frac, U_LONG nf, const char *exp_chr, U_LONG ne)\n{\n    U_LONG i, j, ind_a, ma, mi, me;\n    U_LONG loc;\n    S_INT  e,es, eb, ef;\n    S_INT  sign, signe;\n    /* get exponent part */\n    e = 0;\n    ma = a->MaxPrec;\n    mi = ni;\n    me = ne;\n    signe = 1;\n    memset(a->frac, 0, ma * sizeof(U_LONG));\n    if(ne > 0) {\n        i = 0;\n        if(exp_chr[0] == '-') {\n            signe = -1;\n            ++i;\n            ++me;\n        } else if(exp_chr[0] == '+') {\n            ++i;\n            ++me;\n        }\n        while(i < me) {\n            es = e*((S_INT)BASE_FIG);\n            e = e * 10 + exp_chr[i] - '0';\n            if(es>e*((S_INT)BASE_FIG)) {\n                return VpException(VP_EXCEPTION_INFINITY,\"exponent overflow\",0);\n            }\n            ++i;\n        }\n    }\n\n    /* get integer part */\n    i = 0;\n    sign = 1;\n    if(ni >= 0) {\n        if(int_chr[0] == '-') {\n            sign = -1;\n            ++i;\n            ++mi;\n        } else if(int_chr[0] == '+') {\n            ++i;\n            ++mi;\n        }\n    }\n\n    e = signe * e;        /* e: The value of exponent part. */\n    e = e + ni;        /* set actual exponent size. */\n\n    if(e > 0)    signe = 1;\n    else        signe = -1;\n\n    /* Adjust the exponent so that it is the multiple of BASE_FIG. */\n    j = 0;\n    ef = 1;\n    while(ef) {\n        if(e>=0) eb =  e;\n        else  eb = -e;\n        ef = eb / ((S_INT)BASE_FIG);\n        ef = eb - ef * ((S_INT)BASE_FIG);\n        if(ef) {\n            ++j;        /* Means to add one more preceeding zero */\n            ++e;\n        }\n    }\n\n    eb = e / ((S_INT)BASE_FIG);\n\n    ind_a = 0;\n    while(i < mi) {\n        a->frac[ind_a] = 0;\n        while((j < (U_LONG)BASE_FIG) &&(i < mi)) {\n            a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0';\n            ++j;\n            ++i;\n        }\n        if(i < mi) {\n            ++ind_a;\n            if(ind_a >= ma) goto over_flow;\n            j = 0;\n        }\n    }\n    loc = 1;\n\n    /* get fraction part */\n\n    i = 0;\n    while(i < nf) {\n        while((j < (U_LONG)BASE_FIG) &&(i < nf)) {\n            a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0';\n            ++j;\n            ++i;\n        }\n        if(i < nf) {\n            ++ind_a;\n            if(ind_a >= ma) goto over_flow;\n            j = 0;\n        }\n    }\n    goto Final;\n\nover_flow:\n    rb_warn(\"Conversion from String to BigDecimal overflow (last few digits discarded).\");\n\nFinal:\n    if(ind_a >= ma) ind_a = ma - 1;\n    while(j < (U_LONG)BASE_FIG) {\n        a->frac[ind_a] = a->frac[ind_a] * 10;\n        ++j;\n    }\n    a->Prec = ind_a + 1;\n    a->exponent = eb;\n    VpSetSign(a,sign);\n    VpNmlz(a);\n    return 1;\n}\n\n/*\n * [Input]\n *   *m  ... Real\n * [Output]\n *   *d  ... fraction part of m(d = 0.xxxxxxx). where # of 'x's is fig.\n *   *e  ... U_LONG,exponent of m.\n * DBLE_FIG ... Number of digits in a double variable.\n *\n *  m -> d*10**e, 0<d<BASE\n * [Returns]\n *   0 ... Zero\n *   1 ... Normal\n *   2 ... Infinity\n *  -1 ... NaN\n */\nVP_EXPORT int\nVpVtoD(double *d, S_LONG *e, Real *m)\n{\n    U_LONG ind_m, mm, fig;\n    double div;\n    int    f = 1;\n\n    if(VpIsNaN(m)) {\n        *d = VpGetDoubleNaN();\n        *e = 0;\n        f = -1; /* NaN */\n        goto Exit;\n    } else\n    if(VpIsPosZero(m)) {\n        *d = 0.0;\n        *e = 0;\n        f  = 0;\n        goto Exit;\n    } else\n    if(VpIsNegZero(m)) {\n        *d = VpGetDoubleNegZero();\n        *e = 0;\n        f  = 0;\n        goto Exit;\n    } else\n    if(VpIsPosInf(m)) {\n        *d = VpGetDoublePosInf();\n        *e = 0;\n        f  = 2;\n        goto Exit;\n    } else\n    if(VpIsNegInf(m)) {\n        *d = VpGetDoubleNegInf();\n        *e = 0;\n        f  = 2;\n        goto Exit;\n    }\n    /* Normal number */\n    fig =(DBLE_FIG + BASE_FIG - 1) / BASE_FIG;\n    ind_m = 0;\n    mm = Min(fig,(m->Prec));\n    *d = 0.0;\n    div = 1.;\n    while(ind_m < mm) {\n        div /=(double)((S_INT)BASE);\n        *d = *d +((double) ((S_INT)m->frac[ind_m++])) * div;\n    }\n    *e = m->exponent * ((S_INT)BASE_FIG);\n    *d *= VpGetSign(m);\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \" VpVtoD: m=%\\n\", m);\n        printf(\"   d=%e * 10 **%ld\\n\", *d, *e);\n        printf(\"   DBLE_FIG = %ld\\n\", DBLE_FIG);\n    }\n#endif /*_DEBUG */\n    return f;\n}\n\n/*\n * m <- d\n */\nVP_EXPORT void\nVpDtoV(Real *m, double d)\n{\n    U_LONG i, ind_m, mm;\n    U_LONG ne;\n    double  val, val2;\n\n    if(isnan(d)) {\n        VpSetNaN(m);\n        goto Exit;\n    }\n    if(isinf(d)) {\n        if(d>0.0) VpSetPosInf(m);\n        else   VpSetNegInf(m);\n        goto Exit;\n    }\n\n    if(d == 0.0) {\n        VpSetZero(m,1);\n        goto Exit;\n    }\n    val =(d > 0.) ? d :(-d);\n    ne = 0;\n    if(val >= 1.0) {\n        while(val >= 1.0) {\n            val /=(double)((S_INT)BASE);\n            ++ne;\n        }\n    } else {\n        val2 = 1.0 /(double)((S_INT)BASE);\n        while(val < val2) {\n            val *=(double)((S_INT)BASE);\n            --ne;\n        }\n    }\n    /* Now val = 0.xxxxx*BASE**ne */\n\n    mm = m->MaxPrec;\n    memset(m->frac, 0, mm * sizeof(U_LONG));\n    for(ind_m = 0;val > 0.0 && ind_m < mm;ind_m++) {\n        val *=(double)((S_INT)BASE);\n        i =(U_LONG) val;\n        val -=(double)((S_INT)i);\n        m->frac[ind_m] = i;\n    }\n    if(ind_m >= mm) ind_m = mm - 1;\n    if(d > 0.0) {\n        VpSetSign(m, (S_INT)1);\n    } else {\n        VpSetSign(m,-(S_INT)1);\n    }\n    m->Prec = ind_m + 1;\n    m->exponent = ne;\n\n    VpInternalRound(m,0,(m->Prec>0)?m->frac[m->Prec-1]:0,\n                      (U_LONG)(val*((double)((S_INT)BASE))));\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        printf(\"VpDtoV d=%30.30e\\n\", d);\n        VPrint(stdout, \"  m=%\\n\", m);\n    }\n#endif /* _DEBUG */\n    return;\n}\n\n/*\n *  m <- ival\n */\nVP_EXPORT void\nVpItoV(Real *m, S_INT ival)\n{\n    U_LONG mm, ind_m;\n    U_LONG val, v1, v2, v;\n    int isign;\n    S_INT ne;\n\n    if(ival == 0) {\n        VpSetZero(m,1);\n        goto Exit;\n    }\n    isign = 1;\n    val = ival;\n    if(ival < 0) {\n        isign = -1;\n        val =(U_LONG)(-ival);\n    }\n    ne = 0;\n    ind_m = 0;\n    mm = m->MaxPrec;\n    while(ind_m < mm) {\n        m->frac[ind_m] = 0;\n        ++ind_m;\n    }\n    ind_m = 0;\n    while(val > 0) {\n        if(val) {\n         v1 = val;\n         v2 = 1;\n            while(v1 >= BASE) {\n                v1 /= BASE;\n                v2 *= BASE;\n            }\n            val = val - v2 * v1;\n            v = v1;\n        } else {\n            v = 0;\n        }\n        m->frac[ind_m] = v;\n        ++ind_m;\n        ++ne;\n    }\n    m->Prec = ind_m - 1;\n    m->exponent = ne;\n    VpSetSign(m,isign);\n    VpNmlz(m);\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        printf(\" VpItoV i=%d\\n\", ival);\n        VPrint(stdout, \"  m=%\\n\", m);\n    }\n#endif /* _DEBUG */\n    return;\n}\n\n/*\n * y = SQRT(x),  y*y - x =>0\n */\nVP_EXPORT int\nVpSqrt(Real *y, Real *x)\n{\n    Real *f = NULL;\n    Real *r = NULL;\n    S_LONG y_prec, f_prec;\n    S_LONG n;\n    S_LONG e;\n    S_LONG prec;\n    S_LONG nr;\n    double val;\n\n    /* Zero, NaN or Infinity ? */\n    if(!VpHasVal(x)) {\n        if(VpIsZero(x)||VpGetSign(x)>0) {\n            VpAsgn(y,x,1);\n            goto Exit;\n        }\n        VpSetNaN(y);\n        return VpException(VP_EXCEPTION_OP,\"(VpSqrt) SQRT(NaN or negative value)\",0);\n        goto Exit;\n    }\n\n     /* Negative ? */\n    if(VpGetSign(x) < 0) {\n        VpSetNaN(y);\n        return VpException(VP_EXCEPTION_OP,\"(VpSqrt) SQRT(negative value)\",0);\n    }\n\n    /* One ? */\n    if(VpIsOne(x)) {\n        VpSetOne(y);\n        goto Exit;\n    }\n\n    n = (S_LONG)y->MaxPrec;\n    if((S_LONG)x->MaxPrec > n) n = (S_LONG)x->MaxPrec;\n    /* allocate temporally variables  */\n    f = VpAlloc(y->MaxPrec *(BASE_FIG + 2), \"#1\");\n    r = VpAlloc((n + n) *(BASE_FIG + 2), \"#1\");\n\n    nr = 0;\n    y_prec = (S_LONG)y->MaxPrec;\n    f_prec = (S_LONG)f->MaxPrec;\n\n    prec = x->exponent;\n    if(prec > 0)    ++prec;\n    else            --prec;\n    prec = prec - (S_LONG)y->MaxPrec;\n    VpVtoD(&val, &e, x);    /* val <- x  */\n    e /= ((S_LONG)BASE_FIG);\n    n = e / 2;\n    if(e - n * 2 != 0) {\n        val /=(double)((S_INT)BASE);\n        n =(e + 1) / 2;\n    }\n    VpDtoV(y, sqrt(val));    /* y <- sqrt(val) */\n    y->exponent += n;\n    n = (DBLE_FIG + BASE_FIG - 1) / BASE_FIG;\n    y->MaxPrec = (U_LONG)Min(n , y_prec);\n    f->MaxPrec = y->MaxPrec + 1;\n    n = y_prec*((S_LONG)BASE_FIG);\n    if((U_LONG)n<maxnr) n = (U_LONG)maxnr;\n    do {\n        y->MaxPrec *= 2;\n        if(y->MaxPrec > (U_LONG)y_prec) y->MaxPrec = (U_LONG)y_prec;\n        f->MaxPrec = y->MaxPrec;\n        VpDivd(f, r, x, y);     /* f = x/y    */\n        VpAddSub(r, f, y, -1);  /* r = f - y  */\n        VpMult(f, VpPt5, r);    /* f = 0.5*r  */\n        if(VpIsZero(f))         goto converge;\n        VpAddSub(r, f, y, 1);   /* r = y + f  */\n        VpAsgn(y, r, 1);        /* y = r      */\n        if(f->exponent <= prec) goto converge;\n    } while(++nr < n);\n    /* */\n#ifdef _DEBUG\n    if(gfDebug) {\n        printf(\"ERROR(VpSqrt): did not converge within %ld iterations.\\n\",\n            nr);\n    }\n#endif /* _DEBUG */\n    y->MaxPrec = y_prec;\n\nconverge:\n    VpChangeSign(y,(S_INT)1);\n#ifdef _DEBUG\n    if(gfDebug) {\n        VpMult(r, y, y);\n        VpAddSub(f, x, r, -1);\n        printf(\"VpSqrt: iterations = %lu\\n\", nr);\n        VPrint(stdout, \"  y =% \\n\", y);\n        VPrint(stdout, \"  x =% \\n\", x);\n        VPrint(stdout, \"  x-y*y = % \\n\", f);\n    }\n#endif /* _DEBUG */\n    y->MaxPrec = y_prec;\n\nExit:\n    VpFree(f);\n    VpFree(r);\n    return 1;\n}\n\n/*\n *\n * f = 0: Round off/Truncate, 1: round up, 2:ceil, 3: floor, 4: Banker's rounding\n * nf: digit position for operation.\n *\n */\nVP_EXPORT int\nVpMidRound(Real *y, int f, int nf)\n/*\n * Round reletively from the decimal point.\n *    f: rounding mode\n *   nf: digit location to round from the the decimal point.\n */\n{\n    /* fracf: any positive digit under rounding position? */\n    /* exptoadd: number of digits needed to compensate negative nf */\n    int n,i,ix,ioffset,fracf,exptoadd;\n    U_LONG v,shifter;\n    U_LONG div;\n\n    nf += y->exponent*((int)BASE_FIG);\n    exptoadd=0;\n    if (nf < 0) {\n\t/* rounding position too left(large). */\n\tif((f!=VP_ROUND_CEIL) && (f!=VP_ROUND_FLOOR)) {\n\t    VpSetZero(y,VpGetSign(y)); /* truncate everything */\n\t    return 0;\n\t}\n        exptoadd = -nf;\n        nf = 0;\n    }\n    /* ix: x->fraq[ix] contains round position */\n    ix = nf/(int)BASE_FIG;\n    if(((U_LONG)ix)>=y->Prec) return 0; /* Unable to round */\n    ioffset = nf - ix*((int)BASE_FIG);\n\n    v = y->frac[ix];\n    /* drop digits after pointed digit */\n    n = BASE_FIG - ioffset - 1;\n    for(shifter=1,i=0;i<n;++i) shifter *= 10;\n    fracf = (v%(shifter*10) > 0);\n    v /= shifter;\n    div = v/10;\n    v = v - div*10;\n    if (fracf == 0) {\n        for(i=ix+1;i<y->Prec;i++) {\n            if (y->frac[i]%BASE) {\n                fracf = 1;\n                break;\n            }\n        }\n    }\n    memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(U_LONG));\n    switch(f) {\n    case VP_ROUND_DOWN: /* Truncate */\n         break;\n    case VP_ROUND_UP:   /* Roundup */\n        if(fracf) ++div;\n         break;\n    case VP_ROUND_HALF_UP:   /* Round half up  */\n        if(v>=5) ++div;\n        break;\n    case VP_ROUND_HALF_DOWN: /* Round half down  */\n        if(v>=6) ++div;\n        break;\n    case VP_ROUND_CEIL: /* ceil */\n        if(fracf && (VpGetSign(y)>0)) ++div;\n        break;\n    case VP_ROUND_FLOOR: /* floor */\n        if(fracf && (VpGetSign(y)<0)) ++div;\n        break;\n    case VP_ROUND_HALF_EVEN: /* Banker's rounding */\n        if(v>5) ++div;\n        else if(v==5) {\n            if((U_LONG)i==(BASE_FIG-1)) {\n                if(ix && (y->frac[ix-1]%2)) ++div;\n            } else {\n                if(div%2) ++div;\n            }\n        }\n        break;\n    }\n    for(i=0;i<=n;++i) div *= 10;\n    if(div>=BASE) {\n        if(ix) {\n            y->frac[ix] = 0;\n            VpRdup(y,ix);\n        } else {\n            S_INT s = VpGetSign(y);\n            int e = y->exponent;\n            VpSetOne(y);\n            VpSetSign(y,s);\n            y->exponent = e+1;\n        }\n    } else {\n        y->frac[ix] = div;\n        VpNmlz(y);\n    }\n    if (exptoadd > 0) {\n        y->exponent += exptoadd/BASE_FIG;\n        exptoadd %= BASE_FIG;\n        for(i=0;i<exptoadd;i++) {\n            y->frac[0] *= 10;\n            if (y->frac[0] >= BASE) {\n                y->frac[0] /= BASE;\n                y->exponent++;\n            }\n        }\n    }\n    return 1;\n}\n\nVP_EXPORT int\nVpLeftRound(Real *y, int f, int nf)\n/*\n * Round from the left hand side of the digits.\n */\n{\n    U_LONG v;\n    if(!VpHasVal(y)) return 0; /* Unable to round */\n    v = y->frac[0];\n    nf -= VpExponent(y)*BASE_FIG;\n    while((v /= 10) != 0) nf--;\n    nf += (BASE_FIG-1);\n    return VpMidRound(y,f,nf);\n}\n\nVP_EXPORT int \nVpActiveRound(Real *y, Real *x, int f, int nf)\n{\n    /* First,assign whole value in truncation mode */\n    if(VpAsgn(y, x, 10)<=1) return 0; /* Zero,NaN,or Infinity */\n    return VpMidRound(y,f,nf);\n}\n\nstatic int\nVpLimitRound(Real *c,U_LONG ixDigit)\n{\n    U_LONG ix = VpGetPrecLimit();\n    if(!VpNmlz(c))    return -1;\n    if(!ix)           return 0;\n    if(!ixDigit) ixDigit = c->Prec-1;\n    if((ix+BASE_FIG-1)/BASE_FIG > ixDigit+1) return 0;\n    return VpLeftRound(c,VpGetRoundMode(),ix);\n}\n\nstatic void \nVpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v)\n{\n    int f = 0;\n\n    if(VpLimitRound(c,ixDigit)) return;\n    if(!v)                      return;\n\n    v /= BASE1;\n    switch(gfRoundMode) {\n    case VP_ROUND_DOWN:\n        break;\n    case VP_ROUND_UP:\n        if(v)                    f = 1;\n        break;\n    case VP_ROUND_HALF_UP:\n        if(v >= 5)               f = 1;\n        break;\n    case VP_ROUND_HALF_DOWN:\n        if(v >= 6)               f = 1;\n        break;\n    case VP_ROUND_CEIL:  /* ceil */\n        if(v && (VpGetSign(c)>0)) f = 1;\n        break;\n    case VP_ROUND_FLOOR: /* floor */\n        if(v && (VpGetSign(c)<0)) f = 1;\n        break;\n    case VP_ROUND_HALF_EVEN:  /* Banker's rounding */\n        if(v>5) f = 1;\n        else if(v==5 && vPrev%2)  f = 1;\n        break;\n    }\n    if(f) {\n        VpRdup(c,ixDigit);    /* round up */\n        VpNmlz(c);\n    }\n}\n\n/*\n *  Rounds up m(plus one to final digit of m).\n */\nstatic int\nVpRdup(Real *m,U_LONG ind_m)\n{\n    U_LONG carry;\n\n    if(!ind_m) ind_m = m->Prec;\n\n    carry = 1;\n    while(carry > 0 && (ind_m--)) {\n        m->frac[ind_m] += carry;\n        if(m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE;\n        else                       carry = 0;\n    }\n    if(carry > 0) {        /* Overflow,count exponent and set fraction part be 1  */\n        if(!AddExponent(m,(S_LONG)1)) return 0;\n        m->Prec = m->frac[0] = 1;\n    } else {\n        VpNmlz(m);\n    }\n    return 1;\n}\n\n/*\n *  y = x - fix(x)\n */\nVP_EXPORT void\nVpFrac(Real *y, Real *x)\n{\n    U_LONG my, ind_y, ind_x;\n\n    if(!VpHasVal(x)) {\n        VpAsgn(y,x,1);\n        goto Exit;\n    }\n\n    if(x->exponent > 0 && (U_LONG)x->exponent >= x->Prec) {\n        VpSetZero(y,VpGetSign(x));\n        goto Exit;\n    } else if(x->exponent <= 0) {\n        VpAsgn(y, x, 1);\n        goto Exit;\n    }\n\n    y->Prec = x->Prec -(U_LONG) x->exponent;\n    y->Prec = Min(y->Prec, y->MaxPrec);\n    y->exponent = 0;\n    VpSetSign(y,VpGetSign(x));\n    ind_y = 0;\n    my = y->Prec;\n    ind_x = x->exponent;\n    while(ind_y < my) {\n        y->frac[ind_y] = x->frac[ind_x];\n        ++ind_y;\n        ++ind_x;\n    }\n    VpNmlz(y);\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpFrac y=%\\n\", y);\n        VPrint(stdout, \"    x=%\\n\", x);\n    }\n#endif /* _DEBUG */\n    return;\n}\n\n/*\n *   y = x ** n\n */\nVP_EXPORT int\nVpPower(Real *y, Real *x, S_INT n)\n{\n    U_LONG s, ss;\n    S_LONG sign;\n    Real *w1 = NULL;\n    Real *w2 = NULL;\n\n    if(VpIsZero(x)) {\n        if(n==0) {\n           VpSetOne(y);\n           goto Exit;\n        }\n        sign = VpGetSign(x);\n        if(n<0) {\n           n = -n;\n           if(sign<0) sign = (n%2)?(-1):(1);\n           VpSetInf (y,sign);\n        } else {\n           if(sign<0) sign = (n%2)?(-1):(1);\n           VpSetZero(y,sign);\n        }\n        goto Exit;\n    }\n    if(!VpIsDef(x)) {\n        VpSetNaN(y); /* Not sure !!! */\n        goto Exit;\n    }\n\n    if((x->exponent == 1) &&(x->Prec == 1) &&(x->frac[0] == 1)) {\n        /* abs(x) = 1 */\n        VpSetOne(y);\n        if(VpGetSign(x) > 0) goto Exit;\n        if((n % 2) == 0) goto Exit;\n        VpSetSign(y,-(S_INT)1);\n        goto Exit;\n    }\n\n    if(n > 0) sign = 1;\n    else if(n < 0) {\n        sign = -1;\n        n = -n;\n    } else {\n        VpSetOne(y);\n        goto Exit;\n    }\n\n    /* Allocate working variables  */\n\n    w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, \"#0\");\n    w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, \"#0\");\n    /* calculation start */\n\n    VpAsgn(y, x, 1);\n    --n;\n    while(n > 0) {\n        VpAsgn(w1, x, 1);\n        s = 1;\nloop1:  ss = s;\n        s += s;\n        if(s >(U_LONG) n) goto out_loop1;\n        VpMult(w2, w1, w1);\n        VpAsgn(w1, w2, 1);\n        goto loop1;\nout_loop1:\n        n -= ss;\n        VpMult(w2, y, w1);\n        VpAsgn(y, w2, 1);\n    }\n    if(sign < 0) {\n        VpDivd(w1, w2, VpConstOne, y);\n        VpAsgn(y, w1, 1);\n    }\n\nExit:\n#ifdef _DEBUG\n    if(gfDebug) {\n        VPrint(stdout, \"VpPower y=%\\n\", y);\n        VPrint(stdout, \"VpPower x=%\\n\", x);\n        printf(\"  n=%d\\n\", n);\n    }\n#endif /* _DEBUG */\n    VpFree(w2);\n    VpFree(w1);\n    return 1;\n}\n\n#ifdef _DEBUG\nint\nVpVarCheck(Real * v)\n/*\n * Checks the validity of the Real variable v.\n * [Input]\n *   v ... Real *, variable to be checked.\n * [Returns]\n *   0  ... correct v.\n *   other ... error\n */\n{\n    U_LONG i;\n\n    if(v->MaxPrec <= 0) {\n        printf(\"ERROR(VpVarCheck): Illegal Max. Precision(=%lu)\\n\",\n            v->MaxPrec);\n        return 1;\n    }\n    if((v->Prec <= 0) ||((v->Prec) >(v->MaxPrec))) {\n        printf(\"ERROR(VpVarCheck): Illegal Precision(=%lu)\\n\", v->Prec);\n        printf(\"       Max. Prec.=%lu\\n\", v->MaxPrec);\n        return 2;\n    }\n    for(i = 0; i < v->Prec; ++i) {\n        if((v->frac[i] >= BASE)) {\n            printf(\"ERROR(VpVarCheck): Illegal fraction\\n\");\n            printf(\"       Frac[%ld]=%lu\\n\", i, v->frac[i]);\n            printf(\"       Prec.   =%lu\\n\", v->Prec);\n            printf(\"       Exp. =%d\\n\", v->exponent);\n            printf(\"       BASE =%lu\\n\", BASE);\n            return 3;\n        }\n    }\n    return 0;\n}\n#endif /* _DEBUG */\n"
  },
  {
    "path": "ext/bigdecimal/bigdecimal.def",
    "content": "EXPORTS\nInit_bigdecimal\n"
  },
  {
    "path": "ext/bigdecimal/bigdecimal.h",
    "content": "/*\n *\n * Ruby BigDecimal(Variable decimal precision) extension library. \n *\n * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) \n *\n * You may distribute under the terms of either the GNU General Public \n * License or the Artistic License, as specified in the README file \n * of this BigDecimal distribution. \n *\n * NOTES:\n *   2003-03-28 V1.0 checked in.\n *\n */\n\n#ifndef  ____BIG_DECIMAL__H____\n#define  ____BIG_DECIMAL__H____\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n *  NaN & Infinity\n */\n#define SZ_NaN  \"NaN\"\n#define SZ_INF  \"Infinity\"\n#define SZ_PINF \"+Infinity\"\n#define SZ_NINF \"-Infinity\"\n\n/*\n *   #define VP_EXPORT other than static to let VP_ routines \n *   be called from outside of this module.\n */\n#define VP_EXPORT static \n\n#define U_LONG unsigned long\n#define S_LONG long\n#define U_INT  unsigned int\n#define S_INT  int\n\n/* Exception codes */\n#define VP_EXCEPTION_ALL        ((unsigned short)0x00FF)\n#define VP_EXCEPTION_INFINITY   ((unsigned short)0x0001)\n#define VP_EXCEPTION_NaN        ((unsigned short)0x0002)\n#define VP_EXCEPTION_UNDERFLOW  ((unsigned short)0x0004)\n#define VP_EXCEPTION_OVERFLOW   ((unsigned short)0x0001) /* 0x0008) */\n#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0001) /* 0x0010) */\n\n/* Following 2 exceptions cann't controlled by user */\n#define VP_EXCEPTION_OP         ((unsigned short)0x0020)\n#define VP_EXCEPTION_MEMORY     ((unsigned short)0x0040)\n\n/* Computation mode */\n#define VP_ROUND_MODE            ((unsigned short)0x0100)\n#define VP_ROUND_UP         1\n#define VP_ROUND_DOWN       2\n#define VP_ROUND_HALF_UP    3\n#define VP_ROUND_HALF_DOWN  4\n#define VP_ROUND_CEIL       5\n#define VP_ROUND_FLOOR      6\n#define VP_ROUND_HALF_EVEN  7\n\n#define VP_SIGN_NaN                0 /* NaN                      */\n#define VP_SIGN_POSITIVE_ZERO      1 /* Positive zero            */\n#define VP_SIGN_NEGATIVE_ZERO     -1 /* Negative zero            */\n#define VP_SIGN_POSITIVE_FINITE    2 /* Positive finite number   */\n#define VP_SIGN_NEGATIVE_FINITE   -2 /* Negative finite number   */\n#define VP_SIGN_POSITIVE_INFINITE  3 /* Positive infinite number */\n#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */\n\n/*\n * VP representation\n *  r = 0.xxxxxxxxx *BASE**exponent\n */\ntypedef struct {\n    VALUE  obj;     /* Back pointer(VALUE) for Ruby object.     */\n    U_LONG MaxPrec; /* Maximum precision size                   */\n                    /* This is the actual size of pfrac[]       */\n                    /*(frac[0] to frac[MaxPrec] are available). */\n    U_LONG Prec;    /* Current precision size.                  */\n                    /* This indicates how much the.             */\n                    /* the array frac[] is actually used.       */\n    S_INT  exponent;/* Exponent part.                           */\n    short  sign;    /* Attributes of the value.                 */\n                    /*\n                     *        ==0 : NaN\n                     *          1 : Positive zero\n                     *         -1 : Negative zero\n                     *          2 : Positive number\n                     *         -2 : Negative number\n                     *          3 : Positive infinite number\n                     *         -3 : Negative infinite number\n                     */\n    short  flag;    /* Not used in vp_routines,space for user.  */\n    U_LONG frac[1]; /* Pointer to array of fraction part.       */\n} Real;\n\n/*  \n *  ------------------\n *   EXPORTables.\n *  ------------------\n */\n\nVP_EXPORT  Real *\nVpNewRbClass(U_LONG mx,char *str,VALUE klass);\n\nVP_EXPORT  Real *VpCreateRbObject(U_LONG mx,const char *str);\n\nVP_EXPORT U_LONG VpBaseFig(void);\nVP_EXPORT U_LONG VpDblFig(void);\nVP_EXPORT U_LONG VpBaseVal(void);\n\n/* Zero,Inf,NaN (isinf(),isnan() used to check) */\nVP_EXPORT double VpGetDoubleNaN(void);\nVP_EXPORT double VpGetDoublePosInf(void);\nVP_EXPORT double VpGetDoubleNegInf(void);\nVP_EXPORT double VpGetDoubleNegZero(void);\n\n/* These 2 functions added at v1.1.7 */\nVP_EXPORT U_LONG VpGetPrecLimit(void);\nVP_EXPORT U_LONG VpSetPrecLimit(U_LONG n);\n\n/* Round mode */\nVP_EXPORT int           VpIsRoundMode(unsigned long n);\nVP_EXPORT unsigned long VpGetRoundMode(void);\nVP_EXPORT unsigned long VpSetRoundMode(unsigned long n);\n\nVP_EXPORT int VpException(unsigned short f,const char *str,int always);\nVP_EXPORT int VpIsNegDoubleZero(double v);\nVP_EXPORT U_LONG VpNumOfChars(Real *vp,const char *pszFmt);\nVP_EXPORT U_LONG VpInit(U_LONG BaseVal);\nVP_EXPORT void *VpMemAlloc(U_LONG mb);\nVP_EXPORT void VpFree(Real *pv);\nVP_EXPORT Real *VpAlloc(U_LONG mx, const char *szVal);\nVP_EXPORT int VpAsgn(Real *c,Real *a,int isw);\nVP_EXPORT int VpAddSub(Real *c,Real *a,Real *b,int operation);\nVP_EXPORT int VpMult(Real *c,Real *a,Real *b);\nVP_EXPORT int VpDivd(Real *c,Real *r,Real *a,Real *b);\nVP_EXPORT int VpComp(Real *a,Real *b);\nVP_EXPORT S_LONG VpExponent10(Real *a);\nVP_EXPORT void VpSzMantissa(Real *a,char *psz);\nVP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus);\nVP_EXPORT void VpToString(Real *a,char *psz,int fFmt,int fPlus);\nVP_EXPORT void VpToFString(Real *a,char *psz,int fFmt,int fPlus);\nVP_EXPORT int VpCtoV(Real *a,const char *int_chr,U_LONG ni,const char *frac,U_LONG nf,const char *exp_chr,U_LONG ne);\nVP_EXPORT int VpVtoD(double *d,S_LONG *e,Real *m);\nVP_EXPORT void VpDtoV(Real *m,double d);\nVP_EXPORT void VpItoV(Real *m,S_INT ival);\nVP_EXPORT int VpSqrt(Real *y,Real *x);\nVP_EXPORT int VpActiveRound(Real *y,Real *x,int f,int il);\nVP_EXPORT int VpMidRound(Real *y, int f, int nf);\nVP_EXPORT int VpLeftRound(Real *y, int f, int nf);\nVP_EXPORT void VpFrac(Real *y,Real *x);\nVP_EXPORT int VpPower(Real *y,Real *x,S_INT n);\n\n/* VP constants */\nVP_EXPORT Real *VpOne(void);\n\n/*  \n *  ------------------\n *  MACRO definitions.\n *  ------------------\n */\n#define Abs(a)     (((a)>= 0)?(a):(-(a)))\n#define Max(a, b)  (((a)>(b))?(a):(b))\n#define Min(a, b)  (((a)>(b))?(b):(a))\n\n#define VpMaxPrec(a)   ((a)->MaxPrec)\n#define VpPrec(a)      ((a)->Prec)\n#define VpGetFlag(a)   ((a)->flag)\n\n/* Sign */\n\n/* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */\n#define VpGetSign(a) (((a)->sign>0)?1:(-1))\n/* Change sign of a to a>0,a<0 if s = 1,-1 respectively */\n#define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((S_LONG)(a)->sign);else (a)->sign=-(short)Abs((S_LONG)(a)->sign);}\n/* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */\n#define VpSetSign(a,s)    {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;}\n\n/* 1 */\n#define VpSetOne(a)       {(a)->frac[0]=(a)->exponent=(a)->Prec=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}\n\n/* ZEROs */\n#define VpIsPosZero(a)  ((a)->sign==VP_SIGN_POSITIVE_ZERO)\n#define VpIsNegZero(a)  ((a)->sign==VP_SIGN_NEGATIVE_ZERO)\n#define VpIsZero(a)     (VpIsPosZero(a) || VpIsNegZero(a))\n#define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO)\n#define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO)\n#define VpSetZero(a,s)  ( ((s)>0)?VpSetPosZero(a):VpSetNegZero(a) )\n\n/* NaN */\n#define VpIsNaN(a)      ((a)->sign==VP_SIGN_NaN)\n#define VpSetNaN(a)     ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN)\n\n/* Infinity */\n#define VpIsPosInf(a)   ((a)->sign==VP_SIGN_POSITIVE_INFINITE)\n#define VpIsNegInf(a)   ((a)->sign==VP_SIGN_NEGATIVE_INFINITE)\n#define VpIsInf(a)      (VpIsPosInf(a) || VpIsNegInf(a))\n#define VpIsDef(a)      ( !(VpIsNaN(a)||VpIsInf(a)) )\n#define VpSetPosInf(a)  ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE)\n#define VpSetNegInf(a)  ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE)\n#define VpSetInf(a,s)   ( ((s)>0)?VpSetPosInf(a):VpSetNegInf(a) )\n#define VpHasVal(a)     (a->frac[0])\n#define VpIsOne(a)      ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))\n#define VpExponent(a)   (a->exponent)\n#ifdef _DEBUG\nint VpVarCheck(Real * v);\nVP_EXPORT int VPrint(FILE *fp,char *cntl_chr,Real *a);\n#endif /* _DEBUG */\n\n#if defined(__cplusplus)\n}  /* extern \"C\" { */\n#endif\n#endif /* ____BIG_DECIMAL__H____ */\n"
  },
  {
    "path": "ext/bigdecimal/bigdecimal_en.html",
    "content": "<!-- saved from url=(0022)http://internet.e-mail -->\n<HTML>\n<HEAD>\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html\">\n<style type=\"text/css\"><!--\nbody {  color: #3f0f0f;  background: #fefeff;  margin-left: 2em; margin-right: 2em;}\nh1 {  color: #ffffff;  background-color: #3939AD;  border-color: #FF00FF;  width: 100%;  border-style: solid;\n  border-top-width: 0.1em;  border-bottom-width: 0.1em;  border-right: none;  border-left: none;\n  padding: 0.1em;  font-weight: bold;  font-size: 160%;  text-align: center;}\nh2 {  color: #00007f;  background-color: #e7e7ff;  border-color: #000094;  width: 100%;  border-style: solid;  border-le  ft: none;  border-right: none;  border-top-width: 0.1em;  border-bottom-width: 0.1em;  padding: 0.1em;\n  font-weight: bold;  font-size: 110%;\n}\nh3 {  color: #00007f;  padding: 0.2em;  font-size: 110%;}\nh4, h5 {  color: #000000;  padding: 0.2em;  font-size: 100%;}\ntable {  margin-top: 0.2em; margin-bottom: 0.2em;  margin-left: 2em; margin-right: 2em;}\ncaption {  color: #7f0000;  font-weight: bold;}\nth {  background: #e7e7ff;  padding-left: 0.2em; padding-right: 0.2em;}\ntd {  background: #f3f7ff;  padding-left: 0.2em; padding-right: 0.2em;}\ncode {  color: #0000df;}\ndt {  margin-top: 0.2em;}\nli {  margin-top: 0.2em;}\npre\n{    BACKGROUND-COLOR: #d0d0d0;    BORDER-BOTTOM: medium none;    BORDER-LEFT: medium none;\n    BORDER-RIGHT: medium none;    BORDER-TOP: medium none;    LINE-HEIGHT: 100%;    MARGIN: 12px 12px 12px 12px;\n    PADDING-BOTTOM: 12px;    PADDING-LEFT: 12px;    PADDING-RIGHT: 12px;    PADDING-TOP: 12px;\n    WHITE-SPACE: pre;    WIDTH: 100%\n}\n--></style>\n\n<TITLE>BigDecimal:An extension library for Ruby</TITLE>\n</HEAD>\n<BODY BGCOLOR=#FFFFE0>\n<H1>BigDecimal(Variable Precision Floating Library for Ruby)</H1>\n<DIV align=\"right\"><A HREF=\"./bigdecimal_ja.html\">Japanese</A></DIV><BR>\nBigDecimal is an extension library for the Ruby interpreter. \nUsing BigDecimal class, you can obtain any number of significant digits in computation. \nFor the details about Ruby see:<BR>\n<UL>\n<LI><A HREF=\"http://www.ruby-lang.org/en/\">http://www.ruby-lang.org/en/</A>:Official Ruby page(English).</LI>\n<LI><A HREF=\"http://kahori.com/ruby/ring/\">http://kahori.com/ruby/ring/</A>:Mutually linked pages relating to Ruby(Japanese).\n</LI>\n</UL> \nNOTE:<BR>\n This software is provided \"AS IS\" and without any express or\n implied warranties,including,without limitation,the implied\n warranties of merchantibility and fitness for a particular\n purpose. For the details,see COPYING and README included in this\n distribution.\n<BR>\n<hr>\n\n<H2>Contents</H2>\n<UL>\n<LI><A HREF=\"#INTRO\">Introduction</LI>\n<LI><A HREF=\"#SPEC\">Usage and methods</A></LI>\n<LI><A HREF=\"#UNDEF\">Infinity,NaN,Zero</A></LI>\n<LI><A HREF=\"#STRUCT\">Internal structure</A></LI>\n<LI><A HREF=\"#BASE\">Binary or decimal number representation</A></LI>\n<LI><A HREF=\"#PREC\">Resulting number of significant digits</A></LI>\n</UL>\n<HR>\n\n<A NAME=\"#INTRO\">\n<H2>Introduction</H2>\nRuby already has builtin (variable length integer number) class Bignum. Using Bignum class,you can obtain\n any integer value in magnitude. But, variable length decimal number class is not yet built in. \nThis is why I made variable length floating class BigDecimal.\nFeel free to send any comments or bug reports to me.\n<A HREF=\"mailto:shigeo@tinyforest.gr.jp\">shigeo@tinyforest.gr.jp</A>\nI will try(but can't promise) to fix bugs reported. \n<hr>\n<H2>Installation</H2>\nThe Ruby latest version can be downloaded from <A HREF=\"http://www.ruby-lang.org/en/\">Official Ruby page</A>.\nOnce decompress the downloaded Ruby archive,follow the normal installation procedures according to the \ndocuments included.\n\n<A NAME=\"#SPEC\">\n<H2>Usage and methods</H2>\nSuppose you already know Ruby programming,\nto create BigDecimal objects,the program would like:<BR>\n\n<CODE><PRE>\n   require 'bigdecimal'\n   a=BigDecimal::new(\"0.123456789123456789\")\n   b=BigDecimal(\"123456.78912345678\",40)\n   c=a+b\n</PRE></CODE>\n\n<H3>List of methods</H3>\nIn 32 bits integer system,every 4 digits(in decimal) are computed simultaneously.\nThis means the number of significant digits in BigDecimal is always a multiple of 4.\n<P>\nSome more methods are available in Ruby code (not C code). \nFunctions such as sin,cos ...,are in math.rb in bigdecimal directory.\nTo use them,require math.rb as:\n<CODE><PRE>\nrequire \"bigdecimal/math.rb\"\n</PRE></CODE>\nFor details,see the math.rb code and comments.\nOther utility methods are in util.rb.\nTo use util.rb, require it as:\n<CODE><PRE>\nrequire \"bigdecimal/util.rb\"\n</PRE></CODE>\nFor details,see the util.rb code.\n\n<H4><U>Class methods</U></H4>\n<UL>\n<LI><B>new</B></LI><BLOCKQUOTE>\n\"new\" method creates a new BigDecimal object.<BR>\na=BigDecimal::new(s[,n]) or<BR>\na=BigDecimal(s[,n]) or<BR>\nwhere:<BR>\ns: Initial value string. Spaces will be ignored. Any unrecognizable character for \nrepresenting initial value terminates the string.<BR>\nn: Maximum number of significant digits of a. n must be a Fixnum object.\nIf n is omitted or is equal to 0,then the maximum number of significant digits of a is determined from the length of s.\nActual number of digits handled in computations are usually gretaer than n.<BR>\nn is useful when performing divisions like\n<CODE><PRE>\nBigDecimal(\"1\")    / BigDecimal(\"3\")    # => 0.3333333333 33E0\nBigDecimal(\"1\",10) / BigDecimal(\"3\",10) # => 0.3333333333 3333333333 33333333E0\n</PRE></CODE>\nbut the resulting digits obtained may differ in future version.\n</BLOCKQUOTE>\n\n<LI><B>mode</B></LI><BLOCKQUOTE>\nf = BigDecimal.mode(s[,v])<BR>\nmode method controls BigDecimal computation. If the second argument is not given or is nil,then the value\nof current setting is returned.\nFollowing usage are defined.<BR>\n<P><B>[EXCEPTION control]</B><P>\nActions when computation results NaN or Infinity can be defined as follows.\n<P>\n<BLOCKQUOTE>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>\n</BLOCKQUOTE>\nEXCEPTION_NaN controls the execution when computation results to NaN.<BR>\nEXCEPTION_INFINITY controls the execution when computation results to Infinity(}Infinity).<BR>\nEXCEPTION_UNDERFLOW controls the execution when computation underflows.<BR>\nEXCEPTION_OVERFLOW controls the execution when computation overflows.<BR>\nEXCEPTION_ZERODIVIDE controls the execution when zero-division occures.<BR>\nEXCEPTION_ALL controls the execution for any exception defined occures.<BR>\nIf the flag is true,then the relating exception is thrown.<BR>\nNo exception is thrown when the flag is false(default) and computation \ncontinues with the result:<BR>\n<BLOCKQUOTE>\nEXCEPTION_NaN results to NaN<BR>\nEXCEPTION_INFINITY results to +Infinity or -Infinity<BR>\nEXCEPTION_UNDERFLOW results to 0.<BR>\nEXCEPTION_OVERFLOW results to +Infinity or -Infinity<BR>\nEXCEPTION_ZERODIVIDE results to +Infinity or -Infinity<BR>\n</BLOCKQUOTE>\nEXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are\n currently the same.<BR>\nThe return value of mode method is the value set.<BR>\nIf nil is specified for the second argument,then current setting is returned.<BR>\nSuppose the return value of the mode method is f,then \n f &amp; BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.\n<P>\n<B>[ROUND error control]</B><P>\nRounding operation can be controlled as:\n<BLOCKQUOTE>\nf = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)\n</BLOCKQUOTE>\nwhere flag must be one of:\n<TABLE>\n\n<TR><TD>ROUND_UP</TD><TD>round away from zero.</TD></TR>\n<TR><TD>ROUND_DOWN</TD><TD>round towards zero(truncate).</TD></TR>\n<TR><TD>ROUND_HALF_UP</TD><TD>round up if the digit &gt;= 5 otherwise truncated(default).</TD></TR>\n<TR><TD>ROUND_HALF_DOWN</TD><TD>round up if the digit &gt;= 6 otherwise truncated.</TD></TR>\n<TR><TD>ROUND_HALF_EVEN</TD><TD>round towards the even neighbor(Banker's rounding).\n<TR><TD>ROUND_CEILING</TD><TD>round towards positive infinity(ceil).</TD></TR>\n<TR><TD>ROUND_FLOOR</TD><TD>round towards negative infinity(floor).</TD></TR>\n</TABLE>\nNew rounding mode is returned. If nil is specified for the second argument,then current setting is returned.<BR>\nThe digit location for rounding operation can not be specified by this mode method,\nuse truncate/round/ceil/floor/add/sub/mult/div mthods for each instance instead.\n</BLOCKQUOTE>\n\n<LI><B>limit[(n)]</B></LI><BLOCKQUOTE>\nLimits the maximum digits that the newly created BigDecimal objects can hold never exceed n.\nThis means the rounding operation specified by BigDecimal.mode is \nperformed if necessary.\nlimit returns the value before set if n is nil or is not specified.\nZero,the default value,means no upper limit.<BR>\nThe limit has no more priority than instance methods such as truncate,round,ceil,floor,add,sub,mult,and div. <BR>\nmf = BigDecimal::limit(n)<BR>\n</BLOCKQUOTE>\n\n<LI><B>double_fig</B></LI><BLOCKQUOTE>\ndouble_fig is a class method which returns the number of digits \nthe Float class can have.\n<CODE><PRE>\n  p BigDecimal::double_fig  # ==> 20 (depends on the CPU etc.)\n</PRE></CODE>\nThe equivalent C programs which calculates the value of\ndouble_fig is:\n<CODE><PRE>\n double v          = 1.0;\n int    double_fig = 0;\n while(v + 1.0 > 1.0) {\n    ++double_fig;\n    v /= 10;\n }\n</PRE></CODE>\n</BLOCKQUOTE>\n\n<LI><B>BASE</B></LI><BLOCKQUOTE>\nBase value used in the BigDecimal calculation.\nOn 32 bits integer system,the value of BASE is 10000.<BR>\nb = BigDecimal::BASE<BR>\n</BLOCKQUOTE>\n</UL>\n\n<H4><U>Instance methods</U></H4>\n<UL>\n<LI><B>+</B></LI><BLOCKQUOTE>\naddition(c = a + b)<BR>\nFor the resulting number of significant digits of c,see <A HREF=\"#PREC\">Resulting number of significant digits</A>.\n\n</BLOCKQUOTE>\n<LI><B>-</B></LI><BLOCKQUOTE>\nsubtraction (c = a - b) or negation (c = -a)<BR>\nFor the resulting number of significant digits of c,see <A HREF=\"#PREC\">Resulting number of significant digits</A>.\n\n</BLOCKQUOTE>\n<LI><B>*</B></LI><BLOCKQUOTE>\nmultiplication(c = a * b)<BR>\nFor the resulting number of significant digits of c,see <A HREF=\"#PREC\">Resulting number of significant digits</A>.\n\n</BLOCKQUOTE>\n<LI><B>/</B></LI><BLOCKQUOTE>\ndivision(c = a / b)<BR>\nFor the resulting number of significant digits of c,see <A HREF=\"#PREC\">Resulting number of significant digits</A>.\n</BLOCKQUOTE>\n\n<LI><B>add(b,n)</B></LI><BLOCKQUOTE>\nc = a.add(b,n)<BR>\nc = a.add(b,n) performs c = a + b.<BR>\nIf n is less than the actual significant digits of a + b,\nthen c is rounded properly according to the BigDecimal.limit.<BR>\nIf n is zero,then the result is the same as +'s.\n</BLOCKQUOTE>\n<LI><B>sub(b,n)</B></LI><BLOCKQUOTE>\nc = a.sub(b,n)<BR>\nc = a.sub(b,n) performs c = a - b.<BR>\nIf n is less than the actual significant digits of a - b,\nthen c is rounded properly according to the BigDecimal.limit.<BR>\nIf n is zero,then the result is the same as -'s.\n\n</BLOCKQUOTE>\n<LI><B>mult(b,n)</B></LI><BLOCKQUOTE>\nc = a.mult(b,n)<BR>\nc = a.mult(b,n) performs c = a * b.<BR>\nIf n is less than the actual significant digits of a * b,\nthen c is rounded properly according to the BigDecimal.limit.<BR>\nIf n is zero,then the result is the same as *'s.\n\n</BLOCKQUOTE>\n<LI><B>div(b[,n])</B></LI><BLOCKQUOTE>\nc = a.div(b,n)<BR>\nc = a.div(b,n) performs c = a / b.<BR>\nIf n is less than the actual significant digits of a / b,\nthen c is rounded properly according to the BigDecimal.limit.<BR>\nIf n is zero,then the result is the same as /'s.\nIf n is not given,then the result will be an integer(BigDecimal) like Float#div.\n</BLOCKQUOTE>\n\n<LI><B>fix</B></LI><BLOCKQUOTE>\nc = a.fix<BR>\nreturns integer part of a.<BR>\n\n</BLOCKQUOTE>\n<LI><B>frac</B></LI><BLOCKQUOTE>\nc = a.frac<BR>\nreturns fraction part of a.<BR>\n\n</BLOCKQUOTE>\n<LI><B>floor[(n)]</B></LI><BLOCKQUOTE>\nc = a.floor<BR>\nreturns the maximum integer value (in BigDecimal) which is less than or equal to a.\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").floor  #  ==> 1\n c = BigDecimal(\"-1.23456\").floor #  ==> -2\n</PRE></CODE>\n\nAs shown in the following example,an optional integer argument (n) specifying the position \nof the target digit can be given.<BR>\nIf n> 0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>\nIf n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").floor(4)   #  ==> 1.2345\n c = BigDecimal(\"15.23456\").floor(-1) #  ==> 10.0\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>ceil[(n)]</B></LI><BLOCKQUOTE>\nc = a.ceil<BR>\nreturns the minimum integer value (in BigDecimal) which is greater than or equal to a.\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").ceil  #  ==> 2\n c = BigDecimal(\"-1.23456\").ceil #  ==> -1\n</PRE></CODE>\n\nAs shown in the following example,an optional integer argument (n) specifying the position \nof the target digit can be given.<BR>\nIf n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>\nIf n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").ceil(4)   # ==> 1.2346\n c = BigDecimal(\"15.23456\").ceil(-1) # ==> 20.0\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>\nc = a.round<BR>\nround a to the nearest 1(default)D<BR>\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").round  #  ==> 1\n c = BigDecimal(\"-1.23456\").round #  ==> -1\n</PRE></CODE>\nThe rounding operation changes according to BigDecimal::mode(BigDecimal::ROUND_MODE,flag) if specified.\n\nAs shown in the following example,an optional integer argument (n) specifying the position \nof the target digit can be given.<BR>\nIf n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction  part digits is less than or equal to n).<BR>\nIf n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).\n<CODE><PRE>\nc = BigDecimal::new(\"1.23456\").round(4)   #  ==> 1.2346\nc = BigDecimal::new(\"15.23456\").round(-1) #  ==> 20.0\n</PRE></CODE>\n\nRounding operation can be specified by setting the second optional argument b with the valid ROUND_MODE.<BR>\n<CODE><PRE>\nc = BigDecimal::new(\"1.23456\").round(3,BigDecimal::ROUND_HALF_EVEN)   #  ==> 1.234\nc = BigDecimal::new(\"1.23356\").round(3,BigDecimal::ROUND_HALF_EVEN)   #  ==> 1.234\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>truncate[(n)]</B></LI><BLOCKQUOTE>\nc = a.truncate<BR>\ntruncate a to the nearest 1D<BR>\nAs shown in the following example,an optional integer argument (n) specifying the position \nof the target digit can be given.<BR>\nIf n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>\nIf n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).\n\n<CODE><PRE>\nc = BigDecimal::new(\"1.23456\").truncate(4)   #  ==> 1.2345\nc = BigDecimal::new(\"15.23456\").truncate(-1) #  ==> 10.0\n</PRE></CODE>\n</BLOCKQUOTE>\n<LI><B>abs</B></LI><BLOCKQUOTE>\nc = a.abs<BR>\nreturns an absolute value of a.<BR>\n\n</BLOCKQUOTE>\n<LI><B>to_i</B></LI><BLOCKQUOTE>\nchanges a to an integer.<BR>\ni = a.to_i<BR>\ni becomes to Fixnum or Bignum.\nIf a is Infinity or NaN,then i becomes to nil.\n\n</BLOCKQUOTE>\n<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>\nconverts to string(default results look like \"0.xxxxxEn\").\n<CODE><PRE>\nBigDecimal(\"1.23456\").to_s  #  ==> \"0.123456E1\"\n</PRE></CODE>\nIf n(>0) is given,then a space is inserted to each of two parts divided by the decimal point \nafter every n digits for readability.\n<CODE><PRE>\nBigDecimal(\"0.1234567890123456789\").to_s(10)   #  ==> \"0.1234567890 123456789E0\"\n</PRE></CODE>\nn can be a string representing a positive integer number.\n<CODE><PRE>\nBigDecimal(\"0.1234567890123456789\").to_s(\"10\") #  ==> \"0.1234567890 123456789E0\"\n</PRE></CODE>\nIf the first character is '+'(or ' '),then '+'(or ' ') will be set before value string\nwhen the value is positive.\n<CODE><PRE>\nBigDecimal(\"0.1234567890123456789\").to_s(\" 10\") #  ==> \" 0.1234567890 123456789E0\"\nBigDecimal(\"0.1234567890123456789\").to_s(\"+10\") #  ==> \"+0.1234567890 123456789E0\"\nBigDecimal(\"-0.1234567890123456789\").to_s(\"10\") #  ==> \"-0.1234567890 123456789E0\"\n</PRE></CODE>\n\nAt the end of the string,'E'(or 'e') or 'F'(or 'f') can be specified to change \nnumber representation.\n<CODE><PRE>\nBigDecimal(\"1234567890.123456789\").to_s(\"E\")  #  ==> \"0.1234567890123456789E10\"\nBigDecimal(\"1234567890.123456789\").to_s(\"F\")  #  ==> \"1234567890.123456789\"\nBigDecimal(\"1234567890.123456789\").to_s(\"5E\") #  ==> \"0.12345 67890 12345 6789E10\"\nBigDecimal(\"1234567890.123456789\").to_s(\"5F\") #  ==> \"12345 67890.12345 6789\"\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>exponent</B></LI><BLOCKQUOTE>\nreturns an integer holding exponent value of a.<BR>\nn = a.exponent <BR>\nmeans a = 0.xxxxxxx*10**n.\n</BLOCKQUOTE>\n\n<LI><B>precs</B></LI><BLOCKQUOTE>\nn,m = a.precs <BR>\nprec returns number of significant digits (n) and maximum number of \nsignificant digits (m) of a.\n</BLOCKQUOTE>\n\n<LI><B>to_f</B></LI><BLOCKQUOTE>\nCreates a new Float object having (nearly) the same value.\nUse split method if you want to convert by yourself.\n</BLOCKQUOTE>\n\n</BLOCKQUOTE>\n<LI><B>sign</B></LI><BLOCKQUOTE>\nn = a.sign <BR>\nreturns positive value if a &gt; 0,negative value if a &lt; 0,\notherwise zero if a == 0.<BR>\nwhere the value of n means that a is:<BR>\nn = BigDecimal::SIGN_NaN(0) : a is NaN<BR>\nn = BigDecimal::SIGN_POSITIVE_ZERO(1) : a is +0<BR>\nn = BigDecimal::SIGN_NEGATIVE_ZERO(-1) : a is -0<BR>\nn = BigDecimal::SIGN_POSITIVE_FINITE(2) : a is positive<BR>\nn = BigDecimal::SIGN_NEGATIVE_FINITE(-2) : a is negative<BR>\nn = BigDecimal::SIGN_POSITIVE_INFINITE(3) : a is +Infinity<BR>\nn = BigDecimal::SIGN_NEGATIVE_INFINITE(-3) : a is -Infinity<BR>\nThe value in () is the actual value,see (<A HREF=\"#STRUCT\">Internal structure</A>.<BR>\n\n</BLOCKQUOTE>\n<LI><B>nan?</B></LI><BLOCKQUOTE>\na.nan? returns True when a is NaN.\n\n</BLOCKQUOTE>\n<LI><B>infinite?</B></LI><BLOCKQUOTE>\na.infinite? returns 1 when a is +,-1 when a is -, nil otherwise.\n\n</BLOCKQUOTE>\n<LI><B>finite?</B></LI><BLOCKQUOTE>\na.finite? returns true when a is neither  nor NaN.\n</BLOCKQUOTE>\n\n<LI><B>zero?</B></LI><BLOCKQUOTE>\nc = a.zero?<BR>\nreturns true if a is equal to 0,otherwise returns false<BR>\n</BLOCKQUOTE>\n<LI><B>nonzero?</B></LI><BLOCKQUOTE>\nc = a.nonzero?<BR>\nreturns nil if a is 0,otherwise returns a itself.<BR>\n</BLOCKQUOTE>\n\n<LI><B>split</B></LI><BLOCKQUOTE>\ndecomposes a BigDecimal value to 4 parts.\nAll 4 parts are returned as an array.<BR>\nParts consist of a sign(0 when the value is NaN,+1 for positive and\n -1 for negative value), a string representing fraction part,base value(always 10 currently),and an integer(Fixnum) for exponent respectively.\na=BigDecimal::new(\"3.14159265\")<BR>\nf,x,y,z = a.split<BR>\nwhere f=+1,x=\"314159265\",y=10 and z=1<BR>\ntherefore,you can translate BigDecimal value to Float as:<BR>\ns = \"0.\"+x<BR>\nb = f*(s.to_f)*(y**z)<BR>\n\n</BLOCKQUOTE>\n<LI><B>inspect</B></LI><BLOCKQUOTE>\nis used for debugging output.<BR>\np a=BigDecimal::new(\"3.14\",10)<BR>\nshould produce output like \"#&lt;0x112344:'0.314E1',4(12)%gt;\".\nwhere \"0x112344\" is the address,\n'0.314E1' is the value,4 is the number of the significant digits,\nand 12 is the maximum number of the significant digits \nthe object can hold.\n</BLOCKQUOTE>\n\n<LI><B>sqrt</B></LI><BLOCKQUOTE>\nc = a.sqrt(n)<BR>\ncomputes square root value of a with significant digit number n at least.<BR>\n</BLOCKQUOTE>\n\n<LI><B>**</B></LI><BLOCKQUOTE>\nc = a ** n<BR>\nreturns the value of a powered by n.\nn must be an integer.<BR>\n\n</BLOCKQUOTE>\n<LI><B>power</B></LI><BLOCKQUOTE>\nThe same as ** method.<BR>\nc = a.power(n)<BR>\nreturns the value of a powered by n(c=a**n).\nn must be an integer.<BR>\n</BLOCKQUOTE>\n\n<LI><B>divmod,quo,modulo,%,remainder</B></LI><BLOCKQUOTE>\nSee,corresponding methods in Float class.\n</BLOCKQUOTE>\n\n</BLOCKQUOTE>\n<LI><B>&lt;=&gt;</B></LI><BLOCKQUOTE>\nc = a &lt;=&gt; b <BR>\nreturns 0 if a==b,1 if a &gt b,and returns -1 if a &lt b.<BR>\n</BLOCKQUOTE>\n</UL>\n\nFollowing methods need no explanation.<BR>\n<UL>\n<LI>==</LI>\n<LI>===</LI>\nsame as ==,used in case statement.\n<LI>!=</LI>\n<LI>&lt;</LI>\n<LI>&lt;=</LI>\n<LI>&gt;</LI>\n<LI>&gt;=</LI>\n</UL>\n\n<HR>\n<H3>About 'coerce'</H3>\n<B>For the binary operation like A op B:</B>\n<DL>\n<DT> 1.Both A and B are BigDecimal objects</DT>\n<DD> A op B is normally performed.</DD>\n<DT> 2.A is the BigDecimal object but B is other than BigDecimal object</DT>\n<DD> Operation is performed,after B is translated to correcponding BigDecimal object(because BigDecimal supports coerce method).</DD>\n<DT> 3.A is not the BigDecimal object but B is BigDecimal object</DT>\n<DD>If A has coerce mthod,then B will translate A to corresponding \nBigDecimal object and the operation is performed,otherwise an error occures.</DD>\n</DL>\n\nString is not translated to BigDecimal in default.\nUncomment /* #define ENABLE_NUMERIC_STRING */ in bigdecimal.c, compile and install \nagain if you want to enable string to BigDecimal conversion.\nTranslation stops without error at the character representing non digit.\nFor instance,\"10XX\" is translated to 10,\"XXXX\" is translated to 0.<BR>\nString representing zero or infinity such as \"Infinity\",\"+Infinity\",\"-Infinity\",and \"NaN\" can also be translated to BigDecimal unless false is specified by mode method.<BR>\n\nBigDecimal class supports coerce method(for the details about coerce method,see Ruby documentations). This means the most binary operation can be performed if the BigDecimal object is at the left hand side of the operation.<BR><BR>\n\n For example:\n<CODE><PRE>\n  a = BigDecimal.E(20)\n  c = a * \"0.123456789123456789123456789\" # A String is changed to BigDecimal object.\n</PRE></CODE>\nis performed normally.<BR>\n But,because String does not have coerce method,the following example can not be performed.<BR>\n\n<CODE><PRE>\n  a = BigDecimal.E(20)\n  c = \"0.123456789123456789123456789\" * a # ERROR\n</PRE></CODE>\n\nIf you actually have any inconvenience about the error above.\nYou can define a new class derived from String class,\nand define coerce method within the new class.<BR>\n\n<hr>\n<A NAME=\"#UNDEF\">\n<H2>Infinity,Not a Number(NaN),Zero</H2>\nInfinite numbers and NaN can be represented by string writing \"+Infinity\"(or \"Infinity\"),\"-Infinity\",and \"NaN\" respectively in your program.\nInfinite numbers can be obtained by 1.0/0.0(=Infinity) or -1.0/0.0(=-Infinity).\n<BR><BR>\nNaN(Not a number) can be obtained by undefined computation like 0.0/0.0 \nor Infinity-Infinity.\nAny computation including NaN results to NaN.\nComparisons with NaN never become true,including comparison with NaN itself.\n<BR><BR>\nZero has two different variations as +0.0 and -0.0.\nBut,still, +0.0==-0.0 is true.\n<BR><BR>\nComputation results including Infinity,NaN,+0.0 or -0.0 become complicated.\nRun following program and comfirm the results.\nSend me any incorrect result if you find.\n\n<CODE><PRE>\n require \"bigdecimal\"\n aa  = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)\n ba  = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)\n opa = %w(+ - * / <=> > >=  < == != <=)\n for a in aa\n  for b in ba\n    for op in opa\n      x = BigDecimal::new(a)\n      y = BigDecimal::new(b)\n      eval(\"ans= x #{op} y;print a,' ',op,' ',b,' ==> ',ans.to_s,\\\"\\n\\\"\")\n    end\n  end\n end\n</PRE></CODE>\n<hr>\n\n<A NAME=\"#STRUCT\">\n<H2>Internal structure</H2>\nBigDecimal number is defined by the structure Real in BigDecimal.h.\nDigits representing a float number are kept in the array frac[] defined in the structure.\nIn the program,any floating number(BigDecimal number) is represented as:<BR>\n <BigDecimal number> = 0.xxxxxxxxx*BASE**n<BR><BR>\nwhere 'x' is any digit representing mantissa(kept in the array frac[]),\nBASE is base value(=10000 in 32 bit integer system),\nand n is the exponent value.<BR>\nLarger BASE value enables smaller size of the array frac[],and increases computation speed.\nThe value of BASE is defined ind VpInit(). In 32 bit integer system,this value is \n10000. In 64 bit integer system,the value becomes larger.\nBigDecimal has not yet been compiled and tested on 64 bit integer system.\nIt will be very nice if anyone try to run BigDecimal on 64 bit system and\n inform me the results.\nWhen BASE is 10000,an element of the array frac[] can have vale of from 0 to 9999.\n(up to 4 digits).<BR>\nThe structure Real is defined in bigdecimal.h as:<BR>\n<CODE><PRE>\n  typedef struct {\n     VALUE  obj;     /* Back pointer(VALUE) for Ruby object.         */\n     unsigned long MaxPrec; /* The size of the array frac[]          */\n     unsigned long Prec;    /* Current size of frac[] actually used. */\n     short    sign;         /* Attribute of the value.  */\n                            /*  ==0 : NaN               */\n                            /*    1 : +0                */\n                            /*   -1 : -0                */\n                            /*    2 : Positive number   */\n                            /*   -2 : Negative number   */\n                            /*    3 : +Infinity         */\n                            /*   -3 : -Infinity         */\n     unsigned short flag;   /* Control flag             */\n     int      exponent;     /* Exponent value(0.xxxx*BASE**exponent) */\n     unsigned long frac[1]; /* An araay holding mantissa(Variable)   */\n  } Real;\n</CODE></PRE>\nThe decimal value 1234.56784321 is represented as(BASE=10000):<BR>\n<PRE>\n    0.1234 5678 4321*(10000)**1\n</PRE>\nwhere frac[0]=1234,frac[1]=5678,frac[2]=4321,\nPrec=3,sign=2,exponent=1. MaxPrec can be any value greater than or equal to \nPrec.\n<hr>\n\n<A NAME=\"#BASE\">\n<H2>Binary or decimal number representation</H2>\nI adopted decimal number representation for BigDecimal implementation.\nOf cource,binary number representation is common on the most computers.\n\n<H3>Advantages using decimal representation</H3>\nThe reason why I adopted decimal number representation for BigDecimal is:<BR>\n<DL>\n<DT>Easy for debugging\n<DD>The floating number 1234.56784321 can be easily represented as:<BR>\n  frac[0]=1234,frac[1]=5678,frac[2]=4321,exponent=1,and sign=2.\n<DT>Exact representation\n<DD>Following program can add all numbers(in decimal) in a file\n without any error(no round operation).<BR>\n\n<CODE><PRE>\n   file = File::open(....,\"r\")\n   s = BigDecimal::new(\"0\")\n   while line = file.gets\n      s = s + line\n   end\n</PRE></CODE>\n\nIf the internal representation is binary,translation from decimal to \nbinary is required and the translation error is inevitable.\nFor example, 0.1 can not exactly be represented in binary.<BR>\n0.1 => b1*2**(-1)+b1*2**(-2)+b3*2**(-3)+b4*2**(-4)....<BR>\nwhere b1=0,b2=0,b3=0,b4=1...<BR>\nbn(n=1,2,3,...) is infinite series of digit with value of 0 or 1,\nand rounding operation is necessary but where we should round the series ?\nOf cource,exact \"0.1\" is printed if the rouding operation is properly done,\n<DT>Significant digit we can have is automatically determined\n<DD>In binary representation,0.1 can not be represented in finite series of digit.\n\nBut we only need one element(frac[0]=1) in decimal representation.\nThis means that we can always determine the size of the array frac[] in Real \nstructure.\n</DL>\n\n<H3>Disadvantage of decimal representation</H3>\nBecause most computers have no internal decimal representaion.\nOnce you use BigDecimal,you need to keep using it without\nconsidering computation cost if exact computation is required.\n\n<H4>Which is the first input?</H4>\nBecause most people uses decimal notatin for numeric data representation,\nBigDecimal can handle numeric data without loss of translation error.\n<hr>\n\n<A NAME=\"#PREC\">\n<H2>Resulting number of significant digits</H2>\nFor the fundamental arithmetics such as addition,subtraction,\nmultiplication,and division,I prepared 2 group of methods<BR>\n\n<H3>1. +,-,*,/</H3>\nFor the operation + - * /,you can not specify the resulting \nnumber of significant digits.<BR>\nResulting number of significant digits are defined as:<BR>\n1.1 For *,resulting number of significant digits is the sum of the \nsignificant digits of both side of the operator. For / ,resulting number of significant digits is the sum of the \nmaximum significant digits of both side of the operator.<BR>\n1.2 For + and -,resulting number of significant digits is determined so that\n no round operation is needed. <br>\nFor example, c has more than 100 siginificant digits if c is computed as:<BR>\nc = 0.1+0.1*10**(-100)<br>\n<BR>\nAs +,-,and * are always exact(no round operation is performed unless BigDecimal.limit is specified),\nwhich means more momories are required to keep computation results.\nBut,the division such as c=1.0/3.0 will always be rounded.<BR>\n\n<H3>2. add,sub,mult,div</H3>\nThe length of the significant digits obtained from +,-,*,/ \nis always defined by that of right and left side of the operator.\nTo specify the length of the significant digits by your self,\nuse methos add,sub,mult,div.\n<CODE><PRE>\n BigDecimal(\"2\").div(3,12) # 2.0/3.0 => 0.6666666666 67E0\n</PRE></CODE>\n</BLOCKQUOTE>\n\n<H3>3. truncate,round,ceil,floor</H3>\nUsing these methods,you can specify rounding location relatively from\ndecimal point.\n<CODE><PRE>\n BigDecimal(\"6.66666666666666\").round(12) # => 0.6666666666 667E1\n</PRE></CODE>\n</BLOCKQUOTE>\n\n\n<H3>4. Example</H3>\nFollowing example compute the ratio of the circumference of a circle to \nits dirmeter(pi=3.14159265358979....) using J.Machin's formula.\n<BR><BR>\n<CODE><PRE>\n#!/usr/local/bin/ruby\n\nrequire \"bigdecimal\"\n#\n# Calculates 3.1415.... (the number of times that a circle's diameter\n# will fit around the circle) using J. Machin's formula.\n#\ndef big_pi(sig) # sig: Number of significant figures\n  exp    = -sig\n  pi     = BigDecimal::new(\"0\")\n  two    = BigDecimal::new(\"2\")\n  m25    = BigDecimal::new(\"-0.04\")\n  m57121 = BigDecimal::new(\"-57121\")\n\n  u = BigDecimal::new(\"1\")\n  k = BigDecimal::new(\"1\")\n  w = BigDecimal::new(\"1\")\n  t = BigDecimal::new(\"-80\")\n  while (u.nonzero? && u.exponent >= exp) \n    t   = t*m25\n    u   = t.div(k,sig)\n    pi  = pi + u\n    k   = k+two\n  end\n\n  u = BigDecimal::new(\"1\")\n  k = BigDecimal::new(\"1\")\n  w = BigDecimal::new(\"1\")\n  t = BigDecimal::new(\"956\")\n  while (u.nonzero? && u.exponent >= exp )\n    t   = t.div(m57121,sig)\n    u   = t.div(k,sig)\n    pi  = pi + u\n    k   = k+two\n  end\n  pi\nend\n\nif $0 == __FILE__\n  if ARGV.size == 1\n    print \"PI(\"+ARGV[0]+\"):\\n\"\n    p big_pi(ARGV[0].to_i)\n  else\n    print \"TRY: ruby pi.rb 1000 \\n\"\n  end\nend\n\n</PRE></CODE>\n<HR>\n<FONT size=2>\n<I>\n<A HREF=\"http://www.tinyforest.gr.jp\">\nShigeo Kobayashi\n</A>\n(E-Mail:<A HREF=\"mailto:shigeo@tinyforest.gr.jp\">&lt;shigeo@tinyforest.gr.jp&gt;</U></A>)\n</I>\n</FONT>\n</TD>\n</TR>\n</TABLE>\n</BODY>\n</HTML>\n"
  },
  {
    "path": "ext/bigdecimal/bigdecimal_ja.html",
    "content": "<!-- saved from url=(0022)http://internet.e-mail -->\n<HTML>\n<HEAD>\n<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=Shift_JIS\">\n<style type=\"text/css\"><!--\nbody { color: #3f0f0f;  background: #fefeff; margin-left: 2em; margin-right: 2em;}\nh1 { color: #ffffff;  background-color: #3939AD;  border-color: #FF00FF;  width: 100%;\n  border-style: solid;  border-top-width: 0.1em;  border-bottom-width: 0.1em;  border-right: none;\n  border-left: none;  padding: 0.1em;  font-weight: bold;  font-size: 160%;  text-align: center;\n}\nh2 {  color: #00007f;  background-color: #e7e7ff;  border-color: #000094;  width: 100%;\n  border-style: solid; border-left: none;  border-right: none;  border-top-width: 0.1em;  border-bottom-width: 0.1em;\n  padding: 0.1em;\n  font-weight: bold;  font-size: 110%;\n}\nh3 {  color: #00007f;  padding: 0.2em;  font-size: 110%;}\nh4, h5 {  color: #000000;  padding: 0.2em;  font-size: 100%;}\ntable {  margin-top: 0.2em; margin-bottom: 0.2em;  margin-left: 2em; margin-right: 2em;}\ncaption {  color: #7f0000;  font-weight: bold;}\nth {  background: #e7e7ff;  padding-left: 0.2em; padding-right: 0.2em;}\ntd {  background: #f3f7ff;  padding-left: 0.2em; padding-right: 0.2em;}\ncode {  color: #0000df;}\ndt {  margin-top: 0.2em;}\nli {  margin-top: 0.2em;}\npre\n{    BACKGROUND-COLOR: #d0d0d0;    BORDER-BOTTOM: medium none;    BORDER-LEFT: medium none;\n    BORDER-RIGHT: medium none;    BORDER-TOP: medium none;    LINE-HEIGHT: 100%;    MARGIN: 12px 12px 12px 12px;\n    PADDING-BOTTOM: 12px;    PADDING-LEFT: 12px;    PADDING-RIGHT: 12px;    PADDING-TOP: 12px;\n    WHITE-SPACE: pre;    WIDTH: 100%\n}\n--></style>\n\n<TITLE>BigDecimal:An extension library for Ruby</TITLE>\n</HEAD>\n<BODY BGCOLOR=#FFFFE0>\n<H1>BigDecimal(ϒ_ZpgCu)</H1>\n<DIV align=\"right\"><A HREF=\"./bigdecimal_en.html\">English</A></DIV><BR>\nBigDecimal ̓IuWFNgw̋͂ȃXNvgł Ruby ɉϒ_\nvZ@\\ǉ邽߂̊gCułB\nRuby ɂĂ̏ڂe͈ȉURLQƂĂB\n<UL>\n<LI><A HREF=\"http://www.ruby-lang.org/ja/\">http://www.ruby-lang.org/ja/</A>FRubyy[W</LI>\n<LI><A HREF=\"http://kahori.com/ruby/ring/\">http://kahori.com/ruby/ring/</A>FRubyɊւy[WH܂</LI>\n</UL> \n<hr>\n<H2>ڎ</H2>\n<UL>\n<LI><A HREF=\"#INTRO\">͂߂</LI>\n<LI><A HREF=\"#SPEC\">gp@ƃ\\bḧꗗ</A></LI>\n<LI><A HREF=\"#UNDEF\">A񐔁A[̈</A></LI>\n<LI><A HREF=\"#STRUCT\">\\</A></LI>\n<LI><A HREF=\"#BASE\">2i10i</A></LI>\n<LI><A HREF=\"#PREC\">vZxɂ</A></LI>\n</UL>\n\n<HR>\n<A NAME=\"#INTRO\">\n<H2>͂߂</H2>\nRuby ɂ Bignum ƂNXAS̐łvZ邱Ƃł܂B\nACӌ̕_ZpNX悤łBŁA\nCӌ̕_ZpgCu BigDecimal 쐬܂B\ns⏕EĂꍇǂǂA\n<A HREF=\"mailto:shigeo@tinyforest.gr.jp\">shigeo@tinyforest.gr.jp</A>\n܂łm点Bs𒼂C͑傢ɂ܂BAԂȂǂ̊֌WŖ\n͂ł܂B܂AʂɂĂۏ؂ł̂ł͂܂B\n\\߁AB\n<BR><BR>\ñvÓARɔzzEςč\\܂BA쌠͕Ă܂B\nzzEϓ̌ Ruby ̂ɏ܂Bڂ README ǂłB\n\n<hr>\n<H2>CXg[ɂ</H2>\nBigDecimal ܂ Ruby ̍ŐVł<A HREF=\"http://www.ruby-lang.org/ja/\">Rubyy[W</A>_E[hł܂B\n_E[hŐVł𓀂Aʏ̃CXg[菇sĉB\nRuby CXg[΁A BigDecimal pł悤ɂȂ͂łB\n\\[Xt@C \nbigdecimal.c,bigdecimal.h \n̂Q݂̂łB<BR>\n\n<hr>\n<A NAME=\"#SPEC\">\n<H2>gp@ƃ\\bḧꗗ</H2>\nuRuby͊ɏvƂOŁA\n<CODE><PRE>\nrequire 'bigdecimal'\na=BigDecimal::new(\"0.123456789123456789\")\nb=BigDecimal(\"123456.78912345678\",40)\nc=a+b\n</PRE></CODE>\n<br>\nƂ悤ȊŎgp܂B\n\n<H3>\\bhꗗ</H3>\nȉ̃\\bhp\\łB\nuLvƂ BigDecimal xۏ؂錅łB\n҂ł͂܂A኱̗]TČvZ܂B\n܂AႦ΂RQrbg̃VXeł͂POiłSɌvZ܂B]āAł́A\ńuLv͂S̔{ƂȂĂ܂B\n<P>\nȉ̃\\bhȊOɂA(C ł͂Ȃ) Ruby \\[X̌`\n񋟂Ă̂܂BႦ΁A\n<CODE><PRE>\nrequire \"bigdecimal/math.rb\"\n</PRE></CODE>\nƂ邱ƂŁAsin  cos Ƃ֐gpł悤ɂȂ܂B\ngp@ȂǁAڍׂ math.rb ̓eQƂĉB\n\n̑AFloat Ƃ̑ݕϊȂǂ̃\\bh util.rb ŃT|[gĂ܂B\npɂ\n<CODE><PRE>\nrequire \"bigdecimal/util.rb\"\n</PRE></CODE>\n̂悤ɂ܂Bڍׂ util.rb ̓eQƂĉB\n\n<H4><U>NX\\bh</U></H4>\n<UL>\n<LI><B>new</B></LI><BLOCKQUOTE>\nV BigDecimal IuWFNg𐶐܂B<BR>\na=BigDecimal::new(s[,n]) ܂<BR>\na=BigDecimal(s[,n])<BR>\ns ͐\\鏉l𕶎Ŏw肵܂B\nXy[X͖܂B܂AfłȂo_\n͏ÎƂ݂Ȃ܂B\nn ͕KvȗLia ̍őLj𐮐Ŏw肵܂B\nn  0 ܂͏ȗꂽƂ́An ̒l s ̗LƂ݂Ȃ܂B\ns ̗L n Ƃ n=0 ̂ƂƓłB\na ̍őL n ኱傢l̗p܂B\nőL͈ȉ̂悤ȊZsƂɈӖ܂B\n<CODE><PRE>\nBigDecimal(\"1\")    / BigDecimal(\"3\")    # => 0.3333333333 33E0\nBigDecimal(\"1\",10) / BigDecimal(\"3\",10) # => 0.3333333333 3333333333 33333333E0\n</PRE></CODE>\nAX̉ZɂőL n ̎舵͏̃o[W\n኱ύX\\܂B\n</BLOCKQUOTE>\n\n<LI><B>mode</B></LI><BLOCKQUOTE>\nf = BigDecimal.mode(s[,v])<BR>\nBigDecimal̎sʂ𐧌䂵܂BQȗA܂ nil w肷\n̐ݒl߂܂B<BR>\nȉ̎gp@`Ă܂B\n<P>\n<B>[O]</B><P>\nvZʂ(NaN)[ɂ鏜ZɂȂƂ̏`邱Ƃł܂B\n<BLOCKQUOTE>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>\nf = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>\n</BLOCKQUOTE>\n\nEXCEPTION_NaN ͌ʂ NaN ɂȂƂ̎włB<BR>\nEXCEPTION_INFINITY ͌ʂ(}Infinity)ɂȂƂ̎włB<BR>\nEXCEPTION_UNDERFLOW ͎wA_[t[Ƃ̎włB<BR>\nEXCEPTION_OVERFLOW ͎wI[o[t[Ƃ̎włB<BR>\nEXCEPTION_ZERODIVIDE ̓[ɂ銄ZsƂ̎włB<BR>\nEXCEPTION_ALL ́A\\ȑSĂɑ΂ĈꊇĐݒ肷ƂɎgp܂B<BR><BR>\n\nflag  true ̂Ƃ́Aw肵ԂɂȂƂɗO𔭍s悤ɂȂ܂B<BR>\nflag  falseiftHgjȂAO͔s܂BvZʂ͈ȉ̂悤ɂȂ܂B<BR>\n<BLOCKQUOTE>\nEXCEPTION_NaN ̂ƂA(NaN)<BR>\nEXCEPTION_INFINITY ̂ƂA(+ or -Infinity)<BR>\nEXCEPTION_UNDERFLOW ̂ƂA[<BR>\nEXCEPTION_OVERFLOW ̂ƂA+Infinity  -Infinity<BR>\nEXCEPTION_ZERODIVIDE ̂ƂA+Infinity  -Infinity<BR>\n</BLOCKQUOTE>\nEXCEPTION_INFINITYAEXCEPTION_OVERFLOWAEXCEPTION_ZERODIVIDE\n͍̂Ƃ듯łB<BR>\n߂ĺAݒ̒lłBulv̈Ӗ́AႦ\nBigDecimal::EXCEPTION_NaNƁulv &  [ȊOȂ\nEXCEPTION_NaNݒ肳ĂƂӖłB\n\n<P>\n<B>[ۂߏw]</B><P>\nvZr̊ۂߑ̎w肪ł܂B\n<BLOCKQUOTE>\nf = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)\n</BLOCKQUOTE>\ň`Ŏw肵܂B<BR>\nŁAflag ͈ȉ(ʓ͑ΉCX^X\\bh)̈w肵܂B\n<TABLE>\n<TR><TD>ROUND_UP</TD><TD>SĐ؂グ܂B</TD></TR>\n<TR><TD>ROUND_DOWN</TD><TD>SĐ؂̂Ă܂(truncate)B</TD></TR>\n<TR><TD>ROUND_HALF_UP</TD><TD>ľܓ܂(ftHg)B</TD></TR>\n<TR><TD>ROUND_HALF_DOWN</TD><TD>܎̘Z܂B</TD></TR>\n<TR><TD>ROUND_HALF_EVEN</TD><TD>l̘Z܂BT̎͏ʂP̎̂݌Jグ܂(Banker's rounding)B</TD></TR>\n<TR><TD>ROUND_CEILING</TD><TD>l̑傫ɌJグ܂(ceil)B</TD></TR>\n<TR><TD>ROUND_FLOOR</TD><TD>l̏ɌJ艺܂(floor)B</TD></TR>\n\n</TABLE>\n߂l͎w flag ̒lłB\nQ nil w肷ƁA̐ݒlԂ܂B\nmode \\bhł͊ۂߑ̈ʒu[Uw肷邱Ƃ͂ł܂B\nۂߑƈʒuŐ䂵ꍇ BigDecimal::limit  truncate/round/ceil/floorA\nadd/sub/mult/div ƂCX^X\\bhgpĉB\n</BLOCKQUOTE>\n<LI><B>limit([n])</B></LI><BLOCKQUOTE>\nBigDecimalIuWFNg̍ő包nɐ܂B\n߂l͐ݒ肷O̒lłBݒl̃ftHgl͂OŁAƂӖłB\nn w肵ȂA܂ n  nil ̏ꍇ́A̍ő包Ԃ܂B<BR>\nvZ𑱍sԂɁǍɑĂ܂悤ȏꍇ\n limit ŗ\\ߌ𐧌ł܂B̏ꍇ BigDecimal.mode Ŏw肳ꂽ\nۂߏs܂B\nACX^X\\bh (truncate/round/ceil/floor/add/sub/mult/div) \n limit D悳܂B<BR>\nmf = BigDecimal::limit(n)<BR>\n</BLOCKQUOTE>\n\n<LI><B>double_fig</B></LI><BLOCKQUOTE>\nRuby  Float NXێłL̐Ԃ܂B\n<CODE><PRE>\n  p BigDecimal::double_fig  # ==> 20 (depends on the CPU etc.)\n</PRE></CODE>\ndouble_fig͈ȉ C vǑʂƓłB\n<CODE><PRE>\n double v          = 1.0;\n int    double_fig = 0;\n while(v + 1.0 > 1.0) {\n    ++double_fig;\n    v /= 10;\n }\n</PRE></CODE>\n</BLOCKQUOTE>\n\n<LI><B>BASE</B></LI><BLOCKQUOTE>\nŎgp̒lłB 32 rbg̏nł10000łB<BR>\nb = BigDecimal::BASE<BR>\n</BLOCKQUOTE>\n</UL>\n\n<H4><U>CX^X\\bh</U></H4>\n<UL>\n<LI><B>+</B></LI><BLOCKQUOTE>\nZic = a + bj<BR>\nc ̐xɂẮu<A HREF=\"#PREC\">vZxɂ</A>vQƂĂB\n</BLOCKQUOTE>\n\n<LI><B>-</B></LI><BLOCKQUOTE>\nZic = a - bjA܂͕]ic = -aj<BR>\nc ̐xɂẮu<A HREF=\"#PREC\">vZxɂ</A>vQƂĂB\n\n</BLOCKQUOTE>\n<LI><B>*</B></LI><BLOCKQUOTE>\nZ(c = a * b)<BR>\nc̐x(a̐x)+(b̐x)xłB<br>\nڂ́u<A HREF=\"#PREC\">vZxɂ</A>vQƂĂB\n\n</BLOCKQUOTE>\n<LI><B>/</B></LI><BLOCKQUOTE>\nZ(c = a / b)<BR>\nc ̐xɂẮu<A HREF=\"#PREC\">vZxɂ</A>vQƂĂB\n\n</BLOCKQUOTE>\n\n<LI><B>add(b,n)</B></LI><BLOCKQUOTE>\nȉ̂悤Ɏgp܂B<BR>\nc = a.add(b,n)<BR>\nc = a + b ő n ܂ŌvZ܂B<BR>\na + b ̐x n 傫Ƃ BigDecimal.mode Ŏw肳ꂽ@Ŋۂ߂܂B<BR>\nn [Ȃ + ƓłB\n</BLOCKQUOTE>\n<LI><B>sub(b,n)</B></LI><BLOCKQUOTE>\nȉ̂悤Ɏgp܂B<BR>\nc = a.sub(b,n)<BR>\nc = a - b ő n ܂ŌvZ܂B<BR>\na - b ̐x n 傫Ƃ BigDecimal.mode Ŏw肳ꂽ@Ŋۂ߂܂B<BR>\nn [Ȃ - ƓłB\n\n</BLOCKQUOTE>\n<LI><B>mult(b,n)</B></LI><BLOCKQUOTE>\nȉ̂悤Ɏgp܂B<BR>\nc = a.mult(b,n)<BR>\nc = a * b ő n ܂ŌvZ܂B<BR>\na * b ̐x n 傫Ƃ BigDecimal.mode Ŏw肳ꂽ@Ŋۂ߂܂B<BR>\nn [Ȃ * ƓłB\n\n</BLOCKQUOTE>\n<LI><B>div(b[,n])</B></LI><BLOCKQUOTE>\nȉ̂悤Ɏgp܂B<BR>\nc = a.div(b,n)<BR>\nc = a / b ő n ܂ŌvZ܂B\na / b ̐x n 傫Ƃ BigDecimal.mode Ŏw肳ꂽ@Ŋۂ߂܂B<BR>\nn [Ȃ / ƓłB<BR>\nn ȗꂽƂ Float#div ƓlɌʂ(BigDecimal)ɂȂ܂B\n</BLOCKQUOTE>\n\n<LI><B>fix</B></LI><BLOCKQUOTE>\na ̏_ȉ̐؂̂āB<BR>\nc = a.fix\n</BLOCKQUOTE>\n<LI><B>frac</B></LI><BLOCKQUOTE>\na ̐̐؂̂āB<BR>\nc = a.frac\n</BLOCKQUOTE>\n\n<LI><B>floor[(n)]</B></LI><BLOCKQUOTE>\nc = a.floor<BR>\na ȉ̍ő吮iBigDecimal ljԂ܂B\n<CODE><PRE>\nc = BigDecimal(\"1.23456\").floor  #  ==> 1\nc = BigDecimal(\"-1.23456\").floor #  ==> -2\n</PRE></CODE>\nȉ̂悤Ɉ n ^邱Ƃł܂B<BR>\nn>=0 ȂA_ȉ n+1 ʂ̐𑀍삵܂(_ȉAő n ɂ܂)B<BR>\nn ̂Ƃ͏_ȏ n ڂ𑀍삵܂(_ʒu獶ɏȂƂ n  0 т܂)B<BR>\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").floor(4)   #  ==> 1.2345\n c = BigDecimal(\"15.23456\").floor(-1) #  ==> 10.0\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>ceil[(n)]</B></LI><BLOCKQUOTE>\nc = a.ceil<BR>\na ȏ̐̂AłvZA̒liBigDecimal ljԂ܂B\n<CODE><PRE>\nc = BigDecimal(\"1.23456\").ceil  #  ==> 2\nc = BigDecimal(\"-1.23456\").ceil #  ==> -1\n</PRE></CODE>\n\nȉ̂悤Ɉ^āA_ȉ n+1 ʂ̐𑀍삷邱Ƃł܂B<BR>\nn>=0 ȂA_ȉ n+1 ʂ̐𑀍삵܂(_ȉAő n ɂ܂)B<BR>\n n ̂Ƃ͏_ȏ n ڂ𑀍삵܂(_ʒu獶ɏȂƂ n  0 т܂)B<BR>\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").ceil(4)   # ==> 1.2346\n c = BigDecimal(\"15.23456\").ceil(-1) # ==> 20.0\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>\nc = a.round<BR>\n\nNX\\bh BigDecimal::mode(BigDecimal::ROUND_MODE,flag) Ŏw肵 \nROUND_MODE ɏ]Ċۂߑs܂B\nBigDecimal::mode(BigDecimal::ROUND_MODE,flag) ŉw肹AA\nw肵Ȃꍇ́u_ȉʂ̐ľܓĐiBigDecimal ljvɂ܂B<BR>\n<CODE><PRE>\n c = BigDecimal(\"1.23456\").round  #  ==> 1\n c = BigDecimal(\"-1.23456\").round #  ==> -1\n</PRE></CODE>\n\nȉ̂悤Ɉ^āA_ȉ n+1 ʂ̐𑀍삷邱Ƃł܂B<BR>\nn ̎́A_ȉ n+1 ʂ̐ۂ߂܂(_ȉAő n ɂ܂)B<BR>\nn ̂Ƃ͏_ȏ n ڂۂ߂܂(_ʒu獶ɏȂƂ n  0 т܂)B\n<CODE><PRE>\nc = BigDecimal(\"1.23456\").round(4)   #  ==> 1.2346\nc = BigDecimal(\"15.23456\").round(-1) #  ==> 20.0\n</PRE></CODE>\nQԖڂ̈w肷ƁABigDecimal#mode ̎w𖳎āAw肳ꂽ@\nۂߑs܂B\n<CODE><PRE>\nc = BigDecimal(\"1.23456\").round(3,BigDecimal::ROUND_HALF_EVEN)   #  ==> 1.234\nc = BigDecimal(\"1.23356\").round(3,BigDecimal::ROUND_HALF_EVEN)   #  ==> 1.234\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>truncate</B></LI><BLOCKQUOTE>\nc = a.truncate<BR>\n_ȉ̐؂̂ĂĐiBigDecimal ljɂ܂B<BR>\nȉ̂悤Ɉ^āA_ȉ n+1 ʂ̐𑀍삷邱Ƃł܂B<BR>\nn ̎́A_ȉ n+1 ʂ̐؂̂Ă܂(_ȉAő n ɂ܂)B\nn ̂Ƃ͏_ȏ n ڂ𑀍삵܂(_ʒu獶ɏȂƂ n  0 т܂)B<BR>\n<CODE><PRE>\nc = BigDecimal(\"1.23456\").truncate(4)   #  ==> 1.2345\nc = BigDecimal(\"15.23456\").truncate(-1) #  ==> 10.0\n</PRE></CODE>\n</BLOCKQUOTE>\n\n</BLOCKQUOTE>\n<LI><B>abs</B></LI><BLOCKQUOTE>\n̐Βl<BR>\nc = a.abs<BR>\n\n</BLOCKQUOTE>\n<LI><B>to_i</B></LI><BLOCKQUOTE>\n_ȉ؂̂ĂĐɕϊ܂B<BR>\ni = a.to_i<BR>\ni ͒lɉ Fixnum  Bignum ɂȂ܂B\na  Infinity  NaN ̂ƂAi  nil ɂȂ܂B\n</BLOCKQUOTE>\n<LI><B>to_f</B></LI><BLOCKQUOTE>\nFloat IuWFNgɕϊ܂B\n肫ߍׂlKvȂ split \\bh𗘗p\nB\n</BLOCKQUOTE>\n<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>\nɕϊ܂(ftHg \"0.xxxxxEn\" ̌`ɂȂ܂jB\n<CODE><PRE>\nBigDecimal(\"1.23456\").to_s  #  ==> \"0.123456E1\"\n</PRE></CODE>\n n ɐ̐w肳ꂽƂ́A_ŕ鍶EAꂼ n \nɋ󔒂ŋ؂܂B\n<CODE><PRE>\nBigDecimal(\"0.1234567890123456789\").to_s(10)   #  ==> \"0.1234567890 123456789E0\"\n</PRE></CODE>\n n ɐ̐\\w肷邱Ƃł܂B\n<CODE><PRE>\nBigDecimal(\"0.1234567890123456789\").to_s(\"10\") #  ==> \"0.1234567890 123456789E0\"\n</PRE></CODE>\n̍ŏ '+'i܂ ' 'jtƁAl̏ꍇA擪 '+'i܂ ' 'jt܂\nȉꍇ́A '-' t܂BjB\n<CODE><PRE>\nBigDecimal(\"0.1234567890123456789\").to_s(\" 10\") #  ==> \" 0.1234567890 123456789E0\"\nBigDecimal(\"0.1234567890123456789\").to_s(\"+10\") #  ==> \"+0.1234567890 123456789E0\"\nBigDecimal(\"-0.1234567890123456789\").to_s(\"10\") #  ==> \"-0.1234567890 123456789E0\"\n</PRE></CODE>\n\nɕ̍Ō E(܂ e)  F(܂ f) w肷邱ƂŁAȉ̂悤\n\\`ύX邱Ƃł܂B\n<CODE><PRE>\nBigDecimal(\"1234567890.123456789\").to_s(\"E\")  #  ==> \"0.1234567890123456789E10\"\nBigDecimal(\"1234567890.123456789\").to_s(\"F\")  #  ==> \"1234567890.123456789\"\nBigDecimal(\"1234567890.123456789\").to_s(\"5E\") #  ==> \"0.12345 67890 12345 6789E10\"\nBigDecimal(\"1234567890.123456789\").to_s(\"5F\") #  ==> \"12345 67890.12345 6789\"\n</PRE></CODE>\n\n</BLOCKQUOTE>\n<LI><B>exponent</B></LI><BLOCKQUOTE>\nw𐮐lŕԂ܂B\nn = a.exponent <BR>\n a ̒l 0.xxxxxxx*10**n Ӗ܂B\n</BLOCKQUOTE>\n\n<LI><B>precs</B></LI><BLOCKQUOTE>\nn,m  = a.precs<BR>\na ̗L (n) ƍőL (m) ̔zԂ܂B\n\n</BLOCKQUOTE>\n\n<LI><B>sign</B></LI><BLOCKQUOTE>\nl(sign &gt; 0)A(sign &lt; 0)Ȃ(sigh==0)ł邩̏Ԃ܂B\nn = a.sign <BR>\nƂƂ n ̒l a ȉ̂ƂӖ܂B<BR>\n() ̒̐́Aۂ̒lł(<A HREF=\"#STRUCT\">u\\v</A>Q)B<BR>\nn = BigDecimal::SIGN_NaN(0) : a  NaN<BR>\nn = BigDecimal::SIGN_POSITIVE_ZERO(1) : a  +0<BR>\nn = BigDecimal::SIGN_NEGATIVE_ZERO(-1) : a  -0<BR>\nn = BigDecimal::SIGN_POSITIVE_FINITE(2) : a ͐̒l<BR>\nn = BigDecimal::SIGN_NEGATIVE_FINITE(-2) : a ͕̒l<BR>\nn = BigDecimal::SIGN_POSITIVE_INFINITE(3) : a +Infinity<BR>\nn = BigDecimal::SIGN_NEGATIVE_INFINITE(-3) : a -Infinity<BR>\n\n</BLOCKQUOTE>\n<LI><B>nan?</B></LI><BLOCKQUOTE>\na.nan?  a NaN̂Ƃ^Ԃ܂B\n</BLOCKQUOTE>\n<LI><B>infinite?</B></LI><BLOCKQUOTE>\na.infinite?  a +̂Ƃ 1 A-̂Ƃ -1AȊÔƂ nil Ԃ܂B\n</BLOCKQUOTE>\n<LI><B>finite?</B></LI><BLOCKQUOTE>\na.finite?  a ܂ NaN łȂƂ^Ԃ܂B\n</BLOCKQUOTE>\n\n<LI><B>zero?</B></LI><BLOCKQUOTE>\na  0 Ȃ true ɂȂ܂B<BR>\nc = a.zero?\n</BLOCKQUOTE>\n<LI><B>nonzero?</B></LI><BLOCKQUOTE>\na  0 Ȃ nilA0 ȊOȂ a ̂̂Ԃ܂B<BR>\nc = a.nonzero?\n\n</BLOCKQUOTE>\n<LI><B>split</B></LI><BLOCKQUOTE>\nBigDecimal l 0.xxxxxxx*10**n ƕ\\ƂɁAiNaN̂Ƃ\n0AȊO+1-1ɂȂ܂jA\n̕i\"xxxxxxx\"jƁAi10jAXɎw n z\nԂ܂B<BR>\na=BigDecimal::new(\"3.14159265\")<BR>\nf,x,y,z = a.split<BR>\nƂƁAf=+1Ax=\"314159265\"Ay=10Az=1ɂȂ܂B<BR>\n]āA<BR>\ns = \"0.\"+x<BR>\nb = f*(s.to_f)*(y**z)<BR>\n Float ɕϊ邱Ƃł܂B\n</BLOCKQUOTE>\n<LI><B>inspect</B></LI><BLOCKQUOTE>\nfobOo͂Ɏgp܂B<BR>\np a=BigDecimal::new(\"3.14\",10)<BR>\nƂƁA[0x112344:'0.314E1',4(12)]̂悤ɏo͂܂B\nŏ16i̓IuWFNg̃AhXA '0.314E1' ͒lA\n4݂̗͌L(\\኱傫Ƃ܂)A\nŌ̓IuWFNg蓾ő包ɂȂ܂B\n</BLOCKQUOTE>\n<LI><B>**</B></LI><BLOCKQUOTE>\na  n vZ܂B͐B<BR>\nc = a ** n<BR>\nʂƂ c ̗L a  n {ȏɂȂ̂ŒӁB\n</BLOCKQUOTE>\n<LI><B>power</B></LI><BLOCKQUOTE>\n** ƓŁAa  n vZ܂B͐B<BR>\nc = a.power(n)<BR>\nʂƂ c ̗L a  n {ȏɂȂ̂ŒӁB\n</BLOCKQUOTE>\n<LI><B>sqrt</B></LI><BLOCKQUOTE>\na̗L n ̕in ̕ł͂܂j\nj[g@ŌvZ܂B<BR>\nc = a.sqrt(n)<BR>\n</BLOCKQUOTE>\n\n<LI><B>divmod,quo,modulo,%,remainder</B></LI><BLOCKQUOTE>\nڍׂ͑Ή Float ̊e\\bhQƂĉB\n</BLOCKQUOTE>\n\n<LI><B>&lt=&gt</B></LI><BLOCKQUOTE>\na==b Ȃ 0Aa &gt b Ȃ 1Aa &lt b Ȃ -1 ɂȂ܂B<BR>\nc = a &lt=&gt b \n</BLOCKQUOTE>\n</UL>\ńAǂŎ̔@łB<BR>\n<UL>\n<LI><B>==</B></LI>\n<LI><B>===</B></LI>\nu==vƓł case Ŏgp܂B\n<LI><B>!=</B></LI>\n<LI><B>&lt</B></LI>\n<LI><B>&lt=</B></LI>\n<LI><B>&gt</B></LI>\n<LI><B>&gt=</B></LI>\n</UL>\n\n<H3>coerceɂ</H3>\nBigDecimal IuWFNgZpZq̍ɂƂ́ABigDecimal IuWFNg\nEɂIuWFNg(KvȂ) BigDecimal ɕϊĂvZ܂B\n]āABigDecimal IuWFNgȊOłlӖ̂ȂEɒu\nZ͉\\łB<BR>\nÁiʏjlɎϊ邱Ƃ͂ł܂B\n𐔒lɎϊꍇ bigfloat.c \nu/* #define ENABLE_NUMERIC_STRING */ṽRgOĂA\năRpCAăCXg[Kv܂B\nŐl^ꍇ͒ӂKvłBlɕϊłȂƁA\nPɕϊ~߂邾ŃG[ɂ͂Ȃ܂B\"10XX\"ȂPOA\"XXXX\"͂O\nƈ܂B<BR>\n<CODE><PRE>\n   a = BigDecimal.E(20)\n   c = a * \"0.123456789123456789123456789\" #  BigDecimal ɕϊĂvZ\n</PRE></CODE>\n񐔂\\ƂāA\"Infinity\"A\"+Infinity\"A\"-Infinity\"A\"NaN\"\ngpł܂(啶Eʂ܂)BAmode \\bh false \nw肵ꍇ͗O܂B\n<BR>\n܂ABigDecimalNX coerceiRuby{QƁjT|[gĂ܂B\n]āABigDecimal IuWFNgEɂꍇ͑vłB\nA݂ Ruby C^v^̎dlA񂪍ɂƌvZł܂B<BR>\n<CODE><PRE>\n  a = BigDecimal.E(20)\n  c = \"0.123456789123456789123456789\" * a # G[\n</PRE></CODE>\nKvƂ͎v܂񂪁AǂĂƌl\n String IuWFNgpVȃNX쐬ĂA\ñNX coerce T|[gĂB\n\n<hr>\n<A NAME=\"#UNDEF\">\n<H2>A񐔁A[̈</H2>\nuvƂ͕\\łȂ炢傫ȐłBʂɈ߂\n +Infinityi̖j -Infinityi̖jƂ\n悤ɕ\\L܂B\n 1.0/0.0 ̂悤Ƀ[Ŋ悤ȌvZƂɐ܂B\n<BR><BR>\nu񐔁v 0.0/0.0  Infinity-Infinity ̌ʂ`łȂ\nvZƂɐ܂B񐔂 NaNiNot a Numberjƕ\\L܂B\nNaN ܂ތvZ͑S NaN ɂȂ܂B܂ NaN ͎܂߂āAǂȐ\nƂv܂B\n<BR><BR>\n[ +0.0  -0.0 ݂܂BA+0.0==-0.0  true łB\n<BR><BR>\nInfinityANaNA +0.0  -0.0 ܂񂾌vZʂ͑gݍ킹\n蕡GłB̂ĺAȉ̃vOsČʂ\nmFĂiʂɂāA^ԈႢ𔭌ꂽ\nm点肢܂jB\n\n<PRE>\n<CODE>\nrequire \"bigdecimal\"\n\naa  = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)\nba  = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)\nopa = %w(+ - * / <=> > >=  < == != <=)\n\nfor a in aa\n  for b in ba\n    for op in opa\n      x = BigDecimal::new(a)\n      y = BigDecimal::new(b)\n      eval(\"ans= x #{op} y;print a,' ',op,' ',b,' ==> ',ans.to_s,\\\"\\n\\\"\")\n    end\n  end\nend\n</CODE>\n</PRE>\n\n<hr>\n<A NAME=\"#STRUCT\">\n<H2>\\</H2>\nBigDecimalŕ_͍\\(Real)ŕ\\܂B\n̂ unsigned long ̔z(ȉ̍\\̗vffrac)ŊǗ܂B\nTOIɂ́Aȉ̂悤ɂȂ܂B<BR><BR>\n <_> = 0.xxxxxxxxx*BASE**n<BR><BR>\nŁAx͉\\ABASE͊iPOiȂPOjAn͎w\\\nlłBBASE傫قǁA傫Ȑl\\ł܂B܂Az̃TCY\nȂł܂BBASE͑傫قǓs悢킯łAfobÔ₷Ȃǂ\nlāA10000ɂȂĂ܂iBASEVpInit()֐ŎIɌvZ܂jB\ńA32rbg̏ꍇłB64rbg̏ꍇ͂Ƒ傫ȒlɂȂ܂B\ncOȂA64rbgł̃eXg͂܂Ă܂iAꂽ\nʂĂ΂肪łjB\nBASE10000̂Ƃ́Aȉ̉̔z(frac)̊evfɂ͍őłS\ni[܂B<BR><BR>\n_\\(Real)͈ȉ̂悤ɂȂĂ܂B\n<BR>\n<CODE><PRE>\n  typedef struct {\n     unsigned long MaxPrec; // ő吸x(frac[]̔zTCY)\n     unsigned long Prec;    // x(frac[]̎gpTCY)\n     short    sign;         // ȉ̂悤ɕ̏Ԃ`܂B\n                            //  ==0 : NaN\n                            //    1 : +0\n                            //   -1 : -0\n                            //    2 : ̒l\n                            //   -2 : ̒l\n                            //    3 : +Infinity\n                            //   -3 : -Infinity\n     unsigned short flag;   // e̐tbO\n     int      exponent;     // w̒l(*BASE**exponent)\n     unsigned long frac[1]; // ̔z()\n  } Real;\n</CODE></PRE>\nႦ 1234.56784321 Ƃ(BASE=10000Ȃ)<BR>\n<PRE>\n    0.1234 5678 4321*(10000)**1\n</PRE>\nł frac[0]=1234Afrac[1]=5678Afrac[2]=4321A\nPrec=3Asign=2Aexponent=1 ƂȂ܂BMaxPrec\nPrec 傫΂ł܂܂Bflag \ngp@͎ɈˑēŎgp܂B\n\n<hr>\n<A NAME=\"#BASE\">\n<H2>2i10i</H2>\nBigDecimal  <_> = 0.xxxxxxxxx*10**n Ƃ10i`Őlێ܂B\nAvZ@̕_̓\\́A܂łȂ <_> = 0.bbbbbbbb*2**n Ƃ\n2i`ʂł(x  0  9 ܂ŁAb  0  1 ̐)B\nBigDecimal Ȃ10i̓\\`̗p̂ȉɐ܂B\n<H4>10ĩbg</H4>\n<DL>\n<DT>fobÔ₷\n<DD>܂AvO쐬yłBfrac[0]=1234Afrac[1]=5678Afrac[2]=4321A\nexponent=1Asign=2 Ȃ琔l 1234.56784321 ł̂͌Βɕ܂B\n\n<DT>10i\\LꂽlȂmɓ\\ɕϊł\n<DD>Ⴆ΁Aȉ̂悤ȃvO͑S덷\nvZ邱Ƃł܂Bȉ̗́AsɈ̐l\nĂt@C file ̍vl߂̂łB\n<CODE><PRE>\n   file = File::open(....,\"r\")\n   s = BigDecimal::new(\"0\")\n   while line = file.gets\n      s = s + line\n   end\n</PRE></CODE>\n̗2iłƌ덷荞މ\\܂B\nႦ 0.1 2iŕ\\ 0.1 = b1*2**(-1)+b1*2**(-2)+b3*2**(-3)+b4*2**(-4)....\nƖɑĂ܂܂(b1=0,b2=0,b3=0,b4=1...)B bn(n=1,2,3,...) \n2i\\ 0  1 ̐łB]āAǂőł؂Kv܂B\nŕϊ덷܂BAēx10i\\LɂĈ悤\nꍇ͓K؂ȊۂߑiľܓjɂčĂ \"0.1\" ƕ\\܂BA\nł͐m 0.1 ł͂܂B\n\n<DT>L͗Lłi܂莩łj\n<DD>0.1 \\邽߂̗̈͂̔zvfi frac[0]=1 jōς݂܂B\nzvf̐10il玩IɌł܂B́Aϒ_Zł\n厖ȂƂłBt 0.1 2i\\Ƃɂ2i̗Lɂ̂ 0.1 \nł͌ł܂B\n</DL>\n\n<H3>10ĩfbg</H3>\n͍܂ł̃bǵÂ܂܃fbgɂȂ܂B\nA10i2iɕϊ悤ȑ͕ϊ덷\n𔺂ꍇ邱Ƃ͂ł܂B\nT̃Rs[^10i̓\\ĂȂ̂ŁA\nBigDecimal 𗘗pČ덷̌vZꍇ́AvZx\n𖳎ĂŌ܂ BigDecimal gpKv܂B\n\n<H3>ŏ͉H</H3>\nŌvZƂɂ킴킴2igl͋ɂ߂Ă܂łB\nvZ@Ƀf[^͂ƂقƂǂ̏ꍇA\n10iœ͂܂B̌ʁAdouble ̌vZ@\n\\͍ŏ덷Ăꍇ܂B\nBigDecimal ̓[U͂덷Ŏ荞ނƂł܂B\nfobO₷̂ƁAf[^ǂ݂ݎɌ덷Ȃ\nƂ̂ۂ̃bgłB\n\n<hr>\n<A NAME=\"#PREC\">\n<H2>vZxɂ</H2>\nc = a op b ƂvZ(op  + - * /)Ƃ̓\nȉ̂悤ɂȂ܂B<BR><BR>\nPDZ(a ̗L)+(b ̗L)A\nZ(a ̍őL)+(b ̍őL)̍ő包iۂ́A]TāA\n傫Ȃ܂jϐ c Vɐ܂B\nZ̏ꍇ́A덷oȂ̐x c 𐶐܂BႦ\n c = 0.1+0.1*10**(-100) ̂悤ȏꍇAc ̐x͂POOȏ̐x\n悤ɂȂ܂B\n<BR><BR>\nQD c = a op b ̌vZs܂B<BR><BR>\n̂悤ɁAZƏZł c ͕Ku덷oȂv̐x\nĐ܂(BigDecimal.limit w肵Ȃꍇ)B\nZ(a ̍őL)+(b ̍őL)̍ő包\n c ܂Ac = 1.0/3.0 ̂悤ȌvZŖ炩Ȃ悤ɁA\n c ̍ő吸x𒴂ƂŌvZł؂ꍇ܂B<BR><BR>\nɂAc ̍ő吸x a  b 傫Ȃ܂̂ c KvƂ\n[̈͑傫Ȃ邱ƂɒӂĉB\n<BR><BR>\nӁFu+,-,*,/vł͌ʂ̐xiLjŎwł܂B\nxRg[ꍇ́Aȉ̃CX^X\\bhgp܂B<BR>\n<UL>\n<LI>add,sub,mult,div</LI><BLOCKQUOTE>\ñ\\bh͐擪(ō)̐̌wł܂B\n<CODE><PRE>\n BigDecimal(\"2\").div(3,12) # 2.0/3.0 => 0.6666666666 67E0\n</PRE></CODE>\n</BLOCKQUOTE>\n<LI>truncate,round,ceil,floor</LI><BLOCKQUOTE>\ñ\\bh͏_̑Έʒuw肵Č肵܂B\n<CODE><PRE>\n BigDecimal(\"6.66666666666666\").round(12) # => 0.6666666666 667E1\n</PRE></CODE>\n</BLOCKQUOTE>\n</UL>\n<H3>ŐxRg[ꍇ</H3>\nŐx(L)Rg[ꍇ addAsubAmultAdiv ̃\\bh\ngpł܂B\nȉ̉~vZvÔ悤ɁA\n߂錅͎Ŏw肷邱Ƃł܂B\n<BR><BR>\n<CODE><PRE>\n#!/usr/local/bin/ruby\n\nrequire \"bigdecimal\"\n#\n# Calculates 3.1415.... (the number of times that a circle's diameter\n# will fit around the circle) using J. Machin's formula.\n#\ndef big_pi(sig) # sig: Number of significant figures\n  exp    = -sig\n  pi     = BigDecimal::new(\"0\")\n  two    = BigDecimal::new(\"2\")\n  m25    = BigDecimal::new(\"-0.04\")\n  m57121 = BigDecimal::new(\"-57121\")\n\n  u = BigDecimal::new(\"1\")\n  k = BigDecimal::new(\"1\")\n  w = BigDecimal::new(\"1\")\n  t = BigDecimal::new(\"-80\")\n  while (u.nonzero? && u.exponent >= exp) \n    t   = t*m25\n    u   = t.div(k,sig)\n    pi  = pi + u\n    k   = k+two\n  end\n\n  u = BigDecimal::new(\"1\")\n  k = BigDecimal::new(\"1\")\n  w = BigDecimal::new(\"1\")\n  t = BigDecimal::new(\"956\")\n  while (u.nonzero? && u.exponent >= exp )\n    t   = t.div(m57121,sig)\n    u   = t.div(k,sig)\n    pi  = pi + u\n    k   = k+two\n  end\n  pi\nend\n\nif $0 == __FILE__\n  if ARGV.size == 1\n    print \"PI(\"+ARGV[0]+\"):\\n\"\n    p big_pi(ARGV[0].to_i)\n  else\n    print \"TRY: ruby pi.rb 1000 \\n\"\n  end\nend\n\n</PRE></CODE>\n<HR>\n<FONT size=2>\n<I>\n<A HREF=\"http://www.tinyforest.gr.jp\">\n ΗY\n</A>\n(E-Mail:<A HREF=\"mailto:shigeo@tinyforest.gr.jp\">&ltshigeo@tinyforest.gr.jp&gt</U></A>)\n</I>\n</FONT>\n</TD>\n</TR>\n</TABLE>\n</BODY>\n</HTML>\n"
  },
  {
    "path": "ext/bigdecimal/depend",
    "content": "bigdecimal.o: bigdecimal.c bigdecimal.h $(hdrdir)/ruby.h\n"
  },
  {
    "path": "ext/bigdecimal/extconf.rb",
    "content": "require 'mkmf'\n\nbase_fig = 0\nsrc = \"(BASE * (BASE+1)) / BASE == (BASE+1)\"\nwhile try_static_assert(src, nil, \"-DBASE=10#{'0'*base_fig}UL\")\n  base_fig += 1\nend\n$defs << \"-DBASE=1#{'0'*base_fig}UL\" << \"-DBASE_FIG=#{base_fig}\"\n\ncreate_makefile('bigdecimal')\n"
  },
  {
    "path": "ext/bigdecimal/lib/bigdecimal/jacobian.rb",
    "content": "#\n# require 'bigdecimal/jacobian'\n#\n# Provides methods to compute the Jacobian matrix of a set of equations at a\n# point x. In the methods below:\n#\n# f is an Object which is used to compute the Jacobian matrix of the equations.\n# It must provide the following methods:\n#\n# f.values(x):: returns the values of all functions at x\n#\n# f.zero:: returns 0.0\n# f.one:: returns 1.0\n# f.two:: returns 1.0\n# f.ten:: returns 10.0\n#\n# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.\n#\n# x is the point at which to compute the Jacobian.\n#\n# fx is f.values(x).\n#\nmodule Jacobian\n  #--\n  def isEqual(a,b,zero=0.0,e=1.0e-8)\n    aa = a.abs\n    bb = b.abs\n    if aa == zero &&  bb == zero then\n          true\n    else\n          if ((a-b)/(aa+bb)).abs < e then\n             true\n          else\n             false\n          end\n    end\n  end\n  #++\n\n  # Computes the derivative of f[i] at x[i].\n  # fx is the value of f at x.\n  def dfdxi(f,fx,x,i)\n    nRetry = 0\n    n = x.size\n    xSave = x[i]\n    ok = 0\n    ratio = f.ten*f.ten*f.ten\n    dx = x[i].abs/ratio\n    dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps)\n    dx = f.one/f.ten     if isEqual(dx,f.zero,f.zero,f.eps)\n    until ok>0 do\n      s = f.zero\n      deriv = []\n      if(nRetry>100) then\n         raize \"Singular Jacobian matrix. No change at x[\" + i.to_s + \"]\"\n      end\n      dx = dx*f.two\n      x[i] += dx\n      fxNew = f.values(x)\n      for j in 0...n do\n        if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then\n           ok += 1\n           deriv <<= (fxNew[j]-fx[j])/dx\n        else\n           deriv <<= f.zero\n        end\n      end\n      x[i] = xSave\n    end\n    deriv\n  end\n\n  # Computes the Jacobian of f at x. fx is the value of f at x.\n  def jacobian(f,fx,x)\n    n = x.size\n    dfdx = Array::new(n*n)\n    for i in 0...n do\n      df = dfdxi(f,fx,x,i)\n      for j in 0...n do\n         dfdx[j*n+i] = df[j]\n      end\n    end\n    dfdx\n  end\nend\n"
  },
  {
    "path": "ext/bigdecimal/lib/bigdecimal/ludcmp.rb",
    "content": "#\n# Solves a*x = b for x, using LU decomposition.\n#\nmodule LUSolve\n  # Performs LU decomposition of the n by n matrix a.\n  def ludecomp(a,n,zero=0,one=1)\n    prec = BigDecimal.limit(nil)\n    ps     = []\n    scales = []\n    for i in 0...n do  # pick up largest(abs. val.) element in each row.\n      ps <<= i\n      nrmrow  = zero\n      ixn = i*n\n      for j in 0...n do\n         biggst = a[ixn+j].abs\n         nrmrow = biggst if biggst>nrmrow\n      end\n      if nrmrow>zero then\n         scales <<= one.div(nrmrow,prec)\n      else \n         raise \"Singular matrix\"\n      end\n    end\n    n1          = n - 1\n    for k in 0...n1 do # Gaussian elimination with partial pivoting.\n      biggst  = zero;\n      for i in k...n do\n         size = a[ps[i]*n+k].abs*scales[ps[i]]\n         if size>biggst then\n            biggst = size\n            pividx  = i\n         end\n      end\n      raise \"Singular matrix\" if biggst<=zero\n      if pividx!=k then\n        j = ps[k]\n        ps[k] = ps[pividx]\n        ps[pividx] = j\n      end\n      pivot   = a[ps[k]*n+k]\n      for i in (k+1)...n do\n        psin = ps[i]*n\n        a[psin+k] = mult = a[psin+k].div(pivot,prec)\n        if mult!=zero then\n           pskn = ps[k]*n\n           for j in (k+1)...n do\n             a[psin+j] -= mult.mult(a[pskn+j],prec)\n           end\n        end\n      end\n    end\n    raise \"Singular matrix\" if a[ps[n1]*n+n1] == zero\n    ps\n  end\n\n  # Solves a*x = b for x, using LU decomposition.\n  #\n  # a is a matrix, b is a constant vector, x is the solution vector.\n  #\n  # ps is the pivot, a vector which indicates the permutation of rows performed\n  # during LU decomposition.\n  def lusolve(a,b,ps,zero=0.0)\n    prec = BigDecimal.limit(nil)\n    n = ps.size\n    x = []\n    for i in 0...n do\n      dot = zero\n      psin = ps[i]*n\n      for j in 0...i do\n        dot = a[psin+j].mult(x[j],prec) + dot\n      end\n      x <<= b[ps[i]] - dot\n    end\n    (n-1).downto(0) do |i|\n       dot = zero\n       psin = ps[i]*n\n       for j in (i+1)...n do\n         dot = a[psin+j].mult(x[j],prec) + dot\n       end\n       x[i]  = (x[i]-dot).div(a[psin+i],prec)\n    end\n    x\n  end\nend\n"
  },
  {
    "path": "ext/bigdecimal/lib/bigdecimal/math.rb",
    "content": "#\n#--\n# Contents:\n#   sqrt(x, prec)\n#   sin (x, prec)\n#   cos (x, prec)\n#   atan(x, prec)  Note: |x|<1, x=0.9999 may not converge.\n#   exp (x, prec)\n#   log (x, prec)\n#   PI  (prec)\n#   E   (prec) == exp(1.0,prec)\n#\n# where:\n#   x    ... BigDecimal number to be computed.\n#            |x| must be small enough to get convergence.\n#   prec ... Number of digits to be obtained.\n#++\n#\n# Provides mathematical functions.\n#\n# Example:\n#\n#   require \"bigdecimal\"\n#   require \"bigdecimal/math\"\n#\n#   include BigMath\n#\n#   a = BigDecimal((PI(100)/2).to_s)\n#   puts sin(a,100) # -> 0.10000000000000000000......E1\n#\nmodule BigMath\n\n  # Computes the square root of x to the specified number of digits of \n  # precision.\n  #\n  # BigDecimal.new('2').sqrt(16).to_s \n  #  -> \"0.14142135623730950488016887242096975E1\"\n  #\n  def sqrt(x,prec)\n    x.sqrt(prec)\n  end\n\n  # Computes the sine of x to the specified number of digits of precision.\n  #\n  # If x is infinite or NaN, returns NaN.\n  def sin(x, prec)\n    raise ArgumentError, \"Zero or negative precision for sin\" if prec <= 0\n    return BigDecimal(\"NaN\") if x.infinite? || x.nan?\n    n    = prec + BigDecimal.double_fig\n    one  = BigDecimal(\"1\")\n    two  = BigDecimal(\"2\")\n    x1   = x\n    x2   = x.mult(x,n)\n    sign = 1\n    y    = x\n    d    = y\n    i    = one\n    z    = one\n    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      sign = -sign\n      x1  = x2.mult(x1,n)\n      i  += two\n      z  *= (i-one) * i\n      d   = sign * x1.div(z,m)\n      y  += d\n    end\n    y\n  end\n\n  # Computes the cosine of x to the specified number of digits of precision.\n  #\n  # If x is infinite or NaN, returns NaN.\n  def cos(x, prec)\n    raise ArgumentError, \"Zero or negative precision for cos\" if prec <= 0\n    return BigDecimal(\"NaN\") if x.infinite? || x.nan?\n    n    = prec + BigDecimal.double_fig\n    one  = BigDecimal(\"1\")\n    two  = BigDecimal(\"2\")\n    x1 = one\n    x2 = x.mult(x,n)\n    sign = 1\n    y = one\n    d = y\n    i = BigDecimal(\"0\")\n    z = one\n    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      sign = -sign\n      x1  = x2.mult(x1,n)\n      i  += two\n      z  *= (i-one) * i\n      d   = sign * x1.div(z,m)\n      y  += d\n    end\n    y\n  end\n\n  # Computes the arctangent of x to the specified number of digits of precision.\n  #\n  # If x is infinite or NaN, returns NaN.\n  # Raises an argument error if x > 1.\n  def atan(x, prec)\n    raise ArgumentError, \"Zero or negative precision for atan\" if prec <= 0\n    return BigDecimal(\"NaN\") if x.infinite? || x.nan?\n    raise ArgumentError, \"x.abs must be less than 1.0\" if x.abs>=1\n    n    = prec + BigDecimal.double_fig\n    y = x\n    d = y\n    t = x\n    r = BigDecimal(\"3\")\n    x2 = x.mult(x,n)\n    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      t = -t.mult(x2,n)\n      d = t.div(r,m)\n      y += d\n      r += 2\n    end\n    y\n  end\n\n  # Computes the value of e (the base of natural logarithms) raised to the \n  # power of x, to the specified number of digits of precision.\n  #\n  # If x is infinite or NaN, returns NaN.\n  #\n  # BigMath::exp(BigDecimal.new('1'), 10).to_s\n  # -> \"0.271828182845904523536028752390026306410273E1\"\n  def exp(x, prec)\n    raise ArgumentError, \"Zero or negative precision for exp\" if prec <= 0\n    return BigDecimal(\"NaN\") if x.infinite? || x.nan?\n    n    = prec + BigDecimal.double_fig\n    one  = BigDecimal(\"1\")\n    x1 = one\n    y  = one\n    d  = y\n    z  = one\n    i  = 0\n    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      x1  = x1.mult(x,n)\n      i += 1\n      z *= i\n      d  = x1.div(z,m)\n      y += d\n    end\n    y\n  end\n\n  # Computes the natural logarithm of x to the specified number of digits \n  # of precision.\n  #\n  # Returns x if x is infinite or NaN.\n  #\n  def log(x, prec)\n    raise ArgumentError, \"Zero or negative argument for log\" if x <= 0 || prec <= 0\n    return x if x.infinite? || x.nan?\n    one = BigDecimal(\"1\")\n    two = BigDecimal(\"2\")\n    n  = prec + BigDecimal.double_fig\n    x  = (x - one).div(x + one,n)\n    x2 = x.mult(x,n)\n    y  = x\n    d  = y\n    i = one\n    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      x  = x2.mult(x,n)\n      i += two\n      d  = x.div(i,m)\n      y += d\n    end\n    y*two\n  end\n\n  # Computes the value of pi to the specified number of digits of precision.\n  def PI(prec)\n    raise ArgumentError, \"Zero or negative argument for PI\" if prec <= 0\n    n      = prec + BigDecimal.double_fig\n    zero   = BigDecimal(\"0\")\n    one    = BigDecimal(\"1\")\n    two    = BigDecimal(\"2\")\n\n    m25    = BigDecimal(\"-0.04\")\n    m57121 = BigDecimal(\"-57121\")\n\n    pi     = zero\n\n    d = one\n    k = one\n    w = one\n    t = BigDecimal(\"-80\")\n    while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      t   = t*m25\n      d   = t.div(k,m)\n      k   = k+two\n      pi  = pi + d\n    end\n\n    d = one\n    k = one\n    w = one\n    t = BigDecimal(\"956\")\n    while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      t   = t.div(m57121,n)\n      d   = t.div(k,m)\n      pi  = pi + d\n      k   = k+two\n    end\n    pi\n  end\n\n  # Computes e (the base of natural logarithms) to the specified number of\n  # digits of precision.\n  def E(prec)\n    raise ArgumentError, \"Zero or negative precision for E\" if prec <= 0\n    n    = prec + BigDecimal.double_fig\n    one  = BigDecimal(\"1\")\n    y  = one\n    d  = y\n    z  = one\n    i  = 0\n    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)\n      m = BigDecimal.double_fig if m < BigDecimal.double_fig\n      i += 1\n      z *= i\n      d  = one.div(z,m)\n      y += d\n    end\n    y\n  end\nend\n"
  },
  {
    "path": "ext/bigdecimal/lib/bigdecimal/newton.rb",
    "content": "#\n# newton.rb \n#\n# Solves the nonlinear algebraic equation system f = 0 by Newton's method.\n# This program is not dependent on BigDecimal.\n#\n# To call:\n#    n = nlsolve(f,x)\n#  where n is the number of iterations required,\n#        x is the initial value vector\n#        f is an Object which is used to compute the values of the equations to be solved.\n# It must provide the following methods:\n#\n# f.values(x):: returns the values of all functions at x\n#\n# f.zero:: returns 0.0\n# f.one:: returns 1.0\n# f.two:: returns 1.0\n# f.ten:: returns 10.0\n#\n# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal.\n#\n# On exit, x is the solution vector.\n#\nrequire \"bigdecimal/ludcmp\"\nrequire \"bigdecimal/jacobian\"\n\nmodule Newton\n  include LUSolve\n  include Jacobian\n  \n  def norm(fv,zero=0.0)\n    s = zero\n    n = fv.size\n    for i in 0...n do\n      s += fv[i]*fv[i]\n    end\n    s\n  end\n\n  def nlsolve(f,x)\n    nRetry = 0\n    n = x.size\n\n    f0 = f.values(x)\n    zero = f.zero\n    one  = f.one\n    two  = f.two\n    p5 = one/two\n    d  = norm(f0,zero)\n    minfact = f.ten*f.ten*f.ten\n    minfact = one/minfact\n    e = f.eps\n    while d >= e do\n      nRetry += 1\n      # Not yet converged. => Compute Jacobian matrix\n      dfdx = jacobian(f,f0,x)\n      # Solve dfdx*dx = -f0 to estimate dx\n      dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero)\n      fact = two\n      xs = x.dup\n      begin\n        fact *= p5\n        if fact < minfact then\n          raise \"Failed to reduce function values.\"\n        end\n        for i in 0...n do\n          x[i] = xs[i] - dx[i]*fact\n        end\n        f0 = f.values(x)\n        dn = norm(f0,zero)\n      end while(dn>=d)\n      d = dn\n    end\n    nRetry\n  end\nend\n"
  },
  {
    "path": "ext/bigdecimal/lib/bigdecimal/util.rb",
    "content": "#\n# BigDecimal utility library.\n#\n# To use these functions, require 'bigdecimal/util'\n#\n# The following methods are provided to convert other types to BigDecimals:\n#\n#   String#to_d -> BigDecimal\n#   Float#to_d -> BigDecimal\n#   Rational#to_d -> BigDecimal\n#\n# The following method is provided to convert BigDecimals to other types:\n#\n#   BigDecimal#to_r -> Rational\n#\n# ----------------------------------------------------------------------\n#\nclass Float < Numeric\n  def to_d\n    BigDecimal(self.to_s)\n  end\nend\n\nclass String\n  def to_d\n    BigDecimal(self)\n  end\nend\n\nclass BigDecimal < Numeric\n  # Converts a BigDecimal to a String of the form \"nnnnnn.mmm\".\n  # This method is deprecated; use BigDecimal#to_s(\"F\") instead.\n  def to_digits\n     if self.nan? || self.infinite? || self.zero?\n        self.to_s\n     else\n       i       = self.to_i.to_s\n       s,f,y,z = self.frac.split\n       i + \".\" + (\"0\"*(-z)) + f\n     end\n  end\n\n  # Converts a BigDecimal to a Rational.\n  def to_r \n     sign,digits,base,power = self.split\n     numerator = sign*digits.to_i\n     denomi_power = power - digits.size # base is always 10\n     if denomi_power < 0\n        Rational(numerator,base ** (-denomi_power))\n     else\n        Rational(numerator * (base ** denomi_power),1)\n     end\n  end\nend\n\nclass Rational < Numeric\n  # Converts a Rational to a BigDecimal\n  def to_d(nFig=0)\n     num = self.numerator.to_s\n     if nFig<=0\n        nFig = BigDecimal.double_fig*2+1\n     end\n     BigDecimal.new(num).div(self.denominator,nFig)\n  end\nend\n"
  },
  {
    "path": "ext/bigdecimal/sample/linear.rb",
    "content": "#!/usr/local/bin/ruby\n\n#\n# linear.rb\n#\n# Solves linear equation system(A*x = b) by LU decomposition method.\n#  where  A is a coefficient matrix,x is an answer vector,b is a constant vector.\n#\n# USAGE:\n#   ruby linear.rb [input file solved]\n#\n\nrequire \"bigdecimal\"\nrequire \"bigdecimal/ludcmp\"\n\n#\n# NOTE:\n#   Change following BigDecimal::limit() if needed.\nBigDecimal::limit(100)\n#\n\ninclude LUSolve\ndef rd_order(na)\n   printf(\"Number of equations ?\") if(na <= 0)\n   n = ARGF.gets().to_i\nend\n\nna   = ARGV.size\nzero = BigDecimal::new(\"0.0\")\none  = BigDecimal::new(\"1.0\")\n\nwhile (n=rd_order(na))>0\n  a = []\n  as= []\n  b = []\n  if na <= 0\n     # Read data from console.\n     printf(\"\\nEnter coefficient matrix element A[i,j]\\n\");\n     for i in 0...n do\n       for j in 0...n do\n         printf(\"A[%d,%d]? \",i,j); s = ARGF.gets\n         a  << BigDecimal::new(s);\n         as << BigDecimal::new(s);\n       end\n       printf(\"Contatant vector element b[%d] ? \",i); b << BigDecimal::new(ARGF.gets);\n     end\n  else\n     # Read data from specified file.\n     printf(\"Coefficient matrix and constant vector.\\n\");\n     for i in 0...n do\n       s = ARGF.gets\n       printf(\"%d) %s\",i,s)\n       s = s.split\n       for j in 0...n do\n         a  << BigDecimal::new(s[j]);\n         as << BigDecimal::new(s[j]);\n       end\n       b << BigDecimal::new(s[n]);\n     end\n  end\n  x = lusolve(a,b,ludecomp(a,n,zero,one),zero)\n  printf(\"Answer(x[i] & (A*x-b)[i]) follows\\n\")\n  for i in 0...n do\n     printf(\"x[%d]=%s \",i,x[i].to_s)\n     s = zero\n     for j in 0...n do\n       s = s + as[i*n+j]*x[j]\n     end\n     printf(\" & %s\\n\",(s-b[i]).to_s)\n  end\nend\n"
  },
  {
    "path": "ext/bigdecimal/sample/nlsolve.rb",
    "content": "#!/usr/local/bin/ruby\n\n#\n# nlsolve.rb\n# An example for solving nonlinear algebraic equation system.\n#\n\nrequire \"bigdecimal\"\nrequire \"bigdecimal/newton\"\ninclude Newton\n\nclass Function\n  def initialize()\n    @zero = BigDecimal::new(\"0.0\")\n    @one  = BigDecimal::new(\"1.0\")\n    @two  = BigDecimal::new(\"2.0\")\n    @ten  = BigDecimal::new(\"10.0\")\n    @eps  = BigDecimal::new(\"1.0e-16\")\n  end\n  def zero;@zero;end\n  def one ;@one ;end\n  def two ;@two ;end\n  def ten ;@ten ;end\n  def eps ;@eps ;end\n  def values(x) # <= defines functions solved\n    f = []\n    f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0\n    f2 = x[0] - x[1]                  # f2 = x    - y        => 0\n    f <<= f1\n    f <<= f2\n    f\n  end\nend\n f = BigDecimal::limit(100)\n f = Function.new\n x = [f.zero,f.zero]      # Initial values\n n = nlsolve(f,x)\n p x\n"
  },
  {
    "path": "ext/bigdecimal/sample/pi.rb",
    "content": "#!/usr/local/bin/ruby\n\n#\n# pi.rb\n#\n# Calculates 3.1415.... (the number of times that a circle's diameter\n# will fit around the circle) using J. Machin's formula.\n#\n\nrequire \"bigdecimal\"\nrequire \"bigdecimal/math.rb\"\n\ninclude BigMath\n\nif ARGV.size == 1\n    print \"PI(\"+ARGV[0]+\"):\\n\"\n    p PI(ARGV[0].to_i)\nelse\n    print \"TRY: ruby pi.rb 1000 \\n\"\nend\n"
  },
  {
    "path": "ext/curses/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/curses/curses.c",
    "content": "/* -*- C -*-\n * $Id$\n *\n * ext/curses/curses.c\n * \n * by MAEDA Shugo (ender@pic-internet.or.jp)\n * modified by Yukihiro Matsumoto (matz@netlab.co.jp),\n *         Toki Yoshinori,\n *         Hitoshi Takahashi,\n *         and Takaaki Tateishi (ttate@kt.jaist.ac.jp)\n *\n * maintainers:\n * - Takaaki Tateishi (ttate@kt.jaist.ac.jp)\n */\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n\n#if defined(HAVE_NCURSES_H)\n# include <ncurses.h>\n#elif defined(HAVE_NCURSES_CURSES_H)\n# include <ncurses/curses.h>\n#elif defined(HAVE_CURSES_COLR_CURSES_H)\n# ifdef HAVE_STDARG_PROTOTYPES\n#  include <stdarg.h>\n# else\n#  include <varargs.h>\n# endif\n# include <curses_colr/curses.h>\n#else\n# include <curses.h>\n# if defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__)\n#  if !defined(_maxx)\n#  define _maxx maxx\n#  endif\n#  if !defined(_maxy)\n#  define _maxy maxy\n#  endif\n#  if !defined(_begx)\n#  define _begx begx\n#  endif\n#  if !defined(_begy)\n#  define _begy begy\n#  endif\n# endif\n#endif\n\n#ifdef HAVE_INIT_COLOR\n# define USE_COLOR 1\n#endif\n\n/* supports only ncurses mouse routines */\n#ifdef NCURSES_MOUSE_VERSION\n# define USE_MOUSE 1\n#endif\n\n#define NUM2CH NUM2LONG\n#define CH2FIX LONG2FIX\n\nstatic VALUE mCurses;\nstatic VALUE mKey;\nstatic VALUE cWindow;\n#ifdef USE_MOUSE\nstatic VALUE cMouseEvent;\n#endif\n\nstatic VALUE rb_stdscr;\n\nstruct windata {\n    WINDOW *window;\n};\n\n#define CHECK(c) c\n\nstatic VALUE window_attroff();\nstatic VALUE window_attron();\nstatic VALUE window_attrset();\n\nstatic void\nno_window()\n{\n    rb_raise(rb_eRuntimeError, \"already closed window\");\n}\n\n#define GetWINDOW(obj, winp) do {\\\n    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\\\n\trb_raise(rb_eSecurityError, \"Insecure: operation on untainted window\");\\\n    Data_Get_Struct(obj, struct windata, winp);\\\n    if (winp->window == 0) no_window();\\\n} while (0)\n\nstatic void\nfree_window(winp)\n    struct windata *winp;\n{\n    if (winp->window && winp->window != stdscr) delwin(winp->window);\n    winp->window = 0;\n    free(winp);\n}\n\nstatic VALUE\nprep_window(class, window)\n    VALUE class;\n    WINDOW *window;\n{\n    VALUE obj;\n    struct windata *winp;\n\n    if (window == NULL) {\n\trb_raise(rb_eRuntimeError, \"failed to create window\");\n    }\n\n    obj = rb_obj_alloc(class);\n    Data_Get_Struct(obj, struct windata, winp);\n    winp->window = window;\n    \n    return obj;    \n}\n\n/*-------------------------- module Curses --------------------------*/\n\n/* def init_screen */\nstatic VALUE\ncurses_init_screen()\n{\n    rb_secure(4);\n    if (rb_stdscr) return rb_stdscr;\n    initscr();\n    if (stdscr == 0) {\n\trb_raise(rb_eRuntimeError, \"can't initialize curses\");\n    }\n    clear();\n    rb_stdscr = prep_window(cWindow, stdscr);\n    return rb_stdscr;\n}\n\n/* def stdscr */\n#define curses_stdscr curses_init_screen\n\n/* def close_screen */\nstatic VALUE\ncurses_close_screen()\n{\n    curses_stdscr();\n#ifdef HAVE_ISENDWIN\n    if (!isendwin())\n#endif\n\tendwin();\n    rb_stdscr = 0;\n    return Qnil;\n}\n\nstatic void\ncurses_finalize(VALUE dummy)\n{\n    if (stdscr\n#ifdef HAVE_ISENDWIN\n\t&& !isendwin()\n#endif\n\t)\n\tendwin();\n    rb_stdscr = 0;\n    rb_gc_unregister_address(&rb_stdscr);\n}\n\n/* def closed? */\nstatic VALUE\ncurses_closed()\n{\n#ifdef HAVE_ISENDWIN\n    curses_stdscr();\n    if (isendwin()) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n#else\n    rb_notimplement();\n#endif\n}\n\n/* def clear */\nstatic VALUE\ncurses_clear(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    wclear(stdscr);\n    return Qnil;\n}\n\n/* def clrtoeol */\nstatic VALUE\ncurses_clrtoeol()\n{\n    curses_stdscr();\n    clrtoeol();\n    return Qnil;\n}\n\n/* def refresh */\nstatic VALUE\ncurses_refresh(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    refresh();\n    return Qnil;\n}\n\n/* def doupdate */\nstatic VALUE\ncurses_doupdate(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n#ifdef HAVE_DOUPDATE\n    doupdate();\n#else\n    refresh();\n#endif\n    return Qnil;\n}\n\n/* def echo */\nstatic VALUE\ncurses_echo(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    echo();\n    return Qnil;\n}\n\n/* def noecho */\nstatic VALUE\ncurses_noecho(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    noecho();\n    return Qnil;\n}\n\n/* def raw */\nstatic VALUE\ncurses_raw(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    raw();\n    return Qnil;\n}\n\n/* def noraw */\nstatic VALUE\ncurses_noraw(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    noraw();\n    return Qnil;\n}\n\n/* def cbreak */\nstatic VALUE\ncurses_cbreak(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    cbreak();\n    return Qnil;\n}\n\n/* def nocbreak */\nstatic VALUE\ncurses_nocbreak(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    nocbreak();\n    return Qnil;\n}\n\n/* def nl */\nstatic VALUE\ncurses_nl(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    nl();\n    return Qnil;\n}\n\n/* def nonl */\nstatic VALUE\ncurses_nonl(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    nonl();\n    return Qnil;\n}\n\n/* def beep */\nstatic VALUE\ncurses_beep(obj)\n    VALUE obj;\n{\n#ifdef HAVE_BEEP\n    curses_stdscr();\n    beep();\n#endif\n    return Qnil;\n}\n\n/* def flash */\nstatic VALUE\ncurses_flash(obj)\n    VALUE obj;\n{\n#ifdef HAVE_FLASH\n    curses_stdscr();\n    flash();\n#endif\n    return Qnil;\n}\n\n/* def ungetch */\nstatic VALUE\ncurses_ungetch(obj, ch)\n    VALUE obj;\n    VALUE ch;\n{\n#ifdef HAVE_UNGETCH\n    curses_stdscr();\n    ungetch(NUM2INT(ch));\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n/* def setpos(y, x) */\nstatic VALUE\ncurses_setpos(obj, y, x)\n    VALUE obj;\n    VALUE y;\n    VALUE x;\n{\n    curses_stdscr();\n    move(NUM2INT(y), NUM2INT(x));\n    return Qnil;\n}\n\n/* def standout */\nstatic VALUE\ncurses_standout(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    standout();\n    return Qnil;\n}\n\n/* def standend */\nstatic VALUE\ncurses_standend(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    standend();\n    return Qnil;\n}\n\n/* def inch */\nstatic VALUE\ncurses_inch(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    return CH2FIX(inch());\n}\n\n/* def addch(ch) */\nstatic VALUE\ncurses_addch(obj, ch)\n    VALUE obj;\n    VALUE ch;\n{\n    curses_stdscr();\n    addch(NUM2CH(ch));\n    return Qnil;\n}\n\n/* def insch(ch) */\nstatic VALUE\ncurses_insch(obj, ch)\n    VALUE obj;\n    VALUE ch;\n{\n    curses_stdscr();\n    insch(NUM2CH(ch));\n    return Qnil;\n}\n\n/* def addstr(str) */\nstatic VALUE\ncurses_addstr(obj, str)\n    VALUE obj;\n    VALUE str;\n{\n    curses_stdscr();\n    if (!NIL_P(str)) {\n\taddstr(STR2CSTR(str));\n    }\n    return Qnil;\n}\n\n/* def getch */\nstatic VALUE\ncurses_getch(obj)\n    VALUE obj;\n{\n    rb_read_check(stdin);\n    curses_stdscr();\n    return UINT2NUM(getch());\n}\n\n/* def getstr */\nstatic VALUE\ncurses_getstr(obj)\n    VALUE obj;\n{\n    char rtn[1024]; /* This should be big enough.. I hope */\n\n    curses_stdscr();\n    rb_read_check(stdin);\n#if defined(HAVE_GETNSTR)\n    getnstr(rtn,1023);\n#else\n    getstr(rtn);\n#endif\n    return rb_tainted_str_new2(rtn);\n}\n\n/* def delch */\nstatic VALUE\ncurses_delch(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n    delch();\n    return Qnil;\n}\n\n/* def delelteln */\nstatic VALUE\ncurses_deleteln(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n#if defined(HAVE_DELETELN) || defined(deleteln)\n    deleteln();\n#endif\n    return Qnil;\n}\n\n/* def insertln */\nstatic VALUE\ncurses_insertln(obj)\n    VALUE obj;\n{\n    curses_stdscr();\n#if defined(HAVE_INSERTLN) || defined(insertln)\n    insertln();\n#endif\n    return Qnil;\n}\n\n/* def keyname */\nstatic VALUE\ncurses_keyname(obj, c)\n    VALUE obj;\n    VALUE c;\n{\n#ifdef HAVE_KEYNAME\n  const char *name;\n\n  curses_stdscr();\n  name = keyname(NUM2INT(c));\n  if (name) {\n    return rb_str_new2(name);\n  } else {\n    return Qnil;\n  }\n#else\n  return Qnil;\n#endif\n}\n\nstatic VALUE\ncurses_lines()\n{\n    return INT2FIX(LINES);\n}\n\nstatic VALUE\ncurses_cols()\n{\n    return INT2FIX(COLS);\n}\n\nstatic VALUE\ncurses_curs_set(VALUE obj, VALUE visibility)\n{\n#ifdef HAVE_CURS_SET\n  int n;\n  curses_stdscr();\n  return (n = curs_set(NUM2INT(visibility)) != ERR) ? INT2FIX(n) : Qnil;\n#else\n  return Qnil;\n#endif\n}\n\nstatic VALUE\ncurses_scrl(VALUE obj, VALUE n)\n{\n  /* may have to raise exception on ERR */\n#ifdef HAVE_SCRL\n  curses_stdscr();\n  return (scrl(NUM2INT(n)) == OK) ? Qtrue : Qfalse;\n#else\n  return Qfalse;\n#endif\n}\n\nstatic VALUE\ncurses_setscrreg(VALUE obj, VALUE top, VALUE bottom)\n{\n  /* may have to raise exception on ERR */\n#ifdef HAVE_SETSCRREG\n  curses_stdscr();\n  return (setscrreg(NUM2INT(top), NUM2INT(bottom)) == OK) ? Qtrue : Qfalse;\n#else\n  return Qfalse;\n#endif\n}\n\nstatic VALUE\ncurses_attroff(VALUE obj, VALUE attrs)\n{\n  curses_stdscr();\n  return window_attroff(rb_stdscr,attrs);  \n  /* return INT2FIX(attroff(NUM2INT(attrs))); */\n}\n\nstatic VALUE\ncurses_attron(VALUE obj, VALUE attrs)\n{\n  curses_stdscr();\n  return window_attron(rb_stdscr,attrs);\n  /* return INT2FIX(attroff(NUM2INT(attrs))); */\n}\n\nstatic VALUE\ncurses_attrset(VALUE obj, VALUE attrs)\n{\n  curses_stdscr();\n  return window_attrset(rb_stdscr,attrs);\n  /* return INT2FIX(attroff(NUM2INT(attrs))); */\n}\n\nstatic VALUE\ncurses_bkgdset(VALUE obj, VALUE ch)\n{\n#ifdef HAVE_BKGDSET\n  curses_stdscr();\n  bkgdset(NUM2CH(ch));\n#endif\n  return Qnil;\n}\n\nstatic VALUE\ncurses_bkgd(VALUE obj, VALUE ch)\n{\n#ifdef HAVE_BKGD\n  curses_stdscr();\n  return (bkgd(NUM2CH(ch)) == OK) ? Qtrue : Qfalse;\n#else\n  return Qfalse;\n#endif\n}\n\nstatic VALUE\ncurses_resizeterm(VALUE obj, VALUE lin, VALUE col)\n{\n#if defined(HAVE_RESIZETERM)\n  curses_stdscr();\n  return (resizeterm(NUM2INT(lin),NUM2INT(col)) == OK) ? Qtrue : Qfalse;\n#else\n  return Qnil;\n#endif\n}\n\n#ifdef USE_COLOR\nstatic VALUE\ncurses_start_color(VALUE obj)\n{\n  /* may have to raise exception on ERR */\n  curses_stdscr();\n  return (start_color() == OK) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_init_pair(VALUE obj, VALUE pair, VALUE f, VALUE b)\n{\n  /* may have to raise exception on ERR */\n  curses_stdscr();\n  return (init_pair(NUM2INT(pair),NUM2INT(f),NUM2INT(b)) == OK) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_init_color(VALUE obj, VALUE color, VALUE r, VALUE g, VALUE b)\n{\n  /* may have to raise exception on ERR */\n  curses_stdscr();\n  return (init_color(NUM2INT(color),NUM2INT(r),\n\t\t     NUM2INT(g),NUM2INT(b)) == OK) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_has_colors(VALUE obj)\n{\n  curses_stdscr();\n  return has_colors() ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_can_change_color(VALUE obj)\n{\n  curses_stdscr();\n  return can_change_color() ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_color_content(VALUE obj, VALUE color)\n{\n  short r,g,b;\n\n  curses_stdscr();\n  color_content(NUM2INT(color),&r,&g,&b);\n  return rb_ary_new3(3,INT2FIX(r),INT2FIX(g),INT2FIX(b));\n}\n\nstatic VALUE\ncurses_pair_content(VALUE obj, VALUE pair)\n{\n  short f,b;\n\n  curses_stdscr();\n  pair_content(NUM2INT(pair),&f,&b);\n  return rb_ary_new3(2,INT2FIX(f),INT2FIX(b));\n}\n\nstatic VALUE\ncurses_color_pair(VALUE obj, VALUE attrs)\n{\n  return INT2FIX(COLOR_PAIR(NUM2INT(attrs)));\n}\n\nstatic VALUE\ncurses_pair_number(VALUE obj, VALUE attrs)\n{\n  curses_stdscr();\n  return INT2FIX(PAIR_NUMBER(NUM2INT(attrs)));\n}\n#endif /* USE_COLOR */\n\n#ifdef USE_MOUSE\nstruct mousedata {\n  MEVENT *mevent;\n};\n\nstatic void\nno_mevent()\n{\n  rb_raise(rb_eRuntimeError, \"no such mouse event\");\n}\n\n#define GetMOUSE(obj, data) do {\\\n    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\\\n\trb_raise(rb_eSecurityError, \"Insecure: operation on untainted mouse\");\\\n    Data_Get_Struct(obj, struct mousedata, data);\\\n    if (data->mevent == 0) no_mevent();\\\n} while (0)\n\nstatic void\ncurses_mousedata_free(struct mousedata *mdata)\n{\n  if (mdata->mevent)\n    free(mdata->mevent);\n}\n\nstatic VALUE\ncurses_getmouse(VALUE obj)\n{\n  struct mousedata *mdata;\n  VALUE val;\n\n  curses_stdscr();\n  val = Data_Make_Struct(cMouseEvent,struct mousedata,\n\t\t\t 0,curses_mousedata_free,mdata);\n  mdata->mevent = (MEVENT*)xmalloc(sizeof(MEVENT));\n  return (getmouse(mdata->mevent) == OK) ? val : Qnil;\n}\n\nstatic VALUE\ncurses_ungetmouse(VALUE obj, VALUE mevent)\n{\n  struct mousedata *mdata;\n\n  curses_stdscr();\n  GetMOUSE(mevent,mdata);\n  return (ungetmouse(mdata->mevent) == OK) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_mouseinterval(VALUE obj, VALUE interval)\n{\n  curses_stdscr();\n  return mouseinterval(NUM2INT(interval)) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ncurses_mousemask(VALUE obj, VALUE mask)\n{\n  curses_stdscr();\n  return INT2NUM(mousemask(NUM2UINT(mask),NULL));\n}\n\n#define DEFINE_MOUSE_GET_MEMBER(func_name,mem) \\\nstatic VALUE func_name (VALUE mouse) \\\n{ \\\n  struct mousedata *mdata; \\\n  GetMOUSE(mouse, mdata); \\\n  return (UINT2NUM(mdata->mevent -> mem)); \\\n}\n\nDEFINE_MOUSE_GET_MEMBER(curs_mouse_id, id)\nDEFINE_MOUSE_GET_MEMBER(curs_mouse_x, x)\nDEFINE_MOUSE_GET_MEMBER(curs_mouse_y, y)\nDEFINE_MOUSE_GET_MEMBER(curs_mouse_z, z)\nDEFINE_MOUSE_GET_MEMBER(curs_mouse_bstate, bstate)\n#undef define_curs_mouse_member\n#endif /* USE_MOUSE */\n\nstatic VALUE\ncurses_timeout(VALUE obj, VALUE delay)\n{\n#ifdef HAVE_TIMEOUT\n  curses_stdscr();\n  timeout(NUM2INT(delay));\n  return Qnil;\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE\ncurses_def_prog_mode(VALUE obj)\n{\n#ifdef HAVE_DEF_PROG_MODE\n  curses_stdscr();\n  return def_prog_mode() == OK ? Qtrue : Qfalse;\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE\ncurses_reset_prog_mode(VALUE obj)\n{\n#ifdef HAVE_RESET_PROG_MODE\n  curses_stdscr();\n  return reset_prog_mode() == OK ? Qtrue : Qfalse;\n#else\n    rb_notimplement();\n#endif\n}\n\n/*-------------------------- class Window --------------------------*/\n\n/* def self.allocate */\nstatic VALUE\nwindow_s_allocate(VALUE class)\n{\n    struct windata *winp;\n\n    return Data_Make_Struct(class, struct windata, 0, free_window, winp);\n}\n\n/* def initialize(h, w, top, left) */\nstatic VALUE\nwindow_initialize(obj, h, w, top, left)\n    VALUE obj;\n    VALUE h;\n    VALUE w;\n    VALUE top;\n    VALUE left;\n{\n    struct windata *winp;\n    WINDOW *window;\n\n    rb_secure(4);\n    curses_init_screen();\n    Data_Get_Struct(obj, struct windata, winp);\n    if (winp->window) delwin(winp->window);\n    window = newwin(NUM2INT(h), NUM2INT(w), NUM2INT(top), NUM2INT(left));\n    wclear(window);\n    winp->window = window;\n\n    return obj;\n}\n\n/* def subwin(height, width, top, left) */\nstatic VALUE\nwindow_subwin(obj, height, width, top, left)\n    VALUE obj;\n    VALUE height;\n    VALUE width;\n    VALUE top;\n    VALUE left;\n{\n    struct windata *winp;\n    WINDOW *window;\n    VALUE win;\n    int h, w, t, l;\n\n    h = NUM2INT(height);\n    w = NUM2INT(width);\n    t = NUM2INT(top);\n    l = NUM2INT(left);\n    GetWINDOW(obj, winp);\n    window = subwin(winp->window, h, w, t, l);\n    win = prep_window(rb_obj_class(obj), window);\n\n    return win;\n}\n\n/* def close */\nstatic VALUE\nwindow_close(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    delwin(winp->window);\n    winp->window = 0;\n\n    return Qnil;\n}\n\n/* def clear */\nstatic VALUE\nwindow_clear(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wclear(winp->window);\n    \n    return Qnil;\n}\n\n/* def clrtoeol */\nstatic VALUE\nwindow_clrtoeol(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wclrtoeol(winp->window);\n    \n    return Qnil;\n}\n\n/* def refresh */\nstatic VALUE\nwindow_refresh(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wrefresh(winp->window);\n    \n    return Qnil;\n}\n\n/* def noutrefresh */\nstatic VALUE\nwindow_noutrefresh(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n\n    GetWINDOW(obj, winp);\n#ifdef HAVE_DOUPDATE\n    wnoutrefresh(winp->window);\n#else\n    wrefresh(winp->window);\n#endif\n\n    return Qnil;\n}\n\n/* def move(y, x) */\nstatic VALUE\nwindow_move(obj, y, x)\n    VALUE obj;\n    VALUE y;\n    VALUE x;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    mvwin(winp->window, NUM2INT(y), NUM2INT(x));\n\n    return Qnil;\n}\n\n/* def setpos(y, x) */\nstatic VALUE\nwindow_setpos(obj, y, x)\n    VALUE obj;\n    VALUE y;\n    VALUE x;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wmove(winp->window, NUM2INT(y), NUM2INT(x));\n    return Qnil;\n}\n\n/* def cury */\nstatic VALUE\nwindow_cury(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    int x, y;\n\n    GetWINDOW(obj, winp);\n    getyx(winp->window, y, x);\n    return INT2FIX(y);\n}\n\n/* def curx */\nstatic VALUE\nwindow_curx(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    int x, y;\n\n    GetWINDOW(obj, winp);\n    getyx(winp->window, y, x);\n    return INT2FIX(x);\n}\n\n/* def maxy */\nstatic VALUE\nwindow_maxy(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n\n    GetWINDOW(obj, winp);\n#if defined(getmaxy)\n    return INT2FIX(getmaxy(winp->window));\n#elif defined(getmaxyx)\n    {\n\tint x, y;\n\tgetmaxyx(winp->window, y, x);\n\treturn INT2FIX(y);\n    }\n#else\n    return INT2FIX(winp->window->_maxy+1);\n#endif\n}\n\n/* def maxx */\nstatic VALUE\nwindow_maxx(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n\n    GetWINDOW(obj, winp);\n#if defined(getmaxx)\n    return INT2FIX(getmaxx(winp->window));\n#elif defined(getmaxyx)\n    {\n\tint x, y;\n\tgetmaxyx(winp->window, y, x);\n\treturn INT2FIX(x);\n    }\n#else\n    return INT2FIX(winp->window->_maxx+1);\n#endif\n}\n\n/* def begy */\nstatic VALUE\nwindow_begy(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    int x, y;\n\n    GetWINDOW(obj, winp);\n#ifdef getbegyx\n    getbegyx(winp->window, y, x);\n    return INT2FIX(y);\n#else\n    return INT2FIX(winp->window->_begy);\n#endif\n}\n\n/* def begx */\nstatic VALUE\nwindow_begx(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    int x, y;\n\n    GetWINDOW(obj, winp);\n#ifdef getbegyx\n    getbegyx(winp->window, y, x);\n    return INT2FIX(x);\n#else\n    return INT2FIX(winp->window->_begx);\n#endif\n}\n\n/* def box(vert, hor) */\nstatic VALUE\nwindow_box(argc, argv, self)\n    int argc;\n    VALUE argv[], self;\n{\n    struct windata *winp; \n    VALUE vert, hor, corn;\n\n    rb_scan_args(argc, argv, \"21\", &vert, &hor, &corn);\n\n    GetWINDOW(self, winp);\n    box(winp->window, NUM2CH(vert), NUM2CH(hor));\n\n    if (!NIL_P(corn)) {\n      int cur_x, cur_y, x, y;\n      chtype c;\n\n      c = NUM2CH(corn);\n      getyx(winp->window, cur_y, cur_x);\n      x = NUM2INT(window_maxx(self)) - 1;\n      y = NUM2INT(window_maxy(self)) - 1;\n      wmove(winp->window, 0, 0);\n      waddch(winp->window, c);\n      wmove(winp->window, y, 0);\n      waddch(winp->window, c);\n      wmove(winp->window, y, x);\n      waddch(winp->window, c);\n      wmove(winp->window, 0, x);\n      waddch(winp->window, c);\n      wmove(winp->window, cur_y, cur_x);\n    }\n    \n    return Qnil;\n}\n\n/* def standout */\nstatic VALUE\nwindow_standout(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wstandout(winp->window);\n    return Qnil;\n}\n\n/* def standend */\nstatic VALUE\nwindow_standend(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wstandend(winp->window);\n    return Qnil;\n}\n\n/* def inch */\nstatic VALUE\nwindow_inch(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    return CH2FIX(winch(winp->window));\n}\n\n/* def addch(ch) */\nstatic VALUE\nwindow_addch(obj, ch)\n    VALUE obj;\n    VALUE ch;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    waddch(winp->window, NUM2CH(ch));\n    \n    return Qnil;\n}\n\n/* def insch(ch) */\nstatic VALUE\nwindow_insch(obj, ch)\n    VALUE obj;\n    VALUE ch;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    winsch(winp->window, NUM2CH(ch));\n    \n    return Qnil;\n}\n\n/* def addstr(str) */\nstatic VALUE\nwindow_addstr(obj, str)\n    VALUE obj;\n    VALUE str;\n{\n    if (!NIL_P(str)) {\n\tstruct windata *winp;\n\n\tGetWINDOW(obj, winp);\n\twaddstr(winp->window, STR2CSTR(str));\n    }\n    return Qnil;\n}\n\n/* def <<(str) */\nstatic VALUE\nwindow_addstr2(obj, str)\n    VALUE obj;\n    VALUE str;\n{\n    window_addstr(obj, str);\n    return obj;\n}\n\n/* def getch */\nstatic VALUE\nwindow_getch(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    rb_read_check(stdin);\n    GetWINDOW(obj, winp);\n    return UINT2NUM(wgetch(winp->window));\n}\n\n/* def getstr */\nstatic VALUE\nwindow_getstr(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    char rtn[1024]; /* This should be big enough.. I hope */\n    \n    GetWINDOW(obj, winp);\n    rb_read_check(stdin);\n#if defined(HAVE_WGETNSTR)\n    wgetnstr(winp->window, rtn, 1023);\n#else\n    wgetstr(winp->window, rtn);\n#endif\n    return rb_tainted_str_new2(rtn);\n}\n\n/* def delch */\nstatic VALUE\nwindow_delch(obj)\n    VALUE obj;\n{\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wdelch(winp->window);\n    return Qnil;\n}\n\n/* def delelteln */\nstatic VALUE\nwindow_deleteln(obj)\n    VALUE obj;\n{\n#if defined(HAVE_WDELETELN) || defined(wdeleteln)\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    wdeleteln(winp->window);\n#endif\n    return Qnil;\n}\n\n/* def insertln */\nstatic VALUE\nwindow_insertln(obj)\n    VALUE obj;\n{\n#if defined(HAVE_WINSERTLN) || defined(winsertln)\n    struct windata *winp;\n    \n    GetWINDOW(obj, winp);\n    winsertln(winp->window);\n#endif\n    return Qnil;\n}\n\nstatic VALUE\nwindow_scrollok(VALUE obj, VALUE bf)\n{\n  struct windata *winp;\n\n  GetWINDOW(obj, winp);\n  scrollok(winp->window, RTEST(bf) ? TRUE : FALSE);\n  return Qnil;\n}\n\nstatic VALUE\nwindow_idlok(VALUE obj, VALUE bf)\n{\n  struct windata *winp;\n\n  GetWINDOW(obj, winp);\n  idlok(winp->window, RTEST(bf) ? TRUE : FALSE);\n  return Qnil;\n}\n\nstatic VALUE\nwindow_setscrreg(VALUE obj, VALUE top, VALUE bottom)\n{\n#ifdef HAVE_WSETSCRREG\n  struct windata *winp;\n  int res;\n\n  GetWINDOW(obj, winp);\n  res = wsetscrreg(winp->window, NUM2INT(top), NUM2INT(bottom));\n  /* may have to raise exception on ERR */\n  return (res == OK) ? Qtrue : Qfalse;\n#else\n  return Qfalse;\n#endif\n}\n\n#if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET)\nstatic VALUE\nwindow_color_set(VALUE obj, VALUE col) \n{\n  struct windata *winp;\n  int res;\n\n  GetWINDOW(obj, winp);\n  res = wcolor_set(winp->window, NUM2INT(col), NULL);\n  return (res == OK) ? Qtrue : Qfalse;\n}\n#endif /* USE_COLOR */\n\nstatic VALUE\nwindow_scroll(VALUE obj)\n{\n  struct windata *winp;\n\n  GetWINDOW(obj, winp);\n  /* may have to raise exception on ERR */\n  return (scroll(winp->window) == OK) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nwindow_scrl(VALUE obj, VALUE n)\n{\n#ifdef HAVE_WSCRL\n  struct windata *winp;\n\n  GetWINDOW(obj, winp);\n  /* may have to raise exception on ERR */\n  return (wscrl(winp->window,NUM2INT(n)) == OK) ? Qtrue : Qfalse;\n#else\n  return Qfalse;\n#endif\n}\n\nstatic VALUE\nwindow_attroff(VALUE obj, VALUE attrs)\n{\n#ifdef HAVE_WATTROFF\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  return INT2FIX(wattroff(winp->window,NUM2INT(attrs)));\n#else\n  return Qtrue;\n#endif\n}\n\nstatic VALUE\nwindow_attron(VALUE obj, VALUE attrs)\n{\n#ifdef HAVE_WATTRON\n  struct windata *winp;\n  VALUE val;\n\n  GetWINDOW(obj,winp);\n  val = INT2FIX(wattron(winp->window,NUM2INT(attrs)));\n  if( rb_block_given_p() ){\n    rb_yield(val);\n    wattroff(winp->window,NUM2INT(attrs));\n    return val;\n  }\n  else{\n    return val;\n  }\n#else\n  return Qtrue;\n#endif\n}\n\nstatic VALUE\nwindow_attrset(VALUE obj, VALUE attrs)\n{\n#ifdef HAVE_WATTRSET\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  return INT2FIX(wattrset(winp->window,NUM2INT(attrs)));\n#else\n  return Qtrue;\n#endif\n}\n\nstatic VALUE\nwindow_bkgdset(VALUE obj, VALUE ch)\n{\n#ifdef HAVE_WBKGDSET\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  wbkgdset(winp->window, NUM2CH(ch));\n#endif\n  return Qnil;\n}\n\nstatic VALUE\nwindow_bkgd(VALUE obj, VALUE ch)\n{\n#ifdef HAVE_WBKGD\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  return (wbkgd(winp->window, NUM2CH(ch)) == OK) ? Qtrue : Qfalse;\n#else\n  return Qfalse;\n#endif\n}\n\nstatic VALUE\nwindow_getbkgd(VALUE obj)\n{\n#ifdef HAVE_WGETBKGD\n  chtype c;\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  return (c = getbkgd(winp->window) != ERR) ? CH2FIX(c) : Qnil;\n#else\n  return Qnil;\n#endif\n}\n\nstatic VALUE\nwindow_resize(VALUE obj, VALUE lin, VALUE col)\n{\n#if defined(HAVE_WRESIZE)\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  return wresize(winp->window, NUM2INT(lin), NUM2INT(col)) == OK ? Qtrue : Qfalse;\n#else\n  return Qnil;\n#endif\n}\n\n\nstatic VALUE\nwindow_keypad(VALUE obj, VALUE val)\n{\n#ifdef HAVE_KEYPAD\n  struct windata *winp;\n\n  GetWINDOW(obj,winp);\n  /* keypad() of NetBSD's libcurses returns no value */\n#if defined(__NetBSD__) && !defined(NCURSES_VERSION)\n  keypad(winp->window,(RTEST(val) ? TRUE : FALSE));\n  return Qnil;\n#else\n  /* may have to raise exception on ERR */\n  return (keypad(winp->window,RTEST(val) ? TRUE : FALSE)) == OK ?\n    Qtrue : Qfalse;\n#endif\n#else\n    rb_notimplement();\n#endif /* HAVE_KEYPAD */\n}\n\nstatic VALUE\nwindow_nodelay(VALUE obj, VALUE val)\n{\n#ifdef HAVE_NODELAY\n  struct windata *winp;\n  GetWINDOW(obj,winp);\n\n  /* nodelay() of NetBSD's libcurses returns no value */\n#if defined(__NetBSD__) && !defined(NCURSES_VERSION)\n  nodelay(winp->window, RTEST(val) ? TRUE : FALSE);\n  return Qnil;\n#else\n  return nodelay(winp->window,RTEST(val) ? TRUE : FALSE) == OK ? Qtrue : Qfalse;\n#endif\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE\nwindow_timeout(VALUE obj, VALUE delay)\n{\n#ifdef HAVE_WTIMEOUT\n  struct windata *winp;\n  GetWINDOW(obj,winp);\n\n  wtimeout(winp->window,NUM2INT(delay));\n  return Qnil;\n#else\n    rb_notimplement();\n#endif\n}\n\n/*------------------------- Initialization -------------------------*/\nvoid\nInit_curses()\n{\n    mCurses    = rb_define_module(\"Curses\");\n    mKey       = rb_define_module_under(mCurses, \"Key\");\n\n    rb_gc_register_address(&rb_stdscr);\n\n#ifdef USE_MOUSE\n    cMouseEvent = rb_define_class_under(mCurses,\"MouseEvent\",rb_cObject);\n    rb_undef_method(CLASS_OF(cMouseEvent),\"new\");\n    rb_define_method(cMouseEvent, \"eid\", curs_mouse_id, 0);\n    rb_define_method(cMouseEvent, \"x\", curs_mouse_x, 0);\n    rb_define_method(cMouseEvent, \"y\", curs_mouse_y, 0);\n    rb_define_method(cMouseEvent, \"z\", curs_mouse_z, 0);\n    rb_define_method(cMouseEvent, \"bstate\", curs_mouse_bstate, 0);\n#endif /* USE_MOUSE */\n\n    rb_define_module_function(mCurses, \"init_screen\", curses_init_screen, 0);\n    rb_define_module_function(mCurses, \"close_screen\", curses_close_screen, 0);\n    rb_define_module_function(mCurses, \"closed?\", curses_closed, 0);\n    rb_define_module_function(mCurses, \"stdscr\", curses_stdscr, 0);\n    rb_define_module_function(mCurses, \"refresh\", curses_refresh, 0);\n    rb_define_module_function(mCurses, \"doupdate\", curses_doupdate, 0);\n    rb_define_module_function(mCurses, \"clear\", curses_clear, 0);\n    rb_define_module_function(mCurses, \"clrtoeol\", curses_clrtoeol, 0);\n    rb_define_module_function(mCurses, \"echo\", curses_echo, 0);\n    rb_define_module_function(mCurses, \"noecho\", curses_noecho, 0);\n    rb_define_module_function(mCurses, \"raw\", curses_raw, 0);\n    rb_define_module_function(mCurses, \"noraw\", curses_noraw, 0);\n    rb_define_module_function(mCurses, \"cbreak\", curses_cbreak, 0);\n    rb_define_module_function(mCurses, \"nocbreak\", curses_nocbreak, 0);\n    rb_define_alias(mCurses, \"crmode\", \"cbreak\");\n    rb_define_alias(mCurses, \"nocrmode\", \"nocbreak\");\n    rb_define_module_function(mCurses, \"nl\", curses_nl, 0);\n    rb_define_module_function(mCurses, \"nonl\", curses_nonl, 0);\n    rb_define_module_function(mCurses, \"beep\", curses_beep, 0);\n    rb_define_module_function(mCurses, \"flash\", curses_flash, 0);\n    rb_define_module_function(mCurses, \"ungetch\", curses_ungetch, 1);\n    rb_define_module_function(mCurses, \"setpos\", curses_setpos, 2);\n    rb_define_module_function(mCurses, \"standout\", curses_standout, 0);\n    rb_define_module_function(mCurses, \"standend\", curses_standend, 0);\n    rb_define_module_function(mCurses, \"inch\", curses_inch, 0);\n    rb_define_module_function(mCurses, \"addch\", curses_addch, 1);\n    rb_define_module_function(mCurses, \"insch\", curses_insch, 1);\n    rb_define_module_function(mCurses, \"addstr\", curses_addstr, 1);\n    rb_define_module_function(mCurses, \"getch\", curses_getch, 0);\n    rb_define_module_function(mCurses, \"getstr\", curses_getstr, 0);\n    rb_define_module_function(mCurses, \"delch\", curses_delch, 0);\n    rb_define_module_function(mCurses, \"deleteln\", curses_deleteln, 0);\n    rb_define_module_function(mCurses, \"insertln\", curses_insertln, 0);\n    rb_define_module_function(mCurses, \"keyname\", curses_keyname, 1);\n    rb_define_module_function(mCurses, \"lines\", curses_lines, 0);\n    rb_define_module_function(mCurses, \"cols\", curses_cols, 0);\n    rb_define_module_function(mCurses, \"curs_set\", curses_curs_set, 1);\n    rb_define_module_function(mCurses, \"scrl\", curses_scrl, 1);\n    rb_define_module_function(mCurses, \"setscrreg\", curses_setscrreg, 2);\n    rb_define_module_function(mCurses, \"attroff\", curses_attroff, 1);\n    rb_define_module_function(mCurses, \"attron\", curses_attron, 1);\n    rb_define_module_function(mCurses, \"attrset\", curses_attrset, 1);\n    rb_define_module_function(mCurses, \"bkgdset\", curses_bkgdset, 1);\n    rb_define_module_function(mCurses, \"bkgd\", curses_bkgd, 1);\n    rb_define_module_function(mCurses, \"resizeterm\", curses_resizeterm, 2);\n    rb_define_module_function(mCurses, \"resize\", curses_resizeterm, 2);\n#ifdef USE_COLOR\n    rb_define_module_function(mCurses, \"start_color\", curses_start_color, 0);\n    rb_define_module_function(mCurses, \"init_pair\", curses_init_pair, 3);\n    rb_define_module_function(mCurses, \"init_color\", curses_init_color, 4);\n    rb_define_module_function(mCurses, \"has_colors?\", curses_has_colors, 0);\n    rb_define_module_function(mCurses, \"can_change_color?\",\n\t\t\t      curses_can_change_color, 0);\n    rb_define_module_function(mCurses, \"color_content\", curses_color_content, 1);\n    rb_define_module_function(mCurses, \"pair_content\", curses_pair_content, 1);\n    rb_define_module_function(mCurses, \"color_pair\", curses_color_pair, 1);\n    rb_define_module_function(mCurses, \"pair_number\", curses_pair_number, 1);\n#endif /* USE_COLOR */\n#ifdef USE_MOUSE\n    rb_define_module_function(mCurses, \"getmouse\", curses_getmouse, 0);\n    rb_define_module_function(mCurses, \"ungetmouse\", curses_ungetmouse, 1);\n    rb_define_module_function(mCurses, \"mouseinterval\", curses_mouseinterval, 1);\n    rb_define_module_function(mCurses, \"mousemask\", curses_mousemask, 1);\n#endif /* USE_MOUSE */\n\n    rb_define_module_function(mCurses, \"timeout=\", curses_timeout, 1);\n    rb_define_module_function(mCurses, \"def_prog_mode\", curses_def_prog_mode, 0);\n    rb_define_module_function(mCurses, \"reset_prog_mode\", curses_reset_prog_mode, 0);\n\n    cWindow = rb_define_class_under(mCurses, \"Window\", rb_cData);\n    rb_define_alloc_func(cWindow, window_s_allocate);\n    rb_define_method(cWindow, \"initialize\", window_initialize, 4);\n    rb_define_method(cWindow, \"subwin\", window_subwin, 4);\n    rb_define_method(cWindow, \"close\", window_close, 0);\n    rb_define_method(cWindow, \"clear\", window_clear, 0);\n    rb_define_method(cWindow, \"clrtoeol\", window_clrtoeol, 0);\n    rb_define_method(cWindow, \"refresh\", window_refresh, 0);\n    rb_define_method(cWindow, \"noutrefresh\", window_noutrefresh, 0);\n    rb_define_method(cWindow, \"box\", window_box, -1);\n    rb_define_method(cWindow, \"move\", window_move, 2);\n    rb_define_method(cWindow, \"setpos\", window_setpos, 2);\n#if defined(USE_COLOR) && defined(HAVE_WCOLOR_SET)\n    rb_define_method(cWindow, \"color_set\", window_color_set, 1);\n#endif /* USE_COLOR && HAVE_WCOLOR_SET */\n    rb_define_method(cWindow, \"cury\", window_cury, 0);\n    rb_define_method(cWindow, \"curx\", window_curx, 0);\n    rb_define_method(cWindow, \"maxy\", window_maxy, 0);\n    rb_define_method(cWindow, \"maxx\", window_maxx, 0);\n    rb_define_method(cWindow, \"begy\", window_begy, 0);\n    rb_define_method(cWindow, \"begx\", window_begx, 0);\n    rb_define_method(cWindow, \"standout\", window_standout, 0);\n    rb_define_method(cWindow, \"standend\", window_standend, 0);\n    rb_define_method(cWindow, \"inch\", window_inch, 0);\n    rb_define_method(cWindow, \"addch\", window_addch, 1);\n    rb_define_method(cWindow, \"insch\", window_insch, 1);\n    rb_define_method(cWindow, \"addstr\", window_addstr, 1);\n    rb_define_method(cWindow, \"<<\", window_addstr2, 1);\n    rb_define_method(cWindow, \"getch\", window_getch, 0);\n    rb_define_method(cWindow, \"getstr\", window_getstr, 0);\n    rb_define_method(cWindow, \"delch\", window_delch, 0);\n    rb_define_method(cWindow, \"deleteln\", window_deleteln, 0);\n    rb_define_method(cWindow, \"insertln\", window_insertln, 0);\n    rb_define_method(cWindow, \"scroll\", window_scroll, 0);\n    rb_define_method(cWindow, \"scrollok\", window_scrollok, 1);\n    rb_define_method(cWindow, \"idlok\", window_idlok, 1);\n    rb_define_method(cWindow, \"setscrreg\", window_setscrreg, 2);\n    rb_define_method(cWindow, \"scrl\", window_scrl, 1);\n    rb_define_method(cWindow, \"resize\", window_resize, 2);\n    rb_define_method(cWindow, \"keypad\", window_keypad, 1);\n    rb_define_method(cWindow, \"keypad=\", window_keypad, 1);\n\n    rb_define_method(cWindow, \"attroff\", window_attroff, 1);\n    rb_define_method(cWindow, \"attron\", window_attron, 1);\n    rb_define_method(cWindow, \"attrset\", window_attrset, 1);\n    rb_define_method(cWindow, \"bkgdset\", window_bkgdset, 1);\n    rb_define_method(cWindow, \"bkgd\", window_bkgd, 1);\n    rb_define_method(cWindow, \"getbkgd\", window_getbkgd, 0);\n\n    rb_define_method(cWindow, \"nodelay=\", window_nodelay, 1);\n    rb_define_method(cWindow, \"timeout=\", window_timeout, 1);\n\n#define rb_curses_define_const(c) rb_define_const(mCurses,#c,UINT2NUM(c))\n\n#ifdef USE_COLOR\n    rb_curses_define_const(A_ATTRIBUTES);\n#ifdef A_NORMAL\n    rb_curses_define_const(A_NORMAL);\n#endif\n    rb_curses_define_const(A_STANDOUT);\n    rb_curses_define_const(A_UNDERLINE);\n    rb_curses_define_const(A_REVERSE);\n    rb_curses_define_const(A_BLINK);\n    rb_curses_define_const(A_DIM);\n    rb_curses_define_const(A_BOLD);\n    rb_curses_define_const(A_PROTECT);\n#ifdef A_INVIS /* for NetBSD */\n    rb_curses_define_const(A_INVIS);\n#endif\n    rb_curses_define_const(A_ALTCHARSET);\n    rb_curses_define_const(A_CHARTEXT);\n#ifdef A_HORIZONTAL\n    rb_curses_define_const(A_HORIZONTAL);\n#endif\n#ifdef A_LEFT\n    rb_curses_define_const(A_LEFT);\n#endif\n#ifdef A_LOW\n    rb_curses_define_const(A_LOW);\n#endif\n#ifdef A_RIGHT\n    rb_curses_define_const(A_RIGHT);\n#endif\n#ifdef A_TOP\n    rb_curses_define_const(A_TOP);\n#endif\n#ifdef A_VERTICAL\n    rb_curses_define_const(A_VERTICAL);\n#endif\n    rb_curses_define_const(A_COLOR);\n\n#ifdef COLORS\n    rb_curses_define_const(COLORS);\n#endif\n    rb_curses_define_const(COLOR_BLACK);\n    rb_curses_define_const(COLOR_RED);\n    rb_curses_define_const(COLOR_GREEN);\n    rb_curses_define_const(COLOR_YELLOW);\n    rb_curses_define_const(COLOR_BLUE);\n    rb_curses_define_const(COLOR_MAGENTA);\n    rb_curses_define_const(COLOR_CYAN);\n    rb_curses_define_const(COLOR_WHITE);\n#endif /* USE_COLOR */\n#ifdef USE_MOUSE\n#ifdef BUTTON1_PRESSED\n    rb_curses_define_const(BUTTON1_PRESSED);\n#endif\n#ifdef BUTTON1_RELEASED\n    rb_curses_define_const(BUTTON1_RELEASED);\n#endif\n#ifdef BUTTON1_CLICKED\n    rb_curses_define_const(BUTTON1_CLICKED);\n#endif\n#ifdef BUTTON1_DOUBLE_CLICKED\n    rb_curses_define_const(BUTTON1_DOUBLE_CLICKED);\n#endif\n#ifdef BUTTON1_TRIPLE_CLICKED\n    rb_curses_define_const(BUTTON1_TRIPLE_CLICKED);\n#endif\n#ifdef BUTTON2_PRESSED\n    rb_curses_define_const(BUTTON2_PRESSED);\n#endif\n#ifdef BUTTON2_RELEASED\n    rb_curses_define_const(BUTTON2_RELEASED);\n#endif\n#ifdef BUTTON2_CLICKED\n    rb_curses_define_const(BUTTON2_CLICKED);\n#endif\n#ifdef BUTTON2_DOUBLE_CLICKED\n    rb_curses_define_const(BUTTON2_DOUBLE_CLICKED);\n#endif\n#ifdef BUTTON2_TRIPLE_CLICKED\n    rb_curses_define_const(BUTTON2_TRIPLE_CLICKED);\n#endif\n#ifdef BUTTON3_PRESSED\n    rb_curses_define_const(BUTTON3_PRESSED);\n#endif\n#ifdef BUTTON3_RELEASED\n    rb_curses_define_const(BUTTON3_RELEASED);\n#endif\n#ifdef BUTTON3_CLICKED\n    rb_curses_define_const(BUTTON3_CLICKED);\n#endif\n#ifdef BUTTON3_DOUBLE_CLICKED\n    rb_curses_define_const(BUTTON3_DOUBLE_CLICKED);\n#endif\n#ifdef BUTTON3_TRIPLE_CLICKED\n    rb_curses_define_const(BUTTON3_TRIPLE_CLICKED);\n#endif\n#ifdef BUTTON4_PRESSED\n    rb_curses_define_const(BUTTON4_PRESSED);\n#endif\n#ifdef BUTTON4_RELEASED\n    rb_curses_define_const(BUTTON4_RELEASED);\n#endif\n#ifdef BUTTON4_CLICKED\n    rb_curses_define_const(BUTTON4_CLICKED);\n#endif\n#ifdef BUTTON4_DOUBLE_CLICKED\n    rb_curses_define_const(BUTTON4_DOUBLE_CLICKED);\n#endif\n#ifdef BUTTON4_TRIPLE_CLICKED\n    rb_curses_define_const(BUTTON4_TRIPLE_CLICKED);\n#endif\n#ifdef BUTTON_SHIFT\n    rb_curses_define_const(BUTTON_SHIFT);\n#endif\n#ifdef BUTTON_CTRL\n    rb_curses_define_const(BUTTON_CTRL);\n#endif\n#ifdef BUTTON_ALT\n    rb_curses_define_const(BUTTON_ALT);\n#endif\n#ifdef ALL_MOUSE_EVENTS\n    rb_curses_define_const(ALL_MOUSE_EVENTS);\n#endif\n#ifdef REPORT_MOUSE_POSITION\n    rb_curses_define_const(REPORT_MOUSE_POSITION);\n#endif\n#endif /* USE_MOUSE */\n\n#if defined(KEY_MOUSE) && defined(USE_MOUSE)\n    rb_curses_define_const(KEY_MOUSE);\n    rb_define_const(mKey, \"MOUSE\", INT2NUM(KEY_MOUSE));\n#endif\n#ifdef KEY_MIN\n    rb_curses_define_const(KEY_MIN);\n    rb_define_const(mKey, \"MIN\", INT2NUM(KEY_MIN));\n#endif\n#ifdef KEY_BREAK\n    rb_curses_define_const(KEY_BREAK);\n    rb_define_const(mKey, \"BREAK\", INT2NUM(KEY_BREAK));\n#endif\n#ifdef KEY_DOWN\n    rb_curses_define_const(KEY_DOWN);\n    rb_define_const(mKey, \"DOWN\", INT2NUM(KEY_DOWN));\n#endif\n#ifdef KEY_UP\n    rb_curses_define_const(KEY_UP);\n    rb_define_const(mKey, \"UP\", INT2NUM(KEY_UP));\n#endif\n#ifdef KEY_LEFT\n    rb_curses_define_const(KEY_LEFT);\n    rb_define_const(mKey, \"LEFT\", INT2NUM(KEY_LEFT));\n#endif\n#ifdef KEY_RIGHT\n    rb_curses_define_const(KEY_RIGHT);\n    rb_define_const(mKey, \"RIGHT\", INT2NUM(KEY_RIGHT));\n#endif\n#ifdef KEY_HOME\n    rb_curses_define_const(KEY_HOME);\n    rb_define_const(mKey, \"HOME\", INT2NUM(KEY_HOME));\n#endif\n#ifdef KEY_BACKSPACE\n    rb_curses_define_const(KEY_BACKSPACE);\n    rb_define_const(mKey, \"BACKSPACE\", INT2NUM(KEY_BACKSPACE));\n#endif\n#ifdef KEY_F\n    /* KEY_F(n) : 0 <= n <= 63 */\n    {\n      int i;\n      char c[8];\n      for( i=0; i<64; i++ ){\n\tsprintf(c, \"KEY_F%d\", i);\n\trb_define_const(mCurses, c, INT2NUM(KEY_F(i)));\n\tsprintf(c, \"F%d\", i);\n\trb_define_const(mKey, c, INT2NUM(KEY_F(i)));\n      }\n    }\n#endif\n#ifdef KEY_DL\n    rb_curses_define_const(KEY_DL);\n    rb_define_const(mKey, \"DL\", INT2NUM(KEY_DL));\n#endif\n#ifdef KEY_IL\n    rb_curses_define_const(KEY_IL);\n    rb_define_const(mKey, \"IL\", INT2NUM(KEY_IL));\n#endif\n#ifdef KEY_DC\n    rb_curses_define_const(KEY_DC);\n    rb_define_const(mKey, \"DC\", INT2NUM(KEY_DC));\n#endif\n#ifdef KEY_IC\n    rb_curses_define_const(KEY_IC);\n    rb_define_const(mKey, \"IC\", INT2NUM(KEY_IC));\n#endif\n#ifdef KEY_EIC\n    rb_curses_define_const(KEY_EIC);\n    rb_define_const(mKey, \"EIC\", INT2NUM(KEY_EIC));\n#endif\n#ifdef KEY_CLEAR\n    rb_curses_define_const(KEY_CLEAR);\n    rb_define_const(mKey, \"CLEAR\", INT2NUM(KEY_CLEAR));\n#endif\n#ifdef KEY_EOS\n    rb_curses_define_const(KEY_EOS);\n    rb_define_const(mKey, \"EOS\", INT2NUM(KEY_EOS));\n#endif\n#ifdef KEY_EOL\n    rb_curses_define_const(KEY_EOL);\n    rb_define_const(mKey, \"EOL\", INT2NUM(KEY_EOL));\n#endif\n#ifdef KEY_SF\n    rb_curses_define_const(KEY_SF);\n    rb_define_const(mKey, \"SF\", INT2NUM(KEY_SF));\n#endif\n#ifdef KEY_SR\n    rb_curses_define_const(KEY_SR);\n    rb_define_const(mKey, \"SR\", INT2NUM(KEY_SR));\n#endif\n#ifdef KEY_NPAGE\n    rb_curses_define_const(KEY_NPAGE);\n    rb_define_const(mKey, \"NPAGE\", INT2NUM(KEY_NPAGE));\n#endif\n#ifdef KEY_PPAGE\n    rb_curses_define_const(KEY_PPAGE);\n    rb_define_const(mKey, \"PPAGE\", INT2NUM(KEY_PPAGE));\n#endif\n#ifdef KEY_STAB\n    rb_curses_define_const(KEY_STAB);\n    rb_define_const(mKey, \"STAB\", INT2NUM(KEY_STAB));\n#endif\n#ifdef KEY_CTAB\n    rb_curses_define_const(KEY_CTAB);\n    rb_define_const(mKey, \"CTAB\", INT2NUM(KEY_CTAB));\n#endif\n#ifdef KEY_CATAB\n    rb_curses_define_const(KEY_CATAB);\n    rb_define_const(mKey, \"CATAB\", INT2NUM(KEY_CATAB));\n#endif\n#ifdef KEY_ENTER\n    rb_curses_define_const(KEY_ENTER);\n    rb_define_const(mKey, \"ENTER\", INT2NUM(KEY_ENTER));\n#endif\n#ifdef KEY_SRESET\n    rb_curses_define_const(KEY_SRESET);\n    rb_define_const(mKey, \"SRESET\", INT2NUM(KEY_SRESET));\n#endif\n#ifdef KEY_RESET\n    rb_curses_define_const(KEY_RESET);\n    rb_define_const(mKey, \"RESET\", INT2NUM(KEY_RESET));\n#endif\n#ifdef KEY_PRINT\n    rb_curses_define_const(KEY_PRINT);\n    rb_define_const(mKey, \"PRINT\", INT2NUM(KEY_PRINT));\n#endif\n#ifdef KEY_LL\n    rb_curses_define_const(KEY_LL);\n    rb_define_const(mKey, \"LL\", INT2NUM(KEY_LL));\n#endif\n#ifdef KEY_A1\n    rb_curses_define_const(KEY_A1);\n    rb_define_const(mKey, \"A1\", INT2NUM(KEY_A1));\n#endif\n#ifdef KEY_A3\n    rb_curses_define_const(KEY_A3);\n    rb_define_const(mKey, \"A3\", INT2NUM(KEY_A3));\n#endif\n#ifdef KEY_B2\n    rb_curses_define_const(KEY_B2);\n    rb_define_const(mKey, \"B2\", INT2NUM(KEY_B2));\n#endif\n#ifdef KEY_C1\n    rb_curses_define_const(KEY_C1);\n    rb_define_const(mKey, \"C1\", INT2NUM(KEY_C1));\n#endif\n#ifdef KEY_C3\n    rb_curses_define_const(KEY_C3);\n    rb_define_const(mKey, \"C3\", INT2NUM(KEY_C3));\n#endif\n#ifdef KEY_BTAB\n    rb_curses_define_const(KEY_BTAB);\n    rb_define_const(mKey, \"BTAB\", INT2NUM(KEY_BTAB));\n#endif\n#ifdef KEY_BEG\n    rb_curses_define_const(KEY_BEG);\n    rb_define_const(mKey, \"BEG\", INT2NUM(KEY_BEG));\n#endif\n#ifdef KEY_CANCEL\n    rb_curses_define_const(KEY_CANCEL);\n    rb_define_const(mKey, \"CANCEL\", INT2NUM(KEY_CANCEL));\n#endif\n#ifdef KEY_CLOSE\n    rb_curses_define_const(KEY_CLOSE);\n    rb_define_const(mKey, \"CLOSE\", INT2NUM(KEY_CLOSE));\n#endif\n#ifdef KEY_COMMAND\n    rb_curses_define_const(KEY_COMMAND);\n    rb_define_const(mKey, \"COMMAND\", INT2NUM(KEY_COMMAND));\n#endif\n#ifdef KEY_COPY\n    rb_curses_define_const(KEY_COPY);\n    rb_define_const(mKey, \"COPY\", INT2NUM(KEY_COPY));\n#endif\n#ifdef KEY_CREATE\n    rb_curses_define_const(KEY_CREATE);\n    rb_define_const(mKey, \"CREATE\", INT2NUM(KEY_CREATE));\n#endif\n#ifdef KEY_END\n    rb_curses_define_const(KEY_END);\n    rb_define_const(mKey, \"END\", INT2NUM(KEY_END));\n#endif\n#ifdef KEY_EXIT\n    rb_curses_define_const(KEY_EXIT);\n    rb_define_const(mKey, \"EXIT\", INT2NUM(KEY_EXIT));\n#endif\n#ifdef KEY_FIND\n    rb_curses_define_const(KEY_FIND);\n    rb_define_const(mKey, \"FIND\", INT2NUM(KEY_FIND));\n#endif\n#ifdef KEY_HELP\n    rb_curses_define_const(KEY_HELP);\n    rb_define_const(mKey, \"HELP\", INT2NUM(KEY_HELP));\n#endif\n#ifdef KEY_MARK\n    rb_curses_define_const(KEY_MARK);\n    rb_define_const(mKey, \"MARK\", INT2NUM(KEY_MARK));\n#endif\n#ifdef KEY_MESSAGE\n    rb_curses_define_const(KEY_MESSAGE);\n    rb_define_const(mKey, \"MESSAGE\", INT2NUM(KEY_MESSAGE));\n#endif\n#ifdef KEY_MOVE\n    rb_curses_define_const(KEY_MOVE);\n    rb_define_const(mKey, \"MOVE\", INT2NUM(KEY_MOVE));\n#endif\n#ifdef KEY_NEXT\n    rb_curses_define_const(KEY_NEXT);\n    rb_define_const(mKey, \"NEXT\", INT2NUM(KEY_NEXT));\n#endif\n#ifdef KEY_OPEN\n    rb_curses_define_const(KEY_OPEN);\n    rb_define_const(mKey, \"OPEN\", INT2NUM(KEY_OPEN));\n#endif\n#ifdef KEY_OPTIONS\n    rb_curses_define_const(KEY_OPTIONS);\n    rb_define_const(mKey, \"OPTIONS\", INT2NUM(KEY_OPTIONS));\n#endif\n#ifdef KEY_PREVIOUS\n    rb_curses_define_const(KEY_PREVIOUS);\n    rb_define_const(mKey, \"PREVIOUS\", INT2NUM(KEY_PREVIOUS));\n#endif\n#ifdef KEY_REDO\n    rb_curses_define_const(KEY_REDO);\n    rb_define_const(mKey, \"REDO\", INT2NUM(KEY_REDO));\n#endif\n#ifdef KEY_REFERENCE\n    rb_curses_define_const(KEY_REFERENCE);\n    rb_define_const(mKey, \"REFERENCE\", INT2NUM(KEY_REFERENCE));\n#endif\n#ifdef KEY_REFRESH\n    rb_curses_define_const(KEY_REFRESH);\n    rb_define_const(mKey, \"REFRESH\", INT2NUM(KEY_REFRESH));\n#endif\n#ifdef KEY_REPLACE\n    rb_curses_define_const(KEY_REPLACE);\n    rb_define_const(mKey, \"REPLACE\", INT2NUM(KEY_REPLACE));\n#endif\n#ifdef KEY_RESTART\n    rb_curses_define_const(KEY_RESTART);\n    rb_define_const(mKey, \"RESTART\", INT2NUM(KEY_RESTART));\n#endif\n#ifdef KEY_RESUME\n    rb_curses_define_const(KEY_RESUME);\n    rb_define_const(mKey, \"RESUME\", INT2NUM(KEY_RESUME));\n#endif\n#ifdef KEY_SAVE\n    rb_curses_define_const(KEY_SAVE);\n    rb_define_const(mKey, \"SAVE\", INT2NUM(KEY_SAVE));\n#endif\n#ifdef KEY_SBEG\n    rb_curses_define_const(KEY_SBEG);\n    rb_define_const(mKey, \"SBEG\", INT2NUM(KEY_SBEG));\n#endif\n#ifdef KEY_SCANCEL\n    rb_curses_define_const(KEY_SCANCEL);\n    rb_define_const(mKey, \"SCANCEL\", INT2NUM(KEY_SCANCEL));\n#endif\n#ifdef KEY_SCOMMAND\n    rb_curses_define_const(KEY_SCOMMAND);\n    rb_define_const(mKey, \"SCOMMAND\", INT2NUM(KEY_SCOMMAND));\n#endif\n#ifdef KEY_SCOPY\n    rb_curses_define_const(KEY_SCOPY);\n    rb_define_const(mKey, \"SCOPY\", INT2NUM(KEY_SCOPY));\n#endif\n#ifdef KEY_SCREATE\n    rb_curses_define_const(KEY_SCREATE);\n    rb_define_const(mKey, \"SCREATE\", INT2NUM(KEY_SCREATE));\n#endif\n#ifdef KEY_SDC\n    rb_curses_define_const(KEY_SDC);\n    rb_define_const(mKey, \"SDC\", INT2NUM(KEY_SDC));\n#endif\n#ifdef KEY_SDL\n    rb_curses_define_const(KEY_SDL);\n    rb_define_const(mKey, \"SDL\", INT2NUM(KEY_SDL));\n#endif\n#ifdef KEY_SELECT\n    rb_curses_define_const(KEY_SELECT);\n    rb_define_const(mKey, \"SELECT\", INT2NUM(KEY_SELECT));\n#endif\n#ifdef KEY_SEND\n    rb_curses_define_const(KEY_SEND);\n    rb_define_const(mKey, \"SEND\", INT2NUM(KEY_SEND));\n#endif\n#ifdef KEY_SEOL\n    rb_curses_define_const(KEY_SEOL);\n    rb_define_const(mKey, \"SEOL\", INT2NUM(KEY_SEOL));\n#endif\n#ifdef KEY_SEXIT\n    rb_curses_define_const(KEY_SEXIT);\n    rb_define_const(mKey, \"SEXIT\", INT2NUM(KEY_SEXIT));\n#endif\n#ifdef KEY_SFIND\n    rb_curses_define_const(KEY_SFIND);\n    rb_define_const(mKey, \"SFIND\", INT2NUM(KEY_SFIND));\n#endif\n#ifdef KEY_SHELP\n    rb_curses_define_const(KEY_SHELP);\n    rb_define_const(mKey, \"SHELP\", INT2NUM(KEY_SHELP));\n#endif\n#ifdef KEY_SHOME\n    rb_curses_define_const(KEY_SHOME);\n    rb_define_const(mKey, \"SHOME\", INT2NUM(KEY_SHOME));\n#endif\n#ifdef KEY_SIC\n    rb_curses_define_const(KEY_SIC);\n    rb_define_const(mKey, \"SIC\", INT2NUM(KEY_SIC));\n#endif\n#ifdef KEY_SLEFT\n    rb_curses_define_const(KEY_SLEFT);\n    rb_define_const(mKey, \"SLEFT\", INT2NUM(KEY_SLEFT));\n#endif\n#ifdef KEY_SMESSAGE\n    rb_curses_define_const(KEY_SMESSAGE);\n    rb_define_const(mKey, \"SMESSAGE\", INT2NUM(KEY_SMESSAGE));\n#endif\n#ifdef KEY_SMOVE\n    rb_curses_define_const(KEY_SMOVE);\n    rb_define_const(mKey, \"SMOVE\", INT2NUM(KEY_SMOVE));\n#endif\n#ifdef KEY_SNEXT\n    rb_curses_define_const(KEY_SNEXT);\n    rb_define_const(mKey, \"SNEXT\", INT2NUM(KEY_SNEXT));\n#endif\n#ifdef KEY_SOPTIONS\n    rb_curses_define_const(KEY_SOPTIONS);\n    rb_define_const(mKey, \"SOPTIONS\", INT2NUM(KEY_SOPTIONS));\n#endif\n#ifdef KEY_SPREVIOUS\n    rb_curses_define_const(KEY_SPREVIOUS);\n    rb_define_const(mKey, \"SPREVIOUS\", INT2NUM(KEY_SPREVIOUS));\n#endif\n#ifdef KEY_SPRINT\n    rb_curses_define_const(KEY_SPRINT);\n    rb_define_const(mKey, \"SPRINT\", INT2NUM(KEY_SPRINT));\n#endif\n#ifdef KEY_SREDO\n    rb_curses_define_const(KEY_SREDO);\n    rb_define_const(mKey, \"SREDO\", INT2NUM(KEY_SREDO));\n#endif\n#ifdef KEY_SREPLACE\n    rb_curses_define_const(KEY_SREPLACE);\n    rb_define_const(mKey, \"SREPLACE\", INT2NUM(KEY_SREPLACE));\n#endif\n#ifdef KEY_SRIGHT\n    rb_curses_define_const(KEY_SRIGHT);\n    rb_define_const(mKey, \"SRIGHT\", INT2NUM(KEY_SRIGHT));\n#endif\n#ifdef KEY_SRSUME\n    rb_curses_define_const(KEY_SRSUME);\n    rb_define_const(mKey, \"SRSUME\", INT2NUM(KEY_SRSUME));\n#endif\n#ifdef KEY_SSAVE\n    rb_curses_define_const(KEY_SSAVE);\n    rb_define_const(mKey, \"SSAVE\", INT2NUM(KEY_SSAVE));\n#endif\n#ifdef KEY_SSUSPEND\n    rb_curses_define_const(KEY_SSUSPEND);\n    rb_define_const(mKey, \"SSUSPEND\", INT2NUM(KEY_SSUSPEND));\n#endif\n#ifdef KEY_SUNDO\n    rb_curses_define_const(KEY_SUNDO);\n    rb_define_const(mKey, \"SUNDO\", INT2NUM(KEY_SUNDO));\n#endif\n#ifdef KEY_SUSPEND\n    rb_curses_define_const(KEY_SUSPEND);\n    rb_define_const(mKey, \"SUSPEND\", INT2NUM(KEY_SUSPEND));\n#endif\n#ifdef KEY_UNDO\n    rb_curses_define_const(KEY_UNDO);\n    rb_define_const(mKey, \"UNDO\", INT2NUM(KEY_UNDO));\n#endif\n#ifdef KEY_RESIZE\n    rb_curses_define_const(KEY_RESIZE);\n    rb_define_const(mKey, \"RESIZE\", INT2NUM(KEY_RESIZE));\n#endif\n#ifdef KEY_MAX\n    rb_curses_define_const(KEY_MAX);\n    rb_define_const(mKey, \"MAX\", INT2NUM(KEY_MAX));\n#endif\n    {\n      int c;\n      char name[] = \"KEY_CTRL_x\";\n      for( c = 'A'; c <= 'Z'; c++ ){\n\tsprintf(name, \"KEY_CTRL_%c\", c);\n\trb_define_const(mCurses, name, INT2FIX(c - 'A' + 1));\n      }\n    }\n#undef rb_curses_define_const\n\n    rb_set_end_proc(curses_finalize, 0);\n}\n"
  },
  {
    "path": "ext/curses/depend",
    "content": "curses.o: curses.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/curses/extconf.rb",
    "content": "require 'mkmf'\n\ndir_config('curses')\ndir_config('ncurses')\ndir_config('termcap')\n\nmake=false\nhave_library(\"mytinfo\", \"tgetent\") if /bow/ =~ RUBY_PLATFORM\nhave_library(\"tinfo\", \"tgetent\") or have_library(\"termcap\", \"tgetent\")\nif have_header(*curses=%w\"ncurses.h\") and have_library(\"ncurses\", \"initscr\")\n  make=true\nelsif have_header(*curses=%w\"ncurses/curses.h\") and have_library(\"ncurses\", \"initscr\")\n  make=true\nelsif have_header(*curses=%w\"curses_colr/curses.h\") and have_library(\"cur_colr\", \"initscr\")\n  curses.unshift(\"varargs.h\")\n  make=true\nelsif have_header(*curses=%w\"curses.h\") and have_library(\"curses\", \"initscr\")\n  make=true\nend\n\nif make\n  for f in %w(beep bkgd bkgdset curs_set deleteln doupdate flash getbkgd getnstr init isendwin keyname keypad resizeterm scrl set setscrreg ungetch wattroff wattron wattrset wbkgd wbkgdset wdeleteln wgetnstr wresize wscrl wsetscrreg def_prog_mode reset_prog_mode timeout wtimeout nodelay init_color wcolor_set)\n    have_func(f) || (have_macro(f, curses) && $defs.push(format(\"-DHAVE_%s\", f.upcase)))\n  end\n  flag = \"-D_XOPEN_SOURCE_EXTENDED\"\n  src = \"int test_var[(sizeof(char*)>sizeof(int))*2-1];\"\n  if try_compile(cpp_include(%w[stdio.h stdlib.h]+curses)+src , flag)\n    $defs << flag\n  end\n  create_makefile(\"curses\")\nend\n"
  },
  {
    "path": "ext/curses/hello.rb",
    "content": "#!/usr/local/bin/ruby\n\nrequire \"curses\"\ninclude Curses\n\ndef show_message(message)\n  width = message.length + 6\n  win = Window.new(5, width,\n\t\t   (lines - 5) / 2, (cols - width) / 2)\n  win.box(?|, ?-)\n  win.setpos(2, 3)\n  win.addstr(message)\n  win.refresh\n  win.getch\n  win.close\nend\n\ninit_screen\nbegin\n  crmode\n#  show_message(\"Hit any key\")\n  setpos((lines - 5) / 2, (cols - 10) / 2)\n  addstr(\"Hit any key\")\n  refresh\n  getch\n  show_message(\"Hello, World!\")\n  refresh\nensure\n  close_screen\nend\n"
  },
  {
    "path": "ext/curses/mouse.rb",
    "content": "#!/usr/local/bin/ruby\n\nrequire \"curses\"\ninclude Curses\n\ndef show_message(*msgs)\n  message = msgs.join\n  width = message.length + 6\n  win = Window.new(5, width,\n\t\t   (lines - 5) / 2, (cols - width) / 2)\n  win.keypad = true\n  win.attron(color_pair(COLOR_RED)){\n    win.box(?|, ?-, ?+)\n  }\n  win.setpos(2, 3)\n  win.addstr(message)\n  win.refresh\n  win.getch\n  win.close\nend\n\ninit_screen\nstart_color\ninit_pair(COLOR_BLUE,COLOR_BLUE,COLOR_WHITE)\ninit_pair(COLOR_RED,COLOR_RED,COLOR_WHITE)\ncrmode\nnoecho\nstdscr.keypad(true)\n\nbegin\n  mousemask(BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED|BUTTON4_CLICKED)\n  setpos((lines - 5) / 2, (cols - 10) / 2)\n  attron(color_pair(COLOR_BLUE)|A_BOLD){\n    addstr(\"click\")\n  }\n  refresh\n  while( true )\n    c = getch\n    case c\n    when KEY_MOUSE\n      m = getmouse\n      if( m )\n\tshow_message(\"getch = #{c.inspect}, \",\n\t\t     \"mouse event = #{'0x%x' % m.bstate}, \",\n\t\t     \"axis = (#{m.x},#{m.y},#{m.z})\")\n      end\n      break\n    end\n  end\n  refresh\nensure\n  close_screen\nend\n"
  },
  {
    "path": "ext/curses/rain.rb",
    "content": "#!/usr/local/bin/ruby\n# rain for a curses test\n\nrequire \"curses\"\ninclude Curses\n\ndef onsig(sig)\n  close_screen\n  exit sig\nend\n\ndef ranf\n  rand(32767).to_f / 32767\nend\n\n# main #\nfor i in 1 .. 15  # SIGHUP .. SIGTERM\n  if trap(i, \"SIG_IGN\") != 0 then  # 0 for SIG_IGN\n    trap(i) {|sig| onsig(sig) }\n  end\nend\n\ninit_screen\nnl\nnoecho\nsrand\n\nxpos = {}\nypos = {}\nr = lines - 4\nc = cols - 4\nfor i in 0 .. 4\n  xpos[i] = (c * ranf).to_i + 2\n  ypos[i] = (r * ranf).to_i + 2\nend\n\ni = 0\nwhile TRUE\n  x = (c * ranf).to_i + 2\n  y = (r * ranf).to_i + 2\n\n\n  setpos(y, x); addstr(\".\")\n\n  setpos(ypos[i], xpos[i]); addstr(\"o\")\n\n  i = if i == 0 then 4 else i - 1 end\n  setpos(ypos[i], xpos[i]); addstr(\"O\")\n\n  i = if i == 0 then 4 else i - 1 end\n  setpos(ypos[i] - 1, xpos[i]);      addstr(\"-\")\n  setpos(ypos[i],     xpos[i] - 1); addstr(\"|.|\")\n  setpos(ypos[i] + 1, xpos[i]);      addstr(\"-\")\n\n  i = if i == 0 then 4 else i - 1 end\n  setpos(ypos[i] - 2, xpos[i]);       addstr(\"-\")\n  setpos(ypos[i] - 1, xpos[i] - 1);  addstr(\"/ \\\\\")\n  setpos(ypos[i],     xpos[i] - 2); addstr(\"| O |\")\n  setpos(ypos[i] + 1, xpos[i] - 1); addstr(\"\\\\ /\")\n  setpos(ypos[i] + 2, xpos[i]);       addstr(\"-\")\n\n  i = if i == 0 then 4 else i - 1 end\n  setpos(ypos[i] - 2, xpos[i]);       addstr(\" \")\n  setpos(ypos[i] - 1, xpos[i] - 1);  addstr(\"   \")\n  setpos(ypos[i],     xpos[i] - 2); addstr(\"     \")\n  setpos(ypos[i] + 1, xpos[i] - 1);  addstr(\"   \")\n  setpos(ypos[i] + 2, xpos[i]);       addstr(\" \")\n\n\n  xpos[i] = x\n  ypos[i] = y\n  refresh\n  sleep(0.5)\nend\n\n# end of main\n"
  },
  {
    "path": "ext/curses/view.rb",
    "content": "#!/usr/local/bin/ruby\n\nrequire \"curses\"\ninclude Curses\n\n#\n# main\n#\n\nif ARGV.size != 1 then\n  printf(\"usage: view file\\n\");\n  exit\nend\nbegin\n  fp = open(ARGV[0], \"r\")\nrescue\n  raise \"cannot open file: #{ARGV[1]}\"\nend\n\n# signal(SIGINT, finish)\n\ninit_screen\n#keypad(stdscr, TRUE)\nnonl\ncbreak\nnoecho\n#scrollok(stdscr, TRUE)\n\n# slurp the file\ndata_lines = []\nfp.each_line { |l|\n  data_lines.push(l)\n}\nfp.close\n\n\nlptr = 0\nwhile TRUE\n  i = 0\n  while i < lines\n    setpos(i, 0)\n    #clrtoeol\n    addstr(data_lines[lptr + i]) #if data_lines[lptr + i]\n    i += 1\n  end\n  refresh\n\n  explicit = FALSE\n  n = 0\n  while TRUE\n    c = getch.chr\n    if c =~ /[0-9]/\n      n = 10 * n + c.to_i\n    else\n      break\n    end\n  end\n\n  n = 1 if !explicit && n == 0\n\n  case c\n  when \"n\"  #when KEY_DOWN\n    i = 0\n    while i < n\n      if lptr + lines < data_lines.size then\n\tlptr += 1\n      else\n\tbreak\n      end\n      i += 1 \n    end\n    #wscrl(i)\n      \n  when \"p\"  #when KEY_UP\n    i = 0\n    while i < n\n      if lptr > 0 then\n\tlptr -= 1\n      else\n\tbreak\n      end\n      i += 1 \n    end    \n    #wscrl(-i)\n\n  when \"q\"\n    break\n  end\n\nend\nclose_screen\n"
  },
  {
    "path": "ext/curses/view2.rb",
    "content": "#!/usr/local/bin/ruby\n\nrequire \"curses\"\n\nif ARGV.size != 1 then\n  printf(\"usage: view file\\n\");\n  exit\nend\nbegin\n  fp = open(ARGV[0], \"r\")\nrescue\n  raise \"cannot open file: #{ARGV[1]}\"\nend\n\n# signal(SIGINT, finish)\n\nCurses.init_screen\nCurses.nonl\nCurses.cbreak\nCurses.noecho\n\n$screen = Curses.stdscr\n\n$screen.scrollok(true)\n#$screen.keypad(true)\n\n# slurp the file\n$data_lines = []\nfp.each_line { |l|\n  $data_lines.push(l.chop)\n}\nfp.close\n\n$top = 0\n$data_lines[0..$screen.maxy-1].each_with_index{|line, idx|\n  $screen.setpos(idx, 0)\n  $screen.addstr(line)\n}\n$screen.setpos(0,0)\n$screen.refresh\n\ndef scroll_up\n  if( $top > 0 )\n    $screen.scrl(-1)\n    $top -= 1\n    str = $data_lines[$top]\n    if( str )\n      $screen.setpos(0, 0)\n      $screen.addstr(str)\n    end\n    return true\n  else\n    return false\n  end\nend\n\ndef scroll_down\n  if( $top + $screen.maxy < $data_lines.length )\n    $screen.scrl(1)\n    $top += 1\n    str = $data_lines[$top + $screen.maxy - 1]\n    if( str )\n      $screen.setpos($screen.maxy - 1, 0)\n      $screen.addstr(str)\n    end\n    return true\n  else\n    return false\n  end\nend\n\nwhile true\n  result = true\n  c = Curses.getch\n  case c\n  when Curses::KEY_DOWN, Curses::KEY_CTRL_N\n    result = scroll_down\n  when Curses::KEY_UP, Curses::KEY_CTRL_P\n    result = scroll_up\n  when Curses::KEY_NPAGE, ?\\s  # white space\n    for i in 0..($screen.maxy - 2)\n      if( ! scroll_down )\n\tif( i == 0 )\n\t  result = false\n\tend\n\tbreak\n      end\n    end\n  when Curses::KEY_PPAGE\n    for i in 0..($screen.maxy - 2)\n      if( ! scroll_up )\n\tif( i == 0 )\n\t  result = false\n\tend\n\tbreak\n      end\n    end\n  when Curses::KEY_LEFT, Curses::KEY_CTRL_T\n    while( scroll_up )\n    end\n  when Curses::KEY_RIGHT, Curses::KEY_CTRL_B\n    while( scroll_down )\n    end\n  when ?q\n    break\n  else\n    $screen.setpos(0,0)\n    $screen.addstr(\"[unknown key `#{Curses.keyname(c)}'=#{c}] \")\n  end\n  if( !result )\n    Curses.beep\n  end\n  $screen.setpos(0,0)\nend\nCurses.close_screen\n"
  },
  {
    "path": "ext/dbm/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/dbm/dbm.c",
    "content": "/************************************************\n\n  dbm.c -\n\n  $Author$\n  $Date$\n  created at: Mon Jan 24 15:59:52 JST 1994\n\n  Copyright (C) 1995-2001 Yukihiro Matsumoto\n\n************************************************/\n\n#include \"ruby.h\"\n\n#ifdef HAVE_CDEFS_H\n# include <cdefs.h>\n#endif\n#ifdef HAVE_SYS_CDEFS_H\n# include <sys/cdefs.h>\n#endif\n#include DBM_HDR\n#include <fcntl.h>\n#include <errno.h>\n\nstatic VALUE rb_cDBM, rb_eDBMError;\n\n#define RUBY_DBM_RW_BIT 0x20000000\n\nstruct dbmdata {\n    int  di_size;\n    DBM *di_dbm;\n};\n\nstatic void\nclosed_dbm()\n{\n    rb_raise(rb_eDBMError, \"closed DBM file\");\n}\n\n#define GetDBM(obj, dbmp) {\\\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\\\n    if (dbmp == 0) closed_dbm();\\\n    if (dbmp->di_dbm == 0) closed_dbm();\\\n}\n\n#define GetDBM2(obj, data, dbm) {\\\n    GetDBM(obj, data);\\\n    (dbm) = dbmp->di_dbm;\\\n}\n\nstatic void\nfree_dbm(dbmp)\n    struct dbmdata *dbmp;\n{\n    if (dbmp) {\n\tif (dbmp->di_dbm) dbm_close(dbmp->di_dbm);\n\tfree(dbmp);\n    }\n}\n\nstatic VALUE\nfdbm_close(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n\n    GetDBM(obj, dbmp);\n    dbm_close(dbmp->di_dbm);\n    dbmp->di_dbm = 0;\n\n    return Qnil;\n}\n\nstatic VALUE\nfdbm_closed(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\n    if (dbmp == 0)\n\treturn Qtrue;\n    if (dbmp->di_dbm == 0)\n\treturn Qtrue;\n\n    return Qfalse;\n}\n\nstatic VALUE fdbm_alloc _((VALUE));\nstatic VALUE\nfdbm_alloc(klass)\n    VALUE klass;\n{\n    return Data_Wrap_Struct(klass, 0, free_dbm, 0);\n}\n\nstatic VALUE\nfdbm_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE file, vmode, vflags;\n    DBM *dbm;\n    struct dbmdata *dbmp;\n    int mode, flags = 0;\n\n    if (rb_scan_args(argc, argv, \"12\", &file, &vmode, &vflags) == 1) {\n\tmode = 0666;\t\t/* default value */\n    }\n    else if (NIL_P(vmode)) {\n\tmode = -1;\t\t/* return nil if DB not exist */\n    }\n    else {\n\tmode = NUM2INT(vmode);\n    }\n\n    if (!NIL_P(vflags))\n        flags = NUM2INT(vflags);\n\n    SafeStringValue(file);\n\n    if (flags & RUBY_DBM_RW_BIT) {\n        flags &= ~RUBY_DBM_RW_BIT;\n        dbm = dbm_open(RSTRING(file)->ptr, flags, mode);\n    }\n    else {\n        dbm = 0;\n        if (mode >= 0) {\n            dbm = dbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode);\n        }\n        if (!dbm) {\n            dbm = dbm_open(RSTRING(file)->ptr, O_RDWR, 0);\n        }\n        if (!dbm) {\n            dbm = dbm_open(RSTRING(file)->ptr, O_RDONLY, 0);\n        }\n    }\n\n    if (!dbm) {\n\tif (mode == -1) return Qnil;\n\trb_sys_fail(RSTRING(file)->ptr);\n    }\n\n    dbmp = ALLOC(struct dbmdata);\n    DATA_PTR(obj) = dbmp;\n    dbmp->di_dbm = dbm;\n    dbmp->di_size = -1;\n\n    return obj;\n}\n\nstatic VALUE\nfdbm_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);\n\n    if (NIL_P(fdbm_initialize(argc, argv, obj))) {\n\treturn Qnil;\n    }\n\n    if (rb_block_given_p()) {\n        return rb_ensure(rb_yield, obj, fdbm_close, obj);\n    }\n\n    return obj;\n}\n\nstatic VALUE\nfdbm_fetch(obj, keystr, ifnone)\n    VALUE obj, keystr, ifnone;\n{\n    datum key, value;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    value = dbm_fetch(dbm, key);\n    if (value.dptr == 0) {\n\tif (ifnone == Qnil && rb_block_given_p())\n\t    return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));\n\treturn ifnone;\n    }\n    return rb_tainted_str_new(value.dptr, value.dsize);\n}\n\nstatic VALUE\nfdbm_aref(obj, keystr)\n    VALUE obj, keystr;\n{\n    return fdbm_fetch(obj, keystr, Qnil);\n}\n\nstatic VALUE\nfdbm_fetch_m(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE keystr, valstr, ifnone;\n\n    rb_scan_args(argc, argv, \"11\", &keystr, &ifnone);\n    valstr = fdbm_fetch(obj, keystr, ifnone);\n    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))\n\trb_raise(rb_eIndexError, \"key not found\");\n\n    return valstr;\n}\n\nstatic VALUE\nfdbm_index(obj, valstr)\n    VALUE obj, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(valstr);\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\tif (val.dsize == RSTRING(valstr)->len &&\n\t    memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0) {\n\t    return rb_tainted_str_new(key.dptr, key.dsize);\n\t}\n    }\n    return Qnil;\n}\n\nstatic VALUE\nfdbm_indexes(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new;\n    int i;\n\n    new = rb_ary_new2(argc);\n    for (i=0; i<argc; i++) {\n\trb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));\n    }\n\n    return new;\n}\n\nstatic VALUE\nfdbm_select(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new = rb_ary_new2(argc);\n    int i;\n\n    if (rb_block_given_p()) {\n        datum key, val;\n        DBM *dbm;\n        struct dbmdata *dbmp;\n\n\tif (argc > 0) {\n\t    rb_raise(rb_eArgError, \"wrong number arguments(%d for 0)\", argc);\n\t}\n        GetDBM2(obj, dbmp, dbm);\n        for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n            VALUE assoc, v;\n            val = dbm_fetch(dbm, key);\n            assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),\n                                 rb_tainted_str_new(val.dptr, val.dsize));\n\t    v = rb_yield(assoc);\n\t    if (RTEST(v)) {\n\t\trb_ary_push(new, assoc);\n\t    }\n\t    GetDBM2(obj, dbmp, dbm);\n\t}\n    }\n    else {\n\trb_warn(\"DBM#select(index..) is deprecated; use DBM#values_at\");\n\n        for (i=0; i<argc; i++) {\n            rb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));\n        }\n    }\n\n    return new;\n}\n\nstatic VALUE\nfdbm_values_at(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new = rb_ary_new2(argc);\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_ary_push(new, fdbm_fetch(obj, argv[i], Qnil));\n    }\n\n    return new;\n}\n\nstatic void\nfdbm_modify(obj)\n    VALUE obj;\n{\n    rb_secure(4);\n    if (OBJ_FROZEN(obj)) rb_error_frozen(\"DBM\");\n}\n\nstatic VALUE\nfdbm_delete(obj, keystr)\n    VALUE obj, keystr;\n{\n    datum key, value;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE valstr;\n\n    fdbm_modify(obj);\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    value = dbm_fetch(dbm, key);\n    if (value.dptr == 0) {\n\tif (rb_block_given_p()) return rb_yield(keystr);\n\treturn Qnil;\n    }\n\n    /* need to save value before dbm_delete() */\n    valstr = rb_tainted_str_new(value.dptr, value.dsize);\n\n    if (dbm_delete(dbm, key)) {\n\tdbmp->di_size = -1;\n\trb_raise(rb_eDBMError, \"dbm_delete failed\");\n    }\n    else if (dbmp->di_size >= 0) {\n\tdbmp->di_size--;\n    }\n    return valstr;\n}\n\nstatic VALUE\nfdbm_shift(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE keystr, valstr;\n\n    fdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n\n    key = dbm_firstkey(dbm); \n    if (!key.dptr) return Qnil;\n    val = dbm_fetch(dbm, key);\n    keystr = rb_tainted_str_new(key.dptr, key.dsize);\n    valstr = rb_tainted_str_new(val.dptr, val.dsize);\n    dbm_delete(dbm, key);\n\n    return rb_assoc_new(keystr, valstr);\n}\n\nstatic VALUE\nfdbm_delete_if(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE keystr, valstr;\n    VALUE ret, ary = rb_ary_new();\n    int i, status = 0, n;\n\n    fdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    n = dbmp->di_size;\n    dbmp->di_size = -1;\n\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\tkeystr = rb_tainted_str_new(key.dptr, key.dsize);\n\tvalstr = rb_tainted_str_new(val.dptr, val.dsize);\n        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);\n        if (status != 0) break;\n\tif (RTEST(ret)) rb_ary_push(ary, keystr);\n\tGetDBM2(obj, dbmp, dbm);\n    }\n\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\tkeystr = RARRAY(ary)->ptr[i];\n\tStringValue(keystr);\n\tkey.dptr = RSTRING(keystr)->ptr;\n\tkey.dsize = RSTRING(keystr)->len;\n\tif (dbm_delete(dbm, key)) {\n\t    rb_raise(rb_eDBMError, \"dbm_delete failed\");\n\t}\n    }\n    if (status) rb_jump_tag(status);\n    if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;\n\n    return obj;\n}\n\nstatic VALUE\nfdbm_clear(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    fdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n    while (key = dbm_firstkey(dbm), key.dptr) {\n\tif (dbm_delete(dbm, key)) {\n\t    rb_raise(rb_eDBMError, \"dbm_delete failed\");\n\t}\n    }\n    dbmp->di_size = 0;\n\n    return obj;\n}\n\nstatic VALUE\nfdbm_invert(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE keystr, valstr;\n    VALUE hash = rb_hash_new();\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\tkeystr = rb_tainted_str_new(key.dptr, key.dsize);\n\tvalstr = rb_tainted_str_new(val.dptr, val.dsize);\n\trb_hash_aset(hash, valstr, keystr);\n    }\n    return hash;\n}\n\nstatic VALUE each_pair _((VALUE));\n\nstatic VALUE\neach_pair(obj)\n    VALUE obj;\n{\n    return rb_funcall(obj, rb_intern(\"each_pair\"), 0, 0);\n}\n\nstatic VALUE fdbm_store _((VALUE,VALUE,VALUE));\n\nstatic VALUE\nupdate_i(pair, dbm)\n    VALUE pair, dbm;\n{\n    Check_Type(pair, T_ARRAY);\n    if (RARRAY(pair)->len < 2) {\n\trb_raise(rb_eArgError, \"pair must be [key, value]\");\n    }\n    fdbm_store(dbm, RARRAY(pair)->ptr[0], RARRAY(pair)->ptr[1]);\n    return Qnil;\n}\n\nstatic VALUE\nfdbm_update(obj, other)\n    VALUE obj, other;\n{\n    rb_iterate(each_pair, other, update_i, obj);\n    return obj;\n}\n\nstatic VALUE\nfdbm_replace(obj, other)\n    VALUE obj, other;\n{\n    fdbm_clear(obj);\n    rb_iterate(each_pair, other, update_i, obj);\n    return obj;\n}\n\nstatic VALUE\nfdbm_store(obj, keystr, valstr)\n    VALUE obj, keystr, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    fdbm_modify(obj);\n    keystr = rb_obj_as_string(keystr);\n    valstr = rb_obj_as_string(valstr);\n\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n    if (dbm_store(dbm, key, val, DBM_REPLACE)) {\n#ifdef HAVE_DBM_CLEARERR\n\tdbm_clearerr(dbm);\n#endif\n\tif (errno == EPERM) rb_sys_fail(0);\n\trb_raise(rb_eDBMError, \"dbm_store failed\");\n    }\n\n    return valstr;\n}\n\nstatic VALUE\nfdbm_length(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    int i = 0;\n\n    GetDBM2(obj, dbmp, dbm);\n    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);\n\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\ti++;\n    }\n    dbmp->di_size = i;\n\n    return INT2FIX(i);\n}\n\nstatic VALUE\nfdbm_empty_p(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    int i = 0;\n\n    GetDBM2(obj, dbmp, dbm);\n    if (dbmp->di_size < 0) {\n\tdbm = dbmp->di_dbm;\n\n\tfor (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\t    i++;\n\t}\n    }\n    else {\n\ti = dbmp->di_size;\n    }\n    if (i == 0) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\nfdbm_each_value(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\trb_yield(rb_tainted_str_new(val.dptr, val.dsize));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n    return obj;\n}\n\nstatic VALUE\nfdbm_each_key(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\trb_yield(rb_tainted_str_new(key.dptr, key.dsize));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n    return obj;\n}\n\nstatic VALUE\nfdbm_each_pair(obj)\n    VALUE obj;\n{\n    datum key, val;\n    DBM *dbm;\n    struct dbmdata *dbmp;\n    VALUE keystr, valstr;\n\n    GetDBM2(obj, dbmp, dbm);\n\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\tkeystr = rb_tainted_str_new(key.dptr, key.dsize);\n\tvalstr = rb_tainted_str_new(val.dptr, val.dsize);\n\trb_yield(rb_assoc_new(keystr, valstr));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n\n    return obj;\n}\n\nstatic VALUE\nfdbm_keys(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE ary;\n\n    GetDBM2(obj, dbmp, dbm);\n\n    ary = rb_ary_new();\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\trb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nfdbm_values(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\trb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nfdbm_has_key(obj, keystr)\n    VALUE obj, keystr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    val = dbm_fetch(dbm, key);\n    if (val.dptr) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\nfdbm_has_value(obj, valstr)\n    VALUE obj, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(valstr);\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\tif (val.dsize == RSTRING(valstr)->len &&\n\t    memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)\n\t    return Qtrue;\n    }\n    return Qfalse;\n}\n\nstatic VALUE\nfdbm_to_a(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\trb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),\n\t\t\t\t      rb_tainted_str_new(val.dptr, val.dsize)));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nfdbm_to_hash(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE hash;\n\n    GetDBM2(obj, dbmp, dbm);\n    hash = rb_hash_new();\n    for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {\n\tval = dbm_fetch(dbm, key);\n\trb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),\n\t\t           rb_tainted_str_new(val.dptr, val.dsize));\n    }\n\n    return hash;\n}\n\nstatic VALUE\nfdbm_reject(obj)\n    VALUE obj;\n{\n    return rb_hash_delete_if(fdbm_to_hash(obj));\n}\n\nvoid\nInit_dbm()\n{\n    rb_cDBM = rb_define_class(\"DBM\", rb_cObject);\n    rb_eDBMError = rb_define_class(\"DBMError\", rb_eStandardError);\n    rb_include_module(rb_cDBM, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cDBM, fdbm_alloc);\n    rb_define_singleton_method(rb_cDBM, \"open\", fdbm_s_open, -1);\n\n    rb_define_method(rb_cDBM, \"initialize\", fdbm_initialize, -1);\n    rb_define_method(rb_cDBM, \"close\", fdbm_close, 0);\n    rb_define_method(rb_cDBM, \"closed?\", fdbm_closed, 0);\n    rb_define_method(rb_cDBM, \"[]\", fdbm_aref, 1);\n    rb_define_method(rb_cDBM, \"fetch\", fdbm_fetch_m, -1);\n    rb_define_method(rb_cDBM, \"[]=\", fdbm_store, 2);\n    rb_define_method(rb_cDBM, \"store\", fdbm_store, 2);\n    rb_define_method(rb_cDBM, \"index\",  fdbm_index, 1);\n    rb_define_method(rb_cDBM, \"indexes\",  fdbm_indexes, -1);\n    rb_define_method(rb_cDBM, \"indices\",  fdbm_indexes, -1);\n    rb_define_method(rb_cDBM, \"select\",  fdbm_select, -1);\n    rb_define_method(rb_cDBM, \"values_at\", fdbm_values_at, -1);\n    rb_define_method(rb_cDBM, \"length\", fdbm_length, 0);\n    rb_define_method(rb_cDBM, \"size\", fdbm_length, 0);\n    rb_define_method(rb_cDBM, \"empty?\", fdbm_empty_p, 0);\n    rb_define_method(rb_cDBM, \"each\", fdbm_each_pair, 0);\n    rb_define_method(rb_cDBM, \"each_value\", fdbm_each_value, 0);\n    rb_define_method(rb_cDBM, \"each_key\", fdbm_each_key, 0);\n    rb_define_method(rb_cDBM, \"each_pair\", fdbm_each_pair, 0);\n    rb_define_method(rb_cDBM, \"keys\", fdbm_keys, 0);\n    rb_define_method(rb_cDBM, \"values\", fdbm_values, 0);\n    rb_define_method(rb_cDBM, \"shift\", fdbm_shift, 0);\n    rb_define_method(rb_cDBM, \"delete\", fdbm_delete, 1);\n    rb_define_method(rb_cDBM, \"delete_if\", fdbm_delete_if, 0);\n    rb_define_method(rb_cDBM, \"reject!\", fdbm_delete_if, 0);\n    rb_define_method(rb_cDBM, \"reject\", fdbm_reject, 0);\n    rb_define_method(rb_cDBM, \"clear\", fdbm_clear, 0);\n    rb_define_method(rb_cDBM,\"invert\", fdbm_invert, 0);\n    rb_define_method(rb_cDBM,\"update\", fdbm_update, 1);\n    rb_define_method(rb_cDBM,\"replace\", fdbm_replace, 1);\n\n    rb_define_method(rb_cDBM, \"include?\", fdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"has_key?\", fdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"member?\", fdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"has_value?\", fdbm_has_value, 1);\n    rb_define_method(rb_cDBM, \"key?\", fdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"value?\", fdbm_has_value, 1);\n\n    rb_define_method(rb_cDBM, \"to_a\", fdbm_to_a, 0);\n    rb_define_method(rb_cDBM, \"to_hash\", fdbm_to_hash, 0);\n\n    /* flags for dbm_open() */\n    rb_define_const(rb_cDBM, \"READER\",  INT2FIX(O_RDONLY|RUBY_DBM_RW_BIT));\n    rb_define_const(rb_cDBM, \"WRITER\",  INT2FIX(O_RDWR|RUBY_DBM_RW_BIT));\n    rb_define_const(rb_cDBM, \"WRCREAT\", INT2FIX(O_RDWR|O_CREAT|RUBY_DBM_RW_BIT));\n    rb_define_const(rb_cDBM, \"NEWDB\",   INT2FIX(O_RDWR|O_CREAT|O_TRUNC|RUBY_DBM_RW_BIT));\n\n#ifdef DB_VERSION_STRING\n    rb_define_const(rb_cDBM, \"VERSION\",  rb_str_new2(DB_VERSION_STRING));\n#else\n    rb_define_const(rb_cDBM, \"VERSION\",  rb_str_new2(\"unknown\"));\n#endif\n}\n"
  },
  {
    "path": "ext/dbm/depend",
    "content": "dbm.o: dbm.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/dbm/extconf.rb",
    "content": "require 'mkmf'\n\ndir_config(\"dbm\")\n\nif dblib = with_config(\"dbm-type\", nil)\n  dblib = dblib.split(/[ ,]+/)\nelse\n  dblib = %w(db db2 db1 dbm gdbm gdbm_compat qdbm)\nend\n\nheaders = {\n  \"db\" => [\"db.h\"],\n  \"db1\" => [\"db1/ndbm.h\", \"db1.h\", \"ndbm.h\"],\n  \"db2\" => [\"db2/db.h\", \"db2.h\", \"db.h\"],\n  \"dbm\" => [\"ndbm.h\"],\n  \"gdbm\" => [\"gdbm-ndbm.h\", \"ndbm.h\"],\n  \"gdbm_compat\" => [\"gdbm-ndbm.h\", \"ndbm.h\"],\n  \"qdbm\" => [\"relic.h\"],\n}\n\ndef headers.db_check(db)\n  db_prefix = nil\n  have_gdbm = false\n  hsearch = nil\n\n  case db\n  when /^db2?$/\n    db_prefix = \"__db_n\"\n    hsearch = \"-DDB_DBM_HSEARCH \"\n  when \"gdbm\"\n    have_gdbm = true\n  when \"gdbm_compat\"\n    have_gdbm = true\n    have_library(\"gdbm\") or return false\n  end\n  db_prefix ||= \"\"\n\n  if (have_library(db, db_prefix+\"dbm_open\") || have_func(db_prefix+\"dbm_open\")) and\n      hdr = self.fetch(db, [\"ndbm.h\"]).find {|hdr| have_type(\"DBM\", hdr, hsearch)}\n    have_func(db_prefix+\"dbm_clearerr\") unless have_gdbm\n    $defs << hsearch if hsearch\n    $defs << '-DDBM_HDR=\"<'+hdr+'>\"'\n    true\n  else\n    false\n  end\nend\n\nif dblib.any? {|db| headers.db_check(db)}\n  have_header(\"cdefs.h\")\n  have_header(\"sys/cdefs.h\")\n  create_makefile(\"dbm\")\nend\n"
  },
  {
    "path": "ext/digest/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/digest/bubblebabble/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/digest/bubblebabble/bubblebabble.c",
    "content": "/************************************************\n\n  bubblebabble.c - BubbleBabble encoding support\n\n  $Author$\n  created at: Fri Oct 13 18:31:42 JST 2006\n\n  Copyright (C) 2006 Akinori MUSHA\n\n  $Id$\n\n************************************************/\n\n#include \"ruby.h\"\n#include \"digest.h\"\n\nstatic ID id_digest;\n\nstatic VALUE\nbubblebabble_str_new(VALUE str_digest)\n{\n    char *digest;\n    size_t digest_len;\n    VALUE str;\n    char *p;\n    int i, j, seed = 1;\n    static const char vowels[] = {\n        'a', 'e', 'i', 'o', 'u', 'y'\n    };\n    static const char consonants[] = {\n        'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 'n',\n        'p', 'r', 's', 't', 'v', 'z', 'x'\n    };\n\n    StringValue(str_digest);\n    digest = RSTRING_PTR(str_digest);\n    digest_len = RSTRING_LEN(str_digest);\n\n    if ((LONG_MAX - 2) / 3 < (digest_len | 1)) {\n\trb_raise(rb_eRuntimeError, \"digest string too long\");\n    }\n\n    str = rb_str_new(0, (digest_len | 1) * 3 + 2);\n    p = RSTRING_PTR(str);\n\n    i = j = 0;\n    p[j++] = 'x';\n\n    for (;;) {\n        unsigned char byte1, byte2;\n\n        if (i >= digest_len) {\n            p[j++] = vowels[seed % 6];\n            p[j++] = consonants[16];\n            p[j++] = vowels[seed / 6];\n            break;\n        } \n\n        byte1 = digest[i++];\n        p[j++] = vowels[(((byte1 >> 6) & 3) + seed) % 6];\n        p[j++] = consonants[(byte1 >> 2) & 15];\n        p[j++] = vowels[((byte1 & 3) + (seed / 6)) % 6];\n\n        if (i >= digest_len) {\n            break;\n        }\n\n        byte2 = digest[i++];\n        p[j++] = consonants[(byte2 >> 4) & 15];\n        p[j++] = '-';\n        p[j++] = consonants[byte2 & 15];\n\n        seed = (seed * 5 + byte1 * 7 + byte2) % 36;\n    }\n\n    p[j] = 'x';\n\n    return str;\n}\n\n/*\n * call-seq:\n *     Digest.bubblebabble(string) -> bubblebabble_string\n *\n * Returns a BubbleBabble encoded version of a given _string_.\n */\nstatic VALUE\nrb_digest_s_bubblebabble(VALUE klass, VALUE str)\n{\n    return bubblebabble_str_new(str);\n}\n\n/*\n * call-seq:\n *     Digest::Class.bubblebabble(string, ...) -> hash_string\n *\n * Returns the BubbleBabble encoded hash value of a given _string_.\n */\nstatic VALUE\nrb_digest_class_s_bubblebabble(int argc, VALUE *argv, VALUE klass)\n{\n    return bubblebabble_str_new(rb_funcall2(klass, id_digest, argc, argv));\n}\n\n/*\n * call-seq:\n *     digest_obj.bubblebabble -> hash_string\n *\n * Returns the resulting hash value in a Bubblebabble encoded form.\n */\nstatic VALUE\nrb_digest_instance_bubblebabble(VALUE self)\n{\n    return bubblebabble_str_new(rb_funcall(self, id_digest, 0));\n}\n\n/*\n * This module adds some methods to Digest classes to perform\n * BubbleBabble encoding.\n */\nvoid\nInit_bubblebabble(void)\n{\n    VALUE mDigest, mDigest_Instance, cDigest_Class;\n\n    rb_require(\"digest\");\n\n    mDigest = rb_path2class(\"Digest\");\n    mDigest_Instance = rb_path2class(\"Digest::Instance\");\n    cDigest_Class = rb_path2class(\"Digest::Class\");\n\n    /* Digest::bubblebabble() */\n    rb_define_module_function(mDigest, \"bubblebabble\", rb_digest_s_bubblebabble, 1);\n\n    /* Digest::Class::bubblebabble() */\n    rb_define_singleton_method(cDigest_Class, \"bubblebabble\", rb_digest_class_s_bubblebabble, -1);\n\n    /* Digest::Instance#bubblebabble() */\n    rb_define_method(mDigest_Instance, \"bubblebabble\", rb_digest_instance_bubblebabble, 0);\n\n    id_digest = rb_intern(\"digest\");\n}\n"
  },
  {
    "path": "ext/digest/bubblebabble/depend",
    "content": "bubblebabble.o: bubblebabble.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h \\\n  $(srcdir)/../defs.h\n"
  },
  {
    "path": "ext/digest/bubblebabble/extconf.rb",
    "content": "require 'mkmf'\n\n$defs << \"-DHAVE_CONFIG_H\"\n$INCFLAGS << \" -I$(srcdir)/..\"\n\ncreate_makefile('digest/bubblebabble')\n"
  },
  {
    "path": "ext/digest/defs.h",
    "content": "/* -*- C -*-\n * $Id$\n */\n\n#ifndef DEFS_H\n#define DEFS_H\n\n#include \"ruby.h\"\n#include <sys/types.h>\n\n#if defined(HAVE_SYS_CDEFS_H)\n# include <sys/cdefs.h>\n#endif\n#if !defined(__BEGIN_DECLS)\n# define __BEGIN_DECLS\n# define __END_DECLS\n#endif\n\n#if defined(HAVE_INTTYPES_H)\n# include <inttypes.h>\n#elif !defined __CYGWIN__ || !defined __uint8_t_defined\n  typedef unsigned char uint8_t;\n  typedef unsigned int  uint32_t;\n# if SIZEOF_LONG == 8\n  typedef unsigned long uint64_t;\n# elif SIZEOF_LONG_LONG == 8\n  typedef unsigned LONG_LONG uint64_t;\n# else\n#  define NO_UINT64_T\n# endif\n#endif\n\n#endif /* DEFS_H */\n"
  },
  {
    "path": "ext/digest/depend",
    "content": "digest.o: digest.c digest.h $(hdrdir)/ruby.h $(topdir)/config.h \\\n  $(hdrdir)/defines.h $(hdrdir)/intern.h\n"
  },
  {
    "path": "ext/digest/digest.c",
    "content": "/************************************************\n\n  digest.c -\n\n  $Author$\n  created at: Fri May 25 08:57:27 JST 2001\n\n  Copyright (C) 1995-2001 Yukihiro Matsumoto\n  Copyright (C) 2001-2006 Akinori MUSHA\n\n  $RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $\n  $Id$\n\n************************************************/\n\n#include \"digest.h\"\n\nstatic VALUE rb_mDigest;\nstatic VALUE rb_mDigest_Instance;\nstatic VALUE rb_cDigest_Class;\nstatic VALUE rb_cDigest_Base;\n\nstatic ID id_reset, id_update, id_finish, id_digest, id_hexdigest, id_digest_length;\nstatic ID id_metadata;\n\nRUBY_EXTERN void Init_digest_base(void);\n\n/*\n * Document-module: Digest\n *\n * This module provides a framework for message digest libraries.\n */\n\nstatic VALUE\nhexencode_str_new(VALUE str_digest)\n{\n    char *digest;\n    size_t digest_len;\n    int i;\n    VALUE str;\n    char *p;\n    static const char hex[] = {\n        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n        'a', 'b', 'c', 'd', 'e', 'f'\n    };\n\n    StringValue(str_digest);\n    digest = RSTRING_PTR(str_digest);\n    digest_len = RSTRING_LEN(str_digest);\n\n    if (LONG_MAX / 2 < digest_len) {\n        rb_raise(rb_eRuntimeError, \"digest string too long\");\n    }\n\n    str = rb_str_new(0, digest_len * 2);\n\n    for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {\n        unsigned char byte = digest[i];\n\n        p[i + i]     = hex[byte >> 4];\n        p[i + i + 1] = hex[byte & 0x0f];\n    }\n\n    return str;\n}\n\n/*\n * call-seq:\n *     Digest.hexencode(string) -> hexencoded_string\n *\n * Generates a hex-encoded version of a given _string_.\n */\nstatic VALUE\nrb_digest_s_hexencode(VALUE klass, VALUE str)\n{\n    return hexencode_str_new(str);\n}\n\n/*\n * Document-module: Digest::Instance\n *\n * This module provides instance methods for a digest implementation\n * object to calculate message digest values.\n */\n\nstatic void\nrb_digest_instance_method_unimpl(VALUE self, const char *method)\n{\n    VALUE klass = rb_obj_class(self);\n\n    rb_raise(rb_eRuntimeError, \"%s does not implement %s()\",\n\t     rb_obj_classname(self), method);\n}\n\n/*\n * call-seq:\n *     digest_obj.update(string) -> digest_obj\n *     digest_obj << string -> digest_obj\n *\n * Updates the digest using a given _string_ and returns self.\n *\n * The update() method and the left-shift operator are overridden by\n * each implementation subclass. (One should be an alias for the\n * other)\n */\nstatic VALUE\nrb_digest_instance_update(VALUE self, VALUE str)\n{\n    rb_digest_instance_method_unimpl(self, \"update\");\n}\n\n/*\n * call-seq:\n *     digest_obj.instance_eval { finish } -> digest_obj\n *\n * Finishes the digest and returns the resulting hash value.\n *\n * This method is overridden by each implementation subclass and often\n * made private, because some of those subclasses may leave internal\n * data uninitialized.  Do not call this method from outside.  Use\n * #digest!() instead, which ensures that internal data be reset for\n * security reasons.\n */\nstatic VALUE\nrb_digest_instance_finish(VALUE self)\n{\n    rb_digest_instance_method_unimpl(self, \"finish\");\n}\n\n/*\n * call-seq:\n *     digest_obj.reset -> digest_obj\n *\n * Resets the digest to the initial state and returns self.\n *\n * This method is overridden by each implementation subclass.\n */\nstatic VALUE\nrb_digest_instance_reset(VALUE self)\n{\n    rb_digest_instance_method_unimpl(self, \"reset\");\n}\n\n/*\n * call-seq:\n *     digest_obj.new -> another_digest_obj\n *\n * Returns a new, initialized copy of the digest object.  Equivalent\n * to digest_obj.clone().reset().\n */\nstatic VALUE\nrb_digest_instance_new(VALUE self)\n{\n    VALUE clone = rb_obj_clone(self);\n    rb_funcall(clone, id_reset, 0);\n    return clone;\n}\n\n/*\n * call-seq:\n *     digest_obj.digest -> string\n *     digest_obj.digest(string) -> string\n *\n * If none is given, returns the resulting hash value of the digest,\n * keeping the digest's state.\n *\n * If a _string_ is given, returns the hash value for the given\n * _string_, resetting the digest to the initial state before and\n * after the process.\n */\nstatic VALUE\nrb_digest_instance_digest(int argc, VALUE *argv, VALUE self)\n{\n    VALUE str, value;\n\n    if (rb_scan_args(argc, argv, \"01\", &str) > 0) {\n        rb_funcall(self, id_reset, 0);\n        rb_funcall(self, id_update, 1, str);\n        value = rb_funcall(self, id_finish, 0);\n        rb_funcall(self, id_reset, 0);\n    } else {\n        VALUE clone = rb_obj_clone(self);\n\n        value = rb_funcall(clone, id_finish, 0);\n        rb_funcall(clone, id_reset, 0);\n    }\n\n    return value;\n}\n\n/*\n * call-seq:\n *     digest_obj.digest! -> string\n *\n * Returns the resulting hash value and resets the digest to the\n * initial state.\n */\nstatic VALUE\nrb_digest_instance_digest_bang(VALUE self)\n{\n    VALUE value = rb_funcall(self, id_finish, 0);\n    rb_funcall(self, id_reset, 0);\n\n    return value;\n}\n\n/*\n * call-seq:\n *     digest_obj.hexdigest -> string\n *     digest_obj.hexdigest(string) -> string\n *\n * If none is given, returns the resulting hash value of the digest in\n * a hex-encoded form, keeping the digest's state.\n *\n * If a _string_ is given, returns the hash value for the given\n * _string_ in a hex-encoded form, resetting the digest to the initial\n * state before and after the process.\n */\nstatic VALUE\nrb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self)\n{\n    VALUE str, value;\n\n    if (rb_scan_args(argc, argv, \"01\", &str) > 0) {\n        rb_funcall(self, id_reset, 0);\n        rb_funcall(self, id_update, 1, str);\n        value = rb_funcall(self, id_finish, 0);\n        rb_funcall(self, id_reset, 0);\n    } else {\n        VALUE clone = rb_obj_clone(self);\n\n        value = rb_funcall(clone, id_finish, 0);\n        rb_funcall(clone, id_reset, 0);\n    }\n\n    return hexencode_str_new(value);\n}\n\n/*\n * call-seq:\n *     digest_obj.hexdigest! -> string\n *\n * Returns the resulting hash value and resets the digest to the\n * initial state.\n */\nstatic VALUE\nrb_digest_instance_hexdigest_bang(VALUE self)\n{\n    VALUE value = rb_funcall(self, id_finish, 0);\n    rb_funcall(self, id_reset, 0);\n\n    return hexencode_str_new(value);\n}\n\n/*\n * call-seq:\n *     digest_obj.to_s -> string\n *\n * Returns digest_obj.hexdigest().\n */\nstatic VALUE\nrb_digest_instance_to_s(VALUE self)\n{\n    return rb_funcall(self, id_hexdigest, 0);\n}\n\n/*\n * call-seq:\n *     digest_obj.inspect -> string\n *\n * Creates a printable version of the digest object.\n */\nstatic VALUE\nrb_digest_instance_inspect(VALUE self)\n{\n    VALUE str;\n    size_t digest_len = 32;\t/* about this size at least */\n    char *cname;\n\n    cname = rb_obj_classname(self);\n\n    /* #<Digest::ClassName: xxxxx...xxxx> */\n    str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1);\n    rb_str_buf_cat2(str, \"#<\");\n    rb_str_buf_cat2(str, cname);\n    rb_str_buf_cat2(str, \": \");\n    rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self));\n    rb_str_buf_cat2(str, \">\");\n    return str;\n}\n\n/*\n * call-seq:\n *     digest_obj == another_digest_obj -> boolean\n *     digest_obj == string -> boolean\n *\n * If a string is given, checks whether it is equal to the hex-encoded\n * hash value of the digest object.  If another digest instance is\n * given, checks whether they have the same hash value.  Otherwise\n * returns false.\n */\nstatic VALUE\nrb_digest_instance_equal(VALUE self, VALUE other)\n{\n    VALUE str1, str2;\n\n    if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) {\n        str1 = rb_digest_instance_digest(0, 0, self);\n        str2 = rb_digest_instance_digest(0, 0, other);\n    } else {\n        str1 = rb_digest_instance_to_s(self);\n        str2 = other;\n    }\n\n    /* never blindly assume that subclass methods return strings */\n    StringValue(str1);\n    StringValue(str2);\n\n    if (RSTRING_LEN(str1) == RSTRING_LEN(str2) &&\n\trb_str_cmp(str1, str2) == 0) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *     digest_obj.digest_length -> integer\n *\n * Returns the length of the hash value of the digest.\n *\n * This method should be overridden by each implementation subclass.\n * If not, digest_obj.digest().length() is returned.\n */\nstatic VALUE\nrb_digest_instance_digest_length(VALUE self)\n{\n    /* subclasses really should redefine this method */\n    VALUE digest = rb_digest_instance_digest(0, 0, self);\n\n    /* never blindly assume that #digest() returns a string */\n    StringValue(digest);\n    return INT2NUM(RSTRING_LEN(digest));\n}\n\n/*\n * call-seq:\n *     digest_obj.length -> integer\n *     digest_obj.size -> integer\n *\n * Returns digest_obj.digest_length().\n */\nstatic VALUE\nrb_digest_instance_length(VALUE self)\n{\n    return rb_funcall(self, id_digest_length, 0);\n}\n\n/*\n * call-seq:\n *     digest_obj.block_length -> integer\n *\n * Returns the block length of the digest.\n *\n * This method is overridden by each implementation subclass.\n */\nstatic VALUE\nrb_digest_instance_block_length(VALUE self)\n{\n    rb_digest_instance_method_unimpl(self, \"block_length\");\n}\n\n/*\n * Document-class: Digest::Class\n *\n * This module stands as a base class for digest implementation\n * classes.\n */\n\n/*\n * call-seq:\n *     Digest::Class.digest(string, *parameters) -> hash_string\n *\n * Returns the hash value of a given _string_.  This is equivalent to\n * Digest::Class.new(*parameters).digest(string), where extra\n * _parameters_, if any, are passed through to the constructor and the\n * _string_ is passed to #digest().\n */\nstatic VALUE\nrb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass)\n{\n    VALUE str;\n    volatile VALUE obj;\n\n    if (argc < 1) {\n        rb_raise(rb_eArgError, \"no data given\");\n    }\n\n    str = *argv++;\n    argc--;\n\n    StringValue(str);\n\n    obj = rb_obj_alloc(klass);\n    rb_obj_call_init(obj, argc, argv);\n\n    return rb_funcall(obj, id_digest, 1, str);\n}\n\n/*\n * call-seq:\n *     Digest::Class.hexdigest(string[, ...]) -> hash_string\n *\n * Returns the hex-encoded hash value of a given _string_.  This is\n * almost equivalent to\n * Digest.hexencode(Digest::Class.new(*parameters).digest(string)).\n */\nstatic VALUE\nrb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass)\n{\n    return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv));\n}\n\n/*\n * Document-class: Digest::Base\n *\n * This abstract class provides a common interface to message digest\n * implementation classes written in C.\n */\n\nstatic rb_digest_metadata_t *\nget_digest_base_metadata(VALUE klass)\n{\n    VALUE p;\n    VALUE obj;\n    rb_digest_metadata_t *algo;\n\n    for (p = klass; p; p = RCLASS(p)->super) {\n        if (rb_ivar_defined(p, id_metadata)) {\n            obj = rb_ivar_get(p, id_metadata);\n            break;\n        }\n    }\n\n    if (!p)\n        rb_raise(rb_eRuntimeError, \"Digest::Base cannot be directly inherited in Ruby\");\n\n    Data_Get_Struct(obj, rb_digest_metadata_t, algo);\n\n    switch (algo->api_version) {\n      case 2:\n        break;\n\n      /*\n       * put conversion here if possible when API is updated\n       */\n\n      default:\n        rb_raise(rb_eRuntimeError, \"Incompatible digest API version\");\n    }\n\n    return algo;\n}\n\nstatic VALUE\nrb_digest_base_alloc(VALUE klass)\n{\n    rb_digest_metadata_t *algo;\n    VALUE obj;\n    void *pctx;\n\n    if (klass == rb_cDigest_Base) {\n\trb_raise(rb_eNotImpError, \"Digest::Base is an abstract class\");\n    }\n\n    algo = get_digest_base_metadata(klass);\n\n    pctx = xmalloc(algo->ctx_size);\n    algo->init_func(pctx);\n\n    obj = Data_Wrap_Struct(klass, 0, free, pctx);\n\n    return obj;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_digest_base_copy(VALUE copy, VALUE obj)\n{\n    rb_digest_metadata_t *algo;\n    void *pctx1, *pctx2;\n\n    if (copy == obj) return copy;\n\n    rb_check_frozen(copy);\n\n    algo = get_digest_base_metadata(rb_obj_class(copy));\n\n    Data_Get_Struct(obj, void, pctx1);\n    Data_Get_Struct(copy, void, pctx2);\n    memcpy(pctx2, pctx1, algo->ctx_size);\n\n    return copy;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_digest_base_reset(VALUE self)\n{\n    rb_digest_metadata_t *algo;\n    void *pctx;\n\n    algo = get_digest_base_metadata(rb_obj_class(self));\n\n    Data_Get_Struct(self, void, pctx);\n\n    algo->init_func(pctx);\n\n    return self;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_digest_base_update(VALUE self, VALUE str)\n{\n    rb_digest_metadata_t *algo;\n    void *pctx;\n\n    algo = get_digest_base_metadata(rb_obj_class(self));\n\n    Data_Get_Struct(self, void, pctx);\n\n    StringValue(str);\n    algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));\n\n    return self;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_digest_base_finish(VALUE self)\n{\n    rb_digest_metadata_t *algo;\n    void *pctx;\n    VALUE str;\n\n    algo = get_digest_base_metadata(rb_obj_class(self));\n\n    Data_Get_Struct(self, void, pctx);\n\n    str = rb_str_new(0, algo->digest_len);\n    algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str));\n\n    /* avoid potential coredump caused by use of a finished context */\n    algo->init_func(pctx);\n\n    return str;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_digest_base_digest_length(VALUE self)\n{\n    rb_digest_metadata_t *algo;\n\n    algo = get_digest_base_metadata(rb_obj_class(self));\n\n    return INT2NUM(algo->digest_len);\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_digest_base_block_length(VALUE self)\n{\n    rb_digest_metadata_t *algo;\n\n    algo = get_digest_base_metadata(rb_obj_class(self));\n\n    return INT2NUM(algo->block_len);\n}\n\nvoid\nInit_digest(void)\n{\n    id_reset           = rb_intern(\"reset\");\n    id_update          = rb_intern(\"update\");\n    id_finish          = rb_intern(\"finish\");\n    id_digest          = rb_intern(\"digest\");\n    id_hexdigest       = rb_intern(\"hexdigest\");\n    id_digest_length   = rb_intern(\"digest_length\");\n\n    /*\n     * module Digest\n     */\n    rb_mDigest = rb_define_module(\"Digest\");\n\n    /* module functions */\n    rb_define_module_function(rb_mDigest, \"hexencode\", rb_digest_s_hexencode, 1);\n\n    /*\n     * module Digest::Instance\n     */\n    rb_mDigest_Instance = rb_define_module_under(rb_mDigest, \"Instance\");\n\n    /* instance methods that should be overridden */\n    rb_define_method(rb_mDigest_Instance, \"update\", rb_digest_instance_update, 1);\n    rb_define_method(rb_mDigest_Instance, \"<<\", rb_digest_instance_update, 1);\n    rb_define_private_method(rb_mDigest_Instance, \"finish\", rb_digest_instance_finish, 0);\n    rb_define_method(rb_mDigest_Instance, \"reset\", rb_digest_instance_reset, 0);\n    rb_define_method(rb_mDigest_Instance, \"digest_length\", rb_digest_instance_digest_length, 0);\n    rb_define_method(rb_mDigest_Instance, \"block_length\", rb_digest_instance_block_length, 0);\n\n    /* instance methods that may be overridden */\n    rb_define_method(rb_mDigest_Instance, \"==\", rb_digest_instance_equal, 1);\n    rb_define_method(rb_mDigest_Instance, \"inspect\", rb_digest_instance_inspect, 0);\n\n    /* instance methods that need not usually be overridden */\n    rb_define_method(rb_mDigest_Instance, \"new\", rb_digest_instance_new, 0);\n    rb_define_method(rb_mDigest_Instance, \"digest\", rb_digest_instance_digest, -1);\n    rb_define_method(rb_mDigest_Instance, \"digest!\", rb_digest_instance_digest_bang, 0);\n    rb_define_method(rb_mDigest_Instance, \"hexdigest\", rb_digest_instance_hexdigest, -1);\n    rb_define_method(rb_mDigest_Instance, \"hexdigest!\", rb_digest_instance_hexdigest_bang, 0);\n    rb_define_method(rb_mDigest_Instance, \"to_s\", rb_digest_instance_to_s, 0);\n    rb_define_method(rb_mDigest_Instance, \"length\", rb_digest_instance_length, 0);\n    rb_define_method(rb_mDigest_Instance, \"size\", rb_digest_instance_length, 0);\n\n    /*\n     * class Digest::Class\n     */\n    rb_cDigest_Class = rb_define_class_under(rb_mDigest, \"Class\", rb_cObject);\n    rb_include_module(rb_cDigest_Class, rb_mDigest_Instance);\n\n    /* class methods */\n    rb_define_singleton_method(rb_cDigest_Class, \"digest\", rb_digest_class_s_digest, -1);\n    rb_define_singleton_method(rb_cDigest_Class, \"hexdigest\", rb_digest_class_s_hexdigest, -1);\n\n    id_metadata = rb_intern(\"metadata\");\n\n    /* class Digest::Base < Digest::Class */\n    rb_cDigest_Base = rb_define_class_under(rb_mDigest, \"Base\", rb_cDigest_Class);\n\n    rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc);\n\n    rb_define_method(rb_cDigest_Base, \"initialize_copy\",  rb_digest_base_copy, 1);\n    rb_define_method(rb_cDigest_Base, \"reset\", rb_digest_base_reset, 0);\n    rb_define_method(rb_cDigest_Base, \"update\", rb_digest_base_update, 1);\n    rb_define_method(rb_cDigest_Base, \"<<\", rb_digest_base_update, 1);\n    rb_define_private_method(rb_cDigest_Base, \"finish\", rb_digest_base_finish, 0);\n    rb_define_method(rb_cDigest_Base, \"digest_length\", rb_digest_base_digest_length, 0);\n    rb_define_method(rb_cDigest_Base, \"block_length\", rb_digest_base_block_length, 0);\n}\n"
  },
  {
    "path": "ext/digest/digest.h",
    "content": "/************************************************\n\n  digest.h - header file for ruby digest modules\n\n  $Author$\n  created at: Fri May 25 08:54:56 JST 2001\n\n\n  Copyright (C) 2001-2006 Akinori MUSHA\n\n  $RoughId: digest.h,v 1.3 2001/07/13 15:38:27 knu Exp $\n  $Id$\n\n************************************************/\n\n#include \"ruby.h\"\n\n#define RUBY_DIGEST_API_VERSION\t2\n\ntypedef void (*rb_digest_hash_init_func_t)(void *);\ntypedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t);\ntypedef void (*rb_digest_hash_finish_func_t)(void *, unsigned char *);\n\ntypedef struct {\n    int api_version;\n    size_t digest_len;\n    size_t block_len;\n    size_t ctx_size;\n    rb_digest_hash_init_func_t init_func;\n    rb_digest_hash_update_func_t update_func;\n    rb_digest_hash_finish_func_t finish_func;\n} rb_digest_metadata_t;\n"
  },
  {
    "path": "ext/digest/extconf.rb",
    "content": "# $RoughId: extconf.rb,v 1.6 2001/07/13 15:38:27 knu Exp $\n# $Id$\n\nrequire \"mkmf\"\n\n$INSTALLFILES = {\n  \"digest.h\" => \"$(RUBYARCHDIR)\"\n}\n\ncreate_makefile(\"digest\")\n"
  },
  {
    "path": "ext/digest/lib/digest.rb",
    "content": "require 'digest.so'\n\nmodule Digest\n  def self.const_missing(name)\n    case name\n    when :SHA256, :SHA384, :SHA512\n      lib = 'digest/sha2.so'\n    else\n      lib = File.join('digest', name.to_s.downcase)\n    end\n\n    begin\n      require lib\n    rescue LoadError => e\n      raise LoadError, \"library not found for class Digest::#{name} -- #{lib}\", caller(1)\n    end\n    unless Digest.const_defined?(name)\n      raise NameError, \"uninitialized constant Digest::#{name}\", caller(1)\n    end\n    Digest.const_get(name)\n  end\n\n  class ::Digest::Class\n    # creates a digest object and reads a given file, _name_.\n    # \n    #  p Digest::SHA256.file(\"X11R6.8.2-src.tar.bz2\").hexdigest\n    #  # => \"f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534\"\n    def self.file(name)\n      new.file(name)\n    end\n  end\n\n  module Instance\n    # updates the digest with the contents of a given file _name_ and\n    # returns self.\n    def file(name)\n      File.open(name, \"rb\") {|f|\n        buf = \"\"\n        while f.read(16384, buf)\n          update buf\n        end\n      }\n      self\n    end\n  end\nend\n\ndef Digest(name)\n  Digest.const_get(name)\nend\n"
  },
  {
    "path": "ext/digest/lib/md5.rb",
    "content": "# just for compatibility; requiring \"md5\" is obsoleted\n#\n# $RoughId: md5.rb,v 1.4 2001/07/13 15:38:27 knu Exp $\n# $Id$\n\nrequire 'digest/md5'\n\nclass MD5 < Digest::MD5\n  class << self\n    alias orig_new new\n    def new(str = nil)\n      if str\n        orig_new.update(str)\n      else\n        orig_new\n      end\n    end\n\n    def md5(*args)\n      new(*args)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/digest/lib/sha1.rb",
    "content": "# just for compatibility; requiring \"sha1\" is obsoleted\n#\n# $RoughId: sha1.rb,v 1.4 2001/07/13 15:38:27 knu Exp $\n# $Id$\n\nrequire 'digest/sha1'\n\nclass SHA1 < Digest::SHA1\n  class << self\n    alias orig_new new\n    def new(str = nil)\n      if str\n        orig_new.update(str)\n      else\n        orig_new\n      end\n    end\n\n    def sha1(*args)\n      new(*args)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/digest/md5/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/digest/md5/depend",
    "content": "md5.o: md5.c md5.h $(srcdir)/../defs.h $(hdrdir)/ruby.h $(topdir)/config.h \\\n  $(hdrdir)/defines.h $(hdrdir)/intern.h\nmd5init.o: md5init.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h md5.h \\\n  $(srcdir)/../defs.h\nmd5ossl.o: md5ossl.h\n"
  },
  {
    "path": "ext/digest/md5/extconf.rb",
    "content": "# $RoughId: extconf.rb,v 1.3 2001/08/14 19:54:51 knu Exp $\n# $Id$\n\nrequire \"mkmf\"\n\n$defs << \"-DHAVE_CONFIG_H\"\n$INCFLAGS << \" -I$(srcdir)/..\"\n\n$objs = [ \"md5init.#{$OBJEXT}\" ]\n\ndir_config(\"openssl\")\n\nif !with_config(\"bundled-md5\") &&\n    have_library(\"crypto\") && have_header(\"openssl/md5.h\")\n  $objs << \"md5ossl.#{$OBJEXT}\"\n\nelse\n  $objs << \"md5.#{$OBJEXT}\"\nend\n\nhave_header(\"sys/cdefs.h\")\n\nhave_header(\"inttypes.h\")\n\nhave_header(\"unistd.h\")\n\n$preload = %w[digest]\n\ncreate_makefile(\"digest/md5\")\n"
  },
  {
    "path": "ext/digest/md5/md5.c",
    "content": "/*\n  Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  L. Peter Deutsch\n  ghost@aladdin.com\n\n */\n\n/*\n  Independent implementation of MD5 (RFC 1321).\n\n  This code implements the MD5 Algorithm defined in RFC 1321.\n  It is derived directly from the text of the RFC and not from the\n  reference implementation.\n\n  The original and principal author of md5.c is L. Peter Deutsch\n  <ghost@aladdin.com>.  Other authors are noted in the change history\n  that follows (in reverse chronological order):\n\n  2000-07-03 lpd Patched to eliminate warnings about \"constant is\n\t\tunsigned in ANSI C, signed in traditional\";\n\t\tmade test program self-checking.\n  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.\n  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).\n  1999-05-03 lpd Original version.\n */\n\n/*\n  This code was modified for use in Ruby.\n\n  - Akinori MUSHA <knu@idaemons.org>\n */\n\n/*$OrigId: md5c.c,v 1.2 2001/03/26 08:57:14 matz Exp $ */\n/*$RoughId: md5.c,v 1.2 2001/07/13 19:48:41 knu Exp $ */\n/*$Id$ */\n\n#include \"md5.h\"\n\n#ifdef TEST\n/*\n * Compile with -DTEST to create a self-contained executable test program.\n * The test program should print out the same values as given in section\n * A.5 of RFC 1321, reproduced below.\n */\n#include <string.h>\nmain()\n{\n    static const char *const test[7*2] = {\n\t\"\", \"d41d8cd98f00b204e9800998ecf8427e\",\n\t\"a\", \"0cc175b9c0f1b6a831c399e269772661\",\n\t\"abc\", \"900150983cd24fb0d6963f7d28e17f72\",\n\t\"message digest\", \"f96b697d7cb7938d525a2f31aaf161d0\",\n\t\"abcdefghijklmnopqrstuvwxyz\", \"c3fcd3d76192e4007dfb496cca67e13b\",\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\",\n\t\t\t\t\"d174ab98d277d9f5a5611c2c9f419d9f\",\n\t\"12345678901234567890123456789012345678901234567890123456789012345678901234567890\", \"57edf4a22be3c955ac49da2e2107b67a\"\n    };\n    int i;\n\n    for (i = 0; i < 7*2; i += 2) {\n\tMD5_CTX state;\n\tuint8_t digest[16];\n\tchar hex_output[16*2 + 1];\n\tint di;\n\n\tMD5_Init(&state);\n\tMD5_Update(&state, (const uint8_t *)test[i], strlen(test[i]));\n\tMD5_Final(digest, &state);\n\tprintf(\"MD5 (\\\"%s\\\") = \", test[i]);\n\tfor (di = 0; di < 16; ++di)\n\t    sprintf(hex_output + di * 2, \"%02x\", digest[di]);\n\tputs(hex_output);\n\tif (strcmp(hex_output, test[i + 1]))\n\t    printf(\"**** ERROR, should be: %s\\n\", test[i + 1]);\n    }\n    return 0;\n}\n#endif /* TEST */\n\n\n/*\n * For reference, here is the program that computed the T values.\n */\n#ifdef COMPUTE_T_VALUES\n#include <math.h>\nmain()\n{\n    int i;\n    for (i = 1; i <= 64; ++i) {\n\tunsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));\n\n\t/*\n\t * The following nonsense is only to avoid compiler warnings about\n\t * \"integer constant is unsigned in ANSI C, signed with -traditional\".\n\t */\n\tif (v >> 31) {\n\t    printf(\"#define T%d /* 0x%08lx */ (T_MASK ^ 0x%08lx)\\n\", i,\n\t\t   v, (unsigned long)(unsigned int)(~v));\n\t} else {\n\t    printf(\"#define T%d    0x%08lx\\n\", i, v);\n\t}\n    }\n    return 0;\n}\n#endif /* COMPUTE_T_VALUES */\n/*\n * End of T computation program.\n */\n#ifdef T_MASK\n#undef T_MASK\n#endif\n#define T_MASK ((uint32_t)~0)\n#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)\n#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)\n#define T3    0x242070db\n#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)\n#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)\n#define T6    0x4787c62a\n#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)\n#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)\n#define T9    0x698098d8\n#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)\n#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)\n#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)\n#define T13    0x6b901122\n#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)\n#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)\n#define T16    0x49b40821\n#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)\n#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)\n#define T19    0x265e5a51\n#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)\n#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)\n#define T22    0x02441453\n#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)\n#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)\n#define T25    0x21e1cde6\n#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)\n#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)\n#define T28    0x455a14ed\n#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)\n#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)\n#define T31    0x676f02d9\n#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)\n#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)\n#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)\n#define T35    0x6d9d6122\n#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)\n#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)\n#define T38    0x4bdecfa9\n#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)\n#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)\n#define T41    0x289b7ec6\n#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)\n#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)\n#define T44    0x04881d05\n#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)\n#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)\n#define T47    0x1fa27cf8\n#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)\n#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)\n#define T50    0x432aff97\n#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)\n#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)\n#define T53    0x655b59c3\n#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)\n#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)\n#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)\n#define T57    0x6fa87e4f\n#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)\n#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)\n#define T60    0x4e0811a1\n#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)\n#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)\n#define T63    0x2ad7d2bb\n#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)\n\n\nstatic void\nmd5_process(MD5_CTX *pms, const uint8_t *data /*[64]*/)\n{\n    uint32_t\n\ta = pms->state[0], b = pms->state[1],\n\tc = pms->state[2], d = pms->state[3];\n    uint32_t t;\n\n#ifdef WORDS_BIGENDIAN\n\n    /*\n     * On big-endian machines, we must arrange the bytes in the right\n     * order.  (This also works on machines of unknown byte order.)\n     */\n    uint32_t X[16];\n    const uint8_t *xp = data;\n    int i;\n\n    for (i = 0; i < 16; ++i, xp += 4)\n\tX[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);\n\n#else\n\n    /*\n     * On little-endian machines, we can process properly aligned data\n     * without copying it.\n     */\n    uint32_t xbuf[16];\n    const uint32_t *X;\n\n    if (!((data - (const uint8_t *)0) & 3)) {\n\t/* data are properly aligned */\n\tX = (const uint32_t *)data;\n    } else {\n\t/* not aligned */\n\tmemcpy(xbuf, data, 64);\n\tX = xbuf;\n    }\n#endif\n\n#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))\n\n    /* Round 1. */\n    /* Let [abcd k s i] denote the operation\n       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */\n#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + F(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n    /* Do the following 16 operations. */\n    SET(a, b, c, d,  0,  7,  T1);\n    SET(d, a, b, c,  1, 12,  T2);\n    SET(c, d, a, b,  2, 17,  T3);\n    SET(b, c, d, a,  3, 22,  T4);\n    SET(a, b, c, d,  4,  7,  T5);\n    SET(d, a, b, c,  5, 12,  T6);\n    SET(c, d, a, b,  6, 17,  T7);\n    SET(b, c, d, a,  7, 22,  T8);\n    SET(a, b, c, d,  8,  7,  T9);\n    SET(d, a, b, c,  9, 12, T10);\n    SET(c, d, a, b, 10, 17, T11);\n    SET(b, c, d, a, 11, 22, T12);\n    SET(a, b, c, d, 12,  7, T13);\n    SET(d, a, b, c, 13, 12, T14);\n    SET(c, d, a, b, 14, 17, T15);\n    SET(b, c, d, a, 15, 22, T16);\n#undef SET\n\n     /* Round 2. */\n     /* Let [abcd k s i] denote the operation\n          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */\n#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + G(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n     /* Do the following 16 operations. */\n    SET(a, b, c, d,  1,  5, T17);\n    SET(d, a, b, c,  6,  9, T18);\n    SET(c, d, a, b, 11, 14, T19);\n    SET(b, c, d, a,  0, 20, T20);\n    SET(a, b, c, d,  5,  5, T21);\n    SET(d, a, b, c, 10,  9, T22);\n    SET(c, d, a, b, 15, 14, T23);\n    SET(b, c, d, a,  4, 20, T24);\n    SET(a, b, c, d,  9,  5, T25);\n    SET(d, a, b, c, 14,  9, T26);\n    SET(c, d, a, b,  3, 14, T27);\n    SET(b, c, d, a,  8, 20, T28);\n    SET(a, b, c, d, 13,  5, T29);\n    SET(d, a, b, c,  2,  9, T30);\n    SET(c, d, a, b,  7, 14, T31);\n    SET(b, c, d, a, 12, 20, T32);\n#undef SET\n\n     /* Round 3. */\n     /* Let [abcd k s t] denote the operation\n          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */\n#define H(x, y, z) ((x) ^ (y) ^ (z))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + H(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n     /* Do the following 16 operations. */\n    SET(a, b, c, d,  5,  4, T33);\n    SET(d, a, b, c,  8, 11, T34);\n    SET(c, d, a, b, 11, 16, T35);\n    SET(b, c, d, a, 14, 23, T36);\n    SET(a, b, c, d,  1,  4, T37);\n    SET(d, a, b, c,  4, 11, T38);\n    SET(c, d, a, b,  7, 16, T39);\n    SET(b, c, d, a, 10, 23, T40);\n    SET(a, b, c, d, 13,  4, T41);\n    SET(d, a, b, c,  0, 11, T42);\n    SET(c, d, a, b,  3, 16, T43);\n    SET(b, c, d, a,  6, 23, T44);\n    SET(a, b, c, d,  9,  4, T45);\n    SET(d, a, b, c, 12, 11, T46);\n    SET(c, d, a, b, 15, 16, T47);\n    SET(b, c, d, a,  2, 23, T48);\n#undef SET\n\n     /* Round 4. */\n     /* Let [abcd k s t] denote the operation\n          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */\n#define I(x, y, z) ((y) ^ ((x) | ~(z)))\n#define SET(a, b, c, d, k, s, Ti)\\\n  t = a + I(b,c,d) + X[k] + Ti;\\\n  a = ROTATE_LEFT(t, s) + b\n     /* Do the following 16 operations. */\n    SET(a, b, c, d,  0,  6, T49);\n    SET(d, a, b, c,  7, 10, T50);\n    SET(c, d, a, b, 14, 15, T51);\n    SET(b, c, d, a,  5, 21, T52);\n    SET(a, b, c, d, 12,  6, T53);\n    SET(d, a, b, c,  3, 10, T54);\n    SET(c, d, a, b, 10, 15, T55);\n    SET(b, c, d, a,  1, 21, T56);\n    SET(a, b, c, d,  8,  6, T57);\n    SET(d, a, b, c, 15, 10, T58);\n    SET(c, d, a, b,  6, 15, T59);\n    SET(b, c, d, a, 13, 21, T60);\n    SET(a, b, c, d,  4,  6, T61);\n    SET(d, a, b, c, 11, 10, T62);\n    SET(c, d, a, b,  2, 15, T63);\n    SET(b, c, d, a,  9, 21, T64);\n#undef SET\n\n     /* Then perform the following additions. (That is increment each\n        of the four registers by the value it had before this block\n        was started.) */\n    pms->state[0] += a;\n    pms->state[1] += b;\n    pms->state[2] += c;\n    pms->state[3] += d;\n}\n\nvoid\nMD5_Init(MD5_CTX *pms)\n{\n    pms->count[0] = pms->count[1] = 0;\n    pms->state[0] = 0x67452301;\n    pms->state[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;\n    pms->state[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;\n    pms->state[3] = 0x10325476;\n}\n\nvoid\nMD5_Update(MD5_CTX *pms, const uint8_t *data, size_t nbytes)\n{\n    const uint8_t *p = data;\n    size_t left = nbytes;\n    size_t offset = (pms->count[0] >> 3) & 63;\n    uint32_t nbits = (uint32_t)(nbytes << 3);\n\n    if (nbytes <= 0)\n\treturn;\n\n    /* Update the message length. */\n    pms->count[1] += nbytes >> 29;\n    pms->count[0] += nbits;\n    if (pms->count[0] < nbits)\n\tpms->count[1]++;\n\n    /* Process an initial partial block. */\n    if (offset) {\n\tsize_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);\n\n\tmemcpy(pms->buffer + offset, p, copy);\n\tif (offset + copy < 64)\n\t    return;\n\tp += copy;\n\tleft -= copy;\n\tmd5_process(pms, pms->buffer);\n    }\n\n    /* Process full blocks. */\n    for (; left >= 64; p += 64, left -= 64)\n\tmd5_process(pms, p);\n\n    /* Process a final partial block. */\n    if (left)\n\tmemcpy(pms->buffer, p, left);\n}\n\nvoid\nMD5_Finish(MD5_CTX *pms, uint8_t *digest)\n{\n    static const uint8_t pad[64] = {\n\t0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n    };\n    uint8_t data[8];\n    size_t i;\n\n    /* Save the length before padding. */\n    for (i = 0; i < 8; ++i)\n\tdata[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3));\n    /* Pad to 56 bytes mod 64. */\n    MD5_Update(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);\n    /* Append the length. */\n    MD5_Update(pms, data, 8);\n    for (i = 0; i < 16; ++i)\n\tdigest[i] = (uint8_t)(pms->state[i >> 2] >> ((i & 3) << 3));\n}\n"
  },
  {
    "path": "ext/digest/md5/md5.h",
    "content": "/*\n  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  L. Peter Deutsch\n  ghost@aladdin.com\n\n */\n/*\n  Independent implementation of MD5 (RFC 1321).\n\n  This code implements the MD5 Algorithm defined in RFC 1321.\n  It is derived directly from the text of the RFC and not from the\n  reference implementation.\n\n  The original and principal author of md5.h is L. Peter Deutsch\n  <ghost@aladdin.com>.  Other authors are noted in the change history\n  that follows (in reverse chronological order):\n\n  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.\n  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);\n\tadded conditionalization for C++ compilation from Martin\n\tPurschke <purschke@bnl.gov>.\n  1999-05-03 lpd Original version.\n */\n\n/* $OrigId: md5.h,v 1.2 2001/03/26 08:57:14 matz Exp $ */\n/* $RoughId: md5.h,v 1.3 2002/02/24 08:14:31 knu Exp $ */\n/* $Id$ */\n\n#ifndef MD5_INCLUDED\n#  define MD5_INCLUDED\n\n#include \"defs.h\"\n\n/*\n * This code has some adaptations for the Ghostscript environment, but it\n * will compile and run correctly in any environment with 8-bit chars and\n * 32-bit ints.  Specifically, it assumes that if the following are\n * defined, they have the same meaning as in Ghostscript: P1, P2, P3.\n */\n\n/* Define the state of the MD5 Algorithm. */\ntypedef struct md5_state_s {\n    uint32_t count[2];\t/* message length in bits, lsw first */\n    uint32_t state[4];\t/* digest buffer */\n    uint8_t buffer[64];\t/* accumulate block */\n} MD5_CTX;\n\n#ifdef RUBY\n/* avoid name clash */\n#define MD5_Init\trb_Digest_MD5_Init\n#define MD5_Update\trb_Digest_MD5_Update\n#define MD5_Finish\trb_Digest_MD5_Finish\n#endif\n\nvoid\tMD5_Init _((MD5_CTX *pms));\nvoid\tMD5_Update _((MD5_CTX *pms, const uint8_t *data, size_t nbytes));\nvoid\tMD5_Finish _((MD5_CTX *pms, uint8_t *digest));\n\n#define MD5_BLOCK_LENGTH\t\t64\n#define MD5_DIGEST_LENGTH\t\t16\n#define MD5_DIGEST_STRING_LENGTH\t(MD5_DIGEST_LENGTH * 2 + 1)\n\n#endif /* MD5_INCLUDED */\n"
  },
  {
    "path": "ext/digest/md5/md5init.c",
    "content": "/* $RoughId: md5init.c,v 1.2 2001/07/13 19:49:10 knu Exp $ */\n/* $Id$ */\n\n#include \"digest.h\"\n#if defined(HAVE_OPENSSL_MD5_H)\n#include \"md5ossl.h\"\n#else\n#include \"md5.h\"\n#endif\n\nstatic rb_digest_metadata_t md5 = {\n    RUBY_DIGEST_API_VERSION,\n    MD5_DIGEST_LENGTH,\n    MD5_BLOCK_LENGTH,\n    sizeof(MD5_CTX),\n    (rb_digest_hash_init_func_t)MD5_Init,\n    (rb_digest_hash_update_func_t)MD5_Update,\n    (rb_digest_hash_finish_func_t)MD5_Finish,\n};\n\n/*\n * A class for calculating message digests using the MD5\n * Message-Digest Algorithm by RSA Data Security, Inc., described in\n * RFC1321.\n */\nvoid\nInit_md5()\n{\n    VALUE mDigest, cDigest_Base, cDigest_MD5;\n\n    rb_require(\"digest\");\n\n    mDigest = rb_path2class(\"Digest\");\n    cDigest_Base = rb_path2class(\"Digest::Base\");\n\n    cDigest_MD5 = rb_define_class_under(mDigest, \"MD5\", cDigest_Base);\n\n    rb_ivar_set(cDigest_MD5, rb_intern(\"metadata\"),\n      Data_Wrap_Struct(rb_cObject, 0, 0, &md5));\n}\n"
  },
  {
    "path": "ext/digest/md5/md5ossl.c",
    "content": "/* $Id$ */\n\n#include \"md5ossl.h\"\n\nvoid\nMD5_Finish(MD5_CTX *pctx, unsigned char *digest)\n{\n    MD5_Final(digest, pctx);\n}\n"
  },
  {
    "path": "ext/digest/md5/md5ossl.h",
    "content": "/* $Id$ */\n\n#ifndef MD5OSSL_H_INCLUDED\n#define MD5OSSL_H_INCLUDED\n\n#include <stddef.h>\n#include <openssl/md5.h>\n\n#define MD5_BLOCK_LENGTH\tMD5_CBLOCK\n\nvoid MD5_Finish(MD5_CTX *pctx, unsigned char *digest);\n\n#endif\n"
  },
  {
    "path": "ext/digest/rmd160/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/digest/rmd160/depend",
    "content": "rmd160.o: rmd160.c rmd160.h $(srcdir)/../defs.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h\nrmd160init.o: rmd160init.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h \\\n  rmd160.h $(srcdir)/../defs.h\nrmd160ossl.o: rmd160ossl.h $(srcdir)/../defs.h\n"
  },
  {
    "path": "ext/digest/rmd160/extconf.rb",
    "content": "# $RoughId: extconf.rb,v 1.3 2001/08/14 19:54:51 knu Exp $\n# $Id$\n\nrequire \"mkmf\"\n\n$defs << \"-DNDEBUG\" << \"-DHAVE_CONFIG_H\"\n$INCFLAGS << \" -I$(srcdir)/..\"\n\n$objs = [ \"rmd160init.#{$OBJEXT}\" ]\n\ndir_config(\"openssl\")\n\nif !with_config(\"bundled-rmd160\") &&\n    have_library(\"crypto\") && have_header(\"openssl/ripemd.h\")\n  $objs << \"rmd160ossl.#{$OBJEXT}\"\nelse\n  $objs << \"rmd160.#{$OBJEXT}\"\nend\n\nhave_header(\"sys/cdefs.h\")\n\nhave_header(\"inttypes.h\")\n\nhave_header(\"unistd.h\")\n\n$preload = %w[digest]\n\ncreate_makefile(\"digest/rmd160\")\n"
  },
  {
    "path": "ext/digest/rmd160/rmd160.c",
    "content": "/*\t$NetBSD: rmd160.c,v 1.1.1.1 2001/03/06 11:21:05 agc Exp $\t*/\n/*\t$RoughId: rmd160.c,v 1.2 2001/07/13 19:49:10 knu Exp $\t*/\n/*\t$Id$\t*/\n\n/********************************************************************\\\n *\n *      FILE:     rmd160.c\n *\n *      CONTENTS: A sample C-implementation of the RIPEMD-160\n *\t\t  hash-function.\n *      TARGET:   any computer with an ANSI C compiler\n *\n *      AUTHOR:   Antoon Bosselaers, ESAT-COSIC\n *\t\t  (Arranged for libc by Todd C. Miller)\n *      DATE:     1 March 1996\n *      VERSION:  1.0\n *\n *      Copyright (c) Katholieke Universiteit Leuven\n *      1996, All Rights Reserved\n *\n\\********************************************************************/\n\n#include \"rmd160.h\"\n\n#ifndef lint\n/* __RCSID(\"$NetBSD: rmd160.c,v 1.1.1.1 2001/03/06 11:21:05 agc Exp $\"); */\n#endif\t/* not lint */\n\n/* header files */\n\n#ifdef HAVE_SYS_ENDIAN_H_\n#include <sys/endian.h>\n#endif\n\n#ifdef HAVE_MACHINE_ENDIAN_H_\n#include <machine/endian.h>\n#endif\n\n/* #include \"namespace.h\" */\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifndef _DIAGASSERT\n#define _DIAGASSERT(cond)\tassert(cond)\n#endif\n\n\n/********************************************************************/\n\n/* macro definitions */\n\n/* collect four bytes into one word: */\n#define BYTES_TO_DWORD(strptr)\t\t\t\\\n    (((uint32_t) *((strptr)+3) << 24) |\t\\\n    ((uint32_t) *((strptr)+2) << 16) |\t\t\\\n    ((uint32_t) *((strptr)+1) <<  8) |\t\t\\\n    ((uint32_t) *(strptr)))\n\n/* ROL(x, n) cyclically rotates x over n bits to the left */\n/* x must be of an unsigned 32 bits type and 0 <= n < 32. */\n#define ROL(x, n)\t(((x) << (n)) | ((x) >> (32-(n))))\n\n/* the three basic functions F(), G() and H() */\n#define F(x, y, z)\t((x) ^ (y) ^ (z))\n#define G(x, y, z)\t(((x) & (y)) | (~(x) & (z)))\n#define H(x, y, z)\t(((x) | ~(y)) ^ (z))\n#define I(x, y, z)\t(((x) & (z)) | ((y) & ~(z)))\n#define J(x, y, z)\t((x) ^ ((y) | ~(z)))\n\n/* the eight basic operations FF() through III() */\n#define FF(a, b, c, d, e, x, s)\t{\t\t\t\\\n      (a) += F((b), (c), (d)) + (x);\t\t\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define GG(a, b, c, d, e, x, s)\t{\t\t\t\\\n      (a) += G((b), (c), (d)) + (x) + 0x5a827999U;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define HH(a, b, c, d, e, x, s)\t{\t\t\t\\\n      (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1U;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define II(a, b, c, d, e, x, s)\t{\t\t\t\\\n      (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcU;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define JJ(a, b, c, d, e, x, s)\t{\t\t\t\\\n      (a) += J((b), (c), (d)) + (x) + 0xa953fd4eU;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define FFF(a, b, c, d, e, x, s)\t{\t\t\\\n      (a) += F((b), (c), (d)) + (x);\t\t\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define GGG(a, b, c, d, e, x, s)\t{\t\t\\\n      (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9U;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define HHH(a, b, c, d, e, x, s)\t{\t\t\\\n      (a) += H((b), (c), (d)) + (x) + 0x6d703ef3U;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define III(a, b, c, d, e, x, s)\t{\t\t\\\n      (a) += I((b), (c), (d)) + (x) + 0x5c4dd124U;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n#define JJJ(a, b, c, d, e, x, s)\t{\t\t\\\n      (a) += J((b), (c), (d)) + (x) + 0x50a28be6U;\t\\\n      (a) = ROL((a), (s)) + (e);\t\t\t\\\n      (c) = ROL((c), 10);\t\t\t\t\\\n}\n\n/********************************************************************/\n\nvoid\nRMD160_Init(RMD160_CTX *context)\n{\n\n\t_DIAGASSERT(context != NULL);\n\n\t/* ripemd-160 initialization constants */\n\tcontext->state[0] = 0x67452301U;\n\tcontext->state[1] = 0xefcdab89U;\n\tcontext->state[2] = 0x98badcfeU;\n\tcontext->state[3] = 0x10325476U;\n\tcontext->state[4] = 0xc3d2e1f0U;\n\tcontext->length[0] = context->length[1] = 0;\n\tcontext->buflen = 0;\n}\n\n/********************************************************************/\n\nvoid\nRMD160_Transform(uint32_t state[5], const uint32_t block[16])\n{\n\tuint32_t aa, bb, cc, dd, ee;\n\tuint32_t aaa, bbb, ccc, ddd, eee;\n\n\t_DIAGASSERT(state != NULL);\n\t_DIAGASSERT(block != NULL);\n\n\taa = aaa = state[0];\n\tbb = bbb = state[1];\n\tcc = ccc = state[2];\n\tdd = ddd = state[3];\n\tee = eee = state[4];\n\n\t/* round 1 */\n\tFF(aa, bb, cc, dd, ee, block[ 0], 11);\n\tFF(ee, aa, bb, cc, dd, block[ 1], 14);\n\tFF(dd, ee, aa, bb, cc, block[ 2], 15);\n\tFF(cc, dd, ee, aa, bb, block[ 3], 12);\n\tFF(bb, cc, dd, ee, aa, block[ 4],  5);\n\tFF(aa, bb, cc, dd, ee, block[ 5],  8);\n\tFF(ee, aa, bb, cc, dd, block[ 6],  7);\n\tFF(dd, ee, aa, bb, cc, block[ 7],  9);\n\tFF(cc, dd, ee, aa, bb, block[ 8], 11);\n\tFF(bb, cc, dd, ee, aa, block[ 9], 13);\n\tFF(aa, bb, cc, dd, ee, block[10], 14);\n\tFF(ee, aa, bb, cc, dd, block[11], 15);\n\tFF(dd, ee, aa, bb, cc, block[12],  6);\n\tFF(cc, dd, ee, aa, bb, block[13],  7);\n\tFF(bb, cc, dd, ee, aa, block[14],  9);\n\tFF(aa, bb, cc, dd, ee, block[15],  8);\n\n\t/* round 2 */\n\tGG(ee, aa, bb, cc, dd, block[ 7],  7);\n\tGG(dd, ee, aa, bb, cc, block[ 4],  6);\n\tGG(cc, dd, ee, aa, bb, block[13],  8);\n\tGG(bb, cc, dd, ee, aa, block[ 1], 13);\n\tGG(aa, bb, cc, dd, ee, block[10], 11);\n\tGG(ee, aa, bb, cc, dd, block[ 6],  9);\n\tGG(dd, ee, aa, bb, cc, block[15],  7);\n\tGG(cc, dd, ee, aa, bb, block[ 3], 15);\n\tGG(bb, cc, dd, ee, aa, block[12],  7);\n\tGG(aa, bb, cc, dd, ee, block[ 0], 12);\n\tGG(ee, aa, bb, cc, dd, block[ 9], 15);\n\tGG(dd, ee, aa, bb, cc, block[ 5],  9);\n\tGG(cc, dd, ee, aa, bb, block[ 2], 11);\n\tGG(bb, cc, dd, ee, aa, block[14],  7);\n\tGG(aa, bb, cc, dd, ee, block[11], 13);\n\tGG(ee, aa, bb, cc, dd, block[ 8], 12);\n\n\t/* round 3 */\n\tHH(dd, ee, aa, bb, cc, block[ 3], 11);\n\tHH(cc, dd, ee, aa, bb, block[10], 13);\n\tHH(bb, cc, dd, ee, aa, block[14],  6);\n\tHH(aa, bb, cc, dd, ee, block[ 4],  7);\n\tHH(ee, aa, bb, cc, dd, block[ 9], 14);\n\tHH(dd, ee, aa, bb, cc, block[15],  9);\n\tHH(cc, dd, ee, aa, bb, block[ 8], 13);\n\tHH(bb, cc, dd, ee, aa, block[ 1], 15);\n\tHH(aa, bb, cc, dd, ee, block[ 2], 14);\n\tHH(ee, aa, bb, cc, dd, block[ 7],  8);\n\tHH(dd, ee, aa, bb, cc, block[ 0], 13);\n\tHH(cc, dd, ee, aa, bb, block[ 6],  6);\n\tHH(bb, cc, dd, ee, aa, block[13],  5);\n\tHH(aa, bb, cc, dd, ee, block[11], 12);\n\tHH(ee, aa, bb, cc, dd, block[ 5],  7);\n\tHH(dd, ee, aa, bb, cc, block[12],  5);\n\n\t/* round 4 */\n\tII(cc, dd, ee, aa, bb, block[ 1], 11);\n\tII(bb, cc, dd, ee, aa, block[ 9], 12);\n\tII(aa, bb, cc, dd, ee, block[11], 14);\n\tII(ee, aa, bb, cc, dd, block[10], 15);\n\tII(dd, ee, aa, bb, cc, block[ 0], 14);\n\tII(cc, dd, ee, aa, bb, block[ 8], 15);\n\tII(bb, cc, dd, ee, aa, block[12],  9);\n\tII(aa, bb, cc, dd, ee, block[ 4],  8);\n\tII(ee, aa, bb, cc, dd, block[13],  9);\n\tII(dd, ee, aa, bb, cc, block[ 3], 14);\n\tII(cc, dd, ee, aa, bb, block[ 7],  5);\n\tII(bb, cc, dd, ee, aa, block[15],  6);\n\tII(aa, bb, cc, dd, ee, block[14],  8);\n\tII(ee, aa, bb, cc, dd, block[ 5],  6);\n\tII(dd, ee, aa, bb, cc, block[ 6],  5);\n\tII(cc, dd, ee, aa, bb, block[ 2], 12);\n\n\t/* round 5 */\n\tJJ(bb, cc, dd, ee, aa, block[ 4],  9);\n\tJJ(aa, bb, cc, dd, ee, block[ 0], 15);\n\tJJ(ee, aa, bb, cc, dd, block[ 5],  5);\n\tJJ(dd, ee, aa, bb, cc, block[ 9], 11);\n\tJJ(cc, dd, ee, aa, bb, block[ 7],  6);\n\tJJ(bb, cc, dd, ee, aa, block[12],  8);\n\tJJ(aa, bb, cc, dd, ee, block[ 2], 13);\n\tJJ(ee, aa, bb, cc, dd, block[10], 12);\n\tJJ(dd, ee, aa, bb, cc, block[14],  5);\n\tJJ(cc, dd, ee, aa, bb, block[ 1], 12);\n\tJJ(bb, cc, dd, ee, aa, block[ 3], 13);\n\tJJ(aa, bb, cc, dd, ee, block[ 8], 14);\n\tJJ(ee, aa, bb, cc, dd, block[11], 11);\n\tJJ(dd, ee, aa, bb, cc, block[ 6],  8);\n\tJJ(cc, dd, ee, aa, bb, block[15],  5);\n\tJJ(bb, cc, dd, ee, aa, block[13],  6);\n\n\t/* parallel round 1 */\n\tJJJ(aaa, bbb, ccc, ddd, eee, block[ 5],  8);\n\tJJJ(eee, aaa, bbb, ccc, ddd, block[14],  9);\n\tJJJ(ddd, eee, aaa, bbb, ccc, block[ 7],  9);\n\tJJJ(ccc, ddd, eee, aaa, bbb, block[ 0], 11);\n\tJJJ(bbb, ccc, ddd, eee, aaa, block[ 9], 13);\n\tJJJ(aaa, bbb, ccc, ddd, eee, block[ 2], 15);\n\tJJJ(eee, aaa, bbb, ccc, ddd, block[11], 15);\n\tJJJ(ddd, eee, aaa, bbb, ccc, block[ 4],  5);\n\tJJJ(ccc, ddd, eee, aaa, bbb, block[13],  7);\n\tJJJ(bbb, ccc, ddd, eee, aaa, block[ 6],  7);\n\tJJJ(aaa, bbb, ccc, ddd, eee, block[15],  8);\n\tJJJ(eee, aaa, bbb, ccc, ddd, block[ 8], 11);\n\tJJJ(ddd, eee, aaa, bbb, ccc, block[ 1], 14);\n\tJJJ(ccc, ddd, eee, aaa, bbb, block[10], 14);\n\tJJJ(bbb, ccc, ddd, eee, aaa, block[ 3], 12);\n\tJJJ(aaa, bbb, ccc, ddd, eee, block[12],  6);\n\n\t/* parallel round 2 */\n\tIII(eee, aaa, bbb, ccc, ddd, block[ 6],  9);\n\tIII(ddd, eee, aaa, bbb, ccc, block[11], 13);\n\tIII(ccc, ddd, eee, aaa, bbb, block[ 3], 15);\n\tIII(bbb, ccc, ddd, eee, aaa, block[ 7],  7);\n\tIII(aaa, bbb, ccc, ddd, eee, block[ 0], 12);\n\tIII(eee, aaa, bbb, ccc, ddd, block[13],  8);\n\tIII(ddd, eee, aaa, bbb, ccc, block[ 5],  9);\n\tIII(ccc, ddd, eee, aaa, bbb, block[10], 11);\n\tIII(bbb, ccc, ddd, eee, aaa, block[14],  7);\n\tIII(aaa, bbb, ccc, ddd, eee, block[15],  7);\n\tIII(eee, aaa, bbb, ccc, ddd, block[ 8], 12);\n\tIII(ddd, eee, aaa, bbb, ccc, block[12],  7);\n\tIII(ccc, ddd, eee, aaa, bbb, block[ 4],  6);\n\tIII(bbb, ccc, ddd, eee, aaa, block[ 9], 15);\n\tIII(aaa, bbb, ccc, ddd, eee, block[ 1], 13);\n\tIII(eee, aaa, bbb, ccc, ddd, block[ 2], 11);\n\n\t/* parallel round 3 */\n\tHHH(ddd, eee, aaa, bbb, ccc, block[15],  9);\n\tHHH(ccc, ddd, eee, aaa, bbb, block[ 5],  7);\n\tHHH(bbb, ccc, ddd, eee, aaa, block[ 1], 15);\n\tHHH(aaa, bbb, ccc, ddd, eee, block[ 3], 11);\n\tHHH(eee, aaa, bbb, ccc, ddd, block[ 7],  8);\n\tHHH(ddd, eee, aaa, bbb, ccc, block[14],  6);\n\tHHH(ccc, ddd, eee, aaa, bbb, block[ 6],  6);\n\tHHH(bbb, ccc, ddd, eee, aaa, block[ 9], 14);\n\tHHH(aaa, bbb, ccc, ddd, eee, block[11], 12);\n\tHHH(eee, aaa, bbb, ccc, ddd, block[ 8], 13);\n\tHHH(ddd, eee, aaa, bbb, ccc, block[12],  5);\n\tHHH(ccc, ddd, eee, aaa, bbb, block[ 2], 14);\n\tHHH(bbb, ccc, ddd, eee, aaa, block[10], 13);\n\tHHH(aaa, bbb, ccc, ddd, eee, block[ 0], 13);\n\tHHH(eee, aaa, bbb, ccc, ddd, block[ 4],  7);\n\tHHH(ddd, eee, aaa, bbb, ccc, block[13],  5);\n\n\t/* parallel round 4 */\n\tGGG(ccc, ddd, eee, aaa, bbb, block[ 8], 15);\n\tGGG(bbb, ccc, ddd, eee, aaa, block[ 6],  5);\n\tGGG(aaa, bbb, ccc, ddd, eee, block[ 4],  8);\n\tGGG(eee, aaa, bbb, ccc, ddd, block[ 1], 11);\n\tGGG(ddd, eee, aaa, bbb, ccc, block[ 3], 14);\n\tGGG(ccc, ddd, eee, aaa, bbb, block[11], 14);\n\tGGG(bbb, ccc, ddd, eee, aaa, block[15],  6);\n\tGGG(aaa, bbb, ccc, ddd, eee, block[ 0], 14);\n\tGGG(eee, aaa, bbb, ccc, ddd, block[ 5],  6);\n\tGGG(ddd, eee, aaa, bbb, ccc, block[12],  9);\n\tGGG(ccc, ddd, eee, aaa, bbb, block[ 2], 12);\n\tGGG(bbb, ccc, ddd, eee, aaa, block[13],  9);\n\tGGG(aaa, bbb, ccc, ddd, eee, block[ 9], 12);\n\tGGG(eee, aaa, bbb, ccc, ddd, block[ 7],  5);\n\tGGG(ddd, eee, aaa, bbb, ccc, block[10], 15);\n\tGGG(ccc, ddd, eee, aaa, bbb, block[14],  8);\n\n\t/* parallel round 5 */\n\tFFF(bbb, ccc, ddd, eee, aaa, block[12] ,  8);\n\tFFF(aaa, bbb, ccc, ddd, eee, block[15] ,  5);\n\tFFF(eee, aaa, bbb, ccc, ddd, block[10] , 12);\n\tFFF(ddd, eee, aaa, bbb, ccc, block[ 4] ,  9);\n\tFFF(ccc, ddd, eee, aaa, bbb, block[ 1] , 12);\n\tFFF(bbb, ccc, ddd, eee, aaa, block[ 5] ,  5);\n\tFFF(aaa, bbb, ccc, ddd, eee, block[ 8] , 14);\n\tFFF(eee, aaa, bbb, ccc, ddd, block[ 7] ,  6);\n\tFFF(ddd, eee, aaa, bbb, ccc, block[ 6] ,  8);\n\tFFF(ccc, ddd, eee, aaa, bbb, block[ 2] , 13);\n\tFFF(bbb, ccc, ddd, eee, aaa, block[13] ,  6);\n\tFFF(aaa, bbb, ccc, ddd, eee, block[14] ,  5);\n\tFFF(eee, aaa, bbb, ccc, ddd, block[ 0] , 15);\n\tFFF(ddd, eee, aaa, bbb, ccc, block[ 3] , 13);\n\tFFF(ccc, ddd, eee, aaa, bbb, block[ 9] , 11);\n\tFFF(bbb, ccc, ddd, eee, aaa, block[11] , 11);\n\n\t/* combine results */\n\tddd += cc + state[1];\t\t/* final result for state[0] */\n\tstate[1] = state[2] + dd + eee;\n\tstate[2] = state[3] + ee + aaa;\n\tstate[3] = state[4] + aa + bbb;\n\tstate[4] = state[0] + bb + ccc;\n\tstate[0] = ddd;\n}\n\n/********************************************************************/\n\nvoid\nRMD160_Update(RMD160_CTX *context, const uint8_t *data, size_t nbytes)\n{\n\tuint32_t X[16];\n\tuint32_t ofs = 0;\n\tuint32_t i;\n#ifdef WORDS_BIGENDIAN\n\tuint32_t j;\n#endif\n\n\t_DIAGASSERT(context != NULL);\n\t_DIAGASSERT(data != NULL);\n\n\t/* update length[] */\n\tif (context->length[0] + nbytes < context->length[0])\n\t\tcontext->length[1]++;\t\t/* overflow to msb of length */\n\tcontext->length[0] += nbytes;\n\n\t(void)memset(X, 0, sizeof(X));\n\n        if ( context->buflen + nbytes < 64 )\n        {\n                (void)memcpy(context->bbuffer + context->buflen, data, nbytes);\n                context->buflen += nbytes;\n        }\n        else\n        {\n                /* process first block */\n                ofs = 64 - context->buflen;\n                (void)memcpy(context->bbuffer + context->buflen, data, ofs);\n#ifndef WORDS_BIGENDIAN\n                (void)memcpy(X, context->bbuffer, sizeof(X));\n#else\n                for (j=0; j < 16; j++)\n                        X[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j));\n#endif\n                RMD160_Transform(context->state, X);\n                nbytes -= ofs;\n\n                /* process remaining complete blocks */\n                for (i = 0; i < (nbytes >> 6); i++) {\n#ifndef WORDS_BIGENDIAN\n                        (void)memcpy(X, data + (64 * i) + ofs, sizeof(X));\n#else\n                        for (j=0; j < 16; j++)\n                                X[j] = BYTES_TO_DWORD(data + (64 * i) + (4 * j) + ofs);\n#endif\n                        RMD160_Transform(context->state, X);\n                }\n\n                /*\n                 * Put last bytes from data into context's buffer\n                 */\n                context->buflen = nbytes & 63;\n                memcpy(context->bbuffer, data + (64 * i) + ofs, context->buflen);\n        }\n}\n\n/********************************************************************/\n\nvoid\nRMD160_Finish(RMD160_CTX *context, uint8_t digest[20])\n{\n\tuint32_t i;\n\tuint32_t X[16];\n#ifdef WORDS_BIGENDIAN\n\tuint32_t j;\n#endif\n\n\t_DIAGASSERT(digest != NULL);\n\t_DIAGASSERT(context != NULL);\n\n\t/* append the bit m_n == 1 */\n\tcontext->bbuffer[context->buflen] = (uint8_t)'\\200';\n\n\t(void)memset(context->bbuffer + context->buflen + 1, 0,\n\t\t63 - context->buflen);\n#ifndef WORDS_BIGENDIAN\n\t(void)memcpy(X, context->bbuffer, sizeof(X));\n#else\n\tfor (j=0; j < 16; j++)\n\t\tX[j] = BYTES_TO_DWORD(context->bbuffer + (4 * j));\n#endif\n\tif ((context->buflen) > 55) {\n\t\t/* length goes to next block */\n\t\tRMD160_Transform(context->state, X);\n\t\t(void)memset(X, 0, sizeof(X));\n\t}\n\n\t/* append length in bits */\n\tX[14] = context->length[0] << 3;\n\tX[15] = (context->length[0] >> 29) |\n\t    (context->length[1] << 3);\n\tRMD160_Transform(context->state, X);\n\n\tif (digest != NULL) {\n\t\tfor (i = 0; i < 20; i += 4) {\n\t\t\t/* extracts the 8 least significant bits. */\n\t\t\tdigest[i]     =  context->state[i>>2];\n\t\t\tdigest[i + 1] = (context->state[i>>2] >>  8);\n\t\t\tdigest[i + 2] = (context->state[i>>2] >> 16);\n\t\t\tdigest[i + 3] = (context->state[i>>2] >> 24);\n\t\t}\n\t}\n}\n\n/************************ end of file rmd160.c **********************/\n"
  },
  {
    "path": "ext/digest/rmd160/rmd160.h",
    "content": "/*\t$NetBSD: rmd160.h,v 1.2 2000/07/07 10:47:06 ad Exp $\t*/\n/*\t$RoughId: rmd160.h,v 1.3 2002/02/24 08:14:31 knu Exp $\t*/\n/*\t$Id$\t*/\n\n/********************************************************************\\\n *\n *      FILE:     rmd160.h\n *\n *      CONTENTS: Header file for a sample C-implementation of the\n *                RIPEMD-160 hash-function. \n *      TARGET:   any computer with an ANSI C compiler\n *\n *      AUTHOR:   Antoon Bosselaers, ESAT-COSIC\n *      DATE:     1 March 1996\n *      VERSION:  1.0\n *\n *      Copyright (c) Katholieke Universiteit Leuven\n *      1996, All Rights Reserved\n *\n\\********************************************************************/\n\n/*\n * from OpenBSD: rmd160.h,v 1.4 1999/08/16 09:59:04 millert Exp\n */\n\n#ifndef _RMD160_H_\n#define _RMD160_H_\n\n#include \"defs.h\"\n\ntypedef struct {\n\tuint32_t\tstate[5];\t/* state (ABCDE) */\n\tuint32_t\tlength[2];\t/* number of bits */\n\tuint8_t\t\tbbuffer[64];    /* overflow buffer */\n\tuint32_t\tbuflen;\t\t/* number of chars in bbuffer */\n} RMD160_CTX;\n\n#ifdef RUBY\n#define RMD160_Init\trb_Digest_RMD160_Init\n#define RMD160_Transform\trb_Digest_RMD160_Transform\n#define RMD160_Update\trb_Digest_RMD160_Update\n#define RMD160_Finish\trb_Digest_RMD160_Finish\n#endif\n\n__BEGIN_DECLS\nvoid\tRMD160_Init _((RMD160_CTX *));\nvoid\tRMD160_Transform _((uint32_t[5], const uint32_t[16]));\nvoid\tRMD160_Update _((RMD160_CTX *, const uint8_t *, size_t));\nvoid\tRMD160_Finish _((RMD160_CTX *, uint8_t[20]));\n__END_DECLS\n\n#define RMD160_BLOCK_LENGTH             64\n#define RMD160_DIGEST_LENGTH            20\n#define RMD160_DIGEST_STRING_LENGTH     (RMD160_DIGEST_LENGTH * 2 + 1)\n\n#endif  /* !_RMD160_H_ */\n"
  },
  {
    "path": "ext/digest/rmd160/rmd160init.c",
    "content": "/* $RoughId: rmd160init.c,v 1.3 2001/07/13 20:00:43 knu Exp $ */\n/* $Id$ */\n\n#include \"digest.h\"\n#if defined(HAVE_OPENSSL_RIPEMD_H)\n#include \"rmd160ossl.h\"\n#else\n#include \"rmd160.h\"\n#endif\n\nstatic rb_digest_metadata_t rmd160 = {\n    RUBY_DIGEST_API_VERSION,\n    RMD160_DIGEST_LENGTH,\n    RMD160_BLOCK_LENGTH,\n    sizeof(RMD160_CTX),\n    (rb_digest_hash_init_func_t)RMD160_Init,\n    (rb_digest_hash_update_func_t)RMD160_Update,\n    (rb_digest_hash_finish_func_t)RMD160_Finish,\n};\n\n/*\n * A class for calculating message digests using RIPEMD-160\n * cryptographic hash function, designed by Hans Dobbertin, Antoon\n * Bosselaers, and Bart Preneel.\n */\nvoid\nInit_rmd160()\n{\n    VALUE mDigest, cDigest_Base, cDigest_RMD160;\n\n    rb_require(\"digest\");\n\n    mDigest = rb_path2class(\"Digest\");\n    cDigest_Base = rb_path2class(\"Digest::Base\");\n\n    cDigest_RMD160 = rb_define_class_under(mDigest, \"RMD160\", cDigest_Base);\n\n    rb_ivar_set(cDigest_RMD160, rb_intern(\"metadata\"),\n      Data_Wrap_Struct(rb_cObject, 0, 0, &rmd160));\n}\n"
  },
  {
    "path": "ext/digest/rmd160/rmd160ossl.c",
    "content": "/* $Id$ */\n\n#include \"defs.h\"\n#include \"rmd160ossl.h\"\n\nvoid RMD160_Finish(RMD160_CTX *ctx, char *buf) {\n\tRIPEMD160_Final((unsigned char *)buf, ctx);\n}\n"
  },
  {
    "path": "ext/digest/rmd160/rmd160ossl.h",
    "content": "/* $Id$ */\n\n#ifndef RMD160OSSL_H_INCLUDED\n#define RMD160OSSL_H_INCLUDED\n\n#include <stddef.h>\n#include <openssl/ripemd.h>\n\n#define RMD160_CTX\tRIPEMD160_CTX\n\n#define RMD160_Init\tRIPEMD160_Init\n#define RMD160_Update\tRIPEMD160_Update\n\n#define RMD160_BLOCK_LENGTH\t\tRIPEMD160_CBLOCK\n#define RMD160_DIGEST_LENGTH\t\tRIPEMD160_DIGEST_LENGTH\n\nvoid RMD160_Finish(RMD160_CTX *ctx, char *buf);\n\n#endif\n"
  },
  {
    "path": "ext/digest/sha1/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/digest/sha1/depend",
    "content": "sha1.o: sha1.c sha1.h $(srcdir)/../defs.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h\nsha1init.o: sha1init.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h \\\n  sha1.h $(srcdir)/../defs.h\nsha1ossl.o: sha1ossl.h  $(srcdir)/../defs.h\n"
  },
  {
    "path": "ext/digest/sha1/extconf.rb",
    "content": "# $RoughId: extconf.rb,v 1.3 2001/08/14 19:54:51 knu Exp $\n# $Id$\n\nrequire \"mkmf\"\n\n$defs << \"-DHAVE_CONFIG_H\"\n$INCFLAGS << \" -I$(srcdir)/..\"\n\n$objs = [ \"sha1init.#{$OBJEXT}\" ]\n\ndir_config(\"openssl\")\n\nif !with_config(\"bundled-sha1\") &&\n    have_library(\"crypto\") && have_header(\"openssl/sha.h\")\n  $objs << \"sha1ossl.#{$OBJEXT}\"\nelse\n  $objs << \"sha1.#{$OBJEXT}\"\nend\n\nhave_header(\"sys/cdefs.h\")\n\nhave_header(\"inttypes.h\")\n\nhave_header(\"unistd.h\")\n\n$preload = %w[digest]\n\ncreate_makefile(\"digest/sha1\")\n"
  },
  {
    "path": "ext/digest/sha1/sha1.c",
    "content": "/*\t$NetBSD: sha1.c,v 1.2 2001/03/22 09:51:48 agc Exp $\t*/\n/*\t$OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $\t*/\n/*\t$RoughId: sha1.c,v 1.2 2001/07/13 19:49:10 knu Exp $\t*/\n/*\t$Id$\t*/\n\n/*\n * SHA-1 in C\n * By Steve Reid <steve@edmweb.com>\n * 100% Public Domain\n *\n * Test Vectors (from FIPS PUB 180-1)\n * \"abc\"\n *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n * \"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\n *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n * A million repetitions of \"a\"\n *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n */\n\n#include \"sha1.h\"\n\n#define SHA1HANDSOFF\t\t/* Copies data before messing with it. */\n\n#if defined(_KERNEL) || defined(_STANDALONE)\n#include <sys/param.h>\n#include <sys/systm.h>\n#define _DIAGASSERT(x)\t(void)0\n#else\n/* #include \"namespace.h\" */\n#include <assert.h>\n#include <string.h>\n#endif\n\n#ifndef _DIAGASSERT\n#define _DIAGASSERT(cond)\tassert(cond)\n#endif\n\n/*\n * XXX Kludge until there is resolution regarding mem*() functions\n * XXX in the kernel.\n */\n#if defined(_KERNEL) || defined(_STANDALONE)\n#define\tmemcpy(s, d, l)\t\tbcopy((d), (s), (l))\n#endif\n\n#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))\n\n/*\n * blk0() and blk() perform the initial expand.\n * I got the idea of expanding during the round function from SSLeay\n */\n#ifndef WORDS_BIGENDIAN\n# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \\\n    |(rol(block->l[i],8)&0x00FF00FF))\n#else\n# define blk0(i) block->l[i]\n#endif\n#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \\\n    ^block->l[(i+2)&15]^block->l[i&15],1))\n\n/*\n * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1\n */\n#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);\n#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);\n#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);\n#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);\n#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);\n\n\ntypedef union {\n    uint8_t c[64];\n    uint32_t l[16];\n} CHAR64LONG16;\n\n#ifdef __sparc_v9__\nvoid do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);\nvoid do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);\nvoid do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);\nvoid do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);\n\n#define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i)\n#define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i)\n#define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i)\n#define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i)\n#define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i)\n\nvoid\ndo_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)\n{\n    nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2); nR0(c,d,e,a,b, 3);\n    nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5); nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7);\n    nR0(c,d,e,a,b, 8); nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11);\n    nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14); nR0(a,b,c,d,e,15);\n    nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17); nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19);\n}\n\nvoid\ndo_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)\n{\n    nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22); nR2(c,d,e,a,b,23);\n    nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25); nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27);\n    nR2(c,d,e,a,b,28); nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31);\n    nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34); nR2(a,b,c,d,e,35);\n    nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37); nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39);\n}\n\nvoid\ndo_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)\n{\n    nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42); nR3(c,d,e,a,b,43);\n    nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45); nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47);\n    nR3(c,d,e,a,b,48); nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51);\n    nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54); nR3(a,b,c,d,e,55);\n    nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57); nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59);\n}\n\nvoid\ndo_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)\n{\n    nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62); nR4(c,d,e,a,b,63);\n    nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65); nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67);\n    nR4(c,d,e,a,b,68); nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71);\n    nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74); nR4(a,b,c,d,e,75);\n    nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77); nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79);\n}\n#endif\n\n/*\n * Hash a single 512-bit block. This is the core of the algorithm.\n */\nvoid SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])\n{\n    uint32_t a, b, c, d, e;\n    CHAR64LONG16 *block;\n\n#ifdef SHA1HANDSOFF\n    CHAR64LONG16 workspace;\n#endif\n\n    _DIAGASSERT(buffer != 0);\n    _DIAGASSERT(state != 0);\n\n#ifdef SHA1HANDSOFF\n    block = &workspace;\n    (void)memcpy(block, buffer, 64);\n#else\n    block = (CHAR64LONG16 *)(void *)buffer;\n#endif\n\n    /* Copy context->state[] to working vars */\n    a = state[0];\n    b = state[1];\n    c = state[2];\n    d = state[3];\n    e = state[4];\n\n#ifdef __sparc_v9__\n    do_R01(&a, &b, &c, &d, &e, block);\n    do_R2(&a, &b, &c, &d, &e, block);\n    do_R3(&a, &b, &c, &d, &e, block);\n    do_R4(&a, &b, &c, &d, &e, block);\n#else\n    /* 4 rounds of 20 operations each. Loop unrolled. */\n    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);\n    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);\n    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);\n    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);\n    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);\n    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);\n    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);\n    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);\n    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);\n    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);\n    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);\n    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);\n    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);\n    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);\n    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);\n    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);\n    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);\n    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);\n    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);\n    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);\n#endif\n\n    /* Add the working vars back into context.state[] */\n    state[0] += a;\n    state[1] += b;\n    state[2] += c;\n    state[3] += d;\n    state[4] += e;\n\n    /* Wipe variables */\n    a = b = c = d = e = 0;\n}\n\n\n/*\n * SHA1_Init - Initialize new context\n */\nvoid SHA1_Init(SHA1_CTX *context)\n{\n\n    _DIAGASSERT(context != 0);\n\n    /* SHA1 initialization constants */\n    context->state[0] = 0x67452301;\n    context->state[1] = 0xEFCDAB89;\n    context->state[2] = 0x98BADCFE;\n    context->state[3] = 0x10325476;\n    context->state[4] = 0xC3D2E1F0;\n    context->count[0] = context->count[1] = 0;\n}\n\n\n/*\n * Run your data through this.\n */\nvoid SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len)\n{\n    uint32_t i, j;\n\n    _DIAGASSERT(context != 0);\n    _DIAGASSERT(data != 0);\n\n    j = context->count[0];\n    if ((context->count[0] += len << 3) < j)\n\tcontext->count[1] += (len>>29)+1;\n    j = (j >> 3) & 63;\n    if ((j + len) > 63) {\n\t(void)memcpy(&context->buffer[j], data, (i = 64-j));\n\tSHA1_Transform(context->state, context->buffer);\n\tfor ( ; i + 63 < len; i += 64)\n\t    SHA1_Transform(context->state, &data[i]);\n\tj = 0;\n    } else {\n\ti = 0;\n    }\n    (void)memcpy(&context->buffer[j], &data[i], len - i);\n}\n\n\n/*\n * Add padding and return the message digest.\n */\nvoid SHA1_Finish(SHA1_CTX* context, uint8_t digest[20])\n{\n    size_t i;\n    uint8_t finalcount[8];\n\n    _DIAGASSERT(digest != 0);\n    _DIAGASSERT(context != 0);\n\n    for (i = 0; i < 8; i++) {\n\tfinalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)]\n\t >> ((3-(i & 3)) * 8) ) & 255);\t /* Endian independent */\n    }\n    SHA1_Update(context, (const uint8_t *)\"\\200\", 1);\n    while ((context->count[0] & 504) != 448)\n\tSHA1_Update(context, (const uint8_t *)\"\\0\", 1);\n    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1_Transform() */\n\n    if (digest) {\n\tfor (i = 0; i < 20; i++)\n\t    digest[i] = (uint8_t)\n\t\t((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);\n    }\n}\n"
  },
  {
    "path": "ext/digest/sha1/sha1.h",
    "content": "/*\t$NetBSD: sha1.h,v 1.2 1998/05/29 22:55:44 thorpej Exp $\t*/\n/*\t$RoughId: sha1.h,v 1.3 2002/02/24 08:14:32 knu Exp $\t*/\n/*\t$Id$\t*/\n\n/*\n * SHA-1 in C\n * By Steve Reid <steve@edmweb.com>\n * 100% Public Domain\n */\n\n#ifndef _SYS_SHA1_H_\n#define\t_SYS_SHA1_H_\n\n#include \"defs.h\"\n\ntypedef struct {\n\tuint32_t state[5];\n\tuint32_t count[2];  \n\tuint8_t buffer[64];\n} SHA1_CTX;\n\n#ifdef RUBY\n/* avoid name clash */\n#define SHA1_Transform\trb_Digest_SHA1_Transform\n#define SHA1_Init\trb_Digest_SHA1_Init\n#define SHA1_Update\trb_Digest_SHA1_Update\n#define SHA1_Finish\trb_Digest_SHA1_Finish\n#endif\n\nvoid\tSHA1_Transform _((uint32_t state[5], const uint8_t buffer[64]));\nvoid\tSHA1_Init _((SHA1_CTX *context));\nvoid\tSHA1_Update _((SHA1_CTX *context, const uint8_t *data, size_t len));\nvoid\tSHA1_Finish _((SHA1_CTX *context, uint8_t digest[20]));\n\n#define SHA1_BLOCK_LENGTH\t\t64\n#define SHA1_DIGEST_LENGTH\t\t20\n#define SHA1_DIGEST_STRING_LENGTH\t(SHA1_DIGEST_LENGTH * 2 + 1)\n  \n#endif /* _SYS_SHA1_H_ */\n"
  },
  {
    "path": "ext/digest/sha1/sha1init.c",
    "content": "/* $RoughId: sha1init.c,v 1.2 2001/07/13 19:49:10 knu Exp $ */\n/* $Id$ */\n\n#include \"digest.h\"\n#if defined(HAVE_OPENSSL_SHA_H)\n#include \"sha1ossl.h\"\n#else\n#include \"sha1.h\"\n#endif\n\nstatic rb_digest_metadata_t sha1 = {\n    RUBY_DIGEST_API_VERSION,\n    SHA1_DIGEST_LENGTH,\n    SHA1_BLOCK_LENGTH,\n    sizeof(SHA1_CTX),\n    (rb_digest_hash_init_func_t)SHA1_Init,\n    (rb_digest_hash_update_func_t)SHA1_Update,\n    (rb_digest_hash_finish_func_t)SHA1_Finish,\n};\n\n/*\n * A class for calculating message digests using the SHA-1 Secure Hash\n * Algorithm by NIST (the US' National Institute of Standards and\n * Technology), described in FIPS PUB 180-1.\n */\nvoid\nInit_sha1()\n{\n    VALUE mDigest, cDigest_Base, cDigest_SHA1;\n \n    rb_require(\"digest\");\n \n    mDigest = rb_path2class(\"Digest\");\n    cDigest_Base = rb_path2class(\"Digest::Base\");\n\n    cDigest_SHA1 = rb_define_class_under(mDigest, \"SHA1\", cDigest_Base);\n\n    rb_ivar_set(cDigest_SHA1, rb_intern(\"metadata\"),\n      Data_Wrap_Struct(rb_cObject, 0, 0, &sha1));\n}\n"
  },
  {
    "path": "ext/digest/sha1/sha1ossl.c",
    "content": "/* $Id$ */\n\n#include \"defs.h\"\n#include \"sha1ossl.h\"\n\nvoid\nSHA1_Finish(SHA1_CTX *ctx, char *buf)\n{\n\tSHA1_Final((unsigned char *)buf, ctx);\n}\n"
  },
  {
    "path": "ext/digest/sha1/sha1ossl.h",
    "content": "/* $Id$ */\n\n#ifndef SHA1OSSL_H_INCLUDED\n#define SHA1OSSL_H_INCLUDED\n\n#include <stddef.h>\n#include <openssl/sha.h>\n\n#define SHA1_CTX\tSHA_CTX\n\n#ifdef SHA_BLOCK_LENGTH\n#define SHA1_BLOCK_LENGTH\tSHA_BLOCK_LENGTH\n#else\n#define SHA1_BLOCK_LENGTH\tSHA_CBLOCK\n#endif\n#define SHA1_DIGEST_LENGTH\tSHA_DIGEST_LENGTH\n\nvoid SHA1_Finish(SHA1_CTX *ctx, char *buf);\n\n#endif\n"
  },
  {
    "path": "ext/digest/sha2/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/digest/sha2/depend",
    "content": "sha2.o: sha2.c sha2.h $(srcdir)/../defs.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h\nsha2init.o: sha2init.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \\\n  $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h \\\n  sha2.h $(srcdir)/../defs.h\n"
  },
  {
    "path": "ext/digest/sha2/extconf.rb",
    "content": "# $RoughId: extconf.rb,v 1.4 2001/08/14 19:54:51 knu Exp $\n# $Id$\n\nrequire \"mkmf\"\n\n$defs << \"-DHAVE_CONFIG_H\"\n$INCFLAGS << \" -I$(srcdir)/..\"\n\n$objs = [\n  \"sha2.#{$OBJEXT}\",\n  \"sha2init.#{$OBJEXT}\",\n]\n\nhave_header(\"sys/cdefs.h\")\n\nhave_header(\"inttypes.h\")\n\nhave_header(\"unistd.h\")\n\n$preload = %w[digest]\n\nif have_type(\"uint64_t\", \"defs.h\", $defs.join(' '))\n  create_makefile(\"digest/sha2\")\nend\n"
  },
  {
    "path": "ext/digest/sha2/lib/sha2.rb",
    "content": "#--\n# sha2.rb - defines Digest::SHA2 class which wraps up the SHA256,\n#           SHA384, and SHA512 classes.\n#++\n# Copyright (c) 2006 Akinori MUSHA <knu@iDaemons.org>\n#\n# All rights reserved.  You can redistribute and/or modify it under the same\n# terms as Ruby.\n#\n#   $Id$\n\nrequire 'digest'\n\nmodule Digest\n  #\n  # A meta digest provider class for SHA256, SHA384 and SHA512.\n  #\n  class SHA2 < Digest::Class\n    # call-seq:\n    #     Digest::SHA2.new(bitlen = 256) -> digest_obj\n    #\n    # Creates a new SHA2 hash object with a given bit length.\n    def initialize(bitlen = 256)\n      case bitlen\n      when 256\n        @sha2 = Digest::SHA256.new\n      when 384\n        @sha2 = Digest::SHA384.new\n      when 512\n        @sha2 = Digest::SHA512.new\n      else\n        raise ArgumentError, \"unsupported bit length: %s\" % bitlen.inspect\n      end\n      @bitlen = bitlen\n    end\n\n    # :nodoc:\n    def reset\n      @sha2.reset\n      self\n    end\n\n    # :nodoc:\n    def update(str)\n      @sha2.update(str)\n      self\n    end\n    alias << update\n\n    def finish\n      @sha2.digest!\n    end\n    private :finish\n\n    def block_length\n      @sha2.block_length\n    end\n\n    def digest_length\n      @sha2.digest_length\n    end\n\n    # :nodoc:\n    def initialize_copy(other)\n      @sha2 = other.instance_eval { @sha2.clone }\n    end\n\n    # :nodoc:\n    def inspect\n      \"#<%s:%d %s>\" % [self.class.name, @bitlen, hexdigest]\n    end\n  end\nend\n"
  },
  {
    "path": "ext/digest/sha2/sha2.c",
    "content": "/*\n * sha2.c\n *\n * Version 1.0.0beta1\n *\n * Written by Aaron D. Gifford <me@aarongifford.com>\n *\n * Copyright 2000 Aaron D. Gifford.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n */\n\n/* $RoughId: sha2.c,v 1.3 2002/02/26 22:03:36 knu Exp $ */\n/* $Id$ */\n\n#include \"sha2.h\"\n#include <stdio.h>\n#include <string.h>\t/* memcpy()/memset() or bcopy()/bzero() */\n#include <assert.h>\t/* assert() */\n\n/*\n * ASSERT NOTE:\n * Some sanity checking code is included using assert().  On my FreeBSD\n * system, this additional code can be removed by compiling with NDEBUG\n * defined.  Check your own systems manpage on assert() to see how to\n * compile WITHOUT the sanity checking code on your system.\n *\n * UNROLLED TRANSFORM LOOP NOTE:\n * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform\n * loop version for the hash transform rounds (defined using macros\n * later in this file).  Either define on the command line, for example:\n *\n *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c\n *\n * or define below:\n *\n *   #define SHA2_UNROLL_TRANSFORM\n *\n */\n\n\n/*** SHA-256/384/512 Machine Architecture Definitions *****************/\ntypedef uint8_t  sha2_byte;\t/* Exactly 1 byte */\ntypedef uint32_t sha2_word32;\t/* Exactly 4 bytes */\ntypedef uint64_t sha2_word64;\t/* Exactly 8 bytes */\n\n#if defined(__GNUC__) || defined(_HPUX_SOURCE) || defined(__IBMC__)\n#define ULL(number)\tnumber##ULL\n#else\n#define ULL(number)\t(uint64_t)(number)\n#endif\n\n\n/*** SHA-256/384/512 Various Length Definitions ***********************/\n/* NOTE: Most of these are in sha2.h */\n#define SHA256_SHORT_BLOCK_LENGTH\t(SHA256_BLOCK_LENGTH - 8)\n#define SHA384_SHORT_BLOCK_LENGTH\t(SHA384_BLOCK_LENGTH - 16)\n#define SHA512_SHORT_BLOCK_LENGTH\t(SHA512_BLOCK_LENGTH - 16)\n\n\n/*** ENDIAN REVERSAL MACROS *******************************************/\n#ifndef WORDS_BIGENDIAN\n#define REVERSE32(w,x)\t{ \\\n\tsha2_word32 tmp = (w); \\\n\ttmp = (tmp >> 16) | (tmp << 16); \\\n\t(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \\\n}\n#define REVERSE64(w,x)\t{ \\\n\tsha2_word64 tmp = (w); \\\n\ttmp = (tmp >> 32) | (tmp << 32); \\\n\ttmp = ((tmp & ULL(0xff00ff00ff00ff00)) >> 8) | \\\n\t      ((tmp & ULL(0x00ff00ff00ff00ff)) << 8); \\\n\t(x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \\\n\t      ((tmp & ULL(0x0000ffff0000ffff)) << 16); \\\n}\n#endif\n\n/*\n * Macro for incrementally adding the unsigned 64-bit integer n to the\n * unsigned 128-bit integer (represented using a two-element array of\n * 64-bit words):\n */\n#define ADDINC128(w,n)\t{ \\\n\t(w)[0] += (sha2_word64)(n); \\\n\tif ((w)[0] < (n)) { \\\n\t\t(w)[1]++; \\\n\t} \\\n}\n\n/*\n * Macros for copying blocks of memory and for zeroing out ranges\n * of memory.  Using these macros makes it easy to switch from\n * using memset()/memcpy() and using bzero()/bcopy().\n *\n * Please define either SHA2_USE_MEMSET_MEMCPY or define\n * SHA2_USE_BZERO_BCOPY depending on which function set you\n * choose to use:\n */\n#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)\n/* Default to memset()/memcpy() if no option is specified */\n#define\tSHA2_USE_MEMSET_MEMCPY\t1\n#endif\n#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)\n/* Abort with an error if BOTH options are defined */\n#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!\n#endif\n\n#ifdef SHA2_USE_MEMSET_MEMCPY\n#define MEMSET_BZERO(p,l)\tmemset((p), 0, (l))\n#define MEMCPY_BCOPY(d,s,l)\tmemcpy((d), (s), (l))\n#endif\n#ifdef SHA2_USE_BZERO_BCOPY\n#define MEMSET_BZERO(p,l)\tbzero((p), (l))\n#define MEMCPY_BCOPY(d,s,l)\tbcopy((s), (d), (l))\n#endif\n\n\n/*** THE SIX LOGICAL FUNCTIONS ****************************************/\n/*\n * Bit shifting and rotation (used by the six SHA-XYZ logical functions:\n *\n *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and\n *   S is a ROTATION) because the SHA-256/384/512 description document\n *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this\n *   same \"backwards\" definition.\n */\n/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */\n#define R(b,x) \t\t((x) >> (b))\n/* 32-bit Rotate-right (used in SHA-256): */\n#define S32(b,x)\t(((x) >> (b)) | ((x) << (32 - (b))))\n/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */\n#define S64(b,x)\t(((x) >> (b)) | ((x) << (64 - (b))))\n\n/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */\n#define Ch(x,y,z)\t(((x) & (y)) ^ ((~(x)) & (z)))\n#define Maj(x,y,z)\t(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))\n\n/* Four of six logical functions used in SHA-256: */\n#define Sigma0_256(x)\t(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))\n#define Sigma1_256(x)\t(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))\n#define sigma0_256(x)\t(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))\n#define sigma1_256(x)\t(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))\n\n/* Four of six logical functions used in SHA-384 and SHA-512: */\n#define Sigma0_512(x)\t(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))\n#define Sigma1_512(x)\t(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))\n#define sigma0_512(x)\t(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))\n#define sigma1_512(x)\t(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))\n\n/*** INTERNAL FUNCTION PROTOTYPES *************************************/\n/* NOTE: These should not be accessed directly from outside this\n * library -- they are intended for private internal visibility/use\n * only.\n */\nvoid SHA512_Last(SHA512_CTX*);\nvoid SHA256_Transform(SHA256_CTX*, const sha2_word32*);\nvoid SHA512_Transform(SHA512_CTX*, const sha2_word64*);\n\n\n/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/\n/* Hash constant words K for SHA-256: */\nconst static sha2_word32 K256[64] = {\n\t0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,\n\t0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,\n\t0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,\n\t0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,\n\t0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,\n\t0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,\n\t0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,\n\t0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,\n\t0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,\n\t0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,\n\t0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,\n\t0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,\n\t0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,\n\t0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,\n\t0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,\n\t0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL\n};\n\n/* Initial hash value H for SHA-256: */\nconst static sha2_word32 sha256_initial_hash_value[8] = {\n\t0x6a09e667UL,\n\t0xbb67ae85UL,\n\t0x3c6ef372UL,\n\t0xa54ff53aUL,\n\t0x510e527fUL,\n\t0x9b05688cUL,\n\t0x1f83d9abUL,\n\t0x5be0cd19UL\n};\n\n/* Hash constant words K for SHA-384 and SHA-512: */\nconst static sha2_word64 K512[80] = {\n\tULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd),\n\tULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc),\n\tULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019),\n\tULL(0x923f82a4af194f9b), ULL(0xab1c5ed5da6d8118),\n\tULL(0xd807aa98a3030242), ULL(0x12835b0145706fbe),\n\tULL(0x243185be4ee4b28c), ULL(0x550c7dc3d5ffb4e2),\n\tULL(0x72be5d74f27b896f), ULL(0x80deb1fe3b1696b1),\n\tULL(0x9bdc06a725c71235), ULL(0xc19bf174cf692694),\n\tULL(0xe49b69c19ef14ad2), ULL(0xefbe4786384f25e3),\n\tULL(0x0fc19dc68b8cd5b5), ULL(0x240ca1cc77ac9c65),\n\tULL(0x2de92c6f592b0275), ULL(0x4a7484aa6ea6e483),\n\tULL(0x5cb0a9dcbd41fbd4), ULL(0x76f988da831153b5),\n\tULL(0x983e5152ee66dfab), ULL(0xa831c66d2db43210),\n\tULL(0xb00327c898fb213f), ULL(0xbf597fc7beef0ee4),\n\tULL(0xc6e00bf33da88fc2), ULL(0xd5a79147930aa725),\n\tULL(0x06ca6351e003826f), ULL(0x142929670a0e6e70),\n\tULL(0x27b70a8546d22ffc), ULL(0x2e1b21385c26c926),\n\tULL(0x4d2c6dfc5ac42aed), ULL(0x53380d139d95b3df),\n\tULL(0x650a73548baf63de), ULL(0x766a0abb3c77b2a8),\n\tULL(0x81c2c92e47edaee6), ULL(0x92722c851482353b),\n\tULL(0xa2bfe8a14cf10364), ULL(0xa81a664bbc423001),\n\tULL(0xc24b8b70d0f89791), ULL(0xc76c51a30654be30),\n\tULL(0xd192e819d6ef5218), ULL(0xd69906245565a910),\n\tULL(0xf40e35855771202a), ULL(0x106aa07032bbd1b8),\n\tULL(0x19a4c116b8d2d0c8), ULL(0x1e376c085141ab53),\n\tULL(0x2748774cdf8eeb99), ULL(0x34b0bcb5e19b48a8),\n\tULL(0x391c0cb3c5c95a63), ULL(0x4ed8aa4ae3418acb),\n\tULL(0x5b9cca4f7763e373), ULL(0x682e6ff3d6b2b8a3),\n\tULL(0x748f82ee5defb2fc), ULL(0x78a5636f43172f60),\n\tULL(0x84c87814a1f0ab72), ULL(0x8cc702081a6439ec),\n\tULL(0x90befffa23631e28), ULL(0xa4506cebde82bde9),\n\tULL(0xbef9a3f7b2c67915), ULL(0xc67178f2e372532b),\n\tULL(0xca273eceea26619c), ULL(0xd186b8c721c0c207),\n\tULL(0xeada7dd6cde0eb1e), ULL(0xf57d4f7fee6ed178),\n\tULL(0x06f067aa72176fba), ULL(0x0a637dc5a2c898a6),\n\tULL(0x113f9804bef90dae), ULL(0x1b710b35131c471b),\n\tULL(0x28db77f523047d84), ULL(0x32caab7b40c72493),\n\tULL(0x3c9ebe0a15c9bebc), ULL(0x431d67c49c100d4c),\n\tULL(0x4cc5d4becb3e42b6), ULL(0x597f299cfc657e2a),\n\tULL(0x5fcb6fab3ad6faec), ULL(0x6c44198c4a475817)\n};\n\n/* Initial hash value H for SHA-384 */\nconst static sha2_word64 sha384_initial_hash_value[8] = {\n\tULL(0xcbbb9d5dc1059ed8),\n\tULL(0x629a292a367cd507),\n\tULL(0x9159015a3070dd17),\n\tULL(0x152fecd8f70e5939),\n\tULL(0x67332667ffc00b31),\n\tULL(0x8eb44a8768581511),\n\tULL(0xdb0c2e0d64f98fa7),\n\tULL(0x47b5481dbefa4fa4)\n};\n\n/* Initial hash value H for SHA-512 */\nconst static sha2_word64 sha512_initial_hash_value[8] = {\n\tULL(0x6a09e667f3bcc908),\n\tULL(0xbb67ae8584caa73b),\n\tULL(0x3c6ef372fe94f82b),\n\tULL(0xa54ff53a5f1d36f1),\n\tULL(0x510e527fade682d1),\n\tULL(0x9b05688c2b3e6c1f),\n\tULL(0x1f83d9abfb41bd6b),\n\tULL(0x5be0cd19137e2179)\n};\n\n\n/*** SHA-256: *********************************************************/\nvoid SHA256_Init(SHA256_CTX* context) {\n\tif (context == (SHA256_CTX*)0) {\n\t\treturn;\n\t}\n\tMEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);\n\tMEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);\n\tcontext->bitcount = 0;\n}\n\n#ifdef SHA2_UNROLL_TRANSFORM\n\n/* Unrolled SHA-256 round macros: */\n\n#ifndef WORDS_BIGENDIAN\n\n#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)\t\\\n\tREVERSE32(*data++, W256[j]); \\\n\tT1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \\\n             K256[j] + W256[j]; \\\n\t(d) += T1; \\\n\t(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \\\n\tj++\n\n\n#else\n\n#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)\t\\\n\tT1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \\\n\t     K256[j] + (W256[j] = *data++); \\\n\t(d) += T1; \\\n\t(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \\\n\tj++\n\n#endif\n\n#define ROUND256(a,b,c,d,e,f,g,h)\t\\\n\ts0 = W256[(j+1)&0x0f]; \\\n\ts0 = sigma0_256(s0); \\\n\ts1 = W256[(j+14)&0x0f]; \\\n\ts1 = sigma1_256(s1); \\\n\tT1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \\\n\t     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \\\n\t(d) += T1; \\\n\t(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \\\n\tj++\n\nvoid SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {\n\tsha2_word32\ta, b, c, d, e, f, g, h, s0, s1;\n\tsha2_word32\tT1, *W256;\n\tint\t\tj;\n\n\tW256 = (sha2_word32*)context->buffer;\n\n\t/* Initialize registers with the prev. intermediate value */\n\ta = context->state[0];\n\tb = context->state[1];\n\tc = context->state[2];\n\td = context->state[3];\n\te = context->state[4];\n\tf = context->state[5];\n\tg = context->state[6];\n\th = context->state[7];\n\n\tj = 0;\n\tdo {\n\t\t/* Rounds 0 to 15 (unrolled): */\n\t\tROUND256_0_TO_15(a,b,c,d,e,f,g,h);\n\t\tROUND256_0_TO_15(h,a,b,c,d,e,f,g);\n\t\tROUND256_0_TO_15(g,h,a,b,c,d,e,f);\n\t\tROUND256_0_TO_15(f,g,h,a,b,c,d,e);\n\t\tROUND256_0_TO_15(e,f,g,h,a,b,c,d);\n\t\tROUND256_0_TO_15(d,e,f,g,h,a,b,c);\n\t\tROUND256_0_TO_15(c,d,e,f,g,h,a,b);\n\t\tROUND256_0_TO_15(b,c,d,e,f,g,h,a);\n\t} while (j < 16);\n\n\t/* Now for the remaining rounds to 64: */\n\tdo {\n\t\tROUND256(a,b,c,d,e,f,g,h);\n\t\tROUND256(h,a,b,c,d,e,f,g);\n\t\tROUND256(g,h,a,b,c,d,e,f);\n\t\tROUND256(f,g,h,a,b,c,d,e);\n\t\tROUND256(e,f,g,h,a,b,c,d);\n\t\tROUND256(d,e,f,g,h,a,b,c);\n\t\tROUND256(c,d,e,f,g,h,a,b);\n\t\tROUND256(b,c,d,e,f,g,h,a);\n\t} while (j < 64);\n\n\t/* Compute the current intermediate hash value */\n\tcontext->state[0] += a;\n\tcontext->state[1] += b;\n\tcontext->state[2] += c;\n\tcontext->state[3] += d;\n\tcontext->state[4] += e;\n\tcontext->state[5] += f;\n\tcontext->state[6] += g;\n\tcontext->state[7] += h;\n\n\t/* Clean up */\n\ta = b = c = d = e = f = g = h = T1 = 0;\n}\n\n#else /* SHA2_UNROLL_TRANSFORM */\n\nvoid SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {\n\tsha2_word32\ta, b, c, d, e, f, g, h, s0, s1;\n\tsha2_word32\tT1, T2, *W256;\n\tint\t\tj;\n\n\tW256 = (sha2_word32*)context->buffer;\n\n\t/* Initialize registers with the prev. intermediate value */\n\ta = context->state[0];\n\tb = context->state[1];\n\tc = context->state[2];\n\td = context->state[3];\n\te = context->state[4];\n\tf = context->state[5];\n\tg = context->state[6];\n\th = context->state[7];\n\n\tj = 0;\n\tdo {\n#ifndef WORDS_BIGENDIAN\n\t\t/* Copy data while converting to host byte order */\n\t\tREVERSE32(*data++,W256[j]);\n\t\t/* Apply the SHA-256 compression function to update a..h */\n\t\tT1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];\n#else\n\t\t/* Apply the SHA-256 compression function to update a..h with copy */\n\t\tT1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);\n#endif\n\t\tT2 = Sigma0_256(a) + Maj(a, b, c);\n\t\th = g;\n\t\tg = f;\n\t\tf = e;\n\t\te = d + T1;\n\t\td = c;\n\t\tc = b;\n\t\tb = a;\n\t\ta = T1 + T2;\n\n\t\tj++;\n\t} while (j < 16);\n\n\tdo {\n\t\t/* Part of the message block expansion: */\n\t\ts0 = W256[(j+1)&0x0f];\n\t\ts0 = sigma0_256(s0);\n\t\ts1 = W256[(j+14)&0x0f];\t\n\t\ts1 = sigma1_256(s1);\n\n\t\t/* Apply the SHA-256 compression function to update a..h */\n\t\tT1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + \n\t\t     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);\n\t\tT2 = Sigma0_256(a) + Maj(a, b, c);\n\t\th = g;\n\t\tg = f;\n\t\tf = e;\n\t\te = d + T1;\n\t\td = c;\n\t\tc = b;\n\t\tb = a;\n\t\ta = T1 + T2;\n\n\t\tj++;\n\t} while (j < 64);\n\n\t/* Compute the current intermediate hash value */\n\tcontext->state[0] += a;\n\tcontext->state[1] += b;\n\tcontext->state[2] += c;\n\tcontext->state[3] += d;\n\tcontext->state[4] += e;\n\tcontext->state[5] += f;\n\tcontext->state[6] += g;\n\tcontext->state[7] += h;\n\n\t/* Clean up */\n\ta = b = c = d = e = f = g = h = T1 = T2 = 0;\n}\n\n#endif /* SHA2_UNROLL_TRANSFORM */\n\nvoid SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {\n\tunsigned int\tfreespace, usedspace;\n\n\tif (len == 0) {\n\t\t/* Calling with no data is valid - we do nothing */\n\t\treturn;\n\t}\n\n\t/* Sanity check: */\n\tassert(context != NULL && data != NULL);\n\n\tusedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;\n\tif (usedspace > 0) {\n\t\t/* Calculate how much free space is available in the buffer */\n\t\tfreespace = SHA256_BLOCK_LENGTH - usedspace;\n\n\t\tif (len >= freespace) {\n\t\t\t/* Fill the buffer completely and process it */\n\t\t\tMEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);\n\t\t\tcontext->bitcount += freespace << 3;\n\t\t\tlen -= freespace;\n\t\t\tdata += freespace;\n\t\t\tSHA256_Transform(context, (sha2_word32*)context->buffer);\n\t\t} else {\n\t\t\t/* The buffer is not yet full */\n\t\t\tMEMCPY_BCOPY(&context->buffer[usedspace], data, len);\n\t\t\tcontext->bitcount += len << 3;\n\t\t\t/* Clean up: */\n\t\t\tusedspace = freespace = 0;\n\t\t\treturn;\n\t\t}\n\t}\n\twhile (len >= SHA256_BLOCK_LENGTH) {\n\t\t/* Process as many complete blocks as we can */\n\t\tSHA256_Transform(context, (const sha2_word32*)data);\n\t\tcontext->bitcount += SHA256_BLOCK_LENGTH << 3;\n\t\tlen -= SHA256_BLOCK_LENGTH;\n\t\tdata += SHA256_BLOCK_LENGTH;\n\t}\n\tif (len > 0) {\n\t\t/* There's left-overs, so save 'em */\n\t\tMEMCPY_BCOPY(context->buffer, data, len);\n\t\tcontext->bitcount += len << 3;\n\t}\n\t/* Clean up: */\n\tusedspace = freespace = 0;\n}\n\nvoid SHA256_Finish(SHA256_CTX* context, sha2_byte digest[]) {\n\tsha2_word32\t*d = (sha2_word32*)digest;\n\tunsigned int\tusedspace;\n\n\t/* Sanity check: */\n\tassert(context != NULL);\n\n\t/* If no digest buffer is passed, we don't bother doing this: */\n\tif (digest != (sha2_byte*)0) {\n\t\tusedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;\n#ifndef WORDS_BIGENDIAN\n\t\t/* Convert FROM host byte order */\n\t\tREVERSE64(context->bitcount,context->bitcount);\n#endif\n\t\tif (usedspace > 0) {\n\t\t\t/* Begin padding with a 1 bit: */\n\t\t\tcontext->buffer[usedspace++] = 0x80;\n\n\t\t\tif (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {\n\t\t\t\t/* Set-up for the last transform: */\n\t\t\t\tMEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);\n\t\t\t} else {\n\t\t\t\tif (usedspace < SHA256_BLOCK_LENGTH) {\n\t\t\t\t\tMEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);\n\t\t\t\t}\n\t\t\t\t/* Do second-to-last transform: */\n\t\t\t\tSHA256_Transform(context, (sha2_word32*)context->buffer);\n\n\t\t\t\t/* And set-up for the last transform: */\n\t\t\t\tMEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Set-up for the last transform: */\n\t\t\tMEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);\n\n\t\t\t/* Begin padding with a 1 bit: */\n\t\t\t*context->buffer = 0x80;\n\t\t}\n\t\t/* Set the bit count: */\n\t\t*(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;\n\n\t\t/* Final transform: */\n\t\tSHA256_Transform(context, (sha2_word32*)context->buffer);\n\n#ifndef WORDS_BIGENDIAN\n\t\t{\n\t\t\t/* Convert TO host byte order */\n\t\t\tint\tj;\n\t\t\tfor (j = 0; j < 8; j++) {\n\t\t\t\tREVERSE32(context->state[j],context->state[j]);\n\t\t\t\t*d++ = context->state[j];\n\t\t\t}\n\t\t}\n#else\n\t\tMEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);\n#endif\n\t}\n\n\t/* Clean up state data: */\n\tMEMSET_BZERO(context, sizeof(SHA256_CTX));\n\tusedspace = 0;\n}\n\n/*** SHA-512: *********************************************************/\nvoid SHA512_Init(SHA512_CTX* context) {\n\tif (context == (SHA512_CTX*)0) {\n\t\treturn;\n\t}\n\tMEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);\n\tMEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);\n\tcontext->bitcount[0] = context->bitcount[1] =  0;\n}\n\n#ifdef SHA2_UNROLL_TRANSFORM\n\n/* Unrolled SHA-512 round macros: */\n#ifndef WORDS_BIGENDIAN\n\n#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)\t\\\n\tREVERSE64(*data++, W512[j]); \\\n\tT1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \\\n             K512[j] + W512[j]; \\\n\t(d) += T1, \\\n\t(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \\\n\tj++\n\n\n#else\n\n#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)\t\\\n\tT1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \\\n             K512[j] + (W512[j] = *data++); \\\n\t(d) += T1; \\\n\t(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \\\n\tj++\n\n#endif\n\n#define ROUND512(a,b,c,d,e,f,g,h)\t\\\n\ts0 = W512[(j+1)&0x0f]; \\\n\ts0 = sigma0_512(s0); \\\n\ts1 = W512[(j+14)&0x0f]; \\\n\ts1 = sigma1_512(s1); \\\n\tT1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \\\n             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \\\n\t(d) += T1; \\\n\t(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \\\n\tj++\n\nvoid SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {\n\tsha2_word64\ta, b, c, d, e, f, g, h, s0, s1;\n\tsha2_word64\tT1, *W512 = (sha2_word64*)context->buffer;\n\tint\t\tj;\n\n\t/* Initialize registers with the prev. intermediate value */\n\ta = context->state[0];\n\tb = context->state[1];\n\tc = context->state[2];\n\td = context->state[3];\n\te = context->state[4];\n\tf = context->state[5];\n\tg = context->state[6];\n\th = context->state[7];\n\n\tj = 0;\n\tdo {\n\t\tROUND512_0_TO_15(a,b,c,d,e,f,g,h);\n\t\tROUND512_0_TO_15(h,a,b,c,d,e,f,g);\n\t\tROUND512_0_TO_15(g,h,a,b,c,d,e,f);\n\t\tROUND512_0_TO_15(f,g,h,a,b,c,d,e);\n\t\tROUND512_0_TO_15(e,f,g,h,a,b,c,d);\n\t\tROUND512_0_TO_15(d,e,f,g,h,a,b,c);\n\t\tROUND512_0_TO_15(c,d,e,f,g,h,a,b);\n\t\tROUND512_0_TO_15(b,c,d,e,f,g,h,a);\n\t} while (j < 16);\n\n\t/* Now for the remaining rounds up to 79: */\n\tdo {\n\t\tROUND512(a,b,c,d,e,f,g,h);\n\t\tROUND512(h,a,b,c,d,e,f,g);\n\t\tROUND512(g,h,a,b,c,d,e,f);\n\t\tROUND512(f,g,h,a,b,c,d,e);\n\t\tROUND512(e,f,g,h,a,b,c,d);\n\t\tROUND512(d,e,f,g,h,a,b,c);\n\t\tROUND512(c,d,e,f,g,h,a,b);\n\t\tROUND512(b,c,d,e,f,g,h,a);\n\t} while (j < 80);\n\n\t/* Compute the current intermediate hash value */\n\tcontext->state[0] += a;\n\tcontext->state[1] += b;\n\tcontext->state[2] += c;\n\tcontext->state[3] += d;\n\tcontext->state[4] += e;\n\tcontext->state[5] += f;\n\tcontext->state[6] += g;\n\tcontext->state[7] += h;\n\n\t/* Clean up */\n\ta = b = c = d = e = f = g = h = T1 = 0;\n}\n\n#else /* SHA2_UNROLL_TRANSFORM */\n\nvoid SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {\n\tsha2_word64\ta, b, c, d, e, f, g, h, s0, s1;\n\tsha2_word64\tT1, T2, *W512 = (sha2_word64*)context->buffer;\n\tint\t\tj;\n\n\t/* Initialize registers with the prev. intermediate value */\n\ta = context->state[0];\n\tb = context->state[1];\n\tc = context->state[2];\n\td = context->state[3];\n\te = context->state[4];\n\tf = context->state[5];\n\tg = context->state[6];\n\th = context->state[7];\n\n\tj = 0;\n\tdo {\n#ifndef WORDS_BIGENDIAN\n\t\t/* Convert TO host byte order */\n\t\tREVERSE64(*data++, W512[j]);\n\t\t/* Apply the SHA-512 compression function to update a..h */\n\t\tT1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];\n#else\n\t\t/* Apply the SHA-512 compression function to update a..h with copy */\n\t\tT1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);\n#endif\n\t\tT2 = Sigma0_512(a) + Maj(a, b, c);\n\t\th = g;\n\t\tg = f;\n\t\tf = e;\n\t\te = d + T1;\n\t\td = c;\n\t\tc = b;\n\t\tb = a;\n\t\ta = T1 + T2;\n\n\t\tj++;\n\t} while (j < 16);\n\n\tdo {\n\t\t/* Part of the message block expansion: */\n\t\ts0 = W512[(j+1)&0x0f];\n\t\ts0 = sigma0_512(s0);\n\t\ts1 = W512[(j+14)&0x0f];\n\t\ts1 =  sigma1_512(s1);\n\n\t\t/* Apply the SHA-512 compression function to update a..h */\n\t\tT1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +\n\t\t     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);\n\t\tT2 = Sigma0_512(a) + Maj(a, b, c);\n\t\th = g;\n\t\tg = f;\n\t\tf = e;\n\t\te = d + T1;\n\t\td = c;\n\t\tc = b;\n\t\tb = a;\n\t\ta = T1 + T2;\n\n\t\tj++;\n\t} while (j < 80);\n\n\t/* Compute the current intermediate hash value */\n\tcontext->state[0] += a;\n\tcontext->state[1] += b;\n\tcontext->state[2] += c;\n\tcontext->state[3] += d;\n\tcontext->state[4] += e;\n\tcontext->state[5] += f;\n\tcontext->state[6] += g;\n\tcontext->state[7] += h;\n\n\t/* Clean up */\n\ta = b = c = d = e = f = g = h = T1 = T2 = 0;\n}\n\n#endif /* SHA2_UNROLL_TRANSFORM */\n\nvoid SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {\n\tunsigned int\tfreespace, usedspace;\n\n\tif (len == 0) {\n\t\t/* Calling with no data is valid - we do nothing */\n\t\treturn;\n\t}\n\n\t/* Sanity check: */\n\tassert(context != NULL && data != NULL);\n\n\tusedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;\n\tif (usedspace > 0) {\n\t\t/* Calculate how much free space is available in the buffer */\n\t\tfreespace = SHA512_BLOCK_LENGTH - usedspace;\n\n\t\tif (len >= freespace) {\n\t\t\t/* Fill the buffer completely and process it */\n\t\t\tMEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);\n\t\t\tADDINC128(context->bitcount, freespace << 3);\n\t\t\tlen -= freespace;\n\t\t\tdata += freespace;\n\t\t\tSHA512_Transform(context, (const sha2_word64*)context->buffer);\n\t\t} else {\n\t\t\t/* The buffer is not yet full */\n\t\t\tMEMCPY_BCOPY(&context->buffer[usedspace], data, len);\n\t\t\tADDINC128(context->bitcount, len << 3);\n\t\t\t/* Clean up: */\n\t\t\tusedspace = freespace = 0;\n\t\t\treturn;\n\t\t}\n\t}\n\twhile (len >= SHA512_BLOCK_LENGTH) {\n\t\t/* Process as many complete blocks as we can */\n\t\tSHA512_Transform(context, (const sha2_word64*)data);\n\t\tADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);\n\t\tlen -= SHA512_BLOCK_LENGTH;\n\t\tdata += SHA512_BLOCK_LENGTH;\n\t}\n\tif (len > 0) {\n\t\t/* There's left-overs, so save 'em */\n\t\tMEMCPY_BCOPY(context->buffer, data, len);\n\t\tADDINC128(context->bitcount, len << 3);\n\t}\n\t/* Clean up: */\n\tusedspace = freespace = 0;\n}\n\nvoid SHA512_Last(SHA512_CTX* context) {\n\tunsigned int\tusedspace;\n\n\tusedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;\n#ifndef WORDS_BIGENDIAN\n\t/* Convert FROM host byte order */\n\tREVERSE64(context->bitcount[0],context->bitcount[0]);\n\tREVERSE64(context->bitcount[1],context->bitcount[1]);\n#endif\n\tif (usedspace > 0) {\n\t\t/* Begin padding with a 1 bit: */\n\t\tcontext->buffer[usedspace++] = 0x80;\n\n\t\tif (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {\n\t\t\t/* Set-up for the last transform: */\n\t\t\tMEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);\n\t\t} else {\n\t\t\tif (usedspace < SHA512_BLOCK_LENGTH) {\n\t\t\t\tMEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);\n\t\t\t}\n\t\t\t/* Do second-to-last transform: */\n\t\t\tSHA512_Transform(context, (const sha2_word64*)context->buffer);\n\n\t\t\t/* And set-up for the last transform: */\n\t\t\tMEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);\n\t\t}\n\t} else {\n\t\t/* Prepare for final transform: */\n\t\tMEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);\n\n\t\t/* Begin padding with a 1 bit: */\n\t\t*context->buffer = 0x80;\n\t}\n\t/* Store the length of input data (in bits): */\n\t*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];\n\t*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];\n\n\t/* Final transform: */\n\tSHA512_Transform(context, (const sha2_word64*)context->buffer);\n}\n\nvoid SHA512_Finish(SHA512_CTX* context, sha2_byte digest[]) {\n\tsha2_word64\t*d = (sha2_word64*)digest;\n\n\t/* Sanity check: */\n\tassert(context != NULL);\n\n\t/* If no digest buffer is passed, we don't bother doing this: */\n\tif (digest != (sha2_byte*)0) {\n\t\tSHA512_Last(context);\n\n\t\t/* Save the hash data for output: */\n#ifndef WORDS_BIGENDIAN\n\t\t{\n\t\t\t/* Convert TO host byte order */\n\t\t\tint\tj;\n\t\t\tfor (j = 0; j < 8; j++) {\n\t\t\t\tREVERSE64(context->state[j],context->state[j]);\n\t\t\t\t*d++ = context->state[j];\n\t\t\t}\n\t\t}\n#else\n\t\tMEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);\n#endif\n\t}\n\n\t/* Zero out state data */\n\tMEMSET_BZERO(context, sizeof(SHA512_CTX));\n}\n\n/*** SHA-384: *********************************************************/\nvoid SHA384_Init(SHA384_CTX* context) {\n\tif (context == (SHA384_CTX*)0) {\n\t\treturn;\n\t}\n\tMEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);\n\tMEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);\n\tcontext->bitcount[0] = context->bitcount[1] = 0;\n}\n\nvoid SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {\n\tSHA512_Update((SHA512_CTX*)context, data, len);\n}\n\nvoid SHA384_Finish(SHA384_CTX* context, sha2_byte digest[]) {\n\tsha2_word64\t*d = (sha2_word64*)digest;\n\n\t/* Sanity check: */\n\tassert(context != NULL);\n\n\t/* If no digest buffer is passed, we don't bother doing this: */\n\tif (digest != (sha2_byte*)0) {\n\t\tSHA512_Last((SHA512_CTX*)context);\n\n\t\t/* Save the hash data for output: */\n#ifndef WORDS_BIGENDIAN\n\t\t{\n\t\t\t/* Convert TO host byte order */\n\t\t\tint\tj;\n\t\t\tfor (j = 0; j < 6; j++) {\n\t\t\t\tREVERSE64(context->state[j],context->state[j]);\n\t\t\t\t*d++ = context->state[j];\n\t\t\t}\n\t\t}\n#else\n\t\tMEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);\n#endif\n\t}\n\n\t/* Zero out state data */\n\tMEMSET_BZERO(context, sizeof(SHA384_CTX));\n}\n"
  },
  {
    "path": "ext/digest/sha2/sha2.h",
    "content": "/*\n * sha2.h\n *\n * Version 1.0.0beta1\n *\n * Written by Aaron D. Gifford <me@aarongifford.com>\n *\n * Copyright 2000 Aaron D. Gifford.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n */\n\n/* $RoughId: sha2.h,v 1.3 2002/02/24 08:14:32 knu Exp $ */\n/* $Id$ */\n\n#ifndef __SHA2_H__\n#define __SHA2_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"defs.h\"\n\n\n/*** SHA-256/384/512 Various Length Definitions ***********************/\n#define SHA256_BLOCK_LENGTH\t\t64\n#define SHA256_DIGEST_LENGTH\t\t32\n#define SHA256_DIGEST_STRING_LENGTH\t(SHA256_DIGEST_LENGTH * 2 + 1)\n#define SHA384_BLOCK_LENGTH\t\t128\n#define SHA384_DIGEST_LENGTH\t\t48\n#define SHA384_DIGEST_STRING_LENGTH\t(SHA384_DIGEST_LENGTH * 2 + 1)\n#define SHA512_BLOCK_LENGTH\t\t128\n#define SHA512_DIGEST_LENGTH\t\t64\n#define SHA512_DIGEST_STRING_LENGTH\t(SHA512_DIGEST_LENGTH * 2 + 1)\n\n\n/*** SHA-256/384/512 Context Structures *******************************/\n\ntypedef struct _SHA256_CTX {\n\tuint32_t\tstate[8];\n\tuint64_t\tbitcount;\n\tuint8_t\tbuffer[SHA256_BLOCK_LENGTH];\n} SHA256_CTX;\ntypedef struct _SHA512_CTX {\n\tuint64_t\tstate[8];\n\tuint64_t\tbitcount[2];\n\tuint8_t\tbuffer[SHA512_BLOCK_LENGTH];\n} SHA512_CTX;\n\ntypedef SHA512_CTX SHA384_CTX;\n\n\n#ifdef RUBY\n#define SHA256_Init\t\trb_Digest_SHA256_Init\n#define SHA256_Update\t\trb_Digest_SHA256_Update\n#define SHA256_Finish\t\trb_Digest_SHA256_Finish\n\n#define SHA384_Init\t\trb_Digest_SHA384_Init\n#define SHA384_Update\t\trb_Digest_SHA384_Update\n#define SHA384_Finish\t\trb_Digest_SHA384_Finish\n\n#define SHA512_Init\t\trb_Digest_SHA512_Init\n#define SHA512_Update\t\trb_Digest_SHA512_Update\n#define SHA512_Finish\t\trb_Digest_SHA512_Finish\n#endif\n\n/*** SHA-256/384/512 Function Prototypes ******************************/\nvoid SHA256_Init _((SHA256_CTX *));\nvoid SHA256_Update _((SHA256_CTX*, const uint8_t*, size_t));\nvoid SHA256_Finish _((SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]));\n\nvoid SHA384_Init _((SHA384_CTX*));\nvoid SHA384_Update _((SHA384_CTX*, const uint8_t*, size_t));\nvoid SHA384_Finish _((SHA384_CTX*, uint8_t[SHA384_DIGEST_LENGTH]));\n\nvoid SHA512_Init _((SHA512_CTX*));\nvoid SHA512_Update _((SHA512_CTX*, const uint8_t*, size_t));\nvoid SHA512_Finish _((SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]));\n\n#ifdef\t__cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* __SHA2_H__ */\n\n"
  },
  {
    "path": "ext/digest/sha2/sha2init.c",
    "content": "/* $RoughId: sha2init.c,v 1.3 2001/07/13 20:00:43 knu Exp $ */\n/* $Id$ */\n\n#include \"digest.h\"\n#include \"sha2.h\"\n\n#define FOREACH_BITLEN(func)\tfunc(256) func(384) func(512)\n\n#define DEFINE_ALGO_METADATA(bitlen) \\\nstatic rb_digest_metadata_t sha##bitlen = { \\\n    RUBY_DIGEST_API_VERSION, \\\n    SHA##bitlen##_DIGEST_LENGTH, \\\n    SHA##bitlen##_BLOCK_LENGTH, \\\n    sizeof(SHA##bitlen##_CTX), \\\n    (rb_digest_hash_init_func_t)SHA##bitlen##_Init, \\\n    (rb_digest_hash_update_func_t)SHA##bitlen##_Update, \\\n    (rb_digest_hash_finish_func_t)SHA##bitlen##_Finish, \\\n};\n\nFOREACH_BITLEN(DEFINE_ALGO_METADATA)\n\n/*\n * Classes for calculating message digests using the SHA-256/384/512\n * Secure Hash Algorithm(s) by NIST (the US' National Institute of\n * Standards and Technology), described in FIPS PUB 180-2.\n */\nvoid\nInit_sha2()\n{\n    VALUE mDigest, cDigest_Base;\n    ID id_metadata;\n\n#define DECLARE_ALGO_CLASS(bitlen) \\\n    VALUE cDigest_SHA##bitlen;\n\n    FOREACH_BITLEN(DECLARE_ALGO_CLASS)\n\n    rb_require(\"digest\");\n\n    id_metadata = rb_intern(\"metadata\");\n\n    mDigest = rb_path2class(\"Digest\");\n    cDigest_Base = rb_path2class(\"Digest::Base\");\n\n#define DEFINE_ALGO_CLASS(bitlen) \\\n    cDigest_SHA##bitlen = rb_define_class_under(mDigest, \"SHA\" #bitlen, cDigest_Base); \\\n\\\n    rb_ivar_set(cDigest_SHA##bitlen, id_metadata, \\\n      Data_Wrap_Struct(rb_cObject, 0, 0, &sha##bitlen));\n\n    FOREACH_BITLEN(DEFINE_ALGO_CLASS)\n}\n"
  },
  {
    "path": "ext/digest/test.sh",
    "content": "#!/bin/sh\n#\n# $RoughId: test.sh,v 1.5 2001/07/13 15:38:27 knu Exp $\n# $Id$\n\nRUBY=${RUBY:=ruby}\nMAKE=${MAKE:=make}\nCFLAGS=${CFLAGS:=-Wall}\n\n${RUBY} extconf.rb --with-cflags=\"${CFLAGS}\"\n${MAKE} clean\n${MAKE}\n\nfor algo in md5 rmd160 sha1 sha2; do\n    args=--with-cflags=\"${CFLAGS}\"\n\n    if [ $WITH_BUNDLED_ENGINES ]; then\n\targs=\"$args --with-bundled-$algo\"\n    fi\n\n    (cd $algo &&\n\t${RUBY} extconf.rb $args;\n\t${MAKE} clean;\n\t${MAKE})\n    ln -sf ../../$algo/$algo.so lib/digest/\ndone\n\n${RUBY} -I. -I./lib ../../test/digest/test_digest.rb\n\nrm lib/digest/*.so\n"
  },
  {
    "path": "ext/dl/.cvsignore",
    "content": "Makefile\nmkmf.log\ndlconfig.h\ndlconfig.rb\n*.func\n*.o\n*~\n*.def\n"
  },
  {
    "path": "ext/dl/depend",
    "content": "LDSHARED_TEST = $(LDSHARED) $(LDFLAGS) test/test.o -o test/libtest.so $(LOCAL_LIBS)\n\nlibtest.so: test/libtest.so\n\ntest/libtest.so: test/test.o $(srcdir)/test/libtest.def\n\t$(RUBY) -rftools -e 'ARGV.each do|d|File.mkpath(File.dirname(d))end' $@\n\t$(LDSHARED_TEST:dl.def=test/libtest.def)\n\ntest/test.o: $(srcdir)/test/test.c\n\t@$(RUBY) -rftools -e 'File.mkpath(*ARGV)' test\n\t$(CC) $(CFLAGS) $(CPPFLAGS) -c $(srcdir)/test/test.c -o $@\n\ntest:: dl.so libtest.so force\n\t$(RUBY) -I. -I$(srcdir)/lib $(srcdir)/test/test.rb\n\nforce:\n\n.PHONY: force test\n\nallclean: distclean\n\t@rm -f $(CLEANFILES) $(DISTCLEANFILES)\n\n$(OBJS): ./dlconfig.h\n\nsym.o: dl.h call.func\n\ndl.o: dl.h callback.func cbtable.func\n\nptr.o: dl.h\n\nhandle.o: dl.h\n\ncall.func: $(srcdir)/mkcall.rb ./dlconfig.rb\n\t@echo \"Generating call.func\"\n\t@$(RUBY) $(srcdir)/mkcall.rb > $@\n\ncallback.func: $(srcdir)/mkcallback.rb ./dlconfig.rb\n\t@echo \"Generating callback.func\"\n\t@$(RUBY) $(srcdir)/mkcallback.rb > $@\n\ncbtable.func: $(srcdir)/mkcbtable.rb ./dlconfig.rb\n\t@echo \"Generating cbtable.func\"\n\t@$(RUBY) $(srcdir)/mkcbtable.rb > $@\n\ndebug:\n\t$(MAKE) CPPFLAGS=\"$(CPPFLAGS) -DDEBUG\"\n"
  },
  {
    "path": "ext/dl/dl.c",
    "content": "/*\n * $Id$\n */\n\n#include <ruby.h>\n#include <rubyio.h>\n#include <ctype.h>\n#include \"dl.h\"\n\nVALUE rb_mDL;\nVALUE rb_eDLError;\nVALUE rb_eDLTypeError;\n\nstatic VALUE DLFuncTable;\nstatic void *rb_dl_callback_table[CALLBACK_TYPES][MAX_CALLBACK];\nstatic ID id_call;\n\nstatic int\nrb_dl_scan_callback_args(long stack[], const char *proto,\n\t\t\t int *argc, VALUE argv[])\n{\n  int i;\n  long *sp;\n  VALUE val;\n\n  sp = stack;\n  for (i=1; proto[i]; i++) {\n    switch (proto[i]) {\n    case 'C':\n      {\n\tchar v;\n\tv = (char)(*sp);\n\tsp++;\n\tval = INT2NUM(v);\n      }\n      break;\n    case 'H':\n      {\n\tshort v;\n\tv = (short)(*sp);\n\tsp++;\n\tval = INT2NUM(v);\n      }\n      break;\n    case 'I':\n      {\n\tint v;\n\tv = (int)(*sp);\n\tsp++;\n\tval = INT2NUM(v);\n      }\n      break;\n    case 'L':\n      {\n\tlong v;\n\tv = (long)(*sp);\n\tsp++;\n\tval = INT2NUM(v);\n      }\n      break;\n    case 'F':\n      {\n\tfloat v;\n\tmemcpy(&v, sp, sizeof(float));\n\tsp += sizeof(float)/sizeof(long);\n\tval = rb_float_new(v);\n      }\n      break;\n    case 'D':\n      {\n\tdouble v;\n\tmemcpy(&v, sp, sizeof(double));\n\tsp += sizeof(double)/sizeof(long);\n\tval = rb_float_new(v);\n      }\n      break;\n    case 'P':\n      {\n\tvoid *v;\n\tmemcpy(&v, sp, sizeof(void*));\n\tsp++;\n\tval = rb_dlptr_new(v, 0, 0);\n      }\n      break;\n    case 'S':\n      {\n\tchar *v;\n\tmemcpy(&v, sp, sizeof(void*));\n\tsp++;\n\tval = rb_tainted_str_new2(v);\n      }\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unsupported type `%c'\", proto[i]);\n      break;\n    }\n    argv[i-1] = val;\n  }\n  *argc = (i - 1);\n\n  return (*argc);\n}\n\n#include \"callback.func\"\n\nstatic void\ninit_dl_func_table(){\n#include \"cbtable.func\"\n}\n\nvoid *\ndlmalloc(size_t size)\n{\n  DEBUG_CODE2({\n    void *ptr;\n\n    printf(\"dlmalloc(%d)\",size);\n    ptr = xmalloc(size);\n    printf(\":0x%x\\n\",ptr);\n    return ptr;\n  },\n  {\n    return xmalloc(size);\n  });\n}\n\nvoid *\ndlrealloc(void *ptr, size_t size)\n{\n  DEBUG_CODE({\n    printf(\"dlrealloc(0x%x,%d)\\n\",ptr,size);\n  });\n  return xrealloc(ptr, size);\n}\n\nvoid\ndlfree(void *ptr)\n{\n  DEBUG_CODE({\n    printf(\"dlfree(0x%x)\\n\",ptr);\n  });\n  xfree(ptr);\n}\n\nchar*\ndlstrdup(const char *str)\n{\n  char *newstr;\n\n  newstr = (char*)dlmalloc(strlen(str)+1);\n  strcpy(newstr,str);\n\n  return newstr;\n}\n\nsize_t\ndlsizeof(const char *cstr)\n{\n  size_t size;\n  int i, len, n, dlen;\n  char *d;\n\n  len  = strlen(cstr);\n  size = 0;\n  for (i=0; i<len; i++) {\n    n = 1;\n    if (isdigit(cstr[i+1])) {\n      dlen = 1;\n      while (isdigit(cstr[i+dlen])) { dlen ++; };\n      dlen --;\n      d = ALLOCA_N(char, dlen + 1);\n      strncpy(d, cstr + i + 1, dlen);\n      d[dlen] = '\\0';\n      n = atoi(d);\n    }\n    else{\n      dlen = 0;\n    }\n\n    switch (cstr[i]) {\n    case 'I':\n      DLALIGN(0,size,INT_ALIGN);\n    case 'i':\n      size += sizeof(int) * n;\n      break;\n    case 'L':\n      DLALIGN(0,size,LONG_ALIGN);\n    case 'l':\n      size += sizeof(long) * n;\n      break;\n    case 'F':\n      DLALIGN(0,size,FLOAT_ALIGN);\n    case 'f':\n      size += sizeof(float) * n;\n      break;\n    case 'D':\n      DLALIGN(0,size,DOUBLE_ALIGN);\n    case 'd':\n      size += sizeof(double) * n;\n      break;\n    case 'C':\n    case 'c':\n      size += sizeof(char) * n;\n      break;\n    case 'H':\n      DLALIGN(0,size,SHORT_ALIGN);\n    case 'h':\n      size += sizeof(short) * n;\n      break;\n    case 'P':\n    case 'S':\n      DLALIGN(0,size,VOIDP_ALIGN);\n    case 'p':\n    case 's':\n      size += sizeof(void*) * n;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type '%c'\", cstr[i]);\n      break;\n    }\n    i += dlen;\n  }\n\n  return size;\n}\n\nstatic float *\nc_farray(VALUE v, long *size)\n{\n  int i, len;\n  float *ary;\n  VALUE e;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(float) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    case T_FLOAT:\n      ary[i] = (float)(RFLOAT(e)->value);\n      break;\n    case T_NIL:\n      ary[i] = 0.0;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      break;\n    }\n  }\n\n  return ary;\n}\n\nstatic double *\nc_darray(VALUE v, long *size)\n{\n  int i, len;\n  double *ary;\n  VALUE e;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(double) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    case T_FLOAT:\n      ary[i] = (double)(RFLOAT(e)->value);\n      break;\n    case T_NIL:\n      ary[i] = 0.0;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      break;\n    }\n  }\n\n  return ary;\n}\n\nstatic long *\nc_larray(VALUE v, long *size)\n{\n  int i, len;\n  long *ary;\n  VALUE e;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(long) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n      ary[i] = (long)(NUM2INT(e));\n      break;\n    case T_NIL:\n      ary[i] = 0;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      break;\n    }\n  }\n\n  return ary;\n}\n\nstatic int *\nc_iarray(VALUE v, long *size)\n{\n  int i, len;\n  int *ary;\n  VALUE e;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(int) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n      ary[i] = (int)(NUM2INT(e));\n      break;\n    case T_NIL:\n      ary[i] = 0;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      break;\n    }\n  }\n\n  return ary;\n}\n\nstatic short *\nc_harray(VALUE v, long *size)\n{\n  int i, len;\n  short *ary;\n  VALUE e;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(short) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n      ary[i] = (short)(NUM2INT(e));\n      break;\n    case T_NIL:\n      ary[i] = 0;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      break;\n    }\n  }\n\n  return ary;\n}\n\nstatic char *\nc_carray(VALUE v, long *size)\n{\n  int i, len;\n  char *ary;\n  VALUE e;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(char) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n      ary[i] = (char)(NUM2INT(e));\n      break;\n    case T_NIL:\n      ary[i] = 0;\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      break;\n    }\n  }\n\n  return ary;\n}\n\nstatic void *\nc_parray(VALUE v, long *size)\n{\n  int i, len;\n  void **ary;\n  VALUE e, tmp;\n\n  len = RARRAY(v)->len;\n  *size = sizeof(void*) * len;\n  ary = dlmalloc(*size);\n  for (i=0; i < len; i++) {\n    e = rb_ary_entry(v, i);\n    switch (TYPE(e)) {\n    default:\n      tmp = rb_check_string_type(e);\n      if (NIL_P(tmp)) {\n\t  rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n      }\n      e = tmp;\n      /* fall through */\n    case T_STRING:\n      rb_check_safe_str(e);\n      {\n\tchar *str, *src;\n\tsrc = RSTRING(e)->ptr;\n\tstr = dlstrdup(src);\n\tary[i] = (void*)str;\n      }\n      break;\n    case T_NIL:\n      ary[i] = NULL;\n      break;\n    case T_DATA:\n      if (rb_obj_is_kind_of(e, rb_cDLPtrData)) {\n\tstruct ptr_data *pdata;\n\tData_Get_Struct(e, struct ptr_data, pdata);\n\tary[i] = (void*)(pdata->ptr);\n      }\n      else{\n        e = rb_funcall(e, rb_intern(\"to_ptr\"), 0);\n        if (rb_obj_is_kind_of(e, rb_cDLPtrData)) {\n\t  struct ptr_data *pdata;\n\t  Data_Get_Struct(e, struct ptr_data, pdata);\n\t  ary[i] = (void*)(pdata->ptr);\n\t}\n\telse{\n\t  rb_raise(rb_eDLTypeError, \"unexpected type of the element #%d\", i);\n\t}\n      }\n      break;\n    }\n  }\n\n  return ary;\n}\n\nvoid *\nrb_ary2cary(char t, VALUE v, long *size)\n{\n  int len;\n  VALUE val0;\n\n  val0 = rb_check_array_type(v);\n  if(NIL_P(val0)) {\n    rb_raise(rb_eDLTypeError, \"an array is expected.\");\n  }\n  v = val0;\n\n  len = RARRAY(v)->len;\n  if (len == 0) {\n    return NULL;\n  }\n\n  if (!size) {\n    size = ALLOCA_N(long,1);\n  }\n\n  val0 = rb_ary_entry(v,0);\n  switch (TYPE(val0)) {\n  case T_FIXNUM:\n  case T_BIGNUM:\n    switch (t) {\n    case 'C': case 'c':\n      return (void*)c_carray(v,size);\n    case 'H': case 'h':\n      return (void*)c_harray(v,size);\n    case 'I': case 'i':\n      return (void*)c_iarray(v,size);\n    case 'L': case 'l': case 0:\n      return (void*)c_larray(v,size);\n    default:\n      rb_raise(rb_eDLTypeError, \"type mismatch\");\n    }\n  case T_STRING:\n    return (void*)c_parray(v,size);\n  case T_FLOAT:\n    switch (t) {\n    case 'F': case 'f':\n      return (void*)c_farray(v,size);\n    case 'D': case 'd': case 0:\n      return (void*)c_darray(v,size);\n    }\n    rb_raise(rb_eDLTypeError, \"type mismatch\");\n  case T_DATA:\n    if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) {\n      return (void*)c_parray(v,size);\n    }\n    else{\n      val0 = rb_funcall(val0, rb_intern(\"to_ptr\"), 0);\n      if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) {\n        return (void*)c_parray(v,size);\n      }\n    }\n    rb_raise(rb_eDLTypeError, \"type mismatch\");\n  case T_NIL:\n    return (void*)c_parray(v, size);\n  default:\n    rb_raise(rb_eDLTypeError, \"unsupported type\");\n  }\n}\n\nVALUE\nrb_str_to_ptr(VALUE self)\n{\n  char *ptr;\n  int  len;\n  VALUE p;\n\n  len = RSTRING(self)->len;\n  ptr = (char*)dlmalloc(len + 1);\n  memcpy(ptr, RSTRING(self)->ptr, len);\n  ptr[len] = '\\0';\n  p = rb_dlptr_new((void*)ptr,len,dlfree);\n  OBJ_INFECT(p, self);\n  return p;\n}\n\nVALUE\nrb_ary_to_ptr(int argc, VALUE argv[], VALUE self)\n{\n  void *ptr;\n  VALUE t;\n  long size;\n\n  switch (rb_scan_args(argc, argv, \"01\", &t)) {\n  case 1:\n    ptr = rb_ary2cary(StringValuePtr(t)[0], self, &size);\n    break;\n  case 0:\n    ptr = rb_ary2cary(0, self, &size);\n    break;\n  }\n  if (ptr) {\n      VALUE p = rb_dlptr_new(ptr, size, dlfree);\n      OBJ_INFECT(p, self);\n      return p;\n  }\n  return Qnil;\n}\n\nVALUE\nrb_io_to_ptr(VALUE self)\n{\n  rb_io_t *fptr;\n  FILE     *fp;\n\n  GetOpenFile(self, fptr);\n  fp = fptr->f;\n\n  return fp ? rb_dlptr_new(fp, 0, 0) : Qnil;\n}\n\nVALUE\nrb_dl_dlopen(int argc, VALUE argv[], VALUE self)\n{\n  rb_secure(2);\n  return rb_class_new_instance(argc, argv, rb_cDLHandle);\n}\n\nVALUE\nrb_dl_malloc(VALUE self, VALUE size)\n{\n  rb_secure(4);\n  return rb_dlptr_malloc(DLNUM2LONG(size), dlfree);\n}\n\nVALUE\nrb_dl_strdup(VALUE self, VALUE str)\n{\n  SafeStringValue(str);\n  return rb_dlptr_new(strdup(RSTRING(str)->ptr), RSTRING(str)->len, dlfree);\n}\n\nstatic VALUE\nrb_dl_sizeof(VALUE self, VALUE str)\n{\n  return INT2NUM(dlsizeof(StringValuePtr(str)));\n}\n\nstatic VALUE\nrb_dl_callback(int argc, VALUE argv[], VALUE self)\n{\n  VALUE type, proc;\n  int rettype, entry, i;\n  char fname[127];\n\n  rb_secure(4);\n  proc = Qnil;\n  switch (rb_scan_args(argc, argv, \"11\", &type, &proc)) {\n  case 1:\n    if (rb_block_given_p()) {\n      proc = rb_block_proc();\n    }\n    else{\n      proc = Qnil;\n    }\n  default:\n    break;\n  }\n\n  StringValue(type);\n  switch (RSTRING(type)->ptr[0]) {\n  case '0':\n    rettype = 0x00;\n    break;\n  case 'C':\n    rettype = 0x01;\n    break;\n  case 'H':\n    rettype = 0x02;\n    break;\n  case 'I':\n    rettype = 0x03;\n    break;\n  case 'L':\n    rettype = 0x04;\n    break;\n  case 'F':\n    rettype = 0x05;\n    break;\n  case 'D':\n    rettype = 0x06;\n    break;\n  case 'P':\n    rettype = 0x07;\n    break;\n  default:\n    rb_raise(rb_eDLTypeError, \"unsupported type `%c'\", RSTRING(type)->ptr[0]);\n  }\n\n  entry = -1;\n  for (i=0; i < MAX_CALLBACK; i++) {\n    if (rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil) {\n      entry = i;\n      break;\n    }\n  }\n  if (entry < 0) {\n    rb_raise(rb_eDLError, \"too many callbacks are defined.\");\n  }\n\n  rb_hash_aset(DLFuncTable,\n\t       rb_assoc_new(INT2NUM(rettype),INT2NUM(entry)),\n\t       rb_assoc_new(type,proc));\n  sprintf(fname, \"rb_dl_callback_func_%d_%d\", rettype, entry);\n  return rb_dlsym_new((void (*)())rb_dl_callback_table[rettype][entry],\n\t\t      fname, RSTRING(type)->ptr);\n}\n\nstatic VALUE\nrb_dl_remove_callback(VALUE mod, VALUE sym)\n{\n  freefunc_t f;\n  int i, j;\n\n  rb_secure(4);\n  f = rb_dlsym2csym(sym);\n  for (i=0; i < CALLBACK_TYPES; i++) {\n    for (j=0; j < MAX_CALLBACK; j++) {\n      if (rb_dl_callback_table[i][j] == f) {\n\trb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil);\n\tbreak;\n      }\n    }\n  }\n  return Qnil;\n}\n\nvoid\nInit_dl()\n{\n  void Init_dlptr();\n  void Init_dlsym();\n  void Init_dlhandle();\n\n  id_call = rb_intern(\"call\");\n\n  rb_mDL = rb_define_module(\"DL\");\n\n  rb_eDLError = rb_define_class_under(rb_mDL, \"DLError\", rb_eStandardError);\n  rb_eDLTypeError = rb_define_class_under(rb_mDL, \"DLTypeError\", rb_eDLError);\n\n  DLFuncTable = rb_hash_new();\n  init_dl_func_table();\n  rb_define_const(rb_mDL, \"FuncTable\", DLFuncTable);\n\n  rb_define_const(rb_mDL, \"RTLD_GLOBAL\", INT2NUM(RTLD_GLOBAL));\n  rb_define_const(rb_mDL, \"RTLD_LAZY\",   INT2NUM(RTLD_LAZY));\n  rb_define_const(rb_mDL, \"RTLD_NOW\",    INT2NUM(RTLD_NOW));\n\n  rb_define_const(rb_mDL, \"ALIGN_INT\",   INT2NUM(ALIGN_INT));\n  rb_define_const(rb_mDL, \"ALIGN_LONG\",  INT2NUM(ALIGN_LONG));\n  rb_define_const(rb_mDL, \"ALIGN_FLOAT\", INT2NUM(ALIGN_FLOAT));\n  rb_define_const(rb_mDL, \"ALIGN_SHORT\", INT2NUM(ALIGN_SHORT));\n  rb_define_const(rb_mDL, \"ALIGN_DOUBLE\",INT2NUM(ALIGN_DOUBLE));\n  rb_define_const(rb_mDL, \"ALIGN_VOIDP\", INT2NUM(ALIGN_VOIDP));\n\n  rb_define_const(rb_mDL, \"MAX_ARG\", INT2NUM(MAX_ARG));\n  rb_define_const(rb_mDL, \"DLSTACK\", rb_tainted_str_new2(DLSTACK_METHOD));\n\n  rb_define_module_function(rb_mDL, \"dlopen\", rb_dl_dlopen, -1);\n  rb_define_module_function(rb_mDL, \"callback\", rb_dl_callback, -1);\n  rb_define_module_function(rb_mDL, \"define_callback\", rb_dl_callback, -1);\n  rb_define_module_function(rb_mDL, \"remove_callback\", rb_dl_remove_callback, 1);\n  rb_define_module_function(rb_mDL, \"malloc\", rb_dl_malloc, 1);\n  rb_define_module_function(rb_mDL, \"strdup\", rb_dl_strdup, 1);\n  rb_define_module_function(rb_mDL, \"sizeof\", rb_dl_sizeof, 1);\n\n  Init_dlptr();\n  Init_dlsym();\n  Init_dlhandle();\n\n  rb_define_const(rb_mDL, \"FREE\", rb_dlsym_new(dlfree, \"free\", \"0P\"));\n\n  rb_define_method(rb_cString, \"to_ptr\", rb_str_to_ptr, 0);\n  rb_define_method(rb_cArray, \"to_ptr\", rb_ary_to_ptr, -1);\n  rb_define_method(rb_cIO, \"to_ptr\", rb_io_to_ptr, 0);\n}\n"
  },
  {
    "path": "ext/dl/dl.def",
    "content": "EXPORTS\nInit_dl\ndlfree\ndlmalloc\ndlrealloc\ndlstrdup\nrb_ary_to_ptr\nrb_dl_dlopen\nrb_dl_malloc\nrb_dl_strdup\nrb_eDLError\nrb_eDLTypeError\nrb_io_to_ptr\nrb_mDL\nrb_str_to_ptr\nInit_dlhandle\nrb_cDLHandle\nrb_dlhandle_close\nrb_dlhandle_disable_close\nrb_dlhandle_enable_close\nrb_dlhandle_sym\nInit_dlptr\nrb_cDLPtrData\nrb_dlmem_each\nrb_dlptr2cptr\nrb_dlptr_malloc\nrb_dlptr_aref\nrb_dlptr_aset\nrb_dlptr_cmp\nrb_dlptr_define_data_type\nrb_dlptr_define_struct\nrb_dlptr_define_union\nrb_dlptr_eql\nrb_dlptr_free_get\nrb_dlptr_free_set\nrb_dlptr_get_data_type\nrb_dlptr_inspect\nrb_dlptr_minus\nrb_dlptr_new\nrb_dlptr_new2\nrb_dlptr_null_p\nrb_dlptr_plus\nrb_dlptr_ptr\nrb_dlptr_ref\nrb_dlptr_to_array\nrb_dlptr_to_i\nrb_dlptr_to_s\nrb_dlptr_to_str\nrb_mDLMemorySpace\nInit_dlsym\nrb_cDLSymbol\nrb_dlsym2csym\nrb_dlsym_call\nrb_dlsym_cproto\nrb_dlsym_inspect\nrb_dlsym_name\nrb_dlsym_new\nrb_dlsym_proto\nrb_dlsym_to_ptr\n"
  },
  {
    "path": "ext/dl/dl.h",
    "content": "/* -*- C -*-\n * $Id$\n */\n\n#ifndef RUBY_DL_H\n#define RUBY_DL_H\n\n#include <ruby.h>\n#include <dlconfig.h>\n\n#if defined(HAVE_DLFCN_H)\n# include <dlfcn.h>\n# /* some stranger systems may not define all of these */\n#ifndef RTLD_LAZY\n#define RTLD_LAZY 0\n#endif\n#ifndef RTLD_GLOBAL\n#define RTLD_GLOBAL 0\n#endif\n#ifndef RTLD_NOW\n#define RTLD_NOW 0\n#endif\n#else\n# if defined(HAVE_WINDOWS_H)\n#   include <windows.h>\n#   define dlclose(ptr) FreeLibrary((HINSTANCE)ptr)\n#   define dlopen(name,flag) ((void*)LoadLibrary(name))\n#   define dlerror()    \"unknown error\"\n#   define dlsym(handle,name) ((void*)GetProcAddress(handle,name))\n#   define RTLD_LAZY -1\n#   define RTLD_NOW  -1\n#   define RTLD_GLOBAL -1\n# endif\n#endif\n\n#if !defined(StringValue)\n# define StringValue(v) if(TYPE(v) != T_STRING) v = rb_str_to_str(v)\n#endif\n#if !defined(StringValuePtr)\n# define StringValuePtr(v) RSTRING((TYPE(v) == T_STRING) ? (v) : rb_str_to_str(v))->ptr\n#endif\n\n#ifdef DEBUG\n#define DEBUG_CODE(b) {printf(\"DEBUG:%d\\n\",__LINE__);b;}\n#define DEBUG_CODE2(b1,b2) {printf(\"DEBUG:%d\\n\",__LINE__);b1;}\n#else\n#define DEBUG_CODE(b)\n#define DEBUG_CODE2(b1,b2) b2\n#endif\n\n#define VOID_DLTYPE   0x00\n#define CHAR_DLTYPE   0x01\n#define SHORT_DLTYPE  0x02\n#define INT_DLTYPE    0x03\n#define LONG_DLTYPE   0x04\n#define FLOAT_DLTYPE  0x05\n#define DOUBLE_DLTYPE 0x06\n#define VOIDP_DLTYPE  0x07\n\n#define ARG_TYPE(x,i) (((x) & (0x07 << ((i)*3))) >> ((i)*3))\n#define PUSH_ARG(x,t) do{x <<= 3; x |= t;}while(0)\n#define PUSH_0(x) PUSH_ARG(x,VOID_DLTYPE)\n\n#if SIZEOF_INT == SIZEOF_LONG\n# define PUSH_I(x) PUSH_ARG(x,LONG_DLTYPE)\n# define ANY2I(x)  x.l\n# define DLINT(x)  (long)x\n#else\n# define PUSH_I(x) PUSH_ARG(x,INT_DLTYPE)\n# define ANY2I(x)  x.i\n# define DLINT(x)  (int)x\n#endif\n#define PUSH_L(x) PUSH_ARG(x,LONG_DLTYPE)\n#define ANY2L(x)  x.l\n#define DLLONG(x) (long)x\n\n#if defined(WITH_TYPE_FLOAT)\n# if SIZEOF_FLOAT == SIZEOF_DOUBLE\n#   define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE)\n#   define ANY2F(x)  (x.d)\n#   define DLFLOAT(x) ((double)x)\n# else\n#   define PUSH_F(x) PUSH_ARG(x,FLOAT_DLTYPE)\n#   define ANY2F(x)  (x.f)\n#   define DLFLOAT(x) ((float)x)\n# endif\n#else\n# define PUSH_F(x) PUSH_ARG(x,DOUBLE_DLTYPE)\n# define ANY2F(x)  (x.d)\n# define DLFLOAT(x) ((double)x)\n#endif\n#define PUSH_D(x) PUSH_ARG(x,DOUBLE_DLTYPE)\n#define ANY2D(x)  (x.d)\n#define DLDOUBLE(x) ((double)x)\n\n#if SIZEOF_INT == SIZEOF_VOIDP && SIZEOF_INT != SIZEOF_LONG\n# define PUSH_P(x) PUSH_ARG(x,INT_DLTYPE)\n# define ANY2P(x)  (x.i)\n# define DLVOIDP(x) ((int)x)\n#elif SIZEOF_LONG == SIZEOF_VOIDP\n# define PUSH_P(x) PUSH_ARG(x,LONG_DLTYPE)\n# define ANY2P(x)  (x.l)\n# define DLVOIDP(x) ((long)x)\n#else\n# define PUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE)\n# define ANY2P(x)  (x.p)\n# define DLVOIDP(x) ((void*)p)\n#endif\n\n#if defined(WITH_TYPE_CHAR)\n# define PUSH_C(x) PUSH_ARG(x,CHAR_DLTYPE)\n# define ANY2C(x)  (x.c)\n# define DLCHAR(x) ((char)x)\n#else\n# define PUSH_C(x) PUSH_I(x)\n# define ANY2C(x)  ANY2I(x)\n# define DLCHAR(x) DLINT(x)\n#endif\n\n#if defined(WITH_TYPE_SHORT)\n# define PUSH_H(x) PUSH_ARG(x,SHORT_DLTYPE)\n# define ANY2H(x)  (x.h)\n# define DLSHORT(x) ((short)x)\n#else\n# define PUSH_H(x) PUSH_I(x)\n# define ANY2H(x)  ANY2I(x)\n# define DLSHORT(x) DLINT(x)\n#endif\n\n#define PUSH_S(x) PUSH_P(x)\n#define ANY2S(x) ANY2P(x)\n#define DLSTR(x) DLVOIDP(x)\n\n#define CBPUSH_0(x) PUSH_0(x)\n#define CBPUSH_C(x) PUSH_C(x)\n#define CBPUSH_H(x) PUSH_H(x)\n#define CBPUSH_I(x) PUSH_I(x)\n#define CBPUSH_L(x) PUSH_L(x)\n#define CBPUSH_F(x) PUSH_F(x)\n#define CBPUSH_D(x) PUSH_D(x)\n#if defined(WITH_CBTYPE_VOIDP)\n# define CBPUSH_P(x) PUSH_ARG(x,VOIDP_DLTYPE)\n#else\n# define CBPUSH_P(x) PUSH_P(x)\n#endif\n\n\n#if defined(USE_INLINE_ASM)\n# if defined(__i386__) && defined(__GNUC__)\n#   define DLSTACK\n#   define DLSTACK_METHOD \"asm\"\n#   define DLSTACK_REVERSE\n#   define DLSTACK_PROTO\n#   define DLSTACK_ARGS\n#   define DLSTACK_START(sym)\n#   define DLSTACK_END(sym)\n#   define DLSTACK_PUSH_C(x) asm volatile (\"pushl %0\" :: \"g\" (x));\n#   define DLSTACK_PUSH_H(x) asm volatile (\"pushl %0\" :: \"g\" (x));\n#   define DLSTACK_PUSH_I(x) asm volatile (\"pushl %0\" :: \"g\" (x));\n#   define DLSTACK_PUSH_L(x) asm volatile (\"pushl %0\" :: \"g\" (x));\n#   define DLSTACK_PUSH_P(x) asm volatile (\"pushl %0\" :: \"g\" (x));\n#   define DLSTACK_PUSH_F(x) asm volatile (\"flds %0\"::\"g\"(x));\\\n                             asm volatile (\"subl $4,%esp\");\\\n                             asm volatile (\"fstps (%esp)\");\n#   define DLSTACK_PUSH_D(x) asm volatile (\"fldl %0\"::\"g\"(x));\\\n                             asm volatile (\"subl $8,%esp\");\\\n                             asm volatile (\"fstpl (%esp)\")\n# else\n# error --with-asm is not supported on this machine\n# endif\n#elif defined(USE_DLSTACK)\n# define DLSTACK\n# define DLSTACK_GUARD\n# define DLSTACK_METHOD \"dl\"\n# define DLSTACK_PROTO long,long,long,long,long,\\\n                       long,long,long,long,long,\\\n                       long,long,long,long,long\n# define DLSTACK_ARGS  stack[0],stack[1],stack[2],stack[3],stack[4],\\\n                       stack[5],stack[6],stack[7],stack[8],stack[9],\\\n                       stack[10],stack[11],stack[12],stack[13],stack[14]\n# define DLSTACK_SIZE  (sizeof(long)*15)\n# define DLSTACK_START(sym)\n# define DLSTACK_END(sym)\n# define DLSTACK_PUSH_C(x)  {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}\n# define DLSTACK_PUSH_H(x)  {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}\n# define DLSTACK_PUSH_I(x)  {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;}\n# define DLSTACK_PUSH_L(x)  memcpy(sp,&x,sizeof(long)); sp++;\n# define DLSTACK_PUSH_P(x)  memcpy(sp,&x,sizeof(void*)); sp++;\n# define DLSTACK_PUSH_F(x)  memcpy(sp,&x,sizeof(float)); sp+=sizeof(float)/sizeof(long);\n# define DLSTACK_PUSH_D(x)  memcpy(sp,&x,sizeof(double)); sp+=sizeof(double)/sizeof(long);\n#else\n# define DLSTACK_METHOD \"none\"\n#endif\n\nextern VALUE rb_mDL;\nextern VALUE rb_mDLMemorySpace;\nextern VALUE rb_cDLHandle;\nextern VALUE rb_cDLSymbol;\nextern VALUE rb_cDLPtrData;\nextern VALUE rb_cDLStructData;\n\nextern VALUE rb_eDLError;\nextern VALUE rb_eDLTypeError;\n\n#if defined(LONG2NUM) && (SIZEOF_LONG == SIZEOF_VOIDP)\n# define DLLONG2NUM(x) LONG2NUM((long)x)\n# define DLNUM2LONG(x) (long)(NUM2LONG(x))\n#else\n# define DLLONG2NUM(x) INT2NUM((long)x)\n# define DLNUM2LONG(x) (long)(NUM2INT(x))\n#endif\n\ntypedef struct { char c; void *x; } s_voidp;\ntypedef struct { char c; short x; } s_short;\ntypedef struct { char c; int x; } s_int;\ntypedef struct { char c; long x; } s_long;\ntypedef struct { char c; float x; } s_float;\ntypedef struct { char c; double x; } s_double;\n\n#define ALIGN_VOIDP  (sizeof(s_voidp) - sizeof(void *))\n#define ALIGN_SHORT  (sizeof(s_short) - sizeof(short))\n#define ALIGN_INT    (sizeof(s_int) - sizeof(int))\n#define ALIGN_LONG   (sizeof(s_long) - sizeof(long))\n#define ALIGN_FLOAT  (sizeof(s_float) - sizeof(float))\n#define ALIGN_DOUBLE (sizeof(s_double) - sizeof(double))\n\n/* for compatibility */\n#define VOIDP_ALIGN  ALIGN_VOIDP\n#define SHORT_ALIGN  ALIGN_SHORT\n#define INT_ALIGN    ALIGN_INT\n#define LONG_ALIGN   ALIGN_LONG\n#define FLOAT_ALIGN  ALIGN_FLOAT\n#define DOUBLE_ALIGN ALIGN_DOUBLE\n\n#define DLALIGN(ptr,offset,align) {\\\n  while( (((unsigned long)((char *)ptr + offset)) % align) != 0 ) offset++;\\\n}\n\ntypedef void (*freefunc_t)(void *);\n#define DLFREEFUNC(func) ((freefunc_t)(func))\n\ntypedef union {\n  void*  p;\n  char   c;\n  short  h;\n  int    i;\n  long   l;\n  float  f;\n  double d;\n  char  *s;\n} ANY_TYPE;\n\nstruct dl_handle {\n  void *ptr;\n  int  open;\n  int  enable_close;\n};\n\nstruct sym_data {\n  void *func;\n  char *name;\n  char *type;\n  int  len;\n};\n\nenum DLPTR_CTYPE {\n  DLPTR_CTYPE_UNKNOWN,\n  DLPTR_CTYPE_STRUCT,\n  DLPTR_CTYPE_UNION\n};\n\nstruct ptr_data {\n  void *ptr;       /* a pointer to the data */\n  freefunc_t free; /* free() */\n  char *stype;      /* array of type specifiers */\n  int  *ssize;      /* size[i] = sizeof(type[i]) > 0 */\n  int  slen;   /* the number of type specifiers */\n  ID   *ids;\n  int  ids_num;\n  int  ctype; /* DLPTR_CTYPE_UNKNOWN, DLPTR_CTYPE_STRUCT, DLPTR_CTYPE_UNION */\n  long size;\n};\n\n#define RDLPTR(obj)  ((struct ptr_data *)(DATA_PTR(obj)))\n#define RDLSYM(obj)  ((struct sym_data *)(DATA_PTR(obj)))\n\nvoid dlfree(void*);\nvoid *dlmalloc(size_t);\nvoid *dlrealloc(void*,size_t);\nchar *dlstrdup(const char *);\nsize_t dlsizeof(const char *);\n\nvoid *rb_ary2cary(char t, VALUE ary, long *size);\n\n/*\nvoid rb_dlmem_delete(void *ptr);\nvoid rb_dlmem_aset(void *ptr, VALUE obj);\nVALUE rb_dlmem_aref(void *ptr);\n*/\n\nvoid dlptr_free(struct ptr_data *data);\nvoid dlptr_init(VALUE val);\n\nVALUE rb_dlptr_new(void *ptr, long size, freefunc_t func);\nVALUE rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func);\nVALUE rb_dlptr_malloc(long size, freefunc_t func);\nvoid *rb_dlptr2cptr(VALUE val);\n\nVALUE rb_dlsym_new(void (*func)(), const char *name, const char *type);\nfreefunc_t rb_dlsym2csym(VALUE val);\n\n\n#endif /* RUBY_DL_H */\n"
  },
  {
    "path": "ext/dl/doc/dl.txt",
    "content": "=begin\n\n= Ruby/DL\n\nRuby/DL provides an interface to the dynamic linker such as dlopen() on UNIX\nand LoadLibrary() on Windows.\n\n= Building and Installing\n\n  $ ruby extconf.rb    # to create the Makefile\n  $ make               # to build the library 'dl.so'\n  $ make libtest.so    # to build the C library 'libtest.so' for the test script\n  $ make test          # to run the test script\n  $ make install       # to install the library\n  $ make clean         # to remove the created files without Makefile\n  $ make distclean     # to remove the all created files\n\n= Using Ruby/DL\n\nWe should usually use DL::Importable module provided by \"dl/import.rb\".\nIt has high-level functions to access library functions. We use\nDL::Importable module to extend a module as follows:\n\n  require \"dl/import\"\n  module LIBC\n    extend DL::Importable\n  end\n\nNow we can use methods dlload and extern in this module. We load the\nlibraries using dlload, and define wrapper methods to library functions\nusing extern respectively as follows:\n\n  module LIBC\n    extend DL::Importable\n    dlload \"libc.so.6\",\"libm.so.6\"\n    extern \"int strlen(char*)\"\n  end\n  # Note that we should not include the module LIBC from some reason.\n\nWe can call the library function strlen() using LIBC.strlen. If the first\ncharacter of given function name is an uppercase, the first character of the\ndefined method name becomes lowercase.\nWe can also construct memory images of structures and unions using functions\nstruct and union which are defined in \"dl/struct.rb\" as follows:\n\n  require \"dl/import\"\n  require \"dl/struct\"\n  module LIBC\n    extend DL::Importable\n    Timeval = struct [       # define timeval structure.\n      \"long tv_sec\",\n      \"long tv_uses\",\n    ]\n  end\n  val = LIBC::Timeval.malloc # allocate memory.\n\nNotice that the above example takes LIBC::Timeval.malloc to allocate memory,\nrather than LIBC::Timeval.new. It is because DL::Timeval.new is for wrapping\nan object, PtrData, which has already been created.\n\nWe can define a callback using the module function \"callback\" as follows:\n\n  module Foo\n    extend DL::Importable\n    def my_comp(str1,str2)\n      str1 <=> str2\n    end\n    COMPARE = callback \"int my_comp(char*,char*)\"\n  end\n\nwhere Foo::COMPARE is a Symbol object which invokes the method \"my_comp\".\n\nDL::Importable module is very useful. However, we sometimes encounter a case\nthat we must directly use low-level functions such as dlsym(). In such case,\nwe would use DL module functions. They are described in next section.\n\n= DL module\n\nModule DL consists of three classes, a few module functions and constants.\nThe class Symbol represents the symbol we can call. The class PtrData\nindicates a memory block such as a pointer in C. An object instantiated from\nthe class Handle keeps a handle to opened library.\n\n== Constants\n\n* VERSION\n* MAJOR_VERSION\n* MINOR_VERSION\n* PATCH_VERSION\n* RTLD_GLOBAL\n* RTLD_LAZY\n* RTLD_NOW\n* MAX_ARG\n* MAX_CBARG\n* MAX_CBENT\n\n== Functions\n\n* handle = dlopen(lib){|handle| ... }\n  * is quite equal to `Handle.new(lib)'\n\n* sym = set_callback(cbtype, entry){|args| ... }\n* sym = set_callback(cbtype, entry, proc)\n  * makes entry-th pre-defined function to call the proc or given block. the \n    entry-th pre-defined function is specified by cbtype and entry. cbtype is a\n    prototype of the callback. see also the section `Type specifiers' about \n    cbtype.\n\n* sym = get_callback(cbtype, entry)\n  * returns the Proc object which is given by the above function\n   `set_callback'.\n\n* ptr = malloc(size, [free = nil])\n  * allocates the size bytes, and returns the pointer as a PtrData object ptr.\n\n* ptr = strdup(str)\n  * returns a PtrData object ptr which represents the pointer to a new string\n    which is a duplicate of the string str.\n\n* size = sizeof(type)\n  * returns the size of type. `sizeof(\"C\") + sizeof(\"L\")' is not equal to\n    `sizeof(\"CL\")'. the latter is assumed to returns the enough size of the\n    structure `struct foo { char c; long l; }', but the size may not equal to\n    `sizeof(foo)' of C.\n\n== Handle class\n\n* handle = Handle.new(lib){|handle| ... }\n  * opens a library lib and returns a Handle object handle. if a block is\n    given, the handle is automatically closed as the block ends.\n\n* Handle#close\n  * closes the handle opened by the above Handle.new(lib).\n\n* sym = Handle#sym(func, prototype = \"0\"),\n  sym = Handle#[func, prototype = nil]\n\n  * obtains the pointer to a function called func and returns a Symbol object\n    or a DataPtr object. prototype is a string which consists of type\n    specifiers, it indicates the function's prototype. see also the section\n    `Type specifiers'.\n\n== Symbol class\n\n* sym = Symbol.new(addr, type = nil, name = nil)\n  * creates the Symbol object sym with the type type if type is not nil. addr\n    is the address where the function is allocated. If type is nil, it returns\n    a DataPtr object.\n\n* Symbol::char2type(char)\n  * takes a character char that represents a type and returns the type\n    specifier of the C language.\n\n* str = Symbol#proto()\n  * returns the function prototype.\n\n* str = Symbol#name()\n  * Returns the function name.\n\n* str = Symbol#cproto(),\n  str = Symbol#to_s()\n  * returns the prototype of the C language.\n\n* str = Symbol#inspect()\n  * returns the inspectable string.\n\n* r,rs = Symbol#call(arg1,arg2,...,argN),\n  r,rs = Symbol#[](arg1,arg2,...,argN)\n  * calls the function with parameters arg1, arg2, ..., argN. and the result\n    consists of the return value r and parameters rs. rs is an array.\n\n* ptr = Symbol#to_ptr\n  * returns the corresponding PtrData object ptr.\n\n== PtrData class\n\n* ptr = PtrData.new(addr, [size = 0, free = nil])\n  * returns the PtrData object representing the pointer which indicates the\n    address addr. GC frees the memory using the free function.\n\n* PtrData#free=(sym)\n  * If you specify a symbol object sym, GC frees the memory using the function\n    represented by sym.\n\n* sym = PtrData#free\n  * returns a symbol object sym which is used when GC frees the memory. it\n    usually configured by `PtrData#free=' or `PtrData.new'.\n\n* size = PtrData#size, PtrData#size=(size)\n  * gets and sets allocated size of the memory.\n\n* ary = PtrData#to_a(type, [size])\n  * returns an array of the type which specified with type. type must be one of\n    'S','P','I','L','D' and 'F'.\n\n* str = PtrData#to_s([len])\n  * returns a string which length is len. if len is omitted, the end of the\n    string is '\\0'.\n\n* ptr = PtrData#ptr,+@\n  * returns the pointed value as a PtrData object ptr.\n\n* ptr = PtrData#ref,-@\n  * returns the reference as a PtrData object ptr.\n\n* ptr = PtrData#+\n  * returns the PtrData object\n\n* ptr = PtrData#-\n  * returns the PtrData object\n\n* PtrData#struct!(type, *members)\n  * defines the data type to get access to a structure member with a symbol.\n    (see also PtrData#[])\n\n* PtrData#union!(type, *members)\n  * defines the data type to get access to a union member with a symbol. (see\n    also PtrData#[])\n\n* val = PtrData#[key], PtrData#[key, num = 0]\n  * if the key is a string or symbol, this method returns the value of the\n    structure/union member which has the type defined by PtrData#\n    {struct!,union!}. if the key is a integer value and this object represents\n    the pointer ptr, it returns the value of `(ptr + key).to_s(num)'\n\n* PtrData#[key,num]=val, PtrData#[key]=val\n  * if the key is a string or symbol, this method substitute the value of the\n    structure/union member with val. if the key is a integer value and val is a\n    string, this method copies num bytes of val to the memory area ptr using\n    memcpy(3).\n\n== Type specifiers\n\nthe prototype consists of the following type specifiers, first element of \nprototype represents the type of return value, and remaining elements represent\nthe type of each argument.\n\n    C : char\n    c : char *\n    H : short\n    h : short *\n    I : int\n    i : int *\n    L : long\n    l : long *\n    F : float\n    f : float *\n    D : double\n    d : double *\n    S : const char *\n    s : char *\n    A : const type[]\n    a : type[] (allocates new memory space)\n    P : void * (same as 'p')\n    p : void * (same as 'P')\n    0 : void function (this must be a first character of the prototype)\n\nthe cbtype consists of type specifiers 0, C, I, H, L, F, D, S and P.\nfor example:\n\n    DL.callback('IPP'){|ptr1,ptr2|\n      str1 = ptr1.ptr.to_s\n      str2 = ptr2.ptr.to_s\n      str1 <=> str2\n    }\n=end\n"
  },
  {
    "path": "ext/dl/extconf.rb",
    "content": "require 'mkmf'\n\nbegin # for the exception SystemExit\n\n$:.unshift File.dirname(__FILE__)\nrequire 'type'\n\nif( ARGV.include?(\"--help\") )\n  print <<EOF\n  --help             print this messages\n  --with-type-char   strictly use type 'char'\n  --with-type-short  strictly use type 'short'\n  --with-type-float  strictly use type 'float'\n  --with-args=<max_arg>\n  --with-callback=<max_callback>\n  --enable-asm       use the embedded assembler for passing arguments.\n                     (this option is available for i386 machine now.)\n  --enable-dlstack   use a stack emulation for constructing function call.\nEOF\n  exit(0)\nend\n\n($CPPFLAGS || $CFLAGS) << \" -I.\"\n\nif (Config::CONFIG['CC'] =~ /gcc/)  # from Win32API\n  $CFLAGS << \" -fno-defer-pop -fno-omit-frame-pointer\"\nend\n\n$with_dlstack ||= true\n$with_asm = ! $with_dlstack\n\n$with_type_int = try_cpp(<<EOF)\n#include \"config.h\"\n#if SIZEOF_INT == SIZEOF_LONG\n#error int not needed\n#endif\nEOF\n\n$with_type_float = try_cpp(<<EOF)\n#include \"config.h\"\n#if SIZEOF_FLOAT == SIZEOF_DOUBLE\n#error float not needed\n#endif\nEOF\n\n$with_type_voidp = try_cpp(<<EOF)\n#include \"config.h\"\n#if SIZEOF_VOIDP == SIZEOF_INT || SIZEOF_VOIDP == SIZEOF_LONG\n#error void* not needed\n#endif\nEOF\n\n$with_type_char  = DLTYPE[CHAR][:sym]\n$with_type_short = DLTYPE[SHORT][:sym]\n$with_type_long  = DLTYPE[LONG][:sym]\n$with_type_double= DLTYPE[DOUBLE][:sym]\n$with_type_int   &= DLTYPE[INT][:sym]\n$with_type_float &= DLTYPE[FLOAT][:sym]\n$with_type_voidp &= DLTYPE[VOIDP][:sym]\n\n$with_type_char  = enable_config(\"type-char\", $with_type_char)\n$with_type_short = enable_config(\"type-short\", $with_type_short)\n$with_type_float = enable_config(\"type-float\", $with_type_float)\n\n$with_asm        = enable_config(\"asm\", $with_asm)\n$with_dlstack    = enable_config(\"dlstack\", $with_dlstack)\n\nargs = with_config(\"args\")\nmax_arg = nil\nif( $with_asm || $with_dlstack )\n  $with_type_char = true\n  $with_type_short = true\n  $with_type_float = true\n  max_arg = 0\nend\nif( args )\n  max_arg = args.to_i\n  if( !max_arg )\n    print(\"--with-args=<max_arg>\\n\")\n    exit(1)\n  end\nend\nmax_arg   ||= 6\n\nmax_callback = with_config(\"callback\",\"10\").to_i\ncallback_types = DLTYPE.keys.length\n\n\n$dlconfig_h = <<EOF\n#define MAX_ARG           #{max_arg}\nEOF\n\ndef dlc_define(const)\n  $dlconfig_h << \"#if !defined(#{const})\\n\" +\n                 \"# define #{const}\\n\" +\n                 \"#endif\\n\"\nend\n\n$dlconfig_h << \"#define MAX_CALLBACK #{max_callback}\\n\"\n$dlconfig_h << \"#define CALLBACK_TYPES #{callback_types}\\n\"\nif( $with_dlstack )\n  $dlconfig_h << \"#define USE_DLSTACK\\n\"\nelse\n  if( $with_asm )\n    $dlconfig_h << \"#define USE_INLINE_ASM\\n\"\n  end\nend\nif( $with_type_char )\n  $dlconfig_h << \"#define WITH_TYPE_CHAR\\n\"\nend\nif( $with_type_short )\n  $dlconfig_h << \"#define WITH_TYPE_SHORT\\n\"\nend\nif( $with_type_long )\n  $dlconfig_h << \"#define WITH_TYPE_LONG\\n\"\nend\nif( $with_type_double )\n  $dlconfig_h << \"#define WITH_TYPE_DOUBLE\\n\"\nend\nif( $with_type_float )\n  $dlconfig_h << \"#define WITH_TYPE_FLOAT\\n\"\nend\nif( $with_type_int )\n  $dlconfig_h << \"#define WITH_TYPE_INT\\n\"\nend\nif( $with_type_voidp )\n  $dlconfig_h << \"#define WITH_TYPE_VOIDP\\n\"\nend\n\nif( have_header(\"windows.h\") )\n  have_library(\"kernel32\")\n  have_func(\"GetLastError\", \"windows.h\")\n  dlc_define(\"HAVE_WINDOWS_H\")\n  have_windows_h = true\nend\n\nif( have_header(\"dlfcn.h\") )\n  dlc_define(\"HAVE_DLFCN_H\")\n  have_library(\"dl\")\n  have_func(\"dlopen\")\n  have_func(\"dlclose\")\n  have_func(\"dlsym\")\n  if( have_func(\"dlerror\") )\n    dlc_define(\"HAVE_DLERROR\")\n  end\nelsif ( have_windows_h )\n  have_func(\"LoadLibrary\")\n  have_func(\"FreeLibrary\")\n  have_func(\"GetProcAddress\")\nelse\n  exit(0)\nend\n\ndef File.update(file, str)\n  begin\n    open(file){|f|f.read} == str\n  rescue Errno::ENOENT\n    false\n  end or open(file, \"w\"){|f|f.print(str)}\nend\n\nFile.update(\"dlconfig.h\", <<EOF)\n#ifndef DLCONFIG_H\n#define DLCONFIG_H\n#{$dlconfig_h}\n#endif /* DLCONFIG_H */\nEOF\n\nFile.update(\"dlconfig.rb\", <<EOF)\nMAX_ARG = #{max_arg}\nMAX_CALLBACK = #{max_callback}\nCALLBACK_TYPES = #{callback_types}\nDLTYPE[CHAR][:sym]  = #{$with_type_char}\nDLTYPE[SHORT][:sym] = #{$with_type_short}\nDLTYPE[INT][:sym]   = #{$with_type_int}\nDLTYPE[LONG][:sym]  = #{$with_type_long}\nDLTYPE[FLOAT][:sym] = #{$with_type_float}\nDLTYPE[DOUBLE][:sym]= #{$with_type_double}\nDLTYPE[VOIDP][:sym] = #{$with_type_voidp}\nEOF\n\n$INSTALLFILES = [\n  [\"./dlconfig.h\", \"$(archdir)$(target_prefix)\", \".\"],\n  [\"dl.h\", \"$(archdir)$(target_prefix)\", \"\"],\n]\n$cleanfiles = %w[test/test.o]\n$distcleanfiles = %w[call.func callback.func cbtable.func dlconfig.rb\n./dlconfig.h test/libtest.so test/*~ *~ mkmf.log]\n\ncreate_makefile('dl')\nrescue SystemExit\n  # do nothing\nend\n"
  },
  {
    "path": "ext/dl/h2rb",
    "content": "#!/usr/bin/env ruby\n# -*- ruby -*-\n# $Id$\n\nrequire 'mkmf'\nrequire 'ftools'\n\n$recursive = false\n$force     = false\n$conly     = true\n$inc_path  = []\n$infilename= nil\n$insert_require = true\n\ndef valid_ruby_code?(code)\n  begin\n    eval(\"BEGIN {return true}; #{code}\")\n  rescue SyntaxError\n    return false\n  end\n  return false\nend\n\ndef print_usage\n  print <<EOF\nh2rb [-r] [-I <path>] [-d] [<filename>]\nEOF\nend\n\nwhile( ARGV[0] )\n  case( ARGV[0] )\n  when \"-r\"\n    ARGV.shift\n    $recursive = true\n  when \"-R\"\n    ARGV.shift\n    $recursive = false\n  when \"-l\"\n    ARGV.shift\n    $insert_require = true\n  when \"-L\"\n    ARGV.shift\n    $insert_require = false\n  when \"-c\"\n    ARGV.shift\n    $conly = true\n  when \"-C\"\n    ARGV.shift\n    $conly = false\n  when \"-f\"\n    ARGV.shift\n    $force = true\n  when \"-F\"\n    ARGV.shift\n    $force = false\n  when \"-I\"\n    ARGV.shift\n    $inc_path << ARGV.shift\n  when \"-d\"\n    ARGV.shift\n    $DEBUG = true\n  when \"-h\",\"--help\"\n    print_usage()\n    exit 0\n  when /-.*/\n    $stderr.print(\"unknown option '#{ARGV[0]}'.\\n\")\n    print_usage()\n    exit 0\n  else\n    $infilename = ARGV.shift\n  end\nend\n\n$inc_dir = File.join(CONFIG[\"prefix\"], \"lib\", \"ruby\",\n\t\t     CONFIG[\"MAJOR\"] + \".\" + CONFIG[\"MINOR\"],\n\t\t     \"dl\")\n\nclass H2RBError < StandardError; end\n\n\nclass H2RB\n  def initialize(inc_dir = nil, inc_path = nil, insert_require = nil)\n    @inc_path = inc_path || []\n    @inc_dir  = inc_dir  || '.'\n    @indent = 0\n    @parsed_files = []\n    @insert_require = insert_require || false\n  end\n\n  def find_path(file)\n    if( ! file )\n      return nil\n    end\n    if( File.exist?(file) )\n      if( file[0] == ?/ )\n\treturn file\n      else\n\treturn file\n      end\n    end\n    @inc_path.each{|path|\n    full = File.join(path, file)\n      if( File.exist?(full) )\n\treturn full\n      end\n    }\n    return nil\n  end\n\n  def strip_comment(line)\n    if( @commented )\n      if( e = line.index(\"*/\") )\n\tline[0..(e+1)] = \"\"\n\t@commented = false\n      else\n\tline = \"\"\n      end\n    else\n      if( s = line.index(\"/*\") )\n\tif( e = line.index(\"*/\") )\n\t  line[s..(e+1)] = \"\"\n\telse\n\t  line[s..-1] = \"\"\n\t  @commented = true\n\tend\n      elsif( s = line.index(\"//\") )\n\tline[s..(-1)] = \"\"\n      end\n    end\n      \n    line.gsub!(/\\s+$/,\"\")\n    return line\n  end\n  \n  def up_indent\n    @indent += 1\n  end\n  \n  def down_indent\n    @indent -= 1\n    if( @indent < 0 )\n      raise\n    end\n  end\n  \n  def indent\n    \"  \" * @indent\n  end\n\n  def rescue_begin\n    line = \"#{indent}begin\"\n    up_indent\n    return line\n  end\n\n  def rescue_nameerror\n    down_indent\n    line = [\n      \"#{indent}rescue NameError => e\",\n      \"#{indent}  raise e if( $DEBUG )\",\n      \"#{indent}end\"].join($/)\n    return line\n  end\n\n  def parse_enum(line)\n    if( line =~ /enum\\s+(\\S+\\s+)?\\{(.+)\\}/ )\n      enum_name  = $1\n      enum_block = $2\n      if( enum_name )\n\tline = \"#{indent}# -- enum #{enum_name}\\n\"\n      else\n\tline = \"#{indent}# -- enum\\n\"\n      end\n      enums = enum_block.split(/,/).collect{|e| e.strip}\n      i = 0\n      enums.each{|elem|\n\tvar,val = elem.split(/=/).collect{|e| e.strip}\n\tif( val )\n\t  i = val.to_i\n\tend\n\tline += \"#{indent}#{var} = #{i.to_s}\\n\"\n\ti += 1\n      }\n      line += \"#{indent}# -- end of enum\"\n      return line\n    else\n      return nil\n    end\n  end\n\n  def parse_define(line)\n    case line\n    when /^#\\s*define\\s+(\\S+)\\(\\)/\n      line = nil\n    when /^#\\s*define\\s+(\\S+)\\((.+)\\)\\s+(.+)$/\n      if( @conly )\n\tline = nil\n      else\n\tdefname = $1\n\tdefargs = $2\n\tdefval  = $3\n\tif( !valid_ruby_code?(defval) )\n\t  defval = \"nil # #{defval}\"\n\tend\n\tif( defname[0,1] =~ /^[A-Z]$/ )\n\t  line = \"#{indent}#{defname} = proc{|#{defargs}| #{defval}}\"\n\telse\n\t  line = [\n\t    \"#{indent}def #{defname}(#{defargs})\",\n\t    \"#{indent}  #{defval}\",\n\t    \"#{indent}end\"\n\t  ].join(\"\\n\")\n\tend\n      end\n    when /^#\\s*define\\s+(\\S+)\\((.+)\\)$/\n      if( @conly )\n\tline = nil\n      else\n\tdefname = $1\n\tdefargs = $2\n\tdefval  = nil\n\tif( !valid_ruby_code?(defval) )\n\t  defval = \"nil # #{defval}\"\n\tend\n\tif( defname[0,1] =~ /^[A-Z]$/ )\n\t  line = \"#{indent}#{defname} = proc{|#{defargs}| #{defval}}\"\n\telse\n\t  line = [\n\t    \"#{indent}def #{defname}(#{defargs})\",\n\t    \"#{indent}  #{defval}\",\n\t    \"#{indent}end\"\n\t  ].join(\"\\n\")\n\tend\n      end\n    when /^#\\s*define\\s+(\\S+)\\s+(.+)$/\n      defname = $1\n      defval  = $2\n      if( !valid_ruby_code?(defval) )\n\tdefval = \"nil # #{defval}\"\n      end\n      line = [rescue_begin, \"#{indent}#{defname} = #{defval}\", rescue_nameerror].join($/)\n    when /^#\\s*define\\s+(\\S+)$/\n      defname = $1\n      line = \"#{indent}#{defname} = nil\"\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_undef(line)\n    case line\n    when /^#\\s*undef\\s+([A-Z]\\S+)$/\n      defname = $1\n      line = \"#{indent}remove_const(:#{defname})\"\n    when /^#\\s*undef\\s+(\\S+)$/\n      defname = $1\n      line = \"#{indent}#{defname} = nil\"\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_ifdef(line)\n    case line\n    when /^#\\s*ifdef\\s+(\\S+)$/\n      defname = $1\n      line = [\n\trescue_begin,\n\t\"#{indent}if( defined?(#{defname}) && ! #{defname}.nil? )\"].join($/)\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_ifndef(line)\n    case line\n    when /^#\\s*ifndef\\s+(\\S+)$/\n      defname = $1\n      line = [\n\trescue_begin,\n\t\"#{indent}if( ! defined?(#{defname}) || #{defname}.nil? )\"].join($/)\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_if(line)\n    case line\n    when /^#\\s*if\\s+(.+)$/\n      cond = $1\n      cond.gsub!(/defined(.+)/){ \"defined?(#{$1}) && ! #{$1}.nil?\" }\n      if( valid_ruby_code?(cond) )\n\tline = \"#{indent}if( #{cond} )\"\n      else\n\tline = \"#{indent}if( false ) # #{cond}\"\n      end\n      line = [rescue_begin, line].join($/)\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_elif(line)\n    case line\n    when /^#\\s*elif\\s+(.+)$/\n      cond = $1\n      cond.gsub!(\"defined\",\"defined?\")\n      line = \"#{indent}elsif( #{cond} )\"\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_else(line)\n    case line\n    when /^#\\s*else\\s*/\n      line = \"#{indent}else\"\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_endif(line)\n    case line\n    when /^#\\s*endif\\s*$/\n      line = [\"#{indent}end\", rescue_nameerror].join($/)\n    else\n      line = nil\n    end\n    return line\n  end\n  \n  def parse_include(line)\n    if( ! @insert_require )\n      return nil\n    end\n\n    file = nil\n    case line\n    when /^#\\s*include \"(.+)\"$/\n      file = $1\n      line = \"#{indent}require '#{file}'\"\n    when /^#\\s*include \\<(.+)\\>$/\n      file = $1\n      line = \"#{indent}require '#{file}'\"\n    else\n      line = nil\n    end\n    if( @recursive && file && (!@parsed_files.include?(file)) )\n      parse(file, @recursive, @force, @conly)\n    end\n    return line\n  end\n\n\n  def open_files(infilename)\n    if( ! infilename )\n      return [$stdin, $stdout]\n    end\n\n    old_infilename = infilename\n    infilename = find_path(infilename)\n    if( ! infilename )\n      $stderr.print(\"'#{old_infilename}' was not found.\\n\")\n      return [nil,nil]\n    end\n\n    if( infilename )\n      if( infilename[0,1] == '/' )\n\toutfilename = File.join(@inc_dir, infilename[1..-1] + \".rb\")\n      else\n\toutfilename = infilename + \".rb\"\n      end\n      File.mkpath(File.dirname(outfilename))\n    else\n      outfilename = nil\n    end\n    \n    if( infilename )\n      fin    = File.open(infilename,\"r\")\n    else\n      fin    = $stdin\n    end\n    if( outfilename )\n      if( File.exist?(outfilename) && (!@force) )\n\t$stderr.print(\"'#{outfilename}' have already existed.\\n\")\n\treturn [fin, nil]\n      end\n      fout   = File.open(outfilename,\"w\")\n    else\n      fout   = $stdout\n    end\n\n    $stderr.print(\"#{infilename} -> #{outfilename}\\n\")\n    if( fout )\n      dir = File.dirname(outfilename)\n      if( dir[0,1] != \".\" && dir != \"\" )\n\tfout.print(\"if( ! $LOAD_PATH.include?('#{dir}') )\\n\",\n\t\t   \"  $LOAD_PATH.push('#{dir}')\\n\",\n\t\t   \"end\\n\")\n      end\n    end\n    return [fin,fout]\n  end\n\n  def parse(infilename = nil, recursive = false, force = false, conly = false)\n    @commented = false\n    @recursive = recursive\n    @force     = force\n    @conly     = conly\n    @parsed_files << infilename\n\n    fin,fout = open_files(infilename)\n    if( !fin )\n      return\n    end\n\n    begin\n      line_number = 0\n      pre_line    = nil\n      fin.each_line{|line|\n\tline_number += 1\n\tline.chop!\n\tif( $DEBUG )\n\t  $stderr.print(\"#{line_number}:(#{@indent}):\", line, \"\\n\")\n\tend\n\t\n\tif( pre_line )\n\t  line = pre_line + line\n\t  pre_line = nil\n\tend\n\n\tif( line[-1,1] == \"\\\\\" )\n\t  pre_line = line[0..-2]\n\t  next\n\tend\n\n\tif( eidx = line.index(\"enum \") )\n\t  pre_line = line[eidx .. -1]\n\t  if( i = line.index(\"{\") && j = line.index(\"}\") )\n\t    line = line[0..j]\n\t    pre_line = nil\n\t  else\n\t    next\n\t  end\n\tend\n\n\tline = strip_comment(line)\n\tcase line\n\twhen /^enum\\s/\n\t  line = parse_enum(line)\n\twhen /^#\\s*define\\s/\n\t  line = parse_define(line)\n\twhen /^#\\s*undef\\s/\n\t  line = parse_undef(line)\n\twhen /^#\\s*ifdef\\s/\n\t  line = parse_ifdef(line)\n\t  up_indent\n\twhen /^#\\s*ifndef\\s/\n\t  line = parse_ifndef(line)\n\t  up_indent\n\twhen /^#\\s*if\\s/\n\t  line = parse_if(line)\n\t  up_indent\n\twhen /^#\\s*elif\\s/\n\t  down_indent\n\t  line = parse_elif(line)\n\t  up_indent\n\twhen /^#\\s*else/\n\t  down_indent\n\t  line = parse_else(line)\n\t  up_indent\n\twhen /^#\\s*endif/\n\t  down_indent\n\t  line = parse_endif(line)\n\twhen /^#\\s*include\\s/\n\t  line = parse_include(line)\n\telse\n\t  line = nil\n\tend\n\tif( line && fout )\n\t  fout.print(line, \"     # #{line_number}\",$/)\n\tend\n      }\n    ensure\n      fin.close if fin\n      fout.close if fout\n    end\n  end\nend\n\nh2rb = H2RB.new($inc_dir, $inc_path, $insert_require)\nh2rb.parse($infilename, $recursive, $force, $conly)\n"
  },
  {
    "path": "ext/dl/handle.c",
    "content": "/* -*- C -*-\n * $Id$\n */\n\n#include <ruby.h>\n#include \"dl.h\"\n\nVALUE rb_cDLHandle;\n\nvoid\ndlhandle_free(struct dl_handle *dlhandle)\n{\n  if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) {\n    dlclose(dlhandle->ptr);\n  }\n}\n\nVALUE\nrb_dlhandle_close(VALUE self)\n{\n  struct dl_handle *dlhandle;\n\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  dlhandle->open = 0;\n  return INT2NUM(dlclose(dlhandle->ptr));\n}\n\nVALUE\nrb_dlhandle_s_allocate(VALUE klass)\n{\n  VALUE obj;\n  struct dl_handle *dlhandle;\n\n  obj = Data_Make_Struct(rb_cDLHandle, struct dl_handle, 0,\n\t\t\t dlhandle_free, dlhandle);\n  dlhandle->ptr  = 0;\n  dlhandle->open = 0;\n  dlhandle->enable_close = 0;\n\n  return obj;\n}\n\nVALUE\nrb_dlhandle_initialize(int argc, VALUE argv[], VALUE self)\n{\n  void *ptr;\n  struct dl_handle *dlhandle;\n  VALUE lib, flag;\n  char  *clib;\n  int   cflag;\n  const char *err;\n\n  switch (rb_scan_args(argc, argv, \"11\", &lib, &flag)) {\n  case 1:\n    clib = NIL_P(lib) ? NULL : StringValuePtr(lib);\n    cflag = RTLD_LAZY | RTLD_GLOBAL;\n    break;\n  case 2:\n    clib = NIL_P(lib) ? NULL : StringValuePtr(lib);\n    cflag = NUM2INT(flag);\n    break;\n  default:\n    rb_bug(\"rb_dlhandle_new\");\n  }\n\n  ptr = dlopen(clib, cflag);\n#if defined(HAVE_DLERROR)\n  if (!ptr && (err = dlerror())) {\n    rb_raise(rb_eRuntimeError, \"%s\", err);\n  }\n#else\n  if (!ptr) {\n    err = dlerror();\n    rb_raise(rb_eRuntimeError, \"%s\", err);\n  }\n#endif\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) {\n    dlclose(dlhandle->ptr);\n  }\n  dlhandle->ptr = ptr;\n  dlhandle->open = 1;\n  dlhandle->enable_close = 0;\n\n  if (rb_block_given_p()) {\n    rb_ensure(rb_yield, self, rb_dlhandle_close, self);\n  }\n\n  return Qnil;\n}\n\nVALUE\nrb_dlhandle_enable_close(VALUE self)\n{\n  struct dl_handle *dlhandle;\n\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  dlhandle->enable_close = 1;\n  return Qnil;\n}\n\nVALUE\nrb_dlhandle_disable_close(VALUE self)\n{\n  struct dl_handle *dlhandle;\n\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  dlhandle->enable_close = 0;\n  return Qnil;\n}\n\nVALUE\nrb_dlhandle_to_i(VALUE self)\n{\n  struct dl_handle *dlhandle;\n\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  return DLLONG2NUM(dlhandle);\n}\n\nVALUE\nrb_dlhandle_to_ptr(VALUE self)\n{\n  struct dl_handle *dlhandle;\n\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  return rb_dlptr_new(dlhandle, sizeof(dlhandle), 0);\n}\n\nVALUE\nrb_dlhandle_sym(int argc, VALUE argv[], VALUE self)\n{\n  VALUE sym, type;\n  void (*func)();\n  VALUE val;\n  struct dl_handle *dlhandle;\n  void *handle;\n  const char *name, *stype;\n  const char *err;\n\n  rb_secure(2);\n  if (rb_scan_args(argc, argv, \"11\", &sym, &type) == 2) {\n    SafeStringValue(type);\n    stype = StringValuePtr(type);\n  }\n  else{\n    stype = NULL;\n  }\n\n  if (sym == Qnil) {\n#if defined(RTLD_NEXT)\n    name = RTLD_NEXT;\n#else\n    name = NULL;\n#endif\n  }\n  else{\n    SafeStringValue(sym);\n    name = StringValuePtr(sym);\n  }\n\n  Data_Get_Struct(self, struct dl_handle, dlhandle);\n  if (!dlhandle->open) {\n    rb_raise(rb_eRuntimeError, \"closed handle\");\n  }\n  handle = dlhandle->ptr;\n\n  func = dlsym(handle, name);\n#if defined(HAVE_DLERROR)\n  if (!func && (err = dlerror()))\n#else\n  if (!func)\n#endif\n  {\n#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__)\n    {\n      int  len = strlen(name);\n      char *name_a = (char*)dlmalloc(len+2);\n      strcpy(name_a, name);\n      name_a[len]   = 'A';\n      name_a[len+1] = '\\0';\n      func = dlsym(handle, name_a);\n      dlfree(name_a);\n#if defined(HAVE_DLERROR)\n      if (!func && (err = dlerror()))\n#else\n      if (!func)\n#endif\n      {\n\trb_raise(rb_eRuntimeError, \"unknown symbol \\\"%sA\\\"\", name);\n      }\n    }\n#else\n    rb_raise(rb_eRuntimeError, \"unknown symbol \\\"%s\\\"\", name);\n#endif\n  }\n  val = rb_dlsym_new(func, name, stype);\n\n  return val;\n}\n\nvoid\nInit_dlhandle()\n{\n  rb_cDLHandle = rb_define_class_under(rb_mDL, \"Handle\", rb_cObject);\n  rb_define_alloc_func(rb_cDLHandle, rb_dlhandle_s_allocate);\n  rb_define_method(rb_cDLHandle, \"initialize\", rb_dlhandle_initialize, -1);\n  rb_define_method(rb_cDLHandle, \"to_i\", rb_dlhandle_to_i, 0);\n  rb_define_method(rb_cDLHandle, \"to_ptr\", rb_dlhandle_to_ptr, 0);\n  rb_define_method(rb_cDLHandle, \"close\", rb_dlhandle_close, 0);\n  rb_define_method(rb_cDLHandle, \"sym\",  rb_dlhandle_sym, -1);\n  rb_define_method(rb_cDLHandle, \"[]\",  rb_dlhandle_sym, -1);\n  rb_define_method(rb_cDLHandle, \"disable_close\", rb_dlhandle_disable_close, 0);\n  rb_define_method(rb_cDLHandle, \"enable_close\", rb_dlhandle_enable_close, 0);\n}\n"
  },
  {
    "path": "ext/dl/install.rb",
    "content": "require 'mkmf'\nrequire 'ftools'\n\nSO_LIBS = [\"dl.so\"]\n\n$ruby_version = CONFIG['MAJOR'] + \".\" + CONFIG['MINOR']\n$prefix = CONFIG['prefix']\n$libdir = File.join($prefix,'lib')\n$rubylibdir = File.join($libdir, 'ruby', $ruby_version)\n$arch = CONFIG['arch']\n$archdir = File.join($rubylibdir, $arch)\n\ndef find(dir, match = /./)\n  Dir.chdir(dir)\n  files = []\n  Dir.new(\".\").each{|file|\n    if( file != \".\" && file != \"..\" )\n      case File.ftype(file)\n      when \"file\"\n\tif( file =~ match )\n\t  files.push(File.join(dir,file))\n\tend\n      when \"directory\"\n\tfiles += find(file, match).collect{|f| File.join(dir,f)}\n      end\n    end\n  }\n  Dir.chdir(\"..\")\n  return files\nend\n\ndef install()\n  rb_files = find(File.join(\".\",\"lib\"), /.rb$/)\n\n  SO_LIBS.each{|f|\n    File.makedirs($rubylibdir, \"#{$archdir}\")\n    File.install(f, File.join($archdir,f), 0555, true)\n  }\n\n  rb_files.each{|f|\n    origfile = f\n    instfile = File.join($rubylibdir, origfile.sub(\"./lib/\",\"\"))\n    instdir  = File.dirname(instfile)\n    File.makedirs(instdir)\n    File.install(origfile, instfile, 0644, true)\n  }\nend\n\ninstall()\n"
  },
  {
    "path": "ext/dl/lib/dl/import.rb",
    "content": "# -*- ruby -*-\n\nrequire 'dl'\nrequire 'dl/types'\n\nmodule DL\n  module Importable\n    LIB_MAP = {}\n\n    module Internal\n      def init_types()\n\t@types ||= ::DL::Types.new\n      end\n\n      def init_sym()\n\t@SYM ||= {}\n      end\n\n      def [](name)\n\treturn @SYM[name.to_s][0]\n      end\n\n      def dlload(*libnames)\n\tif( !defined?(@LIBS) )\n\t  @LIBS = []\n\tend\n\tlibnames.each{|libname|\n\t  if( !LIB_MAP[libname] )\n\t    LIB_MAP[libname] = DL.dlopen(libname)\n\t  end\n\t  @LIBS.push(LIB_MAP[libname])\n\t}\n      end\n      alias dllink :dlload\n\n      def parse_cproto(proto)\n\tproto = proto.gsub(/\\s+/, \" \").strip\n\tcase proto\n\twhen /^([\\d\\w\\*_\\s]+)\\(([\\d\\w\\*_\\s\\,\\[\\]]*)\\)$/\n\t  ret = $1\n\t  args = $2.strip()\n\t  ret = ret.split(/\\s+/)\n\t  args = args.split(/\\s*,\\s*/)\n\t  func = ret.pop()\n\t  if( func =~ /^\\*/ )\n\t    func.gsub!(/^\\*+/,\"\")\n\t    ret.push(\"*\")\n\t  end\n\t  ret  = ret.join(\" \")\n\t  return [func, ret, args]\n\telse\n\t  raise(RuntimeError,\"can't parse the function prototype: #{proto}\")\n\tend\n      end\n\n      # example:\n      #   extern \"int strlen(char*)\"\n      #\n      def extern(proto)\n\tfunc,ret,args = parse_cproto(proto)\n\treturn import(func, ret, args)\n      end\n\n      # example:\n      #   callback \"int method_name(int, char*)\"\n      #\n      def callback(proto)\n\tfunc,ret,args = parse_cproto(proto)\n\n\tinit_types()\n\tinit_sym()\n\n\trty,renc,rdec = @types.encode_return_type(ret)\n        if( !rty )\n          raise(TypeError, \"unsupported type: #{ret}\")\n        end\n\tty,enc,dec = encode_argument_types(args)\n\tsymty = rty + ty\n\n\tmodule_eval(\"module_function :#{func}\")\n\tsym = module_eval([\n\t  \"DL::callback(\\\"#{symty}\\\"){|*args|\",\n\t  \"  sym,rdec,enc,dec  = @SYM['#{func}']\",\n\t  \"  args = enc.call(args) if enc\",\n\t  \"  r,rs = #{func}(*args)\",\n\t  \"  r  = renc.call(r) if rdec\",\n\t  \"  rs = dec.call(rs) if (dec && rs)\",\n\t  \"  @retval = r\",\n\t  \"  @args   = rs\",\n\t  \"  r\",\n\t  \"}\",\n\t].join(\"\\n\"))\n\n\t@SYM[func] = [sym,rdec,enc,dec]\n\n\treturn sym\n      end\n\n      # example:\n      #  typealias(\"uint\", \"unsigned int\")\n      #\n      def typealias(alias_type, ty1, enc1=nil, dec1=nil, ty2=nil, enc2=nil, dec2=nil)\n\tinit_types()\n\t@types.typealias(alias_type, ty1, enc1, dec1,\n                                     ty2||ty1, enc2, dec2)\n      end\n\n      # example:\n      #  symbol \"foo_value\"\n      #  symbol \"foo_func\", \"IIP\"\n      #\n      def symbol(name, ty = nil)\n\tsym = nil\n\t@LIBS.each{|lib|\n\t  begin\n\t    if( ty )\n\t      sym = lib[name, ty]\n\t    else\n\t      sym = lib[name]\n\t    end\n\t  rescue\n\t    next\n\t  end\n\t}\n\tif( !sym )\n\t  raise(RuntimeError, \"can't find the symbol `#{name}'\")\n\tend\n\treturn sym\n      end\n\n      # example:\n      #   import(\"get_length\", \"int\", [\"void*\", \"int\"])\n      #\n      def import(name, rettype, argtypes = nil)\n\tinit_types()\n\tinit_sym()\n\n\trty,_,rdec = @types.encode_return_type(rettype)\n        if( !rty )\n          raise(TypeError, \"unsupported type: #{rettype}\")\n        end\n\tty,enc,dec = encode_argument_types(argtypes)\n\tsymty = rty + ty\n\n\tsym = symbol(name, symty)\n\n\tmname = name.dup\n\tif( ?A <= mname[0] && mname[0] <= ?Z )\n\t  mname[0,1] = mname[0,1].downcase\n\tend\n\t@SYM[mname] = [sym,rdec,enc,dec]\n\t\n\tmodule_eval [\n\t  \"def #{mname}(*args)\",\n\t  \"  sym,rdec,enc,dec  = @SYM['#{mname}']\",\n\t  \"  args = enc.call(args) if enc\",\n\t  if( $DEBUG )\n\t    \"  p \\\"[DL] call #{mname} with \\#{args.inspect}\\\"\"\n\t  else\n\t    \"\"\n\t  end,\n\t  \"  r,rs = sym.call(*args)\",\n\t  if( $DEBUG )\n\t    \"  p \\\"[DL] retval=\\#{r.inspect} args=\\#{rs.inspect}\\\"\"\n\t  else\n\t    \"\"\n\t  end,\n\t  \"  r  = rdec.call(r) if rdec\",\n\t  \"  rs = dec.call(rs) if dec\",\n\t  \"  @retval = r\",\n\t  \"  @args   = rs\",\n\t  \"  return r\",\n\t  \"end\",\n\t  \"module_function :#{mname}\",\n\t].join(\"\\n\")\n\n\treturn sym\n      end\n\n      def _args_\n\treturn @args\n      end\n\n      def _retval_\n\treturn @retval\n      end\n\n      def encode_argument_types(tys)\n\tinit_types()\n\tencty = []\n\tenc = nil\n\tdec = nil\n\ttys.each_with_index{|ty,idx|\n\t  ty,c1,c2 = @types.encode_argument_type(ty)\n          if( !ty )\n            raise(TypeError, \"unsupported type: #{ty}\")\n          end\n\t  encty.push(ty)\n\t  if( enc )\n\t    if( c1 )\n\t      conv1 = enc\n\t      enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v}\n\t    end\n\t  else\n\t    if( c1 )\n\t      enc = proc{|v| v[idx] = c1.call(v[idx]); v}\n\t    end\n\t  end\n\t  if( dec )\n\t    if( c2 )\n\t      conv2 = dec\n\t      dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v}\n\t    end\n\t  else\n\t    if( c2 )\n\t      dec = proc{|v| v[idx] = c2.call(v[idx]); v}\n\t    end\n\t  end\n\t}\n\treturn [encty.join, enc, dec]\n      end\n    end # end of Internal\n    include Internal\n  end # end of Importable\nend\n"
  },
  {
    "path": "ext/dl/lib/dl/struct.rb",
    "content": "# -*- ruby -*-\n\nrequire 'dl'\nrequire 'dl/import'\n\nmodule DL\n  module Importable\n    module Internal\n      def define_struct(contents)\n\tinit_types()\n\tStruct.new(@types, contents)\n      end\n      alias struct define_struct\n\n      def define_union(contents)\n\tinit_types()\n\tUnion.new(@types, contents)\n      end\n      alias union define_union\n\n      class Memory\n\tdef initialize(ptr, names, ty, len, enc, dec)\n\t  @ptr = ptr\n\t  @names = names\n\t  @ty    = ty\n\t  @len   = len\n\t  @enc   = enc\n\t  @dec   = dec\n\n\t  # define methods\n\t  @names.each{|name|\n\t    instance_eval [\n\t      \"def #{name}\",\n\t      \"  v = @ptr[\\\"#{name}\\\"]\",\n\t      \"  if( @len[\\\"#{name}\\\"] )\",\n\t      \"    v = v.collect{|x| @dec[\\\"#{name}\\\"] ? @dec[\\\"#{name}\\\"].call(x) : x }\",\n              \"  else\",\n\t      \"    v = @dec[\\\"#{name}\\\"].call(v) if @dec[\\\"#{name}\\\"]\",\n\t      \"  end\",\n\t      \"  return v\",\n\t      \"end\",\n\t      \"def #{name}=(v)\",\n\t      \"  if( @len[\\\"#{name}\\\"] )\",\n\t      \"    v = v.collect{|x| @enc[\\\"#{name}\\\"] ? @enc[\\\"#{name}\\\"].call(x) : x }\",\n\t      \"  else\",\n\t      \"    v = @enc[\\\"#{name}\\\"].call(v) if @enc[\\\"#{name}\\\"]\",\n              \"  end\",\n\t      \"  @ptr[\\\"#{name}\\\"] = v\",\n\t      \"  return v\",\n\t      \"end\",\n\t    ].join(\"\\n\")\n\t  }\n\tend\n\n\tdef to_ptr\n\t  return @ptr\n\tend\n\n\tdef size\n\t  return @ptr.size\n\tend\n      end\n\n      class Struct\n\tdef initialize(types, contents)\n\t  @names = []\n\t  @ty   = {}\n\t  @len  = {}\n\t  @enc  = {}\n\t  @dec  = {}\n\t  @size = 0\n\t  @tys  = \"\"\n\t  @types = types\n\t  parse(contents)\n\tend\n\n\tdef size\n\t  return @size\n\tend\n\n\tdef members\n\t  return @names\n\tend\n\n\t# ptr must be a PtrData object.\n\tdef new(ptr)\n\t  ptr.struct!(@tys, *@names)\n\t  mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)\n\t  return mem\n\tend\n\n\tdef malloc(size = nil)\n\t  if( !size )\n\t    size = @size\n\t  end\n\t  ptr = DL::malloc(size)\n\t  return new(ptr)\n\tend\n\n\tdef parse(contents)\n\t  contents.each{|elem|\n\t    name,ty,num,enc,dec = parse_elem(elem)\n\t    @names.push(name)\n\t    @ty[name]  = ty\n\t    @len[name] = num\n\t    @enc[name] = enc\n\t    @dec[name] = dec\n\t    if( num )\n\t      @tys += \"#{ty}#{num}\"\n\t    else\n\t      @tys += ty\n\t    end\n\t  }\n\t  @size = DL.sizeof(@tys)\n\tend\n\t\n\tdef parse_elem(elem)\n\t  elem.strip!\n\t  case elem\n\t  when /^([\\w\\d_\\*]+)([\\*\\s]+)([\\w\\d_]+)$/\n\t    ty = ($1 + $2).strip\n\t    name = $3\n\t    num = nil;\n\t  when /^([\\w\\d_\\*]+)([\\*\\s]+)([\\w\\d_]+)\\[(\\d+)\\]$/\n\t    ty = ($1 + $2).strip\n\t    name = $3\n\t    num = $4.to_i\n\t  else\n\t    raise(RuntimeError, \"invalid element: #{elem}\")\n\t  end\n\t  ty,enc,dec = @types.encode_struct_type(ty)\n          if( !ty )\n            raise(TypeError, \"unsupported type: #{ty}\")\n          end\n\t  return [name,ty,num,enc,dec]\n\tend\n      end  # class Struct\n      \n      class Union < Struct\n\tdef new\n\t  ptr = DL::malloc(@size)\n\t  ptr.union!(@tys, *@names)\n\t  mem = Memory.new(ptr, @names, @ty, @len, @enc, @dec)\n\t  return mem\n\tend\n      end\n    end  # module Internal\n  end  # module Importable\nend  # module DL\n"
  },
  {
    "path": "ext/dl/lib/dl/types.rb",
    "content": "# -*- ruby -*-\n\nrequire 'dl'\n\nmodule DL\n  class Types\n    TYPES = [\n      # FORMAT:\n      # [\"alias name\",\n      #  \"type name\", encoding_method, decoding_method,   for function prototypes\n      #  \"type name\", encoding_method, decoding_method]   for structures (not implemented)\n      \n      # for Windows\n      [\"DWORD\",  \"unsigned long\", nil, nil,\n                 \"unsigned long\", nil, nil],\n      [\"PDWORD\", \"unsigned long *\", nil, nil,\n                 \"unsigned long *\", nil, nil],\n      [\"WORD\",   \"unsigned short\", nil, nil,\n                 \"unsigned short\", nil, nil],\n      [\"PWORD\",  \"unsigned int *\", nil, nil,\n                 \"unsigned int *\", nil, nil],\n      [\"BYTE\",   \"unsigned char\",   nil, nil,\n                 \"unsigned char\", nil, nil],\n      [\"PBYTE\",  \"unsigned char *\", nil, nil,\n                 \"unsigned char *\", nil, nil],\n      [\"BOOL\",   \"ibool\", nil, nil,\n                 \"ibool\", nil, nil],\n      [\"ATOM\",   \"int\", nil, nil,\n                 \"int\", nil, nil],\n      [\"BYTE\",   \"unsigned char\", nil, nil,\n                 \"unsigned char\", nil, nil],\n      [\"PBYTE\",  \"unsigned char *\", nil, nil,\n                 \"unsigned char *\", nil, nil],\n      [\"UINT\",   \"unsigned int\", nil, nil,\n                 \"unsigned int\", nil, nil],\n      [\"ULONG\",  \"unsigned long\", nil, nil,\n                 \"unsigned long\", nil, nil],\n      [\"UCHAR\",  \"unsigned char\", nil, nil,\n                 \"unsigned char\", nil, nil],\n      [\"HANDLE\", \"unsigned long\", nil, nil,\n                 \"unsigned long\", nil, nil],\n      [\"PHANDLE\",\"void*\", nil, nil,\n                 \"void*\", nil, nil],\n      [\"PVOID\",  \"void*\", nil, nil,\n                 \"void*\", nil, nil],\n      [\"LPCSTR\", \"char*\", nil, nil,\n                 \"char*\", nil, nil],\n      [\"HDC\",    \"unsigned int\", nil, nil,\n                 \"unsigned int\", nil, nil],\n      [\"HWND\",   \"unsigned int\", nil, nil,\n                 \"unsigned int\", nil, nil],\n      \n      # Others\n      [\"uint\",   \"unsigned int\", nil, nil,\n                 \"unsigned int\", nil, nil],\n      [\"u_int\",  \"unsigned int\", nil, nil,\n                 \"unsigned int\", nil, nil],\n      [\"ulong\",  \"unsigned long\", nil, nil,\n                 \"unsigned long\", nil, nil],\n      [\"u_long\", \"unsigned long\", nil, nil,\n                 \"unsigned long\", nil, nil],\n\n      # DL::Importable primitive types\n      [\"ibool\",\n        \"I\",\n\tproc{|v| v ? 1 : 0},\n\tproc{|v| (v != 0) ? true : false},\n        \"I\",\n\tproc{|v| v ? 1 : 0 },\n\tproc{|v| (v != 0) ? true : false} ],\n      [\"cbool\",\n        \"C\",\n\tproc{|v| v ? 1 : 0},\n\tproc{|v| (v != 0) ? true : false},\n        \"C\",\n\tproc{|v,len| v ? 1 : 0},\n\tproc{|v,len| (v != 0) ? true : false}],\n      [\"lbool\",\n        \"L\",\n\tproc{|v| v ? 1 : 0},\n\tproc{|v| (v != 0) ? true : false},\n        \"L\",\n\tproc{|v,len| v ? 1 : 0},\n\tproc{|v,len| (v != 0) ? true : false}],\n      [\"unsigned char\",\n        \"C\",\n\tproc{|v| [v].pack(\"C\").unpack(\"c\")[0]},\n\tproc{|v| [v].pack(\"c\").unpack(\"C\")[0]},\n        \"C\",\n\tproc{|v| [v].pack(\"C\").unpack(\"c\")[0]},\n\tproc{|v| [v].pack(\"c\").unpack(\"C\")[0]}],\n      [\"unsigned short\",\n        \"H\",\n\tproc{|v| [v].pack(\"S\").unpack(\"s\")[0]},\n\tproc{|v| [v].pack(\"s\").unpack(\"S\")[0]},\n        \"H\",\n\tproc{|v| [v].pack(\"S\").unpack(\"s\")[0]},\n\tproc{|v| [v].pack(\"s\").unpack(\"S\")[0]}],\n      [\"unsigned int\",\n        \"I\",\n\tproc{|v| [v].pack(\"I\").unpack(\"i\")[0]},\n\tproc{|v| [v].pack(\"i\").unpack(\"I\")[0]},\n        \"I\",\n\tproc{|v| [v].pack(\"I\").unpack(\"i\")[0]},\n\tproc{|v| [v].pack(\"i\").unpack(\"I\")[0]}],\n      [\"unsigned long\",\n        \"L\",\n\tproc{|v| [v].pack(\"L\").unpack(\"l\")[0]},\n\tproc{|v| [v].pack(\"l\").unpack(\"L\")[0]},\n        \"L\",\n\tproc{|v| [v].pack(\"L\").unpack(\"l\")[0]},\n\tproc{|v| [v].pack(\"l\").unpack(\"L\")[0]}],\n      [\"unsigned char ref\",\n        \"c\",\n\tproc{|v| [v].pack(\"C\").unpack(\"c\")[0]},\n\tproc{|v| [v].pack(\"c\").unpack(\"C\")[0]},\n\tnil, nil, nil],\n      [\"unsigned int ref\",\n        \"i\",\n\tproc{|v| [v].pack(\"I\").unpack(\"i\")[0]},\n\tproc{|v| [v].pack(\"i\").unpack(\"I\")[0]},\n\tnil, nil, nil],\n      [\"unsigned long ref\",\n        \"l\",\n\tproc{|v| [v].pack(\"L\").unpack(\"l\")[0]},\n\tproc{|v| [v].pack(\"l\").unpack(\"L\")[0]},\n\tnil, nil, nil],\n      [\"char ref\",  \"c\", nil, nil,\n                    nil, nil, nil],\n      [\"short ref\", \"h\", nil, nil,\n                    nil, nil, nil],\n      [\"int ref\",   \"i\", nil, nil,\n                    nil, nil, nil],\n      [\"long ref\",  \"l\", nil, nil,\n                    nil, nil, nil],\n      [\"float ref\", \"f\", nil, nil,\n                    nil, nil, nil],\n      [\"double ref\",\"d\", nil, nil,\n                    nil, nil, nil],\n      [\"char\",   \"C\", nil, nil,\n                 \"C\", nil, nil],\n      [\"short\",  \"H\", nil, nil,\n                 \"H\", nil, nil],\n      [\"int\",    \"I\", nil, nil,\n                 \"I\", nil, nil],\n      [\"long\",   \"L\", nil, nil,\n                 \"L\", nil, nil],\n      [\"float\",  \"F\", nil, nil,\n                 \"F\", nil, nil],\n      [\"double\", \"D\", nil, nil,\n                 \"D\", nil, nil],\n      [/^char\\s*\\*$/,\"s\",nil, nil,\n                     \"S\",nil, nil],\n      [/^const char\\s*\\*$/,\"S\",nil, nil,\n                           \"S\",nil, nil],\n      [/^.+\\*$/,   \"P\", nil, nil,\n                   \"P\", nil, nil],\n      [/^.+\\[\\]$/, \"a\", nil, nil,\n                   \"a\", nil, nil],\n      [\"void\",   \"0\", nil, nil,\n                 nil, nil, nil],\n    ]\n\n    def initialize\n      init_types()\n    end\n\n    def typealias(ty1, ty2, enc=nil, dec=nil, ty3=nil, senc=nil, sdec=nil)\n      @TYDEFS.unshift([ty1, ty2, enc, dec, ty3, senc, sdec])\n    end\n\n    def init_types\n      @TYDEFS = TYPES.dup\n    end\n\n    def encode_argument_type(alias_type)\n      proc_encode = nil\n      proc_decode = nil\n      @TYDEFS.each{|aty,ty,enc,dec,_,_,_|\n\tif( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) )\n\t  alias_type = alias_type.gsub(aty,ty) if ty\n          alias_type.strip! if alias_type\n\t  if( proc_encode )\n\t    if( enc )\n\t      conv1 = proc_encode\n\t      proc_encode = proc{|v| enc.call(conv1.call(v))}\n\t    end\n\t  else\n\t    if( enc )\n\t      proc_encode = enc\n\t    end\n\t  end\n\t  if( proc_decode )\n\t    if( dec )\n\t      conv2 = proc_decode\n\t      proc_decode = proc{|v| dec.call(conv2.call(v))}\n\t    end\n\t  else\n\t    if( dec )\n\t      proc_decode = dec\n\t    end\n\t  end\n\tend\n      }\n      return [alias_type, proc_encode, proc_decode]\n    end\n\n    def encode_return_type(ty)\n      ty, enc, dec = encode_argument_type(ty)\n      return [ty, enc, dec]\n    end\n\n    def encode_struct_type(alias_type)\n      proc_encode = nil\n      proc_decode = nil\n      @TYDEFS.each{|aty,_,_,_,ty,enc,dec|\n\tif( (aty.is_a?(Regexp) && (aty =~ alias_type)) || (aty == alias_type) )\n\t  alias_type = alias_type.gsub(aty,ty) if ty\n          alias_type.strip! if alias_type\n\t  if( proc_encode )\n\t    if( enc )\n\t      conv1 = proc_encode\n\t      proc_encode = proc{|v| enc.call(conv1.call(v))}\n\t    end\n\t  else\n\t    if( enc )\n\t      proc_encode = enc\n\t    end\n\t  end\n\t  if( proc_decode )\n\t    if( dec )\n\t      conv2 = proc_decode\n\t      proc_decode = proc{|v| dec.call(conv2.call(v))}\n\t    end\n\t  else\n\t    if( dec )\n\t      proc_decode = dec\n\t    end\n\t  end\n\tend\n      }\n      return [alias_type, proc_encode, proc_decode]\n    end\n  end # end of Types\nend\n"
  },
  {
    "path": "ext/dl/lib/dl/win32.rb",
    "content": "# -*- ruby -*-\n\nrequire 'dl'\n\nclass Win32API\n  DLL = {}\n\n  def initialize(dllname, func, import, export = \"0\")\n    prototype = (export + import.to_s).tr(\"VPpNnLlIi\", \"0SSI\").sub(/^(.)0*$/, '\\1')\n    handle = DLL[dllname] ||= DL::Handle.new(dllname)\n    @sym = handle.sym(func, prototype)\n  end\n\n  def call(*args)\n    import = @sym.proto.split(\"\", 2)[1]\n    args.each_with_index do |x, i|\n      args[i] = nil if x == 0 and import[i] == ?S\n      args[i], = [x].pack(\"I\").unpack(\"i\") if import[i] == ?I\n    end\n    ret, = @sym.call(*args)\n    return ret || 0\n  end\n\n  alias Call call\nend\n"
  },
  {
    "path": "ext/dl/mkcall.rb",
    "content": "# -*- ruby -*-\n\nrequire 'mkmf'\n$:.unshift File.dirname(__FILE__)\nrequire 'type'\nrequire 'dlconfig'\n\ndef output_arg(x,i)\n  \"args[#{i}].#{DLTYPE[x][:stmem]}\"\nend\n\ndef output_args(types)\n  t = []\n  types[1..-1].each_with_index{|x,i| t.push(output_arg(x,i))}\n  t.join(\",\")\nend\n\ndef output_callfunc(types)\n  t = types[0]\n  stmem = DLTYPE[t][:stmem]\n  ctypes = types2ctypes(types)\n  if( t == VOID )\n    callstm = \"(*f)(#{output_args(types)})\"\n  else\n    callstm = \"ret.#{stmem} = (*f)(#{output_args(types)})\"\n  end\n  [ \"{\",\n    \"#{ctypes[0]} (*f)(#{ctypes[1..-1].join(',')}) = func;\",\n    \"#{callstm};\",\n    \"}\"].join(\" \")\nend\n\ndef output_case(types)\n  num = types2num(types)\n  callfunc_stm = output_callfunc(types)\n<<EOF\n  case #{num}:\n#ifdef DEBUG\n    printf(\"#{callfunc_stm}\\\\n\");\n#endif\n    #{callfunc_stm};\n    break;\nEOF\nend\n\ndef rec_output(types = [VOID])\n  print output_case(types)\n  if( types.length <= MAX_ARG )\n    DLTYPE.keys.sort.each{|t|\n      if( t != VOID && DLTYPE[t][:sym] )\n\trec_output(types + [t])\n      end\n    }\n  end\nend\n\nDLTYPE.keys.sort.each{|t|\n  if( DLTYPE[t][:sym] )\n    $stderr.printf(\"  #{DLTYPE[t][:ctype]}\\n\")\n    rec_output([t])\n  end\n}\n"
  },
  {
    "path": "ext/dl/mkcallback.rb",
    "content": "# -*- ruby -*-\n\nrequire 'mkmf'\n$:.unshift File.dirname(__FILE__)\nrequire 'type'\nrequire 'dlconfig'\n\ndef mkfunc(rettype, fnum, argc)\n  args = (0..(argc-1)).collect{|i| \"long arg#{i}\"}.join(\", \")\n\n  subst_code = (0..(argc-1)).collect{|i|\n    \"  buff[#{i.to_s}] = arg#{i.to_s};\"\n  }.join(\"\\n\")\n\n  ret_code =\n    if( DLTYPE[rettype][:c2rb] )\n      \"  return #{DLTYPE[rettype][:rb2c]['retval']};\"\n    else\n      \"  /* no return value */\"\n    end\n\n  code = [\n    \"static #{DLTYPE[rettype][:ctype]}\",\n    \"rb_dl_callback_func_#{rettype.to_s}_#{fnum.to_s}(#{args})\",\n    \"{\",\n    \"  VALUE retval, proto, proc, obj;\",\n    \"  VALUE argv[#{argc.to_s}];\",\n    \"  int  argc;\",\n    \"  long buff[#{argc.to_s}];\",\n    \"\",\n    subst_code,\n    \"\",\n    \"  obj = rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(#{rettype.to_s}),INT2NUM(#{fnum.to_s})));\",\n    \"  if(NIL_P(obj))\",\n    \"    rb_raise(rb_eDLError, \\\"callback function does not exist in DL::FuncTable\\\");\",\n    \"  Check_Type(obj, T_ARRAY);\",\n    \"  proto = rb_ary_entry(obj, 0);\",\n    \"  proc  = rb_ary_entry(obj, 1);\",\n    \"  Check_Type(proto, T_STRING);\",\n    \"  if( RSTRING(proto)->len >= #{argc.to_s} )\",\n    \"    rb_raise(rb_eArgError, \\\"too many arguments\\\");\",\n    \"  rb_dl_scan_callback_args(buff, RSTRING(proto)->ptr, &argc, argv);\",\n    \"  retval = rb_funcall2(proc, id_call, argc, argv);\",\n    \"\",\n    ret_code,\n    \"}\",\n  ].join(\"\\n\")\n\n  return code\nend\n\nDLTYPE.keys.sort.each{|t|\n  for n in 0..(MAX_CALLBACK - 1)\n    print(mkfunc(t, n, 15), \"\\n\\n\")\n  end\n}\n"
  },
  {
    "path": "ext/dl/mkcbtable.rb",
    "content": "# -*- ruby -*-\n\nrequire 'mkmf'\n$:.unshift File.dirname(__FILE__)\nrequire 'type'\nrequire 'dlconfig'\n\ndef mktable(rettype, fnum, argc)\n  code =\n    \"rb_dl_callback_table[#{rettype}][#{fnum}] = &rb_dl_callback_func_#{rettype.to_s}_#{fnum};\"\n  return code\nend\n\nDLTYPE.keys.sort.each{|t|\n  for n in 0..(MAX_CALLBACK - 1)\n    print(mktable(t, n, 15), \"\\n\")\n  end\n}\n"
  },
  {
    "path": "ext/dl/ptr.c",
    "content": "/* -*- C -*-\n * $Id$\n */\n\n#include <ruby.h>\n#include <ctype.h>\n#include \"st.h\"\n#include \"dl.h\"\n\nVALUE rb_cDLPtrData;\nVALUE rb_mDLMemorySpace;\nstatic st_table* st_memory_table;\n\n#ifndef T_SYMBOL\n# define T_SYMBOL T_FIXNUM\n#endif\n\nstatic void\nrb_dlmem_delete(void *ptr)\n{\n  rb_secure(4);\n  st_delete(st_memory_table, (st_data_t*)&ptr, NULL);\n}\n\nstatic void\nrb_dlmem_aset(void *ptr, VALUE obj)\n{\n  if (obj == Qnil) {\n    rb_dlmem_delete(ptr);\n  }\n  else{\n    st_insert(st_memory_table, (st_data_t)ptr, (st_data_t)obj);\n  }\n}\n\nstatic VALUE\nrb_dlmem_aref(void *ptr)\n{\n  VALUE val;\n\n  if(!st_lookup(st_memory_table, (st_data_t)ptr, &val)) return Qnil;\n  return val == Qundef ? Qnil : val;\n}\n\nvoid\ndlptr_free(struct ptr_data *data)\n{\n  if (data->ptr) {\n    DEBUG_CODE({\n      printf(\"dlptr_free(): removing the pointer `0x%x' from the MemorySpace\\n\",\n\t     data->ptr);\n    });\n    rb_dlmem_delete(data->ptr);\n    if (data->free) {\n      DEBUG_CODE({\n\tprintf(\"dlptr_free(): 0x%x(data->ptr:0x%x)\\n\",data->free,data->ptr);\n      });\n      (*(data->free))(data->ptr);\n    }\n  }\n  if (data->stype) dlfree(data->stype);\n  if (data->ssize) dlfree(data->ssize);\n  if (data->ids) dlfree(data->ids);\n}\n\nvoid\ndlptr_init(VALUE val)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(val, struct ptr_data, data);\n  DEBUG_CODE({\n    printf(\"dlptr_init(): add the pointer `0x%x' to the MemorySpace\\n\",\n\t   data->ptr);\n  });\n  rb_dlmem_aset(data->ptr, val);\n  OBJ_TAINT(val);\n}\n\nVALUE\nrb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)\n{\n  struct ptr_data *data;\n  VALUE val;\n\n  rb_secure(4);\n  if (ptr) {\n    val = rb_dlmem_aref(ptr);\n    if (val == Qnil) {\n      val = Data_Make_Struct(klass, struct ptr_data,\n\t\t\t     0, dlptr_free, data);\n      data->ptr = ptr;\n      data->free = func;\n      data->ctype = DLPTR_CTYPE_UNKNOWN;\n      data->stype = NULL;\n      data->ssize = NULL;\n      data->slen = 0;\n      data->size = size;\n      data->ids = NULL;\n      data->ids_num = 0;\n      dlptr_init(val);\n    }\n    else{\n      if (func) {\n\tData_Get_Struct(val, struct ptr_data, data);\n\tdata->free = func;\n      }\n    }\n  }\n  else{\n    val = Qnil;\n  }\n\n  return val;\n}\n\nVALUE\nrb_dlptr_new(void *ptr, long size, freefunc_t func)\n{\n  return rb_dlptr_new2(rb_cDLPtrData, ptr, size, func);\n}\n\nVALUE\nrb_dlptr_malloc(long size, freefunc_t func)\n{\n  void *ptr;\n\n  rb_secure(4);\n  ptr = dlmalloc((size_t)size);\n  memset(ptr,0,(size_t)size);\n  return rb_dlptr_new(ptr, size, func);\n}\n\nvoid *\nrb_dlptr2cptr(VALUE val)\n{\n  struct ptr_data *data;\n  void *ptr;\n\n  if (rb_obj_is_kind_of(val, rb_cDLPtrData)) {\n    Data_Get_Struct(val, struct ptr_data, data);\n    ptr = data->ptr;\n  }\n  else if (val == Qnil) {\n    ptr = NULL;\n  }\n  else{\n    rb_raise(rb_eTypeError, \"DL::PtrData was expected\");\n  }\n    \n  return ptr;\n}\n\nstatic VALUE\nrb_dlptr_s_allocate(VALUE klass)\n{\n  VALUE obj;\n  struct ptr_data *data;\n\n  rb_secure(4);\n  obj = Data_Make_Struct(klass, struct ptr_data, 0, dlptr_free, data);\n  data->ptr = 0;\n  data->free = 0;\n  data->ctype = DLPTR_CTYPE_UNKNOWN;\n  data->stype = NULL;\n  data->ssize = NULL;\n  data->slen  = 0;\n  data->size  = 0;\n  data->ids   = NULL;\n  data->ids_num = 0;\n\n  return obj;\n}\n\nstatic VALUE\nrb_dlptr_initialize(int argc, VALUE argv[], VALUE self)\n{\n  VALUE ptr, sym, size;\n  struct ptr_data *data;\n  void *p = NULL;\n  freefunc_t f = NULL;\n  long s = 0;\n\n  switch (rb_scan_args(argc, argv, \"12\", &ptr, &size, &sym)) {\n  case 1:\n    p = (void*)(DLNUM2LONG(rb_Integer(ptr)));\n    break;\n  case 2:\n    p = (void*)(DLNUM2LONG(rb_Integer(ptr)));\n    s = DLNUM2LONG(size);\n    break;\n  case 3:\n    p = (void*)(DLNUM2LONG(rb_Integer(ptr)));\n    s = DLNUM2LONG(size);\n    f = rb_dlsym2csym(sym);\n    break;\n  default:\n    rb_bug(\"rb_dlptr_initialize\");\n  }\n\n  if (p) {\n    Data_Get_Struct(self, struct ptr_data, data);\n    if (data->ptr && data->free) {\n      /* Free previous memory. Use of inappropriate initialize may cause SEGV. */\n      (*(data->free))(data->ptr);\n    }\n    data->ptr  = p;\n    data->size = s;\n    data->free = f;\n  }\n\n  return Qnil;\n}\n\nstatic VALUE\nrb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)\n{\n  VALUE size, sym, obj;\n  int   s;\n  freefunc_t f = NULL;\n\n  switch (rb_scan_args(argc, argv, \"11\", &size, &sym)) {\n  case 1:\n    s = NUM2INT(size);\n    break;\n  case 2:\n    s = NUM2INT(size);\n    f = rb_dlsym2csym(sym);\n    break;\n  default:\n    rb_bug(\"rb_dlptr_s_malloc\");\n  }\n\n  obj = rb_dlptr_malloc(s,f);\n\n  return obj;\n}\n\nVALUE\nrb_dlptr_to_i(VALUE self)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  return DLLONG2NUM(data->ptr);\n}\n\nVALUE\nrb_dlptr_ptr(VALUE self)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  return rb_dlptr_new(*((void**)(data->ptr)),0,0);\n}\n\nVALUE\nrb_dlptr_ref(VALUE self)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  return rb_dlptr_new(&(data->ptr),0,0);\n}\n\nVALUE\nrb_dlptr_null_p(VALUE self)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  return data->ptr ? Qfalse : Qtrue;\n}\n\nVALUE\nrb_dlptr_free_set(VALUE self, VALUE val)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n\n  data->free = DLFREEFUNC(rb_dlsym2csym(val));\n\n  return Qnil;\n}\n\nVALUE\nrb_dlptr_free_get(VALUE self)\n{\n  struct ptr_data *pdata;\n\n  Data_Get_Struct(self, struct ptr_data, pdata);\n\n  return rb_dlsym_new(pdata->free,\"(free)\",\"0P\");\n}\n\nVALUE\nrb_dlptr_to_array(int argc, VALUE argv[], VALUE self)\n{\n  struct ptr_data *data;\n  int n;\n  int i;\n  int t;\n  VALUE ary;\n  VALUE type, size;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n\n  switch (rb_scan_args(argc, argv, \"11\", &type, &size)) {\n  case 2:\n    t = StringValuePtr(type)[0];\n    n = NUM2INT(size);\n    break;\n  case 1:\n    t = StringValuePtr(type)[0];\n    switch (t) {\n    case 'C':\n      n = data->size;\n      break;\n    case 'H':\n      n = data->size / sizeof(short);\n      break;\n    case 'I':\n      n = data->size / sizeof(int);\n      break;\n    case 'L':\n      n = data->size / sizeof(long);\n      break;\n    case 'F':\n      n = data->size / sizeof(float);\n      break;\n    case 'D':\n      n = data->size / sizeof(double);\n      break;\n    case  'P': case 'p':\n      n = data->size / sizeof(void*);\n      break;\n    case 'S': case 's':\n      n = data->size / sizeof(char*);\n      break;\n    default:\n\tn = 0;\n    }\n    break;\n  default:\n    rb_bug(\"rb_dlptr_to_array\");\n  }\n\n  ary = rb_ary_new();\n\n  for (i=0; i < n; i++) {\n    switch (t) {\n    case 'C':\n      rb_ary_push(ary, INT2NUM(((char*)(data->ptr))[i]));\n      break;\n    case 'H':\n      rb_ary_push(ary, INT2NUM(((short*)(data->ptr))[i]));\n      break;\n    case 'I':\n      rb_ary_push(ary, INT2NUM(((int*)(data->ptr))[i]));\n      break;\n    case 'L':\n      rb_ary_push(ary, DLLONG2NUM(((long*)(data->ptr))[i]));\n      break;\n    case 'D':\n      rb_ary_push(ary, rb_float_new(((double*)(data->ptr))[i]));\n      break;\n    case 'F':\n      rb_ary_push(ary, rb_float_new(((float*)(data->ptr))[i]));\n      break;\n    case 'S':\n      {\n\tchar *str = ((char**)(data->ptr))[i];\n\tif (str) {\n\t  rb_ary_push(ary, rb_tainted_str_new2(str));\n\t}\n\telse{\n\t  rb_ary_push(ary, Qnil);\n\t}\n      }\n      break;\n    case 's':\n      {\n\tchar *str = ((char**)(data->ptr))[i];\n\tif (str) {\n\t  rb_ary_push(ary, rb_tainted_str_new2(str));\n\t  xfree(str);\n\t}\n\telse{\n\t  rb_ary_push(ary, Qnil);\n\t}\n      }\n      break;\n    case 'P':\n      rb_ary_push(ary, rb_dlptr_new(((void**)(data->ptr))[i],0,0));\n      break;\n    case 'p':\n      rb_ary_push(ary,\n\t\t  rb_dlptr_new(((void**)(data->ptr))[i],0,dlfree));\n      break;\n    }\n  }\n\n  return ary;\n}\n\n\nVALUE\nrb_dlptr_to_s(int argc, VALUE argv[], VALUE self)\n{\n  struct ptr_data *data;\n  VALUE arg1, val;\n  int len;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  switch (rb_scan_args(argc, argv, \"01\", &arg1)) {\n  case 0:\n    val = rb_tainted_str_new2((char*)(data->ptr));\n    break;\n  case 1:\n    len = NUM2INT(arg1);\n    val = rb_tainted_str_new((char*)(data->ptr), len);\n    break;\n  default:\n    rb_bug(\"rb_dlptr_to_s\");\n  }\n\n  return val;\n}\n\nVALUE\nrb_dlptr_to_str(int argc, VALUE argv[], VALUE self)\n{\n  struct ptr_data *data;\n  VALUE arg1, val;\n  int len;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  switch (rb_scan_args(argc, argv, \"01\", &arg1)) {\n  case 0:\n    val = rb_tainted_str_new((char*)(data->ptr),data->size);\n    break;\n  case 1:\n    len = NUM2INT(arg1);\n    val = rb_tainted_str_new((char*)(data->ptr), len);\n    break;\n  default:\n    rb_bug(\"rb_dlptr_to_str\");\n  }\n\n  return val;\n}\n\nVALUE\nrb_dlptr_inspect(VALUE self)\n{\n  struct ptr_data *data;\n  char str[1024];\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  snprintf(str, 1023, \"#<%s:0x%lx ptr=0x%lx size=%ld free=0x%lx>\",\n\t   rb_class2name(CLASS_OF(self)), data, data->ptr, data->size,\n\t   (long)data->free);\n  return rb_str_new2(str);\n}\n\nVALUE\nrb_dlptr_eql(VALUE self, VALUE other)\n{\n  void *ptr1, *ptr2;\n  ptr1 = rb_dlptr2cptr(self);\n  ptr2 = rb_dlptr2cptr(other);\n\n  return ptr1 == ptr2 ? Qtrue : Qfalse;\n}\n\nVALUE\nrb_dlptr_cmp(VALUE self, VALUE other)\n{\n  void *ptr1, *ptr2;\n  ptr1 = rb_dlptr2cptr(self);\n  ptr2 = rb_dlptr2cptr(other);\n  return DLLONG2NUM((long)ptr1 - (long)ptr2);\n}\n\nVALUE\nrb_dlptr_plus(VALUE self, VALUE other)\n{\n  void *ptr;\n  long num, size;\n\n  ptr = rb_dlptr2cptr(self);\n  size = RDLPTR(self)->size;\n  num = DLNUM2LONG(other);\n  return rb_dlptr_new((char *)ptr + num, size - num, 0);\n}\n\nVALUE\nrb_dlptr_minus(VALUE self, VALUE other)\n{\n  void *ptr;\n  long num, size;\n\n  ptr = rb_dlptr2cptr(self);\n  size = RDLPTR(self)->size;\n  num = DLNUM2LONG(other);\n  return rb_dlptr_new((char *)ptr - num, size + num, 0);\n}\n\nVALUE\nrb_dlptr_define_data_type(int argc, VALUE argv[], VALUE self)\n{\n  VALUE data_type, type, rest, vid;\n  struct ptr_data *data;\n  int i, t, num;\n  char *ctype;\n\n  rb_scan_args(argc, argv, \"11*\", &data_type, &type, &rest);\n  Data_Get_Struct(self, struct ptr_data, data);\n\n  if (argc == 1 || (argc == 2 && type == Qnil)) {\n    if (NUM2INT(data_type) == DLPTR_CTYPE_UNKNOWN) {\n      data->ctype = DLPTR_CTYPE_UNKNOWN;\n      data->slen = 0;\n      data->ids_num  = 0;\n      if (data->stype) {\n\tdlfree(data->stype);\n\tdata->stype = NULL;\n      }\n      if (data->ids) {\n\tdlfree(data->ids);\n\tdata->ids = NULL;\n      }\n      return Qnil;\n    }\n    else{\n      rb_raise(rb_eArgError, \"wrong arguments\");\n    }\n  }\n\n  t = NUM2INT(data_type);\n  StringValue(type);\n  Check_Type(rest, T_ARRAY);\n  num = RARRAY(rest)->len;\n  for (i=0; i<num; i++) {\n    rb_to_id(rb_ary_entry(rest,i));\n  }\n\n  data->ctype = t;\n  data->slen = num;\n  data->ids_num  = num;\n  if (data->stype) dlfree(data->stype);\n  data->stype = (char*)dlmalloc(sizeof(char) * num);\n  if (data->ssize) dlfree(data->ssize);\n  data->ssize = (int*)dlmalloc(sizeof(int) * num);\n  if (data->ids) dlfree(data->ids);\n  data->ids  = (ID*)dlmalloc(sizeof(ID) * data->ids_num);\n\n  ctype = StringValuePtr(type);\n  for (i=0; i<num; i++) {\n    vid = rb_ary_entry(rest,i);\n    data->ids[i] = rb_to_id(vid);\n    data->stype[i] = *ctype;\n    ctype ++;\n    if (isdigit(*ctype)) {\n      char *p, *d;\n      for (p=ctype; isdigit(*p); p++) ;\n      d = ALLOCA_N(char, p - ctype + 1);\n      strncpy(d, ctype, p - ctype);\n      d[p - ctype] = '\\0';\n      data->ssize[i] = atoi(d);\n      ctype = p;\n    }\n    else{\n      data->ssize[i] = 1;\n    }\n  }\n\n  if (*ctype) {\n    rb_raise(rb_eArgError, \"too few/many arguments\");\n  }\n\n  if (!data->size)\n    data->size = dlsizeof(RSTRING(type)->ptr);\n\n  return Qnil;\n}\n\nVALUE\nrb_dlptr_define_struct(int argc, VALUE argv[], VALUE self)\n{\n  VALUE *pass_argv;\n  int pass_argc, i;\n\n  pass_argc = argc + 1;\n  pass_argv = ALLOCA_N(VALUE, pass_argc);\n  pass_argv[0] = INT2FIX(DLPTR_CTYPE_STRUCT);\n  for (i=1; i<pass_argc; i++) {\n    pass_argv[i] = argv[i-1];\n  }\n  return rb_dlptr_define_data_type(pass_argc, pass_argv, self);\n}\n\nVALUE\nrb_dlptr_define_union(int argc, VALUE argv[], VALUE self)\n{\n  VALUE *pass_argv;\n  int pass_argc, i;\n\n  pass_argc = argc + 1;\n  pass_argv = ALLOCA_N(VALUE, pass_argc);\n  pass_argv[0] = INT2FIX(DLPTR_CTYPE_UNION);\n  for (i=1; i<pass_argc; i++) {\n    pass_argv[i] = argv[i-1];\n  }\n  return rb_dlptr_define_data_type(pass_argc, pass_argv, self);\n}\n\nVALUE\nrb_dlptr_get_data_type(VALUE self)\n{\n  struct ptr_data *data;\n\n  Data_Get_Struct(self, struct ptr_data, data);\n  if (data->stype)\n    return rb_assoc_new(INT2FIX(data->ctype),\n\t\t\trb_tainted_str_new(data->stype, data->slen));\n  else\n    return rb_assoc_new(INT2FIX(data->ctype), Qnil);\n}\n\nstatic VALUE\ncary2ary(void *ptr, char t, int len)\n{\n  VALUE ary;\n  VALUE elem;\n  int i;\n\n  if (len < 1)\n    return Qnil;\n\n  if (len == 1) {\n    switch (t) {\n    case 'I':\n      elem = INT2NUM(*((int*)ptr));\n      ptr = (char *)ptr + sizeof(int);\n      break;\n    case 'L':\n      elem = DLLONG2NUM(*((long*)ptr));\n      ptr = (char *)ptr + sizeof(long);\n      break;\n    case 'P':\n    case 'S':\n      elem = rb_dlptr_new(*((void**)ptr),0, 0);\n      ptr = (char *)ptr + sizeof(void*);\n      break;\n    case 'F':\n      elem = rb_float_new(*((float*)ptr));\n      ptr = (char *)ptr + sizeof(float);\n      break;\n    case 'D':\n      elem = rb_float_new(*((double*)ptr));\n      ptr = (char *)ptr + sizeof(double);\n      break;\n    case 'C':\n      elem = INT2NUM(*((char*)ptr));\n      ptr = (char *)ptr + sizeof(char);\n      break;\n    case 'H':\n      elem = INT2NUM(*((short*)ptr));\n      ptr = (char *)ptr + sizeof(short);\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unsupported type '%c'\", t);\n    }\n    return elem;\n  }\n\n  ary = rb_ary_new();\n  for (i=0; i < len; i++) {\n    switch (t) {\n    case 'I':\n      elem = INT2NUM(*((int*)ptr));\n      ptr = (char *)ptr + sizeof(int);\n      break;\n    case 'L':\n      elem = DLLONG2NUM(*((long*)ptr));\n      ptr = (char *)ptr + sizeof(long);\n      break;\n    case 'P':\n    case 'S':\n      elem = rb_dlptr_new(*((void**)ptr), 0, 0);\n      ptr = (char *)ptr + sizeof(void*);\n      break;\n    case 'F':\n      elem = rb_float_new(*((float*)ptr));\n      ptr = (char *)ptr + sizeof(float);\n      break;\n    case 'D':\n      elem = rb_float_new(*((float*)ptr));\n      ptr = (char *)ptr + sizeof(double);\n      break;\n    case 'C':\n      elem = INT2NUM(*((char*)ptr));\n      ptr = (char *)ptr + sizeof(char);\n      break;\n    case 'H':\n      elem = INT2NUM(*((short*)ptr));\n      ptr = (char *)ptr + sizeof(short);\n      break;\n    default:\n      rb_raise(rb_eDLTypeError, \"unsupported type '%c'\", t);\n    }\n    rb_ary_push(ary, elem);\n  }\n\n  return ary;\n}\n\nVALUE\nrb_dlptr_aref(int argc, VALUE argv[], VALUE self)\n{\n  VALUE key = Qnil, num = Qnil;\n  ID id;\n  struct ptr_data *data;\n  int i;\n  int offset;\n\n  if (rb_scan_args(argc, argv, \"11\", &key, &num) == 1) {\n    num = INT2NUM(0);\n  }\n\n  if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) {\n    VALUE pass[1];\n    pass[0] = num;\n    return rb_dlptr_to_str(1, pass, rb_dlptr_plus(self, key));\n  }\n  rb_to_id(key);\n  if (! (TYPE(key) == T_STRING || TYPE(key) == T_SYMBOL)) {\n    rb_raise(rb_eTypeError, \"the key must be a string or symbol\");\n  }\n\n  id = rb_to_id(key);\n  Data_Get_Struct(self, struct ptr_data, data);\n  offset = 0;\n  switch (data->ctype) {\n  case DLPTR_CTYPE_STRUCT:\n    for (i=0; i < data->ids_num; i++) {\n      switch (data->stype[i]) {\n      case 'I':\n        DLALIGN(data->ptr,offset,INT_ALIGN);\n        break;\n      case 'L':\n        DLALIGN(data->ptr,offset,LONG_ALIGN);\n        break;\n      case 'P':\n      case 'S':\n        DLALIGN(data->ptr,offset,VOIDP_ALIGN);\n        break;\n      case 'F':\n        DLALIGN(data->ptr,offset,FLOAT_ALIGN);\n        break;\n      case 'D':\n        DLALIGN(data->ptr,offset,DOUBLE_ALIGN);\n        break;\n      case 'C':\n        break;\n      case 'H':\n        DLALIGN(data->ptr,offset,SHORT_ALIGN);\n        break;\n      default:\n        rb_raise(rb_eDLTypeError, \"unsupported type '%c'\", data->stype[i]);\n      }\n      if (data->ids[i] == id) {\n\treturn cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);\n      }\n      switch (data->stype[i]) {\n      case 'I':\n\toffset += sizeof(int) * data->ssize[i];\n\tbreak;\n      case 'L':\n\toffset += sizeof(long) * data->ssize[i];\n\tbreak;\n      case 'P':\n      case 'S':\n\toffset += sizeof(void*) * data->ssize[i];\n\tbreak;\n      case 'F':\n\toffset += sizeof(float) * data->ssize[i];\n\tbreak;\n      case 'D':\n\toffset += sizeof(double) * data->ssize[i];\n\tbreak;\n      case 'C':\n\toffset += sizeof(char) * data->ssize[i];\n\tbreak;\n      case 'H':\n\toffset += sizeof(short) * data->ssize[i];\n\tbreak;\n      default:\n\trb_raise(rb_eDLTypeError, \"unsupported type '%c'\", data->stype[i]);\n      }\n    }\n    break;\n  case DLPTR_CTYPE_UNION:\n    for (i=0; i < data->ids_num; i++) {\n      if (data->ids[i] == id) {\n\treturn cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);\n      }\n    }\n    break;\n  } /* end of switch */\n\n  rb_raise(rb_eNameError, \"undefined key `%s' for %s\",\n\t   rb_id2name(id), rb_class2name(CLASS_OF(self)));\n\n  return Qnil;\n}\n\nstatic void *\nary2cary(char t, VALUE val, long *size)\n{\n  void *ptr;\n\n  if (TYPE(val) == T_ARRAY) {\n    ptr = rb_ary2cary(t, val, size);\n  }\n  else{\n    ptr = rb_ary2cary(t, rb_ary_new3(1, val), size);\n  }\n  return ptr;\n}\n\nVALUE\nrb_dlptr_aset(int argc, VALUE argv[], VALUE self)\n{\n  VALUE key = Qnil, num = Qnil, val = Qnil;\n  ID id;\n  struct ptr_data *data;\n  int i;\n  int offset;\n  long memsize;\n  void *memimg;\n\n  rb_secure(4);\n  switch (rb_scan_args(argc, argv, \"21\", &key, &num, &val)) {\n  case 2:\n    val = num;\n    num = Qnil;\n    break;\n  }\n\n  if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) {\n    void *dst, *src;\n    long len;\n\n    StringValue(val);\n    Data_Get_Struct(self, struct ptr_data, data);\n    dst = (void*)((long)(data->ptr) + DLNUM2LONG(key));\n    src = RSTRING(val)->ptr;\n    len = RSTRING(val)->len;\n    if (num == Qnil) {\n      memcpy(dst, src, len);\n    }\n    else{\n      long n = NUM2INT(num);\n      memcpy(dst, src, n < len ? n : len);\n      if (n > len) MEMZERO((char*)dst + len, char, n - len);\n    }\n    return val;\n  }\n\n  id = rb_to_id(key);\n  Data_Get_Struct(self, struct ptr_data, data);\n  switch (data->ctype) {\n  case DLPTR_CTYPE_STRUCT:\n    offset = 0;\n    for (i=0; i < data->ids_num; i++) {\n      switch (data->stype[i]) {\n      case 'I':\n        DLALIGN(data->ptr,offset,INT_ALIGN);\n        break;\n      case 'L':\n        DLALIGN(data->ptr,offset,LONG_ALIGN);\n        break;\n      case 'P':\n      case 'S':\n        DLALIGN(data->ptr,offset,VOIDP_ALIGN);\n        break;\n      case 'D':\n        DLALIGN(data->ptr,offset,DOUBLE_ALIGN);\n        break;\n      case 'F':\n        DLALIGN(data->ptr,offset,FLOAT_ALIGN);\n        break;\n      case 'C':\n        break;\n      case 'H':\n        DLALIGN(data->ptr,offset,SHORT_ALIGN);\n        break;\n      default:\n        rb_raise(rb_eDLTypeError, \"unsupported type '%c'\", data->stype[i]);\n      }\n      if (data->ids[i] == id) {\n\tmemimg = ary2cary(data->stype[i], val, &memsize);\n\tmemcpy((char *)data->ptr + offset, memimg, memsize);\n        dlfree(memimg);\n\treturn val;\n      }\n      switch (data->stype[i]) {\n      case 'I':\n      case 'i':\n\toffset += sizeof(int) * data->ssize[i];\n\tbreak;\n      case 'L':\n      case 'l':\n\toffset += sizeof(long) * data->ssize[i];\n\tbreak;\n      case 'P':\n      case 'p':\n      case 'S':\n      case 's':\n\toffset += sizeof(void*) * data->ssize[i];\n\tbreak;\n      case 'D':\n      case 'd':\n\toffset += sizeof(double) * data->ssize[i];\n\tbreak;\n      case 'F':\n      case 'f':\n\toffset += sizeof(float) * data->ssize[i];\n\tbreak;\n      case 'C':\n      case 'c':\n\toffset += sizeof(char) * data->ssize[i];\n\tbreak;\n      case 'H':\n      case 'h':\n\toffset += sizeof(short) * data->ssize[i];\n\tbreak;\n      default:\n\trb_raise(rb_eDLTypeError, \"unsupported type '%c'\", data->stype[i]);\n      }\n    }\n    return val;\n    /* break; */\n  case DLPTR_CTYPE_UNION:\n    for (i=0; i < data->ids_num; i++) {\n      if (data->ids[i] == id) {\n\tswitch (data->stype[i]) {\n\tcase 'I': case 'i':\n\t  memsize = sizeof(int) * data->ssize[i];\n\t  break;\n\tcase 'L': case 'l':\n\t  memsize = sizeof(long) * data->ssize[i];\n\t  break;\n\tcase 'P': case 'p':\n\tcase 'S': case 's':\n\t  memsize = sizeof(void*) * data->ssize[i];\n\t  break;\n\tcase 'F': case 'f':\n\t  memsize = sizeof(float) * data->ssize[i];\n\t  break;\n\tcase 'D': case 'd':\n\t  memsize = sizeof(double) * data->ssize[i];\n\t  break;\n\tcase 'C': case 'c':\n\t  memsize = sizeof(char) * data->ssize[i];\n\t  break;\n\tcase 'H': case 'h':\n\t  memsize = sizeof(short) * data->ssize[i];\n\t  break;\n\tdefault:\n\t  rb_raise(rb_eDLTypeError, \"unsupported type '%c'\", data->stype[i]);\n\t}\n\tmemimg = ary2cary(data->stype[i], val, NULL);\n\tmemcpy(data->ptr, memimg, memsize);\n        dlfree(memimg);\n      }\n    }\n    return val;\n    /* break; */\n  }\n\n  rb_raise(rb_eNameError, \"undefined key `%s' for %s\",\n\t   rb_id2name(id), rb_class2name(CLASS_OF(self)));\n\n  return Qnil;\n}\n\nVALUE\nrb_dlptr_size(int argc, VALUE argv[], VALUE self)\n{\n  VALUE size;\n\n  if (rb_scan_args(argc, argv, \"01\", &size) == 0){\n    return DLLONG2NUM(RDLPTR(self)->size);\n  }\n  else{\n    RDLPTR(self)->size = DLNUM2LONG(size);\n    return size;\n  }\n}\n\nstatic int\ndlmem_each_i(void* key, VALUE value, void* arg)\n{\n  VALUE vkey = DLLONG2NUM(key);\n  rb_yield(rb_assoc_new(vkey, value));\n  return Qnil;\n}\n\nVALUE\nrb_dlmem_each(VALUE self)\n{\n  st_foreach(st_memory_table, dlmem_each_i, 0);\n  return Qnil;\n}\n\nvoid\nInit_dlptr()\n{\n  rb_cDLPtrData = rb_define_class_under(rb_mDL, \"PtrData\", rb_cObject);\n  rb_define_alloc_func(rb_cDLPtrData, rb_dlptr_s_allocate);\n  rb_define_singleton_method(rb_cDLPtrData, \"malloc\", rb_dlptr_s_malloc, -1);\n  rb_define_method(rb_cDLPtrData, \"initialize\", rb_dlptr_initialize, -1);\n  rb_define_method(rb_cDLPtrData, \"free=\", rb_dlptr_free_set, 1);\n  rb_define_method(rb_cDLPtrData, \"free\",  rb_dlptr_free_get, 0);\n  rb_define_method(rb_cDLPtrData, \"to_i\",  rb_dlptr_to_i, 0);\n  rb_define_method(rb_cDLPtrData, \"ptr\",   rb_dlptr_ptr, 0);\n  rb_define_method(rb_cDLPtrData, \"+@\", rb_dlptr_ptr, 0);\n  rb_define_method(rb_cDLPtrData, \"ref\",   rb_dlptr_ref, 0);\n  rb_define_method(rb_cDLPtrData, \"-@\", rb_dlptr_ref, 0);\n  rb_define_method(rb_cDLPtrData, \"null?\", rb_dlptr_null_p, 0);\n  rb_define_method(rb_cDLPtrData, \"to_a\", rb_dlptr_to_array, -1);\n  rb_define_method(rb_cDLPtrData, \"to_s\", rb_dlptr_to_s, -1);\n  rb_define_method(rb_cDLPtrData, \"to_str\", rb_dlptr_to_str, -1);\n  rb_define_method(rb_cDLPtrData, \"inspect\", rb_dlptr_inspect, 0);\n  rb_define_method(rb_cDLPtrData, \"<=>\", rb_dlptr_cmp, 1);\n  rb_define_method(rb_cDLPtrData, \"==\", rb_dlptr_eql, 1);\n  rb_define_method(rb_cDLPtrData, \"eql?\", rb_dlptr_eql, 1);\n  rb_define_method(rb_cDLPtrData, \"+\", rb_dlptr_plus, 1);\n  rb_define_method(rb_cDLPtrData, \"-\", rb_dlptr_minus, 1);\n  rb_define_method(rb_cDLPtrData, \"define_data_type\",\n\t\t   rb_dlptr_define_data_type, -1);\n  rb_define_method(rb_cDLPtrData, \"struct!\", rb_dlptr_define_struct, -1);\n  rb_define_method(rb_cDLPtrData, \"union!\",  rb_dlptr_define_union,  -1);\n  rb_define_method(rb_cDLPtrData, \"data_type\", rb_dlptr_get_data_type, 0);\n  rb_define_method(rb_cDLPtrData, \"[]\", rb_dlptr_aref, -1);\n  rb_define_method(rb_cDLPtrData, \"[]=\", rb_dlptr_aset, -1);\n  rb_define_method(rb_cDLPtrData, \"size\", rb_dlptr_size, -1);\n  rb_define_method(rb_cDLPtrData, \"size=\", rb_dlptr_size, -1);\n\n  rb_mDLMemorySpace = rb_define_module_under(rb_mDL, \"MemorySpace\");\n  st_memory_table = st_init_numtable();\n  rb_define_const(rb_mDLMemorySpace, \"MemoryTable\", Qnil); /* historical */\n  rb_define_module_function(rb_mDLMemorySpace, \"each\", rb_dlmem_each, 0);\n}\n"
  },
  {
    "path": "ext/dl/sample/c++sample.C",
    "content": "#include <stdio.h>\n\nclass Person {\nprivate:\n  const char *name;\n  int age;\n\npublic:\n  Person(const char *name, int age);\n  const char * get_name();\n  int get_age();\n  void set_age(int i);\n};\n\nPerson::Person(const char *name, int age)\n  : name(name), age(age)\n{\n  /* empty */\n}\n\nconst char *\nPerson::get_name()\n{\n  return name;\n}\n\nint\nPerson::get_age(){\n  return age;\n}\n\nvoid\nPerson::set_age(int i){\n  age = i;\n}\n"
  },
  {
    "path": "ext/dl/sample/c++sample.rb",
    "content": "=begin\n This script shows how to deal with C++ classes using Ruby/DL.\n You must build a dynamic loadable library using \"c++sample.C\"\n to run this script as follows:\n   $ g++ -o libsample.so -shared c++sample.C\n=end\n\nrequire 'dl'\nrequire 'dl/import'\nrequire 'dl/struct'\n\n# Give a name of dynamic loadable library\nLIBNAME = ARGV[0] || \"libsample.so\"\n\nclass Person\n  module Core\n    extend DL::Importable\n    \n    dlload LIBNAME\n\n    # mangled symbol names\n    extern \"void __6PersonPCci(void *, const char *, int)\"\n    extern \"const char *get_name__6Person(void *)\"\n    extern \"int get_age__6Person(void *)\"\n    extern \"void set_age__6Personi(void *, int)\"\n\n    Data = struct [\n      \"char *name\",\n      \"int age\",\n    ]\n  end\n\n  def initialize(name, age)\n    @ptr = Core::Data.alloc\n    Core::__6PersonPCci(@ptr, name, age)\n  end\n\n  def get_name()\n    str = Core::get_name__6Person(@ptr)\n    if( str )\n      str.to_s\n    else\n      nil\n    end\n  end\n\n  def get_age()\n    Core::get_age__6Person(@ptr)\n  end\n\n  def set_age(age)\n    Core::set_age__6Personi(@ptr, age)\n  end\nend\n\nobj = Person.new(\"ttate\", 1)\np obj.get_name()\np obj.get_age()\nobj.set_age(10)\np obj.get_age()\n"
  },
  {
    "path": "ext/dl/sample/drives.rb",
    "content": "# -*- ruby -*-\n# drives.rb -- find existing drives and show the drive type.\n\nrequire 'dl'\nrequire 'dl/import'\n\nmodule Kernel32\n  extend DL::Importable\n\n  dlload \"kernel32\"\n\n  extern \"long GetLogicalDrives()\"\n  extern \"int GetDriveType(char*)\"\n  extern \"long GetDiskFreeSpace(char*, long ref, long ref, long ref, long ref)\"\nend\n\ninclude Kernel32\n\nbuff = Kernel32.getLogicalDrives()\n\ni = 0\nds = []\nwhile( i < 26 )\n  mask = (1 << i)\n  if( buff & mask > 0 )\n    ds.push((65+i).chr)\n  end\n  i += 1\nend\n\n=begin\nFrom the cygwin's /usr/include/w32api/winbase.h:\n#define DRIVE_UNKNOWN 0\n#define DRIVE_NO_ROOT_DIR 1\n#define DRIVE_REMOVABLE 2\n#define DRIVE_FIXED 3\n#define DRIVE_REMOTE 4\n#define DRIVE_CDROM 5\n#define DRIVE_RAMDISK 6\n=end\n\ntypes = [\n  \"unknown\",\n  \"no root dir\",\n  \"Removable\",\n  \"Fixed\", \n  \"Remote\",\n  \"CDROM\",\n  \"RAM\",\n]\nprint(\"Drive : Type (Free Space/Available Space)\\n\")\nds.each{|d|\n  t = Kernel32.getDriveType(d + \":\\\\\")\n  Kernel32.getDiskFreeSpace(d + \":\\\\\", 0, 0, 0, 0)\n  _,sec_per_clus,byte_per_sec,free_clus,total_clus = Kernel32._args_\n  fbytes = sec_per_clus * byte_per_sec * free_clus\n  tbytes = sec_per_clus * byte_per_sec * total_clus\n  unit = \"B\"\n  if( fbytes > 1024 && tbytes > 1024 )\n    fbytes = fbytes / 1024\n    tbytes = tbytes / 1024\n    unit = \"K\"\n  end\n  if( fbytes > 1024 && tbytes > 1024 )\n    fbytes = fbytes / 1024\n    tbytes = tbytes / 1024\n    unit = \"M\"\n  end\n  print(\"#{d} : #{types[t]} (#{fbytes} #{unit}/#{tbytes} #{unit})\\n\")\n}\n"
  },
  {
    "path": "ext/dl/sample/getch.rb",
    "content": "require 'dl'\n\ncrtdll = DL::dlopen(\"crtdll\")\ngetch  = crtdll['_getch', 'L']\nprint(getch.call, \"\\n\")\n"
  },
  {
    "path": "ext/dl/sample/libc.rb",
    "content": "require \"dl/import\"\nrequire \"dl/struct\"\n\nmodule LIBC\n  extend DL::Importable\n\n  begin\n    dlload \"libc.so.6\"\n  rescue\n    dlload \"libc.so.5\"\n  end\n\n  extern \"int atoi(char*)\"\n  extern \"ibool isdigit(int)\"\n  extern \"int gettimeofday(struct timeval *, struct timezone *)\"\n  extern \"char* strcat(char*, char*)\"\n  extern \"FILE* fopen(char*, char*)\"\n  extern \"int fclose(FILE*)\"\n  extern \"int fgetc(FILE*)\"\n  extern \"int strlen(char*)\"\n  extern \"void qsort(void*, int, int, void*)\"\n\n  def str_qsort(ary, comp)\n    len = ary.length\n    r,rs = qsort(ary, len, DL.sizeof('P'), comp)\n    return rs[0].to_a('S', len)\n  end\n\n  Timeval = struct [\n    \"long tv_sec\",\n    \"long tv_usec\",\n  ]\n\n  Timezone = struct [\n    \"int tz_minuteswest\",\n    \"int tz_dsttime\",\n  ]\n\n  def my_compare(ptr1, ptr2)\n    ptr1.ptr.to_s <=> ptr2.ptr.to_s\n  end\n  COMPARE = callback(\"int my_compare(char**, char**)\")\nend\n\n\n$cb1 = DL.callback('IPP'){|ptr1, ptr2|\n  str1 = ptr1.ptr.to_s\n  str2 = ptr2.ptr.to_s\n  str1 <=> str2\n}\n\np LIBC.atoi(\"10\")\n\np LIBC.isdigit(?1)\n\np LIBC.isdigit(?a)\n\np LIBC.strcat(\"a\", \"b\")\n\nary = [\"a\",\"c\",\"b\"]\nptr = ary.to_ptr\nLIBC.qsort(ptr, ary.length, DL.sizeof('P'), LIBC::COMPARE)\np ptr.to_a('S', ary.length)\n\ntv = LIBC::Timeval.malloc\ntz = LIBC::Timezone.malloc\nLIBC.gettimeofday(tv, tz)\n\np Time.at(tv.tv_sec)\n"
  },
  {
    "path": "ext/dl/sample/msgbox.rb",
    "content": "# This script works on Windows.\n\nrequire 'dl'\n\nUser32 = DL.dlopen(\"user32\")\nKernel32 = DL.dlopen(\"kernel32\")\n\nMB_OK = 0\nMB_OKCANCEL = 1\n\nmessage_box = User32['MessageBoxA', 'ILSSI']\nr,rs = message_box.call(0, 'ok?', 'error', MB_OKCANCEL)\n\ncase r\nwhen 1\n  print(\"OK!\\n\")\nwhen 2\n  print(\"Cancel!\\n\")\nend\n"
  },
  {
    "path": "ext/dl/sample/msgbox2.rb",
    "content": "# This script works on Windows.\n\nrequire 'dl/win32'\n\nMB_OK = 0\nMB_OKCANCEL = 1\n\nmessage_box = Win32API.new(\"user32\",'MessageBoxA', 'ISSI', 'I')\nr = message_box.call(0, 'ok?', 'error', MB_OKCANCEL)\n\ncase r\nwhen 1\n  print(\"OK!\\n\")\nwhen 2\n  print(\"Cancel!\\n\")\nelse\n  p r\nend\n"
  },
  {
    "path": "ext/dl/sample/stream.rb",
    "content": "# -*- ruby -*-\n# Display a file name and stream names of a file with those size.\n\nrequire 'dl'\nrequire 'dl/import'\n\nmodule NTFS\n  extend DL::Importable\n\n  dlload \"kernel32.dll\"\n\n  OPEN_EXISTING         = 3\n  GENERIC_READ          = 0x80000000\n  BACKUP_DATA           = 0x00000001\n  BACKUP_ALTERNATE_DATA = 0x00000004\n  FILE_SHARE_READ       = 0x00000001\n  FILE_FLAG_BACKUP_SEMANTICS = 0x02000000\n\n  typealias \"LPSECURITY_ATTRIBUTES\", \"void*\"\n\n  extern \"BOOL BackupRead(HANDLE, PBYTE, DWORD, PDWORD, BOOL, BOOL, PVOID)\"\n  extern \"BOOL BackupSeek(HANDLE, DWORD, DWORD, PDWORD, PDWORD, PVOID)\"\n  extern \"BOOL CloseHandle(HANDLE)\"\n  extern \"HANDLE CreateFile(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,\n                            DWORD, DWORD, HANDLE)\"\n\n  module_function\n\n  def streams(filename)\n    status = []\n    h = createFile(filename,GENERIC_READ,FILE_SHARE_READ,nil,\n\t\t   OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0)\n    if( h != 0 )\n      begin\n\t# allocate the memory for backup data used in backupRead().\n\tdata = DL.malloc(DL.sizeof(\"L5\"))\n\tdata.struct!(\"LLLLL\", :id, :attrs, :size_low, :size_high, :name_size)\n\n\t# allocate memories for references to long values used in backupRead().\n\tcontext = DL.malloc(DL.sizeof(\"L\"))\n\tlval = DL.malloc(DL.sizeof(\"L\"))\n\n\twhile( backupRead(h, data, data.size, lval, false, false, context) )\n\t  size = data[:size_low] + (data[:size_high] << (DL.sizeof(\"I\") * 8))\n\t  case data[:id]\n\t  when BACKUP_ALTERNATE_DATA\n\t    stream_name = DL.malloc(data[:name_size])\n\t    backupRead(h, stream_name, stream_name.size,\n\t\t       lval, false, false, context)\n\t    name = stream_name[0, stream_name.size]\n\t    name.tr!(\"\\000\",\"\")\n\t    if( name =~ /^:(.*?):.*$/ )\n\t      status.push([$1,size])\n\t    end\n\t  when BACKUP_DATA\n\t    status.push([nil,size])\n\t  else\n\t    raise(RuntimeError, \"unknown data type #{data[:id]}.\")\n\t  end\n\t  l1 = DL.malloc(DL.sizeof(\"L\"))\n\t  l2 = DL.malloc(DL.sizeof(\"L\"))\n\t  if( !backupSeek(h, data[:size_low], data[:size_high], l1, l2, context) )\n\t    break\n\t  end\n\tend\n      ensure\n\tbackupRead(h, nil, 0, lval, true, false, context)\n\tcloseHandle(h)\n      end\n      return status\n    else\n      raise(RuntimeError, \"can't open #{filename}.\\n\")\n    end\n  end\nend\n\nARGV.each{|filename|\n  if( File.exist?(filename) )\n    NTFS.streams(filename).each{|name,size|\n      if( name )\n\tprint(\"#{filename}:#{name}\\t#{size}bytes\\n\")\n      else\n\tprint(\"#{filename}\\t#{size}bytes\\n\")\n      end\n    }\n  end\n}\n"
  },
  {
    "path": "ext/dl/sym.c",
    "content": "/* -*- C -*-\n * $Id$\n */\n\n#include <ruby.h>\n#include <errno.h>\n#include \"dl.h\"\n\nVALUE rb_cDLSymbol;\n\nstatic const char *\nchar2type(int ch)\n{\n  switch (ch) {\n  case '0':\n    return \"void\";\n  case 'P':\n    return \"void *\";\n  case 'p':\n    return \"void *\";\n  case 'C':\n    return \"char\";\n  case 'c':\n    return \"char *\";\n  case 'H':\n    return \"short\";\n  case 'h':\n    return \"short *\";\n  case 'I':\n    return \"int\";\n  case 'i':\n    return \"int *\";\n  case 'L':\n    return \"long\";\n  case 'l':\n    return \"long *\";\n  case 'F':\n    return \"double\";\n  case 'f':\n    return \"double *\";\n  case 'D':\n    return \"double\";\n  case 'd':\n    return \"double *\";\n  case 'S':\n    return \"const char *\";\n  case 's':\n    return \"char *\";\n  case 'A':\n    return \"[]\";\n  case 'a':\n    return \"[]\"; /* ?? */\n  }\n  return NULL;\n}\n\nvoid\ndlsym_free(struct sym_data *data)\n{\n  if( data->name ){\n    DEBUG_CODE({\n      printf(\"dlsym_free(): free(data->name:%s)\\n\",data->name);\n    });\n    free(data->name);\n  }\n  if( data->type ){\n    DEBUG_CODE({\n      printf(\"dlsym_free(): free(data->type:%s)\\n\",data->type);\n    });\n    free(data->type);\n  }\n}\n\nVALUE\nrb_dlsym_new(void (*func)(), const char *name, const char *type)\n{\n  VALUE val;\n  struct sym_data *data;\n  const char *ptype;\n\n  rb_secure(4);\n  if( !type || !type[0] ){\n    return rb_dlptr_new((void*)func, 0, 0);\n  }\n\n  for( ptype = type; *ptype; ptype ++ ){\n    if( ! char2type(*ptype) ){\n      rb_raise(rb_eDLTypeError, \"unknown type specifier '%c'\", *ptype);\n    }\n  }\n\n  if( func ){\n    val = Data_Make_Struct(rb_cDLSymbol, struct sym_data, 0, dlsym_free, data);\n    data->func = func;\n    data->name = name ? strdup(name) : NULL;\n    data->type = type ? strdup(type) : NULL;\n    data->len  = type ? strlen(type) : 0;\n#if !(defined(DLSTACK))\n    if( data->len - 1 > MAX_ARG ){\n      rb_raise(rb_eDLError, \"maximum number of arguments is %d.\", MAX_ARG);\n    }\n#endif\n  }\n  else{\n    val = Qnil;\n  }\n\n  return val;\n}\n\nfreefunc_t\nrb_dlsym2csym(VALUE val)\n{\n  struct sym_data *data;\n  freefunc_t func;\n\n  if( rb_obj_is_kind_of(val, rb_cDLSymbol) ){\n    Data_Get_Struct(val, struct sym_data, data);\n    func = data->func;\n  }\n  else if( val == Qnil ){\n    func = NULL;\n  }\n  else{\n    rb_raise(rb_eTypeError, \"DL::Symbol was expected\");\n  }\n\n  return func;\n}\n\nVALUE\nrb_dlsym_s_allocate(VALUE klass)\n{\n  VALUE obj;\n  struct sym_data *data;\n\n  obj = Data_Make_Struct(klass, struct sym_data, 0, dlsym_free, data);\n  data->func = 0;\n  data->name = 0;\n  data->type = 0;\n  data->len  = 0;\n\n  return obj;\n}\n\nVALUE\nrb_dlsym_initialize(int argc, VALUE argv[], VALUE self)\n{\n  VALUE addr, name, type;\n  struct sym_data *data;\n  void *saddr;\n  const char *sname, *stype;\n\n  rb_scan_args(argc, argv, \"12\", &addr, &name, &type);\n\n  saddr = (void*)(DLNUM2LONG(rb_Integer(addr)));\n  if (!NIL_P(name)) StringValue(name);\n  stype = NIL_P(type) ? NULL : StringValuePtr(type);\n  sname = NIL_P(name) ? NULL : RSTRING(name)->ptr;\n\n  if( saddr ){\n    Data_Get_Struct(self, struct sym_data, data);\n    if( data->name ) free(data->name);\n    if( data->type ) free(data->type);\n    data->func = saddr;\n    data->name = sname ? strdup(sname) : 0;\n    data->type = stype ? strdup(stype) : 0;\n    data->len  = stype ? strlen(stype) : 0;\n  }\n\n  return Qnil;\n}\n\nVALUE\nrb_s_dlsym_char2type(VALUE self, VALUE ch)\n{\n  const char *type;\n\n  type = char2type(StringValuePtr(ch)[0]);\n\n  if (type == NULL)\n    return Qnil;\n  else\n    return rb_str_new2(type);\n}\n\nVALUE\nrb_dlsym_name(VALUE self)\n{\n  struct sym_data *sym;\n\n  Data_Get_Struct(self, struct sym_data, sym);\n  return sym->name ? rb_tainted_str_new2(sym->name) : Qnil;\n}\n\nVALUE\nrb_dlsym_proto(VALUE self)\n{\n  struct sym_data *sym;\n\n  Data_Get_Struct(self, struct sym_data, sym);\n  return sym->type ? rb_tainted_str_new2(sym->type) : Qnil;\n}\n\nVALUE\nrb_dlsym_cproto(VALUE self)\n{\n  struct sym_data *sym;\n  const char *ptype, *typestr;\n  size_t len;\n  VALUE val;\n\n  Data_Get_Struct(self, struct sym_data, sym);\n\n  ptype = sym->type;\n\n  if( ptype ){\n    typestr = char2type(*ptype++);\n    len = strlen(typestr);\n    \n    val = rb_tainted_str_new(typestr, len);\n    if (typestr[len - 1] != '*')\n      rb_str_cat(val, \" \", 1);\n\n    if( sym->name ){\n      rb_str_cat2(val, sym->name);\n    }\n    else{\n      rb_str_cat2(val, \"(null)\");\n    }\n    rb_str_cat(val, \"(\", 1);\n    \n    while (*ptype) {\n      const char *ty = char2type(*ptype++);\n      rb_str_cat2(val, ty);\n      if (*ptype)\n\trb_str_cat(val, \", \", 2);\n    }\n\n    rb_str_cat(val, \");\", 2);\n  }\n  else{\n    val = rb_tainted_str_new2(\"void (\");\n    if( sym->name ){\n      rb_str_cat2(val, sym->name);\n    }\n    else{\n      rb_str_cat2(val, \"(null)\");\n    }\n    rb_str_cat2(val, \")()\");\n  }\n\n  return val;\n}\n\nVALUE\nrb_dlsym_inspect(VALUE self)\n{\n  VALUE proto;\n  VALUE val;\n  char  *str;\n  int str_size;\n  struct sym_data *sym;\n\n  Data_Get_Struct(self, struct sym_data, sym);\n  proto = rb_dlsym_cproto(self);\n\n  str_size = RSTRING(proto)->len + 100;\n  str = dlmalloc(str_size);\n  snprintf(str, str_size - 1,\n          \"#<DL::Symbol:0x%lx func=0x%lx '%s'>\",\n\t   sym, sym->func, RSTRING(proto)->ptr);\n  val = rb_tainted_str_new2(str);\n  dlfree(str);\n\n  return val;\n}\n\nstatic int\nstack_size(struct sym_data *sym)\n{\n  int i;\n  int size;\n\n  size = 0;\n  for( i=1; i < sym->len; i++ ){\n    switch(sym->type[i]){\n    case 'C':\n    case 'H':\n    case 'I':\n    case 'L':\n      size += sizeof(long);\n      break;\n    case 'F':\n      size += sizeof(float);\n      break;\n    case 'D':\n      size += sizeof(double);\n      break;\n    case 'c':\n    case 'h':\n    case 'i':\n    case 'l':\n    case 'f':\n    case 'd':\n    case 'p':\n    case 'P':\n    case 's':\n    case 'S':\n    case 'a':\n    case 'A':\n      size += sizeof(void*);\n      break;\n    default:\n      return -(sym->type[i]);\n    }\n  }\n  return size;\n}\n\nstatic ID rb_dl_id_DLErrno;\n\nstatic VALUE\nrb_dl_get_last_error(VALUE self)\n{\n  return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLErrno);\n}\n\nstatic VALUE\nrb_dl_set_last_error(VALUE self, VALUE val)\n{\n  errno = NUM2INT(val);\n  rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, val);\n  return Qnil;\n}\n\n#ifdef HAVE_WINDOWS_H\n#include <windows.h>\nstatic ID rb_dl_id_DLW32Error;\n\nstatic VALUE\nrb_dl_win32_get_last_error(VALUE self)\n{\n  return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLW32Error);\n}\n\nstatic VALUE\nrb_dl_win32_set_last_error(VALUE self, VALUE val)\n{\n    SetLastError(NUM2INT(val));\n    rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, val);\n    return Qnil;\n}\n#endif\n\n#ifdef DLSTACK_GUARD\n# ifdef __MSVC_RUNTIME_CHECKS\n#  pragma runtime_checks(\"s\", off)\n# endif\n# if _MSC_VER >= 1300\n__declspec(noinline)\n# endif\nstatic int\nrb_dlsym_guardcall(char type, ANY_TYPE *ret, long *stack, void *func)\n{\n  char *volatile guard = ALLOCA_N(char, 1); /* guard stack pointer */\n  switch(type){\n  case '0':\n    {\n      void (*f)(DLSTACK_PROTO) = func;\n      f(DLSTACK_ARGS);\n    }\n    break;\n  case 'P':\n  case 'p':\n    {\n      void * (*f)(DLSTACK_PROTO) = func;\n      ret->p = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'C':\n  case 'c':\n    {\n      char (*f)(DLSTACK_PROTO) = func;\n      ret->c = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'H':\n  case 'h':\n    {\n      short (*f)(DLSTACK_PROTO) = func;\n      ret->h = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'I':\n  case 'i':\n    {\n      int (*f)(DLSTACK_PROTO) = func;\n      ret->i = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'L':\n  case 'l':\n    {\n      long (*f)(DLSTACK_PROTO) = func;\n      ret->l = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'F':\n  case 'f':\n    {\n      float (*f)(DLSTACK_PROTO) = func;\n      ret->f = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'D':\n  case 'd':\n    {\n      double (*f)(DLSTACK_PROTO) = func;\n      ret->d = f(DLSTACK_ARGS);\n    }\n    break;\n  case 'S':\n  case 's':\n    {\n      char * (*f)(DLSTACK_PROTO) = func;\n      ret->s = f(DLSTACK_ARGS);\n    }\n    break;\n  default:\n    return 0;\n  }\n  return 1;\n}\n# ifdef __MSVC_RUNTIME_CHECKS\n#  pragma runtime_checks(\"s\", restore)\n# endif\n#endif /* defined(DLSTACK_GUARD) */\n\nVALUE\nrb_dlsym_call(int argc, VALUE argv[], VALUE self)\n{\n  struct sym_data *sym;\n  ANY_TYPE *args;\n  ANY_TYPE *dargs;\n  ANY_TYPE ret;\n  int   *dtypes;\n  VALUE val;\n  VALUE dvals;\n  int i;\n  long ftype;\n  void *func;\n\n  rb_secure_update(self);\n  Data_Get_Struct(self, struct sym_data, sym);\n  DEBUG_CODE({\n    printf(\"rb_dlsym_call(): type = '%s', func = 0x%x\\n\", sym->type, sym->func);\n  });\n  if( (sym->len - 1) != argc ){\n    rb_raise(rb_eArgError, \"%d arguments are needed\", sym->len - 1);\n  }\n\n  ftype = 0;\n  dvals = Qnil;\n\n  args = ALLOC_N(ANY_TYPE, sym->len - 1);\n  dargs = ALLOC_N(ANY_TYPE, sym->len - 1);\n  dtypes = ALLOC_N(int, sym->len - 1);\n#define FREE_ARGS {xfree(args); xfree(dargs); xfree(dtypes);}\n\n  for( i = sym->len - 2; i >= 0; i-- ){\n    dtypes[i] = 0;\n\n    switch( sym->type[i+1] ){\n    case 'p':\n      dtypes[i] = 'p';\n    case 'P':\n      {\n\tstruct ptr_data *data;\n\tVALUE pval;\n\n\tif( argv[i] == Qnil ){\n\t  ANY2P(args[i]) = DLVOIDP(0);\n\t}\n\telse{\n\t  if( rb_obj_is_kind_of(argv[i], rb_cDLPtrData) ){\n\t    pval = argv[i];\n\t  }\n\t  else{\n\t    pval = rb_funcall(argv[i], rb_intern(\"to_ptr\"), 0);\n\t    if( !rb_obj_is_kind_of(pval, rb_cDLPtrData) ){\n\t      rb_raise(rb_eDLTypeError, \"unexpected type of argument #%d\", i);\n\t    }\n\t  }\n\t  rb_check_safe_obj(pval);\n\t  Data_Get_Struct(pval, struct ptr_data, data);\n\t  ANY2P(args[i]) = DLVOIDP(data->ptr);\n\t}\n      }\n      PUSH_P(ftype);\n      break;\n    case 'a':\n      dtypes[i] = 'a';\n    case 'A':\n      if( argv[i] == Qnil ){\n\tANY2P(args[i]) = DLVOIDP(0);\n      }\n      else{\n\tANY2P(args[i]) = DLVOIDP(rb_ary2cary(0, argv[i], NULL));\n      }\n      PUSH_P(ftype);\n      break;\n    case 'C':\n      ANY2C(args[i]) = DLCHAR(NUM2CHR(argv[i]));\n      PUSH_C(ftype);\n      break;\n    case 'c':\n      ANY2C(dargs[i]) = DLCHAR(NUM2CHR(argv[i]));\n      ANY2P(args[i]) = DLVOIDP(&(ANY2C(dargs[i])));\n      dtypes[i] = 'c';\n      PUSH_P(ftype);\n      break;\n    case 'H':\n      ANY2H(args[i]) = DLSHORT(NUM2INT(argv[i]));\n      PUSH_C(ftype);\n      break;\n    case 'h':\n      ANY2H(dargs[i]) = DLSHORT(NUM2INT(argv[i]));\n      ANY2P(args[i]) = DLVOIDP(&(ANY2H(dargs[i])));\n      dtypes[i] = 'h';\n      PUSH_P(ftype);\n      break;\n    case 'I':\n      ANY2I(args[i]) = DLINT(NUM2INT(argv[i]));\n      PUSH_I(ftype);\n      break;\n    case 'i':\n      ANY2I(dargs[i]) = DLINT(NUM2INT(argv[i]));\n      ANY2P(args[i]) = DLVOIDP(&(ANY2I(dargs[i])));\n      dtypes[i] = 'i';\n      PUSH_P(ftype);\n      break;\n    case 'L':\n      ANY2L(args[i]) = DLNUM2LONG(argv[i]);\n      PUSH_L(ftype);\n      break;\n    case 'l':\n      ANY2L(dargs[i]) = DLNUM2LONG(argv[i]);\n      ANY2P(args[i]) = DLVOIDP(&(ANY2L(dargs[i])));\n      dtypes[i] = 'l';\n      PUSH_P(ftype);\n      break;\n    case 'F':\n      Check_Type(argv[i], T_FLOAT);\n      ANY2F(args[i]) = DLFLOAT(RFLOAT(argv[i])->value);\n      PUSH_F(ftype);\n      break;\n    case 'f':\n      Check_Type(argv[i], T_FLOAT);\n      ANY2F(dargs[i]) = DLFLOAT(RFLOAT(argv[i])->value);\n      ANY2P(args[i]) = DLVOIDP(&(ANY2F(dargs[i])));\n      dtypes[i] = 'f';\n      PUSH_P(ftype);\n      break;\n    case 'D':\n      Check_Type(argv[i], T_FLOAT);\n      ANY2D(args[i]) = RFLOAT(argv[i])->value;\n      PUSH_D(ftype);\n      break;\n    case 'd':\n      Check_Type(argv[i], T_FLOAT);\n      ANY2D(dargs[i]) = RFLOAT(argv[i])->value;\n      ANY2P(args[i]) = DLVOIDP(&(ANY2D(dargs[i])));\n      dtypes[i] = 'd';\n      PUSH_P(ftype);\n      break;\n    case 'S':\n      if( argv[i] == Qnil ){\n\tANY2S(args[i]) = DLSTR(0);\n      }\n      else{\n\tVALUE str = argv[i];\n\tSafeStringValue(str);\n\tANY2S(args[i]) = DLSTR(RSTRING(str)->ptr);\n      }\n      PUSH_P(ftype);\n      break;\n    case 's':\n      {\n\tVALUE str = argv[i];\n\tSafeStringValue(str);\n\tANY2S(args[i]) = DLSTR(dlmalloc(RSTRING(str)->len + 1));\n\tmemcpy((char*)(ANY2S(args[i])), RSTRING(str)->ptr, RSTRING(str)->len + 1);\n\tdtypes[i] = 's';\n      }\n      PUSH_P(ftype);\n      break;\n    default:\n      FREE_ARGS;\n      rb_raise(rb_eDLTypeError,\n\t       \"unknown type '%c' of the return value.\",\n\t       sym->type[i+1]);\n    }\n  }\n\n  switch( sym->type[0] ){\n  case '0':\n    PUSH_0(ftype);\n    break;\n  case 'P':\n  case 'p':\n  case 'S':\n  case 's':\n  case 'A':\n  case 'a':\n    PUSH_P(ftype);\n    break;\n  case 'C':\n  case 'c':\n    PUSH_C(ftype);\n    break;\n  case 'H':\n  case 'h':\n    PUSH_H(ftype);\n    break;\n  case 'I':\n  case 'i':\n    PUSH_I(ftype);\n    break;\n  case 'L':\n  case 'l':\n    PUSH_L(ftype);\n    break;\n  case 'F':\n  case 'f':\n    PUSH_F(ftype);\n    break;\n  case 'D':\n  case 'd':\n    PUSH_D(ftype);\n    break;\n  default:\n    FREE_ARGS;\n    rb_raise(rb_eDLTypeError,\n\t     \"unknown type `%c' of the return value.\",\n\t     sym->type[0]);\n  }\n\n  func = sym->func;\n\n#if defined(DLSTACK)\n  {\n#if defined(DLSTACK_SIZE)\n  int  stk_size;\n  long stack[DLSTACK_SIZE];\n  long *sp;\n\n  sp = stack;\n  stk_size = stack_size(sym);\n  if( stk_size < 0 ){\n    FREE_ARGS;\n    rb_raise(rb_eDLTypeError, \"unknown type '%c'.\", -stk_size);\n  }\n  else if( stk_size > (int)(DLSTACK_SIZE) ){\n    FREE_ARGS;\n    rb_raise(rb_eArgError, \"too many arguments.\");\n  }\n#endif\n\n  DLSTACK_START(sym);\n\n#if defined(DLSTACK_REVERSE)\n  for( i = sym->len - 2; i >= 0; i-- )\n#else\n  for( i = 0; i <= sym->len -2; i++ )\n#endif\n  {\n    switch( sym->type[i+1] ){\n    case 'p':\n    case 'P':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'a':\n    case 'A':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'C':\n      DLSTACK_PUSH_C(ANY2C(args[i]));\n      break;\n    case 'c':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'H':\n      DLSTACK_PUSH_H(ANY2H(args[i]));\n      break;\n    case 'h':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'I':\n      DLSTACK_PUSH_I(ANY2I(args[i]));\n      break;\n    case 'i':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'L':\n      DLSTACK_PUSH_L(ANY2L(args[i]));\n      break;\n    case 'l':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'F':\n      DLSTACK_PUSH_F(ANY2F(args[i]));\n      break;\n    case 'f':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'D':\n      DLSTACK_PUSH_D(ANY2D(args[i]));\n      break;\n    case 'd':\n      DLSTACK_PUSH_P(ANY2P(args[i]));\n      break;\n    case 'S':\n    case 's':\n      DLSTACK_PUSH_P(ANY2S(args[i]));\n      break;\n    }\n  }\n  DLSTACK_END(sym->type);\n\n#ifdef DLSTACK_GUARD\n  if(!rb_dlsym_guardcall(sym->type[0], &ret, stack, func)) {\n    FREE_ARGS;\n    rb_raise(rb_eDLTypeError, \"unknown type `%c'\", sym->type[0]);\n  }\n#else /* defined(DLSTACK_GUARD) */\n  {\n    switch( sym->type[0] ){\n    case '0':\n      {\n\tvoid (*f)(DLSTACK_PROTO) = func;\n\tf(DLSTACK_ARGS);\n      }\n      break;\n    case 'P':\n    case 'p':\n      {\n\tvoid * (*f)(DLSTACK_PROTO) = func;\n\tret.p = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'C':\n    case 'c':\n      {\n\tchar (*f)(DLSTACK_PROTO) = func;\n\tret.c = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'H':\n    case 'h':\n      {\n\tshort (*f)(DLSTACK_PROTO) = func;\n\tret.h = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'I':\n    case 'i':\n      {\n\tint (*f)(DLSTACK_PROTO) = func;\n\tret.i = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'L':\n    case 'l':\n      {\n\tlong (*f)(DLSTACK_PROTO) = func;\n\tret.l = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'F':\n    case 'f':\n      {\n\tfloat (*f)(DLSTACK_PROTO) = func;\n\tret.f = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'D':\n    case 'd':\n      {\n\tdouble (*f)(DLSTACK_PROTO) = func;\n\tret.d = f(DLSTACK_ARGS);\n      }\n      break;\n    case 'S':\n    case 's':\n      {\n\tchar * (*f)(DLSTACK_PROTO) = func;\n\tret.s = f(DLSTACK_ARGS);\n      }\n      break;\n    default:\n      FREE_ARGS;\n      rb_raise(rb_eDLTypeError, \"unknown type `%c'\", sym->type[0]);\n    }\n  }\n#endif /* defubed(DLSTACK_GUARD) */\n\n  {\n    /*\n     * We should get the value of errno/GetLastError() before calling another functions.\n     */\n    int last_errno = errno;\n#ifdef _WIN32\n    DWORD win32_last_err = GetLastError();\n#endif\n\n    rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, INT2NUM(last_errno));\n#ifdef _WIN32\n    rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, INT2NUM(win32_last_err));\n#endif\n  }\n\n  }\n#else /* defined(DLSTACK) */\n  switch(ftype){\n#include \"call.func\"\n  default:\n    FREE_ARGS;\n    rb_raise(rb_eDLTypeError, \"unsupported function type `%s'\", sym->type);\n  }\n#endif /* defined(DLSTACK) */\n\n  switch( sym->type[0] ){\n  case '0':\n    val = Qnil;\n    break;\n  case 'P':\n    val = rb_dlptr_new((void*)(ANY2P(ret)), 0, 0);\n    break;\n  case 'p':\n    val = rb_dlptr_new((void*)(ANY2P(ret)), 0, dlfree);\n    break;\n  case 'C':\n  case 'c':\n    val = CHR2FIX((char)(ANY2C(ret)));\n    break;\n  case 'H':\n  case 'h':\n    val = INT2NUM((short)(ANY2H(ret)));\n    break;\n  case 'I':\n  case 'i':\n    val = INT2NUM((int)(ANY2I(ret)));\n    break;\n  case 'L':\n  case 'l':\n    val = DLLONG2NUM((long)(ANY2L(ret)));\n    break;\n  case 'F':\n  case 'f':\n    val = rb_float_new((double)(ANY2F(ret)));\n    break;\n  case 'D':\n  case 'd':\n    val = rb_float_new((double)(ANY2D(ret)));\n    break;\n  case 'S':\n    if( ANY2S(ret) ){\n      val = rb_tainted_str_new2((char*)(ANY2S(ret)));\n    }\n    else{\n      val = Qnil;\n    }\n    break;\n  case 's':\n    if( ANY2S(ret) ){\n      val = rb_tainted_str_new2((char*)(ANY2S(ret)));\n      DEBUG_CODE({\n\tprintf(\"dlfree(%s)\\n\",(char*)(ANY2S(ret)));\n      });\n      dlfree((void*)(ANY2S(ret)));\n    }\n    else{\n      val = Qnil;\n    }\n    break;\n  default:\n    FREE_ARGS;\n    rb_raise(rb_eDLTypeError, \"unknown type `%c'\", sym->type[0]);\n  }\n\n  dvals = rb_ary_new();\n  for( i = 0; i <= sym->len - 2; i++ ){\n    if( dtypes[i] ){\n      switch( dtypes[i] ){\n      case 'c':\n\trb_ary_push(dvals, CHR2FIX(*((char*)(ANY2P(args[i])))));\n\tbreak;\n      case 'h':\n\trb_ary_push(dvals, INT2NUM(*((short*)(ANY2P(args[i])))));\n\tbreak;\n      case 'i':\n\trb_ary_push(dvals, INT2NUM(*((int*)(ANY2P(args[i])))));\n\tbreak;\n      case 'l':\n        rb_ary_push(dvals, DLLONG2NUM(*((long*)(ANY2P(args[i])))));\n        break;\n      case 'f':\n\trb_ary_push(dvals, rb_float_new(*((float*)(ANY2P(args[i])))));\n\tbreak;\n      case 'd':\n\trb_ary_push(dvals, rb_float_new(*((double*)(ANY2P(args[i])))));\n\tbreak;\n      case 'p':\n\trb_ary_push(dvals, rb_dlptr_new((void*)(ANY2P(args[i])), 0, 0));\n\tbreak;\n      case 'a':\n\trb_ary_push(dvals, rb_dlptr_new((void*)ANY2P(args[i]), 0, 0));\n\tbreak;\n      case 's':\n\trb_ary_push(dvals, rb_tainted_str_new2((char*)ANY2S(args[i])));\n\tDEBUG_CODE({\n\t  printf(\"dlfree(%s)\\n\",(char*)ANY2S(args[i]));\n\t});\n\tdlfree((void*)ANY2S(args[i]));\n\tbreak;\n      default:\n\t{\n\t  char c = dtypes[i];\n\t  FREE_ARGS;\n\t  rb_raise(rb_eRuntimeError, \"unknown argument type '%c'\", i, c);\n\t}\n      }\n    }\n    else{\n      switch( sym->type[i+1] ){\n      case 'A':\n\tdlfree((void*)ANY2P(args[i]));\n\tbreak;\n      }\n      rb_ary_push(dvals, argv[i]);\n    }\n  }\n\n  FREE_ARGS;\n#undef FREE_ARGS\n  return rb_assoc_new(val,dvals);\n}\n\nVALUE\nrb_dlsym_to_i(VALUE self)\n{\n  struct sym_data *sym;\n\n  Data_Get_Struct(self, struct sym_data, sym);\n  return DLLONG2NUM(sym);\n}\n\nVALUE\nrb_dlsym_to_ptr(VALUE self)\n{\n  struct sym_data *sym;\n\n  Data_Get_Struct(self, struct sym_data, sym);\n  return rb_dlptr_new(sym->func, sizeof(freefunc_t), 0);\n}\n\nvoid\nInit_dlsym()\n{\n  rb_cDLSymbol = rb_define_class_under(rb_mDL, \"Symbol\", rb_cObject);\n  rb_define_alloc_func(rb_cDLSymbol, rb_dlsym_s_allocate);\n  rb_define_singleton_method(rb_cDLSymbol, \"char2type\", rb_s_dlsym_char2type, 1);\n  rb_define_method(rb_cDLSymbol, \"initialize\", rb_dlsym_initialize, -1);\n  rb_define_method(rb_cDLSymbol, \"call\", rb_dlsym_call, -1);\n  rb_define_method(rb_cDLSymbol, \"[]\",   rb_dlsym_call, -1);\n  rb_define_method(rb_cDLSymbol, \"name\", rb_dlsym_name, 0);\n  rb_define_method(rb_cDLSymbol, \"proto\", rb_dlsym_proto, 0);\n  rb_define_method(rb_cDLSymbol, \"cproto\", rb_dlsym_cproto, 0);\n  rb_define_method(rb_cDLSymbol, \"inspect\", rb_dlsym_inspect, 0);\n  rb_define_method(rb_cDLSymbol, \"to_s\", rb_dlsym_cproto, 0);\n  rb_define_method(rb_cDLSymbol, \"to_ptr\", rb_dlsym_to_ptr, 0);\n  rb_define_method(rb_cDLSymbol, \"to_i\", rb_dlsym_to_i, 0);\n\n  rb_dl_id_DLErrno = rb_intern(\"DLErrno\");\n  rb_define_singleton_method(rb_mDL, \"last_error\", rb_dl_get_last_error, 0);  \n  rb_define_singleton_method(rb_mDL, \"last_error=\", rb_dl_set_last_error, 1);\n#ifdef _WIN32\n  rb_dl_id_DLW32Error = rb_intern(\"DLW32Error\");\n  rb_define_singleton_method(rb_mDL, \"win32_last_error\", rb_dl_win32_get_last_error, 0);\n  rb_define_singleton_method(rb_mDL, \"win32_last_error=\", rb_dl_win32_set_last_error, 1);\n#endif\n}\n"
  },
  {
    "path": "ext/dl/test/libtest.def",
    "content": "EXPORTS\ntest_alloc_test_struct\ntest_append\ntest_arylen\ntest_c2i\ntest_call_func1\ntest_callback1\ntest_close\ntest_d2f\ntest_f2d\ntest_fill_test_struct\ntest_fill_test_union\ntest_gets\ntest_i2c\ntest_init\ntest_isucc\ntest_lcc\ntest_lsucc\ntest_open\ntest_strcat\ntest_strlen\ntest_succ\ntest_data_init\ntest_data_add\ntest_data_aref\ntest_set_long_value\ntest_get_long_value\ninternal_long_value\n"
  },
  {
    "path": "ext/dl/test/test.c",
    "content": "#include <stdio.h>\n#include <string.h>\n\nstatic char internal_string[] = \"internal_string\";\nlong internal_long_value = 100;\n\nstruct test_struct {\n  char c;\n  long l;\n};\n\nunion test_union {\n  char c;\n  int  i;\n  long l;\n  void *p;\n};\n\nstruct test_data {\n  char name[1024];\n  struct test_data *next;\n};\n\nlong\ntest_get_long_value()\n{\n  return internal_long_value;\n};\n\nvoid\ntest_set_long_value(long l)\n{\n  internal_long_value = l;\n};\n\nvoid\ntest_fill_test_struct(struct test_struct *ptr, char c, long l)\n{\n  ptr->c = c;\n  ptr->l = l;\n};\n\nvoid\ntest_fill_test_union(union test_union *ptr, long l)\n{\n  ptr->l = l;\n};\n\nstruct test_struct *\ntest_alloc_test_struct(char c, long l)\n{\n  struct test_struct *data;\n\n  data = (struct test_struct *)malloc(sizeof(struct test_struct));\n  data->c = c;\n  data->l = l;\n\n  return data;\n};\n\nint\ntest_c2i(char c)\n{\n  return (int)c;\n};\n\nchar\ntest_i2c(int i)\n{\n  return (char)i;\n};\n\nlong\ntest_lcc(char c1, char c2)\n{\n  return (long)(c1 + c2);\n};\n\ndouble\ntest_f2d(float f)\n{\n  double d;\n  d = f;\n  return d;\n};\n\nfloat\ntest_d2f(double d)\n{\n  float f;\n  f = d;\n  return f;\n};\n\nint\ntest_strlen(const char *str)\n{\n  return strlen(str);\n};\n\nint\ntest_isucc(int i)\n{\n  return (i+1);\n};\n\nlong\ntest_lsucc(long l)\n{\n  return (l+1);\n};\n\nvoid\ntest_succ(long *l)\n{\n  (*l)++;\n};\n\nchar *\ntest_strcat(char *str1, const char *str2)\n{\n  return strcat(str1, str2);\n};\n\nint\ntest_arylen(char *ary[])\n{\n  int i;\n  for( i=0; ary[i]; i++ ){};\n  return i;\n};\n\nvoid\ntest_append(char *ary[], int len, char *astr)\n{\n  int i;\n  int size1,size2;\n  char *str;\n\n  size2 = strlen(astr);\n\n  for( i=0; i <= len - 1; i++ ){\n    size1 = strlen(ary[i]);\n    str = (char*)malloc(size1 + size2 + 1);\n    strcpy(str, ary[i]);\n    strcat(str, astr);\n    ary[i] = str;\n  };\n};\n\nint\ntest_init(int *argc, char **argv[])\n{\n  int i;\n  char s[256];\n\n  for( i=0; i < (*argc); i++ ){\n    sprintf(s, \"arg%d\", i);\n    if( strcmp((*argv)[i], s) != 0 ){\n      return 1;\n    }\n  }\n  return 0;\n}\n\nFILE *\ntest_open(const char *filename, const char *mode)\n{\n  FILE *file;\n  file = fopen(filename,mode);\n  return file;\n};\n\nvoid\ntest_close(FILE *file)\n{\n  fclose(file);\n};\n\nchar *\ntest_gets(char *s, int size, FILE *f)\n{\n  return fgets(s,size,f);\n};\n\ntypedef int callback1_t(int, char *);\n#define CALLBACK_MSG \"callback message\"\n\nint\ntest_callback1(int err, const char *msg)\n{\n  if( strcmp(msg, CALLBACK_MSG) == 0 ){\n    return 1;\n  }\n  else{\n    return 0;\n  }\n}\n\nint\ntest_call_func1(callback1_t *func)\n{\n  if( func ){\n    return (*func)(0, CALLBACK_MSG);\n  }\n  else{\n    return 0;\n  }\n}\n\nstruct test_data *\ntest_data_init()\n{\n  struct test_data *data;\n\n  data = (struct test_data *)malloc(sizeof(struct test_data));\n  data->next = NULL;\n  memset(data->name, 0, 1024);\n\n  return data;\n};\n\nvoid\ntest_data_add(struct test_data *list, const char *name)\n{\n  struct test_data *data;\n\n  data = (struct test_data *)malloc(sizeof(struct test_data));\n  memset(data->name, 0, 1024);\n  strncpy(data->name, name, 1024);\n  data->next = list->next;\n  list->next = data;\n};\n\nstruct test_data *\ntest_data_aref(struct test_data *list, int i)\n{\n  struct test_data *data;\n  int j;\n\n  for( data = list->next, j=0; data; data = data->next, j++ ){\n    if( i == j ){\n      return data;\n    };\n  };\n  return NULL;\n};\n"
  },
  {
    "path": "ext/dl/test/test.rb",
    "content": "# -*- ruby -*-\n\nrequire 'dl'\nrequire 'dl/import'\n\n$FAIL = 0\n$TOTAL = 0\n\ndef assert(label, ty, *conds)\n  $TOTAL += 1\n  cond = !conds.include?(false)\n  if( cond )\n    printf(\"succeed in `#{label}'\\n\")\n  else\n    $FAIL += 1\n    case ty\n    when :may\n      printf(\"fail in `#{label}' ... expected\\n\")\n    when :must\n      printf(\"fail in `#{label}' ... unexpected\\n\")\n    when :raise\n      raise(RuntimeError, \"fail in `#{label}'\")\n    end\n  end\nend\n\ndef debug(*xs)\n  if( $DEBUG )\n    xs.each{|x|\n      p x\n    }\n  end\nend\n\nprint(\"DLSTACK   = #{DL::DLSTACK}\\n\")\nprint(\"MAX_ARG   = #{DL::MAX_ARG}\\n\")\nprint(\"\\n\")\nprint(\"DL::FREE = #{DL::FREE.inspect}\\n\")\nprint(\"\\n\")\n\n$LIB = nil\nif( !$LIB && File.exist?(\"libtest.so\") )\n  $LIB = \"./libtest.so\"\nend\nif( !$LIB && File.exist?(\"test/libtest.so\") )\n  $LIB = \"./test/libtest.so\"\nend\n\nmodule LIBTest\n  extend DL::Importable\n\n  dlload($LIB)\n  extern \"int test_c2i(char)\"\n  extern \"char test_i2c(int)\"\n  extern \"long test_lcc(char, char)\"\n  extern \"double test_f2d(float)\"\n  extern \"float test_d2f(double)\"\n  extern \"int test_strlen(char*)\"\n  extern \"int test_isucc(int)\"\n  extern \"long test_lsucc(long)\"\n  extern \"void test_succ(long *)\"\n  extern \"int test_arylen(int [])\"\n  extern \"void test_append(char*[], int, char *)\"\nend\n\nDL.dlopen($LIB){|h|\n  c2i = h[\"test_c2i\",\"IC\"]\n  debug c2i\n  r,rs = c2i[?a]\n  debug r,rs\n  assert(\"c2i\", :may, r == ?a)\n  assert(\"extern c2i\", :must, r == LIBTest.test_c2i(?a))\n\n  i2c = h[\"test_i2c\",\"CI\"]\n  debug i2c\n  r,rs = i2c[?a]\n  debug r,rs\n  assert(\"i2c\", :may, r == ?a)\n  assert(\"exern i2c\", :must, r == LIBTest.test_i2c(?a))\n\n  lcc = h[\"test_lcc\",\"LCC\"]\n  debug lcc\n  r,rs = lcc[1,2]\n  assert(\"lcc\", :may, r == 3)\n  assert(\"extern lcc\", :must, r == LIBTest.test_lcc(1,2))\n\n  f2d = h[\"test_f2d\",\"DF\"]\n  debug f2d\n  r,rs = f2d[20.001]\n  debug r,rs\n  assert(\"f2d\", :may, r.to_i == 20)\n  assert(\"extern f2d\", :must, r = LIBTest.test_f2d(20.001))\n\n  d2f = h[\"test_d2f\",\"FD\"]\n  debug d2f\n  r,rs = d2f[20.001]\n  debug r,rs\n  assert(\"d2f\", :may, r.to_i == 20)\n  assert(\"extern d2f\", :must, r == LIBTest.test_d2f(20.001))\n\n  strlen = h[\"test_strlen\",\"IS\"]\n  debug strlen\n  r,rs = strlen[\"0123456789\"]\n  debug r,rs\n  assert(\"strlen\", :must, r == 10)\n  assert(\"extern strlen\", :must, r == LIBTest.test_strlen(\"0123456789\"))\n\n  isucc = h[\"test_isucc\",\"II\"]\n  debug isucc\n  r,rs = isucc[2]\n  debug r,rs\n  assert(\"isucc\", :must, r == 3)\n  assert(\"extern isucc\", :must, r == LIBTest.test_isucc(2))\n\n  lsucc = h[\"test_lsucc\",\"LL\"]\n  debug lsucc\n  r,rs = lsucc[10000000]\n  debug r,rs\n  assert(\"lsucc\", :must, r == 10000001)\n  assert(\"extern lsucc\", :must, r == LIBTest.test_lsucc(10000000))\n\n  succ = h[\"test_succ\",\"0l\"]\n  debug succ\n  r,rs = succ[0]\n  debug r,rs\n  assert(\"succ\", :must, rs[0] == 1)\n  l = DL.malloc(DL.sizeof(\"L\"))\n  l.struct!(\"L\",:lval)\n  LIBTest.test_succ(l)\n  assert(\"extern succ\", :must, rs[0] == l[:lval])\n\n  arylen = h[\"test_arylen\",\"IA\"]\n  debug arylen\n  r,rs = arylen[[\"a\",\"b\",\"c\",\"d\",nil]]\n  debug r,rs\n  assert(\"arylen\", :must, r == 4)\n\n  arylen = h[\"test_arylen\",\"IP\"]\n  debug arylen\n  r,rs = arylen[[\"a\",\"b\",\"c\",\"d\",nil]]\n  debug r,rs\n  assert(\"arylen\", :must, r == 4)\n  assert(\"extern arylen\", :must, r == LIBTest.test_arylen([\"a\",\"b\",\"c\",\"d\",nil]))\n\n  append = h[\"test_append\",\"0aIS\"]\n  debug append\n  r,rs = append[[\"a\",\"b\",\"c\"],3,\"x\"]\n  debug r,rs\n  assert(\"append\", :must, rs[0].to_a('S',3) == [\"ax\",\"bx\",\"cx\"])\n\n  LIBTest.test_append([\"a\",\"b\",\"c\"],3,\"x\")\n  assert(\"extern append\", :must, rs[0].to_a('S',3) == LIBTest._args_[0].to_a('S',3))\n\n  strcat = h[\"test_strcat\",\"SsS\"]\n  debug strcat\n  r,rs = strcat[\"abc\\0\",\"x\"]\n  debug r,rs\n  assert(\"strcat\", :must, rs[0].to_s == \"abcx\")\n\n  init = h[\"test_init\",\"IiP\"]\n  debug init\n  argc = 3\n  argv = [\"arg0\",\"arg1\",\"arg2\"].to_ptr\n  r,rs = init[argc, argv.ref]\n  assert(\"init\", :must, r == 0)\n}\n\n\nh = DL.dlopen($LIB)\n\nsym_open = h[\"test_open\", \"PSS\"]\nsym_gets = h[\"test_gets\", \"SsIP\"]\nsym_close = h[\"test_close\", \"0P\"]\ndebug sym_open,sym_gets,sym_close\n\nline = \"Hello world!\\n\"\nFile.open(\"tmp.txt\", \"w\"){|f|\n  f.print(line)\n}\n\nfp,rs = sym_open[\"tmp.txt\", \"r\"]\nif( fp )\n  fp.free = sym_close\n  r,rs = sym_gets[\" \" * 256, 256, fp]\n  debug r,rs\n  assert(\"open,gets\", :must, rs[0] == line)\n  ObjectSpace.define_finalizer(fp) {File.unlink(\"tmp.txt\")}\n  fp = nil\nelse\n  assert(\"open,gets\", :must, line == nil)\n  File.unlink(\"tmp.txt\")\nend\n\n\ncallback1 = h[\"test_callback1\"]\ndebug callback1\nr,rs = h[\"test_call_func1\", \"IP\"][callback1]\ndebug r,rs\nassert(\"callback1\", :must, r == 1)\n\n\ncallback2 = DL.callback(\"LLP\"){|num,ptr|\n  msg = ptr.to_s\n  if( msg == \"callback message\" )\n    2\n  else\n    0\n  end\n}\ndebug callback2\nr,rs = h[\"test_call_func1\", \"IP\"][callback2]\ndebug r,rs\nassert(\"callback2\", :must, r == 2)\nDL.remove_callback(callback2)\n\nptr = DL.malloc(DL.sizeof('CL'))\nptr.struct!(\"CL\", :c, :l)\nptr[\"c\"] = 0\nptr[\"l\"] = 0\nr,rs = h[\"test_fill_test_struct\",\"0PIL\"][ptr,100,1000]\ndebug r,rs\nassert(\"fill_test_struct\", :must, ptr[\"c\"] == 100, ptr[\"l\"] == 1000)\nassert(\"fill_test_struct\", :must, ptr[:c] == 100, ptr[:l] == 1000) unless (Fixnum === :-)\n\n\nr,rs = h[\"test_alloc_test_struct\", \"PIL\"][100,200]\nr.free = DL::FREE\nr.struct!(\"CL\", :c, :l)\nassert(\"alloc_test_struct\", :must, r[\"c\"] == 100, r[\"l\"] == 200)\nassert(\"alloc_test_struct\", :must, r[:c] == 100, r[:l] == 200) unless (Fixnum === :-)\n\nptr = h[\"test_strlen\"]\nsym1 = DL::Symbol.new(ptr,\"foo\",\"0\")\nsym2 = h[\"test_strlen\",\"LS\"]\nassert(\"Symbol.new\", :must, ptr == sym1.to_ptr, sym1.to_ptr == sym2.to_ptr)\n\nset_val = h[\"test_set_long_value\",\"0\"]\nget_val = h[\"test_get_long_value\",\"L\"]\nlval = get_val[][0]\nptr = h[\"internal_long_value\"]\nptr.struct!(\"L\", :l)\nassert(\"get value\", :must, ptr[\"l\"] == lval)\nassert(\"get value\", :must, ptr[:l] == lval) unless (Fixnum === :-)\nptr[\"l\"] = 200\nlval = get_val[][0]\nassert(\"set value\", :must, ptr[\"l\"] == lval)\nassert(\"set value\", :must, ptr[:l] == lval) unless (Fixnum === :-)\n\n\ndata_init = h[\"test_data_init\", \"P\"]\ndata_add  = h[\"test_data_add\", \"0PS\"]\ndata_aref = h[\"test_data_aref\", \"PPI\"]\nr,rs = data_init[]\nptr = r\ndata_add[ptr, \"name1\"]\ndata_add[ptr, \"name2\"]\ndata_add[ptr, \"name3\"]\n\nr,rs = data_aref[ptr, 1]\nptr = r\nptr.struct!(\"C1024P\", :name, :next)\nassert(\"data_aref\", :must,\n       ptr[\"name\"].collect{|c| c.chr}.join.split(\"\\0\")[0] == \"name2\")\nassert(\"data_aref\", :must,\n       ptr[\"name\"].collect{|c| c.chr}.join.split(\"\\0\")[0] == \"name2\") unless (Fixnum === :-)\n\nptr = ptr[\"next\"]\nptr.struct!(\"C1024P\", :name, :next)\nassert(\"data_aref\", :must,\n       ptr[\"name\"].collect{|c| c.chr}.join.split(\"\\0\")[0] == \"name1\")\nassert(\"data_aref\", :must,\n       ptr[\"name\"].collect{|c| c.chr}.join.split(\"\\0\")[0] == \"name1\") unless (Fixnum === :-)\n\nGC.start\n\nptr = DL::malloc(32)\nptr.struct!(\"CHIL\", \"c\", \"h\", \"i\", \"l\")\nptr[\"c\"] = 1\nptr[\"h\"] = 2\nptr[\"i\"] = 3\nptr[\"l\"] = 4\nassert(\"struct!\", :must,\n       ptr[\"c\"] == 1 &&\n       ptr[\"h\"] == 2 &&\n       ptr[\"i\"] == 3 &&\n       ptr[\"l\"] == 4)\n\nptr = DL::malloc(DL::sizeof(\"IP\"))\nptr.struct!(\"IP\", \"n\", \"ptr\")\nptr[\"n\"] = 10\nptr[\"ptr\"] = nil\nassert(\"struct!\", :must, ptr[\"n\"] == 10 && ptr[\"ptr\"] == nil)\n\nptr = DL::malloc(16)\nptr.struct!(\"CICI\", \"c1\", \"i1\", \"c2\", \"i2\")\nptr[\"c1\"] = 0xf1\nptr[\"c2\"] = 0xf2\nc1 = [ptr[\"c1\"]].pack(\"c\").unpack(\"C\")[0]\nc2 = [ptr[\"c2\"]].pack(\"c\").unpack(\"C\")[0]\nassert(\"struct!\", :must,\n  c1 == 0xf1 &&\n  c2 == 0xf2)\n\n\nGC.start\nprintf(\"fail/total = #{$FAIL}/#{$TOTAL}\\n\")\n"
  },
  {
    "path": "ext/dl/type.rb",
    "content": "# example:\n#  DLTYPE[INT][:rb2c][\"arg0\"] => \"NUM2INT(arg0)\"\n#  DLTYPE[DOUBLE][:c2rb][\"r\"] => \"rb_float_new(r)\"\n\nDLTYPE = {\n  VOID  = 0x00 => {\n    :name => 'VOID',\n    :rb2c => nil,\n    :c2rb => nil,\n    :ctype => \"void\",\n    :stmem => \"v\",\n    :sym => true,\n    :cb => true,\n  },\n  CHAR  = 0x01 => {\n    :name => 'CHAR',\n    :rb2c => proc{|x| \"NUM2CHR(#{x})\"},\n    :c2rb => proc{|x| \"CHR2FIX(#{x})\"},\n    :ctype => \"char\",\n    :stmem => \"c\",\n    :sym => false,\n    :cb => false,\n  },\n  SHORT = 0x02 => {\n    :name => 'SHORT',\n    :rb2c => proc{|x| \"FIX2INT(#{x})\"},\n    :c2rb => proc{|x| \"INT2FIX(#{x})\"},\n    :ctype => \"short\",\n    :stmem => \"h\",\n    :sym => false,\n    :cb => false,\n  },\n  INT   = 0x03 => {\n    :name => 'INT',\n    :rb2c => proc{|x| \"NUM2INT(#{x})\"},\n    :c2rb => proc{|x| \"INT2NUM(#{x})\"},\n    :ctype => \"int\",\n    :stmem => \"i\",\n    :sym => true,\n    :cb => false,\n  },\n  LONG  = 0x04 => {\n    :name => 'LONG',\n    :rb2c => proc{|x| \"NUM2INT(#{x})\"},\n    :c2rb => proc{|x| \"INT2NUM(#{x})\"},\n    :ctype => \"long\",\n    :stmem => \"l\",\n    :sym => true,\n    :cb => true,\n  },\n  FLOAT = 0x05 => {\n    :name => 'FLOAT',\n    :rb2c => proc{|x| \"(float)(RFLOAT(#{x})->value)\"},\n    :c2rb => proc{|x| \"rb_float_new((double)#{x})\"},\n    :ctype => \"float\",\n    :stmem => \"f\",\n    :sym => false,\n    :cb => false,\n  },\n  DOUBLE = 0x06 => {\n    :name => 'DOUBLE',\n    :rb2c => proc{|x| \"RFLOAT(#{x})->value\"},\n    :c2rb => proc{|x| \"rb_float_new(#{x})\"},\n    :ctype => \"double\",\n    :stmem => \"d\",\n    :sym => true,\n    :cb => true,\n  },\n  VOIDP = 0x07 => {\n    :name => 'VOIDP',\n    :rb2c => proc{|x| \"rb_dlptr2cptr(#{x})\"},\n    :c2rb => proc{|x| \"rb_dlptr_new(#{x},sizeof(void*),0)\"},\n    :ctype => \"void *\",\n    :stmem => \"p\",\n    :sym => true,\n    :cb => true,\n  },\n}\n\ndef tpush(t, x)\n  (t << 3)|x\nend\n\ndef tget(t, i)\n  (t & (0x07 << (i * 3))) >> (i * 3)\nend\n\ndef types2num(types)\n  res = 0x00\n  r = types.reverse\n  r.each{|t|\n    res = tpush(res,t)\n  }\n  res\nend\n\ndef num2types(num)\n  ts = []\n  i  = 0\n  t = tget(num,i)\n  while( (t != VOID && i > 0) || (i == 0) )\n    ts.push(DLTYPE[t][:ctype])\n    i += 1\n    t = tget(num,i)\n  end\n  ts\nend\n\ndef types2ctypes(types)\n  res = []\n  types.each{|t|\n    res.push(DLTYPE[t][:ctype])\n  }\n  res\nend\n"
  },
  {
    "path": "ext/etc/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/etc/depend",
    "content": "etc.o : etc.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h \n"
  },
  {
    "path": "ext/etc/etc.c",
    "content": "/************************************************\n\n  etc.c -\n\n  $Author$\n  $Date$\n  created at: Tue Mar 22 18:39:19 JST 1994\n\n************************************************/\n\n#include \"ruby.h\"\n\n#include <sys/types.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#ifdef HAVE_GETPWENT\n#include <pwd.h>\n#endif\n\n#ifdef HAVE_GETGRENT\n#include <grp.h>\n#endif\n\n#ifndef HAVE_TYPE_UID_T\n#define uid_t int\n#endif\n\nstatic VALUE sPasswd, sGroup;\n\n#ifndef _WIN32\nchar *getenv();\n#endif\nchar *getlogin();\n\n/* Returns the short user name of the currently logged in user.\n * Unfortunately, it is often rather easy to fool getlogin().\n * Avoid getlogin() for security-related purposes.\n *\n * e.g.\n *   Etc.getlogin -> 'guest'\n */\nstatic VALUE\netc_getlogin(obj)\n    VALUE obj;\n{\n    char *login;\n\n    rb_secure(4);\n#ifdef HAVE_GETLOGIN\n    login = getlogin();\n    if (!login) login = getenv(\"USER\");\n#else\n    login = getenv(\"USER\");\n#endif\n\n    if (login)\n\treturn rb_tainted_str_new2(login);\n    return Qnil;\n}\n\n#if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)\nstatic VALUE\nsafe_setup_str(str)\n    const char *str;\n{\n    if (str == 0) str = \"\";\n    return rb_tainted_str_new2(str);\n}\n#endif\n\n#ifdef HAVE_GETPWENT\nstatic VALUE\nsetup_passwd(pwd)\n    struct passwd *pwd;\n{\n    if (pwd == 0) rb_sys_fail(\"/etc/passwd\");\n    return rb_struct_new(sPasswd,\n\t\t\t safe_setup_str(pwd->pw_name),\n#ifdef HAVE_ST_PW_PASSWD\n\t\t\t safe_setup_str(pwd->pw_passwd),\n#endif\n\t\t\t PW_UID2VAL(pwd->pw_uid),\n\t\t\t PW_GID2VAL(pwd->pw_gid),\n#ifdef HAVE_ST_PW_GECOS\n\t\t\t safe_setup_str(pwd->pw_gecos),\n#endif\n\t\t\t safe_setup_str(pwd->pw_dir),\n\t\t\t safe_setup_str(pwd->pw_shell),\n#ifdef HAVE_ST_PW_CHANGE\n\t\t\t INT2NUM(pwd->pw_change),\n#endif\n#ifdef HAVE_ST_PW_QUOTA\n\t\t\t INT2NUM(pwd->pw_quota),\n#endif\n#ifdef HAVE_ST_PW_AGE\n\t\t\t PW_AGE2VAL(pwd->pw_age),\n#endif\n#ifdef HAVE_ST_PW_CLASS\n\t\t\t safe_setup_str(pwd->pw_class),\n#endif\n#ifdef HAVE_ST_PW_COMMENT\n\t\t\t safe_setup_str(pwd->pw_comment),\n#endif\n#ifdef HAVE_ST_PW_EXPIRE\n\t\t\t INT2NUM(pwd->pw_expire),\n#endif\n\t\t\t 0\t\t/*dummy*/\n\t);\n}\n#endif\n\n/* Returns the /etc/passwd information for the user with specified integer\n * user id (uid).\n *\n * The information is returned as a Struct::Passwd; see getpwent above for\n * details.\n *\n * e.g.  * Etc.getpwuid(0) -> #<struct Struct::Passwd name=\"root\",\n * passwd=\"x\", uid=0, gid=0, gecos=\"root\",dir=\"/root\", shell=\"/bin/bash\">\n */\nstatic VALUE\netc_getpwuid(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n#if defined(HAVE_GETPWENT)\n    VALUE id;\n    uid_t uid;\n    struct passwd *pwd;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"01\", &id) == 1) {\n\tuid = PW_VAL2UID(id);\n    }\n    else {\n\tuid = getuid();\n    }\n    pwd = getpwuid(uid);\n    if (pwd == 0) rb_raise(rb_eArgError, \"can't find user for %d\", uid);\n    return setup_passwd(pwd);\n#else \n    return Qnil;\n#endif\n}\n\n/* Returns the /etc/passwd information for the user with specified login name.\n *\n * The information is returned as a Struct::Passwd; see getpwent above for\n * details.\n *\n * e.g.  * Etc.getpwnam('root') -> #<struct Struct::Passwd name=\"root\",\n * passwd=\"x\", uid=0, gid=0, gecos=\"root\",dir=\"/root\", shell=\"/bin/bash\">\n */\nstatic VALUE\netc_getpwnam(obj, nam)\n    VALUE obj, nam;\n{\n#ifdef HAVE_GETPWENT\n    struct passwd *pwd;\n\n    SafeStringValue(nam);\n    pwd = getpwnam(RSTRING(nam)->ptr);\n    if (pwd == 0) rb_raise(rb_eArgError, \"can't find user for %s\", RSTRING(nam)->ptr);\n    return setup_passwd(pwd);\n#else \n    return Qnil;\n#endif\n}\n\n#ifdef HAVE_GETPWENT\nstatic int passwd_blocking = 0;\nstatic VALUE\npasswd_ensure()\n{\n    passwd_blocking = Qfalse;\n    return Qnil;\n}\n\nstatic VALUE\npasswd_iterate()\n{\n    struct passwd *pw;\n\n    setpwent();\n    while (pw = getpwent()) {\n\trb_yield(setup_passwd(pw));\n    }\n    endpwent();\n    return Qnil;\n}\n#endif\n\n/* Provides a convenient Ruby iterator which executes a block for each entry \n * in the /etc/passwd file.\n *\n * The code block is passed an Etc::Passwd struct; see getpwent above for \n * details.\n *\n * Example:\n *\n *     require 'etc'\n *\n *     Etc.passwd {|u|\n *       puts u.name + \" = \" + u.gecos\n *     }\n *\n */\nstatic VALUE\netc_passwd(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETPWENT\n    struct passwd *pw;\n\n    rb_secure(4);\n    if (rb_block_given_p()) {\n\tif (passwd_blocking) {\n\t    rb_raise(rb_eRuntimeError, \"parallel passwd iteration\");\n\t}\n\tpasswd_blocking = Qtrue;\n\trb_ensure(passwd_iterate, 0, passwd_ensure, 0);\n    }\n    if (pw = getpwent()) {\n\treturn setup_passwd(pw);\n    }\n#endif\n    return Qnil;\n}\n\n/* Resets the process of reading the /etc/passwd file, so that the next call\n * to getpwent will return the first entry again.\n */\nstatic VALUE\netc_setpwent(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETPWENT\n    setpwent();\n#endif\n    return Qnil;\n}\n\n/* Ends the process of scanning through the /etc/passwd file begun with\n * getpwent, and closes the file.\n */\nstatic VALUE\netc_endpwent(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETPWENT\n    endpwent();\n#endif\n    return Qnil;\n}\n\n/* Returns an entry from the /etc/passwd file. The first time it is called it\n * opens the file and returns the first entry; each successive call returns \n * the next entry, or nil if the end of the file has been reached.\n *\n * To close the file when processing is complete, call endpwent.\n *\n * Each entry is returned as a Struct::Passwd:\n *\n * - Passwd#name contains the short login name of the user as a String.\n *\n * - Passwd#passwd contains the encrypted password of the user as a String.\n *   an 'x' is returned if shadow passwords are in use. An '*' is returned\n *   if the user cannot log in using a password.\n *\n * - Passwd#uid contains the integer user ID (uid) of the user.\n *\n * - Passwd#gid contains the integer group ID (gid) of the user's primary group.\n *\n * - Passwd#gecos contains a longer String description of the user, such as \n *   a full name. Some Unix systems provide structured information in the \n *   gecos field, but this is system-dependent.\n *\n * - Passwd#dir contains the path to the home directory of the user as a String.\n *\n * - Passwd#shell contains the path to the login shell of the user as a String.\n */\nstatic VALUE\netc_getpwent(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETPWENT\n    struct passwd *pw;\n\n    if (pw = getpwent()) {\n\treturn setup_passwd(pw);\n    }\n#endif\n    return Qnil;\n}\n\n#ifdef HAVE_GETGRENT\nstatic VALUE\nsetup_group(grp)\n    struct group *grp;\n{\n    VALUE mem;\n    char **tbl;\n\n    mem = rb_ary_new();\n    tbl = grp->gr_mem;\n    while (*tbl) {\n\trb_ary_push(mem, safe_setup_str(*tbl));\n\ttbl++;\n    }\n    return rb_struct_new(sGroup,\n\t\t\t safe_setup_str(grp->gr_name),\n#ifdef HAVE_ST_GR_PASSWD\n\t\t\t safe_setup_str(grp->gr_passwd),\n#endif\n\t\t\t PW_GID2VAL(grp->gr_gid),\n\t\t\t mem);\n}\n#endif\n\n/* Returns information about the group with specified integer group id (gid), \n * as found in /etc/group.\n *\n * The information is returned as a Struct::Group; see getgrent above for\n * details.\n *\n * e.g.  Etc.getgrgid(100) -> #<struct Struct::Group name=\"users\", passwd=\"x\",\n * gid=100, mem=[\"meta\", \"root\"]>\n *\n */\nstatic VALUE\netc_getgrgid(obj, id)\n    VALUE obj, id;\n{\n#ifdef HAVE_GETGRENT\n    gid_t gid;\n    struct group *grp;\n\n    rb_secure(4);\n    gid = PW_VAL2GID(id);\n    grp = getgrgid(gid);\n    if (grp == 0) rb_raise(rb_eArgError, \"can't find group for %d\", gid);\n    return setup_group(grp);\n#else\n    return Qnil;\n#endif\n}\n\n/* Returns information about the group with specified String name, as found \n * in /etc/group.\n *\n * The information is returned as a Struct::Group; see getgrent above for\n * details.\n *\n * e.g.  Etc.getgrnam('users') -> #<struct Struct::Group name=\"users\",\n * passwd=\"x\", gid=100, mem=[\"meta\", \"root\"]>\n *\n */\nstatic VALUE\netc_getgrnam(obj, nam)\n    VALUE obj, nam;\n{\n#ifdef HAVE_GETGRENT\n    struct group *grp;\n\n    rb_secure(4);\n    SafeStringValue(nam);\n    grp = getgrnam(RSTRING(nam)->ptr);\n    if (grp == 0) rb_raise(rb_eArgError, \"can't find group for %s\", RSTRING(nam)->ptr);\n    return setup_group(grp);\n#else\n    return Qnil;\n#endif\n}\n\n#ifdef HAVE_GETGRENT\nstatic int group_blocking = 0;\nstatic VALUE\ngroup_ensure()\n{\n    group_blocking = Qfalse;\n    return Qnil;\n}\n\nstatic VALUE\ngroup_iterate()\n{\n    struct group *pw;\n\n    setgrent();\n    while (pw = getgrent()) {\n\trb_yield(setup_group(pw));\n    }\n    endgrent();\n    return Qnil;\n}\n#endif\n\n/* Provides a convenient Ruby iterator which executes a block for each entry \n * in the /etc/group file.\n *\n * The code block is passed an Etc::Group struct; see getgrent above for \n * details.\n *\n * Example:\n *\n *     require 'etc'\n *\n *     Etc.group {|g|\n *       puts g.name + \": \" + g.mem.join(', ')\n *     }\n *\n */\nstatic VALUE\netc_group(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETGRENT\n    struct group *grp;\n\n    rb_secure(4);\n    if (rb_block_given_p()) {\n\tif (group_blocking) {\n\t    rb_raise(rb_eRuntimeError, \"parallel group iteration\");\n\t}\n\tgroup_blocking = Qtrue;\n\trb_ensure(group_iterate, 0, group_ensure, 0);\n    }\n    if (grp = getgrent()) {\n\treturn setup_group(grp);\n    }\n#endif\n    return Qnil;\n}\n\n/* Resets the process of reading the /etc/group file, so that the next call\n * to getgrent will return the first entry again.\n */\nstatic VALUE\netc_setgrent(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETGRENT\n    setgrent();\n#endif\n    return Qnil;\n}\n\n/* Ends the process of scanning through the /etc/group file begun by \n * getgrent, and closes the file.\n */\nstatic VALUE\netc_endgrent(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETGRENT\n    endgrent();\n#endif\n    return Qnil;\n}\n\n/* Returns an entry from the /etc/group file. The first time it is called it\n * opens the file and returns the first entry; each successive call returns \n * the next entry, or nil if the end of the file has been reached.\n *\n * To close the file when processing is complete, call endgrent.\n *\n * Each entry is returned as a Struct::Group:\n *\n * - Group#name contains the name of the group as a String.\n *\n * - Group#passwd contains the encrypted password as a String. An 'x' is\n *   returned if password access to the group is not available; an empty \n *   string is returned if no password is needed to obtain membership of \n *   the group.\n *\n * - Group#gid contains the group's numeric ID as an integer.\n *\n * - Group#mem is an Array of Strings containing the short login names of the \n *   members of the group.\n */\nstatic VALUE\netc_getgrent(obj)\n    VALUE obj;\n{\n#ifdef HAVE_GETGRENT\n    struct group *gr;\n\n    if (gr = getgrent()) {\n\treturn setup_group(gr);\n    }\n#endif\n    return Qnil;\n}\n\nstatic VALUE mEtc;\n\n/* The etc module provides access to information from the /etc/passwd and\n * /etc/group files on Linux and Unix systems.\n *\n * Documented by mathew <meta@pobox.com>.\n */\nvoid\nInit_etc()\n{\n    mEtc = rb_define_module(\"Etc\");\n\n    rb_define_module_function(mEtc, \"getlogin\", etc_getlogin, 0);\n\n    rb_define_module_function(mEtc, \"getpwuid\", etc_getpwuid, -1);\n    rb_define_module_function(mEtc, \"getpwnam\", etc_getpwnam, 1);\n    rb_define_module_function(mEtc, \"setpwent\", etc_setpwent, 0);\n    rb_define_module_function(mEtc, \"endpwent\", etc_endpwent, 0);\n    rb_define_module_function(mEtc, \"getpwent\", etc_getpwent, 0);\n    rb_define_module_function(mEtc, \"passwd\", etc_passwd, 0);\n\n    rb_define_module_function(mEtc, \"getgrgid\", etc_getgrgid, 1);\n    rb_define_module_function(mEtc, \"getgrnam\", etc_getgrnam, 1);\n    rb_define_module_function(mEtc, \"group\", etc_group, 0);\n    rb_define_module_function(mEtc, \"setgrent\", etc_setgrent, 0);\n    rb_define_module_function(mEtc, \"endgrent\", etc_endgrent, 0);\n    rb_define_module_function(mEtc, \"getgrent\", etc_getgrent, 0);\n\n    rb_global_variable(&sPasswd);\n    sPasswd =  rb_struct_define(\"Passwd\",\n\t\t\t\t\"name\", \"passwd\", \"uid\", \"gid\",\n#ifdef HAVE_ST_PW_GECOS\n\t\t\t\t\"gecos\",\n#endif\n\t\t\t\t\"dir\", \"shell\",\n#ifdef HAVE_ST_PW_CHANGE\n\t\t\t\t\"change\",\n#endif\n#ifdef HAVE_ST_PW_QUOTA\n\t\t\t\t\"quota\",\n#endif\n#ifdef HAVE_ST_PW_AGE\n\t\t\t\t\"age\",\n#endif\n#ifdef HAVE_ST_PW_CLASS\n\t\t\t\t\"uclass\",\n#endif\n#ifdef HAVE_ST_PW_COMMENT\n\t\t\t\t\"comment\",\n#endif\n#ifdef HAVE_ST_PW_EXPIRE\n\t\t\t\t\"expire\",\n#endif\n\t\t\t\tNULL);\n\n#ifdef HAVE_GETGRENT\n    rb_global_variable(&sGroup);\n    sGroup = rb_struct_define(\"Group\", \"name\",\n#ifdef HAVE_ST_GR_PASSWD\n\t\t\t      \"passwd\",\n#endif\n\t\t\t      \"gid\", \"mem\", NULL);\n#endif\n}\n"
  },
  {
    "path": "ext/etc/etc.txt",
    "content": ".\\\" etc.txt -  -*- Indented-Text -*- created at: Fri Jul 14 00:47:15 JST 1995\n\n** Etc(Module)\n\nThe module to retrieve information under /etc directory.  Available\nonly on UNIX platforms.  All operations defined in this module are\nmodule functions, so that you can include Etc module into your class.\n\nModule Function:\n\n   getlogin\n\n\treturns login name of the user.  It this fails, try getpwuid().\n\n   getpwnam(name)\n\n\tsearches in /etc/passwd file (or equivalent database), and\n\treturns password entry for the user.  The return value is an\n\tpasswd structure, which has members described below.\n\n\t  struct passwd\n\t    name \t# user name(string)\n\t    passwd\t# encrypted password(string)\n\t    uid\t\t# user ID(integer)\n\t    gid\t\t# group ID(integer)\n\t    gecos\t# gecos field(string)\n\t    dir\t\t# home directory(string)\n\t    shell\t# login shell(string)\n\t    # members below are optional\n\t    change\t# password change time(integer)\n\t    quota\t# quota value(integer)\n\t    age\t\t# password age(integer)\n\t    class\t# user access class(string)\n\t    comment\t# comment(string)\n\t    expire\t# account expiration time(integer)\t    \n\t  end\n\n\tSee getpwnam(3) for detail.\n\n   getpwuid([uid])\n\n\treturns passwd entry for the specified user id.  If uid is\n\tommitted, use the value from getuid().  See getpwuid(3) for\n\tdetail.\n\n   getgrgid(gid)\n\n\tsearches in /etc/group file (or equivalent database), and\n\treturns group entry for the group id.  The return value is an\n\tgroup structure, which has members described below.\n\n\t  struct group\n\t    name \t# group name(string)\n\t    passwd\t# group password(string)\n\t    gid\t\t# group ID(integer)\n\t    mem\t\t# array of the group member names\n\t  end\n\n\tSee getgrgid(3) for detail.\n\n   getgrnam(name)\n\n\treturns the group entry for the specified name.  The return\n\tvalue is the group structure.  See getgrnam(3) for detail.\n\n   group\n\n\titerates over all group entries.\n\n   passwd\n\n\titerates over all passwd entries.\n"
  },
  {
    "path": "ext/etc/etc.txt.ja",
    "content": ".\\\" etc.txt.ja -  -*- Indented-Text -*- created at: Fri Jul 14 00:47:15 JST 1995\n\n** Etc(⥸塼)\n\n/etcǥ쥯ȥʲξ뤿Υ⥸塼롥饹˥󥯥롼\nƻȤȤǤ롥\n\nModule Function:\n\n   getlogin\n\n\tʬlogin֤̾줬Ԥgetpwuid()Ѥ\n\tɤ\n\n   getpwnam(name)\n\n\t/etc/passwdե(뤤DBMեNISǡ١)\n\tname̾passwdȥ֤ͤpasswd¤\n\tΤǰʲΥФġ\n\n\t  struct passwd\n\t    name \t# 桼̾(ʸ)\n\t    passwd\t# ѥ(ʸ)\n\t    uid\t\t# 桼ID()\n\t    gid\t\t# 롼ID()\n\t    gecos\t# gecosե(ʸ)\n\t    dir\t\t# ۡǥ쥯ȥ(ʸ)\n\t    shell\t# 󥷥(ʸ)\n\t    # ʹߤΥФϥƥˤäƤ󶡤ʤ\n\t    change\t# ѥѹ()\n\t    quota\t# ()\n\t    age\t\t# ()\n\t    class\t# 桼饹(ʸ)\n\t    comment\t# (ʸ)\n\t    expire\t# ͭ()\t    \n\t  end\n\n\tܺ٤getpwnam(3)򻲾ȤΤȡ\n\n   getpwuid([uid])\n\n\tuid桼IDȤpasswdȥ֤ͤgetpwnam()\n\tƱͤǤ롥άˤgetuid()ͤѤ롥ܺ٤\n\tgetpwuid(3)򻲾ȤΤȡ\n\n   getgrgid(gid)\n\n\t/etc/groupե(뤤ϡgetpwnam)򸡺gid򥰥롼\n\tIDȤ륰롼ץȥ֤ͤgroup¤Τǰʲ\n\tФġ\n\n\t  struct group\n\t    name \t# 롼̾(ʸ)\n\t    passwd\t# 롼פΥѥ(ʸ)\n\t    gid\t\t# 롼ID()\n\t    mem\t\t# 롼ץ̾\n\t  end\n\n\tܺ٤getgrgid(3)򻲾ȤΤȡ\n\n   getgrnam(name)\n\n\tnameȤ̾Υ롼ץȥ֤ͤgetgrgid()Ʊ\n\tͤǤ롥ܺ٤getgrnam(3)򻲾ȡ\n\n   group\n\n\tƤΥ롼ץȥ˥뤿Υƥ졼\n\n   passwd\n\n\tƤpasswdȥ˥뤿Υƥ졼\n"
  },
  {
    "path": "ext/etc/extconf.rb",
    "content": "require 'mkmf'\n\nhave_library(\"sun\", \"getpwnam\")\t# NIS (== YP) interface for IRIX 4\na = have_func(\"getlogin\")\nb = have_func(\"getpwent\")\nc = have_func(\"getgrent\")\nif  a or b or c\n  have_struct_member('struct passwd', 'pw_gecos', 'pwd.h')\n  have_struct_member('struct passwd', 'pw_change', 'pwd.h')\n  have_struct_member('struct passwd', 'pw_quota', 'pwd.h')\n  if have_struct_member('struct passwd', 'pw_age', 'pwd.h')\n    case what_type?('struct passwd', 'pw_age', 'pwd.h')\n    when \"string\"\n      f = \"safe_setup_str\"\n    when \"long long\"\n      f = \"LL2NUM\"\n    else\n      f = \"INT2NUM\"\n    end\n    $defs.push(\"-DPW_AGE2VAL=\"+f)\n  end\n  have_struct_member('struct passwd', 'pw_class', 'pwd.h')\n  have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin/ === RUBY_PLATFORM\n  have_struct_member('struct passwd', 'pw_expire', 'pwd.h')\n  have_struct_member('struct passwd', 'pw_passwd', 'pwd.h')\n  have_struct_member('struct group', 'gr_passwd', 'grp.h')\n  [%w\"uid_t pwd.h\", %w\"gid_t grp.h\"].each do |t, *h|\n    h.unshift(\"sys/types.h\")\n    f = \"INT2NUM\"\n    if have_type(t, h)\n      if try_static_assert(\"sizeof(#{t}) > sizeof(long)\", h)\n\tf = \"LL2NUM\"\n      end\n      if try_static_assert(\"(#{t})-1 > 0\", h)\n\tf = \"U#{f}\"\n      end\n    end\n    t = t.chomp('_t').upcase\n    $defs.push(\"-DPW_#{t}2VAL=#{f}\")\n    $defs.push(\"-DPW_VAL2#{t}=#{f.sub(/([A-Z]+)2(NUM)/, '\\22\\1')}\")\n  end\n  create_makefile(\"etc\")\nend\n"
  },
  {
    "path": "ext/extmk.rb",
    "content": "#! /usr/local/bin/ruby\n# -*- ruby -*-\n\n$extension = nil\n$extstatic = nil\n$force_static = nil\n$install = nil\n$destdir = nil\n$dryrun = false\n$clean = nil\n$nodynamic = nil\n$extinit = nil\n$extobjs = nil\n$extflags = \"\"\n$extlibs = nil\n$extpath = nil\n$ignore = nil\n$message = nil\n\n$progname = $0\nalias $PROGRAM_NAME $0\nalias $0 $progname\n\n$extlist = []\n$compiled = {}\n\n$:.replace([Dir.pwd])\nrequire 'rbconfig'\n\nsrcdir = File.dirname(File.dirname(__FILE__))\n\n$:.unshift(srcdir, File.expand_path(\"lib\", srcdir))\n\n$topdir = \".\"\n$top_srcdir = srcdir\n\nrequire 'mkmf'\nrequire 'optparse/shellwords'\n\ndef sysquote(x)\n  @quote ||= /human|os2|macos/ =~ (CROSS_COMPILING || RUBY_PLATFORM)\n  @quote ? x.quote : x\nend\n\ndef relative_from(path, base)\n  dir = File.join(path, \"\")\n  if File.expand_path(dir) == File.expand_path(dir, base)\n    path\n  else\n    File.join(base, path)\n  end\nend\n\ndef extract_makefile(makefile, keep = true)\n  m = File.read(makefile)\n  if !(target = m[/^TARGET[ \\t]*=[ \\t]*(\\S*)/, 1])\n    return keep\n  end\n  installrb = {}\n  m.scan(/^install-rb-default:[ \\t]*(\\S+)\\n\\1:[ \\t]*(\\S+)/) {installrb[$2] = $1}\n  oldrb = installrb.keys.sort\n  newrb = install_rb(nil, \"\").collect {|d, *f| f}.flatten.sort\n  if target_prefix = m[/^target_prefix[ \\t]*=[ \\t]*\\/(.*)/, 1]\n    target = \"#{target_prefix}/#{target}\"\n  end\n  unless oldrb == newrb\n    if $extout\n      newrb.each {|f| installrb.delete(f)}\n      unless installrb.empty?\n        config = CONFIG.dup\n        install_dirs(target_prefix).each {|var, val| config[var] = val}\n        FileUtils.rm_f(installrb.values.collect {|f| Config.expand(f, config)}, :verbose => true)\n      end\n    end\n    return false\n  end\n  $target = target\n  $extconf_h = m[/^RUBY_EXTCONF_H[ \\t]*=[ \\t]*(\\S+)/, 1]\n  $static ||= m[/^EXTSTATIC[ \\t]*=[ \\t]*(\\S+)/, 1] || false\n  /^STATIC_LIB[ \\t]*=[ \\t]*\\S+/ =~ m or $static = nil\n  $preload = Shellwords.shellwords(m[/^preload[ \\t]*=[ \\t]*(.*)/, 1] || \"\")\n  $DLDFLAGS += \" \" + (m[/^dldflags[ \\t]*=[ \\t]*(.*)/, 1] || \"\")\n  if s = m[/^LIBS[ \\t]*=[ \\t]*(.*)/, 1]\n    s.sub!(/^#{Regexp.quote($LIBRUBYARG)} */, \"\")\n    s.sub!(/ *#{Regexp.quote($LIBS)}$/, \"\")\n    $libs = s\n  end\n  $objs = (m[/^OBJS[ \\t]*=[ \\t](.*)/, 1] || \"\").split\n  $srcs = (m[/^SRCS[ \\t]*=[ \\t](.*)/, 1] || \"\").split\n  $LOCAL_LIBS = m[/^LOCAL_LIBS[ \\t]*=[ \\t]*(.*)/, 1] || \"\"\n  $LIBPATH = Shellwords.shellwords(m[/^libpath[ \\t]*=[ \\t]*(.*)/, 1] || \"\") - %w[$(libdir) $(topdir)]\n  true\nend\n\ndef extmake(target)\n  print \"#{$message} #{target}\\n\"\n  $stdout.flush\n  if $force_static or $static_ext[target]\n    $static = target\n  else\n    $static = false\n  end\n\n  unless $ignore\n    return true if $nodynamic and not $static\n  end\n\n  FileUtils.mkpath target unless File.directory?(target)\n  begin\n    dir = Dir.pwd\n    FileUtils.mkpath target unless File.directory?(target)\n    Dir.chdir target\n    top_srcdir = $top_srcdir\n    topdir = $topdir\n    hdrdir = $hdrdir\n    prefix = \"../\" * (target.count(\"/\")+1)\n    $top_srcdir = relative_from(top_srcdir, prefix)\n    $hdrdir = relative_from(hdrdir, prefix)\n    $topdir = prefix + $topdir\n    $target = target\n    $mdir = target\n    $srcdir = File.join($top_srcdir, \"ext\", $mdir)\n    $preload = nil\n    $objs = \"\"\n    $srcs = \"\"\n    $compiled[target] = false\n    makefile = \"./Makefile\"\n    ok = File.exist?(makefile)\n    unless $ignore\n      rbconfig0 = Config::CONFIG\n      mkconfig0 = CONFIG\n      rbconfig = {\n\t\"hdrdir\" => $hdrdir,\n\t\"srcdir\" => $srcdir,\n\t\"topdir\" => $topdir,\n      }\n      mkconfig = {\n\t\"hdrdir\" => \"$(top_srcdir)\",\n\t\"srcdir\" => \"$(top_srcdir)/ext/#{$mdir}\",\n\t\"topdir\" => $topdir,\n      }\n      rbconfig0.each_pair {|key, val| rbconfig[key] ||= val.dup}\n      mkconfig0.each_pair {|key, val| mkconfig[key] ||= val.dup}\n      Config.module_eval {\n\tremove_const(:CONFIG)\n\tconst_set(:CONFIG, rbconfig)\n\tremove_const(:MAKEFILE_CONFIG)\n\tconst_set(:MAKEFILE_CONFIG, mkconfig)\n      }\n      Object.class_eval {\n\tremove_const(:CONFIG)\n\tconst_set(:CONFIG, mkconfig)\n      }\n      begin\n\t$extconf_h = nil\n\tok &&= extract_makefile(makefile)\n\tconf = [\"#{$srcdir}/makefile.rb\", \"#{$srcdir}/extconf.rb\"].find {|f| File.exist?(f)}\n\tif (($extconf_h && !File.exist?($extconf_h)) ||\n\t    !(t = modified?(makefile, MTIMES)) ||\n\t    [conf, \"#{$srcdir}/depend\"].any? {|f| modified?(f, [t])})\n        then\n\t  ok = false\n          init_mkmf\n\t  Logging::logfile 'mkmf.log'\n\t  rm_f makefile\n\t  if conf\n\t    load $0 = conf\n\t  else\n\t    create_makefile(target)\n\t  end\n\t  $defs << \"-DRUBY_EXPORT\" if $static\n\t  ok = File.exist?(makefile)\n\tend\n      rescue SystemExit\n\t# ignore\n      ensure\n\trm_f \"conftest*\"\n\tconfig = $0\n\t$0 = $PROGRAM_NAME\n      end\n    end\n    ok = yield(ok) if block_given?\n    unless ok\n      open(makefile, \"w\") do |f|\n\tf.print dummy_makefile(CONFIG[\"srcdir\"])\n      end\n      return true\n    end\n    args = sysquote($mflags)\n    unless $destdir.to_s.empty? or $mflags.include?(\"DESTDIR\")\n      args += [sysquote(\"DESTDIR=\" + relative_from($destdir, \"../\"+prefix))]\n    end\n    if $static\n      args += [\"static\"] unless $clean\n      $extlist.push [$static, $target, File.basename($target), $preload]\n    end\n    unless system($make, *args)\n      $ignore or $continue or return false\n    end\n    $compiled[target] = true\n    if $clean\n      FileUtils.rm_f(\"mkmf.log\")\n      if $clean != true\n\tFileUtils.rm_f([makefile, $extconf_h || \"extconf.h\"])\n      end\n      File.unlink(makefile) rescue nil\n    end\n    if $static\n      $extflags ||= \"\"\n      $extlibs ||= []\n      $extpath ||= []\n      unless $mswin\n        $extflags = ($extflags.split | $DLDFLAGS.split | $LDFLAGS.split).join(\" \")\n      end\n      $extlibs = merge_libs($extlibs, $libs.split, $LOCAL_LIBS.split)\n      $extpath |= $LIBPATH\n    end\n  ensure\n    unless $ignore\n      Config.module_eval {\n\tremove_const(:CONFIG)\n\tconst_set(:CONFIG, rbconfig0)\n\tremove_const(:MAKEFILE_CONFIG)\n\tconst_set(:MAKEFILE_CONFIG, mkconfig0)\n      }\n      Object.class_eval {\n\tremove_const(:CONFIG)\n\tconst_set(:CONFIG, mkconfig0)\n      }\n    end\n    $top_srcdir = top_srcdir\n    $topdir = topdir\n    $hdrdir = hdrdir\n    Dir.chdir dir\n  end\n  begin\n    Dir.rmdir target\n    target = File.dirname(target)\n  rescue SystemCallError\n    break\n  end while true\n  true\nend\n\ndef compiled?(target)\n  $compiled[target]\nend\n\ndef parse_args()\n  $mflags = []\n\n  opts = nil\n  $optparser ||= OptionParser.new do |opts|\n    opts.on('-n') {$dryrun = true}\n    opts.on('--[no-]extension [EXTS]', Array) do |v|\n      $extension = (v == false ? [] : v)\n    end\n    opts.on('--[no-]extstatic [STATIC]', Array) do |v|\n      if ($extstatic = v) == false\n        $extstatic = []\n      elsif v\n        $force_static = true if $extstatic.delete(\"static\")\n        $extstatic = nil if $extstatic.empty?\n      end\n    end\n    opts.on('--dest-dir=DIR') do |v|\n      $destdir = v\n    end\n    opts.on('--extout=DIR') do |v|\n      $extout = (v unless v.empty?)\n    end\n    opts.on('--make=MAKE') do |v|\n      $make = v || 'make'\n    end\n    opts.on('--make-flags=FLAGS', '--mflags', Shellwords) do |v|\n      v.grep(/\\A([-\\w]+)=(.*)/) {$configure_args[\"--#{$1}\"] = $2}\n      if arg = v.first\n        arg.insert(0, '-') if /\\A[^-][^=]*\\Z/ =~ arg\n      end\n      $mflags.concat(v)\n    end\n    opts.on('--message [MESSAGE]', String) do |v|\n      $message = v\n    end\n  end\n  begin\n    $optparser.parse!(ARGV)\n  rescue OptionParser::InvalidOption => e\n    retry if /^--/ =~ e.args[0]\n    $optparser.warn(e)\n    abort opts.to_s\n  end\n\n  $destdir ||= ''\n\n  $make, *rest = Shellwords.shellwords($make)\n  $mflags.unshift(*rest) unless rest.empty?\n\n  def $mflags.set?(flag)\n    grep(/\\A-(?!-).*#{flag.chr}/i) { return true }\n    false\n  end\n  def $mflags.defined?(var)\n    grep(/\\A#{var}=(.*)/) {return $1}\n    false\n  end\n\n  if $mflags.set?(?n)\n    $dryrun = true\n  else\n    $mflags.unshift '-n' if $dryrun\n  end\n\n  $continue = $mflags.set?(?k)\n  if $extout\n    $extout = '$(topdir)/'+$extout\n    Config::CONFIG[\"extout\"] = CONFIG[\"extout\"] = $extout\n    $extout_prefix = $extout ? \"$(extout)$(target_prefix)/\" : \"\"\n    $mflags << \"extout=#$extout\" << \"extout_prefix=#$extout_prefix\"\n  end\nend\n\nparse_args()\n\nif target = ARGV.shift and /^[a-z-]+$/ =~ target\n  $mflags.push(target)\n  case target\n  when /^(dist|real)?(clean)$/\n    target = $2\n    $ignore ||= true\n    $clean = $1 ? $1[0] : true\n  when /^install\\b/\n    $install = true\n    $ignore ||= true\n    $mflags.unshift(\"INSTALL_PROG=install -c -p -m 0755\",\n                    \"INSTALL_DATA=install -c -p -m 0644\",\n                    \"MAKEDIRS=mkdir -p\") if $dryrun\n  end\nend\nunless $message\n  if target\n    $message = target.sub(/^(\\w+)e?\\b/, '\\1ing').tr('-', ' ')\n  else\n    $message = \"compiling\"\n  end\nend\n\nEXEEXT = CONFIG['EXEEXT']\nif CROSS_COMPILING\n  $ruby = $mflags.defined?(\"MINIRUBY\") || CONFIG['MINIRUBY']\nelsif sep = config_string('BUILD_FILE_SEPARATOR')\n  $ruby = \"$(topdir:/=#{sep})#{sep}miniruby\" + EXEEXT\nelse\n  $ruby = '$(topdir)/miniruby' + EXEEXT\nend\n$ruby << \" -I'$(topdir)'\"\nunless CROSS_COMPILING\n  $ruby << \" -I'$(top_srcdir)/lib'\"\n  $ruby << \" -I'$(extout)/$(arch)' -I'$(extout)/common'\" if $extout\n  $ruby << \" -I./- -I'$(top_srcdir)/ext' -rpurelib.rb\"\n  ENV[\"RUBYLIB\"] = \"-\"\n  ENV[\"RUBYOPT\"] = \"-rpurelib.rb\"\nend\n$config_h = '$(topdir)/config.h'\n$mflags << \"ruby=#$ruby\"\n\nMTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)}\n\n# get static-link modules\n$static_ext = {}\nif $extstatic\n  $extstatic.each do |target|\n    target = target.downcase if /mswin32|bccwin32/ =~ RUBY_PLATFORM\n    $static_ext[target] = $static_ext.size\n  end\nend\nfor dir in [\"ext\", File::join($top_srcdir, \"ext\")]\n  setup = File::join(dir, CONFIG['setup'])\n  if File.file? setup\n    f = open(setup)\n    while line = f.gets()\n      line.chomp!\n      line.sub!(/#.*$/, '')\n      next if /^\\s*$/ =~ line\n      target, opt = line.split(nil, 3)\n      if target == 'option'\n\tcase opt\n\twhen 'nodynamic'\n\t  $nodynamic = true\n\tend\n\tnext\n      end\n      target = target.downcase if /mswin32|bccwin32/ =~ RUBY_PLATFORM\n      $static_ext[target] = $static_ext.size\n    end\n    MTIMES << f.mtime\n    $setup = setup\n    f.close\n    break\n  end\nend unless $extstatic\n\next_prefix = \"#{$top_srcdir}/ext\"\nexts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t}\nif $extension\n  exts |= $extension.select {|d| File.directory?(\"#{ext_prefix}/#{d}\")}\nelse\n  withes, withouts = %w[--with --without].collect {|w|\n    if not (w = %w[-extensions -ext].collect {|opt|arg_config(w+opt)}).any?\n      proc {false}\n    elsif (w = w.grep(String)).empty?\n      proc {true}\n    else\n      proc {|c1| w.collect {|opt| opt.split(/,/)}.flatten.any?(&c1)}\n    end\n  }\n  cond = proc {|ext|\n    cond1 = proc {|n| File.fnmatch(n, ext, File::FNM_PATHNAME)}\n    withes.call(cond1) or !withouts.call(cond1)\n  }\n  exts |= Dir.glob(\"#{ext_prefix}/*/**/extconf.rb\").collect {|d|\n    d = File.dirname(d)\n    d.slice!(0, ext_prefix.length + 1)\n    d\n  }.find_all {|ext|\n    with_config(ext, &cond)\n  }.sort\nend\n\nif $extout\n  extout = Config.expand(\"#{$extout}\", Config::CONFIG.merge(\"topdir\"=>$topdir))\n  unless $ignore\n    FileUtils.mkpath(extout)\n  end\nend\n\ndir = Dir.pwd\nFileUtils::makedirs('ext')\nDir::chdir('ext')\n\nhdrdir = $hdrdir\n$hdrdir = $top_srcdir = relative_from(srcdir, $topdir = \"..\")\nexts.each do |d|\n  extmake(d) or abort\nend\n$top_srcdir = srcdir\n$topdir = \".\"\n$hdrdir = hdrdir\n\nextinit = Struct.new(:c, :o) {\n  def initialize(src)\n    super(\"#{src}.c\", \"#{src}.#{$OBJEXT}\")\n  end\n}.new(\"extinit\")\nif $ignore\n  FileUtils.rm_f(extinit.to_a) if $clean\n  Dir.chdir \"..\"\n  if $clean\n    Dir.rmdir('ext') rescue nil\n    if $extout\n      FileUtils.rm_rf([extout+\"/common\", extout+\"/include/ruby\", extout+\"/rdoc\"])\n      FileUtils.rm_rf(extout+\"/\"+CONFIG[\"arch\"])\n      if $clean != true\n\tFileUtils.rm_rf(extout+\"/include/\"+CONFIG[\"arch\"])\n\tFileUtils.rm_f($mflags.defined?(\"INSTALLED_LIST\")||ENV[\"INSTALLED_LIST\"]||\".installed.list\")\n\tDir.rmdir(extout+\"/include\") rescue nil\n\tDir.rmdir(extout) rescue nil\n      end\n    end\n  end\n  exit\nend\n\n$extinit ||= \"\"\n$extobjs ||= \"\"\n$extpath ||= []\n$extflags ||= \"\"\n$extlibs ||= []\nunless $extlist.empty?\n  $extinit << \"\\n\" unless $extinit.empty?\n  list = $extlist.dup\n  built = []\n  while e = list.shift\n    s,t,i,r = e\n    if r and !(r -= built).empty?\n      l = list.size\n      if (while l > 0; break true if r.include?(list[l-=1][1]) end)\n        list.insert(l + 1, e)\n      end\n      next\n    end\n    f = format(\"%s/%s.%s\", s, i, $LIBEXT)\n    if File.exist?(f)\n      $extinit << \"    init(Init_#{i}, \\\"#{t}.so\\\");\\n\"\n      $extobjs << \"ext/#{f} \"\n      built << t\n    end\n  end\n\n  src = %{\\\n#include \"ruby.h\"\n\n#define init(func, name) {void func _((void)); ruby_init_ext(name, func);}\n\nvoid ruby_init_ext _((const char *name, void (*init)(void)));\n\nvoid Init_ext _((void))\\n{\\n#$extinit}\n}\n  if !modified?(extinit.c, MTIMES) || IO.read(extinit.c) != src\n    open(extinit.c, \"w\") {|f| f.print src}\n  end\n\n  $extobjs = \"ext/#{extinit.o} #{$extobjs}\"\n  if RUBY_PLATFORM =~ /m68k-human|beos/\n    $extflags.delete(\"-L/usr/local/lib\")\n  end\n  $extpath.delete(\"$(topdir)\")\n  $extflags = libpathflag($extpath) << \" \" << $extflags.strip\n  conf = [\n    ['LIBRUBY_SO_UPDATE', '$(LIBRUBY_EXTS)'],\n    ['SETUP', $setup],\n    [enable_config(\"shared\", $enable_shared) ? 'DLDOBJS' : 'EXTOBJS', $extobjs],\n    ['EXTLIBS', $extlibs.join(' ')], ['EXTLDFLAGS', $extflags]\n  ].map {|n, v|\n    \"#{n}=#{v}\" if v and !(v = v.strip).empty?\n  }.compact\n  puts conf\n  $stdout.flush\n  $mflags.concat(conf)\nelse\n  FileUtils.rm_f(extinit.to_a)\nend\nrubies = []\n%w[RUBY RUBYW STATIC_RUBY].each {|r|\n  n = r\n  if r = arg_config(\"--\"+r.downcase) || config_string(r+\"_INSTALL_NAME\")\n    rubies << Config.expand(r+=EXEEXT)\n    $mflags << \"#{n}=#{r}\"\n  end\n}\n\nDir.chdir \"..\"\nunless $destdir.to_s.empty?\n  $mflags.defined?(\"DESTDIR\") or $mflags << \"DESTDIR=#{$destdir}\"\nend\nputs \"making #{rubies.join(', ')}\"\n$stdout.flush\n$mflags.concat(rubies)\n\nif $nmake == ?b\n  unless (vars = $mflags.grep(/\\A\\w+=/n)).empty?\n    open(mkf = \"libruby.mk\", \"wb\") do |tmf|\n      tmf.puts(\"!include Makefile\")\n      tmf.puts\n      tmf.puts(*vars.map {|v| v.sub(/=/, \" = \")})\n      tmf.puts(\"PRE_LIBRUBY_UPDATE = del #{mkf}\")\n    end\n    $mflags.unshift(\"-f#{mkf}\")\n    vars.each {|flag| flag.sub!(/\\A/, \"-D\")}\n  end\nend\nsystem($make, *sysquote($mflags)) or exit($?.exitstatus)\n\n#Local variables:\n# mode: ruby\n#end:\n"
  },
  {
    "path": "ext/fcntl/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/fcntl/depend",
    "content": "fcntl.o: fcntl.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/fcntl/extconf.rb",
    "content": "require 'mkmf'\ncreate_makefile('fcntl')\n"
  },
  {
    "path": "ext/fcntl/fcntl.c",
    "content": "/************************************************\n\n  fcntl.c -\n\n  $Author$\n  created at: Mon Apr  7 18:53:05 JST 1997\n\n  Copyright (C) 1997-2001 Yukihiro Matsumoto\n\n************************************************/\n\n/************************************************\n= NAME\n\nfcntl - load the C fcntl.h defines\n\n= SYNOPSIS\n\n    require \"fcntl\"\n    m = s.fcntl(Fcntl::F_GETFL, 0)\n    f.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK|m)\n\n= DESCRIPTION\n\nThis module is just a translation of the C <fnctl.h> file.\n\n= NOTE\n\nOnly #define symbols get translated; you must still correctly\npack up your own arguments to pass as args for locking functions, etc.\n\n************************************************/\n\n#include \"ruby.h\"\n#include <fcntl.h>\n\n/* Fcntl loads the constants defined in the system's <fcntl.h> C header\n * file, and used with both the fcntl(2) and open(2) POSIX system calls.\n *\n * Copyright (C) 1997-2001 Yukihiro Matsumoto\n *\n * Documented by mathew <meta@pobox.com>\n *\n * = Usage\n * \n * To perform a fcntl(2) operation, use IO::fcntl in the core classes.\n *\n * To perform an open(2) operation, use IO::sysopen.\n *\n * The set of operations and constants available depends upon specific OS\n * platform. Some values listed below may not be supported on your system.\n *\n * The constants supported by Ruby for use with IO::fcntl are:\n *\n * - F_DUPFD - duplicate a close-on-exec file handle to a non-close-on-exec\n *   file handle.\n *\n * - F_GETFD - read the close-on-exec flag of a file handle.\n *\n * - F_SETFD - set the close-on-exec flag of a file handle.\n *\n * - FD_CLOEXEC - the value of the close-on-exec flag.\n *\n * - F_GETFL - get file descriptor flags.\n *\n * - F_SETFL - set file descriptor flags.\n *\n * - O_APPEND, O_NONBLOCK, etc (see below) - file descriptor flag\n *   values for the above.\n *\n * - F_GETLK - determine whether a given region of a file is locked.\n *\n * - F_SETLK - acquire a lock on a region of a file.\n *\n * - F_SETLKW - acquire a lock on a region of a file, waiting if necessary.\n *\n * - F_RDLCK, F_WRLCK, F_UNLCK - types of lock for the above.\n *\n * The constants supported by Ruby for use with IO::sysopen are:\n *\n * - O_APPEND - open file in append mode.\n *\n * - O_NOCTTY - open tty without it becoming controlling tty.\n *\n * - O_CREAT - create file if it doesn't exist.\n *\n * - O_EXCL - used with O_CREAT, fail if file exists.\n *\n * - O_TRUNC - truncate file on open.\n *\n * - O_NONBLOCK / O_NDELAY - open in non-blocking mode.\n *\n * - O_RDONLY - open read-only.\n *\n * - O_WRONLY - open write-only.\n *\n * - O_RDWR - open read-write.\n *\n * - O_ACCMODE - mask to extract read/write flags.\n *\n * Example:\n * \n *   require 'fcntl'\n *\n *   fd = IO::sysopen('/tmp/tempfile', \n *        Fcntl::O_WRONLY | Fcntl::O_EXCL | Fcntl::O_CREAT)\n *   f = IO.open(fd)\n *   f.syswrite(\"TEMP DATA\")\n *   f.close\n *\n */\nvoid\nInit_fcntl()\n{\n    VALUE mFcntl = rb_define_module(\"Fcntl\");\n#ifdef F_DUPFD\n    rb_define_const(mFcntl, \"F_DUPFD\", INT2NUM(F_DUPFD));\n#endif\n#ifdef F_GETFD\n    rb_define_const(mFcntl, \"F_GETFD\", INT2NUM(F_GETFD));\n#endif\n#ifdef F_GETLK\n    rb_define_const(mFcntl, \"F_GETLK\", INT2NUM(F_GETLK));\n#endif\n#ifdef F_SETFD\n    rb_define_const(mFcntl, \"F_SETFD\", INT2NUM(F_SETFD));\n#endif\n#ifdef F_GETFL\n    rb_define_const(mFcntl, \"F_GETFL\", INT2NUM(F_GETFL));\n#endif\n#ifdef F_SETFL\n    rb_define_const(mFcntl, \"F_SETFL\", INT2NUM(F_SETFL));\n#endif\n#ifdef F_SETLK\n    rb_define_const(mFcntl, \"F_SETLK\", INT2NUM(F_SETLK));\n#endif\n#ifdef F_SETLKW\n    rb_define_const(mFcntl, \"F_SETLKW\", INT2NUM(F_SETLKW));\n#endif\n#ifdef FD_CLOEXEC\n    rb_define_const(mFcntl, \"FD_CLOEXEC\", INT2NUM(FD_CLOEXEC));\n#endif\n#ifdef F_RDLCK\n    rb_define_const(mFcntl, \"F_RDLCK\", INT2NUM(F_RDLCK));\n#endif\n#ifdef F_UNLCK\n    rb_define_const(mFcntl, \"F_UNLCK\", INT2NUM(F_UNLCK));\n#endif\n#ifdef F_WRLCK\n    rb_define_const(mFcntl, \"F_WRLCK\", INT2NUM(F_WRLCK));\n#endif\n#ifdef O_CREAT\n    rb_define_const(mFcntl, \"O_CREAT\", INT2NUM(O_CREAT));\n#endif\n#ifdef O_EXCL\n    rb_define_const(mFcntl, \"O_EXCL\", INT2NUM(O_EXCL));\n#endif\n#ifdef O_NOCTTY\n    rb_define_const(mFcntl, \"O_NOCTTY\", INT2NUM(O_NOCTTY));\n#endif\n#ifdef O_TRUNC\n    rb_define_const(mFcntl, \"O_TRUNC\", INT2NUM(O_TRUNC));\n#endif\n#ifdef O_APPEND\n    rb_define_const(mFcntl, \"O_APPEND\", INT2NUM(O_APPEND));\n#endif\n#ifdef O_NONBLOCK\n    rb_define_const(mFcntl, \"O_NONBLOCK\", INT2NUM(O_NONBLOCK));\n#endif\n#ifdef O_NDELAY\n    rb_define_const(mFcntl, \"O_NDELAY\", INT2NUM(O_NDELAY));\n#endif\n#ifdef O_RDONLY\n    rb_define_const(mFcntl, \"O_RDONLY\", INT2NUM(O_RDONLY));\n#endif\n#ifdef O_RDWR\n    rb_define_const(mFcntl, \"O_RDWR\", INT2NUM(O_RDWR));\n#endif\n#ifdef O_WRONLY\n    rb_define_const(mFcntl, \"O_WRONLY\", INT2NUM(O_WRONLY));\n#endif\n#ifdef O_ACCMODE\n    rb_define_const(mFcntl, \"O_ACCMODE\", INT2FIX(O_ACCMODE));\n#else\n    rb_define_const(mFcntl, \"O_ACCMODE\", INT2FIX(O_RDONLY | O_WRONLY | O_RDWR));\n#endif\n}\n"
  },
  {
    "path": "ext/gdbm/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/gdbm/README",
    "content": "gdbm ext-library for Ruby 1.3 or later\n"
  },
  {
    "path": "ext/gdbm/depend",
    "content": "gdbm.o: gdbm.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/gdbm/extconf.rb",
    "content": "require 'mkmf'\n\ndir_config(\"gdbm\")\nif have_library(\"gdbm\", \"gdbm_open\") and\n   have_header(\"gdbm.h\")\n  create_makefile(\"gdbm\")\nend\n"
  },
  {
    "path": "ext/gdbm/gdbm.c",
    "content": "/************************************************\n\n  gdbm.c -\n\n  $Author$\n  $Date$\n  modified at: Mon Jan 24 15:59:52 JST 1994\n\n  Documentation by Peter Adolphs < futzilogik at users dot sourceforge dot net >\n\n************************************************/\n\n#include \"ruby.h\"\n\n#include <gdbm.h>\n#include <fcntl.h>\n#include <errno.h>\n\n/*\n * Document-class: GDBM\n *\n * == Summary\n *\n * Ruby extension for GNU dbm (gdbm) -- a simple database engine for storing\n * key-value pairs on disk.\n *\n * == Description\n *\n * GNU dbm is a library for simple databases. A database is a file that stores\n * key-value pairs. Gdbm allows the user to store, retrieve, and delete data by\n * key. It furthermore allows a non-sorted traversal of all key-value pairs.\n * A gdbm database thus provides the same functionality as a hash. As\n * with objects of the Hash class, elements can be accessed with <tt>[]</tt>.\n * Furthermore, GDBM mixes in the Enumerable module, thus providing convenient\n * methods such as #find, #collect, #map, etc.\n *\n * A process is allowed to open several different databases at the same time.\n * A process can open a database as a \"reader\" or a \"writer\". Whereas a reader\n * has only read-access to the database, a writer has read- and write-access.\n * A database can be accessed either by any number of readers or by exactly one\n * writer at the same time.\n *\n * == Examples\n *\n * 1. Opening/creating a database, and filling it with some entries:\n *\n *      require 'gdbm'\n *      \n *      gdbm = GDBM.new(\"fruitstore.db\")\n *      gdbm[\"ananas\"]    = \"3\"\n *      gdbm[\"banana\"]    = \"8\"\n *      gdbm[\"cranberry\"] = \"4909\"\n *      gdbm.close\n *\n * 2. Reading out a database:\n *\n *      require 'gdbm'\n *      \n *      gdbm = GDBM.new(\"fruitstore.db\")\n *      gdbm.each_pair do |key, value|\n *        print \"#{key}: #{value}\\n\"\n *      end\n *      gdbm.close\n *\n *    produces\n *\n *      banana: 8\n *      ananas: 3\n *      cranberry: 4909\n *\n * == Links\n *\n * * http://www.gnu.org/software/gdbm/\n */\nstatic VALUE rb_cGDBM, rb_eGDBMError, rb_eGDBMFatalError;\n\n#define RUBY_GDBM_RW_BIT 0x20000000\n\n#define MY_BLOCK_SIZE (2048)\n#define MY_FATAL_FUNC rb_gdbm_fatal\nstatic void\nrb_gdbm_fatal(msg)\n    char *msg;\n{\n    rb_raise(rb_eGDBMFatalError, \"%s\", msg);\n}\n\nstruct dbmdata {\n    int  di_size;\n    GDBM_FILE di_dbm;\n};\n\nstatic void\nclosed_dbm()\n{\n    rb_raise(rb_eRuntimeError, \"closed GDBM file\");\n}\n\n#define GetDBM(obj, dbmp) do {\\\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\\\n    if (dbmp == 0) closed_dbm();\\\n    if (dbmp->di_dbm == 0) closed_dbm();\\\n} while (0)\n\n#define GetDBM2(obj, data, dbm) {\\\n    GetDBM(obj, data);\\\n    (dbm) = dbmp->di_dbm;\\\n}\n\nstatic void\nfree_dbm(dbmp)\n    struct dbmdata *dbmp;\n{\n    if (dbmp) {\n        if (dbmp->di_dbm) gdbm_close(dbmp->di_dbm);\n        free(dbmp);\n    }\n}\n\n/*\n * call-seq:\n *     gdbm.close -> nil\n *\n * Closes the associated database file.\n */\nstatic VALUE\nfgdbm_close(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n\n    GetDBM(obj, dbmp);\n    gdbm_close(dbmp->di_dbm);\n    dbmp->di_dbm = 0;\n\n    return Qnil;\n}\n\n/*\n * call-seq:\n *     gdbm.closed?  -> true or false\n *\n * Returns true if the associated database file has been closed.\n */\nstatic VALUE\nfgdbm_closed(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\n    if (dbmp == 0)\n        return Qtrue;\n    if (dbmp->di_dbm == 0)\n        return Qtrue;\n\n    return Qfalse;\n}\n\nstatic VALUE fgdbm_s_alloc _((VALUE));\n\nstatic VALUE\nfgdbm_s_alloc(klass)\n    VALUE klass;\n{\n    return Data_Wrap_Struct(klass, 0, free_dbm, 0);\n}\n\n/*\n * call-seq:\n *      GDBM.new(filename, mode = 0666, flags = nil)\n *\n * Creates a new GDBM instance by opening a gdbm file named _filename_.\n * If the file does not exist, a new file with file mode _mode_ will be\n * created. _flags_ may be one of the following:\n * * *READER*  - open as a reader\n * * *WRITER*  - open as a writer\n * * *WRCREAT* - open as a writer; if the database does not exist, create a new one\n * * *NEWDB*   - open as a writer; overwrite any existing databases\n *\n * The values *WRITER*, *WRCREAT* and *NEWDB* may be combined with the following\n * values by bitwise or:\n * * *SYNC*    - cause all database operations to be synchronized to the disk\n * * *NOLOCK*  - do not lock the database file\n *\n * If no _flags_ are specified, the GDBM object will try to open the database\n * file as a writer and will create it if it does not already exist\n * (cf. flag <tt>WRCREAT</tt>). If this fails (for instance, if another process\n * has already opened the database as a reader), it will try to open the\n * database file as a reader (cf. flag <tt>READER</tt>).\n */\nstatic VALUE\nfgdbm_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE file, vmode, vflags;\n    GDBM_FILE dbm;\n    struct dbmdata *dbmp;\n    int mode, flags = 0;\n\n    if (rb_scan_args(argc, argv, \"12\", &file, &vmode, &vflags) == 1) {\n        mode = 0666;            /* default value */\n    }\n    else if (NIL_P(vmode)) {\n        mode = -1;              /* return nil if DB does not exist */\n    }\n    else {\n        mode = NUM2INT(vmode);\n    }\n\n    if (!NIL_P(vflags))\n        flags = NUM2INT(vflags);\n\n    SafeStringValue(file);\n\n    if (flags & RUBY_GDBM_RW_BIT) {\n        flags &= ~RUBY_GDBM_RW_BIT;\n\tdbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE, \n\t\t\tflags, mode, MY_FATAL_FUNC);\n    }\n    else {\n        dbm = 0;\n        if (mode >= 0)\n            dbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE, \n                            GDBM_WRCREAT|flags, mode, MY_FATAL_FUNC);\n        if (!dbm)\n            dbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE, \n                            GDBM_WRITER|flags, 0, MY_FATAL_FUNC);\n        if (!dbm)\n            dbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE, \n                            GDBM_READER|flags, 0, MY_FATAL_FUNC);\n    }\n\n    if (!dbm) {\n\tif (mode == -1) return Qnil;\n\n\tif (gdbm_errno == GDBM_FILE_OPEN_ERROR ||\n\t    gdbm_errno == GDBM_CANT_BE_READER ||\n\t    gdbm_errno == GDBM_CANT_BE_WRITER)\n\t    rb_sys_fail(RSTRING(file)->ptr);\n\telse\n\t    rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n    }\n\n    dbmp = ALLOC(struct dbmdata);\n    free_dbm(DATA_PTR(obj));\n    DATA_PTR(obj) = dbmp;\n    dbmp->di_dbm = dbm;\n    dbmp->di_size = -1;\n\n    return obj;\n}\n\n/*\n * call-seq:\n *      GDBM.open(filename, mode = 0666, flags = nil)\n *      GDBM.open(filename, mode = 0666, flags = nil) { |gdbm| ... }\n *\n * If called without a block, this is synonymous to GDBM::new.\n * If a block is given, the new GDBM instance will be passed to the block\n * as a parameter, and the corresponding database file will be closed\n * after the execution of the block code has been finished.\n *\n * Example for an open call with a block:\n *\n *   require 'gdbm'\n *   GDBM.open(\"fruitstore.db\") do |gdbm|\n *     gdbm.each_pair do |key, value|\n *       print \"#{key}: #{value}\\n\"\n *     end\n *   end\n */\nstatic VALUE\nfgdbm_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);\n\n    if (NIL_P(fgdbm_initialize(argc, argv, obj))) {\n\treturn Qnil;\n    }\n\n    if (rb_block_given_p()) {\n        return rb_ensure(rb_yield, obj, fgdbm_close, obj);\n    }\n\n    return obj;\n}\n\nstatic VALUE\nrb_gdbm_fetch(dbm, key)\n    GDBM_FILE dbm;\n    datum key;\n{\n    datum val;\n    VALUE str;\n\n    val = gdbm_fetch(dbm, key);\n    if (val.dptr == 0)\n        return Qnil;\n\n    str = rb_str_new(val.dptr, val.dsize);\n    free(val.dptr);\n    OBJ_TAINT(str);\n    return str;\n}\n\nstatic VALUE\nrb_gdbm_fetch2(dbm, keystr)\n    GDBM_FILE dbm;\n    VALUE keystr;\n{\n    datum key;\n\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    return rb_gdbm_fetch(dbm, key);\n}\n\nstatic VALUE\nrb_gdbm_fetch3(obj, keystr)\n    VALUE obj, keystr;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    GetDBM2(obj, dbmp, dbm);\n    return rb_gdbm_fetch2(dbm, keystr);\n}\n\nstatic VALUE\nrb_gdbm_firstkey(dbm)\n    GDBM_FILE dbm;\n{\n    datum key;\n    VALUE str;\n\n    key = gdbm_firstkey(dbm);\n    if (key.dptr == 0)\n        return Qnil;\n\n    str = rb_str_new(key.dptr, key.dsize);\n    free(key.dptr);\n    OBJ_TAINT(str);\n    return str;\n}\n\nstatic VALUE\nrb_gdbm_nextkey(dbm, keystr)\n    GDBM_FILE dbm;\n    VALUE keystr;\n{\n    datum key, key2;\n    VALUE str;\n\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n    key2 = gdbm_nextkey(dbm, key);\n    if (key2.dptr == 0)\n        return Qnil;\n\n    str = rb_str_new(key2.dptr, key2.dsize);\n    free(key2.dptr);\n    OBJ_TAINT(str);\n    return str;\n}\n\nstatic VALUE\nfgdbm_fetch(obj, keystr, ifnone)\n    VALUE obj, keystr, ifnone;\n{\n    VALUE valstr;\n\n    valstr = rb_gdbm_fetch3(obj, keystr);\n    if (NIL_P(valstr)) {\n\tif (ifnone == Qnil && rb_block_given_p())\n\t    return rb_yield(keystr);\n\treturn ifnone;\n    }\n    return valstr;\n}\n\n/*\n * call-seq:\n *      gdbm[key] -> value\n *\n * Retrieves the _value_ corresponding to _key_.\n */\nstatic VALUE\nfgdbm_aref(obj, keystr)\n    VALUE obj, keystr;\n{\n    return rb_gdbm_fetch3(obj, keystr);\n}\n\n/*\n * call-seq:\n *      gdbm.fetch(key [, default]) -> value\n *\n * Retrieves the _value_ corresponding to _key_. If there is no value\n * associated with _key_, _default_ will be returned instead.\n */\nstatic VALUE\nfgdbm_fetch_m(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE keystr, valstr, ifnone;\n\n    rb_scan_args(argc, argv, \"11\", &keystr, &ifnone);\n    valstr = fgdbm_fetch(obj, keystr, ifnone);\n    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))\n        rb_raise(rb_eIndexError, \"key not found\");\n\n    return valstr;\n}\n\n/*\n * call-seq:\n *      gdbm.index(value) -> key\n *\n * Returns the _key_ for a given _value_. If several keys may map to the\n * same value, the key that is found first will be returned.\n */\nstatic VALUE\nfgdbm_index(obj, valstr)\n    VALUE obj, valstr;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, valstr2;\n\n    StringValue(valstr);\n    GetDBM2(obj, dbmp, dbm);\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n\tvalstr2 = rb_gdbm_fetch2(dbm, keystr);\n        if (!NIL_P(valstr2) &&\n            RSTRING(valstr)->len == RSTRING(valstr2)->len &&\n            memcmp(RSTRING(valstr)->ptr, RSTRING(valstr2)->ptr,\n                   RSTRING(valstr)->len) == 0) {\n\t    return keystr;\n        }\n    }\n    return Qnil;\n}\n\nstatic VALUE\nfgdbm_indexes(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new;\n    int i;\n\n    new = rb_ary_new2(argc);\n    for (i=0; i<argc; i++) {\n\trb_ary_push(new, rb_gdbm_fetch3(obj, argv[i]));\n    }\n\n    return new;\n}\n\n/*\n * call-seq:\n *      gdbm.select { |value| block } -> array\n *\n * Returns a new array of all values of the database for which _block_\n * evaluates to true.\n */\nstatic VALUE\nfgdbm_select(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new = rb_ary_new2(argc);\n    int i;\n\n    if (rb_block_given_p()) {\n        GDBM_FILE dbm;\n        struct dbmdata *dbmp;\n        VALUE keystr;\n\n\tif (argc > 0) {\n\t    rb_raise(rb_eArgError, \"wrong number arguments(%d for 0)\", argc);\n\t}\n        GetDBM2(obj, dbmp, dbm);\n        for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n             keystr = rb_gdbm_nextkey(dbm, keystr)) {\n            VALUE assoc = rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr));\n\t    VALUE v = rb_yield(assoc);\n\n\t    if (RTEST(v)) {\n\t\trb_ary_push(new, assoc);\n\t    }\n\t    GetDBM2(obj, dbmp, dbm);\n        }\n    }\n    else {\n\trb_warn(\"GDBM#select(index..) is deprecated; use GDBM#values_at\");\n\n        for (i=0; i<argc; i++) {\n            rb_ary_push(new, rb_gdbm_fetch3(obj, argv[i]));\n        }\n    }\n\n    return new;\n}\n\n/*\n * call-seq:\n *      gdbm.values_at(key, ...) -> array\n *\n * Returns an array of the values associated with each specified _key_.\n */\nstatic VALUE\nfgdbm_values_at(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new = rb_ary_new2(argc);\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_ary_push(new, rb_gdbm_fetch3(obj, argv[i]));\n    }\n\n    return new;\n}\n\nstatic void\nrb_gdbm_modify(obj)\n    VALUE obj;\n{\n    rb_secure(4);\n    if (OBJ_FROZEN(obj)) rb_error_frozen(\"GDBM\");\n}\n\nstatic VALUE\nrb_gdbm_delete(obj, keystr)\n    VALUE obj, keystr;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    rb_gdbm_modify(obj);\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    if (!gdbm_exists(dbm, key)) {\n        return Qnil;\n    }\n\n    if (gdbm_delete(dbm, key)) {\n        dbmp->di_size = -1;\n        rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n    }\n    else if (dbmp->di_size >= 0) {\n        dbmp->di_size--;\n    }\n    return obj;\n}\n\n/*\n * call-seq:\n *      gdbm.delete(key) -> value or nil\n *\n * Removes the key-value-pair with the specified _key_ from this database and\n * returns the corresponding _value_. Returns nil if the database is empty.\n */\nstatic VALUE\nfgdbm_delete(obj, keystr)\n    VALUE obj, keystr;\n{\n    VALUE valstr;\n\n    valstr = fgdbm_fetch(obj, keystr, Qnil);\n    rb_gdbm_delete(obj, keystr);\n    return valstr;\n}\n\n/*\n * call-seq:\n *      gdbm.shift -> (key, value) or nil\n *\n * Removes a key-value-pair from this database and returns it as a \n * two-item array [ _key_, _value_ ]. Returns nil if the database is empty.\n */\nstatic VALUE\nfgdbm_shift(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, valstr;\n\n    rb_gdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    keystr = rb_gdbm_firstkey(dbm);\n    if (NIL_P(keystr)) return Qnil;\n    valstr = rb_gdbm_fetch2(dbm, keystr);\n    rb_gdbm_delete(obj, keystr);\n\n    return rb_assoc_new(keystr, valstr);\n}\n\n/*\n * call-seq:\n *      gdbm.delete_if { |key, value| block } -> gdbm\n *      gdbm.reject! { |key, value| block } -> gdbm\n *\n * Deletes every key-value pair from _gdbm_ for which _block_ evaluates to true.\n */\nstatic VALUE\nfgdbm_delete_if(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, valstr;\n    VALUE ret, ary = rb_ary_new();\n    int i, status = 0, n;\n\n    rb_gdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    n = dbmp->di_size;\n    dbmp->di_size = -1;\n\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        valstr = rb_gdbm_fetch2(dbm, keystr);\n        ret = rb_protect(rb_yield, rb_assoc_new(keystr, valstr), &status);\n        if (status != 0) break;\n        if (RTEST(ret)) rb_ary_push(ary, keystr);\n        GetDBM2(obj, dbmp, dbm);\n    }\n\n    for (i = 0; i < RARRAY(ary)->len; i++)\n        rb_gdbm_delete(obj, RARRAY(ary)->ptr[i]);\n    if (status) rb_jump_tag(status);\n    if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;\n\n    return obj;\n}\n\n/*\n * call-seq:\n *      gdbm.clear -> gdbm\n *\n * Removes all the key-value pairs within _gdbm_.\n */\nstatic VALUE\nfgdbm_clear(obj)\n    VALUE obj;\n{\n    datum key, nextkey;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    rb_gdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n\n#if 0\n    while (key = gdbm_firstkey(dbm), key.dptr) {\n        if (gdbm_delete(dbm, key)) {\n            free(key.dptr);\n            rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n        }\n        free(key.dptr); \n    }\n#else\n    while (key = gdbm_firstkey(dbm), key.dptr) {\n        for (; key.dptr; key = nextkey) {\n            nextkey = gdbm_nextkey(dbm, key);\n            if (gdbm_delete(dbm, key)) {\n                free(key.dptr);\n                if (nextkey.dptr) free(nextkey.dptr);\n                rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n            }\n            free(key.dptr);\n        }\n    }\n#endif\n    dbmp->di_size = 0;\n\n    return obj;\n}\n\n/*\n * call-seq:\n *     gdbm.invert  -> hash\n *\n * Returns a hash created by using _gdbm_'s values as keys, and the keys\n * as values.\n */\nstatic VALUE\nfgdbm_invert(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, valstr;\n    VALUE hash = rb_hash_new();\n\n    GetDBM2(obj, dbmp, dbm);\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\tvalstr = rb_gdbm_fetch2(dbm, keystr);\n\n\trb_hash_aset(hash, valstr, keystr);\n    }\n    return hash;\n}\n\nstatic VALUE each_pair _((VALUE));\n\nstatic VALUE\neach_pair(obj)\n    VALUE obj;\n{\n    return rb_funcall(obj, rb_intern(\"each_pair\"), 0, 0);\n}\n\nstatic VALUE fgdbm_store _((VALUE,VALUE,VALUE));\n\nstatic VALUE\nupdate_i(pair, dbm)\n    VALUE pair, dbm;\n{\n    Check_Type(pair, T_ARRAY);\n    if (RARRAY(pair)->len < 2) {\n\trb_raise(rb_eArgError, \"pair must be [key, value]\");\n    }\n    fgdbm_store(dbm, RARRAY(pair)->ptr[0], RARRAY(pair)->ptr[1]);\n    return Qnil;\n}\n\n/*\n * call-seq:\n *     gdbm.update(other) -> gdbm\n *\n * Adds the key-value pairs of _other_ to _gdbm_, overwriting entries with\n * duplicate keys with those from _other_. _other_ must have an each_pair\n * method.\n */\nstatic VALUE\nfgdbm_update(obj, other)\n    VALUE obj, other;\n{\n    rb_iterate(each_pair, other, update_i, obj);\n    return obj;\n}\n\n/*\n * call-seq:\n *     gdbm.replace(other) -> gdbm\n *\n * Replaces the content of _gdbm_ with the key-value pairs of _other_.\n * _other_ must have an each_pair method.\n */\nstatic VALUE\nfgdbm_replace(obj, other)\n    VALUE obj, other;\n{\n    fgdbm_clear(obj);\n    rb_iterate(each_pair, other, update_i, obj);\n    return obj;\n}\n\n/*\n * call-seq:\n *      gdbm[key]= value -> value\n *      gdbm.store(key, value) -> value\n *\n * Associates the value _value_ with the specified _key_.\n */\nstatic VALUE\nfgdbm_store(obj, keystr, valstr)\n    VALUE obj, keystr, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    rb_gdbm_modify(obj);\n    StringValue(keystr);\n    StringValue(valstr);\n\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n    if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {\n        if (errno == EPERM) rb_sys_fail(0);\n        rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n    }\n\n    return valstr;\n}\n\n/*\n * call-seq:\n *      gdbm.length -> fixnum\n *      gdbm.size -> fixnum\n *\n * Returns the number of key-value pairs in this database.\n */\nstatic VALUE\nfgdbm_length(obj)\n    VALUE obj;\n{\n    datum key, nextkey;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    int i = 0;\n\n    GetDBM2(obj, dbmp, dbm);\n    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);\n\n    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {\n        nextkey = gdbm_nextkey(dbm, key);\n        free(key.dptr);\n\ti++;\n    }\n    dbmp->di_size = i;\n\n    return INT2FIX(i);\n}\n\n/*\n * call-seq:\n *      gdbm.empty? -> true or false\n *\n * Returns true if the database is empty.\n */\nstatic VALUE\nfgdbm_empty_p(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    GetDBM(obj, dbmp);\n    if (dbmp->di_size < 0) {\n\tdbm = dbmp->di_dbm;\n\n\tkey = gdbm_firstkey(dbm);\n        if (key.dptr) {\n            free(key.dptr);\n            return Qfalse;\n\t}\n        return Qtrue;\n    }\n\n    if (dbmp->di_size == 0) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *      gdbm.each_value { |value| block } -> gdbm\n *\n * Executes _block_ for each key in the database, passing the corresponding\n * _value_ as a parameter.\n */\nstatic VALUE\nfgdbm_each_value(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        rb_yield(rb_gdbm_fetch2(dbm, keystr));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n    return obj;\n}\n\n/*\n * call-seq:\n *      gdbm.each_key { |key| block } -> gdbm\n *\n * Executes _block_ for each key in the database, passing the\n * _key_ as a parameter.\n */\nstatic VALUE\nfgdbm_each_key(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        rb_yield(keystr);\n\tGetDBM2(obj, dbmp, dbm);\n    }\n    return obj;\n}\n\n/*\n * call-seq:\n *      gdbm.each_pair { |key, value| block } -> gdbm\n *\n * Executes _block_ for each key in the database, passing the _key_ and the\n * correspoding _value_ as a parameter.\n */\nstatic VALUE\nfgdbm_each_pair(obj)\n    VALUE obj;\n{\n    GDBM_FILE dbm;\n    struct dbmdata *dbmp;\n    VALUE keystr;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        rb_yield(rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));\n        GetDBM2(obj, dbmp, dbm);\n    }\n\n    return obj;\n}\n\n/*\n * call-seq:\n *      gdbm.keys -> array\n *\n * Returns an array of all keys of this database.\n */\nstatic VALUE\nfgdbm_keys(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        rb_ary_push(ary, keystr);\n    }\n\n    return ary;\n}\n\n/*\n * call-seq:\n *      gdbm.values -> array\n *\n * Returns an array of all values of this database.\n */\nstatic VALUE\nfgdbm_values(obj)\n    VALUE obj;\n{\n    datum key, nextkey;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE valstr, ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {\n        nextkey = gdbm_nextkey(dbm, key);\n        valstr = rb_gdbm_fetch(dbm, key);\n        free(key.dptr);\n        rb_ary_push(ary, valstr);\n    }\n\n    return ary;\n}\n\n/*\n * call-seq:\n *      gdbm.has_key?(k) -> true or false\n *      gdbm.key?(k) -> true or false\n *\n * Returns true if the given key _k_ exists within the database.\n * Returns false otherwise.\n */\nstatic VALUE\nfgdbm_has_key(obj, keystr)\n    VALUE obj, keystr;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    if (gdbm_exists(dbm, key))\n        return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *      gdbm.has_value?(v) -> true or false\n *      gdbm.value?(v) -> true or false\n *\n * Returns true if the given value _v_ exists within the database.\n * Returns false otherwise.\n */\nstatic VALUE\nfgdbm_has_value(obj, valstr)\n    VALUE obj, valstr;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, valstr2;\n\n    StringValue(valstr);\n    GetDBM2(obj, dbmp, dbm);\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n\tvalstr2 = rb_gdbm_fetch2(dbm, keystr);\n\n        if (!NIL_P(valstr2) &&\n            RSTRING(valstr)->len == RSTRING(valstr2)->len &&\n            memcmp(RSTRING(valstr)->ptr, RSTRING(valstr2)->ptr,\n                   RSTRING(valstr)->len) == 0) {\n\t    return Qtrue;\n        }\n    }\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *     gdbm.to_a -> array\n *\n * Returns an array of all key-value pairs contained in the database.\n */\nstatic VALUE\nfgdbm_to_a(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        rb_ary_push(ary, rb_assoc_new(keystr, rb_gdbm_fetch2(dbm, keystr)));\n    }\n\n    return ary;\n}\n\n/*\n * call-seq:\n *     gdbm.reorganize -> gdbm\n *\n * Reorganizes the database file. This operation removes reserved space of\n * elements that have already been deleted. It is only useful after a lot of\n * deletions in the database.\n */\nstatic VALUE\nfgdbm_reorganize(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    rb_gdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    gdbm_reorganize(dbm);\n    return obj;\n}\n\n/*\n * call-seq:\n *     gdbm.sync -> gdbm\n *\n * Unless the _gdbm_ object has been opened with the *SYNC* flag, it is not\n * guarenteed that database modification operations are immediately applied to\n * the database file. This method ensures that all recent modifications\n * to the database are written to the file. Blocks until all writing operations\n * to the disk have been finished.\n */\nstatic VALUE\nfgdbm_sync(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n\n    rb_gdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    gdbm_sync(dbm);\n    return obj;\n}\n\n/*\n * call-seq:\n *     gdbm.cachesize = size -> size\n *\n * Sets the size of the internal bucket cache to _size_.\n */\nstatic VALUE\nfgdbm_set_cachesize(obj, val)\n    VALUE obj, val;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    int optval;\n\n    GetDBM2(obj, dbmp, dbm);\n    optval = FIX2INT(val);\n    if (gdbm_setopt(dbm, GDBM_CACHESIZE, &optval, sizeof(optval)) == -1) {\n        rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n    }\n    return val;\n}\n\n/*\n * call-seq:\n *     gdbm.fastmode = boolean -> boolean\n *\n * Turns the database's fast mode on or off. If fast mode is turned on, gdbm\n * does not wait for writes to be flushed to the disk before continuing.\n *\n * This option is obsolete for gdbm >= 1.8 since fast mode is turned on by\n * default. See also: #syncmode=\n */\nstatic VALUE\nfgdbm_set_fastmode(obj, val)\n    VALUE obj, val;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    int optval;\n\n    GetDBM2(obj, dbmp, dbm);\n    optval = 0;\n    if (RTEST(val))\n        optval = 1;\n\n    if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {\n        rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n    }\n    return val;\n}\n\n/*\n * call-seq:\n *     gdbm.syncmode = boolean -> boolean\n *\n * Turns the database's synchronization mode on or off. If the synchronization\n * mode is turned on, the database's in-memory state will be synchronized to\n * disk after every database modification operation. If the synchronization\n * mode is turned off, GDBM does not wait for writes to be flushed to the disk\n * before continuing.\n *\n * This option is only available for gdbm >= 1.8 where syncmode is turned off\n * by default. See also: #fastmode=\n */\nstatic VALUE\nfgdbm_set_syncmode(obj, val)\n    VALUE obj, val;\n{\n#if !defined(GDBM_SYNCMODE)\n    fgdbm_set_fastmode(obj, RTEST(val) ? Qfalse : Qtrue);\n    return val;\n#else\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    int optval;\n\n    GetDBM2(obj, dbmp, dbm);\n    optval = 0;\n    if (RTEST(val))\n        optval = 1;\n\n    if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {\n        rb_raise(rb_eGDBMError, \"%s\", gdbm_strerror(gdbm_errno));\n    }\n    return val;\n#endif\n}\n\n/*\n * call-seq:\n *     gdbm.to_hash -> hash\n *\n * Returns a hash of all key-value pairs contained in the database.\n */\nstatic VALUE\nfgdbm_to_hash(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n    GDBM_FILE dbm;\n    VALUE keystr, hash;\n\n    GetDBM2(obj, dbmp, dbm);\n    hash = rb_hash_new();\n    for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);\n         keystr = rb_gdbm_nextkey(dbm, keystr)) {\n\n        rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));\n    }\n\n    return hash;\n}\n\n/*\n * call-seq:\n *      gdbm.reject { |key, value| block } -> hash\n *\n * Returns a hash copy of _gdbm_ where all key-value pairs from _gdbm_ for\n * which _block_ evaluates to true are removed. See also: #delete_if\n */\nstatic VALUE\nfgdbm_reject(obj)\n    VALUE obj;\n{\n    return rb_hash_delete_if(fgdbm_to_hash(obj));\n}\n\nvoid\nInit_gdbm()\n{\n    rb_cGDBM = rb_define_class(\"GDBM\", rb_cObject);\n    rb_eGDBMError = rb_define_class(\"GDBMError\", rb_eStandardError);\n    rb_eGDBMFatalError = rb_define_class(\"GDBMFatalError\", rb_eException);\n    rb_include_module(rb_cGDBM, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cGDBM, fgdbm_s_alloc);\n    rb_define_singleton_method(rb_cGDBM, \"open\", fgdbm_s_open, -1);\n\n    rb_define_method(rb_cGDBM, \"initialize\", fgdbm_initialize, -1);\n    rb_define_method(rb_cGDBM, \"close\", fgdbm_close, 0);\n    rb_define_method(rb_cGDBM, \"closed?\", fgdbm_closed, 0);\n    rb_define_method(rb_cGDBM, \"[]\", fgdbm_aref, 1);\n    rb_define_method(rb_cGDBM, \"fetch\", fgdbm_fetch_m, -1);\n    rb_define_method(rb_cGDBM, \"[]=\", fgdbm_store, 2);\n    rb_define_method(rb_cGDBM, \"store\", fgdbm_store, 2);\n    rb_define_method(rb_cGDBM, \"index\",  fgdbm_index, 1);\n    rb_define_method(rb_cGDBM, \"indexes\",  fgdbm_indexes, -1);\n    rb_define_method(rb_cGDBM, \"indices\",  fgdbm_indexes, -1);\n    rb_define_method(rb_cGDBM, \"select\",  fgdbm_select, -1);\n    rb_define_method(rb_cGDBM, \"values_at\",  fgdbm_values_at, -1);\n    rb_define_method(rb_cGDBM, \"length\", fgdbm_length, 0);\n    rb_define_method(rb_cGDBM, \"size\", fgdbm_length, 0);\n    rb_define_method(rb_cGDBM, \"empty?\", fgdbm_empty_p, 0);\n    rb_define_method(rb_cGDBM, \"each\", fgdbm_each_pair, 0);\n    rb_define_method(rb_cGDBM, \"each_value\", fgdbm_each_value, 0);\n    rb_define_method(rb_cGDBM, \"each_key\", fgdbm_each_key, 0);\n    rb_define_method(rb_cGDBM, \"each_pair\", fgdbm_each_pair, 0);\n    rb_define_method(rb_cGDBM, \"keys\", fgdbm_keys, 0);\n    rb_define_method(rb_cGDBM, \"values\", fgdbm_values, 0);\n    rb_define_method(rb_cGDBM, \"shift\", fgdbm_shift, 0);\n    rb_define_method(rb_cGDBM, \"delete\", fgdbm_delete, 1);\n    rb_define_method(rb_cGDBM, \"delete_if\", fgdbm_delete_if, 0);\n    rb_define_method(rb_cGDBM, \"reject!\", fgdbm_delete_if, 0);\n    rb_define_method(rb_cGDBM, \"reject\", fgdbm_reject, 0);\n    rb_define_method(rb_cGDBM, \"clear\", fgdbm_clear, 0);\n    rb_define_method(rb_cGDBM, \"invert\", fgdbm_invert, 0);\n    rb_define_method(rb_cGDBM, \"update\", fgdbm_update, 1);\n    rb_define_method(rb_cGDBM, \"replace\", fgdbm_replace, 1);\n    rb_define_method(rb_cGDBM, \"reorganize\", fgdbm_reorganize, 0);\n    rb_define_method(rb_cGDBM, \"sync\", fgdbm_sync, 0);\n    /* rb_define_method(rb_cGDBM, \"setopt\", fgdbm_setopt, 2); */\n    rb_define_method(rb_cGDBM, \"cachesize=\", fgdbm_set_cachesize, 1);\n    rb_define_method(rb_cGDBM, \"fastmode=\", fgdbm_set_fastmode, 1);\n    rb_define_method(rb_cGDBM, \"syncmode=\", fgdbm_set_syncmode, 1);\n\n    rb_define_method(rb_cGDBM, \"include?\", fgdbm_has_key, 1);\n    rb_define_method(rb_cGDBM, \"has_key?\", fgdbm_has_key, 1);\n    rb_define_method(rb_cGDBM, \"member?\", fgdbm_has_key, 1);\n    rb_define_method(rb_cGDBM, \"has_value?\", fgdbm_has_value, 1);\n    rb_define_method(rb_cGDBM, \"key?\", fgdbm_has_key, 1);\n    rb_define_method(rb_cGDBM, \"value?\", fgdbm_has_value, 1);\n\n    rb_define_method(rb_cGDBM, \"to_a\", fgdbm_to_a, 0);\n    rb_define_method(rb_cGDBM, \"to_hash\", fgdbm_to_hash, 0);\n\n    /* flag for #new and #open: open database as a reader */\n    rb_define_const(rb_cGDBM, \"READER\",  INT2FIX(GDBM_READER|RUBY_GDBM_RW_BIT));\n    /* flag for #new and #open: open database as a writer */\n    rb_define_const(rb_cGDBM, \"WRITER\",  INT2FIX(GDBM_WRITER|RUBY_GDBM_RW_BIT));\n    /* flag for #new and #open: open database as a writer; if the database does not exist, create a new one */\n    rb_define_const(rb_cGDBM, \"WRCREAT\", INT2FIX(GDBM_WRCREAT|RUBY_GDBM_RW_BIT));\n    /* flag for #new and #open: open database as a writer; overwrite any existing databases  */\n    rb_define_const(rb_cGDBM, \"NEWDB\",   INT2FIX(GDBM_NEWDB|RUBY_GDBM_RW_BIT));\n\n    /* flag for #new and #open. this flag is obsolete for gdbm >= 1.8 */\n    rb_define_const(rb_cGDBM, \"FAST\", INT2FIX(GDBM_FAST));\n    /* this flag is obsolete in gdbm 1.8.\n       On gdbm 1.8, fast mode is default behavior. */\n\n    /* gdbm version 1.8 specific */\n#if defined(GDBM_SYNC)\n    /* flag for #new and #open. only for gdbm >= 1.8 */\n    rb_define_const(rb_cGDBM, \"SYNC\",    INT2FIX(GDBM_SYNC));\n#endif\n#if defined(GDBM_NOLOCK)\n    /* flag for #new and #open */\n    rb_define_const(rb_cGDBM, \"NOLOCK\",  INT2FIX(GDBM_NOLOCK));\n#endif\n    /* version of the gdbm library*/\n    rb_define_const(rb_cGDBM, \"VERSION\",  rb_str_new2(gdbm_version));\n}\n"
  },
  {
    "path": "ext/iconv/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\niconv.rb\nconfig.charset\n"
  },
  {
    "path": "ext/iconv/charset_alias.rb",
    "content": "#! /usr/bin/ruby\n# :stopdoc:\nrequire 'rbconfig'\nrequire 'optparse'\n\n# http://www.ctan.org/tex-archive/macros/texinfo/texinfo/intl/config.charset\n# Fri, 30 May 2003 00:09:00 GMT'\n\nOS = Config::CONFIG[\"target_os\"]\nSHELL = Config::CONFIG['SHELL']\n\nclass Hash::Ordered < Hash\n  def [](key)\n    val = super and val.last\n  end\n  def []=(key, val)\n    ary = fetch(key) {return super(key, [self.size, key, val])} and\n      ary << val\n  end\n  def sort\n    values.sort.collect {|i, *rest| rest}\n  end\n  def each(&block)\n    sort.each(&block)\n  end\nend\n\ndef charset_alias(config_charset, mapfile, target = OS)\n  map = Hash::Ordered.new\n  comments = []\n  open(config_charset) do |input|\n    input.find {|line| /^case \"\\$os\" in/ =~ line} or break\n    input.find {|line|\n      /^\\s*([-\\w\\*]+(?:\\s*\\|\\s*[-\\w\\*]+)*)(?=\\))/ =~ line and\n      $&.split('|').any? {|pattern| File.fnmatch?(pattern.strip, target)}\n    } or break\n    input.find do |line|\n      case line\n      when /^\\s*echo \"(?:\\$\\w+\\.)?([-\\w*]+)\\s+([-\\w]+)\"/\n        sys, can = $1, $2\n        can.downcase!\n        map[can] = sys\n        false\n      when /^\\s*;;/\n        true\n      else\n        false\n      end\n    end\n  end\n  case target\n  when /linux|-gnu/\n    # map.delete('ascii')\n  when /cygwin|os2-emx/\n    # get rid of tilde/yen problem.\n    map['shift_jis'] = 'cp932'\n  end\n  st = Hash.new(0)\n  map = map.sort.collect do |can, *sys|\n    if sys.grep(/^en_us(?=.|$)/i) {break true} == true\n      noen = %r\"^(?!en_us)\\w+_\\w+#{Regexp.new($')}$\"i #\"\n      sys.reject! {|s| noen =~ s}\n    end\n    sys = sys.first\n    st[sys] += 1\n    [can, sys]\n  end\n  st.delete_if {|sys, i| i == 1}.empty?\n  st.keys.each {|sys| st[sys] = nil}\n  st.default = nil\n  writer = proc do |f|\n    f.puts(\"require 'iconv.so'\")\n    f.puts\n    f.puts(comments)\n    f.puts(\"class Iconv\")\n    i = 0\n    map.each do |can, sys|\n      if s = st[sys]\n        sys = s\n      elsif st.key?(sys)\n        sys = (st[sys] = \"sys#{i+=1}\") + \" = '#{sys}'.freeze\"\n      else\n        sys = \"'#{sys}'.freeze\"\n      end\n      f.puts(\"  charset_map['#{can}'] = #{sys}\")\n    end\n    f.puts(\"end\")\n  end\n  if mapfile\n    open(mapfile, \"w\", &writer)\n  else\n    writer[STDOUT]\n  end\nend\n\ntarget = OS\nopt = nil\nARGV.options do |opt|\n  opt.banner << \" config.status map.rb\"\n  opt.on(\"--target OS\") {|t| target = t}\n  opt.parse! and (1..2) === ARGV.size\nend or abort opt.to_s\ncharset_alias(ARGV[0], ARGV[1], target)\n"
  },
  {
    "path": "ext/iconv/depend",
    "content": "iconv.o: iconv.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h \\\n  $(hdrdir)/intern.h\n"
  },
  {
    "path": "ext/iconv/extconf.rb",
    "content": "require 'mkmf'\n\ndir_config(\"iconv\")\n\nconf = File.exist?(File.join($srcdir, \"config.charset\"))\nconf = with_config(\"config-charset\", enable_config(\"config-charset\", conf))\n\nif have_func(\"iconv\", \"iconv.h\") or\n    have_library(\"iconv\", \"iconv\", \"iconv.h\")\n  if checking_for(\"const of iconv() 2nd argument\") do\n      create_tmpsrc(cpp_include(\"iconv.h\") + \"---> iconv(cd,0,0,0,0) <---\")\n      src = xpopen(cpp_command(\"\")) {|f|f.read}\n      if !(func = src[/^--->\\s*(\\w+).*\\s*<---/, 1])\n        Logging::message \"iconv function name not found\"\n        false\n      elsif !(second = src[%r\"\\b#{func}\\s*\\(.*?,(.*?),.*?\\)\\s*;\"m, 1])\n        Logging::message \"prototype for #{func}() not found\"\n        false\n      else\n        Logging::message $&+\"\\n\"\n        /\\bconst\\b/ =~ second\n      end\n    end\n    $defs.push('-DICONV_INPTR_CONST')\n  end\n  if conf\n    prefix = '$(srcdir)'\n    prefix =  $nmake ? \"{#{prefix}}\" : \"#{prefix}/\"\n    if $extout\n      wrapper = \"$(RUBYARCHDIR)/iconv.rb\"\n    else\n      wrapper = \"./iconv.rb\"\n      $INSTALLFILES = [[wrapper, \"$(RUBYARCHDIR)\"]]\n    end\n    if String === conf\n      require 'uri'\n      scheme = URI.parse(conf).scheme\n    else\n      conf = \"$(srcdir)/config.charset\"\n    end\n    $cleanfiles << wrapper\n  end\n  create_makefile(\"iconv\")\n  if conf\n    open(\"Makefile\", \"a\") do |mf|\n      mf.print(\"\\nall: #{wrapper}\\n\\n#{wrapper}: #{prefix}charset_alias.rb\")\n      mf.print(\" \", conf) unless scheme\n      mf.print(\"\\n\\t$(RUBY) $(srcdir)/charset_alias.rb #{conf} $@\\n\")\n    end\n  end\nend\n"
  },
  {
    "path": "ext/iconv/iconv.c",
    "content": "/* -*- mode:c; c-file-style:\"ruby\" -*- */\n/**********************************************************************\n\n  iconv.c -\n\n  $Author$\n  $Date$\n  created at: Wed Dec  1 20:28:09 JST 1999\n\n  All the files in this distribution are covered under the Ruby's\n  license (see the file COPYING).\n\n  Documentation by Yukihiro Matsumoto and Gavin Sinclair.\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include <errno.h>\n#include <iconv.h>\n#include <assert.h>\n#include \"st.h\"\n#include \"intern.h\"\n\n/*\n * Document-class: Iconv\n *\n * == Summary\n *\n * Ruby extension for charset conversion.\n * \n * == Abstract\n *\n * Iconv is a wrapper class for the UNIX 95 <tt>iconv()</tt> function family,\n * which translates string between various encoding systems.\n * \n * See Open Group's on-line documents for more details.\n * * <tt>iconv.h</tt>:       http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.h.html\n * * <tt>iconv_open()</tt>:  http://www.opengroup.org/onlinepubs/007908799/xsh/iconv_open.html\n * * <tt>iconv()</tt>:       http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html\n * * <tt>iconv_close()</tt>: http://www.opengroup.org/onlinepubs/007908799/xsh/iconv_close.html\n * \n * Which coding systems are available is platform-dependent.\n * \n * == Examples\n *\n * 1. Simple conversion between two charsets.\n *\n *      converted_text = Iconv.conv('iso-8859-15', 'utf-8', text)\n *\n * 2. Instantiate a new Iconv and use method Iconv#iconv.\n *\n *      cd = Iconv.new(to, from)\n *      begin\n *        input.each { |s| output << cd.iconv(s) }\n *        output << cd.iconv(nil)                   # Don't forget this!\n *      ensure\n *        cd.close\n *      end\n *\n * 3. Invoke Iconv.open with a block.\n *\n *      Iconv.open(to, from) do |cd|\n *        input.each { |s| output << cd.iconv(s) }\n *        output << cd.iconv(nil)\n *      end\n *\n * 4. Shorthand for (3).\n *\n *      Iconv.iconv(to, from, *input.to_a)\n */\n\n/* Invalid value for iconv_t is -1 but 0 for VALUE, I hope VALUE is\n   big enough to keep iconv_t */\n#define VALUE2ICONV(v) ((iconv_t)((VALUE)(v) ^ -1))\n#define ICONV2VALUE(c) ((VALUE)(c) ^ -1)\n\nstruct iconv_env_t\n{\n    iconv_t cd;\n    int argc;\n    VALUE *argv;\n    VALUE ret;\n    VALUE (*append)_((VALUE, VALUE));\n};\n\nstatic VALUE rb_eIconvInvalidEncoding;\nstatic VALUE rb_eIconvFailure;\nstatic VALUE rb_eIconvIllegalSeq;\nstatic VALUE rb_eIconvInvalidChar;\nstatic VALUE rb_eIconvOutOfRange;\nstatic VALUE rb_eIconvBrokenLibrary;\n\nstatic ID rb_success, rb_failed;\nstatic VALUE iconv_fail _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg));\nstatic VALUE iconv_fail_retry _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg));\nstatic VALUE iconv_failure_initialize _((VALUE error, VALUE mesg, VALUE success, VALUE failed));\nstatic VALUE iconv_failure_success _((VALUE self));\nstatic VALUE iconv_failure_failed _((VALUE self));\n\nstatic iconv_t iconv_create _((VALUE to, VALUE from));\nstatic void iconv_dfree _((void *cd));\nstatic VALUE iconv_free _((VALUE cd));\nstatic VALUE iconv_try _((iconv_t cd, const char **inptr, size_t *inlen, char **outptr, size_t *outlen));\nstatic VALUE rb_str_derive _((VALUE str, const char* ptr, int len));\nstatic VALUE iconv_convert _((iconv_t cd, VALUE str, long start, long length, struct iconv_env_t* env));\nstatic VALUE iconv_s_allocate _((VALUE klass));\nstatic VALUE iconv_initialize _((VALUE self, VALUE to, VALUE from));\nstatic VALUE iconv_s_open _((VALUE self, VALUE to, VALUE from));\nstatic VALUE iconv_s_convert _((struct iconv_env_t* env));\nstatic VALUE iconv_s_iconv _((int argc, VALUE *argv, VALUE self));\nstatic VALUE iconv_init_state _((VALUE cd));\nstatic VALUE iconv_finish _((VALUE self));\nstatic VALUE iconv_iconv _((int argc, VALUE *argv, VALUE self));\n\nstatic VALUE charset_map;\n\n/*\n * Document-method: charset_map\n * call-seq: Iconv.charset_map\n *\n * Returns the map from canonical name to system dependent name.\n */\nstatic VALUE charset_map_get _((void))\n{\n    return charset_map;\n}\n\nstatic char *\nmap_charset\n#ifdef HAVE_PROTOTYPES\n    (VALUE *code)\n#else /* HAVE_PROTOTYPES */\n    (code)\n    VALUE *code;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE val = *code;\n\n    if (RHASH(charset_map)->tbl && RHASH(charset_map)->tbl->num_entries) {\n\tVALUE key = rb_funcall2(val, rb_intern(\"downcase\"), 0, 0);\n\tStringValuePtr(key);\n\tif (st_lookup(RHASH(charset_map)->tbl, key, &val)) {\n\t    *code = val;\n\t}\n    }\n    return StringValuePtr(*code);\n}\n\nstatic iconv_t\niconv_create\n#ifdef HAVE_PROTOTYPES\n    (VALUE to, VALUE from)\n#else /* HAVE_PROTOTYPES */\n    (to, from)\n    VALUE to;\n    VALUE from;\n#endif /* HAVE_PROTOTYPES */\n{\n    const char* tocode = map_charset(&to);\n    const char* fromcode = map_charset(&from);\n\n    iconv_t cd = iconv_open(tocode, fromcode);\n\n    if (cd == (iconv_t)-1) {\n\tswitch (errno) {\n\t  case EMFILE:\n\t  case ENFILE:\n\t  case ENOMEM:\n\t    rb_gc();\n\t    cd = iconv_open(tocode, fromcode);\n\t}\n\tif (cd == (iconv_t)-1) {\n\t    int inval = errno == EINVAL;\n\t    const char *s = inval ? \"invalid encoding \" : \"iconv\";\n\t    volatile VALUE msg = rb_str_new(0, strlen(s) + RSTRING(to)->len +\n\t\t\t\t\t    RSTRING(from)->len + 8);\n\n\t    sprintf(RSTRING(msg)->ptr, \"%s(\\\"%s\\\", \\\"%s\\\")\",\n\t\t    s, RSTRING(to)->ptr, RSTRING(from)->ptr);\n\t    s = RSTRING(msg)->ptr;\n\t    RSTRING(msg)->len = strlen(s);\n\t    if (!inval) rb_sys_fail(s);\n\t    rb_exc_raise(iconv_fail(rb_eIconvInvalidEncoding, Qnil,\n\t\t\t\t    rb_ary_new3(2, to, from), NULL, s));\n\t}\n    }\n\n    return cd;\n}\n\nstatic void\niconv_dfree\n#ifdef HAVE_PROTOTYPES\n    (void *cd)\n#else /* HAVE_PROTOTYPES */\n    (cd)\n    void *cd;\n#endif /* HAVE_PROTOTYPES */\n{\n    iconv_close(VALUE2ICONV(cd));\n}\n\n#define ICONV_FREE iconv_dfree\n\nstatic VALUE\niconv_free\n#ifdef HAVE_PROTOTYPES\n    (VALUE cd)\n#else /* HAVE_PROTOTYPES */\n    (cd)\n    VALUE cd;\n#endif /* HAVE_PROTOTYPES */\n{\n    if (cd && iconv_close(VALUE2ICONV(cd)) == -1)\n\trb_sys_fail(\"iconv_close\");\n    return Qnil;\n}\n\nstatic VALUE\ncheck_iconv\n#ifdef HAVE_PROTOTYPES\n    (VALUE obj)\n#else /* HAVE_PROTOTYPES */\n    (obj)\n    VALUE obj;\n#endif /* HAVE_PROTOTYPES */\n{\n    Check_Type(obj, T_DATA);\n    if (RDATA(obj)->dfree != ICONV_FREE) {\n\trb_raise(rb_eArgError, \"Iconv expected (%s)\", rb_class2name(CLASS_OF(obj)));\n    }\n    return (VALUE)DATA_PTR(obj);\n}\n\nstatic VALUE\niconv_try\n#ifdef HAVE_PROTOTYPES\n    (iconv_t cd, const char **inptr, size_t *inlen, char **outptr, size_t *outlen)\n#else /* HAVE_PROTOTYPES */\n    (cd, inptr, inlen, outptr, outlen)\n    iconv_t cd;\n    const char **inptr;\n    size_t *inlen;\n    char **outptr;\n    size_t *outlen;\n#endif /* HAVE_PROTOTYPES */\n{\n#ifdef ICONV_INPTR_CONST\n#define ICONV_INPTR_CAST\n#else\n#define ICONV_INPTR_CAST (char **)\n#endif\n    size_t ret;\n\n    errno = 0;\n    ret = iconv(cd, ICONV_INPTR_CAST inptr, inlen, outptr, outlen);\n    if (ret == (size_t)-1) {\n\tif (!*inlen)\n\t    return Qfalse;\n\tswitch (errno) {\n\t  case E2BIG:\n\t    /* try the left in next loop */\n\t    break;\n\t  case EILSEQ:\n\t    return rb_eIconvIllegalSeq;\n\t  case EINVAL:\n\t    return rb_eIconvInvalidChar;\n\t  case 0:\n\t    return rb_eIconvBrokenLibrary;\n\t  default:\n\t    rb_sys_fail(\"iconv\");\n\t}\n    }\n    else if (*inlen > 0) {\n\t/* something goes wrong */\n\treturn rb_eIconvIllegalSeq;\n    }\n    else if (ret) {\n\treturn Qnil;\t\t/* conversion */\n    }\n    return Qfalse;\n}\n\n#define FAILED_MAXLEN 16\n\nstatic VALUE iconv_failure_initialize\n#ifdef HAVE_PROTOTYPES\n    (VALUE error, VALUE mesg, VALUE success, VALUE failed)\n#else /* HAVE_PROTOTYPES */\n    (error, mesg, success, failed)\n    VALUE error, mesg, success, failed;\n#endif /* HAVE_PROTOTYPES */\n{\n    rb_call_super(1, &mesg);\n    rb_ivar_set(error, rb_success, success);\n    rb_ivar_set(error, rb_failed, failed);\n    return error;\n}\n\nstatic VALUE\niconv_fail\n#ifdef HAVE_PROTOTYPES\n    (VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg)\n#else /* HAVE_PROTOTYPES */\n    (error, success, failed, env, mesg)\n    VALUE error, success, failed;\n    struct iconv_env_t *env;\n    const char *mesg;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE args[3];\n\n    if (mesg && *mesg) {\n\targs[0] = rb_str_new2(mesg);\n    }\n    else if (TYPE(failed) != T_STRING || RSTRING(failed)->len < FAILED_MAXLEN) {\n\targs[0] = rb_inspect(failed);\n    }\n    else {\n\targs[0] = rb_inspect(rb_str_substr(failed, 0, FAILED_MAXLEN));\n\trb_str_cat2(args[0], \"...\");\n    }\n    args[1] = success;\n    args[2] = failed;\n    if (env) {\n\targs[1] = env->append(rb_obj_dup(env->ret), success);\n\tif (env->argc > 0) {\n\t    *(env->argv) = failed;\n\t    args[2] = rb_ary_new4(env->argc, env->argv);\n\t}\n    }\n    return rb_class_new_instance(3, args, error);\n}\n\nstatic VALUE\niconv_fail_retry(VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg)\n{\n    error = iconv_fail(error, success, failed, env, mesg);\n    if (!rb_block_given_p()) rb_exc_raise(error);\n    ruby_errinfo = error;\n    return rb_yield(failed);\n}\n\nstatic VALUE\nrb_str_derive\n#ifdef HAVE_PROTOTYPES\n    (VALUE str, const char* ptr, int len)\n#else /* HAVE_PROTOTYPES */\n    (str, ptr, len)\n    VALUE str;\n    const char *ptr;\n    int len;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE ret;\n\n    if (NIL_P(str))\n\treturn rb_str_new(ptr, len);\n    if (RSTRING(str)->ptr == ptr && RSTRING(str)->len == len)\n\treturn str;\n    if (RSTRING(str)->ptr + RSTRING(str)->len == ptr + len)\n\tret = rb_str_substr(str, ptr - RSTRING(str)->ptr, len);\n    else\n\tret = rb_str_new(ptr, len);\n    OBJ_INFECT(ret, str);\n    return ret;\n}\n\nstatic VALUE\niconv_convert\n#ifdef HAVE_PROTOTYPES\n    (iconv_t cd, VALUE str, long start, long length, struct iconv_env_t* env)\n#else /* HAVE_PROTOTYPES */\n    (cd, str, start, length, env)\n    iconv_t cd;\n    VALUE str;\n    long start;\n    long length;\n    struct iconv_env_t *env;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE ret = Qfalse;\n    VALUE error = Qfalse;\n    VALUE rescue;\n    const char *inptr, *instart;\n    size_t inlen;\n    /* I believe ONE CHARACTER never exceed this. */\n    char buffer[BUFSIZ];\n    char *outptr;\n    size_t outlen;\n\n    if (cd == (iconv_t)-1)\n\trb_raise(rb_eArgError, \"closed iconv\");\n\n    if (NIL_P(str)) {\n\t/* Reset output pointer or something. */\n\tinptr = \"\";\n\tinlen = 0;\n\toutptr = buffer;\n\toutlen = sizeof(buffer);\n\terror = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);\n\tif (RTEST(error)) {\n\t    unsigned int i;\n\t    rescue = iconv_fail_retry(error, Qnil, Qnil, env, 0);\n\t    if (TYPE(rescue) == T_ARRAY) {\n\t\tstr = RARRAY(rescue)->len > 0 ? RARRAY(rescue)->ptr[0] : Qnil;\n\t    }\n\t    if (FIXNUM_P(str) && (i = FIX2INT(str)) <= 0xff) {\n\t\tchar c = i;\n\t\tstr = rb_str_new(&c, 1);\n\t    }\n\t    else if (!NIL_P(str)) {\n\t\tStringValue(str);\n\t    }\n\t}\n\n\tinptr = NULL;\n\tlength = 0;\n    }\n    else {\n\tint slen;\n\n\tStringValue(str);\n\tslen = RSTRING(str)->len;\n\tinptr = RSTRING(str)->ptr;\n\n\tinptr += start;\n\tif (length < 0 || length > start + slen)\n\t    length = slen - start;\n    }\n    instart = inptr;\n    inlen = length;\n\n    do {\n\tchar errmsg[50];\n\tconst char *tmpstart = inptr;\n\toutptr = buffer;\n\toutlen = sizeof(buffer);\n\n\terrmsg[0] = 0;\n\terror = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);\n\n\tif (0 <= outlen && outlen <= sizeof(buffer)) {\n\t    outlen = sizeof(buffer) - outlen;\n\t    if (NIL_P(error) ||\t/* something converted */\n\t\toutlen > inptr - tmpstart || /* input can't contain output */\n\t\t(outlen < inptr - tmpstart && inlen > 0) || /* something skipped */\n\t\tmemcmp(buffer, tmpstart, outlen)) /* something differs */\n\t    {\n\t\tif (NIL_P(str)) {\n\t\t    ret = rb_str_new(buffer, outlen);\n\t\t}\n\t\telse {\n\t\t    if (ret) {\n\t\t\tret = rb_str_buf_cat(ret, instart, tmpstart - instart);\n\t\t    }\n\t\t    else {\n\t\t\tret = rb_str_new(instart, tmpstart - instart);\n\t\t\tOBJ_INFECT(ret, str);\n\t\t    }\n\t\t    ret = rb_str_buf_cat(ret, buffer, outlen);\n\t\t    instart = inptr;\n\t\t}\n\t    }\n\t    else if (!inlen) {\n\t\tinptr = tmpstart + outlen;\n\t    }\n\t}\n\telse {\n\t    /* Some iconv() have a bug, return *outlen out of range */\n\t    sprintf(errmsg, \"bug?(output length = %ld)\", (long)(sizeof(buffer) - outlen));\n\t    error = rb_eIconvOutOfRange;\n\t}\n\n\tif (RTEST(error)) {\n\t    long len = 0;\n\n\t    if (!ret)\n\t\tret = rb_str_derive(str, instart, inptr - instart);\n\t    else if (inptr > instart)\n\t\trb_str_cat(ret, instart, inptr - instart);\n\t    str = rb_str_derive(str, inptr, inlen);\n\t    rescue = iconv_fail_retry(error, ret, str, env, errmsg);\n\t    if (TYPE(rescue) == T_ARRAY) {\n\t\tif ((len = RARRAY(rescue)->len) > 0)\n\t\t    rb_str_concat(ret, RARRAY(rescue)->ptr[0]);\n\t\tif (len > 1 && !NIL_P(str = RARRAY(rescue)->ptr[1])) {\n\t\t    StringValue(str);\n\t\t    inlen = length = RSTRING(str)->len;\n\t\t    instart = inptr = RSTRING(str)->ptr;\n\t\t    continue;\n\t\t}\n\t    }\n\t    else if (!NIL_P(rescue)) {\n\t\trb_str_concat(ret, rescue);\n\t    }\n\t    break;\n\t}\n    } while (inlen > 0);\n\n    if (!ret)\n\tret = rb_str_derive(str, instart, inptr - instart);\n    else if (inptr > instart)\n\trb_str_cat(ret, instart, inptr - instart);\n    return ret;\n}\n\nstatic VALUE\niconv_s_allocate\n#ifdef HAVE_PROTOTYPES\n    (VALUE klass)\n#else /* HAVE_PROTOTYPES */\n    (klass)\n    VALUE klass;\n#endif /* HAVE_PROTOTYPES */\n{\n    return Data_Wrap_Struct(klass, 0, ICONV_FREE, 0);\n}\n\n/*\n * Document-method: new\n * call-seq: Iconv.new(to, from)\n *\n * Creates new code converter from a coding-system designated with +from+\n * to another one designated with +to+.\n * \n * === Parameters\n *\n * +to+::   encoding name for destination\n * +from+:: encoding name for source\n *\n * === Exceptions\n *\n * TypeError::       if +to+ or +from+ aren't String\n * InvalidEncoding:: if designated converter couldn't find out\n * SystemCallError:: if <tt>iconv_open(3)</tt> fails\n */\nstatic VALUE\niconv_initialize\n#ifdef HAVE_PROTOTYPES\n    (VALUE self, VALUE to, VALUE from)\n#else /* HAVE_PROTOTYPES */\n    (self, to, from)\n    VALUE self;\n    VALUE to;\n    VALUE from;\n#endif /* HAVE_PROTOTYPES */\n{\n    iconv_free(check_iconv(self));\n    DATA_PTR(self) = NULL;\n    DATA_PTR(self) = (void *)ICONV2VALUE(iconv_create(to, from));\n    return self;\n}\n\n/*\n * Document-method: open\n * call-seq: Iconv.open(to, from) { |iconv| ... }\n *\n * Equivalent to Iconv.new except that when it is called with a block, it\n * yields with the new instance and closes it, and returns the result which\n * returned from the block.\n */\nstatic VALUE\niconv_s_open\n#ifdef HAVE_PROTOTYPES\n    (VALUE self, VALUE to, VALUE from)\n#else /* HAVE_PROTOTYPES */\n    (self, to, from)\n    VALUE self;\n    VALUE to;\n    VALUE from;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE cd = ICONV2VALUE(iconv_create(to, from));\n\n    self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd);\n    if (rb_block_given_p()) {\n\treturn rb_ensure(rb_yield, self, (VALUE(*)())iconv_finish, self);\n    }\n    else {\n\treturn self;\n    }\n}\n\nstatic VALUE\niconv_s_convert\n#ifdef HAVE_PROTOTYPES\n    (struct iconv_env_t* env)\n#else /* HAVE_PROTOTYPES */\n    (env)\n    struct iconv_env_t *env;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE last = 0;\n\n    for (; env->argc > 0; --env->argc, ++env->argv) {\n\tVALUE s = iconv_convert(env->cd, last = *(env->argv), 0, -1, env);\n\tenv->append(env->ret, s);\n    }\n\n    if (!NIL_P(last)) {\n\tVALUE s = iconv_convert(env->cd, Qnil, 0, 0, env);\n\tif (RSTRING(s)->len)\n\t    env->append(env->ret, s);\n    }\n\n    return env->ret;\n}\n\n/*\n * Document-method: Iconv::iconv\n * call-seq: Iconv.iconv(to, from, *strs)\n *\n * Shorthand for\n *   Iconv.open(to, from) { |cd|\n *     (strs + [nil]).collect { |s| cd.iconv(s) }\n *   }\n *\n * === Parameters\n *\n * <tt>to, from</tt>:: see Iconv.new\n * <tt>strs</tt>:: strings to be converted\n *\n * === Exceptions\n *\n * Exceptions thrown by Iconv.new, Iconv.open and Iconv#iconv.\n */\nstatic VALUE\niconv_s_iconv\n#ifdef HAVE_PROTOTYPES\n    (int argc, VALUE *argv, VALUE self)\n#else /* HAVE_PROTOTYPES */\n    (argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n#endif /* HAVE_PROTOTYPES */\n{\n    struct iconv_env_t arg;\n\n    if (argc < 2)\t\t/* needs `to' and `from' arguments at least */\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for %d)\", argc, 2);\n\n    arg.argc = argc -= 2;\n    arg.argv = argv + 2;\n    arg.append = rb_ary_push;\n    arg.ret = rb_ary_new2(argc);\n    arg.cd = iconv_create(argv[0], argv[1]);\n    return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd));\n}\n\n/*\n * Document-method: Iconv::conv\n * call-seq: Iconv.conv(to, from, str)\n *\n * Shorthand for\n *   Iconv.iconv(to, from, str).join\n * See Iconv.iconv.\n */\nstatic VALUE\niconv_s_conv\n#ifdef HAVE_PROTOTYPES\n    (VALUE self, VALUE to, VALUE from, VALUE str)\n#else /* HAVE_PROTOTYPES */\n    (self, to, from, str)\n    VALUE self, to, from, str;\n#endif /* HAVE_PROTOTYPES */\n{\n    struct iconv_env_t arg;\n\n    arg.argc = 1;\n    arg.argv = &str;\n    arg.append = rb_str_append;\n    arg.ret = rb_str_new(0, 0);\n    arg.cd = iconv_create(to, from);\n    return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd));\n}\n\n/*\n * Document-method: close\n *\n * Finishes conversion.\n *\n * After calling this, calling Iconv#iconv will cause an exception, but\n * multiple calls of #close are guaranteed to end successfully.\n *\n * Returns a string containing the byte sequence to change the output buffer to\n * its initial shift state.\n */\nstatic VALUE\niconv_init_state\n#ifdef HAVE_PROTOTYPES\n    (VALUE cd)\n#else /* HAVE_PROTOTYPES */\n    (cd)\n    VALUE cd;\n#endif /* HAVE_PROTOTYPES */\n{\n    return iconv_convert(VALUE2ICONV(cd), Qnil, 0, 0, NULL);\n}\n\nstatic VALUE\niconv_finish\n#ifdef HAVE_PROTOTYPES\n    (VALUE self)\n#else /* HAVE_PROTOTYPES */\n    (self)\n    VALUE self;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE cd = check_iconv(self);\n\n    if (!cd) return Qnil;\n    DATA_PTR(self) = NULL;\n\n    return rb_ensure(iconv_init_state, cd, iconv_free, cd);\n}\n\n/*\n * Document-method: Iconv#iconv\n * call-seq: iconv(str, start=0, length=-1)\n *\n * Converts string and returns the result.\n * * If +str+ is a String, converts <tt>str[start, length]</tt> and returns the converted string.\n * * If +str+ is +nil+, places converter itself into initial shift state and\n *   just returns a string containing the byte sequence to change the output\n *   buffer to its initial shift state.\n * * Otherwise, raises an exception.\n *\n * === Parameters\n *\n * str::    string to be converted, or nil\n * start::  starting offset\n * length:: conversion length; nil or -1 means whole the string from start\n *\n * === Exceptions\n *\n * * IconvIllegalSequence\n * * IconvInvalidCharacter\n * * IconvOutOfRange\n *\n * === Examples\n *\n * See the Iconv documentation.\n */\nstatic VALUE\niconv_iconv\n#ifdef HAVE_PROTOTYPES\n    (int argc, VALUE *argv, VALUE self)\n#else /* HAVE_PROTOTYPES */\n    (argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n#endif /* HAVE_PROTOTYPES */\n{\n    VALUE str, n1, n2;\n    VALUE cd = check_iconv(self);\n    long start = 0, length = 0, slen = 0;\n\n    rb_scan_args(argc, argv, \"12\", &str, &n1, &n2);\n    if (!NIL_P(str)) slen = RSTRING_LEN(StringValue(str));\n    if (argc != 2 || !RTEST(rb_range_beg_len(n1, &start, &length, slen, 0))) {\n\tif (NIL_P(n1) || ((start = NUM2LONG(n1)) < 0 ? (start += slen) >= 0 : start < slen)) {\n\t    if (NIL_P(n2)) {\n\t\tlength = -1;\n\t    }\n\t    else if ((length = NUM2LONG(n2)) >= slen - start) {\n\t\tlength = slen - start;\n\t    }\n\t}\n    }\n\n    return iconv_convert(VALUE2ICONV(cd), str, start, length, NULL);\n}\n\n/*\n * Document-class: Iconv::Failure\n *\n * Base attributes for Iconv exceptions.\n */\n\n/*\n * Document-method: success\n * call-seq: success\n *\n * Returns string(s) translated successfully until the exception occurred.\n * * In the case of failure occurred within Iconv.iconv, returned\n *   value is an array of strings translated successfully preceding\n *   failure and the last element is string on the way.\n */\nstatic VALUE\niconv_failure_success\n#ifdef HAVE_PROTOTYPES\n(VALUE self)\n#else /* HAVE_PROTOTYPES */\n    (self)\n    VALUE self;\n#endif /* HAVE_PROTOTYPES */\n{\n    return rb_attr_get(self, rb_success);\n}\n\n/*\n * Document-method: failed\n * call-seq: failed\n *\n * Returns substring of the original string passed to Iconv that starts at the\n * character caused the exception. \n */\nstatic VALUE\niconv_failure_failed\n#ifdef HAVE_PROTOTYPES\n(VALUE self)\n#else /* HAVE_PROTOTYPES */\n    (self)\n    VALUE self;\n#endif /* HAVE_PROTOTYPES */\n{\n    return rb_attr_get(self, rb_failed);\n}\n\n/*\n * Document-method: inspect\n * call-seq: inspect\n *\n * Returns inspected string like as: #<_class_: _success_, _failed_>\n */\nstatic VALUE\niconv_failure_inspect\n#ifdef HAVE_PROTOTYPES\n    (VALUE self)\n#else /* HAVE_PROTOTYPES */\n    (self)\n    VALUE self;\n#endif /* HAVE_PROTOTYPES */\n{\n    const char *cname = rb_class2name(CLASS_OF(self));\n    VALUE success = rb_attr_get(self, rb_success);\n    VALUE failed = rb_attr_get(self, rb_failed);\n    VALUE str = rb_str_buf_cat2(rb_str_new2(\"#<\"), cname);\n    str = rb_str_buf_cat(str, \": \", 2);\n    str = rb_str_buf_append(str, rb_inspect(success));\n    str = rb_str_buf_cat(str, \", \", 2);\n    str = rb_str_buf_append(str, rb_inspect(failed));\n    return rb_str_buf_cat(str, \">\", 1);\n}\n\n/*\n * Document-class: Iconv::InvalidEncoding\n * \n * Requested coding-system is not available on this system.\n */\n\n/*\n * Document-class: Iconv::IllegalSequence\n * \n * Input conversion stopped due to an input byte that does not belong to\n * the input codeset, or the output codeset does not contain the\n * character.\n */\n\n/*\n * Document-class: Iconv::InvalidCharacter\n * \n * Input conversion stopped due to an incomplete character or shift\n * sequence at the end of the input buffer.\n */\n\n/*\n * Document-class: Iconv::OutOfRange\n * \n * Iconv library internal error.  Must not occur.\n */\n\n/*\n * Document-class: Iconv::BrokenLibrary\n * \n * Detected a bug of underlying iconv(3) libray.\n * * returns an error without setting errno properly\n */\n\nvoid\nInit_iconv _((void))\n{\n    VALUE rb_cIconv = rb_define_class(\"Iconv\", rb_cData);\n\n    rb_define_alloc_func(rb_cIconv, iconv_s_allocate);\n    rb_define_singleton_method(rb_cIconv, \"open\", iconv_s_open, 2);\n    rb_define_singleton_method(rb_cIconv, \"iconv\", iconv_s_iconv, -1);\n    rb_define_singleton_method(rb_cIconv, \"conv\", iconv_s_conv, 3);\n    rb_define_method(rb_cIconv, \"initialize\", iconv_initialize, 2);\n    rb_define_method(rb_cIconv, \"close\", iconv_finish, 0);\n    rb_define_method(rb_cIconv, \"iconv\", iconv_iconv, -1);\n\n    rb_eIconvFailure = rb_define_module_under(rb_cIconv, \"Failure\");\n    rb_define_method(rb_eIconvFailure, \"initialize\", iconv_failure_initialize, 3);\n    rb_define_method(rb_eIconvFailure, \"success\", iconv_failure_success, 0);\n    rb_define_method(rb_eIconvFailure, \"failed\", iconv_failure_failed, 0);\n    rb_define_method(rb_eIconvFailure, \"inspect\", iconv_failure_inspect, 0);\n\n    rb_eIconvInvalidEncoding = rb_define_class_under(rb_cIconv, \"InvalidEncoding\", rb_eArgError);\n    rb_eIconvIllegalSeq = rb_define_class_under(rb_cIconv, \"IllegalSequence\", rb_eArgError);\n    rb_eIconvInvalidChar = rb_define_class_under(rb_cIconv, \"InvalidCharacter\", rb_eArgError);\n    rb_eIconvOutOfRange = rb_define_class_under(rb_cIconv, \"OutOfRange\", rb_eRuntimeError);\n    rb_eIconvBrokenLibrary = rb_define_class_under(rb_cIconv, \"BrokenLibrary\", rb_eRuntimeError);\n    rb_include_module(rb_eIconvInvalidEncoding, rb_eIconvFailure);\n    rb_include_module(rb_eIconvIllegalSeq, rb_eIconvFailure);\n    rb_include_module(rb_eIconvInvalidChar, rb_eIconvFailure);\n    rb_include_module(rb_eIconvOutOfRange, rb_eIconvFailure);\n    rb_include_module(rb_eIconvBrokenLibrary, rb_eIconvFailure);\n\n    rb_success = rb_intern(\"success\");\n    rb_failed = rb_intern(\"failed\");\n\n    rb_gc_register_address(&charset_map);\n    charset_map = rb_hash_new();\n    rb_define_singleton_method(rb_cIconv, \"charset_map\", charset_map_get, 0);\n}\n\n"
  },
  {
    "path": "ext/io/wait/.cvsignore",
    "content": "Makefile\nmkmf.log\n"
  },
  {
    "path": "ext/io/wait/extconf.rb",
    "content": "require 'mkmf'\ntarget = \"io/wait\"\n\nunless macro_defined?(\"DOSISH\", \"#include <ruby.h>\")\n  fionread = %w[sys/ioctl.h sys/filio.h].find do |h|\n    have_macro(\"FIONREAD\", h)\n  end\n  if fionread\n    $defs << \"-DFIONREAD_HEADER=\\\"<#{fionread}>\\\"\"\n    create_makefile(target)\n  end\nelse\n  if have_func(\"rb_w32_ioctlsocket\", \"ruby.h\")\n    have_func(\"rb_w32_is_socket\", \"ruby.h\")\n    create_makefile(target)\n  end\nend\n"
  },
  {
    "path": "ext/io/wait/lib/nonblock.rb",
    "content": "require \"fcntl\"\nclass IO\n  def nonblock?\n    (fcntl(Fcntl::F_GETFL) & File::NONBLOCK) != 0\n  end\n\n  def nonblock=(nb)\n    f = fcntl(Fcntl::F_GETFL)\n    if nb\n      f |= File::NONBLOCK\n    else\n      f &= ~File::NONBLOCK\n    end\n    fcntl(Fcntl::F_SETFL, f)\n  end\n\n  def nonblock(nb = true)\n    nb, self.nonblock = nonblock?, nb\n    yield\n  ensure\n    self.nonblock = nb\n  end\nend if defined?(Fcntl::F_GETFL)\n"
  },
  {
    "path": "ext/io/wait/wait.c",
    "content": "/**********************************************************************\n\n  io/wait.c -\n\n  $Author$\n  $Date$\n  created at: Tue Aug 28 09:08:06 JST 2001\n\n  All the files in this distribution are covered under the Ruby's\n  license (see the file COPYING).\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n\n#include <sys/types.h>\n#if defined(FIONREAD_HEADER)\n#include FIONREAD_HEADER\n#endif\n\n#ifdef HAVE_RB_W32_IOCTLSOCKET\n#define ioctl ioctlsocket\n#define ioctl_arg u_long\n#define ioctl_arg2num(i) ULONG2NUM(i)\n#else\n#define ioctl_arg int\n#define ioctl_arg2num(i) INT2NUM(i)\n#endif\n\n#ifdef HAVE_RB_W32_IS_SOCKET\n#define FIONREAD_POSSIBLE_P(fd) rb_w32_is_socket(fd)\n#else\n#define FIONREAD_POSSIBLE_P(fd) ((fd),Qtrue)\n#endif\n\nstatic VALUE io_ready_p _((VALUE io));\nstatic VALUE io_wait _((int argc, VALUE *argv, VALUE io));\nvoid Init_wait _((void));\n\nEXTERN struct timeval rb_time_interval _((VALUE time));\n\n/*\n=begin\n= IO wait methods.\n=end\n */\n\n/*\n=begin\n--- IO#ready?\n    returns non-nil if input available without blocking, or nil.\n=end\n*/\nstatic VALUE\nio_ready_p(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    FILE *fp;\n    ioctl_arg n;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    if (!FIONREAD_POSSIBLE_P(fileno(fptr->f))) return Qfalse;\n    fp = fptr->f;\n    if (feof(fp)) return Qfalse;\n    if (rb_read_pending(fp)) return Qtrue;\n    if (ioctl(fileno(fp), FIONREAD, &n)) rb_sys_fail(0);\n    if (n > 0) return ioctl_arg2num(n);\n    return Qnil;\n}\n\n/*\n=begin\n--- IO#wait([timeout])\n    waits until input available or timed out and returns self, or nil\n    when EOF reached.\n=end\n*/\nstatic VALUE\nio_wait(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    rb_io_t *fptr;\n    fd_set rd;\n    FILE *fp;\n    int fd;\n    ioctl_arg n;\n    VALUE timeout;\n    struct timeval *tp, timerec;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    rb_scan_args(argc, argv, \"01\", &timeout);\n    if (NIL_P(timeout)) {\n\ttp = 0;\n    }\n    else {\n\ttimerec = rb_time_interval(timeout);\n\ttp = &timerec;\n    }\n\n    fp = fptr->f;\n    if (feof(fp)) return Qfalse;\n    if (rb_read_pending(fp)) return Qtrue;\n    fd = fileno(fp);\n    FD_ZERO(&rd);\n    FD_SET(fd, &rd);\n    if (rb_thread_select(fd + 1, &rd, NULL, NULL, tp) < 0)\n\trb_sys_fail(0);\n    rb_io_check_closed(fptr);\n    if (!FIONREAD_POSSIBLE_P(fileno(fptr->f))) return Qfalse;\n    if (ioctl(fileno(fp), FIONREAD, &n)) rb_sys_fail(0);\n    if (n > 0) return io;\n    return Qnil;\n}\n\nvoid\nInit_wait()\n{\n    rb_define_method(rb_cIO, \"ready?\", io_ready_p, 0);\n    rb_define_method(rb_cIO, \"wait\", io_wait, -1);\n}\n"
  },
  {
    "path": "ext/nkf/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/nkf/depend",
    "content": "nkf.o : nkf.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h $(srcdir)/nkf-utf8/nkf.c $(srcdir)/nkf-utf8/utf8tbl.c $(srcdir)/nkf-utf8/config.h\n"
  },
  {
    "path": "ext/nkf/extconf.rb",
    "content": "require 'mkmf'\ncreate_makefile('nkf')\n"
  },
  {
    "path": "ext/nkf/lib/kconv.rb",
    "content": "#\n# kconv.rb - Kanji Converter.\n#\n# $Id$\n#\n# ----\n#\n# kconv.rb implements the Kconv class for Kanji Converter.  Additionally,\n# some methods in String classes are added to allow easy conversion.\n#\n\nrequire 'nkf'\n\n#\n# Kanji Converter for Ruby.\n#\nmodule Kconv\n  #\n  # Public Constants\n  #\n  \n  #Constant of Encoding\n  \n  # Auto-Detect\n  AUTO = NKF::AUTO\n  # ISO-2022-JP\n  JIS = NKF::JIS\n  # EUC-JP\n  EUC = NKF::EUC\n  # Shift_JIS\n  SJIS = NKF::SJIS\n  # BINARY\n  BINARY = NKF::BINARY\n  # NOCONV\n  NOCONV = NKF::NOCONV\n  # ASCII\n  ASCII = NKF::ASCII\n  # UTF-8\n  UTF8 = NKF::UTF8\n  # UTF-16\n  UTF16 = NKF::UTF16\n  # UTF-32\n  UTF32 = NKF::UTF32\n  # UNKNOWN\n  UNKNOWN = NKF::UNKNOWN\n\n  #\n  # Private Constants\n  #\n  \n  # Revision of kconv.rb\n  REVISION = %q$Revision$\n  \n  #Regexp of Encoding\n  \n  # Regexp of Shift_JIS string (private constant)\n  RegexpShiftjis = /\\A(?:\n\t\t       [\\x00-\\x7f\\xa1-\\xdf] |\n\t\t       [\\x81-\\x9f\\xe0-\\xfc][\\x40-\\x7e\\x80-\\xfc] \n\t\t      )*\\z/nx\n\n  # Regexp of EUC-JP string (private constant)\n  RegexpEucjp = /\\A(?:\n\t\t    [\\x00-\\x7f]                         |\n\t\t    \\x8e        [\\xa1-\\xdf]             |\n\t\t    \\x8f        [\\xa1-\\xfe] [\\xa1-\\xfe] |\n\t\t    [\\xa1-\\xfe] [\\xa1-\\xfe]\n\t\t   )*\\z/nx\n\n  # Regexp of UTF-8 string (private constant)\n  RegexpUtf8  = /\\A(?:\n\t\t    [\\x00-\\x7f]                                     |\n\t\t    [\\xc2-\\xdf] [\\x80-\\xbf]                         |\n\t\t    \\xe0        [\\xa0-\\xbf] [\\x80-\\xbf]             |\n\t\t    [\\xe1-\\xef] [\\x80-\\xbf] [\\x80-\\xbf]             |\n\t\t    \\xf0        [\\x90-\\xbf] [\\x80-\\xbf] [\\x80-\\xbf] |\n\t\t    [\\xf1-\\xf3] [\\x80-\\xbf] [\\x80-\\xbf] [\\x80-\\xbf] |\n\t\t    \\xf4        [\\x80-\\x8f] [\\x80-\\xbf] [\\x80-\\xbf]\n\t\t   )*\\z/nx\n\n  #\n  # Public Methods\n  #\n  \n  # call-seq:\n  #    Kconv.kconv(str, out_code, in_code = Kconv::AUTO)\n  #\n  # Convert <code>str</code> to out_code.\n  # <code>out_code</code> and <code>in_code</code> are given as constants of Kconv.\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want to decode them, use NKF.nkf.\n  def kconv(str, out_code, in_code = AUTO)\n    opt = '-'\n    case in_code\n    when ::NKF::JIS\n      opt << 'J'\n    when ::NKF::EUC\n      opt << 'E'\n    when ::NKF::SJIS\n      opt << 'S'\n    when ::NKF::UTF8\n      opt << 'W'\n    when ::NKF::UTF16\n      opt << 'W16'\n    end\n\n    case out_code\n    when ::NKF::JIS\n      opt << 'j'\n    when ::NKF::EUC\n      opt << 'e'\n    when ::NKF::SJIS\n      opt << 's'\n    when ::NKF::UTF8\n      opt << 'w'\n    when ::NKF::UTF16\n      opt << 'w16'\n    when ::NKF::NOCONV\n      return str\n    end\n\n    opt = '' if opt == '-'\n\n    ::NKF::nkf(opt, str)\n  end\n  module_function :kconv\n\n  #\n  # Encode to\n  #\n\n  # call-seq:\n  #    Kconv.tojis(str)   -> string\n  #\n  # Convert <code>str</code> to ISO-2022-JP\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-jxm0', str).\n  def tojis(str)\n    ::NKF::nkf('-jm', str)\n  end\n  module_function :tojis\n\n  # call-seq:\n  #    Kconv.toeuc(str)   -> string\n  #\n  # Convert <code>str</code> to EUC-JP\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-exm0', str).\n  def toeuc(str)\n    ::NKF::nkf('-em', str)\n  end\n  module_function :toeuc\n\n  # call-seq:\n  #    Kconv.tosjis(str)   -> string\n  #\n  # Convert <code>str</code> to Shift_JIS\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-sxm0', str).\n  def tosjis(str)\n    ::NKF::nkf('-sm', str)\n  end\n  module_function :tosjis\n\n  # call-seq:\n  #    Kconv.toutf8(str)   -> string\n  #\n  # Convert <code>str</code> to UTF-8\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-wxm0', str).\n  def toutf8(str)\n    ::NKF::nkf('-wm', str)\n  end\n  module_function :toutf8\n\n  # call-seq:\n  #    Kconv.toutf16(str)   -> string\n  #\n  # Convert <code>str</code> to UTF-16\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-w16xm0', str).\n  def toutf16(str)\n    ::NKF::nkf('-w16m', str)\n  end\n  module_function :toutf16\n\n  #\n  # guess\n  #\n\n  # call-seq:\n  #    Kconv.guess(str)   -> integer\n  #\n  # Guess input encoding by NKF.guess2\n  def guess(str)\n    ::NKF::guess(str)\n  end\n  module_function :guess\n\n  # call-seq:\n  #    Kconv.guess_old(str)   -> integer\n  #\n  # Guess input encoding by NKF.guess1\n  def guess_old(str)\n    ::NKF::guess1(str)\n  end\n  module_function :guess_old\n\n  #\n  # isEncoding\n  #\n\n  # call-seq:\n  #    Kconv.iseuc(str)   -> obj or nil\n  #\n  # Returns whether input encoding is EUC-JP or not.\n  #\n  # *Note* don't expect this return value is MatchData.\n  def iseuc(str)\n    RegexpEucjp.match( str )\n  end\n  module_function :iseuc\n\n  # call-seq:\n  #    Kconv.issjis(str)   -> obj or nil\n  #\n  # Returns whether input encoding is Shift_JIS or not.\n  #\n  # *Note* don't expect this return value is MatchData.\n  def issjis(str)\n    RegexpShiftjis.match( str )\n  end\n  module_function :issjis\n\n  # call-seq:\n  #    Kconv.isutf8(str)   -> obj or nil\n  #\n  # Returns whether input encoding is UTF-8 or not.\n  #\n  # *Note* don't expect this return value is MatchData.\n  def isutf8(str)\n    RegexpUtf8.match( str )\n  end\n  module_function :isutf8\n\nend\n\nclass String\n  # call-seq:\n  #    String#kconv(out_code, in_code = Kconv::AUTO)\n  #\n  # Convert <code>self</code> to out_code.\n  # <code>out_code</code> and <code>in_code</code> are given as constants of Kconv.\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want to decode them, use NKF.nkf.\n  def kconv(out_code, in_code=Kconv::AUTO)\n    Kconv::kconv(self, out_code, in_code)\n  end\n  \n  #\n  # to Encoding\n  #\n  \n  # call-seq:\n  #    String#tojis   -> string\n  #\n  # Convert <code>self</code> to ISO-2022-JP\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-jxm0', str).\n  def tojis; Kconv.tojis(self) end\n\n  # call-seq:\n  #    String#toeuc   -> string\n  #\n  # Convert <code>self</code> to EUC-JP\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-exm0', str).\n  def toeuc; Kconv.toeuc(self) end\n\n  # call-seq:\n  #    String#tosjis   -> string\n  #\n  # Convert <code>self</code> to Shift_JIS\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-sxm0', str).\n  def tosjis; Kconv.tosjis(self) end\n\n  # call-seq:\n  #    String#toutf8   -> string\n  #\n  # Convert <code>self</code> to UTF-8\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-wxm0', str).\n  def toutf8; Kconv.toutf8(self) end\n\n  # call-seq:\n  #    String#toutf16   -> string\n  #\n  # Convert <code>self</code> to UTF-16\n  #\n  # *Note*\n  # This method decode MIME encoded string and\n  # convert halfwidth katakana to fullwidth katakana.\n  # If you don't want it, use NKF.nkf('-w16xm0', str).\n  def toutf16; Kconv.toutf16(self) end\n\n  #\n  # is Encoding\n  #\n\n  # call-seq:\n  #    String#iseuc   -> obj or nil\n  #\n  # Returns whether <code>self</code>'s encoding is EUC-JP or not.\n  #\n  # *Note* don't expect this return value is MatchData.\n  def iseuc;\tKconv.iseuc(self) end\n\n  # call-seq:\n  #    String#issjis   -> obj or nil\n  #\n  # Returns whether <code>self</code>'s encoding is Shift_JIS or not.\n  #\n  # *Note* don't expect this return value is MatchData.\n  def issjis;\tKconv.issjis(self) end\n\n  # call-seq:\n  #    String#isutf8   -> obj or nil\n  #\n  # Returns whether <code>self</code>'s encoding is UTF-8 or not.\n  #\n  # *Note* don't expect this return value is MatchData.\n  def isutf8;\tKconv.isutf8(self) end\nend\n"
  },
  {
    "path": "ext/nkf/nkf-utf8/nkf.c",
    "content": "/** Network Kanji Filter. (PDS Version)\n************************************************************************\n** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)\n** \u001b$BO\"Mm@h!'\u001b(B \u001b$B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T@n!!;j\u001b(B \n** \u001b$B!J\u001b(BE-Mail Address: ichikawa@flab.fujitsu.co.jp\u001b$B!K\u001b(B\n** Copyright (C) 1996,1998\n** Copyright (C) 2002\n** \u001b$BO\"Mm@h!'\u001b(B \u001b$BN05eBg3X>pJs9)3X2J\u001b(B \u001b$B2OLn\u001b(B \u001b$B??<#\u001b(B  mime/X0208 support\n** \u001b$B!J\u001b(BE-Mail Address: kono@ie.u-ryukyu.ac.jp\u001b$B!K\u001b(B\n** \u001b$BO\"Mm@h!'\u001b(B COW for DOS & Win16 & Win32 & OS/2\n** \u001b$B!J\u001b(BE-Mail Address: GHG00637@niftyserve.or.p\u001b$B!K\u001b(B\n**\n**    \u001b$B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!\"\u001b(B\n**    \u001b$B$=$N:]$K$O!\"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#\u001b(B\n**    \u001b$B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$\"$j$^$;$s!#\u001b(B\n**    \u001b$B1DMxMxMQ$b>e5-$KH?$7$J$$HO0O$G5v2D$7$^$9!#\u001b(B\n**    \u001b$B%P%$%J%j$NG[I[$N:]$K$O\u001b(Bversion message\u001b$B$rJ]B8$9$k$3$H$r>r7o$H$7$^$9!#\u001b(B\n**    \u001b$B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!\"0-$7$+$i$:!#\u001b(B\n**\n**    Everyone is permitted to do anything on this program \n**    including copying, modifying, improving,\n**    as long as you don't try to pretend that you wrote it.\n**    i.e., the above copyright notice has to appear in all copies.  \n**    Binary distribution requires original version messages.\n**    You don't have to ask before copying, redistribution or publishing.\n**    THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.\n***********************************************************************/\n\n/***********************************************************************\n** UTF-8 \u001b$B%5%]!<%H$K$D$$$F\u001b(B\n**    \u001b$B=>Mh$N\u001b(B nkf \u001b$B$HF~$l$+$($F$=$N$^$^;H$($k$h$&$K$J$C$F$$$^$9\u001b(B\n**    nkf -e \u001b$B$J$I$H$7$F5/F0$9$k$H!\"<+F0H=JL$G\u001b(B UTF-8 \u001b$B$HH=Dj$5$l$l$P!\"\u001b(B\n**    \u001b$B$=$N$^$^\u001b(B euc-jp \u001b$B$KJQ49$5$l$^$9\u001b(B\n**\n**    \u001b$B$^$@%P%0$,$\"$k2DG=@-$,9b$$$G$9!#\u001b(B\n**    (\u001b$BFC$K<+F0H=JL!\"%3!<%I:.:_!\"%(%i!<=hM}7O\u001b(B)\n**\n**    \u001b$B2?$+LdBj$r8+$D$1$?$i!\"\u001b(B\n**        E-Mail: furukawa@tcp-ip.or.jp\n**    \u001b$B$^$G8fO\"Mm$r$*4j$$$7$^$9!#\u001b(B\n***********************************************************************/\n/* $Id$ */\n#define NKF_VERSION \"2.0.8\"\n#define NKF_RELEASE_DATE \"2008-11-08\"\n#include \"config.h\"\n#include \"utf8tbl.h\"\n\n#define COPY_RIGHT \\\n    \"Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),2000 S. Kono, COW\\n\" \\\n    \"Copyright (C) 2002-2008 Kono, Furukawa, Naruse, mastodon\"\n\n\n/*\n**\n**\n**\n** USAGE:       nkf [flags] [file] \n**\n** Flags:\n** b    Output is buffered             (DEFAULT)\n** u    Output is unbuffered\n**\n** t    no operation\n**\n** j    Output code is JIS 7 bit        (DEFAULT SELECT) \n** s    Output code is MS Kanji         (DEFAULT SELECT) \n** e    Output code is AT&T JIS         (DEFAULT SELECT) \n** w    Output code is AT&T JIS         (DEFAULT SELECT) \n** l    Output code is JIS 7bit and ISO8859-1 Latin-1\n**\n** m    MIME conversion for ISO-2022-JP\n** I    Convert non ISO-2022-JP charactor to GETA by Pekoe <pekoe@lair.net>\n** i_ Output sequence to designate JIS-kanji (DEFAULT_J)\n** o_ Output sequence to designate single-byte roman characters (DEFAULT_R)\n** M    MIME output conversion \n**\n** r  {de/en}crypt ROT13/47\n**\n** v  display Version\n**\n** T  Text mode output        (for MS-DOS)\n**\n** x    Do not convert X0201 kana into X0208\n** Z    Convert X0208 alphabet to ASCII\n**\n** f60  fold option\n**\n** m    MIME decode\n** B    try to fix broken JIS, missing Escape\n** B[1-9]  broken level\n**\n** O   Output to 'nkf.out' file or last file name\n** d   Delete \\r in line feed \n** c   Add \\r in line feed \n** -- other long option\n** -- ignore following option (don't use with -O )\n**\n**/\n\n#if (defined(__TURBOC__) || defined(_MSC_VER) || defined(LSI_C) || defined(__MINGW32__) || defined(__EMX__) || defined(__MSDOS__) || defined(__WINDOWS__) || defined(__DOS__) || defined(__OS2__)) && !defined(MSDOS)\n#define MSDOS\n#if (defined(__Win32__) || defined(_WIN32)) && !defined(__WIN32__)\n#define __WIN32__\n#endif\n#endif\n\n#ifdef PERL_XS\n#undef OVERWRITE\n#endif\n\n#ifndef PERL_XS\n#include <stdio.h>\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n\n#if defined(MSDOS) || defined(__OS2__)\n#include <fcntl.h>\n#include <io.h>\n#if defined(_MSC_VER) || defined(__WATCOMC__)\n#define mktemp _mktemp\n#endif\n#endif\n\n#ifdef MSDOS\n#ifdef LSI_C\n#define setbinmode(fp) fsetbin(fp)\n#elif defined(__DJGPP__)\n#include <libc/dosio.h>\n#define setbinmode(fp) djgpp_setbinmode(fp)\n#else /* Microsoft C, Turbo C */\n#define setbinmode(fp) setmode(fileno(fp), O_BINARY)\n#endif\n#else /* UNIX */\n#define setbinmode(fp)\n#endif\n\n#if defined(__DJGPP__)\nvoid  djgpp_setbinmode(FILE *fp)\n{\n    /* we do not use libc's setmode(), which changes COOKED/RAW mode in device. */\n    int fd, m;\n    fd = fileno(fp);\n    m = (__file_handle_modes[fd] & (~O_TEXT)) | O_BINARY;\n    __file_handle_set(fd, m);\n}\n#endif\n\n#ifdef _IOFBF /* SysV and MSDOS, Windows */\n#define       setvbuffer(fp, buf, size)       setvbuf(fp, buf, _IOFBF, size)\n#else /* BSD */\n#define       setvbuffer(fp, buf, size)       setbuffer(fp, buf, size)\n#endif\n\n/*Borland C++ 4.5 EasyWin*/\n#if defined(__TURBOC__) && defined(_Windows) && !defined(__WIN32__) /*Easy Win */\n#define         EASYWIN\n#ifndef __WIN16__\n#define __WIN16__\n#endif\n#include <windows.h>\n#endif\n\n#ifdef OVERWRITE\n/* added by satoru@isoternet.org */\n#if defined(__EMX__)\n#include <sys/types.h>\n#endif\n#include <sys/stat.h>\n#if !defined(MSDOS) || defined(__DJGPP__) /* UNIX, djgpp */\n#include <unistd.h>\n#if defined(__WATCOMC__)\n#include <sys/utime.h>\n#else\n#include <utime.h>\n#endif\n#else /* defined(MSDOS) */\n#ifdef __WIN32__\n#ifdef __BORLANDC__ /* BCC32 */\n#include <utime.h>\n#else /* !defined(__BORLANDC__) */\n#include <sys/utime.h>\n#endif /* (__BORLANDC__) */\n#else /* !defined(__WIN32__) */\n#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__) || defined(__OS2__) || defined(__EMX__) || defined(__IBMC__) || defined(__IBMCPP__)  /* VC++, MinGW, Watcom, emx+gcc, IBM VAC++ */\n#include <sys/utime.h>\n#elif defined(__TURBOC__) /* BCC */\n#include <utime.h>\n#elif defined(LSI_C) /* LSI C */\n#endif /* (__WIN32__) */\n#endif\n#endif\n#endif\n\n#define         FALSE   0\n#define         TRUE    1\n\n/* state of output_mode and input_mode  \n\n   c2           0 means ASCII\n                X0201\n                ISO8859_1\n                X0208\n                EOF      all termination\n   c1           32bit data\n\n */\n\n#define         ASCII           0\n#define         X0208           1\n#define         X0201           2\n#define         ISO8859_1       8\n#define         NO_X0201        3\n#define         X0212      0x2844\n#define         X0213_1    0x284F\n#define         X0213_2    0x2850\n\n/* Input Assumption */\n\n#define         JIS_INPUT       4\n#define         EUC_INPUT      16\n#define         SJIS_INPUT      5\n#define         LATIN1_INPUT    6\n#define         FIXED_MIME      7\n#define         STRICT_MIME     8\n\n/* MIME ENCODE */\n\n#define        \tISO2022JP       9\n#define  \tJAPANESE_EUC   10\n#define\t\tSHIFT_JIS      11\n\n#define\t\tUTF8           12\n#define\t\tUTF8_INPUT     13\n#define\t\tUTF16_INPUT    1015\n#define\t\tUTF32_INPUT    1017\n\n/* byte order */\n\n#define\t\tENDIAN_BIG\t1234\n#define\t\tENDIAN_LITTLE\t4321\n#define\t\tENDIAN_2143\t2143\n#define\t\tENDIAN_3412\t3412\n\n#define         WISH_TRUE      15\n\n/* ASCII CODE */\n\n#define         BS      0x08\n#define         TAB     0x09\n#define         NL      0x0a\n#define         CR      0x0d\n#define         ESC     0x1b\n#define         SPACE   0x20\n#define         AT      0x40\n#define         SSP     0xa0\n#define         DEL     0x7f\n#define         SI      0x0f\n#define         SO      0x0e\n#define         SSO     0x8e\n#define         SS3     0x8f\n\n#define\t\tis_alnum(c)  \\\n            (('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))\n\n/* I don't trust portablity of toupper */\n#define nkf_toupper(c)  (('a'<=c && c<='z')?(c-('a'-'A')):c)\n#define nkf_isoctal(c)  ('0'<=c && c<='7')\n#define nkf_isdigit(c)  ('0'<=c && c<='9')\n#define nkf_isxdigit(c)  (nkf_isdigit(c) || ('a'<=c && c<='f') || ('A'<=c && c <= 'F'))\n#define nkf_isblank(c) (c == SPACE || c == TAB)\n#define nkf_isspace(c) (nkf_isblank(c) || c == CR || c == NL)\n#define nkf_isalpha(c) (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))\n#define nkf_isalnum(c) (nkf_isdigit(c) || nkf_isalpha(c))\n#define nkf_isprint(c) (' '<=c && c<='~')\n#define nkf_isgraph(c) ('!'<=c && c<='~')\n#define hex2bin(c) (('0'<=c&&c<='9') ? (c-'0') : \\\n                    ('A'<=c&&c<='F') ? (c-'A'+10) : \\\n                    ('a'<=c&&c<='f') ? (c-'a'+10) : 0 )\n#define is_eucg3(c2) (((unsigned short)c2 >> 8) == SS3)\n\n#define CP932_TABLE_BEGIN 0xFA\n#define CP932_TABLE_END   0xFC\n#define CP932INV_TABLE_BEGIN 0xED\n#define CP932INV_TABLE_END   0xEE\n#define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END)\n\n#define         HOLD_SIZE       1024\n#if defined(INT_IS_SHORT)\n#define         IOBUF_SIZE      2048\n#else\n#define         IOBUF_SIZE      16384\n#endif\n\n#define         DEFAULT_J       'B'\n#define         DEFAULT_R       'B'\n\n#define         SJ0162  0x00e1          /* 01 - 62 ku offset */\n#define         SJ6394  0x0161          /* 63 - 94 ku offset */\n\n#define         RANGE_NUM_MAX   18\n#define         GETA1   0x22\n#define         GETA2   0x2e\n\n\n#if defined(UTF8_OUTPUT_ENABLE) || defined(UTF8_INPUT_ENABLE)\n#define sizeof_euc_to_utf8_1byte 94\n#define sizeof_euc_to_utf8_2bytes 94\n#define sizeof_utf8_to_euc_C2 64\n#define sizeof_utf8_to_euc_E5B8 64\n#define sizeof_utf8_to_euc_2bytes 112\n#define sizeof_utf8_to_euc_3bytes 16\n#endif\n\n/* MIME preprocessor */\n\n#ifdef EASYWIN /*Easy Win */\nextern POINT _BufferSize;\n#endif\n\nstruct input_code{\n    char *name;\n    nkf_char stat;\n    nkf_char score;\n    nkf_char index;\n    nkf_char buf[3];\n    void (*status_func)(struct input_code *, nkf_char);\n    nkf_char (*iconv_func)(nkf_char c2, nkf_char c1, nkf_char c0);\n    int _file_stat;\n};\n\nstatic char *input_codename = \"\";\n\n#ifndef PERL_XS\nstatic const char *CopyRight = COPY_RIGHT;\n#endif\n#if !defined(PERL_XS) && !defined(WIN32DLL)\nstatic  nkf_char     noconvert(FILE *f);\n#endif\nstatic  void    module_connection(void);\nstatic  nkf_char     kanji_convert(FILE *f);\nstatic  nkf_char     h_conv(FILE *f,nkf_char c2,nkf_char c1);\nstatic  nkf_char     push_hold_buf(nkf_char c2);\nstatic  void    set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0));\nstatic  nkf_char     s_iconv(nkf_char c2,nkf_char c1,nkf_char c0);\nstatic  nkf_char     s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1);\nstatic  nkf_char     e_iconv(nkf_char c2,nkf_char c1,nkf_char c0);\n#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)\n/* UCS Mapping\n * 0: Shift_JIS, eucJP-ascii\n * 1: eucJP-ms\n * 2: CP932, CP51932\n */\n#define UCS_MAP_ASCII 0\n#define UCS_MAP_MS    1\n#define UCS_MAP_CP932 2\nstatic int ms_ucs_map_f = UCS_MAP_ASCII;\n#endif\n#ifdef UTF8_INPUT_ENABLE\n/* no NEC special, NEC-selected IBM extended and IBM extended characters */\nstatic  int     no_cp932ext_f = FALSE;\n/* ignore ZERO WIDTH NO-BREAK SPACE */\nstatic  int     no_best_fit_chars_f = FALSE;\nstatic  int     input_endian = ENDIAN_BIG;\nstatic  nkf_char     unicode_subchar = '?'; /* the regular substitution character */\nstatic  void    nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c);\nstatic  void    encode_fallback_html(nkf_char c);\nstatic  void    encode_fallback_xml(nkf_char c);\nstatic  void    encode_fallback_java(nkf_char c);\nstatic  void    encode_fallback_perl(nkf_char c);\nstatic  void    encode_fallback_subchar(nkf_char c);\nstatic  void    (*encode_fallback)(nkf_char c) = NULL;\nstatic  nkf_char     w2e_conv(nkf_char c2,nkf_char c1,nkf_char c0,nkf_char *p2,nkf_char *p1);\nstatic  nkf_char     w_iconv(nkf_char c2,nkf_char c1,nkf_char c0);\nstatic  nkf_char     w_iconv16(nkf_char c2,nkf_char c1,nkf_char c0);\nstatic  nkf_char     w_iconv32(nkf_char c2,nkf_char c1,nkf_char c0);\nstatic  nkf_char\tunicode_to_jis_common(nkf_char c2,nkf_char c1,nkf_char c0,nkf_char *p2,nkf_char *p1);\nstatic  nkf_char\tw_iconv_common(nkf_char c1,nkf_char c0,const unsigned short *const *pp,nkf_char psize,nkf_char *p2,nkf_char *p1);\nstatic  void    w16w_conv(nkf_char val, nkf_char *p2, nkf_char *p1, nkf_char *p0);\nstatic  nkf_char     ww16_conv(nkf_char c2, nkf_char c1, nkf_char c0);\nstatic  nkf_char     w16e_conv(nkf_char val,nkf_char *p2,nkf_char *p1);\nstatic  void    w_status(struct input_code *, nkf_char);\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\nstatic  int     output_bom_f = FALSE;\nstatic  int     output_endian = ENDIAN_BIG;\nstatic  nkf_char     e2w_conv(nkf_char c2,nkf_char c1);\nstatic  void    w_oconv(nkf_char c2,nkf_char c1);\nstatic  void    w_oconv16(nkf_char c2,nkf_char c1);\nstatic  void    w_oconv32(nkf_char c2,nkf_char c1);\n#endif\nstatic  void    e_oconv(nkf_char c2,nkf_char c1);\nstatic  nkf_char     e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1);\nstatic  void    s_oconv(nkf_char c2,nkf_char c1);\nstatic  void    j_oconv(nkf_char c2,nkf_char c1);\nstatic  void    fold_conv(nkf_char c2,nkf_char c1);\nstatic  void    cr_conv(nkf_char c2,nkf_char c1);\nstatic  void    z_conv(nkf_char c2,nkf_char c1);\nstatic  void    rot_conv(nkf_char c2,nkf_char c1);\nstatic  void    hira_conv(nkf_char c2,nkf_char c1);\nstatic  void    base64_conv(nkf_char c2,nkf_char c1);\nstatic  void    iso2022jp_check_conv(nkf_char c2,nkf_char c1);\nstatic  void    no_connection(nkf_char c2,nkf_char c1);\nstatic  nkf_char     no_connection2(nkf_char c2,nkf_char c1,nkf_char c0);\n\nstatic  void    code_score(struct input_code *ptr);\nstatic  void    code_status(nkf_char c);\n\nstatic  void    std_putc(nkf_char c);\nstatic  nkf_char     std_getc(FILE *f);\nstatic  nkf_char     std_ungetc(nkf_char c,FILE *f);\n\nstatic  nkf_char     broken_getc(FILE *f);\nstatic  nkf_char     broken_ungetc(nkf_char c,FILE *f);\n\nstatic  nkf_char     mime_begin(FILE *f);\nstatic  nkf_char     mime_getc(FILE *f);\nstatic  nkf_char     mime_ungetc(nkf_char c,FILE *f);\n\nstatic  void    switch_mime_getc(void);\nstatic  void    unswitch_mime_getc(void);\nstatic  nkf_char     mime_begin_strict(FILE *f);\nstatic  nkf_char     mime_getc_buf(FILE *f);\nstatic  nkf_char     mime_ungetc_buf(nkf_char c,FILE *f);\nstatic  nkf_char     mime_integrity(FILE *f,const unsigned char *p);\n\nstatic  nkf_char     base64decode(nkf_char c);\nstatic  void    mime_prechar(nkf_char c2, nkf_char c1);\nstatic  void    mime_putc(nkf_char c);\nstatic  void    open_mime(nkf_char c);\nstatic  void    close_mime(void);\nstatic  void    eof_mime(void);\nstatic  void    mimeout_addchar(nkf_char c);\n#ifndef PERL_XS\nstatic  void    usage(void);\nstatic  void    version(void);\n#endif\nstatic  void    options(unsigned char *c);\n#if defined(PERL_XS) || defined(WIN32DLL)\nstatic  void    reinit(void);\n#endif\n\n/* buffers */\n\n#if !defined(PERL_XS) && !defined(WIN32DLL)\nstatic unsigned char   stdibuf[IOBUF_SIZE];\nstatic unsigned char   stdobuf[IOBUF_SIZE];\n#endif\nstatic unsigned char   hold_buf[HOLD_SIZE*2];\nstatic int             hold_count = 0;\n\n/* MIME preprocessor fifo */\n\n#define MIME_BUF_SIZE   (1024)    /* 2^n ring buffer */\n#define MIME_BUF_MASK   (MIME_BUF_SIZE-1)   \n#define Fifo(n)         mime_buf[(n)&MIME_BUF_MASK]\nstatic unsigned char           mime_buf[MIME_BUF_SIZE];\nstatic unsigned int            mime_top = 0;\nstatic unsigned int            mime_last = 0;  /* decoded */\nstatic unsigned int            mime_input = 0; /* undecoded */\nstatic nkf_char (*mime_iconv_back)(nkf_char c2,nkf_char c1,nkf_char c0) = NULL;\n\n/* flags */\nstatic int             unbuf_f = FALSE;\nstatic int             estab_f = FALSE;\nstatic int             nop_f = FALSE;\nstatic int             binmode_f = TRUE;       /* binary mode */\nstatic int             rot_f = FALSE;          /* rot14/43 mode */\nstatic int             hira_f = FALSE;          /* hira/kata henkan */\nstatic int             input_f = FALSE;        /* non fixed input code  */\nstatic int             alpha_f = FALSE;        /* convert JIx0208 alphbet to ASCII */\nstatic int             mime_f = STRICT_MIME;   /* convert MIME B base64 or Q */\nstatic int             mime_decode_f = FALSE;  /* mime decode is explicitly on */\nstatic int             mimebuf_f = FALSE;      /* MIME buffered input */\nstatic int             broken_f = FALSE;       /* convert ESC-less broken JIS */\nstatic int             iso8859_f = FALSE;      /* ISO8859 through */\nstatic int             mimeout_f = FALSE;       /* base64 mode */\n#if defined(MSDOS) || defined(__OS2__) \nstatic int             x0201_f = TRUE;         /* Assume JISX0201 kana */\n#else\nstatic int             x0201_f = NO_X0201;     /* Assume NO JISX0201 */\n#endif\nstatic int             iso2022jp_f = FALSE;    /* convert ISO-2022-JP */\n\n#ifdef UNICODE_NORMALIZATION\nstatic int nfc_f = FALSE;\nstatic nkf_char (*i_nfc_getc)(FILE *) = std_getc; /* input of ugetc */\nstatic nkf_char (*i_nfc_ungetc)(nkf_char c ,FILE *f) = std_ungetc;\nstatic nkf_char nfc_getc(FILE *f);\nstatic nkf_char nfc_ungetc(nkf_char c,FILE *f);\n#endif\n\n#ifdef INPUT_OPTION\nstatic int cap_f = FALSE;\nstatic nkf_char (*i_cgetc)(FILE *) = std_getc; /* input of cgetc */\nstatic nkf_char (*i_cungetc)(nkf_char c ,FILE *f) = std_ungetc;\nstatic nkf_char cap_getc(FILE *f);\nstatic nkf_char cap_ungetc(nkf_char c,FILE *f);\n\nstatic int url_f = FALSE;\nstatic nkf_char (*i_ugetc)(FILE *) = std_getc; /* input of ugetc */\nstatic nkf_char (*i_uungetc)(nkf_char c ,FILE *f) = std_ungetc;\nstatic nkf_char url_getc(FILE *f);\nstatic nkf_char url_ungetc(nkf_char c,FILE *f);\n#endif\n\n#if defined(INT_IS_SHORT)\n#define NKF_INT32_C(n)   (n##L)\n#else\n#define NKF_INT32_C(n)   (n)\n#endif\n#define PREFIX_EUCG3\tNKF_INT32_C(0x8F00)\n#define CLASS_MASK\tNKF_INT32_C(0xFF000000)\n#define CLASS_UNICODE\tNKF_INT32_C(0x01000000)\n#define VALUE_MASK\tNKF_INT32_C(0x00FFFFFF)\n#define UNICODE_MAX\tNKF_INT32_C(0x0010FFFF)\n#define is_unicode_capsule(c) ((c & CLASS_MASK) == CLASS_UNICODE)\n#define is_unicode_bmp(c) ((c & VALUE_MASK) <= NKF_INT32_C(0xFFFF))\n\n#ifdef NUMCHAR_OPTION\nstatic int numchar_f = FALSE;\nstatic nkf_char (*i_ngetc)(FILE *) = std_getc; /* input of ugetc */\nstatic nkf_char (*i_nungetc)(nkf_char c ,FILE *f) = std_ungetc;\nstatic nkf_char numchar_getc(FILE *f);\nstatic nkf_char numchar_ungetc(nkf_char c,FILE *f);\n#endif\n\n#ifdef CHECK_OPTION\nstatic int noout_f = FALSE;\nstatic void no_putc(nkf_char c);\nstatic nkf_char debug_f = FALSE;\nstatic void debug(const char *str);\nstatic nkf_char (*iconv_for_check)(nkf_char c2,nkf_char c1,nkf_char c0) = 0;\n#endif\n\nstatic int guess_f = FALSE;\n#if !defined PERL_XS\nstatic  void    print_guessed_code(char *filename);\n#endif\nstatic  void    set_input_codename(char *codename);\nstatic int is_inputcode_mixed = FALSE;\nstatic int is_inputcode_set   = FALSE;\n\n#ifdef EXEC_IO\nstatic int exec_f = 0;\n#endif\n\n#ifdef SHIFTJIS_CP932\n/* invert IBM extended characters to others */\nstatic int cp51932_f = FALSE;\n\n/* invert NEC-selected IBM extended characters to IBM extended characters */\nstatic int cp932inv_f = TRUE;\n\n/* static nkf_char cp932_conv(nkf_char c2, nkf_char c1); */\n#endif /* SHIFTJIS_CP932 */\n\n#ifdef X0212_ENABLE\nstatic int x0212_f = FALSE;\nstatic nkf_char x0212_shift(nkf_char c);\nstatic nkf_char x0212_unshift(nkf_char c);\n#endif\nstatic int x0213_f = FALSE;\n\nstatic unsigned char prefix_table[256];\n\nstatic void set_code_score(struct input_code *ptr, nkf_char score);\nstatic void clr_code_score(struct input_code *ptr, nkf_char score);\nstatic void status_disable(struct input_code *ptr);\nstatic void status_push_ch(struct input_code *ptr, nkf_char c);\nstatic void status_clear(struct input_code *ptr);\nstatic void status_reset(struct input_code *ptr);\nstatic void status_reinit(struct input_code *ptr);\nstatic void status_check(struct input_code *ptr, nkf_char c);\nstatic void e_status(struct input_code *, nkf_char);\nstatic void s_status(struct input_code *, nkf_char);\n\nstruct input_code input_code_list[] = {\n    {\"EUC-JP\",    0, 0, 0, {0, 0, 0}, e_status, e_iconv, 0},\n    {\"Shift_JIS\", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0},\n#ifdef UTF8_INPUT_ENABLE\n    {\"UTF-8\",     0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0},\n    {\"UTF-16\",    0, 0, 0, {0, 0, 0},     NULL, w_iconv16, 0},\n    {\"UTF-32\",    0, 0, 0, {0, 0, 0},     NULL, w_iconv32, 0},\n#endif\n    {0}\n};\n\nstatic int              mimeout_mode = 0;\nstatic int              base64_count = 0;\n\n/* X0208 -> ASCII converter */\n\n/* fold parameter */\nstatic int             f_line = 0;    /* chars in line */\nstatic int             f_prev = 0;\nstatic int             fold_preserve_f = FALSE; /* preserve new lines */\nstatic int             fold_f  = FALSE;\nstatic int             fold_len  = 0;\n\n/* options */\nstatic unsigned char   kanji_intro = DEFAULT_J;\nstatic unsigned char   ascii_intro = DEFAULT_R;\n\n/* Folding */\n\n#define FOLD_MARGIN  10\n#define DEFAULT_FOLD 60\n\nstatic int             fold_margin  = FOLD_MARGIN;\n\n/* converters */\n\n#ifdef DEFAULT_CODE_JIS\n#   define  DEFAULT_CONV j_oconv\n#endif\n#ifdef DEFAULT_CODE_SJIS\n#   define  DEFAULT_CONV s_oconv\n#endif\n#ifdef DEFAULT_CODE_EUC\n#   define  DEFAULT_CONV e_oconv\n#endif\n#ifdef DEFAULT_CODE_UTF8\n#   define  DEFAULT_CONV w_oconv\n#endif\n\n/* process default */\nstatic void (*output_conv)(nkf_char c2,nkf_char c1) = DEFAULT_CONV;\n\nstatic void (*oconv)(nkf_char c2,nkf_char c1) = no_connection;\n/* s_iconv or oconv */\nstatic nkf_char (*iconv)(nkf_char c2,nkf_char c1,nkf_char c0) = no_connection2;\n\nstatic void (*o_zconv)(nkf_char c2,nkf_char c1) = no_connection;\nstatic void (*o_fconv)(nkf_char c2,nkf_char c1) = no_connection;\nstatic void (*o_crconv)(nkf_char c2,nkf_char c1) = no_connection;\nstatic void (*o_rot_conv)(nkf_char c2,nkf_char c1) = no_connection;\nstatic void (*o_hira_conv)(nkf_char c2,nkf_char c1) = no_connection;\nstatic void (*o_base64conv)(nkf_char c2,nkf_char c1) = no_connection;\nstatic void (*o_iso2022jp_check_conv)(nkf_char c2,nkf_char c1) = no_connection;\n\n/* static redirections */\n\nstatic  void   (*o_putc)(nkf_char c) = std_putc;\n\nstatic  nkf_char    (*i_getc)(FILE *f) = std_getc; /* general input */\nstatic  nkf_char    (*i_ungetc)(nkf_char c,FILE *f) =std_ungetc;\n\nstatic  nkf_char    (*i_bgetc)(FILE *) = std_getc; /* input of mgetc */\nstatic  nkf_char    (*i_bungetc)(nkf_char c ,FILE *f) = std_ungetc;\n\nstatic  void   (*o_mputc)(nkf_char c) = std_putc ; /* output of mputc */\n\nstatic  nkf_char    (*i_mgetc)(FILE *) = std_getc; /* input of mgetc */\nstatic  nkf_char    (*i_mungetc)(nkf_char c ,FILE *f) = std_ungetc;\n\n/* for strict mime */\nstatic  nkf_char    (*i_mgetc_buf)(FILE *) = std_getc; /* input of mgetc_buf */\nstatic  nkf_char    (*i_mungetc_buf)(nkf_char c,FILE *f) = std_ungetc;\n\n/* Global states */\nstatic int output_mode = ASCII,    /* output kanji mode */\n           input_mode =  ASCII,    /* input kanji mode */\n           shift_mode =  FALSE;    /* TRUE shift out, or X0201  */\nstatic int mime_decode_mode =   FALSE;    /* MIME mode B base64, Q hex */\n\n/* X0201 / X0208 conversion tables */\n\n/* X0201 kana conversion table */\n/* 90-9F A0-DF */\nstatic const\nunsigned char cv[]= {\n    0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57,\n    0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21,\n    0x25,0x23,0x25,0x25,0x25,0x27,0x25,0x29,\n    0x25,0x63,0x25,0x65,0x25,0x67,0x25,0x43,\n    0x21,0x3c,0x25,0x22,0x25,0x24,0x25,0x26,\n    0x25,0x28,0x25,0x2a,0x25,0x2b,0x25,0x2d,\n    0x25,0x2f,0x25,0x31,0x25,0x33,0x25,0x35,\n    0x25,0x37,0x25,0x39,0x25,0x3b,0x25,0x3d,\n    0x25,0x3f,0x25,0x41,0x25,0x44,0x25,0x46,\n    0x25,0x48,0x25,0x4a,0x25,0x4b,0x25,0x4c,\n    0x25,0x4d,0x25,0x4e,0x25,0x4f,0x25,0x52,\n    0x25,0x55,0x25,0x58,0x25,0x5b,0x25,0x5e,\n    0x25,0x5f,0x25,0x60,0x25,0x61,0x25,0x62,\n    0x25,0x64,0x25,0x66,0x25,0x68,0x25,0x69,\n    0x25,0x6a,0x25,0x6b,0x25,0x6c,0x25,0x6d,\n    0x25,0x6f,0x25,0x73,0x21,0x2b,0x21,0x2c,\n    0x00,0x00};\n\n\n/* X0201 kana conversion table for daguten */\n/* 90-9F A0-DF */\nstatic const\nunsigned char dv[]= { \n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x74,\n    0x00,0x00,0x00,0x00,0x25,0x2c,0x25,0x2e,\n    0x25,0x30,0x25,0x32,0x25,0x34,0x25,0x36,\n    0x25,0x38,0x25,0x3a,0x25,0x3c,0x25,0x3e,\n    0x25,0x40,0x25,0x42,0x25,0x45,0x25,0x47,\n    0x25,0x49,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x25,0x50,0x25,0x53,\n    0x25,0x56,0x25,0x59,0x25,0x5c,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00};\n\n/* X0201 kana conversion table for han-daguten */\n/* 90-9F A0-DF */\nstatic const\nunsigned char ev[]= { \n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x25,0x51,0x25,0x54,\n    0x25,0x57,0x25,0x5a,0x25,0x5d,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00};\n\n\n/* X0208 kigou conversion table */\n/* 0x8140 - 0x819e */\nstatic const\nunsigned char fv[] = {\n\n    0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a,\n    0x3b,0x3f,0x21,0x00,0x00,0x27,0x60,0x00,\n    0x5e,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f,\n    0x5c,0x00,0x00,0x7c,0x00,0x00,0x60,0x27,\n    0x22,0x22,0x28,0x29,0x00,0x00,0x5b,0x5d,\n    0x7b,0x7d,0x3c,0x3e,0x00,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x2b,0x2d,0x00,0x00,\n    0x00,0x3d,0x00,0x3c,0x3e,0x00,0x00,0x00,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n    0x24,0x00,0x00,0x25,0x23,0x26,0x2a,0x40,\n    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\n} ;\n\n\n#define    CRLF      1\n\nstatic int             file_out_f = FALSE;\n#ifdef OVERWRITE\nstatic int             overwrite_f = FALSE;\nstatic int             preserve_time_f = FALSE;\nstatic int             backup_f = FALSE;\nstatic char            *backup_suffix = \"\";\nstatic char *get_backup_filename(const char *suffix, const char *filename);\n#endif\n\nstatic int             crmode_f = 0;   /* CR, NL, CRLF */\n#ifdef EASYWIN /*Easy Win */\nstatic int             end_check;\n#endif /*Easy Win */\n\n#define STD_GC_BUFSIZE (256)\nnkf_char std_gc_buf[STD_GC_BUFSIZE];\nnkf_char std_gc_ndx;\n\n#ifdef WIN32DLL\n#include \"nkf32dll.c\"\n#elif defined(PERL_XS)\n#else /* WIN32DLL */\nint main(int argc, char **argv)\n{\n    FILE  *fin;\n    unsigned char  *cp;\n\n    char *outfname = NULL;\n    char *origfname;\n\n#ifdef EASYWIN /*Easy Win */\n    _BufferSize.y = 400;/*Set Scroll Buffer Size*/\n#endif\n\n    for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) {\n        cp = (unsigned char *)*argv;\n        options(cp);\n#ifdef EXEC_IO\n        if (exec_f){\n            int fds[2], pid;\n            if (pipe(fds) < 0 || (pid = fork()) < 0){\n                abort();\n            }\n            if (pid == 0){\n                if (exec_f > 0){\n                    close(fds[0]);\n                    dup2(fds[1], 1);\n                }else{\n                    close(fds[1]);\n                    dup2(fds[0], 0);\n                }\n                execvp(argv[1], &argv[1]);\n            }\n            if (exec_f > 0){\n                close(fds[1]);\n                dup2(fds[0], 0);\n            }else{\n                close(fds[0]);\n                dup2(fds[1], 1);\n            }\n            argc = 0;\n            break;\n        }\n#endif\n    }\n    if(x0201_f == WISH_TRUE)\n         x0201_f = ((!iso2022jp_f)? TRUE : NO_X0201);\n\n    if (binmode_f == TRUE)\n#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))\n    if (freopen(\"\",\"wb\",stdout) == NULL) \n        return (-1);\n#else\n    setbinmode(stdout);\n#endif\n\n    if (unbuf_f)\n      setbuf(stdout, (char *) NULL);\n    else\n      setvbuffer(stdout, (char *) stdobuf, IOBUF_SIZE);\n\n    if (argc == 0) {\n      if (binmode_f == TRUE)\n#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))\n      if (freopen(\"\",\"rb\",stdin) == NULL) return (-1);\n#else\n      setbinmode(stdin);\n#endif\n      setvbuffer(stdin, (char *) stdibuf, IOBUF_SIZE);\n      if (nop_f)\n          noconvert(stdin);\n      else {\n          kanji_convert(stdin);\n          if (guess_f) print_guessed_code(NULL);\n      }\n    } else {\n      int nfiles = argc;\n\tint is_argument_error = FALSE;\n      while (argc--) {\n\t    is_inputcode_mixed = FALSE;\n\t    is_inputcode_set   = FALSE;\n\t    input_codename = \"\";\n#ifdef CHECK_OPTION\n\t    iconv_for_check = 0;\n#endif\n          if ((fin = fopen((origfname = *argv++), \"r\")) == NULL) {\n              perror(*--argv);\n\t\t*argv++;\n\t\tis_argument_error = TRUE;\n\t\tcontinue;\n          } else {\n#ifdef OVERWRITE\n              int fd = 0;\n              int fd_backup = 0;\n#endif\n\n/* reopen file for stdout */\n              if (file_out_f == TRUE) {\n#ifdef OVERWRITE\n                  if (overwrite_f){\n                      outfname = malloc(strlen(origfname)\n                                        + strlen(\".nkftmpXXXXXX\")\n                                        + 1);\n                      if (!outfname){\n                          perror(origfname);\n                          return -1;\n                      }\n                      strcpy(outfname, origfname);\n#ifdef MSDOS\n                      {\n                          int i;\n                          for (i = strlen(outfname); i; --i){\n                              if (outfname[i - 1] == '/'\n                                  || outfname[i - 1] == '\\\\'){\n                                  break;\n                              }\n                          }\n                          outfname[i] = '\\0';\n                      }\n                      strcat(outfname, \"ntXXXXXX\");\n                      mktemp(outfname);\n\t\t\tfd = open(outfname, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,\n                                S_IREAD | S_IWRITE);\n#else\n                      strcat(outfname, \".nkftmpXXXXXX\");\n                      fd = mkstemp(outfname);\n#endif\n                      if (fd < 0\n                          || (fd_backup = dup(fileno(stdout))) < 0\n                          || dup2(fd, fileno(stdout)) < 0\n                          ){\n                          perror(origfname);\n                          return -1;\n                      }\n                  }else\n#endif\n\t\t  if(argc == 1 ) {\n\t\t      outfname = *argv++;\n\t\t      argc--;\n\t\t  } else {\n\t\t      outfname = \"nkf.out\";\n\t\t  }\n\n\t\t  if(freopen(outfname, \"w\", stdout) == NULL) {\n\t\t      perror (outfname);\n\t\t      return (-1);\n\t\t  }\n                  if (binmode_f == TRUE) {\n#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))\n                      if (freopen(\"\",\"wb\",stdout) == NULL) \n                           return (-1);\n#else\n                      setbinmode(stdout);\n#endif\n                  }\n              }\n              if (binmode_f == TRUE)\n#if defined(__OS2__) && (defined(__IBMC__) || defined(__IBMCPP__))\n                 if (freopen(\"\",\"rb\",fin) == NULL) \n                    return (-1);\n#else\n                 setbinmode(fin);\n#endif \n              setvbuffer(fin, (char *) stdibuf, IOBUF_SIZE);\n              if (nop_f)\n                  noconvert(fin);\n              else {\n                  char *filename = NULL;\n                  kanji_convert(fin);\n                  if (nfiles > 1) filename = origfname;\n                  if (guess_f) print_guessed_code(filename);\n              }\n              fclose(fin);\n#ifdef OVERWRITE\n              if (overwrite_f) {\n                  struct stat     sb;\n#if defined(MSDOS) && !defined(__MINGW32__) && !defined(__WIN32__) && !defined(__WATCOMC__) && !defined(__EMX__) && !defined(__OS2__) && !defined(__DJGPP__)\n                  time_t tb[2];\n#else\n                  struct utimbuf  tb;\n#endif\n\n                  fflush(stdout);\n                  close(fd);\n                  if (dup2(fd_backup, fileno(stdout)) < 0){\n                      perror(\"dup2\");\n                  }\n                  if (stat(origfname, &sb)) {\n                      fprintf(stderr, \"Can't stat %s\\n\", origfname);\n                  }\n                  /* \u001b$B%Q!<%_%C%7%g%s$rI|85\u001b(B */\n                  if (chmod(outfname, sb.st_mode)) {\n                      fprintf(stderr, \"Can't set permission %s\\n\", outfname);\n                  }\n\n                  /* \u001b$B%?%$%`%9%?%s%W$rI|85\u001b(B */\n\t\t    if(preserve_time_f){\n#if defined(MSDOS) && !defined(__MINGW32__) && !defined(__WIN32__) && !defined(__WATCOMC__) && !defined(__EMX__) && !defined(__OS2__) && !defined(__DJGPP__)\n\t\t\ttb[0] = tb[1] = sb.st_mtime;\n\t\t\tif (utime(outfname, tb)) {\n\t\t\t    fprintf(stderr, \"Can't set timestamp %s\\n\", outfname);\n\t\t\t}\n#else\n\t\t\ttb.actime  = sb.st_atime;\n\t\t\ttb.modtime = sb.st_mtime;\n\t\t\tif (utime(outfname, &tb)) {\n\t\t\t    fprintf(stderr, \"Can't set timestamp %s\\n\", outfname);\n\t\t\t}\n#endif\n\t\t    }\n\t\t    if(backup_f){\n\t\t\tchar *backup_filename = get_backup_filename(backup_suffix, origfname);\n#ifdef MSDOS\n\t\t\tunlink(backup_filename);\n#endif\n\t\t\tif (rename(origfname, backup_filename)) {\n\t\t\t    perror(backup_filename);\n\t\t\t    fprintf(stderr, \"Can't rename %s to %s\\n\",\n\t\t\t\t    origfname, backup_filename);\n\t\t\t}\n\t\t    }else{\n#ifdef MSDOS\n\t\t\tif (unlink(origfname)){\n\t\t\t    perror(origfname);\n\t\t\t}\n#endif\n\t\t    }\n                  if (rename(outfname, origfname)) {\n                      perror(origfname);\n                      fprintf(stderr, \"Can't rename %s to %s\\n\",\n                              outfname, origfname);\n                  }\n                  free(outfname);\n              }\n#endif\n          }\n      }\n\tif (is_argument_error)\n\t    return(-1);\n    }\n#ifdef EASYWIN /*Easy Win */\n    if (file_out_f == FALSE) \n        scanf(\"%d\",&end_check);\n    else \n        fclose(stdout);\n#else /* for Other OS */\n    if (file_out_f == TRUE) \n        fclose(stdout);\n#endif /*Easy Win */\n    return (0);\n}\n#endif /* WIN32DLL */\n\n#ifdef OVERWRITE\nchar *get_backup_filename(const char *suffix, const char *filename)\n{\n    char *backup_filename;\n    int asterisk_count = 0;\n    int i, j;\n    int filename_length = strlen(filename);\n\n    for(i = 0; suffix[i]; i++){\n\tif(suffix[i] == '*') asterisk_count++;\n    }\n\n    if(asterisk_count){\n\tbackup_filename = malloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);\n\tif (!backup_filename){\n\t    perror(\"Can't malloc backup filename.\");\n\t    return NULL;\n\t}\n\n\tfor(i = 0, j = 0; suffix[i];){\n\t    if(suffix[i] == '*'){\n\t\tbackup_filename[j] = '\\0';\n\t\tstrncat(backup_filename, filename, filename_length);\n\t\ti++;\n\t\tj += filename_length;\n\t    }else{\n\t\tbackup_filename[j++] = suffix[i++];\n\t    }\n\t}\n\tbackup_filename[j] = '\\0';\n    }else{\n\tj = strlen(suffix) + filename_length;\n\tbackup_filename = malloc( + 1);\n\tstrcpy(backup_filename, filename);\n\tstrcat(backup_filename, suffix);\n\tbackup_filename[j] = '\\0';\n    }\n    return backup_filename;\n}\n#endif\n\nstatic const\nstruct {\n    const char *name;\n    const char *alias;\n} long_option[] = {\n    {\"ic=\", \"\"},\n    {\"oc=\", \"\"},\n    {\"base64\",\"jMB\"},\n    {\"euc\",\"e\"},\n    {\"euc-input\",\"E\"},\n    {\"fj\",\"jm\"},\n    {\"help\",\"v\"},\n    {\"jis\",\"j\"},\n    {\"jis-input\",\"J\"},\n    {\"mac\",\"sLm\"},\n    {\"mime\",\"jM\"},\n    {\"mime-input\",\"m\"},\n    {\"msdos\",\"sLw\"},\n    {\"sjis\",\"s\"},\n    {\"sjis-input\",\"S\"},\n    {\"unix\",\"eLu\"},\n    {\"version\",\"V\"},\n    {\"windows\",\"sLw\"},\n    {\"hiragana\",\"h1\"},\n    {\"katakana\",\"h2\"},\n    {\"katakana-hiragana\",\"h3\"},\n    {\"guess\", \"g\"},\n    {\"cp932\", \"\"},\n    {\"no-cp932\", \"\"},\n#ifdef X0212_ENABLE\n    {\"x0212\", \"\"},\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n    {\"utf8\", \"w\"},\n    {\"utf16\", \"w16\"},\n    {\"ms-ucs-map\", \"\"},\n    {\"fb-skip\", \"\"},\n    {\"fb-html\", \"\"},\n    {\"fb-xml\", \"\"},\n    {\"fb-perl\", \"\"},\n    {\"fb-java\", \"\"},\n    {\"fb-subchar\", \"\"},\n    {\"fb-subchar=\", \"\"},\n#endif\n#ifdef UTF8_INPUT_ENABLE\n    {\"utf8-input\", \"W\"},\n    {\"utf16-input\", \"W16\"},\n    {\"no-cp932ext\", \"\"},\n    {\"no-best-fit-chars\",\"\"},\n#endif\n#ifdef UNICODE_NORMALIZATION\n    {\"utf8mac-input\", \"\"},\n#endif\n#ifdef OVERWRITE\n    {\"overwrite\", \"\"},\n    {\"overwrite=\", \"\"},\n    {\"in-place\", \"\"},\n    {\"in-place=\", \"\"},\n#endif\n#ifdef INPUT_OPTION\n    {\"cap-input\", \"\"},\n    {\"url-input\", \"\"},\n#endif\n#ifdef NUMCHAR_OPTION\n    {\"numchar-input\", \"\"},\n#endif\n#ifdef CHECK_OPTION\n    {\"no-output\", \"\"},\n    {\"debug\", \"\"},\n#endif\n#ifdef SHIFTJIS_CP932\n    {\"cp932inv\", \"\"},\n#endif\n#ifdef EXEC_IO\n    {\"exec-in\", \"\"},\n    {\"exec-out\", \"\"},\n#endif\n    {\"prefix=\", \"\"},\n};\n\nstatic int option_mode = 0;\n\nvoid options(unsigned char *cp)\n{\n    nkf_char i, j;\n    unsigned char *p;\n    unsigned char *cp_back = NULL;\n    char codeset[32];\n\n    if (option_mode==1)\n\treturn;\n    while(*cp && *cp++!='-');\n    while (*cp || cp_back) {\n\tif(!*cp){\n\t    cp = cp_back;\n\t    cp_back = NULL;\n\t    continue;\n\t}\n\tp = 0;\n        switch (*cp++) {\n        case '-':  /* literal options */\n\t    if (!*cp || *cp == SPACE) {        /* ignore the rest of arguments */\n\t\toption_mode = 1;\n\t\treturn;\n\t    }\n            for (i=0;i<sizeof(long_option)/sizeof(long_option[0]);i++) {\n                p = (unsigned char *)long_option[i].name;\n                for (j=0;*p && *p != '=' && *p == cp[j];p++, j++);\n\t\tif (*p == cp[j] || cp[j] == ' '){\n\t\t    p = &cp[j] + 1;\n\t\t    break;\n\t\t}\n\t\tp = 0;\n            }\n\t    if (p == 0) return;\n\t    while(*cp && *cp != SPACE && cp++);\n            if (long_option[i].alias[0]){\n\t\tcp_back = cp;\n\t\tcp = (unsigned char *)long_option[i].alias;\n\t    }else{\n                if (strcmp(long_option[i].name, \"ic=\") == 0){\n\t\t    for (i=0; i < 16 && SPACE < p[i] && p[i] < DEL; i++){\n\t\t\tcodeset[i] = nkf_toupper(p[i]);\n\t\t    }\n\t\t    codeset[i] = 0;\n\t\t    if(strcmp(codeset, \"ISO-2022-JP\") == 0){\n\t\t\tinput_f = JIS_INPUT;\n\t\t    }else if(strcmp(codeset, \"X-ISO2022JP-CP932\") == 0 ||\n\t\t      strcmp(codeset, \"CP50220\") == 0 ||\n\t\t      strcmp(codeset, \"CP50221\") == 0 ||\n\t\t      strcmp(codeset, \"CP50222\") == 0){\n\t\t\tinput_f = JIS_INPUT;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = TRUE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"ISO-2022-JP-1\") == 0){\n\t\t\tinput_f = JIS_INPUT;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n\t\t    }else if(strcmp(codeset, \"ISO-2022-JP-3\") == 0){\n\t\t\tinput_f = JIS_INPUT;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n\t\t\tx0213_f = TRUE;\n\t\t    }else if(strcmp(codeset, \"SHIFT_JIS\") == 0){\n\t\t\tinput_f = SJIS_INPUT;\n\t\t    }else if(strcmp(codeset, \"WINDOWS-31J\") == 0 ||\n\t\t\t     strcmp(codeset, \"CSWINDOWS31J\") == 0 ||\n\t\t\t     strcmp(codeset, \"CP932\") == 0 ||\n\t\t\t     strcmp(codeset, \"MS932\") == 0){\n\t\t\tinput_f = SJIS_INPUT;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = TRUE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUCJP\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUC-JP\") == 0){\n\t\t\tinput_f = EUC_INPUT;\n\t\t    }else if(strcmp(codeset, \"CP51932\") == 0){\n\t\t\tinput_f = EUC_INPUT;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = TRUE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUC-JP-MS\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUCJP-MS\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUCJPMS\") == 0){\n\t\t\tinput_f = EUC_INPUT;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_MS;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUC-JP-ASCII\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUCJP-ASCII\") == 0){\n\t\t\tinput_f = EUC_INPUT;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_ASCII;\n#endif\n\t\t    }else if(strcmp(codeset, \"SHIFT_JISX0213\") == 0 ||\n\t\t\t     strcmp(codeset, \"SHIFT_JIS-2004\") == 0){\n\t\t\tinput_f = SJIS_INPUT;\n\t\t\tx0213_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = FALSE;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUC-JISX0213\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUC-JIS-2004\") == 0){\n\t\t\tinput_f = EUC_INPUT;\n\t\t\tx0213_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp51932_f = FALSE;\n#endif\n#ifdef UTF8_INPUT_ENABLE\n\t\t    }else if(strcmp(codeset, \"UTF-8\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-8N\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-8-BOM\") == 0){\n\t\t\tinput_f = UTF8_INPUT;\n#ifdef UNICODE_NORMALIZATION\n\t\t    }else if(strcmp(codeset, \"UTF8-MAC\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-8-MAC\") == 0){\n\t\t\tinput_f = UTF8_INPUT;\n\t\t\tnfc_f = TRUE;\n#endif\n\t\t    }else if(strcmp(codeset, \"UTF-16\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-16BE\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-16BE-BOM\") == 0){\n\t\t\tinput_f = UTF16_INPUT;\n\t\t\tinput_endian = ENDIAN_BIG;\n\t\t    }else if(strcmp(codeset, \"UTF-16LE\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-16LE-BOM\") == 0){\n\t\t\tinput_f = UTF16_INPUT;\n\t\t\tinput_endian = ENDIAN_LITTLE;\n\t\t    }else if(strcmp(codeset, \"UTF-32\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-32BE\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-32BE-BOM\") == 0){\n\t\t\tinput_f = UTF32_INPUT;\n\t\t\tinput_endian = ENDIAN_BIG;\n\t\t    }else if(strcmp(codeset, \"UTF-32LE\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-32LE-BOM\") == 0){\n\t\t\tinput_f = UTF32_INPUT;\n\t\t\tinput_endian = ENDIAN_LITTLE;\n#endif\n\t\t    }\n                    continue;\n\t\t}\n                if (strcmp(long_option[i].name, \"oc=\") == 0){\n\t\t    x0201_f = FALSE;\n\t\t    for (i=0; i < 16 && SPACE < p[i] && p[i] < DEL; i++){\n\t\t\tcodeset[i] = nkf_toupper(p[i]);\n\t\t    }\n\t\t    codeset[i] = 0;\n\t\t    if(strcmp(codeset, \"ISO-2022-JP\") == 0){\n\t\t\toutput_conv = j_oconv;\n\t\t    }else if(strcmp(codeset, \"X-ISO2022JP-CP932\") == 0){\n\t\t\toutput_conv = j_oconv;\n\t\t\tno_cp932ext_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"CP50220\") == 0){\n\t\t\toutput_conv = j_oconv;\n\t\t\tx0201_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"CP50221\") == 0){\n\t\t\toutput_conv = j_oconv;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"ISO-2022-JP-1\") == 0){\n\t\t\toutput_conv = j_oconv;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n\t\t    }else if(strcmp(codeset, \"ISO-2022-JP-3\") == 0){\n\t\t\toutput_conv = j_oconv;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n\t\t\tx0213_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n\t\t    }else if(strcmp(codeset, \"SHIFT_JIS\") == 0){\n\t\t\toutput_conv = s_oconv;\n\t\t    }else if(strcmp(codeset, \"WINDOWS-31J\") == 0 ||\n\t\t\t     strcmp(codeset, \"CSWINDOWS31J\") == 0 ||\n\t\t\t     strcmp(codeset, \"CP932\") == 0 ||\n\t\t\t     strcmp(codeset, \"MS932\") == 0){\n\t\t\toutput_conv = s_oconv;\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUCJP\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUC-JP\") == 0){\n\t\t\toutput_conv = e_oconv;\n\t\t    }else if(strcmp(codeset, \"CP51932\") == 0){\n\t\t\toutput_conv = e_oconv;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_CP932;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUC-JP-MS\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUCJP-MS\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUCJPMS\") == 0){\n\t\t\toutput_conv = e_oconv;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_MS;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUC-JP-ASCII\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUCJP-ASCII\") == 0){\n\t\t\toutput_conv = e_oconv;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t\tms_ucs_map_f = UCS_MAP_ASCII;\n#endif\n\t\t    }else if(strcmp(codeset, \"SHIFT_JISX0213\") == 0 ||\n\t\t\t     strcmp(codeset, \"SHIFT_JIS-2004\") == 0){\n\t\t\toutput_conv = s_oconv;\n\t\t\tx0213_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n\t\t    }else if(strcmp(codeset, \"EUC-JISX0213\") == 0 ||\n\t\t\t     strcmp(codeset, \"EUC-JIS-2004\") == 0){\n\t\t\toutput_conv = e_oconv;\n#ifdef X0212_ENABLE\n\t\t\tx0212_f = TRUE;\n#endif\n\t\t\tx0213_f = TRUE;\n#ifdef SHIFTJIS_CP932\n\t\t\tcp932inv_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n\t\t    }else if(strcmp(codeset, \"UTF-8\") == 0){\n\t\t\toutput_conv = w_oconv;\n\t\t    }else if(strcmp(codeset, \"UTF-8N\") == 0){\n\t\t\toutput_conv = w_oconv;\n\t\t    }else if(strcmp(codeset, \"UTF-8-BOM\") == 0){\n\t\t\toutput_conv = w_oconv;\n\t\t\toutput_bom_f = TRUE;\n\t\t    }else if(strcmp(codeset, \"UTF-16BE\") == 0){\n\t\t\toutput_conv = w_oconv16;\n\t\t    }else if(strcmp(codeset, \"UTF-16\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-16BE-BOM\") == 0){\n\t\t\toutput_conv = w_oconv16;\n\t\t\toutput_bom_f = TRUE;\n\t\t    }else if(strcmp(codeset, \"UTF-16LE\") == 0){\n\t\t\toutput_conv = w_oconv16;\n\t\t\toutput_endian = ENDIAN_LITTLE;\n\t\t    }else if(strcmp(codeset, \"UTF-16LE-BOM\") == 0){\n\t\t\toutput_conv = w_oconv16;\n\t\t\toutput_endian = ENDIAN_LITTLE;\n\t\t\toutput_bom_f = TRUE;\n\t\t    }else if(strcmp(codeset, \"UTF-32\") == 0 ||\n\t\t\t     strcmp(codeset, \"UTF-32BE\") == 0){\n\t\t\toutput_conv = w_oconv32;\n\t\t    }else if(strcmp(codeset, \"UTF-32BE-BOM\") == 0){\n\t\t\toutput_conv = w_oconv32;\n\t\t\toutput_bom_f = TRUE;\n\t\t    }else if(strcmp(codeset, \"UTF-32LE\") == 0){\n\t\t\toutput_conv = w_oconv32;\n\t\t\toutput_endian = ENDIAN_LITTLE;\n\t\t    }else if(strcmp(codeset, \"UTF-32LE-BOM\") == 0){\n\t\t\toutput_conv = w_oconv32;\n\t\t\toutput_endian = ENDIAN_LITTLE;\n\t\t\toutput_bom_f = TRUE;\n#endif\n\t\t    }\n                    continue;\n\t\t}\n#ifdef OVERWRITE\n                if (strcmp(long_option[i].name, \"overwrite\") == 0){\n                    file_out_f = TRUE;\n                    overwrite_f = TRUE;\n\t\t    preserve_time_f = TRUE;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"overwrite=\") == 0){\n                    file_out_f = TRUE;\n                    overwrite_f = TRUE;\n\t\t    preserve_time_f = TRUE;\n\t\t    backup_f = TRUE;\n\t\t    backup_suffix = malloc(strlen((char *) p) + 1);\n\t\t    strcpy(backup_suffix, (char *) p);\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"in-place\") == 0){\n                    file_out_f = TRUE;\n                    overwrite_f = TRUE;\n\t\t    preserve_time_f = FALSE;\n\t\t    continue;\n                }\n                if (strcmp(long_option[i].name, \"in-place=\") == 0){\n                    file_out_f = TRUE;\n                    overwrite_f = TRUE;\n\t\t    preserve_time_f = FALSE;\n\t\t    backup_f = TRUE;\n\t\t    backup_suffix = malloc(strlen((char *) p) + 1);\n\t\t    strcpy(backup_suffix, (char *) p);\n\t\t    continue;\n                }\n#endif\n#ifdef INPUT_OPTION\n                if (strcmp(long_option[i].name, \"cap-input\") == 0){\n                    cap_f = TRUE;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"url-input\") == 0){\n                    url_f = TRUE;\n                    continue;\n                }\n#endif\n#ifdef NUMCHAR_OPTION\n                if (strcmp(long_option[i].name, \"numchar-input\") == 0){\n                    numchar_f = TRUE;\n                    continue;\n                }\n#endif\n#ifdef CHECK_OPTION\n                if (strcmp(long_option[i].name, \"no-output\") == 0){\n                    noout_f = TRUE;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"debug\") == 0){\n                    debug_f = TRUE;\n                    continue;\n                }\n#endif\n                if (strcmp(long_option[i].name, \"cp932\") == 0){\n#ifdef SHIFTJIS_CP932\n                    cp51932_f = TRUE;\n                    cp932inv_f = TRUE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n                    ms_ucs_map_f = UCS_MAP_CP932;\n#endif\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"no-cp932\") == 0){\n#ifdef SHIFTJIS_CP932\n                    cp51932_f = FALSE;\n                    cp932inv_f = FALSE;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n                    ms_ucs_map_f = UCS_MAP_ASCII;\n#endif\n                    continue;\n                }\n#ifdef SHIFTJIS_CP932\n                if (strcmp(long_option[i].name, \"cp932inv\") == 0){\n                    cp932inv_f = TRUE;\n                    continue;\n                }\n#endif\n\n#ifdef X0212_ENABLE\n                if (strcmp(long_option[i].name, \"x0212\") == 0){\n                    x0212_f = TRUE;\n                    continue;\n                }\n#endif\n\n#ifdef EXEC_IO\n                  if (strcmp(long_option[i].name, \"exec-in\") == 0){\n                      exec_f = 1;\n                      return;\n                  }\n                  if (strcmp(long_option[i].name, \"exec-out\") == 0){\n                      exec_f = -1;\n                      return;\n                  }\n#endif\n#if defined(UTF8_OUTPUT_ENABLE) && defined(UTF8_INPUT_ENABLE)\n                if (strcmp(long_option[i].name, \"no-cp932ext\") == 0){\n\t\t    no_cp932ext_f = TRUE;\n                    continue;\n                }\n\t\tif (strcmp(long_option[i].name, \"no-best-fit-chars\") == 0){\n\t\t    no_best_fit_chars_f = TRUE;\n\t\t    continue;\n\t\t}\n                if (strcmp(long_option[i].name, \"fb-skip\") == 0){\n\t\t    encode_fallback = NULL;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"fb-html\") == 0){\n\t\t    encode_fallback = encode_fallback_html;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"fb-xml\" ) == 0){\n\t\t    encode_fallback = encode_fallback_xml;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"fb-java\") == 0){\n\t\t    encode_fallback = encode_fallback_java;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"fb-perl\") == 0){\n\t\t    encode_fallback = encode_fallback_perl;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"fb-subchar\") == 0){\n\t\t    encode_fallback = encode_fallback_subchar;\n                    continue;\n                }\n                if (strcmp(long_option[i].name, \"fb-subchar=\") == 0){\n\t\t    encode_fallback = encode_fallback_subchar;\n\t\t    unicode_subchar = 0;\n\t\t    if (p[0] != '0'){\n\t\t\t/* decimal number */\n\t\t\tfor (i = 0; i < 7 && nkf_isdigit(p[i]); i++){\n\t\t\t    unicode_subchar *= 10;\n\t\t\t    unicode_subchar += hex2bin(p[i]);\n\t\t\t}\n\t\t    }else if(p[1] == 'x' || p[1] == 'X'){\n\t\t\t/* hexadecimal number */\n\t\t\tfor (i = 2; i < 8 && nkf_isxdigit(p[i]); i++){\n\t\t\t    unicode_subchar <<= 4;\n\t\t\t    unicode_subchar |= hex2bin(p[i]);\n\t\t\t}\n\t\t    }else{\n\t\t\t/* octal number */\n\t\t\tfor (i = 1; i < 8 && nkf_isoctal(p[i]); i++){\n\t\t\t    unicode_subchar *= 8;\n\t\t\t    unicode_subchar += hex2bin(p[i]);\n\t\t\t}\n\t\t    }\n\t\t    w16e_conv(unicode_subchar, &i, &j);\n\t\t    unicode_subchar = i<<8 | j;\n                    continue;\n                }\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n                if (strcmp(long_option[i].name, \"ms-ucs-map\") == 0){\n                    ms_ucs_map_f = UCS_MAP_MS;\n                    continue;\n                }\n#endif\n#ifdef UNICODE_NORMALIZATION\n\t\tif (strcmp(long_option[i].name, \"utf8mac-input\") == 0){\n\t\t    input_f = UTF8_INPUT;\n\t\t    nfc_f = TRUE;\n\t\t    continue;\n\t\t}\n#endif\n                if (strcmp(long_option[i].name, \"prefix=\") == 0){\n                    if (nkf_isgraph(p[0])){\n                        for (i = 1; nkf_isgraph(p[i]); i++){\n                            prefix_table[p[i]] = p[0];\n                        }\n                    }\n                    continue;\n                }\n            }\n            continue;\n        case 'b':           /* buffered mode */\n            unbuf_f = FALSE;\n            continue;\n        case 'u':           /* non bufferd mode */\n            unbuf_f = TRUE;\n            continue;\n        case 't':           /* transparent mode */\n            if (*cp=='1') {\n\t\t/* alias of -t */\n\t\tnop_f = TRUE;\n\t\t*cp++;\n\t    } else if (*cp=='2') {\n\t\t/*\n\t\t * -t with put/get\n\t\t *\n\t\t * nkf -t2MB hoge.bin | nkf -t2mB | diff -s - hoge.bin\n\t\t *\n\t\t */\n\t\tnop_f = 2;\n\t\t*cp++;\n            } else\n\t\tnop_f = TRUE;\n            continue;\n        case 'j':           /* JIS output */\n        case 'n':\n            output_conv = j_oconv;\n            continue;\n        case 'e':           /* AT&T EUC output */\n            output_conv = e_oconv;\n            cp932inv_f = FALSE;\n            continue;\n        case 's':           /* SJIS output */\n            output_conv = s_oconv;\n            continue;\n        case 'l':           /* ISO8859 Latin-1 support, no conversion */\n            iso8859_f = TRUE;  /* Only compatible with ISO-2022-JP */\n            input_f = LATIN1_INPUT;\n            continue;\n        case 'i':           /* Kanji IN ESC-$-@/B */\n            if (*cp=='@'||*cp=='B') \n                kanji_intro = *cp++;\n            continue;\n        case 'o':           /* ASCII IN ESC-(-J/B */\n            if (*cp=='J'||*cp=='B'||*cp=='H') \n                ascii_intro = *cp++;\n            continue;\n        case 'h':\n            /*  \n                bit:1   katakana->hiragana\n                bit:2   hiragana->katakana\n            */\n            if ('9'>= *cp && *cp>='0') \n                hira_f |= (*cp++ -'0');\n            else \n                hira_f |= 1;\n            continue;\n        case 'r':\n            rot_f = TRUE;\n            continue;\n#if defined(MSDOS) || defined(__OS2__) \n        case 'T':\n            binmode_f = FALSE;\n            continue;\n#endif\n#ifndef PERL_XS\n        case 'V':\n            version();\n            exit(1);\n            break;\n        case 'v':\n            usage();\n            exit(1);\n            break;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n        case 'w':           /* UTF-8 output */\n            if (cp[0] == '8') {\n\t\toutput_conv = w_oconv; cp++;\n\t\tif (cp[0] == '0'){\n\t\t    cp++;\n\t\t} else {\n\t\t    output_bom_f = TRUE;\n\t\t}\n\t    } else {\n\t\tif ('1'== cp[0] && '6'==cp[1]) {\n\t\t    output_conv = w_oconv16; cp+=2;\n\t\t} else if ('3'== cp[0] && '2'==cp[1]) {\n\t\t    output_conv = w_oconv32; cp+=2;\n\t\t} else {\n\t\t    output_conv = w_oconv;\n\t\t    continue;\n\t\t}\n\t\tif (cp[0]=='L') {\n\t\t    cp++;\n\t\t    output_endian = ENDIAN_LITTLE;\n\t\t} else if (cp[0] == 'B') {\n\t\t    cp++;\n                } else {\n\t\t    continue;\n                }\n\t\tif (cp[0] == '0'){\n\t\t    cp++;\n\t\t} else {\n\t\t    output_bom_f = TRUE;\n\t\t}\n\t    }\n            continue;\n#endif\n#ifdef UTF8_INPUT_ENABLE\n        case 'W':           /* UTF input */\n\t    if (cp[0] == '8') {\n\t\tcp++;\n\t\tinput_f = UTF8_INPUT;\n\t    }else{\n\t\tif ('1'== cp[0] && '6'==cp[1]) {\n\t\t    cp += 2;\n\t\t    input_f = UTF16_INPUT;\n\t\t    input_endian = ENDIAN_BIG;\n\t\t} else if ('3'== cp[0] && '2'==cp[1]) {\n\t\t    cp += 2;\n\t\t    input_f = UTF32_INPUT;\n\t\t    input_endian = ENDIAN_BIG;\n\t\t} else {\n\t\t    input_f = UTF8_INPUT;\n\t\t    continue;\n\t\t}\n\t\tif (cp[0]=='L') {\n\t\t    cp++;\n\t\t    input_endian = ENDIAN_LITTLE;\n\t\t} else if (cp[0] == 'B') {\n\t\t    cp++;\n\t\t}\n\t    }\n            continue;\n#endif\n        /* Input code assumption */\n        case 'J':   /* JIS input */\n            input_f = JIS_INPUT;\n            continue;\n        case 'E':   /* AT&T EUC input */\n            input_f = EUC_INPUT;\n            continue;\n        case 'S':   /* MS Kanji input */\n            input_f = SJIS_INPUT;\n            if (x0201_f==NO_X0201) x0201_f=TRUE;\n            continue;\n        case 'Z':   /* Convert X0208 alphabet to asii */\n            /*  bit:0   Convert X0208\n                bit:1   Convert Kankaku to one space\n                bit:2   Convert Kankaku to two spaces\n                bit:3   Convert HTML Entity\n            */\n            if ('9'>= *cp && *cp>='0') \n                alpha_f |= 1<<(*cp++ -'0');\n            else \n                alpha_f |= TRUE;\n            continue;\n        case 'x':   /* Convert X0201 kana to X0208 or X0201 Conversion */\n            x0201_f = FALSE;    /* No X0201->X0208 conversion */\n            /* accept  X0201\n                    ESC-(-I     in JIS, EUC, MS Kanji\n                    SI/SO       in JIS, EUC, MS Kanji\n                    SSO         in EUC, JIS, not in MS Kanji\n                    MS Kanji (0xa0-0xdf) \n               output  X0201\n                    ESC-(-I     in JIS (0x20-0x5f)\n                    SSO         in EUC (0xa0-0xdf)\n                    0xa0-0xd    in MS Kanji (0xa0-0xdf) \n            */\n            continue;\n        case 'X':   /* Assume X0201 kana */\n            /* Default value is NO_X0201 for EUC/MS-Kanji mix */\n            x0201_f = TRUE;\n            continue;\n        case 'F':   /* prserve new lines */\n\t    fold_preserve_f = TRUE;\n        case 'f':   /* folding -f60 or -f */\n            fold_f = TRUE;\n            fold_len = 0;\n            while('0'<= *cp && *cp <='9') { /* we don't use atoi here */\n\t\tfold_len *= 10;\n\t\tfold_len += *cp++ - '0';\n\t    }\n            if (!(0<fold_len && fold_len<BUFSIZ)) \n                fold_len = DEFAULT_FOLD;\n\t    if (*cp=='-') {\n\t\tfold_margin = 0;\n\t\tcp++;\n\t\twhile('0'<= *cp && *cp <='9') { /* we don't use atoi here */\n\t\t    fold_margin *= 10;\n\t\t    fold_margin += *cp++ - '0';\n\t\t}\n\t    }\n            continue;\n        case 'm':   /* MIME support */\n            /* mime_decode_f = TRUE; */ /* this has too large side effects... */\n            if (*cp=='B'||*cp=='Q') {\n                mime_decode_mode = *cp++;\n                mimebuf_f = FIXED_MIME;\n            } else if (*cp=='N') {\n                mime_f = TRUE; cp++;\n            } else if (*cp=='S') {\n                mime_f = STRICT_MIME; cp++;\n            } else if (*cp=='0') {\n                mime_decode_f = FALSE;\n                mime_f = FALSE; cp++;\n            }\n            continue;\n        case 'M':   /* MIME output */\n            if (*cp=='B') {\n                mimeout_mode = 'B';\n                mimeout_f = FIXED_MIME; cp++;\n            } else if (*cp=='Q') {\n                mimeout_mode = 'Q';\n                mimeout_f = FIXED_MIME; cp++;\n            } else {\n\t\tmimeout_f = TRUE;\n\t    }\n            continue;\n        case 'B':   /* Broken JIS support */\n            /*  bit:0   no ESC JIS\n                bit:1   allow any x on ESC-(-x or ESC-$-x\n                bit:2   reset to ascii on NL\n            */\n            if ('9'>= *cp && *cp>='0') \n                broken_f |= 1<<(*cp++ -'0');\n            else \n                broken_f |= TRUE;\n            continue;\n#ifndef PERL_XS\n        case 'O':/* for Output file */\n            file_out_f = TRUE;\n            continue;\n#endif\n        case 'c':/* add cr code */\n            crmode_f = CRLF;\n            continue;\n        case 'd':/* delete cr code */\n            crmode_f = NL;\n            continue;\n        case 'I':   /* ISO-2022-JP output */\n            iso2022jp_f = TRUE;\n            continue;\n        case 'L':  /* line mode */\n            if (*cp=='u') {         /* unix */\n                crmode_f = NL; cp++;\n            } else if (*cp=='m') { /* mac */\n                crmode_f = CR; cp++;\n            } else if (*cp=='w') { /* windows */\n                crmode_f = CRLF; cp++;\n            } else if (*cp=='0') { /* no conversion  */\n                crmode_f = 0; cp++;\n            }\n            continue;\n        case 'g':\n#ifndef PERL_XS\n            guess_f = TRUE;\n#endif\n            continue;\n        case ' ':    \n        /* module muliple options in a string are allowed for Perl moudle  */\n\t    while(*cp && *cp++!='-');\n            continue;\n        default:\n            /* bogus option but ignored */\n            continue;\n        }\n    }\n}\n\nstruct input_code * find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))\n{\n    if (iconv_func){\n        struct input_code *p = input_code_list;\n        while (p->name){\n            if (iconv_func == p->iconv_func){\n                return p;\n            }\n            p++;\n        }\n    }\n    return 0;\n}\n\nvoid set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))\n{\n#ifdef INPUT_CODE_FIX\n    if (f || !input_f)\n#endif\n        if (estab_f != f){\n            estab_f = f;\n        }\n\n    if (iconv_func\n#ifdef INPUT_CODE_FIX\n        && (f == -TRUE || !input_f) /* -TRUE means \"FORCE\" */\n#endif\n        ){\n        iconv = iconv_func;\n    }\n#ifdef CHECK_OPTION\n    if (estab_f && iconv_for_check != iconv){\n        struct input_code *p = find_inputcode_byfunc(iconv);\n        if (p){\n            set_input_codename(p->name);\n            debug(input_codename);\n        }\n        iconv_for_check = iconv;\n    }\n#endif\n}\n\n#define SCORE_L2       (1)                   /* \u001b$BBh\u001b(B2\u001b$B?e=`4A;z\u001b(B */\n#define SCORE_KANA     (SCORE_L2 << 1)       /* \u001b$B$$$o$f$kH>3Q%+%J\u001b(B */\n#define SCORE_DEPEND   (SCORE_KANA << 1)     /* \u001b$B5!<o0MB8J8;z\u001b(B */\n#ifdef SHIFTJIS_CP932\n#define SCORE_CP932    (SCORE_DEPEND << 1)   /* CP932 \u001b$B$K$h$kFI$_49$(\u001b(B */\n#define SCORE_NO_EXIST (SCORE_CP932 << 1)    /* \u001b$BB8:_$7$J$$J8;z\u001b(B */\n#else\n#define SCORE_NO_EXIST (SCORE_DEPEND << 1)   /* \u001b$BB8:_$7$J$$J8;z\u001b(B */\n#endif\n#define SCORE_iMIME    (SCORE_NO_EXIST << 1) /* MIME \u001b$B$K$h$k;XDj\u001b(B */\n#define SCORE_ERROR    (SCORE_iMIME << 1) /* \u001b$B%(%i!<\u001b(B */\n\n#define SCORE_INIT (SCORE_iMIME)\n\nconst nkf_char score_table_A0[] = {\n    0, 0, 0, 0,\n    0, 0, 0, 0,\n    0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,\n    SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_NO_EXIST,\n};\n\nconst nkf_char score_table_F0[] = {\n    SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,\n    SCORE_L2, SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST,\n    SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,\n    SCORE_DEPEND, SCORE_NO_EXIST, SCORE_NO_EXIST, SCORE_ERROR,\n};\n\nvoid set_code_score(struct input_code *ptr, nkf_char score)\n{\n    if (ptr){\n        ptr->score |= score;\n    }\n}\n\nvoid clr_code_score(struct input_code *ptr, nkf_char score)\n{\n    if (ptr){\n        ptr->score &= ~score;\n    }\n}\n\nvoid code_score(struct input_code *ptr)\n{\n    nkf_char c2 = ptr->buf[0];\n#ifdef UTF8_OUTPUT_ENABLE\n    nkf_char c1 = ptr->buf[1];\n#endif\n    if (c2 < 0){\n        set_code_score(ptr, SCORE_ERROR);\n    }else if (c2 == SSO){\n        set_code_score(ptr, SCORE_KANA);\n#ifdef UTF8_OUTPUT_ENABLE\n    }else if (!e2w_conv(c2, c1)){\n        set_code_score(ptr, SCORE_NO_EXIST);\n#endif\n    }else if ((c2 & 0x70) == 0x20){\n        set_code_score(ptr, score_table_A0[c2 & 0x0f]);\n    }else if ((c2 & 0x70) == 0x70){\n        set_code_score(ptr, score_table_F0[c2 & 0x0f]);\n    }else if ((c2 & 0x70) >= 0x50){\n        set_code_score(ptr, SCORE_L2);\n    }\n}\n\nvoid status_disable(struct input_code *ptr)\n{\n    ptr->stat = -1;\n    ptr->buf[0] = -1;\n    code_score(ptr);\n    if (iconv == ptr->iconv_func) set_iconv(FALSE, 0);\n}\n\nvoid status_push_ch(struct input_code *ptr, nkf_char c)\n{\n    ptr->buf[ptr->index++] = c;\n}\n\nvoid status_clear(struct input_code *ptr)\n{\n    ptr->stat = 0;\n    ptr->index = 0;\n}\n\nvoid status_reset(struct input_code *ptr)\n{\n    status_clear(ptr);\n    ptr->score = SCORE_INIT;\n}\n\nvoid status_reinit(struct input_code *ptr)\n{\n    status_reset(ptr);\n    ptr->_file_stat = 0;\n}\n\nvoid status_check(struct input_code *ptr, nkf_char c)\n{\n    if (c <= DEL && estab_f){\n        status_reset(ptr);\n    }\n}\n\nvoid s_status(struct input_code *ptr, nkf_char c)\n{\n    switch(ptr->stat){\n      case -1:\n          status_check(ptr, c);\n          break;\n      case 0:\n          if (c <= DEL){\n              break;\n#ifdef NUMCHAR_OPTION\n          }else if (is_unicode_capsule(c)){\n              break;\n#endif\n          }else if (0xa1 <= c && c <= 0xdf){\n              status_push_ch(ptr, SSO);\n              status_push_ch(ptr, c);\n              code_score(ptr);\n              status_clear(ptr);\n          }else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xef)){\n              ptr->stat = 1;\n              status_push_ch(ptr, c);\n#ifdef SHIFTJIS_CP932\n          }else if (cp51932_f\n                    && is_ibmext_in_sjis(c)){\n              ptr->stat = 2;\n              status_push_ch(ptr, c);\n#endif /* SHIFTJIS_CP932 */\n#ifdef X0212_ENABLE\n          }else if (x0212_f && 0xf0 <= c && c <= 0xfc){\n              ptr->stat = 1;\n              status_push_ch(ptr, c);\n#endif /* X0212_ENABLE */\n          }else{\n              status_disable(ptr);\n          }\n          break;\n      case 1:\n          if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){\n              status_push_ch(ptr, c);\n              s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);\n              code_score(ptr);\n              status_clear(ptr);\n          }else{\n              status_disable(ptr);\n          }\n          break;\n      case 2:\n#ifdef SHIFTJIS_CP932\n          if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){\n              status_push_ch(ptr, c);\n              if (s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]) == 0){\n                  set_code_score(ptr, SCORE_CP932);\n                  status_clear(ptr);\n                  break;\n              }\n          }\n#endif /* SHIFTJIS_CP932 */\n#ifndef X0212_ENABLE\n          status_disable(ptr);\n#endif\n          break;\n    }\n}\n\nvoid e_status(struct input_code *ptr, nkf_char c)\n{\n    switch (ptr->stat){\n      case -1:\n          status_check(ptr, c);\n          break;\n      case 0:\n          if (c <= DEL){\n              break;\n#ifdef NUMCHAR_OPTION\n          }else if (is_unicode_capsule(c)){\n              break;\n#endif\n          }else if (SSO == c || (0xa1 <= c && c <= 0xfe)){\n              ptr->stat = 1;\n              status_push_ch(ptr, c);\n#ifdef X0212_ENABLE\n          }else if (0x8f == c){\n              ptr->stat = 2;\n              status_push_ch(ptr, c);\n#endif /* X0212_ENABLE */\n          }else{\n              status_disable(ptr);\n          }\n          break;\n      case 1:\n          if (0xa1 <= c && c <= 0xfe){\n              status_push_ch(ptr, c);\n              code_score(ptr);\n              status_clear(ptr);\n          }else{\n              status_disable(ptr);\n          }\n          break;\n#ifdef X0212_ENABLE\n      case 2:\n          if (0xa1 <= c && c <= 0xfe){\n              ptr->stat = 1;\n              status_push_ch(ptr, c);\n          }else{\n              status_disable(ptr);\n          }\n#endif /* X0212_ENABLE */\n    }\n}\n\n#ifdef UTF8_INPUT_ENABLE\nvoid w_status(struct input_code *ptr, nkf_char c)\n{\n    switch (ptr->stat){\n      case -1:\n          status_check(ptr, c);\n          break;\n      case 0:\n          if (c <= DEL){\n              break;\n#ifdef NUMCHAR_OPTION\n          }else if (is_unicode_capsule(c)){\n              break;\n#endif\n          }else if (0xc0 <= c && c <= 0xdf){\n              ptr->stat = 1;\n              status_push_ch(ptr, c);\n          }else if (0xe0 <= c && c <= 0xef){\n              ptr->stat = 2;\n              status_push_ch(ptr, c);\n          }else if (0xf0 <= c && c <= 0xf4){\n              ptr->stat = 3;\n              status_push_ch(ptr, c);\n          }else{\n              status_disable(ptr);\n          }\n          break;\n      case 1:\n      case 2:\n          if (0x80 <= c && c <= 0xbf){\n              status_push_ch(ptr, c);\n              if (ptr->index > ptr->stat){\n                  int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb\n                             && ptr->buf[2] == 0xbf);\n                  w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],\n                           &ptr->buf[0], &ptr->buf[1]);\n                  if (!bom){\n                      code_score(ptr);\n                  }\n                  status_clear(ptr);\n              }\n          }else{\n              status_disable(ptr);\n          }\n          break;\n      case 3:\n\tif (0x80 <= c && c <= 0xbf){\n\t    if (ptr->index < ptr->stat){\n\t\tstatus_push_ch(ptr, c);\n\t    } else {\n\t    \tstatus_clear(ptr);\n\t    }\n          }else{\n              status_disable(ptr);\n          }\n          break;\n    }\n}\n#endif\n\nvoid code_status(nkf_char c)\n{\n    int action_flag = 1;\n    struct input_code *result = 0;\n    struct input_code *p = input_code_list;\n    while (p->name){\n        if (!p->status_func) {\n\t    ++p;\n\t    continue;\n\t}\n        if (!p->status_func)\n\t    continue;\n        (p->status_func)(p, c);\n        if (p->stat > 0){\n            action_flag = 0;\n        }else if(p->stat == 0){\n            if (result){\n                action_flag = 0;\n            }else{\n                result = p;\n            }\n        }\n        ++p;\n    }\n\n    if (action_flag){\n        if (result && !estab_f){\n            set_iconv(TRUE, result->iconv_func);\n        }else if (c <= DEL){\n            struct input_code *ptr = input_code_list;\n            while (ptr->name){\n                status_reset(ptr);\n                ++ptr;\n            }\n        }\n    }\n}\n\n#ifndef WIN32DLL\nnkf_char std_getc(FILE *f)\n{\n    if (std_gc_ndx){\n        return std_gc_buf[--std_gc_ndx];\n    }\n    return getc(f);\n}\n#endif /*WIN32DLL*/\n\nnkf_char std_ungetc(nkf_char c, FILE *f)\n{\n    if (std_gc_ndx == STD_GC_BUFSIZE){\n        return EOF;\n    }\n    std_gc_buf[std_gc_ndx++] = c;\n    return c;\n}\n\n#ifndef WIN32DLL\nvoid std_putc(nkf_char c)\n{\n    if(c!=EOF)\n      putchar(c);\n}\n#endif /*WIN32DLL*/\n\n#if !defined(PERL_XS) && !defined(WIN32DLL)\nnkf_char noconvert(FILE *f)\n{\n    nkf_char    c;\n\n    if (nop_f == 2)\n\tmodule_connection();\n    while ((c = (*i_getc)(f)) != EOF)\n      (*o_putc)(c);\n    (*o_putc)(EOF);\n    return 1;\n}\n#endif\n\nvoid module_connection(void)\n{\n    oconv = output_conv; \n    o_putc = std_putc;\n\n    /* replace continucation module, from output side */\n\n    /* output redicrection */\n#ifdef CHECK_OPTION\n    if (noout_f || guess_f){\n        o_putc = no_putc;\n    }\n#endif\n    if (mimeout_f) {\n\to_mputc = o_putc;\n\to_putc = mime_putc;\n\tif (mimeout_f == TRUE) {\n\t    o_base64conv = oconv; oconv = base64_conv;\n\t}\n\t/* base64_count = 0; */\n    }\n\n    if (crmode_f) {\n\to_crconv = oconv; oconv = cr_conv;\n    }\n    if (rot_f) {\n\to_rot_conv = oconv; oconv = rot_conv;\n    }\n    if (iso2022jp_f) {\n\to_iso2022jp_check_conv = oconv; oconv = iso2022jp_check_conv;\n    }\n    if (hira_f) {\n\to_hira_conv = oconv; oconv = hira_conv;\n    }\n    if (fold_f) {\n\to_fconv = oconv; oconv = fold_conv;\n\tf_line = 0;\n    }\n    if (alpha_f || x0201_f) {\n\to_zconv = oconv; oconv = z_conv;\n    }\n\n    i_getc = std_getc;\n    i_ungetc = std_ungetc;\n    /* input redicrection */\n#ifdef INPUT_OPTION\n    if (cap_f){\n        i_cgetc = i_getc; i_getc = cap_getc;\n        i_cungetc = i_ungetc; i_ungetc= cap_ungetc;\n    }\n    if (url_f){\n        i_ugetc = i_getc; i_getc = url_getc;\n        i_uungetc = i_ungetc; i_ungetc= url_ungetc;\n    }\n#endif\n#ifdef NUMCHAR_OPTION\n    if (numchar_f){\n        i_ngetc = i_getc; i_getc = numchar_getc;\n        i_nungetc = i_ungetc; i_ungetc= numchar_ungetc;\n    }\n#endif\n#ifdef UNICODE_NORMALIZATION\n    if (nfc_f && input_f == UTF8_INPUT){\n        i_nfc_getc = i_getc; i_getc = nfc_getc;\n        i_nfc_ungetc = i_ungetc; i_ungetc= nfc_ungetc;\n    }\n#endif\n    if (mime_f && mimebuf_f==FIXED_MIME) {\n\ti_mgetc = i_getc; i_getc = mime_getc;\n\ti_mungetc = i_ungetc; i_ungetc = mime_ungetc;\n    }\n    if (broken_f & 1) {\n\ti_bgetc = i_getc; i_getc = broken_getc;\n\ti_bungetc = i_ungetc; i_ungetc = broken_ungetc;\n    }\n    if (input_f == JIS_INPUT || input_f == EUC_INPUT || input_f == LATIN1_INPUT) {\n        set_iconv(-TRUE, e_iconv);\n    } else if (input_f == SJIS_INPUT) {\n        set_iconv(-TRUE, s_iconv);\n#ifdef UTF8_INPUT_ENABLE\n    } else if (input_f == UTF8_INPUT) {\n        set_iconv(-TRUE, w_iconv);\n    } else if (input_f == UTF16_INPUT) {\n        set_iconv(-TRUE, w_iconv16);\n    } else if (input_f == UTF32_INPUT) {\n        set_iconv(-TRUE, w_iconv32);\n#endif\n    } else {\n        set_iconv(FALSE, e_iconv);\n    }\n\n    {\n        struct input_code *p = input_code_list;\n        while (p->name){\n            status_reinit(p++);\n        }\n    }\n}\n\n/*\n * Check and Ignore BOM\n */\nvoid check_bom(FILE *f)\n{\n    int c2;\n    switch(c2 = (*i_getc)(f)){\n    case 0x00:\n\tif((c2 = (*i_getc)(f)) == 0x00){\n\t    if((c2 = (*i_getc)(f)) == 0xFE){\n\t\tif((c2 = (*i_getc)(f)) == 0xFF){\n\t\t    if(!input_f){\n\t\t\tset_iconv(TRUE, w_iconv32);\n\t\t    }\n\t\t    if (iconv == w_iconv32) {\n\t\t\tinput_endian = ENDIAN_BIG;\n\t\t\treturn;\n\t\t    }\n\t\t    (*i_ungetc)(0xFF,f);\n\t\t}else (*i_ungetc)(c2,f);\n\t\t(*i_ungetc)(0xFE,f);\n\t    }else if(c2 == 0xFF){\n\t\tif((c2 = (*i_getc)(f)) == 0xFE){\n\t\t    if(!input_f){\n\t\t\tset_iconv(TRUE, w_iconv32);\n\t\t    }\n\t\t    if (iconv == w_iconv32) {\n\t\t\tinput_endian = ENDIAN_2143;\n\t\t\treturn;\n\t\t    }\n\t\t    (*i_ungetc)(0xFF,f);\n\t\t}else (*i_ungetc)(c2,f);\n\t\t(*i_ungetc)(0xFF,f);\n\t    }else (*i_ungetc)(c2,f);\n\t    (*i_ungetc)(0x00,f);\n\t}else (*i_ungetc)(c2,f);\n\t(*i_ungetc)(0x00,f);\n\tbreak;\n    case 0xEF:\n\tif((c2 = (*i_getc)(f)) == 0xBB){\n\t    if((c2 = (*i_getc)(f)) == 0xBF){\n\t\tif(!input_f){\n\t\t    set_iconv(TRUE, w_iconv);\n\t\t}\n\t\tif (iconv == w_iconv) {\n\t\t    return;\n\t\t}\n\t\t(*i_ungetc)(0xBF,f);\n\t    }else (*i_ungetc)(c2,f);\n\t    (*i_ungetc)(0xBB,f);\n\t}else (*i_ungetc)(c2,f);\n\t(*i_ungetc)(0xEF,f);\n\tbreak;\n    case 0xFE:\n\tif((c2 = (*i_getc)(f)) == 0xFF){\n\t    if((c2 = (*i_getc)(f)) == 0x00){\n\t\tif((c2 = (*i_getc)(f)) == 0x00){\n\t\t    if(!input_f){\n\t\t\tset_iconv(TRUE, w_iconv32);\n\t\t    }\n\t\t    if (iconv == w_iconv32) {\n\t\t\tinput_endian = ENDIAN_3412;\n\t\t\treturn;\n\t\t    }\n\t\t    (*i_ungetc)(0x00,f);\n\t\t}else (*i_ungetc)(c2,f);\n\t\t(*i_ungetc)(0x00,f);\n\t    }else (*i_ungetc)(c2,f);\n\t    if(!input_f){\n\t\tset_iconv(TRUE, w_iconv16);\n\t    }\n\t    if (iconv == w_iconv16) {\n\t\tinput_endian = ENDIAN_BIG;\n\t\treturn;\n\t    }\n\t    (*i_ungetc)(0xFF,f);\n\t}else (*i_ungetc)(c2,f);\n\t(*i_ungetc)(0xFE,f);\n\tbreak;\n    case 0xFF:\n\tif((c2 = (*i_getc)(f)) == 0xFE){\n\t    if((c2 = (*i_getc)(f)) == 0x00){\n\t\tif((c2 = (*i_getc)(f)) == 0x00){\n\t\t    if(!input_f){\n\t\t\tset_iconv(TRUE, w_iconv32);\n\t\t    }\n\t\t    if (iconv == w_iconv32) {\n\t\t\tinput_endian = ENDIAN_LITTLE;\n\t\t\treturn;\n\t\t    }\n\t\t    (*i_ungetc)(0x00,f);\n\t\t}else (*i_ungetc)(c2,f);\n\t\t(*i_ungetc)(0x00,f);\n\t    }else (*i_ungetc)(c2,f);\n\t    if(!input_f){\n\t\tset_iconv(TRUE, w_iconv16);\n\t    }\n\t    if (iconv == w_iconv16) {\n\t\tinput_endian = ENDIAN_LITTLE;\n\t\treturn;\n\t    }\n\t    (*i_ungetc)(0xFE,f);\n\t}else (*i_ungetc)(c2,f);\n\t(*i_ungetc)(0xFF,f);\n\tbreak;\n    default:\n\t(*i_ungetc)(c2,f);\n\tbreak;\n    }\n}\n\n/*\n   Conversion main loop. Code detection only. \n */\n\nnkf_char kanji_convert(FILE *f)\n{\n    nkf_char    c3, c2=0, c1, c0=0;\n    int is_8bit = FALSE;\n\n    if(input_f == SJIS_INPUT || input_f == EUC_INPUT\n#ifdef UTF8_INPUT_ENABLE\n       || input_f == UTF8_INPUT || input_f == UTF16_INPUT\n#endif\n      ){\n\tis_8bit = TRUE;\n    }\n\n    input_mode = ASCII;\n    output_mode = ASCII;\n    shift_mode = FALSE;\n\n#define NEXT continue      /* no output, get next */\n#define SEND ;             /* output c1 and c2, get next */\n#define LAST break         /* end of loop, go closing  */\n\n    module_connection();\n    check_bom(f);\n\n    while ((c1 = (*i_getc)(f)) != EOF) {\n#ifdef INPUT_CODE_FIX\n\tif (!input_f)\n#endif\n\t    code_status(c1);\n        if (c2) {\n            /* second byte */\n            if (c2 > ((input_f == JIS_INPUT && ms_ucs_map_f) ? 0x92 : DEL)) {\n                /* in case of 8th bit is on */\n                if (!estab_f&&!mime_decode_mode) {\n                    /* in case of not established yet */\n                    /* It is still ambiguious */\n                    if (h_conv(f, c2, c1)==EOF) \n                        LAST;\n                    else \n                        c2 = 0;\n                    NEXT;\n                } else {\n\t\t    /* in case of already established */\n\t\t    if (c1 < AT) {\n\t\t\t/* ignore bogus code and not CP5022x UCD */\n\t\t\tc2 = 0;\n\t\t\tNEXT;\n\t\t    } else {\n\t\t\tSEND;\n\t\t    }\n\t\t}\n            } else\n                /* second byte, 7 bit code */\n                /* it might be kanji shitfted */\n                if ((c1 == DEL) || (c1 <= SPACE)) {\n                    /* ignore bogus first code */\n                    c2 = 0;\n                    NEXT;\n                } else\n                    SEND;\n        } else {\n            /* first byte */\n#ifdef UTF8_INPUT_ENABLE\n\t    if (iconv == w_iconv16) {\n\t\tif (input_endian == ENDIAN_BIG) {\n\t\t    c2 = c1;\n\t\t    if ((c1 = (*i_getc)(f)) != EOF) {\n\t\t\tif (0xD8 <= c2 && c2 <= 0xDB) {\n\t\t\t    if ((c0 = (*i_getc)(f)) != EOF) {\n\t\t\t\tc0 <<= 8;\n\t\t\t\tif ((c3 = (*i_getc)(f)) != EOF) {\n\t\t\t\t    c0 |= c3;\n\t\t\t\t} else c2 = EOF;\n\t\t\t    } else c2 = EOF;\n\t\t\t}\n\t\t    } else c2 = EOF;\n\t\t} else {\n\t\t    if ((c2 = (*i_getc)(f)) != EOF) {\n\t\t\tif (0xD8 <= c2 && c2 <= 0xDB) {\n\t\t\t    if ((c3 = (*i_getc)(f)) != EOF) {\n\t\t\t\tif ((c0 = (*i_getc)(f)) != EOF) {\n\t\t\t\t    c0 <<= 8;\n\t\t\t\t    c0 |= c3;\n\t\t\t\t} else c2 = EOF;\n\t\t\t    } else c2 = EOF;\n\t\t\t}\n\t\t    } else c2 = EOF;\n\t\t}\n\t\tSEND;\n            } else if(iconv == w_iconv32){\n\t\tint c3 = c1;\n\t\tif((c2 = (*i_getc)(f)) != EOF &&\n\t\t   (c1 = (*i_getc)(f)) != EOF &&\n\t\t   (c0 = (*i_getc)(f)) != EOF){\n\t\t    switch(input_endian){\n\t\t    case ENDIAN_BIG:\n\t\t\tc1 = (c2&0xFF)<<16 | (c1&0xFF)<<8 | (c0&0xFF);\n\t\t\tbreak;\n\t\t    case ENDIAN_LITTLE:\n\t\t\tc1 = (c3&0xFF) | (c2&0xFF)<<8 | (c1&0xFF)<<16;\n\t\t\tbreak;\n\t\t    case ENDIAN_2143:\n\t\t\tc1 = (c3&0xFF)<<16 | (c1&0xFF) | (c0&0xFF)<<8;\n\t\t\tbreak;\n\t\t    case ENDIAN_3412:\n\t\t\tc1 = (c3&0xFF)<<8 | (c2&0xFF) | (c0&0xFF)<<16;\n\t\t\tbreak;\n\t\t    }\n\t\t    c2 = 0;\n\t\t}else{\n\t\t    c2 = EOF;\n\t\t}\n\t\tSEND;\n            } else\n#endif\n#ifdef NUMCHAR_OPTION\n            if (is_unicode_capsule(c1)){\n                SEND;\n\t    } else\n#endif\n\t    if (c1 > ((input_f == JIS_INPUT && ms_ucs_map_f) ? 0x92 : DEL)) {\n                /* 8 bit code */\n                if (!estab_f && !iso8859_f) {\n                    /* not established yet */\n                    c2 = c1;\n                    NEXT;\n                } else { /* estab_f==TRUE */\n                    if (iso8859_f) {\n                        c2 = ISO8859_1;\n                        c1 &= 0x7f;\n                        SEND;\n                    } else if (SSP<=c1 && c1<0xe0 && iconv == s_iconv) {\n                        /* SJIS X0201 Case... */\n                        if(iso2022jp_f && x0201_f==NO_X0201) {\n                            (*oconv)(GETA1, GETA2);\n                            NEXT;\n                        } else {\n\t\t\t    c2 = X0201;\n\t\t\t    c1 &= 0x7f;\n\t\t\t    SEND;\n\t\t\t}\n                    } else if (c1==SSO && iconv != s_iconv) {\n                        /* EUC X0201 Case */\n                        c1 = (*i_getc)(f);  /* skip SSO */\n                        code_status(c1);\n                        if (SSP<=c1 && c1<0xe0) {\n\t\t\t    if(iso2022jp_f &&  x0201_f==NO_X0201) {\n\t\t\t\t(*oconv)(GETA1, GETA2);\n\t\t\t\tNEXT;\n\t\t\t    } else {\n\t\t\t\tc2 = X0201;\n\t\t\t\tc1 &= 0x7f;\n\t\t\t\tSEND;\n\t\t\t    }\n                        } else  { /* bogus code, skip SSO and one byte */\n                            NEXT;\n                        }\n                    } else {\n                       /* already established */\n                       c2 = c1;\n                       NEXT;\n                    }\n                }\n            } else if ((c1 > SPACE) && (c1 != DEL)) {\n                /* in case of Roman characters */\n                if (shift_mode) { \n                    /* output 1 shifted byte */\n                    if (iso8859_f) {\n                        c2 = ISO8859_1;\n                        SEND;\n                    } else if (SPACE<=c1 && c1<(0xe0&0x7f) ){\n                      /* output 1 shifted byte */\n\t\t\tif(iso2022jp_f && x0201_f==NO_X0201) {\n\t\t\t    (*oconv)(GETA1, GETA2);\n\t\t\t    NEXT;\n\t\t\t} else {\n\t\t\t    c2 = X0201;\n\t\t\t    SEND;\n\t\t\t}\n                    } else {\n                        /* look like bogus code */\n                        NEXT;\n                    }\n                } else if (input_mode == X0208 || input_mode == X0212 ||\n\t\t\t   input_mode == X0213_1 || input_mode == X0213_2) {\n                    /* in case of Kanji shifted */\n                    c2 = c1;\n                    NEXT;\n                } else if (c1 == '=' && mime_f && !mime_decode_mode ) {\n                    /* Check MIME code */\n                    if ((c1 = (*i_getc)(f)) == EOF) {\n                        (*oconv)(0, '=');\n                        LAST;\n                    } else if (c1 == '?') {\n                        /* =? is mime conversion start sequence */\n\t\t\tif(mime_f == STRICT_MIME) {\n\t\t\t    /* check in real detail */\n\t\t\t    if (mime_begin_strict(f) == EOF) \n\t\t\t\tLAST;\n\t\t\t    else\n\t\t\t\tNEXT;\n\t\t\t} else if (mime_begin(f) == EOF) \n                            LAST;\n                        else\n                            NEXT;\n                    } else {\n                        (*oconv)(0, '=');\n                        (*i_ungetc)(c1,f);\n                        NEXT;\n                    }\n                } else {\n                    /* normal ASCII code */ \n                    SEND;\n                }\n            } else if (c1 == SI && (!is_8bit || mime_decode_mode)) {\n                shift_mode = FALSE; \n                NEXT;\n            } else if (c1 == SO && (!is_8bit || mime_decode_mode)) {\n                shift_mode = TRUE; \n                NEXT;\n            } else if (c1 == ESC && (!is_8bit || mime_decode_mode)) {\n                if ((c1 = (*i_getc)(f)) == EOF) {\n                    /*  (*oconv)(0, ESC); don't send bogus code */\n                    LAST;\n                } else if (c1 == '$') {\n                    if ((c1 = (*i_getc)(f)) == EOF) {\n                        /*\n                        (*oconv)(0, ESC); don't send bogus code \n                        (*oconv)(0, '$'); */\n                        LAST;\n                    } else if (c1 == '@'|| c1 == 'B') {\n                        /* This is kanji introduction */\n                        input_mode = X0208;\n                        shift_mode = FALSE;\n                        set_input_codename(\"ISO-2022-JP\");\n#ifdef CHECK_OPTION\n                        debug(input_codename);\n#endif\n                        NEXT;\n                    } else if (c1 == '(') {\n                        if ((c1 = (*i_getc)(f)) == EOF) {\n                            /* don't send bogus code \n                            (*oconv)(0, ESC);\n                            (*oconv)(0, '$');\n                            (*oconv)(0, '(');\n                                */\n                            LAST;\n                        } else if (c1 == '@'|| c1 == 'B') {\n                            /* This is kanji introduction */\n                            input_mode = X0208;\n                            shift_mode = FALSE;\n                            NEXT;\n#ifdef X0212_ENABLE\n                        } else if (c1 == 'D'){\n                            input_mode = X0212;\n                            shift_mode = FALSE;\n                            NEXT;\n#endif /* X0212_ENABLE */\n                        } else if (c1 == (X0213_1&0x7F)){\n                            input_mode = X0213_1;\n                            shift_mode = FALSE;\n                            NEXT;\n                        } else if (c1 == (X0213_2&0x7F)){\n                            input_mode = X0213_2;\n                            shift_mode = FALSE;\n                            NEXT;\n                        } else {\n                            /* could be some special code */\n                            (*oconv)(0, ESC);\n                            (*oconv)(0, '$');\n                            (*oconv)(0, '(');\n                            (*oconv)(0, c1);\n                            NEXT;\n                        }\n                    } else if (broken_f&0x2) {\n                        /* accept any ESC-(-x as broken code ... */\n                        input_mode = X0208;\n                        shift_mode = FALSE;\n                        NEXT;\n                    } else {\n                        (*oconv)(0, ESC);\n                        (*oconv)(0, '$');\n                        (*oconv)(0, c1);\n                        NEXT;\n                    }\n                } else if (c1 == '(') {\n                    if ((c1 = (*i_getc)(f)) == EOF) {\n                        /* don't send bogus code \n                        (*oconv)(0, ESC);\n                        (*oconv)(0, '('); */\n                        LAST;\n                    } else {\n                        if (c1 == 'I') {\n                            /* This is X0201 kana introduction */\n                            input_mode = X0201; shift_mode = X0201;\n                            NEXT;\n                        } else if (c1 == 'B' || c1 == 'J' || c1 == 'H') {\n                            /* This is X0208 kanji introduction */\n                            input_mode = ASCII; shift_mode = FALSE;\n                            NEXT;\n                        } else if (broken_f&0x2) {\n                            input_mode = ASCII; shift_mode = FALSE;\n                            NEXT;\n                        } else {\n                            (*oconv)(0, ESC);\n                            (*oconv)(0, '(');\n                            /* maintain various input_mode here */\n                            SEND;\n                        }\n                    }\n               } else if ( c1 == 'N' || c1 == 'n' ){\n                   /* SS2 */\n                   c3 = (*i_getc)(f);  /* skip SS2 */\n                   if ( (SPACE<=c3 && c3 < 0x60) || (0xa0<=c3 && c3 < 0xe0)){\n                       c1 = c3;\n                       c2 = X0201;\n                       SEND;\n                   }else{\n                       (*i_ungetc)(c3, f);\n                       /* lonely ESC  */\n                       (*oconv)(0, ESC);\n                       SEND;\n                   }\n                } else {\n                    /* lonely ESC  */\n                    (*oconv)(0, ESC);\n                    SEND;\n                }\n\t    } else if (c1 == ESC && iconv == s_iconv) {\n\t\t/* ESC in Shift_JIS */\n\t\tif ((c1 = (*i_getc)(f)) == EOF) {\n\t\t    /*  (*oconv)(0, ESC); don't send bogus code */\n\t\t    LAST;\n\t\t} else if (c1 == '$') {\n\t\t    /* J-PHONE emoji */\n\t\t    if ((c1 = (*i_getc)(f)) == EOF) {\n\t\t\t/*\n\t\t\t   (*oconv)(0, ESC); don't send bogus code \n\t\t\t   (*oconv)(0, '$'); */\n\t\t\tLAST;\n\t\t    } else {\n\t\t\tif (('E' <= c1 && c1 <= 'G') ||\n\t\t\t    ('O' <= c1 && c1 <= 'Q')) {\n\t\t\t    /*\n\t\t\t       NUM : 0 1 2 3 4 5\n\t\t\t       BYTE: G E F O P Q\n\t\t\t       C%7 : 1 6 0 2 3 4\n\t\t\t       C%7 : 0 1 2 3 4 5 6\n\t\t\t       NUM : 2 0 3 4 5 X 1\n\t\t\t     */\n\t\t\t    static const int jphone_emoji_first_table[7] = {2, 0, 3, 4, 5, 0, 1};\n\t\t\t    c0 = (jphone_emoji_first_table[c1 % 7] << 8) - SPACE + 0xE000 + CLASS_UNICODE;\n\t\t\t    while ((c1 = (*i_getc)(f)) != EOF) {\n\t\t\t\tif (SPACE <= c1 && c1 <= 'z') {\n\t\t\t\t    (*oconv)(0, c1 + c0);\n\t\t\t\t} else break; /* c1 == SO */\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t    if (c1 == EOF) LAST;\n\t\t    NEXT;\n\t\t} else {\n\t\t    /* lonely ESC  */\n\t\t    (*oconv)(0, ESC);\n\t\t    SEND;\n\t\t}\n            } else if ((c1 == NL || c1 == CR) && broken_f&4) {\n                input_mode = ASCII; set_iconv(FALSE, 0);\n                SEND;\n\t    } else if (c1 == NL && mime_decode_f && !mime_decode_mode ) {\n\t\tif ((c1=(*i_getc)(f))!=EOF && c1 == SPACE) {\n\t\t    i_ungetc(SPACE,f);\n\t\t    continue;\n\t\t} else {\n\t\t    i_ungetc(c1,f);\n\t\t}\n\t\tc1 = NL;\n\t\tSEND;\n\t    } else if (c1 == CR && mime_decode_f && !mime_decode_mode ) {\n\t\tif ((c1=(*i_getc)(f))!=EOF) {\n\t\t    if (c1==SPACE) {\n\t\t\ti_ungetc(SPACE,f);\n\t\t\tcontinue;\n\t\t    } else if (c1 == NL && (c1=(*i_getc)(f))!=EOF && c1 == SPACE) {\n\t\t\ti_ungetc(SPACE,f);\n\t\t\tcontinue;\n\t\t    } else {\n\t\t\ti_ungetc(c1,f);\n\t\t    }\n\t\t    i_ungetc(NL,f);\n\t\t} else {\n\t\t    i_ungetc(c1,f);\n\t\t}\n\t\tc1 = CR;\n\t\tSEND;\n\t    } else if (c1 == DEL && input_mode == X0208 ) {\n\t\t/* CP5022x */\n\t\tc2 = c1;\n\t\tNEXT;\n\t    } else \n                SEND;\n        }\n        /* send: */\n\tswitch(input_mode){\n\tcase ASCII:\n\t    switch ((*iconv)(c2, c1, c0)) {  /* can be EUC / SJIS / UTF-8 / UTF-16 */\n\t    case -2:\n\t\t/* 4 bytes UTF-8 */\n\t\tif ((c0 = (*i_getc)(f)) != EOF) {\n\t\t    code_status(c0);\n\t\t    c0 <<= 8;\n\t\t    if ((c3 = (*i_getc)(f)) != EOF) {\n\t\t\tcode_status(c3);\n\t\t\t(*iconv)(c2, c1, c0|c3);\n\t\t    }\n\t\t}\n\t\tbreak;\n\t    case -1:\n\t\t/* 3 bytes EUC or UTF-8 */\n\t\tif ((c0 = (*i_getc)(f)) != EOF) {\n\t\t    code_status(c0);\n\t\t    (*iconv)(c2, c1, c0);\n\t\t}\n\t\tbreak;\n\t    }\n\t    break;\n\tcase X0208:\n\tcase X0213_1:\n\t    if (ms_ucs_map_f &&\n\t\t0x7F <= c2 && c2 <= 0x92 &&\n\t\t0x21 <= c1 && c1 <= 0x7E) {\n\t\t/* CP932 UDC */\n\t\tif(c1 == 0x7F) return 0;\n\t\tc1 = (c2 - 0x7F) * 94 + c1 - 0x21 + 0xE000 + CLASS_UNICODE;\n\t\tc2 = 0;\n\t    }\n\t    (*oconv)(c2, c1); /* this is JIS, not SJIS/EUC case */\n\t    break;\n#ifdef X0212_ENABLE\n\tcase X0212:\n\t    (*oconv)(PREFIX_EUCG3 | c2, c1);\n\t    break;\n#endif /* X0212_ENABLE */\n\tcase X0213_2:\n\t    (*oconv)(PREFIX_EUCG3 | c2, c1);\n\t    break;\n\tdefault:\n\t    (*oconv)(input_mode, c1);  /* other special case */\n\t}\n\n        c2 = 0;\n        c0 = 0;\n        continue;\n        /* goto next_word */\n    }\n\n    /* epilogue */\n    (*iconv)(EOF, 0, 0);\n    if (!is_inputcode_set)\n    {\n\tif (is_8bit) {\n\t    struct input_code *p = input_code_list;\n\t    struct input_code *result = p;\n\t    while (p->name){\n\t\tif (p->score < result->score) result = p;\n\t\t++p;\n\t    }\n\t    set_input_codename(result->name);\n\t}\n    }\n    return 1;\n}\n\nnkf_char\nh_conv(FILE *f, nkf_char c2, nkf_char c1)\n{\n    nkf_char ret, c3, c0;\n    int hold_index;\n\n\n    /** it must NOT be in the kanji shifte sequence      */\n    /** it must NOT be written in JIS7                   */\n    /** and it must be after 2 byte 8bit code            */\n\n    hold_count = 0;\n    push_hold_buf(c2);\n    push_hold_buf(c1);\n\n    while ((c1 = (*i_getc)(f)) != EOF) {\n        if (c1 == ESC){\n\t    (*i_ungetc)(c1,f);\n            break;\n        }\n        code_status(c1);\n        if (push_hold_buf(c1) == EOF || estab_f){\n            break;\n        }\n    }\n\n    if (!estab_f){\n        struct input_code *p = input_code_list;\n        struct input_code *result = p;\n        if (c1 == EOF){\n            code_status(c1);\n        }\n        while (p->name){\n            if (p->status_func && p->score < result->score){\n                result = p;\n            }\n            ++p;\n        }\n        set_iconv(TRUE, result->iconv_func);\n    }\n\n\n    /** now,\n     ** 1) EOF is detected, or\n     ** 2) Code is established, or\n     ** 3) Buffer is FULL (but last word is pushed)\n     **\n     ** in 1) and 3) cases, we continue to use\n     ** Kanji codes by oconv and leave estab_f unchanged.\n     **/\n\n    ret = c1;\n    hold_index = 0;\n    while (hold_index < hold_count){\n        c2 = hold_buf[hold_index++];\n        if (c2 <= DEL\n#ifdef NUMCHAR_OPTION\n            || is_unicode_capsule(c2)\n#endif\n            ){\n            (*iconv)(0, c2, 0);\n            continue;\n        }else if (iconv == s_iconv && 0xa1 <= c2 && c2 <= 0xdf){\n            (*iconv)(X0201, c2, 0);\n            continue;\n        }\n        if (hold_index < hold_count){\n            c1 = hold_buf[hold_index++];\n        }else{\n            c1 = (*i_getc)(f);\n            if (c1 == EOF){\n                c3 = EOF;\n                break;\n            }\n            code_status(c1);\n        }\n        c0 = 0;\n        switch ((*iconv)(c2, c1, 0)) {  /* can be EUC/SJIS/UTF-8 */\n\tcase -2:\n\t    /* 4 bytes UTF-8 */\n            if (hold_index < hold_count){\n                c0 = hold_buf[hold_index++];\n            } else if ((c0 = (*i_getc)(f)) == EOF) {\n\t\tret = EOF;\n\t\tbreak;\n\t    } else {\n                code_status(c0);\n\t\tc0 <<= 8;\n\t\tif (hold_index < hold_count){\n\t\t    c3 = hold_buf[hold_index++];\n\t\t} else if ((c3 = (*i_getc)(f)) == EOF) {\n\t\t    c0 = ret = EOF;\n\t\t    break;\n\t\t} else {\n\t\t    code_status(c3);\n\t\t    (*iconv)(c2, c1, c0|c3);\n\t\t}\n            }\n\t    break;\n\tcase -1:\n\t    /* 3 bytes EUC or UTF-8 */\n            if (hold_index < hold_count){\n                c0 = hold_buf[hold_index++];\n            } else if ((c0 = (*i_getc)(f)) == EOF) {\n\t\tret = EOF;\n\t\tbreak;\n\t    } else {\n                code_status(c0);\n            }\n            (*iconv)(c2, c1, c0);\n            break;\n\t}\n\tif (c0 == EOF) break;\n    }\n    return ret;\n}\n\nnkf_char push_hold_buf(nkf_char c2)\n{\n    if (hold_count >= HOLD_SIZE*2)\n        return (EOF);\n    hold_buf[hold_count++] = (unsigned char)c2;\n    return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);\n}\n\nnkf_char s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)\n{\n#if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE)\n    nkf_char val;\n#endif\n    static const nkf_char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} };\n#ifdef SHIFTJIS_CP932\n    if (!cp932inv_f && is_ibmext_in_sjis(c2)){\n#if 0\n        extern const unsigned short shiftjis_cp932[3][189];\n#endif\n        val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];\n        if (val){\n            c2 = val >> 8;\n            c1 = val & 0xff;\n        }\n    }\n    if (cp932inv_f\n        && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){\n#if 0\n        extern const unsigned short cp932inv[2][189];\n#endif\n        nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];\n        if (c){\n            c2 = c >> 8;\n            c1 = c & 0xff;\n        }\n    }\n#endif /* SHIFTJIS_CP932 */\n#ifdef X0212_ENABLE\n    if (!x0213_f && is_ibmext_in_sjis(c2)){\n#if 0\n        extern const unsigned short shiftjis_x0212[3][189];\n#endif\n        val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40];\n        if (val){\n            if (val > 0x7FFF){\n                c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f);\n                c1 = val & 0xff;\n            }else{\n                c2 = val >> 8;\n                c1 = val & 0xff;\n            }\n            if (p2) *p2 = c2;\n            if (p1) *p1 = c1;\n            return 0;\n        }\n    }\n#endif\n    if(c2 >= 0x80){\n\tif(x0213_f && c2 >= 0xF0){\n\t    if(c2 <= 0xF3 || (c2 == 0xF4 && c1 < 0x9F)){ /* k=1, 3<=k<=5, k=8, 12<=k<=15 */\n\t\tc2 = PREFIX_EUCG3 | 0x20 | shift_jisx0213_s1a3_table[c2 - 0xF0][0x9E < c1];\n\t    }else{ /* 78<=k<=94 */\n\t\tc2 = PREFIX_EUCG3 | (c2 * 2 - 0x17B);\n\t\tif (0x9E < c1) c2++;\n\t    }\n\t}else{\n\t    c2 = c2 + c2 - ((c2 <= 0x9F) ? SJ0162 : SJ6394);\n\t    if (0x9E < c1) c2++;\n\t}\n\tif (c1 < 0x9F)\n\t    c1 = c1 - ((c1 > DEL) ? SPACE : 0x1F);\n\telse {\n\t    c1 = c1 - 0x7E;\n\t}\n    }\n\n#ifdef X0212_ENABLE\n    c2 = x0212_unshift(c2);\n#endif\n    if (p2) *p2 = c2;\n    if (p1) *p1 = c1;\n    return 0;\n}\n\nnkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    if (c2 == X0201) {\n\tc1 &= 0x7f;\n    } else if ((c2 == EOF) || (c2 == 0) || c2 < SPACE) {\n        /* NOP */\n    } else if (!x0213_f && 0xF0 <= c2 && c2 <= 0xF9 && 0x40 <= c1 && c1 <= 0xFC) {\n\t/* CP932 UDC */\n\tif(c1 == 0x7F) return 0;\n\tc1 = (c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000 + CLASS_UNICODE;\n\tc2 = 0;\n    } else {\n        nkf_char ret = s2e_conv(c2, c1, &c2, &c1);\n        if (ret) return ret;\n    }\n    (*oconv)(c2, c1);\n    return 0;\n}\n\nnkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    if (c2 == X0201) {\n\tc1 &= 0x7f;\n#ifdef X0212_ENABLE\n    }else if (c2 == 0x8f){\n        if (c0 == 0){\n            return -1;\n        }\n\tif (!cp51932_f && !x0213_f && 0xF5 <= c1 && c1 <= 0xFE && 0xA1 <= c0 && c0 <= 0xFE) {\n\t    /* encoding is eucJP-ms, so invert to Unicode Private User Area */\n\t    c1 = (c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC + CLASS_UNICODE;\n\t    c2 = 0;\n\t} else {\n\t    c2 = (c2 << 8) | (c1 & 0x7f);\n\t    c1 = c0 & 0x7f;\n#ifdef SHIFTJIS_CP932\n\t    if (cp51932_f){\n\t\tnkf_char s2, s1;\n\t\tif (e2s_conv(c2, c1, &s2, &s1) == 0){\n\t\t    s2e_conv(s2, s1, &c2, &c1);\n\t\t    if (c2 < 0x100){\n\t\t\tc1 &= 0x7f;\n\t\t\tc2 &= 0x7f;\n\t\t    }\n\t\t}\n\t    }\n#endif /* SHIFTJIS_CP932 */\n        }\n#endif /* X0212_ENABLE */\n    } else if (c2 == SSO){\n        c2 = X0201;\n        c1 &= 0x7f;\n    } else if ((c2 == EOF) || (c2 == 0) || c2 < SPACE) {\n        /* NOP */\n    } else {\n\tif (!cp51932_f && ms_ucs_map_f && 0xF5 <= c2 && c2 <= 0xFE && 0xA1 <= c1 && c1 <= 0xFE) {\n\t    /* encoding is eucJP-ms, so invert to Unicode Private User Area */\n\t    c1 = (c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000 + CLASS_UNICODE;\n\t    c2 = 0;\n\t} else {\n\t    c1 &= 0x7f;\n\t    c2 &= 0x7f;\n#ifdef SHIFTJIS_CP932\n\t    if (cp51932_f && 0x79 <= c2 && c2 <= 0x7c){\n\t\tnkf_char s2, s1;\n\t\tif (e2s_conv(c2, c1, &s2, &s1) == 0){\n\t\t    s2e_conv(s2, s1, &c2, &c1);\n\t\t    if (c2 < 0x100){\n\t\t\tc1 &= 0x7f;\n\t\t\tc2 &= 0x7f;\n\t\t    }\n\t\t}\n\t    }\n#endif /* SHIFTJIS_CP932 */\n        }\n    }\n    (*oconv)(c2, c1);\n    return 0;\n}\n\n#ifdef UTF8_INPUT_ENABLE\nnkf_char w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)\n{\n    nkf_char ret = 0;\n\n    if (!c1){\n        *p2 = 0;\n        *p1 = c2;\n    }else if (0xc0 <= c2 && c2 <= 0xef) {\n\tret =  unicode_to_jis_common(c2, c1, c0, p2, p1);\n#ifdef NUMCHAR_OPTION\n        if (ret > 0){\n            if (p2) *p2 = 0;\n            if (p1) *p1 = CLASS_UNICODE | ww16_conv(c2, c1, c0);\n            ret = 0;\n        }\n#endif\n    }\n    return ret;\n}\n\nnkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    nkf_char ret = 0;\n    static const int w_iconv_utf8_1st_byte[] =\n    { /* 0xC0 - 0xFF */\n\t20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33,\n\t40, 41, 41, 41, 42, 43, 43, 43, 50, 50, 50, 50, 60, 60, 70, 70};\n    \n    if (c2 < 0 || 0xff < c2) {\n    }else if (c2 == 0) { /* 0 : 1 byte*/\n\tc0 = 0;\n    } else if ((c2 & 0xc0) == 0x80) { /* 0x80-0xbf : trail byte */\n\treturn 0;\n    } else{\n    \tswitch (w_iconv_utf8_1st_byte[c2 - 0xC0]) {\n\tcase 21:\n\t    if (c1 < 0x80 || 0xBF < c1) return 0;\n\t    break;\n\tcase 30:\n\t    if (c0 == 0) return -1;\n\t    if (c1 < 0xA0 || 0xBF < c1 || (c0 & 0xc0) != 0x80)\n\t\treturn 0;\n\t    break;\n\tcase 31:\n\tcase 33:\n\t    if (c0 == 0) return -1;\n\t    if ((c1 & 0xc0) != 0x80 || (c0 & 0xc0) != 0x80)\n\t\treturn 0;\n\t    break;\n\tcase 32:\n\t    if (c0 == 0) return -1;\n\t    if (c1 < 0x80 || 0x9F < c1 || (c0 & 0xc0) != 0x80)\n\t\treturn 0;\n\t    break;\n\tcase 40:\n\t    if (c0 == 0) return -2;\n\t    if (c1 < 0x90 || 0xBF < c1 || (c0 & 0xc0c0) != 0x8080)\n\t\treturn 0;\n\t    break;\n\tcase 41:\n\t    if (c0 == 0) return -2;\n\t    if (c1 < 0x80 || 0xBF < c1 || (c0 & 0xc0c0) != 0x8080)\n\t\treturn 0;\n\t    break;\n\tcase 42:\n\t    if (c0 == 0) return -2;\n\t    if (c1 < 0x80 || 0x8F < c1 || (c0 & 0xc0c0) != 0x8080)\n\t\treturn 0;\n\t    break;\n\tdefault:\n\t    return 0;\n\t    break;\n\t}\n    }\n    if (c2 == 0 || c2 == EOF){\n    } else if ((c2 & 0xf8) == 0xf0) { /* 4 bytes */\n\tc1 = CLASS_UNICODE | ww16_conv(c2, c1, c0);\n\tc2 = 0;\n    } else {\n\tret = w2e_conv(c2, c1, c0, &c2, &c1);\n    }\n    if (ret == 0){\n        (*oconv)(c2, c1);\n    }\n    return ret;\n}\n#endif\n\n#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)\nvoid w16w_conv(nkf_char val, nkf_char *p2, nkf_char *p1, nkf_char *p0)\n{\n    val &= VALUE_MASK;\n    if (val < 0x80){\n        *p2 = val;\n        *p1 = 0;\n        *p0 = 0;\n    }else if (val < 0x800){\n\t*p2 = 0xc0 | (val >> 6);\n\t*p1 = 0x80 | (val & 0x3f);\n        *p0 = 0;\n    } else if (val <= NKF_INT32_C(0xFFFF)) {\n        *p2 = 0xe0 | (val >> 12);\n        *p1 = 0x80 | ((val >> 6) & 0x3f);\n        *p0 = 0x80 | (val        & 0x3f);\n    } else if (val <= NKF_INT32_C(0x10FFFF)) {\n        *p2 = 0xe0 |  (val >> 16);\n        *p1 = 0x80 | ((val >> 12) & 0x3f);\n        *p0 = 0x8080 | ((val << 2) & 0x3f00)| (val & 0x3f);\n    } else {\n        *p2 = 0;\n        *p1 = 0;\n        *p0 = 0;\n    }\n}\n#endif\n\n#ifdef UTF8_INPUT_ENABLE\nnkf_char ww16_conv(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    nkf_char val;\n    if (c2 >= 0xf8) {\n\tval = -1;\n    } else if (c2 >= 0xf0){\n\t/* c2: 1st, c1: 2nd, c0: 3rd/4th */\n\tval = (c2 & 0x0f) << 18;\n        val |= (c1 & 0x3f) << 12;\n        val |= (c0 & 0x3f00) >> 2;\n        val |= (c0 & 0x3f);\n    }else if (c2 >= 0xe0){\n        val = (c2 & 0x0f) << 12;\n        val |= (c1 & 0x3f) << 6;\n        val |= (c0 & 0x3f);\n    }else if (c2 >= 0xc0){\n        val = (c2 & 0x1f) << 6;\n        val |= (c1 & 0x3f);\n    }else{\n        val = c2;\n    }\n    return val;\n}\n\nnkf_char w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)\n{\n    nkf_char c2, c1, c0;\n    nkf_char ret = 0;\n    val &= VALUE_MASK;\n    if (val < 0x80){\n        *p2 = 0;\n        *p1 = val;\n    }else{\n\tw16w_conv(val, &c2, &c1, &c0);\n\tret =  unicode_to_jis_common(c2, c1, c0, p2, p1);\n#ifdef NUMCHAR_OPTION\n\tif (ret > 0){\n\t    *p2 = 0;\n\t    *p1 = CLASS_UNICODE | val;\n\t    ret = 0;\n\t}\n#endif\n    }\n    return ret;\n}\n#endif\n\n#ifdef UTF8_INPUT_ENABLE\nnkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    nkf_char ret = 0;\n    if ((c2==0 && c1 < 0x80) || c2==EOF) {\n\t(*oconv)(c2, c1);\n\treturn 0;\n    }else if (0xD8 <= c2 && c2 <= 0xDB) {\n\tif (c0 < NKF_INT32_C(0xDC00) || NKF_INT32_C(0xDFFF) < c0)\n\t    return -2;\n\tc1 =  CLASS_UNICODE | ((c2 << 18) + (c1 << 10) + c0 - NKF_INT32_C(0x35FDC00));\n\tc2 = 0;\n    }else if ((c2>>3) == 27) { /* unpaired surrogate */\n\t/*\n\t   return 2;\n\t*/\n\treturn 1;\n    }else ret = w16e_conv(((c2 & 0xff)<<8) + c1, &c2, &c1);\n    if (ret) return ret;\n    (*oconv)(c2, c1);\n    return 0;\n}\n\nnkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    int ret = 0;\n\n    if ((c2 == 0 && c1 < 0x80) || c2==EOF) {\n    } else if (is_unicode_bmp(c1)) {\n\tret = w16e_conv(c1, &c2, &c1);\n    } else {\n\tc2 = 0;\n\tc1 =  CLASS_UNICODE | c1;\n    }\n    if (ret) return ret;\n    (*oconv)(c2, c1);\n    return 0;\n}\n\nnkf_char unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)\n{\n#if 0\n    extern const unsigned short *const utf8_to_euc_2bytes[];\n    extern const unsigned short *const utf8_to_euc_2bytes_ms[];\n    extern const unsigned short *const utf8_to_euc_2bytes_932[];\n    extern const unsigned short *const *const utf8_to_euc_3bytes[];\n    extern const unsigned short *const *const utf8_to_euc_3bytes_ms[];\n    extern const unsigned short *const *const utf8_to_euc_3bytes_932[];\n#endif\n    const unsigned short *const *pp;\n    const unsigned short *const *const *ppp;\n    static const int no_best_fit_chars_table_C2[] =\n    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 2,\n\t0, 0, 1, 1, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1};\n    static const int no_best_fit_chars_table_C2_ms[] =\n    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0,\n\t0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0};\n    static const int no_best_fit_chars_table_932_C2[] =\n    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1,\n\t0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0};\n    static const int no_best_fit_chars_table_932_C3[] =\n    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1};\n    nkf_char ret = 0;\n\n    if(c2 < 0x80){\n\t*p2 = 0;\n\t*p1 = c2;\n    }else if(c2 < 0xe0){\n\tif(no_best_fit_chars_f){\n\t    if(ms_ucs_map_f == UCS_MAP_CP932){\n\t\tswitch(c2){\n\t\tcase 0xC2:\n\t\t    if(no_best_fit_chars_table_932_C2[c1&0x3F]) return 1;\n\t\t    break;\n\t\tcase 0xC3:\n\t\t    if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;\n\t\t    break;\n\t\t}\n\t    }else if(!cp932inv_f){\n\t\tswitch(c2){\n\t\tcase 0xC2:\n\t\t    if(no_best_fit_chars_table_C2[c1&0x3F]) return 1;\n\t\t    break;\n\t\tcase 0xC3:\n\t\t    if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;\n\t\t    break;\n\t\t}\n\t    }else if(ms_ucs_map_f == UCS_MAP_MS){\n\t\tif(c2 == 0xC2 && no_best_fit_chars_table_C2_ms[c1&0x3F]) return 1;\n\t    }\n\t}\n\tpp =\n\t    ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_2bytes_932 :\n\t    ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_2bytes_ms :\n\t    utf8_to_euc_2bytes;\n\tret =  w_iconv_common(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1);\n    }else if(c0 < 0xF0){\n\tif(no_best_fit_chars_f){\n\t    if(ms_ucs_map_f == UCS_MAP_CP932){\n\t\tif(c2 == 0xE3 && c1 == 0x82 && c0 == 0x94) return 1;\n\t    }else if(ms_ucs_map_f == UCS_MAP_MS){\n\t\tswitch(c2){\n\t\tcase 0xE2:\n\t\t    switch(c1){\n\t\t    case 0x80:\n\t\t\tif(c0 == 0x94 || c0 == 0x96 || c0 == 0xBE) return 1;\n\t\t\tbreak;\n\t\t    case 0x88:\n\t\t\tif(c0 == 0x92) return 1;\n\t\t\tbreak;\n\t\t    }\n\t\t    break;\n\t\tcase 0xE3:\n\t\t    if(c1 == 0x80 || c0 == 0x9C) return 1;\n\t\t    break;\n\t\t}\n\t    }else{\n\t\tswitch(c2){\n\t\tcase 0xE2:\n\t\t    switch(c1){\n\t\t    case 0x80:\n\t\t\tif(c0 == 0x95) return 1;\n\t\t\tbreak;\n\t\t    case 0x88:\n\t\t\tif(c0 == 0xA5) return 1;\n\t\t\tbreak;\n\t\t    }\n\t\t    break;\n\t\tcase 0xEF:\n\t\t    switch(c1){\n\t\t    case 0xBC:\n\t\t\tif(c0 == 0x8D) return 1;\n\t\t\tbreak;\n\t\t    case 0xBD:\n\t\t\tif(c0 == 0x9E && !cp932inv_f) return 1;\n\t\t\tbreak;\n\t\t    case 0xBF:\n\t\t\tif(0xA0 <= c0 && c0 <= 0xA5) return 1;\n\t\t\tbreak;\n\t\t    }\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\tppp =\n\t    ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_3bytes_932 :\n\t    ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_3bytes_ms :\n\t    utf8_to_euc_3bytes;\n\tret = w_iconv_common(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);\n    }else return -1;\n#ifdef SHIFTJIS_CP932\n    if (!ret && !cp932inv_f && is_eucg3(*p2)) {\n\tnkf_char s2, s1;\n\tif (e2s_conv(*p2, *p1, &s2, &s1) == 0) {\n\t    s2e_conv(s2, s1, p2, p1);\n\t}else{\n\t    ret = 1;\n\t}\n    }\n#endif\n    return ret;\n}\n\nnkf_char w_iconv_common(nkf_char c1, nkf_char c0, const unsigned short *const *pp, nkf_char psize, nkf_char *p2, nkf_char *p1)\n{\n    nkf_char c2;\n    const unsigned short *p;\n    unsigned short val;\n\n    if (pp == 0) return 1;\n\n    c1 -= 0x80;\n    if (c1 < 0 || psize <= c1) return 1;\n    p = pp[c1];\n    if (p == 0)  return 1;\n\n    c0 -= 0x80;\n    if (c0 < 0 || sizeof_utf8_to_euc_C2 <= c0) return 1;\n    val = p[c0];\n    if (val == 0) return 1;\n    if (no_cp932ext_f && (\n\t(val>>8) == 0x2D || /* NEC special characters */\n\tval > NKF_INT32_C(0xF300) /* IBM extended characters */\n\t)) return 1;\n\n    c2 = val >> 8;\n   if (val > 0x7FFF){\n        c2 &= 0x7f;\n        c2 |= PREFIX_EUCG3;\n    }\n    if (c2 == SO) c2 = X0201;\n    c1 = val & 0x7f;\n    if (p2) *p2 = c2;\n    if (p1) *p1 = c1;\n    return 0;\n}\n\nvoid nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c)\n{\n    const char *hex = \"0123456789ABCDEF\";\n    int shift = 20;\n    c &= VALUE_MASK;\n    while(shift >= 0){\n\tif(c >= 1<<shift){\n\t    while(shift >= 0){\n\t\t(*f)(0, hex[(c>>shift)&0xF]);\n\t\tshift -= 4;\n\t    }\n\t}else{\n\t    shift -= 4;\n\t}\n    }\n    return;\n}\n\nvoid encode_fallback_html(nkf_char c)\n{\n    (*oconv)(0, '&');\n    (*oconv)(0, '#');\n    c &= VALUE_MASK;\n    if(c >= NKF_INT32_C(1000000))\n\t(*oconv)(0, 0x30+(c/NKF_INT32_C(1000000))%10);\n    if(c >= NKF_INT32_C(100000))\n\t(*oconv)(0, 0x30+(c/NKF_INT32_C(100000) )%10);\n    if(c >= 10000)\n\t(*oconv)(0, 0x30+(c/10000  )%10);\n    if(c >= 1000)\n\t(*oconv)(0, 0x30+(c/1000   )%10);\n    if(c >= 100)\n\t(*oconv)(0, 0x30+(c/100    )%10);\n    if(c >= 10)\n\t(*oconv)(0, 0x30+(c/10     )%10);\n    if(c >= 0)\n\t(*oconv)(0, 0x30+ c         %10);\n    (*oconv)(0, ';');\n    return;\n}\n\nvoid encode_fallback_xml(nkf_char c)\n{\n    (*oconv)(0, '&');\n    (*oconv)(0, '#');\n    (*oconv)(0, 'x');\n    nkf_each_char_to_hex(oconv, c);\n    (*oconv)(0, ';');\n    return;\n}\n\nvoid encode_fallback_java(nkf_char c)\n{\n    const char *hex = \"0123456789ABCDEF\";\n    (*oconv)(0, '\\\\');\n    c &= VALUE_MASK;\n    if(!is_unicode_bmp(c)){\n\t(*oconv)(0, 'U');\n\t(*oconv)(0, '0');\n\t(*oconv)(0, '0');\n\t(*oconv)(0, hex[(c>>20)&0xF]);\n\t(*oconv)(0, hex[(c>>16)&0xF]);\n    }else{\n\t(*oconv)(0, 'u');\n    }\n    (*oconv)(0, hex[(c>>12)&0xF]);\n    (*oconv)(0, hex[(c>> 8)&0xF]);\n    (*oconv)(0, hex[(c>> 4)&0xF]);\n    (*oconv)(0, hex[ c     &0xF]);\n    return;\n}\n\nvoid encode_fallback_perl(nkf_char c)\n{\n    (*oconv)(0, '\\\\');\n    (*oconv)(0, 'x');\n    (*oconv)(0, '{');\n    nkf_each_char_to_hex(oconv, c);\n    (*oconv)(0, '}');\n    return;\n}\n\nvoid encode_fallback_subchar(nkf_char c)\n{\n    c = unicode_subchar;\n    (*oconv)((c>>8)&0xFF, c&0xFF);\n    return;\n}\n#endif\n\n#ifdef UTF8_OUTPUT_ENABLE\nnkf_char e2w_conv(nkf_char c2, nkf_char c1)\n{\n#if 0\n    extern const unsigned short euc_to_utf8_1byte[];\n    extern const unsigned short *const euc_to_utf8_2bytes[];\n    extern const unsigned short *const euc_to_utf8_2bytes_ms[];\n    extern const unsigned short *const x0212_to_utf8_2bytes[];\n#endif\n    const unsigned short *p;\n\n    if (c2 == X0201) {\n        p = euc_to_utf8_1byte;\n#ifdef X0212_ENABLE\n    } else if (is_eucg3(c2)){\n\tif(ms_ucs_map_f == UCS_MAP_ASCII&& c2 == NKF_INT32_C(0x8F22) && c1 == 0x43){\n\t    return 0xA6;\n\t}\n        c2 = (c2&0x7f) - 0x21;\n        if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)\n\t    p = x0212_to_utf8_2bytes[c2];\n        else\n            return 0;\n#endif\n    } else {\n        c2 &= 0x7f;\n        c2 = (c2&0x7f) - 0x21;\n        if (0<=c2 && c2<sizeof_euc_to_utf8_2bytes)\n            p = ms_ucs_map_f != UCS_MAP_ASCII ? euc_to_utf8_2bytes_ms[c2] : euc_to_utf8_2bytes[c2];\n\telse\n\t    return 0;\n    }\n    if (!p) return 0;\n    c1 = (c1 & 0x7f) - 0x21;\n    if (0<=c1 && c1<sizeof_euc_to_utf8_1byte)\n\treturn p[c1];\n    return 0;\n}\n\nvoid w_oconv(nkf_char c2, nkf_char c1)\n{\n    nkf_char c0;\n    nkf_char val;\n\n    if (output_bom_f) {\n\toutput_bom_f = FALSE;\n    \t(*o_putc)('\\357');\n\t(*o_putc)('\\273');\n\t(*o_putc)('\\277');\n    }\n\n    if (c2 == EOF) {\n        (*o_putc)(EOF);\n        return;\n    }\n\n#ifdef NUMCHAR_OPTION\n    if (c2 == 0 && is_unicode_capsule(c1)){\n        val = c1 & VALUE_MASK;\n        if (val < 0x80){\n            (*o_putc)(val);\n        }else if (val < 0x800){\n            (*o_putc)(0xC0 | (val >> 6));\n            (*o_putc)(0x80 | (val & 0x3f));\n        } else if (val <= NKF_INT32_C(0xFFFF)) {\n            (*o_putc)(0xE0 | (val >> 12));\n            (*o_putc)(0x80 | ((val >> 6) & 0x3f));\n            (*o_putc)(0x80 | (val        & 0x3f));\n        } else if (val <= NKF_INT32_C(0x10FFFF)) {\n            (*o_putc)(0xF0 | ( val>>18));\n            (*o_putc)(0x80 | ((val>>12) & 0x3f));\n            (*o_putc)(0x80 | ((val>> 6) & 0x3f));\n            (*o_putc)(0x80 | ( val      & 0x3f));\n        }\n        return;\n    }\n#endif\n\n    if (c2 == 0) { \n\toutput_mode = ASCII;\n        (*o_putc)(c1);\n    } else if (c2 == ISO8859_1) {\n\toutput_mode = ISO8859_1;\n        (*o_putc)(c1 | 0x080);\n    } else {\n        output_mode = UTF8;\n\tval = e2w_conv(c2, c1);\n        if (val){\n            w16w_conv(val, &c2, &c1, &c0);\n            (*o_putc)(c2);\n            if (c1){\n                (*o_putc)(c1);\n                if (c0) (*o_putc)(c0);\n            }\n        }\n    }\n}\n\nvoid w_oconv16(nkf_char c2, nkf_char c1)\n{\n    if (output_bom_f) {\n\toutput_bom_f = FALSE;\n        if (output_endian == ENDIAN_LITTLE){\n            (*o_putc)((unsigned char)'\\377');\n            (*o_putc)('\\376');\n        }else{\n            (*o_putc)('\\376');\n            (*o_putc)((unsigned char)'\\377');\n        }\n    }\n\n    if (c2 == EOF) {\n        (*o_putc)(EOF);\n        return;\n    }\n\n    if (c2 == ISO8859_1) {\n        c2 = 0;\n        c1 |= 0x80;\n#ifdef NUMCHAR_OPTION\n    } else if (c2 == 0 && is_unicode_capsule(c1)) {\n        if (is_unicode_bmp(c1)) {\n            c2 = (c1 >> 8) & 0xff;\n            c1 &= 0xff;\n        } else {\n            c1 &= VALUE_MASK;\n            if (c1 <= UNICODE_MAX) {\n                c2 = (c1 >> 10) + NKF_INT32_C(0xD7C0);   /* high surrogate */\n                c1 = (c1 & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */\n                if (output_endian == ENDIAN_LITTLE){\n                    (*o_putc)(c2 & 0xff);\n                    (*o_putc)((c2 >> 8) & 0xff);\n                    (*o_putc)(c1 & 0xff);\n                    (*o_putc)((c1 >> 8) & 0xff);\n                }else{\n                    (*o_putc)((c2 >> 8) & 0xff);\n                    (*o_putc)(c2 & 0xff);\n                    (*o_putc)((c1 >> 8) & 0xff);\n                    (*o_putc)(c1 & 0xff);\n                }\n            }\n            return;\n        }\n#endif\n    } else if (c2) {\n        nkf_char val = e2w_conv(c2, c1);\n        c2 = (val >> 8) & 0xff;\n        c1 = val & 0xff;\n\tif (!val) return;\n    }\n    if (output_endian == ENDIAN_LITTLE){\n        (*o_putc)(c1);\n        (*o_putc)(c2);\n    }else{\n        (*o_putc)(c2);\n        (*o_putc)(c1);\n    }\n}\n\nvoid w_oconv32(nkf_char c2, nkf_char c1)\n{\n    if (output_bom_f) {\n\toutput_bom_f = FALSE;\n        if (output_endian == ENDIAN_LITTLE){\n            (*o_putc)((unsigned char)'\\377');\n            (*o_putc)('\\376');\n\t    (*o_putc)('\\000');\n\t    (*o_putc)('\\000');\n        }else{\n\t    (*o_putc)('\\000');\n\t    (*o_putc)('\\000');\n            (*o_putc)('\\376');\n            (*o_putc)((unsigned char)'\\377');\n        }\n    }\n\n    if (c2 == EOF) {\n        (*o_putc)(EOF);\n        return;\n    }\n\n    if (c2 == ISO8859_1) {\n        c1 |= 0x80;\n#ifdef NUMCHAR_OPTION\n    } else if (c2 == 0 && is_unicode_capsule(c1)) {\n\tc1 &= VALUE_MASK;\n#endif\n    } else if (c2) {\n        c1 = e2w_conv(c2, c1);\n\tif (!c1) return;\n    }\n    if (output_endian == ENDIAN_LITTLE){\n        (*o_putc)( c1 & NKF_INT32_C(0x000000FF));\n        (*o_putc)((c1 & NKF_INT32_C(0x0000FF00)) >>  8);\n        (*o_putc)((c1 & NKF_INT32_C(0x00FF0000)) >> 16);\n\t(*o_putc)('\\000');\n    }else{\n\t(*o_putc)('\\000');\n        (*o_putc)((c1 & NKF_INT32_C(0x00FF0000)) >> 16);\n        (*o_putc)((c1 & NKF_INT32_C(0x0000FF00)) >>  8);\n        (*o_putc)( c1 & NKF_INT32_C(0x000000FF));\n    }\n}\n#endif\n\nvoid e_oconv(nkf_char c2, nkf_char c1)\n{\n#ifdef NUMCHAR_OPTION\n    if (c2 == 0 && is_unicode_capsule(c1)){\n        w16e_conv(c1, &c2, &c1);\n        if (c2 == 0 && is_unicode_capsule(c1)){\n\t    c2 = c1 & VALUE_MASK;\n\t    if (x0212_f && 0xE000 <= c2 && c2 <= 0xE757) {\n\t\t/* eucJP-ms UDC */\n\t\tc1 &= 0xFFF;\n\t\tc2 = c1 / 94;\n\t\tc2 += c2 < 10 ? 0x75 : 0x8FEB;\n\t\tc1 = 0x21 + c1 % 94;\n\t\tif (is_eucg3(c2)){\n\t\t    (*o_putc)(0x8f);\n\t\t    (*o_putc)((c2 & 0x7f) | 0x080);\n\t\t    (*o_putc)(c1 | 0x080);\n\t\t}else{\n\t\t    (*o_putc)((c2 & 0x7f) | 0x080);\n\t\t    (*o_putc)(c1 | 0x080);\n\t\t}\n\t\treturn;\n\t    } else {\n\t\tif (encode_fallback) (*encode_fallback)(c1);\n\t\treturn;\n\t    }\n        }\n    }\n#endif\n    if (c2 == EOF) {\n        (*o_putc)(EOF);\n        return;\n    } else if (c2 == 0) { \n\toutput_mode = ASCII;\n        (*o_putc)(c1);\n    } else if (c2 == X0201) {\n\toutput_mode = JAPANESE_EUC;\n        (*o_putc)(SSO); (*o_putc)(c1|0x80);\n    } else if (c2 == ISO8859_1) {\n\toutput_mode = ISO8859_1;\n        (*o_putc)(c1 | 0x080);\n#ifdef X0212_ENABLE\n    } else if (is_eucg3(c2)){\n\toutput_mode = JAPANESE_EUC;\n#ifdef SHIFTJIS_CP932\n        if (!cp932inv_f){\n            nkf_char s2, s1;\n            if (e2s_conv(c2, c1, &s2, &s1) == 0){\n                s2e_conv(s2, s1, &c2, &c1);\n            }\n        }\n#endif\n        if (c2 == 0) {\n\t    output_mode = ASCII;\n\t    (*o_putc)(c1);\n\t}else if (is_eucg3(c2)){\n            if (x0212_f){\n                (*o_putc)(0x8f);\n                (*o_putc)((c2 & 0x7f) | 0x080);\n                (*o_putc)(c1 | 0x080);\n            }\n        }else{\n            (*o_putc)((c2 & 0x7f) | 0x080);\n            (*o_putc)(c1 | 0x080);\n        }\n#endif\n    } else {\n        if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) {\n            set_iconv(FALSE, 0);\n            return; /* too late to rescue this char */\n        }\n\toutput_mode = JAPANESE_EUC;\n        (*o_putc)(c2 | 0x080);\n        (*o_putc)(c1 | 0x080);\n    }\n}\n\n#ifdef X0212_ENABLE\nnkf_char x0212_shift(nkf_char c)\n{\n    nkf_char ret = c;\n    c &= 0x7f;\n    if (is_eucg3(ret)){\n        if (0x75 <= c && c <= 0x7f){\n            ret = c + (0x109 - 0x75);\n        }\n    }else{\n        if (0x75 <= c && c <= 0x7f){\n            ret = c + (0x113 - 0x75);\n        }\n    }\n    return ret;\n}\n\n\nnkf_char x0212_unshift(nkf_char c)\n{\n    nkf_char ret = c;\n    if (0x7f <= c && c <= 0x88){\n        ret = c + (0x75 - 0x7f);\n    }else if (0x89 <= c && c <= 0x92){\n        ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89));\n    }\n    return ret;\n}\n#endif /* X0212_ENABLE */\n\nnkf_char e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)\n{\n    nkf_char ndx;\n    if (is_eucg3(c2)){\n\tndx = c2 & 0x7f;\n\tif (x0213_f){\n\t    if((0x21 <= ndx && ndx <= 0x2F)){\n\t\tif (p2) *p2 = ((ndx - 1) >> 1) + 0xec - ndx / 8 * 3;\n\t\tif (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);\n\t\treturn 0;\n\t    }else if(0x6E <= ndx && ndx <= 0x7E){\n\t\tif (p2) *p2 = ((ndx - 1) >> 1) + 0xbe;\n\t\tif (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);\n\t\treturn 0;\n\t    }\n\t    return 1;\n\t}\n#ifdef X0212_ENABLE\n\telse if(nkf_isgraph(ndx)){\n\t    nkf_char val = 0;\n\t    const unsigned short *ptr;\n#if 0\n\t    extern const unsigned short *const x0212_shiftjis[];\n#endif\n\t    ptr = x0212_shiftjis[ndx - 0x21];\n\t    if (ptr){\n\t\tval = ptr[(c1 & 0x7f) - 0x21];\n\t    }\n\t    if (val){\n\t\tc2 = val >> 8;\n\t\tc1 = val & 0xff;\n\t\tif (p2) *p2 = c2;\n\t\tif (p1) *p1 = c1;\n\t\treturn 0;\n\t    }\n\t    c2 = x0212_shift(c2);\n\t}\n#endif /* X0212_ENABLE */\n    }\n    if(0x7F < c2) return 1;\n    if (p2) *p2 = ((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1);\n    if (p1) *p1 = c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);\n    return 0;\n}\n\nvoid s_oconv(nkf_char c2, nkf_char c1)\n{\n#ifdef NUMCHAR_OPTION\n    if (c2 == 0 && is_unicode_capsule(c1)){\n        w16e_conv(c1, &c2, &c1);\n        if (c2 == 0 && is_unicode_capsule(c1)){\n\t    c2 = c1 & VALUE_MASK;\n\t    if (!x0213_f && 0xE000 <= c2 && c2 <= 0xE757) {\n\t\t/* CP932 UDC */\n\t\tc1 &= 0xFFF;\n\t\tc2 = c1 / 188 + 0xF0;\n\t\tc1 = c1 % 188;\n\t\tc1 += 0x40 + (c1 > 0x3e);\n\t\t(*o_putc)(c2);\n\t\t(*o_putc)(c1);\n\t\treturn;\n\t    } else {\n\t\tif(encode_fallback)(*encode_fallback)(c1);\n\t\treturn;\n\t    }\n\t}\n    }\n#endif\n    if (c2 == EOF) {\n        (*o_putc)(EOF);\n        return;\n    } else if (c2 == 0) {\n\toutput_mode = ASCII;\n        (*o_putc)(c1);\n    } else if (c2 == X0201) {\n\toutput_mode = SHIFT_JIS;\n        (*o_putc)(c1|0x80);\n    } else if (c2 == ISO8859_1) {\n\toutput_mode = ISO8859_1;\n        (*o_putc)(c1 | 0x080);\n#ifdef X0212_ENABLE\n    } else if (is_eucg3(c2)){\n\toutput_mode = SHIFT_JIS;\n        if (e2s_conv(c2, c1, &c2, &c1) == 0){\n            (*o_putc)(c2);\n            (*o_putc)(c1);\n        }\n#endif\n    } else {\n        if (!nkf_isprint(c1) || !nkf_isprint(c2)) {\n            set_iconv(FALSE, 0);\n            return; /* too late to rescue this char */\n        }\n\toutput_mode = SHIFT_JIS;\n        e2s_conv(c2, c1, &c2, &c1);\n\n#ifdef SHIFTJIS_CP932\n        if (cp932inv_f\n            && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){\n#if 0\n            extern const unsigned short cp932inv[2][189];\n#endif\n            nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];\n            if (c){\n                c2 = c >> 8;\n                c1 = c & 0xff;\n            }\n        }\n#endif /* SHIFTJIS_CP932 */\n\n        (*o_putc)(c2);\n\tif (prefix_table[(unsigned char)c1]){\n            (*o_putc)(prefix_table[(unsigned char)c1]);\n\t}\n        (*o_putc)(c1);\n    }\n}\n\nvoid j_oconv(nkf_char c2, nkf_char c1)\n{\n#ifdef NUMCHAR_OPTION\n    if (c2 == 0 && is_unicode_capsule(c1)){\n        w16e_conv(c1, &c2, &c1);\n        if (c2 == 0 && is_unicode_capsule(c1)){\n\t    c2 = c1 & VALUE_MASK;\n\t    if (ms_ucs_map_f && 0xE000 <= c2 && c2 <= 0xE757) {\n\t\t/* CP5022x UDC */\n\t\tc1 &= 0xFFF;\n\t\tc2 = 0x7F + c1 / 94;\n\t\tc1 = 0x21 + c1 % 94;\n\t    } else {\n\t\tif (encode_fallback) (*encode_fallback)(c1);\n\t\treturn;\n\t    }\n        }\n    }\n#endif\n    if (c2 == EOF) {\n        if (output_mode !=ASCII && output_mode!=ISO8859_1) {\n            (*o_putc)(ESC);\n            (*o_putc)('(');\n            (*o_putc)(ascii_intro);\n\t    output_mode = ASCII;\n        }\n        (*o_putc)(EOF);\n#ifdef X0212_ENABLE\n    } else if (is_eucg3(c2)){\n\tif(x0213_f){\n\t    if(output_mode!=X0213_2){\n\t\toutput_mode = X0213_2;\n\t\t(*o_putc)(ESC);\n\t\t(*o_putc)('$');\n\t\t(*o_putc)('(');\n\t\t(*o_putc)(X0213_2&0x7F);\n\t    }\n\t}else{\n\t    if(output_mode!=X0212){\n\t\toutput_mode = X0212;\n\t\t(*o_putc)(ESC);\n\t\t(*o_putc)('$');\n\t\t(*o_putc)('(');\n\t\t(*o_putc)(X0212&0x7F);\n\t    }\n        }\n        (*o_putc)(c2 & 0x7f);\n        (*o_putc)(c1);\n#endif\n    } else if (c2==X0201) {\n        if (output_mode!=X0201) {\n            output_mode = X0201;\n            (*o_putc)(ESC);\n            (*o_putc)('(');\n            (*o_putc)('I');\n        }\n        (*o_putc)(c1);\n    } else if (c2==ISO8859_1) {\n            /* iso8859 introduction, or 8th bit on */\n            /* Can we convert in 7bit form using ESC-'-'-A ? \n               Is this popular? */\n\toutput_mode = ISO8859_1;\n        (*o_putc)(c1|0x80);\n    } else if (c2 == 0) {\n        if (output_mode !=ASCII && output_mode!=ISO8859_1) {\n            (*o_putc)(ESC);\n            (*o_putc)('(');\n            (*o_putc)(ascii_intro);\n            output_mode = ASCII;\n        }\n        (*o_putc)(c1);\n    } else {\n\tif(ms_ucs_map_f\n\t   ? c2<0x20 || 0x92<c2 || c1<0x20 || 0x7e<c1\n\t   : c2<0x20 || 0x7e<c2 || c1<0x20 || 0x7e<c1) return;\n\tif(x0213_f){\n\t    if (output_mode!=X0213_1) {\n\t\toutput_mode = X0213_1;\n\t\t(*o_putc)(ESC);\n\t\t(*o_putc)('$');\n\t\t(*o_putc)('(');\n\t\t(*o_putc)(X0213_1&0x7F);\n\t    }\n\t}else if (output_mode != X0208) {\n            output_mode = X0208;\n            (*o_putc)(ESC);\n            (*o_putc)('$');\n            (*o_putc)(kanji_intro);\n        }\n        (*o_putc)(c2);\n        (*o_putc)(c1);\n    }\n}\n\nvoid base64_conv(nkf_char c2, nkf_char c1)\n{\n    mime_prechar(c2, c1);\n    (*o_base64conv)(c2,c1);\n}\n\n\nstatic nkf_char broken_buf[3];\nstatic int broken_counter = 0;\nstatic int broken_last = 0;\nnkf_char broken_getc(FILE *f)\n{\n    nkf_char c,c1;\n\n    if (broken_counter>0) {\n\treturn broken_buf[--broken_counter];\n    }\n    c= (*i_bgetc)(f);\n    if (c=='$' && broken_last != ESC \n            && (input_mode==ASCII || input_mode==X0201)) {\n\tc1= (*i_bgetc)(f);\n\tbroken_last = 0;\n\tif (c1=='@'|| c1=='B') {\n\t    broken_buf[0]=c1; broken_buf[1]=c; \n\t    broken_counter=2;\n\t    return ESC;\n\t} else {\n\t    (*i_bungetc)(c1,f);\n\t    return c;\n\t}\n    } else if (c=='(' && broken_last != ESC \n            && (input_mode==X0208 || input_mode==X0201)) { /* ) */\n\tc1= (*i_bgetc)(f);\n\tbroken_last = 0;\n\tif (c1=='J'|| c1=='B') {\n\t    broken_buf[0]=c1; broken_buf[1]=c;\n\t    broken_counter=2;\n\t    return ESC;\n\t} else {\n\t    (*i_bungetc)(c1,f);\n\t    return c;\n\t}\n    } else {\n\tbroken_last = c;\n\treturn c;\n    }\n}\n\nnkf_char broken_ungetc(nkf_char c, FILE *f)\n{\n    if (broken_counter<2)\n\tbroken_buf[broken_counter++]=c;\n    return c;\n}\n\nstatic nkf_char prev_cr = 0;\n\nvoid cr_conv(nkf_char c2, nkf_char c1)\n{\n    if (prev_cr) {\n\tprev_cr = 0;\n\tif (! (c2==0&&c1==NL) ) {\n\t    cr_conv(0,'\\n');\n\t}\n    }\n    if (c2) {\n        (*o_crconv)(c2,c1);\n    } else if (c1=='\\r') {\n\tprev_cr = c1;\n    } else if (c1=='\\n') {\n        if (crmode_f==CRLF) {\n            (*o_crconv)(0,'\\r');\n\t} else if (crmode_f==CR) {\n            (*o_crconv)(0,'\\r');\n\t    return;\n\t} \n\t(*o_crconv)(0,NL);\n    } else if (c1!='\\032' || crmode_f!=NL){\n        (*o_crconv)(c2,c1);\n    }\n}\n\n/* \n  Return value of fold_conv()\n\n       \\n  add newline  and output char\n       \\r  add newline  and output nothing\n       ' ' space\n       0   skip  \n       1   (or else) normal output \n\n  fold state in prev (previous character)\n\n      >0x80 Japanese (X0208/X0201)\n      <0x80 ASCII\n      \\n    new line \n      ' '   space\n\n  This fold algorthm does not preserve heading space in a line.\n  This is the main difference from fmt.\n*/\n\n#define char_size(c2,c1) (c2?2:1)\n\nvoid fold_conv(nkf_char c2, nkf_char c1)\n{ \n    nkf_char prev0;\n    nkf_char fold_state;\n\n    if (c1== '\\r' && !fold_preserve_f) {\n    \tfold_state=0;  /* ignore cr */\n    }else if (c1== '\\n'&&f_prev=='\\r' && fold_preserve_f) {\n        f_prev = '\\n';\n     \tfold_state=0;  /* ignore cr */\n    } else if (c1== BS) {\n        if (f_line>0) f_line--;\n        fold_state =  1;\n    } else if (c2==EOF && f_line != 0) {    /* close open last line */\n            fold_state = '\\n';\n    } else if ((c1=='\\n' && !fold_preserve_f)\n               || ((c1=='\\r'||(c1=='\\n'&&f_prev!='\\r'))\n                   && fold_preserve_f)) {\n        /* new line */\n        if (fold_preserve_f) { \n            f_prev = c1;\n            f_line = 0;\n            fold_state =  '\\r';\n\t} else if ((f_prev == c1 && !fold_preserve_f)\n                   || (f_prev == '\\n' && fold_preserve_f)\n                   ) {        /* duplicate newline */\n            if (f_line) {\n                f_line = 0;\n                fold_state =  '\\n';    /* output two newline */\n            } else {\n                f_line = 0;\n                fold_state =  1;\n            }\n        } else  {\n            if (f_prev&0x80) {     /* Japanese? */\n                f_prev = c1;\n                fold_state =  0;       /* ignore given single newline */\n            } else if (f_prev==' ') {\n                fold_state =  0;\n            } else {\n                f_prev = c1;\n                if (++f_line<=fold_len) \n                    fold_state =  ' ';\n                else {\n                    f_line = 0;\n                    fold_state =  '\\r';        /* fold and output nothing */\n                }\n            }\n        }\n    } else if (c1=='\\f') {\n        f_prev = '\\n';\n        f_line = 0;\n        fold_state =  '\\n';            /* output newline and clear */\n    } else if ( (c2==0  && c1==' ')||\n               (c2==0  && c1=='\\t')||\n               (c2=='!'&& c1=='!')) {\n        /* X0208 kankaku or ascii space */\n            if (f_prev == ' ') {\n                fold_state = 0;         /* remove duplicate spaces */\n            } else {\n                f_prev = ' ';    \n                if (++f_line<=fold_len) \n                    fold_state = ' ';         /* output ASCII space only */\n                else {\n                    f_prev = ' '; f_line = 0;\n                    fold_state = '\\r';        /* fold and output nothing */\n                }\n            }\n    } else {\n        prev0 = f_prev; /* we still need this one... , but almost done */\n        f_prev = c1;\n        if (c2 || c2==X0201) \n            f_prev |= 0x80;  /* this is Japanese */\n        f_line += char_size(c2,c1);\n        if (f_line<=fold_len) {   /* normal case */\n            fold_state = 1;\n        } else {\n            if (f_line>fold_len+fold_margin) { /* too many kinsoku suspension */\n                f_line = char_size(c2,c1);\n                fold_state =  '\\n';       /* We can't wait, do fold now */\n            } else if (c2==X0201) {\n            /* simple kinsoku rules  return 1 means no folding  */\n                if (c1==(0xde&0x7f)) fold_state = 1; /* \u001b$B!+\u001b(B*/\n                else if (c1==(0xdf&0x7f)) fold_state = 1; /* \u001b$B!,\u001b(B*/\n                else if (c1==(0xa4&0x7f)) fold_state = 1; /* \u001b$B!#\u001b(B*/\n                else if (c1==(0xa3&0x7f)) fold_state = 1; /* \u001b$B!$\u001b(B*/\n                else if (c1==(0xa1&0x7f)) fold_state = 1; /* \u001b$B!W\u001b(B*/\n                else if (c1==(0xb0&0x7f)) fold_state = 1; /* - */\n                else if (SPACE<=c1 && c1<=(0xdf&0x7f)) {      /* X0201 */\n\t\t    f_line = 1;\n\t\t    fold_state = '\\n';/* add one new f_line before this character */\n\t\t} else {\n\t\t    f_line = 1;\n\t\t    fold_state = '\\n';/* add one new f_line before this character */\n\t\t}\n            } else if (c2==0) {\n                /* kinsoku point in ASCII */ \n\t\tif (  c1==')'||    /* { [ ( */\n                     c1==']'||\n                     c1=='}'||\n                     c1=='.'||\n                     c1==','||\n                     c1=='!'||\n                     c1=='?'||\n                     c1=='/'||\n                     c1==':'||\n                     c1==';' ) {\n\t\t    fold_state = 1;\n\t\t/* just after special */\n\t\t} else if (!is_alnum(prev0)) {\n\t\t    f_line = char_size(c2,c1);\n\t\t    fold_state = '\\n';\n\t\t} else if ((prev0==' ') ||   /* ignored new f_line */\n                      (prev0=='\\n')||        /* ignored new f_line */\n                      (prev0&0x80)) {        /* X0208 - ASCII */\n\t\t    f_line = char_size(c2,c1);\n                    fold_state = '\\n';/* add one new f_line before this character */\n                } else {\n                    fold_state = 1;  /* default no fold in ASCII */\n                }\n            } else {\n                if (c2=='!') {\n                    if (c1=='\"')  fold_state = 1; /* \u001b$B!\"\u001b(B */\n                    else if (c1=='#')  fold_state = 1; /* \u001b$B!#\u001b(B */\n                    else if (c1=='W')  fold_state = 1; /* \u001b$B!W\u001b(B */\n                    else if (c1=='K')  fold_state = 1; /* \u001b$B!K\u001b(B */\n                    else if (c1=='$')  fold_state = 1; /* \u001b$B!$\u001b(B */\n                    else if (c1=='%')  fold_state = 1; /* \u001b$B!%\u001b(B */\n                    else if (c1=='\\'') fold_state = 1; /* \u001b$B!\\\u001b(B */\n                    else if (c1=='(')  fold_state = 1; /* \u001b$B!(\u001b(B */\n                    else if (c1==')')  fold_state = 1; /* \u001b$B!)\u001b(B */\n                    else if (c1=='*')  fold_state = 1; /* \u001b$B!*\u001b(B */\n                    else if (c1=='+')  fold_state = 1; /* \u001b$B!+\u001b(B */\n                    else if (c1==',')  fold_state = 1; /* \u001b$B!,\u001b(B */\n                         /* default no fold in kinsoku */\n\t\t    else { \n\t\t\tfold_state = '\\n';\n\t\t\tf_line = char_size(c2,c1);\n\t\t\t/* add one new f_line before this character */\n\t\t    }\n                } else {\n\t\t    f_line = char_size(c2,c1);\n                    fold_state = '\\n'; \n                    /* add one new f_line before this character */\n                }\n            }\n        }\n    }\n    /* terminator process */\n    switch(fold_state) {\n        case '\\n': \n            (*o_fconv)(0,'\\n');\n            (*o_fconv)(c2,c1);\n            break;\n        case 0:    \n            return;\n        case '\\r': \n            (*o_fconv)(0,'\\n');\n            break;\n        case '\\t': \n        case ' ': \n            (*o_fconv)(0,' ');\n            break;\n        default:\n            (*o_fconv)(c2,c1);\n    }\n}\n\nnkf_char z_prev2=0,z_prev1=0;\n\nvoid z_conv(nkf_char c2, nkf_char c1)\n{\n\n    /* if (c2) c1 &= 0x7f; assertion */\n\n    if (x0201_f && z_prev2==X0201) {  /* X0201 */\n        if (c1==(0xde&0x7f)) { /* \u001b$BByE@\u001b(B */\n            z_prev2=0;\n            (*o_zconv)(dv[(z_prev1-SPACE)*2],dv[(z_prev1-SPACE)*2+1]);\n            return;\n        } else if (c1==(0xdf&0x7f)&&ev[(z_prev1-SPACE)*2]) {  /* \u001b$BH>ByE@\u001b(B */\n            z_prev2=0;\n            (*o_zconv)(ev[(z_prev1-SPACE)*2],ev[(z_prev1-SPACE)*2+1]);\n            return;\n        } else {\n            z_prev2=0;\n            (*o_zconv)(cv[(z_prev1-SPACE)*2],cv[(z_prev1-SPACE)*2+1]);\n        }\n    }\n\n    if (c2==EOF) {\n        (*o_zconv)(c2,c1);\n        return;\n    }\n\n    if (x0201_f && c2==X0201) {\n        if (dv[(c1-SPACE)*2]||ev[(c1-SPACE)*2]) {\n            /* wait for \u001b$BByE@\u001b(B or \u001b$BH>ByE@\u001b(B */\n            z_prev1 = c1; z_prev2 = c2;\n            return;\n        } else {\n            (*o_zconv)(cv[(c1-SPACE)*2],cv[(c1-SPACE)*2+1]);\n            return;\n        }\n    }\n\n    /* JISX0208 Alphabet */\n    if (alpha_f && c2 == 0x23 ) {\n        c2 = 0;\n    } else if (alpha_f && c2 == 0x21 ) { \n    /* JISX0208 Kigou */\n       if (0x21==c1) {\n           if (alpha_f&0x2) {\n               c1 = ' ';\n               c2 = 0;\n           } else if (alpha_f&0x4) {\n                (*o_zconv)(0,' ');\n                (*o_zconv)(0,' ');\n                return;\n           } \n       } else if (0x20<c1 && c1<0x7f && fv[c1-0x20]) {\n           c1 = fv[c1-0x20];\n           c2 =  0;\n           if (alpha_f&0x8) {\n               char *entity = 0;\n               switch (c1){\n                 case '>': entity = \"&gt;\"; break;\n                 case '<': entity = \"&lt;\"; break;\n                 case '\\\"': entity = \"&quot;\"; break;\n                 case '&': entity = \"&amp;\"; break;\n               }\n               if (entity){\n                   while (*entity) (*o_zconv)(0, *entity++);\n                   return;\n               }\n           }\n       } \n    }\n    (*o_zconv)(c2,c1);\n}\n\n\n#define rot13(c)  ( \\\n      ( c < 'A' ) ? c: \\\n      (c <= 'M')  ? (c + 13): \\\n      (c <= 'Z')  ? (c - 13): \\\n      (c < 'a')   ? (c): \\\n      (c <= 'm')  ? (c + 13): \\\n      (c <= 'z')  ? (c - 13): \\\n      (c) \\\n)\n\n#define  rot47(c) ( \\\n      ( c < '!' ) ? c: \\\n      ( c <= 'O' ) ? (c + 47) : \\\n      ( c <= '~' ) ?  (c - 47) : \\\n      c \\\n)\n\nvoid rot_conv(nkf_char c2, nkf_char c1)\n{\n    if (c2==0 || c2==X0201 || c2==ISO8859_1) {\n\tc1 = rot13(c1);\n    } else if (c2) {\n\tc1 = rot47(c1);\n\tc2 = rot47(c2);\n    }\n    (*o_rot_conv)(c2,c1);\n}\n\nvoid hira_conv(nkf_char c2, nkf_char c1)\n{\n    if (hira_f & 1) {\n        if (c2 == 0x25) {\n            if (0x20 < c1 && c1 < 0x74) {\n                c2 = 0x24;\n                (*o_hira_conv)(c2,c1);\n                return;\n            } else if (c1 == 0x74 && (output_conv == w_oconv || output_conv == w_oconv16)) {\n                c2 = 0;\n                c1 = CLASS_UNICODE | 0x3094;\n                (*o_hira_conv)(c2,c1);\n                return;\n            }\n        } else if (c2 == 0x21 && (c1 == 0x33 || c1 == 0x34)) {\n            c1 += 2;\n            (*o_hira_conv)(c2,c1);\n            return;\n        }\n    }\n    if (hira_f & 2) {\n        if (c2 == 0 && c1 == (CLASS_UNICODE | 0x3094)) {\n            c2 = 0x25;\n            c1 = 0x74;\n        } else if (c2 == 0x24 && 0x20 < c1 && c1 < 0x74) {\n            c2 = 0x25;\n        } else if (c2 == 0x21 && (c1 == 0x35 || c1 == 0x36)) {\n            c1 -= 2;\n        }\n    }\n    (*o_hira_conv)(c2,c1);\n}\n\n\nvoid iso2022jp_check_conv(nkf_char c2, nkf_char c1)\n{\n    static const nkf_char range[RANGE_NUM_MAX][2] = {\n        {0x222f, 0x2239,},\n        {0x2242, 0x2249,},\n        {0x2251, 0x225b,},\n        {0x226b, 0x2271,},\n        {0x227a, 0x227d,},\n        {0x2321, 0x232f,},\n        {0x233a, 0x2340,},\n        {0x235b, 0x2360,},\n        {0x237b, 0x237e,},\n        {0x2474, 0x247e,},\n        {0x2577, 0x257e,},\n        {0x2639, 0x2640,},\n        {0x2659, 0x267e,},\n        {0x2742, 0x2750,},\n        {0x2772, 0x277e,},\n        {0x2841, 0x287e,},\n        {0x4f54, 0x4f7e,},\n        {0x7425, 0x747e},\n    };\n    nkf_char i;\n    nkf_char start, end, c;\n\n    if(c2 >= 0x00 && c2 <= 0x20 && c1 >= 0x7f && c1 <= 0xff) {\n\tc2 = GETA1;\n\tc1 = GETA2;\n    }\n    if((c2 >= 0x29 && c2 <= 0x2f) || (c2 >= 0x75 && c2 <= 0x7e)) {\n\tc2 = GETA1;\n\tc1 = GETA2;\n    }\n\n    for (i = 0; i < RANGE_NUM_MAX; i++) {\n\tstart = range[i][0];\n\tend   = range[i][1];\n\tc     = (c2 << 8) + c1;\n\tif (c >= start && c <= end) {\n\t    c2 = GETA1;\n\t    c1 = GETA2;\n\t}\n    }\n    (*o_iso2022jp_check_conv)(c2,c1);\n}\n\n\n/* This converts  =?ISO-2022-JP?B?HOGE HOGE?= */\n\nconst unsigned char *mime_pattern[] = {\n    (const unsigned char *)\"\\075?EUC-JP?B?\",\n    (const unsigned char *)\"\\075?SHIFT_JIS?B?\",\n    (const unsigned char *)\"\\075?ISO-8859-1?Q?\",\n    (const unsigned char *)\"\\075?ISO-8859-1?B?\",\n    (const unsigned char *)\"\\075?ISO-2022-JP?B?\",\n    (const unsigned char *)\"\\075?ISO-2022-JP?Q?\",\n#if defined(UTF8_INPUT_ENABLE)\n    (const unsigned char *)\"\\075?UTF-8?B?\",\n    (const unsigned char *)\"\\075?UTF-8?Q?\",\n#endif\n    (const unsigned char *)\"\\075?US-ASCII?Q?\",\n    NULL\n};\n\n\n/* \u001b$B3:Ev$9$k%3!<%I$NM%@hEY$r>e$2$k$?$a$NL\\0u\u001b(B */\nnkf_char (*mime_priority_func[])(nkf_char c2, nkf_char c1, nkf_char c0) = {\n    e_iconv, s_iconv, 0, 0, 0, 0,\n#if defined(UTF8_INPUT_ENABLE)\n    w_iconv, w_iconv,\n#endif\n    0,\n};\n\nconst nkf_char mime_encode[] = {\n    JAPANESE_EUC, SHIFT_JIS,ISO8859_1, ISO8859_1, X0208, X0201,\n#if defined(UTF8_INPUT_ENABLE)\n    UTF8, UTF8,\n#endif\n    ASCII,\n    0\n};\n\nconst nkf_char mime_encode_method[] = {\n    'B', 'B','Q', 'B', 'B', 'Q',\n#if defined(UTF8_INPUT_ENABLE)\n    'B', 'Q',\n#endif\n    'Q',\n    0\n};\n\n\n#define MAXRECOVER 20\n\nvoid switch_mime_getc(void)\n{\n    if (i_getc!=mime_getc) {\n\ti_mgetc = i_getc; i_getc = mime_getc;\n\ti_mungetc = i_ungetc; i_ungetc = mime_ungetc;\n\tif(mime_f==STRICT_MIME) {\n\t    i_mgetc_buf = i_mgetc; i_mgetc = mime_getc_buf;\n\t    i_mungetc_buf = i_mungetc; i_mungetc = mime_ungetc_buf;\n\t}\n    }\n}\n\nvoid unswitch_mime_getc(void)\n{\n    if(mime_f==STRICT_MIME) {\n\ti_mgetc = i_mgetc_buf;\n\ti_mungetc = i_mungetc_buf;\n    }\n    i_getc = i_mgetc;\n    i_ungetc = i_mungetc;\n    if(mime_iconv_back)set_iconv(FALSE, mime_iconv_back);\n    mime_iconv_back = NULL;\n}\n\nnkf_char mime_begin_strict(FILE *f)\n{\n    nkf_char c1 = 0;\n    int i,j,k;\n    const unsigned char *p,*q;\n    nkf_char r[MAXRECOVER];    /* recovery buffer, max mime pattern length */\n\n    mime_decode_mode = FALSE;\n    /* =? has been checked */\n    j = 0;\n    p = mime_pattern[j];\n    r[0]='='; r[1]='?';\n\n    for(i=2;p[i]>' ';i++) {                   /* start at =? */\n        if ( ((r[i] = c1 = (*i_getc)(f))==EOF) || nkf_toupper(c1) != p[i] ) {\n            /* pattern fails, try next one */\n            q = p;\n            while (mime_pattern[++j]) {\n\t\tp = mime_pattern[j];\n                for(k=2;k<i;k++)              /* assume length(p) > i */\n                    if (p[k]!=q[k]) break;\n                if (k==i && nkf_toupper(c1)==p[k]) break;\n            }\n\t    p = mime_pattern[j];\n            if (p) continue;  /* found next one, continue */\n            /* all fails, output from recovery buffer */\n            (*i_ungetc)(c1,f);\n            for(j=0;j<i;j++) {\n                (*oconv)(0,r[j]);\n            }\n            return c1;\n        }\n    }\n    mime_decode_mode = p[i-2];\n\n    mime_iconv_back = iconv;\n    set_iconv(FALSE, mime_priority_func[j]);\n    clr_code_score(find_inputcode_byfunc(mime_priority_func[j]), SCORE_iMIME);\n\n    if (mime_decode_mode=='B') {\n        mimebuf_f = unbuf_f;\n        if (!unbuf_f) {\n            /* do MIME integrity check */\n            return mime_integrity(f,mime_pattern[j]);\n        } \n    }\n    switch_mime_getc();\n    mimebuf_f = TRUE;\n    return c1;\n}\n\nnkf_char mime_getc_buf(FILE *f)\n{\n    /* we don't keep eof of Fifo, becase it contains ?= as\n       a terminator. It was checked in mime_integrity. */\n    return ((mimebuf_f)?\n        (*i_mgetc_buf)(f):Fifo(mime_input++));\n}\n\nnkf_char mime_ungetc_buf(nkf_char c, FILE *f)\n{\n    if (mimebuf_f)\n\t(*i_mungetc_buf)(c,f);\n    else \n\tFifo(--mime_input) = (unsigned char)c;\n    return c;\n}\n\nnkf_char mime_begin(FILE *f)\n{\n    nkf_char c1;\n    int i,k;\n\n    /* In NONSTRICT mode, only =? is checked. In case of failure, we  */\n    /* re-read and convert again from mime_buffer.  */\n\n    /* =? has been checked */\n    k = mime_last;\n    Fifo(mime_last++)='='; Fifo(mime_last++)='?';\n    for(i=2;i<MAXRECOVER;i++) {                   /* start at =? */\n        /* We accept any character type even if it is breaked by new lines */\n        c1 = (*i_getc)(f); Fifo(mime_last++) = (unsigned char)c1;\n        if (c1=='\\n'||c1==' '||c1=='\\r'||\n                c1=='-'||c1=='_'||is_alnum(c1) ) continue;\n        if (c1=='=') {\n            /* Failed. But this could be another MIME preemble */\n            (*i_ungetc)(c1,f);\n            mime_last--;\n            break;\n        }\n        if (c1!='?') break;\n        else {\n            /* c1=='?' */\n            c1 = (*i_getc)(f); Fifo(mime_last++) = (unsigned char)c1;\n            if (!(++i<MAXRECOVER) || c1==EOF) break;\n            if (c1=='b'||c1=='B') {\n                mime_decode_mode = 'B';\n            } else if (c1=='q'||c1=='Q') {\n                mime_decode_mode = 'Q';\n            } else {\n                break;\n            }\n            c1 = (*i_getc)(f); Fifo(mime_last++) = (unsigned char)c1;\n            if (!(++i<MAXRECOVER) || c1==EOF) break;\n            if (c1!='?') {\n                mime_decode_mode = FALSE;\n            }\n            break;\n        }\n    }\n    switch_mime_getc();\n    if (!mime_decode_mode) {\n        /* false MIME premble, restart from mime_buffer */\n        mime_decode_mode = 1;  /* no decode, but read from the mime_buffer */\n        /* Since we are in MIME mode until buffer becomes empty,    */\n        /* we never go into mime_begin again for a while.           */\n        return c1;\n    }\n    /* discard mime preemble, and goto MIME mode */\n    mime_last = k;\n    /* do no MIME integrity check */\n    return c1;   /* used only for checking EOF */\n}\n\n#ifdef CHECK_OPTION\nvoid no_putc(nkf_char c)\n{\n    ;\n}\n\nvoid debug(const char *str)\n{\n    if (debug_f){\n        fprintf(stderr, \"%s\\n\", str);\n    }\n}\n#endif\n\nvoid set_input_codename(char *codename)\n{\n    if (guess_f && \n        is_inputcode_set &&\n        strcmp(codename, \"\") != 0 && \n        strcmp(codename, input_codename) != 0)\n    {\n        is_inputcode_mixed = TRUE;\n    }\n    input_codename = codename;\n    is_inputcode_set = TRUE;\n}\n\n#if !defined(PERL_XS) && !defined(WIN32DLL)\nvoid print_guessed_code(char *filename)\n{\n    char *codename = \"BINARY\";\n    if (!is_inputcode_mixed) {\n        if (strcmp(input_codename, \"\") == 0) {\n            codename = \"ASCII\";\n        } else {\n            codename = input_codename;\n        }\n    }\n    if (filename != NULL) printf(\"%s:\", filename);\n    printf(\"%s\\n\", codename);\n}\n#endif /*WIN32DLL*/\n\n#ifdef INPUT_OPTION \n\nnkf_char hex_getc(nkf_char ch, FILE *f, nkf_char (*g)(FILE *f), nkf_char (*u)(nkf_char c, FILE *f))\n{\n    nkf_char c1, c2, c3;\n    c1 = (*g)(f);\n    if (c1 != ch){\n        return c1;\n    }\n    c2 = (*g)(f);\n    if (!nkf_isxdigit(c2)){\n        (*u)(c2, f);\n        return c1;\n    }\n    c3 = (*g)(f);\n    if (!nkf_isxdigit(c3)){\n        (*u)(c2, f);\n        (*u)(c3, f);\n        return c1;\n    }\n    return (hex2bin(c2) << 4) | hex2bin(c3);\n}\n\nnkf_char cap_getc(FILE *f)\n{\n    return hex_getc(':', f, i_cgetc, i_cungetc);\n}\n\nnkf_char cap_ungetc(nkf_char c, FILE *f)\n{\n    return (*i_cungetc)(c, f);\n}\n\nnkf_char url_getc(FILE *f)\n{\n    return hex_getc('%', f, i_ugetc, i_uungetc);\n}\n\nnkf_char url_ungetc(nkf_char c, FILE *f)\n{\n    return (*i_uungetc)(c, f);\n}\n#endif\n\n#ifdef NUMCHAR_OPTION\nnkf_char numchar_getc(FILE *f)\n{\n    nkf_char (*g)(FILE *) = i_ngetc;\n    nkf_char (*u)(nkf_char c ,FILE *f) = i_nungetc;\n    int i = 0, j;\n    nkf_char buf[8];\n    long c = -1;\n\n    buf[i] = (*g)(f);\n    if (buf[i] == '&'){\n        buf[++i] = (*g)(f);\n        if (buf[i] == '#'){\n            c = 0;\n            buf[++i] = (*g)(f);\n            if (buf[i] == 'x' || buf[i] == 'X'){\n                for (j = 0; j < 7; j++){\n                    buf[++i] = (*g)(f);\n                    if (!nkf_isxdigit(buf[i])){\n                        if (buf[i] != ';'){\n                            c = -1;\n                        }\n                        break;\n                    }\n                    c <<= 4;\n                    c |= hex2bin(buf[i]);\n                }\n            }else{\n                for (j = 0; j < 8; j++){\n                    if (j){\n                        buf[++i] = (*g)(f);\n                    }\n                    if (!nkf_isdigit(buf[i])){\n                        if (buf[i] != ';'){\n                            c = -1;\n                        }\n                        break;\n                    }\n                    c *= 10;\n                    c += hex2bin(buf[i]);\n                }\n            }\n        }\n    }\n    if (c != -1){\n        return CLASS_UNICODE | c;\n    }\n    while (i > 0){\n        (*u)(buf[i], f);\n        --i;\n    }\n    return buf[0];\n}\n\nnkf_char numchar_ungetc(nkf_char c, FILE *f)\n{\n    return (*i_nungetc)(c, f);\n}\n#endif\n\n#ifdef UNICODE_NORMALIZATION\n\n/* Normalization Form C */\nnkf_char nfc_getc(FILE *f)\n{\n    nkf_char (*g)(FILE *f) = i_nfc_getc;\n    nkf_char (*u)(nkf_char c ,FILE *f) = i_nfc_ungetc;\n    int i=0, j, k=1, lower, upper;\n    nkf_char buf[9];\n    const nkf_nfchar *array;\n#if 0\n    extern const struct normalization_pair normalization_table[];\n#endif\n    \n    buf[i] = (*g)(f);\n    while (k > 0 && ((buf[i] & 0xc0) != 0x80)){\n\tlower=0, upper=NORMALIZATION_TABLE_LENGTH-1;\n\twhile (upper >= lower) {\n\t    j = (lower+upper) / 2;\n\t    array = normalization_table[j].nfd;\n\t    for (k=0; k < NORMALIZATION_TABLE_NFD_LENGTH && array[k]; k++){\n\t\tif (array[k] != buf[k]){\n\t\t    array[k] < buf[k] ? (lower = j + 1) : (upper = j - 1);\n\t\t    k = 0;\n\t\t    break;\n\t\t} else if (k >= i)\n\t\t    buf[++i] = (*g)(f);\n\t    }\n\t    if (k > 0){\n\t\tarray = normalization_table[j].nfc;\n\t\tfor (i=0; i < NORMALIZATION_TABLE_NFC_LENGTH && array[i]; i++)\n\t\t    buf[i] = (nkf_char)(array[i]);\n\t\ti--;\n\t\tbreak;\n\t    }\n\t}\n\twhile (i > 0)\n\t    (*u)(buf[i--], f);\n    }\n    return buf[0];\n}\n\nnkf_char nfc_ungetc(nkf_char c, FILE *f)\n{\n    return (*i_nfc_ungetc)(c, f);\n}\n#endif /* UNICODE_NORMALIZATION */\n\n\nnkf_char \nmime_getc(FILE *f)\n{\n    nkf_char c1, c2, c3, c4, cc;\n    nkf_char t1, t2, t3, t4, mode, exit_mode;\n    nkf_char lwsp_count;\n    char *lwsp_buf;\n    char *lwsp_buf_new;\n    nkf_char lwsp_size = 128;\n\n    if (mime_top != mime_last) {  /* Something is in FIFO */\n        return  Fifo(mime_top++);\n    }\n    if (mime_decode_mode==1 ||mime_decode_mode==FALSE) {\n\tmime_decode_mode=FALSE;\n\tunswitch_mime_getc();\n\treturn (*i_getc)(f);\n    }\n\n    if (mimebuf_f == FIXED_MIME)\n        exit_mode = mime_decode_mode;\n    else\n        exit_mode = FALSE;\n    if (mime_decode_mode == 'Q') {\n        if ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);\nrestart_mime_q:\n        if (c1=='_' && mimebuf_f != FIXED_MIME) return ' ';\n\tif (c1<=' ' || DEL<=c1) {\n\t    mime_decode_mode = exit_mode; /* prepare for quit */\n\t    return c1;\n\t}\n        if (c1!='=' && (c1!='?' || mimebuf_f == FIXED_MIME)) {\n\t    return c1;\n\t}\n                \n        mime_decode_mode = exit_mode; /* prepare for quit */\n        if ((c2 = (*i_mgetc)(f)) == EOF) return (EOF);\n        if (c1=='?'&&c2=='=' && mimebuf_f != FIXED_MIME) {\n            /* end Q encoding */\n            input_mode = exit_mode;\n\t    lwsp_count = 0;\n\t    lwsp_buf = malloc((lwsp_size+5)*sizeof(char));\n\t    if (lwsp_buf==NULL) {\n\t\tperror(\"can't malloc\");\n\t\treturn -1;\n\t    }\n\t    while ((c1=(*i_getc)(f))!=EOF) {\n\t\tswitch (c1) {\n\t\tcase NL:\n\t\tcase CR:\n\t\t    if (c1==NL) {\n\t\t\tif ((c1=(*i_getc)(f))!=EOF && (c1==SPACE||c1==TAB)) {\n\t\t\t    i_ungetc(SPACE,f);\n\t\t\t    continue;\n\t\t\t} else {\n\t\t\t    i_ungetc(c1,f);\n\t\t\t}\n\t\t\tc1 = NL;\n\t\t    } else {\n\t\t\tif ((c1=(*i_getc)(f))!=EOF && c1 == NL) {\n\t\t\t    if ((c1=(*i_getc)(f))!=EOF && (c1==SPACE||c1==TAB)) {\n\t\t\t\ti_ungetc(SPACE,f);\n\t\t\t\tcontinue;\n\t\t\t    } else {\n\t\t\t\ti_ungetc(c1,f);\n\t\t\t    }\n\t\t\t    i_ungetc(NL,f);\n\t\t\t} else {\n\t\t\t    i_ungetc(c1,f);\n\t\t\t}\n\t\t\tc1 = CR;\n\t\t    }\n\t\t    break;\n\t\tcase SPACE:\n\t\tcase TAB:\n\t\t    lwsp_buf[lwsp_count] = (unsigned char)c1;\n\t\t    if (lwsp_count++>lwsp_size){\n\t\t\tlwsp_size <<= 1;\n\t\t\tlwsp_buf_new = realloc(lwsp_buf, (lwsp_size+5)*sizeof(char));\n\t\t\tif (lwsp_buf_new==NULL) {\n\t\t\t    free(lwsp_buf);\n\t\t\t    perror(\"can't realloc\");\n\t\t\t    return -1;\n\t\t\t}\n\t\t\tlwsp_buf = lwsp_buf_new;\n\t\t    }\n\t\t    continue;\n\t\t}\n\t\tbreak;\n\t    }\n\t    if (lwsp_count > 0 && (c1 != '=' || (lwsp_buf[lwsp_count-1] != SPACE && lwsp_buf[lwsp_count-1] != TAB))) {\n\t\ti_ungetc(c1,f);\n\t\tfor(lwsp_count--;lwsp_count>0;lwsp_count--)\n\t\t    i_ungetc(lwsp_buf[lwsp_count],f);\n\t\tc1 = lwsp_buf[0];\n\t    }\n\t    free(lwsp_buf);\n            return c1;\n        }\n        if (c1=='='&&c2<' ') { /* this is soft wrap */\n            while((c1 =  (*i_mgetc)(f)) <=' ') {\n\t\tif ((c1 = (*i_mgetc)(f)) == EOF) return (EOF);\n\t    }\n            mime_decode_mode = 'Q'; /* still in MIME */\n\t    goto restart_mime_q;\n\t}\n        if (c1=='?') {\n            mime_decode_mode = 'Q'; /* still in MIME */\n            (*i_mungetc)(c2,f);\n            return c1;\n        }\n        if ((c3 = (*i_mgetc)(f)) == EOF) return (EOF);\n        if (c2<=' ') return c2;\n        mime_decode_mode = 'Q'; /* still in MIME */\n        return ((hex2bin(c2)<<4) + hex2bin(c3));\n    }\n\n    if (mime_decode_mode != 'B') {\n        mime_decode_mode = FALSE;\n        return (*i_mgetc)(f);\n    }\n\n\n    /* Base64 encoding */\n    /* \n        MIME allows line break in the middle of \n        Base64, but we are very pessimistic in decoding\n        in unbuf mode because MIME encoded code may broken by \n        less or editor's control sequence (such as ESC-[-K in unbuffered\n        mode. ignore incomplete MIME.\n    */\n    mode = mime_decode_mode;\n    mime_decode_mode = exit_mode;  /* prepare for quit */\n\n    while ((c1 = (*i_mgetc)(f))<=' ') {\n        if (c1==EOF)\n            return (EOF);\n    }\nmime_c2_retry:\n    if ((c2 = (*i_mgetc)(f))<=' ') {\n        if (c2==EOF)\n            return (EOF);\n\tif (mime_f != STRICT_MIME) goto mime_c2_retry;\n        if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;  \n        return c2;\n    }\n    if ((c1 == '?') && (c2 == '=')) {\n        input_mode = ASCII;\n\tlwsp_count = 0;\n\tlwsp_buf = malloc((lwsp_size+5)*sizeof(char));\n\tif (lwsp_buf==NULL) {\n\t    perror(\"can't malloc\");\n\t    return -1;\n\t}\n\twhile ((c1=(*i_getc)(f))!=EOF) {\n\t    switch (c1) {\n\t    case NL:\n\t    case CR:\n\t\tif (c1==NL) {\n\t\t    if ((c1=(*i_getc)(f))!=EOF && (c1==SPACE||c1==TAB)) {\n\t\t\ti_ungetc(SPACE,f);\n\t\t\tcontinue;\n\t\t    } else {\n\t\t\ti_ungetc(c1,f);\n\t\t    }\n\t\t    c1 = NL;\n\t\t} else {\n\t\t    if ((c1=(*i_getc)(f))!=EOF) {\n\t\t\tif (c1==SPACE) {\n\t\t\t    i_ungetc(SPACE,f);\n\t\t\t    continue;\n\t\t\t} else if ((c1=(*i_getc)(f))!=EOF && (c1==SPACE||c1==TAB)) {\n\t\t\t    i_ungetc(SPACE,f);\n\t\t\t    continue;\n\t\t\t} else {\n\t\t\t    i_ungetc(c1,f);\n\t\t\t}\n\t\t\ti_ungetc(NL,f);\n\t\t    } else {\n\t\t\ti_ungetc(c1,f);\n\t\t    }\n\t\t    c1 = CR;\n\t\t}\n\t\tbreak;\n\t    case SPACE:\n\t    case TAB:\n\t\tlwsp_buf[lwsp_count] = (unsigned char)c1;\n\t\tif (lwsp_count++>lwsp_size){\n\t\t    lwsp_size <<= 1;\n\t\t    lwsp_buf_new = realloc(lwsp_buf, (lwsp_size+5)*sizeof(char));\n\t\t    if (lwsp_buf_new==NULL) {\n\t\t\tfree(lwsp_buf);\n\t\t\tperror(\"can't realloc\");\n\t\t\treturn -1;\n\t\t    }\n\t\t    lwsp_buf = lwsp_buf_new;\n\t\t}\n\t\tcontinue;\n\t    }\n\t    break;\n\t}\n\tif (lwsp_count > 0 && (c1 != '=' || (lwsp_buf[lwsp_count-1] != SPACE && lwsp_buf[lwsp_count-1] != TAB))) {\n\t    i_ungetc(c1,f);\n\t    for(lwsp_count--;lwsp_count>0;lwsp_count--)\n\t\ti_ungetc(lwsp_buf[lwsp_count],f);\n\t    c1 = lwsp_buf[0];\n\t}\n\tfree(lwsp_buf);\n        return c1;\n    }\nmime_c3_retry:\n    if ((c3 = (*i_mgetc)(f))<=' ') {\n        if (c3==EOF)\n            return (EOF);\n\tif (mime_f != STRICT_MIME) goto mime_c3_retry;\n        if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;  \n        return c3;\n    }\nmime_c4_retry:\n    if ((c4 = (*i_mgetc)(f))<=' ') {\n        if (c4==EOF)\n            return (EOF);\n\tif (mime_f != STRICT_MIME) goto mime_c4_retry;\n        if (mimebuf_f!=FIXED_MIME) input_mode = ASCII;  \n        return c4;\n    }\n\n    mime_decode_mode = mode; /* still in MIME sigh... */\n\n    /* BASE 64 decoding */\n\n    t1 = 0x3f & base64decode(c1);\n    t2 = 0x3f & base64decode(c2);\n    t3 = 0x3f & base64decode(c3);\n    t4 = 0x3f & base64decode(c4);\n    cc = ((t1 << 2) & 0x0fc) | ((t2 >> 4) & 0x03);\n    if (c2 != '=') {\n        Fifo(mime_last++) = (unsigned char)cc;\n        cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f);\n        if (c3 != '=') {\n            Fifo(mime_last++) = (unsigned char)cc;\n            cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f);\n            if (c4 != '=') \n                Fifo(mime_last++) = (unsigned char)cc;\n        }\n    } else {\n        return c1;\n    }\n    return  Fifo(mime_top++);\n}\n\nnkf_char mime_ungetc(nkf_char c, FILE *f)\n{\n    Fifo(--mime_top) = (unsigned char)c;\n    return c;\n}\n\nnkf_char mime_integrity(FILE *f, const unsigned char *p)\n{\n    nkf_char c,d;\n    unsigned int q;\n    /* In buffered mode, read until =? or NL or buffer full\n     */\n    mime_input = mime_top;\n    mime_last = mime_top;\n    \n    while(*p) Fifo(mime_input++) = *p++;\n    d = 0;\n    q = mime_input;\n    while((c=(*i_getc)(f))!=EOF) {\n        if (((mime_input-mime_top)&MIME_BUF_MASK)==0) {\n\t    break;   /* buffer full */\n\t}\n        if (c=='=' && d=='?') {\n            /* checked. skip header, start decode */\n            Fifo(mime_input++) = (unsigned char)c;\n            /* mime_last_input = mime_input; */\n            mime_input = q; \n\t    switch_mime_getc();\n            return 1;\n        }\n        if (!( (c=='+'||c=='/'|| c=='=' || c=='?' || is_alnum(c))))\n            break;\n        /* Should we check length mod 4? */\n        Fifo(mime_input++) = (unsigned char)c;\n        d=c;\n    }\n    /* In case of Incomplete MIME, no MIME decode  */\n    Fifo(mime_input++) = (unsigned char)c;\n    mime_last = mime_input;     /* point undecoded buffer */\n    mime_decode_mode = 1;              /* no decode on Fifo last in mime_getc */\n    switch_mime_getc();         /* anyway we need buffered getc */\n    return 1;\n}\n\nnkf_char base64decode(nkf_char c)\n{\n    int             i;\n    if (c > '@') {\n        if (c < '[') {\n            i = c - 'A';                        /* A..Z 0-25 */\n        } else {\n            i = c - 'G'     /* - 'a' + 26 */ ;  /* a..z 26-51 */\n\t}\n    } else if (c > '/') {\n        i = c - '0' + '4'   /* - '0' + 52 */ ;  /* 0..9 52-61 */\n    } else if (c == '+') {\n        i = '>'             /* 62 */ ;          /* +  62 */\n    } else {\n        i = '?'             /* 63 */ ;          /* / 63 */\n    }\n    return (i);\n}\n\nstatic const char basis_64[] =\n   \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nstatic nkf_char b64c;\n#define MIMEOUT_BUF_LENGTH (60)\nchar mimeout_buf[MIMEOUT_BUF_LENGTH+1];\nint mimeout_buf_count = 0;\nint mimeout_preserve_space = 0;\n#define itoh4(c)   (c>=10?c+'A'-10:c+'0')\n\nvoid open_mime(nkf_char mode)\n{\n    const unsigned char *p;\n    int i;\n    int j;\n    p  = mime_pattern[0];\n    for(i=0;mime_encode[i];i++) {\n\tif (mode == mime_encode[i]) {\n\t    p = mime_pattern[i];\n\t    break;\n\t}\n    }\n    mimeout_mode = mime_encode_method[i];\n    \n    i = 0;\n    if (base64_count>45) {\n\tif (mimeout_buf_count>0 && nkf_isblank(mimeout_buf[i])){\n            (*o_mputc)(mimeout_buf[i]);\n\t    i++;\n\t}\n\t(*o_mputc)(NL);\n\t(*o_mputc)(SPACE);\n\tbase64_count = 1;\n\tif (!mimeout_preserve_space && mimeout_buf_count>0\n\t    && (mimeout_buf[i]==SPACE || mimeout_buf[i]==TAB\n\t    \t|| mimeout_buf[i]==CR || mimeout_buf[i]==NL )) {\n\t    i++;\n\t}\n    }\n    if (!mimeout_preserve_space) {\n\tfor (;i<mimeout_buf_count;i++) {\n\t    if (mimeout_buf[i]==SPACE || mimeout_buf[i]==TAB\n\t\t|| mimeout_buf[i]==CR || mimeout_buf[i]==NL ) {\n\t\t(*o_mputc)(mimeout_buf[i]);\n\t\tbase64_count ++;\n\t    } else {\n\t\tbreak;\n\t    }\n\t}\n    }\n    mimeout_preserve_space = FALSE;\n    \n    while(*p) {\n        (*o_mputc)(*p++);\n        base64_count ++;\n    }\n    j = mimeout_buf_count;\n    mimeout_buf_count = 0;\n    for (;i<j;i++) {\n\tmime_putc(mimeout_buf[i]);\n    }\n}\n\nvoid close_mime(void)\n{\n    (*o_mputc)('?');\n    (*o_mputc)('=');\n    base64_count += 2;\n    mimeout_mode = 0;\n}\n\nvoid eof_mime(void)\n{\n    switch(mimeout_mode) {\n    case 'Q':\n    case 'B':\n\tbreak;\n    case 2:\n\t(*o_mputc)(basis_64[((b64c & 0x3)<< 4)]);\n\t(*o_mputc)('=');\n\t(*o_mputc)('=');\n\tbase64_count += 3;\n\tbreak;\n    case 1:\n\t(*o_mputc)(basis_64[((b64c & 0xF) << 2)]);\n\t(*o_mputc)('=');\n\tbase64_count += 2;\n\tbreak;\n    }\n    if (mimeout_mode) {\n\tif (mimeout_f!=FIXED_MIME) {\n\t    close_mime(); \n\t} else if (mimeout_mode != 'Q')\n\t    mimeout_mode = 'B';\n    }\n}\n\nvoid mimeout_addchar(nkf_char c)\n{\n    switch(mimeout_mode) {\n    case 'Q':\n\tif (c==CR||c==NL) {\n\t    (*o_mputc)(c);\n\t    base64_count = 0;\n\t} else if(!nkf_isalnum(c)) {\n\t    (*o_mputc)('=');\n\t    (*o_mputc)(itoh4(((c>>4)&0xf)));\n\t    (*o_mputc)(itoh4((c&0xf)));\n\t    base64_count += 3;\n\t} else {\n\t    (*o_mputc)(c);\n\t    base64_count++;\n\t}\n        break;\n    case 'B':\n        b64c=c;\n        (*o_mputc)(basis_64[c>>2]);\n        mimeout_mode=2;\n        base64_count ++;\n        break;\n    case 2:\n        (*o_mputc)(basis_64[((b64c & 0x3)<< 4) | ((c & 0xF0) >> 4)]);\n        b64c=c;\n        mimeout_mode=1;\n        base64_count ++;\n        break;\n    case 1:\n        (*o_mputc)(basis_64[((b64c & 0xF) << 2) | ((c & 0xC0) >>6)]);\n        (*o_mputc)(basis_64[c & 0x3F]);\n        mimeout_mode='B';\n        base64_count += 2;\n        break;\n    default:\n\t(*o_mputc)(c);\n\tbase64_count++;\n        break;\n    }\n}\n\nnkf_char mime_lastchar2, mime_lastchar1;\n\nvoid mime_prechar(nkf_char c2, nkf_char c1)\n{\n    if (mimeout_mode){\n        if (c2){\n            if (base64_count + mimeout_buf_count/3*4> 66){\n                (*o_base64conv)(EOF,0);\n                (*o_base64conv)(0,NL);\n                (*o_base64conv)(0,SPACE);\n            }\n        }/*else if (mime_lastchar2){\n            if (c1 <=DEL && !nkf_isspace(c1)){\n                (*o_base64conv)(0,SPACE);\n            }\n        }*/\n    }/*else{\n        if (c2 && mime_lastchar2 == 0\n            && mime_lastchar1 && !nkf_isspace(mime_lastchar1)){\n            (*o_base64conv)(0,SPACE);\n        }\n    }*/\n    mime_lastchar2 = c2;\n    mime_lastchar1 = c1;\n}\n\nvoid mime_putc(nkf_char c)\n{\n    int i, j;\n    nkf_char lastchar;\n\n    if (mimeout_f == FIXED_MIME){\n        if (mimeout_mode == 'Q'){\n            if (base64_count > 71){\n                if (c!=CR && c!=NL) {\n                    (*o_mputc)('=');\n                    (*o_mputc)(NL);\n                }\n                base64_count = 0;\n            }\n        }else{\n            if (base64_count > 71){\n                eof_mime();\n                (*o_mputc)(NL);\n                base64_count = 0;\n            }\n            if (c == EOF) { /* c==EOF */\n                eof_mime();\n            }\n        }\n        if (c != EOF) { /* c==EOF */\n            mimeout_addchar(c);\n        }\n        return;\n    }\n    \n    /* mimeout_f != FIXED_MIME */\n\n    if (c == EOF) { /* c==EOF */\n\tj = mimeout_buf_count;\n\tmimeout_buf_count = 0;\n\ti = 0;\n\tif (mimeout_mode) {\n\t    for (;i<j;i++) {\n\t\tif (nkf_isspace(mimeout_buf[i]) && base64_count < 71){\n\t\t    break;\n\t\t}\n\t\tmimeout_addchar(mimeout_buf[i]);\n\t    }\n\t    eof_mime();\n\t    for (;i<j;i++) {\n\t\tmimeout_addchar(mimeout_buf[i]);\n\t    }\n\t} else {\n\t    for (;i<j;i++) {\n\t\tmimeout_addchar(mimeout_buf[i]);\n\t    }\n\t}\n        return;\n    }\n\n    if (mimeout_mode=='Q') {\n        if (c <= DEL && (output_mode==ASCII ||output_mode == ISO8859_1 ) ) {\n            if (c <= SPACE) {\n                close_mime();\n                (*o_mputc)(SPACE);\n                base64_count++;\n            }\n            (*o_mputc)(c);\n            base64_count++;\n        }\n        return;\n    }\n\n    if (mimeout_buf_count > 0){\n        lastchar = mimeout_buf[mimeout_buf_count - 1];\n    }else{\n        lastchar = -1;\n    }\n\n    if (!mimeout_mode) {\n        if (c <= DEL && (output_mode==ASCII ||output_mode == ISO8859_1)) {\n            if (nkf_isspace(c)) {\n                if (c==CR || c==NL) {\n                    base64_count=0;\n                }\n                for (i=0;i<mimeout_buf_count;i++) {\n                    (*o_mputc)(mimeout_buf[i]);\n                    if (mimeout_buf[i] == CR || mimeout_buf[i] == NL){\n                        base64_count = 0;\n                    }else{\n                        base64_count++;\n                    }\n                }\n                mimeout_buf[0] = (char)c;\n                mimeout_buf_count = 1;\n            }else{\n                if (base64_count > 1\n                    && base64_count + mimeout_buf_count > 76){\n                    (*o_mputc)(NL);\n                    base64_count = 0;\n                    if (!nkf_isspace(mimeout_buf[0])){\n                        (*o_mputc)(SPACE);\n                        base64_count++;\n                    }\n                }\n                mimeout_buf[mimeout_buf_count++] = (char)c;\n                if (mimeout_buf_count>MIMEOUT_BUF_LENGTH) {\n                    open_mime(output_mode);\n                }\n            }\n            return;\n        }else{\n            if (lastchar==CR || lastchar == NL){\n                for (i=0;i<mimeout_buf_count;i++) {\n                    (*o_mputc)(mimeout_buf[i]);\n                }\n                base64_count = 0;\n                mimeout_buf_count = 0;\n            }\n            if (lastchar==SPACE) {\n                for (i=0;i<mimeout_buf_count-1;i++) {\n                    (*o_mputc)(mimeout_buf[i]);\n                    base64_count++;\n                }\n                mimeout_buf[0] = SPACE;\n                mimeout_buf_count = 1;\n            }\n            open_mime(output_mode);\n        }\n    }else{\n        /* mimeout_mode == 'B', 1, 2 */\n        if ( c<=DEL && (output_mode==ASCII ||output_mode == ISO8859_1 ) ) {\n            if (lastchar == CR || lastchar == NL){\n                if (nkf_isblank(c)) {\n                    for (i=0;i<mimeout_buf_count;i++) {\n                        mimeout_addchar(mimeout_buf[i]);\n                    }\n                    mimeout_buf_count = 0;\n                } else if (SPACE<c && c<DEL) {\n                    eof_mime();\n                    for (i=0;i<mimeout_buf_count;i++) {\n                        (*o_mputc)(mimeout_buf[i]);\n                    }\n                    base64_count = 0;\n                    mimeout_buf_count = 0;\n                }\n            }\n            if (c==SPACE || c==TAB || c==CR || c==NL) {\n                for (i=0;i<mimeout_buf_count;i++) {\n                    if (SPACE<mimeout_buf[i] && mimeout_buf[i]<DEL) {\n                        eof_mime();\n                        for (i=0;i<mimeout_buf_count;i++) {\n                            (*o_mputc)(mimeout_buf[i]);\n                            base64_count++;\n                        }\n                        mimeout_buf_count = 0;\n                    }\n                }\n                mimeout_buf[mimeout_buf_count++] = (char)c;\n                if (mimeout_buf_count>MIMEOUT_BUF_LENGTH) {\n                    eof_mime();\n                    for (i=0;i<mimeout_buf_count;i++) {\n                        (*o_mputc)(mimeout_buf[i]);\n                        base64_count++;\n                    }\n                    mimeout_buf_count = 0;\n                }\n                return;\n            }\n            if (mimeout_buf_count>0 && SPACE<c && c!='=') {\n                mimeout_buf[mimeout_buf_count++] = (char)c;\n                if (mimeout_buf_count>MIMEOUT_BUF_LENGTH) {\n                    j = mimeout_buf_count;\n                    mimeout_buf_count = 0;\n                    for (i=0;i<j;i++) {\n                        mimeout_addchar(mimeout_buf[i]);\n                    }\n                }\n                return;\n            }\n        }\n    }\n    if (mimeout_buf_count>0) {\n\tj = mimeout_buf_count;\n\tmimeout_buf_count = 0;\n\tfor (i=0;i<j;i++) {\n\t    if (mimeout_buf[i]==CR || mimeout_buf[i]==NL)\n\t\tbreak;\n\t    mimeout_addchar(mimeout_buf[i]);\n\t}\n\tif (i<j) {\n\t    eof_mime();\n\t    base64_count=0;\n\t    for (;i<j;i++) {\n\t\t(*o_mputc)(mimeout_buf[i]);\n\t    }\n\t    open_mime(output_mode);\n\t}\n    }\n    mimeout_addchar(c);\n}\n\n\n#if defined(PERL_XS) || defined(WIN32DLL)\nvoid reinit(void)\n{\n    {\n        struct input_code *p = input_code_list;\n        while (p->name){\n            status_reinit(p++);\n        }\n    }\n    unbuf_f = FALSE;\n    estab_f = FALSE;\n    nop_f = FALSE;\n    binmode_f = TRUE;\n    rot_f = FALSE;\n    hira_f = FALSE;\n    input_f = FALSE;\n    alpha_f = FALSE;\n    mime_f = STRICT_MIME;\n    mime_decode_f = FALSE;\n    mimebuf_f = FALSE;\n    broken_f = FALSE;\n    iso8859_f = FALSE;\n    mimeout_f = FALSE;\n#if defined(MSDOS) || defined(__OS2__)\n     x0201_f = TRUE;\n#else\n     x0201_f = NO_X0201;\n#endif\n    iso2022jp_f = FALSE;\n#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)\n    ms_ucs_map_f = UCS_MAP_ASCII;\n#endif\n#ifdef UTF8_INPUT_ENABLE\n    no_cp932ext_f = FALSE;\n    no_best_fit_chars_f = FALSE;\n    encode_fallback = NULL;\n    unicode_subchar  = '?';\n    input_endian = ENDIAN_BIG;\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n    output_bom_f = FALSE;\n    output_endian = ENDIAN_BIG;\n#endif\n#ifdef UNICODE_NORMALIZATION\n    nfc_f = FALSE;\n#endif\n#ifdef INPUT_OPTION\n    cap_f = FALSE;\n    url_f = FALSE;\n    numchar_f = FALSE;\n#endif\n#ifdef CHECK_OPTION\n    noout_f = FALSE;\n    debug_f = FALSE;\n#endif\n    guess_f = FALSE;\n    is_inputcode_mixed = FALSE;\n    is_inputcode_set   = FALSE;\n#ifdef EXEC_IO\n    exec_f = 0;\n#endif\n#ifdef SHIFTJIS_CP932\n    cp51932_f = TRUE;\n    cp932inv_f = TRUE;\n#endif\n#ifdef X0212_ENABLE\n    x0212_f = FALSE;\n    x0213_f = FALSE;\n#endif\n    {\n        int i;\n        for (i = 0; i < 256; i++){\n            prefix_table[i] = 0;\n        }\n    }\n    hold_count = 0;\n    mimeout_buf_count = 0;\n    mimeout_mode = 0;\n    base64_count = 0;\n    f_line = 0;\n    f_prev = 0;\n    fold_preserve_f = FALSE;\n    fold_f = FALSE;\n    fold_len = 0;\n    kanji_intro = DEFAULT_J;\n    ascii_intro = DEFAULT_R;\n    fold_margin  = FOLD_MARGIN;\n    output_conv = DEFAULT_CONV;\n    oconv = DEFAULT_CONV;\n    o_zconv = no_connection;\n    o_fconv = no_connection;\n    o_crconv = no_connection;\n    o_rot_conv = no_connection;\n    o_hira_conv = no_connection;\n    o_base64conv = no_connection;\n    o_iso2022jp_check_conv = no_connection;\n    o_putc = std_putc;\n    i_getc = std_getc;\n    i_ungetc = std_ungetc;\n    i_bgetc = std_getc;\n    i_bungetc = std_ungetc;\n    o_mputc = std_putc;\n    i_mgetc = std_getc;\n    i_mungetc  = std_ungetc;\n    i_mgetc_buf = std_getc;\n    i_mungetc_buf = std_ungetc;\n    output_mode = ASCII;\n    input_mode =  ASCII;\n    shift_mode =  FALSE;\n    mime_decode_mode = FALSE;\n    file_out_f = FALSE;\n    crmode_f = 0;\n    option_mode = 0;\n    broken_counter = 0;\n    broken_last = 0;\n    z_prev2=0,z_prev1=0;\n#ifdef CHECK_OPTION\n    iconv_for_check = 0;\n#endif\n    input_codename = \"\";\n#ifdef WIN32DLL\n    reinitdll();\n#endif /*WIN32DLL*/\n}\n#endif\n\nvoid no_connection(nkf_char c2, nkf_char c1)\n{\n    no_connection2(c2,c1,0);\n}\n\nnkf_char no_connection2(nkf_char c2, nkf_char c1, nkf_char c0)\n{\n    fprintf(stderr,\"nkf internal module connection failure.\\n\");\n    exit(1);\n    return 0; /* LINT */\n}\n\n#ifndef PERL_XS\n#ifdef WIN32DLL\n#define fprintf dllprintf\n#endif\nvoid usage(void)\n{\n    fprintf(stderr,\"USAGE:  nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\\n\");\n    fprintf(stderr,\"Flags:\\n\");\n    fprintf(stderr,\"b,u      Output is buffered (DEFAULT),Output is unbuffered\\n\");\n#ifdef DEFAULT_CODE_SJIS\n    fprintf(stderr,\"j,s,e,w  Output code is JIS 7 bit, Shift_JIS (DEFAULT), EUC-JP, UTF-8N\\n\");\n#endif\n#ifdef DEFAULT_CODE_JIS\n    fprintf(stderr,\"j,s,e,w  Output code is JIS 7 bit (DEFAULT), Shift JIS, EUC-JP, UTF-8N\\n\");\n#endif\n#ifdef DEFAULT_CODE_EUC\n    fprintf(stderr,\"j,s,e,w  Output code is JIS 7 bit, Shift JIS, EUC-JP (DEFAULT), UTF-8N\\n\");\n#endif\n#ifdef DEFAULT_CODE_UTF8\n    fprintf(stderr,\"j,s,e,w  Output code is JIS 7 bit, Shift JIS, EUC-JP, UTF-8N (DEFAULT)\\n\");\n#endif\n#ifdef UTF8_OUTPUT_ENABLE\n    fprintf(stderr,\"         After 'w' you can add more options. -w[ 8 [0], 16 [[BL] [0]] ]\\n\");\n#endif\n    fprintf(stderr,\"J,S,E,W  Input assumption is JIS 7 bit , Shift JIS, EUC-JP, UTF-8\\n\");\n#ifdef UTF8_INPUT_ENABLE\n    fprintf(stderr,\"         After 'W' you can add more options. -W[ 8, 16 [BL] ] \\n\");\n#endif\n    fprintf(stderr,\"t        no conversion\\n\");\n    fprintf(stderr,\"i[@B]    Specify the Esc Seq for JIS X 0208-1978/83 (DEFAULT B)\\n\");\n    fprintf(stderr,\"o[BJH]   Specify the Esc Seq for ASCII/Roman        (DEFAULT B)\\n\");\n    fprintf(stderr,\"r        {de/en}crypt ROT13/47\\n\");\n    fprintf(stderr,\"h        1 katakana->hiragana, 2 hiragana->katakana, 3 both\\n\");\n    fprintf(stderr,\"v        Show this usage. V: show version\\n\");\n    fprintf(stderr,\"m[BQN0]  MIME decode [B:base64,Q:quoted,N:non-strict,0:no decode]\\n\");\n    fprintf(stderr,\"M[BQ]    MIME encode [B:base64 Q:quoted]\\n\");\n    fprintf(stderr,\"l        ISO8859-1 (Latin-1) support\\n\");\n    fprintf(stderr,\"f/F      Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\\n\");\n    fprintf(stderr,\"Z[0-3]   Convert X0208 alphabet to ASCII\\n\");\n    fprintf(stderr,\"         1: Kankaku to 1 space  2: to 2 spaces  3: Convert to HTML Entity\\n\");\n    fprintf(stderr,\"X,x      Assume X0201 kana in MS-Kanji, -x preserves X0201\\n\");\n    fprintf(stderr,\"B[0-2]   Broken input  0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\\n\");\n#ifdef MSDOS\n    fprintf(stderr,\"T        Text mode output\\n\");\n#endif\n    fprintf(stderr,\"O        Output to File (DEFAULT 'nkf.out')\\n\");\n    fprintf(stderr,\"I        Convert non ISO-2022-JP charactor to GETA\\n\");\n    fprintf(stderr,\"d,c      Convert line breaks  -d: LF  -c: CRLF\\n\");\n    fprintf(stderr,\"-L[uwm]  line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\\n\");\n    fprintf(stderr,\"\\n\");\n    fprintf(stderr,\"Long name options\\n\");\n    fprintf(stderr,\" --ic=<input codeset>  --oc=<output codeset>\\n\");\n    fprintf(stderr,\"                   Specify the input or output codeset\\n\");\n    fprintf(stderr,\" --fj  --unix --mac  --windows\\n\");\n    fprintf(stderr,\" --jis  --euc  --sjis  --utf8  --utf16  --mime  --base64\\n\");\n    fprintf(stderr,\"                   Convert for the system or code\\n\");\n    fprintf(stderr,\" --hiragana  --katakana  --katakana-hiragana\\n\");\n    fprintf(stderr,\"                   To Hiragana/Katakana Conversion\\n\");\n    fprintf(stderr,\" --prefix=         Insert escape before troublesome characters of Shift_JIS\\n\");\n#ifdef INPUT_OPTION\n    fprintf(stderr,\" --cap-input, --url-input  Convert hex after ':' or '%%'\\n\");\n#endif\n#ifdef NUMCHAR_OPTION\n    fprintf(stderr,\" --numchar-input   Convert Unicode Character Reference\\n\");\n#endif\n#ifdef UTF8_INPUT_ENABLE\n    fprintf(stderr,\" --fb-{skip, html, xml, perl, java, subchar}\\n\");\n    fprintf(stderr,\"                   Specify how nkf handles unassigned characters\\n\");\n#endif\n#ifdef OVERWRITE\n    fprintf(stderr,\" --in-place[=SUFFIX]  --overwrite[=SUFFIX]\\n\");\n    fprintf(stderr,\"                   Overwrite original listed files by filtered result\\n\");\n    fprintf(stderr,\"                   --overwrite preserves timestamp of original files\\n\");\n#endif\n    fprintf(stderr,\" -g  --guess       Guess the input code\\n\");\n    fprintf(stderr,\" --help  --version Show this help/the version\\n\");\n    fprintf(stderr,\"                   For more information, see also man nkf\\n\");\n    fprintf(stderr,\"\\n\");\n    version();\n}\n\nvoid version(void)\n{\n    fprintf(stderr,\"Network Kanji Filter Version %s (%s) \"\n#if defined(MSDOS) && !defined(__WIN32__) && !defined(__WIN16__) && !defined(__OS2__)\n                  \"for DOS\"\n#endif\n#if defined(MSDOS) && defined(__WIN16__)\n                  \"for Win16\"\n#endif\n#if defined(MSDOS) && defined(__WIN32__)\n                  \"for Win32\"\n#endif\n#ifdef __OS2__\n                  \"for OS/2\"\n#endif\n                  ,NKF_VERSION,NKF_RELEASE_DATE);\n    fprintf(stderr,\"\\n%s\\n\",CopyRight);\n}\n#endif /*PERL_XS*/\n\n/**\n ** \u001b$B%Q%C%A@):n<T\u001b(B\n **  void@merope.pleiades.or.jp (Kusakabe Youichi)\n **  NIDE Naoyuki <nide@ics.nara-wu.ac.jp>\n **  ohta@src.ricoh.co.jp (Junn Ohta)\n **  inouet@strl.nhk.or.jp (Tomoyuki Inoue)\n **  kiri@pulser.win.or.jp (Tetsuaki Kiriyama)\n **  Kimihiko Sato <sato@sail.t.u-tokyo.ac.jp>\n **  a_kuroe@kuroe.aoba.yokohama.jp (Akihiko Kuroe)\n **  kono@ie.u-ryukyu.ac.jp (Shinji Kono)\n **  GHG00637@nifty-serve.or.jp (COW)\n **\n **/\n\n/* end */\n"
  },
  {
    "path": "ext/nkf/nkf-utf8/utf8tbl.c",
    "content": "#include \"config.h\"\n\n#ifdef UTF8_OUTPUT_ENABLE\nconst unsigned short euc_to_utf8_A1[] = {\n         0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A,\n 0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8,\n 0xFF3E, 0x203E, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003,\n 0x4EDD, 0x3005, 0x3006, 0x3007, 0x30FC, 0x2014, 0x2010, 0xFF0F,\n 0xFF3C, 0x301C, 0x2016, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019,\n 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D,\n 0xFF5B, 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D,\n 0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, 0x2212, 0x00B1, 0x00D7,\n 0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E,\n 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0x00A5,\n 0xFF04, 0x00A2, 0x00A3, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20,\n 0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7,\n};\n\n/* Microsoft UCS Mapping Compatible */\nconst unsigned short euc_to_utf8_A1_ms[] = {\n         0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A,\n 0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8,\n 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003,\n 0x4EDD, 0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F,\n 0xFF3C, 0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019,\n 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D,\n 0xFF5B, 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D,\n 0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7,\n 0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E,\n 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5,\n 0xFF04, 0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20,\n 0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7,\n};\nconst unsigned short euc_to_utf8_A2[] = {\n         0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC,\n 0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283,\n 0x222A, 0x2229,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2227, 0x2228, 0x00AC, 0x21D2, 0x21D4, 0x2200,\n 0x2203,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x2220, 0x22A5, 0x2312, 0x2202,\n 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D,\n 0x2235, 0x222B, 0x222C,      0,      0,      0,      0,      0,\n      0,      0, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020,\n 0x2021, 0x00B6,      0,      0,      0,      0, 0x25EF,\n};\n\n/* Microsoft UCS Mapping Compatible */\nconst unsigned short euc_to_utf8_A2_ms[] = {\n         0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC,\n 0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283,\n 0x222A, 0x2229,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2227, 0x2228, 0xFFE2, 0x21D2, 0x21D4, 0x2200,\n 0x2203,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x2220, 0x22A5, 0x2312, 0x2202,\n 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D,\n 0x2235, 0x222B, 0x222C,      0,      0,      0,      0,      0,\n      0,      0, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020,\n 0x2021, 0x00B6,      0,      0,      0,      0, 0x25EF,\n};\nconst unsigned short euc_to_utf8_A3[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17,\n 0xFF18, 0xFF19,      0,      0,      0,      0,      0,      0,\n      0, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27,\n 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F,\n 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37,\n 0xFF38, 0xFF39, 0xFF3A,      0,      0,      0,      0,      0,\n      0, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,\n 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,\n 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,\n 0xFF58, 0xFF59, 0xFF5A,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_A4[] = {\n         0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047,\n 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F,\n 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057,\n 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F,\n 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067,\n 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F,\n 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077,\n 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F,\n 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087,\n 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F,\n 0x3090, 0x3091, 0x3092, 0x3093,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_A5[] = {\n         0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7,\n 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF,\n 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7,\n 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF,\n 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7,\n 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF,\n 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7,\n 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF,\n 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7,\n 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF,\n 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_A6[] = {\n         0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,\n 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,\n 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8,\n 0x03A9,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,\n 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,\n 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,\n 0x03C9,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_A7[] = {\n         0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401,\n 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D,\n 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425,\n 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D,\n 0x042E, 0x042F,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451,\n 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D,\n 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,\n 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D,\n 0x044E, 0x044F,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_A8[] = {\n         0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C,\n 0x252C, 0x2524, 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513,\n 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520,\n 0x252F, 0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538,\n 0x2542,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_A9[] = {\n         0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466,\n 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E,\n 0x246F, 0x2470, 0x2471, 0x2472, 0x2473,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x2474,\n 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C,\n 0x247D, 0x247E, 0x247F, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484,\n 0x2485, 0x2486, 0x2487,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x2776, 0x2777, 0x2778,\n 0x2779, 0x277A, 0x277B, 0x277C, 0x277D, 0x277E,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D,\n 0x248E, 0x248F, 0x2490,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_AA[] = {\n         0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166,\n 0x2167, 0x2168, 0x2169, 0x216A, 0x216B,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x2170, 0x2171, 0x2172,\n 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A,\n 0x217B,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x249C, 0x249D, 0x249E,\n 0x249F, 0x24A0, 0x24A1, 0x24A2, 0x24A3, 0x24A4, 0x24A5, 0x24A6,\n 0x24A7, 0x24A8, 0x24A9, 0x24AA, 0x24AB, 0x24AC, 0x24AD, 0x24AE,\n 0x24AF, 0x24B0, 0x24B1, 0x24B2, 0x24B3, 0x24B4, 0x24B5,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_AB[] = {\n         0x339C, 0x339F, 0x339D, 0x33A0, 0x33A4,      0, 0x33A1,\n 0x33A5, 0x339E, 0x33A2, 0x338E,      0, 0x338F, 0x33C4, 0x3396,\n 0x3397, 0x2113, 0x3398, 0x33B3, 0x33B2, 0x33B1, 0x33B0, 0x2109,\n 0x33D4, 0x33CB, 0x3390, 0x3385, 0x3386, 0x3387,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x2116, 0x33CD, 0x2121,      0,\n};\nconst unsigned short euc_to_utf8_AC[] = {\n         0x2664, 0x2667, 0x2661, 0x2662, 0x2660, 0x2663, 0x2665,\n 0x2666,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x3020, 0x260E, 0x3004,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x261E, 0x261C, 0x261D, 0x261F, 0x21C6, 0x21C4, 0x21C5,\n      0, 0x21E8, 0x21E6, 0x21E7, 0x21E9,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_AD[] = {\n         0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466,\n 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E,\n 0x246F, 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162,\n 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169,      0,\n 0x3349, 0x3314, 0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336,\n 0x3351, 0x3357, 0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B,\n 0x339C, 0x339D, 0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x337B,\n 0x301D, 0x301F, 0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6,\n 0x32A7, 0x32A8, 0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C,\n 0x2252, 0x2261, 0x222B, 0x222E, 0x2211, 0x221A, 0x22A5, 0x2220,\n 0x221F, 0x22BF, 0x2235, 0x2229, 0x222A,      0, 0x3299,\n};\nconst unsigned short euc_to_utf8_AE[] = {\n         0x3349, 0x3322, 0x334D, 0x3314, 0x3316, 0x3305, 0x3333,\n 0x334E, 0x3303, 0x3336, 0x3318, 0x3315, 0x3327, 0x3351, 0x334A,\n 0x3339, 0x3357, 0x330D, 0x3342, 0x3323, 0x3326, 0x333B, 0x332B,\n      0,      0,      0,      0,      0,      0,      0, 0x3300,\n 0x331E, 0x332A, 0x3331, 0x3347,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x337E,\n 0x337D, 0x337C, 0x337B,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x337F,      0,      0,\n};\nconst unsigned short euc_to_utf8_AF[] = {\n         0x222E, 0x221F, 0x22BF,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x301D, 0x301F,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x3094,      0, 0x30F7, 0x30F8, 0x30F9, 0x30FA,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_B0[] = {\n         0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0, 0x611B, 0x6328,\n 0x59F6, 0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25,\n 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, 0x65A1, 0x6271,\n 0x5B9B, 0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE, 0x9B8E, 0x6216,\n 0x7C9F, 0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7,\n 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, 0x5049, 0x56F2,\n 0x5937, 0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F, 0x6170, 0x6613,\n 0x6905, 0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3,\n 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, 0x4E95, 0x4EA5,\n 0x57DF, 0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1, 0x6EA2, 0x9038,\n 0x7A32, 0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1,\n 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, 0x852D,\n};\nconst unsigned short euc_to_utf8_B1[] = {\n         0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87,\n 0x70CF, 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11,\n 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B,\n 0x59E5, 0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B,\n 0x96F2, 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620,\n 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E,\n 0x9834, 0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA,\n 0x99C5, 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186,\n 0x5712, 0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4,\n 0x6CBF, 0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01,\n 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC,\n 0x6C5A, 0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC,\n};\nconst unsigned short euc_to_utf8_B2[] = {\n         0x62BC, 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1,\n 0x8956, 0x9D2C, 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104,\n 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378,\n 0x6069, 0x6E29, 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55,\n 0x4F3D, 0x4FA1, 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1,\n 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3,\n 0x706B, 0x73C2, 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB,\n 0x8304, 0x8377, 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8,\n 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259,\n 0x753B, 0x81E5, 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5,\n 0x4ECB, 0x4F1A, 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB,\n 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539,\n};\nconst unsigned short euc_to_utf8_B3[] = {\n         0x9B41, 0x6666, 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686,\n 0x7D75, 0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, 0x52BE,\n 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, 0x6982, 0x6DAF, 0x788D,\n 0x84CB, 0x8857, 0x8A72, 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9,\n 0x57A3, 0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, 0x5ED3,\n 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, 0x7372, 0x78BA, 0x7A6B,\n 0x899A, 0x89D2, 0x8D6B, 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769,\n 0x5B66, 0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, 0x6A2B,\n 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, 0x5272, 0x559D, 0x6070, 0x62EC,\n 0x6D3B, 0x6E07, 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39,\n 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, 0x7AC3, 0x84B2,\n 0x91DC, 0x938C, 0x565B, 0x9D28, 0x6822, 0x8305, 0x8431,\n};\nconst unsigned short euc_to_utf8_B4[] = {\n         0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E, 0x4F83, 0x51A0,\n 0x5BD2, 0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6,\n 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, 0x611F, 0x6163,\n 0x61BE, 0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA, 0x6B3E, 0x6B53,\n 0x6C57, 0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B,\n 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, 0x809D, 0x8266,\n 0x839E, 0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451, 0x9593, 0x9591,\n 0x95A2, 0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8,\n 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, 0x8D0B, 0x96C1,\n 0x9811, 0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371, 0x559C, 0x5668,\n 0x57FA, 0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC,\n 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, 0x68C4,\n};\nconst unsigned short euc_to_utf8_B5[] = {\n         0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948,\n 0x5B63, 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77,\n 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100,\n 0x5993, 0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591,\n 0x7947, 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0,\n 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775,\n 0x9ECD, 0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45,\n 0x4EC7, 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551,\n 0x673D, 0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE,\n 0x7B08, 0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45,\n 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD,\n 0x92F8, 0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC,\n};\nconst unsigned short euc_to_utf8_B6[] = {\n         0x4F9B, 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6,\n 0x5354, 0x5321, 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37,\n 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1,\n 0x72C2, 0x72ED, 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7,\n 0x93E1, 0x97FF, 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681,\n 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5,\n 0x52E4, 0x5747, 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434,\n 0x7981, 0x79BD, 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F,\n 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5,\n 0x533A, 0x72D7, 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8,\n 0x99D2, 0x5177, 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3,\n 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48,\n};\nconst unsigned short euc_to_utf8_B7[] = {\n         0x6398, 0x7A9F, 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A,\n 0x9688, 0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, 0x541B,\n 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, 0x5366, 0x8888, 0x7941,\n 0x4FC2, 0x50BE, 0x5211, 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B,\n 0x5951, 0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, 0x63B2,\n 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, 0x7566, 0x7A3D, 0x7CFB,\n 0x7D4C, 0x7D99, 0x7E4B, 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08,\n 0x8A63, 0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, 0x9BE8,\n 0x5287, 0x621F, 0x6483, 0x6FC0, 0x9699, 0x6841, 0x5091, 0x6B20,\n 0x6C7A, 0x6F54, 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6,\n 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, 0x5263, 0x55A7, 0x570F,\n 0x5805, 0x5ACC, 0x5EFA, 0x61B2, 0x61F8, 0x62F3, 0x6372,\n};\nconst unsigned short euc_to_utf8_B8[] = {\n         0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E, 0x7814, 0x786F,\n 0x7D79, 0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063,\n 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, 0x539F, 0x53B3,\n 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE, 0x7D43, 0x8237,\n 0x8A00, 0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA,\n 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, 0x6545, 0x67AF,\n 0x6E56, 0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1, 0x83F0, 0x864E,\n 0x8A87, 0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92,\n 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, 0x5FA1, 0x609F,\n 0x68A7, 0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4, 0x8B77, 0x9190,\n 0x4E5E, 0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149,\n 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, 0x5411,\n};\nconst unsigned short euc_to_utf8_B9[] = {\n         0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D,\n 0x5B8F, 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7,\n 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602,\n 0x6643, 0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A,\n 0x6D69, 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0,\n 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1,\n 0x8154, 0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2,\n 0x8CFC, 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D,\n 0x9805, 0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408,\n 0x58D5, 0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B,\n 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09,\n 0x8170, 0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC,\n};\nconst unsigned short euc_to_utf8_BA[] = {\n         0x6B64, 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A,\n 0x6068, 0x61C7, 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5,\n 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F,\n 0x5DE6, 0x5DEE, 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396,\n 0x88DF, 0x5750, 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700,\n 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D,\n 0x6B73, 0x6E08, 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D,\n 0x658E, 0x7D30, 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728,\n 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A,\n 0x80B4, 0x54B2, 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A,\n 0x548B, 0x643E, 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22,\n 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237,\n};\nconst unsigned short euc_to_utf8_BB[] = {\n         0x5BDF, 0x62F6, 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9,\n 0x96D1, 0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, 0x6652,\n 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, 0x6492, 0x6563, 0x685F,\n 0x71E6, 0x73CA, 0x7523, 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB,\n 0x9178, 0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A,\n 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, 0x56DB, 0x58EB, 0x59CB,\n 0x59C9, 0x59FF, 0x5B50, 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D,\n 0x6307, 0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, 0x6B62,\n 0x6B7B, 0x6C0F, 0x7345, 0x7949, 0x79C1, 0x7CF8, 0x7D19, 0x7D2B,\n 0x80A2, 0x8102, 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C,\n 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, 0x4E8B, 0x4F3C,\n 0x4F8D, 0x5150, 0x5B57, 0x5BFA, 0x6148, 0x6301, 0x6642,\n};\nconst unsigned short euc_to_utf8_BC[] = {\n         0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD, 0x75D4, 0x78C1,\n 0x793A, 0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F,\n 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, 0x96EB, 0x4E03,\n 0x53F1, 0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089, 0x6E7F, 0x6F06,\n 0x75BE, 0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D,\n 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, 0x6368, 0x8D66,\n 0x659C, 0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D, 0x8ECA, 0x906E,\n 0x86C7, 0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235,\n 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, 0x60F9, 0x4E3B,\n 0x53D6, 0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9, 0x73E0, 0x7A2E,\n 0x816B, 0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF,\n 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, 0x5468,\n};\nconst unsigned short euc_to_utf8_BD[] = {\n         0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32,\n 0x79C0, 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490,\n 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C,\n 0x96C6, 0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E,\n 0x67D4, 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4,\n 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F,\n 0x51FA, 0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3,\n 0x821C, 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3,\n 0x6E96, 0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806,\n 0x51E6, 0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2,\n 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973,\n 0x5E8F, 0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F,\n};\nconst unsigned short euc_to_utf8_BE[] = {\n         0x52DD, 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531,\n 0x5617, 0x5968, 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11,\n 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB,\n 0x638C, 0x6377, 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2,\n 0x6A1F, 0x6A35, 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126,\n 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0,\n 0x7B11, 0x7CA7, 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D,\n 0x88F3, 0x8A1F, 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4,\n 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E,\n 0x4E57, 0x5197, 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38,\n 0x60C5, 0x64FE, 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63,\n 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE,\n};\nconst unsigned short euc_to_utf8_BF[] = {\n         0x62ED, 0x690D, 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272,\n 0x89E6, 0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, 0x4FB5,\n 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, 0x614E, 0x632F, 0x65B0,\n 0x664B, 0x68EE, 0x699B, 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F,\n 0x795E, 0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, 0x8A3A,\n 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, 0x4EBA, 0x4EC1, 0x5203,\n 0x5875, 0x58EC, 0x5C0B, 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5,\n 0x9663, 0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, 0x53A8,\n 0x9017, 0x5439, 0x5782, 0x5E25, 0x63A8, 0x6C34, 0x708A, 0x7761,\n 0x7C8B, 0x7FE0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F,\n 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, 0x8DA8, 0x96DB,\n 0x636E, 0x6749, 0x6919, 0x83C5, 0x9817, 0x96C0, 0x88FE,\n};\nconst unsigned short euc_to_utf8_C0[] = {\n         0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C, 0x755D, 0x662F,\n 0x51C4, 0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F,\n 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, 0x6E05, 0x7272,\n 0x751F, 0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD, 0x897F, 0x8AA0,\n 0x8A93, 0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E,\n 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, 0x6614, 0x6790,\n 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC, 0x8D64, 0x8DE1,\n 0x8E5F, 0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D,\n 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, 0x8749, 0x4ED9,\n 0x5148, 0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16, 0x5DDD, 0x6226,\n 0x6247, 0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3,\n 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, 0x7DDA,\n};\nconst unsigned short euc_to_utf8_C1[] = {\n         0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E,\n 0x8CCE, 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE,\n 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3,\n 0x7CCE, 0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A,\n 0x72D9, 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20,\n 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275,\n 0x53CC, 0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B,\n 0x5C64, 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB,\n 0x64CD, 0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5,\n 0x4E89, 0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061,\n 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001,\n 0x906D, 0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E,\n};\nconst unsigned short euc_to_utf8_C2[] = {\n         0x81D3, 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247,\n 0x5373, 0x606F, 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7,\n 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3,\n 0x5B58, 0x5B6B, 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A,\n 0x592A, 0x6C70, 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253,\n 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806,\n 0x5BFE, 0x8010, 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234,\n 0x66FF, 0x6CF0, 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8,\n 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927,\n 0x7B2C, 0x918D, 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544,\n 0x5B85, 0x6258, 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17,\n 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA,\n};\nconst unsigned short euc_to_utf8_C3[] = {\n         0x53E9, 0x4F46, 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD,\n 0x7AEA, 0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, 0x8AB0,\n 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, 0x63A2, 0x65E6, 0x6B4E,\n 0x6DE1, 0x6E5B, 0x70AD, 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D,\n 0x80C6, 0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, 0x65AD,\n 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, 0x5024, 0x77E5, 0x5730,\n 0x5F1B, 0x6065, 0x667A, 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4,\n 0x8718, 0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, 0x84C4,\n 0x9010, 0x79E9, 0x7A92, 0x8336, 0x5AE1, 0x7740, 0x4E2D, 0x4EF2,\n 0x5B99, 0x5FE0, 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877,\n 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, 0x732A, 0x82E7,\n 0x8457, 0x8CAF, 0x4E01, 0x5146, 0x51CB, 0x558B, 0x5BF5,\n};\nconst unsigned short euc_to_utf8_C4[] = {\n         0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35, 0x5F6B, 0x5FB4,\n 0x61F2, 0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A,\n 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, 0x8D85, 0x8DF3,\n 0x929A, 0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357, 0x76F4, 0x6715,\n 0x6C88, 0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E,\n 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, 0x6802, 0x63B4,\n 0x69FB, 0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526, 0x7DB4, 0x9354,\n 0x693F, 0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A,\n 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, 0x5243, 0x8C9E,\n 0x5448, 0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F,\n 0x608C, 0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E,\n 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, 0x9013,\n};\nconst unsigned short euc_to_utf8_C5[] = {\n         0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2,\n 0x6575, 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2,\n 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929,\n 0x5C55, 0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B,\n 0x70B9, 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410,\n 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21,\n 0x767B, 0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A,\n 0x52AA, 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC,\n 0x51CD, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6,\n 0x5D8B, 0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF,\n 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8,\n 0x7977, 0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230,\n};\nconst unsigned short euc_to_utf8_C6[] = {\n         0x8463, 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F,\n 0x9003, 0x900F, 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD,\n 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3,\n 0x7AE5, 0x80F4, 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F,\n 0x5F97, 0x5FB3, 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2,\n 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A,\n 0x9CF6, 0x82EB, 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7,\n 0x6566, 0x6C8C, 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D,\n 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058,\n 0x637A, 0x934B, 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960,\n 0x8EDF, 0x96E3, 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302,\n 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165,\n};\nconst unsigned short euc_to_utf8_C7[] = {\n         0x5982, 0x5C3F, 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D,\n 0x6FE1, 0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, 0x5E74,\n 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, 0x4E43, 0x5EFC, 0x4E4B,\n 0x57DC, 0x56A2, 0x60A9, 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF,\n 0x8FB2, 0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, 0x6777,\n 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, 0x7F75, 0x82AD, 0x99AC,\n 0x4FF3, 0x5EC3, 0x62DD, 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C,\n 0x80CC, 0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, 0x6885,\n 0x6973, 0x7164, 0x72FD, 0x8CB7, 0x58F2, 0x8CE0, 0x966A, 0x9019,\n 0x877F, 0x79E4, 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD,\n 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, 0x8584, 0x8FEB,\n 0x66DD, 0x6F20, 0x7206, 0x7E1B, 0x83AB, 0x99C1, 0x9EA6,\n};\nconst unsigned short euc_to_utf8_C8[] = {\n         0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087, 0x7B48, 0x6AE8,\n 0x5E61, 0x808C, 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A,\n 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, 0x95A5, 0x9CE9,\n 0x567A, 0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224, 0x534A, 0x53CD,\n 0x53DB, 0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248,\n 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, 0x8CA9, 0x7BC4,\n 0x91C6, 0x7169, 0x9812, 0x98EF, 0x633D, 0x6669, 0x756A, 0x76E4,\n 0x78D0, 0x8543, 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87,\n 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, 0x6BD4, 0x6CCC,\n 0x75B2, 0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77, 0x80A5, 0x88AB,\n 0x8AB9, 0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099,\n 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, 0x7F8E,\n};\nconst unsigned short euc_to_utf8_C9[] = {\n         0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66,\n 0x819D, 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C,\n 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A,\n 0x6A19, 0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79,\n 0x5EDF, 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C,\n 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7,\n 0x8CD3, 0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B,\n 0x5A66, 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577,\n 0x65A7, 0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299,\n 0x8B5C, 0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB,\n 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8,\n 0x847A, 0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D,\n};\nconst unsigned short euc_to_utf8_CA[] = {\n         0x798F, 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255,\n 0x6CB8, 0x4ECF, 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3,\n 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0,\n 0x6587, 0x805E, 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73,\n 0x5F0A, 0x67C4, 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801,\n 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86,\n 0x504F, 0x5909, 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D,\n 0x4FBF, 0x52C9, 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA,\n 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF,\n 0x5893, 0x6155, 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023,\n 0x4FF8, 0x5305, 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF,\n 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B,\n};\nconst unsigned short euc_to_utf8_CB[] = {\n         0x6CD5, 0x6CE1, 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3,\n 0x840C, 0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, 0x92D2,\n 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, 0x508D, 0x5256, 0x574A,\n 0x59A8, 0x5E3D, 0x5FD8, 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0,\n 0x68D2, 0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, 0x8CBF,\n 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, 0x50D5, 0x535C, 0x58A8,\n 0x64B2, 0x6734, 0x7267, 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1,\n 0x6B86, 0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, 0x76C6,\n 0x6469, 0x78E8, 0x9B54, 0x9EBB, 0x57CB, 0x59B9, 0x6627, 0x679A,\n 0x6BCE, 0x54E9, 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE,\n 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, 0x672B, 0x6CAB,\n 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, 0x4E07, 0x6162, 0x6E80,\n};\nconst unsigned short euc_to_utf8_CC[] = {\n         0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45, 0x5DF3, 0x7B95,\n 0x5CAC, 0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999,\n 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, 0x725F, 0x77DB,\n 0x9727, 0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5, 0x540D, 0x547D,\n 0x660E, 0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5,\n 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, 0x6478, 0x6A21,\n 0x8302, 0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2, 0x7DB2, 0x8017,\n 0x8499, 0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905,\n 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, 0x7D0B, 0x9580,\n 0x5301, 0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036, 0x91CE, 0x5F25,\n 0x77E2, 0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756,\n 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, 0x7652,\n};\nconst unsigned short euc_to_utf8_CD[] = {\n         0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB,\n 0x5BA5, 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67,\n 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A,\n 0x9091, 0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E,\n 0x8A89, 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8,\n 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6,\n 0x7194, 0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981,\n 0x8B21, 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32,\n 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8,\n 0x6765, 0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A,\n 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7,\n 0x5229, 0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483,\n};\nconst unsigned short euc_to_utf8_CE[] = {\n         0x75E2, 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B,\n 0x7387, 0x7ACB, 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C,\n 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6,\n 0x616E, 0x65C5, 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC,\n 0x5BEE, 0x6599, 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C,\n 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B,\n 0x7DD1, 0x502B, 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8,\n 0x8F2A, 0x96A3, 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F,\n 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C,\n 0x73B2, 0x793C, 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97,\n 0x9F62, 0x66A6, 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9,\n 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F,\n};\nconst unsigned short euc_to_utf8_CF[] = {\n         0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089,\n 0x8CC2, 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, 0x6717,\n 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001,\n 0x807E, 0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332,\n 0x8AD6, 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, 0x60D1,\n 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568,\n 0x6900, 0x6E7E, 0x7897, 0x8155,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_D0[] = {\n         0x5F0C, 0x4E10, 0x4E15, 0x4E2A, 0x4E31, 0x4E36, 0x4E3C,\n 0x4E3F, 0x4E42, 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A,\n 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, 0x4EA2, 0x4EB0,\n 0x4EB3, 0x4EB6, 0x4ECE, 0x4ECD, 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7,\n 0x4EDE, 0x4EED, 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B,\n 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, 0x4F98, 0x4F7B,\n 0x4F69, 0x4F70, 0x4F91, 0x4F6F, 0x4F86, 0x4F96, 0x5118, 0x4FD4,\n 0x4FDF, 0x4FCE, 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4,\n 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, 0x5005, 0x4F1C,\n 0x4FF6, 0x5021, 0x5029, 0x502C, 0x4FFE, 0x4FEF, 0x5011, 0x5006,\n 0x5043, 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056,\n 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, 0x50B2,\n};\nconst unsigned short euc_to_utf8_D1[] = {\n         0x50C9, 0x50CA, 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5,\n 0x50ED, 0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, 0x5102,\n 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, 0x513A, 0x5137, 0x513C,\n 0x513B, 0x513F, 0x5140, 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8,\n 0x5169, 0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, 0x5189,\n 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, 0x51A4, 0x51A6, 0x51A2,\n 0x51A9, 0x51AA, 0x51AB, 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5,\n 0x51BD, 0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, 0x51ED,\n 0x51F0, 0x51F5, 0x51FE, 0x5204, 0x520B, 0x5214, 0x520E, 0x5227,\n 0x522A, 0x522E, 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C,\n 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, 0x5273, 0x527F, 0x527D,\n 0x528D, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8FA8,\n};\nconst unsigned short euc_to_utf8_D2[] = {\n         0x8FA7, 0x52AC, 0x52AD, 0x52BC, 0x52B5, 0x52C1, 0x52CD,\n 0x52D7, 0x52DE, 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5,\n 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, 0x5310, 0x530F,\n 0x5315, 0x531A, 0x5323, 0x532F, 0x5331, 0x5333, 0x5338, 0x5340,\n 0x5346, 0x5345, 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369,\n 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, 0x53A0, 0x53A6,\n 0x53A5, 0x53AE, 0x53B0, 0x53B6, 0x53C3, 0x7C12, 0x96D9, 0x53DF,\n 0x66FC, 0x71EE, 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D,\n 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, 0x5429, 0x541D,\n 0x544E, 0x548F, 0x5475, 0x548E, 0x545F, 0x5471, 0x5477, 0x5470,\n 0x5492, 0x547B, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7,\n 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, 0x54A8,\n};\nconst unsigned short euc_to_utf8_D3[] = {\n         0x54AB, 0x54C2, 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5,\n 0x54E6, 0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, 0x54E2,\n 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, 0x555C, 0x5545, 0x5556,\n 0x5557, 0x5538, 0x5533, 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A,\n 0x559F, 0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, 0x5583,\n 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, 0x55DF, 0x55C4, 0x55DC,\n 0x55E4, 0x55D4, 0x5614, 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B,\n 0x55F9, 0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, 0x5638,\n 0x566B, 0x5664, 0x562F, 0x566C, 0x566A, 0x5686, 0x5680, 0x568A,\n 0x56A0, 0x5694, 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2,\n 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, 0x56D1, 0x56D3,\n 0x56D7, 0x56EE, 0x56F9, 0x5700, 0x56FF, 0x5704, 0x5709,\n};\nconst unsigned short euc_to_utf8_D4[] = {\n         0x5708, 0x570B, 0x570D, 0x5713, 0x5718, 0x5716, 0x55C7,\n 0x571C, 0x5726, 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F,\n 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, 0x5793, 0x57A0,\n 0x57B3, 0x57A4, 0x57AA, 0x57B0, 0x57C3, 0x57C6, 0x57D4, 0x57D2,\n 0x57D3, 0x580A, 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872,\n 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, 0x583D, 0x5879,\n 0x5885, 0x58B9, 0x589F, 0x58AB, 0x58BA, 0x58DE, 0x58BB, 0x58B8,\n 0x58AE, 0x58C5, 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5,\n 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, 0x58FB, 0x58FC,\n 0x58FD, 0x5902, 0x590A, 0x5910, 0x591B, 0x68A6, 0x5925, 0x592C,\n 0x592D, 0x5932, 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E,\n 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, 0x5969,\n};\nconst unsigned short euc_to_utf8_D5[] = {\n         0x5978, 0x5981, 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2,\n 0x59C6, 0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, 0x5A1F,\n 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, 0x5A6C, 0x5A49, 0x5A35,\n 0x5A36, 0x5A62, 0x5A6A, 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2,\n 0x5ABD, 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, 0x5AFB,\n 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, 0x5B2A, 0x5B36, 0x5B3E,\n 0x5B43, 0x5B45, 0x5B40, 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65,\n 0x5B69, 0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, 0x5B80,\n 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0,\n 0x5BE4, 0x5BE6, 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6,\n 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, 0x5C20, 0x5C22,\n 0x5C28, 0x5C38, 0x5C39, 0x5C41, 0x5C46, 0x5C4E, 0x5C53,\n};\nconst unsigned short euc_to_utf8_D6[] = {\n         0x5C50, 0x5C4F, 0x5B71, 0x5C6C, 0x5C6E, 0x4E62, 0x5C76,\n 0x5C79, 0x5C8C, 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6,\n 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, 0x5CE9, 0x5CFD,\n 0x5CFA, 0x5CED, 0x5D8C, 0x5CEA, 0x5D0B, 0x5D15, 0x5D17, 0x5D5C,\n 0x5D1F, 0x5D1B, 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18,\n 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, 0x5D76, 0x5D87,\n 0x5D84, 0x5D82, 0x5DA2, 0x5D9D, 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90,\n 0x5DB7, 0x5DBC, 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB,\n 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, 0x5E11, 0x5E1B,\n 0x5E36, 0x5E37, 0x5E44, 0x5E43, 0x5E40, 0x5E4E, 0x5E57, 0x5E54,\n 0x5E5F, 0x5E62, 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC,\n 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, 0x5ECF,\n};\nconst unsigned short euc_to_utf8_D7[] = {\n         0x5ED6, 0x5EE3, 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1,\n 0x5EE8, 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, 0x5EF8,\n 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, 0x5F0B, 0x5F11, 0x5F16,\n 0x5F29, 0x5F2D, 0x5F38, 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F,\n 0x5F51, 0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, 0x5F77,\n 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, 0x5F91, 0x5F87, 0x5F9E,\n 0x5F99, 0x5F98, 0x5FA0, 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB,\n 0x5FE4, 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, 0x6060,\n 0x6019, 0x6010, 0x6029, 0x600E, 0x6031, 0x601B, 0x6015, 0x602B,\n 0x6026, 0x600F, 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F,\n 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, 0x6064, 0x6042, 0x606C,\n 0x606B, 0x6059, 0x6081, 0x608D, 0x60E7, 0x6083, 0x609A,\n};\nconst unsigned short euc_to_utf8_D8[] = {\n         0x6084, 0x609B, 0x6096, 0x6097, 0x6092, 0x60A7, 0x608B,\n 0x60E1, 0x60B8, 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6,\n 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, 0x60F7, 0x6100,\n 0x60F4, 0x60FA, 0x6103, 0x6121, 0x60FB, 0x60F1, 0x610D, 0x610E,\n 0x6147, 0x613E, 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C,\n 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159,\n 0x615A, 0x616B, 0x6174, 0x616F, 0x6165, 0x6171, 0x615F, 0x615D,\n 0x6153, 0x6175, 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A,\n 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, 0x61C9, 0x61F7,\n 0x61C8, 0x61C3, 0x61C6, 0x61BA, 0x61CB, 0x7F79, 0x61CD, 0x61E6,\n 0x61E3, 0x61F6, 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE,\n 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, 0x621B,\n};\nconst unsigned short euc_to_utf8_D9[] = {\n         0x621E, 0x6221, 0x622A, 0x622E, 0x6230, 0x6232, 0x6233,\n 0x6241, 0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, 0x627C,\n 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, 0x6296, 0x62D4, 0x6283,\n 0x6294, 0x62D7, 0x62D1, 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4,\n 0x62C8, 0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, 0x62C9,\n 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, 0x6308, 0x62EF, 0x62F5,\n 0x6350, 0x633E, 0x634D, 0x641C, 0x634F, 0x6396, 0x638E, 0x6380,\n 0x63AB, 0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, 0x636B,\n 0x6369, 0x63BE, 0x63E9, 0x63C0, 0x63C6, 0x63E3, 0x63C9, 0x63D2,\n 0x63F6, 0x63C4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436,\n 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, 0x646F, 0x6476, 0x644E,\n 0x652A, 0x6495, 0x6493, 0x64A5, 0x64A9, 0x6488, 0x64BC,\n};\nconst unsigned short euc_to_utf8_DA[] = {\n         0x64DA, 0x64D2, 0x64C5, 0x64C7, 0x64BB, 0x64D8, 0x64C2,\n 0x64F1, 0x64E7, 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF,\n 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, 0x64FD, 0x6518,\n 0x651C, 0x6505, 0x6524, 0x6523, 0x652B, 0x6534, 0x6535, 0x6537,\n 0x6536, 0x6538, 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558,\n 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, 0x8B8A, 0x659B,\n 0x659F, 0x65AB, 0x65B7, 0x65C3, 0x65C6, 0x65C1, 0x65C4, 0x65CC,\n 0x65D2, 0x65DB, 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A,\n 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, 0x661C, 0x664F,\n 0x6644, 0x6649, 0x6641, 0x665E, 0x665D, 0x6664, 0x6667, 0x6668,\n 0x665F, 0x6662, 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684,\n 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, 0x66BC,\n};\nconst unsigned short euc_to_utf8_DB[] = {\n         0x66C4, 0x66B8, 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6,\n 0x66E9, 0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, 0x6726,\n 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, 0x6741, 0x6738, 0x6737,\n 0x6746, 0x675E, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770,\n 0x67A9, 0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, 0x6785,\n 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, 0x67E9, 0x67B8, 0x67E4,\n 0x67DE, 0x67DD, 0x67E2, 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7,\n 0x6A9C, 0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, 0x684E,\n 0x68B3, 0x682B, 0x6859, 0x6863, 0x6877, 0x687F, 0x689F, 0x688F,\n 0x68AD, 0x6894, 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874,\n 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, 0x6901, 0x68CA,\n 0x6908, 0x68D8, 0x6922, 0x6926, 0x68E1, 0x690C, 0x68CD,\n};\nconst unsigned short euc_to_utf8_DC[] = {\n         0x68D4, 0x68E7, 0x68D5, 0x6936, 0x6912, 0x6904, 0x68D7,\n 0x68E3, 0x6925, 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A,\n 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, 0x6978, 0x696B,\n 0x6954, 0x697E, 0x696E, 0x6939, 0x6974, 0x693D, 0x6959, 0x6930,\n 0x6961, 0x695E, 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0,\n 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, 0x69CA, 0x69DD,\n 0x69BB, 0x69C3, 0x69A7, 0x6A2E, 0x6991, 0x69A0, 0x699C, 0x6995,\n 0x69B4, 0x69DE, 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9,\n 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, 0x6A14, 0x69EB,\n 0x6A0A, 0x6A12, 0x6AC1, 0x6A23, 0x6A13, 0x6A44, 0x6A0C, 0x6A72,\n 0x6A36, 0x6A78, 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38,\n 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, 0x6AA3,\n};\nconst unsigned short euc_to_utf8_DD[] = {\n         0x6A97, 0x8617, 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3,\n 0x6AAC, 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, 0x6AFB,\n 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, 0x9B31, 0x6B1F, 0x6B38,\n 0x6B37, 0x76DC, 0x6B39, 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50,\n 0x6B59, 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, 0x6B7F,\n 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, 0x6B95, 0x6B9E, 0x6BA4,\n 0x6BAA, 0x6BAB, 0x6BAF, 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC,\n 0x6BC6, 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, 0x6BEF,\n 0x9EBE, 0x6C08, 0x6C13, 0x6C14, 0x6C1B, 0x6C24, 0x6C23, 0x6C5E,\n 0x6C55, 0x6C62, 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B,\n 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, 0x6CF1, 0x6CD3,\n 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, 0x6CAE, 0x6CB1, 0x6CBE,\n};\nconst unsigned short euc_to_utf8_DE[] = {\n         0x6CBA, 0x6CDB, 0x6CEF, 0x6CD9, 0x6CEA, 0x6D1F, 0x884D,\n 0x6D36, 0x6D2B, 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12,\n 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, 0x6D59, 0x6D8E,\n 0x6D95, 0x6FE4, 0x6D85, 0x6DF9, 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7,\n 0x6DE6, 0x6DB8, 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2,\n 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, 0x6DEE, 0x6E2D,\n 0x6E6E, 0x6E2E, 0x6E19, 0x6E72, 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B,\n 0x6E2B, 0x6E76, 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24,\n 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, 0x6EC9, 0x6EB7,\n 0x6ED3, 0x6EBD, 0x6EAF, 0x6EC4, 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F,\n 0x6EA5, 0x6EC2, 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8,\n 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, 0x6ECC,\n};\nconst unsigned short euc_to_utf8_DF[] = {\n         0x6F3E, 0x6F13, 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81,\n 0x6F80, 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, 0x6F58,\n 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, 0x6FA3, 0x6FA1, 0x6FA4,\n 0x6FB9, 0x6FC6, 0x6FAA, 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8,\n 0x6FF1, 0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, 0x7001,\n 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, 0x701D, 0x7018, 0x701F,\n 0x7030, 0x703E, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF,\n 0x70F1, 0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, 0x70DD,\n 0x70D9, 0x7109, 0x70FD, 0x711C, 0x7119, 0x7165, 0x7155, 0x7188,\n 0x7166, 0x7162, 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184,\n 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, 0x71D2, 0x71C9,\n 0x71D4, 0x71CE, 0x71E0, 0x71EC, 0x71E7, 0x71F5, 0x71FC,\n};\nconst unsigned short euc_to_utf8_E0[] = {\n         0x71F9, 0x71FF, 0x720D, 0x7210, 0x721B, 0x7228, 0x722D,\n 0x722C, 0x7230, 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246,\n 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, 0x7287, 0x7292,\n 0x7296, 0x72A2, 0x72A7, 0x72B9, 0x72B2, 0x72C3, 0x72C6, 0x72C4,\n 0x72CE, 0x72D2, 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F,\n 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, 0x732F, 0x7329,\n 0x7325, 0x733E, 0x734E, 0x734F, 0x9ED8, 0x7357, 0x736A, 0x7368,\n 0x7370, 0x7378, 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE,\n 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, 0x7405, 0x746F,\n 0x7425, 0x73F8, 0x7432, 0x743A, 0x7455, 0x743F, 0x745F, 0x7459,\n 0x7441, 0x745C, 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E,\n 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, 0x73F1,\n};\nconst unsigned short euc_to_utf8_E1[] = {\n         0x74E0, 0x74E3, 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0,\n 0x74F1, 0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, 0x750E,\n 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, 0x752C, 0x753C, 0x7544,\n 0x754D, 0x754A, 0x7549, 0x755B, 0x7546, 0x755A, 0x7569, 0x7564,\n 0x7567, 0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574,\n 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, 0x759D, 0x75A5, 0x75A3,\n 0x75C2, 0x75B3, 0x75C3, 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1,\n 0x75CD, 0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, 0x75FF,\n 0x75FC, 0x7601, 0x75F0, 0x75FA, 0x75F2, 0x75F3, 0x760B, 0x760D,\n 0x7609, 0x761F, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634,\n 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, 0x765C, 0x7658, 0x7661,\n 0x7662, 0x7668, 0x7669, 0x766A, 0x7667, 0x766C, 0x7670,\n};\nconst unsigned short euc_to_utf8_E2[] = {\n         0x7672, 0x7676, 0x7678, 0x767C, 0x7680, 0x7683, 0x7688,\n 0x768B, 0x768E, 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4,\n 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, 0x76D2, 0x76DE,\n 0x76E1, 0x76E5, 0x76E7, 0x76EA, 0x862F, 0x76FB, 0x7708, 0x7707,\n 0x7704, 0x7729, 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737,\n 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, 0x7765, 0x777F,\n 0x777E, 0x7779, 0x778E, 0x778B, 0x7791, 0x77A0, 0x779E, 0x77B0,\n 0x77B6, 0x77B9, 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD,\n 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, 0x780C, 0x7812,\n 0x7926, 0x7820, 0x792A, 0x7845, 0x788E, 0x7874, 0x7886, 0x787C,\n 0x789A, 0x788C, 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6,\n 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, 0x78EC,\n};\nconst unsigned short euc_to_utf8_E3[] = {\n         0x78E7, 0x78DA, 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911,\n 0x7919, 0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, 0x795A,\n 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, 0x799D, 0x79A7, 0x9F4B,\n 0x79AA, 0x79AE, 0x79B3, 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7,\n 0x79EC, 0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, 0x7A20,\n 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, 0x7A37, 0x7A43, 0x7A57,\n 0x7A49, 0x7A61, 0x7A62, 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D,\n 0x7A88, 0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, 0x7AB0,\n 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, 0x9083, 0x7AC7, 0x7ACA, 0x7ACD,\n 0x7ACF, 0x7AD5, 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2,\n 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, 0x7B06, 0x7B33,\n 0x7B18, 0x7B19, 0x7B1E, 0x7B35, 0x7B28, 0x7B36, 0x7B50,\n};\nconst unsigned short euc_to_utf8_E4[] = {\n         0x7B7A, 0x7B04, 0x7B4D, 0x7B0B, 0x7B4C, 0x7B45, 0x7B75,\n 0x7B65, 0x7B74, 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D,\n 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, 0x7B92, 0x7B8F,\n 0x7B5D, 0x7B99, 0x7BCB, 0x7BC1, 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6,\n 0x7BDD, 0x7BE9, 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00,\n 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, 0x7BF6, 0x7C23,\n 0x7C27, 0x7C2A, 0x7C1F, 0x7C37, 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43,\n 0x7C54, 0x7C4F, 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56,\n 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, 0x7CAD, 0x7CA2,\n 0x7CAB, 0x7CA1, 0x7CA8, 0x7CB3, 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9,\n 0x7CBD, 0x7CC0, 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2,\n 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, 0x7D06,\n};\nconst unsigned short euc_to_utf8_E5[] = {\n         0x7D02, 0x7D1C, 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E,\n 0x7D32, 0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, 0x7D72,\n 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, 0x7D89, 0x7D5B, 0x7D8F,\n 0x7D7D, 0x7D9B, 0x7DBA, 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD,\n 0x7DAB, 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, 0x7DB0,\n 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, 0x7DF2, 0x7DE1, 0x7E05,\n 0x7E0A, 0x7E23, 0x7E21, 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B,\n 0x7E22, 0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, 0x7E37,\n 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, 0x7E56, 0x7E5E, 0x7E59, 0x7E5A,\n 0x7E79, 0x7E6A, 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D,\n 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, 0x7E90, 0x7E93,\n 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, 0x7E9C, 0x7F38, 0x7F3A,\n};\nconst unsigned short euc_to_utf8_E6[] = {\n         0x7F45, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F50, 0x7F51, 0x7F55,\n 0x7F54, 0x7F58, 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78,\n 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, 0x7F94, 0x7F9E,\n 0x7F9D, 0x7F9A, 0x7FA3, 0x7FAF, 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6,\n 0x7FB8, 0x8B71, 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1,\n 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, 0x8004, 0x800B,\n 0x8012, 0x8018, 0x8019, 0x801C, 0x8021, 0x8028, 0x803F, 0x803B,\n 0x804A, 0x8046, 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068,\n 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, 0x807F, 0x8084,\n 0x8086, 0x8085, 0x809B, 0x8093, 0x809A, 0x80AD, 0x5190, 0x80AC,\n 0x80DB, 0x80E5, 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109,\n 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, 0x814B,\n};\nconst unsigned short euc_to_utf8_E7[] = {\n         0x968B, 0x8146, 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171,\n 0x816E, 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, 0x8180,\n 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, 0x815F, 0x8193, 0x81A9,\n 0x81B0, 0x81B5, 0x81BE, 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA,\n 0x81C9, 0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, 0x81DF,\n 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, 0x8201, 0x8202, 0x8205,\n 0x8207, 0x820A, 0x820D, 0x8210, 0x8216, 0x8229, 0x822B, 0x8238,\n 0x8233, 0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, 0x8264,\n 0x8262, 0x8268, 0x826A, 0x826B, 0x822E, 0x8271, 0x8277, 0x8278,\n 0x827E, 0x828D, 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1,\n 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, 0x8393, 0x8303,\n 0x82FB, 0x82F9, 0x82DE, 0x8306, 0x82DC, 0x8309, 0x82D9,\n};\nconst unsigned short euc_to_utf8_E8[] = {\n         0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339,\n 0x8350, 0x8345, 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A,\n 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, 0x8387, 0x838A,\n 0x837C, 0x83B5, 0x8373, 0x8375, 0x83A0, 0x8389, 0x83A8, 0x83F4,\n 0x8413, 0x83EB, 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1,\n 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, 0x8420, 0x83BD,\n 0x8438, 0x8506, 0x83FB, 0x846D, 0x842A, 0x843C, 0x855A, 0x8484,\n 0x8477, 0x846B, 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C,\n 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, 0x84BF, 0x849F,\n 0x84D9, 0x84CD, 0x84BB, 0x84DA, 0x84D0, 0x84C1, 0x84C6, 0x84D6,\n 0x84A1, 0x8521, 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F,\n 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, 0x8548,\n};\nconst unsigned short euc_to_utf8_E9[] = {\n         0x8541, 0x8602, 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588,\n 0x8591, 0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, 0x8587,\n 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, 0x85BA, 0x85CF, 0x85B9,\n 0x85D0, 0x85D5, 0x85DD, 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613,\n 0x860B, 0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, 0x863F,\n 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, 0x8671, 0x8693, 0x86A3,\n 0x86A9, 0x86AA, 0x868B, 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6,\n 0x86B0, 0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, 0x86EC,\n 0x86DF, 0x86DB, 0x86EF, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703,\n 0x86FB, 0x8711, 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F,\n 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, 0x8760, 0x875F, 0x8778,\n 0x874C, 0x874E, 0x8774, 0x8757, 0x8768, 0x876E, 0x8759,\n};\nconst unsigned short euc_to_utf8_EA[] = {\n         0x8753, 0x8763, 0x876A, 0x8805, 0x87A2, 0x879F, 0x8782,\n 0x87AF, 0x87CB, 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4,\n 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, 0x87E0, 0x880F,\n 0x880D, 0x87FE, 0x87F6, 0x87F7, 0x880E, 0x87D2, 0x8811, 0x8816,\n 0x8815, 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B,\n 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, 0x886B, 0x8881,\n 0x887E, 0x889E, 0x8875, 0x887D, 0x88B5, 0x8872, 0x8882, 0x8897,\n 0x8892, 0x88AE, 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF,\n 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, 0x88DD, 0x88F9,\n 0x8902, 0x88FC, 0x88F4, 0x88E8, 0x88F2, 0x8904, 0x890C, 0x890A,\n 0x8913, 0x8943, 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944,\n 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, 0x895E,\n};\nconst unsigned short euc_to_utf8_EB[] = {\n         0x8966, 0x8964, 0x896D, 0x896A, 0x896F, 0x8974, 0x8977,\n 0x897E, 0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, 0x89A9,\n 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, 0x89BD, 0x89BF, 0x89C0,\n 0x89DA, 0x89DC, 0x89DD, 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16,\n 0x8A10, 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, 0x8A5B,\n 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, 0x8A6C, 0x8A62, 0x8A85,\n 0x8A82, 0x8A84, 0x8AA8, 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A,\n 0x8AA3, 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, 0x8AE7,\n 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB,\n 0x8B0C, 0x8B07, 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20,\n 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, 0x8B41, 0x8B4C,\n 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, 0x8B5B, 0x8B5A, 0x8B6B,\n};\nconst unsigned short euc_to_utf8_EC[] = {\n         0x8B5F, 0x8B6C, 0x8B6F, 0x8B74, 0x8B7D, 0x8B80, 0x8B8C,\n 0x8B8E, 0x8B92, 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41,\n 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, 0x8C62, 0x8C6C,\n 0x8C78, 0x8C7A, 0x8C82, 0x8C89, 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E,\n 0x8C94, 0x8C7C, 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2,\n 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, 0x8CE3, 0x8CDA,\n 0x8CFD, 0x8CFA, 0x8CFB, 0x8D04, 0x8D05, 0x8D0A, 0x8D07, 0x8D0F,\n 0x8D0D, 0x8D10, 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67,\n 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, 0x8DBE, 0x8DBA,\n 0x8DCF, 0x8DDA, 0x8DD6, 0x8DCC, 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB,\n 0x8DDF, 0x8DE3, 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E,\n 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, 0x8E4A,\n};\nconst unsigned short euc_to_utf8_ED[] = {\n         0x8E47, 0x8E49, 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64,\n 0x8E60, 0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, 0x8E81,\n 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, 0x8E93, 0x8E91, 0x8E94,\n 0x8E99, 0x8EAA, 0x8EA1, 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE,\n 0x8EC5, 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, 0x8EEB,\n 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, 0x8F19, 0x8F13, 0x8F1C,\n 0x8F1F, 0x8F1B, 0x8F0C, 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45,\n 0x8F42, 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, 0x8F5C,\n 0x8F62, 0x8F63, 0x8F64, 0x8F9C, 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF,\n 0x8FB7, 0x8FDA, 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4,\n 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, 0x900D, 0x901E,\n 0x9016, 0x900B, 0x9027, 0x9036, 0x9035, 0x9039, 0x8FF8,\n};\nconst unsigned short euc_to_utf8_EE[] = {\n         0x904F, 0x9050, 0x9051, 0x9052, 0x900E, 0x9049, 0x903E,\n 0x9056, 0x9058, 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072,\n 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, 0x908F, 0x90A8,\n 0x90AF, 0x90B1, 0x90B5, 0x90E2, 0x90E4, 0x6248, 0x90DB, 0x9102,\n 0x9112, 0x9119, 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163,\n 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, 0x9182, 0x91A2,\n 0x91AB, 0x91AF, 0x91AA, 0x91B5, 0x91B4, 0x91BA, 0x91C0, 0x91C1,\n 0x91C9, 0x91CB, 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC,\n 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, 0x9215, 0x9211,\n 0x925E, 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923F,\n 0x924B, 0x9250, 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF,\n 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, 0x932E,\n};\nconst unsigned short euc_to_utf8_EF[] = {\n         0x9319, 0x9322, 0x931A, 0x9323, 0x933A, 0x9335, 0x933B,\n 0x935C, 0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, 0x93AD,\n 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, 0x93E5, 0x93D8, 0x93C3,\n 0x93DD, 0x93D0, 0x93C8, 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403,\n 0x9407, 0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, 0x9441,\n 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, 0x945E, 0x946A, 0x9229,\n 0x9470, 0x9475, 0x9477, 0x947D, 0x945A, 0x947C, 0x947E, 0x9481,\n 0x947F, 0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, 0x9599,\n 0x95A0, 0x95A8, 0x95A7, 0x95AD, 0x95BC, 0x95BB, 0x95B9, 0x95BE,\n 0x95CA, 0x6FF6, 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6,\n 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, 0x962E, 0x962F,\n 0x9642, 0x964C, 0x964F, 0x964B, 0x9677, 0x965C, 0x965E,\n};\nconst unsigned short euc_to_utf8_F0[] = {\n         0x965D, 0x965F, 0x9666, 0x9672, 0x966C, 0x968D, 0x9698,\n 0x9695, 0x9697, 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4,\n 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, 0x96CD, 0x894D,\n 0x96DC, 0x970D, 0x96D5, 0x96F9, 0x9704, 0x9706, 0x9708, 0x9713,\n 0x970E, 0x9711, 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730,\n 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749,\n 0x975C, 0x9760, 0x9764, 0x9766, 0x9768, 0x52D2, 0x976B, 0x9771,\n 0x9779, 0x9785, 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F,\n 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, 0x97B4, 0x97C3,\n 0x97C6, 0x97C8, 0x97CB, 0x97DC, 0x97ED, 0x9F4F, 0x97F2, 0x7ADF,\n 0x97F6, 0x97F5, 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837,\n 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, 0x9870,\n};\nconst unsigned short euc_to_utf8_F1[] = {\n         0x9871, 0x9874, 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6,\n 0x98C4, 0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, 0x9912,\n 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, 0x9924, 0x9920, 0x992C,\n 0x992E, 0x993D, 0x993E, 0x9942, 0x9949, 0x9945, 0x9950, 0x994B,\n 0x9951, 0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, 0x99AD,\n 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, 0x99D8, 0x99D1, 0x99ED,\n 0x99EE, 0x99F1, 0x99F2, 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05,\n 0x99E2, 0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, 0x9A43,\n 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, 0x9A57, 0x9A5F, 0x9A62, 0x9A65,\n 0x9A64, 0x9A69, 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0,\n 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, 0x9AE2, 0x9AE3,\n 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, 0x9AF4, 0x9AF1, 0x9AF7,\n};\nconst unsigned short euc_to_utf8_F2[] = {\n         0x9AFB, 0x9B06, 0x9B18, 0x9B1A, 0x9B1F, 0x9B22, 0x9B23,\n 0x9B25, 0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32,\n 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, 0x9B58, 0x9B74,\n 0x9B93, 0x9B83, 0x9B91, 0x9B96, 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8,\n 0x9BB4, 0x9BC0, 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2,\n 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, 0x9BF2, 0x9BF1,\n 0x9BF0, 0x9C15, 0x9C14, 0x9C09, 0x9C13, 0x9C0C, 0x9C06, 0x9C08,\n 0x9C12, 0x9C0A, 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21,\n 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, 0x9C60, 0x9C67,\n 0x9C76, 0x9C78, 0x9CE7, 0x9CEC, 0x9CF0, 0x9D09, 0x9D08, 0x9CEB,\n 0x9D03, 0x9D06, 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44,\n 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, 0x9D48,\n};\nconst unsigned short euc_to_utf8_F3[] = {\n         0x9D5D, 0x9D5E, 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72,\n 0x9D89, 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, 0x9DA9,\n 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, 0x9DBA, 0x9DC6, 0x9DCF,\n 0x9DC2, 0x9DD9, 0x9DD3, 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD,\n 0x9E1A, 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, 0x9E88,\n 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, 0x9E9D, 0x9EA5, 0x9EA9,\n 0x9EB8, 0x9EAA, 0x9EAD, 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0,\n 0x9ED4, 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, 0x9EEF,\n 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07,\n 0x9F08, 0x76B7, 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52,\n 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, 0x9F67, 0x9F6C,\n 0x9F6A, 0x9F77, 0x9F72, 0x9F76, 0x9F95, 0x9F9C, 0x9FA0,\n};\nconst unsigned short euc_to_utf8_F4[] = {\n         0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_F5[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFE33,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFE31,      0,      0,\n      0,      0,      0,      0,      0, 0xFE30,      0,      0,\n      0,      0, 0xFE35, 0xFE36, 0xFE39, 0xFE3A,      0,      0,\n 0xFE37, 0xFE38, 0xFE3F, 0xFE40, 0xFE3D, 0xFE3E, 0xFE41, 0xFE42,\n 0xFE43, 0xFE44, 0xFE3B, 0xFE3C,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_F9[] = {\n         0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB,\n 0x6631, 0x68C8, 0x92F9, 0x66FB, 0x5F45, 0x4E28, 0x4EE1, 0x4EFC,\n 0x4F00, 0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94,\n 0x4FCD, 0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042,\n 0x5094, 0x50F4, 0x50D8, 0x514A, 0x5164, 0x519D, 0x51BE, 0x51EC,\n 0x5215, 0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324,\n 0x5372, 0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9,\n 0x54FF, 0x5586, 0x5759, 0x5765, 0x57AC, 0x57C8, 0x57C7, 0xFA0F,\n 0xFA10, 0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963,\n 0x59A4, 0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E,\n 0x5CA6, 0x5CBA, 0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D,\n 0x5DB8, 0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7,\n};\nconst unsigned short euc_to_utf8_FA[] = {\n         0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120,\n 0x60F2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62A6, 0x63F5,\n 0x6460, 0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609,\n 0x662E, 0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673,\n 0x6699, 0x66A0, 0x66B2, 0x66BF, 0x66FA, 0x670E, 0xF929, 0x6766,\n 0x67BB, 0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968,\n 0xFA14, 0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E,\n 0x6AE2, 0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, 0x6C86, 0x6C6F, 0x6CDA,\n 0x6D04, 0x6D87, 0x6D6F, 0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2,\n 0x6DFC, 0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5,\n 0x6FF5, 0x7005, 0x7007, 0x7028, 0x7085, 0x70AB, 0x710F, 0x7104,\n 0x715C, 0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1,\n};\nconst unsigned short euc_to_utf8_FB[] = {\n         0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6,\n 0x73E3, 0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E,\n 0x7462, 0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E,\n 0x769B, 0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864,\n 0x787A, 0x7930, 0xFA18, 0xFA19, 0xFA1A, 0x7994, 0xFA1B, 0x799B,\n 0x7AD1, 0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C,\n 0x7DB7, 0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301,\n 0x8362, 0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559,\n 0x856B, 0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12,\n 0x8A37, 0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53,\n 0x8B7F, 0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24,\n 0xFA25, 0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA,\n};\nconst unsigned short euc_to_utf8_FC[] = {\n         0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206,\n 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251,\n 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9,\n 0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB,\n 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4,\n 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC,\n 0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F,\n 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C,\n 0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1,\n 0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1,      0,\n      0, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176,\n 0x2177, 0x2178, 0x2179, 0xFFE2, 0x00A6, 0xFF07, 0xFF02,\n};\n\n/* Microsoft UCS Mapping Compatible */\nconst unsigned short euc_to_utf8_FC_ms[] = {\n         0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206,\n 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251,\n 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9,\n 0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB,\n 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4,\n 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC,\n 0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F,\n 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C,\n 0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1,\n 0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1,      0,\n      0, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176,\n 0x2177, 0x2178, 0x2179, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02,\n};\n\n#ifdef X0212_ENABLE\nconst unsigned short euc_to_utf8_8FA2[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x02D8,\n 0x02C7, 0x00B8, 0x02D9, 0x02DD, 0x00AF, 0x02DB, 0x02DA, 0xFF5E,\n 0x0384, 0x0385,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x00A1, 0xFFE4, 0x00BF,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x00BA, 0x00AA, 0x00A9, 0x00AE, 0x2122,\n 0x00A4, 0x2116,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_8FA6[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x0386, 0x0388, 0x0389, 0x038A, 0x03AA,      0, 0x038C,\n      0, 0x038E, 0x03AB,      0, 0x038F,      0,      0,      0,\n      0, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03CA, 0x0390, 0x03CC,\n 0x03C2, 0x03CD, 0x03CB, 0x03B0, 0x03CE,      0,      0,\n};\nconst unsigned short euc_to_utf8_8FA7[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,\n 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x040E, 0x040F,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,\n 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045E, 0x045F,\n};\nconst unsigned short euc_to_utf8_8FA9[] = {\n         0x00C6, 0x0110,      0, 0x0126,      0, 0x0132,      0,\n 0x0141, 0x013F,      0, 0x014A, 0x00D8, 0x0152,      0, 0x0166,\n 0x00DE,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x00E6, 0x0111, 0x00F0, 0x0127, 0x0131, 0x0133, 0x0138,\n 0x0142, 0x0140, 0x0149, 0x014B, 0x00F8, 0x0153, 0x00DF, 0x0167,\n 0x00FE,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_8FAA[] = {\n         0x00C1, 0x00C0, 0x00C4, 0x00C2, 0x0102, 0x01CD, 0x0100,\n 0x0104, 0x00C5, 0x00C3, 0x0106, 0x0108, 0x010C, 0x00C7, 0x010A,\n 0x010E, 0x00C9, 0x00C8, 0x00CB, 0x00CA, 0x011A, 0x0116, 0x0112,\n 0x0118,      0, 0x011C, 0x011E, 0x0122, 0x0120, 0x0124, 0x00CD,\n 0x00CC, 0x00CF, 0x00CE, 0x01CF, 0x0130, 0x012A, 0x012E, 0x0128,\n 0x0134, 0x0136, 0x0139, 0x013D, 0x013B, 0x0143, 0x0147, 0x0145,\n 0x00D1, 0x00D3, 0x00D2, 0x00D6, 0x00D4, 0x01D1, 0x0150, 0x014C,\n 0x00D5, 0x0154, 0x0158, 0x0156, 0x015A, 0x015C, 0x0160, 0x015E,\n 0x0164, 0x0162, 0x00DA, 0x00D9, 0x00DC, 0x00DB, 0x016C, 0x01D3,\n 0x0170, 0x016A, 0x0172, 0x016E, 0x0168, 0x01D7, 0x01DB, 0x01D9,\n 0x01D5, 0x0174, 0x00DD, 0x0178, 0x0176, 0x0179, 0x017D, 0x017B,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_8FAB[] = {\n         0x00E1, 0x00E0, 0x00E4, 0x00E2, 0x0103, 0x01CE, 0x0101,\n 0x0105, 0x00E5, 0x00E3, 0x0107, 0x0109, 0x010D, 0x00E7, 0x010B,\n 0x010F, 0x00E9, 0x00E8, 0x00EB, 0x00EA, 0x011B, 0x0117, 0x0113,\n 0x0119, 0x01F5, 0x011D, 0x011F,      0, 0x0121, 0x0125, 0x00ED,\n 0x00EC, 0x00EF, 0x00EE, 0x01D0,      0, 0x012B, 0x012F, 0x0129,\n 0x0135, 0x0137, 0x013A, 0x013E, 0x013C, 0x0144, 0x0148, 0x0146,\n 0x00F1, 0x00F3, 0x00F2, 0x00F6, 0x00F4, 0x01D2, 0x0151, 0x014D,\n 0x00F5, 0x0155, 0x0159, 0x0157, 0x015B, 0x015D, 0x0161, 0x015F,\n 0x0165, 0x0163, 0x00FA, 0x00F9, 0x00FC, 0x00FB, 0x016D, 0x01D4,\n 0x0171, 0x016B, 0x0173, 0x016F, 0x0169, 0x01D8, 0x01DC, 0x01DA,\n 0x01D6, 0x0175, 0x00FD, 0x00FF, 0x0177, 0x017A, 0x017E, 0x017C,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_8FB0[] = {\n         0x4E02, 0x4E04, 0x4E05, 0x4E0C, 0x4E12, 0x4E1F, 0x4E23,\n 0x4E24, 0x4E28, 0x4E2B, 0x4E2E, 0x4E2F, 0x4E30, 0x4E35, 0x4E40,\n 0x4E41, 0x4E44, 0x4E47, 0x4E51, 0x4E5A, 0x4E5C, 0x4E63, 0x4E68,\n 0x4E69, 0x4E74, 0x4E75, 0x4E79, 0x4E7F, 0x4E8D, 0x4E96, 0x4E97,\n 0x4E9D, 0x4EAF, 0x4EB9, 0x4EC3, 0x4ED0, 0x4EDA, 0x4EDB, 0x4EE0,\n 0x4EE1, 0x4EE2, 0x4EE8, 0x4EEF, 0x4EF1, 0x4EF3, 0x4EF5, 0x4EFD,\n 0x4EFE, 0x4EFF, 0x4F00, 0x4F02, 0x4F03, 0x4F08, 0x4F0B, 0x4F0C,\n 0x4F12, 0x4F15, 0x4F16, 0x4F17, 0x4F19, 0x4F2E, 0x4F31, 0x4F60,\n 0x4F33, 0x4F35, 0x4F37, 0x4F39, 0x4F3B, 0x4F3E, 0x4F40, 0x4F42,\n 0x4F48, 0x4F49, 0x4F4B, 0x4F4C, 0x4F52, 0x4F54, 0x4F56, 0x4F58,\n 0x4F5F, 0x4F63, 0x4F6A, 0x4F6C, 0x4F6E, 0x4F71, 0x4F77, 0x4F78,\n 0x4F79, 0x4F7A, 0x4F7D, 0x4F7E, 0x4F81, 0x4F82, 0x4F84,\n};\nconst unsigned short euc_to_utf8_8FB1[] = {\n         0x4F85, 0x4F89, 0x4F8A, 0x4F8C, 0x4F8E, 0x4F90, 0x4F92,\n 0x4F93, 0x4F94, 0x4F97, 0x4F99, 0x4F9A, 0x4F9E, 0x4F9F, 0x4FB2,\n 0x4FB7, 0x4FB9, 0x4FBB, 0x4FBC, 0x4FBD, 0x4FBE, 0x4FC0, 0x4FC1,\n 0x4FC5, 0x4FC6, 0x4FC8, 0x4FC9, 0x4FCB, 0x4FCC, 0x4FCD, 0x4FCF,\n 0x4FD2, 0x4FDC, 0x4FE0, 0x4FE2, 0x4FF0, 0x4FF2, 0x4FFC, 0x4FFD,\n 0x4FFF, 0x5000, 0x5001, 0x5004, 0x5007, 0x500A, 0x500C, 0x500E,\n 0x5010, 0x5013, 0x5017, 0x5018, 0x501B, 0x501C, 0x501D, 0x501E,\n 0x5022, 0x5027, 0x502E, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040,\n 0x5041, 0x5042, 0x5045, 0x5046, 0x504A, 0x504C, 0x504E, 0x5051,\n 0x5052, 0x5053, 0x5057, 0x5059, 0x505F, 0x5060, 0x5062, 0x5063,\n 0x5066, 0x5067, 0x506A, 0x506D, 0x5070, 0x5071, 0x503B, 0x5081,\n 0x5083, 0x5084, 0x5086, 0x508A, 0x508E, 0x508F, 0x5090,\n};\nconst unsigned short euc_to_utf8_8FB2[] = {\n         0x5092, 0x5093, 0x5094, 0x5096, 0x509B, 0x509C, 0x509E,\n 0x509F, 0x50A0, 0x50A1, 0x50A2, 0x50AA, 0x50AF, 0x50B0, 0x50B9,\n 0x50BA, 0x50BD, 0x50C0, 0x50C3, 0x50C4, 0x50C7, 0x50CC, 0x50CE,\n 0x50D0, 0x50D3, 0x50D4, 0x50D8, 0x50DC, 0x50DD, 0x50DF, 0x50E2,\n 0x50E4, 0x50E6, 0x50E8, 0x50E9, 0x50EF, 0x50F1, 0x50F6, 0x50FA,\n 0x50FE, 0x5103, 0x5106, 0x5107, 0x5108, 0x510B, 0x510C, 0x510D,\n 0x510E, 0x50F2, 0x5110, 0x5117, 0x5119, 0x511B, 0x511C, 0x511D,\n 0x511E, 0x5123, 0x5127, 0x5128, 0x512C, 0x512D, 0x512F, 0x5131,\n 0x5133, 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514A, 0x514F,\n 0x5153, 0x5155, 0x5157, 0x5158, 0x515F, 0x5164, 0x5166, 0x517E,\n 0x5183, 0x5184, 0x518B, 0x518E, 0x5198, 0x519D, 0x51A1, 0x51A3,\n 0x51AD, 0x51B8, 0x51BA, 0x51BC, 0x51BE, 0x51BF, 0x51C2,\n};\nconst unsigned short euc_to_utf8_8FB3[] = {\n         0x51C8, 0x51CF, 0x51D1, 0x51D2, 0x51D3, 0x51D5, 0x51D8,\n 0x51DE, 0x51E2, 0x51E5, 0x51EE, 0x51F2, 0x51F3, 0x51F4, 0x51F7,\n 0x5201, 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218,\n 0x5222, 0x5228, 0x5231, 0x5232, 0x5235, 0x523C, 0x5245, 0x5249,\n 0x5255, 0x5257, 0x5258, 0x525A, 0x525C, 0x525F, 0x5260, 0x5261,\n 0x5266, 0x526E, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285,\n 0x528A, 0x528C, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529A,\n 0x529C, 0x52A4, 0x52A5, 0x52A6, 0x52A7, 0x52AF, 0x52B0, 0x52B6,\n 0x52B7, 0x52B8, 0x52BA, 0x52BB, 0x52BD, 0x52C0, 0x52C4, 0x52C6,\n 0x52C8, 0x52CC, 0x52CF, 0x52D1, 0x52D4, 0x52D6, 0x52DB, 0x52DC,\n 0x52E1, 0x52E5, 0x52E8, 0x52E9, 0x52EA, 0x52EC, 0x52F0, 0x52F1,\n 0x52F4, 0x52F6, 0x52F7, 0x5300, 0x5303, 0x530A, 0x530B,\n};\nconst unsigned short euc_to_utf8_8FB4[] = {\n         0x530C, 0x5311, 0x5313, 0x5318, 0x531B, 0x531C, 0x531E,\n 0x531F, 0x5325, 0x5327, 0x5328, 0x5329, 0x532B, 0x532C, 0x532D,\n 0x5330, 0x5332, 0x5335, 0x533C, 0x533D, 0x533E, 0x5342, 0x534C,\n 0x534B, 0x5359, 0x535B, 0x5361, 0x5363, 0x5365, 0x536C, 0x536D,\n 0x5372, 0x5379, 0x537E, 0x5383, 0x5387, 0x5388, 0x538E, 0x5393,\n 0x5394, 0x5399, 0x539D, 0x53A1, 0x53A4, 0x53AA, 0x53AB, 0x53AF,\n 0x53B2, 0x53B4, 0x53B5, 0x53B7, 0x53B8, 0x53BA, 0x53BD, 0x53C0,\n 0x53C5, 0x53CF, 0x53D2, 0x53D3, 0x53D5, 0x53DA, 0x53DD, 0x53DE,\n 0x53E0, 0x53E6, 0x53E7, 0x53F5, 0x5402, 0x5413, 0x541A, 0x5421,\n 0x5427, 0x5428, 0x542A, 0x542F, 0x5431, 0x5434, 0x5435, 0x5443,\n 0x5444, 0x5447, 0x544D, 0x544F, 0x545E, 0x5462, 0x5464, 0x5466,\n 0x5467, 0x5469, 0x546B, 0x546D, 0x546E, 0x5474, 0x547F,\n};\nconst unsigned short euc_to_utf8_8FB5[] = {\n         0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548D, 0x5491,\n 0x5495, 0x5496, 0x549C, 0x549F, 0x54A1, 0x54A6, 0x54A7, 0x54A9,\n 0x54AA, 0x54AD, 0x54AE, 0x54B1, 0x54B7, 0x54B9, 0x54BA, 0x54BB,\n 0x54BF, 0x54C6, 0x54CA, 0x54CD, 0x54CE, 0x54E0, 0x54EA, 0x54EC,\n 0x54EF, 0x54F6, 0x54FC, 0x54FE, 0x54FF, 0x5500, 0x5501, 0x5505,\n 0x5508, 0x5509, 0x550C, 0x550D, 0x550E, 0x5515, 0x552A, 0x552B,\n 0x5532, 0x5535, 0x5536, 0x553B, 0x553C, 0x553D, 0x5541, 0x5547,\n 0x5549, 0x554A, 0x554D, 0x5550, 0x5551, 0x5558, 0x555A, 0x555B,\n 0x555E, 0x5560, 0x5561, 0x5564, 0x5566, 0x557F, 0x5581, 0x5582,\n 0x5586, 0x5588, 0x558E, 0x558F, 0x5591, 0x5592, 0x5593, 0x5594,\n 0x5597, 0x55A3, 0x55A4, 0x55AD, 0x55B2, 0x55BF, 0x55C1, 0x55C3,\n 0x55C6, 0x55C9, 0x55CB, 0x55CC, 0x55CE, 0x55D1, 0x55D2,\n};\nconst unsigned short euc_to_utf8_8FB6[] = {\n         0x55D3, 0x55D7, 0x55D8, 0x55DB, 0x55DE, 0x55E2, 0x55E9,\n 0x55F6, 0x55FF, 0x5605, 0x5608, 0x560A, 0x560D, 0x560E, 0x560F,\n 0x5610, 0x5611, 0x5612, 0x5619, 0x562C, 0x5630, 0x5633, 0x5635,\n 0x5637, 0x5639, 0x563B, 0x563C, 0x563D, 0x563F, 0x5640, 0x5641,\n 0x5643, 0x5644, 0x5646, 0x5649, 0x564B, 0x564D, 0x564F, 0x5654,\n 0x565E, 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566D,\n 0x566F, 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568B,\n 0x568C, 0x5695, 0x5699, 0x569A, 0x569D, 0x569E, 0x569F, 0x56A6,\n 0x56A7, 0x56A8, 0x56A9, 0x56AB, 0x56AC, 0x56AD, 0x56B1, 0x56B3,\n 0x56B7, 0x56BE, 0x56C5, 0x56C9, 0x56CA, 0x56CB, 0x56CF, 0x56D0,\n 0x56CC, 0x56CD, 0x56D9, 0x56DC, 0x56DD, 0x56DF, 0x56E1, 0x56E4,\n 0x56E5, 0x56E6, 0x56E7, 0x56E8, 0x56F1, 0x56EB, 0x56ED,\n};\nconst unsigned short euc_to_utf8_8FB7[] = {\n         0x56F6, 0x56F7, 0x5701, 0x5702, 0x5707, 0x570A, 0x570C,\n 0x5711, 0x5715, 0x571A, 0x571B, 0x571D, 0x5720, 0x5722, 0x5723,\n 0x5724, 0x5725, 0x5729, 0x572A, 0x572C, 0x572E, 0x572F, 0x5733,\n 0x5734, 0x573D, 0x573E, 0x573F, 0x5745, 0x5746, 0x574C, 0x574D,\n 0x5752, 0x5762, 0x5765, 0x5767, 0x5768, 0x576B, 0x576D, 0x576E,\n 0x576F, 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779,\n 0x577A, 0x577B, 0x577C, 0x577E, 0x5781, 0x5783, 0x578C, 0x5794,\n 0x5797, 0x5799, 0x579A, 0x579C, 0x579D, 0x579E, 0x579F, 0x57A1,\n 0x5795, 0x57A7, 0x57A8, 0x57A9, 0x57AC, 0x57B8, 0x57BD, 0x57C7,\n 0x57C8, 0x57CC, 0x57CF, 0x57D5, 0x57DD, 0x57DE, 0x57E4, 0x57E6,\n 0x57E7, 0x57E9, 0x57ED, 0x57F0, 0x57F5, 0x57F6, 0x57F8, 0x57FD,\n 0x57FE, 0x57FF, 0x5803, 0x5804, 0x5808, 0x5809, 0x57E1,\n};\nconst unsigned short euc_to_utf8_8FB8[] = {\n         0x580C, 0x580D, 0x581B, 0x581E, 0x581F, 0x5820, 0x5826,\n 0x5827, 0x582D, 0x5832, 0x5839, 0x583F, 0x5849, 0x584C, 0x584D,\n 0x584F, 0x5850, 0x5855, 0x585F, 0x5861, 0x5864, 0x5867, 0x5868,\n 0x5878, 0x587C, 0x587F, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889,\n 0x588A, 0x588C, 0x588D, 0x588F, 0x5890, 0x5894, 0x5896, 0x589D,\n 0x58A0, 0x58A1, 0x58A2, 0x58A6, 0x58A9, 0x58B1, 0x58B2, 0x58C4,\n 0x58BC, 0x58C2, 0x58C8, 0x58CD, 0x58CE, 0x58D0, 0x58D2, 0x58D4,\n 0x58D6, 0x58DA, 0x58DD, 0x58E1, 0x58E2, 0x58E9, 0x58F3, 0x5905,\n 0x5906, 0x590B, 0x590C, 0x5912, 0x5913, 0x5914, 0x8641, 0x591D,\n 0x5921, 0x5923, 0x5924, 0x5928, 0x592F, 0x5930, 0x5933, 0x5935,\n 0x5936, 0x593F, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595B,\n 0x595D, 0x595E, 0x595F, 0x5961, 0x5963, 0x596B, 0x596D,\n};\nconst unsigned short euc_to_utf8_8FB9[] = {\n         0x596F, 0x5972, 0x5975, 0x5976, 0x5979, 0x597B, 0x597C,\n 0x598B, 0x598C, 0x598E, 0x5992, 0x5995, 0x5997, 0x599F, 0x59A4,\n 0x59A7, 0x59AD, 0x59AE, 0x59AF, 0x59B0, 0x59B3, 0x59B7, 0x59BA,\n 0x59BC, 0x59C1, 0x59C3, 0x59C4, 0x59C8, 0x59CA, 0x59CD, 0x59D2,\n 0x59DD, 0x59DE, 0x59DF, 0x59E3, 0x59E4, 0x59E7, 0x59EE, 0x59EF,\n 0x59F1, 0x59F2, 0x59F4, 0x59F7, 0x5A00, 0x5A04, 0x5A0C, 0x5A0D,\n 0x5A0E, 0x5A12, 0x5A13, 0x5A1E, 0x5A23, 0x5A24, 0x5A27, 0x5A28,\n 0x5A2A, 0x5A2D, 0x5A30, 0x5A44, 0x5A45, 0x5A47, 0x5A48, 0x5A4C,\n 0x5A50, 0x5A55, 0x5A5E, 0x5A63, 0x5A65, 0x5A67, 0x5A6D, 0x5A77,\n 0x5A7A, 0x5A7B, 0x5A7E, 0x5A8B, 0x5A90, 0x5A93, 0x5A96, 0x5A99,\n 0x5A9C, 0x5A9E, 0x5A9F, 0x5AA0, 0x5AA2, 0x5AA7, 0x5AAC, 0x5AB1,\n 0x5AB2, 0x5AB3, 0x5AB5, 0x5AB8, 0x5ABA, 0x5ABB, 0x5ABF,\n};\nconst unsigned short euc_to_utf8_8FBA[] = {\n         0x5AC4, 0x5AC6, 0x5AC8, 0x5ACF, 0x5ADA, 0x5ADC, 0x5AE0,\n 0x5AE5, 0x5AEA, 0x5AEE, 0x5AF5, 0x5AF6, 0x5AFD, 0x5B00, 0x5B01,\n 0x5B08, 0x5B17, 0x5B34, 0x5B19, 0x5B1B, 0x5B1D, 0x5B21, 0x5B25,\n 0x5B2D, 0x5B38, 0x5B41, 0x5B4B, 0x5B4C, 0x5B52, 0x5B56, 0x5B5E,\n 0x5B68, 0x5B6E, 0x5B6F, 0x5B7C, 0x5B7D, 0x5B7E, 0x5B7F, 0x5B81,\n 0x5B84, 0x5B86, 0x5B8A, 0x5B8E, 0x5B90, 0x5B91, 0x5B93, 0x5B94,\n 0x5B96, 0x5BA8, 0x5BA9, 0x5BAC, 0x5BAD, 0x5BAF, 0x5BB1, 0x5BB2,\n 0x5BB7, 0x5BBA, 0x5BBC, 0x5BC0, 0x5BC1, 0x5BCD, 0x5BCF, 0x5BD6,\n 0x5BD7, 0x5BD8, 0x5BD9, 0x5BDA, 0x5BE0, 0x5BEF, 0x5BF1, 0x5BF4,\n 0x5BFD, 0x5C0C, 0x5C17, 0x5C1E, 0x5C1F, 0x5C23, 0x5C26, 0x5C29,\n 0x5C2B, 0x5C2C, 0x5C2E, 0x5C30, 0x5C32, 0x5C35, 0x5C36, 0x5C59,\n 0x5C5A, 0x5C5C, 0x5C62, 0x5C63, 0x5C67, 0x5C68, 0x5C69,\n};\nconst unsigned short euc_to_utf8_8FBB[] = {\n         0x5C6D, 0x5C70, 0x5C74, 0x5C75, 0x5C7A, 0x5C7B, 0x5C7C,\n 0x5C7D, 0x5C87, 0x5C88, 0x5C8A, 0x5C8F, 0x5C92, 0x5C9D, 0x5C9F,\n 0x5CA0, 0x5CA2, 0x5CA3, 0x5CA6, 0x5CAA, 0x5CB2, 0x5CB4, 0x5CB5,\n 0x5CBA, 0x5CC9, 0x5CCB, 0x5CD2, 0x5CDD, 0x5CD7, 0x5CEE, 0x5CF1,\n 0x5CF2, 0x5CF4, 0x5D01, 0x5D06, 0x5D0D, 0x5D12, 0x5D2B, 0x5D23,\n 0x5D24, 0x5D26, 0x5D27, 0x5D31, 0x5D34, 0x5D39, 0x5D3D, 0x5D3F,\n 0x5D42, 0x5D43, 0x5D46, 0x5D48, 0x5D55, 0x5D51, 0x5D59, 0x5D4A,\n 0x5D5F, 0x5D60, 0x5D61, 0x5D62, 0x5D64, 0x5D6A, 0x5D6D, 0x5D70,\n 0x5D79, 0x5D7A, 0x5D7E, 0x5D7F, 0x5D81, 0x5D83, 0x5D88, 0x5D8A,\n 0x5D92, 0x5D93, 0x5D94, 0x5D95, 0x5D99, 0x5D9B, 0x5D9F, 0x5DA0,\n 0x5DA7, 0x5DAB, 0x5DB0, 0x5DB4, 0x5DB8, 0x5DB9, 0x5DC3, 0x5DC7,\n 0x5DCB, 0x5DD0, 0x5DCE, 0x5DD8, 0x5DD9, 0x5DE0, 0x5DE4,\n};\nconst unsigned short euc_to_utf8_8FBC[] = {\n         0x5DE9, 0x5DF8, 0x5DF9, 0x5E00, 0x5E07, 0x5E0D, 0x5E12,\n 0x5E14, 0x5E15, 0x5E18, 0x5E1F, 0x5E20, 0x5E2E, 0x5E28, 0x5E32,\n 0x5E35, 0x5E3E, 0x5E4B, 0x5E50, 0x5E49, 0x5E51, 0x5E56, 0x5E58,\n 0x5E5B, 0x5E5C, 0x5E5E, 0x5E68, 0x5E6A, 0x5E6B, 0x5E6C, 0x5E6D,\n 0x5E6E, 0x5E70, 0x5E80, 0x5E8B, 0x5E8E, 0x5EA2, 0x5EA4, 0x5EA5,\n 0x5EA8, 0x5EAA, 0x5EAC, 0x5EB1, 0x5EB3, 0x5EBD, 0x5EBE, 0x5EBF,\n 0x5EC6, 0x5ECC, 0x5ECB, 0x5ECE, 0x5ED1, 0x5ED2, 0x5ED4, 0x5ED5,\n 0x5EDC, 0x5EDE, 0x5EE5, 0x5EEB, 0x5F02, 0x5F06, 0x5F07, 0x5F08,\n 0x5F0E, 0x5F19, 0x5F1C, 0x5F1D, 0x5F21, 0x5F22, 0x5F23, 0x5F24,\n 0x5F28, 0x5F2B, 0x5F2C, 0x5F2E, 0x5F30, 0x5F34, 0x5F36, 0x5F3B,\n 0x5F3D, 0x5F3F, 0x5F40, 0x5F44, 0x5F45, 0x5F47, 0x5F4D, 0x5F50,\n 0x5F54, 0x5F58, 0x5F5B, 0x5F60, 0x5F63, 0x5F64, 0x5F67,\n};\nconst unsigned short euc_to_utf8_8FBD[] = {\n         0x5F6F, 0x5F72, 0x5F74, 0x5F75, 0x5F78, 0x5F7A, 0x5F7D,\n 0x5F7E, 0x5F89, 0x5F8D, 0x5F8F, 0x5F96, 0x5F9C, 0x5F9D, 0x5FA2,\n 0x5FA7, 0x5FAB, 0x5FA4, 0x5FAC, 0x5FAF, 0x5FB0, 0x5FB1, 0x5FB8,\n 0x5FC4, 0x5FC7, 0x5FC8, 0x5FC9, 0x5FCB, 0x5FD0, 0x5FD1, 0x5FD2,\n 0x5FD3, 0x5FD4, 0x5FDE, 0x5FE1, 0x5FE2, 0x5FE8, 0x5FE9, 0x5FEA,\n 0x5FEC, 0x5FED, 0x5FEE, 0x5FEF, 0x5FF2, 0x5FF3, 0x5FF6, 0x5FFA,\n 0x5FFC, 0x6007, 0x600A, 0x600D, 0x6013, 0x6014, 0x6017, 0x6018,\n 0x601A, 0x601F, 0x6024, 0x602D, 0x6033, 0x6035, 0x6040, 0x6047,\n 0x6048, 0x6049, 0x604C, 0x6051, 0x6054, 0x6056, 0x6057, 0x605D,\n 0x6061, 0x6067, 0x6071, 0x607E, 0x607F, 0x6082, 0x6086, 0x6088,\n 0x608A, 0x608E, 0x6091, 0x6093, 0x6095, 0x6098, 0x609D, 0x609E,\n 0x60A2, 0x60A4, 0x60A5, 0x60A8, 0x60B0, 0x60B1, 0x60B7,\n};\nconst unsigned short euc_to_utf8_8FBE[] = {\n         0x60BB, 0x60BE, 0x60C2, 0x60C4, 0x60C8, 0x60C9, 0x60CA,\n 0x60CB, 0x60CE, 0x60CF, 0x60D4, 0x60D5, 0x60D9, 0x60DB, 0x60DD,\n 0x60DE, 0x60E2, 0x60E5, 0x60F2, 0x60F5, 0x60F8, 0x60FC, 0x60FD,\n 0x6102, 0x6107, 0x610A, 0x610C, 0x6110, 0x6111, 0x6112, 0x6113,\n 0x6114, 0x6116, 0x6117, 0x6119, 0x611C, 0x611E, 0x6122, 0x612A,\n 0x612B, 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141,\n 0x6145, 0x6146, 0x6149, 0x615E, 0x6160, 0x616C, 0x6172, 0x6178,\n 0x617B, 0x617C, 0x617F, 0x6180, 0x6181, 0x6183, 0x6184, 0x618B,\n 0x618D, 0x6192, 0x6193, 0x6197, 0x6198, 0x619C, 0x619D, 0x619F,\n 0x61A0, 0x61A5, 0x61A8, 0x61AA, 0x61AD, 0x61B8, 0x61B9, 0x61BC,\n 0x61C0, 0x61C1, 0x61C2, 0x61CE, 0x61CF, 0x61D5, 0x61DC, 0x61DD,\n 0x61DE, 0x61DF, 0x61E1, 0x61E2, 0x61E7, 0x61E9, 0x61E5,\n};\nconst unsigned short euc_to_utf8_8FBF[] = {\n         0x61EC, 0x61ED, 0x61EF, 0x6201, 0x6203, 0x6204, 0x6207,\n 0x6213, 0x6215, 0x621C, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229,\n 0x622B, 0x6239, 0x623D, 0x6242, 0x6243, 0x6244, 0x6246, 0x624C,\n 0x6250, 0x6251, 0x6252, 0x6254, 0x6256, 0x625A, 0x625C, 0x6264,\n 0x626D, 0x626F, 0x6273, 0x627A, 0x627D, 0x628D, 0x628E, 0x628F,\n 0x6290, 0x62A6, 0x62A8, 0x62B3, 0x62B6, 0x62B7, 0x62BA, 0x62BE,\n 0x62BF, 0x62C4, 0x62CE, 0x62D5, 0x62D6, 0x62DA, 0x62EA, 0x62F2,\n 0x62F4, 0x62FC, 0x62FD, 0x6303, 0x6304, 0x630A, 0x630B, 0x630D,\n 0x6310, 0x6313, 0x6316, 0x6318, 0x6329, 0x632A, 0x632D, 0x6335,\n 0x6336, 0x6339, 0x633C, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346,\n 0x634A, 0x634B, 0x634E, 0x6352, 0x6353, 0x6354, 0x6358, 0x635B,\n 0x6365, 0x6366, 0x636C, 0x636D, 0x6371, 0x6374, 0x6375,\n};\nconst unsigned short euc_to_utf8_8FC0[] = {\n         0x6378, 0x637C, 0x637D, 0x637F, 0x6382, 0x6384, 0x6387,\n 0x638A, 0x6390, 0x6394, 0x6395, 0x6399, 0x639A, 0x639E, 0x63A4,\n 0x63A6, 0x63AD, 0x63AE, 0x63AF, 0x63BD, 0x63C1, 0x63C5, 0x63C8,\n 0x63CE, 0x63D1, 0x63D3, 0x63D4, 0x63D5, 0x63DC, 0x63E0, 0x63E5,\n 0x63EA, 0x63EC, 0x63F2, 0x63F3, 0x63F5, 0x63F8, 0x63F9, 0x6409,\n 0x640A, 0x6410, 0x6412, 0x6414, 0x6418, 0x641E, 0x6420, 0x6422,\n 0x6424, 0x6425, 0x6429, 0x642A, 0x642F, 0x6430, 0x6435, 0x643D,\n 0x643F, 0x644B, 0x644F, 0x6451, 0x6452, 0x6453, 0x6454, 0x645A,\n 0x645B, 0x645C, 0x645D, 0x645F, 0x6460, 0x6461, 0x6463, 0x646D,\n 0x6473, 0x6474, 0x647B, 0x647D, 0x6485, 0x6487, 0x648F, 0x6490,\n 0x6491, 0x6498, 0x6499, 0x649B, 0x649D, 0x649F, 0x64A1, 0x64A3,\n 0x64A6, 0x64A8, 0x64AC, 0x64B3, 0x64BD, 0x64BE, 0x64BF,\n};\nconst unsigned short euc_to_utf8_8FC1[] = {\n         0x64C4, 0x64C9, 0x64CA, 0x64CB, 0x64CC, 0x64CE, 0x64D0,\n 0x64D1, 0x64D5, 0x64D7, 0x64E4, 0x64E5, 0x64E9, 0x64EA, 0x64ED,\n 0x64F0, 0x64F5, 0x64F7, 0x64FB, 0x64FF, 0x6501, 0x6504, 0x6508,\n 0x6509, 0x650A, 0x650F, 0x6513, 0x6514, 0x6516, 0x6519, 0x651B,\n 0x651E, 0x651F, 0x6522, 0x6526, 0x6529, 0x652E, 0x6531, 0x653A,\n 0x653C, 0x653D, 0x6543, 0x6547, 0x6549, 0x6550, 0x6552, 0x6554,\n 0x655F, 0x6560, 0x6567, 0x656B, 0x657A, 0x657D, 0x6581, 0x6585,\n 0x658A, 0x6592, 0x6595, 0x6598, 0x659D, 0x65A0, 0x65A3, 0x65A6,\n 0x65AE, 0x65B2, 0x65B3, 0x65B4, 0x65BF, 0x65C2, 0x65C8, 0x65C9,\n 0x65CE, 0x65D0, 0x65D4, 0x65D6, 0x65D8, 0x65DF, 0x65F0, 0x65F2,\n 0x65F4, 0x65F5, 0x65F9, 0x65FE, 0x65FF, 0x6600, 0x6604, 0x6608,\n 0x6609, 0x660D, 0x6611, 0x6612, 0x6615, 0x6616, 0x661D,\n};\nconst unsigned short euc_to_utf8_8FC2[] = {\n         0x661E, 0x6621, 0x6622, 0x6623, 0x6624, 0x6626, 0x6629,\n 0x662A, 0x662B, 0x662C, 0x662E, 0x6630, 0x6631, 0x6633, 0x6639,\n 0x6637, 0x6640, 0x6645, 0x6646, 0x664A, 0x664C, 0x6651, 0x664E,\n 0x6657, 0x6658, 0x6659, 0x665B, 0x665C, 0x6660, 0x6661, 0x66FB,\n 0x666A, 0x666B, 0x666C, 0x667E, 0x6673, 0x6675, 0x667F, 0x6677,\n 0x6678, 0x6679, 0x667B, 0x6680, 0x667C, 0x668B, 0x668C, 0x668D,\n 0x6690, 0x6692, 0x6699, 0x669A, 0x669B, 0x669C, 0x669F, 0x66A0,\n 0x66A4, 0x66AD, 0x66B1, 0x66B2, 0x66B5, 0x66BB, 0x66BF, 0x66C0,\n 0x66C2, 0x66C3, 0x66C8, 0x66CC, 0x66CE, 0x66CF, 0x66D4, 0x66DB,\n 0x66DF, 0x66E8, 0x66EB, 0x66EC, 0x66EE, 0x66FA, 0x6705, 0x6707,\n 0x670E, 0x6713, 0x6719, 0x671C, 0x6720, 0x6722, 0x6733, 0x673E,\n 0x6745, 0x6747, 0x6748, 0x674C, 0x6754, 0x6755, 0x675D,\n};\nconst unsigned short euc_to_utf8_8FC3[] = {\n         0x6766, 0x676C, 0x676E, 0x6774, 0x6776, 0x677B, 0x6781,\n 0x6784, 0x678E, 0x678F, 0x6791, 0x6793, 0x6796, 0x6798, 0x6799,\n 0x679B, 0x67B0, 0x67B1, 0x67B2, 0x67B5, 0x67BB, 0x67BC, 0x67BD,\n 0x67F9, 0x67C0, 0x67C2, 0x67C3, 0x67C5, 0x67C8, 0x67C9, 0x67D2,\n 0x67D7, 0x67D9, 0x67DC, 0x67E1, 0x67E6, 0x67F0, 0x67F2, 0x67F6,\n 0x67F7, 0x6852, 0x6814, 0x6819, 0x681D, 0x681F, 0x6828, 0x6827,\n 0x682C, 0x682D, 0x682F, 0x6830, 0x6831, 0x6833, 0x683B, 0x683F,\n 0x6844, 0x6845, 0x684A, 0x684C, 0x6855, 0x6857, 0x6858, 0x685B,\n 0x686B, 0x686E, 0x686F, 0x6870, 0x6871, 0x6872, 0x6875, 0x6879,\n 0x687A, 0x687B, 0x687C, 0x6882, 0x6884, 0x6886, 0x6888, 0x6896,\n 0x6898, 0x689A, 0x689C, 0x68A1, 0x68A3, 0x68A5, 0x68A9, 0x68AA,\n 0x68AE, 0x68B2, 0x68BB, 0x68C5, 0x68C8, 0x68CC, 0x68CF,\n};\nconst unsigned short euc_to_utf8_8FC4[] = {\n         0x68D0, 0x68D1, 0x68D3, 0x68D6, 0x68D9, 0x68DC, 0x68DD,\n 0x68E5, 0x68E8, 0x68EA, 0x68EB, 0x68EC, 0x68ED, 0x68F0, 0x68F1,\n 0x68F5, 0x68F6, 0x68FB, 0x68FC, 0x68FD, 0x6906, 0x6909, 0x690A,\n 0x6910, 0x6911, 0x6913, 0x6916, 0x6917, 0x6931, 0x6933, 0x6935,\n 0x6938, 0x693B, 0x6942, 0x6945, 0x6949, 0x694E, 0x6957, 0x695B,\n 0x6963, 0x6964, 0x6965, 0x6966, 0x6968, 0x6969, 0x696C, 0x6970,\n 0x6971, 0x6972, 0x697A, 0x697B, 0x697F, 0x6980, 0x698D, 0x6992,\n 0x6996, 0x6998, 0x69A1, 0x69A5, 0x69A6, 0x69A8, 0x69AB, 0x69AD,\n 0x69AF, 0x69B7, 0x69B8, 0x69BA, 0x69BC, 0x69C5, 0x69C8, 0x69D1,\n 0x69D6, 0x69D7, 0x69E2, 0x69E5, 0x69EE, 0x69EF, 0x69F1, 0x69F3,\n 0x69F5, 0x69FE, 0x6A00, 0x6A01, 0x6A03, 0x6A0F, 0x6A11, 0x6A15,\n 0x6A1A, 0x6A1D, 0x6A20, 0x6A24, 0x6A28, 0x6A30, 0x6A32,\n};\nconst unsigned short euc_to_utf8_8FC5[] = {\n         0x6A34, 0x6A37, 0x6A3B, 0x6A3E, 0x6A3F, 0x6A45, 0x6A46,\n 0x6A49, 0x6A4A, 0x6A4E, 0x6A50, 0x6A51, 0x6A52, 0x6A55, 0x6A56,\n 0x6A5B, 0x6A64, 0x6A67, 0x6A6A, 0x6A71, 0x6A73, 0x6A7E, 0x6A81,\n 0x6A83, 0x6A86, 0x6A87, 0x6A89, 0x6A8B, 0x6A91, 0x6A9B, 0x6A9D,\n 0x6A9E, 0x6A9F, 0x6AA5, 0x6AAB, 0x6AAF, 0x6AB0, 0x6AB1, 0x6AB4,\n 0x6ABD, 0x6ABE, 0x6ABF, 0x6AC6, 0x6AC9, 0x6AC8, 0x6ACC, 0x6AD0,\n 0x6AD4, 0x6AD5, 0x6AD6, 0x6ADC, 0x6ADD, 0x6AE4, 0x6AE7, 0x6AEC,\n 0x6AF0, 0x6AF1, 0x6AF2, 0x6AFC, 0x6AFD, 0x6B02, 0x6B03, 0x6B06,\n 0x6B07, 0x6B09, 0x6B0F, 0x6B10, 0x6B11, 0x6B17, 0x6B1B, 0x6B1E,\n 0x6B24, 0x6B28, 0x6B2B, 0x6B2C, 0x6B2F, 0x6B35, 0x6B36, 0x6B3B,\n 0x6B3F, 0x6B46, 0x6B4A, 0x6B4D, 0x6B52, 0x6B56, 0x6B58, 0x6B5D,\n 0x6B60, 0x6B67, 0x6B6B, 0x6B6E, 0x6B70, 0x6B75, 0x6B7D,\n};\nconst unsigned short euc_to_utf8_8FC6[] = {\n         0x6B7E, 0x6B82, 0x6B85, 0x6B97, 0x6B9B, 0x6B9F, 0x6BA0,\n 0x6BA2, 0x6BA3, 0x6BA8, 0x6BA9, 0x6BAC, 0x6BAD, 0x6BAE, 0x6BB0,\n 0x6BB8, 0x6BB9, 0x6BBD, 0x6BBE, 0x6BC3, 0x6BC4, 0x6BC9, 0x6BCC,\n 0x6BD6, 0x6BDA, 0x6BE1, 0x6BE3, 0x6BE6, 0x6BE7, 0x6BEE, 0x6BF1,\n 0x6BF7, 0x6BF9, 0x6BFF, 0x6C02, 0x6C04, 0x6C05, 0x6C09, 0x6C0D,\n 0x6C0E, 0x6C10, 0x6C12, 0x6C19, 0x6C1F, 0x6C26, 0x6C27, 0x6C28,\n 0x6C2C, 0x6C2E, 0x6C33, 0x6C35, 0x6C36, 0x6C3A, 0x6C3B, 0x6C3F,\n 0x6C4A, 0x6C4B, 0x6C4D, 0x6C4F, 0x6C52, 0x6C54, 0x6C59, 0x6C5B,\n 0x6C5C, 0x6C6B, 0x6C6D, 0x6C6F, 0x6C74, 0x6C76, 0x6C78, 0x6C79,\n 0x6C7B, 0x6C85, 0x6C86, 0x6C87, 0x6C89, 0x6C94, 0x6C95, 0x6C97,\n 0x6C98, 0x6C9C, 0x6C9F, 0x6CB0, 0x6CB2, 0x6CB4, 0x6CC2, 0x6CC6,\n 0x6CCD, 0x6CCF, 0x6CD0, 0x6CD1, 0x6CD2, 0x6CD4, 0x6CD6,\n};\nconst unsigned short euc_to_utf8_8FC7[] = {\n         0x6CDA, 0x6CDC, 0x6CE0, 0x6CE7, 0x6CE9, 0x6CEB, 0x6CEC,\n 0x6CEE, 0x6CF2, 0x6CF4, 0x6D04, 0x6D07, 0x6D0A, 0x6D0E, 0x6D0F,\n 0x6D11, 0x6D13, 0x6D1A, 0x6D26, 0x6D27, 0x6D28, 0x6C67, 0x6D2E,\n 0x6D2F, 0x6D31, 0x6D39, 0x6D3C, 0x6D3F, 0x6D57, 0x6D5E, 0x6D5F,\n 0x6D61, 0x6D65, 0x6D67, 0x6D6F, 0x6D70, 0x6D7C, 0x6D82, 0x6D87,\n 0x6D91, 0x6D92, 0x6D94, 0x6D96, 0x6D97, 0x6D98, 0x6DAA, 0x6DAC,\n 0x6DB4, 0x6DB7, 0x6DB9, 0x6DBD, 0x6DBF, 0x6DC4, 0x6DC8, 0x6DCA,\n 0x6DCE, 0x6DCF, 0x6DD6, 0x6DDB, 0x6DDD, 0x6DDF, 0x6DE0, 0x6DE2,\n 0x6DE5, 0x6DE9, 0x6DEF, 0x6DF0, 0x6DF4, 0x6DF6, 0x6DFC, 0x6E00,\n 0x6E04, 0x6E1E, 0x6E22, 0x6E27, 0x6E32, 0x6E36, 0x6E39, 0x6E3B,\n 0x6E3C, 0x6E44, 0x6E45, 0x6E48, 0x6E49, 0x6E4B, 0x6E4F, 0x6E51,\n 0x6E52, 0x6E53, 0x6E54, 0x6E57, 0x6E5C, 0x6E5D, 0x6E5E,\n};\nconst unsigned short euc_to_utf8_8FC8[] = {\n         0x6E62, 0x6E63, 0x6E68, 0x6E73, 0x6E7B, 0x6E7D, 0x6E8D,\n 0x6E93, 0x6E99, 0x6EA0, 0x6EA7, 0x6EAD, 0x6EAE, 0x6EB1, 0x6EB3,\n 0x6EBB, 0x6EBF, 0x6EC0, 0x6EC1, 0x6EC3, 0x6EC7, 0x6EC8, 0x6ECA,\n 0x6ECD, 0x6ECE, 0x6ECF, 0x6EEB, 0x6EED, 0x6EEE, 0x6EF9, 0x6EFB,\n 0x6EFD, 0x6F04, 0x6F08, 0x6F0A, 0x6F0C, 0x6F0D, 0x6F16, 0x6F18,\n 0x6F1A, 0x6F1B, 0x6F26, 0x6F29, 0x6F2A, 0x6F2F, 0x6F30, 0x6F33,\n 0x6F36, 0x6F3B, 0x6F3C, 0x6F2D, 0x6F4F, 0x6F51, 0x6F52, 0x6F53,\n 0x6F57, 0x6F59, 0x6F5A, 0x6F5D, 0x6F5E, 0x6F61, 0x6F62, 0x6F68,\n 0x6F6C, 0x6F7D, 0x6F7E, 0x6F83, 0x6F87, 0x6F88, 0x6F8B, 0x6F8C,\n 0x6F8D, 0x6F90, 0x6F92, 0x6F93, 0x6F94, 0x6F96, 0x6F9A, 0x6F9F,\n 0x6FA0, 0x6FA5, 0x6FA6, 0x6FA7, 0x6FA8, 0x6FAE, 0x6FAF, 0x6FB0,\n 0x6FB5, 0x6FB6, 0x6FBC, 0x6FC5, 0x6FC7, 0x6FC8, 0x6FCA,\n};\nconst unsigned short euc_to_utf8_8FC9[] = {\n         0x6FDA, 0x6FDE, 0x6FE8, 0x6FE9, 0x6FF0, 0x6FF5, 0x6FF9,\n 0x6FFC, 0x6FFD, 0x7000, 0x7005, 0x7006, 0x7007, 0x700D, 0x7017,\n 0x7020, 0x7023, 0x702F, 0x7034, 0x7037, 0x7039, 0x703C, 0x7043,\n 0x7044, 0x7048, 0x7049, 0x704A, 0x704B, 0x7054, 0x7055, 0x705D,\n 0x705E, 0x704E, 0x7064, 0x7065, 0x706C, 0x706E, 0x7075, 0x7076,\n 0x707E, 0x7081, 0x7085, 0x7086, 0x7094, 0x7095, 0x7096, 0x7097,\n 0x7098, 0x709B, 0x70A4, 0x70AB, 0x70B0, 0x70B1, 0x70B4, 0x70B7,\n 0x70CA, 0x70D1, 0x70D3, 0x70D4, 0x70D5, 0x70D6, 0x70D8, 0x70DC,\n 0x70E4, 0x70FA, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x710B,\n 0x710C, 0x710F, 0x711E, 0x7120, 0x712B, 0x712D, 0x712F, 0x7130,\n 0x7131, 0x7138, 0x7141, 0x7145, 0x7146, 0x7147, 0x714A, 0x714B,\n 0x7150, 0x7152, 0x7157, 0x715A, 0x715C, 0x715E, 0x7160,\n};\nconst unsigned short euc_to_utf8_8FCA[] = {\n         0x7168, 0x7179, 0x7180, 0x7185, 0x7187, 0x718C, 0x7192,\n 0x719A, 0x719B, 0x71A0, 0x71A2, 0x71AF, 0x71B0, 0x71B2, 0x71B3,\n 0x71BA, 0x71BF, 0x71C0, 0x71C1, 0x71C4, 0x71CB, 0x71CC, 0x71D3,\n 0x71D6, 0x71D9, 0x71DA, 0x71DC, 0x71F8, 0x71FE, 0x7200, 0x7207,\n 0x7208, 0x7209, 0x7213, 0x7217, 0x721A, 0x721D, 0x721F, 0x7224,\n 0x722B, 0x722F, 0x7234, 0x7238, 0x7239, 0x7241, 0x7242, 0x7243,\n 0x7245, 0x724E, 0x724F, 0x7250, 0x7253, 0x7255, 0x7256, 0x725A,\n 0x725C, 0x725E, 0x7260, 0x7263, 0x7268, 0x726B, 0x726E, 0x726F,\n 0x7271, 0x7277, 0x7278, 0x727B, 0x727C, 0x727F, 0x7284, 0x7289,\n 0x728D, 0x728E, 0x7293, 0x729B, 0x72A8, 0x72AD, 0x72AE, 0x72B1,\n 0x72B4, 0x72BE, 0x72C1, 0x72C7, 0x72C9, 0x72CC, 0x72D5, 0x72D6,\n 0x72D8, 0x72DF, 0x72E5, 0x72F3, 0x72F4, 0x72FA, 0x72FB,\n};\nconst unsigned short euc_to_utf8_8FCB[] = {\n         0x72FE, 0x7302, 0x7304, 0x7305, 0x7307, 0x730B, 0x730D,\n 0x7312, 0x7313, 0x7318, 0x7319, 0x731E, 0x7322, 0x7324, 0x7327,\n 0x7328, 0x732C, 0x7331, 0x7332, 0x7335, 0x733A, 0x733B, 0x733D,\n 0x7343, 0x734D, 0x7350, 0x7352, 0x7356, 0x7358, 0x735D, 0x735E,\n 0x735F, 0x7360, 0x7366, 0x7367, 0x7369, 0x736B, 0x736C, 0x736E,\n 0x736F, 0x7371, 0x7377, 0x7379, 0x737C, 0x7380, 0x7381, 0x7383,\n 0x7385, 0x7386, 0x738E, 0x7390, 0x7393, 0x7395, 0x7397, 0x7398,\n 0x739C, 0x739E, 0x739F, 0x73A0, 0x73A2, 0x73A5, 0x73A6, 0x73AA,\n 0x73AB, 0x73AD, 0x73B5, 0x73B7, 0x73B9, 0x73BC, 0x73BD, 0x73BF,\n 0x73C5, 0x73C6, 0x73C9, 0x73CB, 0x73CC, 0x73CF, 0x73D2, 0x73D3,\n 0x73D6, 0x73D9, 0x73DD, 0x73E1, 0x73E3, 0x73E6, 0x73E7, 0x73E9,\n 0x73F4, 0x73F5, 0x73F7, 0x73F9, 0x73FA, 0x73FB, 0x73FD,\n};\nconst unsigned short euc_to_utf8_8FCC[] = {\n         0x73FF, 0x7400, 0x7401, 0x7404, 0x7407, 0x740A, 0x7411,\n 0x741A, 0x741B, 0x7424, 0x7426, 0x7428, 0x7429, 0x742A, 0x742B,\n 0x742C, 0x742D, 0x742E, 0x742F, 0x7430, 0x7431, 0x7439, 0x7440,\n 0x7443, 0x7444, 0x7446, 0x7447, 0x744B, 0x744D, 0x7451, 0x7452,\n 0x7457, 0x745D, 0x7462, 0x7466, 0x7467, 0x7468, 0x746B, 0x746D,\n 0x746E, 0x7471, 0x7472, 0x7480, 0x7481, 0x7485, 0x7486, 0x7487,\n 0x7489, 0x748F, 0x7490, 0x7491, 0x7492, 0x7498, 0x7499, 0x749A,\n 0x749C, 0x749F, 0x74A0, 0x74A1, 0x74A3, 0x74A6, 0x74A8, 0x74A9,\n 0x74AA, 0x74AB, 0x74AE, 0x74AF, 0x74B1, 0x74B2, 0x74B5, 0x74B9,\n 0x74BB, 0x74BF, 0x74C8, 0x74C9, 0x74CC, 0x74D0, 0x74D3, 0x74D8,\n 0x74DA, 0x74DB, 0x74DE, 0x74DF, 0x74E4, 0x74E8, 0x74EA, 0x74EB,\n 0x74EF, 0x74F4, 0x74FA, 0x74FB, 0x74FC, 0x74FF, 0x7506,\n};\nconst unsigned short euc_to_utf8_8FCD[] = {\n         0x7512, 0x7516, 0x7517, 0x7520, 0x7521, 0x7524, 0x7527,\n 0x7529, 0x752A, 0x752F, 0x7536, 0x7539, 0x753D, 0x753E, 0x753F,\n 0x7540, 0x7543, 0x7547, 0x7548, 0x754E, 0x7550, 0x7552, 0x7557,\n 0x755E, 0x755F, 0x7561, 0x756F, 0x7571, 0x7579, 0x757A, 0x757B,\n 0x757C, 0x757D, 0x757E, 0x7581, 0x7585, 0x7590, 0x7592, 0x7593,\n 0x7595, 0x7599, 0x759C, 0x75A2, 0x75A4, 0x75B4, 0x75BA, 0x75BF,\n 0x75C0, 0x75C1, 0x75C4, 0x75C6, 0x75CC, 0x75CE, 0x75CF, 0x75D7,\n 0x75DC, 0x75DF, 0x75E0, 0x75E1, 0x75E4, 0x75E7, 0x75EC, 0x75EE,\n 0x75EF, 0x75F1, 0x75F9, 0x7600, 0x7602, 0x7603, 0x7604, 0x7607,\n 0x7608, 0x760A, 0x760C, 0x760F, 0x7612, 0x7613, 0x7615, 0x7616,\n 0x7619, 0x761B, 0x761C, 0x761D, 0x761E, 0x7623, 0x7625, 0x7626,\n 0x7629, 0x762D, 0x7632, 0x7633, 0x7635, 0x7638, 0x7639,\n};\nconst unsigned short euc_to_utf8_8FCE[] = {\n         0x763A, 0x763C, 0x764A, 0x7640, 0x7641, 0x7643, 0x7644,\n 0x7645, 0x7649, 0x764B, 0x7655, 0x7659, 0x765F, 0x7664, 0x7665,\n 0x766D, 0x766E, 0x766F, 0x7671, 0x7674, 0x7681, 0x7685, 0x768C,\n 0x768D, 0x7695, 0x769B, 0x769C, 0x769D, 0x769F, 0x76A0, 0x76A2,\n 0x76A3, 0x76A4, 0x76A5, 0x76A6, 0x76A7, 0x76A8, 0x76AA, 0x76AD,\n 0x76BD, 0x76C1, 0x76C5, 0x76C9, 0x76CB, 0x76CC, 0x76CE, 0x76D4,\n 0x76D9, 0x76E0, 0x76E6, 0x76E8, 0x76EC, 0x76F0, 0x76F1, 0x76F6,\n 0x76F9, 0x76FC, 0x7700, 0x7706, 0x770A, 0x770E, 0x7712, 0x7714,\n 0x7715, 0x7717, 0x7719, 0x771A, 0x771C, 0x7722, 0x7728, 0x772D,\n 0x772E, 0x772F, 0x7734, 0x7735, 0x7736, 0x7739, 0x773D, 0x773E,\n 0x7742, 0x7745, 0x7746, 0x774A, 0x774D, 0x774E, 0x774F, 0x7752,\n 0x7756, 0x7757, 0x775C, 0x775E, 0x775F, 0x7760, 0x7762,\n};\nconst unsigned short euc_to_utf8_8FCF[] = {\n         0x7764, 0x7767, 0x776A, 0x776C, 0x7770, 0x7772, 0x7773,\n 0x7774, 0x777A, 0x777D, 0x7780, 0x7784, 0x778C, 0x778D, 0x7794,\n 0x7795, 0x7796, 0x779A, 0x779F, 0x77A2, 0x77A7, 0x77AA, 0x77AE,\n 0x77AF, 0x77B1, 0x77B5, 0x77BE, 0x77C3, 0x77C9, 0x77D1, 0x77D2,\n 0x77D5, 0x77D9, 0x77DE, 0x77DF, 0x77E0, 0x77E4, 0x77E6, 0x77EA,\n 0x77EC, 0x77F0, 0x77F1, 0x77F4, 0x77F8, 0x77FB, 0x7805, 0x7806,\n 0x7809, 0x780D, 0x780E, 0x7811, 0x781D, 0x7821, 0x7822, 0x7823,\n 0x782D, 0x782E, 0x7830, 0x7835, 0x7837, 0x7843, 0x7844, 0x7847,\n 0x7848, 0x784C, 0x784E, 0x7852, 0x785C, 0x785E, 0x7860, 0x7861,\n 0x7863, 0x7864, 0x7868, 0x786A, 0x786E, 0x787A, 0x787E, 0x788A,\n 0x788F, 0x7894, 0x7898, 0x78A1, 0x789D, 0x789E, 0x789F, 0x78A4,\n 0x78A8, 0x78AC, 0x78AD, 0x78B0, 0x78B1, 0x78B2, 0x78B3,\n};\nconst unsigned short euc_to_utf8_8FD0[] = {\n         0x78BB, 0x78BD, 0x78BF, 0x78C7, 0x78C8, 0x78C9, 0x78CC,\n 0x78CE, 0x78D2, 0x78D3, 0x78D5, 0x78D6, 0x78E4, 0x78DB, 0x78DF,\n 0x78E0, 0x78E1, 0x78E6, 0x78EA, 0x78F2, 0x78F3, 0x7900, 0x78F6,\n 0x78F7, 0x78FA, 0x78FB, 0x78FF, 0x7906, 0x790C, 0x7910, 0x791A,\n 0x791C, 0x791E, 0x791F, 0x7920, 0x7925, 0x7927, 0x7929, 0x792D,\n 0x7931, 0x7934, 0x7935, 0x793B, 0x793D, 0x793F, 0x7944, 0x7945,\n 0x7946, 0x794A, 0x794B, 0x794F, 0x7951, 0x7954, 0x7958, 0x795B,\n 0x795C, 0x7967, 0x7969, 0x796B, 0x7972, 0x7979, 0x797B, 0x797C,\n 0x797E, 0x798B, 0x798C, 0x7991, 0x7993, 0x7994, 0x7995, 0x7996,\n 0x7998, 0x799B, 0x799C, 0x79A1, 0x79A8, 0x79A9, 0x79AB, 0x79AF,\n 0x79B1, 0x79B4, 0x79B8, 0x79BB, 0x79C2, 0x79C4, 0x79C7, 0x79C8,\n 0x79CA, 0x79CF, 0x79D4, 0x79D6, 0x79DA, 0x79DD, 0x79DE,\n};\nconst unsigned short euc_to_utf8_8FD1[] = {\n         0x79E0, 0x79E2, 0x79E5, 0x79EA, 0x79EB, 0x79ED, 0x79F1,\n 0x79F8, 0x79FC, 0x7A02, 0x7A03, 0x7A07, 0x7A09, 0x7A0A, 0x7A0C,\n 0x7A11, 0x7A15, 0x7A1B, 0x7A1E, 0x7A21, 0x7A27, 0x7A2B, 0x7A2D,\n 0x7A2F, 0x7A30, 0x7A34, 0x7A35, 0x7A38, 0x7A39, 0x7A3A, 0x7A44,\n 0x7A45, 0x7A47, 0x7A48, 0x7A4C, 0x7A55, 0x7A56, 0x7A59, 0x7A5C,\n 0x7A5D, 0x7A5F, 0x7A60, 0x7A65, 0x7A67, 0x7A6A, 0x7A6D, 0x7A75,\n 0x7A78, 0x7A7E, 0x7A80, 0x7A82, 0x7A85, 0x7A86, 0x7A8A, 0x7A8B,\n 0x7A90, 0x7A91, 0x7A94, 0x7A9E, 0x7AA0, 0x7AA3, 0x7AAC, 0x7AB3,\n 0x7AB5, 0x7AB9, 0x7ABB, 0x7ABC, 0x7AC6, 0x7AC9, 0x7ACC, 0x7ACE,\n 0x7AD1, 0x7ADB, 0x7AE8, 0x7AE9, 0x7AEB, 0x7AEC, 0x7AF1, 0x7AF4,\n 0x7AFB, 0x7AFD, 0x7AFE, 0x7B07, 0x7B14, 0x7B1F, 0x7B23, 0x7B27,\n 0x7B29, 0x7B2A, 0x7B2B, 0x7B2D, 0x7B2E, 0x7B2F, 0x7B30,\n};\nconst unsigned short euc_to_utf8_8FD2[] = {\n         0x7B31, 0x7B34, 0x7B3D, 0x7B3F, 0x7B40, 0x7B41, 0x7B47,\n 0x7B4E, 0x7B55, 0x7B60, 0x7B64, 0x7B66, 0x7B69, 0x7B6A, 0x7B6D,\n 0x7B6F, 0x7B72, 0x7B73, 0x7B77, 0x7B84, 0x7B89, 0x7B8E, 0x7B90,\n 0x7B91, 0x7B96, 0x7B9B, 0x7B9E, 0x7BA0, 0x7BA5, 0x7BAC, 0x7BAF,\n 0x7BB0, 0x7BB2, 0x7BB5, 0x7BB6, 0x7BBA, 0x7BBB, 0x7BBC, 0x7BBD,\n 0x7BC2, 0x7BC5, 0x7BC8, 0x7BCA, 0x7BD4, 0x7BD6, 0x7BD7, 0x7BD9,\n 0x7BDA, 0x7BDB, 0x7BE8, 0x7BEA, 0x7BF2, 0x7BF4, 0x7BF5, 0x7BF8,\n 0x7BF9, 0x7BFA, 0x7BFC, 0x7BFE, 0x7C01, 0x7C02, 0x7C03, 0x7C04,\n 0x7C06, 0x7C09, 0x7C0B, 0x7C0C, 0x7C0E, 0x7C0F, 0x7C19, 0x7C1B,\n 0x7C20, 0x7C25, 0x7C26, 0x7C28, 0x7C2C, 0x7C31, 0x7C33, 0x7C34,\n 0x7C36, 0x7C39, 0x7C3A, 0x7C46, 0x7C4A, 0x7C55, 0x7C51, 0x7C52,\n 0x7C53, 0x7C59, 0x7C5A, 0x7C5B, 0x7C5C, 0x7C5D, 0x7C5E,\n};\nconst unsigned short euc_to_utf8_8FD3[] = {\n         0x7C61, 0x7C63, 0x7C67, 0x7C69, 0x7C6D, 0x7C6E, 0x7C70,\n 0x7C72, 0x7C79, 0x7C7C, 0x7C7D, 0x7C86, 0x7C87, 0x7C8F, 0x7C94,\n 0x7C9E, 0x7CA0, 0x7CA6, 0x7CB0, 0x7CB6, 0x7CB7, 0x7CBA, 0x7CBB,\n 0x7CBC, 0x7CBF, 0x7CC4, 0x7CC7, 0x7CC8, 0x7CC9, 0x7CCD, 0x7CCF,\n 0x7CD3, 0x7CD4, 0x7CD5, 0x7CD7, 0x7CD9, 0x7CDA, 0x7CDD, 0x7CE6,\n 0x7CE9, 0x7CEB, 0x7CF5, 0x7D03, 0x7D07, 0x7D08, 0x7D09, 0x7D0F,\n 0x7D11, 0x7D12, 0x7D13, 0x7D16, 0x7D1D, 0x7D1E, 0x7D23, 0x7D26,\n 0x7D2A, 0x7D2D, 0x7D31, 0x7D3C, 0x7D3D, 0x7D3E, 0x7D40, 0x7D41,\n 0x7D47, 0x7D48, 0x7D4D, 0x7D51, 0x7D53, 0x7D57, 0x7D59, 0x7D5A,\n 0x7D5C, 0x7D5D, 0x7D65, 0x7D67, 0x7D6A, 0x7D70, 0x7D78, 0x7D7A,\n 0x7D7B, 0x7D7F, 0x7D81, 0x7D82, 0x7D83, 0x7D85, 0x7D86, 0x7D88,\n 0x7D8B, 0x7D8C, 0x7D8D, 0x7D91, 0x7D96, 0x7D97, 0x7D9D,\n};\nconst unsigned short euc_to_utf8_8FD4[] = {\n         0x7D9E, 0x7DA6, 0x7DA7, 0x7DAA, 0x7DB3, 0x7DB6, 0x7DB7,\n 0x7DB9, 0x7DC2, 0x7DC3, 0x7DC4, 0x7DC5, 0x7DC6, 0x7DCC, 0x7DCD,\n 0x7DCE, 0x7DD7, 0x7DD9, 0x7E00, 0x7DE2, 0x7DE5, 0x7DE6, 0x7DEA,\n 0x7DEB, 0x7DED, 0x7DF1, 0x7DF5, 0x7DF6, 0x7DF9, 0x7DFA, 0x7E08,\n 0x7E10, 0x7E11, 0x7E15, 0x7E17, 0x7E1C, 0x7E1D, 0x7E20, 0x7E27,\n 0x7E28, 0x7E2C, 0x7E2D, 0x7E2F, 0x7E33, 0x7E36, 0x7E3F, 0x7E44,\n 0x7E45, 0x7E47, 0x7E4E, 0x7E50, 0x7E52, 0x7E58, 0x7E5F, 0x7E61,\n 0x7E62, 0x7E65, 0x7E6B, 0x7E6E, 0x7E6F, 0x7E73, 0x7E78, 0x7E7E,\n 0x7E81, 0x7E86, 0x7E87, 0x7E8A, 0x7E8D, 0x7E91, 0x7E95, 0x7E98,\n 0x7E9A, 0x7E9D, 0x7E9E, 0x7F3C, 0x7F3B, 0x7F3D, 0x7F3E, 0x7F3F,\n 0x7F43, 0x7F44, 0x7F47, 0x7F4F, 0x7F52, 0x7F53, 0x7F5B, 0x7F5C,\n 0x7F5D, 0x7F61, 0x7F63, 0x7F64, 0x7F65, 0x7F66, 0x7F6D,\n};\nconst unsigned short euc_to_utf8_8FD5[] = {\n         0x7F71, 0x7F7D, 0x7F7E, 0x7F7F, 0x7F80, 0x7F8B, 0x7F8D,\n 0x7F8F, 0x7F90, 0x7F91, 0x7F96, 0x7F97, 0x7F9C, 0x7FA1, 0x7FA2,\n 0x7FA6, 0x7FAA, 0x7FAD, 0x7FB4, 0x7FBC, 0x7FBF, 0x7FC0, 0x7FC3,\n 0x7FC8, 0x7FCE, 0x7FCF, 0x7FDB, 0x7FDF, 0x7FE3, 0x7FE5, 0x7FE8,\n 0x7FEC, 0x7FEE, 0x7FEF, 0x7FF2, 0x7FFA, 0x7FFD, 0x7FFE, 0x7FFF,\n 0x8007, 0x8008, 0x800A, 0x800D, 0x800E, 0x800F, 0x8011, 0x8013,\n 0x8014, 0x8016, 0x801D, 0x801E, 0x801F, 0x8020, 0x8024, 0x8026,\n 0x802C, 0x802E, 0x8030, 0x8034, 0x8035, 0x8037, 0x8039, 0x803A,\n 0x803C, 0x803E, 0x8040, 0x8044, 0x8060, 0x8064, 0x8066, 0x806D,\n 0x8071, 0x8075, 0x8081, 0x8088, 0x808E, 0x809C, 0x809E, 0x80A6,\n 0x80A7, 0x80AB, 0x80B8, 0x80B9, 0x80C8, 0x80CD, 0x80CF, 0x80D2,\n 0x80D4, 0x80D5, 0x80D7, 0x80D8, 0x80E0, 0x80ED, 0x80EE,\n};\nconst unsigned short euc_to_utf8_8FD6[] = {\n         0x80F0, 0x80F2, 0x80F3, 0x80F6, 0x80F9, 0x80FA, 0x80FE,\n 0x8103, 0x810B, 0x8116, 0x8117, 0x8118, 0x811C, 0x811E, 0x8120,\n 0x8124, 0x8127, 0x812C, 0x8130, 0x8135, 0x813A, 0x813C, 0x8145,\n 0x8147, 0x814A, 0x814C, 0x8152, 0x8157, 0x8160, 0x8161, 0x8167,\n 0x8168, 0x8169, 0x816D, 0x816F, 0x8177, 0x8181, 0x8190, 0x8184,\n 0x8185, 0x8186, 0x818B, 0x818E, 0x8196, 0x8198, 0x819B, 0x819E,\n 0x81A2, 0x81AE, 0x81B2, 0x81B4, 0x81BB, 0x81CB, 0x81C3, 0x81C5,\n 0x81CA, 0x81CE, 0x81CF, 0x81D5, 0x81D7, 0x81DB, 0x81DD, 0x81DE,\n 0x81E1, 0x81E4, 0x81EB, 0x81EC, 0x81F0, 0x81F1, 0x81F2, 0x81F5,\n 0x81F6, 0x81F8, 0x81F9, 0x81FD, 0x81FF, 0x8200, 0x8203, 0x820F,\n 0x8213, 0x8214, 0x8219, 0x821A, 0x821D, 0x8221, 0x8222, 0x8228,\n 0x8232, 0x8234, 0x823A, 0x8243, 0x8244, 0x8245, 0x8246,\n};\nconst unsigned short euc_to_utf8_8FD7[] = {\n         0x824B, 0x824E, 0x824F, 0x8251, 0x8256, 0x825C, 0x8260,\n 0x8263, 0x8267, 0x826D, 0x8274, 0x827B, 0x827D, 0x827F, 0x8280,\n 0x8281, 0x8283, 0x8284, 0x8287, 0x8289, 0x828A, 0x828E, 0x8291,\n 0x8294, 0x8296, 0x8298, 0x829A, 0x829B, 0x82A0, 0x82A1, 0x82A3,\n 0x82A4, 0x82A7, 0x82A8, 0x82A9, 0x82AA, 0x82AE, 0x82B0, 0x82B2,\n 0x82B4, 0x82B7, 0x82BA, 0x82BC, 0x82BE, 0x82BF, 0x82C6, 0x82D0,\n 0x82D5, 0x82DA, 0x82E0, 0x82E2, 0x82E4, 0x82E8, 0x82EA, 0x82ED,\n 0x82EF, 0x82F6, 0x82F7, 0x82FD, 0x82FE, 0x8300, 0x8301, 0x8307,\n 0x8308, 0x830A, 0x830B, 0x8354, 0x831B, 0x831D, 0x831E, 0x831F,\n 0x8321, 0x8322, 0x832C, 0x832D, 0x832E, 0x8330, 0x8333, 0x8337,\n 0x833A, 0x833C, 0x833D, 0x8342, 0x8343, 0x8344, 0x8347, 0x834D,\n 0x834E, 0x8351, 0x8355, 0x8356, 0x8357, 0x8370, 0x8378,\n};\nconst unsigned short euc_to_utf8_8FD8[] = {\n         0x837D, 0x837F, 0x8380, 0x8382, 0x8384, 0x8386, 0x838D,\n 0x8392, 0x8394, 0x8395, 0x8398, 0x8399, 0x839B, 0x839C, 0x839D,\n 0x83A6, 0x83A7, 0x83A9, 0x83AC, 0x83BE, 0x83BF, 0x83C0, 0x83C7,\n 0x83C9, 0x83CF, 0x83D0, 0x83D1, 0x83D4, 0x83DD, 0x8353, 0x83E8,\n 0x83EA, 0x83F6, 0x83F8, 0x83F9, 0x83FC, 0x8401, 0x8406, 0x840A,\n 0x840F, 0x8411, 0x8415, 0x8419, 0x83AD, 0x842F, 0x8439, 0x8445,\n 0x8447, 0x8448, 0x844A, 0x844D, 0x844F, 0x8451, 0x8452, 0x8456,\n 0x8458, 0x8459, 0x845A, 0x845C, 0x8460, 0x8464, 0x8465, 0x8467,\n 0x846A, 0x8470, 0x8473, 0x8474, 0x8476, 0x8478, 0x847C, 0x847D,\n 0x8481, 0x8485, 0x8492, 0x8493, 0x8495, 0x849E, 0x84A6, 0x84A8,\n 0x84A9, 0x84AA, 0x84AF, 0x84B1, 0x84B4, 0x84BA, 0x84BD, 0x84BE,\n 0x84C0, 0x84C2, 0x84C7, 0x84C8, 0x84CC, 0x84CF, 0x84D3,\n};\nconst unsigned short euc_to_utf8_8FD9[] = {\n         0x84DC, 0x84E7, 0x84EA, 0x84EF, 0x84F0, 0x84F1, 0x84F2,\n 0x84F7, 0x8532, 0x84FA, 0x84FB, 0x84FD, 0x8502, 0x8503, 0x8507,\n 0x850C, 0x850E, 0x8510, 0x851C, 0x851E, 0x8522, 0x8523, 0x8524,\n 0x8525, 0x8527, 0x852A, 0x852B, 0x852F, 0x8533, 0x8534, 0x8536,\n 0x853F, 0x8546, 0x854F, 0x8550, 0x8551, 0x8552, 0x8553, 0x8556,\n 0x8559, 0x855C, 0x855D, 0x855E, 0x855F, 0x8560, 0x8561, 0x8562,\n 0x8564, 0x856B, 0x856F, 0x8579, 0x857A, 0x857B, 0x857D, 0x857F,\n 0x8581, 0x8585, 0x8586, 0x8589, 0x858B, 0x858C, 0x858F, 0x8593,\n 0x8598, 0x859D, 0x859F, 0x85A0, 0x85A2, 0x85A5, 0x85A7, 0x85B4,\n 0x85B6, 0x85B7, 0x85B8, 0x85BC, 0x85BD, 0x85BE, 0x85BF, 0x85C2,\n 0x85C7, 0x85CA, 0x85CB, 0x85CE, 0x85AD, 0x85D8, 0x85DA, 0x85DF,\n 0x85E0, 0x85E6, 0x85E8, 0x85ED, 0x85F3, 0x85F6, 0x85FC,\n};\nconst unsigned short euc_to_utf8_8FDA[] = {\n         0x85FF, 0x8600, 0x8604, 0x8605, 0x860D, 0x860E, 0x8610,\n 0x8611, 0x8612, 0x8618, 0x8619, 0x861B, 0x861E, 0x8621, 0x8627,\n 0x8629, 0x8636, 0x8638, 0x863A, 0x863C, 0x863D, 0x8640, 0x8642,\n 0x8646, 0x8652, 0x8653, 0x8656, 0x8657, 0x8658, 0x8659, 0x865D,\n 0x8660, 0x8661, 0x8662, 0x8663, 0x8664, 0x8669, 0x866C, 0x866F,\n 0x8675, 0x8676, 0x8677, 0x867A, 0x868D, 0x8691, 0x8696, 0x8698,\n 0x869A, 0x869C, 0x86A1, 0x86A6, 0x86A7, 0x86A8, 0x86AD, 0x86B1,\n 0x86B3, 0x86B4, 0x86B5, 0x86B7, 0x86B8, 0x86B9, 0x86BF, 0x86C0,\n 0x86C1, 0x86C3, 0x86C5, 0x86D1, 0x86D2, 0x86D5, 0x86D7, 0x86DA,\n 0x86DC, 0x86E0, 0x86E3, 0x86E5, 0x86E7, 0x8688, 0x86FA, 0x86FC,\n 0x86FD, 0x8704, 0x8705, 0x8707, 0x870B, 0x870E, 0x870F, 0x8710,\n 0x8713, 0x8714, 0x8719, 0x871E, 0x871F, 0x8721, 0x8723,\n};\nconst unsigned short euc_to_utf8_8FDB[] = {\n         0x8728, 0x872E, 0x872F, 0x8731, 0x8732, 0x8739, 0x873A,\n 0x873C, 0x873D, 0x873E, 0x8740, 0x8743, 0x8745, 0x874D, 0x8758,\n 0x875D, 0x8761, 0x8764, 0x8765, 0x876F, 0x8771, 0x8772, 0x877B,\n 0x8783, 0x8784, 0x8785, 0x8786, 0x8787, 0x8788, 0x8789, 0x878B,\n 0x878C, 0x8790, 0x8793, 0x8795, 0x8797, 0x8798, 0x8799, 0x879E,\n 0x87A0, 0x87A3, 0x87A7, 0x87AC, 0x87AD, 0x87AE, 0x87B1, 0x87B5,\n 0x87BE, 0x87BF, 0x87C1, 0x87C8, 0x87C9, 0x87CA, 0x87CE, 0x87D5,\n 0x87D6, 0x87D9, 0x87DA, 0x87DC, 0x87DF, 0x87E2, 0x87E3, 0x87E4,\n 0x87EA, 0x87EB, 0x87ED, 0x87F1, 0x87F3, 0x87F8, 0x87FA, 0x87FF,\n 0x8801, 0x8803, 0x8806, 0x8809, 0x880A, 0x880B, 0x8810, 0x8819,\n 0x8812, 0x8813, 0x8814, 0x8818, 0x881A, 0x881B, 0x881C, 0x881E,\n 0x881F, 0x8828, 0x882D, 0x882E, 0x8830, 0x8832, 0x8835,\n};\nconst unsigned short euc_to_utf8_8FDC[] = {\n         0x883A, 0x883C, 0x8841, 0x8843, 0x8845, 0x8848, 0x8849,\n 0x884A, 0x884B, 0x884E, 0x8851, 0x8855, 0x8856, 0x8858, 0x885A,\n 0x885C, 0x885F, 0x8860, 0x8864, 0x8869, 0x8871, 0x8879, 0x887B,\n 0x8880, 0x8898, 0x889A, 0x889B, 0x889C, 0x889F, 0x88A0, 0x88A8,\n 0x88AA, 0x88BA, 0x88BD, 0x88BE, 0x88C0, 0x88CA, 0x88CB, 0x88CC,\n 0x88CD, 0x88CE, 0x88D1, 0x88D2, 0x88D3, 0x88DB, 0x88DE, 0x88E7,\n 0x88EF, 0x88F0, 0x88F1, 0x88F5, 0x88F7, 0x8901, 0x8906, 0x890D,\n 0x890E, 0x890F, 0x8915, 0x8916, 0x8918, 0x8919, 0x891A, 0x891C,\n 0x8920, 0x8926, 0x8927, 0x8928, 0x8930, 0x8931, 0x8932, 0x8935,\n 0x8939, 0x893A, 0x893E, 0x8940, 0x8942, 0x8945, 0x8946, 0x8949,\n 0x894F, 0x8952, 0x8957, 0x895A, 0x895B, 0x895C, 0x8961, 0x8962,\n 0x8963, 0x896B, 0x896E, 0x8970, 0x8973, 0x8975, 0x897A,\n};\nconst unsigned short euc_to_utf8_8FDD[] = {\n         0x897B, 0x897C, 0x897D, 0x8989, 0x898D, 0x8990, 0x8994,\n 0x8995, 0x899B, 0x899C, 0x899F, 0x89A0, 0x89A5, 0x89B0, 0x89B4,\n 0x89B5, 0x89B6, 0x89B7, 0x89BC, 0x89D4, 0x89D5, 0x89D6, 0x89D7,\n 0x89D8, 0x89E5, 0x89E9, 0x89EB, 0x89ED, 0x89F1, 0x89F3, 0x89F6,\n 0x89F9, 0x89FD, 0x89FF, 0x8A04, 0x8A05, 0x8A07, 0x8A0F, 0x8A11,\n 0x8A12, 0x8A14, 0x8A15, 0x8A1E, 0x8A20, 0x8A22, 0x8A24, 0x8A26,\n 0x8A2B, 0x8A2C, 0x8A2F, 0x8A35, 0x8A37, 0x8A3D, 0x8A3E, 0x8A40,\n 0x8A43, 0x8A45, 0x8A47, 0x8A49, 0x8A4D, 0x8A4E, 0x8A53, 0x8A56,\n 0x8A57, 0x8A58, 0x8A5C, 0x8A5D, 0x8A61, 0x8A65, 0x8A67, 0x8A75,\n 0x8A76, 0x8A77, 0x8A79, 0x8A7A, 0x8A7B, 0x8A7E, 0x8A7F, 0x8A80,\n 0x8A83, 0x8A86, 0x8A8B, 0x8A8F, 0x8A90, 0x8A92, 0x8A96, 0x8A97,\n 0x8A99, 0x8A9F, 0x8AA7, 0x8AA9, 0x8AAE, 0x8AAF, 0x8AB3,\n};\nconst unsigned short euc_to_utf8_8FDE[] = {\n         0x8AB6, 0x8AB7, 0x8ABB, 0x8ABE, 0x8AC3, 0x8AC6, 0x8AC8,\n 0x8AC9, 0x8ACA, 0x8AD1, 0x8AD3, 0x8AD4, 0x8AD5, 0x8AD7, 0x8ADD,\n 0x8ADF, 0x8AEC, 0x8AF0, 0x8AF4, 0x8AF5, 0x8AF6, 0x8AFC, 0x8AFF,\n 0x8B05, 0x8B06, 0x8B0B, 0x8B11, 0x8B1C, 0x8B1E, 0x8B1F, 0x8B0A,\n 0x8B2D, 0x8B30, 0x8B37, 0x8B3C, 0x8B42, 0x8B43, 0x8B44, 0x8B45,\n 0x8B46, 0x8B48, 0x8B52, 0x8B53, 0x8B54, 0x8B59, 0x8B4D, 0x8B5E,\n 0x8B63, 0x8B6D, 0x8B76, 0x8B78, 0x8B79, 0x8B7C, 0x8B7E, 0x8B81,\n 0x8B84, 0x8B85, 0x8B8B, 0x8B8D, 0x8B8F, 0x8B94, 0x8B95, 0x8B9C,\n 0x8B9E, 0x8B9F, 0x8C38, 0x8C39, 0x8C3D, 0x8C3E, 0x8C45, 0x8C47,\n 0x8C49, 0x8C4B, 0x8C4F, 0x8C51, 0x8C53, 0x8C54, 0x8C57, 0x8C58,\n 0x8C5B, 0x8C5D, 0x8C59, 0x8C63, 0x8C64, 0x8C66, 0x8C68, 0x8C69,\n 0x8C6D, 0x8C73, 0x8C75, 0x8C76, 0x8C7B, 0x8C7E, 0x8C86,\n};\nconst unsigned short euc_to_utf8_8FDF[] = {\n         0x8C87, 0x8C8B, 0x8C90, 0x8C92, 0x8C93, 0x8C99, 0x8C9B,\n 0x8C9C, 0x8CA4, 0x8CB9, 0x8CBA, 0x8CC5, 0x8CC6, 0x8CC9, 0x8CCB,\n 0x8CCF, 0x8CD6, 0x8CD5, 0x8CD9, 0x8CDD, 0x8CE1, 0x8CE8, 0x8CEC,\n 0x8CEF, 0x8CF0, 0x8CF2, 0x8CF5, 0x8CF7, 0x8CF8, 0x8CFE, 0x8CFF,\n 0x8D01, 0x8D03, 0x8D09, 0x8D12, 0x8D17, 0x8D1B, 0x8D65, 0x8D69,\n 0x8D6C, 0x8D6E, 0x8D7F, 0x8D82, 0x8D84, 0x8D88, 0x8D8D, 0x8D90,\n 0x8D91, 0x8D95, 0x8D9E, 0x8D9F, 0x8DA0, 0x8DA6, 0x8DAB, 0x8DAC,\n 0x8DAF, 0x8DB2, 0x8DB5, 0x8DB7, 0x8DB9, 0x8DBB, 0x8DC0, 0x8DC5,\n 0x8DC6, 0x8DC7, 0x8DC8, 0x8DCA, 0x8DCE, 0x8DD1, 0x8DD4, 0x8DD5,\n 0x8DD7, 0x8DD9, 0x8DE4, 0x8DE5, 0x8DE7, 0x8DEC, 0x8DF0, 0x8DBC,\n 0x8DF1, 0x8DF2, 0x8DF4, 0x8DFD, 0x8E01, 0x8E04, 0x8E05, 0x8E06,\n 0x8E0B, 0x8E11, 0x8E14, 0x8E16, 0x8E20, 0x8E21, 0x8E22,\n};\nconst unsigned short euc_to_utf8_8FE0[] = {\n         0x8E23, 0x8E26, 0x8E27, 0x8E31, 0x8E33, 0x8E36, 0x8E37,\n 0x8E38, 0x8E39, 0x8E3D, 0x8E40, 0x8E41, 0x8E4B, 0x8E4D, 0x8E4E,\n 0x8E4F, 0x8E54, 0x8E5B, 0x8E5C, 0x8E5D, 0x8E5E, 0x8E61, 0x8E62,\n 0x8E69, 0x8E6C, 0x8E6D, 0x8E6F, 0x8E70, 0x8E71, 0x8E79, 0x8E7A,\n 0x8E7B, 0x8E82, 0x8E83, 0x8E89, 0x8E90, 0x8E92, 0x8E95, 0x8E9A,\n 0x8E9B, 0x8E9D, 0x8E9E, 0x8EA2, 0x8EA7, 0x8EA9, 0x8EAD, 0x8EAE,\n 0x8EB3, 0x8EB5, 0x8EBA, 0x8EBB, 0x8EC0, 0x8EC1, 0x8EC3, 0x8EC4,\n 0x8EC7, 0x8ECF, 0x8ED1, 0x8ED4, 0x8EDC, 0x8EE8, 0x8EEE, 0x8EF0,\n 0x8EF1, 0x8EF7, 0x8EF9, 0x8EFA, 0x8EED, 0x8F00, 0x8F02, 0x8F07,\n 0x8F08, 0x8F0F, 0x8F10, 0x8F16, 0x8F17, 0x8F18, 0x8F1E, 0x8F20,\n 0x8F21, 0x8F23, 0x8F25, 0x8F27, 0x8F28, 0x8F2C, 0x8F2D, 0x8F2E,\n 0x8F34, 0x8F35, 0x8F36, 0x8F37, 0x8F3A, 0x8F40, 0x8F41,\n};\nconst unsigned short euc_to_utf8_8FE1[] = {\n         0x8F43, 0x8F47, 0x8F4F, 0x8F51, 0x8F52, 0x8F53, 0x8F54,\n 0x8F55, 0x8F58, 0x8F5D, 0x8F5E, 0x8F65, 0x8F9D, 0x8FA0, 0x8FA1,\n 0x8FA4, 0x8FA5, 0x8FA6, 0x8FB5, 0x8FB6, 0x8FB8, 0x8FBE, 0x8FC0,\n 0x8FC1, 0x8FC6, 0x8FCA, 0x8FCB, 0x8FCD, 0x8FD0, 0x8FD2, 0x8FD3,\n 0x8FD5, 0x8FE0, 0x8FE3, 0x8FE4, 0x8FE8, 0x8FEE, 0x8FF1, 0x8FF5,\n 0x8FF6, 0x8FFB, 0x8FFE, 0x9002, 0x9004, 0x9008, 0x900C, 0x9018,\n 0x901B, 0x9028, 0x9029, 0x902F, 0x902A, 0x902C, 0x902D, 0x9033,\n 0x9034, 0x9037, 0x903F, 0x9043, 0x9044, 0x904C, 0x905B, 0x905D,\n 0x9062, 0x9066, 0x9067, 0x906C, 0x9070, 0x9074, 0x9079, 0x9085,\n 0x9088, 0x908B, 0x908C, 0x908E, 0x9090, 0x9095, 0x9097, 0x9098,\n 0x9099, 0x909B, 0x90A0, 0x90A1, 0x90A2, 0x90A5, 0x90B0, 0x90B2,\n 0x90B3, 0x90B4, 0x90B6, 0x90BD, 0x90CC, 0x90BE, 0x90C3,\n};\nconst unsigned short euc_to_utf8_8FE2[] = {\n         0x90C4, 0x90C5, 0x90C7, 0x90C8, 0x90D5, 0x90D7, 0x90D8,\n 0x90D9, 0x90DC, 0x90DD, 0x90DF, 0x90E5, 0x90D2, 0x90F6, 0x90EB,\n 0x90EF, 0x90F0, 0x90F4, 0x90FE, 0x90FF, 0x9100, 0x9104, 0x9105,\n 0x9106, 0x9108, 0x910D, 0x9110, 0x9114, 0x9116, 0x9117, 0x9118,\n 0x911A, 0x911C, 0x911E, 0x9120, 0x9125, 0x9122, 0x9123, 0x9127,\n 0x9129, 0x912E, 0x912F, 0x9131, 0x9134, 0x9136, 0x9137, 0x9139,\n 0x913A, 0x913C, 0x913D, 0x9143, 0x9147, 0x9148, 0x914F, 0x9153,\n 0x9157, 0x9159, 0x915A, 0x915B, 0x9161, 0x9164, 0x9167, 0x916D,\n 0x9174, 0x9179, 0x917A, 0x917B, 0x9181, 0x9183, 0x9185, 0x9186,\n 0x918A, 0x918E, 0x9191, 0x9193, 0x9194, 0x9195, 0x9198, 0x919E,\n 0x91A1, 0x91A6, 0x91A8, 0x91AC, 0x91AD, 0x91AE, 0x91B0, 0x91B1,\n 0x91B2, 0x91B3, 0x91B6, 0x91BB, 0x91BC, 0x91BD, 0x91BF,\n};\nconst unsigned short euc_to_utf8_8FE3[] = {\n         0x91C2, 0x91C3, 0x91C5, 0x91D3, 0x91D4, 0x91D7, 0x91D9,\n 0x91DA, 0x91DE, 0x91E4, 0x91E5, 0x91E9, 0x91EA, 0x91EC, 0x91ED,\n 0x91EE, 0x91EF, 0x91F0, 0x91F1, 0x91F7, 0x91F9, 0x91FB, 0x91FD,\n 0x9200, 0x9201, 0x9204, 0x9205, 0x9206, 0x9207, 0x9209, 0x920A,\n 0x920C, 0x9210, 0x9212, 0x9213, 0x9216, 0x9218, 0x921C, 0x921D,\n 0x9223, 0x9224, 0x9225, 0x9226, 0x9228, 0x922E, 0x922F, 0x9230,\n 0x9233, 0x9235, 0x9236, 0x9238, 0x9239, 0x923A, 0x923C, 0x923E,\n 0x9240, 0x9242, 0x9243, 0x9246, 0x9247, 0x924A, 0x924D, 0x924E,\n 0x924F, 0x9251, 0x9258, 0x9259, 0x925C, 0x925D, 0x9260, 0x9261,\n 0x9265, 0x9267, 0x9268, 0x9269, 0x926E, 0x926F, 0x9270, 0x9275,\n 0x9276, 0x9277, 0x9278, 0x9279, 0x927B, 0x927C, 0x927D, 0x927F,\n 0x9288, 0x9289, 0x928A, 0x928D, 0x928E, 0x9292, 0x9297,\n};\nconst unsigned short euc_to_utf8_8FE4[] = {\n         0x9299, 0x929F, 0x92A0, 0x92A4, 0x92A5, 0x92A7, 0x92A8,\n 0x92AB, 0x92AF, 0x92B2, 0x92B6, 0x92B8, 0x92BA, 0x92BB, 0x92BC,\n 0x92BD, 0x92BF, 0x92C0, 0x92C1, 0x92C2, 0x92C3, 0x92C5, 0x92C6,\n 0x92C7, 0x92C8, 0x92CB, 0x92CC, 0x92CD, 0x92CE, 0x92D0, 0x92D3,\n 0x92D5, 0x92D7, 0x92D8, 0x92D9, 0x92DC, 0x92DD, 0x92DF, 0x92E0,\n 0x92E1, 0x92E3, 0x92E5, 0x92E7, 0x92E8, 0x92EC, 0x92EE, 0x92F0,\n 0x92F9, 0x92FB, 0x92FF, 0x9300, 0x9302, 0x9308, 0x930D, 0x9311,\n 0x9314, 0x9315, 0x931C, 0x931D, 0x931E, 0x931F, 0x9321, 0x9324,\n 0x9325, 0x9327, 0x9329, 0x932A, 0x9333, 0x9334, 0x9336, 0x9337,\n 0x9347, 0x9348, 0x9349, 0x9350, 0x9351, 0x9352, 0x9355, 0x9357,\n 0x9358, 0x935A, 0x935E, 0x9364, 0x9365, 0x9367, 0x9369, 0x936A,\n 0x936D, 0x936F, 0x9370, 0x9371, 0x9373, 0x9374, 0x9376,\n};\nconst unsigned short euc_to_utf8_8FE5[] = {\n         0x937A, 0x937D, 0x937F, 0x9380, 0x9381, 0x9382, 0x9388,\n 0x938A, 0x938B, 0x938D, 0x938F, 0x9392, 0x9395, 0x9398, 0x939B,\n 0x939E, 0x93A1, 0x93A3, 0x93A4, 0x93A6, 0x93A8, 0x93AB, 0x93B4,\n 0x93B5, 0x93B6, 0x93BA, 0x93A9, 0x93C1, 0x93C4, 0x93C5, 0x93C6,\n 0x93C7, 0x93C9, 0x93CA, 0x93CB, 0x93CC, 0x93CD, 0x93D3, 0x93D9,\n 0x93DC, 0x93DE, 0x93DF, 0x93E2, 0x93E6, 0x93E7, 0x93F9, 0x93F7,\n 0x93F8, 0x93FA, 0x93FB, 0x93FD, 0x9401, 0x9402, 0x9404, 0x9408,\n 0x9409, 0x940D, 0x940E, 0x940F, 0x9415, 0x9416, 0x9417, 0x941F,\n 0x942E, 0x942F, 0x9431, 0x9432, 0x9433, 0x9434, 0x943B, 0x943F,\n 0x943D, 0x9443, 0x9445, 0x9448, 0x944A, 0x944C, 0x9455, 0x9459,\n 0x945C, 0x945F, 0x9461, 0x9463, 0x9468, 0x946B, 0x946D, 0x946E,\n 0x946F, 0x9471, 0x9472, 0x9484, 0x9483, 0x9578, 0x9579,\n};\nconst unsigned short euc_to_utf8_8FE6[] = {\n         0x957E, 0x9584, 0x9588, 0x958C, 0x958D, 0x958E, 0x959D,\n 0x959E, 0x959F, 0x95A1, 0x95A6, 0x95A9, 0x95AB, 0x95AC, 0x95B4,\n 0x95B6, 0x95BA, 0x95BD, 0x95BF, 0x95C6, 0x95C8, 0x95C9, 0x95CB,\n 0x95D0, 0x95D1, 0x95D2, 0x95D3, 0x95D9, 0x95DA, 0x95DD, 0x95DE,\n 0x95DF, 0x95E0, 0x95E4, 0x95E6, 0x961D, 0x961E, 0x9622, 0x9624,\n 0x9625, 0x9626, 0x962C, 0x9631, 0x9633, 0x9637, 0x9638, 0x9639,\n 0x963A, 0x963C, 0x963D, 0x9641, 0x9652, 0x9654, 0x9656, 0x9657,\n 0x9658, 0x9661, 0x966E, 0x9674, 0x967B, 0x967C, 0x967E, 0x967F,\n 0x9681, 0x9682, 0x9683, 0x9684, 0x9689, 0x9691, 0x9696, 0x969A,\n 0x969D, 0x969F, 0x96A4, 0x96A5, 0x96A6, 0x96A9, 0x96AE, 0x96AF,\n 0x96B3, 0x96BA, 0x96CA, 0x96D2, 0x5DB2, 0x96D8, 0x96DA, 0x96DD,\n 0x96DE, 0x96DF, 0x96E9, 0x96EF, 0x96F1, 0x96FA, 0x9702,\n};\nconst unsigned short euc_to_utf8_8FE7[] = {\n         0x9703, 0x9705, 0x9709, 0x971A, 0x971B, 0x971D, 0x9721,\n 0x9722, 0x9723, 0x9728, 0x9731, 0x9733, 0x9741, 0x9743, 0x974A,\n 0x974E, 0x974F, 0x9755, 0x9757, 0x9758, 0x975A, 0x975B, 0x9763,\n 0x9767, 0x976A, 0x976E, 0x9773, 0x9776, 0x9777, 0x9778, 0x977B,\n 0x977D, 0x977F, 0x9780, 0x9789, 0x9795, 0x9796, 0x9797, 0x9799,\n 0x979A, 0x979E, 0x979F, 0x97A2, 0x97AC, 0x97AE, 0x97B1, 0x97B2,\n 0x97B5, 0x97B6, 0x97B8, 0x97B9, 0x97BA, 0x97BC, 0x97BE, 0x97BF,\n 0x97C1, 0x97C4, 0x97C5, 0x97C7, 0x97C9, 0x97CA, 0x97CC, 0x97CD,\n 0x97CE, 0x97D0, 0x97D1, 0x97D4, 0x97D7, 0x97D8, 0x97D9, 0x97DD,\n 0x97DE, 0x97E0, 0x97DB, 0x97E1, 0x97E4, 0x97EF, 0x97F1, 0x97F4,\n 0x97F7, 0x97F8, 0x97FA, 0x9807, 0x980A, 0x9819, 0x980D, 0x980E,\n 0x9814, 0x9816, 0x981C, 0x981E, 0x9820, 0x9823, 0x9826,\n};\nconst unsigned short euc_to_utf8_8FE8[] = {\n         0x982B, 0x982E, 0x982F, 0x9830, 0x9832, 0x9833, 0x9835,\n 0x9825, 0x983E, 0x9844, 0x9847, 0x984A, 0x9851, 0x9852, 0x9853,\n 0x9856, 0x9857, 0x9859, 0x985A, 0x9862, 0x9863, 0x9865, 0x9866,\n 0x986A, 0x986C, 0x98AB, 0x98AD, 0x98AE, 0x98B0, 0x98B4, 0x98B7,\n 0x98B8, 0x98BA, 0x98BB, 0x98BF, 0x98C2, 0x98C5, 0x98C8, 0x98CC,\n 0x98E1, 0x98E3, 0x98E5, 0x98E6, 0x98E7, 0x98EA, 0x98F3, 0x98F6,\n 0x9902, 0x9907, 0x9908, 0x9911, 0x9915, 0x9916, 0x9917, 0x991A,\n 0x991B, 0x991C, 0x991F, 0x9922, 0x9926, 0x9927, 0x992B, 0x9931,\n 0x9932, 0x9933, 0x9934, 0x9935, 0x9939, 0x993A, 0x993B, 0x993C,\n 0x9940, 0x9941, 0x9946, 0x9947, 0x9948, 0x994D, 0x994E, 0x9954,\n 0x9958, 0x9959, 0x995B, 0x995C, 0x995E, 0x995F, 0x9960, 0x999B,\n 0x999D, 0x999F, 0x99A6, 0x99B0, 0x99B1, 0x99B2, 0x99B5,\n};\nconst unsigned short euc_to_utf8_8FE9[] = {\n         0x99B9, 0x99BA, 0x99BD, 0x99BF, 0x99C3, 0x99C9, 0x99D3,\n 0x99D4, 0x99D9, 0x99DA, 0x99DC, 0x99DE, 0x99E7, 0x99EA, 0x99EB,\n 0x99EC, 0x99F0, 0x99F4, 0x99F5, 0x99F9, 0x99FD, 0x99FE, 0x9A02,\n 0x9A03, 0x9A04, 0x9A0B, 0x9A0C, 0x9A10, 0x9A11, 0x9A16, 0x9A1E,\n 0x9A20, 0x9A22, 0x9A23, 0x9A24, 0x9A27, 0x9A2D, 0x9A2E, 0x9A33,\n 0x9A35, 0x9A36, 0x9A38, 0x9A47, 0x9A41, 0x9A44, 0x9A4A, 0x9A4B,\n 0x9A4C, 0x9A4E, 0x9A51, 0x9A54, 0x9A56, 0x9A5D, 0x9AAA, 0x9AAC,\n 0x9AAE, 0x9AAF, 0x9AB2, 0x9AB4, 0x9AB5, 0x9AB6, 0x9AB9, 0x9ABB,\n 0x9ABE, 0x9ABF, 0x9AC1, 0x9AC3, 0x9AC6, 0x9AC8, 0x9ACE, 0x9AD0,\n 0x9AD2, 0x9AD5, 0x9AD6, 0x9AD7, 0x9ADB, 0x9ADC, 0x9AE0, 0x9AE4,\n 0x9AE5, 0x9AE7, 0x9AE9, 0x9AEC, 0x9AF2, 0x9AF3, 0x9AF5, 0x9AF9,\n 0x9AFA, 0x9AFD, 0x9AFF, 0x9B00, 0x9B01, 0x9B02, 0x9B03,\n};\nconst unsigned short euc_to_utf8_8FEA[] = {\n         0x9B04, 0x9B05, 0x9B08, 0x9B09, 0x9B0B, 0x9B0C, 0x9B0D,\n 0x9B0E, 0x9B10, 0x9B12, 0x9B16, 0x9B19, 0x9B1B, 0x9B1C, 0x9B20,\n 0x9B26, 0x9B2B, 0x9B2D, 0x9B33, 0x9B34, 0x9B35, 0x9B37, 0x9B39,\n 0x9B3A, 0x9B3D, 0x9B48, 0x9B4B, 0x9B4C, 0x9B55, 0x9B56, 0x9B57,\n 0x9B5B, 0x9B5E, 0x9B61, 0x9B63, 0x9B65, 0x9B66, 0x9B68, 0x9B6A,\n 0x9B6B, 0x9B6C, 0x9B6D, 0x9B6E, 0x9B73, 0x9B75, 0x9B77, 0x9B78,\n 0x9B79, 0x9B7F, 0x9B80, 0x9B84, 0x9B85, 0x9B86, 0x9B87, 0x9B89,\n 0x9B8A, 0x9B8B, 0x9B8D, 0x9B8F, 0x9B90, 0x9B94, 0x9B9A, 0x9B9D,\n 0x9B9E, 0x9BA6, 0x9BA7, 0x9BA9, 0x9BAC, 0x9BB0, 0x9BB1, 0x9BB2,\n 0x9BB7, 0x9BB8, 0x9BBB, 0x9BBC, 0x9BBE, 0x9BBF, 0x9BC1, 0x9BC7,\n 0x9BC8, 0x9BCE, 0x9BD0, 0x9BD7, 0x9BD8, 0x9BDD, 0x9BDF, 0x9BE5,\n 0x9BE7, 0x9BEA, 0x9BEB, 0x9BEF, 0x9BF3, 0x9BF7, 0x9BF8,\n};\nconst unsigned short euc_to_utf8_8FEB[] = {\n         0x9BF9, 0x9BFA, 0x9BFD, 0x9BFF, 0x9C00, 0x9C02, 0x9C0B,\n 0x9C0F, 0x9C11, 0x9C16, 0x9C18, 0x9C19, 0x9C1A, 0x9C1C, 0x9C1E,\n 0x9C22, 0x9C23, 0x9C26, 0x9C27, 0x9C28, 0x9C29, 0x9C2A, 0x9C31,\n 0x9C35, 0x9C36, 0x9C37, 0x9C3D, 0x9C41, 0x9C43, 0x9C44, 0x9C45,\n 0x9C49, 0x9C4A, 0x9C4E, 0x9C4F, 0x9C50, 0x9C53, 0x9C54, 0x9C56,\n 0x9C58, 0x9C5B, 0x9C5D, 0x9C5E, 0x9C5F, 0x9C63, 0x9C69, 0x9C6A,\n 0x9C5C, 0x9C6B, 0x9C68, 0x9C6E, 0x9C70, 0x9C72, 0x9C75, 0x9C77,\n 0x9C7B, 0x9CE6, 0x9CF2, 0x9CF7, 0x9CF9, 0x9D0B, 0x9D02, 0x9D11,\n 0x9D17, 0x9D18, 0x9D1C, 0x9D1D, 0x9D1E, 0x9D2F, 0x9D30, 0x9D32,\n 0x9D33, 0x9D34, 0x9D3A, 0x9D3C, 0x9D45, 0x9D3D, 0x9D42, 0x9D43,\n 0x9D47, 0x9D4A, 0x9D53, 0x9D54, 0x9D5F, 0x9D63, 0x9D62, 0x9D65,\n 0x9D69, 0x9D6A, 0x9D6B, 0x9D70, 0x9D76, 0x9D77, 0x9D7B,\n};\nconst unsigned short euc_to_utf8_8FEC[] = {\n         0x9D7C, 0x9D7E, 0x9D83, 0x9D84, 0x9D86, 0x9D8A, 0x9D8D,\n 0x9D8E, 0x9D92, 0x9D93, 0x9D95, 0x9D96, 0x9D97, 0x9D98, 0x9DA1,\n 0x9DAA, 0x9DAC, 0x9DAE, 0x9DB1, 0x9DB5, 0x9DB9, 0x9DBC, 0x9DBF,\n 0x9DC3, 0x9DC7, 0x9DC9, 0x9DCA, 0x9DD4, 0x9DD5, 0x9DD6, 0x9DD7,\n 0x9DDA, 0x9DDE, 0x9DDF, 0x9DE0, 0x9DE5, 0x9DE7, 0x9DE9, 0x9DEB,\n 0x9DEE, 0x9DF0, 0x9DF3, 0x9DF4, 0x9DFE, 0x9E0A, 0x9E02, 0x9E07,\n 0x9E0E, 0x9E10, 0x9E11, 0x9E12, 0x9E15, 0x9E16, 0x9E19, 0x9E1C,\n 0x9E1D, 0x9E7A, 0x9E7B, 0x9E7C, 0x9E80, 0x9E82, 0x9E83, 0x9E84,\n 0x9E85, 0x9E87, 0x9E8E, 0x9E8F, 0x9E96, 0x9E98, 0x9E9B, 0x9E9E,\n 0x9EA4, 0x9EA8, 0x9EAC, 0x9EAE, 0x9EAF, 0x9EB0, 0x9EB3, 0x9EB4,\n 0x9EB5, 0x9EC6, 0x9EC8, 0x9ECB, 0x9ED5, 0x9EDF, 0x9EE4, 0x9EE7,\n 0x9EEC, 0x9EED, 0x9EEE, 0x9EF0, 0x9EF1, 0x9EF2, 0x9EF5,\n};\nconst unsigned short euc_to_utf8_8FED[] = {\n         0x9EF8, 0x9EFF, 0x9F02, 0x9F03, 0x9F09, 0x9F0F, 0x9F10,\n 0x9F11, 0x9F12, 0x9F14, 0x9F16, 0x9F17, 0x9F19, 0x9F1A, 0x9F1B,\n 0x9F1F, 0x9F22, 0x9F26, 0x9F2A, 0x9F2B, 0x9F2F, 0x9F31, 0x9F32,\n 0x9F34, 0x9F37, 0x9F39, 0x9F3A, 0x9F3C, 0x9F3D, 0x9F3F, 0x9F41,\n 0x9F43, 0x9F44, 0x9F45, 0x9F46, 0x9F47, 0x9F53, 0x9F55, 0x9F56,\n 0x9F57, 0x9F58, 0x9F5A, 0x9F5D, 0x9F5E, 0x9F68, 0x9F69, 0x9F6D,\n 0x9F6E, 0x9F6F, 0x9F70, 0x9F71, 0x9F73, 0x9F75, 0x9F7A, 0x9F7D,\n 0x9F8F, 0x9F90, 0x9F91, 0x9F92, 0x9F94, 0x9F96, 0x9F97, 0x9F9E,\n 0x9FA1, 0x9FA2, 0x9FA3, 0x9FA5,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short euc_to_utf8_8FF3[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174,\n 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x2160, 0x2161,\n};\nconst unsigned short euc_to_utf8_8FF4[] = {\n            0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168,\n    0x2169, 0xff07, 0xff02, 0x3231, 0x2116, 0x2121, 0x70bb, 0x4efc,\n    0x50f4, 0x51ec, 0x5307, 0x5324, 0xfa0e, 0x548a, 0x5759, 0xfa0f,\n    0xfa10, 0x589e, 0x5bec, 0x5cf5, 0x5d53, 0xfa11, 0x5fb7, 0x6085,\n    0x6120, 0x654e, 0x663b, 0x6665, 0xfa12, 0xf929, 0x6801, 0xfa13,\n    0xfa14, 0x6a6b, 0x6ae2, 0x6df8, 0x6df2, 0x7028, 0xfa15, 0xfa16,\n    0x7501, 0x7682, 0x769e, 0xfa17, 0x7930, 0xfa18, 0xfa19, 0xfa1a,\n    0xfa1b, 0x7ae7, 0xfa1c, 0xfa1d, 0x7da0, 0x7dd6, 0xfa1e, 0x8362,\n    0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0xfa22, 0x8b7f, 0x8cf4,\n    0x8d76, 0xfa23, 0xfa24, 0xfa25, 0x90de, 0xfa26, 0x9115, 0xfa27,\n    0xfa28, 0x9592, 0xf9dc, 0xfa29, 0x973b, 0x974d, 0x9751, 0xfa2a,\n    0xfa2b, 0xfa2c, 0x999e, 0x9ad9, 0x9b72, 0xfa2d, 0x9ed1,\n};\n#endif /* X0212_ENABLE */\n\nconst unsigned short euc_to_utf8_1byte[] = {\n         0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,\n 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,\n 0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,\n 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,\n 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87,\n 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,\n 0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,\n 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x00A9, 0x2122,\n};\nconst unsigned short *const euc_to_utf8_2bytes[] = {\n                 euc_to_utf8_A1, euc_to_utf8_A2, euc_to_utf8_A3,\n euc_to_utf8_A4, euc_to_utf8_A5, euc_to_utf8_A6, euc_to_utf8_A7,\n euc_to_utf8_A8, euc_to_utf8_A9, euc_to_utf8_AA, euc_to_utf8_AB,\n euc_to_utf8_AC, euc_to_utf8_AD, euc_to_utf8_AE, euc_to_utf8_AF,\n euc_to_utf8_B0, euc_to_utf8_B1, euc_to_utf8_B2, euc_to_utf8_B3,\n euc_to_utf8_B4, euc_to_utf8_B5, euc_to_utf8_B6, euc_to_utf8_B7,\n euc_to_utf8_B8, euc_to_utf8_B9, euc_to_utf8_BA, euc_to_utf8_BB,\n euc_to_utf8_BC, euc_to_utf8_BD, euc_to_utf8_BE, euc_to_utf8_BF,\n euc_to_utf8_C0, euc_to_utf8_C1, euc_to_utf8_C2, euc_to_utf8_C3,\n euc_to_utf8_C4, euc_to_utf8_C5, euc_to_utf8_C6, euc_to_utf8_C7,\n euc_to_utf8_C8, euc_to_utf8_C9, euc_to_utf8_CA, euc_to_utf8_CB,\n euc_to_utf8_CC, euc_to_utf8_CD, euc_to_utf8_CE, euc_to_utf8_CF,\n euc_to_utf8_D0, euc_to_utf8_D1, euc_to_utf8_D2, euc_to_utf8_D3,\n euc_to_utf8_D4, euc_to_utf8_D5, euc_to_utf8_D6, euc_to_utf8_D7,\n euc_to_utf8_D8, euc_to_utf8_D9, euc_to_utf8_DA, euc_to_utf8_DB,\n euc_to_utf8_DC, euc_to_utf8_DD, euc_to_utf8_DE, euc_to_utf8_DF,\n euc_to_utf8_E0, euc_to_utf8_E1, euc_to_utf8_E2, euc_to_utf8_E3,\n euc_to_utf8_E4, euc_to_utf8_E5, euc_to_utf8_E6, euc_to_utf8_E7,\n euc_to_utf8_E8, euc_to_utf8_E9, euc_to_utf8_EA, euc_to_utf8_EB,\n euc_to_utf8_EC, euc_to_utf8_ED, euc_to_utf8_EE, euc_to_utf8_EF,\n euc_to_utf8_F0, euc_to_utf8_F1, euc_to_utf8_F2, euc_to_utf8_F3,\n euc_to_utf8_F4, euc_to_utf8_F5,              0,              0,\n              0, euc_to_utf8_F9, euc_to_utf8_FA, euc_to_utf8_FB,\n euc_to_utf8_FC,              0,              0,\n};\n/* Microsoft UCS Mapping Compatible */\nconst unsigned short *const euc_to_utf8_2bytes_ms[] = {\n                 euc_to_utf8_A1_ms, euc_to_utf8_A2_ms, euc_to_utf8_A3,\n euc_to_utf8_A4, euc_to_utf8_A5, euc_to_utf8_A6, euc_to_utf8_A7,\n euc_to_utf8_A8, euc_to_utf8_A9, euc_to_utf8_AA, euc_to_utf8_AB,\n euc_to_utf8_AC, euc_to_utf8_AD, euc_to_utf8_AE, euc_to_utf8_AF,\n euc_to_utf8_B0, euc_to_utf8_B1, euc_to_utf8_B2, euc_to_utf8_B3,\n euc_to_utf8_B4, euc_to_utf8_B5, euc_to_utf8_B6, euc_to_utf8_B7,\n euc_to_utf8_B8, euc_to_utf8_B9, euc_to_utf8_BA, euc_to_utf8_BB,\n euc_to_utf8_BC, euc_to_utf8_BD, euc_to_utf8_BE, euc_to_utf8_BF,\n euc_to_utf8_C0, euc_to_utf8_C1, euc_to_utf8_C2, euc_to_utf8_C3,\n euc_to_utf8_C4, euc_to_utf8_C5, euc_to_utf8_C6, euc_to_utf8_C7,\n euc_to_utf8_C8, euc_to_utf8_C9, euc_to_utf8_CA, euc_to_utf8_CB,\n euc_to_utf8_CC, euc_to_utf8_CD, euc_to_utf8_CE, euc_to_utf8_CF,\n euc_to_utf8_D0, euc_to_utf8_D1, euc_to_utf8_D2, euc_to_utf8_D3,\n euc_to_utf8_D4, euc_to_utf8_D5, euc_to_utf8_D6, euc_to_utf8_D7,\n euc_to_utf8_D8, euc_to_utf8_D9, euc_to_utf8_DA, euc_to_utf8_DB,\n euc_to_utf8_DC, euc_to_utf8_DD, euc_to_utf8_DE, euc_to_utf8_DF,\n euc_to_utf8_E0, euc_to_utf8_E1, euc_to_utf8_E2, euc_to_utf8_E3,\n euc_to_utf8_E4, euc_to_utf8_E5, euc_to_utf8_E6, euc_to_utf8_E7,\n euc_to_utf8_E8, euc_to_utf8_E9, euc_to_utf8_EA, euc_to_utf8_EB,\n euc_to_utf8_EC, euc_to_utf8_ED, euc_to_utf8_EE, euc_to_utf8_EF,\n euc_to_utf8_F0, euc_to_utf8_F1, euc_to_utf8_F2, euc_to_utf8_F3,\n euc_to_utf8_F4, euc_to_utf8_F5,              0,              0,\n              0, euc_to_utf8_F9, euc_to_utf8_FA, euc_to_utf8_FB,\n euc_to_utf8_FC_ms,              0,              0,\n};\n\n#ifdef X0212_ENABLE\nconst unsigned short *const x0212_to_utf8_2bytes[] = {\n                              0, euc_to_utf8_8FA2,              0,\n              0,              0, euc_to_utf8_8FA6, euc_to_utf8_8FA7,\n              0, euc_to_utf8_8FA9, euc_to_utf8_8FAA, euc_to_utf8_8FAB,\n              0,              0,              0,              0,\n euc_to_utf8_8FB0, euc_to_utf8_8FB1, euc_to_utf8_8FB2, euc_to_utf8_8FB3,\n euc_to_utf8_8FB4, euc_to_utf8_8FB5, euc_to_utf8_8FB6, euc_to_utf8_8FB7,\n euc_to_utf8_8FB8, euc_to_utf8_8FB9, euc_to_utf8_8FBA, euc_to_utf8_8FBB,\n euc_to_utf8_8FBC, euc_to_utf8_8FBD, euc_to_utf8_8FBE, euc_to_utf8_8FBF,\n euc_to_utf8_8FC0, euc_to_utf8_8FC1, euc_to_utf8_8FC2, euc_to_utf8_8FC3,\n euc_to_utf8_8FC4, euc_to_utf8_8FC5, euc_to_utf8_8FC6, euc_to_utf8_8FC7,\n euc_to_utf8_8FC8, euc_to_utf8_8FC9, euc_to_utf8_8FCA, euc_to_utf8_8FCB,\n euc_to_utf8_8FCC, euc_to_utf8_8FCD, euc_to_utf8_8FCE, euc_to_utf8_8FCF,\n euc_to_utf8_8FD0, euc_to_utf8_8FD1, euc_to_utf8_8FD2, euc_to_utf8_8FD3,\n euc_to_utf8_8FD4, euc_to_utf8_8FD5, euc_to_utf8_8FD6, euc_to_utf8_8FD7,\n euc_to_utf8_8FD8, euc_to_utf8_8FD9, euc_to_utf8_8FDA, euc_to_utf8_8FDB,\n euc_to_utf8_8FDC, euc_to_utf8_8FDD, euc_to_utf8_8FDE, euc_to_utf8_8FDF,\n euc_to_utf8_8FE0, euc_to_utf8_8FE1, euc_to_utf8_8FE2, euc_to_utf8_8FE3,\n euc_to_utf8_8FE4, euc_to_utf8_8FE5, euc_to_utf8_8FE6, euc_to_utf8_8FE7,\n euc_to_utf8_8FE8, euc_to_utf8_8FE9, euc_to_utf8_8FEA, euc_to_utf8_8FEB,\n euc_to_utf8_8FEC, euc_to_utf8_8FED,              0,              0,\n              0,              0,              0,       euc_to_utf8_8FF3,\n euc_to_utf8_8FF4,            0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,};\n#endif /* X0212_ENABLE */\n#endif /* UTF8_OUTPUT_ENABLE */\n\n#ifdef UTF8_INPUT_ENABLE\nconst unsigned short utf8_to_euc_C2[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xA242, 0x2171, 0x2172, 0xA270, 0x216F, 0xA243, 0x2178,\n 0x212F, 0xA26D, 0xA26C,      0, 0x224C,      0, 0xA26E, 0xA234,\n 0x216B, 0x215E,      0,      0, 0x212D,      0, 0x2279,      0,\n 0xA231,      0, 0xA26B,      0,      0,      0,      0, 0xA244,\n};\nconst unsigned short utf8_to_euc_C2_ms[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xA242, 0x2171, 0x2172, 0xA270,   0x5C, 0xA243, 0x2178,\n 0x212F, 0xA26D, 0xA26C,      0, 0x224C,      0, 0xA26E, 0xA234,\n 0x216B, 0x215E,      0,      0, 0x212D,      0, 0x2279,      0,\n 0xA231,      0, 0xA26B,      0,      0,      0,      0, 0xA244,\n};\nconst unsigned short utf8_to_euc_C2_932[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,   0x21, 0x2171, 0x2172,      0,   0x5C,   0x7C, 0x2178,\n 0x212F,   0x63,   0x61, 0x2263, 0x224C,   0x2D,   0x52, 0x2131,\n 0x216B, 0x215E,   0x32,   0x33, 0x212D, 0x264C, 0x2279, 0x2126,\n 0x2124,   0x31,   0x6F, 0x2264,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_C3[] = {\n 0xAA22, 0xAA21, 0xAA24, 0xAA2A, 0xAA23, 0xAA29, 0xA921, 0xAA2E,\n 0xAA32, 0xAA31, 0xAA34, 0xAA33, 0xAA40, 0xAA3F, 0xAA42, 0xAA41,\n      0, 0xAA50, 0xAA52, 0xAA51, 0xAA54, 0xAA58, 0xAA53, 0x215F,\n 0xA92C, 0xAA63, 0xAA62, 0xAA65, 0xAA64, 0xAA72, 0xA930, 0xA94E,\n 0xAB22, 0xAB21, 0xAB24, 0xAB2A, 0xAB23, 0xAB29, 0xA941, 0xAB2E,\n 0xAB32, 0xAB31, 0xAB34, 0xAB33, 0xAB40, 0xAB3F, 0xAB42, 0xAB41,\n 0xA943, 0xAB50, 0xAB52, 0xAB51, 0xAB54, 0xAB58, 0xAB53, 0x2160,\n 0xA94C, 0xAB63, 0xAB62, 0xAB65, 0xAB64, 0xAB72, 0xA950, 0xAB73,\n};\nconst unsigned short utf8_to_euc_C3_932[] = {\n   0x41,   0x41,   0x41,   0x41,   0x41,   0x41,   0x41,   0x43,\n   0x45,   0x45,   0x45,   0x45,   0x49,   0x49,   0x49,   0x49,\n   0x44,   0x4E,   0x4F,   0x4F,   0x4F,   0x4F,   0x4F, 0x215F,\n   0x4F,   0x55,   0x55,   0x55,   0x55,   0x59,   0x54,   0x73,\n   0x61,   0x61,   0x61,   0x61,   0x61,   0x61,   0x61,   0x63,\n   0x65,   0x65,   0x65,   0x65,   0x69,   0x69,   0x69,   0x69,\n   0x64,   0x6E,   0x6F,   0x6F,   0x6F,   0x6F,   0x6F, 0x2160,\n   0x6F,   0x75,   0x75,   0x75,   0x75,   0x79,   0x74,   0x79,\n};\nconst unsigned short utf8_to_euc_C4[] = {\n 0xAA27, 0xAB27, 0xAA25, 0xAB25, 0xAA28, 0xAB28, 0xAA2B, 0xAB2B,\n 0xAA2C, 0xAB2C, 0xAA2F, 0xAB2F, 0xAA2D, 0xAB2D, 0xAA30, 0xAB30,\n 0xA922, 0xA942, 0xAA37, 0xAB37,      0,      0, 0xAA36, 0xAB36,\n 0xAA38, 0xAB38, 0xAA35, 0xAB35, 0xAA3A, 0xAB3A, 0xAA3B, 0xAB3B,\n 0xAA3D, 0xAB3D, 0xAA3C,      0, 0xAA3E, 0xAB3E, 0xA924, 0xA944,\n 0xAA47, 0xAB47, 0xAA45, 0xAB45,      0,      0, 0xAA46, 0xAB46,\n 0xAA44, 0xA945, 0xA926, 0xA946, 0xAA48, 0xAB48, 0xAA49, 0xAB49,\n 0xA947, 0xAA4A, 0xAB4A, 0xAA4C, 0xAB4C, 0xAA4B, 0xAB4B, 0xA929,\n};\nconst unsigned short utf8_to_euc_C5[] = {\n 0xA949, 0xA928, 0xA948, 0xAA4D, 0xAB4D, 0xAA4F, 0xAB4F, 0xAA4E,\n 0xAB4E, 0xA94A, 0xA92B, 0xA94B, 0xAA57, 0xAB57,      0,      0,\n 0xAA56, 0xAB56, 0xA92D, 0xA94D, 0xAA59, 0xAB59, 0xAA5B, 0xAB5B,\n 0xAA5A, 0xAB5A, 0xAA5C, 0xAB5C, 0xAA5D, 0xAB5D, 0xAA5F, 0xAB5F,\n 0xAA5E, 0xAB5E, 0xAA61, 0xAB61, 0xAA60, 0xAB60, 0xA92F, 0xA94F,\n 0xAA6C, 0xAB6C, 0xAA69, 0xAB69, 0xAA66, 0xAB66, 0xAA6B, 0xAB6B,\n 0xAA68, 0xAB68, 0xAA6A, 0xAB6A, 0xAA71, 0xAB71, 0xAA74, 0xAB74,\n 0xAA73, 0xAA75, 0xAB75, 0xAA77, 0xAB77, 0xAA76, 0xAB76,      0,\n};\nconst unsigned short utf8_to_euc_C7[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xAA26, 0xAB26, 0xAA43,\n 0xAB43, 0xAA55, 0xAB55, 0xAA67, 0xAB67, 0xAA70, 0xAB70, 0xAA6D,\n 0xAB6D, 0xAA6F, 0xAB6F, 0xAA6E, 0xAB6E,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xAB39,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_CB[] = {\n      0,      0,      0,      0,      0,      0,      0, 0xA230,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xA22F, 0xA232, 0xA236, 0xA235,      0, 0xA233,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_CE[] = {\n      0,      0,      0,      0, 0xA238, 0xA239, 0xA661,      0,\n 0xA662, 0xA663, 0xA664,      0, 0xA667,      0, 0xA669, 0xA66C,\n 0xA676, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627,\n 0x2628, 0x2629, 0x262A, 0x262B, 0x262C, 0x262D, 0x262E, 0x262F,\n 0x2630, 0x2631,      0, 0x2632, 0x2633, 0x2634, 0x2635, 0x2636,\n 0x2637, 0x2638, 0xA665, 0xA66A, 0xA671, 0xA672, 0xA673, 0xA674,\n 0xA67B, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, 0x2646, 0x2647,\n 0x2648, 0x2649, 0x264A, 0x264B, 0x264C, 0x264D, 0x264E, 0x264F,\n};\nconst unsigned short utf8_to_euc_CF[] = {\n 0x2650, 0x2651, 0xA678, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656,\n 0x2657, 0x2658, 0xA675, 0xA67A, 0xA677, 0xA679, 0xA67C,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_D0[] = {\n      0, 0x2727, 0xA742, 0xA743, 0xA744, 0xA745, 0xA746, 0xA747,\n 0xA748, 0xA749, 0xA74A, 0xA74B, 0xA74C,      0, 0xA74D, 0xA74E,\n 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2728, 0x2729,\n 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F, 0x2730, 0x2731,\n 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, 0x2739,\n 0x273A, 0x273B, 0x273C, 0x273D, 0x273E, 0x273F, 0x2740, 0x2741,\n 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2758, 0x2759,\n 0x275A, 0x275B, 0x275C, 0x275D, 0x275E, 0x275F, 0x2760, 0x2761,\n};\nconst unsigned short utf8_to_euc_D1[] = {\n 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2768, 0x2769,\n 0x276A, 0x276B, 0x276C, 0x276D, 0x276E, 0x276F, 0x2770, 0x2771,\n      0, 0x2757, 0xA772, 0xA773, 0xA774, 0xA775, 0xA776, 0xA777,\n 0xA778, 0xA779, 0xA77A, 0xA77B, 0xA77C,      0, 0xA77D, 0xA77E,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E280[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x213E,      0,      0,      0, 0x213D, 0x213D, 0x2142,      0,\n 0x2146, 0x2147,      0,      0, 0x2148, 0x2149,      0,      0,\n 0x2277, 0x2278,      0,      0,      0, 0x2145, 0x2144,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2273,      0, 0x216C, 0x216D,      0,      0,      0,      0,\n      0,      0,      0, 0x2228,      0,      0, 0x2131,      0,\n};\nconst unsigned short utf8_to_euc_E280_ms[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x213E,      0,      0,      0, 0x213D, 0x213D, 0x2142,      0,\n 0x2146, 0x2147,      0,      0, 0x2148, 0x2149,      0,      0,\n 0x2277, 0x2278,      0,      0,      0, 0x2145, 0x2144,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2273,      0, 0x216C, 0x216D,      0,      0,      0,      0,\n      0,      0,      0, 0x2228,      0,      0,   0x7E,      0,\n};\nconst unsigned short utf8_to_euc_E280_932[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x213E,      0,      0,      0,      0, 0x213D,      0,      0,\n 0x2146, 0x2147,      0,      0, 0x2148, 0x2149,      0,      0,\n 0x2277, 0x2278,      0,      0,      0, 0x2145, 0x2144,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2273,      0, 0x216C, 0x216D,      0,      0,      0,      0,\n      0,      0,      0, 0x2228,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E284[] = {\n      0,      0,      0, 0x216E,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x2D62,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x2D64, 0xA26F,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x2272,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E285[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2D35, 0x2D36, 0x2D37, 0x2D38, 0x2D39, 0x2D3A, 0x2D3B, 0x2D3C,\n 0x2D3D, 0x2D3E,      0,      0,      0,      0,      0,      0,\n 0xF373, 0xF374, 0xF375, 0xF376, 0xF377, 0xF378, 0xF379, 0xF37A,\n 0xF37B, 0xF37C,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E286[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x222B, 0x222C, 0x222A, 0x222D,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E287[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x224D,      0, 0x224E,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E288[] = {\n 0x224F,      0, 0x225F, 0x2250,      0,      0,      0, 0x2260,\n 0x223A,      0,      0, 0x223B,      0,      0,      0,      0,\n      0, 0x2D74, 0x215D,      0,      0,      0,      0,      0,\n      0,      0, 0x2265,      0,      0, 0x2267, 0x2167, 0x2D78,\n 0x225C,      0,      0,      0,      0, 0x2142,      0, 0x224A,\n 0x224B, 0x2241, 0x2240, 0x2269, 0x226A,      0, 0x2D73,      0,\n      0,      0,      0,      0, 0x2168, 0x2268,      0,      0,\n      0,      0,      0,      0,      0, 0x2266,      0,      0,\n};\nconst unsigned short utf8_to_euc_E288_932[] = {\n 0x224F,      0, 0x225F, 0x2250,      0,      0,      0, 0x2260,\n 0x223A,      0,      0, 0x223B,      0,      0,      0,      0,\n      0, 0x2D74,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2265,      0,      0, 0x2267, 0x2167, 0x2D78,\n 0x225C,      0,      0,      0,      0, 0x2142,      0, 0x224A,\n 0x224B, 0x2241, 0x2240, 0x2269, 0x226A,      0, 0x2D73,      0,\n      0,      0,      0,      0, 0x2168, 0x2268,      0,      0,\n      0,      0,      0,      0,      0, 0x2266,      0,      0,\n};\nconst unsigned short utf8_to_euc_E289[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2262,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2162, 0x2261,      0,      0,      0,      0, 0x2165, 0x2166,\n      0,      0, 0x2263, 0x2264,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E28A[] = {\n      0,      0, 0x223E, 0x223F,      0,      0, 0x223C, 0x223D,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x225D,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x2D79,\n};\nconst unsigned short utf8_to_euc_E28C[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x225E,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E291[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2D21, 0x2D22, 0x2D23, 0x2D24, 0x2D25, 0x2D26, 0x2D27, 0x2D28,\n 0x2D29, 0x2D2A, 0x2D2B, 0x2D2C, 0x2D2D, 0x2D2E, 0x2D2F, 0x2D30,\n 0x2D31, 0x2D32, 0x2D33, 0x2D34,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E294[] = {\n 0x2821, 0x282C, 0x2822, 0x282D,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x2823,      0,      0, 0x282E,\n 0x2824,      0,      0, 0x282F, 0x2826,      0,      0, 0x2831,\n 0x2825,      0,      0, 0x2830, 0x2827, 0x283C,      0,      0,\n 0x2837,      0,      0, 0x2832, 0x2829, 0x283E,      0,      0,\n 0x2839,      0,      0, 0x2834, 0x2828,      0,      0, 0x2838,\n 0x283D,      0,      0, 0x2833, 0x282A,      0,      0, 0x283A,\n 0x283F,      0,      0, 0x2835, 0x282B,      0,      0, 0x283B,\n};\nconst unsigned short utf8_to_euc_E295[] = {\n      0,      0, 0x2840,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x2836,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E296[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2223, 0x2222,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2225, 0x2224,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x2227, 0x2226,      0,      0,\n};\nconst unsigned short utf8_to_euc_E297[] = {\n      0,      0,      0,      0,      0,      0, 0x2221, 0x217E,\n      0,      0,      0, 0x217B,      0,      0, 0x217D, 0x217C,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x227E,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E298[] = {\n      0,      0,      0,      0,      0, 0x217A, 0x2179,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E299[] = {\n 0x216A,      0, 0x2169,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2276,      0,      0, 0x2275,      0, 0x2274,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E380[] = {\n 0x2121, 0x2122, 0x2123, 0x2137,      0, 0x2139, 0x213A, 0x213B,\n 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159,\n 0x215A, 0x215B, 0x2229, 0x222E, 0x214C, 0x214D,      0,      0,\n      0,      0,      0,      0, 0x2141, 0x2D60,      0, 0x2D61,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E380_932[] = {\n 0x2121, 0x2122, 0x2123, 0x2137,      0, 0x2139, 0x213A, 0x213B,\n 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159,\n 0x215A, 0x215B, 0x2229, 0x222E, 0x214C, 0x214D,      0,      0,\n      0,      0,      0,      0,      0, 0x2D60,      0, 0x2D61,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E381[] = {\n      0, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427,\n 0x2428, 0x2429, 0x242A, 0x242B, 0x242C, 0x242D, 0x242E, 0x242F,\n 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437,\n 0x2438, 0x2439, 0x243A, 0x243B, 0x243C, 0x243D, 0x243E, 0x243F,\n 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447,\n 0x2448, 0x2449, 0x244A, 0x244B, 0x244C, 0x244D, 0x244E, 0x244F,\n 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457,\n 0x2458, 0x2459, 0x245A, 0x245B, 0x245C, 0x245D, 0x245E, 0x245F,\n};\nconst unsigned short utf8_to_euc_E382[] = {\n 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,\n 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F,\n 0x2470, 0x2471, 0x2472, 0x2473,      0,      0,      0,      0,\n      0,      0,      0, 0x212B, 0x212C, 0x2135, 0x2136,      0,\n      0, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527,\n 0x2528, 0x2529, 0x252A, 0x252B, 0x252C, 0x252D, 0x252E, 0x252F,\n 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537,\n 0x2538, 0x2539, 0x253A, 0x253B, 0x253C, 0x253D, 0x253E, 0x253F,\n};\nconst unsigned short utf8_to_euc_E382_932[] = {\n 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,\n 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F,\n 0x2470, 0x2471, 0x2472, 0x2473, 0x2574,      0,      0,      0,\n      0,      0,      0, 0x212B, 0x212C, 0x2135, 0x2136,      0,\n      0, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527,\n 0x2528, 0x2529, 0x252A, 0x252B, 0x252C, 0x252D, 0x252E, 0x252F,\n 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537,\n 0x2538, 0x2539, 0x253A, 0x253B, 0x253C, 0x253D, 0x253E, 0x253F,\n};\nconst unsigned short utf8_to_euc_E383[] = {\n 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547,\n 0x2548, 0x2549, 0x254A, 0x254B, 0x254C, 0x254D, 0x254E, 0x254F,\n 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557,\n 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 0x255F,\n 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567,\n 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x256D, 0x256E, 0x256F,\n 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576,      0,\n      0,      0,      0, 0x2126, 0x213C, 0x2133, 0x2134,      0,\n};\nconst unsigned short utf8_to_euc_E388[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x2D6A, 0x2D6B,      0,      0,      0,      0,      0,\n      0, 0x2D6C,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E38A[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x2D65, 0x2D66, 0x2D67, 0x2D68,\n 0x2D69,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E38C[] = {\n      0,      0,      0, 0x2D46,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x2D4A,      0,      0,\n      0,      0,      0,      0, 0x2D41,      0,      0,      0,\n 0x2D44,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x2D42, 0x2D4C,      0,      0, 0x2D4B, 0x2D45,\n      0,      0,      0, 0x2D4D,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x2D47,      0,\n      0,      0,      0, 0x2D4F,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E38D[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x2D40, 0x2D4E,      0,      0, 0x2D43,      0,      0,\n      0, 0x2D48,      0,      0,      0,      0,      0, 0x2D49,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x2D5F, 0x2D6F, 0x2D6E, 0x2D6D,      0,\n};\nconst unsigned short utf8_to_euc_E38E[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x2D53, 0x2D54,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x2D50, 0x2D51, 0x2D52,      0,\n      0, 0x2D56,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E38F[] = {\n      0,      0,      0,      0, 0x2D55,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x2D63,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E4B8[] = {\n 0x306C, 0x437A, 0xB021, 0x3C37, 0xB022, 0xB023,      0, 0x4B7C,\n 0x3E66, 0x3B30, 0x3E65, 0x323C, 0xB024, 0x4954, 0x4D3F,      0,\n 0x5022, 0x312F, 0xB025,      0, 0x336E, 0x5023, 0x4024, 0x5242,\n 0x3556, 0x4A3A,      0,      0,      0,      0, 0x3E67, 0xB026,\n      0, 0x4E3E,      0, 0xB027, 0xB028,      0, 0x4A42,      0,\n 0xB029,      0, 0x5024, 0xB02A,      0, 0x4366, 0xB02B, 0xB02C,\n 0xB02D, 0x5025, 0x367A,      0,      0, 0xB02E, 0x5026,      0,\n 0x345D, 0x4330,      0, 0x3C67, 0x5027,      0,      0, 0x5028,\n};\nconst unsigned short utf8_to_euc_E4B9[] = {\n 0xB02F, 0xB030, 0x5029, 0x4735, 0xB031, 0x3557,      0, 0xB032,\n      0,      0,      0, 0x4737,      0, 0x4663, 0x3843, 0x4B33,\n      0, 0xB033,      0,      0,      0, 0x6949, 0x502A, 0x3E68,\n 0x502B, 0x3235, 0xB034,      0, 0xB035, 0x3665, 0x3870, 0x4C69,\n      0,      0, 0x5626, 0xB036,      0,      0,      0,      0,\n 0xB037, 0xB038,      0,      0,      0,      0,      0,      0,\n      0, 0x4D70,      0, 0x467D, 0xB039, 0xB03A,      0,      0,\n      0, 0xB03B,      0,      0,      0,      0, 0x3425, 0xB03C,\n};\nconst unsigned short utf8_to_euc_E4BA[] = {\n 0x3535,      0, 0x502C,      0,      0, 0x502D, 0x4E3B,      0,\n 0x4D3D, 0x4168, 0x502F, 0x3B76, 0x4673, 0xB03D, 0x5032,      0,\n      0, 0x313E, 0x385F,      0, 0x385E, 0x3066, 0xB03E, 0xB03F,\n 0x4F4B, 0x4F4A,      0, 0x3A33, 0x3021, 0xB040, 0x5033, 0x5034,\n 0x5035, 0x4B34, 0x5036,      0, 0x3872, 0x3067, 0x4B72,      0,\n 0x357C,      0,      0, 0x357D, 0x357E, 0x4462, 0x4E3C, 0xB041,\n 0x5037,      0,      0, 0x5038,      0,      0, 0x5039,      0,\n      0, 0xB042, 0x3F4D,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E4BB[] = {\n 0x3D3A, 0x3F4E, 0x503E, 0xB043, 0x503C,      0, 0x503D, 0x3558,\n      0,      0, 0x3A23, 0x3270,      0, 0x503B, 0x503A, 0x4A29,\n 0xB044,      0,      0,      0, 0x3B46, 0x3B45, 0x423E, 0x503F,\n 0x4955, 0x4067, 0xB045, 0xB046,      0, 0x2138, 0x5040, 0x5042,\n 0xB047, 0xB048, 0xB049, 0x4265, 0x4E61, 0x304A,      0,      0,\n 0xB04A,      0,      0,      0,      0, 0x5041, 0x323E, 0xB04B,\n 0x3644, 0xB04C, 0x4367, 0xB04D,      0, 0xB04E, 0x376F, 0x5043,\n      0,      0,      0, 0x4724, 0xF42F, 0xB04F, 0xB050, 0xB051,\n};\nconst unsigned short utf8_to_euc_E4BC[] = {\n 0xB052, 0x346B, 0xB053, 0xB054,      0,      0,      0,      0,\n 0xB055, 0x5044, 0x304B, 0xB056, 0xB057, 0x3860, 0x346C, 0x497A,\n 0x4832, 0x3559, 0xB058,      0,      0, 0xB059, 0xB05A, 0xB05B,\n      0, 0xB05C, 0x3271,      0, 0x5067, 0x4541,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xB05D, 0x476C,\n 0x5046, 0xB05E,      0, 0xB060, 0x483C, 0xB061, 0x4E62, 0xB062,\n 0x3F2D, 0xB063, 0x3B47, 0xB064, 0x3B77, 0x3240, 0xB065,      0,\n};\nconst unsigned short utf8_to_euc_E4BD[] = {\n 0xB066,      0, 0xB067, 0x4451,      0,      0, 0x4322, 0x504A,\n 0xB068, 0xB069,      0, 0xB06A, 0xB06B, 0x304C, 0x4463, 0x3D3B,\n 0x3A34, 0x4D24, 0xB06C, 0x424E, 0xB06D, 0x323F, 0xB06E, 0x5049,\n 0xB06F, 0x4D3E, 0x5045, 0x5047, 0x3A6E, 0x5048, 0x5524, 0xB070,\n 0xB05F,      0,      0, 0xB071,      0,      0,      0,      0,\n      0, 0x5050, 0xB072,      0, 0xB073,      0, 0xB074, 0x5053,\n 0x5051, 0xB075,      0, 0x3242,      0, 0x4A3B, 0x504B, 0xB076,\n 0xB077, 0xB078, 0xB079, 0x504F, 0x3873, 0xB07A, 0xB07B, 0x3B48,\n};\nconst unsigned short utf8_to_euc_E4BE[] = {\n      0, 0xB07C, 0xB07D, 0x3426, 0xB07E, 0xB121, 0x5054,      0,\n 0x504C, 0xB122, 0xB123, 0x4E63, 0xB124, 0x3B78, 0xB125, 0x504D,\n 0xB126, 0x5052, 0xB127, 0xB128, 0xB129,      0, 0x5055, 0xB12A,\n 0x504E, 0xB12B, 0xB12C, 0x3621,      0, 0x304D, 0xB12D, 0xB12E,\n 0x3622, 0x3241,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x5525,      0, 0x4B79, 0x496E, 0x3874,\n      0,      0, 0xB12F,      0,      0, 0x3F2F, 0x4E37, 0xB130,\n      0, 0xB131,      0, 0xB132, 0xB133, 0xB134, 0xB135, 0x4A58,\n};\nconst unsigned short utf8_to_euc_E4BF[] = {\n 0xB136, 0xB137, 0x3738, 0x4225, 0x3264, 0xB138, 0xB139,      0,\n 0xB13A, 0xB13B, 0x3D53, 0xB13C, 0xB13D, 0xB13E, 0x5059, 0xB13F,\n 0x505E, 0x505C, 0xB140,      0, 0x5057,      0,      0, 0x422F,\n 0x505A,      0, 0x505D, 0x505B, 0xB141, 0x4A5D,      0, 0x5058,\n 0xB142, 0x3F2E, 0xB143, 0x4B73, 0x505F, 0x5060,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x3D24, 0x506D,\n 0xB144,      0, 0xB145, 0x4750,      0, 0x4936, 0x5068,      0,\n 0x4A70,      0, 0x3236,      0, 0xB146, 0xB147, 0x506C, 0xB148,\n};\nconst unsigned short utf8_to_euc_E580[] = {\n 0xB149, 0xB14A,      0,      0, 0xB14B, 0x5066, 0x506F, 0xB14C,\n      0, 0x4152, 0xB14D, 0x3844, 0xB14E, 0x475C, 0xB14F, 0x6047,\n 0xB150, 0x506E, 0x455D, 0xB151, 0x5063,      0, 0x3876, 0xB152,\n 0xB153, 0x3875, 0x5061, 0xB154, 0xB155, 0xB156, 0xB157, 0x3C5A,\n      0, 0x5069, 0xB158, 0x4A6F, 0x434D, 0x5065, 0x3771, 0xB159,\n 0x5062, 0x506A, 0x5064, 0x4E51, 0x506B, 0x4F41, 0xB15A,      0,\n 0xB15B,      0, 0xB15C, 0xB15D,      0, 0xB15E, 0x3666,      0,\n      0, 0x3770,      0, 0xB176,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E581[] = {\n 0xB15F, 0xB160, 0xB161, 0x5070,      0, 0xB162, 0xB163, 0x5071,\n 0x5075, 0x304E, 0xB164,      0, 0xB165,      0, 0xB166, 0x4A50,\n 0x5074, 0xB167, 0xB168, 0xB169,      0, 0x5073, 0x5077, 0xB16A,\n      0, 0xB16B, 0x5076,      0, 0x4464,      0,      0, 0xB16C,\n 0xB16D,      0, 0xB16E, 0xB16F,      0, 0x3772, 0xB170, 0xB171,\n      0,      0, 0xB172,      0, 0x5078, 0xB173,      0,      0,\n 0xB174, 0xB175, 0x3C45,      0, 0x4226, 0x4465, 0x3676,      0,\n 0x5079,      0,      0,      0,      0, 0x3536,      0,      0,\n};\nconst unsigned short utf8_to_euc_E582[] = {\n 0x507A, 0xB177,      0, 0xB178, 0xB179, 0x507C, 0xB17A,      0,\n      0,      0, 0xB17B,      0,      0, 0x4B35, 0xB17C, 0xB17D,\n 0xB17E, 0x3766, 0xB221, 0xB222, 0xB223,      0, 0xB224,      0,\n 0x3B31, 0x4877, 0x507B, 0xB225, 0xB226,      0, 0xB227, 0xB228,\n 0xB229, 0xB22A, 0xB22B,      0,      0,      0,      0,      0,\n      0,      0, 0xB22C,      0, 0x3A45, 0x4D43,      0, 0xB22D,\n 0xB22E,      0, 0x507E, 0x5123, 0x507D, 0x3A44,      0, 0x3D7D,\n      0, 0xB22F, 0xB230,      0,      0, 0xB231, 0x3739,      0,\n};\nconst unsigned short utf8_to_euc_E583[] = {\n 0xB232,      0, 0x5124, 0xB233, 0xB234, 0x364F,      0, 0xB235,\n      0, 0x5121, 0x5122,      0, 0xB236, 0x462F, 0xB237, 0x417C,\n 0xB238, 0x3623,      0, 0xB239, 0xB23A, 0x4B4D, 0x5125,      0,\n 0xB23B,      0, 0x4E3D,      0, 0xB23C, 0xB23D, 0x5126, 0xB23E,\n      0,      0, 0xB23F, 0x5129, 0xB240, 0x5127, 0xB241, 0x414E,\n 0xB242, 0xB243,      0,      0,      0, 0x5128, 0x512A, 0xB244,\n      0, 0xB245, 0xB251,      0, 0xF430, 0x512C, 0xB246,      0,\n      0, 0x512B, 0xB247, 0x4A48,      0,      0, 0xB248,      0,\n};\nconst unsigned short utf8_to_euc_E584[] = {\n 0x3537, 0x512E, 0x512F, 0xB249, 0x322F,      0, 0xB24A, 0xB24B,\n 0xB24C, 0x512D,      0, 0xB24D, 0xB24E, 0xB24F, 0xB250,      0,\n 0xB252,      0, 0x3C74,      0, 0x5132, 0x5131, 0x5130, 0xB253,\n 0x5056, 0xB254, 0x5133, 0xB255, 0xB256, 0xB257, 0xB258, 0x3D7E,\n      0, 0x5134,      0, 0xB259,      0,      0,      0, 0xB25A,\n 0xB25B,      0, 0x4D25,      0, 0xB25C, 0xB25D,      0, 0xB25E,\n      0, 0xB25F, 0x4C59, 0xB260, 0xB261, 0xB262,      0, 0x5136,\n 0xB263, 0xB264, 0x5135, 0x5138, 0x5137,      0,      0, 0x5139,\n};\nconst unsigned short utf8_to_euc_E585[] = {\n 0x513A, 0x3074, 0xB265, 0x3835, 0x373B, 0x3D3C, 0x437B, 0x3624,\n 0x4068, 0x3877, 0xB266, 0x396E, 0x513C, 0x4C48, 0x4546, 0xB267,\n 0x3B79,      0, 0x513B, 0xB268, 0x513D, 0xB269,      0, 0xB26A,\n 0xB26B,      0, 0x455E,      0, 0x3375,      0,      0, 0xB26C,\n      0,      0, 0x513E,      0, 0xB26D, 0x467E, 0xB26E,      0,\n 0x4134, 0x5140, 0x5141, 0x482C, 0x3878, 0x4F3B, 0x5142,      0,\n      0, 0x3626,      0,      0,      0, 0x4A3C, 0x4236, 0x3671,\n 0x4535,      0,      0,      0, 0x3773,      0, 0xB26F,      0,\n};\nconst unsigned short utf8_to_euc_E586[] = {\n 0x5143,      0, 0x5144, 0xB270, 0xB271, 0x4662, 0x315F,      0,\n      0, 0x5147, 0x3A7D, 0xB272, 0x5146, 0x3A46, 0xB273, 0x5148,\n 0x666E, 0x5149, 0x4B41, 0x514A,      0, 0x514B, 0x514C, 0x3E69,\n 0xB274, 0x3C4C,      0,      0,      0, 0xB275,      0,      0,\n 0x3427, 0xB276, 0x514F, 0xB277, 0x514D, 0x4C3D, 0x514E,      0,\n 0x495A, 0x5150, 0x5151, 0x5152, 0x455F, 0xB278,      0,      0,\n 0x5156, 0x5154, 0x5155, 0x5153, 0x3A63, 0x5157, 0x4C6A, 0x4E64,\n 0xB279,      0, 0xB27A,      0, 0xB27B, 0x5158, 0xB27C, 0xB27D,\n};\nconst unsigned short utf8_to_euc_E587[] = {\n      0,      0, 0xB27E,      0, 0x4028, 0x5159, 0x3D5A,      0,\n 0xB321, 0x515A,      0, 0x437C, 0x4E3F, 0x4560,      0, 0xB322,\n      0, 0xB323, 0xB324, 0xB325,      0, 0xB326, 0x5245,      0,\n 0xB327,      0,      0, 0x515B, 0x7425, 0x3645, 0xB328,      0,\n 0x515C, 0x4B5E, 0xB329,      0,      0, 0xB32A, 0x3D68, 0x427C,\n      0, 0x515E, 0x4664,      0, 0xF431, 0x515F, 0xB32B,      0,\n 0x5160, 0x332E, 0xB32C, 0xB32D, 0xB32E, 0x5161, 0x3627, 0xB32F,\n 0x464C, 0x317A, 0x3D50,      0,      0, 0x4821, 0x5162,      0,\n};\nconst unsigned short utf8_to_euc_E588[] = {\n 0x4561, 0xB330, 0xB331, 0x3F4F, 0x5163, 0xB332, 0x4A2C, 0x405A,\n 0x3422,      0, 0x3429, 0x5164,      0,      0, 0x5166,      0,\n      0, 0x373A, 0xB333, 0xB334, 0x5165, 0xB335, 0xB336, 0x4E73,\n 0xB337,      0,      0,      0,      0, 0x3D69,      0,      0,\n      0,      0, 0xB338,      0, 0x483D, 0x4A4C,      0, 0x5167,\n 0xB339, 0x4D78, 0x5168,      0,      0,      0, 0x5169,      0,\n 0x457E, 0xB33A, 0xB33B, 0x516A,      0, 0xB33C, 0x4029, 0x3A7E,\n 0x3774, 0x516B, 0x3B49, 0x396F, 0xB33D,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E589[] = {\n      0,      0,      0, 0x4466, 0x516D, 0xB33E,      0, 0x4227,\n      0, 0xB33F, 0x3A6F, 0x516E, 0x516F, 0x4130,      0, 0x516C,\n      0,      0,      0,      0, 0x5171, 0xB340, 0x4B36, 0xB341,\n 0xB342,      0, 0xB343, 0x3964, 0xB344,      0, 0x5170, 0xB345,\n 0xB346, 0xB347,      0, 0x3775, 0x3A5E, 0x476D, 0xB348,      0,\n      0, 0x5174, 0x5172,      0,      0,      0, 0xB349, 0x497B,\n 0x3E6A, 0x517B, 0x3364, 0x5175, 0x5173, 0x414F,      0, 0xB34A,\n 0xB34B, 0xB34C,      0,      0,      0, 0x5177,      0, 0x5176,\n};\nconst unsigned short utf8_to_euc_E58A[] = {\n 0xB34D,      0, 0xB34E, 0x3344,      0, 0xB34F,      0, 0x3760,\n 0x517C, 0x4E2D, 0xB350,      0, 0xB351, 0x5178,      0,      0,\n      0, 0x517D, 0x517A, 0xB352, 0x5179, 0xB353, 0xB354, 0xB355,\n 0xB356,      0, 0xB357, 0x4E4F, 0xB358,      0,      0, 0x3879,\n 0x3243,      0,      0, 0x4E74, 0xB359, 0xB35A, 0xB35B, 0xB35C,\n      0, 0x3D75, 0x4558, 0x3965, 0x5222, 0x5223,      0, 0xB35D,\n 0xB35E, 0x4E65,      0,      0, 0x4F2B, 0x5225, 0xB35F, 0xB360,\n 0xB361, 0x387A, 0xB362, 0xB363, 0x5224, 0xB364, 0x332F,      0,\n};\nconst unsigned short utf8_to_euc_E58B[] = {\n 0xB365, 0x5226,      0, 0x4B56, 0xB366, 0x443C, 0xB367, 0x4D26,\n 0xB368, 0x4A59,      0,      0, 0xB369, 0x5227,      0, 0xB36A,\n      0, 0xB36B, 0x7055,      0, 0xB36C, 0x4630, 0xB36D, 0x5228,\n 0x342A, 0x4C33,      0, 0xB36E, 0xB36F, 0x3E21, 0x5229, 0x4A67,\n 0x522D, 0xB370, 0x402A, 0x522A, 0x3650, 0xB371, 0x522B, 0x342B,\n 0xB372, 0xB373, 0xB374,      0, 0xB375,      0,      0,      0,\n 0xB376, 0xB377, 0x372E, 0x522E, 0xB378, 0x522F, 0xB379, 0xB37A,\n 0x5230, 0x5231, 0x3C5B,      0,      0,      0, 0x387B, 0x4C5E,\n};\nconst unsigned short utf8_to_euc_E58C[] = {\n 0xB37B, 0x4C68, 0x4677, 0xB37C,      0, 0x4A71, 0x5232, 0xF432,\n 0x5233,      0, 0xB37D, 0xB37E, 0xB421, 0x5235,      0, 0x5237,\n 0x5236, 0xB422,      0, 0xB423,      0, 0x5238, 0x323D, 0x4B4C,\n 0xB424, 0x3A7C, 0x5239, 0xB425, 0xB426, 0x4159, 0xB427, 0xB428,\n 0x3E22, 0x3629,      0, 0x523A, 0xF433, 0xB429,      0, 0xB42A,\n 0xB42B, 0xB42C, 0x485B, 0xB42D, 0xB42E, 0xB42F,      0, 0x523B,\n 0xB430, 0x523C, 0xB431, 0x523D,      0, 0xB432,      0,      0,\n 0x523E, 0x4924, 0x3668, 0x3065, 0xB433, 0xB434, 0xB435, 0x463F,\n};\nconst unsigned short utf8_to_euc_E58D[] = {\n 0x523F, 0x3D3D, 0xB436, 0x4069,      0, 0x5241, 0x5240, 0x3E23,\n 0x3861, 0x5243, 0x483E, 0xB438, 0xB437, 0x5244,      0,      0,\n      0, 0x485C, 0x4234, 0x426E, 0x3628,      0,      0, 0x466E,\n 0x4331, 0xB439, 0x476E, 0xB43A, 0x4B4E,      0, 0x5246,      0,\n 0x406A, 0xB43B,      0, 0xB43C,      0, 0xB43D, 0x3735,      0,\n      0, 0x5247,      0,      0, 0xB43E, 0xB43F, 0x5248, 0x312C,\n 0x3075, 0x346D, 0xB440, 0x4228, 0x3551, 0x4D71,      0, 0x524B,\n 0x3237, 0xB441,      0, 0x524A,      0,      0, 0xB442, 0x362A,\n};\nconst unsigned short utf8_to_euc_E58E[] = {\n      0,      0, 0x524C, 0xB443, 0x4C71,      0,      0, 0xB444,\n 0xB445,      0,      0,      0,      0,      0, 0xB446,      0,\n      0,      0,      0, 0xB447, 0xB448,      0, 0x524D,      0,\n 0x4E52, 0xB449, 0x387C,      0,      0, 0xB44A,      0, 0x3836,\n 0x524E, 0xB44B,      0,      0, 0xB44C, 0x5250, 0x524F,      0,\n 0x3F5F, 0x3139, 0xB44D, 0xB44E,      0, 0x315E, 0x5251, 0xB44F,\n 0x5252,      0, 0xB450, 0x3837, 0xB451, 0xB452, 0x5253, 0xB453,\n 0xB454,      0, 0xB455, 0x356E,      0, 0xB456,      0,      0,\n};\nconst unsigned short utf8_to_euc_E58F[] = {\n 0xB457,      0, 0x3B32, 0x5254,      0, 0xB458,      0,      0,\n 0x4B74, 0x3A35, 0x355A, 0x4D27, 0x4150, 0x483F, 0x3C7D, 0xB459,\n      0,      0, 0xB45A, 0xB45B, 0x3D47, 0xB45C, 0x3C68, 0x3C75,\n      0, 0x3D76, 0xB45D, 0x4840,      0, 0xB45E, 0xB45F, 0x5257,\n 0xB460, 0x3143, 0x4151, 0x387D, 0x3845, 0x3667, 0xB461, 0xB462,\n 0x525B, 0x4321, 0x427E, 0x362B, 0x3E24, 0x525C, 0x525A, 0x3244,\n 0x4266, 0x3C38, 0x3B4B, 0x3126,      0, 0xB463, 0x3370, 0x3966,\n 0x3B4A,      0, 0x525D,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E590[] = {\n      0, 0x525E, 0xB464, 0x3549, 0x3346,      0,      0,      0,\n 0x3967, 0x3548, 0x445F, 0x3125, 0x4631, 0x4C3E, 0x3921, 0x4D79,\n 0x4547, 0x387E,      0, 0xB465,      0,      0,      0,      0,\n      0,      0, 0xB466, 0x372F,      0, 0x5267,      0, 0x3663,\n 0x4B4A, 0xB467,      0,      0,      0,      0, 0x485D, 0xB468,\n 0xB469, 0x5266, 0xB46A, 0x345E, 0x5261, 0x5262, 0x5264, 0xB46B,\n      0, 0xB46C,      0,      0, 0xB46D, 0xB46E, 0x5265,      0,\n 0x355B, 0x3F61,      0, 0x4A2D, 0x5263, 0x525F, 0x3863,      0,\n};\nconst unsigned short utf8_to_euc_E591[] = {\n 0x5260,      0, 0x4F24, 0xB46F, 0xB470,      0, 0x4A72, 0xB471,\n 0x4468, 0x3862, 0x3970,      0,      0, 0xB472, 0x5268, 0xB473,\n      0, 0x465D,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xB474, 0x526C,\n      0,      0, 0xB475,      0, 0xB476,      0, 0xB477, 0xB478,\n 0x3C7E, 0xB479, 0x3C76, 0xB47A,      0, 0xB47B, 0xB47C,      0,\n 0x526F, 0x526D,      0, 0x4C23, 0xB47D, 0x526A, 0x5273, 0x526E,\n      0,      0,      0, 0x5271, 0x3846, 0x4C3F,      0, 0xB47E,\n};\nconst unsigned short utf8_to_euc_E592[] = {\n 0x5272, 0xB521,      0, 0xB522, 0x5274, 0xB523, 0x5276,      0,\n 0xB524, 0xB525, 0xF435, 0x3A70, 0x4F42, 0xB526, 0x526B, 0x5269,\n 0x5275, 0xB527, 0x5270,      0,      0, 0xB528, 0xB529,      0,\n      0,      0,      0,      0, 0xB52A,      0,      0, 0xB52B,\n      0, 0xB52C, 0x5278,      0, 0x5323, 0x527A, 0xB52D, 0xB52E,\n 0x527E, 0xB52F, 0xB530, 0x5321, 0x527B, 0xB531, 0xB532, 0x533E,\n      0, 0xB533, 0x3A69, 0x3331,      0,      0,      0, 0xB534,\n 0x5279, 0xB535, 0xB536, 0xB537, 0x5325, 0x3076, 0x5324, 0xB538,\n};\nconst unsigned short utf8_to_euc_E593[] = {\n 0x3025, 0x494A, 0x5322,      0, 0x527C,      0, 0xB539, 0x5277,\n 0x527D, 0x3A48, 0xB53A,      0,      0, 0xB53B, 0xB53C,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x5326,      0,      0,      0,      0,      0,      0,      0,\n 0xB53D, 0x3077, 0x532F,      0,      0, 0x5327, 0x5328,      0,\n 0x3E25, 0x4B69, 0xB53E,      0, 0xB53F, 0x532D, 0x532C, 0xB540,\n      0,      0, 0x452F,      0,      0,      0, 0xB541,      0,\n      0,      0, 0x532E,      0, 0xB542, 0x532B, 0xB543, 0xB544,\n};\nconst unsigned short utf8_to_euc_E594[] = {\n 0xB545, 0xB546,      0,      0, 0x3134, 0xB547, 0x3A36, 0x3F30,\n 0xB548, 0xB549,      0,      0, 0xB54A, 0xB54B, 0xB54C, 0x5329,\n 0x4562,      0,      0,      0, 0x532A, 0xB54D, 0x3022,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xB54E, 0xB54F,      0,      0, 0x5334, 0x4D23,\n      0, 0x3E27, 0xB550, 0x533A,      0, 0xB551, 0xB552,      0,\n 0x5339, 0x5330,      0, 0xB553, 0xB554, 0xB555, 0x4243,      0,\n};\nconst unsigned short utf8_to_euc_E595[] = {\n 0x5331, 0xB556,      0,      0, 0x426F, 0x5336, 0x3E26, 0xB557,\n      0, 0xB558, 0xB559,      0, 0x5333, 0xB55A,      0, 0x4C64,\n 0xB55B, 0xB55C,      0, 0x373C,      0,      0, 0x5337, 0x5338,\n 0xB55D,      0, 0xB55E, 0xB55F, 0x5335, 0x533B, 0xB560,      0,\n 0xB561, 0xB562,      0, 0x5332, 0xB563,      0, 0xB564,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x5341, 0x5346,      0, 0x5342, 0xB565,\n};\nconst unsigned short utf8_to_euc_E596[] = {\n 0x533D, 0xB566, 0xB567, 0x5347, 0x4131,      0, 0xB568, 0x5349,\n 0xB569, 0x3922, 0x533F, 0x437D,      0,      0, 0xB56A, 0xB56B,\n      0, 0xB56C, 0xB56D, 0xB56E, 0xB56F,      0,      0, 0xB570,\n 0x5343, 0x533C, 0x342D,      0, 0x346E, 0x3365, 0x5344, 0x5340,\n      0,      0,      0, 0xB571, 0xB572,      0,      0, 0x3776,\n 0x534A, 0x5348, 0x4153, 0x354A, 0x362C, 0xB573, 0x5345,      0,\n 0x3674,      0, 0xB574,      0,      0,      0, 0x3144,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xB575,\n};\nconst unsigned short utf8_to_euc_E597[] = {\n      0, 0xB576,      0, 0xB577, 0x534E, 0x534C, 0xB578, 0x5427,\n      0, 0xB579,      0, 0xB57A, 0xB57B,      0, 0xB57C,      0,\n      0, 0xB57D, 0xB57E, 0xB621, 0x5351,      0,      0, 0xB622,\n 0xB623,      0, 0x534B, 0xB624, 0x534F,      0, 0xB625, 0x534D,\n      0,      0, 0xB626, 0x3B4C, 0x5350,      0,      0,      0,\n      0, 0xB627,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xB628, 0x5353,\n      0, 0x5358,      0,      0,      0, 0x5356, 0x5355, 0xB629,\n};\nconst unsigned short utf8_to_euc_E598[] = {\n      0,      0,      0,      0,      0, 0xB62A, 0x4332,      0,\n 0xB62B, 0x3245, 0xB62C,      0,      0, 0xB62D, 0xB62E, 0xB62F,\n 0xB630, 0xB631, 0xB632,      0, 0x5352,      0, 0x5354, 0x3E28,\n 0x3133, 0xB633,      0, 0x5357,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x325E,      0,      0, 0xB634,      0,      0, 0x5362,\n 0xB635, 0x3E7C, 0x535E, 0xB636, 0x535C, 0xB637, 0x535D, 0xB638,\n 0x535F, 0xB639,      0, 0xB63A, 0xB63B, 0xB63C,      0, 0xB63D,\n};\nconst unsigned short utf8_to_euc_E599[] = {\n 0xB63E, 0xB63F, 0x313D, 0xB640, 0xB641,      0, 0xB642,      0,\n      0, 0xB643,      0, 0xB644, 0x4139, 0xB645, 0x5359, 0xB646,\n 0x535A,      0,      0,      0, 0xB647,      0,      0,      0,\n      0,      0,      0, 0x337A,      0,      0, 0xB648,      0,\n 0xB649, 0xB64A, 0xB64B, 0xB64C, 0x5361,      0, 0xB64D,      0,\n 0x346F, 0xB64E, 0x5364, 0x5360, 0x5363, 0xB64F,      0, 0xB650,\n      0, 0xB651, 0xB652,      0, 0x4A2E, 0xB653,      0,      0,\n 0x4655,      0, 0x4838,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E59A[] = {\n 0x5366,      0,      0,      0, 0xB654, 0xB655, 0x5365, 0x3345,\n 0xB656,      0, 0x5367, 0xB657, 0xB658,      0,      0, 0x536A,\n      0,      0,      0,      0, 0x5369, 0xB659,      0,      0,\n      0, 0xB65A, 0xB65B,      0,      0, 0xB65C, 0xB65D, 0xB65E,\n 0x5368,      0, 0x4739,      0,      0, 0x536B, 0xB65F, 0xB660,\n 0xB661, 0xB662,      0, 0xB663, 0xB664, 0xB665, 0x536C,      0,\n      0, 0xB666,      0, 0xB667, 0x536E,      0, 0x536D, 0xB668,\n      0,      0,      0,      0, 0x5370,      0, 0xB669,      0,\n};\nconst unsigned short utf8_to_euc_E59B[] = {\n 0x5373, 0x5371, 0x536F, 0x5372,      0, 0xB66A,      0,      0,\n 0x5374, 0xB66B, 0xB66C, 0xB66D, 0xB670, 0xB671, 0x5375, 0xB66E,\n 0xB66F, 0x5376,      0, 0x5377,      0,      0,      0, 0x5378,\n 0x5145, 0xB672, 0x3C7C, 0x3B4D, 0xB673, 0xB674, 0x3273, 0xB675,\n 0x3078, 0xB676,      0, 0x4344, 0xB677, 0xB678, 0xB679, 0xB67A,\n 0xB67B,      0,      0, 0xB67D,      0, 0xB67E, 0x5379,      0,\n 0x3A24, 0xB67C, 0x304F, 0x3F5E,      0,      0, 0xB721, 0xB722,\n      0, 0x537A, 0x3847,      0,      0, 0x3971,      0, 0x537C,\n};\nconst unsigned short utf8_to_euc_E59C[] = {\n 0x537B, 0xB723, 0xB724, 0x4A60, 0x537D,      0,      0, 0xB725,\n 0x5421, 0x537E, 0xB726, 0x5422, 0xB727, 0x5423,      0, 0x3777,\n      0, 0xB728, 0x3160, 0x5424,      0, 0xB729, 0x5426,      0,\n 0x5425,      0, 0xB72A, 0xB72B, 0x5428, 0xB72C,      0, 0x455A,\n 0xB72D,      0, 0xB72E, 0xB72F, 0xB730, 0xB731, 0x5429, 0x3035,\n 0x3A5F, 0xB732, 0xB733,      0, 0xB734, 0x373D, 0xB735, 0xB736,\n 0x434F,      0,      0, 0xB737, 0xB738,      0,      0, 0x542A,\n 0x542B,      0,      0, 0x542D,      0, 0xB739, 0xB73A, 0xB73B,\n};\nconst unsigned short utf8_to_euc_E59D[] = {\n 0x542E,      0, 0x3A64,      0,      0, 0xB73C, 0xB73D, 0x3651,\n      0,      0, 0x4B37,      0, 0xB73E, 0xB73F, 0x542C, 0x542F,\n 0x3A41, 0x3923, 0xB740,      0,      0,      0,      0,      0,\n      0, 0xF436,      0,      0,      0,      0,      0,      0,\n      0, 0x5433, 0xB741,      0, 0x3A25, 0xB742, 0x4333, 0xB743,\n 0xB744, 0x5430, 0x445A, 0xB745,      0, 0xB746, 0xB747, 0xB748,\n 0xB749, 0xB74A,      0, 0xB74B, 0xB74C, 0xB74D,      0, 0xB74E,\n      0, 0xB74F, 0xB750, 0xB751, 0xB752,      0, 0xB753, 0x5434,\n};\nconst unsigned short utf8_to_euc_E59E[] = {\n      0, 0xB754, 0x3F62, 0xB755,      0,      0,      0,      0,\n 0x5432, 0x5435,      0, 0x373F, 0xB756,      0,      0,      0,\n      0,      0,      0, 0x5436, 0xB757, 0xB760,      0, 0xB758,\n      0, 0xB759, 0xB75A,      0, 0xB75B, 0xB75C, 0xB75D, 0xB75E,\n 0x5437, 0xB75F, 0x3924, 0x3340, 0x5439,      0,      0, 0xB761,\n 0xB762, 0xB763, 0x543A,      0, 0xB764,      0,      0,      0,\n 0x543B,      0,      0, 0x5438,      0,      0,      0,      0,\n 0xB765,      0,      0,      0,      0, 0xB766,      0,      0,\n};\nconst unsigned short utf8_to_euc_E59F[] = {\n 0x5431,      0,      0, 0x543C,      0,      0, 0x543D, 0xB767,\n 0xB768,      0,      0, 0x4B64, 0xB769,      0, 0x3E6B, 0xB76A,\n      0,      0, 0x543F, 0x5440, 0x543E, 0xB76B, 0x5442,      0,\n      0,      0,      0,      0, 0x4738, 0xB76C, 0xB76D, 0x3068,\n 0x4956, 0xB77E,      0, 0x5443, 0xB76E,      0, 0xB76F, 0xB770,\n      0, 0xB771,      0,      0,      0, 0xB772,      0,      0,\n 0xB773,      0,      0,      0, 0x3E7D, 0xB774, 0xB775, 0x3C39,\n 0xB776, 0x475D, 0x3470,      0, 0x3A6B, 0xB777, 0xB778, 0xB779,\n};\nconst unsigned short utf8_to_euc_E5A0[] = {\n 0x4B59,      0, 0x4632, 0xB77A, 0xB77B, 0x3778, 0x424F,      0,\n 0xB77C, 0xB77D, 0x5441, 0x5444, 0xB821, 0xB822,      0,      0,\n      0,      0,      0,      0,      0, 0x4244,      0,      0,\n      0, 0x5445,      0, 0xB823,      0, 0x5446, 0xB824, 0xB825,\n 0xB826, 0x5448,      0,      0, 0x4469,      0, 0xB827, 0xB828,\n      0,      0, 0x342E,      0,      0, 0xB829,      0, 0x7421,\n 0x3161, 0x4A73, 0xB82A,      0, 0x3E6C, 0x4548,      0,      0,\n      0, 0xB82B, 0x3A66,      0,      0, 0x544E,      0, 0xB82C,\n};\nconst unsigned short utf8_to_euc_E5A1[] = {\n 0x4A3D, 0x4E5D,      0,      0,      0,      0,      0,      0,\n      0, 0xB82D, 0x3274, 0x544A, 0xB82E, 0xB82F,      0, 0xB830,\n 0xB831, 0x413A, 0x544D,      0, 0x4563, 0xB832,      0, 0x4549,\n 0x4564, 0x4839, 0x444D,      0,      0,      0, 0x3A49, 0xB833,\n      0, 0xB834, 0x5449,      0, 0xB835,      0,      0, 0xB836,\n 0xB837, 0x3176,      0, 0x4536,      0,      0,      0,      0,\n 0x544B,      0, 0x5447,      0,      0, 0x3F50,      0,      0,\n 0xB838, 0x544F,      0,      0, 0xB839,      0, 0x3D4E, 0xB83A,\n};\nconst unsigned short utf8_to_euc_E5A2[] = {\n 0xB83B, 0xB83C,      0, 0x362D,      0, 0x5450,      0, 0xB83D,\n 0xB83E, 0xB83F, 0xB840,      0, 0xB841, 0xB842,      0, 0xB843,\n 0xB844,      0,      0, 0x4A68, 0xB845,      0, 0xB846, 0x417D,\n      0,      0,      0,      0, 0x4446, 0xB847, 0xF439, 0x5452,\n 0xB848, 0xB849, 0xB84A,      0,      0,      0, 0xB84B,      0,\n 0x4B4F, 0xB84C,      0, 0x5453,      0,      0, 0x5458,      0,\n      0, 0xB84D, 0xB84E, 0x4A2F,      0,      0,      0,      0,\n 0x5457, 0x5451, 0x5454, 0x5456, 0xB850,      0, 0x3A26,      0,\n};\nconst unsigned short utf8_to_euc_E5A3[] = {\n      0, 0x4A49, 0xB851,      0, 0xB84F, 0x5459,      0, 0x4345,\n 0xB852,      0, 0x3275,      0, 0x3E6D, 0xB853, 0xB854,      0,\n 0xB855, 0x545B, 0xB856, 0x545A, 0xB857, 0x3968, 0xB858, 0x545C,\n 0x545E, 0x545D, 0xB859,      0, 0x5460, 0xB85A, 0x5455, 0x5462,\n      0, 0xB85B, 0xB85C,      0, 0x5461, 0x545F,      0,      0,\n      0, 0xB85D,      0, 0x3B4E, 0x3F51,      0, 0x4154, 0x5463,\n 0x403C, 0x306D, 0x4764, 0xB85E,      0,      0,      0, 0x445B,\n      0, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5A4[] = {\n      0,      0, 0x5469,      0,      0, 0xB85F, 0xB860,      0,\n      0, 0x4A51, 0x546A, 0xB861, 0xB862,      0,      0, 0x3246,\n 0x546B,      0, 0xB863, 0xB864, 0xB865, 0x4D3C, 0x3330,      0,\n 0x5249, 0x3D48, 0x423F, 0x546C, 0x4C6B, 0xB867,      0,      0,\n      0, 0xB868, 0x4C34, 0xB869, 0xB86A, 0x546E,      0, 0x4267,\n 0xB86B, 0x4537, 0x4240, 0x4957, 0x546F, 0x5470, 0x317B, 0xB86C,\n 0xB86D, 0x3C3A, 0x5471, 0xB86E,      0, 0xB86F, 0xB870, 0x3050,\n 0x5472,      0,      0,      0,      0,      0, 0x5473, 0xB871,\n};\nconst unsigned short utf8_to_euc_E5A5[] = {\n      0,      0,      0, 0xB872, 0x3162,      0, 0xB873, 0x3471,\n 0x4660, 0x4A74,      0,      0,      0,      0, 0x5477, 0x4155,\n 0x5476, 0x3740, 0xB874, 0xB875, 0x4B5B, 0x5475,      0, 0x4565,\n 0x5479, 0xB876, 0x5478, 0xB877,      0, 0xB878, 0xB879, 0xB87A,\n 0x547B, 0xB87B, 0x547A, 0xB87C,      0, 0x317C,      0, 0x547C,\n 0x3E29, 0x547E, 0x4325, 0xB87D, 0x547D, 0xB87E, 0x4A33, 0xB921,\n      0,      0, 0xB922, 0x3D77, 0x455B, 0xB923, 0xB924,      0,\n 0x5521, 0xB925,      0, 0xB926, 0xB927, 0x3925,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5A6[] = {\n      0, 0x5522, 0x4721, 0x485E, 0x4C51,      0,      0,      0,\n      0,      0, 0x4725, 0xB928, 0xB929, 0x552B, 0xB92A,      0,\n      0,      0, 0xB92B, 0x3538,      0, 0xB92C, 0x4D45, 0xB92D,\n      0, 0x4C2F,      0, 0x562C,      0, 0x5523,      0, 0xB92E,\n      0,      0,      0, 0x5526, 0xB92F, 0x4245,      0, 0xB930,\n 0x4B38,      0,      0,      0, 0x454A, 0xB931, 0xB932, 0xB933,\n 0xB934,      0, 0x5527, 0xB935,      0,      0,      0, 0xB936,\n      0, 0x4B65, 0xB937, 0x3A4A, 0xB938,      0, 0x3E2A,      0,\n};\nconst unsigned short utf8_to_euc_E5A7[] = {\n      0, 0xB939,      0, 0xB93A, 0xB93B,      0, 0x5528,      0,\n 0xB93C, 0x3B50, 0xB93D, 0x3B4F,      0, 0xB93E,      0,      0,\n 0x3039, 0x3848, 0xB93F, 0x402B, 0x3051,      0,      0,      0,\n      0, 0x552C, 0x552D,      0, 0x552A, 0xB940, 0xB941, 0xB942,\n      0,      0,      0, 0xB943, 0xB944, 0x3138, 0x342F, 0xB945,\n 0x5529,      0, 0x4C45, 0x4931,      0,      0, 0xB946, 0xB947,\n      0, 0xB948, 0xB949,      0, 0xB94A,      0, 0x3028, 0xB94B,\n      0,      0,      0, 0x3079,      0,      0,      0, 0x3B51,\n};\nconst unsigned short utf8_to_euc_E5A8[] = {\n 0xB94C, 0x3052,      0, 0x3023, 0xB94D,      0,      0,      0,\n      0, 0x5532,      0,      0, 0xB94E, 0xB94F, 0xB950,      0,\n      0, 0x5530, 0xB951, 0xB952,      0,      0,      0,      0,\n 0x4C3C,      0, 0x5533,      0, 0x5531,      0, 0xB953, 0x552F,\n 0x3F31,      0,      0, 0xB954, 0xB955, 0x552E,      0, 0xB956,\n 0xB957, 0x4A5A, 0xB958,      0,      0, 0xB959,      0, 0x3864,\n 0xB95A,      0,      0,      0,      0, 0x5537, 0x5538,      0,\n      0,      0,      0,      0, 0x3E2B,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5A9[] = {\n 0x5534, 0x4F2C,      0,      0, 0xB95B, 0xB95C, 0x474C, 0xB95D,\n 0xB95E, 0x5536,      0,      0, 0xB95F,      0,      0,      0,\n 0xB960,      0,      0,      0,      0, 0xB961,      0,      0,\n      0,      0, 0x3A27,      0,      0,      0, 0xB962,      0,\n      0,      0, 0x5539, 0xB963,      0, 0xB964, 0x4958, 0xB965,\n      0,      0, 0x553A,      0, 0x5535, 0xB966,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xB967,\n      0,      0, 0xB968, 0xB969,      0,      0, 0xB96A, 0x4C3B,\n};\nconst unsigned short utf8_to_euc_E5AA[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xB96B,      0,      0,      0,      0,\n 0xB96C,      0, 0x475E, 0xB96D,      0,      0, 0xB96E,      0,\n      0, 0xB96F, 0x553B, 0x4932, 0xB970,      0, 0xB971, 0xB972,\n 0xB973,      0, 0xB974,      0,      0,      0,      0, 0xB975,\n      0,      0,      0,      0, 0xB976,      0,      0,      0,\n      0, 0xB977, 0xB978, 0xB979,      0, 0xB97A,      0,      0,\n 0xB97B,      0, 0xB97C, 0xB97D, 0x553C, 0x5540, 0x553D, 0xB97E,\n};\nconst unsigned short utf8_to_euc_E5AB[] = {\n      0, 0x3247, 0x553F,      0, 0xBA21,      0, 0xBA22,      0,\n 0xBA23, 0x3C3B,      0, 0x553E, 0x3779,      0,      0, 0xBA24,\n 0x554C,      0,      0,      0,      0,      0, 0x5545, 0x5542,\n      0,      0, 0xBA25,      0, 0xBA26,      0,      0,      0,\n 0xBA27, 0x4364,      0, 0x5541,      0, 0xBA28, 0x5543,      0,\n      0, 0x5544, 0xBA29,      0,      0,      0, 0xBA2A,      0,\n      0,      0,      0,      0,      0, 0xBA2B, 0xBA2C,      0,\n      0,      0, 0x5546, 0x5547,      0, 0xBA2D,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5AC[] = {\n 0xBA2E, 0xBA2F,      0,      0,      0,      0,      0,      0,\n 0xBA30, 0x3472,      0, 0x5549, 0x5548,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x554A, 0xBA31,\n      0, 0xBA33,      0, 0xBA34,      0, 0xBA35,      0,      0,\n      0, 0xBA36, 0x3E6E,      0,      0, 0xBA37,      0,      0,\n      0,      0, 0x554D,      0, 0x445C, 0xBA38,      0,      0,\n 0x3145,      0, 0x554B,      0, 0xBA32,      0, 0x554E,      0,\n 0xBA39,      0,      0,      0,      0,      0, 0x554F,      0,\n};\nconst unsigned short utf8_to_euc_E5AD[] = {\n 0x5552, 0xBA3A,      0, 0x5550,      0, 0x5551,      0,      0,\n      0,      0,      0, 0xBA3B, 0xBA3C,      0,      0,      0,\n 0x3B52, 0x5553, 0xBA3D,      0, 0x3926, 0x5554, 0xBA3E, 0x3B7A,\n 0x4238,      0, 0x5555, 0x5556, 0x3B5A, 0x3927, 0xBA3F, 0x4C52,\n      0,      0,      0, 0x3528, 0x3849, 0x5557, 0x3358,      0,\n 0xBA40, 0x5558,      0, 0x4239,      0,      0, 0xBA41, 0xBA42,\n 0x5559, 0x5623,      0, 0x555A,      0, 0x555B,      0,      0,\n 0x555C,      0, 0x555E,      0, 0xBA43, 0xBA44, 0xBA45, 0xBA46,\n};\nconst unsigned short utf8_to_euc_E5AE[] = {\n 0x555F, 0xBA47,      0, 0x5560, 0xBA48, 0x4270, 0xBA49, 0x3127,\n 0x3C69, 0x3042, 0xBA4A, 0x4157, 0x3430, 0x3C35, 0xBA4B, 0x3928,\n 0xBA4C, 0xBA4D,      0, 0xBA4E, 0xBA4F, 0x4566, 0xBA50, 0x3D21,\n 0x3431, 0x4368, 0x446A, 0x3038, 0x3539, 0x4A75,      0, 0x3C42,\n      0,      0, 0x3552, 0x406B, 0x3C3C, 0x4D28, 0x5561,      0,\n 0xBA51, 0xBA52,      0,      0, 0xBA53, 0xBA54, 0x355C, 0xBA55,\n 0x3A4B, 0xBA56, 0xBA57, 0x3332, 0x3163, 0x3E2C, 0x3248, 0xBA58,\n 0x5562, 0x4D46, 0xBA59,      0, 0xBA5A,      0,      0, 0x3D49,\n};\nconst unsigned short utf8_to_euc_E5AF[] = {\n 0xBA5B, 0xBA5C, 0x3C64, 0x5563, 0x3473, 0x4652, 0x4C29, 0x5564,\n      0, 0x5565,      0,      0, 0x4959, 0xBA5D,      0, 0xBA5E,\n 0x5567,      0, 0x3428, 0x3677, 0x5566,      0, 0xBA5F, 0xBA60,\n 0xBA61, 0xBA62, 0xBA63, 0x3432,      0, 0x3F32, 0x556B, 0x3B21,\n 0xBA64, 0x3249, 0x556A,      0, 0x5568, 0x556C, 0x5569, 0x472B,\n 0x5C4D, 0x3F33,      0, 0x556D, 0xF43A,      0, 0x4E40, 0xBA65,\n 0x556E, 0xBA66,      0, 0x5570, 0xBA67, 0x437E, 0x556F,      0,\n 0x4023,      0, 0x3B7B,      0,      0, 0xBA68, 0x4250, 0x3C77,\n};\nconst unsigned short utf8_to_euc_E5B0[] = {\n      0, 0x4975, 0x406C,      0, 0x3C4D, 0x5571, 0x3E2D, 0x5572,\n 0x5573, 0x3053, 0x423A, 0x3F52, 0xBA69, 0x5574, 0x4633, 0x3E2E,\n      0, 0x3E2F,      0, 0x5575,      0,      0, 0x406D, 0xBA6A,\n      0,      0, 0x3E30,      0,      0,      0, 0xBA6B, 0xBA6C,\n 0x5576,      0, 0x5577, 0xBA6D, 0x4C60,      0, 0xBA6E,      0,\n 0x5578, 0xBA6F,      0, 0xBA70, 0xBA71, 0x3646, 0xBA72,      0,\n 0xBA73, 0x3D22, 0xBA74,      0,      0, 0xBA75, 0xBA76,      0,\n 0x5579, 0x557A, 0x3C5C, 0x3F2C, 0x4674, 0x3F54, 0x4878, 0x4722,\n};\nconst unsigned short utf8_to_euc_E5B1[] = {\n 0x3649, 0x557B,      0,      0,      0, 0x356F, 0x557C,      0,\n 0x367E,      0, 0x464F, 0x3230,      0, 0x3B53, 0x557D, 0x5622,\n 0x5621, 0x367D,      0, 0x557E,      0, 0x4538,      0,      0,\n      0, 0xBA77, 0xBA78,      0, 0xBA79,      0, 0x4230,      0,\n 0x454B, 0x3C48, 0xBA7A, 0xBA7B, 0x4158, 0x4D7A,      0, 0xBA7C,\n 0xBA7D, 0xBA7E,      0,      0, 0x5624, 0xBB21, 0x5625, 0x4656,\n 0xBB22, 0x3B33,      0,      0, 0xBB23, 0xBB24, 0x5627,      0,\n      0, 0x5628, 0xBB25, 0xBB26, 0xBB27, 0xBB28,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5B2[] = {\n      0,      0,      0,      0,      0,      0,      0, 0xBB29,\n 0xBB2A,      0, 0xBB2B,      0, 0x5629,      0,      0, 0xBB2C,\n 0x3474, 0x562A, 0xBB2D,      0, 0x562B,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xBB2E,      0, 0xBB2F,\n 0xBB30, 0x322C, 0xBB31, 0xBB32,      0,      0, 0xBB33,      0,\n 0x413B, 0x3464, 0xBB34, 0x562D, 0x4C28,      0,      0,      0,\n      0, 0x4252, 0xBB35, 0x3359, 0xBB36, 0xBB37, 0x562F, 0x5631,\n 0x345F,      0, 0xBB38, 0x562E, 0x5630,      0, 0x5633,      0,\n};\nconst unsigned short utf8_to_euc_E5B3[] = {\n      0,      0,      0,      0,      0, 0x5632,      0, 0x5634,\n      0, 0xBB39,      0, 0xBB3A,      0,      0,      0,      0,\n      0,      0, 0xBB3B,      0,      0,      0,      0, 0xBB3D,\n      0, 0x5635,      0,      0,      0, 0xBB3C,      0,      0,\n 0x463D, 0x362E,      0,      0,      0,      0,      0,      0,\n 0x3265, 0x5636, 0x563B,      0,      0, 0x5639, 0xBB3E, 0x4A77,\n 0x4A76, 0xBB3F, 0xBB40,      0, 0xBB41, 0xF43B, 0x4567,      0,\n      0,      0, 0x5638, 0x3D54,      0, 0x5637,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5B4[] = {\n      0, 0xBB42,      0,      0,      0,      0, 0xBB43, 0x3F72,\n      0,      0,      0, 0x563C,      0, 0xBB44, 0x3A6A,      0,\n      0, 0x5642, 0xBB45,      0, 0x5643, 0x563D, 0x3333, 0x563E,\n 0x5647, 0x5646, 0x5645, 0x5641,      0,      0,      0, 0x5640,\n      0,      0, 0x5644, 0xBB47, 0xBB48,      0, 0xBB49, 0xBB4A,\n      0, 0x4A78,      0, 0xBB46,      0,      0,      0,      0,\n      0, 0xBB4B,      0,      0, 0xBB4C,      0,      0,      0,\n      0, 0xBB4D,      0,      0,      0, 0xBB4E,      0, 0xBB4F,\n};\nconst unsigned short utf8_to_euc_E5B5[] = {\n      0,      0, 0xBB50, 0xBB51,      0,      0, 0xBB52,      0,\n 0xBB53,      0, 0xBB57, 0x564B, 0x5648,      0, 0x564A,      0,\n 0x4D72, 0xBB55, 0x5649, 0xF43C,      0, 0xBB54,      0,      0,\n      0, 0xBB56,      0,      0, 0x563F,      0,      0, 0xBB58,\n 0xBB59, 0xBB5A, 0xBB5B,      0, 0xBB5C,      0,      0,      0,\n      0, 0x3F73, 0xBB5D,      0, 0x564C, 0xBB5E,      0, 0x3A37,\n 0xBB5F,      0,      0, 0x564D,      0,      0, 0x564E,      0,\n      0, 0xBB60, 0xBB61,      0,      0,      0, 0xBB62, 0xBB63,\n};\nconst unsigned short utf8_to_euc_E5B6[] = {\n      0, 0xBB64, 0x5651, 0xBB65, 0x5650,      0,      0, 0x564F,\n 0xBB66,      0, 0xBB67, 0x4568, 0x563A,      0,      0,      0,\n 0x5657,      0, 0xBB68, 0xBB69, 0xBB6A, 0xBB6B,      0,      0,\n      0, 0xBB6C,      0, 0xBB6D,      0, 0x5653,      0, 0xBB6E,\n 0xBB6F,      0, 0x5652,      0,      0,      0,      0, 0xBB70,\n      0,      0,      0, 0xBB71, 0x5654,      0, 0x5655,      0,\n 0xBB72,      0, 0xE674,      0, 0xBB73,      0,      0, 0x5658,\n 0xBB74, 0xBB75, 0x4E66,      0, 0x5659, 0x5656,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5B7[] = {\n      0,      0,      0, 0xBB76,      0,      0,      0, 0xBB77,\n      0, 0x565A,      0, 0xBB78, 0x3460, 0x565B, 0xBB7A,      0,\n 0xBB79,      0, 0x565D, 0x565C,      0,      0, 0x565E,      0,\n 0xBB7B, 0xBB7C,      0, 0x565F,      0, 0x406E, 0x3D23,      0,\n 0xBB7D, 0x3D64,      0, 0x4163, 0xBB7E, 0x3929, 0x3A38, 0x392A,\n 0x3570, 0xBC21,      0, 0x5660,      0,      0, 0x3A39,      0,\n      0, 0x384A, 0x5661, 0x4C26, 0x4743, 0x5662,      0, 0x392B,\n 0xBC22, 0xBC23,      0, 0x342C,      0, 0x4327, 0x3652,      0,\n};\nconst unsigned short utf8_to_euc_E5B8[] = {\n 0xBC24,      0, 0x3B54, 0x495B,      0,      0, 0x4841, 0xBC25,\n      0,      0,      0, 0x5663, 0x3475, 0xBC26,      0,      0,\n      0, 0x5666, 0xBC27,      0, 0xBC28, 0xBC29, 0x4421,      0,\n 0xBC2A, 0x5665, 0x5664, 0x5667,      0, 0x446B,      0, 0xBC2B,\n 0xBC2C,      0,      0,      0,      0, 0x3F63,      0,      0,\n 0xBC2E,      0,      0, 0x3B55,      0, 0x404A, 0xBC2D, 0x4253,\n 0x3522,      0, 0xBC2F, 0x4422,      0, 0xBC30, 0x5668, 0x5669,\n 0x3E6F,      0,      0,      0,      0, 0x4B39, 0xBC31,      0,\n};\nconst unsigned short utf8_to_euc_E5B9[] = {\n 0x566C,      0,      0, 0x566B, 0x566A, 0x497D,      0, 0x5673,\n      0, 0xBC34,      0, 0xBC32, 0x4B5A,      0, 0x566D,      0,\n 0xBC33, 0xBC35,      0,      0, 0x566F, 0x4B6B, 0xBC36, 0x566E,\n 0xBC37,      0,      0, 0xBC38, 0xBC39,      0, 0xBC3A, 0x5670,\n      0, 0x4828, 0x5671, 0x4A3E, 0x5672,      0,      0,      0,\n 0xBC3B,      0, 0xBC3C, 0xBC3D, 0xBC3E, 0xBC3F, 0xBC40,      0,\n 0xBC41,      0, 0x3433, 0x4A3F, 0x472F, 0x5674, 0x5675,      0,\n 0x392C, 0x3434, 0x5676, 0x3838, 0x4D44, 0x4D29, 0x3476, 0x5678,\n};\nconst unsigned short utf8_to_euc_E5BA[] = {\n 0xBC42, 0x4423,      0, 0x392D, 0x3E31,      0,      0, 0x485F,\n      0,      0, 0x3E32, 0xBC43,      0,      0, 0xBC44, 0x3D78,\n      0,      0,      0,      0,      0, 0x446C, 0x4A79, 0x4539,\n      0,      0, 0x392E,      0, 0x495C,      0,      0,      0,\n 0x5679,      0, 0xBC45,      0, 0xBC46, 0xBC47, 0x4559, 0x3A42,\n 0xBC48,      0, 0xBC49, 0x384B, 0xBC4A, 0x446D,      0,      0,\n      0, 0xBC4B,      0, 0xBC4C,      0, 0x3043, 0x3D6E, 0x392F,\n 0x4D47,      0,      0,      0,      0, 0xBC4D, 0xBC4E, 0xBC4F,\n};\nconst unsigned short utf8_to_euc_E5BB[] = {\n      0, 0x567A, 0x567B, 0x4751,      0,      0, 0xBC50,      0,\n 0x567C, 0x4E77, 0x4F2D, 0xBC52, 0xBC51,      0, 0xBC53, 0x567E,\n 0x567D, 0xBC54, 0xBC55, 0x3347, 0xBC56, 0xBC57, 0x5721,      0,\n      0,      0, 0x5724, 0x5725, 0xBC58, 0x5723, 0xBC59, 0x4940,\n 0x3E33, 0x5727, 0x5726, 0x5722,      0, 0xBC5A,      0,      0,\n 0x5728, 0x5729,      0, 0xBC5B, 0x572A,      0,      0,      0,\n 0x572D, 0x572B,      0, 0x572C, 0x572E,      0, 0x3164, 0x446E,\n 0x572F,      0, 0x377A, 0x3276, 0x4736,      0, 0x5730, 0x467B,\n};\nconst unsigned short utf8_to_euc_E5BC[] = {\n      0, 0x4A5B, 0xBC5C, 0x5731, 0x4F2E,      0, 0xBC5D, 0xBC5E,\n 0xBC5F, 0x5732, 0x4A40, 0x5735, 0x5021, 0x5031, 0xBC60, 0x3C30,\n 0x4675, 0x5736,      0, 0x355D, 0x4424, 0x307A, 0x5737, 0x4A26,\n 0x3930, 0xBC61,      0, 0x4350, 0xBC62, 0xBC63,      0, 0x446F,\n      0, 0xBC64, 0xBC65, 0xBC66, 0xBC67, 0x4C6F, 0x3839, 0x384C,\n 0xBC68, 0x5738,      0, 0xBC69, 0xBC6A, 0x5739, 0xBC6B, 0x573F,\n 0xBC6C, 0x3C65,      0,      0, 0xBC6D, 0x4425, 0xBC6E, 0x362F,\n 0x573A,      0,      0, 0xBC6F, 0x492B, 0xBC70, 0x4346, 0xBC71,\n};\nconst unsigned short utf8_to_euc_E5BD[] = {\n 0xBC72, 0x573B,      0,      0, 0xBC73, 0xBC74,      0, 0xBC75,\n 0x573C,      0, 0x3630,      0, 0x573D, 0xBC76, 0x573E,      0,\n 0xBC77, 0x5740,      0, 0x4576, 0xBC78,      0, 0x5741, 0x5742,\n 0xBC79, 0x5743,      0, 0xBC7A, 0x5734, 0x5733,      0,      0,\n 0xBC7B, 0x5744, 0x3741, 0xBC7C, 0xBC7D,      0, 0x4927, 0xBC7E,\n      0, 0x3A4C, 0x4937, 0x4426, 0x494B, 0x5745,      0, 0xBD21,\n 0x3E34, 0x3146, 0xBD22, 0x5746, 0xBD23, 0xBD24,      0, 0x5747,\n 0xBD25, 0x4C72, 0xBD26,      0, 0x4860, 0xBD27, 0xBD28, 0x574A,\n};\nconst unsigned short utf8_to_euc_E5BE[] = {\n 0x317D, 0x402C, 0x5749, 0x5748, 0x3742, 0x4254,      0, 0x574E,\n 0x574C, 0xBD29, 0x574B, 0x4E27, 0x3865, 0xBD2A,      0, 0xBD2B,\n 0x3D79, 0x574D, 0x454C, 0x3D3E,      0,      0, 0xBD2C, 0x4640,\n 0x5751, 0x5750,      0,      0, 0xBD2D, 0xBD2E, 0x574F,      0,\n 0x5752, 0x3866, 0xBD2F,      0, 0xBD32,      0,      0, 0xBD30,\n 0x5753, 0x497C, 0x3D5B, 0xBD31, 0xBD33, 0x5754, 0x4879, 0xBD34,\n 0xBD35, 0xBD36,      0, 0x4641, 0x4427,      0,      0, 0xF43E,\n 0xBD37, 0x4530,      0,      0, 0x5755, 0x352B,      0,      0,\n};\nconst unsigned short utf8_to_euc_E5BF[] = {\n      0,      0,      0, 0x3F34, 0xBD38, 0x492C,      0, 0xBD39,\n 0xBD3A, 0xBD3B,      0, 0xBD3C, 0x3477, 0x4726,      0,      0,\n 0xBD3D, 0xBD3E, 0xBD3F, 0xBD40, 0xBD41,      0, 0x5756, 0x3B56,\n 0x4B3A, 0x4B3B,      0,      0, 0x317E, 0x575B, 0xBD42,      0,\n 0x4369, 0xBD43, 0xBD44,      0, 0x5758,      0,      0,      0,\n 0xBD45, 0xBD46, 0xBD47, 0x3277, 0xBD48, 0xBD49, 0xBD4A, 0xBD4B,\n 0x582D, 0x575A, 0xBD4C, 0xBD4D,      0, 0x4730, 0xBD4E,      0,\n 0x5759,      0, 0xBD4F, 0x5757, 0xBD50, 0x397A,      0, 0x575D,\n};\nconst unsigned short utf8_to_euc_E680[] = {\n      0,      0,      0,      0,      0,      0,      0, 0xBD51,\n      0,      0, 0xBD52,      0,      0, 0xBD53, 0x5763, 0x5769,\n 0x5761,      0, 0x455C, 0xBD54, 0xBD55, 0x5766, 0x495D, 0xBD56,\n 0xBD57, 0x5760, 0xBD58, 0x5765, 0x4E67, 0x3B57,      0, 0xBD59,\n 0x4255, 0x575E,      0,      0, 0xBD5A, 0x355E, 0x5768, 0x402D,\n 0x3165, 0x5762, 0x3278, 0x5767,      0, 0xBD5B,      0, 0x3631,\n      0, 0x5764,      0, 0xBD5C,      0, 0xBD5D,      0,      0,\n      0,      0, 0x576A,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E681[] = {\n 0xBD5E, 0x576C, 0x5776, 0x5774,      0,      0, 0x5771, 0xBD5F,\n 0xBD60, 0xBD61, 0x5770, 0x4E78, 0xBD62, 0x5772,      0,      0,\n 0x3632, 0xBD63, 0x3931,      0, 0xBD64, 0x3D7A, 0xBD65, 0xBD66,\n      0, 0x5779, 0x576B,      0,      0, 0xBD67,      0, 0x576F,\n 0x575F, 0xBD68, 0x327A, 0x5773, 0x5775, 0x4351,      0, 0xBD69,\n 0x3A28, 0x3238, 0x576D, 0x5778, 0x5777, 0x3633,      0, 0x4229,\n 0x3366, 0xBD6A,      0,      0,      0, 0x3743,      0, 0x576E,\n      0,      0,      0,      0,      0,      0, 0xBD6B, 0xBD6C,\n};\nconst unsigned short utf8_to_euc_E682[] = {\n      0, 0x577A, 0xBD6D, 0x577D, 0x5821, 0xF43F, 0xBD6E,      0,\n 0xBD6F, 0x3C3D, 0xBD70, 0x5827, 0x4470, 0x577B, 0xBD71,      0,\n      0, 0xBD72, 0x5825, 0xBD73, 0x3279, 0xBD74, 0x5823, 0x5824,\n 0xBD75,      0, 0x577E, 0x5822,      0, 0xBD76, 0xBD77, 0x3867,\n 0x4D2A,      0, 0xBD78, 0x3435, 0xBD79, 0xBD7A, 0x3159, 0x5826,\n 0xBD7B, 0x473A, 0x302D,      0,      0,      0,      0,      0,\n 0xBD7C, 0xBD7D, 0x4861, 0x575C, 0x582C, 0x5830, 0x4C65, 0xBD7E,\n 0x5829,      0,      0, 0xBE21, 0x4569, 0x582E, 0xBE22,      0,\n};\nconst unsigned short utf8_to_euc_E683[] = {\n      0,      0, 0xBE23,      0, 0xBE24, 0x3E70, 0x582F, 0x4657,\n 0xBE25, 0xBE26, 0xBE27, 0xBE28,      0,      0, 0xBE29, 0xBE2A,\n      0, 0x4F47,      0, 0x582B, 0xBE2B, 0xBE2C,      0,      0,\n 0x5831, 0xBE2D, 0x397B, 0xBE2E, 0x404B, 0xBE2F, 0xBE30, 0x3054,\n 0x582A, 0x5828, 0xBE31, 0x415A,      0, 0xBE32,      0, 0x577C,\n 0x3B34,      0,      0,      0,      0,      0,      0,      0,\n 0x4246, 0x583D, 0xBE33, 0x415B, 0x5838, 0xBE34, 0x5835, 0x5836,\n 0xBE35, 0x3C66, 0x5839, 0x583C, 0xBE36, 0xBE37,      0,      0,\n};\nconst unsigned short utf8_to_euc_E684[] = {\n 0x5837, 0x3D25, 0xBE38, 0x583A,      0,      0, 0x5834, 0xBE39,\n 0x4C7C, 0x4C7B, 0xBE3A,      0, 0xBE3B, 0x583E, 0x583F, 0x3055,\n 0xBE3C, 0xBE3D, 0xBE3E, 0xBE3F, 0xBE40, 0x5833, 0xBE41, 0xBE42,\n      0, 0xBE43, 0x3672, 0x3026, 0xBE44,      0, 0xBE45, 0x3436,\n 0xF440, 0x583B, 0xBE46,      0,      0,      0,      0, 0x5843,\n 0x5842,      0, 0xBE47, 0xBE48, 0x5847,      0,      0,      0,\n 0xBE49, 0xBE4A,      0,      0, 0x5848, 0xBE4B, 0xBE4C, 0xBE4D,\n      0, 0xBE4E,      0,      0, 0x5846, 0x5849, 0x5841, 0x5845,\n};\nconst unsigned short utf8_to_euc_E685[] = {\n      0, 0xBE4F, 0x584A,      0, 0x584B, 0xBE50, 0xBE51, 0x5840,\n 0x3B7C, 0xBE52, 0x5844, 0x4256, 0x3932, 0x5832, 0x3F35,      0,\n      0,      0,      0, 0x5858,      0, 0x4A69,      0,      0,\n 0x584E, 0x584F, 0x5850,      0,      0, 0x5857, 0xBE53, 0x5856,\n 0xBE54,      0, 0x4B7D, 0x3437,      0, 0x5854,      0, 0x3745,\n 0x3334,      0,      0, 0x5851, 0xBE55,      0, 0x4E38, 0x5853,\n 0x3056, 0x5855, 0xBE56, 0x584C, 0x5852, 0x5859, 0x3744, 0x584D,\n 0xBE57,      0,      0, 0xBE58, 0xBE59,      0, 0x4D5D, 0xBE5A,\n};\nconst unsigned short utf8_to_euc_E686[] = {\n 0xBE5B, 0xBE5C, 0x4D2B, 0xBE5D, 0xBE5E,      0,      0, 0x585C,\n      0,      0, 0x5860, 0xBE5F,      0, 0xBE60, 0x417E,      0,\n 0x4E79, 0x5861, 0xBE61, 0xBE62, 0x585E,      0, 0x585B, 0xBE63,\n 0xBE64, 0x585A, 0x585F,      0, 0xBE65, 0xBE66,      0, 0xBE67,\n 0xBE68,      0,      0,      0, 0x4A30, 0xBE69,      0, 0x4634,\n 0xBE6A, 0x3746, 0xBE6B, 0x5862, 0x585D, 0xBE6C, 0x5863,      0,\n      0,      0, 0x377B,      0,      0,      0, 0x3231,      0,\n 0xBE6D, 0xBE6E, 0x586B,      0, 0xBE6F,      0, 0x3438,      0,\n};\nconst unsigned short utf8_to_euc_E687[] = {\n 0xBE70, 0xBE71, 0xBE72, 0x5869,      0,      0, 0x586A, 0x3A29,\n 0x5868, 0x5866, 0x5865, 0x586C, 0x5864, 0x586E, 0xBE73, 0xBE74,\n 0x327B,      0,      0,      0,      0, 0xBE75,      0,      0,\n      0,      0,      0,      0, 0xBE76, 0xBE77, 0xBE78, 0xBE79,\n      0, 0xBE7A, 0xBE7B, 0x5870,      0, 0xBE7E, 0x586F, 0xBE7C,\n      0, 0xBE7D,      0,      0, 0xBF21, 0xBF22,      0, 0xBF23,\n      0,      0, 0x4428,      0, 0x5873,      0, 0x5871, 0x5867,\n 0x377C,      0, 0x5872,      0, 0x5876, 0x5875, 0x5877, 0x5874,\n};\nconst unsigned short utf8_to_euc_E688[] = {\n 0x5878, 0xBF24,      0, 0xBF25, 0xBF26,      0,      0, 0xBF27,\n 0x5879, 0x587A, 0x4A6A,      0, 0x587C, 0x587B, 0x3D3F,      0,\n 0x402E, 0x3266, 0x327C, 0xBF28, 0x587D, 0xBF29, 0x303F,      0,\n      0,      0, 0x404C, 0x587E, 0xBF2A, 0x6C43, 0x5921, 0x3761,\n 0xBF2B, 0x5922, 0xBF2C, 0xBF2D,      0,      0, 0x406F, 0xBF2E,\n      0, 0xBF2F, 0x5923, 0xBF30,      0,      0, 0x5924, 0x353A,\n 0x5925,      0, 0x5926, 0x5927, 0x4257,      0,      0,      0,\n 0x384D, 0xBF31,      0, 0x4C61,      0, 0xBF32,      0, 0x4B3C,\n};\nconst unsigned short utf8_to_euc_E689[] = {\n 0x3D6A, 0x5928, 0xBF33, 0xBF34, 0xBF35,      0, 0xBF36, 0x4070,\n 0x6E3D, 0x4862,      0, 0x3C6A, 0xBF37, 0x3A4D, 0x5929,      0,\n 0xBF38, 0xBF39, 0xBF3A, 0x4247, 0xBF3B, 0x4A27, 0xBF3C,      0,\n 0x4271,      0, 0xBF3D, 0x592C, 0xBF3E,      0, 0x592A,      0,\n 0x592D,      0,      0, 0x592B, 0xBF3F,      0,      0,      0,\n 0x592E,      0,      0,      0,      0, 0xBF40, 0x4A31, 0xBF41,\n      0, 0x3037,      0, 0xBF42,      0,      0, 0x495E,      0,\n      0, 0x4863, 0xBF43,      0, 0x592F, 0xBF44, 0x5932, 0x3E35,\n};\nconst unsigned short utf8_to_euc_E68A[] = {\n 0x353B,      0, 0x5930, 0x5937, 0x3E36,      0,      0,      0,\n      0, 0x5931, 0x4744,      0,      0, 0xBF45, 0xBF46, 0xBF47,\n 0xBF48, 0x4D5E, 0x5933, 0x5934, 0x5938, 0x456A, 0x5935, 0x3933,\n 0x405E,      0,      0, 0x5946, 0x4834,      0, 0x4272,      0,\n      0,      0,      0,      0,      0,      0, 0xBF49,      0,\n 0xBF4A,      0,      0, 0x4864, 0x5A2D,      0,      0,      0,\n      0, 0x4A7A,      0, 0xBF4B,      0, 0x4471, 0xBF4C, 0xBF4D,\n      0, 0x4B75, 0xBF4E, 0x593B, 0x3221, 0x436A, 0xBF4F, 0xBF50,\n};\nconst unsigned short utf8_to_euc_E68B[] = {\n      0,      0, 0x5944,      0, 0xBF51, 0x4334, 0x593E, 0x5945,\n 0x5940, 0x5947, 0x5943,      0, 0x5942, 0x476F, 0xBF52, 0x593C,\n 0x327D, 0x593A, 0x3571, 0x4273, 0x5936, 0xBF53, 0xBF54, 0x5939,\n 0x3934, 0x405B, 0xBF55, 0x3E37, 0x5941, 0x4752,      0,      0,\n 0x3572, 0x3348,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xBF56,      0, 0x3367, 0x3F21, 0x5949, 0x594E,\n      0, 0x594A, 0xBF57, 0x377D, 0xBF58, 0x594F, 0x3B22, 0x3969,\n      0,      0,      0,      0, 0xBF59, 0xBF5A, 0x3D26, 0x593D,\n};\nconst unsigned short utf8_to_euc_E68C[] = {\n      0, 0x3B7D, 0x594C, 0xBF5B, 0xBF5C,      0,      0, 0x3B58,\n 0x594D, 0x3044, 0xBF5D, 0xBF5E, 0x5948, 0xBF5F,      0,      0,\n 0xBF60, 0x4429,      0, 0xBF61,      0,      0, 0xBF62,      0,\n 0xBF63, 0x3573,      0,      0,      0,      0,      0, 0x3634,\n      0,      0,      0,      0,      0,      0,      0, 0x594B,\n 0x3027, 0xBF64, 0xBF65, 0x3A43,      0, 0xBF66,      0, 0x3F36,\n      0,      0,      0,      0,      0, 0xBF67, 0xBF68,      0,\n      0, 0xBF69, 0x4472,      0, 0xBF6A, 0x4854, 0x5951, 0x415E,\n};\nconst unsigned short utf8_to_euc_E68D[] = {\n      0, 0xBF6B, 0xBF6C, 0xBF6D, 0xBF6E,      0, 0xBF6F,      0,\n      0, 0x422A, 0xBF70, 0xBF71, 0x3B2B, 0x5952, 0xBF72, 0x5954,\n 0x5950,      0, 0xBF73, 0xBF74, 0xBF75, 0x4A61,      0, 0x443D,\n 0xBF76,      0,      0, 0xBF77, 0x415C,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xBF78, 0xBF79, 0x4A7B,\n 0x3C4E, 0x5960,      0, 0x595F, 0xBF7A, 0xBF7B, 0x3F78,      0,\n      0, 0xBF7C, 0x377E,      0, 0xBF7D, 0xBF7E, 0x5959, 0x3E39,\n 0xC021,      0, 0x4668, 0x4731, 0xC022, 0xC023,      0, 0xC024,\n};\nconst unsigned short utf8_to_euc_E68E[] = {\n 0x5957,      0, 0xC025, 0x415D, 0xC026,      0,      0, 0xC027,\n 0x3C78, 0x595C, 0xC028,      0, 0x3E38,      0, 0x5956, 0x595B,\n 0xC029,      0, 0x4753,      0, 0xC02A, 0xC02B, 0x5955,      0,\n 0x3721, 0xC02C, 0xC02D, 0x335D,      0,      0, 0xC02E, 0x595D,\n 0x4E2B, 0x3A4E, 0x4335, 0x595A, 0xC02F, 0x405C, 0xC030, 0x3935,\n 0x3F64, 0x3166, 0x413C, 0x5958, 0x3545, 0xC031, 0xC032, 0xC033,\n      0,      0, 0x3747,      0, 0x444F, 0x595E,      0,      0,\n      0,      0,      0, 0x415F,      0, 0xC034, 0x5961,      0,\n};\nconst unsigned short utf8_to_euc_E68F[] = {\n 0x5963, 0xC035,      0, 0x4237, 0x5969, 0xC036, 0x5964,      0,\n 0xC037, 0x5966,      0,      0,      0,      0, 0xC038, 0x4941,\n 0x4473, 0xC039, 0x5967, 0xC03A, 0xC03B, 0xC03C, 0x4D2C,      0,\n      0,      0, 0x4D48, 0x3439, 0xC03D,      0,      0,      0,\n 0xC03E, 0x302E,      0, 0x5965,      0, 0xC03F,      0,      0,\n      0, 0x5962, 0xC040,      0, 0xC041,      0, 0x3478,      0,\n      0,      0, 0xC042, 0xC043, 0x3167, 0xC044, 0x5968,      0,\n 0xC045, 0xC046, 0x4D49,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E690[] = {\n      0,      0,      0,      0,      0,      0, 0x596C,      0,\n      0, 0xC047, 0xC048,      0,      0, 0x423B,      0, 0x5973,\n 0xC049,      0, 0xC04A, 0x596D, 0xC04B,      0, 0x596A, 0x5971,\n 0xC04C,      0,      0,      0, 0x5953,      0, 0xC04D,      0,\n 0xC04E,      0, 0xC04F,      0, 0xC050, 0xC051, 0x596E,      0,\n 0x5972, 0xC052, 0xC053,      0, 0x4842, 0x456B,      0, 0xC054,\n 0xC055,      0,      0,      0, 0x596B, 0xC056, 0x596F,      0,\n      0,      0, 0x3748,      0,      0, 0xC057, 0x3A71, 0xC058,\n};\nconst unsigned short utf8_to_euc_E691[] = {\n      0,      0, 0x405D,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xC059,      0,      0, 0x5977, 0xC05A,\n      0, 0xC05B, 0xC05C, 0xC05D, 0xC05E,      0,      0,      0,\n 0x4526,      0, 0xC05F, 0xC060, 0xC061, 0xC062,      0, 0xC063,\n 0xC064, 0xC065,      0, 0xC066,      0,      0,      0, 0x5974,\n      0, 0x4B60,      0,      0,      0, 0xC067,      0, 0x5975,\n      0,      0,      0, 0xC068, 0xC069,      0, 0x5976,      0,\n 0x4C4E,      0, 0x4022, 0xC06A,      0, 0xC06B,      0,      0,\n};\nconst unsigned short utf8_to_euc_E692[] = {\n      0,      0,      0, 0x3762,      0, 0xC06C,      0, 0xC06D,\n 0x597D,      0,      0,      0,      0,      0,      0, 0xC06E,\n 0xC06F, 0xC070, 0x3B35, 0x597A,      0, 0x5979,      0,      0,\n 0xC071, 0xC072, 0x4732, 0xC073,      0, 0xC074, 0x4635, 0xC075,\n      0, 0xC076,      0, 0xC077, 0x4531, 0x597B, 0xC078,      0,\n 0xC079, 0x597C,      0, 0x496F, 0xC07A, 0x4745, 0x3B23,      0,\n 0x4071,      0, 0x4B50, 0xC07B,      0,      0,      0,      0,\n      0, 0x3349,      0, 0x5A25, 0x597E, 0xC07C, 0xC07D, 0xC07E,\n};\nconst unsigned short utf8_to_euc_E693[] = {\n      0, 0x4D4A, 0x5A27,      0, 0xC121, 0x5A23,      0, 0x5A24,\n      0, 0xC122, 0xC123, 0xC124, 0xC125, 0x4160, 0xC126,      0,\n 0xC127, 0xC128, 0x5A22,      0, 0x593F, 0xC129,      0, 0xC12A,\n 0x5A26,      0, 0x5A21,      0,      0,      0,      0,      0,\n 0x5A2B, 0x5A2C, 0x4527, 0x5A2E, 0xC12B, 0xC12C, 0x3B24, 0x5A29,\n      0, 0xC12D, 0xC12E,      0, 0x353C, 0xC12F,      0, 0x5A2F,\n 0xC130, 0x5A28, 0x5A33,      0, 0x5A32, 0xC131, 0x5A31, 0xC132,\n      0,      0, 0x5A34, 0xC133,      0, 0x5A36, 0x3E71, 0xC134,\n};\nconst unsigned short utf8_to_euc_E694[] = {\n 0x5A35, 0xC135,      0,      0, 0xC136, 0x5A39,      0,      0,\n 0xC137, 0xC138, 0xC139,      0,      0,      0,      0, 0xC13A,\n      0,      0,      0, 0xC13B, 0xC13C,      0, 0xC13D,      0,\n 0x5A37, 0xC13E,      0, 0xC13F, 0x5A38, 0x5970, 0xC140, 0xC141,\n      0,      0, 0xC142, 0x5A3B, 0x5A3A,      0, 0xC143,      0,\n      0, 0xC144, 0x5978, 0x5A3C, 0x5A30,      0, 0xC145, 0x3B59,\n      0, 0xC146,      0,      0, 0x5A3D, 0x5A3E, 0x5A40, 0x5A3F,\n 0x5A41, 0x327E, 0xC147, 0x3936, 0xC148, 0xC149, 0x4A7C, 0x402F,\n};\nconst unsigned short utf8_to_euc_E695[] = {\n      0,      0,      0, 0xC14A,      0, 0x384E,      0, 0xC14B,\n 0x5A43, 0xC14C,      0,      0,      0, 0x5A46, 0xF441, 0x4952,\n 0xC14D, 0x355F, 0xC14E,      0, 0xC14F, 0x5A45, 0x5A44, 0x4754,\n 0x5A47, 0x3635,      0,      0,      0, 0x5A49, 0x5A48, 0xC150,\n 0xC151,      0, 0x343A, 0x3B36,      0,      0, 0x4658, 0xC152,\n      0,      0,      0, 0xC153, 0x3749,      0,      0,      0,\n 0x3F74,      0, 0x5A4A,      0, 0x4030, 0x4528,      0, 0x495F,\n 0x5A4B,      0, 0xC154,      0,      0, 0xC155,      0,      0,\n};\nconst unsigned short utf8_to_euc_E696[] = {\n      0, 0xC156, 0x5A4C, 0x5A4D,      0, 0xC157,      0, 0x4A38,\n 0x555D, 0x4046, 0xC158,      0, 0x494C,      0, 0x3A58,      0,\n 0x4865, 0x4843, 0xC159,      0,      0, 0xC15A,      0, 0x454D,\n 0xC15B, 0x4E41,      0, 0x5A4F, 0x3C50, 0xC15C,      0, 0x5A50,\n 0xC15D, 0x3036,      0, 0xC15E, 0x3654, 0x404D, 0xC15F, 0x4960,\n      0,      0,      0, 0x5A51, 0x3B42, 0x4347, 0xC160, 0x3B5B,\n 0x3F37,      0, 0xC161, 0xC162, 0xC163,      0,      0, 0x5A52,\n      0, 0x4A7D,      0,      0, 0x3177, 0x3B5C,      0, 0xC164,\n};\nconst unsigned short utf8_to_euc_E697[] = {\n      0, 0x5A55, 0xC165, 0x5A53, 0x5A56, 0x4E39, 0x5A54,      0,\n 0xC166, 0xC167,      0, 0x407B, 0x5A57,      0, 0xC168, 0x4232,\n 0xC169,      0, 0x5A58,      0, 0xC16A,      0, 0xC16B, 0x347A,\n 0xC16C, 0x5A5A,      0, 0x5A59,      0,      0,      0, 0xC16D,\n 0x5A5B, 0x5A5C, 0x347B,      0,      0, 0x467C, 0x4336, 0x356C,\n 0x3B5D, 0x4161,      0,      0, 0x3D5C, 0x3030,      0,      0,\n 0xC16E, 0x5A5D, 0xC16F,      0, 0xC170, 0xC171,      0,      0,\n      0, 0xC172, 0x3222, 0x5A61,      0,      0, 0xC173, 0xC174,\n};\nconst unsigned short utf8_to_euc_E698[] = {\n 0xC175,      0, 0x3937, 0x5A60, 0xC176,      0, 0x3A2B, 0x3E3A,\n 0xC177, 0xC178, 0x5A5F,      0, 0x3E3B, 0xC179, 0x4C40, 0x3A2A,\n      0, 0xC17A, 0xC17B, 0x3057, 0x404E, 0xC17C, 0xC17D,      0,\n      0,      0,      0,      0, 0x5A66, 0xC17E, 0xC221, 0x4031,\n 0x3147, 0xC222, 0xC223, 0xC224, 0xC225, 0x3D55, 0xC226, 0x4B66,\n 0x3A72, 0xC227, 0xC228, 0xC229, 0xC22A, 0x3E3C, 0xC22B, 0x4027,\n 0xC22C, 0xC22D,      0, 0xC22E, 0x5A65, 0x5A63, 0x5A64, 0xC230,\n      0, 0xC22F,      0, 0xF442, 0x436B,      0,      0, 0x5B26,\n};\nconst unsigned short utf8_to_euc_E699[] = {\n 0xC231, 0x5A6A, 0x3B7E, 0x3938, 0x5A68, 0xC232, 0xC233,      0,\n      0, 0x5A69, 0xC234, 0x3F38, 0xC235,      0, 0xC237, 0x5A67,\n      0, 0xC236, 0x3B2F,      0,      0,      0,      0, 0xC238,\n 0xC239, 0xC23A,      0, 0xC23B, 0xC23C, 0x5A6C, 0x5A6B, 0x5A70,\n 0xC23D, 0xC23E, 0x5A71,      0, 0x5A6D, 0xF443, 0x3322, 0x5A6E,\n 0x5A6F, 0x4855, 0xC240, 0xC241, 0xC242,      0, 0x4961, 0x374A,\n 0x5A72,      0,      0, 0xC244, 0x4032, 0xC245, 0x3E3D, 0xC247,\n 0xC248, 0xC249, 0x4352, 0xC24A, 0xC24C,      0, 0xC243, 0xC246,\n};\nconst unsigned short utf8_to_euc_E69A[] = {\n 0xC24B, 0x3647,      0, 0x5A73, 0x5A77,      0,      0, 0x324B,\n 0x5A74, 0x5A76,      0, 0xC24D, 0xC24E, 0xC24F, 0x5A75,      0,\n 0xC250, 0x3D6B, 0xC251,      0,      0,      0, 0x4348, 0x3045,\n 0x5A78, 0xC252, 0xC253, 0xC254, 0xC255, 0x5A79,      0, 0xC256,\n 0xC257,      0, 0x442A,      0, 0xC258,      0, 0x4E71,      0,\n      0,      0,      0, 0x3B43,      0, 0xC259, 0x4A6B,      0,\n      0, 0xC25A, 0xC25B,      0, 0x4B3D, 0xC25C,      0,      0,\n 0x5B22, 0x5A7B,      0, 0xC25D, 0x5A7E,      0, 0x5A7D, 0xC25E,\n};\nconst unsigned short utf8_to_euc_E69B[] = {\n 0xC25F, 0x5A7A, 0xC260, 0xC261, 0x5B21,      0,      0, 0x465E,\n 0xC262, 0x5A7C,      0,      0, 0xC263,      0, 0xC264, 0xC265,\n      0,      0,      0,      0, 0xC266,      0, 0x5B23,      0,\n      0, 0x3D6C, 0x5B24, 0xC267, 0x4D4B, 0x4778,      0, 0xC268,\n 0x5B25,      0,      0,      0,      0,      0, 0x5B27,      0,\n 0xC269, 0x5B28,      0, 0xC26A, 0xC26B,      0, 0xC26C,      0,\n 0x5B29,      0, 0x364A, 0x3148, 0x3939, 0x5B2A,      0, 0x5B2B,\n 0x3D71, 0x4162, 0xC26D, 0xC23F, 0x5258, 0x413E, 0x413D, 0x4258,\n};\nconst unsigned short utf8_to_euc_E69C[] = {\n 0x3A47,      0,      0, 0x5072,      0, 0xC26E,      0, 0xC26F,\n 0x376E, 0x4D2D,      0, 0x4A7E,      0, 0x497E, 0xC270, 0x5B2C,\n      0,      0,      0, 0xC271, 0x3A73, 0x443F, 0x5B2D, 0x4F2F,\n      0, 0xC272,      0, 0x4B3E, 0xC273, 0x442B, 0x5B2E, 0x347C,\n 0xC274,      0, 0xC275,      0,      0,      0, 0x5B2F, 0x5B30,\n 0x4C5A,      0, 0x4C24, 0x4B76, 0x4B5C, 0x3B25, 0x5B32,      0,\n      0, 0x3C6B,      0, 0xC276, 0x4B51,      0, 0x5B34, 0x5B37,\n 0x5B36,      0, 0x3479,      0,      0, 0x3560, 0xC277, 0x5B33,\n};\nconst unsigned short utf8_to_euc_E69D[] = {\n      0, 0x5B35,      0,      0,      0, 0xC278, 0x5B38, 0xC279,\n 0xC27A, 0x3F79,      0,      0, 0xC27B,      0, 0x4D7B, 0x3049,\n 0x3A60, 0x423C,      0, 0x3C5D, 0xC27C, 0xC27D, 0x3E73,      0,\n      0, 0x5B3B,      0,      0, 0x454E, 0xC27E, 0x5B39, 0x422B,\n 0x5B3A, 0x3E72, 0x4C5D, 0x5B3C, 0x5B3D, 0x4D68, 0xC321,      0,\n      0,      0, 0x5B42,      0, 0xC322, 0x393A, 0xC323, 0x4755,\n 0x5B3F, 0x456C, 0x5A5E, 0x5A62, 0xC324, 0x354F, 0xC325, 0x4747,\n      0,      0,      0, 0xC326, 0x5B41,      0, 0x3E3E, 0x4844,\n};\nconst unsigned short utf8_to_euc_E69E[] = {\n      0, 0xC327,      0,      0, 0xC328, 0x5B47,      0, 0x487A,\n      0, 0x5B3E,      0, 0x5B44, 0x5B43,      0, 0xC329, 0xC32A,\n 0x404F, 0xC32B,      0, 0xC32C,      0, 0x4B6D, 0xC32D, 0x4E53,\n 0xC32E, 0xC32F, 0x4B67, 0xC330, 0x324C, 0x3B5E,      0,      0,\n 0x4F48, 0x5B46, 0x3F75,      0,      0,      0, 0x5B45,      0,\n      0, 0x5B40,      0,      0,      0,      0,      0, 0x384F,\n 0xC331, 0xC332, 0xC333, 0x5B4C, 0x5B4A, 0xC334, 0x324D, 0x5B48,\n 0x5B4E, 0x5B54,      0, 0xC335, 0xC336, 0xC337,      0,      0,\n};\nconst unsigned short utf8_to_euc_E69F[] = {\n 0xC339, 0x4248, 0xC33A, 0xC33B, 0x4A41, 0xC33C, 0x5B56,      0,\n 0xC33D, 0xC33E, 0x4922,      0,      0,      0, 0x5B55, 0x4770,\n 0x4B3F, 0x343B, 0xC33F, 0x4077, 0x3D40,      0,      0, 0xC340,\n 0x4453, 0xC341, 0x4D2E,      0, 0xC342, 0x5B51, 0x5B50,      0,\n      0, 0xC343, 0x5B52,      0, 0x5B4F,      0, 0xC344, 0x5B57,\n      0, 0x5B4D,      0,      0, 0x5B4B,      0, 0x5B53, 0x5B49,\n 0xC345, 0x436C, 0xC346, 0x4C78, 0x3C46, 0x3A74, 0xC347, 0xC348,\n      0, 0xC338,      0, 0x3A3A,      0,      0, 0x4B6F, 0x3341,\n};\nconst unsigned short utf8_to_euc_E6A0[] = {\n      0, 0xF446, 0x444E, 0x464A, 0x3149,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x4072, 0xC34A,      0, 0x4034, 0x372A,\n      0, 0xC34B,      0,      0,      0, 0xC34C, 0x5B59, 0xC34D,\n      0, 0x393B, 0x337C,      0,      0,      0,      0, 0xC34F,\n 0xC34E, 0x5B5B, 0x3374, 0x5B61, 0xC350, 0xC351,      0, 0xC352,\n 0xC353, 0xC354, 0x5B5E, 0xC355, 0x4073,      0,      0,      0,\n 0x334B, 0x3A2C,      0, 0xC356, 0x334A, 0x3A4F,      0, 0xC357,\n};\nconst unsigned short utf8_to_euc_E6A1[] = {\n 0x5B5C, 0x3765, 0x374B, 0x456D, 0xC358, 0xC359, 0x5B5A,      0,\n 0x3046,      0, 0xC35A,      0, 0xC35B, 0x5B5D, 0x5B5F,      0,\n 0x364D, 0x372C, 0xC349, 0x343C, 0x354B, 0xC35C,      0, 0xC35D,\n 0xC35E, 0x5B62,      0, 0xC35F, 0x3A79, 0x4B71,      0, 0x3B37,\n      0,      0,      0, 0x5B63,      0,      0,      0, 0x4930,\n      0,      0,      0, 0xC360,      0,      0, 0xC361, 0xC362,\n 0xC363, 0xC364, 0xC365,      0, 0x5B6F, 0xC366, 0x3233, 0x5B64,\n      0, 0xC367, 0xC368, 0xC369, 0xC36A,      0, 0x5B75, 0x5B65,\n};\nconst unsigned short utf8_to_euc_E6A2[] = {\n      0, 0x4E42, 0xC36B, 0x5B6C, 0xC36C, 0x475F, 0xC36D,      0,\n 0xC36E,      0,      0,      0,      0, 0x5B74,      0, 0x5B67,\n      0,      0,      0, 0x3034, 0x5B69,      0, 0xC36F, 0x393C,\n 0xC370,      0, 0xC371, 0x5B6B, 0xC372, 0x5B6A,      0, 0x5B66,\n 0x5B71, 0xC373, 0x3E3F, 0xC374,      0, 0xC375, 0x546D, 0x3868,\n 0x4D7C, 0xC376, 0xC377,      0,      0, 0x5B68, 0xC378, 0x4474,\n 0x3323, 0x3A2D, 0xC379, 0x5B60,      0, 0x5B70, 0x3361,      0,\n      0, 0x5B6E, 0x5B72, 0xC37A, 0x456E,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6A3[] = {\n      0,      0,      0,      0, 0x347E, 0xC37B, 0x5C32,      0,\n 0xC37C, 0x4C49, 0x5B77, 0x347D, 0xC37D, 0x5B7E,      0, 0xC37E,\n 0xC421, 0xC422, 0x4B40, 0xC423, 0x5C21, 0x5C23, 0xC424, 0x5C27,\n 0x5B79, 0xC425, 0x432A,      0, 0xC426, 0xC427,      0, 0x456F,\n 0x5C2B, 0x5B7C,      0, 0x5C28,      0, 0xC428,      0, 0x5C22,\n 0xC429,      0, 0xC42A, 0xC42B, 0xC42C, 0xC42D, 0x3F39, 0x5C2C,\n 0xC42E, 0xC42F, 0x4033,      0,      0, 0xC430, 0xC431,      0,\n      0, 0x5C2A, 0x343D, 0xC432, 0xC433, 0xC434,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6A4[] = {\n 0x4F50, 0x5B76,      0,      0, 0x5C26, 0x3058, 0xC435,      0,\n 0x5B78, 0xC436, 0xC437, 0x4C3A, 0x5B7D, 0x3F22, 0x4447, 0x5B73,\n 0xC438, 0xC439, 0x5C25, 0xC43A,      0,      0, 0xC43B, 0xC43C,\n      0, 0x3F7A, 0x5C2F, 0x3371, 0x3821,      0,      0,      0,\n      0, 0x5C31, 0x5B7A, 0x5C30,      0, 0x5C29, 0x5B7B,      0,\n 0x5C2D,      0, 0x5C2E,      0,      0,      0,      0,      0,\n 0x5C3F, 0xC43D,      0, 0xC43E, 0x464E, 0xC43F, 0x5C24,      0,\n 0xC440, 0x5C3B,      0, 0xC441,      0, 0x5C3D,      0, 0x4458,\n};\nconst unsigned short utf8_to_euc_E6A5[] = {\n      0,      0, 0xC442,      0,      0, 0xC443,      0,      0,\n      0, 0xC444, 0x4D4C,      0,      0,      0, 0xC445,      0,\n      0,      0,      0, 0x4976, 0x5C38, 0x424A,      0, 0xC446,\n      0, 0x5C3E, 0x413F, 0xC447, 0x5C35, 0x5C42, 0x5C41,      0,\n 0x466F, 0x5C40, 0x466A, 0xC448, 0xC449, 0xC44A, 0xC44B,      0,\n 0xC44C, 0xC44D, 0x5C44, 0x5C37, 0xC44E, 0x3648, 0x5C3A, 0x3D5D,\n 0xC44F, 0xC450, 0xC451, 0x4760, 0x5C3C, 0x364B,      0, 0x5C34,\n 0x5C36, 0x5C33, 0xC452, 0xC453, 0x4F30, 0x335A, 0x5C39, 0xC454,\n};\nconst unsigned short utf8_to_euc_E6A6[] = {\n 0xC455, 0x5C43, 0x3335,      0,      0,      0,      0,      0,\n      0,      0, 0x3A67,      0,      0, 0xC456, 0x315D,      0,\n      0, 0x5C54, 0xC457,      0, 0x4F31, 0x5C57, 0xC458,      0,\n 0xC459,      0,      0, 0x3F3A, 0x5C56,      0,      0,      0,\n 0x5C55, 0xC45A,      0,      0,      0, 0xC45B, 0xC45C, 0x5C52,\n 0xC45D,      0,      0, 0xC45E,      0, 0xC45F, 0x5C46, 0xC460,\n      0, 0x5C63, 0x5C45,      0, 0x5C58,      0,      0, 0xC461,\n 0xC462,      0, 0xC463, 0x5C50, 0xC464,      0, 0x5C4B, 0x5C48,\n};\nconst unsigned short utf8_to_euc_E6A7[] = {\n      0, 0x5C49,      0, 0x5C51,      0, 0xC465,      0, 0x7422,\n 0xC466,      0, 0x5C4E, 0x393D, 0x4448, 0x4164, 0x5C4C,      0,\n 0x5C47, 0xC467,      0, 0x5C4A,      0,      0, 0xC468, 0xC469,\n 0x4D4D, 0x4B6A,      0,      0,      0, 0x5C4F, 0x5C59,      0,\n      0,      0, 0xC46A,      0,      0, 0xC46B,      0, 0x5C61,\n 0x5C5A,      0,      0, 0x5C67,      0, 0x5C65, 0xC46C, 0xC46D,\n      0, 0xC46E, 0x5C60, 0xC46F,      0, 0xC470,      0,      0,\n      0, 0x5C5F,      0, 0x4450,      0, 0x4165, 0xC471, 0x5C5D,\n};\nconst unsigned short utf8_to_euc_E6A8[] = {\n 0xC472, 0xC473, 0x5C5B, 0xC474,      0, 0x5C62,      0,      0,\n      0,      0, 0x5C68, 0x4875, 0x5C6E,      0,      0, 0xC475,\n      0, 0xC476, 0x5C69, 0x5C6C, 0x5C66, 0xC477,      0, 0x4374,\n      0, 0x4938, 0xC478, 0x5C5C,      0, 0xC479, 0x5C64, 0x3E40,\n 0xC47A, 0x4C4F, 0x5C78, 0x5C6B, 0xC47B,      0,      0,      0,\n 0xC47C, 0x3822, 0x3223, 0x335F,      0,      0, 0x5C53,      0,\n 0xC47D,      0, 0xC47E,      0, 0xC521, 0x3E41, 0x5C70, 0xC522,\n 0x5C77, 0x3C79, 0x3372, 0xC523,      0, 0x432E, 0xC524, 0xC525,\n};\nconst unsigned short utf8_to_euc_E6A9[] = {\n      0,      0,      0,      0, 0x5C6D, 0xC526, 0xC527, 0x5C72,\n 0x5C76, 0xC528, 0xC529, 0x3636,      0,      0, 0xC52A,      0,\n 0xC52B, 0xC52C, 0xC52D,      0,      0, 0xC52E, 0xC52F,      0,\n 0x354C, 0x5C74,      0, 0xC530,      0,      0,      0, 0x3521,\n      0, 0x464B, 0x5C73,      0, 0xC531,      0, 0x5C75, 0xC532,\n      0,      0, 0xC533, 0xF449,      0,      0,      0,      0,\n      0, 0xC534, 0x5C6F, 0xC535,      0,      0,      0,      0,\n 0x5C71,      0,      0,      0,      0,      0, 0xC536, 0x3360,\n};\nconst unsigned short utf8_to_euc_E6AA[] = {\n 0x4349, 0xC537,      0, 0xC538, 0x5C7C,      0, 0xC539, 0xC53A,\n      0, 0xC53B,      0, 0xC53C,      0, 0x5C7A, 0x3869,      0,\n 0x5C79, 0xC53D,      0,      0,      0,      0,      0, 0x5D21,\n      0,      0,      0, 0xC53E, 0x5B58, 0xC53F, 0xC540, 0xC541,\n 0x5C7B,      0, 0x5C7D, 0x5C7E,      0, 0xC542,      0,      0,\n      0,      0, 0x5D2C, 0xC543, 0x5D28,      0, 0x5B6D, 0xC544,\n 0xC545, 0xC546,      0, 0x5D27, 0xC547,      0,      0,      0,\n 0x5D26,      0,      0, 0x5D23,      0, 0xC548, 0xC549, 0xC54A,\n};\nconst unsigned short utf8_to_euc_E6AB[] = {\n      0, 0x5C6A, 0x5D25, 0x5D24,      0,      0, 0xC54B,      0,\n 0xC54D, 0xC54C,      0,      0, 0xC54E,      0,      0,      0,\n 0xC54F, 0x5D2A,      0, 0x4F26, 0xC550, 0xC551, 0xC552,      0,\n      0,      0, 0x5D2D, 0x367B, 0xC553, 0xC554, 0x5D29, 0x5D2B,\n      0,      0, 0xF44A,      0, 0xC555,      0,      0, 0xC556,\n 0x4827,      0, 0x5D2E,      0, 0xC557,      0,      0,      0,\n 0xC558, 0xC559, 0xC55A,      0,      0,      0,      0,      0,\n      0,      0, 0x5D32, 0x5D2F, 0xC55B, 0xC55C,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6AC[] = {\n      0,      0, 0xC55D, 0xC55E, 0x4D73, 0x5D30, 0xC55F, 0xC560,\n      0, 0xC561, 0x5C5E,      0,      0,      0,      0, 0xC562,\n 0xC563, 0xC564, 0x5D33,      0,      0,      0, 0x5D34, 0xC565,\n      0,      0,      0, 0xC566,      0, 0x3135, 0xC567, 0x5D36,\n 0x3767, 0x3C21,      0, 0x3655, 0xC568,      0,      0, 0x3224,\n 0xC569,      0,      0, 0xC56A, 0xC56B,      0,      0, 0xC56C,\n      0,      0, 0x4D5F,      0,      0, 0xC56D, 0xC56E, 0x5D38,\n 0x5D37, 0x5D3A, 0x353D, 0xC56F,      0, 0x3656, 0x343E, 0xC570,\n};\nconst unsigned short utf8_to_euc_E6AD[] = {\n      0,      0,      0, 0x5D3D,      0,      0, 0xC571, 0x5D3C,\n      0, 0x5D3E, 0xC572,      0, 0x324E, 0xC573, 0x4337,      0,\n 0x5D3F,      0, 0xC574, 0x343F, 0x5D41,      0, 0xC575,      0,\n 0xC576, 0x5D40,      0, 0x5D42,      0, 0xC577,      0, 0x5D43,\n 0xC578, 0x5D44, 0x3B5F, 0x4035, 0x3A21,      0, 0x4970, 0xC579,\n      0, 0x4A62, 0x4F44, 0xC57A,      0,      0, 0xC57B, 0x3B75,\n 0xC57C,      0,      0, 0x3A50, 0x4E72, 0xC57D,      0,      0,\n 0x5D45, 0x5D46,      0, 0x3B60,      0, 0xC57E, 0xC621, 0x5D47,\n};\nconst unsigned short utf8_to_euc_E6AE[] = {\n 0x5D48,      0, 0xC622, 0x5D4A, 0x5D49, 0xC623, 0x4B58,      0,\n      0, 0x3D5E, 0x3C6C, 0x3B44,      0, 0x5D4B,      0,      0,\n      0,      0,      0,      0,      0, 0x5D4D, 0x3F23, 0xC624,\n 0x5D4C,      0,      0, 0xC625,      0,      0, 0x5D4E, 0xC626,\n 0xC627,      0, 0xC628, 0xC629, 0x5D4F,      0,      0,      0,\n 0xC62A, 0xC62B, 0x5D50, 0x5D51, 0xC62C, 0xC62D, 0xC62E, 0x5D52,\n 0xC62F, 0x5D54, 0x5D53, 0x5D55, 0x3225, 0x434A,      0, 0x5D56,\n 0xC630, 0xC631, 0x3B26, 0x334C, 0x5D57, 0xC632, 0xC633, 0x4542,\n};\nconst unsigned short utf8_to_euc_E6AF[] = {\n 0x544C,      0,      0, 0xC634, 0xC635, 0x3523, 0x5D58,      0,\n      0, 0xC636,      0, 0x5D59, 0xC637, 0x4A6C, 0x4B68,      0,\n      0,      0, 0x4647, 0x5D5A, 0x4866,      0, 0xC638,      0,\n 0x487B,      0, 0xC639, 0x4C53,      0,      0,      0, 0x5D5B,\n      0, 0xC63A,      0, 0xC63B,      0,      0, 0xC63C, 0xC63D,\n      0,      0,      0, 0x5D5D, 0x5D5C,      0, 0xC63E, 0x5D5F,\n      0, 0xC63F,      0, 0x5D5E,      0,      0,      0, 0xC640,\n      0, 0xC641,      0,      0,      0,      0,      0, 0xC642,\n};\nconst unsigned short utf8_to_euc_E6B0[] = {\n      0,      0, 0xC643,      0, 0xC644, 0xC645,      0,      0,\n 0x5D61, 0xC646,      0,      0,      0, 0xC647, 0xC648, 0x3B61,\n 0xC649, 0x4C31, 0xC64A, 0x5D62, 0x5D63,      0,      0, 0x3524,\n      0, 0xC64B,      0, 0x5D64,      0,      0,      0, 0xC64C,\n      0,      0,      0, 0x5D66, 0x5D65,      0, 0xC64D, 0xC64E,\n 0xC64F,      0,      0,      0, 0xC650,      0, 0xC651,      0,\n      0,      0,      0, 0xC652, 0x3F65, 0xC653, 0xC654, 0x4939,\n 0x314A,      0, 0xC655, 0xC656,      0,      0, 0x4845, 0xC657,\n};\nconst unsigned short utf8_to_euc_E6B1[] = {\n 0x4475, 0x3D41, 0x3561,      0,      0,      0,      0,      0,\n      0,      0, 0xC658, 0xC659,      0, 0xC65A, 0x4846, 0xC65B,\n 0x3C2E,      0, 0xC65C,      0, 0xC65D, 0x5D68,      0, 0x3440,\n      0, 0xC65E, 0x3178, 0xC65F, 0xC660, 0x4672, 0x5D67, 0x393E,\n 0x4353,      0, 0x5D69,      0,      0,      0,      0, 0xC736,\n 0x5D71,      0, 0x5D6A, 0xC661,      0, 0xC662,      0, 0xC663,\n 0x4241,      0, 0x3562, 0x5D72, 0xC664,      0, 0xC665,      0,\n 0xC666, 0xC667, 0x3768, 0xC668,      0, 0x3525, 0x5D70,      0,\n};\nconst unsigned short utf8_to_euc_E6B2[] = {\n      0, 0x5D6E, 0x5D6B, 0x4D60,      0, 0xC669, 0xC66A, 0xC66B,\n 0x4440, 0xC66C,      0,      0, 0x4659, 0x5D6C,      0,      0,\n 0x5D74,      0, 0x5D73, 0x3723, 0xC66D, 0xC66E, 0x322D, 0xC66F,\n 0xC670, 0x3A3B, 0x5D6D, 0x5D6F, 0xC671,      0,      0, 0xC672,\n      0, 0x4B57, 0x4274,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x4B77,      0,      0, 0x5D7C,      0,\n 0xC673, 0x5D7D, 0xC674, 0x324F, 0xC675,      0,      0,      0,\n 0x4A28, 0x4C7D, 0x5E21, 0x3C23, 0x3E42, 0x5D78, 0x5D7E, 0x3168,\n};\nconst unsigned short utf8_to_euc_E6B3[] = {\n      0, 0x3637, 0xC676,      0, 0x5D75, 0x5D7A, 0xC677,      0,\n      0, 0x4074, 0x4771,      0, 0x4867, 0xC678,      0, 0xC679,\n 0xC67A, 0xC67B, 0xC67C, 0x5D77, 0xC67D, 0x4B21, 0xC67E, 0x5D79,\n      0, 0x5E24, 0xC721, 0x5E22, 0xC722, 0x5D7B,      0,      0,\n 0xC723, 0x4B22, 0x4748, 0x3563,      0, 0x4525,      0, 0xC724,\n 0x436D, 0xC725, 0x5E25, 0xC726, 0xC727,      0, 0xC728, 0x5E23,\n 0x4259, 0x5D76, 0xC729, 0x314B, 0xC72A,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6B4[] = {\n      0,      0,      0,      0, 0xC72B,      0,      0, 0xC72C,\n      0,      0, 0xC72D, 0x4D4E, 0x5E30,      0, 0xC72E, 0xC72F,\n      0, 0xC730, 0x5E2F, 0xC731,      0,      0,      0, 0x4076,\n      0, 0x5E2C, 0xC732, 0x4D6C,      0,      0, 0x4636, 0x5E26,\n      0,      0,      0,      0,      0, 0x4445, 0xC733, 0xC734,\n 0xC735, 0x314C, 0x393F, 0x5E29,      0,      0, 0xC737, 0xC738,\n      0, 0xC739, 0x3D27, 0x5E2E,      0, 0x5E2D, 0x5E28,      0,\n 0x5E2B, 0xC73A,      0, 0x3368, 0xC73B, 0x5E2A, 0x4749, 0xC73C,\n};\nconst unsigned short utf8_to_euc_E6B5[] = {\n      0, 0x4E2E,      0,      0, 0x3E74, 0x4075,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xC73D,\n      0, 0x5E36, 0x5E34,      0, 0x494D,      0, 0xC73E, 0xC73F,\n      0, 0xC740,      0, 0x5E31, 0x5E33, 0xC741, 0x313A, 0xC742,\n      0, 0x3940, 0x4F32,      0, 0x333D,      0, 0x4962, 0xC743,\n 0xC744,      0,      0,      0, 0x4D61,      0,      0, 0x3324,\n 0x3F3B, 0x5E35,      0,      0, 0xC745,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6B6[] = {\n      0,      0, 0xC746,      0,      0, 0x5E3A,      0, 0xC747,\n 0x3E43,      0,      0,      0, 0x4D30,      0, 0x5E37,      0,\n      0, 0xC748, 0xC749, 0x5E32, 0xC74A, 0x5E38, 0xC74B, 0xC74C,\n 0xC74D, 0x4E5E,      0, 0x4573, 0x4642,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xC74E,      0, 0xC74F,      0,      0, 0x3336,\n      0,      0, 0x3155,      0, 0xC750, 0x5E3E,      0, 0xC751,\n 0x5E41, 0xC752,      0,      0, 0x4E43, 0xC753,      0, 0xC754,\n};\nconst unsigned short utf8_to_euc_E6B7[] = {\n 0x4D64,      0,      0,      0, 0xC755, 0x5E48, 0x5E42, 0x5E3F,\n 0xC756,      0, 0xC757, 0x4E54, 0x5E45,      0, 0xC758, 0xC759,\n      0, 0x3D4A, 0x5E47,      0,      0, 0x5E4C, 0xC75A,      0,\n 0x4571, 0x5E4A,      0, 0xC75B,      0, 0xC75C, 0x5E44, 0xC75D,\n 0xC75E, 0x4338, 0xC75F,      0, 0x5E4B, 0xC760, 0x5E40,      0,\n 0x5E46, 0xC761, 0x5E4D, 0x307C, 0x5E43,      0, 0x5E4E, 0xC762,\n 0xC763, 0x3F3C, 0xF44C, 0x3D5F, 0xC764, 0x4A25, 0xC765, 0x3A2E,\n 0xF44B, 0x5E3B, 0x5E49, 0x453A, 0xC766,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6B8[] = {\n 0xC767,      0,      0,      0, 0xC768, 0x4036,      0, 0x3369,\n 0x3A51, 0x3E44, 0x5E3D, 0x3D42,      0,      0,      0,      0,\n      0,      0,      0, 0x374C,      0, 0x5E3C,      0,      0,\n      0, 0x5E52, 0x3D6D, 0x383A,      0, 0x5E61, 0xC769, 0x5E5B,\n 0x3574, 0x454F, 0xC76A, 0x5E56, 0x5E5F, 0x302F, 0x3132, 0xC76B,\n      0, 0x3239,      0, 0x5E58, 0x422C, 0x5E4F, 0x5E51, 0x3941,\n      0,      0, 0xC76C,      0,      0,      0, 0xC76D,      0,\n 0x5E62, 0xC76E, 0x5E5D, 0xC76F, 0xC770,      0, 0x5E55,      0,\n};\nconst unsigned short utf8_to_euc_E6B9[] = {\n      0,      0,      0, 0x5E5C, 0xC771, 0xC772,      0,      0,\n 0xC773, 0xC774, 0x4C2B, 0xC775,      0, 0x5E5A, 0x5E5E, 0xC776,\n      0, 0xC777, 0xC778, 0xC779, 0xC77A,      0, 0x3850, 0xC77B,\n 0x3E45,      0,      0, 0x4339, 0xC77C, 0xC77D, 0xC77E, 0x5E54,\n      0,      0, 0xC821, 0xC822,      0,      0,      0, 0x4D2F,\n 0xC823,      0,      0, 0x5E57,      0,      0, 0x5E50, 0x4572,\n      0,      0, 0x5E53, 0xC824,      0,      0, 0x5E59,      0,\n      0,      0,      0, 0xC825,      0, 0xC826, 0x4F51, 0x3C3E,\n};\nconst unsigned short utf8_to_euc_E6BA[] = {\n 0x4B7E,      0, 0x5E63,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x482E, 0xC827,      0, 0x5E6F,\n 0x383B,      0,      0, 0xC828,      0,      0, 0x3D60,      0,\n 0x5E65, 0xC829,      0,      0, 0x4E2F, 0x3942,      0, 0x5E72,\n 0xC82A,      0, 0x306E,      0,      0, 0x5E70,      0, 0xC82B,\n      0,      0, 0x5E64,      0,      0, 0xC82C, 0xC82D, 0x5E6A,\n      0, 0xC82E, 0x5E6C, 0xC82F,      0,      0, 0x4D4F, 0x5E67,\n      0,      0, 0x452E, 0xC830,      0, 0x5E69,      0, 0xC831,\n};\nconst unsigned short utf8_to_euc_E6BB[] = {\n 0xC832, 0xC833, 0x5E71, 0xC834, 0x5E6B, 0x4C47,      0, 0xC835,\n 0xC836, 0x5E66, 0xC837, 0x3C22, 0x5E7E, 0xC838, 0xC839, 0xC83A,\n      0, 0x336A,      0, 0x5E68, 0x5E6D, 0x5E6E,      0,      0,\n      0,      0,      0,      0,      0, 0x426C, 0x425A,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xC83B, 0x5E76, 0xC83C, 0xC83D, 0x5E7C,\n      0,      0, 0x5E7A,      0, 0x4529,      0,      0, 0x5F23,\n 0x5E77, 0xC83E,      0, 0xC83F,      0, 0xC840, 0x5E78, 0x5E60,\n};\nconst unsigned short utf8_to_euc_E6BC[] = {\n      0, 0x3579, 0x493A,      0, 0xC841,      0, 0x3C3F,      0,\n 0xC842, 0x3977, 0xC843,      0, 0xC844, 0xC845,      0, 0x4F33,\n      0, 0x5E74,      0, 0x5F22, 0x3169, 0x4166, 0xC846,      0,\n 0xC847,      0, 0xC848, 0xC849,      0,      0,      0,      0,\n 0x4779,      0, 0x3441, 0x4E7A,      0,      0, 0xC84A,      0,\n      0, 0xC84B, 0xC84C, 0x4C21, 0x4452, 0xC853,      0, 0xC84D,\n 0xC84E, 0x5E7B, 0x5E7D, 0xC84F,      0,      0, 0xC850,      0,\n 0x4132,      0,      0, 0xC851, 0xC852,      0, 0x5F21, 0x5E79,\n};\nconst unsigned short utf8_to_euc_E6BD[] = {\n      0, 0x5E73,      0,      0,      0, 0x3443,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xC854,\n      0, 0xC855, 0xC856, 0xC857, 0x3769,      0,      0, 0xC858,\n 0x5F2F, 0xC859, 0xC85A, 0x5F2A, 0x4078, 0xC85B, 0xC85C, 0x3363,\n      0, 0xC85D, 0xC85E,      0, 0x3D61,      0, 0x5F33,      0,\n 0xC85F,      0,      0,      0, 0xC860, 0x5F2C, 0x442C, 0x5F29,\n 0x4459,      0,      0,      0, 0x5F4C,      0,      0,      0,\n 0x5F26,      0, 0x5F25,      0, 0x5F2E, 0xC861, 0xC862,      0,\n};\nconst unsigned short utf8_to_euc_E6BE[] = {\n 0x5F28, 0x5F27, 0x5F2D, 0xC863, 0x4021,      0, 0x5F24, 0xC864,\n 0xC865,      0,      0, 0xC866, 0xC867, 0xC868, 0x5F30,      0,\n 0xC869, 0x5F31, 0xC86A, 0xC86B, 0xC86C,      0, 0xC86D, 0x3442,\n      0,      0, 0xC86E,      0,      0,      0,      0, 0xC86F,\n 0xC870, 0x5F36,      0, 0x5F35, 0x5F37, 0xC871, 0xC872, 0xC873,\n 0xC874,      0, 0x5F3A,      0,      0,      0, 0xC875, 0xC876,\n 0xC877, 0x4543,      0, 0x5F34,      0, 0xC878, 0xC879,      0,\n      0, 0x5F38,      0,      0, 0xC87A,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E6BF[] = {\n 0x3763, 0x4279, 0x5F32, 0x473B,      0, 0xC87B, 0x5F39, 0xC87C,\n 0xC87D,      0, 0xC87E,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x5F3E, 0x5F3C,      0,      0,\n 0x5F3F,      0, 0xC921, 0x5F42,      0,      0, 0xC922, 0x5F3B,\n 0x396A, 0x4728,      0,      0, 0x5E39,      0,      0,      0,\n 0xC923, 0xC924,      0, 0x4D74, 0x5F3D,      0, 0x5F41, 0x4275,\n 0xC925, 0x5F40,      0, 0x5F2B,      0, 0xC926, 0x6F69,      0,\n      0, 0xC927, 0x5F45,      0, 0xC928, 0xC929, 0x5F49,      0,\n};\nconst unsigned short utf8_to_euc_E780[] = {\n 0xC92A, 0x5F47,      0,      0,      0, 0xC92B, 0xC92C, 0xC92D,\n      0, 0x5F43,      0, 0x5F44,      0, 0xC92E,      0, 0x5F48,\n      0, 0x5F46,      0,      0,      0, 0x494E,      0, 0xC92F,\n 0x5F4E,      0, 0x5F4B, 0x5F4A,      0, 0x5F4D, 0x4654, 0x5F4F,\n 0xC930,      0,      0, 0xC931,      0,      0, 0x4375, 0x426D,\n 0xF44D,      0,      0,      0, 0x4025,      0,      0, 0xC932,\n 0x5F50,      0, 0x5F52,      0, 0xC933,      0,      0, 0xC934,\n      0, 0xC935,      0,      0, 0xC936,      0, 0x5F51,      0,\n};\nconst unsigned short utf8_to_euc_E781[] = {\n      0,      0,      0, 0xC937, 0xC938,      0,      0,      0,\n 0xC939, 0xC93A, 0xC93B, 0xC93C, 0x5E75,      0, 0xC941,      0,\n      0, 0x5F53,      0,      0, 0xC93D, 0xC93E,      0,      0,\n 0x4667,      0,      0,      0,      0, 0xC93F, 0xC940,      0,\n      0,      0,      0, 0x5F54, 0xC942, 0xC943,      0,      0,\n      0,      0,      0, 0x3250, 0xC944,      0, 0xC945, 0x4574,\n 0x3325,      0,      0,      0,      0, 0xC946, 0xC947,      0,\n 0x3564,      0,      0,      0, 0x3C5E, 0x3A52, 0xC948,      0,\n};\nconst unsigned short utf8_to_euc_E782[] = {\n      0, 0xC949,      0,      0,      0, 0xC94A, 0xC94B,      0,\n      0, 0x4F27, 0x3F66,      0,      0,      0, 0x316A,      0,\n      0,      0, 0x5F56,      0, 0xC94C, 0xC94D, 0xC94E, 0xC94F,\n 0xC950, 0x5F55,      0, 0xC951,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xC952,      0,      0,      0,\n      0,      0,      0, 0xC953, 0x5F59, 0x433A, 0x5F5C, 0x5F57,\n 0xC954, 0xC955,      0, 0x5F5B, 0xC956,      0,      0, 0xC957,\n 0x5F5A, 0x4540, 0x3059, 0xF42E,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E783[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x4E75,      0, 0xC958, 0x5F5E,      0,      0,      0, 0x3128,\n      0, 0xC959,      0, 0xC95A, 0xC95B, 0xC95C, 0xC95D,      0,\n 0xC95E, 0x5F60,      0,      0, 0xC95F, 0x5F5F,      0, 0x5F5D,\n      0,      0,      0,      0, 0xC960,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x5F58,      0,      0,      0,      0,      0,      0,\n      0, 0x4B23, 0xC961,      0,      0, 0x5F62,      0,      0,\n};\nconst unsigned short utf8_to_euc_E784[] = {\n      0,      0,      0, 0xC962, 0xC963, 0xC964, 0xC965, 0xC966,\n      0, 0x5F61,      0, 0xC967, 0xC968,      0,      0, 0xC969,\n      0,      0,      0,      0, 0x316B,      0,      0,      0,\n      0, 0x5F64, 0x4A32,      0, 0x5F63,      0, 0xC96A,      0,\n 0xC96B, 0x4C35,      0,      0,      0,      0, 0x3E47,      0,\n      0,      0,      0, 0xC96C,      0, 0xC96D,      0, 0xC96E,\n 0xC96F, 0xC970,      0,      0,      0,      0, 0x4133,      0,\n 0xC971,      0,      0,      0, 0x3E46,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E785[] = {\n      0, 0xC972,      0,      0,      0, 0xC973, 0xC974, 0xC975,\n      0, 0x4E7B, 0xC976, 0xC977, 0x5F6A,      0, 0x4079,      0,\n 0xC978,      0, 0xC979,      0,      0, 0x5F66, 0x5F6B, 0xC97A,\n      0, 0x316C, 0xC97B,      0, 0xC97C,      0, 0xC97D,      0,\n 0xC97E,      0, 0x5F69,      0, 0x4761, 0x5F65, 0x5F68, 0x3E48,\n 0xCA21, 0x4851,      0,      0, 0x5F6C,      0, 0x3C51,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xCA22,      0,      0,      0, 0x407A,      0,      0,\n};\nconst unsigned short utf8_to_euc_E786[] = {\n 0xCA23,      0,      0,      0, 0x5F6F, 0xCA24,      0, 0xCA25,\n 0x5F67,      0, 0x3727,      0, 0xCA26,      0,      0, 0x5F6D,\n      0,      0, 0xCA27,      0, 0x4D50, 0x5F70,      0,      0,\n      0, 0x7426, 0xCA28, 0xCA29,      0,      0,      0, 0x3D4F,\n 0xCA2A,      0, 0xCA2B,      0,      0,      0,      0,      0,\n 0x5F71,      0,      0,      0, 0x5F72,      0,      0, 0xCA2C,\n 0xCA2D, 0x472E, 0xCA2E, 0xCA2F,      0,      0,      0,      0,\n      0, 0x5F74, 0xCA30,      0,      0,      0, 0x5F75, 0xCA31,\n};\nconst unsigned short utf8_to_euc_E787[] = {\n 0xCA32, 0xCA33,      0, 0x4733, 0xCA34,      0,      0,      0,\n 0x4575, 0x5F77,      0, 0xCA35, 0xCA36,      0, 0x5F79,      0,\n 0x4E55,      0, 0x5F76, 0xCA37, 0x5F78, 0x316D, 0xCA38, 0x5F73,\n      0, 0xCA39, 0xCA3A,      0, 0xCA3B,      0,      0, 0x535B,\n 0x5F7A,      0,      0,      0,      0, 0x4167, 0x3B38, 0x5F7C,\n      0,      0,      0,      0, 0x5F7B, 0x3F24, 0x5259,      0,\n      0,      0,      0,      0,      0, 0x5F7D,      0,      0,\n 0xCA3C, 0x6021,      0, 0x5F6E, 0x5F7E,      0, 0xCA3D, 0x6022,\n};\nconst unsigned short utf8_to_euc_E788[] = {\n 0xCA3E,      0,      0,      0,      0,      0, 0x477A, 0xCA3F,\n 0xCA40, 0xCA41,      0,      0,      0, 0x6023,      0,      0,\n 0x6024,      0,      0, 0xCA42,      0,      0,      0, 0xCA43,\n      0,      0, 0xCA44, 0x6025,      0, 0xCA45,      0, 0xCA46,\n      0,      0,      0,      0, 0xCA47,      0,      0,      0,\n 0x6026,      0, 0x445E, 0xCA48, 0x6028, 0x6027,      0, 0xCA49,\n 0x6029,      0, 0x602A,      0, 0xCA4A, 0x3C5F, 0x4963,      0,\n 0xCA4B, 0xCA4C, 0x4C6C, 0x602B, 0x602C, 0x4156, 0x3C24, 0x602D,\n};\nconst unsigned short utf8_to_euc_E789[] = {\n 0x602E, 0xCA4D, 0xCA4E, 0xCA4F,      0, 0xCA50, 0x602F, 0x4A52,\n 0x4847,      0,      0, 0x6030, 0x4757,      0, 0xCA51, 0xCA52,\n 0xCA53,      0, 0x442D, 0xCA54,      0, 0xCA55, 0xCA56,      0,\n 0x6031, 0x3267, 0xCA57, 0x356D, 0xCA58, 0x4C46, 0xCA59, 0x4C36,\n 0xCA5A, 0x3234, 0x4F34, 0xCA5B,      0,      0,      0, 0x4B52,\n 0xCA5C, 0x4A2A,      0, 0xCA5D,      0,      0, 0xCA5E, 0xCA5F,\n      0, 0xCA60, 0x4037,      0, 0x6032,      0,      0, 0xCA61,\n 0xCA62, 0x4643,      0, 0xCA63, 0xCA64, 0x3823, 0x6033, 0xCA65,\n};\nconst unsigned short utf8_to_euc_E78A[] = {\n 0x3A54, 0x6035, 0x6034,      0, 0xCA66,      0,      0, 0x6036,\n      0, 0xCA67,      0,      0,      0, 0xCA68, 0xCA69,      0,\n      0,      0, 0x6037, 0xCA6A,      0,      0, 0x6038,      0,\n      0,      0,      0, 0xCA6B,      0,      0,      0,      0,\n 0x353E,      0, 0x6039,      0,      0,      0,      0, 0x603A,\n 0xCA6C,      0,      0,      0, 0x3824, 0xCA6D, 0xCA6E, 0x4848,\n      0, 0xCA6F, 0x603C,      0, 0xCA70,      0, 0x3E75,      0,\n      0, 0x603B,      0,      0,      0,      0, 0xCA71,      0,\n};\nconst unsigned short utf8_to_euc_E78B[] = {\n      0, 0xCA72, 0x3638, 0x603D, 0x603F,      0, 0x603E, 0xCA73,\n      0, 0xCA74,      0,      0, 0xCA75,      0, 0x6040,      0,\n 0x3851,      0, 0x6041,      0,      0, 0xCA76, 0xCA77, 0x3669,\n 0xCA78, 0x4140,      0, 0x397D,      0,      0,      0, 0xCA79,\n 0x6043, 0x6044, 0x6042,      0,      0, 0xCA7A,      0,      0,\n      0, 0x3C6D,      0,      0, 0x4648, 0x3639,      0,      0,\n      0,      0,      0, 0xCA7B, 0xCA7C,      0,      0, 0x6046,\n 0x432C, 0x6045, 0xCA7D, 0xCA7E, 0x4F35, 0x4762, 0xCB21,      0,\n};\nconst unsigned short utf8_to_euc_E78C[] = {\n      0,      0, 0xCB22,      0, 0xCB23, 0xCB24,      0, 0xCB25,\n      0,      0, 0x6049, 0xCB26,      0, 0xCB27,      0,      0,\n      0,      0, 0xCB28, 0xCB29,      0,      0, 0x604B, 0x6048,\n 0xCB2A, 0xCB2B,      0, 0x4C54, 0x604A, 0x604C, 0xCB2C, 0x4E44,\n      0,      0, 0xCB2D,      0, 0xCB2E, 0x6050,      0, 0xCB2F,\n 0xCB30, 0x604F, 0x4376, 0x472D, 0xCB31,      0, 0x3825, 0x604E,\n      0, 0xCB32, 0xCB33,      0, 0x604D, 0xCB34, 0x4D31, 0x4D32,\n      0,      0, 0xCB35, 0xCB36,      0, 0xCB37, 0x6051, 0x316E,\n};\nconst unsigned short utf8_to_euc_E78D[] = {\n      0,      0,      0, 0xCB38, 0x3976, 0x3B62,      0,      0,\n      0,      0,      0,      0,      0, 0xCB39, 0x6052, 0x6053,\n 0xCB3A,      0, 0xCB3B,      0,      0,      0, 0xCB3C, 0x6055,\n 0xCB3D,      0,      0,      0,      0, 0xCB3E, 0xCB3F, 0xCB40,\n 0xCB41,      0,      0, 0x3D43,      0,      0, 0xCB42, 0xCB43,\n 0x6057, 0xCB44, 0x6056, 0xCB45, 0xCB46,      0, 0xCB47, 0xCB48,\n 0x6058, 0xCB49, 0x334D,      0,      0, 0x605A,      0, 0xCB4A,\n 0x6059, 0xCB4B, 0x605C, 0x605B, 0xCB4C,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E78E[] = {\n 0xCB4D, 0xCB4E,      0, 0xCB4F, 0x383C, 0xCB50, 0xCB51, 0x4E28,\n      0, 0x364C,      0, 0x3226,      0,      0, 0xCB52,      0,\n 0xCB53,      0,      0, 0xCB54,      0, 0xCB55, 0x366A, 0xCB56,\n 0xCB57,      0,      0,      0, 0xCB58,      0, 0xCB59, 0xCB5A,\n 0xCB5B,      0, 0xCB5C,      0,      0, 0xCB5D, 0xCB5E,      0,\n      0, 0x3461, 0xCB5F, 0xCB60,      0, 0xCB61,      0,      0,\n      0,      0, 0x4E68, 0x605E,      0, 0xCB62,      0, 0xCB63,\n      0, 0xCB64,      0, 0x6060, 0xCB65, 0xCB66,      0, 0xCB67,\n};\nconst unsigned short utf8_to_euc_E78F[] = {\n 0x6061,      0, 0x3251,      0,      0, 0xCB68, 0xCB69,      0,\n 0x605D, 0xCB6A, 0x3B39, 0xCB6B, 0xCB6C, 0x4441, 0x605F, 0xCB6D,\n      0,      0, 0xCB6E, 0xCB6F,      0,      0, 0xCB70,      0,\n      0, 0xCB71,      0,      0,      0, 0xCB72, 0x6064,      0,\n 0x3C6E, 0xCB73,      0, 0xCB74,      0, 0x6062, 0xCB75, 0xCB76,\n      0, 0xCB77, 0x373E,      0,      0, 0x4849, 0x6063,      0,\n      0, 0x607E,      0,      0, 0xCB78, 0xCB79,      0, 0xCB7A,\n 0x6069, 0xCB7B, 0xCB7C, 0xCB7D,      0, 0xCB7E, 0x383D, 0xCC21,\n};\nconst unsigned short utf8_to_euc_E790[] = {\n 0xCC22, 0xCC23,      0, 0x3565, 0xCC24, 0x6066, 0x4D7D, 0xCC25,\n      0, 0x4E30, 0xCC26,      0,      0,      0,      0,      0,\n      0, 0xCC27,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xCC28, 0xCC29,      0,      0,      0,      0,\n      0,      0, 0x4276,      0, 0xCC2A, 0x6068, 0xCC2B,      0,\n 0xCC2C, 0xCC2D, 0xCC2E, 0xCC2F, 0xCC30, 0xCC31, 0xCC32, 0xCC33,\n 0xCC34, 0xCC35, 0x606A, 0x4E56, 0x3657, 0x487C, 0x474A,      0,\n      0, 0xCC36, 0x606B,      0,      0,      0,      0, 0x606D,\n};\nconst unsigned short utf8_to_euc_E791[] = {\n 0xCC37, 0x6070,      0, 0xCC38, 0xCC39,      0, 0xCC3A, 0xCC3B,\n      0,      0,      0, 0xCC3C,      0, 0xCC3D,      0,      0,\n      0, 0xCC3E, 0xCC3F,      0,      0, 0x606C,      0, 0xCC40,\n      0, 0x606F, 0x386A, 0x314D, 0x6071, 0xCC41, 0x3F70, 0x606E,\n 0x4E5C,      0, 0xCC42, 0x6074, 0x7424,      0, 0xCC43, 0xCC44,\n 0xCC45, 0x6072, 0x6075, 0xCC46,      0, 0xCC47, 0xCC48, 0x6067,\n 0x6073, 0xCC49, 0xCC4A, 0x3A3C,      0,      0, 0x6076,      0,\n      0,      0,      0,      0,      0,      0, 0x6077,      0,\n};\nconst unsigned short utf8_to_euc_E792[] = {\n 0xCC4B, 0xCC4C,      0, 0x4D7E,      0, 0xCC4D, 0xCC4E, 0xCC4F,\n      0, 0xCC50,      0, 0x6078,      0,      0,      0, 0xCC51,\n 0xCC52, 0xCC53, 0xCC54,      0,      0,      0,      0,      0,\n 0xCC55, 0xCC56, 0xCC57,      0, 0xCC58,      0, 0x6079, 0xCC59,\n 0xCC5A, 0xCC5B, 0x6065, 0xCC5C,      0,      0, 0xCC5D, 0x607A,\n 0xCC5E, 0xCC5F, 0xCC60, 0xCC61,      0,      0, 0xCC62, 0xCC63,\n 0x3444, 0xCC64, 0xCC65,      0,      0, 0xCC66,      0,      0,\n      0, 0xCC67,      0, 0xCC68,      0, 0x3C25,      0, 0xCC69,\n};\nconst unsigned short utf8_to_euc_E793[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xCC6A, 0xCC6B, 0x607B,      0, 0xCC6C,      0,      0, 0x607C,\n 0xCC6D,      0,      0, 0xCC6E, 0x607D,      0,      0,      0,\n 0xCC6F,      0, 0xCC70, 0xCC71, 0x313B,      0, 0xCC72, 0xCC73,\n 0x6121,      0, 0x493B, 0x6122, 0xCC74,      0, 0x3424, 0x6123,\n 0xCC75, 0x6124, 0xCC76, 0xCC77,      0,      0, 0x6125, 0xCC78,\n 0x6127, 0x6128, 0x6126,      0, 0xCC79,      0, 0x4953, 0x612A,\n 0x6129,      0, 0xCC7A, 0xCC7B, 0xCC7C,      0,      0, 0xCC7D,\n};\nconst unsigned short utf8_to_euc_E794[] = {\n      0, 0xF450,      0, 0x612C, 0x612B, 0x612D, 0xCC7E,      0,\n      0,      0,      0,      0, 0x612E, 0x6130, 0x612F,      0,\n      0, 0x3979, 0xCD21, 0x6132,      0, 0x6131, 0xCD22, 0xCD23,\n 0x3445,      0, 0x3F53,      0, 0x453C,      0, 0x6133, 0x4038,\n 0xCD24, 0xCD25,      0, 0x3B3A, 0xCD26, 0x3179, 0x6134, 0xCD27,\n 0x4D51, 0xCD28, 0xCD29, 0x4A63, 0x6135,      0,      0, 0xCD2A,\n 0x4544, 0x4D33, 0x3943, 0x3F3D,      0,      0, 0xCD2B, 0x434B,\n 0x5234, 0xCD2C, 0x442E, 0x3268, 0x6136, 0xCD2D, 0xCD2E, 0xCD2F,\n};\nconst unsigned short utf8_to_euc_E795[] = {\n 0xCD30,      0,      0, 0xCD31, 0x6137,      0, 0x613C, 0xCD32,\n 0xCD33, 0x613A, 0x6139, 0x5A42, 0x3326, 0x6138, 0xCD34, 0x305A,\n 0xCD35, 0x482A, 0xCD36,      0, 0x484A,      0,      0, 0xCD37,\n      0, 0x4E31, 0x613D, 0x613B, 0x435C, 0x4026, 0xCD38, 0xCD39,\n 0x482B, 0xCD3A, 0x492D,      0, 0x613F, 0x4E2C, 0x374D, 0x6140,\n      0, 0x613E, 0x4856, 0x6141,      0, 0x6142,      0, 0xCD3B,\n 0x305B, 0xCD3C,      0, 0x3E76, 0x6147,      0, 0x6144, 0x466D,\n 0x6143, 0xCD3D, 0xCD3E, 0xCD3F, 0xCD40, 0xCD41, 0xCD42, 0x3526,\n};\nconst unsigned short utf8_to_euc_E796[] = {\n      0, 0xCD43, 0x614A,      0,      0, 0xCD44, 0x6145, 0x6146,\n      0, 0x6149, 0x6148, 0x4925,      0,      0, 0x4142, 0x4141,\n 0xCD45, 0x353F, 0xCD46, 0xCD47, 0x614B, 0xCD48,      0,      0,\n      0, 0xCD49, 0x614C,      0, 0xCD4A, 0x614D,      0,      0,\n      0,      0, 0xCD4B, 0x614F, 0xCD4C, 0x614E,      0,      0,\n      0,      0,      0, 0x3156,      0,      0,      0,      0,\n      0, 0x6157, 0x4868, 0x6151, 0xCD4D, 0x6153,      0,      0,\n 0x6155, 0x3F3E, 0xCD4E,      0, 0x6156, 0x6154, 0x3C40, 0xCD4F,\n};\nconst unsigned short utf8_to_euc_E797[] = {\n 0xCD50, 0xCD51, 0x6150, 0x6152, 0xCD52, 0x4942, 0xCD53, 0x3E49,\n      0,      0, 0x6159,      0, 0xCD54, 0x6158, 0xCD55, 0xCD56,\n      0,      0, 0x615A,      0, 0x3C26, 0x3A2F,      0, 0xCD57,\n 0x4577, 0x615B,      0, 0x444B, 0xCD58,      0, 0x615D, 0xCD59,\n 0xCD5A, 0xCD5B, 0x4E21, 0x615C, 0xCD5C,      0,      0, 0xCD5D,\n      0, 0x4169,      0,      0, 0xCD5E,      0, 0xCD5F, 0xCD60,\n 0x6162, 0xCD61, 0x6164, 0x6165, 0x4354,      0,      0,      0,\n      0, 0xCD62, 0x6163,      0, 0x6160,      0, 0x615E, 0x615F,\n};\nconst unsigned short utf8_to_euc_E798[] = {\n 0xCD63, 0x6161, 0xCD64, 0xCD65, 0xCD66,      0,      0, 0xCD67,\n 0xCD68, 0x6168, 0xCD69, 0x6166, 0xCD6A, 0x6167,      0, 0xCD6B,\n      0,      0, 0xCD6C, 0xCD6D,      0, 0xCD6E, 0xCD6F,      0,\n      0, 0xCD70,      0, 0xCD71, 0xCD72, 0xCD73, 0xCD74, 0x6169,\n 0x616B, 0x616C, 0x616D, 0xCD75, 0x616E, 0xCD76, 0xCD77, 0x616A,\n      0, 0xCD78,      0,      0,      0, 0xCD79,      0,      0,\n 0x6170,      0, 0xCD7A, 0xCD7B, 0x616F, 0xCD7C,      0,      0,\n 0xCD7D, 0xCD7E, 0xCE21, 0x6171, 0xCE22,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E799[] = {\n 0xCE24, 0xCE25, 0x4E45, 0xCE26, 0xCE27, 0xCE28, 0x6174, 0x6172,\n 0x6173, 0xCE29, 0xCE23, 0xCE2A, 0x3462,      0,      0,      0,\n      0,      0, 0x4C7E,      0,      0, 0xCE2B, 0x4A4A,      0,\n 0x6176, 0xCE2C,      0,      0, 0x6175,      0,      0, 0xCE2D,\n      0, 0x6177, 0x6178,      0, 0xCE2E, 0xCE2F,      0, 0x617C,\n 0x6179, 0x617A, 0x617B,      0, 0x617D, 0xCE30, 0xCE31, 0xCE32,\n 0x617E, 0xCE33, 0x6221,      0, 0xCE34,      0, 0x6222,      0,\n 0x6223,      0, 0x482F, 0x4550, 0x6224, 0x4772, 0x4934,      0,\n};\nconst unsigned short utf8_to_euc_E79A[] = {\n 0x6225, 0xCE35, 0xF451, 0x6226, 0x452A, 0xCE36, 0x3327, 0x3944,\n 0x6227,      0,      0, 0x6228, 0xCE37, 0xCE38, 0x6229,      0,\n 0x3B29,      0,      0, 0x622B,      0, 0xCE39, 0x622A,      0,\n      0, 0x622C, 0x622D, 0xCE3A, 0xCE3B, 0xCE3C, 0xF452, 0xCE3D,\n 0xCE3E,      0, 0xCE3F, 0xCE40, 0xCE41, 0xCE42, 0xCE43, 0xCE44,\n 0xCE45,      0, 0xCE46,      0,      0, 0xCE47, 0x4869,      0,\n 0x622E,      0,      0,      0, 0x622F,      0,      0, 0x7369,\n 0x6230, 0x6231, 0x6232,      0,      0, 0xCE48,      0, 0x3B2E,\n};\nconst unsigned short utf8_to_euc_E79B[] = {\n      0, 0xCE49, 0x6233, 0x4756,      0, 0xCE4A, 0x4B5F,      0,\n 0x314E, 0xCE4B, 0x3157, 0xCE4C, 0xCE4D, 0x6234, 0xCE4E,      0,\n      0,      0, 0x6236,      0, 0xCE4F,      0, 0x6235, 0x4570,\n      0, 0xCE50,      0, 0x4039, 0x5D39,      0, 0x6237, 0x4C41,\n 0xCE51, 0x6238,      0, 0x3446, 0x4857, 0x6239, 0xCE52, 0x623A,\n 0xCE53,      0, 0x623B,      0, 0xCE54,      0, 0x4C5C,      0,\n 0xCE55, 0xCE56, 0x4C55,      0, 0x443E,      0, 0xCE57,      0,\n 0x416A, 0xCE58,      0, 0x623D, 0xCE59,      0, 0x3D62,      0,\n};\nconst unsigned short utf8_to_euc_E79C[] = {\n 0xCE5A, 0x3E4A,      0,      0, 0x6240,      0, 0xCE5B, 0x623F,\n 0x623E, 0x487D, 0xCE5C, 0x3447, 0x3829,      0, 0xCE5D,      0,\n      0,      0, 0xCE5E,      0, 0xCE5F, 0xCE60,      0, 0xCE61,\n      0, 0xCE62, 0xCE63, 0x6246, 0xCE64,      0, 0x6243, 0x3F3F,\n 0x4C32,      0, 0xCE65,      0, 0x6242, 0x6244, 0x6245,      0,\n 0xCE66, 0x6241,      0,      0,      0, 0xCE67, 0xCE68, 0xCE69,\n      0,      0,      0,      0, 0xCE6A, 0xCE6B, 0xCE6C, 0x6247,\n 0x6248, 0xCE6D, 0x442F,      0, 0x3463, 0xCE6E, 0xCE6F,      0,\n};\nconst unsigned short utf8_to_euc_E79D[] = {\n 0x4365,      0, 0xCE70,      0,      0, 0xCE71, 0xCE72, 0x6249,\n      0,      0, 0xCE73,      0,      0, 0xCE74, 0xCE75, 0xCE76,\n      0,      0, 0xCE77,      0,      0,      0, 0xCE78, 0xCE79,\n      0,      0, 0x624A, 0x624D, 0xCE7A,      0, 0xCE7B, 0xCE7C,\n 0xCE7D, 0x3F67, 0xCE7E, 0x4644, 0xCF21, 0x624E, 0x4B53, 0xCF22,\n 0x624B,      0, 0xCF23, 0x624C, 0xCF24,      0,      0,      0,\n 0xCF25,      0, 0xCF26, 0xCF27, 0xCF28,      0,      0,      0,\n      0, 0x6251, 0xCF29,      0,      0, 0xCF2A, 0x6250, 0x624F,\n};\nconst unsigned short utf8_to_euc_E79E[] = {\n 0xCF2B,      0,      0,      0, 0xCF2C,      0,      0,      0,\n      0,      0,      0, 0x6253, 0xCF2D, 0xCF2E, 0x6252,      0,\n      0, 0x6254,      0,      0, 0xCF2F, 0xCF30, 0xCF31,      0,\n      0,      0, 0xCF32,      0,      0,      0, 0x6256, 0xCF33,\n 0x6255,      0, 0xCF34,      0,      0, 0x4A4D,      0, 0xCF35,\n      0,      0, 0xCF36,      0, 0x3D56, 0x4E46, 0xCF37, 0xCF38,\n 0x6257, 0xCF39,      0, 0x4637,      0, 0xCF3A, 0x6258,      0,\n      0, 0x6259,      0, 0x625D, 0x625B, 0x625C, 0xCF3B, 0x625A,\n};\nconst unsigned short utf8_to_euc_E79F[] = {\n      0,      0,      0, 0xCF3C,      0,      0,      0, 0x625E,\n      0, 0xCF3D,      0,      0,      0, 0x625F,      0,      0,\n      0, 0xCF3E, 0xCF3F,      0,      0, 0xCF40,      0, 0x6260,\n      0, 0xCF41, 0x6261, 0x4C37, 0x6262,      0, 0xCF42, 0xCF43,\n 0xCF44,      0, 0x4C70, 0x6263, 0xCF45, 0x434E, 0xCF46, 0x476A,\n      0, 0x366B, 0xCF47,      0, 0xCF48, 0x433B, 0x6264, 0x363A,\n 0xCF49, 0xCF4A,      0, 0x4050, 0xCF4B,      0,      0,      0,\n 0xCF4C,      0,      0, 0xCF4D, 0x6265,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E7A0[] = {\n      0,      0, 0x3A3D,      0,      0, 0xCF4E, 0xCF4F,      0,\n      0, 0xCF50,      0,      0, 0x6266, 0xCF51, 0xCF52,      0,\n      0, 0xCF53, 0x6267,      0, 0x3826, 0x3A55,      0,      0,\n      0,      0,      0,      0,      0, 0xCF54,      0,      0,\n 0x6269, 0xCF55, 0xCF56, 0xCF57,      0, 0x4556, 0x3A56, 0x354E,\n      0,      0,      0,      0,      0, 0xCF58, 0xCF59,      0,\n 0xCF5A,      0, 0x4B24,      0, 0x474B, 0xCF5B,      0, 0xCF5C,\n      0,      0, 0x4557,      0,      0,      0,      0, 0x395C,\n};\nconst unsigned short utf8_to_euc_E7A1[] = {\n      0,      0,      0, 0xCF5D, 0xCF5E, 0x626B,      0, 0xCF5F,\n 0xCF60,      0,      0,      0, 0xCF61,      0, 0xCF62,      0,\n      0,      0, 0xCF63,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xCF64, 0x3E4B, 0xCF65,      0,\n 0xCF66, 0xCF67,      0, 0xCF68, 0xCF69,      0,      0,      0,\n 0xCF6A,      0, 0xCF6B, 0x4E32, 0x3945,      0, 0xCF6C, 0x3827,\n      0,      0, 0x4823,      0, 0x626D,      0,      0,      0,\n      0,      0, 0xCF6D,      0, 0x626F,      0, 0xCF6E,      0,\n};\nconst unsigned short utf8_to_euc_E7A2[] = {\n      0, 0x386B,      0,      0,      0,      0, 0x626E, 0x4476,\n      0,      0, 0xCF6F,      0, 0x6271, 0x3337, 0x626C, 0xCF70,\n      0, 0x486A,      0, 0x3130, 0xCF71, 0x3A6C,      0, 0x4F52,\n 0xCF72,      0, 0x6270,      0,      0, 0xCF74, 0xCF75, 0xCF76,\n      0, 0xCF73,      0, 0x6272, 0xCF77,      0,      0, 0x4A4B,\n 0xCF78, 0x4059, 0x6274,      0, 0xCF79, 0xCF7A,      0, 0x6275,\n 0xCF7B, 0xCF7C, 0xCF7D, 0xCF7E,      0, 0x6273,      0,      0,\n      0,      0, 0x334E, 0xD021, 0x627B, 0xD022, 0x627A, 0xD023,\n};\nconst unsigned short utf8_to_euc_E7A3[] = {\n      0, 0x3C27,      0,      0,      0, 0x627C, 0x6277, 0xD024,\n 0xD025, 0xD026, 0x627D, 0x6278, 0xD027,      0, 0xD028,      0,\n 0x4858, 0x6276, 0xD029, 0xD02A, 0x6279, 0xD02B, 0xD02C,      0,\n      0,      0, 0x6322, 0xD02E,      0,      0,      0, 0xD02F,\n 0xD030, 0xD031,      0,      0, 0xD02D,      0, 0xD032, 0x6321,\n 0x4B61,      0, 0xD033,      0, 0x627E,      0,      0, 0x306B,\n      0,      0, 0xD034, 0xD035, 0x6324,      0, 0xD037, 0xD038,\n      0,      0, 0xD039, 0xD03A,      0, 0x6323,      0, 0xD03B,\n};\nconst unsigned short utf8_to_euc_E7A4[] = {\n 0xD036, 0x3E4C,      0,      0,      0,      0, 0xD03C, 0x6325,\n      0,      0,      0,      0, 0xD03D,      0, 0x4143,      0,\n 0xD03E, 0x6327, 0x6326,      0,      0,      0,      0,      0,\n      0, 0x6328, 0xD03F,      0, 0xD040,      0, 0xD041, 0xD042,\n 0xD043,      0,      0,      0,      0, 0xD044, 0x6268, 0xD045,\n      0, 0xD046, 0x626A, 0x632A, 0x6329, 0xD047,      0,      0,\n 0xF454, 0xD048,      0,      0, 0xD049, 0xD04A,      0,      0,\n      0,      0, 0x3C28, 0xD04B, 0x4E69, 0xD04C, 0x3C52, 0xD04D,\n};\nconst unsigned short utf8_to_euc_E7A5[] = {\n 0x632B, 0x3737,      0,      0, 0xD04E, 0xD04F, 0xD050, 0x3540,\n 0x3527, 0x3B63, 0xD051, 0xD052,      0,      0,      0, 0xD053,\n 0x4D34, 0xD054,      0, 0x6331, 0xD055, 0x6330, 0x4144, 0x632D,\n 0xD056,      0, 0x632F, 0xD057, 0xD058, 0x3D4B, 0x3F40, 0x632E,\n 0x632C,      0, 0x472A,      0,      0, 0x3E4D,      0, 0xD059,\n 0x493C, 0xD05A,      0, 0xD05B,      0, 0x3A57,      0,      0,\n      0,      0, 0xD05C,      0,      0,      0,      0, 0x4578,\n      0, 0xD05D, 0x6332, 0xD05E, 0xD05F,      0, 0xD060, 0x6333,\n};\nconst unsigned short utf8_to_euc_E7A6[] = {\n 0x6349, 0x3658,      0,      0, 0x4F3D, 0x4135,      0,      0,\n      0,      0, 0x6334, 0xD061, 0xD062, 0x3252, 0x4477, 0x4A21,\n      0, 0xD063,      0, 0xD064, 0xD065, 0xD066, 0xD067,      0,\n 0xD068,      0,      0, 0xD069, 0xD06A, 0x6335,      0,      0,\n      0, 0xD06B,      0,      0,      0,      0, 0x357A, 0x6336,\n 0xD06C, 0xD06D, 0x6338, 0xD06E,      0,      0, 0x6339, 0xD06F,\n 0x4729, 0xD070,      0, 0x633A, 0xD071,      0,      0,      0,\n 0xD072, 0x633B, 0x633C, 0xD073,      0, 0x3659, 0x3253, 0x4645,\n};\nconst unsigned short utf8_to_euc_E7A7[] = {\n 0x3D28, 0x3B64, 0xD074,      0, 0xD075,      0,      0, 0xD076,\n 0xD077, 0x633D, 0xD078, 0x3D29,      0,      0,      0, 0xD079,\n      0, 0x324A, 0x4943,      0, 0xD07A, 0x633E, 0xD07B,      0,\n 0x486B,      0, 0xD07C,      0,      0, 0xD07D, 0xD07E, 0x4145,\n 0xD121, 0x6341, 0xD122, 0x6342, 0x4769, 0xD123, 0x3F41, 0x633F,\n      0, 0x4361, 0xD124, 0xD125, 0x6340, 0xD126,      0,      0,\n 0x3E4E, 0xD127,      0,      0,      0,      0,      0,      0,\n 0xD128,      0,      0, 0x305C, 0xD129,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E7A8[] = {\n 0x3529,      0, 0xD12A, 0xD12B,      0,      0,      0, 0xD12C,\n 0x6343, 0xD12D, 0xD12E, 0x4478, 0xD12F, 0x6344, 0x4047,      0,\n      0, 0xD130,      0,      0, 0x4C2D, 0xD131,      0, 0x4923,\n 0x6345, 0x6346, 0x4355, 0xD132, 0x4E47,      0, 0xD133, 0x6348,\n 0x6347, 0xD134,      0,      0,      0,      0,      0, 0xD135,\n      0,      0,      0, 0xD136,      0, 0xD137, 0x3C6F, 0xD138,\n 0xD139, 0x634A, 0x3070,      0, 0xD13A, 0xD13B,      0, 0x634D,\n 0xD13C, 0xD13D, 0xD13E, 0x634B, 0x3254, 0x374E, 0x634C, 0x3946,\n};\nconst unsigned short utf8_to_euc_E7A9[] = {\n 0x3972,      0, 0x4A66, 0x634E, 0xD13F, 0xD140, 0x4B54, 0xD141,\n 0xD142, 0x6350,      0,      0, 0xD143, 0x4051, 0x314F, 0x323A,\n 0x302C,      0,      0,      0,      0, 0xD144, 0xD145, 0x634F,\n      0, 0xD146,      0,      0, 0xD147, 0xD148,      0, 0xD149,\n 0xD14A, 0x6351, 0x6352, 0x3E77,      0, 0xD14B,      0, 0xD14C,\n      0, 0x6353, 0xD14D, 0x334F,      0, 0xD14E,      0,      0,\n 0x6355,      0,      0,      0, 0x376A, 0xD14F, 0x3566,      0,\n 0xD150, 0x6356, 0x3675,      0,      0, 0x6357, 0xD151, 0x407C,\n};\nconst unsigned short utf8_to_euc_E7AA[] = {\n 0xD152, 0x464D, 0xD153, 0x4060, 0x3A75, 0xD154, 0xD155,      0,\n 0x6358,      0, 0xD156, 0xD157,      0,      0,      0,      0,\n 0xD158, 0xD159, 0x4362, 0x416B, 0xD15A, 0x635A, 0x635C, 0x6359,\n 0x635B,      0,      0,      0,      0,      0, 0xD15B, 0x3722,\n 0xD15C,      0,      0, 0xD15D,      0,      0,      0,      0,\n      0, 0x635D, 0x3726,      0, 0xD15E,      0, 0x3567, 0x4D52,\n 0x635F,      0,      0, 0xD15F,      0, 0xD160, 0x6360,      0,\n      0, 0xD161, 0x312E, 0xD162, 0xD163,      0,      0, 0x6363,\n};\nconst unsigned short utf8_to_euc_E7AB[] = {\n      0,      0,      0, 0x3376, 0x6362, 0x6361, 0xD164, 0x6365,\n 0x635E, 0xD165, 0x6366, 0x4E29, 0xD166, 0x6367, 0xD167, 0x6368,\n      0, 0xD168, 0x5474, 0x636A,      0, 0x6369,      0,      0,\n      0, 0x636B, 0x636C, 0xD169, 0x4E35, 0x636D,      0, 0x706F,\n 0x3E4F, 0x636E, 0x636F, 0x3D57,      0, 0x4638, 0x6370, 0xF459,\n 0xD16A, 0xD16B, 0x4328, 0xD16C, 0xD16D, 0x6371,      0, 0x433C,\n 0x6372, 0xD16E,      0,      0, 0xD16F,      0, 0x3625,      0,\n 0x513F, 0x435D, 0x3C33, 0xD170,      0, 0xD171, 0xD172, 0x3448,\n};\nconst unsigned short utf8_to_euc_E7AC[] = {\n      0,      0, 0x6373,      0, 0x6422,      0, 0x6376, 0xD173,\n 0x3568,      0, 0x6375, 0x6424,      0,      0,      0, 0x6374,\n      0, 0x3E50,      0,      0, 0xD174,      0,      0,      0,\n 0x6378, 0x6379,      0, 0x452B,      0,      0, 0x637A, 0xD175,\n 0x335E,      0,      0, 0xD176,      0, 0x3F5A, 0x4964, 0xD177,\n 0x637C, 0xD178, 0xD179, 0xD17A, 0x4268, 0xD17B, 0xD17C, 0xD17D,\n 0xD17E, 0xD221,      0, 0x6377, 0xD222, 0x637B, 0x637D,      0,\n      0, 0x3A7B,      0,      0,      0, 0xD223,      0, 0xD224,\n};\nconst unsigned short utf8_to_euc_E7AD[] = {\n 0xD225, 0xD226,      0,      0,      0, 0x6426, 0x492E, 0xD227,\n 0x4826, 0x4579,      0, 0x365A, 0x6425, 0x6423, 0xD228, 0x4835,\n 0x637E, 0x435E, 0x457B,      0, 0x457A, 0xD229, 0x3A76,      0,\n      0,      0,      0,      0,      0, 0x6438,      0,      0,\n 0xD22A,      0,      0,      0, 0xD22B, 0x6428, 0xD22C, 0x642A,\n      0, 0xD22D, 0xD22E,      0, 0x642D, 0xD22F, 0x642E, 0xD230,\n 0x642B, 0x642C, 0xD231, 0xD232, 0x6429, 0x6427,      0, 0xD233,\n      0,      0, 0x6421,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E7AE[] = {\n      0,      0,      0,      0, 0xD234,      0, 0x4A4F, 0x3255,\n      0, 0xD235,      0, 0x6435,      0, 0x6432, 0xD236, 0x6437,\n 0xD237, 0xD238, 0x6436,      0, 0x4773, 0x4C27, 0xD239, 0x3B3B,\n 0x6430, 0x6439, 0x6434, 0xD23A, 0x6433, 0x642F, 0xD23B, 0x6431,\n 0xD23C, 0x3449,      0,      0,      0, 0xD23D,      0,      0,\n      0,      0, 0x433D,      0, 0xD23E, 0x407D,      0, 0xD23F,\n 0xD240, 0x4822, 0xD241,      0, 0x643E, 0xD242, 0xD243,      0,\n 0x4824,      0, 0xD244, 0xD245, 0xD246, 0xD247,      0,      0,\n};\nconst unsigned short utf8_to_euc_E7AF[] = {\n 0x4061, 0x643B, 0xD248,      0, 0x484F, 0xD249, 0x643F, 0x4A53,\n 0xD24A, 0x435B, 0xD24B, 0x643A, 0x643C,      0,      0, 0x643D,\n      0,      0,      0,      0, 0xD24C,      0, 0xD24D, 0xD24E,\n      0, 0xD24F, 0xD250, 0xD251,      0, 0x6440,      0,      0,\n 0x3C44,      0,      0,      0, 0x4646, 0x6445, 0x6444,      0,\n 0xD252, 0x6441, 0xD253,      0,      0, 0x4F36,      0,      0,\n      0,      0, 0xD254, 0x644A, 0xD255, 0xD256, 0x644E, 0x644B,\n 0xD257, 0xD258, 0xD259,      0, 0xD25A,      0, 0xD25B,      0,\n};\nconst unsigned short utf8_to_euc_E7B0[] = {\n 0x6447, 0xD25C, 0xD25D, 0xD25E, 0xD25F,      0, 0xD260, 0x6448,\n      0, 0xD261,      0, 0xD262, 0xD263, 0x644D, 0xD264, 0xD265,\n      0, 0x6442, 0x5255, 0x6449, 0x6443,      0,      0, 0x644C,\n      0, 0xD266,      0, 0xD267,      0,      0,      0, 0x6452,\n 0xD268, 0x344A,      0, 0x644F,      0, 0xD269, 0xD26A, 0x6450,\n 0xD26B,      0, 0x6451, 0x6454, 0xD26C,      0,      0,      0,\n      0, 0xD26D,      0, 0xD26E, 0xD26F,      0, 0xD270, 0x6453,\n 0x4876, 0xD271, 0xD272,      0,      0, 0x6455, 0x4E7C, 0x4A6D,\n};\nconst unsigned short utf8_to_euc_E7B1[] = {\n 0x645A,      0,      0, 0x6457,      0,      0, 0xD273,      0,\n      0,      0, 0xD274,      0, 0x6456, 0x4052,      0, 0x6459,\n 0x645B, 0xD276, 0xD277, 0xD278, 0x6458, 0xD275, 0x645F,      0,\n 0x645C, 0xD279, 0xD27A, 0xD27B, 0xD27C, 0xD27D, 0xD27E, 0x645D,\n 0x6446, 0xD321,      0, 0xD322, 0x645E, 0x6460,      0, 0xD323,\n      0, 0xD324,      0,      0, 0x6461, 0xD325, 0xD326,      0,\n 0xD327,      0, 0xD328, 0x4A46,      0, 0x6462,      0,      0,\n      0, 0xD329,      0,      0, 0xD32A, 0xD32B, 0x4C62,      0,\n};\nconst unsigned short utf8_to_euc_E7B2[] = {\n      0, 0x364E, 0x3729, 0x6463,      0,      0, 0xD32C, 0xD32D,\n      0, 0x4A34,      0, 0x3F68,      0, 0x4C30,      0, 0xD32E,\n 0x6464,      0, 0x4E33,      0, 0xD32F, 0x4774,      0, 0x4146,\n 0x4734,      0,      0, 0x3D4D,      0,      0, 0xD330, 0x3040,\n 0xD331, 0x6469, 0x6467,      0, 0x6465, 0x3421, 0xD332, 0x3E51,\n 0x646A,      0,      0, 0x6468,      0, 0x6466, 0x646E,      0,\n 0xD333, 0x646D, 0x646C, 0x646B,      0,      0, 0xD334, 0xD335,\n      0, 0x646F, 0xD336, 0xD337, 0xD338, 0x6470, 0x403A, 0xD339,\n};\nconst unsigned short utf8_to_euc_E7B3[] = {\n 0x6471,      0, 0x6473,      0, 0xD33A, 0x6472,      0, 0xD33B,\n 0xD33C, 0xD33D, 0x3852,      0,      0, 0xD33E, 0x4138, 0xD33F,\n      0,      0, 0x6475, 0xD340, 0xD341, 0xD342, 0x457C, 0xD343,\n 0x6474, 0xD344, 0xD345,      0, 0x6476, 0xD346, 0x4A35, 0x416C,\n 0x3947,      0, 0x6477,      0,      0,      0, 0xD347, 0x4E48,\n      0, 0xD348,      0, 0xD349,      0,      0,      0, 0x6479,\n      0,      0, 0x647A,      0, 0x647B, 0xD34A, 0x647C,      0,\n 0x3B65,      0, 0x647D, 0x374F,      0,      0, 0x356A,      0,\n};\nconst unsigned short utf8_to_euc_E7B4[] = {\n 0x352A,      0, 0x6521, 0xD34B, 0x4C73, 0x3948, 0x647E, 0xD34C,\n 0xD34D, 0xD34E, 0x6524, 0x4C66,      0, 0x473C,      0, 0xD34F,\n 0x4933, 0xD350, 0xD351, 0xD352, 0x3D63, 0x6523, 0xD353, 0x3C53,\n 0x3949, 0x3B66, 0x3569, 0x4A36, 0x6522, 0xD354, 0xD355,      0,\n 0x4147, 0x4B42, 0x3A77, 0xD356,      0,      0, 0xD357,      0,\n      0,      0, 0xD358, 0x3B67, 0x445D, 0xD359, 0x6527, 0x4E5F,\n 0x3A59, 0xD35A, 0x6528, 0x3F42,      0, 0x652A,      0,      0,\n      0, 0x3E52, 0x3A30,      0, 0xD35B, 0xD35C, 0xD35D, 0x6529,\n};\nconst unsigned short utf8_to_euc_E7B5[] = {\n 0xD35E, 0xD35F, 0x3D2A, 0x383E, 0x4148, 0x6525, 0x652B, 0xD360,\n 0xD361,      0,      0, 0x6526, 0x3750, 0xD362, 0x652E, 0x6532,\n 0x376B, 0xD363,      0, 0xD364,      0,      0, 0x652D, 0xD365,\n      0, 0xD366, 0xD367, 0x6536, 0xD368, 0xD369, 0x394A,      0,\n      0, 0x4D6D, 0x303C, 0x6533,      0, 0xD36A, 0x356B, 0xD36B,\n 0x6530,      0, 0xD36C,      0,      0,      0, 0x6531,      0,\n 0xD36D, 0x457D, 0x652F, 0x652C,      0, 0x3328, 0x4064,      0,\n 0xD36E, 0x3828, 0xD36F, 0xD370,      0, 0x6538,      0, 0xD371,\n};\nconst unsigned short utf8_to_euc_E7B6[] = {\n      0, 0xD372, 0xD373, 0xD374,      0, 0xD375, 0xD376,      0,\n 0xD377, 0x6535,      0, 0xD378, 0xD379, 0xD37A,      0, 0x6537,\n      0, 0xD37B,      0, 0x6534,      0,      0, 0xD37C, 0xD37D,\n      0, 0x3751, 0x4233, 0x6539, 0x416E, 0xD37E, 0xD421, 0x6546,\n 0xF45C,      0, 0x6542, 0x653C,      0,      0, 0xD422, 0xD423,\n      0,      0, 0xD424, 0x6540, 0x3C7A, 0x305D, 0x653B, 0x6543,\n 0x6547, 0x394B, 0x4C56, 0xD425, 0x4456, 0x653D, 0xD426, 0xD427,\n 0x6545, 0xD428, 0x653A, 0x433E,      0, 0x653F, 0x303D, 0x4C4A,\n};\nconst unsigned short utf8_to_euc_E7B7[] = {\n      0,      0, 0xD429, 0xD42A, 0xD42B, 0xD42C, 0xD42D, 0x653E,\n      0,      0, 0x365B, 0x486C, 0xD42E, 0xD42F, 0xD430, 0x416D,\n      0, 0x4E50, 0x3D6F,      0,      0, 0x656E, 0xF45D, 0xD431,\n 0x6548, 0xD432, 0x407E,      0, 0x6544, 0x6549, 0x654B,      0,\n 0x4479, 0x654E, 0xD434,      0, 0x654A, 0xD435, 0xD436,      0,\n 0x4A54, 0x344B, 0xD437, 0xD438, 0x4C4B, 0xD439,      0, 0x305E,\n      0, 0xD43A, 0x654D,      0, 0x4E7D, 0xD43B, 0xD43C,      0,\n      0, 0xD43D, 0xD43E, 0x654C,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E7B8[] = {\n 0xD433, 0x316F,      0,      0, 0x466C, 0x654F,      0,      0,\n 0xD43F, 0x6556, 0x6550, 0x6557,      0,      0,      0,      0,\n 0xD440, 0xD441, 0x6553,      0,      0, 0xD442,      0, 0xD443,\n      0,      0,      0, 0x477B, 0xD444, 0xD445, 0x3C4A, 0x6555,\n 0xD446, 0x6552, 0x6558, 0x6551,      0,      0, 0x3D44, 0xD447,\n 0xD448,      0,      0, 0x4B25, 0xD449, 0xD44A, 0x3D4C, 0xD44B,\n      0, 0x6554, 0x6560, 0xD44C,      0, 0x655C, 0xD44D, 0x655F,\n      0, 0x655D, 0x6561, 0x655B,      0, 0x6541, 0x4053, 0xD44E,\n};\nconst unsigned short utf8_to_euc_E7B9[] = {\n      0, 0x484B,      0, 0x655E, 0xD44F, 0xD450, 0x6559, 0xD451,\n      0,      0, 0x4121, 0x3752,      0, 0x3D2B, 0xD452,      0,\n 0xD453,      0, 0xD454,      0, 0x3F25, 0x4136, 0x6564,      0,\n 0xD455, 0x6566, 0x6567,      0,      0, 0x6563, 0x6565, 0xD456,\n      0, 0xD457, 0xD458,      0,      0, 0xD459, 0x655A, 0x6562,\n      0, 0x656A, 0x6569, 0xD45A,      0, 0x4B7A, 0xD45B, 0xD45C,\n 0x372B,      0,      0, 0xD45D,      0,      0,      0,      0,\n 0xD45E, 0x6568,      0, 0x656C, 0x656B, 0x656F, 0xD45F, 0x6571,\n};\nconst unsigned short utf8_to_euc_E7BA[] = {\n      0, 0xD460, 0x3B3C, 0x656D,      0,      0, 0xD461, 0xD462,\n 0x6572, 0x6573, 0xD463,      0, 0x6574, 0xD464, 0x657A, 0x453B,\n 0x6576, 0xD465, 0x6575, 0x6577, 0x6578, 0xD466, 0x6579,      0,\n 0xD467,      0, 0xD468, 0x657B, 0x657C, 0xD469, 0xD46A,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E7BC[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x344C,      0,\n 0x657D,      0, 0x657E, 0xD46C, 0xD46B, 0xD46D, 0xD46E, 0xD46F,\n};\nconst unsigned short utf8_to_euc_E7BD[] = {\n      0,      0,      0, 0xD470, 0xD471, 0x6621,      0, 0xD472,\n      0,      0,      0,      0, 0x6622, 0x6623, 0x6624, 0xD473,\n 0x6625, 0x6626, 0xD474, 0xD475, 0x6628, 0x6627,      0,      0,\n 0x6629,      0,      0, 0xD476, 0xD477, 0xD478,      0, 0x662A,\n 0x662B, 0xD479,      0, 0xD47A, 0xD47B, 0xD47C, 0xD47D, 0x662E,\n 0x662C, 0x662D, 0x3A61, 0x3753,      0, 0xD47E, 0x4356,      0,\n 0x4833, 0xD521, 0x3D70,      0,      0, 0x474D,      0, 0x486D,\n 0x662F, 0x586D,      0,      0,      0, 0xD522, 0xD523, 0xD524,\n};\nconst unsigned short utf8_to_euc_E7BE[] = {\n 0xD525,      0, 0x6630, 0x6632,      0, 0x4D65, 0x6631, 0x6634,\n 0x6633,      0, 0x4D53, 0xD526, 0x6635, 0xD527, 0x487E, 0xD528,\n 0xD529, 0xD52A,      0,      0, 0x6636,      0, 0xD52B, 0xD52C,\n      0,      0, 0x6639,      0, 0xD52D, 0x6638, 0x6637,      0,\n      0, 0xD52E, 0xD52F, 0x663A, 0x3732,      0, 0xD530,      0,\n 0x4122, 0x3541, 0xD531,      0,      0, 0xD532, 0x663E, 0x663B,\n      0,      0, 0x663C,      0, 0xD533,      0, 0x663F,      0,\n 0x6640, 0x663D,      0,      0, 0xD534, 0x3129,      0, 0xD535,\n};\nconst unsigned short utf8_to_euc_E7BF[] = {\n 0xD536, 0x3227,      0, 0xD537,      0, 0x6642, 0x6643,      0,\n 0xD538,      0, 0x6644,      0, 0x4D62,      0, 0xD539, 0xD53A,\n      0,      0, 0x3D2C,      0, 0x6646, 0x6645,      0,      0,\n      0,      0,      0, 0xD53B,      0,      0,      0, 0xD53C,\n 0x3F69, 0x6647,      0, 0xD53D,      0, 0xD53E, 0x6648,      0,\n 0xD53F, 0x6649,      0, 0x3465, 0xD540,      0, 0xD541, 0xD542,\n 0x344D,      0, 0xD543, 0x664A,      0,      0,      0,      0,\n      0, 0x664B, 0xD544, 0x4B5D, 0x4D63, 0xD545, 0xD546, 0xD547,\n};\nconst unsigned short utf8_to_euc_E880[] = {\n 0x4D54, 0x4F37,      0, 0x394D, 0x664E, 0x3C54, 0x664D, 0xD548,\n 0xD549,      0, 0xD54A, 0x664F, 0x3C29, 0xD54B, 0xD54C, 0xD54D,\n 0x4251, 0xD54E, 0x6650, 0xD54F, 0xD550, 0x394C, 0xD551, 0x4C57,\n 0x6651, 0x6652,      0,      0, 0x6653, 0xD552, 0xD553, 0xD554,\n 0xD555, 0x6654,      0,      0, 0xD556,      0, 0xD557,      0,\n 0x6655,      0,      0,      0, 0xD558,      0, 0xD559,      0,\n 0xD55A,      0,      0, 0x3C2A, 0xD55B, 0xD55C, 0x4C6D, 0xD55D,\n      0, 0xD55E, 0xD55F, 0x6657, 0xD560, 0x433F, 0xD561, 0x6656,\n};\nconst unsigned short utf8_to_euc_E881[] = {\n 0xD562,      0,      0,      0, 0xD563,      0, 0x6659,      0,\n      0,      0, 0x6658,      0,      0,      0,      0,      0,\n      0,      0, 0x665A,      0,      0,      0, 0x403B,      0,\n 0x665B,      0, 0x665C,      0,      0,      0, 0x4A39, 0x665D,\n 0xD564, 0x416F, 0x665E,      0, 0xD565,      0, 0xD566,      0,\n 0x665F,      0,      0,      0,      0, 0xD567,      0, 0x4E7E,\n 0x6662, 0xD568, 0x6661, 0x6660, 0x4430, 0xD569, 0x6663, 0x3F26,\n      0, 0x6664,      0,      0,      0, 0x6665, 0x4F38, 0x6666,\n};\nconst unsigned short utf8_to_euc_E882[] = {\n      0, 0xD56A,      0,      0, 0x6667, 0x6669, 0x6668, 0x4825,\n 0xD56B, 0x4679,      0, 0x4F3E, 0x4829,      0, 0xD56C,      0,\n      0,      0,      0, 0x666B,      0,      0, 0x3E53,      0,\n 0x492A,      0, 0x666C, 0x666A, 0xD56D, 0x344E, 0xD56E,      0,\n      0, 0x3854, 0x3B68,      0,      0, 0x486E, 0xD56F, 0xD570,\n      0, 0x382A, 0x4B43, 0xD571, 0x666F, 0x666D,      0, 0x394E,\n      0, 0x394F, 0x3069,      0, 0x3A68,      0,      0,      0,\n 0xD572, 0xD573, 0x4759,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E883[] = {\n      0,      0,      0, 0x305F, 0x6674,      0, 0x4340,      0,\n 0xD574,      0,      0,      0, 0x4758, 0xD575, 0x425B, 0xD576,\n      0,      0, 0xD577,      0, 0xD578, 0xD579, 0x6676, 0xD57A,\n 0xD57B, 0x6672, 0x6675, 0x6670,      0, 0x6673, 0x4B26,      0,\n 0xD57C, 0x3855,      0,      0, 0x307D, 0x6671,      0,      0,\n      0,      0,      0,      0,      0, 0xD57D, 0xD57E, 0x6678,\n 0xD621, 0x6679, 0xD622, 0xD623, 0x4639,      0, 0xD624,      0,\n 0x363B, 0xD625, 0xD626,      0, 0x6726, 0x473D, 0xD627,      0,\n};\nconst unsigned short utf8_to_euc_E884[] = {\n      0,      0, 0x3B69, 0xD628,      0, 0x363C, 0x4048, 0x4F46,\n 0x4C2E, 0x6677, 0x4054, 0xD629,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xD62A, 0xD62B,\n 0xD62C,      0, 0x3553, 0x667A, 0xD62D,      0, 0xD62E,      0,\n 0xD62F,      0,      0, 0x667C, 0xD630,      0,      0, 0xD631,\n      0, 0x667B,      0,      0, 0xD632,      0,      0, 0x667D,\n 0xD633, 0x4326,      0, 0x473E,      0, 0xD634,      0,      0,\n      0, 0x4431, 0xD635,      0, 0xD636,      0, 0x6723,      0,\n};\nconst unsigned short utf8_to_euc_E885[] = {\n      0,      0,      0,      0,      0, 0xD637, 0x6722, 0xD638,\n      0,      0, 0xD639, 0x667E, 0xD63A,      0, 0x3F55,      0,\n 0x4965, 0x6725, 0xD63B, 0x6724, 0x3950, 0x4F53,      0, 0xD63C,\n      0,      0,      0,      0,      0,      0,      0, 0x6735,\n 0xD63D, 0xD63E,      0,      0,      0, 0x6729, 0x672A, 0xD63F,\n 0xD640, 0xD641,      0, 0x3C70,      0, 0xD642, 0x6728, 0xD643,\n 0x3978, 0x6727,      0,      0, 0x672B,      0,      0, 0xD644,\n 0x4432, 0x4A22, 0x4123,      0,      0,      0,      0, 0x425C,\n};\nconst unsigned short utf8_to_euc_E886[] = {\n 0x672F, 0xD645, 0x6730, 0x672C, 0xD647, 0xD648, 0xD649,      0,\n 0x672D,      0, 0x672E, 0xD64A,      0,      0, 0xD64B, 0x3951,\n 0xD646,      0,      0, 0x6736,      0, 0x6732, 0xD64C,      0,\n 0xD64D,      0, 0x4966, 0xD64E, 0x4B6C, 0x4928, 0xD64F,      0,\n 0x6731,      0, 0xD650, 0x6734, 0x6733,      0,      0,      0,\n 0x4B44, 0x6737,      0,      0,      0,      0, 0xD651,      0,\n 0x6738,      0, 0xD652, 0x4137, 0xD653, 0x6739,      0,      0,\n 0x673B,      0, 0x673F, 0xD654,      0, 0x673C, 0x673A, 0x473F,\n};\nconst unsigned short utf8_to_euc_E887[] = {\n 0x673D,      0, 0x673E, 0xD656,      0, 0xD657, 0x3232,      0,\n 0x6745, 0x6740, 0xD658, 0xD655,      0, 0x6741, 0xD659, 0xD65A,\n      0, 0x6742,      0, 0x4221,      0, 0xD65B,      0, 0xD65C,\n 0x6744, 0x6743, 0x6746, 0xD65D,      0, 0xD65E, 0xD65F, 0x6747,\n 0x6748, 0xD660,      0, 0x3F43, 0xD661, 0x3269,      0, 0x6749,\n 0x4E57,      0, 0x3C2B, 0xD662, 0xD663, 0x3D2D,      0,      0,\n 0xD664, 0xD665, 0xD666, 0x3B6A, 0x4357, 0xD667, 0xD668,      0,\n 0xD669, 0xD66A, 0x674A, 0x674B, 0x3131, 0xD66B, 0x674C, 0xD66C,\n};\nconst unsigned short utf8_to_euc_E888[] = {\n 0xD66D, 0x674D, 0x674E, 0xD66E,      0, 0x674F,      0, 0x6750,\n 0x363D, 0x5A2A, 0x6751,      0, 0x4065, 0x6752, 0x3C4B, 0xD66F,\n 0x6753,      0, 0x5030, 0xD670, 0xD671,      0, 0x6754, 0x4A5E,\n 0x345C, 0xD672, 0xD673, 0x4124, 0x3D58, 0xD674, 0x4971, 0x3D2E,\n      0, 0xD675, 0xD676,      0,      0,      0,      0,      0,\n 0xD677, 0x6755, 0x3952, 0x6756, 0x484C,      0, 0x6764,      0,\n      0,      0, 0xD678, 0x6758, 0xD679, 0x4249, 0x4775, 0x383F,\n 0x6757, 0x4125, 0xD67A,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E889[] = {\n 0x6759,      0,      0, 0xD67B, 0xD67C, 0xD67D, 0xD67E, 0x447A,\n      0,      0,      0, 0xD721,      0,      0, 0xD722, 0xD723,\n      0, 0xD724,      0,      0,      0,      0, 0xD725,      0,\n 0x675B, 0x675A, 0x675D,      0, 0xD726, 0x675C,      0, 0x675E,\n 0xD727,      0, 0x6760, 0xD728, 0x675F,      0, 0x344F, 0xD729,\n 0x6761,      0, 0x6762, 0x6763,      0, 0xD72A, 0x3A31, 0x4E49,\n      0, 0x6765, 0x3F27,      0, 0xD72B,      0, 0x3170, 0x6766,\n 0x6767,      0,      0, 0xD72C,      0, 0xD72D, 0x6768, 0xD72E,\n};\nconst unsigned short utf8_to_euc_E88A[] = {\n 0xD72F, 0xD730,      0, 0xD731, 0xD732,      0,      0, 0xD733,\n      0, 0xD734, 0xD735, 0x3072,      0, 0x6769, 0xD736,      0,\n      0, 0xD737, 0x676A,      0, 0xD738,      0, 0xD739,      0,\n 0xD73A, 0x4967, 0xD73B, 0xD73C,      0, 0x3C47,      0, 0x676C,\n 0xD73D, 0xD73E,      0, 0xD73F, 0xD740, 0x3329, 0x3032, 0xD741,\n 0xD742, 0xD743, 0xD744, 0x676B, 0x676E, 0x474E, 0xD745, 0x3F44,\n 0xD746, 0x3256, 0xD747, 0x4B27, 0xD748,      0,      0, 0xD749,\n 0x375D, 0x365C, 0xD74A, 0x676D, 0xD74B, 0x326A, 0xD74C, 0xD74D,\n};\nconst unsigned short utf8_to_euc_E88B[] = {\n      0,      0,      0,      0,      0, 0x3423, 0xD74E,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xD74F, 0x3171, 0x6772, 0x4E6A, 0x425D, 0xD750,      0, 0x4944,\n      0, 0x677E, 0xD751, 0x3257, 0x677C,      0, 0x677A, 0x6771,\n 0xD752, 0x676F, 0xD753, 0x6770, 0xD754, 0x3C63, 0x366C, 0x4377,\n 0xD755,      0, 0xD756, 0x4651,      0, 0xD757,      0, 0xD758,\n      0, 0x3151,      0, 0x6774, 0x6773,      0, 0xD759, 0xD75A,\n      0, 0x6779, 0x6775, 0x6778,      0, 0xD75B, 0xD75C,      0,\n};\nconst unsigned short utf8_to_euc_E88C[] = {\n 0xD75D, 0xD75E, 0x4C50, 0x6777, 0x3258, 0x337D, 0x677B, 0xD75F,\n 0xD760, 0x677D, 0xD761, 0xD762,      0,      0, 0x3754,      0,\n      0,      0,      0,      0,      0,      0, 0x6823, 0x682C,\n 0x682D,      0,      0, 0xD764, 0x302B, 0xD765, 0xD766, 0xD767,\n      0, 0xD768, 0xD769, 0x6834,      0,      0,      0,      0,\n 0x3071,      0,      0, 0x682B, 0xD76A, 0xD76B, 0xD76C, 0x682A,\n 0xD76D, 0x6825, 0x6824, 0xD76E, 0x6822, 0x6821, 0x4363, 0xD76F,\n 0x427B, 0x6827, 0xD770,      0, 0xD771, 0xD772,      0,      0,\n};\nconst unsigned short utf8_to_euc_E88D[] = {\n 0x6826,      0, 0xD773, 0xD774, 0xD775, 0x6829,      0, 0xD776,\n      0, 0x4170, 0x3755,      0,      0, 0xD777, 0xD778, 0x3141,\n 0x6828, 0xD779, 0x3953, 0xD83E, 0xD763, 0xD77A, 0xD77B, 0xD77C,\n 0x4171,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xF45F,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xD77D,      0,      0, 0x683A,      0, 0x683B,      0, 0x3259,\n 0xD77E,      0,      0, 0x322E, 0x6838, 0xD821,      0, 0xD822,\n};\nconst unsigned short utf8_to_euc_E88E[] = {\n 0xD823,      0, 0xD824,      0, 0xD825, 0x682E, 0xD826, 0x6836,\n      0, 0x683D, 0x6837,      0,      0, 0xD827, 0x6835,      0,\n      0,      0, 0xD828, 0x6776, 0xD829, 0xD82A, 0x6833,      0,\n 0xD82B, 0xD82C, 0x682F, 0xD82D, 0xD82E, 0xD82F, 0x3450, 0x6831,\n 0x683C,      0, 0x6832,      0,      0,      0, 0xD830, 0xD831,\n 0x683E, 0xD832, 0x6830, 0x477C, 0xD833, 0xD84C,      0,      0,\n      0, 0x4D69,      0,      0,      0, 0x6839,      0,      0,\n      0,      0,      0,      0,      0, 0x684F, 0xD834, 0xD835,\n};\nconst unsigned short utf8_to_euc_E88F[] = {\n 0xD836, 0x6847,      0,      0,      0, 0x3F7B,      0, 0xD837,\n      0, 0xD838, 0x3546,      0, 0x365D,      0, 0x6842, 0xD839,\n 0xD83A, 0xD83B,      0, 0x325B, 0xD83C,      0, 0x3E54,      0,\n 0x6845,      0,      0,      0, 0x3A5A, 0xD83D,      0, 0x4551,\n 0x684A,      0,      0,      0,      0,      0,      0,      0,\n 0xD83F, 0x4A6E, 0xD840, 0x6841,      0,      0,      0, 0x325A,\n 0x3856, 0x4929, 0x684B,      0, 0x683F,      0, 0xD841, 0x6848,\n 0xD842, 0xD843,      0, 0x6852, 0xD844, 0x6843,      0,      0,\n};\nconst unsigned short utf8_to_euc_E890[] = {\n      0, 0xD845,      0, 0x6844, 0x463A,      0, 0xD846, 0x6849,\n      0,      0, 0xD847, 0x6846, 0x4B28, 0x684C, 0x3060, 0xD848,\n      0, 0xD849,      0, 0x6840,      0, 0xD84A,      0,      0,\n      0, 0xD84B,      0,      0,      0,      0,      0,      0,\n 0x684E,      0, 0x684D,      0,      0,      0,      0,      0,\n      0, 0x476B, 0x6854,      0, 0x685F,      0,      0, 0xD84D,\n      0, 0x337E,      0,      0,      0, 0x6862,      0,      0,\n 0x6850, 0xD84E,      0,      0, 0x6855, 0x4D6E,      0,      0,\n};\nconst unsigned short utf8_to_euc_E891[] = {\n      0,      0,      0,      0,      0, 0xD84F, 0x685E, 0xD850,\n 0xD851, 0x4D55, 0xD852,      0,      0, 0xD853, 0x4E2A, 0xD854,\n      0, 0xD855, 0xD856,      0,      0,      0, 0xD857, 0x4378,\n 0xD858, 0xD859, 0xD85A, 0x336B, 0xD85B,      0,      0,      0,\n 0xD85C, 0x4972, 0x6864, 0x4621, 0xD85D, 0xD85E, 0x3031, 0xD85F,\n      0, 0x685D, 0xD860, 0x6859, 0x4172, 0x6853, 0x685B, 0x6860,\n 0xD861, 0x472C,      0, 0xD862, 0xD863, 0x302A, 0xD864, 0x6858,\n 0xD865, 0x6861, 0x4978,      0, 0xD866, 0xD867,      0,      0,\n};\nconst unsigned short utf8_to_euc_E892[] = {\n      0, 0xD868, 0x685C,      0, 0x6857, 0xD869,      0,      0,\n      0,      0,      0, 0x3E55,      0,      0,      0,      0,\n 0x3D2F,      0, 0xD86A, 0xD86B, 0x3C2C, 0xD86C,      0,      0,\n      0, 0x4C58,      0,      0, 0x4947,      0, 0xD86D, 0x6867,\n      0, 0x6870,      0,      0,      0,      0, 0xD86E,      0,\n 0xD86F, 0xD870, 0xD871,      0,      0, 0x685A,      0, 0xD872,\n      0, 0xD873, 0x3377,      0, 0xD874,      0,      0,      0,\n 0x3E78, 0x6865, 0xD875, 0x686A, 0x4173, 0xD876, 0xD877, 0x6866,\n};\nconst unsigned short utf8_to_euc_E893[] = {\n 0xD878, 0x686D, 0xD879,      0, 0x435F,      0, 0x686E, 0xD87A,\n 0xD87B, 0x4D56, 0x6863, 0x3338, 0xD87C, 0x6869,      0, 0xD87D,\n 0x686C, 0x4C2C,      0, 0xD87E,      0,      0, 0x686F,      0,\n      0, 0x6868, 0x686B,      0, 0xD921,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xD922,\n      0,      0, 0xD923,      0, 0x4B29,      0, 0x4F21, 0xD924,\n 0xD925, 0xD926, 0xD927,      0, 0x6873,      0,      0, 0xD928,\n      0,      0, 0xD92A, 0xD92B, 0x687A, 0xD92C,      0, 0x6872,\n};\nconst unsigned short utf8_to_euc_E894[] = {\n 0x3C43,      0, 0xD92D, 0xD92E,      0,      0, 0x6851, 0xD92F,\n      0,      0,      0,      0, 0xD930,      0, 0xD931,      0,\n 0xD932, 0x4A4E,      0, 0x4C22, 0x6879, 0x6878,      0, 0x6874,\n 0x6875,      0, 0x3136,      0, 0xD933,      0, 0xD934, 0x6877,\n      0, 0x6871, 0xD935, 0xD936, 0xD937, 0xD938, 0x4455, 0xD939,\n      0,      0, 0xD93A, 0xD93B, 0x6876, 0x307E,      0, 0xD93C,\n      0,      0, 0xD929, 0xD93D, 0xD93E, 0x4222, 0xD93F,      0,\n      0,      0,      0,      0,      0, 0x4A43,      0, 0xD940,\n};\nconst unsigned short utf8_to_euc_E895[] = {\n 0x687B, 0x6921,      0, 0x4859,      0,      0, 0xD941,      0,\n 0x687E, 0x3E56, 0x3C49, 0x6923,      0,      0, 0x363E, 0xD942,\n 0xD943, 0xD944, 0xD945, 0xD946,      0, 0x6924, 0xD947, 0x4979,\n 0x687D, 0xD948, 0x6856,      0, 0xD949, 0xD94A, 0xD94B, 0xD94C,\n 0xD94D, 0xD94E, 0xD94F, 0x687C, 0xD950,      0,      0,      0,\n 0x4F4F, 0x4622, 0x4973, 0xD951,      0, 0x692B,      0, 0xD952,\n      0,      0,      0,      0,      0,      0,      0, 0x6931,\n      0, 0xD953, 0xD954, 0xD955,      0, 0xD956, 0x6932, 0xD957,\n};\nconst unsigned short utf8_to_euc_E896[] = {\n 0x6925, 0xD958,      0,      0, 0x4776, 0xD959, 0xD95A, 0x692F,\n 0x6927, 0xD95B, 0x6929, 0xD95C, 0xD95D,      0,      0, 0xD95E,\n 0x6933, 0x6928,      0, 0xD95F, 0x692C,      0,      0, 0x3172,\n 0xD960, 0x4665,      0, 0x692D, 0x6930, 0xD961,      0, 0xD962,\n 0xD963,      0, 0xD964,      0, 0x6926, 0xD965, 0x4126, 0xD966,\n 0x692A, 0x3B27, 0x3F45, 0x3730, 0x4C74, 0xD974, 0x4C79, 0x3D72,\n 0xF461,      0,      0,      0, 0xD967,      0, 0xD968, 0xD969,\n 0xD96A, 0x6937, 0x6935,      0, 0xD96B, 0xD96C, 0xD96D, 0xD96E,\n};\nconst unsigned short utf8_to_euc_E897[] = {\n      0, 0x4F4E, 0xD96F,      0,      0,      0,      0, 0xD970,\n      0, 0x6934, 0xD971, 0xD972,      0, 0x4D75, 0xD973, 0x6936,\n 0x6938,      0,      0,      0,      0, 0x6939,      0,      0,\n 0xD975,      0, 0xD976,      0, 0x693C, 0x693A,      0, 0xD977,\n 0xD978,      0,      0,      0, 0x4623, 0x693B, 0xD979,      0,\n 0xD97A, 0x484D, 0x692E,      0,      0, 0xD97B,      0,      0,\n      0,      0,      0, 0xD97C,      0,      0, 0xD97D, 0x3D73,\n      0, 0x693D, 0x6942, 0x4174, 0xD97E,      0, 0x6941, 0xDA21,\n};\nconst unsigned short utf8_to_euc_E898[] = {\n 0xDA22,      0, 0x6922,      0, 0xDA23, 0xDA24, 0x6943, 0x4149,\n      0,      0, 0x693E, 0x6940,      0, 0xDA25, 0xDA26,      0,\n 0xDA27, 0xDA28, 0xDA29, 0x693F,      0,      0, 0x5D31, 0x5D22,\n 0xDA2A, 0xDA2B, 0x6945, 0xDA2C,      0,      0, 0xDA2D,      0,\n      0, 0xDA2E, 0x6944,      0,      0,      0,      0, 0xDA2F,\n      0, 0xDA30,      0,      0,      0, 0x4D76,      0, 0x623C,\n 0x6946,      0,      0,      0,      0,      0, 0xDA31,      0,\n 0xDA32,      0, 0xDA33,      0, 0xDA34, 0xDA35,      0, 0x6947,\n};\nconst unsigned short utf8_to_euc_E899[] = {\n 0xDA36, 0xB866, 0xDA37,      0,      0,      0, 0xDA38,      0,\n      0,      0,      0,      0,      0, 0x6948, 0x3857,      0,\n 0x3554,      0, 0xDA39, 0xDA3A, 0x694A, 0x515D, 0xDA3B, 0xDA3C,\n 0xDA3D, 0xDA3E, 0x3575,      0, 0x4E3A, 0xDA3F, 0x3673, 0x694B,\n 0xDA40, 0xDA41, 0xDA42, 0xDA43, 0xDA44,      0,      0, 0x694C,\n      0, 0xDA45,      0, 0x436E, 0xDA46,      0,      0, 0xDA47,\n      0, 0x694D,      0,      0,      0, 0xDA48, 0xDA49, 0xDA4A,\n      0, 0x467A, 0xDA4B, 0x303A,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E89A[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xDA6D,      0, 0x3263, 0x6952, 0x6953, 0xDA4C,      0,      0,\n      0, 0xDA4D,      0, 0x694E,      0, 0x3B3D, 0xDA4E,      0,\n 0xDA4F,      0, 0xDA50,      0, 0xDA51,      0,      0,      0,\n      0, 0xDA52,      0, 0x694F, 0x4742,      0, 0xDA53, 0xDA54,\n 0xDA55, 0x6950, 0x6951, 0x695B,      0, 0xDA56,      0, 0x6955,\n 0x6958, 0xDA57,      0, 0xDA58, 0xDA59, 0xDA5A, 0x6954, 0xDA5B,\n 0xDA5C, 0xDA5D,      0,      0,      0,      0,      0, 0xDA5E,\n};\nconst unsigned short utf8_to_euc_E89B[] = {\n 0xDA5F, 0xDA60,      0, 0xDA61, 0x6956, 0xDA62, 0x6957, 0x3C58,\n      0, 0x6959,      0, 0x4341,      0, 0x3756, 0x3342,      0,\n      0, 0xDA63, 0xDA64,      0, 0x695C, 0xDA65,      0, 0xDA66,\n      0, 0x333F, 0xDA67, 0x6961, 0xDA68,      0, 0x695D, 0x6960,\n 0xDA69,      0,      0, 0xDA6A, 0x483A, 0xDA6B,      0, 0xDA6C,\n      0, 0x695E,      0,      0, 0x695F, 0x4948, 0x485A, 0x6962,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x427D, 0x696C, 0xDA6E, 0x6968, 0xDA6F, 0xDA70, 0x326B,      0,\n};\nconst unsigned short utf8_to_euc_E89C[] = {\n 0x6966,      0, 0x4B2A, 0x6967, 0xDA71, 0xDA72, 0x6964, 0xDA73,\n 0x6965, 0x696A, 0x696D, 0xDA74,      0, 0x696B, 0xDA75, 0xDA76,\n 0xDA77, 0x6969, 0x6963, 0xDA78, 0xDA79,      0,      0,      0,\n 0x4358, 0xDA7A, 0x6974,      0, 0x4C2A,      0, 0xDA7B, 0xDA7C,\n      0, 0xDA7D,      0, 0xDA7E,      0, 0x6972,      0,      0,\n 0xDB21, 0x6973,      0,      0,      0,      0, 0xDB22, 0xDB23,\n      0, 0xDB24, 0xDB25,      0, 0x696E,      0,      0, 0x6970,\n      0, 0xDB26, 0xDB27, 0x6971, 0xDB28, 0xDB29, 0xDB2A, 0x696F,\n};\nconst unsigned short utf8_to_euc_E89D[] = {\n 0xDB2B,      0,      0, 0xDB2C,      0, 0xDB2D,      0,      0,\n      0, 0x4066,      0, 0x4F39, 0x6978, 0xDB2E, 0x6979,      0,\n      0,      0,      0, 0x6A21,      0, 0x3F2A,      0, 0x697B,\n 0xDB2F, 0x697E,      0,      0,      0, 0xDB30,      0, 0x6976,\n 0x6975, 0xDB31,      0, 0x6A22, 0xDB32, 0xDB33, 0x325C,      0,\n 0x697C,      0, 0x6A23,      0,      0,      0, 0x697D, 0xDB34,\n      0, 0xDB35, 0xDB36,      0, 0x697A,      0, 0x4433,      0,\n 0x6977,      0,      0, 0xDB37,      0,      0,      0, 0x4768,\n};\nconst unsigned short utf8_to_euc_E89E[] = {\n      0,      0, 0x6A27, 0xDB38, 0xDB39, 0xDB3A, 0xDB3B, 0xDB3C,\n 0xDB3D, 0xDB3E,      0, 0xDB3F, 0xDB40, 0x4D3B,      0,      0,\n 0xDB41,      0,      0, 0xDB42,      0, 0xDB43,      0, 0xDB44,\n 0xDB45, 0xDB46,      0,      0,      0,      0, 0xDB47, 0x6A26,\n 0xDB48,      0, 0x6A25, 0xDB49,      0,      0,      0, 0xDB4A,\n      0,      0,      0, 0x6A2E, 0xDB4B, 0xDB4C, 0xDB4D, 0x6A28,\n      0, 0xDB4E,      0, 0x6A30,      0, 0xDB4F,      0,      0,\n      0,      0, 0x4D66, 0x6A33,      0, 0x6A2A, 0xDB50, 0xDB51,\n};\nconst unsigned short utf8_to_euc_E89F[] = {\n 0x6A2B, 0xDB52,      0,      0, 0x6A2F,      0, 0x6A32, 0x6A31,\n 0xDB53, 0xDB54, 0xDB55, 0x6A29,      0,      0, 0xDB56,      0,\n 0x6A2C,      0, 0x6A3D,      0,      0, 0xDB57, 0xDB58,      0,\n      0, 0xDB59, 0xDB5A,      0, 0xDB5B,      0,      0, 0xDB5C,\n 0x6A36,      0, 0xDB5D, 0xDB5E, 0xDB5F,      0,      0,      0,\n      0,      0, 0xDB60, 0xDB61,      0, 0xDB62,      0, 0x6A34,\n      0, 0xDB63, 0x6A35, 0xDB64,      0,      0, 0x6A3A, 0x6A3B,\n 0xDB65, 0x332A, 0xDB66, 0x3542,      0,      0, 0x6A39, 0xDB67,\n};\nconst unsigned short utf8_to_euc_E8A0[] = {\n      0, 0xDB68,      0, 0xDB69,      0, 0x6A24, 0xDB6A, 0xF464,\n      0, 0xDB6B, 0xDB6C, 0xDB6D,      0, 0x6A38, 0x6A3C, 0x6A37,\n 0xDB6E, 0x6A3E, 0xDB70, 0xDB71, 0xDB72, 0x6A40, 0x6A3F,      0,\n 0xDB73, 0xDB6F, 0xDB74, 0xDB75, 0xDB76,      0, 0xDB77, 0xDB78,\n      0, 0x6A42, 0x6A41, 0x695A,      0,      0,      0, 0x6A46,\n 0xDB79,      0,      0,      0,      0, 0xDB7A, 0xDB7B,      0,\n 0xDB7C, 0x6A43, 0xDB7D,      0,      0, 0xDB7E, 0x6A44,      0,\n      0, 0x6A45, 0xDC21, 0x6A47, 0xDC22,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E8A1[] = {\n 0x376C, 0xDC23, 0x6A49, 0xDC24, 0x6A48, 0xDC25, 0x3D30,      0,\n 0xDC26, 0xDC27, 0xDC28, 0xDC29, 0x3954, 0x5E27, 0xDC2A,      0,\n      0, 0xDC2B, 0x6A4A, 0x3D51,      0, 0xDC2C, 0xDC2D, 0x3339,\n 0xDC2E, 0x6A4B, 0xDC2F, 0x3152, 0xDC30, 0x3E57, 0x6A4C, 0xDC31,\n 0xDC32, 0x3955, 0x6A4D, 0x3061, 0xDC33,      0,      0,      0,\n 0x493D, 0xDC34,      0, 0x6A4E,      0,      0,      0,      0,\n 0x3F6A, 0xDC35, 0x6A55,      0,      0, 0x6A52,      0, 0x436F,\n      0, 0xDC36,      0, 0xDC37,      0, 0x6A53, 0x6A50, 0x365E,\n};\nconst unsigned short utf8_to_euc_E8A2[] = {\n 0xDC38, 0x6A4F, 0x6A56,      0,      0,      0,      0,      0,\n 0x3736,      0,      0, 0x425E,      0, 0x6A5C,      0,      0,\n      0,      0, 0x6A58,      0,      0,      0, 0x4235, 0x6A57,\n 0xDC39, 0x6A5A, 0xDC3A, 0xDC3B, 0xDC3C,      0, 0x6A51, 0xDC3D,\n 0xDC3E,      0, 0x6A5B,      0, 0x6A5D,      0,      0,      0,\n 0xDC3F,      0, 0xDC40, 0x486F,      0,      0, 0x6A59,      0,\n 0x6A5E, 0x6A60,      0,      0, 0x3853, 0x6A54,      0, 0x3041,\n      0,      0, 0xDC41,      0,      0, 0xDC42, 0xDC43, 0x6A5F,\n};\nconst unsigned short utf8_to_euc_E8A3[] = {\n 0xDC44, 0x3A5B, 0x4E76, 0x6A61, 0x6A62, 0x4175,      0,      0,\n      0,      0, 0xDC45, 0xDC46, 0xDC47, 0xDC48, 0xDC49, 0x4E22,\n      0, 0xDC4A, 0xDC4B, 0xDC4C, 0x6A63, 0x4D35,      0,      0,\n 0x6A64, 0x6A65,      0, 0xDC4D, 0x4A64, 0x6A66, 0xDC4E, 0x3A40,\n      0, 0x4E23,      0,      0,      0,      0,      0, 0xDC4F,\n 0x6A6B,      0,      0,      0,      0,      0,      0, 0xDC50,\n 0xDC51, 0xDC52, 0x6A6C, 0x3E58, 0x6A6A, 0xDC53,      0, 0xDC54,\n 0x4D67, 0x6A67,      0,      0, 0x6A69, 0x403D, 0x3F7E,      0,\n};\nconst unsigned short utf8_to_euc_E8A4[] = {\n      0, 0xDC55, 0x6A68,      0, 0x6A6D,      0, 0xDC56, 0x4A23,\n      0,      0, 0x6A6F,      0, 0x6A6E, 0xDC57, 0xDC58, 0xDC59,\n 0x336C,      0, 0x4B2B, 0x6A70,      0, 0xDC5A, 0xDC5B,      0,\n 0xDC5C, 0xDC5D, 0xDC5E,      0, 0xDC5F, 0x6A7C, 0x6A72,      0,\n 0xDC60,      0,      0,      0,      0, 0x6A73, 0xDC61, 0xDC62,\n 0xDC63,      0, 0x6A74, 0x6A75,      0,      0,      0,      0,\n 0xDC64, 0xDC65, 0xDC66,      0,      0, 0xDC67, 0x6A79,      0,\n 0x6A7A, 0xDC68, 0xDC69, 0x6A78,      0,      0, 0xDC6A,      0,\n};\nconst unsigned short utf8_to_euc_E8A5[] = {\n 0xDC6B, 0x6A76, 0xDC6C, 0x6A71, 0x6A77, 0xDC6D, 0xDC6E,      0,\n      0, 0xDC6F,      0,      0, 0x6A7B, 0x7037,      0, 0xDC70,\n      0,      0, 0xDC71,      0,      0,      0, 0x3228, 0xDC72,\n      0,      0, 0xDC73, 0xDC74, 0xDC75,      0, 0x6A7E, 0x365F,\n 0x6A7D, 0xDC76, 0xDC77, 0xDC78, 0x6B22,      0, 0x6B21,      0,\n      0,      0, 0x6B24, 0xDC79,      0, 0x6B23, 0xDC7A, 0x6B25,\n 0xDC7B,      0, 0x3D31, 0xDC7C, 0x6B26, 0xDC7D,      0, 0x6B27,\n      0,      0, 0xDC7E, 0xDD21, 0xDD22, 0xDD23, 0x6B28, 0x403E,\n};\nconst unsigned short utf8_to_euc_E8A6[] = {\n      0, 0x4D57,      0, 0x6B29,      0,      0, 0x4A24, 0x4746,\n 0x6B2A, 0xDD24, 0x6B2B, 0x382B,      0, 0xDD25,      0, 0x352C,\n 0xDD26,      0,      0, 0x6B2C, 0xDD27, 0xDD28, 0x3B6B, 0x4741,\n 0x6B2D,      0, 0x3350, 0xDD29, 0xDD2A,      0,      0, 0xDD2B,\n 0xDD2C, 0x6B2E,      0,      0,      0, 0xDD2D, 0x6B30, 0x4D77,\n      0, 0x6B2F, 0x3F46,      0, 0x6B31,      0,      0, 0x6B32,\n 0xDD2E,      0, 0x6B33, 0x3451, 0xDD2F, 0xDD30, 0xDD31, 0xDD32,\n      0,      0, 0x6B34,      0, 0xDD33, 0x6B35,      0, 0x6B36,\n};\nconst unsigned short utf8_to_euc_E8A7[] = {\n 0x6B37,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0x3351,      0, 0xDD34, 0xDD35, 0xDD36, 0xDD37,\n 0xDD38,      0, 0x6B38,      0, 0x6B39, 0x6B3A,      0,      0,\n      0,      0,      0, 0x3272,      0, 0xDD39, 0x3F28, 0x6B3B,\n      0, 0xDD3A,      0, 0xDD3B,      0, 0xDD3C,      0,      0,\n      0, 0xDD3D,      0, 0xDD3E, 0x6B3C,      0, 0xDD3F,      0,\n 0x6B3D, 0xDD40,      0,      0,      0, 0xDD41,      0, 0xDD42,\n};\nconst unsigned short utf8_to_euc_E8A8[] = {\n 0x3840,      0, 0x447B, 0x6B3E, 0xDD43, 0xDD44,      0, 0xDD45,\n 0x3757,      0, 0x3F56,      0, 0x6B41,      0, 0x4624, 0xDD46,\n 0x6B40, 0xDD47, 0xDD48, 0x3731, 0xDD49, 0xDD4A, 0x6B3F, 0x4277,\n 0x352D,      0,      0, 0x6B42,      0, 0x6B43, 0xDD4B, 0x3E59,\n 0xDD4C,      0, 0xDD4D, 0x376D, 0xDD4E, 0x6B44, 0xDD4F,      0,\n      0,      0, 0x4B2C, 0xDD50, 0xDD51, 0x405F,      0, 0xDD52,\n      0, 0x3576,      0, 0x4C75, 0x414A, 0xDD53, 0x6B45, 0xDD54,\n      0,      0, 0x3F47, 0x4370, 0x3E5A, 0xDD55, 0xDD56,      0,\n};\nconst unsigned short utf8_to_euc_E8A9[] = {\n 0xDD57, 0x6B46,      0, 0xDD58,      0, 0xDD59, 0x6B49, 0xDD5A,\n 0x6B4A, 0xDD5B,      0,      0,      0, 0xDD5C, 0xDD5D,      0,\n 0x3A3E, 0x4242, 0x6B48, 0xDD5E, 0x3E5B, 0x493E, 0xDD5F, 0xDD60,\n 0xDD61,      0,      0, 0x6B47, 0xDD62, 0xDD63, 0x3B6C,      0,\n 0x3153, 0xDD64, 0x6B4E, 0x3758,      0, 0xDD65, 0x3B6E, 0xDD66,\n      0, 0x3B6D,      0, 0x4F4D, 0x6B4D, 0x6B4C, 0x4127,      0,\n 0x354D, 0x4F43, 0x333A, 0x3E5C,      0, 0xDD67, 0xDD68, 0xDD69,\n      0, 0xDD6A, 0xDD6B, 0xDD6C, 0x6B4B,      0, 0xDD6D, 0xDD6E,\n};\nconst unsigned short utf8_to_euc_E8AA[] = {\n 0xDD6F,      0, 0x6B50, 0xDD70, 0x6B51, 0x6B4F, 0xDD71, 0x3858,\n      0, 0x4D40,      0, 0xDD72, 0x3B6F, 0x4727,      0, 0xDD73,\n 0xDD74, 0x6B54, 0xDD75, 0x4040,      0, 0x4342, 0xDD76, 0xDD77,\n 0x4D36, 0xDD78, 0x6B57,      0,      0,      0, 0x386C, 0xDD79,\n 0x403F, 0x6B53,      0, 0x6B58, 0x386D, 0x6B55, 0x6B56, 0xDD7A,\n 0x6B52, 0xDD7B,      0,      0, 0x4062, 0x4649, 0xDD7C, 0xDD7D,\n 0x432F,      0, 0x325D, 0xDD7E,      0,      0, 0xDE21, 0xDE22,\n      0, 0x4870,      0, 0xDE23, 0x3543,      0, 0xDE24, 0x4434,\n};\nconst unsigned short utf8_to_euc_E8AB[] = {\n      0,      0, 0x6B5B, 0xDE25, 0x6B59,      0, 0xDE26, 0x434C,\n 0xDE27, 0xDE28, 0xDE29, 0x4041, 0x3452, 0x6B5A,      0, 0x3F5B,\n      0, 0xDE2A, 0x4E4A, 0xDE2B, 0xDE2C, 0xDE2D, 0x4F40, 0xDE2E,\n      0,      0, 0x6B5C, 0x6B67, 0x4435, 0xDE2F, 0x6B66, 0xDE30,\n 0x6B63, 0x6B6B, 0x6B64,      0, 0x6B60,      0, 0x447C, 0x6B5F,\n      0,      0,      0, 0x6B5D, 0xDE31, 0x4D21, 0x3B70,      0,\n 0xDE32, 0x6B61,      0, 0x6B5E, 0xDE33, 0xDE34, 0xDE35, 0x6B65,\n 0x3D74,      0, 0x3841,      0, 0xDE36,      0, 0x427A, 0xDE37,\n};\nconst unsigned short utf8_to_euc_E8AC[] = {\n 0x4B45, 0x315A, 0x3062,      0, 0x4625, 0xDE38, 0xDE39, 0x6B69,\n      0,      0, 0xDE3F, 0xDE3A, 0x6B68,      0, 0x4666,      0,\n 0x6B6D, 0xDE3B,      0,      0, 0x6B62,      0, 0x6B6C, 0x6B6E,\n      0, 0x382C, 0x6B6A, 0x3956, 0xDE3C, 0x3C55, 0xDE3D, 0xDE3E,\n 0x6B6F, 0x4D58,      0,      0,      0,      0, 0x6B72,      0,\n 0x6B75,      0,      0, 0x6B73, 0x4935, 0xDE40,      0,      0,\n 0xDE41,      0,      0, 0x6B70,      0,      0,      0, 0xDE42,\n      0, 0x3660,      0,      0, 0xDE43,      0, 0x6B74,      0,\n};\nconst unsigned short utf8_to_euc_E8AD[] = {\n      0, 0x6B76, 0xDE44, 0xDE45, 0xDE46, 0xDE47, 0xDE48,      0,\n 0xDE49, 0x6B7A,      0,      0, 0x6B77, 0xDE4E, 0x6B79, 0x6B78,\n      0,      0, 0xDE4A, 0xDE4B, 0xDE4C,      0, 0x6B7B,      0,\n 0x3C31, 0xDE4D, 0x6B7D, 0x6B7C, 0x4968,      0, 0xDE4F, 0x6C21,\n      0,      0,      0, 0xDE50,      0,      0, 0x3759,      0,\n      0,      0,      0, 0x6B7E, 0x6C22, 0xDE51,      0, 0x6C23,\n 0x3544, 0x6641, 0x3E79,      0, 0x6C24,      0, 0xDE52, 0x386E,\n 0xDE53, 0xDE54,      0,      0, 0xDE55, 0x6C25, 0xDE56, 0xF466,\n};\nconst unsigned short utf8_to_euc_E8AE[] = {\n 0x6C26, 0xDE57,      0, 0x3B3E, 0xDE58, 0xDE59,      0,      0,\n      0,      0, 0x5A4E, 0xDE5A, 0x6C27, 0xDE5B, 0x6C28, 0xDE5C,\n 0x3D32,      0, 0x6C29, 0x6C2A, 0xDE5D, 0xDE5E, 0x6C2B,      0,\n      0, 0x6C2C, 0x6C2D,      0, 0xDE5F,      0, 0xDE60, 0xDE61,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E8B0[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x432B,\n 0xDE62, 0xDE63, 0x6C2E,      0,      0, 0xDE64, 0xDE65, 0x6C30,\n};\nconst unsigned short utf8_to_euc_E8B1[] = {\n      0, 0x6C2F,      0,      0,      0, 0xDE66, 0x4626, 0xDE67,\n 0x6C31, 0xDE68, 0x4B2D, 0xDE69, 0x6C32,      0, 0x6C33, 0xDE6A,\n 0x6C34, 0xDE6B,      0, 0xDE6C, 0xDE6D, 0x6C35,      0, 0xDE6E,\n 0xDE6F, 0xDE72, 0x465A, 0xDE70,      0, 0xDE71,      0,      0,\n      0, 0x3E5D, 0x6C36, 0xDE73, 0xDE74,      0, 0xDE75,      0,\n 0xDE76, 0xDE77, 0x396B, 0x502E, 0x6C37, 0xDE78,      0,      0,\n      0,      0,      0, 0xDE79,      0, 0xDE7A, 0xDE7B,      0,\n 0x6C38, 0x493F, 0x6C39, 0xDE7C, 0x6C41,      0, 0xDE7D,      0,\n};\nconst unsigned short utf8_to_euc_E8B2[] = {\n      0,      0, 0x6C3A,      0,      0, 0x6C3C, 0xDE7E, 0xDF21,\n      0, 0x6C3B, 0x6C3D, 0xDF22, 0x4B46, 0x6C3E, 0x6C3F,      0,\n 0xDF23,      0, 0xDF24, 0xDF25, 0x6C40,      0,      0,      0,\n 0x6C42, 0xDF26,      0, 0xDF27, 0xDF28, 0x332D, 0x4467,      0,\n 0x4969, 0x3A62, 0x3957,      0, 0xDF29,      0,      0, 0x494F,\n 0x325F, 0x484E, 0x6C45, 0x3453, 0x4055, 0x6C44, 0x6C49, 0x4379,\n 0x4C63,      0, 0x6C47, 0x6C48, 0x352E,      0, 0x6C4A, 0x4763,\n 0x425F, 0xDF2A, 0xDF2B, 0x4871, 0x453D, 0x6C46,      0, 0x4B47,\n};\nconst unsigned short utf8_to_euc_E8B3[] = {\n 0x326C, 0x6C4C, 0x4F28, 0x4442, 0x4F45, 0xDF2C, 0xDF2D, 0x3B71,\n 0x6C4B, 0xDF2E, 0x4231, 0xDF2F,      0, 0x6C5C, 0x4128, 0xDF30,\n      0, 0x4678,      0, 0x4950,      0, 0xDF32, 0xDF31,      0,\n      0, 0xDF33, 0x6C4F, 0x3B3F, 0x3B72, 0xDF34, 0x3E5E,      0,\n 0x4765, 0xDF35, 0x382D, 0x6C4E, 0x6C4D,      0, 0x496A,      0,\n 0xDF36,      0, 0x3C41,      0, 0xDF37, 0x4552,      0, 0xDF38,\n 0xDF39,      0, 0xDF3A,      0, 0xF467, 0xDF3B,      0, 0xDF3C,\n 0xDF3D,      0, 0x6C51, 0x6C52, 0x3958, 0x6C50, 0xDF3E, 0xDF3F,\n};\nconst unsigned short utf8_to_euc_E8B4[] = {\n      0, 0xDF40,      0, 0xDF41, 0x6C53, 0x6C54,      0, 0x6C56,\n 0x4223, 0xDF42, 0x6C55, 0x3466,      0, 0x6C58,      0, 0x6C57,\n 0x6C59,      0, 0xDF43, 0x6C5B, 0x6C5D,      0, 0x6C5E, 0xDF44,\n      0,      0,      0, 0xDF45,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E8B5[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x4056, 0xDF46, 0x3C4F, 0x6C5F,\n      0, 0xDF47,      0, 0x3352, 0xDF48, 0x6C60, 0xDF49,      0,\n 0x4176, 0x6C61,      0, 0x6C62, 0x496B,      0, 0xF468, 0x352F,\n      0,      0,      0,      0,      0,      0,      0, 0xDF4A,\n};\nconst unsigned short utf8_to_euc_E8B6[] = {\n      0, 0x6C63, 0xDF4B,      0, 0xDF4C, 0x4436,      0,      0,\n 0xDF4D,      0, 0x315B,      0,      0, 0xDF4E,      0,      0,\n 0xDF4F, 0xDF50,      0,      0,      0, 0xDF51,      0,      0,\n      0, 0x6C64,      0,      0,      0,      0, 0xDF52, 0xDF53,\n 0xDF54,      0,      0, 0x3C71,      0,      0, 0xDF55,      0,\n 0x3F76,      0,      0, 0xDF56, 0xDF57,      0,      0, 0xDF58,\n      0,      0, 0xDF59, 0x422D,      0, 0xDF5A,      0, 0xDF5B,\n      0, 0xDF5C, 0x6C67, 0xDF5D, 0xDF6F,      0, 0x6C66,      0,\n};\nconst unsigned short utf8_to_euc_E8B7[] = {\n 0xDF5E,      0, 0x6C65,      0,      0, 0xDF5F, 0xDF60, 0xDF61,\n 0xDF62,      0, 0xDF63, 0x6C6D, 0x6C6B,      0, 0xDF64, 0x6C68,\n      0, 0xDF65,      0,      0, 0xDF66, 0xDF67, 0x6C6A, 0xDF68,\n      0, 0xDF69, 0x6C69, 0x6C6C,      0, 0x3577,      0, 0x6C70,\n      0, 0x4057,      0, 0x6C71, 0xDF6A, 0xDF6B,      0, 0xDF6C,\n 0x3859,      0, 0x6C6E, 0x6C6F, 0xDF6D,      0,      0, 0x4F29,\n 0xDF6E, 0xDF70, 0xDF71, 0x4437, 0xDF72, 0x4129,      0,      0,\n      0,      0,      0,      0, 0x6C72, 0xDF73,      0, 0x6C75,\n};\nconst unsigned short utf8_to_euc_E8B8[] = {\n      0, 0xDF74,      0,      0, 0xDF75, 0xDF76, 0xDF77,      0,\n 0x6C73, 0x6C74, 0x4D59, 0xDF78,      0,      0,      0, 0x4627,\n 0x6C78, 0xDF79,      0,      0, 0xDF7A,      0, 0xDF7B,      0,\n      0,      0,      0,      0,      0, 0x6C76, 0x6C77, 0x6C79,\n 0xDF7C, 0xDF7D, 0xDF7E, 0xE021,      0,      0, 0xE022, 0xE023,\n      0,      0, 0x6D29,      0,      0,      0,      0,      0,\n 0x6C7C, 0xE024,      0, 0xE025, 0x6C7D, 0x6C7B, 0xE026, 0xE027,\n 0xE028, 0xE029,      0,      0,      0, 0xE02A,      0,      0,\n};\nconst unsigned short utf8_to_euc_E8B9[] = {\n 0xE02B, 0xE02C, 0x6C7A,      0, 0x447D,      0,      0, 0x6D21,\n 0x6D25, 0x6D22, 0x6C7E, 0xE02D, 0x6D23, 0xE02E, 0xE02F, 0xE030,\n 0x6D24,      0,      0,      0, 0xE031, 0x6D2B,      0,      0,\n      0, 0x6D26,      0, 0xE032, 0xE033, 0xE034, 0xE035, 0x4058,\n 0x6D28, 0xE036, 0xE037, 0x6D2A, 0x6D27,      0,      0,      0,\n      0, 0xE038,      0,      0, 0xE039, 0xE03A,      0, 0xE03B,\n 0xE03C, 0xE03D, 0x6D2D,      0, 0x3D33,      0, 0x6D2C,      0,\n      0, 0xE03E, 0xE03F, 0xE040, 0x6D2E,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E8BA[] = {\n      0, 0x6D2F, 0xE041, 0xE042, 0x6D32, 0x6D31,      0, 0x6D30,\n      0, 0xE043, 0x6D34, 0x6D33,      0, 0x4C76,      0,      0,\n 0xE044, 0x6D36, 0xE045, 0x6D35, 0x6D37, 0xE046,      0,      0,\n      0, 0x6D38, 0xE047, 0xE048,      0, 0xE049, 0xE04A,      0,\n      0, 0x6D3A, 0xE04B,      0,      0,      0,      0, 0xE04C,\n      0, 0xE04D, 0x6D39, 0x3F48, 0x6D3B, 0xE04E, 0xE04F, 0x366D,\n 0x6D3C, 0x6D3E,      0, 0xE050,      0, 0xE051,      0,      0,\n      0,      0, 0xE052, 0xE053,      0,      0, 0x6D3F,      0,\n};\nconst unsigned short utf8_to_euc_E8BB[] = {\n 0xE054, 0xE055,      0, 0xE056, 0xE057, 0x6D40, 0x6D3D, 0xE058,\n 0x6D41,      0, 0x3C56, 0x6D42, 0x3530, 0x3733,      0, 0xE059,\n      0, 0xE05A, 0x382E,      0, 0xE05B,      0,      0,      0,\n      0,      0,      0, 0x6D43, 0xE05C,      0,      0, 0x4670,\n      0,      0, 0x453E, 0x6D44,      0,      0,      0,      0,\n 0xE05D,      0,      0, 0x6D47,      0, 0xE064, 0xE05E,      0,\n 0xE05F, 0xE060,      0,      0,      0,      0,      0, 0xE061,\n 0x3C34, 0xE062, 0xE063, 0x6D46, 0x6D45, 0x375A, 0x6D48,      0,\n};\nconst unsigned short utf8_to_euc_E8BC[] = {\n 0xE065,      0, 0xE066, 0x3353,      0, 0x6D4A,      0, 0xE067,\n 0xE068, 0x3A5C, 0x6D49,      0, 0x6D52,      0,      0, 0xE069,\n 0xE06A,      0, 0x6D4C, 0x6D4E, 0x4A65, 0x6D4B, 0xE06B, 0xE06C,\n 0xE06D, 0x6D4D,      0, 0x6D51, 0x6D4F, 0x3531, 0xE06E, 0x6D50,\n 0xE06F, 0xE070,      0, 0xE071,      0, 0xE072, 0x6D53, 0xE073,\n 0xE074, 0x475A, 0x4E58,      0, 0xE075, 0xE076, 0xE077, 0x3D34,\n      0,      0,      0, 0x6D54, 0xE078, 0xE079, 0xE07A, 0xE07B,\n 0x4D22, 0x6D56, 0xE07C, 0x6D55,      0,      0, 0x6D59, 0x4D41,\n};\nconst unsigned short utf8_to_euc_E8BD[] = {\n 0xE07D, 0xE07E, 0x6D58, 0xE121, 0x336D, 0x6D57, 0x6D5C, 0xE122,\n      0, 0x6D5B,      0,      0, 0x6D5A, 0x4532, 0x6D5D, 0xE123,\n      0, 0xE124, 0xE125, 0xE126, 0xE127, 0xE128,      0, 0x6D5E,\n 0xE129,      0,      0,      0, 0x6D5F, 0xE12A, 0xE12B, 0x396C,\n      0, 0x3725, 0x6D60, 0x6D61, 0x6D62, 0xE12C,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E8BE[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x3F49, 0x6D63, 0xE12D, 0x3C2D, 0x6D64,\n 0xE12E, 0xE12F,      0, 0x6D65, 0xE130, 0xE131, 0xE132, 0x5221,\n 0x517E,      0,      0,      0,      0, 0x6D66, 0x6570, 0x6D67,\n 0x4324, 0x3F2B, 0x4740,      0,      0, 0xE133, 0xE134, 0x6D68,\n 0xE135,      0, 0x4A55, 0x4454, 0x397E,      0, 0xE136, 0x4329,\n};\nconst unsigned short utf8_to_euc_E8BF[] = {\n 0xE137, 0xE138, 0x312A,      0, 0x4B78, 0x3F57, 0xE139,      0,\n      0,      0, 0xE13A, 0xE13B,      0, 0xE13C, 0x375E,      0,\n 0xE13D, 0x3661, 0xE13E, 0xE13F, 0x4A56, 0xE140,      0,      0,\n      0,      0, 0x6D69,      0,      0,      0,      0,      0,\n 0xE141,      0, 0x6D6B, 0xE142, 0xE143, 0x6D6A, 0x3260,      0,\n 0xE144, 0x4676, 0x6D6C, 0x4777,      0, 0x4533, 0xE145, 0x6D6D,\n 0x3D52, 0xE146,      0,      0, 0x6D6F, 0xE147, 0xE148, 0x4C42,\n 0x6D7E, 0x6D71, 0x6D72, 0xE149,      0, 0x4449, 0xE14A,      0,\n};\nconst unsigned short utf8_to_euc_E980[] = {\n 0x4260, 0x4177, 0xE14B, 0x4628, 0xE14C, 0x6D70, 0x3555,      0,\n 0xE14D,      0,      0, 0x6D79, 0xE14E, 0x6D76, 0x6E25, 0x4629,\n 0x4360, 0x6D73,      0, 0x447E, 0x4553, 0x6D74, 0x6D78, 0x3F60,\n 0xE14F, 0x4767, 0x444C, 0xE150,      0, 0x4042, 0x6D77, 0x422E,\n 0x4224, 0x6D75, 0x3029, 0x4F22,      0,      0,      0, 0x6D7A,\n 0xE151, 0xE152, 0xE154,      0, 0xE155, 0xE156, 0x4261, 0xE153,\n      0, 0x3D35, 0x3F4A, 0xE157, 0xE158, 0x6D7C, 0x6D7B, 0xE159,\n 0x306F, 0x6D7D,      0,      0, 0x492F,      0, 0x6E27, 0xE15A,\n};\nconst unsigned short utf8_to_euc_E981[] = {\n      0, 0x465B, 0x3F6B, 0xE15B, 0xE15C, 0x4359,      0, 0x3678,\n      0, 0x6E26, 0x4D37, 0x313F, 0xE15D, 0x4A57, 0x3261, 0x6E21,\n 0x6E22, 0x6E23, 0x6E24, 0x463B, 0x4323, 0x3063, 0x6E28,      0,\n 0x6E29, 0x7423,      0, 0xE15E, 0x423D, 0xE15F, 0x6E2A,      0,\n 0x3173, 0x414C, 0xE160, 0x382F,      0, 0x4D5A, 0xE161, 0xE162,\n 0x6E2B, 0x452C,      0,      0, 0xE163, 0x4178, 0x3C57, 0x6E2C,\n 0xE164,      0, 0x6E2F,      0, 0xE165, 0x3D65, 0x6E2D, 0x412B,\n 0x412A, 0xE166, 0x3064,      0, 0x4E4B, 0x6E31,      0, 0x4872,\n};\nconst unsigned short utf8_to_euc_E982[] = {\n 0x6E33, 0x6E32, 0x6E30, 0x6364, 0x3454, 0xE167,      0, 0x6D6E,\n 0xE168, 0x6E35, 0x6E34, 0xE169, 0xE16A,      0, 0xE16B, 0x6E36,\n 0xE16C, 0x4D38,      0,      0,      0, 0xE16D,      0, 0xE16E,\n 0xE16F, 0xE170,      0, 0xE171,      0,      0,      0,      0,\n 0xE172, 0xE173, 0xE174, 0x4661,      0, 0xE175, 0x4B2E,      0,\n 0x6E37,      0, 0x3C59,      0,      0,      0,      0, 0x6E38,\n 0xE176, 0x6E39, 0xE177, 0xE178, 0xE179, 0x6E3A, 0xE17A,      0,\n 0x4521,      0,      0,      0,      0, 0xE17B, 0xE17D,      0,\n};\nconst unsigned short utf8_to_euc_E983[] = {\n      0, 0x306A,      0, 0xE17E, 0xE221, 0xE222,      0, 0xE223,\n 0xE224,      0, 0x3959,      0, 0xE17C,      0, 0x4F3A,      0,\n      0,      0, 0xE22D,      0,      0, 0xE225,      0, 0xE226,\n 0xE227, 0xE228,      0, 0x6E3E, 0xE229, 0xE22A, 0xF46C, 0xE22B,\n      0, 0x3734, 0x6E3B,      0, 0x6E3C, 0xE22C,      0,      0,\n 0x4974,      0,      0, 0xE22F,      0, 0x3354,      0, 0xE230,\n 0xE231,      0,      0,      0, 0xE232, 0x4D39, 0xE22E, 0x363F,\n      0,      0,      0,      0,      0, 0x4554, 0xE233, 0xE234,\n};\nconst unsigned short utf8_to_euc_E984[] = {\n 0xE235,      0, 0x6E3F,      0, 0xE236, 0xE237, 0xE238,      0,\n 0xE239,      0,      0,      0,      0, 0xE23A,      0,      0,\n 0xE23B,      0, 0x6E40,      0, 0xE23C, 0xF46E, 0xE23D, 0xE23E,\n 0xE23F, 0x6E41, 0xE240,      0, 0xE241,      0, 0xE242,      0,\n 0xE243,      0, 0xE245, 0xE246,      0, 0xE244,      0, 0xE247,\n      0, 0xE248,      0,      0,      0, 0x4522, 0xE249, 0xE24A,\n 0x6E43, 0xE24B, 0x6E42,      0, 0xE24C,      0, 0xE24D, 0xE24E,\n      0, 0xE24F, 0xE250,      0, 0xE251, 0xE252,      0,      0,\n};\nconst unsigned short utf8_to_euc_E985[] = {\n      0,      0,      0, 0xE253,      0,      0,      0, 0xE254,\n 0xE255, 0x4653, 0x6E44, 0x3D36, 0x3C60, 0x475B, 0x4371, 0xE256,\n      0,      0, 0x3C72, 0xE257, 0x3F6C,      0, 0x6E45, 0xE258,\n 0x6E46, 0xE259, 0xE25A, 0xE25B,      0,      0,      0,      0,\n      0, 0xE25C, 0x3F5D, 0x6E47, 0xE25D, 0x6E48,      0, 0xE25E,\n      0, 0x6E49, 0x4D6F,      0, 0x3D37, 0xE25F,      0,      0,\n      0,      0, 0x6E4B, 0x6E4A, 0xE260, 0x395A,      0, 0x3973,\n 0x3B40, 0xE261, 0xE262, 0xE263,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E986[] = {\n      0, 0xE264, 0x6E4E, 0xE265,      0, 0xE266, 0xE267, 0x3D66,\n      0, 0x6E4D, 0xE268, 0x6E4C,      0, 0x4269, 0xE269,      0,\n 0x386F, 0xE26A, 0x4043, 0xE26B, 0xE26C, 0xE26D,      0, 0x4830,\n 0xE26E,      0,      0,      0, 0x3D39,      0, 0xE26F,      0,\n      0, 0xE270, 0x6E4F,      0, 0x3E5F,      0, 0xE271,      0,\n 0xE272,      0, 0x6E52, 0x6E50, 0xE273, 0xE274, 0xE275, 0x6E51,\n 0xE276, 0xE277, 0xE278, 0xE279, 0x6E54, 0x6E53, 0xE27A,      0,\n 0x3E7A,      0, 0x6E55, 0xE27B, 0xE27C, 0xE27D,      0, 0xE27E,\n};\nconst unsigned short utf8_to_euc_E987[] = {\n 0x6E56, 0x6E57, 0xE321, 0xE322,      0, 0xE323, 0x4850, 0x3A53,\n 0x3C61, 0x6E58,      0, 0x6E59, 0x4E24, 0x3D45, 0x4C6E, 0x4E4C,\n 0x6E5A, 0x3662,      0, 0xE324, 0xE325,      0, 0x6E5B, 0xE326,\n 0x4523, 0xE327, 0xE328, 0x6E5E, 0x3378, 0x3F4B, 0xE329, 0x6E5C,\n      0, 0x6E5D,      0, 0x4460, 0xE32A, 0xE32B, 0x4B55, 0x367C,\n      0, 0xE32C, 0xE32D,      0, 0xE32E, 0xE32F, 0xE330, 0xE331,\n 0xE332, 0xE333,      0,      0,      0, 0x6E60, 0x6E61, 0xE334,\n      0, 0xE335,      0, 0xE336, 0x6E5F, 0xE337,      0, 0x6E63,\n};\nconst unsigned short utf8_to_euc_E988[] = {\n 0xE338, 0xE339,      0,      0, 0xE33A, 0xE33B, 0xE33C, 0xE33D,\n      0, 0xE33E, 0xE33F,      0, 0xE340, 0x465F, 0x3343,      0,\n 0xE341, 0x6E67, 0xE342, 0xE343, 0x6E64, 0x6E66, 0xE344,      0,\n 0xE345,      0,      0,      0, 0xE346, 0xE347, 0x6E62,      0,\n      0,      0,      0, 0xE348, 0xE349, 0xE34A, 0xE34B,      0,\n 0xE34C, 0x6F4F,      0,      0, 0x6E65,      0, 0xE34D, 0xE34E,\n 0xE34F,      0,      0, 0xE350, 0x4E6B, 0xE351, 0xE352, 0x385A,\n 0xE353, 0xE354, 0xE355,      0, 0xE356,      0, 0xE357, 0x6E6F,\n};\nconst unsigned short utf8_to_euc_E989[] = {\n 0xE358,      0, 0xE359, 0xE35A, 0x4534, 0x6E6A, 0xE35B, 0xE35C,\n 0x6E6D, 0x6E6B, 0xE35D, 0x6E70,      0, 0xE35E, 0xE35F, 0xE360,\n 0x6E71, 0xE361,      0,      0,      0,      0,      0, 0x6E69,\n 0xE362, 0xE363, 0x6E76, 0x3174, 0xE364, 0xE365, 0x6E68,      0,\n 0xE366, 0xE367, 0x482D,      0, 0x6E6C, 0xE368, 0x3E60, 0xE369,\n 0xE36A, 0xE36B,      0,      0,      0,      0, 0xE36C, 0xE36D,\n 0xE36E, 0x395B,      0,      0,      0, 0xE36F, 0xE370, 0xE371,\n 0xE372, 0xE373,      0, 0xE374, 0xE375, 0xE376, 0x4B48, 0xE377,\n};\nconst unsigned short utf8_to_euc_E98A[] = {\n 0x3664,      0,      0, 0x3D46,      0, 0x463C,      0,      0,\n 0xE378, 0xE379, 0xE37A,      0,      0, 0xE37B, 0xE37C,      0,\n      0, 0x412D, 0xE37D, 0x6E74,      0, 0x6E6E, 0x6E73, 0xE37E,\n 0x4C43, 0xE421, 0x4438, 0x6E75, 0x6E72,      0,      0, 0xE422,\n 0xE423,      0,      0,      0, 0xE424, 0xE425,      0, 0xE426,\n 0xE427,      0,      0, 0xE428,      0, 0x412C,      0, 0xE429,\n      0,      0, 0xE42A,      0,      0,      0, 0xE42B, 0x6E79,\n 0xE42C, 0x6E78, 0xE42D, 0xE42E, 0xE42F, 0xE430,      0, 0xE431,\n};\nconst unsigned short utf8_to_euc_E98B[] = {\n 0xE432, 0xE433, 0xE434, 0xE435,      0, 0xE436, 0xE437, 0xE438,\n 0xE439,      0,      0, 0xE43A, 0xE43B, 0xE43C, 0xE43D, 0x6E77,\n 0xE43E,      0, 0x4B2F, 0xE43F,      0, 0xE440,      0, 0xE441,\n 0xE442, 0xE443,      0,      0, 0xE444, 0xE445,      0, 0xE446,\n 0xE447, 0xE448,      0, 0xE449, 0x3D7B, 0xE44A,      0, 0xE44B,\n 0xE44C, 0x6E7A, 0x4A5F,      0, 0xE44D, 0x3154, 0xE44E,      0,\n 0xE44F,      0, 0x4946, 0x4372,      0,      0,      0,      0,\n 0x3578, 0xE450, 0x6E7C, 0xE451, 0x395D,      0,      0, 0xE452,\n};\nconst unsigned short utf8_to_euc_E98C[] = {\n 0xE453,      0, 0xE454,      0,      0,      0, 0x3B2C,      0,\n 0xE455,      0,      0,      0,      0, 0xE456,      0, 0x6E7B,\n 0x3F6D, 0xE457,      0,      0, 0xE458, 0xE459,      0,      0,\n 0x3F6E, 0x6F21, 0x6F23,      0, 0xE45A, 0xE45B, 0xE45C, 0xE45D,\n 0x3E7B, 0xE45E, 0x6F22, 0x6F24, 0xE45F, 0xE460, 0x3653, 0xE461,\n 0x4945, 0xE462, 0xE463, 0x3C62, 0x4F23,      0, 0x6E7E, 0x3A78,\n      0,      0, 0x4F3F, 0xE464, 0xE465, 0x6F26, 0xE466, 0xE467,\n      0,      0, 0x6F25, 0x6F27,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E98D[] = {\n      0,      0,      0,      0, 0x6E7D,      0,      0, 0xE468,\n 0xE469, 0xE46A,      0, 0x4669,      0, 0x4555,      0,      0,\n 0xE46B, 0xE46C, 0xE46D,      0, 0x4457, 0xE46E, 0x6F2C, 0xE46F,\n 0xE470,      0, 0xE471, 0x4343, 0x6F28,      0, 0xE472,      0,\n 0x6F29,      0,      0,      0, 0xE473, 0xE474,      0, 0xE475,\n      0, 0xE476, 0xE477,      0, 0x372D, 0xE478, 0x6F2B, 0xE479,\n 0xE47A, 0xE47B,      0, 0xE47C, 0xE47D, 0x3830, 0xE47E,      0,\n      0,      0, 0xE521,      0, 0x6F2A, 0xE522, 0x3E61, 0xE523,\n};\nconst unsigned short utf8_to_euc_E98E[] = {\n 0xE524, 0xE525, 0xE526,      0,      0,      0,      0,      0,\n 0xE527,      0, 0xE528, 0xE529, 0x3379, 0xE52A,      0, 0xE52B,\n      0,      0, 0xE52C,      0, 0x6F30, 0xE52D, 0x3A3F, 0x4179,\n 0xE52E,      0, 0x444A, 0xE52F,      0,      0, 0xE530,      0,\n      0, 0xE531,      0, 0xE532, 0xE533,      0, 0xE534, 0x333B,\n 0xE535, 0xE53B,      0, 0xE536, 0x6F2E, 0x6F2F, 0x4443,      0,\n 0x6F2D,      0,      0,      0, 0xE537, 0xE538, 0xE539,      0,\n      0, 0x6F31, 0xE53A,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E98F[] = {\n      0, 0xE53C,      0, 0x6F37, 0xE53D, 0xE53E, 0xE53F, 0xE540,\n 0x6F3A, 0xE541, 0xE542, 0xE543, 0xE544, 0xE545,      0,      0,\n 0x6F39, 0x452D,      0, 0xE546,      0,      0, 0x6F32, 0x6F33,\n 0x6F36, 0xE547,      0,      0, 0xE548, 0x6F38, 0xE549, 0xE54A,\n      0, 0x3640, 0xE54B,      0, 0x6F3B, 0x6F35, 0xE54C, 0xE54D,\n 0x6F34,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xE54F,\n 0xE550, 0xE54E, 0xE551, 0xE552,      0, 0xE553,      0,      0,\n};\nconst unsigned short utf8_to_euc_E990[] = {\n      0, 0xE554, 0xE555, 0x6F3F, 0xE556,      0,      0, 0x6F40,\n 0xE557, 0xE558,      0,      0,      0, 0xE559, 0xE55A, 0xE55B,\n 0x6F41,      0,      0, 0x6F3E, 0x6F3D, 0xE55C, 0xE55D, 0xE55E,\n 0x3E62, 0x462A, 0x6F3C,      0,      0,      0,      0, 0xE55F,\n      0, 0x6F45,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x6F43,      0,      0, 0xE560, 0xE561,\n      0, 0xE562, 0xE563, 0xE564, 0xE565, 0x6F44, 0x6F42,      0,\n 0x4278,      0, 0x6F46, 0xE566,      0, 0xE568,      0, 0xE567,\n};\nconst unsigned short utf8_to_euc_E991[] = {\n      0, 0x6F47,      0, 0xE569, 0x6F49, 0xE56A,      0,      0,\n 0xE56B,      0, 0xE56C,      0, 0xE56D,      0,      0,      0,\n      0, 0x3455, 0x6F48, 0x4C7A,      0, 0xE56E,      0,      0,\n      0, 0xE56F, 0x6F54, 0x6F4A, 0xE570,      0, 0x6F4D, 0xE571,\n 0x6F4B, 0xE572, 0x6F4C, 0xE573,      0,      0,      0,      0,\n 0xE574,      0, 0x6F4E, 0xE575,      0, 0xE576, 0xE577, 0xE578,\n 0x6F50, 0xE579, 0xE57A,      0,      0, 0x6F51,      0, 0x6F52,\n      0,      0,      0,      0, 0x6F55, 0x6F53, 0x6F56, 0x6F58,\n};\nconst unsigned short utf8_to_euc_E992[] = {\n      0, 0x6F57,      0, 0xE57C, 0xE57B,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E995[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0x4439,\n 0xE57D, 0xE57E,      0,      0,      0,      0, 0xE621,      0,\n};\nconst unsigned short utf8_to_euc_E996[] = {\n 0x4C67,      0, 0x6F59, 0x412E, 0xE622,      0,      0, 0x6F5A,\n 0xE623, 0x4A44, 0x6F5B, 0x332B, 0xE624, 0xE625, 0xE626, 0x313C,\n      0, 0x3457, 0xF471, 0x3456, 0x6F5C,      0, 0x6F5D,      0,\n 0x6F5E, 0x6F5F,      0,      0,      0, 0xE627, 0xE628, 0xE629,\n 0x6F60, 0xE62A, 0x3458, 0x3355, 0x395E, 0x4836, 0xE62B, 0x6F62,\n 0x6F61, 0xE62C,      0, 0xE62D, 0xE62E, 0x6F63,      0,      0,\n      0,      0, 0x315C,      0, 0xE62F,      0, 0xE630,      0,\n      0, 0x6F66, 0xE631, 0x6F65, 0x6F64, 0xE632, 0x6F67, 0xE633,\n};\nconst unsigned short utf8_to_euc_E997[] = {\n      0,      0,      0, 0x6F6A,      0,      0, 0xE634, 0x3047,\n 0xE635, 0xE636, 0x6F68, 0xE637, 0x6F6C, 0x6F6B,      0,      0,\n 0xE638, 0xE639, 0xE63A, 0xE63B, 0x6F6E, 0x6F6D, 0x6F6F,      0,\n 0x462E, 0xE63C, 0xE63D,      0, 0x6F70, 0xE63E, 0xE63F, 0xE640,\n 0xE641, 0x6F71, 0x6F73,      0, 0xE642, 0x6F72, 0xE643,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E998[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0x496C, 0xE644, 0xE645,      0,\n      0, 0x6F74, 0xE646,      0, 0xE647, 0xE648, 0xE649,      0,\n 0x6F75,      0, 0x3A65,      0, 0xE64A,      0, 0x6F76, 0x6F77,\n      0, 0xE64B, 0x4B49, 0xE64C,      0,      0,      0, 0xE64D,\n 0xE64E, 0xE64F, 0xE650, 0x414B, 0xE651, 0xE652,      0, 0x3024,\n};\nconst unsigned short utf8_to_euc_E999[] = {\n 0x424B, 0xE653, 0x6F78,      0, 0x496D,      0,      0,      0,\n      0,      0,      0, 0x6F7B, 0x6F79, 0x395F,      0, 0x6F7A,\n 0x3842,      0, 0xE654,      0, 0xE655,      0, 0xE656, 0xE657,\n 0xE658,      0,      0, 0x4A45, 0x6F7D, 0x7021, 0x6F7E, 0x7022,\n      0, 0xE659, 0x3121, 0x3F58, 0x3D7C, 0x3459, 0x7023,      0,\n      0,      0, 0x4766,      0, 0x7025,      0, 0xE65A,      0,\n 0x3122,      0, 0x7024, 0x4444, 0xE65B, 0x4E4D, 0x462B, 0x6F7C,\n 0x4E26,      0, 0x3831, 0xE65C, 0xE65D, 0x4D5B, 0xE65E, 0xE65F,\n};\nconst unsigned short utf8_to_euc_E99A[] = {\n      0, 0xE660, 0xE661, 0xE662, 0xE663, 0x3679, 0x4E34,      0,\n 0x3728, 0xE664, 0x4262, 0x6721,      0, 0x7026, 0x332C, 0x3F6F,\n      0, 0xE665,      0,      0, 0x3356, 0x7028, 0xE666, 0x7029,\n 0x7027, 0x3764, 0xE667, 0x3A5D, 0x3E63, 0xE668,      0, 0xE669,\n 0x3123,      0,      0, 0x4E59, 0xE66A, 0xE66B, 0xE66C, 0x702B,\n 0x6E2E, 0xE66D, 0x702A,      0,      0,      0, 0xE66E, 0xE66F,\n 0x702E, 0x702C, 0x702D, 0xE670, 0x702F,      0, 0x7030, 0x4E6C,\n 0x7031, 0x7032, 0xE671, 0x4049, 0x483B,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E99B[] = {\n 0x3F7D, 0x3467,      0,      0, 0x4D3A, 0x326D, 0x3D38, 0x385B,\n      0, 0x7035, 0xE672, 0x7034, 0x3B73, 0x7036, 0x7033,      0,\n      0, 0x3B28, 0xE673,      0,      0, 0x703A, 0x6A2D,      0,\n 0xE675, 0x5256, 0xE676, 0x3F77, 0x7038, 0xE677, 0xE678, 0xE679,\n      0,      0, 0x4E25, 0x4671,      0,      0,      0,      0,\n 0x312B, 0xE67A, 0x4063, 0x3C36,      0,      0,      0, 0xE67B,\n 0x4A37, 0xE67C, 0x3140,      0,      0,      0, 0x4E6D, 0x4D6B,\n      0, 0x703B, 0xE67D, 0x4545,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E99C[] = {\n 0x3C7B,      0, 0xE67E, 0xE721, 0x703C, 0xE722, 0x703D, 0x3F4C,\n 0x703E, 0xE723, 0x4E6E,      0,      0, 0x7039, 0x7040, 0x7042,\n      0, 0x7041,      0, 0x703F,      0,      0, 0x7043,      0,\n      0, 0x7044, 0xE724, 0xE725, 0x417A, 0xE726, 0x3262,      0,\n      0, 0xE727, 0xE728, 0xE729, 0x7045,      0,      0, 0x4C38,\n 0xE72A,      0, 0x7046,      0,      0,      0,      0,      0,\n 0x7047, 0xE72B, 0x4F2A, 0xE72C,      0,      0,      0,      0,\n 0x5B31, 0x7048,      0, 0xF474,      0, 0x7049, 0x704A,      0,\n};\nconst unsigned short utf8_to_euc_E99D[] = {\n      0, 0xE72D, 0x704E, 0xE72E, 0x704B,      0, 0x704C,      0,\n 0x704D, 0x704F, 0xE72F,      0,      0, 0xF475, 0xE730, 0xE731,\n      0, 0xF476, 0x4044,      0,      0, 0xE732, 0x4C77, 0xE733,\n 0xE734, 0x4045, 0xE735, 0xE736, 0x7050,      0, 0x4873,      0,\n 0x7051, 0x7353, 0x4C4C, 0xE737, 0x7052,      0, 0x7053, 0xE738,\n 0x7054, 0x3357, 0xE739, 0x7056,      0, 0x3F59, 0xE73A,      0,\n      0, 0x7057,      0, 0xE73B, 0x3724,      0, 0xE73C, 0xE73D,\n 0xE73E, 0x7058, 0x705C, 0xE73F, 0x705A, 0xE740,      0, 0xE741,\n};\nconst unsigned short utf8_to_euc_E99E[] = {\n 0xE742, 0x705B,      0,      0, 0x3373, 0x7059, 0x705D,      0,\n      0, 0xE743,      0, 0x705E,      0, 0x3048,      0, 0x705F,\n 0x7060,      0,      0,      0,      0, 0xE744, 0xE745, 0xE746,\n 0x3E64, 0xE747, 0xE748,      0, 0x7061,      0, 0xE749, 0xE74A,\n 0x3547,      0, 0xE74B, 0x7064,      0,      0, 0x7063,      0,\n 0x7062,      0,      0, 0x6B71, 0xE74C, 0x4A5C, 0xE74D,      0,\n      0, 0xE74E, 0xE74F, 0x7065, 0x7066, 0xE750, 0xE751,      0,\n 0xE752, 0xE753, 0xE754,      0, 0xE755,      0, 0xE756, 0xE757,\n};\nconst unsigned short utf8_to_euc_E99F[] = {\n      0, 0xE758,      0, 0x7067, 0xE759, 0xE75A, 0x7068, 0xE75B,\n 0x7069, 0xE75C, 0xE75D, 0x706A, 0xE75E, 0xE75F, 0xE760,      0,\n 0xE761, 0xE762,      0, 0x345A, 0xE763,      0,      0, 0xE764,\n 0xE765, 0xE766,      0, 0xE76A, 0x706B, 0xE767, 0xE768,      0,\n 0xE769, 0xE76B,      0,      0, 0xE76C,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x706C, 0x4723, 0xE76D,\n      0, 0xE76E, 0x706E, 0x323B, 0xE76F, 0x7071, 0x7070, 0xE770,\n 0xE771,      0, 0xE772, 0x3124,      0,      0,      0, 0x3641,\n};\nconst unsigned short utf8_to_euc_E9A0[] = {\n      0, 0x4A47, 0x443A, 0x3A22,      0, 0x3960, 0x3D67, 0xE773,\n 0x3F5C,      0, 0xE774,      0, 0x7073, 0xE776, 0xE777, 0x7072,\n 0x4D42, 0x3468, 0x4852, 0x465C, 0xE778,      0, 0xE779, 0x3F7C,\n 0x4E4E, 0xE775, 0x375B,      0, 0xE77A,      0, 0xE77B,      0,\n 0xE77C, 0x7076,      0, 0xE77D, 0x7075, 0xE828, 0xE77E,      0,\n      0,      0,      0, 0xE821, 0x4B4B, 0x462C, 0xE822, 0xE823,\n 0xE824,      0, 0xE825, 0xE826, 0x3150, 0xE827,      0, 0x7077,\n 0x7074,      0,      0, 0x4951, 0x4D6A, 0x7078, 0xE829,      0,\n};\nconst unsigned short utf8_to_euc_E9A1[] = {\n      0,      0,      0,      0, 0xE82A,      0, 0x7079, 0xE82B,\n      0,      0, 0xE82C, 0x707B, 0x426A, 0x335B, 0x335C, 0x707A,\n      0, 0xE82D, 0xE82E, 0xE82F, 0x3469, 0x3832, 0xE830, 0xE831,\n 0x346A, 0xE832, 0xE833, 0x453F,      0,      0, 0x4E60,      0,\n      0,      0, 0xE834, 0xE835,      0, 0xE836, 0xE837, 0x385C,\n      0,      0, 0xE838, 0x707C, 0xE839,      0,      0, 0x707D,\n 0x707E, 0x7121,      0, 0x7123, 0x7122,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9A2[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x4977,      0, 0x7124, 0xE83A,      0, 0xE83B, 0xE83C, 0x7125,\n 0xE83D, 0x7126,      0,      0, 0xE83E,      0, 0x7127, 0xE83F,\n 0xE840,      0, 0xE841, 0xE842,      0,      0,      0, 0xE843,\n};\nconst unsigned short utf8_to_euc_E9A3[] = {\n      0,      0, 0xE844, 0x7129, 0x7128, 0xE845, 0x712A,      0,\n 0xE846,      0,      0,      0, 0xE847,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0x4874, 0x664C,      0,      0, 0x3F29,\n      0, 0xE848, 0x3532, 0xE849,      0, 0xE84A, 0xE84B, 0xE84C,\n      0, 0x712B, 0xE84D, 0x712C,      0, 0x522C, 0x5D3B, 0x4853,\n      0,      0, 0x307B, 0xE84E, 0x303B,      0, 0xE84F,      0,\n      0,      0,      0,      0, 0x3B74, 0x4B30, 0x3E7E,      0,\n};\nconst unsigned short utf8_to_euc_E9A4[] = {\n      0,      0, 0xE850, 0x712D,      0, 0x4C5F,      0, 0xE851,\n 0xE852, 0x712E, 0x4D5C,      0, 0x3142,      0,      0,      0,\n 0x3B41, 0xE853, 0x712F, 0x326E, 0x7130, 0xE854, 0xE855, 0xE856,\n 0x7131,      0, 0xE857, 0xE858, 0xE859, 0x7133, 0x7134, 0xE85A,\n 0x7136, 0x7132, 0xE85B,      0, 0x7135,      0, 0xE85C, 0xE85D,\n 0x345B,      0,      0, 0xE85E, 0x7137,      0, 0x7138,      0,\n      0, 0xE85F, 0xE860, 0xE861, 0xE862, 0xE863,      0,      0,\n      0, 0xE864, 0xE865, 0xE866, 0xE867, 0x7139, 0x713A,      0,\n};\nconst unsigned short utf8_to_euc_E9A5[] = {\n 0xE868, 0xE869, 0x713B,      0,      0, 0x713D, 0xE86A, 0xE86B,\n 0xE86C, 0x713C,      0, 0x713F, 0x7142, 0xE86D, 0xE86E,      0,\n 0x713E, 0x7140, 0x7141,      0, 0xE86F, 0x7143,      0, 0x3642,\n 0xE870, 0xE871,      0, 0xE872, 0xE873,      0, 0xE874, 0xE875,\n 0xE876,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9A6[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0x3C73, 0x7144,\n 0x7145, 0x3961,      0, 0xE877,      0, 0xE878, 0xF47A, 0xE879,\n      0,      0,      0,      0,      0, 0x7146, 0xE87A,      0,\n 0x333E,      0,      0,      0, 0x474F, 0x7147, 0x7148,      0,\n 0xE87B, 0xE87C, 0xE87D, 0x435A, 0x466B, 0xE87E,      0,      0,\n      0, 0xE921, 0xE922,      0, 0x7149, 0xE923,      0, 0xE924,\n};\nconst unsigned short utf8_to_euc_E9A7[] = {\n      0, 0x477D,      0, 0xE925, 0x424C, 0x3158, 0x366E,      0,\n 0x366F, 0xE926,      0,      0,      0,      0,      0,      0,\n 0x4373, 0x714E, 0x3670, 0xE927, 0xE928, 0x326F,      0,      0,\n 0x714D, 0xE929, 0xE92A, 0x714B, 0xE92B, 0x714C, 0xE92C, 0x714A,\n      0,      0, 0x7158,      0,      0,      0,      0, 0xE92D,\n      0,      0, 0xE92E, 0xE92F, 0xE930, 0x714F, 0x7150,      0,\n 0xE931, 0x7151, 0x7152,      0, 0xE932, 0xE933,      0,      0,\n 0x7154, 0xE934,      0, 0x7153,      0, 0xE935, 0xE936, 0x3D59,\n};\nconst unsigned short utf8_to_euc_E9A8[] = {\n      0, 0x7155, 0xE937, 0xE938, 0xE939, 0x7157,      0,      0,\n      0,      0,      0, 0xE93A, 0xE93B,      0, 0x3533, 0x7156,\n 0xE93C, 0xE93D, 0x417B, 0x3833,      0,      0, 0xE93E,      0,\n      0, 0x7159,      0,      0,      0,      0, 0xE93F,      0,\n 0xE940,      0, 0xE941, 0xE942, 0xE943,      0,      0, 0xE944,\n 0x424D,      0,      0, 0x715A,      0, 0xE945, 0xE946,      0,\n 0x462D,      0,      0, 0xE947,      0, 0xE948, 0xE949, 0x715B,\n 0xE94A,      0,      0,      0,      0,      0, 0x7160,      0,\n};\nconst unsigned short utf8_to_euc_E9A9[] = {\n 0x715E, 0xE94C, 0x715D, 0x715F, 0xE94D, 0x715C,      0, 0xE94B,\n      0,      0, 0xE94E, 0xE94F, 0xE950, 0x7162, 0xE951,      0,\n      0, 0xE952,      0,      0, 0xE953, 0x7161, 0xE954, 0x7164,\n      0,      0, 0x3643, 0x7163,      0, 0xE955,      0, 0x7165,\n      0,      0, 0x7166,      0, 0x7168, 0x7167,      0,      0,\n      0, 0x7169, 0x716B, 0x716A,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9AA[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x397C,      0, 0xE956,      0, 0xE957, 0x716C, 0xE958, 0xE959,\n 0x716D,      0, 0xE95A,      0, 0xE95B, 0xE95C, 0xE95D,      0,\n 0x333C, 0xE95E,      0, 0xE95F, 0x716E,      0, 0xE960, 0xE961,\n};\nconst unsigned short utf8_to_euc_E9AB[] = {\n 0x716F, 0xE962,      0, 0xE963, 0x3F71,      0, 0xE964,      0,\n 0xE965,      0,      0,      0,      0,      0, 0xE966, 0x7170,\n 0xE967, 0x7171, 0xE968, 0x7172, 0x7173, 0xE969, 0xE96A, 0xE96B,\n 0x3962, 0xF47B,      0, 0xE96C, 0xE96D,      0, 0x7174, 0x7175,\n 0xE96E,      0, 0x7176, 0x7177, 0xE96F, 0xE970, 0x7178, 0xE971,\n      0, 0xE972, 0x4831, 0x717A, 0xE973, 0x4926, 0x717B, 0x7179,\n      0, 0x717D, 0xE974, 0xE975, 0x717C, 0xE976,      0, 0x717E,\n      0, 0xE977, 0xE978, 0x7221,      0, 0xE979,      0, 0xE97A,\n};\nconst unsigned short utf8_to_euc_E9AC[] = {\n 0xE97B, 0xE97C, 0xE97D, 0xE97E, 0xEA21, 0xEA22, 0x7222,      0,\n 0xEA23, 0xEA24,      0, 0xEA25, 0xEA26, 0xEA27, 0xEA28,      0,\n 0xEA29,      0, 0xEA2A,      0,      0,      0, 0xEA2B,      0,\n 0x7223, 0xEA2C, 0x7224, 0xEA2D, 0xEA2E,      0,      0, 0x7225,\n 0xEA2F,      0, 0x7226, 0x7227,      0, 0x7228, 0xEA30, 0x7229,\n 0x722A, 0x722B, 0x722C, 0xEA31,      0, 0xEA32, 0x722D, 0x722E,\n      0, 0x5D35, 0x722F, 0xEA33, 0xEA34, 0xEA35,      0, 0xEA36,\n      0, 0xEA37, 0xEA38, 0x6478, 0x3534, 0xEA39,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9AD[] = {\n      0, 0x3321, 0x3A32, 0x7231, 0x7230, 0x4C25,      0,      0,\n 0xEA3A,      0,      0, 0xEA3B, 0xEA3C, 0x7233, 0x7234, 0x7232,\n      0, 0x7235,      0,      0, 0x4B62, 0xEA3D, 0xEA3E, 0xEA3F,\n 0x7236,      0, 0x357B, 0xEA40,      0,      0, 0xEA41,      0,\n      0, 0xEA42,      0, 0xEA43,      0, 0xEA44, 0xEA45,      0,\n 0xEA46,      0, 0xEA47, 0xEA48, 0xEA49, 0xEA4A, 0xEA4B, 0x4F25,\n      0,      0, 0xF47C, 0xEA4C, 0x7237, 0xEA4D,      0, 0xEA4E,\n 0xEA4F, 0xEA50,      0,      0,      0,      0,      0, 0xEA51,\n};\nconst unsigned short utf8_to_euc_E9AE[] = {\n 0xEA52,      0,      0, 0x7239, 0xEA53, 0xEA54, 0xEA55, 0xEA56,\n      0, 0xEA57, 0xEA58, 0xEA59,      0, 0xEA5A, 0x303E, 0xEA5B,\n 0xEA5C, 0x723A, 0x4A2B, 0x7238, 0xEA5D,      0, 0x723B, 0x723C,\n      0,      0, 0xEA5E,      0,      0, 0xEA5F, 0xEA60, 0x723D,\n 0x723E,      0,      0,      0,      0,      0, 0xEA61, 0xEA62,\n 0x723F, 0xEA63, 0x4B6E, 0x3B2D, 0xEA64, 0x3A7A, 0x412F,      0,\n 0xEA65, 0xEA66, 0xEA67,      0, 0x7240,      0,      0, 0xEA68,\n 0xEA69, 0x7243,      0, 0xEA6A, 0xEA6B,      0, 0xEA6C, 0xEA6D,\n};\nconst unsigned short utf8_to_euc_E9AF[] = {\n 0x7241, 0xEA6E,      0,      0,      0,      0, 0x7244, 0xEA6F,\n 0xEA70, 0x3871, 0x7242,      0,      0,      0, 0xEA71, 0x7245,\n 0xEA72, 0x7246, 0x7247,      0, 0x724B,      0, 0x3B2A, 0xEA73,\n 0xEA74,      0,      0, 0x4264,      0, 0xEA75,      0, 0xEA76,\n      0, 0x724C, 0x7249, 0x7248, 0x724A, 0xEA77,      0, 0xEA78,\n 0x375F,      0, 0xEA79, 0xEA7A,      0,      0,      0, 0xEA7B,\n 0x7250, 0x724F, 0x724E, 0xEA7C,      0, 0x3033,      0, 0xEA7D,\n 0xEA7E, 0xEB21, 0xEB22,      0,      0, 0xEB23,      0, 0xEB24,\n};\nconst unsigned short utf8_to_euc_E9B0[] = {\n 0xEB25,      0, 0xEB26,      0, 0x725A,      0, 0x7256,      0,\n 0x7257, 0x7253, 0x7259, 0xEB27, 0x7255, 0x3362,      0, 0xEB28,\n 0x4F4C, 0xEB29, 0x7258, 0x7254, 0x7252, 0x7251, 0xEB2A,      0,\n 0xEB2B, 0xEB2C, 0xEB2D, 0x725C, 0xEB2E,      0, 0xEB2F,      0,\n      0, 0x725F, 0xEB30, 0xEB31, 0x725E, 0x725D, 0xEB32, 0xEB33,\n 0xEB34, 0xEB35, 0xEB36,      0,      0, 0x4949, 0x725B, 0x3073,\n 0x7260, 0xEB37, 0x7262,      0,      0, 0xEB38, 0xEB39, 0xEB3A,\n      0, 0x336F, 0x724D, 0x3137,      0, 0xEB3B, 0x7264,      0,\n};\nconst unsigned short utf8_to_euc_E9B1[] = {\n      0, 0xEB3C,      0, 0xEB3D, 0xEB3E, 0xEB3F, 0x7263, 0x7261,\n 0x432D, 0xEB40, 0xEB41,      0,      0,      0, 0xEB42, 0xEB43,\n 0xEB44,      0, 0x4B70, 0xEB45, 0xEB46,      0, 0xEB47, 0x4E5A,\n 0xEB48,      0, 0x7265, 0xEB49, 0xEB50, 0xEB4A, 0xEB4B, 0xEB4C,\n 0x7266,      0,      0, 0xEB4D,      0,      0,      0, 0x7267,\n 0xEB52, 0xEB4E, 0xEB4F, 0xEB51,      0,      0, 0xEB53,      0,\n 0xEB54,      0, 0xEB55,      0,      0, 0xEB56, 0x7268, 0xEB57,\n 0x7269,      0,      0, 0xEB58,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9B3[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x443B, 0xEB59, 0x726A,\n      0, 0x4837,      0, 0x726F, 0x726B,      0,      0,      0,\n 0x726C,      0, 0xEB5A, 0x4B31, 0x4C44,      0, 0x4650, 0xEB5B,\n      0, 0xEB5C,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9B4[] = {\n      0,      0, 0xEB5E, 0x7270,      0,      0, 0x7271, 0x463E,\n 0x726E, 0x726D,      0, 0xEB5D,      0,      0, 0x322A,      0,\n      0, 0xEB5F, 0x7279,      0,      0, 0x7278,      0, 0xEB60,\n 0xEB61,      0,      0, 0x3175, 0xEB62, 0xEB63, 0xEB64, 0x7276,\n      0,      0,      0, 0x7275,      0,      0, 0x7273,      0,\n 0x337B,      0, 0x7272, 0x3C32, 0x3229,      0,      0, 0xEB65,\n 0xEB66,      0, 0xEB67, 0xEB68, 0xEB69,      0,      0,      0,\n      0,      0, 0xEB6A, 0x3963, 0xEB6B, 0xEB6D, 0x727C, 0x727B,\n};\nconst unsigned short utf8_to_euc_E9B5[] = {\n      0, 0x727A, 0xEB6E, 0xEB6F, 0x7277, 0xEB6C, 0x727D, 0xEB70,\n 0x727E,      0, 0xEB71,      0,      0,      0,      0,      0,\n 0x7325, 0x7324,      0, 0xEB72, 0xEB73,      0,      0,      0,\n      0, 0x7326,      0,      0, 0x312D, 0x7321, 0x7322, 0xEB74,\n 0x3974, 0x4C39, 0xEB76, 0xEB75, 0x7323, 0xEB77,      0,      0,\n      0, 0xEB78, 0xEB79, 0xEB7A, 0x4B32,      0,      0, 0x732B,\n 0xEB7B,      0, 0x7327,      0,      0,      0, 0xEB7C, 0xEB7D,\n      0,      0, 0x732C, 0xEB7E, 0xEC21,      0, 0xEC22,      0,\n};\nconst unsigned short utf8_to_euc_E9B6[] = {\n      0,      0,      0, 0xEC23, 0xEC24,      0, 0xEC25, 0x7329,\n      0, 0x7328, 0xEC26,      0,      0, 0xEC27, 0xEC28, 0x375C,\n      0,      0, 0xEC29, 0xEC2A,      0, 0xEC2B, 0xEC2C, 0xEC2D,\n 0xEC2E,      0, 0x732D,      0,      0,      0,      0,      0,\n      0, 0xEC2F,      0,      0, 0x732E,      0,      0,      0,\n      0, 0x732F, 0xEC30, 0x732A, 0xEC31,      0, 0xEC32, 0x7274,\n      0, 0xEC33, 0x7330,      0, 0x4461, 0xEC34,      0,      0,\n 0x7334, 0xEC35, 0x7335, 0x7333, 0xEC36,      0,      0, 0xEC37,\n};\nconst unsigned short utf8_to_euc_E9B7[] = {\n      0, 0x7332, 0x7338, 0xEC38, 0x7331,      0, 0x7336, 0xEC39,\n      0, 0xEC3A, 0xEC3B,      0,      0,      0,      0, 0x7337,\n      0,      0,      0, 0x733A, 0xEC3C, 0xEC3D, 0xEC3E, 0xEC3F,\n      0, 0x7339, 0xEC40,      0,      0,      0, 0xEC41, 0xEC42,\n 0xEC43,      0,      0,      0,      0, 0xEC44, 0x733C, 0xEC45,\n      0, 0xEC46,      0, 0xEC47,      0, 0x733D, 0xEC48, 0x733E,\n 0xEC49,      0, 0x4F49, 0xEC4A, 0xEC4B,      0,      0,      0,\n 0x733B, 0x426B, 0x3A6D,      0,      0, 0x733F, 0xEC4C,      0,\n};\nconst unsigned short utf8_to_euc_E9B8[] = {\n      0,      0, 0xEC4E,      0,      0,      0,      0, 0xEC4F,\n      0,      0, 0xEC4D,      0,      0,      0, 0xEC50,      0,\n 0xEC51, 0xEC52, 0xEC53,      0,      0, 0xEC54, 0xEC55,      0,\n      0, 0xEC56, 0x7340, 0x7341, 0xEC57, 0xEC58, 0x7342,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9B9[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x7343,      0,      0,\n 0x3834, 0x7344, 0xEC59, 0xEC5A, 0xEC5B, 0x7345,      0, 0x3C2F,\n};\nconst unsigned short utf8_to_euc_E9BA[] = {\n 0xEC5C, 0x7346, 0xEC5D, 0xEC5E, 0xEC5F, 0xEC60,      0, 0xEC61,\n 0x7347,      0,      0, 0x7348, 0x7349,      0, 0xEC62, 0xEC63,\n      0, 0x734C, 0x734A, 0x4F3C,      0, 0x734B, 0xEC64, 0x4E6F,\n 0xEC65,      0,      0, 0xEC66,      0, 0x734D, 0xEC67, 0x4E5B,\n      0,      0,      0,      0, 0xEC68, 0x734E, 0x477E,      0,\n 0xEC69, 0x734F, 0x7351,      0, 0xEC6A, 0x7352, 0xEC6B, 0xEC6C,\n 0xEC6D,      0,      0, 0xEC6E, 0xEC6F, 0xEC70,      0,      0,\n 0x7350, 0x396D, 0x4C4D, 0x4B63, 0x5677,      0, 0x5D60, 0x4B7B,\n};\nconst unsigned short utf8_to_euc_E9BB[] = {\n      0,      0,      0,      0, 0x322B,      0, 0xEC71,      0,\n 0xEC72,      0,      0, 0xEC73, 0x7354, 0x3550, 0x7355, 0x7356,\n 0x7357, 0xF47E, 0x3975,      0, 0x7358, 0xEC74,      0,      0,\n 0x6054, 0x4C5B,      0, 0x4263, 0x7359, 0x735B, 0x735A, 0xEC75,\n 0x735C,      0,      0,      0, 0xEC76, 0x735D,      0, 0xEC77,\n 0x735E,      0,      0,      0, 0xEC78, 0xEC79, 0xEC7A, 0x735F,\n 0xEC7B, 0xEC7C, 0xEC7D,      0, 0x7360, 0xEC7E, 0x7361, 0x7362,\n 0xED21, 0x7363,      0, 0x7364, 0x7365, 0x7366,      0, 0xED22,\n};\nconst unsigned short utf8_to_euc_E9BC[] = {\n      0,      0, 0xED23, 0xED24,      0,      0,      0, 0x7367,\n 0x7368, 0xED25,      0,      0,      0,      0, 0x4524, 0xED26,\n 0xED27, 0xED28, 0xED29, 0x385D, 0xED2A, 0x736A, 0xED2B, 0xED2C,\n      0, 0xED2D, 0xED2E, 0xED2F,      0,      0,      0, 0xED30,\n 0x414D, 0x736B, 0xED31,      0,      0,      0, 0xED32,      0,\n      0,      0, 0xED33, 0xED34, 0x736C,      0,      0, 0xED35,\n      0, 0xED36, 0xED37,      0, 0xED38,      0,      0, 0xED39,\n      0, 0xED3A, 0xED3B, 0x4921, 0xED3C, 0xED3D, 0x736D, 0xED3E,\n};\nconst unsigned short utf8_to_euc_E9BD[] = {\n      0, 0xED3F,      0, 0xED40, 0xED41, 0xED42, 0xED43, 0xED44,\n      0,      0, 0x736E, 0x6337,      0,      0, 0x6C5A, 0x706D,\n      0,      0, 0x736F, 0xED45, 0x7370, 0xED46, 0xED47, 0xED48,\n 0xED49,      0, 0xED4A,      0,      0, 0xED4B, 0xED4C, 0x7372,\n 0x7373, 0x7374, 0x4E70, 0x7371,      0,      0, 0x7375, 0x7376,\n 0xED4D, 0xED4E, 0x7378,      0, 0x7377, 0xED4F, 0xED50, 0xED51,\n 0xED52, 0xED53, 0x737A, 0xED54,      0, 0xED55, 0x737B, 0x7379,\n      0,      0, 0xED56,      0,      0, 0xED57,      0,      0,\n};\nconst unsigned short utf8_to_euc_E9BE[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0x4E36,      0, 0xED58,\n 0xED59, 0xED5A, 0xED5B,      0, 0xED5C, 0x737C, 0xED5D, 0xED5E,\n      0,      0,      0,      0, 0x737D, 0x6354, 0xED5F,      0,\n 0x737E, 0xED60, 0xED61, 0xED62,      0, 0xED63,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_EFA4[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xF445,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_EFA7[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xF472,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_EFA8[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xF434, 0xF437,\n 0xF438, 0xF43D, 0xF444, 0xF447, 0xF448, 0xF44E, 0xF44F, 0xF453,\n 0xF455, 0xF456, 0xF457, 0xF458, 0xF45A, 0xF45B, 0xF45E, 0xF460,\n 0xF462, 0xF463, 0xF465, 0xF469, 0xF46A, 0xF46B, 0xF46D, 0xF46F,\n 0xF470, 0xF473, 0xF477, 0xF478, 0xF479, 0xF47D,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_EFBC[] = {\n      0, 0x212A, 0xF42A, 0x2174, 0x2170, 0x2173, 0x2175, 0xF429,\n 0x214A, 0x214B, 0x2176, 0x215C, 0x2124, 0x215D, 0x2125, 0x213F,\n 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337,\n 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129,\n 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347,\n 0x2348, 0x2349, 0x234A, 0x234B, 0x234C, 0x234D, 0x234E, 0x234F,\n 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357,\n 0x2358, 0x2359, 0x235A, 0x214E, 0x2140, 0x214F, 0x2130, 0x2132,\n};\nconst unsigned short utf8_to_euc_EFBD[] = {\n 0x212E, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367,\n 0x2368, 0x2369, 0x236A, 0x236B, 0x236C, 0x236D, 0x236E, 0x236F,\n 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377,\n 0x2378, 0x2379, 0x237A, 0x2150, 0x2143, 0x2151, 0xA237,      0,\n      0, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,\n 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,\n 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,\n 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F,\n};\nconst unsigned short utf8_to_euc_EFBD_ms[] = {\n 0x212E, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367,\n 0x2368, 0x2369, 0x236A, 0x236B, 0x236C, 0x236D, 0x236E, 0x236F,\n 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377,\n 0x2378, 0x2379, 0x237A, 0x2150, 0x2143, 0x2151, 0x2141,      0,\n      0, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,\n 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,\n 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,\n 0x0E38, 0x0E39, 0x0E3A, 0x0E3B, 0x0E3C, 0x0E3D, 0x0E3E, 0x0E3F,\n};\nconst unsigned short utf8_to_euc_EFBE[] = {\n 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,\n 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,\n 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,\n 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0E5C, 0x0E5D, 0x0E5E, 0x0E5F,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short utf8_to_euc_EFBF[] = {\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0x2171, 0x2172, 0x224C, 0x2131, 0xA243, 0x216F,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short *const utf8_to_euc_E2[] = {\n utf8_to_euc_E280,                0,                0,                0,\n utf8_to_euc_E284, utf8_to_euc_E285, utf8_to_euc_E286, utf8_to_euc_E287,\n utf8_to_euc_E288, utf8_to_euc_E289, utf8_to_euc_E28A,                0,\n utf8_to_euc_E28C,                0,                0,                0,\n                0, utf8_to_euc_E291,                0,                0,\n utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297,\n utf8_to_euc_E298, utf8_to_euc_E299,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n};\nconst unsigned short *const utf8_to_euc_E2_ms[] = {\n utf8_to_euc_E280_ms,                0,                0,                0,\n utf8_to_euc_E284, utf8_to_euc_E285, utf8_to_euc_E286, utf8_to_euc_E287,\n utf8_to_euc_E288, utf8_to_euc_E289, utf8_to_euc_E28A,                0,\n utf8_to_euc_E28C,                0,                0,                0,\n                0, utf8_to_euc_E291,                0,                0,\n utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297,\n utf8_to_euc_E298, utf8_to_euc_E299,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n};\nconst unsigned short *const utf8_to_euc_E2_932[] = {\n utf8_to_euc_E280_932,                0,                0,                0,\n utf8_to_euc_E284, utf8_to_euc_E285, utf8_to_euc_E286, utf8_to_euc_E287,\n utf8_to_euc_E288_932, utf8_to_euc_E289, utf8_to_euc_E28A,                0,\n utf8_to_euc_E28C,                0,                0,                0,\n                0, utf8_to_euc_E291,                0,                0,\n utf8_to_euc_E294, utf8_to_euc_E295, utf8_to_euc_E296, utf8_to_euc_E297,\n utf8_to_euc_E298, utf8_to_euc_E299,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n};\nconst unsigned short *const utf8_to_euc_E3[] = {\n utf8_to_euc_E380, utf8_to_euc_E381, utf8_to_euc_E382, utf8_to_euc_E383,\n                0,                0,                0,                0,\n utf8_to_euc_E388,                0, utf8_to_euc_E38A,                0,\n utf8_to_euc_E38C, utf8_to_euc_E38D, utf8_to_euc_E38E, utf8_to_euc_E38F,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n};\nconst unsigned short *const utf8_to_euc_E3_932[] = {\n utf8_to_euc_E380_932, utf8_to_euc_E381, utf8_to_euc_E382_932, utf8_to_euc_E383,\n                0,                0,                0,                0,\n utf8_to_euc_E388,                0, utf8_to_euc_E38A,                0,\n utf8_to_euc_E38C, utf8_to_euc_E38D, utf8_to_euc_E38E, utf8_to_euc_E38F,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n};\nconst unsigned short *const utf8_to_euc_E4[] = {\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n utf8_to_euc_E4B8, utf8_to_euc_E4B9, utf8_to_euc_E4BA, utf8_to_euc_E4BB,\n utf8_to_euc_E4BC, utf8_to_euc_E4BD, utf8_to_euc_E4BE, utf8_to_euc_E4BF,\n};\nconst unsigned short *const utf8_to_euc_E5[] = {\n utf8_to_euc_E580, utf8_to_euc_E581, utf8_to_euc_E582, utf8_to_euc_E583,\n utf8_to_euc_E584, utf8_to_euc_E585, utf8_to_euc_E586, utf8_to_euc_E587,\n utf8_to_euc_E588, utf8_to_euc_E589, utf8_to_euc_E58A, utf8_to_euc_E58B,\n utf8_to_euc_E58C, utf8_to_euc_E58D, utf8_to_euc_E58E, utf8_to_euc_E58F,\n utf8_to_euc_E590, utf8_to_euc_E591, utf8_to_euc_E592, utf8_to_euc_E593,\n utf8_to_euc_E594, utf8_to_euc_E595, utf8_to_euc_E596, utf8_to_euc_E597,\n utf8_to_euc_E598, utf8_to_euc_E599, utf8_to_euc_E59A, utf8_to_euc_E59B,\n utf8_to_euc_E59C, utf8_to_euc_E59D, utf8_to_euc_E59E, utf8_to_euc_E59F,\n utf8_to_euc_E5A0, utf8_to_euc_E5A1, utf8_to_euc_E5A2, utf8_to_euc_E5A3,\n utf8_to_euc_E5A4, utf8_to_euc_E5A5, utf8_to_euc_E5A6, utf8_to_euc_E5A7,\n utf8_to_euc_E5A8, utf8_to_euc_E5A9, utf8_to_euc_E5AA, utf8_to_euc_E5AB,\n utf8_to_euc_E5AC, utf8_to_euc_E5AD, utf8_to_euc_E5AE, utf8_to_euc_E5AF,\n utf8_to_euc_E5B0, utf8_to_euc_E5B1, utf8_to_euc_E5B2, utf8_to_euc_E5B3,\n utf8_to_euc_E5B4, utf8_to_euc_E5B5, utf8_to_euc_E5B6, utf8_to_euc_E5B7,\n utf8_to_euc_E5B8, utf8_to_euc_E5B9, utf8_to_euc_E5BA, utf8_to_euc_E5BB,\n utf8_to_euc_E5BC, utf8_to_euc_E5BD, utf8_to_euc_E5BE, utf8_to_euc_E5BF,\n};\nconst unsigned short *const utf8_to_euc_E6[] = {\n utf8_to_euc_E680, utf8_to_euc_E681, utf8_to_euc_E682, utf8_to_euc_E683,\n utf8_to_euc_E684, utf8_to_euc_E685, utf8_to_euc_E686, utf8_to_euc_E687,\n utf8_to_euc_E688, utf8_to_euc_E689, utf8_to_euc_E68A, utf8_to_euc_E68B,\n utf8_to_euc_E68C, utf8_to_euc_E68D, utf8_to_euc_E68E, utf8_to_euc_E68F,\n utf8_to_euc_E690, utf8_to_euc_E691, utf8_to_euc_E692, utf8_to_euc_E693,\n utf8_to_euc_E694, utf8_to_euc_E695, utf8_to_euc_E696, utf8_to_euc_E697,\n utf8_to_euc_E698, utf8_to_euc_E699, utf8_to_euc_E69A, utf8_to_euc_E69B,\n utf8_to_euc_E69C, utf8_to_euc_E69D, utf8_to_euc_E69E, utf8_to_euc_E69F,\n utf8_to_euc_E6A0, utf8_to_euc_E6A1, utf8_to_euc_E6A2, utf8_to_euc_E6A3,\n utf8_to_euc_E6A4, utf8_to_euc_E6A5, utf8_to_euc_E6A6, utf8_to_euc_E6A7,\n utf8_to_euc_E6A8, utf8_to_euc_E6A9, utf8_to_euc_E6AA, utf8_to_euc_E6AB,\n utf8_to_euc_E6AC, utf8_to_euc_E6AD, utf8_to_euc_E6AE, utf8_to_euc_E6AF,\n utf8_to_euc_E6B0, utf8_to_euc_E6B1, utf8_to_euc_E6B2, utf8_to_euc_E6B3,\n utf8_to_euc_E6B4, utf8_to_euc_E6B5, utf8_to_euc_E6B6, utf8_to_euc_E6B7,\n utf8_to_euc_E6B8, utf8_to_euc_E6B9, utf8_to_euc_E6BA, utf8_to_euc_E6BB,\n utf8_to_euc_E6BC, utf8_to_euc_E6BD, utf8_to_euc_E6BE, utf8_to_euc_E6BF,\n};\nconst unsigned short *const utf8_to_euc_E7[] = {\n utf8_to_euc_E780, utf8_to_euc_E781, utf8_to_euc_E782, utf8_to_euc_E783,\n utf8_to_euc_E784, utf8_to_euc_E785, utf8_to_euc_E786, utf8_to_euc_E787,\n utf8_to_euc_E788, utf8_to_euc_E789, utf8_to_euc_E78A, utf8_to_euc_E78B,\n utf8_to_euc_E78C, utf8_to_euc_E78D, utf8_to_euc_E78E, utf8_to_euc_E78F,\n utf8_to_euc_E790, utf8_to_euc_E791, utf8_to_euc_E792, utf8_to_euc_E793,\n utf8_to_euc_E794, utf8_to_euc_E795, utf8_to_euc_E796, utf8_to_euc_E797,\n utf8_to_euc_E798, utf8_to_euc_E799, utf8_to_euc_E79A, utf8_to_euc_E79B,\n utf8_to_euc_E79C, utf8_to_euc_E79D, utf8_to_euc_E79E, utf8_to_euc_E79F,\n utf8_to_euc_E7A0, utf8_to_euc_E7A1, utf8_to_euc_E7A2, utf8_to_euc_E7A3,\n utf8_to_euc_E7A4, utf8_to_euc_E7A5, utf8_to_euc_E7A6, utf8_to_euc_E7A7,\n utf8_to_euc_E7A8, utf8_to_euc_E7A9, utf8_to_euc_E7AA, utf8_to_euc_E7AB,\n utf8_to_euc_E7AC, utf8_to_euc_E7AD, utf8_to_euc_E7AE, utf8_to_euc_E7AF,\n utf8_to_euc_E7B0, utf8_to_euc_E7B1, utf8_to_euc_E7B2, utf8_to_euc_E7B3,\n utf8_to_euc_E7B4, utf8_to_euc_E7B5, utf8_to_euc_E7B6, utf8_to_euc_E7B7,\n utf8_to_euc_E7B8, utf8_to_euc_E7B9, utf8_to_euc_E7BA,                0,\n utf8_to_euc_E7BC, utf8_to_euc_E7BD, utf8_to_euc_E7BE, utf8_to_euc_E7BF,\n};\nconst unsigned short *const utf8_to_euc_E8[] = {\n utf8_to_euc_E880, utf8_to_euc_E881, utf8_to_euc_E882, utf8_to_euc_E883,\n utf8_to_euc_E884, utf8_to_euc_E885, utf8_to_euc_E886, utf8_to_euc_E887,\n utf8_to_euc_E888, utf8_to_euc_E889, utf8_to_euc_E88A, utf8_to_euc_E88B,\n utf8_to_euc_E88C, utf8_to_euc_E88D, utf8_to_euc_E88E, utf8_to_euc_E88F,\n utf8_to_euc_E890, utf8_to_euc_E891, utf8_to_euc_E892, utf8_to_euc_E893,\n utf8_to_euc_E894, utf8_to_euc_E895, utf8_to_euc_E896, utf8_to_euc_E897,\n utf8_to_euc_E898, utf8_to_euc_E899, utf8_to_euc_E89A, utf8_to_euc_E89B,\n utf8_to_euc_E89C, utf8_to_euc_E89D, utf8_to_euc_E89E, utf8_to_euc_E89F,\n utf8_to_euc_E8A0, utf8_to_euc_E8A1, utf8_to_euc_E8A2, utf8_to_euc_E8A3,\n utf8_to_euc_E8A4, utf8_to_euc_E8A5, utf8_to_euc_E8A6, utf8_to_euc_E8A7,\n utf8_to_euc_E8A8, utf8_to_euc_E8A9, utf8_to_euc_E8AA, utf8_to_euc_E8AB,\n utf8_to_euc_E8AC, utf8_to_euc_E8AD, utf8_to_euc_E8AE,                0,\n utf8_to_euc_E8B0, utf8_to_euc_E8B1, utf8_to_euc_E8B2, utf8_to_euc_E8B3,\n utf8_to_euc_E8B4, utf8_to_euc_E8B5, utf8_to_euc_E8B6, utf8_to_euc_E8B7,\n utf8_to_euc_E8B8, utf8_to_euc_E8B9, utf8_to_euc_E8BA, utf8_to_euc_E8BB,\n utf8_to_euc_E8BC, utf8_to_euc_E8BD, utf8_to_euc_E8BE, utf8_to_euc_E8BF,\n};\nconst unsigned short *const utf8_to_euc_E9[] = {\n utf8_to_euc_E980, utf8_to_euc_E981, utf8_to_euc_E982, utf8_to_euc_E983,\n utf8_to_euc_E984, utf8_to_euc_E985, utf8_to_euc_E986, utf8_to_euc_E987,\n utf8_to_euc_E988, utf8_to_euc_E989, utf8_to_euc_E98A, utf8_to_euc_E98B,\n utf8_to_euc_E98C, utf8_to_euc_E98D, utf8_to_euc_E98E, utf8_to_euc_E98F,\n utf8_to_euc_E990, utf8_to_euc_E991, utf8_to_euc_E992,                0,\n                0, utf8_to_euc_E995, utf8_to_euc_E996, utf8_to_euc_E997,\n utf8_to_euc_E998, utf8_to_euc_E999, utf8_to_euc_E99A, utf8_to_euc_E99B,\n utf8_to_euc_E99C, utf8_to_euc_E99D, utf8_to_euc_E99E, utf8_to_euc_E99F,\n utf8_to_euc_E9A0, utf8_to_euc_E9A1, utf8_to_euc_E9A2, utf8_to_euc_E9A3,\n utf8_to_euc_E9A4, utf8_to_euc_E9A5, utf8_to_euc_E9A6, utf8_to_euc_E9A7,\n utf8_to_euc_E9A8, utf8_to_euc_E9A9, utf8_to_euc_E9AA, utf8_to_euc_E9AB,\n utf8_to_euc_E9AC, utf8_to_euc_E9AD, utf8_to_euc_E9AE, utf8_to_euc_E9AF,\n utf8_to_euc_E9B0, utf8_to_euc_E9B1,                0, utf8_to_euc_E9B3,\n utf8_to_euc_E9B4, utf8_to_euc_E9B5, utf8_to_euc_E9B6, utf8_to_euc_E9B7,\n utf8_to_euc_E9B8, utf8_to_euc_E9B9, utf8_to_euc_E9BA, utf8_to_euc_E9BB,\n utf8_to_euc_E9BC, utf8_to_euc_E9BD, utf8_to_euc_E9BE,                0,\n};\nconst unsigned short *const utf8_to_euc_EF[] = {\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n utf8_to_euc_EFA4,                0,                0, utf8_to_euc_EFA7,\n utf8_to_euc_EFA8,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n utf8_to_euc_EFBC, utf8_to_euc_EFBD, utf8_to_euc_EFBE, utf8_to_euc_EFBF,\n};\nconst unsigned short *const utf8_to_euc_EF_ms[] = {\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n utf8_to_euc_EFA4,                0,                0, utf8_to_euc_EFA7,\n utf8_to_euc_EFA8,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n                0,                0,                0,                0,\n utf8_to_euc_EFBC, utf8_to_euc_EFBD_ms, utf8_to_euc_EFBE, utf8_to_euc_EFBF,\n};\nconst unsigned short *const utf8_to_euc_2bytes[] = {\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0, utf8_to_euc_C2, utf8_to_euc_C3,\n utf8_to_euc_C4, utf8_to_euc_C5,              0, utf8_to_euc_C7,\n              0,              0,              0, utf8_to_euc_CB,\n              0,              0, utf8_to_euc_CE, utf8_to_euc_CF,\n utf8_to_euc_D0, utf8_to_euc_D1,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n};\nconst unsigned short *const utf8_to_euc_2bytes_ms[] = {\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0, utf8_to_euc_C2_ms, utf8_to_euc_C3,\n utf8_to_euc_C4, utf8_to_euc_C5,              0, utf8_to_euc_C7,\n              0,              0,              0, utf8_to_euc_CB,\n              0,              0, utf8_to_euc_CE, utf8_to_euc_CF,\n utf8_to_euc_D0, utf8_to_euc_D1,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n};\nconst unsigned short *const utf8_to_euc_2bytes_932[] = {\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0, utf8_to_euc_C2_932, utf8_to_euc_C3_932,\n utf8_to_euc_C4, utf8_to_euc_C5,              0, utf8_to_euc_C7,\n              0,              0,              0, utf8_to_euc_CB,\n              0,              0, utf8_to_euc_CE, utf8_to_euc_CF,\n utf8_to_euc_D0, utf8_to_euc_D1,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n              0,              0,              0,              0,\n};\nconst unsigned short *const *const utf8_to_euc_3bytes[] = {\n              0,              0, utf8_to_euc_E2, utf8_to_euc_E3,\n utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7,\n utf8_to_euc_E8, utf8_to_euc_E9,              0,              0,\n              0,              0,              0, utf8_to_euc_EF,\n};\nconst unsigned short *const *const utf8_to_euc_3bytes_ms[] = {\n              0,              0, utf8_to_euc_E2_ms, utf8_to_euc_E3,\n utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7,\n utf8_to_euc_E8, utf8_to_euc_E9,              0,              0,\n              0,              0,              0, utf8_to_euc_EF_ms,\n};\nconst unsigned short *const *const utf8_to_euc_3bytes_932[] = {\n              0,              0, utf8_to_euc_E2_932, utf8_to_euc_E3_932,\n utf8_to_euc_E4, utf8_to_euc_E5, utf8_to_euc_E6, utf8_to_euc_E7,\n utf8_to_euc_E8, utf8_to_euc_E9,              0,              0,\n              0,              0,              0, utf8_to_euc_EF_ms,\n};\n\n#ifdef UNICODE_NORMALIZATION\n\n/* Normalization Table by Apple */\n/* http://developer.apple.com/technotes/tn/tn1150table.html */\n\nconst struct normalization_pair normalization_table[] = {\n    {{0xcd,0xbe},\t{0x3b}},\n    {{0xc3,0x80},\t{0x41,0xcc,0x80,0x00}},\n    {{0xc3,0x81},\t{0x41,0xcc,0x81}},\n    {{0xc3,0x82},\t{0x41,0xcc,0x82}},\n    {{0xe1,0xba,0xa6},\t{0x41,0xcc,0x82,0xcc,0x80}},\n    {{0xe1,0xba,0xa4},\t{0x41,0xcc,0x82,0xcc,0x81}},\n    {{0xe1,0xba,0xaa},\t{0x41,0xcc,0x82,0xcc,0x83}},\n    {{0xe1,0xba,0xa8},\t{0x41,0xcc,0x82,0xcc,0x89}},\n    {{0xc3,0x83},\t{0x41,0xcc,0x83}},\n    {{0xc4,0x80},\t{0x41,0xcc,0x84}},\n    {{0xc4,0x82},\t{0x41,0xcc,0x86}},\n    {{0xe1,0xba,0xb0},\t{0x41,0xcc,0x86,0xcc,0x80}},\n    {{0xe1,0xba,0xae},\t{0x41,0xcc,0x86,0xcc,0x81}},\n    {{0xe1,0xba,0xb4},\t{0x41,0xcc,0x86,0xcc,0x83}},\n    {{0xe1,0xba,0xb2},\t{0x41,0xcc,0x86,0xcc,0x89}},\n    {{0xc7,0xa0},\t{0x41,0xcc,0x87,0xcc,0x84}},\n    {{0xc3,0x84},\t{0x41,0xcc,0x88}},\n    {{0xc7,0x9e},\t{0x41,0xcc,0x88,0xcc,0x84}},\n    {{0xe1,0xba,0xa2},\t{0x41,0xcc,0x89}},\n    {{0xc3,0x85},\t{0x41,0xcc,0x8a}},\n    {{0xc7,0xba},\t{0x41,0xcc,0x8a,0xcc,0x81}},\n    {{0xc7,0x8d},\t{0x41,0xcc,0x8c}},\n    {{0xc8,0x80},\t{0x41,0xcc,0x8f}},\n    {{0xc8,0x82},\t{0x41,0xcc,0x91}},\n    {{0xe1,0xba,0xa0},\t{0x41,0xcc,0xa3}},\n    {{0xe1,0xba,0xac},\t{0x41,0xcc,0xa3,0xcc,0x82}},\n    {{0xe1,0xba,0xb6},\t{0x41,0xcc,0xa3,0xcc,0x86}},\n    {{0xe1,0xb8,0x80},\t{0x41,0xcc,0xa5}},\n    {{0xc4,0x84},\t{0x41,0xcc,0xa8}},\n    {{0xe1,0xb8,0x82},\t{0x42,0xcc,0x87}},\n    {{0xe1,0xb8,0x84},\t{0x42,0xcc,0xa3}},\n    {{0xe1,0xb8,0x86},\t{0x42,0xcc,0xb1}},\n    {{0xc4,0x86},\t{0x43,0xcc,0x81}},\n    {{0xc4,0x88},\t{0x43,0xcc,0x82}},\n    {{0xc4,0x8a},\t{0x43,0xcc,0x87}},\n    {{0xc4,0x8c},\t{0x43,0xcc,0x8c}},\n    {{0xc3,0x87},\t{0x43,0xcc,0xa7}},\n    {{0xe1,0xb8,0x88},\t{0x43,0xcc,0xa7,0xcc,0x81}},\n    {{0xe1,0xb8,0x8a},\t{0x44,0xcc,0x87}},\n    {{0xc4,0x8e},\t{0x44,0xcc,0x8c}},\n    {{0xe1,0xb8,0x8c},\t{0x44,0xcc,0xa3}},\n    {{0xe1,0xb8,0x90},\t{0x44,0xcc,0xa7}},\n    {{0xe1,0xb8,0x92},\t{0x44,0xcc,0xad}},\n    {{0xe1,0xb8,0x8e},\t{0x44,0xcc,0xb1}},\n    {{0xc3,0x88},\t{0x45,0xcc,0x80}},\n    {{0xc3,0x89},\t{0x45,0xcc,0x81}},\n    {{0xc3,0x8a},\t{0x45,0xcc,0x82}},\n    {{0xe1,0xbb,0x80},\t{0x45,0xcc,0x82,0xcc,0x80}},\n    {{0xe1,0xba,0xbe},\t{0x45,0xcc,0x82,0xcc,0x81}},\n    {{0xe1,0xbb,0x84},\t{0x45,0xcc,0x82,0xcc,0x83}},\n    {{0xe1,0xbb,0x82},\t{0x45,0xcc,0x82,0xcc,0x89}},\n    {{0xe1,0xba,0xbc},\t{0x45,0xcc,0x83}},\n    {{0xc4,0x92},\t{0x45,0xcc,0x84}},\n    {{0xe1,0xb8,0x94},\t{0x45,0xcc,0x84,0xcc,0x80}},\n    {{0xe1,0xb8,0x96},\t{0x45,0xcc,0x84,0xcc,0x81}},\n    {{0xc4,0x94},\t{0x45,0xcc,0x86}},\n    {{0xc4,0x96},\t{0x45,0xcc,0x87}},\n    {{0xc3,0x8b},\t{0x45,0xcc,0x88}},\n    {{0xe1,0xba,0xba},\t{0x45,0xcc,0x89}},\n    {{0xc4,0x9a},\t{0x45,0xcc,0x8c}},\n    {{0xc8,0x84},\t{0x45,0xcc,0x8f}},\n    {{0xc8,0x86},\t{0x45,0xcc,0x91}},\n    {{0xe1,0xba,0xb8},\t{0x45,0xcc,0xa3}},\n    {{0xe1,0xbb,0x86},\t{0x45,0xcc,0xa3,0xcc,0x82}},\n    {{0xe1,0xb8,0x9c},\t{0x45,0xcc,0xa7,0xcc,0x86}},\n    {{0xc4,0x98},\t{0x45,0xcc,0xa8}},\n    {{0xe1,0xb8,0x98},\t{0x45,0xcc,0xad}},\n    {{0xe1,0xb8,0x9a},\t{0x45,0xcc,0xb0}},\n    {{0xe1,0xb8,0x9e},\t{0x46,0xcc,0x87}},\n    {{0xc7,0xb4},\t{0x47,0xcc,0x81}},\n    {{0xc4,0x9c},\t{0x47,0xcc,0x82}},\n    {{0xe1,0xb8,0xa0},\t{0x47,0xcc,0x84}},\n    {{0xc4,0x9e},\t{0x47,0xcc,0x86}},\n    {{0xc4,0xa0},\t{0x47,0xcc,0x87}},\n    {{0xc7,0xa6},\t{0x47,0xcc,0x8c}},\n    {{0xc4,0xa2},\t{0x47,0xcc,0xa7}},\n    {{0xc4,0xa4},\t{0x48,0xcc,0x82}},\n    {{0xe1,0xb8,0xa2},\t{0x48,0xcc,0x87}},\n    {{0xe1,0xb8,0xa6},\t{0x48,0xcc,0x88}},\n    {{0xe1,0xb8,0xa4},\t{0x48,0xcc,0xa3}},\n    {{0xe1,0xb8,0xa8},\t{0x48,0xcc,0xa7}},\n    {{0xe1,0xb8,0xaa},\t{0x48,0xcc,0xae}},\n    {{0xc3,0x8c},\t{0x49,0xcc,0x80}},\n    {{0xc3,0x8d},\t{0x49,0xcc,0x81}},\n    {{0xc3,0x8e},\t{0x49,0xcc,0x82}},\n    {{0xc4,0xa8},\t{0x49,0xcc,0x83}},\n    {{0xc4,0xaa},\t{0x49,0xcc,0x84}},\n    {{0xc4,0xac},\t{0x49,0xcc,0x86}},\n    {{0xc4,0xb0},\t{0x49,0xcc,0x87}},\n    {{0xc3,0x8f},\t{0x49,0xcc,0x88}},\n    {{0xe1,0xb8,0xae},\t{0x49,0xcc,0x88,0xcc,0x81}},\n    {{0xe1,0xbb,0x88},\t{0x49,0xcc,0x89}},\n    {{0xc7,0x8f},\t{0x49,0xcc,0x8c}},\n    {{0xc8,0x88},\t{0x49,0xcc,0x8f}},\n    {{0xc8,0x8a},\t{0x49,0xcc,0x91}},\n    {{0xe1,0xbb,0x8a},\t{0x49,0xcc,0xa3}},\n    {{0xc4,0xae},\t{0x49,0xcc,0xa8}},\n    {{0xe1,0xb8,0xac},\t{0x49,0xcc,0xb0}},\n    {{0xc4,0xb4},\t{0x4a,0xcc,0x82}},\n    {{0xe1,0xb8,0xb0},\t{0x4b,0xcc,0x81}},\n    {{0xc7,0xa8},\t{0x4b,0xcc,0x8c}},\n    {{0xe1,0xb8,0xb2},\t{0x4b,0xcc,0xa3}},\n    {{0xc4,0xb6},\t{0x4b,0xcc,0xa7}},\n    {{0xe1,0xb8,0xb4},\t{0x4b,0xcc,0xb1}},\n    {{0xc4,0xb9},\t{0x4c,0xcc,0x81}},\n    {{0xc4,0xbd},\t{0x4c,0xcc,0x8c}},\n    {{0xe1,0xb8,0xb6},\t{0x4c,0xcc,0xa3}},\n    {{0xe1,0xb8,0xb8},\t{0x4c,0xcc,0xa3,0xcc,0x84}},\n    {{0xc4,0xbb},\t{0x4c,0xcc,0xa7}},\n    {{0xe1,0xb8,0xbc},\t{0x4c,0xcc,0xad}},\n    {{0xe1,0xb8,0xba},\t{0x4c,0xcc,0xb1}},\n    {{0xe1,0xb8,0xbe},\t{0x4d,0xcc,0x81}},\n    {{0xe1,0xb9,0x80},\t{0x4d,0xcc,0x87}},\n    {{0xe1,0xb9,0x82},\t{0x4d,0xcc,0xa3}},\n    {{0xc5,0x83},\t{0x4e,0xcc,0x81}},\n    {{0xc3,0x91},\t{0x4e,0xcc,0x83}},\n    {{0xe1,0xb9,0x84},\t{0x4e,0xcc,0x87}},\n    {{0xc5,0x87},\t{0x4e,0xcc,0x8c}},\n    {{0xe1,0xb9,0x86},\t{0x4e,0xcc,0xa3}},\n    {{0xc5,0x85},\t{0x4e,0xcc,0xa7}},\n    {{0xe1,0xb9,0x8a},\t{0x4e,0xcc,0xad}},\n    {{0xe1,0xb9,0x88},\t{0x4e,0xcc,0xb1}},\n    {{0xc3,0x92},\t{0x4f,0xcc,0x80}},\n    {{0xc3,0x93},\t{0x4f,0xcc,0x81}},\n    {{0xc3,0x94},\t{0x4f,0xcc,0x82}},\n    {{0xe1,0xbb,0x92},\t{0x4f,0xcc,0x82,0xcc,0x80}},\n    {{0xe1,0xbb,0x90},\t{0x4f,0xcc,0x82,0xcc,0x81}},\n    {{0xe1,0xbb,0x96},\t{0x4f,0xcc,0x82,0xcc,0x83}},\n    {{0xe1,0xbb,0x94},\t{0x4f,0xcc,0x82,0xcc,0x89}},\n    {{0xc3,0x95},\t{0x4f,0xcc,0x83}},\n    {{0xe1,0xb9,0x8c},\t{0x4f,0xcc,0x83,0xcc,0x81}},\n    {{0xe1,0xb9,0x8e},\t{0x4f,0xcc,0x83,0xcc,0x88}},\n    {{0xc5,0x8c},\t{0x4f,0xcc,0x84}},\n    {{0xe1,0xb9,0x90},\t{0x4f,0xcc,0x84,0xcc,0x80}},\n    {{0xe1,0xb9,0x92},\t{0x4f,0xcc,0x84,0xcc,0x81}},\n    {{0xc5,0x8e},\t{0x4f,0xcc,0x86}},\n    {{0xc3,0x96},\t{0x4f,0xcc,0x88}},\n    {{0xe1,0xbb,0x8e},\t{0x4f,0xcc,0x89}},\n    {{0xc5,0x90},\t{0x4f,0xcc,0x8b}},\n    {{0xc7,0x91},\t{0x4f,0xcc,0x8c}},\n    {{0xc8,0x8c},\t{0x4f,0xcc,0x8f}},\n    {{0xc8,0x8e},\t{0x4f,0xcc,0x91}},\n    {{0xc6,0xa0},\t{0x4f,0xcc,0x9b}},\n    {{0xe1,0xbb,0x9c},\t{0x4f,0xcc,0x9b,0xcc,0x80}},\n    {{0xe1,0xbb,0x9a},\t{0x4f,0xcc,0x9b,0xcc,0x81}},\n    {{0xe1,0xbb,0xa0},\t{0x4f,0xcc,0x9b,0xcc,0x83}},\n    {{0xe1,0xbb,0x9e},\t{0x4f,0xcc,0x9b,0xcc,0x89}},\n    {{0xe1,0xbb,0xa2},\t{0x4f,0xcc,0x9b,0xcc,0xa3}},\n    {{0xe1,0xbb,0x8c},\t{0x4f,0xcc,0xa3}},\n    {{0xe1,0xbb,0x98},\t{0x4f,0xcc,0xa3,0xcc,0x82}},\n    {{0xc7,0xaa},\t{0x4f,0xcc,0xa8}},\n    {{0xc7,0xac},\t{0x4f,0xcc,0xa8,0xcc,0x84}},\n    {{0xe1,0xb9,0x94},\t{0x50,0xcc,0x81}},\n    {{0xe1,0xb9,0x96},\t{0x50,0xcc,0x87}},\n    {{0xc5,0x94},\t{0x52,0xcc,0x81}},\n    {{0xe1,0xb9,0x98},\t{0x52,0xcc,0x87}},\n    {{0xc5,0x98},\t{0x52,0xcc,0x8c}},\n    {{0xc8,0x90},\t{0x52,0xcc,0x8f}},\n    {{0xc8,0x92},\t{0x52,0xcc,0x91}},\n    {{0xe1,0xb9,0x9a},\t{0x52,0xcc,0xa3}},\n    {{0xe1,0xb9,0x9c},\t{0x52,0xcc,0xa3,0xcc,0x84}},\n    {{0xc5,0x96},\t{0x52,0xcc,0xa7}},\n    {{0xe1,0xb9,0x9e},\t{0x52,0xcc,0xb1}},\n    {{0xc5,0x9a},\t{0x53,0xcc,0x81}},\n    {{0xe1,0xb9,0xa4},\t{0x53,0xcc,0x81,0xcc,0x87}},\n    {{0xc5,0x9c},\t{0x53,0xcc,0x82}},\n    {{0xe1,0xb9,0xa0},\t{0x53,0xcc,0x87}},\n    {{0xc5,0xa0},\t{0x53,0xcc,0x8c}},\n    {{0xe1,0xb9,0xa6},\t{0x53,0xcc,0x8c,0xcc,0x87}},\n    {{0xe1,0xb9,0xa2},\t{0x53,0xcc,0xa3}},\n    {{0xe1,0xb9,0xa8},\t{0x53,0xcc,0xa3,0xcc,0x87}},\n    {{0xc5,0x9e},\t{0x53,0xcc,0xa7}},\n    {{0xe1,0xb9,0xaa},\t{0x54,0xcc,0x87}},\n    {{0xc5,0xa4},\t{0x54,0xcc,0x8c}},\n    {{0xe1,0xb9,0xac},\t{0x54,0xcc,0xa3}},\n    {{0xc5,0xa2},\t{0x54,0xcc,0xa7}},\n    {{0xe1,0xb9,0xb0},\t{0x54,0xcc,0xad}},\n    {{0xe1,0xb9,0xae},\t{0x54,0xcc,0xb1}},\n    {{0xc3,0x99},\t{0x55,0xcc,0x80}},\n    {{0xc3,0x9a},\t{0x55,0xcc,0x81}},\n    {{0xc3,0x9b},\t{0x55,0xcc,0x82}},\n    {{0xc5,0xa8},\t{0x55,0xcc,0x83}},\n    {{0xe1,0xb9,0xb8},\t{0x55,0xcc,0x83,0xcc,0x81}},\n    {{0xc5,0xaa},\t{0x55,0xcc,0x84}},\n    {{0xe1,0xb9,0xba},\t{0x55,0xcc,0x84,0xcc,0x88}},\n    {{0xc5,0xac},\t{0x55,0xcc,0x86}},\n    {{0xc3,0x9c},\t{0x55,0xcc,0x88}},\n    {{0xc7,0x9b},\t{0x55,0xcc,0x88,0xcc,0x80}},\n    {{0xc7,0x97},\t{0x55,0xcc,0x88,0xcc,0x81}},\n    {{0xc7,0x95},\t{0x55,0xcc,0x88,0xcc,0x84}},\n    {{0xc7,0x99},\t{0x55,0xcc,0x88,0xcc,0x8c}},\n    {{0xe1,0xbb,0xa6},\t{0x55,0xcc,0x89}},\n    {{0xc5,0xae},\t{0x55,0xcc,0x8a}},\n    {{0xc5,0xb0},\t{0x55,0xcc,0x8b}},\n    {{0xc7,0x93},\t{0x55,0xcc,0x8c}},\n    {{0xc8,0x94},\t{0x55,0xcc,0x8f}},\n    {{0xc8,0x96},\t{0x55,0xcc,0x91}},\n    {{0xc6,0xaf},\t{0x55,0xcc,0x9b}},\n    {{0xe1,0xbb,0xaa},\t{0x55,0xcc,0x9b,0xcc,0x80}},\n    {{0xe1,0xbb,0xa8},\t{0x55,0xcc,0x9b,0xcc,0x81}},\n    {{0xe1,0xbb,0xae},\t{0x55,0xcc,0x9b,0xcc,0x83}},\n    {{0xe1,0xbb,0xac},\t{0x55,0xcc,0x9b,0xcc,0x89}},\n    {{0xe1,0xbb,0xb0},\t{0x55,0xcc,0x9b,0xcc,0xa3}},\n    {{0xe1,0xbb,0xa4},\t{0x55,0xcc,0xa3}},\n    {{0xe1,0xb9,0xb2},\t{0x55,0xcc,0xa4}},\n    {{0xc5,0xb2},\t{0x55,0xcc,0xa8}},\n    {{0xe1,0xb9,0xb6},\t{0x55,0xcc,0xad}},\n    {{0xe1,0xb9,0xb4},\t{0x55,0xcc,0xb0}},\n    {{0xe1,0xb9,0xbc},\t{0x56,0xcc,0x83}},\n    {{0xe1,0xb9,0xbe},\t{0x56,0xcc,0xa3}},\n    {{0xe1,0xba,0x80},\t{0x57,0xcc,0x80}},\n    {{0xe1,0xba,0x82},\t{0x57,0xcc,0x81}},\n    {{0xc5,0xb4},\t{0x57,0xcc,0x82}},\n    {{0xe1,0xba,0x86},\t{0x57,0xcc,0x87}},\n    {{0xe1,0xba,0x84},\t{0x57,0xcc,0x88}},\n    {{0xe1,0xba,0x88},\t{0x57,0xcc,0xa3}},\n    {{0xe1,0xba,0x8a},\t{0x58,0xcc,0x87}},\n    {{0xe1,0xba,0x8c},\t{0x58,0xcc,0x88}},\n    {{0xe1,0xbb,0xb2},\t{0x59,0xcc,0x80}},\n    {{0xc3,0x9d},\t{0x59,0xcc,0x81}},\n    {{0xc5,0xb6},\t{0x59,0xcc,0x82}},\n    {{0xe1,0xbb,0xb8},\t{0x59,0xcc,0x83}},\n    {{0xe1,0xba,0x8e},\t{0x59,0xcc,0x87}},\n    {{0xc5,0xb8},\t{0x59,0xcc,0x88}},\n    {{0xe1,0xbb,0xb6},\t{0x59,0xcc,0x89}},\n    {{0xe1,0xbb,0xb4},\t{0x59,0xcc,0xa3}},\n    {{0xc5,0xb9},\t{0x5a,0xcc,0x81}},\n    {{0xe1,0xba,0x90},\t{0x5a,0xcc,0x82}},\n    {{0xc5,0xbb},\t{0x5a,0xcc,0x87}},\n    {{0xc5,0xbd},\t{0x5a,0xcc,0x8c}},\n    {{0xe1,0xba,0x92},\t{0x5a,0xcc,0xa3}},\n    {{0xe1,0xba,0x94},\t{0x5a,0xcc,0xb1}},\n    {{0xe1,0xbf,0xaf},\t{0x60}},\n    {{0xc3,0xa0},\t{0x61,0xcc,0x80}},\n    {{0xc3,0xa1},\t{0x61,0xcc,0x81}},\n    {{0xc3,0xa2},\t{0x61,0xcc,0x82}},\n    {{0xe1,0xba,0xa7},\t{0x61,0xcc,0x82,0xcc,0x80}},\n    {{0xe1,0xba,0xa5},\t{0x61,0xcc,0x82,0xcc,0x81}},\n    {{0xe1,0xba,0xab},\t{0x61,0xcc,0x82,0xcc,0x83}},\n    {{0xe1,0xba,0xa9},\t{0x61,0xcc,0x82,0xcc,0x89}},\n    {{0xc3,0xa3},\t{0x61,0xcc,0x83}},\n    {{0xc4,0x81},\t{0x61,0xcc,0x84}},\n    {{0xc4,0x83},\t{0x61,0xcc,0x86}},\n    {{0xe1,0xba,0xb1},\t{0x61,0xcc,0x86,0xcc,0x80}},\n    {{0xe1,0xba,0xaf},\t{0x61,0xcc,0x86,0xcc,0x81}},\n    {{0xe1,0xba,0xb5},\t{0x61,0xcc,0x86,0xcc,0x83}},\n    {{0xe1,0xba,0xb3},\t{0x61,0xcc,0x86,0xcc,0x89}},\n    {{0xc7,0xa1},\t{0x61,0xcc,0x87,0xcc,0x84}},\n    {{0xc3,0xa4},\t{0x61,0xcc,0x88}},\n    {{0xc7,0x9f},\t{0x61,0xcc,0x88,0xcc,0x84}},\n    {{0xe1,0xba,0xa3},\t{0x61,0xcc,0x89}},\n    {{0xc3,0xa5},\t{0x61,0xcc,0x8a}},\n    {{0xc7,0xbb},\t{0x61,0xcc,0x8a,0xcc,0x81}},\n    {{0xc7,0x8e},\t{0x61,0xcc,0x8c}},\n    {{0xc8,0x81},\t{0x61,0xcc,0x8f}},\n    {{0xc8,0x83},\t{0x61,0xcc,0x91}},\n    {{0xe1,0xba,0xa1},\t{0x61,0xcc,0xa3}},\n    {{0xe1,0xba,0xad},\t{0x61,0xcc,0xa3,0xcc,0x82}},\n    {{0xe1,0xba,0xb7},\t{0x61,0xcc,0xa3,0xcc,0x86}},\n    {{0xe1,0xb8,0x81},\t{0x61,0xcc,0xa5}},\n    {{0xc4,0x85},\t{0x61,0xcc,0xa8}},\n    {{0xe1,0xb8,0x83},\t{0x62,0xcc,0x87}},\n    {{0xe1,0xb8,0x85},\t{0x62,0xcc,0xa3}},\n    {{0xe1,0xb8,0x87},\t{0x62,0xcc,0xb1}},\n    {{0xc4,0x87},\t{0x63,0xcc,0x81}},\n    {{0xc4,0x89},\t{0x63,0xcc,0x82}},\n    {{0xc4,0x8b},\t{0x63,0xcc,0x87}},\n    {{0xc4,0x8d},\t{0x63,0xcc,0x8c}},\n    {{0xc3,0xa7},\t{0x63,0xcc,0xa7}},\n    {{0xe1,0xb8,0x89},\t{0x63,0xcc,0xa7,0xcc,0x81}},\n    {{0xe1,0xb8,0x8b},\t{0x64,0xcc,0x87}},\n    {{0xc4,0x8f},\t{0x64,0xcc,0x8c}},\n    {{0xe1,0xb8,0x8d},\t{0x64,0xcc,0xa3}},\n    {{0xe1,0xb8,0x91},\t{0x64,0xcc,0xa7}},\n    {{0xe1,0xb8,0x93},\t{0x64,0xcc,0xad}},\n    {{0xe1,0xb8,0x8f},\t{0x64,0xcc,0xb1}},\n    {{0xc3,0xa8},\t{0x65,0xcc,0x80}},\n    {{0xc3,0xa9},\t{0x65,0xcc,0x81}},\n    {{0xc3,0xaa},\t{0x65,0xcc,0x82}},\n    {{0xe1,0xbb,0x81},\t{0x65,0xcc,0x82,0xcc,0x80}},\n    {{0xe1,0xba,0xbf},\t{0x65,0xcc,0x82,0xcc,0x81}},\n    {{0xe1,0xbb,0x85},\t{0x65,0xcc,0x82,0xcc,0x83}},\n    {{0xe1,0xbb,0x83},\t{0x65,0xcc,0x82,0xcc,0x89}},\n    {{0xe1,0xba,0xbd},\t{0x65,0xcc,0x83}},\n    {{0xc4,0x93},\t{0x65,0xcc,0x84}},\n    {{0xe1,0xb8,0x95},\t{0x65,0xcc,0x84,0xcc,0x80}},\n    {{0xe1,0xb8,0x97},\t{0x65,0xcc,0x84,0xcc,0x81}},\n    {{0xc4,0x95},\t{0x65,0xcc,0x86}},\n    {{0xc4,0x97},\t{0x65,0xcc,0x87}},\n    {{0xc3,0xab},\t{0x65,0xcc,0x88}},\n    {{0xe1,0xba,0xbb},\t{0x65,0xcc,0x89}},\n    {{0xc4,0x9b},\t{0x65,0xcc,0x8c}},\n    {{0xc8,0x85},\t{0x65,0xcc,0x8f}},\n    {{0xc8,0x87},\t{0x65,0xcc,0x91}},\n    {{0xe1,0xba,0xb9},\t{0x65,0xcc,0xa3}},\n    {{0xe1,0xbb,0x87},\t{0x65,0xcc,0xa3,0xcc,0x82}},\n    {{0xe1,0xb8,0x9d},\t{0x65,0xcc,0xa7,0xcc,0x86}},\n    {{0xc4,0x99},\t{0x65,0xcc,0xa8}},\n    {{0xe1,0xb8,0x99},\t{0x65,0xcc,0xad}},\n    {{0xe1,0xb8,0x9b},\t{0x65,0xcc,0xb0}},\n    {{0xe1,0xb8,0x9f},\t{0x66,0xcc,0x87}},\n    {{0xc7,0xb5},\t{0x67,0xcc,0x81}},\n    {{0xc4,0x9d},\t{0x67,0xcc,0x82}},\n    {{0xe1,0xb8,0xa1},\t{0x67,0xcc,0x84}},\n    {{0xc4,0x9f},\t{0x67,0xcc,0x86}},\n    {{0xc4,0xa1},\t{0x67,0xcc,0x87}},\n    {{0xc7,0xa7},\t{0x67,0xcc,0x8c}},\n    {{0xc4,0xa3},\t{0x67,0xcc,0xa7}},\n    {{0xc4,0xa5},\t{0x68,0xcc,0x82}},\n    {{0xe1,0xb8,0xa3},\t{0x68,0xcc,0x87}},\n    {{0xe1,0xb8,0xa7},\t{0x68,0xcc,0x88}},\n    {{0xe1,0xb8,0xa5},\t{0x68,0xcc,0xa3}},\n    {{0xe1,0xb8,0xa9},\t{0x68,0xcc,0xa7}},\n    {{0xe1,0xb8,0xab},\t{0x68,0xcc,0xae}},\n    {{0xe1,0xba,0x96},\t{0x68,0xcc,0xb1}},\n    {{0xc3,0xac},\t{0x69,0xcc,0x80}},\n    {{0xc3,0xad},\t{0x69,0xcc,0x81}},\n    {{0xc3,0xae},\t{0x69,0xcc,0x82}},\n    {{0xc4,0xa9},\t{0x69,0xcc,0x83}},\n    {{0xc4,0xab},\t{0x69,0xcc,0x84}},\n    {{0xc4,0xad},\t{0x69,0xcc,0x86}},\n    {{0xc3,0xaf},\t{0x69,0xcc,0x88}},\n    {{0xe1,0xb8,0xaf},\t{0x69,0xcc,0x88,0xcc,0x81}},\n    {{0xe1,0xbb,0x89},\t{0x69,0xcc,0x89}},\n    {{0xc7,0x90},\t{0x69,0xcc,0x8c}},\n    {{0xc8,0x89},\t{0x69,0xcc,0x8f}},\n    {{0xc8,0x8b},\t{0x69,0xcc,0x91}},\n    {{0xe1,0xbb,0x8b},\t{0x69,0xcc,0xa3}},\n    {{0xc4,0xaf},\t{0x69,0xcc,0xa8}},\n    {{0xe1,0xb8,0xad},\t{0x69,0xcc,0xb0}},\n    {{0xc4,0xb5},\t{0x6a,0xcc,0x82}},\n    {{0xc7,0xb0},\t{0x6a,0xcc,0x8c}},\n    {{0xe1,0xb8,0xb1},\t{0x6b,0xcc,0x81}},\n    {{0xc7,0xa9},\t{0x6b,0xcc,0x8c}},\n    {{0xe1,0xb8,0xb3},\t{0x6b,0xcc,0xa3}},\n    {{0xc4,0xb7},\t{0x6b,0xcc,0xa7}},\n    {{0xe1,0xb8,0xb5},\t{0x6b,0xcc,0xb1}},\n    {{0xc4,0xba},\t{0x6c,0xcc,0x81}},\n    {{0xc4,0xbe},\t{0x6c,0xcc,0x8c}},\n    {{0xe1,0xb8,0xb7},\t{0x6c,0xcc,0xa3}},\n    {{0xe1,0xb8,0xb9},\t{0x6c,0xcc,0xa3,0xcc,0x84}},\n    {{0xc4,0xbc},\t{0x6c,0xcc,0xa7}},\n    {{0xe1,0xb8,0xbd},\t{0x6c,0xcc,0xad}},\n    {{0xe1,0xb8,0xbb},\t{0x6c,0xcc,0xb1}},\n    {{0xe1,0xb8,0xbf},\t{0x6d,0xcc,0x81}},\n    {{0xe1,0xb9,0x81},\t{0x6d,0xcc,0x87}},\n    {{0xe1,0xb9,0x83},\t{0x6d,0xcc,0xa3}},\n    {{0xc5,0x84},\t{0x6e,0xcc,0x81}},\n    {{0xc3,0xb1},\t{0x6e,0xcc,0x83}},\n    {{0xe1,0xb9,0x85},\t{0x6e,0xcc,0x87}},\n    {{0xc5,0x88},\t{0x6e,0xcc,0x8c}},\n    {{0xe1,0xb9,0x87},\t{0x6e,0xcc,0xa3}},\n    {{0xc5,0x86},\t{0x6e,0xcc,0xa7}},\n    {{0xe1,0xb9,0x8b},\t{0x6e,0xcc,0xad}},\n    {{0xe1,0xb9,0x89},\t{0x6e,0xcc,0xb1}},\n    {{0xc3,0xb2},\t{0x6f,0xcc,0x80}},\n    {{0xc3,0xb3},\t{0x6f,0xcc,0x81}},\n    {{0xc3,0xb4},\t{0x6f,0xcc,0x82}},\n    {{0xe1,0xbb,0x93},\t{0x6f,0xcc,0x82,0xcc,0x80}},\n    {{0xe1,0xbb,0x91},\t{0x6f,0xcc,0x82,0xcc,0x81}},\n    {{0xe1,0xbb,0x97},\t{0x6f,0xcc,0x82,0xcc,0x83}},\n    {{0xe1,0xbb,0x95},\t{0x6f,0xcc,0x82,0xcc,0x89}},\n    {{0xc3,0xb5},\t{0x6f,0xcc,0x83}},\n    {{0xe1,0xb9,0x8d},\t{0x6f,0xcc,0x83,0xcc,0x81}},\n    {{0xe1,0xb9,0x8f},\t{0x6f,0xcc,0x83,0xcc,0x88}},\n    {{0xc5,0x8d},\t{0x6f,0xcc,0x84}},\n    {{0xe1,0xb9,0x91},\t{0x6f,0xcc,0x84,0xcc,0x80}},\n    {{0xe1,0xb9,0x93},\t{0x6f,0xcc,0x84,0xcc,0x81}},\n    {{0xc5,0x8f},\t{0x6f,0xcc,0x86}},\n    {{0xc3,0xb6},\t{0x6f,0xcc,0x88}},\n    {{0xe1,0xbb,0x8f},\t{0x6f,0xcc,0x89}},\n    {{0xc5,0x91},\t{0x6f,0xcc,0x8b}},\n    {{0xc7,0x92},\t{0x6f,0xcc,0x8c}},\n    {{0xc8,0x8d},\t{0x6f,0xcc,0x8f}},\n    {{0xc8,0x8f},\t{0x6f,0xcc,0x91}},\n    {{0xc6,0xa1},\t{0x6f,0xcc,0x9b}},\n    {{0xe1,0xbb,0x9d},\t{0x6f,0xcc,0x9b,0xcc,0x80}},\n    {{0xe1,0xbb,0x9b},\t{0x6f,0xcc,0x9b,0xcc,0x81}},\n    {{0xe1,0xbb,0xa1},\t{0x6f,0xcc,0x9b,0xcc,0x83}},\n    {{0xe1,0xbb,0x9f},\t{0x6f,0xcc,0x9b,0xcc,0x89}},\n    {{0xe1,0xbb,0xa3},\t{0x6f,0xcc,0x9b,0xcc,0xa3}},\n    {{0xe1,0xbb,0x8d},\t{0x6f,0xcc,0xa3}},\n    {{0xe1,0xbb,0x99},\t{0x6f,0xcc,0xa3,0xcc,0x82}},\n    {{0xc7,0xab},\t{0x6f,0xcc,0xa8}},\n    {{0xc7,0xad},\t{0x6f,0xcc,0xa8,0xcc,0x84}},\n    {{0xe1,0xb9,0x95},\t{0x70,0xcc,0x81}},\n    {{0xe1,0xb9,0x97},\t{0x70,0xcc,0x87}},\n    {{0xc5,0x95},\t{0x72,0xcc,0x81}},\n    {{0xe1,0xb9,0x99},\t{0x72,0xcc,0x87}},\n    {{0xc5,0x99},\t{0x72,0xcc,0x8c}},\n    {{0xc8,0x91},\t{0x72,0xcc,0x8f}},\n    {{0xc8,0x93},\t{0x72,0xcc,0x91}},\n    {{0xe1,0xb9,0x9b},\t{0x72,0xcc,0xa3}},\n    {{0xe1,0xb9,0x9d},\t{0x72,0xcc,0xa3,0xcc,0x84}},\n    {{0xc5,0x97},\t{0x72,0xcc,0xa7}},\n    {{0xe1,0xb9,0x9f},\t{0x72,0xcc,0xb1}},\n    {{0xc5,0x9b},\t{0x73,0xcc,0x81}},\n    {{0xe1,0xb9,0xa5},\t{0x73,0xcc,0x81,0xcc,0x87}},\n    {{0xc5,0x9d},\t{0x73,0xcc,0x82}},\n    {{0xe1,0xb9,0xa1},\t{0x73,0xcc,0x87}},\n    {{0xc5,0xa1},\t{0x73,0xcc,0x8c}},\n    {{0xe1,0xb9,0xa7},\t{0x73,0xcc,0x8c,0xcc,0x87}},\n    {{0xe1,0xb9,0xa3},\t{0x73,0xcc,0xa3}},\n    {{0xe1,0xb9,0xa9},\t{0x73,0xcc,0xa3,0xcc,0x87}},\n    {{0xc5,0x9f},\t{0x73,0xcc,0xa7}},\n    {{0xe1,0xb9,0xab},\t{0x74,0xcc,0x87}},\n    {{0xe1,0xba,0x97},\t{0x74,0xcc,0x88}},\n    {{0xc5,0xa5},\t{0x74,0xcc,0x8c}},\n    {{0xe1,0xb9,0xad},\t{0x74,0xcc,0xa3}},\n    {{0xc5,0xa3},\t{0x74,0xcc,0xa7}},\n    {{0xe1,0xb9,0xb1},\t{0x74,0xcc,0xad}},\n    {{0xe1,0xb9,0xaf},\t{0x74,0xcc,0xb1}},\n    {{0xc3,0xb9},\t{0x75,0xcc,0x80}},\n    {{0xc3,0xba},\t{0x75,0xcc,0x81}},\n    {{0xc3,0xbb},\t{0x75,0xcc,0x82}},\n    {{0xc5,0xa9},\t{0x75,0xcc,0x83}},\n    {{0xe1,0xb9,0xb9},\t{0x75,0xcc,0x83,0xcc,0x81}},\n    {{0xc5,0xab},\t{0x75,0xcc,0x84}},\n    {{0xe1,0xb9,0xbb},\t{0x75,0xcc,0x84,0xcc,0x88}},\n    {{0xc5,0xad},\t{0x75,0xcc,0x86}},\n    {{0xc3,0xbc},\t{0x75,0xcc,0x88}},\n    {{0xc7,0x9c},\t{0x75,0xcc,0x88,0xcc,0x80}},\n    {{0xc7,0x98},\t{0x75,0xcc,0x88,0xcc,0x81}},\n    {{0xc7,0x96},\t{0x75,0xcc,0x88,0xcc,0x84}},\n    {{0xc7,0x9a},\t{0x75,0xcc,0x88,0xcc,0x8c}},\n    {{0xe1,0xbb,0xa7},\t{0x75,0xcc,0x89}},\n    {{0xc5,0xaf},\t{0x75,0xcc,0x8a}},\n    {{0xc5,0xb1},\t{0x75,0xcc,0x8b}},\n    {{0xc7,0x94},\t{0x75,0xcc,0x8c}},\n    {{0xc8,0x95},\t{0x75,0xcc,0x8f}},\n    {{0xc8,0x97},\t{0x75,0xcc,0x91}},\n    {{0xc6,0xb0},\t{0x75,0xcc,0x9b}},\n    {{0xe1,0xbb,0xab},\t{0x75,0xcc,0x9b,0xcc,0x80}},\n    {{0xe1,0xbb,0xa9},\t{0x75,0xcc,0x9b,0xcc,0x81}},\n    {{0xe1,0xbb,0xaf},\t{0x75,0xcc,0x9b,0xcc,0x83}},\n    {{0xe1,0xbb,0xad},\t{0x75,0xcc,0x9b,0xcc,0x89}},\n    {{0xe1,0xbb,0xb1},\t{0x75,0xcc,0x9b,0xcc,0xa3}},\n    {{0xe1,0xbb,0xa5},\t{0x75,0xcc,0xa3}},\n    {{0xe1,0xb9,0xb3},\t{0x75,0xcc,0xa4}},\n    {{0xc5,0xb3},\t{0x75,0xcc,0xa8}},\n    {{0xe1,0xb9,0xb7},\t{0x75,0xcc,0xad}},\n    {{0xe1,0xb9,0xb5},\t{0x75,0xcc,0xb0}},\n    {{0xe1,0xb9,0xbd},\t{0x76,0xcc,0x83}},\n    {{0xe1,0xb9,0xbf},\t{0x76,0xcc,0xa3}},\n    {{0xe1,0xba,0x81},\t{0x77,0xcc,0x80}},\n    {{0xe1,0xba,0x83},\t{0x77,0xcc,0x81}},\n    {{0xc5,0xb5},\t{0x77,0xcc,0x82}},\n    {{0xe1,0xba,0x87},\t{0x77,0xcc,0x87}},\n    {{0xe1,0xba,0x85},\t{0x77,0xcc,0x88}},\n    {{0xe1,0xba,0x98},\t{0x77,0xcc,0x8a}},\n    {{0xe1,0xba,0x89},\t{0x77,0xcc,0xa3}},\n    {{0xe1,0xba,0x8b},\t{0x78,0xcc,0x87}},\n    {{0xe1,0xba,0x8d},\t{0x78,0xcc,0x88}},\n    {{0xe1,0xbb,0xb3},\t{0x79,0xcc,0x80}},\n    {{0xc3,0xbd},\t{0x79,0xcc,0x81}},\n    {{0xc5,0xb7},\t{0x79,0xcc,0x82}},\n    {{0xe1,0xbb,0xb9},\t{0x79,0xcc,0x83}},\n    {{0xe1,0xba,0x8f},\t{0x79,0xcc,0x87}},\n    {{0xc3,0xbf},\t{0x79,0xcc,0x88}},\n    {{0xe1,0xbb,0xb7},\t{0x79,0xcc,0x89}},\n    {{0xe1,0xba,0x99},\t{0x79,0xcc,0x8a}},\n    {{0xe1,0xbb,0xb5},\t{0x79,0xcc,0xa3}},\n    {{0xc5,0xba},\t{0x7a,0xcc,0x81}},\n    {{0xe1,0xba,0x91},\t{0x7a,0xcc,0x82}},\n    {{0xc5,0xbc},\t{0x7a,0xcc,0x87}},\n    {{0xc5,0xbe},\t{0x7a,0xcc,0x8c}},\n    {{0xe1,0xba,0x93},\t{0x7a,0xcc,0xa3}},\n    {{0xe1,0xba,0x95},\t{0x7a,0xcc,0xb1}},\n    {{0xe1,0xbf,0xad},\t{0xc2,0xa8,0xcc,0x80}},\n    {{0xe1,0xbf,0xae},\t{0xc2,0xa8,0xcc,0x81}},\n    {{0xce,0x85},\t{0xc2,0xa8,0xcc,0x8d}},\n    {{0xe1,0xbf,0x81},\t{0xc2,0xa8,0xcd,0x82}},\n    {{0xe1,0xbf,0xbd},\t{0xc2,0xb4}},\n    {{0xce,0x87},\t{0xc2,0xb7}},\n    {{0xd3,0x94},\t{0xc3,0x86}},\n    {{0xc7,0xbc},\t{0xc3,0x86,0xcc,0x81}},\n    {{0xc7,0xa2},\t{0xc3,0x86,0xcc,0x84}},\n    {{0xc7,0xbe},\t{0xc3,0x98,0xcc,0x81}},\n    {{0xd3,0x95},\t{0xc3,0xa6}},\n    {{0xc7,0xbd},\t{0xc3,0xa6,0xcc,0x81}},\n    {{0xc7,0xa3},\t{0xc3,0xa6,0xcc,0x84}},\n    {{0xc7,0xbf},\t{0xc3,0xb8,0xcc,0x81}},\n    {{0xe1,0xba,0x9b},\t{0xc5,0xbf,0xcc,0x87}},\n    {{0xd3,0x98},\t{0xc6,0x8f}},\n    {{0xd3,0x9a},\t{0xc6,0x8f,0xcc,0x88}},\n    {{0xd3,0xa8},\t{0xc6,0x9f}},\n    {{0xd3,0xaa},\t{0xc6,0x9f,0xcc,0x88}},\n    {{0xd3,0xa0},\t{0xc6,0xb7}},\n    {{0xc7,0xae},\t{0xc6,0xb7,0xcc,0x8c}},\n    {{0xd3,0x99},\t{0xc9,0x99}},\n    {{0xd3,0x9b},\t{0xc9,0x99,0xcc,0x88}},\n    {{0xd3,0xa9},\t{0xc9,0xb5}},\n    {{0xd3,0xab},\t{0xc9,0xb5,0xcc,0x88}},\n    {{0xd3,0xa1},\t{0xca,0x92}},\n    {{0xc7,0xaf},\t{0xca,0x92,0xcc,0x8c}},\n    {{0xcd,0xb4},\t{0xca,0xb9}},\n    {{0xcd,0x80},\t{0xcc,0x80}},\n    {{0xcd,0x81},\t{0xcc,0x81}},\n    {{0xcc,0x90},\t{0xcc,0x86,0xcc,0x87}},\n    {{0xcd,0x84},\t{0xcc,0x88,0xcc,0x8d}},\n    {{0xcd,0x83},\t{0xcc,0x93}},\n    {{0xe1,0xbe,0xba},\t{0xce,0x91,0xcc,0x80}},\n    {{0xe1,0xbe,0xbb},\t{0xce,0x91,0xcc,0x81}},\n    {{0xe1,0xbe,0xb9},\t{0xce,0x91,0xcc,0x84}},\n    {{0xe1,0xbe,0xb8},\t{0xce,0x91,0xcc,0x86}},\n    {{0xce,0x86},\t{0xce,0x91,0xcc,0x8d}},\n    {{0xe1,0xbc,0x88},\t{0xce,0x91,0xcc,0x93}},\n    {{0xe1,0xbc,0x8a},\t{0xce,0x91,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0x8c},\t{0xce,0x91,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0x8e},\t{0xce,0x91,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbc,0x89},\t{0xce,0x91,0xcc,0x94}},\n    {{0xe1,0xbc,0x8b},\t{0xce,0x91,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0x8d},\t{0xce,0x91,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbc,0x8f},\t{0xce,0x91,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbe,0xbc},\t{0xce,0x91,0xcd,0x85}},\n    {{0xe1,0xbe,0x88},\t{0xce,0x91,0xcd,0x85,0xcc,0x93}},\n    {{0xe1,0xbe,0x8a},\t{0xce,0x91,0xcd,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbe,0x8c},\t{0xce,0x91,0xcd,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbe,0x8e},\t{0xce,0x91,0xcd,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbe,0x89},\t{0xce,0x91,0xcd,0x85,0xcc,0x94}},\n    {{0xe1,0xbe,0x8b},\t{0xce,0x91,0xcd,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbe,0x8d},\t{0xce,0x91,0xcd,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbe,0x8f},\t{0xce,0x91,0xcd,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0x88},\t{0xce,0x95,0xcc,0x80}},\n    {{0xe1,0xbf,0x89},\t{0xce,0x95,0xcc,0x81}},\n    {{0xce,0x88},\t{0xce,0x95,0xcc,0x8d}},\n    {{0xe1,0xbc,0x98},\t{0xce,0x95,0xcc,0x93}},\n    {{0xe1,0xbc,0x9a},\t{0xce,0x95,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0x9c},\t{0xce,0x95,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0x99},\t{0xce,0x95,0xcc,0x94}},\n    {{0xe1,0xbc,0x9b},\t{0xce,0x95,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0x9d},\t{0xce,0x95,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbf,0x8a},\t{0xce,0x97,0xcc,0x80}},\n    {{0xe1,0xbf,0x8b},\t{0xce,0x97,0xcc,0x81}},\n    {{0xce,0x89},\t{0xce,0x97,0xcc,0x8d}},\n    {{0xe1,0xbc,0xa8},\t{0xce,0x97,0xcc,0x93}},\n    {{0xe1,0xbc,0xaa},\t{0xce,0x97,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0xac},\t{0xce,0x97,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0xae},\t{0xce,0x97,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbc,0xa9},\t{0xce,0x97,0xcc,0x94}},\n    {{0xe1,0xbc,0xab},\t{0xce,0x97,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0xad},\t{0xce,0x97,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbc,0xaf},\t{0xce,0x97,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0x8c},\t{0xce,0x97,0xcd,0x85}},\n    {{0xe1,0xbe,0x98},\t{0xce,0x97,0xcd,0x85,0xcc,0x93}},\n    {{0xe1,0xbe,0x9a},\t{0xce,0x97,0xcd,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbe,0x9c},\t{0xce,0x97,0xcd,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbe,0x9e},\t{0xce,0x97,0xcd,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbe,0x99},\t{0xce,0x97,0xcd,0x85,0xcc,0x94}},\n    {{0xe1,0xbe,0x9b},\t{0xce,0x97,0xcd,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbe,0x9d},\t{0xce,0x97,0xcd,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbe,0x9f},\t{0xce,0x97,0xcd,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0x9a},\t{0xce,0x99,0xcc,0x80}},\n    {{0xe1,0xbf,0x9b},\t{0xce,0x99,0xcc,0x81}},\n    {{0xe1,0xbf,0x99},\t{0xce,0x99,0xcc,0x84}},\n    {{0xe1,0xbf,0x98},\t{0xce,0x99,0xcc,0x86}},\n    {{0xce,0xaa},\t{0xce,0x99,0xcc,0x88}},\n    {{0xce,0x8a},\t{0xce,0x99,0xcc,0x8d}},\n    {{0xe1,0xbc,0xb8},\t{0xce,0x99,0xcc,0x93}},\n    {{0xe1,0xbc,0xba},\t{0xce,0x99,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0xbc},\t{0xce,0x99,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0xbe},\t{0xce,0x99,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbc,0xb9},\t{0xce,0x99,0xcc,0x94}},\n    {{0xe1,0xbc,0xbb},\t{0xce,0x99,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0xbd},\t{0xce,0x99,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbc,0xbf},\t{0xce,0x99,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0xb8},\t{0xce,0x9f,0xcc,0x80}},\n    {{0xe1,0xbf,0xb9},\t{0xce,0x9f,0xcc,0x81}},\n    {{0xce,0x8c},\t{0xce,0x9f,0xcc,0x8d}},\n    {{0xe1,0xbd,0x88},\t{0xce,0x9f,0xcc,0x93}},\n    {{0xe1,0xbd,0x8a},\t{0xce,0x9f,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbd,0x8c},\t{0xce,0x9f,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbd,0x89},\t{0xce,0x9f,0xcc,0x94}},\n    {{0xe1,0xbd,0x8b},\t{0xce,0x9f,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbd,0x8d},\t{0xce,0x9f,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbf,0xac},\t{0xce,0xa1,0xcc,0x94}},\n    {{0xe1,0xbf,0xaa},\t{0xce,0xa5,0xcc,0x80}},\n    {{0xe1,0xbf,0xab},\t{0xce,0xa5,0xcc,0x81}},\n    {{0xe1,0xbf,0xa9},\t{0xce,0xa5,0xcc,0x84}},\n    {{0xe1,0xbf,0xa8},\t{0xce,0xa5,0xcc,0x86}},\n    {{0xce,0xab},\t{0xce,0xa5,0xcc,0x88}},\n    {{0xce,0x8e},\t{0xce,0xa5,0xcc,0x8d}},\n    {{0xe1,0xbd,0x99},\t{0xce,0xa5,0xcc,0x94}},\n    {{0xe1,0xbd,0x9b},\t{0xce,0xa5,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbd,0x9d},\t{0xce,0xa5,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbd,0x9f},\t{0xce,0xa5,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0xba},\t{0xce,0xa9,0xcc,0x80}},\n    {{0xe1,0xbf,0xbb},\t{0xce,0xa9,0xcc,0x81}},\n    {{0xce,0x8f},\t{0xce,0xa9,0xcc,0x8d}},\n    {{0xe1,0xbd,0xa8},\t{0xce,0xa9,0xcc,0x93}},\n    {{0xe1,0xbd,0xaa},\t{0xce,0xa9,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbd,0xac},\t{0xce,0xa9,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbd,0xae},\t{0xce,0xa9,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbd,0xa9},\t{0xce,0xa9,0xcc,0x94}},\n    {{0xe1,0xbd,0xab},\t{0xce,0xa9,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbd,0xad},\t{0xce,0xa9,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbd,0xaf},\t{0xce,0xa9,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0xbc},\t{0xce,0xa9,0xcd,0x85}},\n    {{0xe1,0xbe,0xa8},\t{0xce,0xa9,0xcd,0x85,0xcc,0x93}},\n    {{0xe1,0xbe,0xaa},\t{0xce,0xa9,0xcd,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbe,0xac},\t{0xce,0xa9,0xcd,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbe,0xae},\t{0xce,0xa9,0xcd,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbe,0xa9},\t{0xce,0xa9,0xcd,0x85,0xcc,0x94}},\n    {{0xe1,0xbe,0xab},\t{0xce,0xa9,0xcd,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbe,0xad},\t{0xce,0xa9,0xcd,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbe,0xaf},\t{0xce,0xa9,0xcd,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbd,0xb0},\t{0xce,0xb1,0xcc,0x80}},\n    {{0xe1,0xbd,0xb1},\t{0xce,0xb1,0xcc,0x81}},\n    {{0xe1,0xbe,0xb1},\t{0xce,0xb1,0xcc,0x84}},\n    {{0xe1,0xbe,0xb0},\t{0xce,0xb1,0xcc,0x86}},\n    {{0xce,0xac},\t{0xce,0xb1,0xcc,0x8d}},\n    {{0xe1,0xbc,0x80},\t{0xce,0xb1,0xcc,0x93}},\n    {{0xe1,0xbc,0x82},\t{0xce,0xb1,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0x84},\t{0xce,0xb1,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0x86},\t{0xce,0xb1,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbc,0x81},\t{0xce,0xb1,0xcc,0x94}},\n    {{0xe1,0xbc,0x83},\t{0xce,0xb1,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0x85},\t{0xce,0xb1,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbc,0x87},\t{0xce,0xb1,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbe,0xb6},\t{0xce,0xb1,0xcd,0x82}},\n    {{0xe1,0xbe,0xb3},\t{0xce,0xb1,0xcd,0x85}},\n    {{0xe1,0xbe,0xb2},\t{0xce,0xb1,0xcd,0x85,0xcc,0x80}},\n    {{0xe1,0xbe,0xb4},\t{0xce,0xb1,0xcd,0x85,0xcc,0x81}},\n    {{0xe1,0xbe,0x80},\t{0xce,0xb1,0xcd,0x85,0xcc,0x93}},\n    {{0xe1,0xbe,0x82},\t{0xce,0xb1,0xcd,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbe,0x84},\t{0xce,0xb1,0xcd,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbe,0x86},\t{0xce,0xb1,0xcd,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbe,0x81},\t{0xce,0xb1,0xcd,0x85,0xcc,0x94}},\n    {{0xe1,0xbe,0x83},\t{0xce,0xb1,0xcd,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbe,0x85},\t{0xce,0xb1,0xcd,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbe,0x87},\t{0xce,0xb1,0xcd,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbe,0xb7},\t{0xce,0xb1,0xcd,0x85,0xcd,0x82}},\n    {{0xe1,0xbd,0xb2},\t{0xce,0xb5,0xcc,0x80}},\n    {{0xe1,0xbd,0xb3},\t{0xce,0xb5,0xcc,0x81}},\n    {{0xce,0xad},\t{0xce,0xb5,0xcc,0x8d}},\n    {{0xe1,0xbc,0x90},\t{0xce,0xb5,0xcc,0x93}},\n    {{0xe1,0xbc,0x92},\t{0xce,0xb5,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0x94},\t{0xce,0xb5,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0x91},\t{0xce,0xb5,0xcc,0x94}},\n    {{0xe1,0xbc,0x93},\t{0xce,0xb5,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0x95},\t{0xce,0xb5,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbd,0xb4},\t{0xce,0xb7,0xcc,0x80}},\n    {{0xe1,0xbd,0xb5},\t{0xce,0xb7,0xcc,0x81}},\n    {{0xce,0xae},\t{0xce,0xb7,0xcc,0x8d}},\n    {{0xe1,0xbc,0xa0},\t{0xce,0xb7,0xcc,0x93}},\n    {{0xe1,0xbc,0xa2},\t{0xce,0xb7,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0xa4},\t{0xce,0xb7,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0xa6},\t{0xce,0xb7,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbc,0xa1},\t{0xce,0xb7,0xcc,0x94}},\n    {{0xe1,0xbc,0xa3},\t{0xce,0xb7,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0xa5},\t{0xce,0xb7,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbc,0xa7},\t{0xce,0xb7,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0x86},\t{0xce,0xb7,0xcd,0x82}},\n    {{0xe1,0xbf,0x83},\t{0xce,0xb7,0xcd,0x85}},\n    {{0xe1,0xbf,0x82},\t{0xce,0xb7,0xcd,0x85,0xcc,0x80}},\n    {{0xe1,0xbf,0x84},\t{0xce,0xb7,0xcd,0x85,0xcc,0x81}},\n    {{0xe1,0xbe,0x90},\t{0xce,0xb7,0xcd,0x85,0xcc,0x93}},\n    {{0xe1,0xbe,0x92},\t{0xce,0xb7,0xcd,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbe,0x94},\t{0xce,0xb7,0xcd,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbe,0x96},\t{0xce,0xb7,0xcd,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbe,0x91},\t{0xce,0xb7,0xcd,0x85,0xcc,0x94}},\n    {{0xe1,0xbe,0x93},\t{0xce,0xb7,0xcd,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbe,0x95},\t{0xce,0xb7,0xcd,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbe,0x97},\t{0xce,0xb7,0xcd,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0x87},\t{0xce,0xb7,0xcd,0x85,0xcd,0x82}},\n    {{0xe1,0xbe,0xbe},\t{0xce,0xb9}},\n    {{0xe1,0xbd,0xb6},\t{0xce,0xb9,0xcc,0x80}},\n    {{0xe1,0xbd,0xb7},\t{0xce,0xb9,0xcc,0x81}},\n    {{0xe1,0xbf,0x91},\t{0xce,0xb9,0xcc,0x84}},\n    {{0xe1,0xbf,0x90},\t{0xce,0xb9,0xcc,0x86}},\n    {{0xcf,0x8a},\t{0xce,0xb9,0xcc,0x88}},\n    {{0xe1,0xbf,0x92},\t{0xce,0xb9,0xcc,0x88,0xcc,0x80}},\n    {{0xe1,0xbf,0x93},\t{0xce,0xb9,0xcc,0x88,0xcc,0x81}},\n    {{0xce,0x90},\t{0xce,0xb9,0xcc,0x88,0xcc,0x8d}},\n    {{0xe1,0xbf,0x97},\t{0xce,0xb9,0xcc,0x88,0xcd,0x82}},\n    {{0xce,0xaf},\t{0xce,0xb9,0xcc,0x8d}},\n    {{0xe1,0xbc,0xb0},\t{0xce,0xb9,0xcc,0x93}},\n    {{0xe1,0xbc,0xb2},\t{0xce,0xb9,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbc,0xb4},\t{0xce,0xb9,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbc,0xb6},\t{0xce,0xb9,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbc,0xb1},\t{0xce,0xb9,0xcc,0x94}},\n    {{0xe1,0xbc,0xb3},\t{0xce,0xb9,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbc,0xb5},\t{0xce,0xb9,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbc,0xb7},\t{0xce,0xb9,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0x96},\t{0xce,0xb9,0xcd,0x82}},\n    {{0xe1,0xbd,0xb8},\t{0xce,0xbf,0xcc,0x80}},\n    {{0xe1,0xbd,0xb9},\t{0xce,0xbf,0xcc,0x81}},\n    {{0xcf,0x8c},\t{0xce,0xbf,0xcc,0x8d}},\n    {{0xe1,0xbd,0x80},\t{0xce,0xbf,0xcc,0x93}},\n    {{0xe1,0xbd,0x82},\t{0xce,0xbf,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbd,0x84},\t{0xce,0xbf,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbd,0x81},\t{0xce,0xbf,0xcc,0x94}},\n    {{0xe1,0xbd,0x83},\t{0xce,0xbf,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbd,0x85},\t{0xce,0xbf,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbf,0xb4},\t{0xce,0xbf,0xcd,0x85,0xcc,0x81}},\n    {{0xe1,0xbf,0xa4},\t{0xcf,0x81,0xcc,0x93}},\n    {{0xe1,0xbf,0xa5},\t{0xcf,0x81,0xcc,0x94}},\n    {{0xe1,0xbd,0xba},\t{0xcf,0x85,0xcc,0x80}},\n    {{0xe1,0xbd,0xbb},\t{0xcf,0x85,0xcc,0x81}},\n    {{0xe1,0xbf,0xa1},\t{0xcf,0x85,0xcc,0x84}},\n    {{0xe1,0xbf,0xa0},\t{0xcf,0x85,0xcc,0x86}},\n    {{0xcf,0x8b},\t{0xcf,0x85,0xcc,0x88}},\n    {{0xe1,0xbf,0xa2},\t{0xcf,0x85,0xcc,0x88,0xcc,0x80}},\n    {{0xe1,0xbf,0xa3},\t{0xcf,0x85,0xcc,0x88,0xcc,0x81}},\n    {{0xce,0xb0},\t{0xcf,0x85,0xcc,0x88,0xcc,0x8d}},\n    {{0xe1,0xbf,0xa7},\t{0xcf,0x85,0xcc,0x88,0xcd,0x82}},\n    {{0xcf,0x8d},\t{0xcf,0x85,0xcc,0x8d}},\n    {{0xe1,0xbd,0x90},\t{0xcf,0x85,0xcc,0x93}},\n    {{0xe1,0xbd,0x92},\t{0xcf,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbd,0x94},\t{0xcf,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbd,0x96},\t{0xcf,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbd,0x91},\t{0xcf,0x85,0xcc,0x94}},\n    {{0xe1,0xbd,0x93},\t{0xcf,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbd,0x95},\t{0xcf,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbd,0x97},\t{0xcf,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0xa6},\t{0xcf,0x85,0xcd,0x82}},\n    {{0xe1,0xbd,0xbc},\t{0xcf,0x89,0xcc,0x80}},\n    {{0xe1,0xbd,0xbd},\t{0xcf,0x89,0xcc,0x81}},\n    {{0xcf,0x8e},\t{0xcf,0x89,0xcc,0x8d}},\n    {{0xe1,0xbd,0xa0},\t{0xcf,0x89,0xcc,0x93}},\n    {{0xe1,0xbd,0xa2},\t{0xcf,0x89,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbd,0xa4},\t{0xcf,0x89,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbd,0xa6},\t{0xcf,0x89,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbd,0xa1},\t{0xcf,0x89,0xcc,0x94}},\n    {{0xe1,0xbd,0xa3},\t{0xcf,0x89,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbd,0xa5},\t{0xcf,0x89,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbd,0xa7},\t{0xcf,0x89,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0xb6},\t{0xcf,0x89,0xcd,0x82}},\n    {{0xe1,0xbf,0xb3},\t{0xcf,0x89,0xcd,0x85}},\n    {{0xe1,0xbf,0xb2},\t{0xcf,0x89,0xcd,0x85,0xcc,0x80}},\n    {{0xe1,0xbe,0xa0},\t{0xcf,0x89,0xcd,0x85,0xcc,0x93}},\n    {{0xe1,0xbe,0xa2},\t{0xcf,0x89,0xcd,0x85,0xcc,0x93,0xcc,0x80}},\n    {{0xe1,0xbe,0xa4},\t{0xcf,0x89,0xcd,0x85,0xcc,0x93,0xcc,0x81}},\n    {{0xe1,0xbe,0xa6},\t{0xcf,0x89,0xcd,0x85,0xcc,0x93,0xcd,0x82}},\n    {{0xe1,0xbe,0xa1},\t{0xcf,0x89,0xcd,0x85,0xcc,0x94}},\n    {{0xe1,0xbe,0xa3},\t{0xcf,0x89,0xcd,0x85,0xcc,0x94,0xcc,0x80}},\n    {{0xe1,0xbe,0xa5},\t{0xcf,0x89,0xcd,0x85,0xcc,0x94,0xcc,0x81}},\n    {{0xe1,0xbe,0xa7},\t{0xcf,0x89,0xcd,0x85,0xcc,0x94,0xcd,0x82}},\n    {{0xe1,0xbf,0xb7},\t{0xcf,0x89,0xcd,0x85,0xcd,0x82}},\n    {{0xcf,0x94},\t{0xcf,0x92,0xcc,0x88}},\n    {{0xcf,0x93},\t{0xcf,0x92,0xcc,0x8d}},\n    {{0xd0,0x87},\t{0xd0,0x86,0xcc,0x88}},\n    {{0xd3,0x90},\t{0xd0,0x90,0xcc,0x86}},\n    {{0xd3,0x92},\t{0xd0,0x90,0xcc,0x88}},\n    {{0xd0,0x83},\t{0xd0,0x93,0xcc,0x81}},\n    {{0xd3,0x96},\t{0xd0,0x95,0xcc,0x86}},\n    {{0xd0,0x81},\t{0xd0,0x95,0xcc,0x88}},\n    {{0xd3,0x81},\t{0xd0,0x96,0xcc,0x86}},\n    {{0xd3,0x9c},\t{0xd0,0x96,0xcc,0x88}},\n    {{0xd3,0x9e},\t{0xd0,0x97,0xcc,0x88}},\n    {{0xd3,0xa2},\t{0xd0,0x98,0xcc,0x84}},\n    {{0xd0,0x99},\t{0xd0,0x98,0xcc,0x86}},\n    {{0xd3,0xa4},\t{0xd0,0x98,0xcc,0x88}},\n    {{0xd0,0x8c},\t{0xd0,0x9a,0xcc,0x81}},\n    {{0xd3,0xa6},\t{0xd0,0x9e,0xcc,0x88}},\n    {{0xd3,0xae},\t{0xd0,0xa3,0xcc,0x84}},\n    {{0xd0,0x8e},\t{0xd0,0xa3,0xcc,0x86}},\n    {{0xd3,0xb0},\t{0xd0,0xa3,0xcc,0x88}},\n    {{0xd3,0xb2},\t{0xd0,0xa3,0xcc,0x8b}},\n    {{0xd3,0xb4},\t{0xd0,0xa7,0xcc,0x88}},\n    {{0xd3,0xb8},\t{0xd0,0xab,0xcc,0x88}},\n    {{0xd3,0x91},\t{0xd0,0xb0,0xcc,0x86}},\n    {{0xd3,0x93},\t{0xd0,0xb0,0xcc,0x88}},\n    {{0xd1,0x93},\t{0xd0,0xb3,0xcc,0x81}},\n    {{0xd3,0x97},\t{0xd0,0xb5,0xcc,0x86}},\n    {{0xd1,0x91},\t{0xd0,0xb5,0xcc,0x88}},\n    {{0xd3,0x82},\t{0xd0,0xb6,0xcc,0x86}},\n    {{0xd3,0x9d},\t{0xd0,0xb6,0xcc,0x88}},\n    {{0xd3,0x9f},\t{0xd0,0xb7,0xcc,0x88}},\n    {{0xd3,0xa3},\t{0xd0,0xb8,0xcc,0x84}},\n    {{0xd0,0xb9},\t{0xd0,0xb8,0xcc,0x86}},\n    {{0xd3,0xa5},\t{0xd0,0xb8,0xcc,0x88}},\n    {{0xd1,0x9c},\t{0xd0,0xba,0xcc,0x81}},\n    {{0xd3,0xa7},\t{0xd0,0xbe,0xcc,0x88}},\n    {{0xd3,0xaf},\t{0xd1,0x83,0xcc,0x84}},\n    {{0xd1,0x9e},\t{0xd1,0x83,0xcc,0x86}},\n    {{0xd3,0xb1},\t{0xd1,0x83,0xcc,0x88}},\n    {{0xd3,0xb3},\t{0xd1,0x83,0xcc,0x8b}},\n    {{0xd3,0xb5},\t{0xd1,0x87,0xcc,0x88}},\n    {{0xd3,0xb9},\t{0xd1,0x8b,0xcc,0x88}},\n    {{0xd1,0x97},\t{0xd1,0x96,0xcc,0x88}},\n    {{0xd1,0xb6},\t{0xd1,0xb4,0xcc,0x8f}},\n    {{0xd1,0xb7},\t{0xd1,0xb5,0xcc,0x8f}},\n    {{0xef,0xac,0xae},\t{0xd7,0x90,0xd6,0xb7}},\n    {{0xef,0xac,0xaf},\t{0xd7,0x90,0xd6,0xb8}},\n    {{0xef,0xac,0xb0},\t{0xd7,0x90,0xd6,0xbc}},\n    {{0xef,0xac,0xb1},\t{0xd7,0x91,0xd6,0xbc}},\n    {{0xef,0xad,0x8c},\t{0xd7,0x91,0xd6,0xbf}},\n    {{0xef,0xac,0xb2},\t{0xd7,0x92,0xd6,0xbc}},\n    {{0xef,0xac,0xb3},\t{0xd7,0x93,0xd6,0xbc}},\n    {{0xef,0xac,0xb4},\t{0xd7,0x94,0xd6,0xbc}},\n    {{0xef,0xad,0x8b},\t{0xd7,0x95,0xd6,0xb9}},\n    {{0xef,0xac,0xb5},\t{0xd7,0x95,0xd6,0xbc}},\n    {{0xef,0xac,0xb6},\t{0xd7,0x96,0xd6,0xbc}},\n    {{0xef,0xac,0xb8},\t{0xd7,0x98,0xd6,0xbc}},\n    {{0xef,0xac,0xb9},\t{0xd7,0x99,0xd6,0xbc}},\n    {{0xef,0xac,0xba},\t{0xd7,0x9a,0xd6,0xbc}},\n    {{0xef,0xac,0xbb},\t{0xd7,0x9b,0xd6,0xbc}},\n    {{0xef,0xad,0x8d},\t{0xd7,0x9b,0xd6,0xbf}},\n    {{0xef,0xac,0xbc},\t{0xd7,0x9c,0xd6,0xbc}},\n    {{0xef,0xac,0xbe},\t{0xd7,0x9e,0xd6,0xbc}},\n    {{0xef,0xad,0x80},\t{0xd7,0xa0,0xd6,0xbc}},\n    {{0xef,0xad,0x81},\t{0xd7,0xa1,0xd6,0xbc}},\n    {{0xef,0xad,0x83},\t{0xd7,0xa3,0xd6,0xbc}},\n    {{0xef,0xad,0x84},\t{0xd7,0xa4,0xd6,0xbc}},\n    {{0xef,0xad,0x8e},\t{0xd7,0xa4,0xd6,0xbf}},\n    {{0xef,0xad,0x86},\t{0xd7,0xa6,0xd6,0xbc}},\n    {{0xef,0xad,0x87},\t{0xd7,0xa7,0xd6,0xbc}},\n    {{0xef,0xad,0x88},\t{0xd7,0xa8,0xd6,0xbc}},\n    {{0xef,0xad,0x89},\t{0xd7,0xa9,0xd6,0xbc}},\n    {{0xef,0xac,0xac},\t{0xd7,0xa9,0xd6,0xbc,0xd7,0x81}},\n    {{0xef,0xac,0xad},\t{0xd7,0xa9,0xd6,0xbc,0xd7,0x82}},\n    {{0xef,0xac,0xaa},\t{0xd7,0xa9,0xd7,0x81}},\n    {{0xef,0xac,0xab},\t{0xd7,0xa9,0xd7,0x82}},\n    {{0xef,0xad,0x8a},\t{0xd7,0xaa,0xd6,0xbc}},\n    {{0xef,0xac,0x9f},\t{0xd7,0xb2,0xd6,0xb7}},\n    {{0xe0,0xa5,0x98},\t{0xe0,0xa4,0x95,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x99},\t{0xe0,0xa4,0x96,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x9a},\t{0xe0,0xa4,0x97,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x9b},\t{0xe0,0xa4,0x9c,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x9c},\t{0xe0,0xa4,0xa1,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x9d},\t{0xe0,0xa4,0xa2,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa4,0xa9},\t{0xe0,0xa4,0xa8,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x9e},\t{0xe0,0xa4,0xab,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa5,0x9f},\t{0xe0,0xa4,0xaf,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa4,0xb1},\t{0xe0,0xa4,0xb0,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa4,0xb4},\t{0xe0,0xa4,0xb3,0xe0,0xa4,0xbc}},\n    {{0xe0,0xa7,0x9c},\t{0xe0,0xa6,0xa1,0xe0,0xa6,0xbc}},\n    {{0xe0,0xa7,0x9d},\t{0xe0,0xa6,0xa2,0xe0,0xa6,0xbc}},\n    {{0xe0,0xa6,0xb0},\t{0xe0,0xa6,0xac,0xe0,0xa6,0xbc}},\n    {{0xe0,0xa7,0x9f},\t{0xe0,0xa6,0xaf,0xe0,0xa6,0xbc}},\n    {{0xe0,0xa7,0x8b},\t{0xe0,0xa7,0x87,0xe0,0xa6,0xbe}},\n    {{0xe0,0xa7,0x8c},\t{0xe0,0xa7,0x87,0xe0,0xa7,0x97}},\n    {{0xe0,0xa9,0x99},\t{0xe0,0xa8,0x96,0xe0,0xa8,0xbc}},\n    {{0xe0,0xa9,0x9a},\t{0xe0,0xa8,0x97,0xe0,0xa8,0xbc}},\n    {{0xe0,0xa9,0x9b},\t{0xe0,0xa8,0x9c,0xe0,0xa8,0xbc}},\n    {{0xe0,0xa9,0x9c},\t{0xe0,0xa8,0xa1,0xe0,0xa8,0xbc}},\n    {{0xe0,0xa9,0x9e},\t{0xe0,0xa8,0xab,0xe0,0xa8,0xbc}},\n    {{0xe0,0xad,0x9c},\t{0xe0,0xac,0xa1,0xe0,0xac,0xbc}},\n    {{0xe0,0xad,0x9d},\t{0xe0,0xac,0xa2,0xe0,0xac,0xbc}},\n    {{0xe0,0xad,0x9f},\t{0xe0,0xac,0xaf,0xe0,0xac,0xbc}},\n    {{0xe0,0xad,0x8b},\t{0xe0,0xad,0x87,0xe0,0xac,0xbe}},\n    {{0xe0,0xad,0x88},\t{0xe0,0xad,0x87,0xe0,0xad,0x96}},\n    {{0xe0,0xad,0x8c},\t{0xe0,0xad,0x87,0xe0,0xad,0x97}},\n    {{0xe0,0xae,0x94},\t{0xe0,0xae,0x92,0xe0,0xaf,0x97}},\n    {{0xe0,0xaf,0x8a},\t{0xe0,0xaf,0x86,0xe0,0xae,0xbe}},\n    {{0xe0,0xaf,0x8c},\t{0xe0,0xaf,0x86,0xe0,0xaf,0x97}},\n    {{0xe0,0xaf,0x8b},\t{0xe0,0xaf,0x87,0xe0,0xae,0xbe}},\n    {{0xe0,0xb1,0x88},\t{0xe0,0xb1,0x86,0xe0,0xb1,0x96}},\n    {{0xe0,0xb3,0x80},\t{0xe0,0xb2,0xbf,0xe0,0xb3,0x95}},\n    {{0xe0,0xb3,0x8a},\t{0xe0,0xb3,0x86,0xe0,0xb3,0x82}},\n    {{0xe0,0xb3,0x8b},\t{0xe0,0xb3,0x86,0xe0,0xb3,0x82,0xe0,0xb3,0x95}},\n    {{0xe0,0xb3,0x87},\t{0xe0,0xb3,0x86,0xe0,0xb3,0x95}},\n    {{0xe0,0xb3,0x88},\t{0xe0,0xb3,0x86,0xe0,0xb3,0x96}},\n    {{0xe0,0xb5,0x8a},\t{0xe0,0xb5,0x86,0xe0,0xb4,0xbe}},\n    {{0xe0,0xb5,0x8c},\t{0xe0,0xb5,0x86,0xe0,0xb5,0x97}},\n    {{0xe0,0xb5,0x8b},\t{0xe0,0xb5,0x87,0xe0,0xb4,0xbe}},\n    {{0xe0,0xb8,0xb3},\t{0xe0,0xb9,0x8d,0xe0,0xb8,0xb2}},\n    {{0xe0,0xba,0xb3},\t{0xe0,0xbb,0x8d,0xe0,0xba,0xb2}},\n    {{0xe0,0xbd,0xa9},\t{0xe0,0xbd,0x80,0xe0,0xbe,0xb5}},\n    {{0xe0,0xbd,0x83},\t{0xe0,0xbd,0x82,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbd,0x8d},\t{0xe0,0xbd,0x8c,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbd,0x92},\t{0xe0,0xbd,0x91,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbd,0x97},\t{0xe0,0xbd,0x96,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbd,0x9c},\t{0xe0,0xbd,0x9b,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbd,0xb3},\t{0xe0,0xbd,0xb2,0xe0,0xbd,0xb1}},\n    {{0xe0,0xbd,0xb5},\t{0xe0,0xbd,0xb4,0xe0,0xbd,0xb1}},\n    {{0xe0,0xbe,0x81},\t{0xe0,0xbe,0x80,0xe0,0xbd,0xb1}},\n    {{0xe0,0xbe,0xb9},\t{0xe0,0xbe,0x90,0xe0,0xbe,0xb5}},\n    {{0xe0,0xbe,0x93},\t{0xe0,0xbe,0x92,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbe,0x9d},\t{0xe0,0xbe,0x9c,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbe,0xa2},\t{0xe0,0xbe,0xa1,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbe,0xa7},\t{0xe0,0xbe,0xa6,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbe,0xac},\t{0xe0,0xbe,0xab,0xe0,0xbe,0xb7}},\n    {{0xe0,0xbd,0xb6},\t{0xe0,0xbe,0xb2,0xe0,0xbe,0x80}},\n    {{0xe0,0xbd,0xb7},\t{0xe0,0xbe,0xb2,0xe0,0xbe,0x80,0xe0,0xbd,0xb1}},\n    {{0xe0,0xbd,0xb8},\t{0xe0,0xbe,0xb3,0xe0,0xbe,0x80}},\n    {{0xe0,0xbd,0xb9},\t{0xe0,0xbe,0xb3,0xe0,0xbe,0x80,0xe0,0xbd,0xb1}},\n    {{0xe1,0xbf,0x8d},\t{0xe1,0xbe,0xbf,0xcc,0x80}},\n    {{0xe1,0xbf,0x8e},\t{0xe1,0xbe,0xbf,0xcc,0x81}},\n    {{0xe1,0xbf,0x8f},\t{0xe1,0xbe,0xbf,0xcd,0x82}},\n    {{0xe1,0xbf,0x9d},\t{0xe1,0xbf,0xbe,0xcc,0x80}},\n    {{0xe1,0xbf,0x9e},\t{0xe1,0xbf,0xbe,0xcc,0x81}},\n    {{0xe1,0xbf,0x9f},\t{0xe1,0xbf,0xbe,0xcd,0x82}},\n    {{0xe3,0x82,0x94},\t{0xe3,0x81,0x86,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x8c},\t{0xe3,0x81,0x8b,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x8e},\t{0xe3,0x81,0x8d,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x90},\t{0xe3,0x81,0x8f,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x92},\t{0xe3,0x81,0x91,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x94},\t{0xe3,0x81,0x93,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x96},\t{0xe3,0x81,0x95,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x98},\t{0xe3,0x81,0x97,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x9a},\t{0xe3,0x81,0x99,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x9c},\t{0xe3,0x81,0x9b,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0x9e},\t{0xe3,0x81,0x9d,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xa0},\t{0xe3,0x81,0x9f,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xa2},\t{0xe3,0x81,0xa1,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xa5},\t{0xe3,0x81,0xa4,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xa7},\t{0xe3,0x81,0xa6,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xa9},\t{0xe3,0x81,0xa8,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xb0},\t{0xe3,0x81,0xaf,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xb1},\t{0xe3,0x81,0xaf,0xe3,0x82,0x9a}},\n    {{0xe3,0x81,0xb3},\t{0xe3,0x81,0xb2,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xb4},\t{0xe3,0x81,0xb2,0xe3,0x82,0x9a}},\n    {{0xe3,0x81,0xb6},\t{0xe3,0x81,0xb5,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xb7},\t{0xe3,0x81,0xb5,0xe3,0x82,0x9a}},\n    {{0xe3,0x81,0xb9},\t{0xe3,0x81,0xb8,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xba},\t{0xe3,0x81,0xb8,0xe3,0x82,0x9a}},\n    {{0xe3,0x81,0xbc},\t{0xe3,0x81,0xbb,0xe3,0x82,0x99}},\n    {{0xe3,0x81,0xbd},\t{0xe3,0x81,0xbb,0xe3,0x82,0x9a}},\n    {{0xe3,0x82,0x9e},\t{0xe3,0x82,0x9d,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0xb4},\t{0xe3,0x82,0xa6,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xac},\t{0xe3,0x82,0xab,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xae},\t{0xe3,0x82,0xad,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xb0},\t{0xe3,0x82,0xaf,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xb2},\t{0xe3,0x82,0xb1,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xb4},\t{0xe3,0x82,0xb3,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xb6},\t{0xe3,0x82,0xb5,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xb8},\t{0xe3,0x82,0xb7,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xba},\t{0xe3,0x82,0xb9,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xbc},\t{0xe3,0x82,0xbb,0xe3,0x82,0x99}},\n    {{0xe3,0x82,0xbe},\t{0xe3,0x82,0xbd,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x80},\t{0xe3,0x82,0xbf,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x82},\t{0xe3,0x83,0x81,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x85},\t{0xe3,0x83,0x84,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x87},\t{0xe3,0x83,0x86,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x89},\t{0xe3,0x83,0x88,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x90},\t{0xe3,0x83,0x8f,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x91},\t{0xe3,0x83,0x8f,0xe3,0x82,0x9a}},\n    {{0xe3,0x83,0x93},\t{0xe3,0x83,0x92,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x94},\t{0xe3,0x83,0x92,0xe3,0x82,0x9a}},\n    {{0xe3,0x83,0x96},\t{0xe3,0x83,0x95,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x97},\t{0xe3,0x83,0x95,0xe3,0x82,0x9a}},\n    {{0xe3,0x83,0x99},\t{0xe3,0x83,0x98,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x9a},\t{0xe3,0x83,0x98,0xe3,0x82,0x9a}},\n    {{0xe3,0x83,0x9c},\t{0xe3,0x83,0x9b,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0x9d},\t{0xe3,0x83,0x9b,0xe3,0x82,0x9a}},\n    {{0xe3,0x83,0xb7},\t{0xe3,0x83,0xaf,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0xb8},\t{0xe3,0x83,0xb0,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0xb9},\t{0xe3,0x83,0xb1,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0xba},\t{0xe3,0x83,0xb2,0xe3,0x82,0x99}},\n    {{0xe3,0x83,0xbe},\t{0xe3,0x83,0xbd,0xe3,0x82,0x99}},\n};\n#endif /* UNICODE_NORMALIZATION */\n#endif /* UTF8_INPUT_ENABLE */\n\n#ifdef SHIFTJIS_CP932\nconst unsigned short shiftjis_cp932[3][189] = {\n {\n  0xEEEF, 0xEEF0, 0xEEF1, 0xEEF2, 0xEEF3, 0xEEF4, 0xEEF5, 0xEEF6,\n  0xEEF7, 0xEEF8, 0x8754, 0x8755, 0x8756, 0x8757, 0x8758, 0x8759,\n  0x875A, 0x875B, 0x875C, 0x875D, 0x81CA, 0xEEFA, 0xEEFB, 0xEEFC,\n  0x878A, 0x8782, 0x8784, 0x81E6, 0xED40, 0xED41, 0xED42, 0xED43,\n  0xED44, 0xED45, 0xED46, 0xED47, 0xED48, 0xED49, 0xED4A, 0xED4B,\n  0xED4C, 0xED4D, 0xED4E, 0xED4F, 0xED50, 0xED51, 0xED52, 0xED53,\n  0xED54, 0xED55, 0xED56, 0xED57, 0xED58, 0xED59, 0xED5A, 0xED5B,\n  0xED5C, 0xED5D, 0xED5E, 0xED5F, 0xED60, 0xED61, 0xED62,      0,\n  0xED63, 0xED64, 0xED65, 0xED66, 0xED67, 0xED68, 0xED69, 0xED6A,\n  0xED6B, 0xED6C, 0xED6D, 0xED6E, 0xED6F, 0xED70, 0xED71, 0xED72,\n  0xED73, 0xED74, 0xED75, 0xED76, 0xED77, 0xED78, 0xED79, 0xED7A,\n  0xED7B, 0xED7C, 0xED7D, 0xED7E, 0xED80, 0xED81, 0xED82, 0xED83,\n  0xED84, 0xED85, 0xED86, 0xED87, 0xED88, 0xED89, 0xED8A, 0xED8B,\n  0xED8C, 0xED8D, 0xED8E, 0xED8F, 0xED90, 0xED91, 0xED92, 0xED93,\n  0xED94, 0xED95, 0xED96, 0xED97, 0xED98, 0xED99, 0xED9A, 0xED9B,\n  0xED9C, 0xED9D, 0xED9E, 0xED9F, 0xEDA0, 0xEDA1, 0xEDA2, 0xEDA3,\n  0xEDA4, 0xEDA5, 0xEDA6, 0xEDA7, 0xEDA8, 0xEDA9, 0xEDAA, 0xEDAB,\n  0xEDAC, 0xEDAD, 0xEDAE, 0xEDAF, 0xEDB0, 0xEDB1, 0xEDB2, 0xEDB3,\n  0xEDB4, 0xEDB5, 0xEDB6, 0xEDB7, 0xEDB8, 0xEDB9, 0xEDBA, 0xEDBB,\n  0xEDBC, 0xEDBD, 0xEDBE, 0xEDBF, 0xEDC0, 0xEDC1, 0xEDC2, 0xEDC3,\n  0xEDC4, 0xEDC5, 0xEDC6, 0xEDC7, 0xEDC8, 0xEDC9, 0xEDCA, 0xEDCB,\n  0xEDCC, 0xEDCD, 0xEDCE, 0xEDCF, 0xEDD0, 0xEDD1, 0xEDD2, 0xEDD3,\n  0xEDD4, 0xEDD5, 0xEDD6, 0xEDD7, 0xEDD8, 0xEDD9, 0xEDDA, 0xEDDB,\n  0xEDDC, 0xEDDD, 0xEDDE, 0xEDDF, 0xEDE0,\n },\n {\n  0xEDE1, 0xEDE2, 0xEDE3, 0xEDE4, 0xEDE5, 0xEDE6, 0xEDE7, 0xEDE8,\n  0xEDE9, 0xEDEA, 0xEDEB, 0xEDEC, 0xEDED, 0xEDEE, 0xEDEF, 0xEDF0,\n  0xEDF1, 0xEDF2, 0xEDF3, 0xEDF4, 0xEDF5, 0xEDF6, 0xEDF7, 0xEDF8,\n  0xEDF9, 0xEDFA, 0xEDFB, 0xEDFC, 0xEE40, 0xEE41, 0xEE42, 0xEE43,\n  0xEE44, 0xEE45, 0xEE46, 0xEE47, 0xEE48, 0xEE49, 0xEE4A, 0xEE4B,\n  0xEE4C, 0xEE4D, 0xEE4E, 0xEE4F, 0xEE50, 0xEE51, 0xEE52, 0xEE53,\n  0xEE54, 0xEE55, 0xEE56, 0xEE57, 0xEE58, 0xEE59, 0xEE5A, 0xEE5B,\n  0xEE5C, 0xEE5D, 0xEE5E, 0xEE5F, 0xEE60, 0xEE61, 0xEE62,      0,\n  0xEE63, 0xEE64, 0xEE65, 0xEE66, 0xEE67, 0xEE68, 0xEE69, 0xEE6A,\n  0xEE6B, 0xEE6C, 0xEE6D, 0xEE6E, 0xEE6F, 0xEE70, 0xEE71, 0xEE72,\n  0xEE73, 0xEE74, 0xEE75, 0xEE76, 0xEE77, 0xEE78, 0xEE79, 0xEE7A,\n  0xEE7B, 0xEE7C, 0xEE7D, 0xEE7E, 0xEE80, 0xEE81, 0xEE82, 0xEE83,\n  0xEE84, 0xEE85, 0xEE86, 0xEE87, 0xEE88, 0xEE89, 0xEE8A, 0xEE8B,\n  0xEE8C, 0xEE8D, 0xEE8E, 0xEE8F, 0xEE90, 0xEE91, 0xEE92, 0xEE93,\n  0xEE94, 0xEE95, 0xEE96, 0xEE97, 0xEE98, 0xEE99, 0xEE9A, 0xEE9B,\n  0xEE9C, 0xEE9D, 0xEE9E, 0xEE9F, 0xEEA0, 0xEEA1, 0xEEA2, 0xEEA3,\n  0xEEA4, 0xEEA5, 0xEEA6, 0xEEA7, 0xEEA8, 0xEEA9, 0xEEAA, 0xEEAB,\n  0xEEAC, 0xEEAD, 0xEEAE, 0xEEAF, 0xEEB0, 0xEEB1, 0xEEB2, 0xEEB3,\n  0xEEB4, 0xEEB5, 0xEEB6, 0xEEB7, 0xEEB8, 0xEEB9, 0xEEBA, 0xEEBB,\n  0xEEBC, 0xEEBD, 0xEEBE, 0xEEBF, 0xEEC0, 0xEEC1, 0xEEC2, 0xEEC3,\n  0xEEC4, 0xEEC5, 0xEEC6, 0xEEC7, 0xEEC8, 0xEEC9, 0xEECA, 0xEECB,\n  0xEECC, 0xEECD, 0xEECE, 0xEECF, 0xEED0, 0xEED1, 0xEED2, 0xEED3,\n  0xEED4, 0xEED5, 0xEED6, 0xEED7, 0xEED8, 0xEED9, 0xEEDA, 0xEEDB,\n  0xEEDC, 0xEEDD, 0xEEDE, 0xEEDF, 0xEEE0,\n },\n {\n  0xEEE1, 0xEEE2, 0xEEE3, 0xEEE4, 0xEEE5, 0xEEE6, 0xEEE7, 0xEEE8,\n  0xEEE9, 0xEEEA, 0xEEEB, 0xEEEC,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,\n },\n};\nconst unsigned short cp932inv[2][189] = {\n {\n  0xFA5C, 0xFA5D, 0xFA5E, 0xFA5F, 0xFA60, 0xFA61, 0xFA62, 0xFA63,\n  0xFA64, 0xFA65, 0xFA66, 0xFA67, 0xFA68, 0xFA69, 0xFA6A, 0xFA6B,\n  0xFA6C, 0xFA6D, 0xFA6E, 0xFA6F, 0xFA70, 0xFA71, 0xFA72, 0xFA73,\n  0xFA74, 0xFA75, 0xFA76, 0xFA77, 0xFA78, 0xFA79, 0xFA7A, 0xFA7B,\n  0xFA7C, 0xFA7D, 0xFA7E, 0xFA80, 0xFA81, 0xFA82, 0xFA83, 0xFA84,\n  0xFA85, 0xFA86, 0xFA87, 0xFA88, 0xFA89, 0xFA8A, 0xFA8B, 0xFA8C,\n  0xFA8D, 0xFA8E, 0xFA8F, 0xFA90, 0xFA91, 0xFA92, 0xFA93, 0xFA94,\n  0xFA95, 0xFA96, 0xFA97, 0xFA98, 0xFA99, 0xFA9A, 0xFA9B,      0,\n  0xFA9C, 0xFA9D, 0xFA9E, 0xFA9F, 0xFAA0, 0xFAA1, 0xFAA2, 0xFAA3,\n  0xFAA4, 0xFAA5, 0xFAA6, 0xFAA7, 0xFAA8, 0xFAA9, 0xFAAA, 0xFAAB,\n  0xFAAC, 0xFAAD, 0xFAAE, 0xFAAF, 0xFAB0, 0xFAB1, 0xFAB2, 0xFAB3,\n  0xFAB4, 0xFAB5, 0xFAB6, 0xFAB7, 0xFAB8, 0xFAB9, 0xFABA, 0xFABB,\n  0xFABC, 0xFABD, 0xFABE, 0xFABF, 0xFAC0, 0xFAC1, 0xFAC2, 0xFAC3,\n  0xFAC4, 0xFAC5, 0xFAC6, 0xFAC7, 0xFAC8, 0xFAC9, 0xFACA, 0xFACB,\n  0xFACC, 0xFACD, 0xFACE, 0xFACF, 0xFAD0, 0xFAD1, 0xFAD2, 0xFAD3,\n  0xFAD4, 0xFAD5, 0xFAD6, 0xFAD7, 0xFAD8, 0xFAD9, 0xFADA, 0xFADB,\n  0xFADC, 0xFADD, 0xFADE, 0xFADF, 0xFAE0, 0xFAE1, 0xFAE2, 0xFAE3,\n  0xFAE4, 0xFAE5, 0xFAE6, 0xFAE7, 0xFAE8, 0xFAE9, 0xFAEA, 0xFAEB,\n  0xFAEC, 0xFAED, 0xFAEE, 0xFAEF, 0xFAF0, 0xFAF1, 0xFAF2, 0xFAF3,\n  0xFAF4, 0xFAF5, 0xFAF6, 0xFAF7, 0xFAF8, 0xFAF9, 0xFAFA, 0xFAFB,\n  0xFAFC, 0xFB40, 0xFB41, 0xFB42, 0xFB43, 0xFB44, 0xFB45, 0xFB46,\n  0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C, 0xFB4D, 0xFB4E,\n  0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55, 0xFB56,\n  0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B,\n },\n {\n  0xFB5C, 0xFB5D, 0xFB5E, 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63,\n  0xFB64, 0xFB65, 0xFB66, 0xFB67, 0xFB68, 0xFB69, 0xFB6A, 0xFB6B,\n  0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70, 0xFB71, 0xFB72, 0xFB73,\n  0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79, 0xFB7A, 0xFB7B,\n  0xFB7C, 0xFB7D, 0xFB7E, 0xFB80, 0xFB81, 0xFB82, 0xFB83, 0xFB84,\n  0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B, 0xFB8C,\n  0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,\n  0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B,      0,\n  0xFB9C, 0xFB9D, 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3,\n  0xFBA4, 0xFBA5, 0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB,\n  0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF, 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3,\n  0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8, 0xFBB9, 0xFBBA, 0xFBBB,\n  0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1, 0xFBC2, 0xFBC3,\n  0xFBC4, 0xFBC5, 0xFBC6, 0xFBC7, 0xFBC8, 0xFBC9, 0xFBCA, 0xFBCB,\n  0xFBCC, 0xFBCD, 0xFBCE, 0xFBCF, 0xFBD0, 0xFBD1, 0xFBD2, 0xFBD3,\n  0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,\n  0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3,\n  0xFBE4, 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB,\n  0xFBEC, 0xFBED, 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3,\n  0xFBF4, 0xFBF5, 0xFBF6, 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB,\n  0xFBFC, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46,\n  0xFC47, 0xFC48, 0xFC49, 0xFC4A, 0xFC4B,      0,      0, 0xFA40,\n  0xFA41, 0xFA42, 0xFA43, 0xFA44, 0xFA45, 0xFA46, 0xFA47, 0xFA48,\n  0xFA49, 0x81CA, 0xFA55, 0xFA56, 0xFA57,\n },\n};\n#endif /* SHIFTJIS_CP932 */\n\n#ifdef X0212_ENABLE\nconst unsigned short shiftjis_x0212[3][189] = {\n {\n  0xF373, 0xF374, 0xF375, 0xF376, 0xF377, 0xF378, 0xF379, 0xF37A,\n  0xF37B, 0xF37C, 0xF37D, 0xF37E, 0xF421, 0xF422, 0xF423, 0xF424,\n  0xF425, 0xF426, 0xF427, 0xF428, 0x224C, 0xA243, 0xF429, 0xF42A,\n  0xF42B, 0xF42C, 0xF42D, 0x2268, 0xD463, 0xDC5F, 0xE469, 0xE378,\n  0xD921, 0xB13B, 0xF42E, 0xC22D, 0xC37C, 0xE450, 0xC23F, 0xBC74,\n  0xB029, 0xB048, 0xF42F, 0xB052, 0xB054, 0xB063, 0xB06E, 0xB127,\n  0xB123, 0xB12C, 0xB129, 0xB13E, 0xB15F, 0xB158, 0xB148, 0xB157,\n  0xB163, 0xB174, 0xB161, 0xB223, 0xF430, 0xB23B, 0xB266,      0,\n  0xB26D, 0xB275, 0xB27C, 0xF431, 0xB335, 0xB358, 0xB35B, 0xB365,\n  0xB36E, 0xB37B, 0xF432, 0xF433, 0xB440, 0xB447, 0xB450, 0xB45E,\n  0xF434, 0xB52A, 0xF435, 0xB52F, 0xB544, 0xB568, 0xF436, 0xB742,\n  0xB764, 0xB768, 0xB767, 0xF437, 0xF438, 0xF439, 0xB84E, 0xB861,\n  0xB875, 0xB877, 0xB878, 0xB87C, 0xB92F, 0xB937, 0xBA3E, 0xBA5B,\n  0xCD2A, 0xBA61, 0xF43A, 0xBA6B, 0xBB33, 0xBB38, 0xF43B, 0xBB4A,\n  0xF43C, 0xF43D, 0xBB50, 0xBB5E, 0xBB74, 0xBB75, 0xBB79, 0xBC64,\n  0xBC6D, 0xBC7E, 0xF43E, 0xBD42, 0xBD67, 0xF43F, 0xBD70, 0xBE30,\n  0xBE2C, 0xF440, 0xBE33, 0xBE3D, 0xBE4D, 0xBE49, 0xBE64, 0xBF28,\n  0xBF49, 0xC044, 0xC064, 0xC074, 0xC126, 0xF441, 0xC175, 0xC17C,\n  0xF442, 0xC178, 0xC22B, 0xC221, 0xC225, 0xF443, 0xC238, 0xC23A,\n  0xF444, 0xC244, 0xC252, 0xC257, 0xC25B, 0xC25E, 0xC26D, 0xC270,\n  0xF445, 0xC321, 0xC335, 0xC349, 0xC339, 0xF446, 0xC358, 0xC37E,\n  0xF447, 0xC44C, 0xF448, 0xC459, 0xC46A, 0xC47D, 0xF449, 0xC527,\n  0xC535, 0xC536, 0xF44A, 0xC555, 0xC638, 0xC657, 0xC660, 0xC66A,\n  0xC663, 0xC721, 0xC72B, 0xC747, 0xC743,\n },\n {\n  0xC74B, 0xC74F, 0xC759, 0xF44B, 0xF44C, 0xC766, 0xC76E, 0xC77C,\n  0xC76B, 0xC770, 0xC831, 0xC865, 0xC878, 0xC926, 0xC92B, 0xC92D,\n  0xF44D, 0xC94A, 0xC953, 0xC969, 0xC963, 0xC97C, 0xC974, 0xC975,\n  0xF44E, 0xCA33, 0xCA3D, 0xCA6F, 0xCA71, 0xCB2E, 0xF44F, 0xCB4A,\n  0xCB66, 0xCB6A, 0xCB70, 0xCB74, 0xCB6E, 0xCC25, 0xCB79, 0xCC2B,\n  0xCC2E, 0xCC2D, 0xCC32, 0xCC42, 0xCC50, 0xCC59, 0xF450, 0xCD3B,\n  0xF451, 0xCE3B, 0xF452, 0xCE3A, 0xCE43, 0xF453, 0xCE72, 0xB35D,\n  0xCF55, 0xCF62, 0xCF69, 0xCF6D, 0xF454, 0xF455, 0xF456,      0,\n  0xF457, 0xD065, 0xF458, 0xD069, 0xD168, 0xF459, 0xF45A, 0xD16C,\n  0xD23B, 0xF45B, 0xD361, 0xD368, 0xD427, 0xF45C, 0xF45D, 0xD454,\n  0xD472, 0xD52E, 0xF45E, 0xD75E, 0xF45F, 0xD822, 0xD837, 0xD841,\n  0xD851, 0xD874, 0xD946, 0xD948, 0xD951, 0xF460, 0xF461, 0xF462,\n  0xF463, 0xF464, 0xDC53, 0xDD48, 0xDD54, 0xDD6A, 0xDD7A, 0xDE24,\n  0xDE30, 0xF465, 0xDE35, 0xDE4B, 0xF466, 0xDF39, 0xF467, 0xDF43,\n  0xF468, 0xF469, 0xE059, 0xF46A, 0xF46B, 0xE162, 0xF46C, 0xF46D,\n  0xF46E, 0xE247, 0xE328, 0xE326, 0xE329, 0xE32F, 0xE330, 0xE32A,\n  0xE32B, 0xE33C, 0xE341, 0xE33F, 0xE355, 0xE358, 0xE356, 0xE35F,\n  0xE363, 0xE361, 0xE354, 0xE369, 0xE426, 0xE371, 0xE372, 0xE44B,\n  0xE441, 0xE443, 0xE43E, 0xF46F, 0xE440, 0xE447, 0xE43F, 0xE460,\n  0xE45E, 0xE451, 0xF470, 0xE45C, 0xE452, 0xE45B, 0xE454, 0xE47A,\n  0xE46F, 0xE533, 0xE53F, 0xE549, 0xE550, 0xE562, 0xE56A, 0xE56B,\n  0xF471, 0xF472, 0xF473, 0xE668, 0xE66F, 0xE72C, 0xF474, 0xE72E,\n  0xF475, 0xE731, 0xF476, 0xE732, 0xE831, 0xE836, 0xF477, 0xF478,\n  0xE85D, 0xF479, 0xF47A, 0xE951, 0xF47B,\n },\n {\n  0xE96D, 0xEA4D, 0xF47C, 0xEA5B, 0xEA66, 0xEA6A, 0xEB25, 0xEB7B,\n  0xEB7A, 0xF47D, 0xEC56, 0xF47E,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,      0,      0,      0,\n       0,      0,      0,      0,      0,\n },\n};\n\nconst unsigned short x0212_shiftjis_A2[] = {\n         0x819F,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0x8143,      0,      0, 0x8150,      0,      0, 0x8160,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA55,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B0[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0, 0xFA68,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFA69,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFA6B,      0, 0xFA6C,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA6D,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFA6E,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B1[] = {\n              0,      0, 0xFA70,      0,      0,      0, 0xFA6F,\n      0, 0xFA72,      0,      0, 0xFA71,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA61,      0,      0, 0xFA73,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFA76,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFA77,\n 0xFA75,      0,      0,      0,      0,      0,      0, 0xFA74,\n      0, 0xFA7A,      0, 0xFA78,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFA79,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B2[] = {\n              0,      0, 0xFA7B,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA7D,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFA7E,      0,\n      0,      0,      0,      0,      0, 0xFA80,      0,      0,\n      0,      0,      0,      0,      0, 0xFA81,      0,      0,\n      0,      0,      0,      0, 0xFA82,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B3[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFA84,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFA85,      0,      0, 0xFA86,      0, 0xFB77,      0,      0,\n      0,      0,      0,      0,      0, 0xFA87,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFA88,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA89,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B4[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFA8C,      0,      0,      0,      0,      0,      0, 0xFA8D,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFA8E,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFA8F,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B5[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFA91,      0,      0,      0,      0, 0xFA93,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFA94,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFA95,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B7[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFA97,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFA98,      0,      0, 0xFA9A,\n 0xFA99,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B8[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFA9E,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFA9F,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAA0,      0, 0xFAA1,\n 0xFAA2,      0,      0,      0, 0xFAA3,      0,      0,\n};\nconst unsigned short x0212_shiftjis_B9[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFAA4,\n      0,      0,      0,      0,      0,      0,      0, 0xFAA5,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_BA[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFAA6,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFAA7,      0,      0,      0,      0,\n      0, 0xFAA9,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFAAB,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_BB[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFAAC,      0,      0,      0,      0,\n 0xFAAD,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFAAF,      0,      0,      0,      0,      0,\n 0xFAB2,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFAB3,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFAB4, 0xFAB5,      0,      0,\n      0, 0xFAB6,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_BC[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFAB7,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAB8,      0,      0,\n      0,      0,      0,      0, 0xFA67,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFAB9,\n};\nconst unsigned short x0212_shiftjis_BD[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFABB,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFABC,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFABE,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_BE[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFAC0,      0,      0,      0,\n 0xFABF,      0,      0, 0xFAC2,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAC3,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFAC5,      0,      0,      0, 0xFAC4,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFAC6,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_BF[] = {\n              0,      0,      0,      0,      0,      0,      0,\n 0xFAC7,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFAC8,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C0[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFAC9,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFACA,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFACB,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C1[] = {\n              0,      0,      0,      0,      0, 0xFACC,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFACE,      0,      0,\n 0xFAD1,      0,      0,      0, 0xFACF,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C2[] = {\n         0xFAD3,      0,      0,      0, 0xFAD4,      0,      0,\n      0,      0,      0, 0xFAD2,      0, 0xFA63,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFAD6,      0, 0xFAD7,      0,      0,      0,      0, 0xFA66,\n      0,      0,      0,      0, 0xFAD9,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFADA,      0,      0,      0,      0, 0xFADB,\n      0,      0,      0, 0xFADC,      0,      0, 0xFADD,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFADE,      0,      0,\n 0xFADF,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C3[] = {\n         0xFAE1,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAE2,      0,      0,\n      0, 0xFAE4,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFAE3,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFAE6,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFA64,      0, 0xFAE7,\n};\nconst unsigned short x0212_shiftjis_C4[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFAE9,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFAEB,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFAEC,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAED,      0,\n};\nconst unsigned short x0212_shiftjis_C5[] = {\n              0,      0,      0,      0,      0,      0, 0xFAEF,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAF0, 0xFAF1,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFAF3,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C6[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFAF4,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFAF5,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFAF6,      0,      0, 0xFAF8,      0,      0,      0,      0,\n      0,      0, 0xFAF7,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C7[] = {\n         0xFAF9,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFAFA,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFAFC,      0,      0,      0, 0xFAFB,\n      0,      0,      0, 0xFB40,      0,      0,      0, 0xFB41,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB42,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFB45,      0,\n      0,      0,      0, 0xFB48,      0,      0, 0xFB46,      0,\n 0xFB49,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFB47,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C8[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB4A,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFB4B,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFB4C,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_C9[] = {\n              0,      0,      0,      0,      0, 0xFB4D,      0,\n      0,      0,      0, 0xFB4E,      0, 0xFB4F,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB51,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFB52,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFB54,      0,      0,      0,      0,\n      0, 0xFB53,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFB56, 0xFB57,      0,      0,\n      0,      0,      0,      0, 0xFB55,      0,      0,\n};\nconst unsigned short x0212_shiftjis_CA[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFB59,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFB5A,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFB5B,\n      0, 0xFB5C,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_CB[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFB5D,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB5F,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFB60,      0,\n      0,      0, 0xFB61,      0,      0,      0, 0xFB64,      0,\n 0xFB62,      0,      0,      0, 0xFB63,      0,      0,      0,\n      0, 0xFB66,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_CC[] = {\n              0,      0,      0,      0, 0xFB65,      0,      0,\n      0,      0,      0, 0xFB67,      0, 0xFB69, 0xFB68,      0,\n      0,      0, 0xFB6A,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB6B,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFB6C,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB6D,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_CD[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFAA8,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFB6F,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_CE[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB73, 0xFB71,      0,      0,      0,      0,\n      0,      0,      0, 0xFB74,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB76,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_CF[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFB78,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB79,      0,      0,      0,      0,      0,\n      0, 0xFB7A,      0,      0,      0, 0xFB7B,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D0[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFB81,      0,      0,\n      0, 0xFB83,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D1[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFB84,      0,      0,      0, 0xFB87,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D2[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFB88,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D3[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB8A,      0,      0,      0,      0,      0,      0,\n 0xFB8B,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D4[] = {\n              0,      0,      0,      0,      0,      0, 0xFB8C,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFB8F,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA5C,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFB90,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D5[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFB91,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D7[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFB93,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D8[] = {\n              0, 0xFB95,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFB96,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB97,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB98,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFB99,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_D9[] = {\n         0xFA60,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFB9A,      0,\n 0xFB9B,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFB9C,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_DC[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFBA2,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFA5D,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_DD[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFBA3,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFBA4,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFBA5,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFBA6,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_DE[] = {\n              0,      0,      0, 0xFBA7,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFBA8,      0,      0,      0,      0, 0xFBAA,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFBAB,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_DF[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFBAD,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFBAF,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E0[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFBB2,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E1[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFBB5,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E2[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFBB9,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E3[] = {\n              0,      0,      0,      0,      0, 0xFBBB,      0,\n 0xFBBA, 0xFBBC, 0xFBBF, 0xFBC0,      0,      0,      0, 0xFBBD,\n 0xFBBE,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFBC1,      0,      0, 0xFBC3,\n      0, 0xFBC2,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFBCA, 0xFBC4, 0xFBC6,      0,\n 0xFBC5,      0,      0,      0,      0,      0,      0, 0xFBC7,\n      0, 0xFBC9,      0, 0xFBC8,      0,      0,      0,      0,\n      0, 0xFBCB,      0,      0,      0,      0,      0,      0,\n      0, 0xFBCD, 0xFBCE,      0,      0,      0,      0,      0,\n 0xFA5F,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E4[] = {\n              0,      0,      0,      0,      0, 0xFBCC,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFBD2, 0xFBD6,\n 0xFBD4, 0xFBD0,      0, 0xFBD1,      0,      0,      0, 0xFBD5,\n      0,      0,      0, 0xFBCF,      0,      0,      0,      0,\n 0xFA65, 0xFBD9, 0xFBDC,      0, 0xFBDE,      0,      0,      0,\n      0,      0,      0, 0xFBDD, 0xFBDB,      0, 0xFBD8,      0,\n 0xFBD7,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFA5E,      0,      0,      0,      0,      0, 0xFBE0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFBDF,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E5[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFBE1,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0, 0xFBE2,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFBE3,      0,      0,      0,      0,      0,      0,\n 0xFBE4,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFBE5,      0,      0,      0,      0,      0,\n      0,      0, 0xFBE6, 0xFBE7,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E6[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n 0xFBEB,      0,      0,      0,      0,      0,      0, 0xFBEC,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E7[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0, 0xFBED,      0, 0xFBEF,      0,\n      0, 0xFBF1, 0xFBF3,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E8[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFBF4,      0,      0,      0,      0, 0xFBF5,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFBF8,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_E9[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0, 0xFBFB,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFC40,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_EA[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0, 0xFC41,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFC43,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFC44,      0,\n      0,      0, 0xFC45,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_EB[] = {\n              0,      0,      0,      0, 0xFC46,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0, 0xFC48, 0xFC47,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_EC[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0, 0xFC4A,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,\n};\nconst unsigned short x0212_shiftjis_F3[] = {\n              0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0,      0,      0,      0,      0,      0,\n      0,      0,      0, 0xFA40, 0xFA41, 0xFA42, 0xFA43, 0xFA44,\n 0xFA45, 0xFA46, 0xFA47, 0xFA48, 0xFA49, 0xFA4A, 0xFA4B,\n};\nconst unsigned short x0212_shiftjis_F4[] = {\n         0xFA4C, 0xFA4D, 0xFA4E, 0xFA4F, 0xFA50, 0xFA51, 0xFA52,\n 0xFA53, 0xFA56, 0xFA57, 0xFA58, 0xFA59, 0xFA5A, 0xFA62, 0xFA6A,\n 0xFA7C, 0xFA83, 0xFA8A, 0xFA8B, 0xFA90, 0xFA92, 0xFA96, 0xFA9B,\n 0xFA9C, 0xFA9D, 0xFAAA, 0xFAAE, 0xFAB0, 0xFAB1, 0xFABA, 0xFABD,\n 0xFAC1, 0xFACD, 0xFAD0, 0xFAD5, 0xFAD8, 0xFAE0, 0xFAE5, 0xFAE8,\n 0xFAEA, 0xFAEE, 0xFAF2, 0xFB43, 0xFB44, 0xFB50, 0xFB58, 0xFB5E,\n 0xFB6E, 0xFB70, 0xFB72, 0xFB75, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB80,\n 0xFB82, 0xFB85, 0xFB86, 0xFB89, 0xFB8D, 0xFB8E, 0xFB92, 0xFB94,\n 0xFB9D, 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA9, 0xFBAC, 0xFBAE,\n 0xFBB0, 0xFBB1, 0xFBB3, 0xFBB4, 0xFBB6, 0xFBB7, 0xFBB8, 0xFBD3,\n 0xFBDA, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEE, 0xFBF0, 0xFBF2, 0xFBF6,\n 0xFBF7, 0xFBF9, 0xFBFA, 0xFBFC, 0xFC42, 0xFC49, 0xFC4B,\n};\nconst unsigned short *const x0212_shiftjis[] = {\n                                    0, x0212_shiftjis_A2,                 0,\n                 0,                 0,                 0,                 0,\n                 0,                 0,                 0,                 0,\n                 0,                 0,                 0,                 0,\n x0212_shiftjis_B0, x0212_shiftjis_B1, x0212_shiftjis_B2, x0212_shiftjis_B3,\n x0212_shiftjis_B4, x0212_shiftjis_B5,                 0, x0212_shiftjis_B7,\n x0212_shiftjis_B8, x0212_shiftjis_B9, x0212_shiftjis_BA, x0212_shiftjis_BB,\n x0212_shiftjis_BC, x0212_shiftjis_BD, x0212_shiftjis_BE, x0212_shiftjis_BF,\n x0212_shiftjis_C0, x0212_shiftjis_C1, x0212_shiftjis_C2, x0212_shiftjis_C3,\n x0212_shiftjis_C4, x0212_shiftjis_C5, x0212_shiftjis_C6, x0212_shiftjis_C7,\n x0212_shiftjis_C8, x0212_shiftjis_C9, x0212_shiftjis_CA, x0212_shiftjis_CB,\n x0212_shiftjis_CC, x0212_shiftjis_CD, x0212_shiftjis_CE, x0212_shiftjis_CF,\n x0212_shiftjis_D0, x0212_shiftjis_D1, x0212_shiftjis_D2, x0212_shiftjis_D3,\n x0212_shiftjis_D4, x0212_shiftjis_D5,                 0, x0212_shiftjis_D7,\n x0212_shiftjis_D8, x0212_shiftjis_D9,                 0,                 0,\n x0212_shiftjis_DC, x0212_shiftjis_DD, x0212_shiftjis_DE, x0212_shiftjis_DF,\n x0212_shiftjis_E0, x0212_shiftjis_E1, x0212_shiftjis_E2, x0212_shiftjis_E3,\n x0212_shiftjis_E4, x0212_shiftjis_E5, x0212_shiftjis_E6, x0212_shiftjis_E7,\n x0212_shiftjis_E8, x0212_shiftjis_E9, x0212_shiftjis_EA, x0212_shiftjis_EB,\n x0212_shiftjis_EC,                 0,                 0,                 0,\n                 0,                 0,                 0, x0212_shiftjis_F3,\n x0212_shiftjis_F4,                 0,                 0,                 0,\n                 0,                 0,                 0,                 0,\n                 0,                 0,                 0,\n};\n#endif /* X0212_ENABLE */\n"
  },
  {
    "path": "ext/nkf/nkf-utf8/utf8tbl.h",
    "content": "#ifndef _UTF8TBL_H_\n#define _UTF8TBL_H_\n\n#ifdef UTF8_OUTPUT_ENABLE\nextern const unsigned short euc_to_utf8_1byte[];\nextern const unsigned short *const euc_to_utf8_2bytes[];\nextern const unsigned short *const euc_to_utf8_2bytes_ms[];\nextern const unsigned short *const x0212_to_utf8_2bytes[];\n#endif /* UTF8_OUTPUT_ENABLE */\n\n#ifdef UTF8_INPUT_ENABLE\nextern const unsigned short *const utf8_to_euc_2bytes[];\nextern const unsigned short *const utf8_to_euc_2bytes_ms[];\nextern const unsigned short *const utf8_to_euc_2bytes_932[];\nextern const unsigned short *const *const utf8_to_euc_3bytes[];\nextern const unsigned short *const *const utf8_to_euc_3bytes_ms[];\nextern const unsigned short *const *const utf8_to_euc_3bytes_932[];\n#endif /* UTF8_INPUT_ENABLE */\n\n#ifdef UNICODE_NORMALIZATION\nextern const struct normalization_pair normalization_table[];\n#endif\n\n#ifdef SHIFTJIS_CP932\nextern const unsigned short shiftjis_cp932[3][189];\nextern const unsigned short cp932inv[2][189];\n#endif /* SHIFTJIS_CP932 */\n\n#ifdef X0212_ENABLE\nextern const unsigned short shiftjis_x0212[3][189];\nextern const unsigned short *const x0212_shiftjis[];\n#endif /* X0212_ENABLE */\n\n#endif\n"
  },
  {
    "path": "ext/nkf/nkf.c",
    "content": "/*\n *  NKF - Ruby extension for Network Kanji Filter\n *\n *  original nkf2.x is maintained at http://sourceforge.jp/projects/nkf/\n *\n *  $Id$\n *\n */\n\n#define RUBY_NKF_REVISION \"$Revision$\"\n#define RUBY_NKF_VERSION NKF_VERSION \" (\" NKF_RELEASE_DATE \")\"\n\n#include \"ruby.h\"\n\n/* Encoding Constants */\n#define\t_AUTO\t\t0\n#define\t_JIS\t\t1\n#define\t_EUC\t\t2\n#define\t_SJIS\t\t3\n#define\t_BINARY\t\t4\n#define\t_NOCONV\t\t4\n#define\t_ASCII\t\t5\n/* 0b011x is reserved for UTF-8 Family */\n#define\t_UTF8\t\t6\n/* 0b10xx is reserved for UTF-16 Family */\n#define\t_UTF16\t\t8\n/* 0b11xx is reserved for UTF-32 Family */\n#define\t_UTF32\t\t12\n#define\t_OTHER\t\t16\n#define\t_UNKNOWN\t_AUTO\n\n/* Replace nkf's getchar/putchar for variable modification */\n/* we never use getc, ungetc */\n\n#undef getc\n#undef ungetc\n#define getc(f)         (input_ctr>=i_len?-1:input[input_ctr++])\n#define ungetc(c,f)     input_ctr--\n\n#define INCSIZE         32\n#undef putchar\n#undef TRUE\n#undef FALSE\n#define putchar(c)      rb_nkf_putchar(c)\n\n/* Input/Output pointers */\n\nstatic unsigned char *output;\nstatic unsigned char *input;\nstatic int input_ctr;\nstatic int i_len;\nstatic int output_ctr;\nstatic int o_len;\nstatic int incsize;\n\nstatic VALUE result;\n\nstatic int\nrb_nkf_putchar(c)\n  unsigned int c;\n{\n  if (output_ctr >= o_len) {\n    o_len += incsize;\n    rb_str_resize(result, o_len);\n    incsize *= 2;\n    output = (unsigned char *)RSTRING(result)->ptr;\n  }\n  output[output_ctr++] = c;\n\n  return c;\n}\n\n/* Include kanji filter main part */\n/* getchar and putchar will be replaced during inclusion */\n\n#define PERL_XS 1\n#include \"nkf-utf8/config.h\"\n#include \"nkf-utf8/utf8tbl.c\"\n#include \"nkf-utf8/nkf.c\"\n\nint nkf_split_options(arg)\n    const char* arg;\n{\n    int count = 0;\n    char option[256];\n    int i = 0, j = 0;\n    int is_escaped = FALSE;\n    int is_single_quoted = FALSE;\n    int is_double_quoted = FALSE;\n    for(i = 0; arg[i]; i++){\n\tif(j == 255){\n\t    return -1;\n\t}else if(is_single_quoted){\n\t    if(arg[i] == '\\''){\n\t\tis_single_quoted = FALSE;\n\t    }else{\n\t\toption[j++] = arg[i];\n\t    }\n\t}else if(is_escaped){\n\t    is_escaped = FALSE;\n\t    option[j++] = arg[i];\n\t}else if(arg[i] == '\\\\'){\n\t    is_escaped = TRUE;\n\t}else if(is_double_quoted){\n\t    if(arg[i] == '\"'){\n\t\tis_double_quoted = FALSE;\n\t    }else{\n\t\toption[j++] = arg[i];\n\t    }\n\t}else if(arg[i] == '\\''){\n\t    is_single_quoted = TRUE;\n\t}else if(arg[i] == '\"'){\n\t    is_double_quoted = TRUE;\n\t}else if(arg[i] == ' '){\n\t    option[j] = '\\0';\n\t    options(option);\n\t    j = 0;\n\t}else{\n\t    option[j++] = arg[i];\n\t}\n    }\n    if(j){\n\toption[j] = '\\0';\n\toptions(option);\n    }\n    return count;\n}\n\n/*\n *  call-seq:\n *     NKF.nkf(opt, str)   -> string\n *\n *  Convert _str_ and return converted result.\n *  Conversion details are specified by _opt_ as String.\n *\n *     require 'nkf'\n *     output = NKF.nkf(\"-s\", input)\n *\n *  *Note*\n *  By default, nkf decodes MIME encoded string.\n *  If you want not to decode input, use NKF.nkf with <b>-m0</b> flag.\n */\n\nstatic VALUE\nrb_nkf_kconv(obj, opt, src)\n  VALUE obj, opt, src;\n{\n  char *opt_ptr, *opt_end;\n  volatile VALUE v;\n\n  reinit();\n  StringValue(opt);\n  opt_ptr = RSTRING(opt)->ptr;\n  opt_end = opt_ptr + RSTRING(opt)->len;\n  nkf_split_options(opt_ptr);\n\n  incsize = INCSIZE;\n\n  input_ctr = 0;\n  StringValue(src);\n  input = (unsigned char *)RSTRING(src)->ptr;\n  i_len = RSTRING(src)->len;\n  result = rb_str_new(0, i_len*3 + 10);\n  v = result;\n\n  output_ctr = 0;\n  output     = (unsigned char *)RSTRING(result)->ptr;\n  o_len      = RSTRING(result)->len;\n  *output    = '\\0';\n\n  if(x0201_f == WISH_TRUE)\n    x0201_f = ((!iso2022jp_f)? TRUE : NO_X0201);\n\n  kanji_convert(NULL);\n  RSTRING(result)->ptr[output_ctr] = '\\0';\n  RSTRING(result)->len = output_ctr;\n  OBJ_INFECT(result, src);\n\n  return result;\n}\n\n\n/*\n *  call-seq:\n *     NKF.guess1(str)  -> integer\n *\n *  Returns guessed encoding of _str_ as integer.\n *\n *  Algorithm described in:\n *  Ken Lunde. `Understanding Japanese Information Processing'\n *  Sebastopol, CA: O'Reilly & Associates.\n *\n *      case NKF.guess1(input)\n *      when NKF::JIS\n *        \"ISO-2022-JP\"\n *      when NKF::SJIS\n *        \"Shift_JIS\"\n *      when NKF::EUC\n *        \"EUC-JP\"\n *      when NKF::UNKNOWN\n *        \"UNKNOWN(ASCII)\"\n *      when NKF::BINARY\n *        \"BINARY\"\n *      end\n */\n\nstatic VALUE\nrb_nkf_guess1(obj, src)\n  VALUE obj, src;\n{\n  unsigned char *p;\n  unsigned char *pend;\n  int sequence_counter = 0;\n\n  StringValue(src);\n  p = (unsigned char *)RSTRING(src)->ptr;\n  pend = p + RSTRING(src)->len;\n  if (p == pend) return INT2FIX(_UNKNOWN);\n\n#define INCR do {\\\n      p++;\\\n      if (p==pend) return INT2FIX(_UNKNOWN);\\\n      sequence_counter++;\\\n      if (sequence_counter % 2 == 1 && *p != 0xa4)\\\n\tsequence_counter = 0;\\\n      if (6 <= sequence_counter) {\\\n\t  sequence_counter = 0;\\\n\t  return INT2FIX(_EUC);\\\n      }\\\n  } while (0)\n\n  if (*p == 0xa4)\n    sequence_counter = 1;\n\n  while (p<pend) {\n    if (*p == '\\033') {\n      return INT2FIX(_JIS);\n    }\n    if (*p < '\\006' || *p == 0x7f || *p == 0xff) {\n      return INT2FIX(_BINARY);\n    }\n    if (0x81 <= *p && *p <= 0x8d) {\n      return INT2FIX(_SJIS);\n    }\n    if (0x8f <= *p && *p <= 0x9f) {\n      return INT2FIX(_SJIS);\n    }\n    if (*p == 0x8e) {\t/* SS2 */\n      INCR;\n      if ((0x40 <= *p && *p <= 0x7e) ||\n\t  (0x80 <= *p && *p <= 0xa0) ||\n\t  (0xe0 <= *p && *p <= 0xfc))\n\treturn INT2FIX(_SJIS);\n    }\n    else if (0xa1 <= *p && *p <= 0xdf) {\n      INCR;\n      if (0xf0 <= *p && *p <= 0xfe)\n\treturn INT2FIX(_EUC);\n      if (0xe0 <= *p && *p <= 0xef) {\n\twhile (p < pend && *p >= 0x40) {\n\t  if (*p >= 0x81) {\n\t    if (*p <= 0x8d || (0x8f <= *p && *p <= 0x9f)) {\n\t      return INT2FIX(_SJIS);\n\t    }\n\t    else if (0xfd <= *p && *p <= 0xfe) {\n\t      return INT2FIX(_EUC);\n\t    }\n\t  }\n\t  INCR;\n\t}\n      }\n      else if (*p <= 0x9f) {\n\treturn INT2FIX(_SJIS);\n      }\n    }\n    else if (0xf0 <= *p && *p <= 0xfe) {\n      return INT2FIX(_EUC);\n    }\n    else if (0xe0 <= *p && *p <= 0xef) {\n      INCR;\n      if ((0x40 <= *p && *p <= 0x7e) ||\n\t  (0x80 <= *p && *p <= 0xa0)) {\n\treturn INT2FIX(_SJIS);\n      }\n      if (0xfd <= *p && *p <= 0xfe) {\n\treturn INT2FIX(_EUC);\n      }\n    }\n    INCR;\n  }\n  return INT2FIX(_UNKNOWN);\n}\n\n\n/*\n *  call-seq:\n *     NKF.guess2(str)  -> integer\n *\n *  Returns guessed encoding of _str_ as integer by nkf routine.\n *\n *     case NKF.guess(input)\n *     when NKF::ASCII\n *       \"ASCII\"\n *     when NKF::JIS\n *       \"ISO-2022-JP\"\n *     when NKF::SJIS\n *       \"Shift_JIS\"\n *     when NKF::EUC\n *       \"EUC-JP\"\n *     when NKF::UTF8\n *       \"UTF-8\"\n *     when NKF::UTF16\n *       \"UTF-16\"\n *     when NKF::UNKNOWN\n *       \"UNKNOWN\"\n *     when NKF::BINARY\n *       \"BINARY\"\n *     end\n */\n\nstatic VALUE\nrb_nkf_guess2(obj, src)\n  VALUE obj, src;\n{\n  int code = _BINARY;\n\n  reinit();\n\n  input_ctr = 0;\n  StringValue(src);\n  input = (unsigned char *)RSTRING(src)->ptr;\n  i_len = RSTRING(src)->len;\n\n  if(x0201_f == WISH_TRUE)\n    x0201_f = ((!iso2022jp_f)? TRUE : NO_X0201);\n\n  guess_f = TRUE;\n  kanji_convert( NULL );\n  guess_f = FALSE;\n\n  if (!is_inputcode_mixed) {\n    if (strcmp(input_codename, \"\") == 0) {\n      code = _ASCII;\n    } else if (strcmp(input_codename, \"ISO-2022-JP\") == 0) {\n      code = _JIS;\n    } else if (strcmp(input_codename, \"EUC-JP\") == 0) {\n      code = _EUC;\n    } else if (strcmp(input_codename, \"Shift_JIS\") == 0) {\n      code = _SJIS;\n    } else if (strcmp(input_codename, \"UTF-8\") == 0) {\n      code = _UTF8;\n    } else if (strcmp(input_codename, \"UTF-16\") == 0) {\n      code = _UTF16;\n    } else if (strlen(input_codename) > 0) {\n      code = _UNKNOWN;\n    }\n  }\n\n  return INT2FIX( code );\n}\n\n\n/*\n *  NKF - Ruby extension for Network Kanji Filter \n *\n *  == Description\n *\n *  This is a Ruby Extension version of nkf (Netowrk Kanji Filter).\n *  It converts the first argument and return converted result. Conversion\n *  details are specified by flags as the first argument.\n *\n *  *Nkf* is a yet another kanji code converter among networks, hosts and terminals.\n *  It converts input kanji code to designated kanji code\n *  such as ISO-2022-JP, Shift_JIS, EUC-JP, UTF-8 or UTF-16.\n *\n *  One of the most unique faculty of *nkf* is the guess of the input kanji encodings.\n *  It currently recognizes ISO-2022-JP, Shift_JIS, EUC-JP, UTF-8 and UTF-16.\n *  So users needn't set the input kanji code explicitly.\n *\n *  By default, X0201 kana is converted into X0208 kana.\n *  For X0201 kana, SO/SI, SSO and ESC-(-I methods are supported.\n *  For automatic code detection, nkf assumes no X0201 kana in Shift_JIS.\n *  To accept X0201 in Shift_JIS, use <b>-X</b>, <b>-x</b> or <b>-S</b>.\n *\n *  == Flags\n *\n *  === -b -u\n *\n *  Output is buffered (DEFAULT), Output is unbuffered.\n *\n *  === -j -s -e -w -w16\n *\n *  Output code is ISO-2022-JP (7bit JIS), Shift_JIS, EUC-JP,\n *  UTF-8N, UTF-16BE.\n *  Without this option and compile option, ISO-2022-JP is assumed.\n *\n *  === -J -S -E -W -W16\n *\n *  Input assumption is JIS 7 bit, Shift_JIS, EUC-JP,\n *  UTF-8, UTF-16LE.\n *\n *  ==== -J\n *\n *  Assume  JIS input. It also accepts EUC-JP.\n *  This is the default. This flag does not exclude Shift_JIS.\n *\n *  ==== -S\n *\n *  Assume Shift_JIS and X0201 kana input. It also accepts JIS.\n *  EUC-JP is recognized as X0201 kana. Without <b>-x</b> flag,\n *  X0201 kana (halfwidth kana) is converted into X0208.\n *\n *  ==== -E\n *\n *  Assume EUC-JP input. It also accepts JIS.\n *  Same as -J.\n *\n *  === -t\n *\n *  No conversion.\n *\n *  === -i_\n *\n *  Output sequence to designate JIS-kanji. (DEFAULT B)\n *\n *  === -o_\n *\n *  Output sequence to designate ASCII. (DEFAULT B)\n *\n *  === -r\n *\n *  {de/en}crypt ROT13/47\n *\n *  === -h[123] --hiragana --katakana --katakana-hiragana\n *\n *  [-h1 --hiragana] Katakana to Hiragana conversion.\n *\n *  [-h2 --katakana] Hiragana to Katakana conversion.\n *\n *  [-h3 --katakana-hiragana] Katakana to Hiragana and Hiragana to Katakana conversion.\n *\n *  === -T\n *\n *  Text mode output (MS-DOS)\n *\n *  === -l\n *\n *  ISO8859-1 (Latin-1) support\n *\n *  === -f[<code>m</code> [- <code>n</code>]]\n *\n *  Folding on <code>m</code> length with <code>n</code> margin in a line.\n *  Without this option, fold length is 60 and fold margin is 10.\n *\n *  === -F\n *\n *  New line preserving line folding.\n *\n *  === -Z[0-3]\n *\n *  Convert X0208 alphabet (Fullwidth Alphabets) to ASCII.\n *\n *  [-Z -Z0] Convert X0208 alphabet to ASCII.\n *\n *  [-Z1] Converts X0208 kankaku to single ASCII space.\n *\n *  [-Z2] Converts X0208 kankaku to double ASCII spaces.\n *\n *  [-Z3] Replacing Fullwidth >, <, \", & into '&gt;', '&lt;', '&quot;', '&amp;' as in HTML.\n *\n *  === -X -x\n *\n *  Assume X0201 kana in MS-Kanji.\n *  With <b>-X</b> or without this option, X0201 is converted into X0208 Kana.\n *  With <b>-x</b>, try to preserve X0208 kana and do not convert X0201 kana to X0208.\n *  In JIS output, ESC-(-I is used. In EUC output, SSO is used.\n *\n *  === -B[0-2]\n *\n *  Assume broken JIS-Kanji input, which lost ESC.\n *  Useful when your site is using old B-News Nihongo patch.\n *\n *  [-B1] allows any char after ESC-( or ESC-$.\n *\n *  [-B2] forces ASCII after NL.\n *\n *  === -I\n *\n *  Replacing non iso-2022-jp char into a geta character\n *  (substitute character in Japanese).\n *\n *  === -d -c\n *\n *  Delete \\r in line feed, Add \\r in line feed.\n *\n *  === -m[BQN0]\n *\n *  MIME ISO-2022-JP/ISO8859-1 decode. (DEFAULT)\n *  To see ISO8859-1 (Latin-1) -l is necessary.\n *\n *  [-mB] Decode MIME base64 encoded stream. Remove header or other part before\n *  conversion. \n *\n *  [-mQ] Decode MIME quoted stream. '_' in quoted stream is converted to space.\n *\n *  [-mN] Non-strict decoding.\n *  It allows line break in the middle of the base64 encoding.\n *\n *  [-m0] No MIME decode.\n *\n *  === -M\n *\n *  MIME encode. Header style. All ASCII code and control characters are intact.\n *  Kanji conversion is performed before encoding, so this cannot be used as a picture encoder.\n *\n *  [-MB] MIME encode Base64 stream.\n *\n *  [-MQ] Perfome quoted encoding.\n *\n *  === -l\n *\n *  Input and output code is ISO8859-1 (Latin-1) and ISO-2022-JP.\n *  <b>-s</b>, <b>-e</b> and <b>-x</b> are not compatible with this option.\n *\n *  === -L[uwm]\n *\n *  new line mode\n *  Without this option, nkf doesn't convert line breaks.\n *\n *  [-Lu] unix (LF)\n *\n *  [-Lw] windows (CRLF)\n *\n *  [-Lm] mac (CR)\n *\n *  === --fj --unix --mac --msdos --windows\n *\n *  convert for these system\n *\n *  === --jis --euc --sjis --mime --base64\n *\n *  convert for named code\n *\n *  === --jis-input --euc-input --sjis-input --mime-input --base64-input\n *\n *  assume input system\n *\n *  === --ic=<code>input codeset</code> --oc=<code>output codeset</code>\n *\n *  Set the input or output codeset.\n *  NKF supports following codesets and those codeset name are case insensitive.\n *\n *  [ISO-2022-JP] a.k.a. RFC1468, 7bit JIS, JUNET\n *\n *  [EUC-JP (eucJP-nkf)] a.k.a. AT&T JIS, Japanese EUC, UJIS\n *\n *  [eucJP-ascii] a.k.a. x-eucjp-open-19970715-ascii\n *\n *  [eucJP-ms] a.k.a. x-eucjp-open-19970715-ms\n *\n *  [CP51932] Microsoft Version of EUC-JP.\n *\n *  [Shift_JIS] SJIS, MS-Kanji\n *\n *  [CP932] a.k.a. Windows-31J\n *\n *  [UTF-8] same as UTF-8N\n *\n *  [UTF-8N] UTF-8 without BOM\n *\n *  [UTF-8-BOM] UTF-8 with BOM\n *\n *  [UTF-16] same as UTF-16BE\n *\n *  [UTF-16BE] UTF-16 Big Endian without BOM\n *\n *  [UTF-16BE-BOM] UTF-16 Big Endian with BOM\n *\n *  [UTF-16LE] UTF-16 Little Endian without BOM\n *\n *  [UTF-16LE-BOM] UTF-16 Little Endian with BOM\n *\n *  [UTF8-MAC] NKDed UTF-8, a.k.a. UTF8-NFD (input only)\n *\n *  === --fb-{skip, html, xml, perl, java, subchar}\n *\n *  Specify the way that nkf handles unassigned characters.\n *  Without this option, --fb-skip is assumed.\n *\n *  === --prefix= <code>escape character</code> <code>target character</code> ..\n *\n *  When nkf converts to Shift_JIS,\n *  nkf adds a specified escape character to specified 2nd byte of Shift_JIS characters.\n *  1st byte of argument is the escape character and following bytes are target characters.\n *\n *  === --disable-cp932ext\n *\n *  Handle the characters extended in CP932 as unassigned characters.\n *\n *  === --cap-input\n *\n *  Decode hex encoded characters.\n *\n *  === --url-input\n *\n *  Unescape percent escaped characters.\n *\n *  === --\n *\n *  Ignore rest of -option.\n */\n\nvoid\nInit_nkf()\n{\n    /* hoge */\n    VALUE mKconv = rb_define_module(\"NKF\");\n    /* hoge */\n\n    rb_define_module_function(mKconv, \"nkf\", rb_nkf_kconv, 2);\n    rb_define_module_function(mKconv, \"guess1\", rb_nkf_guess1, 1);\n    rb_define_module_function(mKconv, \"guess2\", rb_nkf_guess2, 1);\n    rb_define_alias(mKconv, \"guess\", \"guess2\");\n    rb_define_alias(rb_singleton_class(mKconv), \"guess\", \"guess2\");\n\n    /* Auto-Detect */\n    rb_define_const(mKconv, \"AUTO\", INT2FIX(_AUTO));\n    /* ISO-2022-JP */\n    rb_define_const(mKconv, \"JIS\", INT2FIX(_JIS));\n    /* EUC-JP */\n    rb_define_const(mKconv, \"EUC\", INT2FIX(_EUC));\n    /* Shift_JIS */\n    rb_define_const(mKconv, \"SJIS\", INT2FIX(_SJIS));\n    /* BINARY */\n    rb_define_const(mKconv, \"BINARY\", INT2FIX(_BINARY));\n    /* No conversion */\n    rb_define_const(mKconv, \"NOCONV\", INT2FIX(_NOCONV));\n    /* ASCII */\n    rb_define_const(mKconv, \"ASCII\", INT2FIX(_ASCII));\n    /* UTF-8 */\n    rb_define_const(mKconv, \"UTF8\", INT2FIX(_UTF8));\n    /* UTF-16 */\n    rb_define_const(mKconv, \"UTF16\", INT2FIX(_UTF16));\n    /* UTF-32 */\n    rb_define_const(mKconv, \"UTF32\", INT2FIX(_UTF32));\n    /* UNKNOWN */\n    rb_define_const(mKconv, \"UNKNOWN\", INT2FIX(_UNKNOWN));\n    /* Full version string of nkf */\n    rb_define_const(mKconv, \"VERSION\", rb_str_new2(RUBY_NKF_VERSION));\n    /* Version of nkf */\n    rb_define_const(mKconv, \"NKF_VERSION\", rb_str_new2(NKF_VERSION));\n    /* Release date of nkf */\n    rb_define_const(mKconv, \"NKF_RELEASE_DATE\", rb_str_new2(NKF_RELEASE_DATE));\n}\n"
  },
  {
    "path": "ext/openssl/.cvsignore",
    "content": "GNUmakefile\nMakefile\nmkmf.log\ndep\nextconf.h\n"
  },
  {
    "path": "ext/openssl/extconf.rb",
    "content": "=begin\n= $RCSfile$ -- Generator for Makefile\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\nrequire \"mkmf\"\n\ndir_config(\"openssl\")\ndir_config(\"kerberos\")\n\nmessage \"=== OpenSSL for Ruby configurator ===\\n\"\n\n##\n# Adds -Wall -DOSSL_DEBUG for compilation and some more targets when GCC is used\n# To turn it on, use: --with-debug or --enable-debug\n#\nif with_config(\"debug\") or enable_config(\"debug\")\n  $defs.push(\"-DOSSL_DEBUG\") unless $defs.include? \"-DOSSL_DEBUG\"\n\n  if /gcc/ =~ CONFIG[\"CC\"]\n    $CPPFLAGS += \" -Wall\" unless $CPPFLAGS.split.include? \"-Wall\"\n  end\nend\n\nmessage \"=== Checking for system dependent stuff... ===\\n\"\nhave_library(\"nsl\", \"t_open\")\nhave_library(\"socket\", \"socket\")\nhave_header(\"assert.h\")\n\nmessage \"=== Checking for required stuff... ===\\n\"\nif $mingw\n  have_library(\"wsock32\")\n  have_library(\"gdi32\")\nend\nresult = have_header(\"openssl/ssl.h\")\nresult &&= %w[crypto libeay32].any? {|lib| have_library(lib, \"OpenSSL_add_all_digests\")}\nresult &&= %w[ssl ssleay32].any? {|lib| have_library(lib, \"SSL_library_init\")}\nif !result\n  unless pkg_config(\"openssl\") and have_header(\"openssl/ssl.h\")\n    message \"=== Checking for required stuff failed. ===\\n\"\n    message \"Makefile wasn't created. Fix the errors above.\\n\"\n    exit 1\n  end\nend\n\nunless have_header(\"openssl/conf_api.h\")\n  message \"OpenSSL 0.9.6 or later required.\\n\"\n  exit 1\nend\n\n%w\"rb_str_set_len rb_block_call\".each {|func| have_func(func, \"ruby.h\")}\n\nmessage \"=== Checking for OpenSSL features... ===\\n\"\nhave_func(\"ERR_peek_last_error\")\nhave_func(\"BN_mod_add\")\nhave_func(\"BN_mod_sqr\")\nhave_func(\"BN_mod_sub\")\nhave_func(\"BN_pseudo_rand_range\")\nhave_func(\"BN_rand_range\")\nhave_func(\"CONF_get1_default_config_file\")\nhave_func(\"EVP_CIPHER_CTX_copy\")\nhave_func(\"EVP_CIPHER_CTX_set_padding\")\nhave_func(\"EVP_CipherFinal_ex\")\nhave_func(\"EVP_CipherInit_ex\")\nhave_func(\"EVP_DigestFinal_ex\")\nhave_func(\"EVP_DigestInit_ex\")\nhave_func(\"EVP_MD_CTX_cleanup\")\nhave_func(\"EVP_MD_CTX_create\")\nhave_func(\"EVP_MD_CTX_destroy\")\nhave_func(\"EVP_MD_CTX_init\")\nhave_func(\"HMAC_CTX_cleanup\")\nhave_func(\"HMAC_CTX_copy\")\nhave_func(\"HMAC_CTX_init\")\nhave_func(\"PEM_def_callback\")\nhave_func(\"PKCS5_PBKDF2_HMAC\")\nhave_func(\"PKCS5_PBKDF2_HMAC_SHA1\")\nhave_func(\"X509V3_set_nconf\")\nhave_func(\"X509V3_EXT_nconf_nid\")\nhave_func(\"X509_CRL_add0_revoked\")\nhave_func(\"X509_CRL_set_issuer_name\")\nhave_func(\"X509_CRL_set_version\")\nhave_func(\"X509_CRL_sort\")\nhave_func(\"X509_STORE_get_ex_data\")\nhave_func(\"X509_STORE_set_ex_data\")\nhave_func(\"OBJ_NAME_do_all_sorted\")\nhave_func(\"SSL_SESSION_get_id\")\nhave_func(\"OPENSSL_cleanse\")\nif try_compile(\"#define FOO(a, ...) foo(a, ##__VA_ARGS__)\\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\\n\")\n  $defs.push(\"-DHAVE_VA_ARGS_MACRO\")\nend\nif have_header(\"openssl/engine.h\")\n  have_func(\"ENGINE_add\")\n  have_func(\"ENGINE_load_builtin_engines\")\n  have_func(\"ENGINE_load_openbsd_dev_crypto\")\n  have_func(\"ENGINE_get_digest\")\n  have_func(\"ENGINE_get_cipher\")\n  have_func(\"ENGINE_cleanup\")\nend\nif try_compile(<<SRC)\n#include <openssl/opensslv.h>\n#if OPENSSL_VERSION_NUMBER < 0x00907000L\n# error \"OpenSSL version is less than 0.9.7.\"\n#endif\nSRC\n  have_header(\"openssl/ocsp.h\")\nend\nhave_struct_member(\"EVP_CIPHER_CTX\", \"flags\", \"openssl/evp.h\")\nhave_struct_member(\"EVP_CIPHER_CTX\", \"engine\", \"openssl/evp.h\")\nhave_struct_member(\"X509_ATTRIBUTE\", \"single\", \"openssl/x509.h\")\n\nmessage \"=== Checking done. ===\\n\"\n\ncreate_header\ncreate_makefile(\"openssl\")\nmessage \"Done.\\n\"\n"
  },
  {
    "path": "ext/openssl/lib/net/ftptls.rb",
    "content": "=begin\n= $RCSfile$ -- SSL/TLS enhancement for Net::HTTP.\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2003 Blaz Grilc <farmer@gmx.co.uk>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Requirements\n\n= Version\n  $Id$\n  \n= Notes\n  Tested on FreeBSD 5-CURRENT and 4-STABLE\n  - ruby 1.6.8 (2003-01-17) [i386-freebsd5]\n  - OpenSSL 0.9.7a Feb 19 2003\n  - ruby-openssl-0.2.0.p0\n  tested on ftp server: glftpd 1.30\n=end\n\nrequire 'socket'\nrequire 'openssl'\nrequire 'net/ftp'\n\nmodule Net\n  class FTPTLS < FTP\n    def connect(host, port=FTP_PORT)\n      @hostname = host\n      super\n    end\n\n    def login(user = \"anonymous\", passwd = nil, acct = nil)\n       store = OpenSSL::X509::Store.new\n       store.set_default_paths\n       ctx = OpenSSL::SSL::SSLContext.new('SSLv23')\n       ctx.cert_store = store\n       ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER\n       ctx.key = nil\n       ctx.cert = nil\n       voidcmd(\"AUTH TLS\")\n       @sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx)\n       @sock.connect\n       @sock.post_connection_check(@hostname)\n       super(user, passwd, acct)\n       voidcmd(\"PBSZ 0\")\n    end\n  end\nend\n"
  },
  {
    "path": "ext/openssl/lib/net/telnets.rb",
    "content": "=begin\n= $RCSfile$ -- SSL/TLS enhancement for Net::Telnet.\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n  \n  2001/11/06: Contiributed to Ruby/OpenSSL project.\n\n== class Net::Telnet\n\nThis class will initiate SSL/TLS session automaticaly if the server\nsent OPT_STARTTLS. Some options are added for SSL/TLS.\n\n  host = Net::Telnet::new({\n           \"Host\"       => \"localhost\",\n           \"Port\"       => \"telnets\",\n           ## follows are new options.\n           'CertFile'   => \"user.crt\",\n           'KeyFile'    => \"user.key\",\n           'CAFile'     => \"/some/where/certs/casert.pem\",\n           'CAPath'     => \"/some/where/caserts\",\n           'VerifyMode' => SSL::VERIFY_PEER,\n           'VerifyCallback' => verify_proc\n         })\n\nOr, the new options ('Cert', 'Key' and 'CACert') are available from\nMichal Rokos's OpenSSL module.\n\n  cert_data = File.open(\"user.crt\"){|io| io.read }\n  pkey_data = File.open(\"user.key\"){|io| io.read }\n  cacert_data = File.open(\"your_ca.pem\"){|io| io.read }\n  host = Net::Telnet::new({\n           \"Host\"       => \"localhost\",\n           \"Port\"       => \"telnets\",\n           'Cert'       => OpenSSL::X509::Certificate.new(cert_data)\n           'Key'        => OpenSSL::PKey::RSA.new(pkey_data)\n           'CACert'     => OpenSSL::X509::Certificate.new(cacert_data)\n           'CAFile'     => \"/some/where/certs/casert.pem\",\n           'CAPath'     => \"/some/where/caserts\",\n           'VerifyMode' => SSL::VERIFY_PEER,\n           'VerifyCallback' => verify_proc\n         })\n\nThis class is expected to be a superset of usual Net::Telnet.\n=end\n\nrequire \"net/telnet\"\nrequire \"openssl\"\n\nmodule Net\n  class Telnet\n    attr_reader :ssl\n\n    OPT_STARTTLS       =  46.chr # \"\\056\" # \"\\x2e\" # Start TLS\n    TLS_FOLLOWS        =   1.chr # \"\\001\" # \"\\x01\" # FOLLOWS (for STARTTLS)\n\n    alias preprocess_orig preprocess\n\n    def ssl?; @ssl; end\n\n    def preprocess(string)\n      # combine CR+NULL into CR\n      string = string.gsub(/#{CR}#{NULL}/no, CR) if @options[\"Telnetmode\"]\n\n      # combine EOL into \"\\n\"\n      string = string.gsub(/#{EOL}/no, \"\\n\") unless @options[\"Binmode\"]\n\n      string.gsub(/#{IAC}(\n                   [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|\n                   [#{DO}#{DONT}#{WILL}#{WONT}][#{OPT_BINARY}-#{OPT_EXOPL}]|\n                   #{SB}[#{OPT_BINARY}-#{OPT_EXOPL}]\n                     (#{IAC}#{IAC}|[^#{IAC}])+#{IAC}#{SE}\n                 )/xno) do\n        if    IAC == $1  # handle escaped IAC characters\n          IAC\n        elsif AYT == $1  # respond to \"IAC AYT\" (are you there)\n          self.write(\"nobody here but us pigeons\" + EOL)\n          ''\n        elsif DO[0] == $1[0]  # respond to \"IAC DO x\"\n          if    OPT_BINARY[0] == $1[1]\n            @telnet_option[\"BINARY\"] = true\n            self.write(IAC + WILL + OPT_BINARY)\n          elsif OPT_STARTTLS[0] == $1[1]\n            self.write(IAC + WILL + OPT_STARTTLS)\n            self.write(IAC + SB + OPT_STARTTLS + TLS_FOLLOWS + IAC + SE)\n          else\n            self.write(IAC + WONT + $1[1..1])\n          end\n          ''\n        elsif DONT[0] == $1[0]  # respond to \"IAC DON'T x\" with \"IAC WON'T x\"\n          self.write(IAC + WONT + $1[1..1])\n          ''\n        elsif WILL[0] == $1[0]  # respond to \"IAC WILL x\"\n          if    OPT_BINARY[0] == $1[1]\n            self.write(IAC + DO + OPT_BINARY)\n          elsif OPT_ECHO[0] == $1[1]\n            self.write(IAC + DO + OPT_ECHO)\n          elsif OPT_SGA[0]  == $1[1]\n            @telnet_option[\"SGA\"] = true\n            self.write(IAC + DO + OPT_SGA)\n          else\n            self.write(IAC + DONT + $1[1..1])\n          end\n          ''\n        elsif WONT[0] == $1[0]  # respond to \"IAC WON'T x\"\n          if    OPT_ECHO[0] == $1[1]\n            self.write(IAC + DONT + OPT_ECHO)\n          elsif OPT_SGA[0]  == $1[1]\n            @telnet_option[\"SGA\"] = false\n            self.write(IAC + DONT + OPT_SGA)\n          else\n            self.write(IAC + DONT + $1[1..1])\n          end\n          ''\n        elsif SB[0] == $1[0]    # respond to \"IAC SB xxx IAC SE\"\n          if    OPT_STARTTLS[0] == $1[1] && TLS_FOLLOWS[0] == $2[0]\n            @sock = OpenSSL::SSL::SSLSocket.new(@sock)\n            @sock.cert            = @options['Cert'] unless @sock.cert\n            @sock.key             = @options['Key'] unless @sock.key\n            @sock.ca_cert         = @options['CACert']\n            @sock.ca_file         = @options['CAFile']\n            @sock.ca_path         = @options['CAPath']\n            @sock.timeout         = @options['Timeout']\n            @sock.verify_mode     = @options['VerifyMode']\n            @sock.verify_callback = @options['VerifyCallback']\n            @sock.verify_depth    = @options['VerifyDepth']\n            @sock.connect\n            if @options['VerifyMode'] != OpenSSL::SSL::VERIFY_NONE\n              @sock.post_connection_check(@options['Host'])\n            end\n            @ssl = true\n          end\n          ''\n        else\n          ''\n        end\n      end\n    end # preprocess\n    \n    alias waitfor_org waitfor\n\n    def waitfor(options)\n      time_out = @options[\"Timeout\"]\n      waittime = @options[\"Waittime\"]\n\n      if options.kind_of?(Hash)\n        prompt   = if options.has_key?(\"Match\")\n                     options[\"Match\"]\n                   elsif options.has_key?(\"Prompt\")\n                     options[\"Prompt\"]\n                   elsif options.has_key?(\"String\")\n                     Regexp.new( Regexp.quote(options[\"String\"]) )\n                   end\n        time_out = options[\"Timeout\"]  if options.has_key?(\"Timeout\")\n        waittime = options[\"Waittime\"] if options.has_key?(\"Waittime\")\n      else\n        prompt = options\n      end\n\n      if time_out == false\n        time_out = nil\n      end\n\n      line = ''\n      buf = ''\n      @rest = '' unless @rest\n\n      until(prompt === line and not IO::select([@sock], nil, nil, waittime))\n        unless IO::select([@sock], nil, nil, time_out)\n          raise TimeoutError, \"timed-out; wait for the next data\"\n        end\n        begin\n          c = @rest + @sock.sysread(1024 * 1024)\n          @dumplog.log_dump('<', c) if @options.has_key?(\"Dump_log\")\n          if @options[\"Telnetmode\"]   \n            pos = 0\n            catch(:next){\n              while true\n                case c[pos]\n                when IAC[0]\n                  case c[pos+1]\n                  when DO[0], DONT[0], WILL[0], WONT[0]\n                    throw :next unless c[pos+2]\n                    pos += 3\n                  when SB[0]\n                    ret = detect_sub_negotiation(c, pos)\n                    throw :next unless ret\n                    pos = ret\n                  when nil\n                    throw :next\n                  else\n                    pos += 2\n                  end\n                when nil\n                  throw :next\n                else\n                  pos += 1\n                end\n              end\n            }\n\n            buf = preprocess(c[0...pos])\n            @rest = c[pos..-1]\n          end\n          @log.print(buf) if @options.has_key?(\"Output_log\")\n          line.concat(buf)\n          yield buf if block_given?   \n        rescue EOFError # End of file reached\n          if line == ''\n            line = nil\n            yield nil if block_given? \n          end\n          break\n        end\n      end\n      line\n    end\n\n    private\n\n    def detect_sub_negotiation(data, pos)\n      return nil if data.length < pos+6  # IAC SB x param IAC SE\n      pos += 3\n      while true\n        case data[pos]\n        when IAC[0]\n          if data[pos+1] == SE[0]\n            pos += 2\n            return pos\n          else\n            pos += 2\n          end\n        when nil\n          return nil\n        else\n          pos += 1\n        end\n      end\n    end\n\n  end\nend\n"
  },
  {
    "path": "ext/openssl/lib/openssl/bn.rb",
    "content": "=begin\n= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for BN\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\n##\n# Should we care what if somebody require this file directly?\n#require 'openssl'\n\nmodule OpenSSL\n  class BN\n    include Comparable\n  end # BN\nend # OpenSSL\n\n##\n# Add double dispatch to Integer\n#\nclass Integer\n  def to_bn\n    OpenSSL::BN::new(self)\n  end\nend # Integer\n\n"
  },
  {
    "path": "ext/openssl/lib/openssl/buffering.rb",
    "content": "=begin\n= $RCSfile$ -- Buffering mix-in module.\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\nmodule Buffering\n  include Enumerable\n  attr_accessor :sync\n  BLOCK_SIZE = 1024*16\n\n  def initialize(*args)\n    @eof = false\n    @rbuffer = \"\"\n    @sync = @io.sync\n  end\n\n  #\n  # for reading.\n  #\n  private\n\n  def fill_rbuff\n    begin\n      @rbuffer << self.sysread(BLOCK_SIZE)\n    rescue Errno::EAGAIN\n      retry\n    rescue EOFError\n      @eof = true\n    end\n  end\n\n  def consume_rbuff(size=nil)\n    if @rbuffer.empty?\n      nil\n    else\n      size = @rbuffer.size unless size\n      ret = @rbuffer[0, size]\n      @rbuffer[0, size] = \"\"\n      ret\n    end\n  end\n\n  public\n\n  def read(size=nil, buf=nil)\n    if size == 0\n      if buf\n        buf.clear\n      else\n        buf = \"\"\n      end\n      return @eof ? nil : buf\n    end\n    until @eof\n      break if size && size <= @rbuffer.size\n      fill_rbuff\n    end\n    ret = consume_rbuff(size) || \"\"\n    if buf\n      buf.replace(ret)\n      ret = buf\n    end\n    (size && ret.empty?) ? nil : ret\n  end\n\n  def readpartial(maxlen, buf=nil)\n    if maxlen == 0\n      if buf\n        buf.clear\n      else\n        buf = \"\"\n      end\n      return @eof ? nil : buf\n    end\n    if @rbuffer.empty?\n      begin\n        return sysread(maxlen, buf)\n      rescue Errno::EAGAIN\n        retry\n      end\n    end\n    ret = consume_rbuff(maxlen)\n    if buf\n      buf.replace(ret)\n      ret = buf\n    end\n    raise EOFError if ret.empty?\n    ret\n  end\n\n  def gets(eol=$/)\n    idx = @rbuffer.index(eol)\n    until @eof\n      break if idx\n      fill_rbuff\n      idx = @rbuffer.index(eol)\n    end\n    if eol.is_a?(Regexp)\n      size = idx ? idx+$&.size : nil\n    else\n      size = idx ? idx+eol.size : nil\n    end\n    consume_rbuff(size)\n  end\n\n  def each(eol=$/)\n    while line = self.gets(eol)\n      yield line\n    end\n  end\n  alias each_line each\n\n  def readlines(eol=$/)\n    ary = []\n    while line = self.gets(eol)\n      ary << line\n    end\n    ary\n  end\n\n  def readline(eol=$/)\n    raise EOFError if eof?\n    gets(eol)\n  end\n\n  def getc\n    c = read(1)\n    c ? c[0] : nil\n  end\n\n  def each_byte\n    while c = getc\n      yield(c)\n    end\n  end\n\n  def readchar\n    raise EOFError if eof?\n    getc\n  end\n\n  def ungetc(c)\n    @rbuffer[0,0] = c.chr\n  end\n\n  def eof?\n    fill_rbuff if !@eof && @rbuffer.empty?\n    @eof && @rbuffer.empty?\n  end\n  alias eof eof?\n\n  #\n  # for writing.\n  #\n  private\n\n  def do_write(s)\n    @wbuffer = \"\" unless defined? @wbuffer\n    @wbuffer << s\n    @sync ||= false\n    if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)\n      remain = idx ? idx + $/.size : @wbuffer.length\n      nwritten = 0\n      while remain > 0\n        str = @wbuffer[nwritten,remain]\n        begin\n          nwrote = syswrite(str)\n        rescue Errno::EAGAIN\n          retry\n        end\n        remain -= nwrote\n        nwritten += nwrote\n      end\n      @wbuffer[0,nwritten] = \"\"\n    end\n  end\n\n  public\n\n  def write(s)\n    do_write(s)\n    s.length\n  end\n\n  def << (s)\n    do_write(s)\n    self\n  end\n\n  def puts(*args)\n    s = \"\"\n    if args.empty?\n      s << \"\\n\"\n    end\n    args.each{|arg|\n      s << arg.to_s\n      if $/ && /\\n\\z/ !~ s\n        s << \"\\n\"\n      end\n    }\n    do_write(s)\n    nil\n  end\n\n  def print(*args)\n    s = \"\"\n    args.each{ |arg| s << arg.to_s }\n    do_write(s)\n    nil\n  end\n\n  def printf(s, *args)\n    do_write(s % args)\n    nil\n  end\n\n  def flush\n    osync = @sync\n    @sync = true\n    do_write \"\"\n    @sync = osync\n  end\n\n  def close\n    flush rescue nil\n    sysclose\n  end\nend\n"
  },
  {
    "path": "ext/openssl/lib/openssl/cipher.rb",
    "content": "=begin\n= $RCSfile$ -- Ruby-space predefined Cipher subclasses\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\n##\n# Should we care what if somebody require this file directly?\n#require 'openssl'\n\nmodule OpenSSL\n  class Cipher\n    %w(AES CAST5 BF DES IDEA RC2 RC4 RC5).each{|name|\n      klass = Class.new(Cipher){\n        define_method(:initialize){|*args|\n          cipher_name = args.inject(name){|n, arg| \"#{n}-#{arg}\" }\n          super(cipher_name)\n        }\n      }\n      const_set(name, klass)\n    }\n\n    %w(128 192 256).each{|keylen|\n      klass = Class.new(Cipher){\n        define_method(:initialize){|mode|\n          mode ||= \"CBC\"\n          cipher_name = \"AES-#{keylen}-#{mode}\"\n          super(cipher_name)\n        }\n      }\n      const_set(\"AES#{keylen}\", klass)\n    }\n\n    # Generate, set, and return a random key.\n    # You must call cipher.encrypt or cipher.decrypt before calling this method.\n    def random_key\n      str = OpenSSL::Random.random_bytes(self.key_len)\n      self.key = str\n      return str\n    end\n\n    # Generate, set, and return a random iv.\n    # You must call cipher.encrypt or cipher.decrypt before calling this method.\n    def random_iv\n      str = OpenSSL::Random.random_bytes(self.iv_len)\n      self.iv = str\n      return str\n    end\n\n    # This class is only provided for backwards compatibility.  Use OpenSSL::Digest in the future.\n    class Cipher < Cipher\n      # add warning\n    end\n  end # Cipher\nend # OpenSSL\n"
  },
  {
    "path": "ext/openssl/lib/openssl/digest.rb",
    "content": "=begin\n= $RCSfile$ -- Ruby-space predefined Digest subclasses\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\n##\n# Should we care what if somebody require this file directly?\n#require 'openssl'\n\nmodule OpenSSL\n  class Digest\n\n    alg = %w(DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA SHA1)\n    if OPENSSL_VERSION_NUMBER > 0x00908000\n      alg += %w(SHA224 SHA256 SHA384 SHA512)\n    end\n\n    def self.digest(name, data)\n        super(data, name)\n    end\n\n    alg.each{|name|\n      klass = Class.new(Digest){\n        define_method(:initialize){|*data|\n          if data.length > 1\n            raise ArgumentError,\n              \"wrong number of arguments (#{data.length} for 1)\"\n          end\n          super(name, data.first)\n        }\n      }\n      singleton = (class <<klass; self; end)\n      singleton.class_eval{\n        define_method(:digest){|data| Digest.digest(name, data) }\n        define_method(:hexdigest){|data| Digest.hexdigest(name, data) }\n      }\n      const_set(name, klass)\n    }\n\n    # This class is only provided for backwards compatibility.  Use OpenSSL::Digest in the future.\n    class Digest < Digest\n      def initialize(*args)\n        # add warning\n        super(*args)\n      end\n    end\n\n  end # Digest\nend # OpenSSL\n\n"
  },
  {
    "path": "ext/openssl/lib/openssl/pkcs7.rb",
    "content": "=begin\n= $RCSfile$ -- PKCS7\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id: digest.rb 12148 2007-04-05 05:59:22Z technorama $\n=end\n\nmodule OpenSSL\n  class PKCS7\n    # This class is only provided for backwards compatibility.  Use OpenSSL::PKCS7 in the future.\n    class PKCS7 < PKCS7\n      def initialize(*args)\n        super(*args)\n\n        warn(\"Warning: OpenSSL::PKCS7::PKCS7 is deprecated after Ruby 1.9; use OpenSSL::PKCS7 instead\")\n      end\n    end\n\n  end # PKCS7\nend # OpenSSL\n\n"
  },
  {
    "path": "ext/openssl/lib/openssl/ssl.rb",
    "content": "=begin\n= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\nrequire \"openssl\"\nrequire \"openssl/buffering\"\nrequire \"fcntl\"\n\nmodule OpenSSL\n  module SSL\n    class SSLContext\n      DEFAULT_PARAMS = {\n        :ssl_version => \"SSLv23\",\n        :verify_mode => OpenSSL::SSL::VERIFY_PEER,\n        :ciphers => \"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW\",\n        :options => OpenSSL::SSL::OP_ALL,\n      }\n\n      DEFAULT_CERT_STORE = OpenSSL::X509::Store.new\n      DEFAULT_CERT_STORE.set_default_paths\n      if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL)\n        DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL\n      end\n\n      def set_params(params={})\n        params = DEFAULT_PARAMS.merge(params)\n        self.ssl_version = params.delete(:ssl_version)\n        params.each{|name, value| self.__send__(\"#{name}=\", value) }\n        if self.verify_mode != OpenSSL::SSL::VERIFY_NONE\n          unless self.ca_file or self.ca_path or self.cert_store\n            self.cert_store = DEFAULT_CERT_STORE\n          end\n        end\n        return params\n      end\n    end\n\n    module SocketForwarder\n      def addr\n        to_io.addr\n      end\n\n      def peeraddr\n        to_io.peeraddr\n      end\n\n      def setsockopt(level, optname, optval)\n        to_io.setsockopt(level, optname, optval)\n      end\n\n      def getsockopt(level, optname)\n        to_io.getsockopt(level, optname)\n      end\n\n      def fcntl(*args)\n        to_io.fcntl(*args)\n      end\n\n      def closed?\n        to_io.closed?\n      end\n\n      def do_not_reverse_lookup=(flag)\n        to_io.do_not_reverse_lookup = flag\n      end\n    end\n\n    module Nonblock\n      def initialize(*args)\n        flag = File::NONBLOCK\n        flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL)\n        @io.fcntl(Fcntl::F_SETFL, flag)\n        super\n      end\n    end\n\n    def verify_certificate_identity(cert, hostname)\n      should_verify_common_name = true\n      cert.extensions.each{|ext|\n        next if ext.oid != \"subjectAltName\"\n        ext.value.split(/,\\s+/).each{|general_name|\n          if /\\ADNS:(.*)/ =~ general_name\n            should_verify_common_name = false\n            reg = Regexp.escape($1).gsub(/\\\\\\*/, \"[^.]+\")\n            return true if /\\A#{reg}\\z/i =~ hostname\n          elsif /\\AIP Address:(.*)/ =~ general_name\n            should_verify_common_name = false\n            return true if $1 == hostname\n          end\n        }\n      }\n      if should_verify_common_name\n        cert.subject.to_a.each{|oid, value|\n          if oid == \"CN\"\n            reg = Regexp.escape(value).gsub(/\\\\\\*/, \"[^.]+\")\n            return true if /\\A#{reg}\\z/i =~ hostname\n          end\n        }\n      end\n      return false\n    end\n    module_function :verify_certificate_identity\n\n    class SSLSocket\n      include Buffering\n      include SocketForwarder\n      include Nonblock\n\n      def post_connection_check(hostname)\n        unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname)\n          raise SSLError, \"hostname was not match with the server certificate\"\n        end\n        return true\n      end\n\n      def session\n        SSL::Session.new(self)\n      rescue SSL::Session::SessionError\n        nil\n      end\n    end\n\n    class SSLServer\n      include SocketForwarder\n      attr_accessor :start_immediately\n\n      def initialize(svr, ctx)\n        @svr = svr\n        @ctx = ctx\n        unless ctx.session_id_context\n          session_id = OpenSSL::Digest::MD5.hexdigest($0)\n          @ctx.session_id_context = session_id\n        end\n        @start_immediately = true\n      end\n\n      def to_io\n        @svr\n      end\n\n      def listen(backlog=5)\n        @svr.listen(backlog)\n      end\n\n      def shutdown(how=Socket::SHUT_RDWR)\n        @svr.shutdown(how)\n      end\n\n      def accept\n        sock = @svr.accept\n        begin\n          ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)\n          ssl.sync_close = true\n          ssl.accept if @start_immediately\n          ssl\n        rescue SSLError => ex\n          sock.close\n          raise ex\n        end\n      end\n\n      def close\n        @svr.close\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/openssl/lib/openssl/x509.rb",
    "content": "=begin\n= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\nrequire \"openssl\"\n\nmodule OpenSSL\n  module X509\n    class ExtensionFactory\n      def create_extension(*arg)\n        if arg.size > 1\n          create_ext(*arg)\n        else\n          send(\"create_ext_from_\"+arg[0].class.name.downcase, arg[0])\n        end\n      end\n\n      def create_ext_from_array(ary)\n        raise ExtensionError, \"unexpected array form\" if ary.size > 3 \n        create_ext(ary[0], ary[1], ary[2])\n      end\n\n      def create_ext_from_string(str) # \"oid = critical, value\"\n        oid, value = str.split(/=/, 2)\n        oid.strip!\n        value.strip!\n        create_ext(oid, value)\n      end\n      \n      def create_ext_from_hash(hash)\n        create_ext(hash[\"oid\"], hash[\"value\"], hash[\"critical\"])\n      end\n    end\n    \n    class Extension\n      def to_s # \"oid = critical, value\"\n        str = self.oid\n        str << \" = \"\n        str << \"critical, \" if self.critical?\n        str << self.value.gsub(/\\n/, \", \")\n      end\n        \n      def to_h # {\"oid\"=>sn|ln, \"value\"=>value, \"critical\"=>true|false}\n        {\"oid\"=>self.oid,\"value\"=>self.value,\"critical\"=>self.critical?}\n      end\n\n      def to_a\n        [ self.oid, self.value, self.critical? ]\n      end\n    end\n\n    class Name\n      module RFC2253DN\n        Special = ',=+<>#;'\n        HexChar = /[0-9a-fA-F]/\n        HexPair = /#{HexChar}#{HexChar}/\n        HexString = /#{HexPair}+/\n        Pair = /\\\\(?:[#{Special}]|\\\\|\"|#{HexPair})/\n        StringChar = /[^#{Special}\\\\\"]/\n        QuoteChar = /[^\\\\\"]/\n        AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\\.[0-9]+)*/\n        AttributeValue = /\n          (?![\"#])((?:#{StringChar}|#{Pair})*)|\n          \\#(#{HexString})|\n          \"((?:#{QuoteChar}|#{Pair})*)\"\n        /x\n        TypeAndValue = /\\A(#{AttributeType})=#{AttributeValue}/\n\n        module_function\n\n        def expand_pair(str)\n          return nil unless str\n          return str.gsub(Pair){|pair|\n            case pair.size\n            when 2 then pair[1,1]\n            when 3 then Integer(\"0x#{pair[1,2]}\").chr\n            else raise OpenSSL::X509::NameError, \"invalid pair: #{str}\"\n            end\n          }\n        end\n\n        def expand_hexstring(str)\n          return nil unless str\n          der = str.gsub(HexPair){|hex| Integer(\"0x#{hex}\").chr }\n          a1 = OpenSSL::ASN1.decode(der)\n          return a1.value, a1.tag\n        end\n\n        def expand_value(str1, str2, str3)\n          value = expand_pair(str1)\n          value, tag = expand_hexstring(str2) unless value\n          value = expand_pair(str3) unless value\n          return value, tag\n        end\n\n        def scan(dn)\n          str = dn\n          ary = []\n          while true\n            if md = TypeAndValue.match(str)\n              matched = md.to_s\n              remain = md.post_match\n              type = md[1]\n              value, tag = expand_value(md[2], md[3], md[4]) rescue nil\n              if value\n                type_and_value = [type, value]\n                type_and_value.push(tag) if tag\n                ary.unshift(type_and_value)\n                if remain.length > 2 && remain[0] == ?,\n                  str = remain[1..-1]\n                  next\n                elsif remain.length > 2 && remain[0] == ?+\n                  raise OpenSSL::X509::NameError,\n                    \"multi-valued RDN is not supported: #{dn}\"\n                elsif remain.empty?\n                  break\n                end\n              end\n            end\n            msg_dn = dn[0, dn.length - str.length] + \" =>\" + str\n            raise OpenSSL::X509::NameError, \"malformed RDN: #{msg_dn}\"\n          end\n          return ary\n        end\n      end\n\n      class <<self\n        def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE)\n          ary = OpenSSL::X509::Name::RFC2253DN.scan(str)\n          self.new(ary, template)\n        end\n\n        def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)\n          ary = str.scan(/\\s*([^\\/,]+)\\s*/).collect{|i| i[0].split(\"=\", 2) }\n          self.new(ary, template)\n        end\n\n        alias parse parse_openssl\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/openssl/lib/openssl.rb",
    "content": "=begin\n= $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions\n\n= Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>\n  All rights reserved.\n\n= Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n= Version\n  $Id$\n=end\n\nrequire 'openssl.so'\n\nrequire 'openssl/bn'\nrequire 'openssl/cipher'\nrequire 'openssl/digest'\nrequire 'openssl/pkcs7'\nrequire 'openssl/ssl'\nrequire 'openssl/x509'\n\n"
  },
  {
    "path": "ext/openssl/openssl_missing.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include RUBY_EXTCONF_H\n\n#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ST_ENGINE)\n# include <openssl/engine.h>\n#endif\n#include <openssl/x509_vfy.h>\n\n#if !defined(OPENSSL_NO_HMAC)\n#include <string.h> /* memcpy() */\n#include <openssl/hmac.h>\n\n#include \"openssl_missing.h\"\n\n#if !defined(HAVE_HMAC_CTX_COPY)\nvoid\nHMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in)\n{\n    if (!out || !in) return;\n    memcpy(out, in, sizeof(HMAC_CTX));\n\n    EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx);\n    EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx);\n    EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx);\n}\n#endif /* HAVE_HMAC_CTX_COPY */\n#endif /* NO_HMAC */\n\n#if !defined(HAVE_X509_STORE_SET_EX_DATA)\n\nint X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data)\n{\n    return CRYPTO_set_ex_data(&str->ex_data, idx, data);\n}\n \nvoid *X509_STORE_get_ex_data(X509_STORE *str, int idx)\n{\n    return CRYPTO_get_ex_data(&str->ex_data, idx);\n}\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_CREATE)\nEVP_MD_CTX *\nEVP_MD_CTX_create(void)\n{\n    EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX));\n    if (!ctx) return NULL;\n\n    memset(ctx, 0, sizeof(EVP_MD_CTX));\n\n    return ctx;\n}\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_CLEANUP)\nint\nEVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)\n{\n    /* FIXME!!! */\n    memset(ctx, 0, sizeof(EVP_MD_CTX));\n\n    return 1;\n}\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_DESTROY)\nvoid\nEVP_MD_CTX_destroy(EVP_MD_CTX *ctx)\n{\n    EVP_MD_CTX_cleanup(ctx);\n    OPENSSL_free(ctx);\n}\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_INIT)\nvoid\nEVP_MD_CTX_init(EVP_MD_CTX *ctx)\n{\n    memset(ctx, 0, sizeof(EVP_MD_CTX));\n}\n#endif\n\n#if !defined(HAVE_HMAC_CTX_INIT)\nvoid\nHMAC_CTX_init(HMAC_CTX *ctx)\n{\n    EVP_MD_CTX_init(&ctx->i_ctx);\n    EVP_MD_CTX_init(&ctx->o_ctx);\n    EVP_MD_CTX_init(&ctx->md_ctx);\n}\n#endif\n\n#if !defined(HAVE_HMAC_CTX_CLEANUP)\nvoid\nHMAC_CTX_cleanup(HMAC_CTX *ctx)\n{\n    EVP_MD_CTX_cleanup(&ctx->i_ctx);\n    EVP_MD_CTX_cleanup(&ctx->o_ctx);\n    EVP_MD_CTX_cleanup(&ctx->md_ctx);\n    memset(ctx, 0, sizeof(HMAC_CTX));\n}\n#endif\n\n#if !defined(HAVE_EVP_CIPHER_CTX_COPY)\n/* \n * this function does not exist in OpenSSL yet... or ever?.\n * a future version may break this function.\n * tested on 0.9.7d.\n */\nint\nEVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in)\n{\n    memcpy(out, in, sizeof(EVP_CIPHER_CTX));\n\n#if defined(HAVE_ENGINE_ADD) && defined(HAVE_ST_ENGINE)\n    if (in->engine) ENGINE_add(out->engine);\n    if (in->cipher_data) {\n\tout->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);\n\tmemcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);\n    }\n#endif\n\n    return 1;\n}\n#endif\n\n#if !defined(HAVE_X509_CRL_SET_VERSION)\nint\nX509_CRL_set_version(X509_CRL *x, long version)\n{\n    if (x == NULL || x->crl == NULL) return 0;\n    if (x->crl->version == NULL) {\n\tx->crl->version = M_ASN1_INTEGER_new();\n\tif (x->crl->version == NULL) return 0;\n    }\n    return ASN1_INTEGER_set(x->crl->version, version);\n}\n#endif\n\n#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME)\nint\nX509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)\n{\n    if (x == NULL || x->crl == NULL) return 0;\n    return X509_NAME_set(&x->crl->issuer, name);\n}\n#endif\n\n#if !defined(HAVE_X509_CRL_SORT)\nint\nX509_CRL_sort(X509_CRL *c)\n{\n    int i;\n    X509_REVOKED *r;\n    /* sort the data so it will be written in serial\n     * number order */\n    sk_X509_REVOKED_sort(c->crl->revoked);\n    for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++) {\n\tr=sk_X509_REVOKED_value(c->crl->revoked, i);\n\tr->sequence=i;\n    }\n    return 1;\n}\n#endif\n\n#if !defined(HAVE_X509_CRL_ADD0_REVOKED)\nstatic int\nOSSL_X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b)\n{\n    return(ASN1_STRING_cmp(\n\t\t(ASN1_STRING *)(*a)->serialNumber,\n\t\t(ASN1_STRING *)(*b)->serialNumber));\n}\n\t\t    \nint\nX509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)\n{\n    X509_CRL_INFO *inf;\n    \n    inf = crl->crl;\n    if (!inf->revoked)\n\tinf->revoked = sk_X509_REVOKED_new(OSSL_X509_REVOKED_cmp);\n    if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev))\n\treturn 0;\n    return 1;\n}\n#endif\n\n#if !defined(HAVE_BN_MOD_SQR)\nint\nBN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)\n{\n    if (!BN_sqr(r, (BIGNUM*)a, ctx)) return 0;\n    return BN_mod(r, r, m, ctx);\n}\n#endif\n\n#if !defined(HAVE_BN_MOD_ADD) || !defined(HAVE_BN_MOD_SUB)\nint BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)\n{\n    if (!BN_mod(r,m,d,ctx)) return 0;\n    if (!r->neg) return 1;\n    return (d->neg ? BN_sub : BN_add)(r, r, d);\n}\n#endif\n\n#if !defined(HAVE_BN_MOD_ADD)\nint\nBN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)\n{\n    if (!BN_add(r, a, b)) return 0;\n    return BN_nnmod(r, r, m, ctx);\n}\n#endif\n\n#if !defined(HAVE_BN_MOD_SUB)\nint\nBN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)\n{\n    if (!BN_sub(r, a, b)) return 0;\n    return BN_nnmod(r, r, m, ctx);\n}\n#endif\n\n#if !defined(HAVE_BN_RAND_RANGE) || !defined(HAVE_BN_PSEUDO_RAND_RANGE)\nstatic int\nbn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)\n{\n    int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;\n    int n;\n\n    if (range->neg || BN_is_zero(range)) return 0;\n\n    n = BN_num_bits(range);\n\n    if (n == 1) {\n\tif (!BN_zero(r)) return 0;\n    } else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {\n\tdo {\n\t    if (!bn_rand(r, n + 1, -1, 0)) return 0;\n\t    if (BN_cmp(r ,range) >= 0) {\n\t\tif (!BN_sub(r, r, range)) return 0;\n\t\tif (BN_cmp(r, range) >= 0)\n\t\t    if (!BN_sub(r, r, range)) return 0;\n\t    }\n\t} while (BN_cmp(r, range) >= 0);\n    } else {\n\tdo {\n\t    if (!bn_rand(r, n, -1, 0)) return 0;\n\t} while (BN_cmp(r, range) >= 0);\n    }\n\n    return 1;\n}\n#endif\n\n#if !defined(HAVE_BN_RAND_RANGE)\nint\nBN_rand_range(BIGNUM *r, BIGNUM *range)\n{\n    return bn_rand_range(0, r, range);\n}\n#endif\n\n#if !defined(HAVE_BN_PSEUDO_RAND_RANGE)\nint\nBN_pseudo_rand_range(BIGNUM *r, BIGNUM *range)\n{\n    return bn_rand_range(1, r, range);\n}\n#endif\n\n#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE)\n#define OPENSSL_CONF \"openssl.cnf\"\nchar *\nCONF_get1_default_config_file(void)\n{\n    char *file;\n    int len;\n\n    file = getenv(\"OPENSSL_CONF\");\n    if (file) return BUF_strdup(file);\n    len = strlen(X509_get_default_cert_area());\n#ifndef OPENSSL_SYS_VMS\n    len++;\n#endif\n    len += strlen(OPENSSL_CONF);\n    file = OPENSSL_malloc(len + 1);\n    if (!file) return NULL;\n    strcpy(file,X509_get_default_cert_area());\n#ifndef OPENSSL_SYS_VMS\n    strcat(file,\"/\");\n#endif\n    strcat(file,OPENSSL_CONF);\n\n    return file;\n}\n#endif\n\n#if !defined(HAVE_PEM_DEF_CALLBACK)\n#define OSSL_PASS_MIN_LENGTH 4\nint\nPEM_def_callback(char *buf, int num, int w, void *key)\n{\n    int i,j;\n    const char *prompt;\n    \n    if (key) {\n\ti = strlen(key);\n\ti = (i > num) ? num : i;\n\tmemcpy(buf, key, i);\n\treturn i;\n    }\n\n    prompt = EVP_get_pw_prompt();\n    if (prompt == NULL) prompt = \"Enter PEM pass phrase:\";\n    for (;;) {\n\ti = EVP_read_pw_string(buf, num, prompt, w);\n\tif (i != 0) {\n\t    memset(buf, 0, (unsigned int)num);\n\t    return(-1);\n\t}\n\tj = strlen(buf);\n\tif (j < OSSL_PASS_MIN_LENGTH) {\n\t    fprintf(stderr,\n\t\t    \"phrase is too short, needs to be at least %d chars\\n\",\n\t\t    OSSL_PASS_MIN_LENGTH);\n\t}\n\telse break;\n    }\n    return j;\n}\n#endif\n\n"
  },
  {
    "path": "ext/openssl/openssl_missing.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_OPENSSL_MISSING_H_)\n#define _OSSL_OPENSSL_MISSING_H_\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n#ifndef TYPEDEF_D2I_OF\ntypedef char *d2i_of_void();\n#endif\n\n/*\n * These functions are not included in headers of OPENSSL <= 0.9.6b\n */\n\n#if !defined(PEM_read_bio_DSAPublicKey)\n# define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \\\n        (char *(*)())d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,bp,(char **)x,cb,u)\n#endif\n\n#if !defined(PEM_write_bio_DSAPublicKey)\n# define PEM_write_bio_DSAPublicKey(bp,x) \\\n\tPEM_ASN1_write_bio((int (*)())i2d_DSAPublicKey,\\\n\t\tPEM_STRING_DSA_PUBLIC,\\\n\t\tbp,(char *)x, NULL, NULL, 0, NULL, NULL)\n#endif\n\n#if !defined(DSAPrivateKey_dup)\n# define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((int (*)())i2d_DSAPrivateKey, \\\n\t(char *(*)())d2i_DSAPrivateKey,(char *)dsa)\n#endif\n\n#if !defined(DSAPublicKey_dup)\n# define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((int (*)())i2d_DSAPublicKey, \\\n\t(char *(*)())d2i_DSAPublicKey,(char *)dsa)\n#endif\n\n#if !defined(X509_REVOKED_dup)\n# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((int (*)())i2d_X509_REVOKED, \\\n\t(char *(*)())d2i_X509_REVOKED, (char *)rev)\n#endif\n\n#if !defined(PKCS7_SIGNER_INFO_dup)\n#  define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((int (*)())i2d_PKCS7_SIGNER_INFO, \\\n\t(char *(*)())d2i_PKCS7_SIGNER_INFO, (char *)si)\n#endif\n\n#if !defined(PKCS7_RECIP_INFO_dup)\n#  define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((int (*)())i2d_PKCS7_RECIP_INFO, \\\n\t(char *(*)())d2i_PKCS7_RECIP_INFO, (char *)ri)\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_INIT)\nvoid HMAC_CTX_init(HMAC_CTX *ctx);\n#endif\n\n#if !defined(HAVE_HMAC_CTX_COPY)\nvoid HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);\n#endif\n\n#if !defined(HAVE_HMAC_CTX_CLEANUP)\nvoid HMAC_CTX_cleanup(HMAC_CTX *ctx);\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_CREATE)\nEVP_MD_CTX *EVP_MD_CTX_create(void);\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_INIT)\nvoid EVP_MD_CTX_init(EVP_MD_CTX *ctx);\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_CLEANUP)\nint EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);\n#endif\n\n#if !defined(HAVE_EVP_MD_CTX_DESTROY)\nvoid EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);\n#endif\n\n#if !defined(HAVE_EVP_CIPHER_CTX_COPY)\nint EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in);\n#endif\n\n#if !defined(HAVE_EVP_DIGESTINIT_EX)\n#  define EVP_DigestInit_ex(ctx, md, engine) EVP_DigestInit(ctx, md)\n#endif\n#if !defined(HAVE_EVP_DIGESTFINAL_EX)\n#  define EVP_DigestFinal_ex(ctx, buf, len) EVP_DigestFinal(ctx, buf, len)\n#endif\n\n#if !defined(HAVE_EVP_CIPHERINIT_EX)\n#  define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc) EVP_CipherInit(ctx, type, key, iv, enc)\n#endif\n#if !defined(HAVE_EVP_CIPHERFINAL_EX)\n#  define EVP_CipherFinal_ex(ctx, outm, outl) EVP_CipherFinal(ctx, outm, outl)\n#endif\n\n#if !defined(EVP_CIPHER_name)\n#  define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))\n#endif\n\n#if !defined(EVP_MD_name)\n#  define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e))\n#endif\n\n#if !defined(HAVE_EVP_HMAC_INIT_EX)\n#  define HMAC_Init_ex(ctx, key, len, digest, engine) HMAC_Init(ctx, key, len, digest)\n#endif\n\n#if !defined(PKCS7_is_detached)\n#  define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))\n#endif\n\n#if !defined(PKCS7_type_is_encrypted)\n#  define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)\n#endif\n\n#if !defined(HAVE_OPENSSL_CLEANSE)\n#define OPENSSL_cleanse(p, l) memset(p, 0, l)\n#endif\n\n#if !defined(HAVE_X509_STORE_SET_EX_DATA)\nvoid *X509_STORE_get_ex_data(X509_STORE *str, int idx);\nint X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data);\n#endif\n\n#if !defined(HAVE_X509_CRL_SET_VERSION)\nint X509_CRL_set_version(X509_CRL *x, long version);\n#endif\n\n#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME)\nint X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);\n#endif\n\n#if !defined(HAVE_X509_CRL_SORT)\nint X509_CRL_sort(X509_CRL *c);\n#endif\n\n#if !defined(HAVE_X509_CRL_ADD0_REVOKED)\nint X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);\n#endif\n\n#if !defined(HAVE_BN_MOD_SQR)\nint BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);\n#endif\n\n#if !defined(HAVE_BN_MOD_ADD)\nint BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);\n#endif\n\n#if !defined(HAVE_BN_MOD_SUB)\nint BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);\n#endif\n\n#if !defined(HAVE_BN_RAND_RANGE)\nint BN_rand_range(BIGNUM *r, BIGNUM *range);\n#endif\n\n#if !defined(HAVE_BN_PSEUDO_RAND_RANGE)\nint BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range);\n#endif\n\n#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE)\nchar *CONF_get1_default_config_file(void);\n#endif\n\n#if !defined(HAVE_PEM_DEF_CALLBACK)\nint PEM_def_callback(char *buf, int num, int w, void *key);\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n\n\n#endif /* _OSSL_OPENSSL_MISSING_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n#include <stdarg.h> /* for ossl_raise */\n\n/*\n * String to HEXString conversion\n */\nint\nstring2hex(char *buf, int buf_len, char **hexbuf, int *hexbuf_len)\n{\n    static const char hex[]=\"0123456789abcdef\";\n    int i, len = 2 * buf_len;\n\n    if (buf_len < 0 || len < buf_len) { /* PARANOIA? */\n\treturn -1;\n    }\n    if (!hexbuf) { /* if no buf, return calculated len */\n\tif (hexbuf_len) {\n\t    *hexbuf_len = len;\n\t}\n\treturn len;\n    }\n    if (!(*hexbuf = OPENSSL_malloc(len + 1))) {\n\treturn -1;\n    }\n    for (i = 0; i < buf_len; i++) {\n\t(*hexbuf)[2 * i] = hex[((unsigned char)buf[i]) >> 4];\n\t(*hexbuf)[2 * i + 1] = hex[buf[i] & 0x0f];\n    }\n    (*hexbuf)[2 * i] = '\\0';\n\n    if (hexbuf_len) {\n\t*hexbuf_len = len;\n    }\n    return len;\n}\n\n/*\n * Data Conversion\n */\nSTACK_OF(X509) *\nossl_x509_ary2sk0(VALUE ary)  \n{\n    STACK_OF(X509) *sk;\n    VALUE val;\n    X509 *x509;\n    int i;\n\n    Check_Type(ary, T_ARRAY);\n    sk = sk_X509_new_null();\n    if (!sk) ossl_raise(eOSSLError, NULL); \n\n    for (i = 0; i < RARRAY_LEN(ary); i++) {\n        val = rb_ary_entry(ary, i);\n        if (!rb_obj_is_kind_of(val, cX509Cert)) {\n            sk_X509_pop_free(sk, X509_free);\n            ossl_raise(eOSSLError, \"object not X509 cert in array\"); \n        }\n        x509 = DupX509CertPtr(val); /* NEED TO DUP */\n        sk_X509_push(sk, x509);\n    }\n    return sk;\n}\n\nSTACK_OF(X509) *\nossl_protect_x509_ary2sk(VALUE ary, int *status)\n{\n    return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,\n\t\t\t\t       ary, status);\n}\n\nSTACK_OF(X509) *\nossl_x509_ary2sk(VALUE ary)\n{\n    STACK_OF(X509) *sk;\n    int status = 0;\n\n    sk = ossl_protect_x509_ary2sk(ary, &status);\n    if(status) rb_jump_tag(status);\n\n    return sk;\n}\n\n#define OSSL_IMPL_SK2ARY(name, type)\t        \\\nVALUE\t\t\t\t\t\t\\\nossl_##name##_sk2ary(STACK_OF(type) *sk)\t\\\n{\t\t\t\t\t\t\\\n    type *t;\t\t\t\t\t\\\n    int i, num;\t\t\t\t\t\\\n    VALUE ary;\t\t\t\t\t\\\n\t\t\t\t\t\t\\\n    if (!sk) {\t\t\t\t\t\\\n\tOSSL_Debug(\"empty sk!\");\t\t\\\n\treturn Qnil;\t\t\t\t\\\n    }\t\t\t\t\t\t\\\n    num = sk_##type##_num(sk);\t\t\t\\\n    if (num < 0) {\t\t\t\t\\\n\tOSSL_Debug(\"items in sk < -1???\");\t\\\n\treturn rb_ary_new();\t\t\t\\\n    }\t\t\t\t\t\t\\\n    ary = rb_ary_new2(num);\t\t\t\\\n\t\t\t\t\t\t\\\n    for (i=0; i<num; i++) {\t\t\t\\\n\tt = sk_##type##_value(sk, i);\t\t\\\n\trb_ary_push(ary, ossl_##name##_new(t));\t\\\n    }\t\t\t\t\t\t\\\n    return ary;\t\t\t\t\t\\\n}\nOSSL_IMPL_SK2ARY(x509, X509)\nOSSL_IMPL_SK2ARY(x509crl, X509_CRL)\n\nstatic VALUE\nossl_str_new(int size)\n{\n    return rb_str_new(0, size);\n}\n\nVALUE\nossl_buf2str(char *buf, int len)\n{\n    VALUE str;\n    int status = 0;\n\n    str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);\n    if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);\n    OPENSSL_free(buf);\n    if(status) rb_jump_tag(status);\n\n    return str;\n}\n\n/*\n * our default PEM callback\n */\nstatic VALUE\nossl_pem_passwd_cb0(VALUE flag)\n{\t\n    VALUE pass;\n\n    pass = rb_yield(flag);\n    SafeStringValue(pass);\n\n    return pass;\n}\n\nint\nossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)\n{\n    int len, status = 0;\n    VALUE rflag, pass;\n    \n    if (pwd || !rb_block_given_p())\n\treturn PEM_def_callback(buf, max_len, flag, pwd);\n\n    while (1) {\n\t/*\n\t * when the flag is nonzero, this passphrase\n\t * will be used to perform encryption; otherwise it will\n\t * be used to perform decryption.\n\t */\n\trflag = flag ? Qtrue : Qfalse;\n\tpass  = rb_protect(ossl_pem_passwd_cb0, rflag, &status);\n\tif (status) return -1; /* exception was raised. */\n\tlen = RSTRING_LEN(pass);\n\tif (len < 4) { /* 4 is OpenSSL hardcoded limit */\n\t    rb_warning(\"password must be longer than 4 bytes\");\n\t    continue;\n\t}\n\tif (len > max_len) {\n\t    rb_warning(\"password must be shorter then %d bytes\", max_len-1);\n\t    continue;\n\t}\n\tmemcpy(buf, RSTRING_PTR(pass), len);\n\tbreak;\n    }\n    return len;\n}\n\n/*\n * Verify callback\n */\nint ossl_verify_cb_idx;\n\nVALUE\nossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)\n{   \n    return rb_funcall(args->proc, rb_intern(\"call\"), 2,\n                      args->preverify_ok, args->store_ctx);\n}\n \nint \nossl_verify_cb(int ok, X509_STORE_CTX *ctx)\n{\n    VALUE proc, rctx, ret;\n    struct ossl_verify_cb_args args;\n    int state = 0;\n\n    proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);\n    if ((void*)proc == 0)\n\tproc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);\n    if ((void*)proc == 0)\n\treturn ok;\n    if (!NIL_P(proc)) {\n\trctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,\n\t\t\t  (VALUE)ctx, &state);\n\tret = Qfalse;\n\tif (!state) {\n\t    args.proc = proc;\n\t    args.preverify_ok = ok ? Qtrue : Qfalse;\n\t    args.store_ctx = rctx;\n\t    ret = rb_ensure(ossl_call_verify_cb_proc, (VALUE)&args,\n\t\t\t    ossl_x509stctx_clear_ptr, rctx);\n\t}\n\tif (ret == Qtrue) {\n\t    X509_STORE_CTX_set_error(ctx, X509_V_OK);\n\t    ok = 1;\n\t}\n\telse{\n\t    if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {\n\t\tX509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);\n\t    }\n\t    ok = 0;\n\t}\n    }\n\n    return ok;\n}\n\n/*\n * main module\n */\nVALUE mOSSL;\n\n/*\n * OpenSSLError < StandardError\n */\nVALUE eOSSLError;\n\n/*\n * Convert to DER string\n */\nID ossl_s_to_der;\n\nVALUE\nossl_to_der(VALUE obj)\n{\n    VALUE tmp;\n\n    tmp = rb_funcall(obj, ossl_s_to_der, 0);\n    StringValue(tmp);\n\n    return tmp;\n}\n\nVALUE\nossl_to_der_if_possible(VALUE obj)\n{\n    if(rb_respond_to(obj, ossl_s_to_der))\n\treturn ossl_to_der(obj);\n    return obj;\n}\n\n/*\n * Errors\n */\nvoid\nossl_raise(VALUE exc, const char *fmt, ...)\n{\n    va_list args;\n    char buf[BUFSIZ];\n    const char *msg;\n    long e;\n    int len = 0;\n\n#ifdef HAVE_ERR_PEEK_LAST_ERROR\n    e = ERR_peek_last_error();\n#else\n    e = ERR_peek_error();\n#endif\n    if (fmt) {\n\tva_start(args, fmt);\n\tlen = vsnprintf(buf, BUFSIZ, fmt, args);\n\tva_end(args);\n    }\n    if (len < BUFSIZ && e) {\n\tif (dOSSL == Qtrue) /* FULL INFO */\n\t    msg = ERR_error_string(e, NULL);\n\telse\n\t    msg = ERR_reason_error_string(e);\n\tfmt = len ? \": %s\" : \"%s\";\n\tlen += snprintf(buf+len, BUFSIZ-len, fmt, msg);\n    }\n    if (dOSSL == Qtrue){ /* show all errors on the stack */\n\twhile ((e = ERR_get_error()) != 0){\n\t    rb_warn(\"error on stack: %s\", ERR_error_string(e, NULL));\n\t}\n    }\n    ERR_clear_error();\n\n    if(len > BUFSIZ) len = strlen(buf);\n    rb_exc_raise(rb_exc_new(exc, buf, len));\n}\n\n/*\n * call-seq:\n *   OpenSSL.errors -> [String...]\n *\n * See any remaining errors held in queue.\n *\n * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.\n */\nVALUE\nossl_get_errors()\n{\n    VALUE ary;\n    long e;\n\n    ary = rb_ary_new();\n    while ((e = ERR_get_error()) != 0){\n        rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));\n    }\n\n    return ary;\n}\n\n/*\n * Debug\n */\nVALUE dOSSL;\n\n#if !defined(HAVE_VA_ARGS_MACRO)\nvoid\nossl_debug(const char *fmt, ...)\n{\n    va_list args;\n\t\n    if (dOSSL == Qtrue) {\n\tfprintf(stderr, \"OSSL_DEBUG: \");\n\tva_start(args, fmt);\n\tvfprintf(stderr, fmt, args);\n\tva_end(args);\n\tfprintf(stderr, \" [CONTEXT N/A]\\n\");\n    }\n}\n#endif\n\n/*\n * call-seq:\n *   OpenSSL.debug -> true | false\n */\nstatic VALUE\nossl_debug_get(VALUE self)\n{\n    return dOSSL;\n}\n\n/*\n * call-seq:\n *   OpenSSL.debug = boolean -> boolean\n *\n * Turns on or off CRYPTO_MEM_CHECK.\n * Also shows some debugging message on stderr.\n */\nstatic VALUE\nossl_debug_set(VALUE self, VALUE val)\n{\n    VALUE old = dOSSL;\n    dOSSL = val;\n\t\n    if (old != dOSSL) {\n\tif (dOSSL == Qtrue) {\n\t    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);\n\t    fprintf(stderr, \"OSSL_DEBUG: IS NOW ON!\\n\");\n\t} else if (old == Qtrue) {\n\t    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);\n\t    fprintf(stderr, \"OSSL_DEBUG: IS NOW OFF!\\n\");\n\t}\n    }\n    return val;\n}\n\n/*\n * OSSL library init\n */\nvoid\nInit_openssl()\n{\n    /*\n     * Init timezone info\n     */\n#if 0\n    tzset();\n#endif\n\n    /*\n     * Init all digests, ciphers\n     */\n    /* CRYPTO_malloc_init(); */\n    /* ENGINE_load_builtin_engines(); */\n    OpenSSL_add_ssl_algorithms();\n    OpenSSL_add_all_algorithms();\n    ERR_load_crypto_strings();\n    SSL_load_error_strings();\n\n    /*\n     * FIXME:\n     * On unload do:\n     */\n#if 0\n    CONF_modules_unload(1);\n    destroy_ui_method();\n    EVP_cleanup();\n    ENGINE_cleanup();\n    CRYPTO_cleanup_all_ex_data();\n    ERR_remove_state(0);\n    ERR_free_strings();\n#endif\n\n    /*\n     * Init main module\n     */\n    mOSSL = rb_define_module(\"OpenSSL\");\n\n    /*\n     * Constants\n     */\n    rb_define_const(mOSSL, \"VERSION\", rb_str_new2(OSSL_VERSION));\n    rb_define_const(mOSSL, \"OPENSSL_VERSION\", rb_str_new2(OPENSSL_VERSION_TEXT));\n    rb_define_const(mOSSL, \"OPENSSL_VERSION_NUMBER\", INT2NUM(OPENSSL_VERSION_NUMBER));\n\n    /*\n     * Generic error,\n     * common for all classes under OpenSSL module\n     */\n    eOSSLError = rb_define_class_under(mOSSL,\"OpenSSLError\",rb_eStandardError);\n\n    /*\n     * Verify callback Proc index for ext-data\n     */\n    if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, \"ossl_verify_cb_idx\", 0, 0, 0)) < 0)\n        ossl_raise(eOSSLError, \"X509_STORE_CTX_get_ex_new_index\");\n\n    /*\n     * Init debug core\n     */\n    dOSSL = Qfalse;\n    rb_define_module_function(mOSSL, \"debug\", ossl_debug_get, 0);\n    rb_define_module_function(mOSSL, \"debug=\", ossl_debug_set, 1);\n    rb_define_module_function(mOSSL, \"errors\", ossl_get_errors, 0);\n\n    /*\n     * Get ID of to_der\n     */\n    ossl_s_to_der = rb_intern(\"to_der\");\n\n    /*\n     * Init components\n     */\n    Init_ossl_bn();\n    Init_ossl_cipher();\n    Init_ossl_config();\n    Init_ossl_digest();\n    Init_ossl_hmac();\n    Init_ossl_ns_spki();\n    Init_ossl_pkcs12();\n    Init_ossl_pkcs7();\n    Init_ossl_pkcs5();\n    Init_ossl_pkey();\n    Init_ossl_rand();\n    Init_ossl_ssl();\n    Init_ossl_x509();\n    Init_ossl_ocsp();\n    Init_ossl_engine();\n    Init_ossl_asn1();\n}\n\n#if defined(OSSL_DEBUG)\n/*\n * Check if all symbols are OK with 'make LDSHARED=gcc all'\n */\nint\nmain(int argc, char *argv[], char *env[])\n{\n    return 0;\n}\n#endif /* OSSL_DEBUG */\n\n"
  },
  {
    "path": "ext/openssl/ossl.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_H_)\n#define _OSSL_H_\n\n#include RUBY_EXTCONF_H\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n#if 0\n  mOSSL = rb_define_module(\"OpenSSL\");\n  mX509 = rb_define_module_under(mOSSL, \"X509\");\n#endif\n\n/*\n* OpenSSL has defined RFILE and Ruby has defined RFILE - so undef it!\n*/\n#if defined(RFILE) /*&& !defined(OSSL_DEBUG)*/\n#  undef RFILE\n#endif\n#include <ruby.h>\n#include <rubyio.h>\n\n/*\n * Check the OpenSSL version\n * The only supported are:\n * \tOpenSSL >= 0.9.7\n */\n#include <openssl/opensslv.h>\n\n#ifdef HAVE_ASSERT_H\n#  include <assert.h>\n#else\n#  define assert(condition)\n#endif\n\n#if defined(_WIN32)\n#  define OSSL_NO_CONF_API 1\n#  ifdef USE_WINSOCK2\n#    include <winsock2.h>\n#  else\n#    include <winsock.h>\n#  endif\n#endif\n#include <errno.h>\n#include <openssl/err.h>\n#include <openssl/asn1_mac.h>\n#include <openssl/x509v3.h>\n#include <openssl/ssl.h>\n#include <openssl/pkcs12.h>\n#include <openssl/pkcs7.h>\n#include <openssl/hmac.h>\n#include <openssl/rand.h>\n#include <openssl/conf.h>\n#include <openssl/conf_api.h>\n#undef X509_NAME\n#undef PKCS7_SIGNER_INFO\n#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ST_ENGINE)\n#  define OSSL_ENGINE_ENABLED\n#  include <openssl/engine.h>\n#endif\n#if defined(HAVE_OPENSSL_OCSP_H)\n#  define OSSL_OCSP_ENABLED\n#  include <openssl/ocsp.h>\n#endif\n\n/*\n * Common Module\n */\nextern VALUE mOSSL;\n\n/*\n * Common Error Class\n */\nextern VALUE eOSSLError;\n\n/*\n * CheckTypes\n */\n#define OSSL_Check_Kind(obj, klass) do {\\\n  if (!rb_obj_is_kind_of(obj, klass)) {\\\n    ossl_raise(rb_eTypeError, \"wrong argument (%s)! (Expected kind of %s)\",\\\n               rb_obj_classname(obj), rb_class2name(klass));\\\n  }\\\n} while (0)\n\n#define OSSL_Check_Instance(obj, klass) do {\\\n  if (!rb_obj_is_instance_of(obj, klass)) {\\\n    ossl_raise(rb_eTypeError, \"wrong argument (%s)! (Expected instance of %s)\",\\\n               rb_obj_classname(obj), rb_class2name(klass));\\\n  }\\\n} while (0)\n\n#define OSSL_Check_Same_Class(obj1, obj2) do {\\\n  if (!rb_obj_is_instance_of(obj1, rb_obj_class(obj2))) {\\\n    ossl_raise(rb_eTypeError, \"wrong argument type\");\\\n  }\\\n} while (0)\n\n/*\n * Compatibility\n */\n#if OPENSSL_VERSION_NUMBER >= 0x10000000L\n#define OSSL_MORE_CONST const\n#define STACK _STACK\n#else\n#define OSSL_MORE_CONST\n#endif\n\n/*\n * String to HEXString conversion\n */\nint string2hex(char *, int, char **, int *);\n\n/*\n * Data Conversion\n */\nSTACK_OF(X509) *ossl_x509_ary2sk0(VALUE);\nSTACK_OF(X509) *ossl_x509_ary2sk(VALUE);\nSTACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*);\nVALUE ossl_x509_sk2ary(STACK_OF(X509) *certs);\nVALUE ossl_x509crl_sk2ary(STACK_OF(X509_CRL) *crl);\nVALUE ossl_buf2str(char *buf, int len);\n#define ossl_str_adjust(str, p) \\\ndo{\\\n    int len = RSTRING_LEN(str);\\\n    int newlen = (p) - (unsigned char*)RSTRING_PTR(str);\\\n    assert(newlen <= len);\\\n    rb_str_set_len(str, newlen);\\\n}while(0)\n\n/*\n * our default PEM callback\n */\nint ossl_pem_passwd_cb(char *, int, int, void *);\n\n/*\n * ERRor messages\n */\n#define OSSL_ErrMsg() ERR_reason_error_string(ERR_get_error())\nNORETURN(void ossl_raise(VALUE, const char *, ...));\n\n/*\n * Verify callback\n */\nextern int ossl_verify_cb_idx;\n\nstruct ossl_verify_cb_args {\n    VALUE proc;\n    VALUE preverify_ok;\n    VALUE store_ctx;\n};\n\nVALUE ossl_call_verify_cb_proc(struct ossl_verify_cb_args *);\nint ossl_verify_cb(int, X509_STORE_CTX *);\n\n/*\n * String to DER String\n */\nextern ID ossl_s_to_der;\nVALUE ossl_to_der(VALUE);\nVALUE ossl_to_der_if_possible(VALUE);\n\n/*\n * Debug\n */\nextern VALUE dOSSL;\n\n#if defined(HAVE_VA_ARGS_MACRO)\n#define OSSL_Debug(fmt, ...) do { \\\n  if (dOSSL == Qtrue) { \\\n    fprintf(stderr, \"OSSL_DEBUG: \"); \\\n    fprintf(stderr, fmt, ##__VA_ARGS__); \\\n    fprintf(stderr, \" [%s:%d]\\n\", __FILE__, __LINE__); \\\n  } \\\n} while (0)\n\n#define OSSL_Warning(fmt, ...) do { \\\n  OSSL_Debug(fmt, ##__VA_ARGS__); \\\n  rb_warning(fmt, ##__VA_ARGS__); \\\n} while (0)\n\n#define OSSL_Warn(fmt, ...) do { \\\n  OSSL_Debug(fmt, ##__VA_ARGS__); \\\n  rb_warn(fmt, ##__VA_ARGS__); \\\n} while (0)\n#else\nvoid ossl_debug(const char *, ...);\n#define OSSL_Debug ossl_debug\n#define OSSL_Warning rb_warning\n#define OSSL_Warn rb_warn\n#endif\n\n/*\n * Include all parts\n */\n#include \"openssl_missing.h\"\n#include \"ruby_missing.h\"\n#include \"ossl_asn1.h\"\n#include \"ossl_bio.h\"\n#include \"ossl_bn.h\"\n#include \"ossl_cipher.h\"\n#include \"ossl_config.h\"\n#include \"ossl_digest.h\"\n#include \"ossl_hmac.h\"\n#include \"ossl_ns_spki.h\"\n#include \"ossl_ocsp.h\"\n#include \"ossl_pkcs12.h\"\n#include \"ossl_pkcs7.h\"\n#include \"ossl_pkcs5.h\"\n#include \"ossl_pkey.h\"\n#include \"ossl_rand.h\"\n#include \"ossl_ssl.h\"\n#include \"ossl_version.h\"\n#include \"ossl_x509.h\"\n#include \"ossl_engine.h\"\n\nvoid Init_openssl(void);\n\n#if defined(__cplusplus)\n}\n#endif\n\n#endif /* _OSSL_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_asn1.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#if defined(HAVE_SYS_TIME_H)\n#  include <sys/time.h>\n#elif !defined(NT) && !defined(_WIN32)\nstruct timeval {\n    long tv_sec;\t/* seconds */\n    long tv_usec;\t/* and microseconds */\n};\n#endif\n\n/*\n * DATE conversion\n */\nVALUE\nasn1time_to_time(ASN1_TIME *time)\n{\n    struct tm tm;\n    VALUE argv[6];\n    \n    if (!time || !time->data) return Qnil;\n    memset(&tm, 0, sizeof(struct tm));\n\t\n    switch (time->type) {\n    case V_ASN1_UTCTIME:\n\tif (sscanf(time->data, \"%2d%2d%2d%2d%2d%2dZ\", &tm.tm_year, &tm.tm_mon,\n    \t\t&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {\n\t    ossl_raise(rb_eTypeError, \"bad UTCTIME format\");\n\t} \n\tif (tm.tm_year < 69) {\n\t    tm.tm_year += 2000;\n\t} else {\n\t    tm.tm_year += 1900;\n\t}\n\tbreak;\n    case V_ASN1_GENERALIZEDTIME:\n\tif (sscanf(time->data, \"%4d%2d%2d%2d%2d%2dZ\", &tm.tm_year, &tm.tm_mon,\n    \t\t&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {\n\t    ossl_raise(rb_eTypeError, \"bad GENERALIZEDTIME format\" );\n\t} \n\tbreak;\n    default:\n\trb_warning(\"unknown time format\");\n        return Qnil;\n    }\n    argv[0] = INT2NUM(tm.tm_year);\n    argv[1] = INT2NUM(tm.tm_mon);\n    argv[2] = INT2NUM(tm.tm_mday);\n    argv[3] = INT2NUM(tm.tm_hour);\n    argv[4] = INT2NUM(tm.tm_min);\n    argv[5] = INT2NUM(tm.tm_sec);\n\n    return rb_funcall2(rb_cTime, rb_intern(\"utc\"), 6, argv);\n}\n\n/*\n * This function is not exported in Ruby's *.h\n */\nextern struct timeval rb_time_timeval(VALUE);\n\ntime_t\ntime_to_time_t(VALUE time)\n{\n    return (time_t)NUM2LONG(rb_Integer(time));\n}\n\n/*\n * STRING conversion\n */\nVALUE\nasn1str_to_str(ASN1_STRING *str)\n{\n    return rb_str_new(str->data, str->length);\n}\n\n/*\n * ASN1_INTEGER conversions\n * TODO: Make a decision what's the right way to do this.\n */\n#define DO_IT_VIA_RUBY 0\nVALUE\nasn1integer_to_num(ASN1_INTEGER *ai)\n{\n    BIGNUM *bn;\n#if DO_IT_VIA_RUBY\n    char *txt;\n#endif\n    VALUE num;\n\n    if (!ai) {\n\tossl_raise(rb_eTypeError, \"ASN1_INTEGER is NULL!\");\n    }\n    if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) {\n\tossl_raise(eOSSLError, NULL);\n    }\n#if DO_IT_VIA_RUBY\n    if (!(txt = BN_bn2dec(bn))) {\n\tBN_free(bn);\n\tossl_raise(eOSSLError, NULL);\n    }\n    num = rb_cstr_to_inum(txt, 10, Qtrue);\n    OPENSSL_free(txt);\n#else\n    num = ossl_bn_new(bn);\n#endif\n    BN_free(bn);\n\n    return num;\n}\n\n#if DO_IT_VIA_RUBY\nASN1_INTEGER *\nnum_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)\n{\n    BIGNUM *bn = NULL;\n\n    if (RTEST(rb_obj_is_kind_of(obj, cBN))) {\n\tbn = GetBNPtr(obj);\n    } else {\n\tobj = rb_String(obj);\n\tif (!BN_dec2bn(&bn, StringValuePtr(obj))) {\n\t    ossl_raise(eOSSLError, NULL);\n\t}\n    }\n    if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) {\n\tBN_free(bn);\n\tossl_raise(eOSSLError, NULL);\n    }\n    BN_free(bn);\n    return ai;\n}\n#else\nASN1_INTEGER *\nnum_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)\n{\n    BIGNUM *bn = GetBNPtr(obj);\n    \n    if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) {\n\tossl_raise(eOSSLError, NULL);\n    }\n    return ai;\n}\n#endif\n\n/********/\n/*\n * ASN1 module\n */\n#define ossl_asn1_get_value(o)       rb_attr_get((o),rb_intern(\"@value\"))\n#define ossl_asn1_get_tag(o)         rb_attr_get((o),rb_intern(\"@tag\"))\n#define ossl_asn1_get_tagging(o)     rb_attr_get((o),rb_intern(\"@tagging\"))\n#define ossl_asn1_get_tag_class(o)   rb_attr_get((o),rb_intern(\"@tag_class\"))\n\n#define ossl_asn1_set_value(o,v)     rb_iv_set((o),\"@value\",(v))\n#define ossl_asn1_set_tag(o,v)       rb_iv_set((o),\"@tag\",(v))\n#define ossl_asn1_set_tagging(o,v)   rb_iv_set((o),\"@tagging\",(v))\n#define ossl_asn1_set_tag_class(o,v) rb_iv_set((o),\"@tag_class\",(v))\n\nVALUE mASN1;\nVALUE eASN1Error;\n\nVALUE cASN1Data;\nVALUE cASN1Primitive;\nVALUE cASN1Constructive;\n\nVALUE cASN1Boolean;                           /* BOOLEAN           */\nVALUE cASN1Integer, cASN1Enumerated;          /* INTEGER           */\nVALUE cASN1BitString;                         /* BIT STRING        */\nVALUE cASN1OctetString, cASN1UTF8String;      /* STRINGs           */\nVALUE cASN1NumericString, cASN1PrintableString;\nVALUE cASN1T61String, cASN1VideotexString;\nVALUE cASN1IA5String, cASN1GraphicString;\nVALUE cASN1ISO64String, cASN1GeneralString;\nVALUE cASN1UniversalString, cASN1BMPString;\nVALUE cASN1Null;                              /* NULL              */\nVALUE cASN1ObjectId;                          /* OBJECT IDENTIFIER */\nVALUE cASN1UTCTime, cASN1GeneralizedTime;     /* TIME              */\nVALUE cASN1Sequence, cASN1Set;                /* CONSTRUCTIVE      */\n\nstatic ID sIMPLICIT, sEXPLICIT;\nstatic ID sUNIVERSAL, sAPPLICATION, sCONTEXT_SPECIFIC, sPRIVATE;\n\n/*\n * Ruby to ASN1 converters\n */\nstatic ASN1_BOOLEAN\nobj_to_asn1bool(VALUE obj)\n{\n     return RTEST(obj) ? 0xff : 0x100;\n}\n\nstatic ASN1_INTEGER*\nobj_to_asn1int(VALUE obj)\n{\n    return num_to_asn1integer(obj, NULL);\n}\n\nstatic ASN1_BIT_STRING*\nobj_to_asn1bstr(VALUE obj, long unused_bits)\n{\n    ASN1_BIT_STRING *bstr;\n\n    if(unused_bits < 0) unused_bits = 0;\n    StringValue(obj);\n    if(!(bstr = ASN1_BIT_STRING_new()))\n\tossl_raise(eASN1Error, NULL);\n    ASN1_BIT_STRING_set(bstr, RSTRING_PTR(obj), RSTRING_LEN(obj));\n    bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */\n    bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);\n\n    return bstr;\n}\n\nstatic ASN1_STRING*\nobj_to_asn1str(VALUE obj)\n{\n    ASN1_STRING *str;\n\n    StringValue(obj);\n    if(!(str = ASN1_STRING_new()))\n\tossl_raise(eASN1Error, NULL);\n    ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LEN(obj));\n\n    return str;\n}\n\nstatic ASN1_NULL*\nobj_to_asn1null(VALUE obj)\n{\n    ASN1_NULL *null;\n\n    if(!NIL_P(obj))\n\tossl_raise(eASN1Error, \"nil expected\");\n    if(!(null = ASN1_NULL_new()))\n\tossl_raise(eASN1Error, NULL);\n\n    return null;\n}\n\nstatic ASN1_OBJECT*\nobj_to_asn1obj(VALUE obj)\n{\n    ASN1_OBJECT *a1obj;\n\n    StringValue(obj);\n    a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 0);\n    if(!a1obj) a1obj = OBJ_txt2obj(RSTRING_PTR(obj), 1);\n    if(!a1obj) ossl_raise(eASN1Error, \"invalid OBJECT ID\");\n\n    return a1obj;\n}\n\nstatic ASN1_UTCTIME*\nobj_to_asn1utime(VALUE time)\n{\n    time_t sec;\n    ASN1_UTCTIME *t;\n\n    sec = time_to_time_t(time);\n    if(!(t = ASN1_UTCTIME_set(NULL, sec)))\n        ossl_raise(eASN1Error, NULL);\n\n    return t;\n}\n\nstatic ASN1_GENERALIZEDTIME*\nobj_to_asn1gtime(VALUE time)\n{\n    time_t sec;\n    ASN1_GENERALIZEDTIME *t;\n\n    sec = time_to_time_t(time);\n    if(!(t =ASN1_GENERALIZEDTIME_set(NULL, sec)))\n        ossl_raise(eASN1Error, NULL);\n\n    return t;\n}\n\nstatic ASN1_STRING*\nobj_to_asn1derstr(VALUE obj)\n{\n    ASN1_STRING *a1str;\n    VALUE str;\n\n    str = ossl_to_der(obj);\n    if(!(a1str = ASN1_STRING_new()))\n\tossl_raise(eASN1Error, NULL);\n    ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LEN(str));\n\n    return a1str;\n}\n\n/*\n * DER to Ruby converters\n */\nstatic VALUE\ndecode_bool(OSSL_MORE_CONST unsigned char* der, int length)\n{\n    int bool;\n    OSSL_MORE_CONST unsigned char *p;\n\n    p = der;\n    if((bool = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0)\n\tossl_raise(eASN1Error, NULL);\n\n    return bool ? Qtrue : Qfalse;\n}\n\nstatic VALUE\ndecode_int(OSSL_MORE_CONST unsigned char* der, int length)\n{\n    ASN1_INTEGER *ai;\n    OSSL_MORE_CONST unsigned char *p;\n    VALUE ret; \n    int status = 0;\n\n    p = der;\n    if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length)))\n\tossl_raise(eASN1Error, NULL);\n    ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num,\n\t\t     (VALUE)ai, &status);\n    ASN1_INTEGER_free(ai);\n    if(status) rb_jump_tag(status);\n\n    return ret;\n}\n\nstatic VALUE\ndecode_bstr(OSSL_MORE_CONST unsigned char* der, int length, long *unused_bits)\n{\n    ASN1_BIT_STRING *bstr;\n    OSSL_MORE_CONST unsigned char *p;\n    unsigned char *buf;\n    long len;\n    VALUE ret;\n\n    p = der;\n    if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))\n\tossl_raise(eASN1Error, NULL);\n    len = bstr->length;\n    if(!(buf = OPENSSL_malloc(len))){\n\tASN1_BIT_STRING_free(bstr);\n\tossl_raise(eASN1Error, NULL);\n    }\n    *unused_bits = 0;\n    if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)\n\t*unused_bits = bstr->flags & 0x07;\n    memcpy(buf, bstr->data, len);\n    ASN1_BIT_STRING_free(bstr);\n    ret = ossl_buf2str(buf, len);\n\n    return ret;\n}\n\nstatic VALUE\ndecode_enum(OSSL_MORE_CONST unsigned char* der, int length)\n{\n    ASN1_ENUMERATED *ai;\n    OSSL_MORE_CONST unsigned char *p;\n    VALUE ret; \n    int status = 0;\n\n    p = der;\n    if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length)))\n\tossl_raise(eASN1Error, NULL);\n    ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num,\n\t\t     (VALUE)ai, &status);\n    ASN1_ENUMERATED_free(ai);\n    if(status) rb_jump_tag(status);\n\n    return ret;\n}\n\nstatic VALUE\ndecode_null(OSSL_MORE_CONST unsigned char* der, int length)\n{\n    ASN1_NULL *null;\n    OSSL_MORE_CONST unsigned char *p;\n\n    p = der;\n    if(!(null = d2i_ASN1_NULL(NULL, &p, length)))\n\tossl_raise(eASN1Error, NULL);\n    ASN1_NULL_free(null);\n\n    return Qnil;\n}\n\nstatic VALUE\ndecode_obj(OSSL_MORE_CONST unsigned char* der, int length)\n{\n    ASN1_OBJECT *obj;\n    OSSL_MORE_CONST unsigned char *p;\n    VALUE ret;\n    int nid;\n    BIO *bio;\n\n    p = der;\n    if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length)))\n\tossl_raise(eASN1Error, NULL);\n    if((nid = OBJ_obj2nid(obj)) != NID_undef){\n\tASN1_OBJECT_free(obj);\n\tret = rb_str_new2(OBJ_nid2sn(nid));\n    }\n    else{\n\tif(!(bio = BIO_new(BIO_s_mem()))){\n\t    ASN1_OBJECT_free(obj);\n\t    ossl_raise(eASN1Error, NULL);\n\t}\n\ti2a_ASN1_OBJECT(bio, obj);\n\tASN1_OBJECT_free(obj);\n\tret = ossl_membio2str(bio);\n    }\n\n    return ret;\n}\n\nstatic VALUE\ndecode_time(OSSL_MORE_CONST unsigned char* der, int length)\n{\n    ASN1_TIME *time;\n    OSSL_MORE_CONST unsigned char *p;\n    VALUE ret;\n    int status = 0;\n\n    p = der;\n    if(!(time = d2i_ASN1_TIME(NULL, &p, length)))\n\tossl_raise(eASN1Error, NULL);\n    ret = rb_protect((VALUE(*)_((VALUE)))asn1time_to_time,\n\t\t     (VALUE)time, &status);\n    ASN1_TIME_free(time);\n    if(status) rb_jump_tag(status);\n\n    return ret;\n}\n\n/********/\n\ntypedef struct {\n    const char *name;\n    VALUE *klass;\n} ossl_asn1_info_t;\n\nstatic ossl_asn1_info_t ossl_asn1_info[] = {\n    { \"EOC\",               NULL,                  },  /*  0 */\n    { \"BOOLEAN\",           &cASN1Boolean,         },  /*  1 */\n    { \"INTEGER\",           &cASN1Integer,         },  /*  2 */\n    { \"BIT_STRING\",        &cASN1BitString,       },  /*  3 */\n    { \"OCTET_STRING\",      &cASN1OctetString,     },  /*  4 */\n    { \"NULL\",              &cASN1Null,            },  /*  5 */\n    { \"OBJECT\",            &cASN1ObjectId,        },  /*  6 */\n    { \"OBJECT_DESCRIPTOR\", NULL,                  },  /*  7 */\n    { \"EXTERNAL\",          NULL,                  },  /*  8 */\n    { \"REAL\",              NULL,                  },  /*  9 */\n    { \"ENUMERATED\",        &cASN1Enumerated,      },  /* 10 */\n    { \"EMBEDDED_PDV\",      NULL,                  },  /* 11 */\n    { \"UTF8STRING\",        &cASN1UTF8String,      },  /* 12 */\n    { \"RELATIVE_OID\",      NULL,                  },  /* 13 */\n    { \"[UNIVERSAL 14]\",    NULL,                  },  /* 14 */\n    { \"[UNIVERSAL 15]\",    NULL,                  },  /* 15 */\n    { \"SEQUENCE\",          &cASN1Sequence,        },  /* 16 */\n    { \"SET\",               &cASN1Set,             },  /* 17 */\n    { \"NUMERICSTRING\",     &cASN1NumericString,   },  /* 18 */\n    { \"PRINTABLESTRING\",   &cASN1PrintableString, },  /* 19 */\n    { \"T61STRING\",         &cASN1T61String,       },  /* 20 */\n    { \"VIDEOTEXSTRING\",    &cASN1VideotexString,  },  /* 21 */\n    { \"IA5STRING\",         &cASN1IA5String,       },  /* 22 */\n    { \"UTCTIME\",           &cASN1UTCTime,         },  /* 23 */\n    { \"GENERALIZEDTIME\",   &cASN1GeneralizedTime, },  /* 24 */\n    { \"GRAPHICSTRING\",     &cASN1GraphicString,   },  /* 25 */\n    { \"ISO64STRING\",       &cASN1ISO64String,     },  /* 26 */\n    { \"GENERALSTRING\",     &cASN1GeneralString,   },  /* 27 */\n    { \"UNIVERSALSTRING\",   &cASN1UniversalString, },  /* 28 */\n    { \"CHARACTER_STRING\",  NULL,                  },  /* 29 */\n    { \"BMPSTRING\",         &cASN1BMPString,       },  /* 30 */\n};\n\nint ossl_asn1_info_size = (sizeof(ossl_asn1_info)/sizeof(ossl_asn1_info[0]));\n\nstatic int ossl_asn1_default_tag(VALUE obj);\n\nASN1_TYPE*\nossl_asn1_get_asn1type(VALUE obj)\n{\n    ASN1_TYPE *ret;\n    VALUE value, rflag;\n    void *ptr;\n    void (*free_func)();\n    long tag, flag;\n\n    tag = ossl_asn1_default_tag(obj);\n    value = ossl_asn1_get_value(obj);\n    switch(tag){\n    case V_ASN1_BOOLEAN:\n\tptr = (void*)obj_to_asn1bool(value);\n\tfree_func = NULL;\n\tbreak;\n    case V_ASN1_INTEGER:         /* FALLTHROUGH */\n    case V_ASN1_ENUMERATED:\n\tptr = obj_to_asn1int(value);\n\tfree_func = ASN1_INTEGER_free;\n\tbreak;\n    case V_ASN1_BIT_STRING:\n        rflag = rb_attr_get(obj, rb_intern(\"@unused_bits\"));\n        flag = NIL_P(rflag) ? -1 : NUM2INT(rflag);\n\tptr = obj_to_asn1bstr(value, flag);\n\tfree_func = ASN1_BIT_STRING_free;\n\tbreak;\n    case V_ASN1_NULL:\n\tptr = obj_to_asn1null(value);\n\tfree_func = ASN1_NULL_free;\n\tbreak;\n    case V_ASN1_OCTET_STRING:    /* FALLTHROUGH */\n    case V_ASN1_UTF8STRING:      /* FALLTHROUGH */\n    case V_ASN1_NUMERICSTRING:   /* FALLTHROUGH */\n    case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */\n    case V_ASN1_T61STRING:       /* FALLTHROUGH */\n    case V_ASN1_VIDEOTEXSTRING:  /* FALLTHROUGH */\n    case V_ASN1_IA5STRING:       /* FALLTHROUGH */\n    case V_ASN1_GRAPHICSTRING:   /* FALLTHROUGH */\n    case V_ASN1_ISO64STRING:     /* FALLTHROUGH */\n    case V_ASN1_GENERALSTRING:   /* FALLTHROUGH */\n    case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */\n    case V_ASN1_BMPSTRING:   \n\tptr = obj_to_asn1str(value);\n\tfree_func = ASN1_STRING_free;\n\tbreak;\n    case V_ASN1_OBJECT:\n\tptr = obj_to_asn1obj(value);\n\tfree_func = ASN1_OBJECT_free;\n\tbreak;\n    case V_ASN1_UTCTIME:\n\tptr = obj_to_asn1utime(value);\n\tfree_func = ASN1_TIME_free;\n\tbreak;\n    case V_ASN1_GENERALIZEDTIME:\n\tptr = obj_to_asn1gtime(value);\n\tfree_func = ASN1_TIME_free;\n\tbreak;\n    case V_ASN1_SET:             /* FALLTHROUGH */\n    case V_ASN1_SEQUENCE:\n\tptr = obj_to_asn1derstr(obj);\n\tfree_func = ASN1_STRING_free;\n\tbreak;\n    default:\n\tossl_raise(eASN1Error, \"unsupported ASN.1 type\");\n    }\n    if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){\n\tif(free_func) free_func(ptr);\n\tossl_raise(eASN1Error, \"ASN1_TYPE alloc failure\");\n    }\n    memset(ret, 0, sizeof(ASN1_TYPE));\n    ASN1_TYPE_set(ret, tag, ptr);\n\n    return ret;\n}\n\nstatic int\nossl_asn1_default_tag(VALUE obj)\n{\n    int i;\n\n    for(i = 0; i < ossl_asn1_info_size; i++){\n\tif(ossl_asn1_info[i].klass &&\n\t   rb_obj_is_kind_of(obj, *ossl_asn1_info[i].klass)){\n\t    return i;\n\t}\n    }\n    ossl_raise(eASN1Error, \"universal tag for %s not found\",\n\t       rb_class2name(CLASS_OF(obj)));\n\n    return -1; /* dummy */\n}\n\nstatic int\nossl_asn1_tag(VALUE obj)\n{\n    VALUE tag;\n\n    tag = ossl_asn1_get_tag(obj);\n    if(NIL_P(tag))\n\tossl_raise(eASN1Error, \"tag number not specified\");\n\n    return NUM2INT(tag);\n}\n\nstatic int\nossl_asn1_is_explicit(VALUE obj)\n{\n    VALUE s;\n    int ret = -1;\n\n    s = ossl_asn1_get_tagging(obj);\n    if(NIL_P(s)) return 0;\n    else if(SYMBOL_P(s)){\n\tif (SYM2ID(s) == sIMPLICIT)\n\t    ret = 0;\n\telse if (SYM2ID(s) == sEXPLICIT)\n\t    ret = 1;\n    }\n    if(ret < 0){\n\tossl_raise(eASN1Error, \"invalid tag default\");\n    }\n\n    return ret;\n}\n\nstatic int\nossl_asn1_tag_class(VALUE obj)\n{\n    VALUE s;\n    int ret = -1;\n\n    s = ossl_asn1_get_tag_class(obj);\n    if(NIL_P(s)) ret = V_ASN1_UNIVERSAL;\n    else if(SYMBOL_P(s)){\n\tif (SYM2ID(s) == sUNIVERSAL)\n\t    ret = V_ASN1_UNIVERSAL;\n\telse if (SYM2ID(s) == sAPPLICATION)\n\t    ret = V_ASN1_APPLICATION;\n\telse if (SYM2ID(s) == sCONTEXT_SPECIFIC)\n\t    ret = V_ASN1_CONTEXT_SPECIFIC;\n\telse if (SYM2ID(s) == sPRIVATE)\n\t    ret = V_ASN1_PRIVATE;\n    }\n    if(ret < 0){\n\tossl_raise(eASN1Error, \"invalid tag class\");\n    }\n\n    return ret;\n}\n\nstatic VALUE\nossl_asn1_class2sym(int tc)\n{\n    if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)\n\treturn ID2SYM(sPRIVATE);\n    else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)\n\treturn ID2SYM(sCONTEXT_SPECIFIC);\n    else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)\n\treturn ID2SYM(sAPPLICATION);\n    else\n\treturn ID2SYM(sUNIVERSAL);\n}\n\nstatic VALUE\nossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)\n{\n    if(!SYMBOL_P(tag_class))\n\tossl_raise(eASN1Error, \"invalid tag class\");\n    if((SYM2ID(tag_class) == sUNIVERSAL) && NUM2INT(tag) > 31)\n\tossl_raise(eASN1Error, \"tag number for Universal too large\");\n    ossl_asn1_set_tag(self, tag);\n    ossl_asn1_set_value(self, value);\n    ossl_asn1_set_tag_class(self, tag_class);\n\n    return self;\n}\n\nstatic VALUE \njoin_der_i(VALUE i, VALUE str) \n{\n    i = ossl_to_der_if_possible(i);\n    StringValue(i);\n    rb_str_append(str, i);\n    return Qnil;\n}\n\nstatic VALUE\njoin_der(VALUE enumerable)\n{\n    VALUE str = rb_str_new(0, 0);\n    rb_block_call(enumerable, rb_intern(\"each\"), 0, 0, join_der_i, str);\n    return str;\n}\n\nstatic VALUE\nossl_asn1data_to_der(VALUE self)\n{\n    VALUE value, der;\n    int tag, tag_class, is_cons = 0;\n    long length;\n    unsigned char *p;\n\n    value = ossl_asn1_get_value(self);\n    if(rb_obj_is_kind_of(value, rb_cArray)){\n\tis_cons = 1;\n\tvalue = join_der(value);\n    }\n    StringValue(value);\n\n    tag = ossl_asn1_tag(self);\n    tag_class = ossl_asn1_tag_class(self);\n    if((length = ASN1_object_size(1, RSTRING_LEN(value), tag)) <= 0)\n\tossl_raise(eASN1Error, NULL);\n    der = rb_str_new(0, length);\n    p = RSTRING_PTR(der);\n    ASN1_put_object(&p, is_cons, RSTRING_LEN(value), tag, tag_class);\n    memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));\n    p += RSTRING_LEN(value);\n    ossl_str_adjust(der, p);\n\n    return der;\n}\n\nstatic VALUE\nossl_asn1_decode0(OSSL_MORE_CONST unsigned char **pp, long length,\n\t\t  long *offset, long depth, int once, int yield)\n{\n    OSSL_MORE_CONST unsigned char *start, *p;\n    long len, off = *offset;\n    int hlen, tag, tc, j;\n    VALUE ary, asn1data, value, tag_class;\n\n    ary = rb_ary_new();\n    p = *pp;\n    while(length > 0){\n\tstart = p;\n\tj = ASN1_get_object(&p, &len, &tag, &tc, length);\n\tif(j & 0x80) ossl_raise(eASN1Error, NULL);\n\thlen = p - start;\n\tif(yield){\n\t    VALUE arg = rb_ary_new();\n\t    rb_ary_push(arg, LONG2NUM(depth));\n\t    rb_ary_push(arg, LONG2NUM(off));\n\t    rb_ary_push(arg, LONG2NUM(hlen));\n\t    rb_ary_push(arg, LONG2NUM(len));\n\t    rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);\n\t    rb_ary_push(arg, ossl_asn1_class2sym(tc));\n\t    rb_ary_push(arg, INT2NUM(tag));\n\t    rb_yield(arg);\n\t}\n\tlength -= hlen;\n\toff += hlen; \n\tif(len > length) ossl_raise(eASN1Error, \"value is too short\");\n\tif((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)\n\t    tag_class = sPRIVATE;\n\telse if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)\n\t    tag_class = sCONTEXT_SPECIFIC;\n\telse if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)\n\t    tag_class = sAPPLICATION;\n\telse\n\t    tag_class = sUNIVERSAL;\n\tif(j & V_ASN1_CONSTRUCTED){\n\t    /* TODO: if j == 0x21 it is indefinite length object. */\n\t    if((j == 0x21) && (len == 0)){\n\t\tlong lastoff = off;\n\t\tvalue = ossl_asn1_decode0(&p, length, &off, depth+1, 0, yield);\n\t\tlen = off - lastoff;\n\t    }\n\t    else value = ossl_asn1_decode0(&p, len, &off, depth+1, 0, yield);\n\t}\n\telse{\n\t    value = rb_str_new(p, len);\n\t    p += len;\n\t    off += len;\n\t}\n\tif(tag_class == sUNIVERSAL &&\n\t   tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass){\n\t    VALUE klass = *ossl_asn1_info[tag].klass;\n\t    long flag = 0;\n\t    if(!rb_obj_is_kind_of(value, rb_cArray)){\n\t\tswitch(tag){\n\t\tcase V_ASN1_BOOLEAN:\n\t\t    value = decode_bool(start, hlen+len);\n\t\t    break;\n\t\tcase V_ASN1_INTEGER:\n\t\t    value = decode_int(start, hlen+len);\n\t\t    break;\n\t\tcase V_ASN1_BIT_STRING:\n\t\t    value = decode_bstr(start, hlen+len, &flag);\n\t\t    break;\n\t\tcase V_ASN1_NULL:\n\t\t    value = decode_null(start, hlen+len);\n\t\t    break;\n\t\tcase V_ASN1_ENUMERATED:\n\t\t    value = decode_enum(start, hlen+len);\n\t\t    break;\n\t\tcase V_ASN1_OBJECT:\n\t\t    value = decode_obj(start, hlen+len);\n\t\t    break;\n\t\tcase V_ASN1_UTCTIME:           /* FALLTHROUGH */\n\t\tcase V_ASN1_GENERALIZEDTIME:\n\t\t    value = decode_time(start, hlen+len);\n\t\t    break;\n\t\tdefault:\n\t\t    /* use original value */\n\t\t    break;\n\t\t}\n\t    }\n\t    asn1data = rb_funcall(klass, rb_intern(\"new\"), 1, value);\n\t    if(tag == V_ASN1_BIT_STRING){\n\t\trb_iv_set(asn1data, \"@unused_bits\", LONG2NUM(flag));\n\t    }\n\t}\n\telse{\n\t    asn1data = rb_funcall(cASN1Data, rb_intern(\"new\"), 3,\n\t\t\t\t  value, INT2NUM(tag), ID2SYM(tag_class));\n\t}\n\trb_ary_push(ary, asn1data);\n\tlength -= len;\n        if(once) break;\n    }\n    *pp = p;\n    *offset = off;\n\n    return ary;\n}\n\nstatic VALUE\nossl_asn1_traverse(VALUE self, VALUE obj)\n{\n    OSSL_MORE_CONST unsigned char *p;\n    long offset = 0;\n    volatile VALUE tmp;\n\n    obj = ossl_to_der_if_possible(obj);\n    tmp = rb_str_new4(StringValue(obj));\n    p = RSTRING_PTR(tmp);\n    ossl_asn1_decode0(&p, RSTRING_LEN(tmp), &offset, 0, 0, 1);\n\n    return Qnil;\n}\n\nstatic VALUE\nossl_asn1_decode(VALUE self, VALUE obj)\n{\n    VALUE ret, ary;\n    OSSL_MORE_CONST unsigned char *p;\n    long offset = 0;\n    volatile VALUE tmp;\n\n    obj = ossl_to_der_if_possible(obj);\n    tmp = rb_str_new4(StringValue(obj));\n    p = RSTRING_PTR(tmp);\n    ary = ossl_asn1_decode0(&p, RSTRING_LEN(tmp), &offset, 0, 1, 0);\n    ret = rb_ary_entry(ary, 0);\n\n    return ret;\n}\n\nstatic VALUE\nossl_asn1_decode_all(VALUE self, VALUE obj)\n{\n    VALUE ret;\n    OSSL_MORE_CONST unsigned char *p;\n    long offset = 0;\n    volatile VALUE tmp;\n\n    obj = ossl_to_der_if_possible(obj);\n    tmp = rb_str_new4(StringValue(obj));\n    p = RSTRING_PTR(tmp);\n    ret = ossl_asn1_decode0(&p, RSTRING_LEN(tmp), &offset, 0, 0, 0);\n\n    return ret;\n}\n\nstatic VALUE\nossl_asn1_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE value, tag, tagging, tag_class;\n\n    rb_scan_args(argc, argv, \"13\", &value, &tag, &tagging, &tag_class);\n    if(argc > 1){\n\tif(NIL_P(tag))\n\t    ossl_raise(eASN1Error, \"must specify tag number\");\n        if(NIL_P(tagging))\n\t    tagging = ID2SYM(sEXPLICIT);\n\tif(!SYMBOL_P(tagging))\n\t    ossl_raise(eASN1Error, \"invalid tag default\");\n\tif(NIL_P(tag_class))\n\t    tag_class = ID2SYM(sCONTEXT_SPECIFIC);\n\tif(!SYMBOL_P(tag_class))\n\t    ossl_raise(eASN1Error, \"invalid tag class\");\n\tif(SYM2ID(tagging) == sIMPLICIT && NUM2INT(tag) > 31)\n\t    ossl_raise(eASN1Error, \"tag number for Universal too large\");\n    }\n    else{\n\ttag = INT2NUM(ossl_asn1_default_tag(self));\n        tagging = Qnil;\n\ttag_class = ID2SYM(sUNIVERSAL);\n    }\n    ossl_asn1_set_tag(self, tag);\n    ossl_asn1_set_value(self, value);\n    ossl_asn1_set_tagging(self, tagging);\n    ossl_asn1_set_tag_class(self, tag_class);\n\n    return self;\n}\n\nstatic int\nossl_i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **pp)\n{\n#if OPENSSL_VERSION_NUMBER < 0x00907000L\n    if(!a) return 0;\n    if(a->type == V_ASN1_BOOLEAN)\n        return i2d_ASN1_BOOLEAN(a->value.boolean, pp);\n#endif\n    return i2d_ASN1_TYPE(a, pp);\n}\n\nstatic void\nossl_ASN1_TYPE_free(ASN1_TYPE *a)\n{\n#if OPENSSL_VERSION_NUMBER < 0x00907000L\n    if(!a) return;\n    if(a->type == V_ASN1_BOOLEAN){\n        OPENSSL_free(a);\n        return;\n    }\n#endif\n    ASN1_TYPE_free(a);\n}\n\nstatic VALUE\nossl_asn1prim_to_der(VALUE self)\n{\n    ASN1_TYPE *asn1;\n    int tn, tc, explicit;\n    long length, reallen;\n    unsigned char *buf, *p;\n    VALUE str;\n\n    tn = NUM2INT(ossl_asn1_get_tag(self));\n    tc = ossl_asn1_tag_class(self);\n    explicit = ossl_asn1_is_explicit(self);\n    asn1 = ossl_asn1_get_asn1type(self);\n\n    length = ASN1_object_size(1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn);\n    if(!(buf = OPENSSL_malloc(length))){\n\tossl_ASN1_TYPE_free(asn1);\n\tossl_raise(eASN1Error, \"cannot alloc buffer\");\n    }\n    p = buf;\n    if(tc == V_ASN1_UNIVERSAL) ossl_i2d_ASN1_TYPE(asn1, &p);\n    else{\n\tif(explicit){\n\t    ASN1_put_object(&p, 1, ossl_i2d_ASN1_TYPE(asn1, NULL), tn, tc);\n\t    ossl_i2d_ASN1_TYPE(asn1, &p);\n\t}\n\telse{\n\t    ossl_i2d_ASN1_TYPE(asn1, &p);\n\t    *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);\n\t}\n    }\n    ossl_ASN1_TYPE_free(asn1);\n    reallen = p - buf;\n    assert(reallen <= length);\n    str = ossl_buf2str(buf, reallen); /* buf will be free in ossl_buf2str */\n\n    return str;\n}\n\nstatic VALUE\nossl_asn1cons_to_der(VALUE self)\n{\n    int tag, tn, tc, explicit;\n    long seq_len, length;\n    unsigned char *p;\n    VALUE value, str;\n\n    tag = ossl_asn1_default_tag(self);\n    tn = NUM2INT(ossl_asn1_get_tag(self));\n    tc = ossl_asn1_tag_class(self);\n    explicit = ossl_asn1_is_explicit(self);\n    value = join_der(ossl_asn1_get_value(self));\n\n    seq_len = ASN1_object_size(1, RSTRING_LEN(value), tag);\n    length = ASN1_object_size(1, seq_len, tn);\n    str = rb_str_new(0, length);\n    p = RSTRING_PTR(str);\n    if(tc == V_ASN1_UNIVERSAL)\n\tASN1_put_object(&p, 1, RSTRING_LEN(value), tn, tc);\n    else{\n\tif(explicit){\n\t    ASN1_put_object(&p, 1, seq_len, tn, tc);\n\t    ASN1_put_object(&p, 1, RSTRING_LEN(value), tag, V_ASN1_UNIVERSAL);\n\t}\n\telse ASN1_put_object(&p, 1, RSTRING_LEN(value), tn, tc);\n    }\n    memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));\n    p += RSTRING_LEN(value);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\nstatic VALUE\nossl_asn1cons_each(VALUE self)\n{\n    rb_ary_each(ossl_asn1_get_value(self));\n    return self;\n}\n\nstatic VALUE\nossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)\n{\n    StringValue(oid);\n    StringValue(sn);\n    StringValue(ln);\n\n    if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln)))\n\tossl_raise(eASN1Error, NULL);\n\n    return Qtrue;\n}\n\nstatic VALUE\nossl_asn1obj_get_sn(VALUE self)\n{\n    VALUE val, ret = Qnil;\n    int nid;\n\n    val = ossl_asn1_get_value(self);\n    if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)\n\tret = rb_str_new2(OBJ_nid2sn(nid));\n\n    return ret;\n}\n\nstatic VALUE\nossl_asn1obj_get_ln(VALUE self)\n{\n    VALUE val, ret = Qnil;\n    int nid;\n\n    val = ossl_asn1_get_value(self);\n    if ((nid = OBJ_txt2nid(StringValuePtr(val))) != NID_undef)\n\tret = rb_str_new2(OBJ_nid2ln(nid));\n\n    return ret;\n}\n\nstatic VALUE\nossl_asn1obj_get_oid(VALUE self)\n{\n    VALUE val;\n    ASN1_OBJECT *a1obj;\n    char buf[128];\n\n    val = ossl_asn1_get_value(self);\n    a1obj = obj_to_asn1obj(val);\n    OBJ_obj2txt(buf, sizeof(buf), a1obj, 1);\n    ASN1_OBJECT_free(a1obj);\n\n    return rb_str_new2(buf);\n}\n\n#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \\\nstatic VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\\\n{ return rb_funcall3(cASN1##klass, rb_intern(\"new\"), argc, argv); }\n\nOSSL_ASN1_IMPL_FACTORY_METHOD(Boolean)\nOSSL_ASN1_IMPL_FACTORY_METHOD(Integer)\nOSSL_ASN1_IMPL_FACTORY_METHOD(Enumerated)\nOSSL_ASN1_IMPL_FACTORY_METHOD(BitString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(OctetString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(UTF8String)\nOSSL_ASN1_IMPL_FACTORY_METHOD(NumericString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(PrintableString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(T61String)\nOSSL_ASN1_IMPL_FACTORY_METHOD(VideotexString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(IA5String)\nOSSL_ASN1_IMPL_FACTORY_METHOD(GraphicString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(ISO64String)\nOSSL_ASN1_IMPL_FACTORY_METHOD(GeneralString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(UniversalString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(BMPString)\nOSSL_ASN1_IMPL_FACTORY_METHOD(Null)\nOSSL_ASN1_IMPL_FACTORY_METHOD(ObjectId)\nOSSL_ASN1_IMPL_FACTORY_METHOD(UTCTime)\nOSSL_ASN1_IMPL_FACTORY_METHOD(GeneralizedTime)\nOSSL_ASN1_IMPL_FACTORY_METHOD(Sequence)\nOSSL_ASN1_IMPL_FACTORY_METHOD(Set)\n\nvoid\nInit_ossl_asn1()\n{\n    VALUE ary;\n    int i;\n\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n\n    sUNIVERSAL = rb_intern(\"UNIVERSAL\");\n    sCONTEXT_SPECIFIC = rb_intern(\"CONTEXT_SPECIFIC\");\n    sAPPLICATION = rb_intern(\"APPLICATION\");\n    sPRIVATE = rb_intern(\"PRIVATE\");\n    sEXPLICIT = rb_intern(\"EXPLICIT\");\n    sIMPLICIT = rb_intern(\"IMPLICIT\");\n\n    mASN1 = rb_define_module_under(mOSSL, \"ASN1\");\n    eASN1Error = rb_define_class_under(mASN1, \"ASN1Error\", eOSSLError);\n    rb_define_module_function(mASN1, \"traverse\", ossl_asn1_traverse, 1);\n    rb_define_module_function(mASN1, \"decode\", ossl_asn1_decode, 1);\n    rb_define_module_function(mASN1, \"decode_all\", ossl_asn1_decode_all, 1);\n    ary = rb_ary_new();\n    rb_define_const(mASN1, \"UNIVERSAL_TAG_NAME\", ary);\n    for(i = 0; i < ossl_asn1_info_size; i++){\n\tif(ossl_asn1_info[i].name[0] == '[') continue;\n\trb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i));\n\trb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));\n    }\n\n    cASN1Data = rb_define_class_under(mASN1, \"ASN1Data\", rb_cObject);\n    rb_attr(cASN1Data, rb_intern(\"value\"), 1, 1, 0);\n    rb_attr(cASN1Data, rb_intern(\"tag\"), 1, 1, 0);\n    rb_attr(cASN1Data, rb_intern(\"tag_class\"), 1, 1, 0);\n    rb_define_method(cASN1Data, \"initialize\", ossl_asn1data_initialize, 3);\n    rb_define_method(cASN1Data, \"to_der\", ossl_asn1data_to_der, 0);\n\n    cASN1Primitive = rb_define_class_under(mASN1, \"Primitive\", cASN1Data);\n    rb_attr(cASN1Primitive, rb_intern(\"tagging\"), 1, 1, Qtrue);\n    rb_define_method(cASN1Primitive, \"initialize\", ossl_asn1_initialize, -1);\n    rb_define_method(cASN1Primitive, \"to_der\", ossl_asn1prim_to_der, 0);\n\n    cASN1Constructive = rb_define_class_under(mASN1,\"Constructive\", cASN1Data);\n    rb_include_module(cASN1Constructive, rb_mEnumerable);\n    rb_attr(cASN1Constructive, rb_intern(\"tagging\"), 1, 1, Qtrue);\n    rb_define_method(cASN1Constructive, \"initialize\", ossl_asn1_initialize, -1);\n    rb_define_method(cASN1Constructive, \"to_der\", ossl_asn1cons_to_der, 0);\n    rb_define_method(cASN1Constructive, \"each\", ossl_asn1cons_each, 0);\n\n#define OSSL_ASN1_DEFINE_CLASS(name, super) \\\ndo{\\\n    cASN1##name = rb_define_class_under(mASN1, #name, cASN1##super);\\\n    rb_define_module_function(mASN1, #name, ossl_asn1_##name, -1);\\\n}while(0)\n\n    OSSL_ASN1_DEFINE_CLASS(Boolean, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(Integer, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(Enumerated, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(BitString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(OctetString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(UTF8String, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(NumericString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(PrintableString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(T61String, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(VideotexString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(IA5String, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(GraphicString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(ISO64String, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(GeneralString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(UniversalString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(BMPString, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(Null, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(ObjectId, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(UTCTime, Primitive);\n    OSSL_ASN1_DEFINE_CLASS(GeneralizedTime, Primitive);\n\n    OSSL_ASN1_DEFINE_CLASS(Sequence, Constructive);\n    OSSL_ASN1_DEFINE_CLASS(Set, Constructive);\n\n    rb_define_singleton_method(cASN1ObjectId, \"register\", ossl_asn1obj_s_register, 3);\n    rb_define_method(cASN1ObjectId, \"sn\", ossl_asn1obj_get_sn, 0);\n    rb_define_method(cASN1ObjectId, \"ln\", ossl_asn1obj_get_ln, 0);\n    rb_define_method(cASN1ObjectId, \"oid\", ossl_asn1obj_get_oid, 0);\n    rb_define_alias(cASN1ObjectId, \"short_name\", \"sn\");\n    rb_define_alias(cASN1ObjectId, \"long_name\", \"ln\");\n    rb_attr(cASN1BitString, rb_intern(\"unused_bits\"), 1, 1, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_asn1.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_ASN1_H_)\n#define _OSSL_ASN1_H_\n\n/*\n * ASN1_DATE conversions\n */\nVALUE asn1time_to_time(ASN1_TIME *);\ntime_t time_to_time_t(VALUE);\n\n/*\n * ASN1_STRING conversions\n */\nVALUE asn1str_to_str(ASN1_STRING *);\n\n/*\n * ASN1_INTEGER conversions\n */\nVALUE asn1integer_to_num(ASN1_INTEGER *);\nASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *);\n\n/*\n * ASN1 module\n */\nextern VALUE mASN1;\nextern VALUE eASN1Error;  \n\nextern VALUE cASN1Data;\nextern VALUE cASN1Primitive;\nextern VALUE cASN1Constructive;\n \nextern VALUE cASN1Boolean;                           /* BOOLEAN           */\nextern VALUE cASN1Integer, cASN1Enumerated;          /* INTEGER           */\nextern VALUE cASN1BitString;                         /* BIT STRING        */\nextern VALUE cASN1OctetString, cASN1UTF8String;      /* STRINGs           */\nextern VALUE cASN1NumericString, cASN1PrintableString;\nextern VALUE cASN1T61String, cASN1VideotexString;\nextern VALUE cASN1IA5String, cASN1GraphicString;\nextern VALUE cASN1ISO64String, cASN1GeneralString;\nextern VALUE cASN1UniversalString, cASN1BMPString;\nextern VALUE cASN1Null;                              /* NULL              */\nextern VALUE cASN1ObjectId;                          /* OBJECT IDENTIFIER */\nextern VALUE cASN1UTCTime, cASN1GeneralizedTime;     /* TIME              */\nextern VALUE cASN1Sequence, cASN1Set;                /* CONSTRUCTIVE      */\n\nASN1_TYPE *ossl_asn1_get_asn1type(VALUE);\n\nvoid Init_ossl_asn1(void);\n\n#endif\n"
  },
  {
    "path": "ext/openssl/ossl_bio.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\nBIO *\nossl_obj2bio(VALUE obj)\n{\n    BIO *bio;\n\n    if (TYPE(obj) == T_FILE) {\n\trb_io_t *fptr;\n\tFILE *fp;\n\tint fd;\n\n\tGetOpenFile(obj, fptr);\n\trb_io_check_readable(fptr);\n\tif ((fd = dup(FPTR_TO_FD(fptr))) < 0){\n\t    rb_sys_fail(0);\n\t}\n\tif (!(fp = fdopen(fd, \"r\"))){\n\t    close(fd);\n\t    rb_sys_fail(0);\n\t}\n\tif (!(bio = BIO_new_fp(fp, BIO_CLOSE))){\n\t    fclose(fp);\n\t    ossl_raise(eOSSLError, NULL);\n\t}\n    }\n    else {\n\tStringValue(obj);\n\tbio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LEN(obj));\n\tif (!bio) ossl_raise(eOSSLError, NULL);\n    }\n\n    return bio;\n}\n\nBIO *\nossl_protect_obj2bio(VALUE obj, int *status)\n{\n     BIO *ret = NULL;\n     ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status);\n     return ret;\n}\n\nVALUE\nossl_membio2str0(BIO *bio)\n{\n    VALUE ret;\n    BUF_MEM *buf;\n\n    BIO_get_mem_ptr(bio, &buf);\n    ret = rb_str_new(buf->data, buf->length);\n\n    return ret;\n}\n\nVALUE\nossl_protect_membio2str(BIO *bio, int *status)\n{\n    return rb_protect((VALUE(*)_((VALUE)))ossl_membio2str0, (VALUE)bio, status);\n}\n\nVALUE \nossl_membio2str(BIO *bio)\n{\n    VALUE ret;\n    int status = 0;\n\n    ret = ossl_protect_membio2str(bio, &status);\n    BIO_free(bio);\n    if(status) rb_jump_tag(status);\n\n    return ret;\n}\n"
  },
  {
    "path": "ext/openssl/ossl_bio.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' team members\n * Copyright (C) 2003\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_BIO_H_)\n#define _OSSL_BIO_H_\n\nBIO *ossl_obj2bio(VALUE);\nBIO *ossl_protect_obj2bio(VALUE,int*);\nVALUE ossl_membio2str0(BIO*);\nVALUE ossl_membio2str(BIO*);\nVALUE ossl_protect_membio2str(BIO*,int*);\n\n#endif\n\n"
  },
  {
    "path": "ext/openssl/ossl_bn.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Technorama team <oss-ruby@technorama.net>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n/* modified by Michal Rokos <m.rokos@sh.cvut.cz> */\n#include \"ossl.h\"\n\n#define WrapBN(klass, obj, bn) do { \\\n  if (!bn) { \\\n    ossl_raise(rb_eRuntimeError, \"BN wasn't initialized!\"); \\\n  } \\\n  obj = Data_Wrap_Struct(klass, 0, BN_clear_free, bn); \\\n} while (0)\n\n#define GetBN(obj, bn) do { \\\n  Data_Get_Struct(obj, BIGNUM, bn); \\\n  if (!bn) { \\\n    ossl_raise(rb_eRuntimeError, \"BN wasn't initialized!\"); \\\n  } \\\n} while (0)\n\n#define SafeGetBN(obj, bn) do { \\\n  OSSL_Check_Kind(obj, cBN); \\\n  GetBN(obj, bn); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cBN;\nVALUE eBNError;\n\n/*\n * Public\n */\nVALUE\nossl_bn_new(const BIGNUM *bn)\n{\n    BIGNUM *newbn;\n    VALUE obj;\n\n    newbn = bn ? BN_dup(bn) : BN_new();\n    if (!newbn) {\n\tossl_raise(eBNError, NULL);\n    }\n    WrapBN(cBN, obj, newbn);\n\n    return obj;\n}\n\nBIGNUM *\nGetBNPtr(VALUE obj)\n{\n    BIGNUM *bn = NULL;\n\n    if (RTEST(rb_obj_is_kind_of(obj, cBN))) {\n\tGetBN(obj, bn);\n    } else switch (TYPE(obj)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n\tobj = rb_String(obj);\n\tif (!BN_dec2bn(&bn, StringValuePtr(obj))) {\n\t    ossl_raise(eBNError, NULL);\n\t}\n\tWrapBN(cBN, obj, bn); /* Handle potencial mem leaks */\n\tbreak;\n    default:\n\tossl_raise(rb_eTypeError, \"Cannot convert into OpenSSL::BN\");\n    }\n    return bn;\n}\n\n/*\n * Private\n */\n/*\n * BN_CTX - is used in more difficult math. ops\n * (Why just 1? Because Ruby itself isn't thread safe,\n *  we don't need to care about threads)\n */\nBN_CTX *ossl_bn_ctx;\n\nstatic VALUE\nossl_bn_alloc(VALUE klass)\n{\n    BIGNUM *bn;\n    VALUE obj;\n\t\n    if (!(bn = BN_new())) {\n\tossl_raise(eBNError, NULL);\n    }\n    WrapBN(klass, obj, bn);\n\n    return obj;\n}\n\n/*\n * call-seq:\n *    BN.new => aBN\n *    BN.new(bn) => aBN\n *    BN.new(string) => aBN\n *    BN.new(string, 0 | 2 | 10 | 16) => aBN\n */\nstatic VALUE\nossl_bn_initialize(int argc, VALUE *argv, VALUE self)\n{\n    BIGNUM *bn;\n    VALUE str, bs;\n    int base = 10;\n\n    if (rb_scan_args(argc, argv, \"11\", &str, &bs) == 2) {\n\tbase = NUM2INT(bs);\n    }\n    StringValue(str);\n    GetBN(self, bn);\n    if (RTEST(rb_obj_is_kind_of(str, cBN))) {\n\tBIGNUM *other;\n\n\tGetBN(str, other); /* Safe - we checked kind_of? above */\n\tif (!BN_copy(bn, other)) {\n\t    ossl_raise(eBNError, NULL);\n\t}\n\treturn self;\n    }\n\n    switch (base) {\n    case 0:\n\tif (!BN_mpi2bn(RSTRING_PTR(str), RSTRING_LEN(str), bn)) {\n\t    ossl_raise(eBNError, NULL);\n\t}\n\tbreak;\n    case 2:\n\tif (!BN_bin2bn(RSTRING_PTR(str), RSTRING_LEN(str), bn)) {\n\t    ossl_raise(eBNError, NULL);\n\t}\n\tbreak;\n    case 10:\n\tif (!BN_dec2bn(&bn, RSTRING_PTR(str))) {\n\t    ossl_raise(eBNError, NULL);\n\t}\n\tbreak;\n    case 16:\n\tif (!BN_hex2bn(&bn, RSTRING_PTR(str))) {\n\t    ossl_raise(eBNError, NULL);\n\t}\n\tbreak;\n    default:\n\tossl_raise(rb_eArgError, \"illegal radix %d\", base);\n    }\n    return self;\n}\n\n/*\n * call-seq:\n *    bn.to_s => string\n *    bn.to_s(base) => string\n *\n * === Parameters\n * * +base+ - integer\n * * * Valid values:\n * * * * 0 - MPI\n * * * * 2 - binary\n * * * * 10 - the default\n * * * * 16 - hex\n */\nstatic VALUE\nossl_bn_to_s(int argc, VALUE *argv, VALUE self)\n{\n    BIGNUM *bn;\n    VALUE str, bs;\n    int base = 10, len;\n    char *buf;\n\n    if (rb_scan_args(argc, argv, \"01\", &bs) == 1) {\n\tbase = NUM2INT(bs);\n    }\n    GetBN(self, bn);\n    switch (base) {\n    case 0:\n\tlen = BN_bn2mpi(bn, NULL);\n        str = rb_str_new(0, len);\n\tif (BN_bn2mpi(bn, RSTRING_PTR(str)) != len)\n\t    ossl_raise(eBNError, NULL);\n\tbreak;\n    case 2:\n\tlen = BN_num_bytes(bn);\n        str = rb_str_new(0, len);\n\tif (BN_bn2bin(bn, RSTRING_PTR(str)) != len)\n\t    ossl_raise(eBNError, NULL);\n\tbreak;\n    case 10:\n\tif (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);\n\tstr = ossl_buf2str(buf, strlen(buf));\n\tbreak;\n    case 16:\n\tif (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);\n\tstr = ossl_buf2str(buf, strlen(buf));\n\tbreak;\n    default:\n\tossl_raise(rb_eArgError, \"illegal radix %d\", base);\n    }\n\n    return str;\n}\n\n/*\n * call-seq:\n *    bn.to_i => integer\n */\nstatic VALUE\nossl_bn_to_i(VALUE self)\n{\n    BIGNUM *bn;\n    char *txt;\n    VALUE num;\n\n    GetBN(self, bn);\n\n    if (!(txt = BN_bn2dec(bn))) {\n\tossl_raise(eBNError, NULL);\n    }\n    num = rb_cstr_to_inum(txt, 10, Qtrue);\n    OPENSSL_free(txt);\n\n    return num;\n}\n\nstatic VALUE\nossl_bn_to_bn(VALUE self)\n{\n    return self;\n}\n\nstatic VALUE\nossl_bn_coerce(VALUE self, VALUE other)\n{\n    switch(TYPE(other)) {\n    case T_STRING:\n\tself = ossl_bn_to_s(0, NULL, self);\n\tbreak;\n    case T_FIXNUM:\n    case T_BIGNUM:\n\tself = ossl_bn_to_i(self);\n\tbreak;\n    default:\n\tif (!RTEST(rb_obj_is_kind_of(other, cBN))) {\n\t    ossl_raise(rb_eTypeError, \"Don't know how to coerce\");\n\t}\n    }\n    return rb_assoc_new(other, self);\n}\n\n#define BIGNUM_BOOL1(func)\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func -> true | false\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn;\t\t\t\t\t\\\n\tGetBN(self, bn);\t\t\t\t\\\n\tif (BN_##func(bn)) {\t\t\t\t\\\n\t    return Qtrue;\t\t\t\t\\\n\t}\t\t\t\t\t\t\\\n\treturn Qfalse;\t\t\t\t\t\\\n    }\nBIGNUM_BOOL1(is_zero);\nBIGNUM_BOOL1(is_one);\nBIGNUM_BOOL1(is_odd);\n\n#define BIGNUM_1c(func)\t\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func -> aBN\t\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn, *result;\t\t\t\t\\\n\tVALUE obj;\t\t\t\t\t\\\n\tGetBN(self, bn);\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\\\n\t}\t\t\t\t\t\t\\\n\tif (!BN_##func(result, bn, ossl_bn_ctx)) {\t\\\n\t    BN_free(result);\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\\\n\t}\t\t\t\t\t\t\\\n\tWrapBN(CLASS_OF(self), obj, result);\t\t\\\n\treturn obj;\t\t\t\t\t\\\n    }\nBIGNUM_1c(sqr);\n\n#define BIGNUM_2(func)\t\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func(bn2) -> aBN\t\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self, VALUE other)\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn1, *bn2 = GetBNPtr(other), *result;\t\\\n\tVALUE obj;\t\t\t\t\t\\\n\tGetBN(self, bn1);\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\\\n\t}\t\t\t\t\t\t\\\n\tif (!BN_##func(result, bn1, bn2)) {\t\t\\\n\t    BN_free(result);\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\\\n\t}\t\t\t\t\t\t\\\n\tWrapBN(CLASS_OF(self), obj, result);\t\t\\\n\treturn obj;\t\t\t\t\t\\\n    }\nBIGNUM_2(add);\nBIGNUM_2(sub);\n\n#define BIGNUM_2c(func)\t\t\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\t\\\n     *   bn.##func(bn2) -> aBN\t\t\t\t\t\\\n     *\t\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self, VALUE other)\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n\tBIGNUM *bn1, *bn2 = GetBNPtr(other), *result;\t\t\\\n\tVALUE obj;\t\t\t\t\t\t\\\n\tGetBN(self, bn1);\t\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tif (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) {\t\\\n\t    BN_free(result);\t\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tWrapBN(CLASS_OF(self), obj, result);\t\t\t\\\n\treturn obj;\t\t\t\t\t\t\\\n    }\nBIGNUM_2c(mul);\nBIGNUM_2c(mod);\nBIGNUM_2c(exp);\nBIGNUM_2c(gcd);\nBIGNUM_2c(mod_sqr);\nBIGNUM_2c(mod_inverse);\n\n/*\n * call-seq:\n *    bn1 / bn2 => [result, remainder]\n */\nstatic VALUE\nossl_bn_div(VALUE self, VALUE other)\n{\n    BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;\n    VALUE obj1, obj2;\n\n    GetBN(self, bn1);\n\n    if (!(r1 = BN_new())) {\n\tossl_raise(eBNError, NULL);\n    }\n    if (!(r2 = BN_new())) {\n\tBN_free(r1);\n\tossl_raise(eBNError, NULL);\n    }\n    if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {\n\tBN_free(r1);\n\tBN_free(r2);\n\tossl_raise(eBNError, NULL);\n    }\n    WrapBN(CLASS_OF(self), obj1, r1);\n    WrapBN(CLASS_OF(self), obj2, r2);\n    \n    return rb_ary_new3(2, obj1, obj2);\n}\n\n#define BIGNUM_3c(func)\t\t\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\t\\\n     *   bn.##func(bn1, bn2) -> aBN\t\t\t\t\\\n     *\t\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self, VALUE other1, VALUE other2)\t\\\n    {\t\t\t\t\t\t\t\t\\\n\tBIGNUM *bn1, *bn2 = GetBNPtr(other1);\t\t\t\\\n\tBIGNUM *bn3 = GetBNPtr(other2), *result;\t\t\\\n\tVALUE obj;\t\t\t\t\t\t\\\n\tGetBN(self, bn1);\t\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tif (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) {\t\\\n\t    BN_free(result);\t\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tWrapBN(CLASS_OF(self), obj, result);\t\t\t\\\n\treturn obj;\t\t\t\t\t\t\\\n    }\nBIGNUM_3c(mod_add);\nBIGNUM_3c(mod_sub);\nBIGNUM_3c(mod_mul);\nBIGNUM_3c(mod_exp);\n\n#define BIGNUM_BIT(func)\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func(bit) -> self\t\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self, VALUE bit)\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn;\t\t\t\t\t\\\n\tGetBN(self, bn);\t\t\t\t\\\n\tif (!BN_##func(bn, NUM2INT(bit))) {\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\\\n\t}\t\t\t\t\t\t\\\n\treturn self;\t\t\t\t\t\\\n    }\nBIGNUM_BIT(set_bit);\nBIGNUM_BIT(clear_bit);\nBIGNUM_BIT(mask_bits);\n\n/*\n * call-seq:\n *    bn.bit_set?(bit) => true | false\n */\nstatic VALUE\nossl_bn_is_bit_set(VALUE self, VALUE bit)\n{\n    int b;\n    BIGNUM *bn;\n\n    b = NUM2INT(bit);\n    GetBN(self, bn);\n    if (BN_is_bit_set(bn, b)) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n#define BIGNUM_SHIFT(func)\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func(bits) -> aBN\t\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self, VALUE bits)\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn, *result;\t\t\t\t\\\n\tint b;\t\t\t\t\t\t\\\n\tVALUE obj;\t\t\t\t\t\\\n\tb = NUM2INT(bits);\t\t\t\t\\\n\tGetBN(self, bn);\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\\\n\t\tossl_raise(eBNError, NULL);\t\t\\\n\t}\t\t\t\t\t\t\\\n\tif (!BN_##func(result, bn, b)) {\t\t\\\n\t\tBN_free(result);\t\t\t\\\n\t\tossl_raise(eBNError, NULL);\t\t\\\n\t}\t\t\t\t\t\t\\\n\tWrapBN(CLASS_OF(self), obj, result);\t\t\\\n\treturn obj;\t\t\t\t\t\\\n    }\nBIGNUM_SHIFT(lshift);\nBIGNUM_SHIFT(rshift);\n\n#define BIGNUM_SELF_SHIFT(func)\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func!(bits) -> self\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_self_##func(VALUE self, VALUE bits)\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn;\t\t\t\t\t\\\n\tint b;\t\t\t\t\t\t\\\n\tb = NUM2INT(bits);\t\t\t\t\\\n\tGetBN(self, bn);\t\t\t\t\\\n\tif (!BN_##func(bn, bn, b))\t\t\t\\\n\t\tossl_raise(eBNError, NULL);\t\t\\\n\treturn self;\t\t\t\t\t\\\n    }\nBIGNUM_SELF_SHIFT(lshift);\nBIGNUM_SELF_SHIFT(rshift);\n\n#define BIGNUM_RAND(func)\t\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\t\\\n     *   BN.##func(bits [, fill [, odd]]) -> aBN\t\t\\\n     *\t\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\t\\\n    ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass)\t\\\n    {\t\t\t\t\t\t\t\t\\\n\tBIGNUM *result;\t\t\t\t\t\t\\\n\tint bottom = 0, top = 0, b;\t\t\t\t\\\n\tVALUE bits, fill, odd, obj;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\tswitch (rb_scan_args(argc, argv, \"12\", &bits, &fill, &odd)) {\t\\\n\tcase 3:\t\t\t\t\t\t\t\\\n\t    bottom = (odd == Qtrue) ? 1 : 0;\t\t\t\\\n\t    /* FALLTHROUGH */\t\t\t\t\t\\\n\tcase 2:\t\t\t\t\t\t\t\\\n\t    top = NUM2INT(fill);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tb = NUM2INT(bits);\t\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tif (!BN_##func(result, b, top, bottom)) {\t\t\\\n\t    BN_free(result);\t\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tWrapBN(klass, obj, result);\t\t\t\t\\\n\treturn obj;\t\t\t\t\t\t\\\n    }\nBIGNUM_RAND(rand);\nBIGNUM_RAND(pseudo_rand);\n\n#define BIGNUM_RAND_RANGE(func)\t\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\t\\\n     *   BN.##func(range) -> aBN\t\t\t\t\\\n     *\t\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\t\\\n    ossl_bn_s_##func##_range(VALUE klass, VALUE range)\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n\tBIGNUM *bn = GetBNPtr(range), *result;\t\t\t\\\n\tVALUE obj;\t\t\t\t\t\t\\\n\tif (!(result = BN_new())) {\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tif (!BN_##func##_range(result, bn)) {\t\t\t\\\n\t    BN_free(result);\t\t\t\t\t\\\n\t    ossl_raise(eBNError, NULL);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tWrapBN(klass, obj, result);\t\t\t\t\\\n\treturn obj;\t\t\t\t\t\t\\\n    }\nBIGNUM_RAND_RANGE(rand);\nBIGNUM_RAND_RANGE(pseudo_rand);\n\n/*\n * call-seq:\n *    BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn\n *\n * === Parameters\n * * +bits+ - integer\n * * +safe+ - boolean\n * * +add+ - BN\n * * +rem+ - BN\n */\nstatic VALUE\nossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)\n{\n    BIGNUM *add = NULL, *rem = NULL, *result;\n    int safe = 1, num;\n    VALUE vnum, vsafe, vadd, vrem, obj;\n\n    rb_scan_args(argc, argv, \"13\", &vnum, &vsafe, &vadd, &vrem);\n\t\n    num = NUM2INT(vnum);\n\n    if (vsafe == Qfalse) {\n\tsafe = 0;\n    }\n    if (!NIL_P(vadd)) {\n\tadd = GetBNPtr(vadd);\n\trem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);\n    }\n    if (!(result = BN_new())) {\n\tossl_raise(eBNError, NULL);\n    }\n    if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {\n\tBN_free(result);\n\tossl_raise(eBNError, NULL);\n    }\n    WrapBN(klass, obj, result);\n    \n    return obj;\n}\n\n#define BIGNUM_NUM(func)\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func -> integer\t\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE \t\t\t\t\\\n    ossl_bn_##func(VALUE self)\t\t\t\\\n    {\t\t\t\t\t\t\\\n\tBIGNUM *bn;\t\t\t\t\\\n\tGetBN(self, bn);\t\t\t\\\n\treturn INT2FIX(BN_##func(bn));\t\t\\\n    }\nBIGNUM_NUM(num_bytes);\nBIGNUM_NUM(num_bits);\n\nstatic VALUE\nossl_bn_copy(VALUE self, VALUE other)\n{\n    BIGNUM *bn1, *bn2;\n    \n    rb_check_frozen(self);\n    \n    if (self == other) return self;\n    \n    GetBN(self, bn1);\n    bn2 = GetBNPtr(other);\n    \n    if (!BN_copy(bn1, bn2)) {\n\tossl_raise(eBNError, NULL);\n    }\n    return self;\n}\n\n#define BIGNUM_CMP(func)\t\t\t\t\\\n    /*\t\t\t\t\t\t\t\\\n     * call-seq:\t\t\t\t\t\\\n     *   bn.##func(bn2) -> integer\t\t\t\\\n     *\t\t\t\t\t\t\t\\\n     */\t\t\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\\\n    ossl_bn_##func(VALUE self, VALUE other)\t\t\\\n    {\t\t\t\t\t\t\t\\\n\tBIGNUM *bn1, *bn2 = GetBNPtr(other);\t\t\\\n\tGetBN(self, bn1);\t\t\t\t\\\n\treturn INT2FIX(BN_##func(bn1, bn2));\t\t\\\n    }\nBIGNUM_CMP(cmp);\nBIGNUM_CMP(ucmp);\n\nstatic VALUE\nossl_bn_eql(VALUE self, VALUE other)\n{\n    if (ossl_bn_cmp(self, other) == INT2FIX(0)) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *    bn.prime? => true | false\n *    bn.prime?(checks) => true | false\n *\n * === Parameters\n * * +checks+ - integer\n */\nstatic VALUE\nossl_bn_is_prime(int argc, VALUE *argv, VALUE self)\n{\n    BIGNUM *bn;\n    VALUE vchecks;\n    int checks = BN_prime_checks;\n\n    if (rb_scan_args(argc, argv, \"01\", &vchecks) == 0) {\n\tchecks = NUM2INT(vchecks);\n    }\n    GetBN(self, bn);\n    switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) {\n    case 1:\n\treturn Qtrue;\n    case 0:\n\treturn Qfalse;\n    default:\n\tossl_raise(eBNError, NULL);\n    }\n    /* not reachable */\n    return Qnil;\n}\n\n/*\n * call-seq:\n *    bn.prime_fasttest? => true | false\n *    bn.prime_fasttest?(checks) => true | false\n *    bn.prime_fasttest?(checks, trial_div) => true | false\n *\n * === Parameters\n * * +checks+ - integer\n * * +trial_div+ - boolean\n */\nstatic VALUE\nossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)\n{\n    BIGNUM *bn;\n    VALUE vchecks, vtrivdiv;\n    int checks = BN_prime_checks, do_trial_division = 1;\n\n    rb_scan_args(argc, argv, \"02\", &vchecks, &vtrivdiv);\n\n    if (!NIL_P(vchecks)) {\n\tchecks = NUM2INT(vchecks);\n    }\n    GetBN(self, bn);\n    /* handle true/false */\n    if (vtrivdiv == Qfalse) {\n\tdo_trial_division = 0;\n    }\n    switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) {\n    case 1:\n\treturn Qtrue;\n    case 0:\n\treturn Qfalse;\n    default:\n\tossl_raise(eBNError, NULL);\n    }\n    /* not reachable */\n    return Qnil;\n}\n\n/*\n * INIT\n * (NOTE: ordering of methods is the same as in 'man bn')\n */\nvoid\nInit_ossl_bn()\n{\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n\n    if (!(ossl_bn_ctx = BN_CTX_new())) {\n\tossl_raise(rb_eRuntimeError, \"Cannot init BN_CTX\");\n    }\n\n    eBNError = rb_define_class_under(mOSSL, \"BNError\", eOSSLError);\n\n    cBN = rb_define_class_under(mOSSL, \"BN\", rb_cObject);\n\n    rb_define_alloc_func(cBN, ossl_bn_alloc);\n    rb_define_method(cBN, \"initialize\", ossl_bn_initialize, -1);\n\t\n    rb_define_copy_func(cBN, ossl_bn_copy);\n    rb_define_method(cBN, \"copy\", ossl_bn_copy, 1);\n\n    /* swap (=coerce?) */\n\n    rb_define_method(cBN, \"num_bytes\", ossl_bn_num_bytes, 0);\n    rb_define_method(cBN, \"num_bits\", ossl_bn_num_bits, 0);\n    /* num_bits_word */\n\n    rb_define_method(cBN, \"+\", ossl_bn_add, 1);\n    rb_define_method(cBN, \"-\", ossl_bn_sub, 1);\n    rb_define_method(cBN, \"*\", ossl_bn_mul, 1);\n    rb_define_method(cBN, \"sqr\", ossl_bn_sqr, 0);\n    rb_define_method(cBN, \"/\", ossl_bn_div, 1);\n    rb_define_method(cBN, \"%\", ossl_bn_mod, 1);\n    /* nnmod */\n\n    rb_define_method(cBN, \"mod_add\", ossl_bn_mod_add, 2);\n    rb_define_method(cBN, \"mod_sub\", ossl_bn_mod_sub, 2);\n    rb_define_method(cBN, \"mod_mul\", ossl_bn_mod_mul, 2);\n    rb_define_method(cBN, \"mod_sqr\", ossl_bn_mod_sqr, 1);\n    rb_define_method(cBN, \"**\", ossl_bn_exp, 1);\n    rb_define_method(cBN, \"mod_exp\", ossl_bn_mod_exp, 2);\n    rb_define_method(cBN, \"gcd\", ossl_bn_gcd, 1);\n\n    /* add_word\n     * sub_word\n     * mul_word\n     * div_word\n     * mod_word */\n\n    rb_define_method(cBN, \"cmp\", ossl_bn_cmp, 1);\n    rb_define_alias(cBN, \"<=>\", \"cmp\");\n    rb_define_method(cBN, \"ucmp\", ossl_bn_ucmp, 1);\n    rb_define_method(cBN, \"eql?\", ossl_bn_eql, 1);\n    rb_define_alias(cBN, \"==\", \"eql?\");\n    rb_define_alias(cBN, \"===\", \"eql?\");\n    rb_define_method(cBN, \"zero?\", ossl_bn_is_zero, 0);\n    rb_define_method(cBN, \"one?\", ossl_bn_is_one, 0);\n    /* is_word */\n    rb_define_method(cBN, \"odd?\", ossl_bn_is_odd, 0);\n\n    /* zero\n     * one\n     * value_one - DON'T IMPL.\n     * set_word\n     * get_word */\n    \n    rb_define_singleton_method(cBN, \"rand\", ossl_bn_s_rand, -1);\n    rb_define_singleton_method(cBN, \"pseudo_rand\", ossl_bn_s_pseudo_rand, -1);\n    rb_define_singleton_method(cBN, \"rand_range\", ossl_bn_s_rand_range, 1);\n    rb_define_singleton_method(cBN, \"pseudo_rand_range\", ossl_bn_s_pseudo_rand_range, 1);\n\n    rb_define_singleton_method(cBN, \"generate_prime\", ossl_bn_s_generate_prime, -1);\n    rb_define_method(cBN, \"prime?\", ossl_bn_is_prime, -1);\n\n    rb_define_method(cBN, \"set_bit!\", ossl_bn_set_bit, 1);\n    rb_define_method(cBN, \"clear_bit!\", ossl_bn_clear_bit, 1);\n    rb_define_method(cBN, \"bit_set?\", ossl_bn_is_bit_set, 1);\n    rb_define_method(cBN, \"mask_bits!\", ossl_bn_mask_bits, 1);\n    rb_define_method(cBN, \"<<\", ossl_bn_lshift, 1);\n    rb_define_method(cBN, \">>\", ossl_bn_rshift, 1);\n    rb_define_method(cBN, \"lshift!\", ossl_bn_self_lshift, 1);\n    rb_define_method(cBN, \"rshift!\", ossl_bn_self_rshift, 1);\n    /* lshift1 - DON'T IMPL. */\n    /* rshift1 - DON'T IMPL. */\n\n    /*\n     * bn2bin\n     * bin2bn\n     * bn2hex\n     * bn2dec\n     * hex2bn\n     * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s\n     * print - NOT IMPL.\n     * print_fp - NOT IMPL.\n     * bn2mpi\n     * mpi2bn\n     */\n    rb_define_method(cBN, \"to_s\", ossl_bn_to_s, -1);\n    rb_define_method(cBN, \"to_i\", ossl_bn_to_i, 0);\n    rb_define_alias(cBN, \"to_int\", \"to_i\");\n    rb_define_method(cBN, \"to_bn\", ossl_bn_to_bn, 0);\n    rb_define_method(cBN, \"coerce\", ossl_bn_coerce, 1);\n\t\n    /*\n     * TODO:\n     * But how to: from_bin, from_mpi? PACK?\n     * to_bin\n     * to_mpi\n     */\n\n    rb_define_method(cBN, \"mod_inverse\", ossl_bn_mod_inverse, 1);\n\n    /* RECiProcal\n     * MONTgomery */\n\n    /*\n     * TODO:\n     * Where to belong these?\n     */\n    rb_define_method(cBN, \"prime_fasttest?\", ossl_bn_is_prime_fasttest, -1);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_bn.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_BN_H_)\n#define _OSSL_BN_H_\n\nextern VALUE cBN;\nextern VALUE eBNError;\n\nextern BN_CTX *ossl_bn_ctx;\n\nVALUE ossl_bn_new(const BIGNUM *);\nBIGNUM *GetBNPtr(VALUE);\nvoid Init_ossl_bn(void);\n\n\n#endif /* _OSS_BN_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_cipher.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define MakeCipher(obj, klass, ctx) \\\n    obj = Data_Make_Struct(klass, EVP_CIPHER_CTX, 0, ossl_cipher_free, ctx)\n#define GetCipher(obj, ctx) do { \\\n    Data_Get_Struct(obj, EVP_CIPHER_CTX, ctx); \\\n    if (!ctx) { \\\n\tossl_raise(rb_eRuntimeError, \"Cipher not inititalized!\"); \\\n    } \\\n} while (0)\n#define SafeGetCipher(obj, ctx) do { \\\n    OSSL_Check_Kind(obj, cCipher); \\\n    GetCipher(obj, ctx); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cCipher;\nVALUE eCipherError;\n\nstatic VALUE ossl_cipher_alloc(VALUE klass);\n\n/*\n * PUBLIC\n */\nconst EVP_CIPHER *\nGetCipherPtr(VALUE obj)\n{\n    EVP_CIPHER_CTX *ctx;\n\n    SafeGetCipher(obj, ctx);\n\n    return EVP_CIPHER_CTX_cipher(ctx);\n}\n\nVALUE\nossl_cipher_new(const EVP_CIPHER *cipher)\n{\n    VALUE ret;\n    EVP_CIPHER_CTX *ctx;\n\n    ret = ossl_cipher_alloc(cCipher);\n    GetCipher(ret, ctx);\n    EVP_CIPHER_CTX_init(ctx);\n    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)\n\tossl_raise(eCipherError, NULL);\n\n    return ret;\n}\n\n/*\n * PRIVATE\n */\nstatic void\nossl_cipher_free(EVP_CIPHER_CTX *ctx)\n{\n    if (ctx) {\n\tEVP_CIPHER_CTX_cleanup(ctx);\n\tfree(ctx);\n    }\n}\n\nstatic VALUE\nossl_cipher_alloc(VALUE klass)\n{\n    EVP_CIPHER_CTX *ctx;\n    VALUE obj;\n\n    MakeCipher(obj, klass, ctx);\n    EVP_CIPHER_CTX_init(ctx);\n\t\n    return obj;\n}\n\n/*\n *  call-seq:\n *     Cipher.new(string) -> cipher\n *\n *  The string must contain a valid cipher name like \"AES-128-CBC\" or \"3DES\".\n *\n *  A list of cipher names is available by calling OpenSSL::Cipher.ciphers.\n */\nstatic VALUE\nossl_cipher_initialize(VALUE self, VALUE str)\n{\n    EVP_CIPHER_CTX *ctx;\n    const EVP_CIPHER *cipher;\n    char *name;\n\n    name = StringValuePtr(str);\n    GetCipher(self, ctx);\n    if (!(cipher = EVP_get_cipherbyname(name))) {\n\tossl_raise(rb_eRuntimeError, \"unsupported cipher algorithm (%s)\", name);\n    }\n    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)\n\tossl_raise(eCipherError, NULL);\n\n    return self;\n}\nstatic VALUE\nossl_cipher_copy(VALUE self, VALUE other)\n{\n    EVP_CIPHER_CTX *ctx1, *ctx2;\n\t\n    rb_check_frozen(self);\n    if (self == other) return self;\n\n    GetCipher(self, ctx1);\n    SafeGetCipher(other, ctx2);\n    if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1)\n\tossl_raise(eCipherError, NULL);\n\n    return self;\n}\n\nstatic void*\nadd_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary)\n{\n    rb_ary_push(ary, rb_str_new2(name->name));\n    return NULL;\n}\n\n/*\n *  call-seq:\n *     Cipher.ciphers -> array[string...]\n *\n *  Returns the names of all available ciphers in an array.\n */\nstatic VALUE\nossl_s_ciphers(VALUE self)\n{\n#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED\n    VALUE ary;\n\n    ary = rb_ary_new();\n    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,\n                    (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary,\n                    (void*)ary);\n\n    return ary;\n#else\n    rb_notimplement();\n#endif\n}\n\n/*\n *  call-seq:\n *     cipher.reset -> self\n *\n *  Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1).\n */\nstatic VALUE\nossl_cipher_reset(VALUE self)\n{\n    EVP_CIPHER_CTX *ctx;\n\n    GetCipher(self, ctx);\n    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1)\n\tossl_raise(eCipherError, NULL);\n\t\t\n    return self;\n}\n\nstatic VALUE\nossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)\n{\n    EVP_CIPHER_CTX *ctx;\n    unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL;\n    unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL;\n    VALUE pass, init_v;\n\n    if(rb_scan_args(argc, argv, \"02\", &pass, &init_v) > 0){\n\t/*\n\t * oops. this code mistakes salt for IV.\n\t * We deprecated the arguments for this method, but we decided\n\t * keeping this behaviour for backward compatibility.\n\t */\n\tconst char *cname  = rb_class2name(rb_obj_class(self));\n\trb_warn(\"argumtents for %s#encrypt and %s#decrypt were deprecated; \"\n                \"use %s#pkcs5_keyivgen to derive key and IV\",\n                cname, cname, cname);\n\tStringValue(pass);\n\tGetCipher(self, ctx);\n\tif (NIL_P(init_v)) memcpy(iv, \"OpenSSL for Ruby rulez!\", sizeof(iv));\n\telse{\n\t    StringValue(init_v);\n\t    if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) {\n\t\tmemset(iv, 0, EVP_MAX_IV_LENGTH);\n\t\tmemcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v));\n\t    }\n\t    else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv));\n\t}\n\tEVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,\n\t\t       RSTRING_PTR(pass), RSTRING_LEN(pass), 1, key, NULL);\n\tp_key = key;\n\tp_iv = iv;\n    }\n    else {\n\tGetCipher(self, ctx);\n    }\n    if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {\n\tossl_raise(eCipherError, NULL);\n    }\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     cipher.encrypt -> self\n *\n *  Make sure to call .encrypt or .decrypt before using any of the following methods:\n *  * [key=, iv=, random_key, random_iv, pkcs5_keyivgen]\n *\n *  Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1).\n */\nstatic VALUE\nossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)\n{\n    return ossl_cipher_init(argc, argv, self, 1);\n}\n\n/*\n *  call-seq:\n *     cipher.decrypt -> self\n *\n *  Make sure to call .encrypt or .decrypt before using any of the following methods:\n *  * [key=, iv=, random_key, random_iv, pkcs5_keyivgen]\n *\n *  Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0).\n */\nstatic VALUE\nossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)\n{\n    return ossl_cipher_init(argc, argv, self, 0);\n}\n\n/*\n *  call-seq:\n *     cipher.pkcs5_keyivgen(pass [, salt [, iterations [, digest]]] ) -> nil\n *\n *  Generates and sets the key/iv based on a password.\n *\n *  WARNING: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, or DES\n *  with MD5 or SHA1.  Using anything else (like AES) will generate the key/iv using an\n *  OpenSSL specific method.  Use a PKCS5 v2 key generation method instead.\n *\n *  === Parameters\n *  +salt+ must be an 8 byte string if provided.\n *  +iterations+ is a integer with a default of 2048.\n *  +digest+ is a Digest object that defaults to 'MD5'\n *\n *  A minimum of 1000 iterations is recommended.\n *\n */\nstatic VALUE\nossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)\n{\n    EVP_CIPHER_CTX *ctx;\n    const EVP_MD *digest;\n    VALUE vpass, vsalt, viter, vdigest;\n    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL;\n    int iter;\n\n    rb_scan_args(argc, argv, \"13\", &vpass, &vsalt, &viter, &vdigest);\n    StringValue(vpass);\n    if(!NIL_P(vsalt)){\n\tStringValue(vsalt);\n\tif(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)\n\t    rb_raise(eCipherError, \"salt must be an 8-octet string\");\n\tsalt = RSTRING_PTR(vsalt);\n    }\n    iter = NIL_P(viter) ? 2048 : NUM2INT(viter);\n    digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest);\n    GetCipher(self, ctx);\n    EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,\n\t\t   RSTRING_PTR(vpass), RSTRING_LEN(vpass), iter, key, iv); \n    if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)\n\tossl_raise(eCipherError, NULL);\n    OPENSSL_cleanse(key, sizeof key);\n    OPENSSL_cleanse(iv, sizeof iv);\n\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     cipher << data -> string\n *\n *  === Parameters\n *  +data+ is a nonempty string.\n *\n * This method is deprecated and not available in 1.9.x or later.\n */\nstatic VALUE\nossl_cipher_update_deprecated(VALUE self, VALUE data)\n{\n    const char *cname;\n\n    cname = rb_class2name(rb_obj_class(self));\n    rb_warning(\"%s#<< is deprecated; use %s#update instead\", cname, cname);\n    return rb_funcall(self, rb_intern(\"update\"), 1, data);\n}\n\n\n/*\n *  call-seq:\n *     cipher.update(data [, buffer]) -> string or buffer\n *\n *  === Parameters\n *  +data+ is a nonempty string.\n *  +buffer+ is an optional string to store the result.\n */\nstatic VALUE \nossl_cipher_update(int argc, VALUE *argv, VALUE self)\n{\n    EVP_CIPHER_CTX *ctx;\n    char *in;\n    int in_len, out_len;\n    VALUE data, str;\n\n    rb_scan_args(argc, argv, \"11\", &data, &str);\n\n    StringValue(data);\n    in = RSTRING_PTR(data);\n    if ((in_len = RSTRING_LEN(data)) == 0)\n        rb_raise(rb_eArgError, \"data must not be empty\");\n    GetCipher(self, ctx);\n    out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);\n\n    if (NIL_P(str)) {\n        str = rb_str_new(0, out_len);\n    } else {\n        StringValue(str);\n        rb_str_resize(str, out_len);\n    }\n\n    if (!EVP_CipherUpdate(ctx, RSTRING_PTR(str), &out_len, in, in_len))\n\tossl_raise(eCipherError, NULL);\n    assert(out_len < RSTRING_LEN(str));\n    rb_str_set_len(str, out_len);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     cipher.final -> aString\n *\n *  Returns the remaining data held in the cipher object.  Further calls to update() or final() will return garbage.\n *\n *  See EVP_CipherFinal_ex for further information.\n */\nstatic VALUE \nossl_cipher_final(VALUE self)\n{\n    EVP_CIPHER_CTX *ctx;\n    int out_len;\n    VALUE str;\n\n    GetCipher(self, ctx);\n    str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));\n    if (!EVP_CipherFinal_ex(ctx, RSTRING_PTR(str), &out_len))\n\tossl_raise(eCipherError, NULL);\n    assert(out_len <= RSTRING_LEN(str));\n    rb_str_set_len(str, out_len);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     cipher.name -> string\n *\n *  Returns the name of the cipher which may differ slightly from the original name provided.\n */\nstatic VALUE\nossl_cipher_name(VALUE self)\n{\n    EVP_CIPHER_CTX *ctx;\n\n    GetCipher(self, ctx);\n\n    return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx)));\n}\n\n/*\n *  call-seq:\n *     cipher.key = string -> string\n *\n *  Sets the cipher key.\n *\n *  Only call this method after calling cipher.encrypt or cipher.decrypt.\n */\nstatic VALUE\nossl_cipher_set_key(VALUE self, VALUE key)\n{\n    EVP_CIPHER_CTX *ctx;\n\n    StringValue(key);\n    GetCipher(self, ctx);\n\n    if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx))\n        ossl_raise(eCipherError, \"key length too short\");\n\n    if (EVP_CipherInit_ex(ctx, NULL, NULL, RSTRING_PTR(key), NULL, -1) != 1)\n        ossl_raise(eCipherError, NULL);\n\n    return key;\n}\n\n/*\n *  call-seq:\n *     cipher.iv = string -> string\n *\n *  Sets the cipher iv.\n *\n *  Only call this method after calling cipher.encrypt or cipher.decrypt.\n */\nstatic VALUE\nossl_cipher_set_iv(VALUE self, VALUE iv)\n{\n    EVP_CIPHER_CTX *ctx;\n\n    StringValue(iv);\n    GetCipher(self, ctx);\n\n    if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx))\n        ossl_raise(eCipherError, \"iv length too short\");\n\n    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, RSTRING_PTR(iv), -1) != 1)\n\tossl_raise(eCipherError, NULL);\n\n    return iv;\n}\n\n\n/*\n *  call-seq:\n *     cipher.key_length = integer -> integer\n *\n *  Sets the key length of the cipher.  If the cipher is a fixed length cipher then attempting to set the key\n *  length to any value other than the fixed value is an error.\n *\n *  Under normal circumstances you do not need to call this method (and probably shouldn't).\n *\n *  See EVP_CIPHER_CTX_set_key_length for further information.\n */\nstatic VALUE\nossl_cipher_set_key_length(VALUE self, VALUE key_length)\n{\n    int len = NUM2INT(key_length);\n    EVP_CIPHER_CTX *ctx;\n \n    GetCipher(self, ctx);\n    if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)\n        ossl_raise(eCipherError, NULL);\n\n    return key_length;\n}\n\n/*\n *  call-seq:\n *     cipher.padding = integer -> integer\n *\n *  Enables or disables padding. By default encryption operations are padded using standard block padding and the\n *  padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the\n *  total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur.\n *\n *  See EVP_CIPHER_CTX_set_padding for further information.\n */\nstatic VALUE\nossl_cipher_set_padding(VALUE self, VALUE padding)\n{\n#if defined(HAVE_EVP_CIPHER_CTX_SET_PADDING)\n    EVP_CIPHER_CTX *ctx;\n    int pad = NUM2INT(padding);\n\n    GetCipher(self, ctx);\n    if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)\n\tossl_raise(eCipherError, NULL);\n#else\n    rb_notimplement();\n#endif\n    return padding;\n}\n\n#define CIPHER_0ARG_INT(func)\t\t\t\t\t\\\n    static VALUE\t\t\t\t\t\t\\\n    ossl_cipher_##func(VALUE self)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n\tEVP_CIPHER_CTX *ctx;\t\t\t\t\t\\\n\tGetCipher(self, ctx);\t\t\t\t\t\\\n\treturn INT2NUM(EVP_CIPHER_##func(EVP_CIPHER_CTX_cipher(ctx)));\t\\\n    }\nCIPHER_0ARG_INT(key_length)\nCIPHER_0ARG_INT(iv_length)\nCIPHER_0ARG_INT(block_size)\n\n#if 0\n/*\n *  call-seq:\n *     cipher.key_length -> integer\n *\n */\nstatic VALUE ossl_cipher_key_length() { }\n/*\n *  call-seq:\n *     cipher.iv_length -> integer\n *\n */\nstatic VALUE ossl_cipher_iv_length() { }\n/*\n *  call-seq:\n *     cipher.block_size -> integer\n *\n */\nstatic VALUE ossl_cipher_block_size() { }\n#endif\n\n/*\n * INIT\n */\nvoid \nInit_ossl_cipher(void)\n{\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n    cCipher = rb_define_class_under(mOSSL, \"Cipher\", rb_cObject);\n    eCipherError = rb_define_class_under(cCipher, \"CipherError\", eOSSLError);\n\n    rb_define_alloc_func(cCipher, ossl_cipher_alloc);\n    rb_define_copy_func(cCipher, ossl_cipher_copy);\n    rb_define_module_function(cCipher, \"ciphers\", ossl_s_ciphers, 0);\n    rb_define_method(cCipher, \"initialize\", ossl_cipher_initialize, 1);\n    rb_define_method(cCipher, \"reset\", ossl_cipher_reset, 0);\n    rb_define_method(cCipher, \"encrypt\", ossl_cipher_encrypt, -1);\n    rb_define_method(cCipher, \"decrypt\", ossl_cipher_decrypt, -1);\n    rb_define_method(cCipher, \"pkcs5_keyivgen\", ossl_cipher_pkcs5_keyivgen, -1);\n    rb_define_method(cCipher, \"update\", ossl_cipher_update, -1);\n#if RUBY_VERSION_CODE < 190\n    rb_define_method(cCipher, \"<<\", ossl_cipher_update_deprecated, 1);\n#endif\n    rb_define_method(cCipher, \"final\", ossl_cipher_final, 0);\n    rb_define_method(cCipher, \"name\", ossl_cipher_name, 0);\n    rb_define_method(cCipher, \"key=\", ossl_cipher_set_key, 1);\n    rb_define_method(cCipher, \"key_len=\", ossl_cipher_set_key_length, 1);\n    rb_define_method(cCipher, \"key_len\", ossl_cipher_key_length, 0);\n    rb_define_method(cCipher, \"iv=\", ossl_cipher_set_iv, 1);\n    rb_define_method(cCipher, \"iv_len\", ossl_cipher_iv_length, 0);\n    rb_define_method(cCipher, \"block_size\", ossl_cipher_block_size, 0);\n    rb_define_method(cCipher, \"padding=\", ossl_cipher_set_padding, 1);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_cipher.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_CIPHER_H_)\n#define _OSSL_CIPHER_H_\n\nextern VALUE cCipher;\nextern VALUE eCipherError;\n\nconst EVP_CIPHER *GetCipherPtr(VALUE);\nVALUE ossl_cipher_new(const EVP_CIPHER *);\nvoid Init_ossl_cipher(void);\n\n#endif /* _OSSL_CIPHER_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_config.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapConfig(klass, obj, conf) do { \\\n    if (!conf) { \\\n\tossl_raise(rb_eRuntimeError, \"Config wasn't intitialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, NCONF_free, conf); \\\n} while (0)\n#define GetConfig(obj, conf) do { \\\n    Data_Get_Struct(obj, CONF, conf); \\\n    if (!conf) { \\\n\tossl_raise(rb_eRuntimeError, \"Config wasn't intitialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetConfig(obj, conf) do { \\\n    OSSL_Check_Kind(obj, cConfig); \\\n    GetConfig(obj, conf); \\\n} while(0);\n\n/*\n * Classes\n */\nVALUE cConfig;\nVALUE eConfigError;\n\n/* \n * Public \n */\n\nstatic CONF *parse_config(VALUE, CONF*);\n\nCONF *\nGetConfigPtr(VALUE obj)\n{\n    CONF *conf;\n\n    SafeGetConfig(obj, conf);\n\n    return conf;\n}\n\nCONF *\nDupConfigPtr(VALUE obj)\n{\n    VALUE str;\n\n    OSSL_Check_Kind(obj, cConfig);\n    str = rb_funcall(obj, rb_intern(\"to_s\"), 0);\n\n    return parse_config(str, NULL);\n}\n\n/*\n * Private\n */\nstatic CONF *\nparse_config(VALUE str, CONF *dst)\n{\n    CONF *conf;\n    BIO *bio;\n    long eline = -1;\n\n    bio = ossl_obj2bio(str);\n    conf = dst ? dst : NCONF_new(NULL);\n    if(!conf){\n\tBIO_free(bio);\n\tossl_raise(eConfigError, NULL);\n    }\n    if(!NCONF_load_bio(conf, bio, &eline)){\n\tBIO_free(bio);\n\tif(!dst) NCONF_free(conf);\n\tif (eline <= 0) ossl_raise(eConfigError, \"wrong config format\");\n\telse ossl_raise(eConfigError, \"error in line %d\", eline);\n\tossl_raise(eConfigError, NULL);\n    }\n    BIO_free(bio);\n\n    return conf;\n}\n\nstatic VALUE\nossl_config_s_parse(VALUE klass, VALUE str)\n{\n    CONF *conf;\n    VALUE obj;\n\n    conf = parse_config(str, NULL);\n    WrapConfig(klass, obj, conf);\n\n    return obj;\n}\n\nstatic VALUE\nossl_config_s_alloc(VALUE klass)\n{\n    CONF *conf;\n    VALUE obj;\n\n    if(!(conf = NCONF_new(NULL)))\n\tossl_raise(eConfigError, NULL);\n    WrapConfig(klass, obj, conf);\n\n    return obj;\n}\n\nstatic VALUE\nossl_config_copy(VALUE self, VALUE other)\n{\n    VALUE str;\n    CONF *conf;\n\n    str = rb_funcall(self, rb_intern(\"to_s\"), 0);\n    GetConfig(other, conf);\n    parse_config(str, conf);\n\n    return self;\n}\n\nstatic VALUE\nossl_config_initialize(int argc, VALUE *argv, VALUE self)\n{\n    CONF *conf;\n    long eline = -1;\n    char *filename;\n    VALUE path;\n\n    rb_scan_args(argc, argv, \"01\", &path);\n    if(!NIL_P(path)){\n\tSafeStringValue(path);\n        filename = StringValuePtr(path);\n\tGetConfig(self, conf);\n\tif (!NCONF_load(conf, filename, &eline)){\n\t    if (eline <= 0)\n\t\tossl_raise(eConfigError, \"wrong config file %s\", filename);\n\t    else\n\t\tossl_raise(eConfigError, \"error in %s:%d\", filename, eline);\n        }\n    }\n#ifdef OSSL_NO_CONF_API\n    else rb_raise(rb_eArgError, \"wrong number of arguments (0 for 1)\");\n#else\n    else {\n\tGetConfig(self, conf);\n\t_CONF_new_data(conf);\n    }\n#endif\n    \n    return self;\n}\n\nstatic void\nrb_ossl_config_modify_check(VALUE config)\n{\n    if (OBJ_FROZEN(config)) rb_error_frozen(\"OpenSSL::Config\");\n    if (!OBJ_TAINTED(config) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify OpenSSL config\");\n}\n\nstatic VALUE\nossl_config_add_value(VALUE self, VALUE section, VALUE name, VALUE value)\n{\n#ifdef OSSL_NO_CONF_API\n    rb_notimplement();\n#else\n    CONF *conf;\n    CONF_VALUE *sv, *cv;\n\n    rb_ossl_config_modify_check(self);\n    StringValue(section);\n    StringValue(name);\n    StringValue(value);\n    GetConfig(self, conf);\n    if(!(sv = _CONF_get_section(conf, RSTRING_PTR(section)))){\n\tif(!(sv = _CONF_new_section(conf, RSTRING_PTR(section)))){\n\t    ossl_raise(eConfigError, NULL);\n\t}\n    }\n    if(!(cv = OPENSSL_malloc(sizeof(CONF_VALUE)))){\n\tossl_raise(eConfigError, NULL);\n    }\n    cv->name = BUF_strdup(RSTRING_PTR(name));\n    cv->value = BUF_strdup(RSTRING_PTR(value));\n    if(!cv->name || !cv->value || !_CONF_add_string(conf, sv, cv)){\n\tOPENSSL_free(cv->name);\n\tOPENSSL_free(cv->value);\n\tOPENSSL_free(cv);\n\tossl_raise(eConfigError, \"_CONF_add_string failure\");\n    }\n    \n    return value;\n#endif\n}\n\nstatic VALUE\nossl_config_get_value(VALUE self, VALUE section, VALUE name)\n{\n    CONF *conf;\n    char *str;\n\n    StringValue(section);\n    StringValue(name);\n    GetConfig(self, conf);\n    str = NCONF_get_string(conf, RSTRING_PTR(section), RSTRING_PTR(name));\n    if(!str){\n\tERR_clear_error();\n\treturn Qnil;\n    }\n\n    return rb_str_new2(str);\n}\n\nstatic VALUE\nossl_config_get_value_old(int argc, VALUE *argv, VALUE self)\n{\n    VALUE section, name;\n    \n    rb_scan_args(argc, argv, \"11\", &section, &name);\n\n    /* support conf.value(nil, \"HOME\") -> conf.get_value(\"\", \"HOME\") */\n    if (NIL_P(section)) section = rb_str_new2(\"\");\n    /* support conf.value(\"HOME\") -> conf.get_value(\"\", \"HOME\") */\n    if (NIL_P(name)) {\n\tname = section;\n\tsection = rb_str_new2(\"\");\n    }\n    /* NOTE: Don't care about conf.get_value(nil, nil) */\n    rb_warn(\"Config#value is deprecated; use Config#get_value\");\n    return ossl_config_get_value(self, section, name);\n}\n\nstatic VALUE\nset_conf_section_i(VALUE i, VALUE *arg)\n{\n    VALUE name, value;\n\n    Check_Type(i, T_ARRAY);\n    name = rb_ary_entry(i, 0);\n    value = rb_ary_entry(i, 1);\n    ossl_config_add_value(arg[0], arg[1], name, value);\n\n    return Qnil;\n}\n\nstatic VALUE\nossl_config_set_section(VALUE self, VALUE section, VALUE hash)\n{\n    VALUE arg[2];\n\n    rb_ossl_config_modify_check(self);\n    arg[0] = self;\n    arg[1] = section;\n    rb_block_call(hash, rb_intern(\"each\"), 0, 0, set_conf_section_i, (VALUE)arg);\n    return hash;\n}\n\n/*\n * Get all numbers as strings - use str.to_i to convert\n * long number = CONF_get_number(confp->config, sect, StringValuePtr(item));\n */\nstatic VALUE\nossl_config_get_section(VALUE self, VALUE section)\n{\n    CONF *conf;\n    STACK_OF(CONF_VALUE) *sk;\n    CONF_VALUE *entry;\n    int i, entries;\n    VALUE hash;\n\n    hash = rb_hash_new();\n    StringValue(section);\n    GetConfig(self, conf);\n    if (!(sk = NCONF_get_section(conf, StringValuePtr(section)))) {\n\tERR_clear_error();\n\treturn hash;\n    }\n    if ((entries = sk_CONF_VALUE_num(sk)) < 0) {\n\tOSSL_Debug(\"# of items in section is < 0?!?\");\n\treturn hash;\n    }\n    for (i=0; i<entries; i++) {\n\tentry = sk_CONF_VALUE_value(sk, i);\t\t\n\trb_hash_aset(hash, rb_str_new2(entry->name), rb_str_new2(entry->value));\n    }\n\n    return hash;\n}\n\nstatic VALUE\nossl_config_get_section_old(VALUE self, VALUE section)\n{\n    rb_warn(\"Config#section is deprecated; use Config#[]\");\n    return ossl_config_get_section(self, section);\n}\n\n#ifdef IMPLEMENT_LHASH_DOALL_ARG_FN\nstatic void\nget_conf_section(CONF_VALUE *cv, VALUE ary)\n{\n    if(cv->name) return;\n    rb_ary_push(ary, rb_str_new2(cv->section));\n}\n\nstatic IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE*, VALUE);\n\nstatic VALUE\nossl_config_get_sections(VALUE self)\n{\n    CONF *conf;\n    VALUE ary;\n\n    GetConfig(self, conf);\n    ary = rb_ary_new();\n    lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(get_conf_section), (void*)ary);\n\n    return ary;\n}\n\nstatic void\ndump_conf_value(CONF_VALUE *cv, VALUE str)\n{\n    STACK_OF(CONF_VALUE) *sk;\n    CONF_VALUE *v;\n    int i, num;\n\n    if (cv->name) return;\n    sk = (STACK_OF(CONF_VALUE)*)cv->value;\n    num = sk_CONF_VALUE_num(sk);\n    rb_str_cat2(str, \"[ \");\n    rb_str_cat2(str, cv->section);\n    rb_str_cat2(str, \" ]\\n\");\n    for(i = 0; i < num; i++){\n\tv = sk_CONF_VALUE_value(sk, i);\n\trb_str_cat2(str, v->name ? v->name : \"None\");\n\trb_str_cat2(str, \"=\");\n\trb_str_cat2(str, v->value ? v->value : \"None\");\n\trb_str_cat2(str, \"\\n\");\n    }\n    rb_str_cat2(str, \"\\n\");\n}\n\nstatic IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE*, VALUE);\n\nstatic VALUE\ndump_conf(CONF *conf)\n{\n    VALUE str;\n\n    str = rb_str_new(0, 0);\n    lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_conf_value), (void*)str);\n\n    return str;\n}\n\nstatic VALUE\nossl_config_to_s(VALUE self)\n{\n    CONF *conf;\n\n    GetConfig(self, conf);\n\n    return dump_conf(conf);\n}\n\nstatic void\neach_conf_value(CONF_VALUE *cv, void* dummy)\n{\n    STACK_OF(CONF_VALUE) *sk;\n    CONF_VALUE *v;\n    VALUE section, name, value, args;\n    int i, num;\n\n    if (cv->name) return;\n    sk = (STACK_OF(CONF_VALUE)*)cv->value;\n    num = sk_CONF_VALUE_num(sk);\n    section = rb_str_new2(cv->section);\n    for(i = 0; i < num; i++){\n\tv = sk_CONF_VALUE_value(sk, i);\n\tname = v->name ? rb_str_new2(v->name) : Qnil;\n\tvalue = v->value ? rb_str_new2(v->value) : Qnil;\n        args = rb_ary_new3(3, section, name, value);\n\trb_yield(args);\n    }\n}\n\nstatic IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE*, void*);\n\nstatic VALUE\nossl_config_each(VALUE self)\n{\n    CONF *conf;\n\n    GetConfig(self, conf);\n    lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(each_conf_value), (void*)NULL);\n\n    return self;\n}\n#else\nstatic VALUE\nossl_config_get_sections(VALUE self)\n{\n    rb_warn(\"#sections don't work with %s\", OPENSSL_VERSION_TEXT);\n    return rb_ary_new();\n}\n\nstatic VALUE\nossl_config_to_s(VALUE self)\n{\n    rb_warn(\"#to_s don't work with %s\", OPENSSL_VERSION_TEXT);\n    return rb_str_new(0, 0);\n}\n\nstatic VALUE\nossl_config_each(VALUE self)\n{\n    rb_warn(\"#each don't work with %s\", OPENSSL_VERSION_TEXT);\n    return self;\n}\n#endif\n\nstatic VALUE\nossl_config_inspect(VALUE self)\n{\n    VALUE str, ary = ossl_config_get_sections(self);\n    char *cname = rb_class2name(rb_obj_class(self));\n\n    str = rb_str_new2(\"#<\");\n    rb_str_cat2(str, cname);\n    rb_str_cat2(str, \" sections=\");\n    rb_str_append(str, rb_inspect(ary));\n    rb_str_cat2(str, \">\");\n\n    return str;\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_config()\n{\n    eConfigError = rb_define_class_under(mOSSL, \"ConfigError\", eOSSLError);\n    cConfig = rb_define_class_under(mOSSL, \"Config\", rb_cObject);\n\n    rb_define_const(cConfig, \"DEFAULT_CONFIG_FILE\",\n\t\t    rb_str_new2(CONF_get1_default_config_file()));\n    rb_include_module(cConfig, rb_mEnumerable);\n    rb_define_singleton_method(cConfig, \"parse\", ossl_config_s_parse, 1);\n    rb_define_alias(CLASS_OF(cConfig), \"load\", \"new\");\n    rb_define_alloc_func(cConfig, ossl_config_s_alloc);\n    rb_define_copy_func(cConfig, ossl_config_copy);\n    rb_define_method(cConfig, \"initialize\", ossl_config_initialize, -1);\n    rb_define_method(cConfig, \"get_value\", ossl_config_get_value, 2);\n    rb_define_method(cConfig, \"value\", ossl_config_get_value_old, -1);\n    rb_define_method(cConfig, \"add_value\", ossl_config_add_value, 3);\n    rb_define_method(cConfig, \"[]\", ossl_config_get_section, 1);\n    rb_define_method(cConfig, \"section\", ossl_config_get_section_old, 1);\n    rb_define_method(cConfig, \"[]=\", ossl_config_set_section, 2);\n    rb_define_method(cConfig, \"sections\", ossl_config_get_sections, 0);\n    rb_define_method(cConfig, \"to_s\", ossl_config_to_s, 0);\n    rb_define_method(cConfig, \"each\", ossl_config_each, 0);\n    rb_define_method(cConfig, \"inspect\", ossl_config_inspect, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_config.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_CONFIG_H_)\n#define _OSSL_CONFIG_H_\n\nextern VALUE cConfig;\nextern VALUE eConfigError;\n\nCONF* GetConfigPtr(VALUE obj);\nCONF* DupConfigPtr(VALUE obj);\nvoid Init_ossl_config(void);\n\n#endif /* _OSSL_CONFIG_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_digest.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define GetDigest(obj, ctx) do { \\\n    Data_Get_Struct(obj, EVP_MD_CTX, ctx); \\\n    if (!ctx) { \\\n\tossl_raise(rb_eRuntimeError, \"Digest CTX wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetDigest(obj, ctx) do { \\\n    OSSL_Check_Kind(obj, cDigest); \\\n    GetDigest(obj, ctx); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cDigest;\nVALUE eDigestError;\n\nstatic VALUE ossl_digest_alloc(VALUE klass);\n\n/*\n * Public\n */\nconst EVP_MD *\nGetDigestPtr(VALUE obj)\n{\n    const EVP_MD *md;\n\n    if (TYPE(obj) == T_STRING) {\n    \tconst char *name = STR2CSTR(obj);\n\n        md = EVP_get_digestbyname(name);\n        if (!md)\n            ossl_raise(rb_eRuntimeError, \"Unsupported digest algorithm (%s).\", name);\n    } else {\n        EVP_MD_CTX *ctx;\n\n        SafeGetDigest(obj, ctx);\n\n        md = EVP_MD_CTX_md(ctx);\n    }\n\n    return md;\n}\n\nVALUE\nossl_digest_new(const EVP_MD *md)\n{  \n    VALUE ret;\n    EVP_MD_CTX *ctx;\n\n    ret = ossl_digest_alloc(cDigest);\n    GetDigest(ret, ctx);\n    EVP_DigestInit_ex(ctx, md, NULL);\n   \n    return ret;\n}\n\n/*\n * Private\n */\nstatic VALUE\nossl_digest_alloc(VALUE klass)\n{\n    EVP_MD_CTX *ctx;\n    VALUE obj;\n\n    ctx = EVP_MD_CTX_create();\n    if (ctx == NULL)\n\tossl_raise(rb_eRuntimeError, \"EVP_MD_CTX_create() failed\");\n    obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx);\n\n    return obj;\n}\n\nVALUE ossl_digest_update(VALUE, VALUE);\n\n/*\n *  call-seq:\n *     Digest.new(string) -> digest\n *\n */\nstatic VALUE\nossl_digest_initialize(int argc, VALUE *argv, VALUE self)\n{\n    EVP_MD_CTX *ctx;\n    const EVP_MD *md;\n    char *name;\n    VALUE type, data;\n\n    rb_scan_args(argc, argv, \"11\", &type, &data);\n    md = GetDigestPtr(type);\n    if (!NIL_P(data)) StringValue(data);\n\n    GetDigest(self, ctx);\n    EVP_DigestInit_ex(ctx, md, NULL);\n    \n    if (!NIL_P(data)) return ossl_digest_update(self, data);\n    return self;\n}\n\nstatic VALUE\nossl_digest_copy(VALUE self, VALUE other)\n{\n    EVP_MD_CTX *ctx1, *ctx2;\n    \n    rb_check_frozen(self);\n    if (self == other) return self;\n\n    GetDigest(self, ctx1);\n    SafeGetDigest(other, ctx2);\n\n    if (!EVP_MD_CTX_copy(ctx1, ctx2)) {\n\tossl_raise(eDigestError, NULL);\n    }\n    return self;\n}\n\n/*\n *  call-seq:\n *     digest.reset -> self\n *\n */\nstatic VALUE\nossl_digest_reset(VALUE self)\n{\n    EVP_MD_CTX *ctx;\n\n    GetDigest(self, ctx);\n    EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL);\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     digest.update(string) -> aString\n *\n */\nVALUE\nossl_digest_update(VALUE self, VALUE data)\n{\n    EVP_MD_CTX *ctx;\n\n    StringValue(data);\n    GetDigest(self, ctx);\n    EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));\n\n    return self;\n}\n\n/*\n *  call-seq:\n *      digest.finish -> aString\n *\n */\nstatic VALUE\nossl_digest_finish(int argc, VALUE *argv, VALUE self)\n{\n    EVP_MD_CTX *ctx;\n    VALUE str;\n\n    rb_scan_args(argc, argv, \"01\", &str);\n\n    GetDigest(self, ctx);\n\n    if (NIL_P(str)) {\n        str = rb_str_new(NULL, EVP_MD_CTX_size(ctx));\n    } else {\n        StringValue(str);\n        rb_str_resize(str, EVP_MD_CTX_size(ctx));\n    }\n\n    EVP_DigestFinal_ex(ctx, RSTRING_PTR(str), NULL);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *      digest.name -> string\n *\n */\nstatic VALUE\nossl_digest_name(VALUE self)\n{\n    EVP_MD_CTX *ctx;\n\n    GetDigest(self, ctx);\n\n    return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));\n}\n\n/*\n *  call-seq:\n *      digest.digest_size -> integer\n *\n *  Returns the output size of the digest.\n */\nstatic VALUE\nossl_digest_size(VALUE self)\n{\n    EVP_MD_CTX *ctx;\n\n    GetDigest(self, ctx);\n\n    return INT2NUM(EVP_MD_CTX_size(ctx));\n}\n\nstatic VALUE\nossl_digest_block_length(VALUE self)\n{\n    EVP_MD_CTX *ctx;\n\n    GetDigest(self, ctx);\n\n    return INT2NUM(EVP_MD_CTX_block_size(ctx));\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_digest()\n{\n    rb_require(\"openssl\");\n    rb_require(\"digest\");\n\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n\n    cDigest = rb_define_class_under(mOSSL, \"Digest\", rb_path2class(\"Digest::Class\"));\n    eDigestError = rb_define_class_under(cDigest, \"DigestError\", eOSSLError);\n\t\n    rb_define_alloc_func(cDigest, ossl_digest_alloc);\n\n    rb_define_method(cDigest, \"initialize\", ossl_digest_initialize, -1);\n    rb_define_copy_func(cDigest, ossl_digest_copy);\n    rb_define_method(cDigest, \"reset\", ossl_digest_reset, 0);\n    rb_define_method(cDigest, \"update\", ossl_digest_update, 1);\n    rb_define_alias(cDigest, \"<<\", \"update\");\n    rb_define_private_method(cDigest, \"finish\", ossl_digest_finish, -1);\n    rb_define_method(cDigest, \"digest_length\", ossl_digest_size, 0);\n    rb_define_method(cDigest, \"block_length\", ossl_digest_block_length, 0);\n\n    rb_define_method(cDigest, \"name\", ossl_digest_name, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_digest.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_DIGEST_H_)\n#define _OSSL_DIGEST_H_\n\nextern VALUE cDigest;\nextern VALUE eDigestError;\n\nconst EVP_MD *GetDigestPtr(VALUE);\nVALUE ossl_digest_new(const EVP_MD *);\nvoid Init_ossl_digest(void);\n\n#endif /* _OSSL_DIGEST_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_engine.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#if defined(OSSL_ENGINE_ENABLED)\n\n#define WrapEngine(klass, obj, engine) do { \\\n    if (!engine) { \\\n\tossl_raise(rb_eRuntimeError, \"ENGINE wasn't initialized.\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, ENGINE_free, engine); \\\n} while(0)\n#define GetEngine(obj, engine) do { \\\n    Data_Get_Struct(obj, ENGINE, engine); \\\n    if (!engine) { \\\n        ossl_raise(rb_eRuntimeError, \"ENGINE wasn't initialized.\"); \\\n    } \\\n} while (0)\n#define SafeGetEngine(obj, engine) do { \\\n    OSSL_Check_Kind(obj, cEngine); \\\n    GetPKCS7(obj, engine); \\\n} while (0)\n\n/* \n * Classes\n */\nVALUE cEngine;\nVALUE eEngineError;\n\n/*\n * Private\n */\n#define OSSL_ENGINE_LOAD_IF_MATCH(x) \\\ndo{\\\n  if(!strcmp(#x, RSTRING_PTR(name))){\\\n    ENGINE_load_##x();\\\n    return Qtrue;\\\n  }\\\n}while(0)\n\nstatic VALUE\nossl_engine_s_load(int argc, VALUE *argv, VALUE klass)\n{\n#if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES)\n    return Qnil;\n#else\n    VALUE name;\n\n    rb_scan_args(argc, argv, \"01\", &name);\n    if(NIL_P(name)){\n        ENGINE_load_builtin_engines();\n        return Qtrue;\n    }\n    StringValue(name);\n#ifndef OPENSSL_NO_STATIC_ENGINE\n    OSSL_ENGINE_LOAD_IF_MATCH(dynamic);\n    OSSL_ENGINE_LOAD_IF_MATCH(cswift);\n    OSSL_ENGINE_LOAD_IF_MATCH(chil);\n    OSSL_ENGINE_LOAD_IF_MATCH(atalla);\n    OSSL_ENGINE_LOAD_IF_MATCH(nuron);\n    OSSL_ENGINE_LOAD_IF_MATCH(ubsec);\n    OSSL_ENGINE_LOAD_IF_MATCH(aep);\n    OSSL_ENGINE_LOAD_IF_MATCH(sureware);\n    OSSL_ENGINE_LOAD_IF_MATCH(4758cca);\n#endif\n#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO\n    OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);\n#endif\n    OSSL_ENGINE_LOAD_IF_MATCH(openssl);\n    rb_warning(\"no such builtin loader for `%s'\", RSTRING_PTR(name));\n    return Qnil;\n#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */\n}\n\nstatic VALUE\nossl_engine_s_cleanup(VALUE self)\n{\n#if defined(HAVE_ENGINE_CLEANUP)\n    ENGINE_cleanup();\n#endif\n    return Qnil;\n}\n\nstatic VALUE\nossl_engine_s_engines(VALUE klass)\n{\n    ENGINE *e;\n    VALUE ary, obj;\n\n    ary = rb_ary_new();\n    for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){\n        WrapEngine(klass, obj, e);\n        rb_ary_push(ary, obj);\n    }\n\n    return ary;\n}\n\nstatic VALUE\nossl_engine_s_by_id(VALUE klass, VALUE id)\n{\n    ENGINE *e;\n    VALUE obj;\n\n    StringValue(id);\n    ossl_engine_s_load(1, &id, klass);\n    if(!(e = ENGINE_by_id(RSTRING_PTR(id))))\n\tossl_raise(eEngineError, NULL);\n    WrapEngine(klass, obj, e);\n    if(rb_block_given_p()) rb_yield(obj);\n    if(!ENGINE_init(e))\n\tossl_raise(eEngineError, NULL);\n    ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK,\n\t\t0, NULL, (void(*)())ossl_pem_passwd_cb);\n    ERR_clear_error();\n\n    return obj;\n}\n\nstatic VALUE\nossl_engine_s_alloc(VALUE klass)\n{\n    ENGINE *e;\n    VALUE obj;\n\n    if (!(e = ENGINE_new())) {\n       ossl_raise(eEngineError, NULL);\n    }\n    WrapEngine(klass, obj, e);\n\n    return obj;\n}\n\nstatic VALUE\nossl_engine_get_id(VALUE self)\n{\n    ENGINE *e;\n    GetEngine(self, e);\n    return rb_str_new2(ENGINE_get_id(e));\n}\n\nstatic VALUE\nossl_engine_get_name(VALUE self)\n{\n    ENGINE *e;\n    GetEngine(self, e);\n    return rb_str_new2(ENGINE_get_name(e));\n}\n\nstatic VALUE\nossl_engine_finish(VALUE self)\n{\n    ENGINE *e;\n\n    GetEngine(self, e);\n    if(!ENGINE_finish(e)) ossl_raise(eEngineError, NULL);\n\n    return Qnil;\n}\n\nstatic VALUE\nossl_engine_get_cipher(VALUE self, VALUE name)\n{\n#if defined(HAVE_ENGINE_GET_CIPHER)\n    ENGINE *e;\n    const EVP_CIPHER *ciph, *tmp;\n    char *s;\n    int nid;\n\n    s = StringValuePtr(name);\n    tmp = EVP_get_cipherbyname(s);\n    if(!tmp) ossl_raise(eEngineError, \"no such cipher `%s'\", s);\n    nid = EVP_CIPHER_nid(tmp);\n    GetEngine(self, e);\n    ciph = ENGINE_get_cipher(e, nid);\n    if(!ciph) ossl_raise(eEngineError, NULL);\n\n    return ossl_cipher_new(ciph);\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE\nossl_engine_get_digest(VALUE self, VALUE name)\n{\n#if defined(HAVE_ENGINE_GET_DIGEST)\n    ENGINE *e;\n    const EVP_MD *md, *tmp;\n    char *s;\n    int nid;\n\n    s = StringValuePtr(name);\n    tmp = EVP_get_digestbyname(s);\n    if(!tmp) ossl_raise(eEngineError, \"no such digest `%s'\", s);\n    nid = EVP_MD_nid(tmp);\n    GetEngine(self, e);\n    md = ENGINE_get_digest(e, nid);\n    if(!md) ossl_raise(eEngineError, NULL);\n\n    return ossl_digest_new(md);\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE\nossl_engine_load_privkey(int argc, VALUE *argv, VALUE self)\n{\n    ENGINE *e;\n    EVP_PKEY *pkey;\n    VALUE id, data, obj;\n    char *sid, *sdata;\n\n    rb_scan_args(argc, argv, \"02\", &id, &data);\n    sid = NIL_P(id) ? NULL : StringValuePtr(id);\n    sdata = NIL_P(data) ? NULL : StringValuePtr(data);\n    GetEngine(self, e);\n#if OPENSSL_VERSION_NUMBER < 0x00907000L\n    pkey = ENGINE_load_private_key(e, sid, sdata);\n#else\n    pkey = ENGINE_load_private_key(e, sid, NULL, sdata);\n#endif\n    if (!pkey) ossl_raise(eEngineError, NULL);\n    obj = ossl_pkey_new(pkey);\n    OSSL_PKEY_SET_PRIVATE(obj);\n\n    return obj;\n}\n\nstatic VALUE\nossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self)\n{\n    ENGINE *e;\n    EVP_PKEY *pkey;\n    VALUE id, data;\n    char *sid, *sdata;\n\n    rb_scan_args(argc, argv, \"02\", &id, &data);\n    sid = NIL_P(id) ? NULL : StringValuePtr(id);\n    sdata = NIL_P(data) ? NULL : StringValuePtr(data);\n    GetEngine(self, e);\n#if OPENSSL_VERSION_NUMBER < 0x00907000L\n    pkey = ENGINE_load_public_key(e, sid, sdata);\n#else\n    pkey = ENGINE_load_public_key(e, sid, NULL, sdata);\n#endif\n    if (!pkey) ossl_raise(eEngineError, NULL);\n\n    return ossl_pkey_new(pkey);\n}\n\nstatic VALUE\nossl_engine_set_default(VALUE self, VALUE flag)\n{\n    ENGINE *e;\n    int f = NUM2INT(flag);\n\n    GetEngine(self, e);\n    ENGINE_set_default(e, f);\n\n    return Qtrue;\n}\n\nstatic VALUE\nossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self)\n{\n    ENGINE *e;\n    VALUE cmd, val;\n    int ret;\n\n    GetEngine(self, e);\n    rb_scan_args(argc, argv, \"11\", &cmd, &val);\n    StringValue(cmd);\n    if (!NIL_P(val)) StringValue(val);\n    ret = ENGINE_ctrl_cmd_string(e, RSTRING_PTR(cmd),\n\t\t\t\t NIL_P(val) ? NULL : RSTRING_PTR(val), 0);\n    if (!ret) ossl_raise(eEngineError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_engine_cmd_flag_to_name(int flag)\n{\n    switch(flag){\n    case ENGINE_CMD_FLAG_NUMERIC:  return rb_str_new2(\"NUMERIC\");\n    case ENGINE_CMD_FLAG_STRING:   return rb_str_new2(\"STRING\");\n    case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2(\"NO_INPUT\");\n    case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2(\"INTERNAL\");\n    default: return rb_str_new2(\"UNKNOWN\");\n    }\n}\n\nstatic VALUE\nossl_engine_get_cmds(VALUE self)\n{\n    ENGINE *e;\n    const ENGINE_CMD_DEFN *defn, *p;\n    VALUE ary, tmp;\n\n    GetEngine(self, e);\n    ary = rb_ary_new();\n    if ((defn = ENGINE_get_cmd_defns(e)) != NULL){\n\tfor (p = defn; p->cmd_num > 0; p++){\n\t    tmp = rb_ary_new();\n\t    rb_ary_push(tmp, rb_str_new2(p->cmd_name));\n\t    rb_ary_push(tmp, rb_str_new2(p->cmd_desc));\n\t    rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags));\n\t    rb_ary_push(ary, tmp);\n\t}\n    }\n\n    return ary;\n}\n\nstatic VALUE\nossl_engine_inspect(VALUE self)\n{\n    VALUE str;\n    char *cname = rb_class2name(rb_obj_class(self));\n    \n    str = rb_str_new2(\"#<\");\n    rb_str_cat2(str, cname);\n    rb_str_cat2(str, \" id=\\\"\");\n    rb_str_append(str, ossl_engine_get_id(self));\n    rb_str_cat2(str, \"\\\" name=\\\"\");\n    rb_str_append(str, ossl_engine_get_name(self));\n    rb_str_cat2(str, \"\\\">\");\n\n    return str;\n}\n\n#define DefEngineConst(x) rb_define_const(cEngine, #x, INT2NUM(ENGINE_##x))\n\nvoid\nInit_ossl_engine()\n{\n    cEngine = rb_define_class_under(mOSSL, \"Engine\", rb_cObject);\n    eEngineError = rb_define_class_under(cEngine, \"EngineError\", eOSSLError);\n\n    rb_define_alloc_func(cEngine, ossl_engine_s_alloc);\n    rb_define_singleton_method(cEngine, \"load\", ossl_engine_s_load, -1);\n    rb_define_singleton_method(cEngine, \"cleanup\", ossl_engine_s_cleanup, 0);\n    rb_define_singleton_method(cEngine, \"engines\", ossl_engine_s_engines, 0);\n    rb_define_singleton_method(cEngine, \"by_id\", ossl_engine_s_by_id, 1);\n    rb_undef_method(CLASS_OF(cEngine), \"new\");\n\n    rb_define_method(cEngine, \"id\", ossl_engine_get_id, 0);\n    rb_define_method(cEngine, \"name\", ossl_engine_get_name, 0);\n    rb_define_method(cEngine, \"finish\", ossl_engine_finish, 0);\n    rb_define_method(cEngine, \"cipher\", ossl_engine_get_cipher, 1);\n    rb_define_method(cEngine, \"digest\",  ossl_engine_get_digest, 1);\n    rb_define_method(cEngine, \"load_private_key\", ossl_engine_load_privkey, -1);\n    rb_define_method(cEngine, \"load_public_key\", ossl_engine_load_pubkey, -1);\n    rb_define_method(cEngine, \"set_default\", ossl_engine_set_default, 1);\n    rb_define_method(cEngine, \"ctrl_cmd\", ossl_engine_ctrl_cmd, -1);\n    rb_define_method(cEngine, \"cmds\", ossl_engine_get_cmds, 0);\n    rb_define_method(cEngine, \"inspect\", ossl_engine_inspect, 0);\n\n    DefEngineConst(METHOD_RSA);\n    DefEngineConst(METHOD_DSA);\n    DefEngineConst(METHOD_DH);\n    DefEngineConst(METHOD_RAND);\n#ifdef ENGINE_METHOD_BN_MOD_EXP\n    DefEngineConst(METHOD_BN_MOD_EXP);\n#endif\n#ifdef ENGINE_METHOD_BN_MOD_EXP_CRT\n    DefEngineConst(METHOD_BN_MOD_EXP_CRT);\n#endif\n#ifdef ENGINE_METHOD_CIPHERS\n    DefEngineConst(METHOD_CIPHERS);\n#endif\n#ifdef ENGINE_METHOD_DIGESTS\n    DefEngineConst(METHOD_DIGESTS);\n#endif\n    DefEngineConst(METHOD_ALL);\n    DefEngineConst(METHOD_NONE);\n}\n#else\nvoid\nInit_ossl_engine()\n{\n}\n#endif\n"
  },
  {
    "path": "ext/openssl/ossl_engine.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(OSSL_ENGINE_H)\n#define OSSL_ENGINE_H\n\nextern VALUE cEngine;\nextern VALUE eEngineError;\n\nvoid Init_ossl_engine(void);\n\n#endif /* OSSL_ENGINE_H */\n"
  },
  {
    "path": "ext/openssl/ossl_hmac.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(OPENSSL_NO_HMAC)\n\n#include \"ossl.h\"\n\n#define MakeHMAC(obj, klass, ctx) \\\n    obj = Data_Make_Struct(klass, HMAC_CTX, 0, ossl_hmac_free, ctx)\n#define GetHMAC(obj, ctx) do { \\\n    Data_Get_Struct(obj, HMAC_CTX, ctx); \\\n    if (!ctx) { \\\n\tossl_raise(rb_eRuntimeError, \"HMAC wasn't initialized\"); \\\n    } \\\n} while (0)\n#define SafeGetHMAC(obj, ctx) do { \\\n    OSSL_Check_Kind(obj, cHMAC); \\\n    GetHMAC(obj, ctx); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cHMAC;\nVALUE eHMACError;\n\n/*\n * Public\n */\n\n/*\n * Private\n */\nstatic void\nossl_hmac_free(HMAC_CTX *ctx)\n{\n    HMAC_CTX_cleanup(ctx);\n    free(ctx);\n}\n\nstatic VALUE\nossl_hmac_alloc(VALUE klass)\n{\n    HMAC_CTX *ctx;\n    VALUE obj;\n\n    MakeHMAC(obj, klass, ctx);\n    HMAC_CTX_init(ctx);\n\t\n    return obj;\n}\n\n\n/*\n *  call-seq:\n *     HMAC.new(key, digest) -> hmac\n *\n */\nstatic VALUE\nossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)\n{\n    HMAC_CTX *ctx;\n\n    StringValue(key);\n    GetHMAC(self, ctx);\n    HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LEN(key),\n\t\t GetDigestPtr(digest), NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_hmac_copy(VALUE self, VALUE other)\n{\n    HMAC_CTX *ctx1, *ctx2;\n    \n    rb_check_frozen(self);\n    if (self == other) return self;\n\n    GetHMAC(self, ctx1);\n    SafeGetHMAC(other, ctx2);\n\n    HMAC_CTX_copy(ctx1, ctx2);\n    return self;\n}\n\n/*\n *  call-seq:\n *     hmac.update(string) -> self\n *\n */\nstatic VALUE\nossl_hmac_update(VALUE self, VALUE data)\n{\n    HMAC_CTX *ctx;\n\n    StringValue(data);\n    GetHMAC(self, ctx);\n    HMAC_Update(ctx, RSTRING_PTR(data), RSTRING_LEN(data));\n\n    return self;\n}\n\nstatic void\nhmac_final(HMAC_CTX *ctx, char **buf, int *buf_len)\n{\n    HMAC_CTX final;\n\n    HMAC_CTX_copy(&final, ctx);\n    if (!(*buf = OPENSSL_malloc(HMAC_size(&final)))) {\n\tHMAC_CTX_cleanup(&final);\n\tOSSL_Debug(\"Allocating %d mem\", HMAC_size(&final));\n\tossl_raise(eHMACError, \"Cannot allocate memory for hmac\");\n    }\n    HMAC_Final(&final, *buf, buf_len);\n    HMAC_CTX_cleanup(&final);\n}\n\n/*\n *  call-seq:\n *     hmac.digest -> aString\n *\n */\nstatic VALUE\nossl_hmac_digest(VALUE self)\n{\n    HMAC_CTX *ctx;\n    char *buf;\n    int buf_len;\n    VALUE digest;\n\t\n    GetHMAC(self, ctx);\n    hmac_final(ctx, &buf, &buf_len);\n    digest = ossl_buf2str(buf, buf_len);\n    \n    return digest;\n}\n\n/*\n *  call-seq:\n *     hmac.hexdigest -> aString\n *\n */\nstatic VALUE\nossl_hmac_hexdigest(VALUE self)\n{\n    HMAC_CTX *ctx;\n    char *buf, *hexbuf;\n    int buf_len;\n    VALUE hexdigest;\n\t\n    GetHMAC(self, ctx);\n    hmac_final(ctx, &buf, &buf_len);\n    if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * buf_len) {\n\tOPENSSL_free(buf);\n\tossl_raise(eHMACError, \"Memory alloc error\");\n    }\n    OPENSSL_free(buf);\n    hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);\n\n    return hexdigest;\n}\n\n/*\n *  call-seq:\n *     hmac.reset -> self\n *\n */\nstatic VALUE\nossl_hmac_reset(VALUE self)\n{\n    HMAC_CTX *ctx;\n\n    GetHMAC(self, ctx);\n    HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     HMAC.digest(digest, key, data) -> aString\n *\n */\nstatic VALUE\nossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)\n{\n    char *buf;\n    int buf_len;\n\t\n    StringValue(key);\n    StringValue(data);\n    buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LEN(key),\n\t       RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);\n\n    return rb_str_new(buf, buf_len);\n}\n\n/*\n *  call-seq:\n *     HMAC.digest(digest, key, data) -> aString\n *\n */\nstatic VALUE\nossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)\n{\n    char *buf, *hexbuf;\n    int buf_len;\n    VALUE hexdigest;\n\n    StringValue(key);\n    StringValue(data);\n\t\n    buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LEN(key),\n\t       RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);\n    if (string2hex(buf, buf_len, &hexbuf, NULL) != 2 * buf_len) {\n\tossl_raise(eHMACError, \"Cannot convert buf to hexbuf\");\n    }\n    hexdigest = ossl_buf2str(hexbuf, 2 * buf_len);\n\n    return hexdigest;\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_hmac()\n{\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n\n    eHMACError = rb_define_class_under(mOSSL, \"HMACError\", eOSSLError);\n\t\n    cHMAC = rb_define_class_under(mOSSL, \"HMAC\", rb_cObject);\n\n    rb_define_alloc_func(cHMAC, ossl_hmac_alloc);\n    rb_define_singleton_method(cHMAC, \"digest\", ossl_hmac_s_digest, 3);\n    rb_define_singleton_method(cHMAC, \"hexdigest\", ossl_hmac_s_hexdigest, 3);\n    \n    rb_define_method(cHMAC, \"initialize\", ossl_hmac_initialize, 2);\n    rb_define_copy_func(cHMAC, ossl_hmac_copy);\n\n    rb_define_method(cHMAC, \"reset\", ossl_hmac_reset, 0);\n    rb_define_method(cHMAC, \"update\", ossl_hmac_update, 1);\n    rb_define_alias(cHMAC, \"<<\", \"update\");\n    rb_define_method(cHMAC, \"digest\", ossl_hmac_digest, 0);\n    rb_define_method(cHMAC, \"hexdigest\", ossl_hmac_hexdigest, 0);\n    rb_define_alias(cHMAC, \"inspect\", \"hexdigest\");\n    rb_define_alias(cHMAC, \"to_s\", \"hexdigest\");\n}\n\n#else /* NO_HMAC */\n#  warning >>> OpenSSL is compiled without HMAC support <<<\nvoid\nInit_ossl_hmac()\n{\n    rb_warning(\"HMAC will NOT be avaible: OpenSSL is compiled without HMAC.\");\n}\n#endif /* NO_HMAC */\n"
  },
  {
    "path": "ext/openssl/ossl_hmac.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_HMAC_H_)\n#define _OSSL_HMAC_H_\n\nextern VALUE cHMAC;\nextern VALUE eHMACError;\n\nvoid Init_ossl_hmac(void);\n\n#endif /* _OSSL_HMAC_H_ */\n"
  },
  {
    "path": "ext/openssl/ossl_ns_spki.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapSPKI(klass, obj, spki) do { \\\n    if (!spki) { \\\n\tossl_raise(rb_eRuntimeError, \"SPKI wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, NETSCAPE_SPKI_free, spki); \\\n} while (0)\n#define GetSPKI(obj, spki) do { \\\n    Data_Get_Struct(obj, NETSCAPE_SPKI, spki); \\\n    if (!spki) { \\\n\tossl_raise(rb_eRuntimeError, \"SPKI wasn't initialized!\"); \\\n    } \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE mNetscape;\nVALUE cSPKI;\nVALUE eSPKIError;\n\n/*\n * Public functions\n */\n\n/*\n * Private functions\n */\nstatic VALUE\nossl_spki_alloc(VALUE klass)\n{\n    NETSCAPE_SPKI *spki;\n    VALUE obj;\n\t\n    if (!(spki = NETSCAPE_SPKI_new())) {\n\tossl_raise(eSPKIError, NULL);\n    }\t\n    WrapSPKI(klass, obj, spki);\n\t\n    return obj;\n}\n\nstatic VALUE\nossl_spki_initialize(int argc, VALUE *argv, VALUE self)\n{\n    NETSCAPE_SPKI *spki;\n    VALUE buffer;\n    unsigned char *p;\n\t\n    if (rb_scan_args(argc, argv, \"01\", &buffer) == 0) {\n\treturn self;\n    }\n    StringValue(buffer);\n    if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), -1))) {\n\tp = RSTRING_PTR(buffer);\n\tif (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {\n\t    ossl_raise(eSPKIError, NULL);\n\t}\n    }\n    NETSCAPE_SPKI_free(DATA_PTR(self));\n    DATA_PTR(self) = spki;\n    ERR_clear_error();\n\n    return self;\n}\n\nstatic VALUE\nossl_spki_to_der(VALUE self)\n{\n    NETSCAPE_SPKI *spki;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetSPKI(self, spki);\n    if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0)\n        ossl_raise(eX509CertError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)\n        ossl_raise(eX509CertError, NULL);\n    ossl_str_adjust(str, p);\n    \n    return str;\n}\n\nstatic VALUE\nossl_spki_to_pem(VALUE self)\n{\n    NETSCAPE_SPKI *spki;\n    char *data;\n    VALUE str;\n\t\n    GetSPKI(self, spki);\n    if (!(data = NETSCAPE_SPKI_b64_encode(spki))) {\n\tossl_raise(eSPKIError, NULL);\n    }\n    str = ossl_buf2str(data, strlen(data));\n\n    return str;\n}\n\nstatic VALUE\nossl_spki_print(VALUE self)\n{\n    NETSCAPE_SPKI *spki;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\t\n    GetSPKI(self, spki);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eSPKIError, NULL);\n    }\n    if (!NETSCAPE_SPKI_print(out, spki)) {\n\tBIO_free(out);\n\tossl_raise(eSPKIError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n\t\n    return str;\n}\n\nstatic VALUE\nossl_spki_get_public_key(VALUE self)\n{\n    NETSCAPE_SPKI *spki;\n    EVP_PKEY *pkey;\n\n    GetSPKI(self, spki);\n    if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */\n\tossl_raise(eSPKIError, NULL);\n    }\n\n    return ossl_pkey_new(pkey); /* NO DUP - OK */\n}\n\nstatic VALUE\nossl_spki_set_public_key(VALUE self, VALUE key)\n{\n    NETSCAPE_SPKI *spki;\n\n    GetSPKI(self, spki);\n    if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */\n\tossl_raise(eSPKIError, NULL);\n    }\n\n    return key;\n}\n\nstatic VALUE\nossl_spki_get_challenge(VALUE self)\n{\n    NETSCAPE_SPKI *spki;\n\n    GetSPKI(self, spki);\n    if (spki->spkac->challenge->length <= 0) {\n\tOSSL_Debug(\"Challenge.length <= 0?\");\n\treturn rb_str_new(0, 0);\n    }\n\n    return rb_str_new(spki->spkac->challenge->data,\n\t\t      spki->spkac->challenge->length);\n}\n\nstatic VALUE\nossl_spki_set_challenge(VALUE self, VALUE str)\n{\n    NETSCAPE_SPKI *spki;\n\n    StringValue(str);\n    GetSPKI(self, spki);\n    if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str),\n\t\t\t RSTRING_LEN(str))) {\n\tossl_raise(eSPKIError, NULL);\n    }\n    \n    return str;\n}\n\nstatic VALUE\nossl_spki_sign(VALUE self, VALUE key, VALUE digest)\n{\n    NETSCAPE_SPKI *spki;\n    EVP_PKEY *pkey;\n    const EVP_MD *md;\n\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    md = GetDigestPtr(digest);\n    GetSPKI(self, spki);\n    if (!NETSCAPE_SPKI_sign(spki, pkey, md)) {\n\tossl_raise(eSPKIError, NULL);\n    }\n\n    return self;\n}\n\n/*\n * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'\n */\nstatic VALUE\nossl_spki_verify(VALUE self, VALUE key)\n{\n    NETSCAPE_SPKI *spki;\n\n    GetSPKI(self, spki);\n    switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */\n    case 0:\n\treturn Qfalse;\n    case 1:\n\treturn Qtrue;\n    default:\n\tossl_raise(eSPKIError, NULL);\n    }\n    return Qnil; /* dummy */\n}\n\n/*\n * NETSCAPE_SPKI init\n */\nvoid\nInit_ossl_ns_spki()\n{\n    mNetscape = rb_define_module_under(mOSSL, \"Netscape\");\n\t\n    eSPKIError = rb_define_class_under(mNetscape, \"SPKIError\", eOSSLError);\n\t\n    cSPKI = rb_define_class_under(mNetscape, \"SPKI\", rb_cObject);\n\t\n    rb_define_alloc_func(cSPKI, ossl_spki_alloc);\n    rb_define_method(cSPKI, \"initialize\", ossl_spki_initialize, -1);\n\t\n    rb_define_method(cSPKI, \"to_der\", ossl_spki_to_der, 0);\n    rb_define_method(cSPKI, \"to_pem\", ossl_spki_to_pem, 0);\n    rb_define_alias(cSPKI, \"to_s\", \"to_pem\");\n    rb_define_method(cSPKI, \"to_text\", ossl_spki_print, 0);\n    rb_define_method(cSPKI, \"public_key\", ossl_spki_get_public_key, 0);\n    rb_define_method(cSPKI, \"public_key=\", ossl_spki_set_public_key, 1);\n    rb_define_method(cSPKI, \"sign\", ossl_spki_sign, 2);\n    rb_define_method(cSPKI, \"verify\", ossl_spki_verify, 1);\n    rb_define_method(cSPKI, \"challenge\", ossl_spki_get_challenge, 0);\n    rb_define_method(cSPKI, \"challenge=\", ossl_spki_set_challenge, 1);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_ns_spki.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_NS_SPKI_H_)\n#define _OSSL_NS_SPKI_H_\n\nextern VALUE mNetscape;\nextern VALUE cSPKI;\nextern VALUE eSPKIError;\n\nvoid Init_ossl_ns_spki(void);\n\n#endif /* _OSSL_NS_SPKI_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_ocsp.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#if defined(OSSL_OCSP_ENABLED)\n\n#define WrapOCSPReq(klass, obj, req) do { \\\n    if(!req) ossl_raise(rb_eRuntimeError, \"Request wasn't initialized!\"); \\\n    obj = Data_Wrap_Struct(klass, 0, OCSP_REQUEST_free, req); \\\n} while (0)\n#define GetOCSPReq(obj, req) do { \\\n    Data_Get_Struct(obj, OCSP_REQUEST, req); \\\n    if(!req) ossl_raise(rb_eRuntimeError, \"Request wasn't initialized!\"); \\\n} while (0)\n#define SafeGetOCSPReq(obj, req) do { \\\n    OSSL_Check_Kind(obj, cOCSPReq); \\\n    GetOCSPReq(obj, req); \\\n} while (0)\n\n#define WrapOCSPRes(klass, obj, res) do { \\\n    if(!res) ossl_raise(rb_eRuntimeError, \"Response wasn't initialized!\"); \\\n    obj = Data_Wrap_Struct(klass, 0, OCSP_RESPONSE_free, res); \\\n} while (0)\n#define GetOCSPRes(obj, res) do { \\\n    Data_Get_Struct(obj, OCSP_RESPONSE, res); \\\n    if(!res) ossl_raise(rb_eRuntimeError, \"Response wasn't initialized!\"); \\\n} while (0)\n#define SafeGetOCSPRes(obj, res) do { \\\n    OSSL_Check_Kind(obj, cOCSPRes); \\\n    GetOCSPRes(obj, res); \\\n} while (0)\n\n#define WrapOCSPBasicRes(klass, obj, res) do { \\\n    if(!res) ossl_raise(rb_eRuntimeError, \"Response wasn't initialized!\"); \\\n    obj = Data_Wrap_Struct(klass, 0, OCSP_BASICRESP_free, res); \\\n} while (0)\n#define GetOCSPBasicRes(obj, res) do { \\\n    Data_Get_Struct(obj, OCSP_BASICRESP, res); \\\n    if(!res) ossl_raise(rb_eRuntimeError, \"Response wasn't initialized!\"); \\\n} while (0)\n#define SafeGetOCSPBasicRes(obj, res) do { \\\n    OSSL_Check_Kind(obj, cOCSPBasicRes); \\\n    GetOCSPBasicRes(obj, res); \\\n} while (0)\n\n#define WrapOCSPCertId(klass, obj, cid) do { \\\n    if(!cid) ossl_raise(rb_eRuntimeError, \"Cert ID wasn't initialized!\"); \\\n    obj = Data_Wrap_Struct(klass, 0, OCSP_CERTID_free, cid); \\\n} while (0)\n#define GetOCSPCertId(obj, cid) do { \\\n    Data_Get_Struct(obj, OCSP_CERTID, cid); \\\n    if(!cid) ossl_raise(rb_eRuntimeError, \"Cert ID wasn't initialized!\"); \\\n} while (0)\n#define SafeGetOCSPCertId(obj, cid) do { \\\n    OSSL_Check_Kind(obj, cOCSPCertId); \\\n    GetOCSPCertId(obj, cid); \\\n} while (0)\n\nVALUE mOCSP;\nVALUE eOCSPError;\nVALUE cOCSPReq;\nVALUE cOCSPRes;\nVALUE cOCSPBasicRes;\nVALUE cOCSPCertId;\n\n/*\n * Public\n */\nstatic VALUE\nossl_ocspcertid_new(OCSP_CERTID *cid)\n{\n    VALUE obj;\n    WrapOCSPCertId(cOCSPCertId, obj, cid);\n    return obj;\n}\n\n/*\n * OCSP::Resquest\n */\nstatic VALUE\nossl_ocspreq_alloc(VALUE klass)\n{\n    OCSP_REQUEST *req;\n    VALUE obj;\n\n    if (!(req = OCSP_REQUEST_new()))\n\tossl_raise(eOCSPError, NULL);\n    WrapOCSPReq(klass, obj, req);\n\n    return obj;\n}\n\nstatic VALUE\nossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE arg;\n    unsigned char *p;\n\n    rb_scan_args(argc, argv, \"01\", &arg);\n    if(!NIL_P(arg)){\n\targ = ossl_to_der_if_possible(arg);\n\tStringValue(arg);\n\tp = (unsigned char*)RSTRING_PTR(arg);\n\tif(!d2i_OCSP_REQUEST((OCSP_REQUEST**)&DATA_PTR(self), &p,\n\t\t\t     RSTRING_LEN(arg))){\n\t    ossl_raise(eOCSPError, \"cannot load DER encoded request\");\n\t}\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)\n{\n    OCSP_REQUEST *req;\n    VALUE val;\n    int ret;\n\n    rb_scan_args(argc, argv, \"01\", &val);\n    if(NIL_P(val)) {\n\tGetOCSPReq(self, req);\n\tret = OCSP_request_add1_nonce(req, NULL, -1);\n    }\n    else{\n\tStringValue(val);\n\tGetOCSPReq(self, req);\n\tret = OCSP_request_add1_nonce(req, RSTRING_PTR(val), RSTRING_LEN(val));\n    }\n    if(!ret) ossl_raise(eOCSPError, NULL);\n\n    return self;\n}\n\n/* Check nonce validity in a request and response.\n * Return value reflects result:\n *  1: nonces present and equal.\n *  2: nonces both absent.\n *  3: nonce present in response only.\n *  0: nonces both present and not equal.\n * -1: nonce in request only.\n *\n *  For most responders clients can check return > 0.\n *  If responder doesn't handle nonces return != 0 may be\n *  necessary. return == 0 is always an error.\n */\nstatic VALUE\nossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)\n{\n    OCSP_REQUEST *req;\n    OCSP_BASICRESP *bs;\n    int res;\n\n    GetOCSPReq(self, req);\n    SafeGetOCSPBasicRes(basic_resp, bs);\n    res = OCSP_check_nonce(req, bs);\n\n    return INT2NUM(res);\n}\n\nstatic VALUE\nossl_ocspreq_add_certid(VALUE self, VALUE certid)\n{\n    OCSP_REQUEST *req;\n    OCSP_CERTID *id;\n\n    GetOCSPReq(self, req);\n    GetOCSPCertId(certid, id);\n    if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id)))\n\tossl_raise(eOCSPError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspreq_get_certid(VALUE self)\n{\n    OCSP_REQUEST *req;\n    OCSP_ONEREQ *one;\n    OCSP_CERTID *id;\n    VALUE ary, tmp;\n    int i, count;\n\n    GetOCSPReq(self, req);\n    count = OCSP_request_onereq_count(req);\n    ary = (count > 0) ? rb_ary_new() : Qnil;\n    for(i = 0; i < count; i++){\n\tone = OCSP_request_onereq_get0(req, i);\n\tif(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one))))\n\t    ossl_raise(eOCSPError, NULL);\n\tWrapOCSPCertId(cOCSPCertId, tmp, id);\n\trb_ary_push(ary, tmp);\n    }\n\n    return ary;\n}\n\nstatic VALUE\nossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)\n{\n    VALUE signer_cert, signer_key, certs, flags;\n    OCSP_REQUEST *req;\n    X509 *signer;\n    EVP_PKEY *key;\n    STACK_OF(X509) *x509s;\n    unsigned long flg;\n    int ret;\n\n    rb_scan_args(argc, argv, \"22\", &signer_cert, &signer_key, &certs, &flags);\n    signer = GetX509CertPtr(signer_cert);\n    key = GetPrivPKeyPtr(signer_key);\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    if(NIL_P(certs)){\n\tx509s = sk_X509_new_null();\n\tflags |= OCSP_NOCERTS;\n    }\n    else x509s = ossl_x509_ary2sk(certs);\n    GetOCSPReq(self, req);\n    ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg);\n    sk_X509_pop_free(x509s, X509_free);\n    if(!ret) ossl_raise(eOCSPError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspreq_verify(int argc, VALUE *argv, VALUE self)\n{\n    VALUE certs, store, flags;\n    OCSP_REQUEST *req;\n    STACK_OF(X509) *x509s;\n    X509_STORE *x509st;\n    int flg, result;\n\n    rb_scan_args(argc, argv, \"21\", &certs, &store, &flags);\n    x509st = GetX509StorePtr(store);\n    flg = NIL_P(flags) ? 0 : INT2NUM(flags);\n    x509s = ossl_x509_ary2sk(certs);\n    GetOCSPReq(self, req);\n    result = OCSP_request_verify(req, x509s, x509st, flg);\n    sk_X509_pop_free(x509s, X509_free);\n    if(!result) rb_warn(\"%s\", ERR_error_string(ERR_peek_error(), NULL));\n\n    return result ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_ocspreq_to_der(VALUE self)\n{\n    OCSP_REQUEST *req;\n    VALUE str;\n    unsigned char *p;\n    long len;\n\n    GetOCSPReq(self, req);\n    if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0)\n\tossl_raise(eOCSPError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_OCSP_REQUEST(req, &p) <= 0)\n\tossl_raise(eOCSPError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n/*\n * OCSP::Response\n */\nstatic VALUE\nossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp)\n{\n    OCSP_BASICRESP *bs;\n    OCSP_RESPONSE *res;\n    VALUE obj;\n    int st = NUM2INT(status);\n\n    if(NIL_P(basic_resp)) bs = NULL;\n    else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */\n    if(!(res = OCSP_response_create(st, bs)))\n\tossl_raise(eOCSPError, NULL);\n    WrapOCSPRes(klass, obj, res);\n\n    return obj;\n}\n\nstatic VALUE\nossl_ocspres_alloc(VALUE klass)\n{\n    OCSP_RESPONSE *res;\n    VALUE obj;\n\n    if(!(res = OCSP_RESPONSE_new()))\n\tossl_raise(eOCSPError, NULL);\n    WrapOCSPRes(klass, obj, res);\n\n    return obj;\n}\n\nstatic VALUE\nossl_ocspres_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE arg;\n    unsigned char *p;\n\n    rb_scan_args(argc, argv, \"01\", &arg);\n    if(!NIL_P(arg)){\n\targ = ossl_to_der_if_possible(arg);\n\tStringValue(arg);\n\tp = RSTRING_PTR(arg);\n\tif(!d2i_OCSP_RESPONSE((OCSP_RESPONSE**)&DATA_PTR(self), &p,\n\t\t\t      RSTRING_LEN(arg))){\n\t    ossl_raise(eOCSPError, \"cannot load DER encoded response\");\n\t}\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspres_status(VALUE self)\n{\n    OCSP_RESPONSE *res;\n    int st;\n\n    GetOCSPRes(self, res);\n    st = OCSP_response_status(res);\n\n    return INT2NUM(st);\n}\n\nstatic VALUE\nossl_ocspres_status_string(VALUE self)\n{\n    OCSP_RESPONSE *res;\n    int st;\n\n    GetOCSPRes(self, res);\n    st = OCSP_response_status(res);\n\n    return rb_str_new2(OCSP_response_status_str(st));\n}\n\nstatic VALUE\nossl_ocspres_get_basic(VALUE self)\n{\n    OCSP_RESPONSE *res;\n    OCSP_BASICRESP *bs;\n    VALUE ret;\n\n    GetOCSPRes(self, res);\n    if(!(bs = OCSP_response_get1_basic(res)))\n\treturn Qnil;\n    WrapOCSPBasicRes(cOCSPBasicRes, ret, bs);\n\n    return ret;\n}\n\nstatic VALUE\nossl_ocspres_to_der(VALUE self)\n{\n    OCSP_RESPONSE *res;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetOCSPRes(self, res);\n    if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0)\n\tossl_raise(eOCSPError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_OCSP_RESPONSE(res, NULL) <= 0)\n\tossl_raise(eOCSPError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n/*\n * OCSP::BasicResponse\n */\nstatic VALUE\nossl_ocspbres_alloc(VALUE klass)\n{\n    OCSP_BASICRESP *bs;\n    VALUE obj;\n\n    if(!(bs = OCSP_BASICRESP_new()))\n\tossl_raise(eOCSPError, NULL);\n    WrapOCSPBasicRes(klass, obj, bs);\n\n    return obj;\n}\n\nstatic VALUE\nossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)\n{\n    return self;\n}\n\nstatic VALUE\nossl_ocspbres_copy_nonce(VALUE self, VALUE request)\n{\n    OCSP_BASICRESP *bs;\n    OCSP_REQUEST *req;\n    int ret;\n\n    GetOCSPBasicRes(self, bs);\n    SafeGetOCSPReq(request, req);\n    ret = OCSP_copy_nonce(bs, req);\n\n    return INT2NUM(ret);\n}\n\nstatic VALUE\nossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self)\n{\n    OCSP_BASICRESP *bs;\n    VALUE val;\n    int ret;\n\n    rb_scan_args(argc, argv, \"01\", &val);\n    if(NIL_P(val)) {\n\tGetOCSPBasicRes(self, bs);\n\tret = OCSP_basic_add1_nonce(bs, NULL, -1);\n    }\n    else{\n\tStringValue(val);\n\tGetOCSPBasicRes(self, bs);\n\tret = OCSP_basic_add1_nonce(bs, RSTRING_PTR(val), RSTRING_LEN(val));\n    }\n    if(!ret) ossl_raise(eOCSPError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,\n\t\t\t VALUE reason, VALUE revtime,\n\t\t\t VALUE thisupd, VALUE nextupd, VALUE ext)\n{\n    OCSP_BASICRESP *bs;\n    OCSP_SINGLERESP *single;\n    OCSP_CERTID *id;\n    int st, rsn;\n    ASN1_TIME *ths, *nxt, *rev;\n    int error, i, rstatus = 0;\n    VALUE tmp;\n\n    st = NUM2INT(status);\n    rsn = NIL_P(status) ? 0 : NUM2INT(reason);\n    if(!NIL_P(ext)){\n\t/* All ary's members should be X509Extension */\n\tCheck_Type(ext, T_ARRAY);\n\tfor (i = 0; i < RARRAY_LEN(ext); i++)\n\t    OSSL_Check_Kind(RARRAY_PTR(ext)[i], cX509Ext);\n    }\n\n    error = 0;\n    ths = nxt = rev = NULL;\n    if(!NIL_P(revtime)){\n\ttmp = rb_protect(rb_Integer, revtime, &rstatus);\n\tif(rstatus) goto err;\n\trev = X509_gmtime_adj(NULL, NUM2INT(tmp));\n    }\n    tmp = rb_protect(rb_Integer, thisupd, &rstatus);\n    if(rstatus) goto err;\n    ths = X509_gmtime_adj(NULL, NUM2INT(tmp));\n    tmp = rb_protect(rb_Integer, nextupd, &rstatus);\n    if(rstatus) goto err;\n    nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));\n\n    GetOCSPBasicRes(self, bs);\n    SafeGetOCSPCertId(cid, id);\n    if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){\n\terror = 1;\n\tgoto err;\n    }\n\n    if(!NIL_P(ext)){\n\tX509_EXTENSION *x509ext;\n\tsk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free);\n\tsingle->singleExtensions = NULL;\n\tfor(i = 0; i < RARRAY_LEN(ext); i++){\n\t    x509ext = DupX509ExtPtr(RARRAY_PTR(ext)[i]);\n\t    if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){\n\t\tX509_EXTENSION_free(x509ext);\n\t\terror = 1;\n\t\tgoto err;\n\t    }\n\t    X509_EXTENSION_free(x509ext);\n\t}\n    }\n\n err:\n    ASN1_TIME_free(ths);\n    ASN1_TIME_free(nxt);\n    ASN1_TIME_free(rev);\n    if(error) ossl_raise(eOCSPError, NULL);\n    if(rstatus) rb_jump_tag(rstatus);\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspbres_get_status(VALUE self)\n{\n    OCSP_BASICRESP *bs;\n    OCSP_SINGLERESP *single;\n    OCSP_CERTID *cid;\n    ASN1_TIME *revtime, *thisupd, *nextupd;\n    int status, reason;\n    X509_EXTENSION *x509ext;\n    VALUE ret, ary, ext;\n    int count, ext_count, i, j;\n\n    GetOCSPBasicRes(self, bs);\n    ret = rb_ary_new();\n    count = OCSP_resp_count(bs);\n    for(i = 0; i < count; i++){\n\tsingle = OCSP_resp_get0(bs, i);\n\tif(!single) continue;\n\n\trevtime = thisupd = nextupd = NULL;\n\tstatus = OCSP_single_get0_status(single, &reason, &revtime,\n\t\t\t\t\t &thisupd, &nextupd);\n\tif(status < 0) continue;\n\tif(!(cid = OCSP_CERTID_dup(single->certId)))\n\t    ossl_raise(eOCSPError, NULL);\n\tary = rb_ary_new();\n\trb_ary_push(ary, ossl_ocspcertid_new(cid));\n\trb_ary_push(ary, INT2NUM(status));\n\trb_ary_push(ary, INT2NUM(reason));\n\trb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil);\n\trb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil);\n\trb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil);\n\text = rb_ary_new();\n\text_count = OCSP_SINGLERESP_get_ext_count(single);\n\tfor(j = 0; j < ext_count; j++){\n\t    x509ext = OCSP_SINGLERESP_get_ext(single, j);\n\t    rb_ary_push(ext, ossl_x509ext_new(x509ext));\n\t}\n\trb_ary_push(ary, ext);\n\trb_ary_push(ret, ary);\n    }\n\n    return ret;\n} \n\nstatic VALUE\nossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)\n{\n    VALUE signer_cert, signer_key, certs, flags;\n    OCSP_BASICRESP *bs;\n    X509 *signer;\n    EVP_PKEY *key;\n    STACK_OF(X509) *x509s;\n    unsigned long flg;\n    int ret;\n\n    rb_scan_args(argc, argv, \"22\", &signer_cert, &signer_key, &certs, &flags);\n    signer = GetX509CertPtr(signer_cert);\n    key = GetPrivPKeyPtr(signer_key);\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    if(NIL_P(certs)){\n\tx509s = sk_X509_new_null();\n\tflg |= OCSP_NOCERTS;\n    }\n    else{\n\tx509s = ossl_x509_ary2sk(certs);\n    }\n    GetOCSPBasicRes(self, bs);\n    ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);\n    sk_X509_pop_free(x509s, X509_free);\n    if(!ret) ossl_raise(eOCSPError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)\n{\n    VALUE certs, store, flags, result;\n    OCSP_BASICRESP *bs;\n    STACK_OF(X509) *x509s;\n    X509_STORE *x509st;\n    int flg;\n\n    rb_scan_args(argc, argv, \"21\", &certs, &store, &flags);\n    x509st = GetX509StorePtr(store);\n    flg = NIL_P(flags) ? 0 : INT2NUM(flags);\n    x509s = ossl_x509_ary2sk(certs);\n    GetOCSPBasicRes(self, bs);\n    result = OCSP_basic_verify(bs, x509s, x509st, flg) > 0 ? Qtrue : Qfalse;\n    sk_X509_pop_free(x509s, X509_free);\n    if(!result) rb_warn(\"%s\", ERR_error_string(ERR_peek_error(), NULL));\n\n    return result;\n}\n\n/*\n * OCSP::CertificateId\n */\nstatic VALUE\nossl_ocspcid_alloc(VALUE klass)\n{\n    OCSP_CERTID *id;\n    VALUE obj;\n\n    if(!(id = OCSP_CERTID_new()))\n\tossl_raise(eOCSPError, NULL);\n    WrapOCSPCertId(klass, obj, id);\n\n    return obj;\n}\n\nstatic VALUE\nossl_ocspcid_initialize(VALUE self, VALUE subject, VALUE issuer)\n{\n    OCSP_CERTID *id, *newid;\n    X509 *x509s, *x509i;\n\n    x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */\n    x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */\n    if(!(newid = OCSP_cert_to_id(NULL, x509s, x509i)))\n\tossl_raise(eOCSPError, NULL);\n    GetOCSPCertId(self, id);\n    OCSP_CERTID_free(id);\n    RDATA(self)->data = newid;\n\n    return self;\n}\n\nstatic VALUE\nossl_ocspcid_cmp(VALUE self, VALUE other)\n{\n    OCSP_CERTID *id, *id2;\n    int result;\n\n    GetOCSPCertId(self, id);\n    SafeGetOCSPCertId(other, id2);\n    result = OCSP_id_cmp(id, id2);\n\n    return (result == 0) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_ocspcid_cmp_issuer(VALUE self, VALUE other)\n{\n    OCSP_CERTID *id, *id2;\n    int result;\n\n    GetOCSPCertId(self, id);\n    SafeGetOCSPCertId(other, id2);\n    result = OCSP_id_issuer_cmp(id, id2);\n\n    return (result == 0) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_ocspcid_get_serial(VALUE self)\n{\n    OCSP_CERTID *id;\n\n    GetOCSPCertId(self, id);\n\n    return asn1integer_to_num(id->serialNumber);\n}\n\nvoid\nInit_ossl_ocsp()\n{\n    mOCSP = rb_define_module_under(mOSSL, \"OCSP\");\n\n    eOCSPError = rb_define_class_under(mOCSP, \"OCSPError\", eOSSLError);\n\n    cOCSPReq = rb_define_class_under(mOCSP, \"Request\", rb_cObject);\n    rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);\n    rb_define_method(cOCSPReq, \"initialize\", ossl_ocspreq_initialize, -1);\n    rb_define_method(cOCSPReq, \"add_nonce\", ossl_ocspreq_add_nonce, -1);\n    rb_define_method(cOCSPReq, \"check_nonce\", ossl_ocspreq_check_nonce, 1);\n    rb_define_method(cOCSPReq, \"add_certid\", ossl_ocspreq_add_certid, 1);\n    rb_define_method(cOCSPReq, \"certid\", ossl_ocspreq_get_certid, 0);\n    rb_define_method(cOCSPReq, \"sign\", ossl_ocspreq_sign, -1);\n    rb_define_method(cOCSPReq, \"verify\", ossl_ocspreq_verify, -1);\n    rb_define_method(cOCSPReq, \"to_der\", ossl_ocspreq_to_der, 0);\n\n    cOCSPRes = rb_define_class_under(mOCSP, \"Response\", rb_cObject);\n    rb_define_singleton_method(cOCSPRes, \"create\", ossl_ocspres_s_create, 2);\n    rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);\n    rb_define_method(cOCSPRes, \"initialize\", ossl_ocspres_initialize, -1);\n    rb_define_method(cOCSPRes, \"status\", ossl_ocspres_status, 0);\n    rb_define_method(cOCSPRes, \"status_string\", ossl_ocspres_status_string, 0);\n    rb_define_method(cOCSPRes, \"basic\", ossl_ocspres_get_basic, 0);\n    rb_define_method(cOCSPRes, \"to_der\", ossl_ocspres_to_der, 0);\n\n    cOCSPBasicRes = rb_define_class_under(mOCSP, \"BasicResponse\", rb_cObject);\n    rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);\n    rb_define_method(cOCSPBasicRes, \"initialize\", ossl_ocspbres_initialize, -1);\n    rb_define_method(cOCSPBasicRes, \"copy_nonce\", ossl_ocspbres_copy_nonce, 1);\n    rb_define_method(cOCSPBasicRes, \"add_nonce\", ossl_ocspbres_add_nonce, -1);\n    rb_define_method(cOCSPBasicRes, \"add_status\", ossl_ocspbres_add_status, 7);\n    rb_define_method(cOCSPBasicRes, \"status\", ossl_ocspbres_get_status, 0);\n    rb_define_method(cOCSPBasicRes, \"sign\", ossl_ocspbres_sign, -1);\n    rb_define_method(cOCSPBasicRes, \"verify\", ossl_ocspbres_verify, -1);\n\n    cOCSPCertId = rb_define_class_under(mOCSP, \"CertificateId\", rb_cObject);\n    rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);\n    rb_define_method(cOCSPCertId, \"initialize\", ossl_ocspcid_initialize, 2);\n    rb_define_method(cOCSPCertId, \"cmp\", ossl_ocspcid_cmp, 1);\n    rb_define_method(cOCSPCertId, \"cmp_issuer\", ossl_ocspcid_cmp_issuer, 1);\n    rb_define_method(cOCSPCertId, \"serial\", ossl_ocspcid_get_serial, 0);\n\n#define DefOCSPConst(x) rb_define_const(mOCSP, #x, INT2NUM(OCSP_##x))\n\n    DefOCSPConst(RESPONSE_STATUS_SUCCESSFUL);\n    DefOCSPConst(RESPONSE_STATUS_MALFORMEDREQUEST);\n    DefOCSPConst(RESPONSE_STATUS_INTERNALERROR);\n    DefOCSPConst(RESPONSE_STATUS_TRYLATER);\n    DefOCSPConst(RESPONSE_STATUS_SIGREQUIRED);\n    DefOCSPConst(RESPONSE_STATUS_UNAUTHORIZED);\n\n    DefOCSPConst(REVOKED_STATUS_NOSTATUS);\n    DefOCSPConst(REVOKED_STATUS_UNSPECIFIED);\n    DefOCSPConst(REVOKED_STATUS_KEYCOMPROMISE);\n    DefOCSPConst(REVOKED_STATUS_CACOMPROMISE);\n    DefOCSPConst(REVOKED_STATUS_AFFILIATIONCHANGED);\n    DefOCSPConst(REVOKED_STATUS_SUPERSEDED);\n    DefOCSPConst(REVOKED_STATUS_CESSATIONOFOPERATION);\n    DefOCSPConst(REVOKED_STATUS_CERTIFICATEHOLD);\n    DefOCSPConst(REVOKED_STATUS_REMOVEFROMCRL);\n\n    DefOCSPConst(NOCERTS);\n    DefOCSPConst(NOINTERN);\n    DefOCSPConst(NOSIGS);\n    DefOCSPConst(NOCHAIN);\n    DefOCSPConst(NOVERIFY);\n    DefOCSPConst(NOEXPLICIT);\n    DefOCSPConst(NOCASIGN);\n    DefOCSPConst(NODELEGATED);\n    DefOCSPConst(NOCHECKS);\n    DefOCSPConst(TRUSTOTHER);\n    DefOCSPConst(RESPID_KEY);\n    DefOCSPConst(NOTIME);\n\n#define DefOCSPVConst(x) rb_define_const(mOCSP, \"V_\" #x, INT2NUM(V_OCSP_##x))\n\n    DefOCSPVConst(CERTSTATUS_GOOD);\n    DefOCSPVConst(CERTSTATUS_REVOKED);\n    DefOCSPVConst(CERTSTATUS_UNKNOWN);\n    DefOCSPVConst(RESPID_NAME);\n    DefOCSPVConst(RESPID_KEY);\n}\n\n#else /* ! OSSL_OCSP_ENABLED */\nvoid\nInit_ossl_ocsp()\n{\n}\n#endif\n"
  },
  {
    "path": "ext/openssl/ossl_ocsp.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2003  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_OCSP_H_)\n#define _OSSL_OCSP_H_\n\n#if defined(OSSL_OCSP_ENABLED)\nextern VALUE mOCSP;\nextern VALUE cOPCSReq;\nextern VALUE cOPCSRes;\nextern VALUE cOPCSBasicRes;\n#endif\n\nvoid Init_ossl_ocsp(void);\n\n#endif /* _OSSL_OCSP_H_ */\n"
  },
  {
    "path": "ext/openssl/ossl_pkcs12.c",
    "content": "/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n * $Id$\n */\n#include \"ossl.h\"\n\n#define WrapPKCS12(klass, obj, p12) do { \\\n    if(!p12) ossl_raise(rb_eRuntimeError, \"PKCS12 wasn't initialized.\"); \\\n    obj = Data_Wrap_Struct(klass, 0, PKCS12_free, p12); \\\n} while (0)\n\n#define GetPKCS12(obj, p12) do { \\\n    Data_Get_Struct(obj, PKCS12, p12); \\\n    if(!p12) ossl_raise(rb_eRuntimeError, \"PKCS12 wasn't initialized.\"); \\\n} while (0)\n\n#define SafeGetPKCS12(obj, p12) do { \\\n    OSSL_Check_Kind(obj, cPKCS12); \\\n    GetPKCS12(obj, p12); \\\n} while (0)\n\n#define ossl_pkcs12_set_key(o,v)      rb_iv_set((o), \"@key\", (v))\n#define ossl_pkcs12_set_cert(o,v)     rb_iv_set((o), \"@certificate\", (v))\n#define ossl_pkcs12_set_ca_certs(o,v) rb_iv_set((o), \"@ca_certs\", (v))\n#define ossl_pkcs12_get_key(o)        rb_iv_get((o), \"@key\")\n#define ossl_pkcs12_get_cert(o)       rb_iv_get((o), \"@certificate\")\n#define ossl_pkcs12_get_ca_certs(o)   rb_iv_get((o), \"@ca_certs\")\n\n/*\n * Classes\n */\nVALUE cPKCS12;\nVALUE ePKCS12Error;\n\n/*\n * Private\n */\nstatic VALUE\nossl_pkcs12_s_allocate(VALUE klass)\n{\n    PKCS12 *p12;\n    VALUE obj;\n\n    if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL);\n    WrapPKCS12(klass, obj, p12);\n\n    return obj;\n}\n\n/*\n * call-seq:\n *    PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]])\n *\n * === Parameters\n * * +pass+ - string\n * * +name+ - A string describing the key.\n * * +key+ - Any PKey.\n * * +cert+ - A X509::Certificate.\n * * * The public_key portion of the certificate must contain a valid public key.\n * * * The not_before and not_after fields must be filled in.\n * * +ca+ - An optional array of X509::Certificate's.\n * * +key_pbe+ - string\n * * +cert_pbe+ - string\n * * +key_iter+ - integer\n * * +mac_iter+ - integer\n * * +keytype+ - An integer representing an MSIE specific extension.\n *\n * Any optional arguments may be supplied as nil to preserve the OpenSSL defaults.\n *\n * See the OpenSSL documentation for PKCS12_create().\n */\nstatic VALUE\nossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)\n{\n    VALUE pass, name, pkey, cert, ca, key_nid, cert_nid, key_iter, mac_iter, keytype;\n    VALUE obj;\n    char *passphrase, *friendlyname;\n    EVP_PKEY *key;\n    X509 *x509;\n    STACK_OF(X509) *x509s;\n    int nkey = 0, ncert = 0, kiter = 0, miter = 0, ktype = 0;\n    PKCS12 *p12;\n    \n    rb_scan_args(argc, argv, \"46\", &pass, &name, &pkey, &cert, &ca, &key_nid, &cert_nid, &key_iter, &mac_iter, &keytype);\n    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);\n    friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);\n    key = GetPKeyPtr(pkey);\n    x509 = GetX509CertPtr(cert);\n    x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);\n/* TODO: make a VALUE to nid function */\n    if (!NIL_P(key_nid)) {\n        if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)\n            rb_raise(rb_eArgError, \"Unknown PBE algorithm %s\", StringValuePtr(key_nid));\n    }\n    if (!NIL_P(cert_nid)) {\n        if ((ncert = OBJ_txt2nid(StringValuePtr(cert_nid))) == NID_undef)\n            rb_raise(rb_eArgError, \"Unknown PBE algorithm %s\", StringValuePtr(cert_nid));\n    }\n    if (!NIL_P(key_iter))\n        kiter = NUM2INT(key_iter);\n    if (!NIL_P(mac_iter))\n        miter = NUM2INT(mac_iter);\n    if (!NIL_P(keytype))\n        ktype = NUM2INT(keytype);\n\n    p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,\n                        nkey, ncert, kiter, miter, ktype);\n    sk_X509_pop_free(x509s, X509_free);\n    if(!p12) ossl_raise(ePKCS12Error, NULL);\n    WrapPKCS12(cPKCS12, obj, p12);\n\n    ossl_pkcs12_set_key(obj, pkey);\n    ossl_pkcs12_set_cert(obj, cert);\n    ossl_pkcs12_set_ca_certs(obj, ca);\n\n    return obj;\n}\n\n/*\n * call-seq:\n *    PKCS12.new -> pkcs12\n *    PKCS12.new(str) -> pkcs12\n *    PKCS12.new(str, pass) -> pkcs12\n *\n * === Parameters\n * * +str+ - Must be a DER encoded PKCS12 string.\n * * +pass+ - string\n */\nstatic VALUE\nossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)\n{\n    BIO *in;\n    VALUE arg, pass, pkey, cert, ca;\n    char *passphrase;\n    EVP_PKEY *key;\n    X509 *x509;\n    STACK_OF(X509) *x509s = NULL;\n    int st = 0;\n\n    if(rb_scan_args(argc, argv, \"02\", &arg, &pass) == 0) return self;\n    passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);\n    in = ossl_obj2bio(arg);\n    d2i_PKCS12_bio(in, (PKCS12 **)&DATA_PTR(self));\n    BIO_free(in);\n\n    pkey = cert = ca = Qnil;\n    if(!PKCS12_parse((PKCS12*)DATA_PTR(self), passphrase, &key, &x509, &x509s))\n\tossl_raise(ePKCS12Error, \"PKCS12_parse\");\n    pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,\n\t\t      &st); /* NO DUP */\n    if(st) goto err;\n    cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st);\n    if(st) goto err;\n    if(x509s){\n\tca =\n\t    rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st);\n\tif(st) goto err;\n    }\n\n  err:\n    X509_free(x509);\n    sk_X509_pop_free(x509s, X509_free);\n    ossl_pkcs12_set_key(self, pkey);\n    ossl_pkcs12_set_cert(self, cert);\n    ossl_pkcs12_set_ca_certs(self, ca);\n    if(st) rb_jump_tag(st);\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs12_to_der(VALUE self)\n{\n    PKCS12 *p12;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetPKCS12(self, p12);\n    if((len = i2d_PKCS12(p12, NULL)) <= 0)\n\tossl_raise(ePKCS12Error, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_PKCS12(p12, &p) <= 0)\n\tossl_raise(ePKCS12Error, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\nvoid\nInit_ossl_pkcs12()\n{\n    /*\n     * Defines a file format commonly used to store private keys with\n     * accompanying public key certificates, protected with a password-based\n     * symmetric key.\n     */\n    cPKCS12 = rb_define_class_under(mOSSL, \"PKCS12\", rb_cObject);\n    ePKCS12Error = rb_define_class_under(cPKCS12, \"PKCS12Error\", eOSSLError);\n    rb_define_singleton_method(cPKCS12, \"create\", ossl_pkcs12_s_create, -1);\n\n    rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate);\n    rb_attr(cPKCS12, rb_intern(\"key\"), 1, 0, Qfalse);\n    rb_attr(cPKCS12, rb_intern(\"certificate\"), 1, 0, Qfalse);\n    rb_attr(cPKCS12, rb_intern(\"ca_certs\"), 1, 0, Qfalse);\n    rb_define_method(cPKCS12, \"initialize\", ossl_pkcs12_initialize, -1);\n    rb_define_method(cPKCS12, \"to_der\", ossl_pkcs12_to_der, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_pkcs12.h",
    "content": "/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n * $Id$\n */\n#if !defined(_OSSL_PKCS12_H_)\n#define _OSSL_PKCS12_H_\n\nextern VALUE cPKCS12;\nextern VALUE ePKCS12Error;\n\nvoid Init_ossl_pkcs12(void);\n\n#endif /* _OSSL_PKCS12_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_pkcs5.c",
    "content": "/*\n * $Id$\n * Copyright (C) 2007 Technorama Ltd. <oss-ruby@technorama.net>\n */\n#include \"ossl.h\"\n\nVALUE mPKCS5;\nVALUE ePKCS5;\n\n/*\n * call-seq:\n *    PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string\n *\n * === Parameters\n * * +pass+ - string\n * * +salt+ - string\n * * +iter+ - integer - should be greater than 1000.  2000 is better.\n * * +keylen+ - integer\n * * +digest+ - a string or OpenSSL::Digest object.\n *\n * Available in OpenSSL 0.9.9?.\n *\n * Digests other than SHA1 may not be supported by other cryptography libraries.\n */\nstatic VALUE\nossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)\n{\n#ifdef HAVE_PKCS5_PBKDF2_HMAC\n    VALUE str;\n    const EVP_MD *md;\n    int len = NUM2INT(keylen);\n\n    StringValue(pass);\n    StringValue(salt);\n    md = GetDigestPtr(digest);\n\n    str = rb_str_new(0, len);\n\n    if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LEN(pass), RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter), md, len, RSTRING_PTR(str)) != 1)\n        ossl_raise(ePKCS5, \"PKCS5_PBKDF2_HMAC\");\n\n    return str;\n#else\n    rb_notimplement();\n#endif\n}\n\n\n/*\n * call-seq:\n *    PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string\n *\n * === Parameters\n * * +pass+ - string\n * * +salt+ - string\n * * +iter+ - integer - should be greater than 1000.  2000 is better.\n * * +keylen+ - integer\n *\n * This method is available almost any version OpenSSL.\n *\n * Conforms to rfc2898.\n */\nstatic VALUE\nossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)\n{\n#ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1\n    VALUE str;\n    int len = NUM2INT(keylen);\n\n    StringValue(pass);\n    StringValue(salt);\n\n    str = rb_str_new(0, len);\n\n    if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LEN(pass), RSTRING_PTR(salt), RSTRING_LEN(salt), NUM2INT(iter), len, RSTRING_PTR(str)) != 1)\n        ossl_raise(ePKCS5, \"PKCS5_PBKDF2_HMAC_SHA1\");\n\n    return str;\n#else\n    rb_notimplement();\n#endif\n}\n\nvoid\nInit_ossl_pkcs5()\n{\n    /*\n     * Password-based Encryption\n     *\n     */\n    mPKCS5 = rb_define_module_under(mOSSL, \"PKCS5\");\n    ePKCS5 = rb_define_class_under(mPKCS5, \"PKCS5Error\", eOSSLError);\n\n    rb_define_module_function(mPKCS5, \"pbkdf2_hmac\", ossl_pkcs5_pbkdf2_hmac, 5);\n    rb_define_module_function(mPKCS5, \"pbkdf2_hmac_sha1\", ossl_pkcs5_pbkdf2_hmac_sha1, 4);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_pkcs5.h",
    "content": "#if !defined(_OSSL_PKCS5_H_)\n#define _OSSL_PKCS5_H_\n\nvoid Init_ossl_pkcs5(void);\n\n#endif /* _OSSL_PKCS5_H_ */\n"
  },
  {
    "path": "ext/openssl/ossl_pkcs7.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapPKCS7(klass, obj, pkcs7) do { \\\n    if (!pkcs7) { \\\n\tossl_raise(rb_eRuntimeError, \"PKCS7 wasn't initialized.\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, PKCS7_free, pkcs7); \\\n} while (0)\n#define GetPKCS7(obj, pkcs7) do { \\\n    Data_Get_Struct(obj, PKCS7, pkcs7); \\\n    if (!pkcs7) { \\\n\tossl_raise(rb_eRuntimeError, \"PKCS7 wasn't initialized.\"); \\\n    } \\\n} while (0)\n#define SafeGetPKCS7(obj, pkcs7) do { \\\n    OSSL_Check_Kind(obj, cPKCS7); \\\n    GetPKCS7(obj, pkcs7); \\\n} while (0)\n\n#define WrapPKCS7si(klass, obj, p7si) do { \\\n    if (!p7si) { \\\n\tossl_raise(rb_eRuntimeError, \"PKCS7si wasn't initialized.\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, PKCS7_SIGNER_INFO_free, p7si); \\\n} while (0)\n#define GetPKCS7si(obj, p7si) do { \\\n    Data_Get_Struct(obj, PKCS7_SIGNER_INFO, p7si); \\\n    if (!p7si) { \\\n\tossl_raise(rb_eRuntimeError, \"PKCS7si wasn't initialized.\"); \\\n    } \\\n} while (0)\n#define SafeGetPKCS7si(obj, p7si) do { \\\n    OSSL_Check_Kind(obj, cPKCS7Signer); \\\n    GetPKCS7si(obj, p7si); \\\n} while (0)\n\n#define WrapPKCS7ri(klass, obj, p7ri) do { \\\n    if (!p7ri) { \\\n\tossl_raise(rb_eRuntimeError, \"PKCS7ri wasn't initialized.\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, PKCS7_RECIP_INFO_free, p7ri); \\\n} while (0)\n#define GetPKCS7ri(obj, p7ri) do { \\\n    Data_Get_Struct(obj, PKCS7_RECIP_INFO, p7ri); \\\n    if (!p7ri) { \\\n\tossl_raise(rb_eRuntimeError, \"PKCS7ri wasn't initialized.\"); \\\n    } \\\n} while (0)\n#define SafeGetPKCS7ri(obj, p7ri) do { \\\n    OSSL_Check_Kind(obj, cPKCS7Recipient); \\\n    GetPKCS7ri(obj, p7ri); \\\n} while (0)\n\n#define numberof(ary) (sizeof(ary)/sizeof(ary[0]))\n\n#define ossl_pkcs7_set_data(o,v)       rb_iv_set((o), \"@data\", (v))\n#define ossl_pkcs7_get_data(o)         rb_iv_get((o), \"@data\")\n#define ossl_pkcs7_set_err_string(o,v) rb_iv_set((o), \"@error_string\", (v))\n#define ossl_pkcs7_get_err_string(o)   rb_iv_get((o), \"@error_string\")\n\n/* \n * Classes\n */\nVALUE cPKCS7;\nVALUE cPKCS7Signer;\nVALUE cPKCS7Recipient;\nVALUE ePKCS7Error;\n\n/*\n * Public\n * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM)\n */\nstatic VALUE\nossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si)\n{\n    PKCS7_SIGNER_INFO *pkcs7;\n    VALUE obj;\n\n    pkcs7 = p7si ? PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new();\n    if (!pkcs7) ossl_raise(ePKCS7Error, NULL);\n    WrapPKCS7si(cPKCS7Signer, obj, pkcs7);\n\n    return obj;\n}\n\nstatic PKCS7_SIGNER_INFO *\nDupPKCS7SignerPtr(VALUE obj)\n{\n    PKCS7_SIGNER_INFO *p7si, *pkcs7;\n\t\n    SafeGetPKCS7si(obj, p7si);\n    if (!(pkcs7 = PKCS7_SIGNER_INFO_dup(p7si))) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return pkcs7;\n}\n\nstatic VALUE\nossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri)\n{\n    PKCS7_RECIP_INFO *pkcs7;\n    VALUE obj;\n\n    pkcs7 = p7ri ? PKCS7_RECIP_INFO_dup(p7ri) : PKCS7_RECIP_INFO_new();\n    if (!pkcs7) ossl_raise(ePKCS7Error, NULL);\n    WrapPKCS7ri(cPKCS7Recipient, obj, pkcs7);\n\n    return obj;\n}\n\nstatic PKCS7_RECIP_INFO *\nDupPKCS7RecipientPtr(VALUE obj)\n{\n    PKCS7_RECIP_INFO *p7ri, *pkcs7;\n\t\n    SafeGetPKCS7ri(obj, p7ri);\n    if (!(pkcs7 = PKCS7_RECIP_INFO_dup(p7ri))) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return pkcs7;\n}\n\n/*\n * call-seq:\n *    PKCS7.read_smime(string) => pkcs7\n */\nstatic VALUE\nossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)\n{\n    BIO *in, *out;\n    PKCS7 *pkcs7;\n    VALUE ret, data;\n\n    in = ossl_obj2bio(arg);\n    out = NULL;\n    pkcs7 = SMIME_read_PKCS7(in, &out);\n    BIO_free(in);\n    if(!pkcs7) ossl_raise(ePKCS7Error, NULL);\n    data = out ? ossl_membio2str(out) : Qnil;\n    WrapPKCS7(cPKCS7, ret, pkcs7);\n    ossl_pkcs7_set_data(ret, data);\n    ossl_pkcs7_set_err_string(ret, Qnil);\n\n    return ret;\n}\n\n/*\n * call-seq:\n *    PKCS7.write_smime(pkcs7 [, data [, flags]]) => string\n */\nstatic VALUE\nossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)\n{\n    VALUE pkcs7, data, flags;\n    BIO *out, *in;\n    PKCS7 *p7;\n    VALUE str;\n    int flg;\n\n    rb_scan_args(argc, argv, \"12\", &pkcs7, &data, &flags);\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7);\n    SafeGetPKCS7(pkcs7, p7);\n    if(!NIL_P(data) && PKCS7_is_detached(p7))\n\tflg |= PKCS7_DETACHED;\n    in = NIL_P(data) ? NULL : ossl_obj2bio(data);\n    if(!(out = BIO_new(BIO_s_mem()))){\n        BIO_free(in);\n        ossl_raise(ePKCS7Error, NULL);\n    }\n    if(!SMIME_write_PKCS7(out, p7, in, flg)){\n        BIO_free(out);\n        BIO_free(in);\n        ossl_raise(ePKCS7Error, NULL);\n    }\n    BIO_free(in);\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n * call-seq:\n *    PKCS7.sign(cert, key, data, [, certs [, flags]]) => pkcs7\n */\nstatic VALUE\nossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)\n{\n    VALUE cert, key, data, certs, flags;\n    X509 *x509;\n    EVP_PKEY *pkey;\n    BIO *in;\n    STACK_OF(X509) *x509s;\n    int flg, status = 0;\n    PKCS7 *pkcs7;\n    VALUE ret;\n\n    rb_scan_args(argc, argv, \"32\", &cert, &key, &data, &certs, &flags);\n    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    in = ossl_obj2bio(data);\n    if(NIL_P(certs)) x509s = NULL;\n    else{\n\tx509s = ossl_protect_x509_ary2sk(certs, &status);\n\tif(status){\n\t    BIO_free(in);\n\t    rb_jump_tag(status);\n\t}\n    }\n    if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){\n\tBIO_free(in);\n\tsk_X509_pop_free(x509s, X509_free);\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    WrapPKCS7(cPKCS7, ret, pkcs7);\n    ossl_pkcs7_set_data(ret, data);\n    ossl_pkcs7_set_err_string(ret, Qnil);\n    BIO_free(in);\n    sk_X509_pop_free(x509s, X509_free);\n\n    return ret;\n}\n\n/*\n * call-seq:\n *    PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7\n */\nstatic VALUE\nossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)\n{\n    VALUE certs, data, cipher, flags;\n    STACK_OF(X509) *x509s;\n    BIO *in;\n    const EVP_CIPHER *ciph;\n    int flg, status = 0;\n    VALUE ret;\n    PKCS7 *p7;\n\n    rb_scan_args(argc, argv, \"22\", &certs, &data, &cipher, &flags);\n    if(NIL_P(cipher)){\n#if !defined(OPENSSL_NO_RC2)\n\tciph = EVP_rc2_40_cbc();\n#elif !defined(OPENSSL_NO_DES)\n\tciph = EVP_des_ede3_cbc();\n#elif !defined(OPENSSL_NO_RC2)\n\tciph = EVP_rc2_40_cbc();\n#elif !defined(OPENSSL_NO_AES)\n\tciph = EVP_EVP_aes_128_cbc();\n#else\n\tossl_raise(ePKCS7Error, \"Must specify cipher\");\n#endif\n\n    }\n    else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    in = ossl_obj2bio(data);\n    x509s = ossl_protect_x509_ary2sk(certs, &status);\n    if(status){\n\tBIO_free(in);\n\trb_jump_tag(status);\n    }\n    if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){\n\tBIO_free(in);\n\tsk_X509_pop_free(x509s, X509_free);\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    BIO_free(in);\n    WrapPKCS7(cPKCS7, ret, p7);\n    ossl_pkcs7_set_data(ret, data);\n    sk_X509_pop_free(x509s, X509_free);\n\n    return ret;\n}\n\nstatic VALUE\nossl_pkcs7_alloc(VALUE klass)\n{\n    PKCS7 *pkcs7;\n    VALUE obj;\n\n    if (!(pkcs7 = PKCS7_new())) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    WrapPKCS7(klass, obj, pkcs7);\n    \n    return obj;\n}\n\n/*\n * call-seq:\n *    PKCS7.new => pkcs7\n *    PKCS7.new(string) => pkcs7\n *\n * Many methods in this class aren't documented.\n */\nstatic VALUE\nossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)\n{\n    PKCS7 *p7;\n    BIO *in;\n    VALUE arg;\n\n    if(rb_scan_args(argc, argv, \"01\", &arg) == 0)\n\treturn self;\n    arg = ossl_to_der_if_possible(arg);\n    in = ossl_obj2bio(arg);\n    p7 = PEM_read_bio_PKCS7(in, (PKCS7 **)&DATA_PTR(self), NULL, NULL);\n    if (!p7) {\n\tBIO_reset(in);\n        p7 = d2i_PKCS7_bio(in, (PKCS7 **)&DATA_PTR(self));\n    }\n    BIO_free(in);\n    ossl_pkcs7_set_data(self, Qnil);\n    ossl_pkcs7_set_err_string(self, Qnil);\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs7_copy(VALUE self, VALUE other)\n{\n    PKCS7 *a, *b, *pkcs7;\n\n    rb_check_frozen(self);\n    if (self == other) return self;\n\n    GetPKCS7(self, a);\n    SafeGetPKCS7(other, b);\n\n    pkcs7 = PKCS7_dup(b);\n    if (!pkcs7) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    DATA_PTR(self) = pkcs7;\n    PKCS7_free(a);\n\n    return self;\n}\n\nstatic int\nossl_pkcs7_sym2typeid(VALUE sym)\n{\n    int i, ret = Qnil;\n    const char *s;\n\n    static struct {\n        const char *name;\n        int nid;\n    } p7_type_tab[] = {\n        { \"signed\",             NID_pkcs7_signed },\n        { \"data\",               NID_pkcs7_data },\n        { \"signedAndEnveloped\", NID_pkcs7_signedAndEnveloped },\n        { \"enveloped\",          NID_pkcs7_enveloped },\n        { \"encrypted\",          NID_pkcs7_encrypted },\n        { \"digest\",             NID_pkcs7_digest },\n        { NULL,                 0 },\n    };\n\n    if(TYPE(sym) == T_SYMBOL) s = rb_id2name(SYM2ID(sym));\n    else s = StringValuePtr(sym);\n    for(i = 0; i < numberof(p7_type_tab); i++){\n\tif(p7_type_tab[i].name == NULL)\n\t    ossl_raise(ePKCS7Error, \"unknown type \\\"%s\\\"\", s);\n\tif(strcmp(p7_type_tab[i].name, s) == 0){\n\t    ret = p7_type_tab[i].nid;\n\t    break;\n\t}\n    }\n\n    return ret;\n}\n\n/*\n * call-seq:\n *    pkcs7.type = type => type\n */\nstatic VALUE\nossl_pkcs7_set_type(VALUE self, VALUE type)\n{\n    PKCS7 *p7;\n\n    GetPKCS7(self, p7);\n    if(!PKCS7_set_type(p7, ossl_pkcs7_sym2typeid(type)))\n\tossl_raise(ePKCS7Error, NULL);\n\n    return type;\n}\n\n/*\n * call-seq:\n *    pkcs7.type => string or nil\n */\nstatic VALUE\nossl_pkcs7_get_type(VALUE self)\n{\n    PKCS7 *p7;\n\n    GetPKCS7(self, p7);\n    if(PKCS7_type_is_signed(p7))\n\treturn ID2SYM(rb_intern(\"signed\"));\n    if(PKCS7_type_is_encrypted(p7))\n\treturn ID2SYM(rb_intern(\"encrypted\"));\n    if(PKCS7_type_is_enveloped(p7))\n\treturn ID2SYM(rb_intern(\"enveloped\"));\n    if(PKCS7_type_is_signedAndEnveloped(p7))\n\treturn ID2SYM(rb_intern(\"signedAndEnveloped\"));\n    if(PKCS7_type_is_data(p7))\n\treturn ID2SYM(rb_intern(\"data\"));\n    return Qnil;\n}\n\nstatic VALUE\nossl_pkcs7_set_detached(VALUE self, VALUE flag)\n{\n    PKCS7 *p7;\n\n    GetPKCS7(self, p7);\n    if(flag != Qtrue && flag != Qfalse)\n\tossl_raise(ePKCS7Error, \"must specify a boolean\");\n    if(!PKCS7_set_detached(p7, flag == Qtrue ? 1 : 0))\n\tossl_raise(ePKCS7Error, NULL);\n\n    return flag;\n}\n\nstatic VALUE\nossl_pkcs7_get_detached(VALUE self)\n{\n    PKCS7 *p7;\n    GetPKCS7(self, p7);\n    return PKCS7_get_detached(p7) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_pkcs7_detached_p(VALUE self)\n{\n    PKCS7 *p7;\n    GetPKCS7(self, p7);\n    return PKCS7_is_detached(p7) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_pkcs7_set_cipher(VALUE self, VALUE cipher)\n{\n    PKCS7 *pkcs7;\n\n    GetPKCS7(self, pkcs7);\n    if (!PKCS7_set_cipher(pkcs7, GetCipherPtr(cipher))) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return cipher;\n}\n\nstatic VALUE\nossl_pkcs7_add_signer(VALUE self, VALUE signer)\n{\n    PKCS7 *pkcs7;\n    PKCS7_SIGNER_INFO *p7si;\n\n    p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */\n    GetPKCS7(self, pkcs7);\n    if (!PKCS7_add_signer(pkcs7, p7si)) {\n\tPKCS7_SIGNER_INFO_free(p7si);\n\tossl_raise(ePKCS7Error, \"Could not add signer.\");\n    }\n    if (PKCS7_type_is_signed(pkcs7)){\n\tPKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,\n\t\t\t\t   V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs7_get_signer(VALUE self)\n{\n    PKCS7 *pkcs7;\n    STACK_OF(PKCS7_SIGNER_INFO) *sk;\n    PKCS7_SIGNER_INFO *si;\n    int num, i;\n    VALUE ary;\n    \n    GetPKCS7(self, pkcs7);\n    if (!(sk = PKCS7_get_signer_info(pkcs7))) {\n\tOSSL_Debug(\"OpenSSL::PKCS7#get_signer_info == NULL!\");\n\treturn rb_ary_new();\n    }\n    if ((num = sk_PKCS7_SIGNER_INFO_num(sk)) < 0) {\n\tossl_raise(ePKCS7Error, \"Negative number of signers!\");\n    }\n    ary = rb_ary_new2(num);\n    for (i=0; i<num; i++) {\n\tsi = sk_PKCS7_SIGNER_INFO_value(sk, i);\n\trb_ary_push(ary, ossl_pkcs7si_new(si));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nossl_pkcs7_add_recipient(VALUE self, VALUE recip)\n{\n    PKCS7 *pkcs7;\n    PKCS7_RECIP_INFO *ri;\n\n    ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */\n    GetPKCS7(self, pkcs7);\n    if (!PKCS7_add_recipient_info(pkcs7, ri)) {\n\tPKCS7_RECIP_INFO_free(ri);\n\tossl_raise(ePKCS7Error, \"Could not add recipient.\");\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs7_get_recipient(VALUE self)\n{\n    PKCS7 *pkcs7;\n    STACK_OF(PKCS7_RECIP_INFO) *sk;\n    PKCS7_RECIP_INFO *si;\n    int num, i;\n    VALUE ary;\n    \n    GetPKCS7(self, pkcs7);\n    if (PKCS7_type_is_enveloped(pkcs7))\n\tsk = pkcs7->d.enveloped->recipientinfo;\n    else if (PKCS7_type_is_signedAndEnveloped(pkcs7))\n\tsk = pkcs7->d.signed_and_enveloped->recipientinfo;\n    else sk = NULL;\n    if (!sk) return rb_ary_new();\n    if ((num = sk_PKCS7_RECIP_INFO_num(sk)) < 0) {\n\tossl_raise(ePKCS7Error, \"Negative number of recipient!\");\n    }\n    ary = rb_ary_new2(num);\n    for (i=0; i<num; i++) {\n\tsi = sk_PKCS7_RECIP_INFO_value(sk, i);\n\trb_ary_push(ary, ossl_pkcs7ri_new(si));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nossl_pkcs7_add_certificate(VALUE self, VALUE cert)\n{\n    PKCS7 *pkcs7;\n    X509 *x509;\n\n    GetPKCS7(self, pkcs7);\n    x509 = GetX509CertPtr(cert);  /* NO NEED TO DUP */\n    if (!PKCS7_add_certificate(pkcs7, x509)){\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return self;\n}\n\nstatic STACK_OF(X509) *\npkcs7_get_certs(VALUE self)\n{\n    PKCS7 *pkcs7;\n    STACK_OF(X509) *certs;\n    int i;\n\n    GetPKCS7(self, pkcs7);\n    i = OBJ_obj2nid(pkcs7->type);\n    switch(i){\n    case NID_pkcs7_signed:\n        certs = pkcs7->d.sign->cert;\n        break;\n    case NID_pkcs7_signedAndEnveloped:\n        certs = pkcs7->d.signed_and_enveloped->cert;\n        break;\n    default:\n        certs = NULL;\n    }\n\n    return certs;\n}\n\nstatic STACK_OF(X509_CRL) *\npkcs7_get_crls(VALUE self)\n{\n    PKCS7 *pkcs7;\n    STACK_OF(X509_CRL) *crls;\n    int i;\n\n    GetPKCS7(self, pkcs7);\n    i = OBJ_obj2nid(pkcs7->type);\n    switch(i){\n    case NID_pkcs7_signed:\n        crls = pkcs7->d.sign->crl;\n        break;\n    case NID_pkcs7_signedAndEnveloped:\n        crls = pkcs7->d.signed_and_enveloped->crl;\n        break;\n    default:\n        crls = NULL;\n    }\n\n    return crls;\n}\n\nstatic VALUE\nossl_pkcs7_set_certs_i(VALUE i, VALUE arg)\n{\n    return ossl_pkcs7_add_certificate(arg, i);\n}\n\nstatic VALUE\nossl_pkcs7_set_certificates(VALUE self, VALUE ary)\n{\n    STACK_OF(X509) *certs;\n    X509 *cert;\n\n    certs = pkcs7_get_certs(self);\n    while((cert = sk_X509_pop(certs))) X509_free(cert);\n    rb_block_call(ary, rb_intern(\"each\"), 0, 0, ossl_pkcs7_set_certs_i, self);\n\n    return ary;\n}\n\nstatic VALUE\nossl_pkcs7_get_certificates(VALUE self)\n{\n    return ossl_x509_sk2ary(pkcs7_get_certs(self));\n}\n\nstatic VALUE\nossl_pkcs7_add_crl(VALUE self, VALUE crl)\n{\n    PKCS7 *pkcs7;\n    X509_CRL *x509crl;\n\n    GetPKCS7(self, pkcs7); /* NO DUP needed! */\n    x509crl = GetX509CRLPtr(crl);\n    if (!PKCS7_add_crl(pkcs7, x509crl)) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs7_set_crls_i(VALUE i, VALUE arg)\n{\n    return ossl_pkcs7_add_crl(arg, i);\n}\n\nstatic VALUE\nossl_pkcs7_set_crls(VALUE self, VALUE ary)\n{\n    STACK_OF(X509_CRL) *crls;\n    X509_CRL *crl;\n\n    crls = pkcs7_get_crls(self);\n    while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl);\n    rb_block_call(ary, rb_intern(\"each\"), 0, 0, ossl_pkcs7_set_crls_i, self);\n\n    return ary;\n}\n\nstatic VALUE\nossl_pkcs7_get_crls(VALUE self)\n{\n    return ossl_x509crl_sk2ary(pkcs7_get_crls(self));\n}\n\nstatic VALUE\nossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)\n{\n    VALUE certs, store, indata, flags;\n    STACK_OF(X509) *x509s;\n    X509_STORE *x509st;\n    int flg, ok, status = 0;\n    BIO *in, *out;\n    PKCS7 *p7;\n    VALUE data;\n    const char *msg;\n\n    rb_scan_args(argc, argv, \"22\", &certs, &store, &indata, &flags);\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self);\n    in = NIL_P(indata) ? NULL : ossl_obj2bio(indata);\n    if(NIL_P(certs)) x509s = NULL;\n    else{\n\tx509s = ossl_protect_x509_ary2sk(certs, &status);\n\tif(status){\n\t    BIO_free(in);\n\t    rb_jump_tag(status);\n\t}\n    }\n    x509st = GetX509StorePtr(store);\n    GetPKCS7(self, p7);\n    if(!(out = BIO_new(BIO_s_mem()))){\n\tBIO_free(in);\n\tsk_X509_pop_free(x509s, X509_free);\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    ok = PKCS7_verify(p7, x509s, x509st, in, out, flg);\n    BIO_free(in);\n    if (ok < 0) ossl_raise(ePKCS7Error, NULL);\n    msg = ERR_reason_error_string(ERR_get_error());\n    ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);\n    ERR_clear_error();\n    data = ossl_membio2str(out);\n    ossl_pkcs7_set_data(self, data);\n    sk_X509_pop_free(x509s, X509_free);\n\n    return (ok == 1) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self)\n{\n    VALUE pkey, cert, flags;\n    EVP_PKEY *key;\n    X509 *x509;\n    int flg;\n    PKCS7 *p7;\n    BIO *out;\n    VALUE str;\n\n    rb_scan_args(argc, argv, \"21\", &pkey, &cert, &flags);\n    key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */\n    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */\n    flg = NIL_P(flags) ? 0 : NUM2INT(flags);\n    GetPKCS7(self, p7);\n    if(!(out = BIO_new(BIO_s_mem())))\n\tossl_raise(ePKCS7Error, NULL);\n    if(!PKCS7_decrypt(p7, key, x509, out, flg)){\n\tBIO_free(out);\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    str = ossl_membio2str(out); /* out will be free */\n\n    return str;\n}\n\nstatic VALUE\nossl_pkcs7_add_data(VALUE self, VALUE data)\n{\n    PKCS7 *pkcs7;\n    BIO *out, *in;\n    char buf[4096];\n    int len;\n\n    in = ossl_obj2bio(data);\n    GetPKCS7(self, pkcs7);\n    if(PKCS7_type_is_signed(pkcs7)){\n\tif(!PKCS7_content_new(pkcs7, NID_pkcs7_data))\n\t    ossl_raise(ePKCS7Error, NULL);\n    }\n    if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;\n    for(;;){\n\tif((len = BIO_read(in, buf, sizeof(buf))) <= 0)\n\t    break;\n\tif(BIO_write(out, buf, len) != len)\n\t    goto err;\n    }\n    if(!PKCS7_dataFinal(pkcs7, out)) goto err;\n    ossl_pkcs7_set_data(self, Qnil);\n    \n err:\n    BIO_free(out);\n    BIO_free(in);\n    if(ERR_peek_error()){\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return data;\n}\n\nstatic VALUE\nossl_pkcs7_to_der(VALUE self)\n{\n    PKCS7 *pkcs7;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetPKCS7(self, pkcs7);\n    if((len = i2d_PKCS7(pkcs7, NULL)) <= 0)\n\tossl_raise(ePKCS7Error, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_PKCS7(pkcs7, &p) <= 0)\n\tossl_raise(ePKCS7Error, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\nstatic VALUE\nossl_pkcs7_to_pem(VALUE self)\n{\n    PKCS7 *pkcs7;\n    BIO *out;\n    VALUE str;\n\t\n    GetPKCS7(self, pkcs7);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    if (!PEM_write_bio_PKCS7(out, pkcs7)) {\n\tBIO_free(out);\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n * SIGNER INFO\n */\nstatic VALUE\nossl_pkcs7si_alloc(VALUE klass)\n{\n    PKCS7_SIGNER_INFO *p7si;\n    VALUE obj;\n\n    if (!(p7si = PKCS7_SIGNER_INFO_new())) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    WrapPKCS7si(klass, obj, p7si);\n\n    return obj;\n}\n\nstatic VALUE\nossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest)\n{\n    PKCS7_SIGNER_INFO *p7si;\n    EVP_PKEY *pkey;\n    X509 *x509;\n    const EVP_MD *md;\n\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */\n    md = GetDigestPtr(digest);\n    GetPKCS7si(self, p7si);\n    if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs7si_get_issuer(VALUE self)\n{\n    PKCS7_SIGNER_INFO *p7si;\n\n    GetPKCS7si(self, p7si);\n\n    return ossl_x509name_new(p7si->issuer_and_serial->issuer);\n}\n\nstatic VALUE\nossl_pkcs7si_get_serial(VALUE self)\n{\n    PKCS7_SIGNER_INFO *p7si;\n\n    GetPKCS7si(self, p7si);\n\n    return asn1integer_to_num(p7si->issuer_and_serial->serial);\n}\n\nstatic VALUE\nossl_pkcs7si_get_signed_time(VALUE self)\n{\n    PKCS7_SIGNER_INFO *p7si;\n    ASN1_TYPE *asn1obj;\n\t\n    GetPKCS7si(self, p7si);\n\t\n    if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    if (asn1obj->type == V_ASN1_UTCTIME) {\n\treturn asn1time_to_time(asn1obj->value.utctime);\n    }\n    /*\n     * OR\n     * ossl_raise(ePKCS7Error, \"...\");\n     * ?\n     */\n\n    return Qnil;\n}\n\n/*\n * RECIPIENT INFO\n */\nstatic VALUE\nossl_pkcs7ri_alloc(VALUE klass)\n{\n    PKCS7_RECIP_INFO *p7ri;\n    VALUE obj;\n\n    if (!(p7ri = PKCS7_RECIP_INFO_new())) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n    WrapPKCS7ri(klass, obj, p7ri);\n\n    return obj;\n}\n\nstatic VALUE\nossl_pkcs7ri_initialize(VALUE self, VALUE cert)\n{\n    PKCS7_RECIP_INFO *p7ri;\n    X509 *x509;\n\n    x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */\n    GetPKCS7ri(self, p7ri);\n    if (!PKCS7_RECIP_INFO_set(p7ri, x509)) {\n\tossl_raise(ePKCS7Error, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_pkcs7ri_get_issuer(VALUE self)\n{\n    PKCS7_RECIP_INFO *p7ri;\n\n    GetPKCS7ri(self, p7ri);\n\n    return ossl_x509name_new(p7ri->issuer_and_serial->issuer);\n}\n\nstatic VALUE\nossl_pkcs7ri_get_serial(VALUE self)\n{\n    PKCS7_RECIP_INFO *p7ri;\n\n    GetPKCS7ri(self, p7ri);\n\n    return asn1integer_to_num(p7ri->issuer_and_serial->serial);\n}\n\nstatic VALUE\nossl_pkcs7ri_get_enc_key(VALUE self)\n{\n    PKCS7_RECIP_INFO *p7ri;\n\n    GetPKCS7ri(self, p7ri);\n\n    return asn1str_to_str(p7ri->enc_key);\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_pkcs7()\n{\n    cPKCS7 = rb_define_class_under(mOSSL, \"PKCS7\", rb_cObject);\n    ePKCS7Error = rb_define_class_under(cPKCS7, \"PKCS7Error\", eOSSLError);\n    rb_define_singleton_method(cPKCS7, \"read_smime\", ossl_pkcs7_s_read_smime, 1);\n    rb_define_singleton_method(cPKCS7, \"write_smime\", ossl_pkcs7_s_write_smime, -1);\n    rb_define_singleton_method(cPKCS7, \"sign\",  ossl_pkcs7_s_sign, -1);\n    rb_define_singleton_method(cPKCS7, \"encrypt\", ossl_pkcs7_s_encrypt, -1);\n    rb_attr(cPKCS7, rb_intern(\"data\"), 1, 0, Qfalse);\n    rb_attr(cPKCS7, rb_intern(\"error_string\"), 1, 1, Qfalse);\n    rb_define_alloc_func(cPKCS7, ossl_pkcs7_alloc);\n    rb_define_copy_func(cPKCS7, ossl_pkcs7_copy);\n    rb_define_method(cPKCS7, \"initialize\", ossl_pkcs7_initialize, -1);\n    rb_define_method(cPKCS7, \"type=\", ossl_pkcs7_set_type, 1);\n    rb_define_method(cPKCS7, \"type\", ossl_pkcs7_get_type, 0);\n    rb_define_method(cPKCS7, \"detached=\", ossl_pkcs7_set_detached, 1);\n    rb_define_method(cPKCS7, \"detached\", ossl_pkcs7_get_detached, 0);\n    rb_define_method(cPKCS7, \"detached?\", ossl_pkcs7_detached_p, 0);\n    rb_define_method(cPKCS7, \"cipher=\", ossl_pkcs7_set_cipher, 1);\n    rb_define_method(cPKCS7, \"add_signer\", ossl_pkcs7_add_signer, 1);\n    rb_define_method(cPKCS7, \"signers\", ossl_pkcs7_get_signer, 0);\n    rb_define_method(cPKCS7, \"add_recipient\", ossl_pkcs7_add_recipient, 1);\n    rb_define_method(cPKCS7, \"recipients\", ossl_pkcs7_get_recipient, 0);\n    rb_define_method(cPKCS7, \"add_certificate\", ossl_pkcs7_add_certificate, 1);\n    rb_define_method(cPKCS7, \"certificates=\", ossl_pkcs7_set_certificates, 1);\n    rb_define_method(cPKCS7, \"certificates\", ossl_pkcs7_get_certificates, 0);\n    rb_define_method(cPKCS7, \"add_crl\", ossl_pkcs7_add_crl, 1);\n    rb_define_method(cPKCS7, \"crls=\", ossl_pkcs7_set_crls, 1);\n    rb_define_method(cPKCS7, \"crls\", ossl_pkcs7_get_crls, 0);\n    rb_define_method(cPKCS7, \"add_data\", ossl_pkcs7_add_data, 1);\n    rb_define_alias(cPKCS7,  \"data=\", \"add_data\");\n    rb_define_method(cPKCS7, \"verify\", ossl_pkcs7_verify, -1);\n    rb_define_method(cPKCS7, \"decrypt\", ossl_pkcs7_decrypt, -1);\n    rb_define_method(cPKCS7, \"to_pem\", ossl_pkcs7_to_pem, 0);\n    rb_define_alias(cPKCS7,  \"to_s\", \"to_pem\");\n    rb_define_method(cPKCS7, \"to_der\", ossl_pkcs7_to_der, 0);\n\n    cPKCS7Signer = rb_define_class_under(cPKCS7, \"SignerInfo\", rb_cObject);\n    rb_define_const(cPKCS7, \"Signer\", cPKCS7Signer);\n    rb_define_alloc_func(cPKCS7Signer, ossl_pkcs7si_alloc);\n    rb_define_method(cPKCS7Signer, \"initialize\", ossl_pkcs7si_initialize,3);\n    rb_define_method(cPKCS7Signer, \"issuer\", ossl_pkcs7si_get_issuer, 0);\n    rb_define_alias(cPKCS7Signer, \"name\", \"issuer\");\n    rb_define_method(cPKCS7Signer, \"serial\", ossl_pkcs7si_get_serial,0);\n    rb_define_method(cPKCS7Signer,\"signed_time\",ossl_pkcs7si_get_signed_time,0);\n\n    cPKCS7Recipient = rb_define_class_under(cPKCS7,\"RecipientInfo\",rb_cObject);\n    rb_define_alloc_func(cPKCS7Recipient, ossl_pkcs7ri_alloc);\n    rb_define_method(cPKCS7Recipient, \"initialize\", ossl_pkcs7ri_initialize,1); \n    rb_define_method(cPKCS7Recipient, \"issuer\", ossl_pkcs7ri_get_issuer,0);\n    rb_define_method(cPKCS7Recipient, \"serial\", ossl_pkcs7ri_get_serial,0);\n    rb_define_method(cPKCS7Recipient, \"enc_key\", ossl_pkcs7ri_get_enc_key,0); \n\n#define DefPKCS7Const(x) rb_define_const(cPKCS7, #x, INT2NUM(PKCS7_##x))\n\n    DefPKCS7Const(TEXT);\n    DefPKCS7Const(NOCERTS);\n    DefPKCS7Const(NOSIGS);\n    DefPKCS7Const(NOCHAIN);\n    DefPKCS7Const(NOINTERN);\n    DefPKCS7Const(NOVERIFY);\n    DefPKCS7Const(DETACHED);\n    DefPKCS7Const(BINARY);\n    DefPKCS7Const(NOATTR);\n    DefPKCS7Const(NOSMIMECAP);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_pkcs7.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_PKCS7_H_)\n#define _OSSL_PKCS7_H_\n\nextern VALUE cPKCS7;\nextern VALUE cPKCS7Signer;\nextern VALUE cPKCS7Recipient;\nextern VALUE ePKCS7Error;\n\nvoid Init_ossl_pkcs7(void);\n\n#endif /* _OSSL_PKCS7_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_pkey.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n/*\n * Classes\n */\nVALUE mPKey;\nVALUE cPKey;\nVALUE ePKeyError;\nID id_private_q;\n\n/*\n * callback for generating keys\n */\nvoid\nossl_generate_cb(int p, int n, void *arg)\n{\n    VALUE ary;\n\n    ary = rb_ary_new2(2);\n    rb_ary_store(ary, 0, INT2NUM(p));\n    rb_ary_store(ary, 1, INT2NUM(n));\n\n    rb_yield(ary);\n}\n\n/*\n * Public\n */\nVALUE\nossl_pkey_new(EVP_PKEY *pkey)\n{\n    if (!pkey) {\n\tossl_raise(ePKeyError, \"Cannot make new key from NULL.\");\n    }\n    switch (EVP_PKEY_type(pkey->type)) {\n#if !defined(OPENSSL_NO_RSA)\n    case EVP_PKEY_RSA:\n\treturn ossl_rsa_new(pkey);\n#endif\n#if !defined(OPENSSL_NO_DSA)\n    case EVP_PKEY_DSA:\n\treturn ossl_dsa_new(pkey);\n#endif\n#if !defined(OPENSSL_NO_DH)\n    case EVP_PKEY_DH:\n\treturn ossl_dh_new(pkey);\n#endif\n#if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)\n    case EVP_PKEY_EC:\n\treturn ossl_ec_new(pkey);\n#endif\n    default:\n\tossl_raise(ePKeyError, \"unsupported key type\");\n    }\n    return Qnil; /* not reached */\n}\n\nVALUE\nossl_pkey_new_from_file(VALUE filename)\n{\n    FILE *fp;\n    EVP_PKEY *pkey;\n\n    SafeStringValue(filename);\n    if (!(fp = fopen(RSTRING_PTR(filename), \"r\"))) {\n\tossl_raise(ePKeyError, \"%s\", strerror(errno));\n    }\n\n    pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);\n    fclose(fp);\n    if (!pkey) {\n\tossl_raise(ePKeyError, NULL);\n    }\n\n    return ossl_pkey_new(pkey);\n}\n\nEVP_PKEY *\nGetPKeyPtr(VALUE obj)\n{\n    EVP_PKEY *pkey;\n\n    SafeGetPKey(obj, pkey);\n\n    return pkey;\n}\n\nEVP_PKEY *\nGetPrivPKeyPtr(VALUE obj)\n{\n    EVP_PKEY *pkey;\n\t\n    if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {\n\tossl_raise(rb_eArgError, \"Private key is needed.\");\n    }\n    SafeGetPKey(obj, pkey);\n\n    return pkey;\n}\n\nEVP_PKEY *\nDupPKeyPtr(VALUE obj)\n{\n    EVP_PKEY *pkey;\n\t\n    SafeGetPKey(obj, pkey);\n    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);\n\n    return pkey;\n}\n\nEVP_PKEY *\nDupPrivPKeyPtr(VALUE obj)\n{\n    EVP_PKEY *pkey;\n\t\n    if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {\n\tossl_raise(rb_eArgError, \"Private key is needed.\");\n    }\n    SafeGetPKey(obj, pkey);\n    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);\n\n    return pkey;\n}\n\n/*\n * Private\n */\nstatic VALUE\nossl_pkey_alloc(VALUE klass)\n{\n    EVP_PKEY *pkey;\n    VALUE obj;\n\n    if (!(pkey = EVP_PKEY_new())) {\n\tossl_raise(ePKeyError, NULL);\n    }\n    WrapPKey(klass, obj, pkey);\n\n    return obj;\n}\n\nstatic VALUE\nossl_pkey_initialize(VALUE self)\n{\n    if (rb_obj_is_instance_of(self, cPKey)) {\n\tossl_raise(rb_eNotImpError, \"OpenSSL::PKey::PKey is an abstract class.\");\n    }\n    return self;\n}\n\nstatic VALUE\nossl_pkey_sign(VALUE self, VALUE digest, VALUE data)\n{\n    EVP_PKEY *pkey;\n    EVP_MD_CTX ctx;\n    int buf_len;\n    VALUE str;\n\n    if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {\n\tossl_raise(rb_eArgError, \"Private key is needed.\");\n    }\n    GetPKey(self, pkey);\n    EVP_SignInit(&ctx, GetDigestPtr(digest));\n    StringValue(data);\n    EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));\n    str = rb_str_new(0, EVP_PKEY_size(pkey)+16);\n    if (!EVP_SignFinal(&ctx, RSTRING_PTR(str), &buf_len, pkey))\n\tossl_raise(ePKeyError, NULL);\n    assert(buf_len <= RSTRING_LEN(str));\n    rb_str_set_len(str, buf_len);\n\n    return str;\n}\n\nstatic VALUE\nossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)\n{\n    EVP_PKEY *pkey;\n    EVP_MD_CTX ctx;\n\n    GetPKey(self, pkey);\n    EVP_VerifyInit(&ctx, GetDigestPtr(digest));\n    StringValue(sig);\n    StringValue(data);\n    EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));\n    switch (EVP_VerifyFinal(&ctx, RSTRING_PTR(sig), RSTRING_LEN(sig), pkey)) {\n    case 0:\n\treturn Qfalse;\n    case 1:\n\treturn Qtrue;\n    default:\n\tossl_raise(ePKeyError, NULL);\n    }\n    return Qnil; /* dummy */\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_pkey()\n{\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n        \n    mPKey = rb_define_module_under(mOSSL, \"PKey\");\n\t\n    ePKeyError = rb_define_class_under(mPKey, \"PKeyError\", eOSSLError);\n\n    cPKey = rb_define_class_under(mPKey, \"PKey\", rb_cObject);\n\t\n    rb_define_alloc_func(cPKey, ossl_pkey_alloc);\n    rb_define_method(cPKey, \"initialize\", ossl_pkey_initialize, 0);\n\n    rb_define_method(cPKey, \"sign\", ossl_pkey_sign, 2);\n    rb_define_method(cPKey, \"verify\", ossl_pkey_verify, 3);\n\t\n    id_private_q = rb_intern(\"private?\");\n\t\n    /*\n     * INIT rsa, dsa, dh, ec\n     */\n    Init_ossl_rsa();\n    Init_ossl_dsa();\n    Init_ossl_dh();\n    Init_ossl_ec();\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_pkey.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_PKEY_H_)\n#define _OSSL_PKEY_H_\n\nextern VALUE mPKey;\nextern VALUE cPKey;\nextern VALUE ePKeyError;\nextern ID id_private_q;\n\n#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), \"private\", Qtrue)\n#define OSSL_PKEY_SET_PUBLIC(obj)  rb_iv_set((obj), \"private\", Qfalse)\n#define OSSL_PKEY_IS_PRIVATE(obj)  (rb_iv_get((obj), \"private\") == Qtrue)\n\n#define WrapPKey(klass, obj, pkey) do { \\\n    if (!pkey) { \\\n\trb_raise(rb_eRuntimeError, \"PKEY wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, EVP_PKEY_free, pkey); \\\n    OSSL_PKEY_SET_PUBLIC(obj); \\\n} while (0)\n#define GetPKey(obj, pkey) do {\\\n    Data_Get_Struct(obj, EVP_PKEY, pkey);\\\n    if (!pkey) { \\\n\trb_raise(rb_eRuntimeError, \"PKEY wasn't initialized!\");\\\n    } \\\n} while (0)\n#define SafeGetPKey(obj, pkey) do { \\\n    OSSL_Check_Kind(obj, cPKey); \\\n    GetPKey(obj, pkey); \\\n} while (0)\n\nvoid ossl_generate_cb(int, int, void *);\n\nVALUE ossl_pkey_new(EVP_PKEY *);\nVALUE ossl_pkey_new_from_file(VALUE);\nEVP_PKEY *GetPKeyPtr(VALUE);\nEVP_PKEY *DupPKeyPtr(VALUE);\nEVP_PKEY *GetPrivPKeyPtr(VALUE);\nEVP_PKEY *DupPrivPKeyPtr(VALUE);\nvoid Init_ossl_pkey(void);\n\n/*\n * RSA\n */\nextern VALUE cRSA;\nextern VALUE eRSAError;\n\nVALUE ossl_rsa_new(EVP_PKEY *);\nvoid Init_ossl_rsa(void);\n\n/*\n * DSA\n */\nextern VALUE cDSA;\nextern VALUE eDSAError;\n\nVALUE ossl_dsa_new(EVP_PKEY *);\nvoid Init_ossl_dsa(void);\n\n/*\n * DH\n */\nextern VALUE cDH;\nextern VALUE eDHError;\nextern DH *OSSL_DEFAULT_DH_512;\nextern DH *OSSL_DEFAULT_DH_1024;\n\nVALUE ossl_dh_new(EVP_PKEY *);\nvoid Init_ossl_dh(void);\n\n/*\n * EC\n */\nextern VALUE cEC;\nextern VALUE eECError;\nextern VALUE cEC_GROUP;\nextern VALUE eEC_GROUP;\nextern VALUE cEC_POINT;\nextern VALUE eEC_POINT;\nVALUE ossl_ec_new(EVP_PKEY *);\nvoid Init_ossl_ec(void);\n\n\n#define OSSL_PKEY_BN(keytype, name)\t\t\t\t\t\\\n/*\t\t\t\t\t\t\t\t\t\\\n *  call-seq:\t\t\t\t\t\t\t\t\\\n *     key.##name -> aBN\t\t\t\t\t\t\\\n */\t\t\t\t\t\t\t\t\t\\\nstatic VALUE ossl_##keytype##_get_##name(VALUE self)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tEVP_PKEY *pkey;\t\t\t\t\t\t\t\\\n\tBIGNUM *bn;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tGetPKey(self, pkey);\t\t\t\t\t\t\\\n\tbn = pkey->pkey.keytype->name;\t\t\t\t\t\\\n\tif (bn == NULL)\t\t\t\t\t\t\t\\\n\t\treturn Qnil;\t\t\t\t\t\t\\\n\treturn ossl_bn_new(bn);\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\n/*\t\t\t\t\t\t\t\t\t\\\n *  call-seq:\t\t\t\t\t\t\t\t\\\n *     key.##name = bn -> bn\t\t\t\t\t\t\\\n */\t\t\t\t\t\t\t\t\t\\\nstatic VALUE ossl_##keytype##_set_##name(VALUE self, VALUE bignum)\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tEVP_PKEY *pkey;\t\t\t\t\t\t\t\\\n\tBIGNUM *bn;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tGetPKey(self, pkey);\t\t\t\t\t\t\\\n\tif (NIL_P(bignum)) {\t\t\t\t\t\t\\\n\t\tBN_clear_free(pkey->pkey.keytype->name);\t\t\\\n\t\tpkey->pkey.keytype->name = NULL;\t\t\t\\\n\t\treturn Qnil;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\tbn = GetBNPtr(bignum);\t\t\t\t\t\t\\\n\tif (pkey->pkey.keytype->name == NULL)\t\t\t\t\\\n\t\tpkey->pkey.keytype->name = BN_new();\t\t\t\\\n\tif (pkey->pkey.keytype->name == NULL)\t\t\t\t\\\n\t\tossl_raise(eBNError, NULL);\t\t\t\t\\\n\tif (BN_copy(pkey->pkey.keytype->name, bn) == NULL)\t\t\\\n\t\tossl_raise(eBNError, NULL);\t\t\t\t\\\n\treturn bignum;\t\t\t\t\t\t\t\\\n}\n\n#define DEF_OSSL_PKEY_BN(class, keytype, name)\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\t\\\n\trb_define_method(class, #name, ossl_##keytype##_get_##name, 0);\t\\\n\trb_define_method(class, #name \"=\", ossl_##keytype##_set_##name, 1);\\\n} while (0)\n\n#endif /* _OSSL_PKEY_H_ */\n"
  },
  {
    "path": "ext/openssl/ossl_pkey_dh.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(OPENSSL_NO_DH)\n\n#include \"ossl.h\"\n\n#define GetPKeyDH(obj, pkey) do { \\\n    GetPKey(obj, pkey); \\\n    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) { /* PARANOIA? */ \\\n\tossl_raise(rb_eRuntimeError, \"THIS IS NOT A DH!\") ; \\\n    } \\\n} while (0)\n\n#define DH_HAS_PRIVATE(dh) ((dh)->priv_key)\n\n#ifdef OSSL_ENGINE_ENABLED\n#  define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine)\n#else\n#  define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh)\n#endif\n\n\n/*\n * Classes\n */\nVALUE cDH;\nVALUE eDHError;\n\n/*\n * Public\n */\nstatic VALUE\ndh_instance(VALUE klass, DH *dh)\n{\n    EVP_PKEY *pkey;\n    VALUE obj;\n\t\n    if (!dh) {\n\treturn Qfalse;\n    }\n    if (!(pkey = EVP_PKEY_new())) {\n\treturn Qfalse;\n    }\n    if (!EVP_PKEY_assign_DH(pkey, dh)) {\n\tEVP_PKEY_free(pkey);\n\treturn Qfalse;\n    }\n    WrapPKey(klass, obj, pkey);\n\n    return obj;\n}\n\nVALUE\nossl_dh_new(EVP_PKEY *pkey)\n{\n    VALUE obj;\n\n    if (!pkey) {\n\tobj = dh_instance(cDH, DH_new());\n    } else {\n\tif (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) {\n\t    ossl_raise(rb_eTypeError, \"Not a DH key!\");\n\t}\n\tWrapPKey(cDH, obj, pkey);\n    }\n    if (obj == Qfalse) {\n\tossl_raise(eDHError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n * Private\n */\nstatic DH *\ndh_generate(int size, int gen)\n{\n    DH *dh;\n    \n    dh = DH_generate_parameters(size, gen,\n\t    rb_block_given_p() ? ossl_generate_cb : NULL,\n\t    NULL);\n    if (!dh) return 0;\n\n    if (!DH_generate_key(dh)) {\n\tDH_free(dh);\n\treturn 0;\n    }\n\n    return dh;\n}\n\n/*\n *  call-seq:\n *     DH.generate(size [, generator]) -> dh\n *\n *  === Parameters\n *  * +size+ is an integer representing the desired key size.  Keys smaller than 1024 should be considered insecure.\n *  * +generator+ is a small number > 1, typically 2 or 5.\n *\n */\nstatic VALUE\nossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)\n{\n    DH *dh ;\n    int g = 2;\n    VALUE size, gen, obj;\n\t\n    if (rb_scan_args(argc, argv, \"11\", &size, &gen) == 2) {\n\tg = NUM2INT(gen);\n    }\n    dh = dh_generate(NUM2INT(size), g);\n    obj = dh_instance(klass, dh);\n    if (obj == Qfalse) {\n\tDH_free(dh);\n\tossl_raise(eDHError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     DH.new([size [, generator] | string]) -> dh\n *\n *  === Parameters\n *  * +size+ is an integer representing the desired key size.  Keys smaller than 1024 should be considered insecure.\n *  * +generator+ is a small number > 1, typically 2 or 5.\n *  * +string+ contains the DER or PEM encoded key.\n *\n *  === Examples\n *  * DH.new -> dh\n *  * DH.new(1024) -> dh\n *  * DH.new(1024, 5) -> dh\n *  * DH.new(File.read('key.pem')) -> dh\n */\nstatic VALUE\nossl_dh_initialize(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    DH *dh;\n    int g = 2;\n    BIO *in;\n    VALUE arg, gen;\n\n    GetPKey(self, pkey);\n    if(rb_scan_args(argc, argv, \"02\", &arg, &gen) == 0) {\n      dh = DH_new();\n    }\n    else if (FIXNUM_P(arg)) {\n\tif (!NIL_P(gen)) {\n\t    g = NUM2INT(gen);\n\t}\n\tif (!(dh = dh_generate(FIX2INT(arg), g))) {\n\t    ossl_raise(eDHError, NULL);\n\t}\n    }\n    else {\n\targ = ossl_to_der_if_possible(arg);\n\tin = ossl_obj2bio(arg);\n\tdh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);\n\tif (!dh){\n\t    BIO_reset(in);\n\t    dh = d2i_DHparams_bio(in, NULL);\n\t}\n\tBIO_free(in);\n\tif (!dh) ossl_raise(eDHError, NULL);\n    }\n    if (!EVP_PKEY_assign_DH(pkey, dh)) {\n\tDH_free(dh);\n\tossl_raise(eDHError, NULL);\n    }\n    return self;\n}\n\n/*\n *  call-seq:\n *     dh.public? -> true | false\n *\n */\nstatic VALUE\nossl_dh_is_public(VALUE self)\n{\n    EVP_PKEY *pkey;\n\n    GetPKeyDH(self, pkey);\n\n    return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     dh.private? -> true | false\n *\n */\nstatic VALUE\nossl_dh_is_private(VALUE self)\n{\n    EVP_PKEY *pkey;\n\n    GetPKeyDH(self, pkey);\n\t\n    return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     dh.to_pem -> aString\n *\n */\nstatic VALUE\nossl_dh_export(VALUE self)\n{\n    EVP_PKEY *pkey;\n    BIO *out;\n    VALUE str;\n\n    GetPKeyDH(self, pkey);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eDHError, NULL);\n    }\n    if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) {\n\tBIO_free(out);\n\tossl_raise(eDHError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     dh.to_der -> aString\n *\n */\nstatic VALUE\nossl_dh_to_der(VALUE self)\n{       \n    EVP_PKEY *pkey;\n    unsigned char *p;\n    long len;\n    VALUE str;\n\n    GetPKeyDH(self, pkey);\n    if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0)\n\tossl_raise(eDHError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_DHparams(pkey->pkey.dh, &p) < 0)\n\tossl_raise(eDHError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     dh.params -> hash\n *\n * Stores all parameters of key to the hash\n * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!\n * Don't use :-)) (I's up to you)\n */\nstatic VALUE\nossl_dh_get_params(VALUE self)\n{\n    EVP_PKEY *pkey;\n    VALUE hash;\n\n    GetPKeyDH(self, pkey);\n\n    hash = rb_hash_new();\n\n    rb_hash_aset(hash, rb_str_new2(\"p\"), ossl_bn_new(pkey->pkey.dh->p));\n    rb_hash_aset(hash, rb_str_new2(\"g\"), ossl_bn_new(pkey->pkey.dh->g));\n    rb_hash_aset(hash, rb_str_new2(\"pub_key\"), ossl_bn_new(pkey->pkey.dh->pub_key));\n    rb_hash_aset(hash, rb_str_new2(\"priv_key\"), ossl_bn_new(pkey->pkey.dh->priv_key));\n    \n    return hash;\n}\n\n/*\n *  call-seq:\n *     dh.to_text -> aString\n *\n * Prints all parameters of key to buffer\n * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!\n * Don't use :-)) (I's up to you)\n */\nstatic VALUE\nossl_dh_to_text(VALUE self)\n{\n    EVP_PKEY *pkey;\n    BIO *out;\n    VALUE str;\n\n    GetPKeyDH(self, pkey);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eDHError, NULL);\n    }\n    if (!DHparams_print(out, pkey->pkey.dh)) {\n\tBIO_free(out);\n\tossl_raise(eDHError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     dh.public_key -> aDH\n *\n *  Makes new instance DH PUBLIC_KEY from PRIVATE_KEY\n */\nstatic VALUE\nossl_dh_to_public_key(VALUE self)\n{\n    EVP_PKEY *pkey;\n    DH *dh;\n    VALUE obj;\n\t\n    GetPKeyDH(self, pkey);\n    dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */\n    obj = dh_instance(CLASS_OF(self), dh);\n    if (obj == Qfalse) {\n\tDH_free(dh);\n\tossl_raise(eDHError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     dh.check_params -> true | false\n *\n */\nstatic VALUE\nossl_dh_check_params(VALUE self)\n{\n    DH *dh;\n    EVP_PKEY *pkey;\n    int codes;\n    \n    GetPKeyDH(self, pkey);\n    dh = pkey->pkey.dh;\n\n    if (!DH_check(dh, &codes)) {\n\treturn Qfalse;\n    }\n\n    return codes == 0 ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     dh.generate_key -> self\n *\n */\nstatic VALUE\nossl_dh_generate_key(VALUE self)\n{\n    DH *dh;\n    EVP_PKEY *pkey;\n\n    GetPKeyDH(self, pkey);\n    dh = pkey->pkey.dh;\n\n    if (!DH_generate_key(dh))\n\tossl_raise(eDHError, \"Failed to generate key\");\n    return self;\n}\n\n/*\n *  call-seq:\n *     dh.compute_key(pub_bn) -> aString\n *\n *  === Parameters\n *  * +pub_bn+ is a OpenSSL::BN.\n *\n *  Returns aString containing a shared secret computed from the other parties public value.\n *\n *  See DH_compute_key() for further information.\n *\n */\nstatic VALUE\nossl_dh_compute_key(VALUE self, VALUE pub)\n{\n    DH *dh;\n    EVP_PKEY *pkey;\n    BIGNUM *pub_key;\n    VALUE str;\n    int len;\n\n    GetPKeyDH(self, pkey);\n    dh = pkey->pkey.dh;\n    pub_key = GetBNPtr(pub);\n    len = DH_size(dh);\n    str = rb_str_new(0, len);\n    if ((len = DH_compute_key(RSTRING_PTR(str), pub_key, dh)) < 0) {\n\tossl_raise(eDHError, NULL);\n    }\n    rb_str_set_len(str, len);\n\n    return str;\n}\n\nOSSL_PKEY_BN(dh, p);\nOSSL_PKEY_BN(dh, g);\nOSSL_PKEY_BN(dh, pub_key);\nOSSL_PKEY_BN(dh, priv_key);\n\n/*\n * -----BEGIN DH PARAMETERS-----\n * MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2\n * zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC\n * -----END DH PARAMETERS-----\n */\nstatic unsigned char DEFAULT_DH_512_PRIM[] = {\n    0xf4, 0xcd, 0x71, 0xe5, 0x8d, 0x18, 0x3f, 0x98,\n    0x9f, 0x4f, 0x60, 0xb0, 0x02, 0x2e, 0xfe, 0x7c,\n    0x09, 0xdf, 0x15, 0xc4, 0x1c, 0x71, 0x63, 0xba,\n    0x04, 0xb8, 0x27, 0x94, 0x44, 0xc8, 0x93, 0xa8,\n    0x48, 0x4c, 0xca, 0x6d, 0x7a, 0xae, 0x18, 0x4a,\n    0x81, 0x91, 0xb6, 0xce, 0x4d, 0x8e, 0xf6, 0xe5,\n    0x08, 0x04, 0x8c, 0x52, 0x8f, 0xe3, 0x4a, 0x31,\n    0x44, 0x47, 0x19, 0xa1, 0x4a, 0xc8, 0x8b, 0xcb,\n};\nstatic unsigned char DEFAULT_DH_512_GEN[] = { 0x02 }; \nDH *OSSL_DEFAULT_DH_512 = NULL;\n  \n/* \n * -----BEGIN DH PARAMETERS-----\n * MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ\n * AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR\n * T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC\n * -----END DH PARAMETERS-----\n */\nstatic unsigned char DEFAULT_DH_1024_PRIM[] = {\n    0x9d, 0x25, 0x39, 0x5c, 0xb4, 0x54, 0x8a, 0xff,\n    0x25, 0xe6, 0xd6, 0x9f, 0x4c, 0xc3, 0xc1, 0x8d,\n    0xa1, 0xfa, 0xba, 0x88, 0x4c, 0x53, 0xa9, 0x74,\n    0xda, 0xfa, 0xba, 0x0b, 0x20, 0xbe, 0x40, 0xd7,\n    0xba, 0xe7, 0x1d, 0x70, 0x28, 0x61, 0x60, 0x4c,\n    0x49, 0x01, 0x5f, 0xd9, 0x0f, 0x60, 0x16, 0x3d,\n    0xba, 0xd3, 0xa9, 0x5e, 0xfa, 0x98, 0x64, 0x60,\n    0x26, 0x0e, 0x04, 0x75, 0xd8, 0x13, 0xd7, 0x31,\n    0xb4, 0x8e, 0xad, 0xeb, 0x9c, 0x57, 0x4c, 0x8f,\n    0x65, 0xf3, 0x90, 0x16, 0x31, 0xdc, 0x15, 0x6f,\n    0x7d, 0x1d, 0x00, 0xae, 0x76, 0xf2, 0xd1, 0x11,\n    0xd1, 0x4f, 0x88, 0x7b, 0x29, 0x9f, 0xf6, 0xce,\n    0x68, 0xef, 0x57, 0xe7, 0x85, 0xf2, 0x40, 0x54,\n    0x1c, 0x12, 0x40, 0xa2, 0x35, 0x25, 0xcf, 0x12,\n    0xa3, 0xe1, 0x07, 0x8e, 0xdb, 0x1d, 0xb4, 0x14,\n    0xff, 0x57, 0xe7, 0x19, 0x8d, 0x51, 0x77, 0x83\n};\nstatic unsigned char DEFAULT_DH_1024_GEN[] = { 0x02 };\nDH *OSSL_DEFAULT_DH_1024 = NULL;\n\nstatic DH*\nossl_create_dh(unsigned char *p, size_t plen, unsigned char *g, size_t glen)\n{\n    DH *dh;\n\n    if ((dh = DH_new()) == NULL) ossl_raise(eDHError, NULL);\n    dh->p = BN_bin2bn(p, plen, NULL);\n    dh->g = BN_bin2bn(g, glen, NULL);\n    if (dh->p == NULL || dh->g == NULL){\n        DH_free(dh);\n\tossl_raise(eDHError, NULL);\n    }\n\n    return dh;\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_dh()\n{\n#if 0 /* let rdoc know about mOSSL and mPKey */\n    mOSSL = rb_define_module(\"OpenSSL\");\n    mPKey = rb_define_module_under(mOSSL, \"PKey\");\n#endif\n\n    eDHError = rb_define_class_under(mPKey, \"DHError\", ePKeyError);\n    cDH = rb_define_class_under(mPKey, \"DH\", cPKey);\n    rb_define_singleton_method(cDH, \"generate\", ossl_dh_s_generate, -1);\n    rb_define_method(cDH, \"initialize\", ossl_dh_initialize, -1);\n    rb_define_method(cDH, \"public?\", ossl_dh_is_public, 0);\n    rb_define_method(cDH, \"private?\", ossl_dh_is_private, 0);\n    rb_define_method(cDH, \"to_text\", ossl_dh_to_text, 0);\n    rb_define_method(cDH, \"export\", ossl_dh_export, 0);\n    rb_define_alias(cDH, \"to_pem\", \"export\");\n    rb_define_alias(cDH, \"to_s\", \"export\");\n    rb_define_method(cDH, \"to_der\", ossl_dh_to_der, 0);\n    rb_define_method(cDH, \"public_key\", ossl_dh_to_public_key, 0);\n    rb_define_method(cDH, \"params_ok?\", ossl_dh_check_params, 0);\n    rb_define_method(cDH, \"generate_key!\", ossl_dh_generate_key, 0);\n    rb_define_method(cDH, \"compute_key\", ossl_dh_compute_key, 1);\n    DEF_OSSL_PKEY_BN(cDH, dh, p);\n    DEF_OSSL_PKEY_BN(cDH, dh, g);\n    DEF_OSSL_PKEY_BN(cDH, dh, pub_key);\n    DEF_OSSL_PKEY_BN(cDH, dh, priv_key);\n    rb_define_method(cDH, \"params\", ossl_dh_get_params, 0);\n\n    OSSL_DEFAULT_DH_512 = ossl_create_dh(\n\tDEFAULT_DH_512_PRIM, sizeof(DEFAULT_DH_512_PRIM),\n\tDEFAULT_DH_512_GEN, sizeof(DEFAULT_DH_512_GEN));\n    OSSL_DEFAULT_DH_1024 = ossl_create_dh(\n\tDEFAULT_DH_1024_PRIM, sizeof(DEFAULT_DH_1024_PRIM),\n\tDEFAULT_DH_1024_GEN, sizeof(DEFAULT_DH_1024_GEN));\n}\n\n#else /* defined NO_DH */\nvoid\nInit_ossl_dh()\n{\n}\n#endif /* NO_DH */\n\n"
  },
  {
    "path": "ext/openssl/ossl_pkey_dsa.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(OPENSSL_NO_DSA)\n\n#include \"ossl.h\"\n\n#define GetPKeyDSA(obj, pkey) do { \\\n    GetPKey(obj, pkey); \\\n    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DSA) { /* PARANOIA? */ \\\n\tossl_raise(rb_eRuntimeError, \"THIS IS NOT A DSA!\"); \\\n    } \\\n} while (0)\n\n#define DSA_HAS_PRIVATE(dsa) ((dsa)->priv_key)\n#define DSA_PRIVATE(obj,dsa) (DSA_HAS_PRIVATE(dsa)||OSSL_PKEY_IS_PRIVATE(obj))\n\n/*\n * Classes\n */\nVALUE cDSA;\nVALUE eDSAError;\n\n/*\n * Public\n */\nstatic VALUE\ndsa_instance(VALUE klass, DSA *dsa)\n{\n    EVP_PKEY *pkey;\n    VALUE obj;\n\t\n    if (!dsa) {\n\treturn Qfalse;\n    }\n    if (!(pkey = EVP_PKEY_new())) {\n\treturn Qfalse;\n    }\n    if (!EVP_PKEY_assign_DSA(pkey, dsa)) {\n\tEVP_PKEY_free(pkey);\n\treturn Qfalse;\n    }\n    WrapPKey(klass, obj, pkey);\n\n    return obj;\n}\n\nVALUE\nossl_dsa_new(EVP_PKEY *pkey)\n{\n    VALUE obj;\n\n    if (!pkey) {\n\tobj = dsa_instance(cDSA, DSA_new());\n    } else {\n\tif (EVP_PKEY_type(pkey->type) != EVP_PKEY_DSA) {\n\t    ossl_raise(rb_eTypeError, \"Not a DSA key!\");\n\t}\n\tWrapPKey(cDSA, obj, pkey);\n    }\n    if (obj == Qfalse) {\n\tossl_raise(eDSAError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n * Private\n */\nstatic DSA *\ndsa_generate(int size)\n{\n    DSA *dsa;\n    unsigned char seed[20];\n    int seed_len = 20, counter;\n    unsigned long h;\n\n    if (!RAND_bytes(seed, seed_len)) {\n\treturn 0;\n    }\n    dsa = DSA_generate_parameters(size, seed, seed_len, &counter, &h,\n\t    rb_block_given_p() ? ossl_generate_cb : NULL,\n\t    NULL);\n    if(!dsa) return 0;\n\n    if (!DSA_generate_key(dsa)) {\n\tDSA_free(dsa);\n\treturn 0;\n    }\n\n    return dsa;\n}\n\n/*\n *  call-seq:\n *    DSA.generate(size) -> dsa\n *\n *  === Parameters\n *  * +size+ is an integer representing the desired key size.\n *\n */\nstatic VALUE\nossl_dsa_s_generate(VALUE klass, VALUE size)\n{\n    DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */\n    VALUE obj = dsa_instance(klass, dsa);\n\n    if (obj == Qfalse) {\n\tDSA_free(dsa);\n\tossl_raise(eDSAError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *    DSA.new([size | string [, pass]) -> dsa\n *\n *  === Parameters\n *  * +size+ is an integer representing the desired key size.\n *  * +string+ contains a DER or PEM encoded key.\n *  * +pass+ is a string that contains a optional password.\n *\n *  === Examples\n *  * DSA.new -> dsa\n *  * DSA.new(1024) -> dsa\n *  * DSA.new(File.read('dsa.pem')) -> dsa\n *  * DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa\n *\n */\nstatic VALUE\nossl_dsa_initialize(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    DSA *dsa;\n    BIO *in;\n    char *passwd = NULL;\n    VALUE arg, pass;\n\t\n    GetPKey(self, pkey);\n    if(rb_scan_args(argc, argv, \"02\", &arg, &pass) == 0) {\n        dsa = DSA_new();\n    }\n    else if (FIXNUM_P(arg)) {\n\tif (!(dsa = dsa_generate(FIX2INT(arg)))) {\n\t    ossl_raise(eDSAError, NULL);\n\t}\n    }\n    else {\n\tif (!NIL_P(pass)) passwd = StringValuePtr(pass);\n\targ = ossl_to_der_if_possible(arg);\n\tin = ossl_obj2bio(arg);\n\tdsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);\n\tif (!dsa) {\n\t    BIO_reset(in);\n\t    dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);\n\t}\n\tif (!dsa) {\n\t    BIO_reset(in);\n\t    dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);\n\t}\n\tif (!dsa) {\n\t    BIO_reset(in);\n\t    dsa = d2i_DSAPrivateKey_bio(in, NULL);\n\t}\n\tif (!dsa) {\n\t    BIO_reset(in);\n\t    dsa = d2i_DSA_PUBKEY_bio(in, NULL);\n\t}\n\tBIO_free(in);\n\tif (!dsa) ossl_raise(eDSAError, \"Neither PUB key nor PRIV key:\");\n    }\n    if (!EVP_PKEY_assign_DSA(pkey, dsa)) {\n\tDSA_free(dsa);\n\tossl_raise(eDSAError, NULL);\n    }\n\n    return self;\n}\n\n/*\n *  call-seq:\n *    dsa.public? -> true | false\n *\n */\nstatic VALUE\nossl_dsa_is_public(VALUE self)\n{\n    EVP_PKEY *pkey;\n\n    GetPKeyDSA(self, pkey);\n\n    return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *    dsa.private? -> true | false\n *\n */\nstatic VALUE\nossl_dsa_is_private(VALUE self)\n{\n    EVP_PKEY *pkey;\n\t\n    GetPKeyDSA(self, pkey);\n\t\n    return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *    dsa.to_pem([cipher, password]) -> aString\n *\n *  === Parameters\n *  +cipher+ is an OpenSSL::Cipher.\n *  +password+ is a string containing your password.\n *\n *  === Examples\n *  * DSA.to_pem -> aString\n *  * DSA.to_pem(cipher, 'mypassword') -> aString\n *\n */\nstatic VALUE\nossl_dsa_export(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    BIO *out;\n    const EVP_CIPHER *ciph = NULL;\n    char *passwd = NULL;\n    VALUE cipher, pass, str;\n\n    GetPKeyDSA(self, pkey);\n    rb_scan_args(argc, argv, \"02\", &cipher, &pass);\n    if (!NIL_P(cipher)) {\n\tciph = GetCipherPtr(cipher);\n\tif (!NIL_P(pass)) {\n\t    passwd = StringValuePtr(pass);\n\t}\n    }\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eDSAError, NULL);\n    }\n    if (DSA_HAS_PRIVATE(pkey->pkey.dsa)) {\n\tif (!PEM_write_bio_DSAPrivateKey(out, pkey->pkey.dsa, ciph,\n\t\t\t\t\t NULL, 0, ossl_pem_passwd_cb, passwd)){\n\t    BIO_free(out);\n\t    ossl_raise(eDSAError, NULL);\n\t}\n    } else {\n\tif (!PEM_write_bio_DSAPublicKey(out, pkey->pkey.dsa)) {\n\t    BIO_free(out);\n\t    ossl_raise(eDSAError, NULL);\n\t}\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *    dsa.to_der -> aString\n *\n */\nstatic VALUE\nossl_dsa_to_der(VALUE self)\n{\n    EVP_PKEY *pkey;\n    int (*i2d_func)_((DSA*, unsigned char**));\n    unsigned char *p;\n    long len;\n    VALUE str;\n\n    GetPKeyDSA(self, pkey);\n    if(DSA_HAS_PRIVATE(pkey->pkey.dsa))\n\ti2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey;\n    else\n\ti2d_func = i2d_DSA_PUBKEY;\n    if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)\n\tossl_raise(eDSAError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_func(pkey->pkey.dsa, &p) < 0)\n\tossl_raise(eDSAError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *    dsa.params -> hash\n *\n * Stores all parameters of key to the hash\n * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!\n * Don't use :-)) (I's up to you)\n */\nstatic VALUE\nossl_dsa_get_params(VALUE self)\n{\n    EVP_PKEY *pkey;\n    VALUE hash;\n\n    GetPKeyDSA(self, pkey);\n\n    hash = rb_hash_new();\n\n    rb_hash_aset(hash, rb_str_new2(\"p\"), ossl_bn_new(pkey->pkey.dsa->p));\n    rb_hash_aset(hash, rb_str_new2(\"q\"), ossl_bn_new(pkey->pkey.dsa->q));\n    rb_hash_aset(hash, rb_str_new2(\"g\"), ossl_bn_new(pkey->pkey.dsa->g));\n    rb_hash_aset(hash, rb_str_new2(\"pub_key\"), ossl_bn_new(pkey->pkey.dsa->pub_key));\n    rb_hash_aset(hash, rb_str_new2(\"priv_key\"), ossl_bn_new(pkey->pkey.dsa->priv_key));\n    \n    return hash;\n}\n\n/*\n *  call-seq:\n *    dsa.to_text -> aString\n *\n * Prints all parameters of key to buffer\n * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!\n * Don't use :-)) (I's up to you)\n */\nstatic VALUE\nossl_dsa_to_text(VALUE self)\n{\n    EVP_PKEY *pkey;\n    BIO *out;\n    VALUE str;\n\n    GetPKeyDSA(self, pkey);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eDSAError, NULL);\n    }\n    if (!DSA_print(out, pkey->pkey.dsa, 0)) { /* offset = 0 */\n\tBIO_free(out);\n\tossl_raise(eDSAError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *    dsa.public_key -> aDSA\n *\n * Makes new instance DSA PUBLIC_KEY from PRIVATE_KEY\n */\nstatic VALUE\nossl_dsa_to_public_key(VALUE self)\n{\n    EVP_PKEY *pkey;\n    DSA *dsa;\n    VALUE obj;\n\t\n    GetPKeyDSA(self, pkey);\n    /* err check performed by dsa_instance */\n    dsa = DSAPublicKey_dup(pkey->pkey.dsa);\n    obj = dsa_instance(CLASS_OF(self), dsa);\n    if (obj == Qfalse) {\n\tDSA_free(dsa);\n\tossl_raise(eDSAError, NULL);\n    }\n    return obj;\n}\n\n#define ossl_dsa_buf_size(pkey) (DSA_size((pkey)->pkey.dsa)+16)\n\n/*\n *  call-seq:\n *    dsa.syssign(string) -> aString\n *\n */\nstatic VALUE\nossl_dsa_sign(VALUE self, VALUE data)\n{\n    EVP_PKEY *pkey;\n    int buf_len;\n    VALUE str;\n\n    GetPKeyDSA(self, pkey);\n    StringValue(data);\n    if (!DSA_PRIVATE(self, pkey->pkey.dsa)) {\n\tossl_raise(eDSAError, \"Private DSA key needed!\");\n    }\n    str = rb_str_new(0, ossl_dsa_buf_size(pkey));\n    if (!DSA_sign(0, RSTRING_PTR(data), RSTRING_LEN(data), RSTRING_PTR(str),\n\t\t  &buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */\n\tossl_raise(eDSAError, NULL);\n    }\n    rb_str_set_len(str, buf_len);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *    dsa.sysverify(digest, sig) -> true | false\n *\n */\nstatic VALUE\nossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)\n{\n    EVP_PKEY *pkey;\n    int ret;\n\n    GetPKeyDSA(self, pkey);\n    StringValue(digest);\n    StringValue(sig);\n    /* type is ignored (0) */\n    ret = DSA_verify(0, RSTRING_PTR(digest), RSTRING_LEN(digest),\n\t\t     RSTRING_PTR(sig), RSTRING_LEN(sig), pkey->pkey.dsa);\n    if (ret < 0) {\n\tossl_raise(eDSAError, NULL);\n    }\n    else if (ret == 1) {\n\treturn Qtrue;\n    }\n\n    return Qfalse;\n}\n\nOSSL_PKEY_BN(dsa, p);\nOSSL_PKEY_BN(dsa, q);\nOSSL_PKEY_BN(dsa, g);\nOSSL_PKEY_BN(dsa, pub_key);\nOSSL_PKEY_BN(dsa, priv_key);\n\n/*\n * INIT\n */\nvoid\nInit_ossl_dsa()\n{\n#if 0 /* let rdoc know about mOSSL and mPKey */\n    mOSSL = rb_define_module(\"OpenSSL\");\n    mPKey = rb_define_module_under(mOSSL, \"PKey\");\n#endif\n\n    eDSAError = rb_define_class_under(mPKey, \"DSAError\", ePKeyError);\n\n    cDSA = rb_define_class_under(mPKey, \"DSA\", cPKey);\n\t\n    rb_define_singleton_method(cDSA, \"generate\", ossl_dsa_s_generate, 1);\n    rb_define_method(cDSA, \"initialize\", ossl_dsa_initialize, -1);\n\n    rb_define_method(cDSA, \"public?\", ossl_dsa_is_public, 0);\n    rb_define_method(cDSA, \"private?\", ossl_dsa_is_private, 0);\n    rb_define_method(cDSA, \"to_text\", ossl_dsa_to_text, 0);\n    rb_define_method(cDSA, \"export\", ossl_dsa_export, -1);\n    rb_define_alias(cDSA, \"to_pem\", \"export\");\n    rb_define_alias(cDSA, \"to_s\", \"export\");\n    rb_define_method(cDSA, \"to_der\", ossl_dsa_to_der, 0);\n    rb_define_method(cDSA, \"public_key\", ossl_dsa_to_public_key, 0);\n    rb_define_method(cDSA, \"syssign\", ossl_dsa_sign, 1);\n    rb_define_method(cDSA, \"sysverify\", ossl_dsa_verify, 2);\n\n    DEF_OSSL_PKEY_BN(cDSA, dsa, p);\n    DEF_OSSL_PKEY_BN(cDSA, dsa, q);\n    DEF_OSSL_PKEY_BN(cDSA, dsa, g);\n    DEF_OSSL_PKEY_BN(cDSA, dsa, pub_key);\n    DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key);\n\n    rb_define_method(cDSA, \"params\", ossl_dsa_get_params, 0);\n}\n\n#else /* defined NO_DSA */\nvoid\nInit_ossl_dsa()\n{\n}\n#endif /* NO_DSA */\n"
  },
  {
    "path": "ext/openssl/ossl_pkey_ec.c",
    "content": "/*\n * Copyright (C) 2006-2007 Technorama Ltd. <oss-ruby@technorama.net>\n */\n\n#include \"ossl.h\"\n\n#if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)\n\ntypedef struct {\n\tEC_GROUP *group;\n\tint dont_free;\n} ossl_ec_group;\n\ntypedef struct {\n\tEC_POINT *point;\n\tint dont_free;\n} ossl_ec_point;\n\n\n#define EXPORT_PEM 0\n#define EXPORT_DER 1\n\n\n#define GetPKeyEC(obj, pkey) do { \\\n    GetPKey(obj, pkey); \\\n    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) { \\\n\tossl_raise(rb_eRuntimeError, \"THIS IS NOT A EC PKEY!\"); \\\n    } \\\n} while (0)\n\n#define SafeGet_ec_group(obj, group) do { \\\n    OSSL_Check_Kind(obj, cEC_GROUP); \\\n    Data_Get_Struct(obj, ossl_ec_group, group); \\\n} while(0)\n\n#define Get_EC_KEY(obj, key) do { \\\n    EVP_PKEY *pkey; \\\n    GetPKeyEC(obj, pkey); \\\n    key = pkey->pkey.ec; \\\n} while(0)\n\n#define Require_EC_KEY(obj, key) do { \\\n    Get_EC_KEY(obj, key); \\\n    if (key == NULL) \\\n        rb_raise(eECError, \"EC_KEY is not initialized\"); \\\n} while(0)\n\n#define SafeRequire_EC_KEY(obj, key) do { \\\n    OSSL_Check_Kind(obj, cEC); \\\n    Require_EC_KEY(obj, key); \\\n} while (0)\n\n#define Get_EC_GROUP(obj, g) do { \\\n    ossl_ec_group *ec_group; \\\n    Data_Get_Struct(obj, ossl_ec_group, ec_group); \\\n    if (ec_group == NULL) \\\n        rb_raise(eEC_GROUP, \"missing ossl_ec_group structure\"); \\\n    g = ec_group->group; \\\n} while(0)\n\n#define Require_EC_GROUP(obj, group) do { \\\n    Get_EC_GROUP(obj, group); \\\n    if (group == NULL) \\\n        rb_raise(eEC_GROUP, \"EC_GROUP is not initialized\"); \\\n} while(0)\n\n#define SafeRequire_EC_GROUP(obj, group) do { \\\n    OSSL_Check_Kind(obj, cEC_GROUP); \\\n    Require_EC_GROUP(obj, group); \\\n} while(0)\n\n#define Get_EC_POINT(obj, p) do { \\\n    ossl_ec_point *ec_point; \\\n    Data_Get_Struct(obj, ossl_ec_point, ec_point); \\\n    if (ec_point == NULL) \\\n        rb_raise(eEC_POINT, \"missing ossl_ec_point structure\"); \\\n    p = ec_point->point; \\\n} while(0)\n\n#define Require_EC_POINT(obj, point) do { \\\n    Get_EC_POINT(obj, point); \\\n    if (point == NULL) \\\n        rb_raise(eEC_POINT, \"EC_POINT is not initialized\"); \\\n} while(0)\n\n#define SafeRequire_EC_POINT(obj, point) do { \\\n    OSSL_Check_Kind(obj, cEC_POINT); \\\n    Require_EC_POINT(obj, point); \\\n} while(0)\n\nVALUE cEC;\nVALUE eECError;\nVALUE cEC_GROUP;\nVALUE eEC_GROUP;\nVALUE cEC_POINT;\nVALUE eEC_POINT;\n\nstatic ID s_GFp;\nstatic ID s_GFp_simple;\nstatic ID s_GFp_mont;\nstatic ID s_GFp_nist;\nstatic ID s_GF2m;\nstatic ID s_GF2m_simple;\n\nstatic ID ID_uncompressed;\nstatic ID ID_compressed;\nstatic ID ID_hybrid;\n\nstatic VALUE ec_instance(VALUE klass, EC_KEY *ec)\n{\n    EVP_PKEY *pkey;\n    VALUE obj;\n\t\n    if (!ec) {\n\treturn Qfalse;\n    }\n    if (!(pkey = EVP_PKEY_new())) {\n\treturn Qfalse;\n    }\n    if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {\n\tEVP_PKEY_free(pkey);\n\treturn Qfalse;\n    }\n    WrapPKey(klass, obj, pkey);\n\n    return obj;\n}\n\nVALUE ossl_ec_new(EVP_PKEY *pkey)\n{\n    VALUE obj;\n\n    if (!pkey) {\n\tobj = ec_instance(cEC, EC_KEY_new());\n    } else {\n\tif (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {\n\t    ossl_raise(rb_eTypeError, \"Not a EC key!\");\n\t}\n\tWrapPKey(cEC, obj, pkey);\n    }\n    if (obj == Qfalse) {\n\tossl_raise(eECError, NULL);\n    }\n\n    return obj;\n}\n\n\n/*  call-seq:\n *     OpenSSL::PKey::EC.new()\n *     OpenSSL::PKey::EC.new(ec_key)\n *     OpenSSL::PKey::EC.new(ec_group)\n *     OpenSSL::PKey::EC.new(\"secp112r1\")\n *     OpenSSL::PKey::EC.new(pem_string)\n *     OpenSSL::PKey::EC.new(der_string)\n *\n *  See the OpenSSL documentation for:\n *     EC_KEY_*\n */\nstatic VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    EC_KEY *ec = NULL;\n    VALUE arg, pass;\n    VALUE group = Qnil;\n\t\n    GetPKey(self, pkey);\n    if (pkey->pkey.ec)\n        rb_raise(eECError, \"EC_KEY already initialized\");\n\n    rb_scan_args(argc, argv, \"02\", &arg, &pass);\n\n    if (NIL_P(arg)) {\n        ec = EC_KEY_new();\n    } else {\n        if (rb_obj_is_kind_of(arg, cEC)) {\n            EC_KEY *other_ec = NULL;\n\n            SafeRequire_EC_KEY(arg, other_ec);\n            ec = EC_KEY_dup(other_ec);\n        } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {\n        \tec = EC_KEY_new();\n        \tgroup = arg;\n        } else {\n            BIO *in = ossl_obj2bio(arg);\n\n            ec = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);\n            if (!ec) {\n                BIO_reset(in);\n                ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);\n            }\n            if (!ec) {\n                BIO_reset(in);\n                ec = d2i_ECPrivateKey_bio(in, NULL);\n            }\n            if (!ec) {\n                BIO_reset(in);\n                ec = d2i_EC_PUBKEY_bio(in, NULL);\n            }\n\n            BIO_free(in);\n\n            if (ec == NULL) {\n                const char *name = STR2CSTR(arg);\n                int nid = OBJ_sn2nid(name);\n\n                if (nid == NID_undef)\n                    ossl_raise(eECError, \"unknown curve name (%s)\\n\", name);\n\n                if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL)\n                    ossl_raise(eECError, \"unable to create curve (%s)\\n\", name);\n\n                EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);\n                EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);\n            }\n        }\n    }\n\n    if (ec == NULL)\n        ossl_raise(eECError, NULL);\n\n    if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {\n\tEC_KEY_free(ec);\n\tossl_raise(eECError, \"EVP_PKEY_assign_EC_KEY\");\n    }\n\n    rb_iv_set(self, \"@group\", Qnil);\n\n    if (!NIL_P(group))\n        rb_funcall(self, rb_intern(\"group=\"), 1, arg);\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     key.group   => group\n *\n *  Returns a constant <code>OpenSSL::EC::Group</code> that is tied to the key.\n *  Modifying the returned group can make the key invalid.\n */\nstatic VALUE ossl_ec_key_get_group(VALUE self)\n{\n    VALUE group_v;\n    EC_KEY *ec;\n    ossl_ec_group *ec_group;\n    EC_GROUP *group;\n\n    Require_EC_KEY(self, ec);\n\n    group_v = rb_iv_get(self, \"@group\");\n    if (!NIL_P(group_v))\n        return group_v;\n\n    if ((group = (EC_GROUP *)EC_KEY_get0_group(ec)) != NULL) {\n        group_v = rb_obj_alloc(cEC_GROUP);\n        SafeGet_ec_group(group_v, ec_group);\n        ec_group->group = group;\n        ec_group->dont_free = 1;\n        rb_iv_set(group_v, \"@key\", self);\n        rb_iv_set(self, \"@group\", group_v);\n        return group_v;\n    }\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     key.group = group   => group\n *\n *  Returns the same object passed, not the group object associated with the key.\n *  If you wish to access the group object tied to the key call key.group after setting\n *  the group.\n *\n *  Setting the group will immediately destroy any previously assigned group object.\n *  The group is internally copied by OpenSSL.  Modifying the original group after \n *  assignment will not effect the internal key structure.\n *  (your changes may be lost).  BE CAREFUL.\n *\n *  EC_KEY_set_group calls EC_GROUP_free(key->group) then EC_GROUP_dup(), not EC_GROUP_copy.\n *  This documentation is accurate for OpenSSL 0.9.8b.\n */\nstatic VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v)\n{\n    VALUE old_group_v;\n    EC_KEY *ec;\n    EC_GROUP *group;\n\n    Require_EC_KEY(self, ec);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    old_group_v = rb_iv_get(self, \"@group\");\n    if (!NIL_P(old_group_v)) {\n        ossl_ec_group *old_ec_group;\n        SafeGet_ec_group(old_group_v, old_ec_group);\n\n        old_ec_group->group = NULL;\n        old_ec_group->dont_free = 0;\n        rb_iv_set(old_group_v, \"@key\", Qnil);\n    }\n\n    rb_iv_set(self, \"@group\", Qnil);\n\n    if (EC_KEY_set_group(ec, group) != 1)\n        ossl_raise(eECError, \"EC_KEY_set_group\");\n\n    return group_v;\n}\n\n/*\n *  call-seq:\n *     key.private_key   => OpenSSL::BN\n *\n *  See the OpenSSL documentation for EC_KEY_get0_private_key()\n */\nstatic VALUE ossl_ec_key_get_private_key(VALUE self)\n{\n    EC_KEY *ec;\n    const BIGNUM *bn;\n\n    Require_EC_KEY(self, ec);\n\n    if ((bn = EC_KEY_get0_private_key(ec)) == NULL)\n        return Qnil;\n\n    return ossl_bn_new(bn);\n}\n\n/*\n *  call-seq:\n *     key.private_key = openssl_bn\n *\n *  See the OpenSSL documentation for EC_KEY_set_private_key()\n */\nstatic VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)\n{\n    EC_KEY *ec;\n    BIGNUM *bn = NULL;\n\n    Require_EC_KEY(self, ec);\n    if (!NIL_P(private_key))\n        bn = GetBNPtr(private_key);\n\n    switch (EC_KEY_set_private_key(ec, bn)) {\n    case 1:\n        break;\n    case 0:\n        if (bn == NULL)\n            break;\n    default:\n        ossl_raise(eECError, \"EC_KEY_set_private_key\");\n    }\n\n    return private_key;\n}\n\n\nstatic VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v)\n{\n    VALUE obj;\n    const EC_GROUP *group;\n    ossl_ec_point *new_point;\n\n    obj = rb_obj_alloc(cEC_POINT);\n    Data_Get_Struct(obj, ossl_ec_point, new_point);\n\n    SafeRequire_EC_GROUP(group_v, group);\n\n    new_point->point = EC_POINT_dup(point, group);\n    if (new_point->point == NULL)\n        ossl_raise(eEC_POINT, \"EC_POINT_dup\");\n    rb_iv_set(obj, \"@group\", group_v);\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     key.public_key   => OpenSSL::PKey::EC::Point\n *\n *  See the OpenSSL documentation for EC_KEY_get0_public_key()\n */\nstatic VALUE ossl_ec_key_get_public_key(VALUE self)\n{\n    EC_KEY *ec;\n    const EC_POINT *point;\n    VALUE group;\n\n    Require_EC_KEY(self, ec);\n\n    if ((point = EC_KEY_get0_public_key(ec)) == NULL)\n        return Qnil;\n\n    group = rb_funcall(self, rb_intern(\"group\"), 0);\n    if (NIL_P(group))\n        ossl_raise(eECError, \"EC_KEY_get0_get0_group (has public_key but no group???\");\n\n    return ossl_ec_point_dup(point, group);\n}\n\n/*\n *  call-seq:\n *     key.public_key = ec_point\n *\n *  See the OpenSSL documentation for EC_KEY_set_public_key()\n */\nstatic VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)\n{\n    EC_KEY *ec;\n    EC_POINT *point = NULL;\n\n    Require_EC_KEY(self, ec);\n    if (!NIL_P(public_key))\n        SafeRequire_EC_POINT(public_key, point);\n\n    switch (EC_KEY_set_public_key(ec, point)) {\n    case 1:\n        break;\n    case 0:\n        if (point == NULL)\n            break;\n    default:\n        ossl_raise(eECError, \"EC_KEY_set_public_key\");\n    }\n\n    return public_key;\n}\n\n/*\n *  call-seq:\n *     key.public_key? => true or false\n *\n *  Both public_key? and private_key? may return false at the same time unlike other PKey classes.\n */\nstatic VALUE ossl_ec_key_is_public_key(VALUE self)\n{\n    EC_KEY *ec;\n\n    Require_EC_KEY(self, ec);\n\n    return (EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse);\n}\n\n/*\n *  call-seq:\n *     key.private_key? => true or false\n *\n *  Both public_key? and private_key? may return false at the same time unlike other PKey classes.\n */\nstatic VALUE ossl_ec_key_is_private_key(VALUE self)\n{\n    EC_KEY *ec;\n\n    Require_EC_KEY(self, ec);\n\n    return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);\n}\n\nstatic VALUE ossl_ec_key_to_string(VALUE self, int format)\n{\n    EC_KEY *ec;\n    BIO *out;\n    int i = -1;\n    int private = 0;\n    EVP_CIPHER *cipher = NULL;\n    char *password = NULL;\n    VALUE str;\n\n    Require_EC_KEY(self, ec);\n\n    if (EC_KEY_get0_public_key(ec) == NULL)\n        rb_raise(eECError, \"can't export - no public key set\");\n\n    if (EC_KEY_check_key(ec) != 1)\n\tossl_raise(eECError, \"can't export - EC_KEY_check_key failed\");\n\n    if (EC_KEY_get0_private_key(ec))\n        private = 1;\n\n    if (!(out = BIO_new(BIO_s_mem())))\n        ossl_raise(eECError, \"BIO_new(BIO_s_mem())\");\n\n    switch(format) {\n    case EXPORT_PEM:\n    \tif (private) {\n    \t    if (cipher || password)\n/* BUG: finish cipher/password key export */\n    \t        rb_notimplement();\n            i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);\n    \t} else {\n    \t    if (cipher || password)\n                rb_raise(rb_eArgError, \"encryption is not supported when exporting this key type\");\n\n            i = PEM_write_bio_EC_PUBKEY(out, ec);\n        }\n\n    \tbreak;\n    case EXPORT_DER:\n        if (private) {\n    \t    if (cipher || password)\n                rb_raise(rb_eArgError, \"encryption is not supported when exporting this key type\");\n\n            i = i2d_ECPrivateKey_bio(out, ec);\n        } else {\n    \t    if (cipher || password)\n                rb_raise(rb_eArgError, \"encryption is not supported when exporting this key type\");\n\n            i = i2d_EC_PUBKEY_bio(out, ec);\n        }\n\n    \tbreak;\n    default:\n        BIO_free(out);\n    \trb_raise(rb_eRuntimeError, \"unknown format (internal error)\");\n    }\n\n    if (i != 1) {\n        BIO_free(out);\n        ossl_raise(eECError, \"outlen=%d\", i);\n    }\n\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     key.to_pem   => String\n *\n *  See the OpenSSL documentation for PEM_write_bio_ECPrivateKey()\n */\nstatic VALUE ossl_ec_key_to_pem(VALUE self)\n{\n    return ossl_ec_key_to_string(self, EXPORT_PEM);\n}\n\n/*\n *  call-seq:\n *     key.to_der   => String\n *\n *  See the OpenSSL documentation for i2d_ECPrivateKey_bio()\n */\nstatic VALUE ossl_ec_key_to_der(VALUE self)\n{\n    return ossl_ec_key_to_string(self, EXPORT_DER);\n}\n\n/*\n *  call-seq:\n *     key.to_text   => String\n *\n *  See the OpenSSL documentation for EC_KEY_print()\n */\nstatic VALUE ossl_ec_key_to_text(VALUE self)\n{\n    EC_KEY *ec;\n    BIO *out;\n    VALUE str;\n\n    Require_EC_KEY(self, ec);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eECError, \"BIO_new(BIO_s_mem())\");\n    }\n    if (!EC_KEY_print(out, ec, 0)) {\n\tBIO_free(out);\n\tossl_raise(eECError, \"EC_KEY_print\");\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     key.generate_key   => self\n *\n *  See the OpenSSL documentation for EC_KEY_generate_key()\n */\nstatic VALUE ossl_ec_key_generate_key(VALUE self)\n{\n    EC_KEY *ec;\n\n    Require_EC_KEY(self, ec);\n\n    if (EC_KEY_generate_key(ec) != 1)\n\tossl_raise(eECError, \"EC_KEY_generate_key\");\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     key.check_key   => true\n *\n *  Raises an exception if the key is invalid.\n *\n *  See the OpenSSL documentation for EC_KEY_check_key()\n */\nstatic VALUE ossl_ec_key_check_key(VALUE self)\n{\n    EC_KEY *ec;\n\n    Require_EC_KEY(self, ec);\n\n    if (EC_KEY_check_key(ec) != 1)\n\tossl_raise(eECError, \"EC_KEY_check_key\");\n\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     key.dh_compute_key(pubkey)   => String\n *\n *  See the OpenSSL documentation for ECDH_compute_key()\n */\nstatic VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)\n{\n    EC_KEY *ec;\n    EC_POINT *point;\n    int buf_len;\n    VALUE str;\n\n    Require_EC_KEY(self, ec);\n    SafeRequire_EC_POINT(pubkey, point);\n\n/* BUG: need a way to figure out the maximum string size */\n    buf_len = 1024;\n    str = rb_str_new(0, buf_len);\n/* BUG: take KDF as a block */\n    buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL);\n    if (buf_len < 0)\n         ossl_raise(eECError, \"ECDH_compute_key\");\n\n    rb_str_resize(str, buf_len);\n\n    return str;\n}\n\n/* sign_setup */\n\n/*\n *  call-seq:\n *     key.dsa_sign_asn1(data)   => String\n *\n *  See the OpenSSL documentation for ECDSA_sign()\n */\nstatic VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)\n{\n    EC_KEY *ec;\n    unsigned int buf_len;\n    VALUE str;\n\n    Require_EC_KEY(self, ec);\n    StringValue(data);\n\n    if (EC_KEY_get0_private_key(ec) == NULL)\n\tossl_raise(eECError, \"Private EC key needed!\");\n\n    str = rb_str_new(0, ECDSA_size(ec) + 16);\n    if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LEN(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)\n         ossl_raise(eECError, \"ECDSA_sign\");\n\n    rb_str_resize(str, buf_len);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     key.dsa_verify(data, sig)   => true or false\n *\n *  See the OpenSSL documentation for ECDSA_verify()\n */\nstatic VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)\n{\n    EC_KEY *ec;\n\n    Require_EC_KEY(self, ec);\n    StringValue(data);\n    StringValue(sig);\n\n    switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LEN(data), (unsigned char *) RSTRING_PTR(sig), RSTRING_LEN(sig), ec)) {\n    case 1:\treturn Qtrue;\n    case 0:\treturn Qfalse;\n    default:\tbreak;\n    }\n\n    ossl_raise(eECError, \"ECDSA_verify\");\n}\n\nstatic void ossl_ec_group_free(ossl_ec_group *ec_group)\n{\n    if (!ec_group->dont_free && ec_group->group)\n        EC_GROUP_clear_free(ec_group->group);\n    free(ec_group);\n}\n\nstatic VALUE ossl_ec_group_alloc(VALUE klass)\n{\n    ossl_ec_group *ec_group;\n    VALUE obj;\n\n    obj = Data_Make_Struct(klass, ossl_ec_group, 0, ossl_ec_group_free, ec_group);\n\n    return obj;\n}\n\n/*  call-seq:\n *     OpenSSL::PKey::EC::Group.new(\"secp112r1\")\n *     OpenSSL::PKey::EC::Group.new(ec_group)\n *     OpenSSL::PKey::EC::Group.new(pem_string)\n *     OpenSSL::PKey::EC::Group.new(der_string)\n *     OpenSSL::PKey::EC::Group.new(pem_file)\n *     OpenSSL::PKey::EC::Group.new(der_file)\n *     OpenSSL::PKey::EC::Group.new(:GFp_simple)\n *     OpenSSL::PKey::EC::Group.new(:GFp_mult)\n *     OpenSSL::PKey::EC::Group.new(:GFp_nist)\n *     OpenSSL::PKey::EC::Group.new(:GF2m_simple)\n *     OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b)\n *     OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b)\n *\n *  See the OpenSSL documentation for EC_GROUP_*\n */\nstatic VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE arg1, arg2, arg3, arg4;\n    ossl_ec_group *ec_group;\n    EC_GROUP *group = NULL;\n\n    Data_Get_Struct(self, ossl_ec_group, ec_group);\n    if (ec_group->group != NULL)\n        rb_raise(rb_eRuntimeError, \"EC_GROUP is already initialized\");\n\n    switch (rb_scan_args(argc, argv, \"13\", &arg1, &arg2, &arg3, &arg4)) {\n    case 1:\n        if (SYMBOL_P(arg1)) {\n            const EC_METHOD *method = NULL;\n            ID id = SYM2ID(arg1);\n\n            if (id == s_GFp_simple) {\n                method = EC_GFp_simple_method();\n            } else if (id == s_GFp_mont) {\n                method = EC_GFp_mont_method();\n            } else if (id == s_GFp_nist) {\n                method = EC_GFp_nist_method();\n            } else if (id == s_GF2m_simple) {\n                method = EC_GF2m_simple_method();\n            }\n\n            if (method) {\n                if ((group = EC_GROUP_new(method)) == NULL)\n                    ossl_raise(eEC_GROUP, \"EC_GROUP_new\");\n            } else {\n                rb_raise(rb_eArgError, \"unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple\");\n            }\n        } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {\n            const EC_GROUP *arg1_group;\n\n            SafeRequire_EC_GROUP(arg1, arg1_group);\n            if ((group = EC_GROUP_dup(arg1_group)) == NULL)\n                ossl_raise(eEC_GROUP, \"EC_GROUP_dup\");\n        } else {\n            BIO *in = ossl_obj2bio(arg1);\n\n            group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);\n            if (!group) {\n                BIO_reset(in);\n                group = d2i_ECPKParameters_bio(in, NULL);\n            }\n\n            BIO_free(in);\n\n            if (!group) {\n                const char *name = STR2CSTR(arg1);\n                int nid = OBJ_sn2nid(name);\n\n                if (nid == NID_undef)\n                    ossl_raise(eEC_GROUP, \"unknown curve name (%s)\", name);\n\n                group = EC_GROUP_new_by_curve_name(nid);\n                if (group == NULL)\n                    ossl_raise(eEC_GROUP, \"unable to create curve (%s)\", name);\n\n                EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);\n                EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);\n            }\n        }\n\n        break;\n    case 4:\n        if (SYMBOL_P(arg1)) {\n            ID id = SYM2ID(arg1);\n            EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;\n            const BIGNUM *p = GetBNPtr(arg2);\n            const BIGNUM *a = GetBNPtr(arg3);\n            const BIGNUM *b = GetBNPtr(arg4);\n\n            if (id == s_GFp) {\n                new_curve = EC_GROUP_new_curve_GFp;\n            } else if (id == s_GF2m) {\n                new_curve = EC_GROUP_new_curve_GF2m;\n            } else {\n                rb_raise(rb_eArgError, \"unknown symbol, must be :GFp or :GF2m\");\n            }\n\n            if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)\n                ossl_raise(eEC_GROUP, \"EC_GROUP_new_by_GF*\");\n        } else {\n             rb_raise(rb_eArgError, \"unknown argument, must be :GFp or :GF2m\");\n        }\n\n        break;\n    default:\n        rb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    if (group == NULL)\n        ossl_raise(eEC_GROUP, \"\");\n\n    ec_group->group = group;\n\n    return self;\n}\n\n/*  call-seq:\n *     group1 == group2   => true | false\n *\n */\nstatic VALUE ossl_ec_group_eql(VALUE a, VALUE b)\n{\n    EC_GROUP *group1 = NULL, *group2 = NULL;\n\n    Require_EC_GROUP(a, group1);\n    SafeRequire_EC_GROUP(b, group2);\n\n    if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)\n       return Qfalse;\n\n    return Qtrue;\n}\n\n/*  call-seq:\n *     group.generator   => ec_point\n *\n *  See the OpenSSL documentation for EC_GROUP_get0_generator()\n */\nstatic VALUE ossl_ec_group_get_generator(VALUE self)\n{\n    VALUE point_obj;\n    EC_GROUP *group = NULL;\n\n    Require_EC_GROUP(self, group);\n\n    point_obj = ossl_ec_point_dup(EC_GROUP_get0_generator(group), self);\n\n    return point_obj;\n}\n\n/*  call-seq:\n *     group.set_generator(generator, order, cofactor)   => self\n *\n *  See the OpenSSL documentation for EC_GROUP_set_generator()\n */\nstatic VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)\n{\n    EC_GROUP *group = NULL;\n    const EC_POINT *point;\n    const BIGNUM *o, *co;\n\n    Require_EC_GROUP(self, group);\n    SafeRequire_EC_POINT(generator, point);\n    o = GetBNPtr(order);\n    co = GetBNPtr(cofactor);\n\n    if (EC_GROUP_set_generator(group, point, o, co) != 1)\n        ossl_raise(eEC_GROUP, \"EC_GROUP_set_generator\");\n\n    return self;\n}\n\n/*  call-seq:\n *     group.get_order   => order_bn\n *\n *  See the OpenSSL documentation for EC_GROUP_get_order()\n */\nstatic VALUE ossl_ec_group_get_order(VALUE self)\n{\n    VALUE bn_obj;\n    BIGNUM *bn;\n    EC_GROUP *group = NULL;\n\n    Require_EC_GROUP(self, group);\n\n    bn_obj = ossl_bn_new(NULL);\n    bn = GetBNPtr(bn_obj);\n\n    if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1)\n        ossl_raise(eEC_GROUP, \"EC_GROUP_get_order\");\n\n    return bn_obj;\n}\n\n/*  call-seq:\n *     group.get_cofactor   => cofactor_bn\n *\n *  See the OpenSSL documentation for EC_GROUP_get_cofactor()\n */\nstatic VALUE ossl_ec_group_get_cofactor(VALUE self)\n{\n    VALUE bn_obj;\n    BIGNUM *bn;\n    EC_GROUP *group = NULL;\n\n    Require_EC_GROUP(self, group);\n\n    bn_obj = ossl_bn_new(NULL);\n    bn = GetBNPtr(bn_obj);\n\n    if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1)\n        ossl_raise(eEC_GROUP, \"EC_GROUP_get_cofactor\");\n\n    return bn_obj;\n}\n\n/*  call-seq:\n *     group.curve_name  => String\n *\n *  See the OpenSSL documentation for EC_GROUP_get_curve_name()\n */\nstatic VALUE ossl_ec_group_get_curve_name(VALUE self)\n{\n    EC_GROUP *group = NULL;\n    int nid;\n\n    Get_EC_GROUP(self, group);\n    if (group == NULL)\n        return Qnil;\n\n    nid = EC_GROUP_get_curve_name(group);\n\n/* BUG: an nid or asn1 object should be returned, maybe. */\n    return rb_str_new2(OBJ_nid2sn(nid));\n}\n\n/*  call-seq:\n *     EC.builtin_curves => [[name, comment], ...]\n *\n *  See the OpenSSL documentation for EC_builtin_curves()\n */\nstatic VALUE ossl_s_builtin_curves(VALUE self)\n{\n    EC_builtin_curve *curves = NULL;\n    int n;\n    int crv_len = EC_get_builtin_curves(NULL, 0);\n    VALUE ary, ret;\n\n    curves = ALLOCA_N(EC_builtin_curve, crv_len);\n    if (curves == NULL)\n        return Qnil;\n    if (!EC_get_builtin_curves(curves, crv_len))\n        ossl_raise(rb_eRuntimeError, \"EC_get_builtin_curves\");\n\n    ret = rb_ary_new2(crv_len);\n\n    for (n = 0; n < crv_len; n++) {\n        const char *sname = OBJ_nid2sn(curves[n].nid);\n        const char *comment = curves[n].comment;\n\n        ary = rb_ary_new2(2);\n        rb_ary_push(ary, rb_str_new2(sname));\n        rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil);\n        rb_ary_push(ret, ary);\n    }\n\n    return ret;\n}\n\n/*  call-seq:\n *     group.asn1_flag  => Fixnum\n *\n *  See the OpenSSL documentation for EC_GROUP_get_asn1_flag()\n */\nstatic VALUE ossl_ec_group_get_asn1_flag(VALUE self)\n{\n    EC_GROUP *group = NULL;\n    int flag;\n\n    Require_EC_GROUP(self, group);\n\n    flag = EC_GROUP_get_asn1_flag(group);\n\n    return INT2FIX(flag);\n}\n\n/*  call-seq:\n *     group.asn1_flag = Fixnum   => Fixnum\n *\n *  See the OpenSSL documentation for EC_GROUP_set_asn1_flag()\n */\nstatic VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)\n{\n    EC_GROUP *group = NULL;\n\n    Require_EC_GROUP(self, group);\n\n    EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));\n\n    return flag_v;\n}\n\n/*  call-seq:\n *     group.point_conversion_form  => :uncompressed | :compressed | :hybrid \n *\n *  See the OpenSSL documentation for EC_GROUP_get_point_conversion_form()\n */\nstatic VALUE ossl_ec_group_get_point_conversion_form(VALUE self)\n{\n    EC_GROUP *group = NULL;\n    point_conversion_form_t form;\n    VALUE ret;\n\n    Require_EC_GROUP(self, group);\n\n    form = EC_GROUP_get_point_conversion_form(group);\n\n    switch (form) {\n    case POINT_CONVERSION_UNCOMPRESSED:\tret = ID_uncompressed; break;\n    case POINT_CONVERSION_COMPRESSED:\tret = ID_compressed; break;\n    case POINT_CONVERSION_HYBRID:\tret = ID_hybrid; break;\n    default:\trb_raise(eEC_GROUP, \"unsupported point conversion form: %d, this module should be updated\", form);\n    }\n    \n   return ID2SYM(ret);\n}\n\n/*  call-seq:\n *     group.point_conversion_form = form => form\n *\n *  See the OpenSSL documentation for EC_GROUP_set_point_conversion_form()\n */\nstatic VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)\n{\n    EC_GROUP *group = NULL;\n    point_conversion_form_t form;\n    ID form_id = SYM2ID(form_v);\n\n    Require_EC_GROUP(self, group);\n\n    if (form_id == ID_uncompressed) {\n        form = POINT_CONVERSION_UNCOMPRESSED;\n    } else if (form_id == ID_compressed) {\n        form = POINT_CONVERSION_COMPRESSED;\n    } else if (form_id == ID_hybrid) {\n        form = POINT_CONVERSION_HYBRID;\n    } else {\n        rb_raise(rb_eArgError, \"form must be :compressed, :uncompressed, or :hybrid\");\n    }\n\n    EC_GROUP_set_point_conversion_form(group, form);\n\n    return form_v;\n}\n\n/*  call-seq:\n *     group.seed   => String or nil\n *\n *  See the OpenSSL documentation for EC_GROUP_get0_seed()\n */\nstatic VALUE ossl_ec_group_get_seed(VALUE self)\n{\n    EC_GROUP *group = NULL;\n    size_t seed_len;\n\n    Require_EC_GROUP(self, group);\n\n    seed_len = EC_GROUP_get_seed_len(group);\n\n    if (seed_len == 0)\n        return Qnil;\n\n    return rb_str_new(EC_GROUP_get0_seed(group), seed_len);\n}\n\n/*  call-seq:\n *     group.seed = seed  => seed\n *\n *  See the OpenSSL documentation for EC_GROUP_set_seed()\n */\nstatic VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)\n{\n    EC_GROUP *group = NULL;\n\n    Require_EC_GROUP(self, group);\n    StringValue(seed);\n\n    if (EC_GROUP_set_seed(group, RSTRING_PTR(seed), RSTRING_LEN(seed)) != RSTRING_LEN(seed))\n        ossl_raise(eEC_GROUP, \"EC_GROUP_set_seed\");\n\n    return seed;\n}\n\n/* get/set curve GFp, GF2m */\n\n/*  call-seq:\n *     group.degree   => Fixnum\n *\n *  See the OpenSSL documentation for EC_GROUP_get_degree()\n */\nstatic VALUE ossl_ec_group_get_degree(VALUE self)\n{\n    EC_GROUP *group = NULL;\n\n    Require_EC_GROUP(self, group);\n\n    return INT2NUM(EC_GROUP_get_degree(group));\n}\n\nstatic VALUE ossl_ec_group_to_string(VALUE self, int format)\n{\n    EC_GROUP *group;\n    BIO *out;\n    int i = -1;\n    VALUE str;\n\n    Get_EC_GROUP(self, group);\n\n    if (!(out = BIO_new(BIO_s_mem())))\n        ossl_raise(eEC_GROUP, \"BIO_new(BIO_s_mem())\");\n\n    switch(format) {\n    case EXPORT_PEM:\n        i = PEM_write_bio_ECPKParameters(out, group);\n    \tbreak;\n    case EXPORT_DER:\n        i = i2d_ECPKParameters_bio(out, group);\n    \tbreak;\n    default:\n        BIO_free(out);\n    \trb_raise(rb_eRuntimeError, \"unknown format (internal error)\");\n    }\n\n    if (i != 1) {\n        BIO_free(out);\n        ossl_raise(eECError, NULL);\n    }\n\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*  call-seq:\n *     group.to_pem   => String\n *\n *  See the OpenSSL documentation for PEM_write_bio_ECPKParameters()\n */\nstatic VALUE ossl_ec_group_to_pem(VALUE self)\n{\n    return ossl_ec_group_to_string(self, EXPORT_PEM);\n}\n\n/*  call-seq:\n *     group.to_der   => String\n *\n *  See the OpenSSL documentation for i2d_ECPKParameters_bio()\n */\nstatic VALUE ossl_ec_group_to_der(VALUE self)\n{\n    return ossl_ec_group_to_string(self, EXPORT_DER);\n}\n\n/*  call-seq:\n *     group.to_text   => String\n *\n *  See the OpenSSL documentation for ECPKParameters_print()\n */\nstatic VALUE ossl_ec_group_to_text(VALUE self)\n{\n    EC_GROUP *group;\n    BIO *out;\n    VALUE str;\n\n    Require_EC_GROUP(self, group);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eEC_GROUP, \"BIO_new(BIO_s_mem())\");\n    }\n    if (!ECPKParameters_print(out, group, 0)) {\n\tBIO_free(out);\n\tossl_raise(eEC_GROUP, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n\nstatic void ossl_ec_point_free(ossl_ec_point *ec_point)\n{\n    if (!ec_point->dont_free && ec_point->point)\n        EC_POINT_clear_free(ec_point->point);\n    free(ec_point);\n}\n\nstatic VALUE ossl_ec_point_alloc(VALUE klass)\n{\n    ossl_ec_point *ec_point;\n    VALUE obj;\n\n    obj = Data_Make_Struct(klass, ossl_ec_point, 0, ossl_ec_point_free, ec_point);\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     OpenSSL::PKey::EC::Point.new(point)\n *     OpenSSL::PKey::EC::Point.new(group)\n *     OpenSSL::PKey::EC::Point.new(group, bn)\n *\n *  See the OpenSSL documentation for EC_POINT_*\n */\nstatic VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)\n{\n    ossl_ec_point *ec_point;\n    EC_POINT *point = NULL;\n    VALUE arg1, arg2;\n    VALUE group_v = Qnil;\n    const EC_GROUP *group = NULL;\n\n    Data_Get_Struct(self, ossl_ec_point, ec_point);\n    if (ec_point->point)\n        rb_raise(eEC_POINT, \"EC_POINT already initialized\");\n\n    switch (rb_scan_args(argc, argv, \"11\", &arg1, &arg2)) {\n    case 1:\n        if (rb_obj_is_kind_of(arg1, cEC_POINT)) {\n            const EC_POINT *arg_point;\n\n            group_v = rb_iv_get(arg1, \"@group\");\n            SafeRequire_EC_GROUP(group_v, group);\n            SafeRequire_EC_POINT(arg1, arg_point);\n\n            point = EC_POINT_dup(arg_point, group);\n        } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {\n            group_v = arg1;\n            SafeRequire_EC_GROUP(group_v, group);\n\n            point = EC_POINT_new(group);\n        } else {\n            rb_raise(eEC_POINT, \"wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group\");\n        }\n\n        break;\n     case 2:\n        if (!rb_obj_is_kind_of(arg1, cEC_GROUP))\n            rb_raise(rb_eArgError, \"1st argument must be OpenSSL::PKey::EC::Group\");\n        group_v = arg1;\n        SafeRequire_EC_GROUP(group_v, group);\n        \n        if (rb_obj_is_kind_of(arg2, cBN)) {\n            const BIGNUM *bn = GetBNPtr(arg2);\n\n            point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);\n        } else {\n            BIO *in = ossl_obj2bio(arg1);\n\n/* BUG: finish me */\n\n            BIO_free(in);\n\n            if (point == NULL) {\n                ossl_raise(eEC_POINT, \"unknown type for 2nd arg\");\n            }\n        }\n        break;\n    default:\n        rb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    if (point == NULL)\n        ossl_raise(eEC_POINT, NULL);\n\n    if (NIL_P(group_v))\n        rb_raise(rb_eRuntimeError, \"missing group (internal error)\");\n\n    ec_point->point = point;\n\n    rb_iv_set(self, \"@group\", group_v);\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     point1 == point2 => true | false\n *\n */\nstatic VALUE ossl_ec_point_eql(VALUE a, VALUE b)\n{\n    EC_POINT *point1, *point2;\n    VALUE group_v1 = rb_iv_get(a, \"@group\");\n    VALUE group_v2 = rb_iv_get(b, \"@group\");\n    const EC_GROUP *group;\n\n    if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)\n        return Qfalse;\n\n    Require_EC_POINT(a, point1);\n    SafeRequire_EC_POINT(b, point2);\n    SafeRequire_EC_GROUP(group_v1, group);\n\n    if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)\n        return Qfalse;\n\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     point.infinity? => true | false\n *\n */\nstatic VALUE ossl_ec_point_is_at_infinity(VALUE self)\n{\n    EC_POINT *point;\n    VALUE group_v = rb_iv_get(self, \"@group\");\n    const EC_GROUP *group;\n\n    Require_EC_POINT(self, point);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    switch (EC_POINT_is_at_infinity(group, point)) {\n    case 1: return Qtrue;\n    case 0: return Qfalse;\n    default: ossl_raise(cEC_POINT, \"EC_POINT_is_at_infinity\");\n    }\n}\n\n/*\n *  call-seq:\n *     point.on_curve? => true | false\n *\n */\nstatic VALUE ossl_ec_point_is_on_curve(VALUE self)\n{\n    EC_POINT *point;\n    VALUE group_v = rb_iv_get(self, \"@group\");\n    const EC_GROUP *group;\n\n    Require_EC_POINT(self, point);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {\n    case 1: return Qtrue;\n    case 0: return Qfalse;\n    default: ossl_raise(cEC_POINT, \"EC_POINT_is_on_curve\");\n    }\n}\n\n/*\n *  call-seq:\n *     point.make_affine! => self\n *\n */\nstatic VALUE ossl_ec_point_make_affine(VALUE self)\n{\n    EC_POINT *point;\n    VALUE group_v = rb_iv_get(self, \"@group\");\n    const EC_GROUP *group;\n\n    Require_EC_POINT(self, point);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)\n        ossl_raise(cEC_POINT, \"EC_POINT_make_affine\");\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     point.invert! => self\n *\n */\nstatic VALUE ossl_ec_point_invert(VALUE self)\n{\n    EC_POINT *point;\n    VALUE group_v = rb_iv_get(self, \"@group\");\n    const EC_GROUP *group;\n\n    Require_EC_POINT(self, point);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)\n        ossl_raise(cEC_POINT, \"EC_POINT_invert\");\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     point.set_to_infinity! => self\n *\n */\nstatic VALUE ossl_ec_point_set_to_infinity(VALUE self)\n{\n    EC_POINT *point;\n    VALUE group_v = rb_iv_get(self, \"@group\");\n    const EC_GROUP *group;\n\n    Require_EC_POINT(self, point);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    if (EC_POINT_set_to_infinity(group, point) != 1)\n        ossl_raise(cEC_POINT, \"EC_POINT_set_to_infinity\");\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     point.to_bn   => OpenSSL::BN\n *\n *  See the OpenSSL documentation for EC_POINT_point2bn()\n */\nstatic VALUE ossl_ec_point_to_bn(VALUE self)\n{\n    EC_POINT *point;\n    VALUE bn_obj;\n    VALUE group_v = rb_iv_get(self, \"@group\");\n    const EC_GROUP *group;\n    point_conversion_form_t form;\n    BIGNUM *bn;\n\n    Require_EC_POINT(self, point);\n    SafeRequire_EC_GROUP(group_v, group);\n\n    form = EC_GROUP_get_point_conversion_form(group);\n\n    bn_obj = rb_obj_alloc(cBN);\n    bn = GetBNPtr(bn_obj);\n\n    if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)\n        ossl_raise(eEC_POINT, \"EC_POINT_point2bn\");\n\n    return bn_obj;\n}\n\nstatic void no_copy(VALUE klass)\n{\n    rb_undef_method(klass, \"copy\");\n    rb_undef_method(klass, \"clone\");\n    rb_undef_method(klass, \"dup\");\n    rb_undef_method(klass, \"initialize_copy\");\n}\n\nvoid Init_ossl_ec()\n{\n#ifdef DONT_NEED_RDOC_WORKAROUND\n    mOSSL = rb_define_module(\"OpenSSL\");\n    mPKey = rb_define_module_under(mOSSL, \"PKey\");\n#endif\n\n    eECError = rb_define_class_under(mPKey, \"ECError\", ePKeyError);\n\n    cEC = rb_define_class_under(mPKey, \"EC\", cPKey);\n    cEC_GROUP = rb_define_class_under(cEC, \"Group\", rb_cObject);\n    cEC_POINT = rb_define_class_under(cEC, \"Point\", rb_cObject);\n    eEC_GROUP = rb_define_class_under(cEC_GROUP, \"Error\", eOSSLError);\n    eEC_POINT = rb_define_class_under(cEC_POINT, \"Error\", eOSSLError);\n\n    s_GFp = rb_intern(\"GFp\");\n    s_GF2m = rb_intern(\"GF2m\");\n    s_GFp_simple = rb_intern(\"GFp_simple\");\n    s_GFp_mont = rb_intern(\"GFp_mont\");\n    s_GFp_nist = rb_intern(\"GFp_nist\");\n    s_GF2m_simple = rb_intern(\"GF2m_simple\");\n\n    ID_uncompressed = rb_intern(\"uncompressed\");\n    ID_compressed = rb_intern(\"compressed\");\n    ID_hybrid = rb_intern(\"hybrid\");\n\n#ifdef OPENSSL_EC_NAMED_CURVE\n    rb_define_const(cEC, \"NAMED_CURVE\", ULONG2NUM(OPENSSL_EC_NAMED_CURVE));\n#endif\n\n    rb_define_singleton_method(cEC, \"builtin_curves\", ossl_s_builtin_curves, 0);\n\n    rb_define_method(cEC, \"initialize\", ossl_ec_key_initialize, -1);\n/* copy/dup/cmp */\n\n    rb_define_method(cEC, \"group\", ossl_ec_key_get_group, 0);\n    rb_define_method(cEC, \"group=\", ossl_ec_key_set_group, 1);\n    rb_define_method(cEC, \"private_key\", ossl_ec_key_get_private_key, 0);\n    rb_define_method(cEC, \"private_key=\", ossl_ec_key_set_private_key, 1);\n    rb_define_method(cEC, \"public_key\", ossl_ec_key_get_public_key, 0);\n    rb_define_method(cEC, \"public_key=\", ossl_ec_key_set_public_key, 1);\n    rb_define_method(cEC, \"private_key?\", ossl_ec_key_is_private_key, 0);\n    rb_define_method(cEC, \"public_key?\", ossl_ec_key_is_public_key, 0);\n/*  rb_define_method(cEC, \"\", ossl_ec_key_get_, 0);\n    rb_define_method(cEC, \"=\", ossl_ec_key_set_ 1);\n    set/get enc_flags\n    set/get _conv_from\n    set/get asn1_flag (can use ruby to call self.group.asn1_flag)\n    set/get precompute_mult\n*/\n    rb_define_method(cEC, \"generate_key\", ossl_ec_key_generate_key, 0);\n    rb_define_method(cEC, \"check_key\", ossl_ec_key_check_key, 0);\n\n    rb_define_method(cEC, \"dh_compute_key\", ossl_ec_key_dh_compute_key, 1);\n    rb_define_method(cEC, \"dsa_sign_asn1\", ossl_ec_key_dsa_sign_asn1, 1);\n    rb_define_method(cEC, \"dsa_verify_asn1\", ossl_ec_key_dsa_verify_asn1, 2);\n/* do_sign/do_verify */\n\n    rb_define_method(cEC, \"to_pem\", ossl_ec_key_to_pem, 0);\n    rb_define_method(cEC, \"to_der\", ossl_ec_key_to_der, 0);\n    rb_define_method(cEC, \"to_text\", ossl_ec_key_to_text, 0);\n\n\n    rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);\n    rb_define_method(cEC_GROUP, \"initialize\", ossl_ec_group_initialize, -1);\n    rb_define_method(cEC_GROUP, \"eql?\", ossl_ec_group_eql, 1);\n    rb_define_alias(cEC_GROUP, \"==\", \"eql?\");\n/* copy/dup/cmp */\n\n    rb_define_method(cEC_GROUP, \"generator\", ossl_ec_group_get_generator, 0);\n    rb_define_method(cEC_GROUP, \"set_generator\", ossl_ec_group_set_generator, 3);\n    rb_define_method(cEC_GROUP, \"order\", ossl_ec_group_get_order, 0);\n    rb_define_method(cEC_GROUP, \"cofactor\", ossl_ec_group_get_cofactor, 0);\n\n    rb_define_method(cEC_GROUP, \"curve_name\", ossl_ec_group_get_curve_name, 0);\n/*    rb_define_method(cEC_GROUP, \"curve_name=\", ossl_ec_group_set_curve_name, 1); */\n\n    rb_define_method(cEC_GROUP, \"asn1_flag\", ossl_ec_group_get_asn1_flag, 0);\n    rb_define_method(cEC_GROUP, \"asn1_flag=\", ossl_ec_group_set_asn1_flag, 1);\n\n    rb_define_method(cEC_GROUP, \"point_conversion_form\", ossl_ec_group_get_point_conversion_form, 0);\n    rb_define_method(cEC_GROUP, \"point_conversion_form=\", ossl_ec_group_set_point_conversion_form, 1);\n\n    rb_define_method(cEC_GROUP, \"seed\", ossl_ec_group_get_seed, 0);\n    rb_define_method(cEC_GROUP, \"seed=\", ossl_ec_group_set_seed, 1);\n\n/* get/set GFp, GF2m */\n\n    rb_define_method(cEC_GROUP, \"degree\", ossl_ec_group_get_degree, 0);\n\n/* check* */\n\n\n    rb_define_method(cEC_GROUP, \"to_pem\", ossl_ec_group_to_pem, 0);\n    rb_define_method(cEC_GROUP, \"to_der\", ossl_ec_group_to_der, 0);\n    rb_define_method(cEC_GROUP, \"to_text\", ossl_ec_group_to_text, 0);\n\n\n    rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc);\n    rb_define_method(cEC_POINT, \"initialize\", ossl_ec_point_initialize, -1);\n    rb_attr(cEC_POINT, rb_intern(\"group\"), 1, 0, 0);\n    rb_define_method(cEC_POINT, \"eql?\", ossl_ec_point_eql, 1);\n    rb_define_alias(cEC_POINT, \"==\", \"eql?\");\n\n    rb_define_method(cEC_POINT, \"infinity?\", ossl_ec_point_is_at_infinity, 0);\n    rb_define_method(cEC_POINT, \"on_curve?\", ossl_ec_point_is_on_curve, 0);\n    rb_define_method(cEC_POINT, \"make_affine!\", ossl_ec_point_make_affine, 0);\n    rb_define_method(cEC_POINT, \"invert!\", ossl_ec_point_invert, 0);\n    rb_define_method(cEC_POINT, \"set_to_infinity!\", ossl_ec_point_set_to_infinity, 0);\n/* all the other methods */\n\n    rb_define_method(cEC_POINT, \"to_bn\", ossl_ec_point_to_bn, 0);\n\n    no_copy(cEC);\n    no_copy(cEC_GROUP);\n    no_copy(cEC_POINT);\n}\n\n#else /* defined NO_EC */\nvoid Init_ossl_ec()\n{\n}\n#endif /* NO_EC */\n"
  },
  {
    "path": "ext/openssl/ossl_pkey_rsa.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(OPENSSL_NO_RSA)\n\n#include \"ossl.h\"\n\n#define GetPKeyRSA(obj, pkey) do { \\\n    GetPKey(obj, pkey); \\\n    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { /* PARANOIA? */ \\\n\tossl_raise(rb_eRuntimeError, \"THIS IS NOT A RSA!\") ; \\\n    } \\\n} while (0)\n\n#define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q)\n#define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj))\n\n/*\n * Classes\n */\nVALUE cRSA;\nVALUE eRSAError;\n\n/*\n * Public\n */\nstatic VALUE\nrsa_instance(VALUE klass, RSA *rsa)\n{\n    EVP_PKEY *pkey;\n    VALUE obj;\n\t\n    if (!rsa) {\n\treturn Qfalse;\n    }\n    if (!(pkey = EVP_PKEY_new())) {\n\treturn Qfalse;\n    }\n    if (!EVP_PKEY_assign_RSA(pkey, rsa)) {\n\tEVP_PKEY_free(pkey);\n\treturn Qfalse;\n    }\n    WrapPKey(klass, obj, pkey);\n\t\n    return obj;\n}\n\nVALUE\nossl_rsa_new(EVP_PKEY *pkey)\n{\n    VALUE obj;\n\n    if (!pkey) {\n\tobj = rsa_instance(cRSA, RSA_new());\n    }\n    else {\n\tif (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {\n\t    ossl_raise(rb_eTypeError, \"Not a RSA key!\");\n\t}\n\tWrapPKey(cRSA, obj, pkey);\n    }\n    if (obj == Qfalse) {\n\tossl_raise(eRSAError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n * Private\n */\nstatic RSA *\nrsa_generate(int size, int exp)\n{\n    return RSA_generate_key(size, exp,\n\t    rb_block_given_p() ? ossl_generate_cb : NULL,\n\t    NULL);\n}\n\n/*\n *  call-seq:\n *     RSA.generate(size [, exponent]) -> rsa\n *\n *  === Parameters\n *  * +size+ is an integer representing the desired key size.  Keys smaller than 1024 should be considered insecure.\n *  * +exponent+ is an odd number normally 3, 17, or 65537.\n *\n */\nstatic VALUE\nossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)\n{\n/* why does this method exist?  why can't initialize take an optional exponent? */\n    RSA *rsa;\n    VALUE size, exp;\n    VALUE obj;\n\n    rb_scan_args(argc, argv, \"11\", &size, &exp);\n\n    rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2INT(exp)); /* err handled by rsa_instance */\n    obj = rsa_instance(klass, rsa);\n\n    if (obj == Qfalse) {\n\tRSA_free(rsa);\n\tossl_raise(eRSAError, NULL);\n    }\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     RSA.new([size | encoded_key] [, pass]) -> rsa\n *\n *  === Parameters\n *  * +size+ is an integer representing the desired key size.\n *  * +encoded_key+ is a string containing PEM or DER encoded key.\n *  * +pass+ is an optional string with the password to decrypt the encoded key.\n *\n *  === Examples\n *  * RSA.new(2048) -> rsa \n *  * RSA.new(File.read(\"rsa.pem\")) -> rsa\n *  * RSA.new(File.read(\"rsa.pem\"), \"mypassword\") -> rsa\n */\nstatic VALUE\nossl_rsa_initialize(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    RSA *rsa;\n    BIO *in;\n    char *passwd = NULL;\n    VALUE arg, pass;\n\t\n    GetPKey(self, pkey);\n    if(rb_scan_args(argc, argv, \"02\", &arg, &pass) == 0) {\n\trsa = RSA_new();\n    }\n    else if (FIXNUM_P(arg)) {\n\trsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));\n\tif (!rsa) ossl_raise(eRSAError, NULL);\n    }\n    else {\n\tif (!NIL_P(pass)) passwd = StringValuePtr(pass);\n\targ = ossl_to_der_if_possible(arg);\n\tin = ossl_obj2bio(arg);\n\trsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);\n\tif (!rsa) {\n\t    BIO_reset(in);\n\t    rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);\n\t}\n\tif (!rsa) {\n\t    BIO_reset(in);\n\t    rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);\n\t}\n\tif (!rsa) {\n\t    BIO_reset(in);\n\t    rsa = d2i_RSAPrivateKey_bio(in, NULL);\n\t}\n\tif (!rsa) {\n\t    BIO_reset(in);\n\t    rsa = d2i_RSAPublicKey_bio(in, NULL);\n\t}\n\tif (!rsa) {\n\t    BIO_reset(in);\n\t    rsa = d2i_RSA_PUBKEY_bio(in, NULL);\n\t}\n\tBIO_free(in);\n\tif (!rsa) ossl_raise(eRSAError, \"Neither PUB key nor PRIV key:\");\n    }\n    if (!EVP_PKEY_assign_RSA(pkey, rsa)) {\n\tRSA_free(rsa);\n\tossl_raise(eRSAError, NULL);\n    }\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     rsa.public? -> true\n *\n *  The return value is always true since every private key is also a public key.\n *\n */\nstatic VALUE\nossl_rsa_is_public(VALUE self)\n{\n    EVP_PKEY *pkey;\n\n    GetPKeyRSA(self, pkey);\n    /*\n     * This method should check for n and e.  BUG.\n     */\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     rsa.private? -> true | false\n *\n */\nstatic VALUE\nossl_rsa_is_private(VALUE self)\n{\n    EVP_PKEY *pkey;\n\t\n    GetPKeyRSA(self, pkey);\n    \n    return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     rsa.to_pem([cipher, pass]) -> aString\n *\n *  === Parameters\n *  * +cipher+ is a Cipher object.\n *  * +pass+ is a string.\n *\n *  === Examples\n *  * rsa.to_pem -> aString\n *  * rsa.to_pem(cipher, pass) -> aString\n */\nstatic VALUE\nossl_rsa_export(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    BIO *out;\n    const EVP_CIPHER *ciph = NULL;\n    char *passwd = NULL;\n    VALUE cipher, pass, str;\n\n    GetPKeyRSA(self, pkey);\n\n    rb_scan_args(argc, argv, \"02\", &cipher, &pass);\n\n    if (!NIL_P(cipher)) {\n\tciph = GetCipherPtr(cipher);\n\tif (!NIL_P(pass)) {\n\t    passwd = StringValuePtr(pass);\n\t}\n    }\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eRSAError, NULL);\n    }\n    if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {\n\tif (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,\n\t\t\t\t\t NULL, 0, ossl_pem_passwd_cb, passwd)) {\n\t    BIO_free(out);\n\t    ossl_raise(eRSAError, NULL);\n\t}\n    } else {\n\tif (!PEM_write_bio_RSAPublicKey(out, pkey->pkey.rsa)) {\n\t    BIO_free(out);\n\t    ossl_raise(eRSAError, NULL);\n\t}\n    }\n    str = ossl_membio2str(out);\n    \n    return str;\n}\n\n/*\n *  call-seq:\n *     rsa.to_der -> aString\n *\n */\nstatic VALUE\nossl_rsa_to_der(VALUE self)\n{\n    EVP_PKEY *pkey;\n    int (*i2d_func)_((const RSA*, unsigned char**));\n    unsigned char *p;\n    long len;\n    VALUE str;\n\n    GetPKeyRSA(self, pkey);\n    if(RSA_HAS_PRIVATE(pkey->pkey.rsa))\n\ti2d_func = i2d_RSAPrivateKey;\n    else\n\ti2d_func = i2d_RSAPublicKey;\n    if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)\n\tossl_raise(eRSAError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_func(pkey->pkey.rsa, &p) < 0)\n\tossl_raise(eRSAError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n#define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)\n\n/*\n *  call-seq:\n *     rsa.public_encrypt(string [, padding]) -> aString\n *\n */\nstatic VALUE\nossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    int buf_len, pad;\n    VALUE str, buffer, padding;\n\n    GetPKeyRSA(self, pkey);\n    rb_scan_args(argc, argv, \"11\", &buffer, &padding);\n    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);\n    StringValue(buffer);\n    str = rb_str_new(0, ossl_rsa_buf_size(pkey));\n    buf_len = RSA_public_encrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),\n\t\t\t\t RSTRING_PTR(str), pkey->pkey.rsa,\n\t\t\t\t pad);\n    if (buf_len < 0) ossl_raise(eRSAError, NULL);\n    rb_str_set_len(str, buf_len);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     rsa.public_decrypt(string [, padding]) -> aString\n *\n */\nstatic VALUE\nossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    int buf_len, pad;\n    VALUE str, buffer, padding;\n\n    GetPKeyRSA(self, pkey);\n    rb_scan_args(argc, argv, \"11\", &buffer, &padding);\n    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);\n    StringValue(buffer);\n    str = rb_str_new(0, ossl_rsa_buf_size(pkey));\n    buf_len = RSA_public_decrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),\n\t\t\t\t RSTRING_PTR(str), pkey->pkey.rsa,\n\t\t\t\t pad);\n    if (buf_len < 0) ossl_raise(eRSAError, NULL);\n    rb_str_set_len(str, buf_len);\n    \n    return str;\n}\n\n/*\n *  call-seq:\n *     rsa.private_encrypt(string [, padding]) -> aString\n *\n */\nstatic VALUE\nossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    int buf_len, pad;\n    VALUE str, buffer, padding;\n\n    GetPKeyRSA(self, pkey);\n    if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {\n\tossl_raise(eRSAError, \"private key needed.\");\n    }\t\n    rb_scan_args(argc, argv, \"11\", &buffer, &padding);\n    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);\n    StringValue(buffer);\n    str = rb_str_new(0, ossl_rsa_buf_size(pkey));\n    buf_len = RSA_private_encrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),\n\t\t\t\t  RSTRING_PTR(str), pkey->pkey.rsa,\n\t\t\t\t  pad);\n    if (buf_len < 0) ossl_raise(eRSAError, NULL);\n    rb_str_set_len(str, buf_len);\n    \n    return str;\n}\n\n\n/*\n *  call-seq:\n *     rsa.private_decrypt(string [, padding]) -> aString\n *\n */\nstatic VALUE\nossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)\n{\n    EVP_PKEY *pkey;\n    int buf_len, pad;\n    VALUE str, buffer, padding;\n\n    GetPKeyRSA(self, pkey);\n    if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {\n\tossl_raise(eRSAError, \"private key needed.\");\n    }\n    rb_scan_args(argc, argv, \"11\", &buffer, &padding);\n    pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);\n    StringValue(buffer);\n    str = rb_str_new(0, ossl_rsa_buf_size(pkey));\n    buf_len = RSA_private_decrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),\n\t\t\t\t  RSTRING_PTR(str), pkey->pkey.rsa,\n\t\t\t\t  pad);\n    if (buf_len < 0) ossl_raise(eRSAError, NULL);\n    rb_str_set_len(str, buf_len);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     rsa.params -> hash\n *\n * Stores all parameters of key to the hash\n * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!\n * Don't use :-)) (I's up to you)\n */\nstatic VALUE\nossl_rsa_get_params(VALUE self)\n{\n    EVP_PKEY *pkey;\n    VALUE hash;\n\n    GetPKeyRSA(self, pkey);\n\n    hash = rb_hash_new();\n\n    rb_hash_aset(hash, rb_str_new2(\"n\"), ossl_bn_new(pkey->pkey.rsa->n));\n    rb_hash_aset(hash, rb_str_new2(\"e\"), ossl_bn_new(pkey->pkey.rsa->e));\n    rb_hash_aset(hash, rb_str_new2(\"d\"), ossl_bn_new(pkey->pkey.rsa->d));\n    rb_hash_aset(hash, rb_str_new2(\"p\"), ossl_bn_new(pkey->pkey.rsa->p));\n    rb_hash_aset(hash, rb_str_new2(\"q\"), ossl_bn_new(pkey->pkey.rsa->q));\n    rb_hash_aset(hash, rb_str_new2(\"dmp1\"), ossl_bn_new(pkey->pkey.rsa->dmp1));\n    rb_hash_aset(hash, rb_str_new2(\"dmq1\"), ossl_bn_new(pkey->pkey.rsa->dmq1));\n    rb_hash_aset(hash, rb_str_new2(\"iqmp\"), ossl_bn_new(pkey->pkey.rsa->iqmp));\n    \n    return hash;\n}\n\n/*\n *  call-seq:\n *     rsa.to_text -> aString\n *\n * Prints all parameters of key to buffer\n * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!\n * Don't use :-)) (It's up to you)\n */\nstatic VALUE\nossl_rsa_to_text(VALUE self)\n{\n    EVP_PKEY *pkey;\n    BIO *out;\n    VALUE str;\n\n    GetPKeyRSA(self, pkey);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eRSAError, NULL);\n    }\n    if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */\n\tBIO_free(out);\n\tossl_raise(eRSAError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     rsa.public_key -> aRSA\n *\n * Makes new instance RSA PUBLIC_KEY from PRIVATE_KEY\n */\nstatic VALUE\nossl_rsa_to_public_key(VALUE self)\n{\n    EVP_PKEY *pkey;\n    RSA *rsa;\n    VALUE obj;\n    \n    GetPKeyRSA(self, pkey);\n    /* err check performed by rsa_instance */\n    rsa = RSAPublicKey_dup(pkey->pkey.rsa);\n    obj = rsa_instance(CLASS_OF(self), rsa);\n    if (obj == Qfalse) {\n\tRSA_free(rsa);\n\tossl_raise(eRSAError, NULL);\n    }\n    return obj;\n}\n\n/*\n * TODO: Test me\n\nstatic VALUE\nossl_rsa_blinding_on(VALUE self)\n{\n    EVP_PKEY *pkey;\n    \n    GetPKeyRSA(self, pkey);\n\n    if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {\n\tossl_raise(eRSAError, NULL);\n    }\n    return self;\n}\n\nstatic VALUE\nossl_rsa_blinding_off(VALUE self)\n{\n    EVP_PKEY *pkey;\n    \n    GetPKeyRSA(self, pkey);\n    RSA_blinding_off(pkey->pkey.rsa);\n\n    return self;\n}\n */\n\nOSSL_PKEY_BN(rsa, n);\nOSSL_PKEY_BN(rsa, e);\nOSSL_PKEY_BN(rsa, d);\nOSSL_PKEY_BN(rsa, p);\nOSSL_PKEY_BN(rsa, q);\nOSSL_PKEY_BN(rsa, dmp1);\nOSSL_PKEY_BN(rsa, dmq1);\nOSSL_PKEY_BN(rsa, iqmp);\n\n/*\n * INIT\n */\n#define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))\n\nvoid\nInit_ossl_rsa()\n{\n#if 0 /* let rdoc know about mOSSL and mPKey */\n    mOSSL = rb_define_module(\"OpenSSL\");\n    mPKey = rb_define_module_under(mOSSL, \"PKey\");\n#endif\n\n    eRSAError = rb_define_class_under(mPKey, \"RSAError\", ePKeyError);\n\n    cRSA = rb_define_class_under(mPKey, \"RSA\", cPKey);\n\n    rb_define_singleton_method(cRSA, \"generate\", ossl_rsa_s_generate, -1);\n    rb_define_method(cRSA, \"initialize\", ossl_rsa_initialize, -1);\n\t\n    rb_define_method(cRSA, \"public?\", ossl_rsa_is_public, 0);\n    rb_define_method(cRSA, \"private?\", ossl_rsa_is_private, 0);\n    rb_define_method(cRSA, \"to_text\", ossl_rsa_to_text, 0);\n    rb_define_method(cRSA, \"export\", ossl_rsa_export, -1);\n    rb_define_alias(cRSA, \"to_pem\", \"export\");\n    rb_define_alias(cRSA, \"to_s\", \"export\");\n    rb_define_method(cRSA, \"to_der\", ossl_rsa_to_der, 0);\n    rb_define_method(cRSA, \"public_key\", ossl_rsa_to_public_key, 0);\n    rb_define_method(cRSA, \"public_encrypt\", ossl_rsa_public_encrypt, -1);\n    rb_define_method(cRSA, \"public_decrypt\", ossl_rsa_public_decrypt, -1);\n    rb_define_method(cRSA, \"private_encrypt\", ossl_rsa_private_encrypt, -1);\n    rb_define_method(cRSA, \"private_decrypt\", ossl_rsa_private_decrypt, -1);\n\n    DEF_OSSL_PKEY_BN(cRSA, rsa, n);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, e);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, d);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, p);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, q);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);\n    DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);\n\n    rb_define_method(cRSA, \"params\", ossl_rsa_get_params, 0);\n\n    DefRSAConst(PKCS1_PADDING);\n    DefRSAConst(SSLV23_PADDING);\n    DefRSAConst(NO_PADDING);\n    DefRSAConst(PKCS1_OAEP_PADDING);\n\n/*\n * TODO: Test it\n    rb_define_method(cRSA, \"blinding_on!\", ossl_rsa_blinding_on, 0);\n    rb_define_method(cRSA, \"blinding_off!\", ossl_rsa_blinding_off, 0);\n */\n}\n\n#else /* defined NO_RSA */\nvoid\nInit_ossl_rsa()\n{\n}\n#endif /* NO_RSA */\n\n"
  },
  {
    "path": "ext/openssl/ossl_rand.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n/*\n * Classes\n */\nVALUE mRandom;\nVALUE eRandomError;\n\n/*\n * Struct\n */\n\n/*\n * Public\n */\n\n/*\n * Private\n */\n\n/*\n *  call-seq:\n *     seed(str) -> str\n *\n */\nstatic VALUE\nossl_rand_seed(VALUE self, VALUE str)\n{\n    StringValue(str);\n    RAND_seed(RSTRING_PTR(str), RSTRING_LEN(str));\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     add(str, entropy) -> self\n *\n */\nstatic VALUE\nossl_rand_add(VALUE self, VALUE str, VALUE entropy)\n{\n    StringValue(str);\n    RAND_add(RSTRING_PTR(str), RSTRING_LEN(str), NUM2DBL(entropy));\n\n    return self;\n}\n\n/*\n *  call-seq:\n *     load_random_file(filename) -> true\n *\n */\nstatic VALUE\nossl_rand_load_file(VALUE self, VALUE filename)\n{\n    SafeStringValue(filename);\n\t\n    if(!RAND_load_file(RSTRING_PTR(filename), -1)) {\n\tossl_raise(eRandomError, NULL);\n    }\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     write_random_file(filename) -> true\n *\n */\nstatic VALUE\nossl_rand_write_file(VALUE self, VALUE filename)\n{\n    SafeStringValue(filename);\n    if (RAND_write_file(RSTRING_PTR(filename)) == -1) {\n\tossl_raise(eRandomError, NULL);\n    }\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     random_bytes(length) -> aString\n *\n */\nstatic VALUE\nossl_rand_bytes(VALUE self, VALUE len)\n{\n    VALUE str;\n    int n = NUM2INT(len);\n\n    str = rb_str_new(0, n);\n    if (!RAND_bytes(RSTRING_PTR(str), n)) {\n\tossl_raise(eRandomError, NULL);\n    }\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     pseudo_bytes(length) -> aString\n *\n */\nstatic VALUE\nossl_rand_pseudo_bytes(VALUE self, VALUE len)\n{\n    VALUE str;\n    int n = NUM2INT(len);\n\n    str = rb_str_new(0, n);\n    if (!RAND_pseudo_bytes(RSTRING_PTR(str), n)) {\n\tossl_raise(eRandomError, NULL);\n    }\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     egd(filename) -> true\n *\n */\nstatic VALUE\nossl_rand_egd(VALUE self, VALUE filename)\n{\n    SafeStringValue(filename);\n\t\n    if(!RAND_egd(RSTRING_PTR(filename))) {\n\tossl_raise(eRandomError, NULL);\n    }\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     egd_bytes(filename, length) -> true\n *\n */\nstatic VALUE\nossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)\n{\n    long n = NUM2INT(len);\n\n    SafeStringValue(filename);\n\n    if (!RAND_egd_bytes(RSTRING_PTR(filename), n)) {\n\tossl_raise(eRandomError, NULL);\n    }\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     status? => true | false\n *\n * Return true if the PRNG has been seeded with enough data, false otherwise.\n */\nstatic VALUE\nossl_rand_status(VALUE self)\n{\n    return RAND_status() ? Qtrue : Qfalse;\n}\n\n#define DEFMETH(class, name, func, argc) \\\n\trb_define_method(class, name, func, argc); \\\n\trb_define_singleton_method(class, name, func, argc);\n\n/*\n * INIT\n */\nvoid\nInit_ossl_rand()\n{\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n\n    mRandom = rb_define_module_under(mOSSL, \"Random\");\n\t\n    eRandomError = rb_define_class_under(mRandom, \"RandomError\", eOSSLError);\n\t\n    DEFMETH(mRandom, \"seed\", ossl_rand_seed, 1);\n    DEFMETH(mRandom, \"random_add\", ossl_rand_add, 2);\n    DEFMETH(mRandom, \"load_random_file\", ossl_rand_load_file, 1);\n    DEFMETH(mRandom, \"write_random_file\", ossl_rand_write_file, 1);\n    DEFMETH(mRandom, \"random_bytes\", ossl_rand_bytes, 1);\n    DEFMETH(mRandom, \"pseudo_bytes\", ossl_rand_pseudo_bytes, 1);\n    DEFMETH(mRandom, \"egd\", ossl_rand_egd, 1);\n    DEFMETH(mRandom, \"egd_bytes\", ossl_rand_egd_bytes, 2);\t\n    DEFMETH(mRandom, \"status?\", ossl_rand_status, 0)\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_rand.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_RAND_H_)\n#define _OSSL_RAND_H_\n\nextern VALUE mRandom;\nextern VALUE eRandomError;\n\nvoid Init_ossl_rand(void);\n\n#endif /* _OSSL_RAND_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_ssl.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2000-2002  GOTOU Yuuzou <gotoyuzo@notwork.org>\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * Copyright (C) 2001-2007  Technorama Ltd. <oss-ruby@technorama.net>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n#include <rubysig.h>\n#include <rubyio.h>\n\n#if defined(HAVE_UNISTD_H)\n#  include <unistd.h> /* for read(), and write() */\n#endif\n\n#define numberof(ary) (sizeof(ary)/sizeof(ary[0]))\n\n#ifdef _WIN32\n#  define TO_SOCKET(s) _get_osfhandle(s)\n#else\n#  define TO_SOCKET(s) s\n#endif\n\nVALUE mSSL;\nVALUE eSSLError;\nVALUE cSSLContext;\nVALUE cSSLSocket;\n\n#define ossl_sslctx_set_cert(o,v)        rb_iv_set((o),\"@cert\",(v))\n#define ossl_sslctx_set_key(o,v)         rb_iv_set((o),\"@key\",(v))\n#define ossl_sslctx_set_client_ca(o,v)   rb_iv_set((o),\"@client_ca\",(v))\n#define ossl_sslctx_set_ca_file(o,v)     rb_iv_set((o),\"@ca_file\",(v))\n#define ossl_sslctx_set_ca_path(o,v)     rb_iv_set((o),\"@ca_path\",(v))\n#define ossl_sslctx_set_timeout(o,v)     rb_iv_set((o),\"@timeout\",(v))\n#define ossl_sslctx_set_verify_mode(o,v) rb_iv_set((o),\"@verify_mode\",(v))\n#define ossl_sslctx_set_verify_dep(o,v)  rb_iv_set((o),\"@verify_depth\",(v))\n#define ossl_sslctx_set_verify_cb(o,v)   rb_iv_set((o),\"@verify_callback\",(v))\n#define ossl_sslctx_set_options(o,v)     rb_iv_set((o),\"@options\",(v))\n#define ossl_sslctx_set_cert_store(o,v)  rb_iv_set((o),\"@cert_store\",(v))\n#define ossl_sslctx_set_extra_cert(o,v)  rb_iv_set((o),\"@extra_chain_cert\",(v))\n#define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),\"@client_cert_cb\",(v))\n#define ossl_sslctx_set_tmp_dh_cb(o,v)   rb_iv_set((o),\"@tmp_dh_callback\",(v))\n#define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_get((o),\"@session_id_context\"(v))\n\n#define ossl_sslctx_get_cert(o)          rb_iv_get((o),\"@cert\")\n#define ossl_sslctx_get_key(o)           rb_iv_get((o),\"@key\")\n#define ossl_sslctx_get_client_ca(o)     rb_iv_get((o),\"@client_ca\")\n#define ossl_sslctx_get_ca_file(o)       rb_iv_get((o),\"@ca_file\")\n#define ossl_sslctx_get_ca_path(o)       rb_iv_get((o),\"@ca_path\")\n#define ossl_sslctx_get_timeout(o)       rb_iv_get((o),\"@timeout\")\n#define ossl_sslctx_get_verify_mode(o)   rb_iv_get((o),\"@verify_mode\")\n#define ossl_sslctx_get_verify_dep(o)    rb_iv_get((o),\"@verify_depth\")\n#define ossl_sslctx_get_verify_cb(o)     rb_iv_get((o),\"@verify_callback\")\n#define ossl_sslctx_get_options(o)       rb_iv_get((o),\"@options\")\n#define ossl_sslctx_get_cert_store(o)    rb_iv_get((o),\"@cert_store\")\n#define ossl_sslctx_get_extra_cert(o)    rb_iv_get((o),\"@extra_chain_cert\")\n#define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),\"@client_cert_cb\")\n#define ossl_sslctx_get_tmp_dh_cb(o)     rb_iv_get((o),\"@tmp_dh_callback\")\n#define ossl_sslctx_get_sess_id_ctx(o)   rb_iv_get((o),\"@session_id_context\")\n\nstatic const char *ossl_sslctx_attrs[] = {\n    \"cert\", \"key\", \"client_ca\", \"ca_file\", \"ca_path\",\n    \"timeout\", \"verify_mode\", \"verify_depth\",\n    \"verify_callback\", \"options\", \"cert_store\", \"extra_chain_cert\",\n    \"client_cert_cb\", \"tmp_dh_callback\", \"session_id_context\",\n    \"session_get_cb\", \"session_new_cb\", \"session_remove_cb\",\n};\n\n#define ossl_ssl_get_io(o)           rb_iv_get((o),\"@io\")\n#define ossl_ssl_get_ctx(o)          rb_iv_get((o),\"@context\")\n#define ossl_ssl_get_sync_close(o)   rb_iv_get((o),\"@sync_close\")\n#define ossl_ssl_get_x509(o)         rb_iv_get((o),\"@x509\")\n#define ossl_ssl_get_key(o)          rb_iv_get((o),\"@key\")\n#define ossl_ssl_get_tmp_dh(o)       rb_iv_get((o),\"@tmp_dh\")\n\n#define ossl_ssl_set_io(o,v)         rb_iv_set((o),\"@io\",(v))\n#define ossl_ssl_set_ctx(o,v)        rb_iv_set((o),\"@context\",(v))\n#define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),\"@sync_close\",(v))\n#define ossl_ssl_set_x509(o,v)       rb_iv_set((o),\"@x509\",(v))\n#define ossl_ssl_set_key(o,v)        rb_iv_set((o),\"@key\",(v))\n#define ossl_ssl_set_tmp_dh(o,v)     rb_iv_set((o),\"@tmp_dh\",(v))\n\nstatic const char *ossl_ssl_attr_readers[] = { \"io\", \"context\", };\nstatic const char *ossl_ssl_attrs[] = { \"sync_close\", };\n\nID ID_callback_state;\n\n/*\n * SSLContext class\n */\nstruct {\n    const char *name;\n    OSSL_MORE_CONST SSL_METHOD *(*func)(void);\n} ossl_ssl_method_tab[] = {\n#define OSSL_SSL_METHOD_ENTRY(name) { #name, name##_method }\n    OSSL_SSL_METHOD_ENTRY(TLSv1),\n    OSSL_SSL_METHOD_ENTRY(TLSv1_server),\n    OSSL_SSL_METHOD_ENTRY(TLSv1_client),\n    OSSL_SSL_METHOD_ENTRY(SSLv2),\n    OSSL_SSL_METHOD_ENTRY(SSLv2_server),\n    OSSL_SSL_METHOD_ENTRY(SSLv2_client),\n    OSSL_SSL_METHOD_ENTRY(SSLv3),\n    OSSL_SSL_METHOD_ENTRY(SSLv3_server),\n    OSSL_SSL_METHOD_ENTRY(SSLv3_client),\n    OSSL_SSL_METHOD_ENTRY(SSLv23),\n    OSSL_SSL_METHOD_ENTRY(SSLv23_server),\n    OSSL_SSL_METHOD_ENTRY(SSLv23_client),\n#undef OSSL_SSL_METHOD_ENTRY\n};\n\nint ossl_ssl_ex_vcb_idx;\nint ossl_ssl_ex_store_p;\nint ossl_ssl_ex_ptr_idx;\nint ossl_ssl_ex_client_cert_cb_idx;\nint ossl_ssl_ex_tmp_dh_callback_idx;\n\nstatic void\nossl_sslctx_free(SSL_CTX *ctx)\n{\n    if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)\n\tctx->cert_store = NULL;\n    SSL_CTX_free(ctx);\n}\n\nstatic VALUE\nossl_sslctx_s_alloc(VALUE klass)\n{\n    SSL_CTX *ctx;\n\n    ctx = SSL_CTX_new(SSLv23_method());\n    if (!ctx) {\n        ossl_raise(eSSLError, \"SSL_CTX_new:\");\n    }\n    SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);\n    SSL_CTX_set_options(ctx, SSL_OP_ALL);\n    return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx);\n}\n\nstatic VALUE\nossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)\n{\n    OSSL_MORE_CONST SSL_METHOD *method = NULL;\n    const char *s;\n    int i;\n\n    SSL_CTX *ctx;\n    if(TYPE(ssl_method) == T_SYMBOL)\n\ts = rb_id2name(SYM2ID(ssl_method));\n    else\n\ts =  StringValuePtr(ssl_method);\n    for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {\n        if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {\n            method = ossl_ssl_method_tab[i].func();\n            break;\n        }\n    }\n    if (!method) {\n        ossl_raise(rb_eArgError, \"unknown SSL method `%s'.\", s);\n    }\n    Data_Get_Struct(self, SSL_CTX, ctx);\n    if (SSL_CTX_set_ssl_version(ctx, method) != 1) {\n        ossl_raise(eSSLError, \"SSL_CTX_set_ssl_version:\");\n    }\n\n    return ssl_method;\n}\n\n/*\n * call-seq:\n *    SSLContext.new => ctx\n *    SSLContext.new(:TLSv1) => ctx\n *    SSLContext.new(\"SSLv23_client\") => ctx\n *\n * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS\n */\nstatic VALUE\nossl_sslctx_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE ssl_method;\n    int i;\n\n    for(i = 0; i < numberof(ossl_sslctx_attrs); i++){\n\tchar buf[32];\n\tsnprintf(buf, sizeof(buf), \"@%s\", ossl_sslctx_attrs[i]);\n\trb_iv_set(self, buf, Qnil);\n    }\n    if (rb_scan_args(argc, argv, \"01\", &ssl_method) == 0){\n        return self;\n    }\n    ossl_sslctx_set_ssl_version(self, ssl_method);\n\n    return self;\n}\n\nstatic VALUE\nossl_call_client_cert_cb(VALUE obj)\n{\n    VALUE cb, ary, cert, key;\n    SSL *ssl;\n\n    Data_Get_Struct(obj, SSL, ssl);\n    cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx);\n    if (NIL_P(cb)) return Qfalse;\n    ary = rb_funcall(cb, rb_intern(\"call\"), 1, obj);\n    Check_Type(ary, T_ARRAY);\n    GetX509CertPtr(cert = rb_ary_entry(ary, 0));\n    GetPKeyPtr(key = rb_ary_entry(ary, 1));\n    ossl_ssl_set_x509(obj, cert);\n    ossl_ssl_set_key(obj, key);\n\n    return Qtrue;\n}\n\nstatic int\nossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)\n{\n    VALUE obj;\n    int status, success;\n\n    obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);\n    success = rb_protect((VALUE(*)_((VALUE)))ossl_call_client_cert_cb,\n                         obj, &status);\n    if (status || !success) return 0;\n    *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj));\n    *pkey = DupPKeyPtr(ossl_ssl_get_key(obj));\n\n    return 1;\n}\n\n#if !defined(OPENSSL_NO_DH)\nstatic VALUE\nossl_call_tmp_dh_callback(VALUE *args)\n{\n    SSL *ssl;\n    VALUE cb, dh;\n    EVP_PKEY *pkey;\n\n    Data_Get_Struct(args[0], SSL, ssl);\n    cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx);\n    if (NIL_P(cb)) return Qfalse;\n    dh = rb_funcall(cb, rb_intern(\"call\"), 3, args[0], args[1], args[2]);\n    pkey = GetPKeyPtr(dh);\n    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse;\n    ossl_ssl_set_tmp_dh(args[0], dh);\n\n    return Qtrue;\n}\n\nstatic DH*\nossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)\n{\n    VALUE args[3];\n    int status, success;\n\n    args[0] = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);\n    args[1] = INT2FIX(is_export);\n    args[2] = INT2FIX(keylength);\n    success = rb_protect((VALUE(*)_((VALUE)))ossl_call_tmp_dh_callback,\n                         (VALUE)args, &status);\n    if (status || !success) return NULL;\n\n    return GetPKeyPtr(ossl_ssl_get_tmp_dh(args[0]))->pkey.dh;\n}\n\nstatic DH*\nossl_default_tmp_dh_callback(SSL *ssl, int is_export, int keylength)\n{\n    rb_warning(\"using default DH parameters.\");\n\n    switch(keylength){\n    case 512:\n\treturn OSSL_DEFAULT_DH_512;\n    case 1024:\n\treturn OSSL_DEFAULT_DH_1024;\n    }\n    return NULL;\n}\n#endif /* OPENSSL_NO_DH */\n\nstatic int\nossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)\n{\n    VALUE cb;\n    SSL *ssl;\n\n    ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());\n    cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);\n    X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb);\n    return ossl_verify_cb(preverify_ok, ctx);\n}\n\nstatic VALUE\nossl_call_session_get_cb(VALUE ary)\n{\n    VALUE ssl_obj, sslctx_obj, cb, ret;\n    \n    Check_Type(ary, T_ARRAY);\n    ssl_obj = rb_ary_entry(ary, 0);\n\n    sslctx_obj = rb_iv_get(ssl_obj, \"@context\");\n    if (NIL_P(sslctx_obj)) return Qnil;\n    cb = rb_iv_get(sslctx_obj, \"@session_get_cb\");\n    if (NIL_P(cb)) return Qnil;\n\n    return rb_funcall(cb, rb_intern(\"call\"), 1, ary);\n}\n\n/* this method is currently only called for servers (in OpenSSL <= 0.9.8e) */\nstatic SSL_SESSION *\nossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)\n{\n    VALUE ary, ssl_obj, ret_obj;\n    SSL_SESSION *sess;\n    void *ptr;\n    int state = 0;\n\n    OSSL_Debug(\"SSL SESSION get callback entered\");\n    if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)\n    \treturn NULL;\n    ssl_obj = (VALUE)ptr;\n    ary = rb_ary_new2(2);\n    rb_ary_push(ary, ssl_obj);\n    rb_ary_push(ary, rb_str_new(buf, len));\n\n    ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_get_cb, ary, &state);\n    if (state) {\n        rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));\n        return NULL;\n    }\n    if (!rb_obj_is_instance_of(ret_obj, cSSLSession))\n        return NULL;\n\n    SafeGetSSLSession(ret_obj, sess);\n    *copy = 1;\n\n    return sess;\n}\n\nstatic VALUE\nossl_call_session_new_cb(VALUE ary)\n{\n    VALUE ssl_obj, sslctx_obj, cb, ret;\n    \n    Check_Type(ary, T_ARRAY);\n    ssl_obj = rb_ary_entry(ary, 0);\n\n    sslctx_obj = rb_iv_get(ssl_obj, \"@context\");\n    if (NIL_P(sslctx_obj)) return Qnil;\n    cb = rb_iv_get(sslctx_obj, \"@session_new_cb\");\n    if (NIL_P(cb)) return Qnil;\n\n    return rb_funcall(cb, rb_intern(\"call\"), 1, ary);\n}\n\n/* return 1 normal.  return 0 removes the session */\nstatic int\nossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)\n{\n    VALUE ary, ssl_obj, sess_obj, ret_obj;\n    void *ptr;\n    int state = 0;\n\n    OSSL_Debug(\"SSL SESSION new callback entered\");\n\n    if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)\n    \treturn 1;\n    ssl_obj = (VALUE)ptr;\n    sess_obj = rb_obj_alloc(cSSLSession);\n    CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);\n    DATA_PTR(sess_obj) = sess;\n\n    ary = rb_ary_new2(2);\n    rb_ary_push(ary, ssl_obj);\n    rb_ary_push(ary, sess_obj);\n\n    ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);\n    if (state) {\n        rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));\n        return 0; /* what should be returned here??? */\n    }\n\n    return RTEST(ret_obj) ? 1 : 0;\n}\n\nstatic VALUE\nossl_call_session_remove_cb(VALUE ary)\n{\n    VALUE sslctx_obj, cb, ret;\n    \n    Check_Type(ary, T_ARRAY);\n    sslctx_obj = rb_ary_entry(ary, 0);\n\n    cb = rb_iv_get(sslctx_obj, \"@session_remove_cb\");\n    if (NIL_P(cb)) return Qnil;\n\n    return rb_funcall(cb, rb_intern(\"call\"), 1, ary);\n}\n\nstatic void\nossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)\n{\n    VALUE ary, sslctx_obj, sess_obj, ret_obj;\n    void *ptr;\n    int state = 0;\n\n    OSSL_Debug(\"SSL SESSION remove callback entered\");\n\n    if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL)\n    \treturn;\n    sslctx_obj = (VALUE)ptr;\n    sess_obj = rb_obj_alloc(cSSLSession);\n    CRYPTO_add(&sess->references, 1, CRYPTO_LOCK_SSL_SESSION);\n    DATA_PTR(sess_obj) = sess;\n\n    ary = rb_ary_new2(2);\n    rb_ary_push(ary, sslctx_obj);\n    rb_ary_push(ary, sess_obj);\n\n    ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_session_new_cb, ary, &state);\n    if (state) {\n/*\n  the SSL_CTX is frozen, nowhere to save state.\n  there is no common accessor method to check it either.\n        rb_ivar_set(sslctx_obj, ID_callback_state, INT2NUM(state));\n*/\n    }\n}\n\nstatic VALUE\nossl_sslctx_add_extra_chain_cert_i(VALUE i, VALUE arg)\n{\n    X509 *x509;\n    SSL_CTX *ctx;\n\n    Data_Get_Struct(arg, SSL_CTX, ctx);\n    x509 = DupX509CertPtr(i);\n    if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){\n\tossl_raise(eSSLError, NULL);\n    }\n\n    return i;\n}\n\n/*\n * call-seq:\n *    ctx.setup => Qtrue # first time\n *    ctx.setup => nil # thereafter\n *\n * This method is called automatically when a new SSLSocket is created.\n * Normally you do not need to call this method (unless you are writing an extension in C).\n */\nstatic VALUE\nossl_sslctx_setup(VALUE self)\n{\n    SSL_CTX *ctx;\n    X509 *cert = NULL, *client_ca = NULL;\n    X509_STORE *store;\n    EVP_PKEY *key = NULL;\n    char *ca_path = NULL, *ca_file = NULL;\n    int i, verify_mode;\n    VALUE val;\n\n    if(OBJ_FROZEN(self)) return Qnil;\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n#if !defined(OPENSSL_NO_DH)\n    if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){\n\tSSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);\n    }\n    else{\n\tSSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);\n    }\n#endif\n    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);\n\n    val = ossl_sslctx_get_cert_store(self);\n    if(!NIL_P(val)){\n\t/*\n         * WORKAROUND:\n\t *   X509_STORE can count references, but\n\t *   X509_STORE_free() doesn't care it.\n\t *   So we won't increment it but mark it by ex_data.\n\t */\n        store = GetX509StorePtr(val); /* NO NEED TO DUP */\n        SSL_CTX_set_cert_store(ctx, store);\n        SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);\n    }\n\n    val = ossl_sslctx_get_extra_cert(self);\n    if(!NIL_P(val)){\n\trb_block_call(val, rb_intern(\"each\"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);\n    }\n\n    /* private key may be bundled in certificate file. */\n    val = ossl_sslctx_get_cert(self);\n    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */\n    val = ossl_sslctx_get_key(self);\n    key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */\n    if (cert && key) {\n        if (!SSL_CTX_use_certificate(ctx, cert)) {\n            /* Adds a ref => Safe to FREE */\n            ossl_raise(eSSLError, \"SSL_CTX_use_certificate:\");\n        }\n        if (!SSL_CTX_use_PrivateKey(ctx, key)) {\n            /* Adds a ref => Safe to FREE */\n            ossl_raise(eSSLError, \"SSL_CTX_use_PrivateKey:\");\n        }\n        if (!SSL_CTX_check_private_key(ctx)) {\n            ossl_raise(eSSLError, \"SSL_CTX_check_private_key:\");\n        }\n    }\n\n    val = ossl_sslctx_get_client_ca(self);\n    if(!NIL_P(val)){\n\tif(TYPE(val) == T_ARRAY){\n\t    for(i = 0; i < RARRAY_LEN(val); i++){\n\t\tclient_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);\n        \tif (!SSL_CTX_add_client_CA(ctx, client_ca)){\n\t\t    /* Copies X509_NAME => FREE it. */\n        \t    ossl_raise(eSSLError, \"SSL_CTX_add_client_CA\");\n        \t}\n\t    }\n        }\n\telse{\n\t    client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */\n            if (!SSL_CTX_add_client_CA(ctx, client_ca)){\n\t\t/* Copies X509_NAME => FREE it. */\n        \tossl_raise(eSSLError, \"SSL_CTX_add_client_CA\");\n            }\n\t}\n    }\n\n    val = ossl_sslctx_get_ca_file(self);\n    ca_file = NIL_P(val) ? NULL : StringValuePtr(val);\n    val = ossl_sslctx_get_ca_path(self);\n    ca_path = NIL_P(val) ? NULL : StringValuePtr(val);\n    if(ca_file || ca_path){\n\tif (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))\n\t    rb_warning(\"can't set verify locations\");\n    }\n\n    val = ossl_sslctx_get_verify_mode(self);\n    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);\n    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);\n    if (RTEST(ossl_sslctx_get_client_cert_cb(self)))\n\tSSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);\n\n    val = ossl_sslctx_get_timeout(self);\n    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));\n\n    val = ossl_sslctx_get_verify_dep(self);\n    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));\n\n    val = ossl_sslctx_get_options(self);\n    if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val));\n    rb_obj_freeze(self);\n\n    val = ossl_sslctx_get_sess_id_ctx(self);\n    if (!NIL_P(val)){\n\tStringValue(val);\n\tif (!SSL_CTX_set_session_id_context(ctx, RSTRING_PTR(val),\n\t\t\t\t\t    RSTRING_LEN(val))){\n\t    ossl_raise(eSSLError, \"SSL_CTX_set_session_id_context:\");\n\t}\n    }\n\n    if (RTEST(rb_iv_get(self, \"@session_get_cb\"))) {\n\tSSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);\n\tOSSL_Debug(\"SSL SESSION get callback added\");\n    }\n    if (RTEST(rb_iv_get(self, \"@session_new_cb\"))) {\n\tSSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);\n\tOSSL_Debug(\"SSL SESSION new callback added\");\n    }\n    if (RTEST(rb_iv_get(self, \"@session_remove_cb\"))) {\n\tSSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);\n\tOSSL_Debug(\"SSL SESSION remove callback added\");\n    }\n    return Qtrue;\n}\n\nstatic VALUE\nossl_ssl_cipher_to_ary(OSSL_MORE_CONST SSL_CIPHER *cipher)\n{\n    VALUE ary;\n    int bits, alg_bits;\n\n    ary = rb_ary_new2(4);\n    rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher)));\n    rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher)));\n    bits = SSL_CIPHER_get_bits(cipher, &alg_bits);\n    rb_ary_push(ary, INT2FIX(bits));\n    rb_ary_push(ary, INT2FIX(alg_bits));\n\n    return ary;\n}\n\n/*\n * call-seq:\n *    ctx.ciphers => [[name, version, bits, alg_bits], ...]\n */\nstatic VALUE\nossl_sslctx_get_ciphers(VALUE self)\n{\n    SSL_CTX *ctx;\n    STACK_OF(SSL_CIPHER) *ciphers;\n    SSL_CIPHER *cipher;\n    VALUE ary;\n    int i, num;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n    if(!ctx){\n        rb_warning(\"SSL_CTX is not initialized.\");\n        return Qnil;\n    }\n    ciphers = ctx->cipher_list;\n\n    if (!ciphers)\n        return rb_ary_new();\n\n    num = sk_num((STACK*)ciphers);\n    ary = rb_ary_new2(num);\n    for(i = 0; i < num; i++){\n        cipher = (SSL_CIPHER*)sk_value((STACK*)ciphers, i);\n        rb_ary_push(ary, ossl_ssl_cipher_to_ary(cipher));\n    }\n    return ary;\n}\n\n/*\n * call-seq:\n *    ctx.ciphers = \"cipher1:cipher2:...\"\n *    ctx.ciphers = [name, ...]\n *    ctx.ciphers = [[name, version, bits, alg_bits], ...]\n */\nstatic VALUE\nossl_sslctx_set_ciphers(VALUE self, VALUE v)\n{\n    SSL_CTX *ctx;\n    VALUE str, elem;\n    int i;\n\n    rb_check_frozen(self);\n    if (NIL_P(v))\n\treturn v;\n    else if (TYPE(v) == T_ARRAY) {\n        str = rb_str_new(0, 0);\n        for (i = 0; i < RARRAY_LEN(v); i++) {\n            elem = rb_ary_entry(v, i);\n            if (TYPE(elem) == T_ARRAY) elem = rb_ary_entry(elem, 0);\n            elem = rb_String(elem);\n            rb_str_append(str, elem);\n            if (i < RARRAY_LEN(v)-1) rb_str_cat2(str, \":\");\n        }\n    } else {\n        str = v;\n        StringValue(str);\n    }\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n    if(!ctx){\n        ossl_raise(eSSLError, \"SSL_CTX is not initialized.\");\n        return Qnil;\n    }\n    if (!SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(str))) {\n        ossl_raise(eSSLError, \"SSL_CTX_set_cipher_list:\");\n    }\n\n    return v;\n}\n\n\n/*\n *  call-seq:\n *     ctx.session_add(session) -> true | false\n *\n */\nstatic VALUE\nossl_sslctx_session_add(VALUE self, VALUE arg)\n{\n    SSL_CTX *ctx;\n    SSL_SESSION *sess;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n    SafeGetSSLSession(arg, sess);\n\n    return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     ctx.session_remove(session) -> true | false\n *\n */\nstatic VALUE\nossl_sslctx_session_remove(VALUE self, VALUE arg)\n{\n    SSL_CTX *ctx;\n    SSL_SESSION *sess;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n    SafeGetSSLSession(arg, sess);\n\n    return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     ctx.session_cache_mode -> integer\n *\n */\nstatic VALUE\nossl_sslctx_get_session_cache_mode(VALUE self)\n{\n    SSL_CTX *ctx;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n    return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx));\n}\n\n/*\n *  call-seq:\n *     ctx.session_cache_mode=(integer) -> integer\n *\n */\nstatic VALUE\nossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)\n{\n    SSL_CTX *ctx;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n    SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg));\n\n    return arg;\n}\n\n/*\n *  call-seq:\n *     ctx.session_cache_size -> integer\n *\n */\nstatic VALUE\nossl_sslctx_get_session_cache_size(VALUE self)\n{\n    SSL_CTX *ctx;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n    return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx));\n}\n\n/*\n *  call-seq:\n *     ctx.session_cache_size=(integer) -> integer\n *\n */\nstatic VALUE\nossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)\n{\n    SSL_CTX *ctx;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n    SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg));\n\n    return arg;\n}\n\n/*\n *  call-seq:\n *     ctx.session_cache_stats -> Hash\n *\n */\nstatic VALUE\nossl_sslctx_get_session_cache_stats(VALUE self)\n{\n    SSL_CTX *ctx;\n    VALUE hash;\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n    hash = rb_hash_new();\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"cache_num\")), LONG2NUM(SSL_CTX_sess_number(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"connect\")), LONG2NUM(SSL_CTX_sess_connect(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"connect_good\")), LONG2NUM(SSL_CTX_sess_connect_good(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"connect_renegotiate\")), LONG2NUM(SSL_CTX_sess_connect_renegotiate(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"accept\")), LONG2NUM(SSL_CTX_sess_accept(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"accept_good\")), LONG2NUM(SSL_CTX_sess_accept_good(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"accept_renegotiate\")), LONG2NUM(SSL_CTX_sess_accept_renegotiate(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"cache_hits\")), LONG2NUM(SSL_CTX_sess_hits(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"cb_hits\")), LONG2NUM(SSL_CTX_sess_cb_hits(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"cache_misses\")), LONG2NUM(SSL_CTX_sess_misses(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"cache_full\")), LONG2NUM(SSL_CTX_sess_cache_full(ctx)));\n    rb_hash_aset(hash, ID2SYM(rb_intern(\"timeouts\")), LONG2NUM(SSL_CTX_sess_timeouts(ctx)));\n\n    return hash;\n}\n\n\n/*\n *  call-seq:\n *     ctx.flush_sessions(time | nil) -> self\n *\n */\nstatic VALUE\nossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)\n{\n    VALUE arg1;\n    SSL_CTX *ctx;\n    time_t tm = 0;\n    int cb_state;\n\n    rb_scan_args(argc, argv, \"01\", &arg1);\n\n    Data_Get_Struct(self, SSL_CTX, ctx);\n\n    if (NIL_P(arg1)) {\n        tm = time(0);\n    } else if (rb_obj_is_instance_of(arg1, rb_cTime)) {\n        tm = NUM2LONG(rb_funcall(arg1, rb_intern(\"to_i\"), 0));\n    } else {\n        rb_raise(rb_eArgError, \"arg must be Time or nil\");\n    }\n\n    SSL_CTX_flush_sessions(ctx, tm);\n\n    return self;\n}\n\n/*\n * SSLSocket class\n */\nstatic void\nossl_ssl_shutdown(SSL *ssl)\n{\n    if (ssl) {\n        SSL_shutdown(ssl);\n        SSL_clear(ssl);\n    }\n}\n\nstatic void\nossl_ssl_free(SSL *ssl)\n{\n    ossl_ssl_shutdown(ssl);\n    SSL_free(ssl);\n}\n\nstatic VALUE\nossl_ssl_s_alloc(VALUE klass)\n{\n    return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL);\n}\n\n/*\n * call-seq:\n *    SSLSocket.new(io) => aSSLSocket\n *    SSLSocket.new(io, ctx) => aSSLSocket\n *\n * === Parameters\n * * +io+ is a real ruby IO object.  Not an IO like object that responds to read/write.\n * * +ctx+ is an OpenSSLSSL::SSLContext.\n *\n * The OpenSSL::Buffering module provides additional IO methods.\n *\n * This method will freeze the SSLContext if one is provided;\n * however, session management is still allowed in the frozen SSLContext.\n */\nstatic VALUE\nossl_ssl_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE io, ctx;\n\n    if (rb_scan_args(argc, argv, \"11\", &io, &ctx) == 1) {\n        ctx = rb_funcall(cSSLContext, rb_intern(\"new\"), 0);\n    }\n    OSSL_Check_Kind(ctx, cSSLContext);\n    Check_Type(io, T_FILE);\n    ossl_ssl_set_io(self, io);\n    ossl_ssl_set_ctx(self, ctx);\n    ossl_ssl_set_sync_close(self, Qfalse);\n    ossl_sslctx_setup(ctx);\n    rb_call_super(0, 0);\n\n    return self;\n}\n\nstatic VALUE\nossl_ssl_setup(VALUE self)\n{\n    VALUE io, v_ctx, cb;\n    SSL_CTX *ctx;\n    SSL *ssl;\n    rb_io_t *fptr;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if(!ssl){\n        v_ctx = ossl_ssl_get_ctx(self);\n        Data_Get_Struct(v_ctx, SSL_CTX, ctx);\n\n        ssl = SSL_new(ctx);\n        if (!ssl) {\n            ossl_raise(eSSLError, \"SSL_new:\");\n        }\n        DATA_PTR(self) = ssl;\n\n        io = ossl_ssl_get_io(self);\n        GetOpenFile(io, fptr);\n        rb_io_check_readable(fptr);\n        rb_io_check_writable(fptr);\n        SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr)));\n\tSSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void*)self);\n\tcb = ossl_sslctx_get_verify_cb(v_ctx);\n\tSSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void*)cb);\n\tcb = ossl_sslctx_get_client_cert_cb(v_ctx);\n\tSSL_set_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx, (void*)cb);\n\tcb = ossl_sslctx_get_tmp_dh_cb(v_ctx);\n\tSSL_set_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx, (void*)cb);\n    }\n\n    return Qtrue;\n}\n\n#ifdef _WIN32\n#define ssl_get_error(ssl, ret) (errno = WSAGetLastError(), SSL_get_error(ssl, ret))\n#else\n#define ssl_get_error(ssl, ret) SSL_get_error(ssl, ret)\n#endif\n\nstatic VALUE\nossl_start_ssl(VALUE self, int (*func)(), const char *funcname)\n{\n    SSL *ssl;\n    rb_io_t *fptr;\n    int ret, ret2;\n    VALUE cb_state;\n\n    rb_ivar_set(self, ID_callback_state, Qnil);\n\n    Data_Get_Struct(self, SSL, ssl);\n    GetOpenFile(ossl_ssl_get_io(self), fptr);\n    for(;;){\n\tif((ret = func(ssl)) > 0) break;\n\tswitch((ret2 = ssl_get_error(ssl, ret))){\n\tcase SSL_ERROR_WANT_WRITE:\n            rb_io_wait_writable(FPTR_TO_FD(fptr));\n            continue;\n\tcase SSL_ERROR_WANT_READ:\n            rb_io_wait_readable(FPTR_TO_FD(fptr));\n            continue;\n\tcase SSL_ERROR_SYSCALL:\n\t    if (errno) rb_sys_fail(funcname);\n\t    ossl_raise(eSSLError, \"%s SYSCALL returned=%d errno=%d state=%s\", funcname, ret2, errno, SSL_state_string_long(ssl));\n\tdefault:\n\t    ossl_raise(eSSLError, \"%s returned=%d errno=%d state=%s\", funcname, ret2, errno, SSL_state_string_long(ssl));\n\t}\n    }\n\n    cb_state = rb_ivar_get(self, ID_callback_state);\n    if (!NIL_P(cb_state))\n        rb_jump_tag(NUM2INT(cb_state));\n\n    return self;\n}\n\n/*\n * call-seq:\n *    ssl.connect => self\n */\nstatic VALUE\nossl_ssl_connect(VALUE self)\n{\n    ossl_ssl_setup(self);\n    return ossl_start_ssl(self, SSL_connect, \"SSL_connect\");\n}\n\n/*\n * call-seq:\n *    ssl.accept => self\n */\nstatic VALUE\nossl_ssl_accept(VALUE self)\n{\n    ossl_ssl_setup(self);\n    return ossl_start_ssl(self, SSL_accept, \"SSL_accept\");\n}\n\n/*\n * call-seq:\n *    ssl.sysread(length) => string\n *    ssl.sysread(length, buffer) => buffer\n *\n * === Parameters\n * * +length+ is a positive integer.\n * * +buffer+ is a string used to store the result.\n */\nstatic VALUE\nossl_ssl_read(int argc, VALUE *argv, VALUE self)\n{\n    SSL *ssl;\n    int ilen, nread = 0;\n    VALUE len, str;\n    rb_io_t *fptr;\n\n    rb_scan_args(argc, argv, \"11\", &len, &str);\n    ilen = NUM2INT(len);\n    if(NIL_P(str)) str = rb_str_new(0, ilen);\n    else{\n        StringValue(str);\n        rb_str_modify(str);\n        rb_str_resize(str, ilen);\n    }\n    if(ilen == 0) return str;\n\n    Data_Get_Struct(self, SSL, ssl);\n    GetOpenFile(ossl_ssl_get_io(self), fptr);\n    if (ssl) {\n\tif(SSL_pending(ssl) <= 0)\n\t    rb_thread_wait_fd(FPTR_TO_FD(fptr));\n\tfor (;;){\n\t    nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LEN(str));\n\t    switch(ssl_get_error(ssl, nread)){\n\t    case SSL_ERROR_NONE:\n\t\tgoto end;\n\t    case SSL_ERROR_ZERO_RETURN:\n\t\trb_eof_error();\n\t    case SSL_ERROR_WANT_WRITE:\n                rb_io_wait_writable(FPTR_TO_FD(fptr));\n                continue;\n\t    case SSL_ERROR_WANT_READ:\n                rb_io_wait_readable(FPTR_TO_FD(fptr));\n\t\tcontinue;\n\t    case SSL_ERROR_SYSCALL:\n\t\tif(ERR_peek_error() == 0 && nread == 0) rb_eof_error();\n\t\trb_sys_fail(0);\n\t    default:\n\t\tossl_raise(eSSLError, \"SSL_read:\");\n\t    }\n        }\n    }\n    else {\n        ID id_sysread = rb_intern(\"sysread\");\n        rb_warning(\"SSL session is not started yet.\");\n        return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str);\n    }\n\n  end:\n    rb_str_set_len(str, nread);\n    OBJ_TAINT(str);\n\n    return str;\n}\n\n/*\n * call-seq:\n *    ssl.syswrite(string) => integer\n */\nstatic VALUE\nossl_ssl_write(VALUE self, VALUE str)\n{\n    SSL *ssl;\n    int nwrite = 0;\n    rb_io_t *fptr;\n\n    StringValue(str);\n    Data_Get_Struct(self, SSL, ssl);\n    GetOpenFile(ossl_ssl_get_io(self), fptr);\n\n    if (ssl) {\n\tfor (;;){\n\t    nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LEN(str));\n\t    switch(ssl_get_error(ssl, nwrite)){\n\t    case SSL_ERROR_NONE:\n\t\tgoto end;\n\t    case SSL_ERROR_WANT_WRITE:\n                rb_io_wait_writable(FPTR_TO_FD(fptr));\n                continue;\n\t    case SSL_ERROR_WANT_READ:\n                rb_io_wait_readable(FPTR_TO_FD(fptr));\n                continue;\n\t    case SSL_ERROR_SYSCALL:\n\t\tif (errno) rb_sys_fail(0);\n\t    default:\n\t\tossl_raise(eSSLError, \"SSL_write:\");\n\t    }\n        }\n    }\n    else {\n        ID id_syswrite = rb_intern(\"syswrite\");\n        rb_warning(\"SSL session is not started yet.\");\n\treturn rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str);\n    }\n\n  end:\n    return INT2NUM(nwrite);\n}\n\n/*\n * call-seq:\n *    ssl.sysclose => nil\n */\nstatic VALUE\nossl_ssl_close(VALUE self)\n{\n    SSL *ssl;\n\n    Data_Get_Struct(self, SSL, ssl);\n    ossl_ssl_shutdown(ssl);\n    if (RTEST(ossl_ssl_get_sync_close(self)))\n\trb_funcall(ossl_ssl_get_io(self), rb_intern(\"close\"), 0);\n\n    return Qnil;\n}\n\n/*\n * call-seq:\n *    ssl.cert => cert or nil\n */\nstatic VALUE\nossl_ssl_get_cert(VALUE self)\n{\n    SSL *ssl;\n    X509 *cert = NULL;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n\n    /*\n     * Is this OpenSSL bug? Should add a ref?\n     * TODO: Ask for.\n     */\n    cert = SSL_get_certificate(ssl); /* NO DUPs => DON'T FREE. */\n\n    if (!cert) {\n        return Qnil;\n    }\n    return ossl_x509_new(cert);\n}\n\n/*\n * call-seq:\n *    ssl.peer_cert => cert or nil\n */\nstatic VALUE\nossl_ssl_get_peer_cert(VALUE self)\n{\n    SSL *ssl;\n    X509 *cert = NULL;\n    VALUE obj;\n\n    Data_Get_Struct(self, SSL, ssl);\n\n    if (!ssl){\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n\n    cert = SSL_get_peer_certificate(ssl); /* Adds a ref => Safe to FREE. */\n\n    if (!cert) {\n        return Qnil;\n    }\n    obj = ossl_x509_new(cert);\n    X509_free(cert);\n\n    return obj;\n}\n\n/*\n * call-seq:\n *    ssl.peer_cert_chain => [cert, ...] or nil\n */\nstatic VALUE\nossl_ssl_get_peer_cert_chain(VALUE self)\n{\n    SSL *ssl;\n    STACK_OF(X509) *chain;\n    X509 *cert;\n    VALUE ary;\n    int i, num;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if(!ssl){\n\trb_warning(\"SSL session is not started yet.\");\n\treturn Qnil;\n    }\n    chain = SSL_get_peer_cert_chain(ssl);\n    if(!chain) return Qnil;\n    num = sk_X509_num(chain);\n    ary = rb_ary_new2(num);\n    for (i = 0; i < num; i++){\n\tcert = (X509*)sk_X509_value(chain, i);\n\trb_ary_push(ary, ossl_x509_new(cert));\n    }\n\n    return ary;\n}\n\n/*\n * call-seq:\n *    ssl.cipher => [name, version, bits, alg_bits]\n */\nstatic VALUE\nossl_ssl_get_cipher(VALUE self)\n{\n    SSL *ssl;\n    OSSL_MORE_CONST SSL_CIPHER *cipher;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (!ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n    cipher = SSL_get_current_cipher(ssl);\n\n    return ossl_ssl_cipher_to_ary(cipher);\n}\n\n/*\n * call-seq:\n *    ssl.state => string\n */\nstatic VALUE\nossl_ssl_get_state(VALUE self)\n{\n    SSL *ssl;\n    VALUE ret;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (!ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n    ret = rb_str_new2(SSL_state_string(ssl));\n    if (ruby_verbose) {\n        rb_str_cat2(ret, \": \");\n        rb_str_cat2(ret, SSL_state_string_long(ssl));\n    }\n    return ret;\n}\n\n/*\n * call-seq:\n *    ssl.pending => integer\n */\nstatic VALUE\nossl_ssl_pending(VALUE self)\n{\n    SSL *ssl;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (!ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n\n    return INT2NUM(SSL_pending(ssl));\n}\n\n/*\n *  call-seq:\n *     ssl.session_reused? -> true | false\n *\n */\nstatic VALUE\nossl_ssl_session_reused(VALUE self)\n{\n    SSL *ssl;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (!ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n\n    switch(SSL_session_reused(ssl)) {\n    case 1:\treturn Qtrue;\n    case 0:\treturn Qfalse;\n    default:\tossl_raise(eSSLError, \"SSL_session_reused\");\n    }\n}\n\n/*\n *  call-seq:\n *     ssl.session = session -> session\n *\n */\nstatic VALUE\nossl_ssl_set_session(VALUE self, VALUE arg1)\n{\n    SSL *ssl;\n    SSL_SESSION *sess;\n\n/* why is ossl_ssl_setup delayed? */\n    ossl_ssl_setup(self);\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (!ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n\n    SafeGetSSLSession(arg1, sess);\n\n    if (SSL_set_session(ssl, sess) != 1)\n        ossl_raise(eSSLError, \"SSL_set_session\");\n\n    return arg1;\n}\n\nstatic VALUE\nossl_ssl_get_verify_result(VALUE self)\n{\n    SSL *ssl;\n\n    Data_Get_Struct(self, SSL, ssl);\n    if (!ssl) {\n        rb_warning(\"SSL session is not started yet.\");\n        return Qnil;\n    }\n\n    return INT2FIX(SSL_get_verify_result(ssl));\n}\n\nvoid\nInit_ossl_ssl()\n{\n    int i;\n    VALUE ary;\n\n#if 0 /* let rdoc know about mOSSL */\n    mOSSL = rb_define_module(\"OpenSSL\");\n#endif\n\n    ID_callback_state = rb_intern(\"@callback_state\");\n\n    ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,\"ossl_ssl_ex_vcb_idx\",0,0,0);\n    ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,\"ossl_ssl_ex_store_p\",0,0,0);\n    ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,\"ossl_ssl_ex_ptr_idx\",0,0,0);\n    ossl_ssl_ex_client_cert_cb_idx =\n\tSSL_get_ex_new_index(0,\"ossl_ssl_ex_client_cert_cb_idx\",0,0,0);\n    ossl_ssl_ex_tmp_dh_callback_idx =\n\tSSL_get_ex_new_index(0,\"ossl_ssl_ex_tmp_dh_callback_idx\",0,0,0);\n\n    mSSL = rb_define_module_under(mOSSL, \"SSL\");\n    eSSLError = rb_define_class_under(mSSL, \"SSLError\", eOSSLError);\n\n    Init_ossl_ssl_session();\n\n    /* class SSLContext\n     *\n     * The following attributes are available but don't show up in rdoc.\n     * All attributes must be set before calling SSLSocket.new(io, ctx).\n     * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout,\n     * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback,\n     * * session_id_context, session_add_cb, session_new_cb, session_remove_cb\n     */\n    cSSLContext = rb_define_class_under(mSSL, \"SSLContext\", rb_cObject);\n    rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);\n    for(i = 0; i < numberof(ossl_sslctx_attrs); i++)\n        rb_attr(cSSLContext, rb_intern(ossl_sslctx_attrs[i]), 1, 1, Qfalse);\n    rb_define_alias(cSSLContext, \"ssl_timeout\", \"timeout\");\n    rb_define_method(cSSLContext, \"initialize\",  ossl_sslctx_initialize, -1);\n    rb_define_method(cSSLContext, \"ssl_version=\", ossl_sslctx_set_ssl_version, 1);\n    rb_define_method(cSSLContext, \"ciphers\",     ossl_sslctx_get_ciphers, 0);\n    rb_define_method(cSSLContext, \"ciphers=\",    ossl_sslctx_set_ciphers, 1);\n\n    rb_define_method(cSSLContext, \"setup\", ossl_sslctx_setup, 0);\n\n    \n    rb_define_const(cSSLContext, \"SESSION_CACHE_OFF\", LONG2FIX(SSL_SESS_CACHE_OFF));\n    rb_define_const(cSSLContext, \"SESSION_CACHE_CLIENT\", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */\n    rb_define_const(cSSLContext, \"SESSION_CACHE_SERVER\", LONG2FIX(SSL_SESS_CACHE_SERVER));\n    rb_define_const(cSSLContext, \"SESSION_CACHE_BOTH\", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */\n    rb_define_const(cSSLContext, \"SESSION_CACHE_NO_AUTO_CLEAR\", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR));\n    rb_define_const(cSSLContext, \"SESSION_CACHE_NO_INTERNAL_LOOKUP\", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));\n    rb_define_const(cSSLContext, \"SESSION_CACHE_NO_INTERNAL_STORE\", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE));\n    rb_define_const(cSSLContext, \"SESSION_CACHE_NO_INTERNAL\", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL));\n    rb_define_method(cSSLContext, \"session_add\",     ossl_sslctx_session_add, 1);\n    rb_define_method(cSSLContext, \"session_remove\",     ossl_sslctx_session_remove, 1);\n    rb_define_method(cSSLContext, \"session_cache_mode\",     ossl_sslctx_get_session_cache_mode, 0);\n    rb_define_method(cSSLContext, \"session_cache_mode=\",     ossl_sslctx_set_session_cache_mode, 1);\n    rb_define_method(cSSLContext, \"session_cache_size\",     ossl_sslctx_get_session_cache_size, 0);\n    rb_define_method(cSSLContext, \"session_cache_size=\",     ossl_sslctx_set_session_cache_size, 1);\n    rb_define_method(cSSLContext, \"session_cache_stats\",     ossl_sslctx_get_session_cache_stats, 0);\n    rb_define_method(cSSLContext, \"flush_sessions\",     ossl_sslctx_flush_sessions, -1);\n\n    ary = rb_ary_new2(numberof(ossl_ssl_method_tab));\n    for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {\n        rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));\n    }\n    rb_obj_freeze(ary);\n    /* holds a list of available SSL/TLS methods */\n    rb_define_const(cSSLContext, \"METHODS\", ary);\n\n    /* class SSLSocket\n     *\n     * The following attributes are available but don't show up in rdoc.\n     * * io, context, sync_close\n     *\n     */\n    cSSLSocket = rb_define_class_under(mSSL, \"SSLSocket\", rb_cObject);\n    rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);\n    for(i = 0; i < numberof(ossl_ssl_attr_readers); i++)\n        rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse);\n    for(i = 0; i < numberof(ossl_ssl_attrs); i++)\n        rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse);\n    rb_define_alias(cSSLSocket, \"to_io\", \"io\");\n    rb_define_method(cSSLSocket, \"initialize\", ossl_ssl_initialize, -1);\n    rb_define_method(cSSLSocket, \"connect\",    ossl_ssl_connect, 0);\n    rb_define_method(cSSLSocket, \"accept\",     ossl_ssl_accept, 0);\n    rb_define_method(cSSLSocket, \"sysread\",    ossl_ssl_read, -1);\n    rb_define_method(cSSLSocket, \"syswrite\",   ossl_ssl_write, 1);\n    rb_define_method(cSSLSocket, \"sysclose\",   ossl_ssl_close, 0);\n    rb_define_method(cSSLSocket, \"cert\",       ossl_ssl_get_cert, 0);\n    rb_define_method(cSSLSocket, \"peer_cert\",  ossl_ssl_get_peer_cert, 0);\n    rb_define_method(cSSLSocket, \"peer_cert_chain\", ossl_ssl_get_peer_cert_chain, 0);\n    rb_define_method(cSSLSocket, \"cipher\",     ossl_ssl_get_cipher, 0);\n    rb_define_method(cSSLSocket, \"state\",      ossl_ssl_get_state, 0);\n    rb_define_method(cSSLSocket, \"pending\",    ossl_ssl_pending, 0);\n    rb_define_method(cSSLSocket, \"session_reused?\",    ossl_ssl_session_reused, 0);\n    rb_define_method(cSSLSocket, \"session=\",    ossl_ssl_set_session, 1);\n    rb_define_method(cSSLSocket, \"verify_result\", ossl_ssl_get_verify_result, 0);\n\n#define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2FIX(SSL_##x))\n\n    ossl_ssl_def_const(VERIFY_NONE);\n    ossl_ssl_def_const(VERIFY_PEER);\n    ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);\n    ossl_ssl_def_const(VERIFY_CLIENT_ONCE);\n    /* Not introduce constants included in OP_ALL such as...\n     * ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);\n     * ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);\n     * ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);\n     * ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);\n     * ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);\n     * ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);\n     * ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);\n     * ossl_ssl_def_const(OP_TLS_D5_BUG);\n     * ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);\n     * ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);\n     */\n    ossl_ssl_def_const(OP_ALL);\n#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)\n    ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);\n#endif\n#if defined(SSL_OP_SINGLE_ECDH_USE)\n    ossl_ssl_def_const(OP_SINGLE_ECDH_USE);\n#endif\n    ossl_ssl_def_const(OP_SINGLE_DH_USE);\n    ossl_ssl_def_const(OP_EPHEMERAL_RSA);\n#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)\n    ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);\n#endif\n    ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);\n    ossl_ssl_def_const(OP_NO_SSLv2);\n    ossl_ssl_def_const(OP_NO_SSLv3);\n    ossl_ssl_def_const(OP_NO_TLSv1);\n#if defined(SSL_OP_NO_TICKET)\n    ossl_ssl_def_const(OP_NO_TICKET);\n#endif\n    ossl_ssl_def_const(OP_PKCS1_CHECK_1);\n    ossl_ssl_def_const(OP_PKCS1_CHECK_2);\n    ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);\n    ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_ssl.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_SSL_H_)\n#define _OSSL_SSL_H_\n\n#define GetSSLSession(obj, sess) do { \\\n\tData_Get_Struct(obj, SSL_SESSION, sess); \\\n\tif (!sess) { \\\n\t\tossl_raise(rb_eRuntimeError, \"SSL Session wasn't initialized.\"); \\\n\t} \\\n} while (0)\n\n#define SafeGetSSLSession(obj, sess) do { \\\n\tOSSL_Check_Kind(obj, cSSLSession); \\\n\tGetSSLSession(obj, sess); \\\n} while (0)\n        \nextern VALUE mSSL;\nextern VALUE eSSLError;\nextern VALUE cSSLSocket;\nextern VALUE cSSLContext;\nextern VALUE cSSLSession;\n\nvoid Init_ossl_ssl(void);\nvoid Init_ossl_ssl_session(void);\n\n#endif /* _OSSL_SSL_H_ */\n\n"
  },
  {
    "path": "ext/openssl/ossl_ssl_session.c",
    "content": "/*\n *  Copyright (C) 2004-2007 Technorama Ltd. <oss-ruby@technorama.net>\n */\n\n#include \"ossl.h\"\n\n#define GetSSLSession(obj, sess) do { \\\n\tData_Get_Struct(obj, SSL_SESSION, sess); \\\n\tif (!sess) { \\\n\t\tossl_raise(rb_eRuntimeError, \"SSL Session wasn't initialized.\"); \\\n\t} \\\n} while (0)\n\n#define SafeGetSSLSession(obj, sess) do { \\\n\tOSSL_Check_Kind(obj, cSSLSession); \\\n\tGetSSLSession(obj, sess); \\\n} while (0)\n        \n\nVALUE cSSLSession;\nstatic VALUE eSSLSession;\n\nstatic VALUE ossl_ssl_session_alloc(VALUE klass)\n{\n\treturn Data_Wrap_Struct(klass, 0, SSL_SESSION_free, NULL);\n}\n\n/*\n * call-seq:\n *    Session.new(SSLSocket | string) => session\n *\n * === Parameters\n * +SSLSocket+ is an OpenSSL::SSL::SSLSocket\n * +string+ must be a DER or PEM encoded Session.\n*/\nstatic VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)\n{\n\tSSL_SESSION *ctx = NULL;\n\tVALUE obj;\n\tunsigned char *p;\n\n\tif (RDATA(self)->data)\n\t\tossl_raise(eSSLSession, \"SSL Session already initialized\");\n\n\tif (rb_obj_is_instance_of(arg1, cSSLSocket)) {\n\t\tSSL *ssl;\n\n\t\tData_Get_Struct(arg1, SSL, ssl);\n\n\t\tif (!ssl || (ctx = SSL_get1_session(ssl)) == NULL)\n\t\t\tossl_raise(eSSLSession, \"no session available\");\n\t} else {\n\t\tBIO *in = ossl_obj2bio(arg1);\n\n\t\tctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);\n\n\t\tif (!ctx) {\n\t\t\tBIO_reset(in);\n\t\t\tctx = d2i_SSL_SESSION_bio(in, NULL);\n\t\t}\n\n\t\tBIO_free(in);\n\n\t\tif (!ctx)\n\t\t\tossl_raise(rb_eArgError, \"unknown type\");\n\t}\n\n\t/* should not happen */\n\tif (ctx == NULL)\n\t\tossl_raise(eSSLSession, \"ctx not set - internal error\");\n\n\tRDATA(self)->data = ctx;\n\n\treturn self;\n}\n\n/*\n * call-seq:\n *    session1 == session2 -> boolean\n *\n*/\nstatic VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)\n{\n\tSSL_SESSION *ctx1, *ctx2;\n\n\tGetSSLSession(val1, ctx1);\n\tSafeGetSSLSession(val2, ctx2);\n\n\tswitch (SSL_SESSION_cmp(ctx1, ctx2)) {\n\tcase 0:\t\treturn Qtrue;\n\tdefault:\treturn Qfalse;\n\t}\n}\n\n/*\n * call-seq:\n *    session.time -> Time\n *\n*/\nstatic VALUE ossl_ssl_session_get_time(VALUE self)\n{\n\tSSL_SESSION *ctx;\n\ttime_t t;\n\n\tGetSSLSession(self, ctx);\n\n\tt = SSL_SESSION_get_time(ctx);\n\n\tif (t == 0)\n\t\treturn Qnil;\n\n\treturn rb_funcall(rb_cTime, rb_intern(\"at\"), 1, LONG2NUM(t));\n}\n\n/*\n * call-seq:\n *    session.timeout -> integer\n *\n * How long until the session expires in seconds.\n *\n*/\nstatic VALUE ossl_ssl_session_get_timeout(VALUE self)\n{\n\tSSL_SESSION *ctx;\n\ttime_t t;\n\n\tGetSSLSession(self, ctx);\n\n\tt = SSL_SESSION_get_timeout(ctx);\n\n\treturn ULONG2NUM(t);\n}\n\n#define SSLSESSION_SET_TIME(func)\t\t\t\t\t\t\\\n\tstatic VALUE ossl_ssl_session_set_##func(VALUE self, VALUE time_v)\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tSSL_SESSION *ctx;\t\t\t\t\t\t\\\n\t\ttime_t t;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tGetSSLSession(self, ctx);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (rb_obj_is_instance_of(time_v, rb_cTime)) {\t\t\t\\\n\t\t\ttime_v = rb_funcall(time_v, rb_intern(\"to_i\"), 0);\t\\\n\t\t} else if (FIXNUM_P(time_v)) {\t\t\t\t\t\\\n\t\t\t;\t\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\t\\\n\t\t\trb_raise(rb_eArgError, \"unknown type\");\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tt = NUM2ULONG(time_v);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tSSL_SESSION_set_##func(ctx, t);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn ossl_ssl_session_get_##func(self);\t\t\t\\\n\t}\n\nSSLSESSION_SET_TIME(time)\nSSLSESSION_SET_TIME(timeout)\n\n#ifdef HAVE_SSL_SESSION_GET_ID\n/*\n * call-seq:\n *    session.id -> aString\n *\n * Returns the Session ID.\n*/\nstatic VALUE ossl_ssl_session_get_id(VALUE self)\n{\n\tSSL_SESSION *ctx;\n\tconst unsigned char *p = NULL;\n\tunsigned int i = 0;\n\n\tGetSSLSession(self, ctx);\n\n\tp = SSL_SESSION_get_id(ctx, &i);\n\n\treturn rb_str_new((const char *) p, i);\n}\n#endif\n\n/*\n * call-seq:\n *    session.to_der -> aString\n *\n * Returns an ASN1 encoded String that contains the Session object.\n*/\nstatic VALUE ossl_ssl_session_to_der(VALUE self)\n{\n\tSSL_SESSION *ctx;\n\tunsigned char buf[1024*10], *p;\n\tint len;\n\n\tGetSSLSession(self, ctx);\n\n\tp = buf;\n\tlen = i2d_SSL_SESSION(ctx, &p);\n\n\tif (len <= 0)\n\t\tossl_raise(eSSLSession, \"i2d_SSL_SESSION\");\n\telse if (len >= sizeof(buf))\n\t\tossl_raise(eSSLSession, \"i2d_SSL_SESSION too large\");\n\n\treturn rb_str_new((const char *) p, len);\n}\n\n/*\n * call-seq:\n *    session.to_pem -> String\n *\n * Returns a PEM encoded String that contains the Session object.\n*/\nstatic VALUE ossl_ssl_session_to_pem(VALUE self)\n{\n\tSSL_SESSION *ctx;\n\tBIO *out;\n\tBUF_MEM *buf;\n\tVALUE str;\n\tint i;\n         \n\tGetSSLSession(self, ctx);\n\n\tif (!(out = BIO_new(BIO_s_mem()))) {\n\t\tossl_raise(eSSLSession, \"BIO_s_mem()\");\n\t}\n\n\tif (!(i=PEM_write_bio_SSL_SESSION(out, ctx))) {\n\t\tBIO_free(out);\n\t\tossl_raise(eSSLSession, \"SSL_SESSION_print()\");\n\t}\n\n\tBIO_get_mem_ptr(out, &buf);\n\tstr = rb_str_new(buf->data, buf->length);\n\tBIO_free(out);\n\n\treturn str;\n}\n\n\n/*\n * call-seq:\n *    session.to_text -> String\n *\n * Shows everything in the Session object.\n*/\nstatic VALUE ossl_ssl_session_to_text(VALUE self)\n{\n\tSSL_SESSION *ctx;\n\tBIO *out;\n\tBUF_MEM *buf;\n\tVALUE str;\n         \n\tGetSSLSession(self, ctx);\n\n\tif (!(out = BIO_new(BIO_s_mem()))) {\n\t\tossl_raise(eSSLSession, \"BIO_s_mem()\");\n\t}\n\n\tif (!SSL_SESSION_print(out, ctx)) {\n\t\tBIO_free(out);\n\t\tossl_raise(eSSLSession, \"SSL_SESSION_print()\");\n\t}\n\n\tBIO_get_mem_ptr(out, &buf);\n\tstr = rb_str_new(buf->data, buf->length);\n\tBIO_free(out);\n\n\treturn str;\n}\n                                                     \n\nvoid Init_ossl_ssl_session(void)\n{\n#if 0 /* let rdoc know about mOSSL */\n\tmOSSL = rb_define_module(\"OpenSSL\");\n\tmSSL = rb_define_module_under(mOSSL, \"SSL\");\n#endif\n\tcSSLSession = rb_define_class_under(mSSL, \"Session\", rb_cObject);\n\teSSLSession = rb_define_class_under(cSSLSession, \"SessionError\", eOSSLError);\n\n\trb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc);\n\trb_define_method(cSSLSession, \"initialize\", ossl_ssl_session_initialize, 1);\n\n\trb_define_method(cSSLSession, \"==\", ossl_ssl_session_eq, 1);\n\n\trb_define_method(cSSLSession, \"time\", ossl_ssl_session_get_time, 0);\n\trb_define_method(cSSLSession, \"time=\", ossl_ssl_session_set_time, 1);\n\trb_define_method(cSSLSession, \"timeout\", ossl_ssl_session_get_timeout, 0);\n\trb_define_method(cSSLSession, \"timeout=\", ossl_ssl_session_set_timeout, 1);\n\n#ifdef HAVE_SSL_SESSION_GET_ID\n\trb_define_method(cSSLSession, \"id\", ossl_ssl_session_get_id, 0);\n#else\n\trb_undef_method(cSSLSession, \"id\");\n#endif\n\trb_define_method(cSSLSession, \"to_der\", ossl_ssl_session_to_der, 0);\n\trb_define_method(cSSLSession, \"to_pem\", ossl_ssl_session_to_pem, 0);\n\trb_define_method(cSSLSession, \"to_text\", ossl_ssl_session_to_text, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_version.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_VERSION_H_)\n#define _OSSL_VERSION_H_\n\n#define OSSL_VERSION \"1.0.0\"\n\n#endif /* _OSSL_VERSION_H_ */\n"
  },
  {
    "path": "ext/openssl/ossl_x509.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\nVALUE mX509;\n\n#define DefX509Const(x) rb_define_const(mX509, #x,INT2FIX(X509_##x))\n#define DefX509Default(x,i) \\\n  rb_define_const(mX509, \"DEFAULT_\" #x, rb_str_new2(X509_get_default_##i()))\n\nvoid\nInit_ossl_x509()\n{\n    mX509 = rb_define_module_under(mOSSL, \"X509\");\n\n    Init_ossl_x509attr();\n    Init_ossl_x509cert();\n    Init_ossl_x509crl();\n    Init_ossl_x509ext();\n    Init_ossl_x509name();\n    Init_ossl_x509req();\n    Init_ossl_x509revoked();\n    Init_ossl_x509store();\n\n    DefX509Const(V_OK);\n    DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT);\n    DefX509Const(V_ERR_UNABLE_TO_GET_CRL);\n    DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);\n    DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE);\n    DefX509Const(V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);\n    DefX509Const(V_ERR_CERT_SIGNATURE_FAILURE);\n    DefX509Const(V_ERR_CRL_SIGNATURE_FAILURE);\n    DefX509Const(V_ERR_CERT_NOT_YET_VALID);\n    DefX509Const(V_ERR_CERT_HAS_EXPIRED);\n    DefX509Const(V_ERR_CRL_NOT_YET_VALID);\n    DefX509Const(V_ERR_CRL_HAS_EXPIRED);\n    DefX509Const(V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD);\n    DefX509Const(V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD);\n    DefX509Const(V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD);\n    DefX509Const(V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);\n    DefX509Const(V_ERR_OUT_OF_MEM);\n    DefX509Const(V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);\n    DefX509Const(V_ERR_SELF_SIGNED_CERT_IN_CHAIN);\n    DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);\n    DefX509Const(V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);\n    DefX509Const(V_ERR_CERT_CHAIN_TOO_LONG);\n    DefX509Const(V_ERR_CERT_REVOKED);\n    DefX509Const(V_ERR_INVALID_CA);\n    DefX509Const(V_ERR_PATH_LENGTH_EXCEEDED);\n    DefX509Const(V_ERR_INVALID_PURPOSE);\n    DefX509Const(V_ERR_CERT_UNTRUSTED);\n    DefX509Const(V_ERR_CERT_REJECTED);\n    DefX509Const(V_ERR_SUBJECT_ISSUER_MISMATCH);\n    DefX509Const(V_ERR_AKID_SKID_MISMATCH);\n    DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH);\n    DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN);\n    DefX509Const(V_ERR_APPLICATION_VERIFICATION);\n\n#if defined(X509_V_FLAG_CRL_CHECK)\n    DefX509Const(V_FLAG_CRL_CHECK);\n#endif\n#if defined(X509_V_FLAG_CRL_CHECK_ALL)\n    DefX509Const(V_FLAG_CRL_CHECK_ALL);\n#endif\n\n    DefX509Const(PURPOSE_SSL_CLIENT);\n    DefX509Const(PURPOSE_SSL_SERVER);\n    DefX509Const(PURPOSE_NS_SSL_SERVER);\n    DefX509Const(PURPOSE_SMIME_SIGN);\n    DefX509Const(PURPOSE_SMIME_ENCRYPT);\n    DefX509Const(PURPOSE_CRL_SIGN);\n    DefX509Const(PURPOSE_ANY);\n#if defined(X509_PURPOSE_OCSP_HELPER)\n    DefX509Const(PURPOSE_OCSP_HELPER);\n#endif\n\n    DefX509Const(TRUST_COMPAT);\n    DefX509Const(TRUST_SSL_CLIENT);\n    DefX509Const(TRUST_SSL_SERVER);\n    DefX509Const(TRUST_EMAIL);\n    DefX509Const(TRUST_OBJECT_SIGN);\n#if defined(X509_TRUST_OCSP_SIGN)\n    DefX509Const(TRUST_OCSP_SIGN);\n#endif\n#if defined(X509_TRUST_OCSP_REQUEST)\n    DefX509Const(TRUST_OCSP_REQUEST);\n#endif\n\n    DefX509Default(CERT_AREA, cert_area);\n    DefX509Default(CERT_DIR, cert_dir);\n    DefX509Default(CERT_FILE, cert_file);\n    DefX509Default(CERT_DIR_ENV, cert_dir_env);\n    DefX509Default(CERT_FILE_ENV, cert_file_env);\n    DefX509Default(PRIVATE_DIR, private_dir);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_x509.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_X509_H_)\n#define _OSSL_X509_H_\n\n/*\n * X509 main module\n */\nextern VALUE mX509;\n\nvoid Init_ossl_x509(void);\n\n/*\n * X509Attr\n */\nextern VALUE cX509Attr;\nextern VALUE eX509AttrError;\n\nVALUE ossl_x509attr_new(X509_ATTRIBUTE *);\nX509_ATTRIBUTE *DupX509AttrPtr(VALUE);\nvoid Init_ossl_x509attr(void);\n\n/*\n * X509Cert\n */\nextern VALUE cX509Cert;\nextern VALUE eX509CertError;\n\nVALUE ossl_x509_new(X509 *);\nVALUE ossl_x509_new_from_file(VALUE);\nX509 *GetX509CertPtr(VALUE);\nX509 *DupX509CertPtr(VALUE);\nvoid Init_ossl_x509cert(void);\n\n/*\n * X509CRL\n */\nextern VALUE cX509CRL;\nextern VALUE eX509CRLError;\n\nVALUE ossl_x509crl_new(X509_CRL *);\nX509_CRL *GetX509CRLPtr(VALUE);\nX509_CRL *DupX509CRLPtr(VALUE);\nvoid Init_ossl_x509crl(void);\n\n/*\n * X509Extension\n */\nextern VALUE cX509Ext;\nextern VALUE cX509ExtFactory;\nextern VALUE eX509ExtError;\n\nVALUE ossl_x509ext_new(X509_EXTENSION *);\nX509_EXTENSION *GetX509ExtPtr(VALUE);\nX509_EXTENSION *DupX509ExtPtr(VALUE);\nvoid Init_ossl_x509ext(void);\n\n/*\n * X509Name\n */\nextern VALUE cX509Name;\nextern VALUE eX509NameError;\n\nVALUE ossl_x509name_new(X509_NAME *);\nX509_NAME *GetX509NamePtr(VALUE);\nvoid Init_ossl_x509name(void);\n\n/*\n * X509Request\n */\nextern VALUE cX509Req;\nextern VALUE eX509ReqError;\n\nVALUE ossl_x509req_new(X509_REQ *);\nX509_REQ *GetX509ReqPtr(VALUE);\nX509_REQ *DupX509ReqPtr(VALUE);\nvoid Init_ossl_x509req(void);\n\n/*\n * X509Revoked\n */\nextern VALUE cX509Rev;\nextern VALUE eX509RevError;\n\nVALUE ossl_x509revoked_new(X509_REVOKED *);\nX509_REVOKED *DupX509RevokedPtr(VALUE);\nvoid Init_ossl_x509revoked(void);\n\n/*\n * X509Store and X509StoreContext\n */\nextern VALUE cX509Store;\nextern VALUE cX509StoreContext;\nextern VALUE eX509StoreError;\n\nVALUE ossl_x509store_new(X509_STORE *);\nX509_STORE *GetX509StorePtr(VALUE);\nX509_STORE *DupX509StorePtr(VALUE);\n\nVALUE ossl_x509stctx_new(X509_STORE_CTX *);\nVALUE ossl_x509stctx_clear_ptr(VALUE);\nX509_STORE_CTX *GetX509StCtxtPtr(VALUE);\n\nvoid Init_ossl_x509store(void);\n\n#endif /* _OSSL_X509_H_ */\n"
  },
  {
    "path": "ext/openssl/ossl_x509attr.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509Attr(klass, obj, attr) do { \\\n    if (!attr) { \\\n\tossl_raise(rb_eRuntimeError, \"ATTR wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_ATTRIBUTE_free, attr); \\\n} while (0)\n#define GetX509Attr(obj, attr) do { \\\n    Data_Get_Struct(obj, X509_ATTRIBUTE, attr); \\\n    if (!attr) { \\\n\tossl_raise(rb_eRuntimeError, \"ATTR wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509Attr(obj, attr) do { \\\n    OSSL_Check_Kind(obj, cX509Attr); \\\n    GetX509Attr(obj, attr); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509Attr;\nVALUE eX509AttrError;\n\n/*\n * Public\n */\nVALUE\nossl_x509attr_new(X509_ATTRIBUTE *attr)\n{\n    X509_ATTRIBUTE *new;\n    VALUE obj;\n    \n    if (!attr) {\n\tnew = X509_ATTRIBUTE_new();\n    } else {\n\tnew = X509_ATTRIBUTE_dup(attr);\n    }\n    if (!new) {\n\tossl_raise(eX509AttrError, NULL);\n    }\n    WrapX509Attr(cX509Attr, obj, new);\n\n    return obj;\n}\n\nX509_ATTRIBUTE *\nDupX509AttrPtr(VALUE obj)\n{\n    X509_ATTRIBUTE *attr, *new;\n\n    SafeGetX509Attr(obj, attr);\n    if (!(new = X509_ATTRIBUTE_dup(attr))) {\n\tossl_raise(eX509AttrError, NULL);\n    }\n\n    return new;\n}\n\n/*\n * Private\n */\nstatic VALUE\nossl_x509attr_alloc(VALUE klass)\n{\n    X509_ATTRIBUTE *attr;\n    VALUE obj;\n\n    if (!(attr = X509_ATTRIBUTE_new())) \n\tossl_raise(eX509AttrError, NULL);\n    WrapX509Attr(klass, obj, attr);\n\n    return obj;\n}\n\n/*\n * call-seq:\n *    Attribute.new(oid [, value]) => attr\n */\nstatic VALUE\nossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE oid, value;\n    X509_ATTRIBUTE *attr;\n    OSSL_MORE_CONST unsigned char *p;\n\n    GetX509Attr(self, attr);\n    if(rb_scan_args(argc, argv, \"11\", &oid, &value) == 1){\n\toid = ossl_to_der_if_possible(oid);\n\tStringValue(oid);\n\tp = RSTRING_PTR(oid);\n\tif(!d2i_X509_ATTRIBUTE((X509_ATTRIBUTE**)&DATA_PTR(self),\n\t\t\t       &p, RSTRING_LEN(oid))){\n\t    ossl_raise(eX509AttrError, NULL);\n\t}\n\treturn self;\n    }\n    rb_funcall(self, rb_intern(\"oid=\"), 1, oid);\n    rb_funcall(self, rb_intern(\"value=\"), 1, value);\n\n    return self;\n}\n\n/*\n * call-seq:\n *    attr.oid = string => string\n */\nstatic VALUE\nossl_x509attr_set_oid(VALUE self, VALUE oid)\n{\n    X509_ATTRIBUTE *attr;\n    ASN1_OBJECT *obj;\n    char *s;\n \n    s = StringValuePtr(oid);\n    obj = OBJ_txt2obj(s, 0);\n    if(!obj) obj = OBJ_txt2obj(s, 1);\n    if(!obj) ossl_raise(eX509AttrError, NULL);\n    GetX509Attr(self, attr);\n    X509_ATTRIBUTE_set1_object(attr, obj);\n \n    return oid;\n}\n\n/*\n * call-seq:\n *    attr.oid => string\n */\nstatic VALUE\nossl_x509attr_get_oid(VALUE self)\n{\n    X509_ATTRIBUTE *attr;\n    ASN1_OBJECT *oid;\n    BIO *out;\n    VALUE ret;\n    int nid;\n\n    GetX509Attr(self, attr);\n    oid = X509_ATTRIBUTE_get0_object(attr);\n    if ((nid = OBJ_obj2nid(oid)) != NID_undef)\n\tret = rb_str_new2(OBJ_nid2sn(nid));\n    else{\n\tif (!(out = BIO_new(BIO_s_mem())))\n\t    ossl_raise(eX509AttrError, NULL);\n\ti2a_ASN1_OBJECT(out, oid);\n\tret = ossl_membio2str(out);\n    }\n  \n    return ret;\n}\n\n#if defined(HAVE_ST_X509_ATTRIBUTE_SINGLE) || defined(HAVE_ST_SINGLE)\n#  define OSSL_X509ATTR_IS_SINGLE(attr)  ((attr)->single)\n#  define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->single = 1)\n#else\n#  define OSSL_X509ATTR_IS_SINGLE(attr)  (!(attr)->set)\n#  define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->set = 0)\n#endif\n\n/*\n * call-seq:\n *    attr.value = asn1 => asn1\n */\nstatic VALUE\nossl_x509attr_set_value(VALUE self, VALUE value)\n{\n    X509_ATTRIBUTE *attr;\n    ASN1_TYPE *a1type;\n\n    if(!(a1type = ossl_asn1_get_asn1type(value)))\n\tossl_raise(eASN1Error, \"could not get ASN1_TYPE\");\n    if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){\n\tASN1_TYPE_free(a1type);\n\tossl_raise(eASN1Error, \"couldn't set SEQUENCE for attribute value.\");\n    }\n    GetX509Attr(self, attr);\n    if(attr->value.set){\n\tif(OSSL_X509ATTR_IS_SINGLE(attr)) ASN1_TYPE_free(attr->value.single);\n\telse sk_ASN1_TYPE_free(attr->value.set);\n    }\n    OSSL_X509ATTR_SET_SINGLE(attr);\n    attr->value.single = a1type;\n\n    return value;\n}\n\n/*\n * call-seq:\n *    attr.value => asn1\n */\nstatic VALUE\nossl_x509attr_get_value(VALUE self)\n{\n    X509_ATTRIBUTE *attr;\n    VALUE str, asn1;\n    long length;\n    unsigned char *p;\n\n    GetX509Attr(self, attr);\n    if(attr->value.ptr == NULL) return Qnil;\n    if(OSSL_X509ATTR_IS_SINGLE(attr)){\n\tlength = i2d_ASN1_TYPE(attr->value.single, NULL);\n\tstr = rb_str_new(0, length);\n\tp = RSTRING_PTR(str);\n\ti2d_ASN1_TYPE(attr->value.single, &p);\n\tossl_str_adjust(str, p);\n    }\n    else{\n\tlength = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set,\n\t\t\t(unsigned char **) NULL, i2d_ASN1_TYPE,\n\t\t\tV_ASN1_SET, V_ASN1_UNIVERSAL, 0);\n\tstr = rb_str_new(0, length);\n\tp = RSTRING_PTR(str);\n\ti2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,\n\t\t\ti2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);\n\tossl_str_adjust(str, p);\n    }\n    asn1 = rb_funcall(mASN1, rb_intern(\"decode\"), 1, str);\n\n    return asn1;\n}\n\n/*\n * call-seq:\n *    attr.to_der => string\n */\nstatic VALUE\nossl_x509attr_to_der(VALUE self)\n{\n    X509_ATTRIBUTE *attr;\n    VALUE str;\n    int len;\n    unsigned char *p;\n\n    GetX509Attr(self, attr);\n    if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)\n\tossl_raise(eX509AttrError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)\n\tossl_raise(eX509AttrError, NULL);\n    rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str)); \n\n    return str;\n}\n\n/*\n * X509_ATTRIBUTE init\n */\nvoid\nInit_ossl_x509attr()\n{\n    eX509AttrError = rb_define_class_under(mX509, \"AttributeError\", eOSSLError);\n\n    cX509Attr = rb_define_class_under(mX509, \"Attribute\", rb_cObject);\n    rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc);\n    rb_define_method(cX509Attr, \"initialize\", ossl_x509attr_initialize, -1);\n    rb_define_method(cX509Attr, \"oid=\", ossl_x509attr_set_oid, 1);\n    rb_define_method(cX509Attr, \"oid\", ossl_x509attr_get_oid, 0);\n    rb_define_method(cX509Attr, \"value=\", ossl_x509attr_set_value, 1);\n    rb_define_method(cX509Attr, \"value\", ossl_x509attr_get_value, 0);\n    rb_define_method(cX509Attr, \"to_der\", ossl_x509attr_to_der, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_x509cert.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509(klass, obj, x509) do { \\\n    if (!x509) { \\\n\tossl_raise(rb_eRuntimeError, \"CERT wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_free, x509); \\\n} while (0)\n#define GetX509(obj, x509) do { \\\n    Data_Get_Struct(obj, X509, x509); \\\n    if (!x509) { \\\n\tossl_raise(rb_eRuntimeError, \"CERT wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509(obj, x509) do { \\\n    OSSL_Check_Kind(obj, cX509Cert); \\\n    GetX509(obj, x509); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509Cert;\nVALUE eX509CertError;\n\n/*\n * Public\n */\nVALUE\nossl_x509_new(X509 *x509)\n{\n    X509 *new;\n    VALUE obj;\n\n    if (!x509) {\n\tnew = X509_new();\n    } else {\n\tnew = X509_dup(x509);\n    }\n    if (!new) {\n\tossl_raise(eX509CertError, NULL);\n    }\n    WrapX509(cX509Cert, obj, new);\n\t\n    return obj;\n}\n\nVALUE \nossl_x509_new_from_file(VALUE filename)\n{\n    X509 *x509;\n    FILE *fp;\n    VALUE obj;\n\n    SafeStringValue(filename);\n    if (!(fp = fopen(RSTRING_PTR(filename), \"r\"))) {\n\tossl_raise(eX509CertError, \"%s\", strerror(errno));\n    }\n    x509 = PEM_read_X509(fp, NULL, NULL, NULL);\n    /*\n     * prepare for DER...\n#if !defined(OPENSSL_NO_FP_API)\n    if (!x509) {\n\trewind(fp);\n\n\tx509 = d2i_X509_fp(fp, NULL);\n    }\n#endif\n    */\n    fclose(fp);\n    if (!x509) {\n\tossl_raise(eX509CertError, NULL);\n    }\n    WrapX509(cX509Cert, obj, x509);\n\n    return obj;\n}\n\nX509 *\nGetX509CertPtr(VALUE obj)\n{\n    X509 *x509;\n\t\n    SafeGetX509(obj, x509);\n\t\n    return x509;\n}\n\nX509 *\nDupX509CertPtr(VALUE obj)\n{\n    X509 *x509;\n\t\n    SafeGetX509(obj, x509);\n\t\n    CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);\n\t\n    return x509;\n}\n\n/*\n * Private\n */\nstatic VALUE \nossl_x509_alloc(VALUE klass)\n{\n    X509 *x509;\n    VALUE obj;\n\n    x509 = X509_new();\n    if (!x509) ossl_raise(eX509CertError, NULL);\n\n    WrapX509(klass, obj, x509);\n\n    return obj;\n}\n\n/*\n * call-seq:\n *    Certificate.new => cert\n *    Certificate.new(string) => cert\n */\nstatic VALUE \nossl_x509_initialize(int argc, VALUE *argv, VALUE self)\n{\n    BIO *in;\n    X509 *x509;\n    VALUE arg;\n\n    if (rb_scan_args(argc, argv, \"01\", &arg) == 0) {\n\t/* create just empty X509Cert */\n\treturn self;\n    }\n    arg = ossl_to_der_if_possible(arg);\n    in = ossl_obj2bio(arg);\n    x509 = PEM_read_bio_X509(in, (X509 **)&DATA_PTR(self), NULL, NULL);\n    if (!x509) {\n\tBIO_reset(in);\n\tx509 = d2i_X509_bio(in, (X509 **)&DATA_PTR(self));\n    }\n    BIO_free(in);\n    if (!x509) ossl_raise(eX509CertError, NULL);\n    \n    return self;\n}\n\nstatic VALUE\nossl_x509_copy(VALUE self, VALUE other)\n{\n    X509 *a, *b, *x509;\n\t\n    rb_check_frozen(self);\n    if (self == other) return self;\n\n    GetX509(self, a);\n    SafeGetX509(other, b);\n\n    x509 = X509_dup(b);\n    if (!x509) ossl_raise(eX509CertError, NULL);\n    \n    DATA_PTR(self) = x509;\n    X509_free(a);\n\n    return self;\n}\n\n/*\n * call-seq:\n *    cert.to_der => string\n */\nstatic VALUE \nossl_x509_to_der(VALUE self)\n{\n    X509 *x509;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetX509(self, x509);\n    if ((len = i2d_X509(x509, NULL)) <= 0)\n\tossl_raise(eX509CertError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if (i2d_X509(x509, &p) <= 0)\n\tossl_raise(eX509CertError, NULL);\n    ossl_str_adjust(str, p);\n    \n    return str;\n}\n\n/*\n * call-seq:\n *    cert.to_pem => string\n */\nstatic VALUE \nossl_x509_to_pem(VALUE self)\n{\n    X509 *x509;\n    BIO *out;\n    VALUE str;\n\t\n    GetX509(self, x509);\n    out = BIO_new(BIO_s_mem());\n    if (!out) ossl_raise(eX509CertError, NULL);\n\n    if (!PEM_write_bio_X509(out, x509)) {\n\tBIO_free(out);\n\tossl_raise(eX509CertError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n * call-seq:\n *    cert.to_text => string\n */\nstatic VALUE\nossl_x509_to_text(VALUE self)\n{\n    X509 *x509;\n    BIO *out;\n    VALUE str;\n\t\n    GetX509(self, x509);\n\n    out = BIO_new(BIO_s_mem());\n    if (!out) ossl_raise(eX509CertError, NULL);\n\n    if (!X509_print(out, x509)) {\n\tBIO_free(out);\n\tossl_raise(eX509CertError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n#if 0\n/*\n * Makes from X509 X509_REQuest\n */\nstatic VALUE \nossl_x509_to_req(VALUE self)\n{\n    X509 *x509;\n    X509_REQ *req;\n    VALUE obj;\n\n    GetX509(self, x509);\n    if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) {\n\tossl_raise(eX509CertError, NULL);\n    }\n    obj = ossl_x509req_new(req);\n    X509_REQ_free(req);\n\n    return obj;\n}\n#endif\n\n/*\n * call-seq:\n *    cert.version => integer\n */\nstatic VALUE \nossl_x509_get_version(VALUE self)\n{\n    X509 *x509;\n\n    GetX509(self, x509);\n\t\n    return LONG2NUM(X509_get_version(x509));\n}\n\n/*\n * call-seq:\n *    cert.version = integer => integer\n */\nstatic VALUE \nossl_x509_set_version(VALUE self, VALUE version)\n{\n    X509 *x509;\n    long ver;\n\n    if ((ver = NUM2LONG(version)) < 0) {\n\tossl_raise(eX509CertError, \"version must be >= 0!\");\n    }\n    GetX509(self, x509);\n    if (!X509_set_version(x509, ver)) {\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return version;\n}\n\n/*\n * call-seq:\n *    cert.serial => integer\n */\nstatic VALUE \nossl_x509_get_serial(VALUE self)\n{\n    X509 *x509;\n\n    GetX509(self, x509);\n\t\n    return asn1integer_to_num(X509_get_serialNumber(x509));\n}\n\n/*\n * call-seq:\n *    cert.serial = integer => integer\n */\nstatic VALUE \nossl_x509_set_serial(VALUE self, VALUE num)\n{\n    X509 *x509;\n\n    GetX509(self, x509);\n\n    x509->cert_info->serialNumber =\n\tnum_to_asn1integer(num, X509_get_serialNumber(x509));\n\t\n    return num;\n}\n\n/*\n * call-seq:\n *    cert.signature_algorithm => string\n */\nstatic VALUE \nossl_x509_get_signature_algorithm(VALUE self)\n{\n    X509 *x509;\n    BIO *out;\n    VALUE str;\n\n    GetX509(self, x509);\n    out = BIO_new(BIO_s_mem());\n    if (!out) ossl_raise(eX509CertError, NULL);\n\n    if (!i2a_ASN1_OBJECT(out, x509->cert_info->signature->algorithm)) {\n\tBIO_free(out);\n\tossl_raise(eX509CertError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n * call-seq:\n *    cert.subject => name\n */\nstatic VALUE \nossl_x509_get_subject(VALUE self)\n{\n    X509 *x509;\n    X509_NAME *name;\n\t\n    GetX509(self, x509);\n    if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return ossl_x509name_new(name);\n}\n\n/*\n * call-seq:\n *    cert.subject = name => name\n */\nstatic VALUE \nossl_x509_set_subject(VALUE self, VALUE subject)\n{\n    X509 *x509;\n\t\n    GetX509(self, x509);\n    if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return subject;\n}\n\n/*\n * call-seq:\n *    cert.issuer => name\n */\nstatic VALUE \nossl_x509_get_issuer(VALUE self)\n{\n    X509 *x509;\n    X509_NAME *name;\n\n    GetX509(self, x509);\n    if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return ossl_x509name_new(name);\n}\n\n/*\n * call-seq:\n *    cert.issuer = name => name\n */\nstatic VALUE \nossl_x509_set_issuer(VALUE self, VALUE issuer)\n{\n    X509 *x509;\n\n    GetX509(self, x509);\n    if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return issuer;\n}\n\n/*\n * call-seq:\n *    cert.not_before => time\n */\nstatic VALUE \nossl_x509_get_not_before(VALUE self)\n{\n    X509 *x509;\n    ASN1_UTCTIME *asn1time;\n\n    GetX509(self, x509);\n    if (!(asn1time = X509_get_notBefore(x509))) { /* NO DUP - don't free! */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return asn1time_to_time(asn1time);\n}\n\n/*\n * call-seq:\n *    cert.not_before = time => time\n */\nstatic VALUE \nossl_x509_set_not_before(VALUE self, VALUE time)\n{\n    X509 *x509;\n    time_t sec;\n\t\n    sec = time_to_time_t(time);\n    GetX509(self, x509);\n    if (!X509_time_adj(X509_get_notBefore(x509), 0, &sec)) {\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return time;\n}\n\n/*\n * call-seq:\n *    cert.not_after => time\n */\nstatic VALUE \nossl_x509_get_not_after(VALUE self)\n{\n    X509 *x509;\n    ASN1_TIME *asn1time;\n\n    GetX509(self, x509);\n    if (!(asn1time = X509_get_notAfter(x509))) { /* NO DUP - don't free! */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return asn1time_to_time(asn1time);\n}\n\n/*\n * call-seq:\n *    cert.not_before = time => time\n */\nstatic VALUE \nossl_x509_set_not_after(VALUE self, VALUE time)\n{\n    X509 *x509;\n    time_t sec;\n\t\n    sec = time_to_time_t(time);\n    GetX509(self, x509);\n    if (!X509_time_adj(X509_get_notAfter(x509), 0, &sec)) {\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return time;\n}\n\n/*\n * call-seq:\n *    cert.public_key => key\n */\nstatic VALUE \nossl_x509_get_public_key(VALUE self)\n{\n    X509 *x509;\n    EVP_PKEY *pkey;\n\n    GetX509(self, x509);\n    if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return ossl_pkey_new(pkey); /* NO DUP - OK */\n}\n\n/*\n * call-seq:\n *    cert.public_key = key => key\n */\nstatic VALUE \nossl_x509_set_public_key(VALUE self, VALUE key)\n{\n    X509 *x509;\n\n    GetX509(self, x509);\n    if (!X509_set_pubkey(x509, GetPKeyPtr(key))) { /* DUPs pkey */\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return key;\n}\n\n/*\n * call-seq:\n *    cert.sign(key, digest) => self\n */\nstatic VALUE \nossl_x509_sign(VALUE self, VALUE key, VALUE digest)\n{\n    X509 *x509;\n    EVP_PKEY *pkey;\n    const EVP_MD *md;\n\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    md = GetDigestPtr(digest);\n    GetX509(self, x509);\n    if (!X509_sign(x509, pkey, md)) {\n\tossl_raise(eX509CertError, NULL);\n    }\n\n    return self;\n}\n\n/*\n * call-seq:\n *    cert.verify(key) => true | false\n *\n * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'\n */\nstatic VALUE \nossl_x509_verify(VALUE self, VALUE key)\n{\n    X509 *x509;\n    EVP_PKEY *pkey;\n    int i;\n\n    pkey = GetPKeyPtr(key); /* NO NEED TO DUP */\n    GetX509(self, x509);\n    if ((i = X509_verify(x509, pkey)) < 0) {\n\tossl_raise(eX509CertError, NULL);\n    } \n    if (i > 0) {\n\treturn Qtrue;\n    }\n\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *    cert.check_private_key(key)\n *\n * Checks if 'key' is PRIV key for this cert\n */\nstatic VALUE \nossl_x509_check_private_key(VALUE self, VALUE key)\n{\n    X509 *x509;\n    EVP_PKEY *pkey;\n\t\n    /* not needed private key, but should be */\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    GetX509(self, x509);\n    if (!X509_check_private_key(x509, pkey)) {\n\tOSSL_Warning(\"Check private key:%s\", OSSL_ErrMsg());\n\treturn Qfalse;\n    }\n\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    cert.extensions => [extension...]\n */\nstatic VALUE \nossl_x509_get_extensions(VALUE self)\n{\n    X509 *x509;\n    int count, i;\n    X509_EXTENSION *ext;\n    VALUE ary;\n\n    GetX509(self, x509);\n    count = X509_get_ext_count(x509);\n    if (count < 0) {\n\treturn rb_ary_new();\n    }\n    ary = rb_ary_new2(count);\n    for (i=0; i<count; i++) {\n\text = X509_get_ext(x509, i); /* NO DUP - don't free! */\n\trb_ary_push(ary, ossl_x509ext_new(ext));\n    }\n\n    return ary;\n}\n\n/*\n * call-seq:\n *    cert.extensions = [ext...] => [ext...]\n */\nstatic VALUE \nossl_x509_set_extensions(VALUE self, VALUE ary)\n{\n    X509 *x509;\n    X509_EXTENSION *ext;\n    int i;\n\t\n    Check_Type(ary, T_ARRAY);\n    /* All ary's members should be X509Extension */\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\tOSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);\n    }\n    GetX509(self, x509);\n    sk_X509_EXTENSION_pop_free(x509->cert_info->extensions, X509_EXTENSION_free);\n    x509->cert_info->extensions = NULL;\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\text = DupX509ExtPtr(RARRAY_PTR(ary)[i]);\n\t\n\tif (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */\n\t    X509_EXTENSION_free(ext);\n\t    ossl_raise(eX509CertError, NULL);\n\t}\n\tX509_EXTENSION_free(ext);\n    }\n\n    return ary;\n}\n\n/*\n * call-seq:\n *    cert.add_extension(extension) => extension\n */\nstatic VALUE \nossl_x509_add_extension(VALUE self, VALUE extension)\n{\n    X509 *x509;\n    X509_EXTENSION *ext;\n\t\n    GetX509(self, x509);\n    ext = DupX509ExtPtr(extension);\n    if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */\n\tX509_EXTENSION_free(ext);\n\tossl_raise(eX509CertError, NULL);\n    }\n    X509_EXTENSION_free(ext);\n\n    return extension;\n}\n\nstatic VALUE\nossl_x509_inspect(VALUE self)\n{\n    VALUE str;\n    char *cname = rb_class2name(rb_obj_class(self));\n\n    str = rb_str_new2(\"#<\");\n    rb_str_cat2(str, cname);\n    rb_str_cat2(str, \" \");\n\n    rb_str_cat2(str, \"subject=\");\n    rb_str_append(str, rb_inspect(ossl_x509_get_subject(self)));\n    rb_str_cat2(str, \", \");\n\n    rb_str_cat2(str, \"issuer=\");\n    rb_str_append(str, rb_inspect(ossl_x509_get_issuer(self)));\n    rb_str_cat2(str, \", \");\n\n    rb_str_cat2(str, \"serial=\");\n    rb_str_append(str, rb_inspect(ossl_x509_get_serial(self)));\n    rb_str_cat2(str, \", \");\n\n    rb_str_cat2(str, \"not_before=\");\n    rb_str_append(str, rb_inspect(ossl_x509_get_not_before(self)));\n    rb_str_cat2(str, \", \");\n\n    rb_str_cat2(str, \"not_after=\");\n    rb_str_append(str, rb_inspect(ossl_x509_get_not_after(self)));\n\n    str = rb_str_cat2(str, \">\");\n\n    return str;\n}\n\n/*\n * INIT\n */\nvoid \nInit_ossl_x509cert()\n{\n    eX509CertError = rb_define_class_under(mX509, \"CertificateError\", eOSSLError);\n\t\n    cX509Cert = rb_define_class_under(mX509, \"Certificate\", rb_cObject);\n\t\n    rb_define_alloc_func(cX509Cert, ossl_x509_alloc);\n    rb_define_method(cX509Cert, \"initialize\", ossl_x509_initialize, -1);\n    rb_define_copy_func(cX509Cert, ossl_x509_copy);\n    \n    rb_define_method(cX509Cert, \"to_der\", ossl_x509_to_der, 0);\n    rb_define_method(cX509Cert, \"to_pem\", ossl_x509_to_pem, 0);\n    rb_define_alias(cX509Cert, \"to_s\", \"to_pem\");\n    rb_define_method(cX509Cert, \"to_text\", ossl_x509_to_text, 0);\n    rb_define_method(cX509Cert, \"version\", ossl_x509_get_version, 0);\n    rb_define_method(cX509Cert, \"version=\", ossl_x509_set_version, 1);\n    rb_define_method(cX509Cert, \"signature_algorithm\", ossl_x509_get_signature_algorithm, 0);\n    rb_define_method(cX509Cert, \"serial\", ossl_x509_get_serial, 0);\n    rb_define_method(cX509Cert, \"serial=\", ossl_x509_set_serial, 1);\n    rb_define_method(cX509Cert, \"subject\", ossl_x509_get_subject, 0);\n    rb_define_method(cX509Cert, \"subject=\", ossl_x509_set_subject, 1);\n    rb_define_method(cX509Cert, \"issuer\", ossl_x509_get_issuer, 0);\n    rb_define_method(cX509Cert, \"issuer=\", ossl_x509_set_issuer, 1);\n    rb_define_method(cX509Cert, \"not_before\", ossl_x509_get_not_before, 0);\n    rb_define_method(cX509Cert, \"not_before=\", ossl_x509_set_not_before, 1);\n    rb_define_method(cX509Cert, \"not_after\", ossl_x509_get_not_after, 0);\n    rb_define_method(cX509Cert, \"not_after=\", ossl_x509_set_not_after, 1);\n    rb_define_method(cX509Cert, \"public_key\", ossl_x509_get_public_key, 0);\n    rb_define_method(cX509Cert, \"public_key=\", ossl_x509_set_public_key, 1);\n    rb_define_method(cX509Cert, \"sign\", ossl_x509_sign, 2);\n    rb_define_method(cX509Cert, \"verify\", ossl_x509_verify, 1);\n    rb_define_method(cX509Cert, \"check_private_key\", ossl_x509_check_private_key, 1);\n    rb_define_method(cX509Cert, \"extensions\", ossl_x509_get_extensions, 0);\n    rb_define_method(cX509Cert, \"extensions=\", ossl_x509_set_extensions, 1);\n    rb_define_method(cX509Cert, \"add_extension\", ossl_x509_add_extension, 1);\n    rb_define_method(cX509Cert, \"inspect\", ossl_x509_inspect, 0);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_x509crl.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509CRL(klass, obj, crl) do { \\\n    if (!crl) { \\\n\tossl_raise(rb_eRuntimeError, \"CRL wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_CRL_free, crl); \\\n} while (0)\n#define GetX509CRL(obj, crl) do { \\\n    Data_Get_Struct(obj, X509_CRL, crl); \\\n    if (!crl) { \\\n\tossl_raise(rb_eRuntimeError, \"CRL wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509CRL(obj, crl) do { \\\n    OSSL_Check_Kind(obj, cX509CRL); \\\n    GetX509CRL(obj, crl); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509CRL;\nVALUE eX509CRLError;\n\n/*\n * PUBLIC\n */\nX509_CRL *\nGetX509CRLPtr(VALUE obj)\n{\n    X509_CRL *crl;\n\n    SafeGetX509CRL(obj, crl);\n\n    return crl;\n}\n\nX509_CRL *\nDupX509CRLPtr(VALUE obj)\n{\n    X509_CRL *crl;\n\n    SafeGetX509CRL(obj, crl);\n    CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);\n\n    return crl;\n}\n\nVALUE\nossl_x509crl_new(X509_CRL *crl)\n{\n    X509_CRL *tmp;\n    VALUE obj;\n\n    tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new();\n    if(!tmp) ossl_raise(eX509CRLError, NULL);\n    WrapX509CRL(cX509CRL, obj, tmp);\n        \n    return obj;\n}\n\n/*\n * PRIVATE\n */\nstatic VALUE \nossl_x509crl_alloc(VALUE klass)\n{\n    X509_CRL *crl;\n    VALUE obj;\n\n    if (!(crl = X509_CRL_new())) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    WrapX509CRL(klass, obj, crl);\n\n    return obj;\n}\n\nstatic VALUE \nossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)\n{\n    BIO *in;\n    X509_CRL *crl;\n    VALUE arg;\n\n    if (rb_scan_args(argc, argv, \"01\", &arg) == 0) {\n\treturn self;\n    }\n    arg = ossl_to_der_if_possible(arg);\n    in = ossl_obj2bio(arg);\n    crl = PEM_read_bio_X509_CRL(in, (X509_CRL **)&DATA_PTR(self), NULL, NULL);\n    if (!crl) {\n\tBIO_reset(in);\n\tcrl = d2i_X509_CRL_bio(in, (X509_CRL **)&DATA_PTR(self));\n    }\n    BIO_free(in);\n    if (!crl) ossl_raise(eX509CRLError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_x509crl_copy(VALUE self, VALUE other)\n{\n    X509_CRL *a, *b, *crl;\n\t\n    rb_check_frozen(self);\n    if (self == other) return self;\n    GetX509CRL(self, a);\n    SafeGetX509CRL(other, b);\n    if (!(crl = X509_CRL_dup(b))) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    X509_CRL_free(a);\n    DATA_PTR(self) = crl;\n\n    return self;\n}\n\nstatic VALUE \nossl_x509crl_get_version(VALUE self)\n{\n    X509_CRL *crl;\n    long ver;\n\n    GetX509CRL(self, crl);\n    ver = X509_CRL_get_version(crl);\n\n    return LONG2NUM(ver);\n}\n\nstatic VALUE \nossl_x509crl_set_version(VALUE self, VALUE version)\n{\n    X509_CRL *crl;\n    long ver;\n\n    if ((ver = NUM2LONG(version)) < 0) {\n\tossl_raise(eX509CRLError, \"version must be >= 0!\");\n    }\n    GetX509CRL(self, crl);\n    if (!X509_CRL_set_version(crl, ver)) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n\n    return version;\n}\n\nstatic VALUE \nossl_x509crl_get_signature_algorithm(VALUE self)\n{\n    X509_CRL *crl;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\n    GetX509CRL(self, crl);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    if (!i2a_ASN1_OBJECT(out, crl->sig_alg->algorithm)) {\n\tBIO_free(out);\n\tossl_raise(eX509CRLError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n    return str;\n}\n\nstatic VALUE \nossl_x509crl_get_issuer(VALUE self)\n{\n    X509_CRL *crl;\n\n    GetX509CRL(self, crl);\n\n    return ossl_x509name_new(X509_CRL_get_issuer(crl)); /* NO DUP - don't free */\n}\n\nstatic VALUE \nossl_x509crl_set_issuer(VALUE self, VALUE issuer)\n{\n    X509_CRL *crl;\n\n    GetX509CRL(self, crl);\n\n    if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */\n\tossl_raise(eX509CRLError, NULL);\n    }\n    return issuer;\n}\n\nstatic VALUE \nossl_x509crl_get_last_update(VALUE self)\n{\n    X509_CRL *crl;\n\n    GetX509CRL(self, crl);\n\n    return asn1time_to_time(X509_CRL_get_lastUpdate(crl));\n}\n\nstatic VALUE \nossl_x509crl_set_last_update(VALUE self, VALUE time)\n{\n    X509_CRL *crl;\n    time_t sec;\n\n    sec = time_to_time_t(time);\n    GetX509CRL(self, crl);\n    if (!X509_time_adj(crl->crl->lastUpdate, 0, &sec)) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n\n    return time;\n}\n\nstatic VALUE \nossl_x509crl_get_next_update(VALUE self)\n{\n    X509_CRL *crl;\n\n    GetX509CRL(self, crl);\n\n    return asn1time_to_time(X509_CRL_get_nextUpdate(crl));\n}\n\nstatic VALUE \nossl_x509crl_set_next_update(VALUE self, VALUE time)\n{\n    X509_CRL *crl;\n    time_t sec;\n\n    sec = time_to_time_t(time);\n    GetX509CRL(self, crl);\n    /* This must be some thinko in OpenSSL */\n    if (!(crl->crl->nextUpdate = X509_time_adj(crl->crl->nextUpdate, 0, &sec))){\n\tossl_raise(eX509CRLError, NULL);\n    }\n\n    return time;\n}\n\nstatic VALUE\nossl_x509crl_get_revoked(VALUE self)\n{\n    X509_CRL *crl;\n    int i, num;\n    X509_REVOKED *rev;\n    VALUE ary, revoked;\n\n    GetX509CRL(self, crl);\n    num = sk_X509_CRL_num(X509_CRL_get_REVOKED(crl));\n    if (num < 0) {\n\tOSSL_Debug(\"num < 0???\");\n\treturn rb_ary_new();\n    }\n    ary = rb_ary_new2(num);\n    for(i=0; i<num; i++) {\n\t/* NO DUP - don't free! */\n\trev = (X509_REVOKED *)sk_X509_CRL_value(X509_CRL_get_REVOKED(crl), i);\n\trevoked = ossl_x509revoked_new(rev);\n\trb_ary_push(ary, revoked);\n    }\n\n    return ary;\n}\n\nstatic VALUE \nossl_x509crl_set_revoked(VALUE self, VALUE ary)\n{\n    X509_CRL *crl;\n    X509_REVOKED *rev;\n    int i;\n\n    Check_Type(ary, T_ARRAY);\n    /* All ary members should be X509 Revoked */\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\tOSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Rev);\n    }\n    GetX509CRL(self, crl);\n    sk_X509_REVOKED_pop_free(crl->crl->revoked, X509_REVOKED_free);\n    crl->crl->revoked = NULL;\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\trev = DupX509RevokedPtr(RARRAY_PTR(ary)[i]);\n\tif (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */\n\t    ossl_raise(eX509CRLError, NULL);\n\t}\n    }\n    X509_CRL_sort(crl);\n\n    return ary;\n}\n\nstatic VALUE \nossl_x509crl_add_revoked(VALUE self, VALUE revoked)\n{\n    X509_CRL *crl;\n    X509_REVOKED *rev;\n\n    GetX509CRL(self, crl);\n    rev = DupX509RevokedPtr(revoked);\n    if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */\n\tossl_raise(eX509CRLError, NULL);\n    }\n    X509_CRL_sort(crl);\n\n    return revoked;\n}\n\nstatic VALUE \nossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)\n{\n    X509_CRL *crl;\n    EVP_PKEY *pkey;\n    const EVP_MD *md;\n\n    GetX509CRL(self, crl);\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    md = GetDigestPtr(digest);\n    if (!X509_CRL_sign(crl, pkey, md)) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE \nossl_x509crl_verify(VALUE self, VALUE key)\n{\n    X509_CRL *crl;\n    int ret;\n\n    GetX509CRL(self, crl);\n    if ((ret = X509_CRL_verify(crl, GetPKeyPtr(key))) < 0) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    if (ret == 1) {\n\treturn Qtrue;\n    }\n\n    return Qfalse;\n}\n\nstatic VALUE \nossl_x509crl_to_der(VALUE self)\n{\n    X509_CRL *crl;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\n    GetX509CRL(self, crl);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    if (!i2d_X509_CRL_bio(out, crl)) {\n\tBIO_free(out);\n\tossl_raise(eX509CRLError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n\n    return str;\n}\n\nstatic VALUE \nossl_x509crl_to_pem(VALUE self)\n{\n    X509_CRL *crl;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\n    GetX509CRL(self, crl);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    if (!PEM_write_bio_X509_CRL(out, crl)) {\n\tBIO_free(out);\n\tossl_raise(eX509CRLError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n\n    return str;\n}\n\nstatic VALUE \nossl_x509crl_to_text(VALUE self)\n{\n    X509_CRL *crl;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\n    GetX509CRL(self, crl);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509CRLError, NULL);\n    }\n    if (!X509_CRL_print(out, crl)) {\n\tBIO_free(out);\n\tossl_raise(eX509CRLError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n\t\n    return str;\n}\n\n/*\n * Gets X509v3 extensions as array of X509Ext objects\n */\nstatic VALUE \nossl_x509crl_get_extensions(VALUE self)\n{\n    X509_CRL *crl;\n    int count, i;\n    X509_EXTENSION *ext;\n    VALUE ary;\n\n    GetX509CRL(self, crl);\n    count = X509_CRL_get_ext_count(crl);\n    if (count < 0) {\n\tOSSL_Debug(\"count < 0???\");\n\treturn rb_ary_new();\n    }\n    ary = rb_ary_new2(count);\n    for (i=0; i<count; i++) {\n\text = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */\n\trb_ary_push(ary, ossl_x509ext_new(ext));\n    }\n\n    return ary;\n}\n\n/*\n * Sets X509_EXTENSIONs\n */\nstatic VALUE \nossl_x509crl_set_extensions(VALUE self, VALUE ary)\n{\n    X509_CRL *crl;\n    X509_EXTENSION *ext;\n    int i;\n\t\n    Check_Type(ary, T_ARRAY);\n    /* All ary members should be X509 Extensions */\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\tOSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);\n    }\n    GetX509CRL(self, crl);\n    sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free);\n    crl->crl->extensions = NULL;\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\text = DupX509ExtPtr(RARRAY_PTR(ary)[i]);\n\tif(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */\n\t    X509_EXTENSION_free(ext);\n\t    ossl_raise(eX509CRLError, NULL);\n\t}\n\tX509_EXTENSION_free(ext);\n    }\n\n    return ary;\n}\n\nstatic VALUE \nossl_x509crl_add_extension(VALUE self, VALUE extension)\n{\n    X509_CRL *crl;\n    X509_EXTENSION *ext;\n\n    GetX509CRL(self, crl);\n    ext = DupX509ExtPtr(extension);\n    if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */\n\tX509_EXTENSION_free(ext);\n\tossl_raise(eX509CRLError, NULL);\n    }\n    X509_EXTENSION_free(ext);\n\n    return extension;\n}\n\n/*\n * INIT\n */\nvoid \nInit_ossl_x509crl()\n{\n    eX509CRLError = rb_define_class_under(mX509, \"CRLError\", eOSSLError);\n\n    cX509CRL = rb_define_class_under(mX509, \"CRL\", rb_cObject);\n\t\n    rb_define_alloc_func(cX509CRL, ossl_x509crl_alloc);\n    rb_define_method(cX509CRL, \"initialize\", ossl_x509crl_initialize, -1);\n    rb_define_copy_func(cX509CRL, ossl_x509crl_copy);\n    \n    rb_define_method(cX509CRL, \"version\", ossl_x509crl_get_version, 0);\n    rb_define_method(cX509CRL, \"version=\", ossl_x509crl_set_version, 1);\n    rb_define_method(cX509CRL, \"signature_algorithm\", ossl_x509crl_get_signature_algorithm, 0);\n    rb_define_method(cX509CRL, \"issuer\", ossl_x509crl_get_issuer, 0);\n    rb_define_method(cX509CRL, \"issuer=\", ossl_x509crl_set_issuer, 1);\n    rb_define_method(cX509CRL, \"last_update\", ossl_x509crl_get_last_update, 0);\n    rb_define_method(cX509CRL, \"last_update=\", ossl_x509crl_set_last_update, 1);\n    rb_define_method(cX509CRL, \"next_update\", ossl_x509crl_get_next_update, 0);\n    rb_define_method(cX509CRL, \"next_update=\", ossl_x509crl_set_next_update, 1);\n    rb_define_method(cX509CRL, \"revoked\", ossl_x509crl_get_revoked, 0);\n    rb_define_method(cX509CRL, \"revoked=\", ossl_x509crl_set_revoked, 1);\n    rb_define_method(cX509CRL, \"add_revoked\", ossl_x509crl_add_revoked, 1);\n    rb_define_method(cX509CRL, \"sign\", ossl_x509crl_sign, 2);\n    rb_define_method(cX509CRL, \"verify\", ossl_x509crl_verify, 1);\n    rb_define_method(cX509CRL, \"to_der\", ossl_x509crl_to_der, 0);\n    rb_define_method(cX509CRL, \"to_pem\", ossl_x509crl_to_pem, 0);\n    rb_define_alias(cX509CRL, \"to_s\", \"to_pem\");\n    rb_define_method(cX509CRL, \"to_text\", ossl_x509crl_to_text, 0);\n    rb_define_method(cX509CRL, \"extensions\", ossl_x509crl_get_extensions, 0);\n    rb_define_method(cX509CRL, \"extensions=\", ossl_x509crl_set_extensions, 1);\n    rb_define_method(cX509CRL, \"add_extension\", ossl_x509crl_add_extension, 1);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_x509ext.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509Ext(klass, obj, ext) do { \\\n    if (!ext) { \\\n\tossl_raise(rb_eRuntimeError, \"EXT wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_EXTENSION_free, ext); \\\n} while (0)\n#define GetX509Ext(obj, ext) do { \\\n    Data_Get_Struct(obj, X509_EXTENSION, ext); \\\n    if (!ext) { \\\n\tossl_raise(rb_eRuntimeError, \"EXT wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509Ext(obj, ext) do { \\\n    OSSL_Check_Kind(obj, cX509Ext); \\\n    GetX509Ext(obj, ext); \\\n} while (0)\n#define MakeX509ExtFactory(klass, obj, ctx) do { \\\n    if (!(ctx = OPENSSL_malloc(sizeof(X509V3_CTX)))) \\\n        ossl_raise(rb_eRuntimeError, \"CTX wasn't allocated!\"); \\\n    X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, 0); \\\n    obj = Data_Wrap_Struct(klass, 0, ossl_x509extfactory_free, ctx); \\\n} while (0)\n#define GetX509ExtFactory(obj, ctx) do { \\\n    Data_Get_Struct(obj, X509V3_CTX, ctx); \\\n    if (!ctx) { \\\n\tossl_raise(rb_eRuntimeError, \"CTX wasn't initialized!\"); \\\n    } \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509Ext;\nVALUE cX509ExtFactory;\nVALUE eX509ExtError;\n\n/*\n * Public\n */\nVALUE \nossl_x509ext_new(X509_EXTENSION *ext)\n{\n    X509_EXTENSION *new;\n    VALUE obj;\n\n    if (!ext) {\n\tnew = X509_EXTENSION_new();\n    } else {\n\tnew = X509_EXTENSION_dup(ext);\n    }\n    if (!new) {\n\tossl_raise(eX509ExtError, NULL);\n    }\n    WrapX509Ext(cX509Ext, obj, new);\n\t\n    return obj;\n}\n\nX509_EXTENSION *\nGetX509ExtPtr(VALUE obj)\n{\n    X509_EXTENSION *ext;\n\n    SafeGetX509Ext(obj, ext);\n\n    return ext;\n}\n\nX509_EXTENSION *\nDupX509ExtPtr(VALUE obj)\n{\n    X509_EXTENSION *ext, *new;\n\n    SafeGetX509Ext(obj, ext);\n    if (!(new = X509_EXTENSION_dup(ext))) {\n\tossl_raise(eX509ExtError, NULL);\n    }\n\n    return new;\n}\n\n/*\n * Private\n */\n/*\n * Ext factory\n */\nstatic void\nossl_x509extfactory_free(X509V3_CTX *ctx)\n{\n    OPENSSL_free(ctx);\n}\n\nstatic VALUE \nossl_x509extfactory_alloc(VALUE klass)\n{\n    X509V3_CTX *ctx;\n    VALUE obj;\n\n    MakeX509ExtFactory(klass, obj, ctx);\n\n    return obj;\n}\n\nstatic VALUE \nossl_x509extfactory_set_issuer_cert(VALUE self, VALUE cert)\n{\n    X509V3_CTX *ctx;\n\n    GetX509ExtFactory(self, ctx);\n    rb_iv_set(self, \"@issuer_certificate\", cert);\n    ctx->issuer_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */\n\n    return cert;\n}\n\nstatic VALUE \nossl_x509extfactory_set_subject_cert(VALUE self, VALUE cert)\n{\n    X509V3_CTX *ctx;\n\n    GetX509ExtFactory(self, ctx);\n    rb_iv_set(self, \"@subject_certificate\", cert);\n    ctx->subject_cert = GetX509CertPtr(cert); /* NO DUP NEEDED */\n\n    return cert;\n}\n\nstatic VALUE \nossl_x509extfactory_set_subject_req(VALUE self, VALUE req)\n{\n    X509V3_CTX *ctx;\n\n    GetX509ExtFactory(self, ctx);\n    rb_iv_set(self, \"@subject_request\", req);\n    ctx->subject_req = GetX509ReqPtr(req); /* NO DUP NEEDED */\n\n    return req;\n}\n\nstatic VALUE \nossl_x509extfactory_set_crl(VALUE self, VALUE crl)\n{\n    X509V3_CTX *ctx;\n\n    GetX509ExtFactory(self, ctx);\n    rb_iv_set(self, \"@crl\", crl);\n    ctx->crl = GetX509CRLPtr(crl); /* NO DUP NEEDED */\n\n    return crl;\n}\n\nstatic VALUE\nossl_x509extfactory_set_config(VALUE self, VALUE config)\n{\n#ifdef HAVE_X509V3_SET_NCONF\n    X509V3_CTX *ctx;\n    CONF *conf;\n\n    GetX509ExtFactory(self, ctx);\n    rb_iv_set(self, \"@config\", config);\n    conf = GetConfigPtr(config);  /* NO DUP NEEDED */\n    X509V3_set_nconf(ctx, conf);\n\n    return config;\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE \nossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self)\n{\n    /*X509V3_CTX *ctx;*/\n    VALUE issuer_cert, subject_cert, subject_req, crl;\n\t\n    /*GetX509ExtFactory(self, ctx);*/\n\n    rb_scan_args(argc, argv, \"04\",\n\t\t &issuer_cert, &subject_cert, &subject_req, &crl);\n    if (!NIL_P(issuer_cert))\n\tossl_x509extfactory_set_issuer_cert(self, issuer_cert);\n    if (!NIL_P(subject_cert))\n\tossl_x509extfactory_set_subject_cert(self, subject_cert);\n    if (!NIL_P(subject_req))\n\tossl_x509extfactory_set_subject_req(self, subject_req);\n    if (!NIL_P(crl))\n\tossl_x509extfactory_set_crl(self, crl);\n\n    return self;\n}\n\n/*\n * Array to X509_EXTENSION\n * Structure:\n * [\"ln\", \"value\", bool_critical] or\n * [\"sn\", \"value\", bool_critical] or\n * [\"ln\", \"critical,value\"] or the same for sn\n * [\"ln\", \"value\"] => not critical\n */\nstatic VALUE \nossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)\n{\n    X509V3_CTX *ctx;\n    X509_EXTENSION *ext;\n    VALUE oid, value, critical, valstr, obj;\n    int nid;\n#ifdef HAVE_X509V3_EXT_NCONF_NID\n    VALUE rconf;\n    CONF *conf;\n    ID i_config;\n#else\n    static LHASH *empty_lhash;\n#endif\n\n    rb_scan_args(argc, argv, \"21\", &oid, &value, &critical);\n    StringValue(oid);\n    StringValue(value);\n    if(NIL_P(critical)) critical = Qfalse;\n\n    nid = OBJ_ln2nid(RSTRING_PTR(oid));\n    if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid));\n    if(!nid) ossl_raise(eX509ExtError, \"unknown OID `%s'\", RSTRING_PTR(oid));\n    valstr = rb_str_new2(RTEST(critical) ? \"critical,\" : \"\");\n    rb_str_append(valstr, value);\n    GetX509ExtFactory(self, ctx);\n#ifdef HAVE_X509V3_EXT_NCONF_NID\n    i_config = rb_intern(\"@config\");\n    if (rb_ivar_defined(self, i_config))\n\trconf = rb_ivar_get(self, i_config);\n    else\n\trconf = Qnil;\n    conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf);\n    ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));\n#else\n    if (!empty_lhash) empty_lhash = lh_new(NULL, NULL);\n    ext = X509V3_EXT_conf_nid(empty_lhash, ctx, nid, RSTRING_PTR(valstr));\n#endif\n    if (!ext){\n\tossl_raise(eX509ExtError, \"%s = %s\",\n\t\t   RSTRING_PTR(oid), RSTRING_PTR(value));\n    }\n    WrapX509Ext(cX509Ext, obj, ext);\n\n    return obj;\n}\n\n/*\n * Ext\n */\nstatic VALUE\nossl_x509ext_alloc(VALUE klass)\n{\n    X509_EXTENSION *ext;\n    VALUE obj;\n\n    if(!(ext = X509_EXTENSION_new())){\n\tossl_raise(eX509ExtError, NULL);\n    }\n    WrapX509Ext(klass, obj, ext);\n\n    return obj;\n}\n\nstatic VALUE\nossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE oid, value, critical;\n    OSSL_MORE_CONST unsigned char *p;\n    X509_EXTENSION *ext;\n\n    GetX509Ext(self, ext);\n    if(rb_scan_args(argc, argv, \"12\", &oid, &value, &critical) == 1){\n\toid = ossl_to_der_if_possible(oid);\n\tStringValue(oid);\n\tp  = RSTRING_PTR(oid);\n\tif(!d2i_X509_EXTENSION((X509_EXTENSION**)&DATA_PTR(self),\n\t\t\t       &p, RSTRING_LEN(oid)))\n\t    ossl_raise(eX509ExtError, NULL);\n\treturn self;\n    }\n    rb_funcall(self, rb_intern(\"oid=\"), 1, oid);\n    rb_funcall(self, rb_intern(\"value=\"), 1, value);\n    if(argc > 2) rb_funcall(self, rb_intern(\"critical=\"), 1, critical);\n\n    return self;\n}\n\nstatic VALUE\nossl_x509ext_set_oid(VALUE self, VALUE oid)\n{\n    X509_EXTENSION *ext;\n    ASN1_OBJECT *obj;\n    char *s;\n\n    s = StringValuePtr(oid);\n    obj = OBJ_txt2obj(s, 0);\n    if(!obj) obj = OBJ_txt2obj(s, 1);\n    if(!obj) ossl_raise(eX509ExtError, NULL);\n    GetX509Ext(self, ext);\n    X509_EXTENSION_set_object(ext, obj);\n\n    return oid;\n}\n\nstatic VALUE\nossl_x509ext_set_value(VALUE self, VALUE data)\n{\n    X509_EXTENSION *ext;\n    ASN1_OCTET_STRING *asn1s;\n    char *s;\n\n    data = ossl_to_der_if_possible(data);\n    StringValue(data);\n    if(!(s = OPENSSL_malloc(RSTRING_LEN(data))))\n\tossl_raise(eX509ExtError, \"malloc error\");\n    memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data));\n    if(!(asn1s = ASN1_OCTET_STRING_new())){\n\tfree(s);\n\tossl_raise(eX509ExtError, NULL);\n    }\n    if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LEN(data))){\n\tfree(s);\n\tASN1_OCTET_STRING_free(asn1s);\n\tossl_raise(eX509ExtError, NULL);\n    }\n    GetX509Ext(self, ext);\n    X509_EXTENSION_set_data(ext, asn1s);\n\n    return data;\n}\n\nstatic VALUE\nossl_x509ext_set_critical(VALUE self, VALUE flag)\n{\n    X509_EXTENSION *ext;\n\n    GetX509Ext(self, ext);\n    X509_EXTENSION_set_critical(ext, RTEST(flag) ? 1 : 0);\n\n    return flag;\n}\n\nstatic VALUE \nossl_x509ext_get_oid(VALUE obj)\n{\n    X509_EXTENSION *ext;\n    ASN1_OBJECT *extobj;\n    BIO *out;\n    VALUE ret;\n    int nid;\n\n    GetX509Ext(obj, ext);\n    extobj = X509_EXTENSION_get_object(ext);\n    if ((nid = OBJ_obj2nid(extobj)) != NID_undef)\n\tret = rb_str_new2(OBJ_nid2sn(nid));\n    else{\n\tif (!(out = BIO_new(BIO_s_mem())))\n\t    ossl_raise(eX509ExtError, NULL);\n\ti2a_ASN1_OBJECT(out, extobj);\n\tret = ossl_membio2str(out);\n    }\n\n    return ret;\n}\n\nstatic VALUE\nossl_x509ext_get_value(VALUE obj)\n{\n    X509_EXTENSION *ext;\n    BIO *out;\n    VALUE ret;\n\n    GetX509Ext(obj, ext);\n    if (!(out = BIO_new(BIO_s_mem())))\n\tossl_raise(eX509ExtError, NULL);\n    if (!X509V3_EXT_print(out, ext, 0, 0))\n\tM_ASN1_OCTET_STRING_print(out, ext->value);\n    ret = ossl_membio2str(out);\n\n    return ret;\n}\n\nstatic VALUE\nossl_x509ext_get_critical(VALUE obj)\n{\n    X509_EXTENSION *ext;\n\n    GetX509Ext(obj, ext);\n    return X509_EXTENSION_get_critical(ext) ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_x509ext_to_der(VALUE obj)\n{\n    X509_EXTENSION *ext;\n    unsigned char *p;\n    long len;\n    VALUE str;\n\n    GetX509Ext(obj, ext);\n    if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0)\n\tossl_raise(eX509ExtError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_X509_EXTENSION(ext, &p) < 0)\n\tossl_raise(eX509ExtError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_x509ext()\n{\n    eX509ExtError = rb_define_class_under(mX509, \"ExtensionError\", eOSSLError);\n    \n    cX509ExtFactory = rb_define_class_under(mX509, \"ExtensionFactory\", rb_cObject);\n\t\n    rb_define_alloc_func(cX509ExtFactory, ossl_x509extfactory_alloc);\n    rb_define_method(cX509ExtFactory, \"initialize\", ossl_x509extfactory_initialize, -1);\n\t\n    rb_attr(cX509ExtFactory, rb_intern(\"issuer_certificate\"), 1, 0, Qfalse);\n    rb_attr(cX509ExtFactory, rb_intern(\"subject_certificate\"), 1, 0, Qfalse);\n    rb_attr(cX509ExtFactory, rb_intern(\"subject_request\"), 1, 0, Qfalse);\n    rb_attr(cX509ExtFactory, rb_intern(\"crl\"), 1, 0, Qfalse);\n    rb_attr(cX509ExtFactory, rb_intern(\"config\"), 1, 0, Qfalse);\n\n    rb_define_method(cX509ExtFactory, \"issuer_certificate=\", ossl_x509extfactory_set_issuer_cert, 1);\n    rb_define_method(cX509ExtFactory, \"subject_certificate=\", ossl_x509extfactory_set_subject_cert, 1);\n    rb_define_method(cX509ExtFactory, \"subject_request=\", ossl_x509extfactory_set_subject_req, 1);\n    rb_define_method(cX509ExtFactory, \"crl=\", ossl_x509extfactory_set_crl, 1);\n    rb_define_method(cX509ExtFactory, \"config=\", ossl_x509extfactory_set_config, 1);\n    rb_define_method(cX509ExtFactory, \"create_ext\", ossl_x509extfactory_create_ext, -1);\n\t\n    cX509Ext = rb_define_class_under(mX509, \"Extension\", rb_cObject);\n    rb_define_alloc_func(cX509Ext, ossl_x509ext_alloc);\n    rb_define_method(cX509Ext, \"initialize\", ossl_x509ext_initialize, -1);\n    rb_define_method(cX509Ext, \"oid=\", ossl_x509ext_set_oid, 1);\n    rb_define_method(cX509Ext, \"value=\", ossl_x509ext_set_value, 1);\n    rb_define_method(cX509Ext, \"critical=\", ossl_x509ext_set_critical, 1);\n    rb_define_method(cX509Ext, \"oid\", ossl_x509ext_get_oid, 0);\n    rb_define_method(cX509Ext, \"value\", ossl_x509ext_get_value, 0);\n    rb_define_method(cX509Ext, \"critical?\", ossl_x509ext_get_critical, 0);\n    rb_define_method(cX509Ext, \"to_der\", ossl_x509ext_to_der, 0);\n}\n"
  },
  {
    "path": "ext/openssl/ossl_x509name.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001 Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509Name(klass, obj, name) do { \\\n    if (!name) { \\\n\tossl_raise(rb_eRuntimeError, \"Name wasn't initialized.\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_NAME_free, name); \\\n} while (0)\n#define GetX509Name(obj, name) do { \\\n    Data_Get_Struct(obj, X509_NAME, name); \\\n    if (!name) { \\\n\tossl_raise(rb_eRuntimeError, \"Name wasn't initialized.\"); \\\n    } \\\n} while (0)\n#define SafeGetX509Name(obj, name) do { \\\n    OSSL_Check_Kind(obj, cX509Name); \\\n    GetX509Name(obj, name); \\\n} while (0)\n\n#define OBJECT_TYPE_TEMPLATE \\\n  rb_const_get(cX509Name, rb_intern(\"OBJECT_TYPE_TEMPLATE\"))\n#define DEFAULT_OBJECT_TYPE \\\n  rb_const_get(cX509Name, rb_intern(\"DEFAULT_OBJECT_TYPE\"))\n\n/*\n * Classes\n */\nVALUE cX509Name;\nVALUE eX509NameError;\n\n/*\n * Public\n */\nVALUE \nossl_x509name_new(X509_NAME *name)\n{\n    X509_NAME *new;\n    VALUE obj;\n\n    if (!name) {\n\tnew = X509_NAME_new();\n    } else {\n\tnew = X509_NAME_dup(name);\n    }\n    if (!new) {\n\tossl_raise(eX509NameError, NULL);\n    }\n    WrapX509Name(cX509Name, obj, new);\n    \n    return obj;\n}\n\nX509_NAME *\nGetX509NamePtr(VALUE obj)\n{\n    X509_NAME *name;\n\n    SafeGetX509Name(obj, name);\n\n    return name;\n}\n\n/*\n * Private\n */\nstatic VALUE\nossl_x509name_alloc(VALUE klass)\n{\n    X509_NAME *name;\n    VALUE obj;\n\t\n    if (!(name = X509_NAME_new())) {\n\tossl_raise(eX509NameError, NULL);\n    }\n    WrapX509Name(klass, obj, name);\n\n    return obj;\n}\n\nstatic int id_aref;\nstatic VALUE ossl_x509name_add_entry(int, VALUE*, VALUE);\n#define rb_aref(obj, key) rb_funcall(obj, id_aref, 1, key)\n\nstatic VALUE\nossl_x509name_init_i(VALUE i, VALUE args)\n{\n    VALUE self = rb_ary_entry(args, 0);\n    VALUE template = rb_ary_entry(args, 1);\n    VALUE entry[3];\n\n    Check_Type(i, T_ARRAY);\n    entry[0] = rb_ary_entry(i, 0);\n    entry[1] = rb_ary_entry(i, 1);\n    entry[2] = rb_ary_entry(i, 2);\n    if(NIL_P(entry[2])) entry[2] = rb_aref(template, entry[0]);\n    if(NIL_P(entry[2])) entry[2] = DEFAULT_OBJECT_TYPE;\n    ossl_x509name_add_entry(3, entry, self);\n\n    return Qnil;\n}\n\n/*\n * call-seq:\n *    X509::Name.new => name\n *    X509::Name.new(string) => name\n *    X509::Name.new(dn) => name\n *    X509::Name.new(dn, template) => name\n */\nstatic VALUE\nossl_x509name_initialize(int argc, VALUE *argv, VALUE self)\n{\n    X509_NAME *name;\n    VALUE arg, template;\n\n    GetX509Name(self, name);\n    if (rb_scan_args(argc, argv, \"02\", &arg, &template) == 0) {\n\treturn self;\n    }\n    else {\n\tVALUE tmp = rb_check_array_type(arg);\n\tif (!NIL_P(tmp)) {\n\t    VALUE args;\n\t    if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE;\n\t    args = rb_ary_new3(2, self, template);\n\t    rb_block_call(tmp, rb_intern(\"each\"), 0, 0, ossl_x509name_init_i, args);\n\t}\n\telse{\n\t    unsigned char *p;\n\t    VALUE str = ossl_to_der_if_possible(arg);\n\t    StringValue(str);\n\t    p = RSTRING_PTR(str);\n\t    if(!d2i_X509_NAME((X509_NAME**)&DATA_PTR(self), &p, RSTRING_LEN(str))){\n\t\tossl_raise(eX509NameError, NULL);\n\t    }\n\t}\n    }\n\n    return self;\n}\n\n/*\n * call-seq:\n *    name.add_entry(oid, value [, type]) => self\n */\nstatic\nVALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self)\n{\n    X509_NAME *name;\n    VALUE oid, value, type;\n\n    rb_scan_args(argc, argv, \"21\", &oid, &value, &type);\n    StringValue(oid);\n    StringValue(value);\n    if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);\n    GetX509Name(self, name);\n    if (!X509_NAME_add_entry_by_txt(name, RSTRING_PTR(oid), NUM2INT(type),\n\t\tRSTRING_PTR(value), RSTRING_LEN(value), -1, 0)) {\n\tossl_raise(eX509NameError, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_x509name_to_s_old(VALUE self)\n{\n    X509_NAME *name;\n    char *buf;\n    VALUE str;\n\n    GetX509Name(self, name);\n    buf = X509_NAME_oneline(name, NULL, 0);\n    str = rb_str_new2(buf);\n    OPENSSL_free(buf);\n\n    return str;\n}\n\n/*\n * call-seq:\n *    name.to_s => string\n *    name.to_s(integer) => string\n */\nstatic VALUE\nossl_x509name_to_s(int argc, VALUE *argv, VALUE self)\n{\n    X509_NAME *name;\n    VALUE flag, str;\n    BIO *out;\n    unsigned long iflag;\n\n    rb_scan_args(argc, argv, \"01\", &flag);\n    if (NIL_P(flag))\n\treturn ossl_x509name_to_s_old(self);\n    else iflag = NUM2ULONG(flag);\n    if (!(out = BIO_new(BIO_s_mem())))\n\tossl_raise(eX509NameError, NULL);\n    GetX509Name(self, name);\n    if (!X509_NAME_print_ex(out, name, 0, iflag)){\n\tBIO_free(out);\n\tossl_raise(eX509NameError, NULL);\n    }\n    str = ossl_membio2str(out);\n\n    return str;\n}\n\n/*\n * call-seq:\n *    name.to_a => [[name, data, type], ...]\n */\nstatic VALUE \nossl_x509name_to_a(VALUE self)\n{\n    X509_NAME *name;\n    X509_NAME_ENTRY *entry;\n    int i,entries;\n    char long_name[512];\n    const char *short_name;\n    VALUE ary, ret;\n\t\n    GetX509Name(self, name);\n    entries = X509_NAME_entry_count(name);\n    if (entries < 0) {\n\tOSSL_Debug(\"name entries < 0!\");\n\treturn rb_ary_new();\n    }\n    ret = rb_ary_new2(entries);\n    for (i=0; i<entries; i++) {\n\tif (!(entry = X509_NAME_get_entry(name, i))) {\n\t    ossl_raise(eX509NameError, NULL);\n\t}\n\tif (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object)) {\n\t    ossl_raise(eX509NameError, NULL);\n\t}\n\tshort_name = OBJ_nid2sn(OBJ_ln2nid(long_name));\n\tary = rb_ary_new3(3, rb_str_new2(short_name),\n        \t\t  rb_str_new(entry->value->data, entry->value->length),\n        \t\t  INT2FIX(entry->value->type));\n\trb_ary_push(ret, ary);\n    }\n    return ret;\n}\n\nstatic int\nossl_x509name_cmp0(VALUE self, VALUE other)\n{\n    X509_NAME *name1, *name2;\n\n    GetX509Name(self, name1);\n    SafeGetX509Name(other, name2);\n\n    return X509_NAME_cmp(name1, name2);\n}\n\nstatic VALUE\nossl_x509name_cmp(VALUE self, VALUE other)\n{\n    int result;\n\n    result = ossl_x509name_cmp0(self, other);\n    if (result < 0) return INT2FIX(-1);\n    if (result > 1) return INT2FIX(1);\n\n    return INT2FIX(0);\n}\n\nstatic VALUE\nossl_x509name_eql(VALUE self, VALUE other)\n{\n    int result;\n\n    if(CLASS_OF(other) != cX509Name) return Qfalse;\n    result = ossl_x509name_cmp0(self, other);\n\n    return (result == 0) ? Qtrue : Qfalse;\n}\n\n/*\n * call-seq:\n *    name.hash => integer\n */\nstatic VALUE\nossl_x509name_hash(VALUE self)\n{\n    X509_NAME *name;\n    unsigned long hash;\n\n    GetX509Name(self, name);\n\n    hash = X509_NAME_hash(name);\n\n    return ULONG2NUM(hash);\n}\n\n/*\n * call-seq:\n *    name.to_der => string\n */\nstatic VALUE\nossl_x509name_to_der(VALUE self)\n{\n    X509_NAME *name;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetX509Name(self, name);\n    if((len = i2d_X509_NAME(name, NULL)) <= 0)\n\tossl_raise(eX509NameError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if(i2d_X509_NAME(name, &p) <= 0)\n\tossl_raise(eX509NameError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\n/*\n * INIT\n */\nvoid \nInit_ossl_x509name()\n{\n    VALUE utf8str, ptrstr, ia5str, hash;\n\n    id_aref = rb_intern(\"[]\");\n    eX509NameError = rb_define_class_under(mX509, \"NameError\", eOSSLError);\n    cX509Name = rb_define_class_under(mX509, \"Name\", rb_cObject);\n\n    rb_define_alloc_func(cX509Name, ossl_x509name_alloc);\n    rb_define_method(cX509Name, \"initialize\", ossl_x509name_initialize, -1);\n    rb_define_method(cX509Name, \"add_entry\", ossl_x509name_add_entry, -1);\n    rb_define_method(cX509Name, \"to_s\", ossl_x509name_to_s, -1);\n    rb_define_method(cX509Name, \"to_a\", ossl_x509name_to_a, 0);\n    rb_define_method(cX509Name, \"cmp\", ossl_x509name_cmp, 1);\n    rb_define_alias(cX509Name, \"<=>\", \"cmp\");\n    rb_define_method(cX509Name, \"eql?\", ossl_x509name_eql, 1);\n    rb_define_method(cX509Name, \"hash\", ossl_x509name_hash, 0);\n    rb_define_method(cX509Name, \"to_der\", ossl_x509name_to_der, 0);\n\n    utf8str = INT2NUM(V_ASN1_UTF8STRING);\n    ptrstr = INT2NUM(V_ASN1_PRINTABLESTRING);\n    ia5str = INT2NUM(V_ASN1_IA5STRING);\n    rb_define_const(cX509Name, \"DEFAULT_OBJECT_TYPE\", utf8str);\n    hash = rb_hash_new();\n    RHASH(hash)->ifnone = utf8str;\n    rb_hash_aset(hash, rb_str_new2(\"C\"), ptrstr);\n    rb_hash_aset(hash, rb_str_new2(\"countryName\"), ptrstr);\n    rb_hash_aset(hash, rb_str_new2(\"serialNumber\"), ptrstr);\n    rb_hash_aset(hash, rb_str_new2(\"dnQualifier\"), ptrstr);\n    rb_hash_aset(hash, rb_str_new2(\"DC\"), ia5str);\n    rb_hash_aset(hash, rb_str_new2(\"domainComponent\"), ia5str);\n    rb_hash_aset(hash, rb_str_new2(\"emailAddress\"), ia5str);\n    rb_define_const(cX509Name, \"OBJECT_TYPE_TEMPLATE\", hash);\n\n    rb_define_const(cX509Name, \"COMPAT\", ULONG2NUM(XN_FLAG_COMPAT));\n    rb_define_const(cX509Name, \"RFC2253\", ULONG2NUM(XN_FLAG_RFC2253));\n    rb_define_const(cX509Name, \"ONELINE\", ULONG2NUM(XN_FLAG_ONELINE));\n    rb_define_const(cX509Name, \"MULTILINE\", ULONG2NUM(XN_FLAG_MULTILINE));\n}\n"
  },
  {
    "path": "ext/openssl/ossl_x509req.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509Req(klass, obj, req) do { \\\n    if (!req) { \\\n\tossl_raise(rb_eRuntimeError, \"Req wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_REQ_free, req); \\\n} while (0)\n#define GetX509Req(obj, req) do { \\\n    Data_Get_Struct(obj, X509_REQ, req); \\\n    if (!req) { \\\n\tossl_raise(rb_eRuntimeError, \"Req wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509Req(obj, req) do { \\\n    OSSL_Check_Kind(obj, cX509Req); \\\n    GetX509Req(obj, req); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509Req;\nVALUE eX509ReqError;\n\n/*\n * Public functions\n */\nVALUE\nossl_x509req_new(X509_REQ *req)\n{\n    X509_REQ *new;\n    VALUE obj;\n\n    if (!req) {\n\tnew = X509_REQ_new();\n    } else {\n\tnew = X509_REQ_dup(req);\n    }\n    if (!new) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    WrapX509Req(cX509Req, obj, new);\n\n    return obj;\n}\n\nX509_REQ *\nGetX509ReqPtr(VALUE obj)\n{\n    X509_REQ *req;\n\n    SafeGetX509Req(obj, req);\n\n    return req;\n}\n\nX509_REQ *\nDupX509ReqPtr(VALUE obj)\n{\n    X509_REQ *req, *new;\n\n    SafeGetX509Req(obj, req);\n    if (!(new = X509_REQ_dup(req))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return new;\n}\n\n/*\n * Private functions\n */\nstatic VALUE \nossl_x509req_alloc(VALUE klass)\n{\n    X509_REQ *req;\n    VALUE obj;\n\n    if (!(req = X509_REQ_new())) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    WrapX509Req(klass, obj, req);\n\n    return obj;\n}\n\nstatic VALUE \nossl_x509req_initialize(int argc, VALUE *argv, VALUE self)\n{\n    BIO *in;\n    X509_REQ *req;\n    VALUE arg;\n\n    if (rb_scan_args(argc, argv, \"01\", &arg) == 0) {\n\treturn self;\n    }\n    arg = ossl_to_der_if_possible(arg);\n    in = ossl_obj2bio(arg);\n    req = PEM_read_bio_X509_REQ(in, (X509_REQ **)&DATA_PTR(self), NULL, NULL);\n    if (!req) {\n\tBIO_reset(in);\n\treq = d2i_X509_REQ_bio(in, (X509_REQ **)&DATA_PTR(self));\n    }\n    BIO_free(in);\n    if (!req) ossl_raise(eX509ReqError, NULL);\n\n    return self;\n}\n\nstatic VALUE\nossl_x509req_copy(VALUE self, VALUE other)\n{\n    X509_REQ *a, *b, *req;\n\t\n    rb_check_frozen(self);\n    if (self == other) return self;\n    GetX509Req(self, a);\n    SafeGetX509Req(other, b);\n    if (!(req = X509_REQ_dup(b))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    X509_REQ_free(a);\n    DATA_PTR(self) = req;\n\n    return self;\n}\n\nstatic VALUE \nossl_x509req_to_pem(VALUE self)\n{\n    X509_REQ *req;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\t\n    GetX509Req(self, req);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    if (!PEM_write_bio_X509_REQ(out, req)) {\n\tBIO_free(out);\n\tossl_raise(eX509ReqError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n\n    return str;\n}\n\nstatic VALUE\nossl_x509req_to_der(VALUE self)\n{\n    X509_REQ *req;\n    VALUE str;\n    long len;\n    unsigned char *p;\n\n    GetX509Req(self, req);\n    if ((len = i2d_X509_REQ(req, NULL)) <= 0)\n\tossl_raise(eX509CertError, NULL);\n    str = rb_str_new(0, len);\n    p = RSTRING_PTR(str);\n    if (i2d_X509_REQ(req, &p) <= 0)\n\tossl_raise(eX509ReqError, NULL);\n    ossl_str_adjust(str, p);\n\n    return str;\n}\n\nstatic VALUE \nossl_x509req_to_text(VALUE self)\n{\n    X509_REQ *req;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\n    GetX509Req(self, req);\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    if (!X509_REQ_print(out, req)) {\n\tBIO_free(out);\n\tossl_raise(eX509ReqError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n\n    return str;\n}\n\n#if 0\n/*\n * Makes X509 from X509_REQuest\n */\nstatic VALUE \nossl_x509req_to_x509(VALUE self, VALUE days, VALUE key)\n{\n    X509_REQ *req;\n    X509 *x509;\n\t\n    GetX509Req(self, req);\n    ...\n    if (!(x509 = X509_REQ_to_X509(req, d, pkey))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return ossl_x509_new(x509);\n}\n#endif\n\nstatic VALUE \nossl_x509req_get_version(VALUE self)\n{\n    X509_REQ *req;\n    long version;\n\n    GetX509Req(self, req);\n    version = X509_REQ_get_version(req);\n\n    return LONG2FIX(version);\n}\n\nstatic VALUE \nossl_x509req_set_version(VALUE self, VALUE version)\n{\n    X509_REQ *req;\n    long ver;\n\n    if ((ver = FIX2LONG(version)) < 0) {\n\tossl_raise(eX509ReqError, \"version must be >= 0!\");\n    }\n    GetX509Req(self, req);\n    if (!X509_REQ_set_version(req, ver)) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return version;\n}\n\nstatic VALUE \nossl_x509req_get_subject(VALUE self)\n{\n    X509_REQ *req;\n    X509_NAME *name;\n\n    GetX509Req(self, req);\n    if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return ossl_x509name_new(name);\n}\n\nstatic VALUE \nossl_x509req_set_subject(VALUE self, VALUE subject)\n{\n    X509_REQ *req;\n\t\n    GetX509Req(self, req);\n    /* DUPs name */\n    if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return subject;\n}\n\nstatic VALUE \nossl_x509req_get_signature_algorithm(VALUE self)\n{\n    X509_REQ *req;\n    BIO *out;\n    BUF_MEM *buf;\n    VALUE str;\n\n    GetX509Req(self, req);\n\t\n    if (!(out = BIO_new(BIO_s_mem()))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    if (!i2a_ASN1_OBJECT(out, req->sig_alg->algorithm)) {\n\tBIO_free(out);\n\tossl_raise(eX509ReqError, NULL);\n    }\n    BIO_get_mem_ptr(out, &buf);\n    str = rb_str_new(buf->data, buf->length);\n    BIO_free(out);\n    return str;\n}\n\nstatic VALUE \nossl_x509req_get_public_key(VALUE self)\n{\n    X509_REQ *req;\n    EVP_PKEY *pkey;\n\n    GetX509Req(self, req);\n    if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return ossl_pkey_new(pkey); /* NO DUP - OK */\n}\n\nstatic VALUE \nossl_x509req_set_public_key(VALUE self, VALUE key)\n{\n    X509_REQ *req;\n    EVP_PKEY *pkey;\n\n    GetX509Req(self, req);\n    pkey = GetPKeyPtr(key); /* NO NEED TO DUP */\n    if (!X509_REQ_set_pubkey(req, pkey)) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return key;\n}\n\nstatic VALUE \nossl_x509req_sign(VALUE self, VALUE key, VALUE digest)\n{\n    X509_REQ *req;\n    EVP_PKEY *pkey;\n    const EVP_MD *md;\n\n    GetX509Req(self, req);\n    pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */\n    md = GetDigestPtr(digest);\n    if (!X509_REQ_sign(req, pkey, md)) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return self;\n}\n\n/*\n * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'\n */\nstatic VALUE \nossl_x509req_verify(VALUE self, VALUE key)\n{\n    X509_REQ *req;\n    EVP_PKEY *pkey;\n    int i;\n\n    GetX509Req(self, req);\n    pkey = GetPKeyPtr(key); /* NO NEED TO DUP */\n    if ((i = X509_REQ_verify(req, pkey)) < 0) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n    if (i > 0) {\n\treturn Qtrue;\n    }\n\n    return Qfalse;\n}\n\nstatic VALUE \nossl_x509req_get_attributes(VALUE self)\n{\n    X509_REQ *req;\n    int count, i;\n    X509_ATTRIBUTE *attr;\n    VALUE ary;\n\t\n    GetX509Req(self, req);\n\n    count = X509_REQ_get_attr_count(req);\n    if (count < 0) {\n\tOSSL_Debug(\"count < 0???\");\n\treturn rb_ary_new();\n    }\n    ary = rb_ary_new2(count);\n    for (i=0; i<count; i++) {\n\tattr = X509_REQ_get_attr(req, i);\n\trb_ary_push(ary, ossl_x509attr_new(attr));\n    }\n\n    return ary;\n}\n\nstatic VALUE \nossl_x509req_set_attributes(VALUE self, VALUE ary)\n{\n    X509_REQ *req;\n    X509_ATTRIBUTE *attr;\n    int i;\n    VALUE item;\n\n    Check_Type(ary, T_ARRAY);\n    for (i=0;i<RARRAY_LEN(ary); i++) {\n\tOSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Attr);\n    }\n    GetX509Req(self, req);\n    sk_X509_ATTRIBUTE_pop_free(req->req_info->attributes, X509_ATTRIBUTE_free);\n    req->req_info->attributes = NULL;\n    for (i=0;i<RARRAY_LEN(ary); i++) {\n\titem = RARRAY_PTR(ary)[i];\n\tattr = DupX509AttrPtr(item);\n\tif (!X509_REQ_add1_attr(req, attr)) {\n\t    ossl_raise(eX509ReqError, NULL);\n\t}\n    }\n    return ary;\n}\n\nstatic VALUE \nossl_x509req_add_attribute(VALUE self, VALUE attr)\n{\n    X509_REQ *req;\n\n    GetX509Req(self, req);\n    if (!X509_REQ_add1_attr(req, DupX509AttrPtr(attr))) {\n\tossl_raise(eX509ReqError, NULL);\n    }\n\n    return attr;\n}\n\n/*\n * X509_REQUEST init\n */\nvoid \nInit_ossl_x509req()\n{\n    eX509ReqError = rb_define_class_under(mX509, \"RequestError\", eOSSLError);\n\t\n    cX509Req = rb_define_class_under(mX509, \"Request\", rb_cObject);\n\t\n    rb_define_alloc_func(cX509Req, ossl_x509req_alloc);\n    rb_define_method(cX509Req, \"initialize\", ossl_x509req_initialize, -1);\n    rb_define_copy_func(cX509Req, ossl_x509req_copy);\n\t\n    rb_define_method(cX509Req, \"to_pem\", ossl_x509req_to_pem, 0);\n    rb_define_method(cX509Req, \"to_der\", ossl_x509req_to_der, 0);\n    rb_define_alias(cX509Req, \"to_s\", \"to_pem\");\n    rb_define_method(cX509Req, \"to_text\", ossl_x509req_to_text, 0);\n    rb_define_method(cX509Req, \"version\", ossl_x509req_get_version, 0);\n    rb_define_method(cX509Req, \"version=\", ossl_x509req_set_version, 1);\n    rb_define_method(cX509Req, \"subject\", ossl_x509req_get_subject, 0);\n    rb_define_method(cX509Req, \"subject=\", ossl_x509req_set_subject, 1);\n    rb_define_method(cX509Req, \"signature_algorithm\", ossl_x509req_get_signature_algorithm, 0);\n    rb_define_method(cX509Req, \"public_key\", ossl_x509req_get_public_key, 0);\n    rb_define_method(cX509Req, \"public_key=\", ossl_x509req_set_public_key, 1);\n    rb_define_method(cX509Req, \"sign\", ossl_x509req_sign, 2);\n    rb_define_method(cX509Req, \"verify\", ossl_x509req_verify, 1);\n    rb_define_method(cX509Req, \"attributes\", ossl_x509req_get_attributes, 0);\n    rb_define_method(cX509Req, \"attributes=\", ossl_x509req_set_attributes, 1);\n    rb_define_method(cX509Req, \"add_attribute\", ossl_x509req_add_attribute, 1);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_x509revoked.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n\n#define WrapX509Rev(klass, obj, rev) do { \\\n    if (!rev) { \\\n\tossl_raise(rb_eRuntimeError, \"REV wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_REVOKED_free, rev); \\\n} while (0)\n#define GetX509Rev(obj, rev) do { \\\n    Data_Get_Struct(obj, X509_REVOKED, rev); \\\n    if (!rev) { \\\n\tossl_raise(rb_eRuntimeError, \"REV wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509Rev(obj, rev) do { \\\n    OSSL_Check_Kind(obj, cX509Rev); \\\n    GetX509Rev(obj, rev); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509Rev;\nVALUE eX509RevError;\n\n/*\n * PUBLIC\n */\nVALUE \nossl_x509revoked_new(X509_REVOKED *rev)\n{\n    X509_REVOKED *new;\n    VALUE obj;\n\n    if (!rev) {\n\tnew = X509_REVOKED_new();\n    } else {\n\tnew = X509_REVOKED_dup(rev);\n    }\n    if (!new) {\n\tossl_raise(eX509RevError, NULL);\n    }\n    WrapX509Rev(cX509Rev, obj, new);\n\n    return obj;\n}\n\nX509_REVOKED *\nDupX509RevokedPtr(VALUE obj)\n{\n    X509_REVOKED *rev, *new;\n\n    SafeGetX509Rev(obj, rev);\n    if (!(new = X509_REVOKED_dup(rev))) {\n\tossl_raise(eX509RevError, NULL);\n    }\n\n    return new;\n}\n\n/*\n * PRIVATE\n */\nstatic VALUE \nossl_x509revoked_alloc(VALUE klass)\n{\n    X509_REVOKED *rev;\n    VALUE obj;\n\n    if (!(rev = X509_REVOKED_new())) {\n\tossl_raise(eX509RevError, NULL);\n    }\n    WrapX509Rev(klass, obj, rev);\n\n    return obj;\n}\n\nstatic VALUE \nossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self)\n{\n    /* EMPTY */\n    return self;\n}\n\nstatic VALUE \nossl_x509revoked_get_serial(VALUE self)\n{\n    X509_REVOKED *rev;\n\n    GetX509Rev(self, rev);\n\n    return asn1integer_to_num(rev->serialNumber);\n}\n\nstatic VALUE \nossl_x509revoked_set_serial(VALUE self, VALUE num)\n{\n    X509_REVOKED *rev;\n\n    GetX509Rev(self, rev);\n    rev->serialNumber = num_to_asn1integer(num, rev->serialNumber);\n\n    return num;\n}\n\nstatic VALUE \nossl_x509revoked_get_time(VALUE self)\n{\n    X509_REVOKED *rev;\n\t\n    GetX509Rev(self, rev);\n\n    return asn1time_to_time(rev->revocationDate);\n}\n\nstatic VALUE \nossl_x509revoked_set_time(VALUE self, VALUE time)\n{\n    X509_REVOKED *rev;\n    time_t sec;\n\n    sec = time_to_time_t(time);\n    GetX509Rev(self, rev);\n    if (!X509_time_adj(rev->revocationDate, 0, &sec)) {\n\tossl_raise(eX509RevError, NULL);\n    }\n\n    return time;\n}\n/*\n * Gets X509v3 extensions as array of X509Ext objects\n */\nstatic VALUE \nossl_x509revoked_get_extensions(VALUE self)\n{\n    X509_REVOKED *rev;\n    int count, i;\n    X509_EXTENSION *ext;\n    VALUE ary;\n\n    GetX509Rev(self, rev);\n    count = X509_REVOKED_get_ext_count(rev);\n    if (count < 0) {\n\tOSSL_Debug(\"count < 0???\");\n\treturn rb_ary_new();\n    }\n    ary = rb_ary_new2(count);\n    for (i=0; i<count; i++) {\n\text = X509_REVOKED_get_ext(rev, i);\n\trb_ary_push(ary, ossl_x509ext_new(ext));\n    }\n\n    return ary;\n}\n\n/*\n * Sets X509_EXTENSIONs\n */\nstatic VALUE \nossl_x509revoked_set_extensions(VALUE self, VALUE ary)\n{\n    X509_REVOKED *rev;\n    X509_EXTENSION *ext;\n    int i;\n    VALUE item;\n\n    Check_Type(ary, T_ARRAY);\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\tOSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);\n    }\n    GetX509Rev(self, rev);\n    sk_X509_EXTENSION_pop_free(rev->extensions, X509_EXTENSION_free);\n    rev->extensions = NULL;\n    for (i=0; i<RARRAY_LEN(ary); i++) {\n\titem = RARRAY_PTR(ary)[i];\n\text = DupX509ExtPtr(item);\n\tif(!X509_REVOKED_add_ext(rev, ext, -1)) {\n\t    ossl_raise(eX509RevError, NULL);\n\t}\n    }\n\n    return ary;\n}\n\nstatic VALUE\nossl_x509revoked_add_extension(VALUE self, VALUE ext)\n{\n    X509_REVOKED *rev;\n    \n    GetX509Rev(self, rev);\n    if(!X509_REVOKED_add_ext(rev, DupX509ExtPtr(ext), -1)) {\n\tossl_raise(eX509RevError, NULL);\n    }\n\n    return ext;\n}\n\n/*\n * INIT\n */\nvoid\nInit_ossl_x509revoked()\n{\n    eX509RevError = rb_define_class_under(mX509, \"RevokedError\", eOSSLError);\n\n    cX509Rev = rb_define_class_under(mX509, \"Revoked\", rb_cObject);\n\t\n    rb_define_alloc_func(cX509Rev, ossl_x509revoked_alloc);\n    rb_define_method(cX509Rev, \"initialize\", ossl_x509revoked_initialize, -1);\n\t\n    rb_define_method(cX509Rev, \"serial\", ossl_x509revoked_get_serial, 0);\n    rb_define_method(cX509Rev, \"serial=\", ossl_x509revoked_set_serial, 1);\n    rb_define_method(cX509Rev, \"time\", ossl_x509revoked_get_time, 0);\n    rb_define_method(cX509Rev, \"time=\", ossl_x509revoked_set_time, 1);\n    rb_define_method(cX509Rev, \"extensions\", ossl_x509revoked_get_extensions, 0);\n    rb_define_method(cX509Rev, \"extensions=\", ossl_x509revoked_set_extensions, 1);\n    rb_define_method(cX509Rev, \"add_extension\", ossl_x509revoked_add_extension, 1);\n}\n\n"
  },
  {
    "path": "ext/openssl/ossl_x509store.c",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#include \"ossl.h\"\n#include <rubysig.h>\n\n#define WrapX509Store(klass, obj, st) do { \\\n    if (!st) { \\\n\tossl_raise(rb_eRuntimeError, \"STORE wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, X509_STORE_free, st); \\\n} while (0)\n#define GetX509Store(obj, st) do { \\\n    Data_Get_Struct(obj, X509_STORE, st); \\\n    if (!st) { \\\n\tossl_raise(rb_eRuntimeError, \"STORE wasn't initialized!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509Store(obj, st) do { \\\n    OSSL_Check_Kind(obj, cX509Store); \\\n    GetX509Store(obj, st); \\\n} while (0)\n\n#define WrapX509StCtx(klass, obj, ctx) do { \\\n    if (!ctx) { \\\n\tossl_raise(rb_eRuntimeError, \"STORE_CTX wasn't initialized!\"); \\\n    } \\\n    obj = Data_Wrap_Struct(klass, 0, ossl_x509stctx_free, ctx); \\\n} while (0)\n#define GetX509StCtx(obj, ctx) do { \\\n    Data_Get_Struct(obj, X509_STORE_CTX, ctx); \\\n    if (!ctx) { \\\n\tossl_raise(rb_eRuntimeError, \"STORE_CTX is out of scope!\"); \\\n    } \\\n} while (0)\n#define SafeGetX509StCtx(obj, storep) do { \\\n    OSSL_Check_Kind(obj, cX509StoreContext); \\\n    GetX509Store(obj, ctx); \\\n} while (0)\n\n/*\n * Classes\n */\nVALUE cX509Store;\nVALUE cX509StoreContext;\nVALUE eX509StoreError;\n\n/*\n * Public functions\n */\nVALUE \nossl_x509store_new(X509_STORE *store)\n{\n    VALUE obj;\n\n    WrapX509Store(cX509Store, obj, store);\n\n    return obj;\n}\n\nX509_STORE *\nGetX509StorePtr(VALUE obj)\n{\n    X509_STORE *store;\n\n    SafeGetX509Store(obj, store);\n\n    return store;\n}\n\nX509_STORE *\nDupX509StorePtr(VALUE obj)\n{   \n    X509_STORE *store;\n\n    SafeGetX509Store(obj, store);\n    CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);\n    \n    return store;\n}\n\n/*\n * Private functions\n */\nstatic VALUE \nossl_x509store_alloc(VALUE klass)\n{\n    X509_STORE *store;\n    VALUE obj;\n\n    if((store = X509_STORE_new()) == NULL){\n        ossl_raise(eX509StoreError, NULL);\n    }\n    WrapX509Store(klass, obj, store);\n\n    return obj;\n}\n\n/*\n * General callback for OpenSSL verify\n */\nstatic VALUE\nossl_x509store_set_vfy_cb(VALUE self, VALUE cb)\n{\n    X509_STORE *store;\n\n    GetX509Store(self, store);\n    X509_STORE_set_ex_data(store, ossl_verify_cb_idx, (void*)cb);\n    rb_iv_set(self, \"@verify_callback\", cb);\n\n    return cb;\n}\n\n\n/*\n * call-seq:\n *    X509::Store.new => store\n *\n */\nstatic VALUE\nossl_x509store_initialize(int argc, VALUE *argv, VALUE self)\n{\n    X509_STORE *store;\n\n/* BUG: This method takes any number of arguments but appears to ignore them. */\n    GetX509Store(self, store);\n    X509_STORE_set_verify_cb_func(store, ossl_verify_cb);\n    ossl_x509store_set_vfy_cb(self, Qnil);\n\n#if (OPENSSL_VERSION_NUMBER < 0x00907000L)\n    rb_iv_set(self, \"@flags\", INT2NUM(0));\n    rb_iv_set(self, \"@purpose\", INT2NUM(0));\n    rb_iv_set(self, \"@trust\", INT2NUM(0));\n#endif\n\n    /* last verification status */\n    rb_iv_set(self, \"@error\", Qnil);\n    rb_iv_set(self, \"@error_string\", Qnil);\n    rb_iv_set(self, \"@chain\", Qnil);\n    rb_iv_set(self, \"@time\", Qnil);\n\n    return self;\n}\n\nstatic VALUE\nossl_x509store_set_flags(VALUE self, VALUE flags)\n{\n#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)\n    X509_STORE *store;\n    long f = NUM2LONG(flags);\n\n    GetX509Store(self, store);\n    X509_STORE_set_flags(store, f);\n#else\n    rb_iv_set(self, \"@flags\", flags);\n#endif\n\n    return flags;\n}\n\nstatic VALUE\nossl_x509store_set_purpose(VALUE self, VALUE purpose)\n{\n#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)\n    X509_STORE *store;\n    long p = NUM2LONG(purpose);\n    \n    GetX509Store(self, store);\n    X509_STORE_set_purpose(store, p);\n#else\n    rb_iv_set(self, \"@purpose\", purpose);\n#endif\n\n    return purpose;\n}\n\nstatic VALUE\nossl_x509store_set_trust(VALUE self, VALUE trust)\n{\n#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)\n    X509_STORE *store;\n    long t = NUM2LONG(trust);\n\n    GetX509Store(self, store);\n    X509_STORE_set_trust(store, t);\n#else\n    rb_iv_set(self, \"@trust\", trust);\n#endif\n\n    return trust;\n}\n\nstatic VALUE \nossl_x509store_set_time(VALUE self, VALUE time)\n{\n    rb_iv_set(self, \"@time\", time);\n    return time;\n}\n\nstatic VALUE \nossl_x509store_add_file(VALUE self, VALUE file)\n{\n    X509_STORE *store;\n    X509_LOOKUP *lookup;\n    char *path = NULL;\n\n    if(file != Qnil){\n        Check_SafeStr(file);\n\tpath = RSTRING_PTR(file);\n    }\n    GetX509Store(self, store);\n    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());\n    if(lookup == NULL) ossl_raise(eX509StoreError, NULL);\n    if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){\n        ossl_raise(eX509StoreError, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE \nossl_x509store_add_path(VALUE self, VALUE dir)\n{\n    X509_STORE *store;\n    X509_LOOKUP *lookup;\n    char *path = NULL;\n\n    if(dir != Qnil){\n        Check_SafeStr(dir);\n\tpath = RSTRING_PTR(dir);\n    }\n    GetX509Store(self, store);\n    lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());\n    if(lookup == NULL) ossl_raise(eX509StoreError, NULL);\n    if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){\n        ossl_raise(eX509StoreError, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_x509store_set_default_paths(VALUE self)\n{\n    X509_STORE *store;\n\n    GetX509Store(self, store);\n    if (X509_STORE_set_default_paths(store) != 1){\n        ossl_raise(eX509StoreError, NULL);\n    }\n\n    return Qnil;\n}\n\nstatic VALUE\nossl_x509store_add_cert(VALUE self, VALUE arg)\n{\n    X509_STORE *store;\n    X509 *cert;\n\n    cert = GetX509CertPtr(arg); /* NO NEED TO DUP */\n    GetX509Store(self, store);\n    if (X509_STORE_add_cert(store, cert) != 1){\n        ossl_raise(eX509StoreError, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE\nossl_x509store_add_crl(VALUE self, VALUE arg)\n{\n    X509_STORE *store;\n    X509_CRL *crl;\n\n    crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */\n    GetX509Store(self, store);\n    if (X509_STORE_add_crl(store, crl) != 1){\n        ossl_raise(eX509StoreError, NULL);\n    }\n\n    return self;\n}\n\nstatic VALUE ossl_x509stctx_get_err(VALUE);\nstatic VALUE ossl_x509stctx_get_err_string(VALUE);\nstatic VALUE ossl_x509stctx_get_chain(VALUE);\n\nstatic VALUE \nossl_x509store_verify(int argc, VALUE *argv, VALUE self)\n{\n    VALUE cert, chain;\n    VALUE ctx, proc, result;\n\n    rb_scan_args(argc, argv, \"11\", &cert, &chain);\n    ctx = rb_funcall(cX509StoreContext, rb_intern(\"new\"), 3, self, cert, chain);\n    proc = rb_block_given_p() ?  rb_block_proc() :\n\t   rb_iv_get(self, \"@verify_callback\");\n    rb_iv_set(ctx, \"@verify_callback\", proc);\n    result = rb_funcall(ctx, rb_intern(\"verify\"), 0);\n\n    rb_iv_set(self, \"@error\", ossl_x509stctx_get_err(ctx));\n    rb_iv_set(self, \"@error_string\", ossl_x509stctx_get_err_string(ctx));\n    rb_iv_set(self, \"@chain\", ossl_x509stctx_get_chain(ctx));\n\n    return result;\n}\n\n/*\n * Public Functions\n */\nstatic void ossl_x509stctx_free(X509_STORE_CTX*);\n\nVALUE\nossl_x509stctx_new(X509_STORE_CTX *ctx)\n{\n    VALUE obj;\n\n    WrapX509StCtx(cX509StoreContext, obj, ctx);\n\n    return obj;\n}\n\nVALUE\nossl_x509stctx_clear_ptr(VALUE obj)\n{\n    OSSL_Check_Kind(obj, cX509StoreContext);\n    RDATA(obj)->data = NULL;\n\n    return obj;\n}\n\n/*\n * Private functions\n */\nstatic void\nossl_x509stctx_free(X509_STORE_CTX *ctx)\n{\n    if(ctx->untrusted)\n\tsk_X509_pop_free(ctx->untrusted, X509_free);\n    if(ctx->cert)\n\tX509_free(ctx->cert);\n    X509_STORE_CTX_free(ctx);\n}\n\nstatic VALUE \nossl_x509stctx_alloc(VALUE klass)\n{\n    X509_STORE_CTX *ctx;\n    VALUE obj;\n\n    if((ctx = X509_STORE_CTX_new()) == NULL){\n        ossl_raise(eX509StoreError, NULL);\n    }\n    WrapX509StCtx(klass, obj, ctx);\n\n    return obj;\n}\n\nstatic VALUE ossl_x509stctx_set_flags(VALUE, VALUE);\nstatic VALUE ossl_x509stctx_set_purpose(VALUE, VALUE);\nstatic VALUE ossl_x509stctx_set_trust(VALUE, VALUE);\nstatic VALUE ossl_x509stctx_set_time(VALUE, VALUE);\n\nstatic VALUE\nossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)\n{\n    VALUE store, cert, chain, t;\n    X509_STORE_CTX *ctx;\n    X509_STORE *x509st;\n    X509 *x509 = NULL;\n    STACK_OF(X509) *x509s = NULL;\n\n    rb_scan_args(argc, argv, \"12\", &store, &cert, &chain);\n    GetX509StCtx(self, ctx);\n    SafeGetX509Store(store, x509st);\n    if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */\n    if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);\n#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)\n    if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){\n        sk_X509_pop_free(x509s, X509_free);\n        ossl_raise(eX509StoreError, NULL);\n    }\n#else\n    X509_STORE_CTX_init(ctx, x509st, x509, x509s);\n    ossl_x509stctx_set_flags(self, rb_iv_get(store, \"@flags\"));\n    ossl_x509stctx_set_purpose(self, rb_iv_get(store, \"@purpose\"));\n    ossl_x509stctx_set_trust(self, rb_iv_get(store, \"@trust\"));\n#endif\n    if (!NIL_P(t = rb_iv_get(store, \"@time\")))\n\tossl_x509stctx_set_time(self, t);\n    rb_iv_set(self, \"@verify_callback\", rb_iv_get(store, \"@verify_callback\"));\n    rb_iv_set(self, \"@cert\", cert);\n\n    return self;\n}\n\nstatic VALUE\nossl_x509stctx_verify(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n    int result;\n\n    GetX509StCtx(self, ctx);\n    X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx,\n                               (void*)rb_iv_get(self, \"@verify_callback\"));\n    result = X509_verify_cert(ctx);\n\n    return result ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nossl_x509stctx_get_chain(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n    STACK_OF(X509) *chain;\n    X509 *x509;\n    int i, num;\n    VALUE ary;\n\n    GetX509StCtx(self, ctx);\n    if((chain = X509_STORE_CTX_get_chain(ctx)) == NULL){\n        return Qnil;\n    }\n    if((num = sk_X509_num(chain)) < 0){\n\tOSSL_Debug(\"certs in chain < 0???\");\n\treturn rb_ary_new();\n    }\n    ary = rb_ary_new2(num);\n    for(i = 0; i < num; i++) {\n\tx509 = sk_X509_value(chain, i);\n\trb_ary_push(ary, ossl_x509_new(x509));\n    }\n\n    return ary;\n}\n\nstatic VALUE \nossl_x509stctx_get_err(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n\n    GetX509StCtx(self, ctx);\n\n    return INT2FIX(X509_STORE_CTX_get_error(ctx));\n}\n\nstatic VALUE\nossl_x509stctx_set_error(VALUE self, VALUE err)\n{\n    X509_STORE_CTX *ctx;\n\n    GetX509StCtx(self, ctx);\n    X509_STORE_CTX_set_error(ctx, NUM2INT(err));\n\n    return err;\n}\n\nstatic VALUE \nossl_x509stctx_get_err_string(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n    long err;\n\n    GetX509StCtx(self, ctx);\n    err = X509_STORE_CTX_get_error(ctx);\n\n    return rb_str_new2(X509_verify_cert_error_string(err));\n}\n\nstatic VALUE \nossl_x509stctx_get_err_depth(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n\n    GetX509StCtx(self, ctx);\n\n    return INT2FIX(X509_STORE_CTX_get_error_depth(ctx));\n}\n\nstatic VALUE \nossl_x509stctx_get_curr_cert(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n\n    GetX509StCtx(self, ctx);\n\n    return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));\n}\n\nstatic VALUE\nossl_x509stctx_get_curr_crl(VALUE self)\n{\n#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)\n    X509_STORE_CTX *ctx;\n\n    GetX509StCtx(self, ctx);\n    if(!ctx->current_crl) return Qnil;\n\n    return ossl_x509crl_new(ctx->current_crl);\n#else\n    return Qnil;\n#endif\n}\n\nstatic VALUE\nossl_x509stctx_cleanup(VALUE self)\n{\n    X509_STORE_CTX *ctx;\n\n    GetX509StCtx(self, ctx);\n    X509_STORE_CTX_cleanup(ctx);\n\n    return self;\n}\n\nstatic VALUE\nossl_x509stctx_set_flags(VALUE self, VALUE flags)\n{\n    X509_STORE_CTX *store;\n    long f = NUM2LONG(flags);\n\n    GetX509StCtx(self, store);\n    X509_STORE_CTX_set_flags(store, f);\n\n    return flags;\n}\n\nstatic VALUE\nossl_x509stctx_set_purpose(VALUE self, VALUE purpose)\n{\n    X509_STORE_CTX *store;\n    long p = NUM2LONG(purpose);\n\n    GetX509StCtx(self, store);\n    X509_STORE_CTX_set_purpose(store, p);\n\n    return purpose;\n}\n\nstatic VALUE\nossl_x509stctx_set_trust(VALUE self, VALUE trust)\n{\n    X509_STORE_CTX *store;\n    long t = NUM2LONG(trust);\n\n    GetX509StCtx(self, store);\n    X509_STORE_CTX_set_trust(store, t);\n\n    return trust;\n}\n\n/*\n * call-seq:\n *    storectx.time = time => time\n */\nstatic VALUE\nossl_x509stctx_set_time(VALUE self, VALUE time)\n{\n    X509_STORE_CTX *store;\n    long t;\n\n    t = NUM2LONG(rb_Integer(time));\n    GetX509StCtx(self, store);\n    X509_STORE_CTX_set_time(store, 0, t);\n\n    return time;\n}\n\n/*\n * INIT\n */\nvoid \nInit_ossl_x509store()\n{\n    VALUE x509stctx;\n\n    eX509StoreError = rb_define_class_under(mX509, \"StoreError\", eOSSLError);\n\n    cX509Store = rb_define_class_under(mX509, \"Store\", rb_cObject);\n    rb_attr(cX509Store, rb_intern(\"verify_callback\"), 1, 0, Qfalse);\n    rb_attr(cX509Store, rb_intern(\"error\"), 1, 0, Qfalse);\n    rb_attr(cX509Store, rb_intern(\"error_string\"), 1, 0, Qfalse);\n    rb_attr(cX509Store, rb_intern(\"chain\"), 1, 0, Qfalse);\n    rb_define_alloc_func(cX509Store, ossl_x509store_alloc);\n    rb_define_method(cX509Store, \"initialize\",   ossl_x509store_initialize, -1);\n    rb_define_method(cX509Store, \"verify_callback=\", ossl_x509store_set_vfy_cb, 1);\n    rb_define_method(cX509Store, \"flags=\",       ossl_x509store_set_flags, 1);\n    rb_define_method(cX509Store, \"purpose=\",     ossl_x509store_set_purpose, 1);\n    rb_define_method(cX509Store, \"trust=\",       ossl_x509store_set_trust, 1);\n    rb_define_method(cX509Store, \"time=\",        ossl_x509store_set_time, 1);\n    rb_define_method(cX509Store, \"add_path\",     ossl_x509store_add_path, 1);\n    rb_define_method(cX509Store, \"add_file\",     ossl_x509store_add_file, 1);\n    rb_define_method(cX509Store, \"set_default_paths\", ossl_x509store_set_default_paths, 0);\n    rb_define_method(cX509Store, \"add_cert\",     ossl_x509store_add_cert, 1);\n    rb_define_method(cX509Store, \"add_crl\",      ossl_x509store_add_crl, 1);\n    rb_define_method(cX509Store, \"verify\",       ossl_x509store_verify, -1);\n\n    cX509StoreContext = rb_define_class_under(mX509,\"StoreContext\",rb_cObject);\n    x509stctx = cX509StoreContext;\n    rb_define_alloc_func(cX509StoreContext, ossl_x509stctx_alloc);\n    rb_define_method(x509stctx,\"initialize\",  ossl_x509stctx_initialize, -1);\n    rb_define_method(x509stctx,\"verify\",      ossl_x509stctx_verify, 0);\n    rb_define_method(x509stctx,\"chain\",       ossl_x509stctx_get_chain,0);\n    rb_define_method(x509stctx,\"error\",       ossl_x509stctx_get_err, 0);\n    rb_define_method(x509stctx,\"error=\",      ossl_x509stctx_set_error, 1);\n    rb_define_method(x509stctx,\"error_string\",ossl_x509stctx_get_err_string,0);\n    rb_define_method(x509stctx,\"error_depth\", ossl_x509stctx_get_err_depth, 0);\n    rb_define_method(x509stctx,\"current_cert\",ossl_x509stctx_get_curr_cert, 0);\n    rb_define_method(x509stctx,\"current_crl\", ossl_x509stctx_get_curr_crl, 0);\n    rb_define_method(x509stctx,\"cleanup\",     ossl_x509stctx_cleanup, 0);\n    rb_define_method(x509stctx,\"flags=\",      ossl_x509stctx_set_flags, 1);\n    rb_define_method(x509stctx,\"purpose=\",    ossl_x509stctx_set_purpose, 1);\n    rb_define_method(x509stctx,\"trust=\",      ossl_x509stctx_set_trust, 1);\n    rb_define_method(x509stctx,\"time=\",       ossl_x509stctx_set_time, 1);\n\n}\n"
  },
  {
    "path": "ext/openssl/ruby_missing.h",
    "content": "/*\n * $Id$\n * 'OpenSSL for Ruby' project\n * Copyright (C) 2001-2003  Michal Rokos <m.rokos@sh.cvut.cz>\n * All rights reserved.\n */\n/*\n * This program is licenced under the same licence as Ruby.\n * (See the file 'LICENCE'.)\n */\n#if !defined(_OSSL_RUBY_MISSING_H_)\n#define _OSSL_RUBY_MISSING_H_\n\n#define rb_define_copy_func(klass, func) \\\n\trb_define_method(klass, \"initialize_copy\", func, 1)\n\n\n#ifndef GetReadFile\n#define FPTR_TO_FD(fptr) (fptr->fd)\n#else\n#define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))\n#endif\n\n#ifndef HAVE_RB_IO_T\n#define rb_io_t OpenFile\n#endif\n\n#ifndef HAVE_RB_STR_SET_LEN\n/* these methods should probably be backported to 1.8 */\n#define rb_str_set_len(str, length) do {\t\\\n\tRSTRING(str)->ptr[length] = 0;\t\t\\\n\tRSTRING(str)->len = length;\t\t\\\n} while(0)\n#endif /* ! HAVE_RB_STR_SET_LEN */\n\n#ifndef HAVE_RB_BLOCK_CALL\n/* the openssl module doesn't use arg[3-4] and arg2 is always rb_each */\n#define rb_block_call(arg1, arg2, arg3, arg4, arg5, arg6) rb_iterate(rb_each, arg1, arg5, arg6)\n#endif /* ! HAVE_RB_BLOCK_CALL */\n\n#endif /* _OSSL_RUBY_MISSING_H_ */\n"
  },
  {
    "path": "ext/pty/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/pty/README",
    "content": "pty extension version 0.3 by A.ito\n\n1. Introduction\n\nThis extension module adds ruby a functionality to execute an \narbitrary command through pseudo tty (pty).\n\n2. Install\n\nFollow the instruction below.\n\n(1) Execute\n\n      ruby extconf.rb\n\n    then Makefile is generated.\n\n(3) Do make; make install.\n\n3. What you can do\n\nThis extension module defines a module named PTY, which contains\nfollowing module fungtions:\n\n   getpty(command)\n   spawn(command)\n\n      This function reserves a pty, executes command over the pty \n      and returns an array. The return value is an array with three\n      elements. The first element in the array is for reading and the \n      second for writing. The third element is the process ID of the\n      child process. If this function is called with an iterator block,\n      the array is passed to the block as block parameters, and the\n      function itself returns nil.\n\n      When the child process is suspended or finished, an exception is\n      raised.  If this function is called with an iterator block,\n      exception is raised only within the block.  Child process\n      monitor is terminated on block exit.\n\n   protect_signal\n   reset_signal\n\n      These functions are obsolete in this version of pty.\n\n4. License\n\n(C) Copyright 1998 by Akinori Ito.\n\nThis software may be redistributed freely for this purpose, in full \nor in part, provided that this entire copyright notice is included \non any copies of this software and applications and derivations thereof.\n\nThis software is provided on an \"as is\" basis, without warranty of any\nkind, either expressed or implied, as to any matter including, but not\nlimited to warranty of fitness of purpose, or merchantability, or\nresults obtained from use of this software.\n\n5. Bug report\n\nPlease feel free to send E-mail to\n\n   aito@ei5sun.yz.yamagata-u.ac.jp\n\nfor any bug report, opinion, contribution, etc.\n"
  },
  {
    "path": "ext/pty/README.expect",
    "content": "\tREADME for expect\n\t\tby A. Ito, 28 October, 1998\n\n\tExpect library adds IO class a method called expect(), which\ndoes similar act to tcl's expect extension. \n\nThe usage of the method is:\n\n   IO#expect(pattern,timeout=9999999)\n\nwhere `pattern' is an instance of String or Regexp and `timeout'\nis Fixnum, which can be omitted. \n\tWhen the method is called without block, it waits until the\ninput which matches the pattern is obtained from the IO or the time\nspecified as the timeout passes. When the pattern is obtained from the\nIO, the method returns an array. The first element of the array is the\nentire string obtained from the IO until the pattern matches. The\nfollowing elements indicates the specific pattern which matched to the\nanchor in the regular expression. If the method ends because of\ntimeout, it returns nil. \n \tWhen the method is called with block, the array is passed as\nthe block parameter.\n"
  },
  {
    "path": "ext/pty/README.expect.ja",
    "content": "\tREADME for expect\n\t\tby A. Ito, 28 October, 1998\n\n  Expect饤֥ϡtcl  expect ѥåȻ褦ʵǽ\nIO饹ɲäޤ\n\n  ɲä᥽åɤλȤϼ̤Ǥ\n\n   IO#expect(pattern,timeout=9999999)\n\npattern  String  Regexp Υ󥹥󥹡timeout  Fixnum\nΥ󥹥󥹤Ǥtimeout ϾάǤޤ\n  Υ᥽åɤ֥åʤǸƤФ줿硤ޤ쥷ФǤ\nIO֥Ȥ pattern ˥ޥåѥɤߤޤ\nޤԤޤѥ줿顤Υѥ˴ؤ\n֤ޤκǽǤϡpattern ˥ޥåޤǤɤߤ\nޤ줿ƤʸǤ2ܰʹߤǤϡpattern ɽ\n˥󥫡äˡΥ󥫡˥ޥåʬǤ\n⤷ॢȤϡΥ᥽åɤnil֤ޤ\n  Υ᥽åɤ֥åդǸƤФ줿ˤϡޥåǤ\n󤬥֥åȤϤ졤֥åɾޤ\n"
  },
  {
    "path": "ext/pty/README.ja",
    "content": "pty ĥ⥸塼 version 0.3 by A.ito\n\n1. Ϥ\n\nγĥ⥸塼ϡtty (pty) ̤Ŭʥޥɤ\n¹Ԥ뵡ǽ ruby 󶡤ޤ\n\n2. 󥹥ȡ\n\nΤ褦ˤƥ󥹥ȡ뤷Ƥ\n\n(1)  ruby extconf.rb\n\n    ¹Ԥ Makefile ޤ\n\n(2) make; make install ¹ԤƤ\n\n3. Ǥ뤫\n\nγĥ⥸塼ϡPTY Ȥ⥸塼ޤ\nˤϡΤ褦ʥ⥸塼ؿޤޤƤޤ\n\n   getpty(command)\n   spawn(command)\n\n      δؿϡttyݤꤵ줿ޥɤ򤽤βtty\n      θǼ¹Ԥ֤ޤͤ3ĤǤʤ\n      ǤǽǤϲttyɤ߽ФIO֥ȡ\n      2ܤϽ񤭤िIO֥ȡ3ܤϻҥץΥץ\n      IDǤδؿƥ졼ȤƸƤФ줿硤\n      Ǥϥ֥åѥ᡼ȤϤ졤ؿΤnil֤ޤ\n\n      δؿˤäƺ줿֥ץưƤ֡ҥץ\n      ξ֤ƻ뤹뤿 SIGCHLD ʥªޤҥץ\n      λߤˤϡ㳰ȯޤδ֡٤Ƥ\n      SIGCHLD  PTY ⥸塼ΥʥϥɥªΤǡ\n      ֥ץ¾δؿ(system() Ȥ IO.popen()ʤ)\n      Ȥȡͽʤ㳰ȯ뤳Ȥޤɤ\n      ˤϡprotect_signal()򻲾ȤƤ\n\n      δؿ֥åѥ᡼դǸƤФ줿ˤϡΥ֥å\n      ǤΤ SIGCHLD ªޤäơ֥åѥ᡼\n      ȤϤ줿IO֥Ȥ򡤥֥åγ˻ФƻȤ\n      ϴޤ\n\n\n   protect_signal\n\n      δؿϥƥ졼Ǥǻꤵ줿֥åǤϡ\n      ҥץλƤ㳰ȯޤ󡥤δؿȤȤǡ\n      PTYλҥץưƤ֤Ǥ⡤system() IO.popen()ʤɤ\n      ؿ˻ȤȤǤޤ㤨С\n\n        PTY.spawn(\"command_foo\") do |r,w|\n          ...\n          ...\n          PTY.protect_signal do\n            system \"some other commands\"\n          end\n          ...\n        end\n\n      Τ褦ʵҤˤꡤ\"some other commands\" λȤ\n      㳰ȯΤɤޤ\n\n    reset_signal\n\n      PTY λҥץưƤƤ⡤Υץνλ㳰ȯ\n      ʤ褦ˤޤ\n\n4. ѤˤĤ\n\nƣ§ͭޤ\n\nץޤϥɥȤ˸ɽѤ줺\nɽƤ˸¤ꡤïǤ⡤Υեȥ̵\nԤ̵ǤѡۡѤǤޤŪϸꤵƤޤ\n\n\nΥץѡۤ¾Υץ˴ط԰٤ˤ\näʤ»ФƤ⡤ԤϰǤ餤ޤ\n\n5. Х\n\nХݡȤϴޤޤ\n\n\taito@ei5sun.yz.yamagata-u.ac.jp\n\nޤŻҥ᡼ǥХݡȤ꤯\n"
  },
  {
    "path": "ext/pty/depend",
    "content": "pty.o: pty.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/pty/expect_sample.rb",
    "content": "#\n# sample program of expect.rb\n#\n#  by A. Ito\n#\n#  This program reports the latest version of ruby interpreter\n#  by connecting to ftp server at ruby-lang.org.\n#\nrequire 'pty'\nrequire 'expect'\n\nfnames = []\nPTY.spawn(\"ftp ftp.ruby-lang.org\") do |r_f,w_f,pid|\n  w_f.sync = true\n  \n  $expect_verbose = false\n  \n  if !ENV['USER'].nil?\n    username = ENV['USER']\n  elsif !ENV['LOGNAME'].nil?\n    username = ENV['LOGNAME']\n  else\n    username = 'guest'\n  end\n  \n  r_f.expect(/^(Name).*: |(word):|> /) do\n    w_f.puts($1 ? \"ftp\" : $2 ? \"#{username}@\" : \"cd pub/ruby\")\n  end\n  r_f.expect(\"> \") do\n    w_f.print \"dir\\n\"\n  end\n  \n  r_f.expect(/[^\\-]> /) do |output|\n    for x in output[0].split(\"\\n\")\n      if x =~ /(ruby.*?\\.tar\\.gz)/ then\n         fnames.push $1\n      end\n    end\n  end\n  begin\n    w_f.print \"quit\\n\"\n  rescue\n  end\nend\n\nprint \"The latest ruby interpreter is \"\nprint fnames.sort.pop\nprint \"\\n\"\n"
  },
  {
    "path": "ext/pty/extconf.rb",
    "content": "require 'mkmf'\n\nif /mswin32|mingw|bccwin32/ !~ RUBY_PLATFORM\n  have_header(\"sys/stropts.h\")\n  have_func(\"setresuid\")\n  have_header(\"libutil.h\")\n  have_header(\"pty.h\")\n  have_library(\"util\", \"openpty\")\n  if have_func(\"openpty\") or\n      have_func(\"_getpty\") or\n      have_func(\"ptsname\") or\n      have_func(\"ioctl\")\n    create_makefile('pty')\n  end\nend\n"
  },
  {
    "path": "ext/pty/lib/expect.rb",
    "content": "$expect_verbose = false\n\nclass IO\n  def expect(pat,timeout=9999999)\n    buf = ''\n    case pat\n    when String\n      e_pat = Regexp.new(Regexp.quote(pat))\n    when Regexp\n      e_pat = pat\n    end\n    while true\n      if !IO.select([self],nil,nil,timeout) or eof? then\n        result = nil\n        break\n      end\n      c = getc.chr\n      buf << c\n      if $expect_verbose\n        STDOUT.print c\n        STDOUT.flush\n      end\n      if mat=e_pat.match(buf) then\n        result = [buf,*mat.to_a[1..-1]]\n        break\n      end\n    end\n    if block_given? then\n      yield result\n    else\n      return result\n    end\n    nil\n  end\nend\n\n"
  },
  {
    "path": "ext/pty/pty.c",
    "content": "#include\t\"config.h\"\n#include\t<stdio.h>\n#include\t<sys/types.h>\n#include\t<sys/stat.h>\n#include\t<sys/file.h>\n#include\t<fcntl.h>\n#include\t<errno.h>\n#include\t<pwd.h>\n#ifdef HAVE_SYS_IOCTL_H\n#include\t<sys/ioctl.h>\n#endif\n#ifdef HAVE_LIBUTIL_H\n#include\t<libutil.h>\n#endif\n#ifdef HAVE_PTY_H\n#include\t<pty.h>\n#endif\n#ifdef HAVE_SYS_WAIT_H\n#include <sys/wait.h>\n#else\n#define WIFSTOPPED(status)    (((status) & 0xff) == 0x7f)\n#endif\n#include <ctype.h>\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"util.h\"\n\n#include <signal.h>\n#ifdef HAVE_SYS_STROPTS_H\n#include <sys/stropts.h>\n#endif\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#define\tDEVICELEN\t16\n\n#if !defined(HAVE_OPENPTY)\n#if defined(__hpux)\nstatic const\nchar\tMasterDevice[] = \"/dev/ptym/pty%s\",\n\tSlaveDevice[] =  \"/dev/pty/tty%s\",\n\t*const deviceNo[] = {\n\t\t\"p0\",\"p1\",\"p2\",\"p3\",\"p4\",\"p5\",\"p6\",\"p7\",\n\t\t\"p8\",\"p9\",\"pa\",\"pb\",\"pc\",\"pd\",\"pe\",\"pf\",\n\t\t\"q0\",\"q1\",\"q2\",\"q3\",\"q4\",\"q5\",\"q6\",\"q7\",\n\t\t\"q8\",\"q9\",\"qa\",\"qb\",\"qc\",\"qd\",\"qe\",\"qf\",\n\t\t\"r0\",\"r1\",\"r2\",\"r3\",\"r4\",\"r5\",\"r6\",\"r7\",\n\t\t\"r8\",\"r9\",\"ra\",\"rb\",\"rc\",\"rd\",\"re\",\"rf\",\n\t\t\"s0\",\"s1\",\"s2\",\"s3\",\"s4\",\"s5\",\"s6\",\"s7\",\n\t\t\"s8\",\"s9\",\"sa\",\"sb\",\"sc\",\"sd\",\"se\",\"sf\",\n\t\t\"t0\",\"t1\",\"t2\",\"t3\",\"t4\",\"t5\",\"t6\",\"t7\",\n\t\t\"t8\",\"t9\",\"ta\",\"tb\",\"tc\",\"td\",\"te\",\"tf\",\n\t\t\"u0\",\"u1\",\"u2\",\"u3\",\"u4\",\"u5\",\"u6\",\"u7\",\n\t\t\"u8\",\"u9\",\"ua\",\"ub\",\"uc\",\"ud\",\"ue\",\"uf\",\n\t\t\"v0\",\"v1\",\"v2\",\"v3\",\"v4\",\"v5\",\"v6\",\"v7\",\n\t\t\"v8\",\"v9\",\"va\",\"vb\",\"vc\",\"vd\",\"ve\",\"vf\",\n\t\t\"w0\",\"w1\",\"w2\",\"w3\",\"w4\",\"w5\",\"w6\",\"w7\",\n\t\t\"w8\",\"w9\",\"wa\",\"wb\",\"wc\",\"wd\",\"we\",\"wf\",\n\t\t0,\n\t};\n#elif defined(_IBMESA)  /* AIX/ESA */\nstatic const\nchar\tMasterDevice[] = \"/dev/ptyp%s\",\n  \tSlaveDevice[] = \"/dev/ttyp%s\",\n\t*const deviceNo[] = {\n\"00\",\"01\",\"02\",\"03\",\"04\",\"05\",\"06\",\"07\",\"08\",\"09\",\"0a\",\"0b\",\"0c\",\"0d\",\"0e\",\"0f\",\n\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"1a\",\"1b\",\"1c\",\"1d\",\"1e\",\"1f\",\n\"20\",\"21\",\"22\",\"23\",\"24\",\"25\",\"26\",\"27\",\"28\",\"29\",\"2a\",\"2b\",\"2c\",\"2d\",\"2e\",\"2f\",\n\"30\",\"31\",\"32\",\"33\",\"34\",\"35\",\"36\",\"37\",\"38\",\"39\",\"3a\",\"3b\",\"3c\",\"3d\",\"3e\",\"3f\",\n\"40\",\"41\",\"42\",\"43\",\"44\",\"45\",\"46\",\"47\",\"48\",\"49\",\"4a\",\"4b\",\"4c\",\"4d\",\"4e\",\"4f\",\n\"50\",\"51\",\"52\",\"53\",\"54\",\"55\",\"56\",\"57\",\"58\",\"59\",\"5a\",\"5b\",\"5c\",\"5d\",\"5e\",\"5f\",\n\"60\",\"61\",\"62\",\"63\",\"64\",\"65\",\"66\",\"67\",\"68\",\"69\",\"6a\",\"6b\",\"6c\",\"6d\",\"6e\",\"6f\",\n\"70\",\"71\",\"72\",\"73\",\"74\",\"75\",\"76\",\"77\",\"78\",\"79\",\"7a\",\"7b\",\"7c\",\"7d\",\"7e\",\"7f\",\n\"80\",\"81\",\"82\",\"83\",\"84\",\"85\",\"86\",\"87\",\"88\",\"89\",\"8a\",\"8b\",\"8c\",\"8d\",\"8e\",\"8f\",\n\"90\",\"91\",\"92\",\"93\",\"94\",\"95\",\"96\",\"97\",\"98\",\"99\",\"9a\",\"9b\",\"9c\",\"9d\",\"9e\",\"9f\",\n\"a0\",\"a1\",\"a2\",\"a3\",\"a4\",\"a5\",\"a6\",\"a7\",\"a8\",\"a9\",\"aa\",\"ab\",\"ac\",\"ad\",\"ae\",\"af\",\n\"b0\",\"b1\",\"b2\",\"b3\",\"b4\",\"b5\",\"b6\",\"b7\",\"b8\",\"b9\",\"ba\",\"bb\",\"bc\",\"bd\",\"be\",\"bf\",\n\"c0\",\"c1\",\"c2\",\"c3\",\"c4\",\"c5\",\"c6\",\"c7\",\"c8\",\"c9\",\"ca\",\"cb\",\"cc\",\"cd\",\"ce\",\"cf\",\n\"d0\",\"d1\",\"d2\",\"d3\",\"d4\",\"d5\",\"d6\",\"d7\",\"d8\",\"d9\",\"da\",\"db\",\"dc\",\"dd\",\"de\",\"df\",\n\"e0\",\"e1\",\"e2\",\"e3\",\"e4\",\"e5\",\"e6\",\"e7\",\"e8\",\"e9\",\"ea\",\"eb\",\"ec\",\"ed\",\"ee\",\"ef\",\n\"f0\",\"f1\",\"f2\",\"f3\",\"f4\",\"f5\",\"f6\",\"f7\",\"f8\",\"f9\",\"fa\",\"fb\",\"fc\",\"fd\",\"fe\",\"ff\",\n\t\t};\n#elif !defined(HAVE_PTSNAME)\nstatic const\nchar\tMasterDevice[] = \"/dev/pty%s\",\n\tSlaveDevice[] = \"/dev/tty%s\",\n\t*const deviceNo[] = {\n\t\t\"p0\",\"p1\",\"p2\",\"p3\",\"p4\",\"p5\",\"p6\",\"p7\",\n\t\t\"p8\",\"p9\",\"pa\",\"pb\",\"pc\",\"pd\",\"pe\",\"pf\",\n\t\t\"q0\",\"q1\",\"q2\",\"q3\",\"q4\",\"q5\",\"q6\",\"q7\",\n\t\t\"q8\",\"q9\",\"qa\",\"qb\",\"qc\",\"qd\",\"qe\",\"qf\",\n\t\t\"r0\",\"r1\",\"r2\",\"r3\",\"r4\",\"r5\",\"r6\",\"r7\",\n\t\t\"r8\",\"r9\",\"ra\",\"rb\",\"rc\",\"rd\",\"re\",\"rf\",\n\t\t\"s0\",\"s1\",\"s2\",\"s3\",\"s4\",\"s5\",\"s6\",\"s7\",\n\t\t\"s8\",\"s9\",\"sa\",\"sb\",\"sc\",\"sd\",\"se\",\"sf\",\n\t\t0,\n\t};\n#endif\n#endif /* !defined(HAVE_OPENPTY) */\n\n#ifndef HAVE_SETEUID\n# ifdef HAVE_SETREUID\n#  define seteuid(e)\tsetreuid(-1, (e))\n# else /* NOT HAVE_SETREUID */\n#  ifdef HAVE_SETRESUID\n#   define seteuid(e)\tsetresuid(-1, (e), -1)\n#  else /* NOT HAVE_SETRESUID */\n    /* I can't set euid. (;_;) */\n#  endif /* HAVE_SETRESUID */\n# endif /* HAVE_SETREUID */\n#endif /* NO_SETEUID */\n\nstatic VALUE eChildExited;\n\nstatic VALUE\nechild_status(self)\n    VALUE self;\n{\n    return rb_ivar_get(self, rb_intern(\"status\"));\n}\n\nstruct pty_info {\n    int fd;\n    rb_pid_t child_pid;\n    VALUE thread;\n};\n\nstatic void\nraise_from_wait(state, info)\n    struct pty_info *info;\n    char *state;\n{\n    extern VALUE rb_last_status;\n    char buf[1024];\n    VALUE exc;\n\n    snprintf(buf, sizeof(buf), \"pty - %s: %ld\", state, (long)info->child_pid);\n    exc = rb_exc_new2(eChildExited, buf);\n    rb_iv_set(exc, \"status\", rb_last_status);\n    rb_funcall(info->thread, rb_intern(\"raise\"), 1, exc);\n}\n\nstatic VALUE\npty_syswait(info)\n    struct pty_info *info;\n{\n    int cpid, status;\n\n    for (;;) {\n\tcpid = rb_waitpid(info->child_pid, &status, WUNTRACED);\n\tif (cpid == -1) return Qnil;\n\n#if defined(WIFSTOPPED)\n#elif defined(IF_STOPPED)\n#define WIFSTOPPED(status) IF_STOPPED(status)\n#else\n---->> Either IF_STOPPED or WIFSTOPPED is needed <<----\n#endif /* WIFSTOPPED | IF_STOPPED */\n\tif (WIFSTOPPED(status)) { /* suspend */\n\t    raise_from_wait(\"stopped\", info);\n\t}\n\telse if (kill(info->child_pid, 0) == 0) {\n\t    raise_from_wait(\"changed\", info);\n\t}\n\telse {\n\t    raise_from_wait(\"exited\", info);\n\t    return Qnil;\n\t}\n    }\n}\n\nstatic void getDevice _((int*, int*, char [DEVICELEN]));\n\nstruct exec_info {\n    int argc;\n    VALUE *argv;\n};\n\nstatic VALUE pty_exec _((VALUE v));\n\nstatic VALUE\npty_exec(v)\n    VALUE v;\n{\n    struct exec_info *arg = (struct exec_info *)v;\n    return rb_f_exec(arg->argc, arg->argv);\n}\n\nstatic void\nestablishShell(argc, argv, info, SlaveName)\n    int argc;\n    VALUE *argv;\n    struct pty_info *info;\n    char SlaveName[DEVICELEN];\n{\n    int \t\ti,master,slave;\n    char\t\t*p, tmp, *getenv();\n    struct passwd\t*pwent;\n    VALUE\t\tv;\n    struct exec_info\targ;\n    int\t\t\tstatus;\n\n    if (argc == 0) {\n\tchar *shellname;\n\n\tif ((p = getenv(\"SHELL\")) != NULL) {\n\t    shellname = p;\n\t}\n\telse {\n\t    pwent = getpwuid(getuid());\n\t    if (pwent && pwent->pw_shell)\n\t\tshellname = pwent->pw_shell;\n\t    else\n\t\tshellname = \"/bin/sh\";\n\t}\n\tv = rb_str_new2(shellname);\n\targc = 1;\n\targv = &v;\n    }\n    getDevice(&master, &slave, SlaveName);\n\n    info->thread = rb_thread_current();\n    if((i = fork()) < 0) {\n\tclose(master);\n\tclose(slave);\n\trb_sys_fail(\"fork failed\");\n    }\n\n    if(i == 0) {\t/* child */\n\t/*\n\t * Set free from process group and controlling terminal\n\t */\n#ifdef HAVE_SETSID\n\t(void) setsid();\n#else /* HAS_SETSID */\n# ifdef HAVE_SETPGRP\n#  ifdef SETGRP_VOID\n\tif (setpgrp() == -1)\n\t    perror(\"setpgrp()\");\n#  else /* SETGRP_VOID */\n\tif (setpgrp(0, getpid()) == -1)\n\t    rb_sys_fail(\"setpgrp()\");\n\tif ((i = open(\"/dev/tty\", O_RDONLY)) < 0)\n\t    rb_sys_fail(\"/dev/tty\");\n\telse {\n\t    if (ioctl(i, TIOCNOTTY, (char *)0))\n\t\tperror(\"ioctl(TIOCNOTTY)\");\n\t    close(i);\n\t}\n#  endif /* SETGRP_VOID */\n# endif /* HAVE_SETPGRP */\n#endif /* HAS_SETSID */\n\n\t/*\n\t * obtain new controlling terminal\n\t */\n#if defined(TIOCSCTTY)\n\tclose(master);\n\t(void) ioctl(slave, TIOCSCTTY, (char *)0);\n\t/* errors ignored for sun */\n#else\n\tclose(slave);\n\tslave = open(SlaveName, O_RDWR);\n\tif (slave < 0) {\n\t    perror(\"open: pty slave\");\n\t    _exit(1);\n\t}\n\tclose(master);\n#endif\n\twrite(slave, \"\", 1);\n\tdup2(slave,0);\n\tdup2(slave,1);\n\tdup2(slave,2);\n\tclose(slave);\n#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID)\n\tseteuid(getuid());\n#endif\n\n\targ.argc = argc;\n\targ.argv = argv;\n\trb_protect(pty_exec, (VALUE)&arg, &status);\n\tsleep(1);\n\t_exit(1);\n    }\n\n    read(master, &tmp, 1);\n    close(slave);\n\n    info->child_pid = i;\n    info->fd = master;\n}\n\nstatic VALUE\npty_finalize_syswait(info)\n    struct pty_info *info;\n{\n    rb_thread_kill(info->thread);\n    rb_funcall(info->thread, rb_intern(\"value\"), 0);\n    rb_detach_process(info->child_pid);\n    return Qnil;\n}\n\nstatic int\nget_device_once(master, slave, SlaveName, fail)\n    int *master, *slave, fail;\n    char SlaveName[DEVICELEN];\n{\n#if defined HAVE_OPENPTY\n/*\n * Use openpty(3) of 4.3BSD Reno and later,\n * or the same interface function.\n */\n    if (openpty(master, slave, SlaveName,\n\t\t(struct termios *)0, (struct winsize *)0) == -1) {\n\tif (!fail) return -1;\n\trb_raise(rb_eRuntimeError, \"openpty() failed\");\n    }\n\n    return 0;\n#elif defined HAVE__GETPTY\n    char *name;\n\n    if (!(name = _getpty(master, O_RDWR, 0622, 0))) {\n\tif (!fail) return -1;\n\trb_raise(rb_eRuntimeError, \"_getpty() failed\");\n    }\n\n    *slave = open(name, O_RDWR);\n    strncpy(SlaveName, name, sizeof SlaveName);\n\n    return 0;\n#else /* HAVE__GETPTY */\n    int\t i,j;\n\n#ifdef HAVE_PTSNAME\n    char *pn;\n    void (*s)();\n\n    extern char *ptsname(int);\n    extern int unlockpt(int);\n    extern int grantpt(int);\n\n    if((i = open(\"/dev/ptmx\", O_RDWR, 0)) != -1) {\n\ts = signal(SIGCHLD, SIG_DFL);\n\tif(grantpt(i) != -1) {\n\t    signal(SIGCHLD, s);\n\t    if(unlockpt(i) != -1) {\n\t\tif((pn = ptsname(i)) != NULL) {\n\t\t    if((j = open(pn, O_RDWR, 0)) != -1) {\n#if defined I_PUSH && !defined linux\n\t\t\tif(ioctl(j, I_PUSH, \"ptem\") != -1) {\n\t\t\t    if(ioctl(j, I_PUSH, \"ldterm\") != -1) {\n\t\t\t\tioctl(j, I_PUSH, \"ttcompat\");\n#endif\n\t\t\t\t*master = i;\n\t\t\t\t*slave = j;\n\t\t\t\tstrncpy(SlaveName, pn, sizeof SlaveName);\n\t\t\t\treturn 0;\n#if defined I_PUSH && !defined linux\n\t\t\t    }\n\t\t\t}\n#endif\n\t\t    }\n\t\t}\n\t    }\n\t}\n\tclose(i);\n    }\n    if (!fail) rb_raise(rb_eRuntimeError, \"can't get Master/Slave device\");\n    return -1;\n#else\n    char **p;\n    char MasterName[DEVICELEN];\n\n    for (p = deviceNo; *p != NULL; p++) {\n\tsnprintf(MasterName, sizeof MasterName, MasterDevice, *p);\n\tif ((i = open(MasterName,O_RDWR,0)) >= 0) {\n\t    *master = i;\n\t    snprintf(SlaveName, sizeof SlaveName, SlaveDevice, *p);\n\t    if ((j = open(SlaveName,O_RDWR,0)) >= 0) {\n\t\t*slave = j;\n\t\tchown(SlaveName, getuid(), getgid());\n\t\tchmod(SlaveName, 0622);\n\t\treturn 0;\n\t    }\n\t    close(i);\n\t}\n    }\n    if (fail) rb_raise(rb_eRuntimeError, \"can't get %s\", SlaveName);\n    return -1;\n#endif\n#endif\n}\n\nstatic void\ngetDevice(master, slave, slavename)\n    int *master, *slave;\n    char slavename[DEVICELEN];\n{\n    if (get_device_once(master, slave, slavename, 0)) {\n\trb_gc();\n\tget_device_once(master, slave, slavename, 1);\n    }\n}\n\n/* ruby function: getpty */\nstatic VALUE\npty_getpty(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE res;\n    struct pty_info info;\n    struct pty_info thinfo;\n    rb_io_t *wfptr,*rfptr;\n    VALUE rport = rb_obj_alloc(rb_cFile);\n    VALUE wport = rb_obj_alloc(rb_cFile);\n    char SlaveName[DEVICELEN];\n\n    MakeOpenFile(rport, rfptr);\n    MakeOpenFile(wport, wfptr);\n\n    establishShell(argc, argv, &info, SlaveName);\n\n    rfptr->mode = rb_io_mode_flags(\"r\");\n    rfptr->f = fdopen(info.fd, \"r\");\n    rfptr->path = strdup(SlaveName);\n\n    wfptr->mode = rb_io_mode_flags(\"w\") | FMODE_SYNC;\n    wfptr->f = fdopen(dup(info.fd), \"w\");\n    wfptr->path = strdup(SlaveName);\n\n    res = rb_ary_new2(3);\n    rb_ary_store(res,0,(VALUE)rport);\n    rb_ary_store(res,1,(VALUE)wport);\n    rb_ary_store(res,2,INT2FIX(info.child_pid));\n\n    thinfo.thread = rb_thread_create(pty_syswait, (void*)&info);\n    thinfo.child_pid = info.child_pid;\n    rb_thread_schedule();\n\n    if (rb_block_given_p()) {\n\trb_ensure(rb_yield, res, pty_finalize_syswait, (VALUE)&thinfo);\n\treturn Qnil;\n    }\n    return res;\n}\n\n/* ruby function: protect_signal - obsolete */\nstatic VALUE\npty_protect(self)\n    VALUE self;\n{\n    rb_warn(\"PTY::protect_signal is no longer needed\");\n    rb_yield(Qnil);\n    return self;\n}\n\n/* ruby function: reset_signal - obsolete */\nstatic VALUE\npty_reset_signal(self)\n    VALUE self;\n{\n    rb_warn(\"PTY::reset_signal is no longer needed\");\n    return self;\n}\n\nstatic VALUE cPTY;\n\nvoid\nInit_pty()\n{\n    cPTY = rb_define_module(\"PTY\");\n    rb_define_module_function(cPTY,\"getpty\",pty_getpty,-1);\n    rb_define_module_function(cPTY,\"spawn\",pty_getpty,-1);\n    rb_define_module_function(cPTY,\"protect_signal\",pty_protect,0);\n    rb_define_module_function(cPTY,\"reset_signal\",pty_reset_signal,0);\n\n    eChildExited = rb_define_class_under(cPTY,\"ChildExited\",rb_eRuntimeError);\n    rb_define_method(eChildExited,\"status\",echild_status,0);\n}\n"
  },
  {
    "path": "ext/pty/script.rb",
    "content": "require 'pty'\n\nif ARGV.size == 0 then\n  ofile = \"typescript\"\nelse\n  ofile = ARGV[0]\nend\n\nlogfile = File.open(ofile,\"a\")\n\nsystem \"stty -echo raw lnext ^_\"\n\nPTY.spawn(\"/bin/csh\") do |r_pty,w_pty,pid|\n\n  Thread.new do\n    while true\n      w_pty.print STDIN.getc.chr\n      w_pty.flush\n    end\n  end\n  \n  begin\n    while true\n      c = r_pty.sysread(512)\n      break if c.nil?\n      print c\n      STDOUT.flush\n      logfile.print c\n    end\n  rescue\n  #  print $@,':',$!,\"\\n\"\n    logfile.close\n  end\nend\n\nsystem \"stty echo -raw lnext ^v\"\n\n"
  },
  {
    "path": "ext/pty/shl.rb",
    "content": "#\n#  old-fashioned 'shl' like program\n#  by A. Ito\n#\n#  commands:\n#     c        creates new shell\n#     C-z      suspends shell\n#     p        lists all shell\n#     0,1,...  choose shell\n#     q        quit\n\nrequire 'pty'\n\n$shells = []\n$n_shells = 0\n\n$r_pty = nil\n$w_pty = nil\n\ndef writer\n  system \"stty -echo raw\"\n  begin\n    while true\n      c = STDIN.getc\n      if c == 26 then # C-z\n        $reader.raise(nil)\n        return 'Suspend'\n      end\n      $w_pty.print c.chr\n      $w_pty.flush\n    end\n  rescue\n    $reader.raise(nil)\n    return 'Exit'\n  ensure\n    system \"stty echo -raw\"\n  end\nend\n\n$reader = Thread.new {\n  while true\n    begin\n      next if $r_pty.nil?\n      c = $r_pty.getc\n      if c.nil? then\n        Thread.stop\n      end\n      print c.chr\n      STDOUT.flush\n    rescue\n      Thread.stop\n    end\n  end\n}\n\n# $reader.raise(nil)\n\n\nwhile true\n  print \">> \"\n  STDOUT.flush\n  case gets\n  when /^c/i\n    $shells[$n_shells] = PTY.spawn(\"/bin/csh\")\n    $r_pty,$w_pty = $shells[$n_shells]\n    $n_shells += 1\n    $reader.run\n    if writer == 'Exit'\n      $n_shells -= 1\n      $shells[$n_shells] = nil\n    end\n  when /^p/i\n    for i in 0..$n_shells\n      unless $shells[i].nil?\n        print i,\"\\n\"\n      end\n    end\n  when /^([0-9]+)/\n    n = $1.to_i\n    if $shells[n].nil?\n      print \"\\##{i} doesn't exist\\n\"\n    else\n      $r_pty,$w_pty = $shells[n]\n      $reader.run\n      if writer == 'Exit' then\n        $shells[n] = nil\n      end\n    end\n  when /^q/i\n    exit\n  end\nend\n"
  },
  {
    "path": "ext/purelib.rb",
    "content": "nul = nil\n$:.each_with_index {|path, index|\n  if /\\A(?:\\.\\/)*-\\z/ =~ path\n    nul = index\n    break\n  end\n}\nif nul\n  $:[nul..-1] = [\".\"]\nend\n"
  },
  {
    "path": "ext/racc/cparse/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/racc/cparse/cparse.c",
    "content": "/*\n\n    cparse.c -- Racc Runtime Core\n  \n    Copyright (c) 1999-2006 Minero Aoki\n  \n    This library is free software.\n    You can distribute/modify this program under the same terms of ruby.\n\n    $originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $\n\n*/\n\n#include \"ruby.h\"\n#include \"version.h\"\n\n/* -----------------------------------------------------------------------\n                        Important Constants\n----------------------------------------------------------------------- */\n\n#define RACC_VERSION \"1.4.5\"\n\n#define DEFAULT_TOKEN -1\n#define ERROR_TOKEN    1\n#define FINAL_TOKEN    0\n\n#define vDEFAULT_TOKEN  INT2FIX(DEFAULT_TOKEN)\n#define vERROR_TOKEN    INT2FIX(ERROR_TOKEN)\n#define vFINAL_TOKEN    INT2FIX(FINAL_TOKEN)\n\n/* -----------------------------------------------------------------------\n                          File Local Variables\n----------------------------------------------------------------------- */\n\nstatic VALUE RaccBug;\nstatic VALUE CparseParams;\n\nstatic ID id_yydebug;\nstatic ID id_nexttoken;\nstatic ID id_onerror;\nstatic ID id_noreduce;\nstatic ID id_errstatus;\n\nstatic ID id_d_shift;\nstatic ID id_d_reduce;\nstatic ID id_d_accept;\nstatic ID id_d_read_token;\nstatic ID id_d_next_state;\nstatic ID id_d_e_pop;\n\n/* -----------------------------------------------------------------------\n                              Utils\n----------------------------------------------------------------------- */\n\n/* For backward compatibility */\n#ifndef ID2SYM\n# define ID2SYM(i) ULONG2NUM(i)\n#endif\n#ifndef SYM2ID\n#  define SYM2ID(v) ((ID)NUM2ULONG(v))\n#endif\n#ifndef SYMBOL_P\n#  define SYMBOL_P(v) FIXNUM_P(v)\n#endif\n#ifndef LONG2NUM\n#  define LONG2NUM(i) INT2NUM(i)\n#endif\n#if RUBY_VERSION_CODE >= 190\n#  define HAVE_RB_BLOCK_CALL 1\n#endif\n\nstatic ID value_to_id _((VALUE v));\nstatic inline long num_to_long _((VALUE n));\n\nstatic ID\nvalue_to_id(VALUE v)\n{\n    if (! SYMBOL_P(v)) {\n        rb_raise(rb_eTypeError, \"not symbol\");\n    }\n    return SYM2ID(v);\n}\n\nstatic inline long\nnum_to_long(VALUE n)\n{\n    return NUM2LONG(n);\n}\n\n#define AREF(s, idx) \\\n    ((0 <= idx && idx < RARRAY(s)->len) ? RARRAY(s)->ptr[idx] : Qnil)\n\n/* -----------------------------------------------------------------------\n                        Parser Stack Interfaces\n----------------------------------------------------------------------- */\n\nstatic VALUE get_stack_tail _((VALUE stack, long len));\nstatic void cut_stack_tail _((VALUE stack, long len));\n\nstatic VALUE\nget_stack_tail(VALUE stack, long len)\n{\n    if (len < 0) return Qnil;  /* system error */\n    if (len > RARRAY(stack)->len) len = RARRAY(stack)->len;\n    return rb_ary_new4(len, RARRAY(stack)->ptr + RARRAY(stack)->len - len);\n}\n\nstatic void\ncut_stack_tail(VALUE stack, long len)\n{\n    while (len > 0) {\n        rb_ary_pop(stack);\n        len--;\n    }\n}\n\n#define STACK_INIT_LEN 64\n#define NEW_STACK() rb_ary_new2(STACK_INIT_LEN)\n#define PUSH(s, i) rb_ary_store(s, RARRAY(s)->len, i)\n#define POP(s) rb_ary_pop(s)\n#define LAST_I(s) \\\n    ((RARRAY(s)->len > 0) ? RARRAY(s)->ptr[RARRAY(s)->len - 1] : Qnil)\n#define GET_TAIL(s, len) get_stack_tail(s, len)\n#define CUT_TAIL(s, len) cut_stack_tail(s, len)\n\n/* -----------------------------------------------------------------------\n                       struct cparse_params\n----------------------------------------------------------------------- */\n\nstruct cparse_params {\n    VALUE value_v;         /* VALUE version of this struct */\n\n    VALUE parser;          /* parser object */\n\n    int   lex_is_iterator;\n    VALUE lexer;           /* scanner object */\n    ID    lexmid;          /* name of scanner method (must be an iterator) */\n\n    /* State transition tables (immutable)\n       Data structure is from Dragon Book 4.9 */\n    /* action table */\n    VALUE action_table;\n    VALUE action_check;\n    VALUE action_default;\n    VALUE action_pointer;\n    /* goto table */\n    VALUE goto_table;\n    VALUE goto_check;\n    VALUE goto_default;\n    VALUE goto_pointer;\n\n    long  nt_base;         /* NonTerminal BASE index */\n    VALUE reduce_table;    /* reduce data table */\n    VALUE token_table;     /* token conversion table */\n\n    /* parser stacks and parameters */\n    VALUE state;\n    long curstate;\n    VALUE vstack;\n    VALUE tstack;\n    VALUE t;\n    long shift_n;\n    long reduce_n;\n    long ruleno;\n\n    long errstatus;         /* nonzero in error recovering mode */\n    long nerr;              /* number of error */\n\n    int use_result_var;\n\n    VALUE retval;           /* return value of parser routine */\n    long fin;               /* parse result status */\n#define CP_FIN_ACCEPT  1\n#define CP_FIN_EOT     2\n#define CP_FIN_CANTPOP 3\n\n    int debug;              /* user level debug */\n    int sys_debug;          /* system level debug */\n\n    long i;                 /* table index */\n};\n\n/* -----------------------------------------------------------------------\n                        Parser Main Routines\n----------------------------------------------------------------------- */\n\nstatic VALUE racc_cparse _((VALUE parser, VALUE arg, VALUE sysdebug));\nstatic VALUE racc_yyparse _((VALUE parser, VALUE lexer, VALUE lexmid,\n                             VALUE arg, VALUE sysdebug));\n\nstatic void call_lexer _((struct cparse_params *v));\nstatic VALUE lexer_i _((VALUE block_args, VALUE data, VALUE self));\n\nstatic VALUE assert_array _((VALUE a));\nstatic long assert_integer _((VALUE n));\nstatic VALUE assert_hash _((VALUE h));\nstatic VALUE initialize_params _((VALUE vparams, VALUE parser, VALUE arg,\n                                 VALUE lexer, VALUE lexmid));\nstatic void cparse_params_mark _((void *ptr));\n\nstatic void parse_main _((struct cparse_params *v,\n                         VALUE tok, VALUE val, int resume));\nstatic void extract_user_token _((struct cparse_params *v,\n                                  VALUE block_args, VALUE *tok, VALUE *val));\nstatic void shift _((struct cparse_params* v, long act, VALUE tok, VALUE val));\nstatic int reduce _((struct cparse_params* v, long act));\nstatic VALUE reduce0 _((VALUE block_args, VALUE data, VALUE self));\n\n#ifdef DEBUG\n# define D_puts(msg)        if (v->sys_debug) puts(msg)\n# define D_printf(fmt,arg)  if (v->sys_debug) printf(fmt,arg)\n#else\n# define D_puts(msg)\n# define D_printf(fmt,arg)\n#endif\n\nstatic VALUE\nracc_cparse(VALUE parser, VALUE arg, VALUE sysdebug)\n{\n    volatile VALUE vparams;\n    struct cparse_params *v;\n\n    vparams = Data_Make_Struct(CparseParams, struct cparse_params,\n                               cparse_params_mark, -1, v);\n    D_puts(\"starting cparse\");\n    v->sys_debug = RTEST(sysdebug);\n    vparams = initialize_params(vparams, parser, arg, Qnil, Qnil);\n    v->lex_is_iterator = Qfalse;\n    parse_main(v, Qnil, Qnil, 0);\n\n    return v->retval;\n}\n\nstatic VALUE\nracc_yyparse(VALUE parser, VALUE lexer, VALUE lexmid, VALUE arg, VALUE sysdebug)\n{\n    volatile VALUE vparams;\n    struct cparse_params *v;\n\n    vparams = Data_Make_Struct(CparseParams, struct cparse_params,\n                               cparse_params_mark, -1, v);\n    v->sys_debug = RTEST(sysdebug);\n    D_puts(\"start C yyparse\");\n    vparams = initialize_params(vparams, parser, arg, lexer, lexmid);\n    v->lex_is_iterator = Qtrue;\n    D_puts(\"params initialized\");\n    parse_main(v, Qnil, Qnil, 0);\n    call_lexer(v);\n    if (!v->fin) {\n        rb_raise(rb_eArgError, \"%s() is finished before EndOfToken\",\n                 rb_id2name(v->lexmid));\n    }\n\n    return v->retval;\n}\n\n#ifdef HAVE_RB_BLOCK_CALL\nstatic void\ncall_lexer(struct cparse_params *v)\n{\n    rb_block_call(v->lexer, v->lexmid, 0, NULL, lexer_i, v->value_v);\n}\n#else\nstatic VALUE\nlexer_iter(VALUE data)\n{\n    struct cparse_params *v;\n\n    Data_Get_Struct(data, struct cparse_params, v);\n    rb_funcall(v->lexer, v->lexmid, 0);\n    return Qnil;\n}\n\nstatic void\ncall_lexer(struct cparse_params *v)\n{\n    rb_iterate(lexer_iter, v->value_v, lexer_i, v->value_v);\n}\n#endif\n\nstatic VALUE\nlexer_i(VALUE block_args, VALUE data, VALUE self)\n{\n    struct cparse_params *v;\n    VALUE tok, val;\n\n    Data_Get_Struct(data, struct cparse_params, v);\n    if (v->fin)\n        rb_raise(rb_eArgError, \"extra token after EndOfToken\");\n    extract_user_token(v, block_args, &tok, &val);\n    parse_main(v, tok, val, 1);\n    if (v->fin && v->fin != CP_FIN_ACCEPT)\n       rb_iter_break(); \n    return Qnil;\n}\n\nstatic VALUE\nassert_array(VALUE a)\n{\n    Check_Type(a, T_ARRAY);\n    return a;\n}\n\nstatic VALUE\nassert_hash(VALUE h)\n{\n    Check_Type(h, T_HASH);\n    return h;\n}\n\nstatic long\nassert_integer(VALUE n)\n{\n    return NUM2LONG(n);\n}\n\nstatic VALUE\ninitialize_params(VALUE vparams, VALUE parser, VALUE arg, VALUE lexer, VALUE lexmid)\n{\n    struct cparse_params *v;\n\n    Data_Get_Struct(vparams, struct cparse_params, v);\n    v->value_v = vparams;\n    v->parser = parser;\n    v->lexer = lexer;\n    if (! NIL_P(lexmid))\n        v->lexmid = value_to_id(lexmid);\n\n    v->debug = RTEST(rb_ivar_get(parser, id_yydebug));\n\n    Check_Type(arg, T_ARRAY);\n    if (!(13 <= RARRAY(arg)->len && RARRAY(arg)->len <= 14))\n        rb_raise(RaccBug, \"[Racc Bug] wrong arg.size %ld\", RARRAY(arg)->len);\n    v->action_table   = assert_array  (RARRAY(arg)->ptr[ 0]);\n    v->action_check   = assert_array  (RARRAY(arg)->ptr[ 1]);\n    v->action_default = assert_array  (RARRAY(arg)->ptr[ 2]);\n    v->action_pointer = assert_array  (RARRAY(arg)->ptr[ 3]);\n    v->goto_table     = assert_array  (RARRAY(arg)->ptr[ 4]);\n    v->goto_check     = assert_array  (RARRAY(arg)->ptr[ 5]);\n    v->goto_default   = assert_array  (RARRAY(arg)->ptr[ 6]);\n    v->goto_pointer   = assert_array  (RARRAY(arg)->ptr[ 7]);\n    v->nt_base        = assert_integer(RARRAY(arg)->ptr[ 8]);\n    v->reduce_table   = assert_array  (RARRAY(arg)->ptr[ 9]);\n    v->token_table    = assert_hash   (RARRAY(arg)->ptr[10]);\n    v->shift_n        = assert_integer(RARRAY(arg)->ptr[11]);\n    v->reduce_n       = assert_integer(RARRAY(arg)->ptr[12]);\n    if (RARRAY(arg)->len > 13) {\n        v->use_result_var = RTEST(RARRAY(arg)->ptr[13]);\n    }\n    else {\n        v->use_result_var = Qtrue;\n    }\n\n    v->tstack = v->debug ? NEW_STACK() : Qnil;\n    v->vstack = NEW_STACK();\n    v->state = NEW_STACK();\n    v->curstate = 0;\n    PUSH(v->state, INT2FIX(0));\n    v->t = INT2FIX(FINAL_TOKEN + 1);   /* must not init to FINAL_TOKEN */\n    v->nerr = 0;\n    v->errstatus = 0;\n    rb_ivar_set(parser, id_errstatus, LONG2NUM(v->errstatus));\n\n    v->retval = Qnil;\n    v->fin = 0;\n\n    v->lex_is_iterator = Qfalse;\n\n    rb_iv_set(parser, \"@vstack\", v->vstack);\n    if (v->debug) {\n        rb_iv_set(parser, \"@tstack\", v->tstack);\n    }\n    else {\n        rb_iv_set(parser, \"@tstack\", Qnil);\n    }\n\n    return vparams;\n}\n\nstatic void\ncparse_params_mark(void *ptr)\n{\n    struct cparse_params *v = (struct cparse_params*)ptr;\n\n    rb_gc_mark(v->value_v);\n    rb_gc_mark(v->parser);\n    rb_gc_mark(v->lexer);\n    rb_gc_mark(v->action_table);\n    rb_gc_mark(v->action_check);\n    rb_gc_mark(v->action_default);\n    rb_gc_mark(v->action_pointer);\n    rb_gc_mark(v->goto_table);\n    rb_gc_mark(v->goto_check);\n    rb_gc_mark(v->goto_default);\n    rb_gc_mark(v->goto_pointer);\n    rb_gc_mark(v->reduce_table);\n    rb_gc_mark(v->token_table);\n    rb_gc_mark(v->state);\n    rb_gc_mark(v->vstack);\n    rb_gc_mark(v->tstack);\n    rb_gc_mark(v->t);\n    rb_gc_mark(v->retval);\n}\n\nstatic void\nextract_user_token(struct cparse_params *v, VALUE block_args,\n                   VALUE *tok, VALUE *val)\n{\n    if (NIL_P(block_args)) {\n        /* EOF */\n        *tok = Qfalse;\n        *val = rb_str_new(\"$\", 1);\n        return;\n    }\n\n    if (TYPE(block_args) != T_ARRAY) {\n        rb_raise(rb_eTypeError,\n                 \"%s() %s %s (must be Array[2])\",\n                 v->lex_is_iterator ? rb_id2name(v->lexmid) : \"next_token\",\n                 v->lex_is_iterator ? \"yielded\" : \"returned\",\n                 rb_class2name(CLASS_OF(block_args)));\n    }\n    if (RARRAY(block_args)->len != 2) {\n        rb_raise(rb_eArgError,\n                 \"%s() %s wrong size of array (%ld for 2)\",\n                 v->lex_is_iterator ? rb_id2name(v->lexmid) : \"next_token\",\n                 v->lex_is_iterator ? \"yielded\" : \"returned\",\n                 RARRAY(block_args)->len);\n    }\n    *tok = AREF(block_args, 0);\n    *val = AREF(block_args, 1);\n}\n\n#define SHIFT(v,act,tok,val) shift(v,act,tok,val)\n#define REDUCE(v,act) do {\\\n    switch (reduce(v,act)) {  \\\n      case 0: /* normal */    \\\n        break;                \\\n      case 1: /* yyerror */   \\\n        goto user_yyerror;    \\\n      case 2: /* yyaccept */  \\\n        D_puts(\"u accept\");   \\\n        goto accept;          \\\n      default:                \\\n        break;                \\\n    }                         \\\n} while (0)\n\nstatic void\nparse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume)\n{\n    long i;              /* table index */\n    long act;            /* action type */\n    VALUE act_value;     /* action type, VALUE version */\n    int read_next = 1;   /* true if we need to read next token */\n    VALUE tmp;\n\n    if (resume)\n        goto resume;\n    \n    while (1) {\n        D_puts(\"\");\n        D_puts(\"---- enter new loop ----\");\n        D_puts(\"\");\n\n        D_printf(\"(act) k1=%ld\\n\", v->curstate);\n        tmp = AREF(v->action_pointer, v->curstate);\n        if (NIL_P(tmp)) goto notfound;\n        D_puts(\"(act) pointer[k1] ok\");\n        i = NUM2LONG(tmp);\n\n        D_printf(\"read_next=%d\\n\", read_next);\n        if (read_next && (v->t != vFINAL_TOKEN)) {\n            if (v->lex_is_iterator) {\n                D_puts(\"resuming...\");\n                if (v->fin) rb_raise(rb_eArgError, \"token given after EOF\");\n                v->i = i;  /* save i */\n                return;\n              resume:\n                D_puts(\"resumed\");\n                i = v->i;  /* load i */\n            }\n            else {\n                D_puts(\"next_token\");\n                tmp = rb_funcall(v->parser, id_nexttoken, 0);\n                extract_user_token(v, tmp, &tok, &val);\n            }\n            /* convert token */\n            v->t = rb_hash_aref(v->token_table, tok);\n            if (NIL_P(v->t)) {\n                v->t = vERROR_TOKEN;\n            }\n            D_printf(\"(act) t(k2)=%ld\\n\", NUM2LONG(v->t));\n            if (v->debug) {\n                rb_funcall(v->parser, id_d_read_token,\n                           3, v->t, tok, val);\n            }\n        }\n        read_next = 0;\n\n        i += NUM2LONG(v->t);\n        D_printf(\"(act) i=%ld\\n\", i);\n        if (i < 0) goto notfound;\n\n        act_value = AREF(v->action_table, i);\n        if (NIL_P(act_value)) goto notfound;\n        act = NUM2LONG(act_value);\n        D_printf(\"(act) table[i]=%ld\\n\", act);\n\n        tmp = AREF(v->action_check, i);\n        if (NIL_P(tmp)) goto notfound;\n        if (NUM2LONG(tmp) != v->curstate) goto notfound;\n        D_printf(\"(act) check[i]=%ld\\n\", NUM2LONG(tmp));\n\n        D_puts(\"(act) found\");\n      act_fixed:\n        D_printf(\"act=%ld\\n\", act);\n        goto handle_act;\n    \n      notfound:\n        D_puts(\"(act) not found: use default\");\n        act_value = AREF(v->action_default, v->curstate);\n        act = NUM2LONG(act_value);\n        goto act_fixed;\n\n\n      handle_act:\n        if (act > 0 && act < v->shift_n) {\n            D_puts(\"shift\");\n            if (v->errstatus > 0) {\n                v->errstatus--;\n                rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus));\n            }\n            SHIFT(v, act, v->t, val);\n            read_next = 1;\n        }\n        else if (act < 0 && act > -(v->reduce_n)) {\n            D_puts(\"reduce\");\n            REDUCE(v, act);\n        }\n        else if (act == -(v->reduce_n)) {\n            goto error;\n          error_recovered:\n            ;   /* goto label requires stmt */\n        }\n        else if (act == v->shift_n) {\n            D_puts(\"accept\");\n            goto accept;\n        }\n        else {\n            rb_raise(RaccBug, \"[Racc Bug] unknown act value %ld\", act);\n        }\n\n        if (v->debug) {\n            rb_funcall(v->parser, id_d_next_state,\n                       2, LONG2NUM(v->curstate), v->state);\n        }\n    }\n    /* not reach */\n\n\n  accept:\n    if (v->debug) rb_funcall(v->parser, id_d_accept, 0);\n    v->retval = RARRAY(v->vstack)->ptr[0];\n    v->fin = CP_FIN_ACCEPT;\n    return;\n\n\n  error:\n    D_printf(\"error detected, status=%ld\\n\", v->errstatus);\n    if (v->errstatus == 0) {\n        v->nerr++;\n        rb_funcall(v->parser, id_onerror,\n                   3, v->t, val, v->vstack);\n    }\n  user_yyerror:\n    if (v->errstatus == 3) {\n        if (v->t == vFINAL_TOKEN) {\n            v->retval = Qfalse;\n            v->fin = CP_FIN_EOT;\n            return;\n        }\n        read_next = 1;\n    }\n    v->errstatus = 3;\n    rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus));\n\n    /* check if we can shift/reduce error token */\n    D_printf(\"(err) k1=%ld\\n\", v->curstate);\n    D_printf(\"(err) k2=%d (error)\\n\", ERROR_TOKEN);\n    while (1) {\n        tmp = AREF(v->action_pointer, v->curstate);\n        if (NIL_P(tmp)) goto error_pop;\n        D_puts(\"(err) pointer[k1] ok\");\n\n        i = NUM2LONG(tmp) + ERROR_TOKEN;\n        D_printf(\"(err) i=%ld\\n\", i);\n        if (i < 0) goto error_pop;\n\n        act_value = AREF(v->action_table, i);\n        if (NIL_P(act_value)) {\n            D_puts(\"(err) table[i] == nil\");\n            goto error_pop;\n        }\n        act = NUM2LONG(act_value);\n        D_printf(\"(err) table[i]=%ld\\n\", act);\n\n        tmp = AREF(v->action_check, i);\n        if (NIL_P(tmp)) {\n            D_puts(\"(err) check[i] == nil\");\n            goto error_pop;\n        }\n        if (NUM2LONG(tmp) != v->curstate) {\n            D_puts(\"(err) check[i] != k1\");\n            goto error_pop;\n        }\n\n        D_puts(\"(err) found: can handle error token\");\n        break;\n          \n      error_pop:\n        D_puts(\"(err) act not found: can't handle error token; pop\");\n\n        if (RARRAY(v->state)->len <= 1) {\n            v->retval = Qnil;\n            v->fin = CP_FIN_CANTPOP;\n            return;\n        }\n        POP(v->state);\n        POP(v->vstack);\n        v->curstate = num_to_long(LAST_I(v->state));\n        if (v->debug) {\n            POP(v->tstack);\n            rb_funcall(v->parser, id_d_e_pop,\n                       3, v->state, v->tstack, v->vstack);\n        }\n    }\n\n    /* shift/reduce error token */\n    if (act > 0 && act < v->shift_n) {\n        D_puts(\"e shift\");\n        SHIFT(v, act, ERROR_TOKEN, val);\n    }\n    else if (act < 0 && act > -(v->reduce_n)) {\n        D_puts(\"e reduce\");\n        REDUCE(v, act);\n    }\n    else if (act == v->shift_n) {\n        D_puts(\"e accept\");\n        goto accept;\n    }\n    else {\n        rb_raise(RaccBug, \"[Racc Bug] unknown act value %ld\", act);\n    }\n    goto error_recovered;\n}\n\nstatic void\nshift(struct cparse_params *v, long act, VALUE tok, VALUE val)\n{\n    PUSH(v->vstack, val);\n    if (v->debug) {\n        PUSH(v->tstack, tok);\n        rb_funcall(v->parser, id_d_shift,\n                   3, tok, v->tstack, v->vstack);\n    }\n    v->curstate = act;\n    PUSH(v->state, LONG2NUM(v->curstate));\n}\n\nstatic int\nreduce(struct cparse_params *v, long act)\n{\n    VALUE code;\n    v->ruleno = -act * 3;\n    code = rb_catch(\"racc_jump\", reduce0, v->value_v);\n    v->errstatus = num_to_long(rb_ivar_get(v->parser, id_errstatus));\n    return NUM2INT(code);\n}\n\nstatic VALUE\nreduce0(VALUE val, VALUE data, VALUE self)\n{\n    struct cparse_params *v;\n    VALUE reduce_to, reduce_len, method_id;\n    long len;\n    ID mid;\n    VALUE tmp, tmp_t = Qundef, tmp_v = Qundef;\n    long i, k1, k2;\n    VALUE goto_state;\n\n    Data_Get_Struct(data, struct cparse_params, v);\n    reduce_len = RARRAY(v->reduce_table)->ptr[v->ruleno];\n    reduce_to  = RARRAY(v->reduce_table)->ptr[v->ruleno+1];\n    method_id  = RARRAY(v->reduce_table)->ptr[v->ruleno+2];\n    len = NUM2LONG(reduce_len);\n    mid = value_to_id(method_id);\n\n    /* call action */\n    if (len == 0) {\n        tmp = Qnil;\n        if (mid != id_noreduce)\n            tmp_v = rb_ary_new();\n        if (v->debug)\n            tmp_t = rb_ary_new();\n    }\n    else {\n        if (mid != id_noreduce) {\n            tmp_v = GET_TAIL(v->vstack, len);\n            tmp = RARRAY(tmp_v)->ptr[0];\n        }\n        else {\n            tmp = RARRAY(v->vstack)->ptr[ RARRAY(v->vstack)->len - len ];\n        }\n        CUT_TAIL(v->vstack, len);\n        if (v->debug) {\n            tmp_t = GET_TAIL(v->tstack, len);\n            CUT_TAIL(v->tstack, len);\n        }\n        CUT_TAIL(v->state, len);\n    }\n    if (mid != id_noreduce) {\n        if (v->use_result_var) {\n            tmp = rb_funcall(v->parser, mid,\n                             3, tmp_v, v->vstack, tmp);\n        }\n        else {\n            tmp = rb_funcall(v->parser, mid,\n                             2, tmp_v, v->vstack);\n        }\n    }\n\n    /* then push result */\n    PUSH(v->vstack, tmp);\n    if (v->debug) {\n        PUSH(v->tstack, reduce_to);\n        rb_funcall(v->parser, id_d_reduce,\n                   4, tmp_t, reduce_to, v->tstack, v->vstack);\n    }\n\n    /* calculate transition state */\n    if (RARRAY(v->state)->len == 0)\n        rb_raise(RaccBug, \"state stack unexpectedly empty\");\n    k2 = num_to_long(LAST_I(v->state));\n    k1 = num_to_long(reduce_to) - v->nt_base;\n    D_printf(\"(goto) k1=%ld\\n\", k1);\n    D_printf(\"(goto) k2=%ld\\n\", k2);\n\n    tmp = AREF(v->goto_pointer, k1);\n    if (NIL_P(tmp)) goto notfound;\n\n    i = NUM2LONG(tmp) + k2;\n    D_printf(\"(goto) i=%ld\\n\", i);\n    if (i < 0) goto notfound;\n\n    goto_state = AREF(v->goto_table, i);\n    if (NIL_P(goto_state)) {\n        D_puts(\"(goto) table[i] == nil\");\n        goto notfound;\n    }\n    D_printf(\"(goto) table[i]=%ld (goto_state)\\n\", NUM2LONG(goto_state));\n\n    tmp = AREF(v->goto_check, i);\n    if (NIL_P(tmp)) {\n        D_puts(\"(goto) check[i] == nil\");\n        goto notfound;\n    }\n    if (tmp != LONG2NUM(k1)) {\n        D_puts(\"(goto) check[i] != table[i]\");\n        goto notfound;\n    }\n    D_printf(\"(goto) check[i]=%ld\\n\", NUM2LONG(tmp));\n\n    D_puts(\"(goto) found\");\n  transit:\n    PUSH(v->state, goto_state);\n    v->curstate = NUM2LONG(goto_state);\n    return INT2FIX(0);\n\n  notfound:\n    D_puts(\"(goto) not found: use default\");\n    /* overwrite `goto-state' by default value */\n    goto_state = AREF(v->goto_default, k1);\n    goto transit;\n}\n\n/* -----------------------------------------------------------------------\n                          Ruby Interface\n----------------------------------------------------------------------- */\n\nvoid\nInit_cparse(void)\n{\n    VALUE Racc, Parser;\n    ID id_racc = rb_intern(\"Racc\");\n\n    if (rb_const_defined(rb_cObject, id_racc)) {\n        Racc = rb_const_get(rb_cObject, id_racc);\n        Parser = rb_const_get_at(Racc, rb_intern(\"Parser\"));\n    }\n    else {\n        Racc = rb_define_module(\"Racc\");\n        Parser = rb_define_class_under(Racc, \"Parser\", rb_cObject);\n    }\n    rb_define_private_method(Parser, \"_racc_do_parse_c\", racc_cparse, 2);\n    rb_define_private_method(Parser, \"_racc_yyparse_c\", racc_yyparse, 4);\n    rb_define_const(Parser, \"Racc_Runtime_Core_Version_C\",\n                    rb_str_new2(RACC_VERSION));\n    rb_define_const(Parser, \"Racc_Runtime_Core_Id_C\",\n        rb_str_new2(\"$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $\"));\n\n    CparseParams = rb_define_class_under(Racc, \"CparseParams\", rb_cObject);\n\n    RaccBug = rb_eRuntimeError;\n\n    id_yydebug      = rb_intern(\"@yydebug\");\n    id_nexttoken    = rb_intern(\"next_token\");\n    id_onerror      = rb_intern(\"on_error\");\n    id_noreduce     = rb_intern(\"_reduce_none\");\n    id_errstatus    = rb_intern(\"@racc_error_status\");\n\n    id_d_shift       = rb_intern(\"racc_shift\");\n    id_d_reduce      = rb_intern(\"racc_reduce\");\n    id_d_accept      = rb_intern(\"racc_accept\");\n    id_d_read_token  = rb_intern(\"racc_read_token\");\n    id_d_next_state  = rb_intern(\"racc_next_state\");\n    id_d_e_pop       = rb_intern(\"racc_e_pop\");\n}\n"
  },
  {
    "path": "ext/racc/cparse/depend",
    "content": "cparse.o: cparse.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/racc/cparse/extconf.rb",
    "content": "# $Id$\n\nrequire 'mkmf'\ncreate_makefile 'racc/cparse'\n"
  },
  {
    "path": "ext/rational/extconf.rb",
    "content": "require 'mkmf'\n\ncreate_makefile('rational')\n"
  },
  {
    "path": "ext/rational/lib/rational.rb",
    "content": "#\n#   rational.rb -\n#       $Release Version: 0.5 $\n#       $Revision: 1.7 $\n#       $Date: 1999/08/24 12:49:28 $\n#       by Keiju ISHITSUKA(SHL Japan Inc.)\n#\n# Documentation by Kevin Jackson and Gavin Sinclair.\n# \n# Performance improvements by Kurt Stephens.\n#\n# When you <tt>require 'rational'</tt>, all interactions between numbers\n# potentially return a rational result.  For example:\n#\n#   1.quo(2)              # -> 0.5\n#   require 'rational'\n#   1.quo(2)              # -> Rational(1,2)\n# \n# See Rational for full documentation.\n#\n\n# Pull in some optimization\nrequire \"rational.so\"\n\n#\n# Creates a Rational number (i.e. a fraction).  +a+ and +b+ should be Integers:\n# \n#   Rational(1,3)           # -> 1/3\n#\n# Note: trying to construct a Rational with floating point or real values\n# produces errors:\n#\n#   Rational(1.1, 2.3)      # -> NoMethodError\n#\ndef Rational(a, b = 1)\n  if a.kind_of?(Rational) && b == 1\n    a\n  else\n    Rational.reduce(a, b)\n  end\nend\n\n#\n# Rational implements a rational class for numbers.\n#\n# <em>A rational number is a number that can be expressed as a fraction p/q\n# where p and q are integers and q != 0.  A rational number p/q is said to have\n# numerator p and denominator q.  Numbers that are not rational are called\n# irrational numbers.</em> (http://mathworld.wolfram.com/RationalNumber.html)\n#\n# To create a Rational Number:\n#   Rational(a,b)             # -> a/b\n#   Rational.new!(a,b)        # -> a/b\n#\n# Examples:\n#   Rational(5,6)             # -> 5/6\n#   Rational(5)               # -> 5/1\n# \n# Rational numbers are reduced to their lowest terms:\n#   Rational(6,10)            # -> 3/5\n#\n# But not if you use the unusual method \"new!\":\n#   Rational.new!(6,10)       # -> 6/10\n#\n# Division by zero is obviously not allowed:\n#   Rational(3,0)             # -> ZeroDivisionError\n#\nclass Rational < Numeric\n  @RCS_ID='-$Id: rational.rb,v 1.7 1999/08/24 12:49:28 keiju Exp keiju $-'\n\n  #\n  # Reduces the given numerator and denominator to their lowest terms.  Use\n  # Rational() instead.\n  #\n  def Rational.reduce(num, den = 1)\n    raise ZeroDivisionError, \"denominator is zero\" if den == 0\n\n    if den < 0\n      num = -num\n      den = -den\n    end\n    gcd = num.gcd(den)\n    num = num.div(gcd)\n    den = den.div(gcd)\n    if den == 1 && defined?(Unify)\n      num\n    else\n      new!(num, den)\n    end\n  end\n\n  #\n  # Implements the constructor.  This method does not reduce to lowest terms or\n  # check for division by zero.  Therefore #Rational() should be preferred in\n  # normal use.\n  #\n  def Rational.new!(num, den = 1)\n    new(num, den)\n  end\n\n  private_class_method :new\n\n  #\n  # This method is actually private.\n  #\n  def initialize(num, den)\n    if den < 0\n      num = -num\n      den = -den\n    end\n    @numerator = num.to_i\n    @denominator = den.to_i\n  end\n\n  #\n  # Returns the addition of this value and +a+.\n  #\n  # Examples:\n  #   r = Rational(3,4)      # -> Rational(3,4)\n  #   r + 1                  # -> Rational(7,4)\n  #   r + 0.5                # -> 1.25\n  #\n  def + (a)\n    case a\n    when Rational # => Rational | Integer\n      Rational(@numerator * a.denominator + a.numerator * @denominator, @denominator * a.denominator)\n    when Integer  # => Rational\n      Rational.reduce(@numerator + a * @denominator, @denominator)\n    when Float\n      self.to_f + a\n    else\n      x, y = a.coerce(self)\n      x + y\n    end\n  end\n\n  #\n  # Returns the difference of this value and +a+.\n  # subtracted.\n  #\n  # Examples:\n  #   r = Rational(3,4)    # -> Rational(3,4)\n  #   r - 1                # -> Rational(-1,4)\n  #   r - 0.5              # -> 0.25\n  #\n  def - (a)\n    case a\n    when Rational # => Rational | Integer\n      Rational(@numerator * a.denominator - a.numerator * @denominator, @denominator * a.denominator)\n    when Integer  # => Rational\n      Rational.reduce(@numerator - a * @denominator, @denominator)\n    when Float\n      self.to_f - a\n    else\n      x, y = a.coerce(self)\n      x - y\n    end\n  end\n\n  #\n  # Unary Minus--Returns the receiver's value, negated.\n  #\n  def -@\n    Rational.new!(-@numerator, @denominator)\n  end\n\n  #\n  # Returns the product of this value and +a+.\n  #\n  # Examples:\n  #   r = Rational(3,4)    # -> Rational(3,4)\n  #   r * 2                # -> Rational(3,2)\n  #   r * 4                # -> Rational(3,1)\n  #   r * 0.5              # -> 0.375\n  #   r * Rational(1,2)    # -> Rational(3,8)\n  #\n  def * (a)\n    case a\n    when Rational\n      Rational(@numerator * a.numerator, @denominator * a.denominator)\n    when Integer\n      Rational(@numerator * a, @denominator)\n    when Float\n      self.to_f * a\n    else\n      x, y = a.coerce(self)\n      x * y\n    end\n  end\n\n  #\n  # Returns the quotient of this value and +a+.\n  #   r = Rational(3,4)    # -> Rational(3,4)\n  #   r / 2                # -> Rational(3,8)\n  #   r / 2.0              # -> 0.375\n  #   r / Rational(1,2)    # -> Rational(3,2)\n  #\n  def / (a)\n    case a\n    when Rational\n      Rational(@numerator * a.denominator, @denominator * a.numerator)\n    when Integer\n      raise ZeroDivisionError, \"division by zero\" if a == 0\n      Rational(@numerator, @denominator * a)\n    when Float\n      self.to_f / a\n    else\n      x, y = a.coerce(self)\n      x / y\n    end\n  end\n\n  #\n  # Returns this value raised to the given power.\n  #\n  # Examples:\n  #   r = Rational(3,4)    # -> Rational(3,4)\n  #   r ** 2               # -> Rational(9,16)\n  #   r ** 2.0             # -> 0.5625\n  #   r ** Rational(1,2)   # -> 0.866025403784439\n  #\n  def ** (other)\n    case other\n    when Rational, Float\n      self.to_f ** other\n    when Integer\n      if other > 0\n\tRational.new!(@numerator ** other, @denominator ** other)\n      elsif other < 0\n\tRational.new!(@denominator ** -other, @numerator ** -other)\n      else\n\tRational.new!(1, 1) # why not Fixnum 1?\n      end\n    else\n      x, y = other.coerce(self)\n      x ** y\n    end\n  end\n\n  def div(other)\n    (self / other).floor\n  end\n\n  #\n  # Returns the remainder when this value is divided by +other+.\n  #\n  # Examples:\n  #   r = Rational(7,4)    # -> Rational(7,4)\n  #   r % Rational(1,2)    # -> Rational(1,4)\n  #   r % 1                # -> Rational(3,4)\n  #   r % Rational(1,7)    # -> Rational(1,28)\n  #   r % 0.26             # -> 0.19\n  #\n  def % (other)\n    value = (self / other).floor\n    self - other * value\n  end\n\n  #\n  # Returns the quotient _and_ remainder.\n  #\n  # Examples:\n  #   r = Rational(7,4)        # -> Rational(7,4)\n  #   r.divmod Rational(1,2)   # -> [3, Rational(1,4)]\n  #\n  def divmod(other)\n    value = (self / other).floor\n    [value, self - other * value]\n  end\n\n  #\n  # Returns the absolute value.\n  #\n  def abs\n    if @numerator > 0\n      self\n    else\n      Rational.new!(-@numerator, @denominator)\n    end\n  end\n\n  # Returns true or false.\n  def zero?\n    @numerator.zero?\n  end\n\n  # See Numeric#nonzero?\n  def nonzero?\n    @numerator.nonzero? ? self : nil\n  end\n\n\n  #\n  # Returns +true+ iff this value is numerically equal to +other+.\n  #\n  # But beware:\n  #   Rational(1,2) == Rational(4,8)          # -> true\n  #   Rational(1,2) == Rational.new!(4,8)     # -> false\n  #\n  # Don't use Rational.new!\n  #\n  def == (other)\n    case other\n    when Rational\n      @numerator == other.numerator && @denominator == other.denominator\n    when Integer\n      @numerator == other && @denominator == 1\n    when Float\n      self.to_f == other\n    else\n      other == self\n    end\n  end\n\n  #\n  # Standard comparison operator.\n  #\n  def <=> (other)\n    case other\n    when Rational\n      @numerator * other.denominator <=> other.numerator * @denominator\n    when Integer\n      @numerator <=> other * @denominator\n    when Float\n      self.to_f <=> other\n    else\n      x, y = other.coerce(self) rescue return nil\n      x <=> y\n    end\n  end\n\n  def coerce(other)\n    case other\n    when Float\n      return other, self.to_f\n    when Integer\n      return Rational.new!(other, 1), self\n    else\n      super\n    end\n  end\n\n  #\n  # Converts the rational to an Integer.  Not the _nearest_ integer, the\n  # truncated integer.  Study the following example carefully:\n  #   Rational(+7,4).to_i             # -> 1\n  #   Rational(-7,4).to_i             # -> -1\n  #   (-1.75).to_i                    # -> -1\n  #\n  # In other words:\n  #   Rational(-7,4) == -1.75                 # -> true\n  #   Rational(-7,4).to_i == (-1.75).to_i     # -> true\n  #\n\n\n  def floor()\n    @numerator.div(@denominator)\n  end\n\n  def ceil()\n    -((-@numerator).div(@denominator))\n  end\n\n  def truncate()\n    if @numerator < 0\n      -((-@numerator).div(@denominator))\n    else\n      @numerator.div(@denominator)\n    end\n  end\n\n  alias_method :to_i, :truncate\n\n  def round()\n    if @numerator < 0\n      -((@numerator * -2 + @denominator).div(@denominator * 2))\n    else\n      ((@numerator * 2 + @denominator).div(@denominator * 2))\n    end\n  end\n\n  #\n  # Converts the rational to a Float.\n  #\n  def to_f\n    @numerator.to_f/@denominator.to_f\n  end\n\n  #\n  # Returns a string representation of the rational number.\n  #\n  # Example:\n  #   Rational(3,4).to_s          #  \"3/4\"\n  #   Rational(8).to_s            #  \"8\"\n  #\n  def to_s\n    if @denominator == 1\n      @numerator.to_s\n    else\n      \"#{@numerator}/#{@denominator}\"\n    end\n  end\n\n  #\n  # Returns +self+.\n  #\n  def to_r\n    self\n  end\n\n  #\n  # Returns a reconstructable string representation:\n  #\n  #   Rational(5,8).inspect     # -> \"Rational(5, 8)\"\n  #\n  def inspect\n    \"Rational(#{@numerator.inspect}, #{@denominator.inspect})\"\n  end\n\n  #\n  # Returns a hash code for the object.\n  #\n  def hash\n    @numerator.hash ^ @denominator.hash\n  end\n\n  attr :numerator\n  attr :denominator\n\n  private :initialize\nend\n\nclass Integer\n  #\n  # In an integer, the value _is_ the numerator of its rational equivalent.\n  # Therefore, this method returns +self+.\n  #\n  def numerator\n    self\n  end\n\n  #\n  # In an integer, the denominator is 1.  Therefore, this method returns 1.\n  #\n  def denominator\n    1\n  end\n\n  #\n  # Returns a Rational representation of this integer.\n  #\n  def to_r\n    Rational(self, 1)\n  end\n\n  #\n  # Returns the <em>greatest common denominator</em> of the two numbers (+self+\n  # and +n+).\n  #\n  # Examples:\n  #   72.gcd 168           # -> 24\n  #   19.gcd 36            # -> 1\n  #\n  # The result is positive, no matter the sign of the arguments.\n  #\n  def gcd(other)\n    min = self.abs\n    max = other.abs\n    while min > 0\n      tmp = min\n      min = max % min\n      max = tmp\n    end\n    max\n  end\n\n  #\n  # Returns the <em>lowest common multiple</em> (LCM) of the two arguments\n  # (+self+ and +other+).\n  #\n  # Examples:\n  #   6.lcm 7        # -> 42\n  #   6.lcm 9        # -> 18\n  #\n  def lcm(other)\n    if self.zero? or other.zero?\n      0\n    else\n      (self.div(self.gcd(other)) * other).abs\n    end\n  end\n\n  #\n  # Returns the GCD _and_ the LCM (see #gcd and #lcm) of the two arguments\n  # (+self+ and +other+).  This is more efficient than calculating them\n  # separately.\n  #\n  # Example:\n  #   6.gcdlcm 9     # -> [3, 18]\n  #\n  def gcdlcm(other)\n    gcd = self.gcd(other)\n    if self.zero? or other.zero?\n      [gcd, 0]\n    else\n      [gcd, (self.div(gcd) * other).abs]\n    end\n  end\nend\n\nclass Fixnum\n  remove_method :quo\n\n  # If Rational is defined, returns a Rational number instead of a Float.\n  def quo(other)\n    Rational.new!(self, 1) / other\n  end\n  alias rdiv quo\n\n  # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0).\n  def rpower (other)\n    if other >= 0\n      self.power!(other)\n    else\n      Rational.new!(self, 1)**other\n    end\n  end\n\nend\n\nclass Bignum\n  remove_method :quo\n\n  # If Rational is defined, returns a Rational number instead of a Float.\n  def quo(other)\n    Rational.new!(self, 1) / other\n  end\n  alias rdiv quo\n\n  # Returns a Rational number if the result is in fact rational (i.e. +other+ < 0).\n  def rpower (other)\n    if other >= 0\n      self.power!(other)\n    else\n      Rational.new!(self, 1)**other\n    end\n  end\n\nend\n\nunless defined? 1.power!\n  class Fixnum\n    alias power! **\n    alias ** rpower\n  end\n  class Bignum\n    alias power! **\n    alias ** rpower\n  end\nend\n"
  },
  {
    "path": "ext/rational/rational.c",
    "content": "#include \"ruby.h\"\n\n/*\n * call-seq:\n *    fixnum.gcd(fixnum)  ->  fixnum\n *\n * Fixnum-specific optimized version of Integer#gcd.  Delegates to\n * Integer#gcd as necessary.\n */\nstatic VALUE\nfix_gcd(self, other)\n    VALUE self, other;\n{\n    long a, b, min, max;\n\n    /*\n     * Note: Cannot handle values <= FIXNUM_MIN here due to overflow during negation.\n     */\n    if (!FIXNUM_P(other) ||\n\t(a = FIX2LONG(self)) <= FIXNUM_MIN ||\n\t(b = FIX2LONG(other)) <= FIXNUM_MIN ) {\n\t/* Delegate to Integer#gcd */\n\treturn rb_call_super(1, &other);\n    }\n\n    min = a < 0 ? -a : a;\n    max = b < 0 ? -b : b;\n\n    while (min > 0) {\n\tlong tmp = min;\n\tmin = max % min;\n\tmax = tmp;\n    }\n\n    return LONG2FIX(max);\n}\n\nvoid\nInit_rational()\n{\n    rb_define_method(rb_cFixnum, \"gcd\", fix_gcd, 1);\n}\n"
  },
  {
    "path": "ext/readline/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/readline/README",
    "content": "Extension for GNU Readline Library\n\nExample:\n\n  require \"readline\"\n  include Readline\n\n  line = readline(\"Prompt> \", true)\n\n[Readline]\n\n<module function>\n\nreadline(prompt, add_history=nil)\n\n  Reads one line with line editing.  The inputted line is added to the\n  history if add_history is true.\n\n<class methods>\n\ncompletion_proc = proc\n\n  Specifies a Proc object to determine completion behavior.  It\n  should take input-string, and return an array of completion\n  candidates.\n\ncompletion_proc\n\n  Returns the completion Proc object.\n\ncompletion_case_fold = bool\n\n  Sets whether or not to ignore case on completion.\n\ncompletion_case_fold\n\n  Returns true if completion ignores case.\n\ncompletion_append_character = char\n\n  Specifies a character to be appended on completion.\n  Nothing will be appended if an empty string (\"\") or nil is\n  specified.\n\ncompletion_append_character\n\n  Returns a string containing a character to be appended on\n  completion.  The default is a space (\" \").\n\nvi_editing_mode\n\n  Specifies VI editing mode.\n\nemacs_editing_mode\n\n  Specifies Emacs editing mode.\n\n<class constants>\n\nHISTORY\n\nThe history buffer.  It behaves just like an array.\n"
  },
  {
    "path": "ext/readline/README.ja",
    "content": "GNU Readline LibraryѤ뤿γĥ⥸塼Ǥ\n\nrequire \"readline\"\ninclude Readline\n\nline = readline(\"Prompt> \", true)\n\nΤ褦˻ѤƤ\n\n[Readline]\n\n<⥸塼ؿ>\n\nreadline(prompt, add_history=nil)\n\n  Ϥɤ߹ߤޤ\n  add_historytrueξ硢ҥȥɤ߹ʸɲäޤ\n\n<饹᥽å>\n\ncompletion_proc = proc\n\n  䴰ưꤹProc֥Ȥꤷޤ\n  procϰʸꡢʸ֤褦\n  Ƥ\n\ncompletion_proc\n\n  䴰ưꤹProc֥Ȥ֤ޤ\n\ncompletion_case_fold = case_fold\n\n  䴰ʸʸ̤ʤ硢trueꤷޤ\n\ncompletion_case_fold\n\n  䴰ʸʸ̤ʤ硢true֤ޤ\n\ncompletion_append_character = char\n\n  䴰ղäʸʸǻꤷޤƬΰʸ\n  ꤵ졢ʸ (\"\") ޤ nil ꤹȲղ\n  ʤʤޤ\n\ncompletion_append_character\n\n  䴰ղäʸʸ֤ޤǥեȤ\n   (\" \") Ǥ\n\nvi_editing_mode\n\n  VI⡼ɤˤʤޤ\n\nemacs_editing_mode\n\n  Emacs⡼ɤˤʤޤ\n\n<饹>\n\nHISTORY\n\nҥȥФϤ̤ƹԤäƤ\nƱ褦˰褦ˤʤäƤޤ\n"
  },
  {
    "path": "ext/readline/depend",
    "content": "readline.o: readline.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/readline/extconf.rb",
    "content": "require \"mkmf\"\n\n$readline_headers = [\"stdio.h\"]\n\ndef have_readline_header(header)\n  if have_header(header)\n    $readline_headers.push(header)\n    return true\n  else\n    return false\n  end\nend\n\ndef have_readline_var(var)\n  return have_var(var, $readline_headers)\nend\n\ndir_config('curses')\ndir_config('ncurses')\ndir_config('termcap')\ndir_config(\"readline\")\nenable_libedit = enable_config(\"libedit\")\nhave_library(\"user32\", nil) if /cygwin/ === RUBY_PLATFORM\nhave_library(\"ncurses\", \"tgetnum\") ||\n  have_library(\"termcap\", \"tgetnum\") ||\n  have_library(\"curses\", \"tgetnum\")\n\nif enable_libedit\n  unless (have_readline_header(\"editline/readline.h\") ||\n          have_readline_header(\"readline/readline.h\")) &&\n          have_library(\"edit\", \"readline\")\n    exit\n  end\nelse\n  unless ((have_readline_header(\"readline/readline.h\") &&\n           have_readline_header(\"readline/history.h\")) &&\n           (have_library(\"readline\", \"readline\") ||\n            have_library(\"edit\", \"readline\"))) ||\n            (have_readline_header(\"editline/readline.h\") &&\n             have_library(\"edit\", \"readline\"))\n    exit\n  end\nend\n\nhave_func(\"rl_filename_completion_function\")\nhave_func(\"rl_username_completion_function\")\nhave_func(\"rl_completion_matches\")\nhave_readline_var(\"rl_deprep_term_function\")\nhave_readline_var(\"rl_completion_append_character\")\nhave_readline_var(\"rl_basic_word_break_characters\")\nhave_readline_var(\"rl_completer_word_break_characters\")\nhave_readline_var(\"rl_basic_quote_characters\")\nhave_readline_var(\"rl_completer_quote_characters\")\nhave_readline_var(\"rl_filename_quote_characters\")\nhave_readline_var(\"rl_attempted_completion_over\")\nhave_readline_var(\"rl_library_version\")\nhave_readline_var(\"rl_event_hook\")\nhave_func(\"rl_cleanup_after_signal\")\nhave_func(\"rl_clear_signals\")\nhave_func(\"rl_vi_editing_mode\")\nhave_func(\"rl_emacs_editing_mode\")\nhave_func(\"replace_history_entry\")\nhave_func(\"remove_history\")\ncreate_makefile(\"readline\")\n"
  },
  {
    "path": "ext/readline/readline.c",
    "content": "/* readline.c -- GNU Readline module\n   Copyright (C) 1997-2001  Shugo Maeda */\n\n#include \"config.h\"\n#include <errno.h>\n#include <stdio.h>\n#include <ctype.h>\n#include <string.h>\n#ifdef HAVE_READLINE_READLINE_H\n#include <readline/readline.h>\n#endif\n#ifdef HAVE_READLINE_HISTORY_H\n#include <readline/history.h>\n#endif\n#ifdef HAVE_EDITLINE_READLINE_H\n#include <editline/readline.h>\n#endif\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"rubysig.h\"\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\nstatic VALUE mReadline;\n\n#define TOLOWER(c) (isupper(c) ? tolower(c) : c)\n\n#define COMPLETION_PROC \"completion_proc\"\n#define COMPLETION_CASE_FOLD \"completion_case_fold\"\nstatic ID completion_proc, completion_case_fold;\n\n#ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION\n# define rl_filename_completion_function filename_completion_function\n#endif\n#ifndef HAVE_RL_USERNAME_COMPLETION_FUNCTION\n# define rl_username_completion_function username_completion_function\n#endif\n#ifndef HAVE_RL_COMPLETION_MATCHES\n# define rl_completion_matches completion_matches\n#endif\n\nstatic char **readline_attempted_completion_function(const char *text,\n                                                     int start, int end);\n\n#ifdef HAVE_RL_EVENT_HOOK\n#ifdef DOSISH\n#define BUSY_WAIT 1\n#else\n#define BUSY_WAIT 0\n#endif\n\nstatic int readline_event(void);\nstatic int\nreadline_event()\n{\n#if BUSY_WAIT\n    rb_thread_schedule();\n#else\n    fd_set rset;\n\n    FD_ZERO(&rset);\n    FD_SET(fileno(rl_instream), &rset);\n    rb_thread_select(fileno(rl_instream) + 1, &rset, NULL, NULL, NULL);\n    return 0;\n#endif\n}\n#endif\n\nstatic VALUE\nreadline_readline(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE tmp, add_hist, result;\n    char *prompt = NULL;\n    char *buff;\n    int status;\n    rb_io_t *ofp, *ifp;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"02\", &tmp, &add_hist) > 0) {\n\tSafeStringValue(tmp);\n\tprompt = RSTRING(tmp)->ptr;\n    }\n\n    if (!isatty(0) && errno == EBADF) rb_raise(rb_eIOError, \"stdin closed\");\n\n    Check_Type(rb_stdout, T_FILE);\n    GetOpenFile(rb_stdout, ofp);\n    rl_outstream = GetWriteFile(ofp);\n    Check_Type(rb_stdin, T_FILE);\n    GetOpenFile(rb_stdin, ifp);\n    rl_instream = GetReadFile(ifp);\n    buff = (char*)rb_protect((VALUE(*)_((VALUE)))readline, (VALUE)prompt,\n                              &status);\n    if (status) {\n#if defined HAVE_RL_CLEANUP_AFTER_SIGNAL\n        /* restore terminal mode and signal handler*/\n        rl_cleanup_after_signal();\n#elif defined HAVE_RL_DEPREP_TERM_FUNCTION\n        /* restore terminal mode */\n\tif (rl_deprep_term_function != NULL) /* NULL in libedit. [ruby-dev:29116] */\n\t    (*rl_deprep_term_function)();\n\telse\n#else\n        rl_deprep_terminal();\n#endif\n        rb_jump_tag(status);\n    }\n\n    if (RTEST(add_hist) && buff) {\n\tadd_history(buff);\n    }\n    if (buff)\n\tresult = rb_tainted_str_new2(buff);\n    else\n\tresult = Qnil;\n    if (buff) system_free(buff);\n    return result;\n}\n\nstatic VALUE\nreadline_s_set_completion_proc(self, proc)\n    VALUE self;\n    VALUE proc;\n{\n    rb_secure(4);\n    if (!rb_respond_to(proc, rb_intern(\"call\")))\n\trb_raise(rb_eArgError, \"argument must respond to `call'\");\n    return rb_ivar_set(mReadline, completion_proc, proc);\n}\n\nstatic VALUE\nreadline_s_get_completion_proc(self)\n    VALUE self;\n{\n    rb_secure(4);\n    return rb_attr_get(mReadline, completion_proc);\n}\n\nstatic VALUE\nreadline_s_set_completion_case_fold(self, val)\n    VALUE self;\n    VALUE val;\n{\n    rb_secure(4);\n    return rb_ivar_set(mReadline, completion_case_fold, val);\n}\n\nstatic VALUE\nreadline_s_get_completion_case_fold(self)\n    VALUE self;\n{\n    rb_secure(4);\n    return rb_attr_get(mReadline, completion_case_fold);\n}\n\nstatic char **\nreadline_attempted_completion_function(text, start, end)\n    const char *text;\n    int start;\n    int end;\n{\n    VALUE proc, ary, temp;\n    char **result;\n    int case_fold;\n    int i, matches;\n    size_t len;\n\n    proc = rb_attr_get(mReadline, completion_proc);\n    if (NIL_P(proc))\n\treturn NULL;\n#ifdef HAVE_RL_ATTEMPTED_COMPLETION_OVER\n    rl_attempted_completion_over = 1;\n#endif\n    case_fold = RTEST(rb_attr_get(mReadline, completion_case_fold));\n    ary = rb_funcall(proc, rb_intern(\"call\"), 1, rb_tainted_str_new2(text));\n    if (TYPE(ary) != T_ARRAY)\n\tary = rb_Array(ary);\n    matches = RARRAY(ary)->len;\n    if (matches == 0)\n\treturn NULL;\n    result = system_malloc(sizeof(char *) * (matches + 2));\n    for (i = 0; i < matches; i++) {\n\ttemp = rb_obj_as_string(RARRAY(ary)->ptr[i]);\n\tresult[i + 1] = system_malloc(sizeof(char) * (RSTRING(temp)->len + 1));\n\tstrcpy(result[i + 1], RSTRING(temp)->ptr);\n    }\n    result[matches + 1] = NULL;\n\n    if (matches == 1) {\n\tlen = strlen(result[1]);\n\tresult[0] = (char *) system_malloc(sizeof(char) * (len + 1));\n\tmemcpy(result[0], result[1], sizeof(char) * len);\n\tresult[0][len] = '\\0';\n    }\n    else {\n\tregister int i = 1;\n\tint low = 100000;\n\n\twhile (i < matches) {\n\t    register int c1, c2, si;\n\n\t    if (case_fold) {\n\t\tfor (si = 0;\n\t\t     (c1 = TOLOWER(result[i][si])) &&\n\t\t\t (c2 = TOLOWER(result[i + 1][si]));\n\t\t     si++)\n\t\t    if (c1 != c2) break;\n\t    } else {\n\t\tfor (si = 0;\n\t\t     (c1 = result[i][si]) &&\n\t\t\t (c2 = result[i + 1][si]);\n\t\t     si++)\n\t\t    if (c1 != c2) break;\n\t    }\n\n\t    if (low > si) low = si;\n\t    i++;\n\t}\n\tresult[0] = system_malloc(sizeof(char) * (low + 1));\n\tstrncpy(result[0], result[1], low);\n\tresult[0][low] = '\\0';\n    }\n\n    return result;\n}\n\nstatic VALUE\nreadline_s_vi_editing_mode(self)\n    VALUE self;\n{\n#ifdef HAVE_RL_VI_EDITING_MODE\n    rb_secure(4);\n    rl_vi_editing_mode(1,0);\n    return Qnil;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_VI_EDITING_MODE */\n}\n\nstatic VALUE\nreadline_s_emacs_editing_mode(self)\n    VALUE self;\n{\n#ifdef HAVE_RL_EMACS_EDITING_MODE\n    rb_secure(4);\n    rl_emacs_editing_mode(1,0);\n    return Qnil;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_EMACS_EDITING_MODE */\n}\n\nstatic VALUE\nreadline_s_set_completion_append_character(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER\n    rb_secure(4);\n    if (NIL_P(str)) {\n\trl_completion_append_character = '\\0';\n    }\n    else {\n\tSafeStringValue(str);\n\tif (RSTRING(str)->len == 0) {\n\t    rl_completion_append_character = '\\0';\n\t} else {\n\t    rl_completion_append_character = RSTRING(str)->ptr[0];\n\t}\n    }\n    return self;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */\n}\n\nstatic VALUE\nreadline_s_get_completion_append_character(self)\n    VALUE self;\n{\n#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER\n    VALUE str;\n\n    rb_secure(4);\n    if (rl_completion_append_character == '\\0')\n\treturn Qnil;\n\n    str = rb_str_new(\"\", 1);\n    RSTRING(str)->ptr[0] = rl_completion_append_character;\n    return str;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_COMPLETION_APPEND_CHARACTER */\n}\n\nstatic VALUE\nreadline_s_set_basic_word_break_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS\n    static char *basic_word_break_characters = NULL;\n\n    rb_secure(4);\n    SafeStringValue(str);\n    if (basic_word_break_characters == NULL) {\n\tbasic_word_break_characters =\n\t    ALLOC_N(char, RSTRING(str)->len + 1);\n    }\n    else {\n\tREALLOC_N(basic_word_break_characters, char, RSTRING(str)->len + 1);\n    }\n    strncpy(basic_word_break_characters,\n\t    RSTRING(str)->ptr, RSTRING(str)->len);\n    basic_word_break_characters[RSTRING(str)->len] = '\\0';\n    rl_basic_word_break_characters = basic_word_break_characters;\n    return self;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_get_basic_word_break_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_BASIC_WORD_BREAK_CHARACTERS\n    rb_secure(4);\n    if (rl_basic_word_break_characters == NULL)\n\treturn Qnil;\n    return rb_tainted_str_new2(rl_basic_word_break_characters);\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_BASIC_WORD_BREAK_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_set_completer_word_break_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS\n    static char *completer_word_break_characters = NULL;\n\n    rb_secure(4);\n    SafeStringValue(str);\n    if (completer_word_break_characters == NULL) {\n\tcompleter_word_break_characters =\n\t    ALLOC_N(char, RSTRING(str)->len + 1);\n    }\n    else {\n\tREALLOC_N(completer_word_break_characters, char, RSTRING(str)->len + 1);\n    }\n    strncpy(completer_word_break_characters,\n\t    RSTRING(str)->ptr, RSTRING(str)->len);\n    completer_word_break_characters[RSTRING(str)->len] = '\\0';\n    rl_completer_word_break_characters = completer_word_break_characters;\n    return self;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_get_completer_word_break_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS\n    rb_secure(4);\n    if (rl_completer_word_break_characters == NULL)\n\treturn Qnil;\n    return rb_tainted_str_new2(rl_completer_word_break_characters);\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_set_basic_quote_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS\n    static char *basic_quote_characters = NULL;\n\n    rb_secure(4);\n    SafeStringValue(str);\n    if (basic_quote_characters == NULL) {\n\tbasic_quote_characters =\n\t    ALLOC_N(char, RSTRING(str)->len + 1);\n    }\n    else {\n\tREALLOC_N(basic_quote_characters, char, RSTRING(str)->len + 1);\n    }\n    strncpy(basic_quote_characters,\n\t    RSTRING(str)->ptr, RSTRING(str)->len);\n    basic_quote_characters[RSTRING(str)->len] = '\\0';\n    rl_basic_quote_characters = basic_quote_characters;\n\n    return self;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_get_basic_quote_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_BASIC_QUOTE_CHARACTERS\n    rb_secure(4);\n    if (rl_basic_quote_characters == NULL)\n\treturn Qnil;\n    return rb_tainted_str_new2(rl_basic_quote_characters);\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_BASIC_QUOTE_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_set_completer_quote_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS\n    static char *completer_quote_characters = NULL;\n\n    rb_secure(4);\n    SafeStringValue(str);\n    if (completer_quote_characters == NULL) {\n\tcompleter_quote_characters =\n\t    ALLOC_N(char, RSTRING(str)->len + 1);\n    }\n    else {\n\tREALLOC_N(completer_quote_characters, char, RSTRING(str)->len + 1);\n    }\n    strncpy(completer_quote_characters,\n\t    RSTRING(str)->ptr, RSTRING(str)->len);\n    completer_quote_characters[RSTRING(str)->len] = '\\0';\n    rl_completer_quote_characters = completer_quote_characters;\n\n    return self;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_get_completer_quote_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_COMPLETER_QUOTE_CHARACTERS\n    rb_secure(4);\n    if (rl_completer_quote_characters == NULL)\n\treturn Qnil;\n    return rb_tainted_str_new2(rl_completer_quote_characters);\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_COMPLETER_QUOTE_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_set_filename_quote_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS\n    static char *filename_quote_characters = NULL;\n\n    rb_secure(4);\n    SafeStringValue(str);\n    if (filename_quote_characters == NULL) {\n\tfilename_quote_characters =\n\t    ALLOC_N(char, RSTRING(str)->len + 1);\n    }\n    else {\n\tREALLOC_N(filename_quote_characters, char, RSTRING(str)->len + 1);\n    }\n    strncpy(filename_quote_characters,\n\t    RSTRING(str)->ptr, RSTRING(str)->len);\n    filename_quote_characters[RSTRING(str)->len] = '\\0';\n    rl_filename_quote_characters = filename_quote_characters;\n\n    return self;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */\n}\n\nstatic VALUE\nreadline_s_get_filename_quote_characters(self, str)\n    VALUE self, str;\n{\n#ifdef HAVE_RL_FILENAME_QUOTE_CHARACTERS\n    rb_secure(4);\n    if (rl_filename_quote_characters == NULL)\n\treturn Qnil;\n    return rb_tainted_str_new2(rl_filename_quote_characters);\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif /* HAVE_RL_FILENAME_QUOTE_CHARACTERS */\n}\n\nstatic VALUE\nhist_to_s(self)\n    VALUE self;\n{\n    return rb_str_new2(\"HISTORY\");\n}\n\nstatic VALUE\nhist_get(self, index)\n    VALUE self;\n    VALUE index;\n{\n    HIST_ENTRY *entry;\n    int i;\n\n    rb_secure(4);\n    i = NUM2INT(index);\n    if (i < 0) {\n        i += history_length;\n    }\n    entry = history_get(history_base + i);\n    if (entry == NULL) {\n\trb_raise(rb_eIndexError, \"invalid index\");\n    }\n    return rb_tainted_str_new2(entry->line);\n}\n\nstatic VALUE\nhist_set(self, index, str)\n    VALUE self;\n    VALUE index;\n    VALUE str;\n{\n#ifdef HAVE_REPLACE_HISTORY_ENTRY\n    HIST_ENTRY *entry;\n    int i;\n\n    rb_secure(4);\n    i = NUM2INT(index);\n    SafeStringValue(str);\n    if (i < 0) {\n        i += history_length;\n    }\n    entry = replace_history_entry(i, RSTRING(str)->ptr, NULL);\n    if (entry == NULL) {\n\trb_raise(rb_eIndexError, \"invalid index\");\n    }\n    return str;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif\n}\n\nstatic VALUE\nhist_push(self, str)\n    VALUE self;\n    VALUE str;\n{\n    rb_secure(4);\n    SafeStringValue(str);\n    add_history(RSTRING(str)->ptr);\n    return self;\n}\n\nstatic VALUE\nhist_push_method(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE str;\n    \n    rb_secure(4);\n    while (argc--) {\n\tstr = *argv++;\n\tSafeStringValue(str);\n\tadd_history(RSTRING(str)->ptr);\n    }\n    return self;\n}\n\nstatic VALUE\nrb_remove_history(index)\n    int index;\n{\n#ifdef HAVE_REMOVE_HISTORY\n    HIST_ENTRY *entry;\n    VALUE val;\n\n    rb_secure(4);\n    entry = remove_history(index);\n    if (entry) {\n        val = rb_tainted_str_new2(entry->line);\n        system_free((void *) entry->line);\n        system_free(entry);\n        return val;\n    }\n    return Qnil;\n#else\n    rb_notimplement();\n    return Qnil; /* not reached */\n#endif\n}\n\nstatic VALUE\nhist_pop(self)\n    VALUE self;\n{\n    rb_secure(4);\n    if (history_length > 0) {\n\treturn rb_remove_history(history_length - 1);\n    } else {\n\treturn Qnil;\n    }\n}\n\nstatic VALUE\nhist_shift(self)\n    VALUE self;\n{\n    rb_secure(4);\n    if (history_length > 0) {\n\treturn rb_remove_history(0);\n    } else {\n\treturn Qnil;\n    }\n}\n\nstatic VALUE\nhist_each(self)\n    VALUE self;\n{\n    HIST_ENTRY *entry;\n    int i;\n\n    rb_secure(4);\n    for (i = 0; i < history_length; i++) {\n        entry = history_get(history_base + i);\n        if (entry == NULL)\n            break;\n\trb_yield(rb_tainted_str_new2(entry->line));\n    }\n    return self;\n}\n\nstatic VALUE\nhist_length(self)\n    VALUE self;\n{\n    rb_secure(4);\n    return INT2NUM(history_length);\n}\n\nstatic VALUE\nhist_empty_p(self)\n    VALUE self;\n{\n    rb_secure(4);\n    return history_length == 0 ? Qtrue : Qfalse;\n}\n\nstatic VALUE\nhist_delete_at(self, index)\n    VALUE self;\n    VALUE index;\n{\n    int i;\n\n    rb_secure(4);\n    i = NUM2INT(index);\n    if (i < 0)\n        i += history_length;\n    if (i < 0 || i > history_length - 1) {\n\trb_raise(rb_eIndexError, \"invalid index\");\n    }\n    return rb_remove_history(i);\n}\n\nstatic VALUE\nfilename_completion_proc_call(self, str)\n    VALUE self;\n    VALUE str;\n{\n    VALUE result;\n    char **matches;\n    int i;\n\n    matches = rl_completion_matches(StringValuePtr(str),\n\t\t\t\t    rl_filename_completion_function);\n    if (matches) {\n\tresult = rb_ary_new();\n\tfor (i = 0; matches[i]; i++) {\n\t    rb_ary_push(result, rb_tainted_str_new2(matches[i]));\n\t    system_free(matches[i]);\n\t}\n\tsystem_free(matches);\n\tif (RARRAY(result)->len >= 2)\n\t    rb_ary_shift(result);\n    }\n    else {\n\tresult = Qnil;\n    }\n    return result;\n}\n\nstatic VALUE\nusername_completion_proc_call(self, str)\n    VALUE self;\n    VALUE str;\n{\n    VALUE result;\n    char **matches;\n    int i;\n\n    matches = rl_completion_matches(StringValuePtr(str),\n\t\t\t\t    rl_username_completion_function);\n    if (matches) {\n\tresult = rb_ary_new();\n\tfor (i = 0; matches[i]; i++) {\n\t    rb_ary_push(result, rb_tainted_str_new2(matches[i]));\n\t    system_free(matches[i]);\n\t}\n\tsystem_free(matches);\n\tif (RARRAY(result)->len >= 2)\n\t    rb_ary_shift(result);\n    }\n    else {\n\tresult = Qnil;\n    }\n    return result;\n}\n\nvoid\nInit_readline()\n{\n    VALUE history, fcomp, ucomp;\n\n    /* Allow conditional parsing of the ~/.inputrc file. */\n    rl_readline_name = \"Ruby\";\n\n    using_history();\n\n    completion_proc = rb_intern(COMPLETION_PROC);\n    completion_case_fold = rb_intern(COMPLETION_CASE_FOLD);\n\n    mReadline = rb_define_module(\"Readline\");\n    rb_define_module_function(mReadline, \"readline\",\n\t\t\t      readline_readline, -1);\n    rb_define_singleton_method(mReadline, \"completion_proc=\",\n\t\t\t       readline_s_set_completion_proc, 1);\n    rb_define_singleton_method(mReadline, \"completion_proc\",\n\t\t\t       readline_s_get_completion_proc, 0);\n    rb_define_singleton_method(mReadline, \"completion_case_fold=\",\n\t\t\t       readline_s_set_completion_case_fold, 1);\n    rb_define_singleton_method(mReadline, \"completion_case_fold\",\n\t\t\t       readline_s_get_completion_case_fold, 0);\n    rb_define_singleton_method(mReadline, \"vi_editing_mode\",\n\t\t\t       readline_s_vi_editing_mode, 0);\n    rb_define_singleton_method(mReadline, \"emacs_editing_mode\",\n\t\t\t       readline_s_emacs_editing_mode, 0);\n    rb_define_singleton_method(mReadline, \"completion_append_character=\",\n\t\t\t       readline_s_set_completion_append_character, 1);\n    rb_define_singleton_method(mReadline, \"completion_append_character\",\n\t\t\t       readline_s_get_completion_append_character, 0);\n    rb_define_singleton_method(mReadline, \"basic_word_break_characters=\",\n\t\t\t       readline_s_set_basic_word_break_characters, 1);\n    rb_define_singleton_method(mReadline, \"basic_word_break_characters\",\n\t\t\t       readline_s_get_basic_word_break_characters, 0);\n    rb_define_singleton_method(mReadline, \"completer_word_break_characters=\",\n\t\t\t       readline_s_set_completer_word_break_characters, 1);\n    rb_define_singleton_method(mReadline, \"completer_word_break_characters\",\n\t\t\t       readline_s_get_completer_word_break_characters, 0);\n    rb_define_singleton_method(mReadline, \"basic_quote_characters=\",\n\t\t\t       readline_s_set_basic_quote_characters, 1);\n    rb_define_singleton_method(mReadline, \"basic_quote_characters\",\n\t\t\t       readline_s_get_basic_quote_characters, 0);\n    rb_define_singleton_method(mReadline, \"completer_quote_characters=\",\n\t\t\t       readline_s_set_completer_quote_characters, 1);\n    rb_define_singleton_method(mReadline, \"completer_quote_characters\",\n\t\t\t       readline_s_get_completer_quote_characters, 0);\n    rb_define_singleton_method(mReadline, \"filename_quote_characters=\",\n\t\t\t       readline_s_set_filename_quote_characters, 1);\n    rb_define_singleton_method(mReadline, \"filename_quote_characters\",\n\t\t\t       readline_s_get_filename_quote_characters, 0);\n\n    history = rb_obj_alloc(rb_cObject);\n    rb_extend_object(history, rb_mEnumerable);\n    rb_define_singleton_method(history,\"to_s\", hist_to_s, 0);\n    rb_define_singleton_method(history,\"[]\", hist_get, 1);\n    rb_define_singleton_method(history,\"[]=\", hist_set, 2);\n    rb_define_singleton_method(history,\"<<\", hist_push, 1);\n    rb_define_singleton_method(history,\"push\", hist_push_method, -1);\n    rb_define_singleton_method(history,\"pop\", hist_pop, 0);\n    rb_define_singleton_method(history,\"shift\", hist_shift, 0);\n    rb_define_singleton_method(history,\"each\", hist_each, 0);\n    rb_define_singleton_method(history,\"length\", hist_length, 0);\n    rb_define_singleton_method(history,\"size\", hist_length, 0);\n    rb_define_singleton_method(history,\"empty?\", hist_empty_p, 0);\n    rb_define_singleton_method(history,\"delete_at\", hist_delete_at, 1);\n    rb_define_const(mReadline, \"HISTORY\", history);\n\n    fcomp = rb_obj_alloc(rb_cObject);\n    rb_define_singleton_method(fcomp, \"call\",\n\t\t\t       filename_completion_proc_call, 1);\n    rb_define_const(mReadline, \"FILENAME_COMPLETION_PROC\", fcomp);\n\n    ucomp = rb_obj_alloc(rb_cObject);\n    rb_define_singleton_method(ucomp, \"call\",\n\t\t\t       username_completion_proc_call, 1);\n    rb_define_const(mReadline, \"USERNAME_COMPLETION_PROC\", ucomp);\n#if defined HAVE_RL_LIBRARY_VERSION\n    rb_define_const(mReadline, \"VERSION\", rb_str_new2(rl_library_version));\n#else\n    rb_define_const(mReadline, \"VERSION\",\n                    rb_str_new2(\"2.0 or before version\"));\n#endif\n\n    rl_attempted_completion_function = readline_attempted_completion_function;\n#ifdef HAVE_RL_EVENT_HOOK\n    rl_event_hook = readline_event;\n#endif\n#ifdef HAVE_RL_CLEAR_SIGNALS\n    rl_clear_signals();\n#endif\n}\n"
  },
  {
    "path": "ext/sdbm/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/sdbm/_sdbm.c",
    "content": "/*\n * sdbm - ndbm work-alike hashed database library\n * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).\n * author: oz@nexus.yorku.ca\n * status: public domain.\n *\n * core routines\n */\n\n#ifndef lint\n/*char sdbm_rcsid[] = \"$Id$\";*/\n#endif\n\n#include \"sdbm.h\"\n#include \"config.h\"\n\n/*\n * sdbm - ndbm work-alike hashed database library\n * tuning and portability constructs [not nearly enough]\n * author: oz@nexus.yorku.ca\n */\n\n#define BYTESIZ\t\t8\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#ifdef BSD42\n#define SEEK_SET\tL_SET\n#define\tmemset(s,c,n)\tbzero(s, n)\t\t/* only when c is zero */\n#define\tmemcpy(s1,s2,n)\tbcopy(s2, s1, n)\n#define\tmemcmp(s1,s2,n)\tbcmp(s1,s2,n)\n#endif\n\n/*\n * important tuning parms (hah)\n */\n\n#define SEEDUPS\t\t/* always detect duplicates */\n#define BADMESS\t\t/* generate a message for worst case:\n\t\t\t   cannot make room after SPLTMAX splits */\n/*\n * misc\n */\n#ifdef DEBUG\n#define debug(x)\tprintf x\n#else\n#define debug(x)\n#endif\n\n#ifdef BIG_E\n#define GET_SHORT(p, i)\t(((unsigned)((unsigned char *)(p))[(i)*2] << 8) + (((unsigned char *)(p))[(i)*2 + 1]))\n#define PUT_SHORT(p, i, s) (((unsigned char *)(p))[(i)*2] = (unsigned char)((s) >> 8), ((unsigned char *)(p))[(i)*2 + 1] = (unsigned char)(s))\n#else\n#define GET_SHORT(p, i)\t((p)[i])\n#define PUT_SHORT(p, i, s)\t((p)[i] = (s))\n#endif\n\n/*#include \"pair.h\"*/\nstatic int   fitpair proto((char *, int));\nstatic void  putpair proto((char *, datum, datum));\nstatic datum getpair proto((char *, datum));\nstatic int   delpair proto((char *, datum));\nstatic int   chkpage proto((char *));\nstatic datum getnkey proto((char *, int));\nstatic void  splpage proto((char *, char *, long));\n#ifdef SEEDUPS\nstatic int   duppair proto((char *, datum));\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#ifdef DOSISH\n#include <io.h>\n#endif\n#include <sys/types.h>\n#include <sys/stat.h>\n#ifdef BSD42\n#include <sys/file.h>\n#else\n#include <fcntl.h>\n/*#include <memory.h>*/\n#endif\n#ifndef O_BINARY\n#define O_BINARY\t0\n#endif\n\n#include <errno.h>\n#ifndef EPERM\n#define EPERM\tEACCES\n#endif\n#include <string.h>\n\n#ifdef __STDC__\n#include <stddef.h>\n#endif\n\n#ifndef NULL\n#define NULL\t0\n#endif\n\n/*\n * externals\n */\n#if !defined sun && !defined MSDOS && !defined _WIN32 && !defined __CYGWIN__ && !defined(errno)\nextern int errno;\n#endif\n\n/*\n * forward\n */\nstatic int getdbit proto((DBM *, long));\nstatic int setdbit proto((DBM *, long));\nstatic int getpage proto((DBM *, long));\nstatic datum getnext proto((DBM *));\nstatic int makroom proto((DBM *, long, int));\n\n/*\n * useful macros\n */\n#define bad(x)\t\t((x).dptr == NULL || (x).dsize < 0)\n#define exhash(item)\tsdbm_hash((item).dptr, (item).dsize)\n#define ioerr(db)\t((db)->flags |= DBM_IOERR)\n\n#define OFF_PAG(off)\t(long) (off) * PBLKSIZ\n#define OFF_DIR(off)\t(long) (off) * DBLKSIZ\n\nstatic long masks[] = {\n\t000000000000L, 000000000001L, 000000000003L,\n\t000000000007L, 000000000017L, 000000000037L,\n\t000000000077L, 000000000177L, 000000000377L,\n\t000000000777L, 000000001777L, 000000003777L,\n\t000000007777L, 000000017777L, 000000037777L,\n\t000000077777L, 000000177777L, 000000377777L,\n\t000000777777L, 000001777777L, 000003777777L,\n\t000007777777L, 000017777777L, 000037777777L,\n\t000077777777L, 000177777777L, 000377777777L,\n\t000777777777L, 001777777777L, 003777777777L,\n\t007777777777L, 017777777777L\n};\n\ndatum nullitem = {NULL, 0};\n\nDBM *\nsdbm_open(file, flags, mode)\nregister char *file;\nregister int flags;\nregister int mode;\n{\n\tregister DBM *db;\n\tregister char *dirname;\n\tregister char *pagname;\n\tregister int n;\n\n\tif (file == NULL || !*file)\n\t\treturn errno = EINVAL, (DBM *) NULL;\n/*\n * need space for two seperate filenames\n */\n\tn = strlen(file) * 2 + strlen(DIRFEXT) + strlen(PAGFEXT) + 2;\n\n\tif ((dirname = malloc((unsigned) n)) == NULL)\n\t\treturn errno = ENOMEM, (DBM *) NULL;\n/*\n * build the file names\n */\n\tdirname = strcat(strcpy(dirname, file), DIRFEXT);\n\tpagname = strcpy(dirname + strlen(dirname) + 1, file);\n\tpagname = strcat(pagname, PAGFEXT);\n\n\tdb = sdbm_prep(dirname, pagname, flags, mode);\n\tfree((char *) dirname);\n\treturn db;\n}\n\nDBM *\nsdbm_prep(dirname, pagname, flags, mode)\nchar *dirname;\nchar *pagname;\nint flags;\nint mode;\n{\n\tregister DBM *db;\n\tstruct stat dstat;\n\n\tif ((db = (DBM *) malloc(sizeof(DBM))) == NULL)\n\t\treturn errno = ENOMEM, (DBM *) NULL;\n\n        db->flags = 0;\n        db->hmask = 0;\n        db->blkptr = 0;\n        db->keyptr = 0;\n/*\n * adjust user flags so that WRONLY becomes RDWR, \n * as required by this package. Also set our internal\n * flag for RDONLY.\n */\n\tif (flags & O_WRONLY)\n\t\tflags = (flags & ~O_WRONLY) | O_RDWR;\n\tif (flags & O_RDONLY)\n\t\tdb->flags = DBM_RDONLY;\n/*\n * open the files in sequence, and stat the dirfile.\n * If we fail anywhere, undo everything, return NULL.\n */\n\tflags |= O_BINARY;\n\tif ((db->pagf = open(pagname, flags, mode)) > -1) {\n\t\tif ((db->dirf = open(dirname, flags, mode)) > -1) {\n/*\n * need the dirfile size to establish max bit number.\n */\n\t\t\tif (fstat(db->dirf, &dstat) == 0) {\n/*\n * zero size: either a fresh database, or one with a single,\n * unsplit data page: dirpage is all zeros.\n */\n\t\t\t\tdb->dirbno = (!dstat.st_size) ? 0 : -1;\n\t\t\t\tdb->pagbno = -1;\n\t\t\t\tdb->maxbno = dstat.st_size * (long) BYTESIZ;\n\n\t\t\t\t(void) memset(db->pagbuf, 0, PBLKSIZ);\n\t\t\t\t(void) memset(db->dirbuf, 0, DBLKSIZ);\n\t\t\t/*\n\t\t\t * success\n\t\t\t */\n\t\t\t\treturn db;\n\t\t\t}\n\t\t\t(void) close(db->dirf);\n\t\t}\n\t\t(void) close(db->pagf);\n\t}\n\tfree((char *) db);\n\treturn (DBM *) NULL;\n}\n\nvoid\nsdbm_close(db)\nregister DBM *db;\n{\n\tif (db == NULL)\n\t\terrno = EINVAL;\n\telse {\n\t\t(void) close(db->dirf);\n\t\t(void) close(db->pagf);\n\t\tfree((char *) db);\n\t}\n}\n\ndatum\nsdbm_fetch(db, key)\nregister DBM *db;\ndatum key;\n{\n\tif (db == NULL || bad(key))\n\t\treturn errno = EINVAL, nullitem;\n\n\tif (getpage(db, exhash(key)))\n\t\treturn getpair(db->pagbuf, key);\n\n\treturn ioerr(db), nullitem;\n}\n\nint\nsdbm_delete(db, key)\nregister DBM *db;\ndatum key;\n{\n\tif (db == NULL || bad(key))\n\t\treturn errno = EINVAL, -1;\n\tif (sdbm_rdonly(db))\n\t\treturn errno = EPERM, -1;\n\n\tif (getpage(db, exhash(key))) {\n\t\tif (!delpair(db->pagbuf, key))\n\t\t\treturn -1;\n/*\n * update the page file\n */\n\t\tif (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0\n\t\t    || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)\n\t\t\treturn ioerr(db), -1;\n\n\t\treturn 0;\n\t}\n\n\treturn ioerr(db), -1;\n}\n\nint\nsdbm_store(db, key, val, flags)\nregister DBM *db;\ndatum key;\ndatum val;\nint flags;\n{\n\tint need;\n\tregister long hash;\n\n\tif (db == NULL || bad(key))\n\t\treturn errno = EINVAL, -1;\n\tif (sdbm_rdonly(db))\n\t\treturn errno = EPERM, -1;\n\n\tneed = key.dsize + val.dsize;\n/*\n * is the pair too big (or too small) for this database ??\n */\n\tif (need < 0 || need > PAIRMAX)\n\t\treturn errno = EINVAL, -1;\n\n\tif (getpage(db, (hash = exhash(key)))) {\n/*\n * if we need to replace, delete the key/data pair\n * first. If it is not there, ignore.\n */\n\t\tif (flags == DBM_REPLACE)\n\t\t\t(void) delpair(db->pagbuf, key);\n#ifdef SEEDUPS\n\t\telse if (duppair(db->pagbuf, key))\n\t\t\treturn 1;\n#endif\n/*\n * if we do not have enough room, we have to split.\n */\n\t\tif (!fitpair(db->pagbuf, need))\n\t\t\tif (!makroom(db, hash, need))\n\t\t\t\treturn ioerr(db), -1;\n/*\n * we have enough room or split is successful. insert the key,\n * and update the page file.\n */\n\t\t(void) putpair(db->pagbuf, key, val);\n\n\t\tif (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0\n\t\t    || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)\n\t\t\treturn ioerr(db), -1;\n\t/*\n\t * success\n\t */\n\t\treturn 0;\n\t}\n\n\treturn ioerr(db), -1;\n}\n\n/*\n * makroom - make room by splitting the overfull page\n * this routine will attempt to make room for SPLTMAX times before\n * giving up.\n */\nstatic int\nmakroom(db, hash, need)\nregister DBM *db;\nlong hash;\nint need;\n{\n\tlong newp;\n\tchar twin[PBLKSIZ];\n#if defined MSDOS || (defined _WIN32 && !defined __CYGWIN__)\n\tchar zer[PBLKSIZ];\n\tlong oldtail;\n#endif\n\tchar *pag = db->pagbuf;\n\tchar *new = twin;\n\tregister int smax = SPLTMAX;\n\n\tdo {\n/*\n * split the current page\n */\n\t\t(void) splpage(pag, new, db->hmask + 1);\n/*\n * address of the new page\n */\n\t\tnewp = (hash & db->hmask) | (db->hmask + 1);\n\t\tdebug((\"newp: %ld\\n\", newp));\n/*\n * write delay, read avoidence/cache shuffle:\n * select the page for incoming pair: if key is to go to the new page,\n * write out the previous one, and copy the new one over, thus making\n * it the current page. If not, simply write the new page, and we are\n * still looking at the page of interest. current page is not updated\n * here, as sdbm_store will do so, after it inserts the incoming pair.\n */\n\n#if defined MSDOS || (defined _WIN32 && !defined __CYGWIN__)\n\t/*\n\t * Fill hole with 0 if made it.\n\t * (hole is NOT read as 0)\n\t */\n\toldtail = lseek(db->pagf, 0L, SEEK_END);\n\tmemset(zer, 0, PBLKSIZ);\n\twhile (OFF_PAG(newp) > oldtail) {\n\t\tif (lseek(db->pagf, 0L, SEEK_END) < 0 ||\n\t\t    write(db->pagf, zer, PBLKSIZ) < 0) {\n\n\t\t\treturn 0;\n\t\t}\n\t\toldtail += PBLKSIZ;\n\t}\n#endif\n\n\t\tif (hash & (db->hmask + 1)) {\n\t\t\tif (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0\n\t\t\t    || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)\n\t\t\t\treturn 0;\n\t\t\tdb->pagbno = newp;\n\t\t\t(void) memcpy(pag, new, PBLKSIZ);\n\t\t}\n\t\telse if (lseek(db->pagf, OFF_PAG(newp), SEEK_SET) < 0\n\t\t\t || write(db->pagf, new, PBLKSIZ) < 0)\n\t\t\treturn 0;\n\n\t\tif (!setdbit(db, db->curbit))\n\t\t\treturn 0;\n/*\n * see if we have enough room now\n */\n\t\tif (fitpair(pag, need))\n\t\t\treturn 1;\n/*\n * try again... update curbit and hmask as getpage would have\n * done. because of our update of the current page, we do not\n * need to read in anything. BUT we have to write the current\n * [deferred] page out, as the window of failure is too great.\n */\n\t\tdb->curbit = 2 * db->curbit + \n\t\t\t((hash & (db->hmask + 1)) ? 2 : 1);\n\t\tdb->hmask |= (db->hmask + 1);\n\n\t\tif (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0\n\t\t    || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)\n\t\t\treturn 0;\n\n\t} while (--smax);\n/*\n * if we are here, this is real bad news. After SPLTMAX splits,\n * we still cannot fit the key. say goodnight.\n */\n#ifdef BADMESS\n\t(void) write(2, \"sdbm: cannot insert after SPLTMAX attempts.\\n\", 44);\n#endif\n\treturn 0;\n\n}\n\n/*\n * the following two routines will break if\n * deletions aren't taken into account. (ndbm bug)\n */\ndatum\nsdbm_firstkey(db)\nregister DBM *db;\n{\n\tif (db == NULL)\n\t\treturn errno = EINVAL, nullitem;\n/*\n * start at page 0\n */\n\t(void) memset(db->pagbuf, 0, PBLKSIZ);\n\tif (lseek(db->pagf, OFF_PAG(0), SEEK_SET) < 0\n\t    || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)\n\t\treturn ioerr(db), nullitem;\n\tdb->pagbno = 0;\n\tdb->blkptr = 0;\n\tdb->keyptr = 0;\n\n\treturn getnext(db);\n}\n\ndatum\nsdbm_nextkey(db)\nregister DBM *db;\n{\n\tif (db == NULL)\n\t\treturn errno = EINVAL, nullitem;\n\treturn getnext(db);\n}\n\n/*\n * all important binary trie traversal\n */\nstatic int\ngetpage(db, hash)\nregister DBM *db;\nregister long hash;\n{\n\tregister int hbit;\n\tregister long dbit;\n\tregister long pagb;\n\n\tdbit = 0;\n\thbit = 0;\n\twhile (dbit < db->maxbno && getdbit(db, dbit))\n\t\tdbit = 2 * dbit + ((hash & ((long) 1 << hbit++)) ? 2 : 1);\n\n\tdebug((\"dbit: %d...\", dbit));\n\n\tdb->curbit = dbit;\n\tdb->hmask = masks[hbit];\n\n\tpagb = hash & db->hmask;\n/*\n * see if the block we need is already in memory.\n * note: this lookaside cache has about 10% hit rate.\n */\n\tif (pagb != db->pagbno) { \n/*\n * note: here, we assume a \"hole\" is read as 0s.\n * if not, must zero pagbuf first.\n */\n\t\t(void) memset(db->pagbuf, 0, PBLKSIZ);\n\n\t\tif (lseek(db->pagf, OFF_PAG(pagb), SEEK_SET) < 0\n\t\t    || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)\n\t\t\treturn 0;\n\t\tif (!chkpage(db->pagbuf)) {\n\t\t\treturn 0;\n\t\t}\n\t\tdb->pagbno = pagb;\n\n\t\tdebug((\"pag read: %d\\n\", pagb));\n\t}\n\treturn 1;\n}\n\nstatic int\ngetdbit(db, dbit)\nregister DBM *db;\nregister long dbit;\n{\n\tregister long c;\n\tregister long dirb;\n\n\tc = dbit / BYTESIZ;\n\tdirb = c / DBLKSIZ;\n\n\tif (dirb != db->dirbno) {\n\t\tif (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0\n\t\t    || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)\n\t\t\treturn 0;\n\t\tdb->dirbno = dirb;\n\n\t\tdebug((\"dir read: %d\\n\", dirb));\n\t}\n\n\treturn db->dirbuf[c % DBLKSIZ] & (1 << (dbit % BYTESIZ));\n}\n\nstatic int\nsetdbit(db, dbit)\nregister DBM *db;\nregister long dbit;\n{\n\tregister long c;\n\tregister long dirb;\n\n\tc = dbit / BYTESIZ;\n\tdirb = c / DBLKSIZ;\n\n\tif (dirb != db->dirbno) {\n\t\tif (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0\n\t\t    || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)\n\t\t\treturn 0;\n\t\tdb->dirbno = dirb;\n\n\t\tdebug((\"dir read: %d\\n\", dirb));\n\t}\n\n\tdb->dirbuf[c % DBLKSIZ] |= (1 << (dbit % BYTESIZ));\n\n\tif (dbit >= db->maxbno)\n\t\tdb->maxbno += (long) DBLKSIZ * BYTESIZ;\n\n\tif (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0\n\t    || write(db->dirf, db->dirbuf, DBLKSIZ) < 0)\n\t\treturn 0;\n\n\treturn 1;\n}\n\n/*\n * getnext - get the next key in the page, and if done with\n * the page, try the next page in sequence\n */\nstatic datum\ngetnext(db)\nregister DBM *db;\n{\n\tdatum key;\n\n\tfor (;;) {\n\t\tdb->keyptr++;\n\t\tkey = getnkey(db->pagbuf, db->keyptr);\n\t\tif (key.dptr != NULL)\n\t\t\treturn key;\n/*\n * we either run out, or there is nothing on this page..\n * try the next one... If we lost our position on the\n * file, we will have to seek.\n */\n\t\tdb->keyptr = 0;\n\t\tif (db->pagbno != db->blkptr++)\n\t\t\tif (lseek(db->pagf, OFF_PAG(db->blkptr), SEEK_SET) < 0)\n\t\t\t\tbreak;\n\t\tdb->pagbno = db->blkptr;\n\t\tif (read(db->pagf, db->pagbuf, PBLKSIZ) <= 0)\n\t\t\tbreak;\n\t\tif (!chkpage(db->pagbuf)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ioerr(db), nullitem;\n}\n\n/* pair.c */\n/*\n * sdbm - ndbm work-alike hashed database library\n * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).\n * author: oz@nexus.yorku.ca\n * status: public domain.\n *\n * page-level routines\n */\n\n#ifndef lint\n/*char pair_rcsid[] = \"$Id$\";*/\n#endif\n\n#ifndef BSD42\n/*#include <memory.h>*/\n#endif\n\n#define exhash(item)\tsdbm_hash((item).dptr, (item).dsize)\n\n/* \n * forward \n */\nstatic int seepair proto((char *, int, char *, int));\n\n/*\n * page format:\n *\t+------------------------------+\n * ino\t| n | keyoff | datoff | keyoff |\n * \t+------------+--------+--------+\n *\t| datoff | - - - ---->\t       |\n *\t+--------+---------------------+\n *\t|\t F R E E A R E A       |\n *\t+--------------+---------------+\n *\t|  <---- - - - | data          |\n *\t+--------+-----+----+----------+\n *\t|  key   | data     | key      |\n *\t+--------+----------+----------+\n *\n * calculating the offsets for free area:  if the number\n * of entries (ino[0]) is zero, the offset to the END of\n * the free area is the block size. Otherwise, it is the\n * nth (ino[ino[0]]) entry's offset.\n */\n\nstatic int\nfitpair(pag, need)\nchar *pag;\nint need;\n{\n\tregister int n;\n\tregister int off;\n\tregister int free;\n\tregister short *ino = (short *) pag;\n\n\toff = ((n = GET_SHORT(ino,0)) > 0) ? GET_SHORT(ino,n) : PBLKSIZ;\n\tfree = off - (n + 1) * sizeof(short);\n\tneed += 2 * sizeof(short);\n\n\tdebug((\"free %d need %d\\n\", free, need));\n\n\treturn need <= free;\n}\n\nstatic void\nputpair(pag, key, val)\nchar *pag;\ndatum key;\ndatum val;\n{\n\tregister int n;\n\tregister int off;\n\tregister short *ino = (short *) pag;\n\n\toff = ((n = GET_SHORT(ino,0)) > 0) ? GET_SHORT(ino,n) : PBLKSIZ;\n/*\n * enter the key first\n */\n\toff -= key.dsize;\n\tif (key.dsize)\n\t\t(void) memcpy(pag + off, key.dptr, key.dsize);\n\tPUT_SHORT(ino,n + 1,off);\n/*\n * now the data\n */\n\toff -= val.dsize;\n\tif (val.dsize)\n\t\t(void) memcpy(pag + off, val.dptr, val.dsize);\n\tPUT_SHORT(ino,n + 2,off);\n/*\n * adjust item count\n */\n\tPUT_SHORT(ino,0,GET_SHORT(ino,0) + 2);\n}\n\nstatic datum\ngetpair(pag, key)\nchar *pag;\ndatum key;\n{\n\tregister int i;\n\tregister int n;\n\tdatum val;\n\tregister short *ino = (short *) pag;\n\n\tif ((n = GET_SHORT(ino,0)) == 0)\n\t\treturn nullitem;\n\n\tif ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)\n\t\treturn nullitem;\n\n\tval.dptr = pag + GET_SHORT(ino,i + 1);\n\tval.dsize = GET_SHORT(ino,i) - GET_SHORT(ino,i + 1);\n\treturn val;\n}\n\n#ifdef SEEDUPS\nstatic int\nduppair(pag, key)\nchar *pag;\ndatum key;\n{\n\tregister short *ino = (short *) pag;\n\treturn GET_SHORT(ino,0) > 0 &&\n\t\t   seepair(pag, GET_SHORT(ino,0), key.dptr, key.dsize) > 0;\n}\n#endif\n\nstatic datum\ngetnkey(pag, num)\nchar *pag;\nint num;\n{\n\tdatum key;\n\tregister int off;\n\tregister short *ino = (short *) pag;\n\n\tnum = num * 2 - 1;\n\tif (GET_SHORT(ino,0) == 0 || num > GET_SHORT(ino,0))\n\t\treturn nullitem;\n\n\toff = (num > 1) ? GET_SHORT(ino,num - 1) : PBLKSIZ;\n\n\tkey.dptr = pag + GET_SHORT(ino,num);\n\tkey.dsize = off - GET_SHORT(ino,num);\n\n\treturn key;\n}\n\nstatic int\ndelpair(pag, key)\nchar *pag;\ndatum key;\n{\n\tregister int n;\n\tregister int i;\n\tregister short *ino = (short *) pag;\n\n\tif ((n = GET_SHORT(ino,0)) == 0)\n\t\treturn 0;\n\n\tif ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)\n\t\treturn 0;\n/*\n * found the key. if it is the last entry\n * [i.e. i == n - 1] we just adjust the entry count.\n * hard case: move all data down onto the deleted pair,\n * shift offsets onto deleted offsets, and adjust them.\n * [note: 0 < i < n]\n */\n\tif (i < n - 1) {\n\t\tregister int m;\n\t\tregister char *dst = pag + (i == 1 ? PBLKSIZ : GET_SHORT(ino,i - 1));\n\t\tregister char *src = pag + GET_SHORT(ino,i + 1);\n\t\tregister int   zoo = dst - src;\n\n\t\tdebug((\"free-up %d \", zoo));\n/*\n * shift data/keys down\n */\n\t\tm = GET_SHORT(ino,i + 1) - GET_SHORT(ino,n);\n#ifdef DUFF\n#define MOVB \t*--dst = *--src\n\n\t\tif (m > 0) {\n\t\t\tregister int loop = (m + 8 - 1) >> 3;\n\n\t\t\tswitch (m & (8 - 1)) {\n\t\t\tcase 0:\tdo {\n\t\t\t\tMOVB;\tcase 7:\tMOVB;\n\t\t\tcase 6:\tMOVB;\tcase 5:\tMOVB;\n\t\t\tcase 4:\tMOVB;\tcase 3:\tMOVB;\n\t\t\tcase 2:\tMOVB;\tcase 1:\tMOVB;\n\t\t\t\t} while (--loop);\n\t\t\t}\n\t\t}\n#else\n#ifdef MEMMOVE\n\t\tmemmove(dst, src, m);\n#else\n\t\twhile (m--)\n\t\t\t*--dst = *--src;\n#endif\n#endif\n/*\n * adjust offset index up\n */\n\t\twhile (i < n - 1) {\n\t\t\tPUT_SHORT(ino,i, GET_SHORT(ino,i + 2) + zoo);\n\t\t\ti++;\n\t\t}\n\t}\n\tPUT_SHORT(ino, 0, GET_SHORT(ino, 0) - 2);\n\treturn 1;\n}\n\n/*\n * search for the key in the page.\n * return offset index in the range 0 < i < n.\n * return 0 if not found.\n */\nstatic int\nseepair(pag, n, key, siz)\nchar *pag;\nregister int n;\nregister char *key;\nregister int siz;\n{\n\tregister int i;\n\tregister int off = PBLKSIZ;\n\tregister short *ino = (short *) pag;\n\n\tfor (i = 1; i < n; i += 2) {\n\t\tif (siz == off - GET_SHORT(ino,i) &&\n\t\t    memcmp(key, pag + GET_SHORT(ino,i), siz) == 0)\n\t\t\treturn i;\n\t\toff = GET_SHORT(ino,i + 1);\n\t}\n\treturn 0;\n}\n\nstatic void\nsplpage(pag, new, sbit)\nchar *pag;\nchar *new;\nlong sbit;\n{\n\tdatum key;\n\tdatum val;\n\n\tregister int n;\n\tregister int off = PBLKSIZ;\n\tchar cur[PBLKSIZ];\n\tregister short *ino = (short *) cur;\n\n\t(void) memcpy(cur, pag, PBLKSIZ);\n\t(void) memset(pag, 0, PBLKSIZ);\n\t(void) memset(new, 0, PBLKSIZ);\n\n\tn = GET_SHORT(ino,0);\n\tfor (ino++; n > 0; ino += 2) {\n\t\tkey.dptr = cur + GET_SHORT(ino,0); \n\t\tkey.dsize = off - GET_SHORT(ino,0);\n\t\tval.dptr = cur + GET_SHORT(ino,1);\n\t\tval.dsize = GET_SHORT(ino,0) - GET_SHORT(ino,1);\n/*\n * select the page pointer (by looking at sbit) and insert\n */\n\t\t(void) putpair((exhash(key) & sbit) ? new : pag, key, val);\n\n\t\toff = GET_SHORT(ino,1);\n\t\tn -= 2;\n\t}\n\n\tdebug((\"%d split %d/%d\\n\", ((short *) cur)[0] / 2, \n\t       ((short *) new)[0] / 2,\n\t       ((short *) pag)[0] / 2));\n}\n\n/*\n * check page sanity: \n * number of entries should be something\n * reasonable, and all offsets in the index should be in order.\n * this could be made more rigorous.\n */\nstatic int\nchkpage(pag)\nchar *pag;\n{\n\tregister int n;\n\tregister int off;\n\tregister short *ino = (short *) pag;\n\n\tif ((n = GET_SHORT(ino,0)) < 0 || n > PBLKSIZ / sizeof(short))\n\t\treturn 0;\n\n\tif (n > 0) {\n\t\toff = PBLKSIZ;\n\t\tfor (ino++; n > 0; ino += 2) {\n\t\t\tif (GET_SHORT(ino,0) > off || GET_SHORT(ino,1) > off ||\n\t\t\t    GET_SHORT(ino,1) > GET_SHORT(ino,0))\n\t\t\t\treturn 0;\n\t\t\toff = GET_SHORT(ino,1);\n\t\t\tn -= 2;\n\t\t}\n\t}\n\treturn 1;\n}\n\n/* hash.c */\n/*\n * sdbm - ndbm work-alike hashed database library\n * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).\n * author: oz@nexus.yorku.ca\n * status: public domain. keep it that way.\n *\n * hashing routine\n */\n\n/*\n * polynomial conversion ignoring overflows\n * [this seems to work remarkably well, in fact better\n * then the ndbm hash function. Replace at your own risk]\n * use: 65599\tnice.\n *      65587   even better. \n */\nlong\nsdbm_hash(str, len)\nregister char *str;\nregister int len;\n{\n\tregister unsigned long n = 0;\n\n#ifdef DUFF\n\n#define HASHC\tn = *str++ + 65599 * n\n\n\tif (len > 0) {\n\t\tregister int loop = (len + 8 - 1) >> 3;\n\n\t\tswitch(len & (8 - 1)) {\n\t\tcase 0:\tdo {\n\t\t\tHASHC;\tcase 7:\tHASHC;\n\t\tcase 6:\tHASHC;\tcase 5:\tHASHC;\n\t\tcase 4:\tHASHC;\tcase 3:\tHASHC;\n\t\tcase 2:\tHASHC;\tcase 1:\tHASHC;\n\t\t\t} while (--loop);\n\t\t}\n\n\t}\n#else\n\twhile (len--)\n\t\tn = ((*str++) & 255) + 65587L * n;\n#endif\n\treturn n;\n}\n"
  },
  {
    "path": "ext/sdbm/depend",
    "content": "_sdbm.o: _sdbm.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\ninit.o: init.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/sdbm/extconf.rb",
    "content": "require 'mkmf'\n\ncreate_makefile(\"sdbm\")\n"
  },
  {
    "path": "ext/sdbm/init.c",
    "content": "/************************************************\n\n  sdbminit.c -\n\n  $Author$\n  $Date$\n  created at: Fri May  7 08:34:24 JST 1999\n\n  Copyright (C) 1995-2001 Yukihiro Matsumoto\n\n************************************************/\n\n#include \"ruby.h\"\n\n#include \"sdbm.h\"\n#include <fcntl.h>\n#include <errno.h>\n\nstatic VALUE rb_cDBM, rb_eDBMError;\n\nstruct dbmdata {\n    int  di_size;\n    DBM *di_dbm;\n};\n\nstatic void\nclosed_sdbm()\n{\n    rb_raise(rb_eDBMError, \"closed SDBM file\");\n}\n\n#define GetDBM(obj, dbmp) {\\\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\\\n    if (dbmp == 0) closed_sdbm();\\\n    if (dbmp->di_dbm == 0) closed_sdbm();\\\n}\n\n#define GetDBM2(obj, data, dbm) {\\\n    GetDBM(obj, data);\\\n    (dbm) = dbmp->di_dbm;\\\n}\n\nstatic void\nfree_sdbm(dbmp)\n    struct dbmdata *dbmp;\n{\n\n    if (dbmp->di_dbm) sdbm_close(dbmp->di_dbm);\n    free(dbmp);\n}\n\nstatic VALUE\nfsdbm_close(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n\n    GetDBM(obj, dbmp);\n    sdbm_close(dbmp->di_dbm);\n    dbmp->di_dbm = 0;\n\n    return Qnil;\n}\n\nstatic VALUE\nfsdbm_closed(obj)\n    VALUE obj;\n{\n    struct dbmdata *dbmp;\n\n    Data_Get_Struct(obj, struct dbmdata, dbmp);\n    if (dbmp == 0)\n\treturn Qtrue;\n    if (dbmp->di_dbm == 0)\n\treturn Qtrue;\n\n    return Qfalse;\n}\n\nstatic VALUE fsdbm_alloc _((VALUE));\nstatic VALUE\nfsdbm_alloc(klass)\n    VALUE klass;\n{\n    return Data_Wrap_Struct(klass, 0, free_sdbm, 0);\n}\n\nstatic VALUE\nfsdbm_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE file, vmode;\n    DBM *dbm;\n    struct dbmdata *dbmp;\n    int mode;\n\n    if (rb_scan_args(argc, argv, \"11\", &file, &vmode) == 1) {\n\tmode = 0666;\t\t/* default value */\n    }\n    else if (NIL_P(vmode)) {\n\tmode = -1;\t\t/* return nil if DB not exist */\n    }\n    else {\n\tmode = NUM2INT(vmode);\n    }\n    SafeStringValue(file);\n\n    dbm = 0;\n    if (mode >= 0)\n\tdbm = sdbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode);\n    if (!dbm)\n\tdbm = sdbm_open(RSTRING(file)->ptr, O_RDWR, 0);\n    if (!dbm)\n\tdbm = sdbm_open(RSTRING(file)->ptr, O_RDONLY, 0);\n\n    if (!dbm) {\n\tif (mode == -1) return Qnil;\n\trb_sys_fail(RSTRING(file)->ptr);\n    }\n\n    dbmp = ALLOC(struct dbmdata);\n    DATA_PTR(obj) = dbmp;\n    dbmp->di_dbm = dbm;\n    dbmp->di_size = -1;\n\n    return obj;\n}\n\nstatic VALUE\nfsdbm_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj = Data_Wrap_Struct(klass, 0, free_sdbm, 0);\n\n    if (NIL_P(fsdbm_initialize(argc, argv, obj))) {\n\treturn Qnil;\n    }\n\n    if (rb_block_given_p()) {\n        return rb_ensure(rb_yield, obj, fsdbm_close, obj);\n    }\n\n    return obj;\n}\n\nstatic VALUE\nfsdbm_fetch(obj, keystr, ifnone)\n    VALUE obj, keystr, ifnone;\n{\n    datum key, value;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    value = sdbm_fetch(dbm, key);\n    if (value.dptr == 0) {\n\tif (ifnone == Qnil && rb_block_given_p())\n\t    return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));\n\treturn ifnone;\n    }\n    return rb_tainted_str_new(value.dptr, value.dsize);\n}\n\nstatic VALUE\nfsdbm_aref(obj, keystr)\n    VALUE obj, keystr;\n{\n    return fsdbm_fetch(obj, keystr, Qnil);\n}\n\nstatic VALUE\nfsdbm_fetch_m(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE keystr, valstr, ifnone;\n\n    rb_scan_args(argc, argv, \"11\", &keystr, &ifnone);\n    valstr = fsdbm_fetch(obj, keystr, ifnone);\n    if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))\n\trb_raise(rb_eIndexError, \"key not found\");\n\n    return valstr;\n}\n\nstatic VALUE\nfsdbm_index(obj, valstr)\n    VALUE obj, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(valstr);\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\tif (val.dsize == RSTRING(valstr)->len &&\n\t    memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)\n\t    return rb_tainted_str_new(key.dptr, key.dsize);\n    }\n    return Qnil;\n}\n\nstatic VALUE\nfsdbm_indexes(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new;\n    int i;\n\n    new = rb_ary_new2(argc);\n    for (i=0; i<argc; i++) {\n\trb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));\n    }\n\n    return new;\n}\n\nstatic VALUE\nfsdbm_select(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new = rb_ary_new2(argc);\n    int i;\n\n    if (rb_block_given_p()) {\n        datum key, val;\n        DBM *dbm;\n        struct dbmdata *dbmp;\n\n\tif (argc > 0) {\n\t    rb_raise(rb_eArgError, \"wrong number of arguments (%d for 0)\", argc);\n\t}\n        GetDBM2(obj, dbmp, dbm);\n        for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n            VALUE assoc, v;\n            val = sdbm_fetch(dbm, key);\n            assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),\n                                 rb_tainted_str_new(val.dptr, val.dsize));\n\t    v = rb_yield(assoc);\n\t    if (RTEST(v)) {\n\t\trb_ary_push(new, assoc);\n\t    }\n\t    GetDBM2(obj, dbmp, dbm);\n        }\n    }\n    else {\n\trb_warn(\"SDBM#select(index..) is deprecated; use SDBM#values_at\");\n\n        for (i=0; i<argc; i++) {\n            rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));\n        }\n    }\n\n    return new;\n}\n\nstatic VALUE\nfsdbm_values_at(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE new = rb_ary_new2(argc);\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));\n    }\n\n    return new;\n}\n\nstatic void\nfdbm_modify(obj)\n    VALUE obj;\n{\n    rb_secure(4);\n    if (OBJ_FROZEN(obj)) rb_error_frozen(\"SDBM\");\n}\n\nstatic VALUE\nfsdbm_delete(obj, keystr)\n    VALUE obj, keystr;\n{\n    datum key, value;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE valstr;\n\n    fdbm_modify(obj);\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n\n    value = sdbm_fetch(dbm, key);\n    if (value.dptr == 0) {\n\tif (rb_block_given_p()) return rb_yield(keystr);\n\treturn Qnil;\n    }\n\n    /* need to save value before sdbm_delete() */\n    valstr = rb_tainted_str_new(value.dptr, value.dsize);\n\n    if (sdbm_delete(dbm, key)) {\n\tdbmp->di_size = -1;\n\trb_raise(rb_eDBMError, \"dbm_delete failed\");\n    }\n    else if (dbmp->di_size >= 0) {\n\tdbmp->di_size--;\n    }\n    return valstr;\n}\n\nstatic VALUE\nfsdbm_shift(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE keystr, valstr;\n\n    fdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    key = sdbm_firstkey(dbm); \n    if (!key.dptr) return Qnil;\n    val = sdbm_fetch(dbm, key);\n    keystr = rb_tainted_str_new(key.dptr, key.dsize);\n    valstr = rb_tainted_str_new(val.dptr, val.dsize);\n    sdbm_delete(dbm, key);\n    if (dbmp->di_size >= 0) {\n\tdbmp->di_size--;\n    }\n\n    return rb_assoc_new(keystr, valstr);\n}\n\nstatic VALUE\nfsdbm_delete_if(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE keystr, valstr;\n    VALUE ret, ary = rb_ary_new();\n    int i, status = 0, n;\n\n    fdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    n = dbmp->di_size;\n    dbmp->di_size = -1;\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\tkeystr = rb_tainted_str_new(key.dptr, key.dsize);\n\tvalstr = rb_tainted_str_new(val.dptr, val.dsize);\n        ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);\n        if (status != 0) break;\n\tif (RTEST(ret)) rb_ary_push(ary, keystr);\n\tGetDBM2(obj, dbmp, dbm);\n    }\n\n    for (i = 0; i < RARRAY(ary)->len; i++) {\n\tkeystr = RARRAY(ary)->ptr[i];\n\tStringValue(keystr);\n\tkey.dptr = RSTRING(keystr)->ptr;\n\tkey.dsize = RSTRING(keystr)->len;\n\tif (sdbm_delete(dbm, key)) {\n\t    rb_raise(rb_eDBMError, \"sdbm_delete failed\");\n\t}\n    }\n    if (status) rb_jump_tag(status);\n    if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;\n\n    return obj;\n}\n\nstatic VALUE\nfsdbm_clear(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    fdbm_modify(obj);\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n    while (key = sdbm_firstkey(dbm), key.dptr) {\n\tif (sdbm_delete(dbm, key)) {\n\t    rb_raise(rb_eDBMError, \"sdbm_delete failed\");\n\t}\n    }\n    dbmp->di_size = 0;\n\n    return obj;\n}\n\nstatic VALUE\nfsdbm_invert(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE keystr, valstr;\n    VALUE hash = rb_hash_new();\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\tkeystr = rb_tainted_str_new(key.dptr, key.dsize);\n\tvalstr = rb_tainted_str_new(val.dptr, val.dsize);\n\trb_hash_aset(hash, valstr, keystr);\n    }\n    return hash;\n}\n\nstatic VALUE each_pair _((VALUE));\n\nstatic VALUE\neach_pair(obj)\n    VALUE obj;\n{\n    return rb_funcall(obj, rb_intern(\"each_pair\"), 0, 0);\n}\n\nstatic VALUE fsdbm_store _((VALUE,VALUE,VALUE));\n\nstatic VALUE\nupdate_i(pair, dbm)\n    VALUE pair, dbm;\n{\n    Check_Type(pair, T_ARRAY);\n    if (RARRAY(pair)->len < 2) {\n\trb_raise(rb_eArgError, \"pair must be [key, value]\");\n    }\n    fsdbm_store(dbm, RARRAY(pair)->ptr[0], RARRAY(pair)->ptr[1]);\n    return Qnil;\n}\n\nstatic VALUE\nfsdbm_update(obj, other)\n    VALUE obj, other;\n{\n    rb_iterate(each_pair, other, update_i, obj);\n    return obj;\n}\n\nstatic VALUE\nfsdbm_replace(obj, other)\n    VALUE obj, other;\n{\n    fsdbm_clear(obj);\n    rb_iterate(each_pair, other, update_i, obj);\n    return obj;\n}\n\nstatic VALUE\nfsdbm_store(obj, keystr, valstr)\n    VALUE obj, keystr, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    if (valstr == Qnil) {\n\tfsdbm_delete(obj, keystr);\n\treturn Qnil;\n    }\n\n    fdbm_modify(obj);\n    StringValue(keystr);\n    StringValue(valstr);\n\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    dbmp->di_size = -1;\n    if (sdbm_store(dbm, key, val, DBM_REPLACE)) {\n#ifdef HAVE_DBM_CLAERERR\n\tsdbm_clearerr(dbm);\n#endif\n\tif (errno == EPERM) rb_sys_fail(0);\n\trb_raise(rb_eDBMError, \"sdbm_store failed\");\n    }\n\n    return valstr;\n}\n\nstatic VALUE\nfsdbm_length(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    int i = 0;\n\n    GetDBM2(obj, dbmp, dbm);\n    if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);\n\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\ti++;\n    }\n    dbmp->di_size = i;\n\n    return INT2FIX(i);\n}\n\nstatic VALUE\nfsdbm_empty_p(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    int i = 0;\n\n    GetDBM(obj, dbmp);\n    if (dbmp->di_size < 0) {\n\tdbm = dbmp->di_dbm;\n\n\tfor (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\t    i++;\n\t}\n    }\n    else {\n\ti = dbmp->di_size;\n    }\n    if (i == 0) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\nfsdbm_each_value(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\trb_yield(rb_tainted_str_new(val.dptr, val.dsize));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n    return obj;\n}\n\nstatic VALUE\nfsdbm_each_key(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\trb_yield(rb_tainted_str_new(key.dptr, key.dsize));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n    return obj;\n}\n\nstatic VALUE\nfsdbm_each_pair(obj)\n    VALUE obj;\n{\n    datum key, val;\n    DBM *dbm;\n    struct dbmdata *dbmp;\n    VALUE keystr, valstr;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\tkeystr = rb_tainted_str_new(key.dptr, key.dsize);\n\tvalstr = rb_tainted_str_new(val.dptr, val.dsize);\n\trb_yield(rb_assoc_new(keystr, valstr));\n\tGetDBM2(obj, dbmp, dbm);\n    }\n\n    return obj;\n}\n\nstatic VALUE\nfsdbm_keys(obj)\n    VALUE obj;\n{\n    datum key;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\trb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nfsdbm_values(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\trb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nfsdbm_has_key(obj, keystr)\n    VALUE obj, keystr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(keystr);\n    key.dptr = RSTRING(keystr)->ptr;\n    key.dsize = RSTRING(keystr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    val = sdbm_fetch(dbm, key);\n    if (val.dptr) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\nfsdbm_has_value(obj, valstr)\n    VALUE obj, valstr;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n\n    StringValue(valstr);\n    val.dptr = RSTRING(valstr)->ptr;\n    val.dsize = RSTRING(valstr)->len;\n\n    GetDBM2(obj, dbmp, dbm);\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\tif (val.dsize == RSTRING(valstr)->len &&\n\t    memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)\n\t    return Qtrue;\n    }\n    return Qfalse;\n}\n\nstatic VALUE\nfsdbm_to_a(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE ary;\n\n    GetDBM2(obj, dbmp, dbm);\n    ary = rb_ary_new();\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\trb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),\n\t\t\t\t      rb_tainted_str_new(val.dptr, val.dsize)));\n    }\n\n    return ary;\n}\n\nstatic VALUE\nfsdbm_to_hash(obj)\n    VALUE obj;\n{\n    datum key, val;\n    struct dbmdata *dbmp;\n    DBM *dbm;\n    VALUE hash;\n\n    GetDBM2(obj, dbmp, dbm);\n    hash = rb_hash_new();\n    for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {\n\tval = sdbm_fetch(dbm, key);\n\trb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),\n\t\t           rb_tainted_str_new(val.dptr, val.dsize));\n    }\n\n    return hash;\n}\n\nstatic VALUE\nfsdbm_reject(obj)\n    VALUE obj;\n{\n    return rb_hash_delete_if(fsdbm_to_hash(obj));\n}\n\nvoid\nInit_sdbm()\n{\n    rb_cDBM = rb_define_class(\"SDBM\", rb_cObject);\n    rb_eDBMError = rb_define_class(\"SDBMError\", rb_eStandardError);\n    rb_include_module(rb_cDBM, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cDBM, fsdbm_alloc);\n    rb_define_singleton_method(rb_cDBM, \"open\", fsdbm_s_open, -1);\n\n    rb_define_method(rb_cDBM, \"initialize\", fsdbm_initialize, -1);\n    rb_define_method(rb_cDBM, \"close\", fsdbm_close, 0);\n    rb_define_method(rb_cDBM, \"closed?\", fsdbm_closed, 0);\n    rb_define_method(rb_cDBM, \"[]\", fsdbm_aref, 1);\n    rb_define_method(rb_cDBM, \"fetch\", fsdbm_fetch_m, -1);\n    rb_define_method(rb_cDBM, \"[]=\", fsdbm_store, 2);\n    rb_define_method(rb_cDBM, \"store\", fsdbm_store, 2);\n    rb_define_method(rb_cDBM, \"index\",  fsdbm_index, 1);\n    rb_define_method(rb_cDBM, \"indexes\",  fsdbm_indexes, -1);\n    rb_define_method(rb_cDBM, \"indices\",  fsdbm_indexes, -1);\n    rb_define_method(rb_cDBM, \"select\",  fsdbm_select, -1);\n    rb_define_method(rb_cDBM, \"values_at\",  fsdbm_values_at, -1);\n    rb_define_method(rb_cDBM, \"length\", fsdbm_length, 0);\n    rb_define_method(rb_cDBM, \"size\", fsdbm_length, 0);\n    rb_define_method(rb_cDBM, \"empty?\", fsdbm_empty_p, 0);\n    rb_define_method(rb_cDBM, \"each\", fsdbm_each_pair, 0);\n    rb_define_method(rb_cDBM, \"each_value\", fsdbm_each_value, 0);\n    rb_define_method(rb_cDBM, \"each_key\", fsdbm_each_key, 0);\n    rb_define_method(rb_cDBM, \"each_pair\", fsdbm_each_pair, 0);\n    rb_define_method(rb_cDBM, \"keys\", fsdbm_keys, 0);\n    rb_define_method(rb_cDBM, \"values\", fsdbm_values, 0);\n    rb_define_method(rb_cDBM, \"shift\", fsdbm_shift, 0);\n    rb_define_method(rb_cDBM, \"delete\", fsdbm_delete, 1);\n    rb_define_method(rb_cDBM, \"delete_if\", fsdbm_delete_if, 0);\n    rb_define_method(rb_cDBM, \"reject!\", fsdbm_delete_if, 0);\n    rb_define_method(rb_cDBM, \"reject\", fsdbm_reject, 0);\n    rb_define_method(rb_cDBM, \"clear\", fsdbm_clear, 0);\n    rb_define_method(rb_cDBM,\"invert\", fsdbm_invert, 0);\n    rb_define_method(rb_cDBM,\"update\", fsdbm_update, 1);\n    rb_define_method(rb_cDBM,\"replace\", fsdbm_replace, 1);\n\n    rb_define_method(rb_cDBM, \"include?\", fsdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"has_key?\", fsdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"member?\", fsdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"has_value?\", fsdbm_has_value, 1);\n    rb_define_method(rb_cDBM, \"key?\", fsdbm_has_key, 1);\n    rb_define_method(rb_cDBM, \"value?\", fsdbm_has_value, 1);\n\n    rb_define_method(rb_cDBM, \"to_a\", fsdbm_to_a, 0);\n    rb_define_method(rb_cDBM, \"to_hash\", fsdbm_to_hash, 0);\n}\n"
  },
  {
    "path": "ext/sdbm/sdbm.h",
    "content": "/*\n * sdbm - ndbm work-alike hashed database library\n * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).\n * author: oz@nexus.yorku.ca\n * status: public domain. \n */\n#ifndef\t_SDBM_H_\n#define\t_SDBM_H_\n\n#define DBLKSIZ 4096\n#define PBLKSIZ 1024\n#define PAIRMAX 1008\t\t\t/* arbitrary on PBLKSIZ-N */\n#define SPLTMAX\t10\t\t\t/* maximum allowed splits */\n\t\t\t\t\t/* for a single insertion */\n#define DIRFEXT\t\".dir\"\n#define PAGFEXT\t\".pag\"\n\ntypedef struct {\n\tint dirf;\t\t       /* directory file descriptor */\n\tint pagf;\t\t       /* page file descriptor */\n\tint flags;\t\t       /* status/error flags, see below */\n\tlong maxbno;\t\t       /* size of dirfile in bits */\n\tlong curbit;\t\t       /* current bit number */\n\tlong hmask;\t\t       /* current hash mask */\n\tlong blkptr;\t\t       /* current block for nextkey */\n\tint keyptr;\t\t       /* current key for nextkey */\n\tlong blkno;\t\t       /* current page to read/write */\n\tlong pagbno;\t\t       /* current page in pagbuf */\n\tchar pagbuf[PBLKSIZ];\t       /* page file block buffer */\n\tlong dirbno;\t\t       /* current block in dirbuf */\n\tchar dirbuf[DBLKSIZ];\t       /* directory file block buffer */\n} DBM;\n\n#define DBM_RDONLY\t0x1\t       /* data base open read-only */\n#define DBM_IOERR\t0x2\t       /* data base I/O error */\n\n/*\n * utility macros\n */\n#define sdbm_rdonly(db)\t\t((db)->flags & DBM_RDONLY)\n#define sdbm_error(db)\t\t((db)->flags & DBM_IOERR)\n\n#define sdbm_clearerr(db)\t((db)->flags &= ~DBM_IOERR)  /* ouch */\n\n#define sdbm_dirfno(db)\t((db)->dirf)\n#define sdbm_pagfno(db)\t((db)->pagf)\n\ntypedef struct {\n\tchar *dptr;\n\tint dsize;\n} datum;\n\nextern datum nullitem;\n\n#if defined(__STDC__) || defined(MSDOS)\n#define proto(p) p\n#else\n#define proto(p) ()\n#endif\n\n/*\n * flags to sdbm_store\n */\n#define DBM_INSERT\t0\n#define DBM_REPLACE\t1\n\n/*\n * ndbm interface\n */\nextern DBM *sdbm_open proto((char *, int, int));\nextern void sdbm_close proto((DBM *));\nextern datum sdbm_fetch proto((DBM *, datum));\nextern int sdbm_delete proto((DBM *, datum));\nextern int sdbm_store proto((DBM *, datum, datum, int));\nextern datum sdbm_firstkey proto((DBM *));\nextern datum sdbm_nextkey proto((DBM *));\n\n/*\n * other\n */\nextern DBM *sdbm_prep proto((char *, char *, int, int));\nextern long sdbm_hash proto((char *, int));\n\n#endif\t/* _SDBM_H_ */\n"
  },
  {
    "path": "ext/socket/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/socket/addrinfo.h",
    "content": "/*\n * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the project nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef ADDR_INFO_H\n#define ADDR_INFO_H\n#ifndef HAVE_GETADDRINFO\n\n/* special compatibility hack */\n#undef EAI_ADDRFAMILY\n#undef EAI_AGAIN\n#undef EAI_BADFLAGS\n#undef EAI_FAIL\n#undef EAI_FAMILY\n#undef EAI_MEMORY\n#undef EAI_NODATA\n#undef EAI_NONAME\n#undef EAI_SERVICE\n#undef EAI_SOCKTYPE\n#undef EAI_SYSTEM\n#undef EAI_BADHINTS\n#undef EAI_PROTOCOL\n#undef EAI_MAX\n\n#undef AI_PASSIVE\n#undef AI_CANONNAME\n#undef AI_NUMERICHOST\n#undef AI_ALL\n#undef AI_ADDRCONFIG\n#undef AI_V4MAPPED\n#undef AI_DEFAULT\n\n#undef NI_NOFQDN\n#undef NI_NUMERICHOST\n#undef NI_NAMEREQD\n#undef NI_NUMERICSERV\n#undef NI_DGRAM\n\n#undef addrinfo\n#define addrinfo addrinfo__compat\n#undef getaddrinfo\n#define getaddrinfo getaddrinfo__compat\n#undef getnameinfo\n#define getnameinfo getnameinfo__compat\n#undef freehostent\n#define freehostent freehostent__compat\n#undef freeaddrinfo\n#define freeaddrinfo freeaddrinfo__compat\n\n#ifndef __P\n# ifdef HAVE_PROTOTYPES\n#  define __P(args) args\n# else\n#  define __P(args) ()\n# endif\n#endif\n\n/* special compatibility hack -- end*/\n\n\n/*\n * Error return codes from getaddrinfo()\n */\n#define\tEAI_ADDRFAMILY\t 1\t/* address family for hostname not supported */\n#define\tEAI_AGAIN\t 2\t/* temporary failure in name resolution */\n#define\tEAI_BADFLAGS\t 3\t/* invalid value for ai_flags */\n#define\tEAI_FAIL\t 4\t/* non-recoverable failure in name resolution */\n#define\tEAI_FAMILY\t 5\t/* ai_family not supported */\n#define\tEAI_MEMORY\t 6\t/* memory allocation failure */\n#define\tEAI_NODATA\t 7\t/* no address associated with hostname */\n#define\tEAI_NONAME\t 8\t/* hostname nor servname provided, or not known */\n#define\tEAI_SERVICE\t 9\t/* servname not supported for ai_socktype */\n#define\tEAI_SOCKTYPE\t10\t/* ai_socktype not supported */\n#define\tEAI_SYSTEM\t11\t/* system error returned in errno */\n#define EAI_BADHINTS\t12\n#define EAI_PROTOCOL\t13\n#define EAI_MAX\t\t14\n\n/*\n * Flag values for getaddrinfo()\n */\n#define\tAI_PASSIVE\t0x00000001 /* get address to use bind() */\n#define\tAI_CANONNAME\t0x00000002 /* fill ai_canonname */\n#define\tAI_NUMERICHOST\t0x00000004 /* prevent name resolution */\n/* valid flags for addrinfo */\n#define\tAI_MASK\t\t(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)\n\n#define\tAI_ALL\t\t0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */\n#define\tAI_V4MAPPED_CFG\t0x00000200 /* accept IPv4-mapped if kernel supports */\n#define\tAI_ADDRCONFIG\t0x00000400 /* only if any address is assigned */\n#define\tAI_V4MAPPED\t0x00000800 /* accept IPv4-mapped IPv6 address */\n/* special recommended flags for getipnodebyname */\n#define\tAI_DEFAULT\t(AI_V4MAPPED_CFG | AI_ADDRCONFIG)\n\n/*\n * Constants for getnameinfo()\n */\n#ifndef NI_MAXHOST\n#define\tNI_MAXHOST\t1025\n#define\tNI_MAXSERV\t32\n#endif\n\n/*\n * Flag values for getnameinfo()\n */\n#define\tNI_NOFQDN\t0x00000001\n#define\tNI_NUMERICHOST\t0x00000002\n#define\tNI_NAMEREQD\t0x00000004\n#define\tNI_NUMERICSERV\t0x00000008\n#define\tNI_DGRAM\t0x00000010\n\nstruct addrinfo {\n\tint\tai_flags;\t/* AI_PASSIVE, AI_CANONNAME */\n\tint\tai_family;\t/* PF_xxx */\n\tint\tai_socktype;\t/* SOCK_xxx */\n\tint\tai_protocol;\t/* 0 or IPPROTO_xxx for IPv4 and IPv6 */\n\tsize_t\tai_addrlen;\t/* length of ai_addr */\n\tchar\t*ai_canonname;\t/* canonical name for hostname */\n\tstruct sockaddr *ai_addr;\t/* binary address */\n\tstruct addrinfo *ai_next;\t/* next structure in linked list */\n};\n\nextern int getaddrinfo __P((\n\tconst char *hostname, const char *servname,\n\tconst struct addrinfo *hints,\n\tstruct addrinfo **res));\n\nextern int getnameinfo __P((\n\tconst struct sockaddr *sa,\n\tsize_t salen,\n\tchar *host,\n\tsize_t hostlen,\n\tchar *serv,\n\tsize_t servlen,\n\tint flags));\n\nextern void freehostent __P((struct hostent *));\nextern void freeaddrinfo __P((struct addrinfo *));\n#if defined __UCLIBC__\nconst\n#endif\nextern char *gai_strerror __P((int));\n\n/* In case there is no definition of offsetof() provided - though any proper\nStandard C system should have one. */\n\n#ifndef offsetof\n#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))\n#endif\n\n#endif\n#endif\n"
  },
  {
    "path": "ext/socket/depend",
    "content": "socket.o : socket.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/rubyio.h $(hdrdir)/rubysig.h sockport.h\ngetnameinfo.o: getnameinfo.c $(topdir)/config.h addrinfo.h sockport.h\ngetaddrinfo.o: getaddrinfo.c $(topdir)/config.h addrinfo.h sockport.h\n"
  },
  {
    "path": "ext/socket/extconf.rb",
    "content": "require 'mkmf'\n\ncase RUBY_PLATFORM\nwhen /bccwin32/\n  test_func = \"WSACleanup\"\n  have_library(\"ws2_32\", \"WSACleanup\")\nwhen /mswin32|mingw/\n  test_func = \"WSACleanup\"\n  if with_config(\"winsock2\")\n    have_library(\"ws2_32\", \"WSACleanup\")\n  else\n    have_library(\"wsock32\", \"WSACleanup\")\n  end\nwhen /cygwin/\n  test_func = \"socket\"\nwhen /beos/\n  test_func = \"socket\"\n  have_library(\"net\", \"socket\")\n  have_func(\"closesocket\")\nwhen /i386-os2_emx/\n  test_func = \"socket\"\n  have_library(\"socket\", \"socket\")\nelse\n  test_func = \"socket\"\n  have_library(\"nsl\", \"t_open\")\n  have_library(\"socket\", \"socket\")\nend\n\nunless $mswin or $bccwin or $mingw\n  headers = %w<sys/types.h netdb.h string.h sys/socket.h netinet/in.h>\nend\nif /solaris/ =~ RUBY_PLATFORM and !try_compile(\"\")\n  # bug of gcc 3.0 on Solaris 8 ?\n  headers << \"sys/feature_tests.h\"\nend\nif have_header(\"arpa/inet.h\")\n  headers << \"arpa/inet.h\"\nend\n\nipv6 = false\ndefault_ipv6 = /cygwin/ !~ RUBY_PLATFORM\nif enable_config(\"ipv6\", default_ipv6)\n  if checking_for(\"ipv6\") {try_link(<<EOF)}\n#include <sys/types.h>\n#include <sys/socket.h>\nmain()\n{\n  socket(AF_INET6, SOCK_STREAM, 0);\n}\nEOF\n    $defs << \"-DENABLE_IPV6\" << \"-DINET6\"\n    ipv6 = true\n  end\nend\n\nif ipv6\n  ipv6lib = nil\n  class << (fmt = \"unknown\")\n    def %(s) s || self end\n  end\n  idirs, ldirs = dir_config(\"inet6\", %w[/usr/inet6 /usr/local/v6].find {|d| File.directory?(d)})\n  checking_for(\"ipv6 type\", fmt) do\n    if have_macro(\"IPV6_INRIA_VERSION\", \"netinet/in.h\")\n      \"inria\"\n    elsif have_macro(\"__KAME__\", \"netinet/in.h\")\n      have_library(ipv6lib = \"inet6\")\n      \"kame\"\n    elsif have_macro(\"_TOSHIBA_INET6\", \"sys/param.h\")\n      have_library(ipv6lib = \"inet6\") and \"toshiba\"\n    elsif have_macro(\"__V6D__\", \"sys/v6config.h\")\n      have_library(ipv6lib = \"v6\") and \"v6d\"\n    elsif have_macro(\"_ZETA_MINAMI_INET6\", \"sys/param.h\")\n      have_library(ipv6lib = \"inet6\") and \"zeta\"\n    elsif ipv6lib = with_config(\"ipv6-lib\")\n      warn <<EOS\n--with-ipv6-lib and --with-ipv6-libdir option will be obsolete, use\n--with-inet6lib and --with-inet6-{include,lib} options instead.\nEOS\n      find_library(ipv6lib, nil, with_config(\"ipv6-libdir\", ldirs)) and\n        ipv6lib\n    elsif have_library(\"inet6\")\n      \"inet6\"\n    end\n  end or not ipv6lib or abort <<EOS\n\nFatal: no #{ipv6lib} library found.  cannot continue.\nYou need to fetch lib#{ipv6lib}.a from appropriate\nipv6 kit and compile beforehand.\nEOS\nend\n\nif have_struct_member(\"struct sockaddr_in\", \"sin_len\", headers)\n  $defs[-1] = \"-DHAVE_SIN_LEN\"\nend\n\n#   doug's fix, NOW add -Dss_family... only if required!\n[nil, \" -Dss_family=__ss_family -Dss_len=__ss_len\"].each do |flags|\n  if flags\n    cppflags = $CPPFLAGS\n    $CPPFLAGS += flags\n  end\n  if have_struct_member(\"struct sockaddr_storage\", \"ss_family\", headers)\n    $defs[-1] = \"-DHAVE_SOCKADDR_STORAGE\"\n    break\n  elsif flags\n    $CPPFLAGS = cppflags\n  end\nend\n\nif have_struct_member(\"struct sockaddr\", \"sa_len\", headers)\n  $defs[-1] = \"-DHAVE_SA_LEN \"\nend\n\nhave_header(\"netinet/tcp.h\") if not /cygwin/ =~ RUBY_PLATFORM # for cygwin 1.1.5\nhave_header(\"netinet/udp.h\")\n\nif have_func(\"sendmsg\") | have_func(\"recvmsg\")\n  have_struct_member('struct msghdr', 'msg_control', ['sys/types.h', 'sys/socket.h'])\n  have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])\nend\n\ngetaddr_info_ok = enable_config(\"wide-getaddrinfo\") do\n  checking_for(\"wide getaddrinfo\") {try_run(<<EOF)}\n#{cpp_include(headers)}\n#include <stdlib.h>\n\n#ifndef EXIT_SUCCESS\n#define EXIT_SUCCESS 0\n#endif\n#ifndef EXIT_FAILURE\n#define EXIT_FAILURE 1\n#endif\n\n#ifndef AF_LOCAL\n#define AF_LOCAL AF_UNIX\n#endif\n\nmain()\n{\n  int passive, gaierr, inet4 = 0, inet6 = 0;\n  struct addrinfo hints, *ai, *aitop;\n  char straddr[INET6_ADDRSTRLEN], strport[16];\n\n  for (passive = 0; passive <= 1; passive++) {\n    memset(&hints, 0, sizeof(hints));\n    hints.ai_family = AF_UNSPEC;\n    hints.ai_protocol = IPPROTO_TCP;\n    hints.ai_flags = passive ? AI_PASSIVE : 0;\n    hints.ai_socktype = SOCK_STREAM;\n    if ((gaierr = getaddrinfo(NULL, \"54321\", &hints, &aitop)) != 0) {\n      (void)gai_strerror(gaierr);\n      goto bad;\n    }\n    for (ai = aitop; ai; ai = ai->ai_next) {\n      if (ai->ai_family == AF_LOCAL) continue;\n      if (ai->ai_addr == NULL)\n        goto bad;\n#if defined(_AIX)\n      if (ai->ai_family == AF_INET6 && passive) {\n        inet6++;\n        continue;\n      }\n      ai->ai_addr->sa_len = ai->ai_addrlen;\n      ai->ai_addr->sa_family = ai->ai_family;\n#endif\n      if (ai->ai_addrlen == 0 ||\n          getnameinfo(ai->ai_addr, ai->ai_addrlen,\n                      straddr, sizeof(straddr), strport, sizeof(strport),\n                      NI_NUMERICHOST|NI_NUMERICSERV) != 0) {\n        goto bad;\n      }\n      if (strcmp(strport, \"54321\") != 0) {\n        goto bad;\n      }\n      switch (ai->ai_family) {\n      case AF_INET:\n        if (passive) {\n          if (strcmp(straddr, \"0.0.0.0\") != 0) {\n            goto bad;\n          }\n        } else {\n          if (strcmp(straddr, \"127.0.0.1\") != 0) {\n            goto bad;\n          }\n        }\n        inet4++;\n        break;\n      case AF_INET6:\n        if (passive) {\n          if (strcmp(straddr, \"::\") != 0) {\n            goto bad;\n          }\n        } else {\n          if (strcmp(straddr, \"::1\") != 0) {\n            goto bad;\n          }\n        }\n        inet6++;\n        break;\n      case AF_UNSPEC:\n        goto bad;\n        break;\n      default:\n        /* another family support? */\n        break;\n      }\n    }\n  }\n\n  if (!(inet4 == 0 || inet4 == 2))\n    goto bad;\n  if (!(inet6 == 0 || inet6 == 2))\n    goto bad;\n\n  if (aitop)\n    freeaddrinfo(aitop);\n  exit(EXIT_SUCCESS);\n\n bad:\n  if (aitop)\n    freeaddrinfo(aitop);\n  exit(EXIT_FAILURE);\n}\nEOF\nend\nif ipv6 and not getaddr_info_ok\n  abort <<EOS\n\nFatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature.\nBut your getaddrinfo() and getnameinfo() are appeared to be broken.  Sorry,\nyou cannot compile IPv6 socket classes with broken these functions.\nYou can try --enable-wide-getaddrinfo.\nEOS\nend\n\ncase with_config(\"lookup-order-hack\", \"UNSPEC\")\nwhen \"INET\"\n  $defs << \"-DLOOKUP_ORDER_HACK_INET\"\nwhen \"INET6\"\n  $defs << \"-DLOOKUP_ORDER_HACK_INET6\"\nwhen \"UNSPEC\"\n  # nothing special\nelse\n  abort <<EOS\n\nFatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC)\nEOS\nend\n\n$objs = [\"socket.#{$OBJEXT}\"]\n\nunless getaddr_info_ok and have_func(\"getnameinfo\", \"netdb.h\") and have_func(\"getaddrinfo\", \"netdb.h\")\n  if have_struct_member(\"struct in6_addr\", \"s6_addr8\", headers)\n    $defs[-1] = \"-DHAVE_ADDR8\"\n  end\n  $CPPFLAGS=\"-I. \"+$CPPFLAGS\n  $objs += [\"getaddrinfo.#{$OBJEXT}\"]\n  $objs += [\"getnameinfo.#{$OBJEXT}\"]\n  have_func(\"inet_ntop\") or have_func(\"inet_ntoa\")\n  have_func(\"inet_pton\") or have_func(\"inet_aton\")\n  have_func(\"getservbyport\")\n  if have_func(\"gai_strerror\")\n    unless checking_for(\"gai_strerror() returns const pointer\") {!try_compile(<<EOF)}\n#{cpp_include(headers)}\n#include <stdlib.h>\nvoid\nconftest_gai_strerror_is_const()\n{\n    *gai_strerror(0) = 0;\n}\nEOF\n      $defs << \"-DGAI_STRERROR_CONST\"\n    end\n  end\n  have_header(\"arpa/nameser.h\")\n  have_header(\"resolv.h\")\nend\n\nunless have_type(\"socklen_t\", headers)\n  $defs << \"-Dsocklen_t=int\"\nend\n\nhave_header(\"sys/un.h\")\nhave_header(\"sys/uio.h\")\n\nif have_func(test_func)\n  have_func(\"hsterror\")\n  have_func(\"getipnodebyname\") or have_func(\"gethostbyname2\")\n  have_func(\"socketpair\")\n  unless have_func(\"gethostname\")\n    have_func(\"uname\")\n  end\n  if enable_config(\"socks\", ENV[\"SOCKS_SERVER\"])\n    if have_library(\"socks5\", \"SOCKSinit\")\n      $defs << \"-DSOCKS5\" << \"-DSOCKS\"\n    elsif have_library(\"socks\", \"Rconnect\")\n      $defs << \"-DSOCKS\"\n    end\n  end\n  create_makefile(\"socket\")\nend\n"
  },
  {
    "path": "ext/socket/getaddrinfo.c",
    "content": "/*\n * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the project nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * \"#ifdef FAITH\" part is local hack for supporting IPv4-v6 translator.\n *\n * Issues to be discussed:\n * - Thread safe-ness must be checked.\n * - Return values.  There are nonstandard return values defined and used\n *   in the source code.  This is because RFC2133 is silent about which error\n *   code must be returned for which situation.\n * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag.\n */\n\n#include \"config.h\"\n#ifdef RUBY_EXTCONF_H\n#include RUBY_EXTCONF_H\n#endif\n#include <sys/types.h>\n#if !defined(_WIN32) && !defined(__VMS)\n#include <sys/param.h>\n#if defined(__BEOS__)\n# include <net/socket.h>\n#else\n# include <sys/socket.h>\n#endif\n#include <netinet/in.h>\n#if defined(HAVE_ARPA_INET_H)\n#include <arpa/inet.h>\n#endif\n#if defined(HAVE_ARPA_NAMESER_H)\n#include <arpa/nameser.h>\n#endif\n#include <netdb.h>\n#if defined(HAVE_RESOLV_H)\n#ifdef _SX\n#include <stdio.h>\n#endif\n#include <resolv.h>\n#endif\n#include <unistd.h>\n#elif defined(__VMS )\n#include <socket.h>\n#include <inet.h>\n#include <in.h>\n#include <netdb.h>\n#else\n#include <winsock2.h>\n#include <io.h>\n#endif\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stddef.h>\n#include <ctype.h>\n\n#ifdef SOCKS5\n#include <socks.h>\n#endif\n\n#include \"addrinfo.h\"\n#include \"sockport.h\"\n\n#if defined(__KAME__) && defined(INET6)\n# define FAITH\n#endif\n\n#define SUCCESS 0\n#define ANY 0\n#define YES 1\n#define NO  0\n\n#ifdef FAITH\nstatic int translate = NO;\nstatic struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;\n#endif\n\nstatic const char in_addrany[] = { 0, 0, 0, 0 };\nstatic const char in6_addrany[] = {\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n};\nstatic const char in_loopback[] = { 127, 0, 0, 1 }; \nstatic const char in6_loopback[] = {\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1\n};\n\nstruct sockinet {\n\tu_char\tsi_len;\n\tu_char\tsi_family;\n\tu_short\tsi_port;\n};\n\nstatic const struct afd {\n\tint a_af;\n\tint a_addrlen;\n\tint a_socklen;\n\tint a_off;\n\tconst char *a_addrany;\n\tconst char *a_loopback;\t\n} afdl [] = {\n#ifdef INET6\n#define N_INET6 0\n\t{PF_INET6, sizeof(struct in6_addr),\n\t sizeof(struct sockaddr_in6),\n\t offsetof(struct sockaddr_in6, sin6_addr),\n\t in6_addrany, in6_loopback},\n#define N_INET  1\n#else\n#define N_INET  0\n#endif\n\t{PF_INET, sizeof(struct in_addr),\n\t sizeof(struct sockaddr_in),\n\t offsetof(struct sockaddr_in, sin_addr),\n\t in_addrany, in_loopback},\n\t{0, 0, 0, 0, NULL, NULL},\n};\n\n#ifdef INET6\n#define PTON_MAX\t16\n#else\n#define PTON_MAX\t4\n#endif\n\nstatic int get_name __P((const char *, const struct afd *,\n\t\t\t  struct addrinfo **, char *, struct addrinfo *,\n\t\t\t  int));\nstatic int get_addr __P((const char *, int, struct addrinfo **,\n\t\t\tstruct addrinfo *, int));\nstatic int str_isnumber __P((const char *));\n\t\nstatic const char *const ai_errlist[] = {\n\t\"success.\",\n\t\"address family for hostname not supported.\",\t/* EAI_ADDRFAMILY */\n\t\"temporary failure in name resolution.\",\t/* EAI_AGAIN      */\n\t\"invalid value for ai_flags.\",\t\t       \t/* EAI_BADFLAGS   */\n\t\"non-recoverable failure in name resolution.\", \t/* EAI_FAIL       */\n\t\"ai_family not supported.\",\t\t\t/* EAI_FAMILY     */\n\t\"memory allocation failure.\", \t\t\t/* EAI_MEMORY     */\n\t\"no address associated with hostname.\", \t/* EAI_NODATA     */\n\t\"hostname nor servname provided, or not known.\",/* EAI_NONAME     */\n\t\"servname not supported for ai_socktype.\",\t/* EAI_SERVICE    */\n\t\"ai_socktype not supported.\", \t\t\t/* EAI_SOCKTYPE   */\n\t\"system error returned in errno.\", \t\t/* EAI_SYSTEM     */\n\t\"invalid value for hints.\",\t\t\t/* EAI_BADHINTS\t  */\n\t\"resolved protocol is unknown.\",\t\t/* EAI_PROTOCOL   */\n\t\"unknown error.\", \t\t\t\t/* EAI_MAX        */\n};\n\n#define GET_CANONNAME(ai, str) \\\nif (pai->ai_flags & AI_CANONNAME) {\\\n\tif (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\\\n\t\tstrcpy((ai)->ai_canonname, (str));\\\n\t} else {\\\n\t\terror = EAI_MEMORY;\\\n\t\tgoto free;\\\n\t}\\\n}\n\n#define GET_AI(ai, afd, addr, port) {\\\n\tchar *p;\\\n\tif (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\\\n\t\t\t\t\t      ((afd)->a_socklen)))\\\n\t    == NULL) {\\\n\t\terror = EAI_MEMORY;\\\n\t\tgoto free;\\\n\t}\\\n\tmemcpy(ai, pai, sizeof(struct addrinfo));\\\n\t(ai)->ai_addr = (struct sockaddr *)((ai) + 1);\\\n\tmemset((ai)->ai_addr, 0, (afd)->a_socklen);\\\n\tSET_SA_LEN((ai)->ai_addr, (ai)->ai_addrlen = (afd)->a_socklen);\\\n\t(ai)->ai_addr->sa_family = (ai)->ai_family = (afd)->a_af;\\\n\t((struct sockinet *)(ai)->ai_addr)->si_port = port;\\\n\tp = (char *)((ai)->ai_addr);\\\n\tmemcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\\\n}\n\n#define ERR(err) { error = (err); goto bad; }\n\n#ifndef HAVE_GAI_STRERROR\n#ifdef GAI_STRERROR_CONST\nconst\n#endif\nchar *\ngai_strerror(ecode)\n\tint ecode;\n{\n\tif (ecode < 0 || ecode > EAI_MAX)\n\t\tecode = EAI_MAX;\n\treturn (char *)ai_errlist[ecode];\n}\n#endif\n\nvoid\nfreeaddrinfo(ai)\n\tstruct addrinfo *ai;\n{\n\tstruct addrinfo *next;\n\n\tdo {\n\t\tnext = ai->ai_next;\n\t\tif (ai->ai_canonname)\n\t\t\tfree(ai->ai_canonname);\n\t\t/* no need to free(ai->ai_addr) */\n\t\tfree(ai);\n\t} while ((ai = next) != NULL);\n}\n\nstatic int\nstr_isnumber(p)\n\tconst char *p;\n{\n\tchar *q = (char *)p;\n\twhile (*q) {\n\t\tif (! isdigit(*q))\n\t\t\treturn NO;\n\t\tq++;\n\t}\n\treturn YES;\n}\n\n#ifndef HAVE_INET_PTON\n\nstatic int\ninet_pton(af, hostname, pton)\n\tint af;\n\tconst char *hostname;\n\tvoid *pton;\n{\n\tstruct in_addr in;\n\n#ifdef HAVE_INET_ATON\n\tif (!inet_aton(hostname, &in))\n\t    return 0;\n#else\n\tint d1, d2, d3, d4;\n\tchar ch;\n\n\tif (sscanf(hostname, \"%d.%d.%d.%d%c\", &d1, &d2, &d3, &d4, &ch) == 4 &&\n\t    0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&\n\t    0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {\n\t    in.s_addr = htonl(\n\t\t((long) d1 << 24) | ((long) d2 << 16) |\n\t\t((long) d3 << 8) | ((long) d4 << 0));\n\t}\n\telse {\n\t    return 0;\n\t}\n#endif\n\tmemcpy(pton, &in, sizeof(in));\n\treturn 1;\n}\n#endif\n\nint\ngetaddrinfo(hostname, servname, hints, res)\n\tconst char *hostname, *servname;\n\tconst struct addrinfo *hints;\n\tstruct addrinfo **res;\n{\n\tstruct addrinfo sentinel;\n\tstruct addrinfo *top = NULL;\n\tstruct addrinfo *cur;\n\tint i, error = 0;\n\tchar pton[PTON_MAX];\n\tstruct addrinfo ai;\n\tstruct addrinfo *pai;\n\tu_short port;\n\n#ifdef FAITH\n\tstatic int firsttime = 1;\n\n\tif (firsttime) {\n\t\t/* translator hack */\n\t\t{\n\t\t\tchar *q = getenv(\"GAI\");\n\t\t\tif (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)\n\t\t\t\ttranslate = YES;\n\t\t}\n\t\tfirsttime = 0;\n\t}\n#endif\n\n\t/* initialize file static vars */\n\tsentinel.ai_next = NULL;\n\tcur = &sentinel;\n\tpai = &ai;\n\tpai->ai_flags = 0;\n\tpai->ai_family = PF_UNSPEC;\n\tpai->ai_socktype = ANY;\n\tpai->ai_protocol = ANY;\n\tpai->ai_addrlen = 0;\n\tpai->ai_canonname = NULL;\n\tpai->ai_addr = NULL;\n\tpai->ai_next = NULL;\n\tport = ANY;\n\t\n\tif (hostname == NULL && servname == NULL)\n\t\treturn EAI_NONAME;\n\tif (hints) {\n\t\t/* error check for hints */\n\t\tif (hints->ai_addrlen || hints->ai_canonname ||\n\t\t    hints->ai_addr || hints->ai_next)\n\t\t\tERR(EAI_BADHINTS); /* xxx */\n\t\tif (hints->ai_flags & ~AI_MASK)\n\t\t\tERR(EAI_BADFLAGS);\n\t\tswitch (hints->ai_family) {\n\t\tcase PF_UNSPEC:\n\t\tcase PF_INET:\n#ifdef INET6\n\t\tcase PF_INET6:\n#endif\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tERR(EAI_FAMILY);\n\t\t}\n\t\tmemcpy(pai, hints, sizeof(*pai));\n\t\tswitch (pai->ai_socktype) {\n\t\tcase ANY:\n\t\t\tswitch (pai->ai_protocol) {\n\t\t\tcase ANY:\n\t\t\t\tbreak;\n\t\t\tcase IPPROTO_UDP:\n\t\t\t\tpai->ai_socktype = SOCK_DGRAM;\n\t\t\t\tbreak;\n\t\t\tcase IPPROTO_TCP:\n\t\t\t\tpai->ai_socktype = SOCK_STREAM;\n\t\t\t\tbreak;\n\t\t\tdefault:\n#if defined(SOCK_RAW)\n\t\t\t\tpai->ai_socktype = SOCK_RAW;\n#endif\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n#if defined(SOCK_RAW)\n\t\tcase SOCK_RAW:\n\t\t\tbreak;\n#endif\n\t\tcase SOCK_DGRAM:\n\t\t\tif (pai->ai_protocol != IPPROTO_UDP &&\n\t\t\t    pai->ai_protocol != ANY)\n\t\t\t\tERR(EAI_BADHINTS);\t/*xxx*/\n\t\t\tpai->ai_protocol = IPPROTO_UDP;\n\t\t\tbreak;\n\t\tcase SOCK_STREAM:\n\t\t\tif (pai->ai_protocol != IPPROTO_TCP &&\n\t\t\t    pai->ai_protocol != ANY)\n\t\t\t\tERR(EAI_BADHINTS);\t/*xxx*/\n\t\t\tpai->ai_protocol = IPPROTO_TCP;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tERR(EAI_SOCKTYPE);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/*\n\t * service port\n\t */\n\tif (servname) {\n\t\tif (str_isnumber(servname)) {\n\t\t\tif (pai->ai_socktype == ANY) {\n\t\t\t\t/* caller accept *ANY* socktype */\n\t\t\t\tpai->ai_socktype = SOCK_DGRAM;\n\t\t\t\tpai->ai_protocol = IPPROTO_UDP;\n\t\t\t}\n\t\t\tport = htons((unsigned short)atoi(servname));\n\t\t} else {\n\t\t\tstruct servent *sp;\n\t\t\tconst char *proto;\n\n\t\t\tproto = NULL;\n\t\t\tswitch (pai->ai_socktype) {\n\t\t\tcase ANY:\n\t\t\t\tproto = NULL;\n\t\t\t\tbreak;\n\t\t\tcase SOCK_DGRAM:\n\t\t\t\tproto = \"udp\";\n\t\t\t\tbreak;\n\t\t\tcase SOCK_STREAM:\n\t\t\t\tproto = \"tcp\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tfprintf(stderr, \"panic!\\n\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ((sp = getservbyname((char*)servname, proto)) == NULL)\n\t\t\t\tERR(EAI_SERVICE);\n\t\t\tport = sp->s_port;\n\t\t\tif (pai->ai_socktype == ANY)\n\t\t\t\tif (strcmp(sp->s_proto, \"udp\") == 0) {\n\t\t\t\t\tpai->ai_socktype = SOCK_DGRAM;\n\t\t\t\t\tpai->ai_protocol = IPPROTO_UDP;\n\t\t\t\t} else if (strcmp(sp->s_proto, \"tcp\") == 0) {\n\t\t\t\t\tpai->ai_socktype = SOCK_STREAM;\n\t\t\t\t\tpai->ai_protocol = IPPROTO_TCP;\n\t\t\t\t} else\n\t\t\t\t\tERR(EAI_PROTOCOL);\t/*xxx*/\n\t\t}\n\t}\n\t\n\t/*\n\t * hostname == NULL.\n\t * passive socket -> anyaddr (0.0.0.0 or ::)\n\t * non-passive socket -> localhost (127.0.0.1 or ::1)\n\t */\n\tif (hostname == NULL) {\n\t\tconst struct afd *afd;\n\t\tint s;\n\n\t\tfor (afd = &afdl[0]; afd->a_af; afd++) {\n\t\t\tif (!(pai->ai_family == PF_UNSPEC\n\t\t\t   || pai->ai_family == afd->a_af)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * filter out AFs that are not supported by the kernel\n\t\t\t * XXX errno?\n\t\t\t */\n\t\t\ts = socket(afd->a_af, SOCK_DGRAM, 0);\n\t\t\tif (s < 0)\n\t\t\t\tcontinue;\n#if defined(HAVE_CLOSESOCKET)\n\t\t\tclosesocket(s);\n#else\n\t\t\tclose(s);\n#endif\n\n\t\t\tif (pai->ai_flags & AI_PASSIVE) {\n\t\t\t\tGET_AI(cur->ai_next, afd, afd->a_addrany, port);\n\t\t\t\t/* xxx meaningless?\n\t\t\t\t * GET_CANONNAME(cur->ai_next, \"anyaddr\");\n\t\t\t\t */\n\t\t\t} else {\n\t\t\t\tGET_AI(cur->ai_next, afd, afd->a_loopback,\n\t\t\t\t\tport);\n\t\t\t\t/* xxx meaningless?\n\t\t\t\t * GET_CANONNAME(cur->ai_next, \"localhost\");\n\t\t\t\t */\n\t\t\t}\n\t\t\tcur = cur->ai_next;\n\t\t}\n\t\ttop = sentinel.ai_next;\n\t\tif (top)\n\t\t\tgoto good;\n\t\telse\n\t\t\tERR(EAI_FAMILY);\n\t}\n\t\n\t/* hostname as numeric name */\n\tfor (i = 0; afdl[i].a_af; i++) {\n\t\tif (inet_pton(afdl[i].a_af, hostname, pton)) {\n\t\t\tu_long v4a;\n#ifdef INET6\n\t\t\tu_char pfx;\n#endif\n\n\t\t\tswitch (afdl[i].a_af) {\n\t\t\tcase AF_INET:\n\t\t\t\tv4a = ((struct in_addr *)pton)->s_addr;\n\t\t\t\tif (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))\n\t\t\t\t\tpai->ai_flags &= ~AI_CANONNAME;\n\t\t\t\tv4a >>= IN_CLASSA_NSHIFT;\n\t\t\t\tif (v4a == 0 || v4a == IN_LOOPBACKNET)\n\t\t\t\t\tpai->ai_flags &= ~AI_CANONNAME;\n\t\t\t\tbreak;\n#ifdef INET6\n\t\t\tcase AF_INET6:\n#ifdef HAVE_ADDR8\n\t\t\t\tpfx = ((struct in6_addr *)pton)->s6_addr8[0];\n#else\n\t\t\t\tpfx = ((struct in6_addr *)pton)->s6_addr[0];\n#endif\n\t\t\t\tif (pfx == 0 || pfx == 0xfe || pfx == 0xff)\n\t\t\t\t\tpai->ai_flags &= ~AI_CANONNAME;\n\t\t\t\tbreak;\n#endif\n\t\t\t}\n\t\t\t\n\t\t\tif (pai->ai_family == afdl[i].a_af ||\n\t\t\t    pai->ai_family == PF_UNSPEC) {\n\t\t\t\tif (! (pai->ai_flags & AI_CANONNAME)) {\n\t\t\t\t\tGET_AI(top, &afdl[i], pton, port);\n\t\t\t\t\tgoto good;\n\t\t\t\t}\n\t\t\t\t/*\n\t\t\t\t * if AI_CANONNAME and if reverse lookup\n\t\t\t\t * fail, return ai anyway to pacify\n\t\t\t\t * calling application.\n\t\t\t\t *\n\t\t\t\t * XXX getaddrinfo() is a name->address\n\t\t\t\t * translation function, and it looks strange\n\t\t\t\t * that we do addr->name translation here.\n\t\t\t\t */\n\t\t\t\tget_name(pton, &afdl[i], &top, pton, pai, port);\n\t\t\t\tgoto good;\n\t\t\t} else \n\t\t\t\tERR(EAI_FAMILY);\t/*xxx*/\n\t\t}\n\t}\n\n\tif (pai->ai_flags & AI_NUMERICHOST)\n\t\tERR(EAI_NONAME);\n\n\t/* hostname as alphabetical name */\n\terror = get_addr(hostname, pai->ai_family, &top, pai, port);\n\tif (error == 0) {\n\t\tif (top) {\n good:\n\t\t\t*res = top;\n\t\t\treturn SUCCESS;\n\t\t} else\n\t\t\terror = EAI_FAIL;\n\t}\n free:\n\tif (top)\n\t\tfreeaddrinfo(top);\n bad:\n\t*res = NULL;\n\treturn error;\n}\n\nstatic int\nget_name(addr, afd, res, numaddr, pai, port0)\n\tconst char *addr;\n\tconst struct afd *afd;\n\tstruct addrinfo **res;\n\tchar *numaddr;\n\tstruct addrinfo *pai;\n\tint port0;\n{\n\tu_short port = port0 & 0xffff;\n\tstruct hostent *hp;\n\tstruct addrinfo *cur;\n\tint error = 0;\n#ifdef INET6\n\tint h_error;\n#endif\n\n#ifdef INET6\n\thp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);\n#else\n\thp = gethostbyaddr((char*)addr, afd->a_addrlen, AF_INET);\n#endif\n\tif (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {\n\t\tGET_AI(cur, afd, hp->h_addr_list[0], port);\n\t\tGET_CANONNAME(cur, hp->h_name);\n\t} else\n\t\tGET_AI(cur, afd, numaddr, port);\n\t\n#ifdef INET6\n\tif (hp)\n\t\tfreehostent(hp);\n#endif\n\t*res = cur;\n\treturn SUCCESS;\n free:\n\tif (cur)\n\t\tfreeaddrinfo(cur);\n#ifdef INET6\n\tif (hp)\n\t\tfreehostent(hp);\n#endif\n /* bad: */\n\t*res = NULL;\n\treturn error;\n}\n\nstatic int\nget_addr(hostname, af, res, pai, port0)\n\tconst char *hostname;\n\tint af;\n\tstruct addrinfo **res;\n\tstruct addrinfo *pai;\n\tint port0;\n{\n\tu_short port = port0 & 0xffff;\n\tstruct addrinfo sentinel;\n\tstruct hostent *hp;\n\tstruct addrinfo *top, *cur;\n\tconst struct afd *afd;\n\tint i, error = 0, h_error;\n\tchar *ap;\n\n\ttop = NULL;\n\tsentinel.ai_next = NULL;\n\tcur = &sentinel;\n#ifdef INET6\n\tif (af == AF_UNSPEC) {\n\t\thp = getipnodebyname(hostname, AF_INET6,\n\t\t\t\tAI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);\n\t} else\n\t\thp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);\n#else\n\thp = gethostbyname((char*)hostname);\n\th_error = h_errno;\n#endif\n\tif (hp == NULL) {\n\t\tswitch (h_error) {\n\t\tcase HOST_NOT_FOUND:\n\t\tcase NO_DATA:\n\t\t\terror = EAI_NODATA;\n\t\t\tbreak;\n\t\tcase TRY_AGAIN:\n\t\t\terror = EAI_AGAIN;\n\t\t\tbreak;\n\t\tcase NO_RECOVERY:\n\t\tdefault:\n\t\t\terror = EAI_FAIL;\n\t\t\tbreak;\n\t\t}\n\t\tgoto bad;\n\t}\n\n\tif ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||\n\t    (hp->h_addr_list[0] == NULL))\n\t\tERR(EAI_FAIL);\n\t\n\tfor (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {\n\t\tswitch (af) {\n#ifdef INET6\n\t\tcase AF_INET6:\n\t\t\tafd = &afdl[N_INET6];\n\t\t\tbreak;\n#endif\n#ifndef INET6\n\t\tdefault:\t/* AF_UNSPEC */\n#endif\n\t\tcase AF_INET:\n\t\t\tafd = &afdl[N_INET];\n\t\t\tbreak;\n#ifdef INET6\n\t\tdefault:\t/* AF_UNSPEC */\n\t\t\tif (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {\n\t\t\t\tap += sizeof(struct in6_addr) -\n\t\t\t\t\tsizeof(struct in_addr);\n\t\t\t\tafd = &afdl[N_INET];\n\t\t\t} else\n\t\t\t\tafd = &afdl[N_INET6];\n\t\t\tbreak;\n#endif\n\t\t}\n#ifdef FAITH\n\t\tif (translate && afd->a_af == AF_INET) {\n\t\t\tstruct in6_addr *in6;\n\n\t\t\tGET_AI(cur->ai_next, &afdl[N_INET6], ap, port);\n\t\t\tin6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;\n\t\t\tmemcpy(&in6->s6_addr32[0], &faith_prefix,\n\t\t\t    sizeof(struct in6_addr) - sizeof(struct in_addr));\n\t\t\tmemcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr));\n\t\t} else\n#endif /* FAITH */\n\t\tGET_AI(cur->ai_next, afd, ap, port);\n\t\tif (cur == &sentinel) {\n\t\t\ttop = cur->ai_next;\n\t\t\tGET_CANONNAME(top, hp->h_name);\n\t\t}\n\t\tcur = cur->ai_next;\n\t}\n#ifdef INET6\n\tfreehostent(hp);\n#endif\n\t*res = top;\n\treturn SUCCESS;\n free:\n\tif (top)\n\t\tfreeaddrinfo(top);\n#ifdef INET6\n\tif (hp)\n\t\tfreehostent(hp);\n#endif\n bad:\n\t*res = NULL;\n\treturn error;\n}\n"
  },
  {
    "path": "ext/socket/getnameinfo.c",
    "content": "/*\n * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.\n * All rights reserved.\n * \n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the project nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n * \n * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * Issues to be discussed:\n * - Thread safe-ness must be checked\n * - Return values.  There seems to be no standard for return value (RFC2133)\n *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().\n */\n\n#include \"config.h\"\n#include <stdio.h>\n#include <sys/types.h>\n#ifndef _WIN32\n#if defined(__BEOS__)\n# include <net/socket.h>\n#else\n# include <sys/socket.h>\n#endif\n#include <netinet/in.h>\n#if defined(HAVE_ARPA_INET_H)\n#include <arpa/inet.h>\n#endif\n#if defined(HAVE_ARPA_NAMESER_H)\n#include <arpa/nameser.h>\n#endif\n#include <netdb.h>\n#if defined(HAVE_RESOLV_H)\n#include <resolv.h>\n#endif\n#endif\n#ifdef _WIN32\n#include <winsock2.h>\n#define snprintf _snprintf\n#endif\n\n#include <string.h>\n#include <stddef.h>\n\n#ifdef SOCKS5\n#include <socks.h>\n#endif\n\n#include \"addrinfo.h\"\n#include \"sockport.h\"\n\n#define SUCCESS 0\n#define ANY 0\n#define YES 1\n#define NO  0\n\nstruct sockinet {\n\tu_char\tsi_len;\n\tu_char\tsi_family;\n\tu_short\tsi_port;\n};\n\nstatic struct afd {\n\tint a_af;\n\tint a_addrlen;\n\tint a_socklen;\n\tint a_off;\n} afdl [] = {\n#ifdef INET6\n#define N_INET6 0\n\t{PF_INET6, sizeof(struct in6_addr),\n\t sizeof(struct sockaddr_in6),\n\t offsetof(struct sockaddr_in6, sin6_addr)},\n#define N_INET  1\n#else\n#define N_INET  0\n#endif\n\t{PF_INET, sizeof(struct in_addr),\n\t sizeof(struct sockaddr_in),\n\t offsetof(struct sockaddr_in, sin_addr)},\n\t{0, 0, 0, 0},\n};\n\n#define ENI_NOSOCKET \t0\n#define ENI_NOSERVNAME\t1\n#define ENI_NOHOSTNAME\t2\n#define ENI_MEMORY\t3\n#define ENI_SYSTEM\t4\n#define ENI_FAMILY\t5\n#define ENI_SALEN\t6\n\n#ifndef HAVE_INET_NTOP\nstatic const char *\ninet_ntop(af, addr, numaddr, numaddr_len)\n\tint af;\n\tconst void *addr;\n\tchar *numaddr;\n\tsize_t numaddr_len;\n{\n#ifdef HAVE_INET_NTOA\n\tstruct in_addr in;\n\tmemcpy(&in.s_addr, addr, sizeof(in.s_addr));\n\tsnprintf(numaddr, numaddr_len, \"%s\", inet_ntoa(in));\n#else\n\tunsigned long x = ntohl(*(unsigned long*)addr);\n\tsnprintf(numaddr, numaddr_len, \"%d.%d.%d.%d\",\n\t\t (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,\n\t\t (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);\n#endif\n\treturn numaddr;\n}\n#endif\n\nint\ngetnameinfo(sa, salen, host, hostlen, serv, servlen, flags)\n\tconst struct sockaddr *sa;\n\tsize_t salen;\n\tchar *host;\n\tsize_t hostlen;\n\tchar *serv;\n\tsize_t servlen;\n\tint flags;\n{\n\tstruct afd *afd;\n\tstruct servent *sp;\n\tstruct hostent *hp;\n\tu_short port;\n\tint family, len, i;\n\tchar *addr, *p;\n\tu_long v4a;\n#ifdef INET6\n\tu_char pfx;\n#endif\n\tint h_error;\n\tchar numserv[512];\n\tchar numaddr[512];\n\n\tif (sa == NULL)\n\t\treturn ENI_NOSOCKET;\n\n\tlen = SA_LEN(sa);\n\tif (len != salen) return ENI_SALEN;\n\t\n\tfamily = sa->sa_family;\n\tfor (i = 0; afdl[i].a_af; i++)\n\t\tif (afdl[i].a_af == family) {\n\t\t\tafd = &afdl[i];\n\t\t\tgoto found;\n\t\t}\n\treturn ENI_FAMILY;\n\t\n found:\n\tif (len != afd->a_socklen) return ENI_SALEN;\n\t\n\tport = ((struct sockinet *)sa)->si_port; /* network byte order */\n\taddr = (char *)sa + afd->a_off;\n\n\tif (serv == NULL || servlen == 0) {\n\t\t/* what we should do? */\n\t} else if (flags & NI_NUMERICSERV) {\n\t\tsnprintf(numserv, sizeof(numserv), \"%d\", ntohs(port));\n\t\tif (strlen(numserv) + 1 > servlen)\n\t\t\treturn ENI_MEMORY;\n\t\tstrcpy(serv, numserv);\n\t} else {\n#if defined(HAVE_GETSERVBYPORT)\n\t\tsp = getservbyport(port, (flags & NI_DGRAM) ? \"udp\" : \"tcp\");\n\t\tif (sp) {\n\t\t\tif (strlen(sp->s_name) + 1 > servlen)\n\t\t\t\treturn ENI_MEMORY;\n\t\t\tstrcpy(serv, sp->s_name);\n\t\t} else\n\t\t\treturn ENI_NOSERVNAME;\n#else\n\t\treturn ENI_NOSERVNAME;\n#endif\n\t}\n\n\tswitch (sa->sa_family) {\n\tcase AF_INET:\n\t\tv4a = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);\n\t\tif (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))\n\t\t\tflags |= NI_NUMERICHOST;\n\t\tv4a >>= IN_CLASSA_NSHIFT;\n\t\tif (v4a == 0)\n\t\t\tflags |= NI_NUMERICHOST;\t\t\t\n\t\tbreak;\n#ifdef INET6\n\tcase AF_INET6:\n#ifdef HAVE_ADDR8\n\t\tpfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0];\n#else\n\t\tpfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];\n#endif\n\t\tif (pfx == 0 || pfx == 0xfe || pfx == 0xff)\n\t\t\tflags |= NI_NUMERICHOST;\n\t\tbreak;\n#endif\n\t}\n\tif (host == NULL || hostlen == 0) {\n\t\t/* what should we do? */\n\t} else if (flags & NI_NUMERICHOST) {\n\t\tif (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))\n\t\t    == NULL)\n\t\t\treturn ENI_SYSTEM;\n\t\tif (strlen(numaddr) > hostlen)\n\t\t\treturn ENI_MEMORY;\n\t\tstrcpy(host, numaddr);\n\t} else {\n#ifdef INET6\n\t\thp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);\n#else\n\t\thp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);\n\t\th_error = h_errno;\n#endif\n\n\t\tif (hp) {\n\t\t\tif (flags & NI_NOFQDN) {\n\t\t\t\tp = strchr(hp->h_name, '.');\n\t\t\t\tif (p) *p = '\\0';\n\t\t\t}\n\t\t\tif (strlen(hp->h_name) + 1 > hostlen) {\n#ifdef INET6\n\t\t\t\tfreehostent(hp);\n#endif\n\t\t\t\treturn ENI_MEMORY;\n\t\t\t}\n\t\t\tstrcpy(host, hp->h_name);\n#ifdef INET6\n\t\t\tfreehostent(hp);\n#endif\n\t\t} else {\n\t\t\tif (flags & NI_NAMEREQD)\n\t\t\t\treturn ENI_NOHOSTNAME;\n\t\t\tif (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))\n\t\t\t    == NULL)\n\t\t\t\treturn ENI_NOHOSTNAME;\n\t\t\tif (strlen(numaddr) > hostlen)\n\t\t\t\treturn ENI_MEMORY;\n\t\t\tstrcpy(host, numaddr);\n\t\t}\n\t}\n\treturn SUCCESS;\n}\n"
  },
  {
    "path": "ext/socket/socket.c",
    "content": "/************************************************\n\n  socket.c -\n\n  $Author$\n  $Date$\n  created at: Thu Mar 31 12:21:29 JST 1994\n\n  Copyright (C) 1993-2001 Yukihiro Matsumoto\n\n************************************************/\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"rubysig.h\"\n#include \"util.h\"\n#include <stdio.h>\n#include <sys/types.h>\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#ifdef HAVE_SYS_UIO_H\n#include <sys/uio.h>\n#endif\n\n#ifndef _WIN32\n#if defined(__BEOS__)\n# include <net/socket.h>\n#else\n# include <sys/socket.h>\n# define pseudo_AF_FTIP pseudo_AF_RTIP\t/* workaround for NetBSD and etc. */\n#endif\n#include <netinet/in.h>\n#ifdef HAVE_NETINET_IN_SYSTM_H\n# include <netinet/in_systm.h>\n#endif\n#ifdef HAVE_NETINET_TCP_H\n# include <netinet/tcp.h>\n#endif\n#ifdef HAVE_NETINET_UDP_H\n# include <netinet/udp.h>\n#endif\n#ifdef HAVE_ARPA_INET_H\n# include <arpa/inet.h>\n#endif\n#include <netdb.h>\n#endif\n#include <errno.h>\n#ifdef HAVE_SYS_UN_H\n#include <sys/un.h>\n#endif\n\n#if defined(HAVE_FCNTL)\n#ifdef HAVE_SYS_SELECT_H\n#include <sys/select.h>\n#endif\n#ifdef HAVE_SYS_TYPES_H\n#include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_TIME_H\n#include <sys/time.h>\n#endif\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>\n#endif\n#endif\n#ifndef EWOULDBLOCK\n#define EWOULDBLOCK EAGAIN\n#endif\n#ifndef HAVE_GETADDRINFO\n# include \"addrinfo.h\"\n#endif\n#include \"sockport.h\"\n\n#if defined(__vms)\n#include <tcp.h>\n#endif\n\nstatic int do_not_reverse_lookup = 0;\n\nVALUE rb_cBasicSocket;\nVALUE rb_cIPSocket;\nVALUE rb_cTCPSocket;\nVALUE rb_cTCPServer;\nVALUE rb_cUDPSocket;\n#ifdef AF_UNIX\nVALUE rb_cUNIXSocket;\nVALUE rb_cUNIXServer;\n#endif\nVALUE rb_cSocket;\n\nstatic VALUE rb_eSocket;\n\n#ifdef SOCKS\nVALUE rb_cSOCKSSocket;\n#ifdef SOCKS5\n#include <socks.h>\n#else\nvoid SOCKSinit();\nint Rconnect();\n#endif\n#endif\n\n#define INET_CLIENT 0\n#define INET_SERVER 1\n#define INET_SOCKS  2\n\n#ifndef HAVE_SOCKADDR_STORAGE\n/*\n * RFC 2553: protocol-independent placeholder for socket addresses\n */\n#define _SS_MAXSIZE\t128\n#define _SS_ALIGNSIZE\t(sizeof(double))\n#define _SS_PAD1SIZE\t(_SS_ALIGNSIZE - sizeof(unsigned char) * 2)\n#define _SS_PAD2SIZE\t(_SS_MAXSIZE - sizeof(unsigned char) * 2 - \\\n\t\t\t\t_SS_PAD1SIZE - _SS_ALIGNSIZE)\n\nstruct sockaddr_storage {\n#ifdef HAVE_SA_LEN\n\tunsigned char ss_len;\t\t/* address length */\n\tunsigned char ss_family;\t/* address family */\n#else\n\tunsigned short ss_family;\n#endif\n\tchar\t__ss_pad1[_SS_PAD1SIZE];\n\tdouble\t__ss_align;\t/* force desired structure storage alignment */\n\tchar\t__ss_pad2[_SS_PAD2SIZE];\n};\n#endif\n\n#if defined(INET6) && (defined(LOOKUP_ORDER_HACK_INET) || defined(LOOKUP_ORDER_HACK_INET6))\n#define LOOKUP_ORDERS\t\t3\nstatic int lookup_order_table[LOOKUP_ORDERS] = {\n#if defined(LOOKUP_ORDER_HACK_INET)\n    PF_INET, PF_INET6, PF_UNSPEC,\n#elif defined(LOOKUP_ORDER_HACK_INET6)\n    PF_INET6, PF_INET, PF_UNSPEC,\n#else\n    /* should not happen */\n#endif\n};\n\nstatic int\nruby_getaddrinfo(nodename, servname, hints, res)\n     char *nodename;\n     char *servname;\n     struct addrinfo *hints;\n     struct addrinfo **res;\n{\n    struct addrinfo tmp_hints;\n    int i, af, error;\n\n    if (hints->ai_family != PF_UNSPEC) {\n\treturn getaddrinfo(nodename, servname, hints, res);\n    }\n\n    for (i = 0; i < LOOKUP_ORDERS; i++) {\n\taf = lookup_order_table[i];\n\tMEMCPY(&tmp_hints, hints, struct addrinfo, 1);\n\ttmp_hints.ai_family = af;\n\terror = getaddrinfo(nodename, servname, &tmp_hints, res);\n\tif (error) {\n\t    if (tmp_hints.ai_family == PF_UNSPEC) {\n\t\tbreak;\n\t    }\n\t}\n\telse {\n\t    break;\n\t}\n    }\n\n    return error;\n}\n#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo((node),(serv),(hints),(res))\n#endif\n\n#if defined(_AIX)\nstatic int\nruby_getaddrinfo__aix(nodename, servname, hints, res)\n     char *nodename;\n     char *servname;\n     struct addrinfo *hints;\n     struct addrinfo **res;\n{\n    int error = getaddrinfo(nodename, servname, hints, res);\n    struct addrinfo *r;\n    if (error)\n\treturn error;\n    for (r = *res; r != NULL; r = r->ai_next) {\n\tif (r->ai_addr->sa_family == 0)\n\t    r->ai_addr->sa_family = r->ai_family;\n\tif (r->ai_addr->sa_len == 0)\n\t    r->ai_addr->sa_len = r->ai_addrlen;\n    }\n    return 0;\n}\n#undef getaddrinfo\n#define getaddrinfo(node,serv,hints,res) ruby_getaddrinfo__aix((node),(serv),(hints),(res))\nstatic int\nruby_getnameinfo__aix(sa, salen, host, hostlen, serv, servlen, flags)\n     const struct sockaddr *sa;\n     size_t salen;\n     char *host;\n     size_t hostlen;\n     char *serv;\n     size_t servlen;\n     int flags;\n{\n  struct sockaddr_in6 *sa6;\n  u_int32_t *a6;\n\n  if (sa->sa_family == AF_INET6) {\n    sa6 = (struct sockaddr_in6 *)sa;\n    a6 = sa6->sin6_addr.u6_addr.u6_addr32;\n\n    if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) {\n      strncpy(host, \"::\", hostlen);\n      snprintf(serv, servlen, \"%d\", sa6->sin6_port);\n      return 0;\n    }\n  }\n  return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);\n}\n#undef getnameinfo\n#define getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \\\n            ruby_getnameinfo__aix((sa), (salen), (host), (hostlen), (serv), (servlen), (flags))\n#ifndef CMSG_SPACE\n# define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))\n#endif\n#ifndef CMSG_LEN\n# define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))\n#endif\n#endif\n\n#ifdef HAVE_CLOSESOCKET\n#undef close\n#define close closesocket\n#endif\n\nstatic VALUE\ninit_sock(sock, fd)\n    VALUE sock;\n    int fd;\n{\n    rb_io_t *fp;\n\n    MakeOpenFile(sock, fp);\n    fp->f = rb_fdopen(fd, \"r\");\n    fp->f2 = rb_fdopen(fd, \"w\");\n    fp->mode = FMODE_READWRITE;\n    rb_io_synchronized(fp);\n\n    return sock;\n}\n\nstatic VALUE\nbsock_s_for_fd(klass, fd)\n    VALUE klass, fd;\n{\n    rb_io_t *fptr;\n    VALUE sock = init_sock(rb_obj_alloc(klass), NUM2INT(fd));\n\n    GetOpenFile(sock, fptr);\n\n    return sock;\n}\n\nstatic VALUE\nbsock_shutdown(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    VALUE howto;\n    int how;\n    rb_io_t *fptr;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't shutdown socket\");\n    }\n    rb_scan_args(argc, argv, \"01\", &howto);\n    if (howto == Qnil)\n\thow = 2;\n    else {\n\thow = NUM2INT(howto);\n\tif (how < 0 || 2 < how) {\n\t    rb_raise(rb_eArgError, \"`how' should be either 0, 1, 2\");\n\t}\n    }\n    GetOpenFile(sock, fptr);\n    if (shutdown(fileno(fptr->f), how) == -1)\n\trb_sys_fail(0);\n\n    return INT2FIX(0);\n}\n\nstatic VALUE\nbsock_close_read(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close socket\");\n    }\n    GetOpenFile(sock, fptr);\n    shutdown(fileno(fptr->f), 0);\n    if (!(fptr->mode & FMODE_WRITABLE)) {\n\treturn rb_io_close(sock);\n    }\n    fptr->mode &= ~FMODE_READABLE;\n\n    return Qnil;\n}\n\nstatic VALUE\nbsock_close_write(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close socket\");\n    }\n    GetOpenFile(sock, fptr);\n    if (!(fptr->mode & FMODE_READABLE)) {\n\treturn rb_io_close(sock);\n    }\n    shutdown(fileno(fptr->f2), 1);\n    fptr->mode &= ~FMODE_WRITABLE;\n\n    return Qnil;\n}\n\n/*\n * Document-method: setsockopt\n * call-seq: setsockopt(level, optname, optval)\n *\n * Sets a socket option. These are protocol and system specific, see your\n * local sytem documentation for details.\n *\n * === Parameters\n * * +level+ is an integer, usually one of the SOL_ constants such as\n *   Socket::SOL_SOCKET, or a protocol level.\n * * +optname+ is an integer, usually one of the SO_ constants, such\n *   as Socket::SO_REUSEADDR.\n * * +optval+ is the value of the option, it is passed to the underlying\n *   setsockopt() as a pointer to a certain number of bytes. How this is\n *   done depends on the type:\n *   - Fixnum: value is assigned to an int, and a pointer to the int is\n *     passed, with length of sizeof(int).\n *   - true or false: 1 or 0 (respectively) is assigned to an int, and the\n *     int is passed as for a Fixnum. Note that +false+ must be passed,\n *     not +nil+.\n *   - String: the string's data and length is passed to the socket.\n *\n * === Examples\n *\n * Some socket options are integers with boolean values, in this case\n * #setsockopt could be called like this:\n *   sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)\n *\n * Some socket options are integers with numeric values, in this case\n * #setsockopt could be called like this:\n *   sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)\n *\n * Option values may be structs. Passing them can be complex as it involves\n * examining your system headers to determine the correct definition. An\n * example is an +ip_mreq+, which may be defined in your system headers as:\n *   struct ip_mreq {\n *     struct  in_addr imr_multiaddr;\n *     struct  in_addr imr_interface;\n *   };\n * \n * In this case #setsockopt could be called like this:\n *   optval =  IPAddr.new(\"224.0.0.251\") + Socket::INADDR_ANY\n *   sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)\n *\n*/\nstatic VALUE\nbsock_setsockopt(sock, lev, optname, val)\n    VALUE sock, lev, optname, val;\n{\n    int level, option;\n    rb_io_t *fptr;\n    int i;\n    char *v;\n    int vlen;\n\n    rb_secure(2);\n    level = NUM2INT(lev);\n    option = NUM2INT(optname);\n\n    switch (TYPE(val)) {\n      case T_FIXNUM:\n\ti = FIX2INT(val);\n\tgoto numval;\n      case T_FALSE:\n\ti = 0;\n\tgoto numval;\n      case T_TRUE:\n\ti = 1;\n      numval:\n\tv = (char*)&i; vlen = sizeof(i);\n\tbreak;\n      default:\n\tStringValue(val);\n\tv = RSTRING(val)->ptr;\n\tvlen = RSTRING(val)->len;\n\tbreak;\n    }\n\n    GetOpenFile(sock, fptr);\n    if (setsockopt(fileno(fptr->f), level, option, v, vlen) < 0)\n\trb_sys_fail(fptr->path);\n\n    return INT2FIX(0);\n}\n\n/*\n * Document-method: getsockopt\n * call-seq: getsockopt(level, optname)\n *\n * Gets a socket option. These are protocol and system specific, see your\n * local sytem documentation for details. The option is returned as\n * a String with the data being the binary value of the socket option.\n *\n * === Parameters\n * * +level+ is an integer, usually one of the SOL_ constants such as\n *   Socket::SOL_SOCKET, or a protocol level.\n * * +optname+ is an integer, usually one of the SO_ constants, such\n *   as Socket::SO_REUSEADDR.\n *\n * === Examples\n *\n * Some socket options are integers with boolean values, in this case\n * #getsockopt could be called like this:\n *   optval = sock.getsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR)\n *   optval = optval.unpack \"i\"\n *   reuseaddr = optval[0] == 0 ? false : true\n *\n * Some socket options are integers with numeric values, in this case\n * #getsockopt could be called like this:\n *   optval = sock.getsockopt(Socket::IPPROTO_IP, Socket::IP_TTL)\n *   ipttl = optval.unpack(\"i\")[0]\n *\n * Option values may be structs. Decoding them can be complex as it involves\n * examining your system headers to determine the correct definition. An\n * example is a +struct linger+, which may be defined in your system headers\n * as:\n *   struct linger {\n *     int l_onoff;\n *     int l_linger;\n *   };\n * \n * In this case #getsockopt could be called like this:\n *   optval =  sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER)\n *   onoff, linger = optval.unpack \"ii\"\n*/\nstatic VALUE\nbsock_getsockopt(sock, lev, optname)\n    VALUE sock, lev, optname;\n{\n#if !defined(__BEOS__)\n    int level, option;\n    socklen_t len;\n    char *buf;\n    rb_io_t *fptr;\n\n    level = NUM2INT(lev);\n    option = NUM2INT(optname);\n    len = 256;\n    buf = ALLOCA_N(char,len);\n    GetOpenFile(sock, fptr);\n\n    GetOpenFile(sock, fptr);\n    if (getsockopt(fileno(fptr->f), level, option, buf, &len) < 0)\n\trb_sys_fail(fptr->path);\n\n    return rb_str_new(buf, len);\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic VALUE\nbsock_getsockname(sock)\n    VALUE sock;\n{\n    char buf[1024];\n    socklen_t len = sizeof buf;\n    rb_io_t *fptr;\n\n    GetOpenFile(sock, fptr);\n    if (getsockname(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0)\n\trb_sys_fail(\"getsockname(2)\");\n    return rb_str_new(buf, len);\n}\n\nstatic VALUE\nbsock_getpeername(sock)\n    VALUE sock;\n{\n    char buf[1024];\n    socklen_t len = sizeof buf;\n    rb_io_t *fptr;\n\n    GetOpenFile(sock, fptr);\n    if (getpeername(fileno(fptr->f), (struct sockaddr*)buf, &len) < 0)\n\trb_sys_fail(\"getpeername(2)\");\n    return rb_str_new(buf, len);\n}\n\nstatic VALUE\nbsock_send(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    VALUE mesg, to;\n    VALUE flags;\n    rb_io_t *fptr;\n    FILE *f;\n    int fd, n;\n\n    rb_secure(4);\n    rb_scan_args(argc, argv, \"21\", &mesg, &flags, &to);\n\n    StringValue(mesg);\n    if (!NIL_P(to)) StringValue(to);\n    GetOpenFile(sock, fptr);\n    f = GetWriteFile(fptr);\n    fd = fileno(f);\n    rb_thread_fd_writable(fd);\n  retry:\n    if (!NIL_P(to)) {\n        TRAP_BEG;\n\tn = sendto(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags),\n\t\t   (struct sockaddr*)RSTRING(to)->ptr, RSTRING(to)->len);\n        TRAP_END;\n    }\n    else {\n        TRAP_BEG;\n\tn = send(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags));\n        TRAP_END;\n    }\n    if (n < 0) {\n\tif (rb_io_wait_writable(fd)) {\n\t    goto retry;\n\t}\n\trb_sys_fail(\"send(2)\");\n    }\n    return INT2FIX(n);\n}\n\nstatic VALUE ipaddr _((struct sockaddr*));\n#ifdef HAVE_SYS_UN_H\nstatic VALUE unixaddr _((struct sockaddr_un*, socklen_t));\n#endif\n\nenum sock_recv_type {\n    RECV_RECV,\t\t\t/* BasicSocket#recv(no from) */\n    RECV_IP,\t\t\t/* IPSocket#recvfrom */\n    RECV_UNIX,\t\t\t/* UNIXSocket#recvfrom */\n    RECV_SOCKET\t\t\t/* Socket#recvfrom */\n};\n\nstatic VALUE\ns_recvfrom(sock, argc, argv, from)\n    VALUE sock;\n    int argc;\n    VALUE *argv;\n    enum sock_recv_type from;\n{\n    rb_io_t *fptr;\n    VALUE str;\n    char buf[1024];\n    socklen_t alen = sizeof buf;\n    VALUE len, flg;\n    long buflen;\n    long slen;\n    int fd, flags;\n\n    rb_scan_args(argc, argv, \"11\", &len, &flg);\n\n    if (flg == Qnil) flags = 0;\n    else             flags = NUM2INT(flg);\n    buflen = NUM2INT(len);\n\n    GetOpenFile(sock, fptr);\n    if (rb_read_pending(fptr->f)) {\n\trb_raise(rb_eIOError, \"recv for buffered IO\");\n    }\n    fd = fileno(fptr->f);\n\n    str = rb_tainted_str_new(0, buflen);\n\n  retry:\n    rb_str_locktmp(str);\n    rb_thread_wait_fd(fd);\n    TRAP_BEG;\n    slen = recvfrom(fd, RSTRING(str)->ptr, buflen, flags, (struct sockaddr*)buf, &alen);\n    TRAP_END;\n    rb_str_unlocktmp(str);\n\n    if (slen < 0) {\n\tif (rb_io_wait_readable(fd)) {\n\t    goto retry;\n\t}\n\trb_sys_fail(\"recvfrom(2)\");\n    }\n    if (slen < RSTRING(str)->len) {\n\tRSTRING(str)->len = slen;\n\tRSTRING(str)->ptr[slen] = '\\0';\n    }\n    rb_obj_taint(str);\n    switch (from) {\n      case RECV_RECV:\n\treturn (VALUE)str;\n      case RECV_IP:\n#if 0\n\tif (alen != sizeof(struct sockaddr_in)) {\n\t    rb_raise(rb_eTypeError, \"sockaddr size differs - should not happen\");\n\t}\n#endif\n\tif (alen && alen != sizeof(buf)) /* OSX doesn't return a 'from' result from recvfrom for connection-oriented sockets */\n\t    return rb_assoc_new(str, ipaddr((struct sockaddr*)buf));\n\telse\n\t    return rb_assoc_new(str, Qnil);\n\n#ifdef HAVE_SYS_UN_H\n      case RECV_UNIX:\n        return rb_assoc_new(str, unixaddr((struct sockaddr_un*)buf, alen));\n#endif\n      case RECV_SOCKET:\n\treturn rb_assoc_new(str, rb_str_new(buf, alen));\n      default:\n\trb_bug(\"s_recvfrom called with bad value\");\n    }\n}\n\nstatic VALUE\ns_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)\n{\n    rb_io_t *fptr;\n    VALUE str;\n    char buf[1024];\n    socklen_t alen = sizeof buf;\n    VALUE len, flg;\n    long buflen;\n    long slen;\n    int fd, flags;\n    VALUE addr = Qnil;\n\n    rb_scan_args(argc, argv, \"11\", &len, &flg);\n\n    if (flg == Qnil) flags = 0;\n    else             flags = NUM2INT(flg);\n    buflen = NUM2INT(len);\n\n#ifdef MSG_DONTWAIT\n    /* MSG_DONTWAIT avoids the race condition between fcntl and recvfrom.\n       It is not portable, though. */\n    flags |= MSG_DONTWAIT;\n#endif\n\n    GetOpenFile(sock, fptr);\n    if (rb_read_pending(fptr->f)) {\n\trb_raise(rb_eIOError, \"recvfrom for buffered IO\");\n    }\n    fd = fileno(fptr->f);\n\n    str = rb_tainted_str_new(0, buflen);\n\n    rb_io_check_closed(fptr);\n    rb_io_set_nonblock(fptr);\n    slen = recvfrom(fd, RSTRING(str)->ptr, buflen, flags, (struct sockaddr*)buf, &alen);\n\n    if (slen < 0) {\n\trb_sys_fail(\"recvfrom(2)\");\n    }\n    if (slen < RSTRING(str)->len) {\n\tRSTRING(str)->len = slen;\n\tRSTRING(str)->ptr[slen] = '\\0';\n    }\n    rb_obj_taint(str);\n    switch (from) {\n      case RECV_RECV:\n\treturn str;\n\n      case RECV_IP:\n        if (alen && alen != sizeof(buf)) /* connection-oriented socket may not return a from result */\n            addr = ipaddr((struct sockaddr*)buf);\n        break;\n\n      case RECV_SOCKET:\n        addr = rb_str_new(buf, alen);\n        break;\n\n      default:\n        rb_bug(\"s_recvfrom_nonblock called with bad value\");\n    }\n    return rb_assoc_new(str, addr);\n}\n\nstatic VALUE\nbsock_recv(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    return s_recvfrom(sock, argc, argv, RECV_RECV);\n}\n\n/*\n * call-seq:\n * \tbasicsocket.recv_nonblock(maxlen) => mesg\n * \tbasicsocket.recv_nonblock(maxlen, flags) => mesg\n * \n * Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after\n * O_NONBLOCK is set for the underlying file descriptor.\n * _flags_ is zero or more of the +MSG_+ options.\n * The result, _mesg_, is the data received.\n *\n * When recvfrom(2) returns 0, Socket#recv_nonblock returns\n * an empty string as data.\n * The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.\n * \n * === Parameters\n * * +maxlen+ - the number of bytes to receive from the socket\n * * +flags+ - zero or more of the +MSG_+ options \n * \n * === Example\n * \tserv = TCPServer.new(\"127.0.0.1\", 0)\n * \taf, port, host, addr = serv.addr\n * \tc = TCPSocket.new(addr, port)\n * \ts = serv.accept\n * \tc.send \"aaa\", 0\n * \tIO.select([s])\n * \tp s.recv_nonblock(10) #=> \"aaa\"\n *\n * Refer to Socket#recvfrom for the exceptions that may be thrown if the call\n * to _recv_nonblock_ fails. \n *\n * BasicSocket#recv_nonblock may raise any error corresponding to recvfrom(2) failure,\n * including Errno::EAGAIN.\n *\n * === See\n * * Socket#recvfrom\n */\n\nstatic VALUE\nbsock_recv_nonblock(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    return s_recvfrom_nonblock(sock, argc, argv, RECV_RECV);\n}\n\nstatic VALUE\nbsock_do_not_rev_lookup()\n{\n    return do_not_reverse_lookup?Qtrue:Qfalse;\n}\n\nstatic VALUE\nbsock_do_not_rev_lookup_set(self, val)\n    VALUE self, val;\n{\n    rb_secure(4);\n    do_not_reverse_lookup = RTEST(val);\n    return val;\n}\n\nstatic void\nmake_ipaddr0(addr, buf, len)\n    struct sockaddr *addr;\n    char *buf;\n    size_t len;\n{\n    int error;\n\n    error = getnameinfo(addr, SA_LEN(addr), buf, len, NULL, 0, NI_NUMERICHOST);\n    if (error) {\n\trb_raise(rb_eSocket, \"getnameinfo: %s\", gai_strerror(error));\n    }\n}\n\nstatic VALUE\nmake_ipaddr(addr)\n    struct sockaddr *addr;\n{\n    char buf[1024];\n\n    make_ipaddr0(addr, buf, sizeof(buf));\n    return rb_str_new2(buf);\n}\n\nstatic void\nmake_inetaddr(host, buf, len)\n    long host;\n    char *buf;\n    size_t len;\n{\n    struct sockaddr_in sin;\n\n    MEMZERO(&sin, struct sockaddr_in, 1);\n    sin.sin_family = AF_INET;\n    SET_SIN_LEN(&sin, sizeof(sin));\n    sin.sin_addr.s_addr = host;\n    make_ipaddr0((struct sockaddr*)&sin, buf, len);\n}\n\nstatic int\nstr_isnumber(p)\n        const char *p;\n{\n    char *ep;\n\n    if (!p || *p == '\\0')\n       return 0;\n    ep = NULL;\n    (void)strtoul(p, &ep, 10);\n    if (ep && *ep == '\\0')\n       return 1;\n    else\n       return 0;\n}\n\nstatic char *\nhost_str(host, hbuf, len)\n    VALUE host;\n    char *hbuf;\n    size_t len;\n{\n    if (NIL_P(host)) {\n\treturn NULL;\n    }\n    else if (rb_obj_is_kind_of(host, rb_cInteger)) {\n\tunsigned long i = NUM2ULONG(host);\n\n\tmake_inetaddr(htonl(i), hbuf, len);\n\treturn hbuf;\n    }\n    else {\n\tchar *name;\n\n\tSafeStringValue(host);\n\tname = RSTRING(host)->ptr;\n\tif (!name || *name == 0 || (name[0] == '<' && strcmp(name, \"<any>\") == 0)) {\n\t    make_inetaddr(INADDR_ANY, hbuf, len);\n\t}\n\telse if (name[0] == '<' && strcmp(name, \"<broadcast>\") == 0) {\n\t    make_inetaddr(INADDR_BROADCAST, hbuf, len);\n\t}\n\telse if (strlen(name) >= len) {\n\t    rb_raise(rb_eArgError, \"hostname too long (%d)\", strlen(name));\n\t}\n\telse {\n\t    strcpy(hbuf, name);\n\t}\n\treturn hbuf;\n    }\n}\n\nstatic char *\nport_str(port, pbuf, len)\n    VALUE port;\n    char *pbuf;\n    size_t len;\n{\n    if (NIL_P(port)) {\n\treturn 0;\n    }\n    else if (FIXNUM_P(port)) {\n\tsnprintf(pbuf, len, \"%ld\", FIX2LONG(port));\n\treturn pbuf;\n    }\n    else {\n\tchar *serv;\n\n\tSafeStringValue(port);\n\tserv = RSTRING(port)->ptr;\n\tif (strlen(serv) >= len) {\n\t    rb_raise(rb_eArgError, \"service name too long (%d)\", strlen(serv));\n\t}\n\tstrcpy(pbuf, serv);\n\treturn pbuf;\n    }\n}\n\n#ifndef NI_MAXHOST\n# define NI_MAXHOST 1025\n#endif\n#ifndef NI_MAXSERV\n# define NI_MAXSERV 32\n#endif\n\nstatic struct addrinfo*\nsock_addrinfo(host, port, socktype, flags)\n    VALUE host, port;\n    int socktype, flags;\n{\n    struct addrinfo hints;\n    struct addrinfo* res = NULL;\n    char *hostp, *portp;\n    int error;\n    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];\n\n    hostp = host_str(host, hbuf, sizeof(hbuf));\n    portp = port_str(port, pbuf, sizeof(pbuf));\n\n    if (socktype == 0 && flags == 0 && str_isnumber(portp)) {\n       socktype = SOCK_DGRAM;\n    }\n\n    MEMZERO(&hints, struct addrinfo, 1);\n    hints.ai_family = AF_UNSPEC;\n    hints.ai_socktype = socktype;\n    hints.ai_flags = flags;\n    error = getaddrinfo(hostp, portp, &hints, &res);\n    if (error) {\n\tif (hostp && hostp[strlen(hostp)-1] == '\\n') {\n\t    rb_raise(rb_eSocket, \"newline at the end of hostname\");\n\t}\n\trb_raise(rb_eSocket, \"getaddrinfo: %s\", gai_strerror(error));\n    }\n\n#if defined(__APPLE__) && defined(__MACH__)\n    {\n        struct addrinfo *r;\n       r = res;\n       while (r) {\n            if (! r->ai_socktype) r->ai_socktype = hints.ai_socktype;\n            if (! r->ai_protocol) {\n                if (r->ai_socktype == SOCK_DGRAM) {\n                    r->ai_protocol = IPPROTO_UDP;\n                } else if (r->ai_socktype == SOCK_STREAM) {\n                    r->ai_protocol = IPPROTO_TCP;\n                }\n            }\n            r = r->ai_next;\n        }\n    }\n#endif\n    return res;\n}\n\nstatic VALUE\nipaddr(sockaddr)\n    struct sockaddr *sockaddr;\n{\n    VALUE family, port, addr1, addr2;\n    VALUE ary;\n    int error;\n    char hbuf[1024], pbuf[1024];\n\n    switch (sockaddr->sa_family) {\n    case AF_UNSPEC:\n\tfamily = rb_str_new2(\"AF_UNSPEC\");\n\tbreak;\n    case AF_INET:\n\tfamily = rb_str_new2(\"AF_INET\");\n\tbreak;\n#ifdef INET6\n    case AF_INET6:\n\tfamily = rb_str_new2(\"AF_INET6\");\n\tbreak;\n#endif\n#ifdef AF_LOCAL\n    case AF_LOCAL:\n\tfamily = rb_str_new2(\"AF_LOCAL\");\n\tbreak;\n#elif  AF_UNIX\n    case AF_UNIX:\n\tfamily = rb_str_new2(\"AF_UNIX\");\n\tbreak;\n#endif\n    default:\n        sprintf(pbuf, \"unknown:%d\", sockaddr->sa_family);\n\tfamily = rb_str_new2(pbuf);\n\tbreak;\n    }\n    addr1 = Qnil;\n    if (!do_not_reverse_lookup) {\n\terror = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf),\n\t\t\t    NULL, 0, 0);\n\tif (! error) {\n\t    addr1 = rb_str_new2(hbuf);\n\t}\n    }\n    error = getnameinfo(sockaddr, SA_LEN(sockaddr), hbuf, sizeof(hbuf),\n\t\t\tpbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV);\n    if (error) {\n\trb_raise(rb_eSocket, \"getnameinfo: %s\", gai_strerror(error));\n    }\n    addr2 = rb_str_new2(hbuf);\n    if (addr1 == Qnil) {\n\taddr1 = addr2;\n    }\n    port = INT2FIX(atoi(pbuf));\n    ary = rb_ary_new3(4, family, port, addr1, addr2);\n\n    return ary;\n}\n\nstatic int\nruby_socket(domain, type, proto)\n    int domain, type, proto;\n{\n    int fd;\n\n    fd = socket(domain, type, proto);\n    if (fd < 0) {\n\tif (errno == EMFILE || errno == ENFILE) {\n\t    rb_gc();\n\t    fd = socket(domain, type, proto);\n\t}\n    }\n    return fd;\n}\n\nstatic int\nwait_connectable(fd)\n    int fd;\n{\n    int sockerr;\n    socklen_t sockerrlen;\n    fd_set fds_w;\n    fd_set fds_e;\n\n    for (;;) {\n\tFD_ZERO(&fds_w);\n\tFD_ZERO(&fds_e);\n\n\tFD_SET(fd, &fds_w);\n\tFD_SET(fd, &fds_e);\n\n\trb_thread_select(fd+1, 0, &fds_w, &fds_e, 0);\n\n\tif (FD_ISSET(fd, &fds_w)) {\n\t    return 0;\n\t}\n\telse if (FD_ISSET(fd, &fds_e)) {\n\t    sockerrlen = sizeof(sockerr);\n\t    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr,\n\t\t\t   &sockerrlen) == 0) {\n\t\tif (sockerr == 0)\n\t\t    continue;\t/* workaround for winsock */\n\t\terrno = sockerr;\n\t    }\n\t    return -1;\n\t}\n    }\n\n    return 0;\n}\n\n#ifdef __CYGWIN__\n#define WAIT_IN_PROGRESS 10\n#endif\n#ifdef __APPLE__\n#define WAIT_IN_PROGRESS 10\n#endif\n#ifdef __linux__\n/* returns correct error */\n#define WAIT_IN_PROGRESS 0\n#endif\n#ifndef WAIT_IN_PROGRESS\n/* BSD origin code apparently has a problem */\n#define WAIT_IN_PROGRESS 1\n#endif\n\nstatic int\nruby_connect(fd, sockaddr, len, socks)\n    int fd;\n    struct sockaddr *sockaddr;\n    int len;\n    int socks;\n{\n    int status;\n    int mode;\n#if WAIT_IN_PROGRESS > 0\n    int wait_in_progress = -1;\n    int sockerr;\n    socklen_t sockerrlen;\n#endif\n\n#if defined(HAVE_FCNTL)\n# if defined(F_GETFL)\n    mode = fcntl(fd, F_GETFL, 0);\n# else\n    mode = 0;\n# endif\n\n#ifdef O_NDELAY\n# define NONBLOCKING O_NDELAY\n#else\n#ifdef O_NBIO\n# define NONBLOCKING O_NBIO\n#else\n# define NONBLOCKING O_NONBLOCK\n#endif\n#endif\n#ifdef SOCKS5\n    if (!socks)\n#endif\n    fcntl(fd, F_SETFL, mode|NONBLOCKING);\n#endif /* HAVE_FCNTL */\n\n    for (;;) {\n#if defined(SOCKS) && !defined(SOCKS5)\n\tif (socks) {\n\t    status = Rconnect(fd, sockaddr, len);\n\t}\n\telse\n#endif\n\t{\n\t    status = connect(fd, sockaddr, len);\n\t}\n\tif (status < 0) {\n\t    switch (errno) {\n\t      case EAGAIN:\n#ifdef EINPROGRESS\n\t      case EINPROGRESS:\n#endif\n#if WAIT_IN_PROGRESS > 0\n\t\tsockerrlen = sizeof(sockerr);\n\t\tstatus = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen);\n\t\tif (status) break;\n\t\tif (sockerr) {\n\t\t    status = -1;\n\t\t    errno = sockerr;\n\t\t    break;\n\t\t}\n#endif\n#ifdef EALREADY\n\t      case EALREADY:\n#endif\n#if WAIT_IN_PROGRESS > 0\n\t\twait_in_progress = WAIT_IN_PROGRESS;\n#endif\n\t\tstatus = wait_connectable(fd);\n\t\tif (status) {\n\t\t    break;\n\t\t}\n\t\terrno = 0;\n\t\tcontinue;\n\n#if WAIT_IN_PROGRESS > 0\n\t      case EINVAL:\n\t\tif (wait_in_progress-- > 0) {\n\t\t    /*\n\t\t     * connect() after EINPROGRESS returns EINVAL on\n\t\t     * some platforms, need to check true error\n\t\t     * status.\n\t\t     */\n\t\t    sockerrlen = sizeof(sockerr);\n\t\t    status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen);\n\t\t    if (!status && !sockerr) {\n\t\t\tstruct timeval tv = {0, 100000};\n\t\t\trb_thread_wait_for(tv);\n\t\t\tcontinue;\n\t\t    }\n\t\t    status = -1;\n\t\t    errno = sockerr;\n\t\t}\n\t\tbreak;\n#endif\n\n#ifdef EISCONN\n\t      case EISCONN:\n\t\tstatus = 0;\n\t\terrno = 0;\n\t\tbreak;\n#endif\n\t      default:\n\t\tbreak;\n\t    }\n\t}\n#ifdef HAVE_FCNTL\n\tfcntl(fd, F_SETFL, mode);\n#endif\n\treturn status;\n    }\n}\n\nstruct inetsock_arg\n{\n    VALUE sock;\n    struct {\n\tVALUE host, serv;\n\tstruct addrinfo *res;\n    } remote, local;\n    int type;\n    int fd;\n};\n\nstatic VALUE\ninetsock_cleanup(arg)\n    struct inetsock_arg *arg;\n{\n    if (arg->remote.res) {\n\tfreeaddrinfo(arg->remote.res);\n\targ->remote.res = 0;\n    }\n    if (arg->local.res) {\n\tfreeaddrinfo(arg->local.res);\n\targ->local.res = 0;\n    }\n    if (arg->fd >= 0) {\n\tclose(arg->fd);\n    }\n    return Qnil;\n}\n\nstatic VALUE\ninit_inetsock_internal(arg)\n    struct inetsock_arg *arg;\n{\n    int type = arg->type;\n    struct addrinfo *res;\n    int fd, status = 0;\n    char *syscall;\n\n    arg->remote.res = sock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM,\n\t\t\t\t    (type == INET_SERVER) ? AI_PASSIVE : 0);\n    /*\n     * Maybe also accept a local address\n     */\n\n    if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) {\n\targ->local.res = sock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0);\n    }\n\n    arg->fd = fd = -1;\n    for (res = arg->remote.res; res; res = res->ai_next) {\n\tstatus = ruby_socket(res->ai_family,res->ai_socktype,res->ai_protocol);\n\tsyscall = \"socket(2)\";\n\tfd = status;\n\tif (fd < 0) {\n\t    continue;\n\t}\n\targ->fd = fd;\n\tif (type == INET_SERVER) {\n#if !defined(_WIN32) && !defined(__CYGWIN__)\n\t    status = 1;\n\t    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,\n\t\t       (char*)&status, sizeof(status));\n#endif\n\t    status = bind(fd, res->ai_addr, res->ai_addrlen);\n\t    syscall = \"bind(2)\";\n\t}\n\telse {\n\t    if (arg->local.res) {\n\t\tstatus = bind(fd, arg->local.res->ai_addr, arg->local.res->ai_addrlen);\n\t\tsyscall = \"bind(2)\";\n\t    }\n\n\t    if (status >= 0) {\n\t\tstatus = ruby_connect(fd, res->ai_addr, res->ai_addrlen,\n\t\t\t\t      (type == INET_SOCKS));\n\t\tsyscall = \"connect(2)\";\n\t    }\n\t}\n\n\tif (status < 0) {\n\t    close(fd);\n\t    arg->fd = fd = -1;\n\t    continue;\n\t} else\n\t    break;\n    }\n    if (status < 0) {\n\trb_sys_fail(syscall);\n    }\n\n    arg->fd = -1;\n\n    if (type == INET_SERVER)\n\tlisten(fd, 5);\n\n    /* create new instance */\n    return init_sock(arg->sock, fd);\n}\n\nstatic VALUE\ninit_inetsock(sock, remote_host, remote_serv, local_host, local_serv, type)\n    VALUE sock, remote_host, remote_serv, local_host, local_serv;\n    int type;\n{\n    struct inetsock_arg arg;\n    arg.sock = sock;\n    arg.remote.host = remote_host;\n    arg.remote.serv = remote_serv;\n    arg.remote.res = 0;\n    arg.local.host = local_host;\n    arg.local.serv = local_serv;\n    arg.local.res = 0;\n    arg.type = type;\n    arg.fd = -1;\n    return rb_ensure(init_inetsock_internal, (VALUE)&arg,\n\t\t     inetsock_cleanup, (VALUE)&arg);\n}\n\n/*\n * call-seq:\n *    TCPSocket.new(remote_host, remote_port, local_host=nil, local_port=nil)\n *\n * Opens a TCP connection to +remote_host+ on +remote_port+.  If +local_host+\n * and +local_port+ are specified, then those parameters are used on the local\n * end to establish the connection.\n */\nstatic VALUE\ntcp_init(argc, argv, sock)\n     int argc;\n     VALUE *argv;\n     VALUE sock;\n{\n    VALUE remote_host, remote_serv;\n    VALUE local_host, local_serv;\n\n    rb_scan_args(argc, argv, \"22\", &remote_host, &remote_serv,\n\t\t\t&local_host, &local_serv);\n\n    return init_inetsock(sock, remote_host, remote_serv,\n\t\t\tlocal_host, local_serv, INET_CLIENT);\n}\n\n#ifdef SOCKS\nstatic VALUE\nsocks_init(sock, host, serv)\n    VALUE sock, host, serv;\n{\n    static init = 0;\n\n    if (init == 0) {\n\tSOCKSinit(\"ruby\");\n\tinit = 1;\n    }\n\n    return init_inetsock(sock, host, serv, Qnil, Qnil, INET_SOCKS);\n}\n\n#ifdef SOCKS5\nstatic VALUE\nsocks_s_close(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close socket\");\n    }\n    GetOpenFile(sock, fptr);\n    shutdown(fileno(fptr->f), 2);\n    shutdown(fileno(fptr->f2), 2);\n    return rb_io_close(sock);\n}\n#endif\n#endif\n\nstruct hostent_arg {\n    VALUE host;\n    struct addrinfo* addr;\n    VALUE (*ipaddr)_((struct sockaddr*, size_t));\n};\n\nstatic VALUE\nmake_hostent_internal(arg)\n    struct hostent_arg *arg;\n{\n    VALUE host = arg->host;\n    struct addrinfo* addr = arg->addr;\n    VALUE (*ipaddr)_((struct sockaddr*, size_t)) = arg->ipaddr;\n\n    struct addrinfo *ai;\n    struct hostent *h;\n    VALUE ary, names;\n    char **pch;\n    const char* hostp;\n    char hbuf[NI_MAXHOST];\n\n    ary = rb_ary_new();\n    if (addr->ai_canonname) {\n\thostp = addr->ai_canonname;\n    }\n    else {\n\thostp = host_str(host, hbuf, sizeof(hbuf));\n    }\n    rb_ary_push(ary, rb_str_new2(hostp));\n\n    if (addr->ai_canonname && (h = gethostbyname(addr->ai_canonname))) {\n\tnames = rb_ary_new();\n\tif (h->h_aliases != NULL) {\n\t    for (pch = h->h_aliases; *pch; pch++) {\n\t\trb_ary_push(names, rb_str_new2(*pch));\n\t    }\n\t}\n    }\n    else {\n\tnames = rb_ary_new2(0);\n    }\n    rb_ary_push(ary, names);\n    rb_ary_push(ary, INT2NUM(addr->ai_family));\n    for (ai = addr; ai; ai = ai->ai_next) {\n      /* Pushing all addresses regardless of address family is not the\n       * behaviour expected of gethostbyname(). All the addresses in struct\n       * hostent->h_addr_list must be of the same family.\n       */\n       if(ai->ai_family == addr->ai_family) {\n\t   rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen));\n       }\n    }\n\n    return ary;\n}\n\nstatic VALUE\nmake_hostent(host, addr, ipaddr)\n    VALUE host;\n    struct addrinfo* addr;\n    VALUE (*ipaddr)_((struct sockaddr*, size_t));\n{\n    struct hostent_arg arg;\n\n    arg.host = host;\n    arg.addr = addr;\n    arg.ipaddr = ipaddr;\n    return rb_ensure(make_hostent_internal, (VALUE)&arg,\n\t\t     RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)addr);\n}\n\nVALUE\ntcp_sockaddr(addr, len)\n    struct sockaddr *addr;\n    size_t len;\n{\n    return make_ipaddr(addr);\n}\n\nstatic VALUE\ntcp_s_gethostbyname(obj, host)\n    VALUE obj, host;\n{\n    rb_secure(3);\n    return make_hostent(host, sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), tcp_sockaddr);\n}\n\nstatic VALUE\ntcp_svr_init(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    VALUE arg1, arg2;\n\n    if (rb_scan_args(argc, argv, \"11\", &arg1, &arg2) == 2)\n\treturn init_inetsock(sock, arg1, arg2, Qnil, Qnil, INET_SERVER);\n    else\n\treturn init_inetsock(sock, Qnil, arg1, Qnil, Qnil, INET_SERVER);\n}\n\nstatic void\nmake_fd_nonblock(int fd)\n{\n    int flags;\n#ifdef F_GETFL\n    flags = fcntl(fd, F_GETFL);\n    if (flags == -1) {\n        rb_sys_fail(0);\n    }\n#else\n    flags = 0;\n#endif\n    flags |= O_NONBLOCK;\n    if (fcntl(fd, F_SETFL, flags) == -1) {\n        rb_sys_fail(0);\n    }\n}\n\nstatic VALUE\ns_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)\n{\n    int fd2;\n\n    rb_secure(3);\n    rb_io_set_nonblock(fptr);\n    fd2 = accept(fileno(fptr->f), (struct sockaddr*)sockaddr, len);\n    if (fd2 < 0) {\n        rb_sys_fail(\"accept(2)\");\n    }\n    make_fd_nonblock(fd2);\n    return init_sock(rb_obj_alloc(klass), fd2);\n}\n\nstatic VALUE\ns_accept(klass, fd, sockaddr, len)\n    VALUE klass;\n    int fd;\n    struct sockaddr *sockaddr;\n    socklen_t *len;\n{\n    int fd2;\n    int retry = 0;\n\n    rb_secure(3);\n  retry:\n    rb_thread_wait_fd(fd);\n#if defined(_nec_ews)\n    fd2 = accept(fd, sockaddr, len);\n#else\n    TRAP_BEG;\n    fd2 = accept(fd, sockaddr, len);\n    TRAP_END;\n#endif\n    if (fd2 < 0) {\n\tswitch (errno) {\n\t  case EMFILE:\n\t  case ENFILE:\n\t    if (retry) break;\n\t    rb_gc();\n\t    retry = 1;\n\t    goto retry;\n\t  case EWOULDBLOCK:\n\t    break;\n\t  default:\n\t    if (!rb_io_wait_readable(fd)) break;\n\t    retry = 0;\n\t    goto retry;\n\t}\n\trb_sys_fail(0);\n    }\n    if (!klass) return INT2NUM(fd2);\n    return init_sock(rb_obj_alloc(klass), fd2);\n}\n\nstatic VALUE\ntcp_accept(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_storage from;\n    socklen_t fromlen;\n\n    GetOpenFile(sock, fptr);\n    fromlen = sizeof(from);\n    return s_accept(rb_cTCPSocket, fileno(fptr->f),\n\t\t    (struct sockaddr*)&from, &fromlen);\n}\n\n/*\n * call-seq:\n * \ttcpserver.accept_nonblock => tcpsocket\n * \n * Accepts an incoming connection using accept(2) after\n * O_NONBLOCK is set for the underlying file descriptor.\n * It returns an accepted TCPSocket for the incoming connection.\n * \n * === Example\n * \trequire 'socket'\n * \tserv = TCPServer.new(2202)\n * \tbegin\n * \t  sock = serv.accept_nonblock\n * \trescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR\n * \t  IO.select([serv])\n * \t  retry\n * \tend\n * \t# sock is an accepted socket.\n * \n * Refer to Socket#accept for the exceptions that may be thrown if the call\n * to TCPServer#accept_nonblock fails. \n *\n * TCPServer#accept_nonblock may raise any error corresponding to accept(2) failure,\n * including Errno::EAGAIN.\n * \n * === See\n * * TCPServer#accept\n * * Socket#accept\n */\nstatic VALUE\ntcp_accept_nonblock(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_storage from;\n    socklen_t fromlen;\n\n    GetOpenFile(sock, fptr);\n    fromlen = sizeof(from);\n    return s_accept_nonblock(rb_cTCPSocket, fptr,\n                             (struct sockaddr *)&from, &fromlen);\n}\n\nstatic VALUE\ntcp_sysaccept(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_storage from;\n    socklen_t fromlen;\n\n    GetOpenFile(sock, fptr);\n    fromlen = sizeof(from);\n    return s_accept(0, fileno(fptr->f), (struct sockaddr*)&from, &fromlen);\n}\n\n#ifdef HAVE_SYS_UN_H\nstruct unixsock_arg {\n    struct sockaddr_un *sockaddr;\n    int fd;\n};\n\nstatic VALUE\nunixsock_connect_internal(arg)\n    struct unixsock_arg *arg;\n{\n    return (VALUE)ruby_connect(arg->fd, arg->sockaddr, sizeof(*arg->sockaddr),\n\t\t\t       0);\n}\n\nstatic VALUE\ninit_unixsock(sock, path, server)\n    VALUE sock;\n    VALUE path;\n    int server;\n{\n    struct sockaddr_un sockaddr;\n    int fd, status;\n    rb_io_t *fptr;\n\n    SafeStringValue(path);\n    fd = ruby_socket(AF_UNIX, SOCK_STREAM, 0);\n    if (fd < 0) {\n\trb_sys_fail(\"socket(2)\");\n    }\n\n    MEMZERO(&sockaddr, struct sockaddr_un, 1);\n    sockaddr.sun_family = AF_UNIX;\n    if (sizeof(sockaddr.sun_path) <= RSTRING(path)->len) {\n        rb_raise(rb_eArgError, \"too long unix socket path (max: %dbytes)\",\n            (int)sizeof(sockaddr.sun_path)-1);\n    }\n    strcpy(sockaddr.sun_path, StringValueCStr(path));\n\n    if (server) {\n        status = bind(fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr));\n    }\n    else {\n\tint prot;\n\tstruct unixsock_arg arg;\n\targ.sockaddr = &sockaddr;\n\targ.fd = fd;\n        status = rb_protect(unixsock_connect_internal, (VALUE)&arg, &prot);\n\tif (prot) {\n\t    close(fd);\n\t    rb_jump_tag(prot);\n\t}\n    }\n\n    if (status < 0) {\n\tclose(fd);\n\trb_sys_fail(sockaddr.sun_path);\n    }\n\n    if (server) listen(fd, 5);\n\n    init_sock(sock, fd);\n    GetOpenFile(sock, fptr);\n    if (server) {\n        fptr->path = strdup(RSTRING(path)->ptr);\n    }\n\n    return sock;\n}\n#endif\n\nstatic VALUE\nip_addr(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_storage addr;\n    socklen_t len = sizeof addr;\n\n    GetOpenFile(sock, fptr);\n\n    if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)\n\trb_sys_fail(\"getsockname(2)\");\n    return ipaddr((struct sockaddr*)&addr);\n}\n\nstatic VALUE\nip_peeraddr(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_storage addr;\n    socklen_t len = sizeof addr;\n\n    GetOpenFile(sock, fptr);\n\n    if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)\n\trb_sys_fail(\"getpeername(2)\");\n    return ipaddr((struct sockaddr*)&addr);\n}\n\nstatic VALUE\nip_recvfrom(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    return s_recvfrom(sock, argc, argv, RECV_IP);\n}\n\nstatic VALUE\nip_s_getaddress(obj, host)\n    VALUE obj, host;\n{\n    struct sockaddr_storage addr;\n    struct addrinfo *res = sock_addrinfo(host, Qnil, SOCK_STREAM, 0);\n\n    /* just take the first one */\n    memcpy(&addr, res->ai_addr, res->ai_addrlen);\n    freeaddrinfo(res);\n\n    return make_ipaddr((struct sockaddr*)&addr);\n}\n\nstatic VALUE\nudp_init(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    VALUE arg;\n    int socktype = AF_INET;\n    int fd;\n\n    rb_secure(3);\n    if (rb_scan_args(argc, argv, \"01\", &arg) == 1) {\n\tsocktype = NUM2INT(arg);\n    }\n    fd = ruby_socket(socktype, SOCK_DGRAM, 0);\n    if (fd < 0) {\n\trb_sys_fail(\"socket(2) - udp\");\n    }\n\n    return init_sock(sock, fd);\n}\n\nstruct udp_arg\n{\n    struct addrinfo *res;\n    int fd;\n};\n\nstatic VALUE\nudp_connect_internal(arg)\n    struct udp_arg *arg;\n{\n    int fd = arg->fd;\n    struct addrinfo *res;\n\n    for (res = arg->res; res; res = res->ai_next) {\n\tif (ruby_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) {\n\t    return Qtrue;\n\t}\n    }\n    return Qfalse;\n}\n\nstatic VALUE\nudp_connect(sock, host, port)\n    VALUE sock, host, port;\n{\n    rb_io_t *fptr;\n    struct udp_arg arg;\n    VALUE ret;\n\n    rb_secure(3);\n    arg.res = sock_addrinfo(host, port, SOCK_DGRAM, 0);\n    GetOpenFile(sock, fptr);\n    arg.fd = fileno(fptr->f);\n    ret = rb_ensure(udp_connect_internal, (VALUE)&arg,\n\t\t    RUBY_METHOD_FUNC(freeaddrinfo), (VALUE)arg.res);\n    if (!ret) rb_sys_fail(\"connect(2)\");\n    return INT2FIX(0);\n}\n\nstatic VALUE\nudp_bind(sock, host, port)\n    VALUE sock, host, port;\n{\n    rb_io_t *fptr;\n    struct addrinfo *res0, *res;\n\n    rb_secure(3);\n    res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0);\n    GetOpenFile(sock, fptr);\n    for (res = res0; res; res = res->ai_next) {\n\tif (bind(fileno(fptr->f), res->ai_addr, res->ai_addrlen) < 0) {\n\t    continue;\n\t}\n\tfreeaddrinfo(res0);\n\treturn INT2FIX(0);\n    }\n    freeaddrinfo(res0);\n    rb_sys_fail(\"bind(2)\");\n    return INT2FIX(0);\n}\n\nstatic VALUE\nudp_send(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    VALUE mesg, flags, host, port;\n    rb_io_t *fptr;\n    FILE *f;\n    int n;\n    struct addrinfo *res0, *res;\n\n    if (argc == 2 || argc == 3) {\n\treturn bsock_send(argc, argv, sock);\n    }\n    rb_secure(4);\n    rb_scan_args(argc, argv, \"4\", &mesg, &flags, &host, &port);\n\n    StringValue(mesg);\n    res0 = sock_addrinfo(host, port, SOCK_DGRAM, 0);\n    GetOpenFile(sock, fptr);\n    f = GetWriteFile(fptr);\n    for (res = res0; res; res = res->ai_next) {\n      retry:\n\tn = sendto(fileno(f), RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags),\n\t\t   res->ai_addr, res->ai_addrlen);\n\tif (n >= 0) {\n\t    freeaddrinfo(res0);\n\t    return INT2FIX(n);\n\t}\n\tif (rb_io_wait_writable(fileno(f))) {\n\t    goto retry;\n\t}\n    }\n    freeaddrinfo(res0);\n    rb_sys_fail(\"sendto(2)\");\n    return INT2FIX(n);\n}\n\n/*\n * call-seq:\n * \tudpsocket.recvfrom_nonblock(maxlen) => [mesg, sender_inet_addr]\n * \tudpsocket.recvfrom_nonblock(maxlen, flags) => [mesg, sender_inet_addr]\n * \n * Receives up to _maxlen_ bytes from +udpsocket+ using recvfrom(2) after\n * O_NONBLOCK is set for the underlying file descriptor.\n * _flags_ is zero or more of the +MSG_+ options.\n * The first element of the results, _mesg_, is the data received.\n * The second element, _sender_inet_addr_, is an array to represent the sender address.\n *\n * When recvfrom(2) returns 0,\n * Socket#recvfrom_nonblock returns an empty string as data.\n * It means an empty packet.\n * \n * === Parameters\n * * +maxlen+ - the number of bytes to receive from the socket\n * * +flags+ - zero or more of the +MSG_+ options \n * \n * === Example\n * \trequire 'socket'\n * \ts1 = UDPSocket.new\n * \ts1.bind(\"127.0.0.1\", 0)\n * \ts2 = UDPSocket.new\n * \ts2.bind(\"127.0.0.1\", 0)\n * \ts2.connect(*s1.addr.values_at(3,1))\n * \ts1.connect(*s2.addr.values_at(3,1))\n * \ts1.send \"aaa\", 0\n * \tIO.select([s2])\n * \tp s2.recvfrom_nonblock(10)  #=> [\"aaa\", [\"AF_INET\", 33302, \"localhost.localdomain\", \"127.0.0.1\"]]\n *\n * Refer to Socket#recvfrom for the exceptions that may be thrown if the call\n * to _recvfrom_nonblock_ fails. \n *\n * UDPSocket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure,\n * including Errno::EAGAIN.\n *\n * === See\n * * Socket#recvfrom\n */\nstatic VALUE\nudp_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)\n{\n    return s_recvfrom_nonblock(sock, argc, argv, RECV_IP);\n}\n\n#ifdef HAVE_SYS_UN_H\nstatic VALUE\nunix_init(sock, path)\n    VALUE sock, path;\n{\n    return init_unixsock(sock, path, 0);\n}\n\nstatic char *\nunixpath(struct sockaddr_un *sockaddr, socklen_t len)\n{\n    if (sockaddr->sun_path < (char*)sockaddr + len)\n        return sockaddr->sun_path;\n    else\n        return \"\";\n}\n\nstatic VALUE\nunix_path(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(sock, fptr);\n    if (fptr->path == 0) {\n\tstruct sockaddr_un addr;\n\tsocklen_t len = sizeof(addr);\n\tif (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)\n\t    rb_sys_fail(0);\n\tfptr->path = strdup(unixpath(&addr, len));\n    }\n    return rb_str_new2(fptr->path);\n}\n\nstatic VALUE\nunix_svr_init(sock, path)\n    VALUE sock, path;\n{\n    return init_unixsock(sock, path, 1);\n}\n\nstatic VALUE\nunix_recvfrom(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    return s_recvfrom(sock, argc, argv, RECV_UNIX);\n}\n\n#if defined(HAVE_ST_MSG_CONTROL) && defined(SCM_RIGHTS)\n#define FD_PASSING_BY_MSG_CONTROL 1\n#else\n#define FD_PASSING_BY_MSG_CONTROL 0\n#endif\n\n#if defined(HAVE_ST_MSG_ACCRIGHTS)\n#define FD_PASSING_BY_MSG_ACCRIGHTS 1\n#else\n#define FD_PASSING_BY_MSG_ACCRIGHTS 0\n#endif\n\nstatic VALUE\nunix_send_io(sock, val)\n    VALUE sock, val;\n{\n#if defined(HAVE_SENDMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)\n    int fd;\n    rb_io_t *fptr;\n    struct msghdr msg;\n    struct iovec vec[1];\n    char buf[1];\n\n#if FD_PASSING_BY_MSG_CONTROL\n    struct {\n\tstruct cmsghdr hdr;\n        char pad[8+sizeof(int)+8];\n    } cmsg;\n#endif\n\n    if (rb_obj_is_kind_of(val, rb_cIO)) {\n        rb_io_t *valfptr;\n\tGetOpenFile(val, valfptr);\n\tfd = fileno(valfptr->f);\n    }\n    else if (FIXNUM_P(val)) {\n        fd = FIX2INT(val);\n    }\n    else {\n\trb_raise(rb_eTypeError, \"neither IO nor file descriptor\");\n    }\n\n    GetOpenFile(sock, fptr);\n\n    msg.msg_name = NULL;\n    msg.msg_namelen = 0;\n\n    /* Linux and Solaris doesn't work if msg_iov is NULL. */\n    buf[0] = '\\0';\n    vec[0].iov_base = buf;\n    vec[0].iov_len = 1;\n    msg.msg_iov = vec;\n    msg.msg_iovlen = 1;\n\n#if FD_PASSING_BY_MSG_CONTROL\n    msg.msg_control = (caddr_t)&cmsg;\n    msg.msg_controllen = CMSG_LEN(sizeof(int));\n    msg.msg_flags = 0;\n    MEMZERO((char*)&cmsg, char, sizeof(cmsg));\n    cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));\n    cmsg.hdr.cmsg_level = SOL_SOCKET;\n    cmsg.hdr.cmsg_type = SCM_RIGHTS;\n    *(int *)CMSG_DATA(&cmsg.hdr) = fd;\n#else\n    msg.msg_accrights = (caddr_t)&fd;\n    msg.msg_accrightslen = sizeof(fd);\n#endif\n\n    if (sendmsg(fileno(fptr->f), &msg, 0) == -1)\n\trb_sys_fail(\"sendmsg(2)\");\n\n    return Qnil;\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n#if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)\nstatic void\nthread_read_select(fd)\n    int fd;\n{\n    fd_set fds;\n\n    FD_ZERO(&fds);\n    FD_SET(fd, &fds);\n    rb_thread_select(fd+1, &fds, 0, 0, 0);\n}\n#endif\n\nstatic VALUE\nunix_recv_io(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n#if defined(HAVE_RECVMSG) && (FD_PASSING_BY_MSG_CONTROL || FD_PASSING_BY_MSG_ACCRIGHTS)\n    VALUE klass, mode;\n    rb_io_t *fptr;\n    struct msghdr msg;\n    struct iovec vec[2];\n    char buf[1];\n\n    int fd;\n#if FD_PASSING_BY_MSG_CONTROL\n    struct {\n\tstruct cmsghdr hdr;\n        char pad[8+sizeof(int)+8];\n    } cmsg;\n#endif\n\n    rb_scan_args(argc, argv, \"02\", &klass, &mode);\n    if (argc == 0)\n\tklass = rb_cIO;\n    if (argc <= 1)\n\tmode = Qnil;\n\n    GetOpenFile(sock, fptr);\n\n    thread_read_select(fileno(fptr->f));\n\n    msg.msg_name = NULL;\n    msg.msg_namelen = 0;\n\n    vec[0].iov_base = buf;\n    vec[0].iov_len = sizeof(buf);\n    msg.msg_iov = vec;\n    msg.msg_iovlen = 1;\n\n#if FD_PASSING_BY_MSG_CONTROL\n    msg.msg_control = (caddr_t)&cmsg;\n    msg.msg_controllen = CMSG_SPACE(sizeof(int));\n    msg.msg_flags = 0;\n    cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int));\n    cmsg.hdr.cmsg_level = SOL_SOCKET;\n    cmsg.hdr.cmsg_type = SCM_RIGHTS;\n    *(int *)CMSG_DATA(&cmsg.hdr) = -1;\n#else\n    msg.msg_accrights = (caddr_t)&fd;\n    msg.msg_accrightslen = sizeof(fd);\n    fd = -1;\n#endif\n\n    if (recvmsg(fileno(fptr->f), &msg, 0) == -1)\n\trb_sys_fail(\"recvmsg(2)\");\n\n#if FD_PASSING_BY_MSG_CONTROL\n    if (msg.msg_controllen != CMSG_SPACE(sizeof(int))) {\n      rb_raise(rb_eSocket,\n          \"file descriptor was not passed (msg_controllen=%d, %d expected)\",\n          msg.msg_controllen, CMSG_SPACE(sizeof(int)));\n    }\n    if (cmsg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {\n      rb_raise(rb_eSocket,\n          \"file descriptor was not passed (cmsg_len=%d, %d expected)\",\n          cmsg.hdr.cmsg_len, CMSG_LEN(sizeof(int)));\n    }\n    if (cmsg.hdr.cmsg_level != SOL_SOCKET) {\n      rb_raise(rb_eSocket,\n          \"file descriptor was not passed (cmsg_level=%d, %d expected)\",\n          cmsg.hdr.cmsg_level, SOL_SOCKET);\n    }\n    if (cmsg.hdr.cmsg_type != SCM_RIGHTS) {\n      rb_raise(rb_eSocket,\n          \"file descriptor was not passed (cmsg_type=%d, %d expected)\",\n          cmsg.hdr.cmsg_type, SCM_RIGHTS);\n    }\n#else\n    if (msg.msg_accrightslen != sizeof(fd)) {\n\trb_raise(rb_eSocket,\n            \"file descriptor was not passed (accrightslen) : %d != %d\",\n            msg.msg_accrightslen, sizeof(fd));\n    }\n#endif\n\n#if FD_PASSING_BY_MSG_CONTROL\n    fd = *(int *)CMSG_DATA(&cmsg.hdr);\n#endif\n\n    if (klass == Qnil)\n\treturn INT2FIX(fd);\n    else {\n\tstatic ID for_fd = 0;\n\tint ff_argc;\n\tVALUE ff_argv[2];\n\tif (!for_fd)\n\t    for_fd = rb_intern(\"for_fd\");\n\tff_argc = mode == Qnil ? 1 : 2;\n\tff_argv[0] = INT2FIX(fd);\n\tff_argv[1] = mode;\n        return rb_funcall2(klass, for_fd, ff_argc, ff_argv);\n    }\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\nstatic VALUE\nunix_accept(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_un from;\n    socklen_t fromlen;\n\n    GetOpenFile(sock, fptr);\n    fromlen = sizeof(struct sockaddr_un);\n    return s_accept(rb_cUNIXSocket, fileno(fptr->f),\n\t\t    (struct sockaddr*)&from, &fromlen);\n}\n\n/*\n * call-seq:\n * \tunixserver.accept_nonblock => unixsocket\n * \n * Accepts an incoming connection using accept(2) after\n * O_NONBLOCK is set for the underlying file descriptor.\n * It returns an accepted UNIXSocket for the incoming connection.\n * \n * === Example\n * \trequire 'socket'\n * \tserv = UNIXServer.new(\"/tmp/sock\")\n * \tbegin\n * \t  sock = serv.accept_nonblock\n * \trescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR\n * \t  IO.select([serv])\n * \t  retry\n * \tend\n * \t# sock is an accepted socket.\n * \n * Refer to Socket#accept for the exceptions that may be thrown if the call\n * to UNIXServer#accept_nonblock fails. \n *\n * UNIXServer#accept_nonblock may raise any error corresponding to accept(2) failure,\n * including Errno::EAGAIN.\n * \n * === See\n * * UNIXServer#accept\n * * Socket#accept\n */\nstatic VALUE\nunix_accept_nonblock(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_un from;\n    socklen_t fromlen;\n\n    GetOpenFile(sock, fptr);\n    fromlen = sizeof(from);\n    return s_accept_nonblock(rb_cUNIXSocket, fptr,\n                             (struct sockaddr *)&from, &fromlen);\n}\n\nstatic VALUE\nunix_sysaccept(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_un from;\n    socklen_t fromlen;\n\n    GetOpenFile(sock, fptr);\n    fromlen = sizeof(struct sockaddr_un);\n    return s_accept(0, fileno(fptr->f), (struct sockaddr*)&from, &fromlen);\n}\n\nstatic VALUE\nunixaddr(sockaddr, len)\n    struct sockaddr_un *sockaddr;\n    socklen_t len;\n{\n    return rb_assoc_new(rb_str_new2(\"AF_UNIX\"),\n                        rb_str_new2(unixpath(sockaddr, len)));\n}\n\nstatic VALUE\nunix_addr(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_un addr;\n    socklen_t len = sizeof addr;\n\n    GetOpenFile(sock, fptr);\n\n    if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)\n\trb_sys_fail(\"getsockname(2)\");\n    return unixaddr(&addr, len);\n}\n\nstatic VALUE\nunix_peeraddr(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    struct sockaddr_un addr;\n    socklen_t len = sizeof addr;\n\n    GetOpenFile(sock, fptr);\n\n    if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)\n\trb_sys_fail(\"getpeername(2)\");\n    return unixaddr(&addr, len);\n}\n#endif\n\nstatic void\nsetup_domain_and_type(domain, dv, type, tv)\n    VALUE domain, type;\n    int *dv, *tv;\n{\n    VALUE tmp;\n    char *ptr;\n\n    tmp = rb_check_string_type(domain);\n    if (!NIL_P(tmp)) {\n\tdomain = tmp;\n\trb_check_safe_obj(domain);\n\tptr = RSTRING(domain)->ptr;\n\tif (strcmp(ptr, \"AF_INET\") == 0)\n\t    *dv = AF_INET;\n#ifdef AF_UNIX\n\telse if (strcmp(ptr, \"AF_UNIX\") == 0)\n\t    *dv = AF_UNIX;\n#endif\n#ifdef AF_ISO\n\telse if (strcmp(ptr, \"AF_ISO\") == 0)\n\t    *dv = AF_ISO;\n#endif\n#ifdef AF_NS\n\telse if (strcmp(ptr, \"AF_NS\") == 0)\n\t    *dv = AF_NS;\n#endif\n#ifdef AF_IMPLINK\n\telse if (strcmp(ptr, \"AF_IMPLINK\") == 0)\n\t    *dv = AF_IMPLINK;\n#endif\n#ifdef PF_INET\n\telse if (strcmp(ptr, \"PF_INET\") == 0)\n\t    *dv = PF_INET;\n#endif\n#ifdef PF_UNIX\n\telse if (strcmp(ptr, \"PF_UNIX\") == 0)\n\t    *dv = PF_UNIX;\n#endif\n#ifdef PF_IMPLINK\n\telse if (strcmp(ptr, \"PF_IMPLINK\") == 0)\n\t    *dv = PF_IMPLINK;\n\telse if (strcmp(ptr, \"AF_IMPLINK\") == 0)\n\t    *dv = AF_IMPLINK;\n#endif\n#ifdef PF_AX25\n\telse if (strcmp(ptr, \"PF_AX25\") == 0)\n\t    *dv = PF_AX25;\n#endif\n#ifdef PF_IPX\n\telse if (strcmp(ptr, \"PF_IPX\") == 0)\n\t    *dv = PF_IPX;\n#endif\n\telse\n\t    rb_raise(rb_eSocket, \"unknown socket domain %s\", ptr);\n    }\n    else {\n\t*dv = NUM2INT(domain);\n    }\n    tmp = rb_check_string_type(type);\n    if (!NIL_P(tmp)) {\n\ttype = tmp;\n\trb_check_safe_obj(type);\n\tptr = RSTRING(type)->ptr;\n\tif (strcmp(ptr, \"SOCK_STREAM\") == 0)\n\t    *tv = SOCK_STREAM;\n\telse if (strcmp(ptr, \"SOCK_DGRAM\") == 0)\n\t    *tv = SOCK_DGRAM;\n#ifdef SOCK_RAW\n\telse if (strcmp(ptr, \"SOCK_RAW\") == 0)\n\t    *tv = SOCK_RAW;\n#endif\n#ifdef SOCK_SEQPACKET\n\telse if (strcmp(ptr, \"SOCK_SEQPACKET\") == 0)\n\t    *tv = SOCK_SEQPACKET;\n#endif\n#ifdef SOCK_RDM\n\telse if (strcmp(ptr, \"SOCK_RDM\") == 0)\n\t    *tv = SOCK_RDM;\n#endif\n#ifdef SOCK_PACKET\n\telse if (strcmp(ptr, \"SOCK_PACKET\") == 0)\n\t    *tv = SOCK_PACKET;\n#endif\n\telse\n\t    rb_raise(rb_eSocket, \"unknown socket type %s\", ptr);\n    }\n    else {\n\t*tv = NUM2INT(type);\n    }\n}\n\nstatic VALUE\nsock_initialize(sock, domain, type, protocol)\n    VALUE sock, domain, type, protocol;\n{\n    int fd;\n    int d, t;\n\n    rb_secure(3);\n    setup_domain_and_type(domain, &d, type, &t);\n    fd = ruby_socket(d, t, NUM2INT(protocol));\n    if (fd < 0) rb_sys_fail(\"socket(2)\");\n\n    return init_sock(sock, fd);\n}\n\nstatic VALUE\nsock_s_socketpair(klass, domain, type, protocol)\n    VALUE klass, domain, type, protocol;\n{\n#if defined HAVE_SOCKETPAIR\n    int d, t, p, sp[2];\n    int ret;\n\n    setup_domain_and_type(domain, &d, type, &t);\n    p = NUM2INT(protocol);\n    ret = socketpair(d, t, p, sp);\n    if (ret < 0 && (errno == EMFILE || errno == ENFILE)) {\n        rb_gc();\n        ret = socketpair(d, t, p, sp);\n    }\n    if (ret < 0) {\n\trb_sys_fail(\"socketpair(2)\");\n    }\n\n    return rb_assoc_new(init_sock(rb_obj_alloc(klass), sp[0]),\n\t\t\tinit_sock(rb_obj_alloc(klass), sp[1]));\n#else\n    rb_notimplement();\n#endif\n}\n\n#ifdef HAVE_SYS_UN_H\nstatic VALUE\nunix_s_socketpair(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE domain, type, protocol;\n    domain = INT2FIX(PF_UNIX);\n\n    rb_scan_args(argc, argv, \"02\", &type, &protocol);\n    if (argc == 0)\n\ttype = INT2FIX(SOCK_STREAM);\n    if (argc <= 1)\n\tprotocol = INT2FIX(0);\n\n    return sock_s_socketpair(klass, domain, type, protocol);\n}\n#endif\n\n/*\n * call-seq:\n * \tsocket.connect(server_sockaddr) => 0\n * \n * Requests a connection to be made on the given +server_sockaddr+. Returns 0 if\n * successful, otherwise an exception is raised.\n *  \n * === Parameter\n * * +server_sockaddr+ - the +struct+ sockaddr contained in a string\n * \n * === Example:\n * \t# Pull down Google's web page\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' )\n * \tsocket.connect( sockaddr )\n * \tsocket.write( \"GET / HTTP/1.0\\r\\n\\r\\n\" )\n * \tresults = socket.read \n * \n * === Unix-based Exceptions\n * On unix-based systems the following system exceptions may be raised if \n * the call to _connect_ fails:\n * * Errno::EACCES - search permission is denied for a component of the prefix\n *   path or write access to the +socket+ is denided\n * * Errno::EADDRINUSE - the _sockaddr_ is already in use\n * * Errno::EADDRNOTAVAIL - the specified _sockaddr_ is not available from the\n *   local machine\n * * Errno::EAFNOSUPPORT - the specified _sockaddr_ is not a valid address for \n *   the address family of the specified +socket+\n * * Errno::EALREADY - a connection is already in progress for the specified\n *   socket\n * * Errno::EBADF - the +socket+ is not a valid file descriptor\n * * Errno::ECONNREFUSED - the target _sockaddr_ was not listening for connections\n *   refused the connection request\n * * Errno::ECONNRESET - the remote host reset the connection request\n * * Errno::EFAULT - the _sockaddr_ cannot be accessed\n * * Errno::EHOSTUNREACH - the destination host cannot be reached (probably \n *   because the host is down or a remote router cannot reach it)\n * * Errno::EINPROGRESS - the O_NONBLOCK is set for the +socket+ and the\n *   connection cnanot be immediately established; the connection will be\n *   established asynchronously\n * * Errno::EINTR - the attempt to establish the connection was interrupted by\n *   delivery of a signal that was caught; the connection will be established\n *   asynchronously\n * * Errno::EISCONN - the specified +socket+ is already connected\n * * Errno::EINVAL - the address length used for the _sockaddr_ is not a valid\n *   length for the address family or there is an invalid family in _sockaddr_ \n * * Errno::ENAMETOOLONG - the pathname resolved had a length which exceeded\n *   PATH_MAX\n * * Errno::ENETDOWN - the local interface used to reach the destination is down\n * * Errno::ENETUNREACH - no route to the network is present\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOSR - there were insufficient STREAMS resources available to \n *   complete the operation\n * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket\n * * Errno::EOPNOTSUPP - the calling +socket+ is listening and cannot be connected\n * * Errno::EPROTOTYPE - the _sockaddr_ has a different type than the socket \n *   bound to the specified peer address\n * * Errno::ETIMEDOUT - the attempt to connect time out before a connection\n *   was made.\n * \n * On unix-based systems if the address family of the calling +socket+ is\n * AF_UNIX the follow exceptions may be raised if the call to _connect_\n * fails:\n * * Errno::EIO - an i/o error occured while reading from or writing to the \n *   file system\n * * Errno::ELOOP - too many symbolic links were encountered in translating\n *   the pathname in _sockaddr_\n * * Errno::ENAMETOOLLONG - a component of a pathname exceeded NAME_MAX \n *   characters, or an entired pathname exceeded PATH_MAX characters\n * * Errno::ENOENT - a component of the pathname does not name an existing file\n *   or the pathname is an empty string\n * * Errno::ENOTDIR - a component of the path prefix of the pathname in _sockaddr_\n *   is not a directory \n * \n * === Windows Exceptions\n * On Windows systems the following system exceptions may be raised if \n * the call to _connect_ fails:\n * * Errno::ENETDOWN - the network is down\n * * Errno::EADDRINUSE - the socket's local address is already in use\n * * Errno::EINTR - the socket was cancelled\n * * Errno::EINPROGRESS - a blocking socket is in progress or the service provider\n *   is still processing a callback function. Or a nonblocking connect call is \n *   in progress on the +socket+.\n * * Errno::EALREADY - see Errno::EINVAL\n * * Errno::EADDRNOTAVAIL - the remote address is not a valid address, such as \n *   ADDR_ANY TODO check ADDRANY TO INADDR_ANY\n * * Errno::EAFNOSUPPORT - addresses in the specified family cannot be used with\n *   with this +socket+\n * * Errno::ECONNREFUSED - the target _sockaddr_ was not listening for connections\n *   refused the connection request\n * * Errno::EFAULT - the socket's internal address or address length parameter\n *   is too small or is not a valid part of the user space address\n * * Errno::EINVAL - the +socket+ is a listening socket\n * * Errno::EISCONN - the +socket+ is already connected\n * * Errno::ENETUNREACH - the network cannot be reached from this host at this time\n * * Errno::EHOSTUNREACH - no route to the network is present\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket\n * * Errno::ETIMEDOUT - the attempt to connect time out before a connection\n *   was made.\n * * Errno::EWOULDBLOCK - the socket is marked as nonblocking and the \n *   connection cannot be completed immediately\n * * Errno::EACCES - the attempt to connect the datagram socket to the \n *   broadcast address failed\n * \n * === See\n * * connect manual pages on unix-based systems\n * * connect function in Microsoft's Winsock functions reference\n */\nstatic VALUE\nsock_connect(sock, addr)\n    VALUE sock, addr;\n{\n    rb_io_t *fptr;\n    int fd;\n\n    StringValue(addr);\n    addr = rb_str_new4(addr);\n    GetOpenFile(sock, fptr);\n    fd = fileno(fptr->f);\n    if (ruby_connect(fd, (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len, 0) < 0) {\n\trb_sys_fail(\"connect(2)\");\n    }\n\n    return INT2FIX(0);\n}\n\n/*\n * call-seq:\n * \tsocket.connect_nonblock(server_sockaddr) => 0\n * \n * Requests a connection to be made on the given +server_sockaddr+ after\n * O_NONBLOCK is set for the underlying file descriptor.\n * Returns 0 if successful, otherwise an exception is raised.\n *  \n * === Parameter\n * * +server_sockaddr+ - the +struct+ sockaddr contained in a string\n * \n * === Example:\n * \t# Pull down Google's web page\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new(AF_INET, SOCK_STREAM, 0)\n * \tsockaddr = Socket.sockaddr_in(80, 'www.google.com')\n * \tbegin\n * \t  socket.connect_nonblock(sockaddr)\n * \trescue Errno::EINPROGRESS\n * \t  IO.select(nil, [socket])\n * \t  begin\n * \t    socket.connect_nonblock(sockaddr)\n * \t  rescue Errno::EISCONN\n * \t  end\n * \tend\n * \tsocket.write(\"GET / HTTP/1.0\\r\\n\\r\\n\")\n * \tresults = socket.read \n * \n * Refer to Socket#connect for the exceptions that may be thrown if the call\n * to _connect_nonblock_ fails. \n *\n * Socket#connect_nonblock may raise any error corresponding to connect(2) failure,\n * including Errno::EINPROGRESS.\n *\n * === See\n * * Socket#connect\n */\nstatic VALUE\nsock_connect_nonblock(sock, addr)\n    VALUE sock, addr;\n{\n    rb_io_t *fptr;\n    int n;\n\n    StringValue(addr);\n    addr = rb_str_new4(addr);\n    GetOpenFile(sock, fptr);\n    rb_io_set_nonblock(fptr);\n    n = connect(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len);\n    if (n < 0) {\n\trb_sys_fail(\"connect(2)\");\n    }\n\n    return INT2FIX(n);\n}\n\n/*\n * call-seq:\n * \tsocket.bind(server_sockaddr) => 0\n * \n * Binds to the given +struct+ sockaddr.\n * \n * === Parameter\n * * +server_sockaddr+ - the +struct+ sockaddr contained in a string\n *\n * === Example\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.bind( sockaddr )\n *  \n * === Unix-based Exceptions\n * On unix-based based systems the following system exceptions may be raised if \n * the call to _bind_ fails:\n * * Errno::EACCES - the specified _sockaddr_ is protected and the current\n *   user does not have permission to bind to it\n * * Errno::EADDRINUSE - the specified _sockaddr_ is already in use\n * * Errno::EADDRNOTAVAIL - the specified _sockaddr_ is not available from the\n *   local machine\n * * Errno::EAFNOSUPPORT - the specified _sockaddr_ isnot a valid address for\n *   the family of the calling +socket+\n * * Errno::EBADF - the _sockaddr_ specified is not a valid file descriptor\n * * Errno::EFAULT - the _sockaddr_ argument cannot be accessed\n * * Errno::EINVAL - the +socket+ is already bound to an address, and the \n *   protocol does not support binding to the new _sockaddr_ or the +socket+\n *   has been shut down.\n * * Errno::EINVAL - the address length is not a valid length for the address\n *   family\n * * Errno::ENAMETOOLONG - the pathname resolved had a length which exceeded\n *   PATH_MAX\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOSR - there were insufficient STREAMS resources available to \n *   complete the operation\n * * Errno::ENOTSOCK - the +socket+ does not refer to a socket\n * * Errno::EOPNOTSUPP - the socket type of the +socket+ does not support \n *   binding to an address\n * \n * On unix-based based systems if the address family of the calling +socket+ is\n * Socket::AF_UNIX the follow exceptions may be raised if the call to _bind_\n * fails:\n * * Errno::EACCES - search permission is denied for a component of the prefix\n *   path or write access to the +socket+ is denided\n * * Errno::EDESTADDRREQ - the _sockaddr_ argument is a null pointer\n * * Errno::EISDIR - same as Errno::EDESTADDRREQ\n * * Errno::EIO - an i/o error occurred\n * * Errno::ELOOP - too many symbolic links were encountered in translating\n *   the pathname in _sockaddr_\n * * Errno::ENAMETOOLLONG - a component of a pathname exceeded NAME_MAX \n *   characters, or an entired pathname exceeded PATH_MAX characters\n * * Errno::ENOENT - a component of the pathname does not name an existing file\n *   or the pathname is an empty string\n * * Errno::ENOTDIR - a component of the path prefix of the pathname in _sockaddr_\n *   is not a directory\n * * Errno::EROFS - the name would reside on a read only filesystem\n * \n * === Windows Exceptions\n * On Windows systems the following system exceptions may be raised if \n * the call to _bind_ fails:\n * * Errno::ENETDOWN-- the network is down\n * * Errno::EACCES - the attempt to connect the datagram socket to the \n *   broadcast address failed\n * * Errno::EADDRINUSE - the socket's local address is already in use\n * * Errno::EADDRNOTAVAIL - the specified address is not a valid address for this\n *   computer\n * * Errno::EFAULT - the socket's internal address or address length parameter\n *   is too small or is not a valid part of the user space addressed\n * * Errno::EINVAL - the +socket+ is already bound to an address\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket\n * \n * === See\n * * bind manual pages on unix-based systems\n * * bind function in Microsoft's Winsock functions reference\n */ \nstatic VALUE\nsock_bind(sock, addr)\n    VALUE sock, addr;\n{\n    rb_io_t *fptr;\n\n    StringValue(addr);\n    GetOpenFile(sock, fptr);\n    if (bind(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0)\n\trb_sys_fail(\"bind(2)\");\n\n    return INT2FIX(0);\n}\n\n/*\n * call-seq:\n * \tsocket.listen( int ) => 0\n * \n * Listens for connections, using the specified +int+ as the backlog. A call\n * to _listen_ only applies if the +socket+ is of type SOCK_STREAM or \n * SOCK_SEQPACKET.\n * \n * === Parameter\n * * +backlog+ - the maximum length of the queue for pending connections.\n * \n * === Example 1\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.bind( sockaddr )\n * \tsocket.listen( 5 )\n * \n * === Example 2 (listening on an arbitary port, unix-based systems only):\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsocket.listen( 1 )\n * \n * === Unix-based Exceptions\n * On unix based systems the above will work because a new +sockaddr+ struct\n * is created on the address ADDR_ANY, for an arbitrary port number as handed\n * off by the kernel. It will not work on Windows, because Windows requires that\n * the +socket+ is bound by calling _bind_ before it can _listen_.\n * \n * If the _backlog_ amount exceeds the implementation-dependent maximum\n * queue length, the implementation's maximum queue length will be used.\n * \n * On unix-based based systems the following system exceptions may be raised if the\n * call to _listen_ fails:\n * * Errno::EBADF - the _socket_ argument is not a valid file descriptor\n * * Errno::EDESTADDRREQ - the _socket_ is not bound to a local address, and \n *   the protocol does not support listening on an unbound socket\n * * Errno::EINVAL - the _socket_ is already connected\n * * Errno::ENOTSOCK - the _socket_ argument does not refer to a socket\n * * Errno::EOPNOTSUPP - the _socket_ protocol does not support listen\n * * Errno::EACCES - the calling process does not have approriate privileges\n * * Errno::EINVAL - the _socket_ has been shut down\n * * Errno::ENOBUFS - insufficient resources are available in the system to \n *   complete the call\n * \n * === Windows Exceptions\n * On Windows systems the following system exceptions may be raised if \n * the call to _listen_ fails:\n * * Errno::ENETDOWN - the network is down\n * * Errno::EADDRINUSE - the socket's local address is already in use. This \n *   usually occurs during the execution of _bind_ but could be delayed\n *   if the call to _bind_ was to a partially wildcard address (involving\n *   ADDR_ANY) and if a specific address needs to be commmitted at the \n *   time of the call to _listen_\n * * Errno::EINPROGRESS - a Windows Sockets 1.1 call is in progress or the\n *   service provider is still processing a callback function\n * * Errno::EINVAL - the +socket+ has not been bound with a call to _bind_.\n * * Errno::EISCONN - the +socket+ is already connected\n * * Errno::EMFILE - no more socket descriptors are available\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOTSOC - +socket+ is not a socket\n * * Errno::EOPNOTSUPP - the referenced +socket+ is not a type that supports\n *   the _listen_ method\n * \n * === See\n * * listen manual pages on unix-based systems\n * * listen function in Microsoft's Winsock functions reference\n */\nstatic VALUE\nsock_listen(sock, log)\n    VALUE sock, log;\n{\n    rb_io_t *fptr;\n    int backlog;\n\n    rb_secure(4);\n    backlog = NUM2INT(log);\n    GetOpenFile(sock, fptr);\n    if (listen(fileno(fptr->f), backlog) < 0)\n\trb_sys_fail(\"listen(2)\");\n\n    return INT2FIX(0);\n}\n\n/*\n * call-seq:\n * \tsocket.recvfrom(maxlen) => [mesg, sender_sockaddr]\n * \tsocket.recvfrom(maxlen, flags) => [mesg, sender_sockaddr]\n * \n * Receives up to _maxlen_ bytes from +socket+. _flags_ is zero or more\n * of the +MSG_+ options. The first element of the results, _mesg_, is the data\n * received. The second element, _sender_sockaddr_, contains protocol-specific information\n * on the sender.\n * \n * === Parameters\n * * +maxlen+ - the number of bytes to receive from the socket\n * * +flags+ - zero or more of the +MSG_+ options \n * \n * === Example\n * \t# In one file, start this first\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.bind( sockaddr )\n * \tsocket.listen( 5 )\n * \tclient, client_sockaddr = socket.accept\n * \tdata = client.recvfrom( 20 )[0].chomp\n * \tputs \"I only received 20 bytes '#{data}'\"\n * \tsleep 1\n * \tsocket.close\n * \n * \t# In another file, start this second\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.connect( sockaddr )\n * \tsocket.puts \"Watch this get cut short!\"\n * \tsocket.close \n * \n * === Unix-based Exceptions\n * On unix-based based systems the following system exceptions may be raised if the\n * call to _recvfrom_ fails:\n * * Errno::EAGAIN - the +socket+ file descriptor is marked as O_NONBLOCK and no\n *   data is waiting to be received; or MSG_OOB is set and no out-of-band data\n *   is available and either the +socket+ file descriptor is marked as \n *   O_NONBLOCK or the +socket+ does not support blocking to wait for \n *   out-of-band-data\n * * Errno::EWOULDBLOCK - see Errno::EAGAIN\n * * Errno::EBADF - the +socket+ is not a valid file descriptor\n * * Errno::ECONNRESET - a connection was forcibly closed by a peer\n * * Errno::EFAULT - the socket's internal buffer, address or address length \n *   cannot be accessed or written\n * * Errno::EINTR - a signal interupted _recvfrom_ before any data was available\n * * Errno::EINVAL - the MSG_OOB flag is set and no out-of-band data is available\n * * Errno::EIO - an i/o error occurred while reading from or writing to the \n *   filesystem\n * * Errno::ENOBUFS - insufficient resources were available in the system to \n *   perform the operation\n * * Errno::ENOMEM - insufficient memory was available to fulfill the request\n * * Errno::ENOSR - there were insufficient STREAMS resources available to \n *   complete the operation\n * * Errno::ENOTCONN - a receive is attempted on a connection-mode socket that\n *   is not connected\n * * Errno::ENOTSOCK - the +socket+ does not refer to a socket\n * * Errno::EOPNOTSUPP - the specified flags are not supported for this socket type\n * * Errno::ETIMEDOUT - the connection timed out during connection establishment\n *   or due to a transmission timeout on an active connection\n * \n * === Windows Exceptions\n * On Windows systems the following system exceptions may be raised if \n * the call to _recvfrom_ fails:\n * * Errno::ENETDOWN - the network is down\n * * Errno::EFAULT - the internal buffer and from parameters on +socket+ are not\n *   part of the user address space, or the internal fromlen parameter is\n *   too small to accomodate the peer address\n * * Errno::EINTR - the (blocking) call was cancelled by an internal call to\n *   the WinSock function WSACancelBlockingCall\n * * Errno::EINPROGRESS - a blocking Windows Sockets 1.1 call is in progress or \n *   the service provider is still processing a callback function\n * * Errno::EINVAL - +socket+ has not been bound with a call to _bind_, or an\n *   unknown flag was specified, or MSG_OOB was specified for a socket with\n *   SO_OOBINLINE enabled, or (for byte stream-style sockets only) the internal\n *   len parameter on +socket+ was zero or negative\n * * Errno::EISCONN - +socket+ is already connected. The call to _recvfrom_ is\n *   not permitted with a connected socket on a socket that is connetion \n *   oriented or connectionless.\n * * Errno::ENETRESET - the connection has been broken due to the keep-alive \n *   activity detecting a failure while the operation was in progress.\n * * Errno::EOPNOTSUPP - MSG_OOB was specified, but +socket+ is not stream-style\n *   such as type SOCK_STREAM. OOB data is not supported in the communication\n *   domain associated with +socket+, or +socket+ is unidirectional and \n *   supports only send operations\n * * Errno::ESHUTDOWN - +socket+ has been shutdown. It is not possible to \n *   call _recvfrom_ on a socket after _shutdown_ has been invoked.\n * * Errno::EWOULDBLOCK - +socket+ is marked as nonblocking and a  call to \n *   _recvfrom_ would block.\n * * Errno::EMSGSIZE - the message was too large to fit into the specified buffer\n *   and was truncated.\n * * Errno::ETIMEDOUT - the connection has been dropped, because of a network\n *   failure or because the system on the other end went down without\n *   notice\n * * Errno::ECONNRESET - the virtual circuit was reset by the remote side \n *   executing a hard or abortive close. The application should close the\n *   socket; it is no longer usable. On a UDP-datagram socket this error\n *   indicates a previous send operation resulted in an ICMP Port Unreachable\n *   message.\n */\nstatic VALUE\nsock_recvfrom(argc, argv, sock)\n    int argc;\n    VALUE *argv;\n    VALUE sock;\n{\n    return s_recvfrom(sock, argc, argv, RECV_SOCKET);\n}\n\n/*\n * call-seq:\n * \tsocket.recvfrom_nonblock(maxlen) => [mesg, sender_sockaddr]\n * \tsocket.recvfrom_nonblock(maxlen, flags) => [mesg, sender_sockaddr]\n * \n * Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after\n * O_NONBLOCK is set for the underlying file descriptor.\n * _flags_ is zero or more of the +MSG_+ options.\n * The first element of the results, _mesg_, is the data received.\n * The second element, _sender_sockaddr_, contains protocol-specific information\n * on the sender.\n *\n * When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns\n * an empty string as data.\n * The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.\n * \n * === Parameters\n * * +maxlen+ - the number of bytes to receive from the socket\n * * +flags+ - zero or more of the +MSG_+ options \n * \n * === Example\n * \t# In one file, start this first\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new(AF_INET, SOCK_STREAM, 0)\n * \tsockaddr = Socket.sockaddr_in(2200, 'localhost')\n * \tsocket.bind(sockaddr)\n * \tsocket.listen(5)\n * \tclient, client_sockaddr = socket.accept\n * \tbegin\n * \t  pair = client.recvfrom_nonblock(20)\n * \trescue Errno::EAGAIN, Errno::EWOULDBLOCK\n * \t  IO.select([client])\n * \t  retry\n * \tend\n * \tdata = pair[0].chomp\n * \tputs \"I only received 20 bytes '#{data}'\"\n * \tsleep 1\n * \tsocket.close\n * \n * \t# In another file, start this second\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new(AF_INET, SOCK_STREAM, 0)\n * \tsockaddr = Socket.sockaddr_in(2200, 'localhost')\n * \tsocket.connect(sockaddr)\n * \tsocket.puts \"Watch this get cut short!\"\n * \tsocket.close \n * \n * Refer to Socket#recvfrom for the exceptions that may be thrown if the call\n * to _recvfrom_nonblock_ fails. \n *\n * Socket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure,\n * including Errno::EAGAIN.\n *\n * === See\n * * Socket#recvfrom\n */\nstatic VALUE\nsock_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)\n{\n    return s_recvfrom_nonblock(sock, argc, argv, RECV_SOCKET);\n}\n\n/*\n * call-seq:\n * \tsocket.accept => [ socket, string ]\n * \n * Accepts an incoming connection returning an array containing a new\n * Socket object and a string holding the +struct+ sockaddr information about \n * the caller.\n * \n * === Example\n * \t# In one script, start this first\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.bind( sockaddr )\n * \tsocket.listen( 5 )\n * \tclient, client_sockaddr = socket.accept\n * \tputs \"The client said, '#{client.readline.chomp}'\"\n * \tclient.puts \"Hello from script one!\"\n * \tsocket.close\n * \n * \t# In another script, start this second\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.connect( sockaddr )\n * \tsocket.puts \"Hello from script 2.\" \n * \tputs \"The server said, '#{socket.readline.chomp}'\"\n * \tsocket.close \n * \n * === Unix-based Exceptions\n * On unix-based based systems the following system exceptions may be raised if the\n * call to _accept_ fails:\n * * Errno::EAGAIN - O_NONBLOCK is set for the +socket+ file descriptor and no \n *   connections are parent to be accepted\n * * Errno::EWOULDBLOCK - same as Errno::EAGAIN\n * * Errno::EBADF - the +socket+ is not a valid file descriptor\n * * Errno::ECONNABORTED - a connection has been aborted\n * * Errno::EFAULT - the socket's internal address or address length parameter \n *   cannot be access or written\n * * Errno::EINTR - the _accept_ method was interrupted by a signal that was \n *   caught before a valid connection arrived\n * * Errno::EINVAL - the +socket+ is not accepting connections\n * * Errno::EMFILE - OPEN_MAX file descriptors are currently open in the calling \n *   process\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOMEM - there was insufficient memory available to complete the\n *   operation\n * * Errno::ENOSR - there was insufficient STREAMS resources available to \n *   complete the operation\n * * Errno::ENFILE - the maximum number of file descriptors in the system are \n *   already open\n * * Errno::ENOTSOCK - the +socket+ does not refer to a socket\n * * Errno::EOPNOTSUPP - the socket type for the calling +socket+ does not \n *   support accept connections\n * * Errno::EPROTO - a protocol error has occurred\n * \n * === Windows Exceptions\n * On Windows systems the following system exceptions may be raised if \n * the call to _accept_ fails:\n * * Errno::ECONNRESET - an incoming connection was indicated, but was \n *   terminated by the remote peer prior to accepting the connection\n * * Errno::EFAULT - the socket's internal address or address length parameter\n *   is too small or is not a valid part of the user space address\n * * Errno::EINVAL - the _listen_ method was not invoked prior to calling _accept_\n * * Errno::EINPROGRESS - a blocking Windows Sockets 1.1 call is in progress or\n *   the service provider is still processing a callback function\n * * Errno::EMFILE - the queue is not empty, upong etry to _accept_ and there are\n *   no socket descriptors available\n * * Errno::ENETDOWN - the network is down\n * * Errno::ENOBUFS - no buffer space is available\n * * Errno::ENOTSOCK - +socket+ is not a socket\n * * Errno::EOPNOTSUPP - +socket+ is not a type that supports connection-oriented\n *   service.\n * * Errno::EWOULDBLOCK - +socket+ is marked as nonblocking and no connections are\n *   present to be accepted\n * \n * === See\n * * accept manual pages on unix-based systems\n * * accept function in Microsoft's Winsock functions reference\n */\nstatic VALUE\nsock_accept(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    VALUE sock2;\n    char buf[1024];\n    socklen_t len = sizeof buf;\n\n    GetOpenFile(sock, fptr);\n    sock2 = s_accept(rb_cSocket,fileno(fptr->f),(struct sockaddr*)buf,&len);\n\n    return rb_assoc_new(sock2, rb_str_new(buf, len));\n}\n\n/*\n * call-seq:\n *    socket.accept_nonblock => [client_socket, client_sockaddr]\n * \n * Accepts an incoming connection using accept(2) after\n * O_NONBLOCK is set for the underlying file descriptor.\n * It returns an array containg the accpeted socket\n * for the incoming connection, _client_socket_,\n * and a string that contains the +struct+ sockaddr information\n * about the caller, _client_sockaddr_.\n * \n * === Example\n * \t# In one script, start this first\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new(AF_INET, SOCK_STREAM, 0)\n * \tsockaddr = Socket.sockaddr_in(2200, 'localhost')\n * \tsocket.bind(sockaddr)\n * \tsocket.listen(5)\n * \tbegin\n * \t  client_socket, client_sockaddr = socket.accept_nonblock\n * \trescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR\n * \t  IO.select([socket])\n * \t  retry\n * \tend\n * \tputs \"The client said, '#{client_socket.readline.chomp}'\"\n * \tclient_socket.puts \"Hello from script one!\"\n * \tsocket.close\n *\n * \t# In another script, start this second\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new(AF_INET, SOCK_STREAM, 0)\n * \tsockaddr = Socket.sockaddr_in(2200, 'localhost')\n * \tsocket.connect(sockaddr)\n * \tsocket.puts \"Hello from script 2.\" \n * \tputs \"The server said, '#{socket.readline.chomp}'\"\n * \tsocket.close\n * \n * Refer to Socket#accept for the exceptions that may be thrown if the call\n * to _accept_nonblock_ fails. \n *\n * Socket#accept_nonblock may raise any error corresponding to accept(2) failure,\n * including Errno::EAGAIN.\n * \n * === See\n * * Socket#accept\n */\nstatic VALUE\nsock_accept_nonblock(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    VALUE sock2;\n    char buf[1024];\n    socklen_t len = sizeof buf;\n\n    GetOpenFile(sock, fptr);\n    sock2 = s_accept_nonblock(rb_cSocket, fptr, (struct sockaddr *)buf, &len);\n    return rb_assoc_new(sock2, rb_str_new(buf, len));\n}\n\n/*\n * call-seq:\n * \tsocket.sysaccept => [client_socket_fd, client_sockaddr]\n * \n * Accepts an incoming connection returnings an array containg the (integer)\n * file descriptor for the incoming connection, _client_socket_fd_,\n * and a string that contains the +struct+ sockaddr information\n * about the caller, _client_sockaddr_.\n * \n * === Example\n * \t# In one script, start this first\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.bind( sockaddr )\n * \tsocket.listen( 5 )\n * \tclient_fd, client_sockaddr = socket.sysaccept\n * \tclient_socket = Socket.for_fd( client_fd )\n * \tputs \"The client said, '#{client_socket.readline.chomp}'\"\n * \tclient_socket.puts \"Hello from script one!\"\n * \tsocket.close\n * \n * \t# In another script, start this second\n * \trequire 'socket'\n * \tinclude Socket::Constants\n * \tsocket = Socket.new( AF_INET, SOCK_STREAM, 0 )\n * \tsockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )\n * \tsocket.connect( sockaddr )\n * \tsocket.puts \"Hello from script 2.\" \n * \tputs \"The server said, '#{socket.readline.chomp}'\"\n * \tsocket.close\n * \n * Refer to Socket#accept for the exceptions that may be thrown if the call\n * to _sysaccept_ fails. \n * \n * === See\n * * Socket#accept\n */\nstatic VALUE\nsock_sysaccept(sock)\n    VALUE sock;\n{\n    rb_io_t *fptr;\n    VALUE sock2;\n    char buf[1024];\n    socklen_t len = sizeof buf;\n\n    GetOpenFile(sock, fptr);\n    sock2 = s_accept(0,fileno(fptr->f),(struct sockaddr*)buf,&len);\n\n    return rb_assoc_new(sock2, rb_str_new(buf, len));\n}\n\n#ifdef HAVE_GETHOSTNAME\nstatic VALUE\nsock_gethostname(obj)\n    VALUE obj;\n{\n    char buf[1024];\n\n    rb_secure(3);\n    if (gethostname(buf, (int)sizeof buf - 1) < 0)\n\trb_sys_fail(\"gethostname\");\n\n    buf[sizeof buf - 1] = '\\0';\n    return rb_str_new2(buf);\n}\n#else\n#ifdef HAVE_UNAME\n\n#include <sys/utsname.h>\n\nstatic VALUE\nsock_gethostname(obj)\n    VALUE obj;\n{\n    struct utsname un;\n\n    rb_secure(3);\n    uname(&un);\n    return rb_str_new2(un.nodename);\n}\n#else\nstatic VALUE\nsock_gethostname(obj)\n    VALUE obj;\n{\n    rb_notimplement();\n}\n#endif\n#endif\n\nstatic VALUE\nmake_addrinfo(res0)\n    struct addrinfo *res0;\n{\n    VALUE base, ary;\n    struct addrinfo *res;\n\n    if (res0 == NULL) {\n\trb_raise(rb_eSocket, \"host not found\");\n    }\n    base = rb_ary_new();\n    for (res = res0; res; res = res->ai_next) {\n\tary = ipaddr(res->ai_addr);\n\trb_ary_push(ary, INT2FIX(res->ai_family));\n\trb_ary_push(ary, INT2FIX(res->ai_socktype));\n\trb_ary_push(ary, INT2FIX(res->ai_protocol));\n\trb_ary_push(base, ary);\n    }\n    return base;\n}\n\n/* Returns a String containing the binary value of a struct sockaddr. */\nVALUE\nsock_sockaddr(addr, len)\n    struct sockaddr *addr;\n    size_t len;\n{\n    char *ptr;\n\n    switch (addr->sa_family) {\n      case AF_INET:\n\tptr = (char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr;\n\tlen = sizeof(((struct sockaddr_in*)addr)->sin_addr.s_addr);\n\tbreak;\n#ifdef INET6\n      case AF_INET6:\n\tptr = (char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr;\n\tlen = sizeof(((struct sockaddr_in6*)addr)->sin6_addr.s6_addr);\n\tbreak;\n#endif\n      default:\n        rb_raise(rb_eSocket, \"unknown socket family:%d\", addr->sa_family);\n\tbreak;\n    }\n    return rb_str_new(ptr, len);\n}\n\n/*\n * Document-class: IPSocket\n *\n * IPSocket is the parent of TCPSocket and UDPSocket and implements\n * functionality common to them.\n *\n * A number of APIs in IPSocket, Socket, and their descendants return an\n * address as an array. The members of that array are:\n * - address family: A string like \"AF_INET\" or \"AF_INET6\" if it is one of the\n *   commonly used families, the string \"unknown:#\" (where `#' is the address\n *   family number) if it is not one of the common ones.  The strings map to\n *   the Socket::AF_* constants.\n * - port: The port number.\n * - name: Either the canonical name from looking the address up in the DNS, or\n *   the address in presentation format\n * - address: The address in presentation format (a dotted decimal string for\n *   IPv4, a hex string for IPv6).\n *\n * The address and port can be used directly to create sockets and to bind or\n * connect them to the address.\n */\n\n/*\n * Document-class: Socket\n *\n * Socket contains a number of generally useful singleton methods and\n * constants, as well as offering low-level interfaces that can be used to\n * develop socket applications using protocols other than TCP, UDP, and UNIX\n * domain sockets.\n */\n\n/*\n * Document-method: gethostbyname\n * call-seq: Socket.gethostbyname(host) => hostent\n *\n * Resolve +host+ and return name and address information for it, similarly to\n * gethostbyname(3). +host+ can be a domain name or the presentation format of\n * an address.\n *\n * Returns an array of information similar to that found in a +struct hostent+:\n *   - cannonical name: the cannonical name for host in the DNS, or a\n *     string representing the address\n *   - aliases: an array of aliases for the canonical name, there may be no aliases\n *   - address family: usually one of Socket::AF_INET or Socket::AF_INET6\n *   - address: a string, the binary value of the +struct sockaddr+ for this name, in\n *     the indicated address family\n *   - ...: if there are multiple addresses for this host,  a series of\n *     strings/+struct sockaddr+s may follow, not all necessarily in the same\n *     address family. Note that the fact that they may not be all in the same\n *     address family is a departure from the behaviour of gethostbyname(3).\n *\n * Note: I believe that the fact that the multiple addresses returned are not\n * necessarily in the same address family may be a bug, since if this function\n * actually called gethostbyname(3), ALL the addresses returned in the trailing\n * address list (h_addr_list from struct hostent) would be of the same address\n * family!  Examples from my system, OS X 10.3:\n *\n *   [\"localhost\", [], 30, \"\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\001\", \"\\177\\000\\000\\001\"]\n *     and\n *   [\"ensemble.local\", [], 30, \"\\376\\200\\000\\004\\000\\000\\000\\000\\002\\003\\223\\377\\376\\255\\010\\214\", \"\\300\\250{\\232\" ]\n *\n * Similar information can be returned by Socket.getaddrinfo if called as:\n *\n *    Socket.getaddrinfo(+host+, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)\n *\n * == Examples\n *   \n *   Socket.gethostbyname \"example.com\"                                                           \n *   => [\"example.com\", [], 2, \"\\300\\000\\\"\\246\"]\n *   \n * This name has no DNS aliases, and a single IPv4 address.\n *   \n *   Socket.gethostbyname \"smtp.telus.net\"\n *   => [\"smtp.svc.telus.net\", [\"smtp.telus.net\"], 2, \"\\307\\271\\334\\371\"]\n *   \n * This name is an an alias so the canonical name is returned, as well as the\n * alias and a single IPv4 address.\n *   \n *   Socket.gethostbyname \"localhost\"\n *   => [\"localhost\", [], 30, \"\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\001\", \"\\177\\000\\000\\001\"]\n *   \n * This machine has no aliases, returns an IPv6 address, and has an additional IPv4 address.\n *\n * +host+ can also be an IP address in presentation format, in which case a\n * reverse lookup is done on the address:\n *\n *   Socket.gethostbyname(\"127.0.0.1\")\n *   => [\"localhost\", [], 2, \"\\177\\000\\000\\001\"]\n *\n *   Socket.gethostbyname(\"192.0.34.166\")\n *   => [\"www.example.com\", [], 2, \"\\300\\000\\\"\\246\"]\n *\n *\n * == See\n * See: Socket.getaddrinfo\n */\nstatic VALUE\nsock_s_gethostbyname(obj, host)\n    VALUE obj, host;\n{\n    rb_secure(3);\n    return make_hostent(host, sock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr);\n}\n\nstatic VALUE\nsock_s_gethostbyaddr(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE addr, type;\n    struct hostent *h;\n    struct sockaddr *sa;\n    char **pch;\n    VALUE ary, names;\n    int t = AF_INET;\n\n    rb_scan_args(argc, argv, \"11\", &addr, &type);\n    sa = (struct sockaddr*)StringValuePtr(addr);\n    if (!NIL_P(type)) {\n\tt = NUM2INT(type);\n    }\n#ifdef INET6\n    else if (RSTRING(addr)->len == 16) {\n\tt = AF_INET6;\n    }\n#endif\n    h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, t);\n    if (h == NULL) {\n#ifdef HAVE_HSTRERROR\n\textern int h_errno;\n\trb_raise(rb_eSocket, \"%s\", (char*)hstrerror(h_errno));\n#else\n\trb_raise(rb_eSocket, \"host not found\");\n#endif\n    }\n    ary = rb_ary_new();\n    rb_ary_push(ary, rb_str_new2(h->h_name));\n    names = rb_ary_new();\n    rb_ary_push(ary, names);\n    if (h->h_aliases != NULL) {\n\tfor (pch = h->h_aliases; *pch; pch++) {\n\t    rb_ary_push(names, rb_str_new2(*pch));\n\t}\n    }\n    rb_ary_push(ary, INT2NUM(h->h_addrtype));\n#ifdef h_addr\n    for (pch = h->h_addr_list; *pch; pch++) {\n\trb_ary_push(ary, rb_str_new(*pch, h->h_length));\n    }\n#else\n    rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length));\n#endif\n\n    return ary;\n}\n\n/*\n * Document-method: getservbyname\n * call-seq: Socket.getservbyname(name, proto=\"tcp\") => port\n *\n * +name+ is a service name (\"ftp\", \"telnet\", ...) and proto is a protocol name\n * (\"udp\", \"tcp\", ...). '/etc/services' (or your system's equivalent) is\n * searched for a service for +name+ and +proto+, and the port number is\n * returned.\n *\n * Note that unlike Socket.getaddrinfo, +proto+ may not be specified using the\n * Socket::SOCK_* constants, a string must must be used.\n */\nstatic VALUE\nsock_s_getservbyaname(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE service, proto;\n    struct servent *sp;\n    int port;\n\n    rb_scan_args(argc, argv, \"11\", &service, &proto);\n    if (NIL_P(proto)) proto = rb_str_new2(\"tcp\");\n    StringValue(service);\n    StringValue(proto);\n\n    sp = getservbyname(StringValueCStr(service),  StringValueCStr(proto));\n    if (sp) {\n\tport = ntohs(sp->s_port);\n    }\n    else {\n\tchar *s = RSTRING(service)->ptr;\n\tchar *end;\n\n\tport = strtoul(s, &end, 0);\n\tif (*end != '\\0') {\n\t    rb_raise(rb_eSocket, \"no such service %s/%s\", s, RSTRING(proto)->ptr);\n\t}\n    }\n    return INT2FIX(port);\n}\n\n/*\nDocumentation should explain the following:\n\n  $ pp Socket.getaddrinfo(\"\", 1, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)\n  [[\"AF_INET\", 1, \"0.0.0.0\", \"0.0.0.0\", 2, 1, 6]]\n\n  $ pp Socket.getaddrinfo(nil, 1, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)\n  [[\"AF_INET6\", 1, \"::\", \"::\", 30, 1, 6],\n   [\"AF_INET\", 1, \"0.0.0.0\", \"0.0.0.0\", 2, 1, 6]]\n\n  $ pp Socket.getaddrinfo(\"localhost\", 1, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)\n  [[\"AF_INET6\", 1, \"localhost\", \"::1\", 30, 1, 6],\n   [\"AF_INET\", 1, \"localhost\", \"127.0.0.1\", 2, 1, 6]]\n\n  $ pp Socket.getaddrinfo(\"ensemble.local.\", 1, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)\n  [[\"AF_INET\", 1, \"localhost\", \"192.168.123.154\", 2, 1, 6]]\n\nDoes it?\n\nAPI suggestion: this method has too many arguments, it would be backwards compatible and easier\nto understand if limit args were accepted as :family=>..., :flags=>...\n*/\n\n/*\n * Document-method: getaddrinfo\n * call-seq: Socket.getaddrinfo(host, service, family=nil, socktype=nil, protocol=nil, flags=nil) => addrinfo\n *\n * Return address information for +host+ and +port+. The remaining arguments\n * are hints that limit the address information returned.\n *\n * This method corresponds closely to the POSIX.1g getaddrinfo() definition.\n *\n * === Parameters\n * - +host+ is a host name or an address string (dotted decimal for IPv4, or a hex string\n *   for IPv6) for which to return information. A nil is also allowed, its meaning\n *   depends on +flags+, see below.\n * - +service+ is a service name (\"http\", \"ssh\", ...), or \n *   a port number (80, 22, ...), see Socket.getservbyname for more\n *   information. A nil is also allowed, meaning zero.\n * - +family+ limits the output to a specific address family, one of the\n *   Socket::AF_* constants. Socket::AF_INET (IPv4) and Socket::AF_INET6 (IPv6)\n *   are the most commonly used families. You will usually pass either nil or\n *   Socket::AF_UNSPEC, allowing the IPv6 information to be returned first if\n *   +host+ is reachable via IPv6, and IPv4 information otherwise.  The two\n *   strings \"AF_INET\" or \"AF_INET6\" are also allowed, they are converted to\n *   their respective Socket::AF_* constants.\n * - +socktype+ limits the output to a specific type of socket, one of the\n *   Socket::SOCK_* constants. Socket::SOCK_STREAM (for TCP) and\n *   Socket::SOCK_DGRAM (for UDP) are the most commonly used socket types. If\n *   nil, then information for all types of sockets supported by +service+ will\n *   be returned. You will usually know what type of socket you intend to\n *   create, and should pass that socket type in.\n * - +protocol+ limits the output to a specific protocol numpber, one of the\n *   Socket::IPPROTO_* constants. It is usually implied by the socket type\n *   (Socket::SOCK_STREAM => Socket::IPPROTO_TCP, ...), if you pass other than\n *   nil you already know what this is for.\n * - +flags+ is one of the Socket::AI_* constants. They mean:\n *   - Socket::AI_PASSIVE: when set, if +host+ is nil the 'any' address will be\n *     returned, Socket::INADDR_ANY or 0 for IPv4, \"0::0\" or \"::\" for IPv6.  This\n *     address is suitable for use by servers that will bind their socket and do\n *     a passive listen, thus the name of the flag. Otherwise the local or\n *     loopback address will be returned, this is \"127.0.0.1\" for IPv4 and \"::1'\n *     for IPv6.\n *   - ...\n *\n *\n * === Returns\n *\n * Returns an array of arrays, where each subarray contains:\n * - address family, a string like \"AF_INET\" or \"AF_INET6\"\n * - port number, the port number for +service+\n * - host name, either a canonical name for +host+, or it's address in presentation\n *   format if the address could not be looked up.\n * - host IP, the address of +host+ in presentation format\n * - address family, as a numeric value (one of the Socket::AF_* constants).\n * - socket type, as a numeric value (one of the Socket::SOCK_* constants).\n * - protocol number, as a numeric value (one of the Socket::IPPROTO_* constants).\n *\n * The first four values are identical to what is commonly returned as an\n * address array, see IPSocket for more information.\n *\n * === Examples\n *\n * Not all input combinations are valid, and while there are many combinations,\n * only a few cases are common.\n *\n * A typical client will call getaddrinfo with the +host+ and +service+ it\n * wants to connect to. It knows that it will attempt to connect with either\n * TCP or UDP, and specifies +socktype+ accordingly. It loops through all\n * returned addresses, and try to connect to them in turn:\n *\n *   addrinfo = Socket::getaddrinfo('www.example.com', 'www', nil, Socket::SOCK_STREAM)\n *   addrinfo.each do |af, port, name, addr|\n *     begin\n *       sock = TCPSocket.new(addr, port)\n *       # ...\n *       exit 1\n *     rescue\n *     end\n *   end\n *\n * With UDP you don't know if connect suceeded, but if communication fails,\n * the next address can be tried.\n *\n * A typical server will call getaddrinfo with a +host+ of nil, the +service+\n * it listens to, and a +flags+ of Socket::AI_PASSIVE. It will listen for\n * connections on the first returned address:\n *   addrinfo = Socket::getaddrinfo(nil, 'www', nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE)\n *   af, port, name, addr = addrinfo.first\n *   sock = TCPServer(addr, port)\n *   while( client = s.accept )\n *     # ...\n *   end\n */\nstatic VALUE\nsock_s_getaddrinfo(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE host, port, family, socktype, protocol, flags, ret;\n    char hbuf[1024], pbuf[1024];\n    char *hptr, *pptr, *ap;\n    struct addrinfo hints, *res;\n    int error;\n\n    host = port = family = socktype = protocol = flags = Qnil;\n    rb_scan_args(argc, argv, \"24\", &host, &port, &family, &socktype, &protocol, &flags);\n    if (NIL_P(host)) {\n\thptr = NULL;\n    }\n    else {\n\tstrncpy(hbuf, StringValuePtr(host), sizeof(hbuf));\n\thbuf[sizeof(hbuf) - 1] = '\\0';\n\thptr = hbuf;\n    }\n    if (NIL_P(port)) {\n\tpptr = NULL;\n    }\n    else if (FIXNUM_P(port)) {\n\tsnprintf(pbuf, sizeof(pbuf), \"%ld\", FIX2LONG(port));\n\tpptr = pbuf;\n    }\n    else {\n\tstrncpy(pbuf, StringValuePtr(port), sizeof(pbuf));\n\tpbuf[sizeof(pbuf) - 1] = '\\0';\n\tpptr = pbuf;\n    }\n\n    MEMZERO(&hints, struct addrinfo, 1);\n    if (NIL_P(family)) {\n\thints.ai_family = PF_UNSPEC;\n    }\n    else if (FIXNUM_P(family)) {\n\thints.ai_family = FIX2INT(family);\n    }\n    else if ((ap = StringValuePtr(family)) != 0) {\n\tif (strcmp(ap, \"AF_INET\") == 0) {\n\t    hints.ai_family = PF_INET;\n\t}\n#ifdef INET6\n\telse if (strcmp(ap, \"AF_INET6\") == 0) {\n\t    hints.ai_family = PF_INET6;\n\t}\n#endif\n    }\n\n    if (!NIL_P(socktype)) {\n\thints.ai_socktype = NUM2INT(socktype);\n    }\n    if (!NIL_P(protocol)) {\n\thints.ai_protocol = NUM2INT(protocol);\n    }\n    if (!NIL_P(flags)) {\n\thints.ai_flags = NUM2INT(flags);\n    }\n    error = getaddrinfo(hptr, pptr, &hints, &res);\n    if (error) {\n\trb_raise(rb_eSocket, \"getaddrinfo: %s\", gai_strerror(error));\n    }\n\n    ret = make_addrinfo(res);\n    freeaddrinfo(res);\n    return ret;\n}\n\nstatic VALUE\nsock_s_getnameinfo(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags, tmp;\n    char *hptr, *pptr;\n    char hbuf[1024], pbuf[1024];\n    int fl;\n    struct addrinfo hints, *res = NULL, *r;\n    int error;\n    struct sockaddr_storage ss;\n    struct sockaddr *sap;\n    char *ap;\n\n    sa = flags = Qnil;\n    rb_scan_args(argc, argv, \"11\", &sa, &flags);\n\n    fl = 0;\n    if (!NIL_P(flags)) {\n\tfl = NUM2INT(flags);\n    }\n    tmp = rb_check_string_type(sa);\n    if (!NIL_P(tmp)) {\n\tsa = tmp;\n\tif (sizeof(ss) < RSTRING(sa)->len) {\n\t    rb_raise(rb_eTypeError, \"sockaddr length too big\");\n\t}\n\tmemcpy(&ss, RSTRING(sa)->ptr, RSTRING(sa)->len);\n\tif (RSTRING(sa)->len != SA_LEN((struct sockaddr*)&ss)) {\n\t    rb_raise(rb_eTypeError, \"sockaddr size differs - should not happen\");\n\t}\n\tsap = (struct sockaddr*)&ss;\n\tgoto call_nameinfo;\n    }\n    tmp = rb_check_array_type(sa);\n    if (!NIL_P(tmp)) {\n\tsa = tmp;\n\tMEMZERO(&hints, struct addrinfo, 1);\n\tif (RARRAY(sa)->len == 3) {\n\t    af = RARRAY(sa)->ptr[0];\n\t    port = RARRAY(sa)->ptr[1];\n\t    host = RARRAY(sa)->ptr[2];\n\t}\n\telse if (RARRAY(sa)->len >= 4) {\n\t    af = RARRAY(sa)->ptr[0];\n\t    port = RARRAY(sa)->ptr[1];\n\t    host = RARRAY(sa)->ptr[3];\n\t    if (NIL_P(host)) {\n\t\thost = RARRAY(sa)->ptr[2];\n\t    }\n\t    else {\n\t\t/*\n\t\t * 4th element holds numeric form, don't resolve.\n\t\t * see ipaddr().\n\t\t */\n#ifdef AI_NUMERICHOST /* AIX 4.3.3 doesn't have AI_NUMERICHOST. */\n\t\thints.ai_flags |= AI_NUMERICHOST;\n#endif\n\t    }\n\t}\n\telse {\n\t    rb_raise(rb_eArgError, \"array size should be 3 or 4, %ld given\",\n\t\t     RARRAY(sa)->len);\n\t}\n\t/* host */\n\tif (NIL_P(host)) {\n\t    hptr = NULL;\n\t}\n\telse {\n\t    strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));\n\t    hbuf[sizeof(hbuf) - 1] = '\\0';\n\t    hptr = hbuf;\n\t}\n\t/* port */\n\tif (NIL_P(port)) {\n\t    strcpy(pbuf, \"0\");\n\t    pptr = NULL;\n\t}\n\telse if (FIXNUM_P(port)) {\n\t    snprintf(pbuf, sizeof(pbuf), \"%ld\", NUM2LONG(port));\n\t    pptr = pbuf;\n\t}\n\telse {\n\t    strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));\n\t    pbuf[sizeof(pbuf) - 1] = '\\0';\n\t    pptr = pbuf;\n\t}\n\thints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;\n\t/* af */\n\tif (NIL_P(af)) {\n\t    hints.ai_family = PF_UNSPEC;\n\t}\n\telse if (FIXNUM_P(af)) {\n\t    hints.ai_family = FIX2INT(af);\n\t}\n\telse if ((ap = StringValuePtr(af)) != 0) {\n\t    if (strcmp(ap, \"AF_INET\") == 0) {\n\t\thints.ai_family = PF_INET;\n\t    }\n#ifdef INET6\n\t    else if (strcmp(ap, \"AF_INET6\") == 0) {\n\t\thints.ai_family = PF_INET6;\n\t    }\n#endif\n\t}\n\terror = getaddrinfo(hptr, pptr, &hints, &res);\n\tif (error) goto error_exit_addr;\n\tsap = res->ai_addr;\n    }\n    else {\n\trb_raise(rb_eTypeError, \"expecting String or Array\");\n    }\n\n  call_nameinfo:\n    error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),\n\t\t\tpbuf, sizeof(pbuf), fl);\n    if (error) goto error_exit_name;\n    if (res) {\n\tfor (r = res->ai_next; r; r = r->ai_next) {\n\t    char hbuf2[1024], pbuf2[1024];\n\n\t    sap = r->ai_addr;\n\t    error = getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2),\n\t\t\t\tpbuf2, sizeof(pbuf2), fl);\n\t    if (error) goto error_exit_name;\n\t    if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {\n\t\tfreeaddrinfo(res);\n\t\trb_raise(rb_eSocket, \"sockaddr resolved to multiple nodename\");\n\t    }\n\t}\n\tfreeaddrinfo(res);\n    }\n    return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));\n\n  error_exit_addr:\n    if (res) freeaddrinfo(res);\n    rb_raise(rb_eSocket, \"getaddrinfo: %s\", gai_strerror(error));\n\n  error_exit_name:\n    if (res) freeaddrinfo(res);\n    rb_raise(rb_eSocket, \"getnameinfo: %s\", gai_strerror(error));\n}\n\nstatic VALUE\nsock_s_pack_sockaddr_in(self, port, host)\n    VALUE self, port, host;\n{\n    struct addrinfo *res = sock_addrinfo(host, port, 0, 0);\n    VALUE addr = rb_str_new((char*)res->ai_addr, res->ai_addrlen);\n\n    freeaddrinfo(res);\n    OBJ_INFECT(addr, port);\n    OBJ_INFECT(addr, host);\n\n    return addr;\n}\n\nstatic VALUE\nsock_s_unpack_sockaddr_in(self, addr)\n    VALUE self, addr;\n{\n    struct sockaddr_in * sockaddr;\n    VALUE host;\n\n    sockaddr = (struct sockaddr_in*)StringValuePtr(addr);\n    if (((struct sockaddr *)sockaddr)->sa_family != AF_INET\n#ifdef INET6\n        && ((struct sockaddr *)sockaddr)->sa_family != AF_INET6\n#endif\n        ) {\n#ifdef INET6\n        rb_raise(rb_eArgError, \"not an AF_INET/AF_INET6 sockaddr\");\n#else\n        rb_raise(rb_eArgError, \"not an AF_INET sockaddr\");\n#endif\n    }\n    host = make_ipaddr((struct sockaddr*)sockaddr);\n    OBJ_INFECT(host, addr);\n    return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);\n}\n\n#ifdef HAVE_SYS_UN_H\nstatic VALUE\nsock_s_pack_sockaddr_un(self, path)\n    VALUE self, path;\n{\n    struct sockaddr_un sockaddr;\n    char *sun_path;\n    VALUE addr;\n\n    MEMZERO(&sockaddr, struct sockaddr_un, 1);\n    sockaddr.sun_family = AF_UNIX;\n    sun_path = StringValueCStr(path);\n    if (sizeof(sockaddr.sun_path) <= strlen(sun_path)) {\n        rb_raise(rb_eArgError, \"too long unix socket path (max: %dbytes)\",\n            (int)sizeof(sockaddr.sun_path)-1);\n    }\n    strncpy(sockaddr.sun_path, sun_path, sizeof(sockaddr.sun_path)-1);\n    addr = rb_str_new((char*)&sockaddr, sizeof(sockaddr));\n    OBJ_INFECT(addr, path);\n\n    return addr;\n}\n\nstatic VALUE\nsock_s_unpack_sockaddr_un(self, addr)\n    VALUE self, addr;\n{\n    struct sockaddr_un * sockaddr;\n    char *sun_path;\n    VALUE path;\n\n    sockaddr = (struct sockaddr_un*)StringValuePtr(addr);\n    if (((struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {\n        rb_raise(rb_eArgError, \"not an AF_UNIX sockaddr\");\n    }\n    if (sizeof(struct sockaddr_un) < RSTRING(addr)->len) {\n        rb_raise(rb_eTypeError, \"too long sockaddr_un - %ld longer than %d\",\n\t\t RSTRING(addr)->len, sizeof(struct sockaddr_un));\n    }\n    sun_path = unixpath(sockaddr, RSTRING(addr)->len);\n    if (sizeof(struct sockaddr_un) == RSTRING(addr)->len &&\n        sun_path == sockaddr->sun_path &&\n        sun_path + strlen(sun_path) == RSTRING(addr)->ptr + RSTRING(addr)->len) {\n        rb_raise(rb_eArgError, \"sockaddr_un.sun_path not NUL terminated\");\n    }\n    path = rb_str_new2(sun_path);\n    OBJ_INFECT(path, addr);\n    return path;\n}\n#endif\n\nstatic VALUE mConst;\n\nstatic void\nsock_define_const(name, value)\n    char *name;\n    int value;\n{\n    rb_define_const(rb_cSocket, name, INT2FIX(value));\n    rb_define_const(mConst, name, INT2FIX(value));\n}\n\n/*\n * Class +Socket+ provides access to the underlying operating system\n * socket implementations. It can be used to provide more operating system\n * specific functionality than the protocol-specific socket classes but at the\n * expense of greater complexity. In particular, the class handles addresses\n * using +struct sockaddr+ structures packed into Ruby strings, which can be\n * a joy to manipulate.\n * \n * === Exception Handling\n * Ruby's implementation of +Socket+ causes an exception to be raised\n * based on the error generated by the system dependent implementation.\n * This is why the methods are documented in a way that isolate\n * Unix-based system exceptions from Windows based exceptions. If more\n * information on particular exception is needed please refer to the \n * Unix manual pages or the Windows WinSock reference.\n * \n * \n * === Documentation by\n * * Zach Dennis\n * * Sam Roberts\n * * <em>Programming Ruby</em> from The Pragmatic Bookshelf.  \n * \n * Much material in this documentation is taken with permission from  \n * <em>Programming Ruby</em> from The Pragmatic Bookshelf.  \n */\nvoid\nInit_socket()\n{\n    rb_eSocket = rb_define_class(\"SocketError\", rb_eStandardError);\n\n    rb_cBasicSocket = rb_define_class(\"BasicSocket\", rb_cIO);\n    rb_undef_method(rb_cBasicSocket, \"initialize\");\n\n    rb_define_singleton_method(rb_cBasicSocket, \"do_not_reverse_lookup\",\n\t\t\t       bsock_do_not_rev_lookup, 0);\n    rb_define_singleton_method(rb_cBasicSocket, \"do_not_reverse_lookup=\",\n\t\t\t       bsock_do_not_rev_lookup_set, 1);\n    rb_define_singleton_method(rb_cBasicSocket, \"for_fd\", bsock_s_for_fd, 1);\n\n    rb_define_method(rb_cBasicSocket, \"close_read\", bsock_close_read, 0);\n    rb_define_method(rb_cBasicSocket, \"close_write\", bsock_close_write, 0);\n    rb_define_method(rb_cBasicSocket, \"shutdown\", bsock_shutdown, -1);\n    rb_define_method(rb_cBasicSocket, \"setsockopt\", bsock_setsockopt, 3);\n    rb_define_method(rb_cBasicSocket, \"getsockopt\", bsock_getsockopt, 2);\n    rb_define_method(rb_cBasicSocket, \"getsockname\", bsock_getsockname, 0);\n    rb_define_method(rb_cBasicSocket, \"getpeername\", bsock_getpeername, 0);\n    rb_define_method(rb_cBasicSocket, \"send\", bsock_send, -1);\n    rb_define_method(rb_cBasicSocket, \"recv\", bsock_recv, -1);\n    rb_define_method(rb_cBasicSocket, \"recv_nonblock\", bsock_recv_nonblock, -1);\n\n    rb_cIPSocket = rb_define_class(\"IPSocket\", rb_cBasicSocket);\n    rb_define_global_const(\"IPsocket\", rb_cIPSocket);\n    rb_define_method(rb_cIPSocket, \"addr\", ip_addr, 0);\n    rb_define_method(rb_cIPSocket, \"peeraddr\", ip_peeraddr, 0);\n    rb_define_method(rb_cIPSocket, \"recvfrom\", ip_recvfrom, -1);\n    rb_define_singleton_method(rb_cIPSocket, \"getaddress\", ip_s_getaddress, 1);\n\n    rb_cTCPSocket = rb_define_class(\"TCPSocket\", rb_cIPSocket);\n    rb_define_global_const(\"TCPsocket\", rb_cTCPSocket);\n    rb_define_singleton_method(rb_cTCPSocket, \"gethostbyname\", tcp_s_gethostbyname, 1);\n    rb_define_method(rb_cTCPSocket, \"initialize\", tcp_init, -1);\n\n#ifdef SOCKS\n    rb_cSOCKSSocket = rb_define_class(\"SOCKSSocket\", rb_cTCPSocket);\n    rb_define_global_const(\"SOCKSsocket\", rb_cSOCKSSocket);\n    rb_define_method(rb_cSOCKSSocket, \"initialize\", socks_init, 2);\n#ifdef SOCKS5\n    rb_define_method(rb_cSOCKSSocket, \"close\", socks_s_close, 0);\n#endif\n#endif\n\n    rb_cTCPServer = rb_define_class(\"TCPServer\", rb_cTCPSocket);\n    rb_define_global_const(\"TCPserver\", rb_cTCPServer);\n    rb_define_method(rb_cTCPServer, \"accept\", tcp_accept, 0);\n    rb_define_method(rb_cTCPServer, \"accept_nonblock\", tcp_accept_nonblock, 0);\n    rb_define_method(rb_cTCPServer, \"sysaccept\", tcp_sysaccept, 0);\n    rb_define_method(rb_cTCPServer, \"initialize\", tcp_svr_init, -1);\n    rb_define_method(rb_cTCPServer, \"listen\", sock_listen, 1);\n\n    rb_cUDPSocket = rb_define_class(\"UDPSocket\", rb_cIPSocket);\n    rb_define_global_const(\"UDPsocket\", rb_cUDPSocket);\n    rb_define_method(rb_cUDPSocket, \"initialize\", udp_init, -1);\n    rb_define_method(rb_cUDPSocket, \"connect\", udp_connect, 2);\n    rb_define_method(rb_cUDPSocket, \"bind\", udp_bind, 2);\n    rb_define_method(rb_cUDPSocket, \"send\", udp_send, -1);\n    rb_define_method(rb_cUDPSocket, \"recvfrom_nonblock\", udp_recvfrom_nonblock, -1);\n\n#ifdef HAVE_SYS_UN_H\n    rb_cUNIXSocket = rb_define_class(\"UNIXSocket\", rb_cBasicSocket);\n    rb_define_global_const(\"UNIXsocket\", rb_cUNIXSocket);\n    rb_define_method(rb_cUNIXSocket, \"initialize\", unix_init, 1);\n    rb_define_method(rb_cUNIXSocket, \"path\", unix_path, 0);\n    rb_define_method(rb_cUNIXSocket, \"addr\", unix_addr, 0);\n    rb_define_method(rb_cUNIXSocket, \"peeraddr\", unix_peeraddr, 0);\n    rb_define_method(rb_cUNIXSocket, \"recvfrom\", unix_recvfrom, -1);\n    rb_define_method(rb_cUNIXSocket, \"send_io\", unix_send_io, 1);\n    rb_define_method(rb_cUNIXSocket, \"recv_io\", unix_recv_io, -1);\n    rb_define_singleton_method(rb_cUNIXSocket, \"socketpair\", unix_s_socketpair, -1);\n    rb_define_singleton_method(rb_cUNIXSocket, \"pair\", unix_s_socketpair, -1);\n\n    rb_cUNIXServer = rb_define_class(\"UNIXServer\", rb_cUNIXSocket);\n    rb_define_global_const(\"UNIXserver\", rb_cUNIXServer);\n    rb_define_method(rb_cUNIXServer, \"initialize\", unix_svr_init, 1);\n    rb_define_method(rb_cUNIXServer, \"accept\", unix_accept, 0);\n    rb_define_method(rb_cUNIXServer, \"accept_nonblock\", unix_accept_nonblock, 0);\n    rb_define_method(rb_cUNIXServer, \"sysaccept\", unix_sysaccept, 0);\n    rb_define_method(rb_cUNIXServer, \"listen\", sock_listen, 1);\n#endif\n\n    rb_cSocket = rb_define_class(\"Socket\", rb_cBasicSocket);\n\n    rb_define_method(rb_cSocket, \"initialize\", sock_initialize, 3);\n    rb_define_method(rb_cSocket, \"connect\", sock_connect, 1);\n    rb_define_method(rb_cSocket, \"connect_nonblock\", sock_connect_nonblock, 1);\n    rb_define_method(rb_cSocket, \"bind\", sock_bind, 1);\n    rb_define_method(rb_cSocket, \"listen\", sock_listen, 1);\n    rb_define_method(rb_cSocket, \"accept\", sock_accept, 0);\n    rb_define_method(rb_cSocket, \"accept_nonblock\", sock_accept_nonblock, 0);\n    rb_define_method(rb_cSocket, \"sysaccept\", sock_sysaccept, 0);\n\n    rb_define_method(rb_cSocket, \"recvfrom\", sock_recvfrom, -1);\n    rb_define_method(rb_cSocket, \"recvfrom_nonblock\", sock_recvfrom_nonblock, -1);\n\n    rb_define_singleton_method(rb_cSocket, \"socketpair\", sock_s_socketpair, 3);\n    rb_define_singleton_method(rb_cSocket, \"pair\", sock_s_socketpair, 3);\n    rb_define_singleton_method(rb_cSocket, \"gethostname\", sock_gethostname, 0);\n    rb_define_singleton_method(rb_cSocket, \"gethostbyname\", sock_s_gethostbyname, 1);\n    rb_define_singleton_method(rb_cSocket, \"gethostbyaddr\", sock_s_gethostbyaddr, -1);\n    rb_define_singleton_method(rb_cSocket, \"getservbyname\", sock_s_getservbyaname, -1);\n    rb_define_singleton_method(rb_cSocket, \"getaddrinfo\", sock_s_getaddrinfo, -1);\n    rb_define_singleton_method(rb_cSocket, \"getnameinfo\", sock_s_getnameinfo, -1);\n    rb_define_singleton_method(rb_cSocket, \"sockaddr_in\", sock_s_pack_sockaddr_in, 2);\n    rb_define_singleton_method(rb_cSocket, \"pack_sockaddr_in\", sock_s_pack_sockaddr_in, 2);\n    rb_define_singleton_method(rb_cSocket, \"unpack_sockaddr_in\", sock_s_unpack_sockaddr_in, 1);\n#ifdef HAVE_SYS_UN_H\n    rb_define_singleton_method(rb_cSocket, \"sockaddr_un\", sock_s_pack_sockaddr_un, 1);\n    rb_define_singleton_method(rb_cSocket, \"pack_sockaddr_un\", sock_s_pack_sockaddr_un, 1);\n    rb_define_singleton_method(rb_cSocket, \"unpack_sockaddr_un\", sock_s_unpack_sockaddr_un, 1);\n#endif\n\n    /* constants */\n    mConst = rb_define_module_under(rb_cSocket, \"Constants\");\n    sock_define_const(\"SOCK_STREAM\", SOCK_STREAM);\n    sock_define_const(\"SOCK_DGRAM\", SOCK_DGRAM);\n#ifdef SOCK_RAW\n    sock_define_const(\"SOCK_RAW\", SOCK_RAW);\n#endif\n#ifdef SOCK_RDM\n    sock_define_const(\"SOCK_RDM\", SOCK_RDM);\n#endif\n#ifdef SOCK_SEQPACKET\n    sock_define_const(\"SOCK_SEQPACKET\", SOCK_SEQPACKET);\n#endif\n#ifdef SOCK_PACKET\n    sock_define_const(\"SOCK_PACKET\", SOCK_PACKET);\n#endif\n\n    sock_define_const(\"AF_INET\", AF_INET);\n#ifdef PF_INET\n    sock_define_const(\"PF_INET\", PF_INET);\n#endif\n#ifdef AF_UNIX\n    sock_define_const(\"AF_UNIX\", AF_UNIX);\n    sock_define_const(\"PF_UNIX\", PF_UNIX);\n#endif\n#ifdef AF_AX25\n    sock_define_const(\"AF_AX25\", AF_AX25);\n    sock_define_const(\"PF_AX25\", PF_AX25);\n#endif\n#ifdef AF_IPX\n    sock_define_const(\"AF_IPX\", AF_IPX);\n    sock_define_const(\"PF_IPX\", PF_IPX);\n#endif\n#ifdef AF_APPLETALK\n    sock_define_const(\"AF_APPLETALK\", AF_APPLETALK);\n    sock_define_const(\"PF_APPLETALK\", PF_APPLETALK);\n#endif\n#ifdef AF_UNSPEC\n    sock_define_const(\"AF_UNSPEC\", AF_UNSPEC);\n    sock_define_const(\"PF_UNSPEC\", PF_UNSPEC);\n#endif\n#ifdef INET6\n    sock_define_const(\"AF_INET6\", AF_INET6);\n#endif\n#ifdef INET6\n    sock_define_const(\"PF_INET6\", PF_INET6);\n#endif\n#ifdef AF_LOCAL\n    sock_define_const(\"AF_LOCAL\", AF_LOCAL);\n#endif\n#ifdef PF_LOCAL\n    sock_define_const(\"PF_LOCAL\", PF_LOCAL);\n#endif\n#ifdef AF_IMPLINK\n    sock_define_const(\"AF_IMPLINK\", AF_IMPLINK);\n#endif\n#ifdef PF_IMPLINK\n    sock_define_const(\"PF_IMPLINK\", PF_IMPLINK);\n#endif\n#ifdef AF_PUP\n    sock_define_const(\"AF_PUP\", AF_PUP);\n#endif\n#ifdef PF_PUP\n    sock_define_const(\"PF_PUP\", PF_PUP);\n#endif\n#ifdef AF_CHAOS\n    sock_define_const(\"AF_CHAOS\", AF_CHAOS);\n#endif\n#ifdef PF_CHAOS\n    sock_define_const(\"PF_CHAOS\", PF_CHAOS);\n#endif\n#ifdef AF_NS\n    sock_define_const(\"AF_NS\", AF_NS);\n#endif\n#ifdef PF_NS\n    sock_define_const(\"PF_NS\", PF_NS);\n#endif\n#ifdef AF_ISO\n    sock_define_const(\"AF_ISO\", AF_ISO);\n#endif\n#ifdef PF_ISO\n    sock_define_const(\"PF_ISO\", PF_ISO);\n#endif\n#ifdef AF_OSI\n    sock_define_const(\"AF_OSI\", AF_OSI);\n#endif\n#ifdef PF_OSI\n    sock_define_const(\"PF_OSI\", PF_OSI);\n#endif\n#ifdef AF_ECMA\n    sock_define_const(\"AF_ECMA\", AF_ECMA);\n#endif\n#ifdef PF_ECMA\n    sock_define_const(\"PF_ECMA\", PF_ECMA);\n#endif\n#ifdef AF_DATAKIT\n    sock_define_const(\"AF_DATAKIT\", AF_DATAKIT);\n#endif\n#ifdef PF_DATAKIT\n    sock_define_const(\"PF_DATAKIT\", PF_DATAKIT);\n#endif\n#ifdef AF_CCITT\n    sock_define_const(\"AF_CCITT\", AF_CCITT);\n#endif\n#ifdef PF_CCITT\n    sock_define_const(\"PF_CCITT\", PF_CCITT);\n#endif\n#ifdef AF_SNA\n    sock_define_const(\"AF_SNA\", AF_SNA);\n#endif\n#ifdef PF_SNA\n    sock_define_const(\"PF_SNA\", PF_SNA);\n#endif\n#ifdef AF_DEC\n    sock_define_const(\"AF_DEC\", AF_DEC);\n#endif\n#ifdef PF_DEC\n    sock_define_const(\"PF_DEC\", PF_DEC);\n#endif\n#ifdef AF_DLI\n    sock_define_const(\"AF_DLI\", AF_DLI);\n#endif\n#ifdef PF_DLI\n    sock_define_const(\"PF_DLI\", PF_DLI);\n#endif\n#ifdef AF_LAT\n    sock_define_const(\"AF_LAT\", AF_LAT);\n#endif\n#ifdef PF_LAT\n    sock_define_const(\"PF_LAT\", PF_LAT);\n#endif\n#ifdef AF_HYLINK\n    sock_define_const(\"AF_HYLINK\", AF_HYLINK);\n#endif\n#ifdef PF_HYLINK\n    sock_define_const(\"PF_HYLINK\", PF_HYLINK);\n#endif\n#ifdef AF_ROUTE\n    sock_define_const(\"AF_ROUTE\", AF_ROUTE);\n#endif\n#ifdef PF_ROUTE\n    sock_define_const(\"PF_ROUTE\", PF_ROUTE);\n#endif\n#ifdef AF_LINK\n    sock_define_const(\"AF_LINK\", AF_LINK);\n#endif\n#ifdef PF_LINK\n    sock_define_const(\"PF_LINK\", PF_LINK);\n#endif\n#ifdef AF_COIP\n    sock_define_const(\"AF_COIP\", AF_COIP);\n#endif\n#ifdef PF_COIP\n    sock_define_const(\"PF_COIP\", PF_COIP);\n#endif\n#ifdef AF_CNT\n    sock_define_const(\"AF_CNT\", AF_CNT);\n#endif\n#ifdef PF_CNT\n    sock_define_const(\"PF_CNT\", PF_CNT);\n#endif\n#ifdef AF_SIP\n    sock_define_const(\"AF_SIP\", AF_SIP);\n#endif\n#ifdef PF_SIP\n    sock_define_const(\"PF_SIP\", PF_SIP);\n#endif\n#ifdef AF_NDRV\n    sock_define_const(\"AF_NDRV\", AF_NDRV);\n#endif\n#ifdef PF_NDRV\n    sock_define_const(\"PF_NDRV\", PF_NDRV);\n#endif\n#ifdef AF_ISDN\n    sock_define_const(\"AF_ISDN\", AF_ISDN);\n#endif\n#ifdef PF_ISDN\n    sock_define_const(\"PF_ISDN\", PF_ISDN);\n#endif\n#ifdef AF_NATM\n    sock_define_const(\"AF_NATM\", AF_NATM);\n#endif\n#ifdef PF_NATM\n    sock_define_const(\"PF_NATM\", PF_NATM);\n#endif\n#ifdef AF_SYSTEM\n    sock_define_const(\"AF_SYSTEM\", AF_SYSTEM);\n#endif\n#ifdef PF_SYSTEM\n    sock_define_const(\"PF_SYSTEM\", PF_SYSTEM);\n#endif\n#ifdef AF_NETBIOS\n    sock_define_const(\"AF_NETBIOS\", AF_NETBIOS);\n#endif\n#ifdef PF_NETBIOS\n    sock_define_const(\"PF_NETBIOS\", PF_NETBIOS);\n#endif\n#ifdef AF_PPP\n    sock_define_const(\"AF_PPP\", AF_PPP);\n#endif\n#ifdef PF_PPP\n    sock_define_const(\"PF_PPP\", PF_PPP);\n#endif\n#ifdef AF_ATM\n    sock_define_const(\"AF_ATM\", AF_ATM);\n#endif\n#ifdef PF_ATM\n    sock_define_const(\"PF_ATM\", PF_ATM);\n#endif\n#ifdef AF_NETGRAPH\n    sock_define_const(\"AF_NETGRAPH\", AF_NETGRAPH);\n#endif\n#ifdef PF_NETGRAPH\n    sock_define_const(\"PF_NETGRAPH\", PF_NETGRAPH);\n#endif\n#ifdef AF_MAX\n    sock_define_const(\"AF_MAX\", AF_MAX);\n#endif\n#ifdef PF_MAX\n    sock_define_const(\"PF_MAX\", PF_MAX);\n#endif\n#ifdef AF_E164\n    sock_define_const(\"AF_E164\", AF_E164);\n#endif\n#ifdef PF_XTP\n    sock_define_const(\"PF_XTP\", PF_XTP);\n#endif\n#ifdef PF_RTIP\n    sock_define_const(\"PF_RTIP\", PF_RTIP);\n#endif\n#ifdef PF_PIP\n    sock_define_const(\"PF_PIP\", PF_PIP);\n#endif\n#ifdef PF_KEY\n    sock_define_const(\"PF_KEY\", PF_KEY);\n#endif\n\n    sock_define_const(\"MSG_OOB\", MSG_OOB);\n#ifdef MSG_PEEK\n    sock_define_const(\"MSG_PEEK\", MSG_PEEK);\n#endif\n#ifdef MSG_DONTROUTE\n    sock_define_const(\"MSG_DONTROUTE\", MSG_DONTROUTE);\n#endif\n#ifdef MSG_EOR\n    sock_define_const(\"MSG_EOR\", MSG_EOR);\n#endif\n#ifdef MSG_TRUNC\n    sock_define_const(\"MSG_TRUNC\", MSG_TRUNC);\n#endif\n#ifdef MSG_CTRUNC\n    sock_define_const(\"MSG_CTRUNC\", MSG_CTRUNC);\n#endif\n#ifdef MSG_WAITALL\n    sock_define_const(\"MSG_WAITALL\", MSG_WAITALL);\n#endif\n#ifdef MSG_DONTWAIT\n    sock_define_const(\"MSG_DONTWAIT\", MSG_DONTWAIT);\n#endif\n#ifdef MSG_EOF\n    sock_define_const(\"MSG_EOF\", MSG_EOF);\n#endif\n#ifdef MSG_FLUSH\n    sock_define_const(\"MSG_FLUSH\", MSG_FLUSH);\n#endif\n#ifdef MSG_HOLD\n    sock_define_const(\"MSG_HOLD\", MSG_HOLD);\n#endif\n#ifdef MSG_SEND\n    sock_define_const(\"MSG_SEND\", MSG_SEND);\n#endif\n#ifdef MSG_HAVEMORE\n    sock_define_const(\"MSG_HAVEMORE\", MSG_HAVEMORE);\n#endif\n#ifdef MSG_RCVMORE\n    sock_define_const(\"MSG_RCVMORE\", MSG_RCVMORE);\n#endif\n#ifdef MSG_COMPAT\n    sock_define_const(\"MSG_COMPAT\", MSG_COMPAT);\n#endif\n\n    sock_define_const(\"SOL_SOCKET\", SOL_SOCKET);\n#ifdef SOL_IP\n    sock_define_const(\"SOL_IP\", SOL_IP);\n#endif\n#ifdef SOL_IPX\n    sock_define_const(\"SOL_IPX\", SOL_IPX);\n#endif\n#ifdef SOL_AX25\n    sock_define_const(\"SOL_AX25\", SOL_AX25);\n#endif\n#ifdef SOL_ATALK\n    sock_define_const(\"SOL_ATALK\", SOL_ATALK);\n#endif\n#ifdef SOL_TCP\n    sock_define_const(\"SOL_TCP\", SOL_TCP);\n#endif\n#ifdef SOL_UDP\n    sock_define_const(\"SOL_UDP\", SOL_UDP);\n#endif\n\n#ifdef\tIPPROTO_IP\n    sock_define_const(\"IPPROTO_IP\", IPPROTO_IP);\n#else\n    sock_define_const(\"IPPROTO_IP\", 0);\n#endif\n#ifdef\tIPPROTO_ICMP\n    sock_define_const(\"IPPROTO_ICMP\", IPPROTO_ICMP);\n#else\n    sock_define_const(\"IPPROTO_ICMP\", 1);\n#endif\n#ifdef\tIPPROTO_IGMP\n    sock_define_const(\"IPPROTO_IGMP\", IPPROTO_IGMP);\n#endif\n#ifdef\tIPPROTO_GGP\n    sock_define_const(\"IPPROTO_GGP\", IPPROTO_GGP);\n#endif\n#ifdef\tIPPROTO_TCP\n    sock_define_const(\"IPPROTO_TCP\", IPPROTO_TCP);\n#else\n    sock_define_const(\"IPPROTO_TCP\", 6);\n#endif\n#ifdef\tIPPROTO_EGP\n    sock_define_const(\"IPPROTO_EGP\", IPPROTO_EGP);\n#endif\n#ifdef\tIPPROTO_PUP\n    sock_define_const(\"IPPROTO_PUP\", IPPROTO_PUP);\n#endif\n#ifdef\tIPPROTO_UDP\n    sock_define_const(\"IPPROTO_UDP\", IPPROTO_UDP);\n#else\n    sock_define_const(\"IPPROTO_UDP\", 17);\n#endif\n#ifdef\tIPPROTO_IDP\n    sock_define_const(\"IPPROTO_IDP\", IPPROTO_IDP);\n#endif\n#ifdef\tIPPROTO_HELLO\n    sock_define_const(\"IPPROTO_HELLO\", IPPROTO_HELLO);\n#endif\n#ifdef\tIPPROTO_ND\n    sock_define_const(\"IPPROTO_ND\", IPPROTO_ND);\n#endif\n#ifdef\tIPPROTO_TP\n    sock_define_const(\"IPPROTO_TP\", IPPROTO_TP);\n#endif\n#ifdef\tIPPROTO_XTP\n    sock_define_const(\"IPPROTO_XTP\", IPPROTO_XTP);\n#endif\n#ifdef\tIPPROTO_EON\n    sock_define_const(\"IPPROTO_EON\", IPPROTO_EON);\n#endif\n#ifdef\tIPPROTO_BIP\n    sock_define_const(\"IPPROTO_BIP\", IPPROTO_BIP);\n#endif\n/**/\n#ifdef\tIPPROTO_RAW\n    sock_define_const(\"IPPROTO_RAW\", IPPROTO_RAW);\n#else\n    sock_define_const(\"IPPROTO_RAW\", 255);\n#endif\n#ifdef\tIPPROTO_MAX\n    sock_define_const(\"IPPROTO_MAX\", IPPROTO_MAX);\n#endif\n\n\t/* Some port configuration */\n#ifdef\tIPPORT_RESERVED\n    sock_define_const(\"IPPORT_RESERVED\", IPPORT_RESERVED);\n#else\n    sock_define_const(\"IPPORT_RESERVED\", 1024);\n#endif\n#ifdef\tIPPORT_USERRESERVED\n    sock_define_const(\"IPPORT_USERRESERVED\", IPPORT_USERRESERVED);\n#else\n    sock_define_const(\"IPPORT_USERRESERVED\", 5000);\n#endif\n\t/* Some reserved IP v.4 addresses */\n#ifdef\tINADDR_ANY\n    sock_define_const(\"INADDR_ANY\", INADDR_ANY);\n#else\n    sock_define_const(\"INADDR_ANY\", 0x00000000);\n#endif\n#ifdef\tINADDR_BROADCAST\n    sock_define_const(\"INADDR_BROADCAST\", INADDR_BROADCAST);\n#else\n    sock_define_const(\"INADDR_BROADCAST\", 0xffffffff);\n#endif\n#ifdef\tINADDR_LOOPBACK\n    sock_define_const(\"INADDR_LOOPBACK\", INADDR_LOOPBACK);\n#else\n    sock_define_const(\"INADDR_LOOPBACK\", 0x7F000001);\n#endif\n#ifdef\tINADDR_UNSPEC_GROUP\n    sock_define_const(\"INADDR_UNSPEC_GROUP\", INADDR_UNSPEC_GROUP);\n#else\n    sock_define_const(\"INADDR_UNSPEC_GROUP\", 0xe0000000);\n#endif\n#ifdef\tINADDR_ALLHOSTS_GROUP\n    sock_define_const(\"INADDR_ALLHOSTS_GROUP\", INADDR_ALLHOSTS_GROUP);\n#else\n    sock_define_const(\"INADDR_ALLHOSTS_GROUP\", 0xe0000001);\n#endif\n#ifdef\tINADDR_MAX_LOCAL_GROUP\n    sock_define_const(\"INADDR_MAX_LOCAL_GROUP\", INADDR_MAX_LOCAL_GROUP);\n#else\n    sock_define_const(\"INADDR_MAX_LOCAL_GROUP\", 0xe00000ff);\n#endif\n#ifdef\tINADDR_NONE\n    sock_define_const(\"INADDR_NONE\", INADDR_NONE);\n#else\n    sock_define_const(\"INADDR_NONE\", 0xffffffff);\n#endif\n\t/* IP [gs]etsockopt options */\n#ifdef\tIP_OPTIONS\n    sock_define_const(\"IP_OPTIONS\", IP_OPTIONS);\n#endif\n#ifdef\tIP_HDRINCL\n    sock_define_const(\"IP_HDRINCL\", IP_HDRINCL);\n#endif\n#ifdef\tIP_TOS\n    sock_define_const(\"IP_TOS\", IP_TOS);\n#endif\n#ifdef\tIP_TTL\n    sock_define_const(\"IP_TTL\", IP_TTL);\n#endif\n#ifdef\tIP_RECVOPTS\n    sock_define_const(\"IP_RECVOPTS\", IP_RECVOPTS);\n#endif\n#ifdef\tIP_RECVRETOPTS\n    sock_define_const(\"IP_RECVRETOPTS\", IP_RECVRETOPTS);\n#endif\n#ifdef\tIP_RECVDSTADDR\n    sock_define_const(\"IP_RECVDSTADDR\", IP_RECVDSTADDR);\n#endif\n#ifdef\tIP_RETOPTS\n    sock_define_const(\"IP_RETOPTS\", IP_RETOPTS);\n#endif\n#ifdef\tIP_MULTICAST_IF\n    sock_define_const(\"IP_MULTICAST_IF\", IP_MULTICAST_IF);\n#endif\n#ifdef\tIP_MULTICAST_TTL\n    sock_define_const(\"IP_MULTICAST_TTL\", IP_MULTICAST_TTL);\n#endif\n#ifdef\tIP_MULTICAST_LOOP\n    sock_define_const(\"IP_MULTICAST_LOOP\", IP_MULTICAST_LOOP);\n#endif\n#ifdef\tIP_ADD_MEMBERSHIP\n    sock_define_const(\"IP_ADD_MEMBERSHIP\", IP_ADD_MEMBERSHIP);\n#endif\n#ifdef\tIP_DROP_MEMBERSHIP\n    sock_define_const(\"IP_DROP_MEMBERSHIP\", IP_DROP_MEMBERSHIP);\n#endif\n#ifdef\tIP_DEFAULT_MULTICAST_TTL\n    sock_define_const(\"IP_DEFAULT_MULTICAST_TTL\", IP_DEFAULT_MULTICAST_TTL);\n#endif\n#ifdef\tIP_DEFAULT_MULTICAST_LOOP\n    sock_define_const(\"IP_DEFAULT_MULTICAST_LOOP\", IP_DEFAULT_MULTICAST_LOOP);\n#endif\n#ifdef\tIP_MAX_MEMBERSHIPS\n    sock_define_const(\"IP_MAX_MEMBERSHIPS\", IP_MAX_MEMBERSHIPS);\n#endif\n#ifdef SO_DEBUG\n    sock_define_const(\"SO_DEBUG\", SO_DEBUG);\n#endif\n    sock_define_const(\"SO_REUSEADDR\", SO_REUSEADDR);\n#ifdef SO_REUSEPORT\n    sock_define_const(\"SO_REUSEPORT\", SO_REUSEPORT);\n#endif\n#ifdef SO_TYPE\n    sock_define_const(\"SO_TYPE\", SO_TYPE);\n#endif\n#ifdef SO_ERROR\n    sock_define_const(\"SO_ERROR\", SO_ERROR);\n#endif\n#ifdef SO_DONTROUTE\n    sock_define_const(\"SO_DONTROUTE\", SO_DONTROUTE);\n#endif\n#ifdef SO_BROADCAST\n    sock_define_const(\"SO_BROADCAST\", SO_BROADCAST);\n#endif\n#ifdef SO_SNDBUF\n    sock_define_const(\"SO_SNDBUF\", SO_SNDBUF);\n#endif\n#ifdef SO_RCVBUF\n    sock_define_const(\"SO_RCVBUF\", SO_RCVBUF);\n#endif\n#ifdef SO_KEEPALIVE\n    sock_define_const(\"SO_KEEPALIVE\", SO_KEEPALIVE);\n#endif\n#ifdef SO_OOBINLINE\n    sock_define_const(\"SO_OOBINLINE\", SO_OOBINLINE);\n#endif\n#ifdef SO_NO_CHECK\n    sock_define_const(\"SO_NO_CHECK\", SO_NO_CHECK);\n#endif\n#ifdef SO_PRIORITY\n    sock_define_const(\"SO_PRIORITY\", SO_PRIORITY);\n#endif\n#ifdef SO_LINGER\n    sock_define_const(\"SO_LINGER\", SO_LINGER);\n#endif\n#ifdef SO_PASSCRED\n    sock_define_const(\"SO_PASSCRED\", SO_PASSCRED);\n#endif\n#ifdef SO_PEERCRED\n    sock_define_const(\"SO_PEERCRED\", SO_PEERCRED);\n#endif\n#ifdef SO_RCVLOWAT\n    sock_define_const(\"SO_RCVLOWAT\", SO_RCVLOWAT);\n#endif\n#ifdef SO_SNDLOWAT\n    sock_define_const(\"SO_SNDLOWAT\", SO_SNDLOWAT);\n#endif\n#ifdef SO_RCVTIMEO\n    sock_define_const(\"SO_RCVTIMEO\", SO_RCVTIMEO);\n#endif\n#ifdef SO_SNDTIMEO\n    sock_define_const(\"SO_SNDTIMEO\", SO_SNDTIMEO);\n#endif\n#ifdef SO_ACCEPTCONN\n    sock_define_const(\"SO_ACCEPTCONN\", SO_ACCEPTCONN);\n#endif\n#ifdef SO_USELOOPBACK\n    sock_define_const(\"SO_USELOOPBACK\", SO_USELOOPBACK);\n#endif\n#ifdef SO_ACCEPTFILTER\n    sock_define_const(\"SO_ACCEPTFILTER\", SO_ACCEPTFILTER);\n#endif\n#ifdef SO_DONTTRUNC\n    sock_define_const(\"SO_DONTTRUNC\", SO_DONTTRUNC);\n#endif\n#ifdef SO_WANTMORE\n    sock_define_const(\"SO_WANTMORE\", SO_WANTMORE);\n#endif\n#ifdef SO_WANTOOBFLAG\n    sock_define_const(\"SO_WANTOOBFLAG\", SO_WANTOOBFLAG);\n#endif\n#ifdef SO_NREAD\n    sock_define_const(\"SO_NREAD\", SO_NREAD);\n#endif\n#ifdef SO_NKE\n    sock_define_const(\"SO_NKE\", SO_NKE);\n#endif\n#ifdef SO_NOSIGPIPE\n    sock_define_const(\"SO_NOSIGPIPE\", SO_NOSIGPIPE);\n#endif\n\n#ifdef SO_SECURITY_AUTHENTICATION\n    sock_define_const(\"SO_SECURITY_AUTHENTICATION\", SO_SECURITY_AUTHENTICATION);\n#endif\n#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT\n    sock_define_const(\"SO_SECURITY_ENCRYPTION_TRANSPORT\", SO_SECURITY_ENCRYPTION_TRANSPORT);\n#endif\n#ifdef SO_SECURITY_ENCRYPTION_NETWORK\n    sock_define_const(\"SO_SECURITY_ENCRYPTION_NETWORK\", SO_SECURITY_ENCRYPTION_NETWORK);\n#endif\n\n#ifdef SO_BINDTODEVICE\n    sock_define_const(\"SO_BINDTODEVICE\", SO_BINDTODEVICE);\n#endif\n#ifdef SO_ATTACH_FILTER\n    sock_define_const(\"SO_ATTACH_FILTER\", SO_ATTACH_FILTER);\n#endif\n#ifdef SO_DETACH_FILTER\n    sock_define_const(\"SO_DETACH_FILTER\", SO_DETACH_FILTER);\n#endif\n#ifdef SO_PEERNAME\n    sock_define_const(\"SO_PEERNAME\", SO_PEERNAME);\n#endif\n#ifdef SO_TIMESTAMP\n    sock_define_const(\"SO_TIMESTAMP\", SO_TIMESTAMP);\n#endif\n\n#ifdef SOPRI_INTERACTIVE\n    sock_define_const(\"SOPRI_INTERACTIVE\", SOPRI_INTERACTIVE);\n#endif\n#ifdef SOPRI_NORMAL\n    sock_define_const(\"SOPRI_NORMAL\", SOPRI_NORMAL);\n#endif\n#ifdef SOPRI_BACKGROUND\n    sock_define_const(\"SOPRI_BACKGROUND\", SOPRI_BACKGROUND);\n#endif\n\n#ifdef IPX_TYPE\n    sock_define_const(\"IPX_TYPE\", IPX_TYPE);\n#endif\n\n#ifdef TCP_NODELAY\n    sock_define_const(\"TCP_NODELAY\", TCP_NODELAY);\n#endif\n#ifdef TCP_MAXSEG\n    sock_define_const(\"TCP_MAXSEG\", TCP_MAXSEG);\n#endif\n\n#ifdef EAI_ADDRFAMILY\n    sock_define_const(\"EAI_ADDRFAMILY\", EAI_ADDRFAMILY);\n#endif\n#ifdef EAI_AGAIN\n    sock_define_const(\"EAI_AGAIN\", EAI_AGAIN);\n#endif\n#ifdef EAI_BADFLAGS\n    sock_define_const(\"EAI_BADFLAGS\", EAI_BADFLAGS);\n#endif\n#ifdef EAI_FAIL\n    sock_define_const(\"EAI_FAIL\", EAI_FAIL);\n#endif\n#ifdef EAI_FAMILY\n    sock_define_const(\"EAI_FAMILY\", EAI_FAMILY);\n#endif\n#ifdef EAI_MEMORY\n    sock_define_const(\"EAI_MEMORY\", EAI_MEMORY);\n#endif\n#ifdef EAI_NODATA\n    sock_define_const(\"EAI_NODATA\", EAI_NODATA);\n#endif\n#ifdef EAI_NONAME\n    sock_define_const(\"EAI_NONAME\", EAI_NONAME);\n#endif\n#ifdef EAI_SERVICE\n    sock_define_const(\"EAI_SERVICE\", EAI_SERVICE);\n#endif\n#ifdef EAI_SOCKTYPE\n    sock_define_const(\"EAI_SOCKTYPE\", EAI_SOCKTYPE);\n#endif\n#ifdef EAI_SYSTEM\n    sock_define_const(\"EAI_SYSTEM\", EAI_SYSTEM);\n#endif\n#ifdef EAI_BADHINTS\n    sock_define_const(\"EAI_BADHINTS\", EAI_BADHINTS);\n#endif\n#ifdef EAI_PROTOCOL\n    sock_define_const(\"EAI_PROTOCOL\", EAI_PROTOCOL);\n#endif\n#ifdef EAI_MAX\n    sock_define_const(\"EAI_MAX\", EAI_MAX);\n#endif\n#ifdef AI_PASSIVE\n    sock_define_const(\"AI_PASSIVE\", AI_PASSIVE);\n#endif\n#ifdef AI_CANONNAME\n    sock_define_const(\"AI_CANONNAME\", AI_CANONNAME);\n#endif\n#ifdef AI_NUMERICHOST\n    sock_define_const(\"AI_NUMERICHOST\", AI_NUMERICHOST);\n#endif\n#ifdef AI_MASK\n    sock_define_const(\"AI_MASK\", AI_MASK);\n#endif\n#ifdef AI_ALL\n    sock_define_const(\"AI_ALL\", AI_ALL);\n#endif\n#ifdef AI_V4MAPPED_CFG\n    sock_define_const(\"AI_V4MAPPED_CFG\", AI_V4MAPPED_CFG);\n#endif\n#ifdef AI_ADDRCONFIG\n    sock_define_const(\"AI_ADDRCONFIG\", AI_ADDRCONFIG);\n#endif\n#ifdef AI_V4MAPPED\n    sock_define_const(\"AI_V4MAPPED\", AI_V4MAPPED);\n#endif\n#ifdef AI_DEFAULT\n    sock_define_const(\"AI_DEFAULT\", AI_DEFAULT);\n#endif\n#ifdef NI_MAXHOST\n    sock_define_const(\"NI_MAXHOST\", NI_MAXHOST);\n#endif\n#ifdef NI_MAXSERV\n    sock_define_const(\"NI_MAXSERV\", NI_MAXSERV);\n#endif\n#ifdef NI_NOFQDN\n    sock_define_const(\"NI_NOFQDN\", NI_NOFQDN);\n#endif\n#ifdef NI_NUMERICHOST\n    sock_define_const(\"NI_NUMERICHOST\", NI_NUMERICHOST);\n#endif\n#ifdef NI_NAMEREQD\n    sock_define_const(\"NI_NAMEREQD\", NI_NAMEREQD);\n#endif\n#ifdef NI_NUMERICSERV\n    sock_define_const(\"NI_NUMERICSERV\", NI_NUMERICSERV);\n#endif\n#ifdef NI_DGRAM\n    sock_define_const(\"NI_DGRAM\", NI_DGRAM);\n#endif\n#ifdef SHUT_RD\n    sock_define_const(\"SHUT_RD\", SHUT_RD);\n#else\n    sock_define_const(\"SHUT_RD\", 0);\n#endif\n#ifdef SHUT_WR\n    sock_define_const(\"SHUT_WR\", SHUT_WR);\n#else\n    sock_define_const(\"SHUT_WR\", 1);\n#endif\n#ifdef SHUT_RDWR\n    sock_define_const(\"SHUT_RDWR\", SHUT_RDWR);\n#else\n    sock_define_const(\"SHUT_RDWR\", 2);\n#endif\n}\n"
  },
  {
    "path": "ext/socket/sockport.h",
    "content": "/************************************************\n\n  sockport.h -\n\n  $Author$\n  $Date$\n  created at: Fri Apr 30 23:19:34 JST 1999\n\n************************************************/\n\n#ifndef SOCKPORT_H\n#define SOCKPORT_H\n\n#ifndef SA_LEN\n# ifdef HAVE_SA_LEN\n#  define SA_LEN(sa) (sa)->sa_len\n# else\n#  ifdef INET6\n#   define SA_LEN(sa) \\\n\t(((sa)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \\\n\t\t\t\t       : sizeof(struct sockaddr))\n#  else\n    /* by tradition, sizeof(struct sockaddr) covers most of the sockaddrs */\n#   define SA_LEN(sa)\t(sizeof(struct sockaddr))\n#  endif\n# endif\n#endif\n\n#ifdef HAVE_SA_LEN\n# define SET_SA_LEN(sa, len) (sa)->sa_len = (len)\n#else\n# define SET_SA_LEN(sa, len) (len)\n#endif\n\n#ifdef HAVE_SIN_LEN\n# define SIN_LEN(si) (si)->sin_len\n# define SET_SIN_LEN(si,len) (si)->sin_len = (len)\n#else\n# define SIN_LEN(si) sizeof(struct sockaddr_in)\n# define SET_SIN_LEN(si,len)\n#endif\n\n#ifndef IN_MULTICAST\n# define IN_CLASSD(i)\t(((long)(i) & 0xf0000000) == 0xe0000000)\n# define IN_MULTICAST(i)\tIN_CLASSD(i)\n#endif\n\n#ifndef IN_EXPERIMENTAL\n# define IN_EXPERIMENTAL(i) ((((long)(i)) & 0xe0000000) == 0xe0000000)\n#endif\n\n#ifndef IN_CLASSA_NSHIFT\n# define IN_CLASSA_NSHIFT 24\n#endif\n\n#ifndef IN_LOOPBACKNET\n# define IN_LOOPBACKNET 127\n#endif\n\n#ifndef AF_UNSPEC\n# define AF_UNSPEC 0\n#endif\n\n#ifndef PF_UNSPEC\n# define PF_UNSPEC AF_UNSPEC\n#endif\n\n#ifndef PF_INET\n# define PF_INET AF_INET\n#endif\n\n#if defined(HOST_NOT_FOUND) && !defined(h_errno) && !defined(__CYGWIN__)\nextern int h_errno;\n#endif\n\n#endif\n"
  },
  {
    "path": "ext/stringio/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/stringio/README",
    "content": "-*- rd -*-\n$Author$\n$Date$\n\n=begin\n\n= StringIO\nPseudo (({IO})) class from/to (({String})).\n\nThis library is based on MoonWolf version written in Ruby.  Thanks a lot.\n\n= Differences to (({IO}))\n\n* not implemented: (({fcntl})), (({reopen})).\n* (({fileno})) returns nil.\n* (({pos=})) returns new position, not 0.\n* (({ungetc})) does nothing at start of the string. \n\n=end\n"
  },
  {
    "path": "ext/stringio/depend",
    "content": "stringio.o: stringio.c $(hdrdir)/ruby.h $(topdir)/config.h \\\n  $(hdrdir)/defines.h $(hdrdir)/intern.h $(hdrdir)/rubyio.h\n"
  },
  {
    "path": "ext/stringio/extconf.rb",
    "content": "require 'mkmf'\ncreate_makefile('stringio')\n"
  },
  {
    "path": "ext/stringio/stringio.c",
    "content": "/**********************************************************************\n\n  stringio.c -\n\n  $Author$\n  $Date$\n  $RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $\n  created at: Tue Feb 19 04:10:38 JST 2002\n\n  All the files in this distribution are covered under the Ruby's\n  license (see the file COPYING).\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"re.h\"\n#if defined(HAVE_FCNTL_H) || defined(_WIN32)\n#include <fcntl.h>\n#elif defined(HAVE_SYS_FCNTL_H)\n#include <sys/fcntl.h>\n#endif\n\n#define STRIO_EOF FMODE_SYNC\n\nstruct StringIO {\n    VALUE string;\n    long pos;\n    long lineno;\n    int flags;\n    int count;\n};\n\nstatic struct StringIO* strio_alloc _((void));\nstatic void strio_mark _((struct StringIO *));\nstatic void strio_free _((struct StringIO *));\nstatic struct StringIO* check_strio _((VALUE));\nstatic struct StringIO* get_strio _((VALUE));\nstatic struct StringIO* readable _((struct StringIO *));\nstatic struct StringIO* writable _((struct StringIO *));\nstatic void check_modifiable _((struct StringIO *));\n\n#define IS_STRIO(obj) (RDATA(obj)->dmark == (RUBY_DATA_FUNC)strio_mark)\n#define error_inval(msg) (errno = EINVAL, rb_sys_fail(msg))\n\nstatic struct StringIO *\nstrio_alloc()\n{\n    struct StringIO *ptr = ALLOC(struct StringIO);\n    ptr->string = Qnil;\n    ptr->pos = 0;\n    ptr->lineno = 0;\n    ptr->flags = 0;\n    ptr->count = 1;\n    return ptr;\n}\n\nstatic void\nstrio_mark(ptr)\n    struct StringIO *ptr;\n{\n    if (ptr) {\n\trb_gc_mark(ptr->string);\n    }\n}\n\nstatic void\nstrio_free(ptr)\n    struct StringIO *ptr;\n{\n    if (--ptr->count <= 0) {\n\txfree(ptr);\n    }\n}\n\nstatic struct StringIO*\ncheck_strio(self)\n    VALUE self;\n{\n    Check_Type(self, T_DATA);\n    if (!IS_STRIO(self)) {\n\trb_raise(rb_eTypeError, \"wrong argument type %s (expected StringIO)\",\n\t\t rb_class2name(CLASS_OF(self)));\n    }\n    return DATA_PTR(self);\n}\n\nstatic struct StringIO*\nget_strio(self)\n    VALUE self;\n{\n    struct StringIO *ptr = check_strio(self);\n\n    if (!ptr) {\n\trb_raise(rb_eIOError, \"uninitialized stream\");\n    }\n    return ptr;\n}\n\n#define StringIO(obj) get_strio(obj)\n\n#define CLOSED(ptr) (!((ptr)->flags & FMODE_READWRITE))\n#define READABLE(ptr) ((ptr)->flags & FMODE_READABLE)\n#define WRITABLE(ptr) ((ptr)->flags & FMODE_WRITABLE)\n\nstatic struct StringIO*\nreadable(ptr)\n    struct StringIO *ptr;\n{\n    if (!READABLE(ptr)) {\n\trb_raise(rb_eIOError, \"not opened for reading\");\n    }\n    return ptr;\n}\n\nstatic struct StringIO*\nwritable(ptr)\n    struct StringIO *ptr;\n{\n    if (!WRITABLE(ptr)) {\n\trb_raise(rb_eIOError, \"not opened for writing\");\n    }\n    if (!OBJ_TAINTED(ptr->string)) {\n\trb_secure(4);\n    }\n    return ptr;\n}\n\nstatic void\ncheck_modifiable(ptr)\n    struct StringIO *ptr;\n{\n    if (OBJ_FROZEN(ptr->string)) {\n\trb_raise(rb_eIOError, \"not modifiable string\");\n    }\n}\n\nstatic VALUE strio_s_allocate _((VALUE));\nstatic VALUE strio_s_open _((int, VALUE *, VALUE));\nstatic void strio_init _((int, VALUE *, struct StringIO *));\nstatic VALUE strio_initialize _((int, VALUE *, VALUE));\nstatic VALUE strio_finalize _((VALUE));\nstatic VALUE strio_self _((VALUE));\nstatic VALUE strio_false _((VALUE));\nstatic VALUE strio_nil _((VALUE));\nstatic VALUE strio_0 _((VALUE));\nstatic VALUE strio_first _((VALUE, VALUE));\nstatic VALUE strio_unimpl _((int, VALUE *, VALUE));\nstatic VALUE strio_get_string _((VALUE));\nstatic VALUE strio_set_string _((VALUE, VALUE));\nstatic VALUE strio_close _((VALUE));\nstatic VALUE strio_close_read _((VALUE));\nstatic VALUE strio_close_write _((VALUE));\nstatic VALUE strio_closed _((VALUE));\nstatic VALUE strio_closed_read _((VALUE));\nstatic VALUE strio_closed_write _((VALUE));\nstatic VALUE strio_eof _((VALUE));\nstatic VALUE strio_get_lineno _((VALUE));\nstatic VALUE strio_set_lineno _((VALUE, VALUE));\nstatic VALUE strio_get_pos _((VALUE));\nstatic VALUE strio_set_pos _((VALUE, VALUE));\nstatic VALUE strio_rewind _((VALUE));\nstatic VALUE strio_seek _((int, VALUE *, VALUE));\nstatic VALUE strio_get_sync _((VALUE));\nstatic VALUE strio_each_byte _((VALUE));\nstatic VALUE strio_each_char _((VALUE));\nstatic VALUE strio_getc _((VALUE));\nstatic VALUE strio_ungetc _((VALUE, VALUE));\nstatic VALUE strio_readchar _((VALUE));\nstatic VALUE strio_getline _((int, VALUE *, struct StringIO *));\nstatic VALUE strio_gets _((int, VALUE *, VALUE));\nstatic VALUE strio_readline _((int, VALUE *, VALUE));\nstatic VALUE strio_each _((int, VALUE *, VALUE));\nstatic VALUE strio_readlines _((int, VALUE *, VALUE));\nstatic VALUE strio_write _((VALUE, VALUE));\nstatic VALUE strio_putc _((VALUE, VALUE));\nstatic VALUE strio_read _((int, VALUE *, VALUE));\nstatic VALUE strio_size _((VALUE));\nstatic VALUE strio_truncate _((VALUE, VALUE));\nvoid Init_stringio _((void));\n\n/* Boyer-Moore search: copied from regex.c */\nstatic void bm_init_skip _((long *, const char *, long));\nstatic long bm_search _((const char *, long, const char *, long, const long *));\n\nstatic VALUE\nstrio_s_allocate(klass)\n    VALUE klass;\n{\n    return Data_Wrap_Struct(klass, strio_mark, strio_free, 0);\n}\n\n/*\n * call-seq: StringIO.open(string=\"\"[, mode]) {|strio| ...}\n *\n * Equivalent to StringIO.new except that when it is called with a block, it\n * yields with the new instance and closes it, and returns the result which\n * returned from the block.\n */\nstatic VALUE\nstrio_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj = rb_class_new_instance(argc, argv, klass);\n    if (!rb_block_given_p()) return obj;\n    return rb_ensure(rb_yield, obj, strio_finalize, obj);\n}\n\n/*\n * call-seq: StringIO.new(string=\"\"[, mode])\n *\n * Creates new StringIO instance from with _string_ and _mode_.\n */\nstatic VALUE\nstrio_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct StringIO *ptr = check_strio(self);\n\n    if (!ptr) {\n\tDATA_PTR(self) = ptr = strio_alloc();\n    }\n    rb_call_super(0, 0);\n    strio_init(argc, argv, ptr);\n    return self;\n}\n\nstatic void\nstrio_init(argc, argv, ptr)\n    int argc;\n    VALUE *argv;\n    struct StringIO *ptr;\n{\n    VALUE string, mode;\n    int trunc = Qfalse;\n\n    switch (rb_scan_args(argc, argv, \"02\", &string, &mode)) {\n      case 2:\n\tif (FIXNUM_P(mode)) {\n\t    int flags = FIX2INT(mode);\n\t    ptr->flags = rb_io_modenum_flags(flags);\n\t    trunc = flags & O_TRUNC;\n\t}\n\telse {\n\t    const char *m = StringValueCStr(mode);\n\t    ptr->flags = rb_io_mode_flags(m);\n\t    trunc = *m == 'w';\n\t}\n\tStringValue(string);\n\tif ((ptr->flags & FMODE_WRITABLE) && OBJ_FROZEN(string)) {\n\t    errno = EACCES;\n\t    rb_sys_fail(0);\n\t}\n\tif (trunc) {\n\t    rb_str_resize(string, 0);\n\t}\n\tbreak;\n      case 1:\n\tStringValue(string);\n\tptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;\n\tbreak;\n      case 0:\n\tstring = rb_str_new(\"\", 0);\n\tptr->flags = FMODE_READWRITE;\n\tbreak;\n    }\n    ptr->string = string;\n    ptr->pos = 0;\n    ptr->lineno = 0;\n}\n\nstatic VALUE\nstrio_finalize(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    ptr->string = Qnil;\n    ptr->flags &= ~FMODE_READWRITE;\n    return self;\n}\n\n/*\n * Returns +false+.  Just for compatibility to IO.\n */\nstatic VALUE\nstrio_false(self)\n    VALUE self;\n{\n    StringIO(self);\n    return Qfalse;\n}\n\n/*\n * Returns +nil+.  Just for compatibility to IO.\n */\nstatic VALUE\nstrio_nil(self)\n    VALUE self;\n{\n    StringIO(self);\n    return Qnil;\n}\n\n/*\n * Returns *strio* itself.  Just for compatibility to IO.\n */\nstatic VALUE\nstrio_self(self)\n    VALUE self;\n{\n    StringIO(self);\n    return self;\n}\n\n/*\n * Returns 0.  Just for compatibility to IO.\n */\nstatic VALUE\nstrio_0(self)\n    VALUE self;\n{\n    StringIO(self);\n    return INT2FIX(0);\n}\n\n/*\n * Returns the argument unchanged.  Just for compatibility to IO.\n */\nstatic VALUE\nstrio_first(self, arg)\n    VALUE self, arg;\n{\n    StringIO(self);\n    return arg;\n}\n\n/*\n * Raises NotImplementedError.\n */\nstatic VALUE\nstrio_unimpl(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    StringIO(self);\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n}\n\n/*\n * call-seq: strio.string     -> string\n *\n * Returns underlying String object, the subject of IO.\n */\nstatic VALUE\nstrio_get_string(self)\n    VALUE self;\n{\n    return StringIO(self)->string;\n}\n\n/*\n * call-seq:\n *   strio.string = string  -> string\n *\n * Changes underlying String object, the subject of IO.\n */\nstatic VALUE\nstrio_set_string(self, string)\n    VALUE self, string;\n{\n    struct StringIO *ptr = StringIO(self);\n\n    if (!OBJ_TAINTED(self)) rb_secure(4);\n    ptr->flags &= ~FMODE_READWRITE;\n    StringValue(string);\n    ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;\n    ptr->pos = 0;\n    ptr->lineno = 0;\n    return ptr->string = string;\n}\n\n/*\n * call-seq:\n *   strio.close  -> nil\n *\n * Closes strio.  The *strio* is unavailable for any further data \n * operations; an +IOError+ is raised if such an attempt is made.\n */\nstatic VALUE\nstrio_close(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    if (CLOSED(ptr)) {\n\trb_raise(rb_eIOError, \"closed stream\");\n    }\n    ptr->flags &= ~FMODE_READWRITE;\n    return Qnil;\n}\n\n/*\n * call-seq:\n *   strio.close_read    -> nil\n *\n * Closes the read end of a StringIO.  Will raise an +IOError+ if the\n * *strio* is not readable.\n */\nstatic VALUE\nstrio_close_read(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    if (!READABLE(ptr)) {\n\trb_raise(rb_eIOError, \"closing non-duplex IO for reading\");\n    }\n    ptr->flags &= ~FMODE_READABLE;\n    return Qnil;\n}\n\n/*\n * call-seq:\n *   strio.close_write    -> nil\n *\n * Closes the write end of a StringIO.  Will raise an  +IOError+ if the\n * *strio* is not writeable.\n */\nstatic VALUE\nstrio_close_write(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    if (!WRITABLE(ptr)) {\n\trb_raise(rb_eIOError, \"closing non-duplex IO for writing\");\n    }\n    ptr->flags &= ~FMODE_WRITABLE;\n    return Qnil;\n}\n\n/*\n * call-seq:\n *   strio.closed?    -> true or false\n *\n * Returns +true+ if *strio* is completely closed, +false+ otherwise.\n */\nstatic VALUE\nstrio_closed(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    if (!CLOSED(ptr)) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *   strio.closed_read?    -> true or false\n *\n * Returns +true+ if *strio* is not readable, +false+ otherwise.\n */\nstatic VALUE\nstrio_closed_read(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    if (READABLE(ptr)) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *   strio.closed_write?    -> true or false\n *\n * Returns +true+ if *strio* is not writable, +false+ otherwise.\n */\nstatic VALUE\nstrio_closed_write(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    if (WRITABLE(ptr)) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *   strio.eof     -> true or false\n *   strio.eof?    -> true or false\n *\n * Returns true if *strio* is at end of file. The stringio must be  \n * opened for reading or an +IOError+ will be raised.\n */\nstatic VALUE\nstrio_eof(self)\n    VALUE self;\n{\n    struct StringIO *ptr = readable(StringIO(self));\n    if (ptr->pos < RSTRING(ptr->string)->len) return Qfalse;\n    return Qtrue;\n}\n\n/* :nodoc: */\nstatic VALUE\nstrio_copy(copy, orig)\n    VALUE copy, orig;\n{\n    struct StringIO *ptr;\n\n    orig = rb_convert_type(orig, T_DATA, \"StringIO\", \"to_strio\");\n    if (copy == orig) return copy;\n    ptr = StringIO(orig);\n    if (check_strio(copy)) {\n\tstrio_free(DATA_PTR(copy));\n    }\n    DATA_PTR(copy) = ptr;\n    OBJ_INFECT(copy, orig);\n    ++ptr->count;\n    return copy;\n}\n\n/*\n * call-seq:\n *   strio.lineno    -> integer\n *\n * Returns the current line number in *strio*. The stringio must be\n * opened for reading. +lineno+ counts the number of times  +gets+ is\n * called, rather than the number of newlines  encountered. The two\n * values will differ if +gets+ is  called with a separator other than\n * newline.  See also the  <code>$.</code> variable.\n */\nstatic VALUE\nstrio_get_lineno(self)\n    VALUE self;\n{\n    return LONG2NUM(StringIO(self)->lineno);\n}\n\n/*\n * call-seq:\n *   strio.lineno = integer    -> integer\n *\n * Manually sets the current line number to the given value.\n * <code>$.</code> is updated only on the next read.\n */\nstatic VALUE\nstrio_set_lineno(self, lineno)\n    VALUE self, lineno;\n{\n    StringIO(self)->lineno = NUM2LONG(lineno);\n    return lineno;\n}\n\n/* call-seq: strio.binmode -> true */\n#define strio_binmode strio_self\n\n/* call-seq: strio.fcntl */\n#define strio_fcntl strio_unimpl\n\n/* call-seq: strio.flush -> strio */\n#define strio_flush strio_self\n\n/* call-seq: strio.fsync -> 0 */\n#define strio_fsync strio_0\n\n/*\n * call-seq:\n *   strio.reopen(other_StrIO)     -> strio\n *   strio.reopen(string, mode)    -> strio\n *\n * Reinitializes *strio* with the given <i>other_StrIO</i> or _string_ \n * and _mode_ (see StringIO#new).\n */\nstatic VALUE\nstrio_reopen(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    if (!OBJ_TAINTED(self)) rb_secure(4);\n    if (argc == 1 && TYPE(*argv) != T_STRING) {\n\treturn strio_copy(self, *argv);\n    }\n    strio_init(argc, argv, StringIO(self));\n    return self;\n}\n\n/*\n * call-seq:\n *   strio.pos     -> integer\n *   strio.tell    -> integer\n *\n * Returns the current offset (in bytes) of *strio*.\n */\nstatic VALUE\nstrio_get_pos(self)\n    VALUE self;\n{\n    return LONG2NUM(StringIO(self)->pos);\n}\n\n/*\n * call-seq:\n *   strio.pos = integer    -> integer\n *\n * Seeks to the given position (in bytes) in *strio*.\n */\nstatic VALUE\nstrio_set_pos(self, pos)\n    VALUE self;\n    VALUE pos;\n{\n    struct StringIO *ptr = StringIO(self);\n    long p = NUM2LONG(pos);\n    if (p < 0) {\n\terror_inval(0);\n    }\n    ptr->pos = p;\n    ptr->flags &= ~STRIO_EOF;\n    return pos;\n}\n\n/*\n * call-seq:\n *   strio.rewind    -> 0\n *\n * Positions *strio* to the beginning of input, resetting\n * +lineno+ to zero.\n */\nstatic VALUE\nstrio_rewind(self)\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    ptr->pos = 0;\n    ptr->lineno = 0;\n    ptr->flags &= ~STRIO_EOF;\n    return INT2FIX(0);\n}\n\n/*\n * call-seq:\n *   strio.seek(amount, whence=SEEK_SET) -> 0\n *\n * Seeks to a given offset _amount_ in the stream according to\n * the value of _whence_ (see IO#seek).\n */\nstatic VALUE\nstrio_seek(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE whence;\n    struct StringIO *ptr = StringIO(self);\n    long offset;\n\n    rb_scan_args(argc, argv, \"11\", NULL, &whence);\n    offset = NUM2LONG(argv[0]);\n    if (CLOSED(ptr)) {\n\trb_raise(rb_eIOError, \"closed stream\");\n    }\n    switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {\n      case 0:\n\tbreak;\n      case 1:\n\toffset += ptr->pos;\n\tbreak;\n      case 2:\n\toffset += RSTRING(ptr->string)->len;\n\tbreak;\n      default:\n\terror_inval(\"invalid whence\");\n    }\n    if (offset < 0) {\n\terror_inval(0);\n    }\n    ptr->pos = offset;\n    ptr->flags &= ~STRIO_EOF;\n    return INT2FIX(0);\n}\n\n/*\n * call-seq:\n *   strio.sync    -> true\n *\n * Returns +true+ always.\n */\nstatic VALUE\nstrio_get_sync(self)\n    VALUE self;\n{\n    StringIO(self);\n    return Qtrue;\n}\n\n/* call-seq: strio.sync = boolean -> boolean */\n#define strio_set_sync strio_first\n\n#define strio_tell strio_get_pos\n\n/*\n * call-seq:\n *   strio.each_byte {|byte| block }  -> strio\n *\n * See IO#each_byte.\n */\nstatic VALUE\nstrio_each_byte(self)\n    VALUE self;\n{\n    struct StringIO *ptr = readable(StringIO(self));\n\n    RETURN_ENUMERATOR(self, 0, 0);\n\n    while (ptr->pos < RSTRING_LEN(ptr->string)) {\n\tchar c = RSTRING_PTR(ptr->string)[ptr->pos++];\n\trb_yield(CHR2FIX(c));\n    }\n    return self;\n}\n\n/*\n * call-seq:\n *   strio.getc   -> fixnum or nil\n *\n * See IO#getc.\n */\nstatic VALUE\nstrio_getc(self)\n    VALUE self;\n{\n    struct StringIO *ptr = readable(StringIO(self));\n    int c;\n    if (ptr->pos >= RSTRING(ptr->string)->len) {\n\tptr->flags |= STRIO_EOF;\n\treturn Qnil;\n    }\n    c = RSTRING(ptr->string)->ptr[ptr->pos++];\n    return CHR2FIX(c);\n}\n\nstatic void\nstrio_extend(ptr, pos, len)\n    struct StringIO *ptr;\n    long pos, len;\n{\n    long olen;\n\n    check_modifiable(ptr);\n    olen = RSTRING(ptr->string)->len;\n    if (pos + len > olen) {\n\trb_str_resize(ptr->string, pos + len);\n\tif (pos > olen)\n\t    MEMZERO(RSTRING(ptr->string)->ptr + olen, char, pos - olen);\n    }\n    else {\n\trb_str_modify(ptr->string);\n    }\n}\n\n/*\n * call-seq:\n *   strio.ungetc(integer)   -> nil\n *\n * Pushes back one character (passed as a parameter) onto *strio*\n * such that a subsequent buffered read will return it.  Pushing back \n * behind the beginning of the buffer string is not possible.  Nothing\n * will be done if such an attempt is made.\n * In other case, there is no limitation for multiple pushbacks.\n */\nstatic VALUE\nstrio_ungetc(self, ch)\n    VALUE self, ch;\n{\n    struct StringIO *ptr = readable(StringIO(self));\n    int cc = NUM2INT(ch);\n    long len, pos = ptr->pos;\n\n    if (cc != EOF) {\n\tlen = RSTRING(ptr->string)->len;\n\tif (pos == 0) {\n\t    char *p;\n\t    rb_str_resize(ptr->string, len + 1);\n\t    p = RSTRING(ptr->string)->ptr;\n\t    memmove(p + 1, p, len);\n\t}\n\telse {\n\t    if (len < pos-- ||\n\t\t(unsigned char)RSTRING(ptr->string)->ptr[pos] !=\n\t\t(unsigned char)cc) {\n\t\tstrio_extend(ptr, pos, 1);\n\t    }\n\t    --ptr->pos;\n\t}\n\tRSTRING(ptr->string)->ptr[pos] = cc;\n\tOBJ_INFECT(ptr->string, self);\n\tptr->flags &= ~STRIO_EOF;\n    }\n    return Qnil;\n}\n\n/*\n * call-seq:\n *   strio.readchar   -> fixnum\n *\n * See IO#readchar.\n */\nstatic VALUE\nstrio_readchar(self)\n    VALUE self;\n{\n    VALUE c = strio_getc(self);\n    if (NIL_P(c)) rb_eof_error();\n    return c;\n}\n\n/*\n * call-seq:\n *   strio.each_char {|char| block }  -> strio\n *\n * See IO#each_char.\n */\nstatic VALUE\nstrio_each_char(self)\n    VALUE self;\n{\n    struct StringIO *sio;\n    VALUE str;\n    const char *ptr;\n    size_t len;\n\n    RETURN_ENUMERATOR(self, 0, 0);\n\n    sio = readable(StringIO(self));\n    str = sio->string;\n    ptr = RSTRING_PTR(str);\n    len = RSTRING_LEN(str);\n\n    while (sio->pos < len) {\n\tint pos = sio->pos;\n\tchar c = ptr[pos];\n        int n = mbclen(c);\n\n\tif (len < pos + n) n = len - pos;\n\n\tsio->pos += n;\n        rb_yield(rb_str_substr(str, pos, n));\n    }\n    return self;\n}\n\nstatic void\nbm_init_skip(skip, pat, m)\n     long *skip;\n     const char *pat;\n     long m;\n{\n    int c;\n\n    for (c = 0; c < (1 << CHAR_BIT); c++) {\n\tskip[c] = m;\n    }\n    while (--m) {\n\tskip[(unsigned char)*pat++] = m;\n    }\n}\n\nstatic long\nbm_search(little, llen, big, blen, skip)\n    const char *little;\n    long llen;\n    const char *big;\n    long blen;\n    const long *skip;\n{\n    long i, j, k;\n\n    i = llen - 1;\n    while (i < blen) {\n\tk = i;\n\tj = llen - 1;\n\twhile (j >= 0 && big[k] == little[j]) {\n\t    k--;\n\t    j--;\n\t}\n\tif (j < 0) return k + 1;\n\ti += skip[(unsigned char)big[i]];\n    }\n    return -1;\n}\n\nstatic VALUE\nstrio_getline(argc, argv, ptr)\n    int argc;\n    VALUE *argv;\n    struct StringIO *ptr;\n{\n    const char *s, *e, *p;\n    long n;\n    VALUE str;\n\n    if (argc == 0) {\n\tstr = rb_rs;\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &str);\n\tif (!NIL_P(str)) StringValue(str);\n    }\n\n    if (ptr->pos >= (n = RSTRING(ptr->string)->len)) {\n\tptr->flags |= STRIO_EOF;\n\treturn Qnil;\n    }\n    s = RSTRING(ptr->string)->ptr;\n    e = s + RSTRING(ptr->string)->len;\n    s += ptr->pos;\n    if (NIL_P(str)) {\n\tstr = rb_str_substr(ptr->string, ptr->pos, e - s);\n    }\n    else if ((n = RSTRING(str)->len) == 0) {\n\tp = s;\n\twhile (*p == '\\n') {\n\t    if (++p == e) {\n\t\tptr->flags |= STRIO_EOF;\n\t\treturn Qnil;\n\t    }\n\t}\n\ts = p;\n\twhile ((p = memchr(p, '\\n', e - p)) && (p != e)) {\n\t    if (*++p == '\\n') {\n\t\te = p;\n\t\tbreak;\n\t    }\n\t}\n\tstr = rb_str_substr(ptr->string, s - RSTRING(ptr->string)->ptr, e - s); \n    }\n    else if (n == 1) {\n\tif ((p = memchr(s, RSTRING(str)->ptr[0], e - s)) != 0) {\n\t    e = p + 1;\n\t}\n\tstr = rb_str_substr(ptr->string, ptr->pos, e - s);\n    }\n    else {\n\tif (n < e - s) {\n\t    if (e - s < 1024) {\n\t\tfor (p = s; p + n <= e; ++p) {\n\t\t    if (MEMCMP(p, RSTRING(str)->ptr, char, n) == 0) {\n\t\t\te = p + n;\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\t    }\n\t    else {\n\t\tlong skip[1 << CHAR_BIT], pos;\n\t\tp = RSTRING(str)->ptr;\n\t\tbm_init_skip(skip, p, n);\n\t\tif ((pos = bm_search(p, n, s, e - s, skip)) >= 0) {\n\t\t    e = s + pos + n;\n\t\t}\n\t    }\n\t}\n\tstr = rb_str_substr(ptr->string, ptr->pos, e - s);\n    }\n    ptr->pos = e - RSTRING(ptr->string)->ptr;\n    ptr->lineno++;\n    return str;\n}\n\n/*\n * call-seq:\n *   strio.gets(sep_string=$/)   -> string or nil\n *\n * See IO#gets.\n */\nstatic VALUE\nstrio_gets(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE str = strio_getline(argc, argv, readable(StringIO(self)));\n\n    rb_lastline_set(str);\n    return str;\n}\n\n/*\n * call-seq:\n *   strio.readline(sep_string=$/)   -> string\n *\n * See IO#readline.\n */\nstatic VALUE\nstrio_readline(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE line = strio_gets(argc, argv, self);\n    if (NIL_P(line)) rb_eof_error();\n    return line;\n}\n\n/*\n * call-seq:\n *   strio.each(sep_string=$/)      {|line| block }  -> strio\n *   strio.each_line(sep_string=$/) {|line| block }  -> strio\n *\n * See IO#each.\n */\nstatic VALUE\nstrio_each(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    VALUE line;\n\n    RETURN_ENUMERATOR(self, argc, argv);\n\n    while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) {\n\trb_yield(line);\n    }\n    return self;\n}\n\n/*\n * call-seq:\n *   strio.readlines(sep_string=$/)  ->   array\n *\n * See IO#readlines.\n */\nstatic VALUE\nstrio_readlines(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct StringIO *ptr = StringIO(self);\n    VALUE ary = rb_ary_new(), line;\n    while (!NIL_P(line = strio_getline(argc, argv, readable(ptr)))) {\n\trb_ary_push(ary, line);\n    }\n    return ary;\n}\n\n/*\n * call-seq:\n *   strio.write(string)    -> integer\n *   strio.syswrite(string) -> integer\n *\n * Appends the given string to the underlying buffer string of *strio*.\n * The stream must be opened for writing.  If the argument is not a\n * string, it will be converted to a string using <code>to_s</code>.\n * Returns the number of bytes written.  See IO#write.\n */\nstatic VALUE\nstrio_write(self, str)\n    VALUE self, str;\n{\n    struct StringIO *ptr = writable(StringIO(self));\n    long len, olen;\n\n    if (TYPE(str) != T_STRING)\n\tstr = rb_obj_as_string(str);\n    len = RSTRING(str)->len;\n    if (!len) return INT2FIX(0);\n    check_modifiable(ptr);\n    olen = RSTRING(ptr->string)->len;\n    if (ptr->flags & FMODE_APPEND) {\n\tptr->pos = olen;\n    }\n    if (ptr->pos == olen) {\n\trb_str_cat(ptr->string, RSTRING(str)->ptr, len);\n    }\n    else {\n\tstrio_extend(ptr, ptr->pos, len);\n\trb_str_update(ptr->string, ptr->pos, len, str);\n    }\n    OBJ_INFECT(ptr->string, self);\n    ptr->pos += len;\n    return LONG2NUM(len);\n}\n\n/*\n * call-seq:\n *   strio << obj     -> strio\n *\n * See IO#<<.\n */\n#define strio_addstr rb_io_addstr\n\n/*\n * call-seq:\n *   strio.print()             -> nil\n *   strio.print(obj, ...)     -> nil\n *\n * See IO#print.\n */\n#define strio_print rb_io_print\n\n/*\n * call-seq:\n *   strio.printf(format_string [, obj, ...] )   -> nil\n *\n * See IO#printf.\n */\n#define strio_printf rb_io_printf\n\n/*\n * call-seq:\n *   strio.putc(obj)    -> obj\n *\n * See IO#putc.\n */\nstatic VALUE\nstrio_putc(self, ch)\n    VALUE self, ch;\n{\n    struct StringIO *ptr = writable(StringIO(self));\n    int c = NUM2CHR(ch);\n    long olen;\n\n    check_modifiable(ptr);\n    olen = RSTRING(ptr->string)->len;\n    if (ptr->flags & FMODE_APPEND) {\n\tptr->pos = olen;\n    }\n    strio_extend(ptr, ptr->pos, 1);\n    RSTRING(ptr->string)->ptr[ptr->pos++] = c;\n    OBJ_INFECT(ptr->string, self);\n    return ch;\n}\n\n/*\n * call-seq:\n *   strio.puts(obj, ...)    -> nil\n *\n * See IO#puts.\n */\n#define strio_puts rb_io_puts\n\n/*\n * call-seq:\n *   strio.read([length [, buffer]])    -> string, buffer, or nil\n *\n * See IO#read.\n */\nstatic VALUE\nstrio_read(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct StringIO *ptr = readable(StringIO(self));\n    VALUE str = Qnil;\n    long len, olen;\n\n    switch (argc) {\n      case 2:\n\tstr = argv[1];\n\tStringValue(str);\n\trb_str_modify(str);\n      case 1:\n\tif (!NIL_P(argv[0])) {\n\t    len = olen = NUM2LONG(argv[0]);\n\t    if (len < 0) {\n\t\trb_raise(rb_eArgError, \"negative length %ld given\", len);\n\t    }\n\t    if (len > 0 && ptr->pos >= RSTRING(ptr->string)->len) {\n\t\tptr->flags |= STRIO_EOF;\n\t\tif (!NIL_P(str)) rb_str_resize(str, 0);\n\t\treturn Qnil;\n\t    }\n\t    else if (ptr->flags & STRIO_EOF) {\n\t\tif (!NIL_P(str)) rb_str_resize(str, 0);\n\t\treturn Qnil;\n\t    }\n\t    break;\n\t}\n\t/* fall through */\n      case 0:\n\tolen = -1;\n\tlen = RSTRING(ptr->string)->len;\n\tif (len <= ptr->pos) {\n\t    ptr->flags |= STRIO_EOF;\n\t    if (NIL_P(str)) {\n\t\tstr = rb_str_new(0, 0);\n\t    }\n\t    else {\n\t\trb_str_resize(str, 0);\n\t    }\n\t    return str;\n\t}\n\telse {\n\t    len -= ptr->pos;\n\t}\n\tbreak;\n      default:\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for 0)\", argc);\n    }\n    if (NIL_P(str)) {\n\tstr = rb_str_substr(ptr->string, ptr->pos, len);\n    }\n    else {\n\tlong rest = RSTRING(ptr->string)->len - ptr->pos;\n\tif (len > rest) len = rest;\n\trb_str_resize(str, len);\n\tMEMCPY(RSTRING(str)->ptr, RSTRING(ptr->string)->ptr + ptr->pos, char, len);\n    }\n    if (NIL_P(str)) {\n\tif (!(ptr->flags & STRIO_EOF)) str = rb_str_new(0, 0);\n\tlen = 0;\n    }\n    else {\n\tptr->pos += len = RSTRING(str)->len;\n    }\n    if (olen < 0 || olen > len) ptr->flags |= STRIO_EOF;\n    return str;\n}\n\n/*\n * call-seq:\n *   strio.sysread(integer[, outbuf])    -> string\n *\n * Similar to #read, but raises +EOFError+ at end of string instead of\n * returning +nil+, as well as IO#sysread does.\n */\nstatic VALUE\nstrio_sysread(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE val = strio_read(argc, argv, self);\n    if (NIL_P(val) || RSTRING(val)->len == 0) {\n\trb_eof_error();\n    }\n    return val;\n}\n\n#define strio_syswrite strio_write\n\n/* call-seq: strio.path -> nil */\n#define strio_path strio_nil\n\n/*\n * call-seq:\n *   strio.isatty -> nil\n *   strio.tty? -> nil\n *\n */\n#define strio_isatty strio_false\n\n/* call-seq: strio.pid -> nil */\n#define strio_pid strio_nil\n\n/* call-seq: strio.fileno -> nil */\n#define strio_fileno strio_nil\n\n/*\n * call-seq:\n *   strio.size   -> integer\n *\n * Returns the size of the buffer string.\n */\nstatic VALUE\nstrio_size(self)\n    VALUE self;\n{\n    VALUE string = StringIO(self)->string;\n    if (NIL_P(string)) {\n\trb_raise(rb_eIOError, \"not opened\");\n    }\n    return ULONG2NUM(RSTRING(string)->len);\n}\n\n/*\n * call-seq:\n *   strio.truncate(integer)    -> 0\n *\n * Truncates the buffer string to at most _integer_ bytes. The *strio*\n * must be opened for writing.\n */\nstatic VALUE\nstrio_truncate(self, len)\n    VALUE self, len;\n{\n    VALUE string = writable(StringIO(self))->string;\n    long l = NUM2LONG(len);\n    long plen = RSTRING(string)->len;\n    if (l < 0) {\n\terror_inval(\"negative legnth\");\n    }\n    rb_str_resize(string, l);\n    if (plen < l) {\n\tMEMZERO(RSTRING(string)->ptr + plen, char, l - plen);\n    }\n    return len;\n}\n\n/*\n * Pseudo I/O on String object.\n */\nvoid\nInit_stringio()\n{\n    VALUE StringIO = rb_define_class(\"StringIO\", rb_cData);\n\n    rb_include_module(StringIO, rb_mEnumerable);\n    rb_define_alloc_func(StringIO, strio_s_allocate);\n    rb_define_singleton_method(StringIO, \"open\", strio_s_open, -1);\n    rb_define_method(StringIO, \"initialize\", strio_initialize, -1);\n    rb_define_method(StringIO, \"initialize_copy\", strio_copy, 1);\n    rb_define_method(StringIO, \"reopen\", strio_reopen, -1);\n\n    rb_define_method(StringIO, \"string\", strio_get_string, 0);\n    rb_define_method(StringIO, \"string=\", strio_set_string, 1);\n    rb_define_method(StringIO, \"lineno\", strio_get_lineno, 0);\n    rb_define_method(StringIO, \"lineno=\", strio_set_lineno, 1);\n\n    rb_define_method(StringIO, \"binmode\", strio_binmode, 0);\n    rb_define_method(StringIO, \"close\", strio_close, 0);\n    rb_define_method(StringIO, \"close_read\", strio_close_read, 0);\n    rb_define_method(StringIO, \"close_write\", strio_close_write, 0);\n    rb_define_method(StringIO, \"closed?\", strio_closed, 0);\n    rb_define_method(StringIO, \"closed_read?\", strio_closed_read, 0);\n    rb_define_method(StringIO, \"closed_write?\", strio_closed_write, 0);\n    rb_define_method(StringIO, \"eof\", strio_eof, 0);\n    rb_define_method(StringIO, \"eof?\", strio_eof, 0);\n    rb_define_method(StringIO, \"fcntl\", strio_fcntl, -1);\n    rb_define_method(StringIO, \"flush\", strio_flush, 0);\n    rb_define_method(StringIO, \"fsync\", strio_fsync, 0);\n    rb_define_method(StringIO, \"pos\", strio_get_pos, 0);\n    rb_define_method(StringIO, \"pos=\", strio_set_pos, 1);\n    rb_define_method(StringIO, \"rewind\", strio_rewind, 0);\n    rb_define_method(StringIO, \"seek\", strio_seek, -1);\n    rb_define_method(StringIO, \"sync\", strio_get_sync, 0);\n    rb_define_method(StringIO, \"sync=\", strio_set_sync, 1);\n    rb_define_method(StringIO, \"tell\", strio_tell, 0);\n    rb_define_method(StringIO, \"path\", strio_path, 0);\n\n    rb_define_method(StringIO, \"each\", strio_each, -1);\n    rb_define_method(StringIO, \"each_line\", strio_each, -1);\n    rb_define_method(StringIO, \"lines\", strio_each, -1);\n    rb_define_method(StringIO, \"each_byte\", strio_each_byte, 0);\n    rb_define_method(StringIO, \"bytes\", strio_each_byte, 0);\n    rb_define_method(StringIO, \"each_char\", strio_each_char, 0);\n    rb_define_method(StringIO, \"chars\", strio_each_char, 0);\n    rb_define_method(StringIO, \"getc\", strio_getc, 0);\n    rb_define_method(StringIO, \"getbyte\", strio_getc, 0);\n    rb_define_method(StringIO, \"ungetc\", strio_ungetc, 1);\n    rb_define_method(StringIO, \"readchar\", strio_readchar, 0);\n    rb_define_method(StringIO, \"readbyte\", strio_readchar, 0);\n    rb_define_method(StringIO, \"gets\", strio_gets, -1);\n    rb_define_method(StringIO, \"readline\", strio_readline, -1);\n    rb_define_method(StringIO, \"readlines\", strio_readlines, -1);\n    rb_define_method(StringIO, \"read\", strio_read, -1);\n    rb_define_method(StringIO, \"sysread\", strio_sysread, -1);\n\n    rb_define_method(StringIO, \"write\", strio_write, 1);\n    rb_define_method(StringIO, \"<<\", strio_addstr, 1);\n    rb_define_method(StringIO, \"print\", strio_print, -1);\n    rb_define_method(StringIO, \"printf\", strio_printf, -1);\n    rb_define_method(StringIO, \"putc\", strio_putc, 1);\n    rb_define_method(StringIO, \"puts\", strio_puts, -1);\n    rb_define_method(StringIO, \"syswrite\", strio_syswrite, 1);\n\n    rb_define_method(StringIO, \"isatty\", strio_isatty, 0);\n    rb_define_method(StringIO, \"tty?\", strio_isatty, 0);\n    rb_define_method(StringIO, \"pid\", strio_pid, 0);\n    rb_define_method(StringIO, \"fileno\", strio_fileno, 0);\n    rb_define_method(StringIO, \"size\", strio_size, 0);\n    rb_define_method(StringIO, \"length\", strio_size, 0);\n    rb_define_method(StringIO, \"truncate\", strio_truncate, 1);\n}\n"
  },
  {
    "path": "ext/strscan/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/strscan/depend",
    "content": "strscan.o: strscan.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/strscan/extconf.rb",
    "content": "require 'mkmf'\ncreate_makefile 'strscan'\n"
  },
  {
    "path": "ext/strscan/strscan.c",
    "content": "/*\n    $Id$\n\n    Copyright (c) 1999-2006 Minero Aoki\n\n    This program is free software.\n    You can distribute/modify this program under the terms of\n    the Ruby License. For details, see the file COPYING.\n*/\n\n#include \"ruby.h\"\n#include \"re.h\"\n\n#define STRSCAN_VERSION \"0.7.0\"\n\n/* =======================================================================\n                         Data Type Definitions\n   ======================================================================= */\n\nstatic VALUE StringScanner;\nstatic VALUE ScanError;\n\nstruct strscanner\n{\n    /* multi-purpose flags */\n    unsigned long flags;\n#define FLAG_MATCHED (1 << 0)\n\n    /* the string to scan */\n    VALUE str;\n    \n    /* scan pointers */\n    long prev;   /* legal only when MATCHED_P(s) */\n    long curr;   /* always legal */\n\n    /* the regexp register; legal only when MATCHED_P(s) */\n    struct re_registers regs;\n};\n\n#define MATCHED_P(s)          ((s)->flags & FLAG_MATCHED)\n#define MATCHED(s)             (s)->flags |= FLAG_MATCHED\n#define CLEAR_MATCH_STATUS(s)  (s)->flags &= ~FLAG_MATCHED\n\n#define S_PBEG(s)  (RSTRING((s)->str)->ptr)\n#define S_LEN(s)  (RSTRING((s)->str)->len)\n#define S_PEND(s)  (S_PBEG(s) + S_LEN(s))\n#define CURPTR(s) (S_PBEG(s) + (s)->curr)\n#define S_RESTLEN(s) (S_LEN(s) - (s)->curr)\n\n#define EOS_P(s) ((s)->curr >= RSTRING(p->str)->len)\n\n#define GET_SCANNER(obj,var) do {\\\n    Data_Get_Struct(obj, struct strscanner, var);\\\n    if (NIL_P(var->str)) rb_raise(rb_eArgError, \"uninitialized StringScanner object\");\\\n} while (0)\n\n/* =======================================================================\n                            Function Prototypes\n   ======================================================================= */\n\nstatic VALUE infect _((VALUE str, struct strscanner *p));\nstatic VALUE extract_range _((struct strscanner *p, long beg_i, long end_i));\nstatic VALUE extract_beg_len _((struct strscanner *p, long beg_i, long len));\n\nstatic void check_strscan _((VALUE obj));\nstatic void strscan_mark _((struct strscanner *p));\nstatic void strscan_free _((struct strscanner *p));\nstatic VALUE strscan_s_allocate _((VALUE klass));\nstatic VALUE strscan_initialize _((int argc, VALUE *argv, VALUE self));\nstatic VALUE strscan_init_copy _((VALUE vself, VALUE vorig));\n\nstatic VALUE strscan_s_mustc _((VALUE self));\nstatic VALUE strscan_terminate _((VALUE self));\nstatic VALUE strscan_clear _((VALUE self));\nstatic VALUE strscan_get_string _((VALUE self));\nstatic VALUE strscan_set_string _((VALUE self, VALUE str));\nstatic VALUE strscan_concat _((VALUE self, VALUE str));\nstatic VALUE strscan_get_pos _((VALUE self));\nstatic VALUE strscan_set_pos _((VALUE self, VALUE pos));\nstatic VALUE strscan_do_scan _((VALUE self, VALUE regex,\n                                int succptr, int getstr, int headonly));\nstatic VALUE strscan_scan _((VALUE self, VALUE re));\nstatic VALUE strscan_match_p _((VALUE self, VALUE re));\nstatic VALUE strscan_skip _((VALUE self, VALUE re));\nstatic VALUE strscan_check _((VALUE self, VALUE re));\nstatic VALUE strscan_scan_full _((VALUE self, VALUE re,\n                                  VALUE succp, VALUE getp));\nstatic VALUE strscan_scan_until _((VALUE self, VALUE re));\nstatic VALUE strscan_skip_until _((VALUE self, VALUE re));\nstatic VALUE strscan_check_until _((VALUE self, VALUE re));\nstatic VALUE strscan_search_full _((VALUE self, VALUE re,\n                                    VALUE succp, VALUE getp));\nstatic void adjust_registers_to_matched _((struct strscanner *p));\nstatic VALUE strscan_getch _((VALUE self));\nstatic VALUE strscan_get_byte _((VALUE self));\nstatic VALUE strscan_getbyte _((VALUE self));\nstatic VALUE strscan_peek _((VALUE self, VALUE len));\nstatic VALUE strscan_peep _((VALUE self, VALUE len));\nstatic VALUE strscan_unscan _((VALUE self));\nstatic VALUE strscan_bol_p _((VALUE self));\nstatic VALUE strscan_eos_p _((VALUE self));\nstatic VALUE strscan_empty_p _((VALUE self));\nstatic VALUE strscan_rest_p _((VALUE self));\nstatic VALUE strscan_matched_p _((VALUE self));\nstatic VALUE strscan_matched _((VALUE self));\nstatic VALUE strscan_matched_size _((VALUE self));\nstatic VALUE strscan_aref _((VALUE self, VALUE idx));\nstatic VALUE strscan_pre_match _((VALUE self));\nstatic VALUE strscan_post_match _((VALUE self));\nstatic VALUE strscan_rest _((VALUE self));\nstatic VALUE strscan_rest_size _((VALUE self));\n\nstatic VALUE strscan_inspect _((VALUE self));\nstatic VALUE inspect1 _((struct strscanner *p));\nstatic VALUE inspect2 _((struct strscanner *p));\n\n/* =======================================================================\n                                   Utils\n   ======================================================================= */\n\nstatic VALUE\ninfect(VALUE str, struct strscanner *p)\n{\n    OBJ_INFECT(str, p->str);\n    return str;\n}\n\nstatic VALUE\nextract_range(struct strscanner *p, long beg_i, long end_i)\n{\n    if (beg_i > S_LEN(p)) return Qnil;\n    if (end_i > S_LEN(p))\n        end_i = S_LEN(p);\n    return infect(rb_str_new(S_PBEG(p) + beg_i, end_i - beg_i), p);\n}\n\nstatic VALUE\nextract_beg_len(struct strscanner *p, long beg_i, long len)\n{\n    if (beg_i > S_LEN(p)) return Qnil;\n    if (beg_i + len > S_LEN(p))\n        len = S_LEN(p) - beg_i;\n    return infect(rb_str_new(S_PBEG(p) + beg_i, len), p);\n}\n\n/* =======================================================================\n                               Constructor\n   ======================================================================= */\n\nstatic void\nstrscan_mark(struct strscanner *p)\n{\n    rb_gc_mark(p->str);\n}\n\nstatic void\nstrscan_free(struct strscanner *p)\n{\n    re_free_registers(&(p->regs));\n    free(p);\n}\n\nstatic VALUE\nstrscan_s_allocate(VALUE klass)\n{\n    struct strscanner *p;\n    \n    p = ALLOC(struct strscanner);\n    MEMZERO(p, struct strscanner, 1);\n    CLEAR_MATCH_STATUS(p);\n    MEMZERO(&(p->regs), struct re_registers, 1);\n    p->str = Qnil;\n    return Data_Wrap_Struct(klass, strscan_mark, strscan_free, p);\n}\n\n/*\n * call-seq: StringScanner.new(string, dup = false)\n *\n * Creates a new StringScanner object to scan over the given +string+.\n * +dup+ argument is obsolete and not used now.\n */\nstatic VALUE\nstrscan_initialize(int argc, VALUE *argv, VALUE self)\n{\n    struct strscanner *p;\n    VALUE str, need_dup;\n\n    Data_Get_Struct(self, struct strscanner, p);\n    rb_scan_args(argc, argv, \"11\", &str, &need_dup);\n    StringValue(str);\n    p->str = str;\n\n    return self;\n}\n\nstatic void\ncheck_strscan(VALUE obj)\n{\n    if (TYPE(obj) != T_DATA || RDATA(obj)->dmark != (RUBY_DATA_FUNC)strscan_mark) {\n        rb_raise(rb_eTypeError,\n                 \"wrong argument type %s (expected StringScanner)\",\n                 rb_obj_classname(obj));\n    }\n}\n\n/*\n * call-seq:\n *   dup\n *   clone\n *\n * Duplicates a StringScanner object.\n */\nstatic VALUE\nstrscan_init_copy(VALUE vself, VALUE vorig)\n{\n    struct strscanner *self, *orig;\n\n    Data_Get_Struct(vself, struct strscanner, self);\n    check_strscan(vorig);\n    Data_Get_Struct(vorig, struct strscanner, orig);\n    if (self != orig) {\n        self->flags = orig->flags;\n        self->str = orig->str;\n        self->prev = orig->prev;\n        self->curr = orig->curr;\n        re_copy_registers(&self->regs, &orig->regs);\n    }\n    return vself;\n}\n\n/* =======================================================================\n                          Instance Methods\n   ======================================================================= */\n\n/*\n * call-seq: StringScanner.must_C_version\n *\n * This method is defined for backward compatibility.\n */\nstatic VALUE\nstrscan_s_mustc(VALUE self)\n{\n    return self;\n}\n\n/*\n * Reset the scan pointer (index 0) and clear matching data.\n */\nstatic VALUE\nstrscan_reset(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    p->curr = 0;\n    CLEAR_MATCH_STATUS(p);\n    return self;\n}\n\n/*\n * call-seq:\n *   terminate\n *   clear\n *\n * Set the scan pointer to the end of the string and clear matching data.\n */\nstatic VALUE\nstrscan_terminate(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    p->curr = S_LEN(p);\n    CLEAR_MATCH_STATUS(p);\n    return self;\n}\n\n/*\n * Equivalent to #terminate.\n * This method is obsolete; use #terminate instead.\n */\nstatic VALUE\nstrscan_clear(VALUE self)\n{\n    rb_warning(\"StringScanner#clear is obsolete; use #terminate instead\");\n    return strscan_terminate(self);\n}\n\n/*\n * Returns the string being scanned.\n */\nstatic VALUE\nstrscan_get_string(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    return p->str;\n}\n\n/*\n * call-seq: string=(str)\n *\n * Changes the string being scanned to +str+ and resets the scanner.\n * Returns +str+.\n */\nstatic VALUE\nstrscan_set_string(VALUE self, VALUE str)\n{\n    struct strscanner *p;\n\n    Data_Get_Struct(self, struct strscanner, p);\n    StringValue(str);\n    p->str = rb_str_dup(str);\n    rb_obj_freeze(p->str);\n    p->curr = 0;\n    CLEAR_MATCH_STATUS(p);\n    return str;\n}\n\n/*\n * call-seq:\n *   concat(str)\n *   <<(str)\n *\n * Appends +str+ to the string being scanned.\n * This method does not affect scan pointer.\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.scan(/Fri /)\n *   s << \" +1000 GMT\"\n *   s.string            # -> \"Fri Dec 12 1975 14:39 +1000 GMT\"\n *   s.scan(/Dec/)       # -> \"Dec\"\n */\nstatic VALUE\nstrscan_concat(VALUE self, VALUE str)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    StringValue(str);\n    rb_str_append(p->str, str);\n    return self;\n}\n\n/*\n * Returns the position of the scan pointer.  In the 'reset' position, this\n * value is zero.  In the 'terminated' position (i.e. the string is exhausted),\n * this value is the length of the string.\n *\n * In short, it's a 0-based index into the string.\n *\n *   s = StringScanner.new('test string')\n *   s.pos               # -> 0\n *   s.scan_until /str/  # -> \"test str\"\n *   s.pos               # -> 8\n *   s.terminate         # -> #<StringScanner fin>\n *   s.pos               # -> 11\n */\nstatic VALUE\nstrscan_get_pos(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    return INT2FIX(p->curr);\n}\n\n/*\n * call-seq: pos=(n)\n *\n * Modify the scan pointer.\n *\n *   s = StringScanner.new('test string')\n *   s.pos = 7            # -> 7\n *   s.rest               # -> \"ring\"\n */\nstatic VALUE\nstrscan_set_pos(VALUE self, VALUE v)\n{\n    struct strscanner *p;\n    long i;\n\n    GET_SCANNER(self, p);\n    i = NUM2INT(v);\n    if (i < 0) i += S_LEN(p);\n    if (i < 0) rb_raise(rb_eRangeError, \"index out of range\");\n    if (i > S_LEN(p)) rb_raise(rb_eRangeError, \"index out of range\");\n    p->curr = i;\n    return INT2NUM(i);\n}\n\nstatic VALUE\nstrscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)\n{\n    struct strscanner *p;\n    int ret;\n\n    Check_Type(regex, T_REGEXP);\n    GET_SCANNER(self, p);\n\n    CLEAR_MATCH_STATUS(p);\n    if (S_RESTLEN(p) < 0) {\n        return Qnil;\n    }\n    rb_kcode_set_option(regex);\n    if (headonly) {\n        ret = re_match(RREGEXP(regex)->ptr,\n                       CURPTR(p), S_RESTLEN(p),\n                       0,\n                       &(p->regs));\n    }\n    else {\n        ret = re_search(RREGEXP(regex)->ptr,\n                        CURPTR(p), S_RESTLEN(p),\n                        0,\n                        S_RESTLEN(p),\n                        &(p->regs));\n    }\n    rb_kcode_reset_option();\n\n    if (ret == -2) rb_raise(ScanError, \"regexp buffer overflow\");\n    if (ret < 0) {\n        /* not matched */\n        return Qnil;\n    }\n\n    MATCHED(p);\n    p->prev = p->curr;\n    if (succptr) {\n        p->curr += p->regs.end[0];\n    }\n    if (getstr) {\n        return extract_beg_len(p, p->prev, p->regs.end[0]);\n    }\n    else {\n        return INT2FIX(p->regs.end[0]);\n    }\n}\n\n/*\n * call-seq: scan(pattern) => String\n *\n * Tries to match with +pattern+ at the current position. If there's a match,\n * the scanner advances the \"scan pointer\" and returns the matched string.\n * Otherwise, the scanner returns +nil+.\n *\n *   s = StringScanner.new('test string')\n *   p s.scan(/\\w+/)   # -> \"test\"\n *   p s.scan(/\\w+/)   # -> nil\n *   p s.scan(/\\s+/)   # -> \" \"\n *   p s.scan(/\\w+/)   # -> \"string\"\n *   p s.scan(/./)     # -> nil\n *\n */\nstatic VALUE\nstrscan_scan(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 1, 1, 1);\n}\n\n/*\n * call-seq: match?(pattern)\n *\n * Tests whether the given +pattern+ is matched from the current scan pointer.\n * Returns the length of the match, or +nil+.  The scan pointer is not advanced.\n *\n *   s = StringScanner.new('test string')\n *   p s.match?(/\\w+/)   # -> 4\n *   p s.match?(/\\w+/)   # -> 4\n *   p s.match?(/\\s+/)   # -> nil\n */\nstatic VALUE\nstrscan_match_p(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 0, 0, 1);\n}\n\n/*\n * call-seq: skip(pattern)\n *\n * Attempts to skip over the given +pattern+ beginning with the scan pointer.\n * If it matches, the scan pointer is advanced to the end of the match, and the\n * length of the match is returned.  Otherwise, +nil+ is returned.\n *\n * It's similar to #scan, but without returning the matched string.\n *\n *   s = StringScanner.new('test string')\n *   p s.skip(/\\w+/)   # -> 4\n *   p s.skip(/\\w+/)   # -> nil\n *   p s.skip(/\\s+/)   # -> 1\n *   p s.skip(/\\w+/)   # -> 6\n *   p s.skip(/./)     # -> nil\n *\n */\nstatic VALUE\nstrscan_skip(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 1, 0, 1);\n}\n\n/*\n * call-seq: check(pattern)\n *\n * This returns the value that #scan would return, without advancing the scan\n * pointer.  The match register is affected, though.\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.check /Fri/               # -> \"Fri\"\n *   s.pos                       # -> 0\n *   s.matched                   # -> \"Fri\"\n *   s.check /12/                # -> nil\n *   s.matched                   # -> nil\n *\n * Mnemonic: it \"checks\" to see whether a #scan will return a value.\n */\nstatic VALUE\nstrscan_check(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 0, 1, 1);\n}\n\n/*\n * call-seq: scan_full(pattern, return_string_p, advance_pointer_p)\n *\n * Tests whether the given +pattern+ is matched from the current scan pointer.\n * Returns the matched string if +return_string_p+ is true.\n * Advances the scan pointer if +advance_pointer_p+ is true.\n * The match register is affected.\n *\n * \"full\" means \"#scan with full parameters\".\n */\nstatic VALUE\nstrscan_scan_full(VALUE self, VALUE re, VALUE s, VALUE f)\n{\n    return strscan_do_scan(self, re, RTEST(s), RTEST(f), 1);\n}\n\n\n/*\n * call-seq: scan_until(pattern)\n *\n * Scans the string _until_ the +pattern+ is matched.  Returns the substring up\n * to and including the end of the match, advancing the scan pointer to that\n * location. If there is no match, +nil+ is returned.\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.scan_until(/1/)        # -> \"Fri Dec 1\"\n *   s.pre_match              # -> \"Fri Dec \"\n *   s.scan_until(/XYZ/)      # -> nil\n */\nstatic VALUE\nstrscan_scan_until(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 1, 1, 0);\n}\n\n/*\n * call-seq: exist?(pattern)\n *\n * Looks _ahead_ to see if the +pattern+ exists _anywhere_ in the string,\n * without advancing the scan pointer.  This predicates whether a #scan_until\n * will return a value.\n *\n *   s = StringScanner.new('test string')\n *   s.exist? /s/            # -> 3\n *   s.scan /test/           # -> \"test\"\n *   s.exist? /s/            # -> 6\n *   s.exist? /e/            # -> nil\n */\nstatic VALUE\nstrscan_exist_p(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 0, 0, 0);\n}\n\n/*\n * call-seq: skip_until(pattern)\n *\n * Advances the scan pointer until +pattern+ is matched and consumed.  Returns\n * the number of bytes advanced, or +nil+ if no match was found.\n *\n * Look ahead to match +pattern+, and advance the scan pointer to the _end_\n * of the match.  Return the number of characters advanced, or +nil+ if the\n * match was unsuccessful.\n *\n * It's similar to #scan_until, but without returning the intervening string.\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.skip_until /12/           # -> 10\n *   s                           # \n */\nstatic VALUE\nstrscan_skip_until(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 1, 0, 0);\n}\n\n/*\n * call-seq: check_until(pattern)\n *\n * This returns the value that #scan_until would return, without advancing the\n * scan pointer.  The match register is affected, though.\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.check_until /12/          # -> \"Fri Dec 12\"\n *   s.pos                       # -> 0\n *   s.matched                   # -> 12\n *\n * Mnemonic: it \"checks\" to see whether a #scan_until will return a value.\n */\nstatic VALUE\nstrscan_check_until(VALUE self, VALUE re)\n{\n    return strscan_do_scan(self, re, 0, 1, 0);\n}\n\n/*\n * call-seq: search_full(pattern, return_string_p, advance_pointer_p)\n *\n * Scans the string _until_ the +pattern+ is matched.\n * Returns the matched string if +return_string_p+ is true, otherwise\n * returns the number of bytes advanced.\n * Advances the scan pointer if +advance_pointer_p+, otherwise not.\n * This method does affect the match register.\n */\nstatic VALUE\nstrscan_search_full(VALUE self, VALUE re, VALUE s, VALUE f)\n{\n    return strscan_do_scan(self, re, RTEST(s), RTEST(f), 0);\n}\n\n/* DANGEROUS; need to synchronize with regex.c */\nstatic void\nadjust_registers_to_matched(struct strscanner *p)\n{\n    if (p->regs.allocated == 0) {\n        p->regs.beg = ALLOC_N(int, RE_NREGS);\n        p->regs.end = ALLOC_N(int, RE_NREGS);\n        p->regs.allocated = RE_NREGS;\n    }\n    p->regs.num_regs = 1;\n    p->regs.beg[0] = 0;\n    p->regs.end[0] = p->curr - p->prev;\n}\n\n/*\n * Scans one character and returns it.\n * This method is multi-byte character sensitive.\n * See also #get_byte.\n *\n *   s = StringScanner.new('ab')\n *   s.getch           # => \"a\"\n *   s.getch           # => \"b\"\n *   s.getch           # => nil\n *\n *   $KCODE = 'EUC'\n *   s = StringScanner.new(\"\\244\\242\")\n *   s.getch           # => \"\\244\\242\"   # Japanese hira-kana \"A\" in EUC-JP\n *   s.getch           # => nil\n */\nstatic VALUE\nstrscan_getch(VALUE self)\n{\n    struct strscanner *p;\n    long len;\n\n    GET_SCANNER(self, p);\n    CLEAR_MATCH_STATUS(p);\n    if (EOS_P(p))\n        return Qnil;\n    len = mbclen(*CURPTR(p));\n    if (p->curr + len > S_LEN(p)) {\n        len = S_LEN(p) - p->curr;\n    }\n    p->prev = p->curr;\n    p->curr += len;\n    MATCHED(p);\n    adjust_registers_to_matched(p);\n    return extract_range(p, p->prev + p->regs.beg[0],\n                            p->prev + p->regs.end[0]);\n}\n\n/*\n * Scans one byte and returns it.\n * This method is NOT multi-byte character sensitive.\n * See also #getch.\n *\n *   s = StringScanner.new('ab')\n *   s.get_byte         # => \"a\"\n *   s.get_byte         # => \"b\"\n *   s.get_byte         # => nil\n *\n *   s = StringScanner.new(\"\\244\\242\")\n *   s.get_byte         # => \"\\244\"\n *   s.get_byte         # => \"\\242\"\n *   s.get_byte         # => nil\n */\nstatic VALUE\nstrscan_get_byte(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    CLEAR_MATCH_STATUS(p);\n    if (EOS_P(p)) {\n        return Qnil;\n    }\n    p->prev = p->curr;\n    p->curr++;\n    MATCHED(p);\n    adjust_registers_to_matched(p);\n    return extract_range(p, p->prev + p->regs.beg[0],\n                            p->prev + p->regs.end[0]);\n}\n\n/*\n * Equivalent to #get_byte.\n * This method is obsolete; use #get_byte instead.\n */\nstatic VALUE\nstrscan_getbyte(VALUE self)\n{\n    rb_warning(\"StringScanner#getbyte is obsolete; use #get_byte instead\");\n    return strscan_get_byte(self);\n}\n\n/*\n * call-seq: peek(len)\n *\n * Extracts a string corresponding to <tt>string[pos,len]</tt>, without\n * advancing the scan pointer.\n *\n *   s = StringScanner.new('test string')\n *   s.peek(7)          # => \"test st\"\n *   s.peek(7)          # => \"test st\"\n *\n */\nstatic VALUE\nstrscan_peek(VALUE self, VALUE vlen)\n{\n    struct strscanner *p;\n    long len;\n\n    GET_SCANNER(self, p);\n    len = NUM2LONG(vlen);\n    if (EOS_P(p)) {\n        return infect(rb_str_new(\"\", 0), p);\n    }\n    if (p->curr + len > S_LEN(p)) {\n        len = S_LEN(p) - p->curr;\n    }\n    return extract_beg_len(p, p->curr, len);\n}\n\n/*\n * Equivalent to #peek.\n * This method is obsolete; use #peek instead.\n */\nstatic VALUE\nstrscan_peep(VALUE self, VALUE vlen)\n{\n    rb_warning(\"StringScanner#peep is obsolete; use #peek instead\");\n    return strscan_peek(self, vlen);\n}\n\n/*\n * Set the scan pointer to the previous position.  Only one previous position is\n * remembered, and it changes with each scanning operation.\n *\n *   s = StringScanner.new('test string')\n *   s.scan(/\\w+/)        # => \"test\"\n *   s.unscan\n *   s.scan(/../)         # => \"te\"\n *   s.scan(/\\d/)         # => nil\n *   s.unscan             # ScanError: unscan failed: previous match had failed\n */\nstatic VALUE\nstrscan_unscan(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (! MATCHED_P(p)) {\n        rb_raise(ScanError, \"unscan failed: previous match had failed\");\n    }\n    p->curr = p->prev;\n    CLEAR_MATCH_STATUS(p);\n    return self;\n}\n\n/*\n * Returns +true+ iff the scan pointer is at the beginning of the line.\n *\n *   s = StringScanner.new(\"test\\ntest\\n\")\n *   s.bol?           # => true\n *   s.scan(/te/)\n *   s.bol?           # => false\n *   s.scan(/st\\n/)\n *   s.bol?           # => true\n *   s.terminate\n *   s.bol?           # => true\n */\nstatic VALUE\nstrscan_bol_p(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (CURPTR(p) > S_PEND(p)) return Qnil;\n    if (p->curr == 0) return Qtrue;\n    return (*(CURPTR(p) - 1) == '\\n') ? Qtrue : Qfalse;\n}\n\n/*\n * Returns +true+ if the scan pointer is at the end of the string.\n *\n *   s = StringScanner.new('test string')\n *   p s.eos?          # => false\n *   s.scan(/test/)\n *   p s.eos?          # => false\n *   s.terminate\n *   p s.eos?          # => true\n */\nstatic VALUE\nstrscan_eos_p(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    return EOS_P(p) ? Qtrue : Qfalse;\n}\n\n/*\n * Equivalent to #eos?.\n * This method is obsolete, use #eos? instead.\n */\nstatic VALUE\nstrscan_empty_p(VALUE self)\n{\n    rb_warning(\"StringScanner#empty? is obsolete; use #eos? instead\");\n    return strscan_eos_p(self);\n}\n\n/*\n * Returns true iff there is more data in the string.  See #eos?.\n * This method is obsolete; use #eos? instead.\n *\n *   s = StringScanner.new('test string')\n *   s.eos?              # These two\n *   s.rest?             # are opposites.\n */\nstatic VALUE\nstrscan_rest_p(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    return EOS_P(p) ? Qfalse : Qtrue;\n}\n\n/*\n * Returns +true+ iff the last match was successful.\n *\n *   s = StringScanner.new('test string')\n *   s.match?(/\\w+/)     # => 4\n *   s.matched?          # => true\n *   s.match?(/\\d+/)     # => nil\n *   s.matched?          # => false\n */\nstatic VALUE\nstrscan_matched_p(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    return MATCHED_P(p) ? Qtrue : Qfalse;\n}\n\n/*\n * Returns the last matched string.\n * \n *   s = StringScanner.new('test string')\n *   s.match?(/\\w+/)     # -> 4\n *   s.matched           # -> \"test\"\n */\nstatic VALUE\nstrscan_matched(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (! MATCHED_P(p)) return Qnil;\n\n    return extract_range(p, p->prev + p->regs.beg[0],\n                            p->prev + p->regs.end[0]);\n}\n\n/*\n * Returns the size of the most recent match (see #matched), or +nil+ if there\n * was no recent match.\n *\n *   s = StringScanner.new('test string')\n *   s.check /\\w+/           # -> \"test\"\n *   s.matched_size          # -> 4\n *   s.check /\\d+/           # -> nil\n *   s.matched_size          # -> nil\n */\nstatic VALUE\nstrscan_matched_size(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (! MATCHED_P(p)) return Qnil;\n\n    return INT2NUM(p->regs.end[0] - p->regs.beg[0]);\n}\n\n/*\n * Equivalent to #matched_size.\n * This method is obsolete; use #matched_size instead.\n */\nstatic VALUE\nstrscan_matchedsize(VALUE self)\n{\n    rb_warning(\"StringScanner#matchedsize is obsolete; use #matched_size instead\");\n    return strscan_matched_size(self);\n}\n\n/*\n * call-seq: [](n)\n *\n * Return the n-th subgroup in the most recent match.\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.scan(/(\\w+) (\\w+) (\\d+) /)       # -> \"Fri Dec 12 \"\n *   s[0]                               # -> \"Fri Dec 12 \"\n *   s[1]                               # -> \"Fri\"\n *   s[2]                               # -> \"Dec\"\n *   s[3]                               # -> \"12\"\n *   s.post_match                       # -> \"1975 14:39\"\n *   s.pre_match                        # -> \"\"\n */\nstatic VALUE\nstrscan_aref(VALUE self, VALUE idx)\n{\n    struct strscanner *p;\n    long i;\n\n    GET_SCANNER(self, p);\n    if (! MATCHED_P(p))        return Qnil;\n    \n    i = NUM2LONG(idx);\n    if (i < 0)\n        i += p->regs.num_regs;\n    if (i < 0)                 return Qnil;\n    if (i >= p->regs.num_regs) return Qnil;\n    if (p->regs.beg[i] == -1)  return Qnil;\n\n    return extract_range(p, p->prev + p->regs.beg[i],\n                            p->prev + p->regs.end[i]);\n}\n\n/*\n * Return the <i><b>pre</b>-match</i> (in the regular expression sense) of the last scan.\n *\n *   s = StringScanner.new('test string')\n *   s.scan(/\\w+/)           # -> \"test\"\n *   s.scan(/\\s+/)           # -> \" \"\n *   s.pre_match             # -> \"test\"\n *   s.post_match            # -> \"string\"\n */\nstatic VALUE\nstrscan_pre_match(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (! MATCHED_P(p)) return Qnil;\n\n    return extract_range(p, 0, p->prev + p->regs.beg[0]);\n}\n\n/*\n * Return the <i><b>post</b>-match</i> (in the regular expression sense) of the last scan.\n *\n *   s = StringScanner.new('test string')\n *   s.scan(/\\w+/)           # -> \"test\"\n *   s.scan(/\\s+/)           # -> \" \"\n *   s.pre_match             # -> \"test\"\n *   s.post_match            # -> \"string\"\n */\nstatic VALUE\nstrscan_post_match(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (! MATCHED_P(p)) return Qnil;\n\n    return extract_range(p, p->prev + p->regs.end[0], S_LEN(p));\n}\n\n/*\n * Returns the \"rest\" of the string (i.e. everything after the scan pointer).\n * If there is no more data (eos? = true), it returns <tt>\"\"</tt>.\n */\nstatic VALUE\nstrscan_rest(VALUE self)\n{\n    struct strscanner *p;\n\n    GET_SCANNER(self, p);\n    if (EOS_P(p)) {\n        return infect(rb_str_new(\"\", 0), p);\n    }\n    return extract_range(p, p->curr, S_LEN(p));\n}\n\n/*\n * <tt>s.rest_size</tt> is equivalent to <tt>s.rest.size</tt>.\n */\nstatic VALUE\nstrscan_rest_size(VALUE self)\n{\n    struct strscanner *p;\n    long i;\n\n    GET_SCANNER(self, p);\n    if (EOS_P(p)) {\n        return INT2FIX(0);\n    }\n\n    i = S_LEN(p) - p->curr;\n    return INT2FIX(i);\n}\n\n/*\n * <tt>s.restsize</tt> is equivalent to <tt>s.rest_size</tt>.\n * This method is obsolete; use #rest_size instead.\n */\nstatic VALUE\nstrscan_restsize(VALUE self)\n{\n    rb_warning(\"StringScanner#restsize is obsolete; use #rest_size instead\");\n    return strscan_rest_size(self);\n}\n\n#define INSPECT_LENGTH 5\n#define BUFSIZE 256\n\n/*\n * Returns a string that represents the StringScanner object, showing:\n * - the current position\n * - the size of the string\n * - the characters surrounding the scan pointer\n *\n *   s = StringScanner.new(\"Fri Dec 12 1975 14:39\")\n *   s.inspect            # -> '#<StringScanner 0/21 @ \"Fri D...\">'\n *   s.scan_until /12/    # -> \"Fri Dec 12\"\n *   s.inspect            # -> '#<StringScanner 10/21 \"...ec 12\" @ \" 1975...\">'\n */\nstatic VALUE\nstrscan_inspect(VALUE self)\n{\n    struct strscanner *p;\n    char buf[BUFSIZE];\n    long len;\n    VALUE a, b;\n\n    Data_Get_Struct(self, struct strscanner, p);\n    if (NIL_P(p->str)) {\n        len = snprintf(buf, BUFSIZE, \"#<%s (uninitialized)>\",\n                       rb_class2name(CLASS_OF(self)));\n        return infect(rb_str_new(buf, len), p);\n    }\n    if (EOS_P(p)) {\n        len = snprintf(buf, BUFSIZE, \"#<%s fin>\",\n                       rb_class2name(CLASS_OF(self)));\n        return infect(rb_str_new(buf, len), p);\n    }\n    if (p->curr == 0) {\n        b = inspect2(p);\n        len = snprintf(buf, BUFSIZE, \"#<%s %ld/%ld @ %s>\",\n                       rb_class2name(CLASS_OF(self)),\n                       p->curr, S_LEN(p),\n                       RSTRING(b)->ptr);\n        return infect(rb_str_new(buf, len), p);\n    }\n    a = inspect1(p);\n    b = inspect2(p);\n    len = snprintf(buf, BUFSIZE, \"#<%s %ld/%ld %s @ %s>\",\n                   rb_class2name(CLASS_OF(self)),\n                   p->curr, S_LEN(p),\n                   RSTRING(a)->ptr,\n                   RSTRING(b)->ptr);\n    return infect(rb_str_new(buf, len), p);\n}\n\nstatic VALUE\ninspect1(struct strscanner *p)\n{\n    char buf[BUFSIZE];\n    char *bp = buf;\n    long len;\n\n    if (p->curr == 0) return rb_str_new2(\"\");\n    if (p->curr > INSPECT_LENGTH) {\n        strcpy(bp, \"...\"); bp += 3;\n        len = INSPECT_LENGTH;\n    }\n    else {\n        len = p->curr;\n    }\n    memcpy(bp, CURPTR(p) - len, len); bp += len;\n    return rb_str_dump(rb_str_new(buf, bp - buf));\n}\n\nstatic VALUE\ninspect2(struct strscanner *p)\n{\n    char buf[BUFSIZE];\n    char *bp = buf;\n    long len;\n\n    if (EOS_P(p)) return rb_str_new2(\"\");\n    len = S_LEN(p) - p->curr;\n    if (len > INSPECT_LENGTH) {\n        len = INSPECT_LENGTH;\n        memcpy(bp, CURPTR(p), len); bp += len;\n        strcpy(bp, \"...\"); bp += 3;\n    }\n    else {\n        memcpy(bp, CURPTR(p), len); bp += len;\n    }\n    return rb_str_dump(rb_str_new(buf, bp - buf));\n}\n\n/* =======================================================================\n                              Ruby Interface\n   ======================================================================= */\n\n/*\n * Document-class: StringScanner\n * \n * StringScanner provides for lexical scanning operations on a String.  Here is\n * an example of its usage:\n *\n *   s = StringScanner.new('This is an example string')\n *   s.eos?               # -> false\n *   \n *   p s.scan(/\\w+/)      # -> \"This\"\n *   p s.scan(/\\w+/)      # -> nil\n *   p s.scan(/\\s+/)      # -> \" \"\n *   p s.scan(/\\s+/)      # -> nil\n *   p s.scan(/\\w+/)      # -> \"is\"\n *   s.eos?               # -> false\n *   \n *   p s.scan(/\\s+/)      # -> \" \"\n *   p s.scan(/\\w+/)      # -> \"an\"\n *   p s.scan(/\\s+/)      # -> \" \"\n *   p s.scan(/\\w+/)      # -> \"example\"\n *   p s.scan(/\\s+/)      # -> \" \"\n *   p s.scan(/\\w+/)      # -> \"string\"\n *   s.eos?               # -> true\n *   \n *   p s.scan(/\\s+/)      # -> nil\n *   p s.scan(/\\w+/)      # -> nil\n *\n * Scanning a string means remembering the position of a <i>scan pointer</i>,\n * which is just an index.  The point of scanning is to move forward a bit at\n * a time, so matches are sought after the scan pointer; usually immediately\n * after it.\n *\n * Given the string \"test string\", here are the pertinent scan pointer\n * positions:\n *\n *     t e s t   s t r i n g\n *   0 1 2 ...             1\n *                         0\n *\n * When you #scan for a pattern (a regular expression), the match must occur\n * at the character after the scan pointer.  If you use #scan_until, then the\n * match can occur anywhere after the scan pointer.  In both cases, the scan\n * pointer moves <i>just beyond</i> the last character of the match, ready to\n * scan again from the next character onwards.  This is demonstrated by the\n * example above.\n *\n * == Method Categories\n *\n * There are other methods besides the plain scanners.  You can look ahead in\n * the string without actually scanning.  You can access the most recent match.\n * You can modify the string being scanned, reset or terminate the scanner,\n * find out or change the position of the scan pointer, skip ahead, and so on.\n * \n * === Advancing the Scan Pointer\n *\n * - #getch\n * - #get_byte\n * - #scan\n * - #scan_until\n * - #skip\n * - #skip_until\n *\n * === Looking Ahead\n *\n * - #check\n * - #check_until\n * - #exist?\n * - #match?\n * - #peek\n *\n * === Finding Where we Are\n *\n * - #beginning_of_line? (#bol?)\n * - #eos?\n * - #rest?\n * - #rest_size\n * - #pos\n *\n * === Setting Where we Are\n *\n * - #reset\n * - #terminate\n * - #pos=\n * \n * === Match Data\n *\n * - #matched\n * - #matched?\n * - #matched_size\n * - []\n * - #pre_match\n * - #post_match\n *\n * === Miscellaneous\n *\n * - <<\n * - #concat\n * - #string\n * - #string=\n * - #unscan\n *\n * There are aliases to several of the methods.\n */\nvoid\nInit_strscan(void)\n{\n    ID id_scanerr = rb_intern(\"ScanError\");\n    VALUE tmp;\n\n    StringScanner = rb_define_class(\"StringScanner\", rb_cObject);\n    ScanError = rb_define_class_under(StringScanner, \"Error\", rb_eStandardError);\n    if (!rb_const_defined(rb_cObject, id_scanerr)) {\n\trb_const_set(rb_cObject, id_scanerr, ScanError);\n    }\n    tmp = rb_str_new2(STRSCAN_VERSION);\n    rb_obj_freeze(tmp);\n    rb_const_set(StringScanner, rb_intern(\"Version\"), tmp);\n    tmp = rb_str_new2(\"$Id$\");\n    rb_obj_freeze(tmp);\n    rb_const_set(StringScanner, rb_intern(\"Id\"), tmp);\n    \n    rb_define_alloc_func(StringScanner, strscan_s_allocate);\n    rb_define_private_method(StringScanner, \"initialize\", strscan_initialize, -1);\n    rb_define_private_method(StringScanner, \"initialize_copy\", strscan_init_copy, 1);\n    rb_define_singleton_method(StringScanner, \"must_C_version\", strscan_s_mustc, 0);\n    rb_define_method(StringScanner, \"reset\",       strscan_reset,       0);\n    rb_define_method(StringScanner, \"terminate\",   strscan_terminate,   0);\n    rb_define_method(StringScanner, \"clear\",       strscan_clear,       0);\n    rb_define_method(StringScanner, \"string\",      strscan_get_string,  0);\n    rb_define_method(StringScanner, \"string=\",     strscan_set_string,  1);\n    rb_define_method(StringScanner, \"concat\",      strscan_concat,      1);\n    rb_define_method(StringScanner, \"<<\",          strscan_concat,      1);\n    rb_define_method(StringScanner, \"pos\",         strscan_get_pos,     0);\n    rb_define_method(StringScanner, \"pos=\",        strscan_set_pos,     1);\n    rb_define_method(StringScanner, \"pointer\",     strscan_get_pos,     0);\n    rb_define_method(StringScanner, \"pointer=\",    strscan_set_pos,     1);\n\n    rb_define_method(StringScanner, \"scan\",        strscan_scan,        1);\n    rb_define_method(StringScanner, \"skip\",        strscan_skip,        1);\n    rb_define_method(StringScanner, \"match?\",      strscan_match_p,     1);\n    rb_define_method(StringScanner, \"check\",       strscan_check,       1);\n    rb_define_method(StringScanner, \"scan_full\",   strscan_scan_full,   3);\n\n    rb_define_method(StringScanner, \"scan_until\",  strscan_scan_until,  1);\n    rb_define_method(StringScanner, \"skip_until\",  strscan_skip_until,  1);\n    rb_define_method(StringScanner, \"exist?\",      strscan_exist_p,     1);\n    rb_define_method(StringScanner, \"check_until\", strscan_check_until, 1);\n    rb_define_method(StringScanner, \"search_full\", strscan_search_full, 3);\n\n    rb_define_method(StringScanner, \"getch\",       strscan_getch,       0);\n    rb_define_method(StringScanner, \"get_byte\",    strscan_get_byte,    0);\n    rb_define_method(StringScanner, \"getbyte\",     strscan_getbyte,     0);\n    rb_define_method(StringScanner, \"peek\",        strscan_peek,        1);\n    rb_define_method(StringScanner, \"peep\",        strscan_peep,        1);\n\n    rb_define_method(StringScanner, \"unscan\",      strscan_unscan,      0);\n\n    rb_define_method(StringScanner, \"beginning_of_line?\", strscan_bol_p, 0);\n    rb_alias(StringScanner, rb_intern(\"bol?\"), rb_intern(\"beginning_of_line?\"));\n    rb_define_method(StringScanner, \"eos?\",        strscan_eos_p,       0);\n    rb_define_method(StringScanner, \"empty?\",      strscan_empty_p,     0);\n    rb_define_method(StringScanner, \"rest?\",       strscan_rest_p,      0);\n\n    rb_define_method(StringScanner, \"matched?\",    strscan_matched_p,   0);\n    rb_define_method(StringScanner, \"matched\",     strscan_matched,     0);\n    rb_define_method(StringScanner, \"matched_size\", strscan_matched_size, 0);\n    rb_define_method(StringScanner, \"matchedsize\", strscan_matchedsize, 0);\n    rb_define_method(StringScanner, \"[]\",          strscan_aref,        1);\n    rb_define_method(StringScanner, \"pre_match\",   strscan_pre_match,   0);\n    rb_define_method(StringScanner, \"post_match\",  strscan_post_match,  0);\n\n    rb_define_method(StringScanner, \"rest\",        strscan_rest,        0);\n    rb_define_method(StringScanner, \"rest_size\",   strscan_rest_size,   0);\n    rb_define_method(StringScanner, \"restsize\",    strscan_restsize,    0);\n\n    rb_define_method(StringScanner, \"inspect\",     strscan_inspect,     0);\n}\n"
  },
  {
    "path": "ext/syck/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/syck/bytecode.c",
    "content": "/* Generated by re2c 0.9.10 on Mon Sep 19 23:21:26 2005 */\n#line 1 \"bytecode.re\"\n/*\n * bytecode.re\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n#include \"ruby.h\"\n#include \"syck.h\"\n#include \"gram.h\"\n\n#define QUOTELEN 128\n\n/*\n * They do my bidding...\n */\n#define YYCTYPE     char\n#define YYCURSOR    parser->cursor\n#define YYMARKER    parser->marker\n#define YYLIMIT     parser->limit\n#define YYTOKEN     parser->token\n#define YYTOKTMP    parser->toktmp\n#define YYLINEPTR   parser->lineptr\n#define YYLINECTPTR parser->linectptr\n#define YYLINE      parser->linect\n#define YYFILL(n)   syck_parser_read(parser)\n\nextern SyckParser *syck_parser_ptr;\n\nchar *get_inline( SyckParser *parser );\n\n/*\n * Repositions the cursor at `n' offset from the token start.\n * Only works in `Header' and `Document' sections.\n */\n#define YYPOS(n)    YYCURSOR = YYTOKEN + n\n\n/*\n * Track line numbers\n */\n#define CHK_NL(ptr)    if ( *( ptr - 1 ) == '\\n' && ptr > YYLINECTPTR ) { YYLINEPTR = ptr; YYLINE++; YYLINECTPTR = YYLINEPTR; }\n\n/*\n * I like seeing the level operations as macros...\n */\n#define ADD_LEVEL(len, status)  syck_parser_add_level( parser, len, status )\n#define POP_LEVEL()     syck_parser_pop_level( parser )\n#define CURRENT_LEVEL() syck_parser_current_level( parser )\n\n/*\n * Force a token next time around sycklex()\n */\n#define FORCE_NEXT_TOKEN(tok)    parser->force_token = tok;\n\n/*\n * Adding levels in bytecode requires us to make sure\n * we've got all our tokens worked out.\n */\n#define ADD_BYTE_LEVEL(lvl, len, s ) \\\n        switch ( lvl->status ) \\\n        { \\\n            case syck_lvl_seq: \\\n                lvl->ncount++; \\\n                ADD_LEVEL(len, syck_lvl_open); \\\n                YYPOS(0); \\\n            return '-'; \\\n        \\\n            case syck_lvl_map: \\\n                lvl->ncount++; \\\n                ADD_LEVEL(len, s); \\\n            break; \\\n        \\\n            case syck_lvl_open: \\\n                lvl->status = s; \\\n            break; \\\n        \\\n            default: \\\n                ADD_LEVEL(len, s); \\\n            break; \\\n        }\n\n/*\n * Nice little macro to ensure we're YAML_IOPENed to the current level.\n * * Only use this macro in the \"Document\" section *\n */\n#define ENSURE_YAML_IOPEN(last_lvl, lvl_type, to_len, reset) \\\n        if ( last_lvl->spaces < to_len ) \\\n        { \\\n            if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \\\n            { \\\n                goto Document; \\\n            } \\\n            else \\\n            { \\\n                ADD_LEVEL( to_len, lvl_type ); \\\n                if ( reset == 1 ) YYPOS(0); \\\n                return YAML_IOPEN; \\\n            } \\\n        } \n\n/*\n * Nice little macro to ensure closure of levels.\n * * Only use this macro in the \"Document\" section *\n */\n#define ENSURE_YAML_IEND(last_lvl, to_len) \\\n        if ( last_lvl->spaces > to_len ) \\\n        { \\\n            syck_parser_pop_level( parser ); \\\n            YYPOS(0); \\\n            return YAML_IEND; \\\n        }\n\n/*\n * Concatenates string items and manages allocation\n * to the string\n */\n#define CAT(s, c, i, l) \\\n        { \\\n            if ( i + 1 >= c ) \\\n            { \\\n                c += QUOTELEN; \\\n                S_REALLOC_N( s, char, c ); \\\n            } \\\n            s[i++] = l; \\\n            s[i] = '\\0'; \\\n        }\n\n/*\n * Parser for standard YAML Bytecode [UTF-8]\n */\nint\nsycklex_bytecode_utf8( YYSTYPE *sycklval, SyckParser *parser )\n{\n    SyckLevel *lvl;\n    syck_parser_ptr = parser;\n    if ( YYCURSOR == NULL ) \n    {\n        syck_parser_read( parser );\n    }\n\n    if ( parser->force_token != 0 )\n    {\n        int t = parser->force_token;\n        parser->force_token = 0;\n        return t;\n    }\n\n#line 172 \"bytecode.re\"\n\n\n    lvl = CURRENT_LEVEL();\n    if ( lvl->status == syck_lvl_doc )\n    {\n        goto Document;\n    }\n\n/* Header: */\n\n    YYTOKEN = YYCURSOR;\n\n\n#line 165 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy0;\n\t++YYCURSOR;\nyy0:\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy2;\n\tcase 'D':\tgoto yy3;\n\tdefault:\tgoto yy5;\n\t}\nyy2:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy4;\n\t}\nyy3:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy6;\n\tcase 0x0D:\tgoto yy8;\n\tdefault:\tgoto yy4;\n\t}\nyy4:\n#line 199 \"bytecode.re\"\n{   YYPOS(0);\n            goto Document;\n        }\n#line 195 \"<stdout>\"\nyy5:\tyych = *++YYCURSOR;\n\tgoto yy4;\nyy6:\t++YYCURSOR;\n\tgoto yy7;\nyy7:\n#line 186 \"bytecode.re\"\n{   if ( lvl->status == syck_lvl_header )\n            {\n                CHK_NL(YYCURSOR);\n                goto Directive;\n            }\n            else\n            {\n                ENSURE_YAML_IEND(lvl, -1);\n                YYPOS(0);\n                return 0;\n            }\n        }\n#line 214 \"<stdout>\"\nyy8:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy6;\n\tdefault:\tgoto yy2;\n\t}\n}\n#line 203 \"bytecode.re\"\n\n\nDocument:\n    {\n        lvl = CURRENT_LEVEL();\n        if ( lvl->status == syck_lvl_header )\n        {\n            lvl->status = syck_lvl_doc;\n        }\n\n        YYTOKEN = YYCURSOR;\n\n\n#line 235 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tgoto yy9;\n\t++YYCURSOR;\nyy9:\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy30;\n\tcase 0x0A:\tgoto yy27;\n\tcase 0x0D:\tgoto yy29;\n\tcase 'A':\tgoto yy19;\n\tcase 'D':\tgoto yy12;\n\tcase 'E':\tgoto yy16;\n\tcase 'M':\tgoto yy14;\n\tcase 'P':\tgoto yy13;\n\tcase 'Q':\tgoto yy15;\n\tcase 'R':\tgoto yy21;\n\tcase 'S':\tgoto yy17;\n\tcase 'T':\tgoto yy23;\n\tcase 'c':\tgoto yy25;\n\tdefault:\tgoto yy11;\n\t}\nyy11:yy12:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy41;\n\tcase 0x0D:\tgoto yy44;\n\tdefault:\tgoto yy11;\n\t}\nyy13:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy41;\n\tcase 0x0D:\tgoto yy43;\n\tdefault:\tgoto yy11;\n\t}\nyy14:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy38;\n\tcase 0x0D:\tgoto yy40;\n\tdefault:\tgoto yy11;\n\t}\nyy15:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy35;\n\tcase 0x0D:\tgoto yy37;\n\tdefault:\tgoto yy11;\n\t}\nyy16:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy32;\n\tcase 0x0D:\tgoto yy34;\n\tdefault:\tgoto yy11;\n\t}\nyy17:\t++YYCURSOR;\n\tgoto yy18;\nyy18:\n#line 288 \"bytecode.re\"\n{   ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_str); \n            goto Scalar;\n        }\n#line 296 \"<stdout>\"\nyy19:\t++YYCURSOR;\n\tgoto yy20;\nyy20:\n#line 292 \"bytecode.re\"\n{   ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_open);\n            sycklval->name = get_inline( parser );\n            syck_hdlr_remove_anchor( parser, sycklval->name );\n            CHK_NL(YYCURSOR);\n            return YAML_ANCHOR;\n        }\n#line 307 \"<stdout>\"\nyy21:\t++YYCURSOR;\n\tgoto yy22;\nyy22:\n#line 299 \"bytecode.re\"\n{   ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_str);\n            sycklval->name = get_inline( parser );\n            POP_LEVEL();\n            if ( *( YYCURSOR - 1 ) == '\\n' ) YYCURSOR--;\n            return YAML_ALIAS;\n        }\n#line 318 \"<stdout>\"\nyy23:\t++YYCURSOR;\n\tgoto yy24;\nyy24:\n#line 306 \"bytecode.re\"\n{   char *qstr;\n            ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_open);\n            qstr = get_inline( parser );\n            CHK_NL(YYCURSOR);\n            if ( qstr[0] == '!' )\n            {\n                int qidx = strlen( qstr );\n                if ( qstr[1] == '\\0' )\n                {\n                    free( qstr );\n                    return YAML_ITRANSFER;\n                }\n\n                lvl = CURRENT_LEVEL();\n\n                /*\n                 * URL Prefixing\n                 */\n                if ( qstr[1] == '^' )\n                {\n                    sycklval->name = S_ALLOC_N( char, qidx + strlen( lvl->domain ) );\n                    sycklval->name[0] = '\\0';\n                    strcat( sycklval->name, lvl->domain );\n                    strncat( sycklval->name, qstr + 2, qidx - 2 );\n                    free( qstr );\n                }\n                else\n                {\n                    char *carat = qstr + 1;\n                    char *qend = qstr + qidx;\n                    while ( (++carat) < qend )\n                    {\n                        if ( *carat == '^' )\n                            break;\n                    }\n\n                    if ( carat < qend )\n                    {\n                        free( lvl->domain );\n                        lvl->domain = syck_strndup( qstr + 1, carat - ( qstr + 1 ) );\n                        sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) );\n                        sycklval->name[0] = '\\0';\n                        strcat( sycklval->name, lvl->domain );\n                        strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 );\n                        free( qstr );\n                    }\n                    else\n                    {\n                        sycklval->name = S_ALLOC_N( char, strlen( qstr ) );\n                        sycklval->name[0] = '\\0';\n                        S_MEMCPY( sycklval->name, qstr + 1, char, strlen( qstr ) );\n                        free( qstr );\n                    }\n                }\n                return YAML_TRANSFER;\n            }\n            sycklval->name = qstr;\n            return YAML_TAGURI;\n        }\n#line 382 \"<stdout>\"\nyy25:\t++YYCURSOR;\n\tgoto yy26;\nyy26:\n#line 366 \"bytecode.re\"\n{   goto Comment; }\n#line 388 \"<stdout>\"\nyy27:\t++YYCURSOR;\n\tgoto yy28;\nyy28:\n#line 368 \"bytecode.re\"\n{   CHK_NL(YYCURSOR);\n            if ( lvl->status == syck_lvl_seq )\n            {\n                return YAML_INDENT; \n            }\n            else if ( lvl->status == syck_lvl_map )\n            {\n                if ( lvl->ncount % 2 == 1 ) return ':';\n                else                        return YAML_INDENT;\n            }\n            goto Document;\n        }\n#line 405 \"<stdout>\"\nyy29:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy27;\n\tdefault:\tgoto yy11;\n\t}\nyy30:\t++YYCURSOR;\n\tgoto yy31;\nyy31:\n#line 381 \"bytecode.re\"\n{   ENSURE_YAML_IEND(lvl, -1);\n            YYPOS(0);\n            return 0;\n        }\n#line 419 \"<stdout>\"\nyy32:\t++YYCURSOR;\n\tgoto yy33;\nyy33:\n#line 252 \"bytecode.re\"\n{   if ( lvl->status == syck_lvl_seq && lvl->ncount == 0 )\n            {\n                lvl->ncount++;\n                YYPOS(0);\n                FORCE_NEXT_TOKEN( ']' );\n                return '[';\n            }\n            else if ( lvl->status == syck_lvl_map && lvl->ncount == 0 )\n            {\n                lvl->ncount++;\n                YYPOS(0);\n                FORCE_NEXT_TOKEN( '}' );\n                return '{';\n            }\n            \n            POP_LEVEL();\n            lvl = CURRENT_LEVEL();\n            if ( lvl->status == syck_lvl_seq )\n            {\n                FORCE_NEXT_TOKEN(YAML_INDENT);   \n            }\n            else if ( lvl->status == syck_lvl_map )\n            {\n                if ( lvl->ncount % 2 == 1 )\n                {\n                    FORCE_NEXT_TOKEN(':');\n                }\n                else\n                {\n                    FORCE_NEXT_TOKEN(YAML_INDENT);\n                }\n            }\n            CHK_NL(YYCURSOR);\n            return YAML_IEND;\n        }\n#line 459 \"<stdout>\"\nyy34:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy32;\n\tdefault:\tgoto yy11;\n\t}\nyy35:\t++YYCURSOR;\n\tgoto yy36;\nyy36:\n#line 237 \"bytecode.re\"\n{   int complex = 0;\n            if ( lvl->ncount % 2 == 0 && ( lvl->status == syck_lvl_map || lvl->status == syck_lvl_seq ) )\n            {\n                complex = 1;\n            }\n            ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_seq);\n            CHK_NL(YYCURSOR);\n            if ( complex )\n            {\n                FORCE_NEXT_TOKEN( YAML_IOPEN );\n                return '?';\n            }\n            return YAML_IOPEN;\n        }\n#line 483 \"<stdout>\"\nyy37:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy35;\n\tdefault:\tgoto yy11;\n\t}\nyy38:\t++YYCURSOR;\n\tgoto yy39;\nyy39:\n#line 222 \"bytecode.re\"\n{   int complex = 0;\n            if ( lvl->ncount % 2 == 0 && ( lvl->status == syck_lvl_map || lvl->status == syck_lvl_seq ) )\n            {\n                complex = 1;\n            }\n            ADD_BYTE_LEVEL(lvl, lvl->spaces + 1, syck_lvl_map); \n            CHK_NL(YYCURSOR);\n            if ( complex )\n            {\n                FORCE_NEXT_TOKEN( YAML_IOPEN );\n                return '?';\n            }\n            return YAML_IOPEN;\n        }\n#line 507 \"<stdout>\"\nyy40:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy38;\n\tdefault:\tgoto yy11;\n\t}\nyy41:\t++YYCURSOR;\n\tgoto yy42;\nyy42:\n#line 217 \"bytecode.re\"\n{   ENSURE_YAML_IEND(lvl, -1);\n                YYPOS(0);\n                return 0;\n            }\n#line 521 \"<stdout>\"\nyy43:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy41;\n\tdefault:\tgoto yy11;\n\t}\nyy44:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy41;\n\tdefault:\tgoto yy11;\n\t}\n}\n#line 386 \"bytecode.re\"\n\n\n    }\n\nDirective:\n    {\n        YYTOKEN = YYCURSOR;\n\n\n#line 543 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy45;\n\t++YYCURSOR;\nyy45:\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy47;\n\tcase 'V':\tgoto yy48;\n\tdefault:\tgoto yy50;\n\t}\nyy47:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy49;\n\t}\nyy48:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy51;\n\tdefault:\tgoto yy49;\n\t}\nyy49:\n#line 399 \"bytecode.re\"\n{   YYCURSOR = YYTOKEN;\n               return YAML_DOCSEP;\n           }\n#line 646 \"<stdout>\"\nyy50:\tyych = *++YYCURSOR;\n\tgoto yy49;\nyy51:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy52;\nyy52:\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy51;\n\tcase ':':\tgoto yy53;\n\tdefault:\tgoto yy47;\n\t}\nyy53:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy54;\n\tdefault:\tgoto yy47;\n\t}\nyy54:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy55;\nyy55:\tswitch(yych){\n\tcase 0x0A:\tgoto yy56;\n\tcase 0x0D:\tgoto yy58;\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy54;\n\tdefault:\tgoto yy47;\n\t}\nyy56:\t++YYCURSOR;\n\tgoto yy57;\nyy57:\n#line 396 \"bytecode.re\"\n{   CHK_NL(YYCURSOR);\n               goto Directive; }\n#line 899 \"<stdout>\"\nyy58:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy56;\n\tdefault:\tgoto yy47;\n\t}\n}\n#line 402 \"bytecode.re\"\n\n\n    }\n\nComment:\n    {\n        YYTOKEN = YYCURSOR;\n\n\n#line 916 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tgoto yy59;\n\t++YYCURSOR;\nyy59:\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy61;\n\tcase 0x0A:\tgoto yy62;\n\tcase 0x0D:\tgoto yy64;\n\tdefault:\tgoto yy66;\n\t}\nyy61:yy62:\t++YYCURSOR;\n\tgoto yy63;\nyy63:\n#line 412 \"bytecode.re\"\n{   CHK_NL(YYCURSOR);\n                goto Document; }\n#line 936 \"<stdout>\"\nyy64:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy67;\n\tdefault:\tgoto yy65;\n\t}\nyy65:\n#line 415 \"bytecode.re\"\n{   goto Comment; }\n#line 945 \"<stdout>\"\nyy66:\tyych = *++YYCURSOR;\n\tgoto yy65;\nyy67:\t++YYCURSOR;\n\tyych = *YYCURSOR;\n\tgoto yy63;\n}\n#line 417 \"bytecode.re\"\n\n\n    }\n\nScalar:\n    {\n    int idx = 0;\n    int cap = 100;\n    char *str = S_ALLOC_N( char, cap );\n    char *tok;\n\n    str[0] = '\\0';\n\nScalar2:\n    tok = YYCURSOR;\n\n\n#line 970 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tgoto yy68;\n\t++YYCURSOR;\nyy68:\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy74;\n\tcase 0x0A:\tgoto yy70;\n\tcase 0x0D:\tgoto yy72;\n\tdefault:\tgoto yy76;\n\t}\nyy70:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 'C':\tgoto yy78;\n\tcase 'N':\tgoto yy80;\n\tcase 'Z':\tgoto yy83;\n\tdefault:\tgoto yy71;\n\t}\nyy71:\n#line 461 \"bytecode.re\"\n{   YYCURSOR = tok;\n            goto ScalarEnd; \n        }\n#line 996 \"<stdout>\"\nyy72:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy77;\n\tdefault:\tgoto yy73;\n\t}\nyy73:\n#line 469 \"bytecode.re\"\n{   CAT(str, cap, idx, tok[0]);\n            goto Scalar2; \n        }\n#line 1007 \"<stdout>\"\nyy74:\t++YYCURSOR;\n\tgoto yy75;\nyy75:\n#line 465 \"bytecode.re\"\n{   YYCURSOR = tok;\n            goto ScalarEnd;\n        }\n#line 1015 \"<stdout>\"\nyy76:\tyych = *++YYCURSOR;\n\tgoto yy73;\nyy77:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'C':\tgoto yy78;\n\tcase 'N':\tgoto yy80;\n\tcase 'Z':\tgoto yy83;\n\tdefault:\tgoto yy71;\n\t}\nyy78:\t++YYCURSOR;\n\tgoto yy79;\nyy79:\n#line 435 \"bytecode.re\"\n{   CHK_NL(tok+1);\n            goto Scalar2; }\n#line 1031 \"<stdout>\"\nyy80:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy81;\nyy81:\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy80;\n\tdefault:\tgoto yy82;\n\t}\nyy82:\n#line 438 \"bytecode.re\"\n{   CHK_NL(tok+1);\n            if ( tok + 2 < YYCURSOR )\n            {\n                char *count = tok + 2;\n                int total = strtod( count, NULL );\n                int i;\n                for ( i = 0; i < total; i++ )\n                {\n                    CAT(str, cap, idx, '\\n');\n                }\n            }\n            else\n            {\n                CAT(str, cap, idx, '\\n');\n            }\n            goto Scalar2;\n        }\n#line 1068 \"<stdout>\"\nyy83:\t++YYCURSOR;\n\tgoto yy84;\nyy84:\n#line 456 \"bytecode.re\"\n{   CHK_NL(tok+1);\n            CAT(str, cap, idx, '\\0');\n            goto Scalar2; \n        }\n#line 1077 \"<stdout>\"\n}\n#line 473 \"bytecode.re\"\n\n\nScalarEnd:\n        {\n            SyckNode *n = syck_alloc_str();\n            n->data.str->ptr = str;\n            n->data.str->len = idx;\n            sycklval->nodeData = n;\n            POP_LEVEL();\n            if ( parser->implicit_typing == 1 )\n            {\n                try_tag_implicit( sycklval->nodeData, parser->taguri_expansion );\n            }\n            return YAML_PLAIN;\n        }\n    }\n\n}\n\nchar *\nget_inline( SyckParser *parser )\n{\n    int idx = 0;\n    int cap = 100;\n    char *str = S_ALLOC_N( char, cap );\n    char *tok;\n\n    str[0] = '\\0';\n\nInline:\n    {\n        tok = YYCURSOR;\n\n\n#line 1114 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tgoto yy85;\n\t++YYCURSOR;\nyy85:\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy91;\n\tcase 0x0A:\tgoto yy87;\n\tcase 0x0D:\tgoto yy89;\n\tdefault:\tgoto yy93;\n\t}\nyy87:\t++YYCURSOR;\n\tgoto yy88;\nyy88:\n#line 508 \"bytecode.re\"\n{   CHK_NL(YYCURSOR);\n                return str; }\n#line 1134 \"<stdout>\"\nyy89:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy94;\n\tdefault:\tgoto yy90;\n\t}\nyy90:\n#line 515 \"bytecode.re\"\n{   CAT(str, cap, idx, tok[0]);\n                goto Inline; \n            }\n#line 1145 \"<stdout>\"\nyy91:\t++YYCURSOR;\n\tgoto yy92;\nyy92:\n#line 511 \"bytecode.re\"\n{   YYCURSOR = tok;\n                return str;\n            }\n#line 1153 \"<stdout>\"\nyy93:\tyych = *++YYCURSOR;\n\tgoto yy90;\nyy94:\t++YYCURSOR;\n\tyych = *YYCURSOR;\n\tgoto yy88;\n}\n#line 519 \"bytecode.re\"\n\n\n    }\n\n}\n\n"
  },
  {
    "path": "ext/syck/depend",
    "content": "ruby_headers = $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h \\\n  $(hdrdir)/missing.h $(hdrdir)/intern.h $(hdrdir)/st.h\nbytecode.o: bytecode.c syck.h gram.h $(ruby_headers)\nemitter.o: emitter.c syck.h $(ruby_headers)\ngram.o: gram.c syck.h $(hdrdir)/st.h\nhandler.o: handler.c syck.h $(ruby_headers)\nimplicit.o: implicit.c syck.h $(ruby_headers)\nnode.o: node.c syck.h $(ruby_headers)\nrubyext.o: rubyext.c syck.h $(ruby_headers)\nsyck.o: syck.c syck.h $(ruby_headers)\ntoken.o: token.c syck.h gram.h $(ruby_headers)\nyaml2byte.o: yaml2byte.c syck.h yamlbyte.h $(ruby_headers)\n"
  },
  {
    "path": "ext/syck/emitter.c",
    "content": "/*\n * emitter.c\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n * \n * All Base64 code from Ruby's pack.c.\n * Ruby is Copyright (C) 1993-2003 Yukihiro Matsumoto \n */\n#include \"ruby.h\"\n\n#include <stdio.h>\n#include <string.h>\n\n#include \"syck.h\"\n\n#define DEFAULT_ANCHOR_FORMAT \"id%03d\"\n\nconst char hex_table[] = \n\"0123456789ABCDEF\";\nstatic char b64_table[] =\n\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n/*\n * Built-in base64 (from Ruby's pack.c)\n */\nchar *\nsyck_base64enc( char *s, long len )\n{\n    long i = 0;\n    int padding = '=';\n    char *buff = S_ALLOC_N(char, len * 4 / 3 + 6);\n\n    while (len >= 3) {\n        buff[i++] = b64_table[077 & (*s >> 2)];\n        buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];\n        buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];\n        buff[i++] = b64_table[077 & s[2]];\n        s += 3;\n        len -= 3;\n    }\n    if (len == 2) {\n        buff[i++] = b64_table[077 & (*s >> 2)];\n        buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];\n        buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | (('\\0' >> 6) & 03))];\n        buff[i++] = padding;\n    }\n    else if (len == 1) {\n        buff[i++] = b64_table[077 & (*s >> 2)];\n        buff[i++] = b64_table[077 & (((*s << 4) & 060) | (('\\0' >> 4) & 017))];\n        buff[i++] = padding;\n        buff[i++] = padding;\n    }\n    buff[i++] = '\\n';\n    return buff;\n}\n\nchar *\nsyck_base64dec( char *s, long len )\n{\n    int a = -1,b = -1,c = 0,d;\n    static int first = 1;\n    static int b64_xtable[256];\n    char *ptr = syck_strndup( s, len );\n    char *end = ptr;\n    char *send = s + len;\n\n    if (first) {\n        int i;\n        first = 0;\n\n        for (i = 0; i < 256; i++) {\n        b64_xtable[i] = -1;\n        }\n        for (i = 0; i < 64; i++) {\n        b64_xtable[(int)b64_table[i]] = i;\n        }\n    }\n    while (s < send) {\n        while (s[0] == '\\r' || s[0] == '\\n') { s++; }\n        if ((a = b64_xtable[(int)s[0]]) == -1) break;\n        if ((b = b64_xtable[(int)s[1]]) == -1) break;\n        if ((c = b64_xtable[(int)s[2]]) == -1) break;\n        if ((d = b64_xtable[(int)s[3]]) == -1) break;\n        *end++ = a << 2 | b >> 4;\n        *end++ = b << 4 | c >> 2;\n        *end++ = c << 6 | d;\n        s += 4;\n    }\n    if (a != -1 && b != -1) {\n        if (s + 2 < send && s[2] == '=')\n        *end++ = a << 2 | b >> 4;\n        if (c != -1 && s + 3 < send && s[3] == '=') {\n        *end++ = a << 2 | b >> 4;\n        *end++ = b << 4 | c >> 2;\n        }\n    }\n    *end = '\\0';\n    /*RSTRING(buf)->len = ptr - RSTRING(buf)->ptr;*/\n    return ptr;\n}\n\n/*\n * Allocate an emitter\n */\nSyckEmitter *\nsyck_new_emitter()\n{\n    SyckEmitter *e;\n    e = S_ALLOC( SyckEmitter );\n    e->headless = 0;\n    e->use_header = 0;\n    e->use_version = 0;\n    e->sort_keys = 0;\n    e->anchor_format = NULL;\n    e->explicit_typing = 0;\n    e->best_width = 80;\n    e->style = scalar_none;\n    e->stage = doc_open;\n    e->indent = 2;\n    e->level = -1;\n    e->anchors = NULL;\n    e->markers = NULL;\n    e->anchored = NULL;\n    e->bufsize = SYCK_BUFFERSIZE;\n    e->buffer = NULL;\n    e->marker = NULL;\n    e->bufpos = 0;\n    e->emitter_handler = NULL;\n    e->output_handler = NULL;\n    e->lvl_idx = 0;\n    e->lvl_capa = ALLOC_CT;\n    e->levels = S_ALLOC_N( SyckLevel, e->lvl_capa ); \n    syck_emitter_reset_levels( e );\n    e->bonus = NULL;\n    return e;\n}\n\nint\nsyck_st_free_anchors( char *key, char *name, char *arg )\n{\n    S_FREE( name );\n    return ST_CONTINUE;\n}\n\nvoid\nsyck_emitter_st_free( SyckEmitter *e )\n{\n    /*\n     * Free the anchor tables\n     */\n    if ( e->anchors != NULL )\n    {\n        st_foreach( e->anchors, syck_st_free_anchors, 0 );\n        st_free_table( e->anchors );\n        e->anchors = NULL;\n    }\n\n    if ( e->anchored != NULL )\n    {\n        st_free_table( e->anchored );\n        e->anchored = NULL;\n    }\n\n    /*\n     * Free the markers tables\n     */\n    if ( e->markers != NULL )\n    {\n        st_free_table( e->markers );\n        e->markers = NULL;\n    }\n}\n\nSyckLevel *\nsyck_emitter_current_level( SyckEmitter *e )\n{\n    return &e->levels[e->lvl_idx-1];\n}\n\nSyckLevel *\nsyck_emitter_parent_level( SyckEmitter *e )\n{\n    return &e->levels[e->lvl_idx-2];\n}\n\nvoid\nsyck_emitter_pop_level( SyckEmitter *e )\n{\n    ASSERT( e != NULL );\n\n    /* The root level should never be popped */\n    if ( e->lvl_idx <= 1 ) return;\n\n    e->lvl_idx -= 1;\n    free( e->levels[e->lvl_idx].domain );\n}\n\nvoid \nsyck_emitter_add_level( SyckEmitter *e, int len, enum syck_level_status status )\n{\n    ASSERT( e != NULL );\n    if ( e->lvl_idx + 1 > e->lvl_capa )\n    {\n        e->lvl_capa += ALLOC_CT;\n        S_REALLOC_N( e->levels, SyckLevel, e->lvl_capa );\n    }\n\n    ASSERT( len > e->levels[e->lvl_idx-1].spaces );\n    e->levels[e->lvl_idx].spaces = len;\n    e->levels[e->lvl_idx].ncount = 0;\n    e->levels[e->lvl_idx].domain = syck_strndup( e->levels[e->lvl_idx-1].domain, strlen( e->levels[e->lvl_idx-1].domain ) );\n    e->levels[e->lvl_idx].status = status;\n    e->levels[e->lvl_idx].anctag = 0;\n    e->lvl_idx += 1;\n}\n\nvoid\nsyck_emitter_reset_levels( SyckEmitter *e )\n{\n    while ( e->lvl_idx > 1 )\n    {\n        syck_emitter_pop_level( e );\n    }\n\n    if ( e->lvl_idx < 1 )\n    {\n        e->lvl_idx = 1;\n        e->levels[0].spaces = -1;\n        e->levels[0].ncount = 0;\n        e->levels[0].domain = syck_strndup( \"\", 0 );\n        e->levels[0].anctag = 0;\n    }\n    e->levels[0].status = syck_lvl_header;\n}\n\nvoid\nsyck_emitter_handler( SyckEmitter *e, SyckEmitterHandler hdlr )\n{\n    e->emitter_handler = hdlr;\n}\n\nvoid\nsyck_output_handler( SyckEmitter *e, SyckOutputHandler hdlr )\n{\n    e->output_handler = hdlr;\n}\n\nvoid\nsyck_free_emitter( SyckEmitter *e )\n{\n    /*\n     * Free tables\n     */\n    syck_emitter_st_free( e );\n    syck_emitter_reset_levels( e );\n    S_FREE( e->levels[0].domain );\n    S_FREE( e->levels );\n    if ( e->buffer != NULL )\n    {\n        S_FREE( e->buffer );\n    }\n    S_FREE( e );\n}\n\nvoid\nsyck_emitter_clear( SyckEmitter *e )\n{\n    if ( e->buffer == NULL )\n    {\n        e->buffer = S_ALLOC_N( char, e->bufsize );\n        S_MEMZERO( e->buffer, char, e->bufsize );\n    }\n    e->buffer[0] = '\\0';\n    e->marker = e->buffer;\n    e->bufpos = 0;\n}\n\n/*\n * Raw write to the emitter buffer.\n */\nvoid\nsyck_emitter_write( SyckEmitter *e, char *str, long len )\n{\n    long at;\n    ASSERT( str != NULL )\n    if ( e->buffer == NULL )\n    {\n        syck_emitter_clear( e );\n    }\n    \n    /*\n     * Flush if at end of buffer\n     */\n    at = e->marker - e->buffer;\n    if ( len + at >= e->bufsize )\n    {\n        syck_emitter_flush( e, 0 );\n\tfor (;;) {\n\t    long rest = e->bufsize - (e->marker - e->buffer);\n\t    if (len <= rest) break;\n\t    S_MEMCPY( e->marker, str, char, rest );\n\t    e->marker += rest;\n\t    str += rest;\n\t    len -= rest;\n\t    syck_emitter_flush( e, 0 );\n\t}\n    }\n\n    /*\n     * Write to buffer\n     */\n    S_MEMCPY( e->marker, str, char, len );\n    e->marker += len;\n}\n\n/*\n * Write a chunk of data out.\n */\nvoid\nsyck_emitter_flush( SyckEmitter *e, long check_room )\n{\n    /*\n     * Check for enough space in the buffer for check_room length.\n     */\n    if ( check_room > 0 )\n    {\n        if ( e->bufsize > ( e->marker - e->buffer ) + check_room )\n        {\n            return;\n        }\n    }\n    else\n    {\n        check_room = e->bufsize;\n    }\n\n    /*\n     * Commit buffer.\n     */\n    if ( check_room > e->marker - e->buffer )\n    {\n        check_room = e->marker - e->buffer;\n    }\n    (e->output_handler)( e, e->buffer, check_room );\n    e->bufpos += check_room;\n    e->marker -= check_room;\n}\n\n/*\n * Start emitting from the given node, check for anchoring and then\n * issue the callback to the emitter handler.\n */\nvoid\nsyck_emit( SyckEmitter *e, st_data_t n )\n{\n    SYMID oid;\n    char *anchor_name = NULL;\n    int indent = 0;\n    long x = 0;\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    \n    /*\n     * Determine headers.\n     */\n    if ( e->stage == doc_open && ( e->headless == 0 || e->use_header == 1 ) )\n    {\n        if ( e->use_version == 1 )\n        {\n            char *header = S_ALLOC_N( char, 64 );\n            S_MEMZERO( header, char, 64 );\n            sprintf( header, \"--- %%YAML:%d.%d \", SYCK_YAML_MAJOR, SYCK_YAML_MINOR );\n            syck_emitter_write( e, header, strlen( header ) );\n            S_FREE( header );\n        }\n        else\n        {\n            syck_emitter_write( e, \"--- \", 4 );\n        }\n        e->stage = doc_processing;\n    }\n\n    /* Add new level */\n    if ( lvl->spaces >= 0 ) {\n        indent = lvl->spaces + e->indent;\n    }\n    syck_emitter_add_level( e, indent, syck_lvl_open );\n    lvl = syck_emitter_current_level( e );\n\n    /* Look for anchor */\n    if ( e->anchors != NULL &&\n        st_lookup( e->markers, n, (st_data_t *)&oid ) &&\n        st_lookup( e->anchors, (st_data_t)oid, (st_data_t *)&anchor_name ) )\n    {\n        if ( e->anchored == NULL )\n        {\n            e->anchored = st_init_numtable();\n        }\n\n        if ( ! st_lookup( e->anchored, (st_data_t)anchor_name, (st_data_t *)&x ) )\n        {\n            char *an = S_ALLOC_N( char, strlen( anchor_name ) + 3 );\n            sprintf( an, \"&%s \", anchor_name );\n            syck_emitter_write( e, an, strlen( anchor_name ) + 2 );\n            free( an );\n\n            x = 1;\n            st_insert( e->anchored, (st_data_t)anchor_name, (st_data_t)x );\n            lvl->anctag = 1;\n        }\n        else\n        {\n            char *an = S_ALLOC_N( char, strlen( anchor_name ) + 2 );\n            sprintf( an, \"*%s\", anchor_name );\n            syck_emitter_write( e, an, strlen( anchor_name ) + 1 );\n            free( an );\n\n            goto end_emit;\n        }\n    }\n\n    (e->emitter_handler)( e, n );\n\n    /* Pop the level */\nend_emit:\n    syck_emitter_pop_level( e );\n    if ( e->lvl_idx == 1 ) {\n        syck_emitter_write( e, \"\\n\", 1 );\n        e->headless = 0;\n        e->stage = doc_open;\n    }\n}\n\n/*\n * Determine what tag needs to be written, based on the taguri of the node\n * and the implicit tag which would be assigned to this node.  If a tag is\n * required, write the tag.\n */\nvoid syck_emit_tag( SyckEmitter *e, char *tag, char *ignore )\n{\n    SyckLevel *lvl;\n    if ( tag == NULL ) return;\n    if ( ignore != NULL && syck_tagcmp( tag, ignore ) == 0 && e->explicit_typing == 0 ) return;\n    lvl = syck_emitter_current_level( e );\n\n    /* implicit */\n    if ( strlen( tag ) == 0 ) {\n        syck_emitter_write( e, \"! \", 2 );\n\n    /* global types */\n    } else if ( strncmp( tag, \"tag:\", 4 ) == 0 ) {\n        int taglen = strlen( tag );\n        syck_emitter_write( e, \"!\", 1 );\n        if ( strncmp( tag + 4, YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) {\n            int skip = 4 + strlen( YAML_DOMAIN ) + 1;\n            syck_emitter_write( e, tag + skip, taglen - skip );\n        } else {\n            char *subd = tag + 4;\n            while ( *subd != ':' && *subd != '\\0' ) subd++;\n            if ( *subd == ':' ) {\n                if ( subd - tag > ( strlen( YAML_DOMAIN ) + 5 ) &&\n                     strncmp( subd - strlen( YAML_DOMAIN ), YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) {\n                    syck_emitter_write( e, tag + 4, subd - strlen( YAML_DOMAIN ) - ( tag + 4 ) - 1 );\n                    syck_emitter_write( e, \"/\", 1 );\n                    syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) );\n                } else {\n                    syck_emitter_write( e, tag + 4, subd - ( tag + 4 ) );\n                    syck_emitter_write( e, \"/\", 1 );\n                    syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) );\n                }\n            } else {\n                /* TODO: Invalid tag (no colon after domain) */\n                return;\n            }\n        }\n        syck_emitter_write( e, \" \", 1 );\n\n    /* private types */\n    } else if ( strncmp( tag, \"x-private:\", 10 ) == 0 ) {\n        syck_emitter_write( e, \"!!\", 2 );\n        syck_emitter_write( e, tag + 10, strlen( tag ) - 10 );\n        syck_emitter_write( e, \" \", 1 );\n    }\n    lvl->anctag = 1;\n}\n\n/* \n * Emit a newline and an appropriately spaced indent.\n */\nvoid syck_emit_indent( SyckEmitter *e )\n{\n    int i;\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    if ( e->bufpos == 0 && ( e->marker - e->buffer ) == 0 ) return;\n    if ( lvl->spaces >= 0 ) {\n        char *spcs = S_ALLOC_N( char, lvl->spaces + 2 );\n\n        spcs[0] = '\\n'; spcs[lvl->spaces + 1] = '\\0';\n        for ( i = 0; i < lvl->spaces; i++ ) spcs[i+1] = ' ';\n        syck_emitter_write( e, spcs, lvl->spaces + 1 );\n        free( spcs );\n    }\n}\n\n/* Clear the scan */\n#define SCAN_NONE       0\n/* All printable characters? */\n#define SCAN_NONPRINT   1\n/* Any indented lines? */\n#define SCAN_INDENTED   2\n/* Larger than the requested width? */\n#define SCAN_WIDE       4\n/* Opens or closes with whitespace? */\n#define SCAN_WHITEEDGE  8\n/* Contains a newline */\n#define SCAN_NEWLINE    16\n/* Contains a single quote */\n#define SCAN_SINGLEQ    32\n/* Contains a double quote */\n#define SCAN_DOUBLEQ    64\n/* Starts with a token */\n#define SCAN_INDIC_S    128\n/* Contains a flow indicator */\n#define SCAN_INDIC_C    256\n/* Ends without newlines */\n#define SCAN_NONL_E     512\n/* Ends with many newlines */\n#define SCAN_MANYNL_E   1024\n/* Contains flow map indicators */\n#define SCAN_FLOWMAP    2048\n/* Contains flow seq indicators */\n#define SCAN_FLOWSEQ    4096\n/* Contains a valid doc separator */\n#define SCAN_DOCSEP     8192\n\n/*\n * Basic printable test for LATIN-1 characters.\n */\nint\nsyck_scan_scalar( int req_width, char *cursor, long len )\n{\n    long i = 0, start = 0;\n    int flags = SCAN_NONE;\n\n    if ( len < 1 )  return flags;\n\n    /* c-indicators from the spec */\n    if ( cursor[0] == '[' || cursor[0] == ']' ||\n         cursor[0] == '{' || cursor[0] == '}' ||\n         cursor[0] == '!' || cursor[0] == '*' ||\n         cursor[0] == '&' || cursor[0] == '|' ||\n         cursor[0] == '>' || cursor[0] == '\\'' ||\n         cursor[0] == '\"' || cursor[0] == '#' ||\n         cursor[0] == '%' || cursor[0] == '@' ||\n         cursor[0] == '&' ) {\n            flags |= SCAN_INDIC_S;\n    }\n    if ( ( cursor[0] == '-' || cursor[0] == ':' ||\n           cursor[0] == '?' || cursor[0] == ',' ) &&\n           ( len == 1 || cursor[1] == ' ' || cursor[1] == '\\n' ) )\n    {\n            flags |= SCAN_INDIC_S;\n    }\n\n    /* whitespace edges */\n    if ( cursor[len-1] != '\\n' ) {\n        flags |= SCAN_NONL_E;\n    } else if ( len > 1 && cursor[len-2] == '\\n' ) {\n        flags |= SCAN_MANYNL_E;\n    }\n    if ( \n        ( len > 0 && ( cursor[0] == ' ' || cursor[0] == '\\t' ) ) ||\n        ( len > 1 && ( cursor[len-1] == ' ' || cursor[len-1] == '\\t' ) )\n    ) {\n        flags |= SCAN_WHITEEDGE;\n    }\n\n    /* opening doc sep */\n    if ( len >= 3 && strncmp( cursor, \"---\", 3 ) == 0 )\n        flags |= SCAN_DOCSEP;\n\n    /* scan string */\n    for ( i = 0; i < len; i++ ) {\n\n        if ( ! ( cursor[i] == 0x9 ||\n                 cursor[i] == 0xA ||\n                 cursor[i] == 0xD ||\n               ( cursor[i] >= 0x20 && cursor[i] <= 0x7E ) )\n        ) {\n            flags |= SCAN_NONPRINT;\n        }\n        else if ( cursor[i] == '\\n' ) {\n            flags |= SCAN_NEWLINE;\n            if ( len - i >= 3 && strncmp( &cursor[i+1], \"---\", 3 ) == 0 )\n                flags |= SCAN_DOCSEP;\n            if ( cursor[i+1] == ' ' || cursor[i+1] == '\\t' ) \n                flags |= SCAN_INDENTED;\n            if ( req_width > 0 && i - start > req_width )\n                flags |= SCAN_WIDE;\n            start = i;\n        }\n        else if ( cursor[i] == '\\'' )\n        {\n            flags |= SCAN_SINGLEQ;\n        }\n        else if ( cursor[i] == '\"' )\n        {\n            flags |= SCAN_DOUBLEQ;\n        }\n        else if ( cursor[i] == ']' )\n        {\n            flags |= SCAN_FLOWSEQ;\n        }\n        else if ( cursor[i] == '}' )\n        {\n            flags |= SCAN_FLOWMAP;\n        }\n        /* remember, if plain collections get implemented, to add nb-plain-flow-char */\n        else if ( ( cursor[i] == ' ' && cursor[i+1] == '#' ) ||\n                  ( cursor[i] == ':' && \n                    ( cursor[i+1] == ' ' || cursor[i+1] == '\\n' || i == len - 1 ) ) )\n        {\n            flags |= SCAN_INDIC_C;\n        }\n        else if ( cursor[i] == ',' && \n                  ( cursor[i+1] == ' ' || cursor[i+1] == '\\n' || i == len - 1 ) )\n        {\n            flags |= SCAN_FLOWMAP;\n            flags |= SCAN_FLOWSEQ;\n        }\n    }\n\n    /* printf( \"---STR---\\n%s\\nFLAGS: %d\\n\", cursor, flags ); */\n    return flags;\n}\n/*\n * All scalars should be emitted through this function, which determines an appropriate style,\n * tag and indent.\n */\nvoid syck_emit_scalar( SyckEmitter *e, char *tag, enum scalar_style force_style, int force_indent, int force_width,\n                       char keep_nl, char *str, long len )\n{\n    enum scalar_style favor_style = scalar_literal;\n    SyckLevel *parent = syck_emitter_parent_level( e );\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    int scan = 0;\n    char *implicit;\n    \n    if ( str == NULL ) str = \"\";\n\n    /* No empty nulls as map keys */\n    if ( len == 0 && ( parent->status == syck_lvl_map || parent->status == syck_lvl_imap ) && \n         parent->ncount % 2 == 1 && syck_tagcmp( tag, \"tag:yaml.org,2002:null\" ) == 0 ) \n    {\n        str = \"~\";\n        len = 1;\n    }\n\n    scan = syck_scan_scalar( force_width, str, len );\n    implicit = syck_match_implicit( str, len );\n\n    /* quote strings which default to implicits */\n    implicit = syck_taguri( YAML_DOMAIN, implicit, strlen( implicit ) );\n    if ( syck_tagcmp( tag, implicit ) != 0 && syck_tagcmp( tag, \"tag:yaml.org,2002:str\" ) == 0 ) {\n        force_style = scalar_2quote;\n    } else {\n        /* complex key */\n        if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 &&\n             ( !( tag == NULL || \n             ( implicit != NULL && syck_tagcmp( tag, implicit ) == 0 && e->explicit_typing == 0 ) ) ) ) \n        {\n            syck_emitter_write( e, \"? \", 2 );\n            parent->status = syck_lvl_mapx;\n        }\n        syck_emit_tag( e, tag, implicit );\n    }\n    S_FREE( implicit );\n\n    /* if still arbitrary, sniff a good block style. */\n    if ( force_style == scalar_none ) {\n        if ( scan & SCAN_NEWLINE ) {\n            force_style = scalar_literal;\n        } else {\n            force_style = scalar_plain;\n        }\n    }\n\n    if ( e->style == scalar_fold ) {\n        favor_style = scalar_fold;\n    }\n\n    /* Determine block style */\n    if ( scan & SCAN_NONPRINT ) {\n        force_style = scalar_2quote;\n    } else if ( scan & SCAN_WHITEEDGE ) {\n        force_style = scalar_2quote;\n    } else if ( force_style != scalar_fold && ( scan & SCAN_INDENTED ) ) {\n        force_style = scalar_literal;\n    } else if ( force_style == scalar_plain && ( scan & SCAN_NEWLINE ) ) {\n        force_style = favor_style;\n    } else if ( force_style == scalar_plain && parent->status == syck_lvl_iseq && ( scan & SCAN_FLOWSEQ ) ) {\n        force_style = scalar_2quote;\n    } else if ( force_style == scalar_plain && parent->status == syck_lvl_imap && ( scan & SCAN_FLOWMAP ) ) {\n        force_style = scalar_2quote;\n    /* } else if ( force_style == scalar_fold && ( ! ( scan & SCAN_WIDE ) ) ) {\n        force_style = scalar_literal; */\n    } else if ( force_style == scalar_plain && ( scan & SCAN_INDIC_S || scan & SCAN_INDIC_C ) ) {\n        if ( scan & SCAN_NEWLINE ) {\n            force_style = favor_style;\n        } else {\n            force_style = scalar_2quote;\n        }\n    }\n\n    if ( force_indent > 0 ) {\n        lvl->spaces = parent->spaces + force_indent;\n    } else if ( scan & SCAN_DOCSEP ) {\n        lvl->spaces = parent->spaces + e->indent;\n    }\n\n    /* For now, all ambiguous keys are going to be double-quoted */\n    if ( ( parent->status == syck_lvl_map || parent->status == syck_lvl_mapx ) && parent->ncount % 2 == 1 ) {\n        if ( force_style != scalar_plain ) {\n            force_style = scalar_2quote;\n        }\n    }\n\n    /* If the parent is an inline, double quote anything complex */\n    if ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) {\n        if ( force_style != scalar_plain && force_style != scalar_1quote ) {\n            force_style = scalar_2quote;\n        }\n    }\n\n    /* Fix the ending newlines */\n    if ( scan & SCAN_NONL_E ) {\n        keep_nl = NL_CHOMP;\n    } else if ( scan & SCAN_MANYNL_E ) {\n        keep_nl = NL_KEEP;\n    }\n\n    /* Write the text node */\n    switch ( force_style )\n    {\n        case scalar_1quote:\n            syck_emit_1quoted( e, force_width, str, len );\n        break;\n\n        case scalar_none:\n        case scalar_2quote:\n            syck_emit_2quoted( e, force_width, str, len );\n        break;\n\n        case scalar_fold:\n            syck_emit_folded( e, force_width, keep_nl, str, len );\n        break;\n\n        case scalar_literal:\n            syck_emit_literal( e, keep_nl, str, len );\n        break;\n\n        case scalar_plain:\n            syck_emitter_write( e, str, len );\n        break;\n    }\n\n    if ( parent->status == syck_lvl_mapx )\n    {\n        syck_emitter_write( e, \"\\n\", 1 );\n    }\n}\n\nvoid\nsyck_emitter_escape( SyckEmitter *e, char *src, long len )\n{\n    int i;\n    for( i = 0; i < len; i++ )\n    {\n        if( (src[i] < 0x20) || (0x7E < src[i]) )\n        {\n            syck_emitter_write( e, \"\\\\\", 1 );\n            if( '\\0' == src[i] )\n                syck_emitter_write( e, \"0\", 1 );\n            else\n            {\n                syck_emitter_write( e, \"x\", 1 );\n                syck_emitter_write( e, (char *)hex_table + ((src[i] & 0xF0) >> 4), 1 );\n                syck_emitter_write( e, (char *)hex_table + (src[i] & 0x0F), 1 );\n            }\n        }\n        else\n        {\n            syck_emitter_write( e, src + i, 1 );\n            if( '\\\\' == src[i] )\n                syck_emitter_write( e, \"\\\\\", 1 );\n        }\n    }\n}\n\n/*\n * Outputs a single-quoted block.\n */\nvoid syck_emit_1quoted( SyckEmitter *e, int width, char *str, long len )\n{\n    char do_indent = 0;\n    char *mark = str;\n    char *start = str;\n    char *end = str;\n    syck_emitter_write( e, \"'\", 1 );\n    while ( mark < str + len ) {\n        if ( do_indent ) {\n            syck_emit_indent( e );\n            do_indent = 0;\n        }\n        switch ( *mark ) {\n            case '\\'':  syck_emitter_write( e, \"'\", 1 ); break;\n\n            case '\\n':\n                end = mark + 1;\n                if ( *start != ' ' && *start != '\\n' && *end != '\\n' && *end != ' ' ) {\n                    syck_emitter_write( e, \"\\n\\n\", 2 );\n                } else {\n                    syck_emitter_write( e, \"\\n\", 1 );\n                }\n                do_indent = 1;\n                start = mark + 1;\n            break;\n\n            case ' ':\n                if ( width > 0 && *start != ' ' && mark - end > width ) {\n                    do_indent = 1;\n                    end = mark + 1;\n                } else {\n                    syck_emitter_write( e, \" \", 1 );\n                }\n            break;\n\n            default:\n                syck_emitter_write( e, mark, 1 );\n            break;\n        }\n        mark++;\n    }\n    syck_emitter_write( e, \"'\", 1 );\n}\n\n/*\n * Outputs a double-quoted block.\n */\nvoid syck_emit_2quoted( SyckEmitter *e, int width, char *str, long len )\n{\n    char do_indent = 0;\n    char *mark = str;\n    char *start = str;\n    char *end = str;\n    syck_emitter_write( e, \"\\\"\", 1 );\n    while ( mark < str + len ) {\n        if ( do_indent > 0 ) {\n            if ( do_indent == 2 ) {\n                syck_emitter_write( e, \"\\\\\", 1 );\n            }\n            syck_emit_indent( e );\n            do_indent = 0;\n        }\n        switch ( *mark ) {\n\n            /* Escape sequences allowed within double quotes. */\n            case '\"':  syck_emitter_write( e, \"\\\\\\\"\", 2 ); break;\n            case '\\\\': syck_emitter_write( e, \"\\\\\\\\\", 2 ); break;\n            case '\\0': syck_emitter_write( e, \"\\\\0\",  2 ); break;\n            case '\\a': syck_emitter_write( e, \"\\\\a\",  2 ); break;\n            case '\\b': syck_emitter_write( e, \"\\\\b\",  2 ); break;\n            case '\\f': syck_emitter_write( e, \"\\\\f\",  2 ); break;\n            case '\\r': syck_emitter_write( e, \"\\\\r\",  2 ); break;\n            case '\\t': syck_emitter_write( e, \"\\\\t\",  2 ); break;\n            case '\\v': syck_emitter_write( e, \"\\\\v\",  2 ); break;\n            case 0x1b: syck_emitter_write( e, \"\\\\e\",  2 ); break;\n\n            case '\\n':\n                end = mark + 1;\n                syck_emitter_write( e, \"\\\\n\", 2 );\n                do_indent = 2;\n                start = mark + 1;\n                if ( start < str + len && ( *start == ' ' || *start == '\\n' ) ) {\n                    do_indent = 0;\n                }\n            break;\n\n            case ' ':\n                if ( width > 0 && *start != ' ' && mark - end > width ) {\n                    do_indent = 1;\n                    end = mark + 1;\n                } else {\n                    syck_emitter_write( e, \" \", 1 );\n                }\n            break;\n\n            default:\n                syck_emitter_escape( e, mark, 1 );\n            break;\n        }\n        mark++;\n    }\n    syck_emitter_write( e, \"\\\"\", 1 );\n}\n\n/*\n * Outputs a literal block.\n */\nvoid syck_emit_literal( SyckEmitter *e, char keep_nl, char *str, long len )\n{\n    char *mark = str;\n    char *start = str;\n    char *end = str;\n    syck_emitter_write( e, \"|\", 1 );\n    if ( keep_nl == NL_CHOMP ) {\n        syck_emitter_write( e, \"-\", 1 );\n    } else if ( keep_nl == NL_KEEP ) {\n        syck_emitter_write( e, \"+\", 1 );\n    }\n    syck_emit_indent( e );\n    while ( mark < str + len ) {\n        if ( *mark == '\\n' ) {\n            end = mark;\n            if ( *start != ' ' && *start != '\\n' && *end != '\\n' && *end != ' ' ) end += 1;\n            syck_emitter_write( e, start, end - start );\n            if ( mark + 1 == str + len ) {\n                if ( keep_nl != NL_KEEP ) syck_emitter_write( e, \"\\n\", 1 );\n            } else {\n                syck_emit_indent( e );\n            }\n            start = mark + 1;\n        }\n        mark++;\n    }\n    end = str + len;\n    if ( start < end ) {\n        syck_emitter_write( e, start, end - start );\n    }\n}\n\n/*\n * Outputs a folded block.\n */\nvoid syck_emit_folded( SyckEmitter *e, int width, char keep_nl, char *str, long len )\n{\n    char *mark = str;\n    char *start = str;\n    char *end = str;\n    syck_emitter_write( e, \">\", 1 );\n    if ( keep_nl == NL_CHOMP ) {\n        syck_emitter_write( e, \"-\", 1 );\n    } else if ( keep_nl == NL_KEEP ) {\n        syck_emitter_write( e, \"+\", 1 );\n    }\n    syck_emit_indent( e );\n    if ( width <= 0 ) width = e->best_width;\n    while ( mark < str + len ) {\n        switch ( *mark ) {\n            case '\\n':\n                syck_emitter_write( e, end, mark - end );\n                end = mark + 1;\n                if ( *start != ' ' && *start != '\\n' && *end != '\\n' && *end != ' ' ) {\n                    syck_emitter_write( e, \"\\n\", 1 );\n                }\n                if ( mark + 1 == str + len ) {\n                    if ( keep_nl != NL_KEEP ) syck_emitter_write( e, \"\\n\", 1 );\n                } else {\n                    syck_emit_indent( e );\n                }\n                start = mark + 1;\n            break;\n\n            case ' ':\n                if ( *start != ' ' ) {\n                    if ( mark - end > width ) {\n                        syck_emitter_write( e, end, mark - end );\n                        syck_emit_indent( e );\n                        end = mark + 1;\n                    }\n                }\n            break;\n        }\n        mark++;\n    }\n    if ( end < mark ) {\n        syck_emitter_write( e, end, mark - end );\n    }\n}\n\n/*\n * Begins emission of a sequence.\n */\nvoid syck_emit_seq( SyckEmitter *e, char *tag, enum seq_style style )\n{\n    SyckLevel *parent = syck_emitter_parent_level( e );\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    syck_emit_tag( e, tag, \"tag:yaml.org,2002:seq\" );\n    if ( style == seq_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) {\n        syck_emitter_write( e, \"[\", 1 );\n        lvl->status = syck_lvl_iseq;\n    } else {\n        /* complex key */\n        if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) {\n            syck_emitter_write( e, \"? \", 2 );\n            parent->status = syck_lvl_mapx;\n        }\n        lvl->status = syck_lvl_seq;\n    }\n}\n\n/*\n * Begins emission of a mapping.\n */\nvoid syck_emit_map( SyckEmitter *e, char *tag, enum map_style style )\n{\n    SyckLevel *parent = syck_emitter_parent_level( e );\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    syck_emit_tag( e, tag, \"tag:yaml.org,2002:map\" );\n    if ( style == map_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) {\n        syck_emitter_write( e, \"{\", 1 );\n        lvl->status = syck_lvl_imap;\n    } else {\n        /* complex key */\n        if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) {\n            syck_emitter_write( e, \"? \", 2 );\n            parent->status = syck_lvl_mapx;\n        }\n        lvl->status = syck_lvl_map;\n    }\n}\n\n/*\n * Handles emitting of a collection item (for both\n * sequences and maps)\n */\nvoid syck_emit_item( SyckEmitter *e, st_data_t n )\n{\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    switch ( lvl->status )\n    {\n        case syck_lvl_seq:\n        {\n            SyckLevel *parent = syck_emitter_parent_level( e );\n\n            /* seq-in-map shortcut -- the lvl->anctag check should be unneccesary but\n             * there is a nasty shift/reduce in the parser on this point and\n             * i'm not ready to tickle it. */\n            if ( lvl->anctag == 0 && parent->status == syck_lvl_map && lvl->ncount == 0 ) {\n                lvl->spaces = parent->spaces;\n            }\n\n            /* seq-in-seq shortcut */\n            else if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) {\n                int spcs = ( lvl->spaces - parent->spaces ) - 2;\n                if ( spcs >= 0 ) {\n                    int i = 0;\n                    for ( i = 0; i < spcs; i++ ) {\n                        syck_emitter_write( e, \" \", 1 );\n                    }\n                    syck_emitter_write( e, \"- \", 2 );\n                    break;\n                }\n            }\n\n            syck_emit_indent( e );\n            syck_emitter_write( e, \"- \", 2 );\n        }\n        break;\n\n        case syck_lvl_iseq:\n        {\n            if ( lvl->ncount > 0 ) {\n                syck_emitter_write( e, \", \", 2 );\n            }\n        }\n        break;\n\n        case syck_lvl_map:\n        {\n            SyckLevel *parent = syck_emitter_parent_level( e );\n\n            /* map-in-seq shortcut */\n            if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) {\n                int spcs = ( lvl->spaces - parent->spaces ) - 2;\n                if ( spcs >= 0 ) {\n                    int i = 0;\n                    for ( i = 0; i < spcs; i++ ) {\n                        syck_emitter_write( e, \" \", 1 );\n                    }\n                    break;\n                }\n            }\n\n            if ( lvl->ncount % 2 == 0 ) {\n                syck_emit_indent( e );\n            } else {\n                syck_emitter_write( e, \": \", 2 );\n            }\n        }\n        break;\n\n        case syck_lvl_mapx:\n        {\n            if ( lvl->ncount % 2 == 0 ) {\n                syck_emit_indent( e );\n                lvl->status = syck_lvl_map;\n            } else {\n                int i;\n                if ( lvl->spaces > 0 ) {\n                    char *spcs = S_ALLOC_N( char, lvl->spaces + 1 );\n\n                    spcs[lvl->spaces] = '\\0';\n                    for ( i = 0; i < lvl->spaces; i++ ) spcs[i] = ' ';\n                    syck_emitter_write( e, spcs, lvl->spaces );\n                    S_FREE( spcs );\n                }\n                syck_emitter_write( e, \": \", 2 );\n            }\n        }\n        break;\n\n        case syck_lvl_imap:\n        {\n            if ( lvl->ncount > 0 ) {\n                if ( lvl->ncount % 2 == 0 ) {\n                    syck_emitter_write( e, \", \", 2 );\n                } else {\n                    syck_emitter_write( e, \": \", 2 );\n                }\n            }\n        }\n        break;\n\n        default: break;\n    }\n    lvl->ncount++;\n\n    syck_emit( e, n );\n}\n\n/*\n * Closes emission of a collection.\n */\nvoid syck_emit_end( SyckEmitter *e )\n{\n    SyckLevel *lvl = syck_emitter_current_level( e );\n    SyckLevel *parent = syck_emitter_parent_level( e );\n    switch ( lvl->status )\n    {\n        case syck_lvl_seq:\n            if ( lvl->ncount == 0 ) {\n                syck_emitter_write( e, \"[]\\n\", 3 );\n            } else if ( parent->status == syck_lvl_mapx ) {\n                syck_emitter_write( e, \"\\n\", 1 );\n            }\n        break;\n\n        case syck_lvl_iseq:\n            syck_emitter_write( e, \"]\\n\", 1 );\n        break;\n\n        case syck_lvl_map:\n            if ( lvl->ncount == 0 ) {\n                syck_emitter_write( e, \"{}\\n\", 3 );\n            } else if ( lvl->ncount % 2 == 1 ) {\n                syck_emitter_write( e, \":\\n\", 1 );\n            } else if ( parent->status == syck_lvl_mapx ) {\n                syck_emitter_write( e, \"\\n\", 1 );\n            }\n        break;\n\n        case syck_lvl_imap:\n            syck_emitter_write( e, \"}\\n\", 1 );\n        break;\n\n        default: break;\n    }\n}\n\n/*\n * Fill markers table with emitter nodes in the\n * soon-to-be-emitted tree.\n */\nSYMID\nsyck_emitter_mark_node( SyckEmitter *e, st_data_t n )\n{\n    SYMID oid = 0;\n    char *anchor_name = NULL;\n\n    /*\n     * Ensure markers table is initialized.\n     */\n    if ( e->markers == NULL )\n    {\n        e->markers = st_init_numtable();\n    }\n\n    /*\n     * Markers table initially marks the string position of the\n     * object.  Doesn't yet create an anchor, simply notes the\n     * position.\n     */\n    if ( ! st_lookup( e->markers, n, (st_data_t *)&oid ) )\n    {\n        /*\n         * Store all markers\n         */\n        oid = e->markers->num_entries + 1;\n        st_insert( e->markers, n, (st_data_t)oid );\n    }\n    else\n    {\n        if ( e->anchors == NULL )\n        {\n            e->anchors = st_init_numtable();\n        }\n\n        if ( ! st_lookup( e->anchors, (st_data_t)oid, (st_data_t *)&anchor_name ) )\n        {\n            int idx = 0;\n            char *anc = ( e->anchor_format == NULL ? DEFAULT_ANCHOR_FORMAT : e->anchor_format );\n\n            /*\n             * Second time hitting this object, let's give it an anchor\n             */\n            idx = e->anchors->num_entries + 1;\n            anchor_name = S_ALLOC_N( char, strlen( anc ) + 10 );\n            S_MEMZERO( anchor_name, char, strlen( anc ) + 10 );\n            sprintf( anchor_name, anc, idx );\n\n            /*\n             * Insert into anchors table\n             */\n            st_insert( e->anchors, (st_data_t)oid, (st_data_t)anchor_name );\n        }\n    }\n    return oid;\n}\n\n"
  },
  {
    "path": "ext/syck/extconf.rb",
    "content": "require 'mkmf'\n\nhave_header( \"st.h\" )\ncreate_makefile( \"syck\" )\n\n"
  },
  {
    "path": "ext/syck/gram.c",
    "content": "/* A Bison parser, made by GNU Bison 1.875d.  */\n\n/* Skeleton parser for Yacc-like parsing with Bison,\n   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2, or (at your option)\n   any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n\n/* As a special exception, when this file is copied by Bison into a\n   Bison output file, you may use that output file without restriction.\n   This special exception was added by the Free Software Foundation\n   in version 1.24 of Bison.  */\n\n/* Written by Richard Stallman by simplifying the original so called\n   ``semantic'' parser.  */\n\n/* All symbols defined below should begin with yy or YY, to avoid\n   infringing on user name space.  This should be done even for local\n   variables, as they might otherwise be expanded by user macros.\n   There are some unavoidable exceptions within include files to\n   define necessary library symbols; they are noted \"INFRINGES ON\n   USER NAME SPACE\" below.  */\n\n/* Identify Bison output.  */\n#define YYBISON 1\n\n/* Skeleton name.  */\n#define YYSKELETON_NAME \"yacc.c\"\n\n/* Pure parsers.  */\n#define YYPURE 1\n\n/* Using locations.  */\n#define YYLSP_NEEDED 0\n\n/* If NAME_PREFIX is specified substitute the variables and functions\n   names.  */\n#define yyparse syckparse\n#define yylex   sycklex\n#define yyerror syckerror\n#define yylval  sycklval\n#define yychar  syckchar\n#define yydebug syckdebug\n#define yynerrs sycknerrs\n\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     YAML_ANCHOR = 258,\n     YAML_ALIAS = 259,\n     YAML_TRANSFER = 260,\n     YAML_TAGURI = 261,\n     YAML_ITRANSFER = 262,\n     YAML_WORD = 263,\n     YAML_PLAIN = 264,\n     YAML_BLOCK = 265,\n     YAML_DOCSEP = 266,\n     YAML_IOPEN = 267,\n     YAML_INDENT = 268,\n     YAML_IEND = 269\n   };\n#endif\n#define YAML_ANCHOR 258\n#define YAML_ALIAS 259\n#define YAML_TRANSFER 260\n#define YAML_TAGURI 261\n#define YAML_ITRANSFER 262\n#define YAML_WORD 263\n#define YAML_PLAIN 264\n#define YAML_BLOCK 265\n#define YAML_DOCSEP 266\n#define YAML_IOPEN 267\n#define YAML_INDENT 268\n#define YAML_IEND 269\n\n\n\n\n/* Copy the first part of user declarations.  */\n#line 14 \"gram.y\"\n\n\n#include \"syck.h\"\n\nvoid apply_seq_in_map( SyckParser *parser, SyckNode *n );\n\n#define YYPARSE_PARAM   parser\n#define YYLEX_PARAM     parser\n\n#define NULL_NODE(parser, node) \\\n        SyckNode *node = syck_new_str( \"\", scalar_plain ); \\\n        if ( ((SyckParser *)parser)->taguri_expansion == 1 ) \\\n        { \\\n            node->type_id = syck_taguri( YAML_DOMAIN, \"null\", 4 ); \\\n        } \\\n        else \\\n        { \\\n            node->type_id = syck_strndup( \"null\", 4 ); \\\n        }\n\n\n/* Enabling traces.  */\n#ifndef YYDEBUG\n# define YYDEBUG 1\n#endif\n\n/* Enabling verbose error messages.  */\n#ifdef YYERROR_VERBOSE\n# undef YYERROR_VERBOSE\n# define YYERROR_VERBOSE 1\n#else\n# define YYERROR_VERBOSE 0\n#endif\n\n#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)\n#line 35 \"gram.y\"\ntypedef union YYSTYPE {\n    SYMID nodeId;\n    SyckNode *nodeData;\n    char *name;\n} YYSTYPE;\n/* Line 191 of yacc.c.  */\n#line 140 \"gram.c\"\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n# define YYSTYPE_IS_TRIVIAL 1\n#endif\n\n\n\n/* Copy the second part of user declarations.  */\n\n\n/* Line 214 of yacc.c.  */\n#line 152 \"gram.c\"\n\n#if ! defined (yyoverflow) || YYERROR_VERBOSE\n\n# ifndef YYFREE\n#  define YYFREE free\n# endif\n# ifndef YYMALLOC\n#  define YYMALLOC malloc\n# endif\n\n/* The parser invokes alloca or malloc; define the necessary symbols.  */\n\n# ifdef YYSTACK_USE_ALLOCA\n#  if YYSTACK_USE_ALLOCA\n#   define YYSTACK_ALLOC alloca\n#  endif\n# else\n#  if defined (alloca) || defined (_ALLOCA_H)\n#   define YYSTACK_ALLOC alloca\n#  else\n#   ifdef __GNUC__\n#    define YYSTACK_ALLOC __builtin_alloca\n#   endif\n#  endif\n# endif\n\n# ifdef YYSTACK_ALLOC\n   /* Pacify GCC's `empty if-body' warning. */\n#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)\n# else\n#  if defined (__STDC__) || defined (__cplusplus)\n#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#   define YYSIZE_T size_t\n#  endif\n#  define YYSTACK_ALLOC YYMALLOC\n#  define YYSTACK_FREE YYFREE\n# endif\n#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */\n\n\n#if (! defined (yyoverflow) \\\n     && (! defined (__cplusplus) \\\n\t || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))\n\n/* A type that is properly aligned for any stack member.  */\nunion yyalloc\n{\n  short int yyss;\n  YYSTYPE yyvs;\n  };\n\n/* The size of the maximum gap between one aligned stack and the next.  */\n# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)\n\n/* The size of an array large to enough to hold all stacks, each with\n   N elements.  */\n# define YYSTACK_BYTES(N) \\\n     ((N) * (sizeof (short int) + sizeof (YYSTYPE))\t\t\t\\\n      + YYSTACK_GAP_MAXIMUM)\n\n/* Copy COUNT objects from FROM to TO.  The source and destination do\n   not overlap.  */\n# ifndef YYCOPY\n#  if defined (__GNUC__) && 1 < __GNUC__\n#   define YYCOPY(To, From, Count) \\\n      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))\n#  else\n#   define YYCOPY(To, From, Count)\t\t\\\n      do\t\t\t\t\t\\\n\t{\t\t\t\t\t\\\n\t  register YYSIZE_T yyi;\t\t\\\n\t  for (yyi = 0; yyi < (Count); yyi++)\t\\\n\t    (To)[yyi] = (From)[yyi];\t\t\\\n\t}\t\t\t\t\t\\\n      while (0)\n#  endif\n# endif\n\n/* Relocate STACK from its old location to the new one.  The\n   local variables YYSIZE and YYSTACKSIZE give the old and new number of\n   elements in the stack, and YYPTR gives the new location of the\n   stack.  Advance YYPTR to a properly aligned location for the next\n   stack.  */\n# define YYSTACK_RELOCATE(Stack)\t\t\t\t\t\\\n    do\t\t\t\t\t\t\t\t\t\\\n      {\t\t\t\t\t\t\t\t\t\\\n\tYYSIZE_T yynewbytes;\t\t\t\t\t\t\\\n\tYYCOPY (&yyptr->Stack, Stack, yysize);\t\t\t\t\\\n\tStack = &yyptr->Stack;\t\t\t\t\t\t\\\n\tyynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \\\n\tyyptr += yynewbytes / sizeof (*yyptr);\t\t\t\t\\\n      }\t\t\t\t\t\t\t\t\t\\\n    while (0)\n\n#endif\n\n#if defined (__STDC__) || defined (__cplusplus)\n   typedef signed char yysigned_char;\n#else\n   typedef short int yysigned_char;\n#endif\n\n/* YYFINAL -- State number of the termination state. */\n#define YYFINAL  52\n/* YYLAST -- Last index in YYTABLE.  */\n#define YYLAST   396\n\n/* YYNTOKENS -- Number of terminals. */\n#define YYNTOKENS  23\n/* YYNNTS -- Number of nonterminals. */\n#define YYNNTS  29\n/* YYNRULES -- Number of rules. */\n#define YYNRULES  79\n/* YYNRULES -- Number of states. */\n#define YYNSTATES  128\n\n/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */\n#define YYUNDEFTOK  2\n#define YYMAXUTOK   269\n\n#define YYTRANSLATE(YYX) \t\t\t\t\t\t\\\n  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)\n\n/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */\nstatic const unsigned char yytranslate[] =\n{\n       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,    21,    15,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,    16,     2,\n       2,     2,     2,    22,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,    17,     2,    18,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,    19,     2,    20,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\n       5,     6,     7,     8,     9,    10,    11,    12,    13,    14\n};\n\n#if YYDEBUG\n/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in\n   YYRHS.  */\nstatic const unsigned char yyprhs[] =\n{\n       0,     0,     3,     5,     8,     9,    11,    13,    15,    18,\n      21,    24,    28,    30,    32,    36,    37,    40,    43,    46,\n      49,    51,    54,    56,    58,    60,    63,    66,    69,    72,\n      75,    77,    79,    81,    85,    87,    89,    91,    93,    95,\n      99,   103,   106,   110,   113,   117,   120,   124,   127,   129,\n     133,   136,   140,   143,   145,   149,   151,   153,   157,   161,\n     165,   168,   172,   175,   179,   182,   184,   188,   190,   194,\n     196,   200,   204,   207,   211,   215,   218,   220,   224,   226\n};\n\n/* YYRHS -- A `-1'-separated list of the rules' RHS. */\nstatic const yysigned_char yyrhs[] =\n{\n      24,     0,    -1,    25,    -1,    11,    27,    -1,    -1,    33,\n      -1,    26,    -1,    34,    -1,     5,    26,    -1,     6,    26,\n      -1,     3,    26,    -1,    29,    26,    32,    -1,    25,    -1,\n      28,    -1,    29,    28,    30,    -1,    -1,     7,    28,    -1,\n       5,    28,    -1,     6,    28,    -1,     3,    28,    -1,    12,\n      -1,    29,    13,    -1,    14,    -1,    13,    -1,    14,    -1,\n      31,    32,    -1,     5,    33,    -1,     6,    33,    -1,     7,\n      33,    -1,     3,    33,    -1,     4,    -1,     8,    -1,     9,\n      -1,    29,    33,    32,    -1,    10,    -1,    35,    -1,    39,\n      -1,    42,    -1,    49,    -1,    29,    37,    30,    -1,    29,\n      38,    30,    -1,    15,    27,    -1,     5,    31,    38,    -1,\n       5,    37,    -1,     6,    31,    38,    -1,     6,    37,    -1,\n       3,    31,    38,    -1,     3,    37,    -1,    36,    -1,    38,\n      31,    36,    -1,    38,    31,    -1,    17,    40,    18,    -1,\n      17,    18,    -1,    41,    -1,    40,    21,    41,    -1,    25,\n      -1,    48,    -1,    29,    43,    30,    -1,    29,    47,    30,\n      -1,     5,    31,    47,    -1,     5,    43,    -1,     6,    31,\n      47,    -1,     6,    43,    -1,     3,    31,    47,    -1,     3,\n      43,    -1,    33,    -1,    22,    25,    31,    -1,    27,    -1,\n      44,    16,    45,    -1,    46,    -1,    47,    31,    36,    -1,\n      47,    31,    46,    -1,    47,    31,    -1,    25,    16,    27,\n      -1,    19,    50,    20,    -1,    19,    20,    -1,    51,    -1,\n      50,    21,    51,    -1,    25,    -1,    48,    -1\n};\n\n/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */\nstatic const unsigned short int yyrline[] =\n{\n       0,    56,    56,    60,    65,    70,    71,    74,    75,    80,\n      85,    94,   100,   101,   104,   109,   113,   121,   126,   131,\n     145,   146,   149,   152,   155,   156,   164,   169,   174,   182,\n     186,   194,   207,   208,   218,   219,   220,   221,   222,   228,\n     232,   238,   244,   249,   254,   259,   264,   268,   274,   278,\n     283,   292,   296,   302,   306,   313,   314,   320,   325,   332,\n     337,   342,   347,   352,   356,   362,   363,   369,   379,   396,\n     397,   409,   417,   426,   434,   438,   444,   445,   454,   461\n};\n#endif\n\n#if YYDEBUG || YYERROR_VERBOSE\n/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\n   First, the terminals, then, starting at YYNTOKENS, nonterminals. */\nstatic const char *const yytname[] =\n{\n  \"$end\", \"error\", \"$undefined\", \"YAML_ANCHOR\", \"YAML_ALIAS\",\n  \"YAML_TRANSFER\", \"YAML_TAGURI\", \"YAML_ITRANSFER\", \"YAML_WORD\",\n  \"YAML_PLAIN\", \"YAML_BLOCK\", \"YAML_DOCSEP\", \"YAML_IOPEN\", \"YAML_INDENT\",\n  \"YAML_IEND\", \"'-'\", \"':'\", \"'['\", \"']'\", \"'{'\", \"'}'\", \"','\", \"'?'\",\n  \"$accept\", \"doc\", \"atom\", \"ind_rep\", \"atom_or_empty\", \"empty\",\n  \"indent_open\", \"indent_end\", \"indent_sep\", \"indent_flex_end\", \"word_rep\",\n  \"struct_rep\", \"implicit_seq\", \"basic_seq\", \"top_imp_seq\",\n  \"in_implicit_seq\", \"inline_seq\", \"in_inline_seq\", \"inline_seq_atom\",\n  \"implicit_map\", \"top_imp_map\", \"complex_key\", \"complex_value\",\n  \"complex_mapping\", \"in_implicit_map\", \"basic_mapping\", \"inline_map\",\n  \"in_inline_map\", \"inline_map_atom\", 0\n};\n#endif\n\n# ifdef YYPRINT\n/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to\n   token YYLEX-NUM.  */\nstatic const unsigned short int yytoknum[] =\n{\n       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,    45,    58,    91,    93,   123,\n     125,    44,    63\n};\n# endif\n\n/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */\nstatic const unsigned char yyr1[] =\n{\n       0,    23,    24,    24,    24,    25,    25,    26,    26,    26,\n      26,    26,    27,    27,    28,    28,    28,    28,    28,    28,\n      29,    29,    30,    31,    32,    32,    33,    33,    33,    33,\n      33,    33,    33,    33,    34,    34,    34,    34,    34,    35,\n      35,    36,    37,    37,    37,    37,    37,    37,    38,    38,\n      38,    39,    39,    40,    40,    41,    41,    42,    42,    43,\n      43,    43,    43,    43,    43,    44,    44,    45,    46,    47,\n      47,    47,    47,    48,    49,    49,    50,    50,    51,    51\n};\n\n/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */\nstatic const unsigned char yyr2[] =\n{\n       0,     2,     1,     2,     0,     1,     1,     1,     2,     2,\n       2,     3,     1,     1,     3,     0,     2,     2,     2,     2,\n       1,     2,     1,     1,     1,     2,     2,     2,     2,     2,\n       1,     1,     1,     3,     1,     1,     1,     1,     1,     3,\n       3,     2,     3,     2,     3,     2,     3,     2,     1,     3,\n       2,     3,     2,     1,     3,     1,     1,     3,     3,     3,\n       2,     3,     2,     3,     2,     1,     3,     1,     3,     1,\n       3,     3,     2,     3,     3,     2,     1,     3,     1,     1\n};\n\n/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state\n   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero\n   means the default is an error.  */\nstatic const unsigned char yydefact[] =\n{\n       4,     0,    30,     0,     0,     0,    31,    32,    34,    15,\n      20,     0,     0,     0,     2,     6,     0,     5,     7,    35,\n      36,    37,    38,    10,    29,     8,    26,     9,    27,     0,\n       0,     0,     0,    28,    15,    15,    15,    15,    12,     3,\n      13,    15,    52,    55,     0,    53,    56,    75,    78,    79,\n       0,    76,     1,     0,     0,     0,    21,    15,     0,     0,\n      65,    48,     0,     0,     0,     0,    69,     0,     0,    19,\n      17,    18,    15,    15,    15,    16,    15,    15,    15,    15,\n       0,    15,    51,     0,    74,     0,    23,     0,    47,    64,\n       0,    43,    60,     0,    45,    62,    41,     0,    24,     0,\n      11,    33,    22,    39,    40,    50,    57,    15,    58,    72,\n      14,    73,    54,    77,    65,    46,    63,    42,    59,    44,\n      61,    66,    25,    49,    67,    68,    70,    71\n};\n\n/* YYDEFGOTO[NTERM-NUM]. */\nstatic const yysigned_char yydefgoto[] =\n{\n      -1,    13,    38,    15,    39,    40,    16,   103,    99,   101,\n      17,    18,    19,    61,    62,    63,    20,    44,    45,    21,\n      64,    65,   125,    66,    67,    46,    22,    50,    51\n};\n\n/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\n   STATE-NUM.  */\n#define YYPACT_NINF -97\nstatic const short int yypact[] =\n{\n     250,   318,   -97,   318,   318,   374,   -97,   -97,   -97,   335,\n     -97,   267,   232,     7,   -97,   -97,   192,   -97,   -97,   -97,\n     -97,   -97,   -97,   -97,   -97,   -97,   -97,   -97,   -97,   374,\n     374,   374,   352,   -97,   335,   335,   335,   384,   -97,   -97,\n     -97,   212,   -97,    10,     0,   -97,   -97,   -97,    10,   -97,\n      -4,   -97,   -97,   284,   284,   284,   -97,   335,   318,    30,\n      30,   -97,    -2,    36,    -2,    16,   -97,    36,    30,   -97,\n     -97,   -97,   384,   384,   384,   -97,   363,   301,   301,   301,\n      -2,   335,   -97,   318,   -97,   318,   -97,   158,   -97,   -97,\n     158,   -97,   -97,   158,   -97,   -97,   -97,    24,   -97,    30,\n     -97,   -97,   -97,   -97,   -97,    26,   -97,   335,   -97,   158,\n     -97,   -97,   -97,   -97,   -97,    24,    24,    24,    24,    24,\n      24,   -97,   -97,   -97,   -97,   -97,   -97,   -97\n};\n\n/* YYPGOTO[NTERM-NUM].  */\nstatic const yysigned_char yypgoto[] =\n{\n     -97,   -97,     8,    81,   -56,   109,    33,   -53,    74,   -54,\n      -1,   -97,   -97,   -96,   -31,   -32,   -97,   -97,   -44,   -97,\n      77,   -97,   -97,   -52,     9,    -6,   -97,   -97,   -29\n};\n\n/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If\n   positive, shift that token.  If negative, reduce the rule which\n   number is the opposite.  If zero, do what YYDEFACT says.\n   If YYTABLE_NINF, syntax error.  */\n#define YYTABLE_NINF -1\nstatic const unsigned char yytable[] =\n{\n      24,    96,    26,    28,    33,   100,    49,    52,    14,   123,\n     104,   106,   102,   126,   108,    60,    84,    85,    82,    43,\n      48,    83,    88,    91,    94,   111,    81,   110,    24,    26,\n      28,    68,   107,    24,    26,    28,    33,    86,    32,   112,\n      60,    57,    41,    86,    98,   122,    88,    91,    94,    86,\n     102,   124,    24,    26,    28,   115,   113,   127,   117,     0,\n       0,   119,    32,    32,    32,    32,    97,    41,    41,    41,\n      76,    24,    26,    28,    41,    68,    24,    26,    28,    49,\n       0,     0,    23,     0,    25,    27,   114,     0,     0,   114,\n      41,    43,   114,    48,     0,     0,   116,    59,     0,   118,\n       0,     0,   120,     0,     0,    76,    76,    76,   114,    76,\n      41,    41,    41,     0,    41,    23,    25,    27,     0,     0,\n      32,     0,    59,    32,     0,     0,    32,    87,    90,    93,\n      89,    92,    95,     0,    23,    25,    27,   105,     0,     0,\n      41,   109,    32,    69,    70,    71,    75,     0,     0,     0,\n      80,    87,    90,    93,    89,    92,    95,     0,    23,    25,\n      27,    29,     2,    30,    31,     5,     6,     7,     0,     0,\n      10,   121,     0,    57,     0,     0,     0,     0,     0,     0,\n      58,    69,    70,    71,     0,    80,    69,    70,    71,   105,\n     109,   105,   109,   105,   109,    53,     2,    54,    55,     5,\n       6,     7,     8,     0,    10,    56,     0,    57,     0,    11,\n       0,    12,     0,     0,    58,    77,     2,    78,    79,    37,\n       6,     7,     8,     0,    10,    56,     0,    57,     0,    11,\n       0,    12,     0,     0,    58,     1,     2,     3,     4,     5,\n       6,     7,     8,     0,    10,     0,     0,     0,     0,    11,\n       0,    12,    47,     1,     2,     3,     4,     5,     6,     7,\n       8,     9,    10,     0,     0,     0,     0,    11,     0,    12,\n       1,     2,     3,     4,     5,     6,     7,     8,     0,    10,\n       0,     0,     0,     0,    11,    42,    12,    53,     2,    54,\n      55,     5,     6,     7,     8,     0,    10,    86,     0,     0,\n       0,    11,     0,    12,    77,     2,    78,    79,    37,     6,\n       7,     8,     0,    10,    86,     0,     0,     0,    11,     0,\n      12,     1,     2,     3,     4,     5,     6,     7,     8,     0,\n      10,     0,     0,     0,     0,    11,     0,    12,    34,     2,\n      35,    36,    37,     6,     7,     8,     0,    10,     0,     0,\n       0,     0,    11,     0,    12,    29,     2,    30,    31,     5,\n       6,     7,     0,     0,    10,    56,    72,     2,    73,    74,\n      37,     6,     7,     0,     0,    10,    56,    29,     2,    30,\n      31,     5,     6,     7,     0,     0,    10,    72,     2,    73,\n      74,    37,     6,     7,     0,     0,    10\n};\n\nstatic const yysigned_char yycheck[] =\n{\n       1,    57,     3,     4,     5,    59,    12,     0,     0,   105,\n      63,    64,    14,   109,    67,    16,    20,    21,    18,    11,\n      12,    21,    53,    54,    55,    81,    16,    80,    29,    30,\n      31,    32,    16,    34,    35,    36,    37,    13,     5,    83,\n      41,    15,     9,    13,    14,    99,    77,    78,    79,    13,\n      14,   107,    53,    54,    55,    87,    85,   109,    90,    -1,\n      -1,    93,    29,    30,    31,    32,    58,    34,    35,    36,\n      37,    72,    73,    74,    41,    76,    77,    78,    79,    85,\n      -1,    -1,     1,    -1,     3,     4,    87,    -1,    -1,    90,\n      57,    83,    93,    85,    -1,    -1,    87,    16,    -1,    90,\n      -1,    -1,    93,    -1,    -1,    72,    73,    74,   109,    76,\n      77,    78,    79,    -1,    81,    34,    35,    36,    -1,    -1,\n      87,    -1,    41,    90,    -1,    -1,    93,    53,    54,    55,\n      53,    54,    55,    -1,    53,    54,    55,    63,    -1,    -1,\n     107,    67,   109,    34,    35,    36,    37,    -1,    -1,    -1,\n      41,    77,    78,    79,    77,    78,    79,    -1,    77,    78,\n      79,     3,     4,     5,     6,     7,     8,     9,    -1,    -1,\n      12,    97,    -1,    15,    -1,    -1,    -1,    -1,    -1,    -1,\n      22,    72,    73,    74,    -1,    76,    77,    78,    79,   115,\n     116,   117,   118,   119,   120,     3,     4,     5,     6,     7,\n       8,     9,    10,    -1,    12,    13,    -1,    15,    -1,    17,\n      -1,    19,    -1,    -1,    22,     3,     4,     5,     6,     7,\n       8,     9,    10,    -1,    12,    13,    -1,    15,    -1,    17,\n      -1,    19,    -1,    -1,    22,     3,     4,     5,     6,     7,\n       8,     9,    10,    -1,    12,    -1,    -1,    -1,    -1,    17,\n      -1,    19,    20,     3,     4,     5,     6,     7,     8,     9,\n      10,    11,    12,    -1,    -1,    -1,    -1,    17,    -1,    19,\n       3,     4,     5,     6,     7,     8,     9,    10,    -1,    12,\n      -1,    -1,    -1,    -1,    17,    18,    19,     3,     4,     5,\n       6,     7,     8,     9,    10,    -1,    12,    13,    -1,    -1,\n      -1,    17,    -1,    19,     3,     4,     5,     6,     7,     8,\n       9,    10,    -1,    12,    13,    -1,    -1,    -1,    17,    -1,\n      19,     3,     4,     5,     6,     7,     8,     9,    10,    -1,\n      12,    -1,    -1,    -1,    -1,    17,    -1,    19,     3,     4,\n       5,     6,     7,     8,     9,    10,    -1,    12,    -1,    -1,\n      -1,    -1,    17,    -1,    19,     3,     4,     5,     6,     7,\n       8,     9,    -1,    -1,    12,    13,     3,     4,     5,     6,\n       7,     8,     9,    -1,    -1,    12,    13,     3,     4,     5,\n       6,     7,     8,     9,    -1,    -1,    12,     3,     4,     5,\n       6,     7,     8,     9,    -1,    -1,    12\n};\n\n/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing\n   symbol of state STATE-NUM.  */\nstatic const unsigned char yystos[] =\n{\n       0,     3,     4,     5,     6,     7,     8,     9,    10,    11,\n      12,    17,    19,    24,    25,    26,    29,    33,    34,    35,\n      39,    42,    49,    26,    33,    26,    33,    26,    33,     3,\n       5,     6,    29,    33,     3,     5,     6,     7,    25,    27,\n      28,    29,    18,    25,    40,    41,    48,    20,    25,    48,\n      50,    51,     0,     3,     5,     6,    13,    15,    22,    26,\n      33,    36,    37,    38,    43,    44,    46,    47,    33,    28,\n      28,    28,     3,     5,     6,    28,    29,     3,     5,     6,\n      28,    16,    18,    21,    20,    21,    13,    31,    37,    43,\n      31,    37,    43,    31,    37,    43,    27,    25,    14,    31,\n      32,    32,    14,    30,    30,    31,    30,    16,    30,    31,\n      30,    27,    41,    51,    33,    38,    47,    38,    47,    38,\n      47,    31,    32,    36,    27,    45,    36,    46\n};\n\n#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)\n# define YYSIZE_T __SIZE_TYPE__\n#endif\n#if ! defined (YYSIZE_T) && defined (size_t)\n# define YYSIZE_T size_t\n#endif\n#if ! defined (YYSIZE_T)\n# if defined (__STDC__) || defined (__cplusplus)\n#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYSIZE_T size_t\n# endif\n#endif\n#if ! defined (YYSIZE_T)\n# define YYSIZE_T unsigned int\n#endif\n\n#define yyerrok\t\t(yyerrstatus = 0)\n#define yyclearin\t(yychar = YYEMPTY)\n#define YYEMPTY\t\t(-2)\n#define YYEOF\t\t0\n\n#define YYACCEPT\tgoto yyacceptlab\n#define YYABORT\t\tgoto yyabortlab\n#define YYERROR\t\tgoto yyerrorlab\n\n\n/* Like YYERROR except do call yyerror.  This remains here temporarily\n   to ease the transition to the new meaning of YYERROR, for GCC.\n   Once GCC version 2 has supplanted version 1, this can go.  */\n\n#define YYFAIL\t\tgoto yyerrlab\n\n#define YYRECOVERING()  (!!yyerrstatus)\n\n#define YYBACKUP(Token, Value)\t\t\t\t\t\\\ndo\t\t\t\t\t\t\t\t\\\n  if (yychar == YYEMPTY && yylen == 1)\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      yychar = (Token);\t\t\t\t\t\t\\\n      yylval = (Value);\t\t\t\t\t\t\\\n      yytoken = YYTRANSLATE (yychar);\t\t\t\t\\\n      YYPOPSTACK;\t\t\t\t\t\t\\\n      goto yybackup;\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\n  else\t\t\t\t\t\t\t\t\\\n    { \t\t\t\t\t\t\t\t\\\n      yyerror (\"syntax error: cannot back up\");\\\n      YYERROR;\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\nwhile (0)\n\n#define YYTERROR\t1\n#define YYERRCODE\t256\n\n/* YYLLOC_DEFAULT -- Compute the default location (before the actions\n   are run).  */\n\n#ifndef YYLLOC_DEFAULT\n# define YYLLOC_DEFAULT(Current, Rhs, N)\t\t\\\n   ((Current).first_line   = (Rhs)[1].first_line,\t\\\n    (Current).first_column = (Rhs)[1].first_column,\t\\\n    (Current).last_line    = (Rhs)[N].last_line,\t\\\n    (Current).last_column  = (Rhs)[N].last_column)\n#endif\n\n/* YYLEX -- calling `yylex' with the right arguments.  */\n\n#ifdef YYLEX_PARAM\n# define YYLEX yylex (&yylval, YYLEX_PARAM)\n#else\n# define YYLEX yylex (&yylval)\n#endif\n\n/* Enable debugging if requested.  */\n#if YYDEBUG\n\n# ifndef YYFPRINTF\n#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYFPRINTF fprintf\n# endif\n\n# define YYDPRINTF(Args)\t\t\t\\\ndo {\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\\\n    YYFPRINTF Args;\t\t\t\t\\\n} while (0)\n\n# define YYDSYMPRINT(Args)\t\t\t\\\ndo {\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\\\n    yysymprint Args;\t\t\t\t\\\n} while (0)\n\n# define YYDSYMPRINTF(Title, Token, Value, Location)\t\t\\\ndo {\t\t\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\t\t\\\n    {\t\t\t\t\t\t\t\t\\\n      YYFPRINTF (stderr, \"%s \", Title);\t\t\t\t\\\n      yysymprint (stderr, \t\t\t\t\t\\\n                  Token, Value);\t\\\n      YYFPRINTF (stderr, \"\\n\");\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\\\n} while (0)\n\n/*------------------------------------------------------------------.\n| yy_stack_print -- Print the state stack from its BOTTOM up to its |\n| TOP (included).                                                   |\n`------------------------------------------------------------------*/\n\n#if defined (__STDC__) || defined (__cplusplus)\nstatic void\nyy_stack_print (short int *bottom, short int *top)\n#else\nstatic void\nyy_stack_print (bottom, top)\n    short int *bottom;\n    short int *top;\n#endif\n{\n  YYFPRINTF (stderr, \"Stack now\");\n  for (/* Nothing. */; bottom <= top; ++bottom)\n    YYFPRINTF (stderr, \" %d\", *bottom);\n  YYFPRINTF (stderr, \"\\n\");\n}\n\n# define YY_STACK_PRINT(Bottom, Top)\t\t\t\t\\\ndo {\t\t\t\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\t\t\t\\\n    yy_stack_print ((Bottom), (Top));\t\t\t\t\\\n} while (0)\n\n\n/*------------------------------------------------.\n| Report that the YYRULE is going to be reduced.  |\n`------------------------------------------------*/\n\n#if defined (__STDC__) || defined (__cplusplus)\nstatic void\nyy_reduce_print (int yyrule)\n#else\nstatic void\nyy_reduce_print (yyrule)\n    int yyrule;\n#endif\n{\n  int yyi;\n  unsigned int yylno = yyrline[yyrule];\n  YYFPRINTF (stderr, \"Reducing stack by rule %d (line %u), \",\n             yyrule - 1, yylno);\n  /* Print the symbols being reduced, and their result.  */\n  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)\n    YYFPRINTF (stderr, \"%s \", yytname [yyrhs[yyi]]);\n  YYFPRINTF (stderr, \"-> %s\\n\", yytname [yyr1[yyrule]]);\n}\n\n# define YY_REDUCE_PRINT(Rule)\t\t\\\ndo {\t\t\t\t\t\\\n  if (yydebug)\t\t\t\t\\\n    yy_reduce_print (Rule);\t\t\\\n} while (0)\n\n/* Nonzero means print parse trace.  It is left uninitialized so that\n   multiple parsers can coexist.  */\nint yydebug;\n#else /* !YYDEBUG */\n# define YYDPRINTF(Args)\n# define YYDSYMPRINT(Args)\n# define YYDSYMPRINTF(Title, Token, Value, Location)\n# define YY_STACK_PRINT(Bottom, Top)\n# define YY_REDUCE_PRINT(Rule)\n#endif /* !YYDEBUG */\n\n\n/* YYINITDEPTH -- initial size of the parser's stacks.  */\n#ifndef\tYYINITDEPTH\n# define YYINITDEPTH 200\n#endif\n\n/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only\n   if the built-in stack extension method is used).\n\n   Do not make this value too large; the results are undefined if\n   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)\n   evaluated with infinite-precision integer arithmetic.  */\n\n#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0\n# undef YYMAXDEPTH\n#endif\n\n#ifndef YYMAXDEPTH\n# define YYMAXDEPTH 10000\n#endif\n\n\f\n\n#if YYERROR_VERBOSE\n\n# ifndef yystrlen\n#  if defined (__GLIBC__) && defined (_STRING_H)\n#   define yystrlen strlen\n#  else\n/* Return the length of YYSTR.  */\nstatic YYSIZE_T\n#   if defined (__STDC__) || defined (__cplusplus)\nyystrlen (const char *yystr)\n#   else\nyystrlen (yystr)\n     const char *yystr;\n#   endif\n{\n  register const char *yys = yystr;\n\n  while (*yys++ != '\\0')\n    continue;\n\n  return yys - yystr - 1;\n}\n#  endif\n# endif\n\n# ifndef yystpcpy\n#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)\n#   define yystpcpy stpcpy\n#  else\n/* Copy YYSRC to YYDEST, returning the address of the terminating '\\0' in\n   YYDEST.  */\nstatic char *\n#   if defined (__STDC__) || defined (__cplusplus)\nyystpcpy (char *yydest, const char *yysrc)\n#   else\nyystpcpy (yydest, yysrc)\n     char *yydest;\n     const char *yysrc;\n#   endif\n{\n  register char *yyd = yydest;\n  register const char *yys = yysrc;\n\n  while ((*yyd++ = *yys++) != '\\0')\n    continue;\n\n  return yyd - 1;\n}\n#  endif\n# endif\n\n#endif /* !YYERROR_VERBOSE */\n\n\f\n\n#if YYDEBUG\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\n#if defined (__STDC__) || defined (__cplusplus)\nstatic void\nyysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)\n#else\nstatic void\nyysymprint (yyoutput, yytype, yyvaluep)\n    FILE *yyoutput;\n    int yytype;\n    YYSTYPE *yyvaluep;\n#endif\n{\n  /* Pacify ``unused variable'' warnings.  */\n  (void) yyvaluep;\n\n  if (yytype < YYNTOKENS)\n    {\n      YYFPRINTF (yyoutput, \"token %s (\", yytname[yytype]);\n# ifdef YYPRINT\n      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);\n# endif\n    }\n  else\n    YYFPRINTF (yyoutput, \"nterm %s (\", yytname[yytype]);\n\n  switch (yytype)\n    {\n      default:\n        break;\n    }\n  YYFPRINTF (yyoutput, \")\");\n}\n\n#endif /* ! YYDEBUG */\n/*-----------------------------------------------.\n| Release the memory associated to this symbol.  |\n`-----------------------------------------------*/\n\n#if defined (__STDC__) || defined (__cplusplus)\nstatic void\nyydestruct (int yytype, YYSTYPE *yyvaluep)\n#else\nstatic void\nyydestruct (yytype, yyvaluep)\n    int yytype;\n    YYSTYPE *yyvaluep;\n#endif\n{\n  /* Pacify ``unused variable'' warnings.  */\n  (void) yyvaluep;\n\n  switch (yytype)\n    {\n\n      default:\n        break;\n    }\n}\n\f\n\n/* Prevent warnings from -Wmissing-prototypes.  */\n\n#ifdef YYPARSE_PARAM\n# if defined (__STDC__) || defined (__cplusplus)\nint yyparse (void *YYPARSE_PARAM);\n# else\nint yyparse ();\n# endif\n#else /* ! YYPARSE_PARAM */\n#if defined (__STDC__) || defined (__cplusplus)\nint yyparse (void);\n#else\nint yyparse ();\n#endif\n#endif /* ! YYPARSE_PARAM */\n\n\n\n\n\n\n/*----------.\n| yyparse.  |\n`----------*/\n\n#ifdef YYPARSE_PARAM\n# if defined (__STDC__) || defined (__cplusplus)\nint yyparse (void *YYPARSE_PARAM)\n# else\nint yyparse (YYPARSE_PARAM)\n  void *YYPARSE_PARAM;\n# endif\n#else /* ! YYPARSE_PARAM */\n#if defined (__STDC__) || defined (__cplusplus)\nint\nyyparse (void)\n#else\nint\nyyparse ()\n\n#endif\n#endif\n{\n  /* The lookahead symbol.  */\nint yychar;\n\n/* The semantic value of the lookahead symbol.  */\nYYSTYPE yylval;\n\n/* Number of syntax errors so far.  */\nint yynerrs;\n\n  register int yystate;\n  register int yyn;\n  int yyresult;\n  /* Number of tokens to shift before error messages enabled.  */\n  int yyerrstatus;\n  /* Lookahead token as an internal (translated) token number.  */\n  int yytoken = 0;\n\n  /* Three stacks and their tools:\n     `yyss': related to states,\n     `yyvs': related to semantic values,\n     `yyls': related to locations.\n\n     Refer to the stacks thru separate pointers, to allow yyoverflow\n     to reallocate them elsewhere.  */\n\n  /* The state stack.  */\n  short int yyssa[YYINITDEPTH];\n  short int *yyss = yyssa;\n  register short int *yyssp;\n\n  /* The semantic value stack.  */\n  YYSTYPE yyvsa[YYINITDEPTH];\n  YYSTYPE *yyvs = yyvsa;\n  register YYSTYPE *yyvsp;\n\n\n\n#define YYPOPSTACK   (yyvsp--, yyssp--)\n\n  YYSIZE_T yystacksize = YYINITDEPTH;\n\n  /* The variables used to return semantic value and location from the\n     action routines.  */\n  YYSTYPE yyval;\n\n\n  /* When reducing, the number of symbols on the RHS of the reduced\n     rule.  */\n  int yylen;\n\n  YYDPRINTF ((stderr, \"Starting parse\\n\"));\n\n  yystate = 0;\n  yyerrstatus = 0;\n  yynerrs = 0;\n  yychar = YYEMPTY;\t\t/* Cause a token to be read.  */\n\n  /* Initialize stack pointers.\n     Waste one element of value and location stack\n     so that they stay on the same level as the state stack.\n     The wasted elements are never initialized.  */\n\n  yyssp = yyss;\n  yyvsp = yyvs;\n\n\n  goto yysetstate;\n\n/*------------------------------------------------------------.\n| yynewstate -- Push a new state, which is found in yystate.  |\n`------------------------------------------------------------*/\n yynewstate:\n  /* In all cases, when you get here, the value and location stacks\n     have just been pushed. so pushing a state here evens the stacks.\n     */\n  yyssp++;\n\n yysetstate:\n  *yyssp = yystate;\n\n  if (yyss + yystacksize - 1 <= yyssp)\n    {\n      /* Get the current used size of the three stacks, in elements.  */\n      YYSIZE_T yysize = yyssp - yyss + 1;\n\n#ifdef yyoverflow\n      {\n\t/* Give user a chance to reallocate the stack. Use copies of\n\t   these so that the &'s don't force the real ones into\n\t   memory.  */\n\tYYSTYPE *yyvs1 = yyvs;\n\tshort int *yyss1 = yyss;\n\n\n\t/* Each stack pointer address is followed by the size of the\n\t   data in use in that stack, in bytes.  This used to be a\n\t   conditional around just the two extra args, but that might\n\t   be undefined if yyoverflow is a macro.  */\n\tyyoverflow (\"parser stack overflow\",\n\t\t    &yyss1, yysize * sizeof (*yyssp),\n\t\t    &yyvs1, yysize * sizeof (*yyvsp),\n\n\t\t    &yystacksize);\n\n\tyyss = yyss1;\n\tyyvs = yyvs1;\n      }\n#else /* no yyoverflow */\n# ifndef YYSTACK_RELOCATE\n      goto yyoverflowlab;\n# else\n      /* Extend the stack our own way.  */\n      if (YYMAXDEPTH <= yystacksize)\n\tgoto yyoverflowlab;\n      yystacksize *= 2;\n      if (YYMAXDEPTH < yystacksize)\n\tyystacksize = YYMAXDEPTH;\n\n      {\n\tshort int *yyss1 = yyss;\n\tunion yyalloc *yyptr =\n\t  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));\n\tif (! yyptr)\n\t  goto yyoverflowlab;\n\tYYSTACK_RELOCATE (yyss);\n\tYYSTACK_RELOCATE (yyvs);\n\n#  undef YYSTACK_RELOCATE\n\tif (yyss1 != yyssa)\n\t  YYSTACK_FREE (yyss1);\n      }\n# endif\n#endif /* no yyoverflow */\n\n      yyssp = yyss + yysize - 1;\n      yyvsp = yyvs + yysize - 1;\n\n\n      YYDPRINTF ((stderr, \"Stack size increased to %lu\\n\",\n\t\t  (unsigned long int) yystacksize));\n\n      if (yyss + yystacksize - 1 <= yyssp)\n\tYYABORT;\n    }\n\n  YYDPRINTF ((stderr, \"Entering state %d\\n\", yystate));\n\n  goto yybackup;\n\n/*-----------.\n| yybackup.  |\n`-----------*/\nyybackup:\n\n/* Do appropriate processing given the current state.  */\n/* Read a lookahead token if we need one and don't already have one.  */\n/* yyresume: */\n\n  /* First try to decide what to do without reference to lookahead token.  */\n\n  yyn = yypact[yystate];\n  if (yyn == YYPACT_NINF)\n    goto yydefault;\n\n  /* Not known => get a lookahead token if don't already have one.  */\n\n  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */\n  if (yychar == YYEMPTY)\n    {\n      YYDPRINTF ((stderr, \"Reading a token: \"));\n      yychar = YYLEX;\n    }\n\n  if (yychar <= YYEOF)\n    {\n      yychar = yytoken = YYEOF;\n      YYDPRINTF ((stderr, \"Now at end of input.\\n\"));\n    }\n  else\n    {\n      yytoken = YYTRANSLATE (yychar);\n      YYDSYMPRINTF (\"Next token is\", yytoken, &yylval, &yylloc);\n    }\n\n  /* If the proper action on seeing token YYTOKEN is to reduce or to\n     detect an error, take that action.  */\n  yyn += yytoken;\n  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)\n    goto yydefault;\n  yyn = yytable[yyn];\n  if (yyn <= 0)\n    {\n      if (yyn == 0 || yyn == YYTABLE_NINF)\n\tgoto yyerrlab;\n      yyn = -yyn;\n      goto yyreduce;\n    }\n\n  if (yyn == YYFINAL)\n    YYACCEPT;\n\n  /* Shift the lookahead token.  */\n  YYDPRINTF ((stderr, \"Shifting token %s, \", yytname[yytoken]));\n\n  /* Discard the token being shifted unless it is eof.  */\n  if (yychar != YYEOF)\n    yychar = YYEMPTY;\n\n  *++yyvsp = yylval;\n\n\n  /* Count tokens shifted since error; after three, turn off error\n     status.  */\n  if (yyerrstatus)\n    yyerrstatus--;\n\n  yystate = yyn;\n  goto yynewstate;\n\n\n/*-----------------------------------------------------------.\n| yydefault -- do the default action for the current state.  |\n`-----------------------------------------------------------*/\nyydefault:\n  yyn = yydefact[yystate];\n  if (yyn == 0)\n    goto yyerrlab;\n  goto yyreduce;\n\n\n/*-----------------------------.\n| yyreduce -- Do a reduction.  |\n`-----------------------------*/\nyyreduce:\n  /* yyn is the number of a rule to reduce with.  */\n  yylen = yyr2[yyn];\n\n  /* If YYLEN is nonzero, implement the default value of the action:\n     `$$ = $1'.\n\n     Otherwise, the following line sets YYVAL to garbage.\n     This behavior is undocumented and Bison\n     users should not rely upon it.  Assigning to YYVAL\n     unconditionally makes the parser a bit smaller, and it avoids a\n     GCC warning that YYVAL may be used uninitialized.  */\n  yyval = yyvsp[1-yylen];\n\n\n  YY_REDUCE_PRINT (yyn);\n  switch (yyn)\n    {\n        case 2:\n#line 57 \"gram.y\"\n    {\n           ((SyckParser *)parser)->root = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData );\n        }\n    break;\n\n  case 3:\n#line 61 \"gram.y\"\n    {\n           ((SyckParser *)parser)->root = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData );\n        }\n    break;\n\n  case 4:\n#line 65 \"gram.y\"\n    {\n           ((SyckParser *)parser)->eof = 1;\n        }\n    break;\n\n  case 8:\n#line 76 \"gram.y\"\n    { \n            syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n            yyval.nodeData = yyvsp[0].nodeData;\n        }\n    break;\n\n  case 9:\n#line 81 \"gram.y\"\n    {\n            syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 );\n            yyval.nodeData = yyvsp[0].nodeData;\n        }\n    break;\n\n  case 10:\n#line 86 \"gram.y\"\n    { \n           /*\n            * _Anchors_: The language binding must keep a separate symbol table\n            * for anchors.  The actual ID in the symbol table is returned to the\n            * higher nodes, though.\n            */\n           yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData );\n        }\n    break;\n\n  case 11:\n#line 95 \"gram.y\"\n    {\n           yyval.nodeData = yyvsp[-1].nodeData;\n        }\n    break;\n\n  case 14:\n#line 105 \"gram.y\"\n    {\n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 15:\n#line 109 \"gram.y\"\n    {\n                    NULL_NODE( parser, n );\n                    yyval.nodeData = n;\n                }\n    break;\n\n  case 16:\n#line 114 \"gram.y\"\n    { \n                   if ( ((SyckParser *)parser)->implicit_typing == 1 )\n                   {\n                      try_tag_implicit( yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n                   }\n                   yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 17:\n#line 122 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 18:\n#line 127 \"gram.y\"\n    {\n                    syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 19:\n#line 132 \"gram.y\"\n    { \n                   /*\n                    * _Anchors_: The language binding must keep a separate symbol table\n                    * for anchors.  The actual ID in the symbol table is returned to the\n                    * higher nodes, though.\n                    */\n                   yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData );\n                }\n    break;\n\n  case 26:\n#line 165 \"gram.y\"\n    { \n               syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n               yyval.nodeData = yyvsp[0].nodeData;\n            }\n    break;\n\n  case 27:\n#line 170 \"gram.y\"\n    { \n               syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 );\n               yyval.nodeData = yyvsp[0].nodeData;\n            }\n    break;\n\n  case 28:\n#line 175 \"gram.y\"\n    { \n               if ( ((SyckParser *)parser)->implicit_typing == 1 )\n               {\n                  try_tag_implicit( yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n               }\n               yyval.nodeData = yyvsp[0].nodeData;\n            }\n    break;\n\n  case 29:\n#line 183 \"gram.y\"\n    { \n               yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData );\n            }\n    break;\n\n  case 30:\n#line 187 \"gram.y\"\n    {\n               /*\n                * _Aliases_: The anchor symbol table is scanned for the anchor name.\n                * The anchor's ID in the language's symbol table is returned.\n                */\n               yyval.nodeData = syck_hdlr_get_anchor( (SyckParser *)parser, yyvsp[0].name );\n            }\n    break;\n\n  case 31:\n#line 195 \"gram.y\"\n    { \n               SyckNode *n = yyvsp[0].nodeData;\n               if ( ((SyckParser *)parser)->taguri_expansion == 1 )\n               {\n                   n->type_id = syck_taguri( YAML_DOMAIN, \"str\", 3 );\n               }\n               else\n               {\n                   n->type_id = syck_strndup( \"str\", 3 );\n               }\n               yyval.nodeData = n;\n            }\n    break;\n\n  case 33:\n#line 209 \"gram.y\"\n    {\n               yyval.nodeData = yyvsp[-1].nodeData;\n            }\n    break;\n\n  case 39:\n#line 229 \"gram.y\"\n    { \n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 40:\n#line 233 \"gram.y\"\n    { \n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 41:\n#line 239 \"gram.y\"\n    { \n                    yyval.nodeId = syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData );\n                }\n    break;\n\n  case 42:\n#line 245 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 43:\n#line 250 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 44:\n#line 255 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, 0 );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 45:\n#line 260 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 46:\n#line 265 \"gram.y\"\n    { \n                    yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-2].name, yyvsp[0].nodeData );\n                }\n    break;\n\n  case 47:\n#line 269 \"gram.y\"\n    { \n                    yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData );\n                }\n    break;\n\n  case 48:\n#line 275 \"gram.y\"\n    {\n                    yyval.nodeData = syck_new_seq( yyvsp[0].nodeId );\n                }\n    break;\n\n  case 49:\n#line 279 \"gram.y\"\n    { \n                    syck_seq_add( yyvsp[-2].nodeData, yyvsp[0].nodeId );\n                    yyval.nodeData = yyvsp[-2].nodeData;\n\t\t\t\t}\n    break;\n\n  case 50:\n#line 284 \"gram.y\"\n    { \n                    yyval.nodeData = yyvsp[-1].nodeData;\n\t\t\t\t}\n    break;\n\n  case 51:\n#line 293 \"gram.y\"\n    { \n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 52:\n#line 297 \"gram.y\"\n    { \n                    yyval.nodeData = syck_alloc_seq();\n                }\n    break;\n\n  case 53:\n#line 303 \"gram.y\"\n    {\n                    yyval.nodeData = syck_new_seq( syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) );\n                }\n    break;\n\n  case 54:\n#line 307 \"gram.y\"\n    { \n                    syck_seq_add( yyvsp[-2].nodeData, syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) );\n                    yyval.nodeData = yyvsp[-2].nodeData;\n\t\t\t\t}\n    break;\n\n  case 57:\n#line 321 \"gram.y\"\n    { \n                    apply_seq_in_map( (SyckParser *)parser, yyvsp[-1].nodeData );\n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 58:\n#line 326 \"gram.y\"\n    { \n                    apply_seq_in_map( (SyckParser *)parser, yyvsp[-1].nodeData );\n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 59:\n#line 333 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 60:\n#line 338 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, ((SyckParser *)parser)->taguri_expansion );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 61:\n#line 343 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-2].name, yyvsp[0].nodeData, 0 );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 62:\n#line 348 \"gram.y\"\n    { \n                    syck_add_transfer( yyvsp[-1].name, yyvsp[0].nodeData, 0 );\n                    yyval.nodeData = yyvsp[0].nodeData;\n                }\n    break;\n\n  case 63:\n#line 353 \"gram.y\"\n    { \n                    yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-2].name, yyvsp[0].nodeData );\n                }\n    break;\n\n  case 64:\n#line 357 \"gram.y\"\n    { \n                    yyval.nodeData = syck_hdlr_add_anchor( (SyckParser *)parser, yyvsp[-1].name, yyvsp[0].nodeData );\n                }\n    break;\n\n  case 66:\n#line 364 \"gram.y\"\n    {\n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 68:\n#line 380 \"gram.y\"\n    {\n                    yyval.nodeData = syck_new_map( \n                        syck_hdlr_add_node( (SyckParser *)parser, yyvsp[-2].nodeData ), \n                        syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) );\n                }\n    break;\n\n  case 70:\n#line 398 \"gram.y\"\n    {\n                    if ( yyvsp[-2].nodeData->shortcut == NULL )\n                    {\n                        yyvsp[-2].nodeData->shortcut = syck_new_seq( yyvsp[0].nodeId );\n                    }\n                    else\n                    {\n                        syck_seq_add( yyvsp[-2].nodeData->shortcut, yyvsp[0].nodeId );\n                    }\n                    yyval.nodeData = yyvsp[-2].nodeData;\n                }\n    break;\n\n  case 71:\n#line 410 \"gram.y\"\n    {\n                    apply_seq_in_map( (SyckParser *)parser, yyvsp[-2].nodeData );\n                    syck_map_update( yyvsp[-2].nodeData, yyvsp[0].nodeData );\n                    syck_free_node( yyvsp[0].nodeData );\n                    yyvsp[0].nodeData = NULL;\n                    yyval.nodeData = yyvsp[-2].nodeData;\n                }\n    break;\n\n  case 72:\n#line 418 \"gram.y\"\n    {\n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 73:\n#line 427 \"gram.y\"\n    {\n                    yyval.nodeData = syck_new_map( \n                        syck_hdlr_add_node( (SyckParser *)parser, yyvsp[-2].nodeData ), \n                        syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ) );\n                }\n    break;\n\n  case 74:\n#line 435 \"gram.y\"\n    {\n                    yyval.nodeData = yyvsp[-1].nodeData;\n                }\n    break;\n\n  case 75:\n#line 439 \"gram.y\"\n    {\n                    yyval.nodeData = syck_alloc_map();\n                }\n    break;\n\n  case 77:\n#line 446 \"gram.y\"\n    {\n                    syck_map_update( yyvsp[-2].nodeData, yyvsp[0].nodeData );\n                    syck_free_node( yyvsp[0].nodeData );\n                    yyvsp[0].nodeData = NULL;\n                    yyval.nodeData = yyvsp[-2].nodeData;\n\t\t\t\t}\n    break;\n\n  case 78:\n#line 455 \"gram.y\"\n    {\n                    NULL_NODE( parser, n );\n                    yyval.nodeData = syck_new_map( \n                        syck_hdlr_add_node( (SyckParser *)parser, yyvsp[0].nodeData ), \n                        syck_hdlr_add_node( (SyckParser *)parser, n ) );\n                }\n    break;\n\n\n    }\n\n/* Line 1010 of yacc.c.  */\n#line 1651 \"gram.c\"\n\f\n  yyvsp -= yylen;\n  yyssp -= yylen;\n\n\n  YY_STACK_PRINT (yyss, yyssp);\n\n  *++yyvsp = yyval;\n\n\n  /* Now `shift' the result of the reduction.  Determine what state\n     that goes to, based on the state we popped back to and the rule\n     number reduced by.  */\n\n  yyn = yyr1[yyn];\n\n  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;\n  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)\n    yystate = yytable[yystate];\n  else\n    yystate = yydefgoto[yyn - YYNTOKENS];\n\n  goto yynewstate;\n\n\n/*------------------------------------.\n| yyerrlab -- here on detecting error |\n`------------------------------------*/\nyyerrlab:\n  /* If not already recovering from an error, report this error.  */\n  if (!yyerrstatus)\n    {\n      ++yynerrs;\n#if YYERROR_VERBOSE\n      yyn = yypact[yystate];\n\n      if (YYPACT_NINF < yyn && yyn < YYLAST)\n\t{\n\t  YYSIZE_T yysize = 0;\n\t  int yytype = YYTRANSLATE (yychar);\n\t  const char* yyprefix;\n\t  char *yymsg;\n\t  int yyx;\n\n\t  /* Start YYX at -YYN if negative to avoid negative indexes in\n\t     YYCHECK.  */\n\t  int yyxbegin = yyn < 0 ? -yyn : 0;\n\n\t  /* Stay within bounds of both yycheck and yytname.  */\n\t  int yychecklim = YYLAST - yyn;\n\t  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\n\t  int yycount = 0;\n\n\t  yyprefix = \", expecting \";\n\t  for (yyx = yyxbegin; yyx < yyxend; ++yyx)\n\t    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)\n\t      {\n\t\tyysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);\n\t\tyycount += 1;\n\t\tif (yycount == 5)\n\t\t  {\n\t\t    yysize = 0;\n\t\t    break;\n\t\t  }\n\t      }\n\t  yysize += (sizeof (\"syntax error, unexpected \")\n\t\t     + yystrlen (yytname[yytype]));\n\t  yymsg = (char *) YYSTACK_ALLOC (yysize);\n\t  if (yymsg != 0)\n\t    {\n\t      char *yyp = yystpcpy (yymsg, \"syntax error, unexpected \");\n\t      yyp = yystpcpy (yyp, yytname[yytype]);\n\n\t      if (yycount < 5)\n\t\t{\n\t\t  yyprefix = \", expecting \";\n\t\t  for (yyx = yyxbegin; yyx < yyxend; ++yyx)\n\t\t    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)\n\t\t      {\n\t\t\tyyp = yystpcpy (yyp, yyprefix);\n\t\t\tyyp = yystpcpy (yyp, yytname[yyx]);\n\t\t\tyyprefix = \" or \";\n\t\t      }\n\t\t}\n\t      yyerror (yymsg);\n\t      YYSTACK_FREE (yymsg);\n\t    }\n\t  else\n\t    yyerror (\"syntax error; also virtual memory exhausted\");\n\t}\n      else\n#endif /* YYERROR_VERBOSE */\n\tyyerror (\"syntax error\");\n    }\n\n\n\n  if (yyerrstatus == 3)\n    {\n      /* If just tried and failed to reuse lookahead token after an\n\t error, discard it.  */\n\n      if (yychar <= YYEOF)\n        {\n          /* If at end of input, pop the error token,\n\t     then the rest of the stack, then return failure.  */\n\t  if (yychar == YYEOF)\n\t     for (;;)\n\t       {\n\t\t YYPOPSTACK;\n\t\t if (yyssp == yyss)\n\t\t   YYABORT;\n\t\t YYDSYMPRINTF (\"Error: popping\", yystos[*yyssp], yyvsp, yylsp);\n\t\t yydestruct (yystos[*yyssp], yyvsp);\n\t       }\n        }\n      else\n\t{\n\t  YYDSYMPRINTF (\"Error: discarding\", yytoken, &yylval, &yylloc);\n\t  yydestruct (yytoken, &yylval);\n\t  yychar = YYEMPTY;\n\n\t}\n    }\n\n  /* Else will try to reuse lookahead token after shifting the error\n     token.  */\n  goto yyerrlab1;\n\n\n/*---------------------------------------------------.\n| yyerrorlab -- error raised explicitly by YYERROR.  |\n`---------------------------------------------------*/\nyyerrorlab:\n\n#ifdef __GNUC__\n  /* Pacify GCC when the user code never invokes YYERROR and the label\n     yyerrorlab therefore never appears in user code.  */\n  if (0)\n     goto yyerrorlab;\n#endif\n\n  yyvsp -= yylen;\n  yyssp -= yylen;\n  yystate = *yyssp;\n  goto yyerrlab1;\n\n\n/*-------------------------------------------------------------.\n| yyerrlab1 -- common code for both syntax error and YYERROR.  |\n`-------------------------------------------------------------*/\nyyerrlab1:\n  yyerrstatus = 3;\t/* Each real token shifted decrements this.  */\n\n  for (;;)\n    {\n      yyn = yypact[yystate];\n      if (yyn != YYPACT_NINF)\n\t{\n\t  yyn += YYTERROR;\n\t  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)\n\t    {\n\t      yyn = yytable[yyn];\n\t      if (0 < yyn)\n\t\tbreak;\n\t    }\n\t}\n\n      /* Pop the current state because it cannot handle the error token.  */\n      if (yyssp == yyss)\n\tYYABORT;\n\n      YYDSYMPRINTF (\"Error: popping\", yystos[*yyssp], yyvsp, yylsp);\n      yydestruct (yystos[yystate], yyvsp);\n      YYPOPSTACK;\n      yystate = *yyssp;\n      YY_STACK_PRINT (yyss, yyssp);\n    }\n\n  if (yyn == YYFINAL)\n    YYACCEPT;\n\n  YYDPRINTF ((stderr, \"Shifting error token, \"));\n\n  *++yyvsp = yylval;\n\n\n  yystate = yyn;\n  goto yynewstate;\n\n\n/*-------------------------------------.\n| yyacceptlab -- YYACCEPT comes here.  |\n`-------------------------------------*/\nyyacceptlab:\n  yyresult = 0;\n  goto yyreturn;\n\n/*-----------------------------------.\n| yyabortlab -- YYABORT comes here.  |\n`-----------------------------------*/\nyyabortlab:\n  yyresult = 1;\n  goto yyreturn;\n\n#ifndef yyoverflow\n/*----------------------------------------------.\n| yyoverflowlab -- parser overflow comes here.  |\n`----------------------------------------------*/\nyyoverflowlab:\n  yyerror (\"parser stack overflow\");\n  yyresult = 2;\n  /* Fall through.  */\n#endif\n\nyyreturn:\n#ifndef yyoverflow\n  if (yyss != yyssa)\n    YYSTACK_FREE (yyss);\n#endif\n  return yyresult;\n}\n\n\n#line 464 \"gram.y\"\n\n\nvoid\napply_seq_in_map( SyckParser *parser, SyckNode *n )\n{\n    long map_len;\n    if ( n->shortcut == NULL )\n    {\n        return;\n    }\n\n    map_len = syck_map_count( n );\n    syck_map_assign( n, map_value, map_len - 1,\n        syck_hdlr_add_node( parser, n->shortcut ) );\n\n    n->shortcut = NULL;\n}\n\n\n"
  },
  {
    "path": "ext/syck/gram.h",
    "content": "/* A Bison parser, made by GNU Bison 1.875d.  */\n\n/* Skeleton parser for Yacc-like parsing with Bison,\n   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2, or (at your option)\n   any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n\n/* As a special exception, when this file is copied by Bison into a\n   Bison output file, you may use that output file without restriction.\n   This special exception was added by the Free Software Foundation\n   in version 1.24 of Bison.  */\n\n/* Tokens.  */\n#ifndef YYTOKENTYPE\n# define YYTOKENTYPE\n   /* Put the tokens into the symbol table, so that GDB and other debuggers\n      know about them.  */\n   enum yytokentype {\n     YAML_ANCHOR = 258,\n     YAML_ALIAS = 259,\n     YAML_TRANSFER = 260,\n     YAML_TAGURI = 261,\n     YAML_ITRANSFER = 262,\n     YAML_WORD = 263,\n     YAML_PLAIN = 264,\n     YAML_BLOCK = 265,\n     YAML_DOCSEP = 266,\n     YAML_IOPEN = 267,\n     YAML_INDENT = 268,\n     YAML_IEND = 269\n   };\n#endif\n#define YAML_ANCHOR 258\n#define YAML_ALIAS 259\n#define YAML_TRANSFER 260\n#define YAML_TAGURI 261\n#define YAML_ITRANSFER 262\n#define YAML_WORD 263\n#define YAML_PLAIN 264\n#define YAML_BLOCK 265\n#define YAML_DOCSEP 266\n#define YAML_IOPEN 267\n#define YAML_INDENT 268\n#define YAML_IEND 269\n\n\n\n\n#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)\n#line 35 \"gram.y\"\ntypedef union YYSTYPE {\n    SYMID nodeId;\n    SyckNode *nodeData;\n    char *name;\n} YYSTYPE;\n/* Line 1285 of yacc.c.  */\n#line 71 \"gram.h\"\n# define yystype YYSTYPE /* obsolescent; will be withdrawn */\n# define YYSTYPE_IS_DECLARED 1\n# define YYSTYPE_IS_TRIVIAL 1\n#endif\n\n\n\n\n\n"
  },
  {
    "path": "ext/syck/handler.c",
    "content": "/*\n * handler.c\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n\n#include \"ruby.h\"\n#include \"syck.h\"\n\nSYMID \nsyck_hdlr_add_node( SyckParser *p, SyckNode *n )\n{\n    SYMID id;\n\n    if ( ! n->id ) \n    {\n        n->id = (p->handler)( p, n );\n    }\n    id = n->id;\n\n    if ( n->anchor == NULL )\n    {\n        syck_free_node( n );\n    }\n    return id;\n}\n\nSyckNode *\nsyck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n )\n{\n    SyckNode *ntmp = NULL;\n\n    n->anchor = a;\n    if ( p->bad_anchors != NULL )\n    {\n        SyckNode *bad;\n        if ( st_lookup( p->bad_anchors, (st_data_t)a, (st_data_t *)&bad ) )\n        {\n            if ( n->kind != syck_str_kind )\n            {\n                n->id = bad->id;\n                (p->handler)( p, n );\n            }\n        }\n    }\n    if ( p->anchors == NULL )\n    {\n        p->anchors = st_init_strtable();\n    }\n    if ( st_lookup( p->anchors, (st_data_t)a, (st_data_t *)&ntmp ) )\n    {\n        if ( ntmp != (void *)1 )\n        {\n            syck_free_node( ntmp );\n        }\n    }\n    st_insert( p->anchors, (st_data_t)a, (st_data_t)n );\n    return n;\n}\n\nvoid\nsyck_hdlr_remove_anchor( SyckParser *p, char *a )\n{\n    char *atmp = a;\n    SyckNode *ntmp;\n    if ( p->anchors == NULL )\n    {\n        p->anchors = st_init_strtable();\n    }\n    if ( st_delete( p->anchors, (st_data_t *)&atmp, (st_data_t *)&ntmp ) )\n    {\n        if ( ntmp != (void *)1 )\n        {\n            syck_free_node( ntmp );\n        }\n    }\n    st_insert( p->anchors, (st_data_t)a, (st_data_t)1 );\n}\n\nSyckNode *\nsyck_hdlr_get_anchor( SyckParser *p, char *a )\n{\n    SyckNode *n = NULL;\n\n    if ( p->anchors != NULL )\n    {\n        if ( st_lookup( p->anchors, (st_data_t)a, (st_data_t *)&n ) )\n        {\n            if ( n != (void *)1 )\n            {    \n                S_FREE( a );\n                return n;\n            }\n            else\n            {\n                if ( p->bad_anchors == NULL )\n                {\n                    p->bad_anchors = st_init_strtable();\n                }\n                if ( ! st_lookup( p->bad_anchors, (st_data_t)a, (st_data_t *)&n ) )\n                {\n                    n = (p->bad_anchor_handler)( p, a );\n                    st_insert( p->bad_anchors, (st_data_t)a, (st_data_t)n );\n                }\n            }\n        }\n    }\n\n    if ( n == NULL )\n    {\n        n = (p->bad_anchor_handler)( p, a );\n    }\n\n    if ( n->anchor )\n    {\n        S_FREE( a );\n    } \n    else\n    {\n        n->anchor = a;\n    }\n\n    return n;\n}\n\nvoid\nsyck_add_transfer( char *uri, SyckNode *n, int taguri )\n{\n    if ( n->type_id != NULL )\n    {\n        S_FREE( n->type_id );\n    }\n\n    if ( taguri == 0 )\n    {\n        n->type_id = uri;\n        return;\n    }\n\n    n->type_id = syck_type_id_to_uri( uri );\n    S_FREE( uri );\n}\n\nchar *\nsyck_xprivate( char *type_id, int type_len )\n{\n    char *uri = S_ALLOC_N( char, type_len + 14 );\n    uri[0] = '\\0';\n    strcat( uri, \"x-private:\" );\n    strncat( uri, type_id, type_len );\n    return uri;\n}\n\nchar *\nsyck_taguri( char *domain, char *type_id, int type_len )\n{\n    char *uri = S_ALLOC_N( char, strlen( domain ) + type_len + 14 );\n    uri[0] = '\\0';\n    strcat( uri, \"tag:\" );\n    strcat( uri, domain );\n    strcat( uri, \":\" );\n    strncat( uri, type_id, type_len );\n    return uri;\n}\n\nint \nsyck_try_implicit( SyckNode *n )\n{\n    return 1;\n}\n\n"
  },
  {
    "path": "ext/syck/implicit.c",
    "content": "/* Generated by re2c 0.9.10 on Mon Sep 19 21:46:50 2005 */\n#line 1 \"implicit.re\"\n/*\n * implicit.re\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n\n#include \"ruby.h\"\n#include \"syck.h\"\n\n#define YYCTYPE     char\n#define YYCURSOR    cursor\n#define YYMARKER    marker\n#define YYLIMIT     limit\n#define YYFILL(n)\n\nvoid\ntry_tag_implicit( SyckNode *n, int taguri )\n{\n    char *tid = \"\";\n    switch ( n->kind )\n    {\n        case syck_str_kind:\n            tid = syck_match_implicit( n->data.str->ptr, n->data.str->len );\n        break;\n\n        case syck_seq_kind:\n            tid = \"seq\";\n        break;\n\n        case syck_map_kind:\n            tid = \"map\";\n        break;\n    }\n    if ( n->type_id != NULL ) S_FREE( n->type_id );\n    if ( taguri == 1 )\n    {\n        n->type_id = syck_taguri( YAML_DOMAIN, tid, strlen( tid ) );\n    } else {\n        n->type_id = syck_strndup( tid, strlen( tid ) );\n    }\n}\n\nchar *syck_match_implicit( char *str, size_t len )\n{\n    char *cursor, *limit, *marker;\n    cursor = str;\n    limit = str + len;\n\n\n#line 55 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy0;\n\t++YYCURSOR;\nyy0:\n\tif((YYLIMIT - YYCURSOR) < 26) YYFILL(26);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy6;\n\tcase '+':\tgoto yy16;\n\tcase '-':\tgoto yy17;\n\tcase '.':\tgoto yy20;\n\tcase '0':\tgoto yy18;\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy19;\n\tcase '<':\tgoto yy22;\n\tcase '=':\tgoto yy21;\n\tcase 'F':\tgoto yy15;\n\tcase 'N':\tgoto yy5;\n\tcase 'O':\tgoto yy13;\n\tcase 'T':\tgoto yy11;\n\tcase 'Y':\tgoto yy9;\n\tcase 'f':\tgoto yy14;\n\tcase 'n':\tgoto yy4;\n\tcase 'o':\tgoto yy12;\n\tcase 't':\tgoto yy10;\n\tcase 'y':\tgoto yy8;\n\tcase '~':\tgoto yy2;\n\tdefault:\tgoto yy23;\n\t}\nyy2:\t++YYCURSOR;\n\tif((yych = *YYCURSOR) <= 0x00)\tgoto yy6;\n\tgoto yy3;\nyy3:\n#line 123 \"implicit.re\"\n{   return \"str\"; }\n#line 100 \"<stdout>\"\nyy4:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'o':\tgoto yy172;\n\tcase 'u':\tgoto yy200;\n\tdefault:\tgoto yy3;\n\t}\nyy5:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'O':\tcase 'o':\tgoto yy172;\n\tcase 'U':\tgoto yy195;\n\tcase 'u':\tgoto yy196;\n\tdefault:\tgoto yy3;\n\t}\nyy6:\t++YYCURSOR;\n\tgoto yy7;\nyy7:\n#line 85 \"implicit.re\"\n{   return \"null\"; }\n#line 121 \"<stdout>\"\nyy8:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'e':\tgoto yy194;\n\tdefault:\tgoto yy3;\n\t}\nyy9:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'E':\tgoto yy192;\n\tcase 'e':\tgoto yy193;\n\tdefault:\tgoto yy3;\n\t}\nyy10:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'r':\tgoto yy190;\n\tdefault:\tgoto yy3;\n\t}\nyy11:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'R':\tgoto yy186;\n\tcase 'r':\tgoto yy187;\n\tdefault:\tgoto yy3;\n\t}\nyy12:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'f':\tgoto yy185;\n\tcase 'n':\tgoto yy182;\n\tdefault:\tgoto yy3;\n\t}\nyy13:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'F':\tgoto yy180;\n\tcase 'N':\tcase 'n':\tgoto yy182;\n\tcase 'f':\tgoto yy181;\n\tdefault:\tgoto yy3;\n\t}\nyy14:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'a':\tgoto yy177;\n\tdefault:\tgoto yy3;\n\t}\nyy15:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'A':\tgoto yy168;\n\tcase 'a':\tgoto yy169;\n\tdefault:\tgoto yy3;\n\t}\nyy16:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '.':\tgoto yy167;\n\tcase '0':\tgoto yy158;\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy47;\n\tdefault:\tgoto yy3;\n\t}\nyy17:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '.':\tgoto yy157;\n\tcase '0':\tgoto yy158;\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy47;\n\tdefault:\tgoto yy3;\n\t}\nyy18:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x00:\tgoto yy52;\n\tcase ',':\tgoto yy142;\n\tcase '.':\tgoto yy50;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\tgoto yy140;\n\tcase '8':\n\tcase '9':\tgoto yy141;\n\tcase ':':\tgoto yy49;\n\tcase 'x':\tgoto yy144;\n\tdefault:\tgoto yy3;\n\t}\nyy19:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x00:\tgoto yy52;\n\tcase ',':\tgoto yy47;\n\tcase '.':\tgoto yy50;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy46;\n\tcase ':':\tgoto yy49;\n\tdefault:\tgoto yy3;\n\t}\nyy20:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 'I':\tgoto yy33;\n\tcase 'N':\tgoto yy31;\n\tcase 'i':\tgoto yy32;\n\tcase 'n':\tgoto yy30;\n\tdefault:\tgoto yy3;\n\t}\nyy21:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy28;\n\tgoto yy3;\nyy22:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '<':\tgoto yy24;\n\tdefault:\tgoto yy3;\n\t}\nyy23:\tyych = *++YYCURSOR;\n\tgoto yy3;\nyy24:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy26;\n\tgoto yy25;\nyy25:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy3;\n\t}\nyy26:\t++YYCURSOR;\n\tgoto yy27;\nyy27:\n#line 121 \"implicit.re\"\n{   return \"merge\"; }\n#line 279 \"<stdout>\"\nyy28:\t++YYCURSOR;\n\tgoto yy29;\nyy29:\n#line 119 \"implicit.re\"\n{   return \"default\"; }\n#line 285 \"<stdout>\"\nyy30:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'a':\tgoto yy45;\n\tdefault:\tgoto yy25;\n\t}\nyy31:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'A':\tgoto yy40;\n\tcase 'a':\tgoto yy41;\n\tdefault:\tgoto yy25;\n\t}\nyy32:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'n':\tgoto yy39;\n\tdefault:\tgoto yy25;\n\t}\nyy33:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'N':\tgoto yy34;\n\tcase 'n':\tgoto yy35;\n\tdefault:\tgoto yy25;\n\t}\nyy34:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'F':\tgoto yy36;\n\tdefault:\tgoto yy25;\n\t}\nyy35:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'f':\tgoto yy36;\n\tdefault:\tgoto yy25;\n\t}\nyy36:\tyych = *++YYCURSOR;\n\tif(yych >= 0x01)\tgoto yy25;\n\tgoto yy37;\nyy37:\t++YYCURSOR;\n\tgoto yy38;\nyy38:\n#line 105 \"implicit.re\"\n{   return \"float#inf\"; }\n#line 326 \"<stdout>\"\nyy39:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'f':\tgoto yy36;\n\tdefault:\tgoto yy25;\n\t}\nyy40:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'N':\tgoto yy42;\n\tdefault:\tgoto yy25;\n\t}\nyy41:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'N':\tgoto yy42;\n\tdefault:\tgoto yy25;\n\t}\nyy42:\tyych = *++YYCURSOR;\n\tif(yych >= 0x01)\tgoto yy25;\n\tgoto yy43;\nyy43:\t++YYCURSOR;\n\tgoto yy44;\nyy44:\n#line 109 \"implicit.re\"\n{   return \"float#nan\"; }\n#line 350 \"<stdout>\"\nyy45:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'n':\tgoto yy42;\n\tdefault:\tgoto yy25;\n\t}\nyy46:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy74;\n\tdefault:\tgoto yy48;\n\t}\nyy47:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy48;\nyy48:\tswitch(yych){\n\tcase 0x00:\tgoto yy52;\n\tcase ',':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy47;\n\tcase '.':\tgoto yy50;\n\tcase ':':\tgoto yy49;\n\tdefault:\tgoto yy25;\n\t}\nyy49:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\tgoto yy66;\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy67;\n\tdefault:\tgoto yy25;\n\t}\nyy50:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tgoto yy51;\nyy51:\tswitch(yych){\n\tcase 0x00:\tgoto yy56;\n\tcase ',':\tgoto yy54;\n\tcase '.':\tgoto yy58;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy50;\n\tcase 'E':\tcase 'e':\tgoto yy60;\n\tdefault:\tgoto yy25;\n\t}\nyy52:\t++YYCURSOR;\n\tgoto yy53;\nyy53:\n#line 97 \"implicit.re\"\n{   return \"int\"; }\n#line 432 \"<stdout>\"\nyy54:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy55;\nyy55:\tswitch(yych){\n\tcase 0x00:\tgoto yy56;\n\tcase ',':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy54;\n\tdefault:\tgoto yy25;\n\t}\nyy56:\t++YYCURSOR;\n\tgoto yy57;\nyy57:\n#line 99 \"implicit.re\"\n{   return \"float#fix\"; }\n#line 456 \"<stdout>\"\nyy58:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tgoto yy59;\nyy59:\tswitch(yych){\n\tcase '.':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy58;\n\tcase 'E':\tcase 'e':\tgoto yy60;\n\tdefault:\tgoto yy25;\n\t}\nyy60:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '+':\tcase '-':\tgoto yy61;\n\tdefault:\tgoto yy25;\n\t}\nyy61:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy25;\n\tgoto yy63;\nyy62:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy63;\nyy63:\tswitch(yych){\n\tcase 0x00:\tgoto yy64;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy62;\n\tdefault:\tgoto yy25;\n\t}\nyy64:\t++YYCURSOR;\n\tgoto yy65;\nyy65:\n#line 101 \"implicit.re\"\n{   return \"float#exp\"; }\n#line 506 \"<stdout>\"\nyy66:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy70;\n\tcase '.':\tgoto yy68;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy67;\n\tcase ':':\tgoto yy49;\n\tdefault:\tgoto yy25;\n\t}\nyy67:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy70;\n\tcase '.':\tgoto yy68;\n\tcase ':':\tgoto yy49;\n\tdefault:\tgoto yy25;\n\t}\nyy68:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy69;\nyy69:\tswitch(yych){\n\tcase 0x00:\tgoto yy72;\n\tcase ',':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy68;\n\tdefault:\tgoto yy25;\n\t}\nyy70:\t++YYCURSOR;\n\tgoto yy71;\nyy71:\n#line 95 \"implicit.re\"\n{   return \"int#base60\"; }\n#line 558 \"<stdout>\"\nyy72:\t++YYCURSOR;\n\tgoto yy73;\nyy73:\n#line 103 \"implicit.re\"\n{   return \"float#base60\"; }\n#line 564 \"<stdout>\"\nyy74:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy75;\n\tdefault:\tgoto yy48;\n\t}\nyy75:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy76;\n\tdefault:\tgoto yy48;\n\t}\nyy76:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy77;\n\tdefault:\tgoto yy25;\n\t}\nyy77:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy78;\n\tdefault:\tgoto yy25;\n\t}\nyy78:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy79;\n\tdefault:\tgoto yy25;\n\t}\nyy79:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy80;\n\tdefault:\tgoto yy25;\n\t}\nyy80:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy81;\n\tdefault:\tgoto yy25;\n\t}\nyy81:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy82;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy25;\n\tcase 'T':\tgoto yy84;\n\tcase 't':\tgoto yy85;\n\tdefault:\tgoto yy87;\n\t}\nyy82:\t++YYCURSOR;\n\tgoto yy83;\nyy83:\n#line 111 \"implicit.re\"\n{   return \"timestamp#ymd\"; }\n#line 667 \"<stdout>\"\nyy84:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy126;\n\tdefault:\tgoto yy25;\n\t}\nyy85:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy108;\n\tdefault:\tgoto yy25;\n\t}\nyy86:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 9) YYFILL(9);\n\tyych = *YYCURSOR;\n\tgoto yy87;\nyy87:\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy86;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy88;\n\tdefault:\tgoto yy25;\n\t}\nyy88:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy89;\n\tdefault:\tgoto yy25;\n\t}\nyy89:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ':':\tgoto yy90;\n\tdefault:\tgoto yy25;\n\t}\nyy90:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy91;\n\tdefault:\tgoto yy25;\n\t}\nyy91:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy92;\n\tdefault:\tgoto yy25;\n\t}\nyy92:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ':':\tgoto yy93;\n\tdefault:\tgoto yy25;\n\t}\nyy93:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy94;\n\tdefault:\tgoto yy25;\n\t}\nyy94:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy95;\n\tdefault:\tgoto yy25;\n\t}\nyy95:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy98;\n\tcase '.':\tgoto yy96;\n\tdefault:\tgoto yy25;\n\t}\nyy96:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy97;\nyy97:\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy98;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy96;\n\tdefault:\tgoto yy25;\n\t}\nyy98:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 7) YYFILL(7);\n\tyych = *YYCURSOR;\n\tgoto yy99;\nyy99:\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy98;\n\tcase '+':\tcase '-':\tgoto yy101;\n\tcase 'Z':\tgoto yy100;\n\tdefault:\tgoto yy25;\n\t}\nyy100:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy105;\n\tgoto yy25;\nyy101:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy102;\n\tdefault:\tgoto yy25;\n\t}\nyy102:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy103;\n\tdefault:\tgoto yy25;\n\t}\nyy103:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy105;\n\tcase ':':\tgoto yy104;\n\tdefault:\tgoto yy25;\n\t}\nyy104:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy107;\n\tdefault:\tgoto yy25;\n\t}\nyy105:\t++YYCURSOR;\n\tgoto yy106;\nyy106:\n#line 115 \"implicit.re\"\n{   return \"timestamp#spaced\"; }\n#line 884 \"<stdout>\"\nyy107:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy100;\n\tdefault:\tgoto yy25;\n\t}\nyy108:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy109;\n\tdefault:\tgoto yy25;\n\t}\nyy109:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ':':\tgoto yy110;\n\tdefault:\tgoto yy25;\n\t}\nyy110:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy111;\n\tdefault:\tgoto yy25;\n\t}\nyy111:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy112;\n\tdefault:\tgoto yy25;\n\t}\nyy112:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ':':\tgoto yy113;\n\tdefault:\tgoto yy25;\n\t}\nyy113:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy114;\n\tdefault:\tgoto yy25;\n\t}\nyy114:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy115;\n\tdefault:\tgoto yy25;\n\t}\nyy115:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '.':\tgoto yy116;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy25;\n\tdefault:\tgoto yy117;\n\t}\nyy116:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 7) YYFILL(7);\n\tyych = *YYCURSOR;\n\tgoto yy117;\nyy117:\tswitch(yych){\n\tcase '+':\tcase '-':\tgoto yy119;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy116;\n\tcase 'Z':\tgoto yy118;\n\tdefault:\tgoto yy25;\n\t}\nyy118:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy123;\n\tgoto yy25;\nyy119:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy120;\n\tdefault:\tgoto yy25;\n\t}\nyy120:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy121;\n\tdefault:\tgoto yy25;\n\t}\nyy121:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy123;\n\tcase ':':\tgoto yy122;\n\tdefault:\tgoto yy25;\n\t}\nyy122:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy125;\n\tdefault:\tgoto yy25;\n\t}\nyy123:\t++YYCURSOR;\n\tgoto yy124;\nyy124:\n#line 113 \"implicit.re\"\n{   return \"timestamp#iso8601\"; }\n#line 1069 \"<stdout>\"\nyy125:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy118;\n\tdefault:\tgoto yy25;\n\t}\nyy126:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy127;\n\tdefault:\tgoto yy25;\n\t}\nyy127:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ':':\tgoto yy128;\n\tdefault:\tgoto yy25;\n\t}\nyy128:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy129;\n\tdefault:\tgoto yy25;\n\t}\nyy129:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy130;\n\tdefault:\tgoto yy25;\n\t}\nyy130:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ':':\tgoto yy131;\n\tdefault:\tgoto yy25;\n\t}\nyy131:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy132;\n\tdefault:\tgoto yy25;\n\t}\nyy132:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy133;\n\tdefault:\tgoto yy25;\n\t}\nyy133:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '.':\tgoto yy134;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy25;\n\tcase 'Z':\tgoto yy136;\n\tdefault:\tgoto yy135;\n\t}\nyy134:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 7) YYFILL(7);\n\tyych = *YYCURSOR;\n\tgoto yy135;\nyy135:\tswitch(yych){\n\tcase '+':\tcase '-':\tgoto yy119;\n\tcase '0':\tgoto yy134;\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy138;\n\tcase 'Z':\tgoto yy118;\n\tdefault:\tgoto yy25;\n\t}\nyy136:\tyych = *++YYCURSOR;\n\tif(yych >= 0x01)\tgoto yy25;\n\tgoto yy137;\nyy137:\tyych = *++YYCURSOR;\n\tgoto yy124;\nyy138:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 7) YYFILL(7);\n\tyych = *YYCURSOR;\n\tgoto yy139;\nyy139:\tswitch(yych){\n\tcase '+':\tcase '-':\tgoto yy119;\n\tcase '0':\tgoto yy134;\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy138;\n\tcase 'Z':\tgoto yy136;\n\tdefault:\tgoto yy25;\n\t}\nyy140:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\tgoto yy155;\n\tcase '8':\n\tcase '9':\tgoto yy153;\n\tdefault:\tgoto yy143;\n\t}\nyy141:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy153;\n\tdefault:\tgoto yy152;\n\t}\nyy142:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy143;\nyy143:\tswitch(yych){\n\tcase 0x00:\tgoto yy149;\n\tcase ',':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\tgoto yy142;\n\tcase '.':\tgoto yy50;\n\tcase '8':\n\tcase '9':\tgoto yy151;\n\tcase ':':\tgoto yy49;\n\tdefault:\tgoto yy25;\n\t}\nyy144:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy25;\n\tgoto yy146;\nyy145:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy146;\nyy146:\tswitch(yych){\n\tcase 0x00:\tgoto yy147;\n\tcase ',':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\tgoto yy145;\n\tdefault:\tgoto yy25;\n\t}\nyy147:\t++YYCURSOR;\n\tgoto yy148;\nyy148:\n#line 91 \"implicit.re\"\n{   return \"int#hex\"; }\n#line 1307 \"<stdout>\"\nyy149:\t++YYCURSOR;\n\tgoto yy150;\nyy150:\n#line 93 \"implicit.re\"\n{   return \"int#oct\"; }\n#line 1313 \"<stdout>\"\nyy151:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy152;\nyy152:\tswitch(yych){\n\tcase ',':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy151;\n\tcase '.':\tgoto yy50;\n\tcase ':':\tgoto yy49;\n\tdefault:\tgoto yy25;\n\t}\nyy153:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy154;\n\tdefault:\tgoto yy152;\n\t}\nyy154:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy76;\n\tdefault:\tgoto yy152;\n\t}\nyy155:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\tgoto yy156;\n\tcase '8':\n\tcase '9':\tgoto yy154;\n\tdefault:\tgoto yy143;\n\t}\nyy156:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy76;\n\tdefault:\tgoto yy143;\n\t}\nyy157:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'I':\tgoto yy160;\n\tcase 'i':\tgoto yy159;\n\tdefault:\tgoto yy25;\n\t}\nyy158:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy52;\n\tcase 'x':\tgoto yy144;\n\tdefault:\tgoto yy143;\n\t}\nyy159:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'n':\tgoto yy166;\n\tdefault:\tgoto yy25;\n\t}\nyy160:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'N':\tgoto yy161;\n\tcase 'n':\tgoto yy162;\n\tdefault:\tgoto yy25;\n\t}\nyy161:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'F':\tgoto yy163;\n\tdefault:\tgoto yy25;\n\t}\nyy162:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'f':\tgoto yy163;\n\tdefault:\tgoto yy25;\n\t}\nyy163:\tyych = *++YYCURSOR;\n\tif(yych >= 0x01)\tgoto yy25;\n\tgoto yy164;\nyy164:\t++YYCURSOR;\n\tgoto yy165;\nyy165:\n#line 107 \"implicit.re\"\n{   return \"float#neginf\"; }\n#line 1412 \"<stdout>\"\nyy166:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'f':\tgoto yy163;\n\tdefault:\tgoto yy25;\n\t}\nyy167:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'I':\tgoto yy33;\n\tcase 'i':\tgoto yy32;\n\tdefault:\tgoto yy25;\n\t}\nyy168:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'L':\tgoto yy175;\n\tdefault:\tgoto yy25;\n\t}\nyy169:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'l':\tgoto yy170;\n\tdefault:\tgoto yy25;\n\t}\nyy170:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 's':\tgoto yy171;\n\tdefault:\tgoto yy25;\n\t}\nyy171:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'e':\tgoto yy172;\n\tdefault:\tgoto yy25;\n\t}\nyy172:\tyych = *++YYCURSOR;\n\tif(yych >= 0x01)\tgoto yy25;\n\tgoto yy173;\nyy173:\t++YYCURSOR;\n\tgoto yy174;\nyy174:\n#line 89 \"implicit.re\"\n{   return \"bool#no\"; }\n#line 1452 \"<stdout>\"\nyy175:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'S':\tgoto yy176;\n\tdefault:\tgoto yy25;\n\t}\nyy176:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'E':\tgoto yy172;\n\tdefault:\tgoto yy25;\n\t}\nyy177:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'l':\tgoto yy178;\n\tdefault:\tgoto yy25;\n\t}\nyy178:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 's':\tgoto yy179;\n\tdefault:\tgoto yy25;\n\t}\nyy179:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'e':\tgoto yy172;\n\tdefault:\tgoto yy25;\n\t}\nyy180:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'F':\tgoto yy172;\n\tdefault:\tgoto yy25;\n\t}\nyy181:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'f':\tgoto yy172;\n\tdefault:\tgoto yy25;\n\t}\nyy182:\tyych = *++YYCURSOR;\n\tif(yych >= 0x01)\tgoto yy25;\n\tgoto yy183;\nyy183:\t++YYCURSOR;\n\tgoto yy184;\nyy184:\n#line 87 \"implicit.re\"\n{   return \"bool#yes\"; }\n#line 1496 \"<stdout>\"\nyy185:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'f':\tgoto yy172;\n\tdefault:\tgoto yy25;\n\t}\nyy186:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'U':\tgoto yy189;\n\tdefault:\tgoto yy25;\n\t}\nyy187:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'u':\tgoto yy188;\n\tdefault:\tgoto yy25;\n\t}\nyy188:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'e':\tgoto yy182;\n\tdefault:\tgoto yy25;\n\t}\nyy189:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'E':\tgoto yy182;\n\tdefault:\tgoto yy25;\n\t}\nyy190:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'u':\tgoto yy191;\n\tdefault:\tgoto yy25;\n\t}\nyy191:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'e':\tgoto yy182;\n\tdefault:\tgoto yy25;\n\t}\nyy192:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'S':\tgoto yy182;\n\tdefault:\tgoto yy25;\n\t}\nyy193:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 's':\tgoto yy182;\n\tdefault:\tgoto yy25;\n\t}\nyy194:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 's':\tgoto yy182;\n\tdefault:\tgoto yy25;\n\t}\nyy195:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'L':\tgoto yy199;\n\tdefault:\tgoto yy25;\n\t}\nyy196:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'l':\tgoto yy197;\n\tdefault:\tgoto yy25;\n\t}\nyy197:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'l':\tgoto yy198;\n\tdefault:\tgoto yy25;\n\t}\nyy198:\tyych = *++YYCURSOR;\n\tif(yych <= 0x00)\tgoto yy6;\n\tgoto yy25;\nyy199:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'L':\tgoto yy198;\n\tdefault:\tgoto yy25;\n\t}\nyy200:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'l':\tgoto yy201;\n\tdefault:\tgoto yy25;\n\t}\nyy201:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 'l':\tgoto yy198;\n\tdefault:\tgoto yy25;\n\t}\n}\n#line 125 \"implicit.re\"\n\n\n}\n\n/* Remove ending fragment and compare types */\nint\nsyck_tagcmp( char *tag1, char *tag2 )\n{\n    if ( tag1 == tag2 ) return 1;\n    if ( tag1 == NULL || tag2 == NULL ) return 0;\n    else {\n        int i;\n        char *othorpe;\n        char *tmp1 = syck_strndup( tag1, strlen( tag1 ) );\n        char *tmp2 = syck_strndup( tag2, strlen( tag2 ) );\n        othorpe = strstr( tmp1, \"#\" );\n\t\tif ( othorpe != NULL ) {\n            othorpe[0] = '\\0';\n        }\n        othorpe = strstr( tmp2, \"#\" );\n\t\tif ( othorpe != NULL ) {\n            othorpe[0] = '\\0';\n        }\n        i = strcmp( tmp1, tmp2 );\n        S_FREE( tmp1 ); S_FREE( tmp2 );\n        return i;\n    }\n}\n\nchar *\nsyck_type_id_to_uri( char *type_id )\n{\n    char *cursor, *limit, *marker;\n\n    cursor = type_id;\n    limit = type_id + strlen( type_id );\n\n\n#line 1620 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy202;\n\t++YYCURSOR;\nyy202:\n\tif((YYLIMIT - YYCURSOR) < 11) YYFILL(11);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy204;\n\tcase '!':\tgoto yy208;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\tcase 'u':\n\tcase 'v':\n\tcase 'w':\tcase 'y':\n\tcase 'z':\tgoto yy210;\n\tcase 't':\tgoto yy205;\n\tcase 'x':\tgoto yy207;\n\tdefault:\tgoto yy211;\n\t}\nyy204:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy206;\n\t}\nyy205:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '-':\tgoto yy212;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy214;\n\tcase 'a':\tgoto yy246;\n\tdefault:\tgoto yy206;\n\t}\nyy206:\n#line 202 \"implicit.re\"\n{   return syck_taguri( YAML_DOMAIN, type_id, strlen( type_id ) ); }\n#line 1768 \"<stdout>\"\nyy207:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase ',':\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy215;\n\tcase '-':\tgoto yy236;\n\tdefault:\tgoto yy206;\n\t}\nyy208:\t++YYCURSOR;\n\tgoto yy209;\nyy209:\n#line 176 \"implicit.re\"\n{   return syck_xprivate( type_id + 1, strlen( type_id ) - 1 ); }\n#line 1842 \"<stdout>\"\nyy210:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '-':\tgoto yy212;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy214;\n\tdefault:\tgoto yy206;\n\t}\nyy211:\tyych = *++YYCURSOR;\n\tgoto yy206;\nyy212:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy213;\nyy213:\tswitch(yych){\n\tcase '-':\tgoto yy212;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy214;\n\tdefault:\tgoto yy204;\n\t}\nyy214:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy215;\nyy215:\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '-':\tgoto yy212;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy214;\n\tdefault:\tgoto yy204;\n\t}\nyy216:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy224;\n\tdefault:\tgoto yy204;\n\t}\nyy217:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy220;\n\tdefault:\tgoto yy204;\n\t}\nyy218:\t++YYCURSOR;\n\tgoto yy219;\nyy219:\n#line 178 \"implicit.re\"\n{   char *domain = S_ALLOC_N( char, ( YYCURSOR - type_id ) + 15 );\n                    char *uri;\n\n                    domain[0] = '\\0';\n                    strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 );\n                    strcat( domain, \".\" );\n                    strcat( domain, YAML_DOMAIN );\n                    uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR );\n\n                    S_FREE( domain );\n                    return uri;\n                }\n#line 2149 \"<stdout>\"\nyy220:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 12) YYFILL(12);\n\tyych = *YYCURSOR;\n\tgoto yy221;\nyy221:\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '-':\tgoto yy222;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy220;\n\tdefault:\tgoto yy204;\n\t}\nyy222:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy223;\nyy223:\tswitch(yych){\n\tcase '-':\tgoto yy222;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy220;\n\tdefault:\tgoto yy204;\n\t}\nyy224:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy225;\n\tdefault:\tgoto yy204;\n\t}\nyy225:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy226;\n\tdefault:\tgoto yy204;\n\t}\nyy226:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy227;\n\tdefault:\tgoto yy204;\n\t}\nyy227:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy228;\n\tcase '/':\tgoto yy229;\n\tdefault:\tgoto yy204;\n\t}\nyy228:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy231;\n\tdefault:\tgoto yy204;\n\t}\nyy229:\t++YYCURSOR;\n\tgoto yy230;\nyy230:\n#line 191 \"implicit.re\"\n{   char *domain = S_ALLOC_N( char, YYCURSOR - type_id );\n                               char *uri;\n\n                               domain[0] = '\\0';\n                               strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 );\n                               uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR );\n\n                               S_FREE( domain );\n                               return uri;\n                            }\n#line 2365 \"<stdout>\"\nyy231:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy232;\n\tdefault:\tgoto yy204;\n\t}\nyy232:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy233;\n\tcase '/':\tgoto yy229;\n\tdefault:\tgoto yy204;\n\t}\nyy233:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy234;\n\tdefault:\tgoto yy204;\n\t}\nyy234:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy235;\n\tdefault:\tgoto yy204;\n\t}\nyy235:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '/':\tgoto yy229;\n\tdefault:\tgoto yy204;\n\t}\nyy236:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 'p':\tgoto yy237;\n\tdefault:\tgoto yy213;\n\t}\nyy237:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 'r':\tgoto yy238;\n\tdefault:\tgoto yy213;\n\t}\nyy238:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 'i':\tgoto yy239;\n\tdefault:\tgoto yy213;\n\t}\nyy239:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 'v':\tgoto yy240;\n\tdefault:\tgoto yy213;\n\t}\nyy240:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 'a':\tgoto yy241;\n\tdefault:\tgoto yy213;\n\t}\nyy241:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 't':\tgoto yy242;\n\tdefault:\tgoto yy213;\n\t}\nyy242:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 'e':\tgoto yy243;\n\tdefault:\tgoto yy213;\n\t}\nyy243:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase ':':\tgoto yy244;\n\tdefault:\tgoto yy213;\n\t}\nyy244:\t++YYCURSOR;\n\tgoto yy245;\nyy245:\n#line 174 \"implicit.re\"\n{   return syck_strndup( type_id, strlen( type_id ) ); }\n#line 2485 \"<stdout>\"\nyy246:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase 'g':\tgoto yy247;\n\tdefault:\tgoto yy213;\n\t}\nyy247:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\tgoto yy216;\n\tcase '.':\tgoto yy217;\n\tcase '/':\tgoto yy218;\n\tcase ':':\tgoto yy248;\n\tdefault:\tgoto yy213;\n\t}\nyy248:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase ',':\n\tcase '-':\n\tcase '.':\tgoto yy204;\n\tdefault:\tgoto yy250;\n\t}\nyy249:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy250;\nyy250:\tswitch(yych){\n\tcase ',':\tgoto yy253;\n\tcase '-':\tgoto yy251;\n\tcase '.':\tgoto yy254;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy249;\n\tdefault:\tgoto yy204;\n\t}\nyy251:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy252;\nyy252:\tswitch(yych){\n\tcase '-':\tgoto yy251;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy249;\n\tdefault:\tgoto yy204;\n\t}\nyy253:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy259;\n\tdefault:\tgoto yy204;\n\t}\nyy254:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy255;\n\tdefault:\tgoto yy204;\n\t}\nyy255:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 12) YYFILL(12);\n\tyych = *YYCURSOR;\n\tgoto yy256;\nyy256:\tswitch(yych){\n\tcase ',':\tgoto yy253;\n\tcase '-':\tgoto yy257;\n\tcase '.':\tgoto yy254;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy255;\n\tdefault:\tgoto yy204;\n\t}\nyy257:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy258;\nyy258:\tswitch(yych){\n\tcase '-':\tgoto yy257;\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy255;\n\tdefault:\tgoto yy204;\n\t}\nyy259:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy260;\n\tdefault:\tgoto yy204;\n\t}\nyy260:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy261;\n\tdefault:\tgoto yy204;\n\t}\nyy261:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy262;\n\tdefault:\tgoto yy204;\n\t}\nyy262:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy263;\n\tcase ':':\tgoto yy264;\n\tdefault:\tgoto yy204;\n\t}\nyy263:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy266;\n\tdefault:\tgoto yy204;\n\t}\nyy264:\t++YYCURSOR;\n\tgoto yy265;\nyy265:\n#line 172 \"implicit.re\"\n{   return syck_strndup( type_id, strlen( type_id ) ); }\n#line 2932 \"<stdout>\"\nyy266:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy267;\n\tdefault:\tgoto yy204;\n\t}\nyy267:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy268;\n\tcase ':':\tgoto yy264;\n\tdefault:\tgoto yy204;\n\t}\nyy268:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy269;\n\tdefault:\tgoto yy204;\n\t}\nyy269:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy270;\n\tdefault:\tgoto yy204;\n\t}\nyy270:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase ':':\tgoto yy264;\n\tdefault:\tgoto yy204;\n\t}\n}\n#line 204 \"implicit.re\"\n\n\n}\n"
  },
  {
    "path": "ext/syck/node.c",
    "content": "/*\n * node.c\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n\n#include \"ruby.h\"\n#include \"syck.h\"\n\n/*\n * Node allocation functions\n */\nSyckNode *\nsyck_alloc_node( enum syck_kind_tag type )\n{\n    SyckNode *s;\n\n    s = S_ALLOC( SyckNode );\n    s->kind = type;\n    s->id = 0;\n    s->type_id = NULL;\n    s->anchor = NULL;\n    s->shortcut = NULL;\n\n    return s;\n}\n\nvoid\nsyck_free_node( SyckNode *n )\n{\n    syck_free_members( n );\n    if ( n->type_id != NULL )\n    {\n        S_FREE( n->type_id );\n        n->type_id = NULL;\n    }\n    if ( n->anchor != NULL )\n    {\n        S_FREE( n->anchor );\n        n->anchor = NULL;\n    }\n    S_FREE( n );\n}\n\nSyckNode *\nsyck_alloc_map()\n{\n    SyckNode *n;\n    struct SyckMap *m;\n\n    m = S_ALLOC( struct SyckMap );\n    m->style = map_none;\n    m->idx = 0;\n    m->capa = ALLOC_CT;\n    m->keys = S_ALLOC_N( SYMID, m->capa );\n    m->values = S_ALLOC_N( SYMID, m->capa );\n\n    n = syck_alloc_node( syck_map_kind );\n    n->data.pairs = m;\n    \n    return n;\n}\n\nSyckNode *\nsyck_alloc_seq()\n{\n    SyckNode *n;\n    struct SyckSeq *s;\n\n    s = S_ALLOC( struct SyckSeq );\n    s->style = seq_none;\n    s->idx = 0;\n    s->capa = ALLOC_CT;\n    s->items = S_ALLOC_N( SYMID, s->capa );\n\n    n = syck_alloc_node( syck_seq_kind );\n    n->data.list = s;\n\n    return n;\n}\n\nSyckNode *\nsyck_alloc_str()\n{\n    SyckNode *n;\n    struct SyckStr *s;\n\n    s = S_ALLOC( struct SyckStr );\n    s->len = 0;\n    s->ptr = NULL;\n    s->style = scalar_none;\n\n    n = syck_alloc_node( syck_str_kind );\n    n->data.str = s;\n    \n    return n;\n}\n\nSyckNode *\nsyck_new_str( char *str, enum scalar_style style )\n{\n    return syck_new_str2( str, strlen( str ), style );\n}\n\nSyckNode *\nsyck_new_str2( char *str, long len, enum scalar_style style )\n{\n    SyckNode *n;\n\n    n = syck_alloc_str();\n    n->data.str->ptr = S_ALLOC_N( char, len + 1 );\n    n->data.str->len = len;\n    n->data.str->style = style;\n    memcpy( n->data.str->ptr, str, len );\n    n->data.str->ptr[len] = '\\0';\n\n    return n;\n}\n\nvoid\nsyck_replace_str( SyckNode *n, char *str, enum scalar_style style )\n{\n    syck_replace_str2( n, str, strlen( str ), style );\n}\n\nvoid\nsyck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )\n{\n    if ( n->data.str != NULL ) \n    {\n        S_FREE( n->data.str->ptr );\n        n->data.str->ptr = NULL;\n        n->data.str->len = 0;\n    }\n    n->data.str->ptr = S_ALLOC_N( char, len + 1 );\n    n->data.str->len = len;\n    n->data.str->style = style;\n    memcpy( n->data.str->ptr, str, len );\n    n->data.str->ptr[len] = '\\0';\n}\n\nvoid\nsyck_str_blow_away_commas( SyckNode *n )\n{\n    char *go, *end;\n\n    go = n->data.str->ptr;\n    end = go + n->data.str->len;\n    while ( *(++go) != '\\0' )\n    {\n        if ( *go == ',' )\n        {\n            n->data.str->len -= 1;\n            memmove( go, go + 1, end - go );\n            end -= 1;\n        }\n    }\n}\n\nchar *\nsyck_str_read( SyckNode *n )\n{\n    ASSERT( n != NULL );\n    return n->data.str->ptr;\n}\n\nSyckNode *\nsyck_new_map( SYMID key, SYMID value )\n{\n    SyckNode *n;\n\n    n = syck_alloc_map();\n    syck_map_add( n, key, value );\n\n    return n;\n}\n\nvoid\nsyck_map_empty( SyckNode *n )\n{\n    struct SyckMap *m;\n    ASSERT( n != NULL );\n    ASSERT( n->data.list != NULL );\n\n    S_FREE( n->data.pairs->keys );\n    S_FREE( n->data.pairs->values );\n    m = n->data.pairs;\n    m->idx = 0;\n    m->capa = ALLOC_CT;\n    m->keys = S_ALLOC_N( SYMID, m->capa );\n    m->values = S_ALLOC_N( SYMID, m->capa );\n}\n\nvoid\nsyck_map_add( SyckNode *map, SYMID key, SYMID value )\n{\n    struct SyckMap *m;\n    long idx;\n\n    ASSERT( map != NULL );\n    ASSERT( map->data.pairs != NULL );\n    \n    m = map->data.pairs;\n    idx = m->idx;\n    m->idx += 1;\n    if ( m->idx > m->capa )\n    {\n        m->capa += ALLOC_CT;\n        S_REALLOC_N( m->keys, SYMID, m->capa );\n        S_REALLOC_N( m->values, SYMID, m->capa );\n    }\n    m->keys[idx] = key;\n    m->values[idx] = value;\n}\n\nvoid\nsyck_map_update( SyckNode *map1, SyckNode *map2 )\n{\n    struct SyckMap *m1, *m2;\n    long new_idx, new_capa;\n    ASSERT( map1 != NULL );\n    ASSERT( map2 != NULL );\n\n    m1 = map1->data.pairs;\n    m2 = map2->data.pairs;\n    if ( m2->idx < 1 ) return;\n        \n    new_idx = m1->idx;\n    new_idx += m2->idx;\n    new_capa = m1->capa;\n    while ( new_idx > new_capa )\n    {\n        new_capa += ALLOC_CT;\n    }\n    if ( new_capa > m1->capa )\n    {\n        m1->capa = new_capa;\n        S_REALLOC_N( m1->keys, SYMID, m1->capa );\n        S_REALLOC_N( m1->values, SYMID, m1->capa );\n    }\n    for ( new_idx = 0; new_idx < m2->idx; m1->idx++, new_idx++ )\n    {\n        m1->keys[m1->idx] = m2->keys[new_idx]; \n        m1->values[m1->idx] = m2->values[new_idx]; \n    }\n}\n\nlong\nsyck_map_count( SyckNode *map )\n{\n    ASSERT( map != NULL );\n    ASSERT( map->data.pairs != NULL );\n    return map->data.pairs->idx;\n}\n\nvoid\nsyck_map_assign( SyckNode *map, enum map_part p, long idx, SYMID id )\n{\n    struct SyckMap *m;\n\n    ASSERT( map != NULL );\n    m = map->data.pairs;\n    ASSERT( m != NULL );\n    if ( p == map_key )\n    {\n        m->keys[idx] = id;\n    }\n    else\n    {\n        m->values[idx] = id;\n    }\n}\n\nSYMID\nsyck_map_read( SyckNode *map, enum map_part p, long idx )\n{\n    struct SyckMap *m;\n\n    ASSERT( map != NULL );\n    m = map->data.pairs;\n    ASSERT( m != NULL );\n    if ( p == map_key )\n    {\n        return m->keys[idx];\n    }\n    else\n    {\n        return m->values[idx];\n    }\n}\n\nSyckNode *\nsyck_new_seq( SYMID value )\n{\n    SyckNode *n;\n\n    n = syck_alloc_seq();\n    syck_seq_add( n, value );\n\n    return n;\n}\n\nvoid\nsyck_seq_empty( SyckNode *n )\n{\n    struct SyckSeq *s;\n    ASSERT( n != NULL );\n    ASSERT( n->data.list != NULL );\n\n    S_FREE( n->data.list->items );\n    s = n->data.list;\n    s->idx = 0;\n    s->capa = ALLOC_CT;\n    s->items = S_ALLOC_N( SYMID, s->capa );\n}\n\nvoid\nsyck_seq_add( SyckNode *arr, SYMID value )\n{\n    struct SyckSeq *s;\n    long idx;\n\n    ASSERT( arr != NULL );\n    ASSERT( arr->data.list != NULL );\n    \n    s = arr->data.list;\n    idx = s->idx;\n    s->idx += 1;\n    if ( s->idx > s->capa )\n    {\n        s->capa += ALLOC_CT;\n        S_REALLOC_N( s->items, SYMID, s->capa );\n    }\n    s->items[idx] = value;\n}\n\nlong\nsyck_seq_count( SyckNode *seq )\n{\n    ASSERT( seq != NULL );\n    ASSERT( seq->data.list != NULL );\n    return seq->data.list->idx;\n}\n\nvoid\nsyck_seq_assign( SyckNode *seq, long idx, SYMID id )\n{\n    struct SyckSeq *s;\n\n    ASSERT( map != NULL );\n    s = seq->data.list;\n    ASSERT( m != NULL );\n    s->items[idx] = id;\n}\n\nSYMID\nsyck_seq_read( SyckNode *seq, long idx )\n{\n    struct SyckSeq *s;\n\n    ASSERT( seq != NULL );\n    s = seq->data.list;\n    ASSERT( s != NULL );\n    return s->items[idx];\n}\n\nvoid\nsyck_free_members( SyckNode *n )\n{\n    if ( n == NULL ) return;\n\n    switch ( n->kind  )\n    {\n        case syck_str_kind:\n            if ( n->data.str != NULL ) \n            {\n                S_FREE( n->data.str->ptr );\n                n->data.str->ptr = NULL;\n                n->data.str->len = 0;\n                S_FREE( n->data.str );\n                n->data.str = NULL;\n            }\n        break;\n\n        case syck_seq_kind:\n            if ( n->data.list != NULL )\n            {\n                S_FREE( n->data.list->items );\n                S_FREE( n->data.list );\n                n->data.list = NULL;\n            }\n        break;\n\n        case syck_map_kind:\n            if ( n->data.pairs != NULL )\n            {\n                S_FREE( n->data.pairs->keys );\n                S_FREE( n->data.pairs->values );\n                S_FREE( n->data.pairs );\n                n->data.pairs = NULL;\n            }\n        break;\n    }\n}\n\n"
  },
  {
    "path": "ext/syck/rubyext.c",
    "content": "/* -*- indent-tabs-mode: nil -*- */\n/*\n * rubyext.c\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003-2005 why the lucky stiff\n */\n\n#include \"ruby.h\"\n#include \"syck.h\"\n#include <sys/types.h>\n#include <time.h>\n\ntypedef struct RVALUE {\n    union {\n#if 0\n    struct {\n        unsigned long flags;    /* always 0 for freed obj */\n        struct RVALUE *next;\n    } free;\n#endif\n    struct RBasic  basic;\n    struct RObject object;\n    struct RClass  klass;\n    /*struct RFloat  flonum;*/\n    /*struct RString string;*/\n    struct RArray  array;\n    /*struct RRegexp regexp;*/\n    struct RHash   hash;\n    /*struct RData   data;*/\n    struct RStruct rstruct;\n    /*struct RBignum bignum;*/\n    /*struct RFile   file;*/\n    } as;\n} RVALUE;\n\ntypedef struct {\n   long hash;\n   char *buffer;\n   long length;\n   long remaining;\n   int  printed;\n} bytestring_t;\n\n#define RUBY_DOMAIN   \"ruby.yaml.org,2002\"\n\n/*\n * symbols and constants\n */\nstatic ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver;\nstatic ID s_tags, s_domain, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set;\nstatic VALUE sym_model, sym_generic, sym_input, sym_bytecode;\nstatic VALUE sym_scalar, sym_seq, sym_map;\nstatic VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;\nstatic VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter;\nstatic VALUE oDefaultResolver, oGenericResolver;\n\n/*\n * my private collection of numerical oddities.\n */\nstatic double S_zero()    { return 0.0; }\nstatic double S_one() { return 1.0; }\nstatic double S_inf() { return S_one() / S_zero(); }\nstatic double S_nan() { return S_zero() / S_zero(); }\n\nstatic VALUE syck_node_transform( VALUE );\n\n/*\n * handler prototypes\n */\nSYMID rb_syck_load_handler _((SyckParser *, SyckNode *));\nvoid rb_syck_err_handler _((SyckParser *, char *));\nSyckNode * rb_syck_bad_anchor_handler _((SyckParser *, char *));\nvoid rb_syck_output_handler _((SyckEmitter *, char *, long));\nvoid rb_syck_emitter_handler _((SyckEmitter *, st_data_t));\nint syck_parser_assign_io _((SyckParser *, VALUE *));\nVALUE syck_scalar_alloc _((VALUE class));\nVALUE syck_seq_alloc _((VALUE class));\nVALUE syck_map_alloc _((VALUE class));\n\nstruct parser_xtra {\n    VALUE data;  /* Borrowed this idea from marshal.c to fix [ruby-core:8067] problem */\n    VALUE proc;\n    VALUE resolver;\n    int taint;\n};\n\nstruct emitter_xtra {\n    VALUE oid;\n    VALUE data;\n    VALUE port;\n};\n\n/*\n * Convert YAML to bytecode\n */\nVALUE\nrb_syck_compile(self, port)\n    VALUE self, port;\n{\n    SYMID oid;\n    int taint;\n    char *ret;\n    VALUE bc;\n    bytestring_t *sav; \n\n    SyckParser *parser = syck_new_parser();\n    taint = syck_parser_assign_io(parser, &port);\n    syck_parser_handler( parser, syck_yaml2byte_handler );\n    syck_parser_error_handler( parser, NULL );\n    syck_parser_implicit_typing( parser, 0 );\n    syck_parser_taguri_expansion( parser, 0 );\n    oid = syck_parse( parser );\n    syck_lookup_sym( parser, oid, (char **)&sav );\n\n    ret = S_ALLOCA_N( char, strlen( sav->buffer ) + 3 );\n    ret[0] = '\\0';\n    strcat( ret, \"D\\n\" );\n    strcat( ret, sav->buffer );\n\n    syck_free_parser( parser );\n\n    bc = rb_str_new2( ret );\n    if ( taint )      OBJ_TAINT( bc );\n    return bc;\n}\n\n/*\n * read from io.\n */\nlong\nrb_syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )\n{\n    long len = 0;\n\n    ASSERT( str != NULL );\n    max_size -= skip;\n\n    if ( max_size <= 0 ) max_size = 0;\n    else\n    {\n        /*\n         * call io#read.\n         */\n        VALUE src = (VALUE)str->ptr;\n        VALUE n = LONG2NUM(max_size);\n        VALUE str2 = rb_funcall2(src, s_read, 1, &n);\n        if (!NIL_P(str2))\n        {\n            StringValue(str2);\n            len = RSTRING(str2)->len;\n            memcpy( buf + skip, RSTRING(str2)->ptr, len );\n        }\n    }\n    len += skip;\n    buf[len] = '\\0';\n    return len;\n}\n\n/*\n * determine: are we reading from a string or io?\n * (returns tainted? boolean)\n */\nint\nsyck_parser_assign_io(parser, pport)\n    SyckParser *parser;\n    VALUE *pport;\n{\n    int taint = Qtrue;\n    VALUE tmp, port = *pport;\n    if (!NIL_P(tmp = rb_check_string_type(port))) {\n        taint = OBJ_TAINTED(port); /* original taintedness */\n        port = tmp;\n        syck_parser_str( parser, RSTRING(port)->ptr, RSTRING(port)->len, NULL );\n    }\n    else if (rb_respond_to(port, s_read)) {\n        if (rb_respond_to(port, s_binmode)) {\n            rb_funcall2(port, s_binmode, 0, 0);\n        }\n        syck_parser_str( parser, (char *)port, 0, rb_syck_io_str_read );\n    }\n    else {\n        rb_raise(rb_eTypeError, \"instance of IO needed\");\n    }\n    *pport = port;\n    return taint;\n}\n\n/*\n * Get value in hash by key, forcing an empty hash if nil.\n */\nVALUE\nsyck_get_hash_aref(hsh, key)\n    VALUE hsh, key;\n{\n   VALUE val = rb_hash_aref( hsh, key );\n   if ( NIL_P( val ) ) \n   {\n       val = rb_hash_new();\n       rb_hash_aset(hsh, key, val);\n   }\n   return val;\n}\n\n/*\n * creating timestamps\n */\nSYMID\nrb_syck_mktime(str, len)\n    char *str;\n    long len;\n{\n    VALUE time;\n    char *ptr = str;\n    VALUE year = INT2FIX(0);\n    VALUE mon = INT2FIX(0);\n    VALUE day = INT2FIX(0);\n    VALUE hour = INT2FIX(0);\n    VALUE min = INT2FIX(0);\n    VALUE sec = INT2FIX(0);\n    long usec;\n\n    /* Year*/\n    if ( ptr[0] != '\\0' && len > 0 ) {\n        year = INT2FIX(strtol(ptr, NULL, 10));\n    }\n\n    /* Month*/\n    ptr += 4;\n    if ( ptr[0] != '\\0' && len > ptr - str ) {\n        while ( !ISDIGIT( *ptr ) ) ptr++;\n        mon = INT2FIX(strtol(ptr, NULL, 10));\n    }\n\n    /* Day*/\n    ptr += 2;\n    if ( ptr[0] != '\\0' && len > ptr - str ) {\n        while ( !ISDIGIT( *ptr ) ) ptr++;\n        day = INT2FIX(strtol(ptr, NULL, 10));\n    }\n\n    /* Hour*/\n    ptr += 2;\n    if ( ptr[0] != '\\0' && len > ptr - str ) {\n        while ( !ISDIGIT( *ptr ) ) ptr++;\n        hour = INT2FIX(strtol(ptr, NULL, 10));\n    }\n\n    /* Minute */\n    ptr += 2;\n    if ( ptr[0] != '\\0' && len > ptr - str ) {\n        while ( !ISDIGIT( *ptr ) ) ptr++;\n        min = INT2FIX(strtol(ptr, NULL, 10));\n    }\n\n    /* Second */\n    ptr += 2;\n    if ( ptr[0] != '\\0' && len > ptr - str ) {\n        while ( !ISDIGIT( *ptr ) ) ptr++;\n        sec = INT2FIX(strtol(ptr, NULL, 10));\n    }\n\n    /* Millisecond */\n    ptr += 2;\n    if ( len > ptr - str && *ptr == '.' )\n    {\n        char padded[] = \"000000\";\n        char *end = ptr + 1;\n        char *p = end;\n        while ( isdigit( *end ) ) end++;\n        if (end - p < sizeof(padded)) {\n            MEMCPY(padded, ptr + 1, char, end - (ptr + 1));\n            p = padded;\n        }\n        usec = strtol(p, NULL, 10);\n    }\n    else\n    {\n        usec = 0;\n    }\n\n    /* Time Zone*/\n    while ( len > ptr - str && *ptr != 'Z' && *ptr != '+' && *ptr != '-' && *ptr != '\\0' ) ptr++;\n    if ( len > ptr - str && ( *ptr == '-' || *ptr == '+' ) )\n    {\n        time_t tz_offset = strtol(ptr, NULL, 10) * 3600;\n        time_t tmp;\n\n        while ( *ptr != ':' && *ptr != '\\0' ) ptr++;\n        if ( *ptr == ':' )\n        {\n            ptr += 1;\n            if ( tz_offset < 0 )\n            {\n                tz_offset -= strtol(ptr, NULL, 10) * 60;\n            }\n            else\n            {\n                tz_offset += strtol(ptr, NULL, 10) * 60;\n            }\n        }\n\n        /* Make TZ time*/\n        time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec);\n        tmp = NUM2LONG(rb_funcall(time, s_to_i, 0)) - tz_offset;\n        return rb_funcall(rb_cTime, s_at, 2, LONG2NUM(tmp), LONG2NUM(usec));\n    }\n    else\n    {\n        /* Make UTC time*/\n        return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, LONG2NUM(usec));\n    }\n}\n\n/*\n * handles merging of an array of hashes\n * (see http://www.yaml.org/type/merge/)\n */\nVALUE\nsyck_merge_i( entry, hsh )\n    VALUE entry, hsh;\n{\n    VALUE tmp;\n    if ( !NIL_P(tmp = rb_check_convert_type(entry, T_HASH, \"Hash\", \"to_hash\")) )\n    {\n        entry = tmp;\n        rb_funcall( hsh, s_update, 1, entry );\n    }\n    return Qnil;\n}\n\n/*\n * default handler for ruby.yaml.org types\n */\nint\nyaml_org_handler( n, ref )\n    SyckNode *n;\n    VALUE *ref;\n{\n    char *type_id = n->type_id;\n    int transferred = 0;\n    long i = 0;\n    VALUE obj = Qnil;\n\n    if ( type_id != NULL && strncmp( type_id, \"tag:yaml.org,2002:\", 18 ) == 0 )\n    {\n        type_id += 18;\n    }\n\n    switch (n->kind)\n    {\n        case syck_str_kind:\n            transferred = 1;\n            if ( type_id == NULL )\n            {\n                obj = rb_str_new( n->data.str->ptr, n->data.str->len );\n            }\n            else if ( strcmp( type_id, \"null\" ) == 0 )\n            {\n                obj = Qnil;\n            }\n            else if ( strcmp( type_id, \"binary\" ) == 0 )\n            {\n                VALUE arr;\n                obj = rb_str_new( n->data.str->ptr, n->data.str->len );\n                rb_funcall( obj, s_tr_bang, 2, rb_str_new2( \"\\n\\t \" ), rb_str_new2( \"\" ) );\n                arr = rb_funcall( obj, s_unpack, 1, rb_str_new2( \"m\" ) );\n                obj = rb_ary_shift( arr );\n            }\n            else if ( strcmp( type_id, \"bool#yes\" ) == 0 )\n            {\n                obj = Qtrue;\n            }\n            else if ( strcmp( type_id, \"bool#no\" ) == 0 )\n            {\n                obj = Qfalse;\n            }\n            else if ( strcmp( type_id, \"int#hex\" ) == 0 )\n            {\n                syck_str_blow_away_commas( n );\n                obj = rb_cstr2inum( n->data.str->ptr, 16 );\n            }\n            else if ( strcmp( type_id, \"int#oct\" ) == 0 )\n            {\n                syck_str_blow_away_commas( n );\n                obj = rb_cstr2inum( n->data.str->ptr, 8 );\n            }\n            else if ( strcmp( type_id, \"int#base60\" ) == 0 )\n            {\n                char *ptr, *end;\n                long sixty = 1;\n                long total = 0;\n                syck_str_blow_away_commas( n );\n                ptr = n->data.str->ptr;\n                end = n->data.str->ptr + n->data.str->len;\n                while ( end > ptr )\n                {\n                    long bnum = 0;\n                    char *colon = end - 1;\n                    while ( colon >= ptr && *colon != ':' )\n                    {\n                        colon--;\n                    }\n                    if ( colon >= ptr && *colon == ':' ) *colon = '\\0';\n\n                    bnum = strtol( colon + 1, NULL, 10 );\n                    total += bnum * sixty;\n                    sixty *= 60;\n                    end = colon;\n                }\n                obj = INT2FIX(total);\n            }\n            else if ( strncmp( type_id, \"int\", 3 ) == 0 )\n            {\n                syck_str_blow_away_commas( n );\n                obj = rb_cstr2inum( n->data.str->ptr, 10 );\n            }\n            else if ( strcmp( type_id, \"float#base60\" ) == 0 )\n            {\n                char *ptr, *end;\n                long sixty = 1;\n                double total = 0.0;\n                syck_str_blow_away_commas( n );\n                ptr = n->data.str->ptr;\n                end = n->data.str->ptr + n->data.str->len;\n                while ( end > ptr )\n                {\n                    double bnum = 0;\n                    char *colon = end - 1;\n                    while ( colon >= ptr && *colon != ':' )\n                    {\n                        colon--;\n                    }\n                    if ( colon >= ptr && *colon == ':' ) *colon = '\\0';\n\n                    bnum = strtod( colon + 1, NULL );\n                    total += bnum * sixty;\n                    sixty *= 60;\n                    end = colon;\n                }\n                obj = rb_float_new( total );\n            }\n            else if ( strcmp( type_id, \"float#nan\" ) == 0 )\n            {\n                obj = rb_float_new( S_nan() );\n            }\n            else if ( strcmp( type_id, \"float#inf\" ) == 0 )\n            {\n                obj = rb_float_new( S_inf() );\n            }\n            else if ( strcmp( type_id, \"float#neginf\" ) == 0 )\n            {\n                obj = rb_float_new( -S_inf() );\n            }\n            else if ( strncmp( type_id, \"float\", 5 ) == 0 )\n            {\n                double f;\n                syck_str_blow_away_commas( n );\n                f = strtod( n->data.str->ptr, NULL );\n                obj = rb_float_new( f );\n            }\n            else if ( strcmp( type_id, \"timestamp#iso8601\" ) == 0 )\n            {\n                obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );\n            }\n            else if ( strcmp( type_id, \"timestamp#spaced\" ) == 0 )\n            {\n                obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );\n            }\n            else if ( strcmp( type_id, \"timestamp#ymd\" ) == 0 )\n            {\n                char *ptr = n->data.str->ptr;\n                VALUE year, mon, day;\n\n                /* Year*/\n                ptr[4] = '\\0';\n                year = INT2FIX(strtol(ptr, NULL, 10));\n\n                /* Month*/\n                ptr += 4;\n                while ( !ISDIGIT( *ptr ) ) ptr++;\n                mon = INT2FIX(strtol(ptr, NULL, 10));\n\n                /* Day*/\n                ptr += 2;\n                while ( !ISDIGIT( *ptr ) ) ptr++;\n                day = INT2FIX(strtol(ptr, NULL, 10));\n\n                if ( !cDate ) {\n                    /*\n                     * Load Date module\n                     */\n                    rb_require( \"date\" );\n                    cDate = rb_const_get( rb_cObject, rb_intern(\"Date\") );\n                }\n\n                obj = rb_funcall( cDate, s_new, 3, year, mon, day );\n            }\n            else if ( strncmp( type_id, \"timestamp\", 9 ) == 0 )\n            {\n                obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );\n            }\n            else if ( strncmp( type_id, \"merge\", 5 ) == 0 )\n            {\n                obj = rb_funcall( cMergeKey, s_new, 0 );\n            }\n            else if ( strncmp( type_id, \"default\", 7 ) == 0 )\n            {\n                obj = rb_funcall( cDefaultKey, s_new, 0 );\n            }\n            else if ( n->data.str->style == scalar_plain &&\n                      n->data.str->len > 1 && \n                      strncmp( n->data.str->ptr, \":\", 1 ) == 0 )\n            {\n                obj = rb_funcall( oDefaultResolver, s_transfer, 2, \n                                  rb_str_new2( \"tag:ruby.yaml.org,2002:sym\" ), \n                                  rb_str_new( n->data.str->ptr + 1, n->data.str->len - 1 ) );\n            }\n            else if ( strcmp( type_id, \"str\" ) == 0 )\n            {\n                obj = rb_str_new( n->data.str->ptr, n->data.str->len );\n            }\n            else\n            {\n                transferred = 0;\n                obj = rb_str_new( n->data.str->ptr, n->data.str->len );\n            }\n        break;\n\n        case syck_seq_kind:\n            if ( type_id == NULL || strcmp( type_id, \"seq\" ) == 0 )\n            {\n                transferred = 1;\n            }\n            obj = rb_ary_new2( n->data.list->idx );\n            for ( i = 0; i < n->data.list->idx; i++ )\n            {\n                rb_ary_store( obj, i, syck_seq_read( n, i ) );\n            }\n        break;\n\n        case syck_map_kind:\n            if ( type_id == NULL || strcmp( type_id, \"map\" ) == 0 )\n            {\n                transferred = 1;\n            }\n            obj = rb_hash_new();\n            for ( i = 0; i < n->data.pairs->idx; i++ )\n            {\n                VALUE k = syck_map_read( n, map_key, i );\n                VALUE v = syck_map_read( n, map_value, i );\n                int skip_aset = 0;\n\n                /*\n                 * Handle merge keys\n                 */\n                if ( rb_obj_is_kind_of( k, cMergeKey ) )\n                {\n                    VALUE tmp;\n                    if ( !NIL_P(tmp = rb_check_convert_type(v, T_HASH, \"Hash\", \"to_hash\")) )\n                    {\n                        VALUE dup = rb_funcall( tmp, s_dup, 0 );\n                        rb_funcall( dup, s_update, 1, obj );\n                        obj = dup;\n                        skip_aset = 1;\n                    }\n                    else if ( !NIL_P(tmp = rb_check_array_type(v)) )\n                    {\n                        VALUE end = rb_ary_pop( tmp );\n                        VALUE tmph = rb_check_convert_type(end, T_HASH, \"Hash\", \"to_hash\");\n                        if ( !NIL_P(tmph) )\n                        {\n                            VALUE dup = rb_funcall( tmph, s_dup, 0 );\n                            tmp = rb_ary_reverse( tmp );\n                            rb_ary_push( tmp, obj );\n                            rb_iterate( rb_each, tmp, syck_merge_i, dup );\n                            obj = dup;\n                            skip_aset = 1;\n                        }\n                    }\n                }\n                else if ( rb_obj_is_kind_of( k, cDefaultKey ) )\n                {\n                    rb_funcall( obj, s_default_set, 1, v );\n                    skip_aset = 1;\n                }\n\n                if ( ! skip_aset )\n                {\n                    rb_hash_aset( obj, k, v );\n                }\n            }\n        break;\n    }\n\n    *ref = obj;\n    return transferred;\n}\n\nstatic void syck_node_mark( SyckNode *n );\n\n/*\n * {native mode} node handler\n * - Converts data into native Ruby types\n */\nSYMID\nrb_syck_load_handler(p, n)\n    SyckParser *p;\n    SyckNode *n;\n{\n    VALUE obj = Qnil;\n    struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;\n    VALUE resolver = bonus->resolver;\n    if ( NIL_P( resolver ) )\n    {\n        resolver = oDefaultResolver;\n    }\n\n    /*\n     * Create node, \n     */\n    obj = rb_funcall( resolver, s_node_import, 1, Data_Wrap_Struct( cNode, NULL, NULL, n ) );\n\n    /*\n     * ID already set, let's alter the symbol table to accept the new object\n     */\n    if (n->id > 0 && !NIL_P(obj))\n    {\n        MEMCPY((void *)n->id, (void *)obj, RVALUE, 1);\n        MEMZERO((void *)obj, RVALUE, 1);\n        obj = n->id;\n    }\n\n    if ( bonus->taint)      OBJ_TAINT( obj );\n    if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj);\n\n    rb_hash_aset(bonus->data, INT2FIX(RHASH(bonus->data)->tbl->num_entries), obj);\n    return obj;\n}\n\n/*\n * friendly errors.\n */\nvoid\nrb_syck_err_handler(p, msg)\n    SyckParser *p;\n    char *msg;\n{\n    char *endl = p->cursor;\n\n    while ( *endl != '\\0' && *endl != '\\n' )\n        endl++;\n\n    endl[0] = '\\0';\n    rb_raise(rb_eArgError, \"%s on line %d, col %d: `%s'\",\n           msg,\n           p->linect,\n           p->cursor - p->lineptr, \n           p->lineptr); \n}\n\n/*\n * provide bad anchor object to the parser.\n */\nSyckNode *\nrb_syck_bad_anchor_handler(p, a)\n    SyckParser *p;\n    char *a;\n{\n    VALUE anchor_name = rb_str_new2( a );\n    SyckNode *badanc = syck_new_map( rb_str_new2( \"name\" ), anchor_name );\n    badanc->type_id = syck_strndup( \"tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias\", 53 );\n    return badanc;\n}\n\n/*\n * data loaded based on the model requested.\n */\nvoid\nsyck_set_model( p, input, model )\n    VALUE p, input, model;\n{\n    SyckParser *parser;\n    Data_Get_Struct(p, SyckParser, parser);\n    syck_parser_handler( parser, rb_syck_load_handler );\n    /* WARN: gonna be obsoleted soon!! */\n    if ( model == sym_generic )\n    {\n        rb_funcall( p, s_set_resolver, 1, oGenericResolver );\n    }\n    syck_parser_implicit_typing( parser, 1 );\n    syck_parser_taguri_expansion( parser, 1 );\n\n    if ( NIL_P( input ) )\n    {\n        input = rb_ivar_get( p, s_input ); \n    }\n    if ( input == sym_bytecode )\n    {\n        syck_parser_set_input_type( parser, syck_bytecode_utf8 );\n    }\n    else\n    {\n        syck_parser_set_input_type( parser, syck_yaml_utf8 );\n    }\n    syck_parser_error_handler( parser, rb_syck_err_handler );\n    syck_parser_bad_anchor_handler( parser, rb_syck_bad_anchor_handler );\n}\n\nstatic int\nsyck_st_mark_nodes( char *key, SyckNode *n, char *arg )\n{\n    if ( n != (void *)1 ) syck_node_mark( n );\n    return ST_CONTINUE;\n}\n\n/*\n * mark parser nodes\n */\nstatic void\nsyck_mark_parser(parser)\n    SyckParser *parser;\n{\n    struct parser_xtra *bonus = (struct parser_xtra *)parser->bonus;\n    rb_gc_mark_maybe(parser->root);\n    rb_gc_mark_maybe(parser->root_on_error);\n    rb_gc_mark( bonus->data );\n    rb_gc_mark( bonus->proc );\n    rb_gc_mark( bonus->resolver );\n\n    if ( parser->anchors != NULL )\n    {\n        st_foreach( parser->anchors, syck_st_mark_nodes, 0 );\n    }\n    if ( parser->bad_anchors != NULL )\n    {\n        st_foreach( parser->bad_anchors, syck_st_mark_nodes, 0 );\n    }\n}\n\n/*\n * Free the parser and any bonus attachment.\n */\nvoid\nrb_syck_free_parser(p)\n    SyckParser *p;\n{\n    S_FREE( p->bonus );\n    syck_free_parser(p);\n}\n\n/*\n * YAML::Syck::Parser.allocate\n */\nVALUE syck_parser_s_alloc _((VALUE));\nVALUE \nsyck_parser_s_alloc(class)\n    VALUE class;\n{\n    VALUE pobj;\n    SyckParser *parser = syck_new_parser();\n\n    parser->bonus = S_ALLOC( struct parser_xtra );\n    S_MEMZERO( parser->bonus, struct parser_xtra, 1 );\n\n    pobj = Data_Wrap_Struct( class, syck_mark_parser, rb_syck_free_parser, parser );\n\n    syck_parser_set_root_on_error( parser, Qnil );\n\n    return pobj;\n}\n\n/*\n * YAML::Syck::Parser.initialize( resolver, options )\n */\nstatic VALUE\nsyck_parser_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE options;\n    if (rb_scan_args(argc, argv, \"01\", &options) == 0)\n    {\n        options = rb_hash_new();\n    }\n    else\n    {\n        Check_Type(options, T_HASH);\n    }\n    rb_ivar_set(self, s_options, options);\n    rb_ivar_set(self, s_input, Qnil);\n    return self;\n}\n\n/*\n * YAML::Syck::Parser.bufsize = Integer\n */\nstatic VALUE\nsyck_parser_bufsize_set( self, size )\n    VALUE self, size;\n{\n    SyckParser *parser;\n\n    if ( rb_respond_to( size, s_to_i ) ) {\n        int n = NUM2INT(rb_funcall(size, s_to_i, 0));\n        Data_Get_Struct(self, SyckParser, parser);\n        parser->bufsize = n;\n    }\n    return self;\n}\n\n/*\n * YAML::Syck::Parser.bufsize => Integer\n */\nstatic VALUE\nsyck_parser_bufsize_get( self )\n    VALUE self;\n{\n    SyckParser *parser;\n\n    Data_Get_Struct(self, SyckParser, parser);\n    return INT2FIX( parser->bufsize );\n}\n\n/*\n * YAML::Syck::Parser.load( IO or String )\n */\nVALUE\nsyck_parser_load(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE port, proc, model, input;\n    SyckParser *parser;\n    struct parser_xtra *bonus;\n\n    rb_scan_args(argc, argv, \"11\", &port, &proc);\n\n    input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );\n    model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );\n    Data_Get_Struct(self, SyckParser, parser);\n    syck_set_model( self, input, model );\n\n    bonus = (struct parser_xtra *)parser->bonus;\n    bonus->taint = syck_parser_assign_io(parser, &port);\n    bonus->data = rb_hash_new();\n    bonus->resolver = rb_attr_get( self, s_resolver );\n    if ( NIL_P( proc ) ) bonus->proc = 0;\n    else                 bonus->proc = proc;\n\n    return syck_parse( parser );\n}\n\n/*\n * YAML::Syck::Parser.load_documents( IO or String ) { |doc| }\n */\nVALUE\nsyck_parser_load_documents(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE port, proc, v, input, model;\n    SyckParser *parser;\n    struct parser_xtra *bonus;\n\n    rb_scan_args(argc, argv, \"1&\", &port, &proc);\n\n    input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );\n    model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );\n    Data_Get_Struct(self, SyckParser, parser);\n    syck_set_model( self, input, model );\n    \n    bonus = (struct parser_xtra *)parser->bonus;\n    bonus->taint = syck_parser_assign_io(parser, &port);\n    bonus->resolver = rb_attr_get( self, s_resolver );\n    bonus->proc = 0;\n\n    while ( 1 )\n    {\n        /* Reset hash for tracking nodes */\n        bonus->data = rb_hash_new();\n\n        /* Parse a document */\n        v = syck_parse( parser );\n        if ( parser->eof == 1 )\n        {\n            break;\n        }\n\n        /* Pass document to block */\n        rb_funcall( proc, s_call, 1, v );\n    }\n\n    return Qnil;\n}\n\n/*\n * YAML::Syck::Parser#set_resolver\n */\nVALUE\nsyck_parser_set_resolver( self, resolver )\n    VALUE self, resolver;\n{\n    rb_ivar_set( self, s_resolver, resolver );\n    return self;\n}\n\n/*\n * YAML::Syck::Resolver.initialize\n */\nstatic VALUE\nsyck_resolver_initialize( self )\n    VALUE self;\n{\n    rb_ivar_set(self, s_tags, rb_hash_new());\n    return self;\n}\n\n/*\n * YAML::Syck::Resolver#add_type\n */\nVALUE\nsyck_resolver_add_type( self, taguri, cls )\n    VALUE self, taguri, cls;\n{\n    VALUE tags = rb_attr_get(self, s_tags);\n    rb_hash_aset( tags, taguri, cls );\n    return Qnil;\n}\n\n/*\n * YAML::Syck::Resolver#use_types_at\n */\nVALUE\nsyck_resolver_use_types_at( self, hsh )\n    VALUE self, hsh;\n{\n    rb_ivar_set( self, s_tags, hsh );\n    return Qnil;\n}\n\n/*\n * YAML::Syck::Resolver#detect_implicit \n */\nVALUE\nsyck_resolver_detect_implicit( self, val )\n    VALUE self, val;\n{\n    return rb_str_new2( \"\" );\n}\n\n/*\n * YAML::Syck::Resolver#node_import\n */\nVALUE\nsyck_resolver_node_import( self, node )\n    VALUE self, node;\n{\n    SyckNode *n;\n    VALUE obj;\n    int i = 0;\n    Data_Get_Struct(node, SyckNode, n);\n\n    switch (n->kind)\n    {\n        case syck_str_kind:\n            obj = rb_str_new( n->data.str->ptr, n->data.str->len );\n        break;\n\n        case syck_seq_kind:\n            obj = rb_ary_new2( n->data.list->idx );\n            for ( i = 0; i < n->data.list->idx; i++ )\n            {\n                rb_ary_store( obj, i, syck_seq_read( n, i ) );\n            }\n        break;\n\n        case syck_map_kind:\n            obj = rb_hash_new();\n            for ( i = 0; i < n->data.pairs->idx; i++ )\n            {\n                VALUE k = syck_map_read( n, map_key, i );\n                VALUE v = syck_map_read( n, map_value, i );\n                int skip_aset = 0;\n\n                /*\n                 * Handle merge keys\n                 */\n                if ( rb_obj_is_kind_of( k, cMergeKey ) )\n                {\n                    if ( rb_obj_is_kind_of( v, rb_cHash ) )\n                    {\n                        VALUE dup = rb_funcall( v, s_dup, 0 );\n                        rb_funcall( dup, s_update, 1, obj );\n                        obj = dup;\n                        skip_aset = 1;\n                    }\n                    else if ( rb_obj_is_kind_of( v, rb_cArray ) )\n                    {\n                        VALUE end = rb_ary_pop( v );\n                        if ( rb_obj_is_kind_of( end, rb_cHash ) )\n                        {\n                            VALUE dup = rb_funcall( end, s_dup, 0 );\n                            v = rb_ary_reverse( v );\n                            rb_ary_push( v, obj );\n                            rb_iterate( rb_each, v, syck_merge_i, dup );\n                            obj = dup;\n                            skip_aset = 1;\n                        }\n                    }\n                }\n                else if ( rb_obj_is_kind_of( k, cDefaultKey ) )\n                {\n                    rb_funcall( obj, s_default_set, 1, v );\n                    skip_aset = 1;\n                }\n\n                if ( ! skip_aset )\n                {\n                    rb_hash_aset( obj, k, v );\n                }\n            }\n        break;\n    }\n\n    if ( n->type_id != NULL )\n    {\n        obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );\n    }\n    return obj;\n}\n\n/*\n * Set instance variables\n */\nVALUE\nsyck_set_ivars( vars, obj )\n        VALUE vars, obj;\n{\n    VALUE ivname = rb_ary_entry( vars, 0 );\n    char *ivn;\n    StringValue( ivname );\n    ivn = S_ALLOCA_N( char, RSTRING(ivname)->len + 2 );\n    ivn[0] = '@';\n    ivn[1] = '\\0';\n    strncat( ivn, RSTRING(ivname)->ptr, RSTRING(ivname)->len );\n    rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) );\n    return Qnil;\n}\n\n/*\n * YAML::Syck::Resolver#const_find\n */\nVALUE\nsyck_const_find( const_name )\n    VALUE const_name;\n{\n    VALUE tclass = rb_cObject;\n    VALUE tparts = rb_str_split( const_name, \"::\" );\n    int i = 0;\n    for ( i = 0; i < RARRAY(tparts)->len; i++ ) {\n        VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) );\n        if ( !rb_const_defined( tclass, tpart ) ) return Qnil;\n        tclass = rb_const_get( tclass, tpart );\n    }\n    return tclass;\n}\n\n/*\n * YAML::Syck::Resolver#transfer\n */\nVALUE\nsyck_resolver_transfer( self, type, val )\n    VALUE self, type, val;\n{\n    if (NIL_P(type) || RSTRING(StringValue(type))->len == 0) \n    {\n        type = rb_funcall( self, s_detect_implicit, 1, val );\n    }\n\n    if ( ! (NIL_P(type) || RSTRING(StringValue(type))->len == 0) )\n    {\n        VALUE str_xprivate = rb_str_new2( \"x-private\" );\n        VALUE colon = rb_str_new2( \":\" );\n        VALUE tags = rb_attr_get(self, s_tags);\n        VALUE target_class = rb_hash_aref( tags, type );\n        VALUE subclass = target_class;\n        VALUE obj = Qnil;\n\n        /*\n         * Should no tag match exactly, check for subclass format\n         */\n        if ( NIL_P( target_class ) )\n        {\n            VALUE subclass_parts = rb_ary_new();\n            VALUE parts = rb_str_split( type, \":\" );\n\n            while ( RARRAY(parts)->len > 1 )\n            {\n                VALUE partial;\n                rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) );\n                partial = rb_ary_join( parts, colon );\n                target_class = rb_hash_aref( tags, partial );\n                if ( NIL_P( target_class ) )\n                {\n                    rb_str_append( partial, colon );\n                    target_class = rb_hash_aref( tags, partial );\n                }\n\n                /*\n                 * Possible subclass found, see if it supports subclassing\n                 */\n                if ( ! NIL_P( target_class ) )\n                {\n                    subclass = target_class;\n                    if ( RARRAY(subclass_parts)->len > 0 && rb_respond_to( target_class, s_tag_subclasses ) &&\n                         RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) )\n                    {\n                        VALUE subclass_v;\n                        subclass = rb_ary_join( subclass_parts, colon );\n                        subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass );\n                        subclass_v = syck_const_find( subclass );\n\n                        if ( subclass_v != Qnil ) \n                        {\n                            subclass = subclass_v;\n                        }\n                        else if ( rb_cObject == target_class && subclass_v == Qnil )\n                        {\n                            target_class = cYObject;\n                            type = subclass;\n                            subclass = cYObject;\n                        }\n                        else /* workaround for SEGV. real fix please */\n                        {\n                            rb_raise( rb_eTypeError, \"invalid subclass\" );\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n\n        /* rb_raise(rb_eTypeError, \"invalid typing scheme: %s given\",\n         *         scheme);\n         */\n\n        if ( rb_respond_to( target_class, s_call ) )\n        {\n            obj = rb_funcall( target_class, s_call, 2, type, val );\n        }\n        else\n        {\n            if ( rb_respond_to( target_class, s_yaml_new ) )\n            {\n                obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val );\n            }\n            else if ( !NIL_P( target_class ) )\n            {\n                if ( subclass == rb_cBignum )\n                {\n                    obj = rb_str2inum( val, 10 ); /* for yaml dumped by 1.8.3 [ruby-core:6159] */\n                }\n                else\n                {\n                    obj = rb_obj_alloc( subclass );\n                }\n\n                if ( rb_respond_to( obj, s_yaml_initialize ) )\n                {\n                    rb_funcall( obj, s_yaml_initialize, 2, type, val );\n                }\n                else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) )\n                {\n                    rb_iterate( rb_each, val, syck_set_ivars, obj );\n                }\n            }\n            else \n            {\n                VALUE parts = rb_str_split( type, \":\" );\n                VALUE scheme = rb_ary_shift( parts );\n                if ( rb_str_cmp( scheme, str_xprivate ) == 0 )\n                {\n                    VALUE name = rb_ary_join( parts, colon );\n                    obj = rb_funcall( cPrivateType, s_new, 2, name, val );\n                }\n                else\n                {\n                    VALUE domain = rb_ary_shift( parts );\n                    VALUE name = rb_ary_join( parts, colon );\n                    obj = rb_funcall( cDomainType, s_new, 3, domain, name, val );\n                }\n            }\n        }\n        val = obj;\n    }\n\n    return val;\n}\n\n/*\n * YAML::Syck::Resolver#tagurize\n */\nVALUE\nsyck_resolver_tagurize( self, val )\n    VALUE self, val;\n{\n    VALUE tmp = rb_check_string_type(val);\n\n    if ( !NIL_P(tmp) )\n    {\n        char *taguri = syck_type_id_to_uri( RSTRING(tmp)->ptr );\n        val = rb_str_new2( taguri );\n        S_FREE( taguri );\n    }\n\n    return val;\n}\n\n/*\n * YAML::Syck::DefaultResolver#detect_implicit \n */\nVALUE\nsyck_defaultresolver_detect_implicit( self, val )\n    VALUE self, val;\n{\n    char *type_id;\n    VALUE tmp = rb_check_string_type(val);\n\n    if ( !NIL_P(tmp) )\n    {\n        val = tmp;\n        type_id = syck_match_implicit( RSTRING(val)->ptr, RSTRING(val)->len );\n        return rb_str_new2( type_id );\n    }\n\n    return rb_str_new2( \"\" );\n}\n\n/*\n * YAML::Syck::DefaultResolver#node_import\n */\nVALUE\nsyck_defaultresolver_node_import( self, node )\n    VALUE self, node;\n{\n    SyckNode *n;\n    VALUE obj;\n    Data_Get_Struct( node, SyckNode, n );\n    if ( !yaml_org_handler( n, &obj ) )\n    {\n        obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );\n    }\n    return obj;\n}\n\n/*\n * YAML::Syck::GenericResolver#node_import\n */\nVALUE\nsyck_genericresolver_node_import( self, node )\n    VALUE self, node;\n{\n    SyckNode *n;\n    int i = 0;\n    VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil;\n    Data_Get_Struct(node, SyckNode, n);\n\n    if ( n->type_id != NULL )\n    {\n        t = rb_str_new2(n->type_id);\n    }\n\n    switch (n->kind)\n    {\n        case syck_str_kind:\n        {\n            v = rb_str_new( n->data.str->ptr, n->data.str->len );\n            if ( n->data.str->style == scalar_1quote )\n            {\n                style = sym_1quote;\n            } \n            else if ( n->data.str->style == scalar_2quote )\n            {\n                style = sym_2quote;\n            } \n            else if ( n->data.str->style == scalar_fold )\n            {\n                style = sym_fold;\n            } \n            else if ( n->data.str->style == scalar_literal )\n            {\n                style = sym_literal;\n            } \n            else if ( n->data.str->style == scalar_plain )\n            {\n                style = sym_plain;\n            }\n            obj = rb_funcall( cScalar, s_new, 3, t, v, style );\n        }\n        break;\n\n        case syck_seq_kind:\n            v = rb_ary_new2( syck_seq_count( n ) );\n            for ( i = 0; i < syck_seq_count( n ); i++ )\n            {\n                rb_ary_store( v, i, syck_seq_read( n, i ) );\n            }\n            if ( n->data.list->style == seq_inline )\n            {\n                style = sym_inline;\n            } \n            obj = rb_funcall( cSeq, s_new, 3, t, v, style );\n            rb_iv_set(obj, \"@kind\", sym_seq);\n        break;\n\n        case syck_map_kind:\n            v = rb_hash_new();\n            for ( i = 0; i < syck_map_count( n ); i++ )\n            {\n                rb_hash_aset( v, syck_map_read( n, map_key, i ), syck_map_read( n, map_value, i ) );\n            }\n            if ( n->data.pairs->style == map_inline )\n            {\n                style = sym_inline;\n            } \n            obj = rb_funcall( cMap, s_new, 3, t, v, style );\n            rb_iv_set(obj, \"@kind\", sym_map);\n        break;\n    }\n\n    return obj;\n}\n\n/*\n * YAML::Syck::BadAlias.initialize\n */\nVALUE\nsyck_badalias_initialize( self, val )\n    VALUE self, val;\n{\n    rb_iv_set( self, \"@name\", val );\n    return self;\n}\n\n/*\n * YAML::Syck::BadAlias.<=>\n */\nVALUE\nsyck_badalias_cmp( alias1, alias2 )\n    VALUE alias1, alias2;\n{\n    VALUE str1 = rb_ivar_get( alias1, s_name ); \n    VALUE str2 = rb_ivar_get( alias2, s_name ); \n    VALUE val = rb_funcall( str1, s_cmp, 1, str2 );\n    return val;\n}\n\n/*\n * YAML::DomainType.initialize\n */\nVALUE\nsyck_domaintype_initialize( self, domain, type_id, val )\n    VALUE self, domain, type_id, val;\n{\n    rb_iv_set( self, \"@domain\", domain );\n    rb_iv_set( self, \"@type_id\", type_id );\n    rb_iv_set( self, \"@value\", val );\n    return self;\n}\n\n/*\n * YAML::Object.initialize\n */\nVALUE\nsyck_yobject_initialize( self, klass, ivars )\n    VALUE self, klass, ivars;\n{\n    rb_iv_set( self, \"@class\", klass );\n    rb_iv_set( self, \"@ivars\", ivars );\n    return self;\n}\n\n/*\n * YAML::PrivateType.initialize\n */\nVALUE\nsyck_privatetype_initialize( self, type_id, val )\n    VALUE self, type_id, val;\n{\n    rb_iv_set( self, \"@type_id\", type_id );\n    rb_iv_set( self, \"@value\", val );\n    return self;\n}\n\n/*\n * Mark node contents.\n */\nstatic void\nsyck_node_mark( n )\n    SyckNode *n;\n{\n    int i;\n    rb_gc_mark_maybe( n->id );\n    switch ( n->kind )\n    {\n        case syck_seq_kind:\n            for ( i = 0; i < n->data.list->idx; i++ )\n            {\n                rb_gc_mark( syck_seq_read( n, i ) );\n            }\n        break;\n\n        case syck_map_kind:\n            for ( i = 0; i < n->data.pairs->idx; i++ )\n            {\n                rb_gc_mark( syck_map_read( n, map_key, i ) );\n                rb_gc_mark( syck_map_read( n, map_value, i ) );\n            }\n        break;\n    }\n#if 0 /* maybe needed */\n    if ( n->shortcut ) syck_node_mark( n->shortcut ); /* caution: maybe cyclic */\n#endif\n}\n\n/*\n * YAML::Syck::Scalar.allocate\n */\nVALUE\nsyck_scalar_alloc( class )\n    VALUE class;\n{\n    SyckNode *node = syck_alloc_str();\n    VALUE obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );\n    node->id = obj;\n    return obj;\n}\n\n/*\n * YAML::Syck::Scalar.initialize\n */\nVALUE\nsyck_scalar_initialize( self, type_id, val, style )\n    VALUE self, type_id, val, style;\n{\n    rb_iv_set( self, \"@kind\", sym_scalar );\n    rb_funcall( self, s_type_id_set, 1, type_id );\n    rb_funcall( self, s_value_set, 1, val );\n    rb_funcall( self, s_style_set, 1, style );\n    return self;\n}\n\n/*\n * YAML::Syck::Scalar.style=\n */\nVALUE\nsyck_scalar_style_set( self, style )\n    VALUE self, style;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( NIL_P( style ) )\n    {\n        node->data.str->style = scalar_none;\n    } \n    else if ( style == sym_1quote )\n    {\n        node->data.str->style = scalar_1quote;\n    } \n    else if ( style == sym_2quote )\n    {\n        node->data.str->style = scalar_2quote;\n    } \n    else if ( style == sym_fold )\n    {\n        node->data.str->style = scalar_fold;\n    } \n    else if ( style == sym_literal )\n    {\n        node->data.str->style = scalar_literal;\n    } \n    else if ( style == sym_plain )\n    {\n        node->data.str->style = scalar_plain;\n    }\n\n    rb_iv_set( self, \"@style\", style );\n    return self;\n}\n\n/*\n * YAML::Syck::Scalar.value=\n */\nVALUE\nsyck_scalar_value_set( self, val )\n    VALUE self, val;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    StringValue( val );\n    node->data.str->ptr = syck_strndup( RSTRING(val)->ptr, RSTRING(val)->len );\n    node->data.str->len = RSTRING(val)->len;\n    node->data.str->style = scalar_none;\n\n    rb_iv_set( self, \"@value\", val );\n    return val;\n}\n\n/*\n * YAML::Syck::Seq.allocate\n */\nVALUE\nsyck_seq_alloc( class )\n    VALUE class;\n{\n    SyckNode *node;\n    VALUE obj;\n    node = syck_alloc_seq();\n    obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );\n    node->id = obj;\n    return obj;\n}\n\n/*\n * YAML::Syck::Seq.initialize\n */\nVALUE\nsyck_seq_initialize( self, type_id, val, style )\n    VALUE self, type_id, val, style;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    rb_iv_set( self, \"@kind\", sym_seq );\n    rb_funcall( self, s_type_id_set, 1, type_id );\n    rb_funcall( self, s_value_set, 1, val );\n    rb_funcall( self, s_style_set, 1, style );\n    return self;\n}\n\n/*\n * YAML::Syck::Seq.value=\n */\nVALUE\nsyck_seq_value_set( self, val )\n    VALUE self, val;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    val = rb_check_array_type( val );\n    if ( !NIL_P( val ) ) {\n        int i;\n        syck_seq_empty( node );\n        for ( i = 0; i < RARRAY( val )->len; i++ )\n        {\n            syck_seq_add( node, rb_ary_entry(val, i) );\n        }\n    }\n\n    rb_iv_set( self, \"@value\", val );\n    return val;\n}\n\n/*\n * YAML::Syck::Seq.add\n */\nVALUE\nsyck_seq_add_m( self, val )\n    VALUE self, val;\n{\n    SyckNode *node;\n    VALUE emitter = rb_ivar_get( self, s_emitter );\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( rb_respond_to( emitter, s_node_export ) ) {\n        val = rb_funcall( emitter, s_node_export, 1, val );\n    }\n    syck_seq_add( node, val );\n    rb_ary_push( rb_ivar_get( self, s_value ), val );\n\n    return self;\n}\n\n/*\n * YAML::Syck::Seq.style=\n */\nVALUE\nsyck_seq_style_set( self, style )\n    VALUE self, style;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( style == sym_inline )\n    {\n        node->data.list->style = seq_inline;\n    } \n    else\n    {\n        node->data.list->style = seq_none;\n    }\n\n    rb_iv_set( self, \"@style\", style );\n    return self;\n}\n\n/*\n * YAML::Syck::Map.allocate\n */\nVALUE\nsyck_map_alloc( class )\n    VALUE class;\n{\n    SyckNode *node;\n    VALUE obj;\n    node = syck_alloc_map();\n    obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );\n    node->id = obj;\n    return obj;\n}\n\n/*\n * YAML::Syck::Map.initialize\n */\nVALUE\nsyck_map_initialize( self, type_id, val, style )\n    VALUE self, type_id, val, style;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( !NIL_P( val ) )\n    {\n        VALUE hsh = rb_check_convert_type(val, T_HASH, \"Hash\", \"to_hash\");\n        VALUE keys;\n        int i;\n        if ( NIL_P(hsh) )\n        {\n            rb_raise( rb_eTypeError, \"wrong argument type\" );\n        }\n\n        keys = rb_funcall( hsh, s_keys, 0 );\n        for ( i = 0; i < RARRAY(keys)->len; i++ )\n        {\n            VALUE key = rb_ary_entry(keys, i);\n            syck_map_add( node, key, rb_hash_aref(hsh, key) );\n        }\n    }\n\n    rb_iv_set( self, \"@kind\", sym_seq );\n    rb_funcall( self, s_type_id_set, 1, type_id );\n    rb_funcall( self, s_value_set, 1, val );\n    rb_funcall( self, s_style_set, 1, style );\n    return self;\n}\n\n/*\n * YAML::Syck::Map.value=\n */\nVALUE\nsyck_map_value_set( self, val )\n    VALUE self, val;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( !NIL_P( val ) )\n    {\n        VALUE hsh = rb_check_convert_type(val, T_HASH, \"Hash\", \"to_hash\");\n        VALUE keys;\n        int i;\n        if ( NIL_P(hsh) )\n        {\n            rb_raise( rb_eTypeError, \"wrong argument type\" );\n        }\n\n        syck_map_empty( node );\n        keys = rb_funcall( hsh, s_keys, 0 );\n        for ( i = 0; i < RARRAY(keys)->len; i++ )\n        {\n            VALUE key = rb_ary_entry(keys, i);\n            syck_map_add( node, key, rb_hash_aref(hsh, key) );\n        }\n    }\n\n    rb_iv_set( self, \"@value\", val );\n    return val;\n}\n\n/*\n * YAML::Syck::Map.add\n */\nVALUE\nsyck_map_add_m( self, key, val )\n    VALUE self, key, val;\n{\n    SyckNode *node;\n    VALUE emitter = rb_ivar_get( self, s_emitter );\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( rb_respond_to( emitter, s_node_export ) ) {\n        key = rb_funcall( emitter, s_node_export, 1, key );\n        val = rb_funcall( emitter, s_node_export, 1, val );\n    }\n    syck_map_add( node, key, val );\n    rb_hash_aset( rb_ivar_get( self, s_value ), key, val );\n\n    return self;\n}\n\n/*\n * YAML::Syck::Map.style=\n */\nVALUE\nsyck_map_style_set( self, style )\n    VALUE self, style;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    if ( style == sym_inline )\n    {\n        node->data.pairs->style = map_inline;\n    } \n    else\n    {\n        node->data.pairs->style = map_none;\n    }\n\n    rb_iv_set( self, \"@style\", style );\n    return self;\n}\n\n/*\n * Cloning method for all node types\n */\nVALUE\nsyck_node_init_copy( copy, orig )\n    VALUE copy, orig;\n{\n    SyckNode *copy_n;\n    SyckNode *orig_n;\n\n    if ( copy == orig )\n        return copy;\n\n    if ( TYPE( orig ) != T_DATA )\n    {\n        rb_raise( rb_eTypeError, \"wrong argument type\" );\n    }\n\n    Data_Get_Struct( orig, SyckNode, orig_n );\n    Data_Get_Struct( copy, SyckNode, copy_n );\n    MEMCPY( copy_n, orig_n, SyckNode, 1 );\n    return copy;\n}\n\n/*\n * YAML::Syck::Node#type_id=\n */\nVALUE\nsyck_node_type_id_set( self, type_id )\n    VALUE self, type_id;\n{\n    SyckNode *node;\n    Data_Get_Struct( self, SyckNode, node );\n\n    S_FREE( node->type_id );\n\n    if ( !NIL_P( type_id ) ) {\n        StringValue( type_id );\n        node->type_id = syck_strndup( RSTRING(type_id)->ptr, RSTRING(type_id)->len );\n    }\n\n    rb_iv_set( self, \"@type_id\", type_id );\n    return type_id;\n}\n\n/*\n * YAML::Syck::Node.transform\n */\nVALUE\nsyck_node_transform( self )\n    VALUE self;\n{\n    VALUE t;\n    SyckNode *n;\n    SyckNode *orig_n;\n    Data_Get_Struct(self, SyckNode, orig_n);\n    t = Data_Wrap_Struct( cNode, syck_node_mark, syck_free_node, 0 );\n\n    switch (orig_n->kind)\n    {\n        case syck_map_kind:\n            {\n                int i;\n                DATA_PTR(t) = n = syck_alloc_map();\n                for ( i = 0; i < orig_n->data.pairs->idx; i++ )\n                {\n                    syck_map_add( n, rb_funcall( syck_map_read( orig_n, map_key, i ), s_transform, 0 ),\n                                     rb_funcall( syck_map_read( orig_n, map_value, i ), s_transform, 0 ) );\n                }\n            }\n        break;\n\n        case syck_seq_kind:\n            {\n                int i;\n                DATA_PTR(t) = n = syck_alloc_seq();\n                for ( i = 0; i < orig_n->data.list->idx; i++ )\n                {\n                    syck_seq_add( n, rb_funcall( syck_seq_read( orig_n, i ), s_transform, 0 ) );\n                }\n            }\n        break;\n\n        case syck_str_kind:\n            DATA_PTR(t) = n = syck_new_str2( orig_n->data.str->ptr, orig_n->data.str->len, orig_n->data.str->style );\n        break;\n    }\n\n    if ( orig_n->type_id != NULL )\n    {\n        n->type_id = syck_strndup( orig_n->type_id, strlen( orig_n->type_id ) );\n    }\n    if ( orig_n->anchor != NULL )\n    {\n        n->anchor = syck_strndup( orig_n->anchor, strlen( orig_n->anchor ) );\n    }\n    n->id = t;\n    return rb_funcall( oDefaultResolver, s_node_import, 1, t );\n}\n\n/*\n * Emitter callback: assembles YAML document events from\n * Ruby symbols.  This is a brilliant way to do it.\n * No one could possibly object.\n */\nvoid\nrb_syck_emitter_handler(e, data)\n    SyckEmitter *e;\n    st_data_t data;\n{\n    SyckNode *n;\n    Data_Get_Struct((VALUE)data, SyckNode, n);\n\n    switch (n->kind)\n    {\n        case syck_map_kind:\n            {\n                int i;\n                syck_emit_map( e, n->type_id, n->data.pairs->style );\n                for ( i = 0; i < n->data.pairs->idx; i++ )\n                {\n                    syck_emit_item( e, syck_map_read( n, map_key, i ) );\n                    syck_emit_item( e, syck_map_read( n, map_value, i ) );\n                }\n                syck_emit_end( e );\n            }\n        break;\n\n        case syck_seq_kind:\n            {\n                int i;\n                syck_emit_seq( e, n->type_id, n->data.list->style );\n                for ( i = 0; i < n->data.list->idx; i++ )\n                {\n                    syck_emit_item( e, syck_seq_read( n, i ) );\n                }\n                syck_emit_end( e );\n            }\n        break;\n\n        case syck_str_kind:\n            {\n                syck_emit_scalar( e, n->type_id, n->data.str->style, 0, 0, 0, n->data.str->ptr, n->data.str->len );\n            }\n        break;\n    }\n}\n\n/*\n * Handle output from the emitter\n */\nvoid \nrb_syck_output_handler( emitter, str, len )\n    SyckEmitter *emitter;\n    char *str;\n    long len;\n{\n    struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;\n    VALUE dest = bonus->port;\n    if (TYPE(dest) == T_STRING) {\n        rb_str_cat( dest, str, len );\n    } else {\n        rb_io_write( dest, rb_str_new( str, len ) );\n    }\n}\n\n/*\n * Helper function for marking nodes in the anchor\n * symbol table.\n */\nvoid\nsyck_out_mark( emitter, node )\n    VALUE emitter, node;\n{\n    SyckEmitter *emitterPtr;\n    struct emitter_xtra *bonus;\n    Data_Get_Struct(emitter, SyckEmitter, emitterPtr);\n    bonus = (struct emitter_xtra *)emitterPtr->bonus;\n    rb_ivar_set( node, s_emitter, emitter );\n    /* syck_emitter_mark_node( emitterPtr, (st_data_t)node ); */\n    if ( !NIL_P( bonus->oid ) ) {\n        rb_hash_aset( bonus->data, bonus->oid, node );\n    }\n}\n\n/*\n * Mark emitter values.\n */\nstatic void\nsyck_mark_emitter(emitter)\n    SyckEmitter *emitter;\n{\n    struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;\n    rb_gc_mark( bonus->oid  );\n    rb_gc_mark( bonus->data );\n    rb_gc_mark( bonus->port );\n}\n\n/*\n * Free the emitter and any bonus attachment.\n */\nvoid\nrb_syck_free_emitter(e)\n    SyckEmitter *e;\n{\n    S_FREE( e->bonus );\n    syck_free_emitter(e);\n}\n\n/*\n * YAML::Syck::Emitter.allocate\n */\nVALUE syck_emitter_s_alloc _((VALUE));\nVALUE \nsyck_emitter_s_alloc(class)\n    VALUE class;\n{\n    VALUE pobj;\n    SyckEmitter *emitter = syck_new_emitter();\n\n    emitter->bonus = S_ALLOC( struct emitter_xtra );\n    S_MEMZERO( emitter->bonus, struct emitter_xtra, 1 );\n\n    pobj = Data_Wrap_Struct( class, syck_mark_emitter, rb_syck_free_emitter, emitter );\n    syck_emitter_handler( emitter, rb_syck_emitter_handler );\n    syck_output_handler( emitter, rb_syck_output_handler );\n\n    rb_ivar_set( pobj, s_out, rb_funcall( cOut, s_new, 1, pobj ) );\n    return pobj;\n}\n\n/*\n * YAML::Syck::Emitter.reset( options )\n */\nVALUE\nsyck_emitter_reset( argc, argv, self )\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE options, tmp;\n    SyckEmitter *emitter;\n    struct emitter_xtra *bonus;\n\n    Data_Get_Struct(self, SyckEmitter, emitter);\n    bonus = (struct emitter_xtra *)emitter->bonus;\n\n    bonus->oid = Qnil;\n    bonus->port = rb_str_new2( \"\" );\n    bonus->data = rb_hash_new();\n\n    if (rb_scan_args(argc, argv, \"01\", &options) == 0)\n    {\n        options = rb_hash_new();\n        rb_ivar_set(self, s_options, options);\n    }\n    else if ( !NIL_P(tmp = rb_check_string_type(options)) )\n    {\n        bonus->port = tmp;\n    }\n    else if ( rb_respond_to( options, s_write ) )\n    {\n        bonus->port = options;\n    }\n    else\n    {\n        Check_Type(options, T_HASH);\n        rb_ivar_set(self, s_options, options);\n    }\n    \n    emitter->headless = 0;\n    rb_ivar_set(self, s_level, INT2FIX(0));\n    rb_ivar_set(self, s_resolver, Qnil);\n    return self;\n}\n\n/*\n * YAML::Syck::Emitter.emit( object_id ) { |out| ... }\n */\nVALUE\nsyck_emitter_emit( argc, argv, self )\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE oid, proc;\n    SyckEmitter *emitter;\n    struct emitter_xtra *bonus;\n    SYMID symple;\n    int level = FIX2INT(rb_ivar_get(self, s_level)) + 1;\n    rb_ivar_set(self, s_level, INT2FIX(level));\n\n    rb_scan_args(argc, argv, \"1&\", &oid, &proc);\n    Data_Get_Struct(self, SyckEmitter, emitter);\n    bonus = (struct emitter_xtra *)emitter->bonus;\n\n    /* Calculate anchors, normalize nodes, build a simpler symbol table */\n    bonus->oid = oid;\n    if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) {\n        symple = rb_hash_aref( bonus->data, oid );\n    } else {\n        symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) );\n    }\n    syck_emitter_mark_node( emitter, (st_data_t)symple );\n\n    /* Second pass, build emitted string */\n    level -= 1;\n    rb_ivar_set(self, s_level, INT2FIX(level));\n    if ( level == 0 ) \n    {\n        syck_emit(emitter, (st_data_t)symple);\n        syck_emitter_flush(emitter, 0);\n\n        return bonus->port;\n    }\n    \n    return symple;\n}\n\n/*\n * YAML::Syck::Emitter#node_export\n */\nVALUE\nsyck_emitter_node_export( self, node )\n    VALUE self, node;\n{\n    return rb_funcall( node, s_to_yaml, 1, self );\n}\n\n/*\n * YAML::Syck::Emitter#set_resolver\n */\nVALUE\nsyck_emitter_set_resolver( self, resolver )\n    VALUE self, resolver;\n{\n    rb_ivar_set( self, s_resolver, resolver );\n    return self;\n}\n\n/*\n * YAML::Syck::Out::initialize\n */\nVALUE\nsyck_out_initialize( self, emitter )\n    VALUE self, emitter;\n{\n    rb_ivar_set( self, s_emitter, emitter );\n    return self;\n}\n\n/*\n * YAML::Syck::Out::map\n */\nVALUE\nsyck_out_map( argc, argv, self )\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE type_id, style, map;\n    if (rb_scan_args(argc, argv, \"11\", &type_id, &style) == 1) {\n        style = Qnil;\n    }\n    map = rb_funcall( cMap, s_new, 3, type_id, rb_hash_new(), style );\n    syck_out_mark( rb_ivar_get( self, s_emitter ), map );\n    rb_yield( map );\n    return map;\n}\n\n/*\n * YAML::Syck::Out::seq\n */\nVALUE\nsyck_out_seq( argc, argv, self )\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE type_id, style, seq;\n    if (rb_scan_args(argc, argv, \"11\", &type_id, &style) == 1) {\n        style = Qnil;\n    }\n    seq = rb_funcall( cSeq, s_new, 3, type_id, rb_ary_new(), style );\n    syck_out_mark( rb_ivar_get( self, s_emitter ), seq );\n    rb_yield( seq );\n    return seq;\n}\n\n/*\n * YAML::Syck::Out::scalar\nsyck_out_scalar( self, type_id, str, style )\n    VALUE self, type_id, str, style;\n */\nVALUE\nsyck_out_scalar( argc, argv, self )\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE type_id, str, style, scalar;\n    if (rb_scan_args(argc, argv, \"21\", &type_id, &str, &style) == 2) {\n        style = Qnil;\n    }\n    scalar = rb_funcall( cScalar, s_new, 3, type_id, str, style );\n    syck_out_mark( rb_ivar_get( self, s_emitter ), scalar );\n    return scalar;\n}\n\n/*\n * Initialize Syck extension\n */\nvoid\nInit_syck()\n{\n    VALUE rb_yaml = rb_define_module( \"YAML\" );\n    VALUE rb_syck = rb_define_module_under( rb_yaml, \"Syck\" );\n    rb_define_const( rb_syck, \"VERSION\", rb_str_new2( SYCK_VERSION ) );\n    rb_define_module_function( rb_syck, \"compile\", rb_syck_compile, 1 );\n\n    /*\n     * Global symbols\n     */\n    s_new = rb_intern(\"new\");\n    s_utc = rb_intern(\"utc\");\n    s_at = rb_intern(\"at\");\n    s_to_f = rb_intern(\"to_f\");\n    s_to_i = rb_intern(\"to_i\");\n    s_read = rb_intern(\"read\");\n    s_binmode = rb_intern(\"binmode\");\n    s_transfer = rb_intern(\"transfer\");\n    s_call = rb_intern(\"call\");\n    s_cmp = rb_intern(\"<=>\");\n    s_intern = rb_intern(\"intern\");\n    s_update = rb_intern(\"update\");\n    s_detect_implicit = rb_intern(\"detect_implicit\");\n    s_dup = rb_intern(\"dup\");\n    s_default_set = rb_intern(\"default=\");\n    s_match = rb_intern(\"match\");\n    s_push = rb_intern(\"push\");\n    s_haskey = rb_intern(\"has_key?\");\n    s_keys = rb_intern(\"keys\");\n    s_node_import = rb_intern(\"node_import\");\n    s_tr_bang = rb_intern(\"tr!\");\n    s_unpack = rb_intern(\"unpack\");\n    s_write = rb_intern(\"write\");\n    s_tag_read_class = rb_intern( \"yaml_tag_read_class\" );\n    s_tag_subclasses = rb_intern( \"yaml_tag_subclasses?\" );\n    s_emitter = rb_intern( \"emitter\" );\n    s_set_resolver = rb_intern( \"set_resolver\" );\n    s_node_export = rb_intern( \"node_export\" );\n    s_to_yaml = rb_intern( \"to_yaml\" );\n    s_transform = rb_intern( \"transform\" );\n    s_yaml_new = rb_intern(\"yaml_new\");\n    s_yaml_initialize = rb_intern(\"yaml_initialize\");\n\n    s_tags = rb_intern(\"@tags\");\n    s_name = rb_intern(\"@name\");\n    s_options = rb_intern(\"@options\");\n    s_kind = rb_intern(\"@kind\");\n    s_type_id = rb_intern(\"@type_id\");\n    s_type_id_set = rb_intern(\"type_id=\");\n    s_resolver = rb_intern(\"@resolver\");\n    s_level = rb_intern( \"@level\" );\n    s_style = rb_intern(\"@style\");\n    s_style_set = rb_intern(\"style=\");\n    s_value = rb_intern(\"@value\");\n    s_value_set = rb_intern(\"value=\");\n    s_out = rb_intern(\"@out\");\n    s_input = rb_intern(\"@input\");\n\n    sym_model = ID2SYM(rb_intern(\"Model\"));\n    sym_generic = ID2SYM(rb_intern(\"Generic\"));\n    sym_bytecode = ID2SYM(rb_intern(\"bytecode\"));\n    sym_map = ID2SYM(rb_intern(\"map\"));\n    sym_scalar = ID2SYM(rb_intern(\"scalar\"));\n    sym_seq = ID2SYM(rb_intern(\"seq\"));\n    sym_1quote = ID2SYM(rb_intern(\"quote1\"));\n    sym_2quote = ID2SYM(rb_intern(\"quote2\"));\n    sym_fold = ID2SYM(rb_intern(\"fold\"));\n    sym_literal = ID2SYM(rb_intern(\"literal\"));\n    sym_plain = ID2SYM(rb_intern(\"plain\"));\n    sym_inline = ID2SYM(rb_intern(\"inline\"));\n\n    /*\n     * Define YAML::Syck::Resolver class\n     */\n    cResolver = rb_define_class_under( rb_syck, \"Resolver\", rb_cObject );\n    rb_define_attr( cResolver, \"tags\", 1, 1 );\n    rb_define_method( cResolver, \"initialize\", syck_resolver_initialize, 0 );\n    rb_define_method( cResolver, \"add_type\", syck_resolver_add_type, 2 );\n    rb_define_method( cResolver, \"use_types_at\", syck_resolver_use_types_at, 1 );\n    rb_define_method( cResolver, \"detect_implicit\", syck_resolver_detect_implicit, 1 );\n    rb_define_method( cResolver, \"transfer\", syck_resolver_transfer, 2 );\n    rb_define_method( cResolver, \"node_import\", syck_resolver_node_import, 1 );\n    rb_define_method( cResolver, \"tagurize\", syck_resolver_tagurize, 1 );\n\n    rb_global_variable( &oDefaultResolver );\n    oDefaultResolver = rb_funcall( cResolver, rb_intern( \"new\" ), 0 );\n    rb_define_singleton_method( oDefaultResolver, \"node_import\", syck_defaultresolver_node_import, 1 );\n    rb_define_singleton_method( oDefaultResolver, \"detect_implicit\", syck_defaultresolver_detect_implicit, 1 );\n    rb_define_const( rb_syck, \"DefaultResolver\", oDefaultResolver );\n    rb_global_variable( &oGenericResolver );\n    oGenericResolver = rb_funcall( cResolver, rb_intern( \"new\" ), 0 );\n    rb_define_singleton_method( oGenericResolver, \"node_import\", syck_genericresolver_node_import, 1 );\n    rb_define_const( rb_syck, \"GenericResolver\", oGenericResolver );\n\n    /*\n     * Define YAML::Syck::Parser class\n     */\n    cParser = rb_define_class_under( rb_syck, \"Parser\", rb_cObject );\n    rb_define_attr( cParser, \"options\", 1, 1 );\n    rb_define_attr( cParser, \"resolver\", 1, 1 );\n    rb_define_attr( cParser, \"input\", 1, 1 );\n    rb_define_alloc_func( cParser, syck_parser_s_alloc );\n    rb_define_method(cParser, \"initialize\", syck_parser_initialize, -1 );\n    rb_define_method(cParser, \"bufsize=\", syck_parser_bufsize_set, 1 );\n    rb_define_method(cParser, \"bufsize\", syck_parser_bufsize_get, 0 );\n    rb_define_method(cParser, \"load\", syck_parser_load, -1);\n    rb_define_method(cParser, \"load_documents\", syck_parser_load_documents, -1);\n    rb_define_method(cParser, \"set_resolver\", syck_parser_set_resolver, 1);\n\n    /*\n     * Define YAML::Syck::Node class\n     */\n    cNode = rb_define_class_under( rb_syck, \"Node\", rb_cObject );\n    rb_define_method( cNode, \"initialize_copy\", syck_node_init_copy, 1 );\n    rb_define_attr( cNode, \"emitter\", 1, 1 );\n    rb_define_attr( cNode, \"resolver\", 1, 1 );\n    rb_define_attr( cNode, \"kind\", 1, 0 );\n    rb_define_attr( cNode, \"type_id\", 1, 0 );\n    rb_define_attr( cNode, \"value\", 1, 0 );\n    rb_define_method( cNode, \"type_id=\", syck_node_type_id_set, 1 );\n    rb_define_method( cNode, \"transform\", syck_node_transform, 0);\n\n    /*\n     * Define YAML::Syck::Scalar, YAML::Syck::Seq, YAML::Syck::Map --\n     *     all are the publicly usable variants of YAML::Syck::Node\n     */\n    cScalar = rb_define_class_under( rb_syck, \"Scalar\", cNode );\n    rb_define_alloc_func( cScalar, syck_scalar_alloc );\n    rb_define_method( cScalar, \"initialize\", syck_scalar_initialize, 3 );\n    rb_define_method( cScalar, \"value=\", syck_scalar_value_set, 1 );\n    rb_define_method( cScalar, \"style=\", syck_scalar_style_set, 1 );\n    cSeq = rb_define_class_under( rb_syck, \"Seq\", cNode );\n    rb_define_alloc_func( cSeq, syck_seq_alloc );\n    rb_define_method( cSeq, \"initialize\", syck_seq_initialize, 3 );\n    rb_define_method( cSeq, \"value=\", syck_seq_value_set, 1 );\n    rb_define_method( cSeq, \"add\", syck_seq_add_m, 1 );\n    rb_define_method( cSeq, \"style=\", syck_seq_style_set, 1 );\n    cMap = rb_define_class_under( rb_syck, \"Map\", cNode );\n    rb_define_alloc_func( cMap, syck_map_alloc );\n    rb_define_method( cMap, \"initialize\", syck_map_initialize, 3 );\n    rb_define_method( cMap, \"value=\", syck_map_value_set, 1 );\n    rb_define_method( cMap, \"add\", syck_map_add_m, 2 );\n    rb_define_method( cMap, \"style=\", syck_map_style_set, 1 );\n\n    /*\n     * Define YAML::PrivateType class\n     */\n    cPrivateType = rb_define_class_under( rb_yaml, \"PrivateType\", rb_cObject );\n    rb_define_attr( cPrivateType, \"type_id\", 1, 1 );\n    rb_define_attr( cPrivateType, \"value\", 1, 1 );\n    rb_define_method( cPrivateType, \"initialize\", syck_privatetype_initialize, 2);\n\n    /*\n     * Define YAML::DomainType class\n     */\n    cDomainType = rb_define_class_under( rb_yaml, \"DomainType\", rb_cObject );\n    rb_define_attr( cDomainType, \"domain\", 1, 1 );\n    rb_define_attr( cDomainType, \"type_id\", 1, 1 );\n    rb_define_attr( cDomainType, \"value\", 1, 1 );\n    rb_define_method( cDomainType, \"initialize\", syck_domaintype_initialize, 3);\n\n    /*\n     * Define YAML::Object class\n     */\n    cYObject = rb_define_class_under( rb_yaml, \"Object\", rb_cObject );\n    rb_define_attr( cYObject, \"class\", 1, 1 );\n    rb_define_attr( cYObject, \"ivars\", 1, 1 );\n    rb_define_method( cYObject, \"initialize\", syck_yobject_initialize, 2);\n    rb_define_method( cYObject, \"yaml_initialize\", syck_yobject_initialize, 2);\n\n    /*\n     * Define YAML::Syck::BadAlias class\n     */\n    cBadAlias = rb_define_class_under( rb_syck, \"BadAlias\", rb_cObject );\n    rb_define_attr( cBadAlias, \"name\", 1, 1 );\n    rb_define_method( cBadAlias, \"initialize\", syck_badalias_initialize, 1);\n    rb_define_method( cBadAlias, \"<=>\", syck_badalias_cmp, 1);\n    rb_include_module( cBadAlias, rb_const_get( rb_cObject, rb_intern(\"Comparable\") ) );\n\n    /*\n     * Define YAML::Syck::MergeKey class\n     */\n    cMergeKey = rb_define_class_under( rb_syck, \"MergeKey\", rb_cObject );\n\n    /*\n     * Define YAML::Syck::DefaultKey class\n     */\n    cDefaultKey = rb_define_class_under( rb_syck, \"DefaultKey\", rb_cObject );\n\n    /*\n     * Define YAML::Syck::Out classes\n     */\n    cOut = rb_define_class_under( rb_syck, \"Out\", rb_cObject );\n    rb_define_attr( cOut, \"emitter\", 1, 1 );\n    rb_define_method( cOut, \"initialize\", syck_out_initialize, 1 );\n    rb_define_method( cOut, \"map\", syck_out_map, -1 );\n    rb_define_method( cOut, \"seq\", syck_out_seq, -1 );\n    rb_define_method( cOut, \"scalar\", syck_out_scalar, -1 );\n\n    /*\n     * Define YAML::Syck::Emitter class\n     */\n    cEmitter = rb_define_class_under( rb_syck, \"Emitter\", rb_cObject );\n    rb_define_attr( cEmitter, \"level\", 1, 1 );\n    rb_define_alloc_func( cEmitter, syck_emitter_s_alloc );\n    rb_define_method( cEmitter, \"initialize\", syck_emitter_reset, -1 );\n    rb_define_method( cEmitter, \"reset\", syck_emitter_reset, -1 );\n    rb_define_method( cEmitter, \"emit\", syck_emitter_emit, -1 );\n    rb_define_method( cEmitter, \"set_resolver\", syck_emitter_set_resolver, 1);\n    rb_define_method( cEmitter, \"node_export\", syck_emitter_node_export, 1);\n}\n\n"
  },
  {
    "path": "ext/syck/syck.c",
    "content": "/*\n * syck.c\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n#include \"ruby.h\"\n\n#include <stdio.h>\n#include <string.h>\n\n#include \"syck.h\"\n\nvoid syck_parser_pop_level( SyckParser * );\n\n/*\n * Custom assert\n */\nvoid \nsyck_assert( char *file_name, unsigned line_num )\n{\n    fflush( NULL );\n    fprintf( stderr, \"\\nAssertion failed: %s, line %u\\n\",\n             file_name, line_num );\n    fflush( stderr );\n    abort();\n}\n\n/*\n * Allocates and copies a string\n */\nchar *\nsyck_strndup( char *buf, long len )\n{\n    char *new = S_ALLOC_N( char, len + 1 );\n    S_MEMZERO( new, char, len + 1 );\n    S_MEMCPY( new, buf, char, len );\n    return new;\n}\n\n/*\n * Default FILE IO function\n */\nlong\nsyck_io_file_read( char *buf, SyckIoFile *file, long max_size, long skip )\n{\n    long len = 0;\n\n    ASSERT( file != NULL );\n\n    max_size -= skip;\n    len = fread( buf + skip, sizeof( char ), max_size, file->ptr );\n    len += skip;\n    buf[len] = '\\0';\n\n    return len;\n}\n\n/*\n * Default string IO function\n */\nlong\nsyck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )\n{\n    char *beg;\n    long len = 0;\n\n    ASSERT( str != NULL );\n    beg = str->ptr;\n    if ( max_size >= 0 )\n    {\n        max_size -= skip;\n        if ( max_size <= 0 )  max_size = 0;\n        else                  str->ptr += max_size;\n\n        if ( str->ptr > str->end )\n        {\n            str->ptr = str->end;\n        }\n    }\n    else\n    {\n        /* Use exact string length */\n        while ( str->ptr < str->end ) {\n            if (*(str->ptr++) == '\\n') break;\n        }\n    }\n    if ( beg < str->ptr )\n    {\n        len = ( str->ptr - beg );\n        S_MEMCPY( buf + skip, beg, char, len );\n    }\n    len += skip;\n    buf[len] = '\\0';\n\n    return len;\n}\n\nvoid\nsyck_parser_reset_levels( SyckParser *p )\n{\n    while ( p->lvl_idx > 1 )\n    {\n        syck_parser_pop_level( p );\n    }\n\n    if ( p->lvl_idx < 1 )\n    {\n        p->lvl_idx = 1;\n        p->levels[0].spaces = -1;\n        p->levels[0].ncount = 0;\n        p->levels[0].domain = syck_strndup( \"\", 0 );\n    }\n    p->levels[0].status = syck_lvl_header;\n}\n\nvoid\nsyck_parser_reset_cursor( SyckParser *p )\n{\n    if ( p->buffer == NULL )\n    {\n        p->buffer = S_ALLOC_N( char, p->bufsize );\n        S_MEMZERO( p->buffer, char, p->bufsize );\n    }\n    p->buffer[0] = '\\0';\n\n    p->cursor = NULL;\n    p->lineptr = NULL;\n    p->linectptr = NULL;\n    p->token = NULL;\n    p->toktmp = NULL;\n    p->marker = NULL;\n    p->limit = NULL;\n\n    p->root = 0;\n    p->root_on_error = 0;\n    p->linect = 0;\n    p->eof = 0;\n    p->last_token = 0;\n    p->force_token = 0;\n}\n\n/*\n * Value to return on a parse error\n */\nvoid\nsyck_parser_set_root_on_error( SyckParser *p, SYMID roer )\n{\n    p->root_on_error = roer;\n}\n\n/*\n * Allocate the parser\n */\nSyckParser *\nsyck_new_parser()\n{\n    SyckParser *p;\n    p = S_ALLOC( SyckParser );\n    S_MEMZERO( p, SyckParser, 1 );\n    p->lvl_capa = ALLOC_CT;\n    p->levels = S_ALLOC_N( SyckLevel, p->lvl_capa ); \n    p->input_type = syck_yaml_utf8;\n    p->io_type = syck_io_str;\n    p->io.str = NULL;\n    p->syms = NULL;\n    p->anchors = NULL;\n    p->bad_anchors = NULL;\n    p->implicit_typing = 1;\n    p->taguri_expansion = 0;\n    p->bufsize = SYCK_BUFFERSIZE;\n    p->buffer = NULL;\n    p->lvl_idx = 0;\n    syck_parser_reset_levels( p );\n    return p;\n}\n\nint\nsyck_add_sym( SyckParser *p, char *data )\n{\n    SYMID id = 0;\n    if ( p->syms == NULL )\n    {\n        p->syms = st_init_numtable();\n    }\n    id = p->syms->num_entries + 1;\n    st_insert( p->syms, id, (st_data_t)data );\n    return id;\n}\n\nint\nsyck_lookup_sym( SyckParser *p, SYMID id, char **data )\n{\n    if ( p->syms == NULL ) return 0;\n    return st_lookup( p->syms, id, (st_data_t *)data );\n}\n\nint\nsyck_st_free_nodes( char *key, SyckNode *n, char *arg )\n{\n    if ( n != (void *)1 ) syck_free_node( n );\n    n = NULL;\n    return ST_CONTINUE;\n}\n\nvoid\nsyck_st_free( SyckParser *p )\n{\n    /*\n     * Free the anchor tables\n     */\n    if ( p->anchors != NULL )\n    {\n        st_foreach( p->anchors, syck_st_free_nodes, 0 );\n        st_free_table( p->anchors );\n        p->anchors = NULL;\n    }\n\n    if ( p->bad_anchors != NULL )\n    {\n        st_foreach( p->bad_anchors, syck_st_free_nodes, 0 );\n        st_free_table( p->bad_anchors );\n        p->bad_anchors = NULL;\n    }\n}\n\nvoid\nsyck_free_parser( SyckParser *p )\n{\n    /*\n     * Free the adhoc symbol table\n     */\n    if ( p->syms != NULL )\n    {\n        st_free_table( p->syms );\n        p->syms = NULL;\n    }\n\n    /*\n     * Free tables, levels\n     */\n    syck_st_free( p );\n    syck_parser_reset_levels( p );\n    S_FREE( p->levels[0].domain );\n    S_FREE( p->levels );\n\n    if ( p->buffer != NULL )\n    {\n        S_FREE( p->buffer );\n    }\n    free_any_io( p );\n    S_FREE( p );\n}\n\nvoid\nsyck_parser_handler( SyckParser *p, SyckNodeHandler hdlr )\n{\n    ASSERT( p != NULL );\n    p->handler = hdlr;\n}\n\nvoid\nsyck_parser_implicit_typing( SyckParser *p, int flag )\n{\n    p->implicit_typing = ( flag == 0 ? 0 : 1 );\n}\n\nvoid\nsyck_parser_taguri_expansion( SyckParser *p, int flag )\n{\n    p->taguri_expansion = ( flag == 0 ? 0 : 1 );\n}\n\nvoid\nsyck_parser_error_handler( SyckParser *p, SyckErrorHandler hdlr )\n{\n    ASSERT( p != NULL );\n    p->error_handler = hdlr;\n}\n\nvoid\nsyck_parser_bad_anchor_handler( SyckParser *p, SyckBadAnchorHandler hdlr )\n{\n    ASSERT( p != NULL );\n    p->bad_anchor_handler = hdlr;\n}\n\nvoid\nsyck_parser_set_input_type( SyckParser *p, enum syck_parser_input input_type )\n{\n    ASSERT( p != NULL );\n    p->input_type = input_type;\n}\n\nvoid\nsyck_parser_file( SyckParser *p, FILE *fp, SyckIoFileRead read )\n{\n    ASSERT( p != NULL );\n    free_any_io( p );\n\tsyck_parser_reset_cursor( p );\n    p->io_type = syck_io_file;\n    p->io.file = S_ALLOC( SyckIoFile );\n    p->io.file->ptr = fp;\n    if ( read != NULL )\n    {\n        p->io.file->read = read;\n    }\n    else\n    {\n        p->io.file->read = syck_io_file_read;\n    }\n}\n\nvoid\nsyck_parser_str( SyckParser *p, char *ptr, long len, SyckIoStrRead read )\n{\n    ASSERT( p != NULL );\n    free_any_io( p );\n\tsyck_parser_reset_cursor( p );\n    p->io_type = syck_io_str;\n    p->io.str = S_ALLOC( SyckIoStr );\n    p->io.str->beg = ptr;\n    p->io.str->ptr = ptr;\n    p->io.str->end = ptr + len;\n    if ( read != NULL )\n    {\n        p->io.str->read = read;\n    }\n    else\n    {\n        p->io.str->read = syck_io_str_read;\n    }\n}\n\nvoid\nsyck_parser_str_auto( SyckParser *p, char *ptr, SyckIoStrRead read )\n{\n    syck_parser_str( p, ptr, strlen( ptr ), read );\n}\n\nSyckLevel *\nsyck_parser_current_level( SyckParser *p )\n{\n    return &p->levels[p->lvl_idx-1];\n}\n\nvoid\nsyck_parser_pop_level( SyckParser *p )\n{\n    ASSERT( p != NULL );\n\n    /* The root level should never be popped */\n    if ( p->lvl_idx <= 1 ) return;\n\n    p->lvl_idx -= 1;\n    free( p->levels[p->lvl_idx].domain );\n}\n\nvoid \nsyck_parser_add_level( SyckParser *p, int len, enum syck_level_status status )\n{\n    ASSERT( p != NULL );\n    if ( p->lvl_idx + 1 > p->lvl_capa )\n    {\n        p->lvl_capa += ALLOC_CT;\n        S_REALLOC_N( p->levels, SyckLevel, p->lvl_capa );\n    }\n\n    ASSERT( len > p->levels[p->lvl_idx-1].spaces );\n    p->levels[p->lvl_idx].spaces = len;\n    p->levels[p->lvl_idx].ncount = 0;\n    p->levels[p->lvl_idx].domain = syck_strndup( p->levels[p->lvl_idx-1].domain, strlen( p->levels[p->lvl_idx-1].domain ) );\n    p->levels[p->lvl_idx].status = status;\n    p->lvl_idx += 1;\n}\n\nvoid\nfree_any_io( SyckParser *p )\n{\n    ASSERT( p != NULL );\n    switch ( p->io_type )\n    {\n        case syck_io_str:\n            if ( p->io.str != NULL ) \n            {\n                S_FREE( p->io.str );\n                p->io.str = NULL;\n            }\n        break;\n\n        case syck_io_file:\n            if ( p->io.file != NULL ) \n            {\n                S_FREE( p->io.file );\n                p->io.file = NULL;\n            }\n        break;\n    }\n}\n\nlong\nsyck_move_tokens( SyckParser *p )\n{\n    long count, skip;\n    ASSERT( p->buffer != NULL );\n\n    if ( p->token == NULL )\n        return 0;\n\n    skip = p->limit - p->token;\n    if ( ( count = p->token - p->buffer ) )\n    {\n\tif (skip > 0)\n\t    S_MEMMOVE( p->buffer, p->token, char, skip );\n        p->token = p->buffer;\n        p->marker -= count;\n        p->cursor -= count;\n        p->toktmp -= count;\n        p->limit -= count;\n        p->lineptr -= count;\n        p->linectptr -= count;\n    }\n    return skip;\n}\n\nvoid\nsyck_check_limit( SyckParser *p, long len )\n{\n    if ( p->cursor == NULL )\n    {\n        p->cursor = p->buffer;\n        p->lineptr = p->buffer;\n        p->linectptr = p->buffer;\n        p->marker = p->buffer;\n    }\n    p->limit = p->buffer + len;\n}\n\nlong\nsyck_parser_read( SyckParser *p )\n{\n    long len = 0;\n    long skip = 0;\n    ASSERT( p != NULL );\n    switch ( p->io_type )\n    {\n        case syck_io_str:\n            skip = syck_move_tokens( p );\n            len = (p->io.str->read)( p->buffer, p->io.str, SYCK_BUFFERSIZE - 1, skip );\n            break;\n\n        case syck_io_file:\n            skip = syck_move_tokens( p );\n            len = (p->io.file->read)( p->buffer, p->io.file, SYCK_BUFFERSIZE - 1, skip );\n            break;\n    }\n    syck_check_limit( p, len );\n    return len;\n}\n\nlong\nsyck_parser_readlen( SyckParser *p, long max_size )\n{\n    long len = 0;\n    long skip = 0;\n    ASSERT( p != NULL );\n    switch ( p->io_type )\n    {\n        case syck_io_str:\n            skip = syck_move_tokens( p );\n            len = (p->io.str->read)( p->buffer, p->io.str, max_size, skip );\n            break;\n\n        case syck_io_file:\n            skip = syck_move_tokens( p );\n            len = (p->io.file->read)( p->buffer, p->io.file, max_size, skip );\n            break;\n    }\n    syck_check_limit( p, len );\n    return len;\n}\n\nSYMID\nsyck_parse( SyckParser *p )\n{\n    ASSERT( p != NULL );\n\n    syck_st_free( p );\n    syck_parser_reset_levels( p );\n    syckparse( p );\n    return p->root;\n}\n\nvoid\nsyck_default_error_handler( SyckParser *p, char *msg )\n{\n    printf( \"Error at [Line %d, Col %d]: %s\\n\", \n        p->linect,\n        p->cursor - p->lineptr,\n        msg );\n}\n\n"
  },
  {
    "path": "ext/syck/syck.h",
    "content": "/*\n * syck.h\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n\n#ifndef SYCK_H\n#define SYCK_H\n\n#define SYCK_YAML_MAJOR 1\n#define SYCK_YAML_MINOR 0\n\n#define SYCK_VERSION    \"0.60\"\n#define YAML_DOMAIN     \"yaml.org,2002\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <ctype.h>\n#include \"st.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n * Memory Allocation\n */\n#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)\n#include <alloca.h>\n#endif\n\n#if DEBUG\n  void syck_assert( char *, unsigned );\n# define ASSERT(f) \\\n    if ( f ) \\\n        {}   \\\n    else     \\\n        syck_assert( __FILE__, __LINE__ )\n#else\n# define ASSERT(f)\n#endif\n\n#ifndef NULL\n# define NULL (void *)0\n#endif\n\n#define ALLOC_CT 8\n#define SYCK_BUFFERSIZE 4096\n#define S_ALLOC_N(type,n) (type*)malloc(sizeof(type)*(n))\n#define S_ALLOC(type) (type*)malloc(sizeof(type))\n#define S_REALLOC_N(var,type,n) (var)=(type*)realloc((char*)(var),sizeof(type)*(n))\n#define S_FREE(n) if (n) { free(n); n = NULL; }\n\n#define S_ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n))\n\n#define S_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))\n#define S_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))\n#define S_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))\n#define S_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))\n\n#define BLOCK_FOLD  10\n#define BLOCK_LIT   20\n#define BLOCK_PLAIN 30\n#define NL_CHOMP    40\n#define NL_KEEP     50\n\n/*\n * Node definitions\n */\n#ifndef ST_DATA_T_DEFINED\ntypedef long st_data_t;\n#endif\n\n#define SYMID unsigned long\n\ntypedef struct _syck_node SyckNode;\n\nenum syck_kind_tag {\n    syck_map_kind,\n    syck_seq_kind,\n    syck_str_kind\n};\n\nenum map_part {\n    map_key,\n    map_value\n};\n\nenum map_style {\n    map_none,\n    map_inline\n};\n\nenum seq_style {\n    seq_none,\n    seq_inline\n};\n\nenum scalar_style {\n    scalar_none,\n    scalar_1quote,\n    scalar_2quote,\n    scalar_fold,\n    scalar_literal,\n    scalar_plain\n};\n\n/*\n * Node metadata struct\n */\nstruct _syck_node {\n    /* Symbol table ID */\n    SYMID id;\n    /* Underlying kind */\n    enum syck_kind_tag kind;\n    /* Fully qualified tag-uri for type */\n    char *type_id;\n    /* Anchor name */\n    char *anchor;\n    union {\n        /* Storage for map data */\n        struct SyckMap {\n            enum map_style style;\n            SYMID *keys;\n            SYMID *values;\n            long capa;\n            long idx;\n        } *pairs;\n        /* Storage for sequence data */\n        struct SyckSeq {\n            enum seq_style style;\n            SYMID *items;\n            long capa;\n            long idx;\n        } *list;\n        /* Storage for string data */\n        struct SyckStr {\n            enum scalar_style style;\n            char *ptr;\n            long len;\n        } *str;\n    } data;\n    /* Shortcut node */\n    void *shortcut;\n};\n\n/*\n * Parser definitions\n */\ntypedef struct _syck_parser SyckParser;\ntypedef struct _syck_file SyckIoFile;\ntypedef struct _syck_str SyckIoStr;\ntypedef struct _syck_level SyckLevel;\n\ntypedef SYMID (*SyckNodeHandler)(SyckParser *, SyckNode *);\ntypedef void (*SyckErrorHandler)(SyckParser *, char *);\ntypedef SyckNode * (*SyckBadAnchorHandler)(SyckParser *, char *);\ntypedef long (*SyckIoFileRead)(char *, SyckIoFile *, long, long); \ntypedef long (*SyckIoStrRead)(char *, SyckIoStr *, long, long);\n\nenum syck_io_type {\n    syck_io_str,\n    syck_io_file\n};\n\nenum syck_parser_input {\n    syck_yaml_utf8,\n    syck_yaml_utf16,\n    syck_yaml_utf32,\n    syck_bytecode_utf8\n};\n\nenum syck_level_status {\n    syck_lvl_header,\n    syck_lvl_doc,\n    syck_lvl_open,\n    syck_lvl_seq,\n    syck_lvl_map,\n    syck_lvl_block,\n    syck_lvl_str,\n    syck_lvl_iseq,\n    syck_lvl_imap,\n    syck_lvl_end,\n    syck_lvl_pause,\n    syck_lvl_anctag,\n    syck_lvl_mapx,\n    syck_lvl_seqx\n};\n\n/*\n * Parser structs\n */\nstruct _syck_file {\n    /* File pointer */\n    FILE *ptr;\n    /* Function which FILE -> buffer */\n    SyckIoFileRead read;\n};\n\nstruct _syck_str {\n    /* String buffer pointers */\n    char *beg, *ptr, *end;\n    /* Function which string -> buffer */\n    SyckIoStrRead read;\n};\n\nstruct _syck_level {\n    /* Indent */\n    int spaces;\n    /* Counts nodes emitted at this level, useful for parsing \n     * keys and pairs in bytecode */\n    int ncount;\n    /* Does node have anchors or tags? */\n    int anctag;\n    /* Domain prefixing at the given level */\n    char *domain;\n    /* Keeps a node status */\n    enum syck_level_status status;\n};\n\nstruct _syck_parser {\n    /* Root node */\n    SYMID root, root_on_error;\n    /* Implicit typing flag */\n    int implicit_typing, taguri_expansion;\n    /* Scripting language function to handle nodes */\n    SyckNodeHandler handler;\n    /* Error handler */\n    SyckErrorHandler error_handler;\n    /* InvalidAnchor handler */\n    SyckBadAnchorHandler bad_anchor_handler;\n    /* Parser input type */\n    enum syck_parser_input input_type;\n    /* IO type */\n    enum syck_io_type io_type;\n    /* Custom buffer size */\n    size_t bufsize;\n    /* Buffer pointers */\n    char *buffer, *linectptr, *lineptr, *toktmp, *token, *cursor, *marker, *limit;\n    /* Line counter */\n    int linect;\n    /* Last token from yylex() */\n    int last_token;\n    /* Force a token upon next call to yylex() */\n    int force_token;\n    /* EOF flag */\n    int eof;\n    union {\n        SyckIoFile *file;\n        SyckIoStr *str;\n    } io;\n    /* Symbol table for anchors */\n    st_table *anchors, *bad_anchors;\n    /* Optional symbol table for SYMIDs */\n    st_table *syms;\n    /* Levels of indentation */\n    SyckLevel *levels;\n    int lvl_idx;\n    int lvl_capa;\n    /* Pointer for extension's use */\n    void *bonus;\n};\n\n/*\n * Emitter definitions\n */\ntypedef struct _syck_emitter SyckEmitter;\ntypedef struct _syck_emitter_node SyckEmitterNode;\n\ntypedef void (*SyckOutputHandler)(SyckEmitter *, char *, long); \ntypedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t); \n\nenum doc_stage {\n    doc_open,\n    doc_processing\n};\n\n/*\n * Emitter struct\n */\nstruct _syck_emitter {\n    /* Headerless doc flag */\n    int headless;\n    /* Force header? */\n    int use_header;\n    /* Force version? */\n    int use_version;\n    /* Sort hash keys */\n    int sort_keys;\n    /* Anchor format */\n    char *anchor_format;\n    /* Explicit typing on all collections? */\n    int explicit_typing;\n    /* Best width on folded scalars */\n    int best_width;\n    /* Use literal[1] or folded[2] blocks on all text? */\n    enum scalar_style style;\n    /* Stage of written document */\n    enum doc_stage stage;\n    /* Level counter */\n    int level;\n    /* Default indentation */\n    int indent;\n    /* Object ignore ID */\n    SYMID ignore_id;\n    /* Symbol table for anchors */\n    st_table *markers, *anchors, *anchored;\n    /* Custom buffer size */\n    size_t bufsize;\n    /* Buffer */\n    char *buffer, *marker;\n    /* Absolute position of the buffer */\n    long bufpos;\n    /* Handler for emitter nodes */\n    SyckEmitterHandler emitter_handler;\n    /* Handler for output */\n    SyckOutputHandler output_handler;\n    /* Levels of indentation */\n    SyckLevel *levels;\n    int lvl_idx;\n    int lvl_capa;\n    /* Pointer for extension's use */\n    void *bonus;\n};\n\n/*\n * Emitter node metadata struct\n */\nstruct _syck_emitter_node {\n    /* Node buffer position */\n    long pos;\n    /* Current indent */\n    long indent;\n    /* Collection? */\n    int is_shortcut;\n};\n\n/*\n * Handler prototypes\n */\nSYMID syck_hdlr_add_node( SyckParser *, SyckNode * );\nSyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * );\nvoid syck_hdlr_remove_anchor( SyckParser *, char * );\nSyckNode *syck_hdlr_get_anchor( SyckParser *, char * );\nvoid syck_add_transfer( char *, SyckNode *, int );\nchar *syck_xprivate( char *, int );\nchar *syck_taguri( char *, char *, int );\nint syck_tagcmp( char *, char * );\nint syck_add_sym( SyckParser *, char * );\nint syck_lookup_sym( SyckParser *, SYMID, char ** );\nint syck_try_implicit( SyckNode * );\nchar *syck_type_id_to_uri( char * );\nvoid try_tag_implicit( SyckNode *, int );\nchar *syck_match_implicit( char *, size_t );\n\n/*\n * API prototypes\n */\nchar *syck_strndup( char *, long );\nlong syck_io_file_read( char *, SyckIoFile *, long, long );\nlong syck_io_str_read( char *, SyckIoStr *, long, long );\nchar *syck_base64enc( char *, long );\nchar *syck_base64dec( char *, long );\nSyckEmitter *syck_new_emitter();\nSYMID syck_emitter_mark_node( SyckEmitter *, st_data_t );\nvoid syck_emitter_ignore_id( SyckEmitter *, SYMID );\nvoid syck_output_handler( SyckEmitter *, SyckOutputHandler );\nvoid syck_emitter_handler( SyckEmitter *, SyckEmitterHandler );\nvoid syck_free_emitter( SyckEmitter * );\nvoid syck_emitter_clear( SyckEmitter * );\nvoid syck_emitter_write( SyckEmitter *, char *, long );\nvoid syck_emitter_escape( SyckEmitter *, char *, long );\nvoid syck_emitter_flush( SyckEmitter *, long );\nvoid syck_emit( SyckEmitter *, st_data_t );\nvoid syck_emit_scalar( SyckEmitter *, char *, enum scalar_style, int, int, char, char *, long );\nvoid syck_emit_1quoted( SyckEmitter *, int, char *, long );\nvoid syck_emit_2quoted( SyckEmitter *, int, char *, long );\nvoid syck_emit_folded( SyckEmitter *, int, char, char *, long );\nvoid syck_emit_literal( SyckEmitter *, char, char *, long );\nvoid syck_emit_seq( SyckEmitter *, char *, enum seq_style );\nvoid syck_emit_item( SyckEmitter *, st_data_t );\nvoid syck_emit_map( SyckEmitter *, char *, enum map_style );\nvoid syck_emit_end( SyckEmitter * );\nvoid syck_emit_tag( SyckEmitter *, char *, char * );\nvoid syck_emit_indent( SyckEmitter * );\nSyckLevel *syck_emitter_current_level( SyckEmitter * );\nSyckLevel *syck_emitter_parent_level( SyckEmitter * );\nvoid syck_emitter_pop_level( SyckEmitter * );\nvoid syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status );\nvoid syck_emitter_reset_levels( SyckEmitter * );\nSyckParser *syck_new_parser();\nvoid syck_free_parser( SyckParser * );\nvoid syck_parser_set_root_on_error( SyckParser *, SYMID );\nvoid syck_parser_implicit_typing( SyckParser *, int );\nvoid syck_parser_taguri_expansion( SyckParser *, int );\nint syck_scan_scalar( int, char *, long );\nvoid syck_parser_handler( SyckParser *, SyckNodeHandler );\nvoid syck_parser_error_handler( SyckParser *, SyckErrorHandler );\nvoid syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler );\nvoid syck_parser_set_input_type( SyckParser *, enum syck_parser_input );\nvoid syck_parser_file( SyckParser *, FILE *, SyckIoFileRead );\nvoid syck_parser_str( SyckParser *, char *, long, SyckIoStrRead );\nvoid syck_parser_str_auto( SyckParser *, char *, SyckIoStrRead );\nSyckLevel *syck_parser_current_level( SyckParser * );\nvoid syck_parser_add_level( SyckParser *, int, enum syck_level_status );\nvoid syck_parser_pop_level( SyckParser * );\nvoid free_any_io( SyckParser * );\nlong syck_parser_read( SyckParser * );\nlong syck_parser_readlen( SyckParser *, long );\nSYMID syck_parse( SyckParser * );\nvoid syck_default_error_handler( SyckParser *, char * );\nSYMID syck_yaml2byte_handler( SyckParser *, SyckNode * );\nchar *syck_yaml2byte( char * );\n\n/*\n * Allocation prototypes\n */\nSyckNode *syck_alloc_map();\nSyckNode *syck_alloc_seq();\nSyckNode *syck_alloc_str();\nvoid syck_free_node( SyckNode * );\nvoid syck_free_members( SyckNode * );\nSyckNode *syck_new_str( char *, enum scalar_style );\nSyckNode *syck_new_str2( char *, long, enum scalar_style );\nvoid syck_replace_str( SyckNode *, char *, enum scalar_style );\nvoid syck_replace_str2( SyckNode *, char *, long, enum scalar_style );\nvoid syck_str_blow_away_commas( SyckNode * );\nchar *syck_str_read( SyckNode * );\nSyckNode *syck_new_map( SYMID, SYMID );\nvoid syck_map_empty( SyckNode * );\nvoid syck_map_add( SyckNode *, SYMID, SYMID );\nSYMID syck_map_read( SyckNode *, enum map_part, long );\nvoid syck_map_assign( SyckNode *, enum map_part, long, SYMID );\nlong syck_map_count( SyckNode * );\nvoid syck_map_update( SyckNode *, SyckNode * );\nSyckNode *syck_new_seq( SYMID );\nvoid syck_seq_empty( SyckNode * );\nvoid syck_seq_add( SyckNode *, SYMID );\nvoid syck_seq_assign( SyckNode *, long, SYMID );\nSYMID syck_seq_read( SyckNode *, long );\nlong syck_seq_count( SyckNode * );\n\n/*\n * Lexer prototypes\n */\nvoid syckerror( char * );\nint syckparse( void * );\nunion YYSTYPE;\nint sycklex( union YYSTYPE *, SyckParser * );\n\n#if defined(__cplusplus)\n}  /* extern \"C\" { */\n#endif\n\n#endif /* ifndef SYCK_H */\n"
  },
  {
    "path": "ext/syck/token.c",
    "content": "/* Generated by re2c 0.9.10 on Tue Sep 20 17:46:17 2005 */\n#line 1 \"token.re\"\n/*\n * token.re\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff\n */\n#include \"ruby.h\"\n#include \"syck.h\"\n#include \"gram.h\"\n\n/*\n * Allocate quoted strings in chunks\n */\n#define QUOTELEN    1024\n\n/*\n * They do my bidding...\n */\n#define YYCTYPE     char\n#define YYCURSOR    parser->cursor\n#define YYMARKER    parser->marker\n#define YYLIMIT     parser->limit\n#define YYTOKEN     parser->token\n#define YYTOKTMP    parser->toktmp\n#define YYLINEPTR   parser->lineptr\n#define YYLINECTPTR parser->linectptr\n#define YYLINE      parser->linect\n#define YYFILL(n)   syck_parser_read(parser)\n\n/*\n * Repositions the cursor at `n' offset from the token start.\n * Only works in `Header' and `Document' sections.\n */\n#define YYPOS(n)    YYCURSOR = YYTOKEN + n\n\n/*\n * Track line numbers\n */\n#define NEWLINE(ptr)    YYLINEPTR = ptr + newline_len(ptr); if ( YYLINEPTR > YYLINECTPTR ) { YYLINE++; YYLINECTPTR = YYLINEPTR; }\n\n/*\n * I like seeing the level operations as macros...\n */\n#define ADD_LEVEL(len, status)  syck_parser_add_level( parser, len, status )\n#define POP_LEVEL()     syck_parser_pop_level( parser )\n#define CURRENT_LEVEL() syck_parser_current_level( parser )\n\n/*\n * Force a token next time around sycklex()\n */\n#define FORCE_NEXT_TOKEN(tok)    parser->force_token = tok;\n\n/*\n * Nice little macro to ensure we're YAML_IOPENed to the current level.\n * * Only use this macro in the \"Document\" section *\n */\n#define ENSURE_YAML_IOPEN(last_lvl, to_len, reset) \\\n        if ( last_lvl->spaces < to_len ) \\\n        { \\\n            if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \\\n            { \\\n                goto Document; \\\n            } \\\n            else \\\n            { \\\n                ADD_LEVEL( to_len, syck_lvl_doc ); \\\n                if ( reset == 1 ) YYPOS(0); \\\n                return YAML_IOPEN; \\\n            } \\\n        } \n\n/*\n * Nice little macro to ensure closure of levels.\n * * Only use this macro in the \"Document\" section *\n */\n#define ENSURE_YAML_IEND(last_lvl, to_len) \\\n        if ( last_lvl->spaces > to_len ) \\\n        { \\\n            syck_parser_pop_level( parser ); \\\n            YYPOS(0); \\\n            return YAML_IEND; \\\n        }\n\n/*\n * Concatenates quoted string items and manages allocation\n * to the quoted string\n */\n#define QUOTECAT(s, c, i, l) \\\n        { \\\n            if ( i + 1 >= c ) \\\n            { \\\n                c += QUOTELEN; \\\n                S_REALLOC_N( s, char, c ); \\\n            } \\\n            s[i++] = l; \\\n            s[i] = '\\0'; \\\n        }\n\n#define QUOTECATS(s, c, i, cs, cl) \\\n        { \\\n            while ( i + cl >= c ) \\\n            { \\\n                c += QUOTELEN; \\\n                S_REALLOC_N( s, char, c ); \\\n            } \\\n            S_MEMCPY( s + i, cs, char, cl ); \\\n            i += cl; \\\n            s[i] = '\\0'; \\\n        }\n\n/*\n * Tags a plain scalar with a transfer method\n * * Use only in \"Plain\" section *\n */\n#define RETURN_IMPLICIT() \\\n    { \\\n        SyckNode *n = syck_alloc_str(); \\\n        YYCURSOR = YYTOKEN; \\\n        n->data.str->ptr = qstr; \\\n        n->data.str->len = qidx; \\\n        n->data.str->style = scalar_plain; \\\n        sycklval->nodeData = n; \\\n        if ( parser->implicit_typing == 1 ) \\\n        { \\\n            try_tag_implicit( sycklval->nodeData, parser->taguri_expansion ); \\\n        } \\\n        return YAML_PLAIN; \\\n    }\n\n/* concat the inline characters to the plain scalar */\n#define PLAIN_NOT_INL() \\\n    if ( *(YYCURSOR - 1) == ' ' || is_newline( YYCURSOR - 1 ) ) \\\n    { \\\n        YYCURSOR--; \\\n    } \\\n    QUOTECATS(qstr, qcapa, qidx, YYTOKEN, YYCURSOR - YYTOKEN); \\\n    goto Plain2;\n\n/* trim spaces off the end in case of indent */\n#define PLAIN_IS_INL() \\\n    char *walker = qstr + qidx - 1; \\\n    while ( walker > qstr && ( *walker == '\\n' || *walker == ' ' || *walker == '\\t' ) ) \\\n    { \\\n        qidx--; \\\n        walker[0] = '\\0'; \\\n        walker--; \\\n    }\n\n/*\n * Keep or chomp block?\n * * Use only in \"ScalarBlock\" section *\n */\n#define RETURN_YAML_BLOCK() \\\n    { \\\n        SyckNode *n = syck_alloc_str(); \\\n        if ( ((SyckParser *)parser)->taguri_expansion == 1 ) \\\n        { \\\n            n->type_id = syck_taguri( YAML_DOMAIN, \"str\", 3 ); \\\n        } \\\n        else \\\n        { \\\n            n->type_id = syck_strndup( \"str\", 3 ); \\\n        } \\\n        n->data.str->ptr = qstr; \\\n        n->data.str->len = qidx; \\\n        if ( blockType == BLOCK_LIT ) { \\\n            n->data.str->style = scalar_literal; \\\n        } else { \\\n            n->data.str->style = scalar_fold; \\\n        } \\\n        if ( qidx > 0 ) \\\n        { \\\n            if ( nlDoWhat != NL_KEEP ) \\\n            { \\\n                char *fc = n->data.str->ptr + n->data.str->len - 1; \\\n                while ( is_newline( fc ) ) fc--; \\\n                if ( nlDoWhat != NL_CHOMP && fc < n->data.str->ptr + n->data.str->len - 1 ) \\\n                    fc += 1; \\\n                n->data.str->len = fc - n->data.str->ptr + 1; \\\n            } \\\n        } \\\n        sycklval->nodeData = n; \\\n        return YAML_BLOCK; \\\n    }\n\n/*\n * Handles newlines, calculates indent\n */\n#define GOBBLE_UP_YAML_INDENT( ict, start ) \\\n    char *indent = start; \\\n    NEWLINE(indent); \\\n    while ( indent < YYCURSOR ) \\\n    { \\\n        if ( is_newline( ++indent ) ) \\\n        { \\\n            NEWLINE(indent); \\\n        } \\\n    } \\\n    ict = 0; \\\n    if ( *YYCURSOR == '\\0' ) \\\n    { \\\n        ict = -1; \\\n        start = YYCURSOR - 1; \\\n    } \\\n    else if ( *YYLINEPTR == ' ' ) \\\n    { \\\n        ict = YYCURSOR - YYLINEPTR; \\\n    }\n\n/*\n * If an indent exists at the current level, back up.\n */\n#define GET_TRUE_YAML_INDENT(indt_len) \\\n    { \\\n        SyckLevel *lvl_deep = CURRENT_LEVEL(); \\\n        indt_len = lvl_deep->spaces; \\\n        if ( lvl_deep->status == syck_lvl_seq || ( indt_len == YYCURSOR - YYLINEPTR && lvl_deep->status != syck_lvl_map )  ) \\\n        { \\\n            SyckLevel *lvl_over; \\\n            parser->lvl_idx--; \\\n            lvl_over = CURRENT_LEVEL(); \\\n            indt_len = lvl_over->spaces; \\\n            parser->lvl_idx++; \\\n        } \\\n    }\n\n/*\n * Argjh!  I hate globals!  Here for syckerror() only!\n */\nSyckParser *syck_parser_ptr = NULL;\n\n/*\n * Accessory funcs later in this file.\n */\nvoid eat_comments( SyckParser * );\nchar escape_seq( char );\nint is_newline( char *ptr );\nint newline_len( char *ptr );\nint sycklex_yaml_utf8( YYSTYPE *, SyckParser * );\nint sycklex_bytecode_utf8( YYSTYPE *, SyckParser * );\nint syckwrap();\n\n/*\n * My own re-entrant sycklex() using re2c.\n * You really get used to the limited regexp.\n * It's really nice to not rely on backtracking and such.\n */\nint\nsycklex( YYSTYPE *sycklval, SyckParser *parser )\n{\n    switch ( parser->input_type )\n    {\n        case syck_yaml_utf8:\n        return sycklex_yaml_utf8( sycklval, parser );\n\n        case syck_yaml_utf16:\n            syckerror( \"UTF-16 is not currently supported in Syck.\\nPlease contribute code to help this happen!\" );\n        break;\n\n        case syck_yaml_utf32:\n            syckerror( \"UTF-32 is not currently supported in Syck.\\nPlease contribute code to help this happen!\" );\n        break;\n\n        case syck_bytecode_utf8:\n        return sycklex_bytecode_utf8( sycklval, parser );\n    }\n    return YAML_DOCSEP;\n}\n\n/*\n * Parser for standard YAML [UTF-8]\n */\nint\nsycklex_yaml_utf8( YYSTYPE *sycklval, SyckParser *parser )\n{\n    int doc_level = 0;\n    syck_parser_ptr = parser;\n    if ( YYCURSOR == NULL ) \n    {\n        syck_parser_read( parser );\n    }\n\n    if ( parser->force_token != 0 )\n    {\n        int t = parser->force_token;\n        parser->force_token = 0;\n        return t;\n    }\n\n#line 315 \"token.re\"\n\n\n    if ( YYLINEPTR != YYCURSOR )\n    {\n        goto Document;\n    }\n\nHeader:\n\n    YYTOKEN = YYCURSOR;\n\n\n#line 307 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy0;\n\t++YYCURSOR;\nyy0:\n\tif((YYLIMIT - YYCURSOR) < 5) YYFILL(5);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy7;\n\tcase 0x09:\tcase ' ':\tgoto yy12;\n\tcase 0x0A:\tgoto yy9;\n\tcase 0x0D:\tgoto yy11;\n\tcase '#':\tgoto yy5;\n\tcase '-':\tgoto yy2;\n\tcase '.':\tgoto yy4;\n\tdefault:\tgoto yy14;\n\t}\nyy2:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '-':\tgoto yy28;\n\tdefault:\tgoto yy3;\n\t}\nyy3:\n#line 374 \"token.re\"\n{   YYPOS(0);\n                        goto Document; \n                    }\n#line 337 \"<stdout>\"\nyy4:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '.':\tgoto yy21;\n\tdefault:\tgoto yy3;\n\t}\nyy5:\t++YYCURSOR;\n\tgoto yy6;\nyy6:\n#line 356 \"token.re\"\n{   eat_comments( parser ); \n                        goto Header;\n                    }\n#line 351 \"<stdout>\"\nyy7:\t++YYCURSOR;\n\tgoto yy8;\nyy8:\n#line 360 \"token.re\"\n{   SyckLevel *lvl = CURRENT_LEVEL();\n                        ENSURE_YAML_IEND(lvl, -1);\n                        YYPOS(0);\n                        return 0; \n                    }\n#line 361 \"<stdout>\"\nyy9:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy18;\nyy10:\n#line 366 \"token.re\"\n{   GOBBLE_UP_YAML_INDENT( doc_level, YYTOKEN );\n                        goto Header; \n                    }\n#line 370 \"<stdout>\"\nyy11:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy17;\n\tdefault:\tgoto yy3;\n\t}\nyy12:\t++YYCURSOR;\n\tyych = *YYCURSOR;\n\tgoto yy16;\nyy13:\n#line 370 \"token.re\"\n{   doc_level = YYCURSOR - YYLINEPTR;\n                        goto Header;\n                    }\n#line 384 \"<stdout>\"\nyy14:\tyych = *++YYCURSOR;\n\tgoto yy3;\nyy15:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy16;\nyy16:\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy15;\n\tdefault:\tgoto yy13;\n\t}\nyy17:\tyyaccept = 1;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy18;\nyy18:\tswitch(yych){\n\tcase 0x0A:\tcase ' ':\tgoto yy17;\n\tcase 0x0D:\tgoto yy19;\n\tdefault:\tgoto yy10;\n\t}\nyy19:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy17;\n\tdefault:\tgoto yy20;\n\t}\nyy20:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 1:\tgoto yy10;\n\tcase 0:\tgoto yy3;\n\t}\nyy21:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '.':\tgoto yy22;\n\tdefault:\tgoto yy20;\n\t}\nyy22:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy23;\n\tcase 0x0D:\tgoto yy27;\n\tcase ' ':\tgoto yy25;\n\tdefault:\tgoto yy20;\n\t}\nyy23:\t++YYCURSOR;\n\tgoto yy24;\nyy24:\n#line 342 \"token.re\"\n{   SyckLevel *lvl = CURRENT_LEVEL();\n                        if ( lvl->status == syck_lvl_header )\n                        {\n                            goto Header; \n                        }\n                        else\n                        {\n                            ENSURE_YAML_IEND(lvl, -1);\n                            YYPOS(0);\n                            return 0; \n                        }\n                        return 0; \n                    }\n#line 446 \"<stdout>\"\nyy25:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy26;\nyy26:\tswitch(yych){\n\tcase ' ':\tgoto yy25;\n\tdefault:\tgoto yy24;\n\t}\nyy27:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy23;\n\tdefault:\tgoto yy20;\n\t}\nyy28:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy29;\n\tdefault:\tgoto yy20;\n\t}\nyy29:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy30;\n\tcase 0x0D:\tgoto yy34;\n\tcase ' ':\tgoto yy32;\n\tdefault:\tgoto yy20;\n\t}\nyy30:\t++YYCURSOR;\n\tgoto yy31;\nyy31:\n#line 328 \"token.re\"\n{   SyckLevel *lvl = CURRENT_LEVEL();\n                        if ( lvl->status == syck_lvl_header )\n                        {\n                            YYPOS(3);\n                            goto Directive; \n                        }\n                        else\n                        {\n                            ENSURE_YAML_IEND(lvl, -1);\n                            YYPOS(0);\n                            return 0; \n                        }\n                    }\n#line 489 \"<stdout>\"\nyy32:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy33;\nyy33:\tswitch(yych){\n\tcase ' ':\tgoto yy32;\n\tdefault:\tgoto yy31;\n\t}\nyy34:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy30;\n\tdefault:\tgoto yy20;\n\t}\n}\n#line 378 \"token.re\"\n\n\nDocument:\n    {\n        SyckLevel *lvl = CURRENT_LEVEL();\n        if ( lvl->status == syck_lvl_header )\n        {\n            lvl->status = syck_lvl_doc;\n        }\n\n        YYTOKEN = YYCURSOR;\n\n\n#line 518 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy35;\n\t++YYCURSOR;\nyy35:\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy62;\n\tcase 0x09:\tcase ' ':\tgoto yy60;\n\tcase 0x0A:\tgoto yy37;\n\tcase 0x0D:\tgoto yy39;\n\tcase '!':\tgoto yy51;\n\tcase '\"':\tgoto yy55;\n\tcase '#':\tgoto yy58;\n\tcase '&':\tgoto yy49;\n\tcase '\\'':\tgoto yy53;\n\tcase '*':\tgoto yy50;\n\tcase ',':\tcase ':':\tgoto yy47;\n\tcase '-':\tcase '?':\tgoto yy48;\n\tcase '>':\tcase '|':\tgoto yy57;\n\tcase '[':\tgoto yy41;\n\tcase ']':\tcase '}':\tgoto yy45;\n\tcase '{':\tgoto yy43;\n\tdefault:\tgoto yy64;\n\t}\nyy37:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy92;\nyy38:\n#line 392 \"token.re\"\n{   /* Isolate spaces */\n                        int indt_len;\n                        GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN );\n                        lvl = CURRENT_LEVEL();\n                        doc_level = 0;\n\n                        /* XXX: Comment lookahead */\n                        if ( *YYCURSOR == '#' )\n                        {\n                            goto Document;\n                        }\n\n                        /* Ignore indentation inside inlines */\n                        if ( lvl->status == syck_lvl_iseq || lvl->status == syck_lvl_imap )\n                        {\n                            goto Document;\n                        }\n\n                        /* Check for open indent */\n                        ENSURE_YAML_IEND(lvl, indt_len);\n                        ENSURE_YAML_IOPEN(lvl, indt_len, 0);\n                        if ( indt_len == -1 )\n                        {\n                            return 0;\n                        }\n                        return YAML_INDENT;\n                    }\n#line 578 \"<stdout>\"\nyy39:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy91;\n\tdefault:\tgoto yy40;\n\t}\nyy40:\n#line 497 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, doc_level, 1);\n                        goto Plain; \n                    }\n#line 589 \"<stdout>\"\nyy41:\t++YYCURSOR;\n\tgoto yy42;\nyy42:\n#line 420 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, doc_level, 1);\n                        lvl = CURRENT_LEVEL();\n                        ADD_LEVEL(lvl->spaces + 1, syck_lvl_iseq);\n                        return YYTOKEN[0]; \n                    }\n#line 599 \"<stdout>\"\nyy43:\t++YYCURSOR;\n\tgoto yy44;\nyy44:\n#line 426 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, doc_level, 1);\n                        lvl = CURRENT_LEVEL();\n                        ADD_LEVEL(lvl->spaces + 1, syck_lvl_imap);\n                        return YYTOKEN[0]; \n                    }\n#line 609 \"<stdout>\"\nyy45:\t++YYCURSOR;\n\tgoto yy46;\nyy46:\n#line 432 \"token.re\"\n{   POP_LEVEL();\n                        return YYTOKEN[0]; \n                    }\n#line 617 \"<stdout>\"\nyy47:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy86;\n\tcase 0x0D:\tgoto yy90;\n\tcase ' ':\tgoto yy88;\n\tdefault:\tgoto yy40;\n\t}\nyy48:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy81;\n\tcase 0x0D:\tgoto yy85;\n\tcase ' ':\tgoto yy83;\n\tdefault:\tgoto yy40;\n\t}\nyy49:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy78;\n\tdefault:\tgoto yy40;\n\t}\nyy50:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy75;\n\tdefault:\tgoto yy40;\n\t}\nyy51:\t++YYCURSOR;\n\tgoto yy52;\nyy52:\n#line 471 \"token.re\"\n{   goto TransferMethod; }\n#line 767 \"<stdout>\"\nyy53:\t++YYCURSOR;\n\tgoto yy54;\nyy54:\n#line 473 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, doc_level, 1);\n                        goto SingleQuote; }\n#line 774 \"<stdout>\"\nyy55:\t++YYCURSOR;\n\tgoto yy56;\nyy56:\n#line 476 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, doc_level, 1);\n                        goto DoubleQuote; }\n#line 781 \"<stdout>\"\nyy57:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy70;\n\tcase 0x0D:\tgoto yy74;\n\tcase ' ':\tgoto yy72;\n\tcase '+':\tcase '-':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy67;\n\tdefault:\tgoto yy40;\n\t}\nyy58:\t++YYCURSOR;\n\tgoto yy59;\nyy59:\n#line 486 \"token.re\"\n{   eat_comments( parser ); \n                        goto Document;\n                    }\n#line 807 \"<stdout>\"\nyy60:\t++YYCURSOR;\n\tyych = *YYCURSOR;\n\tgoto yy66;\nyy61:\n#line 490 \"token.re\"\n{   goto Document; }\n#line 814 \"<stdout>\"\nyy62:\t++YYCURSOR;\n\tgoto yy63;\nyy63:\n#line 492 \"token.re\"\n{   ENSURE_YAML_IEND(lvl, -1);\n                        YYPOS(0);\n                        return 0; \n                    }\n#line 823 \"<stdout>\"\nyy64:\tyych = *++YYCURSOR;\n\tgoto yy40;\nyy65:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy66;\nyy66:\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy65;\n\tdefault:\tgoto yy61;\n\t}\nyy67:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy68;\nyy68:\tswitch(yych){\n\tcase 0x0A:\tgoto yy70;\n\tcase 0x0D:\tgoto yy74;\n\tcase ' ':\tgoto yy72;\n\tcase '+':\tcase '-':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tgoto yy67;\n\tdefault:\tgoto yy69;\n\t}\nyy69:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy38;\n\tcase 1:\tgoto yy40;\n\t}\nyy70:\t++YYCURSOR;\n\tgoto yy71;\nyy71:\n#line 479 \"token.re\"\n{   if ( is_newline( YYCURSOR - 1 ) ) \n                        {\n                            YYCURSOR--;\n                        }\n                        goto ScalarBlock; \n                    }\n#line 869 \"<stdout>\"\nyy72:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy73;\nyy73:\tswitch(yych){\n\tcase ' ':\tgoto yy72;\n\tdefault:\tgoto yy71;\n\t}\nyy74:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy70;\n\tdefault:\tgoto yy69;\n\t}\nyy75:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy76;\nyy76:\tswitch(yych){\n\tcase '-':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy75;\n\tdefault:\tgoto yy77;\n\t}\nyy77:\n#line 466 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, doc_level, 1);\n                        sycklval->name = syck_strndup( YYTOKEN + 1, YYCURSOR - YYTOKEN - 1 );\n                        return YAML_ALIAS;\n                    }\n#line 956 \"<stdout>\"\nyy78:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy79;\nyy79:\tswitch(yych){\n\tcase '-':\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy78;\n\tdefault:\tgoto yy80;\n\t}\nyy80:\n#line 455 \"token.re\"\n{   sycklval->name = syck_strndup( YYTOKEN + 1, YYCURSOR - YYTOKEN - 1 );\n\n                        /*\n                         * Remove previous anchors of the same name.  Since the parser will likely\n                         * construct deeper nodes first, we want those nodes to be placed in the\n                         * queue for matching at a higher level of indentation.\n                         */\n                        syck_hdlr_remove_anchor(parser, sycklval->name);\n                        return YAML_ANCHOR;\n                    }\n#line 1036 \"<stdout>\"\nyy81:\t++YYCURSOR;\n\tgoto yy82;\nyy82:\n#line 441 \"token.re\"\n{   ENSURE_YAML_IOPEN(lvl, YYTOKEN - YYLINEPTR, 1);\n                        FORCE_NEXT_TOKEN(YAML_IOPEN);\n                        if ( *YYCURSOR == '#' || is_newline( YYCURSOR ) || is_newline( YYCURSOR - 1 ) )\n                        {\n                            YYCURSOR--; \n                            ADD_LEVEL((YYTOKEN + 1) - YYLINEPTR, syck_lvl_seq);\n                        }\n                        else /* spaces followed by content uses the space as indentation */\n                        {\n                            ADD_LEVEL(YYCURSOR - YYLINEPTR, syck_lvl_seq);\n                        }\n                        return YYTOKEN[0]; \n                    }\n#line 1054 \"<stdout>\"\nyy83:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy84;\nyy84:\tswitch(yych){\n\tcase ' ':\tgoto yy83;\n\tdefault:\tgoto yy82;\n\t}\nyy85:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy81;\n\tdefault:\tgoto yy69;\n\t}\nyy86:\t++YYCURSOR;\n\tgoto yy87;\nyy87:\n#line 436 \"token.re\"\n{   if ( *YYTOKEN == ':' && lvl->status != syck_lvl_imap ) lvl->status = syck_lvl_map;\n                        YYPOS(1); \n                        return YYTOKEN[0]; \n                    }\n#line 1076 \"<stdout>\"\nyy88:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy89;\nyy89:\tswitch(yych){\n\tcase ' ':\tgoto yy88;\n\tdefault:\tgoto yy87;\n\t}\nyy90:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy86;\n\tdefault:\tgoto yy69;\n\t}\nyy91:\tyyaccept = 0;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy92;\nyy92:\tswitch(yych){\n\tcase 0x0A:\tcase ' ':\tgoto yy91;\n\tcase 0x0D:\tgoto yy93;\n\tdefault:\tgoto yy38;\n\t}\nyy93:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy91;\n\tdefault:\tgoto yy69;\n\t}\n}\n#line 501 \"token.re\"\n\n    }\n\nDirective:\n    {\n        YYTOKTMP = YYCURSOR;\n\n\n#line 1117 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy94;\n\t++YYCURSOR;\nyy94:\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy96;\n\tcase 0x09:\tcase ' ':\tgoto yy99;\n\tcase '%':\tgoto yy97;\n\tdefault:\tgoto yy101;\n\t}\nyy96:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy98;\n\t}\nyy97:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy104;\n\tdefault:\tgoto yy98;\n\t}\nyy98:\n#line 514 \"token.re\"\n{   YYCURSOR = YYTOKTMP;\n                        return YAML_DOCSEP;\n                    }\n#line 1221 \"<stdout>\"\nyy99:\t++YYCURSOR;\n\tyych = *YYCURSOR;\n\tgoto yy103;\nyy100:\n#line 512 \"token.re\"\n{   goto Directive; }\n#line 1228 \"<stdout>\"\nyy101:\tyych = *++YYCURSOR;\n\tgoto yy98;\nyy102:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy103;\nyy103:\tswitch(yych){\n\tcase 0x09:\tcase ' ':\tgoto yy102;\n\tdefault:\tgoto yy100;\n\t}\nyy104:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy105;\nyy105:\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy104;\n\tcase ':':\tgoto yy106;\n\tdefault:\tgoto yy96;\n\t}\nyy106:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy107;\n\tdefault:\tgoto yy96;\n\t}\nyy107:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy108;\nyy108:\tswitch(yych){\n\tcase '.':\n\tcase '/':\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\n\tcase ':':\n\tcase ';':\n\tcase '<':\n\tcase '=':\n\tcase '>':\n\tcase '?':\n\tcase '@':\n\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\n\tcase 'G':\n\tcase 'H':\n\tcase 'I':\n\tcase 'J':\n\tcase 'K':\n\tcase 'L':\n\tcase 'M':\n\tcase 'N':\n\tcase 'O':\n\tcase 'P':\n\tcase 'Q':\n\tcase 'R':\n\tcase 'S':\n\tcase 'T':\n\tcase 'U':\n\tcase 'V':\n\tcase 'W':\n\tcase 'X':\n\tcase 'Y':\n\tcase 'Z':\n\tcase '[':\n\tcase '\\\\':\n\tcase ']':\n\tcase '^':\n\tcase '_':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\n\tcase 'g':\n\tcase 'h':\n\tcase 'i':\n\tcase 'j':\n\tcase 'k':\n\tcase 'l':\n\tcase 'm':\n\tcase 'n':\n\tcase 'o':\n\tcase 'p':\n\tcase 'q':\n\tcase 'r':\n\tcase 's':\n\tcase 't':\n\tcase 'u':\n\tcase 'v':\n\tcase 'w':\n\tcase 'x':\n\tcase 'y':\n\tcase 'z':\tgoto yy107;\n\tdefault:\tgoto yy109;\n\t}\nyy109:\n#line 510 \"token.re\"\n{   goto Directive; }\n#line 1484 \"<stdout>\"\n}\n#line 517 \"token.re\"\n\n\n    }\n\nPlain:\n    {\n        int qidx = 0;\n        int qcapa = 100;\n        char *qstr = S_ALLOC_N( char, qcapa );\n        SyckLevel *plvl;\n        int parentIndent;\n\n        YYCURSOR = YYTOKEN;\n        plvl = CURRENT_LEVEL();\n        GET_TRUE_YAML_INDENT(parentIndent);\n\nPlain2: \n        YYTOKEN = YYCURSOR;\n\nPlain3:\n\n\n#line 1509 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy110;\n\t++YYCURSOR;\nyy110:\n\tif((YYLIMIT - YYCURSOR) < 3) YYFILL(3);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy124;\n\tcase 0x09:\tgoto yy126;\n\tcase 0x0A:\tgoto yy112;\n\tcase 0x0D:\tgoto yy114;\n\tcase ' ':\tgoto yy122;\n\tcase ',':\tgoto yy117;\n\tcase ':':\tgoto yy116;\n\tcase ']':\tgoto yy120;\n\tcase '}':\tgoto yy118;\n\tdefault:\tgoto yy127;\n\t}\nyy112:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy142;\nyy113:\n#line 540 \"token.re\"\n{   int indt_len, nl_count = 0;\n                        SyckLevel *lvl;\n                        char *tok = YYTOKEN;\n                        GOBBLE_UP_YAML_INDENT( indt_len, tok );\n                        lvl = CURRENT_LEVEL();\n\n                        if ( indt_len <= parentIndent )\n                        {\n                            RETURN_IMPLICIT();\n                        }\n\n                        while ( YYTOKEN < YYCURSOR )\n                        {\n                            int nl_len = newline_len( YYTOKEN++ );\n                            if ( nl_len )\n                            {\n                                nl_count++;\n                                YYTOKEN += nl_len - 1;\n                            }\n                        }\n                        if ( nl_count <= 1 )\n                        {\n                            QUOTECAT(qstr, qcapa, qidx, ' ');\n                        }\n                        else\n                        {\n                            int i;\n                            for ( i = 0; i < nl_count - 1; i++ )\n                            {\n                                QUOTECAT(qstr, qcapa, qidx, '\\n');\n                            }\n                        }\n\n                        goto Plain2; \n                    }\n#line 1570 \"<stdout>\"\nyy114:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy141;\n\tdefault:\tgoto yy115;\n\t}\nyy115:\n#line 627 \"token.re\"\n{   QUOTECATS(qstr, qcapa, qidx, YYTOKEN, YYCURSOR - YYTOKEN);\n                        goto Plain2;\n                    }\n#line 1581 \"<stdout>\"\nyy116:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy136;\n\tcase 0x0D:\tgoto yy140;\n\tcase ' ':\tgoto yy138;\n\tdefault:\tgoto yy115;\n\t}\nyy117:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy130;\n\tcase 0x0D:\tgoto yy134;\n\tcase ' ':\tgoto yy132;\n\tdefault:\tgoto yy115;\n\t}\nyy118:\t++YYCURSOR;\n\tgoto yy119;\nyy119:\n#line 589 \"token.re\"\n{   if ( plvl->status != syck_lvl_imap )\n                        {\n                            PLAIN_NOT_INL();\n                        }\n                        else\n                        {\n                            PLAIN_IS_INL();\n                        }\n                        RETURN_IMPLICIT();\n                    }\n#line 1612 \"<stdout>\"\nyy120:\t++YYCURSOR;\n\tgoto yy121;\nyy121:\n#line 600 \"token.re\"\n{   if ( plvl->status != syck_lvl_iseq )\n                        {\n                            PLAIN_NOT_INL();\n                        }\n                        else\n                        {\n                            PLAIN_IS_INL();\n                        }\n                        RETURN_IMPLICIT();\n                    }\n#line 1627 \"<stdout>\"\nyy122:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase '#':\tgoto yy128;\n\tdefault:\tgoto yy123;\n\t}\nyy123:\n#line 617 \"token.re\"\n{   if ( qidx == 0 ) \n                        {\n                            goto Plain2;\n                        }\n                        else\n                        {\n                            goto Plain3; \n                        }\n                    }\n#line 1644 \"<stdout>\"\nyy124:\t++YYCURSOR;\n\tgoto yy125;\nyy125:\n#line 615 \"token.re\"\n{   RETURN_IMPLICIT(); }\n#line 1650 \"<stdout>\"\nyy126:\tyych = *++YYCURSOR;\n\tgoto yy123;\nyy127:\tyych = *++YYCURSOR;\n\tgoto yy115;\nyy128:\t++YYCURSOR;\n\tgoto yy129;\nyy129:\n#line 611 \"token.re\"\n{   eat_comments( parser ); \n                        RETURN_IMPLICIT();\n                    }\n#line 1662 \"<stdout>\"\nyy130:\t++YYCURSOR;\n\tgoto yy131;\nyy131:\n#line 578 \"token.re\"\n{   if ( plvl->status != syck_lvl_iseq && plvl->status != syck_lvl_imap )\n                        {\n                            PLAIN_NOT_INL();\n                        }\n                        else\n                        {\n                            PLAIN_IS_INL();\n                        }\n                        RETURN_IMPLICIT();\n                    }\n#line 1677 \"<stdout>\"\nyy132:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy133;\nyy133:\tswitch(yych){\n\tcase ' ':\tgoto yy132;\n\tdefault:\tgoto yy131;\n\t}\nyy134:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy130;\n\tdefault:\tgoto yy135;\n\t}\nyy135:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy113;\n\tcase 1:\tgoto yy115;\n\t}\nyy136:\t++YYCURSOR;\n\tgoto yy137;\nyy137:\n#line 576 \"token.re\"\n{   RETURN_IMPLICIT(); }\n#line 1701 \"<stdout>\"\nyy138:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy139;\nyy139:\tswitch(yych){\n\tcase ' ':\tgoto yy138;\n\tdefault:\tgoto yy137;\n\t}\nyy140:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy136;\n\tdefault:\tgoto yy135;\n\t}\nyy141:\tyyaccept = 0;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy142;\nyy142:\tswitch(yych){\n\tcase 0x0A:\tcase ' ':\tgoto yy141;\n\tcase 0x0D:\tgoto yy143;\n\tdefault:\tgoto yy113;\n\t}\nyy143:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy141;\n\tdefault:\tgoto yy135;\n\t}\n}\n#line 631 \"token.re\"\n\n    }\n\nSingleQuote:\n    {\n        int qidx = 0;\n        int qcapa = 100;\n        char *qstr = S_ALLOC_N( char, qcapa );\n\nSingleQuote2:\n        YYTOKEN = YYCURSOR;\n\n\n#line 1747 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy144;\n\t++YYCURSOR;\nyy144:\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy152;\n\tcase 0x0A:\tgoto yy146;\n\tcase 0x0D:\tgoto yy148;\n\tcase '\\'':\tgoto yy150;\n\tdefault:\tgoto yy153;\n\t}\nyy146:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy157;\nyy147:\n#line 645 \"token.re\"\n{   int indt_len;\n                        int nl_count = 0;\n                        SyckLevel *lvl;\n                        GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN );\n                        lvl = CURRENT_LEVEL();\n\n                        if ( lvl->status != syck_lvl_str )\n                        {\n                            ADD_LEVEL( indt_len, syck_lvl_str );\n                        }\n                        else if ( indt_len < lvl->spaces )\n                        {\n                            /* Error! */\n                        }\n\n                        while ( YYTOKEN < YYCURSOR )\n                        {\n                            int nl_len = newline_len( YYTOKEN++ );\n                            if ( nl_len )\n                            {\n                                nl_count++;\n                                YYTOKEN += nl_len - 1;\n                            }\n                        }\n                        if ( nl_count <= 1 )\n                        {\n                            QUOTECAT(qstr, qcapa, qidx, ' ');\n                        }\n                        else\n                        {\n                            int i;\n                            for ( i = 0; i < nl_count - 1; i++ )\n                            {\n                                QUOTECAT(qstr, qcapa, qidx, '\\n');\n                            }\n                        }\n\n                        goto SingleQuote2; \n                    }\n#line 1807 \"<stdout>\"\nyy148:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy156;\n\tdefault:\tgoto yy149;\n\t}\nyy149:\n#line 712 \"token.re\"\n{   QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); \n                        goto SingleQuote2; \n                    }\n#line 1818 \"<stdout>\"\nyy150:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase '\\'':\tgoto yy154;\n\tdefault:\tgoto yy151;\n\t}\nyy151:\n#line 689 \"token.re\"\n{   SyckLevel *lvl;\n                        SyckNode *n = syck_alloc_str();\n                        lvl = CURRENT_LEVEL();\n\n                        if ( lvl->status == syck_lvl_str )\n                        {\n                            POP_LEVEL();\n                        }\n                        if ( ((SyckParser *)parser)->taguri_expansion == 1 )\n                        {\n                            n->type_id = syck_taguri( YAML_DOMAIN, \"str\", 3 );\n                        }\n                        else\n                        {\n                            n->type_id = syck_strndup( \"str\", 3 );\n                        }\n                        n->data.str->ptr = qstr;\n                        n->data.str->len = qidx;\n                        n->data.str->style = scalar_1quote;\n                        sycklval->nodeData = n;\n                        return YAML_PLAIN; \n                    }\n#line 1848 \"<stdout>\"\nyy152:\tyych = *++YYCURSOR;\n\tgoto yy151;\nyy153:\tyych = *++YYCURSOR;\n\tgoto yy149;\nyy154:\t++YYCURSOR;\n\tgoto yy155;\nyy155:\n#line 685 \"token.re\"\n{   QUOTECAT(qstr, qcapa, qidx, '\\'');\n                        goto SingleQuote2; \n                    }\n#line 1860 \"<stdout>\"\nyy156:\tyyaccept = 0;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy157;\nyy157:\tswitch(yych){\n\tcase 0x0A:\tcase ' ':\tgoto yy156;\n\tcase 0x0D:\tgoto yy158;\n\tdefault:\tgoto yy147;\n\t}\nyy158:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy156;\n\tdefault:\tgoto yy159;\n\t}\nyy159:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy147;\n\t}\n}\n#line 716 \"token.re\"\n\n\n    }\n\n\nDoubleQuote:\n    {\n        int keep_nl = 1;\n        int qidx = 0;\n        int qcapa = 100;\n        char *qstr = S_ALLOC_N( char, qcapa );\n\nDoubleQuote2:\n        YYTOKEN = YYCURSOR;\n\n\n\n#line 1901 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy160;\n\t++YYCURSOR;\nyy160:\n\tif((YYLIMIT - YYCURSOR) < 4) YYFILL(4);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy167;\n\tcase 0x0A:\tgoto yy162;\n\tcase 0x0D:\tgoto yy164;\n\tcase '\"':\tgoto yy169;\n\tcase '\\\\':\tgoto yy166;\n\tdefault:\tgoto yy170;\n\t}\nyy162:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy184;\nyy163:\n#line 734 \"token.re\"\n{   int indt_len;\n                        int nl_count = 0;\n                        SyckLevel *lvl;\n                        GOBBLE_UP_YAML_INDENT( indt_len, YYTOKEN );\n                        lvl = CURRENT_LEVEL();\n\n                        if ( lvl->status != syck_lvl_str )\n                        {\n                            ADD_LEVEL( indt_len, syck_lvl_str );\n                        }\n                        else if ( indt_len < lvl->spaces )\n                        {\n                            /* FIXME */\n                        }\n\n                        if ( keep_nl == 1 )\n                        {\n                            while ( YYTOKEN < YYCURSOR )\n                            {\n                                int nl_len = newline_len( YYTOKEN++ );\n                                if ( nl_len )\n                                {\n                                    nl_count++;\n                                    YYTOKEN += nl_len - 1;\n                                }\n                            }\n                            if ( nl_count <= 1 )\n                            {\n                                QUOTECAT(qstr, qcapa, qidx, ' ');\n                            }\n                            else\n                            {\n                                int i;\n                                for ( i = 0; i < nl_count - 1; i++ )\n                                {\n                                    QUOTECAT(qstr, qcapa, qidx, '\\n');\n                                }\n                            }\n                        }\n\n                        keep_nl = 1;\n                        goto DoubleQuote2; \n                    }\n#line 1966 \"<stdout>\"\nyy164:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy183;\n\tdefault:\tgoto yy165;\n\t}\nyy165:\n#line 820 \"token.re\"\n{   QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); \n                        goto DoubleQuote2; \n                    }\n#line 1977 \"<stdout>\"\nyy166:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy174;\n\tcase 0x0D:\tgoto yy176;\n\tcase ' ':\tgoto yy171;\n\tcase '\"':\tcase '0':\tcase '\\\\':\tcase 'a':\n\tcase 'b':\tcase 'e':\n\tcase 'f':\tcase 'n':\tcase 'r':\tcase 't':\tcase 'v':\tgoto yy178;\n\tcase 'x':\tgoto yy177;\n\tdefault:\tgoto yy165;\n\t}\nyy167:\t++YYCURSOR;\n\tgoto yy168;\nyy168:\n#line 797 \"token.re\"\n{   SyckLevel *lvl;\n                        SyckNode *n = syck_alloc_str();\n                        lvl = CURRENT_LEVEL();\n\n                        if ( lvl->status == syck_lvl_str )\n                        {\n                            POP_LEVEL();\n                        }\n                        if ( ((SyckParser *)parser)->taguri_expansion == 1 )\n                        {\n                            n->type_id = syck_taguri( YAML_DOMAIN, \"str\", 3 );\n                        }\n                        else\n                        {\n                            n->type_id = syck_strndup( \"str\", 3 );\n                        }\n                        n->data.str->ptr = qstr;\n                        n->data.str->len = qidx;\n                        n->data.str->style = scalar_2quote;\n                        sycklval->nodeData = n;\n                        return YAML_PLAIN; \n                    }\n#line 2016 \"<stdout>\"\nyy169:\tyych = *++YYCURSOR;\n\tgoto yy168;\nyy170:\tyych = *++YYCURSOR;\n\tgoto yy165;\nyy171:\t++YYCURSOR;\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tgoto yy172;\nyy172:\tswitch(yych){\n\tcase 0x0A:\tgoto yy174;\n\tcase 0x0D:\tgoto yy176;\n\tcase ' ':\tgoto yy171;\n\tdefault:\tgoto yy173;\n\t}\nyy173:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy163;\n\tcase 1:\tgoto yy165;\n\t}\nyy174:\t++YYCURSOR;\n\tgoto yy175;\nyy175:\n#line 792 \"token.re\"\n{   keep_nl = 0;\n                        YYCURSOR--;\n                        goto DoubleQuote2; \n                    }\n#line 2044 \"<stdout>\"\nyy176:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy174;\n\tdefault:\tgoto yy173;\n\t}\nyy177:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\tgoto yy180;\n\tdefault:\tgoto yy173;\n\t}\nyy178:\t++YYCURSOR;\n\tgoto yy179;\nyy179:\n#line 778 \"token.re\"\n{   char ch = *( YYCURSOR - 1 );\n                        QUOTECAT(qstr, qcapa, qidx, escape_seq( ch ));\n                        goto DoubleQuote2; \n                    }\n#line 2082 \"<stdout>\"\nyy180:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\tgoto yy181;\n\tdefault:\tgoto yy173;\n\t}\nyy181:\t++YYCURSOR;\n\tgoto yy182;\nyy182:\n#line 783 \"token.re\"\n{   long ch;\n                        char *chr_text = syck_strndup( YYTOKEN, 4 );\n                        chr_text[0] = '0';\n                        ch = strtol( chr_text, NULL, 16 );\n                        free( chr_text );\n                        QUOTECAT(qstr, qcapa, qidx, ch);\n                        goto DoubleQuote2; \n                    }\n#line 2119 \"<stdout>\"\nyy183:\tyyaccept = 0;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy184;\nyy184:\tswitch(yych){\n\tcase 0x0A:\tcase ' ':\tgoto yy183;\n\tcase 0x0D:\tgoto yy185;\n\tdefault:\tgoto yy163;\n\t}\nyy185:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy183;\n\tdefault:\tgoto yy173;\n\t}\n}\n#line 824 \"token.re\"\n\n    }\n\nTransferMethod:\n    {\n        int qidx = 0;\n        int qcapa = 100;\n        char *qstr = S_ALLOC_N( char, qcapa );\n\nTransferMethod2:\n        YYTOKTMP = YYCURSOR;\n\n\n#line 2152 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy186;\n\t++YYCURSOR;\nyy186:\n\tif((YYLIMIT - YYCURSOR) < 4) YYFILL(4);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy188;\n\tcase 0x0A:\tgoto yy190;\n\tcase 0x0D:\tgoto yy192;\n\tcase ' ':\tgoto yy191;\n\tcase '\\\\':\tgoto yy194;\n\tdefault:\tgoto yy195;\n\t}\nyy188:\t++YYCURSOR;\n\tgoto yy189;\nyy189:\n#line 838 \"token.re\"\n{   SyckLevel *lvl;\n                        YYCURSOR = YYTOKTMP;\n                        if ( YYCURSOR == YYTOKEN + 1 )\n                        {\n                            free( qstr );\n                            return YAML_ITRANSFER;\n                        }\n\n                        lvl = CURRENT_LEVEL();\n\n                        /*\n                         * URL Prefixing\n                         */\n                        if ( *qstr == '^' )\n                        {\n                            sycklval->name = S_ALLOC_N( char, qidx + strlen( lvl->domain ) );\n                            sycklval->name[0] = '\\0';\n                            strcat( sycklval->name, lvl->domain );\n                            strncat( sycklval->name, qstr + 1, qidx - 1 );\n                            free( qstr );\n                        }\n                        else\n                        {\n                            char *carat = qstr;\n                            char *qend = qstr + qidx;\n                            while ( (++carat) < qend )\n                            {\n                                if ( *carat == '^' )\n                                    break;\n                            }\n\n                            if ( carat < qend )\n                            {\n                                free( lvl->domain );\n                                lvl->domain = syck_strndup( qstr, carat - qstr );\n                                sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) );\n                                sycklval->name[0] = '\\0';\n                                strcat( sycklval->name, lvl->domain );\n                                strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 );\n                                free( qstr );\n                            }\n                            else\n                            {\n                                sycklval->name = qstr;\n                            }\n                        }\n\n                        return YAML_TRANSFER; \n                    }\n#line 2222 \"<stdout>\"\nyy190:\tyych = *++YYCURSOR;\n\tgoto yy189;\nyy191:\tyych = *++YYCURSOR;\n\tgoto yy204;\nyy192:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy188;\n\tdefault:\tgoto yy193;\n\t}\nyy193:\n#line 905 \"token.re\"\n{   QUOTECAT(qstr, qcapa, qidx, *(YYCURSOR - 1)); \n                        goto TransferMethod2;\n                    }\n#line 2237 \"<stdout>\"\nyy194:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '\"':\tcase '0':\tcase '\\\\':\tcase 'a':\n\tcase 'b':\tcase 'e':\n\tcase 'f':\tcase 'n':\tcase 'r':\tcase 't':\tcase 'v':\tgoto yy198;\n\tcase 'x':\tgoto yy196;\n\tdefault:\tgoto yy193;\n\t}\nyy195:\tyych = *++YYCURSOR;\n\tgoto yy193;\nyy196:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\tgoto yy200;\n\tdefault:\tgoto yy197;\n\t}\nyy197:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy193;\n\t}\nyy198:\t++YYCURSOR;\n\tgoto yy199;\nyy199:\n#line 891 \"token.re\"\n{  char ch = *( YYCURSOR - 1 );\n                        QUOTECAT(qstr, qcapa, qidx, escape_seq( ch ));\n                        goto TransferMethod2;\n                    }\n#line 2285 \"<stdout>\"\nyy200:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '0':\n\tcase '1':\n\tcase '2':\n\tcase '3':\n\tcase '4':\n\tcase '5':\n\tcase '6':\n\tcase '7':\n\tcase '8':\n\tcase '9':\tcase 'A':\n\tcase 'B':\n\tcase 'C':\n\tcase 'D':\n\tcase 'E':\n\tcase 'F':\tcase 'a':\n\tcase 'b':\n\tcase 'c':\n\tcase 'd':\n\tcase 'e':\n\tcase 'f':\tgoto yy201;\n\tdefault:\tgoto yy197;\n\t}\nyy201:\t++YYCURSOR;\n\tgoto yy202;\nyy202:\n#line 896 \"token.re\"\n{   long ch;\n                        char *chr_text = syck_strndup( YYTOKTMP, 4 );\n                        chr_text[0] = '0';\n                        ch = strtol( chr_text, NULL, 16 );\n                        free( chr_text );\n                        QUOTECAT(qstr, qcapa, qidx, ch);\n                        goto TransferMethod2;\n                    }\n#line 2322 \"<stdout>\"\nyy203:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy204;\nyy204:\tswitch(yych){\n\tcase ' ':\tgoto yy203;\n\tdefault:\tgoto yy189;\n\t}\n}\n#line 910 \"token.re\"\n\n    }\n\nScalarBlock:\n    {\n        int qidx = 0;\n        int qcapa = 100;\n        char *qstr = S_ALLOC_N( char, qcapa );\n        int blockType = 0;\n        int nlDoWhat = 0;\n        int lastIndent = 0;\n        int forceIndent = -1;\n        char *yyt = YYTOKEN;\n        SyckLevel *lvl = CURRENT_LEVEL();\n        int parentIndent = -1;\n\n        switch ( *yyt )\n        {\n            case '|': blockType = BLOCK_LIT; break;\n            case '>': blockType = BLOCK_FOLD; break;\n        }\n\n        while ( ++yyt <= YYCURSOR )\n        {\n            if ( *yyt == '-' )\n            {\n                nlDoWhat = NL_CHOMP;\n            }\n            else if ( *yyt == '+' )\n            {\n                nlDoWhat = NL_KEEP;\n            }\n            else if ( isdigit( *yyt ) )\n            {\n                forceIndent = strtol( yyt, NULL, 10 );\n            }\n        }\n\n        qstr[0] = '\\0';\n        YYTOKEN = YYCURSOR;\n\nScalarBlock2:\n        YYTOKEN = YYCURSOR;\n\n\n#line 2378 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy205;\n\t++YYCURSOR;\nyy205:\n\tif((YYLIMIT - YYCURSOR) < 5) YYFILL(5);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy213;\n\tcase 0x0A:\tgoto yy207;\n\tcase 0x0D:\tgoto yy209;\n\tcase '#':\tgoto yy211;\n\tcase '-':\tgoto yy215;\n\tdefault:\tgoto yy216;\n\t}\nyy207:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy226;\nyy208:\n#line 956 \"token.re\"\n{   char *pacer;\n                        char *tok = YYTOKEN;\n                        int indt_len = 0, nl_count = 0, fold_nl = 0, nl_begin = 0;\n                        GOBBLE_UP_YAML_INDENT( indt_len, tok );\n                        lvl = CURRENT_LEVEL();\n\n                        if ( lvl->status != syck_lvl_block )\n                        {\n                            GET_TRUE_YAML_INDENT(parentIndent);\n                            if ( forceIndent > 0 ) forceIndent += parentIndent;\n                            if ( indt_len > parentIndent )\n                            {\n                                int new_spaces = forceIndent > 0 ? forceIndent : indt_len;\n                                ADD_LEVEL( new_spaces, syck_lvl_block );\n                                lastIndent = indt_len - new_spaces;\n                                nl_begin = 1;\n                                lvl = CURRENT_LEVEL();\n                            }\n                            else\n                            {\n                                YYCURSOR = YYTOKEN;\n                                RETURN_YAML_BLOCK();\n                            }\n                        }\n\n                        /*\n                         * Fold only in the event of two lines being on the leftmost\n                         * indentation.\n                         */\n                        if ( blockType == BLOCK_FOLD && lastIndent == 0 && ( indt_len - lvl->spaces ) == 0 )\n                        {\n                            fold_nl = 1;\n                        }\n\n                        pacer = YYTOKEN;\n                        while ( pacer < YYCURSOR )\n                        {\n                            int nl_len = newline_len( pacer++ );\n                            if ( nl_len )\n                            {\n                                nl_count++;\n                                pacer += nl_len - 1;\n                            }\n                        }\n\n                        if ( fold_nl == 1 || nl_begin == 1 )\n                        {\n                            nl_count--;\n                        }\n\n                        if ( nl_count < 1 && nl_begin == 0 )\n                        {\n                            QUOTECAT(qstr, qcapa, qidx, ' ');\n                        }\n                        else\n                        {\n                            int i;\n                            for ( i = 0; i < nl_count; i++ )\n                            {\n                                QUOTECAT(qstr, qcapa, qidx, '\\n');\n                            }\n                        }\n\n                        lastIndent = indt_len - lvl->spaces;\n                        YYCURSOR -= lastIndent;\n\n                        if ( indt_len < lvl->spaces )\n                        {\n                            POP_LEVEL();\n                            YYCURSOR = YYTOKEN;\n                            RETURN_YAML_BLOCK();\n                        }\n                        goto ScalarBlock2;\n                    }\n#line 2474 \"<stdout>\"\nyy209:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy225;\n\tdefault:\tgoto yy210;\n\t}\nyy210:\n#line 1070 \"token.re\"\n{   QUOTECAT(qstr, qcapa, qidx, *YYTOKEN);\n                        goto ScalarBlock2;\n                    }\n#line 2485 \"<stdout>\"\nyy211:\t++YYCURSOR;\n\tgoto yy212;\nyy212:\n#line 1032 \"token.re\"\n{   lvl = CURRENT_LEVEL();\n                        if ( lvl->status != syck_lvl_block )\n                        {\n                            eat_comments( parser );\n                            YYTOKEN = YYCURSOR;\n                        }\n                        else\n                        {\n                            QUOTECAT(qstr, qcapa, qidx, *YYTOKEN);\n                        }\n                        goto ScalarBlock2;\n                    }\n#line 2502 \"<stdout>\"\nyy213:\t++YYCURSOR;\n\tgoto yy214;\nyy214:\n#line 1046 \"token.re\"\n{   YYCURSOR--;\n                        POP_LEVEL();\n                        RETURN_YAML_BLOCK(); \n                    }\n#line 2511 \"<stdout>\"\nyy215:\tyyaccept = 1;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tswitch(yych){\n\tcase '-':\tgoto yy217;\n\tdefault:\tgoto yy210;\n\t}\nyy216:\tyych = *++YYCURSOR;\n\tgoto yy210;\nyy217:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase '-':\tgoto yy219;\n\tdefault:\tgoto yy218;\n\t}\nyy218:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy208;\n\tcase 1:\tgoto yy210;\n\t}\nyy219:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy220;\n\tcase 0x0D:\tgoto yy224;\n\tcase ' ':\tgoto yy222;\n\tdefault:\tgoto yy218;\n\t}\nyy220:\t++YYCURSOR;\n\tgoto yy221;\nyy221:\n#line 1051 \"token.re\"\n{   if ( YYTOKEN == YYLINEPTR )\n                        {\n                            if ( blockType == BLOCK_FOLD && qidx > 0 )\n                            {\n                                qidx -= 1;\n                            }\n                            QUOTECAT(qstr, qcapa, qidx, '\\n');\n                            POP_LEVEL();\n                            YYCURSOR = YYTOKEN;\n                            RETURN_YAML_BLOCK();\n                        }\n                        else\n                        {\n                            QUOTECAT(qstr, qcapa, qidx, *YYTOKEN);\n                            YYCURSOR = YYTOKEN + 1;\n                            goto ScalarBlock2;\n                        }\n                    }\n#line 2559 \"<stdout>\"\nyy222:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy223;\nyy223:\tswitch(yych){\n\tcase ' ':\tgoto yy222;\n\tdefault:\tgoto yy221;\n\t}\nyy224:\tyych = *++YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy220;\n\tdefault:\tgoto yy218;\n\t}\nyy225:\tyyaccept = 0;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy226;\nyy226:\tswitch(yych){\n\tcase 0x0A:\tcase ' ':\tgoto yy225;\n\tcase 0x0D:\tgoto yy227;\n\tdefault:\tgoto yy208;\n\t}\nyy227:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy225;\n\tdefault:\tgoto yy218;\n\t}\n}\n#line 1075 \"token.re\"\n\n    }\n\n    return 0;\n\n}\n\nvoid\neat_comments( SyckParser *parser )\n{\nComment:\n    {\n        YYTOKEN = YYCURSOR;\n\n\n#line 2607 \"<stdout>\"\n{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n\tgoto yy228;\n\t++YYCURSOR;\nyy228:\n\tif((YYLIMIT - YYCURSOR) < 2) YYFILL(2);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x00:\tgoto yy230;\n\tcase 0x0A:\tgoto yy232;\n\tcase 0x0D:\tgoto yy233;\n\tdefault:\tgoto yy235;\n\t}\nyy230:\t++YYCURSOR;\n\tgoto yy231;\nyy231:\n#line 1091 \"token.re\"\n{   YYCURSOR = YYTOKEN;\n                        return;\n                    }\n#line 2629 \"<stdout>\"\nyy232:\tyyaccept = 0;\n\tyych = *(YYMARKER = ++YYCURSOR);\n\tgoto yy237;\nyy233:\t++YYCURSOR;\n\tswitch((yych = *YYCURSOR)) {\n\tcase 0x0A:\tgoto yy236;\n\tdefault:\tgoto yy234;\n\t}\nyy234:\n#line 1095 \"token.re\"\n{   goto Comment; \n                    }\n#line 2642 \"<stdout>\"\nyy235:\tyych = *++YYCURSOR;\n\tgoto yy234;\nyy236:\tyyaccept = 0;\n\tYYMARKER = ++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tgoto yy237;\nyy237:\tswitch(yych){\n\tcase 0x0A:\tgoto yy236;\n\tcase 0x0D:\tgoto yy238;\n\tdefault:\tgoto yy231;\n\t}\nyy238:\t++YYCURSOR;\n\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n\tyych = *YYCURSOR;\n\tswitch(yych){\n\tcase 0x0A:\tgoto yy236;\n\tdefault:\tgoto yy239;\n\t}\nyy239:\tYYCURSOR = YYMARKER;\n\tswitch(yyaccept){\n\tcase 0:\tgoto yy231;\n\t}\n}\n#line 1098 \"token.re\"\n\n\n    }\n\n}\n\nchar\nescape_seq( char ch )\n{\n    switch ( ch )\n    {\n        case '0': return '\\0';\n        case 'a': return 7;\n        case 'b': return '\\010';\n        case 'e': return '\\033';\n        case 'f': return '\\014';\n        case 'n': return '\\n';\n        case 'r': return '\\015';\n        case 't': return '\\t';\n        case 'v': return '\\013';\n        default: return ch;\n    }\n}\n\nint\nis_newline( char *ptr )\n{\n    return newline_len( ptr );\n}\n\nint\nnewline_len( char *ptr )\n{\n    if ( *ptr == '\\n' )\n        return 1;\n    \n    if ( *ptr == '\\r' && *( ptr + 1 ) == '\\n' )\n        return 2;\n\n    return 0;\n}\n\nint \nsyckwrap()\n{\n    return 1;\n}\n\nvoid \nsyckerror( char *msg )\n{\n    if ( syck_parser_ptr->error_handler == NULL )\n        syck_parser_ptr->error_handler = syck_default_error_handler;\n\n    syck_parser_ptr->root = syck_parser_ptr->root_on_error;\n    (syck_parser_ptr->error_handler)(syck_parser_ptr, msg);\n}\n\n"
  },
  {
    "path": "ext/syck/yaml2byte.c",
    "content": "/*\n * yaml2byte.c\n *\n * $Author$\n * $Date$\n *\n * Copyright (C) 2003 why the lucky stiff, clark evans\n *\n *   WARNING WARNING WARNING  --- THIS IS *NOT JUST* PLAYING\n *   ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING!\n */ \n#include \"ruby.h\"\n#include <syck.h>\n#include <assert.h>\n#define YAMLBYTE_UTF8\n#include \"yamlbyte.h\"\n\n#include <stdio.h>\n#define TRACE0(a)  \\\n    do { printf(a); printf(\"\\n\"); fflush(stdout); } while(0)\n#define TRACE1(a,b) \\\n    do { printf(a,b); printf(\"\\n\"); fflush(stdout); } while(0)\n#define TRACE2(a,b,c) \\\n    do { printf(a,b,c); printf(\"\\n\"); fflush(stdout); } while(0)\n#define TRACE3(a,b,c,d) \\\n    do { printf(a,b,c,d); printf(\"\\n\"); fflush(stdout); } while(0)\n\n/* Reinvent the wheel... */\n#define CHUNKSIZE 64\n#define HASH ((long)0xCAFECAFE)\ntypedef struct {\n   long hash;\n   char *buffer;\n   long length;\n   long remaining;\n   int  printed;\n} bytestring_t;\nbytestring_t *bytestring_alloc() {\n    bytestring_t *ret; \n    /*TRACE0(\"bytestring_alloc()\");*/\n    ret = S_ALLOC(bytestring_t);\n    ret->hash   = HASH;\n    ret->length = CHUNKSIZE;\n    ret->remaining = ret->length;\n    ret->buffer = S_ALLOC_N(char, ret->length + 1 );\n    ret->buffer[0] = 0;\n    ret->printed = 0;\n    return ret;\n}\nvoid bytestring_append(bytestring_t *str, char code, \n                       char *start, char *finish) \n{\n    long grow;\n    long length = 2;   /* CODE + LF */\n    char *curr;\n    assert(str && HASH == str->hash);\n    /*TRACE0(\"bytestring_append()\");*/\n    if(start) {\n        if(!finish)\n            finish = start + strlen(start);\n        length += (finish-start);\n    }\n    if(length > str->remaining) {\n        grow = (length - str->remaining) + CHUNKSIZE;\n        str->remaining += grow;\n        str->length    += grow; \n        str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 );\n        assert(str->buffer);\n    }\n    curr = str->buffer + (str->length - str->remaining);\n    *curr = code;\n    curr += 1;\n    if(start) \n        while(start < finish)\n            *curr ++ = *start ++;\n    *curr = '\\n';\n    curr += 1;\n    *curr = 0;\n    str->remaining = str->remaining - length;\n    assert( (str->buffer + str->length) - str->remaining );\n}\nvoid bytestring_extend(bytestring_t *str, bytestring_t *ext)\n{\n    char *from;\n    char *curr;\n    char *stop;\n    long grow;\n    long length;\n    assert(str && HASH == str->hash);\n    assert(ext && HASH == ext->hash);\n    if(ext->printed) {\n        assert(ext->buffer[0] ==YAMLBYTE_ANCHOR);\n        curr = ext->buffer;\n        while( '\\n' != *curr)\n            curr++;\n        bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr);\n    } else {\n        ext->printed = 1;\n        length  = (ext->length - ext->remaining);\n        if(length > str->remaining) {\n            grow = (length - str->remaining) + CHUNKSIZE;\n            str->remaining += grow;\n            str->length    += grow; \n            str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 );\n        }\n        curr = str->buffer + (str->length - str->remaining);\n        from = ext->buffer;\n        stop = ext->buffer + length;\n        while( from < stop )\n            *curr ++ = *from ++;\n        *curr = 0;\n        str->remaining = str->remaining - length;\n        assert( (str->buffer + str->length) - str->remaining );\n    }\n}\n\n/* convert SyckNode into yamlbyte_buffer_t objects */\nSYMID\nsyck_yaml2byte_handler(p, n)\n    SyckParser *p;\n    SyckNode *n;\n{\n    SYMID oid;\n    long i;\n    char ch;\n    char nextcode;\n    char *start;\n    char *current;\n    char *finish;\n    bytestring_t *val = NULL;\n    bytestring_t *sav = NULL;\n    /*TRACE0(\"syck_yaml2byte_handler()\");*/\n    val = bytestring_alloc();\n    if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL);\n    if ( n->type_id )\n    {\n        if ( p->taguri_expansion )\n        {\n            bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL);\n        }\n        else\n        {\n            char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 );\n            type_tag[0] = '\\0';\n            strcat( type_tag, \"!\" );\n            strcat( type_tag, n->type_id );\n            bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL);\n\t    S_FREE(type_tag);\n        }\n    }\n    switch (n->kind)\n    {\n        case syck_str_kind:\n            nextcode = YAMLBYTE_SCALAR;\n            start  = n->data.str->ptr;\n            finish = start + n->data.str->len - 1;\n            current = start;\n            /*TRACE2(\"SCALAR: %s %d\", start, n->data.str->len); */\n            while(1) {\n                ch = *current;\n                if('\\n' == ch || 0 == ch || current > finish) {\n                    if(current >= start) {\n                        bytestring_append(val, nextcode, start, current);\n                        nextcode = YAMLBYTE_CONTINUE;\n                    }\n                    start = current + 1;\n                    if(current > finish)\n                    {\n                        break;\n                    }\n                    else if('\\n' == ch )\n                    {\n                        bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL);\n                    }\n                    else if(0 == ch)\n                    {\n                        bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL);\n                    }\n                    else \n                    {\n                        assert(\"oops\");\n                    }\n                }\n                current += 1;\n            }\n        break;\n        case syck_seq_kind:\n            bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL);\n            for ( i = 0; i < n->data.list->idx; i++ )\n            {\n                oid = syck_seq_read( n, i );\n                syck_lookup_sym( p, oid, (char **)&sav );\n                bytestring_extend(val, sav);\n            }\n            bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);\n        break;\n        case syck_map_kind:\n            bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL);\n            for ( i = 0; i < n->data.pairs->idx; i++ )\n            {\n                oid = syck_map_read( n, map_key, i );\n                syck_lookup_sym( p, oid, (char **)&sav );\n                bytestring_extend(val, sav);\n                oid = syck_map_read( n, map_value, i );\n                syck_lookup_sym( p, oid, (char **)&sav );\n                bytestring_extend(val, sav);\n            }\n            bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL);\n        break;\n    }\n    oid = syck_add_sym( p, (char *) val );\n    /*TRACE1(\"Saving: %s\", val->buffer );*/\n    return oid;\n}\n\nchar *\nsyck_yaml2byte(char *yamlstr)\n{\n    SYMID oid;\n    char *ret;\n    bytestring_t *sav; \n\n    SyckParser *parser = syck_new_parser();\n    syck_parser_str_auto( parser, yamlstr, NULL );\n    syck_parser_handler( parser, syck_yaml2byte_handler );\n    syck_parser_error_handler( parser, NULL );\n    syck_parser_implicit_typing( parser, 1 );\n    syck_parser_taguri_expansion( parser, 1 );\n    oid = syck_parse( parser );\n\n    if ( syck_lookup_sym( parser, oid, (char **)&sav ) == 1 ) {\n        ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 );\n        ret[0] = '\\0';\n        strcat( ret, \"D\\n\" );\n        strcat( ret, sav->buffer );\n    }\n    else\n    {\n        ret = NULL;\n    }\n\n    syck_free_parser( parser );\n    return ret;\n}\n\n#ifdef TEST_YBEXT\n#include <stdio.h>\nint main() {\n   char *yaml = \"test: 1\\nand: \\\"with new\\\\nline\\\\n\\\"\\nalso: &3 three\\nmore: *3\";\n   printf(\"--- # YAML \\n\");\n   printf(yaml);\n   printf(\"\\n...\\n\");\n   printf(syck_yaml2byte(yaml));\n   return 0;\n}\n#endif\n\n"
  },
  {
    "path": "ext/syck/yamlbyte.h",
    "content": "/*  yamlbyte.h\n *\n *  The YAML bytecode \"C\" interface header file.   See the YAML bytecode\n *  reference for bytecode sequence rules and for the meaning of each\n *  bytecode.\n */\n\n#ifndef YAMLBYTE_H\n#define YAMLBYTE_H\n#include <stddef.h>\n\n/* define what a character is */\ntypedef unsigned char yamlbyte_utf8_t;\ntypedef unsigned short yamlbyte_utf16_t;\n#ifdef YAMLBYTE_UTF8\n  #ifdef YAMLBYTE_UTF16\n    #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16\n  #endif\n  typedef yamlbyte_utf8_t yamlbyte_char_t;\n#else\n  #ifdef YAMLBYTE_UTF16\n    typedef yamlbyte_utf16_t yamlbyte_char_t;\n  #else\n    #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16\n  #endif\n#endif\n\n/* specify list of bytecodes */\n#define YAMLBYTE_FINISH          ((yamlbyte_char_t) 0)\n#define YAMLBYTE_DOCUMENT        ((yamlbyte_char_t)'D')\n#define YAMLBYTE_DIRECTIVE       ((yamlbyte_char_t)'V')\n#define YAMLBYTE_PAUSE           ((yamlbyte_char_t)'P')\n#define YAMLBYTE_MAPPING         ((yamlbyte_char_t)'M')\n#define YAMLBYTE_SEQUENCE        ((yamlbyte_char_t)'Q')\n#define YAMLBYTE_END_BRANCH      ((yamlbyte_char_t)'E')\n#define YAMLBYTE_SCALAR          ((yamlbyte_char_t)'S')\n#define YAMLBYTE_CONTINUE        ((yamlbyte_char_t)'C')\n#define YAMLBYTE_NEWLINE         ((yamlbyte_char_t)'N')\n#define YAMLBYTE_NULLCHAR        ((yamlbyte_char_t)'Z')\n#define YAMLBYTE_ANCHOR          ((yamlbyte_char_t)'A')\n#define YAMLBYTE_ALIAS           ((yamlbyte_char_t)'R')\n#define YAMLBYTE_TRANSFER        ((yamlbyte_char_t)'T')\n/* formatting bytecodes */\n#define YAMLBYTE_COMMENT         ((yamlbyte_char_t)'c')\n#define YAMLBYTE_INDENT          ((yamlbyte_char_t)'i')\n#define YAMLBYTE_STYLE           ((yamlbyte_char_t)'s')\n/* other bytecodes */\n#define YAMLBYTE_LINE_NUMBER     ((yamlbyte_char_t)'#')\n#define YAMLBYTE_WHOLE_SCALAR    ((yamlbyte_char_t)'<')\n#define YAMLBYTE_NOTICE          ((yamlbyte_char_t)'!')\n#define YAMLBYTE_SPAN            ((yamlbyte_char_t)')')\n#define YAMLBYTE_ALLOC           ((yamlbyte_char_t)'@')\n\n/* second level style bytecodes, ie \"s>\" */\n#define YAMLBYTE_FLOW            ((yamlbyte_char_t)'>')\n#define YAMLBYTE_LITERAL         ((yamlbyte_char_t)'|')\n#define YAMLBYTE_BLOCK           ((yamlbyte_char_t)'b')\n#define YAMLBYTE_PLAIN           ((yamlbyte_char_t)'p')\n#define YAMLBYTE_INLINE_MAPPING  ((yamlbyte_char_t)'{')\n#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')\n#define YAMLBYTE_SINGLE_QUOTED   ((yamlbyte_char_t)39)\n#define YAMLBYTE_DOUBLE_QUOTED   ((yamlbyte_char_t)'\"')\n\n/*\n * The \"C\" API has two variants, one based on instructions,\n * with events delivered via pointers; and the other one\n * is character based where one or more instructions are\n * serialized into a buffer.\n *\n * Note: In the instruction based API, WHOLE_SCALAR does\n *       not have the '<here' marshalling stuff.\n */\n\ntypedef void * yamlbyte_consumer_t;\ntypedef void * yamlbyte_producer_t;\n\n/* push and pull APIs need a way to communicate results */\ntypedef enum {\n    YAMLBYTE_OK          = 0,     /* proceed                        */\n    YAMLBYTE_E_MEMORY    = 'M',   /* could not allocate memory      */\n    YAMLBYTE_E_READ      = 'R',   /* input stream read error        */\n    YAMLBYTE_E_WRITE     = 'W',   /* output stream write error      */\n    YAMLBYTE_E_OTHER     = '?',   /* some other error condition     */\n    YAMLBYTE_E_PARSE     = 'P',   /* parse error, check bytecodes   */\n} yamlbyte_result_t;\n \ntypedef const yamlbyte_char_t *yamlbyte_buff_t; \n\n/* \n *  The \"Instruction\" API \n */\n\ntypedef struct yaml_instruction {\n    yamlbyte_char_t bytecode;\n    yamlbyte_buff_t start;\n    yamlbyte_buff_t finish;  /* open range, *finish is _not_ part */\n} *yamlbyte_inst_t;\n\n/* producer pushes the instruction with one bytecode event to the \n * consumer; if the consumer's result is not YAMLBYTE_OK, then\n * the producer should stop */\ntypedef\n  yamlbyte_result_t\n   (*yamlbyte_push_t)(\n     yamlbyte_consumer_t self,\n     yamlbyte_inst_t  inst\n   );\n\n/* consumer pulls a bytecode instruction from the producer; in this\n * case the instruction (and is buffer) are owned by the producer and\n * will remain valid till the pull function is called once again;\n * if the instruction is NULL, then there are no more results; and\n * it is important to call the pull function till it returns NULL so \n * that the producer can clean up its memory allocations */\ntypedef \n   yamlbyte_result_t\n    (*yamlbyte_pull_t)(\n      yamlbyte_producer_t self,\n      yamlbyte_inst_t *inst   /* to be filled in by the producer */\n    ); \n\n/*\n *  Buffer based API\n */\n\n/* producer pushes a null terminated buffer filled with one or more\n * bytecode events to the consumer; if the consumer's result is not\n * YAMLBYTE_OK, then the producer should stop */\ntypedef\n  yamlbyte_result_t\n   (*yamlbyte_pushbuff_t)(\n     yamlbyte_consumer_t self,\n     yamlbyte_buff_t  buff\n   );\n\n/* consumer pulls bytecode events from the producer; in this case\n * the buffer is owned by the producer, and will remain valid till\n * the pull function is called once again; if the buffer pointer\n * is set to NULL, then there are no more results; it is important\n * to call the pull function till it returns NULL so that the\n * producer can clean up its memory allocations */\ntypedef \n   yamlbyte_result_t\n    (*yamlbyte_pullbuff_t)(\n      yamlbyte_producer_t self,\n      yamlbyte_buff_t *buff   /* to be filled in by the producer */\n    ); \n\n/* convert a pull interface to a push interface; the reverse process\n * requires threads and thus is language dependent */\n#define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result)       \\\n    do {                                                         \\\n        yamlbyte_pullbuff_t _pull = (pull);                              \\\n        yamlbyte_pushbuff_t _push = (push);                              \\\n        yamlbyte_result_t _result = YAMLBYTE_OK;                         \\\n        yamlbyte_producer_t _producer = (producer);                  \\\n        yamlbyte_consumer_t _consumer = (consumer);                  \\\n        while(1) {                                               \\\n            yamlbyte_buff_t buff = NULL;                           \\\n            _result = _pull(_producer,&buff);                    \\\n            if(YAMLBYTE_OK != result || NULL == buff)                \\\n                break;                                           \\\n            _result = _push(_consumer,buff);                     \\\n            if(YAMLBYTE_OK != result)                                \\\n                break;                                           \\\n        }                                                        \\\n        (result) = _result;                                      \\\n    } while(0)\n\n#endif\n"
  },
  {
    "path": "ext/syslog/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/syslog/depend",
    "content": "syslog.o: syslog.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h \\\n  $(hdrdir)/intern.h\n"
  },
  {
    "path": "ext/syslog/extconf.rb",
    "content": "# $RoughId: extconf.rb,v 1.3 2001/11/24 17:49:26 knu Exp $\n# $Id$\n\nrequire 'mkmf'\n\nhave_header(\"syslog.h\") &&\n  have_func(\"openlog\") &&\n  have_func(\"setlogmask\") &&\n  create_makefile(\"syslog\")\n\n"
  },
  {
    "path": "ext/syslog/syslog.c",
    "content": "/* \n * UNIX Syslog extension for Ruby\n * Amos Gouaux, University of Texas at Dallas\n * <amos+ruby@utdallas.edu>\n *\n * $RoughId: syslog.c,v 1.21 2002/02/25 12:21:17 knu Exp $\n * $Id$\n */\n\n#include \"ruby.h\"\n#include \"util.h\"\n#include <syslog.h>\n\n/* Syslog class */\nstatic VALUE mSyslog, mSyslogConstants;\nstatic const char *syslog_ident = NULL;\nstatic int syslog_options = -1, syslog_facility = -1, syslog_mask = -1;\nstatic int syslog_opened = 0;\n\n/* Package helper routines */\nstatic void syslog_write(int pri, int argc, VALUE *argv)\n{\n    VALUE str;\n\n    rb_secure(4);\n    if (argc < 1) {\n        rb_raise(rb_eArgError, \"no log message supplied\");\n    }\n\n    if (!syslog_opened) {\n        rb_raise(rb_eRuntimeError, \"must open syslog before write\");\n    }\n\n    str = rb_f_sprintf(argc, argv);\n\n    syslog(pri, \"%s\", RSTRING(str)->ptr);\n}\n\n/* Syslog module methods */\nstatic VALUE mSyslog_close(VALUE self)\n{\n    rb_secure(4);\n    if (!syslog_opened) {\n        rb_raise(rb_eRuntimeError, \"syslog not opened\");\n    }\n\n    closelog();\n\n    free((void *)syslog_ident);\n    syslog_ident = NULL;\n    syslog_options = syslog_facility = syslog_mask = -1;\n    syslog_opened = 0;\n\n    return Qnil;\n}\n\nstatic VALUE mSyslog_open(int argc, VALUE *argv, VALUE self)\n{\n    VALUE ident, opt, fac;\n\n    if (syslog_opened) {\n        rb_raise(rb_eRuntimeError, \"syslog already open\");\n    }\n\n    rb_scan_args(argc, argv, \"03\", &ident, &opt, &fac);\n\n    if (NIL_P(ident)) {\n        ident = rb_gv_get(\"$0\"); \n    }\n#ifdef SafeStringValue\n    SafeStringValue(ident);\n#else\n    Check_SafeStr(ident);\n#endif\n    syslog_ident = strdup(RSTRING(ident)->ptr);\n\n    if (NIL_P(opt)) {\n\tsyslog_options = LOG_PID | LOG_CONS;\n    } else {\n\tsyslog_options = NUM2INT(opt);\n    }\n\n    if (NIL_P(fac)) {\n\tsyslog_facility = LOG_USER;\n    } else {\n\tsyslog_facility = NUM2INT(fac);\n    }\n\n    openlog(syslog_ident, syslog_options, syslog_facility);\n\n    syslog_opened = 1;\n\n    setlogmask(syslog_mask = setlogmask(0));\n\n    /* be like File.new.open {...} */\n    if (rb_block_given_p()) {\n        rb_ensure(rb_yield, self, mSyslog_close, self);\n    }\n\n    return self;\n}\n\nstatic VALUE mSyslog_reopen(int argc, VALUE *argv, VALUE self)\n{\n    mSyslog_close(self);\n\n    return mSyslog_open(argc, argv, self);\n}\n\nstatic VALUE mSyslog_isopen(VALUE self)\n{\n    return syslog_opened ? Qtrue : Qfalse;\n}\n\nstatic VALUE mSyslog_ident(VALUE self)\n{\n    return syslog_opened ? rb_str_new2(syslog_ident) : Qnil;\n}\n\nstatic VALUE mSyslog_options(VALUE self)\n{\n    return syslog_opened ? INT2NUM(syslog_options) : Qnil;\n}\n\nstatic VALUE mSyslog_facility(VALUE self)\n{\n    return syslog_opened ? INT2NUM(syslog_facility) : Qnil;\n}\n\nstatic VALUE mSyslog_get_mask(VALUE self)\n{\n    return syslog_opened ? INT2NUM(syslog_mask) : Qnil;\n}\n\nstatic VALUE mSyslog_set_mask(VALUE self, VALUE mask)\n{\n    rb_secure(4);\n    if (!syslog_opened) {\n        rb_raise(rb_eRuntimeError, \"must open syslog before setting log mask\");\n    }\n\n    setlogmask(syslog_mask = NUM2INT(mask));\n\n    return mask;\n}\n\nstatic VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)\n{\n    VALUE pri;\n\n    if (argc < 2) {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 2+)\", argc);\n    }\n\n    argc--;\n    pri = *argv++;\n\n    if (!FIXNUM_P(pri)) {\n      rb_raise(rb_eTypeError, \"type mismatch: %s given\", rb_class2name(CLASS_OF(pri)));\n    }\n\n    syslog_write(FIX2INT(pri), argc, argv);\n\n    return self;\n}\n\nstatic VALUE mSyslog_inspect(VALUE self)\n{\n    char buf[1024];\n\n    if (syslog_opened) {\n\tsnprintf(buf, sizeof(buf),\n\t  \"<#%s: opened=true, ident=\\\"%s\\\", options=%d, facility=%d, mask=%d>\",\n\t  rb_class2name(self),\n\t  syslog_ident,\n\t  syslog_options,\n\t  syslog_facility,\n\t  syslog_mask);\n    } else {\n\tsnprintf(buf, sizeof(buf),\n\t  \"<#%s: opened=false>\", rb_class2name(self));\n    }\n\n    return rb_str_new2(buf);\n}\n\nstatic VALUE mSyslog_instance(VALUE self)\n{\n    return self;\n}\n\n#define define_syslog_shortcut_method(pri, name) \\\nstatic VALUE mSyslog_##name(int argc, VALUE *argv, VALUE self) \\\n{ \\\n    syslog_write(pri, argc, argv); \\\n\\\n    return self; \\\n}\n\n#ifdef LOG_EMERG\ndefine_syslog_shortcut_method(LOG_EMERG, emerg)\n#endif\n#ifdef LOG_ALERT\ndefine_syslog_shortcut_method(LOG_ALERT, alert)\n#endif\n#ifdef LOG_CRIT\ndefine_syslog_shortcut_method(LOG_CRIT, crit)\n#endif\n#ifdef LOG_ERR\ndefine_syslog_shortcut_method(LOG_ERR, err)\n#endif\n#ifdef LOG_WARNING\ndefine_syslog_shortcut_method(LOG_WARNING, warning)\n#endif\n#ifdef LOG_NOTICE\ndefine_syslog_shortcut_method(LOG_NOTICE, notice)\n#endif\n#ifdef LOG_INFO\ndefine_syslog_shortcut_method(LOG_INFO, info)\n#endif\n#ifdef LOG_DEBUG\ndefine_syslog_shortcut_method(LOG_DEBUG, debug)\n#endif\n\nstatic VALUE mSyslogConstants_LOG_MASK(VALUE klass, VALUE pri)\n{\n    return INT2FIX(LOG_MASK(FIX2INT(pri)));\n}\n\nstatic VALUE mSyslogConstants_LOG_UPTO(VALUE klass, VALUE pri)\n{\n    return INT2FIX(LOG_UPTO(FIX2INT(pri)));\n}\n\n/* Init for package syslog */\nvoid Init_syslog()\n{\n    mSyslog = rb_define_module(\"Syslog\");\n \n    mSyslogConstants = rb_define_module_under(mSyslog, \"Constants\");\n\n    rb_include_module(mSyslog, mSyslogConstants);\n\n    rb_define_module_function(mSyslog, \"open\", mSyslog_open, -1);\n    rb_define_module_function(mSyslog, \"reopen\", mSyslog_reopen, -1);\n    rb_define_module_function(mSyslog, \"open!\", mSyslog_reopen, -1);\n    rb_define_module_function(mSyslog, \"opened?\", mSyslog_isopen, 0);\n\n    rb_define_module_function(mSyslog, \"ident\", mSyslog_ident, 0);\n    rb_define_module_function(mSyslog, \"options\", mSyslog_options, 0);\n    rb_define_module_function(mSyslog, \"facility\", mSyslog_facility, 0);\n\n    rb_define_module_function(mSyslog, \"log\", mSyslog_log, -1);\n    rb_define_module_function(mSyslog, \"close\", mSyslog_close, 0);\n    rb_define_module_function(mSyslog, \"mask\", mSyslog_get_mask, 0);\n    rb_define_module_function(mSyslog, \"mask=\", mSyslog_set_mask, 1);\n\n    rb_define_module_function(mSyslog, \"LOG_MASK\", mSyslogConstants_LOG_MASK, 1);\n    rb_define_module_function(mSyslog, \"LOG_UPTO\", mSyslogConstants_LOG_UPTO, 1);\n\n    rb_define_module_function(mSyslog, \"inspect\", mSyslog_inspect, 0);\n    rb_define_module_function(mSyslog, \"instance\", mSyslog_instance, 0);\n\n    rb_define_module_function(mSyslogConstants, \"LOG_MASK\", mSyslogConstants_LOG_MASK, 1);\n    rb_define_module_function(mSyslogConstants, \"LOG_UPTO\", mSyslogConstants_LOG_UPTO, 1);\n\n#define rb_define_syslog_const(id) \\\n    rb_define_const(mSyslogConstants, #id, INT2NUM(id))\n\n    /* Various options when opening log */\n#ifdef LOG_PID\n    rb_define_syslog_const(LOG_PID);\n#endif\n#ifdef LOG_CONS\n    rb_define_syslog_const(LOG_CONS);\n#endif\n#ifdef LOG_ODELAY\n    rb_define_syslog_const(LOG_ODELAY); /* deprecated */\n#endif\n#ifdef LOG_NDELAY\n    rb_define_syslog_const(LOG_NDELAY);\n#endif\n#ifdef LOG_NOWAIT\n    rb_define_syslog_const(LOG_NOWAIT); /* deprecated */\n#endif\n#ifdef LOG_PERROR\n    rb_define_syslog_const(LOG_PERROR);\n#endif\n\n    /* Various syslog facilities */\n#ifdef LOG_AUTH\n    rb_define_syslog_const(LOG_AUTH);\n#endif\n#ifdef LOG_AUTHPRIV\n    rb_define_syslog_const(LOG_AUTHPRIV);\n#endif\n#ifdef LOG_CONSOLE\n    rb_define_syslog_const(LOG_CONSOLE);\n#endif\n#ifdef LOG_CRON\n    rb_define_syslog_const(LOG_CRON);\n#endif\n#ifdef LOG_DAEMON\n    rb_define_syslog_const(LOG_DAEMON);\n#endif\n#ifdef LOG_FTP\n    rb_define_syslog_const(LOG_FTP);\n#endif\n#ifdef LOG_KERN\n    rb_define_syslog_const(LOG_KERN);\n#endif\n#ifdef LOG_LPR\n    rb_define_syslog_const(LOG_LPR);\n#endif\n#ifdef LOG_MAIL\n    rb_define_syslog_const(LOG_MAIL);\n#endif\n#ifdef LOG_NEWS\n    rb_define_syslog_const(LOG_NEWS);\n#endif\n#ifdef LOG_NTP\n   rb_define_syslog_const(LOG_NTP);\n#endif\n#ifdef LOG_SECURITY\n    rb_define_syslog_const(LOG_SECURITY);\n#endif\n#ifdef LOG_SYSLOG\n    rb_define_syslog_const(LOG_SYSLOG);\n#endif\n#ifdef LOG_USER\n    rb_define_syslog_const(LOG_USER);\n#endif\n#ifdef LOG_UUCP\n    rb_define_syslog_const(LOG_UUCP);\n#endif\n#ifdef LOG_LOCAL0\n    rb_define_syslog_const(LOG_LOCAL0);\n#endif\n#ifdef LOG_LOCAL1\n    rb_define_syslog_const(LOG_LOCAL1);\n#endif\n#ifdef LOG_LOCAL2\n    rb_define_syslog_const(LOG_LOCAL2);\n#endif\n#ifdef LOG_LOCAL3\n    rb_define_syslog_const(LOG_LOCAL3);\n#endif\n#ifdef LOG_LOCAL4\n    rb_define_syslog_const(LOG_LOCAL4);\n#endif\n#ifdef LOG_LOCAL5\n    rb_define_syslog_const(LOG_LOCAL5);\n#endif\n#ifdef LOG_LOCAL6\n    rb_define_syslog_const(LOG_LOCAL6);\n#endif\n#ifdef LOG_LOCAL7\n    rb_define_syslog_const(LOG_LOCAL7);\n#endif\n\n#define rb_define_syslog_shortcut(name) \\\n    rb_define_module_function(mSyslog, #name, mSyslog_##name, -1)\n\n    /* Various syslog priorities and the shortcut methods */\n#ifdef LOG_EMERG\n    rb_define_syslog_const(LOG_EMERG);\n    rb_define_syslog_shortcut(emerg);\n#endif\n#ifdef LOG_ALERT\n    rb_define_syslog_const(LOG_ALERT);\n    rb_define_syslog_shortcut(alert);\n#endif\n#ifdef LOG_CRIT\n    rb_define_syslog_const(LOG_CRIT);\n    rb_define_syslog_shortcut(crit);\n#endif\n#ifdef LOG_ERR\n    rb_define_syslog_const(LOG_ERR);\n    rb_define_syslog_shortcut(err);\n#endif\n#ifdef LOG_WARNING\n    rb_define_syslog_const(LOG_WARNING);\n    rb_define_syslog_shortcut(warning);\n#endif\n#ifdef LOG_NOTICE\n    rb_define_syslog_const(LOG_NOTICE);\n    rb_define_syslog_shortcut(notice);\n#endif\n#ifdef LOG_INFO\n    rb_define_syslog_const(LOG_INFO);\n    rb_define_syslog_shortcut(info);\n#endif\n#ifdef LOG_DEBUG\n    rb_define_syslog_const(LOG_DEBUG);\n    rb_define_syslog_shortcut(debug);\n#endif\n}\n"
  },
  {
    "path": "ext/syslog/syslog.txt",
    "content": ".\\\" syslog.txt -  -*- Indented-Text -*-\n$RoughId: syslog.txt,v 1.18 2002/02/25 08:20:14 knu Exp $\n$Id$\n\nUNIX Syslog extension for Ruby\nAmos Gouaux, University of Texas at Dallas\n<amos+ruby@utdallas.edu>\n&\nAkinori MUSHA\n<knu@iDaemons.org>\n\nContact:\n  - Akinori MUSHA <knu@iDaemons.org> (current maintainer)\n\n** Syslog(Module)\n\nIncluded Modules: Syslog::Constants\n\nrequire 'syslog'\n\nA Simple wrapper for the UNIX syslog system calls that might be handy\nif you're writing a server in Ruby.  For the details of the syslog(8)\narchitecture and constants, see the syslog(3) manual page of your\nplatform.\n\nModule Methods:\n\n   open(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS,\n\t\tfacility = Syslog::LOG_USER) [{ |syslog| ... }]\n\n\tOpens syslog with the given options and returns the module\n\titself.  If a block is given, calls it with an argument of\n\titself.  If syslog is already opened, raises RuntimeError.\n\n\tExample:\n\t  Syslog.open('ftpd', Syslog::LOG_PID | Syslog::LOG_NDELAY,\n\t\t\t      Syslog::LOG_FTP)\n\n   open!(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS,\n\t\tfacility = Syslog::LOG_USER)\n   reopen(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS,\n\t\tfacility = Syslog::LOG_USER)\n\n\tSame as open, but does a close first.\n\n   opened?\n\n\tReturns true if syslog opened, otherwise false.\n\n   ident\n   options\n   facility\n\n\tReturns the parameters given in the last open, respectively.\n\tEvery call of Syslog::open resets these values.\n\n   log(pri, message, ...)\n\n\tWrites message to syslog.\n\n\tExample:\n\t  Syslog.log(Syslog::LOG_CRIT, \"the sky is falling in %d seconds!\", 10)\n\n   crit(message, ...)\n   emerg(message, ...)\n   alert(message, ...)\n   err(message, ...)\n   warning(message, ...)\n   notice(message, ...)\n   info(message, ...)\n   debug(message, ...)\n\n\tThese are shortcut methods of Syslog::log().  The lineup may\n\tvary depending on what priorities are defined on your system.\n\n\tExample:\n\t  Syslog.crit(\"the sky is falling in %d seconds!\", 5)\n \n   mask\n   mask=(mask)\n\n\tReturns or sets the log priority mask.  The value of the mask\n\tis persistent and will not be reset by Syslog::open or\n\tSyslog::close.\n\n\tExample:\n\t  Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)\n\n   close \n\n\tCloses syslog.\n\n   inspect\n\n\tReturns the \"inspect\" string of the Syslog module.\n\n   instance\n\n\tReturns the module itself. (Just for backward compatibility)\n\n   LOG_MASK(pri)\n\n\tCreates a mask for one priority.\n\n   LOG_UPTO(pri)\n\n\tCreates a mask for all priorities up to pri.\n\n** Syslog::Constants(Module)\n\nrequire 'syslog'\ninclude Syslog::Constants\n\nThis module includes the LOG_* constants available on the system.\n\nModule Methods:\n\n   LOG_MASK(pri)\n\n\tCreates a mask for one priority.\n\n   LOG_UPTO(pri)\n\n\tCreates a mask for all priorities up to pri.\n"
  },
  {
    "path": "ext/syslog/test.rb",
    "content": "#!/usr/bin/env ruby\n# $RoughId: test.rb,v 1.9 2002/02/25 08:20:14 knu Exp $\n# $Id$\n\n# Please only run this test on machines reasonable for testing.\n# If in doubt, ask your admin.\n\nrequire 'test/unit'\n\n# Prepend current directory to load path for testing.\n$:.unshift('.')\n\nrequire 'syslog'\n\nclass TestSyslog < Test::Unit::TestCase\n  def test_new\n    assert_raises(NoMethodError) {\n      Syslog.new\n    }\n  end\n\n  def test_instance\n    sl1 = Syslog.instance\n    sl2 = Syslog.open\n    sl3 = Syslog.instance\n\n    assert_equal(Syslog, sl1)\n    assert_equal(Syslog, sl2)\n    assert_equal(Syslog, sl3)\n  ensure\n    Syslog.close if Syslog.opened?\n  end\n\n  def test_open\n    # default parameters\n    Syslog.open\n\n    assert_equal($0, Syslog.ident)\n    assert_equal(Syslog::LOG_PID | Syslog::LOG_CONS, Syslog.options)\n    assert_equal(Syslog::LOG_USER, Syslog.facility)\n\n    # open without close\n    assert_raises(RuntimeError) {\n      Syslog.open\n    }\n\n    Syslog.close\n\n    # given parameters\n    Syslog.open(\"foo\", Syslog::LOG_NDELAY | Syslog::LOG_PERROR, Syslog::LOG_DAEMON) \n\n    assert_equal('foo', Syslog.ident)\n    assert_equal(Syslog::LOG_NDELAY | Syslog::LOG_PERROR, Syslog.options)\n    assert_equal(Syslog::LOG_DAEMON, Syslog.facility)\n\n    Syslog.close\n\n    # default parameters again (after close)\n    Syslog.open\n    Syslog.close\n\n    assert_equal(nil, Syslog.ident)\n    assert_equal(nil, Syslog.options)\n    assert_equal(nil, Syslog.facility)\n\n    # block\n    param = nil\n    Syslog.open { |param| }\n    assert_equal(Syslog, param)\n  ensure\n    Syslog.close if Syslog.opened?\n  end\n\n  def test_opened?\n    assert_equal(false, Syslog.opened?)\n\n    Syslog.open\n    assert_equal(true, Syslog.opened?)\n\n    Syslog.close\n    assert_equal(false, Syslog.opened?)\n\n    Syslog.open {\n      assert_equal(true, Syslog.opened?)\n    }\n\n    assert_equal(false, Syslog.opened?)\n  end\n\n  def test_close\n    assert_raises(RuntimeError) {\n      Syslog.close\n    }\n  end\n\n  def test_mask\n    assert_equal(nil, Syslog.mask)\n\n    Syslog.open\n\n    orig = Syslog.mask\n\n    Syslog.mask = Syslog.LOG_UPTO(Syslog::LOG_ERR)\n    assert_equal(Syslog.LOG_UPTO(Syslog::LOG_ERR), Syslog.mask)\n\n    Syslog.mask = Syslog.LOG_MASK(Syslog::LOG_CRIT)\n    assert_equal(Syslog.LOG_MASK(Syslog::LOG_CRIT), Syslog.mask)\n\n    Syslog.mask = orig\n  ensure\n    Syslog.close if Syslog.opened?\n  end\n\n  def test_log\n    stderr = IO::pipe\n\n    pid = fork {\n      stderr[0].close\n      STDERR.reopen(stderr[1])\n      stderr[1].close\n\n      options = Syslog::LOG_PERROR | Syslog::LOG_NDELAY\n\n      Syslog.open(\"syslog_test\", options) { |sl|\n\tsl.log(Syslog::LOG_NOTICE, \"test1 - hello, %s!\", \"world\")\n\tsl.notice(\"test1 - hello, %s!\", \"world\")\n      }\n\n      Syslog.open(\"syslog_test\", options | Syslog::LOG_PID) { |sl|\n\tsl.log(Syslog::LOG_CRIT, \"test2 - pid\")\n\tsl.crit(\"test2 - pid\")\n      }\n      exit!\n    }\n\n    stderr[1].close\n    Process.waitpid(pid)\n\n    # LOG_PERROR is not yet implemented on Cygwin.\n    return if RUBY_PLATFORM =~ /cygwin/\n\n    2.times {\n      assert_equal(\"syslog_test: test1 - hello, world!\\n\", stderr[0].gets)\n    }\n\n    2.times {\n      assert_equal(format(\"syslog_test[%d]: test2 - pid\\n\", pid), stderr[0].gets)\n    }\n  end\n\n  def test_inspect\n    Syslog.open { |sl|\n      assert_equal(format('<#%s: opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>',\n\t\t\t  Syslog,\n\t\t\t  sl.ident,\n\t\t\t  sl.options,\n\t\t\t  sl.facility,\n\t\t\t  sl.mask),\n\t\t   sl.inspect)\n    }\n\n    assert_equal(format('<#%s: opened=false>', Syslog), Syslog.inspect)\n  end\nend\n"
  },
  {
    "path": "ext/thread/extconf.rb",
    "content": "require 'mkmf'\n\nenable_config('fastthread', true) or exit\n\nif with_config('mem-pools', true)\n  $CPPFLAGS << ' -DUSE_MEM_POOLS'\nend\n\ncreate_makefile(\"thread\")\n"
  },
  {
    "path": "ext/thread/lib/thread.rb",
    "content": "unless defined? Thread\n  fail \"Thread not available for this ruby interpreter\"\nend\n\nrequire 'thread.so'\n"
  },
  {
    "path": "ext/thread/thread.c",
    "content": "/*\n * Optimized Ruby Mutex implementation, loosely based on thread.rb by\n * Yukihiro Matsumoto <matz@ruby-lang.org>\n *\n *  Copyright 2006-2007  MenTaLguY <mental@rydia.net>\n *\n * RDoc taken from original.\n *\n * This file is made available under the same terms as Ruby.\n */\n\n#include <ruby.h>\n#include <intern.h>\n#include <rubysig.h>\n\nstatic VALUE rb_cMutex;\nstatic VALUE rb_cConditionVariable;\nstatic VALUE rb_cQueue;\nstatic VALUE rb_cSizedQueue;\n\nstatic VALUE set_critical(VALUE value);\n\nstatic VALUE\nthread_exclusive(VALUE (*func)(ANYARGS), VALUE arg)\n{\n    VALUE critical = rb_thread_critical;\n\n    rb_thread_critical = 1;\n    return rb_ensure(func, arg, set_critical, (VALUE)critical);\n}\n\n/*\n *  call-seq:\n *     Thread.exclusive { block }   => obj\n *  \n *  Wraps a block in Thread.critical, restoring the original value\n *  upon exit from the critical section, and returns the value of the\n *  block.\n */\n\nstatic VALUE\nrb_thread_exclusive(void)\n{\n    return thread_exclusive(rb_yield, Qundef);\n}\n\ntypedef struct _Entry {\n    VALUE value;\n    struct _Entry *next;\n} Entry;\n\ntypedef struct _List {\n    Entry *entries;\n    Entry *last_entry;\n    Entry *entry_pool;\n    unsigned long size;\n} List;\n\nstatic void\ninit_list(List *list)\n{\n    list->entries = NULL;\n    list->last_entry = NULL;\n    list->entry_pool = NULL;\n    list->size = 0;\n}\n\nstatic void\nmark_list(List *list)\n{\n    Entry *entry;\n    for (entry = list->entries; entry; entry = entry->next) {\n        rb_gc_mark(entry->value);\n    }\n}\n\nstatic void\nfree_entries(Entry *first)\n{\n    Entry *next;\n    while (first) {\n        next = first->next;\n        xfree(first);\n        first = next;\n    }\n}\n\nstatic void\nfinalize_list(List *list)\n{\n    free_entries(list->entries);\n    free_entries(list->entry_pool);\n}\n\nstatic void\npush_list(List *list, VALUE value)\n{\n    Entry *entry;\n\n    if (list->entry_pool) {\n        entry = list->entry_pool;\n        list->entry_pool = entry->next;\n    } else {\n        entry = ALLOC(Entry);\n    }\n\n    entry->value = value;\n    entry->next = NULL;\n\n    if (list->last_entry) {\n        list->last_entry->next = entry;\n    } else {\n        list->entries = entry;\n    }\n    list->last_entry = entry;\n\n    ++list->size;\n}\n\nstatic void\npush_multiple_list(List *list, VALUE *values, unsigned count)\n{\n    unsigned i;\n    for (i = 0; i < count; i++) {\n        push_list(list, values[i]);\n    }\n}\n\nstatic void\nrecycle_entries(List *list, Entry *first_entry, Entry *last_entry)\n{\n#ifdef USE_MEM_POOLS\n    last_entry->next = list->entry_pool;\n    list->entry_pool = first_entry;\n#else\n    last_entry->next = NULL;\n    free_entries(first_entry);\n#endif\n}\n\nstatic VALUE\nshift_list(List *list)\n{\n    Entry *entry;\n    VALUE value;\n\n    entry = list->entries;\n    if (!entry) return Qnil;\n\n    list->entries = entry->next;\n    if (entry == list->last_entry) {\n        list->last_entry = NULL;\n    }\n\n    --list->size;\n\n    value = entry->value;\n    recycle_entries(list, entry, entry);\n\n    return value;\n}\n\nstatic void\nremove_one(List *list, VALUE value)\n{\n    Entry **ref;\n    Entry *prev;\n    Entry *entry;\n\n    for (ref = &list->entries, prev = NULL, entry = list->entries;\n              entry != NULL;\n              ref = &entry->next, prev = entry, entry = entry->next) {\n        if (entry->value == value) {\n            *ref = entry->next;\n            list->size--;\n            if (!entry->next) {\n                list->last_entry = prev;\n            }\n            recycle_entries(list, entry, entry);\n            break;\n        }\n    }\n}\n\nstatic void\nclear_list(List *list)\n{\n    if (list->last_entry) {\n        recycle_entries(list, list->entries, list->last_entry);\n        list->entries = NULL;\n        list->last_entry = NULL;\n        list->size = 0;\n    }\n}\n\nstatic VALUE\narray_from_list(List const *list)\n{\n    VALUE ary;\n    Entry *entry;\n    ary = rb_ary_new();\n    for (entry = list->entries; entry; entry = entry->next) {\n        rb_ary_push(ary, entry->value);\n    }\n    return ary;\n}\n\nstatic void\nadjust_join(const List *list, VALUE new)\n{\n    extern void rb_thread_set_join _((VALUE, VALUE));\n    Entry *entry;\n    for (entry = list->entries; entry; entry = entry->next) {\n\trb_thread_set_join(entry->value, new);\n    }\n}\n\nstatic VALUE\nwake_thread(VALUE thread)\n{\n    return rb_thread_wakeup_alive(thread);\n}\n\nstatic VALUE\nrun_thread(VALUE thread)\n{\n    thread = wake_thread(thread);\n    if (RTEST(thread) && !rb_thread_critical)\n\trb_thread_schedule();\n    return thread;\n}\n\nstatic VALUE\nwake_one(List *list)\n{\n    VALUE waking;\n\n    waking = Qnil;\n    while (list->entries && !RTEST(waking)) {\n\twaking = wake_thread(shift_list(list));\n    }\n\n    return waking;\n}\n\nstatic VALUE\nwake_all(List *list)\n{\n    while (list->entries) {\n        wake_one(list);\n    }\n    return Qnil;\n}\n\nextern int rb_thread_join _((VALUE thread, double limit));\n#define DELAY_INFTY 1E30\n\nstatic VALUE\nwait_list_inner(VALUE arg)\n{\n    push_list((List *)arg, rb_thread_current());\n    rb_thread_stop();\n    return Qnil;\n}\n\nstatic VALUE\nwait_list_cleanup(VALUE arg)\n{\n    /* cleanup in case of spurious wakeups */\n    remove_one((List *)arg, rb_thread_current());\n    return Qnil;\n}\n\nstatic VALUE\nwait_list(List *list)\n{\n    return rb_ensure(wait_list_inner, (VALUE)list, wait_list_cleanup, (VALUE)list);\n}\n\nstatic void\nkill_waiting_threads(List *waiting)\n{\n    Entry *entry;\n\n    for (entry = waiting->entries; entry; entry = entry->next) {\n\trb_thread_kill(entry->value);\n    }\n}\n\n/*\n * Document-class: Mutex\n *\n * Mutex implements a simple semaphore that can be used to coordinate access to\n * shared data from multiple concurrent threads.\n *\n * Example:\n *\n *   require 'thread'\n *   semaphore = Mutex.new\n *\n *   a = Thread.new {\n *     semaphore.synchronize {\n *       # access shared resource\n *     }\n *   }\n *\n *   b = Thread.new {\n *     semaphore.synchronize {\n *       # access shared resource\n *     }\n *   }\n *\n */\n\ntypedef struct _Mutex {\n    VALUE owner;\n    List waiting;\n} Mutex;\n\n#define MUTEX_LOCKED_P(mutex) (RTEST((mutex)->owner) && rb_thread_alive_p((mutex)->owner))\n\nstatic void\nmark_mutex(Mutex *mutex)\n{\n    rb_gc_mark(mutex->owner);\n    mark_list(&mutex->waiting);\n}\n\nstatic void\nfinalize_mutex(Mutex *mutex)\n{\n    finalize_list(&mutex->waiting);\n}\n\nstatic void\nfree_mutex(Mutex *mutex)\n{\n    kill_waiting_threads(&mutex->waiting);\n    finalize_mutex(mutex);\n    xfree(mutex);\n}\n\nstatic void\ninit_mutex(Mutex *mutex)\n{\n    mutex->owner = Qnil;\n    init_list(&mutex->waiting);\n}\n\n/*\n * Document-method: new\n * call-seq: Mutex.new\n * \n * Creates a new Mutex\n *\n */\n\nstatic VALUE \nrb_mutex_alloc(VALUE klass)\n{\n    Mutex *mutex;\n    mutex = ALLOC(Mutex);\n    init_mutex(mutex);\n    return Data_Wrap_Struct(klass, mark_mutex, free_mutex, mutex);\n}\n\n/*\n * Document-method: locked?\n * call-seq: locked?\n *\n * Returns +true+ if this lock is currently held by some thread.\n *\n */\n\nstatic VALUE\nrb_mutex_locked_p(VALUE self)\n{\n    Mutex *mutex;\n    Data_Get_Struct(self, Mutex, mutex);\n    return MUTEX_LOCKED_P(mutex) ? Qtrue : Qfalse;\n}\n\n/*\n * Document-method: try_lock\n * call-seq: try_lock\n *\n * Attempts to obtain the lock and returns immediately. Returns +true+ if the\n * lock was granted.\n *\n */\n\nstatic VALUE\nrb_mutex_try_lock(VALUE self)\n{\n    Mutex *mutex;\n\n    Data_Get_Struct(self, Mutex, mutex);\n\n    if (MUTEX_LOCKED_P(mutex))\n        return Qfalse;\n\n    mutex->owner = rb_thread_current();\n    return Qtrue;\n}\n\nstatic VALUE\nwait_mutex(VALUE arg)\n{\n    Mutex *mutex = (Mutex *)arg;\n    VALUE current = rb_thread_current();\n\n    push_list(&mutex->waiting, current);\n    do {\n\trb_thread_critical = 0;\n\trb_thread_join(mutex->owner, DELAY_INFTY);\n\trb_thread_critical = 1;\n\tif (!MUTEX_LOCKED_P(mutex)) {\n\t    mutex->owner = current;\n\t    break;\n\t}\n    } while (mutex->owner != current);\n    return Qnil;\n}\n\n/*\n * Document-method: lock\n * call-seq: lock\n *\n * Attempts to grab the lock and waits if it isn't available.\n *\n */\n\nstatic VALUE\nlock_mutex(Mutex *mutex)\n{\n    VALUE current;\n    current = rb_thread_current();\n\n    rb_thread_critical = 1;\n\n    if (!MUTEX_LOCKED_P(mutex)) {\n\tmutex->owner = current;\n    }\n    else {\n\trb_ensure(wait_mutex, (VALUE)mutex, wait_list_cleanup, (VALUE)&mutex->waiting);\n    }\n\n    rb_thread_critical = 0;\n    return Qnil;\n}\n\nstatic VALUE\nlock_mutex_call(VALUE mutex)\n{\n    return lock_mutex((Mutex *)mutex);\n}\n\nstatic VALUE\nrb_mutex_lock(VALUE self)\n{\n    Mutex *mutex;\n    Data_Get_Struct(self, Mutex, mutex);\n    lock_mutex(mutex);\n    return self;\n}\n\n/*\n * Document-method: unlock\n *\n * Releases the lock. Returns +nil+ if ref wasn't locked.\n *\n */\n\nstatic VALUE\nunlock_mutex_inner(Mutex *mutex)\n{\n    VALUE waking;\n\n    if (mutex->owner != rb_thread_current()) {\n\trb_raise(rb_eThreadError, \"not owner\");\n    }\n\n    waking = wake_one(&mutex->waiting);\n\n    if (!NIL_P(waking)) {\n\tadjust_join(&mutex->waiting, waking);\n    }\n\n    mutex->owner = waking;\n\n    return waking;\n}\n\nstatic VALUE\nset_critical(VALUE value)\n{\n    rb_thread_critical = (int)value;\n    return Qundef;\n}\n\nstatic VALUE\nunlock_mutex(Mutex *mutex)\n{\n    VALUE waking = thread_exclusive(unlock_mutex_inner, (VALUE)mutex);\n\n    if (!RTEST(waking)) {\n        return Qfalse;\n    }\n\n    run_thread(waking);\n\n    return Qtrue;\n}\n\nstatic VALUE\nunlock_mutex_call(VALUE mutex)\n{\n    return unlock_mutex((Mutex *)mutex);\n}\n\nstatic VALUE\nrb_mutex_unlock(VALUE self)\n{\n    Mutex *mutex;\n    Data_Get_Struct(self, Mutex, mutex);\n\n    if (RTEST(unlock_mutex(mutex))) {\n        return self;\n    } else {\n        return Qnil;\n    }\n}\n\n/*\n * Document-method: exclusive_unlock\n * call-seq: exclusive_unlock { ... }\n *\n * If the mutex is locked, unlocks the mutex, wakes one waiting thread, and\n * yields in a critical section.\n *\n */\n\nstatic VALUE\nrb_mutex_exclusive_unlock_inner(Mutex *mutex)\n{\n    VALUE waking;\n    waking = unlock_mutex_inner(mutex);\n    rb_yield(Qundef);\n    return waking;\n}\n\nstatic VALUE\nrb_mutex_exclusive_unlock(VALUE self)\n{\n    Mutex *mutex;\n    VALUE waking;\n    Data_Get_Struct(self, Mutex, mutex);\n\n    waking = thread_exclusive(rb_mutex_exclusive_unlock_inner, (VALUE)mutex);\n\n    if (!RTEST(waking)) {\n        return Qnil;\n    }\n\n    run_thread(waking);\n\n    return self;\n}\n\n/*\n * Document-method: synchronize\n * call-seq: synchronize { ... }\n *\n * Obtains a lock, runs the block, and releases the lock when the block\n * completes.  See the example under Mutex.\n *\n */\n\nstatic VALUE\nrb_mutex_synchronize(VALUE self)\n{\n    rb_mutex_lock(self);\n    return rb_ensure(rb_yield, Qundef, rb_mutex_unlock, self);\n}\n\n/*\n * Document-class: ConditionVariable\n *\n * ConditionVariable objects augment class Mutex. Using condition variables,\n * it is possible to suspend while in the middle of a critical section until a\n * resource becomes available.\n *\n * Example:\n *\n *   require 'thread'\n *\n *   mutex = Mutex.new\n *   resource = ConditionVariable.new\n *\n *   a = Thread.new {\n *     mutex.synchronize {\n *       # Thread 'a' now needs the resource\n *       resource.wait(mutex)\n *       # 'a' can now have the resource\n *     }\n *   }\n *\n *   b = Thread.new {\n *     mutex.synchronize {\n *       # Thread 'b' has finished using the resource\n *       resource.signal\n *     }\n *   }\n *\n */\n\ntypedef struct _ConditionVariable {\n    List waiting;\n} ConditionVariable;\n\nstatic void\nmark_condvar(ConditionVariable *condvar)\n{\n    mark_list(&condvar->waiting);\n}\n\nstatic void\nfinalize_condvar(ConditionVariable *condvar)\n{\n    finalize_list(&condvar->waiting);\n}\n\nstatic void\nfree_condvar(ConditionVariable *condvar)\n{\n    kill_waiting_threads(&condvar->waiting);\n    finalize_condvar(condvar);\n    xfree(condvar);\n}\n\nstatic void\ninit_condvar(ConditionVariable *condvar)\n{\n    init_list(&condvar->waiting);\n}\n\n/*\n * Document-method: new\n * call-seq: ConditionVariable.new\n *\n * Creates a new ConditionVariable\n *\n */\n\nstatic VALUE\nrb_condvar_alloc(VALUE klass)\n{\n    ConditionVariable *condvar;\n\n    condvar = ALLOC(ConditionVariable);\n    init_condvar(condvar);\n\n    return Data_Wrap_Struct(klass, mark_condvar, free_condvar, condvar);\n}\n\n/*\n * Document-method: wait\n * call-seq: wait\n *\n * Releases the lock held in +mutex+ and waits; reacquires the lock on wakeup.\n *\n */\n\nstatic void condvar_wakeup(Mutex *mutex);\n\nstatic void\nwait_condvar(ConditionVariable *condvar, Mutex *mutex)\n{\n    condvar_wakeup(mutex);\n    rb_ensure(wait_list, (VALUE)&condvar->waiting, lock_mutex_call, (VALUE)mutex);\n}\n\nstatic void\ncondvar_wakeup(Mutex *mutex)\n{\n    VALUE waking;\n\n    rb_thread_critical = 1;\n    if (rb_thread_current() != mutex->owner) {\n        rb_thread_critical = 0;\n        rb_raise(rb_eThreadError, \"not owner of the synchronization mutex\");\n    }\n    waking = unlock_mutex_inner(mutex);\n    if (RTEST(waking)) {\n\twake_thread(waking);\n    }\n}\n\nstatic VALUE\nlegacy_exclusive_unlock(VALUE mutex)\n{\n    return rb_funcall(mutex, rb_intern(\"exclusive_unlock\"), 0);\n}\n\ntypedef struct {\n    ConditionVariable *condvar;\n    VALUE mutex;\n} legacy_wait_args;\n\nstatic VALUE\nlegacy_wait(VALUE unused, legacy_wait_args *args)\n{\n    wait_list(&args->condvar->waiting);\n    rb_funcall(args->mutex, rb_intern(\"lock\"), 0);\n    return Qnil;\n}\n\nstatic VALUE\nrb_condvar_wait(VALUE self, VALUE mutex_v)\n{\n    ConditionVariable *condvar;\n    Data_Get_Struct(self, ConditionVariable, condvar);\n\n    if (CLASS_OF(mutex_v) != rb_cMutex) {\n        /* interoperate with legacy mutex */\n        legacy_wait_args args;\n        args.condvar = condvar;\n        args.mutex = mutex_v;\n        rb_iterate(legacy_exclusive_unlock, mutex_v, legacy_wait, (VALUE)&args);\n    } else {\n        Mutex *mutex;\n        Data_Get_Struct(mutex_v, Mutex, mutex);\n        wait_condvar(condvar, mutex);\n    }\n\n    return self;\n}\n\n/*\n * Document-method: broadcast\n * call-seq: broadcast\n *\n * Wakes up all threads waiting for this condition.\n *\n */\n\nstatic VALUE\nrb_condvar_broadcast(VALUE self)\n{\n    ConditionVariable *condvar;\n\n    Data_Get_Struct(self, ConditionVariable, condvar);\n  \n    thread_exclusive(wake_all, (VALUE)&condvar->waiting);\n    rb_thread_schedule();\n\n    return self;\n}\n\n/*\n * Document-method: signal\n * call-seq: signal\n *\n * Wakes up the first thread in line waiting for this condition.\n *\n */\n\nstatic void\nsignal_condvar(ConditionVariable *condvar)\n{\n    VALUE waking = thread_exclusive(wake_one, (VALUE)&condvar->waiting);\n\n    if (RTEST(waking)) {\n        run_thread(waking);\n    }\n}\n\nstatic VALUE\nsignal_condvar_call(VALUE condvar)\n{\n    signal_condvar((ConditionVariable *)condvar);\n    return Qundef;\n}\n\nstatic VALUE\nrb_condvar_signal(VALUE self)\n{\n    ConditionVariable *condvar;\n    Data_Get_Struct(self, ConditionVariable, condvar);\n    signal_condvar(condvar);\n    return self;\n}\n\n/*\n * Document-class: Queue\n *\n * This class provides a way to synchronize communication between threads.\n *\n * Example:\n *\n *   require 'thread'\n *\n *   queue = Queue.new\n *\n *   producer = Thread.new do\n *     5.times do |i|\n *       sleep rand(i) # simulate expense\n *       queue << i\n *       puts \"#{i} produced\"\n *     end\n *   end\n *\n *   consumer = Thread.new do\n *     5.times do |i|\n *       value = queue.pop\n *       sleep rand(i/2) # simulate expense\n *       puts \"consumed #{value}\"\n *     end\n *   end\n *\n *   consumer.join\n *\n */\n\ntypedef struct _Queue {\n    Mutex mutex;\n    ConditionVariable value_available;\n    ConditionVariable space_available;\n    List values;\n    unsigned long capacity;\n} Queue;\n\nstatic void\nmark_queue(Queue *queue)\n{\n    mark_mutex(&queue->mutex);\n    mark_condvar(&queue->value_available);\n    mark_condvar(&queue->space_available);\n    mark_list(&queue->values);\n}\n\nstatic void\nfinalize_queue(Queue *queue)\n{\n    finalize_mutex(&queue->mutex);\n    finalize_condvar(&queue->value_available);\n    finalize_condvar(&queue->space_available);\n    finalize_list(&queue->values);\n}\n\nstatic void\nfree_queue(Queue *queue)\n{\n    kill_waiting_threads(&queue->mutex.waiting);\n    kill_waiting_threads(&queue->space_available.waiting);\n    kill_waiting_threads(&queue->value_available.waiting);\n    finalize_queue(queue);\n    xfree(queue);\n}\n\nstatic void\ninit_queue(Queue *queue)\n{\n    init_mutex(&queue->mutex);\n    init_condvar(&queue->value_available);\n    init_condvar(&queue->space_available);\n    init_list(&queue->values);\n    queue->capacity = 0;\n}\n\n/*\n * Document-method: new\n * call-seq: new\n *\n * Creates a new queue.\n *\n */\n\nstatic VALUE\nrb_queue_alloc(VALUE klass)\n{\n    Queue *queue;\n    queue = ALLOC(Queue);\n    init_queue(queue);\n    return Data_Wrap_Struct(klass, mark_queue, free_queue, queue);\n}\n\nstatic VALUE\nrb_queue_marshal_load(VALUE self, VALUE data)\n{\n    Queue *queue;\n    VALUE array;\n    Data_Get_Struct(self, Queue, queue);\n\n    array = rb_marshal_load(data);\n    if (TYPE(array) != T_ARRAY) {\n\trb_raise(rb_eTypeError, \"expected Array of queue data\");\n    }\n    if (RARRAY(array)->len < 1) {\n\trb_raise(rb_eArgError, \"missing capacity value\");\n    }\n    queue->capacity = NUM2ULONG(rb_ary_shift(array));\n    push_multiple_list(&queue->values, RARRAY(array)->ptr, (unsigned)RARRAY(array)->len);\n\n    return self;\n}\n\nstatic VALUE\nrb_queue_marshal_dump(VALUE self)\n{\n    Queue *queue;\n    VALUE array;\n    Data_Get_Struct(self, Queue, queue);\n\n    array = array_from_list(&queue->values);\n    rb_ary_unshift(array, ULONG2NUM(queue->capacity));\n    return rb_marshal_dump(array, Qnil);\n}\n\n/*\n * Document-method: clear\n * call-seq: clear\n *\n * Removes all objects from the queue.\n *\n */\n\nstatic VALUE\nrb_queue_clear(VALUE self)\n{\n    Queue *queue;\n    Data_Get_Struct(self, Queue, queue);\n\n    lock_mutex(&queue->mutex);\n    clear_list(&queue->values);\n    signal_condvar(&queue->space_available);\n    unlock_mutex(&queue->mutex);\n\n    return self;\n}\n\n/*\n * Document-method: empty?\n * call-seq: empty?\n *\n * Returns +true+ if the queue is empty.\n *\n */\n\nstatic VALUE\nrb_queue_empty_p(VALUE self)\n{\n    Queue *queue;\n    VALUE result;\n    Data_Get_Struct(self, Queue, queue);\n\n    lock_mutex(&queue->mutex);\n    result = queue->values.size == 0 ? Qtrue : Qfalse;\n    unlock_mutex(&queue->mutex);\n\n    return result;\n}\n\n/*\n * Document-method: length\n * call-seq: length\n *\n * Returns the length of the queue.\n *\n */\n\nstatic VALUE\nrb_queue_length(VALUE self)\n{\n    Queue *queue;\n    VALUE result;\n    Data_Get_Struct(self, Queue, queue);\n\n    lock_mutex(&queue->mutex);\n    result = ULONG2NUM(queue->values.size);\n    unlock_mutex(&queue->mutex);\n\n    return result;\n}\n\n/*\n * Document-method: num_waiting\n * call-seq: num_waiting\n *\n * Returns the number of threads waiting on the queue.\n *\n */\n\nstatic VALUE\nrb_queue_num_waiting(VALUE self)\n{\n    Queue *queue;\n    VALUE result;\n    Data_Get_Struct(self, Queue, queue);\n\n    lock_mutex(&queue->mutex);\n    result = ULONG2NUM(queue->value_available.waiting.size +\n      queue->space_available.waiting.size);\n    unlock_mutex(&queue->mutex);\n\n    return result;\n}\n\nstatic void\nwait_queue(ConditionVariable *condvar, Mutex *mutex)\n{\n    condvar_wakeup(mutex);\n    wait_list(&condvar->waiting);\n    lock_mutex(mutex);\n}\n\nstatic VALUE queue_pop_inner(VALUE arg);\n\n/*\n * Document-method: pop\n * call_seq: pop(non_block=false)\n *\n * Retrieves data from the queue.  If the queue is empty, the calling thread is\n * suspended until data is pushed onto the queue.  If +non_block+ is true, the\n * thread isn't suspended, and an exception is raised.\n *\n */\n\nstatic VALUE\nrb_queue_pop(int argc, VALUE *argv, VALUE self)\n{\n    Queue *queue;\n    int should_block;\n    Data_Get_Struct(self, Queue, queue);\n\n    if (argc == 0) {\n        should_block = 1;\n    } else if (argc == 1) {\n        should_block = !RTEST(argv[0]);\n    } else {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 1)\", argc);\n    }\n\n    lock_mutex(&queue->mutex);\n    if (!queue->values.entries && !should_block) {\n        unlock_mutex(&queue->mutex);\n        rb_raise(rb_eThreadError, \"queue empty\");\n    }\n\n    while (!queue->values.entries) {\n        wait_queue(&queue->value_available, &queue->mutex);\n    }\n\n    return rb_ensure(queue_pop_inner, (VALUE)queue,\n\t\t     unlock_mutex_call, (VALUE)&queue->mutex);\n}\n\nstatic VALUE\nqueue_pop_inner(VALUE arg)\n{\n    Queue *queue = (Queue *)arg;\n    VALUE result = shift_list(&queue->values);\n    if (queue->capacity && queue->values.size < queue->capacity) {\n        signal_condvar(&queue->space_available);\n    }\n    return result;\n}\n\n/*\n * Document-method: push\n * call-seq: push(obj)\n *\n * Pushes +obj+ to the queue.\n *\n */\n\nstatic VALUE\nrb_queue_push(VALUE self, VALUE value)\n{\n    Queue *queue;\n    Data_Get_Struct(self, Queue, queue);\n\n    lock_mutex(&queue->mutex);\n    while (queue->capacity && queue->values.size >= queue->capacity) {\n        wait_queue(&queue->space_available, &queue->mutex);\n    }\n    push_list(&queue->values, value);\n    rb_ensure(signal_condvar_call, (VALUE)&queue->value_available,\n\t      unlock_mutex_call, (VALUE)&queue->mutex);\n\n    return self;\n}\n\n/*\n * Document-class: SizedQueue\n *\n * This class represents queues of specified size capacity.  The push operation\n * may be blocked if the capacity is full.\n *\n * See Queue for an example of how a SizedQueue works.\n *\n */\n\n/*\n * Document-method: new\n * call-seq: new\n *\n * Creates a fixed-length queue with a maximum size of +max+.\n *\n */\n\n/*\n * Document-method: max\n * call-seq: max\n *\n * Returns the maximum size of the queue.\n *\n */\n\nstatic VALUE\nrb_sized_queue_max(VALUE self)\n{\n    Queue *queue;\n    VALUE result;\n    Data_Get_Struct(self, Queue, queue);\n\n    lock_mutex(&queue->mutex);\n    result = ULONG2NUM(queue->capacity);\n    unlock_mutex(&queue->mutex);\n\n    return result;\n}\n\n/*\n * Document-method: max=\n * call-seq: max=(size)\n *\n * Sets the maximum size of the queue.\n *\n */\n\nstatic VALUE\nrb_sized_queue_max_set(VALUE self, VALUE value)\n{\n    Queue *queue;\n    unsigned long new_capacity;\n    unsigned long difference;\n    Data_Get_Struct(self, Queue, queue);\n\n    new_capacity = NUM2ULONG(value);\n\n    if (new_capacity < 1) {\n        rb_raise(rb_eArgError, \"value must be positive\");\n    }\n\n    lock_mutex(&queue->mutex);\n    if (queue->capacity && new_capacity > queue->capacity) {\n        difference = new_capacity - queue->capacity;\n    } else {\n        difference = 0;\n    }\n    queue->capacity = new_capacity;\n    for (; difference > 0; --difference) {\n        signal_condvar(&queue->space_available);\n    }\n    unlock_mutex(&queue->mutex);\n\n    return self;\n}\n\n/*\n * Document-method: push\n * call-seq: push(obj)\n *\n * Pushes +obj+ to the queue.  If there is no space left in the queue, waits\n * until space becomes available.\n *\n */\n\n/*\n * Document-method: pop\n * call-seq: pop(non_block=false)\n *\n * Retrieves data from the queue and runs a waiting thread, if any.\n *\n */\n\n/* for marshalling mutexes and condvars */\n\nstatic VALUE\ndummy_load(VALUE self, VALUE string)\n{\n    return Qnil;\n}\n\nstatic VALUE\ndummy_dump(VALUE self)\n{\n    return rb_str_new2(\"\");\n}\n\nvoid\nInit_thread(void)\n{\n    rb_define_singleton_method(rb_cThread, \"exclusive\", rb_thread_exclusive, 0);\n\n    rb_cMutex = rb_define_class(\"Mutex\", rb_cObject);\n    rb_define_alloc_func(rb_cMutex, rb_mutex_alloc);\n    rb_define_method(rb_cMutex, \"marshal_load\", dummy_load, 1);\n    rb_define_method(rb_cMutex, \"marshal_dump\", dummy_dump, 0);\n    rb_define_method(rb_cMutex, \"locked?\", rb_mutex_locked_p, 0);\n    rb_define_method(rb_cMutex, \"try_lock\", rb_mutex_try_lock, 0);\n    rb_define_method(rb_cMutex, \"lock\", rb_mutex_lock, 0);\n    rb_define_method(rb_cMutex, \"unlock\", rb_mutex_unlock, 0);\n    rb_define_method(rb_cMutex, \"exclusive_unlock\", rb_mutex_exclusive_unlock, 0);\n    rb_define_method(rb_cMutex, \"synchronize\", rb_mutex_synchronize, 0);\n\n    rb_cConditionVariable = rb_define_class(\"ConditionVariable\", rb_cObject);\n    rb_define_alloc_func(rb_cConditionVariable, rb_condvar_alloc);\n    rb_define_method(rb_cConditionVariable, \"marshal_load\", dummy_load, 1);\n    rb_define_method(rb_cConditionVariable, \"marshal_dump\", dummy_dump, 0);\n    rb_define_method(rb_cConditionVariable, \"wait\", rb_condvar_wait, 1);\n    rb_define_method(rb_cConditionVariable, \"broadcast\", rb_condvar_broadcast, 0);\n    rb_define_method(rb_cConditionVariable, \"signal\", rb_condvar_signal, 0);\n\n    rb_cQueue = rb_define_class(\"Queue\", rb_cObject);\n    rb_define_alloc_func(rb_cQueue, rb_queue_alloc);\n    rb_define_method(rb_cQueue, \"marshal_load\", rb_queue_marshal_load, 1);\n    rb_define_method(rb_cQueue, \"marshal_dump\", rb_queue_marshal_dump, 0);\n    rb_define_method(rb_cQueue, \"clear\", rb_queue_clear, 0);\n    rb_define_method(rb_cQueue, \"empty?\", rb_queue_empty_p, 0);\n    rb_define_method(rb_cQueue, \"length\", rb_queue_length, 0);\n    rb_define_method(rb_cQueue, \"num_waiting\", rb_queue_num_waiting, 0);\n    rb_define_method(rb_cQueue, \"pop\", rb_queue_pop, -1);\n    rb_define_method(rb_cQueue, \"push\", rb_queue_push, 1);\n    rb_alias(rb_cQueue, rb_intern(\"enq\"), rb_intern(\"push\"));\n    rb_alias(rb_cQueue, rb_intern(\"<<\"), rb_intern(\"push\"));\n    rb_alias(rb_cQueue, rb_intern(\"deq\"), rb_intern(\"pop\"));\n    rb_alias(rb_cQueue, rb_intern(\"shift\"), rb_intern(\"pop\"));\n    rb_alias(rb_cQueue, rb_intern(\"size\"), rb_intern(\"length\"));\n\n    rb_cSizedQueue = rb_define_class(\"SizedQueue\", rb_cQueue);\n    rb_define_method(rb_cSizedQueue, \"initialize\", rb_sized_queue_max_set, 1);\n    rb_define_method(rb_cSizedQueue, \"num_waiting\", rb_queue_num_waiting, 0);\n    rb_define_method(rb_cSizedQueue, \"pop\", rb_queue_pop, -1);\n    rb_define_method(rb_cSizedQueue, \"push\", rb_queue_push, 1);\n    rb_define_method(rb_cSizedQueue, \"max\", rb_sized_queue_max, 0);\n    rb_define_method(rb_cSizedQueue, \"max=\", rb_sized_queue_max_set, 1);\n    rb_alias(rb_cSizedQueue, rb_intern(\"enq\"), rb_intern(\"push\"));\n    rb_alias(rb_cSizedQueue, rb_intern(\"<<\"), rb_intern(\"push\"));\n    rb_alias(rb_cSizedQueue, rb_intern(\"deq\"), rb_intern(\"pop\"));\n    rb_alias(rb_cSizedQueue, rb_intern(\"shift\"), rb_intern(\"pop\"));\n}\n\n"
  },
  {
    "path": "ext/tk/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.log\n"
  },
  {
    "path": "ext/tk/ChangeLog.tkextlib",
    "content": "2008-05-12  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/tkDND/shape.rb: wrong package name.\n\n--------------< ... some changes ... >------------------\n\n2007-05-26  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/tcllib/tablelist.rb: fix typo.\n\n\t* ext/tk/lib/tkextlib/tile/dialog.rb: forget to give an argument.\n\n\t* ext/tk/lib/tkextlib/version.rb: update RELEASE_DATE.\n\n2007-01-26  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* ext/tk/lib/tkextlib/iwidgets/checkbox.rb: wrong number of arguments \n\t  [ruby-Bugs-7776].\n\n\t* ext/tk/lib/tkextlib/iwidgets/radiobox.rb: ditto.\n\n\t* ext/tk/lib/tkextlib/blt/tile/checkbutton.rb: change primary name \n\t  of class [ruby-dev:30080].\n\n\t* ext/tk/lib/tkextlib/blt/tile/radiobutton.rb: ditto.\n\n2006-11-07  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile/treeview.rb : minor bug fix.\n\n\t* lib/tkextlib/blt/table.rb: fix bugs which forbade use of \n\t  '::blt::table' command. Now, probably, it'll works properly.\n\n2006-11-06  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/version.rb: keep release date of tkextlib on \n\t  \"Tk::Tkextlib_RELEASE_DATE\".\n\n\t* lib/tkextlib/tile/treeview.rb : support Tile 0.7.8. \n\t  Now, you can handle tree items as objects. \n\n2006-10-04  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile.rb, lib/tkextlib/tile/* : support Tile 0.7.6.\n\n2006-10-03  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/SUPPORT_STATUS: [ruby-talk:211939] check links\n\t  of extensions.\n\n\t* lib/tkextlib/blt/container.rb: define instance methods properly.\n\n        * lib/tkextlib/tile/tcombobox.rb: bug fix [ruby-talk:213003].\n\n\t* lib/tkextlib/tile/tnotebook.rb: ditto.\n\n\t* lib/tkextlib/tile/treeview.rb: ditto.\n\n\t* lib/tkextlib/tile/sizegrip.rb: [new] add 'ttk::sizegrip' widget.\n\n2006-08-31  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt.rb: double dashes (--) option doesn't work\n\t  properly on some versions of BLT (wrong description on the\n\t  manual of `blt::bgexec'?).\n\n2005-12-11  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/SUPPORT_STATUS: update to support libraries in\n          ActiveTcl8.4.12.0.\n\n\t* lib/tkextlib/tile/tnotebook.rb: add Tk::Tile::TNotebook#insert.\n\n\t* sample/tkextlib/tile/demo.rb: improve the look of a part of the demo.\n\n2005-11-25  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/tile/demo.rb: bug fix\n\n\t* sample/tkextlib/tile/themes/*: add some themes (blue,\n\t  keramik, and plastik; require Tile-0.5 or later).\n\n2005-11-22  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile.rb: bug fix (Tk::Tile::USE_TTK_NAMESPACE\n\t  is not defined).\n\n2005-11-19  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/treectrl/demo.rb: remove dependency on Ruby's \n\t  version (1.8 or 1.9).\n\n2005-10-23  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/*: update to support ActiveTcl8.4.11.2\n\n\t* lib/tkextlib/trofs/*: support Trofs 0.4.3\n\n\t* lib/tkextlib/tile/*: support Tile 0.7.2\n\n\t* lib/tkextlib/vu/*: support vu 2.3.0\n\n\t* lib/tkextlib/tcllib/*: support Tcllib 1.8 (Tklib 0.3 part only)\n\n\t* lib/tkextlib/*: improve conversion of option values\n\n2005-10-04  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tktable/tktable.rb: border_* instance methods\n\t  don't call 'border' subcommands.\n\n2005-08-10  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/component.rb: didn't check\n\t  __item_ruby2val_optkeys().\n\n2005-08-09  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/barchart.rb: support to treat tkvariable-type\n\t  configure options.\n\n\t* lib/tkextlib/blt/component.rb: ditto.\n\n\t* lib/tkextlib/blt/dragdrop.rb: ditto.\n\n\t* lib/tkextlib/blt/treeview.rb: ditto.\n\n\t* lib/tkextlib/bwidget/button.rb: ditto.\n\n\t* lib/tkextlib/bwidget/entry.rb: ditto.\n\n\t* lib/tkextlib/bwidget/label.rb: ditto.\n\n\t* lib/tkextlib/bwidget/labelentry.rb: ditto.\n\n\t* lib/tkextlib/bwidget/labelframe.rb: ditto.\n\n\t* lib/tkextlib/bwidget/mainframe.rb: ditto.\n\n\t* lib/tkextlib/bwidget/passwddlg.rb: ditto.\n\n\t* lib/tkextlib/bwidget/spinbox.rb: ditto.\n\n\t* lib/tkextlib/bwidget/tree.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/calendar.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/entryfield.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/hierarchy.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/labeledframe.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/labeledwidget.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/menubar.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/scrolledlistbox.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/spinner.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/toolbar.rb: ditto.\n\n\t* lib/tkextlib/tkimg/pixmap.rb: ditto.\n\n\t* lib/tkextlib/tktable/tktable.rb: ditto.\n\n2005-08-06  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/demo.rb: use Tk::Tile::Scale#variable.\n\n2005-08-04  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/demo.rb: followed previous changes.\n\n2005-08-04  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile/t*.rb: aliased class names starting with 'T'\n\t  to non 'T' ones. (ie. Tk::Tile::TButton -> Tk::Tile::Button)\n\t  [ruby-dev:26724]\n\n\t* lib/tkextlib/tile.rb: ditto. (autoload support)\n\n2005-08-04  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/demo.rb: fixed: Tk::Tile::TProgressbar is\n\t  supported on tile 0.6 or later, not tile 0.5.\n\n\t* sample/tkextlib/tile/demo.rb: updated scales demo to use\n\t  Tk::Tile::TProgressbar for tile 0.6 or later.\n\n\t* sample/tkextlib/tile/demo.rb: set some TkVariable default values.\n\n2005-08-03  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile/treeview.rb: Tk::Tile::Treeview#headingconfigure\n\t  is now working and more. [ruby-dev:26716]\n\n\t* sample/tkextlib/tile/demo.rb: use Tk::Tile::Treeview#headingconfigure \t  instead of direct Tk.tk_call.\n\n2005-08-02  ocean  <ocean@ruby-lang.org>\n\n\t* lib/tkextlib/tile/tprogressbar.rb: Tk::Tile::TProgressbar#start\n\t  takes optional argument `interval'.\n\n\t* sample/tkextlib/tile/demo.rb: emulate Tk::Tile::TProgressbar\n\t  with Tk::Tile::TProgress in tile 0.4. (repeating buttons demo)\n\n2005-08-02  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/demo.rb: added repeating buttons demo.\n\n\t* sample/tkextlib/tile/repeater.tcl: ditto. (new file)\n\n2005-08-01  ocean  <ocean@ruby-lang.org>\n\n\t* lib/tkextlib/tile.rb: fixed autoload for Treeview.\n\n\t* lib/tkextlib/tile/treeview.rb: replaced `ary2tk_list(items)' with\n\t  `*items'.\n\n\t* sample/tkextlib/tile/demo.rb: added treeview demo. (tile 0.5 or\n\t  later is required) [ruby-dev:26668]\n\n2005-08-01  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/demo.rb: added combobox demo.\n\n2005-07-27  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/demo.rb: fixed typo.\n\n2005-06-16  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/SUPPOPRT_STATUS: add RELEASE_DATE information.\n\n\t* lib/tkextlib/tile/style.rb: add \"style element options <elem>\"\n\t  command support.\n\n2005-06-08  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/ICONS/icons.rb: fail to create instances of\n\t  Tk::ICONS [ruby-dev:26305].\n\n2005-06-07  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/themes/kroc.{rb,tcl}: also support tile 0.4.\n\n2005-06-07  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/tile/themes/kroc.{rb,tcl}: support tile 0.5 or later.\n\t  (\"pixmap\" element constructor replaced by \"image\")\n\n2005-06-05  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/tile/demo.rb: fix TypeError & create Console\n\n2005-05-30  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt.rb: add PACKAGE_NAME information of Tcl/Tk\n          Extension.\n\n\t* lib/tkextlib/bwidget.rb: ditto.\n\n\t* lib/tkextlib/iwidgets.rb: ditto.\n\n\t* lib/tkextlib/tile.rb: ditto.\n\n\t* lib/tkextlib/tkimg.rb: ditto.\n\n\t* lib/tkextlib/vu.rb: ditto.\n\n\t* lib/tkextlib/ICONS/icons.rb: ditto.\n\n\t* lib/tkextlib/itcl/incr_tcl.rb: ditto.\n\n\t* lib/tkextlib/itk/incr_tk.rb: ditto.\n\n\t* lib/tkextlib/tcllib/autoscroll.rb: ditto.\n\n\t* lib/tkextlib/tcllib/ctext.rb: ditto.\n\n\t* lib/tkextlib/tcllib/cursor.rb: ditto.\n\n\t* lib/tkextlib/tcllib/datefield.rb: ditto.\n\n\t* lib/tkextlib/tcllib/ico.rb: ditto.\n\n\t* lib/tkextlib/tcllib/ip_entry.rb: ditto.\n\n\t* lib/tkextlib/tcllib/plotchart.rb: ditto.\n\n\t* lib/tkextlib/tcllib/style.rb: ditto.\n\n\t* lib/tkextlib/tcllib/tkpiechart.rb: ditto.\n\n\t* lib/tkextlib/tclx/tclx.rb: ditto.\n\n\t* lib/tkextlib/tkDND/shape.rb: ditto.\n\n\t* lib/tkextlib/tkDND/tkdnd.rb: ditto.\n\n\t* lib/tkextlib/tkHTML/htmlwidget.rb: ditto.\n\n\t* lib/tkextlib/tkimg/bmp.rb: ditto.\n\n\t* lib/tkextlib/tkimg/gif.rb: ditto.\n\n\t* lib/tkextlib/tkimg/ico.rb: ditto.\n\n\t* lib/tkextlib/tkimg/jpeg.rb: ditto.\n\n\t* lib/tkextlib/tkimg/pcx.rb: ditto.\n\n\t* lib/tkextlib/tkimg/pixmap.rb: ditto.\n\n\t* lib/tkextlib/tkimg/png.rb: ditto.\n\n\t* lib/tkextlib/tkimg/ppm.rb: ditto.\n\n\t* lib/tkextlib/tkimg/ps.rb: ditto.\n\n\t* lib/tkextlib/tkimg/sgi.rb: ditto.\n\n\t* lib/tkextlib/tkimg/sun.rb: ditto.\n\n\t* lib/tkextlib/tkimg/tga.rb: ditto.\n\n\t* lib/tkextlib/tkimg/tiff.rb: ditto.\n\n\t* lib/tkextlib/tkimg/window.rb: ditto.\n\n\t* lib/tkextlib/tkimg/xbm.rb: ditto.\n\n\t* lib/tkextlib/tkimg/xpm.rb: ditto.\n\n\t* lib/tkextlib/tktable/tktable.rb: ditto.\n\n\t* lib/tkextlib/tktrans/tktrans.rb: ditto.\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: ditto.\n\n\t* lib/tkextlib/winico/winico.rb: ditto.\n\n2005-05-25  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/iwidgets/scrolledlistbox.rb: follow the change\n          of tk.rb. modify to attend encoding.\n\n\t* lib/tkextlib/iwidgets/scrolledtext.rb: ditto.\n\n\t* lib/tkextlib/iwidgets/scrolledcanvas.rb: bug fix on\n\t  TkCanvas#delete when given non-TkcItem arguments. \n\n2005-05-10  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/winop.rb: fix typo\n\n2005-05-08  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/vu/pie.rb: fix typo\n\n2005-04-10  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/mailwasher.rb: fixed typo. [ruby-dev:26008]\n\n2005-04-09  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/tile/demo.rb: new demo of Tile extension.\n\n\t* sample/tkextlib/tile/iconlib.tcl: part of the demo.\n\n\t* sample/tkextlib/tile/toolbutton.tcl: ditto.\n\n\t* sample/tkextlib/tile/readme.txt: document of the demo.\n\n\t* sample/tkextlib/tile/Orig_LICENSE.txt: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc.tcl: sample theme written with Tcl.\n\n\t* sample/tkextlib/tile/themes/pkgIndex.tcl: pkgIndex of kroc.tcl.\n\n\t* sample/tkextlib/tile/themes/kroc.rb: Kroc theme written with Ruby.\n\n\t* sample/tkextlib/tile/themes/kroc/button-h.gif: images for Kroc theme.\n\n\t* sample/tkextlib/tile/themes/kroc/button-n.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/button-p.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/check-hc.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/check-hu.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/check-nc.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/check-nu.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/radio-hc.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/radio-hu.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/radio-nc.gif: ditto.\n\n\t* sample/tkextlib/tile/themes/kroc/radio-nu.gif: ditto.\n\n\t* lib/tkextlib/tile.rb: bug fix (tested on the new demo).\n\n\t* lib/tkextlib/tile/style.rb: ditto.\n\n\t* lib/tkextlib/tile/tbutton.rb: ditto.\n\n\t* lib/tkextlib/tile/tcheckbutton.rb: ditto.\n\n\t* lib/tkextlib/tile/tcombobox.rb: ditto.\n\n\t* lib/tkextlib/tile/tentry.rb: ditto.\n\n\t* lib/tkextlib/tile/tframe.rb: ditto.\n\n\t* lib/tkextlib/tile/tlabel.rb: ditto.\n\n\t* lib/tkextlib/tile/tlabelframe.rb: ditto.\n\n\t* lib/tkextlib/tile/tmenubutton.rb: ditto.\n\n\t* lib/tkextlib/tile/tnotebook.rb: ditto.\n\n\t* lib/tkextlib/tile/tprogressbar.rb: ditto.\n\n\t* lib/tkextlib/tile/tradiobutton.rb: ditto.\n\n\t* lib/tkextlib/tile/treeview.rb: ditto.\n\n\t* lib/tkextlib/tile/tscrollbar.rb: ditto.\n\n\t* lib/tkextlib/tile/tseparator.rb: ditto.\n\n\t* lib/tkextlib/tile/tsquare.rb: ditto.\n\n\t* lib/tkextlib/tile/tpaned.rb: new library\n\n\t* lib/tkextlib/tile/tscale.rb: ditto.\n\n\t* lib/tkextlib/SUPPORT_STATUS: update support status of Tile extension.\n\n\t* lib/tkextlib/tcllib/ctext.rb: use TkCommandNames on create_self().\n\n\t* lib/tkextlib/tcllib/datefield.rb: ditto.\n\n\t* lib/tkextlib/tcllib/ip_entry.rb: ditto.\n\n\t* lib/tkextlib/tkHTML/htmlwidget.rb: ditto.\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: ditto.\n\n2005-04-09  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/explorer.rb: File.executable? returns true\n\t  even if it's plain text file. (this function only checks access right)\n\n2005-04-09  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/{help,www-options}.rb: fixed typo.\n\t  (click or resize column header)\n\n2005-04-09  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/imovie.rb: fixed typo. (click on clip title)\n\n2005-04-08  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/random.rb: fixed typo. (drop node outside of\n\t  widget, or reenter widget while draggging)\n\n2005-04-08  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/outlook-newgrounp.rb: image had disappered when\n\t  node was selected.\n\n2005-04-08  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/{random,outlook-newgroup}.rb:\n\t  tk::treectrl uses 'afterId' not 'afterID'.\n\n\t* sample/tkextlib/treectrl/{random,outlook-newgroup}.rb:\n\t  item_firstchild can return empty string. (drop node to leaf node)\n\n\t* sample/tkextlib/treectrl/random.rb: Enumerable#find didn't work properly\n\t  because tried to compare String with Integer. (drag node and leave widget)\n\n\t* sample/tkextlib/treectrl/random.rb: and some fixes.\n\n2005-04-08  ocean  <ocean@ruby-lang.org>\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb (selection_clear): fixed typo.\n\n\t* sample/tkextlib/treectrl/random.rb: node deselection now works.\n\n\t* sample/tkextlib/treectrl/demo.rb: fixed typo. (popup menu on column header)\n\n2005-04-08  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/help.rb: fixed typo. (wrong color)\n\n2005-04-08  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/random.rb: fixed typo. (wrong itemheight)\n\n\t* sample/tkextlib/treectrl/outlook-newgroup.rb: ditto.\n\n\t* sample/tkextlib/treectrl/explorer.rb: ditto.\n\n\t* sample/tkextlib/treectrl/help.rb: ditto.\n\n2005-04-07  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/*.rb: some speed up... cache the result of\n\t  version checking.\n\n2005-04-07  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: performance tuning by calling\n\t  tk_send_without_enc. [ruby-dev:25997]\n\n2005-04-04  ocean  <ocean@ruby-lang.org>\n\n\t* lib/tkextlib/tktable/tktable.rb: added Tk::TkTable#selection_present.\n\n2005-04-02  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: support TreeCtrl's cvs head.\n\n2005-04-02  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/component.rb: add TreeCtrl#legend_window_create().\n\n\t* sample/tkextlib/blt/graph6.rb: use legend_window_create().\n\n\t* lib/tkextlib/blt/tree.rb: forget to call tagid().\n\n\t* lib/tkextlib/blt/treeview.rb: ditto.\n\n2005-04-01  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/treectrl/demo.rb: bridge the gap of\n\t  Hash#index or Hash#key between ruby 1.8 and 1.9\n\n2005-04-01  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/component.rb: bug fix on treatment of\n\t  component objects.\n\n\t* sample/tkextlib/blt/graph6.rb: a new sample script. \n\n2005-03-31  ocean  <ocean@ruby-lang.org>\n\n\t* sample/tkextlib/treectrl/demo.rb: should use Hash#index.\n\n\t* sample/tkextlib/treectrl/demo.rb: TkImage was not\n\t  cached properly.\n\n\t* sample/tkextlib/treectrl/random.rb: fixed typo.\n\n2005-03-31  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/iwidgets/sample/hierarchy.rb: show basename\n\t  only [ruby-dev:25970]\n\n\t* sample/tkextlib/treectrl/demo.rb: add check for existence of \n\t  'backgroundimage' option.\n\n\t* sample/tkextlib/treectrl/bitmaps.rb: ditto.\n\n\t* sample/tkextlib/treectrl/outlook-newgroup.rb: lack of '%I'\n\t  event callback argument.\n\n2005-03-31  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/iwidgets/sample/hierarchy.rb: fail to treat\n\t  Japanese (i18n?) filenames.\n\n2005-03-30  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/bwidget/tree.rb: use 'return' in the Proc object.\n\n\t* sample/tkextlib/tkHTML/hv.rb: ditto.\n\n\t* sample/tkextlib/tkHTML/ss.rb: ditto.\n\n\t* sample/tkextlib/tktable/basic.rb: ditto.\n\n\t* sample/tkextlib/tktable/command.rb: ditto.\n\n\t* sample/tkextlib/tktable/debug.rb: ditto.\n\n\t* sample/tkextlib/tktable/maxsize.rb: ditto.\n\n\t* sample/tkextlib/treectrl/demo.rb: ditto.\n\n2005-03-29  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/component.rb: cannot create elements except\n\t  default type of element. \n\n\t* lib/tkextlib/blt/barchart.rb: ditto.\n\n\t* lib/tkextlib/blt/graph.rb: ditto.\n\n\t* lib/tkextlib/blt/stripchart.rb: ditto.\n\n\t* lib/tkextlib/blt/component.rb: axis command option gets\n\t  proper object type of arguments.\n\n\t* sample/tkextlib/blt/calendar.rb: new sample.\n\n\t* sample/tkextlib/blt/pareto.rb: ditto.\n\n2005-03-28  ocean  <ocean@ruby-lang.org>\n\n\t* lib/tkextlib/iwidgets/notebook.rb: fixed typo.\n\n2005-03-26  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt.rb: add commands for zooming.\n\n\t* lib/tkextlib/blt/bitmap.rb (new_with_name): add for using\n          given name.\n\n\t* lib/tkextlib/blt/busy.rb: bug fix on Tk::BLT::Busy::Shild class.\n\n\t* lib/tkextlib/blt/component.rb: typo fix.\n\n\t* lib/tkextlib/blt/component.rb: fix lack of *_create methods\n\n\t* lib/tkextlib/blt/component.rb: proper call on xaxis_* and so on.\n\n\t* lib/tkextlib/blt/htext.rb: add TkVariable object to access\n          special Tcl variables. \n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: typo fix.\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: proper treatment\n          of 'font' option of element_configure.\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: bug fix on item_sort.\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: add methods to\n          call TreeCtrl commands for bindings.\n\n\t* sample/tkextlib/blt/*: add some sample scripts.\n\n\t* sample/tkextlib/treectrl/*: add some sample scripts.\n\n2005-03-18  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: bug fix and define some\n\t  classes for components of Tk::TreeCtrl\n\n2005-03-17  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: call wrong method in\n\t  Tk::TreeCtrl#*_configinfo and current_*_configinfo method\n\n2005-03-16  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/SUPPORT_STATUS: change the status of TkImg\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: bug fix and support\n\t  TkTreeCtrl-1.1\n\n\t* lib/tkextlib/SUPPORT_STATUS: change the supported version of\n\t  TkTreeCtrl\n\n2005-03-15  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* sample/tkextlib/tkimg: add sample\n\n2005-03-06  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/SUPPORT_STATUS: add version info of each extension\n\n2005-03-05  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile.rb: lack of \"autoload TProgressbar\"\n\n2005-03-05  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile.rb: support tile-0.6\n\n\t* lib/tkextlib/tile/tbutton.rb: ditto\n\n\t* lib/tkextlib/tile/tcheckbutton.rb: ditto\n\n\t* lib/tkextlib/tile/tlabel.rb: ditto\n\n\t* lib/tkextlib/tile/tmenubutton.rb: ditto\n\n\t* lib/tkextlib/tile/tnotebook.rb: ditto\n\n\t* lib/tkextlib/tile/tradiobutton.rb: ditto\n\n\t* lib/tkextlib/tile/tcombobox.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tentry.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tframe.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tlabelframe.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tprogressbar.rb: [new] ditto\n\n\t* lib/tkextlib/tile/treeview.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tscrollbar.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tseparator.rb: [new] ditto\n\n\t* lib/tkextlib/tile/tsquare.rb: [new] ditto\n\n2005-02-20  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tclx/tclx.rb: warning TclX's 'signal' command.\n\n2005-01-25  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt/component.rb: bug fix. cannot accept\n          a callback ID string for a command argument. [ruby-dev:25479]\n\n\t* lib/tkextlib/blt/tabset.rb: ditto\n\n\t* lib/tkextlib/blt/treeview.rb: ditto\n\n\t* lib/tkextlib/bwidget/labelentry.rb: ditto\n\n\t* lib/tkextlib/bwidget/listbox.rb: ditto\n\n\t* lib/tkextlib/bwidget/notebook.rb: ditto\n\n\t* lib/tkextlib/bwidget/spinbox.rb: ditto\n\n\t* lib/tkextlib/bwidget/tree.rb: ditto\n\n\t* lib/tkextlib/itk/incr_tk.rb: ditto\n\n\t* lib/tkextlib/iwidgets/scrolledcanvas.rb: ditto\n\n\t* lib/tkextlib/tkDND/tkdnd.rb: ditto\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: ditto\n\n\t* sample/tkextlib/tkHTML/ss.rb: local variable scope bug fix\n          [ruby-dev:25479]\n\n\t* sample/tkextlib/vu/vu_demo.rb: rename from vu.rb; avoid the bug on\n\t  Windows version of Tcl/Tk. The trouble based on the bug occurs when\n\t  the script name (without extension) is a same name as a Tcl/Tk's\n\t  library file name (without extension) required in the script.\n\n2004-12-24  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/blt: add BLT extension support\n\n2004-12-16  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/bwidget/labelentry.rb: use TkCore.callback_obj?()\n\n\t* lib/tkextlib/bwidget/listbox.rb: ditto\n\n\t* lib/tkextlib/bwidget/notebook.rb: ditto\n\n\t* lib/tkextlib/bwidget/spinbox.rb: ditto\n\n\t* lib/tkextlib/itk/incr_tk.rb: ditto\n\n\t* lib/tkextlib/iwidgets/scrolledcanvas.rb: ditto\n\n\t* lib/tkextlib/tkDND/tkdnd.rb: ditto\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: ditto\n\n\t* lib/tkextlib/winico/winico.rb: ditto\n\n2004-12-10  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile/style.rb: 'theme_use' method bug fix\n\n2004-12-08  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/bwidget/notebook.rb: raise method cannot return\n          the raised page.\n\n\t* lib/tkextlib/bwidget/labelentry.rb: bind methods accept\n          subst_args + block\n\n\t* lib/tkextlib/bwidget/listbox.rb: ditto\n\n\t* lib/tkextlib/bwidget/notebook.rb: ditto\n\n\t* lib/tkextlib/bwidget/spinbox.rb: ditto\n\n\t* lib/tkextlib/bwidget/tree.rb: ditto\n\n\t* lib/tkextlib/itk/incr_tk.rb: ditto\n\n\t* lib/tkextlib/iwidgets/scrolledcanvas.rb: ditto\n\n\t* lib/tkextlib/tkDND/tkdnd.rb: ditto\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: ditto\n\n2004-11-26  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/bwidget/notebook.rb: uses epath\n\n\t* lib/tkextlib/bwidget/widget.rb: ditto\n\n\t* lib/tkextlib/tktable/tktable.rb: ditto\n\n\t* lib/tkextlib/tcllib/cursor.rb: ditto, and bug fix\n\n2004-11-10  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tile/style.rb: bug fix\n\n2004-11-07  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/iwidgets/scrolledcanvas.rb: bind-event methods\n\t  accept multi substitution arguments.\n\n\t* lib/tkextlib/tktable/tktable.rb: ditto.\n\n\t* lib/tkextlib/treectrl/tktreectrl.rb: ditto\n\n2004-11-03  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/SUPPORT_STATUS: BLT moves to 'plan to support'\n          from 'not determined'\n\n\t* lib/tkextlib/itk/incr_tk.rb: __cget_cmd and __config_cmd are\n          private methods\n\n\t* lib/tkextlib/tcllib/autoscroll.rb: extend TkCore\n\n\t* lib/tkextlib/tcllib/cursor.rb: ditto.\n\n\t* lib/tkextlib/tcllib/plotchart.rb: ditto.\n\n\t* lib/tkextlib/tcllib/style.rb: ditto.\n\n\t* lib/tkextlib/tile/style.rb: ditto.\n\n\t* lib/tkextlib/tkDND/shape.rb: ditto.\n\n2004-10-24  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/bwidget/tree.rb: bug fix on Windows\n\n2004-10-16  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/tcllib/ico.rb: new library (Tk::Tcllib:ICO)\n\n\t* lib/tkextlib/tcllib.rb: add Tk::Tcllib::ICO (based on tcllib 1.7)\n\n2004-10-06  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/bwidget.rb (BWidget.grab): bug fix\n\n\t* lib/tkextlib/tcllib.rb: typo fix\n\n2004-07-28  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/add winico support\n\n2004-07-23  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* lib/tkextlib/add TclX support (partially; infox command and\n          XPG/3 MsgCat only)\n\n2004-07-15  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* bug fix\n\n\t* support TkTable extension\n\n2004-07-12  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* bug fix\n\n\t* support Iwidgets extension\n\n2004-07-10  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* bug fix\n\n\t* add more part of [incr Widget] support (about 65%? are complete)\n\n\t* use Tk::ValidateConfigure.__def_validcmd() method\n          (new function to define validatecommand methods easier)\n\n\t* tcllib.rb : avoid the loading trouble that almost all part of \n\t  the extension is not available when some libraries are invalid. \n\n2004-07-09  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* add some part of [incr Widget] support (about 50%? are complete)\n\n2004-07-07  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* add [incr Tck], [incr Tk] support\n\n2004-07-06  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* support BWidget extension\n\n\t* add BWidget extension demo\n\n\t* add ICONS extension demo\n\n\t* many bug fix \n\n2004-07-01  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp>\n\n\t* 1st release of tkextlib ( to support Tcl/Tk extensions )\n"
  },
  {
    "path": "ext/tk/MANUAL_tcltklib.eng",
    "content": "(tof)\n                                    2005/07/05  Hidetoshi NAGAI\n\nThis document discribes about the 'tcltklib' library. Although there\nis the 'tcltk' library (tcltk.rb) under this directory, no description\nin this document (because it is not maintained recently). \n\n==============================================================\nmodule TclTklib\n  : Defines methods to do operations which are independed on \n  : Tcl/Tk interpreters\n\n  module TclTkLib::EventFlag\n    : Defines flags to define taget events on 'do_one_event' methos. \n    : When to give, please use bit-operator (e.g. WINDOW | DONT_WAIT). \n\n    [constants]\n       NONE\n         : Is 0. It means \"there is no target\". But on the real\n         : operation, it is same to ALL.\n\n       WINDOW\n         : 'window' event is processed.\n\n       FILE\n         : 'file' event is processed.\n\n       TIMER\n         : 'timer' event is processed.\n\n       IDLE\n         : 'idle' operation (e.g. 're-draw'; the operations when the\n         : other kinds of events doesn't occur) is processed. \n\n       ALL\n         : All kinds of events are processed. \n         : Same to 'WINDOW | FILE | TIMER | IDLE'. \n\n       DONT_WAIT\n         : Without this flag, 'do_one_event' waits the occurence of \n         : a target event. With this flag, doesn't wait and returns \n         : false if there is no target event for processing. \n\n  module TclTkLib::VarAccessFlag\n    : Defines flags to give '_get_variable' and so on. When to give, \n    : please use bit-operator (e.g. GLOBAL_ONLY | LEAVE_ERR_MSG ). \n\n    [constants]\n       NONE\n         : Is 0. It means \"set no flag\". \n\n       GLOBAL_ONLY\n         : (site Tcl/Tk's man page)\n         : Under normal circumstances the procedures look up \n         : variables as follows: If a procedure call is active \n         : in interp, a variable is looked up at the current\n         : level of procedure call. Otherwise, a variable is\n         : looked up first in the current namespace,  then  in\n         : the global namespace. However, if this bit is set\n         : in flags then the variable is looked up only in the\n         : global namespace even if there is a procedure call\n         : active. If both GLOBAL_ONLY and NAMESPACE_ONLY are\n         : given, GLOBAL_ONLY is ignored.\n         :\n         :  *** ATTENTION ***\n         : Tcl7.6 doesn't have namespaces. So NAMESPACE_ONLY \n         : is defined as 0, and then GLOBAL_ONLY is available\n         : even if flag is (GLOBAL_ONLY | NAMESPACE_ONLY). \n\n       NAMESPACE_ONLY\n         : (site Tcl/Tk's man page)\n         : Under normal circumstances the procedures look up\n         : variables as follows: If a procedure call is active\n         : in interp, a variable is looked up at the current\n         : level of procedure call. Otherwise, a variable is\n         : looked up first in the current namespace, then in\n         : the global namespace. However, if this bit is set\n         : in flags then the variable is looked up only in the\n         : current namespace even if there is a procedure call\n         : active.\n         :\n         :  *** ATTENTION ***\n         : Tcl7.6 doesn't have namespaces. So NAMESPACE_ONLY \n         : is defined as 0.\n\n       LEAVE_ERR_MSG\n         : (site Tcl/Tk's man page)\n         : If an error is returned and this bit is set in flags, \n         : then an error message will be left in the interpreter's\n         : result, where it can be retrieved with Tcl_GetObjResult\n         : or Tcl_GetStringResult. If this flag bit isn't set then \n         : no error message is left and the interpreter's result \n         : will not be modified.\n\n       APPEND_VALUE\n         : (site Tcl/Tk's man page)\n         : If this bit is set then newValue is appended to the\n         : current value, instead of replacing it. If the variable\n         : is currently undefined, then this bit is ignored.\n\n       LIST_ELEMENT\n         : (site Tcl/Tk's man page)\n         : If this bit is set, then newValue is converted to a\n         : valid Tcl list element before setting (or appending\n         : to) the variable. A separator space is appended before\n         : the new list element unless the list element is going\n         : to be the first element in a list or sublist (i.e. the \n         : variable's current value is empty, or contains the \n         : single character ``{'', or ends  in `` }'').\n\n       PARSE_VARNAME\n         : (site Tcl/Tk's man page)\n         : If this bit is set when calling _set_variable and so \n         : on, var_name argument may contain both an array and an\n         : element name: if the name contains an open parenthesis \n         : and ends with a close parenthesis, then the value \n         : between the parentheses is treated as an element name \n         : (which can have any string value) and the characters\n         : before  the first open parenthesis are treated as the \n         : name of an array variable. If the flag PARSE_VARNAME\n         : is given, index_name argument should be 'nil' since the \n         : array and element names are taken from var_name.\n         :\n         :  *** ATTENTION ***\n         : Tcl7.6 doesn't have this flag. So PARSE_VARNAME is \n         : defined as 0. \n\n  module TclTkLib::RELEASE_TYPE\n    : Defines release type number of Tcl/Tk\n\n       ALPHA\n         : ALPHA release\n\n       BETA\n         : BETA release\n\n       FINAL\n         : FINAL release\n\n  [module methods]\n     get_version()\n        : return an array of major, minor, release-type number, \n        : number, release-type name, and patchlevel of current \n        : Tcl/Tk library.\n\n     mainloop(check_root = true)\n       : Starts the eventloop. If 'check_root' is true, this method \n       : doesn't return when a root widget exists. \n       : If 'check_root' is false, doen't return by the other\n       : reasons than exceptions.\n\n    mainloop_thread?\n       : Returns whether the current thread executes the eventloop. \n       : If true, the eventloop is working on the current thread. \n       : If no eventloop is working, this method returns nil.\n       : And if the other thread executes the eventloop, returns false.\n       : \n       :  *** ATTENTION ***\n       : When this methods returns false, it is dangerous to call a Tk \n       : interpreter directly.\n\n    mainloop_watchdog(check_root = true)\n       : On the normal eventloop, some kinds of callback operations \n       : cause deadlock. To avoid some of such deadlocks, this\n       : method starts an eventloop and a watchdog-thread.\n\n    do_one_event(flag = TclTkLib::EventFlag::ALL | \n                          TclTkLib::EventFlag::DONT_WAIT)\n       : Do one event for processing. When processed an event, \n       : returns true. \n       : If NOT set DONT_WAIT flag, this method waits occurrence of\n       : a target event. \n       : If set DONT_WAIT flag and no event for processing, returns \n       : false immediately. \n       : If $SAFE >= 4,  or $SAFE >= 1 and the flag is tainted, \n       : force to set DONT_WAIT flag.\n\n    set_eventloop_tick(timer_tick)\n       : Define the interval of thread-switching with an integer\n       : value of mili-seconds. \n       : Default timer_tick is 0. It means that thread-switching \n       : is based on the count of processed events. \n       : ( see 'set_eventloop_weight' method )\n       : However, if the eventloop thread is the only thread, \n       : timer_tick cannt be set to 0. If 0, then is set to 100 ms \n       : automatically (see NO_THREAD_INTERRUPT_TIME on tcltklib.c). \n       : On $SAFE >= 4, cannot call this method. \n\n    get_eventloop_tick\n       : Get current value of 'timer_tick'\n\n    set_no_event_wait(no_event_wait)\n       : Define sleeping time of the eventloop when two or more \n       : thread are running and there is no event for processing. \n       : Default value is 20 (ms).\n       : If the eventloop thread is the only thread, this value is \n       : invalid. \n       : On $SAFE >= 4, cannot call this method. \n\n    get_no_event_wait\n       : Get current value of 'no_event_wait'.\n\n    set_eventloop_weight(loop_max, no_event_tick)\n       : Define the weight parameters for the eventloop thread. \n       : That is invalid when the eventloop is the only thread. \n       : 'loop_max' is the max events for thread-switching. \n       : 'no_event_tick' is the increment value of the event count \n       : when no event for processing (And then, the eventloop thead\n       : sleeps 'no_event_wait' mili-seconds). \n       : 'loop_max == 800' and 'no_event_tick == 10' are defalut. \n       : On $SAFE >= 4, cannot call this method. \n\n    get_eventloop_weight\n       : Get current values of 'loop_max' and 'no_event_tick'.\n\n    mainloop_abort_on_exception=(bool)\n       : Define whether the eventloop stops on exception or not. \n       : If true (default value), stops on exception. \n       : If false, show a warinig message but ignore the exception.\n       : If nil, no warning message and ignore the excepsion. \n       : This parameter is sometimes useful when multiple Tk\n       : interpreters are working. Because the only one eventloop \n       : admins all Tk interpreters, sometimes exception on a\n       : interpreter kills the eventloop thread. Even if such\n       : situation, when abort_on_exception == false or nil, \n       : the eventloop ignores the exception and continue to working. \n       : On $SAFE >= 4, cannot call this method. \n\n    mainloop_abort_on_exception\n       : Get current status of that. \n\n    num_of_mainwindows\n       : Returns the number of main-windows (root-widget). \n       : Because there is only one main-window for one Tk interpreter, \n       : the value is same to the number of interpreters which has \n       : available Tk functions.\n\n    _merge_tklist(str, str, ... )\n       : Get a Tcl's list string from arguments with a Tcl/Tk's \n       : library function. Each arguemnt is converted to a valid \n       : Tcl list element. \n\n    _conv_listelement(str)\n       : Convert the argument to a valid Tcl list element with\n       : Tcl/Tk's library function.\n\n    _toUTF8(str, encoding=nil)\n    _fromUTF8(str, encoding=nil)\n       : Call the function (which is internal function of Tcl/Tk) to\n       : convert to/from a UTF8 string.\n\n    _subst_UTF_backslash(str)\n    _subst_Tcl_backslash(str)\n       : Substitute backslash sequence with Tcl's rule (include \\uhhhh;\n       : give a sixteen-bit hexadecimal value for Unicode character).\n       : _subst_Tcl_backslash method parses all backslash sequence. \n       : _subst_UTF_backslash method parses \\uhhhh only.\n\n    encoding_system\n    encoding_system=(encoding)\n       : Get and set Tcl's system encoding.\n\n    encoding\n    encoding=(encoding)\n       : alias of encoding_system / encoding_system=\n       : ( probably, Ruby/Tk's tk.rb will override them )\n\n\nclass TclTkIp\n  [class methods]\n    new(ip_name=nil, options='')\n       : Generate an instance of TclTkIp class. \n       : If 'ip_name' argument is given as a string, it is the name\n       : of the Tk interpreter which is shown by 'winfo interps'\n       : command. \n       : 'options' argument accepts a string which is the command \n       : line options of wish; such as '-geometry' or '-use'. \n       : The information is used to generate the root widget of the \n       : interpreter. \n       : ( e.g. TclTkIp.new('FOO', '-geometry 500x200 -use 0x2200009') )\n       : If is given nil or falsr for the 'option' argument, generates\n       : the Tcl interpreter without Tk library. Then the interpreter \n       : doesn't need GUI environment. Therefore, even if a window\n       : system doesn't exist or cannot be used, Ruby can control the\n       : Tcl interpreter and the extention libraries loaded on the \n       : interpreter. \n\n  [instance methods]\n    create_slave(name, safe=false)\n       : Create a slave interpreter. \n       : The parent of the interpreter is the receiver of this method.\n       : The name of the slave interpreter is given by 'name' argument. \n       : The 'safe' argument decides whether the slave interpreter is\n       : created as a safe interpreter or not. If true, create a safe\n       : interpreter. Default is false. However, if the parent\n       : interpreter is a safe interpreter, the created interpreter is\n       : a safe interpreter (ignore 'safe' argument value). \n       : If $SAFE >= 4, can create a safe interpreter only. \n\n    make_safe\n       : Make the interpreter to the safe interpreter, and returns\n       : self. If fail, raise RuntimeError.\n\n    safe?\n       : Check whether the interpreter is the safe interpreter. \n       : If is the safe interpreter, returns true. \n\n    allow_ruby_exit?\n       : Return the mode whether 'exit' function of ruby or 'exit' \n       : command of Tcl/Tk can quit the ruby process or not on the \n       : interpreter. If false, such a command quit the interpreter \n       : only.\n       : The default value for a master interpreter is true, and \n       : for a slave interpreter is false.\n\n    allow_ruby_exit=(mode)\n       : Change the mode of 'allow_ruby_exit?'.\n       : If $SAFE >= 4 or the interpreter is a \"safe\" interpreter, \n       : this is not permitted (raise an exception). \n\n    delete\n       : Delete the interpreter. \n       : The deleted interpreter doesn't accept command and then\n       : raise an exception.\n\n    deleted?\n       : Check whether the interpreter is already deleted.\n       : If deleted, returns true. \n\n    has_mainwindow?\n       : Check whether the interpreter has a MainWindow (root widget).\n       : If has, returns true. If doesn't, returns false.  \n       : If IP is already deleted, returns nil. \n\n    restart\n       : Restart Tk part of the interpreter. \n       : Use this when you need Tk functions after destroying the\n       : root widget. \n       : On $SAFE >= 4, cannot call this method. \n\n    _eval(str)\n    _invoke(*args)\n       : Estimates the arguments as a command on the Tk interpreter. \n       : The argument of _eval is a script of Tcl/Tk.\n       : Each argument of _invoke is a token of one command line of\n       : Tcl/Tk. \n       : Because the operation of _invoke doesn't through the\n       : command line parser of Tk interpreter, the cost of\n       : estimation is smaller than _eval. However, auto_load\n       : mechanism of the Tk interpreter doesn't work on _invoke. \n       : So _invoke can call only the command which already\n       : registered on the interpreter by 'load' command and so on. \n       : On _eval command, auto_load mechanism words. So if succeed \n       : to _eval and regist the command once, after that, the\n       : command can be called by _invoke. \n\n    _toUTF8(str, encoding=nil)\n    _fromUTF8(str, encoding=nil)\n       : Call the function (which is internal function of Tcl/Tk) to\n       : convert to/from a UTF8 string.\n\n    _thread_vwait(var_name)\n    _thread_tkwait(mode, target)\n       : 'vwait' or 'tkwait' with thread support. \n       : The difference from normal 'vwait' or 'tkwait' command is \n       : doing independent wait from the vwait stack when they are\n       : called on the other thread than the eventloop thread.\n       : In the case of Tcl/Tk's vwait / tkwait, if 2nd vwait /\n       : tkwait is called on waiting for 1st vwait / tkwait, \n       : returns the order of [2nd]->[1st] regardless of the order\n       : of when the wait condition was fulfilled.  \n       : If _thread_vwait / _thread_tkwait is called on the\n       : eventloop thread, there is no difference from vwait /\n       : tkwait. But if called on the other thread than the\n       : eventloop, stops the thread.  And when the wait condition \n       : is fulfilled, the thread restarts. The meaning of\n       : \"independent from the vwait stack\" is that the timing of \n       : restarting is independent from the waiting status of the \n       : other threads. That is, even if the eventloop thread is \n       : waiting by vwait and is not fulfilled the condition, \n       : _thread_vwait completes the waiting when its waiting\n       : condition is fulfilled and the thread which stopped by\n       : _thread_vwait can continue the operation. \n\n    _return_value\n       : Get the last result value on the interpreter. \n\n    _get_variable(var_name, flag)\n    _get_variable2(var_name, index_name, flag)\n       : Get the current value of a variable. If specified a \n       : index_name (see also the PARSE_VARNAME flag), get the \n       : value of the index_name element. \n\n    _set_variable(var_name, value, flag)\n    _set_variable2(var_name, index_name, value, flag)\n       : Create or modify a variable. If specified a index_name \n       : (see also the PARSE_VARNAME flag), create or modify the \n       : index_name element. \n\n    _unset_variable(var_name)\n    _unset_variable2(var_name, index_name)\n       : Remove a variable. If specified a index_name (see also \n       : the PARSE_VARNAME flag), remove the index_name element. \n\n    _get_global_var(var_name)\n    _get_global_var2(var_name, index_name)\n    _set_global_var(var_name, value)\n    _set_global_var2(var_name, index_name, value)\n    _unset_global_var(var_name)\n    _unset_global_var2(var_name, index_name)\n       : Call the associated method with the flag argument\n       : (GLOBAL_ONLY | LEAVE_ERR_MSG).\n\n    _split_tklist(str)\n       : Split the argument with Tcl/Tk's library function and \n       : get an array as a list of Tcl list elements.\n\n    _merge_tklist(str, str, ... )\n       : Get a Tcl's list string from arguments with a Tcl/Tk's \n       : library function. Each arguemnt is converted to a valid \n       : Tcl list element. \n\n    _conv_listelement(str)\n       : Convert the argument to a valid Tcl list element with\n       : Tcl/Tk's library function.\n\n    mainloop\n    mainloop_watchdog\n       : If on the slave interpreter, never start an eventloop and\n       : returns nil. \n       : With the exception that, same to the TclTkLib module method\n       : with the same name. \n\n    do_one_event\n       : With the exception that the argument is forced to set\n       : DONT_WAIT flag on the slave interpreter, same to\n       : TclTkLib#do_one_event. \n\n    set_eventloop_tick\n    get_eventloop_tick\n    set_no_event_wait\n    get_no_event_wait\n    set_eventloop_weight\n    get_eventloop_weight\n    mainloop_abort_on_exception\n    mainloop_abort_on_exception=\n       : With the exception that it is ignored to set value on the\n       : slave interpreter, same to the TclTkLib module method with\n       : the same name. \n\n    encoding_table\n       : For Ruby m17n. Return encoding relation table between Ruby's \n       : Encoding object and Tcl's encoding name.\n\nclass TkCallbackBreak < StandardError\nclass TkCallbackContinue < StandardError\n  : They are exception classes to break or continue the Tk callback \n  : operation. \n  : If raise TkCallbackBreak on the callback procedure, Ruby returns \n  : 'break' code to Tk interpreter (Then the Tk interpreter will \n  : break the operation for the current event). \n  : If raise TkCallbackContinue, returns 'continue' code (Then the Tk\n  : interpreter will break the operateion for the current bindtag and \n  : starts the operation for the next buindtag for the current event).\n  : However, current tcltklib supports Ruby's 'break' and 'next' to \n  : get the same effect. That is, those classes are obsolete. Those \n  : exist for backward compatibility. \n\n(eof)\n"
  },
  {
    "path": "ext/tk/MANUAL_tcltklib.eucj",
    "content": "(tof)\n                                    2005/07/05  Hidetoshi NAGAI\n\nܥɥȤˤϸŤ tcltk 饤֥ꡤtcltklib 饤֥\nޤޤƤޤεƤϸŤΤȤʤäƤޤ\n\ntcltk 饤֥tcltk.rbˤϸߤǤϥƥʥ󥹤¾Ԥ\nʤᡤŤɥȤΤޤͭǤФ\ntcltklib 饤֥ˤĤƤϡߤ Ruby/Tktk.rb ʲΥ饤֥\n귲ˤƯ뤿濴Ȥƥƥʥ󥹤Ƥ뤿ᡤ\n㤤Ƥޤ\n\nǡޤŤʸ򼨤塤ߤ tcltklib 饤֥ˤ\nƤäޤ\n\nʲ饤֥θŤʸǤ\n==============================================================\n\tMANUAL.euc\n\t\tSep. 19, 1997\tY. Shigehiro\n\nʲ, tcl/tkפȤɽ, tclsh  wish ¸Ƥ, ̤Ǥ\nȤ tcl/tk ؤޤ. tcltk 饤֥, tcltklib 饤֥\nפȤɽ, ܥѥå˴ޤޤ ruby ѤΥ饤֥ؤޤ.\n\n<< tcltk 饤֥ >>\n\ntcl/tk  C 饤֥Ѥ뤿ι(?)।󥿡ե\nޤ.\n\nΥ饤֥ ruby  tcl/tk 饤֥Ѥ뤿ΤΤ, \n tcltklib 饤֥ѤƤޤ.\n\n[]\n\ntcl/tk 󥿥ץ꥿Ǥ, åȤ˲ؼˤ, \n̾³ƥѥ᡼񤭤ޤ. ä, åȤ֥\nȤǤ, Фƥ᥽åɤäƤ, ȤߤʤȤǤޤ. \n, tcl/tk 󥿥ץ꥿Ǥ, Ȥ߹ߥޥɤ, ҤΥåȤ\nƱ褦ʽ񼰤̿Ǽ¹Ԥޤ. ʤ, ޥɤ⥪֥Ȥ\nȹͤ뤳ȤǤޤ.\n\nΤ褦ʹͤ˴Ť, tcltk 饤֥Ǥ, tcl/tk Υޥɤ䥦\nåȤб륪֥Ȥޤ. ֥ȤФ᥽\nɸƤӽФ, e() ᥽åɤˤ¹Ԥޤ. 㤨, tcl/tk  info \nޥɤб ruby Υ֥Ȥ info Ȥ̾ǤȤ,\ntcl/tk \n\tinfo commands\nȤ̿ tcltk 饤֥Ǥ\n\tinfo.e(\"commands\")\nȵҤޤ. ޤ, .פȤå (wish ¹Ի˼ưŪ\n롼ȥå) б ruby Υ֥Ȥ root Ȥ\n̾ǤȤ,\n\t. configure -height 300 -width 300\nȤ tcl/tk ̿\n\troot.e(\"configure -height 300 -width 300\")\nȵҤޤ. Τ褦ʵҤ, ˤޤ, , \nץȤɤͤˤϸŤ餤Τޤ, ºݤ˥ץȤ\nƤߤͽ۳˼ڤǤ.\n\n[ˡ]\n\n1. 饤֥ɤ߹.\n     require \"tcltk\"\n\n2. tcl/tk 󥿥ץ꥿.\n     ip = TclTkInterpreter.new()\n\n3. tcl/tk Υޥɤб륪֥ȤѿƤ.\n     # ޥɤб륪֥Ȥä Hash Ф.\n     c = ip.commands()\n     # Ȥޥɤб륪֥Ȥ̤ѿ.\n     bind, button, info, wm = c.indexes(\"bind\", \"button\", \"info\", \"wm\")\n\n4. ɬפʽԤ.\n     ܤ, ץ򻲾ȤΤ.\n\n5. Ǥ, ٥ȥ롼פ.\n     TclTk.mainloop()\n\n(( ʲ, ⥸塼, 饹ͽ.))\n\n\n\n<< tcltklib 饤֥ >>\n\ntcl/tk  C 饤֥Ѥ뤿।󥿡ե󶡤\n.\n\nѥ/¹Ԥˤ, tcl/tk  C 饤֥꤬ɬפǤ.\n\n[]\n\nΥ饤֥Ѥ, ruby  tcl/tk  C 饤֥ѤǤ\n. Ūˤ, ruby 󥿥ץ꥿ tcl/tk 󥿥ץ꥿ƤӽФ\nȤǤޤ. , (ruby 󥿥ץ꥿ƤӽФ) tcl/tk \n󥿥ץ꥿, դ ruby 󥿥ץ꥿ƤӽФȤǤޤ.\n\n[ˡ]\n\nrequire \"tcltklib\" , ʲΥ⥸塼, 饹ѲǽǤ.\n\n⥸塼 TclTkLib\n    tcl/tk 饤֥ƤӽФ᥽åɤ򽸤᤿⥸塼Ǥ. ,\n    tcl/tk 󥿥ץ꥿طΥ᥽åɤϥ饹 TclTkIp ˤޤ.\n\n  ⥸塼᥽å mainloop()\n      Tk_MainLoop ¹Ԥޤ. Ƥ tk Υɥ̵ʤȽλ\n      ޤ(㤨, tcl/tk ǽ񤯤Ȥ \"destroy .\" 򤷤).\n    : ̵\n    : nil\n\n饹 TclTkIp\n    󥹥󥹤 tcl/tk Υ󥿥ץ꥿бޤ. tcl/tk Υ饤\n    λ̤, 󥹥󥹤ʣƤưޤ(\n    ʤȤ򤹤ɬפϤޤ̵ϤǤ). 󥿥ץ꥿ wish \n    tcl/tk ޥɤ¹ԤǤޤ. , ʲΥޥɤ¹ԤǤ\n    .\n      ޥ ruby\n\t ruby Ǽ¹Ԥޤ(ruby_eval_string ¹Ԥޤ). \n\t 1 ĤǤʤФʤޤ. ͤ ruby μ¹Է̤Ǥ.\n\truby μ¹Է̤ nil  String ǤʤФʤޤ.\n\n  饹᥽å new()\n      TclTkIp 饹Υ󥹥󥹤ޤ\n    : ̵\n     (TclTkIp): 줿󥹥\n\n  ᥽å _eval(script)\n      󥿥ץ꥿ script ɾޤ(Tcl_Eval ¹Ԥޤ). \n      Τ褦, ruby ޥɤˤ script ⤫ ruby ץȤ\n      ԤǤޤ.\n    : script (String) - 󥿥ץ꥿ɾ륹ץʸ\n     (String): ɾ ((Tcl_Interp *)->result)\n\n  ᥽å _return_value()\n      ľ Tcl_Eval ֤ͤޤ. 0(TCL_OK) ｪλǤ.\n    : ̵\n     (Fixnum): ľ Tcl_Eval() ֤.\n\n==============================================================\n\nʲܥɥȺǤ tcltklib 饤֥Ǥ\n==============================================================\n⥸塼 TclTkLib\n   : ġ Tcl/Tk 󥿡ץ꥿˰¸ʤ ( == ٥ȥ롼\n   : פ˴ؤ ) ƤӽФ᥽åɤ⥸塼롥\n\n   ⥸塼 TclTkLib::EventFlag\n      : do_one_event ƤӽФݤνоݥ٥Ȥꤹ뤿\n      : ե饰 ( WINDOW|DONT_WAIT Ȥ褦˥ӥåȱ黻ҤϢ뤷\n      :  ) Ȥ⥸塼롥ʲޤޤ롥\n\n        NONE\n         : ͤ 0 ǡͤȤƤϤʤΥ٥ȤꤷƤʤ\n         : Ȥˤʤ뤬ºݤν ALL ƱȤư롥\n\n        WINDOW\n         : window ٥ȤоݤȤ\n\n        FILE\n         : file ٥ȤоݤȤ\n\n        TIMER\n         : timer ٥ȤоݤȤ\n\n        IDLE\n         : ɥ롼׽ ( ʤɡ¾μΥ٥Ȥȯ\n         : ƤʤȤ˹Ԥ ) оݤȤ\n\n        ALL\n         : ٤ƤμΥ٥ȤоݤȤ\n         : WINDOW|FILE|TIMER|IDLE Ʊ\n\n        DONT_WAIT\n         : оݥ٥Ȥ¸ߤʤˡ٥ȯԤ\n         :  do_one_event λ ( false ֤ )  \n\n   ⥸塼 TclTkLib::VarAccessFlag\n      : _get_variable ʤɤǤΥե饰ꤹ뤿ΤΡե饰\n      : ϰʲ OR Ϣ뤷Ϳ롥\n\n        NONE\n         : ͤ 0 ǡե饰ꤷƤʤΤ\n\n        GLOBAL_ONLY\n         : ̾ѿθϤޤ³ƤӽФԤä٥Ǹ\n         : ˸ߤ֤̾ǸǸ˥Х֤\n         : ԤΥե饰ꤵ줿ˤϡ\n         : Х֤ǤΤ߸롥\n         : ⤷ GLOBAL_ONLY  NAMESPACE_ONLY Ȥξꤵ줿\n         : ˤϡGLOBAL_ONLY λ̵뤵롥\n\n        NAMESPACE_ONLY\n         : Υե饰ꤵ줿ˤϡߤ֤̾ǤΤ\n         : θԤGLOBAL_ONLY ⻲Ȥ뤳ȡ\n\n        LEAVE_ERR_MSG\n         : ѿˤƥ顼ȯ硤Υե饰\n         : ꤵƤС¹Է̤Ȥ Tcl 󥿡ץ꥿˥\n         : 顼åĤ롥Υե饰ꤵƤʤ\n         : С顼åϰڻĤʤ\n\n        APPEND_VALUE\n         : Υե饰ꤵƤ硤ѿ֤ͤΤ\n         : Ϥʤߤͤͤɲ (append; ʸϢ) \n         : 롥ѿ̤ä硤Υե饰̵뤵롥\n\n        LIST_ELEMENT\n         : Υե饰ꤵƤ硤ͤϤޤ Tcl Υꥹ\n         : ǤȤŬڤȤʤ褦Ѵ롥ͤꥹ\n         : (ޤϥ֥ꥹ) κǽǤȤʤΤǤʤ¤ꡤ\n         : ͤľˤ϶ʸɲä롥\n\n        PARSE_VARNAME\n         : _set_variable ʤɤθƤӽФˤƤΥե饰ꤵ\n         : Ƥ硤var_name Ϣ̾̾Ȥξ\n         : ޤǽ (̤ޤߡĤ̤ǽ) \n         : Ȥ򼨤ξ硤̤δ֤̾ꡤǽγ\n         : ̤ޤǤϢ̾Ȥư롥_set_variable2 ʤɤ\n         : Υե饰ꤹ硤Ϣ̾̾ var_name \n         : ФϤǤ뤫顤index_name  nil \n         : ͤФʤʤ\n\n   ⥸塼 TclTkLib::RELEASE_TYPE\n      : Tcl/Tk Υ꡼ֹ\n\n        ALPHA\n         : ALPHA ꡼\n\n        BETA\n         : BETA ꡼\n\n        FINAL\n         : FINAL ꡼\n\n   ⥸塼᥽å\n      get_version()\n         : Tcl/Tk  major, minor, release-type ֹ, release-type ̾,\n         : patchlevel ˤ֤\n\n      mainloop(check_root = true)\n         : ٥ȥ롼פư롥check_root  true ǤС\n         : root widget ¸ߤ¤ꡤΥ᥽åɤϽλʤ\n         : check_root  false ξϡroot widget ǤƤ\n         : Υ᥽åɤϽλʤ ( root widget ǤƤ⡤\n         : WINDOW ʳΥ٥Ȥȯ뤿 )λˤϡ\n         : Ưݤ ( åɤѤʤ ) ɬס\n\n      mainloop_thread?\n         : ȥåɤ٥ȥ롼פ¹ԤƤ륹å\n         : ɤ֤\n         : ٥ȥ롼פ¹ԤƤ륹åɤǤ true \n         : ɤΥåɤǤ⥤٥ȥ롼פ¹ԤƤʤ \n         : nil ¾Υåɤǥ٥ȥ롼פ¹ԤƤ\n         :  false ֤\n         : false κݤ Tk 󥿡ץ꥿ľܸƤ֤ΤϴǤ롥\n\n      mainloop_watchdog(check_root = true)\n         : ̾Υ٥ȥ롼פǤϡ٥ȽƤˤäƤ\n         : ǥåɥåǽ (㤨Х٥Ȥ\n         : Ф륳Хå widget 򤷡νλ\n         : ԤĤʤ)Υ᥽åɤϡǥåɥå\n         : 뤿δƻ륹åդǥ٥ȥ롼פư\n         : ( ƻ륹åɤ˥٥ȥ롼פ¹Ԥ )\n         : ΰ̣ mainloop ƱǤ롥\n\n      do_one_event(flag = TclTkLib::EventFlag::ALL | \n                            TclTkLib::EventFlag::DONT_WAIT)\n         : ԤΥ٥ 1 Ĥ¹Ԥ롥\n         : ٥Ȥ true ֤\n         : ե饰 DONT_WAIT ꤷƤʤ硤ե饰ǽ\n         : ݤȤʤäƤΥ٥ȤȯޤԤ³롥\n         : DONT_WAIT ꤷƤ硤оݥ٥ȤʤƤ\n         : ˽λ false ֤\n         : $SAFE >= 4 $SAFE >= 1  flag Ƥʤ\n         : flag ˤ DONT_WAIT Ūդ롥\n\n      set_eventloop_tick(timer_tick)\n         : ٥ȥ롼פƱ̥åɤƯƤˡ\n         : ֤˴ŤŪʥåɥå󥰤ɤ٤\n         : ( ֳִ ) ȯ뤫ߥñ̤ͤǻꤹ롥\n         : 0 ꤹȡζŪʥå󥰤ϹԤʤ\n         : ɸǤ 0 ꤵƤꡤ٥Ƚ˴Ť\n         : 󥰤Ԥ ( see set_eventloop_weight )\n         : ƯƤ륹åɤ٥ȥ롼פξ硤\n         : timer_tick  0 ꤹ뤳ȤϤǤʤ⤷ꤵ\n         : 顤100 ms ( see NO_THREAD_INTERRUPT_TIME ) ˼ư\n         : ꤵ롥\n         : ܺ٤ά CPU ѥ󤷤Ĥİ\n         : ꤷư¸뤿˼ͤǤ롥\n         : $SAFE >= 4 Ǥϼ¹Ԥػߤ롥\n\n      get_eventloop_tick\n         : timer_tick θ֤ͤ\n\n      set_no_event_wait(no_event_wait)\n         : ʣΥåɤƯƤǡԤ٥Ȥ\n         : ¸ߤʤäݤ sleep ֤Ĺꤹ롥\n         : Ưåɤ٥ȥ롼פξˤϰ̣ʤʤ\n         : ǥեȤͤ 20 (ms)\n         : $SAFE >= 4 Ǥϼ¹Ԥػߤ롥\n\n      get_no_event_wait\n         : no_event_wait θ֤ͤ\n\n      set_eventloop_weight(loop_max, no_event_tick)\n         : ʣΥåɤƯƤݤ Ruby/Tk Υ٥ȥ롼\n         : פ˳ƤŤ뤿Υѥ᡼ꤹ롥\n         : Ưåɤ٥ȥ롼פξˤϰ̣ʤʤ\n         : ٤Υåڤؤδ֤˽륤٥Ȥκȡ\n         : ԤΥ٥Ȥ¸ߤʤݤβûȤꤹ롥\n         : Ԥ٥Ȥ¸ߤʤ no_event_wait ( see \n         : set_no_event_wait ) δ sleep ֤롥\n         : ǥեȤǤϤ줾 800  10 󡤤Ĥޤꡤ800 ĤΥ\n         : ٥ (ɥ륤٥Ȥޤ) Ȥ٥\n         : ȯʤޤޤ 80 νԤ٥ȸλ\n\t : ȤǥȤ 800 ʾˤʤȥåɥå\n         : ȯ뤳Ȥˤʤ롥\n         : $SAFE >= 4 Ǥϼ¹Ԥػߤ롥\n\n      get_eventloop_weight\n         : ߤ loop_max  no_event_tick Ȥ֤ͤ\n         : ( see set_eventloop_wait )\n\n      mainloop_abort_on_exception=(bool)\n         : Tk 󥿡ץ꥿㳰ȯݤˡ٥ȥ롼פ\n         : 顼ߤ뤫ɤꤹ롥true ꤷ\n         : 顼ߤ뤬false ξ㳰̵뤷ƥ٥ȥ롼\n         : פ³롥 nil ξϷٹ⡼ɤǤʤ¤ϥ\n         : 顼åνϤάơ㳰̵뤹롥\n\t : ǥեȤǤ true ꤵƤ롥\n         : ĤΥ󥿡ץ꥿ȤäƤˤϥ顼ˤ\n         : ޤߤƤ̾ʤʣΥ󥿡ץ꥿Ʊ\n         : ưƤˤϡ륤٥ȥ롼פϣ\n         : ĤǤ뤿ᡤ줫Υ󥿡ץ꥿Υ顼ǡ\n         : ¾Υ󥿡ץ꥿ν³Բǽˤʤ뤳Ȥ롥\n         : 褦ʾǤ⥨顼̵뤷ƥ٥ȥ롼פƯ³\n         : Ȥǡ¾Υ󥿡ץ꥿ư³뤳ȤǤ롥\n         : $SAFE >= 4 Ǥϼ¹Ԥػߤ롥\n\n      mainloop_abort_on_exception\n         : Tk 󥿡ץ꥿㳰ȯݤˡ٥ȥ롼פ\n         : 顼ߤ뤫ɤ֤ true/false 롥\n\n      num_of_mainwindows\n         : ߤΥᥤ󥦥ɥ (롼ȥå) ο֤\n         : ᥤ󥦥ɥϰĤΥ󥿡ץ꥿դĤǤ\n         : Τǡͤϸ Tk εǽͭǤ륤󥿡ץ꥿\n         : \n\n      _merge_tklist(str, str, ... )\n         : Tcl/Tk Υ饤֥ؿȤäơʸ󤬤줾\n         : ĤΥꥹǤȤʤ褦Ϣ뤷ʸ֤\n\n      _conv_listelement(str)\n         : Tcl/Tk Υ饤֥ؿȤäơʸ Tcl \n         : ĤΥꥹǤȤŬڤɽˤʤ褦Ѵʸ\n         : ֤\n\n      _toUTF8(str, encoding=nil)\n      _fromUTF8(str, encoding=nil)\n         : Tcl/Tk ¢Ƥ UTF8 ѴƤӽФ\n\n      _subst_UTF_backslash(str)\n      _subst_Tcl_backslash(str)\n         : Tcl Υ롼ǥХåå嵭ˡ ( \\uhhhh ˤ \n         : Unicode ʸɽޤ ) Ϥ롥\n         : _subst_Tcl_backslash Ϥ٤ƤΥХåå嵭ˡ\n         : ֤ΤФ_subst_UTF_backslash  \\uhhhh \n         : ˤ Unicode ʸɽ֤롥\n\n      encoding_system\n      encoding_system=(encoding)\n         : Tcl  system encoding γ\n\n      encoding\n      encoding=(encoding)\n         : encoding_system / encoding_system=  alias\n         : ( Ruby/Tk  tk.rb Ǥ֤ͽΤΡ)\n\n\n饹 TclTkIp\n   饹᥽å\n      new(ip_name=nil, options='')\n         : TclTkIp 饹Υ󥹥󥹤롥\n         : ip_name ʸͿϡ줬 winfo interps ʤɤ\n         : ɽ̾ˤʤ롥\n         : options ˤϡ-geometry  -use ʤɡwish Υޥɥ饤\n         : ȤͿ륪ץƱͤξʸȤͿ롥\n         : Ϳ줿ϡroot widget κݤѤ롥\n         : ( e.g. TclTkIp.new('FOO', '-geometry 500x200 -use 0x2200009') )\n         : ⤷ options ˴ nil ޤ false Ϳ硤Tk 饤\n         : ֥꤬ƳƤʤ (Ĥޤ Tcl Τߤ) 󥿡ץ\n         : 롥ξ GUI Ķɬפʤᡤɥ\n         : ƥब¸ߤʤޤϻѤǤʤĶǤ Tcl 󥿡\n         : ץ꥿Tcl 䤽γĥ饤֥Ѥ뤳ȤǤ롥\n\n   󥹥󥹥᥽å\n      create_slave(name, safe=false)\n         : 쥷ФƤȤ name Ȥ̾Υ졼֥󥿡ץ꥿\n\t : 롥\n\t : safe ˤ륤󥿡ץ꥿ safe 󥿡ץ꥿Ȥ\n         : ꤹ롥ǥեȤ false ȤȤˤʤäƤ뤬\n         : ȤΤ false ꤷƤȤƤ⡤ƤȤʤ륤󥿡\n         : ץ꥿ safe 󥿡ץ꥿ǤСѤ \n         : safe 󥿡ץ꥿Ȥ롥\n         : $SAFE >= 4 Ǥϡsafe 󥿡ץ꥿ʳػߤ롥\n\n      make_safe\n         : Tcl/Tk 󥿡ץ꥿ safe 󥿡ץ꥿ѹ롥\n         : ͤϥ쥷ФǤ륤󥿡ץ꥿ȤǤ롥\n         : Ԥ RuntimeError 㳰ȯ롥\n\n      safe?\n         : Tcl/Tk 󥿡ץ꥿ safe 󥿡ץ꥿Ǥ뤫Ĵ٤롥\n         : safe 󥿡ץ꥿Ǥ true ֤\n\n      allow_ruby_exit?\n         : оݤȤʤ륤󥿡ץ꥿ɾǡruby  exit ؿޤ \n         : Tcl/Tk  exit ޥɤˤä ruby Τλ뤳\n         : ɤ֤\n\t : ʤоݤΥ󥿡ץ꥿λ롥\n         : ޥ󥿡ץ꥿Υǥեͤ true졼֥󥿡\n         : ץ꥿Υǥեͤ false Ǥ롥\n\n      allow_ruby_exit=(mode)\n         : оݤȤʤ륤󥿡ץ꥿ allow_ruby_exit? ξ֤ѹ롥\n\t : $SAFE >= 4 ޤϥ󥿡ץ꥿ safe 󥿡ץ꥿ξ\n\t : ѹʤ (㳰ȯ)\n\n      delete\n         : Tcl/Tk 󥿡ץ꥿ delete 롥\n         : delete 줿󥿡ץ꥿ϡʸڤǤʤʤꡤ\n         : ޥɤäƤ㳰ȯ褦ˤʤ롥\n\n      deleted?\n         : Tcl/Tk 󥿡ץ꥿Ǥ delete Ƥ뤫Ĵ٤롥\n         : delete Ѥߤǥޥɤդʤ֤ˤʤäƤʤ\n         : true ֤\n\n      has_mainwindow?\n         : Tcl/Tk 󥿡ץ꥿˥ᥤ󥦥ɥ (root widget) \n         : ¸ߤ true ¸ߤʤ false ֤\n         : 󥿡ץ꥿ delete ѤߤǤ nil ֤\n\n      restart\n         : Tcl/Tk 󥿡ץ꥿ Tk ʬνƵưԤ\n         : ö root widget ˲˺ Tk εǽɬפ\n         : ʤäѤ롥\n         : $SAFE >= 4 Ǥϼ¹Ԥػߤ롥\n\n      _eval(str)\n      _invoke(*args)\n         : Tcl/Tk 󥿡ץ꥿ɾԤ\n         : _eval ɾץȤĤʸǤ뤳ȤФ\n         : _invoke ɾץȤ token Ȥ˰ĤΰȤ\n         : 褦Ϳ롥\n         : _invoke  Tcl/Tk 󥿡ץ꥿λϴѤ\n         : ʤᡤɾ٤꾯ʤƤࡥ\n         :  auto_load Τ褦ʵƯload ˤä\n         : Tcl/Tk 󥿡ץ꥿˴ϿѤߤΥޥɤ\n         : ӽФȤǤʤ\n         : _eval Ǥ auto_load Ưᡤ _eval ¹\n         : ϿСʹߤ _invoke ǤѤ\n         : 褦ˤʤ롥\n\n      _toUTF8(str, encoding=nil)\n      _fromUTF8(str, encoding=nil)\n         : Tcl/Tk ¢Ƥ UTF8 ѴƤӽФ\n\n      _thread_vwait(var_name)\n      _thread_tkwait(mode, target)\n         : åб vwait 뤤 tkwait Υ᥽åɡ\n         : ̾ vwait 뤤 tkwait ޥɤȰۤʤΤϡ٥\n         : ȥ롼פȤϰۤʤ륹åɤƤӽФ vwait \n         : åȤΩ˾ΩԤʤ뤳ȤǤ롥\n         : ̾ vwait / tkwait Ǥϡvwait / tkwait (1) Ԥ\n         : Ǥ vwait / tkwait (2) ƤФ줿硤Ԥо\n         : ȤʤäƤΩɤ졤(2)->(1) νԤ\n         : λäƤ롥\n         : _thread_vwait / _thread_tkwait ϡ٥ȥ롼פΥ\n         : ɤǸƤФ줿̾ vwait / tkwait Ʊͤư\n         : ٥ȥ롼װʳΥåɤǸƤФ줿ˤϤΥ\n         : åɤߤԤꡤ郎Ω˥å\n         : μ¹ԤƳ롥vwait ԤåȤΩפȤ\n         : ̣ϡκƳΥߥ󥰤¾ΥåɤǤԤ\n         : Ȥ̵طȤȤǤ롥Ĥޤꡤ٥ȥ롼¾\n         : Υåɤ vwait Ԥξ֤ˤäȤƤ⤽δλ\n         : ԤĤȤʤԤ郎Ω衤³\n         : Ȥˤʤ롥\n\n      _return_value\n         : ľ Tcl/Tk Ǥɾμ¹Է̤ȤƤ֤ͤ\n\n      _get_variable(var_name, flag)\n      _get_variable2(var_name, index_name, flag)\n         : Tcl/Tk  var Ȥѿ̾ѿ֤ͤ\n         : ⤷ index_name  (PARSE_VARNAME ե饰⻲) \n         : 줿Ϣ var_name  index_name Ǥ֤\n         : flag ˤѿ򸡺ݤξꤹ롥flag Ϳ\n         : ͤϥ⥸塼 TclTkLib::VarAccessFlag 򻲾Ȥ뤳ȡ\n\n      _set_variable(var_name, value, flag)\n      _set_variable2(var_name, index_name, value, flag)\n         : Tcl/Tk  var Ȥѿ̾ѿͤꤹ롥\n         : ⤷ index_name  (PARSE_VARNAME ե饰⻲) \n         : 줿Ϣ var_name  index_name Ǥ\n         : 롥\n         : flag ˤѿ򸡺ݤξꤹ롥flag Ϳ\n         : ͤϥ⥸塼 TclTkLib::VarAccessFlag 򻲾Ȥ뤳ȡ\n\n      _unset_variable(var_name)\n      _unset_variable2(var_name, index_name)\n         : Tcl/Tk  var_name Ȥѿ̾ѿõ롥\n         : ⤷ index_name  (PARSE_VARNAME ե饰⻲) \n         : 줿Ϣ var_name  index_name Ǥ\n         : õ롥\n\n      _get_global_var(var_name)\n      _get_global_var2(var_name, index_name)\n      _set_global_var(var_name, value)\n      _set_global_var2(var_name, index_name, value)\n      _unset_global_var(var_name)\n      _unset_global_var2(var_name, index_name)\n         : 줾졤бѿ᥽åɤ flag Ф\n         : (GLOBAL_ONLY | LEAVE_ERR_MSG) ͿΡ\n\n      _split_tklist(str)\n         : Tcl/Tk Υ饤֥ؿȤäơʸ str ꥹȤ\n         : ʬ䤹 (ʸȤ֤)\n\n      _merge_tklist(str, str, ... )\n         : Tcl/Tk Υ饤֥ؿȤäơʸ󤬤줾\n         : ĤΥꥹǤȤʤ褦Ϣ뤷ʸ֤\n\n      _conv_listelement(str)\n         : Tcl/Tk Υ饤֥ؿȤäơʸ Tcl \n         : ĤΥꥹǤȤŬڤɽˤʤ褦Ѵʸ\n         : ֤\n\n      mainloop\n      mainloop_watchdog\n         : 졼 IP ξˤϥ٥ȥ롼פư nil ֤\n         : ʳǤϰޤ TclTkLib Ʊ̾᥽åɤƱ\n\n      do_one_event\n         : 졼 IP ξˤϰΥ٥ȥե饰 DONT_WAIT \n         : Ūɲä (٥Ԥǥ꡼פ뤳Ȥ϶ػ)\n         : ʳǤϰޤ TclTkLib Ʊ̾᥽åɤƱ\n\n      set_eventloop_tick\n      get_eventloop_tick\n      set_no_event_wait\n      get_no_event_wait\n      set_eventloop_weight\n      get_eventloop_weight\n      mainloop_abort_on_exception\n      mainloop_abort_on_exception=\n         : 졼 IP ξˤ꤬ͤʤ (̵뤵)\n         : ʳǤϰޤ TclTkLib Ʊ̾᥽åɤƱ\n\n      encoding_table\n         : Ruby m17n Ѥ Ruby  Tk Ȥδ֤ encoding бɽ֤\n\n饹 TkCallbackBreak < StandardError\n饹 TkCallbackContinue < StandardError\n   : ϥ٥ȥХåˤơХåŬڤ\n   : ǤꡤΥХɥΥХǥ󥰽˿ʤ᤿ꤹ뤳\n   : ǽˤ뤿㳰饹Ǥ롥\n   : Хå break  continue ¸뤿ˤϡХå\n   : Ǥ Ruby ³ Tcl/Tk 󥿡ץ꥿¦Ŭڤʥ꥿󥳡\n   : ɤ֤ɬפ롥Ruby μ³̤֤ͤΤǤϡ줬\n   : ̤ͤǤΤݤ̤Ǥʤᡤ㳰ȯѤ\n   : ԤäƤ롥\n   : ߤǤϡХå³ Ruby  break, next ǽλ\n   : 뤳ȤƱη̤뤳ȤǤ褦ˤʤäƤ롥椨\n   : ɬפʤΤǤϤ뤬ߴΤ˻ĤƤ롥\n\n(eof)\n"
  },
  {
    "path": "ext/tk/README.1st",
    "content": "If you want to use Ruby/Tk (tk.rb and so on), you must have tcltklib.so \nwhich is working correctly. When you have some troubles on compiling, \nplease read README.tcltklib and README.ActiveTcl. \nEven if there is a tcltklib.so on your Ruby library directry, it will not \nwork without Tcl/Tk libraries (e.g. libtcl8.4.so) on your environment. \nYou must also check that your Tcl/Tk is installed properly. \n\n--------------------------------------------\n ( the following is written in EUC-JP )\n\nRuby/Tk (tk.rb ʤ) Ȥˤϡtcltklib.so ưƤ\nФʤޤ󡥥ѥ˲꤬ϡREADME.tcltklib \n README.ActiveTcl 򸫤Ƥ\nȤ Ruby Υ饤֥ǥ쥯ȥ tcltklib.so ¸ߤƤȤ\n⡤¹ԴĶ Tcl/Tk 饤֥ (libtcl8.4.so ʤ) ʤеǽ\nTcl/Tk 󥹥ȡ뤵Ƥ뤫åƤ\n\n==========================================================\n                Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n"
  },
  {
    "path": "ext/tk/README.ActiveTcl",
    "content": "ActiveTcl is ActiveState's quality-assured distribution of Tcl. \n\n# see <http://www.activestate.com/Products/ActiveTcl/>\n#     <http://www.tcl.tk/>\n\nIf you want to use ActiveTcl binary package as the Tcl/Tk libraries, \nplease use the following configure options.\n\n   --with-tcl-dir=<ActiveTcl_root>\n   --with-tk-dir=<ActiveTcl_root>\n\nAnd use the followings if you need.\n\n   --with-tcllib=<libname>\n   --with-tklib=<libname>\n   --enable-tcltk-stubs\n\nFor example, when you install ActiveTcl-8.4.x to '/usr/local/ActiveTcl', \n\n   configure --with-tcl-dir=/usr/local/ActiveTcl/  \\\n             --with-tk-dir=/usr/local/ActiveTcl/   \\\n             --with-tcllib=tclstub8.4              \\\n             --with-tklib=tkstub8.4                \\\n             --enable-tcltk-stubs\n\nIt depends on your environment that you have to add the directory of \nActiveTcl's libraries to your library path when execute Ruby/Tk. \nOne of the way is to add entries to TCLLIBPATH environment variable, \nand one of the others add to LD_LIBRARY_PATH environment variable\n\nProbably, using TCLLIBPATH is better. The value is appended at the \nhead of Tcl's 'auto_path' variable. You can see the value of the \nvariable by using 'Tk::AUTO_PATH.value' or 'Tk::AUTO_PATH.list'.\n\nFor example, on Linux, one of the ways is to use LD_LIBRARY_PATH \nenvironment variable. \n-------------------------------------------------------------------------\n [bash]$ LD_LIBRARY_PATH=/usr/local/ActiveTcl/lib:$LD_LIBRARY_PATH \\\n         ruby your-Ruby/Tk-script\n\n [bash]$ LD_LIBRARY_PATH=/usr/local/ActiveTcl/lib:$LD_LIBRARY_PATH irb\n-------------------------------------------------------------------------\nBased on it, the Tcl interpreter changes auto_path variable's value.\n\nThen, you'll be able to use Tcl/Tk extension libraries included in the\nActiveTcl package (e.g. call TkPackage.require('BWidget'), and then,\nuse functions/widgets of BWidget extention). \n\n                                  Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n"
  },
  {
    "path": "ext/tk/README.fork",
    "content": "Ruby/Tk does NOT support forking the process on which Tk interpreter\nis running (unless NEVER control Tk interpreter under the forked child \nprocess). In the library 'tk.rb', a Tk interpreter is initialized. \nTherefore, if you want running Tk under a child process, please call\n\"require 'tk'\" in the child process. \n\n# If do fork and exec(<new Ruby/Tk>) on the child process, you can \n# control Ruby/Tk interpreter on the child process by 'send' command \n# of Tcl/Tk. About this, please see Tk.appsend and Tk.rb_appsend, or \n# 'remote-tk.rb' and the sample 'sample/remote-ip_sample.rb'. \n\nFor example, the following sample1 will NOT work, and sample2 will\nwork properly.\n\n---<sample1: NOT work>---------------------------------------\nrequire 'tk'  ## init Tk interpreter under parent process\n\nexit! if fork ## exit parent process\n\n## child process\nTkButton.new(:text=>'QUIT', :command=>proc{exit}).pack\nTk.mainloop\n-------------------------------------------------------------\n\n---<sample2: will work>--------------------------------------\nexit! if fork ## exit main process\n\n## child process\nrequire 'tk'  ## init Tk interpreter under child process\nTkButton.new(:text=>'QUIT', :command=>proc{exit}).pack\nTk.mainloop\n-------------------------------------------------------------\n\n                                         2004/05/22  Hidetoshi NAGAI\n"
  },
  {
    "path": "ext/tk/README.macosx-aqua",
    "content": "\n  *** for MacOS X Aqua (Tcl/Tk Aqua) users ***\n\nFirst of all, please read README.tcltklib to use Tcl/Tk Aqua Framework.\n\nWith Tcl/Tk Aqua libraries, current tcltklib somtimes freezes when \nusing Aqua specific dialogs (e.g. Tk.messageBox). \nThis is a known bug of Ruby-1.8.4 release.\n\nWhen you meet the trouble on your GUI, you'll be able to avoid the trouble \nby Tcl/Tk's traditional dialogs. \nIf you want to do that, please call some of the following bits of script \nafter \"reqruie 'tk'\".\n\n=================================================================\n# use a traditional dialog for Tk.chooseColor()\nTk.ip_eval(<<'EOS')\n    proc ::tk_chooseColor {args} {\n        return [eval tk::dialog::color:: $args]\n    }\nEOS\n\n# use a traditional dialog for Tk.getOpenFile() and Tk.getMultipleOpenFile()\nTk.ip_eval(<<'EOS')\n    proc ::tk_getOpenFile {args} {\n        if {$::tk_strictMotif} {\n            return [eval tk::MotifFDialog open $args]\n        } else {\n            return [eval ::tk::dialog::file:: open $args]\n        }\n    }\nEOS\n\n# use a traditional dialog for Tk.getSaveFile() and Tk.getMultipleSaveFile()\nTk.ip_eval(<<'EOS')\n    proc ::tk_getSaveFile {args} {\n        if {$::tk_strictMotif} {\n            return [eval tk::MotifFDialog save $args]\n        } else {\n            return [eval ::tk::dialog::file:: save $args]\n        }\n    }\nEOS\n\n# use a traditional dialog for Tk.messageBox()\nTk.ip_eval(<<'EOS')\n    proc ::tk_messageBox {args} {\n        return [eval tk::MessageBox $args]\n    }\nEOS\n\n# use a traditional dialog for Tk.chooseDirectory()\nTk.ip_eval(<<'EOS')\n    proc ::tk_chooseDirectory {args} {\n        return [eval ::tk::dialog::file::chooseDir:: $args]\n    }\nEOS\n=================================================================\n\nEach of them replaces the platform specific dialog command to the \ntraditional one. \n\nIf you use some MultiTkIp objects, probably, you'll have to call the \nbits of script for each MultiTkIp object. \n\n-- \nHidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n"
  },
  {
    "path": "ext/tk/README.tcltklib",
    "content": "To compile 'tcltklib', you must have Tcl/Tk libraries on your environment. \nAlthough 'extconf.rb' script searches Tcl/Tk libraries and header files, \nsometimes fails to find them. And then, 'tcltklib' cannot be compiled. If \nTcl/Tk libraries or header files are installed but are not found, you can \ngive the information by arguments of the 'configure' script. Please give \nsome or all of the following options. \n\n --with-tcltkversion=<version> \n      force version of Tcl/Tk libaray\n      (e.g. libtcl8.4g.so ==> --with-tcltkversion=8.4g)\n\n --with-tcllib=<libname>       (e.g. libtcl8.4.so ==> --with-tcllib=tcl8.4)\n --with-tklib=<libname>        (e.g. libtk8.4.so  ==> --with-tklib=tk8.4)\n\n --enable-tcltk-stubs          (if you force to enable stubs)\n\n --with-tcl-dir=<path> \n      equal to \"--with-tcl-include=<path>/include --with-tcl-lib=<path>/lib\"\n\n --with-tk-dir=<path> \n      equal to \"--with-tk-include=<path>/include --with-tk-lib=<path>/lib\"\n\n --with-tcl-include=<dir>      the directry contains 'tcl.h'\n --with-tk-include=<dir>       the directry contains 'tk.h'\n\n --with-tcl-lib=<dir>          the directry contains 'libtcl<version>.so'\n --with-tk-lib=<dir>           the directry contains 'libtk<version>.so'\n\n --enable-mac-tcltk-framework  (MacOS X) use Tcl/Tk framework\n                               (Obsolete. Please use '--enable-tcltk-framework'.)\n\n --enable-tcltk-framework      use Tcl/Tk framework\n\n --with-tcltk-framework=<dir>  the directory contains Tcl/Tk framework; \n                               \"<dir>/Tcl.framework\" and \"<dir>/Tk.framework\".\n                               When this option is given, it is assumed that \n                               --enable-tcltk-framework option is given also.\n\n --with-tcl-framework-header=<dir>\n      Tcl framework headers directory \n      (e.g. \"/Library/Frameworks/Tcl.framework/Headers\")\n\n --with-tk-framework-header=<dir>\n      Tk framework headers directory \n      (e.g. \"/Library/Frameworks/Tk.framework/Headers\")\n\n\n --with-X11 / --without-X11    use / not use the X Window System\n\n --with-X11-dir=<path> \n      equal to \"--with-X11-include=<path>/include --with-X11-lib=<path>/lib\"\n\n --with-X11-include=<dir>      the directry contais X11 header files\n --with-X11-lib=<dir>          the directry contais X11 libraries\n\n\nIf you forgot to give the options when do 'configure' on toplevel\ndirectry of Ruby sources, please try something like as the followings.\n\n $ cd ext/tcltklib\n $ rm Makefile\n $ CONFIGURE_ARGS='--with-tcl-include=/usr/local/include/tcl8.4/ --with-tcllib=tcl8.4 --with-tklib=tk8.4' ruby extconf.rb\n\n\n *** ATTENTION ***\nWhen your Tcl/Tk libraries are compiled with \"pthread support\", \nRuby/Tk may cause \"Hang-up\" or \"Segmentation Fault\" frequently. \nIf you have such a trouble, please try to use the '--enable-pthread' \noption of the 'configure' command and re-compile Ruby sources. \nIt may help you to avoid this trouble. The following configure \noptions may be useful.\n\n  --enable-tcl-thread/--disable-tcl-thread\n  --with-tclConfig-file=<path of 'tclConfig.sh'>\n\nIt is not need that 'tclConfig.sh' is a normal Tcl/Tk's tclConfig.sh. \nBut the file is expected to include the line \"TCL_THREADS=0\" or \"...=1\".\nWhen no \"TCL_THREADS=?\" line, if Tcl version is 7.x or 8.0 which is \ngiven by \"TCL_MAJOR_VERSION=?\" line and \"TCL_MINOR_VERSION=?\" line, \nthen --disable-tcl-thread is expected. Else, ignore the 'tclConfig.sh'.\nIf --enable-tcl-thread or --disable-tcl-thread option is given, then \n--with-tclConfig-file option is ignored. \n\n==========================================================\n                Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n"
  },
  {
    "path": "ext/tk/depend",
    "content": "tcltklib.o: tcltklib.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\nstubs.o: stubs.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/tk/extconf.rb",
    "content": "# extconf.rb for tcltklib\n\nrequire 'mkmf'\n\n#is_win32 = (/mswin32|mingw|cygwin|bccwin32/ =~ RUBY_PLATFORM)\nis_win32 = (/mswin|mingw|cygwin|bccwin|wince/ =~ RUBY_PLATFORM)\n#is_macosx = (/darwin/ =~ RUBY_PLATFORM)\n\ndef find_framework(tcl_hdr, tk_hdr)\n  if framework_dir = with_config(\"tcltk-framework\")\n    paths = [framework_dir]\n  else\n    unless tcl_hdr || tk_hdr ||\n        enable_config(\"tcltk-framework\", false) ||\n        enable_config(\"mac-tcltk-framework\", false)\n      return false\n    end\n    paths = [\"/Library/Frameworks\", \"/System/Library/Frameworks\"]\n  end\n\n  checking_for('Tcl/Tk Framework') {\n    paths.find{|dir|\n      dir.strip!\n      dir.chomp!('/')\n      (tcl_hdr || FileTest.directory?(dir + \"/Tcl.framework/\") ) &&\n        (tk_hdr || FileTest.directory?(dir + \"/Tk.framework/\") )\n    }\n  }\nend\n\ntcl_framework_header = with_config(\"tcl-framework-header\")\ntk_framework_header  = with_config(\"tk-framework-header\")\n\ntcltk_framework = find_framework(tcl_framework_header, tk_framework_header)\n\nunless is_win32\n  have_library(\"nsl\", \"t_open\")\n  have_library(\"socket\", \"socket\")\n  have_library(\"dl\", \"dlopen\")\n  have_library(\"m\", \"log\") \nend\n\ntk_idir,  tk_ldir  = dir_config(\"tk\")\ntcl_idir, tcl_ldir = dir_config(\"tcl\")\nx11_idir, x11_ldir = dir_config(\"X11\")\n\ntk_ldir2  = with_config(\"tk-lib\")\ntcl_ldir2 = with_config(\"tcl-lib\")\nx11_ldir2 = with_config(\"X11-lib\")\n\ntk_ldir_list  = [tk_ldir2,  tk_ldir]\ntcl_ldir_list = [tcl_ldir2, tcl_ldir]\n\ntklib = with_config(\"tklib\")\ntcllib = with_config(\"tcllib\")\nstubs = enable_config(\"tcltk_stubs\") || with_config(\"tcltk_stubs\")\n\ntcltk_version = with_config(\"tcltkversion\")\n\nuse_X = with_config(\"X11\", (! is_win32))\n\ndef check_tcltk_version(version)\n  return [nil, nil] unless version\n\n  version = version.strip\n\n  tclver = version.dup\n  tkver  = version.dup\n\n  major = dot = minor = dot = plvl = ext = nil\n\n  if version =~ /^(\\d)(\\.?)(\\d)(\\.?)(\\d*)(.*)$/\n    major = $1; minor_dot = $2; minor = $3; plvl_dot  = $4; plvl = $5; ext = $6\n    dot = ! minor_dot.empty?\n    if plvl_dot.empty? && ! plvl.empty?\n      minor << plvl\n    end\n  elsif version =~ /^(\\d)(\\.?)(\\d?)(.*)$/\n    major = $1; minor_dot = $2; minor = $3; ext = $4\n    dot = ! minor_dot.empty?\n  else # unknown -> believe user\n    return [tclver, tkver]\n  end\n\n  # check Tcl7.6 / Tk4.2 ?\n  if major == \"7\" # Tcl7.6 ( not support Tclversion < 7.6 )\n    # Tk4.2\n    tkver  = \"4\" + ((dot)? \".\": \"\") + ((minor.empty)? \"\": \"2\") + ext\n  elsif major == \"4\" # Tk4.2 ( not support Tkversion < 4.2 )\n    # Tcl7.6\n    tclver = \"7\" + ((dot)? \".\": \"\") + ((minor.empty)? \"\": \"6\") + ext\n  end\n\n  [tclver, tkver]\nend\n\ndef find_tcl(tcllib, stubs, version, *opt_paths)\n  default_paths = [\"/usr/local/lib\", \"/usr/pkg/lib\", \"/usr/lib\"]\n  default_paths << \"/Tcl/lib\"  # default for ActiveTcl\n\n  if (paths = opt_paths.compact).empty?\n    paths = default_paths\n  end\n\n  if stubs\n    func = \"Tcl_InitStubs\"\n    lib = \"tclstub\"\n  else\n    func = \"Tcl_FindExecutable\"\n    lib = \"tcl\"\n  end\n\n  if version && ! version.empty?\n    versions = [version]\n  else\n    versions = %w[8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]\n  end\n\n  if tcllib\n    st = find_library(tcllib, func, *paths)\n  else\n    st = versions.find { |ver|\n           find_library(\"#{lib}#{ver}\", func, *paths) or\n           find_library(\"#{lib}#{ver.delete('.')}\", func, *paths) or\n           find_library(\"#{lib}#{ver}g\", func, *paths) or\n           find_library(\"#{lib}#{ver.delete('.')}g\", func, *paths) or\n           find_library(\"tcl#{ver}\", func, *paths) or\n           find_library(\"tcl#{ver.delete('.')}\", func, *paths) or\n           find_library(\"tcl#{ver}g\", func, *paths) or\n           find_library(\"tcl#{ver.delete('.')}g\", func, *paths)\n         } || (!version && find_library(lib, func, *paths))\n  end\n\n  unless st\n    puts(\"Warning:: cannot find Tcl library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options.\")\n  end\n  st\nend\n\ndef find_tk(tklib, stubs, version, *opt_paths)\n  default_paths = [\"/usr/local/lib\", \"/usr/pkg/lib\", \"/usr/lib\"]\n  default_paths << \"/Tcl/lib\"  # default for ActiveTcl\n\n  if (paths = opt_paths.compact).empty?\n    paths = default_paths\n  end\n\n  if stubs\n    func = \"Tk_InitStubs\"\n    lib = \"tkstub\"\n  else\n    func = \"Tk_Init\"\n    lib = \"tk\"\n  end\n\n  if version && ! version.empty?\n    versions = [version]\n  else\n    versions = %w[8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]\n  end\n\n  if tklib\n    st = find_library(tklib, func, *paths)\n  else\n    st = versions.find { |ver|\n           find_library(\"#{lib}#{ver}\", func, *paths) or\n           find_library(\"#{lib}#{ver.delete('.')}\", func, *paths) or\n           find_library(\"#{lib}#{ver}g\", func, *paths) or\n           find_library(\"#{lib}#{ver.delete('.')}g\", func, *paths) or\n           find_library(\"tk#{ver}\", func, *paths) or\n           find_library(\"tk#{ver.delete('.')}\", func, *paths) or \n           find_library(\"tk#{ver}g\", func, *paths) or\n           find_library(\"tk#{ver.delete('.')}g\", func, *paths)\n         } || (!version && find_library(lib, func, *paths))\n  end\n\n  unless st\n    puts(\"Warning:: cannot find Tk library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options.\")\n  end\n  st\nend\n\ndef find_X11(*opt_paths)\n  default_paths = \n    [ \"/usr/X11/lib\", \"/usr/lib/X11\", \"/usr/X11R6/lib\", \"/usr/openwin/lib\" ]\n  paths = opt_paths.compact.concat(default_paths)\n  st = find_library(\"X11\", \"XOpenDisplay\", *paths)\n  unless st\n    puts(\"Warning:: cannot find X11 library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options. If your Tcl/Tk don't require X11, please try --without-X11.\")\n  end\n  st\nend \n\ndef pthread_check()\n  tcl_major_ver = nil\n  tcl_minor_ver = nil\n\n  # Is tcl-thread given by user ?\n  case enable_config(\"tcl-thread\")\n  when true\n    tcl_enable_thread = true\n  when false\n    tcl_enable_thread = false\n  else\n    tcl_enable_thread = nil\n  end\n\n  if (tclConfig = with_config(\"tclConfig-file\"))\n    if tcl_enable_thread == true\n      puts(\"Warning: --with-tclConfig-file option is ignored, because --enable-tcl-thread option is given.\")\n    elsif tcl_enable_thread == false\n      puts(\"Warning: --with-tclConfig-file option is ignored, because --disable-tcl-thread option is given.\")\n    else\n      # tcl-thread is unknown and tclConfig.sh is given\n      begin\n        open(tclConfig, \"r\") do |cfg|\n          while line = cfg.gets()\n            if line =~ /^\\s*TCL_THREADS=(0|1)/\n              tcl_enable_thread = ($1 == \"1\")\n              break\n            end\n\n            if line =~ /^\\s*TCL_MAJOR_VERSION=(\"|')(\\d+)\\1/\n              tcl_major_ver = $2\n              if tcl_major_ver =~ /^[1-7]$/\n                tcl_enable_thread = false\n                break\n              end\n              if tcl_major_ver == \"8\" && tcl_minor_ver == \"0\"\n                tcl_enable_thread = false\n                break\n              end\n            end\n\n            if line =~ /^\\s*TCL_MINOR_VERSION=(\"|')(\\d+)\\1/\n              tcl_minor_ver = $2\n              if tcl_major_ver == \"8\" && tcl_minor_ver == \"0\"\n                tcl_enable_thread = false\n                break\n              end\n            end\n          end\n        end\n\n        if tcl_enable_thread == nil\n          # not find definition\n          if tcl_major_ver\n            puts(\"Warning: '#{tclConfig}' doesn't include TCL_THREADS definition.\")\n          else\n            puts(\"Warning: '#{tclConfig}' may not be a tclConfig file.\")\n          end\n          tclConfig = false\n        end\n      rescue Exception\n        puts(\"Warning: fail to read '#{tclConfig}'!! --> ignore the file\")\n        tclConfig = false\n      end\n    end\n  end\n\n  if tcl_enable_thread == nil && !tclConfig\n    # tcl-thread is unknown and tclConfig is unavailable\n    begin\n      try_run_available = try_run(\"int main() { exit(0); }\")\n    rescue Exception\n      # cannot try_run. Is CROSS-COMPILE environment?\n      puts(%Q'\\\n*****************************************************************************\n**\n** PTHREAD SUPPORT CHECK WARNING: \n**\n**   We cannot check the consistency of pthread support between Ruby \n**   and the Tcl/Tk library in your environment (are you perhaps\n**   cross-compiling?). If pthread support for these 2 packages is\n**   inconsistent you may find you get errors when running Ruby/Tk\n**   (e.g. hangs or segmentation faults).  We strongly recommend\n**   you to check the consistency manually.\n**\n*****************************************************************************\n')\n      return true\n    end\n  end\n\n  if tcl_enable_thread == nil\n    # tcl-thread is unknown\n    if try_run(<<EOF)\n#include <tcl.h>\nint main() { \n   Tcl_Interp *ip;\n   ip = Tcl_CreateInterp();\n   exit((Tcl_Eval(ip, \"set tcl_platform(threaded)\") == TCL_OK)? 0: 1);\n}\nEOF\n      tcl_enable_thread = true\n    elsif try_run(<<EOF)\n#include <tcl.h>\nstatic Tcl_ThreadDataKey dataKey;\nint main() { exit((Tcl_GetThreadData(&dataKey, 1) == dataKey)? 1: 0); }\nEOF\n      tcl_enable_thread = true\n    else\n      tcl_enable_thread = false\n    end\n  end\n\n  # check pthread mode\n  if (macro_defined?('HAVE_NATIVETHREAD', '#include \"ruby.h\"'))\n    # ruby -> enable\n    unless tcl_enable_thread\n      # ruby -> enable && tcl -> disable\n      puts(%Q'\\\n*****************************************************************************\n**\n** PTHREAD SUPPORT MODE WARNING: \n**\n**   Ruby is compiled with --enable-pthread, but your Tcl/Tk library\n**   seems to be compiled without pthread support. Although you can\n**   create the tcltklib library, this combination may cause errors\n**   (e.g. hangs or segmentation faults). If you have no reason to\n**   keep the current pthread support status, we recommend you reconfigure\n**   and recompile the libraries so that both or neither support pthreads.\n**\n**   If you want change the status of pthread support, please recompile \n**   Ruby without \"--enable-pthread\" configure option or recompile Tcl/Tk \n**   with \"--enable-threads\" configure option (if your Tcl/Tk is later \n**   than or equal to Tcl/Tk 8.1).\n**\n*****************************************************************************\n')\n    end\n\n    # ruby -> enable && tcl -> enable/disable\n    if tcl_enable_thread\n      $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1'\n    else\n      $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0'\n    end\n\n    return true\n\n  else\n    # ruby -> disable\n    if tcl_enable_thread\n      # ruby -> disable && tcl -> enable\n      puts(%Q'\\\n*****************************************************************************\n**\n** PTHREAD SUPPORT MODE ERROR: \n**\n**   Ruby is not compiled with --enable-pthread, but your Tcl/Tk \n**   library seems to be compiled with pthread support. This\n**   combination may cause frequent hang or segmentation fault\n**   errors when Ruby/Tk is working. We recommend that you NEVER\n**   create the library with such a combination of pthread support.\n**\n**   Please recompile Ruby with the \"--enable-pthread\" configure option\n**   or recompile Tcl/Tk with the \"--disable-threads\" configure option.\n**\n*****************************************************************************\n')\n      $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1'\n      return false\n    else\n      # ruby -> disable && tcl -> disable\n      $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0'\n      return true\n    end\n  end\nend\n\ntclver, tkver = check_tcltk_version(tcltk_version)\n\nif have_header(\"tcl.h\") && have_header(\"tk.h\") && \n    ( tcltk_framework || \n        ( ( !use_X || find_X11(x11_ldir2, x11_ldir) ) &&\n            find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) &&\n            find_tk(tklib, stubs, tkver, *tk_ldir_list) ) )\n  $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs\n  $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM\n\n  if tcltk_framework\n    if tcl_framework_header\n      $CPPFLAGS += \" -I#{tcl_framework_header}\"\n    else\n      $CPPFLAGS += \" -I#{tcltk_framework}/Tcl.framework/Headers\"\n    end\n\n    if tk_framework_header\n      $CPPFLAGS += \" -I#{tk_framework_header}\"\n    else\n      $CPPFLAGS += \" -I#{tcltk_framework}/Tk.framework/Headers\"\n    end\n\n    $LDFLAGS += ' -framework Tk -framework Tcl'\n  end\n\n  if stubs or pthread_check\n    # create Makefile\n\n    # for SUPPORT_STATUS\n    $INSTALLFILES ||= []\n    $INSTALLFILES << [\"lib/tkextlib/SUPPORT_STATUS\", \"$(RUBYLIBDIR)\", \"lib\"]\n\n    have_func(\"rb_hash_lookup\", \"ruby.h\")\n\n    # create\n    $defs << %[-DRUBY_VERSION=\\\\\"#{RUBY_VERSION}\\\\\"]\n    $defs << %[-DRUBY_RELEASE_DATE=\\\\\"#{RUBY_RELEASE_DATE}\\\\\"]\n    create_makefile(\"tcltklib\")\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/README",
    "content": "README\t\tthis file\nmulti-tk.rb\tmultiple Tk interpreter (included safe-Tk) support\nremotei-tk.rb\tcontrol remote Tk interpreter on the other process support\ntk.rb\t\tTk interface\n\ntk/             library files construct Ruby/Tk\n\ntkextlib/       non-standard Tcl/Tk extension support libraries\n\n*********************************************************************\n***  The followings exists for backward compatibility only.\n***  The only thing which they work is that requires current \n***  library files ( tk/*.rb ). \n*********************************************************************\ntkafter.rb\thandles Tcl after\ntkbgerror.rb\tTk error module\ntkcanvas.rb\tTk canvas interface\ntkclass.rb\tprovides generic names for Tk classes\ntkconsole.rb\tconsole command support\ntkdialog.rb\tTk dialog class\ntkentry.rb\tTk entry class\ntkfont.rb\tTk font support\ntkmacpkg.rb\tMac resource support\ntkmenubar.rb\tTK menubar utility\ntkmngfocus.rb\tfocus manager\ntkpalette.rb\tpallete support\ntkscrollbox.rb\tscroll box, also example of compound widget\ntktext.rb\ttext classes\ntkvirtevent.rb\tvirtual event support\ntkwinpkg.rb\tWin DDE and registry support\n"
  },
  {
    "path": "ext/tk/lib/multi-tk.rb",
    "content": "#\n#               multi-tk.rb - supports multi Tk interpreters\n#                       by Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\nrequire 'tcltklib'\nrequire 'tkutil'\nrequire 'thread'\n\nif defined? Tk\n  fail RuntimeError,\"'multi-tk' library must be required before requiring 'tk'\"\nend\n\n################################################\n# ignore exception on the mainloop?\n\nTclTkLib.mainloop_abort_on_exception = true\n# TclTkLib.mainloop_abort_on_exception = false\n# TclTkLib.mainloop_abort_on_exception = nil\n\n\n################################################\n# add ThreadGroup check to TclTkIp.new\nclass << TclTkIp\n  alias __new__ new\n  private :__new__\n\n  def new(*args)\n    if Thread.current.group != ThreadGroup::Default\n      raise SecurityError, 'only ThreadGroup::Default can call TclTkIp.new'\n    end\n    __new__(*args)\n  end\nend\n\n\n################################################\n# use pseudo-toplevel feature of MultiTkIp ?\nif (!defined?(Use_PseudoToplevel_Feature_of_MultiTkIp) || \n      Use_PseudoToplevel_Feature_of_MultiTkIp)\n  module MultiTkIp_PseudoToplevel_Evaluable\n    #def pseudo_toplevel_eval(body = Proc.new)\n    #  Thread.current[:TOPLEVEL] = self\n    #  begin\n    #    body.call\n    #  ensure\n    #    Thread.current[:TOPLEVEL] = nil\n    #  end\n    #end\n\n    def pseudo_toplevel_evaluable?\n      @pseudo_toplevel_evaluable\n    end\n\n    def pseudo_toplevel_evaluable=(mode)\n      @pseudo_toplevel_evaluable = (mode)? true: false\n    end\n\n    def self.extended(mod)\n      mod.__send__(:extend_object, mod)\n      mod.instance_variable_set('@pseudo_toplevel_evaluable', true)\n    end\n  end\n\n  class Object\n    alias __method_missing_alias_for_MultiTkIp__ method_missing\n    private :__method_missing_alias_for_MultiTkIp__\n\n    def method_missing(id, *args)\n      begin\n        has_top = (top = MultiTkIp.__getip.__pseudo_toplevel) && \n          top.respond_to?(:pseudo_toplevel_evaluable?) && \n          top.pseudo_toplevel_evaluable? && \n          top.respond_to?(id)\n      rescue Exception => e\n        has_top = false\n      end\n\n      if has_top\n        top.__send__(id, *args)\n      else\n        __method_missing_alias_for_MultiTkIp__(id, *args)\n      end\n    end\n  end\nelse\n  # dummy\n  module MultiTkIp_PseudoToplevel_Evaluable\n    def pseudo_toplevel_evaluable?\n      false\n    end\n  end\nend\n\n################################################\n# exceptiopn to treat the return value from IP\nclass MultiTkIp_OK < Exception\n  def self.send(thread, ret=nil)\n    thread.raise self.new(ret)\n  end\n\n  def initialize(ret=nil)\n    super('succeed')\n    @return_value = ret\n  end\n\n  attr_reader :return_value\n  alias value return_value\nend\nMultiTkIp_OK.freeze\n\n\n################################################\n# methods for construction\nclass MultiTkIp\n  BASE_DIR = File.dirname(__FILE__)\n\n  WITH_RUBY_VM  = Object.const_defined?(:VM) && ::VM.class == Class\n  WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class\n\n  (@@SLAVE_IP_ID = ['slave'.freeze, '0'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)\n\n  @@INIT_IP_ENV  = [].taint unless defined?(@@INIT_IP_ENV)  # table of Procs\n  @@ADD_TK_PROCS = [].taint unless defined?(@@ADD_TK_PROCS) # table of [name, args, body]\n\n  @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST)\n\n  unless defined?(@@TK_CMD_TBL)\n    @@TK_CMD_TBL = Object.new.taint\n\n    # @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint)\n    @@TK_CMD_TBL.instance_variable_set('@tbl', Hash.new{|hash,key|\n                                           fail IndexError, \n                                                \"unknown command ID '#{key}'\"\n                                       }.taint)\n\n    class << @@TK_CMD_TBL\n      allow = [\n        '__send__', '__id__', 'freeze', 'inspect', 'kind_of?', 'object_id', \n        '[]', '[]=', 'delete', 'each', 'has_key?'\n      ]\n      instance_methods.each{|m| undef_method(m) unless allow.index(m.to_s)}\n\n      def kind_of?(klass)\n        @tbl.kind_of?(klass)\n      end\n\n      def inspect\n        if Thread.current.group == ThreadGroup::Default\n          @tbl.inspect\n        else\n          ip = MultiTkIp.__getip\n          @tbl.reject{|idx, ent| ent.respond_to?(:ip) && ent.ip != ip}.inspect\n        end\n      end\n\n      def [](idx)\n        return unless (ent = @tbl[idx])\n        if Thread.current.group == ThreadGroup::Default\n          ent\n        elsif ent.respond_to?(:ip)\n          (ent.ip == MultiTkIp.__getip)? ent: nil\n        else\n          ent\n        end\n      end\n\n      def []=(idx,val)\n        if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default\n          fail SecurityError,\"cannot change the entried command\"\n        end\n        @tbl[idx] = val\n      end\n\n      def delete(idx, &blk)\n        # if gets an entry, is permited to delete\n        if self[idx]\n          @tbl.delete(idx) \n        elsif blk\n          blk.call(idx)\n        else\n          nil\n        end\n      end\n\n      def each(&blk)\n        if Thread.current.group == ThreadGroup::Default\n          @tbl.each(&blk)\n        else\n          ip = MultiTkIp.__getip\n          @tbl.each{|idx, ent|\n            blk.call(idx, ent) unless ent.respond_to?(:ip) && ent.ip != ip\n          }\n        end\n        self\n      end\n\n      def has_key?(k)\n        @tbl.has_key?(k)\n      end\n      alias include? has_key?\n      alias key? has_key?\n      alias member? has_key?\n    end\n\n    @@TK_CMD_TBL.freeze\n  end\n\n  ######################################\n\n  @@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){\n    def initialize(ip, cmd)\n      @ip = ip\n      @cmd = cmd\n      self.freeze\n    end\n    attr_reader :ip, :cmd\n    def inspect\n      cmd.inspect\n    end\n    def call(*args)\n      unless @ip.deleted?\n        current = Thread.current\n        backup_ip = current['callback_ip']\n        current['callback_ip'] = @ip\n        begin\n          ret = @ip.cb_eval(@cmd, *args)\n          fail ret if ret.kind_of?(Exception)\n          ret\n        rescue TkCallbackBreak, TkCallbackContinue => e\n          fail e\n\trescue SecurityError => e\n          # in 'exit', 'exit!', and 'abort' : security error --> delete IP\n          if e.backtrace[0] =~ /^(.+?):(\\d+):in `(exit|exit!|abort)'/\n\t    @ip.delete\n          elsif @ip.safe?\n\t    if @ip.respond_to?(:cb_error)\n              @ip.cb_error(e)\n            else\n              nil # ignore\n            end\n          else\n            fail e\n          end\n        rescue Exception => e\n          fail e if e.message =~ /^TkCallback/\n\n          if @ip.safe?\n\t    if @ip.respond_to?(:cb_error)\n              @ip.cb_error(e)\n            else\n              nil # ignore\n            end\n          else\n            fail e\n          end\n        ensure\n          current['callback_ip'] = backup_ip\n        end\n      end\n    end\n  }.freeze\n\n  ######################################\n\n  def _keys2opts(src_keys)\n    return nil if src_keys == nil\n    keys = {}; src_keys.each{|k, v| keys[k.to_s] = v}\n    #keys.collect{|k,v| \"-#{k} #{v}\"}.join(' ')\n    keys.collect{|k,v| \"-#{k} #{TclTkLib._conv_listelement(TkComm::_get_eval_string(v))}\"}.join(' ')\n  end\n  private :_keys2opts\n\n  def _check_and_return(thread, exception, wait=0)\n    unless thread\n      unless exception.kind_of?(MultiTkIp_OK)\n        msg = \"#{exception.class}: #{exception.message}\"\n\n        if @interp.deleted?\n          warn(\"Warning (#{self}): \" + msg)\n          return nil\n        end\n\n        if safe?\n          warn(\"Warning (#{self}): \" + msg) if $DEBUG\n          return nil\n        end\n\n        begin\n          @interp._eval_without_enc(@interp._merge_tklist('bgerror', msg))\n        rescue Exception => e\n          warn(\"Warning (#{self}): \" + msg)\n        end\n      end\n      return nil\n    end\n\n    if wait == 0\n      # no wait\n      Thread.pass\n      if thread.stop?\n        thread.raise exception\n      end\n      return thread\n    end\n\n    # wait to stop the caller thread\n    wait.times{\n      if thread.stop?\n        # ready to send exception\n        thread.raise exception\n        return thread\n      end\n\n      # wait\n      Thread.pass\n    }\n\n    # unexpected error\n    thread.raise RuntimeError, \"the thread may not wait for the return value\"\n    return thread\n  end\n\n  ######################################\n\n  def set_cb_error(cmd = Proc.new)\n    @cb_error_proc[0] = cmd\n  end\n\n  def cb_error(e)\n    if @cb_error_proc[0].respond_to?(:call)\n      @cb_error_proc[0].call(e)\n    end\n  end\n\n  ######################################\n\n  def set_safe_level(safe)\n    if safe > @safe_level[0]\n      @safe_level[0] = safe\n      @cmd_queue.enq([@system, 'set_safe_level', safe])\n    end\n    @safe_level[0]\n  end\n  def safe_level=(safe)\n    set_safe_level(safe)\n  end\n  def self.set_safe_level(safe)\n    __getip.set_safe_level(safe)\n  end\n  def self.safe_level=(safe)\n    self.set_safe_level(safe)\n  end\n  def safe_level\n    @safe_level[0]\n  end\n  def self.safe_level\n    __getip.safe_level\n  end\n\n  def wait_on_mainloop?\n    @wait_on_mainloop[0]\n  end\n  def wait_on_mainloop=(bool)\n    @wait_on_mainloop[0] = bool\n  end\n\n  def running_mainloop?\n    @wait_on_mainloop[1] > 0\n  end\n\n  def _destroy_slaves_of_slaveIP(ip)\n    unless ip.deleted?\n      # ip._split_tklist(ip._invoke('interp', 'slaves')).each{|name|\n      ip._split_tklist(ip._invoke_without_enc('interp', 'slaves')).each{|name|\n        name = _fromUTF8(name)\n        begin\n          # ip._eval_without_enc(\"#{name} eval {foreach i [after info] {after cancel $i}}\")\n          after_ids = ip._eval_without_enc(\"#{name} eval {after info}\")\n          ip._eval_without_enc(\"#{name} eval {foreach i {#{after_ids}} {after cancel $i}}\")\n        rescue Exception\n        end\n        begin\n          # ip._invoke('interp', 'eval', name, 'destroy', '.')\n          ip._invoke(name, 'eval', 'destroy', '.')\n        rescue Exception\n        end\n\n        # safe_base?\n        if ip._eval_without_enc(\"catch {::safe::interpConfigure #{name}}\") == '0'\n          begin\n            ip._eval_without_enc(\"::safe::interpDelete #{name}\")\n          rescue Exception\n          end\n        end\n=begin\n        if ip._invoke('interp', 'exists', name) == '1'\n          begin\n            ip._invoke(name, 'eval', 'exit')\n          rescue Exception\n          end\n        end\n=end\n        unless ip.deleted?\n          if ip._invoke('interp', 'exists', name) == '1'\n            begin\n              ip._invoke('interp', 'delete', name)\n            rescue Exception\n            end\n          end\n        end\n      }\n    end\n  end\n\n  def _receiver_eval_proc_core(safe_level, thread, cmd, *args)\n    begin\n      #ret = proc{$SAFE = safe_level; cmd.call(*args)}.call\n      #ret = cmd.call(safe_level, *args)\n      normal_ret = false\n      ret = catch(:IRB_EXIT) do  # IRB hack\n        retval = cmd.call(safe_level, *args)\n        normal_ret = true\n        retval\n      end\n      unless normal_ret\n        # catch IRB_EXIT\n        exit(ret)\n      end\n      ret\n    rescue SystemExit => e\n      # delete IP\n      unless @interp.deleted?\n        @slave_ip_tbl.each{|name, subip| \n          _destroy_slaves_of_slaveIP(subip)\n          begin\n            # subip._eval_without_enc(\"foreach i [after info] {after cancel $i}\")\n            after_ids = subip._eval_without_enc(\"after info\")\n            subip._eval_without_enc(\"foreach i {#{after_ids}} {after cancel $i}\")\n          rescue Exception\n          end\n=begin\n          begin\n            subip._invoke('destroy', '.') unless subip.deleted?\n          rescue Exception\n          end\n=end\n          # safe_base?\n          if @interp._eval_without_enc(\"catch {::safe::interpConfigure #{name}}\") == '0'\n            begin\n              @interp._eval_without_enc(\"::safe::interpDelete #{name}\")\n            rescue Exception\n            else\n              next if subip.deleted?\n            end\n          end\n          if subip.respond_to?(:safe_base?) && subip.safe_base? && \n              !subip.deleted?\n            # do 'exit' to call the delete_hook procedure\n            begin\n              subip._eval_without_enc('exit') \n            rescue Exception\n            end\n          else\n            begin\n              subip.delete unless subip.deleted?\n            rescue Exception\n            end\n          end\n        }\n\n        begin\n          # @interp._eval_without_enc(\"foreach i [after info] {after cancel $i}\")\n          after_ids = @interp._eval_without_enc(\"after info\")\n          @interp._eval_without_enc(\"foreach i {#{after_ids}} {after cancel $i}\")\n        rescue Exception\n        end\n        begin\n          @interp._invoke('destroy', '.') unless @interp.deleted?\n        rescue Exception\n        end\n        if @safe_base && !@interp.deleted?\n          # do 'exit' to call the delete_hook procedure\n          @interp._eval_without_enc('exit')\n        else\n          @interp.delete unless @interp.deleted?\n        end\n      end\n\n      if e.backtrace[0] =~ /^(.+?):(\\d+):in `(exit|exit!|abort)'/\n        _check_and_return(thread, MultiTkIp_OK.new($3 == 'exit'))\n      else\n        _check_and_return(thread, MultiTkIp_OK.new(nil))\n      end\n\n      # if master? && !safe? && allow_ruby_exit?\n      if !@interp.deleted? && master? && !safe? && allow_ruby_exit?\n=begin\n        ObjectSpace.each_object(TclTkIp){|obj|\n          obj.delete unless obj.deleted?\n        }\n=end\n        #exit(e.status)\n        fail e\n      end\n      # break\n\n    rescue SecurityError => e\n      # in 'exit', 'exit!', and 'abort' : security error --> delete IP\n      if e.backtrace[0] =~ /^(.+?):(\\d+):in `(exit|exit!|abort)'/\n        ret = ($3 == 'exit')\n        unless @interp.deleted?\n          @slave_ip_tbl.each{|name, subip|\n            _destroy_slaves_of_slaveIP(subip)\n            begin\n              # subip._eval_without_enc(\"foreach i [after info] {after cancel $i}\")\n              after_ids = subip._eval_without_enc(\"after info\")\n              subip._eval_without_enc(\"foreach i {#{after_ids}} {after cancel $i}\")\n            rescue Exception\n            end\n=begin\n            begin\n              subip._invoke('destroy', '.') unless subip.deleted?\n            rescue Exception\n            end\n=end\n            # safe_base?\n            if @interp._eval_without_enc(\"catch {::safe::interpConfigure #{name}}\") == '0'\n              begin\n                @interp._eval_without_enc(\"::safe::interpDelete #{name}\")\n              rescue Exception\n              else\n                next if subip.deleted?\n              end\n            end\n            if subip.respond_to?(:safe_base?) && subip.safe_base? && \n                !subip.deleted?\n              # do 'exit' to call the delete_hook procedure\n              begin\n                subip._eval_without_enc('exit') \n              rescue Exception\n              end\n            else\n              begin\n                subip.delete unless subip.deleted?\n              rescue Exception\n              end\n            end\n          }\n\n          begin\n            # @interp._eval_without_enc(\"foreach i [after info] {after cancel $i}\")\n            after_ids = @interp._eval_without_enc(\"after info\")\n            @interp._eval_without_enc(\"foreach i {#{after_ids}} {after cancel $i}\")\n          rescue Exception\n          end\n=begin\n          begin\n            @interp._invoke('destroy', '.') unless @interp.deleted?\n          rescue Exception\n          end\n=end\n          if @safe_base && !@interp.deleted?\n            # do 'exit' to call the delete_hook procedure\n            @interp._eval_without_enc('exit')\n          else\n            @interp.delete unless @interp.deleted?\n          end\n        end\n        _check_and_return(thread, MultiTkIp_OK.new(ret))\n        # break\n\n      else\n        # raise security error\n        _check_and_return(thread, e)\n      end\n\n    rescue Exception => e\n      # raise exception\n      begin\n        bt = _toUTF8(e.backtrace.join(\"\\n\"))\n        if MultiTkIp::WITH_ENCODING\n          bt.force_encoding('utf-8')\n        else\n          bt.instance_variable_set(:@encoding, 'utf-8')\n        end\n      rescue Exception\n        bt = e.backtrace.join(\"\\n\")\n      end\n      begin\n        @interp._set_global_var('errorInfo', bt)\n      rescue Exception\n      end\n      _check_and_return(thread, e)\n\n    else\n      # no exception\n      _check_and_return(thread, MultiTkIp_OK.new(ret))\n    end\n  end\n\n  def _receiver_eval_proc(last_thread, safe_level, thread, cmd, *args)\n    if thread\n      Thread.new{\n        last_thread.join if last_thread\n        unless @interp.deleted?\n          _receiver_eval_proc_core(safe_level, thread, cmd, *args)\n        end\n      }\n    else\n      Thread.new{\n        unless  @interp.deleted?\n          _receiver_eval_proc_core(safe_level, thread, cmd, *args)\n        end\n      }\n      last_thread\n    end\n  end\n\n  private :_receiver_eval_proc, :_receiver_eval_proc_core\n\n  def _receiver_mainloop(check_root)\n    if @evloop_thread[0] && @evloop_thread[0].alive?\n      @evloop_thread[0]\n    else\n      @evloop_thread[0] = Thread.new{\n\twhile !@interp.deleted?\n\t  #if check_root\n\t  #  inf = @interp._invoke_without_enc('info', 'command', '.')\n\t  #  break if !inf.kind_of?(String) || inf != '.'\n\t  #end\n          break if check_root && !@interp.has_mainwindow?\n\t  sleep 0.5\n\tend\n      }\n      @evloop_thread[0]\n    end\n  end\n\n  def _create_receiver_and_watchdog(lvl = $SAFE)\n    lvl = $SAFE if lvl < $SAFE\n\n    # command-procedures receiver\n    receiver = Thread.new(lvl){|safe_level|\n      last_thread = {}\n\n      loop do\n        break if @interp.deleted?\n        thread, cmd, *args = @cmd_queue.deq\n        if thread == @system\n          # control command\n          case cmd\n          when 'set_safe_level'\n            begin\n              safe_level = args[0] if safe_level < args[0] \n            rescue Exception\n            end\n          when 'call_mainloop'\n            thread = args.shift\n            _check_and_return(thread, \n                              MultiTkIp_OK.new(_receiver_mainloop(*args)))\n          else\n            # ignore\n          end\n\n        else\n          # procedure\n          last_thread[thread] = _receiver_eval_proc(last_thread[thread], \n\t\t\t\t\t\t    safe_level, thread, \n\t\t\t\t\t\t    cmd, *args)\n        end\n      end\n    }\n\n    # watchdog of receiver\n    watchdog = Thread.new{\n      begin\n        loop do\n          sleep 1\n          receiver.kill if @interp.deleted?\n          break unless receiver.alive?\n        end\n      rescue Exception\n        # ignore all kind of Exception\n      end\n      # receiver is dead\n      loop do\n        thread, cmd, *args = @cmd_queue.deq\n        next unless thread\n        if thread.alive?\n          if @interp.deleted?\n            thread.raise RuntimeError, 'the interpreter is already deleted'\n          else\n            thread.raise RuntimeError, \n              'the interpreter no longer receives command procedures'\n          end\n        end\n      end\n    }\n\n    # return threads\n    [receiver, watchdog]\n  end\n  private :_check_and_return, :_create_receiver_and_watchdog\n\n  ######################################\n\n  unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD\n    ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!\n    RUN_EVENTLOOP_ON_MAIN_THREAD = false\n  end\n\n  if self.const_defined? :DEFAULT_MASTER_NAME\n    name = DEFAULT_MASTER_NAME.to_s\n  else\n    name = nil\n  end\n  if self.const_defined?(:DEFAULT_MASTER_OPTS) &&\n      DEFAULT_MASTER_OPTS.kind_of?(Hash)\n    keys = DEFAULT_MASTER_OPTS\n  else\n    keys = {}\n  end\n\n  @@DEFAULT_MASTER = self.allocate\n  @@DEFAULT_MASTER.instance_eval{\n    @tk_windows = {}.taint\n\n    @tk_table_list = [].taint\n\n    @slave_ip_tbl = {}.taint\n\n    @slave_ip_top = {}.taint\n\n    @evloop_thread = [].taint\n\n    unless keys.kind_of? Hash\n      fail ArgumentError, \"expecting a Hash object for the 2nd argument\"\n    end\n\n    if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!\n      @interp = TclTkIp.new(name, _keys2opts(keys))\n    else ### Ruby 1.9 !!!!!!!!!!!\n      @interp_thread = Thread.new{\n        current = Thread.current\n        current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys))\n        #sleep\n        current[:mutex] = mutex = Mutex.new\n        current[:root_check] = cond_var = ConditionVariable.new\n\n        begin\n          current[:status] = interp.mainloop(true)\n        rescue Exception=>e\n          current[:status] = e\n        ensure\n          mutex.synchronize{ cond_var.broadcast }\n        end\n        current[:status] = interp.mainloop(false)\n      }\n      until @interp_thread[:interp]\n        Thread.pass\n      end\n      # INTERP_THREAD.run\n      @interp = @interp_thread[:interp]\n\n      def self.mainloop(check_root = true)\n        begin\n          TclTkLib.set_eventloop_window_mode(true)\n          @interp_thread.value\n        ensure\n          TclTkLib.set_eventloop_window_mode(false)\n        end\n      end\n    end\n\n    @ip_name = nil\n\n    @callback_status = [].taint\n\n    @system = Object.new\n\n    @wait_on_mainloop = [true, 0].taint\n\n    @threadgroup  = Thread.current.group\n\n    @safe_base = false\n\n    @safe_level = [$SAFE]\n\n    @cmd_queue = Queue.new\n\n    @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog(@safe_level[0])\n\n    @threadgroup.add @cmd_receiver\n    @threadgroup.add @receiver_watchdog\n\n    # NOT enclose @threadgroup for @@DEFAULT_MASTER\n\n    @@IP_TABLE[ThreadGroup::Default] = self\n    @@IP_TABLE[@threadgroup] = self\n\n    #################################\n\n    @pseudo_toplevel = [false, nil]\n\n    def self.__pseudo_toplevel\n      Thread.current.group == ThreadGroup::Default && \n        MultiTkIp.__getip == @@DEFAULT_MASTER &&\n        self.__pseudo_toplevel_evaluable? && @pseudo_toplevel[1]\n    end\n\n    def self.__pseudo_toplevel=(m)\n      unless (Thread.current.group == ThreadGroup::Default && \n                MultiTkIp.__getip == @@DEFAULT_MASTER)\n        fail SecurityError, \"no permission to manipulate\"\n      end\n\n      # if m.kind_of?(Module) && m.respond_to?(:pseudo_toplevel_evaluable?)\n      if m.respond_to?(:pseudo_toplevel_evaluable?)\n        @pseudo_toplevel[0] = true\n        @pseudo_toplevel[1] = m\n      else\n        fail ArgumentError, 'fail to set pseudo-toplevel'\n      end\n      self\n    end\n\n    def self.__pseudo_toplevel_evaluable?\n      begin\n        @pseudo_toplevel[0] && @pseudo_toplevel[1].pseudo_toplevel_evaluable?\n      rescue Exception\n        false\n      end\n    end\n\n    def self.__pseudo_toplevel_evaluable=(mode)\n      unless (Thread.current.group == ThreadGroup::Default && \n                MultiTkIp.__getip == @@DEFAULT_MASTER)\n        fail SecurityError, \"no permission to manipulate\"\n      end\n\n      @pseudo_toplevel[0] = (mode)? true: false\n    end\n\n    #################################\n\n    @assign_request = Class.new(Exception){\n      def self.new(target, ret)\n        obj = super()\n        obj.target = target\n        obj.ret = ret\n        obj\n      end\n      attr_accessor :target, :ret\n    }\n\n    @assign_thread = Thread.new{\n      loop do\n        begin\n          Thread.stop\n        rescue @assign_request=>req\n          begin\n            req.ret[0] = req.target.instance_eval{\n              @cmd_receiver, @receiver_watchdog = \n                _create_receiver_and_watchdog(@safe_level[0])\n              @threadgroup.add @cmd_receiver\n              @threadgroup.add @receiver_watchdog\n              @threadgroup.enclose\n              true\n            }\n          rescue Exception=>e\n            begin\n              req.ret[0] = e\n            rescue Exception\n              # ignore\n            end\n          end\n        rescue Exception\n          # ignore\n        end\n      end\n    }\n\n    def self.assign_receiver_and_watchdog(target)\n      ret = [nil]\n      @assign_thread.raise(@assign_request.new(target, ret))\n      while ret[0] == nil\n        unless @assign_thread.alive?\n          raise RuntimeError, 'lost the thread to assign a receiver and a watchdog thread'\n        end\n      end\n      if ret[0].kind_of?(Exception)\n        raise ret[0]\n      else\n        ret[0]\n      end\n    end\n\n    #################################\n\n    @init_ip_env_queue = Queue.new\n    Thread.new{\n      current = Thread.current\n      loop {\n        mtx, cond, ret, table, script = @init_ip_env_queue.deq\n        begin\n          ret[0] = table.each{|tg, ip| ip._init_ip_env(script) }\n        rescue Exception => e\n          ret[0] = e\n        ensure\n          mtx.synchronize{ cond.signal }\n        end\n        mtx = cond = ret = table = script = nil  # clear variables for GC\n      }\n    }\n\n    def self.__init_ip_env__(table, script)\n      ret = []\n      mtx  = (Thread.current[:MultiTk_ip_Mutex] ||= Mutex.new)\n      cond = (Thread.current[:MultiTk_ip_CondVar] ||= ConditionVariable.new)\n      mtx.synchronize{\n        @init_ip_env_queue.enq([mtx, cond, ret, table, script])\n        cond.wait(mtx)\n      }\n      if ret[0].kind_of?(Exception)\n        raise ret[0]\n      else\n        ret[0]\n      end\n    end\n\n    #################################\n\n    class << self\n      undef :instance_eval\n    end\n  }\n\n  @@DEFAULT_MASTER.freeze # defend against modification\n\n  ######################################\n\n  def self.inherited(subclass)\n    # trust if on ThreadGroup::Default or @@DEFAULT_MASTER's ThreadGroup\n    if @@IP_TABLE[Thread.current.group] == @@DEFAULT_MASTER\n      begin\n        class << subclass\n          self.methods.each{|m|\n            begin\n              unless m == '__id__' || m == '__send__' || m == 'freeze'\n                undef_method(m)\n              end\n            rescue Exception\n              # ignore all exceptions\n            end\n          }\n        end\n      ensure\n        subclass.freeze\n        fail SecurityError, \n          \"cannot create subclass of MultiTkIp on a untrusted ThreadGroup\"\n      end\n    end\n  end\n\n  ######################################\n\n  @@SAFE_OPT_LIST = [\n    'accessPath'.freeze, \n    'statics'.freeze, \n    'nested'.freeze, \n    'deleteHook'.freeze\n  ].freeze\n\n  def _parse_slaveopts(keys)\n    name = nil\n    safe = false\n    safe_opts = {}\n    tk_opts   = {}\n\n    keys.each{|k,v|\n      k_str = k.to_s\n      if k_str == 'name'\n        name = v \n      elsif k_str == 'safe'\n        safe = v\n      elsif @@SAFE_OPT_LIST.member?(k_str)\n        safe_opts[k_str] = v\n      else\n        tk_opts[k_str] = v\n      end\n    }\n\n    if keys['without_tk'] || keys[:without_tk]\n      [name, safe, safe_opts, nil]\n    else\n      [name, safe, safe_opts, tk_opts]\n    end\n  end\n  private :_parse_slaveopts\n\n  def _create_slave_ip_name\n    @@SLAVE_IP_ID.mutex.synchronize{\n      name = @@SLAVE_IP_ID.join('')\n      @@SLAVE_IP_ID[1].succ!\n      name.freeze\n    }\n  end\n  private :_create_slave_ip_name\n\n  ######################################\n\n  def __check_safetk_optkeys(optkeys)\n    # based on 'safetk.tcl'\n    new_keys = {}\n    optkeys.each{|k,v| new_keys[k.to_s] = v}\n\n    # check 'display'\n    if !new_keys.key?('display')\n      begin\n        #new_keys['display'] = @interp._invoke('winfo screen .')\n        new_keys['display'] = @interp._invoke('winfo', 'screen', '.')\n      rescue\n        if ENV[DISPLAY]\n          new_keys['display'] = ENV[DISPLAY]\n        elsif !new_keys.key?('use')\n          warn \"Warning: no screen info or ENV[DISPLAY], so use ':0.0'\"\n          new_keys['display'] = ':0.0'\n        end\n      end\n    end\n\n    # check 'use'\n    if new_keys.key?('use')\n      # given 'use'\n      case new_keys['use']\n      when TkWindow\n        new_keys['use'] = TkWinfo.id(new_keys['use'])\n        #assoc_display = @interp._eval('winfo screen .')\n        assoc_display = @interp._invoke('winfo', 'screen', '.')\n      when /^\\..*/\n        new_keys['use'] = @interp._invoke('winfo', 'id', new_keys['use'])\n        assoc_display = @interp._invoke('winfo', 'screen', new_keys['use'])\n      else\n        begin\n          pathname = @interp._invoke('winfo', 'pathname', new_keys['use'])\n          assoc_display = @interp._invoke('winfo', 'screen', pathname)\n        rescue\n          assoc_display = new_keys['display']\n        end\n      end\n\n      # match display?\n      if assoc_display != new_keys['display']\n        if optkeys.key?(:display) || optkeys.key?('display')\n          fail RuntimeError, \n            \"conflicting 'display'=>#{new_keys['display']} \" + \n            \"and display '#{assoc_display}' on 'use'=>#{new_keys['use']}\"\n        else\n          new_keys['display'] = assoc_display\n        end\n      end\n    end\n\n    # return\n    new_keys\n  end\n  private :__check_safetk_optkeys\n\n  def __create_safetk_frame(slave_ip, slave_name, app_name, keys)\n    # display option is used by ::safe::loadTk\n    loadTk_keys = {}\n    loadTk_keys['display'] = keys['display']\n    dup_keys = keys.dup\n\n    # keys for toplevel : allow followings\n    toplevel_keys = {}\n    ['height', 'width', 'background', 'menu'].each{|k|\n      toplevel_keys[k] = dup_keys.delete(k) if dup_keys.key?(k)\n    }\n    toplevel_keys['classname'] = 'SafeTk'\n    toplevel_keys['screen'] = dup_keys.delete('display')\n\n    # other keys used by pack option of container frame\n\n    # create toplevel widget\n    begin\n      top = TkToplevel.new(toplevel_keys)\n    rescue NameError => e\n      fail e unless @interp.safe?\n      fail SecurityError, \"unable create toplevel on the safe interpreter\"\n    end\n    msg = \"Untrusted Ruby/Tk applet (#{slave_name})\"\n    if app_name.kind_of?(String)\n      top.title \"#{app_name} (#{slave_name})\"\n    else\n      top.title msg\n    end\n\n    # procedure to delete slave interpreter\n    slave_delete_proc = proc{\n      unless slave_ip.deleted?\n        #if slave_ip._invoke('info', 'command', '.') != \"\"\n        #  slave_ip._invoke('destroy', '.')\n        #end\n        #slave_ip.delete\n        slave_ip._eval_without_enc('exit')\n      end\n      begin\n        top.destroy if top.winfo_exist?\n      rescue\n        # ignore\n      end\n    }\n    tag = TkBindTag.new.bind('Destroy', slave_delete_proc)\n\n    top.bindtags = top.bindtags.unshift(tag)\n\n    # create control frame\n    TkFrame.new(top, :bg=>'red', :borderwidth=>3, :relief=>'ridge') {|fc|\n      fc.bindtags = fc.bindtags.unshift(tag)\n\n      TkFrame.new(fc, :bd=>0){|f|\n        TkButton.new(f, \n                     :text=>'Delete', :bd=>1, :padx=>2, :pady=>0, \n                     :highlightthickness=>0, :command=>slave_delete_proc\n                     ).pack(:side=>:right, :fill=>:both)\n        f.pack(:side=>:right, :fill=>:both, :expand=>true)\n      }\n\n      TkLabel.new(fc, :text=>msg, :padx=>2, :pady=>0, \n                  :anchor=>:w).pack(:side=>:left, :fill=>:both, :expand=>true)\n\n      fc.pack(:side=>:bottom, :fill=>:x)\n    }\n\n    # container frame for slave interpreter\n    dup_keys['fill'] = :both  unless dup_keys.key?('fill')\n    dup_keys['expand'] = true unless dup_keys.key?('expand')\n    c = TkFrame.new(top, :container=>true).pack(dup_keys)\n    c.bind('Destroy', proc{top.destroy})\n\n    # return keys\n    loadTk_keys['use'] = TkWinfo.id(c)\n    [loadTk_keys, top.path]\n  end\n  private :__create_safetk_frame\n\n  def __create_safe_slave_obj(safe_opts, app_name, tk_opts)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    # safe interpreter\n    ip_name = _create_slave_ip_name\n    slave_ip = @interp.create_slave(ip_name, true)\n    @slave_ip_tbl[ip_name] = slave_ip\n    def slave_ip.safe_base?\n      true\n    end\n\n    @interp._eval(\"::safe::interpInit #{ip_name}\")\n\n    slave_ip._invoke('set', 'argv0', app_name) if app_name.kind_of?(String)\n\n    if tk_opts\n      tk_opts = __check_safetk_optkeys(tk_opts)\n      if tk_opts.key?('use')\n        @slave_ip_top[ip_name] = ''\n      else\n        tk_opts, top_path = __create_safetk_frame(slave_ip, ip_name, app_name, \n                                                  tk_opts)\n        @slave_ip_top[ip_name] = top_path\n      end\n      @interp._eval(\"::safe::loadTk #{ip_name} #{_keys2opts(tk_opts)}\")\n    else\n      @slave_ip_top[ip_name] = nil\n    end\n\n    if safe_opts.key?('deleteHook') || safe_opts.key?(:deleteHook)\n      @interp._eval(\"::safe::interpConfigure #{ip_name} \" + \n                    _keys2opts(safe_opts))\n    else\n      @interp._eval(\"::safe::interpConfigure #{ip_name} \" + \n                    _keys2opts(safe_opts) + '-deleteHook {' + \n                    TkComm._get_eval_string(proc{|slave|\n                                              self._default_delete_hook(slave)\n                                            }) + '}')\n    end\n\n    [slave_ip, ip_name]\n  end\n\n  def __create_trusted_slave_obj(name, keys)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    ip_name = _create_slave_ip_name\n    slave_ip = @interp.create_slave(ip_name, false)\n    slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String)\n    slave_ip._invoke('set', 'argv', _keys2opts(keys))\n    @interp._invoke('load', '', 'Tk', ip_name)\n    @slave_ip_tbl[ip_name] = slave_ip\n    [slave_ip, ip_name]\n  end\n\n  ######################################\n\n  def _create_slave_object(keys={})\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    ip = MultiTkIp.new_slave(self, keys={})\n    @slave_ip_tbl[ip.name] = ip\n  end\n\n  ######################################\n\n  def initialize(master, safeip=true, keys={})\n    if $SAFE >= 4\n      fail SecurityError, \"cannot create a new interpreter at level #{$SAFE}\"\n    end\n\n    if safeip == nil && $SAFE >= 2\n      fail SecurityError, \"cannot create a master-ip at level #{$SAFE}\"\n    end\n\n    if master.deleted? && safeip == nil\n      fail RuntimeError, \"cannot create a slave of a deleted interpreter\"\n    end\n\n    if !master.deleted? && !master.master? && master.safe?\n      fail SecurityError, \"safe-slave-ip cannot create a new interpreter\"\n    end\n\n    if safeip == nil && !master.master?\n      fail SecurityError, \"slave-ip cannot create a master-ip\"\n    end\n\n    unless keys.kind_of? Hash\n      fail ArgumentError, \"expecting a Hash object for the 2nd argument\"\n    end\n\n    @tk_windows = {}\n    @tk_table_list = []\n    @slave_ip_tbl = {}\n    @slave_ip_top = {}\n    @cb_error_proc = []\n    @evloop_thread = []\n\n    @tk_windows.taint unless @tk_windows.tainted?\n    @tk_table_list.taint unless @tk_table_list.tainted?\n    @slave_ip_tbl.taint unless @slave_ip_tbl.tainted?\n    @slave_ip_top.taint unless @slave_ip_top.tainted?\n    @cb_error_proc.taint unless @cb_error_proc.tainted?\n    @evloop_thread.taint unless @evloop_thread.tainted?\n\n    @callback_status = []\n\n    name, safe, safe_opts, tk_opts = _parse_slaveopts(keys)\n\n    safe = 4 if safe && !safe.kind_of?(Fixnum)\n\n    @safe_base = false\n\n    if safeip == nil\n      # create master-ip\n      unless WITH_RUBY_VM\n        @interp = TclTkIp.new(name, _keys2opts(tk_opts))\n      else ### Ruby 1.9 !!!!!!!!!!!\n        @interp_thread = Thread.new{\n          Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))\n          #sleep\n          TclTkLib.mainloop(true)\n        }\n        until @interp_thread[:interp]\n          Thread.pass\n        end\n        # INTERP_THREAD.run\n        @interp = @interp_thread[:interp]\n      end\n\n      @ip_name = nil\n      if safe\n        safe = $SAFE if safe < $SAFE\n        @safe_level = [safe]\n      else\n        @safe_level = [$SAFE]\n      end\n    else\n      # create slave-ip\n      if safeip || master.safe?\n        @safe_base = true\n        @interp, @ip_name = master.__create_safe_slave_obj(safe_opts, \n                                                           name, tk_opts)\n        # @interp_thread = nil if RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!\n        @interp_thread = nil unless WITH_RUBY_VM  ### Ruby 1.9 !!!!!!!!!!!\n        if safe\n          safe = master.safe_level if safe < master.safe_level\n          @safe_level = [safe]\n        else\n          @safe_level = [4]\n        end\n      else\n        @interp, @ip_name = master.__create_trusted_slave_obj(name, tk_opts)\n        # @interp_thread = nil if RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!\n        @interp_thread = nil unless WITH_RUBY_VM  ### Ruby 1.9 !!!!!!!!!!!\n        if safe\n          safe = master.safe_level if safe < master.safe_level\n          @safe_level = [safe]\n        else\n          @safe_level = [master.safe_level]\n        end\n      end\n      @set_alias_proc = proc{|name| \n        master._invoke('interp', 'alias', @ip_name, name, '', name)\n      }.freeze\n    end\n\n    @system = Object.new\n\n    @wait_on_mainloop = [true, 0].taint\n    # @wait_on_mainloop = [false, 0].taint\n\n    @threadgroup  = ThreadGroup.new\n\n    @pseudo_toplevel = [false, nil]\n\n    @cmd_queue = Queue.new\n\n=begin\n    @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog(@safe_level[0])\n\n    @threadgroup.add @cmd_receiver\n    @threadgroup.add @receiver_watchdog\n\n    @threadgroup.enclose\n=end\n    @@DEFAULT_MASTER.assign_receiver_and_watchdog(self)\n\n    @@IP_TABLE[@threadgroup] = self\n    @@TK_TABLE_LIST.size.times{ \n      (tbl = {}).tainted? || tbl.taint\n      @tk_table_list << tbl\n    }\n    _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)\n\n    class << self\n      undef :instance_eval\n    end\n\n    # dummy call for initialization\n    self.eval_proc{ Tk.tk_call('set', 'tcl_patchLevel') }\n\n    self.freeze  # defend against modification\n  end\n\n  ######################################\n\n  def _default_delete_hook(slave)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @slave_ip_tbl.delete(slave)\n    top = @slave_ip_top.delete(slave)\n    if top.kind_of?(String)\n      # call default hook of safetk.tcl (ignore exceptions)\n      if top == ''\n        begin\n          @interp._eval(\"::safe::disallowTk #{slave}\")\n        rescue\n          warn(\"Waring: fail to call '::safe::disallowTk'\") if $DEBUG\n        end\n      else # toplevel path\n        begin\n          @interp._eval(\"::safe::tkDelete {} #{top} #{slave}\")\n        rescue\n          warn(\"Waring: fail to call '::safe::tkDelete'\") if $DEBUG\n          begin\n            @interp._eval(\"destroy #{top}\")\n          rescue\n            warn(\"Waring: fail to destroy toplevel\") if $DEBUG\n          end\n        end\n      end\n    end\n  end\n\nend\n\n\n# get target IP\nclass MultiTkIp\n  def self._ip_id_\n    __getip._ip_id_\n  end\n  def _ip_id_\n    # for RemoteTkIp\n    ''\n  end\n\n  def self.__getip\n    current = Thread.current\n    if TclTkLib.mainloop_thread? != false && current['callback_ip']\n      return current['callback_ip']\n    end\n    if current.group == ThreadGroup::Default\n      @@DEFAULT_MASTER\n    else\n      ip = @@IP_TABLE[current.group]\n      unless ip\n        fail SecurityError, \n          \"cannot call Tk methods on #{Thread.current.inspect}\"\n      end\n      ip\n    end\n  end\nend\n\n\n# aliases of constructor\nclass << MultiTkIp\n  alias __new new\n  private :__new\n\n  def new_master(safe=nil, keys={})\n    if MultiTkIp::WITH_RUBY_VM\n      #### TODO !!!!!!\n      fail RuntimeError, \n           'sorry, still not support multiple master-interpreters on Ruby VM'\n    end\n\n    if safe.kind_of?(Hash)\n      keys = safe\n    elsif safe.kind_of?(Integer)\n      raise ArgumentError, \"unexpected argument(s)\" unless keys.kind_of?(Hash)\n      if !keys.key?(:safe) && !keys.key?('safe')\n        keys[:safe] = safe\n      end\n    elsif safe == nil\n      # do nothing\n    else\n      raise ArgumentError, \"unexpected argument(s)\"\n    end\n\n    ip = __new(__getip, nil, keys)\n    #ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?\n     if block_given?\n       Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}\n     end\n    ip\n  end\n\n  alias new new_master\n\n  def new_slave(safe=nil, keys={})\n    if safe.kind_of?(Hash)\n      keys = safe\n    elsif safe.kind_of?(Integer)\n      raise ArgumentError, \"unexpected argument(s)\" unless keys.kind_of?(Hash)\n      if !keys.key?(:safe) && !keys.key?('safe')\n        keys[:safe] = safe\n      end\n    elsif safe == nil\n      # do nothing\n    else\n      raise ArgumentError, \"unexpected argument(s)\"\n    end\n\n    ip = __new(__getip, false, keys)\n    # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?\n    if block_given?\n      Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}\n    end\n    ip\n  end\n  alias new_trusted_slave new_slave\n\n  def new_safe_slave(safe=4, keys={})\n    if safe.kind_of?(Hash)\n      keys = safe\n    elsif safe.kind_of?(Integer)\n      raise ArgumentError, \"unexpected argument(s)\" unless keys.kind_of?(Hash)\n      if !keys.key?(:safe) && !keys.key?('safe')\n        keys[:safe] = safe\n      end\n    else\n      raise ArgumentError, \"unexpected argument(s)\"\n    end\n\n    ip = __new(__getip, true, keys)\n    # ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?\n    if block_given?\n      Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}\n    end\n    ip\n  end\n  alias new_safeTk new_safe_slave\nend\n\n\n# get info\nclass MultiTkIp\n  def inspect\n    s = self.to_s.chop!\n    if self.manipulable?\n      if master?\n        if @interp.deleted?\n          s << ':deleted-master'\n        else\n          s << ':master'\n        end\n      else\n        if @interp.deleted?\n          s << ':deleted-slave'\n        elsif @interp.safe?\n          s << ':safe-slave'\n        else\n          s << ':trusted-slave'\n        end\n      end\n    end\n    s << '>'\n  end\n\n  def master?\n    if @ip_name\n      false\n    else\n      true\n    end\n  end\n  def self.master?\n    __getip.master?\n  end\n\n  def slave?\n    not master?\n  end\n  def self.slave?\n    not self.master?\n  end\n\n  def alive?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    begin\n      return false unless @cmd_receiver.alive?\n      return false if @interp.deleted?\n      return false if @interp._invoke('interp', 'exists', '') == '0'\n    rescue Exception\n      return false\n    end\n    true\n  end\n  def self.alive?\n    __getip.alive?\n  end\n\n  def path\n    @ip_name || ''\n  end\n  def self.path\n    __getip.path\n  end\n  def ip_name\n    @ip_name || ''\n  end\n  def self.ip_name\n    __getip.ip_name\n  end\n  def to_eval\n    @ip_name || ''\n  end\n  def self.to_eval\n    __getip.to_eval\n  end\n\n  def slaves(all = false)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp','slaves').split.map!{|name| \n      if @slave_ip_tbl.key?(name)\n        @slave_ip_tbl[name]\n      elsif all\n        name\n      else\n        nil\n      end\n    }.compact!\n  end\n  def self.slaves(all = false)\n    __getip.slaves(all)\n  end\n\n  def manipulable?\n    return true if (Thread.current.group == ThreadGroup::Default)\n    ip = MultiTkIp.__getip\n    (ip == self) || ip._is_master_of?(@interp)\n  end\n  def self.manipulable?\n    true\n  end\n\n  def _is_master_of?(tcltkip_obj)\n    tcltkip_obj.slave_of?(@interp)\n  end\n  protected :_is_master_of?\nend\n\n\n# instance methods to treat tables\nclass MultiTkIp\n  def _tk_cmd_tbl\n    tbl = {}\n    MultiTkIp.tk_cmd_tbl.each{|id, ent| tbl[id] = ent if ent.ip == self }\n    tbl\n  end\n\n  def _tk_windows\n    @tk_windows\n  end\n\n  def _tk_table_list\n    @tk_table_list\n  end\n\n  def _add_new_tables\n    (@@TK_TABLE_LIST.size - @tk_table_list.size).times{ \n      (tbl = {}).tainted? || tbl.taint\n      @tk_table_list << tbl\n    }\n  end\n\n  def _init_ip_env(script)\n    self.eval_proc{script.call(self)}\n  end\n\n  def _add_tk_procs(name, args, body)\n    return if slave?\n    @interp._invoke('proc', name, args, body) if args && body\n    @interp._invoke('interp', 'slaves').split.each{|slave|\n      @interp._invoke('interp', 'alias', slave, name, '', name)\n    }\n  end\n\n  def _remove_tk_procs(*names)\n    return if slave?\n    names.each{|name|\n      name = name.to_s\n\n      return if @interp.deleted?\n      @interp._invoke('rename', name, '')\n\n      return if @interp.deleted?\n      @interp._invoke('interp', 'slaves').split.each{|slave|\n        return if @interp.deleted?\n        @interp._invoke('interp', 'alias', slave, name, '') rescue nil\n      }\n    }\n  end\n\n  def _init_ip_internal(init_ip_env, add_tk_procs)\n    #init_ip_env.each{|script| self.eval_proc{script.call(self)}}\n    init_ip_env.each{|script| self._init_ip_env(script)}\n    add_tk_procs.each{|name, args, body| \n      if master?\n        @interp._invoke('proc', name, args, body) if args && body\n      else\n        @set_alias_proc.call(name)\n      end\n    }\n  end\nend\n\n\n# class methods to treat tables\nclass MultiTkIp\n  def self.tk_cmd_tbl\n    @@TK_CMD_TBL\n  end\n  def self.tk_windows\n    __getip._tk_windows\n  end\n  def self.tk_object_table(id)\n    __getip._tk_table_list[id]\n  end\n  def self.create_table\n    if __getip.slave? \n      begin\n        raise SecurityError, \"slave-IP has no permission creating a new table\"\n      rescue SecurityError => e\n        #p e.backtrace\n        # Is called on a Ruby/Tk library?\n        caller_info = e.backtrace[1]\n        if caller_info =~ %r{^#{MultiTkIp::BASE_DIR}/(tk|tkextlib)/[^:]+\\.rb:}\n          # Probably, caller is a Ruby/Tk library  -->  allow creating\n        else\n          raise e\n        end\n      end\n    end\n\n    id = @@TK_TABLE_LIST.size\n    obj = Object.new\n    @@TK_TABLE_LIST << obj\n    obj.instance_variable_set(:@id, id)\n    obj.instance_variable_set(:@mutex, Mutex.new)\n    obj.instance_eval{\n      def self.mutex\n        @mutex\n      end\n      def self.method_missing(m, *args)\n        MultiTkIp.tk_object_table(@id).__send__(m, *args)\n      end\n    }\n    obj.freeze\n    @@IP_TABLE.each{|tg, ip| ip._add_new_tables }\n    return obj\n  end\n\n  def self.init_ip_env(script = Proc.new)\n    @@INIT_IP_ENV << script\n    if __getip.slave?\n      begin\n        raise SecurityError, \"slave-IP has no permission initializing IP env\"\n      rescue SecurityError => e\n        #p e.backtrace\n        # Is called on a Ruby/Tk library?\n        caller_info = e.backtrace[1]\n        if caller_info =~ %r{^#{MultiTkIp::BASE_DIR}/(tk|tkextlib)/[^:]+\\.rb:}\n          # Probably, caller is a Ruby/Tk library  -->  allow creating\n        else\n          raise e\n        end\n      end\n    end\n\n    # @@IP_TABLE.each{|tg, ip| \n    #   ip._init_ip_env(script)\n    # }\n    @@DEFAULT_MASTER.__init_ip_env__(@@IP_TABLE, script)\n  end\n\n  def self.add_tk_procs(name, args=nil, body=nil)\n    if name.kind_of?(Array) # => an array of [name, args, body]\n      name.each{|param| self.add_tk_procs(*param)}\n    else\n      name = name.to_s\n      @@ADD_TK_PROCS << [name, args, body]\n      @@IP_TABLE.each{|tg, ip| \n        ip._add_tk_procs(name, args, body)\n      }\n    end\n  end\n\n  def self.remove_tk_procs(*names)\n    names.each{|name|\n      name = name.to_s\n      @@ADD_TK_PROCS.delete_if{|elem| \n        elem.kind_of?(Array) && elem[0].to_s == name\n      }\n    }\n    @@IP_TABLE.each{|tg, ip| \n      ip._remove_tk_procs(*names)\n    }\n  end\n\n  def self.init_ip_internal\n    __getip._init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)\n  end\nend\n\n\n# for callback operation\nclass MultiTkIp\n  def self.cb_entry_class\n    @@CB_ENTRY_CLASS\n  end\n  def self.get_cb_entry(cmd)\n    @@CB_ENTRY_CLASS.new(__getip, cmd).freeze\n  end\n\n=begin\n  def cb_eval(cmd, *args)\n    #self.eval_callback{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) }\n    #ret = self.eval_callback{ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *args)) }\n    ret = self.eval_callback(*args){|safe, *params|\n      $SAFE=safe if $SAFE < safe\n      TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))\n    }\n    if ret.kind_of?(Exception)\n      raise ret\n    end\n    ret\n  end\n=end\n  def cb_eval(cmd, *args)\n    self.eval_callback(*args){|safe, *params|\n      $SAFE=safe if $SAFE < safe\n      # TkUtil.eval_cmd(cmd, *params)\n      TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))\n    }\n  end\n=begin\n  def cb_eval(cmd, *args)\n    @callback_status[0] ||= TkVariable.new\n    @callback_status[1] ||= TkVariable.new\n    st, val = @callback_status\n    th = Thread.new{\n      self.eval_callback(*args){|safe, *params|\n        #p [status, val, safe, *params]\n        $SAFE=safe if $SAFE < safe\n        begin\n          TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))\n        rescue TkCallbackContinue\n          st.value = 4\n        rescue TkCallbackBreak\n          st.value = 3\n        rescue TkCallbackReturn\n          st.value = 2\n        rescue Exception => e\n          val.value = e.message\n          st.value = 1\n        else\n          st.value = 0\n        end\n      }\n    }\n    begin\n      st.wait\n      status = st.numeric\n      retval = val.value\n    rescue => e\n      fail e\n    end\n\n    if status == 1\n      fail RuntimeError, retval\n    elsif status == 2\n      fail TkCallbackReturn, \"Tk callback returns 'return' status\"\n    elsif status == 3\n      fail TkCallbackBreak, \"Tk callback returns 'break' status\"\n    elsif status == 4\n      fail TkCallbackContinue, \"Tk callback returns 'continue' status\"\n    else\n      ''\n    end\n  end\n=end\n\nend\n\n# pseudo-toplevel operation support\nclass MultiTkIp\n  # instance method\n  def __pseudo_toplevel\n    ip = MultiTkIp.__getip\n    (ip == @@DEFAULT_MASTER || ip == self) &&\n      self.__pseudo_toplevel_evaluable? && @pseudo_toplevel[1]\n  end\n\n  def __pseudo_toplevel=(m)\n    unless (Thread.current.group == ThreadGroup::Default && \n              MultiTkIp.__getip == @@DEFAULT_MASTER)\n      fail SecurityError, \"no permission to manipulate\"\n    end\n\n    # if m.kind_of?(Module) && m.respond_to?(:pseudo_toplevel_evaluable?)\n    if m.respond_to?(:pseudo_toplevel_evaluable?)\n      @pseudo_toplevel[0] = true\n      @pseudo_toplevel[1] = m\n    else\n      fail ArgumentError, 'fail to set pseudo-toplevel'\n    end\n    self\n  end\n\n  def __pseudo_toplevel_evaluable?\n    begin\n      @pseudo_toplevel[0] && @pseudo_toplevel[1].pseudo_toplevel_evaluable?\n    rescue Exception\n      false\n    end\n  end\n\n  def __pseudo_toplevel_evaluable=(mode)\n    unless (Thread.current.group == ThreadGroup::Default && \n              MultiTkIp.__getip == @@DEFAULT_MASTER)\n      fail SecurityError, \"no permission to manipulate\"\n    end\n\n    @pseudo_toplevel[0] = (mode)? true: false\n  end\nend\n\n# evaluate a procedure on the proper interpreter\nclass MultiTkIp\n  # instance method\n  def eval_proc_core(req_val, cmd, *args)\n    # check\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    unless cmd.kind_of?(Proc) || cmd.kind_of?(Method)\n      raise RuntimeError, \"A Proc/Method object is expected for the 'cmd' argument\"\n    end\n\n    # on IP thread\n    if @cmd_receiver == Thread.current || \n        (!req_val && TclTkLib.mainloop_thread? != false) # callback\n      begin\n        ret = cmd.call(safe_level, *args)\n      rescue SystemExit => e\n        # exit IP\n        warn(\"Warning: \"+ $! + \" on \" + self.inspect) if $DEBUG\n        begin\n          self._eval_without_enc('exit')\n        rescue Exception\n        end\n        self.delete\n        ret = nil\n      rescue Exception => e\n        if $DEBUG\n          warn(\"Warning: \" + e.class.inspect + \n               ((e.message.length > 0)? ' \"' + e.message + '\"': '') +  \n               \" on \" + self.inspect)\n        end\n=begin\n        begin\n          bt = _toUTF8(e.backtrace.join(\"\\n\"))\n          bt.instance_variable_set(:@encoding, 'utf-8')\n        rescue Exception\n          bt = e.backtrace.join(\"\\n\")\n        end\n        begin\n          @interp._set_global_var('errorInfo', bt)\n        rescue Exception\n        end\n=end\n        ret = e\n      end\n      return ret\n    end\n\n    # send cmd to the proc-queue\n    unless req_val\n      begin\n        @cmd_queue.enq([nil, cmd, *args])\n      rescue Exception => e\n        # ignore\n        if $DEBUG\n          warn(\"Warning: \" + e.class.inspect + \n               ((e.message.length > 0)? ' \"' + e.message + '\"': '') +  \n               \" on \" + self.inspect) \n        end\n        return e\n      end\n      return nil\n    end\n\n    # send and get return value by exception\n    begin\n      @cmd_queue.enq([Thread.current, cmd, *args])\n      Thread.stop\n    rescue MultiTkIp_OK => ret\n      # return value\n      return ret.value\n    rescue SystemExit => e\n      # exit IP\n      warn(\"Warning: \" + $! + \" on \" + self.inspect) if $DEBUG\n      begin\n        self._eval_without_enc('exit')\n      rescue Exception\n      end\n      if !self.deleted? && !safe? && allow_ruby_exit?\n        self.delete\n        fail e\n      else\n        self.delete\n      end\n    rescue Exception => e\n      if $DEBUG\n        warn(\"Warning: \" + e.class.inspect + \n             ((e.message.length > 0)? ' \"' + e.message + '\"': '') +  \n             \" on \" + self.inspect) \n      end\n      return e\n    end\n    return nil\n  end\n  private :eval_proc_core\n\n  def eval_callback(*args)\n    if block_given?\n      cmd = Proc.new\n    else\n      cmd = args.shift\n    end\n    current = Thread.current\n    backup_ip = current['callback_ip']\n    current['callback_ip'] = self\n    begin\n      eval_proc_core(false, cmd, *args)\n    ensure\n      current['callback_ip'] = backup_ip\n    end\n  end\n\n  def eval_proc(*args)\n    # The scope of the eval-block of 'eval_proc' method is different from \n    # the external. If you want to pass local values to the eval-block, \n    # use arguments of eval_proc method. They are passed to block-arguments.\n    if block_given?\n      cmd = Proc.new\n    else\n      unless (cmd = args.shift)\n        fail ArgumentError, \"A Proc or Method object is expected for 1st argument\"\n      end\n    end\n    if TclTkLib.mainloop_thread? == true\n      # call from eventloop\n      current = Thread.current\n      backup_ip = current['callback_ip']\n      current['callback_ip'] = self\n      begin\n        eval_proc_core(false, \n\t               proc{|safe, *params|\n\t\t         $SAFE=safe if $SAFE < safe\n                         cmd.call(*params)\n                       }, *args)\n      ensure\n        current['callback_ip'] = backup_ip\n      end\n    else\n      eval_proc_core(true, \n                     proc{|safe, *params| \n                       $SAFE=safe if $SAFE < safe\n                       Thread.new(*params, &cmd).value\n                     },\n                     *args)\n    end\n  end\n  alias call eval_proc\n\n  def bg_eval_proc(*args)\n    if block_given?\n      cmd = Proc.new\n    else\n      unless (cmd = args.shift)\n        fail ArgumentError, \"A Proc or Method object is expected for 1st argument\"\n      end\n    end\n    Thread.new{\n      eval_proc(cmd, *args)\n=begin\n      eval_proc_core(false, \n                     proc{|safe, *params| \n                       $SAFE=safe if $SAFE < safe\n                       Thread.new(*params, &cmd).value\n                     },\n                     safe_level, *args)\n=end\n    }\n  end\n  alias background_eval_proc bg_eval_proc\n  alias thread_eval_proc bg_eval_proc\n  alias bg_call bg_eval_proc\n  alias background_call bg_eval_proc\n\n  def eval_string(cmd, *eval_args)\n    # cmd string ==> proc\n    unless cmd.kind_of?(String)\n      raise RuntimeError, \"A String object is expected for the 'cmd' argument\"\n    end\n\n    eval_proc_core(true, \n                   proc{|safe| \n                     Kernel.eval(\"$SAFE=#{safe} if $SAFE < #{safe};\" << cmd,\n                                 *eval_args)\n                   })\n  end\n  alias eval_str eval_string\n\n  def bg_eval_string(cmd, *eval_args)\n    # cmd string ==> proc\n    unless cmd.kind_of?(String)\n      raise RuntimeError, \"A String object is expected for the 'cmd' argument\"\n    end\n    Thread.new{\n      eval_proc_core(true, \n                     proc{|safe| \n                       Kernel.eval(\"$SAFE=#{safe} if $SAFE < #{safe};\" << cmd,\n                                   *eval_args)\n                     })\n    }\n  end\n  alias background_eval_string bg_eval_string\n  alias bg_eval_str bg_eval_string\n  alias background_eval_str bg_eval_string\n\n  def eval(*args, &blk)\n    if block_given?\n      eval_proc(*args, &blk)\n    elsif args[0]\n      if args[0].respond_to?(:call)\n        eval_proc(*args)\n      else\n        eval_string(*args)\n      end\n    else\n      fail ArgumentError, \"no argument to eval\"\n    end\n  end\n\n  def bg_eval(*args, &blk)\n    if block_given?\n      bg_eval_proc(*args, &blk)\n    elsif args[0]\n      if args[0].respond_to?(:call)\n        bg_eval_proc(*args)\n      else\n        bg_eval_string(*args)\n      end\n    else\n      fail ArgumentError, \"no argument to eval\"\n    end\n  end\n  alias background_eval bg_eval\nend\n\nclass << MultiTkIp\n  # class method\n  def eval_proc(*args, &blk)\n    # class ==> interp object\n    __getip.eval_proc(*args, &blk)\n  end\n  alias call eval_proc\n\n  def bg_eval_proc(*args, &blk)\n    # class ==> interp object\n    __getip.bg_eval_proc(*args, &blk)\n  end\n  alias background_eval_proc bg_eval_proc\n  alias thread_eval_proc bg_eval_proc\n  alias bg_call bg_eval_proc\n  alias background_call bg_eval_proc\n\n  def eval_string(cmd, *eval_args)\n    # class ==> interp object\n    __getip.eval_string(cmd, *eval_args)\n  end\n  alias eval_str eval_string\n\n  def bg_eval_string(cmd, *eval_args)\n    # class ==> interp object\n    __getip.bg_eval_string(cmd, *eval_args)\n  end\n  alias background_eval_string bg_eval_string\n  alias bg_eval_str bg_eval_string\n  alias background_eval_str bg_eval_string\n\n  def eval(*args, &blk)\n    # class ==> interp object\n    __getip.eval(*args, &blk)\n  end\n  def bg_eval(*args, &blk)\n    # class ==> interp object\n    __getip.bg_eval(*args, &blk)\n  end\n  alias background_eval bg_eval\nend\n\n\n# event loop\n# all master/slave IPs are controled by only one event-loop\nclass << MultiTkIp\n  def mainloop(check_root = true)\n    __getip.mainloop(check_root)\n  end\n  def mainloop_watchdog(check_root = true)\n    __getip.mainloop_watchdog(check_root)\n  end\n  def do_one_event(flag = TclTkLib::EventFlag::ALL)\n    __getip.do_one_event(flag)\n  end\n  def mainloop_abort_on_exception\n    # __getip.mainloop_abort_on_exception\n    TclTkLib.mainloop_abort_on_exception\n  end\n  def mainloop_abort_on_exception=(mode)\n    # __getip.mainloop_abort_on_exception=(mode)\n    TclTkLib.mainloop_abort_on_exception=(mode)\n  end\n  def set_eventloop_tick(tick)\n    __getip.set_eventloop_tick(tick)\n  end\n  def get_eventloop_tick\n    __getip.get_eventloop_tick\n  end\n  def set_no_event_wait(tick)\n    __getip.set_no_event_wait(tick)\n  end\n  def get_no_event_wait\n    __getip.get_no_event_wait\n  end\n  def set_eventloop_weight(loop_max, no_event_tick)\n    __getip.set_eventloop_weight(loop_max, no_event_tick)\n  end\n  def get_eventloop_weight\n    __getip.get_eventloop_weight\n  end\nend\n\n# class methods to delegate to TclTkIp\nclass << MultiTkIp\n  def method_missing(id, *args)\n    __getip.__send__(id, *args)\n  end\n\n  def make_safe\n    __getip.make_safe\n  end\n\n  def safe?\n    __getip.safe?\n  end\n\n  def safe_base?\n    begin\n      __getip.safe_base?\n    rescue\n      false\n    end\n  end\n\n  def allow_ruby_exit?\n    __getip.allow_ruby_exit?\n  end\n\n  def allow_ruby_exit= (mode)\n    __getip.allow_ruby_exit = mode\n  end\n\n  def delete\n    __getip.delete\n  end\n\n  def deleted?\n    __getip.deleted?\n  end\n\n  def has_mainwindow?\n    __getip.has_mainwindow?\n  end\n\n  def invalid_namespace?\n    __getip.invalid_namespace?\n  end\n\n  def abort(msg = nil)\n    __getip.abort(msg)\n  end\n\n  def exit(st = true)\n    __getip.exit(st)\n  end\n\n  def exit!(st = false)\n    __getip.exit!(st)\n  end\n\n  def restart(app_name = nil, keys = {})\n    init_ip_internal\n\n    __getip._invoke('set', 'argv0', app_name) if app_name\n    if keys.kind_of?(Hash)\n      __getip._invoke('set', 'argv', _keys2opts(keys))\n    end\n\n    __getip.restart\n  end\n\n  def _eval(str)\n    __getip._eval(str)\n  end\n\n  def _invoke(*args)\n    __getip._invoke(*args)\n  end\n\n  def _eval_without_enc(str)\n    __getip._eval_without_enc(str)\n  end\n\n  def _invoke_without_enc(*args)\n    __getip._invoke_without_enc(*args)\n  end\n\n  def _eval_with_enc(str)\n    __getip._eval_with_enc(str)\n  end\n\n  def _invoke_with_enc(*args)\n    __getip._invoke_with_enc(*args)\n  end\n\n  def _toUTF8(str, encoding=nil)\n    __getip._toUTF8(str, encoding)\n  end\n\n  def _fromUTF8(str, encoding=nil)\n    __getip._fromUTF8(str, encoding)\n  end\n\n  def _thread_vwait(var)\n    __getip._thread_vwait(var)\n  end\n\n  def _thread_tkwait(mode, target)\n    __getip._thread_tkwait(mode, target)\n  end\n\n  def _return_value\n    __getip._return_value\n  end\n\n  def _get_variable(var, flag)\n    __getip._get_variable(var, flag)\n  end\n  def _get_variable2(var, idx, flag)\n    __getip._get_variable2(var, idx, flag)\n  end\n  def _set_variable(var, value, flag)\n    __getip._set_variable(var, value, flag)\n  end\n  def _set_variable2(var, idx, value, flag)\n    __getip._set_variable2(var, idx, value, flag)\n  end\n  def _unset_variable(var, flag)\n    __getip._unset_variable(var, flag)\n  end\n  def _unset_variable2(var, idx, flag)\n    __getip._unset_variable2(var, idx, flag)\n  end\n\n  def _get_global_var(var)\n    __getip._get_global_var(var)\n  end\n  def _get_global_var2(var, idx)\n    __getip._get_global_var2(var, idx)\n  end\n  def _set_global_var(var, value)\n    __getip._set_global_var(var, value)\n  end\n  def _set_global_var2(var, idx, value)\n    __getip._set_global_var2(var, idx, value)\n  end\n  def _unset_global_var(var)\n    __getip._unset_global_var(var)\n  end\n  def _unset_global_var2(var, idx)\n    __getip._unset_global_var2(var, idx)\n  end\n\n  def _make_menu_embeddable(menu_path)\n    __getip._make_menu_embeddable(menu_path)\n  end\n\n  def _split_tklist(str)\n    __getip._split_tklist(str)\n  end\n  def _merge_tklist(*args)\n    __getip._merge_tklist(*args)\n  end\n  def _conv_listelement(arg)\n    __getip._conv_listelement(arg)\n  end\n\n  def _create_console\n    __getip._create_console\n  end\nend\n\n\n# wrap methods on TclTkLib : not permit calling TclTkLib module methods\nclass << TclTkLib\n  def mainloop(check_root = true)\n    MultiTkIp.mainloop(check_root)\n  end\n  def mainloop_watchdog(check_root = true)\n    MultiTkIp.mainloop_watchdog(check_root)\n  end\n  def do_one_event(flag = TclTkLib::EventFlag::ALL)\n    MultiTkIp.do_one_event(flag)\n  end\n  #def mainloop_abort_on_exception\n  #  MultiTkIp.mainloop_abort_on_exception\n  #end\n  #def mainloop_abort_on_exception=(mode)\n  #  MultiTkIp.mainloop_abort_on_exception=(mode)\n  #end\n  def set_eventloop_tick(tick)\n    MultiTkIp.set_eventloop_tick(tick)\n  end\n  def get_eventloop_tick\n    MultiTkIp.get_eventloop_tick\n  end\n  def set_no_event_wait(tick)\n    MultiTkIp.set_no_event_wait(tick)\n  end\n  def get_no_event_wait\n    MultiTkIp.get_no_event_wait\n  end\n  def set_eventloop_weight(loop_max, no_event_tick)\n    MultiTkIp.set_eventloop_weight(loop_max, no_event_tick)\n  end\n  def get_eventloop_weight\n    MultiTkIp.get_eventloop_weight\n  end\n  def restart(*args)\n    MultiTkIp.restart(*args)\n  end\n\n  def _merge_tklist(*args)\n    MultiTkIp._merge_tklist(*args)\n  end\n  def _conv_listelement(arg)\n    MultiTkIp._conv_listelement(arg)\n  end\nend\n\n\n# depend on TclTkIp\nclass MultiTkIp\n  def mainloop(check_root = true, restart_on_dead = true)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    if WITH_RUBY_VM  ### Ruby 1.9 !!!!!!!!!!!\n      return @interp_thread.value if @interp_thread\n    end\n\n    #return self if self.slave?\n    #return self if self != @@DEFAULT_MASTER\n    if self != @@DEFAULT_MASTER\n      if @wait_on_mainloop[0]\n        begin\n          @wait_on_mainloop[1] += 1\n          if $SAFE >= 4\n\t    _receiver_mainloop(check_root).join\n          else\n            @cmd_queue.enq([@system, 'call_mainloop', \n                            Thread.current, check_root])\n            Thread.stop\n          end\n        rescue MultiTkIp_OK => ret\n          # return value\n          if ret.value.kind_of?(Thread)\n            return ret.value.value\n          else\n            return ret.value\n          end\n        rescue SystemExit => e\n          # exit IP\n          warn(\"Warning: \" + $! + \" on \" + self.inspect) if $DEBUG\n          begin\n            self._eval_without_enc('exit')\n          rescue Exception\n          end\n          self.delete\n        rescue StandardError => e\n          if $DEBUG\n            warn(\"Warning: \" + e.class.inspect + \n                 ((e.message.length > 0)? ' \"' + e.message + '\"': '') +  \n                 \" on \" + self.inspect) \n          end\n          return e\n        rescue Exception => e\n\t  return e\n        ensure\n          @wait_on_mainloop[1] -= 1\n        end\n      end\n      return\n    end\n\n    unless restart_on_dead\n      @wait_on_mainloop[1] += 1\n=begin\n      begin\n        @interp.mainloop(check_root)\n      rescue StandardError => e\n        if $DEBUG\n          warn(\"Warning: \" + e.class.inspect + \n               ((e.message.length > 0)? ' \"' + e.message + '\"': '') +  \n               \" on \" + self.inspect) \n        end\n      end\n=end\n      begin\n\t@interp.mainloop(check_root)\n      ensure\n\t@wait_on_mainloop[1] -= 1\n      end\n    else\n      loop do\n        break unless self.alive?\n        if check_root\n          begin\n            break if TclTkLib.num_of_mainwindows == 0\n          rescue StandardError\n            break\n          end\n        end\n        break if @interp.deleted?\n        begin\n\t  @wait_on_mainloop[1] += 1\n          @interp.mainloop(check_root)\n        rescue StandardError => e\n          if TclTkLib.mainloop_abort_on_exception != nil\n            #STDERR.print(\"Warning: Tk mainloop receives \", $!.class.inspect, \n            #             \" exception (ignore) : \", $!.message, \"\\n\");\n            if $DEBUG\n              warn(\"Warning: Tk mainloop receives \" << e.class.inspect <<\n                   \" exception (ignore) : \" << e.message);\n            end\n          end\n          #raise e\n        rescue Exception => e\n=begin\n          if TclTkLib.mainloop_abort_on_exception != nil\n            #STDERR.print(\"Warning: Tk mainloop receives \", $!.class.inspect, \n            #             \" exception (ignore) : \", $!.message, \"\\n\");\n            if $DEBUG\n              warn(\"Warning: Tk mainloop receives \" << e.class.inspect <<\n                   \" exception (ignore) : \" << e.message);\n            end\n          end\n=end\n          raise e\n        ensure\n          @wait_on_mainloop[1] -= 1\n          Thread.pass  # avoid eventloop conflict\n        end\n      end\n    end\n    self\n  end\n\n  def make_safe\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.make_safe\n  end\n\n  def safe?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.safe?\n  end\n\n  def safe_base?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @safe_base\n  end\n\n  def allow_ruby_exit?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.allow_ruby_exit?\n  end\n\n  def allow_ruby_exit= (mode)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.allow_ruby_exit = mode\n  end\n\n  def delete\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @slave_ip_tbl.each{|name, subip|\n      _destroy_slaves_of_slaveIP(subip)\n=begin\n      begin\n        subip._invoke('destroy', '.') unless subip.deleted?\n      rescue Exception\n      end\n=end\n      begin\n        # subip._eval_without_enc(\"foreach i [after info] {after cancel $i}\")\n\tunless subip.deleted?\n\t  after_ids = subip._eval_without_enc(\"after info\")\n\t  subip._eval_without_enc(\"foreach i {#{after_ids}} {after cancel $i}\")\n\tend\n      rescue Exception\n      end\n\n      # safe_base?\n      if @interp._eval_without_enc(\"catch {::safe::interpConfigure #{name}}\") == '0'\n        begin\n          @interp._eval_without_enc(\"::safe::interpDelete #{name}\")\n        rescue Exception\n        else\n          next if subip.deleted?\n        end\n      end\n      if subip.respond_to?(:safe_base?) && subip.safe_base? && \n          !subip.deleted?\n        # do 'exit' to call the delete_hook procedure\n        begin\n          subip._eval_without_enc('exit') \n        rescue Exception\n        end\n      else\n        begin\n          subip.delete unless subip.deleted?\n        rescue Exception\n        end\n      end\n    }\n\n    begin\n      # @interp._eval_without_enc(\"foreach i [after info] {after cancel $i}\")\n      after_ids = @interp._eval_without_enc(\"after info\")\n      @interp._eval_without_enc(\"foreach i {#{after_ids}} {after cancel $i}\")\n    rescue Exception\n    end\n\n    begin\n      @interp._invoke('destroy', '.') unless @interp.deleted?\n    rescue Exception\n    end\n\n    if @safe_base && !@interp.deleted?\n      # do 'exit' to call the delete_hook procedure\n      @interp._eval_without_enc('exit')\n    end\n    @interp.delete\n    self\n  end\n\n  def deleted?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.deleted?\n  end\n\n  def has_mainwindow?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.has_mainwindow?\n  end\n\n  def invalid_namespace?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.invalid_namespace?\n  end\n\n  def abort(msg = nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if master? && !safe? && allow_ruby_exit?\n      if msg\n        Kernel.abort(msg)\n      else\n        Kernel.abort\n      end\n    else\n      # ignore msg\n      delete\n      1\n    end\n  end\n\n  def exit(st = true)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if master? && !safe? && allow_ruby_exit?\n      Kernel.exit(st)\n    else\n      delete\n      st\n    end\n  end\n\n  def exit!(st = false)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if master? && !safe? && allow_ruby_exit?\n      Kernel.exit!(st)\n    else\n      delete\n      st\n    end\n  end\n\n  def restart(app_name = nil, keys = {})\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    _init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)\n\n    @interp._invoke('set', 'argv0', app_name) if app_name\n    if keys.kind_of?(Hash)\n      @interp._invoke('set', 'argv', _keys2opts(keys))\n    end\n\n    @interp.restart\n  end\n\n  def __eval(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.__eval(str)\n  end\n\n  def __invoke(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.__invoke(*args)\n  end\n\n  def _eval(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._eval(str)\n  end\n\n  def _invoke(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke(*args)\n  end\n\n  def _eval_without_enc(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._eval_without_enc(str)\n  end\n\n  def _invoke_without_enc(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke_without_enc(*args)\n  end\n\n  def _eval_with_enc(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._eval_with_enc(str)\n  end\n\n  def _invoke_with_enc(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke_with_enc(*args)\n  end\n\n  def _toUTF8(str, encoding=nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._toUTF8(str, encoding)\n  end\n\n  def _fromUTF8(str, encoding=nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._fromUTF8(str, encoding)\n  end\n\n  def _thread_vwait(var)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._thread_vwait(var)\n  end\n\n  def _thread_tkwait(mode, target)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._thread_tkwait(mode, target)\n  end\n\n  def _return_value\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._return_value\n  end\n\n  def _get_variable(var, flag)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._get_variable(var, flag)\n  end\n  def _get_variable2(var, idx, flag)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._get_variable2(var, idx, flag)\n  end\n  def _set_variable(var, value, flag)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._set_variable(var, value, flag)\n  end\n  def _set_variable2(var, idx, value, flag)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._set_variable2(var, idx, value, flag)\n  end\n  def _unset_variable(var, flag)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._unset_variable(var, flag)\n  end\n  def _unset_variable2(var, idx, flag)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._unset_variable2(var, idx, flag)\n  end\n\n  def _get_global_var(var)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._get_global_var(var)\n  end\n  def _get_global_var2(var, idx)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._get_global_var2(var, idx)\n  end\n  def _set_global_var(var, value)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._set_global_var(var, value)\n  end\n  def _set_global_var2(var, idx, value)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._set_global_var2(var, idx, value)\n  end\n  def _unset_global_var(var)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._unset_global_var(var)\n  end\n  def _unset_global_var2(var, idx)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._unset_global_var2(var, idx)\n  end\n\n  def _make_menu_embeddable(menu_path)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._make_menu_embeddable(menu_path)\n  end\n\n  def _split_tklist(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._split_tklist(str)\n  end\n  def _merge_tklist(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._merge_tklist(*args)\n  end\n  def _conv_listelement(arg)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._conv_listelement(arg)\n  end\nend\n\n\n# interp command support\nclass MultiTkIp\n  def _lst2ary(str)\n    return [] if str == \"\"\n    idx = str.index('{')\n    while idx and idx > 0 and str[idx-1] == ?\\\\\n      idx = str.index('{', idx+1)\n    end\n    return str.split unless idx\n\n    list = str[0,idx].split\n    str = str[idx+1..-1]\n    i = -1\n    brace = 1\n    str.each_byte {|c|\n      c = c.chr\n      i += 1\n      brace += 1 if c == '{'\n      brace -= 1 if c == '}'\n      break if brace == 0\n    }\n    if i == 0\n      list.push ''\n    elsif str[0, i] == ' '\n      list.push ' '\n    else\n      list.push str[0..i-1]\n    end\n    #list += _lst2ary(str[i+1..-1])\n    list.concat(_lst2ary(str[i+1..-1]))\n    list\n  end\n  private :_lst2ary\n\n  def _slavearg(slave)\n    if slave.kind_of?(MultiTkIp)\n      slave.path\n    elsif slave.kind_of?(String)\n      slave\n    else\n      slave.to_s\n    end\n  end\n  private :_slavearg\n\n  def alias_info(slave, cmd_name)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    _lst2ary(@interp._invoke('interp', 'alias', _slavearg(slave), cmd_name))\n  end\n  def self.alias_info(slave, cmd_name)\n    __getip.alias_info(slave, cmd_name)\n  end\n\n  def alias_delete(slave, cmd_name)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'alias', _slavearg(slave), cmd_name, '')\n    self\n  end\n  def self.alias_delete(slave, cmd_name)\n    __getip.alias_delete(slave, cmd_name)\n    self\n  end\n\n  def def_alias(slave, new_cmd, org_cmd, *args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    ret = @interp._invoke('interp', 'alias', _slavearg(slave), new_cmd, \n                          '', org_cmd, *args)\n    (ret == new_cmd)? self: nil\n  end\n  def self.def_alias(slave, new_cmd, org_cmd, *args)\n    ret = __getip.def_alias(slave, new_cmd, org_cmd, *args)\n    (ret == new_cmd)? self: nil\n  end\n\n  def aliases(slave = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    _lst2ary(@interp._invoke('interp', 'aliases', _slavearg(slave)))\n  end\n  def self.aliases(slave = '')\n    __getip.aliases(slave)\n  end\n\n  def delete_slaves(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    slaves = args.collect{|s| _slavearg(s)}\n    @interp._invoke('interp', 'delete', *slaves) if slaves.size > 0\n    self\n  end\n  def self.delete_slaves(*args)\n    __getip.delete_slaves(*args)\n    self\n  end\n\n  def exist?(slave = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    ret = @interp._invoke('interp', 'exists', _slavearg(slave))\n    (ret == '1')? true: false\n  end\n  def self.exist?(slave = '')\n    __getip.exist?(slave)\n  end\n\n  def delete_cmd(slave, cmd)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    slave_invoke = @interp._invoke('list', 'rename', cmd, '')\n    @interp._invoke('interp', 'eval', _slavearg(slave), slave_invoke)\n    self\n  end\n  def self.delete_cmd(slave, cmd)\n    __getip.delete_cmd(slave, cmd)\n    self\n  end\n\n  def expose_cmd(slave, cmd, aliasname = nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if aliasname\n      @interp._invoke('interp', 'expose', _slavearg(slave), cmd, aliasname)\n    else\n      @interp._invoke('interp', 'expose', _slavearg(slave), cmd)\n    end\n    self\n  end\n  def self.expose_cmd(slave, cmd, aliasname = nil)\n    __getip.expose_cmd(slave, cmd, aliasname)\n    self\n  end\n\n  def hide_cmd(slave, cmd, aliasname = nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if aliasname\n      @interp._invoke('interp', 'hide', _slavearg(slave), cmd, aliasname)\n    else\n      @interp._invoke('interp', 'hide', _slavearg(slave), cmd)\n    end\n    self\n  end\n  def self.hide_cmd(slave, cmd, aliasname = nil)\n    __getip.hide_cmd(slave, cmd, aliasname)\n    self\n  end\n\n  def hidden_cmds(slave = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    _lst2ary(@interp._invoke('interp', 'hidden', _slavearg(slave)))\n  end\n  def self.hidden_cmds(slave = '')\n    __getip.hidden_cmds(slave)\n  end\n\n  def invoke_hidden(slave, cmd, *args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n    else\n      keys = []\n    end\n    keys << _slavearg(slave)\n    if Tk::TCL_MAJOR_VERSION > 8 ||\n        (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5) \n      keys << '--'\n    end\n    keys << cmd\n    keys.concat(args)\n    @interp._invoke('interp', 'invokehidden', *keys)\n  end\n  def self.invoke_hidden(slave, cmd, *args)\n    __getip.invoke_hidden(slave, cmd, *args)\n  end\n\n  def invoke_hidden_on_global(slave, cmd, *args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n    else\n      keys = []\n    end\n    keys << _slavearg(slave)\n    keys << '-global'\n    if Tk::TCL_MAJOR_VERSION > 8 ||\n        (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5) \n      keys << '--'\n    end\n    keys << cmd\n    keys.concat(args)\n    @interp._invoke('interp', 'invokehidden', *keys)\n  end\n  def self.invoke_hidden_on_global(slave, cmd, *args)\n    __getip.invoke_hidden_on_global(slave, cmd, *args)\n  end\n\n  def invoke_hidden_on_namespace(slave, ns, cmd, *args)\n    # for Tcl8.5 or later\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n    else\n      keys = []\n    end\n    keys << _slavearg(slave)\n    keys << '-namespace' << TkComm._get_eval_string(ns)\n    keys << '--' << cmd\n    keys.concat(args)\n    @interp._invoke('interp', 'invokehidden', *keys)\n  end\n  def self.invoke_hidden_on_namespace(slave, ns, cmd, *args)\n    __getip.invoke_hidden_on_namespace(slave, ns, cmd, *args)\n  end\n\n  def mark_trusted(slave = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'marktrusted', _slavearg(slave))\n    self\n  end\n  def self.mark_trusted(slave = '')\n    __getip.mark_trusted(slave)\n    self\n  end\n\n  def set_bgerror_handler(cmd = Proc.new, slave = nil, &b)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    unless TkComm._callback_entry?(cmd)\n      if !slave && b\n        slave = cmd\n        cmd = Proc.new(&b)\n      end\n    end\n    slave = '' unless slave\n\n    @interp._invoke('interp', 'bgerror', _slavearg(slave), cmd)\n  end\n  def self.bgerror(cmd = Proc.new, slave = nil, &b)\n    __getip.bgerror(cmd, slave, &b)\n  end\n\n  def get_bgerror_handler(slave = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    procedure(@interp._invoke('interp', 'bgerror', _slavearg(slave)))\n  end\n  def self.bgerror(slave = '')\n    __getip.bgerror(slave)\n  end\n\n  def set_limit(limit_type, slave = '', opts = {})\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'limit', _slavearg(slave), limit_type, opts)\n  end\n  def self.set_limit(limit_type, slave = '', opts = {})\n    __getip.set_limit(limit_type, slave, opts)\n  end\n\n  def get_limit(limit_type, slave = '', slot = nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    if slot\n      num_or_str(@interp._invoke('interp', 'limit', _slavearg(slave), \n                                 limit_type, slot))\n    else\n      l = @interp._split_tklist(@interp._invoke_without_enc('interp', 'limit', \n                                                            _slavearg(slave), \n                                                            limit_type))\n      l.map!{|s| _fromUTF8(s)}\n      r = {}\n      until l.empty?\n        key = l.shift[1..-1]\n        val = l.shift\n        val = num_or_str(val) if val\n        r[key] = val\n      end\n      r\n    end\n  end\n  def self.get_limit(limit_type, slave = '', slot = nil)\n    __getip.get_limit(limit_type, slave, slot)\n  end\n\n  def recursion_limit(slave = '', limit = None)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    number(@interp._invoke('interp', 'recursionlimit', \n                           _slavearg(slave), limit))\n  end\n  def self.recursion_limit(slave = '', limit = None)\n    __getip.recursion_limit(slave)\n  end\n\n  def alias_target(aliascmd, slave = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'target', _slavearg(slave), aliascmd)\n  end\n  def self.alias_target(aliascmd, slave = '')\n    __getip.alias_target(aliascmd, slave)\n  end\n\n  def share_stdin(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'share', src, 'stdin', dist)\n    self\n  end\n  def self.share_stdin(dist, src = '')\n    __getip.share_stdin(dist, src)\n    self\n  end\n\n  def share_stdout(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'share', src, 'stdout', dist)\n    self\n  end\n  def self.share_stdout(dist, src = '')\n    __getip.share_stdout(dist, src)\n    self\n  end\n\n  def share_stderr(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'share', src, 'stderr', dist)\n    self\n  end\n  def self.share_stderr(dist, src = '')\n    __getip.share_stderr(dist, src)\n    self\n  end\n\n  def transfer_stdin(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'transfer', src, 'stdin', dist)\n    self\n  end\n  def self.transfer_stdin(dist, src = '')\n    __getip.transfer_stdin(dist, src)\n    self\n  end\n\n  def transfer_stdout(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'transfer', src, 'stdout', dist)\n    self\n  end\n  def self.transfer_stdout(dist, src = '')\n    __getip.transfer_stdout(dist, src)\n    self\n  end\n\n  def transfer_stderr(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'transfer', src, 'stderr', dist)\n    self\n  end\n  def self.transfer_stderr(dist, src = '')\n    __getip.transfer_stderr(dist, src)\n    self\n  end\n\n  def share_stdio(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'share', src, 'stdin',  dist)\n    @interp._invoke('interp', 'share', src, 'stdout', dist)\n    @interp._invoke('interp', 'share', src, 'stderr', dist)\n    self\n  end\n  def self.share_stdio(dist, src = '')\n    __getip.share_stdio(dist, src)\n    self\n  end\n\n  def transfer_stdio(dist, src = '')\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._invoke('interp', 'transfer', src, 'stdin',  dist)\n    @interp._invoke('interp', 'transfer', src, 'stdout', dist)\n    @interp._invoke('interp', 'transfer', src, 'stderr', dist)\n    self\n  end\n  def self.transfer_stdio(dist, src = '')\n    __getip.transfer_stdio(dist, src)\n    self\n  end\nend\n\n\n# Safe Base :: manipulating safe interpreter\nclass MultiTkIp\n  def safeip_configure(slot, value=None)\n    # use for '-noStatics' option ==> {statics=>false}\n    #     for '-nestedLoadOk' option ==> {nested=>true}\n    if slot.kind_of?(Hash)\n      ip = MultiTkIp.__getip\n      ip._eval('::safe::interpConfigure ' + @ip_name + ' ' + _keys2opts(slot))\n    else\n      ip._eval('::safe::interpConfigure ' + @ip_name + ' ' + \n               \"-#{slot} #{_get_eval_string(value)}\")\n    end\n    self\n  end\n\n  def safeip_configinfo(slot = nil)\n    ip = MultiTkIp.__getip\n    ret = {}\n    if slot\n      conf = _lst2ary(ip._eval(\"::safe::interpConfigure \" + \n                               @ip_name + \" -#{slot}\"))\n      if conf[0] == '-deleteHook'\n=begin\n        if conf[1] =~ /^rb_out\\S* (c(_\\d+_)?\\d+)/\n          ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$1]\n=end\n        if conf[1] =~ /rb_out\\S*(?:\\s+(::\\S*|[{](::.*)[}]|[\"](::.*)[\"]))? (c(_\\d+_)?(\\d+))/\n          ret[conf[0][1..-1]] = MultiTkIp._tk_cmd_tbl[$4]\n        else\n          ret[conf[0][1..-1]] = conf[1]\n        end\n      else\n        ret[conf[0][1..-1]] = conf[1]\n      end\n    else\n      Hash[*_lst2ary(ip._eval(\"::safe::interpConfigure \" + \n                              @ip_name))].each{|k, v|\n        if k == '-deleteHook'\n=begin\n          if v =~ /^rb_out\\S* (c(_\\d+_)?\\d+)/\n            ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$1]\n=end\n          if v =~ /rb_out\\S*(?:\\s+(::\\S*|[{](::.*)[}]|[\"](::.*)[\"]))? (c(_\\d+_)?(\\d+))/\n            ret[k[1..-1]] = MultiTkIp._tk_cmd_tbl[$4]\n          else\n            ret[k[1..-1]] = v\n          end\n        else\n          ret[k[1..-1]] = v\n        end\n      }\n    end\n    ret\n  end\n\n  def safeip_delete\n    ip = MultiTkIp.__getip\n    ip._eval(\"::safe::interpDelete \" + @ip_name)\n  end\n\n  def safeip_add_to_access_path(dir)\n    ip = MultiTkIp.__getip\n    ip._eval(\"::safe::interpAddToAccessPath #{@ip_name} #{dir}\")\n  end\n\n  def safeip_find_in_access_path(dir)\n    ip = MultiTkIp.__getip\n    ip._eval(\"::safe::interpFindInAccessPath #{@ip_name} #{dir}\")\n  end\n\n  def safeip_set_log_cmd(cmd = Proc.new)\n    ip = MultiTkIp.__getip\n    ip._eval(\"::safe::setLogCmd #{@ip_name} #{_get_eval_string(cmd)}\")\n  end\nend\n\n\n# encoding convert\nclass << MultiTkIp\n  def encoding_table\n    __getip.encoding_table\n  end\nend\nclass MultiTkIp\n  def encoding_table\n    @interp.encoding_table\n  end\n\n  def force_default_encoding=(mode)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.force_default_encoding = mode\n  end\n  def force_default_encoding?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.force_default_encoding?\n  end\n\n  def default_encoding=(enc)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.default_encoding = enc\n  end\n\n  def encoding=(enc)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.encoding = enc\n  end\n  def encoding_name\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.encoding_name\n  end\n  def encoding_obj\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.encoding_obj\n  end\n  alias encoding encoding_name\n  alias default_encoding encoding_name\n\n  def encoding_convertfrom(str, enc=None)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.encoding_convertfrom(str, enc)\n  end\n  alias encoding_convert_from encoding_convertfrom\n\n  def encoding_convertto(str, enc=None)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp.encoding_convertto(str, enc)\n  end\n  alias encoding_convert_to encoding_convertto\nend\n\n\n# remove methods for security\nif MultiTkIp::WITH_RUBY_VM && \n    ! MultiTkIp::RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!\n  class MultiTkIp\n    INTERP_THREAD = @@DEFAULT_MASTER.instance_variable_get('@interp_thread')\n    INTERP_MUTEX  = INTERP_THREAD[:mutex]\n    INTERP_ROOT_CHECK = INTERP_THREAD[:root_check]\n  end\n  module TkCore\n    INTERP_THREAD = MultiTkIp::INTERP_THREAD\n    INTERP_MUTEX  = MultiTkIp::INTERP_MUTEX\n    INTERP_ROOT_CHECK = MultiTkIp::INTERP_ROOT_CHECK\n  end\n  class MultiTkIp\n    remove_const(:INTERP_THREAD)\n    remove_const(:INTERP_MUTEX)\n    remove_const(:INTERP_ROOT_CHECK)\n  end\nend\n\nclass MultiTkIp\n  # undef_method :instance_eval\n  undef_method :instance_variable_get\n  undef_method :instance_variable_set\nend\n# end of MultiTkIp definition\n\n# defend against modification\n#MultiTkIp.freeze\n#TclTkLib.freeze\n\n########################################\n#  start Tk which depends on MultiTkIp\nmodule TkCore\n  INTERP = MultiTkIp\nend\nrequire 'tk'\n"
  },
  {
    "path": "ext/tk/lib/remote-tk.rb",
    "content": "#\n#               remote-tk.rb - supports to control remote Tk interpreters\n#                       by Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>\n\nif defined? MultiTkIp\n  fail RuntimeError, \"'remote-tk' library must be required before requiring 'multi-tk'\"\nend\n\nclass MultiTkIp; end\nclass RemoteTkIp < MultiTkIp; end\n\nclass MultiTkIp\n  @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)\n  @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST)\n  def self._IP_TABLE; @@IP_TABLE; end\n  def self._TK_TABLE_LIST; @@TK_TABLE_LIST; end\n\n  @flag = true\n  def self._DEFAULT_MASTER\n    # work only once\n    if @flag\n      @flag = nil\n      @@DEFAULT_MASTER\n    else\n      nil\n    end\n  end\nend\nclass RemoteTkIp\n  @@IP_TABLE = MultiTkIp._IP_TABLE unless defined?(@@IP_TABLE)\n  @@TK_TABLE_LIST = MultiTkIp._TK_TABLE_LIST unless defined?(@@TK_TABLE_LIST)\nend\nclass << MultiTkIp\n  undef _IP_TABLE\n  undef _TK_TABLE_LIST\nend\n\nrequire 'multi-tk'\n\nclass RemoteTkIp\n  if defined?(@@DEFAULT_MASTER)\n    MultiTkIp._DEFAULT_MASTER\n  else\n    @@DEFAULT_MASTER = MultiTkIp._DEFAULT_MASTER\n  end\nend\n\n\n###############################\n\nclass << RemoteTkIp\n  undef new_master, new_slave, new_safe_slave\n  undef new_trusted_slave, new_safeTk\n\n  def new(*args, &b)\n    ip = __new(*args)\n    ip.eval_proc(&b) if b\n    ip\n  end\nend\n\nclass RemoteTkIp\n  def initialize(remote_ip, displayof=nil, timeout=5)\n    if $SAFE >= 4\n      fail SecurityError, \"cannot access another interpreter at level #{$SAFE}\"\n    end\n\n    @interp = MultiTkIp.__getip\n    if @interp.safe?\n      fail SecurityError, \"safe-IP cannot create RemoteTkIp\"\n    end\n\n\n    @interp.allow_ruby_exit = false\n    @appname = @interp._invoke('tk', 'appname')\n    @remote = remote_ip.to_s.dup.freeze\n    if displayof.kind_of?(TkWindow)\n      @displayof = displayof.path.dup.freeze\n    else\n      @displayof = nil\n    end\n    if self.deleted?\n      fail RuntimeError, \"no Tk application named \\\"#{@remote}\\\"\"\n    end\n\n    @tk_windows = {}\n    @tk_table_list = []\n    @slave_ip_tbl = {}\n    @slave_ip_top = {}\n\n    @tk_windows.taint unless @tk_windows.tainted?\n    @tk_table_list.taint unless @tk_table_list.tainted?\n    @slave_ip_tbl.taint unless @slave_ip_tbl.tainted?\n    @slave_ip_top.taint unless @slave_ip_top.tainted?\n\n    @system = Object.new\n\n    @threadgroup  = ThreadGroup.new\n\n    @safe_level = [$SAFE]\n\n    @wait_on_mainloop = [true, 0]\n\n    @cmd_queue = Queue.new\n\n=begin\n    @cmd_receiver, @receiver_watchdog = _create_receiver_and_watchdog()\n\n    @threadgroup.add @cmd_receiver\n    @threadgroup.add @receiver_watchdog\n\n    @threadgroup.enclose\n=end\n    @@DEFAULT_MASTER.assign_receiver_and_watchdog(self)\n\n    @@IP_TABLE[@threadgroup] = self\n    @@TK_TABLE_LIST.size.times{ \n      (tbl = {}).tainted? || tbl.taint\n      @tk_table_list << tbl\n    }\n\n    @ret_val = TkVariable.new\n    if timeout > 0 && ! _available_check(timeout)\n      fail RuntimeError, \"cannot create connection\"\n    end\n    @ip_id = _create_connection\n\n    class << self\n      undef :instance_eval\n    end\n\n    self.freeze  # defend against modification\n  end\n\n  def manipulable?\n    return true if (Thread.current.group == ThreadGroup::Default)\n    MultiTkIp.__getip == @interp && ! @interp.safe?\n  end\n  def self.manipulable?\n    true\n  end\n\n  def _is_master_of?(tcltkip_obj)\n    tcltkip_obj == @interp\n  end\n  protected :_is_master_of?\n\n  def _ip_id_\n    @ip_id\n  end\n\n  def _available_check(timeout = 5)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    return nil if timeout < 1\n    @ret_val.value = ''\n    @interp._invoke('send', '-async', @remote, \n                    'send', '-async', Tk.appname, \n                    \"set #{@ret_val.id} ready\")\n    Tk.update\n    if @ret_val != 'ready'\n      (1..(timeout*5)).each{\n        sleep 0.2 \n        Tk.update\n        break if @ret_val == 'ready'\n      }\n    end\n    @ret_val.value == 'ready'\n  end\n  private :_available_check\n\n  def _create_connection\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    ip_id = '_' + @interp._invoke('send', @remote, <<-'EOS') + '_'\n      if {[catch {set _rubytk_control_ip_id_} ret] != 0} {\n        set _rubytk_control_ip_id_ 0\n      } else {\n        set _rubytk_control_ip_id_ [expr $ret + 1]\n      }\n      return $_rubytk_control_ip_id_\n    EOS\n\n    @interp._invoke('send', @remote, <<-EOS)\n      proc rb_out#{ip_id} args {\n        send #{@appname} rb_out \\$args\n      }\n    EOS\n\n    ip_id\n  end\n  private :_create_connection\n\n  def _appsend(enc_mode, async, *cmds)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    p ['_appsend', [@remote, @displayof], enc_mode, async, cmds] if $DEBUG\n    if $SAFE >= 4\n      fail SecurityError, \"cannot send commands at level 4\"\n    elsif $SAFE >= 1 && cmds.find{|obj| obj.tainted?}\n      fail SecurityError, \"cannot send tainted commands at level #{$SAFE}\"\n    end\n\n    cmds = @interp._merge_tklist(*TkUtil::_conv_args([], enc_mode, *cmds))\n    if @displayof\n      if async\n        @interp.__invoke('send', '-async', '-displayof', @displayof, \n                         '--', @remote, *cmds)\n      else\n        @interp.__invoke('send', '-displayof', @displayof, \n                         '--', @remote, *cmds)\n      end\n    else\n      if async\n        @interp.__invoke('send', '-async', '--', @remote, *cmds)\n      else\n        @interp.__invoke('send', '--', @remote, *cmds)\n      end\n    end\n  end\n  private :_appsend\n\n  def ready?(timeout=5)\n    if timeout < 0\n      fail ArgumentError, \"timeout must be positive number\"\n    end\n    _available_check(timeout)\n  end\n\n  def is_rubytk?\n    return false if _appsend(false, false, 'info', 'command', 'ruby') == \"\"\n    [ _appsend(false, false, 'ruby', 'RUBY_VERSION'), \n      _appsend(false, false, 'set', 'tk_patchLevel') ]\n  end\n\n  def appsend(async, *args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    if async != true && async != false && async != nil\n      args.unshift(async)\n      async = false\n    end\n    if @displayof\n      Tk.appsend_displayof(@remote, @displayof, async, *args)\n    else\n      Tk.appsend(@remote, async, *args)\n    end\n  end\n\n  def rb_appsend(async, *args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    if async != true && async != false && async != nil\n      args.unshift(async)\n      async = false\n    end\n    if @displayof\n      Tk.rb_appsend_displayof(@remote, @displayof, async, *args)\n    else\n      Tk.rb_appsend(@remote, async, *args)\n    end\n  end\n\n  def create_slave(name, safe=false)\n    if safe\n      safe_opt = ''\n    else\n      safe_opt = '-safe'\n    end\n    _appsend(false, false, \"interp create #{safe_opt} -- #{name}\")\n  end\n\n  def make_safe\n    fail RuntimeError, 'cannot change safe mode of the remote interpreter'\n  end\n\n  def safe?\n    _appsend(false, false, 'interp issafe')\n  end\n\n  def safe_base?\n    false\n  end\n\n  def allow_ruby_exit?\n    false\n  end\n\n  def allow_ruby_exit= (mode)\n    fail RuntimeError, 'cannot change mode of the remote interpreter'\n  end\n\n  def delete\n    _appsend(false, true, 'exit')\n  end\n\n  def deleted?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    if @displayof\n      lst = @interp._invoke_without_enc('winfo', 'interps', \n                                        '-displayof', @displayof)\n    else\n      lst = @interp._invoke_without_enc('winfo', 'interps')\n    end\n    # unless @interp._split_tklist(lst).index(@remote)\n    unless @interp._split_tklist(lst).index(_toUTF8(@remote))\n      true\n    else\n      false\n    end\n  end\n\n  def has_mainwindow?\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n\n    begin\n      inf = @interp._invoke_without_enc('info', 'command', '.')\n    rescue Exception\n      return nil\n    end\n    if !inf.kind_of?(String) || inf != '.'\n      false\n    else\n      true\n    end\n  end\n\n  def invalid_namespace?\n    false\n  end\n\n  def restart\n    fail RuntimeError, 'cannot restart the remote interpreter'\n  end\n\n  def __eval(str)\n    _appsend(false, false, str)\n  end\n  def _eval(str)\n    _appsend(nil, false, str)\n  end\n  def _eval_without_enc(str)\n    _appsend(false, false, str)\n  end\n  def _eval_with_enc(str)\n    _appsend(true, false, str)\n  end\n\n  def _invoke(*args)\n    _appsend(nil, false, *args)\n  end\n\n  def __invoke(*args)\n    _appsend(false, false, *args)\n  end\n  def _invoke(*args)\n    _appsend(nil, false, *args)\n  end\n  def _invoke_without_enc(*args)\n    _appsend(false, false, *args)\n  end\n  def _invoke_with_enc(*args)\n    _appsend(true, false, *args)\n  end\n\n  def _toUTF8(str, encoding=nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._toUTF8(str, encoding)\n  end\n\n  def _fromUTF8(str, encoding=nil)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._fromUTF8(str, encoding)\n  end\n\n  def _thread_vwait(var_name)\n    _appsend(false, 'thread_vwait', varname)\n  end\n\n  def _thread_tkwait(mode, target)\n    _appsend(false, 'thread_tkwait', mode, target)\n  end\n\n  def _return_value\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._return_value\n  end\n\n  def _get_variable(var_name, flag)\n    # ignore flag\n    _appsend(false, 'set', TkComm::_get_eval_string(var_name))\n  end\n  def _get_variable2(var_name, index_name, flag)\n    # ignore flag\n    _appsend(false, 'set', \"#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})\")\n  end\n\n  def _set_variable(var_name, value, flag)\n    # ignore flag\n    _appsend(false, 'set', TkComm::_get_eval_string(var_name), TkComm::_get_eval_string(value))\n  end\n  def _set_variable2(var_name, index_name, value, flag)\n    # ignore flag\n    _appsend(false, 'set', \"#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})\", TkComm::_get_eval_string(value))\n  end\n\n  def _unset_variable(var_name, flag)\n    # ignore flag\n    _appsend(false, 'unset', TkComm::_get_eval_string(var_name))\n  end\n  def _unset_variable2(var_name, index_name, flag)\n    # ignore flag\n    _appsend(false, 'unset', \"#{var_name}(#{index_name})\")\n  end\n\n  def _get_global_var(var_name)\n    _appsend(false, 'set', TkComm::_get_eval_string(var_name))\n  end\n  def _get_global_var2(var_name, index_name)\n    _appsend(false, 'set', \"#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})\")\n  end\n\n  def _set_global_var(var_name, value)\n    _appsend(false, 'set', TkComm::_get_eval_string(var_name), TkComm::_get_eval_string(value))\n  end\n  def _set_global_var2(var_name, index_name, value)\n    _appsend(false, 'set', \"#{TkComm::_get_eval_string(var_name)}(#{TkComm::_get_eval_string(index_name)})\", TkComm::_get_eval_string(value))\n  end\n\n  def _unset_global_var(var_name)\n    _appsend(false, 'unset', TkComm::_get_eval_string(var_name))\n  end\n  def _unset_global_var2(var_name, index_name)\n    _appsend(false, 'unset', \"#{var_name}(#{index_name})\")\n  end\n\n  def _split_tklist(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._split_tklist(str)\n  end\n\n  def _merge_tklist(*args)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._merge_tklist(*args)\n  end\n\n  def _conv_listelement(str)\n    raise SecurityError, \"no permission to manipulate\" unless self.manipulable?\n    @interp._conv_listelement(str)\n  end\n\n  def _create_console\n    fail RuntimeError, 'not support \"_create_console\" on the remote interpreter'\n  end\n\n  def mainloop\n    fail RuntimeError, 'not support \"mainloop\" on the remote interpreter'\n  end\n  def mainloop_watchdog\n    fail RuntimeError, 'not support \"mainloop_watchdog\" on the remote interpreter'\n  end\n  def do_one_evant(flag = nil)\n    fail RuntimeError, 'not support \"do_one_event\" on the remote interpreter'\n  end\n  def mainloop_abort_on_exception\n    fail RuntimeError, 'not support \"mainloop_abort_on_exception\" on the remote interpreter'\n  end\n  def mainloop_abort_on_exception=(mode)\n    fail RuntimeError, 'not support \"mainloop_abort_on_exception=\" on the remote interpreter'\n  end\n  def set_eventloop_tick(*args)\n    fail RuntimeError, 'not support \"set_eventloop_tick\" on the remote interpreter'\n  end\n  def get_eventloop_tick\n    fail RuntimeError, 'not support \"get_eventloop_tick\" on the remote interpreter'\n  end\n  def set_no_event_wait(*args)\n    fail RuntimeError, 'not support \"set_no_event_wait\" on the remote interpreter'\n  end\n  def get_no_event_wait\n    fail RuntimeError, 'not support \"get_no_event_wait\" on the remote interpreter'\n  end\n  def set_eventloop_weight(*args)\n    fail RuntimeError, 'not support \"set_eventloop_weight\" on the remote interpreter'\n  end\n  def get_eventloop_weight\n    fail RuntimeError, 'not support \"get_eventloop_weight\" on the remote interpreter'\n  end\nend\n\nclass << RemoteTkIp\n  def mainloop(*args)\n    fail RuntimeError, 'not support \"mainloop\" on the remote interpreter'\n  end\n  def mainloop_watchdog(*args)\n    fail RuntimeError, 'not support \"mainloop_watchdog\" on the remote interpreter'\n  end\n  def do_one_evant(flag = nil)\n    fail RuntimeError, 'not support \"do_one_event\" on the remote interpreter'\n  end\n  def mainloop_abort_on_exception\n    fail RuntimeError, 'not support \"mainloop_abort_on_exception\" on the remote interpreter'\n  end\n  def mainloop_abort_on_exception=(mode)\n    fail RuntimeError, 'not support \"mainloop_abort_on_exception=\" on the remote interpreter'\n  end\n  def set_eventloop_tick(*args)\n    fail RuntimeError, 'not support \"set_eventloop_tick\" on the remote interpreter'\n  end\n  def get_eventloop_tick\n    fail RuntimeError, 'not support \"get_eventloop_tick\" on the remote interpreter'\n  end\n  def set_no_event_wait(*args)\n    fail RuntimeError, 'not support \"set_no_event_wait\" on the remote interpreter'\n  end\n  def get_no_event_wait\n    fail RuntimeError, 'not support \"get_no_event_wait\" on the remote interpreter'\n  end\n  def set_eventloop_weight(*args)\n    fail RuntimeError, 'not support \"set_eventloop_weight\" on the remote interpreter'\n  end\n  def get_eventloop_weight\n    fail RuntimeError, 'not support \"get_eventloop_weight\" on the remote interpreter'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tcltk.rb",
    "content": "# tof\n\n#### tcltk library, more direct manipulation of tcl/tk\n####    Sep. 5, 1997    Y. Shigehiro\n\nrequire \"tcltklib\"\n\n################\n\n# module TclTk: collection of tcl/tk utilities (supplies namespace.)\nmodule TclTk\n\n  # initialize Hash to hold unique symbols and such\n  @namecnt = {}\n\n  # initialize Hash to hold callbacks\n  @callback = {}\nend\n\n# TclTk.mainloop(): call TclTkLib.mainloop()\ndef TclTk.mainloop()\n  print(\"mainloop: start\\n\") if $DEBUG\n  TclTkLib.mainloop()\n  print(\"mainloop: end\\n\") if $DEBUG\nend\n\n# TclTk.deletecallbackkey(ca): remove callback from TclTk module\n#     this does not remove callbacks from tcl/tk interpreter\n#     without calling this method, TclTkInterpreter will not be GCed\n#   ca: callback(TclTkCallback)\ndef TclTk.deletecallbackkey(ca)\n  print(\"deletecallbackkey: \", ca.to_s(), \"\\n\") if $DEBUG\n  @callback.delete(ca.to_s)\nend\n\n# TclTk.dcb(ca, wid, W): call TclTk.deletecallbackkey() for each callbacks\n#     in an array.\n#     this is for callback for top-level <Destroy>\n#   ca: array of callbacks(TclTkCallback)\n#   wid: top-level widget(TclTkWidget)\n#   w: information about window given by %W(String)\ndef TclTk.dcb(ca, wid, w)\n  if wid.to_s() == w\n    ca.each{|i|\n      TclTk.deletecallbackkey(i)\n    }\n  end\nend\n\n# TclTk._addcallback(ca): register callback\n#   ca: callback(TclTkCallback)\ndef TclTk._addcallback(ca)\n  print(\"_addcallback: \", ca.to_s(), \"\\n\") if $DEBUG\n  @callback[ca.to_s()] = ca\nend\n\n# TclTk._callcallback(key, arg): invoke registered callback\n#   key: key to select callback (to_s value of the TclTkCallback)\n#   arg: parameter from tcl/tk interpreter\ndef TclTk._callcallback(key, arg)\n  print(\"_callcallback: \", @callback[key].inspect, \"\\n\") if $DEBUG\n  @callback[key]._call(arg)\n  # throw out callback value\n  # should return String to satisfy rb_eval_string()\n  return \"\"\nend\n\n# TclTk._newname(prefix): generate unique name(String)\n#   prefix: prefix of the unique name\ndef TclTk._newname(prefix)\n  # generated name counter is stored in @namecnt\n  if !@namecnt.key?(prefix)\n    # first appearing prefix, initialize\n    @namecnt[prefix] = 1\n  else\n    # already appeared prefix, generate next name\n    @namecnt[prefix] += 1\n  end\n  return \"#{prefix}#{@namecnt[prefix]}\"\nend\n\n################\n\n# class TclTkInterpreter: tcl/tk interpreter\nclass TclTkInterpreter\n\n  # initialize(): \n  def initialize()\n    # generate interpreter object\n    @ip = TclTkIp.new()\n\n    # add ruby_fmt command to tcl interpreter\n    # ruby_fmt command format arguments by `format' and call `ruby' command\n    # (notice ruby command receives only one argument)\n    if $DEBUG\n      @ip._eval(\"proc ruby_fmt {fmt args} { puts \\\"ruby_fmt: $fmt $args\\\" ; set cmd [list ruby [format $fmt $args]] ; uplevel $cmd }\")\n    else\n      @ip._eval(\"proc ruby_fmt {fmt args} { set cmd [list ruby [format $fmt $args]] ; uplevel $cmd }\")\n    end\n\n    # @ip._get_eval_string(*args): generate string to evaluate in tcl interpreter\n    #   *args: script which is going to be evaluated under tcl/tk\n    def @ip._get_eval_string(*args)\n      argstr = \"\"\n      args.each{|arg|\n        argstr += \" \" if argstr != \"\"\n        # call to_eval if it is defined\n        if (arg.respond_to?(:to_eval))\n          argstr += arg.to_eval()\n        else\n          # call to_s unless defined\n          argstr += arg.to_s()\n        end\n      }\n      return argstr\n    end\n\n    # @ip._eval_args(*args): evaluate string under tcl/tk interpreter\n    #     returns result string.\n    #   *args: script which is going to be evaluated under tcl/tk\n    def @ip._eval_args(*args)\n      # calculate the string to eval in the interpreter\n      argstr = _get_eval_string(*args)\n\n      # evaluate under the interpreter\n      print(\"_eval: \\\"\", argstr, \"\\\"\") if $DEBUG\n      res = _eval(argstr)\n      if $DEBUG\n        print(\" -> \\\"\", res, \"\\\"\\n\")\n      elsif  _return_value() != 0\n        print(res, \"\\n\")\n      end\n      fail(%Q/can't eval \"#{argstr}\"/) if _return_value() != 0 #'\n      return res\n    end\n\n    # generate tcl/tk command object and register in the hash\n    @commands = {}\n    # for all commands registered in tcl/tk interpreter:\n    @ip._eval(\"info command\").split(/ /).each{|comname|\n      if comname =~ /^[.]/\n        # if command is a widget (path), generate TclTkWidget,\n        # and register it in the hash\n        @commands[comname] = TclTkWidget.new(@ip, comname)\n      else\n        # otherwise, generate TclTkCommand\n        @commands[comname] = TclTkCommand.new(@ip, comname)\n      end\n    }\n  end\n\n  # commands(): returns hash of the tcl/tk commands\n  def commands()\n    return @commands\n  end\n\n  # rootwidget(): returns root widget(TclTkWidget)\n  def rootwidget()\n    return @commands[\".\"]\n  end\n\n  # _tcltkip(): returns @ip(TclTkIp)\n  def _tcltkip()\n    return @ip\n  end\n\n  # method_missing(id, *args): execute undefined method as tcl/tk command\n  #   id: method symbol\n  #   *args: method arguments\n  def method_missing(id, *args)\n    # if command named by id registered, then execute it\n    if @commands.key?(id.id2name)\n      return @commands[id.id2name].e(*args)\n    else\n      # otherwise, exception\n      super\n    end\n  end\nend\n\n# class TclTkObject: base class of the tcl/tk objects\nclass TclTkObject\n\n  # initialize(ip, exp): \n  #   ip: interpreter(TclTkIp)\n  #   exp: tcl/tk representation\n  def initialize(ip, exp)\n    fail(\"type is not TclTkIp\") if !ip.kind_of?(TclTkIp)\n    @ip = ip\n    @exp = exp\n  end\n\n  # to_s(): returns tcl/tk representation\n  def to_s()\n    return @exp\n  end\nend\n\n# class TclTkCommand: tcl/tk commands\n# you should not call TclTkCommand.new()\n# commands are created by TclTkInterpreter:initialize()\nclass TclTkCommand < TclTkObject\n\n  # e(*args): execute command.  returns String (e is for exec or eval)\n  #   *args: command arguments\n  def e(*args)\n    return @ip._eval_args(to_s(), *args)\n  end\nend\n\n# class TclTkLibCommand: tcl/tk commands in the library\nclass TclTkLibCommand < TclTkCommand\n\n  # initialize(ip, name): \n  #   ip: interpreter(TclTkInterpreter)\n  #   name: command name (String)\n  def initialize(ip, name)\n    super(ip._tcltkip, name)\n  end\nend\n\n# class TclTkVariable: tcl/tk variable\nclass TclTkVariable < TclTkObject\n\n  # initialize(interp, dat): \n  #   interp: interpreter(TclTkInterpreter)\n  #   dat: the value to set(String)\n  #       if nil, not initialize variable\n  def initialize(interp, dat)\n    # auto-generate tcl/tk representation (variable name)\n    exp = TclTk._newname(\"v_\")\n    # initialize TclTkObject\n    super(interp._tcltkip(), exp)\n    # safe this for `set' command\n    @set = interp.commands()[\"set\"]\n    # set value\n    set(dat) if dat\n  end\n\n  # although you can set/refer variable by using set in tcl/tk,\n  # we provide the method for accessing variables\n\n  # set(data): set tcl/tk variable using `set'\n  #   data: new value\n  def set(data)\n    @set.e(to_s(), data.to_s())\n  end\n\n  # get(): read tcl/tk variable(String) using `set'\n  def get()\n    return @set.e(to_s())\n  end\nend\n\n# class TclTkWidget: tcl/tk widget\nclass TclTkWidget < TclTkCommand\n\n  # initialize(*args): \n  #   *args: parameters\n  def initialize(*args)\n    if args[0].kind_of?(TclTkIp)\n      # in case the 1st argument is TclTkIp:\n\n      # Wrap tcl/tk widget by TclTkWidget\n      # (used in TclTkInterpreter#initialize())\n\n      # need two arguments\n      fail(\"invalid # of parameter\") if args.size != 2\n\n      # ip: interpreter(TclTkIp)\n      # exp: tcl/tk representation\n      ip, exp = args\n\n      # initialize TclTkObject\n      super(ip, exp)\n    elsif args[0].kind_of?(TclTkInterpreter)\n      # in case 1st parameter is TclTkInterpreter:\n\n      # generate new widget from parent widget\n\n      # interp: interpreter(TclTkInterpreter)\n      # parent: parent widget\n      # command: widget generating tk command(label )\n      # *args: argument to the command \n      interp, parent, command, *args = args\n\n      # generate widget name\n      exp = parent.to_s()\n      exp += \".\" if exp !~ /[.]$/\n      exp += TclTk._newname(\"w_\")\n      # initialize TclTkObject\n      super(interp._tcltkip(), exp)\n      # generate widget\n      res = @ip._eval_args(command, exp, *args)\n#      fail(\"can't create Widget\") if res != exp\n      # for tk_optionMenu, it is legal res != exp\n    else\n      fail(\"first parameter is not TclTkInterpreter\")\n    end\n  end\nend\n\n# class TclTkCallback: tcl/tk callbacks\nclass TclTkCallback < TclTkObject\n\n  # initialize(interp, pr, arg): \n  #   interp: interpreter(TclTkInterpreter)\n  #   pr: callback procedure(Proc)\n  #   arg: string to pass as block parameters of pr\n  #       bind command of tcl/tk uses % replacement for parameters\n  #       pr can receive replaced data using block parameter\n  #       its format is specified by arg string\n  #       You should not specify arg for the command like \n  #       scrollbar with -command option, which receives parameters\n  #       without specifying any replacement\n  def initialize(interp, pr, arg = nil)\n    # auto-generate tcl/tk representation (variable name)\n    exp = TclTk._newname(\"c_\")\n    # initialize TclTkObject\n    super(interp._tcltkip(), exp)\n    # save parameters\n    @pr = pr\n    @arg = arg\n    # register in the module\n    TclTk._addcallback(self)\n  end\n\n  # to_eval(): retuens string representation for @ip._eval_args\n  def to_eval()\n    if @arg\n      # bind replaces %s before calling ruby_fmt, so %%s is used\n      s = %Q/{ruby_fmt {TclTk._callcallback(\"#{to_s()}\", \"%%s\")} #{@arg}}/\n    else\n      s = %Q/{ruby_fmt {TclTk._callcallback(\"#{to_s()}\", \"%s\")}}/\n    end\n\n    return s\n  end\n\n  # _call(arg): invoke callback\n  #   arg: callback parameter\n  def _call(arg)\n    @pr.call(arg)\n  end\nend\n\n# class TclTkImage: tcl/tk images\nclass TclTkImage < TclTkCommand\n\n  # initialize(interp, t, *args): \n  #     generating image is done by TclTkImage.new()\n  #     destrying is done by image delete (inconsistent, sigh)\n  #   interp: interpreter(TclTkInterpreter)\n  #   t: image type (photo, bitmap, etc.)\n  #   *args: command argument\n  def initialize(interp, t, *args)\n    # auto-generate tcl/tk representation\n    exp = TclTk._newname(\"i_\")\n    # initialize TclTkObject\n    super(interp._tcltkip(), exp)\n    # generate image\n    res = @ip._eval_args(\"image create\", t, exp, *args)\n    fail(\"can't create Image\") if res != exp\n  end\nend\n\n# eof\n"
  },
  {
    "path": "ext/tk/lib/tk/after.rb",
    "content": "#\n#   tk/after.rb : methods for Tcl/Tk after command\n#\n#   $Id$\n#\nrequire 'tk/timer'\n"
  },
  {
    "path": "ext/tk/lib/tk/autoload.rb",
    "content": "#\n#  autoload\n#\n############################################\n#  geometry manager\nmodule Tk\n  autoload :Grid,             'tk/grid'\n  def Grid(*args); TkGrid.configure(*args); end\n\n  autoload :Pack,             'tk/pack'\n  def Pack(*args); TkPack.configure(*args); end\n\n  autoload :Place,            'tk/place'\n  def Place(*args); TkPlace.configure(*args); end\nend\n\nautoload :TkGrid,             'tk/grid'\ndef TkGrid(*args); TkGrid.configure(*args); end\n\nautoload :TkPack,             'tk/pack'\ndef TkPack(*args); TkPack.configure(*args); end\n\nautoload :TkPlace,            'tk/place'\ndef TkPlace(*args); TkPlace.configure(*args); end\n\n\n############################################\n# classes on Tk module\nmodule Tk\n  autoload :Button,           'tk/button'\n\n  autoload :Canvas,           'tk/canvas'\n\n  autoload :CheckButton,      'tk/checkbutton'\n  autoload :Checkbutton,      'tk/checkbutton'\n\n  autoload :Entry,            'tk/entry'\n\n  autoload :Frame,            'tk/frame'\n\n  autoload :Label,            'tk/label'\n\n  autoload :LabelFrame,       'tk/labelframe'\n  autoload :Labelframe,       'tk/labelframe'\n\n  autoload :Listbox,          'tk/listbox'\n\n  autoload :Menu,             'tk/menu'\n  autoload :MenuClone,        'tk/menu'\n  autoload :CloneMenu,        'tk/menu'\n  autoload :SystemMenu,       'tk/menu'\n  autoload :SysMenu_Help,     'tk/menu'\n  autoload :SysMenu_System,   'tk/menu'\n  autoload :SysMenu_Apple,    'tk/menu'\n  autoload :Menubutton,       'tk/menu'\n  autoload :MenuButton,       'tk/menu'\n  autoload :OptionMenubutton, 'tk/menu'\n  autoload :OptionMenBbutton, 'tk/menu'\n\n  autoload :Message,          'tk/message'\n\n  autoload :PanedWindow,      'tk/panedwindow'\n  autoload :Panedwindow,      'tk/panedwindow'\n\n  autoload :RadioButton,      'tk/radiobutton'\n  autoload :Radiobutton,      'tk/radiobutton'\n\n  autoload :Root,             'tk/root'\n\n  autoload :Scale,            'tk/scale'\n\n  autoload :Scrollbar,        'tk/scrollbar'\n  autoload :XScrollbar,       'tk/scrollbar'\n  autoload :YScrollbar,       'tk/scrollbar'\n\n  autoload :Spinbox,          'tk/spinbox'\n\n  autoload :Text,             'tk/text'\n\n  autoload :Toplevel,         'tk/toplevel'\nend\n\n\n############################################\n# sub-module of Tk\nmodule Tk\n  autoload :Clock,            'tk/clock'\n\n  autoload :OptionObj,        'tk/optionobj'\n\n  autoload :X_Scrollable,     'tk/scrollable'\n  autoload :Y_Scrollable,     'tk/scrollable'\n  autoload :Scrollable,       'tk/scrollable'\n\n  autoload :Wm,               'tk/wm'\n  autoload :Wm_for_General,   'tk/wm'\n\n  autoload :MacResource,      'tk/macpkg'\n\n  autoload :WinDDE,           'tk/winpkg'\n  autoload :WinRegistry,      'tk/winpkg'\n\n  autoload :ValidateConfigure,     'tk/validation'\n  autoload :ItemValidateConfigure, 'tk/validation'\n\n  autoload :EncodedString,    'tk/encodedstr'\n  def Tk.EncodedString(str, enc = nil); Tk::EncodedString.new(str, enc); end\n\n  autoload :BinaryString,     'tk/encodedstr'\n  def Tk.BinaryString(str); Tk::BinaryString.new(str); end\n\n  autoload :UTF8_String,      'tk/encodedstr'\n  def Tk.UTF8_String(str); Tk::UTF8_String.new(str); end\n\nend\n\n\n############################################\n#  toplevel classes/modules (fixed)\nautoload :TkBgError,          'tk/bgerror'\n\nautoload :TkBindTag,          'tk/bindtag'\nautoload :TkBindTagAll,       'tk/bindtag'\nautoload :TkDatabaseClass,    'tk/bindtag'\n\nautoload :TkConsole,          'tk/console'\n\nautoload :TkcItem,            'tk/canvas'\nautoload :TkcArc,             'tk/canvas'\nautoload :TkcBitmap,          'tk/canvas'\nautoload :TkcImage,           'tk/canvas'\nautoload :TkcLine,            'tk/canvas'\nautoload :TkcOval,            'tk/canvas'\nautoload :TkcPolygon,         'tk/canvas'\nautoload :TkcRectangle,       'tk/canvas'\nautoload :TkcText,            'tk/canvas'\nautoload :TkcWindow,          'tk/canvas'\n\nautoload :TkcTagAccess,       'tk/canvastag'\nautoload :TkcTag,             'tk/canvastag'\nautoload :TkcTagString,       'tk/canvastag'\nautoload :TkcNamedTag,        'tk/canvastag'\nautoload :TkcTagAll,          'tk/canvastag'\nautoload :TkcTagCurrent,      'tk/canvastag'\nautoload :TkcTagGroup,        'tk/canvastag'\n\nautoload :TkClipboard,        'tk/clipboard'\n\nautoload :TkComposite,        'tk/composite'\n\nautoload :TkConsole,          'tk/console'\n\nautoload :TkDialog,           'tk/dialog'\nautoload :TkDialog2,          'tk/dialog'\nautoload :TkDialogObj,        'tk/dialog'\nautoload :TkWarning,          'tk/dialog'\nautoload :TkWarning2,         'tk/dialog'\nautoload :TkWarningObj,       'tk/dialog'\n\nautoload :TkEvent,            'tk/event'\n\nautoload :TkFont,             'tk/font'\nautoload :TkNamedFont,        'tk/font'\n\nautoload :TkImage,            'tk/image'\nautoload :TkBitmapImage,      'tk/image'\nautoload :TkPhotoImage,       'tk/image'\n\nautoload :TkItemConfigMethod, 'tk/itemconfig'\n\nautoload :TkTreatItemFont,    'tk/itemfont'\n\nautoload :TkKinput,           'tk/kinput'\n\nautoload :TkSystemMenu,       'tk/menu'\n\nautoload :TkMenubar,          'tk/menubar'\n\nautoload :TkMenuSpec,         'tk/menuspec'\n\nautoload :TkManageFocus,      'tk/mngfocus'\n\nautoload :TkMsgCatalog,       'tk/msgcat'\nautoload :TkMsgCat,           'tk/msgcat'\n\nautoload :TkNamespace,        'tk/namespace'\n\nautoload :TkOptionDB,         'tk/optiondb'\nautoload :TkOption,           'tk/optiondb'\nautoload :TkResourceDB,       'tk/optiondb'\n\nautoload :TkPackage,          'tk/package'\n\nautoload :TkPalette,          'tk/palette'\n\nautoload :TkRoot,             'tk/root'\n\nautoload :TkScrollbox,        'tk/scrollbox'\n\nautoload :TkSelection,        'tk/selection'\n\nautoload :TkTreatTagFont,     'tk/tagfont'\n\nautoload :TkTextImage,        'tk/textimage'\nautoload :TktImage,           'tk/textimage'\n\nautoload :TkTextMark,         'tk/textmark'\nautoload :TkTextNamedMark,    'tk/textmark'\nautoload :TkTextMarkInsert,   'tk/textmark'\nautoload :TkTextMarkCurrent,  'tk/textmark'\nautoload :TkTextMarkAnchor,   'tk/textmark'\nautoload :TktMark,            'tk/textmark'\nautoload :TktNamedMark,       'tk/textmark'\nautoload :TktMarkInsert,      'tk/textmark'\nautoload :TktMarkCurrent,     'tk/textmark'\nautoload :TktMarkAnchor,      'tk/textmark'\n\nautoload :TkTextTag,          'tk/texttag'\nautoload :TkTextNamedTag,     'tk/texttag'\nautoload :TkTextTagSel,       'tk/texttag'\nautoload :TktTag,             'tk/texttag'\nautoload :TktNamedTag,        'tk/texttag'\nautoload :TktTagSel,          'tk/texttag'\n\nautoload :TkTextWindow,       'tk/textwindow'\nautoload :TktWindow,          'tk/textwindow'\n\nautoload :TkAfter,            'tk/timer'\nautoload :TkTimer,            'tk/timer'\nautoload :TkRTTimer,          'tk/timer'\n\nautoload :TkTextWin,          'tk/txtwin_abst'\n\nautoload :TkValidation,       'tk/validation'\nautoload :TkValidateCommand,  'tk/validation'\n\nautoload :TkVariable,         'tk/variable'\nautoload :TkVarAccess,        'tk/variable'\n\nautoload :TkVirtualEvent,     'tk/virtevent'\nautoload :TkNamedVirtualEvent,'tk/virtevent'\n\nautoload :TkWinfo,            'tk/winfo'\n\nautoload :TkXIM,              'tk/xim'\n\n\n############################################\n#  toplevel classes/modules (switchable)\nmodule Tk\n  @TOPLEVEL_ALIAS_TABLE = {}\n  @TOPLEVEL_ALIAS_TABLE[:Tk] = {\n    :TkButton             => 'tk/button', \n\n    :TkCanvas             => 'tk/canvas', \n\n    :TkCheckButton        => 'tk/checkbutton', \n    :TkCheckbutton        => 'tk/checkbutton', \n\n    # :TkDialog             => 'tk/dialog', \n    # :TkDialog2            => 'tk/dialog', \n    # :TkDialogObj          => 'tk/dialog', \n    # :TkWarning            => 'tk/dialog', \n    # :TkWarning2           => 'tk/dialog', \n    # :TkWarningObj         => 'tk/dialog', \n\n    :TkEntry              => 'tk/entry', \n\n    :TkFrame              => 'tk/frame', \n\n    :TkLabel              => 'tk/label', \n\n    :TkLabelFrame         => 'tk/labelframe', \n    :TkLabelframe         => 'tk/labelframe', \n\n    :TkListbox            => 'tk/listbox', \n\n    :TkMacResource        => 'tk/macpkg', \n\n    :TkMenu               => 'tk/menu', \n    :TkMenuClone          => 'tk/menu', \n    :TkCloneMenu          => 'tk/menu', \n    # :TkSystemMenu         => 'tk/menu', \n    :TkSysMenu_Help       => 'tk/menu', \n    :TkSysMenu_System     => 'tk/menu', \n    :TkSysMenu_Apple      => 'tk/menu', \n    :TkMenubutton         => 'tk/menu', \n    :TkMenuButton         => 'tk/menu', \n    :TkOptionMenubutton   => 'tk/menu', \n    :TkOptionMenuButton   => 'tk/menu', \n\n    :TkMessage            => 'tk/message', \n\n    :TkPanedWindow        => 'tk/panedwindow', \n    :TkPanedwindow        => 'tk/panedwindow', \n\n    :TkRadioButton        => 'tk/radiobutton', \n    :TkRadiobutton        => 'tk/radiobutton', \n\n    # :TkRoot               => 'tk/root', \n\n    :TkScale              => 'tk/scale', \n\n    :TkScrollbar          => 'tk/scrollbar', \n    :TkXScrollbar         => 'tk/scrollbar', \n    :TkYScrollbar         => 'tk/scrollbar', \n\n    :TkSpinbox            => 'tk/spinbox', \n\n    :TkText               => 'tk/text', \n\n    :TkToplevel           => 'tk/toplevel', \n\n    :TkWinDDE             => 'tk/winpkg', \n    :TkWinRegistry        => 'tk/winpkg', \n  }\n\n  @TOPLEVEL_ALIAS_OWNER = {}\n\n  @TOPLEVEL_ALIAS_SETUP_PROC = {}\n\n  @current_default_widget_set = nil\nend\n\n\n############################################\n#  methods to control default widget set\n############################################\n\nclass << Tk\n  def default_widget_set\n    @current_default_widget_set\n  end\n\n  def default_widget_set=(target)\n    target = target.to_sym\n    return target if target == @current_default_widget_set\n\n    if (cmd = @TOPLEVEL_ALIAS_SETUP_PROC[target])\n      cmd.call(target)\n    end\n\n    _replace_toplevel_aliases(target)\n  end\n\n  def __set_toplevel_aliases__(target, obj, *symbols)\n    @TOPLEVEL_ALIAS_TABLE[target = target.to_sym] ||= {}\n    symbols.each{|sym|\n      @TOPLEVEL_ALIAS_TABLE[target][sym = sym.to_sym] = obj\n      # if @current_default_widget_set == target\n      if @TOPLEVEL_ALIAS_OWNER[sym] == target\n        Object.class_eval{remove_const sym} if Object.const_defined?(sym)\n        Object.const_set(sym, obj)\n      end\n    }\n  end\n\n  ###################################\n  private\n  def _replace_toplevel_aliases(target)\n    # check already autoloaded\n    if (table = @TOPLEVEL_ALIAS_TABLE[current = @current_default_widget_set])\n      table.each{|sym, file|\n        if !Object.autoload?(sym) && Object.const_defined?(sym) && \n            @TOPLEVEL_ALIAS_TABLE[current][sym].kind_of?(String)\n          # autoload -> class\n          @TOPLEVEL_ALIAS_TABLE[current][sym] = Object.const_get(sym)\n        end\n      }\n    end\n\n    # setup autoloads\n    @TOPLEVEL_ALIAS_TABLE[target].each{|sym, file|\n      Object.class_eval{remove_const sym} if Object.const_defined?(sym)\n      if file.kind_of?(String)\n        # file => autoload target file\n        Object.autoload(sym, file)\n      else\n        # file => loaded class object\n        Object.const_set(sym, file)\n      end\n      @TOPLEVEL_ALIAS_OWNER[sym] = target\n    }\n\n    # update current alias\n    @current_default_widget_set = target\n  end\nend\n\n############################################\n# setup default widget set => :Tk\nTk.default_widget_set = :Tk\n\n\n############################################\n#  depend on the version of Tcl/Tk\n# major, minor, type, type_name, patchlevel = TclTkLib.get_version\n\n############################################\n# Ttk (Tile) support\n=begin\nif major > 8 || \n    (major == 8 && minor > 5) || \n    (major == 8 && minor == 5 && type >= TclTkLib::RELEASE_TYPE::BETA) \n  # Tcl/Tk 8.5 beta or later\n  Object.autoload :Ttk, 'tkextlib/tile'\n  Tk.autoload :Tile, 'tkextlib/tile'\n\n  require 'tk/ttk_selector'\nend\n=end\nObject.autoload :Ttk, 'tkextlib/tile'\nTk.autoload :Tile, 'tkextlib/tile'\nrequire 'tk/ttk_selector'\n"
  },
  {
    "path": "ext/tk/lib/tk/bgerror.rb",
    "content": "#\n#  tkbgerror -- bgerror ( tkerror ) module\n#                     1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\nrequire 'tk'\n\nmodule TkBgError\n  extend Tk\n\n  TkCommandNames = ['bgerror'.freeze].freeze\n\n  def bgerror(message)\n    tk_call('bgerror', message)\n  end\n  alias tkerror bgerror\n  alias show bgerror\n  module_function :bgerror, :tkerror, :show\n\n  def set_handler(hdlr = Proc.new) #==> handler :: proc{|msg| ...body... }\n    tk_call('proc', 'bgerror', 'msg', install_cmd(hdlr) + ' $msg')\n  end\n  def set_default\n    begin\n      tk_call('rename', 'bgerror', '')\n    rescue RuntimeError\n    end\n  end\n  module_function :set_handler, :set_default\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/bindtag.rb",
    "content": "#\n# tk/bind.rb : control event binding\n#\nrequire 'tk'\n\nclass TkBindTag\n  include TkBindCore\n\n  #BTagID_TBL = {}\n  BTagID_TBL = TkCore::INTERP.create_table\n\n  (Tk_BINDTAG_ID = [\"btag\".freeze, \"00000\".taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    BTagID_TBL.mutex.synchronize{ BTagID_TBL.clear }\n  }\n\n  def TkBindTag.id2obj(id)\n    BTagID_TBL.mutex.synchronize{\n      (BTagID_TBL[id])? BTagID_TBL[id]: id\n    }\n  end\n\n=begin\n  def TkBindTag.new_by_name(name, *args, &b)\n    BTagID_TBL.mutex.synchronize{\n      return BTagID_TBL[name] if BTagID_TBL[name]\n    }\n\n    self.new.instance_eval{\n      BTagID_TBL.mutex.synchronize{\n        BTagID_TBL.delete @id\n        @id = name\n        BTagID_TBL[@id] = self\n      }\n      bind(*args, &b) if args != []\n      self\n    }\n  end\n=end\n  def TkBindTag.new_by_name(name, *args, &b)\n    obj = nil\n    BTagID_TBL.mutex.synchronize{\n      if BTagID_TBL[name]\n        obj = BTagID_TBL[name]\n      else\n        (obj = BTagID_TBL[name] = self.allocate).instance_eval{\n          @id = name\n        }\n      end\n    }\n    bind(*args, &b) if obj && args != []\n    obj\n  end\n\n  def initialize(*args, &b)\n    Tk_BINDTAG_ID.mutex.synchronize{\n      # @id = Tk_BINDTAG_ID.join('')\n      @id = Tk_BINDTAG_ID.join(TkCore::INTERP._ip_id_)\n      Tk_BINDTAG_ID[1].succ!\n    }\n    BTagID_TBL.mutex.synchronize{\n      BTagID_TBL[@id] = self\n    }\n    bind(*args, &b) if args != []\n  end\n\n  ALL = self.new_by_name('all')\n\n  def name\n    @id\n  end\n\n  def to_eval\n    @id\n  end\n\n  def inspect\n    #Kernel.format \"#<TkBindTag: %s>\", @id\n    '#<TkBindTag: ' + @id + '>'\n  end\nend\n\n\nclass TkBindTagAll<TkBindTag\n  def TkBindTagAll.new(*args, &b)\n    $stderr.puts \"Warning: TkBindTagALL is obsolete. Use TkBindTag::ALL\\n\"\n\n    TkBindTag::ALL.bind(*args, &b) if args != []\n    TkBindTag::ALL\n  end\nend\n\n\nclass TkDatabaseClass<TkBindTag\n=begin\n  def self.new(name, *args, &b)\n    BTagID_TBL.mutex.synchronize{\n      return BTagID_TBL[name] if BTagID_TBL[name]\n    }\n    super(name, *args, &b)\n  end\n\n  def initialize(name, *args, &b)\n    @id = name\n    BTagID_TBL.mutex.synchronize{\n      BTagID_TBL[@id] = self\n    }\n    bind(*args, &b) if args != []\n  end\n=end\n  def self.new(name, *args, &b)\n    BTagID_TBL.mutex.synchronize{\n      if BTagID_TBL[name]\n        BTagID_TBL[name]\n      else\n        BTagID_TBL[name] = self.allocate.instance_eval{\n          initialize(name, *args, &b)\n          self\n        }\n      end\n    }\n  end\n\n  def initialize(name, *args, &b)\n    @id = name\n    bind(*args, &b) if args != []\n  end\n\n  def inspect\n    #Kernel.format \"#<TkDatabaseClass: %s>\", @id\n    '#<TkDatabaseClass: ' + @id + '>'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/button.rb",
    "content": "#\n# tk/button.rb : treat button widget\n#\nrequire 'tk'\nrequire 'tk/label'\n\nclass Tk::Button<Tk::Label\n  TkCommandNames = ['button'.freeze].freeze\n  WidgetClassName = 'Button'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('button', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('button', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def invoke\n    _fromUTF8(tk_send_without_enc('invoke'))\n  end\n  def flash\n    tk_send_without_enc('flash')\n    self\n  end\nend\n\n#TkButton = Tk::Button unless Object.const_defined? :TkButton\nTk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)\n"
  },
  {
    "path": "ext/tk/lib/tk/canvas.rb",
    "content": "#\n#               tk/canvas.rb - Tk canvas classes\n#                       by Yukihiro Matsumoto <matz@caelum.co.jp>\n#\nrequire 'tk'\nrequire 'tk/canvastag'\nrequire 'tk/itemconfig'\nrequire 'tk/scrollable'\n\nmodule TkCanvasItemConfig\n  include TkItemConfigMethod\n\n  def __item_strval_optkeys(id)\n    # maybe need to override\n    super(id) + [\n      'fill', 'activefill', 'disabledfill', \n      'outline', 'activeoutline', 'disabledoutline'\n    ]\n  end\n  private :__item_strval_optkeys\n\n  def __item_methodcall_optkeys(id)\n    {'coords'=>'coords'}\n  end\n  private :__item_methodcall_optkeys\n\n  def __item_val2ruby_optkeys(id)  # { key=>proc, ... }\n    super(id).update('window'=>proc{|i, v| window(v)})\n  end\n  private :__item_val2ruby_optkeys\n\n  def __item_pathname(tagOrId)\n    if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag)\n      self.path + ';' + tagOrId.id.to_s\n    else\n      self.path + ';' + tagOrId.to_s\n    end\n  end\n  private :__item_pathname\nend\n\nclass Tk::Canvas<TkWindow\n  include TkCanvasItemConfig\n  include Tk::Scrollable\n\n  TkCommandNames = ['canvas'.freeze].freeze\n  WidgetClassName = 'Canvas'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __destroy_hook__\n    TkcItem::CItemID_TBL.delete(@path)\n  end\n\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('canvas', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('canvas', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def __numval_optkeys\n    super() + ['closeenough']\n  end\n  private :__numval_optkeys\n\n  def __boolval_optkeys\n    super() + ['confine']\n  end\n  private :__boolval_optkeys\n\n  def tagid(tag)\n    if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag)\n      tag.id\n    else\n      tag  # maybe an Array of configure paramters\n    end\n  end\n  private :tagid\n\n\n  # create a canvas item without creating a TkcItem object\n  def create(type, *args)\n    type.create(self, *args)\n  end\n\n\n  def addtag(tag, mode, *args)\n    mode = mode.to_s\n    if args[0] && mode =~ /^(above|below|with(tag)?)$/\n      args[0] = tagid(args[0])\n    end\n    tk_send_without_enc('addtag', tagid(tag), mode, *args)\n    self\n  end\n  def addtag_above(tagOrId, target)\n    addtag(tagOrId, 'above', tagid(target))\n  end\n  def addtag_all(tagOrId)\n    addtag(tagOrId, 'all')\n  end\n  def addtag_below(tagOrId, target)\n    addtag(tagOrId, 'below', tagid(target))\n  end\n  def addtag_closest(tagOrId, x, y, halo=None, start=None)\n    addtag(tagOrId, 'closest', x, y, halo, start)\n  end\n  def addtag_enclosed(tagOrId, x1, y1, x2, y2)\n    addtag(tagOrId, 'enclosed', x1, y1, x2, y2)\n  end\n  def addtag_overlapping(tagOrId, x1, y1, x2, y2)\n    addtag(tagOrId, 'overlapping', x1, y1, x2, y2)\n  end\n  def addtag_withtag(tagOrId, tag)\n    addtag(tagOrId, 'withtag', tagid(tag))\n  end\n\n  def bbox(tagOrId, *tags)\n    list(tk_send_without_enc('bbox', tagid(tagOrId), \n                             *tags.collect{|t| tagid(t)}))\n  end\n\n  #def itembind(tag, context, cmd=Proc.new, *args)\n  #  _bind([path, \"bind\", tagid(tag)], context, cmd, *args)\n  #  self\n  #end\n  def itembind(tag, context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([path, \"bind\", tagid(tag)], context, cmd, *args)\n    self\n  end\n\n  #def itembind_append(tag, context, cmd=Proc.new, *args)\n  #  _bind_append([path, \"bind\", tagid(tag)], context, cmd, *args)\n  #  self\n  #end\n  def itembind_append(tag, context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([path, \"bind\", tagid(tag)], context, cmd, *args)\n    self\n  end\n\n  def itembind_remove(tag, context)\n    _bind_remove([path, \"bind\", tagid(tag)], context)\n    self\n  end\n\n  def itembindinfo(tag, context=nil)\n    _bindinfo([path, \"bind\", tagid(tag)], context)\n  end\n\n  def canvasx(screen_x, *args)\n    #tk_tcl2ruby(tk_send_without_enc('canvasx', screen_x, *args))\n    number(tk_send_without_enc('canvasx', screen_x, *args))\n  end\n  def canvasy(screen_y, *args)\n    #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args))\n    number(tk_send_without_enc('canvasy', screen_y, *args))\n  end\n  alias canvas_x canvasx\n  alias canvas_y canvasy\n\n  def coords(tag, *args)\n    if args == []\n      tk_split_list(tk_send_without_enc('coords', tagid(tag)))\n    else\n      tk_send_without_enc('coords', tagid(tag), *(args.flatten))\n      self\n    end\n  end\n\n  def dchars(tag, first, last=None)\n    tk_send_without_enc('dchars', tagid(tag), \n                        _get_eval_enc_str(first), _get_eval_enc_str(last))\n    self\n  end\n\n  def delete(*args)\n    tbl = nil\n    TkcItem::CItemID_TBL.mutex.synchronize{\n      tbl = TkcItem::CItemID_TBL[self.path]\n    }\n    if tbl\n      args.each{|tag|\n        find('withtag', tag).each{|item|\n          if item.kind_of?(TkcItem)\n            TkcItem::CItemID_TBL.mutex.synchronize{\n              tbl.delete(item.id)\n            }\n          end\n        }\n      }\n    end\n    tk_send_without_enc('delete', *args.collect{|t| tagid(t)})\n    self\n  end\n  alias remove delete\n\n  def dtag(tag, tag_to_del=None)\n    tk_send_without_enc('dtag', tagid(tag), tagid(tag_to_del))\n    self\n  end\n  alias deltag dtag\n\n  def find(mode, *args)\n    list(tk_send_without_enc('find', mode, *args)).collect!{|id| \n      TkcItem.id2obj(self, id)\n    }\n  end\n  def find_above(target)\n    find('above', tagid(target))\n  end\n  def find_all\n    find('all')\n  end\n  def find_below(target)\n    find('below', tagid(target))\n  end\n  def find_closest(x, y, halo=None, start=None)\n    find('closest', x, y, halo, start)\n  end\n  def find_enclosed(x1, y1, x2, y2)\n    find('enclosed', x1, y1, x2, y2)\n  end\n  def find_overlapping(x1, y1, x2, y2)\n    find('overlapping', x1, y1, x2, y2)\n  end\n  def find_withtag(tag)\n    find('withtag', tag)\n  end\n\n  def itemfocus(tagOrId=nil)\n    if tagOrId\n      tk_send_without_enc('focus', tagid(tagOrId))\n      self\n    else\n      ret = tk_send_without_enc('focus')\n      if ret == \"\"\n        nil\n      else\n        TkcItem.id2obj(self, ret)\n      end\n    end\n  end\n\n  def gettags(tagOrId)\n    list(tk_send_without_enc('gettags', tagid(tagOrId))).collect{|tag|\n      TkcTag.id2obj(self, tag)\n    }\n  end\n\n  def icursor(tagOrId, index)\n    tk_send_without_enc('icursor', tagid(tagOrId), index)\n    self\n  end\n\n  def index(tagOrId, idx)\n    number(tk_send_without_enc('index', tagid(tagOrId), idx))\n  end\n\n  def insert(tagOrId, index, string)\n    tk_send_without_enc('insert', tagid(tagOrId), index, \n                        _get_eval_enc_str(string))\n    self\n  end\n\n=begin\n  def itemcget(tagOrId, option)\n    case option.to_s\n    when 'dash', 'activedash', 'disableddash'\n      conf = tk_send_without_enc('itemcget', tagid(tagOrId), \"-#{option}\")\n      if conf =~ /^[0-9]/\n        list(conf)\n      else\n        conf\n      end\n    when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'\n      _fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId), \"-#{option}\"))\n    when 'font', 'kanjifont'\n      #fnt = tk_tcl2ruby(tk_send('itemcget', tagid(tagOrId), \"-#{option}\"))\n      fnt = tk_tcl2ruby(_fromUTF8(tk_send_with_enc('itemcget', tagid(tagOrId), '-font')))\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(tagid(tagOrId), fnt)\n      end\n      if option.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', tagid(tagOrId), \n                                                \"-#{option}\")))\n    end\n  end\n\n  def itemconfigure(tagOrId, key, value=None)\n    if key.kind_of? Hash\n      key = _symbolkey2str(key)\n      coords = key.delete('coords')\n      self.coords(tagOrId, coords) if coords\n\n      if ( key['font'] || key['kanjifont'] \\\n          || key['latinfont'] || key['asciifont'] )\n        tagfont_configure(tagid(tagOrId), key.dup)\n      else\n        _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), \n                                      *hash_kv(key, true)))\n      end\n\n    else\n      if ( key == 'coords' || key == :coords )\n        self.coords(tagOrId, value)\n      elsif ( key == 'font' || key == :font || \n              key == 'kanjifont' || key == :kanjifont || \n              key == 'latinfont' || key == :latinfont || \n              key == 'asciifont' || key == :asciifont )\n        if value == None\n          tagfontobj(tagid(tagOrId))\n        else\n          tagfont_configure(tagid(tagOrId), {key=>value})\n        end\n      else\n        _fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), \n                                      \"-#{key}\", _get_eval_enc_str(value)))\n      end\n    end\n    self\n  end\n#  def itemconfigure(tagOrId, key, value=None)\n#    if key.kind_of? Hash\n#      tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)\n#    else\n#      tk_send 'itemconfigure', tagid(tagOrId), \"-#{key}\", value\n#    end\n#  end\n#  def itemconfigure(tagOrId, keys)\n#    tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys)\n#  end\n\n  def itemconfiginfo(tagOrId, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'coords'\n          return ['coords', '', '', '', self.coords(tagOrId)]\n        when 'dash', 'activedash', 'disableddash'\n          conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', tagid(tagOrId), \"-#{key}\"))\n          if conf[3] && conf[3] =~ /^[0-9]/\n            conf[3] = list(conf[3])\n          end\n          if conf[4] && conf[4] =~ /^[0-9]/\n            conf[4] = list(conf[4])\n          end\n        when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), \"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),\"-#{key}\")))\n          conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), \"-#{key}\")))\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).collect{|conflist|\n          conf = tk_split_simplelist(conflist)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'\n          when 'dash', 'activedash', 'disableddash'\n            if conf[3] && conf[3] =~ /^[0-9]/\n              conf[3] = list(conf[3])\n            end\n            if conf[4] && conf[4] =~ /^[0-9]/\n              conf[4] = list(conf[4])\n            end\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n\n        fontconf = ret.assoc('font')\n        if fontconf\n          ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}\n          fontconf[4] = tagfont_configinfo(tagid(tagOrId), fontconf[4])\n          ret.push(fontconf)\n        end\n\n        ret << ['coords', '', '', '', self.coords(tagOrId)]\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'coords'\n          {'coords' => ['', '', '', self.coords(tagOrId)]}\n        when 'dash', 'activedash', 'disableddash'\n          conf = tk_split_simplelist(tk_send_without_enc('itemconfigure', \n                                                         tagid(tagOrId), \n                                                         \"-#{key}\"))\n          if conf[3] && conf[3] =~ /^[0-9]/\n            conf[3] = list(conf[3])\n          end\n          if conf[4] && conf[4] =~ /^[0-9]/\n            conf[4] = list(conf[4])\n          end\n        when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), \"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId),\"-#{key}\")))\n          conf[4] = tagfont_configinfo(tagid(tagOrId), conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId), \"-#{key}\")))\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', tagid(tagOrId)))).each{|conflist|\n          conf = tk_split_simplelist(conflist)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile'\n          when 'dash', 'activedash', 'disableddash'\n            if conf[2] && conf[2] =~ /^[0-9]/\n              conf[2] = list(conf[2])\n            end\n            if conf[3] && conf[3] =~ /^[0-9]/\n              conf[3] = list(conf[3])\n            end\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n\n        fontconf = ret['font']\n        if fontconf\n          ret.delete('font')\n          ret.delete('kanjifont')\n          fontconf[3] = tagfont_configinfo(tagid(tagOrId), fontconf[3])\n          ret['font'] = fontconf\n        end\n\n        ret['coords'] = ['', '', '', self.coords(tagOrId)]\n\n        ret\n      end\n    end\n  end\n\n  def current_itemconfiginfo(tagOrId, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        conf = itemconfiginfo(tagOrId, key)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        itemconfiginfo(tagOrId).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      itemconfiginfo(tagOrId, key).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n=end\n\n  def lower(tag, below=nil)\n    if below\n      tk_send_without_enc('lower', tagid(tag), tagid(below))\n    else\n      tk_send_without_enc('lower', tagid(tag))\n    end\n    self\n  end\n\n  def move(tag, x, y)\n    tk_send_without_enc('move', tagid(tag), x, y)\n    self\n  end\n\n  def postscript(keys)\n    tk_send(\"postscript\", *hash_kv(keys))\n  end\n\n  def raise(tag, above=nil)\n    if above\n      tk_send_without_enc('raise', tagid(tag), tagid(above))\n    else\n      tk_send_without_enc('raise', tagid(tag))\n    end\n    self\n  end\n\n  def scale(tag, x, y, xs, ys)\n    tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)\n    self\n  end\n\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y, gain=None)\n    tk_send_without_enc('scan', 'dragto', x, y, gain)\n    self\n  end\n\n  def select(mode, *args)\n    r = tk_send_without_enc('select', mode, *args)\n    (mode == 'item')? TkcItem.id2obj(self, r): self\n  end\n  def select_adjust(tagOrId, index)\n    select('adjust', tagid(tagOrId), index)\n  end\n  def select_clear\n    select('clear')\n  end\n  def select_from(tagOrId, index)\n    select('from', tagid(tagOrId), index)\n  end\n  def select_item\n    select('item')\n  end\n  def select_to(tagOrId, index)\n    select('to', tagid(tagOrId), index)\n  end\n\n  def itemtype(tag)\n    TkcItem.type2class(tk_send('type', tagid(tag)))\n  end\nend\n\n#TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas\nTk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)\n\n\nclass TkcItem<TkObject\n  extend Tk\n  include TkcTagAccess\n  extend TkItemFontOptkeys\n  extend TkItemConfigOptkeys\n\n  CItemTypeName = nil\n  CItemTypeToClass = {}\n\n  CItemID_TBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    CItemID_TBL.mutex.synchronize{ CItemID_TBL.clear }\n  }\n\n  def TkcItem.type2class(type)\n    CItemTypeToClass[type]\n  end\n\n  def TkcItem.id2obj(canvas, id)\n    cpath = canvas.path\n    CItemID_TBL.mutex.synchronize{\n      if CItemID_TBL[cpath]\n        CItemID_TBL[cpath][id]? CItemID_TBL[cpath][id]: id\n      else\n        id\n      end\n    }\n  end\n\n  ########################################\n  def self._parse_create_args(args)\n    fontkeys = {}\n    methodkeys = {}\n    if args[-1].kind_of? Hash\n      keys = _symbolkey2str(args.pop)\n      if args.size == 0\n        args = keys.delete('coords')\n        unless args.kind_of?(Array)\n          fail \"coords parameter must be given by an Array\"\n        end\n      end\n\n      #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|\n      #  fontkeys[key] = keys.delete(key) if keys.key?(key)\n      #}\n      __item_font_optkeys(nil).each{|key|\n        fkey = key.to_s\n        fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n        fkey = \"kanji#{key}\"\n        fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n        fkey = \"latin#{key}\"\n        fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n        fkey = \"ascii#{key}\"\n        fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n      }\n\n      __item_optkey_aliases(nil).each{|alias_name, real_name|\n        alias_name = alias_name.to_s\n        if keys.has_key?(alias_name)\n          keys[real_name.to_s] = keys.delete(alias_name)\n        end\n      }\n\n      __item_methodcall_optkeys(nil).each{|key|\n        key = key.to_s\n        methodkeys[key] = keys.delete(key) if keys.key?(key)\n      }\n\n      __item_ruby2val_optkeys(nil).each{|key, method|\n        key = key.to_s\n        keys[key] = method.call(keys[key]) if keys.has_key?(key)\n      }\n\n      #args = args.flatten.concat(hash_kv(keys))\n      args = args.flatten.concat(itemconfig_hash_kv(nil, keys))\n    else\n      args = args.flatten\n    end\n\n    [args, fontkeys]\n  end\n  private_class_method :_parse_create_args\n\n  def self.create(canvas, *args)\n    unless self::CItemTypeName\n      fail RuntimeError, \"#{self} is an abstract class\"\n    end\n    args, fontkeys = _parse_create_args(args)\n    idnum = tk_call_without_enc(canvas.path, 'create', \n                                self::CItemTypeName, *args)\n    canvas.itemconfigure(idnum, fontkeys) unless fontkeys.empty?\n    idnum.to_i  # 'canvas item id' is an integer number\n  end\n  ########################################\n\n  def initialize(parent, *args)\n    #unless parent.kind_of?(Tk::Canvas)\n    #  fail ArgumentError, \"expect Tk::Canvas for 1st argument\"\n    #end\n    @parent = @c = parent\n    @path = parent.path\n\n    @id = create_self(*args) # an integer number as 'canvas item id'\n    CItemID_TBL.mutex.synchronize{\n      CItemID_TBL[@path] = {} unless CItemID_TBL[@path]\n      CItemID_TBL[@path][@id] = self\n    }\n  end\n  def create_self(*args)\n    self.class.create(@c, *args) # return an integer number as 'canvas item id'\n  end\n  private :create_self\n\n  def id\n    @id\n  end\n\n  def exist?\n    if @c.find_withtag(@id)\n      true\n    else\n      false\n    end\n  end\n\n  def delete\n    @c.delete @id\n    CItemID_TBL.mutex.synchronize{\n      CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]\n    }\n    self\n  end\n  alias remove  delete\n  alias destroy delete\nend\n\nclass TkcArc<TkcItem\n  CItemTypeName = 'arc'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcBitmap<TkcItem\n  CItemTypeName = 'bitmap'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcImage<TkcItem\n  CItemTypeName = 'image'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcLine<TkcItem\n  CItemTypeName = 'line'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcOval<TkcItem\n  CItemTypeName = 'oval'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcPolygon<TkcItem\n  CItemTypeName = 'polygon'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcRectangle<TkcItem\n  CItemTypeName = 'rectangle'.freeze\n  CItemTypeToClass[CItemTypeName] = self\nend\n\nclass TkcText<TkcItem\n  CItemTypeName = 'text'.freeze\n  CItemTypeToClass[CItemTypeName] = self\n  def self.create(canvas, *args)\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n      txt = keys['text']\n      keys['text'] = _get_eval_enc_str(txt) if txt\n      args.push(keys)\n    end\n    super(canvas, *args)\n  end\nend\n\nclass TkcWindow<TkcItem\n  CItemTypeName = 'window'.freeze\n  CItemTypeToClass[CItemTypeName] = self\n  def self.create(canvas, *args)\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n      win = keys['window']\n      # keys['window'] = win.epath if win.kind_of?(TkWindow)\n      keys['window'] = _epath(win) if win\n      args.push(keys)\n    end\n    super(canvas, *args)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/canvastag.rb",
    "content": "#\n# tk/canvastag.rb - methods for treating canvas tags\n#\nrequire 'tk'\nrequire 'tk/tagfont'\n\nmodule TkcTagAccess\n  include TkComm\n  include TkTreatTagFont\nend\n\nrequire 'tk/canvas'\n\nmodule TkcTagAccess\n  def addtag(tag)\n    @c.addtag(tag, 'withtag', @id)\n    self\n  end\n\n  def bbox\n    @c.bbox(@id)\n  end\n\n  #def bind(seq, cmd=Proc.new, *args)\n  #  @c.itembind(@id, seq, cmd, *args)\n  #  self\n  #end\n  def bind(seq, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    @c.itembind(@id, seq, cmd, *args)\n    self\n  end\n\n  #def bind_append(seq, cmd=Proc.new, *args)\n  #  @c.itembind_append(@id, seq, cmd, *args)\n  #  self\n  #end\n  def bind_append(seq, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    @c.itembind_append(@id, seq, cmd, *args)\n    self\n  end\n\n  def bind_remove(seq)\n    @c.itembind_remove(@id, seq)\n    self\n  end\n\n  def bindinfo(seq=nil)\n    @c.itembindinfo(@id, seq)\n  end\n\n  def cget(option)\n    @c.itemcget(@id, option)\n  end\n  def cget_strict(option)\n    @c.itemcget_strict(@id, option)\n  end\n\n  def configure(key, value=None)\n    @c.itemconfigure(@id, key, value)\n    self\n  end\n#  def configure(keys)\n#    @c.itemconfigure @id, keys\n#  end\n\n  def configinfo(key=nil)\n    @c.itemconfiginfo(@id, key)\n  end\n\n  def current_configinfo(key=nil)\n    @c.current_itemconfiginfo(@id, key)\n  end\n\n  def coords(*args)\n    @c.coords(@id, *args)\n  end\n\n  def dchars(first, last=None)\n    @c.dchars(@id, first, last)\n    self\n  end\n\n  def dtag(tag_to_del=None)\n    @c.dtag(@id, tag_to_del)\n    self\n  end\n  alias deltag dtag\n\n  def find\n    @c.find('withtag', @id)\n  end\n  alias list find\n\n  def focus\n    @c.itemfocus(@id)\n  end\n\n  def gettags\n    @c.gettags(@id)\n  end\n\n  def icursor(index)\n    @c.icursor(@id, index)\n    self\n  end\n\n  def index(idx)\n    @c.index(@id, idx)\n  end\n\n  def insert(beforethis, string)\n    @c.insert(@id, beforethis, string)\n    self\n  end\n\n  def lower(belowthis=None)\n    @c.lower(@id, belowthis)\n    self\n  end\n\n  def move(xamount, yamount)\n    @c.move(@id, xamount, yamount)\n    self\n  end\n\n  def raise(abovethis=None)\n    @c.raise(@id, abovethis)\n    self\n  end\n\n  def scale(xorigin, yorigin, xscale, yscale)\n    @c.scale(@id, xorigin, yorigin, xscale, yscale)\n    self\n  end\n\n  def select_adjust(index)\n    @c.select('adjust', @id, index)\n    self\n  end\n  def select_from(index)\n    @c.select('from', @id, index)\n    self\n  end\n  def select_to(index)\n    @c.select('to', @id, index)\n    self\n  end\n\n  def itemtype\n    @c.itemtype(@id)\n  end\n\n  # Following operators support logical expressions of canvas tags\n  # (for Tk8.3+).\n  # If tag1.path is 't1' and tag2.path is 't2', then\n  #      ltag = tag1 & tag2; ltag.path => \"(t1)&&(t2)\"\n  #      ltag = tag1 | tag2; ltag.path => \"(t1)||(t2)\"\n  #      ltag = tag1 ^ tag2; ltag.path => \"(t1)^(t2)\"\n  #      ltag = - tag1;      ltag.path => \"!(t1)\"\n  def & (tag)\n    if tag.kind_of? TkObject\n      TkcTagString.new(@c, '(' + @id + ')&&(' + tag.path + ')')\n    else\n      TkcTagString.new(@c, '(' + @id + ')&&(' + tag.to_s + ')')\n    end\n  end\n\n  def | (tag)\n    if tag.kind_of? TkObject\n      TkcTagString.new(@c, '(' + @id + ')||(' + tag.path + ')')\n    else\n      TkcTagString.new(@c, '(' + @id + ')||(' + tag.to_s + ')')\n    end\n  end\n\n  def ^ (tag)\n    if tag.kind_of? TkObject\n      TkcTagString.new(@c, '(' + @id + ')^(' + tag.path + ')')\n    else\n      TkcTagString.new(@c, '(' + @id + ')^(' + tag.to_s + ')')\n    end\n  end\n\n  def -@\n    TkcTagString.new(@c, '!(' + @id + ')')\n  end\nend\n\nclass TkcTag<TkObject\n  include TkcTagAccess\n\n  CTagID_TBL = TkCore::INTERP.create_table\n\n  (Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    CTagID_TBL.mutex.synchronize{ CTagID_TBL.clear }\n  }\n\n  def TkcTag.id2obj(canvas, id)\n    cpath = canvas.path\n    CTagID_TBL.mutex.synchronize{\n      if CTagID_TBL[cpath]\n        CTagID_TBL[cpath][id]? CTagID_TBL[cpath][id]: id\n      else \n        id\n      end\n    }\n  end\n\n  def initialize(parent, mode=nil, *args)\n    #unless parent.kind_of?(TkCanvas)\n    #  fail ArgumentError, \"expect TkCanvas for 1st argument\"\n    #end\n    @c = parent\n    @cpath = parent.path\n    Tk_CanvasTag_ID.mutex.synchronize{\n      # @path = @id = Tk_CanvasTag_ID.join('')\n      @path = @id = Tk_CanvasTag_ID.join(TkCore::INTERP._ip_id_)\n      Tk_CanvasTag_ID[1].succ!\n    }\n    CTagID_TBL.mutex.synchronize{\n      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]\n      CTagID_TBL[@cpath][@id] = self\n    }\n    if mode\n      tk_call_without_enc(@c.path, \"addtag\", @id, mode, *args)\n    end\n  end\n  def id\n    @id\n  end\n\n  def exist?\n    if @c.find_withtag(@id)\n      true\n    else\n      false\n    end\n  end\n\n  def delete\n    @c.delete @id\n    CTagID_TBL.mutex.synchronize{\n      CTagID_TBL[@cpath].delete(@id) if CTagID_TBL[@cpath]\n    }\n    self\n  end\n  alias remove  delete\n  alias destroy delete\n\n  def set_to_above(target)\n    @c.addtag_above(@id, target)\n    self\n  end\n  alias above set_to_above\n\n  def set_to_all\n    @c.addtag_all(@id)\n    self\n  end\n  alias all set_to_all\n\n  def set_to_below(target)\n    @c.addtag_below(@id, target)\n    self\n  end\n  alias below set_to_below\n\n  def set_to_closest(x, y, halo=None, start=None)\n    @c.addtag_closest(@id, x, y, halo, start)\n    self\n  end\n  alias closest set_to_closest\n\n  def set_to_enclosed(x1, y1, x2, y2)\n    @c.addtag_enclosed(@id, x1, y1, x2, y2)\n    self\n  end\n  alias enclosed set_to_enclosed\n\n  def set_to_overlapping(x1, y1, x2, y2)\n    @c.addtag_overlapping(@id, x1, y1, x2, y2)\n    self\n  end\n  alias overlapping set_to_overlapping\n\n  def set_to_withtag(target)\n    @c.addtag_withtag(@id, target)\n    self\n  end\n  alias withtag set_to_withtag\nend\n\nclass TkcTagString<TkcTag\n  def self.new(parent, name, mode=nil, *args)\n    obj = nil\n    CTagID_TBL.mutex.synchronize{\n      if CTagID_TBL[parent.path] && CTagID_TBL[parent.path][name]\n        obj = CTagID_TBL[parent.path][name]\n      else\n        # super(parent, name, *args)\n        (obj = self.allocate).instance_eval{\n          @c = parent\n          @cpath = parent.path\n          @path = @id = name\n          CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]\n          CTagID_TBL[@cpath][@id] = self\n        }\n      end\n    }\n    if obj && mode\n      tk_call_without_enc(@c.path, \"addtag\", @id, mode, *args)\n    end\n    obj\n  end\n\n  def initialize(parent, name, mode=nil, *args)\n    # dummy:: not called by 'new' method\n\n    #unless parent.kind_of?(TkCanvas)\n    #  fail ArgumentError, \"expect TkCanvas for 1st argument\"\n    #end\n    @c = parent\n    @cpath = parent.path\n    @path = @id = name\n\n    if mode\n      tk_call_without_enc(@c.path, \"addtag\", @id, mode, *args)\n    end\n  end\nend\nTkcNamedTag = TkcTagString\n\nclass TkcTagAll<TkcTagString\n  def self.new(parent)\n    super(parent, 'all')\n  end\n=begin\n  def initialize(parent)\n    #unless parent.kind_of?(TkCanvas)\n    #  fail ArgumentError, \"expect TkCanvas for 1st argument\"\n    #end\n    @c = parent\n    @cpath = parent.path\n    @path = @id = 'all'\n    CTagID_TBL.mutex.synchronize{\n      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]\n      CTagID_TBL[@cpath][@id] = self\n    }\n  end\n=end\nend\n\nclass TkcTagCurrent<TkcTagString\n  def self.new(parent)\n    super(parent, 'current')\n  end\n=begin\n  def initialize(parent)\n    #unless parent.kind_of?(TkCanvas)\n    #  fail ArgumentError, \"expect TkCanvas for 1st argument\"\n    #end\n    @c = parent\n    @cpath = parent.path\n    @path = @id = 'current'\n    CTagID_TBL.mutex.synchronize{\n      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]\n      CTagID_TBL[@cpath][@id] = self\n    }\n  end\n=end\nend\n\nclass TkcGroup<TkcTag\n  (Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  #def create_self(parent, *args)\n  def initialize(parent, *args)\n    #unless parent.kind_of?(TkCanvas)\n    #  fail ArgumentError, \"expect TkCanvas for 1st argument\"\n    #end\n    @c = parent\n    @cpath = parent.path\n    Tk_cGroup_ID.mutex.synchronize{\n      # @path = @id = Tk_cGroup_ID.join('')\n      @path = @id = Tk_cGroup_ID.join(TkCore::INTERP._ip_id_)\n      Tk_cGroup_ID[1].succ!\n    }\n    CTagID_TBL.mutex.synchronize{\n      CTagID_TBL[@cpath] = {} unless CTagID_TBL[@cpath]\n      CTagID_TBL[@cpath][@id] = self\n    }\n    include(*args) if args != []\n  end\n  #private :create_self\n  \n  def include(*tags)\n    for i in tags\n      #i.addtag(@id)\n      @c.addtag_withtag(@id, i)\n    end\n    self\n  end\n  alias add include\n\n  def exclude(*tags)\n    for i in tags\n      #i.dtag(@id)\n      @c.dtag(i, @id)\n    end\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/checkbutton.rb",
    "content": "#\n# tk/checkbutton.rb : treat checkbutton widget\n#\nrequire 'tk'\nrequire 'tk/radiobutton'\n\nclass Tk::CheckButton<Tk::RadioButton\n  TkCommandNames = ['checkbutton'.freeze].freeze\n  WidgetClassName = 'Checkbutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('checkbutton', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def toggle\n    tk_send_without_enc('toggle')\n    self\n  end\nend\n\nTk::Checkbutton = Tk::CheckButton\n#TkCheckButton = Tk::CheckButton unless Object.const_defined? :TkCheckButton\n#TkCheckbutton = Tk::Checkbutton unless Object.const_defined? :TkCheckbutton\nTk.__set_toplevel_aliases__(:Tk, Tk::CheckButton, \n                            :TkCheckButton, :TkCheckbutton)\n"
  },
  {
    "path": "ext/tk/lib/tk/clipboard.rb",
    "content": "#\n# tk/clipboard.rb : methods to treat clipboard\n#\nrequire 'tk'\n\nmodule TkClipboard\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['clipboard'.freeze].freeze\n\n  def self.clear(win=nil)\n    if win\n      tk_call_without_enc('clipboard', 'clear', '-displayof', win)\n    else\n      tk_call_without_enc('clipboard', 'clear')\n    end\n  end\n  def self.clear_on_display(win)\n    tk_call_without_enc('clipboard', 'clear', '-displayof', win)\n  end\n\n  def self.get(type=nil)\n    if type\n      tk_call_without_enc('clipboard', 'get', '-type', type)\n    else\n      tk_call_without_enc('clipboard', 'get')\n    end\n  end\n  def self.get_on_display(win, type=nil)\n    if type\n      tk_call_without_enc('clipboard', 'get', '-displayof', win, '-type', type)\n    else\n      tk_call_without_enc('clipboard', 'get', '-displayof', win)\n    end\n  end\n\n  def self.set(data, keys=nil)\n    clear\n    append(data, keys)\n  end\n  def self.set_on_display(win, data, keys=nil)\n    clear(win)\n    append_on_display(win, data, keys)\n  end\n\n  def self.append(data, keys=nil)\n    args = ['clipboard', 'append']\n    args.concat(hash_kv(keys))\n    args.concat(['--', data])\n    tk_call(*args)\n  end\n  def self.append_on_display(win, data, keys=nil)\n    args = ['clipboard', 'append', '-displayof', win]\n    args.concat(hash_kv(keys))\n    args.concat(['--', data])\n    tk_call(*args)\n  end\n\n  def clear\n    TkClipboard.clear_on_display(self)\n    self\n  end\n  def get(type=nil)\n    TkClipboard.get_on_display(self, type)\n  end\n  def set(data, keys=nil)\n    TkClipboard.set_on_display(self, data, keys)\n    self\n  end\n  def append(data, keys=nil)\n    TkClipboard.append_on_display(self, data, keys)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/clock.rb",
    "content": "#\n# tk/clock.rb : methods for clock command\n#\nrequire 'tk'\n\nmodule Tk\n  module Clock\n    include Tk\n    extend TkCore\n\n    def self.add(clk, *args)\n      tk_call_without_enc('clock','add', clk, *args).to_i\n    end\n\n    def self.clicks(ms=nil)\n      ms = ms.to_s if ms.kind_of?(Symbol)\n      case ms\n      when nil, ''\n        tk_call_without_enc('clock','clicks').to_i\n      when /^mic/\n        tk_call_without_enc('clock','clicks','-microseconds').to_i\n      when /^mil/\n        tk_call_without_enc('clock','clicks','-milliseconds').to_i\n      else\n        tk_call_without_enc('clock','clicks','-milliseconds').to_i\n      end\n    end\n\n    def self.format(clk, form=nil)\n      if form\n        tk_call('clock','format',clk,'-format',form)\n      else\n        tk_call('clock','format',clk)\n      end\n    end\n\n    def self.formatGMT(clk, form=nil)\n      if form\n        tk_call('clock','format',clk,'-format',form,'-gmt','1')\n      else\n        tk_call('clock','format',clk,'-gmt','1')\n      end\n    end\n\n    def self.scan(str, base=nil)\n      if base\n        tk_call('clock','scan',str,'-base',base).to_i\n      else\n        tk_call('clock','scan',str).to_i\n      end\n    end\n\n    def self.scanGMT(str, base=nil)\n      if base\n        tk_call('clock','scan',str,'-base',base,'-gmt','1').to_i\n      else\n        tk_call('clock','scan',str,'-gmt','1').to_i\n      end\n    end\n\n    def self.seconds\n      tk_call_without_enc('clock','seconds').to_i\n    end\n    def self.milliseconds\n      tk_call_without_enc('clock','milliseconds').to_i\n    end\n    def self.microseconds\n      tk_call_without_enc('clock','microseconds').to_i\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/composite.rb",
    "content": "#\n# tk/composite.rb : \n#\nrequire 'tk'\n\nmodule TkComposite\n  include Tk\n  extend Tk\n\n=begin\n  def initialize(parent=nil, *args)\n    @delegates = {}\n    @option_methods = {}\n    @option_setting = {}\n\n    if parent.kind_of? Hash\n      keys = _symbolkey2str(parent)\n      parent = keys.delete('parent')\n      @frame = TkFrame.new(parent)\n      @path = @epath = @frame.path\n      initialize_composite(keys)\n    else\n      @frame = TkFrame.new(parent)\n      @path = @epath = @frame.path\n      initialize_composite(*args)\n    end\n  end\n=end\n\n  def _choice_classname_of_baseframe\n    base_class_name = nil\n\n    klass = WidgetClassNames[self.class::WidgetClassName]\n\n    if klass\n      # WidgetClassName is a known class\n      #if klass <= TkFrame || klass < TkComposite\n      if klass <= TkFrame || klass < Tk::Frame || klass < TkComposite\n        # klass is valid for the base frame\n        if self.class <= klass\n          # use my classname\n          base_class_name = self.class.name\n          if base_class_name == ''\n            # anonymous class -> use ancestor's name\n            base_class_name = klass.name\n          end\n        else\n          # not subclass -> use WidgetClassName\n          base_class_name = klass.name\n        end\n\n      else\n        # klass is invalid for the base frame\n        #if self.class < TkFrame || self.class.superclass < TkComposite\n        if self.class < TkFrame || self.class.superclass < Tk::Frame || self.class.superclass < TkComposite\n          # my class name is valid for the base frame -> use my classname\n          base_class_name = self.class.name\n          if base_class_name == ''\n            # anonymous class -> use TkFrame\n            base_class_name = nil\n          end\n        else\n          # no idea for the base frame -> use TkFrame\n          base_class_name = nil\n        end\n      end\n\n    elsif self.class::WidgetClassName && ! self.class::WidgetClassName.empty?\n      # unknown WidgetClassName is defined -> use it for the base frame\n      base_class_name = self.class::WidgetClassName\n\n    else\n      # no valid WidgetClassName\n      #if self.class < TkFrame || self.class.superclass < TkComposite\n      if self.class < TkFrame || self.class.superclass < Tk::Frame || self.class.superclass < TkComposite\n        # my class name is valid for the base frame -> use my classname\n        base_class_name = self.class.name\n        if base_class_name == ''\n          # anonymous class -> use TkFrame\n          base_class_name = nil\n        end\n      else\n        # no idea for the base frame -> use TkFrame\n        base_class_name = nil\n      end\n    end\n\n    base_class_name\n  end\n  private :_choice_classname_of_baseframe\n\n  # def initialize(parent=nil, *args)\n  def initialize(*args)\n    @delegates = {}\n    @option_methods = {}\n    @option_setting = {}\n\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n    else\n      keys = {}\n    end\n    parent = args.shift\n    parent = keys.delete('parent') if keys.has_key?('parent')\n\n    if keys.key?('classname')\n      keys['class'] = keys.delete('classname')\n    end\n    if (base_class_name = (keys.delete('class')).to_s).empty?\n      base_class_name = _choice_classname_of_baseframe\n    end\n\n    if base_class_name\n      # @frame = Tk::Frame.new(parent, :class=>base_class_name)\n      # --> use current TkFrame class\n      @frame = TkFrame.new(parent, :class=>base_class_name)\n    else\n      # @frame = Tk::Frame.new(parent)\n      # --> use current TkFrame class\n      @frame = TkFrame.new(parent)\n    end\n    @path = @epath = @frame.path\n\n    args.push(keys) unless keys.empty?\n    initialize_composite(*args)\n  end\n\n  def database_classname\n    @frame.database_classname\n  end\n\n  def database_class\n    @frame.database_class\n  end\n\n  def epath\n    @epath\n  end\n\n  def initialize_composite(*args) end\n  private :initialize_composite\n\n  def inspect\n    str = super\n    str.chop << ' @epath=' << @epath.inspect << '>'\n  end\n\n  def option_methods(*opts)\n    opts.each{|m_set, m_cget, m_info|\n      m_set  = m_set.to_s\n      m_cget = m_set if !m_cget && self.method(m_set).arity == -1\n      m_cget = m_cget.to_s if m_cget\n      m_info = m_info.to_s if m_info\n      @option_methods[m_set] = {\n        :set  => m_set, :cget => m_cget, :info => m_info\n      }\n    }\n  end\n\n  def delegate_alias(alias_opt, option, *wins)\n    if wins.length == 0\n      fail ArgumentError, \"target widgets are not given\"\n    end\n    if alias_opt != option && (alias_opt == 'DEFAULT' || option == 'DEFAULT')\n      fail ArgumentError, \"cannot alias 'DEFAULT' option\"\n    end\n    alias_opt = alias_opt.to_s\n    option = option.to_s\n    if @delegates[alias_opt].kind_of?(Array)\n      if (elem = @delegates[alias_opt].assoc(option))\n        wins.each{|w| elem[1].push(w)}\n      else\n        @delegates[alias_opt] << [option, wins]\n      end\n    else\n      @delegates[alias_opt] = [ [option, wins] ]\n    end\n  end\n\n  def delegate(option, *wins)\n    delegate_alias(option, option, *wins)\n  end\n\n  def __cget_delegates(slot)\n    slot = slot.to_s\n\n    if @option_methods.include?(slot)\n      if @option_methods[slot][:cget]\n        return self.__send__(@option_methods[slot][:cget])\n      else\n        if @option_setting[slot]\n          return @option_setting[slot]\n        else\n          return ''\n        end\n      end\n    end\n\n    tbl = @delegates[slot]\n    tbl = @delegates['DEFAULT'] unless tbl\n\n    begin\n      if tbl\n        opt, wins = tbl[-1]\n        opt = slot if opt == 'DEFAULT'\n        if wins && wins[-1]\n          # return wins[-1].cget(opt)\n          return wins[-1].cget_strict(opt)\n        end\n      end\n    rescue\n    end\n\n    return None\n  end\n  private :__cget_delegates\n\n  def cget(slot)\n    if (ret = __cget_delegates(slot)) == None\n      super(slot)\n    else\n      ret\n    end\n  end\n\n  def cget_strict(slot)\n    if (ret = __cget_delegates(slot)) == None\n      super(slot)\n    else\n      ret\n    end\n  end\n\n=begin\n  def cget(slot)\n    slot = slot.to_s\n\n    if @option_methods.include?(slot)\n      if @option_methods[slot][:cget]\n        return self.__send__(@option_methods[slot][:cget])\n      else\n        if @option_setting[slot]\n          return @option_setting[slot]\n        else\n          return ''\n        end\n      end\n    end\n\n    tbl = @delegates[slot]\n    tbl = @delegates['DEFAULT'] unless tbl\n\n    begin\n      if tbl\n        opt, wins = tbl[-1]\n        opt = slot if opt == 'DEFAULT'\n        if wins && wins[-1]\n          return wins[-1].cget(opt)\n        end\n      end\n    rescue\n    end\n\n    super(slot)\n  end\n=end\n\n  def configure(slot, value=None)\n    if slot.kind_of? Hash\n      slot.each{|slot,value| configure slot, value}\n      return self\n    end\n\n    slot = slot.to_s\n\n    if @option_methods.include?(slot)\n      unless @option_methods[slot][:cget]\n        if value.kind_of?(Symbol)\n          @option_setting[slot] = value.to_s\n        else\n          @option_setting[slot] = value\n        end\n      end\n      return self.__send__(@option_methods[slot][:set], value)\n    end\n\n    tbl = @delegates[slot]\n    tbl = @delegates['DEFAULT'] unless tbl\n\n    begin\n      if tbl\n        last = nil\n        tbl.each{|opt, wins|\n          opt = slot if opt == 'DEFAULT'\n          wins.each{|w| last = w.configure(opt, value)}\n        }\n        return last\n      end\n    rescue\n    end\n\n    super(slot, value)\n  end\n\n  def configinfo(slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        slot = slot.to_s\n        if @option_methods.include?(slot)\n          if @option_methods[slot][:info]\n            return self.__send__(@option_methods[slot][:info])\n          else\n            return [slot, '', '', '', self.cget(slot)]\n          end\n        end\n\n        tbl = @delegates[slot]\n        tbl = @delegates['DEFAULT'] unless tbl\n\n        begin\n          if tbl\n            if tbl.length == 1\n              opt, wins = tbl[0]\n              if slot == opt || opt == 'DEFAULT'\n                return wins[-1].configinfo(slot)\n              else\n                info = wins[-1].configinfo(opt)\n                info[0] = slot\n                return info\n              end\n            else\n              opt, wins = tbl[-1]\n              return [slot, '', '', '', wins[-1].cget(opt)]\n            end\n          end\n        rescue\n        end\n\n        super(slot)\n\n      else # slot == nil\n        info_list = super(slot)\n\n        tbl = @delegates['DEFAULT']\n        if tbl\n          wins = tbl[0][1]\n          if wins && wins[-1]\n            wins[-1].configinfo.each{|info|\n              slot = info[0]\n              info_list.delete_if{|i| i[0] == slot} << info\n            }\n          end\n        end\n\n        @delegates.each{|slot, tbl|\n          next if slot == 'DEFAULT'\n          if tbl.length == 1\n            opt, wins = tbl[0]\n            next unless wins && wins[-1]\n            if slot == opt\n              info_list.delete_if{|i| i[0] == slot} << \n                wins[-1].configinfo(slot)\n            else\n              info = wins[-1].configinfo(opt)\n              info[0] = slot\n              info_list.delete_if{|i| i[0] == slot} << info\n            end\n          else\n            opt, wins = tbl[-1]\n            info_list.delete_if{|i| i[0] == slot} << \n              [slot, '', '', '', wins[-1].cget(opt)]\n          end\n        }\n\n        @option_methods.each{|slot, m|\n          if m[:info]\n            info = self.__send__(m[:info])\n          else\n            info = [slot, '', '', '', self.cget(slot)]\n          end\n          info_list.delete_if{|i| i[0] == slot} << info\n        }\n\n        info_list\n      end\n\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        slot = slot.to_s\n        if @option_methods.include?(slot)\n          if @option_methods[slot][:info]\n            return self.__send__(@option_methods[slot][:info])\n          else\n            return {slot => ['', '', '', self.cget(slot)]}\n          end\n        end\n\n        tbl = @delegates[slot]\n        tbl = @delegates['DEFAULT'] unless tbl\n\n        begin\n          if tbl\n            if tbl.length == 1\n              opt, wins = tbl[0]\n              if slot == opt || opt == 'DEFAULT'\n                return wins[-1].configinfo(slot)\n              else\n                return {slot => wins[-1].configinfo(opt)[opt]}\n              end\n            else\n              opt, wins = tbl[-1]\n              return {slot => ['', '', '', wins[-1].cget(opt)]}\n            end\n          end\n        rescue\n        end\n\n        super(slot)\n\n      else # slot == nil\n        info_list = super(slot)\n\n        tbl = @delegates['DEFAULT']\n        if tbl\n          wins = tbl[0][1]\n          info_list.update(wins[-1].configinfo) if wins && wins[-1]\n        end\n\n        @delegates.each{|slot, tbl|\n          next if slot == 'DEFAULT'\n          if tbl.length == 1\n            opt, wins = tbl[0]\n            next unless wins && wins[-1]\n            if slot == opt\n              info_list.update(wins[-1].configinfo(slot))\n            else\n              info_list.update({slot => wins[-1].configinfo(opt)[opt]})\n            end\n          else\n            opt, wins = tbl[-1]\n            info_list.update({slot => ['', '', '', wins[-1].cget(opt)]})\n          end\n        }\n\n        @option_methods.each{|slot, m|\n          if m[:info]\n            info = self.__send__(m[:info])\n          else\n            info = {slot => ['', '', '', self.cget(slot)]}\n          end\n          info_list.update(info)\n        }\n\n        info_list\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/console.rb",
    "content": "#\n#   tk/console.rb : control the console on system without a real console\n#\nrequire 'tk'\n\nmodule TkConsole\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['console'.freeze, 'consoleinterp'.freeze].freeze\n\n  def self.create\n    TkCore::INTERP._create_console\n  end\n  self.create  # initialize console\n\n  def self.title(str=None)\n    tk_call 'console', str\n  end\n  def self.hide\n    tk_call_without_enc('console', 'hide')\n  end\n  def self.show\n    tk_call_without_enc('console', 'show')\n  end\n  def self.eval(tcl_script)\n    #\n    # supports a Tcl script only\n    # I have no idea to support a Ruby script seamlessly.\n    #\n    _fromUTF8(tk_call_without_enc('console', 'eval', \n                                  _get_eval_enc_str(tcl_script)))\n  end\n  def self.maininterp_eval(tcl_script)\n    #\n    # supports a Tcl script only\n    # I have no idea to support a Ruby script seamlessly.\n    #\n    _fromUTF8(tk_call_without_enc('consoleinterp', 'eval', \n                                  _get_eval_enc_str(tcl_script)))\n\n  end\n  def self.maininterp_record(tcl_script)\n    #\n    # supports a Tcl script only\n    # I have no idea to support a Ruby script seamlessly.\n    #\n    _fromUTF8(tk_call_without_enc('consoleinterp', 'record', \n                                  _get_eval_enc_str(tcl_script)))\n\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/dialog.rb",
    "content": "#\n#   tk/dialog.rb : create dialog boxes\n#\nrequire 'tk'\nrequire 'tk/variable.rb'\n\nclass TkDialogObj < TkWindow\n  extend Tk\n\n  TkCommandNames = ['tk_dialog'.freeze].freeze\n\n  def self.show(*args)\n    dlog = self.new(*args)\n    dlog.show\n    dlog\n  end\n\n  def _set_button_config(configs)\n    set_config = proc{|c,i|\n      if $VERBOSE && (c.has_key?('command') || c.has_key?(:command))\n        STDERR.print(\"Warning: cannot give a command option \" + \n                     \"to the dialog button#{i}. It was removed.\\n\")\n      end\n      c.delete('command'); c.delete(:command)\n      # @config << Kernel.format(\"%s.button%s configure %s; \", \n      #                                @path, i, hash_kv(c).join(' '))\n      # @config << @path+'.button'+i.to_s+' configure '+hash_kv(c).join(' ')+'; '\n      @config << @path+'.button'+i.to_s+' configure '+\n                   array2tk_list(hash_kv(c))+'; '\n    }\n    case configs\n    when Proc\n      @buttons.each_index{|i|\n        if (c = configs.call(i)).kind_of?(Hash)\n          set_config.call(c,i)\n        end\n      }\n\n    when Array\n      @buttons.each_index{|i|\n        if (c = configs[i]).kind_of?(Hash)\n          set_config.call(c,i)\n        end\n      }\n\n    when Hash\n      @buttons.each_with_index{|s,i|\n        if (c = configs[s]).kind_of?(Hash)\n          set_config.call(c,i)\n        end\n      }\n    end\n    # @config = 'after idle {' + @config + '};' if @config != \"\"\n    @config = array2tk_list(['after', 'idle', @config]) << ';' if @config != \"\"\n  end\n  private :_set_button_config\n\n  # initialize tk_dialog\n  def create_self(keys)\n    # @var = TkVariable.new\n    @val = nil\n\n    @title   = title\n\n    @message = message\n    @message_config = message_config\n    @msgframe_config = msgframe_config\n\n    @bitmap  = bitmap\n    @bitmap_config = message_config\n\n    @default_button = default_button\n\n    @buttons = buttons\n    @button_configs = proc{|num| button_configs(num)}\n    @btnframe_config = btnframe_config\n\n    #@config = \"puts [winfo children .w0000];\"\n    @config = \"\"\n\n    @command = prev_command\n\n    if keys.kind_of?(Hash)\n      @title   = keys['title'] if keys.key? 'title'\n      @message = keys['message'] if keys.key? 'message'\n      @bitmap  = keys['bitmap'] if keys.key? 'bitmap'\n      # @bitmap  = '{}' if @bitmap == nil || @bitmap == \"\"\n      @bitmap  = '' unless @bitmap\n      @default_button = keys['default'] if keys.key? 'default'\n      @buttons = keys['buttons'] if keys.key? 'buttons'\n\n      @command = keys['prev_command'] if keys.key? 'prev_command'\n\n      @message_config = keys['message_config'] if keys.key? 'message_config'\n      @msgframe_config = keys['msgframe_config'] if keys.key? 'msgframe_config'\n      @bitmap_config  = keys['bitmap_config']  if keys.key? 'bitmap_config'\n      @button_configs = keys['button_configs'] if keys.key? 'button_configs'\n      @btnframe_config = keys['btnframe_config'] if keys.key? 'btnframe_config'\n    end\n\n    #if @title.include? ?\\s\n    #  @title = '{' + @title + '}'\n    #end\n\n    if @buttons.kind_of?(Array)\n      _set_button_config(@buttons.collect{|cfg| \n                           (cfg.kind_of? Array)? cfg[1]: nil})\n      @buttons = @buttons.collect{|cfg| (cfg.kind_of? Array)? cfg[0]: cfg}\n    end\n    if @buttons.kind_of?(Hash)\n      _set_button_config(@buttons)\n      @buttons = @buttons.keys\n    end\n    @buttons = tk_split_simplelist(@buttons) if @buttons.kind_of?(String)\n    @buttons = [] unless @buttons\n=begin\n    @buttons = @buttons.collect{|s|\n      if s.kind_of?(Array)\n        s = s.join(' ')\n      end\n      if s.include? ?\\s\n        '{' + s + '}'\n      else\n        s\n      end\n    }\n=end\n\n    if @message_config.kind_of?(Hash)\n      # @config << Kernel.format(\"%s.msg configure %s;\", \n      #                        @path, hash_kv(@message_config).join(' '))\n      # @config << @path+'.msg configure '+hash_kv(@message_config).join(' ')+';'\n      @config << @path+'.msg configure '+\n                   array2tk_list(hash_kv(@message_config))+';'\n    end\n\n    if @msgframe_config.kind_of?(Hash)\n      # @config << Kernel.format(\"%s.top configure %s;\", \n      #                        @path, hash_kv(@msgframe_config).join(' '))\n      # @config << @path+'.top configure '+hash_kv(@msgframe_config).join(' ')+';'\n      @config << @path+'.top configure '+\n                   array2tk_list(hash_kv(@msgframe_config))+';'\n    end\n\n    if @btnframe_config.kind_of?(Hash)\n      # @config << Kernel.format(\"%s.bot configure %s;\", \n      #                        @path, hash_kv(@btnframe_config).join(' '))\n      # @config << @path+'.bot configure '+hash_kv(@btnframe_config).join(' ')+';'\n      @config << @path+'.bot configure '+\n                   array2tk_list(hash_kv(@btnframe_config))+';'\n    end\n\n    if @bitmap_config.kind_of?(Hash)\n      # @config << Kernel.format(\"%s.bitmap configure %s;\", \n      #                        @path, hash_kv(@bitmap_config).join(' '))\n      # @config << @path+'.bitmap configure '+hash_kv(@bitmap_config).join(' ')+';'\n      @config << @path+'.bitmap configure '+\n                    array2tk_list(hash_kv(@bitmap_config))+';'\n    end\n\n    _set_button_config(@button_configs) if @button_configs\n  end\n  private :create_self\n\n  def show\n    # if @command.kind_of?(Proc)\n    if TkComm._callback_entry?(@command)\n      @command.call(self)\n    end\n\n    if @default_button.kind_of?(String)\n      default_button = @buttons.index(@default_button)\n    else\n      default_button = @default_button\n    end\n    # default_button = '{}' if default_button == nil\n    default_button = '' if default_button == nil\n    #Tk.ip_eval('eval {global '+@var.id+';'+@config+\n    #          'set '+@var.id+' [tk_dialog '+ \n    #          @path+\" \"+@title+\" {#{@message}} \"+@bitmap+\" \"+\n    #          String(default_button)+\" \"+@buttons.join(' ')+']}')\n    Tk.ip_eval(@config)\n    # @val = Tk.ip_eval('tk_dialog ' + @path + ' ' + @title + \n    #                 ' {' + @message + '} ' + @bitmap + ' ' + \n    #                 String(default_button) + ' ' + @buttons.join(' ')).to_i\n    # @val = Tk.ip_eval(self.class::TkCommandNames[0] + ' ' + @path + ' ' + \n    #                   @title + ' {' + @message + '} ' + @bitmap + ' ' + \n    #                   String(default_button) + ' ' + @buttons.join(' ')).to_i\n    @val = Tk.ip_eval(array2tk_list([\n                                      self.class::TkCommandNames[0], \n                                      @path, @title, @message, @bitmap, \n                                      String(default_button)\n                                    ].concat(@buttons))).to_i\n  end\n\n  def value\n    # @var.value.to_i\n    @val\n  end\n\n  def name\n    (@val)? @buttons[@val]: nil\n  end\n\n  ############################################################\n  #                                                          #\n  #  following methods should be overridden for each dialog  #\n  #                                                          #\n  ############################################################\n  private\n\n  def title\n    # returns a title string of the dialog window\n    return \"DIALOG\"\n  end\n  def message\n    # returns a message text to display on the dialog\n    return \"MESSAGE\"\n  end\n  def message_config\n    # returns a Hash {option=>value, ...} for the message text\n    return nil\n  end\n  def msgframe_config\n    # returns a Hash {option=>value, ...} for the message text frame\n    return nil\n  end\n  def bitmap\n    # returns a bitmap name or a bitmap file path \n    # (@ + path ; e.g. '@/usr/share/bitmap/sample.xbm')\n    return \"info\"\n  end\n  def bitmap_config\n    # returns nil or a Hash {option=>value, ...} for the bitmap\n    return nil\n  end\n  def default_button\n    # returns a default button's number or name\n    # if nil or null string, set no-default\n    return 0\n  end\n  def buttons\n    #return \"BUTTON1 BUTTON2\"\n    return [\"BUTTON1\", \"BUTTON2\"]\n  end\n  def button_configs(num)\n    # returns nil / Proc / Array or Hash (see _set_button_config)\n    return nil\n  end\n  def btnframe_config\n    # returns nil or a Hash {option=>value, ...} for the button frame\n    return nil\n  end\n  def prev_command\n    # returns nil or a Proc\n    return nil\n  end\nend\nTkDialog2 = TkDialogObj\n\n#\n# TkDialog : with showing at initialize\n#\nclass TkDialog < TkDialogObj\n  def self.show(*args)\n    self.new(*args)\n  end\n\n  def initialize(*args)\n    super(*args)\n    show\n  end\nend\n\n\n#\n# dialog for warning\n#\nclass TkWarningObj < TkDialogObj\n  def initialize(parent = nil, mes = nil)\n    if !mes\n      if parent.kind_of?(TkWindow)\n        mes = \"\"\n      else\n        mes = parent.to_s\n        parent = nil\n      end\n    end\n    super(parent, :message=>mes)\n  end\n\n  def show(mes = nil)\n    mes_bup = @message\n    @message = mes if mes\n    ret = super()\n    @message = mes_bup\n    ret\n  end\n\n  #######\n  private\n\n  def title\n    return \"WARNING\";\n  end\n  def bitmap\n    return \"warning\";\n  end\n  def default_button\n    return 0;\n  end\n  def buttons\n    return \"OK\";\n  end\nend\nTkWarning2 = TkWarningObj\n\nclass TkWarning < TkWarningObj\n  def self.show(*args)\n    self.new(*args)\n  end\n  def initialize(*args)\n    super(*args)\n    show\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/encodedstr.rb",
    "content": "#\n# tk/encodedstr.rb : Tk::EncodedString class\n#\nrequire 'tk'\n\n###########################################\n#  string with Tcl's encoding\n###########################################\nmodule Tk\n  class EncodedString < String\n    Encoding = nil\n\n    def self.subst_utf_backslash(str)\n      # str.gsub(/\\\\u([0-9A-Fa-f]{1,4})/){[$1.hex].pack('U')}\n      TclTkLib._subst_UTF_backslash(str)\n    end\n    def self.utf_backslash(str)\n      self.subst_utf_backslash(str)\n    end\n\n    def self.subst_tk_backslash(str)\n      TclTkLib._subst_Tcl_backslash(str)\n    end\n\n    def self.utf_to_backslash_sequence(str)\n      str.unpack('U*').collect{|c|\n        if c <= 0xFF  # ascii character\n          c.chr\n        else\n          format('\\u%X', c)\n        end\n      }.join('')\n    end\n    def self.utf_to_backslash(str)\n      self.utf_to_backslash_sequence(str)\n    end\n\n    def self.to_backslash_sequence(str)\n      str.unpack('U*').collect{|c|\n        if c <= 0x1F  # control character\n          case c\n          when 0x07; '\\a'\n          when 0x08; '\\b'\n          when 0x09; '\\t'\n          when 0x0a; '\\n'\n          when 0x0b; '\\v'\n          when 0x0c; '\\f'\n          when 0x0d; '\\r'\n          else\n            format('\\x%02X', c)\n          end\n        elsif c <= 0xFF  # ascii character\n          c.chr\n        else\n          format('\\u%X', c)\n        end\n      }.join('')\n    end\n\n    def self.new_with_utf_backslash(str, enc = nil)\n      self.new('', enc).replace(self.subst_utf_backslash(str))\n    end\n\n    def self.new_without_utf_backslash(str, enc = nil)\n      self.new('', enc).replace(str)\n    end\n\n    def initialize(str, enc = nil)\n      super(str)\n      # @encoding = ( enc || \n      #              ((self.class::Encoding)? \n      #                  self.class::Encoding : Tk.encoding_system) )\n      enc ||= (self.class::Encoding)?\n                         self.class::Encoding : \n                         ((Tk.encoding)? Tk.encoding : Tk.encoding_system)\n      if TkCore::WITH_ENCODING\n        unless encobj = Tk::Encoding::ENCODING_TABLE.get_obj(enc)\n          fail ArgumentError, \"unsupported Tk encoding '#{enc}'\"\n        end\n        self.force_encoding(encobj)\n      else\n        @encoding = enc\n      end\n    end\n\n    if TkCore::WITH_ENCODING\n      alias encoding_obj encoding\n      alias __encoding   encoding\n      def encoding\n        Tk::Encoding::ENCODING_TABLE.get_name(super())\n      end\n    else\n      def encoding\n        @encoding\n      end\n      alias encoding_obj encoding\n    end\n\n    if TkCore::WITH_ENCODING\n      # wrapper methods for compatibility\n      alias __instance_variable_get instance_variable_get\n      alias __instance_variable_set instance_variable_set\n      alias __instance_eval         instance_eval\n      alias __instance_variables    instance_variables\n\n      def instance_variable_get(key)\n        if (key.to_s == '@encoding')\n          self.encoding\n        else\n          super(key)\n        end\n      end\n\n      def instance_variable_set(key, value)\n        if (key.to_s == '@encoding')\n          if value\n            self.force_encoding(value)\n          else\n            self.force_encoding(Tk::Encoding::UNKNOWN)\n          end\n          value\n        else\n          super(key, value)\n        end\n      end\n\n      def instance_eval(*args, &b)\n        old_enc = @encoding = self.encoding\n\n        ret = super(*args, &b)\n\n        if @encoding\n          if @encoding != old_enc\n            # modified by user\n            self.force_encoding(@encoding)\n          end\n          remove_instance_variable(:@encoding)\n        else\n          begin\n            remove_instance_variable(:@encoding)\n            # user sets to nil -> use current default\n            self.force_encoding(Tk.encoding)\n          rescue NameError\n            # removed by user -> ignore, because user don't use @encoding\n          end\n        end\n        ret\n      end\n    end\n\n    def instance_variables\n      ret = super()\n      ret << :@encoding  # fake !!\n      ret\n    end\n  end\n  # def Tk.EncodedString(str, enc = nil)\n  #   Tk::EncodedString.new(str, enc)\n  # end\n\n  ##################################\n\n  class BinaryString < EncodedString\n    Encoding = 'binary'.freeze\n  end\n  # def Tk.BinaryString(str)\n  #   Tk::BinaryString.new(str)\n  # end\n\n  ##################################\n\n  class UTF8_String < EncodedString\n    Encoding = 'utf-8'.freeze\n    def self.new(str)\n      super(self.subst_utf_backslash(str))\n    end\n\n    def to_backslash_sequence\n      Tk::EncodedString.utf_to_backslash_sequence(self)\n    end\n    alias to_backslash to_backslash_sequence\n  end\n  # def Tk.UTF8_String(str)\n  #   Tk::UTF8_String.new(str)\n  # end\n\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/entry.rb",
    "content": "#\n#               tk/entry.rb - Tk entry classes\n#                       by Yukihiro Matsumoto <matz@caelum.co.jp>\n\nrequire 'tk'\nrequire 'tk/label'\nrequire 'tk/scrollable'\nrequire 'tk/validation'\n\nclass Tk::Entry<Tk::Label\n  include X_Scrollable\n  include TkValidation\n\n  TkCommandNames = ['entry'.freeze].freeze\n  WidgetClassName = 'Entry'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  #def create_self(keys)\n  #  super(__conv_vcmd_on_hash_kv(keys))\n  #end\n  #private :create_self\n\n  def __strval_optkeys\n    super() + ['show', 'disabledbackground', 'readonlybackground']\n  end\n  private :__strval_optkeys\n\n  def bbox(index)\n    list(tk_send_without_enc('bbox', index))\n  end\n  def cursor\n    number(tk_send_without_enc('index', 'insert'))\n  end\n  alias icursor cursor\n  def cursor=(index)\n    tk_send_without_enc('icursor', index)\n    #self\n    index\n  end\n  alias icursor= cursor=\n  def index(idx)\n    number(tk_send_without_enc('index', idx))\n  end\n  def insert(pos,text)\n    tk_send_without_enc('insert', pos, _get_eval_enc_str(text))\n    self\n  end\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n  def mark(pos)\n    tk_send_without_enc('scan', 'mark', pos)\n    self\n  end\n  def dragto(pos)\n    tk_send_without_enc('scan', 'dragto', pos)\n    self\n  end\n  def selection_adjust(index)\n    tk_send_without_enc('selection', 'adjust', index)\n    self\n  end\n  def selection_clear\n    tk_send_without_enc('selection', 'clear')\n    self\n  end\n  def selection_from(index)\n    tk_send_without_enc('selection', 'from', index)\n    self\n  end\n  def selection_present()\n    bool(tk_send_without_enc('selection', 'present'))\n  end\n  def selection_range(s, e)\n    tk_send_without_enc('selection', 'range', s, e)\n    self\n  end\n  def selection_to(index)\n    tk_send_without_enc('selection', 'to', index)\n    self\n  end\n\n  def invoke_validate\n    bool(tk_send_without_enc('validate'))\n  end\n  def validate(mode = nil)\n    if mode\n      configure 'validate', mode\n    else\n      invoke_validate\n    end\n  end\n\n  def value\n    _fromUTF8(tk_send_without_enc('get'))\n  end\n  def value= (val)\n    tk_send_without_enc('delete', 0, 'end')\n    tk_send_without_enc('insert', 0, _get_eval_enc_str(val))\n    val\n  end\n  alias get value\n  alias set value=\n\n  def [](*args)\n    self.value[*args]\n  end\n  def []=(*args)\n    val = args.pop\n    str = self.value\n    str[*args] = val\n    self.value = str\n    val\n  end\nend\n\n#TkEntry = Tk::Entry unless Object.const_defined? :TkEntry\nTk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)\n"
  },
  {
    "path": "ext/tk/lib/tk/event.rb",
    "content": "#\n#  tk/event.rb - module for event\n#\n\nmodule TkEvent\nend\n\n########################\n\nrequire 'tkutil'\nrequire 'tk'\n\n########################\n\nmodule TkEvent\n  class Event < TkUtil::CallbackSubst\n    module Grp\n      KEY         =           0x1\n      BUTTON      =           0x2\n      MOTION      =           0x4\n      CROSSING    =           0x8\n      FOCUS       =           0x10\n      EXPOSE      =           0x20\n      VISIBILITY  =           0x40\n      CREATE      =           0x80\n      DESTROY     =           0x100\n      UNMAP       =           0x200\n      MAP         =           0x400\n      REPARENT    =           0x800\n      CONFIG      =           0x1000\n      GRAVITY     =           0x2000\n      CIRC        =           0x4000\n      PROP        =           0x8000\n      COLORMAP    =           0x10000\n      VIRTUAL     =           0x20000\n      ACTIVATE    =           0x40000\n      MAPREQ      =           0x80000\n      CONFIGREQ   =           0x100000\n      RESIZEREQ   =           0x200000\n      CIRCREQ     =           0x400000\n\n      MWHEEL      =           KEY\n\n      STRING_DATA =           0x80000000  # special flag for 'data' field\n\n      ALL         =           0xFFFFFFFF\n\n      KEY_BUTTON_MOTION_VIRTUAL  = (KEY|MWHEEL|BUTTON|MOTION|VIRTUAL)\n      KEY_BUTTON_MOTION_CROSSING = (KEY|MWHEEL|BUTTON|MOTION|CROSSING|VIRTUAL)\n    end\n\n    type_data = [\n      #-----+-------------------+------------------+-----------------------#\n      #  ID |  const            |  group_flag      |  context_name         #\n      #-----+-------------------+------------------+-----------------------#\n      [  2,  :KeyPress,          Grp::KEY,         'KeyPress',    'Key'    ], \n      [  3,  :KeyRelease,        Grp::KEY,         'KeyRelease'            ], \n      [  4,  :ButtonPress,       Grp::BUTTON,      'ButtonPress', 'Button' ], \n      [  5,  :ButtonRelease,     Grp::BUTTON,      'ButtonRelease'         ], \n      [  6,  :MotionNotify,      Grp::MOTION,      'Motion'                ], \n      [  7,  :EnterNotify,       Grp::CROSSING,    'Enter'                 ], \n      [  8,  :LeaveNotify,       Grp::CROSSING,    'Leave'                 ], \n      [  9,  :FocusIn,           Grp::FOCUS,       'FocusIn'               ], \n      [ 10,  :FocusOut,          Grp::FOCUS,       'FocusOut'              ], \n      [ 11,  :KeymapNotify,      0,                                        ], \n      [ 12,  :Expose,            Grp::EXPOSE,      'Expose'                ], \n      [ 13,  :GraphicsExpose,    Grp::EXPOSE,                              ], \n      [ 14,  :NoExpose,          0,                                        ], \n      [ 15,  :VisibilityNotify,  Grp::VISIBILITY,  'Visibility'            ], \n      [ 16,  :CreateNotify,      Grp::CREATE,      'Create'                ], \n      [ 17,  :DestroyNotify,     Grp::DESTROY,     'Destroy'               ], \n      [ 18,  :UnmapNotify,       Grp::UNMAP,       'Unmap'                 ], \n      [ 19,  :MapNotify,         Grp::MAP,         'Map'                   ], \n      [ 20,  :MapRequest,        Grp::MAPREQ,      'MapRequest'            ], \n      [ 21,  :ReparentNotify,    Grp::REPARENT,    'Reparent'              ], \n      [ 22,  :ConfigureNotify,   Grp::CONFIG,      'Configure'             ], \n      [ 23,  :ConfigureRequest,  Grp::CONFIGREQ,   'ConfigureRequest'      ], \n      [ 24,  :GravityNotify,     Grp::GRAVITY,     'Gravity'               ], \n      [ 25,  :ResizeRequest,     Grp::RESIZEREQ,   'ResizeRequest'         ], \n      [ 26,  :CirculateNotify,   Grp::CIRC,        'Circulate'             ], \n      [ 27,  :CirculateRequest,  0,                'CirculateRequest'      ], \n      [ 28,  :PropertyNotify,    Grp::PROP,        'Property'              ], \n      [ 29,  :SelectionClear,    0,                                        ], \n      [ 30,  :SelectionRequest,  0,                                        ], \n      [ 31,  :SelectionNotify,   0,                                        ], \n      [ 32,  :ColormapNotify,    Grp::COLORMAP,    'Colormap'              ], \n      [ 33,  :ClientMessage,     0,                                        ], \n      [ 34,  :MappingNotify,     0,                                        ], \n      [ 35,  :VirtualEvent,      Grp::VIRTUAL,                             ],\n      [ 36,  :ActivateNotify,    Grp::ACTIVATE,    'Activate'              ],\n      [ 37,  :DeactivateNotify,  Grp::ACTIVATE,    'Deactivate'            ],\n      [ 38,  :MouseWheelEvent,   Grp::MWHEEL,      'MouseWheel'            ],\n      [ 39,  :TK_LASTEVENT,      0,                                        ]\n    ]\n\n    module TypeNum\n    end\n\n    TYPE_NAME_TBL  = Hash.new\n    TYPE_ID_TBL    = Hash.new\n    TYPE_GROUP_TBL = Hash.new\n\n    type_data.each{|id, c_name, g_flag, *t_names|\n      TypeNum.const_set(c_name, id)\n      t_names.each{|t_name| t_name.freeze; TYPE_NAME_TBL[t_name] = id }\n      TYPE_ID_TBL[id]    = t_names\n      TYPE_GROUP_TBL[id] = g_flag\n    }\n\n    TYPE_NAME_TBL.freeze\n    TYPE_ID_TBL.freeze\n\n    def self.type_id(name)\n      TYPE_NAME_TBL[name.to_s]\n    end\n\n    def self.type_name(id)\n      TYPE_ID_TBL[id] && TYPE_ID_TBL[id][0]\n    end\n\n    def self.group_flag(id)\n      TYPE_GROUP_TBL[id] || 0\n    end\n\n    #############################################\n\n    module StateMask\n      ShiftMask      =        (1<<0)\n      LockMask       =        (1<<1)\n      ControlMask    =        (1<<2)\n      Mod1Mask       =        (1<<3)\n      Mod2Mask       =        (1<<4)\n      Mod3Mask       =        (1<<5)\n      Mod4Mask       =        (1<<6)\n      Mod5Mask       =        (1<<7)\n      Button1Mask    =        (1<<8)\n      Button2Mask    =        (1<<9)\n      Button3Mask    =        (1<<10)\n      Button4Mask    =        (1<<11)\n      Button5Mask    =        (1<<12)\n\n      AnyModifier    =        (1<<15)\n\n      META_MASK      =  (AnyModifier<<1)\n      ALT_MASK       =  (AnyModifier<<2)\n      EXTENDED_MASK  =  (AnyModifier<<3)\n\n      CommandMask    =  Mod1Mask\n      OptionMask     =  Mod2Mask\n    end\n\n    #############################################\n\n    FIELD_FLAG = {\n      # key  =>  flag\n      'above'       => Grp::CONFIG, \n      'borderwidth' => (Grp::CREATE|Grp::CONFIG),\n      'button'      => Grp::BUTTON, \n      'count'       => Grp::EXPOSE, \n      'data'        => (Grp::VIRTUAL|Grp::STRING_DATA), \n      'delta'       => Grp::MWHEEL, \n      'detail'      => (Grp::FOCUS|Grp::CROSSING),\n      'focus'       => Grp::CROSSING,\n      'height'      => (Grp::EXPOSE|Grp::CONFIG),\n      'keycode'     => Grp::KEY,\n      'keysym'      => Grp::KEY,\n      'mode'        => (Grp::CROSSING|Grp::FOCUS),\n      'override'    => (Grp::CREATE|Grp::MAP|Grp::REPARENT|Grp::CONFIG),\n      'place'       => Grp::CIRC,\n      'root'        => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),\n      'rootx'       => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),\n      'rooty'       => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),\n      'sendevent'   => Grp::ALL,\n      'serial'      => Grp::ALL,\n      'state'       => (Grp::KEY_BUTTON_MOTION_VIRTUAL|\n                        Grp::CROSSING|Grp::VISIBILITY),\n      'subwindow'   => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING),\n      'time'        => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING|\n                        Grp::PROP),\n      'warp'        => Grp::KEY_BUTTON_MOTION_VIRTUAL,\n      'width'       => (Grp::EXPOSE|Grp::CREATE|Grp::CONFIG),\n      'window'      => (Grp::CREATE|Grp::UNMAP|Grp::MAP|Grp::REPARENT|\n                        Grp::CONFIG|Grp::GRAVITY|Grp::CIRC),\n      'when'        => Grp::ALL,\n      'x'           => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING|\n                        Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY|\n                        Grp::REPARENT),\n      'y'           => (Grp::KEY_BUTTON_MOTION_VIRTUAL|Grp::CROSSING|\n                        Grp::EXPOSE|Grp::CREATE|Grp::CONFIG|Grp::GRAVITY|\n                        Grp::REPARENT),\n    }\n\n    FIELD_OPERATION = {\n      'root' => proc{|val| \n        begin\n          Tk.tk_call_without_enc('winfo', 'pathname', val)\n          val\n        rescue\n          nil\n        end\n      }, \n\n      'subwindow' => proc{|val| \n        begin\n          Tk.tk_call_without_enc('winfo', 'pathname', val)\n          val\n        rescue\n          nil\n        end\n      }, \n\n      'window' => proc{|val| nil}\n    }\n\n    #-------------------------------------------\n\n    def valid_fields(group_flag=nil)\n      group_flag = self.class.group_flag(self.type) unless group_flag\n\n      fields = {}\n      FIELD_FLAG.each{|key, flag|\n        next if (flag & group_flag) == 0\n        begin\n          val = self.__send__(key)\n        rescue\n          next\n        end\n        # next if !val || val == '??'\n        next if !val || (val == '??' && (flag & Grp::STRING_DATA))\n        fields[key] = val\n      }\n\n      fields\n    end\n\n    def valid_for_generate(group_flag=nil)\n      fields = valid_fields(group_flag)\n\n      FIELD_OPERATION.each{|key, cmd|\n        next unless fields.has_key?(key)\n        val = FIELD_OPERATION[key].call(fields[key])\n        if val\n          fields[key] = val\n        else\n          fields.delete(key)\n        end\n      }\n\n      fields\n    end\n\n    def generate(win, modkeys={})\n      klass = self.class\n\n      if modkeys.has_key?(:type) || modkeys.has_key?('type')\n        modkeys = TkComm._symbolkey2str(modkeys)\n        type_id = modkeys.delete('type')\n      else\n        type_id = self.type\n      end\n\n      type_name  = klass.type_name(type_id)\n      unless type_name\n        fail RuntimeError, \"type_id #{type_id} is invalid\"\n      end\n\n      group_flag = klass.group_flag(type_id)\n\n      opts = valid_for_generate(group_flag)\n\n      modkeys.each{|key, val|\n        if val\n          opts[key.to_s] = val\n        else\n          opts.delete(key.to_s)\n        end\n      }\n\n      if group_flag != Grp::KEY\n        Tk.event_generate(win, type_name, opts)\n      else\n        # If type is KEY event, focus should be set to target widget.\n        # If not set, original widget will get the same event. \n        # That will make infinite loop.\n        w = Tk.tk_call_without_enc('focus')\n        begin\n          Tk.tk_call_without_enc('focus', win)\n          Tk.event_generate(win, type_name, opts)\n        ensure\n          Tk.tk_call_without_enc('focus', w)\n        end\n      end\n    end\n\n    #############################################\n\n    # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>]\n    KEY_TBL = [\n      [ ?#, ?n, :serial ], \n      [ ?a, ?s, :above ], \n      [ ?b, ?n, :num ], \n      [ ?c, ?n, :count ], \n      [ ?d, ?s, :detail ], \n      # ?e\n      [ ?f, ?b, :focus ], \n      # ?g\n      [ ?h, ?n, :height ], \n      [ ?i, ?s, :win_hex ], \n      # ?j\n      [ ?k, ?n, :keycode ], \n      # ?l\n      [ ?m, ?s, :mode ], \n      # ?n\n      [ ?o, ?b, :override ], \n      [ ?p, ?s, :place ], \n      # ?q\n      # ?r\n      [ ?s, ?x, :state ], \n      [ ?t, ?n, :time ], \n      # ?u\n      [ ?v, ?n, :value_mask ], \n      [ ?w, ?n, :width ], \n      [ ?x, ?n, :x ], \n      [ ?y, ?n, :y ], \n      # ?z\n      [ ?A, ?s, :char ], \n      [ ?B, ?n, :borderwidth ], \n      # ?C\n      [ ?D, ?n, :wheel_delta ], \n      [ ?E, ?b, :send_event ], \n      # ?F\n      # ?G\n      # ?H\n      # ?I\n      # ?J\n      [ ?K, ?s, :keysym ], \n      # ?L\n      # ?M\n      [ ?N, ?n, :keysym_num ], \n      # ?O\n      [ ?P, ?s, :property ], \n      # ?Q\n      [ ?R, ?s, :rootwin_id ], \n      [ ?S, ?s, :subwindow ], \n      [ ?T, ?n, :type ], \n      # ?U\n      # ?V\n      [ ?W, ?w, :widget ], \n      [ ?X, ?n, :x_root ], \n      [ ?Y, ?n, :y_root ], \n      # ?Z\n      nil\n    ]\n\n    # [ <'%' subst-key str>, <proc type char>, <instance var (accessor) name>]\n    #   the subst-key string will be converted to a bytecode (128+idx).\n    LONGKEY_TBL = [\n      # for example, for %CTT and %CST subst-key on tkdnd-2.0\n      # ['CTT', ?l, :drop_target_type], \n      # ['CST', ?l, :drop_source_type], \n    ]\n\n    # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>]\n    PROC_TBL = [\n      [ ?n, TkComm.method(:num_or_str) ], \n      [ ?s, TkComm.method(:string) ], \n      [ ?b, TkComm.method(:bool) ], \n      [ ?w, TkComm.method(:window) ], \n\n      [ ?x, proc{|val|\n          begin\n            TkComm::number(val)\n          rescue ArgumentError\n            val\n          end\n        }\n      ], \n\n      nil\n    ]\n\n=begin\n    # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n    KEY_TBL.map!{|inf|\n      if inf.kind_of?(Array)\n        inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n      end\n      inf\n    }\n\n    PROC_TBL.map!{|inf|\n      if inf.kind_of?(Array)\n        inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n      end\n      inf\n    }\n=end\n\n    # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys\n    #\n    #     _get_subst_key() and _get_all_subst_keys() generates key-string \n    #     which describe how to convert callback arguments to ruby objects. \n    #     When binding parameters are given, use _get_subst_key(). \n    #     But when no parameters are given, use _get_all_subst_keys() to \n    #     create a Event class object as a callback parameter. \n    #\n    #     scan_args() is used when doing callback. It convert arguments \n    #     ( which are Tcl strings ) to ruby objects based on the key string \n    #     that is generated by _get_subst_key() or _get_all_subst_keys(). \n    #\n    _setup_subst_table(KEY_TBL, PROC_TBL)\n    # _setup_subst_table(KEY_TBL, LONGKEY_TBL, PROC_TBL) # if use longname-keys\n\n    #\n    # NOTE: The order of parameters which passed to callback procedure is \n    #        <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ...\n    #\n\n    # If you need support extra arguments given by Tcl/Tk, \n    # please override _get_extra_args_tbl\n    #\n    #def self._get_extra_args_tbl\n    #  # return an array of convert procs\n    #  []\n    #end\n\n=begin\n    alias button num\n    alias delta  wheel_delta\n    alias root   rootwin_id\n    alias rootx  x_root\n    alias root_x x_root\n    alias rooty  y_root\n    alias root_y y_root\n    alias sendevent send_event\n=end\n    ALIAS_TBL = {\n      :button    => :num, \n      :data      => :detail, \n      :delta     => :wheel_delta, \n      :root      => :rootwin_id, \n      :rootx     => :x_root, \n      :root_x    => :x_root, \n      :rooty     => :y_root, \n      :root_y    => :y_root, \n      :sendevent => :send_event, \n      :window    => :widget\n    }\n\n    _define_attribute_aliases(ALIAS_TBL)\n\n  end\n\n  ###############################################\n\n  def install_bind_for_event_class(klass, cmd, *args)\n    extra_args_tbl = klass._get_extra_args_tbl\n\n    if args.compact.size > 0\n      args.map!{|arg| klass._sym2subst(arg)}\n      args = args.join(' ')\n      keys = klass._get_subst_key(args)\n\n      if cmd.kind_of?(String)\n        id = cmd\n      elsif cmd.kind_of?(TkCallbackEntry)\n        id = install_cmd(cmd)\n      else\n        id = install_cmd(proc{|*arg|\n          ex_args = []\n          extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)}\n          begin\n            TkUtil.eval_cmd(cmd, *(ex_args.concat(klass.scan_args(keys, arg))))\n          rescue Exception=>e\n            if TkCore::INTERP.kind_of?(TclTkIp)\n              fail e\n            else\n              # MultiTkIp\n              fail Exception, \"#{e.class}: #{e.message.dup}\"\n            end\n          end\n        })\n      end\n    else\n      keys, args = klass._get_all_subst_keys\n\n      if cmd.kind_of?(String)\n        id = cmd\n      elsif cmd.kind_of?(TkCallbackEntry)\n        id = install_cmd(cmd)\n      else\n        id = install_cmd(proc{|*arg|\n          ex_args = []\n          extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)}\n          begin\n            TkUtil.eval_cmd(cmd, *(ex_args << klass.new(*klass.scan_args(keys, arg))))\n          rescue Exception=>e\n            if TkCore::INTERP.kind_of?(TclTkIp)\n              fail e\n            else\n              # MultiTkIp\n              fail Exception, \"#{e.class}: #{e.message.dup}\"\n            end\n          end\n        })\n      end\n    end\n\n    if TkCore::INTERP.kind_of?(TclTkIp)\n      id + ' ' + args\n    else\n      # MultiTkIp\n      \"if {[set st [catch {#{id} #{args}} ret]] != 0} {\n         if {$st == 4} {\n           return -code continue $ret\n         } elseif {$st == 3} {\n           return -code break $ret\n         } elseif {$st == 2} {\n           return -code return $ret\n         } elseif {[regexp {^Exception: (TkCallbackContinue: .*)$} \\\n                                                               $ret m msg]} {\n           return -code continue $msg\n         } elseif {[regexp {^Exception: (TkCallbackBreak: .*)$} $ret m msg]} {\n           return -code break $msg\n         } elseif {[regexp {^Exception: (TkCallbackReturn: .*)$} $ret m msg]} {\n           return -code return $msg\n         } elseif {[regexp {^Exception: (\\\\S+: .*)$} $ret m msg]} {\n           return -code return $msg\n         } else {\n           return -code error $ret\n         }\n       } else {\n          set ret\n       }\"\n    end\n  end\n\n  def install_bind(cmd, *args)\n    install_bind_for_event_class(TkEvent::Event, cmd, *args)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/font.rb",
    "content": "#\n#  tk/font.rb - the class to treat fonts on Ruby/Tk\n#\n#                               by  Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass TkFont\n  include Tk\n  extend TkCore\n\n  TkCommandNames = ['font'.freeze].freeze\n\n  (Tk_FontID = [\"@font\".freeze, \"00000\".taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  Tk_FontNameTBL = TkCore::INTERP.create_table\n  Tk_FontUseTBL  = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{ \n    Tk_FontNameTBL.mutex.synchronize{ Tk_FontNameTBL.clear }\n    Tk_FontUseTBL.mutex.synchronize{ Tk_FontUseTBL.clear }\n  }\n\n  # option_type : default => string\n  OptionType = Hash.new(?s)\n  OptionType['size'] = ?n\n  OptionType['pointadjust'] = ?n\n  OptionType['underline'] = ?b\n  OptionType['overstrike'] = ?b\n\n  # metric_type : default => num_or_str\n  MetricType = Hash.new(?n)\n  MetricType['fixed'] = ?b\n\n  # system font names\n  SYSTEM_FONT_NAMES = []\n  def SYSTEM_FONT_NAMES.add(font_names)\n    (@mutex ||= Mutex.new).synchronize{\n      self.replace(self | font_names.map{|name| name.to_s})\n    }\n  end\n  def SYSTEM_FONT_NAMES.include?(name)\n    (@mutex ||= Mutex.new).synchronize{\n      super(name.to_s)\n    }\n  end\n\n  # set default font\n  case Tk::TK_VERSION\n  when /^4\\..*/\n    DEFAULT_LATIN_FONT_NAME = 'a14'.freeze\n    DEFAULT_KANJI_FONT_NAME = 'k14'.freeze\n\n  when /^8\\.[0-4]/\n    if JAPANIZED_TK\n      begin\n        fontnames = tk_call('font', 'names')\n        case fontnames\n        when /defaultgui/\n          # Tcl/Tk-JP for Windows\n          ltn = 'defaultgui'\n          knj = 'defaultgui'\n        when /Mincho:Helvetica-Bold-12/\n          # Tcl/Tk-JP for UNIX/X\n          ltn, knj = tk_split_simplelist(tk_call('font', 'configure', \n                                                 'Mincho:Helvetica-Bold-12', \n                                                 '-compound'))\n        else\n          # unknown Tcl/Tk-JP\n          #platform = tk_call('set', 'tcl_platform(platform)')\n          platform = Tk::PLATFORM['platform']\n          case platform\n          when 'unix'\n            ltn = {'family'=>'Helvetica'.freeze, \n                   'size'=>-12, 'weight'=>'bold'.freeze}\n            #knj = 'k14'\n            #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0'\n            knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0'\n          when 'windows'\n            ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}\n            knj = 'mincho'\n          when 'macintosh'\n            ltn = 'system'\n            knj = 'mincho'\n          else # unknown\n            ltn = 'Helvetica'\n            knj = 'mincho'\n          end\n        end\n      rescue\n        ltn = 'Helvetica'\n        knj = 'mincho'\n      end\n\n    else # not JAPANIZED_TK\n      begin\n        #platform = tk_call('set', 'tcl_platform(platform)')\n        platform = Tk::PLATFORM['platform']\n        case platform\n        when 'unix'\n          ltn = {'family'=>'Helvetica'.freeze, \n                 'size'=>-12, 'weight'=>'bold'.freeze}\n        when 'windows'\n          ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}\n        when 'macintosh'\n          ltn = 'system'\n        else # unknown\n          ltn = 'Helvetica'\n        end\n      rescue\n        ltn = 'Helvetica'\n      end\n\n      knj = ltn.dup\n    end\n\n    DEFAULT_LATIN_FONT_NAME = ltn.freeze\n    DEFAULT_KANJI_FONT_NAME = knj.freeze\n\n  when /^8\\.[5-9]/, /^9\\..*/\n    if tk_call('font', 'names') =~ /\\bTkDefaultFont\\b/\n      DEFAULT_LATIN_FONT_NAME = 'TkDefaultFont'.freeze\n      DEFAULT_KANJI_FONT_NAME = 'TkDefaultFont'.freeze\n    else\n      DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze\n      DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze\n    end\n\n  else # unknown version\n    DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze\n    DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze\n\n  end\n\n  if $DEBUG\n    print \"default latin font = \"; p DEFAULT_LATIN_FONT_NAME\n    print \"default kanji font = \"; p DEFAULT_KANJI_FONT_NAME\n  end\n\n\n  ###################################\n  class DescendantFont\n    def initialize(compound, type)\n      unless compound.kind_of?(TkFont)\n        fail ArgumentError, \"a TkFont object is expected for the 1st argument\"\n      end\n\n      @compound = compound\n      case type\n      when 'kanji', 'latin', 'ascii'\n        @type = type\n      when :kanji, :latin, :ascii\n        @type = type.to_s\n      else\n        fail ArgumentError, \"unknown type '#{type}'\"\n      end\n    end\n\n    def dup\n      fail RuntimeError, \"cannot dupulicate a descendant font\"\n    end\n    def clone\n      fail RuntimeError, \"cannot clone a descendant font\"\n    end\n\n    def to_eval\n      @compound.__send__(@type + '_font_id')\n    end\n    def font\n      @compound.__send__(@type + '_font_id')\n    end\n    alias font_id font\n    alias name font\n    alias to_s font\n\n    def [](slot)\n      @compound.__send__(@type + '_configinfo', slot)\n    end\n    def []=(slot, value)\n      @compound.__send__(@type + '_configure', slot, value)\n      value\n    end\n\n    def method_missing(id, *args)\n      @compound.__send__(@type + '_' + id.id2name, *args)\n    end\n  end\n\n\n  ###################################\n  # class methods\n  ###################################\n  def TkFont.is_system_font?(fnt)\n    # true  --> system font which is available on the current system\n    # false --> not system font (or unknown system font)\n    # nil   --> system font name, but not available on the current system\n    fnt = fnt.to_s\n    SYSTEM_FONT_NAMES.include?(fnt) && self.names.index(fnt) && true\n  end\n\n  def TkFont.actual(fnt, option=nil)\n    fnt = '{}' if fnt == ''\n    if fnt.kind_of?(TkFont)\n     fnt.actual(option)\n    else\n      actual_core(fnt, nil, option)\n    end\n  end\n  def TkFont.actual_hash(fnt, option=nil)\n    Hash[TkFont.actual_hash(fnt, option)]\n  end\n\n  def TkFont.actual_displayof(fnt, win, option=nil)\n    fnt = '{}' if fnt == ''\n    if fnt.kind_of?(TkFont)\n     fnt.actual_displayof(win, option)\n    else\n      win = '.' unless win\n      actual_core(fnt, win, option)\n    end\n  end\n  def TkFont.actual_hash_displayof(fnt, option=nil)\n    Hash[TkFont.actual_hash_displayof(fnt, option)]\n  end\n\n  def TkFont.configure(fnt, slot, value=None)\n    if fnt.kind_of?(TkFont)\n      fnt.configure(fnt, slot, value)\n    else\n      configure_core(fnt, slot, value)\n    end\n    fnt\n  end\n\n  def TkFont.configinfo(fnt, slot=nil)\n    if fnt.kind_of?(TkFont)\n      fnt.configinfo(fnt, slot)\n    else\n      configinfo_core(fnt, slot)\n    end\n  end\n\n  def TkFont.current_configinfo(fnt, slot=nil)\n    if fnt.kind_of?(TkFont)\n      fnt.current_configinfo(fnt, slot)\n    else\n      current_configinfo_core(fnt, slot)\n    end\n  end\n\n  def TkFont.measure(fnt, text)\n    fnt = '{}' if fnt == ''\n    if fnt.kind_of?(TkFont)\n      fnt.measure(text)\n    else\n      measure_core(fnt, nil, text)\n    end\n  end\n\n  def TkFont.measure_displayof(fnt, win, text)\n    fnt = '{}' if fnt == ''\n    if fnt.kind_of?(TkFont)\n      fnt.measure_displayof(win, text)\n    else\n      win = '.' unless win\n      measure_core(fnt, win, text)\n    end\n  end\n\n  def TkFont.metrics(fnt, option=nil)\n    fnt = '{}' if fnt == ''\n    if fnt.kind_of?(TkFont)\n      fnt.metrics(option)\n    else\n      metrics_core(fnt, nil, option)\n    end\n  end\n  def TkFont.metrics_hash(fnt, option=nil)\n    if option\n      val = TkFont.metrics(fnt, option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[TkFont.metrics(fnt)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def TkFont.metrics_displayof(fnt, win, option=nil)\n    fnt = '{}' if fnt == ''\n    if fnt.kind_of?(TkFont)\n      font.metrics_displayof(win, option=nil)\n    else\n      win = '.' unless win\n      metrics_core(fnt, win, option)\n    end\n  end\n  def TkFont.metrics_hash_displayof(fnt, win, option=nil)\n    if option\n      val = TkFont.metrics_displayof(fnt, win, option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[TkFont.metrics_displayof(fnt, win, option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def TkFont.families(win=nil)\n    case (Tk::TK_VERSION)\n    when /^4\\..*/\n      ['fixed']\n\n    when /^8\\..*/\n      if win\n        tk_split_simplelist(tk_call('font', 'families', '-displayof', win))\n      else\n        tk_split_simplelist(tk_call('font', 'families'))\n      end\n    end\n  end\n\n  def TkFont.names\n    case (Tk::TK_VERSION)\n    when /^4\\..*/\n      r = ['fixed']\n      r += ['a14', 'k14'] if JAPANIZED_TK\n      Tk_FontNameTBL.mutex.synchronize{\n        Tk_FontNameTBL.each_value{|obj| r.push(obj)}\n      }\n      #r | []\n      r.uniq\n\n    when /^8\\..*/\n      tk_split_simplelist(tk_call('font', 'names'))\n\n    end\n  end\n\n  def TkFont.create_copy(font)\n    fail 'source-font must be a TkFont object' unless font.kind_of? TkFont\n    if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      keys = {}\n      font.configinfo.each{|key,value| keys[key] = value }\n      TkFont.new(font.latin_font_id, font.kanji_font_id, keys)\n    else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      TkFont.new(font.latin_font_id, font.kanji_font_id, font.configinfo)\n    end\n  end\n\n  def TkFont.get_obj(name)\n    name = name.to_s\n    if name =~ /^(@font[0-9]+)(|c|l|k)$/\n      Tk_FontNameTBL.mutex.synchronize{\n        Tk_FontNameTBL[$1]\n      }\n    else\n      Tk_FontNameTBL.mutex.synchronize{\n        Tk_FontNameTBL[name]\n      }\n    end\n  end\n\n  def TkFont.init_widget_font(pathname, *args)\n    win, tag, key = pathname.split(';')\n    key = 'font' if key == nil || key == ''\n    path = [win, tag, key].join(';')\n\n    case (Tk::TK_VERSION)\n    when /^4\\..*/\n      regexp = /^-(|kanji)#{key} /\n\n      conf_list = tk_split_simplelist(tk_call(*args)).\n        find_all{|prop| prop =~ regexp}.\n        collect{|prop| tk_split_simplelist(prop)}\n\n      if conf_list.size == 0\n        raise RuntimeError, \"the widget may not support 'font' option\"\n      end\n\n      args << {}\n\n      ltn_key = \"-#{key}\"\n      knj_key = \"-kanji#{key}\"\n\n      ltn_info = conf_list.find{|conf| conf[0] == ltn_key}\n      ltn = ltn_info[-1]\n      ltn = nil if ltn == [] || ltn == \"\"\n\n      knj_info = conf_list.find{|conf| conf[0] == knj_key}\n      knj = knj_info[-1]\n      knj = nil if knj == [] || knj == \"\"\n\n      TkFont.new(ltn, knj).call_font_configure([path, key], *args)\n\n    when /^8\\.[0-4]/\n      regexp = /^-#{key} /\n\n      conf_list = tk_split_simplelist(tk_call(*args)).\n        find_all{|prop| prop =~ regexp}.\n        collect{|prop| tk_split_simplelist(prop)}\n\n      if conf_list.size == 0\n        raise RuntimeError, \"the widget may not support 'font' option\"\n      end\n\n      args << {}\n\n      optkey = \"-#{key}\"\n\n      info = conf_list.find{|conf| conf[0] == optkey}\n      fnt = info[-1]\n      fnt = nil if fnt == [] || fnt == \"\"\n\n      unless fnt\n        # create dummy\n        # TkFont.new(nil, nil).call_font_configure([path, key], *args)\n        dummy_fnt = TkFont.allocate\n        dummy_fnt.instance_eval{ init_dummy_fontobj() }\n        dummy_fnt\n      else\n        begin\n          compound = tk_split_simplelist(\n              Hash[*tk_split_simplelist(tk_call('font', 'configure', \n                                                fnt))].collect{|k,v|\n                [k[1..-1], v]\n              }.assoc('compound')[1])\n        rescue\n          compound = []\n        end\n        if compound == []\n          if TkFont.is_system_font?(fnt)\n            TkNamedFont.new(fnt).call_font_configure([path, key], *args)\n          else\n            TkFont.new(fnt).call_font_configure([path, key], *args)\n          end\n        else\n          TkFont.new(compound[0], \n                     compound[1]).call_font_configure([path, key], *args)\n        end\n      end\n\n    when /^8\\.[5-9]/, /^9\\..*/\n      regexp = /^-#{key} /\n\n      conf_list = tk_split_simplelist(tk_call(*args)).\n        find_all{|prop| prop =~ regexp}.\n        collect{|prop| tk_split_simplelist(prop)}\n\n      if conf_list.size == 0\n        raise RuntimeError, \"the widget may not support 'font' option\"\n      end\n\n      args << {}\n\n      optkey = \"-#{key}\"\n\n      info = conf_list.find{|conf| conf[0] == optkey}\n      fnt = info[-1]\n      fnt = nil if fnt == [] || fnt == \"\"\n\n      unless fnt\n        # create dummy\n        # TkFont.new(nil, nil).call_font_configure([path, key], *args)\n        dummy_fnt = TkFont.allocate\n        dummy_fnt.instance_eval{ init_dummy_fontobj() }\n        dummy_fnt\n      else\n        if TkFont.is_system_font?(fnt)\n          TkNamedFont.new(fnt).call_font_configure([path, key], *args)\n        else\n          TkFont.new(fnt).call_font_configure([path, key], *args)\n        end\n      end\n    end\n  end\n\n  def TkFont.used_on(path=nil)\n    Tk_FontUseTBL.mutex.synchronize{\n      if path\n        Tk_FontUseTBL[path]\n      else\n        # Tk_FontUseTBL.values | []\n        Tk_FontUseTBL.values.uniq\n      end\n    }\n  end\n\n  def TkFont.failsafe(font)\n    begin\n      if /^8\\..*/ === Tk::TK_VERSION  && JAPANIZED_TK\n        tk_call('font', 'failsafe', font)\n      end\n    rescue\n    end\n  end\n\n  ###################################\n  # instance methods\n  ###################################\n  private\n  ###################################\n  def init_dummy_fontobj\n    Tk_FontID.mutex.synchronize{\n      @id = Tk_FontID.join(TkCore::INTERP._ip_id_)\n      Tk_FontID[1].succ!\n    }\n    Tk_FontNameTBL.mutex.synchronize{\n      Tk_FontNameTBL[@id] = self\n    }\n\n    # @latin_desscendant = nil\n    # @kanji_desscendant = nil\n    @descendant = [nil, nil] # [latin, kanji]\n\n    case (Tk::TK_VERSION)\n    when /^4\\..*/\n      @latinfont = \"\"\n      @kanjifont = \"\"\n      if JAPANIZED_TK\n        @compoundfont = [[@latinfont], [@kanjifont]]\n        @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont}\n      else\n        @compoundfont = @latinfont\n        @fontslot = {'font'=>@latinfont}\n      end\n    else\n      @latinfont = @id + 'l'\n      @kanjifont = @id + 'k'\n      @compoundfont = @id + 'c'\n\n      if JAPANIZED_TK\n        tk_call('font', 'create', @latinfont, '-charset', 'iso8859')\n        tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983')\n        tk_call('font', 'create', @compoundfont, \n                '-compound', [@latinfont, @kanjifont])\n      else\n        tk_call('font', 'create', @latinfont)\n        tk_call('font', 'create', @kanjifont)\n        tk_call('font', 'create', @compoundfont)\n      end\n\n      @fontslot = {'font'=>@compoundfont}\n    end\n\n    self\n  end\n\n  def initialize(ltn=nil, knj=nil, keys=nil)\n    ltn = '{}' if ltn == ''\n    knj = '{}' if knj == ''\n\n    Tk_FontID.mutex.synchronize{\n      # @id = Tk_FontID.join('')\n      @id = Tk_FontID.join(TkCore::INTERP._ip_id_)\n      Tk_FontID[1].succ!\n    }\n    Tk_FontNameTBL.mutex.synchronize{\n      Tk_FontNameTBL[@id] = self\n    }\n\n    # @latin_desscendant = nil\n    # @kanji_desscendant = nil\n    @descendant = [nil, nil] # [latin, kanji]\n\n    # @latinfont = @id + 'l'\n    # @kanjifont = @id + 'k'\n    # @compoundfont = @id + 'c'\n    # @fontslot = {}\n\n    if knj.kind_of?(Hash) && !keys\n      keys = knj\n      knj = nil\n    end\n\n    # compound font check\n    if Tk::TK_VERSION == '8.0' && JAPANIZED_TK\n      begin\n        compound = tk_split_simplelist(tk_call('font', 'configure', \n                                               ltn, '-compound'))\n        if knj == nil\n          if compound != []\n            ltn, knj = compound\n          end\n        else\n          if compound != []\n            ltn = compound[0]\n          end\n          compound = tk_split_simplelist(tk_call('font', 'configure', \n                                                 knj, '-compound'))\n          if compound != []\n            knj = compound[1]\n          end\n        end\n      rescue\n      end\n    end\n\n    if ltn\n      if JAPANIZED_TK && !knj\n        if Tk::TK_VERSION =~ /^4..*/\n          knj = DEFAULT_KANJI_FONT_NAME\n        else\n          knj = ltn \n        end\n      end\n    else\n      ltn = DEFAULT_LATIN_FONT_NAME\n      knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj\n    end\n\n    create_compoundfont(ltn, knj, keys)\n  end\n\n  def initialize_copy(font)\n    unless font.kind_of?(TkFont)\n      fail TypeError, '\"initialize_copy should take same class object'\n    end\n    if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      keys = {}\n      font.configinfo.each{|key,value| keys[key] = value }\n      initialize(font.latin_font_id, font.kanji_font_id, keys)\n    else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      initialize(font.latin_font_id, font.kanji_font_id, font.configinfo)\n    end\n  end\n\n  def _get_font_info_from_hash(font)\n    font = _symbolkey2str(font)\n    foundry  = (info = font['foundry'] .to_s)?  info: '*'\n    family   = (info = font['family']  .to_s)?  info: '*'\n    weight   = (info = font['weight']  .to_s)?  info: '*'\n    slant    = (info = font['slant']   .to_s)?  info: '*'\n    swidth   = (info = font['swidth']  .to_s)?  info: '*'\n    adstyle  = (info = font['adstyle'] .to_s)?  info: '*'\n    pixels   = (info = font['pixels']  .to_s)?  info: '*'\n    points   = (info = font['points']  .to_s)?  info: '*'\n    resx     = (info = font['resx']    .to_s)?  info: '*'\n    resy     = (info = font['resy']    .to_s)?  info: '*'\n    space    = (info = font['space']   .to_s)?  info: '*'\n    avgWidth = (info = font['avgWidth'].to_s)?  info: '*'\n    charset  = (info = font['charset'] .to_s)?  info: '*'\n    encoding = (info = font['encoding'].to_s)?  info: '*'\n\n    [foundry, family, weight, slant, swidth, adstyle,\n      pixels, points, resx, resy, space, avgWidth, charset, encoding]\n  end\n\n  def create_latinfont_tk4x(font)\n    if font.kind_of? Hash\n      @latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-'\n\n    elsif font.kind_of? Array\n      finfo = {}\n      finfo['family'] = font[0].to_s\n      if font[1]\n        fsize = font[1].to_s\n        if fsize != '0' && fsize =~ /^(|\\+|-)([0-9]+)$/\n          if $1 == '-'\n            finfo['pixels'] = $2\n          else\n            finfo['points'] = $2\n          end\n        else\n          finfo['points'] = '13'\n        end\n      end\n      font[2..-1].each{|style|\n        case (style)\n        when 'normal'\n          finfo['weight'] = style\n        when 'bold'\n          finfo['weight'] = style\n        when 'roman'\n          finfo['slant'] = 'r'\n        when 'italic'\n          finfo['slant'] = 'i'\n        end\n      }\n\n      @latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'\n\n    elsif font.kind_of? TkFont\n      @latinfont = font.latin_font\n\n    else\n      if font\n        @latinfont = font\n      else\n        @latinfont = DEFAULT_LATIN_FONT_NAME\n      end\n\n    end\n  end\n\n  def create_kanjifont_tk4x(font)\n    unless JAPANIZED_TK\n      @kanjifont = \"\"\n      return\n    end\n\n    if font.kind_of? Hash\n      @kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-'\n\n    elsif font.kind_of? Array\n      finfo = {}\n      finfo['family'] = font[0].to_s\n      if font[1]\n        fsize = font[1].to_s\n        if fsize != '0' && fsize =~ /^(|\\+|-)([0-9]+)$/\n          if $1 == '-'\n            finfo['pixels'] = $2\n          else\n            finfo['points'] = $2\n          end\n        else\n          finfo['points'] = '13'\n        end\n      end\n      font[2..-1].each{|style|\n        case (style)\n        when 'normal'\n          finfo['weight'] = style\n        when 'bold'\n          finfo['weight'] = style\n        when 'roman'\n          finfo['slant'] = 'r'\n        when 'italic'\n          finfo['slant'] = 'i'\n        end\n      }\n\n      @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'\n    elsif font.kind_of? TkFont\n      @kanjifont = font.kanji_font_id\n    else\n      if font\n        @kanjifont = font\n      else\n        @kanjifont = DEFAULT_KANJI_FONT_NAME\n      end\n    end\n  end\n\n  def create_compoundfont_tk4x(ltn, knj, keys)\n    create_latinfont(ltn)\n    create_kanjifont(knj)\n\n    if JAPANIZED_TK\n      @compoundfont = [[@latinfont], [@kanjifont]]\n      @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont}\n      # @fontslot.clear\n      # @fontslot['font'] = @latinfont\n      # @fontslot['kanjifont'] = @kanjifont\n    else\n      @compoundfont = @latinfont\n      @fontslot = {'font'=>@latinfont}\n      # @fontslot.clear\n      # @fontslot['font'] = @latinfont\n    end\n  end\n\n  def create_latinfont_tk8x(font)\n    @latinfont = @id + 'l'\n\n    if JAPANIZED_TK\n      if font.kind_of? Hash\n        if font[:charset] || font['charset']\n          tk_call('font', 'create', @latinfont, *hash_kv(font))\n        else\n          tk_call('font', 'create', @latinfont, \n                  '-charset', 'iso8859', *hash_kv(font))\n        end\n      elsif font.kind_of? Array\n        tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font))\n        tk_call('font', 'configure', @latinfont, '-charset', 'iso8859')\n      elsif font.kind_of? TkFont\n        tk_call('font', 'create', @latinfont, '-copy', font.latin_font)\n      elsif font\n        tk_call('font', 'create', @latinfont, '-copy', font, \n                '-charset', 'iso8859')\n      else\n        tk_call('font', 'create', @latinfont, '-charset', 'iso8859')\n      end\n    else\n      if font.kind_of? Hash\n        tk_call('font', 'create', @latinfont, *hash_kv(font))\n      else\n        keys = {}\n        if font.kind_of? Array\n          actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}\n        elsif font.kind_of? TkFont\n          actual_core(font.latin_font).each{|key,val| keys[key] = val}\n        elsif font\n          actual_core(font).each{|key,val| keys[key] = val}\n        end\n        tk_call('font', 'create', @latinfont, *hash_kv(keys))\n      end\n\n      if font && @compoundfont\n        keys = {}\n        actual_core(@latinfont).each{|key,val| keys[key] = val}\n        tk_call('font', 'configure', @compoundfont, *hash_kv(keys))\n      end\n    end\n  end\n\n  def create_kanjifont_tk8x(font)\n    @kanjifont = @id + 'k'\n\n    if JAPANIZED_TK\n      if font.kind_of? Hash\n        if font[:charset] || font['charset']\n          tk_call('font', 'create', @kanjifont, *hash_kv(font))\n        else\n          tk_call('font', 'create', @kanjifont, \n                  '-charset', 'jisx0208.1983', *hash_kv(font))\n        end\n      elsif font.kind_of? Array\n        tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font))\n        tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983')\n      elsif font.kind_of? TkFont\n        tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font_id)\n      elsif font\n        tk_call('font', 'create', @kanjifont, '-copy', font, \n                '-charset', 'jisx0208.1983')\n      else\n        tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983')\n      end\n      # end of JAPANIZED_TK\n\n    else\n      if font.kind_of? Hash\n        tk_call('font', 'create', @kanjifont, *hash_kv(font))\n      else\n        keys = {}\n        if font.kind_of? Array\n          actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}\n        elsif font.kind_of? TkFont\n          actual_core(font.kanji_font_id).each{|key,val| keys[key] = val}\n        elsif font\n          actual_core(font).each{|key,val| keys[key] = val}\n        end\n        tk_call('font', 'create', @kanjifont, *hash_kv(keys))\n      end\n\n      if font && @compoundfont\n        keys = {}\n        actual_core(@kanjifont).each{|key,val| keys[key] = val}\n        tk_call('font', 'configure', @compoundfont, *hash_kv(keys))\n      end\n    end\n  end\n\n  def create_compoundfont_tk8x(ltn, knj, keys)\n    if knj\n      create_latinfont(ltn)\n      create_kanjifont(knj)\n    else\n      cfnt = ltn\n      create_kanjifont(cfnt)\n      create_latinfont(cfnt)\n    end\n\n    @compoundfont = @id + 'c'\n\n    if JAPANIZED_TK\n      unless keys\n        keys = {}\n      else\n        keys = keys.dup\n      end\n      if (tk_call('font', 'configure', @latinfont, '-underline') == '1' &&\n          tk_call('font', 'configure', @kanjifont, '-underline') == '1' &&\n          !keys.key?('underline'))\n        keys['underline'] = true\n      end\n      if (tk_call('font', 'configure', @latinfont, '-overstrike') == '1' &&\n          tk_call('font', 'configure', @kanjifont, '-overstrike') == '1' &&\n          !keys.key?('overstrike'))\n        keys['overstrike'] = true\n      end\n\n      @fontslot = {'font'=>@compoundfont}\n      # @fontslot['font'] = @compoundfont\n      begin\n        tk_call('font', 'create', @compoundfont, \n                '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n      rescue RuntimeError => e\n        if ltn == knj\n          if e.message =~ /kanji font .* specified/\n            tk_call('font', 'delete', @latinfont)\n            create_latinfont(DEFAULT_LATIN_FONT_NAME)\n            opts = []\n            Hash[*(tk_split_simplelist(tk_call('font', 'configure', \n                                               @kanjifont)))].each{|k,v|\n              case k\n              when '-size', '-weight', '-slant', '-underline', '-overstrike'\n                opts << k << v\n              end\n            }\n            tk_call('font', 'configure', @latinfont, *opts)\n            tk_call('font', 'create', @compoundfont, \n                    '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n\n          elsif e.message =~ /ascii font .* specified/\n            tk_call('font', 'delete', @kanjifont)\n            create_kanjifont(DEFAULT_KANJI_FONT_NAME)\n            opts = []\n            Hash[*(tk_split_simplelist(tk_call('font', 'configure', \n                                               @latinfont)))].each{|k,v|\n              case k\n              when '-size', '-weight', '-slant', '-underline', '-overstrike'\n                opts << k << v\n              end\n            }\n            tk_call('font', 'configure', @kanjifont, *opts)\n            tk_call('font', 'create', @compoundfont, \n                    '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n\n          else\n            raise e\n          end\n        else\n          raise e\n        end\n      end\n    else\n      tk_call('font', 'create', @compoundfont)\n\n      latinkeys = {}\n      begin\n        actual_core(@latinfont).each{|key,val| latinkeys[key] = val}\n      rescue\n        latinkeys = {}\n      end\n      if latinkeys != {}\n        tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))\n      end\n\n      if knj\n        compoundkeys = nil\n        kanjikeys = {}\n        begin\n          actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val}\n        rescue\n          kanjikeys = {}\n        end\n        if kanjikeys != {}\n          tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys))\n        end\n      end\n\n      if cfnt\n        if cfnt.kind_of?(Hash)\n          compoundkeys = cfnt.dup\n        else\n          compoundkeys = {}\n          actual_core(cfnt).each{|key,val| compoundkeys[key] = val}\n        end\n        compoundkeys.update(_symbolkey2str(keys))\n        keys = compoundkeys\n      end\n\n      @fontslot = {'font'=>@compoundfont}\n      # @fontslot['font'] = @compoundfont\n      tk_call('font', 'configure', @compoundfont, *hash_kv(keys))\n    end\n  end\n\n  ###################################\n  public\n  ###################################\n  def inspect\n    sprintf(\"#<%s:%0x:%s>\", self.class.inspect, self.__id__, @compoundfont)\n  end\n\n  def method_missing(id, *args)\n    name = id.id2name\n    case args.length\n    when 1\n      if name[-1] == ?=\n        configure name[0..-2], args[0]\n        args[0]\n      else\n        configure name, args[0]\n        self\n      end\n    when 0\n      begin\n        configinfo name\n      rescue\n        super(id, *args)\n#        fail NameError, \"undefined local variable or method `#{name}' for #{self.to_s}\", error_at\n      end\n    else\n      super(id, *args)\n#      fail NameError, \"undefined method `#{name}' for #{self.to_s}\", error_at\n    end\n  end\n\n  def call_font_configure(path, *args)\n    if path.kind_of?(Array)\n      # [path, optkey]\n      win, tag = path[0].split(';')\n      optkey = path[1].to_s\n    else\n      win, tag, optkey = path.split(';')\n    end\n\n    fontslot = _symbolkey2str(@fontslot)\n    if optkey && optkey != \"\"\n      ltn = fontslot.delete('font')\n      knj = fontslot.delete('kanjifont')\n      fontslot[optkey] = ltn if ltn\n      fontslot[\"kanji#{optkey}\"] = knj if knj\n    end\n\n    keys = _symbolkey2str(args.pop).update(fontslot)\n    args.concat(hash_kv(keys))\n    begin\n      tk_call(*args)\n    rescue => e\n      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        fail e\n      end\n    end\n    Tk_FontUseTBL.mutex.synchronize{\n      Tk_FontUseTBL[[win, tag, optkey].join(';')] = self\n    }\n    self\n  end\n\n  def used\n    ret = []\n    table = nil\n    Tk_FontUseTBL.mutex.synchronize{\n      table = Tk_FontUseTBL.clone # to avoid deadlock\n    }\n    table.each{|key,value|\n      next unless self == value\n      if key.include?(';')\n        win, tag, optkey = key.split(';')\n        winobj = tk_tcl2ruby(win)\n        #if winobj.kind_of? TkText\n        if winobj.kind_of?(TkText) || winobj.kind_of?(Tk::Text)\n          if optkey\n            ret.push([winobj, winobj.tagid2obj(tag), optkey])\n          else\n            ret.push([winobj, winobj.tagid2obj(tag)])\n          end\n        #elsif winobj.kind_of? TkCanvas\n        elsif winobj.kind_of?(TkCanvas) || winobj.kind_of?(Tk::Canvas)\n          if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag\n            if optkey\n              ret.push([winobj, tagobj, optkey])\n            else\n              ret.push([winobj, tagobj])\n            end\n          elsif (tagobj = TkcItem.id2obj(winobj, tag)).kind_of? TkcItem\n            if optkey\n              ret.push([winobj, tagobj, optkey])\n            else\n              ret.push([winobj, tagobj])\n            end\n          else\n            if optkey\n              ret.push([winobj, tag, optkey])\n            else\n              ret.push([winobj, tag])\n            end\n          end\n        #elsif winobj.kind_of? TkMenu\n        elsif winobj.kind_of?(TkMenu) || winobj.kind_of?(Tk::Menu)\n          if optkey\n            ret.push([winobj, tag, optkey])\n          else\n            ret.push([winobj, tag])\n          end\n        else\n          if optkey\n            ret.push([win, tag, optkey])\n          else\n            ret.push([win, tag])\n          end\n        end\n      else\n        ret.push(tk_tcl2ruby(key))\n      end\n    }\n    ret\n  end\n\n  def id\n    @id\n  end\n\n  def to_eval\n    font\n  end\n\n  def font\n    @compoundfont\n  end\n  alias font_id font\n  alias name font\n  alias to_s font\n\n  def latin_font_id\n    @latinfont\n  end\n\n  def latin_font\n    # @latinfont\n    if @descendant[0] # [0] -> latin\n      @descendant[0]\n    else\n      @descendant[0] = DescendantFont.new(self, 'latin')\n    end\n=begin\n    if @latin_descendant\n      @latin_descendant\n    else\n      @latin_descendant = DescendantFont.new(self, 'latin')\n    end\n=end\n  end\n  alias latinfont latin_font\n\n  def kanji_font_id\n    @kanjifont\n  end\n\n  def kanji_font\n    # @kanjifont\n    if @descendant[1] # [1] -> kanji\n      @descendant[1]\n    else\n      @descendant[1] = DescendantFont.new(self, 'kanji')\n    end\n=begin\n    if @kanji_descendant\n      @kanji_descendant\n    else\n      @kanji_descendant = DescendantFont.new(self, 'kanji')\n    end\n=end\n  end\n  alias kanjifont kanji_font\n\n  def actual(option=nil)\n    actual_core(@compoundfont, nil, option)\n  end\n  def actual_hash(option=nil)\n    Hash[actual(option)]\n  end\n\n  def actual_displayof(win, option=nil)\n    win = '.' unless win\n    actual_core(@compoundfont, win, option)\n  end\n  def actual_hash_displayof(win, option=nil)\n    Hash[actual_displayof(win, option)]\n  end\n\n  def latin_actual(option=nil)\n    if @latinfont == nil\n      actual_core(@compoundfont, nil, option) # use @compoundfont\n    else\n      actual_core(@latinfont, nil, option)\n    end\n  end\n  def latin_actual_hash(option=nil)\n    Hash[latin_actual(option)]\n  end\n\n  def latin_actual_displayof(win, option=nil)\n    win = '.' unless win\n    if @latinfont == nil\n      actual_core(@compoundfont, win, option) # use @compoundfont\n    else\n      actual_core(@latinfont, win, option)\n    end\n  end\n  def latin_actual_hash_displayof(win, option=nil)\n    Hash[latin_actual_displayof(win, option)]\n  end\n\n  def kanji_actual(option=nil)\n    #if JAPANIZED_TK\n    if @kanjifont == nil\n      actual_core(@compoundfont, nil, option) # use @compoundfont\n    elsif @kanjifont != \"\"\n      actual_core(@kanjifont, nil, option)\n    else\n      actual_core_tk4x(nil, nil, option)\n    end\n  end\n  def kanji_actual_hash(option=nil)\n    Hash[kanji_actual(option)]\n  end\n\n  def kanji_actual_displayof(win, option=nil)\n    #if JAPANIZED_TK\n    if @kanjifont == nil\n      actual_core(@compoundfont, nil, option) # use @compoundfont\n    elsif @kanjifont != \"\"\n      win = '.' unless win\n      actual_core(@kanjifont, win, option)\n    else\n      actual_core_tk4x(nil, win, option)\n    end\n  end\n  def kanji_actual_hash_displayof(win, option=nil)\n    Hash[kanji_actual_displayof(win, option)]\n  end\n\n  def [](slot)\n    configinfo slot\n  end\n\n  def []=(slot, val)\n    configure slot, val\n    val\n  end\n\n  def configure(slot, value=None)\n    configure_core(@compoundfont, slot, value)\n    self\n  end\n\n  def configinfo(slot=nil)\n    configinfo_core(@compoundfont, slot)\n  end\n\n  def current_configinfo(slot=nil)\n    current_configinfo_core(@compoundfont, slot)\n  end\n\n  def delete\n    delete_core\n  end\n\n  def latin_configure(slot, value=None)\n    if JAPANIZED_TK\n      configure_core(@latinfont, slot, value)\n    else\n      configure(slot, value)\n    end\n    self\n  end\n\n  def latin_configinfo(slot=nil)\n    if JAPANIZED_TK\n      configinfo_core(@latinfont, slot)\n    else\n      configinfo(slot)\n    end\n  end\n  def latin_current_configinfo(slot=nil)\n    Hash[latin_configinfo(slot)]\n  end\n\n  def kanji_configure(slot, value=None)\n    #if JAPANIZED_TK\n    if @kanjifont == nil\n      configure_core(@compoundfont, slot, value) # use @compoundfont\n    elsif @kanjifont != \"\"\n      configure_core(@kanjifont, slot, value)\n      configure('size'=>configinfo('size')) # to reflect new configuration\n    else\n      #\"\"\n      configure(slot, value)\n    end\n    self\n  end\n\n  def kanji_configinfo(slot=nil)\n    #if JAPANIZED_TK\n    if @kanjifont == nil\n      configure_core(@compoundfont, slot) # use @compoundfont\n    elsif @kanjifont != \"\"\n      configinfo_core(@kanjifont, slot)\n    else\n      #[]\n      configinfo(slot)\n    end\n  end\n  def kanji_current_configinfo(slot=nil)\n    Hash[kanji_configinfo(slot)]\n  end\n\n  def replace(ltn, knj=None)\n    knj = ltn if knj == None\n    latin_replace(ltn)\n    kanji_replace(knj)\n    self\n  end\n\n  def latin_replace(ltn)\n    if @latinfont\n      latin_replace_core(ltn)\n      reset_pointadjust\n    else\n      # not compound font -> copy properties of ltn\n      latinkeys = {}\n      begin\n        actual_core(ltn).each{|key,val| latinkeys[key] = val}\n      rescue\n        latinkeys = {}\n      end\n      begin\n        tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))\n      rescue\n        # not exist? (deleted?) -> create font\n        tk_call('font', 'create', @compoundfont, *hash_kv(latinkeys))\n      end\n    end\n\n    self\n  end\n\n  def kanji_replace(knj)\n    return self unless @kanjifont  # ignore\n    kanji_replace_core(knj)\n    reset_pointadjust\n    self\n  end\n\n  def measure(text)\n    measure_core(@compoundfont, nil, text)\n  end\n\n  def measure_displayof(win, text)\n    win = '.' unless win\n    measure_core(@compoundfont, win, text)\n  end\n\n  def metrics(option=nil)\n    metrics_core(@compoundfont, nil, option)\n  end\n  def metrics_hash(option=nil)\n    if option\n      val = metrics(option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[metrics(option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def metrics_displayof(win, option=nil)\n    win = '.' unless win\n    metrics_core(@compoundfont, win, option)\n  end\n  def metrics_hash_displayof(win, option=nil)\n    if option\n      val = metrics_displayof(win, option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[metrics_displayof(win, option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def latin_metrics(option=nil)\n    if @latinfont == nil\n      metrics_core(@compoundfont, nil, option) # use @compoundfont\n    else\n      metrics_core(@latinfont, nil, option)\n    end\n  end\n  def latin_metrics_hash(option=nil)\n    if option\n      val = latin_metrics(option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[latin_metrics(option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def latin_metrics_displayof(win, option=nil)\n    win = '.' unless win\n    if @latinfont == nil\n      metrics_core(@compoundfont, win, option) # use @compoundfont\n    else\n      metrics_core(@latinfont, win, option)\n    end\n  end\n  def latin_metrics_hash_displayof(win, option=nil)\n    if option\n      val = latin_metrics_displayof(win, option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[latin_metrics_displayof(win, option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def kanji_metrics(option=nil)\n    if @latinfont == nil\n      metrics_core(@compoundfont, nil, option) # use @compoundfont\n    elsif JAPANIZED_TK\n      metrics_core(@kanjifont, nil, option)\n    else\n      metrics_core_tk4x(nil, nil, option)\n    end\n  end\n  def kanji_metrics_hash(option=nil)\n    if option\n      val = kanji_metrics(option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[kanji_metrics(option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def kanji_metrics_displayof(win, option=nil)\n    win = '.' unless win\n    if @latinfont == nil\n      metrics_core(@compoundfont, win, option) # use @compoundfont\n    elsif JAPANIZED_TK\n      metrics_core(@kanjifont, win, option)\n    else\n      metrics_core_tk4x(nil, win, option)\n    end\n  end\n  def kanji_metrics_hash_displayof(win, option=nil)\n    if option\n      val = kanji_metrics_displayof(win, option)\n      case TkFont::MetricsType[option.to_s]\n      when ?n\n        val = TkComm::num_or_str(val)\n      when ?b\n        val = TkComm::bool(val)\n      else\n        # do nothing\n      end\n      return val\n    end\n\n    h = Hash[kanji_metrics_displayof(win, option)]\n    h.keys.each{|k| \n      case TkFont::MetricsType[k.to_s]\n      when ?n\n        h[k] = TkComm::num_or_str(h[k])\n      when ?b\n        h[k] = TkComm::bool(h[k])\n      else\n        # do nothing\n      end\n    }\n    h\n  end\n\n  def reset_pointadjust\n    begin\n      if /^8\\..*/ === Tk::TK_VERSION  && JAPANIZED_TK\n        configure('pointadjust' => latin_actual.assoc('size')[1].to_f / \n                                      kanji_actual.assoc('size')[1].to_f )\n      end\n    rescue\n    end\n    self\n  end\n\n  ###################################\n  # private alias\n  ###################################\n  case (Tk::TK_VERSION)\n  when /^4\\..*/\n    alias create_latinfont        create_latinfont_tk4x\n    alias create_kanjifont        create_kanjifont_tk4x\n    alias create_compoundfont     create_compoundfont_tk4x\n\n  when /^8\\.[0-5]/\n    alias create_latinfont        create_latinfont_tk8x\n    alias create_kanjifont        create_kanjifont_tk8x\n    alias create_compoundfont     create_compoundfont_tk8x\n\n  else\n    alias create_latinfont        create_latinfont_tk8x\n    alias create_kanjifont        create_kanjifont_tk8x\n    alias create_compoundfont     create_compoundfont_tk8x\n\n  end\n\n  ###################################\n  # public alias\n  ###################################\n  alias ascii_font             latin_font\n  alias asciifont              latinfont\n  alias create_asciifont       create_latinfont\n  alias ascii_actual           latin_actual\n  alias ascii_actual_displayof latin_actual_displayof\n  alias ascii_configure        latin_configure\n  alias ascii_configinfo       latin_configinfo\n  alias ascii_replace          latin_replace\n  alias ascii_metrics          latin_metrics\n\n  ###################################\n=begin\n  def dup\n    TkFont.new(self)\n  end\n  def clone\n    TkFont.new(self)\n  end\n=end\nend\n\nmodule TkFont::CoreMethods\n  include Tk\n  extend TkCore\n\n  private\n\n  def actual_core_tk4x(font, win=nil, option=nil)\n    # dummy\n    if option == 'pointadjust' || option == :pointadjust\n        1.0\n    elsif option\n      case TkFont::OptionType[option.to_s]\n      when ?n\n        0\n      when ?b\n        false\n      else\n        ''\n      end\n    else\n      [['family',''], ['size',0], ['weight',''], ['slant',''], \n        ['underline',false], ['overstrike',false], ['charset',''], \n        ['pointadjust',0]]\n    end\n  end\n\n  def actual_core_tk8x(font, win=nil, option=nil)\n    font = '{}' if font == ''\n\n    if option == 'compound' || option == :compound\n      \"\"\n    elsif option\n      if win\n        val = tk_call('font', 'actual', font, \n                      \"-displayof\", win, \"-#{option}\")\n      else\n        val = tk_call('font', 'actual', font, \"-#{option}\")\n      end\n      case TkFont::OptionType[option.to_s]\n      when ?n\n        num_or_str(val)\n      when ?b\n        bool(val)\n      else\n        val\n      end\n    else\n      l = tk_split_simplelist(if win\n                                 tk_call('font', 'actual', font, \n                                                     \"-displayof\", win)\n                              else\n                                 tk_call('font', 'actual', font)\n                              end)\n      r = []\n      while key=l.shift\n        if key == '-compound'\n          l.shift\n        else\n          key = key[1..-1]\n          val = l.shift\n          case TkFont::OptionType[key]\n          when ?n\n            r.push [key, num_or_str(val)]\n          when ?b\n            r.push [key, bool(val)]\n          else\n            r.push [key, val]\n          end\n        end\n      end\n      r\n    end\n  end\n\n  def configure_core_tk4x(font, slot, value=None)\n    #\"\"\n    self\n  end\n\n  def configinfo_core_tk4x(font, option=nil)\n    # dummy\n    if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      if option == 'pointadjust' || option == :pointadjust\n        1.0\n      elsif option\n        case TkFont::OptionType[option.to_s]\n        when ?n\n          0\n        when ?b\n          false\n        else\n          ''\n        end\n      else\n        [['family',''], ['size',0], ['weight',''], ['slant',''], \n          ['underline',false], ['overstrike',false], ['charset',''], \n          ['pointadjust',1.0]]\n      end\n    else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      current_configinfo_core_tk4x(font, option)\n    end\n  end\n\n  def current_configinfo_core_tk4x(font, option=nil)\n    if option\n      case TkFont::OptionType[option.to_s]\n      when ?n\n        0\n      when ?b\n        false\n      else\n        ''\n      end\n    else\n      {'family'=>'', 'size'=>0, 'weight'=>'', 'slant'=>'', \n        'underline'=>false, 'overstrike'=>false, \n        'charset'=>false, 'pointadjust'=>1.0}\n    end\n  end\n\n  def configure_core_tk8x(font, slot, value=None)\n    if JAPANIZED_TK\n      begin\n        padjust = tk_call('font', 'configure', font, '-pointadjust')\n      rescue\n        padjust = nil\n      end\n    else\n      padjust = nil\n    end\n    if slot.kind_of? Hash\n      if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family))\n        slot = _symbolkey2str(slot)\n        configure_core_tk8x(font, 'family', slot.delete('family'))\n      end\n\n      if ((slot.key?('size') || slot.key?(:size)) && \n          padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust))\n        tk_call('font', 'configure', font, \n                '-pointadjust', padjust, *hash_kv(slot))\n      else\n        tk_call('font', 'configure', font, *hash_kv(slot))\n      end\n    elsif (slot == 'size' || slot == :size) && padjust != nil\n      tk_call('font', 'configure', font, \n              \"-#{slot}\", value, '-pointadjust', padjust)\n    elsif JAPANIZED_TK && (slot == 'family' || slot == :family)\n      # coumpund font?\n      begin\n        compound = tk_split_simplelist(tk_call('font', 'configure', \n                                               font, '-compound'))\n      rescue\n        tk_call('font', 'configure', font, '-family', value)\n        return self\n      end\n      if compound == []\n        tk_call('font', 'configure', font, '-family', value)\n        return self\n      end\n      ltn, knj = compound\n\n      lfnt = tk_call('font', 'create', '-copy', ltn)\n      begin\n        tk_call('font', 'configure', lfnt, '-family', value)\n        latin_replace_core_tk8x(lfnt)\n      rescue RuntimeError => e\n        fail e if $DEBUG\n      ensure\n        tk_call('font', 'delete', lfnt) if lfnt != ''\n      end\n\n      kfnt = tk_call('font', 'create', '-copy', knj)\n      begin\n        tk_call('font', 'configure', kfnt, '-family', value)\n        kanji_replace_core_tk8x(lfnt)\n      rescue RuntimeError => e\n        fail e if $DEBUG\n      ensure\n        tk_call('font', 'delete', kfnt) if kfnt != ''\n      end\n      \n    else\n      tk_call('font', 'configure', font, \"-#{slot}\", value)\n    end\n    self\n  end\n\n  def configinfo_core_tk8x(font, option=nil)\n    if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      if option == 'compound' || option == :compound\n        \"\"\n      elsif option\n        val = tk_call('font', 'configure', font, \"-#{option}\")\n        case TkFont::OptionType[option.to_s]\n        when ?n\n          num_or_str(val)\n        when ?b\n          bool(val)\n        else\n          val\n        end\n      else\n        l = tk_split_simplelist(tk_call('font', 'configure', font))\n        r = []\n        while key=l.shift\n          if key == '-compound'\n            l.shift\n          else\n            key = key[1..-1]\n            val = l.shift\n            case TkFont::OptionType[key]\n            when ?n\n              r.push [key, num_or_str(val)]\n            when ?b\n              r.push [key, bool(val)]\n            else\n              r.push [key, val]\n            end\n          end\n        end\n        r\n      end\n    else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      current_configinfo_core_tk8x(font, option)\n    end\n  end\n\n  def current_configinfo_core_tk8x(font, option=nil)\n    if option == 'compound'\n      \"\"\n    elsif option\n      val = tk_call('font', 'configure', font, \"-#{option}\")\n      case TkFont::OptionType[option.to_s]\n      when ?n\n        num_or_str(val)\n      when ?b\n        bool(val)\n      else\n        val\n      end\n    else\n      l = tk_split_simplelist(tk_call('font', 'configure', font))\n      h = {}\n      while key=l.shift\n        if key == '-compound'\n          l.shift\n        else\n          key = key[1..-1]\n          val = l.shift\n          case TkFont::OptionType[key]\n          when ?n\n            h[key] = num_or_str(val)\n          when ?b\n            h[key] = bool(val)\n          else\n            h[key] = val\n          end\n        end\n      end\n      h\n    end\n  end\n\n  def delete_core_tk4x\n    TkFont::Tk_FontNameTBL.mutex.synchronize{\n      TkFont::Tk_FontNameTBL.delete(@id)\n    }\n    TkFont::Tk_FontUseTBL.mutex.synchronize{\n      TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self}\n    }\n  end\n\n  def delete_core_tk8x\n    begin\n      tk_call('font', 'delete', @latinfont) if @latinfont\n    rescue\n    end\n    begin\n      tk_call('font', 'delete', @kanjifont) if @kanjifont\n    rescue\n    end\n    begin\n      tk_call('font', 'delete', @compoundfont) if @compoundfont\n    rescue\n    end\n    TkFont::Tk_FontNameTBL.mutex.synchronize{\n      TkFont::Tk_FontNameTBL.delete(@id)\n    }\n    TkFont::Tk_FontUseTBL.mutex.synchronize{\n      TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self}\n    }\n  end\n\n  def latin_replace_core_tk4x(ltn)\n    create_latinfont_tk4x(ltn)\n    @compoundfont[0] = [@latinfont] if JAPANIZED_TK\n    @fontslot['font'] = @latinfont\n    table = nil\n    TkFont::Tk_FontUseTBL.mutex.synchronize{\n      table = TkFont::Tk_FontUseTBL.clone\n    }\n    table.each{|w, fobj|\n      if self == fobj\n        begin\n          if w.include?(';')\n            win, tag, optkey = w.split(';')\n            optkey = 'font' if optkey == nil || optkey == ''\n            winobj = tk_tcl2ruby(win)\n#           winobj.tagfont_configure(tag, {'font'=>@latinfont})\n            #if winobj.kind_of? TkText\n            if winobj.kind_of?(TkText) || winobj.kind_of?(Tk::Text)\n              tk_call(win, 'tag', 'configure', tag, \"-#{optkey}\", @latinfont)\n            #elsif winobj.kind_of? TkCanvas\n            elsif winobj.kind_of?(TkCanvas) || winobj.kind_of?(Tk::Canvas)\n              tk_call(win, 'itemconfigure', tag, \"-#{optkey}\", @latinfont)\n            #elsif winobj.kind_of? TkMenu\n            elsif winobj.kind_of?(TkMenu) || winobj.kind_of?(Tk::Menu)\n              tk_call(win, 'entryconfigure', tag, \"-#{optkey}\", @latinfont)\n            else\n              raise RuntimeError, \"unknown widget type\"\n            end\n          else\n#           tk_tcl2ruby(w).font_configure('font'=>@latinfont)\n            tk_call(w, 'configure', '-font', @latinfont)\n          end\n        rescue\n          TkFont::Tk_FontUseTBL.mutex.synchronize{\n            TkFont::Tk_FontUseTBL.delete(w)\n          }\n        end\n      end\n    }\n    self\n  end\n\n  def kanji_replace_core_tk4x(knj)\n    return self unless JAPANIZED_TK\n\n    create_kanjifont_tk4x(knj)\n    @compoundfont[1] = [@kanjifont]\n    @fontslot['kanjifont'] = @kanjifont\n    table = nil\n    TkFont::Tk_FontUseTBL.mutex.synchronize{\n      table = TkFont::Tk_FontUseTBL.clone\n    }\n    table.dup.each{|w, fobj|\n      if self == fobj\n        begin\n          if w.include?(';')\n            win, tag, optkey = w.split(';')\n            optkey = 'kanjifont' unless optkey\n            winobj = tk_tcl2ruby(win)\n#           winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont})\n            #if winobj.kind_of? TkText\n            if winobj.kind_of?(TkText) || winobj.kind_of?(Tk::Text)\n              tk_call(win, 'tag', 'configure', tag, \"-#{optkey}\", @kanjifont)\n            #elsif winobj.kind_of? TkCanvas\n            elsif winobj.kind_of?(TkCanvas) || winobj.kind_of?(Tk::Canvas)\n              tk_call(win, 'itemconfigure', tag, \"-#{optkey}\", @kanjifont)\n            #elsif winobj.kind_of? TkMenu\n            elsif winobj.kind_of?(TkMenu) || winobj.kind_of?(Tk::Menu)\n              tk_call(win, 'entryconfigure', tag, \"-#{optkey}\", @latinfont)\n            else\n              raise RuntimeError, \"unknown widget type\"\n            end\n          else\n#           tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont)\n            tk_call(w, 'configure', '-kanjifont', @kanjifont)\n          end\n        rescue\n          Tk_FontUseTBL.mutex.synchronize{\n            TkFont::Tk_FontUseTBL.delete(w)\n          }\n        end\n      end\n    }\n    self\n  end\n\n  def latin_replace_core_tk8x(ltn)\n    ltn = '{}' if ltn == ''\n\n    if JAPANIZED_TK\n      begin\n        tk_call('font', 'delete', '@font_tmp')\n      rescue\n      end\n      begin\n        fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont)\n      rescue\n        #fnt_bup = ''\n        fnt_bup = TkFont::DEFAULT_LATIN_FONT_NAME\n      end\n    end\n\n    begin\n      tk_call('font', 'delete', @latinfont)\n    rescue\n    end\n    create_latinfont(ltn)\n\n    if JAPANIZED_TK\n      keys = self.configinfo\n      tk_call('font', 'delete', @compoundfont)\n      begin\n        tk_call('font', 'create', @compoundfont, \n                '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n=begin\n        latinkeys = {}\n        begin\n          actual_core(@latinfont).each{|key,val| latinkeys[key] = val}\n        rescue\n          latinkeys = {}\n        end\n        if latinkeys != {}\n          tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))\n        end\n=end\n      rescue RuntimeError => e\n        tk_call('font', 'delete', @latinfont)\n        if fnt_bup && fnt_bup != ''\n          tk_call('font', 'create', @latinfont, '-copy', fnt_bup)\n          tk_call('font', 'create', @compoundfont, \n                  '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n          tk_call('font', 'delete', fnt_bup)\n        else\n          fail e\n        end\n      end\n\n    else\n      latinkeys = {}\n      begin\n        actual_core(@latinfont).each{|key,val| latinkeys[key] = val}\n      rescue\n        latinkeys = {}\n      end\n      begin\n        tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))\n      rescue\n        # not exist? (deleted?) -> create font\n        tk_call('font', 'create', @compoundfont, *hash_kv(latinkeys))\n      end\n    end    \n    self\n  end\n\n  def kanji_replace_core_tk8x(knj)\n    knj = '{}' if knj == ''\n\n    if JAPANIZED_TK\n      begin\n        tk_call('font', 'delete', '@font_tmp')\n      rescue\n      end\n      begin\n        fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont)\n      rescue\n        #fnt_bup = ''\n        fnt_bup = TkFont::DEFAULT_KANJI_FONT_NAME\n      end\n    end\n\n    begin\n      tk_call('font', 'delete', @kanjifont)\n    rescue\n    end\n    create_kanjifont(knj)\n\n    if JAPANIZED_TK\n      keys = self.configinfo\n      tk_call('font', 'delete', @compoundfont)\n      begin\n        tk_call('font', 'create', @compoundfont, \n                '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n      rescue RuntimeError => e\n        tk_call('font', 'delete', @kanjifont)\n        if fnt_bup && fnt_bup != ''\n          tk_call('font', 'create', @kanjifont, '-copy', fnt_bup)\n          tk_call('font', 'create', @compoundfont, \n                  '-compound', [@latinfont, @kanjifont], *hash_kv(keys))\n          tk_call('font', 'delete', fnt_bup)\n        else\n          fail e\n        end\n      end\n    end    \n    self\n  end\n\n  def measure_core_tk4x(font, win, text)\n    0\n  end\n\n  def measure_core_tk8x(font, win, text)\n    font = '{}' if font == ''\n\n    if win\n      number(tk_call('font', 'measure', font, \n                     '-displayof', win, text))\n    else\n      number(tk_call('font', 'measure', font, text))\n    end\n  end\n\n  def metrics_core_tk4x(font, win, option=nil)\n    # dummy\n    if option\n      \"\"\n    else\n      [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]]\n    end\n  end\n\n  def metrics_core_tk8x(font, win, option=nil)\n    font = '{}' if font == ''\n\n    if option\n      if win\n        number(tk_call('font', 'metrics', font, \n                       \"-displayof\", win, \"-#{option}\"))\n      else\n        number(tk_call('font', 'metrics', font, \"-#{option}\"))\n      end\n    else\n      l = tk_split_list(if win\n                          tk_call('font','metrics',font,\"-displayof\",win)\n                        else\n                          tk_call('font','metrics',font)\n                        end)\n      r = []\n      while key=l.shift\n        r.push [key[1..-1], l.shift.to_i]\n=begin\n        if key == '-fixed'  # boolean value\n          r.push [key[1..-1], bool(l.shift)]\n        else\n          r.push [key[1..-1], l.shift.to_i]\n        end\n=end\n      end\n      r\n    end\n  end\n\n  ###################################\n  # private alias\n  ###################################\n  case (Tk::TK_VERSION)\n  when /^4\\..*/\n    alias actual_core             actual_core_tk4x\n    alias configure_core          configure_core_tk4x\n    alias configinfo_core         configinfo_core_tk4x\n    alias current_configinfo_core current_configinfo_core_tk4x\n    alias delete_core             delete_core_tk4x\n    alias latin_replace_core      latin_replace_core_tk4x\n    alias kanji_replace_core      kanji_replace_core_tk4x\n    alias measure_core            measure_core_tk4x\n    alias metrics_core            metrics_core_tk4x\n\n  when /^8\\.[0-5]/\n    alias actual_core             actual_core_tk8x\n    alias configure_core          configure_core_tk8x\n    alias configinfo_core         configinfo_core_tk8x\n    alias current_configinfo_core current_configinfo_core_tk8x\n    alias delete_core             delete_core_tk8x\n    alias latin_replace_core      latin_replace_core_tk8x\n    alias kanji_replace_core      kanji_replace_core_tk8x\n    alias measure_core            measure_core_tk8x\n    alias metrics_core            metrics_core_tk8x\n\n  else\n    alias actual_core             actual_core_tk8x\n    alias configure_core          configure_core_tk8x\n    alias configinfo_core         configinfo_core_tk8x\n    alias current_configinfo_core current_configinfo_core_tk8x\n    alias delete_core             delete_core_tk8x\n    alias latin_replace_core      latin_replace_core_tk8x\n    alias kanji_replace_core      kanji_replace_core_tk8x\n    alias measure_core            measure_core_tk8x\n    alias metrics_core            metrics_core_tk8x\n\n  end\nend\n\nclass TkFont\n  include TkFont::CoreMethods\n  extend  TkFont::CoreMethods\nend\n\nclass TkNamedFont < TkFont\n  # for built-in named fonts\n  def TkNamedFont.find(name)\n    name = name.to_s\n    unless (obj = Tk_FontNameTBL[name])\n      obj = self.new(name) if TkFont.is_system_font?(name)\n    end\n    obj\n  end\n\n  def TkNamedFont.new(name, keys=nil)\n    name = name.to_s\n    obj = nil\n    Tk_FontNameTBL.mutex.synchronize{\n      unless (obj = Tk_FontNameTBL[name])\n        (obj = self.allocate).instance_eval{\n          @id = @compoundfont = name.to_s\n          @latinfont = nil\n          @kanjifont = nil\n          @descendant = [self, self] # [latin, kanji] : dummy\n          Tk_FontNameTBL[@id] = self\n        }\n      end\n    }\n    obj.instance_eval{ initialize(name, keys) }\n    obj\n  end\n\n  ###########################\n  private\n  ###########################\n  def initialize(name, keys=nil)\n    @id = @compoundfont = name.to_s\n\n    # if not exist named font, create it.\n    begin\n      if keys\n        tk_call('font', 'configure', @compoundfont, keys)\n      else\n        tk_call('font', 'configure', @compoundfont)\n      end\n    rescue\n      # the named font doesn't exist -> create\n      if keys\n        tk_call('font', 'create', @compoundfont, keys)\n      else\n        tk_call('font', 'create', @compoundfont)\n      end\n    end\n  end\n\n  def create_latinfont(fnt)\n    # ignore\n  end\n  def create_kanjifont(fnt)\n    # ignore\n  end\n  def create_compoundfont(ltn, knj, keys)\n    # ignore\n  end\n\n  ###########################\n  public\n  ###########################\n  def latin_font_id\n    @compoundfont\n  end\n  def kanji_font_id\n    @compoundfont\n  end\nend\n\n#######################################\n# define system font names\n#######################################\nif Tk::TCL_MAJOR_VERSION > 8 || \n    (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)\n  # add standard fonts of Tcl/Tk 8.5+\n  TkFont::SYSTEM_FONT_NAMES.add [\n    'TkDefaultFont', 'TkTextFont', 'TkFixedFont', 'TkMenuFont', \n    'TkHeadingFont', 'TkCaptionFont', 'TkSmallCaptionFont', \n    'TkIconFont', 'TkTooltipFont'\n  ]\nend\n\n# platform-specific fonts\n#  -- windows\nTkFont::SYSTEM_FONT_NAMES.add [\n  'ansifixed', 'ansi', 'device', 'oemfixed', 'systemfixed', 'system'\n]\n\n#  --  macintosh, macosx\nTkFont::SYSTEM_FONT_NAMES.add ['system', 'application']\n\nif Tk::TCL_MAJOR_VERSION > 8 || \n    (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)\n  TkFont::SYSTEM_FONT_NAMES.add ['menu']\nend\n\n#  --  macosx (Aqua theme)\nif Tk::TCL_MAJOR_VERSION > 8 || \n    (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)\n  TkFont::SYSTEM_FONT_NAMES.add [\n    'systemSystemFont', 'systemEmphasizedSystemFont', \n    'systemSmallSystemFont', 'systemSmallEmphasizedSystemFont', \n    'systemApplicationFont', 'systemLabelFont', 'systemViewsFont', \n    'systemMenuTitleFont', 'systemMenuItemFont', 'systemMenuItemMarkFont', \n    'systemMenuItemCmdKeyFont', 'systemWindowTitleFont', \n    'systemPushButtonFont', 'systemUtilityWindowTitleFont', \n    'systemAlertHeaderFont', 'systemToolbarFont', 'systemMiniSystemFont', \n    'systemDetailSystemFont', 'systemDetailEmphasizedSystemFont'\n  ]\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/frame.rb",
    "content": "#\n# tk/frame.rb : treat frame widget\n#\nrequire 'tk'\n\nclass Tk::Frame<TkWindow\n  TkCommandNames = ['frame'.freeze].freeze\n  WidgetClassName = 'Frame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n################# old version\n#  def initialize(parent=nil, keys=nil)\n#    if keys.kind_of? Hash\n#      keys = keys.dup\n#      @classname = keys.delete('classname') if keys.key?('classname')\n#      @colormap  = keys.delete('colormap')  if keys.key?('colormap')\n#      @container = keys.delete('container') if keys.key?('container')\n#      @visual    = keys.delete('visual')    if keys.key?('visual')\n#    end\n#    super(parent, keys)\n#  end\n#\n#  def create_self\n#    s = []\n#    s << \"-class\"     << @classname if @classname\n#    s << \"-colormap\"  << @colormap  if @colormap\n#    s << \"-container\" << @container if @container\n#    s << \"-visual\"    << @visual    if @visual\n#    tk_call 'frame', @path, *s\n#  end\n#################\n\n  def __boolval_optkeys\n    super() << 'container'\n  end\n  private :__boolval_optkeys\n\n  def initialize(parent=nil, keys=nil)\n    my_class_name = nil\n    if self.class < WidgetClassNames[self.class::WidgetClassName]\n      my_class_name = self.class.name\n      my_class_name = nil if my_class_name == ''\n    end\n    if parent.kind_of? Hash\n      keys = _symbolkey2str(parent)\n    else\n      if keys\n        keys = _symbolkey2str(keys)\n        keys['parent'] = parent\n      else\n        keys = {'parent'=>parent}\n      end\n    end\n    if keys.key?('classname')\n       keys['class'] = keys.delete('classname')\n    end\n    @classname = keys['class']\n    @colormap  = keys['colormap']\n    @container = keys['container']\n    @visual    = keys['visual']\n    if !@classname && my_class_name\n      keys['class'] = @classname = my_class_name\n    end\n    if @classname.kind_of? TkBindTag\n      @db_class = @classname\n      @classname = @classname.id\n    elsif @classname\n      @db_class = TkDatabaseClass.new(@classname)\n    else\n      @db_class = self.class\n      @classname = @db_class::WidgetClassName\n    end\n    super(keys)\n  end\n\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('frame', @path, *hash_kv(keys))\n  #  else\n  #    tk_call_without_enc( 'frame', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def database_classname\n    @classname\n  end\n\n  def self.database_class\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      self\n    else\n      TkDatabaseClass.new(self.name)\n    end\n  end\n  def self.database_classname\n    self.database_class.name\n  end\n\n  def self.bind(*args, &b)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args, &b)\n    else\n      TkDatabaseClass.new(self.name).bind(*args, &b)\n    end\n  end\n  def self.bind_append(*args, &b)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args, &b)\n    else\n      TkDatabaseClass.new(self.name).bind_append(*args, &b)\n    end\n  end\n  def self.bind_remove(*args)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args)\n    else\n      TkDatabaseClass.new(self.name).bind_remove(*args)\n    end\n  end\n  def self.bindinfo(*args)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args)\n    else\n      TkDatabaseClass.new(self.name).bindinfo(*args)\n    end\n  end\nend\n\n#TkFrame = Tk::Frame unless Object.const_defined? :TkFrame\nTk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)\n"
  },
  {
    "path": "ext/tk/lib/tk/grid.rb",
    "content": "#\n# tk/grid.rb : control grid geometry manager\n#\nrequire 'tk'\n\nmodule TkGrid\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['grid'.freeze].freeze\n\n  def anchor(master, anchor=None)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    tk_call_without_enc('grid', 'anchor', master, anchor)\n  end\n\n  def bbox(master, *args)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    args.unshift(master)\n    list(tk_call_without_enc('grid', 'bbox', *args))\n  end\n\n=begin\n  def configure(win, *args)\n    if args[-1].kind_of?(Hash)\n      opts = args.pop\n    else\n      opts = {}\n    end\n    params = []\n    params.push(_epath(win))\n    args.each{|win|\n      case win\n      when '-', 'x', '^'  # RELATIVE PLACEMENT\n        params.push(win)\n      else\n        params.push(_epath(win))\n      end\n    }\n    opts.each{|k, v|\n      params.push(\"-#{k}\")\n      params.push((v.kind_of?(TkObject))? v.epath: v)\n    }\n    if Tk::TCL_MAJOR_VERSION < 8 ||\n        (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION <= 3)\n      if params[0] == '-' || params[0] == 'x' || params[0] == '^'\n        tk_call_without_enc('grid', *params)\n      else\n        tk_call_without_enc('grid', 'configure', *params)\n      end\n    else\n      tk_call_without_enc('grid', 'configure', *params)\n    end\n  end\n=end\n  def configure(*args)\n    if args[-1].kind_of?(Hash)\n      opts = args.pop\n    else\n      opts = {}\n    end\n    fail ArgumentError, 'no widget is given' if args.empty?\n    params = []\n    args.flatten(1).each{|win|\n      case win\n      when '-', ?-              # RELATIVE PLACEMENT (increase columnspan)\n        params.push('-')\n      when /^-+$/             # RELATIVE PLACEMENT (increase columnspan)\n        params.concat(win.to_s.split(//))\n      when '^', ?^              # RELATIVE PLACEMENT (increase rowspan)\n        params.push('^')\n      when /^\\^+$/             # RELATIVE PLACEMENT (increase rowspan)\n        params.concat(win.to_s.split(//))\n      when 'x', :x, ?x, nil, '' # RELATIVE PLACEMENT (empty column)\n        params.push('x')\n      when /^x+$/             # RELATIVE PLACEMENT (empty column)\n        params.concat(win.to_s.split(//))\n      else\n        params.push(_epath(win))\n      end\n    }\n    opts.each{|k, v|\n      params.push(\"-#{k}\")\n      params.push(_epath(v))  # have to use 'epath' (hash_kv() is unavailable)\n    }\n    if Tk::TCL_MAJOR_VERSION < 8 ||\n        (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION <= 3)\n      if params[0] == '-' || params[0] == 'x' || params[0] == '^'\n        tk_call_without_enc('grid', *params)\n      else\n        tk_call_without_enc('grid', 'configure', *params)\n      end\n    else\n      tk_call_without_enc('grid', 'configure', *params)\n    end\n  end\n  alias grid configure\n\n  def columnconfigure(master, index, args)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    tk_call_without_enc(\"grid\", 'columnconfigure', \n                        master, index, *hash_kv(args))\n  end\n  alias column columnconfigure\n\n  def rowconfigure(master, index, args)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    tk_call_without_enc(\"grid\", 'rowconfigure', master, index, *hash_kv(args))\n  end\n  alias row rowconfigure\n\n  def columnconfiginfo(master, index, slot=nil)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    if slot\n      case slot\n      when 'uniform', :uniform\n        tk_call_without_enc('grid', 'columnconfigure', \n                            master, index, \"-#{slot}\")\n      else\n        num_or_str(tk_call_without_enc('grid', 'columnconfigure', \n                                       master, index, \"-#{slot}\"))\n      end\n    else\n      #ilist = list(tk_call_without_enc('grid','columnconfigure',master,index))\n      ilist = simplelist(tk_call_without_enc('grid', 'columnconfigure', \n                                             master, index))\n      info = {}\n      while key = ilist.shift\n        case key\n        when 'uniform'\n          info[key[1..-1]] = ilist.shift\n        else\n          info[key[1..-1]] = tk_tcl2ruby(ilist.shift)\n        end\n      end\n      info\n    end\n  end\n\n  def rowconfiginfo(master, index, slot=nil)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    if slot\n      case slot\n      when 'uniform', :uniform\n        tk_call_without_enc('grid', 'rowconfigure', \n                            master, index, \"-#{slot}\")\n      else\n        num_or_str(tk_call_without_enc('grid', 'rowconfigure', \n                                       master, index, \"-#{slot}\"))\n      end\n    else\n      #ilist = list(tk_call_without_enc('grid', 'rowconfigure', master, index))\n      ilist = simplelist(tk_call_without_enc('grid', 'rowconfigure', \n                                             master, index))\n      info = {}\n      while key = ilist.shift\n        case key\n        when 'uniform'\n          info[key[1..-1]] = ilist.shift\n        else\n          info[key[1..-1]] = tk_tcl2ruby(ilist.shift)\n        end\n      end\n      info\n    end\n  end\n\n  def add(widget, *args)\n    configure(widget, *args)\n  end\n\n  def forget(*args)\n    return '' if args.size == 0\n    wins = args.collect{|win|\n      # (win.kind_of?(TkObject))? win.epath: win\n      _epath(win)\n    }\n    tk_call_without_enc('grid', 'forget', *wins)\n  end\n\n  def info(slave)\n    # slave = slave.epath if slave.kind_of?(TkObject)\n    slave = _epath(slave)\n    #ilist = list(tk_call_without_enc('grid', 'info', slave))\n    ilist = simplelist(tk_call_without_enc('grid', 'info', slave))\n    info = {}\n    while key = ilist.shift\n      #info[key[1..-1]] = ilist.shift\n      info[key[1..-1]] = tk_tcl2ruby(ilist.shift)\n    end\n    return info\n  end\n\n  def location(master, x, y)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    list(tk_call_without_enc('grid', 'location', master, x, y))\n  end\n\n  def propagate(master, mode=None)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    if mode == None\n      bool(tk_call_without_enc('grid', 'propagate', master))\n    else\n      tk_call_without_enc('grid', 'propagate', master, mode)\n    end\n  end\n\n  def remove(*args)\n    return '' if args.size == 0\n    wins = args.collect{|win|\n      # (win.kind_of?(TkObject))? win.epath: win\n      _epath(win)\n    }\n    tk_call_without_enc('grid', 'remove', *wins)\n  end\n\n  def size(master)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    list(tk_call_without_enc('grid', 'size', master))\n  end\n\n  def slaves(master, args)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    list(tk_call_without_enc('grid', 'slaves', master, *hash_kv(args)))\n  end\n\n  module_function :anchor, :bbox, :add, :forget, :propagate, :info\n  module_function :remove, :size, :slaves, :location\n  module_function :grid, :configure, :columnconfigure, :rowconfigure\n  module_function :column, :row, :columnconfiginfo, :rowconfiginfo\nend\n=begin\ndef TkGrid(win, *args)\n  if args[-1].kind_of?(Hash)\n    opts = args.pop\n  else\n    opts = {}\n  end\n  params = []\n  params.push((win.kind_of?(TkObject))? win.epath: win)\n  args.each{|win|\n    case win\n    when '-', 'x', '^'  # RELATIVE PLACEMENT\n      params.push(win)\n    else\n      params.push((win.kind_of?(TkObject))? win.epath: win)\n    end\n  }\n  opts.each{|k, v|\n    params.push(\"-#{k}\")\n    params.push((v.kind_of?(TkObject))? v.epath: v)\n  }\n  tk_call_without_enc(\"grid\", *params)\nend\n=end\n"
  },
  {
    "path": "ext/tk/lib/tk/image.rb",
    "content": "#\n# tk/image.rb : treat Tk image objects\n#\n\nrequire 'tk'\n\nclass TkImage<TkObject\n  include Tk\n\n  TkCommandNames = ['image'.freeze].freeze\n\n  Tk_IMGTBL = TkCore::INTERP.create_table\n\n  (Tk_Image_ID = ['i'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    Tk_IMGTBL.mutex.synchronize{ Tk_IMGTBL.clear }\n  }\n\n  def self.new(keys=nil)\n    if keys.kind_of?(Hash)\n      name = nil\n      if keys.key?(:imagename)\n        name = keys[:imagename]\n      elsif keys.key?('imagename')\n        name = keys['imagename']\n      end\n      if name\n        if name.kind_of?(TkImage)\n          obj = name\n        else\n          name = _get_eval_string(name)\n          obj = nil\n          Tk_IMGTBL.mutex.synchronize{\n            obj = Tk_IMGTBL[name]\n          }\n        end\n        if obj\n          if !(keys[:without_creating] || keys['without_creating'])\n            keys = _symbolkey2str(keys)\n            keys.delete('imagename')\n            keys.delete('without_creating')\n            obj.instance_eval{\n              tk_call_without_enc('image', 'create', \n                                  @type, @path, *hash_kv(keys, true))\n            }\n          end\n          return obj\n        end\n      end\n    end\n    (obj = self.allocate).instance_eval{\n      Tk_IMGTBL.mutex.synchronize{\n        initialize(keys)\n        Tk_IMGTBL[@path] = self\n      }\n    }\n    obj\n  end\n\n  def initialize(keys=nil)\n    @path = nil\n    without_creating = false\n    if keys.kind_of?(Hash)\n      keys = _symbolkey2str(keys)\n      @path = keys.delete('imagename')\n      without_creating = keys.delete('without_creating')\n    end\n    unless @path\n      Tk_Image_ID.mutex.synchronize{\n        # @path = Tk_Image_ID.join('')\n        @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_)\n        Tk_Image_ID[1].succ!\n      }\n    end\n    unless without_creating\n      tk_call_without_enc('image', 'create', \n                          @type, @path, *hash_kv(keys, true))\n    end\n  end\n\n  def delete\n    Tk_IMGTBL.mutex.synchronize{\n      Tk_IMGTBL.delete(@id) if @id\n    }\n    tk_call_without_enc('image', 'delete', @path)\n    self\n  end\n  def height\n    number(tk_call_without_enc('image', 'height', @path))\n  end\n  def inuse\n    bool(tk_call_without_enc('image', 'inuse', @path))\n  end\n  def itemtype\n    tk_call_without_enc('image', 'type', @path)\n  end\n  def width\n    number(tk_call_without_enc('image', 'width', @path))\n  end\n\n  def TkImage.names\n    Tk_IMGTBL.mutex.synchronize{\n      Tk.tk_call_without_enc('image', 'names').split.collect!{|id|\n        (Tk_IMGTBL[id])? Tk_IMGTBL[id] : id\n      }\n    }\n  end\n\n  def TkImage.types\n    Tk.tk_call_without_enc('image', 'types').split\n  end\nend\n\nclass TkBitmapImage<TkImage\n  def __strval_optkeys\n    super() + ['maskdata', 'maskfile']\n  end\n  private :__strval_optkeys\n\n  def initialize(*args)\n    @type = 'bitmap'\n    super(*args)\n  end\nend\n\nclass TkPhotoImage<TkImage\n  NullArgOptionKeys = [ \"shrink\", \"grayscale\" ]\n\n  def _photo_hash_kv(keys)\n    keys = _symbolkey2str(keys)\n    NullArgOptionKeys.collect{|opt|\n      if keys[opt]\n        keys[opt] = None\n      else\n        keys.delete(opt)\n      end\n    }\n    keys.collect{|k,v|\n      ['-' << k, v]\n    }.flatten\n  end\n  private :_photo_hash_kv\n\n  def initialize(*args)\n    @type = 'photo'\n    super(*args)\n  end\n\n  def blank\n    tk_send_without_enc('blank')\n    self\n  end\n\n  def cget_strict(option)\n    case option.to_s\n    when 'data', 'file'\n      tk_send 'cget', '-' << option.to_s\n    else\n      tk_tcl2ruby(tk_send('cget', '-' << option.to_s))\n    end\n  end\n  def cget(option)\n    unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      cget_strict(option)\n    else\n      begin\n        cget_strict(option)\n      rescue => e\n        if current_configinfo.has_key?(option.to_s)\n          # error on known option\n          fail e\n        else\n          # unknown option\n          nil\n        end\n      end\n    end\n  end\n\n  def copy(src, *opts)\n    if opts.size == 0\n      tk_send('copy', src)\n    elsif opts.size == 1 && opts[0].kind_of?(Hash)\n      tk_send('copy', src, *_photo_hash_kv(opts[0]))\n    else\n      # for backward compatibility\n      args = opts.collect{|term|\n        if term.kind_of?(String) && term.include?(?\\s)\n          term.split\n        else\n          term\n        end\n      }.flatten\n      tk_send('copy', src, *args)\n    end\n    self\n  end\n\n  def data(keys={})\n    #tk_send('data', *_photo_hash_kv(keys))\n    tk_split_list(tk_send('data', *_photo_hash_kv(keys)))\n  end\n\n  def get(x, y)\n    tk_send('get', x, y).split.collect{|n| n.to_i}\n  end\n\n  def put(data, *opts)\n    if opts == []\n      tk_send('put', data)\n    elsif opts.size == 1 && opts[0].kind_of?(Hash)\n      tk_send('put', data, *_photo_hash_kv(opts[0]))\n    else\n      # for backward compatibility\n      tk_send('put', data, '-to', *opts)\n    end\n    self\n  end\n\n  def read(file, *opts)\n    if opts.size == 0\n      tk_send('read', file)\n    elsif opts.size == 1 && opts[0].kind_of?(Hash)\n      tk_send('read', file, *_photo_hash_kv(opts[0]))\n    else\n      # for backward compatibility\n      args = opts.collect{|term|\n        if term.kind_of?(String) && term.include?(?\\s)\n          term.split\n        else\n          term\n        end\n      }.flatten\n      tk_send('read', file, *args)\n    end\n    self\n  end\n\n  def redither\n    tk_send 'redither'\n    self\n  end\n\n  def get_transparency(x, y)\n    bool(tk_send('transparency', 'get', x, y))\n  end\n  def set_transparency(x, y, st)\n    tk_send('transparency', 'set', x, y, st)\n    self\n  end\n\n  def write(file, *opts)\n    if opts.size == 0\n      tk_send('write', file)\n    elsif opts.size == 1 && opts[0].kind_of?(Hash)\n      tk_send('write', file, *_photo_hash_kv(opts[0]))\n    else\n      # for backward compatibility\n      args = opts.collect{|term|\n        if term.kind_of?(String) && term.include?(?\\s)\n          term.split\n        else\n          term\n        end\n      }.flatten\n      tk_send('write', file, *args)\n    end\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/itemconfig.rb",
    "content": "#\n# tk/itemconfig.rb : control item/tag configuration of widget\n#\nrequire 'tk'\nrequire 'tkutil'\nrequire 'tk/itemfont.rb'\n\nmodule TkItemConfigOptkeys\n  include TkUtil\n\n  def __item_optkey_aliases(id)\n    {}\n  end\n  private :__item_optkey_aliases\n\n  def __item_numval_optkeys(id)\n    []\n  end\n  private :__item_numval_optkeys\n\n  def __item_numstrval_optkeys(id)\n    []\n  end\n  private :__item_numstrval_optkeys\n\n  def __item_boolval_optkeys(id)\n    ['exportselection', 'jump', 'setgrid', 'takefocus']\n  end\n  private :__item_boolval_optkeys\n\n  def __item_strval_optkeys(id)\n    # maybe need to override\n    [\n      'text', 'label', 'show', 'data', 'file', 'maskdata', 'maskfile', \n      'activebackground', 'activeforeground', 'background', \n      'disabledforeground', 'disabledbackground', 'foreground', \n      'highlightbackground', 'highlightcolor', 'insertbackground', \n      'selectbackground', 'selectforeground', 'troughcolor'\n    ]\n  end\n  private :__item_strval_optkeys\n\n  def __item_listval_optkeys(id)\n    []\n  end\n  private :__item_listval_optkeys\n\n  def __item_numlistval_optkeys(id)\n    # maybe need to override\n    ['dash', 'activedash', 'disableddash']\n  end\n  private :__item_numlistval_optkeys\n\n  def __item_tkvariable_optkeys(id)\n    ['variable', 'textvariable']\n  end\n  private :__item_tkvariable_optkeys\n\n  def __item_val2ruby_optkeys(id)  # { key=>method, ... }\n    # The method is used to convert a opt-value to a ruby's object.\n    # When get the value of the option \"key\", \"method.call(id, val)\" is called.\n    {}\n  end\n  private :__item_val2ruby_optkeys\n\n  def __item_ruby2val_optkeys(id)  # { key=>method, ... }\n    # The method is used to convert a ruby's object to a opt-value.\n    # When set the value of the option \"key\", \"method.call(id, val)\" is called.\n    # That is, \"-#{key} #{method.call(id, value)}\".\n    {}\n  end\n  private :__item_ruby2val_optkeys\n\n  def __item_methodcall_optkeys(id)  # { key=>method, ... }\n    # Use the method for both of get and set.\n    # Usually, the 'key' will not be a widget option.\n    #\n    # maybe need to override\n    # {'coords'=>'coords'}\n    {}\n  end\n  private :__item_methodcall_optkeys\n\n  ################################################\n\n  def __item_keyonly_optkeys(id)  # { def_key=>(undef_key|nil), ... }\n    # maybe need to override\n    {}\n  end\n  private :__item_keyonly_optkeys\n\n\n  def __conv_item_keyonly_opts(id, keys)\n    return keys unless keys.kind_of?(Hash)\n    keyonly = __item_keyonly_optkeys(id)\n    keys2 = {}\n    keys.each{|k, v|\n      optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s}\n      if optkey\n        defkey, undefkey = optkey\n        if v\n          keys2[defkey.to_s] = None\n        else\n          keys2[undefkey.to_s] = None\n        end\n      else\n        keys2[k.to_s] = v\n      end\n    }\n    keys2\n  end\n\n  def itemconfig_hash_kv(id, keys, enc_mode = nil, conf = nil)\n    hash_kv(__conv_item_keyonly_opts(id, keys), enc_mode, conf)\n  end\nend\n\nmodule TkItemConfigMethod\n  include TkUtil\n  include TkTreatItemFont\n  include TkItemConfigOptkeys\n\n  def TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n    @mode || false\n  end\n  def TkItemConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode)\n    fail SecurityError, \"can't change the mode\" if $SAFE>=4\n    @mode = (mode)? true: false\n  end\n\n  def __item_cget_cmd(id)\n    # maybe need to override\n    [self.path, 'itemcget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    # maybe need to override\n    [self.path, 'itemconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_confinfo_cmd(id)\n    # maybe need to override\n    __item_config_cmd(id)\n  end\n  private :__item_confinfo_cmd\n\n  def __item_configinfo_struct(id)\n    # maybe need to override\n    {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, \n      :default_value=>3, :current_value=>4}\n  end\n  private :__item_configinfo_struct\n\n  ################################################\n\n  def tagid(tagOrId)\n    # maybe need to override\n    tagOrId\n  end\n\n  ################################################\n\n  def __itemcget_core(tagOrId, option)\n    orig_opt = option\n    option = option.to_s\n\n    if option.length == 0\n      fail ArgumentError, \"Invalid option `#{orig_opt.inspect}'\"\n    end\n\n    alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == option}\n    if real_name\n      option = real_name.to_s\n    end\n\n    if ( method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[option] )\n      optval = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\"))\n      begin\n        return method.call(tagOrId, optval)\n      rescue => e\n        warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n        return optval\n      end\n    end\n\n    if ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[option] )\n      return self.__send__(method, tagOrId)\n    end\n\n    case option\n    when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n      begin\n        number(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\")))\n      rescue\n        nil\n      end\n\n    when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n      num_or_str(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\")))\n\n    when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n      begin\n        bool(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\")))\n      rescue\n        nil\n      end\n\n    when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n      simplelist(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\")))\n\n    when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n      conf = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\"))\n      if conf =~ /^[0-9]/\n        list(conf)\n      else\n        conf\n      end\n\n    when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n      v = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\"))\n      (v.empty?)? nil: TkVarAccess.new(v)\n\n    when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n      _fromUTF8(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\")))\n\n    when /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/\n      fontcode = $1\n      fontkey  = $2\n      fnt = tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{fontkey}\")), true)\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(tagid(tagOrId), fontkey)\n      end\n      if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << \"-#{option}\")), true)\n    end\n  end\n  private :__itemcget_core\n\n  def itemcget(tagOrId, option)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      __itemcget_core(tagOrId, option)\n    else\n      begin\n        __itemcget_core(tagOrId, option)\n      rescue => e\n        begin\n          if __current_itemconfiginfo(tagOrId).has_key?(option.to_s)\n            # not tag error & option is known -> error on known option\n            fail e\n          else\n            # not tag error & option is unknown\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n  def itemcget_strict(tagOrId, option)\n    # never use TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n    __itemcget_core(tagOrId, option)\n  end\n\n  def __itemconfigure_core(tagOrId, slot, value=None)\n    if slot.kind_of? Hash\n      slot = _symbolkey2str(slot)\n\n      __item_optkey_aliases(tagid(tagOrId)).each{|alias_name, real_name|\n        alias_name = alias_name.to_s\n        if slot.has_key?(alias_name)\n          slot[real_name.to_s] = slot.delete(alias_name)\n        end\n      }\n\n      __item_methodcall_optkeys(tagid(tagOrId)).each{|key, method|\n        value = slot.delete(key.to_s)\n        self.__send__(method, tagOrId, value) if value\n      }\n\n      __item_ruby2val_optkeys(tagid(tagOrId)).each{|key, method|\n        key = key.to_s\n        slot[key] = method.call(tagOrId, slot[key]) if slot.has_key?(key)\n      }\n\n      __item_keyonly_optkeys(tagid(tagOrId)).each{|defkey, undefkey|\n        conf = slot.find{|kk, vv| kk == defkey.to_s}\n        if conf\n          k, v = conf\n          if v\n            slot[k] = None\n          else\n            slot[undefkey.to_s] = None if undefkey\n            slot.delete(k)\n          end\n        end\n      }\n\n      if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/})\n        tagfont_configure(tagid(tagOrId), slot)\n      elsif slot.size > 0\n        tk_call(*(__item_config_cmd(tagid(tagOrId)).concat(hash_kv(slot))))\n      end\n\n    else\n      orig_slot = slot\n      slot = slot.to_s\n      if slot.length == 0\n        fail ArgumentError, \"Invalid option `#{orig_slot.inspect}'\"\n      end\n\n      alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot}\n      if real_name\n        slot = real_name.to_s\n      end\n\n      if ( conf = __item_keyonly_optkeys(tagid(tagOrId)).find{|k, v| k.to_s == slot } )\n        defkey, undefkey = conf\n        if value\n          tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{defkey}\"))\n        elsif undefkey\n          tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{undefkey}\"))\n        end\n      elsif ( method = _symbolkey2str(__item_ruby2val_optkeys(tagid(tagOrId)))[slot] )\n        tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{slot}\" << method.call(tagOrId, value)))\n      elsif ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] )\n        self.__send__(method, tagOrId, value)\n      elsif (slot =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)\n        if value == None\n          tagfontobj(tagid(tagOrId), $2)\n        else\n          tagfont_configure(tagid(tagOrId), {slot=>value})\n        end\n      else\n        tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{slot}\" << value))\n      end\n    end\n    self\n  end\n  private :__itemconfigure_core\n\n  def __check_available_itemconfigure_options(tagOrId, keys)\n    id = tagid(tagOrId)\n\n    availables = self.__current_itemconfiginfo(id).keys\n\n    # add non-standard keys\n    availables |= __font_optkeys.map{|k|\n      [k.to_s, \"latin#{k}\", \"ascii#{k}\", \"kanji#{k}\"]\n    }.flatten\n    availables |= __item_methodcall_optkeys(id).keys.map{|k| k.to_s}\n    availables |= __item_keyonly_optkeys(id).keys.map{|k| k.to_s}\n\n    keys = _symbolkey2str(keys)\n\n    keys.delete_if{|k, v| !(availables.include?(k))}\n  end\n\n  def itemconfigure(tagOrId, slot, value=None)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      __itemconfigure_core(tagOrId, slot, value)\n    else\n      if slot.kind_of?(Hash)\n        begin\n          __itemconfigure_core(tagOrId, slot)\n        rescue\n          slot = __check_available_itemconfigure_options(tagOrId, slot)\n          __itemconfigure_core(tagOrId, slot) unless slot.empty?\n        end\n      else\n        begin\n          __itemconfigure_core(tagOrId, slot, value)\n        rescue => e\n          begin\n            if __current_itemconfiginfo(tagOrId).has_key?(slot.to_s)\n              # not tag error & option is known -> error on known option\n              fail e\n            else\n              # not tag error & option is unknown\n              nil\n            end\n          rescue\n            fail e  # tag error\n          end\n        end\n      end\n    end\n    self\n  end\n\n  def __itemconfiginfo_core(tagOrId, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)\n        fontkey  = $2\n        # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{fontkey}\"))))\n        conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{fontkey}\")), false, true)\n        conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = \n          conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]\n        if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n            || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n          fnt = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n          if TkFont.is_system_font?(fnt)\n            conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)\n          end\n          conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey)\n        elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n               && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \\\n               && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- )\n          conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = \n            conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1]\n        end\n        conf\n      else\n        if slot\n          slot = slot.to_s\n\n          alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot}\n          if real_name\n            slot = real_name.to_s\n          end\n\n          case slot\n          when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot]\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n              begin\n                val = method.call(tagOrId, optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n              begin\n                val = method.call(tagOrId, optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val\n            end\n\n          when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot]\n            return [slot, '', '', '', self.__send__(method, tagOrId)]\n\n          when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n              end\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n            end\n\n          when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n              end\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n            end\n\n          when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n            end\n\n          when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n          when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n              if v.empty?\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n              else\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v)\n              end\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n              if v.empty?\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n              else\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v)\n              end\n            end\n\n          else\n            # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_list(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), 0, false, true)\n          end\n          conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = \n            conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]\n\n          if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n              && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \\\n              && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- )\n            conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = \n              conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1]\n          end\n\n          conf\n\n        else\n          # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))))).collect{|conflist|\n          #   conf = tk_split_simplelist(conflist)\n          ret = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false).collect{|conflist|\n            conf = tk_split_simplelist(conflist, false, true)\n            conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = \n              conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]\n\n            optkey = conf[__item_configinfo_struct(tagid(tagOrId))[:key]]\n            case optkey\n            when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n              method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey]\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n                begin\n                  val = method(tagOrId, optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n                begin\n                  val = method.call(tagOrId, optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val\n              end\n\n            when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n              # do nothing\n\n            when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n                end\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              end\n\n            when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n                end\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              end\n\n            when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              end\n\n            when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n                if v.empty?\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v)\n                end\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n                if v.empty?\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v)\n                end\n              end\n\n            else\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                if conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]].index('{')\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) \n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) \n                end\n              end\n              if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n                if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]].index('{')\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) \n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) \n                end\n              end\n            end\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n                && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?- )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = \n                conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1]\n            end\n\n            conf\n          }\n\n          __item_font_optkeys(tagid(tagOrId)).each{|optkey|\n            optkey = optkey.to_s\n            fontconf = ret.assoc(optkey)\n            if fontconf && fontconf.size > 2\n              ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/}\n              fnt = fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n              if TkFont.is_system_font?(fnt)\n                fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)\n              end\n              fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey)\n              ret.push(fontconf)\n            end\n          }\n\n          __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method|\n            ret << [optkey.to_s, '', '', '', self.__send__(method, tagOrId)]\n          }\n\n          ret\n        end\n      end\n\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)\n        fontkey  = $2\n        # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{fontkey}\"))))\n        conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{fontkey}\")), false, true)\n        conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = \n          conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]\n\n        if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n            || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n          fnt = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n          if TkFont.is_system_font?(fnt)\n            conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)\n          end\n          conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), fontkey)\n          { conf.shift => conf }\n        elsif ( __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n               && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n          if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?-\n            conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = \n              conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1]\n          end\n          { conf[0] => conf[1] }\n        else\n          { conf.shift => conf }\n        end\n      else\n        if slot\n          slot = slot.to_s\n\n          alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot}\n          if real_name\n            slot = real_name.to_s\n          end\n\n          case slot\n          when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot]\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n              begin\n                val = method.call(tagOrId, optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n              begin\n                val = method.call(tagOrId, optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val\n            end\n\n          when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot]\n            return {slot => ['', '', '', self.__send__(method, tagOrId)]}\n\n          when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n              end\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                num_or_stre(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n            end\n\n          when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n              end\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              begin\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              rescue\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n            end\n\n          when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ )\n              conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n            end\n\n          when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n          when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n            conf = tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), false, true)\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n              v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n              if v.empty?\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n              else\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v)\n              end\n            end\n            if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n              v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n              if v.empty?\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n              else\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v)\n              end\n            end\n\n          else\n            # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))))\n            conf = tk_split_list(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")), 0, false, true)\n          end\n          conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = \n            conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]\n\n          if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n              && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n            if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?-\n              conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = \n                conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1]\n            end\n            { conf[0] => conf[1] }\n          else\n            { conf.shift => conf }\n          end\n\n        else\n          ret = {}\n          # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))))).each{|conflist|\n          #   conf = tk_split_simplelist(conflist)\n          tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false).each{|conflist|\n            conf = tk_split_simplelist(conflist, false, true)\n            conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = \n              conf[__item_configinfo_struct(tagid(tagOrId))[:key]][1..-1]\n\n            optkey = conf[__item_configinfo_struct(tagid(tagOrId))[:key]]\n            case optkey\n            when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n              method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey]\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                optval = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n                begin\n                  val = method.call(tagOrId, optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = val\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                optval = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n                begin\n                  val = method.call(tagOrId, optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = val\n              end\n\n            when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n              # do nothing\n\n            when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    number(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n                end\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    number(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  num_or_str(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              end\n\n            when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    bool(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n                end\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                begin\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    bool(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n                rescue\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  simplelist(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              end\n\n            when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] =~ /^[0-9]/ )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                  list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] =~ /^[0-9]/ )\n                conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                  list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n              end\n\n            when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                v = conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n                if v.empty?\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = nil\n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkVarAccess.new(v)\n                end\n              end\n              if ( conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] )\n                v = conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n                if v.empty?\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil\n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v)\n                end\n              end\n\n            else\n              if ( __item_configinfo_struct(tagid(tagOrId))[:default_value] \\\n                  && conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] )\n                if conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]].index('{')\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]) \n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = \n                    tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:default_value]])\n                end\n              end\n              if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]\n                if conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]].index('{')\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    tk_split_list(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]]) \n                else\n                  conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = \n                    tk_tcl2ruby(conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]])\n                end\n              end\n            end\n\n            if ( __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n                && conf.size == __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n              if conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][0] == ?-\n                conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] = \n                  conf[__item_configinfo_struct(tagid(tagOrId))[:alias]][1..-1]\n              end\n              ret[conf[0]] = conf[1]\n            else\n              ret[conf.shift] = conf\n            end\n          }\n\n          __item_font_optkeys(tagid(tagOrId)).each{|optkey|\n            optkey = optkey.to_s\n            fontconf = ret[optkey]\n            if fontconf.kind_of?(Array)\n              ret.delete(optkey)\n              ret.delete('latin' << optkey)\n              ret.delete('ascii' << optkey)\n              ret.delete('kanji' << optkey)\n              fnt = fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]]\n              if TkFont.is_system_font?(fnt)\n                fontconf[__item_configinfo_struct(tagid(tagOrId))[:default_value]] = TkNamedFont.new(fnt)\n              end\n              fontconf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = tagfontobj(tagid(tagOrId), optkey)\n              ret[optkey] = fontconf\n            end\n          }\n\n          __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method|\n            ret[optkey.to_s] = ['', '', '', self.__send__(method, tagOrId)]\n          }\n\n          ret\n        end\n      end\n    end\n  end\n  private :__itemconfiginfo_core\n\n  def itemconfiginfo(tagOrId, slot = nil)\n    if slot && TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      begin\n        __itemconfiginfo_core(tagOrId, slot)\n      rescue => e\n        begin\n          __itemconfiginfo_core(tagOrId)\n          # not tag error -> option is unknown\n          Array.new(__item_configinfo_struct.values.max).unshift(slot.to_s)\n        rescue\n          fail e  # tag error\n        end\n      end\n    else\n      __itemconfiginfo_core(tagOrId, slot)\n    end\n  end\n\n  def __current_itemconfiginfo(tagOrId, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        org_slot = slot\n        begin\n          conf = __itemconfiginfo_core(tagOrId, slot)\n          if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n              || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n            return {conf[0] => conf[-1]}\n          end\n          slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]]\n        end while(org_slot != slot)\n        fail RuntimeError, \n          \"there is a configure alias loop about '#{org_slot}'\"\n      else\n        ret = {}\n        __itemconfiginfo_core(tagOrId).each{|conf|\n          if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n              || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n            ret[conf[0]] = conf[-1]\n          end\n        }\n\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      __itemconfiginfo_core(tagOrId, slot).each{|key, conf|\n        ret[key] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n\n  def current_itemconfiginfo(tagOrId, slot = nil)\n    __current_itemconfiginfo(tagOrId, slot)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/itemfont.rb",
    "content": "#\n# tk/itemfont.rb : control font of widget items\n#\nrequire 'tk'\n\nmodule TkItemFontOptkeys\n  def __item_font_optkeys(id)\n    # maybe need to override\n    ['font']\n  end\n  private :__item_font_optkeys\nend\n\nmodule TkTreatItemFont\n  include TkItemFontOptkeys\n\n  def __item_pathname(id)\n    # maybe need to override\n    [self.path, id].join(';')\n  end\n  private :__item_pathname\n\n  ################################################\n\n  def tagfont_configinfo(tagOrId, key = nil)\n    optkeys = __item_font_optkeys(tagid(tagOrId))\n    if key && !optkeys.find{|opt| opt.to_s == key.to_s}\n      fail ArgumentError, \"unknown font option name `#{key}'\"\n    end\n\n    win, tag = __item_pathname(tagid(tagOrId)).split(';')\n\n    if key\n      pathname = [win, tag, key].join(';')\n      TkFont.used_on(pathname) || \n        TkFont.init_widget_font(pathname, \n                                *(__item_confinfo_cmd(tagid(tagOrId))))\n    elsif optkeys.size == 1\n      pathname = [win, tag, optkeys[0]].join(';')\n      TkFont.used_on(pathname) || \n        TkFont.init_widget_font(pathname, \n                                *(__item_confinfo_cmd(tagid(tagOrId))))\n    else\n      fonts = {}\n      optkeys.each{|key|\n        key = key.to_s\n        pathname = [win, tag, key].join(';')\n        fonts[key] = \n          TkFont.used_on(pathname) || \n          TkFont.init_widget_font(pathname, \n                                  *(__item_confinfo_cmd(tagid(tagOrId))))\n      }\n      fonts\n    end\n  end\n  alias tagfontobj tagfont_configinfo\n\n  def tagfont_configure(tagOrId, slot)\n    pathname = __item_pathname(tagid(tagOrId))\n\n    slot = _symbolkey2str(slot)\n\n    __item_font_optkeys(tagid(tagOrId)).each{|optkey|\n      optkey = optkey.to_s\n      l_optkey = 'latin' << optkey\n      a_optkey = 'ascii' << optkey\n      k_optkey = 'kanji' << optkey\n\n      if slot.key?(optkey)\n        fnt = slot.delete(optkey)\n        if fnt.kind_of?(TkFont)\n          slot.delete(l_optkey)\n          slot.delete(a_optkey)\n          slot.delete(k_optkey)\n\n          fnt.call_font_configure([pathname, optkey], \n                                  *(__item_config_cmd(tagid(tagOrId)) << {}))\n          next\n        else\n          if fnt\n            if (slot.key?(l_optkey) || \n                slot.key?(a_optkey) || \n                slot.key?(k_optkey))\n              fnt = TkFont.new(fnt)\n\n              lfnt = slot.delete(l_optkey)\n              lfnt = slot.delete(a_optkey) if slot.key?(a_optkey)\n              kfnt = slot.delete(k_optkey)\n\n              fnt.latin_replace(lfnt) if lfnt\n              fnt.kanji_replace(kfnt) if kfnt\n\n              fnt.call_font_configure([pathname, optkey], \n                                      *(__item_config_cmd(tagid(tagOrId)) << {}))\n              next\n            else\n              fnt = hash_kv(fnt) if fnt.kind_of?(Hash)\n              unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n                tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{optkey}\" << fnt))\n              else\n                begin\n                  tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{optkey}\" << fnt))\n                rescue => e\n                  # ignore\n                end\n              end\n            end\n          end\n          next\n        end\n      end\n\n      lfnt = slot.delete(l_optkey)\n      lfnt = slot.delete(a_optkey) if slot.key?(a_optkey)\n      kfnt = slot.delete(k_optkey)\n\n      if lfnt && kfnt\n        TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], \n                                                   *(__item_config_cmd(tagid(tagOrId)) << {}))\n      elsif lfnt\n        latintagfont_configure([lfnt, optkey])\n      elsif kfnt\n        kanjitagfont_configure([kfnt, optkey])\n      end\n    }\n\n    # configure other (without font) options\n    tk_call(*(__item_config_cmd(tagid(tagOrId)).concat(hash_kv(slot)))) if slot != {}\n    self\n  end\n\n  def latintagfont_configure(tagOrId, ltn, keys=nil)\n    if ltn.kind_of?(Array)\n      key = ltn[1]\n      ltn = ltn[0]\n    else\n      key = nil\n    end\n\n    optkeys = __item_font_optkeys(tagid(tagOrId))\n    if key && !optkeys.find{|opt| opt.to_s == key.to_s}\n      fail ArgumentError, \"unknown font option name `#{key}'\"\n    end\n\n    win, tag = __item_pathname(tagid(tagOrId)).split(';')\n\n    optkeys = [key] if key\n\n    optkeys.each{|optkey|\n      optkey = optkey.to_s\n\n      pathname = [win, tag, optkey].join(';')\n\n      if (fobj = TkFont.used_on(pathname))\n        fobj = TkFont.new(fobj) # create a new TkFont object\n      elsif Tk::JAPANIZED_TK\n        fobj = fontobj          # create a new TkFont object\n      else\n        ltn = hash_kv(ltn) if ltn.kind_of?(Hash)\n        unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n          tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{optkey}\" << ltn))\n        else\n          begin\n            tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{optkey}\" << ltn))\n          rescue => e\n            # ignore\n          end\n        end\n        next\n      end\n\n      if fobj.kind_of?(TkFont)\n        if ltn.kind_of?(TkFont)\n          conf = {}\n          ltn.latin_configinfo.each{|key,val| conf[key] = val}\n          if keys\n            fobj.latin_configure(conf.update(keys))\n          else\n            fobj.latin_configure(conf)\n          end\n        else\n          fobj.latin_replace(ltn)\n        end\n      end\n\n      fobj.call_font_configure([pathname, optkey], *(__item_config_cmd(tagid(tagOrId)) << {}))\n    }\n    self\n  end\n  alias asciitagfont_configure latintagfont_configure\n\n  def kanjitagfont_configure(tagOrId, knj, keys=nil)\n    if knj.kind_of?(Array)\n      key = knj[1]\n      knj = knj[0]\n    else\n      key = nil\n    end\n\n    optkeys = __item_font_optkeys(tagid(tagOrId))\n    if key && !optkeys.find{|opt| opt.to_s == key.to_s}\n      fail ArgumentError, \"unknown font option name `#{key}'\"\n    end\n\n    win, tag = __item_pathname(tagid(tagOrId)).split(';')\n\n    optkeys = [key] if key\n\n    optkeys.each{|optkey|\n      optkey = optkey.to_s\n\n      pathname = [win, tag, optkey].join(';')\n\n      if (fobj = TkFont.used_on(pathname))\n        fobj = TkFont.new(fobj) # create a new TkFont object\n      elsif Tk::JAPANIZED_TK\n        fobj = fontobj          # create a new TkFont object\n      else\n        knj = hash_kv(knj) if knj.kind_of?(Hash)\n        unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n          tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{optkey}\" << knj))\n        else\n          begin\n            tk_call(*(__item_config_cmd(tagid(tagOrId)) << \"-#{optkey}\" << knj))\n          rescue => e\n            # ignore\n          end\n        end\n        next\n      end\n\n      if fobj.kind_of?(TkFont)\n        if knj.kind_of?(TkFont)\n          conf = {}\n          knj.kanji_configinfo.each{|key,val| conf[key] = val}\n          if keys\n            fobj.kanji_configure(conf.update(keys))\n          else\n            fobj.kanji_configure(conf)\n          end\n        else\n          fobj.kanji_replace(knj)\n        end\n      end\n\n      fobj.call_font_configure([pathname, optkey], *(__item_config_cmd(tagid(tagOrId)) << {}))\n    }\n    self\n  end\n\n  def tagfont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil)\n    if wintag\n      if winkey\n        fnt = win.tagfontobj(wintag, winkey).dup\n      else\n        fnt = win.tagfontobj(wintag).dup\n      end\n    else\n      if winkey\n        fnt = win.fontobj(winkey).dup\n      else\n        fnt = win.fontobj.dup\n      end\n    end\n\n    if targetkey\n      fnt.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], \n                              *(__item_config_cmd(tagid(tagOrId)) << {}))\n    else\n      fnt.call_font_configure(__item_pathname(tagid(tagOrId)), \n                              *(__item_config_cmd(tagid(tagOrId)) << {}))\n    end\n    self\n  end\n\n\n  def latintagfont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil)\n    if targetkey\n      fontobj(targetkey).dup.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], \n                                                 *(__item_config_cmd(tagid(tagOrId)) << {}))\n    else\n      fontobj.dup.call_font_configure(__item_pathname(tagid(tagOrId)), \n                                      *(__item_config_cmd(tagid(tagOrId)) << {}))\n    end\n\n    if wintag\n      if winkey\n        fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id)\n      else\n        fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id)\n      end\n    else\n      if winkey\n        fontobj.latin_replace(win.fontobj(winkey).latin_font_id)\n      else\n        fontobj.latin_replace(win.fontobj.latin_font_id)\n      end\n    end\n    self\n  end\n  alias asciitagfont_copy latintagfont_copy\n\n  def kanjifont_copy(tagOrId, win, wintag=nil, winkey=nil, targetkey=nil)\n    if targetkey\n      fontobj(targetkey).dup.call_font_configure([__item_pathname(tagid(tagOrId)), targetkey], \n                                                 *(__item_config_cmd(tagid(tagOrId)) << {}))\n    else\n        fontobj.dup.call_font_configure(__item_pathname(tagid(tagOrId)), \n                                        *(__item_config_cmd(tagid(tagOrId)) << {}))\n    end\n\n    if wintag\n      if winkey\n        fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id)\n      else\n        fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id)\n      end\n    else\n      if winkey\n        fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id)\n      else\n        fontobj.kanji_replace(win.fontobj.kanji_font_id)\n      end\n    end\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/kinput.rb",
    "content": "#\n# tk/kinput.rb : control kinput\n#\nrequire 'tk'\n\nmodule TkKinput\n  include Tk\n  extend Tk\n\n  TkCommandNames = [\n    'kinput_start'.freeze, \n    'kinput_send_spot'.freeze, \n    'kanjiInput'.freeze\n  ].freeze\n\n  def TkKinput.start(win, style=None)\n    tk_call('kinput_start', win, style)\n  end\n  def kinput_start(style=None)\n    TkKinput.start(self, style)\n  end\n\n  def TkKinput.send_spot(win)\n    tk_call('kinput_send_spot', win)\n  end\n  def kinput_send_spot\n    TkKinput.send_spot(self)\n  end\n\n  def TkKinput.input_start(win, keys=nil)\n    tk_call('kanjiInput', 'start', win, *hash_kv(keys))\n  end\n  def kanji_input_start(keys=nil)\n    TkKinput.input_start(self, keys)\n  end\n\n  def TkKinput.attribute_config(win, slot, value=None)\n    if slot.kind_of? Hash\n      tk_call('kanjiInput', 'attribute', win, *hash_kv(slot))\n    else\n      tk_call('kanjiInput', 'attribute', win, \"-#{slot}\", value)\n    end\n  end\n  def kinput_attribute_config(slot, value=None)\n    TkKinput.attribute_config(self, slot, value)\n  end\n\n  def TkKinput.attribute_info(win, slot=nil)\n    if slot\n      conf = tk_split_list(tk_call('kanjiInput', 'attribute', \n                                   win, \"-#{slot}\"))\n      conf[0] = conf[0][1..-1]\n      conf\n    else\n      tk_split_list(tk_call('kanjiInput', 'attribute', win)).collect{|conf|\n        conf[0] = conf[0][1..-1]\n        conf\n      }\n    end\n  end\n  def kinput_attribute_info(slot=nil)\n    TkKinput.attribute_info(self, slot)\n  end\n\n  def TkKinput.input_end(win)\n    tk_call('kanjiInput', 'end', win)\n  end\n  def kanji_input_end\n    TkKinput.input_end(self)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/label.rb",
    "content": "#\n# tk/label.rb : treat label widget\n#\nrequire 'tk'\n\nclass Tk::Label<TkWindow\n  TkCommandNames = ['label'.freeze].freeze\n  WidgetClassName = 'Label'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('label', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('label', @path)\n  #  end\n  #end\n  #private :create_self\nend\n\n#TkLabel = Tk::Label unless Object.const_defined? :TkLabel\nTk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)\n"
  },
  {
    "path": "ext/tk/lib/tk/labelframe.rb",
    "content": "#\n# tk/labelframe.rb : treat labelframe widget\n#\nrequire 'tk'\nrequire 'tk/frame'\n\nclass Tk::LabelFrame<Tk::Frame\n  TkCommandNames = ['labelframe'.freeze].freeze\n  WidgetClassName = 'Labelframe'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('labelframe', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('labelframe', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def __val2ruby_optkeys  # { key=>proc, ... }\n    super().update('labelwidget'=>proc{|v| window(v)})\n  end\n  private :__val2ruby_optkeys\nend\n\nTk::Labelframe = Tk::LabelFrame\n#TkLabelFrame = Tk::LabelFrame unless Object.const_defined? :TkLabelFrame\n#TkLabelframe = Tk::Labelframe unless Object.const_defined? :TkLabelframe\nTk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe)\n"
  },
  {
    "path": "ext/tk/lib/tk/listbox.rb",
    "content": "#\n# tk/listbox.rb : treat listbox widget\n#\nrequire 'tk'\nrequire 'tk/itemconfig'\nrequire 'tk/scrollable'\nrequire 'tk/txtwin_abst'\n\nmodule TkListItemConfig\n  include TkItemConfigMethod\n\n  def __item_listval_optkeys(id)\n    []\n  end\n  private :__item_listval_optkeys\nend\n\nclass Tk::Listbox<TkTextWin\n  include TkListItemConfig\n  include Scrollable\n\n  TkCommandNames = ['listbox'.freeze].freeze\n  WidgetClassName = 'Listbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('listbox', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('listbox', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def __tkvariable_optkeys\n    super() << 'listvariable'\n  end\n  private :__tkvariable_optkeys\n\n  def tagid(id)\n    #id.to_s\n    _get_eval_string(id)\n  end\n\n  def activate(y)\n    tk_send_without_enc('activate', y)\n    self\n  end\n  def curselection\n    list(tk_send_without_enc('curselection'))\n  end\n  def get(first, last=nil)\n    if last\n      # tk_split_simplelist(_fromUTF8(tk_send_without_enc('get', first, last)))\n      tk_split_simplelist(tk_send_without_enc('get', first, last), false, true)\n    else\n      _fromUTF8(tk_send_without_enc('get', first))\n    end\n  end\n  def nearest(y)\n    tk_send_without_enc('nearest', y).to_i\n  end\n  def size\n    tk_send_without_enc('size').to_i\n  end\n  def selection_anchor(index)\n    tk_send_without_enc('selection', 'anchor', index)\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send_without_enc('selection', 'clear', first, last)\n    self\n  end\n  def selection_includes(index)\n    bool(tk_send_without_enc('selection', 'includes', index))\n  end\n  def selection_set(first, last=None)\n    tk_send_without_enc('selection', 'set', first, last)\n    self\n  end\n\n  def index(idx)\n    tk_send_without_enc('index', idx).to_i\n  end\n\n  def value\n    get('0', 'end')\n  end\n\n  def value= (vals)\n    unless vals.kind_of?(Array)\n      fail ArgumentError, 'an Array is expected'\n    end\n    tk_send_without_enc('delete', '0', 'end')\n    tk_send_without_enc('insert', '0', \n                        *(vals.collect{|v| _get_eval_enc_str(v)}))\n    vals\n  end\n\n  def clear\n    tk_send_without_enc('delete', '0', 'end')\n    self\n  end\n  alias erase clear\n\n=begin\n  def itemcget(index, key)\n    case key.to_s\n    when 'text', 'label', 'show'\n      _fromUTF8(tk_send_without_enc('itemcget', index, \"-#{key}\"))\n    when 'font', 'kanjifont'\n      #fnt = tk_tcl2ruby(tk_send('itemcget', index, \"-#{key}\"))\n      fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', index, \n                                                      '-font')))\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(index, fnt)\n      end\n      if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(_fromUTF8(tk_send_without_enc('itemcget', index, \"-#{key}\")))\n    end\n  end\n  def itemconfigure(index, key, val=None)\n    if key.kind_of? Hash\n      if (key['font'] || key[:font] || \n          key['kanjifont'] || key[:kanjifont] || \n          key['latinfont'] || key[:latinfont] || \n          key['asciifont'] || key[:asciifont] )\n        tagfont_configure(index, _symbolkey2str(key))\n      else\n        tk_send_without_enc('itemconfigure', index, *hash_kv(key, true))\n      end\n\n    else\n      if (key == 'font' || key == :font || \n          key == 'kanjifont' || key == :kanjifont || \n          key == 'latinfont' || key == :latinfont || \n          key == 'asciifont' || key == :asciifont )\n        if val == None\n          tagfontobj(index)\n        else\n          tagfont_configure(index, {key=>val})\n        end\n      else\n        tk_call('itemconfigure', index, \"-#{key}\", val)\n      end\n    end\n    self\n  end\n\n  def itemconfiginfo(index, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'text', 'label', 'show'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,\"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,\"-#{key}\")))\n          conf[4] = tagfont_configinfo(index, conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure',index,\"-#{key}\")))\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', index))).collect{|conflist|\n          conf = tk_split_simplelist(conflist)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show'\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n        fontconf = ret.assoc('font')\n        if fontconf\n          ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}\n          fontconf[4] = tagfont_configinfo(index, fontconf[4])\n          ret.push(fontconf)\n        else\n          ret\n        end\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'text', 'label', 'show'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,\"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure',index,\"-#{key}\")))\n          conf[4] = tagfont_configinfo(index, conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('itemconfigure',index,\"-#{key}\")))\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        tk_split_simplelist(_fromUTF8(tk_send_without_enc('itemconfigure', index))).each{|conflist|\n          conf = tk_split_simplelist(conflist)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show'\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        fontconf = ret['font']\n        if fontconf\n          ret.delete('font')\n          ret.delete('kanjifont')\n          fontconf[3] = tagfont_configinfo(index, fontconf[3])\n          ret['font'] = fontconf\n        end\n        ret\n      end\n    end\n  end\n\n  def current_itemconfiginfo(index, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        conf = itemconfiginfo(index, key)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        itemconfiginfo(index).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      itemconfiginfo(index, key).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n=end\nend\n\n#TkListbox = Tk::Listbox unless Object.const_defined? :TkListbox\nTk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)\n"
  },
  {
    "path": "ext/tk/lib/tk/macpkg.rb",
    "content": "#\n#   tk/macpkg.rb : methods for Tcl/Tk packages for Macintosh\n#                     2000/11/22 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\n#     ATTENTION !!\n#         This is NOT TESTED. Because I have no test-environment.\n#\n#\nrequire 'tk'\n\nmodule Tk\n  def Tk.load_tclscript_rsrc(resource_name, file=None)\n    # Mac only\n    tk_call('source', '-rsrc', resource_name, file)\n  end\n\n  def Tk.load_tclscript_rsrcid(resource_id, file=None)\n    # Mac only\n    tk_call('source', '-rsrcid', resource_id, file)\n  end\nend\n\nmodule Tk::MacResource\nend\n#TkMacResource = Tk::MacResource\nTk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)\n\nmodule Tk::MacResource\n  extend Tk\n  extend Tk::MacResource\n\n  TkCommandNames = ['resource'.freeze].freeze\n\n  PACKAGE_NAME = 'resource'.freeze\n  def self.package_name\n    PACKAGE_NAME\n  end\n\n  tk_call_without_enc('package', 'require', 'resource')\n\n  def close(rsrcRef)\n    tk_call('resource', 'close', rsrcRef)\n  end\n\n  def delete(rsrcType, opts=nil)\n    tk_call('resource', 'delete', *(hash_kv(opts) << rsrcType))\n  end\n\n  def files(rsrcRef=nil)\n    if rsrcRef\n      tk_call('resource', 'files', rsrcRef)\n    else\n      tk_split_simplelist(tk_call('resource', 'files'))\n    end\n  end\n\n  def list(rsrcType, rsrcRef=nil)\n    tk_split_simplelist(tk_call('resource', 'list', rsrcType, rsrcRef))\n  end\n\n  def open(fname, access=nil)\n    tk_call('resource', 'open', fname, access)\n  end\n\n  def read(rsrcType, rsrcID, rsrcRef=nil)\n    tk_call('resource', 'read', rsrcType, rsrcID, rsrcRef)\n  end\n\n  def types(rsrcRef=nil)\n    tk_split_simplelist(tk_call('resource', 'types', rsrcRef))\n  end\n\n  def write(rsrcType, data, opts=nil)\n    tk_call('resource', 'write', *(hash_kv(opts) << rsrcType << data))\n  end\n\n  module_function :close, :delete, :files, :list, :open, :read, :types, :write\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/menu.rb",
    "content": "#\n# tk/menu.rb : treat menu and menubutton\n#\nrequire 'tk'\nrequire 'tk/itemconfig'\nrequire 'tk/menuspec'\n\nmodule TkMenuEntryConfig\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'entrycget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'entryconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_strval_optkeys(id)\n    super(id) << 'selectcolor'\n  end\n  private :__item_strval_optkeys\n\n  def __item_listval_optkeys(id)\n    []\n  end\n  private :__item_listval_optkeys\n\n  def __item_val2ruby_optkeys(id)  # { key=>proc, ... }\n    super(id).update('menu'=>proc{|i, v| window(v)})\n  end\n  private :__item_val2ruby_optkeys\n\n  alias entrycget itemcget\n  alias entrycget_strict itemcget_strict\n  alias entryconfigure itemconfigure\n  alias entryconfiginfo itemconfiginfo\n  alias current_entryconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\nend\n\nclass Tk::Menu<TkWindow\n  include Wm\n  include TkMenuEntryConfig\n  extend TkMenuSpec\n\n  TkCommandNames = ['menu'.freeze].freeze\n  WidgetClassName = 'Menu'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('menu', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('menu', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def __strval_optkeys\n    super() << 'selectcolor' << 'title'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'tearoff'\n  end\n  private :__boolval_optkeys\n\n  def self.new_menuspec(menu_spec, parent = nil, tearoff = false, keys = nil)\n    if parent.kind_of?(Hash)\n      keys = _symbolkey2str(parent)\n      parent = keys.delete('parent')\n      tearoff = keys.delete('tearoff')\n    elsif tearoff.kind_of?(Hash)\n      keys = _symbolkey2str(tearoff)\n      tearoff = keys.delete('tearoff')\n    elsif keys\n      keys = _symbolkey2str(keys)\n    else\n      keys = {}\n    end\n\n    widgetname = keys.delete('widgetname')\n    _create_menu(parent, menu_spec, widgetname, tearoff, keys)\n  end\n\n  def tagid(id)\n    #id.to_s\n    _get_eval_string(id)\n  end\n\n  def activate(index)\n    tk_send_without_enc('activate', _get_eval_enc_str(index))\n    self\n  end\n  def add(type, keys=nil)\n    tk_send_without_enc('add', type, *hash_kv(keys, true))\n    self\n  end\n  def add_cascade(keys=nil)\n    add('cascade', keys)\n  end\n  def add_checkbutton(keys=nil)\n    add('checkbutton', keys)\n  end\n  def add_command(keys=nil)\n    add('command', keys)\n  end\n  def add_radiobutton(keys=nil)\n    add('radiobutton', keys)\n  end\n  def add_separator(keys=nil)\n    add('separator', keys)\n  end\n\n  def clone_menu(*args)\n    if args[0].kind_of?(TkWindow)\n      parent = args.shift\n    else\n      parent = self\n    end\n\n    if args[0].kind_of?(String) || args[0].kind_of?(Symbol) # menu type\n      type = args.shift\n    else\n      type = None # 'normal'\n    end\n\n    if args[0].kind_of?(Hash)\n      keys = _symbolkey2str(args.shift)\n    else\n      keys = {}\n    end\n\n    parent = keys.delete('parent') if keys.has_key?('parent')\n    type = keys.delete('type') if keys.has_key?('type')\n\n    if keys.empty?\n      Tk::MenuClone.new(self, parent, type)\n    else\n      Tk::MenuClone.new(self, parent, type, keys)\n    end\n  end\n\n  def index(idx)\n    ret = tk_send_without_enc('index', _get_eval_enc_str(idx))\n    (ret == 'none')? nil: number(ret)\n  end\n  def invoke(index)\n    _fromUTF8(tk_send_without_enc('invoke', _get_eval_enc_str(index)))\n  end\n  def insert(index, type, keys=nil)\n    tk_send_without_enc('insert', _get_eval_enc_str(index), \n                        type, *hash_kv(keys, true))\n    self\n  end\n  def delete(first, last=nil)\n    if last\n      tk_send_without_enc('delete', _get_eval_enc_str(first), \n                          _get_eval_enc_str(last))\n    else\n      tk_send_without_enc('delete', _get_eval_enc_str(first))\n    end\n    self\n  end\n  def popup(x, y, index=nil)\n    if index\n      tk_call_without_enc('tk_popup', path, x, y, \n                          _get_eval_enc_str(index))\n    else\n      tk_call_without_enc('tk_popup', path, x, y)\n    end\n    self\n  end\n  def post(x, y)\n    _fromUTF8(tk_send_without_enc('post', x, y))\n  end\n  def postcascade(index)\n    tk_send_without_enc('postcascade', _get_eval_enc_str(index))\n    self\n  end\n  def postcommand(cmd=Proc.new)\n    configure_cmd 'postcommand', cmd\n    self\n  end\n  def set_focus\n    tk_call_without_enc('tk_menuSetFocus', path)\n    self\n  end\n  def tearoffcommand(cmd=Proc.new)\n    configure_cmd 'tearoffcommand', cmd\n    self\n  end\n  def menutype(index)\n    tk_send_without_enc('type', _get_eval_enc_str(index))\n  end\n  def unpost\n    tk_send_without_enc('unpost')\n    self\n  end\n  def xposition(index)\n    number(tk_send_without_enc('xposition', _get_eval_enc_str(index)))\n  end\n  def yposition(index)\n    number(tk_send_without_enc('yposition', _get_eval_enc_str(index)))\n  end\n\n=begin\n  def entrycget(index, key)\n    case key.to_s\n    when 'text', 'label', 'show'\n      _fromUTF8(tk_send_without_enc('entrycget', \n                                    _get_eval_enc_str(index), \"-#{key}\"))\n    when 'font', 'kanjifont'\n      #fnt = tk_tcl2ruby(tk_send('entrycget', index, \"-#{key}\"))\n      fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), '-font')))\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(index, fnt)\n      end\n      if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(_fromUTF8(tk_send_without_enc('entrycget', _get_eval_enc_str(index), \"-#{key}\")))\n    end\n  end\n  def entryconfigure(index, key, val=None)\n    if key.kind_of? Hash\n      if (key['font'] || key[:font] || \n          key['kanjifont'] || key[:kanjifont] || \n          key['latinfont'] || key[:latinfont] || \n          key['asciifont'] || key[:asciifont])\n        tagfont_configure(index, _symbolkey2str(key))\n      else\n        tk_send_without_enc('entryconfigure', _get_eval_enc_str(index), \n                            *hash_kv(key, true))\n      end\n\n    else\n      if (key == 'font' || key == :font || \n          key == 'kanjifont' || key == :kanjifont || \n          key == 'latinfont' || key == :latinfont || \n          key == 'asciifont' || key == :asciifont )\n        if val == None\n          tagfontobj(index)\n        else\n          tagfont_configure(index, {key=>val})\n        end\n      else\n        tk_call('entryconfigure', index, \"-#{key}\", val)\n      end\n    end\n    self\n  end\n\n  def entryconfiginfo(index, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'text', 'label', 'show'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),\"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),\"-#{key}\")))\n          conf[4] = tagfont_configinfo(index, conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),\"-#{key}\")))\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        ret = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).collect{|conflist|\n          conf = tk_split_simplelist(conflist)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show'\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n        if fontconf\n          ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}\n          fontconf[4] = tagfont_configinfo(index, fontconf[4])\n          ret.push(fontconf)\n        else\n          ret\n        end\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'text', 'label', 'show'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),\"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),\"-#{key}\")))\n          conf[4] = tagfont_configinfo(index, conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('entryconfigure',_get_eval_enc_str(index),\"-#{key}\")))\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        tk_split_simplelist(_fromUTF8(tk_send_without_enc('entryconfigure', _get_eval_enc_str(index)))).each{|conflist|\n          conf = tk_split_simplelist(conflist)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show'\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        fontconf = ret['font']\n        if fontconf\n          ret.delete('font')\n          ret.delete('kanjifont')\n          fontconf[3] = tagfont_configinfo(index, fontconf[3])\n          ret['font'] = fontconf\n        end\n        ret\n      end\n    end\n  end\n\n  def current_entryconfiginfo(index, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        conf = entryconfiginfo(index, key)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        entryconfiginfo(index).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      entryconfiginfo(index, key).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n=end\nend\n\n#TkMenu = Tk::Menu unless Object.const_defined? :TkMenu\nTk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)\n\n\nclass Tk::MenuClone<Tk::Menu\n=begin\n  def initialize(parent, type=None)\n    widgetname = nil\n    if parent.kind_of? Hash\n      keys = _symbolkey2str(parent)\n      parent = keys.delete('parent')\n      widgetname = keys.delete('widgetname')\n      type = keys.delete('type'); type = None unless type\n    end\n    #unless parent.kind_of?(TkMenu)\n    #  fail ArgumentError, \"parent must be TkMenu\"\n    #end\n    @parent = parent\n    install_win(@parent.path, widgetname)\n    tk_call_without_enc(@parent.path, 'clone', @path, type)\n  end\n=end\n  def initialize(src_menu, *args)\n    widgetname = nil\n\n    if args[0].kind_of?(TkWindow)  # parent window\n      parent = args.shift\n    else\n      parent = src_menu\n    end\n\n    if args[0].kind_of?(String) || args[0].kind_of?(Symbol)  # menu type\n      type = args.shift\n    else\n      type = None  # 'normal'\n    end\n\n    if args[0].kind_of?(Hash)\n      keys = _symbolkey2str(args.shift)\n      parent = keys.delete('parent') if keys.has_key?('parent')\n      widgetname = keys.delete('widgetname')\n      type = keys.delete('type') if keys.has_key?('type')\n    else\n      keys = nil\n    end\n\n    @src_menu = src_menu\n    @parent = parent\n    @type = type\n    install_win(@parent.path, widgetname)\n    tk_call_without_enc(@src_menu.path, 'clone', @path, @type)\n    configure(keys) if keys && !keys.empty?\n  end\n\n  def source_menu\n    @src_menu\n  end\nend\nTk::CloneMenu = Tk::MenuClone\n#TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone\n#TkCloneMenu = Tk::CloneMenu unless Object.const_defined? :TkCloneMenu\nTk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)\n\nmodule Tk::SystemMenu\n  def initialize(parent, keys=nil)\n    if parent.kind_of? Hash\n      keys = _symbolkey2str(parent)\n      parent = keys.delete('parent')\n    end\n    #unless parent.kind_of? TkMenu\n    #  fail ArgumentError, \"parent must be a TkMenu object\"\n    #end\n    # @path = Kernel.format(\"%s.%s\", parent.path, self.class::SYSMENU_NAME)\n    @path = parent.path + '.' + self.class::SYSMENU_NAME\n    #TkComm::Tk_WINDOWS[@path] = self\n    TkCore::INTERP.tk_windows[@path] = self\n    if self.method(:create_self).arity == 0\n      p 'create_self has no arg' if $DEBUG\n      create_self\n      configure(keys) if keys\n    else\n      p 'create_self has an arg' if $DEBUG\n      create_self(keys)\n    end\n  end\nend\nTkSystemMenu = Tk::SystemMenu\n\n\nclass Tk::SysMenu_Help<Tk::Menu\n  # for all platform\n  include Tk::SystemMenu\n  SYSMENU_NAME = 'help'\nend\n#TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help\nTk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)\n\n\nclass Tk::SysMenu_System<Tk::Menu\n  # for Windows\n  include Tk::SystemMenu\n  SYSMENU_NAME = 'system'\nend\n#TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System\nTk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)\n\n\nclass Tk::SysMenu_Apple<Tk::Menu\n  # for Machintosh\n  include Tk::SystemMenu\n  SYSMENU_NAME = 'apple'\nend\n#TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple\nTk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)\n\n\nclass Tk::Menubutton<Tk::Label\n  TkCommandNames = ['menubutton'.freeze].freeze\n  WidgetClassName = 'Menubutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  def create_self(keys)\n    if keys and keys != None\n      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        # tk_call_without_enc('menubutton', @path, *hash_kv(keys, true))\n        tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                            *hash_kv(keys, true))\n      else\n        begin\n          tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                              *hash_kv(keys, true))\n        rescue\n          tk_call_without_enc(self.class::TkCommandNames[0], @path)\n          keys = __check_available_configure_options(keys)\n          unless keys.empty?\n            tk_call_without_enc('destroy', @path) rescue nil\n            tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                                *hash_kv(keys, true))\n          end\n        end\n      end\n    else\n      # tk_call_without_enc('menubutton', @path)\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def __boolval_optkeys\n    super() << 'indicatoron'\n  end\n  private :__boolval_optkeys\n\nend\nTk::MenuButton = Tk::Menubutton\n#TkMenubutton = Tk::Menubutton unless Object.const_defined? :TkMenubutton\n#TkMenuButton = Tk::MenuButton unless Object.const_defined? :TkMenuButton\nTk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)\n\n\nclass Tk::OptionMenubutton<Tk::Menubutton\n  TkCommandNames = ['tk_optionMenu'.freeze].freeze\n\n  class OptionMenu<TkMenu\n    def initialize(path)  #==> return value of tk_optionMenu\n      @path = path\n      #TkComm::Tk_WINDOWS[@path] = self\n      TkCore::INTERP.tk_windows[@path] = self\n    end\n  end\n\n  def initialize(*args)\n    # args :: [parent,] [var,] [value[, ...],] [keys]\n    #    parent --> TkWindow or nil\n    #    var    --> TkVariable or nil\n    #    keys   --> Hash\n    #       keys[:parent] or keys['parent']     --> parent\n    #       keys[:variable] or keys['variable'] --> var\n    #       keys[:values] or keys['values']     --> value, ...\n    #       other Hash keys are menubutton options\n    keys = {}\n    keys = args.pop if args[-1].kind_of?(Hash)\n    keys = _symbolkey2str(keys)\n\n    parent = nil\n    if args[0].kind_of?(TkWindow) || args[0] == nil\n      keys.delete('parent') # ignore\n      parent = args.shift \n    else\n      parent = keys.delete('parent')\n    end\n\n    @variable = nil\n    if args[0].kind_of?(TkVariable) || args[0] == nil\n      keys.delete('variable') # ignore\n      @variable = args.shift \n    else\n      @variable = keys.delete('variable')\n    end\n    @variable = TkVariable.new unless @variable\n\n    (args = keys.delete('values') || []) if args.empty?\n    if args.empty?\n      args << @variable.value\n    else\n      @variable.value = args[0]\n    end\n\n    install_win(if parent then parent.path end)\n    @menu = OptionMenu.new(tk_call('tk_optionMenu', \n                                   @path, @variable.id, *args))\n\n    configure(keys) if keys\n  end\n\n  def value\n    @variable.value\n  end\n\n  def value=(val)\n    @variable.value = val\n  end\n\n  def activate(index)\n    @menu.activate(index)\n    self\n  end\n  def add(value)\n    @menu.add('radiobutton', 'variable'=>@variable, \n              'label'=>value, 'value'=>value)\n    self\n  end\n  def index(index)\n    @menu.index(index)\n  end\n  def invoke(index)\n    @menu.invoke(index)\n  end\n  def insert(index, value)\n    @menu.insert(index, 'radiobutton', 'variable'=>@variable, \n              'label'=>value, 'value'=>value)\n    self\n  end\n  def delete(index, last=None)\n    @menu.delete(index, last)\n    self\n  end\n  def xposition(index)\n    @menu.xposition(index)\n  end\n  def yposition(index)\n    @menu.yposition(index)\n  end\n  def menu\n    @menu\n  end\n  def menucget(key)\n    @menu.cget(key)\n  end\n  def menucget_strict(key)\n    @menu.cget_strict(key)\n  end\n  def menuconfigure(key, val=None)\n    @menu.configure(key, val)\n    self\n  end\n  def menuconfiginfo(key=nil)\n    @menu.configinfo(key)\n  end\n  def current_menuconfiginfo(key=nil)\n    @menu.current_configinfo(key)\n  end\n  def entrycget(index, key)\n    @menu.entrycget(index, key)\n  end\n  def entrycget_strict(index, key)\n    @menu.entrycget_strict(index, key)\n  end\n  def entryconfigure(index, key, val=None)\n    @menu.entryconfigure(index, key, val)\n    self\n  end\n  def entryconfiginfo(index, key=nil)\n    @menu.entryconfiginfo(index, key)\n  end\n  def current_entryconfiginfo(index, key=nil)\n    @menu.current_entryconfiginfo(index, key)\n  end\nend\n\nTk::OptionMenuButton = Tk::OptionMenubutton\n#TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton\n#TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton\nTk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton, \n                            :TkOptionMenubutton, :TkOptionMenuButton)\n"
  },
  {
    "path": "ext/tk/lib/tk/menubar.rb",
    "content": "#\n# tk/menubar.rb\n#\n# Original version:\n#   Copyright (C) 1998 maeda shugo. All rights reserved. \n#   This file can be distributed under the terms of the Ruby.\n\n# Usage:\n#\n# menu_spec = [\n#   [['File', 0],\n#     ['Open', proc{puts('Open clicked')}, 0],\n#     '---',\n#     ['Quit', proc{exit}, 0]],\n#   [['Edit', 0],\n#     ['Cut', proc{puts('Cut clicked')}, 2],\n#     ['Copy', proc{puts('Copy clicked')}, 0],\n#     ['Paste', proc{puts('Paste clicked')}, 0]]\n# ]\n# menubar = TkMenubar.new(nil, menu_spec,\n#                       'tearoff'=>false,\n#                       'foreground'=>'grey40',\n#                       'activeforeground'=>'red',\n#                       'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1')\n# menubar.pack('side'=>'top', 'fill'=>'x')\n#\n#\n# OR\n#\n#\n# menubar = TkMenubar.new\n# menubar.add_menu([['File', 0],\n#                  ['Open', proc{puts('Open clicked')}, 0],\n#                  '---',\n#                  ['Quit', proc{exit}, 0]])\n# menubar.add_menu([['Edit', 0],\n#                  ['Cut', proc{puts('Cut clicked')}, 2],\n#                  ['Copy', proc{puts('Copy clicked')}, 0],\n#                  ['Paste', proc{puts('Paste clicked')}, 0]])\n# menubar.configure('tearoff', false)\n# menubar.configure('foreground', 'grey40')\n# menubar.configure('activeforeground', 'red')\n# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1')\n# menubar.pack('side'=>'top', 'fill'=>'x')\n#\n#\n# OR\n#\n# radio_var = TkVariable.new('y')\n# menu_spec = [\n#   [['File', 0],\n#     {:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0},\n#     '---',\n#     ['Check_A', TkVariable.new(true), 6],\n#     {:type=>'checkbutton', :label=>'Check_B', \n#                 :variable=>TkVariable.new, :underline=>6},\n#     '---',\n#     ['Radio_X', [radio_var, 'x'], 6],\n#     ['Radio_Y', [radio_var, 'y'], 6],\n#     ['Radio_Z', [radio_var, 'z'], 6],\n#     '---',\n#     ['cascade', [ \n#                    ['sss', proc{p 'sss'}, 0], \n#                    ['ttt', proc{p 'ttt'}, 0], \n#                    ['uuu', proc{p 'uuu'}, 0], \n#                    ['vvv', proc{p 'vvv'}, 0], \n#                 ], 0],\n#     '---',\n#     ['Quit', proc{exit}, 0]],\n#   [['Edit', 0],\n#     ['Cut', proc{puts('Cut clicked')}, 2],\n#     ['Copy', proc{puts('Copy clicked')}, 0],\n#     ['Paste', proc{puts('Paste clicked')}, 0]]\n# ]\n# menubar = TkMenubar.new(nil, menu_spec,\n#                        'tearoff'=>false,\n#                        'foreground'=>'grey40',\n#                        'activeforeground'=>'red',\n#                        'font'=>'Helvetia 12 bold')\n# menubar.pack('side'=>'top', 'fill'=>'x')\n\n# See tk/menuspce.rb about the format of the menu_spec\n\n# To use add_menu, configuration must be done by calling configure after\n# adding all menus by add_menu, not by the constructor arguments.\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tk/composite'\nrequire 'tk/menuspec'\n\nclass TkMenubar<Tk::Frame\n  include TkComposite\n  include TkMenuSpec\n  \n  def initialize(parent = nil, spec = nil, options = nil)\n    if parent.kind_of? Hash\n      options = _symbolkey2str(parent)\n      spec = options.delete('spec')\n      super(options)\n    else\n      super(parent, options)\n    end\n\n    @menus = []\n    \n    spec.each{|info| add_menu(info)} if spec\n\n    options.each{|key, value| configure(key, value)} if options\n  end\n\n  def add_menu(menu_info)\n    mbtn, menu = _create_menubutton(@frame, menu_info)\n\n    submenus = _get_cascade_menus(menu).flatten\n\n    @menus.push([mbtn, menu])\n    delegate('tearoff', menu, *submenus)\n    delegate('foreground', mbtn, menu, *submenus)\n    delegate('background', mbtn, menu, *submenus)\n    delegate('disabledforeground', mbtn, menu, *submenus)\n    delegate('activeforeground', mbtn, menu, *submenus)\n    delegate('activebackground', mbtn, menu, *submenus)\n    delegate('font', mbtn, menu, *submenus)\n    delegate('kanjifont', mbtn, menu, *submenus)\n  end\n  \n  def [](index)\n    return @menus[index]\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/menuspec.rb",
    "content": "#\n# tk/menuspec.rb\n#                              Hidethoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n# based on tkmenubar.rb :\n#   Copyright (C) 1998 maeda shugo. All rights reserved. \n#   This file can be distributed under the terms of the Ruby.\n#\n# The format of the menu_spec is:\n#   [ menu_info, menu_info, ... ]\n#\n# And the format of the menu_info is:\n#   [\n#     [text, underline, configs], # menu button/entry (*1)\n#     [label, command, underline, accelerator, configs],   # command entry\n#     [label, TkVar_obj, underline, accelerator, configs], # checkbutton entry\n#     [label, [TkVar_obj, value], \n#                        underline, accelerator, configs], # radiobutton entry\n#     [label, [[...menu_info...], [...menu_info...], ...], \n#                        underline, accelerator, configs], # cascade entry (*2)\n#     '---', # separator\n#     ...\n#   ]\n#\n# underline, accelerator, and configs are optional pearameters. \n# Hashes are OK instead of Arrays. Then the entry type ('command', \n# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key\n# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info\n# is acceptable for 'menu' key (then, create sub-menu).\n#\n# NOTE: (*1)\n#   If you want to make special menus (*.help for UNIX, *.system for Win, \n#   and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX, \n#   'system' for Win, and 'apple' for Mac) option to the configs hash of \n#   menu button/entry information.\n#\n# NOTE: (*2)\n#   If you want to configure a cascade menu, add :menu_config=>{...configs..}\n#   to the configs of the cascade entry.\n\nmodule TkMenuSpec\n  def _create_menu(parent, menu_info, menu_name = nil, \n                   tearoff = false, default_opts = nil)\n    if tearoff.kind_of?(Hash)\n      default_opts = tearoff\n      tearoff = false\n    end\n\n    if menu_name.kind_of?(Hash)\n      default_opts = menu_name\n      menu_name = nil\n      tearoff = false\n    end\n\n    if default_opts.kind_of?(Hash)\n      orig_opts = _symbolkey2str(default_opts)\n    else\n      orig_opts = {}\n    end\n\n    tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')\n\n    if menu_name\n      #menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)\n      # --> use current TkMenu class\n      menu = TkMenu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)\n    else\n      #menu = Tk::Menu.new(parent, :tearoff=>tearoff)\n      # --> use current TkMenu class\n      menu = TkMenu.new(parent, :tearoff=>tearoff)\n    end\n\n    for item_info in menu_info\n      if item_info.kind_of?(Hash)\n        options = orig_opts.dup\n        options.update(_symbolkey2str(item_info))\n        item_type = (options.delete('type') || 'command').to_s\n        menu_name = options.delete('menu_name')\n        menu_opts = orig_opts.dup\n        menu_opts.update(_symbolkey2str(options.delete('menu_config') || {}))\n        if item_type == 'cascade' && options['menu'].kind_of?(Array)\n          # create cascade menu\n          submenu = _create_menu(menu, options['menu'], menu_name, \n                                 tearoff, menu_opts)\n          options['menu'] = submenu\n        end\n        menu.add(item_type, options)\n\n      elsif item_info.kind_of?(Array)\n        options = orig_opts.dup\n\n        options['label'] = item_info[0] if item_info[0]\n\n        case item_info[1]\n        when TkVariable\n          # checkbutton\n          item_type = 'checkbutton'\n          options['variable'] = item_info[1]\n          options['onvalue']  = true\n          options['offvalue'] = false\n\n        when Array\n          # radiobutton or cascade\n          if item_info[1][0].kind_of?(TkVariable)\n            # radiobutton\n            item_type = 'radiobutton'\n            options['variable'] = item_info[1][0]\n            options['value'] = item_info[1][1] if item_info[1][1]\n\n          else\n            # cascade\n            item_type = 'cascade'\n            menu_opts = orig_opts.dup\n            if item_info[4] && item_info[4].kind_of?(Hash)\n              opts = _symbolkey2str(item_info[4])\n              menu_name = opts.delete('menu_name')\n              menu_config = opts.delete('menu_config') || {}\n              menu_opts.update(_symbolkey2str(menu_config))\n            end\n            submenu = _create_menu(menu, item_info[1], menu_name, \n                                   tearoff, menu_opts)\n            options['menu'] = submenu\n          end\n\n        else\n          # command\n          item_type = 'command'\n          options['command'] = item_info[1] if item_info[1]\n        end\n\n        options['underline'] = item_info[2] if item_info[2]\n        options['accelerator'] = item_info[3] if item_info[3]\n        if item_info[4] && item_info[4].kind_of?(Hash)\n          opts = _symbolkey2str(item_info[4])\n          if item_type == 'cascade'\n            opts.delete('menu_name')\n            opts.delete('menu_config')\n          end\n          options.update(opts)\n        end\n        menu.add(item_type, options)\n\n      elsif /^-+$/ =~ item_info\n        menu.add('separator')\n\n      else\n        menu.add('command', 'label' => item_info)\n      end\n    end\n\n    menu\n  end\n  private :_create_menu\n\n  def _use_menubar?(parent)\n    use_menubar = false\n    if parent.kind_of?(Tk::Root) || parent.kind_of?(Tk::Toplevel)\n      true \n    elsif parent.current_configinfo.has_key?('menu')\n      true\n    else\n      false\n    end\n  end\n  private :_use_menubar?\n\n  def _create_menu_for_menubar(parent)\n    #unless (mbar = parent.menu).kind_of?(TkMenu)\n    # --> use current TkMenu class\n    mbar = parent.menu\n    unless mbar.kind_of?(Tk::Menu) || mbar.kind_of?(TkMenu)\n      #mbar = Tk::Menu.new(parent, :tearoff=>false)\n      mbar = TkMenu.new(parent, :tearoff=>false)\n      parent.menu(mbar)\n    end\n    mbar\n  end\n  private :_create_menu_for_menubar\n\n  def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil)\n    btn_info = menu_info[0]\n\n    if tearoff.kind_of?(Hash)\n      default_opts = tearoff\n      tearoff = false\n    end\n\n    if default_opts.kind_of?(Hash)\n      keys = _symbolkey2str(default_opts)\n    else\n      keys = {}\n    end\n\n    tearoff = keys.delete('tearoff') if keys.key?('tearoff')\n\n    if _use_menubar?(parent)\n      # menubar by menu entries\n      mbar = _create_menu_for_menubar(parent)\n\n      menu_name = nil\n\n      if btn_info.kind_of?(Hash)\n        keys.update(_symbolkey2str(btn_info))\n        menu_name = keys.delete('menu_name')\n        keys['label'] = keys.delete('text') if keys.key?('text')\n      elsif btn_info.kind_of?(Array)\n        keys['label'] = btn_info[0] if btn_info[0]\n        keys['underline'] = btn_info[1] if btn_info[1]\n        if btn_info[2]&&btn_info[2].kind_of?(Hash)\n          keys.update(_symbolkey2str(btn_info[2]))\n          menu_name = keys.delete('menu_name')\n        end\n      else\n        keys = {:label=>btn_info}\n      end\n\n      menu = _create_menu(mbar, menu_info[1..-1], menu_name, \n                          tearoff, default_opts)\n      menu.tearoff(tearoff)\n\n      keys['menu'] = menu\n      mbar.add('cascade', keys)\n\n      [mbar, menu]\n\n    else\n      # menubar by menubuttons\n      #mbtn = Tk::Menubutton.new(parent)\n      # --> use current TkMenubutton class\n      mbtn = TkMenubutton.new(parent)\n\n      menu_name = nil\n\n      if btn_info.kind_of?(Hash)\n        keys.update(_symbolkey2str(btn_info))\n        menu_name = keys.delete('menu_name')\n        keys['text'] = keys.delete('label') if keys.key?('label')\n        mbtn.configure(keys)\n      elsif btn_info.kind_of?(Array)\n        mbtn.configure('text', btn_info[0]) if btn_info[0]\n        mbtn.configure('underline', btn_info[1]) if btn_info[1]\n        # mbtn.configure('accelerator', btn_info[2]) if btn_info[2]\n        if btn_info[2]&&btn_info[2].kind_of?(Hash)\n          keys.update(_symbolkey2str(btn_info[2]))\n          menu_name = keys.delete('menu_name')\n          mbtn.configure(keys)\n        end\n      else\n        mbtn.configure('text', btn_info)\n      end\n\n      mbtn.pack('side' => 'left')\n\n      menu = _create_menu(mbtn, menu_info[1..-1], menu_name, \n                          tearoff, default_opts)\n    \n      mbtn.menu(menu)\n\n      [mbtn, menu]\n    end\n  end\n  private :_create_menubutton\n\n  def _get_cascade_menus(menu)\n    menus = []\n    (0..(menu.index('last'))).each{|idx|\n      if menu.menutype(idx) == 'cascade'\n        submenu = menu.entrycget(idx, 'menu')\n        menus << [submenu, _get_cascade_menus(submenu)]\n      end\n    }\n    menus\n  end\n  private :_get_cascade_menus\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/message.rb",
    "content": "#\n# tk/message.rb : treat message widget\n#\nrequire 'tk'\nrequire 'tk/label'\n\nclass Tk::Message<Tk::Label\n  TkCommandNames = ['message'.freeze].freeze\n  WidgetClassName = 'Message'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('message', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('message', @path)\n  #  end\n  #end\n  private :create_self\nend\n\n#TkMessage = Tk::Message unless Object.const_defined? :TkMessage\nTk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)\n"
  },
  {
    "path": "ext/tk/lib/tk/mngfocus.rb",
    "content": "#\n#   tk/mngfocus.rb : methods for Tcl/Tk standard library 'focus.tcl'\n#                           by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\nrequire 'tk'\n\nmodule TkManageFocus\n  extend Tk\n\n  TkCommandNames = [\n    'tk_focusFollowMouse'.freeze, \n    'tk_focusNext'.freeze, \n    'tk_focusPrev'.freeze\n  ].freeze\n\n  def TkManageFocus.followsMouse\n    tk_call_without_enc('tk_focusFollowsMouse')\n  end\n\n  def TkManageFocus.next(win)\n    tk_tcl2ruby(tk_call('tk_focusNext', win))\n  end\n  def focusNext\n    TkManageFocus.next(self)\n  end\n\n  def TkManageFocus.prev(win)\n    tk_tcl2ruby(tk_call('tk_focusPrev', win))\n  end\n  def focusPrev\n    TkManageFocus.prev(self)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/msgcat.rb",
    "content": "#\n#   tk/msgcat.rb : methods for Tcl message catalog\n#                     by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\nrequire 'tk'\n\n#class TkMsgCatalog\nclass TkMsgCatalog < TkObject\n  include TkCore\n  extend Tk\n  #extend TkMsgCatalog\n\n  TkCommandNames = [\n    '::msgcat::mc'.freeze, \n    '::msgcat::mcmax'.freeze, \n    '::msgcat::mclocale'.freeze, \n    '::msgcat::mcpreferences'.freeze, \n    '::msgcat::mcload'.freeze, \n    '::msgcat::mcset'.freeze, \n    '::msgcat::mcmset'.freeze, \n    '::msgcat::mcunknown'.freeze\n  ].freeze\n\n  tk_call_without_enc('package', 'require', 'Tcl', '8.2')\n\n  PACKAGE_NAME = 'msgcat'.freeze\n  def self.package_name\n    PACKAGE_NAME\n  end\n\n  if self.const_defined? :FORCE_VERSION\n    tk_call_without_enc('package', 'require', 'msgcat', FORCE_VERSION)\n  else\n    tk_call_without_enc('package', 'require', 'msgcat')\n  end\n\n  MSGCAT_EXT = '.msg'\n\n  UNKNOWN_CBTBL = Hash.new{|hash,key| hash[key] = {}}.taint\n\n  TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL')\n    if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} {\n       #return -code $st $ret\n       set idx [string first \"\\n\\n\" $ret]\n       if {$idx > 0} {\n          return -code $st \\\n                 -errorinfo [string range $ret [expr $idx + 2] \\\n                                               [string length $ret]] \\\n                 [string range $ret 0 [expr $idx - 1]]\n       } else {\n          return -code $st $ret\n       }\n    } else {\n        return $ret\n    }\n  EOL\n\n  def self.callback(namespace, locale, src_str, *args)\n    src_str = sprintf(src_str, *args) unless args.empty?\n    cmd_tbl = TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip]\n    cmd = cmd_tbl[namespace]\n    cmd = cmd_tbl['::'] unless cmd  # use global scope as interp default\n    return src_str unless cmd       # no cmd -> return src-str (default action)\n    begin\n      cmd.call(locale, src_str)\n    rescue SystemExit\n      exit(0)\n    rescue Interrupt\n      exit!(1)\n    rescue Exception => e\n      begin\n        msg = _toUTF8(e.class.inspect) + ': ' + \n              _toUTF8(e.message) + \"\\n\" + \n              \"\\n---< backtrace of Ruby side >-----\\n\" + \n              _toUTF8(e.backtrace.join(\"\\n\")) + \n              \"\\n---< backtrace of Tk side >-------\"\n        if TkCore::WITH_ENCODING\n          msg.force_encoding('utf-8')\n        else\n          msg.instance_variable_set(:@encoding, 'utf-8')\n        end\n      rescue Exception\n        msg = e.class.inspect + ': ' + e.message + \"\\n\" + \n              \"\\n---< backtrace of Ruby side >-----\\n\" + \n              e.backtrace.join(\"\\n\") + \n              \"\\n---< backtrace of Tk side >-------\"\n      end\n      fail(e, msg)\n    end\n  end\n\n  def initialize(namespace = nil)\n    if namespace.kind_of?(TkNamespace)\n      @namespace = namespace\n    elsif namespace == nil\n      @namespace = TkNamespace.new('::')  # global namespace\n    else\n      @namespace = TkNamespace.new(namespace)\n    end\n    @path = @namespace.path\n\n    @msgcat_ext = '.msg'\n  end\n  attr_accessor :msgcat_ext\n\n  def method_missing(id, *args)\n    # locale(src, trans) ==> set_translation(locale, src, trans)\n    loc = id.id2name\n    case args.length\n    when 0 # set locale\n      self.locale=(loc)\n\n    when 1 # src only, or trans_list\n      if args[0].kind_of?(Array)\n        # trans_list\n        #list = args[0].collect{|src, trans|\n        #  [ Tk::UTF8_String.new(src), Tk::UTF8_String.new(trans) ]\n        #}\n        self.set_translation_list(loc, args[0])\n      else\n        # src\n        #self.set_translation(loc, Tk::UTF8_String.new(args[0]))\n        self.set_translation(loc, args[0])\n      end\n\n    when 2 # src and trans, or, trans_list and enc\n      if args[0].kind_of?(Array)\n      else\n        #self.set_translation(loc, args[0], Tk::UTF8_String.new(args[1]))\n        self.set_translation(loc, *args)\n      end\n\n    when 3 # src and trans and enc\n      self.set_translation(loc, *args)\n\n    else\n      super(id, *args)\n#      fail NameError, \"undefined method `#{name}' for #{self.to_s}\", error_at\n\n    end\n  end\n\n  # *args ::= form, arg, arg, ...\n  def self.translate(*args)\n    dst = args.collect{|src|\n      tk_call_without_enc('::msgcat::mc', _get_eval_string(src, true))\n    }\n    Tk.UTF8_String(sprintf(*dst))\n  end\n  class << self\n    alias mc translate\n    alias [] translate\n  end\n  def translate(*args)\n    dst = args.collect{|src|\n      @namespace.eval{tk_call_without_enc('::msgcat::mc', \n                                          _get_eval_string(src, true))}\n    }\n    Tk.UTF8_String(sprintf(*dst))\n  end\n  alias mc translate\n  alias [] translate\n\n  def self.maxlen(*src_strings)\n    tk_call('::msgcat::mcmax', *src_strings).to_i\n  end\n  def maxlen(*src_strings)\n    @namespace.eval{tk_call('::msgcat::mcmax', *src_strings).to_i}\n  end\n\n  def self.locale\n    tk_call('::msgcat::mclocale')\n  end\n  def locale\n    @namespace.eval{tk_call('::msgcat::mclocale')}\n  end\n\n  def self.locale=(locale)\n    tk_call('::msgcat::mclocale', locale)\n  end\n  def locale=(locale)\n    @namespace.eval{tk_call('::msgcat::mclocale', locale)}\n  end\n\n  def self.preferences\n    tk_split_simplelist(tk_call('::msgcat::mcpreferences'))\n  end\n  def preferences\n    tk_split_simplelist(@namespace.eval{tk_call('::msgcat::mcpreferences')})\n  end\n\n  def self.load_tk(dir)\n    number(tk_call('::msgcat::mcload', dir))\n  end\n\n  def self.load_rb(dir)\n    count = 0\n    preferences().each{|loc|\n      file = File.join(dir, loc + self::MSGCAT_EXT)\n      if File.readable?(file)\n        count += 1\n        eval(open(file){|f| f.read})\n      end\n    }\n    count\n  end\n\n  def load_tk(dir)\n    number(@namespace.eval{tk_call('::msgcat::mcload', dir)})\n  end\n\n  def load_rb(dir)\n    count = 0\n    preferences().each{|loc|\n      file = File.join(dir, loc + @msgcat_ext)\n      if File.readable?(file)\n        count += 1\n        @namespace.eval(open(file){|f| f.read})\n      end\n    }\n    count\n  end\n\n  def self.load(dir)\n    self.load_rb(dir)\n  end\n  alias load load_rb\n\n  def self.set_translation(locale, src_str, trans_str=None, enc='utf-8')\n    if trans_str && trans_str != None\n      trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc))\n      Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', \n                                         locale, \n                                         _get_eval_string(src_str, true), \n                                         trans_str))\n    else\n      Tk.UTF8_String(tk_call_without_enc('::msgcat::mcset', \n                                         locale, \n                                         _get_eval_string(src_str, true)))\n    end\n  end\n  def set_translation(locale, src_str, trans_str=None, enc='utf-8')\n    if trans_str && trans_str != None\n      trans_str = Tk.UTF8_String(_toUTF8(trans_str, enc)) \n      Tk.UTF8_String(@namespace.eval{\n                       tk_call_without_enc('::msgcat::mcset', \n                                           locale, \n                                           _get_eval_string(src_str, true), \n                                           trans_str)\n                     })\n    else\n      Tk.UTF8_String(@namespace.eval{\n                       tk_call_without_enc('::msgcat::mcset', \n                                           locale, \n                                           _get_eval_string(src_str, true))})\n    end\n  end\n\n  def self.set_translation_list(locale, trans_list, enc='utf-8')\n    # trans_list ::= [ [src, trans], [src, trans], ... ]\n    list = []\n    trans_list.each{|src, trans|\n      if trans && trans != None\n        list << _get_eval_string(src, true) \n        list << Tk.UTF8_Stirng(_toUTF8(trans, enc))\n      else\n        list << _get_eval_string(src, true) << ''\n      end\n    }\n    number(tk_call_without_enc('::msgcat::mcmset', locale, list))\n  end\n  def set_translation_list(locale, trans_list, enc='utf-8')\n    # trans_list ::= [ [src, trans], [src, trans], ... ]\n    list = []\n    trans_list.each{|src, trans|\n      if trans && trans != None\n        list << _get_eval_string(src, true) \n        list << Tk.UTF8_String(_toUTF8(trans, enc))\n      else\n        list << _get_eval_string(src, true) << ''\n      end\n    }\n    number(@namespace.eval{\n             tk_call_without_enc('::msgcat::mcmset', locale, list)\n           })\n  end\n\n  def self.def_unknown_proc(cmd=Proc.new)\n    TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip]['::'] = cmd\n  end\n  def def_unknown_proc(cmd=Proc.new)\n    TkMsgCatalog::UNKNOWN_CBTBL[TkCore::INTERP.__getip][@namespace.path] = cmd\n  end\nend\n\nTkMsgCat = TkMsgCatalog\n"
  },
  {
    "path": "ext/tk/lib/tk/namespace.rb",
    "content": "#\n#   tk/namespace.rb : methods to manipulate Tcl/Tk namespace\n#                           by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\nrequire 'tk'\n\nclass TkNamespace < TkObject\n  extend Tk\n\n  TkCommandNames = [\n    'namespace'.freeze, \n  ].freeze\n\n  Tk_Namespace_ID_TBL = TkCore::INTERP.create_table\n\n  (Tk_Namespace_ID = [\"ns\".freeze, \"00000\".taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  Tk_NsCode_RetObjID_TBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    Tk_Namespace_ID_TBL.mutex.synchronize{ Tk_Namespace_ID_TBL.clear }\n    Tk_NsCode_RetObjID_TBL.mutex.synchronize{ Tk_NsCode_RetObjID_TBL.clear }\n  }\n\n  def TkNamespace.id2obj(id)\n    Tk_Namespace_ID_TBL.mutex.synchronize{\n      Tk_Namespace_ID_TBL[id]? Tk_Namespace_ID_TBL[id]: id\n    }\n  end\n\n  #####################################\n\n  class Ensemble < TkObject\n    def __cget_cmd\n      ['namespace', 'ensemble', 'configure', self.path]\n    end\n    private :__cget_cmd\n\n    def __config_cmd\n      ['namespace', 'ensemble', 'configure', self.path]\n    end\n    private :__config_cmd\n\n    def __configinfo_struct\n      {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, \n        :default_value=>nil, :current_value=>2}\n    end\n    private :__configinfo_struct\n\n    def __boolval_optkeys\n      ['prefixes']\n    end\n    private :__boolval_optkeys\n\n    def __listval_optkeys\n      ['map', 'subcommands', 'unknown']\n    end\n    private :__listval_optkeys\n\n    def self.exist?(ensemble)\n      bool(tk_call('namespace', 'ensemble', 'exists', ensemble))\n    end\n\n    def initialize(keys = {})\n      @ensemble = @path = tk_call('namespace', 'ensemble', 'create', keys)\n    end\n\n    def cget(slot)\n      if slot == :namespace || slot == 'namespace'\n        ns = super(slot)\n        Tk_Namespace_ID_TBL.mutex.synchronize{\n          if TkNamespace::Tk_Namespace_ID_TBL.key?(ns)\n            TkNamespace::Tk_Namespace_ID_TBL[ns]\n          else\n            ns\n          end\n        }\n      else\n        super(slot)\n      end\n    end\n    def cget_strict(slot)\n      if slot == :namespace || slot == 'namespace'\n        ns = super(slot)\n        Tk_Namespace_ID_TBL.mutex.synchronize{\n          if TkNamespace::Tk_Namespace_ID_TBL.key?(ns)\n            TkNamespace::Tk_Namespace_ID_TBL[ns]\n          else\n            ns\n          end\n        }\n      else\n        super(slot)\n      end\n    end\n\n    def configinfo(slot = nil)\n      if slot\n        if slot == :namespace || slot == 'namespace'\n          val = super(slot)\n          Tk_Namespace_ID_TBL.mutex.synchronize{\n            if TkNamespace::Tk_Namespace_ID_TBL.key?(val)\n              val = TkNamespace::Tk_Namespace_ID_TBL[val]\n            end\n          }\n        else\n          val = super(slot)\n        end\n\n        if TkComm::GET_CONFIGINFO_AS_ARRAY\n          [slot.to_s, val]\n        else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n          {slot.to_s => val}\n        end\n\n      else\n        info = super()\n\n        if TkComm::GET_CONFIGINFO_AS_ARRAY\n          Tk_Namespace_ID_TBL.mutex.synchronize{\n            info.map!{|inf| \n              if inf[0] == 'namespace' && \n                  TkNamespace::Tk_Namespace_ID_TBL.key?(inf[-1])\n                [inf[0], TkNamespace::Tk_Namespace_ID_TBL[inf[-1]]]\n              else\n                inf\n              end\n            }\n          }\n        else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n          val = info['namespace']\n          Tk_Namespace_ID_TBL.mutex.synchronize{\n            if TkNamespace::Tk_Namespace_ID_TBL.key?(val)\n              info['namespace'] = TkNamespace::Tk_Namespace_ID_TBL[val]\n            end\n          }\n        end\n\n        info\n      end\n    end\n\n    def exists?\n      bool(tk_call('namespace', 'ensemble', 'exists', @path))\n    end\n  end\n\n  #####################################\n\n  class ScopeArgs < Array\n    include Tk\n\n    # alias __tk_call             tk_call\n    # alias __tk_call_without_enc tk_call_without_enc\n    # alias __tk_call_with_enc    tk_call_with_enc\n    def tk_call(*args)\n      #super('namespace', 'eval', @namespace, *args)\n      args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''}\n      super('namespace', 'eval', @namespace, \n            TkCore::INTERP._merge_tklist(*args))\n    end\n    def tk_call_without_enc(*args)\n      #super('namespace', 'eval', @namespace, *args)\n      args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''}\n      super('namespace', 'eval', @namespace, \n            TkCore::INTERP._merge_tklist(*args))\n    end\n    def tk_call_with_enc(*args)\n      #super('namespace', 'eval', @namespace, *args)\n      args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''}\n      super('namespace', 'eval', @namespace, \n            TkCore::INTERP._merge_tklist(*args))\n    end\n\n    def initialize(namespace, *args)\n      @namespace = namespace\n      super(args.size)\n      self.replace(args)\n    end\n  end\n\n  #####################################\n\n  class NsCode < TkObject\n    def initialize(scope, use_obj_id = false)\n      @scope = scope + ' '\n      @use_obj_id = use_obj_id\n    end\n    def path\n      @scope\n    end\n    def to_eval\n      @scope\n    end\n    def call(*args)\n      ret = TkCore::INTERP._eval_without_enc(@scope + array2tk_list(args))\n      if @use_obj_id\n        ret = TkNamespace::Tk_NsCode_RetObjID_TBL.delete(ret.to_i)\n      end\n      ret\n    end\n  end\n\n  #####################################\n\n  def install_cmd(cmd)\n    lst = tk_split_simplelist(super(cmd), false, false)\n    if lst[1] =~ /^::/\n      lst[1] = @fullname\n    else\n      lst.insert(1, @fullname)\n    end\n    TkCore::INTERP._merge_tklist(*lst)\n  end\n\n  alias __tk_call             tk_call\n  alias __tk_call_without_enc tk_call_without_enc\n  alias __tk_call_with_enc    tk_call_with_enc\n  def tk_call(*args)\n    #super('namespace', 'eval', @fullname, *args)\n    args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''}\n    super('namespace', 'eval', @fullname, \n          TkCore::INTERP._merge_tklist(*args))\n  end\n  def tk_call_without_enc(*args)\n    #super('namespace', 'eval', @fullname, *args)\n    args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''}\n    super('namespace', 'eval', @fullname,  \n          TkCore::INTERP._merge_tklist(*args))\n  end\n  def tk_call_with_enc(*args)\n    #super('namespace', 'eval', @fullname, *args)\n    args = args.collect{|arg| (s = _get_eval_string(arg, true))? s: ''}\n    super('namespace', 'eval', @fullname, \n          TkCore::INTERP._merge_tklist(*args))\n  end\n  alias ns_tk_call             tk_call\n  alias ns_tk_call_without_enc tk_call_without_enc\n  alias ns_tk_call_with_enc    tk_call_with_enc\n\n  def initialize(name = nil, parent = nil)\n    unless name\n      Tk_Namespace_ID.mutex.synchronize{\n        # name = Tk_Namespace_ID.join('')\n        name = Tk_Namespace_ID.join(TkCore::INTERP._ip_id_)\n        Tk_Namespace_ID[1].succ!\n      }\n    end\n    name = __tk_call('namespace', 'current') if name == ''\n    if parent\n      if parent =~ /^::/\n        if name =~ /^::/\n          @fullname = parent + name\n        else\n          @fullname = parent +'::'+ name\n        end\n      else\n        ancestor = __tk_call('namespace', 'current')\n        ancestor = '' if ancestor == '::'\n        if name =~ /^::/\n          @fullname = ancestor + '::' + parent + name\n        else\n          @fullname = ancestor + '::'+ parent +'::'+ name\n        end\n      end\n    else # parent == nil\n      ancestor = __tk_call('namespace', 'current')\n      ancestor = '' if ancestor == '::'\n      if name =~ /^::/\n        @fullname = name\n      else\n        @fullname = ancestor + '::' + name\n      end\n    end\n    @path = @fullname\n    @parent = __tk_call('namespace', 'qualifiers', @fullname)\n    @name = __tk_call('namespace', 'tail', @fullname)\n\n    # create namespace\n    __tk_call('namespace', 'eval', @fullname, '')\n\n    Tk_Namespace_ID_TBL.mutex.synchronize{\n      Tk_Namespace_ID_TBL[@fullname] = self\n    }\n  end\n\n  def self.children(*args)\n    # args ::= [<namespace>] [<pattern>]\n    # <pattern> must be glob-style pattern\n    tk_split_simplelist(tk_call('namespace', 'children', *args)).collect{|ns|\n      # ns is fullname\n      Tk_Namespace_ID_TBL.mutex.synchronize{\n        if Tk_Namespace_ID_TBL.key?(ns)\n          Tk_Namespace_ID_TBL[ns]\n        else\n          ns\n        end\n      }\n    }\n  end\n  def children(pattern=None)\n    TkNamespace.children(@fullname, pattern)\n  end\n\n  def self.code(script = Proc.new)\n    TkNamespace.new('').code(script)\n  end\n=begin\n  def code(script = Proc.new)\n    if script.kind_of?(String)\n      cmd = proc{|*args| ScopeArgs.new(@fullname,*args).instance_eval(script)}\n    elsif script.kind_of?(Proc)\n      cmd = proc{|*args| ScopeArgs.new(@fullname,*args).instance_eval(&script)}\n    else\n      fail ArgumentError, \"String or Proc is expected\"\n    end\n    TkNamespace::NsCode.new(tk_call_without_enc('namespace', 'code', \n                                                _get_eval_string(cmd, false)))\n  end\n=end\n  def code(script = Proc.new)\n    if script.kind_of?(String)\n      cmd = proc{|*args|\n        if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n          obj = ScopeArgs.new(@fullname,*args)\n          ret = obj.instance_exec(obj, script)\n        else\n          ret = ScopeArgs.new(@fullname,*args).instance_eval(script)\n        end\n        id = ret.object_id\n        TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret\n        id\n      }\n    elsif script.kind_of?(Proc)\n      cmd = proc{|*args|\n        if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n          obj = ScopeArgs.new(@fullname,*args)\n          ret = obj.instance_exec(obj, &script)\n        else\n          ret = ScopeArgs.new(@fullname,*args).instance_eval(&script)\n        end\n        id = ret.object_id\n        TkNamespace::Tk_NsCode_RetObjID_TBL[id] = ret\n        id\n      }\n    else\n      fail ArgumentError, \"String or Proc is expected\"\n    end\n    TkNamespace::NsCode.new(tk_call_without_enc('namespace', 'code', \n                                                _get_eval_string(cmd, false)), \n                            true)\n  end\n\n  def self.current_path\n    tk_call('namespace', 'current')\n  end\n  def current_path\n    @fullname\n  end\n\n  def self.current\n    ns = self.current_path\n    Tk_Namespace_ID_TBL.mutex.synchronize{\n      if Tk_Namespace_ID_TBL.key?(ns)\n        Tk_Namespace_ID_TBL[ns]\n      else\n        ns\n      end\n    }\n  end\n  def current_namespace\n    # ns_tk_call('namespace', 'current')\n    # @fullname\n    self\n  end\n  alias current current_namespace\n\n  def self.delete(*ns_list)\n    tk_call('namespace', 'delete', *ns_list)\n    ns_list.each{|ns|\n      Tk_Namespace_ID_TBL.mutex.synchronize{\n        if ns.kind_of?(TkNamespace)\n          Tk_Namespace_ID_TBL.delete(ns.path)\n        else\n          Tk_Namespace_ID_TBL.delete(ns.to_s)\n        end\n      }\n    }\n  end\n  def delete\n    TkNamespece.delete(@fullname)\n  end\n\n  def self.ensemble_create(*keys)\n    tk_call('namespace', 'ensemble', 'create', *hash_kv(keys))\n  end\n  def self.ensemble_configure(cmd, slot, value=None)\n    if slot.kind_of?(Hash)\n      tk_call('namespace', 'ensemble', 'configure', cmd, *hash_kv(slot))\n    else\n      tk_call('namespace', 'ensemble', 'configure', cmd, '-'+slot.to_s, value)\n    end\n  end\n  def self.ensemble_configinfo(cmd, slot = nil)\n    if slot\n      tk_call('namespace', 'ensemble', 'configure', cmd, '-' + slot.to_s)\n    else\n      inf = {}\n      Hash(*tk_split_simplelist(tk_call('namespace', 'ensemble', 'configure', cmd))).each{|k, v| inf[k[1..-1]] = v}\n      inf\n    end\n  end\n  def self.ensemble_exist?(cmd)\n    bool(tk_call('namespace', 'ensemble', 'exists', cmd))\n  end\n\n  def self.eval(namespace, cmd = Proc.new, *args)\n    #tk_call('namespace', 'eval', namespace, cmd, *args)\n    TkNamespace.new(namespace).eval(cmd, *args)\n  end\n=begin\n  def eval(cmd = Proc.new, *args)\n    #TkNamespace.eval(@fullname, cmd, *args)\n    #ns_tk_call(cmd, *args)\n    code_obj = code(cmd)\n    ret = code_obj.call(*args)\n    # uninstall_cmd(TkCore::INTERP._split_tklist(code_obj.path)[-1])\n    uninstall_cmd(_fromUTF8(TkCore::INTERP._split_tklist(_toUTF8(code_obj.path))[-1]))\n    tk_tcl2ruby(ret)\n  end\n=end\n  def eval(cmd = Proc.new, *args)\n    code_obj = code(cmd)\n    ret = code_obj.call(*args)\n    uninstall_cmd(_fromUTF8(TkCore::INTERP._split_tklist(_toUTF8(code_obj.path))[-1]))\n    ret\n  end\n\n  def self.exist?(ns)\n    bool(tk_call('namespace', 'exists', ns))\n  end\n  def exist?\n    TkNamespece.exist?(@fullname)\n  end\n\n  def self.export(*patterns)\n    tk_call('namespace', 'export', *patterns)\n  end\n  def self.export_with_clear(*patterns)\n    tk_call('namespace', 'export', '-clear', *patterns)\n  end\n  def export\n    TkNamespace.export(@fullname)\n  end\n  def export_with_clear\n    TkNamespace.export_with_clear(@fullname)\n  end\n\n  def self.forget(*patterns)\n    tk_call('namespace', 'forget', *patterns)\n  end\n  def forget\n    TkNamespace.forget(@fullname)\n  end\n\n  def self.import(*patterns)\n    tk_call('namespace', 'import', *patterns)\n  end\n  def self.force_import(*patterns)\n    tk_call('namespace', 'import', '-force', *patterns)\n  end\n  def import\n    TkNamespace.import(@fullname)\n  end\n  def force_import\n    TkNamespace.force_import(@fullname)\n  end\n\n  def self.inscope(namespace, script, *args)\n    tk_call('namespace', 'inscope', namespace, script, *args)\n  end\n  def inscope(script, *args)\n    TkNamespace.inscope(@fullname, script, *args)\n  end\n\n  def self.origin(cmd)\n    tk_call('namespace', 'origin', cmd)\n  end\n\n  def self.parent(namespace=None)\n    ns = tk_call('namespace', 'parent', namespace)\n    Tk_Namespace_ID_TBL.mutex.synchronize{\n      if Tk_Namespace_ID_TBL.key?(ns)\n        Tk_Namespace_ID_TBL[ns]\n      else\n        ns\n      end\n    }\n  end\n  def parent\n    tk_call('namespace', 'parent', @fullname)\n  end\n\n  def self.get_path\n    tk_call('namespace', 'path')\n  end\n  def self.set_path(*namespace_list)\n    tk_call('namespace', 'path', array2tk_list(namespace_list))\n  end\n  def set_path\n    tk_call('namespace', 'path', @fullname)\n  end\n\n  def self.qualifiers(str)\n    tk_call('namespace', 'qualifiers', str)\n  end\n\n  def self.tail(str)\n    tk_call('namespace', 'tail', str)\n  end\n\n  def self.upvar(namespace, *var_pairs)\n    tk_call('namespace', 'upvar', namespace, *(var_pairs.flatten))\n  end\n  def upvar(*var_pairs)\n    TkNamespace.inscope(@fullname, *(var_pairs.flatten))\n  end\n\n  def self.get_unknown_handler\n    tk_tcl2ruby(tk_call('namespace', 'unknown'))\n  end\n  def self.set_unknown_handler(cmd = Proc.new)\n    tk_call('namespace', 'unknown', cmd)\n  end\n\n  def self.which(name)\n    tk_call('namespace', 'which', name)\n  end\n  def self.which_command(name)\n    tk_call('namespace', 'which', '-command', name)\n  end\n  def self.which_variable(name)\n    tk_call('namespace', 'which', '-variable', name)\n  end\nend\n\nTkNamespace::Global = TkNamespace.new('::')\n"
  },
  {
    "path": "ext/tk/lib/tk/optiondb.rb",
    "content": "#\n# tk/optiondb.rb : treat option database\n#\nrequire 'tk'\n\nmodule TkOptionDB\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['option'.freeze].freeze\n  (CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  module Priority\n    WidgetDefault = 20\n    StartupFile   = 40\n    UserDefault   = 60\n    Interactive   = 80\n  end\n\n  def add(pat, value, pri=None)\n    # if $SAFE >= 4\n    #   fail SecurityError, \"can't call 'TkOptionDB.add' at $SAFE >= 4\"\n    # end\n    tk_call('option', 'add', pat, value, pri)\n  end\n  def clear\n    # if $SAFE >= 4\n    #   fail SecurityError, \"can't call 'TkOptionDB.crear' at $SAFE >= 4\"\n    # end\n    tk_call_without_enc('option', 'clear')\n  end\n  def get(win, name, klass)\n    tk_call('option', 'get', win ,name, klass)\n  end\n  def readfile(file, pri=None)\n    tk_call('option', 'readfile', file, pri)\n  end\n  alias read_file readfile\n  module_function :add, :clear, :get, :readfile, :read_file\n\n  def read_entries(file, f_enc=nil)\n    if TkCore::INTERP.safe?\n      fail SecurityError, \n        \"can't call 'TkOptionDB.read_entries' on a safe interpreter\"\n    end\n\n    i_enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system)\n\n    unless f_enc\n      f_enc = i_enc\n    end\n\n    ent = []\n    cline = ''\n    open(file, 'r') {|f|\n      while line = f.gets\n        #cline += line.chomp!\n        cline.concat(line.chomp!)\n        case cline\n        when /\\\\$/    # continue\n          cline.chop!\n          next\n        when /^\\s*(!|#)/     # coment\n          cline = ''\n          next\n        when /^([^:]+):(.*)$/\n          pat = $1.strip\n          val = $2.lstrip\n          p \"ResourceDB: #{[pat, val].inspect}\" if $DEBUG\n          pat = TkCore::INTERP._toUTF8(pat, f_enc)\n          pat = TkCore::INTERP._fromUTF8(pat, i_enc)\n          val = TkCore::INTERP._toUTF8(val, f_enc)\n          val = TkCore::INTERP._fromUTF8(val, i_enc)\n          ent << [pat, val]\n          cline = ''\n        else          # unknown --> ignore\n          cline = ''\n          next\n        end\n      end\n    }\n    ent\n  end\n  module_function :read_entries\n      \n  def read_with_encoding(file, f_enc=nil, pri=None)\n    # try to read the file as an OptionDB file\n    read_entries(file, f_enc).each{|pat, val|\n      add(pat, val, pri)\n    }\n\n=begin\n    i_enc = Tk.encoding()\n\n    unless f_enc\n      f_enc = i_enc\n    end\n\n    cline = ''\n    open(file, 'r') {|f|\n      while line = f.gets\n        cline += line.chomp!\n        case cline\n        when /\\\\$/    # continue\n          cline.chop!\n          next\n        when /^\\s*!/     # coment\n          cline = ''\n          next\n        when /^([^:]+):\\s(.*)$/\n          pat = $1\n          val = $2\n          p \"ResourceDB: #{[pat, val].inspect}\" if $DEBUG\n          pat = TkCore::INTERP._toUTF8(pat, f_enc)\n          pat = TkCore::INTERP._fromUTF8(pat, i_enc)\n          val = TkCore::INTERP._toUTF8(val, f_enc)\n          val = TkCore::INTERP._fromUTF8(val, i_enc)\n          add(pat, val, pri)\n          cline = ''\n        else          # unknown --> ignore\n          cline = ''\n          next\n        end\n      end\n    }\n=end\n  end\n  module_function :read_with_encoding\n\n  # support procs on the resource database\n  @@resource_proc_class = Class.new\n\n  @@resource_proc_class.const_set(:CARRIER, '.'.freeze)\n\n  @@resource_proc_class.instance_variable_set('@method_tbl', \n                                              TkCore::INTERP.create_table)\n  @@resource_proc_class.instance_variable_set('@add_method', false)\n  @@resource_proc_class.instance_variable_set('@safe_mode', 4)\n\n  class << @@resource_proc_class\n    private :new\n\n=begin \n    CARRIER    = '.'.freeze\n    METHOD_TBL = TkCore::INTERP.create_table\n    ADD_METHOD = false\n    SAFE_MODE  = 4\n=end\n\n=begin\n    def __closed_block_check__(str)\n      depth = 0\n      str.scan(/[{}]/){|x|\n        if x == \"{\"\n          depth += 1\n        elsif x == \"}\"\n          depth -= 1\n        end\n        if depth <= 0 && !($' =~ /\\A\\s*\\Z/)\n          fail RuntimeError, \"bad string for procedure : #{str.inspect}\"\n        end\n      }\n      str\n    end\n    private :__closed_block_check__\n=end\n\n    def __check_proc_string__(str)\n      # If you want to check the proc_string, do it in this method.\n      # Please define this in the block given to 'new_proc_class' method. \n      str\n    end\n\n    def method_missing(id, *args)\n      #res_proc, proc_str = self::METHOD_TBL[id]\n      res_proc, proc_str = @method_tbl[id]\n\n      proc_source = TkOptionDB.get(self::CARRIER, id.id2name, '').strip\n      res_proc = nil if proc_str != proc_source # resource is changed\n\n      # unless res_proc.kind_of?(Proc)\n      unless TkComm._callback_entry?(res_proc)\n        #if id == :new || !(self::METHOD_TBL.has_key?(id) || self::ADD_METHOD)\n        if id == :new || !(@method_tbl.has_key?(id) || @add_method)\n          raise NoMethodError, \n                \"not support resource-proc '#{id.id2name}' for #{self.name}\"\n        end\n        proc_str = proc_source\n        proc_str = '{' + proc_str + '}' unless /\\A\\{.*\\}\\Z/ =~ proc_str\n        #proc_str = __closed_block_check__(proc_str)\n        proc_str = __check_proc_string__(proc_str)\n        res_proc = proc{ \n          begin\n            #eval(\"$SAFE = #{self::SAFE_MODE};\\nProc.new\" + proc_str)\n            eval(\"$SAFE = #{@safe_mode};\\nProc.new\" + proc_str)\n          rescue SyntaxError=>err\n            raise SyntaxError, \n              TkCore::INTERP._toUTF8(err.message.gsub(/\\(eval\\):\\d:/, \n                                                      \"(#{id.id2name}):\"))\n          end\n        }.call\n        #self::METHOD_TBL[id] = [res_proc, proc_source]\n        @method_tbl[id] = [res_proc, proc_source]\n      end\n      res_proc.call(*args)\n    end\n\n    private :__check_proc_string__, :method_missing\n  end\n  @@resource_proc_class.freeze\n\n=begin\n  def __create_new_class(klass, func, safe = 4, add = false, parent = nil)\n    klass = klass.to_s if klass.kind_of? Symbol\n    unless (?A..?Z) === klass[0]\n      fail ArgumentError, \"bad string '#{klass}' for class name\"\n    end\n    unless func.kind_of? Array\n      fail ArgumentError, \"method-list must be Array\"\n    end\n    func_str = func.join(' ')\n    if parent == nil\n      install_win(parent)\n    elsif parent <= @@resource_proc_class\n      install_win(parent::CARRIER)\n    else\n      fail ArgumentError, \"parent must be Resource-Proc class\"\n    end\n    carrier = Tk.tk_call_without_enc('frame', @path, '-class', klass)\n\n    body = <<-\"EOD\"\n      class #{klass} < TkOptionDB.module_eval('@@resource_proc_class')\n        CARRIER    = '#{carrier}'.freeze\n        METHOD_TBL = TkCore::INTERP.create_table\n        ADD_METHOD = #{add}\n        SAFE_MODE  = #{safe}\n        %w(#{func_str}).each{|f| METHOD_TBL[f.intern] = nil }\n      end\n    EOD\n\n    if parent.kind_of?(Class) && parent <= @@resource_proc_class\n      parent.class_eval(body)\n      eval(parent.name + '::' + klass)\n    else\n      eval(body)\n      eval('TkOptionDB::' + klass)\n    end\n  end\n=end\n  def __create_new_class(klass, func, safe = 4, add = false, parent = nil)\n    if klass.kind_of?(TkWindow)\n      carrier = klass.path\n      CmdClassID.mutex.synchronize{\n        klass = CmdClassID.join(TkCore::INTERP._ip_id_)\n        CmdClassID[1].succ!\n      }\n      parent = nil # ignore parent\n    else\n      klass = klass.to_s if klass.kind_of?(Symbol)\n      unless (?A..?Z) === klass[0]\n        fail ArgumentError, \"bad string '#{klass}' for class name\"\n      end\n      if parent == nil\n        install_win(nil)\n      elsif parent.kind_of?(TkWindow)\n        install_win(parent.path)\n      elsif parent <= @@resource_proc_class\n        install_win(parent::CARRIER)\n      else\n        fail ArgumentError, \"parent must be Resource-Proc class\"\n      end\n      carrier = Tk.tk_call_without_enc('frame', @path, '-class', klass)\n    end\n\n    unless func.kind_of?(Array)\n      fail ArgumentError, \"method-list must be Array\"\n    end\n    func_str = func.join(' ')\n\n    if parent.kind_of?(Class) && parent <= @@resource_proc_class\n      cmd_klass = Class.new(parent)\n    else\n      cmd_klass = Class.new(TkOptionDB.module_eval('@@resource_proc_class'))\n    end\n    cmd_klass.const_set(:CARRIER, carrier.dup.freeze)\n\n    cmd_klass.instance_variable_set('@method_tbl', TkCore::INTERP.create_table)\n    cmd_klass.instance_variable_set('@add_method', add)\n    cmd_klass.instance_variable_set('@safe_mode', safe)\n    func.each{|f| \n      cmd_klass.instance_variable_get('@method_tbl')[f.to_s.intern] = nil\n    }\n=begin\n    cmd_klass.const_set(:METHOD_TBL, TkCore::INTERP.create_table)\n    cmd_klass.const_set(:ADD_METHOD, add)\n    cmd_klass.const_set(:SAFE_MODE, safe)\n    func.each{|f| cmd_klass::METHOD_TBL[f.to_s.intern] = nil }\n=end\n\n    cmd_klass\n  end\n  module_function :__create_new_class\n  private_class_method :__create_new_class\n\n  def __remove_methods_of_proc_class(klass)\n    # for security, make these methods invalid\n    class << klass\n      def __null_method(*args); nil; end\n      [ :class_eval, :name, :superclass, :clone, :dup, :autoload, :autoload?, \n        :ancestors, :const_defined?, :const_get, :const_set, :const_missing, \n        :class_variables, :constants, :included_modules, :instance_methods, \n        :method_defined?, :module_eval, :private_instance_methods, \n        :protected_instance_methods, :public_instance_methods, \n        :singleton_methods, :remove_const, :remove_method, :undef_method, \n        :to_s, :inspect, :display, :method, :methods, :respond_to?, \n        :instance_variable_get, :instance_variable_set, :instance_method, \n        :instance_eval, :instance_exec, :instance_variables, :kind_of?, :is_a?,\n        :private_methods, :protected_methods, :public_methods ].each{|m|\n        alias_method(m, :__null_method)\n      }\n    end\n  end\n  module_function :__remove_methods_of_proc_class\n  private_class_method :__remove_methods_of_proc_class\n\n  RAND_BASE_CNT = [0]\n  RAND_BASE_HEAD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n  RAND_BASE_CHAR = RAND_BASE_HEAD + 'abcdefghijklmnopqrstuvwxyz0123456789_'\n  def __get_random_basename\n    name = '%s%03d' % [RAND_BASE_HEAD[rand(RAND_BASE_HEAD.size),1], \n                       RAND_BASE_CNT[0]]\n    len = RAND_BASE_CHAR.size\n    (6+rand(10)).times{\n      name << RAND_BASE_CHAR[rand(len),1]\n    }\n    RAND_BASE_CNT[0] = RAND_BASE_CNT[0] + 1\n    name\n  end\n  module_function :__get_random_basename\n  private_class_method :__get_random_basename\n\n  # define new proc class :\n  # If you want to modify the new class or create a new subclass, \n  # you must do such operation in the block parameter. \n  # Because the created class is flozen after evaluating the block. \n  def new_proc_class(klass, func, safe = 4, add = false, parent = nil, &b)\n    new_klass = __create_new_class(klass, func, safe, add, parent)\n    new_klass.class_eval(&b) if block_given?\n    __remove_methods_of_proc_class(new_klass)\n    new_klass.freeze\n    new_klass\n  end\n  module_function :new_proc_class\n\n  def eval_under_random_base(parent = nil, &b)\n    new_klass = __create_new_class(__get_random_basename(), \n                                   [], 4, false, parent)\n    ret = new_klass.class_eval(&b) if block_given?\n    __remove_methods_of_proc_class(new_klass)\n    new_klass.freeze\n    ret\n  end\n  module_function :eval_under_random_base\n\n  def new_proc_class_random(klass, func, safe = 4, add = false, &b)\n    eval_under_random_base(){\n      TkOptionDB.new_proc_class(klass, func, safe, add, self, &b)\n    }\n  end\n  module_function :new_proc_class_random\nend\nTkOption = TkOptionDB\nTkResourceDB = TkOptionDB\n"
  },
  {
    "path": "ext/tk/lib/tk/optionobj.rb",
    "content": "#\n# tk/optionobj.rb : control options for a group of widgets\n#\n#  NOTE: If you want to use key-only option (no value), \n#        use Tk::None for the value of the key-only option. \n#\n#        e.g. hash_kv({'aaa'=>1, 'bbb'=>Tk::None, 'ccc'=>3}) \n#                 => [\"-aaa\", 1, \"-bbb\", \"-ccc\", 3]\n#\nrequire 'tk'\n\nmodule Tk\n  class OptionObj < Hash\n    include TkUtil\n\n    def initialize(hash = nil)\n      super()\n      @observ = []\n      update_without_notify(_symbolkey2str(hash)) if hash\n    end\n\n    def observ_info\n      @observ.dup\n    end\n\n    def observs\n      @observ.collect{|win|\n        if win.kind_of?(Array)\n          win[0]\n        else\n          win\n        end\n      }\n    end\n\n    def _remove_win(win)\n      if win.kind_of?(Array)\n        widget, method = win\n        @observ.delete_if{|x| \n          if x.kind_of?(Array)\n            x[0] == widget\n          else\n            x == widget\n          end\n        }\n      else\n        @observ.delete_if{|x|\n          if x.kind_of?(Array)\n            x[0] == win\n          else\n            x == win\n          end\n        }\n      end\n    end\n    private :_remove_win\n\n    def assign(*wins)\n      # win := \n      #   widget             #==> call widget.configure(hash)\n      #   [widget]           #==> call widget.configure(hash)\n      #   [widget, nil, {src=>target, ... }]\n      #                      #==> call widget.configure(hash) \n      #                               with converting hash-key\n      #   [widget, method]   #==> call widget.method(hash)\n      #   [widget, method, {src=>target, ... }]\n      #                      #==> call widget.method(hash) \n      #                               with converting hash-key\n      #   [widget [receiver, method, arg, ... ]]\n      #                      #==> call receiver.method(arg, ... , hash)\n      #   [widget [receiver, method, arg, ... ], {src=>target, ... }]\n      #                      #==> call receiver.method(arg, ... , hash)\n      #                               with onverting hash-key\n      #\n      # src := option_name_on_optobj\n      #\n      # target := \n      #   nil                #==> not use the src\n      #   option_name_on_target_widget\n      #   [ option_name_on_target_widget, ... ]\n      #                      #==> set all of them\n      #\n      wins.each{|win|\n        _remove_win(win)\n        @observ << win\n        notify(win)\n      }\n      self\n    end\n\n    def unassign(*wins)\n      wins.each{|win|\n        _remove_win(win)\n      }\n      self\n    end\n\n    def notify(target = nil)\n      if target\n        targets = [target]\n      elsif @observ.empty?\n        return self\n      else\n        targets = @observ.dup\n      end\n\n      return self if empty?\n\n      org_hash = _symbolkey2str(self)\n\n      targets.each{|win|\n        widget = receiver = win\n        hash = org_hash\n        begin\n          if win.kind_of?(Array)\n            widget, method, conv_tbl = win\n            receiver = widget\n\n            if conv_tbl\n              hash = {}\n              org_hash.each{|key, val|\n                key = conv_tbl[key] if conv_tbl.key?(key)\n                next unless key\n                if key.kind_of?(Array)\n                  key.each{|k| hash[k] = val}\n                else              \n                  hash[key] = val\n                end\n              }\n            end\n\n            if method.kind_of?(Array)\n              receiver, method, *args = method\n              receiver.__send__(method, *(args << hash))\n            elsif method\n              widget.__send__(method, hash)\n            else\n              widget.configure(hash)\n            end\n\n          else\n            widget.configure(self)\n          end\n        rescue => e\n          if ( ( widget.kind_of?(TkObject) \\\n                && widget.respond_to?('exist?') \\\n                && ! receiver.exist? ) \\\n            || ( receiver.kind_of?(TkObject) \\\n                && receiver.respond_to?('exist?') \\\n                && ! receiver.exist? ) )\n            @observ.delete(win)\n          else\n            fail e\n          end\n        end\n      }\n\n      self\n    end\n    alias apply notify\n\n    def +(hash)\n      unless hash.kind_of?(Hash)\n        fail ArgumentError, \"expect a Hash\"\n      end\n      new_obj = self.dup\n      new_obj.update_without_notify(_symbolkey2str(hash))\n      new_obj\n    end\n\n    alias update_without_notify update\n\n    def update(hash)\n      update_without_notify(_symbolkey2str(hash))\n      notify\n    end\n\n    def configure(key, value=nil)\n      if key.kind_of?(Hash)\n        update(key)\n      else\n        store(key,value)\n      end\n    end\n\n    def [](key)\n      super(key.to_s)\n    end\n    alias cget []\n\n    def store(key, val)\n      key = key.to_s\n      super(key, val)\n      notify\n    end\n    def []=(key, val)\n      store(key,val)\n    end\n\n    def replace(hash)\n      super(_symbolkey2str(hash))\n      notify\n    end\n\n    def default(opt)\n      fail RuntimeError, \"unknown option `#{opt}'\"\n    end\n    private :default\n\n    undef :default=\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/pack.rb",
    "content": "#\n# tk/pack.rb : control pack geometry manager\n#\nrequire 'tk'\n\nmodule TkPack\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['pack'.freeze].freeze\n\n=begin\n  def configure(win, *args)\n    if args[-1].kind_of?(Hash)\n      opts = args.pop\n    else\n      opts = {}\n    end\n    params = []\n    # params.push((win.kind_of?(TkObject))? win.epath: win)\n    params.push(_epath(win))\n    args.each{|win|\n      # params.push((win.kind_of?(TkObject))? win.epath: win)\n      params.push(_epath(win))\n    }\n    opts.each{|k, v|\n      params.push(\"-#{k}\")\n      # params.push((v.kind_of?(TkObject))? v.epath: v)\n      params.push(_epath(v))\n    }\n    tk_call_without_enc(\"pack\", 'configure', *params)\n  end\n=end\n  def configure(*args)\n    if args[-1].kind_of?(Hash)\n      opts = args.pop\n    else\n      opts = {}\n    end\n    fail ArgumentError, 'no widget is given' if args.empty?\n    params = []\n    args.flatten(1).each{|win| params.push(_epath(win))}\n    opts.each{|k, v|\n      params.push(\"-#{k}\")\n      params.push(_epath(v))  # have to use 'epath' (hash_kv() is unavailable)\n    }\n    tk_call_without_enc(\"pack\", 'configure', *params)\n  end\n  alias pack configure\n\n  def forget(*args)\n    return '' if args.size == 0\n    wins = args.collect{|win|\n      # (win.kind_of?(TkObject))? win.epath: win\n      _epath(win)\n    }\n    tk_call_without_enc('pack', 'forget', *wins)\n  end\n\n  def info(slave)\n    # slave = slave.epath if slave.kind_of?(TkObject)\n    slave = _epath(slave)\n    ilist = list(tk_call_without_enc('pack', 'info', slave))\n    info = {}\n    while key = ilist.shift\n      info[key[1..-1]] = ilist.shift\n    end\n    return info\n  end\n\n  def propagate(master, mode=None)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    if mode == None\n      bool(tk_call_without_enc('pack', 'propagate', master))\n    else\n      tk_call_without_enc('pack', 'propagate', master, mode)\n    end\n  end\n\n  def slaves(master)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    list(tk_call_without_enc('pack', 'slaves', master))\n  end\n\n  module_function :pack, :configure, :forget, :info, :propagate, :slaves\nend\n=begin\ndef TkPack(win, *args)\n  if args[-1].kind_of?(Hash)\n    opts = args.pop\n  else\n    opts = {}\n  end\n  params = []\n  params.push((win.kind_of?(TkObject))? win.epath: win)\n  args.each{|win|\n    params.push((win.kind_of?(TkObject))? win.epath: win)\n  }\n  opts.each{|k, v|\n    params.push(\"-#{k}\")\n    params.push((v.kind_of?(TkObject))? v.epath: v)\n  }\n  tk_call_without_enc(\"pack\", *params)\nend\n=end\n"
  },
  {
    "path": "ext/tk/lib/tk/package.rb",
    "content": "#\n# tk/package.rb : package command\n#\nrequire 'tk'\n\nmodule TkPackage\n  include TkCore\n  extend TkPackage\n\n  TkCommandNames = ['package'.freeze].freeze\n\n  def add_path(path)\n    Tk::AUTO_PATH.value = Tk::AUTO_PATH.to_a << path\n  end\n\n  def forget(package)\n    tk_call('package', 'forget', package)\n    nil\n  end\n\n  def if_needed(pkg, ver, *arg, &b)\n    size = arg.size\n\n    if size==0 && !b\n      # proc info\n      procedure(tk_call('package', 'ifneeded', pkg, ver))\n\n    elsif size==0 && b\n      # set proc\n      cmd = proc(&b)\n      tk_call('package', 'ifneeded', pkg, ver, cmd)\n      cmd\n\n    elsif size==1 && !b\n      # set proc\n      cmd = arg[0]\n      if cmd\n        tk_call('package', 'ifneeded', pkg, ver, cmd)\n        cmd\n      else\n        # remove proc\n        tk_call('package', 'ifneeded', pkg, ver, '')\n        nil\n      end\n\n    else\n      fail ArgumentError, 'too many arguments'\n    end\n  end\n\n  def names\n    tk_split_simplelist(tk_call('package', 'names'))\n  end\n\n  def provide(package, version=nil)\n    if version\n      tk_call('package', 'provide', package, version)\n    end\n    if (ret = tk_call('package', 'provide', package)) == ''\n      nil\n    else\n      ret\n    end\n  end\n\n  def present(package, version=None)\n    begin\n      tk_call('package', 'present', package, version)\n    rescue => e\n      fail e.class, 'TkPackage ' << e.message\n    end\n  end\n\n  def present_exact(package, version)\n    begin\n      tk_call('package', 'present', '-exact', package, version)\n    rescue => e\n      fail e.class, 'TkPackage ' << e.message\n    end\n  end\n\n  def require(package, version=None)\n    begin\n      tk_call('package', 'require', package, version)\n    rescue => e\n      fail e.class, 'TkPackage ' << e.message\n    end\n  end\n\n  def require_exact(package, version)\n    begin\n      tk_call('package', 'require', '-exact', package, version)\n    rescue => e\n      fail e.class, 'TkPackage ' << e.message\n    end\n  end\n\n  def unknown_proc(*arg, &b)\n    size = arg.size\n\n    if size==0 && !b\n      # proc info\n      procedure(tk_call('package', 'unknown'))\n\n    elsif size==0 && b\n      # set proc\n      cmd = proc(&b)\n      tk_call('package', 'unknown', cmd)\n      cmd\n\n    elsif size==1 && !b\n      # set proc\n      cmd = arg[0]\n      if cmd\n        tk_call('package', 'unknown', cmd)\n        cmd\n      else\n        # remove proc\n        tk_call('package', 'unknown', '')\n        nil\n      end\n\n    else\n      fail ArgumentError, 'too many arguments'\n    end\n  end\n\n  def versions(package)\n    tk_split_simplelist(tk_call('package', 'versions', package))\n  end\n\n  def vcompare(version1, version2)\n    number(tk_call('package', 'vcompare', version1, version2))\n  end\n\n  def vsatisfies(version1, version2)\n    bool(tk_call('package', 'vsatisfies', version1, version2))\n  end\n\n  def prefer(setting = None)\n    tk_call('package', 'prefer', setting)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/palette.rb",
    "content": "#\n#   tk/palette.rb : methods for Tcl/Tk standard library 'palette.tcl'\n#                     1998/06/21 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\nrequire 'tk'\n\nmodule TkPalette\n  include Tk\n  extend Tk\n\n  TkCommandNames = [\n    'tk_setPalette'.freeze, \n    'tk_bisque'.freeze, \n    'tkDarken'.freeze\n  ].freeze\n\n  def TkPalette.set(*args)\n    args = args[0].to_a.flatten if args[0].kind_of? Hash\n    tk_call('tk_setPalette', *args)\n  end\n  def TkPalette.setPalette(*args)\n    TkPalette.set(*args)\n  end\n\n  def TkPalette.bisque\n    tk_call('tk_bisque')\n  end\n\n  def TkPalette.darken(color, percent)\n    tk_call('tkDarken', color, percent)\n  end\n\n  def TkPalette.recolorTree(win, colors)\n    if not colors.kind_of?(Hash)\n      fail \"2nd arg need to be Hash\"\n    end\n\n    tk_call('global', \"tkPalette\")\n    colors.each{|key, value|\n      begin\n        if win.cget(key) == tk_call('set', \"tkPalette(#{key})\")\n          win[key] = colors[key]\n        end\n      rescue\n        # ignore\n      end\n    }\n\n    TkWinfo.children(win).each{|w| TkPalette.recolorTree(w, colors)}\n  end\n\n  def recolorTree(colors)\n    TkPalette.recolorTree(self, colors)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/panedwindow.rb",
    "content": "#\n# tk/panedwindow.rb : treat panedwindow\n#\nrequire 'tk'\n\nclass Tk::PanedWindow<TkWindow\n  TkCommandNames = ['panedwindow'.freeze].freeze\n  WidgetClassName = 'Panedwindow'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('panedwindow', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def add(*args)\n    keys = args.pop\n    fail ArgumentError, \"no window in arguments\" unless keys\n    if keys && keys.kind_of?(Hash)\n      fail ArgumentError, \"no window in arguments\" if args == []\n      # args = args.collect{|w| (w.kind_of?(TkObject))? w.epath: w }\n      args = args.collect{|w| _epath(w) }\n      #args.push(hash_kv(keys))\n      args.concat(hash_kv(keys))\n    else\n      args.push(keys) if keys\n      # args = args.collect{|w| (w.kind_of?(TkObject))? w.epath: w }\n      args = args.collect{|w| _epath(w) }\n    end\n    tk_send_without_enc('add', *args)\n    self\n  end\n\n  def forget(win, *wins)\n    wins.unshift(win)\n    # tk_send_without_enc('forget', *((w.kind_of?(TkObject))? w.epath: w))\n    tk_send_without_enc('forget', *(wins.collect{|w| _epath(w)}))\n    self\n  end\n  alias del forget\n  alias delete forget\n  alias remove forget\n\n  def identify(x, y)\n    list(tk_send_without_enc('identify', x, y))\n  end\n\n  def proxy_coord\n    list(tk_send_without_enc('proxy', 'coord'))\n  end\n  def proxy_forget\n    tk_send_without_enc('proxy', 'forget')\n    self\n  end\n  def proxy_place(x, y)\n    tk_send_without_enc('proxy', 'place', x, y)\n    self\n  end\n\n  def sash_coord(index)\n    list(tk_send('sash', 'coord', index))\n  end\n  def sash_dragto(index, x, y)\n    tk_send('sash', 'dragto', index, x, y)\n    self\n  end\n  def sash_mark(index, x, y)\n    tk_send('sash', 'mark', index, x, y)\n    self\n  end\n  def sash_place(index, x, y)\n    tk_send('sash', 'place', index, x, y)\n    self\n  end\n\n  def panecget_strict(win, key)\n    # win = win.epath if win.kind_of?(TkObject)\n    win = _epath(win)\n    tk_tcl2ruby(tk_send_without_enc('panecget', win, \"-#{key}\"))\n  end\n  def panecget(win, key)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      panecget_strict(win, key)\n    else\n      begin\n        panecget_strict(win, key)\n      rescue => e\n        begin\n          if current_paneconfiginfo(win).has_key?(option.to_s)\n            # not tag error & option is known -> error on known option\n            fail e\n          else\n            # not tag error & option is unknown\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n\n  def paneconfigure(win, key, value=nil)\n    # win = win.epath if win.kind_of?(TkObject)\n    win = _epath(win)\n    if key.kind_of? Hash\n      params = []\n      key.each{|k, v|\n        params.push(\"-#{k}\")\n        # params.push((v.kind_of?(TkObject))? v.epath: v)\n        params.push(_epath(v))\n      }\n      tk_send_without_enc('paneconfigure', win, *params)\n    else\n      # value = value.epath if value.kind_of?(TkObject)\n      value = _epath(value)\n      tk_send_without_enc('paneconfigure', win, \"-#{key}\", value)\n    end\n    self\n  end\n  alias pane_config paneconfigure\n\n  def paneconfiginfo(win, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      # win = win.epath if win.kind_of?(TkObject)\n      win = _epath(win)\n      if key\n        #conf = tk_split_list(tk_send_without_enc('paneconfigure', \n        #                                         win, \"-#{key}\"))\n        conf = tk_split_list(tk_send_without_enc('paneconfigure', \n                                                 win, \"-#{key}\"), \n                             false, true)\n        conf[0] = conf[0][1..-1]\n        if conf[0] == 'hide'\n          conf[3] = bool(conf[3]) unless conf[3].empty?\n          conf[4] = bool(conf[4]) unless conf[4].empty?\n        end\n        conf\n      else\n        #tk_split_simplelist(tk_send_without_enc('paneconfigure', \n        #                                        win)).collect{|conflist|\n        #  conf = tk_split_simplelist(conflist)\n        tk_split_simplelist(tk_send_without_enc('paneconfigure', win), \n                            false, false).collect{|conflist|\n          conf = tk_split_simplelist(conflist, false, true)\n          conf[0] = conf[0][1..-1]\n          if conf[3]\n            if conf[0] == 'hide'\n              conf[3] = bool(conf[3]) unless conf[3].empty?\n            elsif conf[3].index('{')\n              conf[3] = tk_split_list(conf[3]) \n            else\n              conf[3] = tk_tcl2ruby(conf[3]) \n            end\n          end\n          if conf[4]\n            if conf[0] == 'hide'\n              conf[4] = bool(conf[4]) unless conf[4].empty?\n            elsif conf[4].index('{')\n              conf[4] = tk_split_list(conf[4]) \n            else\n              conf[4] = tk_tcl2ruby(conf[4]) \n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      # win = win.epath if win.kind_of?(TkObject)\n      win = _epath(win)\n      if key\n        #conf = tk_split_list(tk_send_without_enc('paneconfigure', \n        #                                         win, \"-#{key}\"))\n        conf = tk_split_list(tk_send_without_enc('paneconfigure', \n                                                 win, \"-#{key}\"), \n                             false, true)\n        key = conf.shift[1..-1]\n        if key == 'hide'\n          conf[2] = bool(conf[2]) unless conf[2].empty?\n          conf[3] = bool(conf[3]) unless conf[3].empty?\n        end\n        { key => conf }\n      else\n        ret = {}\n        #tk_split_simplelist(tk_send_without_enc('paneconfigure', \n        #                                        win)).each{|conflist|\n        #  conf = tk_split_simplelist(conflist)\n        tk_split_simplelist(tk_send_without_enc('paneconfigure', win), \n                            false, false).each{|conflist|\n          conf = tk_split_simplelist(conflist, false, true)\n          key = conf.shift[1..-1]\n          if key\n            if key == 'hide'\n              conf[2] = bool(conf[2]) unless conf[2].empty?\n            elsif conf[2].index('{')\n              conf[2] = tk_split_list(conf[2]) \n            else\n              conf[2] = tk_tcl2ruby(conf[2]) \n            end\n          end\n          if conf[3]\n            if key == 'hide'\n              conf[3] = bool(conf[3]) unless conf[3].empty?\n            elsif conf[3].index('{')\n              conf[3] = tk_split_list(conf[3]) \n            else\n              conf[3] = tk_tcl2ruby(conf[3]) \n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        ret\n      end\n    end\n  end\n  alias pane_configinfo paneconfiginfo\n\n  def current_paneconfiginfo(win, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        conf = paneconfiginfo(win, key)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        paneconfiginfo(win).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      paneconfiginfo(win, key).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n\n  alias current_pane_configinfo current_paneconfiginfo\n\n  def panes\n    list(tk_send_without_enc('panes'))\n  end\nend\n\nTk::Panedwindow = Tk::PanedWindow\n#TkPanedWindow = Tk::PanedWindow unless Object.const_defined? :TkPanedWindow\n#TkPanedwindow = Tk::Panedwindow unless Object.const_defined? :TkPanedwindow\nTk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow, \n                            :TkPanedWindow, :TkPanedwindow)\n"
  },
  {
    "path": "ext/tk/lib/tk/place.rb",
    "content": "#\n# tk/place.rb : control place geometry manager\n#\nrequire 'tk'\n\nmodule TkPlace\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['place'.freeze].freeze\n\n  def configure(win, slot, value=None)\n    # for >= Tk8.4a2 ?\n    # win = win.epath if win.kind_of?(TkObject)\n    win = _epath(win)\n    if slot.kind_of? Hash\n      params = []\n      slot.each{|k, v|\n        params.push(\"-#{k}\")\n        # params.push((v.kind_of?(TkObject))? v.epath: v)\n        params.push(_epath(v))\n      }\n      tk_call_without_enc('place', 'configure', win, *params)\n    else\n      # value = value.epath if value.kind_of?(TkObject)\n      value = _epath(value)\n      tk_call_without_enc('place', 'configure', win, \"-#{slot}\", value)\n    end\n  end\n  alias place configure\n\n  def configinfo(win, slot = nil)\n    # for >= Tk8.4a2 ?\n    if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      # win = win.epath if win.kind_of?(TkObject)\n      win = _epath(win)\n      if slot\n        #conf = tk_split_list(tk_call_without_enc('place', 'configure', \n        #                                        win, \"-#{slot}\") )\n        conf = tk_split_simplelist(tk_call_without_enc('place', 'configure', \n                                                       win, \"-#{slot}\") )\n        conf[0] = conf[0][1..-1]\n        conf[1] = tk_tcl2ruby(conf[1])\n        conf[2] = tk_tcl2ruby(conf[1])\n        conf[3] = tk_tcl2ruby(conf[1])\n        conf[4] = tk_tcl2ruby(conf[1])\n        conf\n      else\n        tk_split_simplelist(tk_call_without_enc('place', 'configure', \n                                                win)).collect{|conflist|\n          #conf = list(conflist)\n          conf = simplelist(conflist).collect!{|inf| tk_tcl2ruby(inf)}\n          conf[0] = conf[0][1..-1]\n          conf\n        }\n      end\n    else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      current_configinfo(win, slot)\n    end\n  end\n\n  def current_configinfo(win, slot = nil)\n    # win = win.epath if win.kind_of?(TkObject)\n    win = _epath(win)\n    if slot\n      #conf = tk_split_list(tk_call_without_enc('place', 'configure', \n      #                                         win, \"-#{slot}\") )\n      conf = tk_split_simplelist(tk_call_without_enc('place', 'configure', \n                                                     win, \"-#{slot}\") )\n      # { conf[0][1..-1] => conf[1] }\n      { conf[0][1..-1] => tk_tcl2ruby(conf[4]) }\n    else\n      ret = {}\n      #tk_split_list(tk_call_without_enc('place','configure',win)).each{|conf|\n      tk_split_simplelist(tk_call_without_enc('place', 'configure', \n                                              win)).each{|conf_list|\n        #ret[conf[0][1..-1]] = conf[1]\n        conf = simplelist(conf_list)\n        ret[conf[0][1..-1]] = tk_tcl2ruby(conf[4])\n      }\n      ret\n    end\n  end\n\n  def forget(win)\n    # win = win.epath if win.kind_of?(TkObject)\n    win = _epath(win)\n    tk_call_without_enc('place', 'forget', win)\n  end\n\n  def info(win)\n    # win = win.epath if win.kind_of?(TkObject)\n    win = _epath(win)\n    #ilist = list(tk_call_without_enc('place', 'info', win))\n    ilist = simplelist(tk_call_without_enc('place', 'info', win))\n    info = {}\n    while key = ilist.shift\n      #info[key[1..-1]] = ilist.shift\n      info[key[1..-1]] = tk_tcl2ruby(ilist.shift)\n    end\n    return info\n  end\n\n  def slaves(master)\n    # master = master.epath if master.kind_of?(TkObject)\n    master = _epath(master)\n    list(tk_call('place', 'slaves', master))\n  end\n\n  module_function :place, :configure, :configinfo, :current_configinfo\n  module_function :forget, :info, :slaves\nend\n=begin\ndef TkPlace(win, slot, value=None)\n  win = win.epath if win.kind_of?(TkObject)\n  if slot.kind_of? Hash\n    params = []\n    slot.each{|k, v|\n      params.push(\"-#{k}\")\n      params.push((v.kind_of?(TkObject))? v.epath: v)\n    }\n    tk_call_without_enc('place', win, *params)\n  else\n    value = value.epath if value.kind_of?(TkObject)\n    tk_call_without_enc('place', win, \"-#{slot}\", value)\n  end\nend\n=end\n"
  },
  {
    "path": "ext/tk/lib/tk/radiobutton.rb",
    "content": "#\n# tk/radiobutton.rb : treat radiobutton widget\n#\nrequire 'tk'\nrequire 'tk/button'\n\nclass Tk::RadioButton<Tk::Button\n  TkCommandNames = ['radiobutton'.freeze].freeze\n  WidgetClassName = 'Radiobutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('radiobutton', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def __boolval_optkeys\n    super() << 'indicatoron'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'selectcolor'\n  end\n  private :__strval_optkeys\n\n  def __ruby2val_optkeys  # { key=>proc, ... }\n    {\n      'variable'=>proc{|v| tk_trace_variable(v)}  # for backward compatibility\n    }\n  end\n  private :__ruby2val_optkeys\n\n\n  def deselect\n    tk_send_without_enc('deselect')\n    self\n  end\n  def select\n    tk_send_without_enc('select')\n    self\n  end\n\n  def get_value\n    var = tk_send_without_enc('cget', '-variable')\n    if TkVariable::USE_TCLs_SET_VARIABLE_FUNCTIONS\n      _fromUTF8(INTERP._get_global_var(var))\n    else\n      INTERP._eval(Kernel.format('global %s; set %s', var, var))\n    end\n  end\n\n  def set_value(val)\n    var = tk_send_without_enc('cget', '-variable')\n    if TkVariable::USE_TCLs_SET_VARIABLE_FUNCTIONS\n      _fromUTF8(INTERP._set_global_var(var, _get_eval_string(val, true)))\n    else\n      s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(Kernel.format('global %s; set %s %s', var, var, s))\n    end\n  end\nend\n\nTk::Radiobutton = Tk::RadioButton\n#TkRadioButton = Tk::RadioButton unless Object.const_defined? :TkRadioButton\n#TkRadiobutton = Tk::Radiobutton unless Object.const_defined? :TkRadiobutton\nTk.__set_toplevel_aliases__(:Tk, Tk::RadioButton, \n                            :TkRadioButton, :TkRadiobutton)\n"
  },
  {
    "path": "ext/tk/lib/tk/root.rb",
    "content": "#\n# tk/root.rb : treat root widget\n#\nrequire 'tk'\nrequire 'tk/wm'\nrequire 'tk/menuspec'\n\nclass Tk::Root<TkWindow\n  include Wm\n  include TkMenuSpec\n\n  def __methodcall_optkeys  # { key=>method, ... }\n    TOPLEVEL_METHODCALL_OPTKEYS\n  end\n  private :__methodcall_optkeys\n\n  def Root.new(keys=nil, &b)\n    unless TkCore::INTERP.tk_windows['.']\n      TkCore::INTERP.tk_windows['.'] = \n        super(:without_creating=>true, :widgetname=>'.'){}\n    end\n    root = TkCore::INTERP.tk_windows['.']\n\n    keys = _symbolkey2str(keys)\n\n    # wm commands\n    root.instance_eval{\n      __methodcall_optkeys.each{|key, method|\n        value = keys.delete(key.to_s)\n        self.__send__(method, value) if value\n      }\n    }\n\n    if keys  # wm commands ( for backward comaptibility )\n      keys.each{|k,v|\n        if v.kind_of? Array\n          root.__send__(k,*v)\n        else\n          root.__send__(k,v)\n        end\n      }\n    end\n\n    if block_given?\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        root.instance_exec(root, &b)\n      else\n        root.instance_eval(&b)\n      end\n    end\n    root\n  end\n\n  WidgetClassName = 'Tk'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.to_eval\n    # self::WidgetClassName\n    '.'\n  end\n\n  def create_self\n    @path = '.'\n  end\n  private :create_self\n\n  def path\n    \".\"\n  end\n\n  def add_menu(menu_info, tearoff=false, opts=nil)\n    # See tk/menuspec.rb for menu_info.\n    # opts is a hash of default configs for all of cascade menus. \n    # Configs of menu_info can override it. \n    if tearoff.kind_of?(Hash)\n      opts = tearoff\n      tearoff = false\n    end\n    _create_menubutton(self, menu_info, tearoff, opts)\n  end\n\n  def add_menubar(menu_spec, tearoff=false, opts=nil)\n    # See tk/menuspec.rb for menu_spec.\n    # opts is a hash of default configs for all of cascade menus.\n    # Configs of menu_spec can override it. \n    menu_spec.each{|info| add_menu(info, tearoff, opts)}\n    self.menu\n  end\n\n  def Root.destroy\n    TkCore::INTERP._invoke('destroy', '.')\n  end\nend\n\nTkRoot = Tk::Root unless Object.const_defined? :TkRoot\n"
  },
  {
    "path": "ext/tk/lib/tk/scale.rb",
    "content": "#\n# tk/scale.rb : treat scale widget\n#\nrequire 'tk'\n\nclass Tk::Scale<TkWindow\n  TkCommandNames = ['scale'.freeze].freeze\n  WidgetClassName = 'Scale'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    if keys and keys != None\n      if keys.key?('command') && ! keys['command'].kind_of?(String)\n        cmd = keys.delete('command')\n        keys['command'] = proc{|val| cmd.call(val.to_f)}\n      end\n      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        #tk_call_without_enc('scale', @path, *hash_kv(keys, true))\n        tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                            *hash_kv(keys, true))\n      else\n        begin\n          tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                              *hash_kv(keys, true))\n        rescue\n          tk_call_without_enc(self.class::TkCommandNames[0], @path)\n          keys = __check_available_configure_options(keys)\n          unless keys.empty?\n            begin\n              tk_call_without_enc('destroy', @path)\n            rescue\n              # cannot destroy\n              configure(keys)\n            else\n              # re-create widget\n              tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                                  *hash_kv(keys, true))\n            end\n          end\n        end\n      end\n    else\n      #tk_call_without_enc('scale', @path)\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def __strval_optkeys\n    super() << 'label'\n  end\n  private :__strval_optkeys\n\n  def _wrap_command_arg(cmd)\n    proc{|val|\n      if val.kind_of?(String)\n        cmd.call(number(val))\n      else\n        cmd.call(val)\n      end\n    }\n  end\n  private :_wrap_command_arg\n\n  def configure_cmd(slot, value)\n    configure(slot=>value)\n  end\n\n  def configure(slot, value=None)\n    if (slot == 'command' || slot == :command)\n      configure('command'=>value)\n    elsif slot.kind_of?(Hash) && \n        (slot.key?('command') || slot.key?(:command))\n      slot = _symbolkey2str(slot)\n      slot['command'] = _wrap_command_arg(slot.delete('command'))\n    end\n    super(slot, value)\n  end\n\n  def command(cmd=Proc.new)\n    configure('command'=>cmd)\n  end\n\n  def get(x=None, y=None)\n    number(tk_send_without_enc('get', x, y))\n  end\n\n  def coords(val=None)\n    tk_split_list(tk_send_without_enc('coords', val))\n  end\n\n  def identify(x, y)\n    tk_send_without_enc('identify', x, y)\n  end\n\n  def set(val)\n    tk_send_without_enc('set', val)\n  end\n\n  def value\n    get\n  end\n\n  def value= (val)\n    set(val)\n    val\n  end\nend\n\n#TkScale = Tk::Scale unless Object.const_defined? :TkScale\nTk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)\n"
  },
  {
    "path": "ext/tk/lib/tk/scrollable.rb",
    "content": "#\n# tk/scrollable.rb : module for scrollable widget\n#\nrequire 'tk'\n\nmodule Tk\n  module XScrollable\n    def xscrollcommand(cmd=Proc.new)\n      configure_cmd 'xscrollcommand', cmd\n      # Tk.update  # avoid scrollbar trouble\n      self\n    end\n\n    def xview(*index)\n      if index.size == 0\n        list(tk_send_without_enc('xview'))\n      else\n        tk_send_without_enc('xview', *index)\n        self\n      end\n    end\n    def xview_moveto(*index)\n      xview('moveto', *index)\n    end\n    def xview_scroll(*index)\n      xview('scroll', *index)\n    end\n\n    def xscrollbar(bar=nil)\n      if bar\n        @xscrollbar = bar\n        @xscrollbar.orient 'horizontal'\n        self.xscrollcommand {|*arg| @xscrollbar.set(*arg)}\n        @xscrollbar.command {|*arg| self.xview(*arg)}\n        Tk.update  # avoid scrollbar trouble\n      end\n      @xscrollbar\n    end\n  end\n\n  module YScrollable\n    def yscrollcommand(cmd=Proc.new)\n      configure_cmd 'yscrollcommand', cmd\n      # Tk.update  # avoid scrollbar trouble\n      self\n    end\n\n    def yview(*index)\n      if index.size == 0\n        list(tk_send_without_enc('yview'))\n      else\n        tk_send_without_enc('yview', *index)\n        self\n      end\n    end\n    def yview_moveto(*index)\n      yview('moveto', *index)\n    end\n    def yview_scroll(*index)\n      yview('scroll', *index)\n    end\n\n    def yscrollbar(bar=nil)\n      if bar\n        @yscrollbar = bar\n        @yscrollbar.orient 'vertical'\n        self.yscrollcommand {|*arg| @yscrollbar.set(*arg)}\n        @yscrollbar.command {|*arg| self.yview(*arg)}\n        Tk.update  # avoid scrollbar trouble\n      end\n      @yscrollbar\n    end\n  end\n\n  X_Scrollable = XScrollable\n  Y_Scrollable = YScrollable\n\n  module Scrollable\n    include XScrollable\n    include YScrollable\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/scrollbar.rb",
    "content": "#\n# tk/scrollbar.rb : treat scrollbar widget\n#\nrequire 'tk'\n\nclass Tk::Scrollbar<TkWindow\n  TkCommandNames = ['scrollbar'.freeze].freeze\n  WidgetClassName = 'Scrollbar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    @assigned = []\n    @scroll_proc = proc{|*args| \n      if self.orient == 'horizontal'\n        @assigned.each{|w| w.xview(*args)}\n      else # 'vertical'\n        @assigned.each{|w| w.yview(*args)}\n      end\n    }\n\n    if keys and keys != None\n      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        #tk_call_without_enc('scrollbar', @path, *hash_kv(keys, true))\n        tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                            *hash_kv(keys, true))\n      else\n        begin\n          tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                              *hash_kv(keys, true))\n        rescue\n          tk_call_without_enc(self.class::TkCommandNames[0], @path)\n          keys = __check_available_configure_options(keys)\n          unless keys.empty?\n            begin\n              tk_call_without_enc('destroy', @path)\n            rescue\n              # cannot destroy\n              configure(keys)\n            else\n              # re-create widget\n              tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                                  *hash_kv(keys, true))\n            end\n          end\n        end\n      end\n    else\n      #tk_call_without_enc('scrollbar', @path)\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def propagate_set(src_win, first, last)\n    self.set(first, last)\n    if self.orient == 'horizontal'\n      @assigned.each{|w| w.xview('moveto', first) if w != src_win}\n    else # 'vertical'\n      @assigned.each{|w| w.yview('moveto', first) if w != src_win}\n    end\n  end\n\n  def assign(*wins)\n    begin\n      self.command(@scroll_proc) if self.cget('command').cmd != @scroll_proc\n    rescue Exception\n      self.command(@scroll_proc)\n    end\n    orient = self.orient\n    wins.each{|w|\n      @assigned << w unless @assigned.index(w)\n      if orient == 'horizontal'\n        w.xscrollcommand proc{|first, last| self.propagate_set(w, first, last)}\n      else # 'vertical'\n        w.yscrollcommand proc{|first, last| self.propagate_set(w, first, last)}\n      end\n    }\n    Tk.update  # avoid scrollbar trouble\n    self\n  end\n\n  def assigned_list\n    begin\n      return @assigned.dup if self.cget('command').cmd == @scroll_proc\n    rescue Exception\n    end\n    fail RuntimeError, \"not depend on the assigned_list\"\n  end\n\n  def configure(*args)\n    ret = super(*args)\n    # Tk.update  # avoid scrollbar trouble\n    ret\n  end\n\n  #def delta(deltax=None, deltay=None)\n  def delta(deltax, deltay)\n    number(tk_send_without_enc('delta', deltax, deltay))\n  end\n\n  #def fraction(x=None, y=None)\n  def fraction(x, y)\n    number(tk_send_without_enc('fraction', x, y))\n  end\n\n  def identify(x, y)\n    tk_send_without_enc('identify', x, y)\n  end\n\n  def get\n    #ary1 = tk_send('get').split\n    #ary2 = []\n    #for i in ary1\n    #  ary2.push number(i)\n    #end\n    #ary2\n    list(tk_send_without_enc('get'))\n  end\n\n  def set(first, last)\n    tk_send_without_enc('set', first, last)\n    self\n  end\n\n  def activate(element=None)\n    tk_send_without_enc('activate', element)\n  end\n\n  def moveto(fraction)\n    tk_send_without_enc('moveto', fraction)\n    self\n  end\n\n  def scroll(*args)\n    tk_send_without_enc('scroll', *args)\n    self\n  end\n\n  def scroll_units(num)\n    scroll(num, 'units')\n    self\n  end\n\n  def scroll_pages(num)\n    scroll(num, 'pages')\n    self\n  end\nend\n\n#TkScrollbar = Tk::Scrollbar unless Object.const_defined? :TkScrollbar\nTk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)\n\n\nclass Tk::XScrollbar<Tk::Scrollbar\n  def create_self(keys)\n    keys = {} unless keys\n    keys['orient'] = 'horizontal'\n    super(keys)\n  end\n  private :create_self\nend\n\n#TkXScrollbar = Tk::XScrollbar unless Object.const_defined? :TkXScrollbar\nTk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)\n\n\nclass Tk::YScrollbar<Tk::Scrollbar\n  def create_self(keys)\n    keys = {} unless keys\n    keys['orient'] = 'vertical'\n    super(keys)\n  end\n  private :create_self\nend\n\n#TkYScrollbar = Tk::YScrollbar unless Object.const_defined? :TkYScrollbar\nTk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)\n"
  },
  {
    "path": "ext/tk/lib/tk/scrollbox.rb",
    "content": "#\n#               tk/scrollbox.rb - Tk Listbox with Scrollbar\n#                                 as an example of Composite Widget\n#                       by Yukihiro Matsumoto <matz@netlab.co.jp>\n#\nrequire 'tk'\nrequire 'tk/listbox'\n\nclass TkScrollbox<Tk::Listbox\n  include TkComposite\n  def initialize_composite(keys=nil)\n    #list = Tk::Listbox.new(@frame)\n    # -> use current TkListbox class\n    list = TkListbox.new(@frame)\n    #scroll = Tk::Scrollbar.new(@frame)\n    # -> use current TkScrollbar class\n    scroll = TkScrollbar.new(@frame)\n    @path = list.path\n\n=begin\n    list.configure 'yscroll', scroll.path+\" set\"\n    list.pack 'side'=>'left','fill'=>'both','expand'=>'yes'\n    scroll.configure 'command', list.path+\" yview\"\n    scroll.pack 'side'=>'right','fill'=>'y'\n=end\n    list.yscrollbar(scroll)\n    list.pack('side'=>'left','fill'=>'both','expand'=>'yes')\n    scroll.pack('side'=>'right','fill'=>'y')\n\n    delegate('DEFAULT', list)\n    delegate('foreground', list)\n    delegate('background', list, scroll)\n    delegate('borderwidth', @frame)\n    delegate('relief', @frame)\n\n    configure keys if keys\n  end\n  private :initialize_composite\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/selection.rb",
    "content": "#\n# tk/selection.rb : control selection\n#\nrequire 'tk'\n\nmodule TkSelection\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['selection'.freeze].freeze\n\n  def self.clear(sel=nil)\n    if sel\n      tk_call_without_enc('selection', 'clear', '-selection', sel)\n    else\n      tk_call_without_enc('selection', 'clear')\n    end\n  end\n  def self.clear_on_display(win, sel=nil)\n    if sel\n      tk_call_without_enc('selection', 'clear', \n                          '-displayof', win, '-selection', sel)\n    else\n      tk_call_without_enc('selection', 'clear', '-displayof', win)\n    end\n  end\n  def clear(sel=nil)\n    TkSelection.clear_on_display(self, sel)\n    self\n  end\n\n  def self.get(keys=nil)\n    #tk_call('selection', 'get', *hash_kv(keys))\n    _fromUTF8(tk_call_without_enc('selection', 'get', *hash_kv(keys)))\n  end\n  def self.get_on_display(win, keys=nil)\n    #tk_call('selection', 'get', '-displayof', win, *hash_kv(keys))\n    _fromUTF8(tk_call_without_enc('selection', 'get', '-displayof', \n                                  win, *hash_kv(keys)))\n  end\n  def get(keys=nil)\n    TkSelection.get_on_display(self, sel)\n  end\n\n  def self.handle(win, func=Proc.new, keys=nil, &b)\n    if func.kind_of?(Hash) && keys == nil\n      keys = func\n      func = Proc.new(&b)\n    end\n    args = ['selection', 'handle']\n    args.concat(hash_kv(keys))\n    args.concat([win, func])\n    tk_call_without_enc(*args)\n  end\n  def handle(func=Proc.new, keys=nil, &b)\n    TkSelection.handle(self, func, keys, &b)\n  end\n\n  def self.get_owner(sel=nil)\n    if sel\n      window(tk_call_without_enc('selection', 'own', '-selection', sel))\n    else\n      window(tk_call_without_enc('selection', 'own'))\n    end\n  end\n  def self.get_owner_on_display(win, sel=nil)\n    if sel\n      window(tk_call_without_enc('selection', 'own', \n                                 '-displayof', win, '-selection', sel))\n    else\n      window(tk_call_without_enc('selection', 'own', '-displayof', win))\n    end\n  end\n  def get_owner(sel=nil)\n    TkSelection.get_owner_on_display(self, sel)\n    self\n  end\n\n  def self.set_owner(win, keys=nil)\n    tk_call_without_enc('selection', 'own', *(hash_kv(keys) << win))\n  end\n  def set_owner(keys=nil)\n    TkSelection.set_owner(self, keys)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/spinbox.rb",
    "content": "#\n#               tk/spinbox.rb - Tk spinbox classes\n#                       by Yukihiro Matsumoto <matz@caelum.co.jp>\n#\nrequire 'tk'\nrequire 'tk/entry'\n\nclass Tk::Spinbox<Tk::Entry\n  TkCommandNames = ['spinbox'.freeze].freeze\n  WidgetClassName = 'Spinbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  class SpinCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?d, ?s, :direction ], \n        [ ?s, ?e, :current ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n\n        [ ?e, proc{|val|\n            #enc = Tk.encoding\n            enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system)\n            if enc\n              Tk.fromUTF8(TkComm::string(val), enc)\n            else\n              TkComm::string(val)\n            end\n          }\n        ], \n\n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        (val)? '1': '0'\n      end\n    end\n\n    def self._config_keys\n      ['command']\n    end\n  end\n\n  def __validation_class_list\n    super() << SpinCommand\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, SpinCommand)\n\n  #def create_self(keys)\n  #  tk_call_without_enc('spinbox', @path)\n  #  if keys and keys != None\n  #    configure(keys)\n  #  end\n  #end\n  #private :create_self\n\n  def __boolval_optkeys\n    super() << 'wrap'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'buttonbackground' << 'format'\n  end\n  private :__strval_optkeys\n\n  def __listval_optkeys\n    super() << 'values'\n  end\n  private :__listval_optkeys\n\n  def identify(x, y)\n    tk_send_without_enc('identify', x, y)\n  end\n\n  def spinup\n    tk_send_without_enc('invoke', 'spinup')\n    self\n  end\n\n  def spindown\n    tk_send_without_enc('invoke', 'spindown')\n    self\n  end\n\n  def set(str)\n    _fromUTF8(tk_send_without_enc('set', _get_eval_enc_str(str)))\n  end\nend\n\n#TkSpinbox = Tk::Spinbox unless Object.const_defined? :TkSpinbox\nTk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)\n"
  },
  {
    "path": "ext/tk/lib/tk/tagfont.rb",
    "content": "#\n# tk/tagfont.rb : control font of tags\n#\nrequire 'tk'\n\nmodule TkTreatTagFont\n  def font_configinfo\n    @parent.tagfont_configinfo(@id)\n  end\n#  alias font font_configinfo\n\n  def font_configure(slot)\n    @parent.tagfont_configure(@id, slot)\n    self\n  end\n\n  def latinfont_configure(ltn, keys=nil)\n    @parent.latintagfont_configure(@id, ltn, keys)\n    self\n  end\n  alias asciifont_configure latinfont_configure\n\n  def kanjifont_configure(knj, keys=nil)\n    @parent.kanjitagfont_configure(@id, ltn, keys)\n    self\n  end\n\n  def font_copy(win, wintag=nil)\n    @parent.tagfont_copy(@id, win, wintag)\n    self\n  end\n\n  def latinfont_copy(win, wintag=nil)\n    @parent.latintagfont_copy(@id, win, wintag)\n    self\n  end\n  alias asciifont_copy latinfont_copy\n\n  def kanjifont_copy(win, wintag=nil)\n    @parent.kanjitagfont_copy(@id, win, wintag)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/text.rb",
    "content": "#\n#               tk/text.rb - Tk text classes\n#                       by Yukihiro Matsumoto <matz@caelum.co.jp>\nrequire 'tk'\nrequire 'tk/itemfont'\nrequire 'tk/itemconfig'\nrequire 'tk/scrollable'\nrequire 'tk/txtwin_abst'\n\nmodule TkTextTagConfig\n  include TkTreatItemFont\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)  # id := [ type, tagOrId ]\n    [self.path, id[0], 'cget', id[1]]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)  # id := [ type, tagOrId ]\n    [self.path, id[0], 'configure', id[1]]\n  end\n  private :__item_config_cmd\n\n  def __item_pathname(id)\n    if id.kind_of?(Array)\n      id = tagid(id[1])\n    end\n    [self.path, id].join(';')\n  end\n  private :__item_pathname\n\n  def tag_cget(tagOrId, option)\n    itemcget(['tag', tagOrId], option)\n  end\n  def tag_cget_strict(tagOrId, option)\n    itemcget_strict(['tag', tagOrId], option)\n  end\n  def tag_configure(tagOrId, slot, value=None)\n    itemconfigure(['tag', tagOrId], slot, value)\n  end\n  def tag_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['tag', tagOrId], slot)\n  end\n  def current_tag_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['tag', tagOrId], slot)\n  end\n\n  def window_cget(tagOrId, option)\n    itemcget(['window', tagOrId], option)\n  end\n  def window_cget_strict(tagOrId, option)\n    itemcget_strict(['window', tagOrId], option)\n  end\n  def window_configure(tagOrId, slot, value=None)\n    itemconfigure(['window', tagOrId], slot, value)\n  end\n  def window_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['window', tagOrId], slot)\n  end\n  def current_window_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['window', tagOrId], slot)\n  end\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\nend\n\nclass Tk::Text<TkTextWin\n  ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze\n  #include TkTreatTextTagFont\n  include TkTextTagConfig\n  include Scrollable\n\n  #######################################\n\n  module IndexModMethods\n    def +(mod)\n      return chars(mod) if mod.kind_of?(Numeric)\n\n      mod = mod.to_s\n      if mod =~ /^\\s*[+-]?\\d/\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod)\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod)\n      end\n    end\n\n    def -(mod)\n      return chars(-mod) if mod.kind_of?(Numeric)\n\n      mod = mod.to_s\n      if mod =~ /^\\s*[+-]?\\d/\n        Tk::Text::IndexString.new(String.new(id) << ' - ' << mod)\n      elsif mod =~ /^\\s*[-]\\s+(\\d.*)$/\n        Tk::Text::IndexString.new(String.new(id) << ' - -' << $1)\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod)\n      end\n    end\n\n    def chars(mod)\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' chars')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' chars')\n      end\n    end\n    alias char chars\n\n    def display_chars(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display chars')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display chars')\n      end\n    end\n    alias display_char display_chars\n\n    def any_chars(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any chars')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any chars')\n      end\n    end\n    alias any_char any_chars\n\n    def indices(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' indices')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' indices')\n      end\n    end\n\n    def display_indices(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display indices')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display indices')\n      end\n    end\n\n    def any_indices(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any indices')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any indices')\n      end\n    end\n\n    def lines(mod)\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' lines')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' lines')\n      end\n    end\n    alias line lines\n\n    def display_lines(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' display_lines')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' display lines')\n      end\n    end\n    alias display_line display_lines\n\n    def any_lines(mod)\n      # Tk8.5 feature\n      fail ArgumentError, 'expect Integer'  unless mod.kind_of?(Integer)\n      if mod < 0\n        Tk::Text::IndexString.new(String.new(id) << ' ' << mod.to_s << ' any_lines')\n      else\n        Tk::Text::IndexString.new(String.new(id) << ' + ' << mod.to_s << ' any lines')\n      end\n    end\n    alias any_line any_lines\n\n    def linestart\n      Tk::Text::IndexString.new(String.new(id) << ' linestart')\n    end\n    def lineend\n      Tk::Text::IndexString.new(String.new(id) << ' lineend')\n    end\n\n    def display_linestart\n      # Tk8.5 feature\n      Tk::Text::IndexString.new(String.new(id) << ' display linestart')\n    end\n    def display_lineend\n      # Tk8.5 feature\n      Tk::Text::IndexString.new(String.new(id) << ' display lineend')\n    end\n\n    def wordstart\n      Tk::Text::IndexString.new(String.new(id) << ' wordstart')\n    end\n    def wordend\n      Tk::Text::IndexString.new(String.new(id) << ' wordend')\n    end\n\n    def display_wordstart\n      # Tk8.5 feature\n      Tk::Text::IndexString.new(String.new(id) << ' display wordstart')\n    end\n    def display_wordend\n      # Tk8.5 feature\n      Tk::Text::IndexString.new(String.new(id) << ' display wordend')\n    end\n  end\n\n  class IndexString < String\n    include IndexModMethods\n\n    def self.at(x,y)\n      self.new(\"@#{x},#{y}\")\n    end\n\n    def self.new(str)\n      if str.kind_of?(String)\n        super(str)\n      elsif str.kind_of?(Symbol)\n        super(str.to_s)\n      else\n        str\n      end\n    end\n\n    def id\n      self\n    end\n  end\n\n  #######################################\n\n  TkCommandNames = ['text'.freeze].freeze\n  WidgetClassName = 'Text'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.new(*args, &block)\n    obj = super(*args){}\n    obj.init_instance_variable\n    if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n      obj.instance_exec(obj, &block) if defined? yield\n    else\n      obj.instance_eval(&block) if defined? yield\n    end\n    obj\n  end\n\n  def init_instance_variable\n    @cmdtbl = []\n    @tags = {}\n  end\n\n  def __destroy_hook__\n    TkTextTag::TTagID_TBL.mutex.synchronize{\n      TkTextTag::TTagID_TBL.delete(@path)\n    }\n    TkTextTag::TMarkID_TBL.mutex.synchronize{\n      TkTextMark::TMarkID_TBL.delete(@path)\n    }\n  end\n\n  def create_self(keys)\n    #if keys and keys != None\n    #  #tk_call_without_enc('text', @path, *hash_kv(keys, true))\n    #  tk_call_without_enc(self.class::TkCommandNames[0], @path, \n    #                     *hash_kv(keys, true))\n    #else\n    #  #tk_call_without_enc('text', @path)\n    #  tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    #end\n    super(keys)\n    init_instance_variable\n  end\n  private :create_self\n\n  def __strval_optkeys\n    super() << 'inactiveseletcionbackground'\n  end\n  private :__strval_optkeys\n\n  def self.at(x, y)\n    Tk::Text::IndexString.at(x, y)\n  end\n\n  def at(x, y)\n    Tk::Text::IndexString.at(x, y)\n  end\n\n  def index(idx)\n    Tk::Text::IndexString.new(tk_send_without_enc('index', \n                                                  _get_eval_enc_str(idx)))\n  end\n\n  def get_displaychars(*index)\n    # Tk8.5 feature\n    get('-displaychars', *index)\n  end\n\n  def value\n    _fromUTF8(tk_send_without_enc('get', \"1.0\", \"end - 1 char\"))\n  end\n\n  def value= (val)\n    tk_send_without_enc('delete', \"1.0\", 'end')\n    tk_send_without_enc('insert', \"1.0\", _get_eval_enc_str(val))\n    val\n  end\n\n  def clear\n    tk_send_without_enc('delete', \"1.0\", 'end')\n    self\n  end\n  alias erase clear\n\n  def _addcmd(cmd)\n    @cmdtbl.push cmd\n  end\n\n  def _addtag(name, obj)\n    @tags[name] = obj\n  end\n\n  def tagid(tag)\n    if tag.kind_of?(TkTextTag) \\\n      || tag.kind_of?(TkTextMark) \\\n      || tag.kind_of?(TkTextImage) \\\n      || tag.kind_of?(TkTextWindow)\n      tag.id\n    else\n      tag  # maybe an Array of configure paramters\n    end\n  end\n  private :tagid\n\n  def tagid2obj(tagid)\n    if @tags[tagid]\n      @tags[tagid]\n    else\n      tagid\n    end\n  end\n\n  def tag_names(index=None)\n    #tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)))).collect{|elt|\n    tk_split_simplelist(tk_send_without_enc('tag', 'names', _get_eval_enc_str(index)), false, true).collect{|elt|\n      tagid2obj(elt)\n    }\n  end\n\n  def mark_names\n    #tk_split_simplelist(_fromUTF8(tk_send_without_enc('mark', 'names'))).collect{|elt|\n    tk_split_simplelist(tk_send_without_enc('mark', 'names'), false, true).collect{|elt|\n      tagid2obj(elt)\n    }\n  end\n\n  def mark_gravity(mark, direction=nil)\n    if direction\n      tk_send_without_enc('mark', 'gravity', \n                          _get_eval_enc_str(mark), direction)\n      self\n    else\n      tk_send_without_enc('mark', 'gravity', _get_eval_enc_str(mark))\n    end\n  end\n\n  def mark_set(mark, index)\n    tk_send_without_enc('mark', 'set', _get_eval_enc_str(mark), \n                        _get_eval_enc_str(index))\n    self\n  end\n  alias set_mark mark_set\n\n  def mark_unset(*marks)\n    tk_send_without_enc('mark', 'unset', \n                        *(marks.collect{|mark| _get_eval_enc_str(mark)}))\n    self\n  end\n  alias unset_mark mark_unset\n\n  def mark_next(index)\n    tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'next', \n                                            _get_eval_enc_str(index))))\n  end\n  alias next_mark mark_next\n\n  def mark_previous(index)\n    tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'previous', \n                                            _get_eval_enc_str(index))))\n  end\n  alias previous_mark mark_previous\n\n  def image_cget_strict(index, slot)\n    case slot.to_s\n    when 'text', 'label', 'show', 'data', 'file'\n      _fromUTF8(tk_send_without_enc('image', 'cget', \n                                    _get_eval_enc_str(index), \"-#{slot}\"))\n    else\n      tk_tcl2ruby(_fromUTF8(tk_send_without_enc('image', 'cget', \n                                                _get_eval_enc_str(index), \n                                                \"-#{slot}\")))\n    end\n  end\n\n  def image_cget(index, slot)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      image_cget_strict(index, slot)\n    else\n      begin\n        image_cget_strict(index, slot)\n      rescue => e\n        begin\n          if current_image_configinfo(index).has_key?(slot.to_s)\n            # not tag error & option is known -> error on known option\n            fail e\n          else\n            # not tag error & option is unknown\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n\n  def image_configure(index, slot, value=None)\n    if slot.kind_of?(Hash)\n      _fromUTF8(tk_send_without_enc('image', 'configure', \n                                    _get_eval_enc_str(index), \n                                    *hash_kv(slot, true)))\n    else\n      _fromUTF8(tk_send_without_enc('image', 'configure', \n                                    _get_eval_enc_str(index), \n                                    \"-#{slot}\", \n                                    _get_eval_enc_str(value)))\n    end\n    self\n  end\n\n  def image_configinfo(index, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        case slot.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), false, true)\n        else\n          #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), 0, false, true)\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        # tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).collect{|conflist|\n        #  conf = tk_split_simplelist(conflist)\n        tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).collect{|conflist|\n          conf = tk_split_simplelist(conflist, false, true)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        case slot.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), false, true)\n        else\n          #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), 0, false, true)\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).each{|conflist|\n        #  conf = tk_split_simplelist(conflist)\n        tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).each{|conflist|\n          conf = tk_split_simplelist(conflist, false, true)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        ret\n      end\n    end\n  end\n\n  def current_image_configinfo(index, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        conf = image_configinfo(index, slot)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        image_configinfo(index).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      image_configinfo(index, slot).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n\n  def image_names\n    #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'names'))).collect{|elt|\n    tk_split_simplelist(tk_send_without_enc('image', 'names'), false, true).collect{|elt|\n      tagid2obj(elt)\n    }\n  end\n\n  def set_insert(index)\n    tk_send_without_enc('mark','set','insert', _get_eval_enc_str(index))\n    self\n  end\n\n  def set_current(index)\n    tk_send_without_enc('mark','set','current', _get_eval_enc_str(index))\n    self\n  end\n\n  def insert(index, chars, *tags)\n    if tags[0].kind_of?(Array)\n      # multiple chars-taglist argument :: str, [tag,...], str, [tag,...], ...\n      args = [chars]\n      while tags.size > 0\n        args << tags.shift.collect{|x|_get_eval_string(x)}.join(' ')  # taglist\n        args << tags.shift if tags.size > 0                           # chars\n      end\n      super(index, *args)\n    else\n      # single chars-taglist argument :: str, tag, tag, ...\n      if tags.size == 0\n        super(index, chars)\n      else\n        super(index, chars, tags.collect{|x|_get_eval_string(x)}.join(' '))\n      end\n    end\n  end\n\n  def destroy\n    @tags = {} unless @tags\n    @tags.each_value do |t|\n      t.destroy\n    end\n    super()\n  end\n\n  def backspace\n    self.delete 'insert'\n  end\n\n  def bbox(index)\n    list(tk_send_without_enc('bbox', _get_eval_enc_str(index)))\n  end\n\n  def compare(idx1, op, idx2)\n    bool(tk_send_without_enc('compare', _get_eval_enc_str(idx1), \n                             op, _get_eval_enc_str(idx2)))\n  end\n\n  def count(idx1, idx2, *opts)\n    # opts are Tk8.5 feature\n    cnt = 0\n    args = opts.collect{|opt|\n      str = opt.to_s\n      cnt += 1 if str != 'update'\n      '-' + str\n    }\n    args << _get_eval_enc_str(idx1) << _get_eval_enc_str(idx2)\n    if cnt <= 1\n      number(tk_send_without_enc('count', *opts))\n    else\n      list(tk_send_without_enc('count', *opts))\n    end\n  end\n\n  def count_info(idx1, idx2, update=true)\n    # Tk8.5 feature\n    opts = [\n      :chars, :displaychars, :displayindices, :displaylines, \n      :indices, :lines, :xpixels, :ypixels\n    ]\n    if update\n      lst = count(idx1, idx2, :update, *opts)\n    else\n      lst = count(idx1, idx2, *opts)\n    end\n    info = {}\n    opts.each_with_index{|key, idx| info[key] = lst[idx]}\n    info\n  end\n\n  def peer_names()\n    # Tk8.5 feature\n    list(tk_send_without_enc('peer', 'names'))\n  end\n\n  def replace(idx1, idx2, *opts)\n    tk_send('replace', idx1, idx2, *opts)\n    self\n  end\n\n  def debug\n    bool(tk_send_without_enc('debug'))\n  end\n  def debug=(boolean)\n    tk_send_without_enc('debug', boolean)\n    #self\n    boolean\n  end\n\n  def dlineinfo(index)\n    list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index)))\n  end\n\n  def modified?\n    bool(tk_send_without_enc('edit', 'modified'))\n  end\n  def modified(mode)\n    tk_send_without_enc('edit', 'modified', mode)\n    self\n  end\n  def modified=(mode)\n    modified(mode)\n    mode\n  end\n\n  def edit_redo\n    tk_send_without_enc('edit', 'redo')\n    self\n  end\n  def edit_reset\n    tk_send_without_enc('edit', 'reset')\n    self\n  end\n  def edit_separator\n    tk_send_without_enc('edit', 'separator')\n    self\n  end\n  def edit_undo\n    tk_send_without_enc('edit', 'undo')\n    self\n  end\n\n  def xview_pickplace(index)\n    tk_send_without_enc('xview', '-pickplace', _get_eval_enc_str(index))\n    self\n  end\n\n  def yview_pickplace(index)\n    tk_send_without_enc('yview', '-pickplace', _get_eval_enc_str(index))\n    self\n  end\n\n  def text_copy\n    # Tk8.4 feature\n    tk_call_without_enc('tk_textCopy', @path)\n    self\n  end\n\n  def text_cut\n    # Tk8.4 feature\n    tk_call_without_enc('tk_textCut', @path)\n    self\n  end\n\n  def text_paste\n    # Tk8.4 feature\n    tk_call_without_enc('tk_textPaste', @path)\n    self\n  end\n\n  def tag_add(tag, index1, index2=None)\n    tk_send_without_enc('tag', 'add', _get_eval_enc_str(tag), \n                        _get_eval_enc_str(index1), \n                        _get_eval_enc_str(index2))\n    self\n  end\n  alias addtag tag_add\n  alias add_tag tag_add\n\n  def tag_delete(*tags)\n    tk_send_without_enc('tag', 'delete', \n                        *(tags.collect{|tag| _get_eval_enc_str(tag)}))\n    TkTextTag::TTagID_TBL.mutex.synchronize{\n      if TkTextTag::TTagID_TBL[@path]\n        tags.each{|tag|\n          if tag.kind_of?(TkTextTag)\n            TkTextTag::TTagID_TBL[@path].delete(tag.id) \n          else\n            TkTextTag::TTagID_TBL[@path].delete(tag) \n          end\n        }\n      end\n    }\n    self\n  end\n  alias deltag tag_delete\n  alias delete_tag tag_delete\n\n  #def tag_bind(tag, seq, cmd=Proc.new, *args)\n  #  _bind([@path, 'tag', 'bind', tag], seq, cmd, *args)\n  #  self\n  #end\n  def tag_bind(tag, seq, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([@path, 'tag', 'bind', tag], seq, cmd, *args)\n    self\n  end\n\n  #def tag_bind_append(tag, seq, cmd=Proc.new, *args)\n  #  _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args)\n  #  self\n  #end\n  def tag_bind_append(tag, seq, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args)\n    self\n  end\n\n  def tag_bind_remove(tag, seq)\n    _bind_remove([@path, 'tag', 'bind', tag], seq)\n    self\n  end\n\n  def tag_bindinfo(tag, context=nil)\n    _bindinfo([@path, 'tag', 'bind', tag], context)\n  end\n\n=begin\n  def tag_cget(tag, key)\n    case key.to_s\n    when 'text', 'label', 'show', 'data', 'file'\n      tk_call_without_enc(@path, 'tag', 'cget', \n                          _get_eval_enc_str(tag), \"-#{key}\")\n    when 'font', 'kanjifont'\n      #fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, \"-#{key}\"))\n      fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('tag','cget',_get_eval_enc_str(tag),'-font')))\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(tag, fnt)\n      end\n      if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@path,'tag','cget',_get_eval_enc_str(tag),\"-#{key}\")))\n    end\n  end\n\n  def tag_configure(tag, key, val=None)\n    if key.kind_of?(Hash)\n      key = _symbolkey2str(key)\n      if ( key['font'] || key['kanjifont'] \\\n          || key['latinfont'] || key['asciifont'] )\n        tagfont_configure(tag, key)\n      else\n        tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), \n                            *hash_kv(key, true))\n      end\n\n    else\n      if  key == 'font' || key == :font || \n          key == 'kanjifont' || key == :kanjifont ||\n          key == 'latinfont' || key == :latinfont || \n          key == 'asciifont' || key == :asciifont\n        if val == None\n          tagfontobj(tag)\n        else\n          tagfont_configure(tag, {key=>val})\n        end\n      else\n        tk_send_without_enc('tag', 'configure', _get_eval_enc_str(tag), \n                            \"-#{key}\", _get_eval_enc_str(val))\n      end\n    end\n    self\n  end\n\n  def tag_configinfo(tag, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),\"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),\"-#{key}\")))\n          conf[4] = tagfont_configinfo(tag, conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),\"-#{key}\")))\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        ret = tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).collect{|conflist|\n          conf = tk_split_simplelist(conflist)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n        fontconf = ret.assoc('font')\n        if fontconf\n          ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}\n          fontconf[4] = tagfont_configinfo(tag, fontconf[4])\n          ret.push(fontconf)\n        else\n          ret\n        end\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        case key.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),\"-#{key}\")))\n        when 'font', 'kanjifont'\n          conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),\"-#{key}\")))\n          conf[4] = tagfont_configinfo(tag, conf[4])\n        else\n          conf = tk_split_list(_fromUTF8(tk_send_without_enc('tag','configure',_get_eval_enc_str(tag),\"-#{key}\")))\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        tk_split_simplelist(_fromUTF8(tk_send('tag','configure',_get_eval_enc_str(tag)))).each{|conflist|\n          conf = tk_split_simplelist(conflist)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        fontconf = ret['font']\n        if fontconf\n          ret.delete('font')\n          ret.delete('kanjifont')\n          fontconf[3] = tagfont_configinfo(tag, fontconf[3])\n          ret['font'] = fontconf\n        end\n        ret\n      end\n    end\n  end\n\n  def current_tag_configinfo(tag, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        conf = tag_configinfo(tag, key)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        tag_configinfo(tag).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      tag_configinfo(tag, key).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n=end\n\n  def tag_raise(tag, above=None)\n    tk_send_without_enc('tag', 'raise', _get_eval_enc_str(tag), \n                        _get_eval_enc_str(above))\n    self\n  end\n\n  def tag_lower(tag, below=None)\n    tk_send_without_enc('tag', 'lower', _get_eval_enc_str(tag), \n                        _get_eval_enc_str(below))\n    self\n  end\n\n  def tag_remove(tag, *indices)\n    tk_send_without_enc('tag', 'remove', _get_eval_enc_str(tag), \n                        *(indices.collect{|idx| _get_eval_enc_str(idx)}))\n    self\n  end\n\n  def tag_ranges(tag)\n    #l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges',\n    #                                            _get_eval_enc_str(tag)))\n    l = tk_split_simplelist(tk_send_without_enc('tag', 'ranges',\n                                                _get_eval_enc_str(tag)), \n                            false, true)\n    r = []\n    while key=l.shift\n      r.push [Tk::Text::IndexString.new(key), Tk::Text::IndexString.new(l.shift)]\n    end\n    r\n  end\n\n  def tag_nextrange(tag, first, last=None)\n    simplelist(tk_send_without_enc('tag', 'nextrange', \n                                   _get_eval_enc_str(tag), \n                                   _get_eval_enc_str(first), \n                                   _get_eval_enc_str(last))).collect{|idx|\n      Tk::Text::IndexString.new(idx)\n    }\n  end\n\n  def tag_prevrange(tag, first, last=None)\n    simplelist(tk_send_without_enc('tag', 'prevrange', \n                                   _get_eval_enc_str(tag), \n                                   _get_eval_enc_str(first), \n                                   _get_eval_enc_str(last))).collect{|idx|\n      Tk::Text::IndexString.new(idx)\n    }\n  end\n\n=begin\n  def window_cget(index, slot)\n    case slot.to_s\n    when 'text', 'label', 'show', 'data', 'file'\n      _fromUTF8(tk_send_without_enc('window', 'cget', \n                                    _get_eval_enc_str(index), \"-#{slot}\"))\n    when 'font', 'kanjifont'\n      #fnt = tk_tcl2ruby(tk_send('window', 'cget', index, \"-#{slot}\"))\n      fnt = tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), '-font')))\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(index, fnt)\n      end\n      if slot.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(_fromUTF8(tk_send_without_enc('window', 'cget', _get_eval_enc_str(index), \"-#{slot}\")))\n    end\n  end\n\n  def window_configure(index, slot, value=None)\n    if index.kind_of?(TkTextWindow)\n      index.configure(slot, value)\n    else\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        win = slot['window']\n        # slot['window'] = win.epath if win.kind_of?(TkWindow)\n        slot['window'] = _epath(win) if win\n        if slot['create']\n          p_create = slot['create']\n          if p_create.kind_of?(Proc)\n#=begin\n            slot['create'] = install_cmd(proc{\n                                           id = p_create.call\n                                           if id.kind_of?(TkWindow)\n                                             id.epath\n                                           else\n                                             id\n                                           end\n                                         })\n#=end\n            slot['create'] = install_cmd(proc{_epath(p_create.call)})\n          end\n        end\n        tk_send_without_enc('window', 'configure', \n                            _get_eval_enc_str(index), \n                            *hash_kv(slot, true))\n      else\n        if slot == 'window' || slot == :window\n          # id = value \n          # value = id.epath if id.kind_of?(TkWindow)\n          value = _epath(value)\n        end\n        if slot == 'create' || slot == :create\n          p_create = value\n          if p_create.kind_of?(Proc)\n#=begin\n            value = install_cmd(proc{\n                                  id = p_create.call\n                                  if id.kind_of?(TkWindow)\n                                    id.epath\n                                  else\n                                    id\n                                  end\n                                })\n#=end\n            value = install_cmd(proc{_epath(p_create.call)})\n          end\n        end\n        tk_send_without_enc('window', 'configure', \n                            _get_eval_enc_str(index), \n                            \"-#{slot}\", _get_eval_enc_str(value))\n      end\n    end\n    self\n  end\n\n  def window_configinfo(win, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        case slot.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), \"-#{slot}\")))\n        else\n          conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), \"-#{slot}\")))\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).collect{|conflist|\n          conf = tk_split_simplelist(conflist)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        case slot.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          conf = tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), \"-#{slot}\")))\n        else\n          conf = tk_split_list(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win), \"-#{slot}\")))\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        tk_split_simplelist(_fromUTF8(tk_send('window', 'configure', _get_eval_enc_str(win)))).each{|conflist|\n          conf = tk_split_simplelist(conflist)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        ret\n      end\n    end\n  end\n\n  def current_window_configinfo(win, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        conf = window_configinfo(win, slot)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        window_configinfo(win).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      window_configinfo(win, slot).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n=end\n\n  def window_names\n    # tk_split_simplelist(_fromUTF8(tk_send_without_enc('window', 'names'))).collect{|elt|\n    tk_split_simplelist(tk_send_without_enc('window', 'names'), false, true).collect{|elt|\n      tagid2obj(elt)\n    }\n  end\n\n  def _ktext_length(txt)\n    if TkCore::WITH_ENCODING ### Ruby 1.9 !!!!!!!!!!!!!\n      return txt.length\n    end\n    ###########################\n\n    if $KCODE !~ /n/i\n      return txt.gsub(/[^\\Wa-zA-Z_\\d]/, ' ').length\n    end\n\n    # $KCODE == 'NONE'\n    if JAPANIZED_TK\n      tk_call_without_enc('kstring', 'length', \n                          _get_eval_enc_str(txt)).to_i\n    else\n      begin\n        tk_call_without_enc('encoding', 'convertto', 'ascii', \n                            _get_eval_enc_str(txt)).length\n      rescue StandardError, NameError\n        # sorry, I have no plan\n        txt.length\n      end\n    end\n  end\n  private :_ktext_length\n\n  def tksearch(*args)\n    # call 'search' subcommand of text widget\n    #   args ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>]\n    # If <pattern> is regexp, then it must be a regular expression of Tcl\n    nocase = false\n    if args[0].kind_of?(Array)\n      opts = args.shift.collect{|opt|\n        s_opt = opt.to_s\n        nocase = true if s_opt == 'nocase'\n        '-' + s_opt\n      }\n    else\n      opts = []\n    end\n\n    if args[0].kind_of?(Regexp)\n      regexp = args.shift\n      if !nocase && (regexp.options & Regexp::IGNORECASE) != 0\n        opts << '-nocase'\n      end\n      args.unshift(regexp.source)\n    end\n\n    opts << '--'\n\n    ret = tk_send('search', *(opts + args))\n    if ret == \"\"\n      nil\n    else\n      Tk::Text::IndexString.new(ret)\n    end\n  end\n\n  def tksearch_with_count(*args)\n    # call 'search' subcommand of text widget\n    #   args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>]\n    # If <pattern> is regexp, then it must be a regular expression of Tcl\n    nocase = false\n    if args[0].kind_of?(Array)\n      opts = args.shift.collect{|opt|\n        s_opt = opt.to_s\n        nocase = true if s_opt == 'nocase'\n        '-' + s_opt\n      }\n    else\n      opts = []\n    end\n\n    opts << '-count' << args.shift\n\n    if args[0].kind_of?(Regexp)\n      regexp = args.shift\n      if !nocase && (regexp.options & Regexp::IGNORECASE) != 0\n        opts << '-nocase'\n      end\n      args.unshift(regexp.source)\n    end\n\n    opts << '--'\n\n    ret = tk_send('search', *(opts + args))\n    if ret == \"\"\n      nil\n    else\n      Tk::Text::IndexString.new(ret)\n    end\n  end\n\n  def search_with_length(pat,start,stop=None)\n    pat = pat.chr if pat.kind_of?(Integer)\n    if stop != None\n      return [\"\", 0] if compare(start,'>=',stop)\n      txt = get(start,stop)\n      if (pos = txt.index(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of?(String)\n          #return [index(start + \" + #{pos} chars\"), pat.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(pat), pat.dup]\n        else\n          #return [index(start + \" + #{pos} chars\"), $&.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(match), match]\n        end\n      else\n        return [\"\", 0]\n      end\n    else\n      txt = get(start,'end - 1 char')\n      if (pos = txt.index(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of?(String)\n          #return [index(start + \" + #{pos} chars\"), pat.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(pat), pat.dup]\n        else\n          #return [index(start + \" + #{pos} chars\"), $&.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(match), match]\n        end\n      else\n        txt = get('1.0','end - 1 char')\n        if (pos = txt.index(pat))\n          match = $&\n          #pos = txt[0..(pos-1)].split('').length if pos > 0\n          pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n          if pat.kind_of?(String)\n            #return [index(\"1.0 + #{pos} chars\"), pat.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), \n                    _ktext_length(pat), pat.dup]\n          else\n            #return [index(\"1.0 + #{pos} chars\"), $&.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), _ktext_length(match), match]\n          end\n        else\n          return [\"\", 0]\n        end\n      end\n    end\n  end\n\n  def search(pat,start,stop=None)\n    search_with_length(pat,start,stop)[0]\n  end\n\n  def rsearch_with_length(pat,start,stop=None)\n    pat = pat.chr if pat.kind_of?(Integer)\n    if stop != None\n      return [\"\", 0] if compare(start,'<=',stop)\n      txt = get(stop,start)\n      if (pos = txt.rindex(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of?(String)\n          #return [index(stop + \" + #{pos} chars\"), pat.split('').length]\n          return [index(stop + \" + #{pos} chars\"), _ktext_length(pat), pat.dup]\n        else\n          #return [index(stop + \" + #{pos} chars\"), $&.split('').length]\n          return [index(stop + \" + #{pos} chars\"), _ktext_length(match), match]\n        end\n      else\n        return [\"\", 0]\n      end\n    else\n      txt = get('1.0',start)\n      if (pos = txt.rindex(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of?(String)\n          #return [index(\"1.0 + #{pos} chars\"), pat.split('').length]\n          return [index(\"1.0 + #{pos} chars\"), _ktext_length(pat), pat.dup]\n        else\n          #return [index(\"1.0 + #{pos} chars\"), $&.split('').length]\n          return [index(\"1.0 + #{pos} chars\"), _ktext_length(match), match]\n        end\n      else\n        txt = get('1.0','end - 1 char')\n        if (pos = txt.rindex(pat))\n          match = $&\n          #pos = txt[0..(pos-1)].split('').length if pos > 0\n          pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n          if pat.kind_of?(String)\n            #return [index(\"1.0 + #{pos} chars\"), pat.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), _ktext_length(pat), pat.dup]\n          else\n            #return [index(\"1.0 + #{pos} chars\"), $&.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), _ktext_length(match), match]\n          end\n        else\n          return [\"\", 0]\n        end\n      end\n    end\n  end\n\n  def rsearch(pat,start,stop=None)\n    rsearch_with_length(pat,start,stop)[0]\n  end\n\n  def dump(type_info, *index, &block)\n    if type_info.kind_of?(Symbol)\n      type_info = [ type_info.to_s ]\n    elsif type_info.kind_of?(String)\n      type_info = [ type_info ]\n    end\n    args = type_info.collect{|inf| '-' + inf}\n    args << '-command' << block if block\n    str = tk_send('dump', *(args + index))\n    result = []\n    sel = nil\n    i = 0\n    while i < str.size\n      # retrieve key\n      idx = str.index(/ /, i)\n      result.push str[i..(idx-1)]\n      i = idx + 1\n      \n      # retrieve value\n      case result[-1]\n      when 'text'\n        if str[i] == ?{\n          # text formed as {...}\n          val, i = _retrieve_braced_text(str, i)\n          result.push val\n        else\n          # text which may contain backslahes\n          val, i = _retrieve_backslashed_text(str, i)\n          result.push val\n        end\n      else\n        idx = str.index(/ /, i)\n        val = str[i..(idx-1)]\n        case result[-1]\n        when 'mark'\n          case val\n          when 'insert'\n            result.push TkTextMarkInsert.new(self)\n          when 'current'\n            result.push TkTextMarkCurrent.new(self)\n          when 'anchor'\n            result.push TkTextMarkAnchor.new(self)\n          else\n            result.push tk_tcl2ruby(val)\n          end\n        when 'tagon'\n          if val == 'sel'\n            if sel\n              result.push sel\n            else\n              result.push TkTextTagSel.new(self)\n            end\n          else\n            result.push tk_tcl2ruby(val)\n          end\n        when 'tagoff'\n            result.push tk_tcl2ruby(val)\n        when 'window'\n          result.push tk_tcl2ruby(val)\n        when 'image'\n          result.push tk_tcl2ruby(val)\n        end\n        i = idx + 1\n      end\n\n      # retrieve index\n      idx = str.index(/ /, i)\n      if idx\n        result.push(Tk::Text::IndexString.new(str[i..(idx-1)]))\n        i = idx + 1\n      else\n        result.push(Tk::Text::IndexString.new(str[i..-1]))\n        break\n      end\n    end\n    \n    kvis = []\n    until result.empty?\n      kvis.push [result.shift, result.shift, result.shift]\n    end\n    kvis  # result is [[key1, value1, index1], [key2, value2, index2], ...]\n  end\n\n  def _retrieve_braced_text(str, i)\n    cnt = 0\n    idx = i\n    while idx < str.size\n      case str[idx]\n      when ?{\n        cnt += 1\n      when ?}\n        cnt -= 1\n        if cnt == 0\n          break\n        end\n      end\n      idx += 1\n    end\n    return str[i+1..idx-1], idx + 2\n  end\n  private :_retrieve_braced_text\n\n  def _retrieve_backslashed_text(str, i)\n    j = i\n    idx = nil\n    loop {\n      idx = str.index(/ /, j)\n      if str[idx-1] == ?\\\\\n        j += 1\n      else\n        break\n      end\n    }\n    val = str[i..(idx-1)]\n    val.gsub!(/\\\\( |\\{|\\})/, '\\1')\n    return val, idx + 1\n  end\n  private :_retrieve_backslashed_text\n\n  def dump_all(*index, &block)\n    dump(['all'], *index, &block)\n  end\n  def dump_mark(*index, &block)\n    dump(['mark'], *index, &block)\n  end\n  def dump_tag(*index, &block)\n    dump(['tag'], *index, &block)\n  end\n  def dump_text(*index, &block)\n    dump(['text'], *index, &block)\n  end\n  def dump_window(*index, &block)\n    dump(['window'], *index, &block)\n  end\n  def dump_image(*index, &block)\n    dump(['image'], *index, &block)\n  end\nend\n\n#TkText = Tk::Text unless Object.const_defined? :TkText\nTk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)\n\n\n#######################################\n\nclass Tk::Text::Peer < Tk::Text\n  # Tk8.5 feature\n  def initialize(text, parent=nil, keys={})\n    unless text.kind_of?(Tk::Text)\n      fail ArgumentError, \"Tk::Text is expected for 1st argument\"\n    end\n    @src_text = text\n    super(parent, keys)\n  end\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(@src_text.path, 'peer', 'create', @path)\n    else\n      tk_call_without_enc(@src_text.path, 'peer', 'create', @path)\n    end\n  end\n  private :create_self\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/textimage.rb",
    "content": "#\n# tk/textimage.rb - treat Tk text image object\n#\nrequire 'tk'\nrequire 'tk/text'\n\nclass TkTextImage<TkObject\n  include Tk::Text::IndexModMethods\n\n  def initialize(parent, index, keys)\n    #unless parent.kind_of?(Tk::Text)\n    #  fail ArgumentError, \"expect Tk::Text for 1st argument\"\n    #end\n    @t = parent\n    if index == 'end' || index == :end\n      @path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))\n    elsif index.kind_of? TkTextMark\n      if tk_call_without_enc(@t.path,'index',index.path) == tk_call_without_enc(@t.path,'index','end')\n        @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', \n                                                       'end - 1 chars'))\n      else\n        @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', \n                                                       index.path))\n      end\n    else\n      @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', \n                                                     _get_eval_enc_str(index)))\n    end\n    @path.gravity = 'left'\n    @index = @path.path\n    @id = tk_call_without_enc(@t.path, 'image', 'create', @index, \n                              *hash_kv(keys, true)).freeze\n    @path.gravity = 'right'\n  end\n\n  def id\n    Tk::Text::IndexString.new(@id)\n  end\n  def mark\n    @path\n  end\n\n  def [](slot)\n    cget(slot)\n  end\n  def []=(slot, value)\n    configure(slot, value)\n    value\n  end\n\n  def cget(slot)\n    @t.image_cget(@index, slot)\n  end\n\n  def cget_strict(slot)\n    @t.image_cget_strict(@index, slot)\n  end\n\n  def configure(slot, value=None)\n    @t.image_configure(@index, slot, value)\n    self\n  end\n#  def configure(slot, value)\n#    tk_call @t.path, 'image', 'configure', @index, \"-#{slot}\", value\n#  end\n\n  def configinfo(slot = nil)\n    @t.image_configinfo(@index, slot)\n  end\n\n  def current_configinfo(slot = nil)\n    @t.current_image_configinfo(@index, slot)\n  end\n\n  def image\n    img = tk_call_without_enc(@t.path, 'image', 'cget', @index, '-image')\n    TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img\n  end\n\n  def image=(value)\n    tk_call_without_enc(@t.path, 'image', 'configure', @index, '-image', \n                        _get_eval_enc_str(value))\n    #self\n    value\n  end\nend\n\nTktImage = TkTextImage\n"
  },
  {
    "path": "ext/tk/lib/tk/textmark.rb",
    "content": "#\n# tk/textmark.rb - methods for treating text marks\n#\nrequire 'tk'\nrequire 'tk/text'\n\nclass TkTextMark<TkObject\n  include Tk::Text::IndexModMethods\n\n  TMarkID_TBL = TkCore::INTERP.create_table\n\n  (Tk_TextMark_ID = ['mark'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    TMarkID_TBL.mutex.synchronize{ TMarkID_TBL.clear }\n  }\n\n  def TkTextMark.id2obj(text, id)\n    tpath = text.path\n    TMarkID_TBL.mutex.synchronize{\n      if TMarkID_TBL[tpath]\n        TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id\n      else\n        id \n      end\n    }\n  end\n\n  def initialize(parent, index)\n    #unless parent.kind_of?(Tk::Text)\n    #  fail ArgumentError, \"expect Tk::Text for 1st argument\"\n    #end\n    @parent = @t = parent\n    @tpath = parent.path\n    Tk_TextMark_ID.mutex.synchronize{\n      # @path = @id = Tk_TextMark_ID.join('')\n      @path = @id = Tk_TextMark_ID.join(TkCore::INTERP._ip_id_).freeze\n      Tk_TextMark_ID[1].succ!\n    }\n    TMarkID_TBL.mutex.synchronize{\n      TMarkID_TBL[@id] = self\n      TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]\n      TMarkID_TBL[@tpath][@id] = self\n    }\n    tk_call_without_enc(@t.path, 'mark', 'set', @id, \n                        _get_eval_enc_str(index))\n    @t._addtag id, self\n  end\n\n  def id\n    Tk::Text::IndexString.new(@id)\n  end\n\n  def exist?\n    #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'names'))).find{|id| id == @id } )\n    if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'mark', 'names'), false, true).find{|id| id == @id } )\n      true\n    else\n      false\n    end\n  end\n\n=begin\n  # move to Tk::Text::IndexModMethods module\n  def +(mod)\n    return chars(mod) if mod.kind_of?(Numeric)\n\n    mod = mod.to_s\n    if mod =~ /^\\s*[+-]?\\d/\n      Tk::Text::IndexString.new(@id + ' + ' + mod)\n    else\n      Tk::Text::IndexString.new(@id + ' ' + mod)\n    end\n  end\n\n  def -(mod)\n    return chars(-mod) if mod.kind_of?(Numeric)\n\n    mod = mod.to_s\n    if mod =~ /^\\s*[+-]?\\d/\n      Tk::Text::IndexString.new(@id + ' - ' + mod)\n    elsif mod =~ /^\\s*[-]\\s+(\\d.*)$/\n      Tk::Text::IndexString.new(@id + ' - -' + $1)\n    else\n      Tk::Text::IndexString.new(@id + ' ' + mod)\n    end\n  end\n=end\n\n  def pos\n    @t.index(@id)\n  end\n\n  def pos=(where)\n    set(where)\n  end\n\n  def set(where)\n    tk_call_without_enc(@t.path, 'mark', 'set', @id, \n                        _get_eval_enc_str(where))\n    self\n  end\n\n  def unset\n    tk_call_without_enc(@t.path, 'mark', 'unset', @id)\n    self\n  end\n  alias destroy unset\n\n  def gravity\n    tk_call_without_enc(@t.path, 'mark', 'gravity', @id)\n  end\n\n  def gravity=(direction)\n    tk_call_without_enc(@t.path, 'mark', 'gravity', @id, direction)\n    #self\n    direction\n  end\n\n  def next(index = nil)\n    if index\n      @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', _get_eval_enc_str(index))))\n    else\n      @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'next', @id)))\n    end\n  end\n\n  def previous(index = nil)\n    if index\n      @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', _get_eval_enc_str(index))))\n    else\n      @t.tagid2obj(_fromUTF8(tk_call_without_enc(@t.path, 'mark', 'previous', @id)))\n    end\n  end\nend\nTktMark = TkTextMark\n\nclass TkTextNamedMark<TkTextMark\n  def self.new(parent, name, index=nil)\n    TMarkID_TBL.mutex.synchronize{\n      if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name]\n        obj = TMarkID_TBL[parent.path][name]\n      else\n        # super(parent, name, *args)\n        (obj = self.allocate).instance_eval{\n          @parent = @t = parent\n          @tpath = parent.path\n          @path = @id = name\n          TMarkID_TBL[@id] = self\n          TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]\n          TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id]\n          @t._addtag @id, self\n        }\n        obj\n      end\n\n      if obj && index\n        tk_call_without_enc(parent.path, 'mark', 'set', name, \n                            _get_eval_enc_str(index))\n      end\n      obj\n    }\n  end\n\n  def initialize(parent, name, index=nil)\n    # dummy:: not called by 'new' method\n\n    #unless parent.kind_of?(Tk::Text)\n    #  fail ArgumentError, \"expect Tk::Text for 1st argument\"\n    #end\n    @parent = @t = parent\n    @tpath = parent.path\n    @path = @id = name\n    tk_call_without_enc(@t.path, 'mark', 'set', @id, \n                        _get_eval_enc_str(index)) if index\n    @t._addtag @id, self\n  end\nend\nTktNamedMark = TkTextNamedMark\n\nclass TkTextMarkInsert<TkTextNamedMark\n  def self.new(parent,*args)\n    super(parent, 'insert', *args)\n  end\nend\nTktMarkInsert = TkTextMarkInsert\n\nclass TkTextMarkCurrent<TkTextNamedMark\n  def self.new(parent,*args)\n    super(parent, 'current', *args)\n  end\nend\nTktMarkCurrent = TkTextMarkCurrent\n\nclass TkTextMarkAnchor<TkTextNamedMark\n  def self.new(parent,*args)\n    super(parent, 'anchor', *args)\n  end\nend\nTktMarkAnchor = TkTextMarkAnchor\n"
  },
  {
    "path": "ext/tk/lib/tk/texttag.rb",
    "content": "#\n# tk/texttag.rb - methods for treating text tags\n#\nrequire 'tk'\nrequire 'tk/text'\nrequire 'tk/tagfont'\n\nclass TkTextTag<TkObject\n  include TkTreatTagFont\n  include Tk::Text::IndexModMethods\n\n  TTagID_TBL = TkCore::INTERP.create_table\n\n  (Tk_TextTag_ID = ['tag'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    TTagID_TBL.mutex.synchronize{ TTagID_TBL.clear }\n  }\n\n  def TkTextTag.id2obj(text, id)\n    tpath = text.path\n    TTagID_TBL.mutex.synchronize{\n      if TTagID_TBL[tpath]\n        TTagID_TBL[tpath][id]? TTagID_TBL[tpath][id]: id\n      else \n        id\n      end\n    }\n  end\n\n  def initialize(parent, *args)\n    #unless parent.kind_of?(TkText)\n    #  fail ArgumentError, \"expect TkText for 1st argument\"\n    #end\n    @parent = @t = parent\n    @tpath = parent.path\n    Tk_TextTag_ID.mutex.synchronize{\n      # @path = @id = Tk_TextTag_ID.join('')\n      @path = @id = Tk_TextTag_ID.join(TkCore::INTERP._ip_id_).freeze\n      Tk_TextTag_ID[1].succ!\n    }\n    TTagID_TBL.mutex.synchronize{\n      TTagID_TBL[@id] = self\n      TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]\n      TTagID_TBL[@tpath][@id] = self\n    }\n    #tk_call @t.path, \"tag\", \"configure\", @id, *hash_kv(keys)\n    if args != []\n      keys = args.pop\n      if keys.kind_of?(Hash)\n        add(*args) if args != []\n        configure(keys)\n      else\n        args.push keys\n        add(*args)\n      end\n    end\n    @t._addtag id, self\n  end\n\n  def id\n    Tk::Text::IndexString.new(@id)\n  end\n\n  def exist?\n    #if ( tk_split_simplelist(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'names'))).find{|id| id == @id } )\n    if ( tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'names'), false, true).find{|id| id == @id } )\n      true\n    else\n      false\n    end\n  end\n\n  def first\n    Tk::Text::IndexString.new(@id + '.first')\n  end\n\n  def last\n    Tk::Text::IndexString.new(@id + '.last')\n  end\n\n  def add(*indices)\n    tk_call_without_enc(@t.path, 'tag', 'add', @id, \n                        *(indices.collect{|idx| _get_eval_enc_str(idx)}))\n    self\n  end\n\n  def remove(*indices)\n    tk_call_without_enc(@t.path, 'tag', 'remove', @id, \n                        *(indices.collect{|idx| _get_eval_enc_str(idx)}))\n    self\n  end\n\n  def ranges\n    l = tk_split_simplelist(tk_call_without_enc(@t.path, 'tag', 'ranges', @id))\n    r = []\n    while key=l.shift\n      r.push [Tk::Text::IndexString.new(key), Tk::Text::IndexString.new(l.shift)]\n    end\n    r\n  end\n\n  def nextrange(first, last=None)\n    simplelist(tk_call_without_enc(@t.path, 'tag', 'nextrange', @id, \n                                   _get_eval_enc_str(first), \n                                   _get_eval_enc_str(last))).collect{|idx|\n      Tk::Text::IndexString.new(idx)\n    }\n  end\n\n  def prevrange(first, last=None)\n    simplelist(tk_call_without_enc(@t.path, 'tag', 'prevrange', @id, \n                                   _get_eval_enc_str(first), \n                                   _get_eval_enc_str(last))).collect{|idx|\n      Tk::Text::IndexString.new(idx)\n    }\n  end\n\n  def [](key)\n    cget key\n  end\n\n  def []=(key,val)\n    configure key, val\n    val\n  end\n\n  def cget(key)\n    @t.tag_cget @id, key\n  end\n  def cget_strict(key)\n    @t.tag_cget_strict @id, key\n  end\n=begin\n  def cget(key)\n    case key.to_s\n    when 'text', 'label', 'show', 'data', 'file'\n      _fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', @id, \"-#{key}\"))\n    when 'font', 'kanjifont'\n      #fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, \"-#{key}\"))\n      fnt = tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', \n                                                      @id, '-font')))\n      unless fnt.kind_of?(TkFont)\n        fnt = tagfontobj(@id, fnt)\n      end\n      if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n    else\n      tk_tcl2ruby(_fromUTF8(tk_call_without_enc(@t.path, 'tag', 'cget', \n                                                @id, \"-#{key}\")))\n    end\n  end\n=end\n\n  def configure(key, val=None)\n    @t.tag_configure @id, key, val\n  end\n#  def configure(key, val=None)\n#    if key.kind_of?(Hash)\n#      tk_call @t.path, 'tag', 'configure', @id, *hash_kv(key)\n#    else\n#      tk_call @t.path, 'tag', 'configure', @id, \"-#{key}\", val\n#    end\n#  end\n#  def configure(key, value)\n#    if value == FALSE\n#      value = \"0\"\n#    elsif value.kind_of?(Proc)\n#      value = install_cmd(value)\n#    end\n#    tk_call @t.path, 'tag', 'configure', @id, \"-#{key}\", value\n#  end\n\n  def configinfo(key=nil)\n    @t.tag_configinfo @id, key\n  end\n\n  def current_configinfo(key=nil)\n    @t.current_tag_configinfo @id, key\n  end\n\n  #def bind(seq, cmd=Proc.new, *args)\n  #  _bind([@t.path, 'tag', 'bind', @id], seq, cmd, *args)\n  #  self\n  #end\n  def bind(seq, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([@t.path, 'tag', 'bind', @id], seq, cmd, *args)\n    self\n  end\n\n  #def bind_append(seq, cmd=Proc.new, *args)\n  #  _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, *args)\n  #  self\n  #end\n  def bind_append(seq, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, *args)\n    self\n  end\n\n  def bind_remove(seq)\n    _bind_remove([@t.path, 'tag', 'bind', @id], seq)\n    self\n  end\n\n  def bindinfo(context=nil)\n    _bindinfo([@t.path, 'tag', 'bind', @id], context)\n  end\n\n  def raise(above=None)\n    tk_call_without_enc(@t.path, 'tag', 'raise', @id, \n                        _get_eval_enc_str(above))\n    self\n  end\n\n  def lower(below=None)\n    tk_call_without_enc(@t.path, 'tag', 'lower', @id, \n                        _get_eval_enc_str(below))\n    self\n  end\n\n  def destroy\n    tk_call_without_enc(@t.path, 'tag', 'delete', @id)\n    TTagID_TBL.mutex.synchronize{\n      TTagID_TBL[@tpath].delete(@id) if TTagID_TBL[@tpath]\n    }\n    self\n  end\nend\nTktTag = TkTextTag\n\nclass TkTextNamedTag<TkTextTag\n  def self.new(parent, name, *args)\n    tagobj = nil\n    TTagID_TBL.mutex.synchronize{\n      if TTagID_TBL[parent.path] && TTagID_TBL[parent.path][name]\n        tagobj = TTagID_TBL[parent.path][name]\n      else\n        # super(parent, name, *args)\n        (tagobj = self.allocate).instance_eval{\n          @parent = @t = parent\n          @tpath = parent.path\n          @path = @id = name\n          TTagID_TBL[@id] = self\n          TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]\n          TTagID_TBL[@tpath][@id] = self unless TTagID_TBL[@tpath][@id]\n          @t._addtag @id, self\n        }\n      end\n    }\n\n    if args != []\n      keys = args.pop\n      if keys.kind_of?(Hash)\n        tagobj.add(*args) if args != []\n        tagobj.configure(keys)\n      else\n        args.push keys\n        tagobj.add(*args)\n      end\n    end\n\n    tagobj\n  end\n\n  def initialize(parent, name, *args)\n    # dummy:: not called by 'new' method\n\n    #unless parent.kind_of?(Tk::Text)\n    #  fail ArgumentError, \"expect Tk::Text for 1st argument\"\n    #end\n    @parent = @t = parent\n    @tpath = parent.path\n    @path = @id = name\n\n    #if mode\n    #  tk_call @t.path, \"addtag\", @id, *args\n    #end\n    if args != []\n      keys = args.pop\n      if keys.kind_of?(Hash)\n        add(*args) if args != []\n        configure(keys)\n      else\n        args.push keys\n        add(*args)\n      end\n    end\n    @t._addtag @id, self\n  end\nend\nTktNamedTag = TkTextNamedTag\n\nclass TkTextTagSel<TkTextNamedTag\n  def self.new(parent, *args)\n    super(parent, 'sel', *args)\n  end\nend\nTktTagSel = TkTextTagSel\n"
  },
  {
    "path": "ext/tk/lib/tk/textwindow.rb",
    "content": "#\n# tk/textwindow.rb - treat Tk text window object\n#\nrequire 'tk'\nrequire 'tk/text'\n\nclass TkTextWindow<TkObject\n  include Tk::Text::IndexModMethods\n\n  def initialize(parent, index, keys = {})\n    #unless parent.kind_of?(Tk::Text)\n    #  fail ArgumentError, \"expect Tk::Text for 1st argument\"\n    #end\n    @t = parent\n    if index == 'end' || index == :end\n      @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', \n                                                     'end - 1 chars'))\n    elsif index.kind_of?(TkTextMark)\n      if tk_call_without_enc(@t.path,'index',index.path) == tk_call_without_enc(@t.path,'index','end')\n        @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', \n                                                       'end - 1 chars'))\n      else\n        @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', \n                                                       index.path))\n      end\n    else\n      @path = TkTextMark.new(@t, tk_call_without_enc(@t.path, 'index', _get_eval_enc_str(index)))\n    end\n    @path.gravity = 'left'\n    @index = @path.path\n    keys = _symbolkey2str(keys)\n    @id = keys['window']\n    # keys['window'] = @id.epath if @id.kind_of?(TkWindow)\n    keys['window'] = _epath(@id) if @id\n    if keys['create']\n      @p_create = keys['create']\n      # if @p_create.kind_of?(Proc)\n      if TkComm._callback_entry?(@p_create)\n=begin\n        keys['create'] = install_cmd(proc{\n                                       @id = @p_create.call\n                                       if @id.kind_of?(TkWindow)\n                                         @id.epath\n                                       else\n                                         @id\n                                       end\n                                     })\n=end\n        keys['create'] = install_cmd(proc{@id = @p_create.call; _epath(@id)})\n      end\n    end\n    tk_call_without_enc(@t.path, 'window', 'create', @index, \n                        *hash_kv(keys, true))\n    @path.gravity = 'right'\n  end\n\n  def id\n    Tk::Text::IndexString.new(_epath(@id))\n  end\n  def mark\n    @path\n  end\n\n  def [](slot)\n    cget(slot)\n  end\n  def []=(slot, value)\n    configure(slot, value)\n    value\n  end\n\n  def cget(slot)\n    @t.window_cget(@index, slot)\n  end\n  def cget_strict(slot)\n    @t.window_cget_strict(@index, slot)\n  end\n\n  def configure(slot, value=None)\n    if slot.kind_of?(Hash)\n      slot = _symbolkey2str(slot)\n      if slot['window']\n        @id = slot['window'] \n        # slot['window'] = @id.epath if @id.kind_of?(TkWindow)\n        slot['window'] = _epath(@id) if @id\n      end\n      if slot['create']\n        self.create=slot.delete('create')\n      end\n      if slot.size > 0\n        tk_call_without_enc(@t.path, 'window', 'configure', @index, \n                            *hash_kv(slot, true))\n      end\n    else\n      if slot == 'window' || slot == :window\n        @id = value \n        # value = @id.epath if @id.kind_of?(TkWindow)\n        value = _epath(@id) if @id\n      end\n      if slot == 'create' || slot == :create\n        self.create=value\n      else\n        tk_call_without_enc(@t.path, 'window', 'configure', @index, \n                            \"-#{slot}\", _get_eval_enc_str(value))\n      end\n    end\n    self\n  end\n\n  def configinfo(slot = nil)\n    @t.window_configinfo(@index, slot)\n  end\n\n  def current_configinfo(slot = nil)\n    @t.current_window_configinfo(@index, slot)\n  end\n\n  def window\n    @id\n  end\n\n  def window=(value)\n    @id = value\n    # value = @id.epath if @id.kind_of?(TkWindow)\n    value = _epath(@id) if @id\n    tk_call_without_enc(@t.path, 'window', 'configure', @index, \n                        '-window', _get_eval_enc_str(value))\n    value\n  end\n\n  def create\n    @p_create\n  end\n\n  def create=(value)\n    @p_create = value\n    # if @p_create.kind_of?(Proc)\n    if TkComm._callback_entry?(@p_create)\n      value = install_cmd(proc{\n                            @id = @p_create.call\n                            if @id.kind_of?(TkWindow)\n                              @id.epath\n                            else\n                              @id\n                            end\n                          })\n    end\n    tk_call_without_enc(@t.path, 'window', 'configure', @index, \n                        '-create', _get_eval_enc_str(value))\n    value\n  end\nend\n\nTktWindow = TkTextWindow\n"
  },
  {
    "path": "ext/tk/lib/tk/timer.rb",
    "content": "#\n#   tk/timer.rb : methods for Tcl/Tk after command\n#\n#   $Id$\n#\nrequire 'tk'\n\nclass TkTimer\n  include TkCore\n  extend TkCore\n\n  TkCommandNames = ['after'.freeze].freeze\n\n  (Tk_CBID = ['a'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  Tk_CBTBL = {}.taint\n\n  TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')\n    if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} {\n        return -code $st $ret\n    } {\n        return $ret\n    }\n  EOL\n\n  DEFAULT_IGNORE_EXCEPTIONS = [ NameError, RuntimeError ].freeze\n\n  ###############################\n  # class methods\n  ###############################\n  def self.start(*args, &b)\n    self.new(*args, &b).start\n  end\n\n  def self.callback(obj_id)\n    ex_obj = Tk_CBTBL[obj_id]\n    return \"\" if ex_obj == nil; # canceled\n    ex_obj.cb_call\n  end\n\n  def self.info(obj = nil)\n    if obj\n      if obj.kind_of?(TkTimer)\n        if obj.after_id\n          inf = tk_split_list(tk_call_without_enc('after','info',obj.after_id))\n          [Tk_CBTBL[inf[0][1]], inf[1]]\n        else\n          nil\n        end\n      else\n        fail ArgumentError, \"TkTimer object is expected\"\n      end\n    else\n      tk_call_without_enc('after', 'info').split(' ').collect!{|id|\n        ret = Tk_CBTBL.find{|key,val| val.after_id == id}\n        (ret == nil)? id: ret[1]\n      }\n    end\n  end\n\n\n  ###############################\n  # instance methods\n  ###############################\n  def do_callback\n    @in_callback = true\n    @after_id = nil\n    begin\n      @return_value = @current_proc.call(self)\n    rescue SystemExit\n      exit(0)\n    rescue Interrupt\n      exit!(1)\n    rescue Exception => e\n      if @cancel_on_exception && \n          @cancel_on_exception.find{|exc| e.kind_of?(exc)}\n        cancel\n        @return_value = e\n        @in_callback = false\n        return e\n      else\n        fail e\n      end\n    end\n    if @set_next\n      set_next_callback(@current_args)\n    else\n      @set_next = true\n    end\n    @in_callback = false\n    @return_value\n  end\n\n  def set_callback(sleep, args=nil)\n    if TkCore::INTERP.deleted?\n      self.cancel\n      return self\n    end\n    @after_script = \"rb_after #{@id}\"\n    @current_args = args\n    @current_script = [sleep, @after_script]\n    @after_id = tk_call_without_enc('after', sleep, @after_script)\n    self\n  end\n\n  def set_next_callback(args)\n    if @running == false || @proc_max == 0 || @do_loop == 0\n      Tk_CBTBL.delete(@id) ;# for GC\n      @running = false\n      # @wait_var.value = 0\n      __at_end__\n      return\n    end\n    if @current_pos >= @proc_max\n      if @do_loop < 0 || (@do_loop -= 1) > 0\n        @current_pos = 0\n      else\n        Tk_CBTBL.delete(@id) ;# for GC\n        @running = false\n        # @wait_var.value = 0\n        __at_end__\n        return\n      end\n    end\n\n    @current_args = args\n\n    # if @sleep_time.kind_of?(Proc)\n    if TkComm._callback_entry?(@sleep_time)\n      sleep = @sleep_time.call(self)\n    else\n      sleep = @sleep_time\n    end\n    @current_sleep = sleep\n\n    cmd, *cmd_args = @loop_proc[@current_pos]\n    @current_pos += 1\n    @current_proc = cmd\n\n    set_callback(sleep, cmd_args)\n  end\n\n  def initialize(*args, &b)\n    Tk_CBID.mutex.synchronize{\n      # @id = Tk_CBID.join('')\n      @id = Tk_CBID.join(TkCore::INTERP._ip_id_)\n      Tk_CBID[1].succ!\n    }\n\n    @wait_var = TkVariable.new(0)\n\n    @at_end_proc = nil\n\n    @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback))\n\n    @set_next = true\n\n    @init_sleep = 0\n    @init_proc = nil\n    @init_args = []\n\n    @current_script = []\n    @current_proc = nil\n    @current_args = nil\n    @return_value = nil\n\n    @sleep_time = 0\n    @current_sleep = 0\n    @loop_exec = 0\n    @do_loop = 0\n    @loop_proc = []\n    @proc_max = 0\n    @current_pos = 0\n\n    @after_id = nil\n    @after_script = nil\n\n    @cancel_on_exception = DEFAULT_IGNORE_EXCEPTIONS\n    # Unless @cancel_on_exception, Ruby/Tk shows an error dialog box when \n    # an excepsion is raised on TkTimer callback procedure. \n    # If @cancel_on_exception is an array of exception classes and the raised \n    # exception is included in the array, Ruby/Tk cancels executing TkTimer \n    # callback procedures silently (TkTimer#cancel is called and no dialog is \n    # shown). \n\n    if b\n      case args.size\n      when 0\n        add_procs(b)\n      when 1\n        args << -1 << b\n      else\n        args << b\n      end\n    end\n\n    set_procs(*args) if args != []\n\n    @running = false\n    @in_callback = false\n  end\n\n  attr :after_id\n  attr :after_script\n  attr :current_proc\n  attr :current_args\n  attr :current_sleep\n  alias :current_interval :current_sleep\n  attr :return_value\n\n  attr_accessor :loop_exec\n\n  def __at_end__\n    @at_end_proc.call(self) if @at_end_proc\n    @wait_var.value = 0  # for wait\n  end\n  private :__at_end__\n\n  def cb_call\n    @cb_cmd.call\n  end\n\n  def get_procs\n    [@init_sleep, @init_proc, @init_args, @sleep_time, @loop_exec, @loop_proc]\n  end\n\n  def current_status\n    [@running, @current_sleep, @current_proc, @current_args, \n      @do_loop, @cancel_on_exception]\n  end\n\n  def cancel_on_exception?\n    @cancel_on_exception\n  end\n\n  def cancel_on_exception=(mode)\n    if mode.kind_of?(Array)\n      @cancel_on_exception = mode\n    elsif mode\n      @cancel_on_exception = DEFAULT_IGNORE_EXCEPTIONS\n    else\n      @cancel_on_exception = false\n    end\n    #self\n  end\n\n  def running?\n    @running\n  end\n\n  def loop_rest\n    @do_loop\n  end\n\n  def loop_rest=(rest)\n    @do_loop = rest\n    #self\n  end\n\n  def set_interval(interval)\n    #if interval != 'idle' && interval != :idle \\\n    #  && !interval.kind_of?(Integer) && !interval.kind_of?(Proc)\n    if interval != 'idle' && interval != :idle \\\n      && !interval.kind_of?(Integer) && !TkComm._callback_entry?(interval)\n      fail ArgumentError, \"expect Integer or Proc\"\n    end\n    @sleep_time = interval\n  end\n\n  def set_procs(interval, loop_exec, *procs)\n    #if interval != 'idle' && interval != :idle \\\n    #   && !interval.kind_of?(Integer) && !interval.kind_of?(Proc)\n    if interval != 'idle' && interval != :idle \\\n      && !interval.kind_of?(Integer) && !TkComm._callback_entry?(interval)\n      fail ArgumentError, \"expect Integer or Proc for 1st argument\"\n    end\n    @sleep_time = interval\n\n    @loop_proc = []\n    procs.each{|e|\n      # if e.kind_of?(Proc)\n      if TkComm._callback_entry?(e)\n        @loop_proc.push([e])\n      else\n        @loop_proc.push(e)\n      end\n    }\n    @proc_max = @loop_proc.size\n    @current_pos = 0\n\n    if loop_exec.kind_of?(Integer) && loop_exec < 0\n      @loop_exec = -1\n    elsif loop_exec == true\n      @loop_exec = -1\n    elsif loop_exec == nil || loop_exec == false || loop_exec == 0\n      @loop_exec = 0\n    else\n      if not loop_exec.kind_of?(Integer)\n        fail ArgumentError, \"expect Integer for 2nd argument\"\n      end\n      @loop_exec = loop_exec\n    end\n    @do_loop = @loop_exec\n\n    self\n  end\n\n  def add_procs(*procs)\n    procs.each{|e|\n      # if e.kind_of?(Proc)\n      if TkComm._callback_entry?(e)\n        @loop_proc.push([e])\n      else\n        @loop_proc.push(e)\n      end\n    }\n    @proc_max = @loop_proc.size\n\n    self\n  end\n\n  def delete_procs(*procs)\n    procs.each{|e|\n      # if e.kind_of?(Proc)\n      if TkComm._callback_entry?(e)\n        @loop_proc.delete([e])\n      else\n        @loop_proc.delete(e)\n      end\n    }\n    @proc_max = @loop_proc.size\n\n    cancel if @proc_max == 0\n\n    self\n  end\n\n  def delete_at(n)\n    @loop_proc.delete_at(n)\n    @proc_max = @loop_proc.size\n    cancel if @proc_max == 0\n    self\n  end\n\n  def set_start_proc(sleep=nil, init_proc=nil, *init_args, &b)\n    # set parameters for 'restart'\n    sleep = @init_sleep unless sleep\n\n    if sleep != 'idle' && sleep != :idle && !sleep.kind_of?(Integer)\n      fail ArgumentError, \"expect Integer or 'idle' for 1st argument\"\n    end\n\n    @init_sleep = sleep\n    @init_proc = init_proc\n    @init_args = init_args\n\n    @init_proc = b if !@init_proc && b\n    @init_proc = proc{|*args| } if @init_sleep > 0 && !@init_proc\n\n    self\n  end\n\n  def start(*init_args, &b)\n    return nil if @running\n\n    Tk_CBTBL[@id] = self\n    @do_loop = @loop_exec\n    @current_pos = 0\n    @return_value = nil\n    @after_id = nil\n\n    @init_sleep = 0\n    @init_proc  = nil\n    @init_args  = nil\n\n    argc = init_args.size\n    if argc > 0\n      sleep = init_args.shift\n      if sleep != 'idle' && sleep != :idle && !sleep.kind_of?(Integer)\n        fail ArgumentError, \"expect Integer or 'idle' for 1st argument\"\n      end\n      @init_sleep = sleep\n    end\n    @init_proc = init_args.shift if argc > 1\n    @init_args = init_args if argc > 2\n\n    @init_proc = b if !@init_proc && b\n    @init_proc = proc{|*args| } if @init_sleep > 0 && !@init_proc\n\n    @current_sleep = @init_sleep\n    @running = true\n    if @init_proc\n      # if not @init_proc.kind_of?(Proc)\n      if !TkComm._callback_entry?(@init_proc)\n        fail ArgumentError, \"Argument '#{@init_proc}' need to be Proc\"\n      end\n      @current_proc = @init_proc\n      set_callback(@init_sleep, @init_args)\n      @set_next = false if @in_callback\n    else\n      set_next_callback(@init_args)\n    end\n\n    self\n  end\n\n  def reset(*reset_args)\n    restart() if @running\n\n    if @init_proc\n      @return_value = @init_proc.call(self)\n    else\n      @return_value = nil\n    end\n\n    @current_pos   = 0\n    @current_args  = @init_args\n    @current_script = []\n\n    @set_next = false if @in_callback\n\n    self\n  end\n\n  def restart(*restart_args, &b)\n    cancel if @running\n    if restart_args == [] && !b\n      start(@init_sleep, @init_proc, *@init_args)\n    else\n      start(*restart_args, &b)\n    end\n  end\n\n  def cancel\n    @running = false\n    # @wait_var.value = 0\n    __at_end__\n    tk_call 'after', 'cancel', @after_id if @after_id\n    @after_id = nil\n\n    Tk_CBTBL.delete(@id) ;# for GC\n    self\n  end\n  alias stop cancel\n\n  def continue(wait=nil)\n    fail RuntimeError, \"is already running\" if @running\n    return restart() if @current_script.empty?\n    sleep, cmd = @current_script\n    fail RuntimeError, \"no procedure to continue\" unless cmd\n    if wait\n      unless wait.kind_of?(Integer)\n        fail ArgumentError, \"expect Integer for 1st argument\"\n      end\n      sleep = wait\n    end\n    Tk_CBTBL[@id] = self\n    @running = true\n    @after_id = tk_call_without_enc('after', sleep, cmd)\n    self\n  end\n\n  def skip\n    fail RuntimeError, \"is not running now\" unless @running\n    cancel\n    Tk_CBTBL[@id] = self\n    @running = true\n    set_next_callback(@current_args)\n    self\n  end\n\n  def info\n    if @after_id\n      inf = tk_split_list(tk_call_without_enc('after', 'info', @after_id))\n      [Tk_CBTBL[inf[0][1]], inf[1]]\n    else\n      nil\n    end\n  end\n\n  def at_end(*arg, &b)\n    if arg.empty?\n      if b \n        @at_end_proc = b\n      else \n        # no proc\n        return @at_end_proc \n      end\n    else\n      fail ArgumentError, \"wrong number of arguments\" if arg.length != 1 || b\n      @at_end_proc = arg[0]\n    end\n    self\n  end\n\n  def wait(on_thread = true, check_root = false)\n    if $SAFE >= 4\n      fail SecurityError, \"can't wait timer at $SAFE >= 4\"\n    end\n\n    unless @running\n      if @return_value.kind_of?(Exception)\n        fail @return_value \n      else\n        return @return_value \n      end\n    end\n\n    @wait_var.wait(on_thread, check_root)\n    if @return_value.kind_of?(Exception)\n      fail @return_value \n    else\n      @return_value \n    end\n  end\n  def eventloop_wait(check_root = false)\n    wait(false, check_root)\n  end\n  def thread_wait(check_root = false)\n    wait(true, check_root)\n  end\n  def tkwait(on_thread = true)\n    wait(on_thread, true)\n  end\n  def eventloop_tkwait\n    wait(false, true)\n  end\n  def thread_tkwait\n    wait(true, true)\n  end\nend\n\nTkAfter = TkTimer\n\n\nclass TkRTTimer < TkTimer\n  DEFAULT_OFFSET_LIST_SIZE = 5\n\n  def initialize(*args, &b)\n    super(*args, &b)\n\n    @offset_list = Array.new(DEFAULT_OFFSET_LIST_SIZE){ [0, 0] }\n    @offset_s = 0\n    @offset_u = 0\n    @est_time = nil\n  end\n\n  def start(*args, &b)\n    return nil if @running\n    @est_time = nil\n    @cb_start_time = Time.now\n    super(*args, &b)\n  end\n\n  def cancel\n    super()\n    @est_time = nil\n    @cb_start_time = Time.now\n    self\n  end\n  alias stop cancel\n\n  def continue(wait=nil)\n    fail RuntimeError, \"is already running\" if @running\n    @cb_start_time = Time.now\n    super(wait)\n  end\n\n  def set_interval(interval)\n    super(interval)\n    @est_time = nil\n  end\n\n  def _offset_ave\n    size = 0\n    d_sec = 0; d_usec = 0\n    @offset_list.each_with_index{|offset, idx|\n      # weight = 1\n      weight = idx + 1\n      size += weight\n      d_sec += offset[0] * weight\n      d_usec += offset[1] * weight\n    }\n    offset_s, mod = d_sec.divmod(size)\n    offset_u = ((mod * 1000000 + d_usec) / size.to_f).round\n    [offset_s, offset_u]\n  end\n  private :_offset_ave\n\n  def set_next_callback(args)\n    if @running == false || @proc_max == 0 || @do_loop == 0\n      Tk_CBTBL.delete(@id) ;# for GC\n      @running = false\n      # @wait_var.value = 0\n      __at_end__\n      return\n    end\n    if @current_pos >= @proc_max\n      if @do_loop < 0 || (@do_loop -= 1) > 0\n        @current_pos = 0\n      else\n        Tk_CBTBL.delete(@id) ;# for GC\n        @running = false\n        # @wait_var.value = 0\n        __at_end__\n        return\n      end\n    end\n\n    @current_args = args\n\n    cmd, *cmd_args = @loop_proc[@current_pos]\n    @current_pos += 1\n    @current_proc = cmd\n\n    @offset_s, @offset_u = _offset_ave\n\n    if TkComm._callback_entry?(@sleep_time)\n      sleep = @sleep_time.call(self)\n    else\n      sleep = @sleep_time\n    end\n\n    if @est_time\n      @est_time = Time.at(@est_time.to_i, @est_time.usec + sleep*1000)\n    else\n      @est_time = Time.at(@cb_start_time.to_i, \n                          @cb_start_time.usec + sleep*1000)\n    end\n\n    now = Time.now\n    real_sleep = ((@est_time.to_i - now.to_i + @offset_s)*1000.0 + \n                  (@est_time.usec - now.usec + @offset_u)/1000.0).round\n    if real_sleep <= 0\n      real_sleep = 0\n      @offset_s = now.to_i\n      @offset_u = now.usec\n    end\n    @current_sleep = real_sleep\n\n    set_callback(real_sleep, cmd_args)\n  end\n\n  def cb_call\n    if @est_time\n      @offset_list.shift\n\n      @cb_start_time = Time.now\n\n      if @current_sleep == 0\n        @offset_list.push([\n                            @offset_s - @cb_start_time.to_i, \n                            @offset_u - @cb_start_time.usec\n                          ])\n      else\n        @offset_list.push([\n                            @offset_s + (@est_time.to_i - @cb_start_time.to_i),\n                            @offset_u + (@est_time.usec - @cb_start_time.usec)\n                          ])\n      end\n    end\n\n    @cb_cmd.call\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/toplevel.rb",
    "content": "#\n# tk/toplevel.rb : treat toplevel widget\n#\nrequire 'tk'\nrequire 'tk/wm'\nrequire 'tk/menuspec'\n\nclass Tk::Toplevel<TkWindow\n  include Wm\n  include TkMenuSpec\n\n  TkCommandNames = ['toplevel'.freeze].freeze\n  WidgetClassName = 'Toplevel'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n################# old version\n#  def initialize(parent=nil, screen=nil, classname=nil, keys=nil)\n#    if screen.kind_of? Hash\n#      keys = screen.dup\n#    else\n#      @screen = screen\n#    end\n#    @classname = classname\n#    if keys.kind_of? Hash\n#      keys = keys.dup\n#      @classname = keys.delete('classname') if keys.key?('classname')\n#      @colormap  = keys.delete('colormap')  if keys.key?('colormap')\n#      @container = keys.delete('container') if keys.key?('container')\n#      @screen    = keys.delete('screen')    if keys.key?('screen')\n#      @use       = keys.delete('use')       if keys.key?('use')\n#      @visual    = keys.delete('visual')    if keys.key?('visual')\n#    end\n#    super(parent, keys)\n#  end\n#\n#  def create_self\n#    s = []\n#    s << \"-class\"     << @classname if @classname\n#    s << \"-colormap\"  << @colormap  if @colormap\n#    s << \"-container\" << @container if @container\n#    s << \"-screen\"    << @screen    if @screen \n#    s << \"-use\"       << @use       if @use\n#    s << \"-visual\"    << @visual    if @visual\n#    tk_call 'toplevel', @path, *s\n#  end\n#################\n\n  def __boolval_optkeys\n    super() << 'container'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'screen'\n  end\n  private :__strval_optkeys\n\n  def __val2ruby_optkeys  # { key=>proc, ... }\n    super().update('menu'=>proc{|v| window(v)})\n  end\n  private :__val2ruby_optkeys\n\n  def __methodcall_optkeys  # { key=>method, ... }\n    TOPLEVEL_METHODCALL_OPTKEYS\n  end\n  private :__methodcall_optkeys\n\n  def _wm_command_option_chk(keys)\n    keys = {} unless keys\n    new_keys = {}\n    wm_cmds = {}\n\n    conf_methods = _symbolkey2str(__methodcall_optkeys())\n\n    keys.each{|k,v| # k is a String\n      if conf_methods.key?(k)\n        wm_cmds[conf_methods[k]] = v\n      elsif Wm.method_defined?(k)\n        case k\n        when 'screen','class','colormap','container','use','visual'\n          new_keys[k] = v\n        else\n          case self.method(k).arity\n          when -1,1\n            wm_cmds[k] = v\n          else\n            new_keys[k] = v\n          end\n        end\n      else\n        new_keys[k] = v\n      end\n    }\n    [new_keys, wm_cmds]\n  end\n  private :_wm_command_option_chk\n\n  def initialize(parent=nil, screen=nil, classname=nil, keys=nil)\n    my_class_name = nil\n    if self.class < WidgetClassNames[WidgetClassName]\n      my_class_name = self.class.name\n      my_class_name = nil if my_class_name == ''\n    end\n    if parent.kind_of? Hash\n      keys = _symbolkey2str(parent)\n      if keys.key?('classname')\n        keys['class'] = keys.delete('classname')\n      end\n      @classname = keys['class']\n      @colormap  = keys['colormap']\n      @container = keys['container']\n      @screen    = keys['screen']\n      @use       = keys['use']\n      @visual    = keys['visual']\n      if !@classname && my_class_name\n        keys['class'] = @classname = my_class_name \n      end\n      if @classname.kind_of? TkBindTag\n        @db_class = @classname\n        keys['class'] = @classname = @classname.id\n      elsif @classname\n        @db_class = TkDatabaseClass.new(@classname)\n        keys['class'] = @classname\n      else\n        @db_class = self.class\n        @classname = @db_class::WidgetClassName\n      end\n      keys, cmds = _wm_command_option_chk(keys)\n      super(keys)\n      cmds.each{|k,v| \n        if v.kind_of? Array\n          self.__send__(k,*v)\n        else\n          self.__send__(k,v)\n        end\n      }\n      return\n    end\n\n    if screen.kind_of? Hash\n      keys = screen\n    else\n      @screen = screen\n      if classname.kind_of? Hash\n        keys = classname\n      else\n        @classname = classname\n      end\n    end\n    if keys.kind_of? Hash\n      keys = _symbolkey2str(keys)\n      if keys.key?('classname')\n        keys['class'] = keys.delete('classname')\n      end\n      @classname = keys['class']  unless @classname\n      @colormap  = keys['colormap']\n      @container = keys['container']\n      @screen    = keys['screen'] unless @screen\n      @use       = keys['use']\n      @visual    = keys['visual']\n    else\n      keys = {}\n    end\n    if !@classname && my_class_name\n      keys['class'] = @classname = my_class_name \n    end\n    if @classname.kind_of? TkBindTag\n      @db_class = @classname\n      keys['class'] = @classname = @classname.id\n    elsif @classname\n      @db_class = TkDatabaseClass.new(@classname)\n      keys['class'] = @classname\n    else\n      @db_class = self.class\n      @classname = @db_class::WidgetClassName\n    end\n    keys, cmds = _wm_command_option_chk(keys)\n    super(parent, keys)\n    cmds.each{|k,v| \n      if v.kind_of? Array\n        self.send(k,*v)\n      else\n        self.send(k,v)\n      end\n    }\n  end\n\n  #def create_self(keys)\n  #  if keys and keys != None\n  #    tk_call_without_enc('toplevel', @path, *hash_kv(keys, true))\n  #  else\n  #    tk_call_without_enc('toplevel', @path)\n  #  end\n  #end\n  #private :create_self\n\n  def specific_class\n    @classname\n  end\n\n  def add_menu(menu_info, tearoff=false, opts=nil)\n    # See tk/menuspec.rb for menu_info.\n    # opts is a hash of default configs for all of cascade menus. \n    # Configs of menu_info can override it. \n    if tearoff.kind_of?(Hash)\n      opts = tearoff\n      tearoff = false\n    end\n    _create_menubutton(self, menu_info, tearoff, opts)\n  end\n\n  def add_menubar(menu_spec, tearoff=false, opts=nil)\n    # See tk/menuspec.rb for menu_spec.\n    # opts is a hash of default configs for all of cascade menus.\n    # Configs of menu_spec can override it. \n    menu_spec.each{|info| add_menu(info, tearoff, opts)}\n    self.menu\n  end\n\n  def self.database_class\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      self\n    else\n      TkDatabaseClass.new(self.name)\n    end\n  end\n  def self.database_classname\n    self.database_class.name\n  end\n\n  def self.bind(*args, &b)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args, &b)\n    else\n      TkDatabaseClass.new(self.name).bind(*args, &b)\n    end\n  end\n  def self.bind_append(*args, &b)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args, &b)\n    else\n      TkDatabaseClass.new(self.name).bind_append(*args, &b)\n    end\n  end\n  def self.bind_remove(*args)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args)\n    else\n      TkDatabaseClass.new(self.name).bind_remove(*args)\n    end\n  end\n  def self.bindinfo(*args)\n    if self == WidgetClassNames[WidgetClassName] || self.name == ''\n      super(*args)\n    else\n      TkDatabaseClass.new(self.name).bindinfo(*args)\n    end\n  end\nend\n\n#TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel\nTk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)\n"
  },
  {
    "path": "ext/tk/lib/tk/ttk_selector.rb",
    "content": "#\n#  ttk_selector\n#\n######################################\n#  toplevel classes/modules\nmodule Tk\n  @TOPLEVEL_ALIAS_TABLE[:Ttk] = {\n    :TkButton       => 'tkextlib/tile/tbutton', \n\n    :TkCheckbutton  => 'tkextlib/tile/tcheckbutton', \n    :TkCheckButton  => 'tkextlib/tile/tcheckbutton', \n\n    # :TkDialog       => 'tkextlib/tile/dialog', \n\n    :TkEntry        => 'tkextlib/tile/tentry', \n\n    :TkCombobox     => 'tkextlib/tile/tcombobox', \n\n    :TkFrame        => 'tkextlib/tile/tframe', \n\n    :TkLabel        => 'tkextlib/tile/tlabel', \n\n    :TkLabelframe   => 'tkextlib/tile/tlabelframe', \n    :TkLabelFrame   => 'tkextlib/tile/tlabelframe', \n\n    :TkMenubutton   => 'tkextlib/tile/tmenubutton', \n    :TkMenuButton   => 'tkextlib/tile/tmenubutton', \n\n    :TkNotebook     => 'tkextlib/tile/tnotebook', \n\n    # :TkPaned        => 'tkextlib/tile/tpaned', \n    :TkPanedwindow  => 'tkextlib/tile/tpaned', \n    :TkPanedWindow  => 'tkextlib/tile/tpaned', \n\n    :TkProgressbar  => 'tkextlib/tile/tprogressbar', \n\n    :TkRadiobutton  => 'tkextlib/tile/tradiobutton', \n    :TkRadioButton  => 'tkextlib/tile/tradiobutton', \n\n    :TkScale        => 'tkextlib/tile/tscale', \n    # :TkProgress     => 'tkextlib/tile/tscale', \n\n    :TkScrollbar    => 'tkextlib/tile/tscrollbar', \n    :TkXScrollbar   => 'tkextlib/tile/tscrollbar', \n    :TkYScrollbar   => 'tkextlib/tile/tscrollbar', \n\n    :TkSeparator    => 'tkextlib/tile/tseparator', \n\n    :TkSizeGrip     => 'tkextlib/tile/sizegrip', \n    :TkSizegrip     => 'tkextlib/tile/sizegrip', \n\n    # :TkSquare       => 'tkextlib/tile/tsquare', \n\n    :TkTreeview     => 'tkextlib/tile/treeview', \n  }\n  @TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]\n\n  ################################################\n  # register some Ttk widgets as default\n  # (Ttk is a standard library on Tcl/Tk8.5+)\n  @TOPLEVEL_ALIAS_TABLE[:Ttk].each{|sym, file|\n    unless Object.autoload?(sym) || Object.const_defined?(sym)\n      Object.autoload(sym, file)\n    end\n  }\n\n  ################################################\n\n  @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] = \n    @TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|\n    unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile) \n      Object.autoload :Ttk, 'tkextlib/tile'\n      Tk.autoload :Tile, 'tkextlib/tile'\n    end\n  }\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/txtwin_abst.rb",
    "content": "#\n# tk/txtwin_abst.rb : TkTextWin abstruct class\n#\nrequire 'tk'\n\nclass TkTextWin<TkWindow\n  TkCommandNames = [].freeze\n  #def create_self\n  #  fail RuntimeError, \"TkTextWin is an abstract class\"\n  #end\n  #private :create_self\n\n  def bbox(index)\n    list(tk_send_without_enc('bbox', index))\n  end\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n  def get(*index)\n    _fromUTF8(tk_send_without_enc('get', *index))\n  end\n  def insert(index, *args)\n    tk_send('insert', index, *args)\n    self\n  end\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n  def see(index)\n    tk_send_without_enc('see', index)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/validation.rb",
    "content": "#\n#  tk/validation.rb - validation support module for entry, spinbox, and so on\n#\nrequire 'tk'\n\nmodule Tk\n  module ValidateConfigure\n    def self.__def_validcmd(scope, klass, keys=nil)\n      keys = klass._config_keys unless keys\n      keys.each{|key|\n        eval(\"def #{key}(*args, &b)\n                 __validcmd_call(#{klass.name}, '#{key}', *args, &b)\n              end\", scope)\n      }\n    end\n\n    def __validcmd_call(klass, key, *args, &b)\n      return cget(key) if args.empty? && !b\n\n      cmd = (b)? proc(&b) : args.shift\n\n      if cmd.kind_of?(klass)\n        configure(key, cmd)\n      elsif !args.empty?\n        configure(key, [cmd, args])\n      else\n        configure(key, cmd)\n      end\n    end\n\n    def __validation_class_list\n      # maybe need to override\n      []\n    end\n\n    def __get_validate_key2class\n      k2c = {}\n      __validation_class_list.each{|klass|\n        klass._config_keys.each{|key|\n          k2c[key.to_s] = klass\n        }\n      }\n      k2c\n    end\n\n    def __conv_vcmd_on_hash_kv(keys)\n      key2class = __get_validate_key2class\n\n      keys = _symbolkey2str(keys)\n      key2class.each{|key, klass|\n        if keys[key].kind_of?(Array)\n          cmd, *args = keys[key]\n          #keys[key] = klass.new(cmd, args.join(' '))\n          keys[key] = klass.new(cmd, *args)\n        # elsif keys[key].kind_of?(Proc) ||  keys[key].kind_of?(Method)\n        elsif TkComm._callback_entry?(keys[key])\n          keys[key] = klass.new(keys[key])\n        end\n      }\n      keys\n    end\n\n    def create_self(keys)\n      super(__conv_vcmd_on_hash_kv(keys))\n    end\n    private :create_self\n\n    def configure(slot, value=TkComm::None)\n      if slot.kind_of?(Hash)\n        super(__conv_vcmd_on_hash_kv(slot))\n      else\n        super(__conv_vcmd_on_hash_kv(slot=>value))\n      end\n      self\n    end\n=begin\n    def configure(slot, value=TkComm::None)\n      key2class = __get_validate_key2class\n\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        key2class.each{|key, klass|\n          if slot[key].kind_of?(Array)\n            cmd, *args = slot[key]\n            slot[key] = klass.new(cmd, args.join(' '))\n          elsif slot[key].kind_of?(Proc) || slot[key].kind_of?(Method)\n            slot[key] = klass.new(slot[key])\n          end\n        }\n        super(slot)\n\n      else\n        slot = slot.to_s\n        if (klass = key2class[slot])\n          if value.kind_of?(Array)\n            cmd, *args = value\n            value = klass.new(cmd, args.join(' '))\n          elsif value.kind_of?(Proc) || value.kind_of?(Method)\n            value = klass.new(value)\n          end\n        end\n        super(slot, value)\n      end\n\n      self\n    end\n=end\n  end\n\n  module ItemValidateConfigure\n    def self.__def_validcmd(scope, klass, keys=nil)\n      keys = klass._config_keys unless keys\n      keys.each{|key|\n        eval(\"def item_#{key}(id, *args, &b)\n                 __item_validcmd_call(#{klass.name}, '#{key}', id, *args, &b)\n              end\", scope)\n      }\n    end\n\n    def __item_validcmd_call(tagOrId, klass, key, *args, &b)\n      return itemcget(tagid(tagOrId), key) if args.empty? && !b\n\n      cmd = (b)? proc(&b) : args.shift\n\n      if cmd.kind_of?(klass)\n        itemconfigure(tagid(tagOrId), key, cmd)\n      elsif !args.empty?\n        itemconfigure(tagid(tagOrId), key, [cmd, args])\n      else\n        itemconfigure(tagid(tagOrId), key, cmd)\n      end\n    end\n\n    def __item_validation_class_list(id)\n      # maybe need to override\n      []\n    end\n\n    def __get_item_validate_key2class(id)\n      k2c = {}\n      __item_validation_class_list(id).each{|klass|\n        klass._config_keys.each{|key|\n          k2c[key.to_s] = klass\n        }\n      }\n    end\n\n    def __conv_item_vcmd_on_hash_kv(keys)\n      key2class = __get_item_validate_key2class(tagid(tagOrId))\n\n      keys = _symbolkey2str(keys)\n      key2class.each{|key, klass|\n        if keys[key].kind_of?(Array)\n          cmd, *args = keys[key]\n          #keys[key] = klass.new(cmd, args.join(' '))\n          keys[key] = klass.new(cmd, *args)\n        # elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method)\n        elsif TkComm._callback_entry?(keys[key])\n          keys[key] = klass.new(keys[key])\n        end\n      }\n      keys\n    end\n\n    def itemconfigure(tagOrId, slot, value=TkComm::None)\n      if slot.kind_of?(Hash)\n        super(__conv_item_vcmd_on_hash_kv(slot))\n      else\n        super(__conv_item_vcmd_on_hash_kv(slot=>value))\n      end\n      self\n    end\n=begin\n    def itemconfigure(tagOrId, slot, value=TkComm::None)\n      key2class = __get_item_validate_key2class(tagid(tagOrId))\n\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        key2class.each{|key, klass|\n          if slot[key].kind_of?(Array)\n            cmd, *args = slot[key]\n            slot[key] = klass.new(cmd, args.join(' '))\n          elsif slot[key].kind_of?(Proc) ||  slot[key].kind_of?(Method)\n            slot[key] = klass.new(slot[key])\n          end\n        }\n        super(slot)\n\n      else\n        slot = slot.to_s\n        if (klass = key2class[slot])\n          if value.kind_of?(Array)\n            cmd, *args = value\n            value = klass.new(cmd, args.join(' '))\n          elsif value.kind_of?(Proc) || value.kind_of?(Method)\n            value = klass.new(value)\n          end\n        end\n        super(slot, value)\n      end\n\n      self\n    end\n=end\n  end\nend\n\nclass TkValidateCommand\n  include TkComm\n  extend  TkComm\n\n  class ValidateArgs < TkUtil::CallbackSubst\n    KEY_TBL = [\n      [ ?d, ?n, :action ], \n      [ ?i, ?x, :index ], \n      [ ?s, ?e, :current ], \n      [ ?v, ?s, :type ], \n      [ ?P, ?e, :value ], \n      [ ?S, ?e, :string ], \n      [ ?V, ?s, :triggered ], \n      [ ?W, ?w, :widget ], \n      nil\n    ]\n\n    PROC_TBL = [\n      [ ?n, TkComm.method(:number) ], \n      [ ?s, TkComm.method(:string) ], \n      [ ?w, TkComm.method(:window) ], \n\n      [ ?e, proc{|val|\n          #enc = Tk.encoding\n          enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system)\n          if enc\n            Tk.fromUTF8(TkComm::string(val), enc)\n          else\n            TkComm::string(val)\n          end\n        }\n      ], \n\n      [ ?x, proc{|val|\n          idx = TkComm::number(val)\n          if idx < 0\n            nil\n          else\n            idx\n          end\n        }\n      ], \n\n      nil\n    ]\n\n=begin\n    # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n    KEY_TBL.map!{|inf|\n      if inf.kind_of?(Array)\n        inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n      end\n      inf\n    }\n\n    PROC_TBL.map!{|inf|\n      if inf.kind_of?(Array)\n        inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n      end\n      inf\n    }\n=end\n\n    _setup_subst_table(KEY_TBL, PROC_TBL);\n\n    #\n    # NOTE: The order of parameters which passed to callback procedure is \n    #        <extra_arg>, <extra_arg>, ... , <subst_arg>, <subst_arg>, ...\n    #\n\n    #def self._get_extra_args_tbl\n    #  # return an array of convert procs\n    #  []\n    #end\n\n    def self.ret_val(val)\n      (val)? '1': '0'\n    end\n  end\n\n  ###############################################\n\n  def self._config_keys\n    # array of config-option key (string or symbol)\n    ['vcmd', 'validatecommand', 'invcmd', 'invalidcommand']\n  end\n\n  def _initialize_for_cb_class(klass, cmd = Proc.new, *args)\n    extra_args_tbl = klass._get_extra_args_tbl\n\n    if args.compact.size > 0\n      args.map!{|arg| klass._sym2subst(arg)}\n      args = args.join(' ')\n      keys = klass._get_subst_key(args)\n      if cmd.kind_of?(String)\n        id = cmd\n      elsif cmd.kind_of?(TkCallbackEntry)\n        @id = install_cmd(cmd)\n      else\n        @id = install_cmd(proc{|*arg|\n             ex_args = []\n             extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)}\n             klass.ret_val(cmd.call(\n               *(ex_args.concat(klass.scan_args(keys, arg)))\n             ))\n        }) + ' ' + args\n      end\n    else\n      keys, args = klass._get_all_subst_keys\n      if cmd.kind_of?(String)\n        id = cmd\n      elsif cmd.kind_of?(TkCallbackEntry)\n        @id = install_cmd(cmd)\n      else\n        @id = install_cmd(proc{|*arg|\n             ex_args = []\n             extra_args_tbl.reverse_each{|conv| ex_args << conv.call(arg.pop)}\n             klass.ret_val(cmd.call(\n               *(ex_args << klass.new(*klass.scan_args(keys, arg)))\n             ))\n        }) + ' ' + args\n      end\n    end\n  end\n\n  def initialize(cmd = Proc.new, *args)\n    _initialize_for_cb_class(self.class::ValidateArgs, cmd, *args)\n  end\n\n  def to_eval\n    @id\n  end\nend\n\nmodule TkValidation\n  include Tk::ValidateConfigure\n\n  class ValidateCmd < TkValidateCommand\n    module Action\n      Insert = 1\n      Delete = 0\n      Others = -1\n      Focus  = -1\n      Forced = -1\n      Textvariable = -1\n      TextVariable = -1\n    end\n  end\n\n  #####################################\n\n  def __validation_class_list\n    super() << ValidateCmd\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, ValidateCmd)\n\n=begin\n  def validatecommand(cmd = Proc.new, args = nil)\n    if cmd.kind_of?(ValidateCmd)\n      configure('validatecommand', cmd)\n    elsif args\n      configure('validatecommand', [cmd, args])\n    else\n      configure('validatecommand', cmd)\n    end\n  end\n=end\n#  def validatecommand(*args, &b)\n#    __validcmd_call(ValidateCmd, 'validatecommand', *args, &b)\n#  end\n#  alias vcmd validatecommand\n\n=begin\n  def invalidcommand(cmd = Proc.new, args = nil)\n    if cmd.kind_of?(ValidateCmd)\n      configure('invalidcommand', cmd)\n    elsif args\n      configure('invalidcommand', [cmd, args])\n    else\n      configure('invalidcommand', cmd)\n    end\n  end\n=end\n#  def invalidcommand(*args, &b)\n#    __validcmd_call(ValidateCmd, 'invalidcommand', *args, &b)\n#  end\n#  alias invcmd invalidcommand\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/variable.rb",
    "content": "#\n# tk/variable.rb : treat Tk variable object\n#\nrequire 'tk'\n\nclass TkVariable\n  include Tk\n  extend TkCore\n\n  include Comparable\n\n  #TkCommandNames = ['tkwait'.freeze].freeze\n  TkCommandNames = ['vwait'.freeze].freeze\n\n  #TkVar_CB_TBL = {}\n  #TkVar_ID_TBL = {}\n  TkVar_CB_TBL = TkCore::INTERP.create_table\n  TkVar_ID_TBL = TkCore::INTERP.create_table\n  (Tk_VARIABLE_ID = [\"v\".freeze, \"00000\".taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n  TkCore::INTERP.init_ip_env{\n    TkVar_CB_TBL.mutex.synchronize{ TkVar_CB_TBL.clear }\n    TkVar_ID_TBL.mutex.synchronize{ TkVar_ID_TBL.clear }\n  }\n\n  major, minor, type, type_name, patchlevel = TclTkLib.get_version\n  USE_OLD_TRACE_OPTION_STYLE = (major < 8) || (major == 8 && minor < 4)\n\n  #TkCore::INTERP.add_tk_procs('rb_var', 'args', \n  #     \"ruby [format \\\"TkVariable.callback %%Q!%s!\\\" $args]\")\n  TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL')\n    if {[set st [catch {eval {ruby_cmd TkVariable callback} $args} ret]] != 0} {\n       set idx [string first \"\\n\\n\" $ret]\n       if {$idx > 0} {\n          global errorInfo\n          set tcl_backtrace $errorInfo\n          set errorInfo [string range $ret [expr $idx + 2] \\\n                                           [string length $ret]]\n          append errorInfo \"\\n\" $tcl_backtrace\n          bgerror [string range $ret 0 [expr $idx - 1]]\n       } else {\n          bgerror $ret\n       }\n       return \"\"\n       #return -code $st $ret\n    } else {\n        return $ret\n    }\n  EOL\n\n  #def TkVariable.callback(args)\n  def TkVariable.callback(id, name1, name2, op)\n    #name1,name2,op = tk_split_list(args)\n    #name1,name2,op = tk_split_simplelist(args)\n    if cb_obj = TkVar_CB_TBL[id]\n      #_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op))\n      begin\n        _get_eval_string(cb_obj.trace_callback(name2, op))\n      rescue SystemExit\n        exit(0)\n      rescue Interrupt\n        exit!(1)\n      rescue Exception => e\n        begin\n          msg = _toUTF8(e.class.inspect) + ': ' + \n                _toUTF8(e.message) + \"\\n\" + \n                \"\\n---< backtrace of Ruby side >-----\\n\" + \n                _toUTF8(e.backtrace.join(\"\\n\")) + \n                \"\\n---< backtrace of Tk side >-------\"\n          if TkCore::WITH_ENCODING\n            msg.force_encoding('utf-8')\n          else\n            msg.instance_variable_set(:@encoding, 'utf-8')\n          end\n        rescue Exception\n          msg = e.class.inspect + ': ' + e.message + \"\\n\" + \n                \"\\n---< backtrace of Ruby side >-----\\n\" + \n                e.backtrace.join(\"\\n\") + \n                \"\\n---< backtrace of Tk side >-------\"\n        end\n        fail(e, msg)\n      end\n=begin\n      begin\n        raise 'check backtrace'\n      rescue\n        # ignore backtrace before 'callback'\n        pos = -($!.backtrace.size)\n      end\n      begin\n        _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op))\n      rescue\n        trace = $!.backtrace\n        raise $!, \"\\n#{trace[0]}: #{$!.message} (#{$!.class})\\n\" + \n                  \"\\tfrom #{trace[1..pos].join(\"\\n\\tfrom \")}\"\n      end\n=end\n    else\n      ''\n    end\n  end\n\n  def self.new_hash(val = {})\n    if val.kind_of?(Hash)\n      self.new(val)\n    else\n      fail ArgumentError, 'Hash is expected'\n    end\n  end\n\n  #\n  # default_value is available only when the variable is an assoc array. \n  #\n  def default_value(val=nil, &b)\n    if b\n      @def_default = :proc\n      @default_val = proc(&b)\n    else\n      @def_default = :val\n      @default_val = val\n    end\n    self\n  end\n  def set_default_value(val)\n    @def_default = :val\n    @default_val = val\n    self\n  end\n  alias default_value= set_default_value\n  def default_proc(cmd = Proc.new)\n    @def_default = :proc\n    @default_val = cmd\n    self\n  end\n\n  def undef_default\n    @default_val = nil\n    @def_default = false\n    self\n  end\n\n  def default_value_type\n    @type\n  end\n  def default_element_value_type(idxs)\n    if idxs.kind_of?(Array)\n      index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')\n    else\n      index = _get_eval_string(idxs, true)\n    end\n    @element_type[index]\n  end\n\n  def _set_default_value_type_core(type, idxs)\n    if type.kind_of?(Class)\n      if type == NilClass\n        type = nil\n      elsif type == Numeric\n        type = :numeric\n      elsif type == TrueClass || type == FalseClass\n        type = :bool\n      elsif type == String\n        type = :string\n      elsif type == Symbol\n        type = :symbol\n      elsif type == Array\n        type = :list\n      elsif type <= TkVariable\n        type = :variable\n      elsif type <= TkWindow\n        type = :window\n      elsif TkComm._callback_entry_class?(type)\n        type = :procedure\n      else\n        type = nil\n      end\n    else\n      case(type)\n      when nil\n        type = nil\n      when :numeric, 'numeric'\n        type = :numeric\n      when true, false, :bool, 'bool'\n        type = :bool\n      when :string, 'string'\n        type = :string\n      when :symbol, 'symbol'\n        type = :symbol\n      when :list, 'list'\n        type = :list\n      when :numlist, 'numlist'\n        type = :numlist\n      when :variable, 'variable'\n        type = :variable\n      when :window, 'window'\n        type = :window\n      when :procedure, 'procedure'\n        type = :procedure\n      else\n        return _set_default_value_type_core(type.class, idxs)\n      end\n    end\n    if idxs\n      if idxs.kind_of?(Array)\n        index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')\n      else\n        index = _get_eval_string(idxs, true)\n      end\n      @element_type[index] = type\n    else\n      @type = type\n    end\n    type\n  end\n  private :_set_default_value_type_core\n\n  def set_default_value_type(type)\n    _set_default_value_type_core(type, nil)\n    self\n  end\n  alias default_value_type= set_default_value_type\n\n  def set_default_element_value_type(idxs, type)\n    _set_default_value_type_core(type, idxs)\n    self\n  end\n\n  def _to_default_type(val, idxs = nil)\n    if idxs\n      if idxs.kind_of?(Array)\n        index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')\n      else\n        index = _get_eval_string(idxs, true)\n      end\n      type = @element_type[index]\n    else\n      type = @type\n    end\n    return val unless type\n    if val.kind_of?(Hash)\n      val.keys.each{|k| val[k] = _to_default_type(val[k], idxs) }\n      val\n    else\n      begin\n        case(type)\n        when :numeric\n          number(val)\n        when :bool\n          TkComm.bool(val)\n        when :string\n          val\n        when :symbol\n          val.intern\n        when :list\n          tk_split_simplelist(val)\n        when :numlist\n          tk_split_simplelist(val).collect!{|v| number(v)}\n        when :variable\n          TkVarAccess.new(val)\n        when :window\n          TkComm.window(val)\n        when :procedure\n          TkComm.procedure(val)\n        else\n          val\n        end\n      rescue\n        val\n      end\n    end\n  end\n  private :_to_default_type\n\n  def _to_default_element_type(idxs, val)\n    _to_default_type(val, idxs)\n  end\n  private :_to_default_element_type\n\n  def initialize(val=\"\", type=nil)\n    # @id = Tk_VARIABLE_ID.join('')\n    begin\n      Tk_VARIABLE_ID.mutex.synchronize{\n        @id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_)\n        Tk_VARIABLE_ID[1].succ!\n      }\n    end until INTERP._invoke_without_enc('info', 'globals', @id).empty?\n\n    TkVar_ID_TBL.mutex.synchronize{\n      TkVar_ID_TBL[@id] = self\n    }\n\n    @var  = @id\n    @elem = nil\n\n    @def_default = false\n    @default_val = nil\n\n    @trace_var  = nil\n    @trace_elem = nil\n    @trace_opts = nil\n\n    @type = nil\n    var = self\n    @element_type = Hash.new{|k,v| var.default_value_type }\n\n    self.default_value_type = type\n\n    # teach Tk-ip that @id is global var\n    INTERP._invoke_without_enc('global', @id)\n    #INTERP._invoke('global', @id)\n\n    # create and init\n    if val.kind_of?(Hash)\n      # assoc-array variable\n      self[''] = 0\n      self.clear\n    end\n    self.value = val\n\n=begin\n    if val == []\n      # INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)', \n      #                     @id, @id, @id))\n    elsif val.kind_of?(Array)\n      a = []\n      # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}\n      # s = '\"' + a.join(\" \").gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      val.each_with_index{|e,i| a.push(i); a.push(e)}\n      #s = '\"' + array2tk_list(a).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      s = '\"' + array2tk_list(a).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(format('global %s; array set %s %s', @id, @id, s))\n    elsif  val.kind_of?(Hash)\n      #s = '\"' + val.to_a.collect{|e| array2tk_list(e)}.join(\" \")\\\n      #             .gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      s = '\"' + val.to_a.collect{|e| array2tk_list(e)}.join(\" \")\\\n                   .gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(format('global %s; array set %s %s', @id, @id, s))\n    else\n      #s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(format('global %s; set %s %s', @id, @id, s))\n    end\n=end\n=begin\n    if  val.kind_of?(Hash)\n      #s = '\"' + val.to_a.collect{|e| array2tk_list(e)}.join(\" \")\\\n      #             .gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      s = '\"' + val.to_a.collect{|e| array2tk_list(e)}.join(\" \")\\\n                   .gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s))\n    else\n      #s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))\n    end\n=end\n  end\n\n  def wait(on_thread = false, check_root = false)\n    if $SAFE >= 4\n      fail SecurityError, \"can't wait variable at $SAFE >= 4\"\n    end\n    on_thread &= (Thread.list.size != 1)\n    if on_thread\n      if check_root\n        INTERP._thread_tkwait('variable', @id)\n      else\n        INTERP._thread_vwait(@id)\n      end\n    else \n      if check_root\n        INTERP._invoke_without_enc('tkwait', 'variable', @id)\n      else\n        INTERP._invoke_without_enc('vwait', @id)\n      end\n    end\n  end\n  def eventloop_wait(check_root = false)\n    wait(false, check_root)\n  end\n  def thread_wait(check_root = false)\n    wait(true, check_root)\n  end\n  def tkwait(on_thread = true)\n    wait(on_thread, true)\n  end\n  def eventloop_tkwait\n    wait(false, true)\n  end\n  def thread_tkwait\n    wait(true, true)\n  end\n\n  def id\n    @id\n  end\n\n  def ref(*idxs)\n    # \"#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})\"\n    TkVarAccess.new(\"#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})\")\n  end\n\n  def is_hash?\n    #ITNERP._eval(\"global #{@id}; array exist #{@id}\") == '1'\n    INTERP._invoke_without_enc('global', @id)\n    # INTERP._invoke_without_enc('array', 'exist', @id) == '1'\n    TkComm.bool(INTERP._invoke_without_enc('array', 'exist', @id))\n  end\n\n  def is_scalar?\n    ! is_hash?\n  end\n\n  def exist?(*elems)\n    INTERP._invoke_without_enc('global', @id)\n    if elems.empty?\n      TkComm.bool(tk_call('info', 'exist', @id))\n    else\n      # array\n      index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',')\n      TkComm.bool(tk_call('info', 'exist', \"#{@id}\")) && \n        TkComm.bool(tk_call('info', 'exist', \"#{@id}(#{index})\"))\n    end\n  end\n\n  def keys\n    if (is_scalar?)\n      fail RuntimeError, 'cannot get keys from a scalar variable'\n    end\n    #tk_split_simplelist(INTERP._eval(\"global #{@id}; array get #{@id}\"))\n    INTERP._invoke_without_enc('global', @id)\n    #tk_split_simplelist(INTERP._fromUTF8(INTERP._invoke_without_enc('array', 'names', @id)))\n    tk_split_simplelist(INTERP._invoke_without_enc('array', 'names', @id), \n                        false, true)\n  end\n\n  def size\n    INTERP._invoke_without_enc('global', @id)\n    TkComm.number(INTERP._invoke_without_enc('array', 'size', @id))\n  end\n\n  def clear\n    if (is_scalar?)\n      fail RuntimeError, 'cannot clear a scalar variable'\n    end\n    keys.each{|k| unset(k)}\n    self\n  end\n\n  def update(hash)\n    if (is_scalar?)\n      fail RuntimeError, 'cannot update a scalar variable'\n    end\n    hash.each{|k,v| self[k] = v}\n    self\n  end\n\nunless const_defined?(:USE_TCLs_SET_VARIABLE_FUNCTIONS)\n  USE_TCLs_SET_VARIABLE_FUNCTIONS = true\nend\n\nif USE_TCLs_SET_VARIABLE_FUNCTIONS\n  ###########################################################################\n  # use Tcl function version of set tkvariable\n  ###########################################################################\n\n  def _value\n    #if INTERP._eval(\"global #{@id}; array exist #{@id}\") == '1'\n    INTERP._invoke_without_enc('global', @id)\n    # if INTERP._invoke('array', 'exist', @id) == '1'\n    if TkComm.bool(INTERP._invoke('array', 'exist', @id))\n      #Hash[*tk_split_simplelist(INTERP._eval(\"global #{@id}; array get #{@id}\"))]\n      Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', @id))]\n    else\n      _fromUTF8(INTERP._get_global_var(@id))\n    end\n  end\n\n  def value=(val)\n    val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable)\n    if val.kind_of?(Hash)\n      self.clear\n      val.each{|k, v|\n        #INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(k)), \n        #                       _toUTF8(_get_eval_string(v)))\n        INTERP._set_global_var2(@id, _get_eval_string(k, true), \n                                _get_eval_string(v, true))\n      }\n      self.value\n#    elsif val.kind_of?(Array)\n=begin\n      INTERP._set_global_var(@id, '')\n      val.each{|v|\n        #INTERP._set_variable(@id, _toUTF8(_get_eval_string(v)), \n        INTERP._set_variable(@id, _get_eval_string(v, true), \n                             TclTkLib::VarAccessFlag::GLOBAL_ONLY   | \n                             TclTkLib::VarAccessFlag::LEAVE_ERR_MSG |\n                             TclTkLib::VarAccessFlag::APPEND_VALUE  | \n                             TclTkLib::VarAccessFlag::LIST_ELEMENT)\n      }\n      self.value\n=end\n#      _fromUTF8(INTERP._set_global_var(@id, array2tk_list(val, true)))\n    else\n      #_fromUTF8(INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val))))\n      _fromUTF8(INTERP._set_global_var(@id, _get_eval_string(val, true)))\n    end\n  end\n\n  def _element_value(*idxs)\n    index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')\n    begin\n      _fromUTF8(INTERP._get_global_var2(@id, index))\n    rescue => e\n      case @def_default\n      when :proc\n        @default_val.call(self, *idxs)\n      when :val\n        @default_val\n      else\n        fail e\n      end\n    end\n    #_fromUTF8(INTERP._get_global_var2(@id, index))\n    #_fromUTF8(INTERP._get_global_var2(@id, _toUTF8(_get_eval_string(index))))\n    #_fromUTF8(INTERP._get_global_var2(@id, _get_eval_string(index, true)))\n  end\n\n  def []=(*args)\n    val = args.pop\n    type = default_element_value_type(args)\n    val = val._value if !type && type != :variable && val.kind_of?(TkVariable)\n    index = args.collect{|idx| _get_eval_string(idx, true)}.join(',')\n    _fromUTF8(INTERP._set_global_var2(@id, index, _get_eval_string(val, true)))\n    #_fromUTF8(INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(index)), \n    #                                 _toUTF8(_get_eval_string(val))))\n    #_fromUTF8(INTERP._set_global_var2(@id, _get_eval_string(index, true), \n    #                                 _get_eval_string(val, true)))\n  end\n\n  def unset(*elems)\n    if elems.empty?\n      INTERP._unset_global_var(@id)\n    else\n      index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',')\n      INTERP._unset_global_var2(@id, index)\n    end\n  end\n  alias remove unset\n\nelse\n  ###########################################################################\n  # use Ruby script version of set tkvariable (traditional methods)\n  ###########################################################################\n\n  def _value\n    begin\n      INTERP._eval(Kernel.format('global %s; set %s', @id, @id))\n      #INTERP._eval(Kernel.format('set %s', @id))\n      #INTERP._invoke_without_enc('set', @id)\n    rescue\n      if INTERP._eval(Kernel.format('global %s; array exists %s', \n                            @id, @id)) != \"1\"\n      #if INTERP._eval(Kernel.format('array exists %s', @id)) != \"1\"\n      #if INTERP._invoke_without_enc('array', 'exists', @id) != \"1\"\n        fail\n      else\n        Hash[*tk_split_simplelist(INTERP._eval(Kernel.format('global %s; array get %s', @id, @id)))]\n        #Hash[*tk_split_simplelist(_fromUTF8(INTERP._invoke_without_enc('array', 'get', @id)))]\n      end\n    end\n  end\n\n  def value=(val)\n    val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable)\n    begin\n      #s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n      s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n      INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))\n      #INTERP._eval(Kernel.format('set %s %s', @id, s))\n      #_fromUTF8(INTERP._invoke_without_enc('set', @id, _toUTF8(s)))\n    rescue\n      if INTERP._eval(Kernel.format('global %s; array exists %s', \n                            @id, @id)) != \"1\"\n      #if INTERP._eval(Kernel.format('array exists %s', @id)) != \"1\"\n      #if INTERP._invoke_without_enc('array', 'exists', @id) != \"1\"\n        fail\n      else\n        if val == []\n          INTERP._eval(Kernel.format('global %s; unset %s; set %s(0) 0; unset %s(0)', @id, @id, @id, @id))\n          #INTERP._eval(Kernel.format('unset %s; set %s(0) 0; unset %s(0)', \n          #                          @id, @id, @id))\n          #INTERP._invoke_without_enc('unset', @id)\n          #INTERP._invoke_without_enc('set', @id+'(0)', 0)\n          #INTERP._invoke_without_enc('unset', @id+'(0)')\n        elsif val.kind_of?(Array)\n          a = []\n          val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e, true))}\n          #s = '\"' + a.join(\" \").gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n          s = '\"' + a.join(\" \").gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"'\n          INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', \n                                     @id, @id, @id, s))\n          #INTERP._eval(Kernel.format('unset %s; array set %s %s', \n          #                          @id, @id, s))\n          #INTERP._invoke_without_enc('unset', @id)\n          #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s)))\n        elsif  val.kind_of?(Hash)\n          #s = '\"' + val.to_a.collect{|e| array2tk_list(e)}.join(\" \")\\\n          #                      .gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"'\n          s = '\"' + val.to_a.collect{|e| array2tk_list(e, true)}.join(\" \")\\\n                                .gsub(/[\\[\\]$\\\\\"]/, '\\\\\\\\\\&') + '\"'\n          INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s', \n                                     @id, @id, @id, s))\n          #INTERP._eval(Kernel.format('unset %s; array set %s %s', \n          #                          @id, @id, s))\n          #INTERP._invoke_without_enc('unset', @id)\n          #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s)))\n        else\n          fail\n        end\n      end\n    end\n  end\n\n  def _element_value(*idxs)\n    index = idxs.collect{|idx| _get_eval_string(idx)}.join(',')\n    begin\n      INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index))\n    rescue => e\n      case @def_default\n      when :proc\n        @default_val.call(self, *idxs)\n      when :val\n        @default_val\n      else\n        fail e\n      end\n    end\n    #INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index))\n    #INTERP._eval(Kernel.format('global %s; set %s(%s)', \n    #                           @id, @id, _get_eval_string(index)))\n    #INTERP._eval(Kernel.format('set %s(%s)', @id, _get_eval_string(index)))\n    #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ')')\n  end\n\n  def []=(*args)\n    val = args.pop\n    type = default_element_value_type(args)\n    val = val._value if !type && type != :variable && val.kind_of?(TkVariable)\n    index = args.collect{|idx| _get_eval_string(idx)}.join(',')\n    INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, \n                              index, _get_eval_string(val)))\n    #INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, \n    #                          _get_eval_string(index), _get_eval_string(val)))\n    #INTERP._eval(Kernel.format('set %s(%s) %s', @id, \n    #                          _get_eval_string(index), _get_eval_string(val)))\n    #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ') ' + \n    #            _get_eval_string(val))\n  end\n\n  def unset(*elems)\n    if elems.empty?\n      INTERP._eval(Kernel.format('global %s; unset %s', @id, @id))\n      #INTERP._eval(Kernel.format('unset %s', @id))\n      #INTERP._eval('unset ' + @id)\n    else\n      index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',')\n      INTERP._eval(Kernel.format('global %s; unset %s(%s)', @id, @id, index))\n      #INTERP._eval(Kernel.format('global %s; unset %s(%s)', \n      #                           @id, @id, _get_eval_string(elem)))\n      #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem)))\n      #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')')\n    end\n  end\n  alias remove unset\n\nend\n\n  protected :_value, :_element_value\n\n  def value\n    _to_default_type(_value)\n  end\n\n  def [](*idxs)\n    _to_default_element_type(idxs, _element_value(*idxs))\n  end\n\n  def set_value(val)\n    self.value = val\n    self\n  end\n\n  def set_element_value(idxs, val)\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n\n  def set_value_type(val)\n    self.default_value_type = val.class\n    self.value = val\n    self\n  end\n\n  alias value_type= set_value_type\n\n  def set_element_value_type(idxs, val)\n    self.set_default_element_value_type(idxs, val.class)\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n\n  def numeric\n    number(_value)\n  end\n  def numeric_element(*idxs)\n    number(_element_value(*idxs))\n  end\n  def set_numeric(val)\n    case val\n    when Numeric\n      self.value=(val)\n    when TkVariable\n      self.value=(val.numeric)\n    else\n      raise ArgumentError, \"Numeric is expected\"\n    end\n    self\n  end\n  alias numeric= set_numeric\n  def set_numeric_element(idxs, val)\n    case val\n    when Numeric\n      val\n    when TkVariable\n      val = val.numeric\n    else\n      raise ArgumentError, \"Numeric is expected\"\n    end\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n  def set_numeric_type(val)\n    @type = :numeric\n    self.numeric=(val)\n    self\n  end\n  alias numeric_type= set_numeric_type\n  def set_numeric_element_type(idxs, val)\n    self.set_default_element_value_type(idxs, :numeric)\n    self.set_numeric_element(idxs, val)\n  end\n\n  def bool\n    TkComm.bool(_value)\n=begin\n    # see Tcl_GetBoolean man-page\n    case _value.downcase\n    when '0', 'false', 'no', 'off'\n      false\n    else\n      true\n    end\n=end\n  end\n  def bool_element(*idxs)\n    TkComm.bool(_element_value(*idxs))\n  end\n  def set_bool(val)\n    if ! val\n      self.value = '0'\n    else\n      case val.to_s.downcase\n      when 'false', '0', 'no', 'off'\n        self.value = '0'\n      else\n        self.value = '1'\n      end\n    end\n    self\n  end\n  alias bool= set_bool\n  def set_bool_element(idxs, val)\n    if ! val\n      val = '0'\n    else\n      case val.to_s.downcase\n      when 'false', '0', 'no', 'off'\n        val = '0'\n      else\n        val = '1'\n      end\n    end\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n  def set_bool_type(val)\n    @type = :bool\n    self.bool=(val)\n    self\n  end\n  alias bool_type= set_bool_type\n  def set_bool_element_type(idxs, val)\n    self.set_default_element_value_type(idxs, :bool)\n    self.set_bool_element(idxs, val)\n  end\n\n  def variable\n    # keeps a Tcl's variable name\n    TkVarAccess.new(self._value)\n  end\n  def variable_element(*idxs)\n    TkVarAccess.new(_element_value(*idxs))\n  end\n  def set_variable(var)\n    var = var.id if var.kind_of?(TkVariable)\n    self.value = var\n    self\n  end\n  alias variable= set_variable\n  def set_variable_element(idxs, var)\n    var = var.id if var.kind_of?(TkVariable)\n    if idxs.kind_of?(Array)\n      self[*idxs]=var\n    else\n      self[idxs]=var\n    end\n    self\n  end\n  def set_variable_type(var)\n    @type = :variable\n    var = var.id if var.kind_of?(TkVariable)\n    self.value = var\n    self\n  end\n  alias variable_type= set_variable_type\n  def set_variable_element_type(idxs, var)\n    self.set_default_element_value_type(idxs, :variable)\n    self.set_variable_element(idxs, var)\n  end\n\n  def window\n    TkComm.window(self._value)\n  end\n  def window_element(*idxs)\n    TkComm.window(_element_value(*idxs))\n  end\n  def set_window(win)\n    win = win._value if win.kind_of?(TkVariable)\n    self.value = win\n    self\n  end\n  alias window= set_window\n  def set_window_element(idxs, win)\n    win = win._value if win.kind_of?(TkVariable)\n    if idxs.kind_of?(Array)\n      self[*idxs]=win\n    else\n      self[idxs]=win\n    end\n    self\n  end\n  def set_window_type(win)\n    @type = :window\n    self.window=(win)\n    self\n  end\n  alias window_type= set_window_type\n  def set_window_element_type(idxs, win)\n    self.set_default_element_value_type(idxs, :window)\n    self.set_window_element(idxs, win)\n  end\n\n  def procedure\n    TkComm.procedure(self._value)\n  end\n  def procedure_element(*idxs)\n    TkComm.procedure(_element_value(*idxs))\n  end\n  def set_procedure(cmd)\n    self.value = cmd\n    self\n  end\n  alias procedure= set_procedure\n  def set_procedure_element(idxs, cmd)\n    cmd = cmd._value if cmd.kind_of?(TkVariable)\n    if idxs.kind_of?(Array)\n      self[*idxs]=cmd\n    else\n      self[idxs]=cmd\n    end\n    self\n  end\n  def set_procedure_type(cmd)\n    @type = :procedure\n    self.procedure=(cmd)\n    self\n  end\n  alias procedure_type= set_procedure_type\n  def set_procedure_element_type(idxs, cmd)\n    self.set_default_element_value_type(idxs, :procedure)\n    self.set_proceure_element(idxs, cmd)\n  end\n\n  def to_i\n    number(_value).to_i\n  end\n  def element_to_i(*idxs)\n    number(_element_value(*idxs)).to_i\n  end\n\n  def to_f\n    number(_value).to_f\n  end\n  def element_to_f(*idxs)\n    number(_element_value(*idxs)).to_f\n  end\n\n  def to_s\n    #string(value).to_s\n    _value\n  end\n  alias string to_s\n  def element_to_s(*idxs)\n    _element_value(*idxs)\n  end\n  def string_element(*idxs)\n    _element_value(*idxs)\n  end\n  def set_string(val)\n    val = val._value if val.kind_of?(TkVariable)\n    self.value=val\n    self\n  end\n  alias string= set_string\n  def set_string_element(idxs, val)\n    val = val._value if val.kind_of?(TkVariable)\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n  def set_string_type(val)\n    @type = :string\n    self.string=(val)\n    self\n  end\n  alias string_type= set_string_type\n  def set_string_element_type(idxs, val)\n    self.set_default_element_value_type(idxs, :string)\n    self.set_string_element(idxs, val)\n  end\n\n  def to_sym\n    _value.intern\n  end\n  alias symbol to_sym\n  def element_to_sym(*idxs)\n    _element_value(*idxs).intern\n  end\n  alias symbol_element element_to_sym\n  def set_symbol(val)\n    val = val._value if val.kind_of?(TkVariable)\n    self.value=val\n    self\n  end\n  alias symbol= set_symbol\n  def set_symbol_element(idxs, val)\n    val = val._value if val.kind_of?(TkVariable)\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n  def set_symbol_type(val)\n    @type = :symbol\n    self.value=(val)\n    self\n  end\n  alias symbol_type= set_symbol_type\n  def set_symbol_element_type(idxs, val)\n    self.set_default_element_value_type(idxs, :symbol)\n    self.set_symbol_element(idxs, val)\n  end\n\n  def list\n    #tk_split_list(value)\n    tk_split_simplelist(_value)\n  end\n  alias to_a list\n  def list_element(*idxs)\n    tk_split_simplelist(_element_value(*idxs))\n  end\n  alias element_to_a list_element\n\n  def numlist\n    list.collect!{|val| number(val)}\n  end\n  def numlist_element(*idxs)\n    list_element(*idxs).collect!{|val| number(val)}\n  end\n\n  def set_list(val)\n    case val\n    when Array\n      self.value=(val)\n    when TkVariable\n      self.value=(val.list)\n    else\n      raise ArgumentError, \"Array is expected\"\n    end\n    self\n  end\n  alias list= set_list\n\n  alias set_numlist set_list\n  alias numlist= set_numlist\n\n  def set_list_element(idxs, val)\n    case val\n    when Array\n      val\n    when TkVariable\n      val = val.list\n    else\n      raise ArgumentError, \"Array is expected\"\n    end\n    if idxs.kind_of?(Array)\n      self[*idxs]=val\n    else\n      self[idxs]=val\n    end\n    self\n  end\n  alias set_numlist_element set_list_element\n\n  def set_list_type(val)\n    @type = :list\n    self.list=(val)\n    self\n  end\n  alias list_type= set_list_type\n  def set_list_element_type(idxs, val)\n    self.set_default_element_value_type(idxs, :list)\n    self.set_list_element(idxs, val)\n  end\n  def set_numlist_type(val)\n    @type = :numlist\n    self.numlist=(val)\n    self\n  end\n  alias numlist_type= set_numlist_type\n  def set_numlist_element_type(idxs, val)\n    self.set_default_element_value_type(idxs, :numlist)\n    self.set_numlist_element(idxs, val)\n  end\n\n  def lappend(*elems)\n    tk_call('lappend', @id, *elems)\n    self\n  end\n  def element_lappend(idxs, *elems)\n    if idxs.kind_of?(Array)\n      idxs = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')\n    end\n    tk_call('lappend', \"#{@id}(#{idxs})\", *elems)\n    self\n  end\n\n  def lindex(idx)\n    tk_call('lindex', self._value, idx)\n  end\n  alias lget lindex\n  def element_lindex(elem_idxs, idx)\n    if elem_idxs.kind_of?(Array)\n      val = _element_value(*elem_idxs)\n    else\n      val = _element_value(elem_idxs)\n    end\n    tk_call('lindex', val, idx)\n  end\n  alias element_lget element_lindex\n\n  def lget_i(idx)\n    number(lget(idx)).to_i\n  end\n  def element_lget_i(elem_idxs, idx)\n    number(element_lget(elem_idxs, idx)).to_i\n  end\n\n  def lget_f(idx)\n    number(lget(idx)).to_f\n  end\n  def element_lget_f(elem_idxs, idx)\n    number(element_lget(elem_idxs, idx)).to_f\n  end\n\n  def lset(idx, val)\n    tk_call('lset', @id, idx, val)\n    self\n  end\n  def element_lset(elem_idxs, idx, val)\n    if elem_idxs.kind_of?(Array)\n      idxs = elem_idxs.collect{|i| _get_eval_string(i, true)}.join(',')\n    end\n    tk_call('lset', \"#{@id}(#{idxs})\", idx, val)\n    self\n  end\n\n  def inspect\n    #Kernel.format \"#<TkVariable: %s>\", @id\n    '#<TkVariable: ' + @id + '>'\n  end\n\n  def coerce(other)\n    case other\n    when TkVariable\n      [other._value, self._value]\n    when String\n      [other, self.to_s]\n    when Symbol\n      [other, self.to_sym]\n    when Integer\n      [other, self.to_i]\n    when Float\n      [other, self.to_f]\n    when Array\n      [other, self.to_a]\n    else\n      [other, self._value]\n    end\n  end\n\n  def &(other)\n    if other.kind_of?(Array)\n      self.to_a & other.to_a\n    else\n      self.to_i & other.to_i\n    end\n  end\n  def |(other)\n    if other.kind_of?(Array)\n      self.to_a | other.to_a\n    else\n      self.to_i | other.to_i\n    end\n  end\n  def +(other)\n    case other\n    when Array\n      self.to_a + other\n    when String\n      self._value + other\n    else\n      begin\n        number(self._value) + other\n      rescue\n        self._value + other.to_s\n      end\n    end\n  end\n  def -(other)\n    if other.kind_of?(Array)\n      self.to_a - other\n    else\n      number(self._value) - other\n    end\n  end\n  def *(other)\n    num_or_str(self._value) * other.to_i\n    #begin\n    #  number(self._value) * other\n    #rescue\n    #  self._value * other\n    #end\n  end\n  def /(other)\n    number(self._value) / other\n  end\n  def %(other)\n    num_or_str(self._value) % other.to_i\n    #begin\n    #  number(self._value) % other\n    #rescue\n    #  self._value % other\n    #end\n  end\n  def **(other)\n    number(self._value) ** other\n  end\n  def =~(other)\n    self._value =~ other\n  end\n\n  def ==(other)\n    case other\n    when TkVariable\n      #self.equal?(other)\n      self._value == other._value\n    when String\n      self.to_s == other\n    when Symbol\n      self.to_sym == other\n    when Integer\n      self.to_i == other\n    when Float\n      self.to_f == other\n    when Array\n      self.to_a == other\n    when Hash\n      # false if self is not an assoc array\n      self._value == other\n    else\n      # false\n      self._value == _get_eval_string(other)\n    end\n  end\n\n  def zero?\n    numeric.zero?\n  end\n  def nonzero?\n    !(numeric.zero?)\n  end\n\n  def <=>(other)\n    if other.kind_of?(TkVariable)\n      begin\n        val = other.numeric\n        other = val\n      rescue\n        other = other._value\n      end\n    elsif other.kind_of?(Numeric)\n      begin\n        return self.numeric <=> other\n      rescue\n        return self._value <=> other.to_s\n      end\n    elsif other.kind_of?(Array)\n      return self.list <=> other\n    else\n      return self._value <=> other\n    end\n  end\n\n  def to_eval\n    @id\n  end\n\n  def trace_callback(elem, op)\n    if @trace_var.kind_of? Array\n      @trace_var.each{|m,e| e.call(self,elem,op) if m.index(op)}\n    end\n    if elem.kind_of?(String) && elem != ''\n      if @trace_elem.kind_of?(Hash) && @trace_elem[elem].kind_of?(Array)\n        @trace_elem[elem].each{|m,e| e.call(self,elem,op) if m.index(op)}\n      end\n    end\n  end\n\n  def _check_trace_opt(opts)\n    if opts.kind_of?(Array)\n      opt_str = opts.map{|s| s.to_s}.join(' ')\n    else\n      opt_str = opts.to_s\n    end\n\n    fail ArgumentError, 'null trace option' if opt_str.empty?\n\n    if opt_str =~ /[^arwu\\s]/\n      # new format (Tcl/Tk8.4+?)\n      if opts.kind_of?(Array)\n        opt_ary = opts.map{|opt| opt.to_s.strip}\n      else\n        opt_ary = opt_str.split(/\\s+|\\|/)\n        opt_ary.delete('')\n      end\n      if USE_OLD_TRACE_OPTION_STYLE\n        opt_ary.uniq.map{|opt|\n          case opt\n          when 'array'\n            'a'\n          when 'read'\n            'r'\n          when 'write'\n            'w'\n          when 'unset'\n            'u'\n          else\n            fail ArgumentError, \"unsupported trace option '#{opt}' on Tcl/Tk#{Tk::TCL_PATCHLEVEL}\"\n          end\n        }.join\n      else\n        opt_ary\n      end\n    else\n      # old format\n      opt_ary = opt_str.delete('^arwu').split(//).uniq\n      if USE_OLD_TRACE_OPTION_STYLE\n        opt_ary.join\n      else\n        opt_ary.map{|c|\n          case c\n          when 'a'\n            'array'\n          when 'r'\n            'read'\n          when 'w'\n            'write'\n          when 'u'\n            'unset'\n          end\n        }\n      end\n    end\n  end\n  private :_check_trace_opt\n\n  def trace(opts, cmd = Proc.new)\n    opts = _check_trace_opt(opts)\n    (@trace_var ||= []).unshift([opts,cmd])\n\n    if @trace_opts == nil\n      TkVar_CB_TBL[@id] = self\n      @trace_opts = opts\n      if USE_OLD_TRACE_OPTION_STYLE\n        Tk.tk_call_without_enc('trace', 'variable', \n                               @id, @trace_opts, 'rb_var ' << @id)\n      else\n        Tk.tk_call_without_enc('trace', 'add', 'variable', \n                               @id, @trace_opts, 'rb_var ' << @id)\n      end\n    else\n      newopts = @trace_opts.dup\n      if USE_OLD_TRACE_OPTION_STYLE\n        opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n        if newopts != @trace_opts\n          Tk.tk_call_without_enc('trace', 'vdelete', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n          @trace_opts.replace(newopts)\n          Tk.tk_call_without_enc('trace', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      else\n        newopts |= opts\n        unless (newopts - @trace_opts).empty?\n          Tk.tk_call_without_enc('trace', 'remove', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n          @trace_opts.replace(newopts)\n          Tk.tk_call_without_enc('trace', 'add', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      end\n    end\n\n    self\n  end\n\n  def trace_element(elem, opts, cmd = Proc.new)\n    if @elem\n      fail(RuntimeError, \n           \"invalid for a TkVariable which denotes an element of Tcl's array\")\n    end\n\n    opts = _check_trace_opt(opts)\n\n    ((@trace_elem ||= {})[elem] ||= []).unshift([opts,cmd])\n\n    if @trace_opts == nil\n      TkVar_CB_TBL[@id] = self\n      @trace_opts = opts\n      if USE_OLD_TRACE_OPTION_STYLE\n        Tk.tk_call_without_enc('trace', 'add', 'variable', \n                               @id, @trace_opts, 'rb_var ' << @id)\n      else\n        Tk.tk_call_without_enc('trace', 'variable', \n                               @id, @trace_opts, 'rb_var ' << @id)\n      end\n    else\n      newopts = @trace_opts.dup\n      if USE_OLD_TRACE_OPTION_STYLE\n        opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n        if newopts != @trace_opts\n          Tk.tk_call_without_enc('trace', 'vdelete', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n          @trace_opts.replace(newopts)\n          Tk.tk_call_without_enc('trace', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      else\n        newopts |= opts\n        unless (newopts - @trace_opts).empty?\n          Tk.tk_call_without_enc('trace', 'remove', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n          @trace_opts.replace(newopts)\n          Tk.tk_call_without_enc('trace', 'add', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      end\n    end\n\n    self\n  end\n\n  def trace_info\n    return [] unless @trace_var\n    @trace_var.dup\n  end\n  alias trace_vinfo trace_info\n\n  def trace_info_for_element(elem)\n    if @elem\n      fail(RuntimeError, \n           \"invalid for a TkVariable which denotes an element of Tcl's array\")\n    end\n    return [] unless @trace_elem\n    return [] unless @trace_elem[elem]\n    @trace_elem[elem].dup\n  end\n  alias trace_vinfo_for_element trace_info_for_element\n\n  def trace_remove(opts,cmd)\n    return self unless @trace_var.kind_of? Array\n\n    opts = _check_trace_opt(opts)\n\n    idx = -1\n    if USE_OLD_TRACE_OPTION_STYLE\n      newopts = ''\n      @trace_var.each_with_index{|e, i|\n        if idx < 0 && e[1] == cmd\n          diff = false\n          ['a', 'r', 'w', 'u'].each{|c|\n            break if (diff = e[0].index(c) ^ opts.index(c))\n          }\n          unless diff\n            #find\n            idx = i\n            next\n          end\n        end\n        e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n      }\n    else\n      newopts = []\n      @trace_var.each_with_index{|e, i|\n        if idx < 0 && e[1] == cmd && \n            e[0].size == opts.size && (e[0] - opts).empty?\n          # find\n          idx = i\n          next\n        end\n        newopts |= e[0]\n      }\n    end\n\n    if idx >= 0\n      @trace_var.delete_at(idx) \n    else\n      return self\n    end\n\n    (@trace_elem ||= {}).each{|elem|\n      @trace_elem[elem].each{|e|\n        if USE_OLD_TRACE_OPTION_STYLE\n          e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n        else\n          newopts |= e[0]\n        end\n      }\n    }\n\n    if USE_OLD_TRACE_OPTION_STYLE\n      diff = false\n      @trace_opts.each_byte{|c| break if (diff = ! newopts.index(c))}\n      if diff\n        Tk.tk_call_without_enc('trace', 'vdelete', \n                               @id, @trace_opts, 'rb_var ' << @id)\n        @trace_opts.replace(newopts)\n        unless @trace_opts.empty?\n          Tk.tk_call_without_enc('trace', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      end\n    else\n      unless (@trace_opts - newopts).empty?\n        Tk.tk_call_without_enc('trace', 'remove', 'variable', \n                               @id, @trace_opts, 'rb_var ' << @id)\n        @trace_opts.replace(newopts)\n        unless @trace_opts.empty?\n          Tk.tk_call_without_enc('trace', 'add', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      end\n    end\n\n    self\n  end\n  alias trace_delete  trace_remove\n  alias trace_vdelete trace_remove\n\n  def trace_remove_for_element(elem,opts,cmd)\n    if @elem\n      fail(RuntimeError, \n           \"invalid for a TkVariable which denotes an element of Tcl's array\")\n    end\n    return self unless @trace_elem.kind_of? Hash\n    return self unless @trace_elem[elem].kind_of? Array\n\n    opts = _check_trace_opt(opts)\n\n    idx = -1\n    if USE_OLD_TRACE_OPTION_STYLE\n      @trace_elem[elem].each_with_index{|e, i|\n        if idx < 0 && e[1] == cmd\n          diff = false\n          ['a', 'r', 'w', 'u'].each{|c|\n            break if (diff = e[0].index(c) ^ opts.index(c))\n          }\n          unless diff\n            #find\n            idx = i\n            next\n          end\n        end\n      }\n    else\n      @trace_elem[elem].each_with_index{|e, i|\n        if idx < 0 && e[1] == cmd && \n            e[0].size == opts.size && (e[0] - opts).empty?\n          # find\n          idx = i\n          next\n        end\n      }\n    end\n\n    if idx >= 0\n      @trace_elem[elem].delete_at(idx)\n    else\n      return self\n    end\n\n    if USE_OLD_TRACE_OPTION_STYLE\n      newopts = ''\n      @trace_var.each{|e| \n        e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n      }\n      @trace_elem.each{|elem|\n        @trace_elem[elem].each{|e|\n          e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n        }\n      }\n    else\n      newopts = []\n      @trace_var.each{|e|\n        newopts |= e[0]\n      }\n      @trace_elem.each{|elem|\n        @trace_elem[elem].each{|e|\n          e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}\n        }\n      }\n    end\n\n    if USE_OLD_TRACE_OPTION_STYLE\n      diff = false\n      @trace_opts.each_byte{|c| break if (diff = ! newopts.index(c))}\n      if diff\n        Tk.tk_call_without_enc('trace', 'vdelete', \n                               @id, @trace_opts, 'rb_var ' << @id)\n        @trace_opts.replace(newopts)\n        unless @trace_opts.empty?\n          Tk.tk_call_without_enc('trace', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      end\n    else\n      unless (@trace_opts - newopts).empty?\n        Tk.tk_call_without_enc('trace', 'remove', 'variable', \n                               @id, @trace_opts, 'rb_var ' << @id)\n        @trace_opts.replace(newopts)\n        unless @trace_opts.empty?\n          Tk.tk_call_without_enc('trace', 'add', 'variable', \n                                 @id, @trace_opts, 'rb_var ' << @id)\n        end\n      end\n    end\n\n    self\n  end\n  alias trace_delete_for_element  trace_remove_for_element\n  alias trace_vdelete_for_element trace_remove_for_element\nend\n\nclass TkVarAccess<TkVariable\n  def self.new(name, *args)\n    if name.kind_of?(TkVariable)\n      name.value = args[0] unless args.empty?\n      return name \n    end\n\n    name = name.to_s\n    v = nil\n    TkVar_ID_TBL.mutex.synchronize{\n      if v = TkVar_ID_TBL[name]\n        v.value = args[0] unless args.empty?\n        return v\n      else\n        (v = self.allocate).instance_eval{\n          @id = name\n          TkVar_ID_TBL[@id] = self\n          @var = @id\n        }\n      end\n    }\n\n    v.instance_eval{ initialize(name, *args) }\n    v\n  end\n\n  def self.new_hash(name, *args)\n    if name.kind_of?(TkVariable)\n      unless name.is_hash?\n        fail ArgumentError, \"already exist as a scalar variable\"\n      end\n      name.value = args[0] unless args.empty?\n      return name \n    end\n\n    name = name.to_s\n    v = nil\n    TkVar_ID_TBL.mutex.synchronize{\n      if v = TkVar_ID_TBL[name]\n        unless v.is_hash?\n          fail ArgumentError, \"already exist as a scalar variable\"\n        end\n        v.value = args[0] unless args.empty?\n        return v\n      else\n        (v = self.allocate).instance_eval{\n          @id = name\n          TkVar_ID_TBL[@id] = self\n          @var = @id\n        }\n      end\n    }\n\n    INTERP._invoke_without_enc('global', name)\n    if args.empty? && INTERP._invoke_without_enc('array', 'exist', name) == '0'\n      v.instance_eval{ initialize(name, {}) }  # force creating\n    else\n      v.instance_eval{ initialize(name, *args) }\n    end\n    v\n  end\n\n  def initialize(varname, val=nil)\n    # @id = varname\n    # TkVar_ID_TBL[@id] = self\n\n    # @var  = @id\n    @elem = nil\n\n    @def_default = false\n    @default_val = nil\n\n    @trace_var  = nil\n    @trace_elem = nil\n    @trace_opts = nil\n\n    @type = nil\n    var = self\n    @element_type = Hash.new{|k,v| var.default_value_type }\n\n    # is an element?\n    if @id =~ /^([^(]+)\\((.+)\\)$/\n      # is an element --> var == $1, elem == $2\n      @var  = $1\n      @elem = $2\n    end\n\n    # teach Tk-ip that @id is global var\n    INTERP._invoke_without_enc('global', @var)\n=begin\n    begin\n      INTERP._invoke_without_enc('global', @id)\n    rescue => e\n      if @id =~ /^(.+)\\([^()]+\\)$/\n        # is an element --> varname == $1\n        INTERP._invoke_without_enc('global', $1)\n      else\n        fail e\n      end\n    end\n=end\n\n    if val\n      if val.kind_of?(Hash)\n        # assoc-array variable\n        self[''] = 0\n        self.clear\n      end\n      #s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&') + '\"' #\"\n      #s = '\"' + _get_eval_string(val).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&') + '\"' #\"\n      #INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))\n      #INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val)))\n      self.value = val\n    end\n  end\nend\n\nmodule Tk\n  begin\n    INTERP._invoke_without_enc('global', 'auto_path')\n    auto_path = INTERP._invoke('set', 'auto_path')\n  rescue => e\n    begin\n      INTERP._invoke_without_enc('global', 'env')\n      auto_path = INTERP._invoke('set', 'env(TCLLIBPATH)')\n    rescue => e\n      auto_path = Tk::LIBRARY\n    end\n  end\n\n  AUTO_PATH = TkVarAccess.new('auto_path', auto_path)\n\n=begin\n  AUTO_OLDPATH = tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath'))\n  AUTO_OLDPATH.each{|s| s.freeze}\n  AUTO_OLDPATH.freeze\n=end\n\n  TCL_PACKAGE_PATH = TkVarAccess.new('tcl_pkgPath')\n  PACKAGE_PATH = TCL_PACKAGE_PATH\n\n  TCL_LIBRARY_PATH = TkVarAccess.new('tcl_libPath')\n  LIBRARY_PATH = TCL_LIBRARY_PATH\n\n  TCL_PRECISION = TkVarAccess.new('tcl_precision')\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/virtevent.rb",
    "content": "#\n#   tk/virtevent.rb : treats virtual events\n#                     1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\nrequire 'tk'\n\nclass TkVirtualEvent<TkObject\n  extend Tk\n\n  TkCommandNames = ['event'.freeze].freeze\n\n  (TkVirtualEventID = [\"VirtEvent\".freeze, \"00000\".taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkVirtualEventTBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    TkVirtualEventTBL.mutex.synchronize{ TkVirtualEventTBL.clear }\n  }\n\n  class PreDefVirtEvent<self\n    def self.new(event, *sequences)\n      if event =~ /^<(<.*>)>$/\n        event = $1\n      elsif event !~ /^<.*>$/\n        event = '<' + event + '>'\n      end\n      TkVirtualEvent::TkVirtualEventTBL.mutex.synchronize{\n        if TkVirtualEvent::TkVirtualEventTBL.has_key?(event)\n          TkVirtualEvent::TkVirtualEventTBL[event]\n        else\n          # super(event, *sequences)\n          (obj = self.allocate).instance_eval{\n            initialize(event, *sequences)\n            TkVirtualEvent::TkVirtualEventTBL[@id] = self\n          }\n        end\n      }\n    end\n\n    def initialize(event, *sequences)\n      @path = @id = event\n      _add_sequences(sequences)\n    end\n  end\n\n  def TkVirtualEvent.getobj(event)\n    obj = nil\n    TkVirtualEventTBL.mutex.synchronize{\n      obj = TkVirtualEventTBL[event]\n    }\n    if obj\n      obj\n    else\n      if tk_call_without_enc('event', 'info').index(\"<#{event}>\")\n        PreDefVirtEvent.new(event)\n      else\n        fail ArgumentError, \"undefined virtual event '<#{event}>'\"\n      end\n    end\n  end\n\n  def TkVirtualEvent.info\n    tk_call_without_enc('event', 'info').split(/\\s+/).collect!{|seq|\n      TkVirtualEvent.getobj(seq[1..-2])\n    }\n  end\n\n  def initialize(*sequences)\n    TkVirtualEventID.mutex.synchronize{\n      # @path = @id = '<' + TkVirtualEventID.join('') + '>'\n      @path = @id = '<' + TkVirtualEventID.join(TkCore::INTERP._ip_id_) + '>'\n      TkVirtualEventID[1].succ!\n    }\n    _add_sequences(sequences)\n  end\n\n  def _add_sequences(seq_ary)\n    unless seq_ary.empty?\n      tk_call_without_enc('event', 'add', \"<#{@id}>\", \n                          *(seq_ary.collect{|seq| \n                              \"<#{tk_event_sequence(seq)}>\"\n                            }) )\n    end\n    self\n  end\n  private :_add_sequences\n\n  def add(*sequences)\n    if sequences != []\n      _add_sequences(sequences)\n      TkVirtualEventTBL.mutex.synchronize{\n        TkVirtualEventTBL[@id] = self\n      }\n    end\n    self\n  end\n\n  def delete(*sequences)\n    if sequences == []\n      tk_call_without_enc('event', 'delete', \"<#{@id}>\")\n      TkVirtualEventTBL.mutex.synchronize{\n        TkVirtualEventTBL.delete(@id)\n      }\n    else\n      tk_call_without_enc('event', 'delete', \"<#{@id}>\", \n                          *(sequences.collect{|seq| \n                              \"<#{tk_event_sequence(seq)}>\"\n                            }) )\n      if tk_call_without_enc('event','info',\"<#{@id}>\").empty?\n        TkVirtualEventTBL.mutex.synchronize{\n          TkVirtualEventTBL.delete(@id)\n        }\n      end\n    end\n    self\n  end\n\n  def info\n    tk_call_without_enc('event','info',\"<#{@id}>\").split(/\\s+/).collect!{|seq|\n      lst = seq.scan(/<*[^<>]+>*/).collect!{|subseq|\n        case (subseq)\n        when /^<<[^<>]+>>$/\n          TkVirtualEvent.getobj(subseq[1..-2])\n        when /^<[^<>]+>$/\n          subseq[1..-2]\n        else\n          subseq.split('')\n        end\n      }.flatten\n      (lst.size == 1) ? lst[0] : lst\n    }\n  end\nend\n\nTkNamedVirtualEvent = TkVirtualEvent::PreDefVirtEvent\n"
  },
  {
    "path": "ext/tk/lib/tk/winfo.rb",
    "content": "#\n# tk/winfo.rb : methods for winfo command\n#\nmodule TkWinfo\nend\n\nrequire 'tk'\n\nmodule TkWinfo\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['winfo'.freeze].freeze\n\n  def TkWinfo.atom(name, win=nil)\n    if win\n      number(tk_call_without_enc('winfo', 'atom', '-displayof', win, \n                                 _get_eval_enc_str(name)))\n    else\n      number(tk_call_without_enc('winfo', 'atom', _get_eval_enc_str(name)))\n    end\n  end\n  def winfo_atom(name)\n    TkWinfo.atom(name, self)\n  end\n\n  def TkWinfo.atomname(id, win=nil)\n    if win\n      _fromUTF8(tk_call_without_enc('winfo', 'atomname', \n                                    '-displayof', win, id))\n    else\n      _fromUTF8(tk_call_without_enc('winfo', 'atomname', id))\n    end\n  end\n  def winfo_atomname(id)\n    TkWinfo.atomname(id, self)\n  end\n\n  def TkWinfo.cells(win)\n    number(tk_call_without_enc('winfo', 'cells', win))\n  end\n  def winfo_cells\n    TkWinfo.cells self\n  end\n\n  def TkWinfo.children(win)\n    list(tk_call_without_enc('winfo', 'children', win))\n  end\n  def winfo_children\n    TkWinfo.children self\n  end\n\n  def TkWinfo.classname(win)\n    tk_call_without_enc('winfo', 'class', win)\n  end\n  def winfo_classname\n    TkWinfo.classname self\n  end\n  alias winfo_class winfo_classname\n\n  def TkWinfo.colormapfull(win)\n     bool(tk_call_without_enc('winfo', 'colormapfull', win))\n  end\n  def winfo_colormapfull\n    TkWinfo.colormapfull self\n  end\n\n  def TkWinfo.containing(rootX, rootY, win=nil)\n    if win\n      window(tk_call_without_enc('winfo', 'containing', \n                                 '-displayof', win, rootX, rootY))\n    else\n      window(tk_call_without_enc('winfo', 'containing', rootX, rootY))\n    end\n  end\n  def winfo_containing(x, y)\n    TkWinfo.containing(x, y, self)\n  end\n\n  def TkWinfo.depth(win)\n    number(tk_call_without_enc('winfo', 'depth', win))\n  end\n  def winfo_depth\n    TkWinfo.depth self\n  end\n\n  def TkWinfo.exist?(win)\n    bool(tk_call_without_enc('winfo', 'exists', win))\n  end\n  def winfo_exist?\n    TkWinfo.exist? self\n  end\n\n  def TkWinfo.fpixels(win, dist)\n    number(tk_call_without_enc('winfo', 'fpixels', win, dist))\n  end\n  def winfo_fpixels(dist)\n    TkWinfo.fpixels self, dist\n  end\n\n  def TkWinfo.geometry(win)\n    tk_call_without_enc('winfo', 'geometry', win)\n  end\n  def winfo_geometry\n    TkWinfo.geometry self\n  end\n\n  def TkWinfo.height(win)\n    number(tk_call_without_enc('winfo', 'height', win))\n  end\n  def winfo_height\n    TkWinfo.height self\n  end\n\n  def TkWinfo.id(win)\n    tk_call_without_enc('winfo', 'id', win)\n  end\n  def winfo_id\n    TkWinfo.id self\n  end\n\n  def TkWinfo.interps(win=nil)\n    if win\n      #tk_split_simplelist(tk_call_without_enc('winfo', 'interps',\n      #                                        '-displayof', win))\n      tk_split_simplelist(tk_call_without_enc('winfo', 'interps',\n                                              '-displayof', win),\n                          false, true)\n    else\n      #tk_split_simplelist(tk_call_without_enc('winfo', 'interps'))\n      tk_split_simplelist(tk_call_without_enc('winfo', 'interps'), \n                          false, true)\n    end\n  end\n  def winfo_interps\n    TkWinfo.interps self\n  end\n\n  def TkWinfo.mapped?(win)\n    bool(tk_call_without_enc('winfo', 'ismapped', win))\n  end\n  def winfo_mapped?\n    TkWinfo.mapped? self\n  end\n\n  def TkWinfo.manager(win)\n    tk_call_without_enc('winfo', 'manager', win)\n  end\n  def winfo_manager\n    TkWinfo.manager self\n  end\n\n  def TkWinfo.appname(win)\n    tk_call('winfo', 'name', win)\n  end\n  def winfo_appname\n    TkWinfo.appname self\n  end\n\n  def TkWinfo.parent(win)\n    window(tk_call_without_enc('winfo', 'parent', win))\n  end\n  def winfo_parent\n    TkWinfo.parent self\n  end\n\n  def TkWinfo.widget(id, win=nil)\n    if win\n      window(tk_call_without_enc('winfo', 'pathname', '-displayof', win, id))\n    else\n      window(tk_call_without_enc('winfo', 'pathname', id))\n    end\n  end\n  def winfo_widget(id)\n    TkWinfo.widget id, self\n  end\n\n  def TkWinfo.pixels(win, dist)\n    number(tk_call_without_enc('winfo', 'pixels', win, dist))\n  end\n  def winfo_pixels(dist)\n    TkWinfo.pixels self, dist\n  end\n\n  def TkWinfo.reqheight(win)\n    number(tk_call_without_enc('winfo', 'reqheight', win))\n  end\n  def winfo_reqheight\n    TkWinfo.reqheight self\n  end\n\n  def TkWinfo.reqwidth(win)\n    number(tk_call_without_enc('winfo', 'reqwidth', win))\n  end\n  def winfo_reqwidth\n    TkWinfo.reqwidth self\n  end\n\n  def TkWinfo.rgb(win, color)\n    list(tk_call_without_enc('winfo', 'rgb', win, color))\n  end\n  def winfo_rgb(color)\n    TkWinfo.rgb self, color\n  end\n\n  def TkWinfo.rootx(win)\n    number(tk_call_without_enc('winfo', 'rootx', win))\n  end\n  def winfo_rootx\n    TkWinfo.rootx self\n  end\n\n  def TkWinfo.rooty(win)\n    number(tk_call_without_enc('winfo', 'rooty', win))\n  end\n  def winfo_rooty\n    TkWinfo.rooty self\n  end\n\n  def TkWinfo.screen(win)\n    tk_call('winfo', 'screen', win)\n  end\n  def winfo_screen\n    TkWinfo.screen self\n  end\n\n  def TkWinfo.screencells(win)\n    number(tk_call_without_enc('winfo', 'screencells', win))\n  end\n  def winfo_screencells\n    TkWinfo.screencells self\n  end\n\n  def TkWinfo.screendepth(win)\n    number(tk_call_without_enc('winfo', 'screendepth', win))\n  end\n  def winfo_screendepth\n    TkWinfo.screendepth self\n  end\n\n  def TkWinfo.screenheight (win)\n    number(tk_call_without_enc('winfo', 'screenheight', win))\n  end\n  def winfo_screenheight\n    TkWinfo.screenheight self\n  end\n\n  def TkWinfo.screenmmheight(win)\n    number(tk_call_without_enc('winfo', 'screenmmheight', win))\n  end\n  def winfo_screenmmheight\n    TkWinfo.screenmmheight self\n  end\n\n  def TkWinfo.screenmmwidth(win)\n    number(tk_call_without_enc('winfo', 'screenmmwidth', win))\n  end\n  def winfo_screenmmwidth\n    TkWinfo.screenmmwidth self\n  end\n\n  def TkWinfo.screenvisual(win)\n    tk_call_without_enc('winfo', 'screenvisual', win)\n  end\n  def winfo_screenvisual\n    TkWinfo.screenvisual self\n  end\n\n  def TkWinfo.screenwidth(win)\n    number(tk_call_without_enc('winfo', 'screenwidth', win))\n  end\n  def winfo_screenwidth\n    TkWinfo.screenwidth self\n  end\n\n  def TkWinfo.server(win)\n    tk_call('winfo', 'server', win)\n  end\n  def winfo_server\n    TkWinfo.server self\n  end\n\n  def TkWinfo.toplevel(win)\n    window(tk_call_without_enc('winfo', 'toplevel', win))\n  end\n  def winfo_toplevel\n    TkWinfo.toplevel self\n  end\n\n  def TkWinfo.visual(win)\n    tk_call_without_enc('winfo', 'visual', win)\n  end\n  def winfo_visual\n    TkWinfo.visual self\n  end\n\n  def TkWinfo.visualid(win)\n    tk_call_without_enc('winfo', 'visualid', win)\n  end\n  def winfo_visualid\n    TkWinfo.visualid self\n  end\n\n  def TkWinfo.visualsavailable(win, includeids=false)\n    if includeids\n      list(tk_call_without_enc('winfo', 'visualsavailable', \n                               win, \"includeids\"))\n    else\n      list(tk_call_without_enc('winfo', 'visualsavailable', win))\n    end\n  end\n  def winfo_visualsavailable(includeids=false)\n    TkWinfo.visualsavailable self, includeids\n  end\n\n  def TkWinfo.vrootheight(win)\n    number(tk_call_without_enc('winfo', 'vrootheight', win))\n  end\n  def winfo_vrootheight\n    TkWinfo.vrootheight self\n  end\n\n  def TkWinfo.vrootwidth(win)\n    number(tk_call_without_enc('winfo', 'vrootwidth', win))\n  end\n  def winfo_vrootwidth\n    TkWinfo.vrootwidth self\n  end\n\n  def TkWinfo.vrootx(win)\n    number(tk_call_without_enc('winfo', 'vrootx', win))\n  end\n  def winfo_vrootx\n    TkWinfo.vrootx self\n  end\n\n  def TkWinfo.vrooty(win)\n    number(tk_call_without_enc('winfo', 'vrooty', win))\n  end\n  def winfo_vrooty\n    TkWinfo.vrooty self\n  end\n\n  def TkWinfo.width(win)\n    number(tk_call_without_enc('winfo', 'width', win))\n  end\n  def winfo_width\n    TkWinfo.width self\n  end\n\n  def TkWinfo.x(win)\n    number(tk_call_without_enc('winfo', 'x', win))\n  end\n  def winfo_x\n    TkWinfo.x self\n  end\n\n  def TkWinfo.y(win)\n    number(tk_call_without_enc('winfo', 'y', win))\n  end\n  def winfo_y\n    TkWinfo.y self\n  end\n\n  def TkWinfo.viewable(win)\n    bool(tk_call_without_enc('winfo', 'viewable', win))\n  end\n  def winfo_viewable\n    TkWinfo.viewable self\n  end\n\n  def TkWinfo.pointerx(win)\n    number(tk_call_without_enc('winfo', 'pointerx', win))\n  end\n  def winfo_pointerx\n    TkWinfo.pointerx self\n  end\n\n  def TkWinfo.pointery(win)\n    number(tk_call_without_enc('winfo', 'pointery', win))\n  end\n  def winfo_pointery\n    TkWinfo.pointery self\n  end\n\n  def TkWinfo.pointerxy(win)\n    list(tk_call_without_enc('winfo', 'pointerxy', win))\n  end\n  def winfo_pointerxy\n    TkWinfo.pointerxy self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/winpkg.rb",
    "content": "#\n#   tk/winpkg.rb : methods for Tcl/Tk packages for Microsoft Windows\n#                     2000/11/22 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>\n#\n#     ATTENTION !!\n#         This is NOT TESTED. Because I have no test-environment.\n#\nrequire 'tk'\n\nmodule Tk::WinDDE\nend\n#TkWinDDE = Tk::WinDDE\nTk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)\n\nmodule Tk::WinDDE\n  extend Tk\n  extend Tk::WinDDE\n\n  TkCommandNames = ['dde'.freeze].freeze\n\n  PACKAGE_NAME = 'dde'.freeze\n  def self.package_name\n    PACKAGE_NAME\n  end\n\n  if self.const_defined? :FORCE_VERSION\n    tk_call_without_enc('package', 'require', 'dde', FORCE_VERSION)\n  else\n    tk_call_without_enc('package', 'require', 'dde')\n  end\n\n  #def servername(topic=None)\n  #  tk_call('dde', 'servername', topic)\n  #end\n  def servername(*args)\n    if args.size == 0\n      tk_call('dde', 'servername')\n    else\n      if args[-1].kind_of?(Hash)  # dde 1.2 +\n        keys = _symbolkey2str(args.pop)\n        force = (keys.delete('force'))? '-force': None\n        exact = (keys.delete('exact'))? '-exact': None\n        if keys.size == 0\n          tk_call('dde', 'servername', force, exact)\n        elsif args.size == 0\n          tk_call('dde', 'servername', force, exact, *hash_kv(keys))\n        else\n          tk_call('dde', 'servername', force, exact, \n                  *((hash_kv(keys) << '--') + args))\n        end\n      else\n        tk_call('dde', 'servername', *args)\n      end\n    end\n  end\n\n  def execute(service, topic, data)\n    tk_call('dde', 'execute', service, topic, data)\n  end\n\n  def async_execute(service, topic, data)\n    tk_call('dde', '-async', 'execute', service, topic, data)\n  end\n\n  def poke(service, topic, item, data)\n    tk_call('dde', 'poke', service, topic, item, data)\n  end\n\n  def request(service, topic, item)\n    tk_call('dde', 'request', service, topic, item)\n  end\n\n  def binary_request(service, topic, item)\n    tk_call('dde', 'request', '-binary', service, topic, item)\n  end\n\n  def services(service, topic)\n    tk_call('dde', 'services', service, topic)\n  end\n\n  def eval(topic, cmd, *args)\n    tk_call('dde', 'eval', topic, cmd, *args)\n  end\n\n  def async_eval(topic, cmd, *args)\n    tk_call('dde', 'eval', -async, topic, cmd, *args)\n  end\n\n  module_function :servername, :execute, :async_execute, \n                  :poke, :request, :services, :eval\nend\n\nmodule Tk::WinRegistry\nend\n#TkWinRegistry = Tk::WinRegistry\nTk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)\n\nmodule Tk::WinRegistry\n  extend Tk\n  extend Tk::WinRegistry\n\n  TkCommandNames = ['registry'.freeze].freeze\n\n  if self.const_defined? :FORCE_VERSION\n    tk_call('package', 'require', 'registry', FORCE_VERSION)\n  else\n    tk_call('package', 'require', 'registry')\n  end\n\n  def broadcast(keynam, timeout=nil)\n    if timeout\n      tk_call('registry', 'broadcast', keynam, '-timeout', timeout)\n    else\n      tk_call('registry', 'broadcast', keynam)\n    end\n  end\n\n  def delete(keynam, valnam=None)\n    tk_call('registry', 'delete', keynam, valnam)\n  end\n\n  def get(keynam, valnam)\n    tk_call('registry', 'get', keynam, valnam)\n  end\n\n  def keys(keynam, pattern=nil)\n    lst = tk_split_simplelist(tk_call('registry', 'keys', keynam))\n    if pattern\n      lst.find_all{|key| key =~ pattern}\n    else\n      lst\n    end\n  end\n\n  def set(keynam, valnam=None, data=None, dattype=None)\n    tk_call('registry', 'set', keynam, valnam, data, dattype)\n  end\n\n  def type(keynam, valnam)\n    tk_call('registry', 'type', keynam, valnam)\n  end\n\n  def values(keynam, pattern=nil)\n    lst = tk_split_simplelist(tk_call('registry', 'values', keynam))\n    if pattern\n      lst.find_all{|val| val =~ pattern}\n    else\n      lst\n    end\n  end\n\n  module_function :delete, :get, :keys, :set, :type, :values\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/wm.rb",
    "content": "#\n# tk/wm.rb : methods for wm command\n#\nrequire 'tk'\n\nmodule Tk\n  module Wm\n    #include TkComm\n    extend TkCore\n\n    TkCommandNames = ['wm'.freeze].freeze\n\n    TOPLEVEL_METHODCALL_OPTKEYS = {}\n\n    def Wm.aspect(win, *args)\n      if args.length == 0\n        list(tk_call_without_enc('wm', 'aspect', win.epath))\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call('wm', 'aspect', win.epath, *args)\n        win\n      end\n    end\n    def aspect(*args)\n      Wm.aspect(self, *args)\n    end\n    alias wm_aspect aspect\n    TOPLEVEL_METHODCALL_OPTKEYS['aspect'] = 'aspect'\n\n    def Wm.attributes(win, slot=nil,value=TkComm::None)\n      if slot == nil\n        lst = tk_split_list(tk_call('wm', 'attributes', win.epath))\n        info = {}\n        while key = lst.shift\n          info[key[1..-1]] = lst.shift\n        end\n        info\n      elsif slot.kind_of? Hash\n        tk_call('wm', 'attributes', win.epath, *hash_kv(slot))\n        win\n      elsif value == TkComm::None\n        tk_call('wm', 'attributes', win.epath, \"-#{slot}\")\n      else\n        tk_call('wm', 'attributes', win.epath, \"-#{slot}\", value)\n        win\n      end\n    end\n    def attributes(slot=nil,value=TkComm::None)\n      Wm.attributes(self, slot, value)\n    end\n    alias wm_attributes attributes\n    TOPLEVEL_METHODCALL_OPTKEYS['attributes'] = 'attributes'\n\n    def Wm.client(win, name=TkComm::None)\n      if name == TkComm::None\n        tk_call('wm', 'client', win.epath)\n      else\n        name = '' if name == nil\n        tk_call('wm', 'client', win.epath, name)\n        win\n      end\n    end\n    def client(name=TkComm::None)\n      Wm.client(self, name)\n    end\n    alias wm_client client\n    TOPLEVEL_METHODCALL_OPTKEYS['client'] = 'client'\n\n    def Wm.colormapwindows(win, *args)\n      if args.size == 0\n        list(tk_call_without_enc('wm', 'colormapwindows', win.epath))\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call_without_enc('wm', 'colormapwindows', win.epath, *args)\n        win\n      end\n    end\n    def colormapwindows(*args)\n      Wm.colormapwindows(self, *args)\n    end\n    alias wm_colormapwindows colormapwindows\n    TOPLEVEL_METHODCALL_OPTKEYS['colormapwindows'] = 'colormapwindows'\n\n    def Wm.command(win, value=nil)\n      if value\n        tk_call('wm', 'command', epath, value)\n        win\n      else\n        #procedure(tk_call('wm', 'command', epath))\n        tk_call('wm', 'command', epath)\n      end\n    end\n    def wm_command(value=nil)\n      Wm.command(self, value)\n    end\n    TOPLEVEL_METHODCALL_OPTKEYS['wm_command'] = 'wm_command'\n\n    def Wm.deiconify(win, ex = true)\n      if ex\n        tk_call_without_enc('wm', 'deiconify', win.epath)\n      else\n        Wm.iconify(win)\n      end\n      win\n    end\n    def deiconify(ex = true)\n      Wm.deiconify(self, ex)\n    end\n    alias wm_deiconify deiconify\n\n    def Wm.focusmodel(win, mode = nil)\n      if mode\n        tk_call_without_enc('wm', 'focusmodel', win.epath, mode)\n        win\n      else\n        tk_call_without_enc('wm', 'focusmodel', win.epath)\n      end\n    end\n    def focusmodel(mode = nil)\n      Wm.focusmodel(self, mode)\n    end\n    alias wm_focusmodel focusmodel\n    TOPLEVEL_METHODCALL_OPTKEYS['focusmodel'] = 'focusmodel'\n\n    def Wm.forget(win)\n      # Tcl/Tk 8.5+ \n      # work with dockable frames\n      tk_call_without_enc('wm', 'forget', win.epath)\n      win\n    end\n    def wm_forget\n      Wm.forget(self)\n    end\n\n    def Wm.frame(win)\n      tk_call_without_enc('wm', 'frame', win.epath)\n    end\n    def frame\n      Wm.frame(self)\n    end\n    alias wm_frame frame\n\n    def Wm.geometry(win, geom=nil)\n      if geom\n        tk_call_without_enc('wm', 'geometry', win.epath, geom)\n        win\n      else\n        tk_call_without_enc('wm', 'geometry', win.epath)\n      end\n    end\n    def geometry(geom=nil)\n      Wm.geometry(self, geom)\n    end\n    alias wm_geometry geometry\n    TOPLEVEL_METHODCALL_OPTKEYS['geometry'] = 'geometry'\n\n    def Wm.grid(win, *args)\n      if args.size == 0\n        list(tk_call_without_enc('wm', 'grid', win.epath))\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call_without_enc('wm', 'grid', win.epath, *args)\n        win\n      end\n    end\n    def wm_grid(*args)\n      Wm.grid(self, *args)\n    end\n    TOPLEVEL_METHODCALL_OPTKEYS['wm_grid'] = 'wm_grid'\n\n    def Wm.group(win, leader = nil)\n      if leader\n        tk_call('wm', 'group', win.epath, leader)\n        win\n      else\n        window(tk_call('wm', 'group', win.epath))\n      end\n    end\n    def group(leader = nil)\n      Wm.group(self, leader)\n    end\n    alias wm_group group\n    TOPLEVEL_METHODCALL_OPTKEYS['group'] = 'group'\n\n    def Wm.iconbitmap(win, bmp=nil)\n      if bmp\n        tk_call_without_enc('wm', 'iconbitmap', win.epath, bmp)\n        win\n      else\n        image_obj(tk_call_without_enc('wm', 'iconbitmap', win.epath))\n      end\n    end\n    def iconbitmap(bmp=nil)\n      Wm.iconbitmap(self, bmp)\n    end\n    alias wm_iconbitmap iconbitmap\n    TOPLEVEL_METHODCALL_OPTKEYS['iconbitmap'] = 'iconbitmap'\n\n    def Wm.iconphoto(win, *imgs)\n      if imgs.empty?\n        win.instance_eval{\n          @wm_iconphoto = nil unless defined? @wm_iconphoto\n          return @wm_iconphoto \n        }\n      end\n\n      imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array)\n      tk_call_without_enc('wm', 'iconphoto', win.epath, *imgs)\n      win.instance_eval{ @wm_iconphoto = imgs  }\n      win\n    end\n    def iconphoto(*imgs)\n      Wm.iconphoto(self, *imgs)\n    end\n    alias wm_iconphoto iconphoto\n    TOPLEVEL_METHODCALL_OPTKEYS['iconphoto'] = 'iconphoto'\n\n    def Wm.iconphoto_default(win, *imgs)\n      imgs = imgs[0] if imgs.length == 1 && imgs[0].kind_of?(Array)\n      tk_call_without_enc('wm', 'iconphoto', win.epath, '-default', *imgs)\n      win\n    end\n    def iconphoto_default(*imgs)\n      Wm.iconphoto_default(self, *imgs)\n    end\n    alias wm_iconphoto_default iconphoto_default\n\n    def Wm.iconify(win, ex = true)\n      if ex\n        tk_call_without_enc('wm', 'iconify', win.epath)\n      else\n        Wm.deiconify(win)\n      end\n      win\n    end\n    def iconify(ex = true)\n      Wm.iconify(self, ex)\n    end\n    alias wm_iconify iconify\n\n    def Wm.iconmask(win, bmp=nil)\n      if bmp\n        tk_call_without_enc('wm', 'iconmask', win.epath, bmp)\n        win\n      else\n        image_obj(tk_call_without_enc('wm', 'iconmask', win.epath))\n      end\n    end\n    def iconmask(bmp=nil)\n      Wm.iconmask(self, bmp)\n    end\n    alias wm_iconmask iconmask\n    TOPLEVEL_METHODCALL_OPTKEYS['iconmask'] = 'iconmask'\n\n    def Wm.iconname(win, name=nil)\n      if name\n        tk_call('wm', 'iconname', win.epath, name)\n        win\n      else\n        tk_call('wm', 'iconname', win.epath)\n      end\n    end\n    def iconname(name=nil)\n      Wm.iconname(self, name)\n    end\n    alias wm_iconname iconname\n    TOPLEVEL_METHODCALL_OPTKEYS['iconname'] = 'iconname'\n\n    def Wm.iconposition(win, *args)\n      if args.size == 0\n        list(tk_call_without_enc('wm', 'iconposition', win.epath))\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call_without_enc('wm', 'iconposition', win.epath, *args)\n        win\n      end\n    end\n    def iconposition(*args)\n      Wm.iconposition(self, *args)\n    end\n    alias wm_iconposition iconposition\n    TOPLEVEL_METHODCALL_OPTKEYS['iconposition'] = 'iconposition'\n\n    def Wm.iconwindow(win, iconwin = nil)\n      if iconwin\n        tk_call_without_enc('wm', 'iconwindow', win.epath, iconwin)\n        win\n      else\n        w = tk_call_without_enc('wm', 'iconwindow', win.epath)\n        (w == '')? nil: window(w)\n      end\n    end\n    def iconwindow(iconwin = nil)\n      Wm.iconwindow(self, iconwin)\n    end\n    alias wm_iconwindow iconwindow\n    TOPLEVEL_METHODCALL_OPTKEYS['iconwindow'] = 'iconwindow'\n\n    def Wm.manage(win)\n      # Tcl/Tk 8.5+ feature\n      tk_call_without_enc('wm', 'manage', win.epath)\n      win\n    end\n    def wm_manage\n      Wm.manage(self)\n    end\n=begin\n    def Wm.manage(win, use_id = nil)\n      # Tcl/Tk 8.5+ feature\n      # --------------------------------------------------------------\n      # In the future release, I want to support to embed the 'win' \n      # into the container which has window-id 'use-id'.\n      # It may give users frexibility on controlling their GUI. \n      # However, it may be difficult for current Tcl/Tk (Tcl/Tk8.5.1), \n      # because it seems to require to modify Tcl/Tk's source code.\n      # --------------------------------------------------------------\n      if use_id\n        tk_call_without_enc('wm', 'manage', win.epath, '-use', use_id)\n      else\n        tk_call_without_enc('wm', 'manage', win.epath)\n      end\n      win\n    end\n=end\n\n    def Wm.maxsize(win, *args)\n      if args.size == 0\n        list(tk_call_without_enc('wm', 'maxsize', win.epath))\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call_without_enc('wm', 'maxsize', win.epath, *args)\n        win\n      end\n    end\n    def maxsize(*args)\n      Wm.maxsize(self, *args)\n    end\n    alias wm_maxsize maxsize\n    TOPLEVEL_METHODCALL_OPTKEYS['maxsize'] = 'maxsize'\n\n    def Wm.minsize(win, *args)\n      if args.size == 0\n        list(tk_call_without_enc('wm', 'minsize', win.epath))\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call_without_enc('wm', 'minsize', win.path, *args)\n        win\n      end\n    end\n    def minsize(*args)\n      Wm.minsize(self, *args)\n    end\n    alias wm_minsize minsize\n    TOPLEVEL_METHODCALL_OPTKEYS['minsize'] = 'minsize'\n\n    def Wm.overrideredirect(win, mode=TkComm::None)\n      if mode == TkComm::None\n        bool(tk_call_without_enc('wm', 'overrideredirect', win.epath))\n      else\n        tk_call_without_enc('wm', 'overrideredirect', win.epath, mode)\n        win\n      end\n    end\n    def overrideredirect(mode=TkComm::None)\n      Wm.overrideredirect(self, mode)\n    end\n    alias wm_overrideredirect overrideredirect\n    TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect'\n\n    def Wm.positionfrom(win, who=TkComm::None)\n      if who == TkComm::None\n        r = tk_call_without_enc('wm', 'positionfrom', win.epath)\n        (r == \"\")? nil: r\n      else\n        tk_call_without_enc('wm', 'positionfrom', win.epath, who)\n        win\n      end\n    end\n    def positionfrom(who=TkComm::None)\n      Wm.positionfrom(self, who)\n    end\n    alias wm_positionfrom positionfrom\n    TOPLEVEL_METHODCALL_OPTKEYS['positionfrom'] = 'positionfrom'\n\n    def Wm.protocol(win, name=nil, cmd=nil, &b)\n      if cmd\n        tk_call_without_enc('wm', 'protocol', win.epath, name, cmd)\n        win\n      elsif b\n        tk_call_without_enc('wm', 'protocol', win.epath, name, proc(&b))\n        win\n      elsif name\n        result = tk_call_without_enc('wm', 'protocol', win.epath, name)\n        (result == \"\")? nil : tk_tcl2ruby(result)\n      else\n        tk_split_simplelist(tk_call_without_enc('wm', 'protocol', win.epath))\n      end\n    end\n    def protocol(name=nil, cmd=nil, &b)\n      Wm.protocol(self, name, cmd, &b)\n    end\n    alias wm_protocol protocol\n\n    def Wm.protocols(win, kv=nil)\n      unless kv\n        ret = {}\n        Wm.protocol(win).each{|name|\n          ret[name] = Wm.protocol(win, name)\n        }\n        return ret\n      end\n\n      unless kv.kind_of?(Hash)\n        fail ArgumentError, 'expect a hash of protocol=>command'\n      end\n      kv.each{|k, v| Wm.protocol(win, k, v)}\n      win\n    end\n    def protocols(kv=nil)\n      Wm.protocols(self, kv)\n    end\n    alias wm_protocols protocols\n    TOPLEVEL_METHODCALL_OPTKEYS['protocols'] = 'protocols'\n\n    def Wm.resizable(win, *args)\n      if args.length == 0\n        list(tk_call_without_enc('wm', 'resizable', win.epath)).map!{|e| bool(e)}\n      else\n        args = args[0] if args.length == 1 && args[0].kind_of?(Array)\n        tk_call_without_enc('wm', 'resizable', win.epath, *args)\n        win\n      end\n    end\n    def resizable(*args)\n      Wm.resizable(self, *args)\n    end\n    alias wm_resizable resizable\n    TOPLEVEL_METHODCALL_OPTKEYS['resizable'] = 'resizable'\n\n    def Wm.sizefrom(win, who=TkComm::None)\n      if who == TkComm::None\n        r = tk_call_without_enc('wm', 'sizefrom', win.epath)\n        (r == \"\")? nil: r\n      else\n        tk_call_without_enc('wm', 'sizefrom', win.epath, who)\n        win\n      end\n    end\n    def sizefrom(who=TkComm::None)\n      Wm.sizefrom(self, who)\n    end\n    alias wm_sizefrom sizefrom\n    TOPLEVEL_METHODCALL_OPTKEYS['sizefrom'] = 'sizefrom'\n\n    def Wm.stackorder(win)\n      list(tk_call('wm', 'stackorder', win.epath))\n    end\n    def stackorder\n      Wm.stackorder(self)\n    end\n    alias wm_stackorder stackorder\n\n    def Wm.stackorder_isabove(win, target)\n      bool(tk_call('wm', 'stackorder', win.epath, 'isabove', target))\n    end\n    def Wm.stackorder_is_above(win, target)\n      Wm.stackorder_isabove(win, target)\n    end\n    def stackorder_isabove(target)\n      Wm.stackorder_isabove(self, target)\n    end\n    alias stackorder_is_above stackorder_isabove\n    alias wm_stackorder_isabove stackorder_isabove\n    alias wm_stackorder_is_above stackorder_isabove\n\n    def Wm.stackorder_isbelow(win, target)\n      bool(tk_call('wm', 'stackorder', win.epath, 'isbelow', target))\n    end\n    def Wm.stackorder_is_below(win, target)\n      Wm.stackorder_isbelow(win, target)\n    end\n    def stackorder_isbelow(target)\n      Wm.stackorder_isbelow(self, target)\n    end\n    alias stackorder_is_below stackorder_isbelow\n    alias wm_stackorder_isbelow stackorder_isbelow\n    alias wm_stackorder_is_below stackorder_isbelow\n\n    def Wm.state(win, st=nil)\n      if st\n        tk_call_without_enc('wm', 'state', win.epath, st)\n        win\n      else\n        tk_call_without_enc('wm', 'state', win.epath)\n      end\n    end\n    def state(st=nil)\n      Wm.state(self, st)\n    end\n    alias wm_state state\n    TOPLEVEL_METHODCALL_OPTKEYS['state'] = 'state'\n\n    def Wm.title(win, str=nil)\n      if str\n        tk_call('wm', 'title', win.epath, str)\n        win\n      else\n        tk_call('wm', 'title', win.epath)\n      end\n    end\n    def title(str=nil)\n      Wm.title(self, str)\n    end\n    alias wm_title title\n    TOPLEVEL_METHODCALL_OPTKEYS['title'] = 'title'\n\n    def Wm.transient(win, master=nil)\n      if master\n        tk_call_without_enc('wm', 'transient', win.epath, master)\n        win\n      else\n        window(tk_call_without_enc('wm', 'transient', win.epath))\n      end\n    end\n    def transient(master=nil)\n      Wm.transient(self, master)\n    end\n    alias wm_transient transient\n    TOPLEVEL_METHODCALL_OPTKEYS['transient'] = 'transient'\n\n    def Wm.withdraw(win, ex = true)\n      if ex\n        tk_call_without_enc('wm', 'withdraw', win.epath)\n      else\n        Wm.deiconify(win)\n      end\n      win\n    end\n    def withdraw(ex = true)\n      Wm.withdraw(self, ex)\n    end\n    alias wm_withdraw withdraw\n  end\n\n  module Wm_for_General\n    Wm.instance_methods.each{|m|\n      if (m = m.to_s) =~ /^wm_(.*)$/\n        eval \"def #{m}(*args, &b); Tk::Wm.#{$1}(self, *args, &b); end\"\n      end\n    }\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk/xim.rb",
    "content": "#\n# tk/xim.rb : control imput_method\n#\nrequire 'tk'\n\nmodule TkXIM\n  include Tk\n  extend Tk\n\n  TkCommandNames = ['imconfigure'.freeze].freeze\n\n  def TkXIM.useinputmethods(value = None, win = nil)\n    if value == None\n      if win\n        bool(tk_call_without_enc('tk', 'useinputmethods', \n                                 '-displayof', win))\n      else\n        bool(tk_call_without_enc('tk', 'useinputmethods'))\n      end\n    else\n      if win\n        bool(tk_call_without_enc('tk', 'useinputmethods', \n                                 '-displayof', win, value))\n      else\n        bool(tk_call_without_enc('tk', 'useinputmethods', value))\n      end\n    end\n  end\n\n  def TkXIM.useinputmethods_displayof(win, value = None)\n    TkXIM.useinputmethods(value, win)\n  end\n\n  def TkXIM.caret(win, keys=nil)\n    if keys\n      tk_call_without_enc('tk', 'caret', win, *hash_kv(keys))\n      self\n    else\n      lst = tk_split_list(tk_call_without_enc('tk', 'caret', win))\n      info = {}\n      while key = lst.shift\n        info[key[1..-1]] = lst.shift\n      end\n      info\n    end\n  end\n\n  def TkXIM.configure(win, slot, value=None)\n    begin\n      if /^8\\.*/ === Tk::TK_VERSION  && JAPANIZED_TK\n        if slot.kind_of? Hash\n          tk_call('imconfigure', win, *hash_kv(slot))\n        else\n          tk_call('imconfigure', win, \"-#{slot}\", value)\n        end\n      end\n    rescue\n    end\n  end\n\n  def TkXIM.configinfo(win, slot=nil)\n    if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      begin\n        if /^8\\.*/ === Tk::TK_VERSION  && JAPANIZED_TK\n          if slot\n            conf = tk_split_list(tk_call('imconfigure', win, \"-#{slot}\"))\n            conf[0] = conf[0][1..-1]\n            conf\n          else\n            tk_split_list(tk_call('imconfigure', win)).collect{|conf|\n              conf[0] = conf[0][1..-1]\n              conf\n            }\n          end\n        else\n          []\n        end\n      rescue\n        []\n      end\n    else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY\n      TkXIM.current_configinfo(win, slot)\n    end\n  end\n\n  def TkXIM.current_configinfo(win, slot=nil)\n    begin\n      if /^8\\.*/ === Tk::TK_VERSION  && JAPANIZED_TK\n        if slot\n          conf = tk_split_list(tk_call('imconfigure', win, \"-#{slot}\"))\n          { conf[0][1..-1] => conf[1] }\n        else\n          ret = {}\n          tk_split_list(tk_call('imconfigure', win)).each{|conf|\n            ret[conf[0][1..-1]] = conf[1]\n          }\n          ret\n        end\n      else\n        {}\n      end\n    rescue\n      {}\n    end\n  end\n\n  def useinputmethods(value=None)\n    TkXIM.useinputmethods(value, self)\n  end\n\n  def caret(keys=nil)\n    TkXIM.caret(self, keys=nil)\n  end\n\n  def imconfigure(slot, value=None)\n    TkXIM.configure(self, slot, value)\n  end\n\n  def imconfiginfo(slot=nil)\n    TkXIM.configinfo(self, slot)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tk.rb",
    "content": "#\n#               tk.rb - Tk interface module using tcltklib\n#                       by Yukihiro Matsumoto <matz@netlab.jp>\n\n# use Shigehiro's tcltklib\nrequire 'tcltklib'\nrequire 'tkutil'\n\n# autoload\nrequire 'tk/autoload'\n\n# for Mutex\nrequire 'thread'\n\nclass TclTkIp\n  # backup original (without encoding) _eval and _invoke\n  alias _eval_without_enc _eval\n  alias _invoke_without_enc _invoke\n\n  def _ip_id_\n    # for RemoteTkIp\n    ''\n  end\nend\n\n# define TkComm module (step 1: basic functions)\nmodule TkComm\n  include TkUtil\n  extend TkUtil\n\n  WidgetClassNames = {}.taint\n  TkExtlibAutoloadModule = [].taint\n\n  # None = Object.new  ### --> definition is moved to TkUtil module\n  # def None.to_s\n  #   'None'\n  # end\n  # None.freeze\n\n  #Tk_CMDTBL = {}\n  #Tk_WINDOWS = {}\n  Tk_IDs = [\"00000\".taint, \"00000\".taint]  # [0]-cmdid, [1]-winid\n  Tk_IDs.instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  # for backward compatibility\n  Tk_CMDTBL = Object.new\n  def Tk_CMDTBL.method_missing(id, *args)\n    TkCore::INTERP.tk_cmd_tbl.__send__(id, *args)\n  end\n  Tk_CMDTBL.freeze\n  Tk_WINDOWS = Object.new\n  def Tk_WINDOWS.method_missing(id, *args)\n    TkCore::INTERP.tk_windows.__send__(id, *args)\n  end\n  Tk_WINDOWS.freeze\n\n  self.instance_eval{\n    @cmdtbl = [].taint\n  }\n\n  unless const_defined?(:GET_CONFIGINFO_AS_ARRAY)\n    # GET_CONFIGINFO_AS_ARRAY = false => returns a Hash { opt =>val, ... }\n    #                           true  => returns an Array [[opt,val], ... ]\n    # val is a list which includes resource info. \n    GET_CONFIGINFO_AS_ARRAY = true\n  end\n  unless const_defined?(:GET_CONFIGINFOwoRES_AS_ARRAY)\n    # for configinfo without resource info; list of [opt, value] pair\n    #           false => returns a Hash { opt=>val, ... }\n    #           true  => returns an Array [[opt,val], ... ]\n    GET_CONFIGINFOwoRES_AS_ARRAY = true\n  end\n  #  *** ATTENTION ***\n  # 'current_configinfo' method always returns a Hash under all cases of above.\n\n  def error_at\n    frames = caller()\n    frames.delete_if do |c|\n      c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\\.rb:\\d+!\n    end\n    frames\n  end\n  private :error_at\n\n  def _genobj_for_tkwidget(path)\n    return TkRoot.new if path == '.'\n\n    begin\n      #tk_class = TkCore::INTERP._invoke('winfo', 'class', path)\n      tk_class = Tk.ip_invoke_without_enc('winfo', 'class', path)\n    rescue\n      return path\n    end\n\n    if ruby_class = WidgetClassNames[tk_class]\n      ruby_class_name = ruby_class.name\n      # gen_class_name = ruby_class_name + 'GeneratedOnTk'\n      gen_class_name = ruby_class_name\n      classname_def = ''\n    else # ruby_class == nil\n      mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}\n      mods.each{|mod|\n        begin\n          mod.const_get(tk_class)  # auto_load\n          break if (ruby_class = WidgetClassNames[tk_class])\n        rescue LoadError\n          # ignore load error\n        end\n      }\n\n      unless ruby_class\n        std_class = 'Tk' << tk_class\n        if Object.const_defined?(std_class)\n          Object.const_get(std_class)  # auto_load\n          ruby_class = WidgetClassNames[tk_class]\n        end\n      end\n\n      if ruby_class\n        # found\n        ruby_class_name = ruby_class.name\n        gen_class_name = ruby_class_name\n        classname_def = ''\n      else\n        # unknown\n        ruby_class_name = 'TkWindow'\n        gen_class_name = 'TkWidget_' + tk_class\n        classname_def = \"WidgetClassName = '#{tk_class}'.freeze\"\n      end\n    end\n\n###################################\n=begin\n    if ruby_class = WidgetClassNames[tk_class]\n      ruby_class_name = ruby_class.name\n      # gen_class_name = ruby_class_name + 'GeneratedOnTk'\n      gen_class_name = ruby_class_name\n      classname_def = ''\n    else\n      mod = TkExtlibAutoloadModule.find{|m| m.const_defined?(tk_class)}\n      if mod\n        ruby_class_name = mod.name + '::' + tk_class\n        gen_class_name = ruby_class_name\n        classname_def = ''\n      elsif Object.const_defined?('Tk' + tk_class)\n        ruby_class_name = 'Tk' + tk_class\n        # gen_class_name = ruby_class_name + 'GeneratedOnTk'\n        gen_class_name = ruby_class_name\n        classname_def = ''\n      else\n        ruby_class_name = 'TkWindow'\n        # gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk'\n        gen_class_name = 'TkWidget_' + tk_class\n        classname_def = \"WidgetClassName = '#{tk_class}'.freeze\"\n      end\n    end\n=end\n\n=begin\n    unless Object.const_defined? gen_class_name\n      Object.class_eval \"class #{gen_class_name}<#{ruby_class_name}\n                           #{classname_def}\n                         end\"\n    end\n    Object.class_eval \"#{gen_class_name}.new('widgetname'=>'#{path}', \n                                             'without_creating'=>true)\"\n=end\n    base = Object\n    gen_class_name.split('::').each{|klass|\n      next if klass == ''\n      if base.const_defined?(klass)\n        base = base.class_eval klass\n      else\n        base = base.class_eval \"class #{klass}<#{ruby_class_name}\n                                  #{classname_def}\n                                end\n                                #{klass}\"\n      end\n    }\n    base.class_eval \"#{gen_class_name}.new('widgetname'=>'#{path}', \n                                           'without_creating'=>true)\"\n  end\n  private :_genobj_for_tkwidget\n  module_function :_genobj_for_tkwidget\n\n  def _at(x,y=nil)\n    if y\n      \"@#{Integer(x)},#{Integer(y)}\"\n    else\n      \"@#{Integer(x)}\"\n    end\n  end\n  module_function :_at\n\n  def tk_tcl2ruby(val, enc_mode = false, listobj = true)\n=begin\n    if val =~ /^rb_out\\S* (c(_\\d+_)?\\d+)/\n      #return Tk_CMDTBL[$1]\n      return TkCore::INTERP.tk_cmd_tbl[$1]\n      #cmd_obj = TkCore::INTERP.tk_cmd_tbl[$1]\n      #if cmd_obj.kind_of?(Proc) || cmd_obj.kind_of?(Method)\n      #  cmd_obj\n      #else\n      #  cmd_obj.cmd\n      #end\n    end\n=end\n    if val =~ /rb_out\\S*(?:\\s+(::\\S*|[{](::.*)[}]|[\"](::.*)[\"]))? (c(_\\d+_)?(\\d+))/\n      return TkCore::INTERP.tk_cmd_tbl[$4]\n    end\n    #if val.include? ?\\s\n    #  return val.split.collect{|v| tk_tcl2ruby(v)}\n    #end\n    case val\n    when /\\A@font\\S+\\z/\n      TkFont.get_obj(val)\n    when /\\A-?\\d+\\z/\n      val.to_i\n    when /\\A\\.\\S*\\z/\n      #Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val)\n      TkCore::INTERP.tk_windows[val]? \n           TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val)\n    when /\\Ai(_\\d+_)?\\d+\\z/\n      TkImage::Tk_IMGTBL.mutex.synchronize{\n        TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val\n      }\n    when /\\A-?\\d+\\.?\\d*(e[-+]?\\d+)?\\z/\n      val.to_f\n    when /\\\\ /\n      val.gsub(/\\\\ /, ' ')\n    when /[^\\\\] /\n      if listobj\n        #tk_split_escstr(val).collect{|elt|\n        #  tk_tcl2ruby(elt, enc_mode, listobj)\n        #}\n        val = _toUTF8(val) unless enc_mode\n        tk_split_escstr(val, false, false).collect{|elt|\n          tk_tcl2ruby(elt, true, listobj)\n        }\n      elsif enc_mode\n        _fromUTF8(val)\n      else\n        val\n      end\n    else\n      if enc_mode\n        _fromUTF8(val)\n      else\n        val\n      end\n    end\n  end\n\n  private :tk_tcl2ruby\n  module_function :tk_tcl2ruby\n  #private_class_method :tk_tcl2ruby\n\nunless const_defined?(:USE_TCLs_LIST_FUNCTIONS)\n  USE_TCLs_LIST_FUNCTIONS = true\nend\n\nif USE_TCLs_LIST_FUNCTIONS\n  ###########################################################################\n  # use Tcl function version of split_list\n  ###########################################################################\n\n  def tk_split_escstr(str, src_enc=true, dst_enc=true)\n    str = _toUTF8(str) if src_enc\n    if dst_enc\n      TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)}\n    else\n      TkCore::INTERP._split_tklist(str)\n    end\n  end\n\n  def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true)\n    # return [] if str == \"\"\n    # list = TkCore::INTERP._split_tklist(str)\n    str = _toUTF8(str) if src_enc\n\n    if depth == 0\n      return \"\" if str == \"\"\n      list = [str]\n    else\n      return [] if str == \"\"\n      list = TkCore::INTERP._split_tklist(str)\n    end\n    if list.size == 1\n      # tk_tcl2ruby(list[0], nil, false)\n      tk_tcl2ruby(list[0], dst_enc, false)\n    else\n      list.collect{|token| tk_split_sublist(token, depth - 1, false, dst_enc)}\n    end\n  end\n\n  def tk_split_list(str, depth=0, src_enc=true, dst_enc=true)\n    return [] if str == \"\"\n    str = _toUTF8(str) if src_enc\n    TkCore::INTERP._split_tklist(str).map!{|token|\n      tk_split_sublist(token, depth - 1, false, dst_enc)\n    }\n  end\n\n  def tk_split_simplelist(str, src_enc=true, dst_enc=true)\n    #lst = TkCore::INTERP._split_tklist(str)\n    #if (lst.size == 1 && lst =~ /^\\{.*\\}$/)\n    #  TkCore::INTERP._split_tklist(str[1..-2])\n    #else\n    #  lst\n    #end\n\n    str = _toUTF8(str) if src_enc\n    if dst_enc\n      TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)}\n    else\n      TkCore::INTERP._split_tklist(str)\n    end\n  end\n\n  def array2tk_list(ary, enc=nil)\n    return \"\" if ary.size == 0\n\n    sys_enc = TkCore::INTERP.encoding\n    sys_enc = TclTkLib.encoding_system unless sys_enc\n\n    dst_enc = (enc == nil)? sys_enc: enc\n\n    dst = ary.collect{|e|\n      if e.kind_of? Array\n        s = array2tk_list(e, enc)\n      elsif e.kind_of? Hash\n        tmp_ary = []\n        #e.each{|k,v| tmp_ary << k << v }\n        e.each{|k,v| tmp_ary << \"-#{_get_eval_string(k)}\" << v }\n        s = array2tk_list(tmp_ary, enc)\n      else\n        s = _get_eval_string(e, enc)\n      end\n\n      if dst_enc != true && dst_enc != false\n        if (s_enc = s.instance_variable_get(:@encoding))\n          s_enc = s_enc.to_s\n        elsif TkCore::WITH_ENCODING\n          s_enc = s.encoding.name\n        else\n          s_enc = sys_enc\n        end\n        dst_enc = true if s_enc != dst_enc\n      end\n\n      s\n    }\n\n    if sys_enc && dst_enc\n      dst.map!{|s| _toUTF8(s)}\n      ret = TkCore::INTERP._merge_tklist(*dst)\n      if TkCore::WITH_ENCODING\n        if dst_enc.kind_of?(String)\n          ret = _fromUTF8(ret, dst_enc)\n          ret.force_encoding(dst_enc)\n        else\n          ret.force_encoding('utf-8')\n        end\n      else # without encoding\n        if dst_enc.kind_of?(String)\n          ret = _fromUTF8(ret, dst_enc)\n          ret.instance_variable_set(:@encoding, dst_enc)\n        else\n          ret.instance_variable_set(:@encoding, 'utf-8')\n        end\n      end\n      ret\n    else\n      TkCore::INTERP._merge_tklist(*dst)\n    end\n  end\n\nelse\n  ###########################################################################\n  # use Ruby script version of split_list (traditional methods)\n  ###########################################################################\n\n  def tk_split_escstr(str, src_enc=true, dst_enc=true)\n    return [] if str == \"\"\n    list = []\n    token = nil\n    escape = false\n    brace = 0\n    str.split('').each {|c|\n      brace += 1 if c == '{' && !escape\n      brace -= 1 if c == '}' && !escape\n      if brace == 0 && c == ' ' && !escape\n        list << token.gsub(/^\\{(.*)\\}$/, '\\1') if token\n        token = nil\n      else\n        token = (token || \"\") << c\n      end\n      escape = (c == '\\\\' && !escape)\n    }\n    list << token.gsub(/^\\{(.*)\\}$/, '\\1') if token\n    list\n  end\n\n  def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true)\n    #return [] if str == \"\"\n    #return [tk_split_sublist(str[1..-2])] if str =~ /^\\{.*\\}$/\n    #list = tk_split_escstr(str)\n    if depth == 0\n      return \"\" if str == \"\"\n      str = str[1..-2] if str =~ /^\\{.*\\}$/\n      list = [str]\n    else\n      return [] if str == []\n      return [tk_split_sublist(str[1..-2], depth - 1)] if str =~ /^\\{.*\\}$/\n      list = tk_split_escstr(str)\n    end\n    if list.size == 1\n      tk_tcl2ruby(list[0], nil, false)\n    else\n      list.collect{|token| tk_split_sublist(token, depth - 1)}\n    end\n  end\n\n  def tk_split_list(str, depth=0, src_enc=true, dst_enc=true)\n    return [] if str == \"\"\n    tk_split_escstr(str).collect{|token| \n      tk_split_sublist(token, depth - 1)\n    }\n  end\n\n  def tk_split_simplelist(str, src_enc=true, dst_enc=true)\n    return [] if str == \"\"\n    list = []\n    token = nil\n    escape = false\n    brace = 0\n    str.split('').each {|c|\n      if c == '\\\\' && !escape\n        escape = true\n        token = (token || \"\") << c if brace > 0\n        next\n      end\n      brace += 1 if c == '{' && !escape\n      brace -= 1 if c == '}' && !escape\n      if brace == 0 && c == ' ' && !escape\n        list << token.gsub(/^\\{(.*)\\}$/, '\\1') if token\n        token = nil\n      else\n        token = (token || \"\") << c\n      end\n      escape = false\n    }\n    list << token.gsub(/^\\{(.*)\\}$/, '\\1') if token\n    list\n  end\n\n  def array2tk_list(ary, enc=nil)\n    ary.collect{|e|\n      if e.kind_of? Array\n        \"{#{array2tk_list(e, enc)}}\"\n      elsif e.kind_of? Hash\n        # \"{#{e.to_a.collect{|ee| array2tk_list(ee)}.join(' ')}}\"\n        e.each{|k,v| tmp_ary << \"-#{_get_eval_string(k)}\" << v }\n        array2tk_list(tmp_ary, enc)\n      else\n        s = _get_eval_string(e, enc)\n        (s.index(/\\s/) || s.size == 0)? \"{#{s}}\": s\n      end\n    }.join(\" \")\n  end\nend\n\n  private :tk_split_escstr, :tk_split_sublist\n  private :tk_split_list, :tk_split_simplelist\n  private :array2tk_list\n\n  module_function :tk_split_escstr, :tk_split_sublist\n  module_function :tk_split_list, :tk_split_simplelist\n  module_function :array2tk_list\n\n  private_class_method :tk_split_escstr, :tk_split_sublist\n  private_class_method :tk_split_list, :tk_split_simplelist\n#  private_class_method :array2tk_list\n\n=begin\n  ### --> definition is moved to TkUtil module\n  def _symbolkey2str(keys)\n    h = {}\n    keys.each{|key,value| h[key.to_s] = value}\n    h\n  end\n  private :_symbolkey2str\n  module_function :_symbolkey2str\n=end\n\n=begin\n  ### --> definition is moved to TkUtil module\n  # def hash_kv(keys, enc_mode = nil, conf = [], flat = false)\n  def hash_kv(keys, enc_mode = nil, conf = nil)\n    # Hash {key=>val, key=>val, ... } or Array [ [key, val], [key, val], ... ]\n    #     ==> Array ['-key', val, '-key', val, ... ]\n    dst = []\n    if keys and keys != None\n      keys.each{|k, v|\n        #dst.push(\"-#{k}\")\n        dst.push('-' + k.to_s)\n        if v != None\n          # v = _get_eval_string(v, enc_mode) if (enc_mode || flat)\n          v = _get_eval_string(v, enc_mode) if enc_mode\n          dst.push(v)\n        end\n      }\n    end\n    if conf\n      conf + dst\n    else\n      dst\n    end\n  end\n  private :hash_kv\n  module_function :hash_kv\n=end\n\n=begin\n  ### --> definition is moved to TkUtil module\n  def bool(val)\n    case val\n    when \"1\", 1, 'yes', 'true'\n      true\n    else\n      false\n    end\n  end\n\n  def number(val)\n    case val\n    when /^-?\\d+$/\n      val.to_i\n    when /^-?\\d+\\.?\\d*(e[-+]?\\d+)?$/\n      val.to_f\n    else\n      fail(ArgumentError, \"invalid value for Number:'#{val}'\")\n    end\n  end\n  def string(val)\n    if val == \"{}\"\n      ''\n    elsif val[0] == ?{ && val[-1] == ?}\n      val[1..-2]\n    else\n      val\n    end\n  end\n  def num_or_str(val)\n    begin\n      number(val)\n    rescue ArgumentError\n      string(val)\n    end\n  end\n=end\n\n  def list(val, depth=0, enc=true)\n    tk_split_list(val, depth, enc, enc)\n  end\n  def simplelist(val, src_enc=true, dst_enc=true)\n    tk_split_simplelist(val, src_enc, dst_enc)\n  end\n  def window(val)\n    if val =~ /^\\./\n      #Tk_WINDOWS[val]? Tk_WINDOWS[val] : _genobj_for_tkwidget(val)\n      TkCore::INTERP.tk_windows[val]? \n           TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val)\n    else\n      nil\n    end\n  end\n  def image_obj(val)\n    if val =~ /^i(_\\d+_)?\\d+$/\n      TkImage::Tk_IMGTBL.mutex.synchronize{\n        TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val\n      }\n    else\n      val\n    end\n  end\n  def procedure(val)\n=begin\n    if val =~ /^rb_out\\S* (c(_\\d+_)?\\d+)/\n      #Tk_CMDTBL[$1]\n      #TkCore::INTERP.tk_cmd_tbl[$1]\n      TkCore::INTERP.tk_cmd_tbl[$1].cmd\n=end\n    if val =~ /rb_out\\S*(?:\\s+(::\\S*|[{](::.*)[}]|[\"](::.*)[\"]))? (c(_\\d+_)?(\\d+))/\n      return TkCore::INTERP.tk_cmd_tbl[$4].cmd\n    else\n      #nil\n      val\n    end\n  end\n  private :bool, :number, :string, :num_or_str\n  private :list, :simplelist, :window, :procedure\n  module_function :bool, :number, :num_or_str, :string\n  module_function :list, :simplelist, :window, :image_obj, :procedure\n\n  def subst(str, *opts)\n    # opts := :nobackslashes | :nocommands | novariables\n    tk_call('subst', \n            *(opts.collect{|opt|\n                opt = opt.to_s\n                (opt[0] == ?-)? opt: '-' << opt\n              } << str))\n  end\n\n  def _toUTF8(str, encoding = nil)\n    TkCore::INTERP._toUTF8(str, encoding)\n  end\n  def _fromUTF8(str, encoding = nil)\n    TkCore::INTERP._fromUTF8(str, encoding)\n  end\n  private :_toUTF8, :_fromUTF8\n  module_function :_toUTF8, :_fromUTF8\n\n  def _callback_entry_class?(cls)\n    cls <= Proc || cls <= Method || cls <= TkCallbackEntry\n  end\n  private :_callback_entry_class?\n  module_function :_callback_entry_class?\n\n  def _callback_entry?(obj)\n    obj.kind_of?(Proc) || obj.kind_of?(Method) || obj.kind_of?(TkCallbackEntry)\n  end\n  private :_callback_entry?\n  module_function :_callback_entry?\n\n=begin\n  ### --> definition is moved to TkUtil module\n  def _get_eval_string(str, enc_mode = nil)\n    return nil if str == None\n    if str.kind_of?(TkObject)\n      str = str.path\n    elsif str.kind_of?(String)\n      str = _toUTF8(str) if enc_mode\n    elsif str.kind_of?(Symbol)\n      str = str.id2name\n      str = _toUTF8(str) if enc_mode\n    elsif str.kind_of?(Hash)\n      str = hash_kv(str, enc_mode).join(\" \")\n    elsif str.kind_of?(Array)\n      str = array2tk_list(str)\n      str = _toUTF8(str) if enc_mode\n    elsif str.kind_of?(Proc)\n      str = install_cmd(str)\n    elsif str == nil\n      str = \"\"\n    elsif str == false\n      str = \"0\"\n    elsif str == true\n      str = \"1\"\n    elsif (str.respond_to?(:to_eval))\n      str = str.to_eval()\n      str = _toUTF8(str) if enc_mode\n    else\n      str = str.to_s() || ''\n      unless str.kind_of? String\n        fail RuntimeError, \"fail to convert the object to a string\" \n      end\n      str = _toUTF8(str) if enc_mode\n    end\n    return str\n  end\n=end\n=begin\n  def _get_eval_string(obj, enc_mode = nil)\n    case obj\n    when Numeric\n      obj.to_s\n    when String\n      (enc_mode)? _toUTF8(obj): obj\n    when Symbol\n      (enc_mode)? _toUTF8(obj.id2name): obj.id2name\n    when TkObject\n      obj.path\n    when Hash\n      hash_kv(obj, enc_mode).join(' ')\n    when Array\n      (enc_mode)? _toUTF8(array2tk_list(obj)): array2tk_list(obj)\n    when Proc, Method, TkCallbackEntry\n      install_cmd(obj)\n    when false\n      '0'\n    when true\n      '1'\n    when nil\n      ''\n    when None\n      nil\n    else\n      if (obj.respond_to?(:to_eval))\n        (enc_mode)? _toUTF8(obj.to_eval): obj.to_eval\n      else\n        begin\n          obj = obj.to_s || ''\n        rescue\n          fail RuntimeError, \"fail to convert object '#{obj}' to string\" \n        end\n        (enc_mode)? _toUTF8(obj): obj\n      end\n    end\n  end\n  private :_get_eval_string\n  module_function :_get_eval_string\n=end\n\n=begin\n  ### --> definition is moved to TkUtil module\n  def _get_eval_enc_str(obj)\n    return obj if obj == None\n    _get_eval_string(obj, true)\n  end\n  private :_get_eval_enc_str\n  module_function :_get_eval_enc_str\n=end\n\n=begin\n  ### --> obsolete\n  def ruby2tcl(v, enc_mode = nil)\n    if v.kind_of?(Hash)\n      v = hash_kv(v)\n      v.flatten!\n      v.collect{|e|ruby2tcl(e, enc_mode)}\n    else\n      _get_eval_string(v, enc_mode)\n    end\n  end\n  private :ruby2tcl\n=end\n\n=begin\n  ### --> definition is moved to TkUtil module\n  def _conv_args(args, enc_mode, *src_args)\n    conv_args = []\n    src_args.each{|arg|\n      conv_args << _get_eval_string(arg, enc_mode) unless arg == None\n      # if arg.kind_of?(Hash)\n      # arg.each{|k, v|\n      #   args << '-' + k.to_s\n      #   args << _get_eval_string(v, enc_mode)\n      # }\n      # elsif arg != None\n      #   args << _get_eval_string(arg, enc_mode)\n      # end\n    }\n    args + conv_args\n  end\n  private :_conv_args\n=end\n\n  def _curr_cmd_id\n    #id = format(\"c%.4d\", Tk_IDs[0])\n    id = \"c\" + TkCore::INTERP._ip_id_ + TkComm::Tk_IDs[0]\n  end\n  def _next_cmd_id\n    TkComm::Tk_IDs.mutex.synchronize{\n      id = _curr_cmd_id\n      #Tk_IDs[0] += 1\n      TkComm::Tk_IDs[0].succ!\n      id\n    }\n  end\n  private :_curr_cmd_id, :_next_cmd_id\n  module_function :_curr_cmd_id, :_next_cmd_id\n\n  def TkComm.install_cmd(cmd, local_cmdtbl=nil)\n    return '' if cmd == ''\n    begin\n      ns = TkCore::INTERP._invoke_without_enc('namespace', 'current')\n      ns = nil if ns == '::' # for backward compatibility\n    rescue\n      # probably, Tcl7.6\n      ns = nil\n    end\n    id = _next_cmd_id\n    #Tk_CMDTBL[id] = cmd\n    if cmd.kind_of?(TkCallbackEntry)\n      TkCore::INTERP.tk_cmd_tbl[id] = cmd\n    else\n      TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd)\n    end\n    @cmdtbl = [] unless defined? @cmdtbl\n    @cmdtbl.taint unless @cmdtbl.tainted?\n    @cmdtbl.push id\n\n    if local_cmdtbl && local_cmdtbl.kind_of?(Array)\n      begin\n        local_cmdtbl << id\n      rescue Exception\n        # ignore\n      end\n    end\n\n    #return Kernel.format(\"rb_out %s\", id);\n    if ns\n      'rb_out' << TkCore::INTERP._ip_id_ << ' ' << ns << ' ' << id\n    else\n      'rb_out' << TkCore::INTERP._ip_id_ << ' ' << id\n    end\n  end\n  def TkComm.uninstall_cmd(id, local_cmdtbl=nil)\n    #id = $1 if /rb_out\\S* (c(_\\d+_)?\\d+)/ =~ id\n    id = $4 if id =~ /rb_out\\S*(?:\\s+(::\\S*|[{](::.*)[}]|[\"](::.*)[\"]))? (c(_\\d+_)?(\\d+))/\n\n    if local_cmdtbl && local_cmdtbl.kind_of?(Array)\n      begin\n        local_cmdtbl.delete(id)\n      rescue Exception\n        # ignore\n      end\n    end\n    @cmdtbl.delete(id)\n\n    #Tk_CMDTBL.delete(id)\n    TkCore::INTERP.tk_cmd_tbl.delete(id)\n  end\n  # private :install_cmd, :uninstall_cmd\n  # module_function :install_cmd, :uninstall_cmd\n  def install_cmd(cmd)\n    TkComm.install_cmd(cmd, @cmdtbl)\n  end\n  def uninstall_cmd(id)\n    TkComm.uninstall_cmd(id, @cmdtbl)\n  end\n\n=begin\n  def install_win(ppath,name=nil)\n    if !name or name == ''\n      #name = format(\"w%.4d\", Tk_IDs[1])\n      #Tk_IDs[1] += 1\n      name = \"w\" + Tk_IDs[1]\n      Tk_IDs[1].succ!\n    end\n    if name[0] == ?.\n      @path = name.dup\n    elsif !ppath or ppath == \".\"\n      @path = Kernel.format(\".%s\", name);\n    else\n      @path = Kernel.format(\"%s.%s\", ppath, name)\n    end\n    #Tk_WINDOWS[@path] = self\n    TkCore::INTERP.tk_windows[@path] = self\n  end\n=end\n  def install_win(ppath,name=nil)\n    if name\n      if name == ''\n        raise ArgumentError, \"invalid wiget-name '#{name}'\"\n      end\n      if name[0] == ?.\n        @path = '' + name\n        @path.freeze\n        return TkCore::INTERP.tk_windows[@path] = self\n      end\n    else\n      Tk_IDs.mutex.synchronize{\n        name = \"w\" + TkCore::INTERP._ip_id_ + Tk_IDs[1]\n        Tk_IDs[1].succ!\n      }\n    end\n    if !ppath or ppath == '.'\n      @path = '.' + name\n    else\n      @path = ppath + '.' + name\n    end\n    @path.freeze\n    TkCore::INTERP.tk_windows[@path] = self\n  end\n\n  def uninstall_win()\n    #Tk_WINDOWS.delete(@path)\n    TkCore::INTERP.tk_windows.delete(@path)\n  end\n  private :install_win, :uninstall_win\n\n  def _epath(win)\n    if win.kind_of?(TkObject)\n      win.epath\n    elsif win.respond_to?(:epath)\n      win.epath\n    else\n      win\n    end\n  end\n  private :_epath\nend\n\n# define TkComm module (step 2: event binding)\nmodule TkComm\n  include TkEvent\n  extend TkEvent\n\n  def tk_event_sequence(context)\n    if context.kind_of? TkVirtualEvent\n      context = context.path\n    end\n    if context.kind_of? Array\n      context = context.collect{|ev|\n        if ev.kind_of? TkVirtualEvent\n          ev.path\n        else\n          ev\n        end\n      }.join(\"><\")\n    end\n    if /,/ =~ context\n      context = context.split(/\\s*,\\s*/).join(\"><\")\n    else\n      context\n    end\n  end\n\n  def _bind_core(mode, what, context, cmd, *args)\n    id = install_bind(cmd, *args) if cmd\n    begin\n      tk_call_without_enc(*(what + [\"<#{tk_event_sequence(context)}>\", \n                              mode + id]))\n    rescue\n      uninstall_cmd(id) if cmd\n      fail\n    end\n  end\n\n  def _bind(what, context, cmd, *args)\n    _bind_core('', what, context, cmd, *args)\n  end\n\n  def _bind_append(what, context, cmd, *args)\n    _bind_core('+', what, context, cmd, *args)\n  end\n\n  def _bind_remove(what, context)\n    tk_call_without_enc(*(what + [\"<#{tk_event_sequence(context)}>\", '']))\n  end\n\n  def _bindinfo(what, context=nil)\n    if context\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        enum_obj = tk_call_without_enc(*what+[\"<#{tk_event_sequence(context)}>\"]).each_line\n      else\n        enum_obj = tk_call_without_enc(*what+[\"<#{tk_event_sequence(context)}>\"])\n      end\n      enum_obj.collect {|cmdline|\n=begin\n        if cmdline =~ /^rb_out\\S* (c(?:_\\d+_)?\\d+)\\s+(.*)$/\n          #[Tk_CMDTBL[$1], $2]\n          [TkCore::INTERP.tk_cmd_tbl[$1], $2]\n=end\n        if cmdline =~ /rb_out\\S*(?:\\s+(::\\S*|[{](::.*)[}]|[\"](::.*)[\"]))? (c(_\\d+_)?(\\d+))/\n          [TkCore::INTERP.tk_cmd_tbl[$4], $5]\n        else\n          cmdline\n        end\n      }\n    else\n      tk_split_simplelist(tk_call_without_enc(*what)).collect!{|seq|\n        l = seq.scan(/<*[^<>]+>*/).collect!{|subseq|\n          case (subseq)\n          when /^<<[^<>]+>>$/\n            TkVirtualEvent.getobj(subseq[1..-2])\n          when /^<[^<>]+>$/\n            subseq[1..-2]\n          else\n            subseq.split('')\n          end\n        }.flatten\n        (l.size == 1) ? l[0] : l\n      }\n    end\n  end\n\n  def _bind_core_for_event_class(klass, mode, what, context, cmd, *args)\n    id = install_bind_for_event_class(klass, cmd, *args) if cmd\n    begin\n      tk_call_without_enc(*(what + [\"<#{tk_event_sequence(context)}>\", \n                              mode + id]))\n    rescue\n      uninstall_cmd(id) if cmd\n      fail\n    end\n  end\n\n  def _bind_for_event_class(klass, what, context, cmd, *args)\n    _bind_core_for_event_class(klass, '', what, context, cmd, *args)\n  end\n\n  def _bind_append_for_event_class(klass, what, context, cmd, *args)\n    _bind_core_for_event_class(klass, '+', what, context, cmd, *args)\n  end\n\n  def _bind_remove_for_event_class(klass, what, context)\n    _bind_remove(what, context)\n  end\n\n  def _bindinfo_for_event_class(klass, what, context=nil)\n    _bindinfo(what, context)\n  end\n\n  private :tk_event_sequence\n  private :_bind_core, :_bind, :_bind_append, :_bind_remove, :_bindinfo\n  private :_bind_core_for_event_class, :_bind_for_event_class, \n          :_bind_append_for_event_class, :_bind_remove_for_event_class, \n          :_bindinfo_for_event_class\n\n  #def bind(tagOrClass, context, cmd=Proc.new, *args)\n  #  _bind([\"bind\", tagOrClass], context, cmd, *args)\n  #  tagOrClass\n  #end\n  def bind(tagOrClass, context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([\"bind\", tagOrClass], context, cmd, *args)\n    tagOrClass\n  end\n\n  #def bind_append(tagOrClass, context, cmd=Proc.new, *args)\n  #  _bind_append([\"bind\", tagOrClass], context, cmd, *args)\n  #  tagOrClass\n  #end\n  def bind_append(tagOrClass, context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([\"bind\", tagOrClass], context, cmd, *args)\n    tagOrClass\n  end\n\n  def bind_remove(tagOrClass, context)\n    _bind_remove(['bind', tagOrClass], context)\n    tagOrClass\n  end\n\n  def bindinfo(tagOrClass, context=nil)\n    _bindinfo(['bind', tagOrClass], context)\n  end\n\n  #def bind_all(context, cmd=Proc.new, *args)\n  #  _bind(['bind', 'all'], context, cmd, *args)\n  #  TkBindTag::ALL\n  #end\n  def bind_all(context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind(['bind', 'all'], context, cmd, *args)\n    TkBindTag::ALL\n  end\n\n  #def bind_append_all(context, cmd=Proc.new, *args)\n  #  _bind_append(['bind', 'all'], context, cmd, *args)\n  #  TkBindTag::ALL\n  #end\n  def bind_append_all(context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append(['bind', 'all'], context, cmd, *args)\n    TkBindTag::ALL\n  end\n\n  def bind_remove_all(context)\n    _bind_remove(['bind', 'all'], context)\n    TkBindTag::ALL\n  end\n\n  def bindinfo_all(context=nil)\n    _bindinfo(['bind', 'all'], context)\n  end\nend\n\n\nmodule TkCore\n  include TkComm\n  extend TkComm\n\n  WITH_RUBY_VM  = Object.const_defined?(:VM) && ::VM.class == Class\n  WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class\n\n  unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD\n    ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!!\n    RUN_EVENTLOOP_ON_MAIN_THREAD = false\n  end\n\n  unless self.const_defined? :INTERP\n    if self.const_defined? :IP_NAME\n      name = IP_NAME.to_s\n    else\n      #name = nil\n      name = $0\n    end\n    if self.const_defined? :IP_OPTS\n      if IP_OPTS.kind_of?(Hash)\n        opts = hash_kv(IP_OPTS).join(' ')\n      else\n        opts = IP_OPTS.to_s\n      end\n    else\n      opts = ''\n    end\n\n    if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!!\n      INTERP = TclTkIp.new(name, opts)\n    else\n      INTERP_MUTEX = Mutex.new\n      INTERP_ROOT_CHECK = ConditionVariable.new\n      INTERP_THREAD = Thread.new{\n        begin\n          Thread.current[:interp] = interp = TclTkIp.new(name, opts)\n        rescue => e\n          Thread.current[:interp] = e\n          raise e\n        end\n        Thread.current[:status] = nil\n        #sleep\n\n        begin\n          Thread.current[:status] = TclTkLib.mainloop(true)\n        rescue Exception=>e\n          Thread.current[:status] = e\n        ensure\n          INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }\n        end\n        Thread.current[:status] = TclTkLib.mainloop(false)\n      }\n\n      until INTERP_THREAD[:interp]\n        Thread.pass\n      end\n      # INTERP_THREAD.run\n      raise INTERP_THREAD[:interp] if INTERP_THREAD[:interp].kind_of? Exception\n\n      INTERP = INTERP_THREAD[:interp]\n    end\n\n    def INTERP.__getip\n      self\n    end\n\n    INTERP.instance_eval{\n      # @tk_cmd_tbl = {}.taint\n      @tk_cmd_tbl = Hash.new{|hash, key|\n        fail IndexError, \"unknown command ID '#{key}'\"\n      }.taint\n      def @tk_cmd_tbl.[]=(idx,val)\n        if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default\n          fail SecurityError,\"cannot change the entried command\"\n        end\n        super(idx,val)\n      end\n\n      @tk_windows = {}.taint\n\n      @tk_table_list = [].taint\n\n      @init_ip_env  = [].taint  # table of Procs\n      @add_tk_procs = [].taint  # table of [name, args, body]\n\n      @cb_entry_class = Class.new(TkCallbackEntry){\n        class << self\n          def inspect\n            sprintf(\"#<Class(TkCallbackEntry):%0x>\", self.__id__)\n          end\n          alias to_s inspect\n        end\n\n        def initialize(ip, cmd)\n          @ip = ip\n          @cmd = cmd\n        end\n        attr_reader :ip, :cmd\n        def call(*args)\n          @ip.cb_eval(@cmd, *args)\n        end\n        def inspect\n          sprintf(\"#<cb_entry:%0x>\", self.__id__)\n        end\n        alias to_s inspect\n      }.freeze\n    }\n\n    def INTERP.cb_entry_class\n      @cb_entry_class\n    end\n    def INTERP.tk_cmd_tbl\n      @tk_cmd_tbl\n    end\n    def INTERP.tk_windows\n      @tk_windows\n    end\n\n    class Tk_OBJECT_TABLE\n      def initialize(id)\n        @id = id\n        @mutex = Mutex.new\n      end\n      def mutex\n        @mutex\n      end\n      def method_missing(m, *args, &b)\n        TkCore::INTERP.tk_object_table(@id).__send__(m, *args, &b)\n      end\n    end\n\n    def INTERP.tk_object_table(id)\n      @tk_table_list[id]\n    end\n    def INTERP.create_table\n      id = @tk_table_list.size\n      (tbl = {}).tainted? || tbl.taint\n      @tk_table_list << tbl\n#      obj = Object.new\n#      obj.instance_eval <<-EOD\n#        def self.method_missing(m, *args)\n#         TkCore::INTERP.tk_object_table(#{id}).send(m, *args)\n#        end\n#      EOD\n#      return obj\n      Tk_OBJECT_TABLE.new(id)\n    end\n\n    def INTERP.get_cb_entry(cmd)\n      @cb_entry_class.new(__getip, cmd).freeze\n    end\n    def INTERP.cb_eval(cmd, *args)\n      TkUtil._get_eval_string(TkUtil.eval_cmd(cmd, *args))\n    end\n\n    def INTERP.init_ip_env(script = Proc.new)\n      @init_ip_env << script\n      script.call(self)\n    end\n    def INTERP.add_tk_procs(name, args = nil, body = nil)\n      if name.kind_of?(Array)\n        name.each{|param| self.add_tk_procs(*param)}\n      else\n        name = name.to_s\n        @add_tk_procs << [name, args, body]\n        self._invoke('proc', name, args, body) if args && body\n      end\n    end\n    def INTERP.remove_tk_procs(*names)\n      names.each{|name|\n        name = name.to_s\n        @add_tk_procs.delete_if{|elem| \n          elem.kind_of?(Array) && elem[0].to_s == name\n        }\n        self._invoke('rename', name, '')\n      }\n    end\n    def INTERP.init_ip_internal\n      ip = self\n      @init_ip_env.each{|script| script.call(ip)}\n      @add_tk_procs.each{|name,args,body| ip._invoke('proc',name,args,body)}\n    end\n  end\n\n  WIDGET_DESTROY_HOOK = '<WIDGET_DESTROY_HOOK>'\n  INTERP._invoke_without_enc('event', 'add', \n                             \"<#{WIDGET_DESTROY_HOOK}>\", '<Destroy>')\n  INTERP._invoke_without_enc('bind', 'all', \"<#{WIDGET_DESTROY_HOOK}>\",\n                             install_cmd(proc{|path|\n                                unless TkCore::INTERP.deleted?\n                                  begin\n                                    if (widget=TkCore::INTERP.tk_windows[path])\n                                      if widget.respond_to?(:__destroy_hook__)\n                                        widget.__destroy_hook__\n                                      end\n                                    end\n                                  rescue Exception=>e\n                                      p e if $DEBUG\n                                  end\n                                end\n                             }) << ' %W')\n\n  INTERP.add_tk_procs(TclTkLib::FINALIZE_PROC_NAME, '', \n                      \"catch { bind all <#{WIDGET_DESTROY_HOOK}> {} }\")\n\n  INTERP.add_tk_procs('rb_out', 'ns args', <<-'EOL')\n    if [regexp {^::} $ns] {\n      set cmd {namespace eval $ns {ruby_cmd TkCore callback} $args}\n    } else {\n      set cmd {eval {ruby_cmd TkCore callback} $ns $args}\n    }\n    if {[set st [catch $cmd ret]] != 0} {\n       #return -code $st $ret\n       set idx [string first \"\\n\\n\" $ret]\n       if {$idx > 0} {\n          return -code $st \\\n                 -errorinfo [string range $ret [expr $idx + 2] \\\n                                               [string length $ret]] \\\n                 [string range $ret 0 [expr $idx - 1]]\n       } else {\n          return -code $st $ret\n       }\n    } else {\n        return $ret\n    }\n  EOL\n=begin\n  INTERP.add_tk_procs('rb_out', 'args', <<-'EOL')\n    if {[set st [catch {eval {ruby_cmd TkCore callback} $args} ret]] != 0} {\n       #return -code $st $ret\n       set idx [string first \"\\n\\n\" $ret]\n       if {$idx > 0} {\n          return -code $st \\\n                 -errorinfo [string range $ret [expr $idx + 2] \\\n                                               [string length $ret]] \\\n                 [string range $ret 0 [expr $idx - 1]]\n       } else {\n          return -code $st $ret\n       }\n    } else {\n        return $ret\n    }\n  EOL\n=end\n=begin\n  INTERP.add_tk_procs('rb_out', 'args', <<-'EOL')\n    #regsub -all {\\\\} $args {\\\\\\\\} args\n    #regsub -all {!} $args {\\\\!} args\n    #regsub -all \"{\" $args \"\\\\{\" args\n    regsub -all {(\\\\|!|\\{|\\})} $args {\\\\\\1} args\n    if {[set st [catch {ruby [format \"TkCore.callback %%Q!%s!\" $args]} ret]] != 0} {\n       #return -code $st $ret\n       set idx [string first \"\\n\\n\" $ret]\n       if {$idx > 0} {\n          return -code $st \\\n                 -errorinfo [string range $ret [expr $idx + 2] \\\n                                               [string length $ret]] \\\n                 [string range $ret 0 [expr $idx - 1]]\n       } else {\n          return -code $st $ret\n       }\n    } else {\n        return $ret\n    }\n  EOL\n=end\n\n  at_exit{ INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) }\n\n  EventFlag = TclTkLib::EventFlag\n\n  def callback_break\n    fail TkCallbackBreak, \"Tk callback returns 'break' status\"\n  end\n\n  def callback_continue\n    fail TkCallbackContinue, \"Tk callback returns 'continue' status\"\n  end\n\n  def callback_return\n    fail TkCallbackReturn, \"Tk callback returns 'return' status\"\n  end\n\n  def TkCore.callback(*arg)\n    begin\n      if TkCore::INTERP.tk_cmd_tbl.kind_of?(Hash)\n        #TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)\n        normal_ret = false\n        ret = catch(:IRB_EXIT) do  # IRB hack\n          retval = TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)\n          normal_ret = true\n          retval\n        end\n        unless normal_ret\n          # catch IRB_EXIT\n          exit(ret)\n        end\n        ret\n      end\n    rescue SystemExit=>e\n      exit(e.status)\n    rescue Interrupt=>e\n      fail(e)\n    rescue Exception => e\n      begin\n        msg = _toUTF8(e.class.inspect) + ': ' + \n              _toUTF8(e.message) + \"\\n\" + \n              \"\\n---< backtrace of Ruby side >-----\\n\" + \n              _toUTF8(e.backtrace.join(\"\\n\")) + \n              \"\\n---< backtrace of Tk side >-------\"\n        if TkCore::WITH_ENCODING\n          msg.force_encoding('utf-8')\n        else\n          msg.instance_variable_set(:@encoding, 'utf-8')\n        end\n      rescue Exception\n        msg = e.class.inspect + ': ' + e.message + \"\\n\" + \n              \"\\n---< backtrace of Ruby side >-----\\n\" + \n              e.backtrace.join(\"\\n\") + \n              \"\\n---< backtrace of Tk side >-------\"\n      end\n      # TkCore::INTERP._set_global_var('errorInfo', msg)\n      # fail(e)\n      fail(e, msg)\n    end\n  end\n=begin\n  def TkCore.callback(arg_str)\n    # arg = tk_split_list(arg_str)\n    arg = tk_split_simplelist(arg_str)\n    #_get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg))\n    #_get_eval_string(TkUtil.eval_cmd(TkCore::INTERP.tk_cmd_tbl[arg.shift], \n    #                        *arg))\n    # TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)\n    begin\n      TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg)\n    rescue Exception => e\n      raise(e, e.class.inspect + ': ' + e.message + \"\\n\" + \n               \"\\n---< backtrace of Ruby side >-----\\n\" + \n               e.backtrace.join(\"\\n\") + \n               \"\\n---< backtrace of Tk side >-------\")\n    end\n#=begin\n#    cb_obj = TkCore::INTERP.tk_cmd_tbl[arg.shift]\n#    unless $DEBUG\n#      cb_obj.call(*arg)\n#    else\n#      begin\n#       raise 'check backtrace'\n#      rescue\n#       # ignore backtrace before 'callback'\n#       pos = -($!.backtrace.size)\n#      end\n#      begin\n#       cb_obj.call(*arg)\n#      rescue\n#       trace = $!.backtrace\n#       raise $!, \"\\n#{trace[0]}: #{$!.message} (#{$!.class})\\n\" + \n#                 \"\\tfrom #{trace[1..pos].join(\"\\n\\tfrom \")}\"\n#      end\n#    end\n#=end\n  end\n=end\n\n  def load_cmd_on_ip(tk_cmd)\n    bool(tk_call('auto_load', tk_cmd))\n  end\n\n  def after(ms, cmd=Proc.new)\n    cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})\n    after_id = tk_call_without_enc(\"after\",ms,cmdid)\n    after_id.instance_variable_set('@cmdid', cmdid)\n    after_id\n  end\n=begin\n  def after(ms, cmd=Proc.new)\n    crit_bup = Thread.critical\n    Thread.critical = true\n\n    myid = _curr_cmd_id\n    cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret})\n\n    Thread.critical = crit_bup\n\n    tk_call_without_enc(\"after\",ms,cmdid)  # return id\n#    return\n#    if false #defined? Thread\n#      Thread.start do\n#       ms = Float(ms)/1000\n#       ms = 10 if ms == 0\n#       sleep ms/1000\n#       cmd.call\n#      end\n#    else\n#      cmdid = install_cmd(cmd)\n#      tk_call(\"after\",ms,cmdid)\n#    end\n  end\n=end\n\n  def after_idle(cmd=Proc.new)\n    cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})\n    after_id = tk_call_without_enc('after','idle',cmdid)\n    after_id.instance_variable_set('@cmdid', cmdid)\n    after_id\n  end\n=begin\n  def after_idle(cmd=Proc.new)\n    crit_bup = Thread.critical\n    Thread.critical = true\n\n    myid = _curr_cmd_id\n    cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret})\n\n    Thread.critical = crit_bup\n\n    tk_call_without_enc('after','idle',cmdid)\n  end\n=end\n\n  def after_cancel(afterId)\n    tk_call_without_enc('after','cancel',afterId)\n    if (cmdid = afterId.instance_variable_get('@cmdid'))\n      afterId.instance_variable_set('@cmdid', nil)\n      uninstall_cmd(cmdid)\n    end\n    afterId\n  end\n\n  def windowingsystem\n    tk_call_without_enc('tk', 'windowingsystem')\n  end\n\n  def scaling(scale=nil)\n    if scale\n      tk_call_without_enc('tk', 'scaling', scale)\n    else\n      Float(number(tk_call_without_enc('tk', 'scaling')))\n    end\n  end\n  def scaling_displayof(win, scale=nil)\n    if scale\n      tk_call_without_enc('tk', 'scaling', '-displayof', win, scale)\n    else\n      Float(number(tk_call_without_enc('tk', '-displayof', win, 'scaling')))\n    end\n  end\n\n  def inactive\n    Integer(tk_call_without_enc('tk', 'inactive'))\n  end\n  def inactive_displayof(win)\n    Integer(tk_call_without_enc('tk', 'inactive', '-displayof', win))\n  end\n  def reset_inactive\n    tk_call_without_enc('tk', 'inactive', 'reset')\n  end\n  def reset_inactive_displayof(win)\n    tk_call_without_enc('tk', 'inactive', '-displayof', win, 'reset')\n  end\n\n  def appname(name=None)\n    tk_call('tk', 'appname', name)\n  end\n\n  def appsend_deny\n    tk_call('rename', 'send', '')\n  end\n\n  def appsend(interp, async, *args)\n    if $SAFE >= 4\n      fail SecurityError, \"cannot send Tk commands at level 4\"\n    elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}\n      fail SecurityError, \"cannot send tainted Tk commands at level #{$SAFE}\"\n    end\n    if async != true && async != false && async != nil\n      args.unshift(async)\n      async = false\n    end\n    if async\n      tk_call('send', '-async', '--', interp, *args)\n    else\n      tk_call('send', '--', interp, *args)\n    end\n  end\n\n  def rb_appsend(interp, async, *args)\n    if $SAFE >= 4\n      fail SecurityError, \"cannot send Ruby commands at level 4\"\n    elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}\n      fail SecurityError, \"cannot send tainted Ruby commands at level #{$SAFE}\"\n    end\n    if async != true && async != false && async != nil\n      args.unshift(async)\n      async = false\n    end\n    #args = args.collect!{|c| _get_eval_string(c).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&')}\n    args = args.collect!{|c| _get_eval_string(c).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&')}\n    # args.push(').to_s\"')\n    # appsend(interp, async, 'ruby \"(', *args)\n    args.push('}.call)\"')\n    appsend(interp, async, 'ruby \"TkComm._get_eval_string(proc{', *args)\n  end\n\n  def appsend_displayof(interp, win, async, *args)\n    if $SAFE >= 4\n      fail SecurityError, \"cannot send Tk commands at level 4\"\n    elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}\n      fail SecurityError, \"cannot send tainted Tk commands at level #{$SAFE}\"\n    end\n    win = '.' if win == nil\n    if async != true && async != false && async != nil\n      args.unshift(async)\n      async = false\n    end\n    if async\n      tk_call('send', '-async', '-displayof', win, '--', interp, *args)\n    else\n      tk_call('send', '-displayor', win, '--', interp, *args)\n    end\n  end\n\n  def rb_appsend_displayof(interp, win, async, *args)\n    if $SAFE >= 4\n      fail SecurityError, \"cannot send Ruby commands at level 4\"\n    elsif $SAFE >= 1 && args.find{|obj| obj.tainted?}\n      fail SecurityError, \"cannot send tainted Ruby commands at level #{$SAFE}\"\n    end\n    win = '.' if win == nil\n    if async != true && async != false && async != nil\n      args.unshift(async)\n      async = false\n    end\n    #args = args.collect!{|c| _get_eval_string(c).gsub(/[\\[\\]$\"]/, '\\\\\\\\\\&')}\n    args = args.collect!{|c| _get_eval_string(c).gsub(/[\\[\\]$\"\\\\]/, '\\\\\\\\\\&')}\n    # args.push(').to_s\"')\n    # appsend_displayof(interp, win, async, 'ruby \"(', *args)\n    args.push('}.call)\"')\n    appsend(interp, win, async, 'ruby \"TkComm._get_eval_string(proc{', *args)\n  end\n\n  def info(*args)\n    tk_call('info', *args)\n  end\n\n  def mainloop(check_root = true)\n    if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD\n      TclTkLib.mainloop(check_root)\n    else ### Ruby 1.9 !!!!!\n      begin\n        TclTkLib.set_eventloop_window_mode(true)\n        if check_root\n          INTERP_MUTEX.synchronize{\n            INTERP_ROOT_CHECK.wait(INTERP_MUTEX)\n            status = INTERP_THREAD[:status]\n            if status\n              INTERP_THREAD[:status] = nil\n              raise status if status.kind_of?(Exception)\n            end\n          }\n        else\n          INTERP_THREAD.value\n        end\n      ensure\n        TclTkLib.set_eventloop_window_mode(false)\n      end\n    end\n  end\n\n  def mainloop_thread?\n    # true  : current thread is mainloop\n    # nil   : there is no mainloop\n    # false : mainloop is running on the other thread\n    #         ( At then, it is dangerous to call Tk interpreter directly. )\n    if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD\n      ### Ruby 1.9 !!!!!!!!!!!\n      TclTkLib.mainloop_thread?\n    else\n      Thread.current == INTERP_THREAD\n    end\n  end\n\n  def mainloop_exist?\n    TclTkLib.mainloop_thread? != nil\n  end\n\n  def is_mainloop?\n    TclTkLib.mainloop_thread? == true\n  end\n\n  def mainloop_watchdog(check_root = true)\n    # watchdog restarts mainloop when mainloop is dead\n    TclTkLib.mainloop_watchdog(check_root)\n  end\n\n  def do_one_event(flag = TclTkLib::EventFlag::ALL)\n    TclTkLib.do_one_event(flag)\n  end\n\n  def set_eventloop_tick(timer_tick)\n    TclTkLib.set_eventloop_tick(timer_tick)\n  end\n\n  def get_eventloop_tick()\n    TclTkLib.get_eventloop_tick\n  end\n\n  def set_no_event_wait(wait)\n    TclTkLib.set_no_even_wait(wait)\n  end\n\n  def get_no_event_wait()\n    TclTkLib.get_no_eventloop_wait\n  end\n\n  def set_eventloop_weight(loop_max, no_event_tick)\n    TclTkLib.set_eventloop_weight(loop_max, no_event_tick)\n  end\n\n  def get_eventloop_weight()\n    TclTkLib.get_eventloop_weight\n  end\n\n  def restart(app_name = nil, keys = {})\n    TkCore::INTERP.init_ip_internal\n\n    tk_call('set', 'argv0', app_name) if app_name\n    if keys.kind_of?(Hash)\n      # tk_call('set', 'argc', keys.size * 2)\n      tk_call('set', 'argv', hash_kv(keys).join(' '))\n    end\n\n    INTERP.restart\n    nil\n  end\n\n  def event_generate(win, context, keys=nil)\n    #win = win.path if win.kind_of?(TkObject)\n    if context.kind_of?(TkEvent::Event)\n      context.generate(win, ((keys)? keys: {}))\n    elsif keys\n      tk_call_without_enc('event', 'generate', win, \n                          \"<#{tk_event_sequence(context)}>\", \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc('event', 'generate', win, \n                          \"<#{tk_event_sequence(context)}>\")\n    end\n    nil\n  end\n\n  def messageBox(keys)\n    tk_call('tk_messageBox', *hash_kv(keys))\n  end\n\n  def getOpenFile(keys = nil)\n    tk_call('tk_getOpenFile', *hash_kv(keys))\n  end\n  def getMultipleOpenFile(keys = nil)\n    simplelist(tk_call('tk_getOpenFile', '-multiple', '1', *hash_kv(keys)))\n  end\n\n  def getSaveFile(keys = nil)\n    tk_call('tk_getSaveFile', *hash_kv(keys))\n  end\n  def getMultipleSaveFile(keys = nil)\n    simplelist(tk_call('tk_getSaveFile', '-multiple', '1', *hash_kv(keys)))\n  end\n\n  def chooseColor(keys = nil)\n    tk_call('tk_chooseColor', *hash_kv(keys))\n  end\n\n  def chooseDirectory(keys = nil)\n    tk_call('tk_chooseDirectory', *hash_kv(keys))\n  end\n\n  def _ip_eval_core(enc_mode, cmd_string)\n    case enc_mode\n    when nil\n      res = INTERP._eval(cmd_string)\n    when false\n      res = INTERP._eval_without_enc(cmd_string)\n    when true\n      res = INTERP._eval_with_enc(cmd_string)\n    end\n    if  INTERP._return_value() != 0\n      fail RuntimeError, res, error_at\n    end\n    return res\n  end\n  private :_ip_eval_core\n\n  def ip_eval(cmd_string)\n    _ip_eval_core(nil, cmd_string)\n  end\n\n  def ip_eval_without_enc(cmd_string)\n    _ip_eval_core(false, cmd_string)\n  end\n\n  def ip_eval_with_enc(cmd_string)\n    _ip_eval_core(true, cmd_string)\n  end\n\n  def _ip_invoke_core(enc_mode, *args)\n    case enc_mode\n    when false\n      res = INTERP._invoke_without_enc(*args)\n    when nil\n      res = INTERP._invoke(*args)\n    when true\n      res = INTERP._invoke_with_enc(*args)\n    end\n    if  INTERP._return_value() != 0\n      fail RuntimeError, res, error_at\n    end\n    return res\n  end\n  private :_ip_invoke_core\n\n  def ip_invoke(*args)\n    _ip_invoke_core(nil, *args)\n  end\n\n  def ip_invoke_without_enc(*args)\n    _ip_invoke_core(false, *args)\n  end\n\n  def ip_invoke_with_enc(*args)\n    _ip_invoke_core(true, *args)\n  end\n\n  def _tk_call_core(enc_mode, *args)\n    ### puts args.inspect if $DEBUG\n    #args.collect! {|x|ruby2tcl(x, enc_mode)}\n    #args.compact!\n    #args.flatten!\n    args = _conv_args([], enc_mode, *args)\n    puts 'invoke args => ' + args.inspect if $DEBUG\n    ### print \"=> \", args.join(\" \").inspect, \"\\n\" if $DEBUG\n    begin\n      # res = INTERP._invoke(*args).taint\n      # res = INTERP._invoke(enc_mode, *args)\n      res = _ip_invoke_core(enc_mode, *args)\n      # >>>>>  _invoke returns a TAINTED string  <<<<<\n    rescue NameError => err\n      # err = $!\n      begin\n        args.unshift \"unknown\"\n        #res = INTERP._invoke(*args).taint \n        #res = INTERP._invoke(enc_mode, *args) \n        res = _ip_invoke_core(enc_mode, *args) \n        # >>>>>  _invoke returns a TAINTED string  <<<<<\n      rescue StandardError => err2\n        fail err2 unless /^invalid command/ =~ err2.message\n        fail err\n      end\n    end\n    if  INTERP._return_value() != 0\n      fail RuntimeError, res, error_at\n    end\n    ### print \"==> \", res.inspect, \"\\n\" if $DEBUG\n    return res\n  end\n  private :_tk_call_core\n\n  def tk_call(*args)\n    _tk_call_core(nil, *args)\n  end\n\n  def tk_call_without_enc(*args)\n    _tk_call_core(false, *args)\n  end\n\n  def tk_call_with_enc(*args)\n    _tk_call_core(true, *args)\n  end\n\n  def _tk_call_to_list_core(depth, arg_enc, val_enc, *args)\n    args = _conv_args([], arg_enc, *args)\n    val = _tk_call_core(false, *args)\n    if !depth.kind_of?(Integer) || depth == 0\n      tk_split_simplelist(val, false, val_enc)\n    else\n      tk_split_list(val, depth, false, val_enc)\n    end\n  end\n  #private :_tk_call_to_list_core\n\n  def tk_call_to_list(*args)\n    _tk_call_to_list_core(-1, nil, true, *args)\n  end\n\n  def tk_call_to_list_without_enc(*args)\n    _tk_call_to_list_core(-1, false, false, *args)\n  end\n\n  def tk_call_to_list_with_enc(*args)\n    _tk_call_to_list_core(-1, true, true, *args)\n  end\n\n  def tk_call_to_simplelist(*args)\n    _tk_call_to_list_core(0, nil, true, *args)\n  end\n\n  def tk_call_to_simplelist_without_enc(*args)\n    _tk_call_to_list_core(0, false, false, *args)\n  end\n\n  def tk_call_to_simplelist_with_enc(*args)\n    _tk_call_to_list_core(0, true, true, *args)\n  end\nend\n\n\nmodule Tk\n  include TkCore\n  extend Tk\n\n  TCL_VERSION = INTERP._invoke_without_enc(\"info\", \"tclversion\").freeze\n  TCL_PATCHLEVEL = INTERP._invoke_without_enc(\"info\", \"patchlevel\").freeze\n\n  major, minor = TCL_VERSION.split('.')\n  TCL_MAJOR_VERSION = major.to_i\n  TCL_MINOR_VERSION = minor.to_i\n\n  TK_VERSION  = INTERP._invoke_without_enc(\"set\", \"tk_version\").freeze\n  TK_PATCHLEVEL  = INTERP._invoke_without_enc(\"set\", \"tk_patchLevel\").freeze\n\n  major, minor = TK_VERSION.split('.')\n  TK_MAJOR_VERSION = major.to_i\n  TK_MINOR_VERSION = minor.to_i\n\n  JAPANIZED_TK = (INTERP._invoke_without_enc(\"info\", \"commands\", \n                                             \"kanji\") != \"\").freeze\n\n  def Tk.const_missing(sym)\n    case(sym)\n    when :TCL_LIBRARY\n      INTERP._invoke_without_enc('global', 'tcl_library')\n      INTERP._invoke(\"set\", \"tcl_library\").freeze\n\n    when :TK_LIBRARY\n      INTERP._invoke_without_enc('global', 'tk_library')\n      INTERP._invoke(\"set\", \"tk_library\").freeze\n\n    when :LIBRARY\n      INTERP._invoke(\"info\", \"library\").freeze\n\n    #when :PKG_PATH, :PACKAGE_PATH, :TCL_PACKAGE_PATH\n    #  INTERP._invoke_without_enc('global', 'tcl_pkgPath')\n    #  tk_split_simplelist(INTERP._invoke('set', 'tcl_pkgPath'))\n\n    #when :LIB_PATH, :LIBRARY_PATH, :TCL_LIBRARY_PATH\n    #  INTERP._invoke_without_enc('global', 'tcl_libPath')\n    #  tk_split_simplelist(INTERP._invoke('set', 'tcl_libPath'))\n\n    when :PLATFORM, :TCL_PLATFORM\n      if $SAFE >= 4\n        fail SecurityError, \"can't get #{sym} when $SAFE >= 4\"\n      end\n      INTERP._invoke_without_enc('global', 'tcl_platform')\n      Hash[*tk_split_simplelist(INTERP._invoke_without_enc('array', 'get', \n                                                           'tcl_platform'))]\n\n    when :ENV\n      INTERP._invoke_without_enc('global', 'env')\n      Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'env'))]\n\n    #when :AUTO_PATH   #<=== \n    #  tk_split_simplelist(INTERP._invoke('set', 'auto_path'))\n\n    #when :AUTO_OLDPATH\n    #  tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath'))\n\n    when :AUTO_INDEX\n      INTERP._invoke_without_enc('global', 'auto_index')\n      Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'auto_index'))]\n\n    when :PRIV, :PRIVATE, :TK_PRIV\n      priv = {}\n      if INTERP._invoke_without_enc('info', 'vars', 'tk::Priv') != \"\"\n        var_nam = 'tk::Priv'\n      else\n        var_nam = 'tkPriv'\n      end\n      INTERP._invoke_without_enc('global', var_nam)\n      Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', \n                                               var_nam))].each{|k,v|\n        k.freeze\n        case v\n        when /^-?\\d+$/\n          priv[k] = v.to_i\n        when /^-?\\d+\\.?\\d*(e[-+]?\\d+)?$/\n          priv[k] = v.to_f\n        else\n          priv[k] = v.freeze\n        end\n      }\n      priv\n\n    else\n      raise NameError, 'uninitialized constant Tk::' + sym.id2name\n    end\n  end\n\n  def Tk.errorInfo\n    INTERP._invoke_without_enc('global', 'errorInfo')\n    INTERP._invoke_without_enc('set', 'errorInfo')\n  end\n\n  def Tk.errorCode\n    INTERP._invoke_without_enc('global', 'errorCode')\n    code = tk_split_simplelist(INTERP._invoke_without_enc('set', 'errorCode'))\n    case code[0]\n    when 'CHILDKILLED', 'CHILDSTATUS', 'CHILDSUSP'\n      begin\n        pid = Integer(code[1])\n        code[1] = pid\n      rescue\n      end\n    end\n    code\n  end\n\n  def Tk.has_mainwindow?\n    INTERP.has_mainwindow?\n  end\n\n  def root\n    Tk::Root.new\n  end\n\n  def Tk.load_tclscript(file, enc=nil)\n    if enc\n      # TCL_VERSION >= 8.5\n      tk_call('source', '-encoding', enc, file)\n    else\n      tk_call('source', file)\n    end\n  end\n\n  def Tk.load_tcllibrary(file, pkg_name=None, interp=None)\n    tk_call('load', file, pkg_name, interp)\n  end\n\n  def Tk.unload_tcllibrary(*args)\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n      nocomp = (keys['nocomplain'])? '-nocomplain': None\n      keeplib = (keys['keeplibrary'])? '-keeplibrary': None\n      tk_call('unload', nocomp, keeplib, '--', *args)\n    else\n      tk_call('unload', *args)\n    end\n  end\n\n  def Tk.pkgconfig_list(mod)\n    # Tk8.5 feature\n    if mod.kind_of?(Module)\n      if mod.respond_to?(:package_name)\n        pkgname = mod.package_name\n      elsif mod.const_defined?(:PACKAGE_NAME)\n        pkgname = mod::PACKAGE_NAME\n      else\n        fail NotImplementedError, 'may not be a module for a Tcl extension'\n      end\n    else\n      pkgname = mod.to_s\n    end\n\n    pkgname = '::' << pkgname unless pkgname =~ /^::/\n\n    tk_split_list(tk_call(pkgname + '::pkgconfig', 'list'))\n  end\n\n  def Tk.pkgconfig_get(mod, key)\n    # Tk8.5 feature\n    if mod.kind_of?(Module)\n      if mod.respond_to?(:package_name)\n        pkgname = mod.package_name\n      else\n        fail NotImplementedError, 'may not be a module for a Tcl extension'\n      end\n    else\n      pkgname = mod.to_s\n    end\n\n    pkgname = '::' << pkgname unless pkgname =~ /^::/\n\n    tk_call(pkgname + '::pkgconfig', 'get', key)\n  end\n\n  def Tk.tcl_pkgconfig_list\n    # Tk8.5 feature\n    Tk.pkgconfig_list('::tcl')\n  end\n\n  def Tk.tcl_pkgconfig_get(key)\n    # Tk8.5 feature\n    Tk.pkgconfig_get('::tcl', key)\n  end\n\n  def Tk.tk_pkgconfig_list\n    # Tk8.5 feature\n    Tk.pkgconfig_list('::tk')\n  end\n\n  def Tk.tk_pkgconfig_get(key)\n    # Tk8.5 feature\n    Tk.pkgconfig_get('::tk', key)\n  end\n\n  def Tk.bell(nice = false)\n    if nice\n      tk_call_without_enc('bell', '-nice')\n    else\n      tk_call_without_enc('bell')\n    end\n    nil\n  end\n\n  def Tk.bell_on_display(win, nice = false)\n    if nice\n      tk_call_without_enc('bell', '-displayof', win, '-nice')\n    else\n      tk_call_without_enc('bell', '-displayof', win)\n    end\n    nil\n  end\n\n  def Tk.destroy(*wins)\n    #tk_call_without_enc('destroy', *wins)\n    tk_call_without_enc('destroy', *(wins.collect{|win|\n                                       if win.kind_of?(TkWindow)\n                                         win.epath\n                                       else\n                                         win\n                                       end\n                                     }))\n  end\n\n  def Tk.exit\n    tk_call_without_enc('destroy', '.')\n  end\n\n  ################################################\n\n  def Tk.sleep(ms = nil, id = nil)\n    if id\n      var = (id.kind_of?(TkVariable))? id: TkVarAccess.new(id.to_s)\n    else\n      var = TkVariable.new\n    end\n\n    var.value = tk_call_without_enc('after', ms, proc{ var.value = 0 }) if ms\n    var.thread_wait\n    ms\n  end\n\n  def Tk.wakeup(id)\n    ((id.kind_of?(TkVariable))? id: TkVarAccess.new(id.to_s)).value = 0\n    nil\n  end\n\n  ################################################\n\n  def Tk.pack(*args)\n    TkPack.configure(*args)\n  end\n  def Tk.pack_forget(*args)\n    TkPack.forget(*args)\n  end\n  def Tk.unpack(*args)\n    TkPack.forget(*args)\n  end\n\n  def Tk.grid(*args)\n    TkGrid.configure(*args)\n  end\n  def Tk.grid_forget(*args)\n    TkGrid.forget(*args)\n  end\n  def Tk.ungrid(*args)\n    TkGrid.forget(*args)\n  end\n\n  def Tk.place(*args)\n    TkPlace.configure(*args)\n  end\n  def Tk.place_forget(*args)\n    TkPlace.forget(*args)\n  end\n  def Tk.unplace(*args)\n    TkPlace.forget(*args)\n  end\n\n  def Tk.update(idle=nil)\n    if idle\n      tk_call_without_enc('update', 'idletasks')\n    else\n      tk_call_without_enc('update')\n    end\n  end\n  def Tk.update_idletasks\n    update(true)\n  end\n  def update(idle=nil)\n    # only for backward compatibility (This never be recommended to use)\n    Tk.update(idle)\n    self\n  end\n\n  # NOTE::\n  #   If no eventloop-thread is running, \"thread_update\" method is same \n  #   to \"update\" method. Else, \"thread_update\" method waits to complete \n  #   idletask operation on the eventloop-thread. \n  def Tk.thread_update(idle=nil)\n    if idle\n      tk_call_without_enc('thread_update', 'idletasks')\n    else\n      tk_call_without_enc('thread_update')\n    end\n  end\n  def Tk.thread_update_idletasks\n    thread_update(true)\n  end\n\n  def Tk.lower_window(win, below=None)\n    tk_call('lower', _epath(win), _epath(below))\n    nil\n  end\n  def Tk.raise_window(win, above=None)\n    tk_call('raise', _epath(win), _epath(above))\n    nil\n  end\n\n  def Tk.current_grabs(win = nil)\n    if win\n      window(tk_call_without_enc('grab', 'current', win))\n    else\n      tk_split_list(tk_call_without_enc('grab', 'current'))\n    end\n  end\n\n  def Tk.focus(display=nil)\n    if display == nil\n      window(tk_call_without_enc('focus'))\n    else\n      window(tk_call_without_enc('focus', '-displayof', display))\n    end\n  end\n\n  def Tk.focus_to(win, force=false)\n    if force\n      tk_call_without_enc('focus', '-force', win)\n    else\n      tk_call_without_enc('focus', win)\n    end\n  end\n\n  def Tk.focus_lastfor(win)\n    window(tk_call_without_enc('focus', '-lastfor', win))\n  end\n\n  def Tk.focus_next(win)\n    TkManageFocus.next(win)\n  end\n\n  def Tk.focus_prev(win)\n    TkManageFocus.prev(win)\n  end\n\n  def Tk.strictMotif(mode=None)\n    bool(tk_call_without_enc('set', 'tk_strictMotif', mode))\n  end\n\n  def Tk.show_kinsoku(mode='both')\n    begin\n      if /^8\\.*/ === TK_VERSION  && JAPANIZED_TK\n        tk_split_simplelist(tk_call('kinsoku', 'show', mode))\n      end\n    rescue\n    end\n  end\n  def Tk.add_kinsoku(chars, mode='both')\n    begin\n      if /^8\\.*/ === TK_VERSION  && JAPANIZED_TK\n        tk_split_simplelist(tk_call('kinsoku', 'add', mode, \n                                    *(chars.split(''))))\n      else\n        []\n      end\n    rescue\n      []\n    end\n  end\n  def Tk.delete_kinsoku(chars, mode='both')\n    begin\n      if /^8\\.*/ === TK_VERSION  && JAPANIZED_TK\n        tk_split_simplelist(tk_call('kinsoku', 'delete', mode, \n                            *(chars.split(''))))\n      end\n    rescue\n    end\n  end\n\n  def Tk.toUTF8(str, encoding = nil)\n    _toUTF8(str, encoding)\n  end\n  \n  def Tk.fromUTF8(str, encoding = nil)\n    _fromUTF8(str, encoding)\n  end\nend\n\n###########################################\n#  string with Tcl's encoding\n###########################################\nmodule Tk\n  def Tk.subst_utf_backslash(str)\n    Tk::EncodedString.subst_utf_backslash(str)\n  end\n  def Tk.subst_tk_backslash(str)\n    Tk::EncodedString.subst_tk_backslash(str)\n  end\n  def Tk.utf_to_backslash_sequence(str)\n    Tk::EncodedString.utf_to_backslash_sequence(str)\n  end\n  def Tk.utf_to_backslash(str)\n    Tk::EncodedString.utf_to_backslash_sequence(str)\n  end\n  def Tk.to_backslash_sequence(str)\n    Tk::EncodedString.to_backslash_sequence(str)\n  end\nend\n\n\n###########################################\n#  convert kanji string to/from utf-8\n###########################################\nif (/^(8\\.[1-9]|9\\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)\n  module Tk\n    module Encoding\n      extend Encoding\n\n      TkCommandNames = ['encoding'.freeze].freeze\n\n      #############################################\n\n      if TkCore::WITH_ENCODING ### Ruby 1.9\n        RubyEncoding = ::Encoding\n\n        # for saving GC cost\n        #ENCNAMES_CMD = ['encoding'.freeze, 'names'.freeze]\n        BINARY_NAME  = 'binary'.freeze\n        UTF8_NAME    = 'utf-8'.freeze\n        DEFAULT_EXTERNAL_NAME = RubyEncoding.default_external.name.freeze\n\n        BINARY  = RubyEncoding.find(BINARY_NAME)\n        UNKNOWN = RubyEncoding.find('ASCII-8BIT')\n\n        ### start of creating ENCODING_TABLE\n        ENCODING_TABLE = TkCore::INTERP.encoding_table\n=begin\n        ENCODING_TABLE = {\n          'binary'       => BINARY, \n          # 'UNKNOWN-8BIT' => UNKNOWN, \n        }\n\n        list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], \n                                                  ENCNAMES_CMD[1])\n        TkCore::INTERP._split_tklist(list).each{|name|\n          begin\n            enc = RubyEncoding.find(name)\n          rescue ArgumentError\n            case name\n            when 'identity'\n              enc = BINARY\n            when 'shiftjis'\n              enc = RubyEncoding.find('Shift_JIS')\n            when 'unicode'\n              enc = RubyEncoding.find('UTF-8')\n              #if Tk.tk_call('set', 'tcl_platform(byteOrder)') =='littleEndian'\n              #  enc = RubyEncoding.find('UTF-16LE')\n              #else\n              #  enc = RubyEncoding.find('UTF-16BE')\n              #end\n            when 'symbol'\n              # single byte data\n              enc = RubyEncoding.find('ASCII-8BIT') ### ???\n            else\n              # unsupported on Ruby, but supported on Tk\n              enc = TkCore::INTERP.create_dummy_encoding_for_tk(name)\n            end\n          end\n          ENCODING_TABLE[name.freeze] = enc\n        }\n=end\n=begin\n        def ENCODING_TABLE.get_name(enc)\n          orig_enc = enc\n\n          # unles enc, use system default\n          #  1st: Ruby/Tk default encoding\n          #  2nd: Tcl/Tk default encoding\n          #  3rd: Ruby's default_external\n          enc ||= TkCore::INTERP.encoding\n          enc ||= TclTkLib.encoding_system\n          enc ||= DEFAULT_EXTERNAL_NAME\n\n          if enc.kind_of?(RubyEncoding)\n            # Ruby's Encoding object\n            if (name = self.key(enc))\n              return name\n            end\n\n            # Is it new ?\n            list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], \n                                                      ENCNAMES_CMD[1])\n            TkComm.simplelist(list).each{|name|\n              if ((enc == RubyEncoding.find(name)) rescue false)\n                # new relation!! update table\n                self[name.freeze] = enc\n                return name\n              end\n            }\n          else\n            # String or Symbol ?\n            if self[name = enc.to_s]\n              return name\n            end\n\n            # Is it new ?\n            if (enc_obj = (RubyEncoding.find(name) rescue false))\n              list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], \n                                                        ENCNAMES_CMD[1])\n              if TkComm.simplelist(list).index(name)\n                # Tk's encoding name ?\n                self[name.freeze] = enc_obj  # new relation!! update table\n                return name\n              else\n                # Ruby's encoding name ?\n                if (name = self.key(enc_obj))\n                  return name\n                end\n              end\n            end\n          end\n\n          fail ArgumentError, \"unsupported Tk encoding '#{orig_enc}'\"\n        end\n\n        def ENCODING_TABLE.get_obj(enc)\n          # returns the encoding object.\n          # If 'enc' is the encoding name on Tk only, it returns nil.\n          ((obj = self[self.get_name(enc)]).kind_of?(RubyEncoding))? obj: nil\n        end\n=end\n        ### end of creating ENCODING_TABLE\n\n      end\n\n      #############################################\n\n      if TkCore::WITH_ENCODING\n        ################################\n        ### Ruby 1.9\n        ################################\n        def force_default_encoding(mode)\n          TkCore::INTERP.force_default_encoding = mode\n        end\n\n        def force_default_encoding?\n          TkCore::INTERP.force_default_encoding?\n        end\n\n        def default_encoding=(enc)\n          TkCore::INTERP.default_encoding = Tk::Encoding::ENCODING_TABLE.get_name(enc)\n        end\n\n        def encoding=(enc)\n          TkCore::INTERP.encoding = Tk::Encoding::ENCODING_TABLE.get_name(enc)\n        end\n\n        def encoding_name\n          Tk::Encoding::ENCODING_TABLE.get_name(TkCore::INTERP.encoding)\n        end\n        def encoding_obj\n          Tk::Encoding::ENCODING_TABLE.get_obj(TkCore::INTERP.encoding)\n        end\n        alias encoding encoding_name\n        alias default_encoding encoding_name\n\n        def tk_encoding_names\n          TkComm.simplelist(TkCore::INTERP._invoke_without_enc(Tk::Encoding::ENCNAMES_CMD[0], Tk::Encoding::ENCNAMES_CMD[1]))\n       end\n        def encoding_names\n          self.tk_encoding_names.find_all{|name|\n            Tk::Encoding::ENCODING_TABLE.get_name(name) rescue false\n          }\n        end\n        def encoding_objs\n          self.tk_encoding_names.map!{|name|\n            Tk::Encoding::ENCODING_TABLE.get_obj(name) rescue nil\n          }.compact\n        end\n\n        def encoding_system=(enc)\n          TclTkLib.encoding_system = Tk::Encoding::ENCODING_TABLE.get_name(enc)\n        end\n\n        def encoding_system_name\n          Tk::Encoding::ENCODING_TABLE.get_name(TclTkLib.encoding_system)\n        end\n        def encoding_system_obj\n          Tk::Encoding::ENCODING_TABLE.get_obj(TclTkLib.encoding_system)\n        end\n        alias encoding_system encoding_system_name\n\n        ################################\n      else\n        ################################\n        ### Ruby 1.8-\n        ################################\n        def force_default_encoding=(mode)\n          true\n        end\n\n        def force_default_encoding?\n          true\n        end\n\n        def default_encoding=(enc)\n          TkCore::INTERP.default_encoding = enc\n        end\n\n        def encoding=(enc)\n          TkCore::INTERP.encoding = enc\n        end\n\n        def encoding_obj\n          TkCore::INTERP.encoding\n        end\n        def encoding_name\n          TkCore::INTERP.encoding\n        end\n        alias encoding encoding_name\n        alias default_encoding encoding_name\n\n        def tk_encoding_names\n          TkComm.simplelist(Tk.tk_call('encoding', 'names'))\n        end\n        def encoding_objs\n          self.tk_encoding_names\n        end\n        def encoding_names\n          self.tk_encoding_names\n        end\n\n        def encoding_system=(enc)\n          TclTkLib.encoding_system = enc\n        end\n\n        def encoding_system_name\n          TclTkLib.encoding_system\n        end\n        def encoding_system_obj\n          TclTkLib.encoding_system\n        end\n        alias encoding_system encoding_system_name\n\n        ################################\n      end\n\n      def encoding_convertfrom(str, enc=nil)\n        enc = encoding_system_name unless enc\n        str = str.dup\n        if TkCore::WITH_ENCODING\n          if str.kind_of?(Tk::EncodedString)\n            str.__instance_variable_set('@encoding', nil)\n          else\n            str.instance_variable_set('@encoding', nil)\n          end\n          str.force_encoding('binary')\n        else\n          str.instance_variable_set('@encoding', 'binary')\n        end\n        ret = TkCore::INTERP._invoke_without_enc('encoding', 'convertfrom', \n                                                 enc, str)\n        if TkCore::WITH_ENCODING\n          ret.force_encoding('utf-8')\n        else\n          Tk::UTF8_String.new(ret)\n        end\n        ret\n      end\n      alias encoding_convert_from encoding_convertfrom\n\n      def encoding_convertto(str, enc=nil)\n        # str must be a UTF-8 string\n        enc = encoding_system_name unless enc\n        ret = TkCore::INTERP._invoke_without_enc('encoding', 'convertto', \n                                                 enc, str)\n        #ret.instance_variable_set('@encoding', 'binary')\n        if TkCore::WITH_ENCODING\n          #ret.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj('binary'))\n          ret.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj(enc))\n        end\n        ret\n      end\n      alias encoding_convert_to encoding_convertto\n\n      def encoding_dirs\n        # Tcl8.5 feature\n        TkComm.simplelist(Tk.tk_call_without_enc('encoding', 'dirs'))\n      end\n\n      def encoding_dirs=(dir_list) # an array or a Tcl's list string\n        # Tcl8.5 feature\n        Tk.tk_call_without_enc('encoding', 'dirs', dir_list)\n      end\n    end\n\n    extend Encoding\n  end\n\n  class TclTkIp\n    def force_default_encoding=(mode)\n      @force_default_encoding = (mode)? true: false\n    end\n\n    def force_default_encoding?\n      @force_default_encoding ||= false\n    end\n\n    def default_encoding=(name)\n      name = name.name if name.kind_of?(::Encoding) if Tk::WITH_ENCODING\n      @encoding = name\n    end\n\n    # from tkencoding.rb by ttate@jaist.ac.jp\n    #attr_accessor :encoding\n    def encoding=(name)\n      self.force_default_encoding = true  # for comaptibility\n      self.default_encoding = name\n    end\n\n    def encoding_name\n      (@encoding)? @encoding.dup: nil\n    end\n    alias encoding encoding_name\n    alias default_encoding encoding_name\n\n    def encoding_obj\n      if Tk::WITH_ENCODING\n        Tk::Encoding.tcl2rb_encoding(@encoding)\n      else\n        (@encoding)? @encoding.dup: nil\n      end\n    end\n\n    alias __toUTF8 _toUTF8\n    alias __fromUTF8 _fromUTF8\n\n    if Object.const_defined?(:Encoding) && ::Encoding.class == Class\n      # with Encoding (Ruby 1.9+)\n      #\n      # use functions on Tcl as default.\n      # but when unsupported encoding on Tcl, use methods on Ruby.\n      #\n      def _toUTF8(str, enc = nil)\n        if enc\n          # use given encoding\n          begin\n            enc_name = Tk::Encoding::ENCODING_TABLE.get_name(enc)\n          rescue\n            # unknown encoding for Tk -> try to convert encoding on Ruby\n            str = str.dup.force_encoding(enc)\n            str.encode!(Tk::Encoding::UTF8_NAME) # modify self !!\n            return str  # if no error, probably succeed converting\n          end\n        end\n\n        enc_name ||= str.instance_variable_get(:@encoding)\n\n        enc_name ||= \n          Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil\n\n        unless enc_name\n          # str.encoding isn't supported by Tk -> try to convert on Ruby\n          begin\n            return str.encode(Tk::Encoding::UTF8_NAME) # new string\n          rescue\n            # error -> ignore, try to use default encoding of Ruby/Tk\n          end\n        end\n\n        #enc_name ||= \n        #  Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding) rescue nil\n        enc_name ||= Tk::Encoding::ENCODING_TABLE.get_name(nil)\n\n        # is 'binary' encoding?\n        if enc_name == Tk::Encoding::BINARY_NAME\n          return str.dup.force_encoding(Tk::Encoding::BINARY_NAME)\n        end\n\n        # force default encoding?\n        if ! str.kind_of?(Tk::EncodedString) && self.force_default_encoding?\n          enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.default_encoding)\n        end\n\n        encstr = __toUTF8(str, enc_name)\n        encstr.force_encoding(Tk::Encoding::UTF8_NAME)\n        encstr\n      end\n      def _fromUTF8(str, enc = nil)\n        # str must be UTF-8 or binary.\n        enc_name = str.instance_variable_get(:@encoding)\n        enc_name ||= \n          Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil\n\n        # is 'binary' encoding?\n        if enc_name == Tk::Encoding::BINARY_NAME\n          return str.dup.force_encoding(Tk::Encoding::BINARY_NAME)\n        end\n\n        # get target encoding name (if enc == nil, use default encoding)\n        begin\n          enc_name = Tk::Encoding::ENCODING_TABLE.get_name(enc)\n        rescue\n          # then, enc != nil\n          # unknown encoding for Tk -> try to convert encoding on Ruby\n          str = str.dup.force_encoding(Tk::Encoding::UTF8_NAME)\n          str.encode!(enc) # modify self !!\n          return str  # if no error, probably succeed converting\n        end\n\n        encstr = __fromUTF8(str, enc_name)\n        encstr.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj(enc_name))\n        encstr\n      end\n      ###\n    else\n      # without Encoding (Ruby 1.8)\n      def _toUTF8(str, encoding = nil)\n        __toUTF8(str, encoding)\n      end\n      def _fromUTF8(str, encoding = nil)\n        __fromUTF8(str, encoding)\n      end\n      ###\n    end\n\n    alias __eval _eval\n    alias __invoke _invoke\n\n    def _eval(cmd)\n      _fromUTF8(__eval(_toUTF8(cmd)))\n    end\n\n    def _invoke(*cmds)\n      _fromUTF8(__invoke(*(cmds.collect{|cmd| _toUTF8(cmd)})))\n    end\n\n    alias _eval_with_enc _eval\n    alias _invoke_with_enc _invoke\n\n=begin\n    #### --> definition is moved to TclTkIp module\n\n    def _toUTF8(str, encoding = nil)\n      # decide encoding\n      if encoding\n        encoding = encoding.to_s\n      elsif str.kind_of?(Tk::EncodedString) && str.encoding != nil\n        encoding = str.encoding.to_s\n      elsif str.instance_variable_get(:@encoding)\n        encoding = str.instance_variable_get(:@encoding).to_s\n      elsif defined?(@encoding) && @encoding != nil\n        encoding = @encoding.to_s\n      else\n        encoding = __invoke('encoding', 'system')\n      end\n\n      # convert\n      case encoding\n      when 'utf-8', 'binary'\n        str\n      else\n        __toUTF8(str, encoding)\n      end\n    end\n\n    def _fromUTF8(str, encoding = nil)\n      unless encoding\n        if defined?(@encoding) && @encoding != nil\n          encoding = @encoding.to_s\n        else\n          encoding = __invoke('encoding', 'system')\n        end\n      end\n\n      if str.kind_of?(Tk::EncodedString)\n        if str.encoding == 'binary'\n          str\n        else\n          __fromUTF8(str, encoding)\n        end\n      elsif str.instance_variable_get(:@encoding).to_s == 'binary'\n        str\n      else\n        __fromUTF8(str, encoding)\n      end\n    end\n=end\n\n=begin\n    def _eval(cmd)\n      if defined?(@encoding) && @encoding != 'utf-8'\n        ret = if cmd.kind_of?(Tk::EncodedString)\n                case cmd.encoding\n                when 'utf-8', 'binary'\n                  __eval(cmd)\n                else\n                  __eval(_toUTF8(cmd, cmd.encoding))\n                end\n              elsif cmd.instance_variable_get(:@encoding) == 'binary'\n                __eval(cmd)\n              else\n                __eval(_toUTF8(cmd, @encoding))\n              end\n        if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary'\n          ret\n        else\n          _fromUTF8(ret, @encoding)\n        end\n      else\n        __eval(cmd)\n      end\n    end\n\n    def _invoke(*cmds)\n      if defined?(@encoding) && @encoding != 'utf-8'\n        cmds = cmds.collect{|cmd|\n          if cmd.kind_of?(Tk::EncodedString)\n            case cmd.encoding\n            when 'utf-8', 'binary'\n              cmd\n            else\n              _toUTF8(cmd, cmd.encoding)\n            end\n          elsif cmd.instance_variable_get(:@encoding) == 'binary'\n            cmd\n          else\n            _toUTF8(cmd, @encoding)\n          end\n        }\n        ret = __invoke(*cmds)\n        if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary'\n          ret\n        else\n          _fromUTF8(ret, @encoding)\n        end\n      else\n        __invoke(*cmds)\n        end\n    end\n=end\n  end\n\n  module TclTkLib\n    class << self\n      def force_default_encoding=(mode)\n        TkCore::INTERP.force_default_encoding = mode\n      end\n\n      def force_default_encoding?\n        TkCore::INTERP.force_default_encoding?\n      end\n\n      def default_encoding=(name)\n        TkCore::INTERP.default_encoding = name\n      end\n\n      alias _encoding encoding\n      alias _encoding= encoding=\n      def encoding=(name)\n        name = name.name if name.kind_of?(::Encoding) if Tk::WITH_ENCODING\n        TkCore::INTERP.encoding = name\n      end\n\n      def encoding_name\n        TkCore::INTERP.encoding\n      end\n      alias encoding encoding_name\n      alias default_encoding encoding_name\n\n      def encoding_obj\n        if Tk::WITH_ENCODING\n          Tk::Encoding.tcl2rb_encoding(TkCore::INTERP.encoding)\n        else\n          TkCore::INTERP.encoding\n        end\n      end\n    end\n  end\n\n  # estimate encoding\n  unless TkCore::WITH_ENCODING \n    case $KCODE\n    when /^e/i  # EUC\n      Tk.encoding = 'euc-jp'\n      Tk.encoding_system = 'euc-jp'\n    when /^s/i  # SJIS\n      begin\n        if Tk.encoding_system == 'cp932'\n          Tk.encoding = 'cp932'\n        else\n          Tk.encoding = 'shiftjis'\n          Tk.encoding_system = 'shiftjis'\n        end\n      rescue StandardError, NameError\n        Tk.encoding = 'shiftjis'\n        Tk.encoding_system = 'shiftjis'\n      end\n    when /^u/i  # UTF8\n      Tk.encoding = 'utf-8'\n      Tk.encoding_system = 'utf-8'\n    else        # NONE\n      if defined? DEFAULT_TK_ENCODING\n        Tk.encoding_system = DEFAULT_TK_ENCODING\n      end\n      begin\n        Tk.encoding = Tk.encoding_system\n      rescue StandardError, NameError\n        Tk.encoding = 'utf-8'\n        Tk.encoding_system = 'utf-8'\n      end\n    end\n\n  else ### Ruby 1.9 !!!!!!!!!!!!\n    loc_enc_obj = ::Encoding.find(::Encoding.locale_charmap)\n    ext_enc_obj = ::Encoding.default_external\n    tksys_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding_system)\n    # p [Tk.encoding, Tk.encoding_system, loc_enc_obj, ext_enc_obj]\n\n=begin\n    if ext_enc_obj == Tk::Encoding::UNKNOWN\n      if defind? DEFAULT_TK_ENCODING\n        if DEFAULT_TK_ENCODING.kind_of?(::Encoding)\n          tk_enc_name    = DEFAULT_TK_ENCODING.name\n          tksys_enc_name = DEFAULT_TK_ENCODING.name\n        else\n          tk_enc_name    = DEFAULT_TK_ENCODING\n          tksys_enc_name = DEFAULT_TK_ENCODING\n        end\n      else\n        tk_enc_name    = loc_enc_obj.name\n        tksys_enc_name = loc_enc_obj.name\n      end\n    else\n      tk_enc_name    = ext_enc_obj.name\n      tksys_enc_name = ext_enc_obj.name\n    end\n\n    # Tk.encoding = tk_enc_name\n    Tk.default_encoding = tk_enc_name\n    Tk.encoding_system = tksys_enc_name\n=end\n\n    if ext_enc_obj == Tk::Encoding::UNKNOWN\n      if loc_enc_obj == Tk::Encoding::UNKNOWN\n        # use Tk.encoding_system\n      else\n        # use locale_charmap\n        begin\n          loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj)\n          if loc_enc_name && loc_enc_name != tksys_enc_name\n            # use locale_charmap\n            Tk.encoding_system = loc_enc_name\n          else\n            # use Tk.encoding_system\n          end\n        rescue ArgumentError\n          # unsupported encoding on Tk -> use Tk.encoding_system\n        end\n      end\n    else\n      begin\n        ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj)\n        if ext_enc_name && ext_enc_name != tksys_enc_name\n          # use default_external\n          Tk.encoding_system = ext_enc_name\n        else\n          # use Tk.encoding_system\n        end\n      rescue ArgumentError\n        # unsupported encoding on Tk -> use Tk.encoding_system\n      end\n    end\n\n    # setup Tk.encoding\n    enc_name = nil\n\n    begin\n      default_def = DEFAULT_TK_ENCODING\n      if ::Encoding.find(default_def.to_s) != Tk::Encoding::UNKNOWN\n        enc_name = Tk::Encoding::ENCODING_TABLE.get_name(default_def)\n      end\n    rescue NameError\n      # ignore\n      enc_name = nil\n    rescue ArgumentError\n      enc_name = nil\n      fail ArgumentError, \n           \"DEFAULT_TK_ENCODING has an unknown encoding #{default_def}\"\n    end\n\n    unless enc_name\n      if ext_enc_obj == Tk::Encoding::UNKNOWN\n        if loc_enc_obj == Tk::Encoding::UNKNOWN\n          # use Tk.encoding_system\n          enc_name = tksys_enc_name\n        else\n          # use locale_charmap\n          begin\n            loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj)\n            if loc_enc_name && loc_enc_name != tksys_enc_name\n              # use locale_charmap\n              enc_name = loc_enc_name\n            else\n              # use Tk.encoding_system\n              enc_name = tksys_enc_name\n            end\n          rescue ArgumentError\n            # unsupported encoding on Tk -> use Tk.encoding_system\n            enc_name = tksys_enc_name\n          end\n        end\n      else\n        begin\n          ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj)\n          if ext_enc_name && ext_enc_name != tksys_enc_name\n            # use default_external\n            enc_name = ext_enc_name\n          else\n            # use Tk.encoding_system\n            enc_name = tksys_enc_name\n          end\n        rescue ArgumentError\n          # unsupported encoding on Tk -> use Tk.encoding_system\n          enc_name = tksys_enc_name\n        end\n      end\n    end\n\n    Tk.default_encoding = (enc_name)? enc_name: tksys_enc_name\n  end\n\nelse\n  # dummy methods\n  module Tk\n    module Encoding\n      extend Encoding\n\n      def force_default_encoding=(mode)\n        nil\n      end\n\n      def force_default_encoding?\n        nil\n      end\n\n      def default_encoding=(enc)\n        nil\n      end\n      def default_encoding\n        nil\n      end\n\n      def encoding=(name)\n        nil\n      end\n      def encoding\n        nil\n      end\n      def encoding_names\n        nil\n      end\n      def encoding_system\n        nil\n      end\n      def encoding_system=(enc)\n        nil\n      end\n\n      def encoding_convertfrom(str, enc=None)\n        str\n      end\n      alias encoding_convert_from encoding_convertfrom\n\n      def encoding_convertto(str, enc=None)\n        str\n      end\n      alias encoding_convert_to encoding_convertto\n      def encoding_dirs\n        nil\n      end\n      def encoding_dirs=(dir_array)\n        nil\n      end\n    end\n\n    extend Encoding\n  end\n\n  class TclTkIp\n    attr_accessor :encoding\n\n    alias __eval _eval\n    alias __invoke _invoke\n\n    alias _eval_with_enc _eval\n    alias _invoke_with_enc _invoke\n  end\nend\n\n\nmodule TkBindCore\n  #def bind(context, cmd=Proc.new, *args)\n  #  Tk.bind(self, context, cmd, *args)\n  #end\n  def bind(context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    Tk.bind(self, context, cmd, *args)\n  end\n\n  #def bind_append(context, cmd=Proc.new, *args)\n  #  Tk.bind_append(self, context, cmd, *args)\n  #end\n  def bind_append(context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    Tk.bind_append(self, context, cmd, *args)\n  end\n\n  def bind_remove(context)\n    Tk.bind_remove(self, context)\n  end\n\n  def bindinfo(context=nil)\n    Tk.bindinfo(self, context)\n  end\nend\n\n\nmodule TkTreatFont\n  def __font_optkeys\n    ['font']\n  end\n  private :__font_optkeys\n\n  def __pathname\n    self.path\n  end\n  private :__pathname\n\n  ################################\n\n  def font_configinfo(key = nil)\n    optkeys = __font_optkeys\n    if key && !optkeys.find{|opt| opt.to_s == key.to_s}\n      fail ArgumentError, \"unknown font option name `#{key}'\"\n    end\n\n    win, tag = __pathname.split(':')\n\n    if key\n      pathname = [win, tag, key].join(';')\n      TkFont.used_on(pathname) || \n        TkFont.init_widget_font(pathname, *__confinfo_cmd)\n    elsif optkeys.size == 1\n      pathname = [win, tag, optkeys[0]].join(';')\n      TkFont.used_on(pathname) || \n        TkFont.init_widget_font(pathname, *__confinfo_cmd)\n    else\n      fonts = {}\n      optkeys.each{|key|\n        key = key.to_s\n        pathname = [win, tag, key].join(';')\n        fonts[key] = \n          TkFont.used_on(pathname) || \n          TkFont.init_widget_font(pathname, *__confinfo_cmd)\n      }\n      fonts\n    end\n  end\n  alias fontobj font_configinfo\n\n  def font_configure(slot)\n    pathname = __pathname\n\n    slot = _symbolkey2str(slot)\n\n    __font_optkeys.each{|optkey|\n      optkey = optkey.to_s\n      l_optkey = 'latin' << optkey\n      a_optkey = 'ascii' << optkey\n      k_optkey = 'kanji' << optkey\n\n      if slot.key?(optkey)\n        fnt = slot.delete(optkey)\n        if fnt.kind_of?(TkFont)\n          slot.delete(l_optkey)\n          slot.delete(a_optkey)\n          slot.delete(k_optkey)\n\n          fnt.call_font_configure([pathname, optkey], *(__config_cmd << {}))\n          next\n        else\n          if fnt\n            if (slot.key?(l_optkey) || \n                slot.key?(a_optkey) || \n                slot.key?(k_optkey))\n              fnt = TkFont.new(fnt)\n\n              lfnt = slot.delete(l_optkey)\n              lfnt = slot.delete(a_optkey) if slot.key?(a_optkey)\n              kfnt = slot.delete(k_optkey)\n\n              fnt.latin_replace(lfnt) if lfnt\n              fnt.kanji_replace(kfnt) if kfnt\n\n              fnt.call_font_configure([pathname, optkey], \n                                      *(__config_cmd << {}))\n              next\n            else\n              fnt = hash_kv(fnt) if fnt.kind_of?(Hash)\n              unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n                tk_call(*(__config_cmd << \"-#{optkey}\" << fnt))\n              else\n                begin\n                  tk_call(*(__config_cmd << \"-#{optkey}\" << fnt))\n                rescue\n                  # ignore\n                end\n              end\n            end\n          end\n          next\n        end\n      end\n\n      lfnt = slot.delete(l_optkey)\n      lfnt = slot.delete(a_optkey) if slot.key?(a_optkey)\n      kfnt = slot.delete(k_optkey)\n\n      if lfnt && kfnt\n        TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], \n                                                   *(__config_cmd << {}))\n      elsif lfnt\n        latinfont_configure([lfnt, optkey])\n      elsif kfnt\n        kanjifont_configure([kfnt, optkey])\n      end\n    }\n\n    # configure other (without font) options\n    tk_call(*(__config_cmd.concat(hash_kv(slot)))) if slot != {}\n    self\n  end\n\n  def latinfont_configure(ltn, keys=nil)\n    if ltn.kind_of?(Array)\n      key = ltn[1]\n      ltn = ltn[0]\n    else\n      key = nil\n    end\n\n    optkeys = __font_optkeys\n    if key && !optkeys.find{|opt| opt.to_s == key.to_s}\n      fail ArgumentError, \"unknown font option name `#{key}'\"\n    end\n\n    win, tag = __pathname.split(':')\n\n    optkeys = [key] if key\n\n    optkeys.each{|optkey|\n      optkey = optkey.to_s\n\n      pathname = [win, tag, optkey].join(';')\n\n      if (fobj = TkFont.used_on(pathname))\n        fobj = TkFont.new(fobj) # create a new TkFont object\n      elsif Tk::JAPANIZED_TK\n        fobj = fontobj          # create a new TkFont object\n      else\n        ltn = hash_kv(ltn) if ltn.kind_of?(Hash)\n        unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n          tk_call(*(__config_cmd << \"-#{optkey}\" << ltn))\n        else\n          begin\n            tk_call(*(__config_cmd << \"-#{optkey}\" << ltn))\n          rescue => e\n            # ignore\n          end\n        end\n        next\n      end\n\n      if fobj.kind_of?(TkFont)\n        if ltn.kind_of?(TkFont)\n          conf = {}\n          ltn.latin_configinfo.each{|key,val| conf[key] = val}\n          if keys\n            fobj.latin_configure(conf.update(keys))\n          else\n            fobj.latin_configure(conf)\n          end\n        else\n          fobj.latin_replace(ltn)\n        end\n      end\n\n      fobj.call_font_configure([pathname, optkey], *(__config_cmd << {}))\n    }\n    self\n  end\n  alias asciifont_configure latinfont_configure\n\n  def kanjifont_configure(knj, keys=nil)\n    if knj.kind_of?(Array)\n      key = knj[1]\n      knj = knj[0]\n    else\n      key = nil\n    end\n\n    optkeys = __font_optkeys\n    if key && !optkeys.find{|opt| opt.to_s == key.to_s}\n      fail ArgumentError, \"unknown font option name `#{key}'\"\n    end\n\n    win, tag = __pathname.split(':')\n\n    optkeys = [key] if key\n\n    optkeys.each{|optkey|\n      optkey = optkey.to_s\n\n      pathname = [win, tag, optkey].join(';')\n\n      if (fobj = TkFont.used_on(pathname))\n        fobj = TkFont.new(fobj) # create a new TkFont object\n      elsif Tk::JAPANIZED_TK\n        fobj = fontobj          # create a new TkFont object\n      else\n        knj = hash_kv(knj) if knj.kind_of?(Hash)\n        unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n          tk_call(*(__config_cmd << \"-#{optkey}\" << knj))\n        else\n          begin\n            tk_call(*(__config_cmd << \"-#{optkey}\" << knj))\n          rescue => e\n            # ignore\n          end\n        end\n        next\n      end\n\n      if fobj.kind_of?(TkFont)\n        if knj.kind_of?(TkFont)\n          conf = {}\n          knj.kanji_configinfo.each{|key,val| conf[key] = val}\n          if keys\n            fobj.kanji_configure(conf.update(keys))\n          else\n            fobj.kanji_configure(conf)\n          end\n        else\n          fobj.kanji_replace(knj)\n        end\n      end\n\n      fobj.call_font_configure([pathname, optkey], *(__config_cmd << {}))\n    }\n    self\n  end\n\n  def font_copy(win, wintag=nil, winkey=nil, targetkey=nil)\n    if wintag\n      if winkey\n        fnt = win.tagfontobj(wintag, winkey).dup\n      else\n        fnt = win.tagfontobj(wintag).dup\n      end\n    else\n      if winkey\n        fnt = win.fontobj(winkey).dup\n      else\n        fnt = win.fontobj.dup\n      end\n    end\n\n    if targetkey\n      fnt.call_font_configure([__pathname, targetkey], *(__config_cmd << {}))\n    else\n      fnt.call_font_configure(__pathname, *(__config_cmd << {}))\n    end\n    self\n  end\n\n  def latinfont_copy(win, wintag=nil, winkey=nil, targetkey=nil)\n    if targetkey\n      fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], \n                                                 *(__config_cmd << {}))\n    else\n      fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {}))\n    end\n\n    if wintag\n      if winkey\n        fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id)\n      else\n        fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id)\n      end\n    else\n      if winkey\n        fontobj.latin_replace(win.fontobj(winkey).latin_font_id)\n      else\n        fontobj.latin_replace(win.fontobj.latin_font_id)\n      end\n    end\n    self\n  end\n  alias asciifont_copy latinfont_copy\n\n  def kanjifont_copy(win, wintag=nil, winkey=nil, targetkey=nil)\n    if targetkey\n      fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], \n                                                 *(__config_cmd << {}))\n    else\n        fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {}))\n    end\n\n    if wintag\n      if winkey\n        fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id)\n      else\n        fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id)\n      end\n    else\n      if winkey\n        fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id)\n      else\n        fontobj.kanji_replace(win.fontobj.kanji_font_id)\n      end\n    end\n    self\n  end\nend\n\n\nmodule TkConfigMethod\n  include TkUtil\n  include TkTreatFont\n\n  def TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n    @mode || false\n  end\n  def TkConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode)\n    fail SecurityError, \"can't change the mode\" if $SAFE>=4\n    @mode = (mode)? true: false\n  end\n\n  def __cget_cmd\n    [self.path, 'cget']\n  end\n  private :__cget_cmd\n\n  def __config_cmd\n    [self.path, 'configure']\n  end\n  private :__config_cmd\n\n  def __confinfo_cmd\n    __config_cmd\n  end\n  private :__confinfo_cmd\n\n  def __configinfo_struct\n    {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, \n      :default_value=>3, :current_value=>4}\n  end\n  private :__configinfo_struct\n\n  def __optkey_aliases\n    {}\n  end\n  private :__optkey_aliases\n\n  def __numval_optkeys\n    []\n  end\n  private :__numval_optkeys\n\n  def __numstrval_optkeys\n    []\n  end\n  private :__numstrval_optkeys\n\n  def __boolval_optkeys\n    ['exportselection', 'jump', 'setgrid', 'takefocus']\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    [\n      'text', 'label', 'show', 'data', 'file', \n      'activebackground', 'activeforeground', 'background', \n      'disabledforeground', 'disabledbackground', 'foreground', \n      'highlightbackground', 'highlightcolor', 'insertbackground', \n      'selectbackground', 'selectforeground', 'troughcolor'\n    ]\n  end\n  private :__strval_optkeys\n\n  def __listval_optkeys\n    []\n  end\n  private :__listval_optkeys\n\n  def __numlistval_optkeys\n    []\n  end\n  private :__numlistval_optkeys\n\n  def __tkvariable_optkeys\n    ['variable', 'textvariable']\n  end\n  private :__tkvariable_optkeys\n\n  def __val2ruby_optkeys  # { key=>proc, ... }\n    # The method is used to convert a opt-value to a ruby's object.\n    # When get the value of the option \"key\", \"proc.call(value)\" is called.\n    {}\n  end\n  private :__val2ruby_optkeys\n\n  def __ruby2val_optkeys  # { key=>proc, ... }\n    # The method is used to convert a ruby's object to a opt-value.\n    # When set the value of the option \"key\", \"proc.call(value)\" is called.\n    # That is, \"-#{key} #{proc.call(value)}\".\n    {}\n  end\n  private :__ruby2val_optkeys\n\n  def __methodcall_optkeys  # { key=>method, ... }\n    # The method is used to both of get and set.\n    # Usually, the 'key' will not be a widget option.\n    {}\n  end\n  private :__methodcall_optkeys\n\n  def __keyonly_optkeys  # { def_key=>undef_key or nil, ... }\n    {}\n  end\n  private :__keyonly_optkeys\n\n  def __conv_keyonly_opts(keys)\n    return keys unless keys.kind_of?(Hash)\n    keyonly = __keyonly_optkeys\n    keys2 = {}\n    keys.each{|k, v|\n      optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s}\n      if optkey\n        defkey, undefkey = optkey\n        if v\n          keys2[defkey.to_s] = None\n        elsif undefkey\n          keys2[undefkey.to_s] = None\n        else\n          # remove key\n        end\n      else\n        keys2[k.to_s] = v\n      end\n    }\n    keys2\n  end\n  private :__conv_keyonly_opts\n\n  def config_hash_kv(keys, enc_mode = nil, conf = nil)\n    hash_kv(__conv_keyonly_opts(keys), enc_mode, conf)\n  end\n\n  ################################\n\n  def [](id)\n    cget(id)\n  end\n\n  def []=(id, val)\n    configure(id, val)\n    val\n  end\n\n  def __cget_core(slot)\n    orig_slot = slot\n    slot = slot.to_s\n \n   if slot.length == 0\n      fail ArgumentError, \"Invalid option `#{orig_slot.inspect}'\"\n    end\n\n    alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}\n    if real_name\n      slot = real_name.to_s\n    end\n\n    if ( method = _symbolkey2str(__val2ruby_optkeys())[slot] )\n      optval = tk_call_without_enc(*(__cget_cmd << \"-#{slot}\"))\n      begin\n        return method.call(optval)\n      rescue => e\n        warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n        return optval\n      end\n    end\n\n    if ( method = _symbolkey2str(__methodcall_optkeys)[slot] )\n      return self.__send__(method)\n    end\n\n    case slot\n    when /^(#{__numval_optkeys.join('|')})$/\n      begin\n        number(tk_call_without_enc(*(__cget_cmd << \"-#{slot}\")))\n      rescue\n        nil\n      end\n\n    when /^(#{__numstrval_optkeys.join('|')})$/\n      num_or_str(tk_call_without_enc(*(__cget_cmd << \"-#{slot}\")))\n\n    when /^(#{__boolval_optkeys.join('|')})$/\n      begin\n        bool(tk_call_without_enc(*(__cget_cmd << \"-#{slot}\")))\n      rescue\n        nil\n      end\n\n    when /^(#{__listval_optkeys.join('|')})$/\n      simplelist(tk_call_without_enc(*(__cget_cmd << \"-#{slot}\")))\n\n    when /^(#{__numlistval_optkeys.join('|')})$/\n      conf = tk_call_without_enc(*(__cget_cmd << \"-#{slot}\"))\n      if conf =~ /^[0-9+-]/\n        list(conf)\n      else\n        conf\n      end\n\n    when /^(#{__strval_optkeys.join('|')})$/\n      _fromUTF8(tk_call_without_enc(*(__cget_cmd << \"-#{slot}\")))\n\n    when /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/\n      fontcode = $1\n      fontkey  = $2\n      fnt = tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << \"-#{fontkey}\")), true)\n      unless fnt.kind_of?(TkFont)\n        fnt = fontobj(fontkey)\n      end\n      if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\\.*/\n        # obsolete; just for compatibility\n        fnt.kanji_font\n      else\n        fnt\n      end\n\n    when /^(#{__tkvariable_optkeys.join('|')})$/\n      v = tk_call_without_enc(*(__cget_cmd << \"-#{slot}\"))\n      (v.empty?)? nil: TkVarAccess.new(v)\n\n    else\n      tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << \"-#{slot}\")), true)\n    end\n  end\n  private :__cget_core\n\n  def cget(slot)\n    unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      __cget_core(slot)\n    else\n      begin\n        __cget_core(slot)\n      rescue => e\n        if current_configinfo.has_key?(slot.to_s)\n          # error on known option\n          fail e\n        else\n          # unknown option\n          nil\n        end\n      end\n    end\n  end\n  def cget_strict(slot)\n    # never use TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n    __cget_core(slot)\n  end\n\n  def __configure_core(slot, value=None)\n    if slot.kind_of? Hash\n      slot = _symbolkey2str(slot)\n\n      __optkey_aliases.each{|alias_name, real_name|\n        alias_name = alias_name.to_s\n        if slot.has_key?(alias_name)\n          slot[real_name.to_s] = slot.delete(alias_name)\n        end\n      }\n\n      __methodcall_optkeys.each{|key, method|\n        value = slot.delete(key.to_s)\n        self.__send__(method, value) if value\n      }\n\n      __ruby2val_optkeys.each{|key, method|\n        key = key.to_s\n        slot[key] = method.call(slot[key]) if slot.has_key?(key)\n      }\n\n      __keyonly_optkeys.each{|defkey, undefkey|\n        conf = slot.find{|kk, vv| kk == defkey.to_s}\n        if conf\n          k, v = conf\n          if v\n            slot[k] = None\n          else\n            slot[undefkey.to_s] = None if undefkey\n            slot.delete(k)\n          end\n        end\n      }\n\n      if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/})\n        font_configure(slot)\n      elsif slot.size > 0\n        tk_call(*(__config_cmd.concat(hash_kv(slot))))\n      end\n\n    else\n      orig_slot = slot\n      slot = slot.to_s\n      if slot.length == 0\n        fail ArgumentError, \"Invalid option `#{orig_slot.inspect}'\"\n      end\n\n      alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}\n      if real_name\n        slot = real_name.to_s\n      end\n\n      if ( conf = __keyonly_optkeys.find{|k, v| k.to_s == slot} )\n        defkey, undefkey = conf\n        if value\n          tk_call(*(__config_cmd << \"-#{defkey}\"))\n        elsif undefkey\n          tk_call(*(__config_cmd << \"-#{undefkey}\"))\n        end\n      elsif ( method = _symbolkey2str(__ruby2val_optkeys)[slot] )\n        tk_call(*(__config_cmd << \"-#{slot}\" << method.call(value)))\n      elsif ( method = _symbolkey2str(__methodcall_optkeys)[slot] )\n        self.__send__(method, value)\n      elsif (slot =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/)\n        if value == None\n          fontobj($2)\n        else\n          font_configure({slot=>value})\n        end\n      else\n        tk_call(*(__config_cmd << \"-#{slot}\" << value))\n      end\n    end\n    self\n  end\n  private :__configure_core\n\n  def __check_available_configure_options(keys)\n    availables = self.current_configinfo.keys\n\n    # add non-standard keys\n    availables |= __font_optkeys.map{|k|\n      [k.to_s, \"latin#{k}\", \"ascii#{k}\", \"kanji#{k}\"]\n    }.flatten\n    availables |= __methodcall_optkeys.keys.map{|k| k.to_s}\n    availables |= __keyonly_optkeys.keys.map{|k| k.to_s}\n\n    keys = _symbolkey2str(keys)\n    keys.delete_if{|k, v| !(availables.include?(k))}\n  end\n\n  def configure(slot, value=None)\n    unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      __configure_core(slot, value)\n    else\n      if slot.kind_of?(Hash)\n        begin\n          __configure_core(slot)\n        rescue\n          slot = __check_available_configure_options(slot)\n          __configure_core(slot) unless slot.empty?\n        end\n      else\n        begin\n          __configure_core(slot, value)\n        rescue => e\n          if current_configinfo.has_key?(slot.to_s)\n            # error on known option\n            fail e\n          else\n            # unknown option\n            nil\n          end\n        end\n      end\n    end\n    self\n  end\n\n  def configure_cmd(slot, value)\n    configure(slot, install_cmd(value))\n  end\n\n  def __configinfo_core(slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (slot && \n          slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/)\n        fontkey  = $2\n        # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{fontkey}\"))))\n        conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{fontkey}\")), false, true)\n        conf[__configinfo_struct[:key]] = \n          conf[__configinfo_struct[:key]][1..-1]\n        if ( ! __configinfo_struct[:alias] \\\n            || conf.size > __configinfo_struct[:alias] + 1 )\n          fnt = conf[__configinfo_struct[:default_value]]\n          if TkFont.is_system_font?(fnt)\n            conf[__configinfo_struct[:default_value]] = TkNamedFont.new(fnt)\n          end\n          conf[__configinfo_struct[:current_value]] = fontobj(fontkey)\n        elsif ( __configinfo_struct[:alias] \\\n               && conf.size == __configinfo_struct[:alias] + 1 \\\n               && conf[__configinfo_struct[:alias]][0] == ?- )\n          conf[__configinfo_struct[:alias]] = \n            conf[__configinfo_struct[:alias]][1..-1]\n        end\n        conf\n      else\n        if slot\n          slot = slot.to_s\n\n          alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}\n          if real_name\n            slot = real_name.to_s\n          end\n\n          case slot\n          when /^(#{__val2ruby_optkeys().keys.join('|')})$/\n            method = _symbolkey2str(__val2ruby_optkeys())[slot]\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd() << \"-#{slot}\")), false, true)\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              optval = conf[__configinfo_struct[:default_value]]\n              begin\n                val = method.call(optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__configinfo_struct[:default_value]] = val\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              optval = conf[__configinfo_struct[:current_value]]\n              begin\n                val = method.call(optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__configinfo_struct[:current_value]] = val\n            end\n\n          when /^(#{__methodcall_optkeys.keys.join('|')})$/\n            method = _symbolkey2str(__methodcall_optkeys)[slot]\n            return [slot, '', '', '', self.__send__(method)]\n\n          when /^(#{__numval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]])\n              begin\n                conf[__configinfo_struct[:default_value]] = \n                  number(conf[__configinfo_struct[:default_value]])\n              rescue\n                conf[__configinfo_struct[:default_value]] = nil\n              end\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              begin\n                conf[__configinfo_struct[:current_value]] = \n                  number(conf[__configinfo_struct[:current_value]])\n              rescue\n                conf[__configinfo_struct[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__numstrval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]])\n              conf[__configinfo_struct[:default_value]] = \n                num_or_str(conf[__configinfo_struct[:default_value]])\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              conf[__configinfo_struct[:current_value]] = \n                num_or_str(conf[__configinfo_struct[:current_value]])\n            end\n\n          when /^(#{__boolval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]])\n              begin\n                conf[__configinfo_struct[:default_value]] = \n                  bool(conf[__configinfo_struct[:default_value]])\n              rescue\n                conf[__configinfo_struct[:default_value]] = nil\n              end\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              begin\n                conf[__configinfo_struct[:current_value]] = \n                  bool(conf[__configinfo_struct[:current_value]])\n              rescue\n                conf[__configinfo_struct[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__listval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]])\n              conf[__configinfo_struct[:default_value]] = \n                simplelist(conf[__configinfo_struct[:default_value]])\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              conf[__configinfo_struct[:current_value]] = \n                simplelist(conf[__configinfo_struct[:current_value]])\n            end\n\n          when /^(#{__numlistval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] \\\n                && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )\n              conf[__configinfo_struct[:default_value]] = \n                list(conf[__configinfo_struct[:default_value]])\n            end\n            if ( conf[__configinfo_struct[:current_value]] \\\n                && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )\n              conf[__configinfo_struct[:current_value]] = \n                list(conf[__configinfo_struct[:current_value]])\n            end\n\n          when /^(#{__strval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n          when /^(#{__tkvariable_optkeys.join('|')})$/\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]])\n              v = conf[__configinfo_struct[:default_value]]\n              if v.empty?\n                conf[__configinfo_struct[:default_value]] = nil\n              else\n                conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v)\n              end\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              v = conf[__configinfo_struct[:current_value]]\n              if v.empty?\n                conf[__configinfo_struct[:current_value]] = nil\n              else\n                conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v)\n              end\n            end\n\n          else\n            # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), 0, false, true)\n          end\n          conf[__configinfo_struct[:key]] = \n            conf[__configinfo_struct[:key]][1..-1]\n\n          if ( __configinfo_struct[:alias] \\\n              && conf.size == __configinfo_struct[:alias] + 1 \\\n              && conf[__configinfo_struct[:alias]][0] == ?- )\n            conf[__configinfo_struct[:alias]] = \n              conf[__configinfo_struct[:alias]][1..-1]\n          end\n\n          conf\n\n        else\n          # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).collect{|conflist|\n          #  conf = tk_split_simplelist(conflist)\n          ret = tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).collect{|conflist|\n            conf = tk_split_simplelist(conflist, false, true)\n            conf[__configinfo_struct[:key]] = \n              conf[__configinfo_struct[:key]][1..-1]\n\n            optkey = conf[__configinfo_struct[:key]]\n            case optkey\n            when /^(#{__val2ruby_optkeys().keys.join('|')})$/\n              method = _symbolkey2str(__val2ruby_optkeys())[optkey]\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                optval = conf[__configinfo_struct[:default_value]]\n                begin\n                  val = method.call(optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__configinfo_struct[:default_value]] = val\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                optval = conf[__configinfo_struct[:current_value]]\n                begin\n                  val = method.call(optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__configinfo_struct[:current_value]] = val\n              end\n\n            when /^(#{__strval_optkeys.join('|')})$/\n              # do nothing\n\n            when /^(#{__numval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                begin\n                  conf[__configinfo_struct[:default_value]] = \n                    number(conf[__configinfo_struct[:default_value]])\n                rescue\n                  conf[__configinfo_struct[:default_value]] = nil\n                end\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                begin\n                  conf[__configinfo_struct[:current_value]] = \n                    number(conf[__configinfo_struct[:current_value]])\n                rescue\n                  conf[__configinfo_struct[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__numstrval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                conf[__configinfo_struct[:default_value]] = \n                  num_or_str(conf[__configinfo_struct[:default_value]])\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                conf[__configinfo_struct[:current_value]] = \n                  num_or_str(conf[__configinfo_struct[:current_value]])\n              end\n\n            when /^(#{__boolval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                begin\n                  conf[__configinfo_struct[:default_value]] = \n                    bool(conf[__configinfo_struct[:default_value]])\n                rescue\n                  conf[__configinfo_struct[:default_value]] = nil\n                end\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                begin\n                  conf[__configinfo_struct[:current_value]] = \n                    bool(conf[__configinfo_struct[:current_value]])\n                rescue\n                  conf[__configinfo_struct[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__listval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                conf[__configinfo_struct[:default_value]] = \n                  simplelist(conf[__configinfo_struct[:default_value]])\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                conf[__configinfo_struct[:current_value]] = \n                  simplelist(conf[__configinfo_struct[:current_value]])\n              end\n\n            when /^(#{__numlistval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] \\\n                  && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )\n                conf[__configinfo_struct[:default_value]] = \n                  list(conf[__configinfo_struct[:default_value]])\n              end\n              if ( conf[__configinfo_struct[:current_value]] \\\n                  && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )\n                conf[__configinfo_struct[:current_value]] = \n                  list(conf[__configinfo_struct[:current_value]])\n              end\n\n            when /^(#{__tkvariable_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                v = conf[__configinfo_struct[:default_value]]\n                if v.empty?\n                  conf[__configinfo_struct[:default_value]] = nil\n                else\n                  conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v)\n                end\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                v = conf[__configinfo_struct[:current_value]]\n                if v.empty?\n                  conf[__configinfo_struct[:current_value]] = nil\n                else\n                  conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v)\n                end\n              end\n\n            else\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                if conf[__configinfo_struct[:default_value]].index('{')\n                  conf[__configinfo_struct[:default_value]] = \n                    tk_split_list(conf[__configinfo_struct[:default_value]]) \n                else\n                  conf[__configinfo_struct[:default_value]] = \n                    tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) \n                end\n              end\n              if conf[__configinfo_struct[:current_value]]\n                if conf[__configinfo_struct[:current_value]].index('{')\n                  conf[__configinfo_struct[:current_value]] = \n                    tk_split_list(conf[__configinfo_struct[:current_value]]) \n                else\n                  conf[__configinfo_struct[:current_value]] = \n                    tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) \n                end\n              end\n            end\n\n            if ( __configinfo_struct[:alias] \\\n                && conf.size == __configinfo_struct[:alias] + 1 \\\n                && conf[__configinfo_struct[:alias]][0] == ?- )\n              conf[__configinfo_struct[:alias]] = \n                conf[__configinfo_struct[:alias]][1..-1]\n            end\n\n            conf\n          }\n\n          __font_optkeys.each{|optkey|\n            optkey = optkey.to_s\n            fontconf = ret.assoc(optkey)\n            if fontconf && fontconf.size > 2\n              ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/}\n              fnt = fontconf[__configinfo_struct[:default_value]]\n              if TkFont.is_system_font?(fnt)\n                fontconf[__configinfo_struct[:default_value]] \\\n                  = TkNamedFont.new(fnt)\n              end\n              fontconf[__configinfo_struct[:current_value]] = fontobj(optkey)\n              ret.push(fontconf)\n            end\n          }\n\n          __methodcall_optkeys.each{|optkey, method|\n            ret << [optkey.to_s, '', '', '', self.__send__(method)]\n          }\n\n          ret\n        end\n      end\n\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (slot && \n          slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/)\n        fontkey  = $2\n        # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{fontkey}\"))))\n        conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{fontkey}\")), false, true)\n        conf[__configinfo_struct[:key]] = \n          conf[__configinfo_struct[:key]][1..-1]\n\n        if ( ! __configinfo_struct[:alias] \\\n            || conf.size > __configinfo_struct[:alias] + 1 )\n          fnt = conf[__configinfo_struct[:default_value]]\n          if TkFont.is_system_font?(fnt)\n            conf[__configinfo_struct[:default_value]] = TkNamedFont.new(fnt)\n          end\n          conf[__configinfo_struct[:current_value]] = fontobj(fontkey)\n          { conf.shift => conf }\n        elsif ( __configinfo_struct[:alias] \\\n               && conf.size == __configinfo_struct[:alias] + 1 )\n          if conf[__configinfo_struct[:alias]][0] == ?-\n            conf[__configinfo_struct[:alias]] = \n              conf[__configinfo_struct[:alias]][1..-1]\n          end\n          { conf[0] => conf[1] }\n        else\n          { conf.shift => conf }\n        end\n      else\n        if slot\n          slot = slot.to_s\n\n          alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}\n          if real_name\n            slot = real_name.to_s\n          end\n\n          case slot\n          when /^(#{__val2ruby_optkeys().keys.join('|')})$/\n            method = _symbolkey2str(__val2ruby_optkeys())[slot]\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              optval = conf[__configinfo_struct[:default_value]]\n              begin\n                val = method.call(optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__configinfo_struct[:default_value]] = val\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              optval = conf[__configinfo_struct[:current_value]]\n              begin\n                val = method.call(optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[__configinfo_struct[:current_value]] = val\n            end\n\n          when /^(#{__methodcall_optkeys.keys.join('|')})$/\n            method = _symbolkey2str(__methodcall_optkeys)[slot]\n            return {slot => ['', '', '', self.__send__(method)]}\n\n          when /^(#{__numval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              begin\n                conf[__configinfo_struct[:default_value]] = \n                  number(conf[__configinfo_struct[:default_value]])\n              rescue\n                conf[__configinfo_struct[:default_value]] = nil\n              end\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              begin\n                conf[__configinfo_struct[:current_value]] = \n                  number(conf[__configinfo_struct[:current_value]])\n              rescue\n                conf[__configinfo_struct[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__numstrval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              conf[__configinfo_struct[:default_value]] = \n                num_or_str(conf[__configinfo_struct[:default_value]])\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              conf[__configinfo_struct[:current_value]] = \n                num_or_str(conf[__configinfo_struct[:current_value]])\n            end\n\n          when /^(#{__boolval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              begin\n                conf[__configinfo_struct[:default_value]] = \n                  bool(conf[__configinfo_struct[:default_value]])\n              rescue\n                conf[__configinfo_struct[:default_value]] = nil\n              end\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              begin\n                conf[__configinfo_struct[:current_value]] = \n                  bool(conf[__configinfo_struct[:current_value]])\n              rescue\n                conf[__configinfo_struct[:current_value]] = nil\n              end\n            end\n\n          when /^(#{__listval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              conf[__configinfo_struct[:default_value]] = \n                simplelist(conf[__configinfo_struct[:default_value]])\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              conf[__configinfo_struct[:current_value]] = \n                simplelist(conf[__configinfo_struct[:current_value]])\n            end\n\n          when /^(#{__numlistval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] \\\n                && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )\n              conf[__configinfo_struct[:default_value]] = \n                list(conf[__configinfo_struct[:default_value]])\n            end\n            if ( conf[__configinfo_struct[:current_value]] \\\n                && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )\n              conf[__configinfo_struct[:current_value]] = \n                list(conf[__configinfo_struct[:current_value]])\n            end\n\n          when /^(#{__tkvariable_optkeys.join('|')})$/\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n\n            if ( __configinfo_struct[:default_value] \\\n                && conf[__configinfo_struct[:default_value]] )\n              v = conf[__configinfo_struct[:default_value]]\n              if v.empty?\n                conf[__configinfo_struct[:default_value]] = nil\n              else\n                conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v)\n              end\n            end\n            if ( conf[__configinfo_struct[:current_value]] )\n              v = conf[__configinfo_struct[:current_value]]\n              if v.empty?\n                conf[__configinfo_struct[:current_value]] = nil\n              else\n                conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v)\n              end\n            end\n\n          when /^(#{__strval_optkeys.join('|')})$/\n            # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), false, true)\n          else\n            # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\"))))\n            conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << \"-#{slot}\")), 0, false, true)\n          end\n          conf[__configinfo_struct[:key]] = \n            conf[__configinfo_struct[:key]][1..-1]\n\n          if ( __configinfo_struct[:alias] \\\n              && conf.size == __configinfo_struct[:alias] + 1 )\n            if conf[__configinfo_struct[:alias]][0] == ?-\n              conf[__configinfo_struct[:alias]] = \n                conf[__configinfo_struct[:alias]][1..-1]\n            end\n            { conf[0] => conf[1] }\n          else\n            { conf.shift => conf }\n          end\n\n        else\n          ret = {}\n          # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).each{|conflist|\n          #  conf = tk_split_simplelist(conflist)\n          tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).each{|conflist|\n            conf = tk_split_simplelist(conflist, false, true)\n            conf[__configinfo_struct[:key]] = \n              conf[__configinfo_struct[:key]][1..-1]\n\n            optkey = conf[__configinfo_struct[:key]]\n            case optkey\n            when /^(#{__val2ruby_optkeys().keys.join('|')})$/\n              method = _symbolkey2str(__val2ruby_optkeys())[optkey]\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                optval = conf[__configinfo_struct[:default_value]]\n                begin\n                  val = method.call(optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__configinfo_struct[:default_value]] = val\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                optval = conf[__configinfo_struct[:current_value]]\n                begin\n                  val = method.call(optval)\n                rescue => e\n                  warn(\"Warning:: #{e.message} (when #{method}.call(#{optval.inspect})\") if $DEBUG\n                  val = optval\n                end\n                conf[__configinfo_struct[:current_value]] = val\n              end\n\n            when /^(#{__strval_optkeys.join('|')})$/\n              # do nothing\n\n            when /^(#{__numval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                begin\n                  conf[__configinfo_struct[:default_value]] = \n                    number(conf[__configinfo_struct[:default_value]])\n                rescue\n                  conf[__configinfo_struct[:default_value]] = nil\n                end\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                begin\n                  conf[__configinfo_struct[:current_value]] = \n                    number(conf[__configinfo_struct[:current_value]])\n                rescue\n                  conf[__configinfo_struct[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__numstrval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                conf[__configinfo_struct[:default_value]] = \n                  num_or_str(conf[__configinfo_struct[:default_value]])\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                conf[__configinfo_struct[:current_value]] = \n                  num_or_str(conf[__configinfo_struct[:current_value]])\n              end\n\n            when /^(#{__boolval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                begin\n                  conf[__configinfo_struct[:default_value]] = \n                    bool(conf[__configinfo_struct[:default_value]])\n                rescue\n                  conf[__configinfo_struct[:default_value]] = nil\n                end\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                begin\n                  conf[__configinfo_struct[:current_value]] = \n                    bool(conf[__configinfo_struct[:current_value]])\n                rescue\n                  conf[__configinfo_struct[:current_value]] = nil\n                end\n              end\n\n            when /^(#{__listval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                conf[__configinfo_struct[:default_value]] = \n                  simplelist(conf[__configinfo_struct[:default_value]])\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                conf[__configinfo_struct[:current_value]] = \n                  simplelist(conf[__configinfo_struct[:current_value]])\n              end\n\n            when /^(#{__numlistval_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] \\\n                  && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ )\n                conf[__configinfo_struct[:default_value]] = \n                  list(conf[__configinfo_struct[:default_value]])\n              end\n              if ( conf[__configinfo_struct[:current_value]] \\\n                  && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ )\n                conf[__configinfo_struct[:current_value]] = \n                  list(conf[__configinfo_struct[:current_value]])\n              end\n\n            when /^(#{__tkvariable_optkeys.join('|')})$/\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                v = conf[__configinfo_struct[:default_value]]\n                if v.empty?\n                  conf[__configinfo_struct[:default_value]] = nil\n                else\n                  conf[__configinfo_struct[:default_value]] = TkVarAccess.new\n                end\n              end\n              if ( conf[__configinfo_struct[:current_value]] )\n                v = conf[__configinfo_struct[:current_value]]\n                if v.empty?\n                  conf[__configinfo_struct[:current_value]] = nil\n                else\n                  conf[__configinfo_struct[:current_value]] = TkVarAccess.new\n                end\n              end\n\n            else\n              if ( __configinfo_struct[:default_value] \\\n                  && conf[__configinfo_struct[:default_value]] )\n                if conf[__configinfo_struct[:default_value]].index('{')\n                  conf[__configinfo_struct[:default_value]] = \n                    tk_split_list(conf[__configinfo_struct[:default_value]]) \n                else\n                  conf[__configinfo_struct[:default_value]] = \n                    tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) \n                end\n              end\n              if conf[__configinfo_struct[:current_value]]\n                if conf[__configinfo_struct[:current_value]].index('{')\n                  conf[__configinfo_struct[:current_value]] = \n                    tk_split_list(conf[__configinfo_struct[:current_value]]) \n                else\n                  conf[__configinfo_struct[:current_value]] = \n                    tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) \n                end\n              end\n            end\n\n            if ( __configinfo_struct[:alias] \\\n                && conf.size == __configinfo_struct[:alias] + 1 )\n              if conf[__configinfo_struct[:alias]][0] == ?-\n                conf[__configinfo_struct[:alias]] = \n                  conf[__configinfo_struct[:alias]][1..-1]\n              end\n              ret[conf[0]] = conf[1]\n            else\n              ret[conf.shift] = conf\n            end\n          }\n\n          __font_optkeys.each{|optkey|\n            optkey = optkey.to_s\n            fontconf = ret[optkey]\n            if fontconf.kind_of?(Array)\n              ret.delete(optkey)\n              ret.delete('latin' << optkey)\n              ret.delete('ascii' << optkey)\n              ret.delete('kanji' << optkey)\n              fnt = fontconf[__configinfo_struct[:default_value]]\n              if TkFont.is_system_font?(fnt)\n                fontconf[__configinfo_struct[:default_value]] \\\n                  = TkNamedFont.new(fnt)\n              end\n              fontconf[__configinfo_struct[:current_value]] = fontobj(optkey)\n              ret[optkey] = fontconf\n            end\n          }\n\n          __methodcall_optkeys.each{|optkey, method|\n            ret[optkey.to_s] = ['', '', '', self.__send__(method)]\n          }\n\n          ret\n        end\n      end\n    end\n  end\n  private :__configinfo_core\n\n  def configinfo(slot = nil)\n    if slot && TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      begin\n        __configinfo_core(slot)\n      rescue\n        Array.new(__configinfo_struct.values.max).unshift(slot.to_s)\n      end\n    else\n      __configinfo_core(slot)\n    end\n  end\n\n  def current_configinfo(slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        org_slot = slot\n        begin\n          conf = configinfo(slot)\n          if ( ! __configinfo_struct[:alias] \\\n              || conf.size > __configinfo_struct[:alias] + 1 )\n            return {conf[0] => conf[-1]}\n          end\n          slot = conf[__configinfo_struct[:alias]]\n        end while(org_slot != slot)\n        fail RuntimeError, \n          \"there is a configure alias loop about '#{org_slot}'\"\n      else\n        ret = {}\n        configinfo().each{|conf|\n          if ( ! __configinfo_struct[:alias] \\\n              || conf.size > __configinfo_struct[:alias] + 1 )\n            ret[conf[0]] = conf[-1]\n          end\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      configinfo(slot).each{|key, conf| \n        ret[key] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\nend\n\nclass TkObject<TkKernel\n  extend  TkCore\n  include Tk\n  include TkConfigMethod\n  include TkBindCore\n\n### --> definition is moved to TkUtil module\n#  def path\n#    @path\n#  end\n\n  def epath\n    @path\n  end\n\n  def to_eval\n    @path\n  end\n\n  def tk_send(cmd, *rest)\n    tk_call(path, cmd, *rest)\n  end\n  def tk_send_without_enc(cmd, *rest)\n    tk_call_without_enc(path, cmd, *rest)\n  end\n  def tk_send_with_enc(cmd, *rest)\n    tk_call_with_enc(path, cmd, *rest)\n  end\n  # private :tk_send, :tk_send_without_enc, :tk_send_with_enc\n\n  def tk_send_to_list(cmd, *rest)\n    tk_call_to_list(path, cmd, *rest)\n  end\n  def tk_send_to_list_without_enc(cmd, *rest)\n    tk_call_to_list_without_enc(path, cmd, *rest)\n  end\n  def tk_send_to_list_with_enc(cmd, *rest)\n    tk_call_to_list_with_enc(path, cmd, *rest)\n  end\n  def tk_send_to_simplelist(cmd, *rest)\n    tk_call_to_simplelist(path, cmd, *rest)\n  end\n  def tk_send_to_simplelist_without_enc(cmd, *rest)\n    tk_call_to_simplelist_without_enc(path, cmd, *rest)\n  end\n  def tk_send_to_simplelist_with_enc(cmd, *rest)\n    tk_call_to_simplelist_with_enc(path, cmd, *rest)\n  end\n\n  def method_missing(id, *args)\n    name = id.id2name\n    case args.length\n    when 1\n      if name[-1] == ?=\n        configure name[0..-2], args[0]\n        args[0]\n      else\n        configure name, args[0]\n        self\n      end\n    when 0\n      begin\n        cget(name)\n      rescue\n        if self.kind_of?(TkWindow)\n          fail NameError, \n               \"unknown option '#{id}' for #{self.inspect} (deleted widget?)\"\n        else\n          super(id, *args)\n        end\n#        fail NameError, \n#             \"undefined local variable or method `#{name}' for #{self.to_s}\", \n#             error_at\n      end\n    else\n      super(id, *args)\n#      fail NameError, \"undefined method `#{name}' for #{self.to_s}\", error_at\n    end\n  end\n\n=begin\n  def [](id)\n    cget(id)\n  end\n\n  def []=(id, val)\n    configure(id, val)\n    val\n  end\n=end\n\n  def event_generate(context, keys=nil)\n    if context.kind_of?(TkEvent::Event)\n      context.generate(self, ((keys)? keys: {}))\n    elsif keys\n      #tk_call('event', 'generate', path, \n      #       \"<#{tk_event_sequence(context)}>\", *hash_kv(keys))\n      tk_call_without_enc('event', 'generate', path, \n                          \"<#{tk_event_sequence(context)}>\", \n                          *hash_kv(keys, true))\n    else\n      #tk_call('event', 'generate', path, \"<#{tk_event_sequence(context)}>\")\n      tk_call_without_enc('event', 'generate', path, \n                          \"<#{tk_event_sequence(context)}>\")\n    end\n  end\n\n  def tk_trace_variable(v)\n    #unless v.kind_of?(TkVariable)\n    #  fail(ArgumentError, \"type error (#{v.class}); must be TkVariable object\")\n    #end\n    v\n  end\n  private :tk_trace_variable\n\n  def destroy\n    #tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id\n  end\nend\n\n\nclass TkWindow<TkObject\n  include TkWinfo\n  extend TkBindCore\n  include Tk::Wm_for_General\n\n  @@WIDGET_INSPECT_FULL = false\n  def TkWindow._widget_inspect_full_?\n    @@WIDGET_INSPECT_FULL\n  end\n  def TkWindow._widget_inspect_full_=(mode)\n    @@WIDGET_INSPECT_FULL = (mode && true) || false\n  end\n\n  TkCommandNames = [].freeze\n  ## ==> If TkCommandNames[0] is a string (not a null string), \n  ##     assume the string is a Tcl/Tk's create command of the widget class. \n  WidgetClassName = ''.freeze\n  # WidgetClassNames[WidgetClassName] = self  \n  ## ==> If self is a widget class, entry to the WidgetClassNames table.\n  def self.to_eval\n    self::WidgetClassName\n  end\n\n  def initialize(parent=nil, keys=nil)\n    if parent.kind_of? Hash\n      keys = _symbolkey2str(parent)\n      parent = keys.delete('parent')\n      widgetname = keys.delete('widgetname')\n      install_win(if parent then parent.path end, widgetname)\n      without_creating = keys.delete('without_creating')\n      # if without_creating && !widgetname \n      #   fail ArgumentError, \n      #        \"if set 'without_creating' to true, need to define 'widgetname'\"\n      # end\n    elsif keys\n      keys = _symbolkey2str(keys)\n      widgetname = keys.delete('widgetname')\n      install_win(if parent then parent.path end, widgetname)\n      without_creating = keys.delete('without_creating')\n      # if without_creating && !widgetname \n      #   fail ArgumentError, \n      #        \"if set 'without_creating' to true, need to define 'widgetname'\"\n      # end\n    else\n      install_win(if parent then parent.path end)\n    end\n    if self.method(:create_self).arity == 0\n      p 'create_self has no arg' if $DEBUG\n      create_self unless without_creating\n      if keys\n        # tk_call @path, 'configure', *hash_kv(keys)\n        configure(keys)\n      end\n    else\n      p 'create_self has args' if $DEBUG\n      fontkeys = {}\n      methodkeys = {}\n      if keys\n        #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key|\n        #  fontkeys[key] = keys.delete(key) if keys.key?(key)\n        #}\n        __font_optkeys.each{|key|\n          fkey = key.to_s\n          fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n          fkey = \"kanji#{key}\"\n          fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n          fkey = \"latin#{key}\"\n          fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n          fkey = \"ascii#{key}\"\n          fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n        }\n\n        __optkey_aliases.each{|alias_name, real_name|\n          alias_name = alias_name.to_s\n          if keys.has_key?(alias_name)\n            keys[real_name.to_s] = keys.delete(alias_name)\n          end\n        }\n\n        __methodcall_optkeys.each{|key|\n          key = key.to_s\n          methodkeys[key] = keys.delete(key) if keys.key?(key)\n        }\n\n        __ruby2val_optkeys.each{|key, method|\n          key = key.to_s\n          keys[key] = method.call(keys[key]) if keys.has_key?(key)\n        }\n      end\n      if without_creating && keys\n        #configure(keys)\n        configure(__conv_keyonly_opts(keys))\n      else\n        #create_self(keys)\n        create_self(__conv_keyonly_opts(keys))\n      end\n      font_configure(fontkeys) unless fontkeys.empty?\n      configure(methodkeys) unless methodkeys.empty?\n    end\n  end\n\n  def create_self(keys)\n    # may need to override\n    begin\n      cmd = self.class::TkCommandNames[0]\n      fail unless (cmd.kind_of?(String) && cmd.length > 0)\n    rescue\n      fail RuntimeError, \"class #{self.class} may be an abstract class\"\n    end\n\n    if keys and keys != None\n      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        tk_call_without_enc(cmd, @path, *hash_kv(keys, true))\n      else\n        begin\n          tk_call_without_enc(cmd, @path, *hash_kv(keys, true))\n        rescue => e\n          tk_call_without_enc(cmd, @path)\n          keys = __check_available_configure_options(keys)\n          unless keys.empty?\n            begin\n              # try to configure\n              configure(keys)\n            rescue\n              # fail => includes options adaptable when creattion only?\n              begin\n                tk_call_without_enc('destroy', @path)\n              rescue\n                # cannot rescue options error\n                fail e \n              else\n                # re-create widget\n                tk_call_without_enc(cmd, @path, *hash_kv(keys, true))\n              end\n            end\n          end\n        end\n      end\n    else\n      tk_call_without_enc(cmd, @path)\n    end\n  end\n  private :create_self\n\n  def inspect\n    if @@WIDGET_INSPECT_FULL\n      super\n    else\n      str = super\n      str[0..(str.index(' '))] << '@path=' << @path.inspect << '>'\n    end\n  end\n\n  def exist?\n    TkWinfo.exist?(self)\n  end\n\n  def bind_class\n    @db_class || self.class()\n  end\n\n  def database_classname\n    TkWinfo.classname(self)\n  end\n  def database_class\n    name = database_classname()\n    if WidgetClassNames[name]\n      WidgetClassNames[name]\n    else\n      TkDatabaseClass.new(name)\n    end\n  end\n  def self.database_classname\n    self::WidgetClassName\n  end\n  def self.database_class\n    WidgetClassNames[self::WidgetClassName]\n  end\n\n  def pack(keys = nil)\n    #tk_call_without_enc('pack', epath, *hash_kv(keys, true))\n    if keys\n      TkPack.configure(self, keys)\n    else\n      TkPack.configure(self)\n    end\n    self\n  end\n\n  def pack_in(target, keys = nil)\n    if keys\n      keys = keys.dup\n      keys['in'] = target\n    else\n      keys = {'in'=>target}\n    end\n    #tk_call 'pack', epath, *hash_kv(keys)\n    TkPack.configure(self, keys)\n    self\n  end\n\n  def pack_forget\n    #tk_call_without_enc('pack', 'forget', epath)\n    TkPack.forget(self)\n    self\n  end\n  alias unpack pack_forget\n\n  def pack_config(slot, value=None)\n    #if slot.kind_of? Hash\n    #  tk_call 'pack', 'configure', epath, *hash_kv(slot)\n    #else\n    #  tk_call 'pack', 'configure', epath, \"-#{slot}\", value\n    #end\n    if slot.kind_of? Hash\n      TkPack.configure(self, slot)\n    else\n      TkPack.configure(self, slot=>value)\n    end\n  end\n  alias pack_configure pack_config\n\n  def pack_info()\n    #ilist = list(tk_call('pack', 'info', epath))\n    #info = {}\n    #while key = ilist.shift\n    #  info[key[1..-1]] = ilist.shift\n    #end\n    #return info\n    TkPack.info(self)\n  end\n\n  def pack_propagate(mode=None)\n    #if mode == None\n    #  bool(tk_call('pack', 'propagate', epath))\n    #else\n    #  tk_call('pack', 'propagate', epath, mode)\n    #  self\n    #end\n    if mode == None\n      TkPack.propagate(self)\n    else\n      TkPack.propagate(self, mode)\n      self\n    end\n  end\n\n  def pack_slaves()\n    #list(tk_call('pack', 'slaves', epath))\n    TkPack.slaves(self)\n  end\n\n  def grid(keys = nil)\n    #tk_call 'grid', epath, *hash_kv(keys)\n    if keys\n      TkGrid.configure(self, keys)\n    else\n      TkGrid.configure(self)\n    end\n    self\n  end\n\n  def grid_in(target, keys = nil)\n    if keys\n      keys = keys.dup\n      keys['in'] = target\n    else\n      keys = {'in'=>target}\n    end\n    #tk_call 'grid', epath, *hash_kv(keys)\n    TkGrid.configure(self, keys)\n    self\n  end\n\n  def grid_anchor(anchor=None)\n    if anchor == None\n      TkGrid.anchor(self)\n    else\n      TkGrid.anchor(self, anchor)\n      self\n    end\n  end\n\n  def grid_forget\n    #tk_call('grid', 'forget', epath)\n    TkGrid.forget(self)\n    self\n  end\n  alias ungrid grid_forget\n\n  def grid_bbox(*args)\n    #list(tk_call('grid', 'bbox', epath, *args))\n    TkGrid.bbox(self, *args)\n  end\n\n  def grid_config(slot, value=None)\n    #if slot.kind_of? Hash\n    #  tk_call 'grid', 'configure', epath, *hash_kv(slot)\n    #else\n    #  tk_call 'grid', 'configure', epath, \"-#{slot}\", value\n    #end\n    if slot.kind_of? Hash\n      TkGrid.configure(self, slot)\n    else\n      TkGrid.configure(self, slot=>value)\n    end\n  end\n  alias grid_configure grid_config\n\n  def grid_columnconfig(index, keys)\n    #tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys))\n    TkGrid.columnconfigure(self, index, keys)\n  end\n  alias grid_columnconfigure grid_columnconfig\n  alias grid_column grid_columnconfig\n\n  def grid_rowconfig(index, keys)\n    #tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys))\n    TkGrid.rowconfigure(self, index, keys)\n  end\n  alias grid_rowconfigure grid_rowconfig\n  alias grid_row grid_rowconfig\n\n  def grid_columnconfiginfo(index, slot=nil)\n    #if slot\n    #  tk_call('grid', 'columnconfigure', epath, index, \"-#{slot}\").to_i\n    #else\n    #  ilist = list(tk_call('grid', 'columnconfigure', epath, index))\n    #  info = {}\n    #  while key = ilist.shift\n    #   info[key[1..-1]] = ilist.shift\n    #  end\n    #  info\n    #end\n    TkGrid.columnconfiginfo(self, index, slot)\n  end\n\n  def grid_rowconfiginfo(index, slot=nil)\n    #if slot\n    #  tk_call('grid', 'rowconfigure', epath, index, \"-#{slot}\").to_i\n    #else\n    #  ilist = list(tk_call('grid', 'rowconfigure', epath, index))\n    #  info = {}\n    #  while key = ilist.shift\n    #   info[key[1..-1]] = ilist.shift\n    #  end\n    #  info\n    #end\n    TkGrid.rowconfiginfo(self, index, slot)\n  end\n\n  def grid_info()\n    #list(tk_call('grid', 'info', epath))\n    TkGrid.info(self)\n  end\n\n  def grid_location(x, y)\n    #list(tk_call('grid', 'location', epath, x, y))\n    TkGrid.location(self, x, y)\n  end\n\n  def grid_propagate(mode=None)\n    #if mode == None\n    #  bool(tk_call('grid', 'propagate', epath))\n    #else\n    #  tk_call('grid', 'propagate', epath, mode)\n    #  self\n    #end\n    if mode == None\n      TkGrid.propagate(self)\n    else\n      TkGrid.propagate(self, mode)\n      self\n    end\n  end\n\n  def grid_remove()\n    #tk_call 'grid', 'remove', epath\n    TkGrid.remove(self)\n    self\n  end\n\n  def grid_size()\n    #list(tk_call('grid', 'size', epath))\n    TkGrid.size(self)\n  end\n\n  def grid_slaves(args)\n    #list(tk_call('grid', 'slaves', epath, *hash_kv(args)))\n    TkGrid.slaves(self, args)\n  end\n\n  def place(keys)\n    #tk_call 'place', epath, *hash_kv(keys)\n    TkPlace.configure(self, keys)\n    self\n  end\n\n  def place_in(target, keys = nil)\n    if keys\n      keys = keys.dup\n      keys['in'] = target\n    else\n      keys = {'in'=>target}\n    end\n    #tk_call 'place', epath, *hash_kv(keys)\n    TkPlace.configure(self, keys)\n    self\n  end\n\n  def  place_forget\n    #tk_call 'place', 'forget', epath\n    TkPlace.forget(self)\n    self\n  end\n  alias unplace place_forget\n\n  def place_config(slot, value=None)\n    #if slot.kind_of? Hash\n    #  tk_call 'place', 'configure', epath, *hash_kv(slot)\n    #else\n    #  tk_call 'place', 'configure', epath, \"-#{slot}\", value\n    #end\n    TkPlace.configure(self, slot, value)\n  end\n  alias place_configure place_config\n\n  def place_configinfo(slot = nil)\n    # for >= Tk8.4a2 ?\n    #if slot\n    #  conf = tk_split_list(tk_call('place', 'configure', epath, \"-#{slot}\") )\n    #  conf[0] = conf[0][1..-1]\n    #  conf\n    #else\n    #  tk_split_simplelist(tk_call('place', \n    #                             'configure', epath)).collect{|conflist|\n    #   conf = tk_split_simplelist(conflist)\n    #   conf[0] = conf[0][1..-1]\n    #   conf\n    #  }\n    #end\n    TkPlace.configinfo(self, slot)\n  end\n\n  def place_info()\n    #ilist = list(tk_call('place', 'info', epath))\n    #info = {}\n    #while key = ilist.shift\n    #  info[key[1..-1]] = ilist.shift\n    #end\n    #return info\n    TkPlace.info(self)\n  end\n\n  def place_slaves()\n    #list(tk_call('place', 'slaves', epath))\n    TkPlace.slaves(self)\n  end\n\n  def set_focus(force=false)\n    if force\n      tk_call_without_enc('focus', '-force', path)\n    else\n      tk_call_without_enc('focus', path)\n    end\n    self\n  end\n  alias focus set_focus\n\n  def grab(opt = nil)\n    unless opt\n      tk_call_without_enc('grab', 'set', path)\n      return self\n    end\n\n    case opt\n    when 'set', :set\n      tk_call_without_enc('grab', 'set', path)\n      return self\n    when 'global', :global\n      #return(tk_call('grab', 'set', '-global', path))\n      tk_call_without_enc('grab', 'set', '-global', path)\n      return self\n    when 'release', :release\n      #return tk_call('grab', 'release', path)\n      tk_call_without_enc('grab', 'release', path)\n      return self\n    when 'current', :current\n      return window(tk_call_without_enc('grab', 'current', path))\n    when 'status', :status\n      return tk_call_without_enc('grab', 'status', path)\n    else\n      return tk_call_without_enc('grab', opt, path)\n    end\n  end\n\n  def grab_current\n    grab('current')\n  end\n  alias current_grab grab_current\n  def grab_release\n    grab('release')\n  end\n  alias release_grab grab_release\n  def grab_set\n    grab('set')\n  end\n  alias set_grab grab_set\n  def grab_set_global\n    grab('global')\n  end\n  alias set_global_grab grab_set_global\n  def grab_status\n    grab('status')\n  end\n\n  def lower(below=None)\n    # below = below.epath if below.kind_of?(TkObject)\n    below = _epath(below)\n    tk_call 'lower', epath, below\n    self\n  end\n  alias lower_window lower\n  def raise(above=None)\n    #above = above.epath if above.kind_of?(TkObject)\n    above = _epath(above)\n    tk_call 'raise', epath, above\n    self\n  end\n  alias raise_window raise\n\n  def command(cmd=nil, &b)\n    if cmd\n      configure_cmd('command', cmd)\n    elsif b\n      configure_cmd('command', Proc.new(&b))\n    else\n      cget('command')\n    end\n  end\n\n  def colormodel(model=None)\n    tk_call('tk', 'colormodel', path, model)\n    self\n  end\n\n  def caret(keys=nil)\n    TkXIM.caret(path, keys)\n  end\n\n  def destroy\n    super\n    children = []\n    rexp = /^#{self.path}\\.[^.]+$/\n    TkCore::INTERP.tk_windows.each{|path, obj|\n      children << [path, obj] if path =~ rexp\n    }\n    if defined?(@cmdtbl)\n      for id in @cmdtbl\n        uninstall_cmd id\n      end\n    end\n\n    children.each{|path, obj|\n      obj.instance_eval{\n        if defined?(@cmdtbl)\n          for id in @cmdtbl\n            uninstall_cmd id\n          end\n        end\n      }\n      TkCore::INTERP.tk_windows.delete(path)\n    }\n\n    begin\n      tk_call_without_enc('destroy', epath)\n    rescue\n    end\n    uninstall_win\n  end\n\n  def wait_visibility(on_thread = true)\n    if $SAFE >= 4\n      fail SecurityError, \"can't wait visibility at $SAFE >= 4\"\n    end\n    on_thread &= (Thread.list.size != 1)\n    if on_thread\n      INTERP._thread_tkwait('visibility', path)\n    else\n      INTERP._invoke('tkwait', 'visibility', path)\n    end\n  end\n  def eventloop_wait_visibility\n    wait_visibility(false)\n  end\n  def thread_wait_visibility\n    wait_visibility(true)\n  end\n  alias wait wait_visibility\n  alias tkwait wait_visibility\n  alias eventloop_wait eventloop_wait_visibility\n  alias eventloop_tkwait eventloop_wait_visibility\n  alias eventloop_tkwait_visibility eventloop_wait_visibility\n  alias thread_wait thread_wait_visibility\n  alias thread_tkwait thread_wait_visibility\n  alias thread_tkwait_visibility thread_wait_visibility\n\n  def wait_destroy(on_thread = true)\n    if $SAFE >= 4\n      fail SecurityError, \"can't wait destroy at $SAFE >= 4\"\n    end\n    on_thread &= (Thread.list.size != 1)\n    if on_thread\n      INTERP._thread_tkwait('window', epath)\n    else\n      INTERP._invoke('tkwait', 'window', epath)\n    end\n  end\n  alias wait_window wait_destroy\n  def eventloop_wait_destroy\n    wait_destroy(false)\n  end\n  alias eventloop_wait_window eventloop_wait_destroy\n  def thread_wait_destroy\n    wait_destroy(true)\n  end\n  alias thread_wait_window thread_wait_destroy\n\n  alias tkwait_destroy wait_destroy\n  alias tkwait_window wait_destroy\n\n  alias eventloop_tkwait_destroy eventloop_wait_destroy\n  alias eventloop_tkwait_window eventloop_wait_destroy\n\n  alias thread_tkwait_destroy thread_wait_destroy\n  alias thread_tkwait_window thread_wait_destroy\n\n  def bindtags(taglist=nil)\n    if taglist\n      fail ArgumentError, \"taglist must be Array\" unless taglist.kind_of? Array\n      tk_call('bindtags', path, taglist)\n      taglist\n    else\n      list(tk_call('bindtags', path)).collect{|tag|\n        if tag.kind_of?(String) \n          if cls = WidgetClassNames[tag]\n            cls\n          elsif btag = TkBindTag.id2obj(tag)\n            btag\n          else\n            tag\n          end\n        else\n          tag\n        end\n      }\n    end\n  end\n\n  def bindtags=(taglist)\n    bindtags(taglist)\n    taglist\n  end\n\n  def bindtags_shift\n    taglist = bindtags\n    tag = taglist.shift\n    bindtags(taglist)\n    tag\n  end\n\n  def bindtags_unshift(tag)\n    bindtags(bindtags().unshift(tag))\n  end\nend\nTkWidget = TkWindow\n\n# freeze core modules\n#TclTkLib.freeze\n#TclTkIp.freeze\n#TkUtil.freeze\n#TkKernel.freeze\n#TkComm.freeze\n#TkComm::Event.freeze\n#TkCore.freeze\n#Tk.freeze\n\nmodule Tk\n  RELEASE_DATE = '2008-05-23'.freeze\n\n  autoload :AUTO_PATH,        'tk/variable'\n  autoload :TCL_PACKAGE_PATH, 'tk/variable'\n  autoload :PACKAGE_PATH,     'tk/variable'\n  autoload :TCL_LIBRARY_PATH, 'tk/variable'\n  autoload :LIBRARY_PATH,     'tk/variable'\n  autoload :TCL_PRECISION,    'tk/variable'\nend\n\n# call setup script for Tk extension libraries (base configuration)\nbegin\n  require 'tkextlib/version.rb'\n  require 'tkextlib/setup.rb'\nrescue LoadError\n  # ignore\nend\n"
  },
  {
    "path": "ext/tk/lib/tkafter.rb",
    "content": "#\n#   tkafter.rb - load tk/after.rb\n#\nrequire 'tk/timer'\n"
  },
  {
    "path": "ext/tk/lib/tkbgerror.rb",
    "content": "#\n#   tkbgerror.rb - load tk/bgerror.rb\n#\nrequire 'tk/bgerror'\n"
  },
  {
    "path": "ext/tk/lib/tkcanvas.rb",
    "content": "#\n#   tkcanvas.rb - load tk/canvas.rb\n#\nrequire 'tk/canvas'\n"
  },
  {
    "path": "ext/tk/lib/tkclass.rb",
    "content": "#\n#               tkclass.rb - Tk classes\n#                       Date: 2000/11/27 09:23:36\n#                       by Yukihiro Matsumoto <matz@caelum.co.jp>\n#\n#                       $Id$\n\nrequire \"tk\"\n\nTopLevel = TkToplevel\nFrame = TkFrame\nLabel = TkLabel\nButton = TkButton\nRadiobutton = TkRadioButton\nCheckbutton = TkCheckButton\nMessage = TkMessage\nEntry = TkEntry\nSpinbox = TkSpinbox\nText = TkText\nScale = TkScale\nScrollbar = TkScrollbar\nListbox = TkListbox\nMenu = TkMenu\nMenubutton = TkMenubutton\nCanvas = TkCanvas\nArc = TkcArc\nBitmap = TkcBitmap\nLine = TkcLine\nOval = TkcOval\nPolygon = TkcPolygon\nRectangle = TkcRectangle\nTextItem = TkcText\nWindowItem = TkcWindow\nBitmapImage = TkBitmapImage\nPhotoImage = TkPhotoImage\nSelection = TkSelection\nWinfo = TkWinfo\nPack = TkPack\nGrid = TkGrid\nPlace = TkPlace\nVariable = TkVariable\nFont = TkFont\nVirtualEvent = TkVirtualEvent\n\ndef Mainloop\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/lib/tkconsole.rb",
    "content": "#\n#   tkconsole.rb - load tk/console.rb\n#\nrequire 'tk/console'\n"
  },
  {
    "path": "ext/tk/lib/tkdialog.rb",
    "content": "#\n#   tkdialog.rb - load tk/dialog.rb\n#\nrequire 'tk/dialog'\n"
  },
  {
    "path": "ext/tk/lib/tkentry.rb",
    "content": "#\n#   tkentry.rb - load tk/entry.rb\n#\nrequire 'tk/entry'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/ICONS/icons.rb",
    "content": "#\n#  tkextlib/ICONS/icons.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/ICONS/setup.rb'\n\n# TkPackage.require('icons', '1.0')\nTkPackage.require('icons')\n\nmodule Tk\n  class ICONS < TkImage\n    extend Tk\n\n    PACKAGE_NAME = 'icons'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('icons')\n      rescue\n        ''\n      end\n    end\n\n    def self.create(*args)  # icon, icon, ..., ?option=>value, ...?\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        icons = simplelist(tk_call('::icons::icons', 'create', \n                                   *(hash_kv(keys) << (args.flatten))))\n      else\n        icons = simplelist(tk_call('::icons::icons', 'create', \n                                   args.flatten))\n      end\n\n      icons.collect{|icon| self.new(icon, :without_creating=>true)}\n    end\n\n    def self.delete(*icons)  # icon, icon, ...\n      icons = icons.flatten\n      return if icons.empty?\n      icons.map!{|icon|\n        if icon.kind_of?(Tk::ICONS)\n          Tk_IMGTBL.delete(icon.path)\n          icon.name\n        elsif icon.to_s =~ /^::icon::(.*)/\n          name = $1\n          Tk_IMGTBL.delete(icon)\n          name\n        else\n          Tk_IMGTBL.delete(\"::icon::#{icon}\")\n          icon\n        end\n      }\n      tk_call('::icons::icons', 'delete', icons)\n    end\n\n    def self.query(*args)  # icon, icon, ..., ?option=>value, ...?\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        simplelist(tk_call('::icons::icons', 'query', \n                           *(hash_kv(keys) << (args.flatten))))\n      else\n        simplelist(tk_call('::icons::icons', 'query', args.flatten))\n      end . map{|inf| list(inf) }\n    end\n\n    ##########################################\n\n    class << self\n      alias _new new\n\n      def new(name, keys=nil)\n        if obj = Tk_IMGTBL[\"::icon::#{name}\"]\n          if keys\n            keys = _symbolkey2str(keys)\n            unless keys.delete('without_creating')\n              tk_call('::icons::icons', 'create', *(hash_kv(keys) << obj.name))\n            end\n          end\n        else\n          obj = _new(name, keys)\n        end\n        obj\n      end\n    end\n\n    ##########################################\n\n    def initialize(name, keys=nil)\n      if name.kind_of?(String) && name =~ /^::icon::(.+)$/\n          @name = $1\n          @path = name\n      else\n        @name = name.to_s\n        @path = \"::icon::#{@name}\"\n      end\n      keys = _symbolkey2str(keys)\n      unless keys.delete('without_creating')\n        tk_call('::icons::icons', 'create', *(hash_kv(keys) << @name))\n      end\n      Tk_IMGTBL[@path] = self\n    end\n\n    def name\n      @name\n    end\n\n    def delete\n      Tk_IMGTBL.delete(@path)\n      tk_call('::icons::icons', 'delete', @name)\n      self\n    end\n\n    def query(keys={})\n      list(simplelist(tk_call('::icons::icons', 'query', \n                               *(hash_kv(keys) << @name))\n                      )[0])\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/ICONS/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/ICONS.rb",
    "content": "#\n#  ICONS support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/ICONS/setup.rb'\n\n# load library\nrequire 'tkextlib/ICONS/icons'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/SUPPORT_STATUS",
    "content": "\n  [ current support status of Tcl/Tk extensions ]\n\n  *** RELEASE_DATE of the libraries => see 'tkextlib/version.rb' ***\n\nThe following list shows *CURRENT* status when this file was modifyed\nat last. If you want to add other Tcl/Tk extensions to the planed list\n(or change its status position), please request them at the ruby-talk,\nruby-list, or ruby-dev ML. Although we cannot promise to support your \nrequests, we'll try to do. \n\nIf you want to check that wrapper libraries are ready to use on your \nenvironment, please execute 'pkg_checker.rb' with no arguments. The \nscript may give you some hints about that.\n\n\n  ***** IMPORTANT NOTE **********************************************\n\n    'support' means that Ruby/Tk's wrapper libraries are released. \n    'not support' does *NOT* mean that the extension doesn't work\n    on Ruby/Tk. \n\n    The version number of each extension means the latest version\n    which is checked its feature. That is, it does NOT means only \n    version of working. Library files maybe include some features \n    which is included in the former version but removed from the \n    latest, and maybe able to support the later version then the \n    shown version.\n\n    Even if the status of the extension is 'not support', you can \n    control the functions/widgets of the extension without wrapper \n    libraries by Tk.tk_call(), Tk.ip_eval(), and so on. \n\n    If you cannot use installed Tcl/Tk extension, please check the \n    followings. \n\n     (1) On your Tcl/Tk, does the extention work?\n\n     (2) Do DLL libraries of the extension exist on DLL load-path?\n         (See also \"<ruby archive>/ext/tcltklib/README.ActiveTcl\")\n\n     (3) Is the Tcl library directory of the extension included in \n         library search-path of the Tcl interpreter linked Ruby/Tk?\n\n    The check results may request you to do some setup operations \n    before using the extension. If so, then please write the step \n    of setup oprations into the \"setup.rb\" file in the directory \n    of the wrapper libraries for the extention (It is the wrapper\n    libraries have the standard structure of the libraries in this \n    directory). The \"setup\" file is required before requiring the \n    Tcl library package (TkPackage.require(<libname>)). \n\n  *******************************************************************\n\n\n===< support with some examples (may be beta quality) >=======================\n\nTcllib       1.8     \nTklib        0.4.1   http://sourceforge.net/projects/tcllib      ==> tcllib\n\nIWidgets     4.0.2   http://sourceforge.net/projects/incrtcl     ==> iwidgets\n\nBWidgets     1.7     http://sourceforge.net/projects/tcllib      ==> bwidget\n\nTkTable      2.9     http://sourceforge.net/projects/tktable     ==> tktable\n                         * see also <http://www.korus.hu/~fery/ruby/tktable.rb>\n                                    written by Ferenc Engard (ferenc@engard.hu)\n\nvu           2.3.0   http://sourceforge.net/projects/tktable     ==> vu\n\nTkHTML       2.0     http://www.hwaci.com/sw/tkhtml/             ==> tkHTML\n\nICONS        1.0     http://www.satisoft.com/tcltk/icons/        ==> ICONS\n\nTkImg        1.3     http://sourceforge.net/projects/tkimg       ==> tkimg\n\n\nBLT          2.4z    http://sourceforge.net/projects/blt\n                        * see also tcltk-ext library on RAA \n                                (http://raa.ruby-lang.org/)\n                      ==> blt\n\nTkTreeCtrl   CVS/Hd(2005-12-02)\n                     http://sourceforge.net/projects/tktreectrl  ==> treectrl\n\nTile         0.8.0/8.5.1\n                     http://sourceforge.net/projects/tktable     ==> tile\n\n\n\n===< support (may be alpha or beta quality) >=================================\n\nIncrTcl      CVS/Hd(2005-02-14)\n                     http://sourceforge.net/projects/incrtcl     ==> itcl, itk\n\nTclX         CVS/Hd(2005-02-07)\n                     http://sourceforge.net/projects/tclx\n                       ==> tclx (partial support; infox command and \n                                                   XPG/3 message catalogs only)\n\nTrofs        0.4.3   http://math.nist.gov/~DPorter/tcltk/trofs/\n\n\n\n===< possibly available (not tested; alpha quality) >=========================\n\nwinico       0.6\n                     http://sourceforge.net/projects/tktable\n                       ==> winico (win32 only)\n\nTkTrans      latest(2004-10-11)\n                     http://www2.cmp.uea.ac.uk/~fuzz/tktrans/default.html\n                       ==>  tktrans (win32 only)\n\nTkDND        1.0a2   http://sourceforge.net/projects/tkdnd       ==> tkDND\n\n\n\n===< plan to support (alpha quality libraries may be included) >==============\n\nGraphViz     ***     http://www.graphviz.org/\n\nTkgeomap     ***     http://tkgeomap.sourceforge.net/index.html\n\n\n\n===< not determined to supprt or not >========================================\n\nTix          ***     http://tixlibrary.sourceforge.net/\n                        * see also tcltk-ext library on RAA \n                                (http://raa.ruby-lang.org/)\n\nTkZinc       ***     http://www.tkzinc.org/\n\nWbc          ***     http://home.t-online.de/home/csaba.nemethi/\n\nMentry       ***     http://home.t-online.de/home/csaba.nemethi/\n\nTablelist    ***     http://home.t-online.de/home/csaba.nemethi/\n\nANIGIF       ***     http://cardtable.sourceforge.net/tcltk/\n\nIMG_ROTATE   ***     http://cardtable.sourceforge.net/tcltk/\n\nTclVfs       ***     http://sourceforge.net/projects/tclvfs/\n\nvfwtcl       ***     http://sourceforge.net/projects/avicaptcl\n                        * Win32 only\n\nmulticast    ***     http://sourceforge.net/projects/avicaptcl\n                        * Win32 only\n\nXBit         ***     http://www.geocities.com/~chengye/\n                        * current implementation is for Windows only\n\nQuickTimeTcl ***     http://hem.fyristorg.com/matben/qt/\n                        * works under Mac OS (8,9,X) or Windows\n\n\n\n===< may not support (already exist, out of Ruby/Tk scope, and so on) >=======\n\nTkCon        ***     http://sourceforge.net/projects/tkcon\n\nExpect       ***     http://sourceforge.net/projects/expect\n\nTclXML       ***     http://sourceforge.net/projects/tclxml\n\nTclXSLT      ***     http://sourceforge.net/projects/tclxml\n\nTclDOM       ***     http://sourceforge.net/projects/tclxml\n\nTclSOAP      ***     http://sourceforge.net/projects/tclsoap\n\nSnack        ***     http://www.speech.kth.se/~kare/snack2.2.tar.gz\n                        * use Snack for Ruby \n                              (see http://rbsnack.sourceforge.net/)\n\nTcom         ***     http://www.vex.net/~cthuang/tcom/\n\ntDOM         ***     http://www.tdom.org\n\nMk4tcl       ***     http://www.equi4.com/metakit/tcl.html\n\nMemchan      ***     http://sourceforge.net/projects/memchan\n\nXOTcl        ***     http://www.xotcl.org/\n\n\n===< tool (may not supprt) >==================================================\n\ntbcload/tclcompiler \n             ***     http://www.tcl.tk/software/tclpro/\n\n\n(End of List)\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/barchart.rb",
    "content": "#\n#  tkextlib/blt/barchart.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\nrequire 'tkextlib/blt/component.rb'\n\nmodule Tk::BLT\n  class Barchart < TkWindow\n    TkCommandNames = ['::blt::barchart'.freeze].freeze\n    WidgetClassName = 'Barchart'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    include PlotComponent\n    include GraphCommand\n\n    def __boolval_optkeys\n      ['bufferelements', 'buffergraph', 'invertxy']\n    end\n    private :__boolval_optkeys\n\n    def __strval_optkeys\n      ['text', 'label', 'title', 'file', \n        'background', 'plotbackground']\n    end\n    private :__strval_optkeys\n\n    def __tkvariable_optkeys\n      super() << 'colormap' << 'fontmap'\n    end\n    private :__tkvariable_optkeys\n\n=begin\n    BarElement_ID = ['blt_barchart_bar'.freeze, '00000'.taint].freeze\n\n    def bar(elem=nil, keys={})\n      if elem.kind_of?(Hash)\n        keys = elem\n        elem = nil\n      end\n      unless elem\n        elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze\n        BarElement_ID[1].succ!\n      end\n      tk_send('bar', elem, keys)\n      Element.new(self, elem, :without_creating=>true)\n    end\n=end\n\n    def extents(item)\n      num_or_str(tk_send_without_enc('extents', item))\n    end\n\n    def invtransform(x, y)\n      list(tk_send_without_enc('invtransform', x, y))\n    end\n\n    def inside(x, y)\n      bool(tk_send_without_enc('inside', x, y))\n    end\n\n    def metafile(file=None)\n      # Windows only\n      tk_send('metafile', file)\n      self\n    end\n\n    def snap(output, keys={})\n      tk_send_without_enc('snap', *(hash_kv(keys, false) + output))\n      self\n    end\n\n    def transform(x, y)\n      list(tk_send_without_enc('transform', x, y))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/bitmap.rb",
    "content": "#\n#  tkextlib/blt/bitmap.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Bitmap < TkObject\n    extend TkCore\n\n    TkCommandNames = ['::blt::bitmap'.freeze].freeze\n\n    BITMAP_ID_TBL = TkCore::INTERP.create_table\n\n    (BITMAP_ID = ['blt_bitmap_id'.freeze, '00000'.taint]).instance_eval{\n      @mutex = Mutex.new\n      def mutex; @mutex; end\n      freeze\n    }\n\n    TkCore::INTERP.init_ip_env{\n      BITMAP_ID_TBL.mutex.synchronize{ BITMAP_ID_TBL.clear }\n    }\n\n    def self.data(name)\n      dat = tk_simple_list(tk_call('::blt::bitmap', 'data', name))\n      [ tk_split_list(dat[0]), tk_simple_list(dat[1]) ]\n    end\n\n    def self.exist?(name)\n      bool(tk_call('::blt::bitmap', 'exists', name))\n    end\n\n    def self.height(name)\n      number(tk_call('::blt::bitmap', 'height', name))\n    end\n\n    def self.width(name)\n      number(tk_call('::blt::bitmap', 'width', name))\n    end\n\n    def self.source(name)\n      tk_simple_list(tk_call('::blt::bitmap', 'source', name))\n    end\n\n    #################################\n\n    class << self\n      alias _new new\n\n      def new(data, keys={})\n        _new(:data, nil, data, keys)\n      end\n      alias define new\n\n      def new_with_name(name, data, keys={})\n        _new(:data, name, data, keys)\n      end\n      alias define_with_name new_with_name\n\n      def compose(text, keys={})\n        _new(:text, nil, text, keys)\n      end\n\n      def compose_with_name(name, text, keys={})\n        _new(:text, name, text, keys)\n      end\n    end\n\n    def initialize(type, name, data, keys = {})\n      if name\n        @id = name\n      else\n        BITMAP_ID.mutex.synchronize{\n          @id = BITMAP_ID.join(TkCore::INTERP._ip_id_)\n          BITMAP_ID[1].succ!\n        }\n        BITMAP_ID_TBL.mutex.synchronize{\n          BITMAP_ID_TBL[@id] = self\n        }\n      end\n\n      @path = @id\n\n      unless bool(tk_call('::blt::bitmap', 'exists', @id))\n        if type == :text\n          tk_call('::blt::bitmap', 'compose', @id, data, *hash_kv(keys))\n        else # :data\n          tk_call('::blt::bitmap', 'define', @id, data, *hash_kv(keys))\n        end\n      end\n    end\n\n    def exist?\n      bool(tk_call('::blt::bitmap', 'exists', @id))\n    end\n\n    def height\n      number(tk_call('::blt::bitmap', 'height', @id))\n    end\n\n    def width\n      number(tk_call('::blt::bitmap', 'width', @id))\n    end\n\n    def source\n      tk_simple_list(tk_call('::blt::bitmap', 'source', @id))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/busy.rb",
    "content": "#\n#  tkextlib/blt/busy.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/itemconfig.rb'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module Busy\n    extend TkCore\n    extend TkItemConfigMethod\n\n    TkCommandNames = ['::blt::busy'.freeze].freeze\n\n    ###########################\n\n    class Shield < TkWindow\n      def self.shield_path(win)\n        win = window(win) unless win.kind_of?(TkWindow)\n        if win.kind_of?(Tk::Toplevel)\n          win.path + '._Busy'\n        else\n          win.path + '_Busy'\n        end\n      end\n\n      def initialize(win)\n        @path = self.class.shield_path(win)\n      end\n    end\n\n    def self.shield_path(win)\n      Tk::BLT::Busy::Shield.shield_path(win)\n    end\n  end\nend\n\nclass << Tk::BLT::Busy\n  def __item_config_cmd(win)\n    ['::blt::busy', 'configure', win]\n  end\n  private :__item_config_cmd\n\n  undef itemcget\n  alias configure itemconfigure\n  alias configinfo itemconfiginfo\n  alias current_configinfo current_itemconfiginfo\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ##################################\n\n  def hold(win, keys={})\n    tk_call('::blt::busy', 'hold', win, *hash_kv(keys))\n  end\n\n  def release(*wins)\n    tk_call('::blt::busy', 'release', *wins)\n  end\n\n  def forget(*wins)\n    tk_call('::blt::busy', 'forget', *wins)\n  end\n\n  def is_busy(pat=None)\n    tk_split_list(tk_call('::blt::busy', 'isbusy', pat))\n  end\n\n  def names(pat=None)\n    tk_split_list(tk_call('::blt::busy', 'names', pat))\n  end\n  alias windows names\n\n  def check(win)\n    bool(tk_call('::blt::busy', 'check', win))\n  end\n\n  def status(win)\n    bool(tk_call('::blt::busy', 'status', win))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/component.rb",
    "content": "#\n#  tkextlib/blt/component.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module PlotComponent\n    include TkItemConfigMethod\n\n    module OptKeys\n      def __item_font_optkeys(id)\n        ['font', 'tickfont', 'titlefont']\n      end\n      private :__item_font_optkeys\n\n      def __item_numstrval_optkeys(id)\n        ['xoffset', 'yoffset']\n      end\n      private :__item_numstrval_optkeys\n\n      def __item_boolval_optkeys(id)\n        ['hide', 'under', 'descending', 'logscale', 'loose', 'showticks', \n          'titlealternate', 'scalesymbols', 'minor', 'raised', \n          'center', 'decoration', 'landscape', 'maxpect']\n      end\n      private :__item_boolval_optkeys\n\n      def __item_strval_optkeys(id)\n        ['text', 'label', 'limits', 'title', \n          'show', 'file', 'maskdata', 'maskfile', \n          'color', 'titlecolor', 'fill', 'outline', 'offdash']\n      end\n      private :__item_strval_optkeys\n\n      def __item_listval_optkeys(id)\n        ['bindtags']\n      end\n      private :__item_listval_optkeys\n\n      def __item_numlistval_optkeys(id)\n        ['dashes', 'majorticks', 'minorticks']\n      end\n      private :__item_numlistval_optkeys\n\n      def __item_tkvariable_optkeys(id)\n        ['variable', 'textvariable', 'colormap', 'fontmap']\n      end\n      private :__item_tkvariable_optkeys\n    end\n\n    include OptKeys\n\n    def __item_cget_cmd(id)\n      if id.kind_of?(Array)\n        # id := [ type, name ]\n        [self.path, id[0], 'cget', id[1]]\n      else\n        [self.path, id, 'cget']\n      end\n    end\n    private :__item_cget_cmd\n\n    def __item_config_cmd(id)\n      if id.kind_of?(Array)\n        # id := [ type, name, ... ]\n        type, *names = id\n        [self.path, type, 'configure'].concat(names)\n      else\n        [self.path, id, 'configure']\n      end\n    end\n    private :__item_config_cmd\n\n    def __item_pathname(id)\n      if id.kind_of?(Array)\n        id = tagid(id[1])\n      end\n      [self.path, id].join(';')\n    end\n    private :__item_pathname\n\n    def axis_cget(id, option)\n      ret = itemcget(['axis', tagid(id)], option)\n    end\n    def axis_cget_strict(id, option)\n      ret = itemcget_strict(['axis', tagid(id)], option)\n    end\n    def axis_configure(*args)\n      slot = args.pop\n      if slot.kind_of?(Hash)\n        value = None\n        slot = _symbolkey2str(slot)\n        if cmd = slot.delete('command')\n          slot['command'] = proc{|w, tick| \n            cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n          }\n        end\n      else\n        value = slot\n        slot = args.pop\n        if slot == :command || slot == 'command'\n          cmd = value\n          value = proc{|w, tick| \n            cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n          }\n        end\n      end\n      id_list = args.flatten.collect!{|id| tagid(id)}.unshift('axis')\n      itemconfigure(id_list, slot, value)\n    end\n    def axis_configinfo(id, slot=nil)\n      itemconfiginfo(['axis', tagid(id)], slot)\n    end\n    def current_axis_configinfo(id, slot=nil)\n      current_itemconfiginfo(['axis', tagid(id)], slot)\n    end\n\n    def crosshairs_cget(option)\n      itemcget('crosshairs', option)\n    end\n    def crosshairs_cget_strict(option)\n      itemcget_strict('crosshairs', option)\n    end\n    def crosshairs_configure(slot, value=None)\n      itemconfigure('crosshairs', slot, value)\n    end\n    def crosshairs_configinfo(slot=nil)\n      itemconfiginfo('crosshairs', slot)\n    end\n    def current_crosshairs_configinfo(slot=nil)\n      current_itemconfiginfo('crosshairs', slot)\n    end\n\n    def element_cget(id, option)\n      itemcget(['element', tagid(id)], option)\n    end\n    def element_cget_strict(id, option)\n      itemcget_strict(['element', tagid(id)], option)\n    end\n    def element_configure(*args)\n      slot = args.pop\n      if slot.kind_of?(Hash)\n        value = None\n      else\n        value = slot\n        slot = args.pop\n      end\n      id_list = args.flatten.collect!{|id| tagid(id)}.unshift('element')\n      itemconfigure(id_list, slot, value)\n    end\n    def element_configinfo(id, slot=nil)\n      itemconfiginfo(['element', tagid(id)], slot)\n    end\n    def current_element_configinfo(id, slot=nil)\n      current_itemconfiginfo(['element', tagid(id)], slot)\n    end\n\n    def bar_cget(id, option)\n      itemcget(['bar', tagid(id)], option)\n    end\n    def bar_cget_strict(id, option)\n      itemcget_strict(['bar', tagid(id)], option)\n    end\n    def bar_configure(*args)\n      slot = args.pop\n      if slot.kind_of?(Hash)\n        value = None\n      else\n        value = slot\n        slot = args.pop\n      end\n      id_list = args.flatten.collect!{|id| tagid(id)}.unshift('bar')\n      itemconfigure(id_list, slot, value)\n    end\n    def bar_configinfo(id, slot=nil)\n      itemconfiginfo(['bar', tagid(id)], slot)\n    end\n    def current_bar_configinfo(id, slot=nil)\n      current_itemconfiginfo(['bar', tagid(id)], slot)\n    end\n\n    def line_cget(id, option)\n      itemcget(['line', tagid(id)], option)\n    end\n    def line_cget_strict(id, option)\n      itemcget_strict(['line', tagid(id)], option)\n    end\n    def line_configure(*args)\n      slot = args.pop\n      if slot.kind_of?(Hash)\n        value = None\n      else\n        value = slot\n        slot = args.pop\n      end\n      id_list = args.flatten.collect!{|id| tagid(id)}.unshift('line')\n      itemconfigure(id_list, slot, value)\n    end\n    def line_configinfo(id, slot=nil)\n      itemconfiginfo(['line', tagid(id)], slot)\n    end\n    def current_line_configinfo(id, slot=nil)\n      current_itemconfiginfo(['line', tagid(id)], slot)\n    end\n\n    def gridline_cget(option)\n      itemcget('grid', option)\n    end\n    def gridline_cget_strict(option)\n      itemcget_strict('grid', option)\n    end\n    def gridline_configure(slot, value=None)\n      itemconfigure('grid', slot, value)\n    end\n    def gridline_configinfo(slot=nil)\n      itemconfiginfo('grid', slot)\n    end\n    def current_gridline_configinfo(slot=nil)\n      current_itemconfiginfo('grid', slot)\n    end\n\n    def legend_cget(option)\n      itemcget('legend', option)\n    end\n    def legend_cget_strict(option)\n      itemcget_strict('legend', option)\n    end\n    def legend_configure(slot, value=None)\n      itemconfigure('legend', slot, value)\n    end\n    def legend_configinfo(slot=nil)\n      itemconfiginfo('legend', slot)\n    end\n    def current_legend_configinfo(slot=nil)\n      current_itemconfiginfo('legend', slot)\n    end\n\n    def pen_cget(id, option)\n      itemcget(['pen', tagid(id)], option)\n    end\n    def pen_cget_strict(id, option)\n      itemcget_strict(['pen', tagid(id)], option)\n    end\n    def pen_configure(*args)\n      slot = args.pop\n      if slot.kind_of?(Hash)\n        value = None\n      else\n        value = slot\n        slot = args.pop\n      end\n      id_list = args.flatten.collect!{|id| tagid(id)}.unshift('pen')\n      itemconfigure(id_list, slot, value)\n    end\n    def pen_configinfo(id, slot=nil)\n      itemconfiginfo(['pen', tagid(id)], slot)\n    end\n    def current_pen_configinfo(id, slot=nil)\n      current_itemconfiginfo(['pen', tagid(id)], slot)\n    end\n\n    def postscript_cget(option)\n      itemcget('postscript', option)\n    end\n    def postscript_cget_strict(option)\n      itemcget_strict('postscript', option)\n    end\n    def postscript_configure(slot, value=None)\n      itemconfigure('postscript', slot, value)\n    end\n    def postscript_configinfo(slot=nil)\n      itemconfiginfo('postscript', slot)\n    end\n    def current_postscript_configinfo(slot=nil)\n      current_itemconfiginfo('postscript', slot)\n    end\n\n    def marker_cget(id, option)\n      itemcget(['marker', tagid(id)], option)\n    end\n    def marker_cget_strict(id, option)\n      itemcget_strict(['marker', tagid(id)], option)\n    end\n    def marker_configure(*args)\n      slot = args.pop\n      if slot.kind_of?(Hash)\n        value = None\n      else\n        value = slot\n        slot = args.pop\n      end\n      id_list = args.flatten.collect!{|id| tagid(id)}.unshift('marker')\n      itemconfigure(id_list, slot, value)\n    end\n    def marker_configinfo(id, slot=nil)\n      itemconfiginfo(['marker', tagid(id)], slot)\n    end\n    def current_marker_configinfo(id, slot=nil)\n      current_itemconfiginfo(['marker', tagid(id)], slot)\n    end\n\n    alias __itemcget itemcget\n    alias __itemcget_strict itemcget_strict\n    alias __itemconfiginfo itemconfiginfo\n    alias __current_itemconfiginfo current_itemconfiginfo\n    private :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo\n\n    def itemcget_strict(tagOrId, option)\n      ret = __itemcget(tagid(tagOrId), option)\n      if option == 'bindtags' || option == :bindtags\n        ret.collect{|tag| TkBindTag.id2obj(tag)}\n      else\n        ret\n      end\n    end\n    def itemcget(tagOrId, option)\n      unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        itemcget_strict(tagOrId, option)\n      else\n        begin\n          itemcget_strict(tagOrId, option)\n        rescue => e\n          begin\n            if current_itemconfiginfo(tagOrId).has_key?(option.to_s)\n              # error on known option\n              fail e\n            else\n              # unknown option\n              nil\n            end\n          rescue\n            fail e  # tag error\n          end\n        end\n      end\n    end\n    def itemconfiginfo(tagOrId, slot = nil)\n      ret = __itemconfiginfo(tagid(tagOrId), slot)\n\n      if TkComm::GET_CONFIGINFO_AS_ARRAY\n        if slot\n          if slot == 'bindtags' || slot == :bindtags\n            ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)}\n            ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)}\n          end\n        else\n          if (inf = ret.assoc('bindtags'))\n            inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}\n            inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}\n          end\n        end\n\n      else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n        if (inf = ret['bindtags'])\n          inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}\n          inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}\n          ret['bindtags'] = inf\n        end\n      end\n\n      ret\n    end\n    def current_itemconfiginfo(tagOrId, slot = nil)\n      ret = __current_itemconfiginfo(tagid(tagOrId), slot)\n\n      if (val = ret['bindtags'])\n        ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)}\n      end\n\n      ret\n    end\n\n    private :itemcget, :itemcget_strict\n    private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n    #################\n\n    class Axis < TkObject\n      (OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n\n      AxisID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        AxisID_TBL.mutex.synchronize{ AxisID_TBL.clear }\n      }\n\n      def self.id2obj(chart, id)\n        cpath = chart.path\n        AxisID_TBL.mutex.synchronize{\n          return id unless AxisID_TBL[cpath]\n          AxisID_TBL[cpath][id]? AxisID_TBL[cpath][id]: id\n        }\n      end\n\n      def self.new(chart, axis=nil, keys={})\n        if axis.kind_of?(Hash)\n          keys = axis\n          axis = nil\n        end\n        if keys\n          keys = _symbolkey2str(keys)\n          not_create = keys.delete('without_creating')\n        else\n          not_create = false\n        end\n\n        obj = nil\n        AxisID_TBL.mutex.synchronize{\n          chart_path = chart.path\n          AxisID_TBL[chart_path] ||= {}\n          if axis && AxisID_TBL[chart_path][axis]\n            obj = AxisID_TBL[chart_path][axis]\n          else\n            (obj = self.allocate).instance_eval{\n              if axis\n                @axis = @id = axis.to_s\n              else\n                OBJ_ID.mutex.synchronize{\n                  @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze\n                  OBJ_ID[1].succ!\n                }\n              end\n              @path = @id\n              @parent = @chart = chart\n              @cpath = @chart.path\n              Axis::AxisID_TBL[@cpath][@axis] = self\n              unless not_create\n                tk_call(@chart, 'axis', 'create', @axis, keys)\n                return obj\n              end\n            }\n          end\n        }\n\n        obj.configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, axis=nil, keys={})\n        # dummy:: not called by 'new' method\n\n        if axis.kind_of?(Hash)\n          keys = axis\n          axis = nil\n        end\n        if axis\n          @axis = @id = axis.to_s\n        else\n          OBJ_ID.mutex.synchronize{\n            @axis = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze\n            OBJ_ID[1].succ!\n          }\n        end\n        @path = @id\n        @parent = @chart = chart\n        @cpath = @chart.path\n        # Axis::AxisID_TBL[@cpath][@axis] = self\n        keys = _symbolkey2str(keys)\n        unless keys.delete('without_creating')\n          # @chart.axis_create(@axis, keys)\n          tk_call(@chart, 'axis', 'create', @axis, keys)\n        end\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.axis_cget(@id, option)\n      end\n      def cget_strict(option)\n        @chart.axis_cget_strict(@id, option)\n      end\n      def configure(key, value=None)\n        @chart.axis_configure(@id, key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.axis_configinfo(@id, key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_axis_configinfo(@id, key)\n      end\n\n      def command(cmd=nil, &b)\n        if cmd\n          configure('command', cmd)\n        elsif b\n          configure('command', Proc.new(&b))\n        else\n          cget('command')\n        end\n      end\n\n      def delete\n        @chart.axis_delete(@id)\n        self\n      end\n\n      def invtransform(val)\n        @chart.axis_invtransform(@id, val)\n      end\n\n      def limits\n        @chart.axis_limits(@id)\n      end\n\n      def name\n        @axis\n      end\n        \n      def transform(val)\n        @chart.axis_transform(@id, val)\n      end\n\n      def view\n        @chart.axis_view(@id)\n        self\n      end\n\n      def use(name=None) # if @id == xaxis | x2axis | yaxis | y2axis\n        @chart.axis_use(@id, name)\n      end\n\n      def use_as(axis) # axis := xaxis | x2axis | yaxis | y2axis\n        @chart.axis_use(axis, @id)\n      end\n    end\n\n    #################\n\n    class Crosshairs < TkObject\n      CrosshairsID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        CrosshairsID_TBL.mutex.synchronize{ CrosshairsID_TBL.clear }\n      }\n\n      def self.new(chart, keys={})\n        obj = nil\n        CrosshairsID_TBL.mutex.synchronize{\n          unless (obj = CrosshairsID_TBL[chart.path])\n            (obj = self.allocate).instance_eval{\n              @parent = @chart = chart\n              @cpath = @chart.path\n              @path = @id = 'crosshairs'\n              Crosshairs::CrosshairsID_TBL[@cpath] = self\n            }\n          end\n        }\n        chart.crosshair_configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, keys={})\n        # dummy:: not called by 'new' method\n\n        @parent = @chart = chart\n        @cpath = @chart.path\n        # Crosshairs::CrosshairsID_TBL[@cpath] = self\n        @chart.crosshair_configure(keys) unless keys.empty?\n        @path = @id = 'crosshairs'\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.crosshair_cget(option)\n      end\n      def cget_strict(option)\n        @chart.crosshair_cget_strict(option)\n      end\n      def configure(key, value=None)\n        @chart.crosshair_configure(key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.crosshair_configinfo(key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_crosshair_configinfo(key)\n      end\n\n      def off\n        @chart.crosshair_off\n        self\n      end\n      def on\n        @chart.crosshair_on\n        self\n      end\n      def toggle\n        @chart.crosshair_toggle\n        self\n      end\n    end\n\n    #################\n\n    class Element < TkObject\n      extend Tk\n      extend TkItemFontOptkeys\n      extend TkItemConfigOptkeys\n\n      extend Tk::BLT::PlotComponent::OptKeys\n\n      ElementTypeName = 'element'\n      ElementTypeToClass = { ElementTypeName=>self }\n\n      ElementID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear }\n      }\n\n      (OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n\n      def Element.type2class(type)\n        ElementTypeToClass[type]\n      end\n\n      def Element.id2obj(chart, id)\n        cpath = chart.path\n        ElementID_TBL.mutex.synchronize{\n          return id unless ElementID_TBL[cpath]\n          ElementID_TBL[cpath][id]? ElementID_TBL[cpath][id]: id\n        }\n      end\n\n      def self.new(chart, element=nil, keys={})\n        if element.kind_of?(Hash)\n          keys = element\n          element = nil\n        end\n        if keys\n          keys = _symbolkey2str(keys)\n          not_create = keys.delete('without_creating')\n        else\n          not_create = false\n        end\n\n        obj = nil\n        ElementID_TBL.mutex.synchronize{\n          chart_path = chart.path\n          ElementID_TBL[chart_path] ||= {}\n          if element && ElementID_TBL[chart_path][element]\n            obj = ElementID_TBL[chart_path][element]\n          else\n            (obj = self.allocate).instance_eval{\n              if element\n                @element = @id = element.to_s\n              else\n                OBJ_ID.mutex.synchronize{\n                  @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze\n                  OBJ_ID[1].succ!\n                }\n              end\n              @path = @id\n              @parent = @chart = chart\n              @cpath = @chart.path\n              @typename = self.class::ElementTypeName\n              Element::ElementID_TBL[@cpath][@element] = self\n              unless not_create\n                tk_call(@chart, @typename, 'create', @element, keys)\n                return obj\n              end\n            }\n          end\n        }\n\n        obj.configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, element=nil, keys={})\n        # dummy:: not called by 'new' method\n\n        if element.kind_of?(Hash)\n          keys = element\n          element = nil\n        end\n        if element\n          @element = @id = element.to_s\n        else\n          OBJ_ID.mutex.synchronize{\n            @element = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze\n            OBJ_ID[1].succ!\n          }\n        end\n        @path = @id\n        @parent = @chart = chart\n        @cpath = @chart.path\n        @typename = self.class::ElementTypeName\n        # Element::ElementID_TBL[@cpath][@element] = self\n        keys = _symbolkey2str(keys)\n        unless keys.delete('without_creating')\n          # @chart.element_create(@element, keys)\n          tk_call(@chart, @typename, 'create', @element, keys)\n        end\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        # @chart.element_cget(@id, option)\n        @chart.__send__(@typename + '_cget', @id, option)\n      end\n      def cget_strict(option)\n        @chart.__send__(@typename + '_cget_strict', @id, option)\n      end\n      def configure(key, value=None)\n        # @chart.element_configure(@id, key, value)\n        @chart.__send__(@typename + '_configure', @id, key, value)\n        self\n      end\n      def configinfo(key=nil)\n        # @chart.element_configinfo(@id, key)\n        @chart.__send__(@typename + '_configinfo', @id, key)\n      end\n      def current_configinfo(key=nil)\n        # @chart.current_element_configinfo(@id, key)\n        @chart.__send__('current_' << @typename << '_configinfo', @id, key)\n      end\n\n      def activate(*args)\n        @chart.element_activate(@id, *args)\n      end\n\n      def closest(x, y, var, keys={})\n        # @chart.element_closest(x, y, var, @id, keys)\n        @chart.__send__(@typename + '_closest', x, y, var, @id, keys)\n      end\n\n      def deactivate\n        @chart.element_deactivate(@id)\n        self\n      end\n\n      def delete\n        @chart.element_delete(@id)\n        self\n      end\n\n      def exist?\n        @chart.element_exist?(@id)\n      end\n\n      def name\n        @element\n      end\n\n      def type\n        @chart.element_type(@id)\n      end\n    end\n\n    class Bar < Element\n      ElementTypeName = 'bar'.freeze\n      ElementTypeToClass[ElementTypeName] = self\n    end\n    class Line < Element\n      ElementTypeName = 'line'.freeze\n      ElementTypeToClass[ElementTypeName] = self\n    end\n\n    #################\n\n    class GridLine < TkObject\n      GridLineID_TBL = TkCore::INTERP.create_table\n      TkCore::INTERP.init_ip_env{\n        GridLineID_TBL.mutex.synchronize{ GridLineID_TBL.clear }\n      }\n\n      def self.new(chart, keys={})\n        obj = nil\n        GridLineID_TBL.mutex.synchronize{\n          unless (obj = GridLineID_TBL[chart.path])\n            (obj = self.allocate).instance_eval{\n              @parent = @chart = chart\n              @cpath = @chart.path\n              @path = @id = 'grid'\n              GridLine::GridLineID_TBL[@cpath] = self\n            }\n          end\n        }\n        chart.gridline_configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, keys={})\n        # dummy:: not called by 'new' method\n\n        @parent = @chart = chart\n        @cpath = @chart.path\n        # GridLine::GridLineID_TBL[@cpath] = self\n        @chart.gridline_configure(keys) unless keys.empty?\n        @path = @id = 'grid'\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.gridline_cget(option)\n      end\n      def cget_strict(option)\n        @chart.gridline_cget_strict(option)\n      end\n      def configure(key, value=None)\n        @chart.gridline_configure(key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.gridline_configinfo(key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_gridline_configinfo(key)\n      end\n\n      def off\n        @chart.gridline_off\n        self\n      end\n      def on\n        @chart.gridline_on\n        self\n      end\n      def toggle\n        @chart.gridline_toggle\n        self\n      end\n    end\n\n    #################\n\n    class Legend < TkObject\n      LegendID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        LegendID_TBL.mutex.synchronize{ LegendID_TBL.clear }\n      }\n\n      def self.new(chart, keys={})\n        obj = nil\n        LegenedID_TBL.mutex.synchronize{\n          unless (obj = LegenedID_TBL[chart.path])\n            (obj = self.allocate).instance_eval{\n              @parent = @chart = chart\n              @cpath = @chart.path\n              @path = @id = 'crosshairs'\n              Legend::LegenedID_TBL[@cpath] = self\n            }\n          end\n        }\n        chart.legend_configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, keys={})\n        # dummy:: not called by 'new' method\n\n        @parent = @chart = chart\n        @cpath = @chart.path\n        # Legend::LegendID_TBL[@cpath] = self\n        @chart.legend_configure(keys) unless keys.empty?\n        @path = @id = 'legend'\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.legend_cget(option)\n      end\n      def cget_strict(option)\n        @chart.legend_cget_strict(option)\n      end\n      def configure(key, value=None)\n        @chart.legend_configure(key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.legend_configinfo(key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_legend_configinfo(key)\n      end\n\n      def activate(*args)\n        @chart.legend_activate(*args)\n      end\n\n      def deactivate(*args)\n        @chart.legend_deactivate(*args)\n      end\n\n      def get(pos, y=nil)\n        @chart.legend_get(pos, y)\n      end\n    end\n\n    #################\n\n    class Pen < TkObject\n      (OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n\n      PenID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        PenID_TBL.mutex.synchronize{ PenID_TBL.clear }\n      }\n\n      def self.id2obj(chart, id)\n        cpath = chart.path\n        PenID_TBL.mutex.synchronize{\n          return id unless PenID_TBL[cpath]\n          PenID_TBL[cpath][id]? PenID_TBL[cpath][id]: id\n        }\n      end\n\n      def self.new(chart, pen=nil, keys={})\n        if pen.kind_of?(Hash)\n          keys = pen\n          pen = nil\n        end\n        if keys\n          keys = _symbolkey2str(keys)\n          not_create = keys.delete('without_creating')\n        else\n          not_create = false\n        end\n\n        obj = nil\n        PenID_TBL.mutex.synchronize{\n          chart_path = chart.path\n          PenID_TBL[chart_path] ||= {}\n          if pen && PenID_TBL[chart_path][pen]\n            obj = PenID_TBL[chart_path][pen]\n          else\n            (obj = self.allocate).instance_eval{\n              if pen\n                @pen = @id = pen.to_s\n              else\n                OBJ_ID.mutex.synchronize{\n                  @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze\n                  OBJ_ID[1].succ!\n                }\n              end\n              @path = @id\n              @parent = @chart = chart\n              @cpath = @chart.path\n              Pen::PenID_TBL[@cpath][@pen] = self\n              unless not_create\n                tk_call(@chart, 'pen', 'create', @pen, keys)\n                return obj\n              end\n            }\n          end\n        }\n\n        obj.configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, pen=nil, keys={})\n        if pen.kind_of?(Hash)\n          keys = pen\n          pen = nil\n        end\n        if pen\n          @pen = @id = pen.to_s\n        else\n          OBJ_ID.mutex.synchronize{\n            @pen = @id = OBJ_ID.join(TkCore::INTERP._ip_id_).freeze\n            OBJ_ID[1].succ!\n          }\n        end\n        @path = @id\n        @parent = @chart = chart\n        @cpath = @chart.path\n        Pen::PenID_TBL[@cpath][@pen] = self\n        keys = _symbolkey2str(keys)\n        unless keys.delete('without_creating')\n          # @chart.pen_create(@pen, keys)\n          tk_call(@chart, 'pen', 'create', @pen, keys)\n        end\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.pen_cget(@id, option)\n      end\n      def cget_strict(option)\n        @chart.pen_cget_strict(@id, option)\n      end\n      def configure(key, value=None)\n        @chart.pen_configure(@id, key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.pen_configinfo(@id, key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_pen_configinfo(@id, key)\n      end\n\n      def delete\n        @chart.pen_delete(@id)\n        self\n      end\n\n      def name\n        @pen\n      end\n    end\n\n    #################\n\n    class Postscript < TkObject\n      PostscriptID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        PostscriptID_TBL.mutex.synchronize{ PostscriptID_TBL.clear }\n      }\n\n      def self.new(chart, keys={})\n        obj = nil\n        PostscriptID_TBL.mutex.synchronize{\n          unless (obj = PostscriptID_TBL[chart.path])\n            (obj = self.allocate).instance_eval{\n              @parent = @chart = chart\n              @cpath = @chart.path\n              @path = @id = 'postscript'\n              Postscript::PostscriptID_TBL[@cpath] = self\n            }\n          end\n        }\n        chart.postscript_configure(keys) if obj && ! keys.empty?\n        obj\n      end\n\n      def initialize(chart, keys={})\n        # dummy:: not called by 'new' method\n\n        @parent = @chart = chart\n        @cpath = @chart.path\n        # Postscript::PostscriptID_TBL[@cpath] = self\n        @chart.postscript_configure(keys) unless keys.empty?\n        @path = @id = 'postscript'\n      end\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.postscript_cget(option)\n      end\n      def cget_strict(option)\n        @chart.postscript_cget_strict(option)\n      end\n      def configure(key, value=None)\n        @chart.postscript_configure(key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.postscript_configinfo(key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_postscript_configinfo(key)\n      end\n\n      def output(file=nil, keys={})\n        if file.kind_of?(Hash)\n          keys = file\n          file = nil\n        end\n\n        ret = @chart.postscript_output(file, keys)\n\n        if file\n          self\n        else\n          ret\n        end\n      end\n    end\n\n    #################\n    class Marker < TkObject\n      extend Tk\n      extend TkItemFontOptkeys\n      extend TkItemConfigOptkeys\n\n      extend Tk::BLT::PlotComponent::OptKeys\n\n      MarkerTypeName = nil\n      MarkerTypeToClass = {}\n      MarkerID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        MarkerID_TBL.mutex.synchronize{ MarkerID_TBL.clear }\n      }\n\n      def Marker.type2class(type)\n        MarkerTypeToClass[type]\n      end\n\n      def Marker.id2obj(chart, id)\n        cpath = chart.path\n        MarkerID_TBL.mutex.synchronize{\n          if MarkerID_TBL[cpath]\n            MarkerID_TBL[cpath][id]? MarkerID_TBL[cpath][id]: id\n          else\n            id\n          end\n        }\n      end\n\n      def self._parse_create_args(keys)\n        fontkeys = {}\n        methodkeys = {}\n        if keys.kind_of? Hash\n          keys = _symbolkey2str(keys)\n\n          __item_font_optkeys(nil).each{|key|\n            fkey = key.to_s\n            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n            fkey = \"kanji#{key}\"\n            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n            fkey = \"latin#{key}\"\n            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n\n            fkey = \"ascii#{key}\"\n            fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey)\n          }\n\n          __item_optkey_aliases(nil).each{|alias_name, real_name|\n            alias_name = alias_name.to_s\n            if keys.has_key?(alias_name)\n              keys[real_name.to_s] = keys.delete(alias_name)\n            end\n          }\n\n          __item_methodcall_optkeys(nil).each{|key|\n            key = key.to_s\n            methodkeys[key] = keys.delete(key) if keys.key?(key)\n          }\n\n          __item_ruby2val_optkeys(nil).each{|key, method|\n            key = key.to_s\n            keys[key] = method.call(keys[key]) if keys.has_key?(key)\n          }\n\n          args = itemconfig_hash_kv(nil, keys)\n        else\n          args = []\n        end\n\n        [args, fontkeys]\n      end\n      private_class_method :_parse_create_args\n\n      def self.create(chart, keys={})\n        unless self::MarkerTypeName\n          fail RuntimeError, \"#{self} is an abstract class\"\n        end\n        args, fontkeys = _parse_create_args(keys)\n        idnum = tk_call_without_enc(chart.path, 'marker', 'create', \n                                    self::MarkerTypeName, *args)\n        chart.marker_configure(idnum, fontkeys) unless fontkeys.empty?\n        idnum.to_i  # 'item id' is an integer number\n      end\n\n      def self.create_type(chart, type, keys={})\n        args, fontkeys = _parse_create_args(keys)\n        idnum = tk_call_without_enc(chart.path, 'marker', 'create', \n                                    type, *args)\n        chart.marker_configure(idnum, fontkeys) unless fontkeys.empty?\n        id = idnum.to_i  # 'item id' is an integer number\n        obj = self.allocate\n        obj.instance_eval{\n          @parent = @chart = chart\n          @cpath = chart.path\n          @id = id\n          Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{\n            Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {}\n            Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self\n          }\n        }\n        obj\n      end\n\n      def initialize(parent, *args)\n        @parent = @chart = parent\n        @cpath = parent.path\n\n        @path = @id = create_self(*args) # an integer number as 'item id'\n        Tk::BLT::PlotComponent::Marker::MarkerID_TBL.mutex.synchronize{\n          Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath] ||= {}\n          Tk::BLT::PlotComponent::Marker::MarkerID_TBL[@cpath][@id] = self\n        }\n      end\n      def create_self(*args)\n        self.class.create(@chart, *args) # return an integer as 'item id'\n      end\n      private :create_self\n\n      def id\n        @id\n      end\n\n      def to_eval\n        @id\n      end\n\n      def cget(option)\n        @chart.marker_cget(@id, option)\n      end\n      def cget_strict(option)\n        @chart.marker_cget_strict(@id, option)\n      end\n      def configure(key, value=None)\n        @chart.marker_configure(@id, key, value)\n        self\n      end\n      def configinfo(key=nil)\n        @chart.marker_configinfo(@id, key)\n      end\n      def current_configinfo(key=nil)\n        @chart.current_marker_configinfo(@id, key)\n      end\n\n      def after(target=None)\n        @chart.marker_after(@id, target)\n      end\n\n      def before(target=None)\n        @chart.marker_before(@id, target)\n      end\n\n      def delete\n        @chart.marker_delete(@id)\n      end\n\n      def exist?\n        @chart.marker_exist(@id)\n      end\n\n      def type\n        @chart.marker_type(@id)\n      end\n    end\n\n    class TextMarker < Marker\n      MarkerTypeName = 'text'.freeze\n      MarkerTypeToClass[MarkerTypeName] = self\n    end\n    class LineMarker < Marker\n      MarkerTypeName = 'line'.freeze\n      MarkerTypeToClass[MarkerTypeName] = self\n    end\n    class BitmapMarker < Marker\n      MarkerTypeName = 'bitmap'.freeze\n      MarkerTypeToClass[MarkerTypeName] = self\n    end\n    class ImageMarker < Marker\n      MarkerTypeName = 'image'.freeze\n      MarkerTypeToClass[MarkerTypeName] = self\n    end\n    class PolygonMarker < Marker\n      MarkerTypeName = 'polygon'.freeze\n      MarkerTypeToClass[MarkerTypeName] = self\n    end\n    class WindowMarker < Marker\n      MarkerTypeName = 'window'.freeze\n      MarkerTypeToClass[MarkerTypeName] = self\n    end\n\n    #################\n\n    def __destroy_hook__\n      Axis::AxisID_TBL.delete(@path)\n      Crosshairs::CrosshairsID_TBL.delete(@path)\n      Element::ElementID_TBL.delete(@path)\n      GridLine::GridLineID_TBL.delete(@path)\n      Legend::LegendID_TBL.delete(@path)\n      Pen::PenID_TBL.delete(@path)\n      Postscript::PostscriptID_TBL.delete(@path)\n      Marker::MarkerID_TBL.delete(@path)\n      super()\n    end\n\n    #################\n\n    def tagid(tag)\n      if tag.kind_of?(Axis) ||\n          tag.kind_of?(Crosshairs) ||\n          tag.kind_of?(Element) ||\n          tag.kind_of?(GridLine) ||\n          tag.kind_of?(Legend) ||\n          tag.kind_of?(Pen) ||\n          tag.kind_of?(Postscript) ||\n          tag.kind_of?(Marker)\n        tag.id\n      else\n        tag  # maybe an Array of configure paramters\n      end\n    end\n\n    def _component_bind(target, tag, context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind([path, target, 'bind', tagid(tag)], context, cmd, *args)\n      self\n    end\n    def _component_bind_append(target, tag, context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind_append([path, target, 'bind', tagid(tag)], context, cmd, *args)\n      self\n    end\n    def _component_bind_remove(target, tag, context)\n      _bind_remove([path, target, 'bind', tagid(tag)], context)\n      self\n    end\n    def _component_bindinfo(target, tag, context=nil)\n      _bindinfo([path, target, 'bind', tagid(tag)], context)\n    end\n    private :_component_bind, :_component_bind_append\n    private :_component_bind_remove, :_component_bindinfo\n\n    def axis_bind(tag, context, *args)\n      _component_bind('axis', tag, context, *args)\n    end\n    def axis_bind_append(tag, context, *args)\n      _component_bind_append('axis', tag, context, *args)\n    end\n    def axis_bind_remove(tag, context)\n      _component_bind_remove('axis', tag, context)\n    end\n    def axis_bindinfo(tag, context=nil)\n      _component_bindinfo('axis', tag, context)\n    end\n\n    def element_bind(tag, context, *args)\n      _component_bind('element', tag, context, *args)\n    end\n    def element_bind_append(tag, context, *args)\n      _component_bind_append('element', tag, context, *args)\n    end\n    def element_bind_remove(tag, context)\n      _component_bind_remove('element', tag, context)\n    end\n    def element_bindinfo(tag, context=nil)\n      _component_bindinfo('element', tag, context)\n    end\n\n    def bar_bind(tag, context, *args)\n      _component_bind('bar', tag, context, *args)\n    end\n    def bar_bind_append(tag, context, *args)\n      _component_bind_append('bar', tag, context, *args)\n    end\n    def bar_bind_remove(tag, context)\n      _component_bind_remove('bar', tag, context)\n    end\n    def bar_bindinfo(tag, context=nil)\n      _component_bindinfo('bar', tag, context)\n    end\n\n    def line_bind(tag, context, *args)\n      _component_bind('line', tag, context, *args)\n    end\n    def line_bind_append(tag, context, *args)\n      _component_bind_append('line', tag, context, *args)\n    end\n    def line_bind_remove(tag, context)\n      _component_bind_remove('line', tag, context)\n    end\n    def line_bindinfo(tag, context=nil)\n      _component_bindinfo('line', tag, context)\n    end\n\n    def legend_bind(tag, context, *args)\n      _component_bind('legend', tag, context, *args)\n    end\n    def legend_bind_append(tag, context, *args)\n      _component_bind_append('legend', tag, context, *args)\n    end\n    def legend_bind_remove(tag, context)\n      _component_bind_remove('legend', tag, context)\n    end\n    def legend_bindinfo(tag, context=nil)\n      _component_bindinfo('legend', tag, context)\n    end\n\n    def marker_bind(tag, context, *args)\n      _component_bind('marker', tag, context, *args)\n    end\n    def marker_bind_append(tag, context, *args)\n      _component_bind_append('marker', tag, context, *args)\n    end\n    def marker_bind_remove(tag, context)\n      _component_bind_remove('marker', tag, context)\n    end\n    def marker_bindinfo(tag, context=nil)\n      _component_bindinfo('marker', tag, context)\n    end\n\n    ###################\n\n    def axis_create(id=nil, keys={})\n      # tk_send('axis', 'create', tagid(id), keys)\n      Tk::BLT::PlotComponent::Axis.new(self, tagid(id), keys)\n    end\n    def axis_delete(*ids)\n      tk_send('axis', 'delete', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def axis_invtransform(id, val)\n      list(tk_send('axis', 'invtransform', tagid(id), val))\n    end\n    def axis_limits(id)\n      list(tk_send('axis', 'limits', tagid(id)))\n    end\n    def axis_names(*pats)\n      simplelist(tk_send('axis', 'names', \n                         *(pats.collect{|pat| tagid(pat)}))).collect{|axis|\n        Tk::BLT::PlotComponent::Axis.id2obj(self, axis)\n      }\n    end\n    def axis_transform(id, val)\n      list(tk_send('axis', 'transform', tagid(id), val))\n    end\n    def axis_view(id)\n      tk_send('axis', 'view', tagid(id))\n      self\n    end\n    def axis_use(id, target=nil)\n      if target\n        Tk::BLT::PlotComponent::Axis.id2obj(self, \n                                            tk_send('axis', 'use', \n                                                    tagid(id), tagid(target)))\n      else\n        Tk::BLT::PlotComponent::Axis.id2obj(self, \n                                            tk_send('axis', 'use', tagid(id)))\n      end\n    end\n\n    ###################\n\n    def crosshairs_off\n      tk_send_without_enc('crosshairs', 'off')\n      self\n    end\n    def crosshairs_on\n      tk_send_without_enc('crosshairs', 'on')\n      self\n    end\n    def crosshairs_toggle\n      tk_send_without_enc('crosshairs', 'toggle')\n      self\n    end\n\n    ###################\n\n    def element_create(id=nil, keys={})\n      # tk_send('element', 'create', tagid(id), keys)\n      Tk::BLT::PlotComponent::Element.new(self, tagid(id), keys)\n    end\n    def element_activate(*args)\n      if args.empty?\n        list(tk_send('element', 'activate')).collect{|elem|\n          Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n        }\n      else\n        # id, *indices\n        id = args.shift\n        tk_send('element', 'activate', tagid(id), *args)\n      end\n    end\n    def element_closest(x, y, var, *args)\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        bool(tk_send('element', 'closest', x, y, var, \n                     *(hash_kv(keys).concat(args.collect{|id| tagid(id)}))))\n      else\n        bool(tk_send('element', 'closest', x, y, var, \n                     *(args.collect{|id| tagid(id)})))\n      end\n    end\n    def element_deactivate(*ids)\n      tk_send('element', 'deactivate', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def element_delete(*ids)\n      tk_send('element', 'delete', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def element_exist?(id)\n      bool(tk_send('element', 'exists', tagid(id)))\n    end\n    def element_names(*pats)\n      simplelist(tk_send('element', 'names', \n                         *(pats.collect{|pat| tagid(pat)}))).collect{|elem|\n        Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n      }\n    end\n    def element_show(*names)\n      if names.empty?\n        simplelist(tk_send('element', 'show'))\n      else\n        tk_send('element', 'show', *(names.collect{|n| tagid(n)}))\n        self\n      end\n    end\n    def element_type(id)\n      tk_send('element', 'type', tagid(id))\n    end\n\n    ###################\n\n    def bar_create(id=nil, keys={})\n      # tk_send('bar', 'create', tagid(id), keys)\n      Tk::BLT::PlotComponent::Bar.new(self, tagid(id), keys)\n    end\n    alias bar bar_create\n    def bar_activate(*args)\n      if args.empty?\n        list(tk_send('bar', 'activate')).collect{|elem|\n          Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n        }\n      else\n        # id, *indices\n        id = args.shift\n        tk_send('bar', 'activate', tagid(id), *args)\n      end\n    end\n    def bar_closest(x, y, var, *args)\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        bool(tk_send('bar', 'closest', x, y, var, \n                     *(hash_kv(keys).concat(args.collect{|id| tagid(id)}))))\n      else\n        bool(tk_send('bar', 'closest', x, y, var, \n                     *(args.collect{|id| tagid(id)})))\n      end\n    end\n    def bar_deactivate(*ids)\n      tk_send('bar', 'deactivate', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def bar_delete(*ids)\n      tk_send('bar', 'delete', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def bar_exist?(id)\n      bool(tk_send('bar', 'exists', tagid(id)))\n    end\n    def bar_names(*pats)\n      simplelist(tk_send('bar', 'names', \n                         *(pats.collect{|pat| tagid(pat)}))).collect{|elem|\n        Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n      }\n    end\n    def bar_show(*names)\n      if names.empty?\n        simplelist(tk_send('bar', 'show'))\n      else\n        tk_send('bar', 'show', *(names.collect{|n| tagid(n)}))\n        self\n      end\n    end\n    def bar_type(id)\n      tk_send('bar', 'type', tagid(id))\n    end\n\n    ###################\n\n    def line_create(id=nil, keys={})\n      # tk_send('line', 'create', tagid(id), keys)\n      Tk::BLT::PlotComponent::Line.new(self, tagid(id), keys)\n    end\n    alias bar line_create\n    def line_activate(*args)\n      if args.empty?\n        list(tk_send('line', 'activate')).collect{|elem|\n          Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n        }\n      else\n        # id, *indices\n        id = args.shift\n        tk_send('line', 'activate', tagid(id), *args)\n      end\n    end\n    def line_closest(x, y, var, *args)\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        bool(tk_send('line', 'closest', x, y, var, \n                     *(hash_kv(keys).concat(args.collect{|id| tagid(id)}))))\n      else\n        bool(tk_send('line', 'closest', x, y, var, \n                     *(args.collect{|id| tagid(id)})))\n      end\n    end\n    def line_deactivate(*ids)\n      tk_send('line', 'deactivate', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def line_delete(*ids)\n      tk_send('line', 'delete', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def line_exist?(id)\n      bool(tk_send('line', 'exists', tagid(id)))\n    end\n    def line_names(*pats)\n      simplelist(tk_send('line', 'names', \n                         *(pats.collect{|pat| tagid(pat)}))).collect{|elem|\n        Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n      }\n    end\n    def line_show(*names)\n      if names.empty?\n        simplelist(tk_send('line', 'show'))\n      else\n        tk_send('line', 'show', *(names.collect{|n| tagid(n)}))\n        self\n      end\n    end\n    def line_type(id)\n      tk_send('line', 'type', tagid(id))\n    end\n\n    ###################\n\n    def gridline_off\n      tk_send_without_enc('grid', 'off')\n      self\n    end\n    def gridline_on\n      tk_send_without_enc('grid', 'on')\n      self\n    end\n    def gridline_toggle\n      tk_send_without_enc('grid', 'toggle')\n      self\n    end\n\n    ###################\n\n    def legend_window_create(parent=nil, keys=nil)\n      if parent.kind_of?(Hash)\n        keys = _symbolkey2str(parent)\n        parent = keys.delete('parent')\n        widgetname = keys.delete('widgetname')\n        keys.delete('without_creating')\n      elsif keys\n        keys = _symbolkey2str(keys)\n        widgetname = keys.delete('widgetname')\n        keys.delete('without_creating')\n      end\n\n      legend = self.class.new(parent, :without_creating=>true, \n                              :widgetname=>widgetname)\n      class << legend\n        def __destroy_hook__\n          TkCore::INTERP.tk_windows.delete(@path)\n        end\n      end\n\n      if keys\n        self.legend_configure(keys.update('position'=>legend))\n      else\n        self.legend_configure('position'=>legend)\n      end\n      legend\n    end\n\n    def legend_activate(*pats)\n      list(tk_send('legend', 'activate', \n                   *(pats.collect{|pat| tagid(pat)}))).collect{|elem|\n        Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n      }\n    end\n    def legend_deactivate(*pats)\n      list(tk_send('legend', 'deactivate', \n                   *(pats.collect{|pat| tagid(pat)}))).collect{|elem|\n        Tk::BLT::PlotComponent::Element.id2obj(self, elem)\n      }\n    end\n    def legend_get(pos, y=nil)\n      if y\n        Tk::BLT::PlotComponent::Element.id2obj(self, \n                                               tk_send('legend', 'get', \n                                                       _at(pos, y)))\n      else\n        Tk::BLT::PlotComponent::Element.id2obj(self, \n                                               tk_send('legend', 'get', pos))\n      end\n    end\n\n    ###################\n\n    def pen_create(id=nil, keys={})\n      # tk_send('pen', 'create', tagid(id), keys)\n      Tk::BLT::PlotComponent::Pen.new(self, tagid(id), keys)\n    end\n    def pen_delete(*ids)\n      tk_send('pen', 'delete', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def pen_names(*pats)\n      simplelist(tk_send('pen', 'names', \n                         *(pats.collect{|pat| tagid(pat)}))).collect{|pen|\n        Tk::BLT::PlotComponent::Pen.id2obj(self, pen)\n      }\n    end\n\n    ###################\n\n    def postscript_output(file=nil, keys={})\n      if file.kind_of?(Hash)\n        keys = file\n        file = nil\n      end\n\n      if file\n        tk_send('postscript', 'output', file, keys)\n        self\n      else\n        tk_send('postscript', 'output', keys)\n      end\n    end\n\n    ###################\n\n    def marker_create(type, keys={})\n      case type\n      when :text, 'text'\n        Tk::BLT::PlotComponent::TextMarker.new(self, keys)\n      when :line, 'line'\n        Tk::BLT::PlotComponent::LineMarker.new(self, keys)\n      when :bitmap, 'bitmap'\n        Tk::BLT::PlotComponent::BitmapMarker.new(self, keys)\n      when :image, 'image'\n        Tk::BLT::PlotComponent::ImageMarker.new(self, keys)\n      when :polygon, 'polygon'\n        Tk::BLT::PlotComponent::PolygonMarker.new(self, keys)\n      when :window, 'window'\n        Tk::BLT::PlotComponent::WindowMarker.new(self, keys)\n      else\n        if type.kind_of?(Tk::BLT::PlotComponent::Marker)\n          type.new(self, keys)\n        else\n          Tk::BLT::PlotComponent::Marker.create_type(self, type, keys)\n        end\n      end\n    end\n    def marker_after(id, target=nil)\n      if target\n        tk_send_without_enc('marker', 'after', tagid(id), tagid(target))\n      else\n        tk_send_without_enc('marker', 'after', tagid(id))\n      end\n      self\n    end\n    def marker_before(id, target=None)\n      if target\n        tk_send_without_enc('marker', 'before', tagid(id), tagid(target))\n      else\n        tk_send_without_enc('marker', 'before', tagid(id))\n      end\n      self\n    end\n    def marker_delete(*ids)\n      tk_send('marker', 'delete', *(ids.collect{|id| tagid(id)}))\n      self\n    end\n    def marker_exist?(id)\n      bool(tk_send('marker', 'exists', tagid(id)))\n    end\n    def marker_names(*pats)\n      simplelist(tk_send('marker', 'names', \n                         *(pats.collect{|pat| tagid(pat)}))).collect{|id|\n        Tk::BLT::PlotComponent::Marker.id2obj(self, id)\n      }\n    end\n    def marker_type(id)\n      tk_send('marker', 'type', tagid(id))\n    end\n\n    ###################\n\n    def xaxis_cget(option)\n      itemcget('xaxis', option)\n    end\n    def xaxis_cget_strict(option)\n      itemcget_strict('xaxis', option)\n    end\n    def xaxis_configure(slot, value=None)\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        if cmd = slot.delete('command')\n          slot['command'] = proc{|w, tick| \n            cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n          }\n        end\n      elsif slot == :command || slot == 'command'\n        cmd = value\n        value = proc{|w, tick| \n          cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n        }\n      end\n      itemconfigure('xaxis', slot, value)\n    end\n    def xaxis_configinfo(slot=nil)\n      itemconfiginfo('xaxis', slot)\n    end\n    def current_xaxis_configinfo(slot=nil)\n      current_itemconfiginfo('xaxis', slot)\n    end\n    def xaxis_bind(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind([path, 'xaxis', 'bind'], context, cmd, *args)\n      self\n    end\n    def xaxis_bind_append(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind_append([path, 'xaxis', 'bind'], context, cmd, *args)\n      self\n    end\n    def xaxis_bind_remove(context)\n      _bind_remove([path, 'xaxis', 'bind'], context)\n      self\n    end\n    def xaxis_bindinfo(context=nil)\n      _bindinfo([path, 'xaxis', 'bind'], context)\n    end\n    def xaxis_invtransform(val)\n      list(tk_send('xaxis', 'invtransform', val))\n    end\n    def xaxis_limits\n      list(tk_send('xaxis', 'limits'))\n    end\n    def xaxis_transform(val)\n      list(tk_send('xaxis', 'transform', val))\n    end\n    def xaxis_use(target=nil)\n      if target\n        Tk::BLT::PlotComponent::Axis.id2obj(self, \n                                            tk_send('xaxis', 'use', \n                                                    tagid(target)))\n      else\n        Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('xaxis', 'use'))\n      end\n    end\n\n    def x2axis_cget(option)\n      itemcget('x2axis', option)\n    end\n    def x2axis_cget_strict(option)\n      itemcget_strict('x2axis', option)\n    end\n    def x2axis_configure(slot, value=None)\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        if cmd = slot.delete('command')\n          slot['command'] = proc{|w, tick| \n            cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n          }\n        end\n      elsif slot == :command || slot == 'command'\n        cmd = value\n        value = proc{|w, tick| \n          cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n        }\n      end\n      itemconfigure('x2axis', slot, value)\n    end\n    def x2axis_configinfo(slot=nil)\n      itemconfiginfo('x2axis', slot)\n    end\n    def current_x2axis_configinfo(slot=nil)\n      current_itemconfiginfo('x2axis', slot)\n    end\n    def x2axis_bind(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind([path, 'x2axis', 'bind'], context, cmd, *args)\n      self\n    end\n    def x2axis_bind_append(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind_append([path, 'x2axis', 'bind'], context, cmd, *args)\n      self\n    end\n    def x2axis_bind_remove(context)\n      _bind_remove([path, 'x2axis', 'bind'], context)\n      self\n    end\n    def x2axis_bindinfo(context=nil)\n      _bindinfo([path, 'x2axis', 'bind'], context)\n    end\n    def x2axis_invtransform(val)\n      list(tk_send('x2axis', 'invtransform', val))\n    end\n    def x2axis_limits\n      list(tk_send('x2axis', 'limits'))\n    end\n    def x2axis_transform(val)\n      list(tk_send('x2axis', 'transform', val))\n    end\n    def x2axis_use(target=nil)\n      if target\n        Tk::BLT::PlotComponent::Axis.id2obj(self, \n                                            tk_send('x2axis', 'use', \n                                                    tagid(target)))\n      else\n        Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('x2axis', 'use'))\n      end\n    end\n\n    def yaxis_cget(option)\n      itemcget('yaxis', option)\n    end\n    def yaxis_cget_strict(option)\n      itemcget_strict('yaxis', option)\n    end\n    def yaxis_configure(slot, value=None)\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        if cmd = slot.delete('command')\n          slot['command'] = proc{|w, tick| \n            cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n          }\n        end\n      elsif slot == :command || slot == 'command'\n        cmd = value\n        value = proc{|w, tick| \n          cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n        }\n      end\n      itemconfigure('yaxis', slot, value)\n    end\n    def yaxis_configinfo(slot=nil)\n      itemconfiginfo('yaxis', slot)\n    end\n    def current_yaxis_configinfo(slot=nil)\n      current_itemconfiginfo('yaxis', slot)\n    end\n    def yaxis_bind(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind([path, 'yaxis', 'bind'], context, cmd, *args)\n      self\n    end\n    def yaxis_bind_append(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind_append([path, 'yaxis', 'bind'], context, cmd, *args)\n      self\n    end\n    def yaxis_bind_remove(context)\n      _bind_remove([path, 'yaxis', 'bind'], context)\n      self\n    end\n    def yaxis_bindinfo(context=nil)\n      _bindinfo([path, 'yaxis', 'bind'], context)\n    end\n    def yaxis_invtransform(val)\n      list(tk_send('yaxis', 'invtransform', val))\n    end\n    def yaxis_limits\n      list(tk_send('yaxis', 'limits'))\n    end\n    def yaxis_transform(val)\n      list(tk_send('yaxis', 'transform', val))\n    end\n    def yaxis_use(target=nil)\n      if target\n        Tk::BLT::PlotComponent::Axis.id2obj(self, \n                                            tk_send('yaxis', 'use', \n                                                    tagid(target)))\n      else\n        Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('yaxis', 'use'))\n      end\n    end\n\n    def y2axis_cget(option)\n      itemcget('y2axis', option)\n    end\n    def y2axis_cget_strict(option)\n      itemcget_strict('y2axis', option)\n    end\n    def y2axis_configure(slot, value=None)\n      if slot.kind_of?(Hash)\n        slot = _symbolkey2str(slot)\n        if cmd = slot.delete('command')\n          slot['command'] = proc{|w, tick| \n            cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n          }\n        end\n      elsif slot == :command || slot == 'command'\n        cmd = value\n        value = proc{|w, tick| \n          cmd.call(TkComm.window(w), TkComm.num_or_str(tick))\n        }\n      end\n      itemconfigure('y2axis', slot, value)\n    end\n    def y2axis_configinfo(slot=nil)\n      axis_configinfo('y2axis', slot)\n    end\n    def current_y2axis_configinfo(slot=nil)\n      current_itemconfiginfo('y2axis', slot)\n    end\n    def y2axis_bind(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind([path, 'y2axis', 'bind'], context, cmd, *args)\n      self\n    end\n    def y2axis_bind_append(context, *args)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind_append([path, 'y2axis', 'bind'], context, cmd, *args)\n      self\n    end\n    def y2axis_bind_remove(context)\n      _bind_remove([path, 'y2axis', 'bind'], context)\n      self\n    end\n    def y2axis_bindinfo(context=nil)\n      _bindinfo([path, 'y2axis', 'bind'], context)\n    end\n    def y2axis_invtransform(val)\n      list(tk_send('y2axis', 'invtransform', val))\n    end\n    def y2axis_limits\n      list(tk_send('y2axis', 'limits'))\n    end\n    def y2axis_transform(val)\n      list(tk_send('y2axis', 'transform', val))\n    end\n    def y2axis_use(target=nil)\n      if target\n        Tk::BLT::PlotComponent::Axis.id2obj(self, \n                                            tk_send('y2axis', 'use', \n                                                    tagid(target)))\n      else\n        Tk::BLT::PlotComponent::Axis.id2obj(self, tk_send('y2axis', 'use'))\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/container.rb",
    "content": "#\n#  tkextlib/blt/container.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Container < TkWindow\n    TkCommandNames = ['::blt::container'.freeze].freeze\n    WidgetClassName = 'Container'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    def __strval_optkeys\n      super() << 'name'\n    end\n    private :__strval_optkeys\n\n    def find_command(pat)\n      Hash[*simplelist(tk_send_without_enc('find', '-command', pat))]\n    end\n\n    def find_name(pat)\n      Hash[*simplelist(tk_send_without_enc('find', '-name', pat))]\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/cutbuffer.rb",
    "content": "#\n#  tkextlib/blt/cutbuffer.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module CutBuffer\n    TkCommandNames = ['::blt::cutbuffer'.freeze].freeze\n\n    def self.get(num = 0)\n      Tk.tk_call('::blt::cutbuffer', 'get', num)\n    end\n    def self.rotate(count = 1)\n      Tk.tk_call('::blt::cutbuffer', 'rotate', count)\n    end\n    def self.set(val, num = 0)\n      Tk.tk_call('::blt::cutbuffer', 'set', val, num)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/dragdrop.rb",
    "content": "#\n#  tkextlib/blt/dragdrop.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/itemconfig'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module DragDrop\n    extend TkCore\n\n    TkCommandNames = ['::blt::drag&drop'.freeze].freeze\n\n    class Token < TkWindow\n      WidgetClassName = 'DragDropToken'.freeze\n      WidgetClassNames[WidgetClassName] = self\n\n      def initialize(arg)\n        if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token\n          arg = _symbolkey2str(arg)\n          install_win(nil, arg['widgetname'])\n        else  # arg is a drag&drop source\n          tk_call('::blt::drag&drop', 'source', arg)\n          install_win(nil, tk_call('::blt::drag&drop', 'token', arg))\n        end\n      end\n    end\n\n    ###################################\n\n    extend TkItemConfigMethod\n    extend Tk::ValidateConfigure\n\n    class << self\n      def __item_config_cmd(id)  # id := ['source'|'target', win]\n        ['::blt::drag&drop', id[0], id[1]]\n      end\n      private :__item_config_cmd\n\n      def __item_boolval_optkeys(id)\n        super(id) << 'selftarget'\n      end\n      private :__item_boolval_optkeys\n\n      def __item_listval_optkeys(id)\n        super(id) << 'send'\n      end\n      private :__item_listval_optkeys\n\n      def __item_strval_optkeys(id)\n        super(id) << 'rejectbg' << 'rejectfg' << 'tokenbg'\n      end\n      private :__item_strval_optkeys\n\n      undef itemcget\n      private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n      def source_configure(win, slot, value=None)\n        itemconfigure(['source', win], slot, value)\n      end\n      def source_configinfo(win, slot=nil)\n        itemconfiginfo(['source', win], slot)\n      end\n      def current_source_configinfo(win, slot=nil)\n        current_itemconfiginfo(['source', win], slot)\n      end\n    end\n\n    class PackageCommand < TkValidateCommand\n      class ValidateArgs < TkUtil::CallbackSubst\n        KEY_TBL = [\n          [ ?t, ?w, :token ],\n          [ ?W, ?w, :widget ],\n          nil\n        ]\n\n        PROC_TBL = [\n          [ ?w, TkComm.method(:window) ], \n          nil\n        ]\n\n=begin\n        # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n        KEY_TBL.map!{|inf|\n          if inf.kind_of?(Array)\n            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n            inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n          end\n          inf\n        }\n\n        PROC_TBL.map!{|inf|\n          if inf.kind_of?(Array)\n            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          end\n          inf\n        }\n=end\n\n        _setup_subst_table(KEY_TBL, PROC_TBL)\n\n        def self.ret_val(val)\n          val\n        end\n      end\n\n      def self._config_keys\n        ['packagecmd']\n      end\n    end\n\n    class SiteCommand < TkValidateCommand\n      class ValidateArgs < TkUtil::CallbackSubst\n        KEY_TBL = [\n          [ ?s, ?b, :compatible ],\n          [ ?t, ?w, :token ],\n          nil\n        ]\n\n        PROC_TBL = [\n          [ ?b, TkComm.method(:bool) ], \n          [ ?w, TkComm.method(:window) ], \n          nil\n        ]\n\n=begin\n        # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n        KEY_TBL.map!{|inf|\n          if inf.kind_of?(Array)\n            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n            inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n          end\n          inf\n        }\n\n        PROC_TBL.map!{|inf|\n          if inf.kind_of?(Array)\n            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          end\n          inf\n        }\n=end\n\n        _setup_subst_table(KEY_TBL, PROC_TBL)\n\n        def self.ret_val(val)\n          val\n        end\n      end\n\n      def self._config_keys\n        ['sitecmd']\n      end\n    end\n\n    def self.__validation_class_list\n      super() << PackageCommand << SiteCommand\n    end\n\n    class << self\n      Tk::ValidateConfigure.__def_validcmd(binding, PackageCommand)\n      Tk::ValidateConfigure.__def_validcmd(binding, SiteCommand)\n    end\n\n    ###################################\n\n    class DnD_Handle < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?i, ?s, :ip_name ],\n        [ ?v, ?v, :value ],\n        [ ?W, ?w, :widget ],\n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?i, TkComm.method(:string) ], \n        [ ?v, TkComm.method(:tk_tcl2ruby) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL)\n    end\n\n    def self.source_handler(win, datatype, cmd=Proc.new, *args)\n      _bind_for_event_class(DnD_Handle, \n                            ['::blt::drag&drop', 'source', win, 'handler'], \n                            cmd, *args)\n    end\n\n    def self.target_handler(win, datatype, cmd=Proc.new, *args)\n      _bind_for_event_class(DnD_Handle, \n                            ['::blt::drag&drop', 'target', win, 'handler'], \n                            cmd, *args)\n    end\n\n    ###################################\n\n    def self.init_source(win)\n      tk_call('::blt::drag&drop', 'source', win)\n    end\n\n    def self.source()\n      list(tk_call('::blt::drag&drop', 'source'))\n    end\n\n    def self.source_handler_list(win)\n      simplelist(tk_call('::blt::drag&drop', 'source', win, 'handler'))\n    end\n    def self.source_handler_info(win, type)\n      tk_tcl2ruby(tk_call('::blt::drag&drop', 'source', win, 'handler', type))\n    end\n\n    def self.target\n      list(tk_call('::blt::drag&drop', 'target'))\n    end\n    def self.target_handler_list(win)\n      simplelist(tk_call('::blt::drag&drop', 'target', win, 'handler'))\n    end\n\n    def self.handle_target(win, type, val=None)\n      tk_call('::blt::drag&drop', 'target', win, 'handle', type, val)\n    end\n\n    def self.token(win)\n      window(tk_call('::blt::drag&drop', 'token', win))\n    end\n\n    def self.drag(win, x, y)\n      tk_call('::blt::drag&drop', 'drag', win, x, y)\n    end\n    def self.drop(win, x, y)\n      tk_call('::blt::drag&drop', 'drop', win, x, y)\n    end\n\n    def self.errors(cmd=Proc.new)\n      tk_call('::blt::drag&drop', 'errors', cmd)\n    end\n\n    def self.active\n      bool(tk_call('::blt::drag&drop', 'active'))\n    end\n\n    def self.location(x=None, y=None)\n      list(tk_call('::blt::drag&drop', 'location', x, y))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/eps.rb",
    "content": "#\n#  tkextlib/blt/eps.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/canvas'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class EPS < TkcItem\n    CItemTypeName = 'eps'.freeze\n    CItemTypeToClass[CItemTypeName] = self\n  end\nend\n\nclass Tk::Canvas\n  alias __BLT_EPS_item_strval_optkeys __item_strval_optkeys\n  def __item_strval_optkeys(id)\n    __BLT_EPS_item_strval_optkeys(id) + [\n      'shadowcolor', 'title', 'titlecolor'\n    ]\n  end\n  private :__item_strval_optkeys\n\n  alias __BLT_EPS_item_boolval_optkeys __item_boolval_optkeys\n  def __item_boolval_optkeys(id)\n    __BLT_EPS_item_boolval_optkeys(id) + ['showimage']\n  end\n  private :__item_boolval_optkeys\nend\n\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/graph.rb",
    "content": "#\n#  tkextlib/blt/graph.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\nrequire 'tkextlib/blt/component.rb'\n\nmodule Tk::BLT\n  class Graph < TkWindow\n    TkCommandNames = ['::blt::graph'.freeze].freeze\n    WidgetClassName = 'Graph'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    include PlotComponent\n    include GraphCommand\n\n    def __boolval_optkeys\n      ['bufferelements', 'invertxy']\n    end\n    private :__boolval_optkeys\n\n    def __strval_optkeys\n      ['text', 'label', 'title', 'file', 'plotbackground']\n    end\n    private :__strval_optkeys\n\n=begin\n    BarElement_ID = ['blt_graph_bar'.freeze, '00000'.taint].freeze\n\n    def bar(elem=nil, keys={})\n      if elem.kind_of?(Hash)\n        keys = elem\n        elem = nil\n      end\n      unless elem\n        elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze\n        BarElement_ID[1].succ!\n      end\n      tk_send('bar', elem, keys)\n      Element.new(self, elem, :without_creating=>true)\n    end\n=end\n\n    def extents(item)\n      num_or_str(tk_send_without_enc('extents', item))\n    end\n\n    def invtransform(x, y)\n      list(tk_send_without_enc('invtransform', x, y))\n    end\n\n    def inside(x, y)\n      bool(tk_send_without_enc('inside', x, y))\n    end\n\n    def snap(output, keys={})\n      tk_send_without_enc('snap', *(hash_kv(keys, false) + output))\n      self\n    end\n\n    def transform(x, y)\n      list(tk_send_without_enc('transform', x, y))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/htext.rb",
    "content": "#\n#  tkextlib/blt/htext.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/itemconfig.rb'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Htext<TkWindow\n    Htext_Var = TkVarAccess.new_hash('htext')\n    Htext_Widget = TkVarAccess.new('htext(widget)', :window)\n    Htext_File = TkVarAccess.new('htext(file)')\n    Htext_Line = TkVarAccess.new('htext(line)')\n\n    include TkItemConfigMethod\n    include Scrollable\n\n    TkCommandNames = ['::blt::htext'.freeze].freeze\n    WidgetClassName = 'Htext'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    alias window_cget itemcget\n    alias window_cget_strict itemcget_strict\n    alias window_configure itemconfigure\n    alias window_configuinfo itemconfiginfo\n    alias current_window_configuinfo current_itemconfiginfo\n\n    def __strval_optkeys\n      super() << 'filename'\n    end\n  private :__strval_optkeys\n\n    def append(win, keys={})\n      tk_send('append', _epath(win), keys)\n      self\n    end\n\n    def goto_line(idx)\n      tk_send_without_enc('gotoline', idx)\n      self\n    end\n    def current_line\n      number(tk_send_without_enc('gotoline'))\n    end\n\n    def index(str)\n      number(tk_send('index', str))\n    end\n\n    def line_pos(str)\n      tk_send('linepos', str)\n    end\n\n    def range(from=None, to=None)\n      tk_send_without_enc('range', from, to)\n    end\n\n    def scan_mark(pos)\n      tk_send_without_enc('scan', 'mark', pos)\n      self\n    end\n\n    def scan_dragto(pos)\n      tk_send_without_enc('scan', 'dragto', pos)\n      self\n    end\n\n    def search(pat, from=None, to=None)\n      num = number(tk_send('search', pat, from, to))\n      (num < 0)? nil: num\n    end\n\n    def selection_adjust(index)\n      tk_send_without_enc('selection', 'adjust', index)\n      self\n    end\n    def selection_clear()\n      tk_send_without_enc('selection', 'clear')\n      self\n    end\n    def selection_from(index)\n      tk_send_without_enc('selection', 'from', index)\n      self\n    end\n    def selection_line(index)\n      tk_send_without_enc('selection', 'line', index)\n      self\n    end\n    def selection_present()\n      bool(tk_send_without_enc('selection', 'present'))\n    end\n    def selection_range(first, last)\n      tk_send_without_enc('selection', 'range', first, last)\n      self\n    end\n    def selection_to(index)\n      tk_send_without_enc('selection', 'to', index)\n      self\n    end\n    def selection_word(index)\n      tk_send_without_enc('selection', 'word', index)\n      self\n    end\n\n    def windows(pat=None)\n      list(tk_send('windows', pat))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/spline.rb",
    "content": "#\n#  tkextlib/blt/spline.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module Spline\n    extend TkCore\n\n    TkCommandNames = ['::blt::spline'.freeze].freeze\n\n    def self.natural(x, y, sx, sy)\n      tk_call('::blt::spline', 'natural', x, y, sx, sy)\n    end\n\n    def self.quadratic(x, y, sx, sy)\n      tk_call('::blt::spline', 'quadratic', x, y, sx, sy)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/stripchart.rb",
    "content": "#\n#  tkextlib/blt/stripchart.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\nrequire 'tkextlib/blt/component.rb'\n\nmodule Tk::BLT\n  class Stripchart < TkWindow\n    TkCommandNames = ['::blt::stripchart'.freeze].freeze\n    WidgetClassName = 'Stripchart'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    include PlotComponent\n    include GraphCommand\n\n    def __boolval_optkeys\n      ['bufferelements', 'buffergraph', 'invertxy']\n    end\n    private :__boolval_optkeys\n\n    def __strval_optkeys\n      ['text', 'label', 'title', 'file', \n        'background', 'plotbackground']\n    end\n    private :__strval_optkeys\n\n=begin\n    BarElement_ID = ['blt_stripchart_bar'.freeze, '00000'.taint].freeze\n\n    def bar(elem=nil, keys={})\n      if elem.kind_of?(Hash)\n        keys = elem\n        elem = nil\n      end\n      unless elem\n        elem = BarElement_ID.join(TkCore::INTERP._ip_id_).freeze\n        BarElement_ID[1].succ!\n      end\n      tk_send('bar', elem, keys)\n      Element.new(self, elem, :without_creating=>true)\n    end\n=end\n\n    def extents(item)\n      num_or_str(tk_send_without_enc('extents', item))\n    end\n\n    def invtransform(x, y)\n      list(tk_send_without_enc('invtransform', x, y))\n    end\n\n    def inside(x, y)\n      bool(tk_send_without_enc('inside', x, y))\n    end\n\n    def metafile(file=None)\n      # Windows only\n      tk_send('metafile', file)\n      self\n    end\n\n    def snap(output, keys={})\n      tk_send_without_enc('snap', *(hash_kv(keys, false) + output))\n      self\n    end\n\n    def transform(x, y)\n      list(tk_send_without_enc('transform', x, y))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/table.rb",
    "content": "#\n#  tkextlib/blt/table.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/itemconfig.rb'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module Table\n    include Tk\n    extend Tk\n    extend TkItemConfigMethod\n\n    TkCommandNames = ['::blt::table'.freeze].freeze\n\n    module TableContainer\n      def blt_table_add(*args)\n        Tk::BLT::Table.add(self, *args)\n        self\n      end\n\n      def blt_table_arrange()\n        Tk::BLT::Table.arrange(self)\n        self\n      end\n\n      def blt_table_cget(*args)\n        Tk::BLT::Table.cget(self, *args)\n      end\n      def blt_table_cget_strict(*args)\n        Tk::BLT::Table.cget_strict(self, *args)\n      end\n\n      def blt_table_configure(*args)\n        Tk::BLT::Table.configure(self, *args)\n        self\n      end\n\n      def blt_table_configinfo(*args)\n        Tk::BLT::Table.configinfo(self, *args)\n      end\n\n      def blt_table_current_configinfo(*args)\n        Tk::BLT::Table.current_configinfo(self, *args)\n      end\n\n      def blt_table_locate(x, y)\n        Tk::BLT::Table.locate(self, x, y)\n      end\n\n      def blt_table_delete(*args)\n        Tk::BLT::Table.delete(self, *args)\n        self\n      end\n\n      def blt_table_extents(item)\n        Tk::BLT::Table.extents(self, item)\n      end\n\n      def blt_table_insert(*args)\n        Tk::BLT::Table.insert(self, *args)\n        self\n      end\n\n      def blt_table_insert_before(*args)\n        Tk::BLT::Table.insert_before(self, *args)\n        self\n      end\n\n      def blt_table_insert_after(*args)\n        Tk::BLT::Table.insert_after(self, *args)\n        self\n      end\n\n      def blt_table_join(first, last)\n        Tk::BLT::Table.join(self, first, last)\n        self\n      end\n\n      def blt_table_save()\n        Tk::BLT::Table.save(self)\n      end\n\n      def blt_table_search(*args)\n        Tk::BLT::Table.search(self, *args)\n      end\n\n      def blt_table_split(*args)\n        Tk::BLT::Table.split(self, *args)\n        self\n      end\n\n      def blt_table_itemcget(*args)\n        Tk::BLT::Table.itemcget(self, *args)\n      end\n      def blt_table_itemcget_strict(*args)\n        Tk::BLT::Table.itemcget_strict(self, *args)\n      end\n\n      def blt_table_itemconfigure(*args)\n        Tk::BLT::Table.itemconfigure(self, *args)\n        self\n      end\n\n      def blt_table_itemconfiginfo(*args)\n        Tk::BLT::Table.itemconfiginfo(self, *args)\n      end\n\n      def blt_table_current_itemconfiginfo(*args)\n        Tk::BLT::Table.current_itemconfiginfo(self, *args)\n      end\n\n      def blt_table_iteminfo(item)\n        Tk::BLT::Table.iteminfo(self, item)\n      end\n    end\n  end\nend\n\n\n############################################\nclass << Tk::BLT::Table\n  def __item_cget_cmd(id) # id := [ container, item ]\n    win = (id[0].kind_of?(TkWindow))? id[0].path: id[0].to_s\n    ['::blt::table', 'cget', win, id[1]]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id) # id := [ container, item, ... ]\n    container, *items = id\n    win = (container.kind_of?(TkWindow))? container.path: container.to_s\n    ['::blt::table', 'configure', win, *items]\n  end\n  private :__item_config_cmd\n\n  def __item_pathname(id)\n    win = (id[0].kind_of?(TkWindow))? id[0].path: id[0].to_s\n    win + ';'\n  end\n  private :__item_pathname\n\n  alias __itemcget itemcget\n  alias __itemcget_strict itemcget_strict\n  alias __itemconfigure itemconfigure\n  alias __itemconfiginfo itemconfiginfo\n  alias __current_itemconfiginfo current_itemconfiginfo\n\n  private :__itemcget, :__itemcget_strict\n  private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo\n\n  def __boolval_optkeys\n    super() << 'propagate'\n  end\n  private :__boolval_optkeys\n\n  def tagid(tag)\n    if tag.kind_of?(Array)\n      case tag[0]\n      when Integer\n        # [row, col]\n        tag.join(',')\n      when :c, :C, 'c', 'C', :r, :R, 'r', 'R'\n        # c0 or r1 or C*, and so on\n        tag.collect{|elem| elem.to_s}.join('')\n      else\n        tag\n      end\n    elsif tag.kind_of?(TkWindow)\n      _epath(tag)\n    else\n      tag\n    end\n  end\n\n  def tagid2obj(tagid)\n    tagid\n  end\n\n  ############################################\n\n  def cget(container, option)\n    __itemcget([container], option)\n  end\n  def cget_strict(container, option)\n    __itemcget_strict([container], option)\n  end\n\n  def configure(container, *args)\n    __itemconfigure([container], *args)\n  end\n\n  def configinfo(container, *args)\n    __itemconfiginfo([container], *args)\n  end\n\n  def current_configinfo(container, *args)\n    __current_itemconfiginfo([container], *args)\n  end\n\n  def itemcget(container, item, option)\n    __itemcget([container, tagid(item)], option)\n  end\n  def itemcget_strict(container, item, option)\n    __itemcget_strict([container, tagid(item)], option)\n  end\n\n  def itemconfigure(container, *args)\n    if args[-1].kind_of?(Hash)\n      # container, item, item, ... , hash_optkeys\n      keys = args.pop\n      fail ArgumentError, 'no item is given' if args.empty?\n      id = [container]\n      args.each{|item| id << tagid(item)}\n      __itemconfigure(id, keys)\n    else\n      # container, item, item, ... , option, value\n      val = args.pop\n      opt = args.pop\n      fail ArgumentError, 'no item is given' if args.empty?\n      id = [container]\n      args.each{|item| id << tagid(item)}\n      __itemconfigure(id, opt, val)\n    end\n    container\n  end\n\n  def itemconfiginfo(container, *args)\n    slot = args[-1]\n    if slot.kind_of?(String) || slot.kind_of?(Symbol)\n      slot = slot.to_s\n      if slot[0] == ?. || slot =~ /^\\d+,\\d+$/ || slot =~ /^(c|C|r|R)(\\*|\\d+)/\n        #   widget     ||    row,col          ||    Ci or Ri\n        slot = nil\n      else\n        # option\n        slot = args.pop\n      end\n    else\n      slot = nil\n    end\n\n    fail ArgumentError, 'no item is given' if args.empty?\n\n    id = [container]\n    args.each{|item| id << tagid(item)}\n    __itemconfiginfo(id, slot)\n  end\n\n  def current_itemconfiginfo(container, *args)\n    slot = args[-1]\n    if slot.kind_of?(String) || slot.kind_of?(Symbol)\n      slot = slot.to_s\n      if slot[0] == ?. || slot =~ /^\\d+,\\d+$/ || slot =~ /^(c|C|r|R)(\\*|\\d+)/\n        #   widget     ||    row,col          ||    Ci or Ri\n        slot = nil\n      else\n        # option\n        slot = args.pop\n      end\n    else\n      slot = nil\n    end\n\n    fail ArgumentError, 'no item is given' if args.empty?\n\n    id = [container]\n    args.each{|item| id << tagid(item)}\n    __current_itemconfiginfo(id, slot)\n  end\n\n  def info(container)\n    ret = {}\n    inf = list(tk_call('::blt::table', 'info', container))\n    until inf.empty?\n      opt = inf.slice!(0..1)\n      ret[opt[1..-1]] = opt[1]\n    end\n    ret\n  end\n\n  def iteminfo(container, item)\n    inf = list(tk_call('::blt::table', 'info', container, tagid(item)).chomp)\n\n    ret = []\n    until inf.empty? || (inf[0].kind_of?(String) && inf[0] =~ /^-/)\n      ret << inf.shift\n    end\n\n    if inf.length > 1\n      keys = {}\n      while inf.length > 1\n        opt = inf.slice!(0..1)\n        keys[opt[0][1..-1]] = opt[1]\n      end\n      ret << keys\n    end\n\n    ret\n  end\n\n  ############################################\n\n  def create_container(container)\n    tk_call('::blt::table', container)\n    begin\n      class << container\n        include Tk::BLT::Table::TableContainer\n      end\n    rescue\n      warn('fail to include TableContainer methods (frozen object?)')\n    end\n    container\n  end\n\n  def add(container, *args)\n    if args.empty?\n      tk_call('::blt::table', container)\n    else\n      args = args.collect{|arg|\n        if arg.kind_of?(TkWindow)\n          _epath(arg)\n        elsif arg.kind_of?(Array)  # index\n          arg.join(',')\n        else\n          arg\n        end\n      }\n      tk_call('::blt::table', container, *args)\n    end\n    container\n  end\n\n  def arrange(container)\n    tk_call('::blt::table', 'arrange', container)\n    container\n  end\n\n  def delete(container, *args)\n    tk_call('::blt::table', 'delete', container, *args)\n  end\n\n  def extents(container, item)\n    ret = []\n    inf = list(tk_call('::blt::table', 'extents', container, item))\n    ret << inf.slice!(0..4) until inf.empty?\n    ret\n  end\n\n  def forget(*wins)\n    wins = wins.collect{|win| _epath(win)}\n    tk_call('::blt::table', 'forget', *wins)\n  end\n\n  def insert(container, *args)\n    tk_call('::blt::table', 'insert', container, *args)\n  end\n\n  def insert_before(container, *args)\n    tk_call('::blt::table', 'insert', container, '-before', *args)\n  end\n\n  def insert_after(container, *args)\n    tk_call('::blt::table', 'insert', container, '-after', *args)\n  end\n\n  def join(container, first, last)\n    tk_call('::blt::table', 'join', container, first, last)\n  end\n\n  def locate(container, x, y)\n    tk_call('::blt::table', 'locate', container, x, y)\n  end\n\n  def containers(arg={})\n    list(tk_call('::blt::table', 'containers', *hash_kv(arg)))\n  end\n\n  def containers_pattern(pat)\n    list(tk_call('::blt::table', 'containers', '-pattern', pat))\n  end\n\n  def containers_slave(win)\n    list(tk_call('::blt::table', 'containers', '-slave', win))\n  end\n\n  def save(container)\n    tk_call('::blt::table', 'save', container)\n  end\n\n  def search(container, keys={})\n    list(tk_call('::blt::table', 'containers', *hash_kv(keys)))\n  end\n\n  def split(container, *args)\n    tk_call('::blt::table', 'split', container, *args)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tabnotebook.rb",
    "content": "#\n#  tkextlib/blt/tabnotebook.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\nrequire 'tkextlib/blt/tabset.rb'\n\nmodule Tk::BLT\n  class Tabnotebook < Tabset\n    TkCommandNames = ['::blt::tabnotebook'.freeze].freeze\n    WidgetClassName = 'Tabnotebook'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    def get_tab(index)\n      Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('id', tagindex(index)))\n    end\n    alias get_id get_tab\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tabset.rb",
    "content": "#\n#  tkextlib/blt/tabset.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Tabset < TkWindow\n    class Tab < TkObject\n      include TkTreatItemFont\n\n      TabID_TBL = TkCore::INTERP.create_table\n\n      (TabsetTab_ID = ['blt_tabset_tab'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n\n      TkCore::INTERP.init_ip_env{\n        TabID_TBL.mutex.synchronize{ TabID_TBL.clear }\n      }\n\n      def self.id2obj(tabset, id)\n        tpath = tabset.path\n        TabID_TBL.mutex.synchronize{\n          if TabID_TBL[tpath]\n            TabID_TBL[tpath][id]? TabID_TBL[tpath]: id\n          else\n            id\n          end\n        }\n      end\n\n      def self.new(parent, pos=nil, name=nil, keys={})\n        if pos.kind_of?(Hash)\n          keys = pos\n          name = nil\n          pos  = nil\n        end\n        if name.kind_of?(Hash)\n          keys = name\n          name = nil\n        end\n        obj = nil\n        TabID_TBL.mutex.synchronize{\n          if name && TabID_TBL[parent.path] && TabID_TBL[parent.path][name]\n            obj = TabID_TBL[parent.path][name]\n            obj.configure if keys && ! keys.empty?\n          else\n            (obj = self.allocate).instance_eval{\n              initialize(parent, pos, name, keys)\n              TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]\n              TabID_TBL[@tpath][@id] = self\n            }\n          end\n        }\n        obj\n      end\n\n      def initialize(parent, pos, name, keys)\n        @t = parent\n        @tpath = parent.path\n        if name\n          @path = @id = name\n          unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)\n            if pos\n              idx = tk_call(@tpath, 'index', '-name', @id)\n              if pos.to_s == 'end'\n                tk_call(@tpath, idx, 'moveto', 'after', 'end')\n              else\n                tk_call(@tpath, idx, 'moveto', 'before', pos)\n              end\n            end\n            tk_call(@tpath, 'tab', 'configure', @id, keys)\n          else\n            pos = 'end' unless pos\n            tk_call(@tpath, 'insert', pos, @id, keys)\n          end\n        else\n          TabsetTab_ID.mutex.synchronize{\n            @path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)\n            TabsetTab_ID[1].succ!\n          }\n          pos = 'end' unless pos\n          tk_call(@tpath, 'insert', pos, @id, keys)\n        end\n      end\n\n      #def bind(context, cmd=Proc.new, *args)\n      #  @t.tab_bind(@id, context, cmd, *args)\n      #  self\n      #end\n      def bind(context, *args)\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0]) || !block_given?\n          cmd = args.shift\n        else\n          cmd = Proc.new\n        end\n        @t.tab_bind(@id, context, cmd, *args)\n        self\n      end\n      #def bind_append(context, cmd=Proc.new, *args)\n      #  @t.tab_bind_append(@id, context, cmd, *args)\n      #  self\n      #end\n      def bind_append(context, *args)\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0]) || !block_given?\n          cmd = args.shift\n        else\n          cmd = Proc.new\n        end\n        @t.tab_bind_append(@id, context, cmd, *args)\n        self\n      end\n      def bind_remove(context)\n        @t.tab_bind_remove(@id, context)\n        self\n      end\n      def bindinfo(context=nil)\n        @t.tab_bindinfo(@id, context)\n      end\n\n      def cget(*args)\n        @t.tab_cget(@id, *args)\n      end\n      def cget_strict(*args)\n        @t.tab_cget_strict(@id, *args)\n      end\n      def configure(*args)\n        @t.tab_configure(@id, *args)\n      end\n      def configinfo(*args)\n        @t.tab_configinfo(@id, *args)\n      end\n      def current_configinfo(*args)\n        @t.current_tab_configinfo(@id, *args)\n      end\n\n      def delete()\n        @t.delete(@id)\n        TabID_TBL.mutex.synchronize{\n          TabID_TBL[@tpath].delete(@id)\n        }\n        self\n      end\n\n      def get_name()\n        @id.dup\n      end\n\n      def focus()\n        @t.focus(self.index)\n      end\n\n      def index()\n        @t.index_name(@id)\n      end\n\n      def invoke()\n        @t.invoke(self.index)\n      end\n\n      def move_before(idx)\n        @t.move_before(self.index, idx)\n      end\n      def move_after(idx)\n        @t.move_after(self.index, idx)\n      end\n\n      def perforation_highlight(mode)\n        @t.perforation.highlight(self.index, mode)\n      end\n      def perforation_invoke()\n        @t.perforation.invoke(self.index)\n      end\n\n      def see()\n        @t.see(self.index)\n      end\n\n      def tearoff(name=None)\n        @t.tab_tearoff(self.index, *args)\n      end\n    end\n\n    ########################################\n\n    class NamedTab < Tab\n      def self.new(parent, name)\n        super(parent, nil, name, {})\n      end\n    end\n\n    ########################################\n\n    include X_Scrollable\n    include TkItemConfigMethod\n\n    TkCommandNames = ['::blt::tabset'.freeze].freeze\n    WidgetClassName = 'Tabset'.freeze\n    WidgetClassNames[WidgetClassName] = self\n\n    def __destroy_hook__\n      Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{\n        Tk::BLT::Tabset::Tab::TabID_TBL.delete(@path)\n      }\n    end\n\n    ########################################\n\n    def __boolval_optkeys\n      super() << 'samewidth' << 'tearoff'\n    end\n    private :__strval_optkeys\n\n    def __strval_optkeys\n      super() << 'tabbackground' << 'tabforeground'\n    end\n    private :__strval_optkeys\n\n    def __item_cget_cmd(id)\n      [self.path, 'tab', 'cget', id]\n    end\n    private :__item_cget_cmd\n\n    def __item_config_cmd(id)\n      [self.path, 'tab', 'configure', id]\n    end\n    private :__item_config_cmd\n\n    def __item_pathname(tagOrId)\n      if tagOrId.kind_of?(Tk::BLT::Tabset::Tab)\n        self.path + ';' + tagOrId.id.to_s\n      else\n        self.path + ';' + tagOrId.to_s\n      end\n    end\n    private :__item_pathname\n\n    alias tab_cget itemcget\n    alias tab_cget_strict itemcget_strict\n    alias tab_configure itemconfigure\n    alias tab_configinfo itemconfiginfo\n    alias current_tab_configinfo current_itemconfiginfo\n\n    def __item_strval_optkeys(id)\n      super(id) << 'shadow'\n    end\n    private :__item_strval_optkeys\n\n    def tagid(tab)\n      if tab.kind_of?(Tk::BLT::Tabset::Tab)\n        tab.id\n      else\n        tab\n      end\n    end\n\n    def tagindex(tab)\n      if tab.kind_of?(Tk::BLT::Tabset::Tab)\n        tab.index\n      else\n        tab\n      end\n    end\n\n    ########################################\n\n    def activate(index)\n      tk_send('activate', tagindex(index))\n      self\n    end\n    alias highlight activate\n\n    #def tabbind(tag, context, cmd=Proc.new, *args)\n    #  _bind([path, \"bind\", tagid(tag)], context, cmd, *args)\n    #  self\n    #end\n    def tabbind(tag, context, *args)\n      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind([path, \"bind\", tagid(tag)], context, cmd, *args)\n      self\n    end\n    #def tabbind_append(tag, context, cmd=Proc.new, *args)\n    #  _bind_append([path, \"bind\", tagid(tag)], context, cmd, *args)\n    #  self\n    #end\n    def tabbind_append(tag, context, *args)\n      # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n      if TkComm._callback_entry?(args[0]) || !block_given?\n        cmd = args.shift\n      else\n        cmd = Proc.new\n      end\n      _bind_append([path, \"bind\", tagid(tag)], context, cmd, *args)\n      self\n    end\n    def tabbind_remove(tag, context)\n      _bind_remove([path, \"bind\", tagid(tag)], context)\n      self\n    end\n    def tabbindinfo(tag, context=nil)\n      _bindinfo([path, \"bind\", tagid(tag)], context)\n    end\n\n    def delete(first, last=None)\n      tk_send('delete', tagindex(first), tagindex(last))\n      if first.kind_of?(Tk::BLT::Tabset::Tab)\n        TabID_TBL.mutex.synchronize{\n          TabID_TBL[@path].delete(first.id)\n        }\n      end\n      # middle tabs of the range are unknown\n      if last.kind_of?(Tk::BLT::Tabset::Tab)\n        TabID_TBL.mutex.synchronize{\n          TabID_TBL[@path].delete(last.id)\n        }\n      end\n      self\n    end\n\n    def focus(index)\n      tk_send('focus', tagindex(index))\n      self\n    end\n\n    def get_tab(index)\n      Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('get', tagindex(index)))\n    end\n\n    def index(str)\n      num_or_str(tk_send('index', str))\n    end\n    def index_name(tab)\n      num_or_str(tk_send('index', '-mame', tagid(tab)))\n    end\n\n    def insert(pos, tab, keys={})\n      Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys)\n    end\n\n    def invoke(index)\n      tk_send('invoke', tagindex(index))\n    end\n\n    def move_before(index, base_idx)\n      tk_send('move', tagindex(index), 'before', tagindex(base_idx))\n      self\n    end\n    def move_after(index, base_idx)\n      tk_send('move', tagindex(index), 'after', tagindex(base_idx))\n      self\n    end\n\n    def nearest(x, y)\n      Tk::BLT::Tabset::Tab.id2obj(num_or_str(tk_send_without_enc('nearest', x, y)))\n    end\n\n    def perforation_highlight(index, mode)\n      tk_send('perforation', 'highlight', tagindex(index), mode)\n      self\n    end\n    def perforation_invoke(index)\n      tk_send('perforation', 'invoke', tagindex(index))\n    end\n\n    def scan_mark(x, y)\n      tk_send_without_enc('scan', 'mark', x, y)\n      self\n    end\n    def scan_dragto(x, y)\n      tk_send_without_enc('scan', 'dragto', x, y)\n      self\n    end\n\n    def see(index)\n      tk_send('see', tagindex(index))\n      self\n    end\n\n    def size()\n      number(tk_send_without_enc('size'))\n    end\n\n    def select(index)\n      tk_send('select', tagindex(index))\n      self\n    end\n\n    def tab_names(pat=None)\n      simplelist(tk_send('tab', 'names', pat)).collect{|name|\n        Tk::BLT::Tabset::Tab.id2obj(name)\n      }\n    end\n\n    def tab_tearoff(index, name=None)\n      window(tk_send('tab', 'tearoff', tagindex(index), name))\n    end\n\n    def xscrollcommand(cmd=Proc.new)\n      configure_cmd 'scrollcommand', cmd\n      self\n    end\n    alias scrollcommand xscrollcommand\n\n    def xview(*index)\n      if index.empty?\n        list(tk_send_without_enc('view'))\n      else\n        tk_send_without_enc('view', *index)\n        self\n      end\n    end\n    alias view xview\n    alias view_moveto xview_moveto\n    alias view_scroll xview_scroll\n\n    alias scrollbar xscrollbar\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/ted.rb",
    "content": "#\n#  tkextlib/blt/ted.rb\n#\n#    *** This is alpha version, because there is no document on BLT. ***\n#\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module Ted\n    extend TkCore\n\n    TkCommandNames = ['::blt::ted'.freeze].freeze\n\n    ##############################\n\n    extend TkItemConfigMethod\n\n    class << self\n      def __item_cget_cmd(id)\n        ['::blt::ted', 'cget', id]\n      end\n      private :__item_cget_cmd\n\n      def __item_config_cmd(id)\n        ['::blt::ted', 'configure', id]\n      end\n      private :__item_config_cmd\n\n      private :itemcget, :itemcget_strict\n      private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n      def cget(master, option)\n        itemcget(master, option)\n      end\n      def cget_strict(master, option)\n        itemcget_strict(master, option)\n      end\n      def configure(master, slot, value=None)\n        itemconfigure(master, slot, value)\n      end\n      def configinfo(master, slot=nil)\n        itemconfiginfo(master, slot)\n      end\n      def current_configinfo(master, slot=nil)\n        current_itemconfiginfo(master, slot)\n      end\n    end\n\n    ##############################\n\n    def self.edit(master, *args)\n      tk_call('::blt::ted', 'edit', master, *args)\n    end\n    def self.rep(master, *args)\n      tk_call('::blt::ted', 'rep', master, *args)\n    end\n    def self.select(master, *args)\n      tk_call('::blt::ted', 'select', master, *args)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/button.rb",
    "content": "#\n#  tkextlib/blt/tile/button.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/button'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class Button < Tk::Button\n      TkCommandNames = ['::blt::tile::button'.freeze].freeze\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/checkbutton.rb",
    "content": "#\n#  tkextlib/blt/tile/checkbutton.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/checkbutton'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class CheckButton < Tk::CheckButton\n      TkCommandNames = ['::blt::tile::checkbutton'.freeze].freeze\n    end\n    Checkbutton = CheckButton\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/frame.rb",
    "content": "#\n#  tkextlib/blt/tile/frame.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class Frame < Tk::Frame\n      TkCommandNames = ['::blt::tile::frame'.freeze].freeze\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/label.rb",
    "content": "#\n#  tkextlib/blt/tile/label.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/label'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class Label < Tk::Label\n      TkCommandNames = ['::blt::tile::label'.freeze].freeze\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/radiobutton.rb",
    "content": "#\n#  tkextlib/blt/tile/radiobutton.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/radiobutton'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class RadioButton < Tk::RadioButton\n      TkCommandNames = ['::blt::tile::radiobutton'.freeze].freeze\n    end\n    Radiobutton = RadioButton\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/scrollbar.rb",
    "content": "#\n#  tkextlib/blt/tile/scrollbar.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/scrollbar'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class Scrollbar < Tk::Scrollbar\n      TkCommandNames = ['::blt::tile::scrollbar'.freeze].freeze\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile/toplevel.rb",
    "content": "#\n#  tkextlib/blt/tile/toplevel.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/toplevel'\nrequire 'tkextlib/blt/tile.rb'\n\nmodule Tk::BLT\n  module Tile\n    class Toplevel < Tk::Toplevel\n      TkCommandNames = ['::blt::tile::toplevel'.freeze].freeze\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tile.rb",
    "content": "#\n#  tkextlib/blt/tile.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module Tile\n    autoload :Button,      'tkextlib/blt/tile/button.rb'\n    autoload :CheckButton, 'tkextlib/blt/tile/checkbutton.rb'\n    autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb'\n    autoload :Radiobutton, 'tkextlib/blt/tile/radiobutton.rb'\n    autoload :RadioButton, 'tkextlib/blt/tile/radiobutton.rb'\n    autoload :Frame,       'tkextlib/blt/tile/frame.rb'\n    autoload :Label,       'tkextlib/blt/tile/label.rb'\n    autoload :Scrollbar,   'tkextlib/blt/tile/scrollbar.rb'\n    autoload :Toplevel,    'tkextlib/blt/tile/toplevel.rb'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/tree.rb",
    "content": "#\n#  tkextlib/blt/tree.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Tree < TkObject\n    TkCommandNames = ['::blt::tree'.freeze].freeze\n\n    ###################################\n\n    class Node < TkObject\n      TreeNodeID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear }\n      }\n\n      def self.id2obj(tree, id)\n        tpath = tree.path\n        TreeNodeID_TBL.mutex.synchronize{\n          if TreeNodeID_TBL[tpath]\n            if TreeNodeID_TBL[tpath][id]\n              TreeNodeID_TBL[tpath][id]\n            else\n              begin\n                # self.new(tree, nil, 'node'=>Integer(id))\n                id = Integer(id)\n                if bool(tk_call(@tpath, 'exists', id))\n                  (obj = self.allocate).instance_eval{\n                    @parent = @tree = tree\n                    @tpath = tpath\n                    @path = @id = id\n                    TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath]\n                    TreeNodeID_TBL[@tpath][@id] = self\n                  }\n                  obj\n                else\n                  id\n                end\n              rescue\n                id\n              end\n            end\n          else\n            id\n          end\n        }\n      end\n\n      def self.new(tree, parent, keys={})\n        keys = _symbolkey2str(keys)\n        tpath = tree.path\n\n        TreeNodeID_TBL.mutex.synchronize{\n          TreeNodeID_TBL[tpath] ||= {}\n          if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id])\n            keys.delete('node')\n            tk_call(tree.path, 'move', id, parent, keys) if parent\n            return obj\n          end\n\n          (obj = self.allocate).instance_eval{\n            initialize(tree, parent, keys)\n            TreeNodeID_TBL[tpath][@id] = self\n          }\n          obj\n        }\n      end\n\n      def initialize(tree, parent, keys={})\n        @parent = @tree = tree\n        @tpath = @parent.path\n\n        if (id = keys['node']) && bool(tk_call(@tpath, 'exists', id))\n          @path = @id = id\n          keys.delete('node')\n          tk_call(@tpath, 'move', @id, parent, keys) if parent\n        else\n          parent = tk_call(@tpath, 'root') unless parent\n          @path = @id = tk_call(@tpath, 'insert', parent, keys)\n        end\n      end\n\n      def id\n        @id\n      end\n\n      def apply(keys={})\n        @tree.apply(@id, keys)\n        self\n      end\n\n      def children()\n        @tree.children(@id)\n      end\n\n      def copy(parent, keys={})\n        @tree.copy(@id, parent, keys)\n      end\n      def copy_to(dest_tree, parent, keys={})\n        @tree.copy_to(@id, dest_tree, parent, keys)\n      end\n\n      def degree()\n        @tree.degree(@id)\n      end\n\n      def delete()\n        @tree.delete(@id)\n        self\n      end\n\n      def depth()\n        @tree.depth(@id)\n      end\n\n      def dump()\n        @tree.dump(@id)\n      end\n\n      def dump_to_file(file)\n        @tree.dump_to_file(@id, file)\n        self\n      end\n\n      def exist?(keys={})\n        @tree.exist?(@id, keys)\n      end\n\n      def find(keys={})\n        @tree.find(@id, keys)\n      end\n\n      def find_child(label)\n        @tree.find_child(@id, label)\n      end\n\n      def first_child()\n        @tree.first_child(@id)\n      end\n\n      def get()\n        @tree.get(@id)\n      end\n      def get_value(key, default_val=None)\n        @tree.get_value(@id, key, default_val)\n      end\n\n      def index()\n        @tree.index(@id)\n      end\n\n      def leaf?()\n        @tree.leaf?(@id)\n      end\n      def link?()\n        @tree.link?(@id)\n      end\n      def root?()\n        @tree.root?(@id)\n      end\n\n      def keys()\n        @tree.keys(@id)\n      end\n\n      def label(text = nil)\n        @tree.label(@id, nil)\n      end\n      def label=(text)\n        @tree.label(@id, text)\n      end\n\n      def last_child()\n        @tree.last_child(@id)\n      end\n\n      def move(dest, keys={})\n        @tree.keys(@id, dest, keys)\n        self\n      end      \n\n      def next()\n        @tree.next(@id)\n      end\n\n      def next_sibling()\n        @tree.next_sibling(@id)\n      end\n\n      def parent()\n        @tree.parent(@id)\n      end\n\n      def fullpath()\n        @tree.fullpath(@id)\n      end\n\n      def position()\n        @tree.position(@id)\n      end\n\n      def previous()\n        @tree.previous(@id)\n      end\n\n      def prev_sibling()\n        @tree.prev_sibling(@id)\n      end\n\n      def restore(str, keys={})\n        @tree.restore(@id, str, keys)\n        self\n      end\n      def restore_overwrite(str, keys={})\n        @tree.restore_overwrite(@id, str, keys)\n        self\n      end\n\n      def restore_from_file(file, keys={})\n        @tree.restore_from_file(@id, file, keys)\n        self\n      end\n      def restore_overwrite_from_file(file, keys={})\n        @tree.restore_overwrite_from_file(@id, file, keys)\n        self\n      end\n\n      def root()\n        @tree.root(@id)\n        self\n      end\n\n      def set(data)\n        @tree.set(@id, data)\n        self\n      end\n\n      def size()\n        @tree.size(@id)\n      end\n\n      def sort(keys={})\n        @tree.sort(@id, keys)\n        self\n      end\n\n      def type(key)\n        @tree.type(@id, key)\n      end\n\n      def unset(*keys)\n        @tree.unset(@id, *keys)\n        self\n      end\n\n      def values(key=None)\n        @tree.values(@id, key)\n      end\n    end\n\n    ###################################\n\n    class Tag < TkObject\n      TreeTagID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }\n      }\n\n      (TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n\n      def self.id2obj(tree, id)\n        tpath = tree.path\n        TreeTagID_TBL.mutex.synchronize{\n          if TreeTagID_TBL[tpath]\n            if TreeTagID_TBL[tpath][id]\n              TreeTagID_TBL[tpath][id]\n            else\n              begin\n                # self.new(tree, id)\n                (obj = self.allocate).instance_eval{\n                  @parent = @tree = tree\n                  @tpath = @parent.path\n                  @path = @id = id.dup.freeze if id\n                  TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]\n                  TreeTagID_TBL[@tpath][@id] = self\n                }\n                obj\n              rescue\n                id\n              end\n            end\n          else\n            id\n          end\n        }\n      end\n\n      def initialize(tree, tag_str = nil)\n        @parent = @tree = tree\n        @tpath = @parent.path\n\n        if tag_str\n          @path = @id = tag_str.dup.freeze\n        else\n          TreeTag_ID.mutex.synchronize{\n            @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_)\n            TreeTag_ID[1].succ!\n          }\n        end\n        TreeTagID_TBL.mutex.synchronize{\n          TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]\n          TreeTagID_TBL[@tpath][@id] = self\n        }\n      end\n\n      def id\n        @id\n      end\n\n      def add(*nodes)\n        tk_call(@tpath, 'tag', 'add', @id, *nodes)\n        self\n      end\n\n      def delete(*nodes)\n        tk_call(@tpath, 'tag', 'delete', @id, *nodes)\n        self\n      end\n\n      def forget()\n        tk_call(@tpath, 'tag', 'forget', @id)\n        TreeTagID_TBL.mutex.synchronize{\n          TreeTagID_TBL[@tpath].delete(@id)\n        }\n        self\n      end\n\n      def nodes()\n        simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|node|\n          Tk::BLT::Tree::Node.id2obj(@path, node)\n        }\n      end\n\n      def set(node)\n        tk_call(@tpath, 'tag', 'set', node, @id)\n        self\n      end\n\n      def unset(node)\n        tk_call(@tpath, 'tag', 'unset', node, @id)\n        self\n      end\n    end\n\n    ###################################\n\n    class Notify < TkObject\n      NotifyID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        NotifyID_TBL.mutex.synchronize{ NotifyID_TBL.clear }\n      }\n\n      def self.id2obj(tree, id)\n        tpath = tree.path\n        NotifyID_TBL.mutex.synchronize{\n          if NotifyID_TBL[tpath]\n            if NotifyID_TBL[tpath][id]\n              NotifyID_TBL[tpath][id]\n            else\n              (obj = self.allocate).instance_eval{\n                @parent = @tree = tree\n                @tpath = @parent.path\n                @path = @id = id\n                NotifyID_TBL[@tpath] ||= {}\n                NotifyID_TBL[@tpath][@id] = self\n              }\n              obj\n            end\n          else\n            return id\n          end\n        }\n      end\n\n      def self.new(tree, *args, &b)\n        NotifyID_TBL.mutex.synchronize{\n          if tree.kind_of?(Array)\n            # not create\n            tpath = tree[0].path            \n            NotifyID_TBL[tpath] ||= {}\n            unless (obj = NotifyID_TBL[tpath][tree[1]])\n              (NotifyID_TBL[tpath][tree[1]] = \n                 obj = self.allocate).instance_eval{\n                @parent = @tree = tree[0]\n                @tpath = @parent.path\n                @path = @id = tree[1]\n              }\n            end\n            return obj\n          end\n\n          (obj = self.allocate).instance_eval{\n            initialize(tree, *args, &b)\n            NotifyID_TBL[@tpath] ||= {}\n            NotifyID_TBL[@tpath][@id] = self\n          }\n          return obj\n        }\n      end\n\n      def initialize(tree, *args, &b)\n        @parent = @tree = tree\n        @tpath = @parent.path\n\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0])\n          cmd = args.shift\n        # elsif args[-1].kind_of?(Proc) || args[-1].kind_of?(Method)\n        elsif TkComm._callback_entry?(args[-1])\n          cmd = args.pop\n        elsif b\n          cmd = Proc.new(&b)\n        else\n          fail ArgumentError, \"lack of 'command' argument\"\n        end\n\n        args = args.collect{|arg| '-' << arg.to_s}\n\n        args << proc{|id, type|\n          cmd.call(Tk::BLT::Tree::Node.id2obj(@tree, id), \n                   ((type[0] == ?-)? type[1..-1]: type))\n        }\n\n        @path = @id = tk_call(@tpath, 'notify', 'create', *args)\n      end\n\n      def id\n        @id\n      end\n\n      def delete()\n        tk_call(@tpath, 'notify', 'delete', @id)\n        NotifyID_TBL.mutex.synchronize{\n          NotifyID_TBL[@tpath].delete(@id)\n        }\n        self\n      end\n\n      def info()\n        lst = simplelist(tk_call(@tpath, 'notify', 'info', id))\n        lst[0] = Tk::BLT::Tree::Notify.id2obj(@tree, lst[0])\n        lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]}\n        lst[2] = tk_tcl2ruby(lst[2])\n        lst\n      end\n    end\n\n    ###################################\n\n    class Trace < TkObject\n      TraceID_TBL = TkCore::INTERP.create_table\n\n      TkCore::INTERP.init_ip_env{\n        TraceID_TBL.mutex.synchronize{ TraceID_TBL.clear }\n      }\n\n      def self.id2obj(tree, id)\n        tpath = tree.path\n        TraceID_TBL.mutex.synchronize{\n          if TraceID_TBL[tpath]\n            if TraceID_TBL[tpath][id]\n              TraceID_TBL[tpath][id]\n            else\n              begin\n                # self.new([tree, id])\n                (obj = self.allocate).instance_eval{\n                  @parent = @tree = tree\n                  @tpath = @parent.path\n                  @path = @id = node  # == traceID\n                  TraceID_TBL[@tpath] ||= {}\n                  TraceID_TBL[@tpath][@id] = self\n                }\n                obj\n              rescue\n                id\n              end\n            end\n          else\n            id\n          end\n        }\n      end\n\n      def self.new(tree, *args, &b)\n        TraceID_TBL.mutex.synchronize{\n          if tree.kind_of?(Array)\n            # not create\n            tpath = tree[0].path\n            TraceID_TBL[tpath] ||= {}\n            unless (obj = TraceID_TBL[tpath][tree[1]])\n              (TraceID_TBL[tpath][tree[1]] = \n                 obj = self.allocate).instance_eval{\n                @parent = @tree = tree\n                @tpath = @parent.path\n                @path = @id = tree[1]  # == traceID\n              }\n            end\n            return obj\n          end\n\n          # super(true, tree, *args, &b)\n          (obj = self.allocate).instance_eval{\n            initialize(tree, *args, &b)\n            TraceID_TBL[@tpath] ||= {}\n            TraceID_TBL[@tpath][@id] = self\n          }\n          return obj\n        }\n      end\n\n      def initialize(tree, node, key, opts, cmd=nil, &b)\n        @parent = @tree = tree\n        @tpath = @parent.path\n\n        if !cmd\n          if b\n            cmd = Proc.new(&b)\n          else\n            fail ArgumentError, \"lack of 'command' argument\"\n          end\n        end\n\n        @path = @id = tk_call(@tpath, 'trace', 'create', node, key, opts, \n                              proc{|t, id, k, ops| \n                                tobj = Tk::BLT::Tree.id2obj(t)\n                                if tobj.kind_of?(Tk::BLT::Tree)\n                                  nobj = Tk::BLT::Tree::Node.id2obj(tobj, id)\n                                else\n                                  nobj = id\n                                end\n                                cmd.call(tobj, nobj, k, ops)\n                              })\n      end\n\n      def id\n        @id\n      end\n\n      def delete()\n        tk_call(@tpath, 'trace', 'delete', @id)\n        TraceID_TBL.mutex.synchronize{\n          TraceID_TBL[tpath].delete(@id)\n        }\n        self\n      end\n\n      def info()\n        lst = simplelist(tk_call(@tpath, 'trace', 'info', id))\n        lst[0] = Tk::BLT::Tree::Trace.id2obj(@tree, lst[0])\n        lst[2] = simplelist(lst[2])\n        lst[3] = tk_tcl2ruby(lst[3])\n        lst\n      end\n    end\n\n    ###################################\n\n    TreeID_TBL = TkCore::INTERP.create_table\n\n    (Tree_ID = ['blt_tree'.freeze, '00000'.taint]).instance_eval{\n      @mutex = Mutex.new\n      def mutex; @mutex; end\n      freeze\n    }\n\n    def __keyonly_optkeys\n      {\n        # apply / find  command\n        'invert'=>nil, 'leafonly'=>nil, 'nocase'=>nil,\n\n        # apply / find / sort command\n        'path'=>nil,\n\n        # copy / restore / restorefile command\n        'overwrite'=>nil,\n\n        # copy command\n        'recurse'=>nil, 'tags'=>nil,\n\n        # sort command\n        'ascii'=>nil, 'decreasing'=>nil, 'disctionary'=>nil, \n        'integer'=>nil, 'real'=>nil, 'recurse'=>nil, 'reorder'=>nil, \n      }\n    end\n\n    def self.id2obj(id)\n      TreeID_TBL.mutex.synchronize{\n        TreeID_TBL[id]? TreeID_TBL[id]: id\n      }\n    end\n\n    def self.names(pat = None)\n      simplelist(tk_call('::blt::tree', 'names', pat)).collect{|name|\n        id2obj(name)\n      }\n    end\n\n    def self.destroy(*names)\n      tk_call('::blt::tree', 'destroy',\n              *(names.collect{|n| (n.kind_of?(Tk::BLT::Tree))? n.id: n }) )\n    end\n\n    def self.new(name = nil)\n      TreeID_TBL.mutex.synchronize{\n        if name && TreeID_TBL[name]\n          TreeID_TBL[name] \n        else\n          (obj = self.allocate).instance_eval{\n            initialize(name)\n            TreeID_TBL[@id] = self\n          }\n          obj\n        end\n      }\n    end\n\n    def initialzie(name = nil)\n      if name\n        @path = @id = name\n      else\n        Tree_ID.mutex.synchronize{\n          @path = @id = Tree_ID.join(TkCore::INTERP._ip_id_)\n          Tree_ID[1].succ!\n        }\n      end\n\n      tk_call('::blt::tree', 'create', @id)\n    end\n\n    def __destroy_hook__\n      Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{\n        Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path)\n      }\n      Tk::BLT::Tree::Tag::TreeTagID_TBL.mutex.synchronize{\n        Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path)\n      }\n      Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{\n        Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path)\n      }\n      Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{\n        Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path)\n      }\n    end\n\n    def tagid(tag)\n      if tag.kind_of?(Tk::BLT::Tree::Node) ||\n          tag.kind_of?(Tk::BLT::Tree::Tag) ||\n          tag.kind_of?(Tk::BLT::Tree::Notify) ||\n          tag.kind_of?(Tk::BLT::Tree::Trace)\n        tag.id\n      else\n        tag  # maybe an Array of configure paramters\n      end\n    end\n\n    def destroy()\n      tk_call('::blt::tree', 'destroy', @id)\n      self\n    end\n\n    def ancestor(node1, node2)\n      Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'ancestor', \n                                               tagid(node1), tagid(node2)))\n    end\n\n    def apply(node, keys={})\n      tk_call('::blt::tree', 'apply', tagid(node), __conv_keyonly_opts(keys))\n      self\n    end\n\n    def attach(tree_obj)\n      tk_call('::blt::tree', 'attach', tree_obj)\n      self\n    end\n\n    def children(node)\n      simplelist(tk_call('::blt::tree', 'children', tagid(node))).collect{|n|\n        Tk::BLT::Tree::Node.id2obj(self, n)\n      }\n    end\n\n    def copy(src, parent, keys={})\n      id = tk_call('::blt::tree', 'copy', tagid(src), tagid(parent), \n                   __conv_keyonly_opts(keys))\n      Tk::BLT::Tree::Node.new(self, nil, 'node'=>id)\n    end\n    def copy_to(src, dest_tree, parent, keys={})\n      return copy(src, parent, keys={}) unless dest_tree\n\n      id = tk_call('::blt::tree', 'copy', tagid(src), dest_tree, \n                   tagid(parent), __conv_keyonly_opts(keys))\n      Tk::BLT::Tree::Node.new(dest_tree, nil, 'node'=>id)\n    end\n\n    def degree(node)\n      number(tk_call('::blt::tree', 'degree', tagid(node)))\n    end\n\n    def delete(*nodes)\n      tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)}))\n      Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{\n        nodes.each{|node|\n          if node.kind_of?(Tk::BLT::Tree::Node)\n            Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id)\n          else\n            Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s)\n          end\n        }\n      }\n      self\n    end\n\n    def depth(node)\n      number(tk_call('::blt::tree', 'depth', tagid(node)))\n    end\n\n    def dump(node)\n      simplelist(tk_call('::blt::tree', 'dump', tagid(node))).collect{|n|\n        simplelist(n)\n      }\n    end\n\n    def dump_to_file(node, file)\n      tk_call('::blt::tree', 'dumpfile', tagid(node), file)\n      self\n    end\n\n    def exist?(node, key=None)\n      bool(tk_call('::blt::tree', 'exists', tagid(node), key))\n    end\n\n    def find(node, keys={})\n      simplelist(tk_call('::blt::tree', 'find', tagid(node), \n                         __conv_keyonly_opts(keys))).collect{|n|\n        Tk::BLT::Tree::Node.id2obj(self, n)\n      }\n    end\n\n    def find_child(node, label)\n      ret = tk_call('::blt::tree', 'findchild', tagid(node), label)\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def first_child(node)\n      ret = tk_call('::blt::tree', 'firstchild', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def get(node)\n      Hash[*simplelist(tk_call('::blt::tree', 'get', tagid(node)))]\n    end\n    def get_value(node, key, default_val=None)\n      tk_call('::blt::tree', 'get', tagid(node), key, default_val)\n    end\n\n    def index(node)\n      Tk::BLT::Tree::Node.id2obj(self, \n                                 tk_call('::blt::tree', 'index', tagid(node)))\n    end\n\n    def insert(parent, keys={})\n      id = tk_call('::blt::tree', 'insert', tagid(parent), keys)\n      Tk::BLT::Tree::Node.new(self, nil, 'node'=>id)\n    end\n\n    def ancestor?(node1, node2)\n      bool(tk_call('::blt::tree', 'is', 'ancestor', \n                   tagid(node1), tagid(node2)))\n    end\n    def before?(node1, node2)\n      bool(tk_call('::blt::tree', 'is', 'before', \n                   tagid(node1), tagid(node2)))\n    end\n    def leaf?(node)\n      bool(tk_call('::blt::tree', 'is', 'leaf', tagid(node)))\n    end\n    def link?(node)\n      bool(tk_call('::blt::tree', 'is', 'link', tagid(node)))\n    end\n    def root?(node)\n      bool(tk_call('::blt::tree', 'is', 'root', tagid(node)))\n    end\n\n    def keys(node, *nodes)\n      if nodes.empty?\n        simplelist(tk_call('blt::tree', 'keys', tagid(node)))\n      else\n        simplelist(tk_call('blt::tree', 'keys', tagid(node), \n                           *(nodes.collect{|n| tagid(n)}))).collect{|lst|\n          simplelist(lst)\n        }\n      end\n    end\n\n    def label(node, text=nil)\n      if text\n        tk_call('::blt::tree', 'label', tagid(node), text)\n        text\n      else\n        tk_call('::blt::tree', 'label', tagid(node))\n      end\n    end\n\n    def last_child(node)\n      ret = tk_call('::blt::tree', 'lastchild', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def link(parent, node, keys={})\n      ret = tk_call('::blt::tree', 'link', tagid(parent), tagid(node), \n                    __conv_keyonly_opts(keys))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def move(node, dest, keys={})\n      tk_call('::blt::tree', 'move', tagid(node), tagid(dest), keys)\n      self\n    end\n\n    def next(node)\n      ret = tk_call('::blt::tree', 'next', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def next_sibling(node)\n      ret = tk_call('::blt::tree', 'nextsibling', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def notify_create(*args, &b)\n      Tk::BLT::Tree::Notify.new(self, *args, &b)\n    end\n\n    def notify_delete(id)\n      if id.kind_of?(Tk::BLT::Tree::Notify)\n        id.delete\n      else\n        tk_call(@path, 'notify', 'delete', id)\n        Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{\n          Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s)\n        }\n      end\n      self\n    end\n\n    def notify_info(id)\n      lst = simplelist(tk_call(@path, 'notify', 'info', tagid(id)))\n      lst[0] = Tk::BLT::Tree::Notify.id2obj(self, lst[0])\n      lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]}\n      lst[2] = tk_tcl2ruby(lst[2])\n      lst\n    end\n\n    def notify_names()\n      tk_call(@path, 'notify', 'names').collect{|id|\n        Tk::BLT::Tree::Notify.id2obj(self, id)\n      }\n    end\n\n    def parent(node)\n      ret = tk_call('::blt::tree', 'parent', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def fullpath(node)\n      tk_call('::blt::tree', 'path', tagid(node))\n    end\n\n    def position(node)\n      number(tk_call('::blt::tree', 'position', tagid(node)))\n    end\n\n    def previous(node)\n      ret = tk_call('::blt::tree', 'previous', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def prev_sibling(node)\n      ret = tk_call('::blt::tree', 'prevsibling', tagid(node))\n      (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret)\n    end\n\n    def restore(node, str, keys={})\n      tk_call('::blt::tree', 'restore', tagid(node), str, \n              __conv_keyonly_opts(keys))\n      self\n    end\n    def restore_overwrite(node, str, keys={})\n      keys = __conv_keyonly_opts(keys)\n      keys.delete('overwrite')\n      keys.delete(:overwrite)\n      tk_call('::blt::tree', 'restore', tagid(node), str, '-overwrite', keys)\n      self\n    end\n\n    def restore_from_file(node, file, keys={})\n      tk_call('::blt::tree', 'restorefile', tagid(node), file, \n              __conv_keyonly_opts(keys))\n      self\n    end\n    def restore_overwrite_from_file(node, file, keys={})\n      keys = __conv_keyonly_opts(keys)\n      keys.delete('overwrite')\n      keys.delete(:overwrite)\n      tk_call('::blt::tree', 'restorefile', tagid(node), file, \n              '-overwrite', keys)\n      self\n    end\n\n    def root(node=None)\n      Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'root', \n                                               tagid(node)))\n    end\n\n    def set(node, data)\n      unless data.kind_of?(Hash)\n        fail ArgumentError, 'Hash is expected for data'\n      end\n      args = []\n      data.each{|k, v|  args << k << v}\n      tk_call('::blt::tree', 'set', tagid(node), *args)\n      self\n    end\n\n    def size(node)\n      number(tk_call('::blt::tree', 'size', tagid(node)))\n    end\n\n    def sort(node, keys={})\n      tk_call('::blt::tree', 'sort', tagid(node), __conv_keyonly_opts(keys))\n      self\n    end\n\n    def tag_add(tag, *nodes)\n      tk_call(@path, 'tag', 'add', tagid(tag), *(nodes.collect{|n| tagid(n)}))\n      self\n    end\n\n    def tag_delete(tag, *nodes)\n      tk_call(@path, 'tag', 'delete', tagid(tag), \n              *(nodes.collect{|n| tagid(n)}))\n      self\n    end\n\n    def tag_forget(tag)\n      tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag)\n      tk_call(@path, 'tag', 'forget', tag)\n      TreeTagID_TBL.mutex.synchronize{\n        TreeTagID_TBL[@path].delete(tag)\n      }\n      self\n    end\n\n    def tag_get(node, *patterns)\n      simplelist(tk_call(@tpath, 'tag', 'get', tagid(node), \n                         *(patterns.collect{|pat| tagid(pat)}))).collect{|str|\n        Tk::BLT::Tree::Tag.id2obj(self, str)\n      }\n    end\n\n    def tag_names(node = None)\n      simplelist(tk_call(@tpath, 'tag', 'names', tagid(node))).collect{|str|\n        Tk::BLT::Tree::Tag.id2obj(self, str)\n      }\n    end\n\n    def tag_nodes(tag)\n      simplelist(tk_call(@tpath, 'tag', 'nodes', tagid(tag))).collect{|node|\n        Tk::BLT::Tree::Node.id2obj(self, node)\n      }\n    end\n\n    def tag_set(node, *tags)\n      tk_call(@path, 'tag', 'set', tagid(node), *(tags.collect{|t| tagid(t)}))\n      self\n    end\n\n    def tag_unset(node, *tags)\n      tk_call(@path, 'tag', 'unset', tagid(node), \n              *(tags.collect{|t| tagid(t)}))\n      self\n    end\n\n    def trace_create(*args, &b)\n      Tk::BLT::Tree::Trace.new(self, *args, &b)\n    end\n\n=begin\n    def trace_delete(*args)\n      args.each{|id|\n        if id.kind_of?(Tk::BLT::Tree::Trace)\n          id.delete\n        else\n          tk_call(@path, 'trace', 'delete', id)\n          Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)\n        end\n        self\n      }\n    end\n=end\n    def trace_delete(*args)\n      args = args.collect{|id| tagid(id)}\n      tk_call(@path, 'trace', 'delete', *args)\n      Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{\n        args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)}\n      }\n      self\n    end\n\n    def trace_info(id)\n      lst = simplelist(tk_call(@path, 'trace', 'info', tagid(id)))\n      lst[0] = Tk::BLT::Tree::Trace.id2obj(self, lst[0])\n      lst[2] = simplelist(lst[2])\n      lst[3] = tk_tcl2ruby(lst[3])\n      lst\n    end\n\n    def trace_names()\n      tk_call(@path, 'trace', 'names').collect{|id|\n        Tk::BLT::Tree::Trace.id2obj(self, id)\n      }\n    end\n\n    def type(node, key)\n      tk_call('::blt::tree', 'type', tagid(node), key)\n    end\n\n    def unset(node, *keys)\n      tk_call('::blt::tree', 'unset', tagid(node), *keys)\n      self\n    end\n\n    def values(node, key=None)\n      simplelist(tk_call('::blt::tree', 'values', tagid(node), key))\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/treeview.rb",
    "content": "#\n#  tkextlib/blt/treeview.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\nrequire 'tk/validation.rb'\n\nmodule Tk::BLT\n  class Treeview < TkWindow\n    module ConfigMethod\n    end\n\n    module TagOrID_Methods\n    end\n\n    class Node < TkObject\n    end\n\n    class Tag < TkObject\n    end\n  end\n\n  class Hiertable < Treeview\n  end\nend\n\n######################################\n\nmodule Tk::BLT::Treeview::ConfigMethod\n  include TkItemConfigMethod\n\n  def __item_boolval_optkeys(id)\n    case id\n    when Array\n      # id := [ 'column', name ]\n      ['edit', 'hide']\n    when 'sort'\n      ['decreasing']\n    else\n      []\n    end\n  end\n  private :__item_boolval_optkeys\n\n  def __item_strval_optkeys(id)\n    case id\n    when Array\n      # id := [ 'column', name ]\n      super() << 'titleforeground' << 'titleshadow'\n    when 'sort'\n      ['decreasing']\n    else\n      []\n    end\n  end\n  private :__item_strval_optkeys\n\n  def __item_listval_optkeys(id)\n    case id\n    when 'entry'\n      ['bindtags']\n    else\n      []\n    end\n  end\n  private :__item_listval_optkeys\n\n  def __item_cget_cmd(id)\n    if id.kind_of?(Array)\n      # id := [ type, name ]\n      [self.path, id[0], 'cget', id[1]]\n    else\n      [self.path, id, 'cget']\n    end\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    if id.kind_of?(Array)\n      # id := [ type, name ]\n      [self.path, id[0], 'configure', id[1]]\n    else\n      [self.path, id, 'configure']\n    end\n  end\n  private :__item_config_cmd\n\n  def __item_pathname(id)\n    if id.kind_of?(Array)\n      id = tagid(id[1])\n    end\n    [self.path, id].join(';')\n  end\n  private :__item_pathname\n\n  def column_cget(name, option)\n    itemcget(['column', name], option)\n  end\n  def column_cget_strict(name, option)\n    itemcget_strict(['column', name], option)\n  end\n  def column_configure(name, slot, value=None)\n    itemconfigure(['column', name], slot, value)\n  end\n  def column_configinfo(name, slot=nil)\n    itemconfiginfo(['column', name], slot)\n  end\n  def current_column_configinfo(name, slot=nil)\n    current_itemconfiginfo(['column', name], slot)\n  end\n\n  def button_cget(option)\n    itemcget('button', option)\n  end\n  def button_cget_strict(option)\n    itemcget_strict('button', option)\n  end\n  def button_configure(slot, value=None)\n    itemconfigure('button', slot, value)\n  end\n  def button_configinfo(slot=nil)\n    itemconfiginfo('button', slot)\n  end\n  def current_button_configinfo(slot=nil)\n    current_itemconfiginfo('button', slot)\n  end\n\n  def entry_cget(option)\n    ret = itemcget('entry', option)\n    if option == 'bindtags' || option == :bindtags\n      ret.collect{|tag| TkBindTag.id2obj(tag)}\n    else\n      ret\n    end\n  end\n  def entry_cget_strict(option)\n    ret = itemcget_strict('entry', option)\n    if option == 'bindtags' || option == :bindtags\n      ret.collect{|tag| TkBindTag.id2obj(tag)}\n    else\n      ret\n    end\n  end\n  def entry_configure(slot, value=None)\n    itemconfigure('entry', slot, value)\n  end\n  def entry_configinfo(slot=nil)\n    ret = itemconfiginfo('entry', slot)\n\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        if slot == 'bindtags' || slot == :bindtags\n          ret[-2] = ret[-2].collect{|tag| TkBindTag.id2obj(tag)}\n          ret[-1] = ret[-1].collect{|tag| TkBindTag.id2obj(tag)}\n        end\n      else\n        inf = ret.assoc('bindtags')\n        inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}\n        inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}\n      end\n\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (inf = ret['bindtags'])\n        inf[-2] = inf[-2].collect{|tag| TkBindTag.id2obj(tag)}\n        inf[-1] = inf[-1].collect{|tag| TkBindTag.id2obj(tag)}\n        ret['bindtags'] = inf\n      end\n    end\n\n    ret\n  end\n  def current_entry_configinfo(slot=nil)\n    ret = current_itemconfiginfo('entry', slot)\n\n    if (val = ret['bindtags'])\n      ret['bindtags'] = val.collect{|tag| TkBindTag.id2obj(tag)}\n    end\n\n    ret\n  end\n\n  def sort_cget(option)\n    itemcget('sort', option)\n  end\n  def sort_cget_strict(option)\n    itemcget_strict('sort', option)\n  end\n  def sort_configure(slot, value=None)\n    itemconfigure('sort', slot, value)\n  end\n  def sort_configinfo(slot=nil)\n    itemconfiginfo('sort', slot)\n  end\n  def current_sort_configinfo(slot=nil)\n    current_itemconfiginfo('sort', slot)\n  end\n\n  def text_cget(option)\n    itemcget('text', option)\n  end\n  def text_cget_strict(option)\n    itemcget_strict('text', option)\n  end\n  def text_configure(slot, value=None)\n    itemconfigure('text', slot, value)\n  end\n  def text_configinfo(slot=nil)\n    itemconfiginfo('text', slot)\n  end\n  def current_text_configinfo(slot=nil)\n    current_itemconfiginfo('text', slot)\n  end\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\nend\n\nclass Tk::BLT::Treeview\n  TkCommandNames = ['::blt::treeview'.freeze].freeze\n  WidgetClassName = 'TreeView'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  include Scrollable\n  include ValidateConfigure\n  include ItemValidateConfigure\n  include Tk::BLT::Treeview::ConfigMethod\n\n  ########################\n\n  def __boolval_optkeys\n    ['autocreate', 'allowduplicates', 'exportselection', 'flat', 'hideroot', \n      'newtags', 'showtitles', 'sortselection']\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() + ['focusforeground', 'linecolor', 'separator', 'trim']\n  end\n  private :__strval_optkeys\n\n  ########################\n\n  class OpenCloseCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?W, ?w, :widget ], \n        [ ?p, ?s, :name ], \n        [ ?P, ?s, :fullpath ], \n        [ ?#, ?x, :node_id ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?x, TkComm.method(:num_or_str) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      ['opencommand', 'closecomand']\n    end\n  end\n\n  def __validation_class_list\n    super() << OpenCloseCommand\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, OpenCloseCommand)\n\n  ########################\n\n  def __item_validation_class_list(id)\n    case id\n    when 'entry'\n      super(id) << OpenCloseCommand\n    else\n      super(id)\n    end\n  end\n\n  Tk::ItemValidateConfigure.__def_validcmd(binding, OpenCloseCommand)\n\n  ########################\n\n  def __destroy_hook__\n    Tk::BLT::Treeview::Node::TreeNodeID_TBL.mutex.synchronize{\n      Tk::BLT::Treeview::Node::TreeNodeID_TBL.delete(@path)\n    }\n    Tk::BLT::Treeview::Tag::TreeTagID_TBL.mutex.synchronize{\n      Tk::BLT::Treeview::Tag::TreeTagID_TBL.delete(@path)\n    }\n  end\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::BLT::Treeview::Node) \\\n      || tag.kind_of?(Tk::BLT::Treeview::Tag)\n      tag.id\n    else\n      tag  # maybe an Array of configure paramters\n    end\n  end\n  private :tagid\n\n  def tagid2obj(tagid)\n    if tagid.kind_of?(Integer)\n      Tk::BLT::Treeview::Node.id2obj(self, tagid.to_s)\n    elsif tagid.kind_of?(String)\n      if tagid =~ /^\\d+$/\n        Tk::BLT::Treeview::Node.id2obj(self, tagid)\n      else\n        Tk::BLT::Treeview::Tag.id2obj(self, tagid)\n      end\n    else\n      tagid\n    end\n  end\n\n  def bbox(*tags)\n    list(tk_send('bbox', *(tags.collect{|tag| tagid(tag)})))\n  end\n\n  def screen_bbox(*tags)\n    list(tk_send('bbox', '-screen', *(tags.collect{|tag| tagid(tag)})))\n  end\n\n  def tag_bind(tag, seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([@path, 'bind', tagid(tag)], seq, cmd, *args)\n    self\n  end\n  def tag_bind_append(tag, seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([@path, 'bind', tagid(tag)], seq, cmd, *args)\n    self\n  end\n  def tag_bind_remove(tag, seq)\n    _bind_remove([@path, 'bind', tagid(tag)], seq)\n    self\n  end\n  def tag_bindinfo(tag, seq=nil)\n    _bindinfo([@path, 'bind', tagid(tag)], seq)\n  end\n\n  def button_activate(tag)\n    tk_send('button', 'activate', tagid(tag))\n    self\n  end\n\n  def button_bind(tag, seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([@path, 'button', 'bind', tagid(tag)], seq, cmd, *args)\n    self\n  end\n  def button_bind_append(tag, seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([@path, 'button', 'bind', tagid(tag)], seq, cmd, *args)\n    self\n  end\n  def button_bind_remove(tag, seq)\n    _bind_remove([@path, 'button', 'bind', tagid(tag)], seq)\n    self\n  end\n  def button_bindinfo(tag, seq=nil)\n    _bindinfo([@path, 'button', 'bind', tagid(tag)], seq)\n  end\n\n  def close(*tags)\n    tk_send('close', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n  def close_recurse(*tags)\n    tk_send('close', '-recurse', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n\n  def column_activate(column=None)\n    if column == None\n      tk_send('column', 'activate')\n    else\n      tk_send('column', 'activate', column)\n      self\n    end\n  end\n\n  def column_delete(*fields)\n    tk_send('column', 'delete', *fields)\n    self\n  end\n  def column_insert(pos, field, *opts)\n    tk_send('column', 'insert', pos, field, *opts)\n    self\n  end\n  def column_invoke(field)\n    tk_send('column', 'invoke', field)\n    self\n  end\n  def column_move(name, dest)\n    tk_send('column', 'move', name, dest)\n    self\n  end\n  def column_names()\n    simplelist(tk_send('column', 'names'))\n  end\n  def column_nearest(x, y=None)\n    tk_send('column', 'nearest', x, y)\n  end\n\n  def curselection\n    simplelist(tk_send('curselection')).collect{|id| tagid2obj(id)}\n  end\n\n  def delete(*tags)\n    tk_send('delete', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n\n  def entry_activate(tag)\n    tk_send('entry', 'activate', tagid(tag))\n    self\n  end\n  def entry_children(tag, first=None, last=None)\n    simplelist(tk_send('entry', 'children', tagid(tag), \n                       first, last)).collect{|id| tagid2obj(id)}\n  end\n  def entry_delete(tag, first=None, last=None)\n    tk_send('entry', 'delete', tagid(tag), first, last)\n  end\n  def entry_before?(tag1, tag2)\n    bool(tk_send('entry', 'isbefore', tagid(tag1), tagid(tag2)))\n  end\n  def entry_hidden?(tag)\n    bool(tk_send('entry', 'ishidden', tagid(tag)))\n  end\n  def entry_open?(tag)\n    bool(tk_send('entry', 'isopen', tagid(tag)))\n  end\n\n  def entry_size(tag)\n    number(tk_send('entry', 'size', tagid(tag)))\n  end\n  def entry_size_recurse(tag)\n    number(tk_send('entry', 'size', '-recurse', tagid(tag)))\n  end\n\n  def _search_flags(keys)\n    keys = _symbolkey2str(keys)\n    keys['exact'] = None if keys.delete('exact')\n    keys['glob'] = None if keys.delete('glob')\n    keys['regexp'] = None if keys.delete('regexp')\n    keys['nonmatching'] = None if keys.delete('nonmatching')\n  end\n  private :_search_flags\n\n  ################################\n\n  class FindExecFlagValue < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?W, ?w, :widget ], \n        [ ?p, ?s, :name ], \n        [ ?P, ?s, :fullpath ], \n        [ ?#, ?x, :node_id ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?x, TkComm.method(:num_or_str) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      []\n    end\n  end\n\n  def _find_exec_flag_value(val)\n    if val.kind_of?(Array)\n      cmd, *args = val\n      #FindExecFlagValue.new(cmd, args.join(' '))\n      FindExecFlagValue.new(cmd, *args)\n    elsif TkComm._callback_entry?(val)\n      FindExecFlagValue.new(val)\n    else\n      val\n    end\n  end\n\n  ################################\n\n  def find(first, last, keys={})\n    keys = _search_flags(keys)\n    keys['exec'] = _find_exec_flag_value(keys['exec']) if keys.key?('exec')\n    args = hash_kv(keys) << '--' << tagid(first) << tagid(last)\n    simplelist(tk_send('find', *args)).collect{|id| tagid2obj(id)}\n  end\n\n  def tag_focus(tag)\n    tk_send('focus', tagid(tag))\n    self\n  end\n  def get(*tags)\n    simplelist(tk_send('get', *(tags.collect{|tag| tagid(tag)})))\n  end\n  def get_full(*tags)\n    simplelist(tk_send('get', '-full', *(tags.collect{|tag| tagid(tag)})))\n  end\n\n  def hide(*tags)\n    if tags[-1].kind_of?(Hash)\n      keys = tags.pop\n    else\n      keys = {}\n    end\n    keys = _search_flags(keys)\n    args = hash_kv(keys) << '--'\n    args.concat(tags.collect{|t| tagid(t)})\n    tk_send('hide', *args)\n    self\n  end\n\n  def index(str)\n    tagid2obj(tk_send('index', str))\n  end\n  def index_at(tag, str)\n    tagid2obj(tk_send('index', '-at', tagid(tag), str))\n  end\n  def index_at_path(tag, str)\n    tagid2obj(tk_send('index', '-at', tagid(tag), '-path', str))\n  end\n\n  def insert(pos, parent=nil, keys={})\n    Tk::BLT::Treeview::Node.new(pos, parent, keys)\n  end\n  def insert_at(tag, pos, parent=nil, keys={})\n    if parent.kind_of?(Hash)\n      keys = parent\n      parent = nil\n    end\n\n    keys = _symbolkey2str(keys)\n    keys['at'] = tagid(tag)\n\n    Tk::BLT::Treeview::Node.new(pos, parent, keys)\n  end\n\n  def move_before(tag, dest)\n    tk_send('move', tagid(tag), 'before', tagid(dest))\n    self\n  end\n  def move_after(tag, dest)\n    tk_send('move', tagid(tag), 'after', tagid(dest))\n    self\n  end\n  def move_into(tag, dest)\n    tk_send('move', tagid(tag), 'into', tagid(dest))\n    self\n  end\n\n  def nearest(x, y, var=None)\n    tagid2obj(tk_send('nearest', x, y, var))\n  end\n\n  def open(*tags)\n    tk_send('open', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n  def open_recurse(*tags)\n    tk_send('open', '-recurse', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n\n  def range(first, last)\n    simplelist(tk_send('range', tagid(first), tagid(last))).collect{|id|\n      tagid2obj(id)\n    }\n  end\n  def range_open(first, last)\n    simplelist(tk_send('range', '-open', \n                       tagid(first), tagid(last))).collect{|id|\n      tagid2obj(id)\n    }\n  end\n\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n\n  def see(tag)\n    tk_send_without_enc('see', tagid(tag))\n    self\n  end\n  def see_anchor(anchor, tag)\n    tk_send_without_enc('see', '-anchor', anchor, tagid(tag))\n    self\n  end\n\n  def selection_anchor(tag)\n    tk_send_without_enc('selection', 'anchor', tagid(tag))\n    self\n  end\n  def selection_cancel()\n    tk_send_without_enc('selection', 'cancel')\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send_without_enc('selection', 'clear', tagid(first), tagid(last))\n    self\n  end\n  def selection_clear_all()\n    tk_send_without_enc('selection', 'clearall')\n    self\n  end\n  def selection_mark(tag)\n    tk_send_without_enc('selection', 'mark', tagid(tag))\n    self\n  end\n  def selection_include?(tag)\n    bool(tk_send('selection', 'include', tagid(tag)))\n  end\n  def selection_present?()\n    bool(tk_send('selection', 'present'))\n  end\n  def selection_set(first, last=None)\n    tk_send_without_enc('selection', 'set', tagid(first), tagid(last))\n    self\n  end\n  def selection_toggle(first, last=None)\n    tk_send_without_enc('selection', 'toggle', tagid(first), tagid(last))\n    self\n  end\n\n  def show(*tags)\n    if tags[-1].kind_of?(Hash)\n      keys = tags.pop\n    else\n      keys = {}\n    end\n    keys = _search_flags(keys)\n    args = hash_kv(keys) << '--'\n    args.concat(tags.collect{|t| tagid(t)})\n    tk_send('show', *args)\n    self\n  end\n\n  def sort_auto(mode)\n    tk_send('sort', 'auto', mode)\n    self\n  end\n  def sort_auto=(mode)\n    tk_send('sort', 'auto', mode)\n    mode\n  end\n  def sort_auto?\n    bool(tk_send('sort', 'auto'))\n  end\n  def sort_once(*tags)\n    tk_send('sort', 'once', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n  def sort_once_recurse(*tags)\n    tk_send('sort', 'once', '-recurse', *(tags.collect{|tag| tagid(tag)}))\n    self\n  end\n\n  def tag_add(tag, *ids)\n    tk_send('tag', 'add', tagid(tag), *ids)\n    self\n  end\n  def tag_delete(tag, *ids)\n    tk_send('tag', 'delete', tagid(tag), *ids)\n    self\n  end\n  def tag_forget(tag)\n    tk_send('tag', 'forget', tagid(tag))\n    self\n  end\n  def tag_names(id=nil)\n    id = (id)? tagid(id): None\n\n    simplelist(tk_send('tag', 'nodes', id)).collect{|tag|\n      Tk::BLT::Treeview::Tag.id2obj(self, tag)\n    }\n  end\n  def tag_nodes(tag)\n    simplelist(tk_send('tag', 'nodes', tagid(tag))).collect{|id|\n      Tk::BLT::Treeview::Node.id2obj(self, id)\n    }\n  end\n\n  def text_apply\n    tk_send('text', 'apply')\n    self\n  end\n  def text_cancel\n    tk_send('text', 'cancel')\n    self\n  end\n\n  def text_delete(first, last)\n    tk_send('text', 'delete', first, last)\n    self\n  end\n  def text_get(x, y)\n    tk_send('text', 'get', x, y)\n  end\n  def text_get_root(x, y)\n    tk_send('text', 'get', '-root', x, y)\n  end\n  def text_icursor(idx)\n    tk_send('text', 'icursor', idx)\n    self\n  end\n  def text_index(idx)\n    num_or_str(tk_send('text', 'index', idx))\n  end\n  def text_insert(idx, str)\n    tk_send('text', 'insert', idx, str)\n    self\n  end\n\n  def text_selection_adjust(idx)\n    tk_send('text', 'selection', 'adjust', idx)\n    self\n  end\n  def text_selection_clear\n    tk_send('text', 'selection', 'clear')\n    self\n  end\n  def text_selection_from(idx)\n    tk_send('text', 'selection', 'from', idx)\n    self\n  end\n  def text_selection_present\n    num_or_str(tk_send('text', 'selection', 'present'))\n  end\n  def text_selection_range(start, last)\n    tk_send('text', 'selection', 'range', start, last)\n    self\n  end\n  def text_selection_to(idx)\n    tk_send('text', 'selection', 'to', idx)\n    self\n  end\n\n  def toggle(tag)\n    tk_send('toggle', tagid(tag))\n    self\n  end\nend\n\n######################################\n\nmodule Tk::BLT::Treeview::TagOrID_Methods\n  def bbox\n    @tree.bbox(self)\n  end\n  def screen_bbox\n    @tree.screen_bbox(self)\n  end\n\n  def bind(seq, *args)\n    @tree.tag_bind(self, seq, *args)\n    self\n  end\n  def bind_append(seq, *args)\n    @tree.tag_bind_append(self, seq, *args)\n    self\n  end\n  def bind_remove(seq)\n    @tree.tag_bind_remove(self, seq)\n    self\n  end\n  def bindinfo(seq=nil)\n    @tree.tag_bindinfo(self, seq)\n  end\n\n  def button_activate\n    @tree.button_activate(self)\n    self\n  end\n\n  def button_bind(seq, *args)\n    @tree.button_bind(self, seq, *args)\n    self\n  end\n  def button_bind_append(seq, *args)\n    @tree.button_bind_append(self, seq, *args)\n    self\n  end\n  def button_bind_remove(seq)\n    @tree.button_bind_remove(self, seq)\n    self\n  end\n  def button_bindinfo(seq=nil)\n    @tree.button_bindinfo(self, seq)\n  end\n\n  def close\n    @tree.close(self)\n    self\n  end\n  def close_recurse\n    @tree.close_recurse(self)\n    self\n  end\n\n  def delete\n    @tree.delete(self)\n    self\n  end\n\n  def entry_activate\n    @tree.entry_activate(self)\n    self\n  end\n  def entry_children(first=None, last=None)\n    @tree.entry_children(self, first, last)\n  end\n  def entry_delete(first=None, last=None)\n    @tree.entry_delete(self, first, last)\n  end\n  def entry_before?(tag)\n    @tree.entry_before?(self, tag)\n  end\n  def entry_hidden?\n    @tree.entry_before?(self)\n  end\n  def entry_open?\n    @tree.entry_open?(self)\n  end\n\n  def entry_size\n    @tree.entry_size(self)\n  end\n  def entry_size_recurse\n    @tree.entry_size_recurse(self)\n  end\n\n  def focus\n    @tree.tag_focus(self)\n    self\n  end\n\n  def get\n    @tree.get(self)\n  end\n  def get_full\n    @tree.get_full(self)\n  end\n\n  def hide\n    @tree.hide(self)\n    self\n  end\n\n  def index(str)\n    @tree.index_at(self, str)\n  end\n  def index_path(str)\n    @tree.index_at_path(self, str)\n  end\n\n  def insert(pos, parent=nil, keys={})\n    @tree.insert_at(self, pos, parent, keys)\n  end\n\n  def move_before(dest)\n    @tree.move_before(self, dest)\n    self\n  end\n  def move_after(dest)\n    @tree.move_after(self, dest)\n    self\n  end\n  def move_into(dest)\n    @tree.move_into(self, dest)\n    self\n  end\n\n  def open\n    @tree.open(self)\n    self\n  end\n  def open_recurse\n    @tree.open_recurse(self)\n    self\n  end\n\n  def range_to(tag)\n    @tree.range(self, tag)\n  end\n  def range_open_to(tag)\n    @tree.range(self, tag)\n  end\n\n  def see\n    @tree.see(self)\n    self\n  end\n  def see_anchor(anchor)\n    @tree.see_anchor(anchor, self)\n    self\n  end\n\n  def selection_anchor\n    @tree.selection_anchor(self)\n    self\n  end\n  def selection_clear\n    @tree.selection_clear(self)\n    self\n  end\n  def selection_mark\n    @tree.selection_mark(self)\n    self\n  end\n  def selection_include?\n    @tree.selection_include?(self)\n  end\n  def selection_set\n    @tree.selection_set(self)\n    self\n  end\n  def selection_toggle\n    @tree.selection_toggle(self)\n    self\n  end\n\n  def show\n    @tree.show(self)\n    self\n  end\n\n  def sort_once\n    @tree.sort_once(self)\n    self\n  end\n  def sort_once_recurse\n    @tree.sort_once_recurse(self)\n    self\n  end\n\n  def toggle\n    @tree.toggle(self)\n    self\n  end\nend\n\n######################################\n\nclass Tk::BLT::Treeview::Node < TkObject\n  include Tk::BLT::Treeview::TagOrID_Methods\n\n  TreeNodeID_TBL = TkCore::INTERP.create_table\n\n  (TreeNode_ID = ['blt_treeview_node'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    TreeNodeID_TBL.mutex.synchronize{\n      if TreeNodeID_TBL[tpath]\n        if TreeNodeID_TBL[tpath][id]\n          TreeNodeID_TBL[tpath][id]\n        else\n          begin\n            # self.new(tree, nil, nil, 'node'=>Integer(id))\n            unless (tk_call(@tpath, 'get', id)).empty?\n              id = Integer(id)\n              (obj = self.allocate).instance_eval{\n                @parent = @tree = tree\n                @tpath = @parent.path\n                @path = @id = id\n                TreeNodeID_TBL[@tpath] ||= {}\n                TreeNodeID_TBL[@tpath][@id] = self\n              }\n              obj\n            else\n              id\n            end\n          rescue\n            id\n          end\n        end\n      else\n        id\n      end\n    }\n  end\n\n  def self.new(tree, pos, parent=nil, keys={})\n    if parent.kind_of?(Hash)\n      keys = parent\n      parent = nil\n    end\n\n    keys = _symbolkey2str(keys)\n    tpath = tree.path\n\n    TreeNodeID_TBL.mutex.synchronize{\n      TreeNodeID_TBL[tpath] ||= {}\n      if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id])\n        keys.delete('node')\n        tk_call(tree.path, 'move', id, pos, parent) if parent\n        return obj\n      end\n\n      #super(tree, pos, parent, keys)\n      (obj = self.allocate).instance_eval{\n        initialize(tree, pos, parent, keys)\n        TreeNodeID_TBL[tpath][@id] = self\n      }\n      obj\n    }\n  end\n\n  def initialize(tree, pos, parent, keys)\n    @parent = @tree = tree\n    @tpath = @parent.path\n\n    if (id = keys['node'])\n      # if tk_call(@tpath, 'get', id).empty?\n      #   fail RuntimeError, \"not exist the node '#{id}'\"\n      # end\n      @path = @id = id\n      tk_call(@tpath, 'move', @id, pos, tagid(parent)) if parent\n      configure(keys) if keys && ! keys.empty?\n    else\n      name = nil\n      TreeNode_ID.mutex.synchronize{\n        name = TreeNode_ID.join(TkCore::INTERP._ip_id_).freeze\n        TreeNode_ID[1].succ!\n      }\n\n      at = keys.delete['at']\n\n      if parent\n        if parent.kind_of?(Tk::BLT::Treeview::Node) || \n            parent.kind_of?(Tk::BLT::Treeview::Tag)\n          path = [get_full(parent.id)[0], name]\n          at = nil # ignore 'at' option\n        else\n          path = [parent.to_s, name]\n        end\n      else\n        path = name\n      end\n\n      if at\n        @id = tk_call(@tpath, 'insert', '-at', tagid(at), pos, path, keys)\n      else\n        @id = tk_call(@tpath, 'insert', pos, path, keys)\n      end\n      @path = @id\n    end\n  end\n\n  def id\n    @id\n  end\nend\n\n######################################\n\nclass Tk::BLT::Treeview::Tag < TkObject\n  include Tk::BLT::Treeview::TagOrID_Methods\n\n  TreeTagID_TBL = TkCore::INTERP.create_table\n\n  (TreeTag_ID = ['blt_treeview_tag'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }\n  }\n\n  def self.id2obj(tree, name)\n    tpath = tree.path\n    TreeTagID_TBL.mutex.synchronize{\n      if TreeTagID_TBL[tpath]\n        if TreeTagID_TBL[tpath][name]\n          TreeTagID_TBL[tpath][name]\n        else\n          #self.new(tree, name)\n          (obj = self.allocate).instance_eval{\n            @parent = @tree = tree\n            @tpath = @parent.path\n            @path = @id = name\n            TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]\n            TreeTagID_TBL[@tpath][@id] = self\n          }\n          obj\n        end\n      else\n        id\n      end\n    }\n  end\n\n  def self.new_by_name(tree, name, *ids)\n    TreeTagID_TBL.mutex.synchronize{\n      unless (obj = TreeTagID_TBL[tree.path][name])\n        (obj = self.allocate).instance_eval{\n          initialize(tree, name, ids)\n          TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]\n          TreeTagID_TBL[@tpath][@id] = self\n        }\n      end\n      obj\n    }\n  end\n\n  def self.new(tree, *ids)\n    TreeTagID_TBL.mutex.synchronize{\n      (obj = self.allocate).instance_eval{\n        if tree.kind_of?(Array)\n          initialize(tree[0], tree[1], ids)\n        else\n          initialize(tree, nil, ids)\n        end\n        TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath]\n        TreeTagID_TBL[@tpath][@id] = self\n      }\n      obj\n    }\n  end\n\n  def initialize(tree, name, ids)\n    @parent = @tree = tree\n    @tpath = @parent.path\n\n    if name\n      @path = @id = name\n    else\n      TreeTag_ID.mutex.synchronize{\n        @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_).freeze\n        TreeTag_ID[1].succ!\n      }\n    end\n\n    unless ids.empty?\n      tk_call(@tpath, 'tag', 'add', @id, *(ids.collect{|id| tagid(id)}))\n    end\n  end\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::BLT::Treeview::Node) \\\n      || tag.kind_of?(Tk::BLT::Treeview::Tag)\n      tag.id\n    else\n      tag\n    end\n  end\n  private :tagid\n\n  def id\n    @id\n  end\n\n  def add(*ids)\n    tk_call(@tpath, 'tag', 'add', @id, *(ids{|id| tagid(id)}))\n    self\n  end\n\n  def remove(*ids)\n    tk_call(@tpath, 'tag', 'delete', @id, *(ids{|id| tagid(id)}))\n    self\n  end\n\n  def forget\n    tk_call(@tpath, 'tag', 'forget', @id)\n    self\n  end\n\n  def nodes\n    simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|id|\n      Tk::BLT::Treeview::Node.id2obj(@tree, id)\n    }\n  end\nend\n\nclass Tk::BLT::Hiertable\n  TkCommandNames = ['::blt::hiertable'.freeze].freeze\n  WidgetClassName = 'Hiertable'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/unix_dnd.rb",
    "content": "#\n#  tkextlib/blt/unix_dnd.rb\n#\n#    *** This is alpha version, because there is no document on BLT. ***\n#\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module DnD\n    extend TkCore\n\n    TkCommandNames = ['::blt::dnd'.freeze].freeze\n\n    ##############################\n\n    extend TkItemConfigMethod\n\n    class << self\n      def __item_cget_cmd(id)\n        ['::blt::dnd', *id]\n      end\n      private :__item_cget_cmd\n\n      def __item_config_cmd(id)\n        ['::blt::dnd', *id]\n      end\n      private :__item_config_cmd\n\n      private :itemcget, :itemcget_strict\n      private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n      def cget(win, option)\n        itemcget(['cget', win], option)\n      end\n      def cget_strict(win, option)\n        itemcget_strict(['cget', win], option)\n      end\n      def configure(win, slot, value=None)\n        itemconfigure(['configure', win], slot, value)\n      end\n      def configinfo(win, slot=nil)\n        itemconfiginfo(['configure', win], slot)\n      end\n      def current_configinfo(win, slot=nil)\n        current_itemconfiginfo(['configure', win], slot)\n      end\n\n      def token_cget(win, option)\n        itemcget(['token', 'cget', win], option)\n      end\n      def token_cget_strict(win, option)\n        itemcget_strict(['token', 'cget', win], option)\n      end\n      def token_configure(win, slot, value=None)\n        itemconfigure(['token', 'configure', win], slot, value)\n      end\n      def token_configinfo(win, slot=nil)\n        itemconfiginfo(['token', 'configure', win], slot)\n      end\n      def current_token_configinfo(win, slot=nil)\n        current_itemconfiginfo(['token', 'configure', win], slot)\n      end\n\n      def token_windowconfigure(win, slot, value=None)\n        itemconfigure(['token', 'window', win], slot, value)\n      end\n      def token_windowconfiginfo(win, slot=nil)\n        itemconfiginfo(['token', 'window', win], slot)\n      end\n      def current_token_windowconfiginfo(win, slot=nil)\n        current_itemconfiginfo(['token', 'window', win], slot)\n      end\n    end\n\n    ##############################\n\n    def self.cancel(win)\n      tk_call('::blt::dnd', 'cancel', *wins)\n    end\n    def self.delete(*wins)\n      tk_call('::blt::dnd', 'delete', *wins)\n    end\n    def self.delete_source(*wins)\n      tk_call('::blt::dnd', 'delete', '-source', *wins)\n    end\n    def self.delete_target(*wins)\n      tk_call('::blt::dnd', 'delete', '-target', *wins)\n    end\n    def self.drag(win, x, y, token=None)\n      tk_call('::blt::dnd', 'drag', win, x, y, token)\n    end\n    def self.drop(win, x, y, token=None)\n      tk_call('::blt::dnd', 'drop', win, x, y, token)\n    end\n    def self.get_data(win, fmt=nil, cmd=nil)\n      if fmt\n        tk_call('::blt::dnd', 'getdata', win, fmt, cmd)\n      else\n        list(tk_call('::blt::dnd', 'getdata', win))\n      end\n    end\n    def self.names(pat=None)\n      list(tk_call('::blt::dnd', 'names', pat))\n    end\n    def self.source_names(pat=None)\n      list(tk_call('::blt::dnd', 'names', '-source', pat))\n    end\n    def self.target_names(pat=None)\n      list(tk_call('::blt::dnd', 'names', '-target', pat))\n    end\n    def self.pull(win, fmt)\n      tk_call('::blt::dnd', 'pull', win, fmt)\n    end\n    def self.register(win, keys={})\n      tk_call('::blt::dnd', 'register', win, keys)\n    end\n    def self.select(win, x, y, timestamp)\n      tk_call('::blt::dnd', 'select', win, x, y, timestamp)\n    end\n    def self.set_data(win, fmt=nil, cmd=nil)\n      if fmt\n        tk_call('::blt::dnd', 'setdata', win, fmt, cmd)\n      else\n        list(tk_call('::blt::dnd', 'setdata', win))\n      end\n    end\n    def self.token(*args)\n      tk_call('::blt::dnd', 'token', *args)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/vector.rb",
    "content": "#\n#  tkextlib/blt/vector.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Vector < TkVariable\n    TkCommandNames = ['::blt::vector'.freeze].freeze\n\n    def self.create(*args)\n      tk_call('::blt::vector', 'create', *args)\n    end\n\n    def self.destroy(*args)\n      tk_call('::blt::vector', 'destroy', *args)\n    end\n\n    def self.expr(expression)\n      tk_call('::blt::vector', 'expr', expression)\n    end\n\n    def self.names(pat=None)\n      list = simplelist(tk_call('::blt::vector', 'names', pat))\n      TkVar_ID_TBL.mutex.synchronize{\n        list.collect{|name|\n          if TkVar_ID_TBL[name]\n            TkVar_ID_TBL[name]\n          elsif name[0..1] == '::' && TkVar_ID_TBL[name[2..-1]]\n            TkVar_ID_TBL[name[2..-1]]\n          else\n            name\n          end\n        }\n      }\n    end\n\n    ####################################\n\n    def initialize(size=nil, keys={})\n      if size.kind_of?(Hash)\n        keys = size\n        size = nil\n      end\n      if size.kind_of?(Array)\n        # [first, last]\n        size = size.join(':')\n      end\n      if size\n        @id = TkCore::INTERP._invoke('::blt::vector', 'create', \n                                     \"#auto(#{size})\", *hash_kv(keys))\n      else\n        @id = TkCore::INTERP._invoke('::blt::vector', 'create', \n                                     \"#auto\", *hash_kv(keys))\n      end\n\n      TkVar_ID_TBL.mutex.synchronize{\n        TkVar_ID_TBL[@id] = self\n      }\n\n      @def_default = false\n      @default_val = nil\n\n      @trace_var  = nil\n      @trace_elem = nil\n      @trace_opts = nil\n\n      # teach Tk-ip that @id is global var\n      TkCore::INTERP._invoke_without_enc('global', @id)\n    end\n\n    def destroy\n      tk_call('::blt::vector', 'destroy', @id)\n    end\n\n    def inspect\n      '#<Tk::BLT::Vector: ' + @id + '>'\n    end\n\n    def to_s\n      @id\n    end\n\n    def *(item)\n      list(tk_call(@id, '*', item))\n    end\n\n    def +(item)\n      list(tk_call(@id, '+', item))\n    end\n\n    def -(item)\n      list(tk_call(@id, '-', item))\n    end\n\n    def /(item)\n      list(tk_call(@id, '/', item))\n    end\n\n    def append(*vectors)\n      tk_call(@id, 'append', *vectors)\n    end\n\n    def binread(channel, len=None, keys={})\n      if len.kind_of?(Hash)\n        keys = len\n        len = None\n      end\n      keys = _symbolkey2str(keys)\n      keys['swap'] = None if keys.delete('swap')\n      tk_call(@id, 'binread', channel, len, keys)\n    end\n\n    def clear()\n      tk_call(@id, 'clear')\n      self\n    end\n\n    def delete(*indices)\n      tk_call(@id, 'delete', *indices)\n      self\n    end\n\n    def dup_vector(vec)\n      tk_call(@id, 'dup', vec)\n      self\n    end\n\n    def expr(expression)\n      tk_call(@id, 'expr', expression)\n      self\n    end\n\n    def index(idx, val=None)\n      number(tk_call(@id, 'index', idx, val))\n    end\n\n    def [](idx)\n      index(idx)\n    end\n\n    def []=(idx, val)\n      index(idx, val)\n    end\n\n    def length()\n      number(tk_call(@id, 'length'))\n    end\n\n    def length=(size)\n      number(tk_call(@id, 'length', size))\n    end\n\n    def merge(*vectors)\n      tk_call(@id, 'merge', *vectors)\n      self\n    end\n\n    def normalize(vec=None)\n      tk_call(@id, 'normalize', vec)\n      self\n    end\n\n    def notify(keyword)\n      tk_call(@id, 'notify', keyword)\n      self\n    end\n\n    def offset()\n      number(tk_call(@id, 'offset'))\n    end\n\n    def offset=(val)\n      number(tk_call(@id, 'offset', val))\n    end\n\n    def random()\n      tk_call(@id, 'random')\n    end\n\n    def populate(vector, density=None)\n      tk_call(@id, 'populate', vector, density)\n      self\n    end\n\n    def range(first, last=None)\n      list(tk_call(@id, 'range', first, last))\n    end\n\n    def search(val1, val2=None)\n      list(tk_call(@id, 'search', val1, val2))\n    end\n\n    def set(item)\n      tk_call(@id, 'set', item)\n      self\n    end\n\n    def seq(start, finish=None, step=None)\n      tk_call(@id, 'seq', start, finish, step)\n      self\n    end\n\n    def sort(*vectors)\n      tk_call(@id, 'sort', *vectors)\n      self\n    end\n\n    def sort_reverse(*vectors)\n      tk_call(@id, 'sort', '-reverse', *vectors)\n      self\n    end\n\n    def split(*vectors)\n      tk_call(@id, 'split', *vectors)\n      self\n    end\n\n    def variable(var)\n      tk_call(@id, 'variable', var)\n      self\n    end\n  end\n\n  class VectorAccess < Vector\n    def self.new(name)\n      TkVar_ID_TBL.mutex.synchronize{\n        if TkVar_ID_TBL[name]\n          TkVar_ID_TBL[name]\n        else\n          (obj = self.allocate).instance_eval{\n            initialize(name)\n            TkVar_ID_TBL[@id] = self\n          }\n          obj\n        end\n      }\n    end\n\n    def initialize(vec_name)\n      @id = vec_name\n\n      @def_default = false\n      @default_val = nil\n\n      @trace_var  = nil\n      @trace_elem = nil\n      @trace_opts = nil\n\n      # teach Tk-ip that @id is global var\n      TkCore::INTERP._invoke_without_enc('global', @id)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/watch.rb",
    "content": "#\n#  tkextlib/blt/watch.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Watch < TkObject\n    extend TkCore\n\n    TkCommandNames = ['::blt::watch'.freeze].freeze\n\n    WATCH_ID_TBL = TkCore::INTERP.create_table\n\n    (BLT_WATCH_ID = ['blt_watch_id'.freeze, '00000'.taint]).instance_eval{\n      @mutex = Mutex.new\n      def mutex; @mutex; end\n      freeze\n    }\n\n    TkCore::INTERP.init_ip_env{\n      WATCH_ID_TBL.mutex.synchronize{ WATCH_ID_TBL.clear }\n    }\n\n    def self.names(state = None)\n      lst = tk_split_list(tk_call('::blt::watch', 'names', state))\n      WATCH_ID_TBL.mutex.synchronize{\n        lst.collect{|name|\n          WATCH_ID_TBL[name] || name\n        }\n      }\n    end\n\n    def __numval_optkeys\n      ['maxlevel']\n    end\n    private :__numval_optkeys\n\n    def __boolval_optkeys\n      ['active']\n    end\n    private :__boolval_optkeys\n\n    def __config_cmd\n      ['::blt::watch', 'configure', self.path]\n    end\n    private :__config_cmd\n\n    def initialize(name = nil, keys = {})\n      if name.kind_of?(Hash)\n        keys = name\n        name = nil\n      end\n\n      if name\n        @id = name.to_s\n      else\n        BLT_WATCH_ID.mutex.synchronize{\n          @id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_)\n          BLT_WATCH_ID[1].succ!\n        }\n      end\n\n      @path = @id\n\n      WATCH_ID_TBL.mutex.synchronize{\n        WATCH_ID_TBL[@id] = self\n      }\n      tk_call('::blt::watch', 'create', @id, *hash_kv(keys))\n    end\n\n    def activate\n      tk_call('::blt::watch', 'activate', @id)\n      self\n    end\n    def deactivate\n      tk_call('::blt::watch', 'deactivate', @id)\n      self\n    end\n    def delete\n      tk_call('::blt::watch', 'delete', @id)\n      self\n    end\n    def info\n      ret = []\n      lst = tk_split_simplelist(tk_call('::blt::watch', 'info', @id))\n      until lst.empty?\n        k, v, *lst = lst\n        k = k[1..-1]\n        case k\n        when /^(#{__strval_optkeys.join('|')})$/\n          # do nothing\n\n        when /^(#{__numval_optkeys.join('|')})$/\n          begin\n            v = number(v)\n          rescue\n            v = nil\n          end\n\n        when /^(#{__numstrval_optkeys.join('|')})$/\n          v = num_or_str(v)\n\n        when /^(#{__boolval_optkeys.join('|')})$/\n          begin\n            v = bool(v)\n          rescue\n            v = nil\n          end\n\n        when /^(#{__listval_optkeys.join('|')})$/\n          v = simplelist(v)\n\n        when /^(#{__numlistval_optkeys.join('|')})$/\n          v = list(v)\n\n        else\n          if v.index('{')\n            v = tk_split_list(v)\n          else\n            v = tk_tcl2ruby(v)\n          end\n        end\n\n        ret << [k, v]\n      end\n\n      ret\n    end\n    def configinfo(slot = nil)\n      if slot\n        slot = slot.to_s\n        v = cget(slot)\n        if TkComm::GET_CONFIGINFO_AS_ARRAY\n          [slot, v]\n        else\n          {slot=>v}\n        end\n      else\n        if TkComm::GET_CONFIGINFO_AS_ARRAY\n          info\n        else\n          Hash[*(info.flatten)]\n        end\n      end\n    end\n    def cget_strict(key)\n      key = key.to_s\n      begin\n        info.assoc(key)[1]\n      rescue\n        fail ArgumentError, \"unknown option '#{key}'\"\n      end\n    end\n    def cget(key)\n      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n        cget_strict(key)\n      else\n        begin\n          cget_strict(key)\n        rescue => e\n          if current_configinfo.has_key?(key.to_s)\n            # error on known option\n            fail e\n          else\n            # unknown option\n            nil\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/win_printer.rb",
    "content": "#\n#  tkextlib/blt/win_printer.rb\n#\n#      *** Windows only ***\n#\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  class Printer < TkObject\n    extend TkCore\n\n    TkCommandNames = ['::blt::printer'.freeze].freeze\n\n    def self.enum(attribute)\n      simplelist(tk_call('::blt::printer', 'enum', attribute))\n    end\n\n    def self.names(pat=None)\n      simplelist(tk_call('::blt::printer', 'names', pat))\n    end\n\n    def self.open(printer)\n      self.new(printer)\n    end\n\n    #################################\n\n    def initialize(printer)\n      @printer_id = tk_call('::blt::printer', 'open', printer)\n    end\n\n    def close\n      tk_call('::blt::print', 'close', @printer_id)\n      self\n    end\n    def get_attrs(var)\n      tk_call('::blt::print', 'getattrs', @printer_id, var)\n      var\n    end\n    def set_attrs(var)\n      tk_call('::blt::print', 'setattrs', @printer_id, var)\n      self\n    end\n    def snap(win)\n      tk_call('::blt::print', 'snap', @printer_id, win)\n      self\n    end\n    def write(str)\n      tk_call('::blt::print', 'write', @printer_id, str)\n      self\n    end\n    def write_with_title(title, str)\n      tk_call('::blt::print', 'write', @printer_id, title, str)\n      self\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt/winop.rb",
    "content": "#\n#  tkextlib/blt/winop.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/blt.rb'\n\nmodule Tk::BLT\n  module Winop\n    extend TkCore\n\n    TkCommandNames = ['::blt::winop'.freeze].freeze\n  end\n  WinOp = Winop\nend\n\nclass << Tk::BLT::Winop\n  def changes(win)\n    tk_call('::blt::winop', 'changes', win)\n  end\n\n  def colormap(win)\n    Hash[*list(tk_call('::blt::winop', 'colormap', win))]\n  end\n\n  def convolve(src, dest, filter)\n    tk_call('::blt::winop', 'convolve', src, dest, filter)\n  end\n\n  def image_convolve(src, dest, filter)\n    tk_call('::blt::winop', 'image', 'convolve', src, dest, filter)\n  end\n  def image_gradient(photo, left, right, type)\n    tk_call('::blt::winop', 'image', 'gradient', photo, left, right, type)\n  end\n  def image_read_jpeg(file, photo)\n    tk_call('::blt::winop', 'image', 'readjpeg', file, photo)\n  end\n  def image_resample(src, dest, horiz_filter=None, vert_filter=None)\n    tk_call('::blt::winop', 'image', 'resample', \n            src, dest, horiz_filter, vert_filter)\n  end\n  def image_rotate(src, dest, angle)\n    tk_call('::blt::winop', 'image', 'rotate', src, dest, angle)\n  end\n  def image_snap(win, photo, width=None, height=None)\n    tk_call('::blt::winop', 'image', 'snap', win, photo, width, height)\n  end\n  def image_subsample(src, dest, x, y, width, height, \n                      horiz_filter=None, vert_filter=None)\n    tk_call('::blt::winop', 'image', 'subsample', \n            src, dest, x, y, width, height, horiz_filter, vert_filter)\n  end\n\n  def quantize(src, dest, colors)\n    tk_call('::blt::winop', 'quantize', src, dest, colors)\n  end\n\n  def query()\n    tk_call('::blt::winop', 'query')\n  end\n\n  def read_jpeg(file, photo)\n    tk_call('::blt::winop', 'readjpeg', file, photo)\n  end\n\n  def resample(src, dest, horiz_filter=None, vert_filter=None)\n    tk_call('::blt::winop', 'resample', \n            src, dest, horiz_filter, vert_filter)\n  end\n\n  def subsample(src, dest, x, y, width, height, \n                horiz_filter=None, vert_filter=None)\n    tk_call('::blt::winop', 'subsample', \n            src, dest, x, y, width, height, horiz_filter, vert_filter)\n  end\n\n  def raise(*wins)\n    tk_call('::blt::winop', 'raise', *wins)\n  end\n\n  def lower(*wins)\n    tk_call('::blt::winop', 'lower', *wins)\n  end\n\n  def map(*wins)\n    tk_call('::blt::winop', 'map', *wins)\n  end\n\n  def unmap(*wins)\n    tk_call('::blt::winop', 'unmap', *wins)\n  end\n\n  def move(win, x, y)\n    tk_call('::blt::winop', 'move', win, x, y)\n  end\n\n  def snap(win, photo)\n    tk_call('::blt::winop', 'snap', win, photo)\n  end\n\n  def warpto(win = None)\n    tk_call('::blt::winop', 'warpto', win)\n  end\n  alias warp_to warpto\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/blt.rb",
    "content": "#\n#  BLT support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/variable'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/blt/setup.rb'\n\n# load all image format handlers\n#TkPackage.require('BLT', '2.4')\nTkPackage.require('BLT')\n\nmodule Tk\n  module BLT\n    TkComm::TkExtlibAutoloadModule.unshift(self)\n\n    extend TkCore\n\n    VERSION = tk_call('set', 'blt_version')\n    PATCH_LEVEL = tk_call('set', 'blt_patchLevel')\n\n    begin\n      lib = TkCore::INTERP._invoke('set', 'blt_library')\n    rescue\n      lib = ''\n    end\n    LIBRARY  = TkVarAccess.new('blt_library', lib)\n\n    begin\n      lib = TkCore::INTERP._invoke('set', 'blt_libPath')\n    rescue\n      lib = ''\n    end\n    LIB_PATH = TkVarAccess.new('blt_libPath', lib)\n\n    PACKAGE_NAME = 'BLT'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('BLT')\n      rescue\n        ''\n      end\n    end\n\n    ####################################################\n\n    def self.beep(percent = 50)\n      tk_call('::blt::beep', percent)\n    end\n\n    def self.bgexec(*args)\n      if args[0].kind_of?(TkVariable)\n        var = args.shift\n      else\n        var = TkVariable.new\n      end\n      params = [var]\n\n      params.concat(hash_kv(args.shift, true)) if args[0].kind_of?(Hash)\n\n      params << '--' if args[0] =~ /^\\s*-[^-]/\n      params.concat(args)\n\n      tk_call('::blt::bgexec', *params)\n      var\n    end\n\n    def self.detach_bgexec(*args)\n      if args[0].kind_of?(TkVariable)\n        var = args.shift\n      else\n        var = TkVariable.new\n      end\n      params = [var]\n\n      params.concat(hash_kv(args.shift, true)) if args[0].kind_of?(Hash)\n\n      params << '--' if args[0] =~ /^\\s*-[^-]/\n      params.concat(args)\n      params << '&'\n\n      [var, tk_split_list(tk_call('::blt::bgexec', *params))]\n    end\n\n    def self.bltdebug(lvl = nil)\n      if lvl\n        tk_call('::blt::bltdebug', lvl)\n      else\n        number(tk_call('::blt::bltdebug'))\n      end\n    end\n\n    def self.crc32_file(name)\n      tk_call_without_enc('::blt::crc32', name)\n    end\n    def self.crc32_data(dat)\n      tk_call_without_enc('::blt::crc32', '-data', dat)\n    end\n\n    ####################################################\n\n    def self.active_legend(graph)\n      tk_call_without_enc('Blt_ActiveLegend', graph)\n    end\n    def self.crosshairs(graph)\n      tk_call_without_enc('Blt_Crosshairs', graph)\n    end\n    def self.zoom_stack(graph)\n      tk_call_without_enc('Blt_ZoomStack', graph)\n    end\n    def self.print_key(graph)\n      tk_call_without_enc('Blt_PrintKey', graph)\n    end\n    def self.closest_point(graph)\n      tk_call_without_enc('Blt_ClosestPoint', graph)\n    end\n\n    module GraphCommand\n      def active_legend\n        tk_call_without_enc('Blt_ActiveLegend', @path)\n        self\n      end\n      def crosshairs\n        tk_call_without_enc('Blt_Crosshairs', @path)\n        self\n      end\n      def zoom_stack\n        tk_call_without_enc('Blt_ZoomStack', @path)\n        self\n      end\n      def print_key\n        tk_call_without_enc('Blt_PrintKey', @path)\n        self\n      end\n      def closest_point\n        tk_call_without_enc('Blt_ClosestPoint', @path)\n        self\n      end\n    end\n\n    ####################################################\n\n    autoload :PlotComponent,'tkextlib/blt/component.rb'\n\n    autoload :Barchart,     'tkextlib/blt/barchart.rb'\n    autoload :Bitmap,       'tkextlib/blt/bitmap.rb'\n    autoload :Busy,         'tkextlib/blt/busy.rb'\n    autoload :Container,    'tkextlib/blt/container.rb'\n    autoload :CutBuffer,    'tkextlib/blt/cutbuffer.rb'\n    autoload :DragDrop,     'tkextlib/blt/dragdrop.rb'\n    autoload :EPS,          'tkextlib/blt/eps.rb'\n    autoload :Htext,        'tkextlib/blt/htext.rb'\n    autoload :Graph,        'tkextlib/blt/graph.rb'\n    autoload :Spline,       'tkextlib/blt/spline.rb'\n    autoload :Stripchart,   'tkextlib/blt/stripchart.rb'\n    autoload :Table,        'tkextlib/blt/table.rb'\n    autoload :Tabnotebook,  'tkextlib/blt/tabnotebook.rb'\n    autoload :Tabset,       'tkextlib/blt/tabset.rb'\n    autoload :Ted,          'tkextlib/blt/ted.rb'\n    autoload :Tile,         'tkextlib/blt/tile.rb'\n    autoload :Tree,         'tkextlib/blt/tree.rb'\n    autoload :TreeView,     'tkextlib/blt/treeview.rb'\n    autoload :Hiertable,    'tkextlib/blt/treeview.rb'\n    # Hierbox is obsolete\n    autoload :Vector,       'tkextlib/blt/vector.rb'\n    autoload :VectorAccess, 'tkextlib/blt/vector.rb'\n    autoload :Watch,        'tkextlib/blt/watch.rb'\n    autoload :Winop,        'tkextlib/blt/winop.rb'\n    autoload :WinOp,        'tkextlib/blt/winop.rb'\n\n    # Unix only\n    autoload :DnD,          'tkextlib/blt/unix_dnd.rb'\n\n    # Windows only\n    autoload :Printer,      'tkextlib/blt/win_printer.rb'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/arrowbutton.rb",
    "content": "#\n#  tkextlib/bwidget/arrowbutton.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/button'\n\nmodule Tk\n  module BWidget\n    class ArrowButton < Tk::BWidget::Button\n    end\n  end\nend\n\nclass Tk::BWidget::ArrowButton\n  TkCommandNames = ['ArrowButton'.freeze].freeze\n  WidgetClassName = 'ArrowButton'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/bitmap.rb",
    "content": "#\n#  tkextlib/bwidget/bitmap.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tk/image'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class Bitmap < TkPhotoImage\n    end\n  end\nend\n\nclass Tk::BWidget::Bitmap\n  def initialize(name)\n    @path = tk_call_without_enc('Bitmap::get', name)\n    Tk_IMGTBL[@path] = self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/button.rb",
    "content": "#\n#  tkextlib/bwidget/button.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/button'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class Button < Tk::Button\n    end\n  end\nend\n\nclass Tk::BWidget::Button\n  TkCommandNames = ['Button'.freeze].freeze\n  WidgetClassName = 'Button'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helptext'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/buttonbox.rb",
    "content": "#\n#  tkextlib/bwidget/buttonbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/button'\n\nmodule Tk\n  module BWidget\n    class ButtonBox < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::ButtonBox\n  TkCommandNames = ['ButtonBox'.freeze].freeze\n  WidgetClassName = 'ButtonBox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  include TkItemConfigMethod\n\n  def __boolval_optkeys\n    super() << 'homogeneous'\n  end\n  private :__boolval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::BWidget::Button)\n      name = tagOrId[:name]\n      return index(name) unless name.empty?\n    end\n    if tagOrId.kind_of?(Tk::Button)\n      return index(tagOrId[:text])\n    end\n    # index(tagOrId.to_s)\n    index(_get_eval_string(tagOrId))\n  end\n\n  def add(keys={}, &b)\n    win = window(tk_send('add', *hash_kv(keys)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def delete(idx)\n    tk_send('delete', tagid(idx))\n    self\n  end\n\n  def index(idx)\n    if idx.kind_of?(Tk::BWidget::Button)\n      name = idx[:name]\n      idx = name unless name.empty?\n    end\n    if idx.kind_of?(Tk::Button)\n      idx = idx[:text]\n    end\n    number(tk_send('index', idx.to_s))\n  end\n\n  def insert(idx, keys={}, &b)\n    win = window(tk_send('insert', tagid(idx), *hash_kv(keys)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def invoke(idx)\n    tk_send('invoke', tagid(idx))\n    self\n  end\n\n  def set_focus(idx)\n    tk_send('setfocus', tagid(idx))\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/combobox.rb",
    "content": "#\n#  tkextlib/bwidget/combobox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/entry'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/listbox'\nrequire 'tkextlib/bwidget/spinbox'\n\nmodule Tk\n  module BWidget\n    class ComboBox < Tk::BWidget::SpinBox\n    end\n  end\nend\n\nclass Tk::BWidget::ComboBox\n  include Scrollable\n\n  TkCommandNames = ['ComboBox'.freeze].freeze\n  WidgetClassName = 'ComboBox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def get_listbox(&b)\n    win = window(tk_send_without_enc('getlistbox'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def icursor(idx)\n    tk_send_without_enc('icursor', idx)\n  end\n\n  def post\n    tk_send_without_enc('post')\n    self\n  end\n\n  def unpost\n    tk_send_without_enc('unpost')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/dialog.rb",
    "content": "#\n#  tkextlib/bwidget/dialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/buttonbox'\n\nmodule Tk\n  module BWidget\n    class Dialog < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::Dialog\n  TkCommandNames = ['Dialog'.freeze].freeze\n  WidgetClassName = 'Dialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  include TkItemConfigMethod\n\n  def __strval_optkeys\n    super() << 'title'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'transient' << 'homogeneous'\n  end\n  private :__boolval_optkeys\n\n  def initialize(parent=nil, keys=nil)\n    @relative = ''\n    if parent.kind_of?(Hash)\n      keys = _symbolkey2str(parent)\n      @relative = keys['parent'] if keys.key?('parent')\n      @relative = keys.delete('relative') if keys.key?('relative')\n      super(keys)\n    elsif keys\n      keys = _symbolkey2str(keys)\n      @relative = keys.delete('parent') if keys.key?('parent')\n      @relative = keys.delete('relative') if keys.key?('relative')\n      super(parent, keys)\n    else\n      super(parent)\n    end\n  end\n\n  def create_self(keys)\n    cmd = self.class::TkCommandNames[0]\n    if keys and keys != None\n      tk_call_without_enc(cmd, @path, '-parent', @relative, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(cmd, @path, '-parent', @relative)\n    end\n  end\n\n  def cget_strict(slot)\n    if slot.to_s == 'relative'\n      super('parent')\n    else\n      super(slot)\n    end\n  end\n  def cget(slot)\n    if slot.to_s == 'relative'\n      super('parent')\n    else\n      super(slot)\n    end\n  end\n\n  def configure(slot, value=None)\n    if slot.kind_of?(Hash)\n      slot = _symbolkey2str(slot)\n      slot['parent'] = slot.delete('relative') if slot.key?('relative')\n      super(slot)\n    else\n      if slot.to_s == 'relative'\n        super('parent', value)\n      else\n        super(slot, value)\n      end\n    end\n  end\n\n  def configinfo(slot=nil)\n    if slot\n      if slot.to_s == 'relative'\n        super('parent')\n      else\n        super(slot)\n      end\n    else\n      ret = super()\n      if TkComm::GET_CONFIGINFO_AS_ARRAY\n        ret << ['relative', 'parent']\n      else\n        ret['relative'] = 'parent'\n      end\n    end\n  end\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::BWidget::Button)\n      name = tagOrId[:name]\n      return index(name) unless name.empty?\n    end\n    if tagOrId.kind_of?(Tk::Button)\n      return index(tagOrId[:text])\n    end\n    # index(tagOrId.to_s)\n    index(_get_eval_string(tagOrId))\n  end\n\n  def add(keys={}, &b)\n    win = window(tk_send('add', *hash_kv(keys)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_frame(&b)\n    win = window(tk_send('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_buttonbox(&b)\n    win = window(@path + '.bbox')\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def draw(focus_win=None)\n    tk_send('draw', focus_win)\n  end\n\n  def enddialog(ret)\n    tk_send('enddialog', ret)\n  end\n\n  def index(idx)\n    get_buttonbox.index(idx)\n  end\n\n  def invoke(idx)\n    tk_send('invoke', tagid(idx))\n    self\n  end\n\n  def set_focus(idx)\n    tk_send('setfocus', tagid(idx))\n    self\n  end\n\n  def withdraw\n    tk_send('withdraw')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/dragsite.rb",
    "content": "#\n#  tkextlib/bwidget/dragsite.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    module DragSite\n    end\n  end\nend\n\nmodule Tk::BWidget::DragSite\n  include Tk\n  extend Tk\n\n  def self.include(klass, type, event)\n    tk_call('DragSite::include', klass, type, event)\n  end\n\n  def self.register(path, keys={})\n    tk_call('DragSite::register', path, *hash_kv(keys))\n  end\n\n  def self.set_drag(path, subpath, initcmd, endcmd, force=None)\n    tk_call('DragSite::setdrag', path, subpath, initcmd, endcmd, force)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/dropsite.rb",
    "content": "#\n#  tkextlib/bwidget/dropsite.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    module DropSite\n    end\n  end\nend\n\nmodule Tk::BWidget::DropSite\n  include Tk\n  extend Tk\n\n  def self.include(klass, type)\n    tk_call('DropSite::include', klass, type)\n  end\n\n  def self.register(path, keys={})\n    tk_call('DropSite::register', path, *hash_kv(keys))\n  end\n\n  def self.set_cursor(cursor)\n    tk_call('DropSite::setcursor', cursor)\n  end\n\n  def self.set_drop(path, subpath, dropover, drop, force=None)\n    tk_call('DropSite::setdrop', path, subpath, dropover, drop, force)\n  end\n\n  def self.set_operation(op)\n    tk_call('DropSite::setoperation', op)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/dynamichelp.rb",
    "content": "#\n#  tkextlib/bwidget/dynamichelp.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    module DynamicHelp\n    end\n  end\nend\n\nmodule Tk::BWidget::DynamicHelp\n  include Tk\n  extend Tk\n\n  def self.__pathname\n    'DynamicHelp::configure'\n  end\n\n  def __strval_optkeys\n    super() << 'topbackground'\n  end\n  private :__strval_optkeys\n\n  def self.__cget_cmd\n    ['DynamicHelp::configure']\n  end\n\n  def self.__config_cmd\n    ['DynamicHelp::configure']\n  end\n\n  def self.cget_strict(slot)\n    slot = slot.to_s\n    info = {}\n    self.current_configinfo.each{|k,v| info[k.to_s] = v if k.to_s == slot}\n    fail RuntimeError, \"unknown option \\\"-#{slot}\\\"\"  if info.empty?\n    info.values[0]\n  end\n  def self.cget(slot)\n    self.current_configinfo(slot).values[0]\n  end\n\n  def self.add(widget, keys={})\n    tk_call('DynamicHelp::add', widget, *hash_kv(keys))\n  end\n\n  def self.delete(widget)\n    tk_call('DynamicHelp::delete', widget)\n  end\n\n  def self.include(klass, type)\n    tk_call('DynamicHelp::include', klass, type)\n  end\n\n  def self.sethelp(path, subpath, force=None)\n    tk_call('DynamicHelp::sethelp', path, subpath, force)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/entry.rb",
    "content": "#\n#  tkextlib/bwidget/entry.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/entry'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class Entry < Tk::Entry\n    end\n  end\nend\n\nclass Tk::BWidget::Entry\n  include Scrollable\n\n  TkCommandNames = ['Entry'.freeze].freeze\n  WidgetClassName = 'Entry'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helptext' << 'insertbackground'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'dragenabled' << 'dropenabled' << 'editable'\n  end\n  private :__boolval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\n\n  def invoke\n    tk_send_without_enc('invoke')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/label.rb",
    "content": "#\n#  tkextlib/bwidget/label.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/label'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class Label < Tk::Label\n    end\n  end\nend\n\nclass Tk::BWidget::Label\n  TkCommandNames = ['Label'.freeze].freeze\n  WidgetClassName = 'Label'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helptext'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'dragenabled' << 'dropenabled'\n  end\n  private :__boolval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\n\n  def set_focus\n    tk_send_without_enc('setfocus')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/labelentry.rb",
    "content": "#\n#  tkextlib/bwidget/labelentry.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/entry'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/labelframe'\nrequire 'tkextlib/bwidget/entry'\n\nmodule Tk\n  module BWidget\n    class LabelEntry < Tk::Entry\n    end\n  end\nend\n\nclass Tk::BWidget::LabelEntry\n  include Scrollable\n\n  TkCommandNames = ['LabelEntry'.freeze].freeze\n  WidgetClassName = 'LabelEntry'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\n\n  def __font_optkeys\n    super() << 'labelfont'\n  end\n  private :__font_optkeys\n\n  #def entrybind(*args)\n  #  _bind([path, 'bind'], *args)\n  #  self\n  #end\n  def entrybind(context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([path, 'bind'], context, cmd, *args)\n    self\n  end\n\n  #def entrybind_append(*args)\n  #  _bind_append([path, 'bind'], *args)\n  #  self\n  #end\n  def entrybind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([path, 'bind'], context, cmd, *args)\n    self\n  end\n\n  def entrybind_remove(*args)\n    _bind_remove([path, 'bind'], *args)\n    self\n  end\n\n  def entrybindinfo(*args)\n    _bindinfo([path, 'bind'], *args)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/labelframe.rb",
    "content": "#\n#  tkextlib/bwidget/labelframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/label'\n\nmodule Tk\n  module BWidget\n    class LabelFrame < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::LabelFrame\n  TkCommandNames = ['LabelFrame'.freeze].freeze\n  WidgetClassName = 'LabelFrame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helptext'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'dragenabled' << 'dropenabled'\n  end\n  private :__boolval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\n\n  def self.align(*args)\n    tk_call('LabelFrame::align', *args)\n  end\n  def get_frame(&b)\n    win = window(tk_send_without_enc('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/listbox.rb",
    "content": "#\n#  tkextlib/bwidget/listbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/canvas'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class ListBox < TkWindow\n      # is NOT a subclass of a listbox widget class.\n      # because it constructed on a canvas widget. \n\n      class Item < TkObject\n      end\n    end\n  end\nend\n\nclass Tk::BWidget::ListBox\n  include TkItemConfigMethod\n  include Scrollable\n\n  TkCommandNames = ['ListBox'.freeze].freeze\n  WidgetClassName = 'ListBox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  class Event_for_Items < TkEvent::Event\n    def self._get_extra_args_tbl\n      [ \n        TkComm.method(:string)   # item idenfier\n      ]\n    end\n  end\n\n  def __boolval_optkeys\n    super() << 'autofocus' << 'dragenabled' << 'dropenabled' << 'selectfill'\n  end\n  private :__boolval_optkeys\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::BWidget::ListBox::Item)\n      tag.id\n    else\n      # tag\n      _get_eval_string(tag)\n    end\n  end\n\n  #def imagebind(*args)\n  #  _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n  #  self\n  #end\n  def imagebind(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_for_event_class(Event_for_Items, [path, 'bindImage'], \n                          context, cmd, *args)\n    self\n  end\n\n  #def imagebind_append(*args)\n  #  _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n  #  self\n  #end\n  def imagebind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], \n                                 context, cmd, *args)\n    self\n  end\n\n  def imagebind_remove(*args)\n    _bind_remove_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n    self\n  end\n\n  def imagebindinfo(*args)\n    _bindinfo_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n  end\n\n  #def textbind(*args)\n  #  _bind_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n  #  self\n  #end\n  def textbind(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_for_event_class(Event_for_Items, [path, 'bindText'], \n                          context, cmd, *args)\n    self\n  end\n\n  #def textbind_append(*args)\n  #  _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n  #  self\n  #end\n  def textbind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], \n                                 context, cmd, *args)\n    self\n  end\n\n  def textbind_remove(*args)\n    _bind_remove_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n    self\n  end\n\n  def textbindinfo(*args)\n    _bindinfo_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n  end\n\n  def delete(*args)\n    tk_send('delete', *args)\n    self\n  end\n\n  def edit(item, text, *args)\n    tk_send('edit', tagid(item), text, *args)\n    self\n  end\n\n  def exist?(item)\n    bool(tk_send('exists', tagid(item)))\n  end\n\n  def index(item)\n    num_or_str(tk_send('index', tagid(item)))\n  end\n\n  def insert(idx, item, keys={})\n    tk_send('insert', idx, tagid(item), *hash_kv(keys))\n    self\n  end\n\n  def get_item(idx)\n    tk_send('items', idx)\n  end\n\n  def items(first=None, last=None)\n    list(tk_send('items', first, last))\n  end\n\n  def move(item, idx)\n    tk_send('move', tagid(item), idx)\n    self\n  end\n\n  def reorder(neworder)\n    tk_send('reorder', neworder)\n    self\n  end\n\n  def see(item)\n    tk_send('see', tagid(item))\n    self\n  end\n\n  def selection_clear\n    tk_send_without_enc('selection', 'clear')\n    self\n  end\n\n  def selection_set(*args)\n    tk_send_without_enc('selection', 'set', \n                        *(args.collect{|item| tagid(item)}))\n    self\n  end\n\n  def selection_add(*args)\n    tk_send_without_enc('selection', 'add', \n                        *(args.collect{|item| tagid(item)}))\n    self\n  end\n\n  def selection_remove(*args)\n    tk_send_without_enc('selection', 'remove', \n                        *(args.collect{|item| tagid(item)}))\n    self\n  end\n\n  def selection_get(*args)\n    simplelist(tk_send_without_enc('selection', 'get')).collect{|item|\n      Tk::BWidget::ListBox::Item.id2obj(self, item)\n    }\n  end\nend\n\nclass Tk::BWidget::ListBox::Item\n  include TkTreatTagFont\n\n  ListItem_TBL = TkCore::INTERP.create_table\n\n  (ListItem_ID = ['bw:item'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    ListItem_TBL.mutex.synchronize{ ListItem_TBL.clear }\n  }\n\n  def self.id2obj(lbox, id)\n    lpath = lbox.path\n    ListItem_TBL.mutex.synchronize{\n      if ListItem_TBL[lpath]\n        ListItem_TBL[lpath][id]? ListItem_TBL[lpath][id]: id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(lbox, *args)\n    if lbox.kind_of?(Tk::BWidget::ListBox)\n      @listbox = lbox\n    else\n      fail RuntimeError, \n        \"expect Tk::BWidget::ListBox or Tk::BWidget::ListBox::Item for 1st argument\"\n    end\n\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n    else\n      keys = {}\n    end\n\n    index = keys.delete('index')\n    unless args.empty?\n      index = args.shift\n    end\n    index = 'end' unless index\n\n    unless args.empty?\n      fail RuntimeError, 'too much arguments'\n    end\n\n    @lpath = @listbox.path\n\n    if keys.key?('itemname')\n      @path = @id = keys.delete('itemname')\n    else\n      ListItem_ID.mutex.synchronize{\n        @path = @id = ListItem_ID.join(TkCore::INTERP._ip_id_)\n        ListItem_ID[1].succ!\n      }\n    end\n\n    ListItem_TBL.mutex.synchronize{\n      ListItem_TBL[@id] = self\n      ListItem_TBL[@lpath] = {} unless ListItem_TBL[@lpath]\n      ListItem_TBL[@lpath][@id] = self\n    }\n\n    @listbox.insert(index, @id, keys)\n  end\n\n  def listbox\n    @listbox\n  end\n\n  def id\n    @id\n  end\n\n  def [](key)\n    cget(key)\n  end\n\n  def []=(key, val)\n    configure(key, val)\n    val\n  end\n\n  def cget(key)\n    @listbox.itemcget(@id, key)\n  end\n  def cget_strict(key)\n    @listbox.itemcget_strict(@id, key)\n  end\n\n  def configure(key, val=None)\n    @listbox.itemconfigure(@id, key, val)\n  end\n\n  def configinfo(key=nil)\n    @listbox.itemconfiginfo(@id, key)\n  end\n\n  def current_configinfo(key=nil)\n    @listbox.current_itemconfiginfo(@id, key)\n  end\n\n  def delete\n    @listbox.delete(@id)\n    self\n  end\n\n  def edit(*args)\n    @listbox.edit(@id, *args)\n    self\n  end\n\n  def exist?\n    @listbox.exist?(@id)\n  end\n\n  def index\n    @listbox.index(@id)\n  end\n\n  def move(index)\n    @listbox.move(@id, index)\n  end\n\n  def see\n    @listbox.see(@id)\n  end\n\n  def selection_add\n    @listbox.selection_add(@id)\n  end\n\n  def selection_remove\n    @listbox.selection_remove(@id)\n  end\n\n  def selection_set\n    @listbox.selection_set(@id)\n  end\n\n  def selection_toggle\n    @listbox.selection_toggle(@id)\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/mainframe.rb",
    "content": "#\n#  tkextlib/bwidget/mainframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/progressbar'\n\nmodule Tk\n  module BWidget\n    class MainFrame < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::MainFrame\n  TkCommandNames = ['MainFrame'.freeze].freeze\n  WidgetClassName = 'MainFrame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'progressfg'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'progressvar'\n  end\n  private :__tkvariable_optkeys\n\n  def __val2ruby_optkeys  # { key=>proc, ... }\n    # The method is used to convert a opt-value to a ruby's object.\n    # When get the value of the option \"key\", \"proc.call(value)\" is called.\n    {\n      'menu'=>proc{|v| simplelist(v).collect!{|elem| simplelist(v)}}\n    }\n  end\n  private :__val2ruby_optkeys\n\n  def add_indicator(keys={}, &b)\n    win = window(tk_send('addindicator', *hash_kv(keys)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def add_toolbar(&b)\n    win = window(tk_send('addtoolbar'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_frame(&b)\n    win = window(tk_send('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_indicator(idx, &b)\n    win = window(tk_send('getindicator', idx))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_menu(menu_id, &b)\n    win = window(tk_send('getmenu', menu_id))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_toolbar(idx, &b)\n    win = window(tk_send('gettoolbar', idx))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def set_menustate(tag, state)\n    tk_send('setmenustate', tag, state)\n    self\n  end\n\n  def show_statusbar(name)\n    tk_send('showstatusbar', name)\n    self\n  end\n\n  def show_toolbar(idx, mode)\n    tk_send('showtoolbar', idx, mode)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/messagedlg.rb",
    "content": "#\n#  tkextlib/bwidget/messagedlg.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/dialog.rb'\n\nmodule Tk\n  module BWidget\n    class MessageDlg < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::MessageDlg\n  TkCommandNames = ['MessageDlg'.freeze].freeze\n  WidgetClassName = 'MessageDlg'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def initialize(parent=nil, keys=nil)\n    @relative = ''\n    if parent.kind_of?(Hash)\n      keys = _symbolkey2str(parent)\n      @relative = keys['parent'] if keys.key?('parent')\n      @relative = keys.delete('relative') if keys.key?('relative')\n      super(keys)\n    elsif keys\n      keys = _symbolkey2str(keys)\n      @relative = keys.delete('parent') if keys.key?('parent')\n      @relative = keys.delete('relative') if keys.key?('relative')\n      super(parent, keys)\n    else\n      super(parent)\n    end\n  end\n\n  def create_self(keys)\n    # NOT create widget.\n    # Because the widget no longer exist when returning from creation.\n    @keys = _symbolkey2str(keys).update('parent'=>@relative)\n    @info = nil\n  end\n  private :create_self\n\n  def __strval_optkeys\n    super() << 'message' << 'title'\n  end\n  private :__strval_optkeys\n\n  def __listval_optkeys\n    super() << 'buttons'\n  end\n  private :__listval_optkeys\n\n  def cget(slot)\n    slot = slot.to_s\n    if slot == 'relative'\n      slot = 'parent'\n    end\n    if winfo_exist?\n      val = super(slot)\n      @keys[slot] = val\n    end\n    @keys[slot]\n  end\n  def cget_strict(slot)\n    slot = slot.to_s\n    if slot == 'relative'\n      slot = 'parent'\n    end\n    if winfo_exist?\n      val = super(slot)\n      @keys[slot] = val\n    end\n    @keys[slot]\n  end\n\n  def configure(slot, value=None)\n    if winfo_exist?\n      super(slot, value)\n    end\n    if slot.kind_of?(Hash)\n      slot = _symbolkey2str(slot)\n      slot['parent'] = slot.delete('relative') if slot.key?('relative')\n      @keys.update(slot)\n\n      if @info\n        # update @info\n        slot.each{|k, v|\n          if TkComm::GET_CONFIGINFO_AS_ARRAY\n            if (inf = @info.assoc(k))\n              inf[-1] = v\n            else\n              @info << [k, '', '', '', v]\n            end\n          else\n            if (inf = @info[k])\n              inf[-1] = v\n            else\n              @info[k] = ['', '', '', v]\n            end\n          end\n        }\n      end\n\n    else # ! Hash\n      slot = slot.to_s\n      slot = 'parent' if slot == 'relative'\n      @keys[slot] = value\n\n      if @info\n        # update @info\n        if TkComm::GET_CONFIGINFO_AS_ARRAY\n          if (inf = @info.assoc(slot))\n            inf[-1] = value\n          else\n            @info << [slot, '', '', '', value]\n          end\n        else\n          if (inf = @info[slot])\n            inf[-1] = value\n          else\n            @info[slot] = ['', '', '', value]\n          end\n        end\n      end\n    end\n\n    self\n  end\n\n  def configinfo(slot=nil)\n    if winfo_exist?\n      @info = super()\n      if TkComm::GET_CONFIGINFO_AS_ARRAY\n        @info << ['relative', 'parent']\n      else\n        @info['relative'] = 'parent'\n      end\n    end\n\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if @info\n        if winfo_exist?\n          # update @keys\n          @info.each{|inf| @keys[inf[0]] = inf[-1] if inf.size > 2 }\n        end\n      else\n        @info = []\n        @keys.each{|k, v|\n          @info << [k, '', '', '', v]\n        }\n        @info << ['relative', 'parent']\n      end\n\n      if slot\n        @info.asoc(slot.to_s).dup\n      else\n        @info.dup\n      end\n\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if @info\n        if winfo_exist?\n          # update @keys\n          @info.each{|k, inf| @keys[k] = inf[-1] if inf.size > 2 }\n        end\n      else\n        @info = {}\n        @keys.each{|k, v|\n          @info[k] = ['', '', '', v]\n        }\n        @info['relative'] = 'parent'\n      end\n\n      if slot\n        @info[slot.to_s].dup\n      else\n        @info.dup\n      end\n    end\n  end\n\n  def create\n    # return the index of the pressed button, or nil if it is destroyed\n    ret = num_or_str(tk_call(self.class::TkCommandNames[0], \n                             @path, *hash_kv(@keys)))\n    (ret < 0)? nil: ret\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/notebook.rb",
    "content": "#\n#  tkextlib/bwidget/notebook.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class NoteBook < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::NoteBook\n  include TkItemConfigMethod\n\n  TkCommandNames = ['NoteBook'.freeze].freeze\n  WidgetClassName = 'NoteBook'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  class Event_for_Tabs < TkEvent::Event\n    def self._get_extra_args_tbl\n      [ \n        TkComm.method(:string)   # page idenfier\n      ]\n    end\n  end\n\n  def __boolval_optkeys\n    super() << 'homogeneous'\n  end\n  private :__boolval_optkeys\n\n  def tagid(id)\n    if id.kind_of?(TkWindow)\n      #id.path\n      id.epath\n    elsif id.kind_of?(TkObject)\n      id.to_eval\n    else\n      # id.to_s\n      _get_eval_string(id)\n    end\n  end\n\n  #def tabbind(*args)\n  #  _bind_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args)\n  #  self\n  #end\n  def tabbind(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_for_event_class(Event_for_Tabs, [path, 'bindtabs'], \n                          context, cmd, *args)\n    self\n  end\n\n  #def tabbind_append(*args)\n  #  _bind_append_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args)\n  #  self\n  #end\n  def tabbind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append_for_event_class(Event_for_Tabs, [path, 'bindtabs'], \n                                 context, cmd, *args)\n    self\n  end\n\n  def tabbind_remove(*args)\n    _bind_remove_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args)\n    self\n  end\n\n  def tabbindinfo(*args)\n    _bindinfo_for_event_class(Event_for_Tabs, [path, 'bindtabs'], *args)\n  end\n\n  def add(page, &b)\n    win = window(tk_send('add', tagid(page)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def compute_size\n    tk_send('compute_size')\n    self\n  end\n\n  def delete(page, destroyframe=None)\n    tk_send('delete', tagid(page), destroyframe)\n    self\n  end\n\n  def get_frame(page, &b)\n    win = window(tk_send('getframe', tagid(page)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def index(page)\n    num_or_str(tk_send('index', tagid(page)))\n  end\n\n  def insert(index, page, keys={}, &b)\n    win = window(tk_send('insert', index, tagid(page), *hash_kv(keys)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def move(page, index)\n    tk_send('move', tagid(page), index)\n    self\n  end\n\n  def get_page(page)\n    tk_send('pages', page)\n  end\n\n  def pages(first=None, last=None)\n    list(tk_send('pages', first, last))\n  end\n\n  def raise(page=nil)\n    if page\n      tk_send('raise', page)\n      self\n    else\n      tk_send('raise')\n    end\n  end\n\n  def see(page)\n    tk_send('see', page)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/pagesmanager.rb",
    "content": "#\n#  tkextlib/bwidget/pagesmanager.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class PagesManager < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::PagesManager\n  TkCommandNames = ['PagesManager'.freeze].freeze\n  WidgetClassName = 'PagesManager'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def tagid(id)\n    # id.to_s\n    _get_eval_string(id)\n  end\n\n  def add(page, &b)\n    win = window(tk_send('add', tagid(page)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def compute_size\n    tk_send('compute_size')\n    self\n  end\n\n  def delete(page)\n    tk_send('delete', tagid(page))\n    self\n  end\n\n  def get_frame(page, &b)\n    win = window(tk_send('getframe', tagid(page)))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def get_page(page)\n    tk_send('pages', page)\n  end\n\n  def pages(first=None, last=None)\n    list(tk_send('pages', first, last))\n  end\n\n  def raise(page=None)\n    tk_send('raise', page)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/panedwindow.rb",
    "content": "#\n#  tkextlib/bwidget/panedwindow.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class PanedWindow < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::PanedWindow\n  TkCommandNames = ['PanedWindow'.freeze].freeze\n  WidgetClassName = 'PanedWindow'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def add(keys={})\n    window(tk_send('add', *hash_kv(keys)))\n  end\n\n  def get_frame(idx, &b)\n    win = window(tk_send_without_enc('getframe', idx))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/panelframe.rb",
    "content": "#\n#  tkextlib/bwidget/panelframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class PanelFrame < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::PanelFrame\n  TkCommandNames = ['PanelFrame'.freeze].freeze\n  WidgetClassName = 'PanelFrame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() + ['panelforeground', 'panelbackground']\n  end\n  private :__strval_optkeys\n\n  def add(win, keys={})\n    tk_send('add', win, keys)\n    self\n  end\n\n  def delete(*wins)\n    tk_send('delete', *wins)\n    self\n  end\n\n  def get_frame(&b)\n    win = window(tk_send_without_enc('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def items\n    list(tk_send('items'))\n  end\n\n  def remove(*wins)\n    tk_send('remove', *wins)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/passwddlg.rb",
    "content": "#\n#  tkextlib/bwidget/passwddlg.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/messagedlg'\n\nmodule Tk\n  module BWidget\n    class PasswdDlg < Tk::BWidget::MessageDlg\n    end\n  end\nend\n\nclass Tk::BWidget::PasswdDlg\n  TkCommandNames = ['PasswdDlg'.freeze].freeze\n  WidgetClassName = 'PasswdDlg'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'loginhelptext' << 'loginlabel' << 'logintext' << \n      'passwdlabel' << 'passwdtext'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'passwdeditable' << 'homogeneous'\n  end\n  private :__boolval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'loginhelpvar' << 'logintextvariable' << \n      'passwdhelpvar' << 'passwdtextvariable'\n  end\n  private :__tkvariable_optkeys\n\n  def create\n    login, passwd = simplelist(tk_call(self.class::TkCommandNames[0], \n                                       @path, *hash_kv(@keys)))\n    [login, passwd]\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/progressbar.rb",
    "content": "#\n#  tkextlib/bwidget/progressbar.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class ProgressBar < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::ProgressBar\n  TkCommandNames = ['ProgressBar'.freeze].freeze\n  WidgetClassName = 'ProgressBar'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/progressdlg.rb",
    "content": "#\n#  tkextlib/bwidget/progressdlg.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/variable'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/progressbar'\nrequire 'tkextlib/bwidget/messagedlg'\n\nmodule Tk\n  module BWidget\n    class ProgressDlg < Tk::BWidget::MessageDlg\n    end\n  end\nend\n\nclass Tk::BWidget::ProgressDlg\n  TkCommandNames = ['ProgressDlg'.freeze].freeze\n  WidgetClassName = 'ProgressDlg'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    # NOT create widget for reusing the object\n    super(keys)\n    @keys['textvariable'] = TkVariable.new unless @keys.key?('textvariable')\n    @keys['variable']     = TkVariable.new unless @keys.key?('variable')\n  end\n\n  def textvariable\n    @keys['textvariable']\n  end\n\n  def text\n    @keys['textvariable'].value\n  end\n\n  def text= (txt)\n    @keys['textvariable'].value = txt\n  end\n\n  def variable\n    @keys['variable']\n  end\n\n  def value\n    @keys['variable'].value\n  end\n\n  def value= (val)\n    @keys['variable'].value = val\n  end\n\n  def create\n    window(tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys)))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/scrollableframe.rb",
    "content": "#\n#  tkextlib/bwidget/scrollableframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class ScrollableFrame < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::ScrollableFrame\n  include Scrollable\n\n  TkCommandNames = ['ScrollableFrame'.freeze].freeze\n  WidgetClassName = 'ScrollableFrame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def get_frame(&b)\n    win = window(tk_send_without_enc('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def see(win, vert=None, horiz=None)\n    tk_send_without_enc('see', win, vert, horiz)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb",
    "content": "#\n#  tkextlib/bwidget/scrolledwindow.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class ScrolledWindow < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::ScrolledWindow\n  TkCommandNames = ['ScrolledWindow'.freeze].freeze\n  WidgetClassName = 'ScrolledWindow'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def get_frame(&b)\n    win = window(tk_send_without_enc('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def set_widget(win)\n    tk_send_without_enc('setwidget', win)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/scrollview.rb",
    "content": "#\n#  tkextlib/bwidget/scrollview.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class ScrollView < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::ScrollView\n  TkCommandNames = ['ScrollView'.freeze].freeze\n  WidgetClassName = 'ScrollView'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'fill'\n  end\n  private :__strval_optkeys\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/selectcolor.rb",
    "content": "#\n#  tkextlib/bwidget/selectcolor.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/messagedlg'\n\nmodule Tk\n  module BWidget\n    class SelectColor < Tk::BWidget::MessageDlg\n      class Dialog < Tk::BWidget::SelectColor\n      end\n      class Menubutton < Tk::Menubutton\n      end\n      MenuButton = Menubutton\n    end\n  end\nend\n\nclass Tk::BWidget::SelectColor\n  extend Tk\n\n  TkCommandNames = ['SelectColor'.freeze].freeze\n  WidgetClassName = 'SelectColor'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def dialog(keys={})\n    newkeys = @keys.dup\n    newkeys.update(_symbolkey2str(keys))\n    tk_call('SelectColor::dialog', @path, *hash_kv(newkeys))\n  end\n\n  def menu(*args)\n    if args[-1].kind_of?(Hash)\n      keys = args.pop\n    else\n      keys = {}\n    end\n    place = args.flatten\n    newkeys = @keys.dup\n    newkeys.update(_symbolkey2str(keys))\n    tk_call('SelectColor::menu', @path, place, *hash_kv(newkeys))\n  end\n\n  def self.set_color(idx, color)\n    tk_call('SelectColor::setcolor', idx, color)\n  end\nend\n\nclass Tk::BWidget::SelectColor::Dialog\n  def create_self(keys)\n    super(keys)\n    @keys['type'] = 'dialog'\n  end\n\n  def create\n    @keys['type'] = 'dialog'  # 'dialog' type returns color\n    tk_call(Tk::BWidget::SelectColor::TkCommandNames[0], \n            @path, *hash_kv(@keys))\n  end\nend\n\nclass Tk::BWidget::SelectColor::Menubutton\n  def create_self(keys)\n    keys = {} unless keys\n    keys = _symbolkey2str(keys)\n    keys['type'] = 'menubutton'  # 'toolbar' type returns widget path\n    window(tk_call(Tk::BWidget::SelectColor::TkCommandNames[0], \n                   @path, *hash_kv(keys)))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/selectfont.rb",
    "content": "#\n#  tkextlib/bwidget/selectfont.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/messagedlg'\n\nmodule Tk\n  module BWidget\n    class SelectFont < Tk::BWidget::MessageDlg\n      class Dialog < Tk::BWidget::SelectFont\n      end\n      class Toolbar < TkWindow\n      end\n    end\n  end\nend\n\nclass Tk::BWidget::SelectFont\n  extend Tk\n\n  TkCommandNames = ['SelectFont'.freeze].freeze\n  WidgetClassName = 'SelectFont'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'sampletext' <<  'title'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    [] # without fontobj operation\n  end\n  private :__font_optkeys\n\n  def create\n    tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys))\n  end\n\n  def self.load_font\n    tk_call('SelectFont::loadfont')\n  end\nend\n\nclass Tk::BWidget::SelectFont::Dialog\n  def __font_optkeys\n    [] # without fontobj operation\n  end\n\n  def create_self(keys)\n    super(keys)\n    @keys['type'] = 'dialog'\n  end\n\n  def configure(slot, value=None)\n    if slot.kind_of?(Hash)\n      slot.delete['type']\n      slot.delete[:type]\n      return self if slot.empty?\n    else\n      return self if slot == 'type' || slot == :type\n    end\n    super(slot, value)\n  end\n\n  def create\n    @keys['type'] = 'dialog'  # 'dialog' type returns font name\n    tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], @path, *hash_kv(@keys))\n  end\nend\n\nclass Tk::BWidget::SelectFont::Toolbar\n  def __font_optkeys\n    [] # without fontobj operation\n  end\n\n  def create_self(keys)\n    keys = {} unless keys\n    keys = _symbolkey2str(keys)\n    keys['type'] = 'toolbar'  # 'toolbar' type returns widget path\n    window(tk_call(Tk::BWidget::SelectFont::TkCommandNames[0], \n                   @path, *hash_kv(keys)))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/separator.rb",
    "content": "#\n#  tkextlib/bwidget/separator.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class Separator < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::Separator\n  TkCommandNames = ['Separator'.freeze].freeze\n  WidgetClassName = 'Separator'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/spinbox.rb",
    "content": "#\n#  tkextlib/bwidget/entry.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\nrequire 'tkextlib/bwidget/arrowbutton'\nrequire 'tkextlib/bwidget/entry'\n\nmodule Tk\n  module BWidget\n    class SpinBox < Tk::Entry\n    end\n  end\nend\n\nclass Tk::BWidget::SpinBox\n  include Scrollable\n\n  TkCommandNames = ['SpinBox'.freeze].freeze\n  WidgetClassName = 'SpinBox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'dragenabled' << 'dropenabled' << 'editable'\n  end\n  private :__boolval_optkeys\n\n  def __listval_optkeys\n    super() << 'values'\n  end\n  private :__listval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\n\n  #def entrybind(*args)\n  #  _bind([path, 'bind'], *args)\n  #  self\n  #end\n  def entrybind(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([path, 'bind'], context, cmd, *args)\n    self\n  end\n\n  #def entrybind_append(*args)\n  #  _bind_append([path, 'bind'], *args)\n  #  self\n  #end\n  def entrybind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([path, 'bind'], context, cmd, *args)\n    self\n  end\n\n  def entrybind_remove(*args)\n    _bind_remove([path, 'bind'], *args)\n    self\n  end\n\n  def entrybindinfo(*args)\n    _bindinfo([path, 'bind'], *args)\n    self\n  end\n\n  def get_index_of_value\n    number(tk_send_without_enc('getvalue'))\n  end\n  alias get_value get_index_of_value\n  alias get_value_index get_index_of_value\n\n  def set_value_by_index(idx)\n    idx = \"@#{idx}\" if idx.kind_of?(Integer)\n    tk_send_without_enc('setvalue', idx)\n    self\n  end\n  alias set_value set_value_by_index\n  alias set_index_value set_value_by_index\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/statusbar.rb",
    "content": "#\n#  tkextlib/bwidget/statusbar.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class StatusBar < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::StatusBar\n  TkCommandNames = ['StatusBar'.freeze].freeze\n  WidgetClassName = 'StatusBar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'showresize'\n  end\n  private :__boolval_optkeys\n\n  def add(win, keys={})\n    tk_send('add', win, keys)\n    self\n  end\n\n  def delete(*wins)\n    tk_send('delete', *wins)\n    self\n  end\n\n  def get_frame(&b)\n    win = window(tk_send_without_enc('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def items\n    list(tk_send('items'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/titleframe.rb",
    "content": "#\n#  tkextlib/bwidget/titleframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/frame'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class TitleFrame < TkWindow\n    end\n  end\nend\n\nclass Tk::BWidget::TitleFrame\n  TkCommandNames = ['TitleFrame'.freeze].freeze\n  WidgetClassName = 'TitleFrame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def get_frame(&b)\n    win = window(tk_send_without_enc('getframe'))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/tree.rb",
    "content": "#\n#  tkextlib/bwidget/tree.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/canvas'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    class Tree < TkWindow\n      class Node < TkObject\n      end\n    end\n  end\nend\n\nclass Tk::BWidget::Tree\n  include TkItemConfigMethod\n  include Scrollable\n\n  TkCommandNames = ['Tree'.freeze].freeze\n  WidgetClassName = 'Tree'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  class Event_for_Items < TkEvent::Event\n    def self._get_extra_args_tbl\n      [ \n        TkComm.method(:string)   # item idenfier\n      ]\n    end\n  end\n\n  def __strval_optkeys\n    super() << 'crossfill' << 'linesfill'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'dragenabled' << 'dropenabled' << \n      'redraw' << 'selectfill' << 'showlines'\n  end\n  private :__boolval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvar'\n  end\n  private :__tkvariable_optkeys\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::BWidget::Tree::Node)\n      tag.id\n    else\n      # tag\n      _get_eval_string(tag)\n    end\n  end\n\n  #def imagebind(*args)\n  #  _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n  #  self\n  #end\n  def imagebind(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_for_event_class(Event_for_Items, [path, 'bindImage'], \n                          context, cmd, *args)\n    self\n  end\n\n  #def imagebind_append(*args)\n  #  _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n  #  self\n  #end\n  def imagebind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append_for_event_class(Event_for_Items, [path, 'bindImage'], \n                                 context, cmd, *args)\n    self\n  end\n\n  def imagebind_remove(*args)\n    _bind_remove_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n    self\n  end\n\n  def imagebindinfo(*args)\n    _bindinfo_for_event_class(Event_for_Items, [path, 'bindImage'], *args)\n  end\n\n  #def textbind(*args)\n  #  _bind_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n  #  self\n  #end\n  def textbind(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_for_event_class(Event_for_Items, [path, 'bindText'], \n                          context, cmd, *args)\n    self\n  end\n\n  #def textbind_append(*args)\n  #  _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n  #  self\n  #end\n  def textbind_append(context, *args)\n    #if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append_for_event_class(Event_for_Items, [path, 'bindText'], \n                                 context, cmd, *args)\n    self\n  end\n\n  def textbind_remove(*args)\n    _bind_remove_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n    self\n  end\n\n  def textbindinfo(*args)\n    _bindinfo_for_event_class(Event_for_Items, [path, 'bindText'], *args)\n  end\n\n  def close_tree(node, recurse=None)\n    tk_send('closetree', tagid(node), recurse)\n    self\n  end\n\n  def delete(*args)\n    tk_send('delete', *(args.collect{|node| tagid(node)}))\n    self\n  end\n\n  def edit(node, text, *args)\n    tk_send('edit', tagid(node), text, *args)\n    self\n  end\n\n  def exist?(node)\n    bool(tk_send('exists', tagid(node)))\n  end\n\n  def index(node)\n    num_or_str(tk_send('index', tagid(node)))\n  end\n\n  def insert(idx, parent, node, keys={})\n    tk_send('insert', idx, tagid(parent), tagid(node), *hash_kv(keys))\n    self\n  end\n\n  def move(parent, node, idx)\n    tk_send('move', tagid(parent), tagid(node), idx)\n    self\n  end\n\n  def get_node(node, idx)\n    Tk::BWidget::Tree::Node.id2obj(self, tk_send('nodes', tagid(node), idx))\n  end\n\n  def nodes(node, first=None, last=None)\n    simplelist(tk_send('nodes', tagid(node), first, last)).collect{|node|\n      Tk::BWidget::Tree::Node.id2obj(self, node)\n    }\n  end\n\n  def open?(node)\n    bool(@tree.itemcget(tagid(node), 'open'))\n  end\n\n  def open_tree(node, recurse=None)\n    tk_send('opentree', tagid(node), recurse)\n    self\n  end\n\n  def parent(node)\n    Tk::BWidget::Tree::Node.id2obj(self, tk_send('parent', tagid(node)))\n  end\n\n  def reorder(node, neworder)\n    tk_send('reorder', tagid(node), neworder)\n    self\n  end\n\n  def see(node)\n    tk_send('see', tagid(node))\n    self\n  end\n\n  def selection_add(*args)\n    tk_send_without_enc('selection', 'add', \n                        *(args.collect{|node| tagid(node)}))\n    self\n  end\n\n  def selection_clear\n    tk_send_without_enc('selection', 'clear')\n    self\n  end\n\n  def selection_get\n    list(tk_send_without_enc('selection', 'get'))\n  end\n\n  def selection_include?(*args)\n    bool(tk_send_without_enc('selection', 'get', \n                             *(args.collect{|node| tagid(node)})))\n  end\n\n  def selection_range(*args)\n    tk_send_without_enc('selection', 'range', \n                        *(args.collect{|node| tagid(node)}))\n    self\n  end\n\n  def selection_remove(*args)\n    tk_send_without_enc('selection', 'remove', \n                        *(args.collect{|node| tagid(node)}))\n    self\n  end\n\n  def selection_set(*args)\n    tk_send_without_enc('selection', 'set', \n                        *(args.collect{|node| tagid(node)}))\n    self\n  end\n\n  def selection_toggle(*args)\n    tk_send_without_enc('selection', 'toggle', \n                        *(args.collect{|node| tagid(node)}))\n    self\n  end\n\n  def toggle(node)\n    tk_send_without_enc('toggle', tagid(node))\n    self\n  end\n\n  def visible(node)\n    bool(tk_send_without_enc('visible', tagid(node)))\n  end\nend\n\nclass Tk::BWidget::Tree::Node\n  include TkTreatTagFont\n\n  TreeNode_TBL = TkCore::INTERP.create_table\n\n  (TreeNode_ID = ['bw:node'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    TreeNode_TBL.mutex.synchronize{ TreeNode_TBL.clear }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    TreeNode_TBL.mutex.synchronize{\n      if TreeNode_TBL[tpath]\n        TreeNode_TBL[tpath][id]? TreeNode_TBL[tpath][id]: id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(tree, *args)\n    if tree.kind_of?(Tk::BWidget::Tree)\n      @tree = tree\n      parent = args.shift\n      if parent.kind_of?(Tk::BWidget::Tree::Node)\n        if parent.tree.path != @tree.path\n          fail RuntimeError, 'tree of parent node is not match'\n        end\n      end\n    elsif tree.kind_of?(Tk::BWidget::Tree::Node)\n      @tree = tree.tree\n      parent = tree.parent\n    else\n      fail RuntimeError, \n        \"expect Tk::BWidget::Tree or Tk::BWidget::Tree::Node for 1st argument\"\n    end\n\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n    else\n      keys = {}\n    end\n\n    index = keys.delete('index')\n    unless args.empty?\n      index = args.shift\n    end\n    index = 'end' unless index\n\n    unless args.empty?\n      fail RuntimeError, 'too much arguments'\n    end\n\n    @tpath = @tree.path\n\n    if keys.key?('nodename')\n      @path = @id = keys.delete('nodename')\n    else\n      TreeNode_ID.mutex.synchronize{\n        @path = @id = TreeNode_ID.join(TkCore::INTERP._ip_id_)\n        TreeNode_ID[1].succ!\n      }\n    end\n\n    TreeNode_TBL.mutex.synchronize{\n      TreeNode_TBL[@id] = self\n      TreeNode_TBL[@tpath] = {} unless TreeNode_TBL[@tpath]\n      TreeNode_TBL[@tpath][@id] = self\n    }\n\n    @tree.insert(index, parent, @id, keys)\n  end\n\n  def tree\n    @tree\n  end\n\n  def id\n    @id\n  end\n\n  def [](key)\n    cget(key)\n  end\n\n  def []=(key, val)\n    configure(key, val)\n    val\n  end\n\n  def cget(key)\n    @tree.itemcget(@id, key)\n  end\n  def cget_strict(key)\n    @tree.itemcget_strict(@id, key)\n  end\n\n  def configure(key, val=None)\n    @tree.itemconfigure(@id, key, val)\n  end\n\n  def configinfo(key=nil)\n    @tree.itemconfiginfo(@id, key)\n  end\n\n  def current_configinfo(key=nil)\n    @tree.current_itemconfiginfo(@id, key)\n  end\n\n  def close_tree(recurse=None)\n    @tree.close_tree(@id, recurse)\n    self\n  end\n\n  def delete\n    @tree.delete(@id)\n    self\n  end\n\n  def edit(*args)\n    @tree.edit(@id, *args)\n    self\n  end\n\n  def exist?\n    @tree.exist?(@id)\n  end\n\n  def index\n    @tree.index(@id)\n  end\n\n  def move(index, parent=nil)\n    if parent\n      @tree.move(parent, @id, index)\n    else\n      @tree.move(self.parent, @id, index)\n    end\n  end\n\n  def open_tree(recurse=None)\n    @tree.open_tree(@id, recurse)\n    self\n  end\n\n  def open?\n    bool(@tree.itemcget(@id, 'open'))\n  end\n\n  def parent\n    @tree.parent(@id)\n  end\n\n  def reorder(neworder)\n    @tree.reorder(@id, neworder)\n  end\n\n  def see\n    @tree.see(@id)\n  end\n\n  def selection_add\n    @tree.selection_add(@id)\n  end\n\n  def selection_remove\n    @tree.selection_remove(@id)\n  end\n\n  def selection_set\n    @tree.selection_set(@id)\n  end\n\n  def selection_toggle\n    @tree.selection_toggle(@id)\n  end\n\n  def toggle\n    @tree.toggle(@id)\n  end\n\n  def visible\n    @tree.visible(@id)\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget/widget.rb",
    "content": "#\n#  tkextlib/bwidget/widget.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/bwidget.rb'\n\nmodule Tk\n  module BWidget\n    module Widget\n    end\n  end\nend\n\nmodule Tk::BWidget::Widget\n  include Tk\n  extend Tk\n\n  def self.__pathname\n    'Widget::configure'\n  end\n\n  def self.__cget_cmd\n    ['Widget::cget']\n  end\n\n  def self.__config_cmd\n    ['Widget::configure']\n  end\n\n  def self.cget_strict(slot)\n    slot = slot.to_s\n    info = {}\n    self.current_configinfo.each{|k,v| info[k.to_s] = v if k.to_s == slot}\n    fail RuntimeError, \"unknown option \\\"-#{slot}\\\"\"  if info.empty?\n    info.values[0]\n  end\n  def self.cget(slot)\n    self.current_configinfo(slot).values[0]\n  end\n\n  def self.add_map(klass, subclass, subpath, opts)\n    tk_call('Widget::addmap', klass, subclass, subpath, opts)\n  end\n\n  def self.bwinclude(klass, subclass, subpath, *args)\n    tk_call('Widget::bwinclude', klass, subclass, subpath, *args)\n  end\n\n  def self.create(klass, path, rename=None, &b)\n    win = window(tk_call('Widget::create', klass, path, rename))\n    if b\n      if TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n        win.instance_exec(self, &b)\n      else\n        win.instance_eval(&b)\n      end\n    end\n    win\n  end\n\n  def self.declare(klass, optlist)\n    tk_call('Widget::declare', klass, optlist)\n  end\n\n  def self.define(klass, filename, *args)\n    tk_call('Widget::define', klass, filename, *args)\n  end\n\n  def self.destroy(win)\n    tk_call('Widget::destroy', _epath(win))\n  end\n\n  def self.focus_next(win)\n    tk_call('Widget::focusNext', win)\n  end\n\n  def self.focus_ok(win)\n    tk_call('Widget::focusOk', win)\n  end\n\n  def self.focus_prev(win)\n    tk_call('Widget::focusPrev', win)\n  end\n\n  def self.generate_doc(dir, widgetlist)\n    tk_call('Widget::generate-doc', dir, widgetlist)\n  end\n\n  def self.generate_widget_doc(klass, iscmd, file)\n    tk_call('Widget::generate-widget-doc', klass, iscmd, file)\n  end\n\n  def self.get_option(win, option)\n    tk_call('Widget::getoption', win, option)\n  end\n\n  def self.get_variable(win, varname, my_varname=None)\n    tk_call('Widget::getVariable', win, varname, my_varname)\n  end\n\n  def self.has_changed(win, option, pvalue)\n    tk_call('Widget::hasChanged', win, option, pvalue)\n  end\n\n  def self.init(klass, win, options)\n    tk_call('Widget::init', klass, win, options)\n  end\n\n  def self.set_option(win, option, value)\n    tk_call('Widget::setoption', win, option, value)\n  end\n\n  def self.sub_cget_strict(win, subwidget)\n    tk_call('Widget::subcget', win, subwidget)\n  end\n  def self.sub_cget(win, subwidget)\n    self.sub_cget_strict(win, subwidget)\n  end\n\n  def self.sync_options(klass, subclass, subpath, options)\n    tk_call('Widget::syncoptions', klass, subclass, subpath, options)\n  end\n\n  def self.tkinclude(klass, tkwidget, subpath, *args)\n    tk_call('Widget::tkinclude', klass, tkwidget, subpath, *args)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/bwidget.rb",
    "content": "#\n#  BWidget extension support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/bwidget/setup.rb'\n\n# load all image format handlers\n#TkPackage.require('BWidget', '1.7')\nTkPackage.require('BWidget')\n\nmodule Tk\n  module BWidget\n    TkComm::TkExtlibAutoloadModule.unshift(self)\n\n    extend TkCore\n\n    LIBRARY = tk_call('set', '::BWIDGET::LIBRARY')\n\n    PACKAGE_NAME = 'BWidget'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('BWidget')\n      rescue\n        ''\n      end\n    end\n\n    def self.XLFDfont(cmd, *args)\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        args.concat(hash_kv(keys))\n      end\n      tk_call('BWidget::XLFDfont', cmd, *args)\n    end\n\n    def self.assert(exp, msg=None)\n      tk_call('BWidget::assert', exp, msg)\n    end\n\n    def self.badOptionString(type, value, list)\n      tk_call('BWidget::badOptionString', type, value, list)\n    end\n\n    def self.bindMouseWheel(widget)\n      tk_call('BWidget::bindMouseWheel', widget)\n    end\n\n    def self.classes(klass)\n      list(tk_call('BWidget::classes', klass))\n    end\n\n    def self.clonename(menu)\n      tk_call('BWidget::clonename', menu)\n    end\n\n    def self.focus(opt, path)\n      tk_call('BWidget::focus', opt, path)\n    end\n\n    def self.get3dcolor(path, bgcolor)\n      tk_call('BWidget::get3dcolor', path, bgcolor)\n    end\n\n    def self.getname(name)\n      tk_call('BWidget::getname', name)\n    end\n\n    def self.grab(opt, path)\n      tk_call('BWidget::grab', opt, path)\n    end\n\n    def self.inuse(klass)\n      bool(tk_call('BWidget::inuse', klass))\n    end\n\n    def self.library(klass, *klasses)\n      tk_call('BWidget::library', klass, *klasses)\n    end\n\n    def self.lreorder(list, neworder)\n      tk_call('BWidget::lreorder', list, neworder)\n    end\n\n    def self.parsetext(text)\n      tk_call('BWidget::parsetext', text)\n    end\n\n    def self.place(path, w, h, *args)\n      if args[-1].kind_of?(Hash)\n        keys = args.pop\n        args.concat(hash_kv(keys))\n      end\n      tk_call('BWidget::place', path, w, h, *(args.flatten))\n    end\n\n    def self.write(file, mode=None)\n      tk_call('BWidget::write', file, mode)\n    end\n\n    def self.wrongNumArgsString(str)\n      tk_call('BWidget::wrongNumArgsString', str)\n    end\n\n    ####################################################\n\n    autoload :ArrowButton,     'tkextlib/bwidget/arrowbutton'\n    autoload :Bitmap,          'tkextlib/bwidget/bitmap'\n    autoload :Button,          'tkextlib/bwidget/button'\n    autoload :ButtonBox,       'tkextlib/bwidget/buttonbox'\n    autoload :ComboBox,        'tkextlib/bwidget/combobox'\n    autoload :Dialog,          'tkextlib/bwidget/dialog'\n    autoload :DragSite,        'tkextlib/bwidget/dragsite'\n    autoload :DropSite,        'tkextlib/bwidget/dropsite'\n    autoload :DynamicHelp,     'tkextlib/bwidget/dynamichelp'\n    autoload :Entry,           'tkextlib/bwidget/entry'\n    autoload :Label,           'tkextlib/bwidget/label'\n    autoload :LabelEntry,      'tkextlib/bwidget/labelentry'\n    autoload :LabelFrame,      'tkextlib/bwidget/labelframe'\n    autoload :ListBox,         'tkextlib/bwidget/listbox'\n    autoload :MainFrame,       'tkextlib/bwidget/mainframe'\n    autoload :MessageDlg,      'tkextlib/bwidget/messagedlg'\n    autoload :NoteBook,        'tkextlib/bwidget/notebook'\n    autoload :PagesManager,    'tkextlib/bwidget/pagesmanager'\n    autoload :PanedWindow,     'tkextlib/bwidget/panedwindow'\n    autoload :PasswdDlg,       'tkextlib/bwidget/passwddlg'\n    autoload :ProgressBar,     'tkextlib/bwidget/progressbar'\n    autoload :ProgressDlg,     'tkextlib/bwidget/progressdlg'\n    autoload :ScrollableFrame, 'tkextlib/bwidget/scrollableframe'\n    autoload :ScrolledWindow,  'tkextlib/bwidget/scrolledwindow'\n    autoload :ScrollView,      'tkextlib/bwidget/scrollview'\n    autoload :SelectColor,     'tkextlib/bwidget/selectcolor'\n    autoload :SelectFont,      'tkextlib/bwidget/selectfont'\n    autoload :Separator,       'tkextlib/bwidget/separator'\n    autoload :SpinBox,         'tkextlib/bwidget/spinbox'\n    autoload :TitleFrame,      'tkextlib/bwidget/titleframe'\n    autoload :Tree,            'tkextlib/bwidget/tree'\n    autoload :Widget,          'tkextlib/bwidget/widget'\n\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/itcl/incr_tcl.rb",
    "content": "#\n#  tkextlib/itk/incr_tcl.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script\nrequire 'tkextlib/itcl.rb'\n\n# TkPackage.require('Itcl', '3.2')\nTkPackage.require('Itcl')\n\nmodule Tk\n  module Itcl\n    include Tk\n    extend Tk\n\n    LIBRARY = TkVarAccess.new('::itcl::library')\n    PURIST = TkVarAccess.new('::itcl::purist')\n\n    VERSION    = TkCore::INTERP._invoke(\"set\", \"::itcl::version\").freeze\n    PATCHLEVEL = TkCore::INTERP._invoke(\"set\", \"::itcl::patchLevel\").freeze\n\n    PACKAGE_NAME = 'Itcl'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Itcl')\n      rescue\n        ''\n      end\n    end\n\n    ##############################################\n\n    class ItclObject < TkObject\n      ITCL_CLASSNAME = ''.freeze\n\n      (ITCL_OBJ_ID = ['itclobj'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n      ITCL_OBJ_TBL = {}.taint\n\n      def initialize(*args)\n        if (@klass = self.class::ITCL_CLASSNAME).empty?\n          fail RuntimeError, 'unknown itcl class (abstract class?)'\n        end\n        Tk::Itcl::ItclObject::ITCL_OBJ_ID.mutex.synchronize{\n          @id = Tk::Itcl::ItclObject::TCL_OBJ_ID.join(TkCore::INTERP._ip_id_)\n          Tk::Itcl::ItclObject::ITCL_OBJ_ID[1].succ!\n        }\n        @path = @id\n      end\n\n      def self.call_proc(name, *args)\n        tk_call(\"#{ITCL_CLASSNAME}::#{cmd}\", *args)\n      end\n\n      def call_method(name, *args)\n        tk_call(@path, name, *args)\n      end\n\n      def isa(klass)\n        bool(tk_call(@path, 'isa', klass))\n      end\n      alias itcl_kind_of? isa\n\n      def info_class\n        tk_call(@path, 'info', 'class')\n      end\n\n      def info_inherit\n        simplelist(tk_call(@path, 'info', 'inherit'))\n      end\n\n      def info_heritage\n        list(tk_call(@path, 'info', 'heritage'))\n      end\n\n      def info_function(*args)\n        if args[-1].kind_of?(Array)\n          params = args.pop\n          params.each{|param|\n            param = param.to_s\n            args << ( (param[0] == ?-)? param: \"-#{param}\" )\n          }\n        end\n        list(tk_call(@path, 'info', 'function', *args))\n      end\n\n      def info_variable(*args)\n        if args[-1].kind_of?(Array)\n          params = args.pop\n          params.each{|param|\n            param = param.to_s\n            args << ( (param[0] == ?-)? param: \"-#{param}\" )\n          }\n        end\n        list(tk_call(@path, 'info', 'variable', *args))\n      end\n    end\n\n    ##############################################\n\n    def self.body(klass, func, args, body)\n      tk_call('::itcl::body', \"#{klass}::#{func}\", args, body)\n    end\n\n    def self.code(cmd, *args)\n      tk_call('::itcl::code', cmd, *args)\n    end\n\n    def self.code_in_namespace(namespace, cmd, *args)\n      tk_call('::itcl::code', '-namespace', namespace, cmd, *args)\n    end\n\n    def self.configbody(klass, var, body)\n      tk_call('::itcl::configbody', \"#{klass}::#{var}\", body)\n    end\n\n    def self.create_itcl_class(name, body)\n      TkCore::INTERP._invoke('::itcl::class', name, body)\n      klass = Class.new(Tk::Itcl::ItclObject)\n      klass.const_set('ITCL_CLASSNAME', name.dup.freeze)\n      klass\n    end\n\n    def self.delete_itcl_class(*names)\n      tk_call('::itcl::delete', 'class',  *names)\n    end\n\n    def self.delete_itcl_object(*names)\n      tk_call('::itcl::delete', 'object',  *names)\n    end\n\n    def self.delete_namespace(*names)\n      tk_call('::itcl::delete', 'namespace',  *names)\n    end\n\n    def self.ensemble(name, *args)\n      tk_call('::itcl::ensemble', name, *args)\n    end\n\n    def self.find_classes(pat=None)\n      simplelist(tk_call('::itcl::find', 'classes', pat))\n    end\n\n    def self.find_objects(*args)\n      simplelist(tk_call('::itcl::find', 'objects', *args))\n    end\n\n    def self.is_itcl_class(target)\n      bool(tk_call('::itcl::is', 'class', target))\n    end\n\n    def self.is_itcl_object(target)\n      bool(tk_call('::itcl::is', 'object', target))\n    end\n\n    def self.create_local_obj(klass, name, *args)\n      tk_call('::itcl::local', klass, name, *args)\n    end\n\n    def self.is_itcl_instance(klass, target)\n      bool(tk_call('::itcl::is', 'object', '-class', klass, target))\n    end\n\n    def self.scope(var)\n      tk_call('::itcl::scope', var)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/itcl/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n\n\n# set [incr Tcl] library directory\n\n# ENV['ITCL_LIBRARY'] = '/usr/local/ActiveTcl/lib/itcl3.2/'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/itcl.rb",
    "content": "#\n#  [incr Tcl] support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/itcl/setup.rb'\n\n# load library\nrequire 'tkextlib/itcl/incr_tcl.rb'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/itk/incr_tk.rb",
    "content": "#\n#  tkextlib/itk/incr_tk.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/menuspec'\nrequire 'tkextlib/itcl.rb'\n\n# call setup script\nrequire 'tkextlib/itk.rb'\n\n#TkPackage.require('Itk', '3.2')\nTkPackage.require('Itk')\n\nmodule Tk\n  module Itk\n    include Tk\n    extend Tk\n\n    LIBRARY = TkVarAccess.new('::itk::library')\n\n    PACKAGE_NAME = 'Itk'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Itk')\n      rescue\n        ''\n      end\n    end\n\n    def self.usual(arg, *args)\n      tk_call('::itk::usual', arg, *args)\n    end\n\n    def self.usual_names\n      list(tk_call('::itk::usual'))\n    end\n\n    ############################\n\n    class Archetype < TkWindow\n      TkCommandNames = [].freeze\n      # WidgetClassName = 'Archetype'.freeze\n      # WidgetClassNames[WidgetClassName] = self\n\n      def self.to_eval\n        '::itk::' << self::WidgetClassName\n      end\n\n      def __destroy_hook__\n        Tk::Itk::Component::ComponentID_TBL.delete(self.path)\n      end\n\n      #### [incr Tk] public methods\n      def component\n        simplelist(tk_send('component'))\n      end\n\n      def component_path(name)\n        window(tk_send('component', name))\n      end\n      alias component_widget component_path\n\n      def component_invoke(name, cmd, *args)\n        window(tk_send('component', name, cmd, *args))\n      end\n\n      def component_obj(*names)\n        names = component if names.empty?\n        names.collect{|name| Tk::Itk::Component.new(self.path, name) }\n      end\n\n      #### [incr Tk] protected methods\n=begin\n      def itk_component_add(visibility, name, create_cmds, option_cmds=None)\n        args = []\n        visibility.each{|v| v = v.to_s; args << ( (v[0] == ?-)? v: \"-#{v}\" )}\n        args << '--' << name << create_cmd << option_cmds\n        tk_call('itk_component', 'add', *args)\n      end\n\n      def itk_component_delete(*names)\n        tk_call('itk_component', 'delete', *names)\n      end\n\n      def itk_initialize(keys={})\n        tk_call('itk_initialize', keys)\n      end\n\n      def itk_option_add(*args)\n        tk_call('itk_option', 'add', *args)\n      end\n\n      def itk_option_define(name, resource, klass, init, config=None)\n        tk_call('itk_option', 'define', name, resource, klass, init, config)\n      end\n      \n      def itk_option_remove(*args)\n        tk_call('itk_option', 'remove', *args)\n      end\n=end\n    end\n\n    ############################\n\n    class Toplevel < Archetype\n      TkCommandNames = ['::itk::Toplevel'].freeze\n      WidgetClassName = 'Toplevel'.freeze\n      WidgetClassNames[WidgetClassName] = self\n\n      include Wm\n      include TkMenuSpec\n\n      def __strval_optkeys\n        super() << 'title'\n      end\n      private :__strval_optkeys\n    end\n\n    ############################\n\n    class Widget < Archetype\n      TkCommandNames = ['::itk::Widget'].freeze\n      WidgetClassName = 'Widget'.freeze\n      WidgetClassNames[WidgetClassName] = self\n    end\n\n\n    ############################\n\n    class Component < TkObject\n      def __cget_cmd\n        [self.master, 'component', self.name, 'cget']\n      end\n      private :__cget_cmd\n\n      def __config_cmd\n        [self.master, 'component', self.name, 'configure']\n      end\n      private :__config_cmd\n\n      ComponentID_TBL = TkCore::INTERP.create_table\n\n      (Itk_Component_ID = ['itk:component'.freeze, '00000'.taint]).instance_eval{\n        @mutex = Mutex.new\n        def mutex; @mutex; end\n        freeze\n      }\n\n      TkCore::INTERP.init_ip_env{\n        ComponentID_TBL.mutex.synchronize{ ComponentID_TBL.clear }\n      }\n\n      def self.id2obj(master, id)\n        if master.kind_of?(TkObject)\n          master = master.path\n        else\n          master = master.to_s\n        end\n        ComponentID_TBL.mutex.synchronize{\n          if ComponentID_TBL.key?(master)\n            (ComponentID_TBL[master].key?(id))? ComponentID_TBL[master][id]: id\n          else\n            id\n          end\n        }\n      end\n\n      def self.new(master, component=nil)\n        if master.kind_of?(TkObject)\n          master = master.path\n        else\n          master = master.to_s\n        end\n\n        if component.kind_of?(Tk::Itk::Component)\n          component = component.name\n        elsif component\n          component = component.to_s\n        else\n          Itk_Component_ID.mutex.synchronize{\n            component = Itk_Component_ID.join(TkCore::INTERP._ip_id_)\n            Itk_Component_ID[1].succ!\n          }\n        end\n\n        ComponentID_TBL.mutex.synchronize{\n          if ComponentID_TBL.key?(master)\n            if ComponentID_TBL[master].key?(component)\n              return ComponentID_TBL[master][component] \n            end\n          else\n            ComponentID_TBL[master] = {}\n          end\n        }\n\n        super(master, component)\n      end\n\n      def initialize(master, component)\n        @master = master\n        @component = component\n\n        ComponentID_TBL.mutex.synchronize{\n          ComponentID_TBL[@master][@component] = self\n        }\n\n        begin\n          @widget = window(tk_call(@master, 'component', @component))\n          @path = @widget.path\n        rescue\n          @widget = nil\n          @path = nil\n        end\n      end\n\n      def path\n        unless @path\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          rescue\n            fail RuntimeError, 'component is not assigned to a widget'\n          end\n        end\n        @path\n      end\n\n      def epath\n        path()\n      end\n\n      def to_eval\n        path()\n      end\n\n      def master\n        @master\n      end\n\n      def name\n        @component\n      end\n\n      def widget\n        unless @widget\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          rescue\n            fail RuntimeError, 'component is not assigned to a widget'\n          end\n        end\n        @widget\n      end\n\n      def widget_class\n        unless @widget\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n            @widget.classname\n          rescue\n            nil\n          end\n        end\n      end\n\n      def method_missing(id, *args)\n        name = id.id2name\n\n        # try 1 : component command\n        begin\n          return tk_call(@master, 'component', @component, name, *args)\n        rescue\n        end\n\n        # try 2 : component configure\n        len = args.length\n        begin\n          case len\n          when 1\n            if name[-1] == ?=\n              return configure(name[0..-2], args[0])\n            else\n              return configure(name, args[0])\n            end\n          when 0\n            return cget(name)\n          end\n        rescue\n        end\n\n        # try 3 : widget method or widget configure\n        begin\n          unless @widget\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          end\n          @widget.__send__(id, *args)\n        rescue\n        end\n\n        # unknown method\n        super(id, *args)\n        # fail RuntimeError, \"unknown method '#{name}' for #{self.inspect}\"\n      end\n\n      def tk_send(cmd, *rest)\n        begin\n          tk_call(@master, 'component', @component, cmd, *rest)\n        rescue\n          unless @path\n            begin\n              @widget = window(tk_call(@master, 'component', @component))\n              @path = @widget.path\n            rescue\n              fail RuntimeError, 'component is not assigned to a widget'\n            end\n          end\n          tk_call(@path, cmd, *rest)\n        end\n      end\n\n      def tk_send_without_enc(cmd, *rest)\n        begin\n          tk_call_without_enc(@master, 'component', @component, cmd, *rest)\n        rescue\n          unless @path\n            begin\n              @widget = window(tk_call(@master, 'component', @component))\n              @path = @widget.path\n            rescue\n              fail RuntimeError, 'component is not assigned to a widget'\n            end\n          end\n          tk_call_without_enc(@path, cmd, *rest)\n        end\n      end\n\n      def tk_send_with_enc(cmd, *rest)\n        begin\n          tk_call_with_enc(@master, 'component', @component, cmd, *rest)\n        rescue\n          unless @path\n            begin\n              @widget = window(tk_call(@master, 'component', @component))\n              @path = @widget.path\n            rescue\n              fail RuntimeError, 'component is not assigned to a widget'\n            end\n          end\n          tk_call_with_enc(@path, cmd, *rest)\n        end\n      end\n\n      #def bind(*args)\n      #  unless @widget\n      #    begin\n      #      @widget = window(tk_call(@master, 'component', @component))\n      #      @path = @widget.path\n      #    rescue\n      #      fail RuntimeError, 'component is not assigned to a widget'\n      #    end\n      #  end\n      #  @widget.bind(*args)\n      #end\n      def bind(context, *args)\n        unless @widget\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          rescue\n            fail RuntimeError, 'component is not assigned to a widget'\n          end\n        end\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0]) || !block_given?\n          cmd = args.shift\n        else\n          cmd = Proc.new\n        end\n        @widget.bind(context, cmd, *args)\n      end\n\n      #def bind_append(*args)\n      #  unless @widget\n      #    begin\n      #      @widget = window(tk_call(@master, 'component', @component))\n      #      @path = @widget.path\n      #    rescue\n      #      fail RuntimeError, 'component is not assigned to a widget'\n      #    end\n      #  end\n      #  @widget.bind_append(*args)\n      #end\n      def bind_append(context, *args)\n        unless @widget\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          rescue\n            fail RuntimeError, 'component is not assigned to a widget'\n          end\n        end\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0]) || !block_given?\n          cmd = args.shift\n        else\n          cmd = Proc.new\n        end\n        @widget.bind_append(context, cmd, *args)\n      end\n\n      def bind_remove(*args)\n        unless @widget\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          rescue\n            fail RuntimeError, 'component is not assigned to a widget'\n          end\n        end\n        @widget.bind_remove(*args)\n      end\n\n      def bindinfo(*args)\n        unless @widget\n          begin\n            @widget = window(tk_call(@master, 'component', @component))\n            @path = @widget.path\n          rescue\n            fail RuntimeError, 'component is not assigned to a widget'\n          end\n        end\n        @widget.bindinfo(*args)\n      end\n\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/itk/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n\n\n# set [incr Tk] library directory\n\n# ENV['ITK_LIBRARY'] = '/usr/local/ActiveTcl/lib/itk3.2/'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/itk.rb",
    "content": "#\n#  [incr Tk] support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/itk/setup.rb'\n\n# load library\nrequire 'tkextlib/itk/incr_tk.rb'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/buttonbox.rb",
    "content": "#\n#  tkextlib/iwidgets/buttonbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Buttonbox < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Buttonbox\n  TkCommandNames = ['::iwidgets::buttonbox'.freeze].freeze\n  WidgetClassName = 'Buttonbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'buttoncget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'buttonconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_boolval_optkeys(id)\n    super(id) << 'defaultring'\n  end\n  private :__item_boolval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias buttoncget itemcget\n  alias buttoncget_strict itemcget_strict\n  alias buttonconfigure itemconfigure\n  alias buttonconfiginfo itemconfiginfo\n  alias current_buttonconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def add(tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'add', tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def default(idx)\n    tk_call(@path, 'default', index(idx))\n    self\n  end\n\n  def delete(idx)\n    tk_call(@path, 'delete', index(idx))\n    self\n  end\n\n  def hide(idx)\n    tk_call(@path, 'hide', index(idx))\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def invoke(idx=nil)\n    if idx\n      tk_call(@path, 'invoke', index(idx))\n    else\n      tk_call(@path, 'invoke')\n    end\n    self\n  end\n\n  def show(idx)\n    tk_call(@path, 'show', index(idx))\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/calendar.rb",
    "content": "#\n#  tkextlib/iwidgets/calendar.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Calendar < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Calendar\n  TkCommandNames = ['::iwidgets::calendar'.freeze].freeze\n  WidgetClassName = 'Calendar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() + [\n      'buttonforeground', 'outline', 'selectcolor', \n      'weekdaybackground', 'weekendbackground'\n    ]\n  end\n  private :__strval_optkeys\n\n  def __listval_optkeys\n    super() << 'days'\n  end\n  private :__listval_optkeys\n\n  def __font_optkeys\n    super() + ['currentdatefont', 'datefont', 'dayfont', 'titlefont']\n  end\n  private :__font_optkeys\n\n  ####################################\n\n  include Tk::ValidateConfigure\n\n  class CalendarCommand < TkValidateCommand\n    #class CalCmdArgs < TkUtil::CallbackSubst\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL  = [ [?d, ?s, :date], nil ]\n      PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      # array of config-option key (string or symbol)\n      ['command']\n    end\n\n    #def initialize(cmd = Proc.new, *args)\n    #  _initialize_for_cb_class(CalCmdArgs, cmd, *args)\n    #end\n  end\n\n  def __validation_class_list\n    super() << CalendarCommand\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, CalendarCommand)\n=begin\n  def command(cmd = Proc.new, args = nil)\n    if cmd.kind_of?(CalendarCommand)\n      configure('command', cmd)\n    elsif args\n      configure('command', [cmd, args])\n    else\n      configure('command', cmd)\n    end\n  end\n=end\n\n  ####################################\n\n  def get_string\n    tk_call(@path, 'get', '-string')\n  end\n  alias get get_string\n\n  def get_clicks\n    number(tk_call(@path, 'get', '-clicks'))\n  end\n\n  def select(date)\n    tk_call(@path, 'select', date)\n    self\n  end\n\n  def show(date)\n    tk_call(@path, 'show', date)\n    self\n  end\n  def show_now\n    tk_call(@path, 'show', 'now')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb",
    "content": "#\n#  tkextlib/iwidgets/canvasprintbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Canvasprintbox < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Canvasprintbox\n  TkCommandNames = ['::iwidgets::canvasprintbox'.freeze].freeze\n  WidgetClassName = 'Canvasprintbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'filename'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'stretch'\n  end\n  private :__boolval_optkeys\n\n  def get_output\n    tk_call(@path, 'getoutput')\n  end\n\n  def print\n    bool(tk_call(@path, 'print'))\n  end\n\n  def refresh\n    tk_call(@path, 'refresh')\n    self\n  end\n\n  def set_canvas(win)\n    tk_call(@path, 'setcanvas', win)\n    self\n  end\n\n  def stop\n    tk_call(@path, 'stop')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb",
    "content": "#\n#  tkextlib/iwidgets/canvasprintdialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Canvasprintdialog < Tk::Iwidgets::Dialog\n    end\n  end\nend\n\nclass Tk::Iwidgets::Canvasprintdialog\n  TkCommandNames = ['::iwidgets::canvasprintdialog'.freeze].freeze\n  WidgetClassName = 'Canvasprintdialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def get_output\n    tk_call(@path, 'getoutput')\n  end\n\n  def print\n    bool(tk_call(@path, 'print'))\n  end\n\n  def refresh\n    tk_call(@path, 'refresh')\n    self\n  end\n\n  def set_canvas(win)\n    tk_call(@path, 'setcanvas', win)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/checkbox.rb",
    "content": "#\n#  tkextlib/iwidgets/checkbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Checkbox < Tk::Iwidgets::Labeledframe\n    end\n  end\nend\n\nclass Tk::Iwidgets::Checkbox\n  TkCommandNames = ['::iwidgets::checkbox'.freeze].freeze\n  WidgetClassName = 'Checkbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'buttoncget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'buttonconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_boolval_optkeys(id)\n    super(id) << 'defaultring'\n  end\n  private :__item_boolval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias buttoncget itemcget\n  alias buttoncget_strict itemcget_strict\n  alias buttonconfigure itemconfigure\n  alias buttonconfiginfo itemconfiginfo\n  alias current_buttonconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def add(tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'add', tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def delete(idx)\n    tk_call(@path, 'delete', index(idx))\n    self\n  end\n\n  def deselect(idx)\n    tk_call(@path, 'deselect', index(idx))\n    self\n  end\n\n  def flash(idx)\n    tk_call(@path, 'flash', index(idx))\n    self\n  end\n\n  def get_tags\n    simplelist(tk_call_without_enc(@path, 'get'))\n  end\n\n  def get_objs\n    simplelist(tk_call_without_enc(@path, 'get')).collect{|id|\n      Tk::Itk::Component.id2obj(self, id)\n    }\n  end\n\n  def get(idx=nil)\n    if idx\n      bool(tk_call_without_enc(@path, 'get', index(idx)))\n    else\n      get_tags\n    end\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def select(idx)\n    tk_call(@path, 'select', index(idx))\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/combobox.rb",
    "content": "#\n#  tkextlib/iwidgets/combobox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Combobox < Tk::Iwidgets::Entryfield\n    end\n  end\nend\n\nclass Tk::Iwidgets::Combobox\n  TkCommandNames = ['::iwidgets::combobox'.freeze].freeze\n  WidgetClassName = 'Combobox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'completion' << 'dropdown' << 'editable' << 'unique'\n  end\n  private :__boolval_optkeys\n\n  def clear(component=None)\n    tk_call(@path, 'clear', component)\n    self\n  end\n\n  def delete_list(first, last=None)\n    tk_call(@path, 'delete', 'list', first, last)\n    self\n  end\n\n  def delete_entry(first, last=None)\n    tk_call(@path, 'delete', 'entry', first, last)\n    self\n  end\n\n  def get_list_contents(index)\n    tk_call(@path, 'get', index)\n  end\n\n  def insert_list(idx, *elems)\n    tk_call(@path, 'insert', 'list', idx, *elems)\n    self\n  end\n\n  def insert_entry(idx, *elems)\n    tk_call(@path, 'insert', 'entry', idx, *elems)\n    self\n  end\n\n  # listbox methods\n  def size\n    tk_send_without_enc('size').to_i\n  end\n  def see(index)\n    tk_send_without_enc('see', index)\n    self\n  end\n  def selection_anchor(index)\n    tk_send_without_enc('selection', 'anchor', index)\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send_without_enc('selection', 'clear', first, last)\n    self\n  end\n  def selection_includes(index)\n    bool(tk_send_without_enc('selection', 'includes', index))\n  end\n  def selection_set(first, last=None)\n    tk_send_without_enc('selection', 'set', first, last)\n    self\n  end\n\n  # scrolledlistbox methods\n  def get_curselection\n    tk_call(@path, 'getcurselection')\n  end\n  def justify(dir)\n    tk_call(@path, 'justify', dir)\n    self\n  end\n  def sort(*params, &b)\n    # see 'lsort' man page about params\n    if b\n      tk_call(@path, 'sort', '-command', proc(&b), *params)\n    else\n      tk_call(@path, 'sort', *params)\n    end\n    self\n  end\n  def sort_ascending\n    tk_call(@path, 'sort', 'ascending')\n    self\n  end\n  def sort_descending\n    tk_call(@path, 'sort', 'descending')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/dateentry.rb",
    "content": "#\n#  tkextlib/iwidgets/dateentry.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Dateentry < Tk::Iwidgets::Datefield\n    end\n  end\nend\n\nclass Tk::Iwidgets::Dateentry\n  TkCommandNames = ['::iwidgets::dateentry'.freeze].freeze\n  WidgetClassName = 'Dateentry'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/datefield.rb",
    "content": "#\n#  tkextlib/iwidgets/datefield.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Datefield < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Datefield\n  TkCommandNames = ['::iwidgets::datefield'.freeze].freeze\n  WidgetClassName = 'Datefield'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'gmt'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    super() << 'textfont'\n  end\n  private :__font_optkeys\n\n  def get_string\n    tk_call(@path, 'get', '-string')\n  end\n  alias get get_string\n\n  def get_clicks\n    number(tk_call(@path, 'get', '-clicks'))\n  end\n\n  def valid?\n    bool(tk_call(@path, 'isvalid'))\n  end\n  alias isvalid? valid?\n\n  def show(date=None)\n    tk_call(@path, 'show', date)\n    self\n  end\n  def show_now\n    tk_call(@path, 'show', 'now')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/dialog.rb",
    "content": "#\n#  tkextlib/iwidgets/dialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Dialog < Tk::Iwidgets::Dialogshell\n    end\n  end\nend\n\nclass Tk::Iwidgets::Dialog\n  TkCommandNames = ['::iwidgets::dialog'.freeze].freeze\n  WidgetClassName = 'Dialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/dialogshell.rb",
    "content": "#\n#  tkextlib/iwidgets/dialogshell.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Dialogshell < Tk::Iwidgets::Shell\n    end\n  end\nend\n\nclass Tk::Iwidgets::Dialogshell\n  TkCommandNames = ['::iwidgets::dialogshell'.freeze].freeze\n  WidgetClassName = 'Dialogshell'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'buttoncget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'buttonconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_boolval_optkeys(id)\n    super(id) << 'defaultring'\n  end\n  private :__item_boolval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias buttoncget itemcget\n  alias buttoncget_strict itemcget_strict\n  alias buttonconfigure itemconfigure\n  alias buttonconfiginfo itemconfiginfo\n  alias current_buttonconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def add(tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'add', tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def default(idx)\n    tk_call(@path, 'default', index(idx))\n    self\n  end\n\n  def delete(idx)\n    tk_call(@path, 'delete', index(idx))\n    self\n  end\n\n  def hide(idx)\n    tk_call(@path, 'hide', index(idx))\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def invoke(idx=nil)\n    if idx\n      tk_call(@path, 'invoke', index(idx))\n    else\n      tk_call(@path, 'invoke')\n    end\n    self\n  end\n\n  def show(idx)\n    tk_call(@path, 'show', index(idx))\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb",
    "content": "#\n#  tkextlib/iwidgets/disjointlistbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Disjointlistbox < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Disjointlistbox\n  TkCommandNames = ['::iwidgets::disjointlistbox'.freeze].freeze\n  WidgetClassName = 'Disjointlistbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'lhslabeltext' << 'rhslabeltext' << 'lhsbuttonlabel' << 'rhsbuttonlabel'\n  end\n  private :__strval_optkeys\n\n  def set_lhs(*items)\n    tk_call(@path, 'setlhs', items)\n    self\n  end\n  def set_rhs(*items)\n    tk_call(@path, 'setrhs', items)\n    self\n  end\n\n  def get_lhs\n    simplelist(tk_call(@path, 'getlhs'))\n  end\n  def get_rhs\n    simplelist(tk_call(@path, 'getrhs'))\n  end\n\n  def insert_lhs(*items)\n    tk_call(@path, 'insertlhs', items)\n    self\n  end\n  def insert_rhs(*items)\n    tk_call(@path, 'insertrhs', items)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/entryfield.rb",
    "content": "#\n#  tkextlib/iwidgets/entryfield.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Entryfield < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Entryfield\n  TkCommandNames = ['::iwidgets::entryfield'.freeze].freeze\n  WidgetClassName = 'Entryfield'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __font_optkeys\n    super() << 'textfont'\n  end\n  private :__font_optkeys\n\n  ####################################\n\n  include Tk::ValidateConfigure\n\n  class EntryfieldValidate < TkValidateCommand\n    #class CalCmdArgs < TkUtil::CallbackSubst\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL  = [ \n        [ ?c, ?s, :char ], \n        [ ?P, ?s, :post ], \n        [ ?S, ?s, :current ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n      PROC_TBL = [ \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n    end\n\n    def self._config_keys\n      ['validate', 'invalid']\n    end\n  end\n\n  def __validation_class_list\n    super() << EntryfieldValidate\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, EntryfieldValidate)\n=begin\n  def validate(cmd = Proc.new, args = nil)\n    if cmd.kind_of?(ValidateCmd)\n      configure('validate', cmd)\n    elsif args\n      configure('validate', [cmd, args])\n    else\n      configure('validate', cmd)\n    end\n  end\n\n  def invalid(cmd = Proc.new, args = nil)\n    if cmd.kind_of?(ValidateCmd)\n      configure('invalid', cmd)\n    elsif args\n      configure('invalid', [cmd, args])\n    else\n      configure('invalid', cmd)\n    end\n  end\n=end\n\n  ####################################\n\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n\n  def value\n    _fromUTF8(tk_send_without_enc('get'))\n  end\n  def value= (val)\n    tk_send_without_enc('delete', 0, 'end')\n    tk_send_without_enc('insert', 0, _get_eval_enc_str(val))\n    val\n  end\n  alias get value\n  alias set value=\n\n  def cursor=(index)\n    tk_send_without_enc('icursor', index)\n    #self\n    index\n  end\n  alias icursor cursor=\n\n  def index(index)\n    number(tk_send_without_enc('index', index))\n  end\n\n  def insert(pos,text)\n    tk_send_without_enc('insert', pos, _get_eval_enc_str(text))\n    self\n  end\n\n  def mark(pos)\n    tk_send_without_enc('scan', 'mark', pos)\n    self\n  end\n  def dragto(pos)\n    tk_send_without_enc('scan', 'dragto', pos)\n    self\n  end\n  def selection_adjust(index)\n    tk_send_without_enc('selection', 'adjust', index)\n    self\n  end\n  def selection_clear\n    tk_send_without_enc('selection', 'clear')\n    self\n  end\n  def selection_from(index)\n    tk_send_without_enc('selection', 'from', index)\n    self\n  end\n  def selection_present()\n    bool(tk_send_without_enc('selection', 'present'))\n  end\n  def selection_range(s, e)\n    tk_send_without_enc('selection', 'range', s, e)\n    self\n  end\n  def selection_to(index)\n    tk_send_without_enc('selection', 'to', index)\n    self\n  end\n\n  # based on tk/scrollable.rb\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/extbutton.rb",
    "content": "#\n#  tkextlib/iwidgets/extbutton.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Extbutton < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Extbutton\n  TkCommandNames = ['::iwidgets::extbutton'.freeze].freeze\n  WidgetClassName = 'Extbutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'bitmapforeground' << 'ringbackground'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'defaultring'\n  end\n  private :__boolval_optkeys\n\n  def invoke\n    tk_call(@path, 'invoke')\n    self\n  end\n\n  def flash\n    tk_call(@path, 'flash')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb",
    "content": "#\n#  tkextlib/iwidgets/extfileselectionbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Extfileselectionbox < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Extfileselectionbox\n  TkCommandNames = ['::iwidgets::extfileselectionbox'.freeze].freeze\n  WidgetClassName = 'Extfileselectionbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() + [\n      'dirslabel', 'fileslabel', 'filterlabel', 'mask', 'nomatchstring', \n      'selectionlabel'\n    ]\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() + ['dirson', 'fileson', 'filteron', 'selectionon']\n  end\n  private :__boolval_optkeys\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def filter\n    tk_call(@path, 'filter')\n    self\n  end\n\n  def get\n    tk_call(@path, 'get')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb",
    "content": "#\n#  tkextlib/iwidgets/extfileselectiondialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Extfileselectiondialog < Tk::Iwidgets::Dialog\n    end\n  end\nend\n\nclass Tk::Iwidgets::Extfileselectiondialog\n  TkCommandNames = ['::iwidgets::extfileselectiondialog'.freeze].freeze\n  WidgetClassName = 'Extfileselectiondialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def filter\n    tk_call(@path, 'filter')\n    self\n  end\n\n  def get\n    tk_call(@path, 'get')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/feedback.rb",
    "content": "#\n#  tkextlib/iwidgets/feedback.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Feedback < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Feedback\n  TkCommandNames = ['::iwidgets::feedback'.freeze].freeze\n  WidgetClassName = 'Feedback'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'barcolor'\n  end\n  private :__strval_optkeys\n\n  def reset\n    tk_call(@path, 'reset')\n    self\n  end\n\n  def step(inc=1)\n    tk_call(@path, 'step', inc)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb",
    "content": "#\n#  tkextlib/iwidgets/fileselectionbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Fileselectionbox < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Fileselectionbox\n  TkCommandNames = ['::iwidgets::fileselectionbox'.freeze].freeze\n  WidgetClassName = 'Fileselectionbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() + [\n      'directory', 'dirslabel', 'fileslabel', 'filterlabel', 'mask', \n      'nomatchstring', 'selectionlabel'\n    ]\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() + ['dirson', 'fileson', 'filteron', 'selectionon']\n  end\n  private :__boolval_optkeys\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def filter\n    tk_call(@path, 'filter')\n    self\n  end\n\n  def get\n    tk_call(@path, 'get')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb",
    "content": "#\n#  tkextlib/iwidgets/fileselectiondialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Fileselectiondialog < Tk::Iwidgets::Dialog\n    end\n  end\nend\n\nclass Tk::Iwidgets::Fileselectiondialog\n  TkCommandNames = ['::iwidgets::fileselectiondialog'.freeze].freeze\n  WidgetClassName = 'Fileselectiondialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def filter\n    tk_call(@path, 'filter')\n    self\n  end\n\n  def get\n    tk_call(@path, 'get')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/finddialog.rb",
    "content": "#\n#  tkextlib/iwidgets/finddialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Finddialog < Tk::Iwidgets::Dialogshell\n    end\n  end\nend\n\nclass Tk::Iwidgets::Finddialog\n  TkCommandNames = ['::iwidgets::finddialog'.freeze].freeze\n  WidgetClassName = 'Finddialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() + [\n      'patternbackground', 'patternforeground', \n      'searchbackground', 'searchforeground'\n    ]\n  end\n  private :__strval_optkeys\n\n  def __val2ruby_optkeys  # { key=>proc, ... }\n    super().update('textwidget'=>proc{|v| window(v)})\n  end\n  private :__val2ruby_optkeys\n\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def find\n    tk_call(@path, 'find')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/hierarchy.rb",
    "content": "#\n#  tkextlib/iwidgets/hierarchy.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/text'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Hierarchy < Tk::Iwidgets::Scrolledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Hierarchy\n  ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze\n  include TkTextTagConfig\n\n  TkCommandNames = ['::iwidgets::hierarchy'.freeze].freeze\n  WidgetClassName = 'Hierarchy'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include Tk::ValidateConfigure\n\n  class QueryCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL  = [ [?n, ?s, :node], nil ]\n      PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      # array of config-option key (string or symbol)\n      ['querycommand']\n    end\n  end\n\n  class IndicatorCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL  = [ \n        [ ?n, ?s, :node ], \n        [ ?s, ?b, :status ], \n        nil\n      ]\n\n      PROC_TBL = [ \n        [ ?s, TkComm.method(:string) ], \n        [ ?b, TkComm.method(:bool) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      # array of config-option key (string or symbol)\n      ['iconcommand', 'icondblcommand', 'imagedblcommand']\n    end\n  end\n\n  class IconCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL  = [ \n        [ ?n, ?s, :node ], \n        [ ?i, ?s, :icon ], \n        nil\n      ]\n      PROC_TBL = [ [ ?s, TkComm.method(:string) ], nil ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      # array of config-option key (string or symbol)\n      ['dblclickcommand', 'imagecommand', 'selectcommand']\n    end\n  end\n\n  def __validation_class_list\n    super() << QueryCommand << IndicatorCommand << IconCommand\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, QueryCommand)\n  Tk::ValidateConfigure.__def_validcmd(binding, IndicatorCommand)\n  Tk::ValidateConfigure.__def_validcmd(binding, IconCommand)\n\n  ####################################\n\n  def __boolval_optkeys\n    super() << 'alwaysquery' << 'expanded' << 'filter'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'markbackground' << 'markforeground' << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    super() << 'textfont'\n  end\n  private :__font_optkeys\n\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def collapse(node)\n    tk_call(@path, 'collapse')\n    self\n  end\n\n  def current\n    tk_call(@path, 'current')\n  end\n\n  def draw(mode=None)\n    case mode\n    when None\n      # do nothing\n    when 'now', :now\n      mode = '-now'\n    when 'eventually', :eventually\n      mode = '-eventually'\n    when String, Symbol\n      mode = mode.to_s\n      mode = '-' << mode if mode[0] != ?-\n    end\n    tk_call(@path, 'draw', mode)\n  end\n\n  def expand(node)\n    tk_call(@path, 'expand', node)\n    self\n  end\n\n  def expanded?(node)\n    bool(tk_call(@path, 'expanded', node))\n  end\n\n  def exp_state\n    list(tk_call(@path, 'expState'))\n  end\n  alias expand_state  exp_state\n  alias expanded_list exp_state\n\n  def mark_clear\n    tk_call(@path, 'mark', 'clear')\n    self\n  end\n  def mark_add(*nodes)\n    tk_call(@path, 'mark', 'add', *nodes)\n    self\n  end\n  def mark_remove(*nodes)\n    tk_call(@path, 'mark', 'remove', *nodes)\n    self\n  end\n  def mark_get\n    list(tk_call(@path, 'mark', 'get'))\n  end\n\n  def refresh(node)\n    tk_call(@path, 'refresh', node)\n    self\n  end\n\n  def prune(node)\n    tk_call(@path, 'prune', node)\n    self\n  end\n\n  def selection_clear\n    tk_call(@path, 'selection', 'clear')\n    self\n  end\n  def selection_add(*nodes)\n    tk_call(@path, 'selection', 'add', *nodes)\n    self\n  end\n  def selection_remove(*nodes)\n    tk_call(@path, 'selection', 'remove', *nodes)\n    self\n  end\n  def selection_get\n    list(tk_call(@path, 'selection', 'get'))\n  end\n\n  def toggle(node)\n    tk_call(@path, 'toggle', node)\n    self\n  end\n\n  # based on Tk::Text widget\n\n  def bbox(index)\n    list(tk_send_without_enc('bbox', _get_eval_enc_str(index)))\n  end\n\n  def compare(idx1, op, idx2)\n    bool(tk_send_without_enc('compare', _get_eval_enc_str(idx1), \n                             op, _get_eval_enc_str(idx2)))\n  end\n\n  def debug\n    bool(tk_send_without_enc('debug'))\n  end\n  def debug=(boolean)\n    tk_send_without_enc('debug', boolean)\n    #self\n    boolean\n  end\n\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n\n  def dlineinfo(index)\n    list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index)))\n  end\n\n  def get(*index)\n    _fromUTF8(tk_send_without_enc('get', *index))\n  end\n\n  def index(index)\n    tk_send_without_enc('index', _get_eval_enc_str(index))\n  end\n\n  def insert(index, chars, *tags)\n    if tags[0].kind_of? Array\n      # multiple chars-taglist argument :: str, [tag,...], str, [tag,...], ...\n      args = [chars]\n      while tags.size > 0\n        args << tags.shift.collect{|x|_get_eval_string(x)}.join(' ')  # taglist\n        args << tags.shift if tags.size > 0                           # chars\n      end\n      super(index, *args)\n    else\n      # single chars-taglist argument :: str, tag, tag, ...\n      if tags.size == 0\n        super(index, chars)\n      else\n        super(index, chars, tags.collect{|x|_get_eval_string(x)}.join(' '))\n      end\n    end\n  end\n\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n  def see(index)\n    tk_send_without_enc('see', index)\n    self\n  end\n\n  # based on tk/scrollable.rb\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\n\n  def yview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('yview'))\n    else\n      tk_send_without_enc('yview', *index)\n      self\n    end\n  end\n  def yview_moveto(*index)\n    yview('moveto', *index)\n  end\n  def yview_scroll(*index)\n    yview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb",
    "content": "#\n#  tkextlib/iwidgets/hyperhelp.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Hyperhelp < Tk::Iwidgets::Shell\n    end\n  end\nend\n\nclass Tk::Iwidgets::Hyperhelp\n  TkCommandNames = ['::iwidgets::hyperhelp'.freeze].freeze\n  WidgetClassName = 'Hyperhelp'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'helpdir'\n  end\n  private :__strval_optkeys\n\n  def __listval_optkeys\n    super() << 'topics'\n  end\n  private :__listval_optkeys\n\n  def show_topic(topic)\n    tk_call(@path, 'showtopic', topic)\n    self\n  end\n\n  def follow_link(href)\n    tk_call(@path, 'followlink', href)\n    self\n  end\n\n  def forward\n    tk_call(@path, 'forward')\n    self\n  end\n\n  def back\n    tk_call(@path, 'back')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/labeledframe.rb",
    "content": "#\n#  tkextlib/iwidgets/labeledframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Labeledframe < Tk::Itk::Archetype\n    end\n  end\nend\n\nclass Tk::Iwidgets::Labeledframe\n  TkCommandNames = ['::iwidgets::labeledframe'.freeze].freeze\n  WidgetClassName = 'Labeledframe'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'labeltext'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'labelvariable'\n  end\n  private :__tkvariable_optkeys\n\n  def __font_optkeys\n    super() << 'labelfont'\n  end\n  private :__font_optkeys\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb",
    "content": "#\n#  tkextlib/iwidgets/labeledwidget.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Labeledwidget < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Labeledwidget\n  extend TkCore\n\n  TkCommandNames = ['::iwidgets::labeledwidget'.freeze].freeze\n  WidgetClassName = 'Labeledwidget'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'labeltext'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'labelvariable'\n  end\n  private :__tkvariable_optkeys\n\n  def __font_optkeys\n    super() << 'labelfont'\n  end\n  private :__font_optkeys\n\n  def self.alignlabels(*wins)\n    tk_call('::iwidgets::Labeledwidget::alignlabels', *wins)\n  end\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/mainwindow.rb",
    "content": "#\n#  tkextlib/iwidgets/mainwindow.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Mainwindow < Tk::Iwidgets::Shell\n    end\n  end\nend\n\nclass Tk::Iwidgets::Mainwindow\n  TkCommandNames = ['::iwidgets::mainwindow'.freeze].freeze\n  WidgetClassName = 'Mainwindow'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'helpline' << 'statusline'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'menubarbackground' << 'menubarforeground' << 'toolbarforeground'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    super() << 'menubarfont' << 'toolbarfont'\n  end\n  private :__font_optkeys\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def menubar(*args)\n    unless args.empty?\n      tk_call(@path, 'menubar', *args)\n    end\n    window(tk_call(@path, 'menubar'))\n  end\n\n  def mousebar(*args)\n    unless args.empty?\n      tk_call(@path, 'mousebar', *args)\n    end\n    window(tk_call(@path, 'mousebar'))\n  end\n\n  def msgd(*args)\n    unless args.empty?\n      tk_call(@path, 'msgd', *args)\n    end\n    window(tk_call(@path, 'msgd'))\n  end\n\n  def toolbar(*args)\n    unless args.empty?\n      tk_call(@path, 'toolbar', *args)\n    end\n    window(tk_call(@path, 'toolbar'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/menubar.rb",
    "content": "#\n#  tkextlib/iwidgets/menubar.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Menubar < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Menubar\n  TkCommandNames = ['::iwidgets::menubar'.freeze].freeze\n  WidgetClassName = 'Menubar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'menubuttons'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvariable'\n  end\n  private :__tkvariable_optkeys\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'menucget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'menuconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_strval_optkeys(id)\n    super(id) << 'selectcolor'\n  end\n  private :__item_strval_optkeys\n\n  def __item_tkvariable_optkeys(id)\n    super(id) << 'helpstr'\n  end\n  private :__item_tkvariable_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias menucget itemcget\n  alias menucget_strict itemcget_strict\n  alias menuconfigure itemconfigure\n  alias menuconfiginfo itemconfiginfo\n  alias current_menuconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def __methodcall_optkeys\n    {'menubuttons'=>'menubuttons'}\n  end\n\n  def menubuttons(val = nil)\n    unless val\n      return tk_call(@path, 'cget', '-menubuttons')\n    end\n\n    tk_call(@path, 'configure', '-menubuttons', _parse_menu_spec(val))\n    self\n  end\n\n  def _parse_menu_spec(menu_spec)\n    ret = ''\n    menu_spec.each{|spec|\n      next unless spec\n\n      if spec.kind_of?(Hash)\n        args = [spec]\n        type = 'options'\n      else\n        type, *args = spec\n      end\n\n      type = type.to_s\n      case type\n      when 'options'\n        keys = args[0]\n        ary = [type]\n        ary.concat(hash_kv(keys))\n        ret << array2tk_list(ary) << \"\\n\"\n\n      when 'menubutton', 'cascade'\n        name, keys = args\n        if keys\n          ary = [type, name]\n          keys = _symbolkey2str(keys)\n          keys['menu'] = _parse_menu_spec(keys['menu']) if keys.key?('menu')\n          ary.concat(hash_kv(keys))\n          ret << array2tk_list(ary) << \"\\n\"\n        else\n          ret << array2tk_list([type, name]) << \"\\n\"\n        end\n\n      else\n        name, keys = args\n        if keys\n          ary = [type, name]\n          ary.concat(hash_kv(keys))\n          ret << array2tk_list(ary) << \"\\n\"\n        else\n          ret << array2tk_list([type, name]) << \"\\n\"\n        end\n      end\n    }\n    ret\n  end\n\n  ####################################\n\n  def add(type, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    keys = _symbolkey2str(keys)\n    keys['menu'] = _parse_menu_spec(keys['menu']) if keys.key?('menu')\n    tk_call(@path, 'add', type, tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def delete(path1, path2=nil)\n    if path2\n    else\n      tk_call(@path, 'delete', index(idx))\n    end\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, type, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    keys = _symbolkey2str(keys)\n    keys['menu'] = _parse_menu_spec(keys['menu']) if keys.key?('menu')\n    tk_call(@path, 'insert', index(idx), type, tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def invoke(idx)\n    tk_call(@path, 'invoke', index(idx))\n    self\n  end\n\n  def menupath(pat)\n    if (win = tk_call(@path, 'path', pat)) == '-1'\n      return nil\n    end\n    window(win)\n  end\n  def menupath_glob(pat)\n    if (win = tk_call(@path, 'path', '-glob', pat)) == '-1'\n      return nil\n    end\n    window(win)\n  end\n  def menupath_tclregexp(pat)\n    if (win = tk_call(@path, 'path', '-regexp', pat)) == '-1'\n      return nil\n    end\n    window(win)\n  end\n\n  def type(path)\n    tk_call(@path, 'type', path)\n  end\n\n  def yposition(path)\n    number(tk_call(@path, 'yposition', path))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/messagebox.rb",
    "content": "#\n#  tkextlib/iwidgets/messagebox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Messagebox < Tk::Iwidgets::Scrolledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Messagebox\n  TkCommandNames = ['::iwidgets::messagebox'.freeze].freeze\n  WidgetClassName = 'Messagebox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'type', 'cget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'type', 'configure', id]\n  end\n  private :__item_config_cmd\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  def __item_boolval_optkeys(id)\n    super(id) << 'bell' << 'show'\n  end\n  private :__item_boolval_optkeys\n\n  alias typecget itemcget\n  alias typecget_strict itemcget_strict\n  alias typeconfigure itemconfigure\n  alias typeconfiginfo itemconfiginfo\n  alias current_typeconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def __strval_optkeys\n    super() << 'filename' << 'savedir'\n  end\n  private :__strval_optkeys\n\n  def type_add(tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    unless tag\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'type', 'add', tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def export(file)\n    tk_call(@path, 'export', file)\n    self\n  end\n\n  def issue(string, type=None, *args)\n    tk_call(@path, 'issue', string, tagid(type), *args)\n    self\n  end\n\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/messagedialog.rb",
    "content": "#\n#  tkextlib/iwidgets/messagedialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Messagedialog < Tk::Iwidgets::Dialog\n    end\n  end\nend\n\nclass Tk::Iwidgets::Messagedialog\n  TkCommandNames = ['::iwidgets::messagedialog'.freeze].freeze\n  WidgetClassName = 'Messagedialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/notebook.rb",
    "content": "#\n#  tkextlib/iwidgets/notebook.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Notebook < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Notebook\n  TkCommandNames = ['::iwidgets::notebook'.freeze].freeze\n  WidgetClassName = 'Notebook'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'pagecget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'pageconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias pagecget itemcget\n  alias pagecget_strict itemcget_strict\n  alias pageconfigure itemconfigure\n  alias pageconfiginfo itemconfiginfo\n  alias current_pageconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def __boolval_optkeys\n    super() << 'auto'\n  end\n  private :__boolval_optkeys\n\n  def add(keys={})\n    window(tk_call(@path, 'add', *hash_kv(keys)))\n  end\n\n  def child_site_list\n    list(tk_call(@path, 'childsite'))\n  end\n\n  def child_site(idx)\n    if (new_idx = self.index(idx)) < 0\n      new_idx = tagid(idx)\n    end\n    window(tk_call(@path, 'childsite', new_idx))\n  end\n\n  def delete(idx1, idx2=nil)\n    if (new_idx1 = self.index(idx1)) < 0\n      new_idx1 = tagid(idx1)\n    end\n    if idx2\n      if (new_idx2 = self.index(idx2)) < 0\n        new_idx2 = tagid(idx2)\n      end\n      tk_call(@path, 'delete', new_idx1, new_idx2)\n    else\n      tk_call(@path, 'delete', new_idx1)\n    end\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, keys={})\n    if (new_idx = self.index(idx)) < 0\n      new_idx = tagid(idx)\n    end\n    window(tk_call(@path, 'insert', new_idx, *hash_kv(keys)))\n  end\n\n  def next\n    tk_call(@path, 'next')\n    self\n  end\n\n  def prev\n    tk_call(@path, 'prev')\n    self\n  end\n\n  def select(idx)\n    if (new_idx = self.index(idx)) < 0\n      new_idx = tagid(idx)\n    end\n    tk_call(@path, 'select', new_idx)\n    self\n  end\n\n  def scrollcommand(cmd=Proc.new)\n    configure_cmd 'scrollcommand', cmd\n    self\n  end\n  alias xscrollcommand scrollcommand\n  alias yscrollcommand scrollcommand\n\n  def xscrollbar(bar=nil)\n    if bar\n      @scrollbar = bar\n      @scrollbar.orient 'horizontal'\n      self.scrollcommand {|*arg| @scrollbar.set(*arg)}\n      @scrollbar.command {|*arg| self.xview(*arg)}\n      Tk.update  # avoid scrollbar trouble\n    end\n    @scrollbar\n  end\n  def yscrollbar(bar=nil)\n    if bar\n      @scrollbar = bar\n      @scrollbar.orient 'vertical'\n      self.scrollcommand {|*arg| @scrollbar.set(*arg)}\n      @scrollbar.command {|*arg| self.yview(*arg)}\n      Tk.update  # avoid scrollbar trouble\n    end\n    @scrollbar\n  end\n  alias scrollbar yscrollbar\n\n  def view(*idxs)\n    if idxs.size == 0\n      idx = num_or_str(tk_send_without_enc('view'))\n      if idx.kind_of?(Fixnum) && idx < 0\n        nil\n      else\n        idx\n      end\n    else\n      tk_send_without_enc('view', *idxs)\n      self\n    end\n  end\n  alias xview view\n  alias yview view\n\n  def view_moveto(*idxs)\n    view('moveto', *idxs)\n  end\n  alias xview_moveto view_moveto\n  alias yview_moveto view_moveto\n  def view_scroll(index, what='pages')\n    view('scroll', index, what)\n  end\n  alias xview_scroll view_scroll\n  alias yview_scroll view_scroll\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/optionmenu.rb",
    "content": "#\n#  tkextlib/iwidgets/optionmenu.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Optionmenu < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Optionmenu\n  TkCommandNames = ['::iwidgets::optionmenu'.freeze].freeze\n  WidgetClassName = 'Optionmenu'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'cyclicon'\n  end\n  private :__boolval_optkeys\n\n  def delete(first, last=nil)\n    if last\n      tk_call(@path, 'delete', first, last)\n    else\n      tk_call(@path, 'delete', first)\n    end\n    self\n  end\n\n  def disable(idx)\n    tk_call(@path, 'disable', idx)\n    self\n  end\n\n  def enable(idx)\n    tk_call(@path, 'enable', idx)\n    self\n  end\n\n  def get(first=nil, last=nil)\n    if last\n      simplelist(tk_call(@path, 'get', first, last))\n    elsif first\n      tk_call(@path, 'get', first)\n    else\n      tk_call(@path, 'get')\n    end\n  end\n  def get_range(first, last)\n    get(first, last)\n  end\n  def get_selected\n    get()\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', idx))\n  end\n\n  def insert(idx, *args)\n    tk_call(@path, 'insert', idx, *args)\n    self\n  end\n\n  def select(idx)\n    tk_call(@path, 'select', idx)\n    self\n  end\n\n  def sort(*params, &b)\n    # see 'lsort' man page about params\n    if b\n      tk_call(@path, 'sort', '-command', proc(&b), *params)\n    else\n      tk_call(@path, 'sort', *params)\n    end\n    self\n  end\n  def sort_ascending\n    tk_call(@path, 'sort', 'ascending')\n    self\n  end\n  def sort_descending\n    tk_call(@path, 'sort', 'descending')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/panedwindow.rb",
    "content": "#\n#  tkextlib/iwidgets/panedwindow.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Panedwindow < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Panedwindow\n  TkCommandNames = ['::iwidgets::panedwindow'.freeze].freeze\n  WidgetClassName = 'Panedwindow'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'panecget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'paneconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias panecget itemcget\n  alias panecget_strict itemcget_strict\n  alias paneconfigure itemconfigure\n  alias paneconfiginfo itemconfiginfo\n  alias current_paneconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def __boolval_optkeys\n    super() << 'showhandle'\n  end\n  private :__boolval_optkeys\n\n  def add(tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    window(tk_call(@path, 'add', tagid(tag), *hash_kv(keys)))\n    tag\n  end\n\n  def child_site_list\n    list(tk_call(@path, 'childsite'))\n  end\n\n  def child_site(idx)\n    window(tk_call(@path, 'childsite', index(idx)))\n  end\n\n  def delete(idx)\n    tk_call(@path, 'delete', index(idx))\n    self\n  end\n\n  def fraction(*percentages)\n    tk_call(@path, 'fraction', *percentages)\n    self\n  end\n\n  def hide(idx)\n    tk_call(@path, 'hide', index(idx))\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    window(tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys)))\n    tag\n  end\n\n  def invoke(idx=nil)\n    if idx\n      tk_call(@path, 'invoke', index(idx))\n    else\n      tk_call(@path, 'invoke')\n    end\n    self\n  end\n\n  def reset\n    tk_call(@path, 'reset')\n    self\n  end\n\n  def show(idx)\n    tk_call(@path, 'show', index(idx))\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/promptdialog.rb",
    "content": "#\n#  tkextlib/iwidgets/promptdialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Promptdialog < Tk::Iwidgets::Dialog\n    end\n  end\nend\n\nclass Tk::Iwidgets::Promptdialog\n  TkCommandNames = ['::iwidgets::promptdialog'.freeze].freeze\n  WidgetClassName = 'Promptdialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  # index method is not available, because it shows index of the entry field\n  def default(name)\n    tk_call(@path, 'default', tagid(name))\n    self\n  end\n\n  def hide(name)\n    tk_call(@path, 'hide', tagid(name))\n    self\n  end\n\n  def invoke(name=nil)\n    if name\n      tk_call(@path, 'invoke', tagid(name))\n    else\n      tk_call(@path, 'invoke')\n    end\n    self\n  end\n\n  def show(name)\n    tk_call(@path, 'show', tagid(name))\n    self\n  end\n\n\n  # based on Tk::Iwidgets::Entryfield\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n\n  def value\n    _fromUTF8(tk_send_without_enc('get'))\n  end\n  def value= (val)\n    tk_send_without_enc('delete', 0, 'end')\n    tk_send_without_enc('insert', 0, _get_eval_enc_str(val))\n    val\n  end\n  alias get value\n  alias set value=\n\n  def cursor=(index)\n    tk_send_without_enc('icursor', index)\n    #self\n    index\n  end\n  alias icursor cursor=\n\n  def index(idx)\n    number(tk_send_without_enc('index', idx))\n  end\n\n  def insert(pos,text)\n    tk_send_without_enc('insert', pos, _get_eval_enc_str(text))\n    self\n  end\n\n  def mark(pos)\n    tk_send_without_enc('scan', 'mark', pos)\n    self\n  end\n  def dragto(pos)\n    tk_send_without_enc('scan', 'dragto', pos)\n    self\n  end\n  def selection_adjust(index)\n    tk_send_without_enc('selection', 'adjust', index)\n    self\n  end\n  def selection_clear\n    tk_send_without_enc('selection', 'clear')\n    self\n  end\n  def selection_from(index)\n    tk_send_without_enc('selection', 'from', index)\n    self\n  end\n  def selection_present()\n    bool(tk_send_without_enc('selection', 'present'))\n  end\n  def selection_range(s, e)\n    tk_send_without_enc('selection', 'range', s, e)\n    self\n  end\n  def selection_to(index)\n    tk_send_without_enc('selection', 'to', index)\n    self\n  end\n\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/pushbutton.rb",
    "content": "#\n#  tkextlib/iwidgets/pushbutton.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Pushbutton < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Pushbutton\n  TkCommandNames = ['::iwidgets::pushbutton'.freeze].freeze\n  WidgetClassName = 'Pushbutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'defaultring'\n  end\n  private :__boolval_optkeys\n\n  def invoke\n    tk_call_without_enc(@path, 'invoke')\n    self\n  end\n\n  def flash\n    tk_call_without_enc(@path, 'flash')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/radiobox.rb",
    "content": "#\n#  tkextlib/iwidgets/radiobox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Radiobox < Tk::Iwidgets::Labeledframe\n    end\n  end\nend\n\nclass Tk::Iwidgets::Radiobox\n  TkCommandNames = ['::iwidgets::radiobox'.freeze].freeze\n  WidgetClassName = 'Radiobox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'buttoncget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'buttonconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_boolval_optkeys(id)\n    super(id) << 'defaultring'\n  end\n  private :__item_boolval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias buttoncget itemcget\n  alias buttoncget_strict itemcget_strict\n  alias buttonconfigure itemconfigure\n  alias buttonconfiginfo itemconfiginfo\n  alias current_buttonconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def add(tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'add', tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def delete(idx)\n    tk_call(@path, 'delete', index(idx))\n    self\n  end\n\n  def deselect(idx)\n    tk_call(@path, 'deselect', index(idx))\n    self\n  end\n\n  def flash(idx)\n    tk_call(@path, 'flash', index(idx))\n    self\n  end\n\n  def get_tag\n    ((tag = tk_call_without_enc(@path, 'get')).empty?)? nil: tag\n  end\n  alias get get_tag\n\n  def get_obj\n    (tag = get_tag)? Tk::Itk::Component.id2obj(self, tag): nil\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    tk_call(@path, 'insert', index(idx), tagid(tag), *hash_kv(keys))\n    tag\n  end\n\n  def select(idx)\n    tk_call(@path, 'select', index(idx))\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scopedobject.rb",
    "content": "#\n#  tkextlib/iwidgets/buttonbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scopedobject < TkObject\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scopedobject\n  TkCommandNames = ['::iwidgets::scopedobject'.freeze].freeze\n  WidgetClassName = 'Scopedobject'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def initialize(obj_name, keys={})\n    @path = tk_call(self.class::TkCommandNames[0], obj_name, *hash_kv(keys))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb",
    "content": "#\n#  tkextlib/iwidgets/scrolledcanvas.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/canvas'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scrolledcanvas < Tk::Iwidgets::Scrolledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scrolledcanvas\n  TkCommandNames = ['::iwidgets::scrolledcanvas'.freeze].freeze\n  WidgetClassName = 'Scrolledcanvas'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ################################\n\n  def __boolval_optkeys\n    super() << 'autoresize'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def initialize(*args)\n    super(*args)\n    @canvas = component_widget('canvas')\n  end\n\n  def method_missing(id, *args)\n    if @canvas.respond_to?(id)\n      @canvas.__send__(id, *args)\n    else\n      super(id, *args)\n    end\n  end\n\n  ################################\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def justify(dir)\n    tk_call(@path, 'justify', dir)\n    self\n  end\n\n  ##########################\n  include TkCanvasItemConfig\n\n  def tagid(tag)\n    if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag)\n      tag.id\n    elsif tag.kind_of?(Tk::Itk::Component)\n      tag.name\n    else\n      tag  # maybe an Array of configure paramters\n    end\n  end\n  private :tagid\n\n  # create a canvas item without creating a TkcItem object\n  def create(type, *args)\n    type.create(self, *args)\n  end\n\n  #######################\n\n  def addtag(tag, mode, *args)\n    tk_send_without_enc('addtag', tagid(tag), mode, *args)\n    self\n  end\n  def addtag_above(tagOrId, target)\n    addtag(tagOrId, 'above', tagid(target))\n  end\n  def addtag_all(tagOrId)\n    addtag(tagOrId, 'all')\n  end\n  def addtag_below(tagOrId, target)\n    addtag(tagOrId, 'below', tagid(target))\n  end\n  def addtag_closest(tagOrId, x, y, halo=None, start=None)\n    addtag(tagOrId, 'closest', x, y, halo, start)\n  end\n  def addtag_enclosed(tagOrId, x1, y1, x2, y2)\n    addtag(tagOrId, 'enclosed', x1, y1, x2, y2)\n  end\n  def addtag_overlapping(tagOrId, x1, y1, x2, y2)\n    addtag(tagOrId, 'overlapping', x1, y1, x2, y2)\n  end\n  def addtag_withtag(tagOrId, tag)\n    addtag(tagOrId, 'withtag', tagid(tag))\n  end\n\n  def bbox(tagOrId, *tags)\n    list(tk_send_without_enc('bbox', tagid(tagOrId), \n                             *tags.collect{|t| tagid(t)}))\n  end\n\n  #def itembind(tag, context, cmd=Proc.new, *args)\n  #  _bind([path, \"bind\", tagid(tag)], context, cmd, *args)\n  #  self\n  #end\n  def itembind(tag, context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([path, \"bind\", tagid(tag)], context, cmd, *args)\n    self\n  end\n\n  #def itembind_append(tag, context, cmd=Proc.new, *args)\n  #  _bind_append([path, \"bind\", tagid(tag)], context, cmd, *args)\n  #  self\n  #end\n  def itembind_append(tag, context, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([path, \"bind\", tagid(tag)], context, cmd, *args)\n    self\n  end\n\n  def itembind_remove(tag, context)\n    _bind_remove([path, \"bind\", tagid(tag)], context)\n    self\n  end\n\n  def itembindinfo(tag, context=nil)\n    _bindinfo([path, \"bind\", tagid(tag)], context)\n  end\n\n  def canvasx(screen_x, *args)\n    #tk_tcl2ruby(tk_send_without_enc('canvasx', screen_x, *args))\n    number(tk_send_without_enc('canvasx', screen_x, *args))\n  end\n  def canvasy(screen_y, *args)\n    #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args))\n    number(tk_send_without_enc('canvasy', screen_y, *args))\n  end\n\n  def coords(tag, *args)\n    if args == []\n      tk_split_list(tk_send_without_enc('coords', tagid(tag)))\n    else\n      tk_send_without_enc('coords', tagid(tag), *(args.flatten))\n      self\n    end\n  end\n\n  def dchars(tag, first, last=None)\n    tk_send_without_enc('dchars', tagid(tag), \n                        _get_eval_enc_str(first), _get_eval_enc_str(last))\n    self\n  end\n\n  def delete(*args)\n    tbl = nil\n    TkcItem::CItemID_TBL.mutex.synchronize{\n      tbl = TkcItem::CItemID_TBL[self.path]\n    }\n    if tbl\n      find('withtag', *args).each{|item| \n        if item.kind_of?(TkcItem)\n          TkcItem::CItemID_TBL.mutex.synchronize{\n            tbl.delete(item.id)\n          }\n        end\n      }\n    end\n    tk_send_without_enc('delete', *args.collect{|t| tagid(t)})\n    self\n  end\n  alias remove delete\n\n  def dtag(tag, tag_to_del=None)\n    tk_send_without_enc('dtag', tagid(tag), tag_to_del)\n    self\n  end\n\n  def find(mode, *args)\n    list(tk_send_without_enc('find', mode, *args)).collect!{|id| \n      TkcItem.id2obj(self, id)\n    }\n  end\n  def find_above(target)\n    find('above', tagid(target))\n  end\n  def find_all\n    find('all')\n  end\n  def find_below(target)\n    find('below', tagid(target))\n  end\n  def find_closest(x, y, halo=None, start=None)\n    find('closest', x, y, halo, start)\n  end\n  def find_enclosed(x1, y1, x2, y2)\n    find('enclosed', x1, y1, x2, y2)\n  end\n  def find_overlapping(x1, y1, x2, y2)\n    find('overlapping', x1, y1, x2, y2)\n  end\n  def find_withtag(tag)\n    find('withtag', tag)\n  end\n\n  def itemfocus(tagOrId=nil)\n    if tagOrId\n      tk_send_without_enc('focus', tagid(tagOrId))\n      self\n    else\n      ret = tk_send_without_enc('focus')\n      if ret == \"\"\n        nil\n      else\n        TkcItem.id2obj(self, ret)\n      end\n    end\n  end\n\n  def gettags(tagOrId)\n    list(tk_send_without_enc('gettags', tagid(tagOrId))).collect{|tag|\n      TkcTag.id2obj(self, tag)\n    }\n  end\n\n  def icursor(tagOrId, index)\n    tk_send_without_enc('icursor', tagid(tagOrId), index)\n    self\n  end\n\n  def index(tagOrId, idx)\n    number(tk_send_without_enc('index', tagid(tagOrId), idx))\n  end\n\n  def insert(tagOrId, index, string)\n    tk_send_without_enc('insert', tagid(tagOrId), index, \n                        _get_eval_enc_str(string))\n    self\n  end\n\n  def lower(tag, below=nil)\n    if below\n      tk_send_without_enc('lower', tagid(tag), tagid(below))\n    else\n      tk_send_without_enc('lower', tagid(tag))\n    end\n    self\n  end\n\n  def move(tag, x, y)\n    tk_send_without_enc('move', tagid(tag), x, y)\n    self\n  end\n\n  def postscript(keys)\n    tk_send(\"postscript\", *hash_kv(keys))\n  end\n\n  def raise(tag, above=nil)\n    if above\n      tk_send_without_enc('raise', tagid(tag), tagid(above))\n    else\n      tk_send_without_enc('raise', tagid(tag))\n    end\n    self\n  end\n\n  def scale(tag, x, y, xs, ys)\n    tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)\n    self\n  end\n\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n\n  def select(mode, *args)\n    r = tk_send_without_enc('select', mode, *args)\n    (mode == 'item')? TkcItem.id2obj(self, r): self\n  end\n  def select_adjust(tagOrId, index)\n    select('adjust', tagid(tagOrId), index)\n  end\n  def select_clear\n    select('clear')\n  end\n  def select_from(tagOrId, index)\n    select('from', tagid(tagOrId), index)\n  end\n  def select_item\n    select('item')\n  end\n  def select_to(tagOrId, index)\n    select('to', tagid(tagOrId), index)\n  end\n\n  def itemtype(tag)\n    TkcItem.type2class(tk_send('type', tagid(tag)))\n  end\n\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\n\n  def yview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('yview'))\n    else\n      tk_send_without_enc('yview', *index)\n      self\n    end\n  end\n  def yview_moveto(*index)\n    yview('moveto', *index)\n  end\n  def yview_scroll(*index)\n    yview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb",
    "content": "#\n#  tkextlib/iwidgets/scrolledframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scrolledframe < Tk::Iwidgets::Scrolledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scrolledframe\n  TkCommandNames = ['::iwidgets::scrolledframe'.freeze].freeze\n  WidgetClassName = 'Scrolledframe'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def justify(dir)\n    tk_call(@path, 'justify', dir)\n    self\n  end\n\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\n\n  def yview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('yview'))\n    else\n      tk_send_without_enc('yview', *index)\n      self\n    end\n  end\n  def yview_moveto(*index)\n    yview('moveto', *index)\n  end\n  def yview_scroll(*index)\n    yview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb",
    "content": "#\n#  tkextlib/iwidgets/scrolledhtml.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scrolledhtml < Tk::Iwidgets::Scrolledtext\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scrolledhtml\n  TkCommandNames = ['::iwidgets::scrolledhtml'.freeze].freeze\n  WidgetClassName = 'Scrolledhtml'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'update'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'fontname' << 'link' << 'alink' << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    super() << 'fixedfont'\n  end\n  private :__font_optkeys\n\n  def import(href)\n    tk_call(@path, 'import', href)\n    self\n  end\n\n  def import_link(href)\n    tk_call(@path, 'import', '-link', href)\n    self\n  end\n\n  def pwd\n    tk_call(@path, 'pwd')\n  end\n\n  def render(htmltext, workdir=None)\n    tk_call(@path, 'render', htmltext, workdir)\n    self\n  end\n\n  def title\n    tk_call(@path, 'title')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb",
    "content": "#\n#  tkextlib/iwidgets/scrolledlistbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/listbox'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scrolledlistbox < Tk::Iwidgets::Scrolledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scrolledlistbox\n  TkCommandNames = ['::iwidgets::scrolledlistbox'.freeze].freeze\n  WidgetClassName = 'Scrolledlistbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'listvariable'\n  end\n  private :__tkvariable_optkeys\n\n  def __font_optkeys\n    super() << 'textfont'\n  end\n  private :__font_optkeys\n\n  ################################\n\n  def initialize(*args)\n    super(*args)\n    @listbox = component_widget('listbox')\n  end\n\n  def method_missing(id, *args)\n    if @listbox.respond_to?(id)\n      @listbox.__send__(id, *args)\n    else\n      super(id, *args)\n    end\n  end\n\n  ################################\n\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def get_curselection\n    tk_call(@path, 'getcurselection')\n  end\n\n  def justify(dir)\n    tk_call(@path, 'justify', dir)\n    self\n  end\n\n  def selected_item_count\n    number(tk_call(@path, 'selecteditemcount'))\n  end\n\n  def sort(*params, &b)\n    # see 'lsort' man page about params\n    if b\n      tk_call(@path, 'sort', '-command', proc(&b), *params)\n    else\n      tk_call(@path, 'sort', *params)\n    end\n    self\n  end\n  def sort_ascending\n    tk_call(@path, 'sort', 'ascending')\n    self\n  end\n  def sort_descending\n    tk_call(@path, 'sort', 'descending')\n    self\n  end\n\n  #####################################\n\n  def bbox(index)\n    list(tk_send_without_enc('bbox', index))\n  end\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n  def get(*index)\n    _fromUTF8(tk_send_without_enc('get', *index))\n  end\n  def insert(index, *args)\n    tk_send('insert', index, *args)\n    self\n  end\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n  def see(index)\n    tk_send_without_enc('see', index)\n    self\n  end\n\n  #####################################\n\n  include TkListItemConfig\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::Itk::Component)\n      tag.name\n    else\n      super(tag)\n    end\n  end\n  private :tagid\n\n  #####################################\n\n  def activate(y)\n    tk_send_without_enc('activate', y)\n    self\n  end\n  def curselection\n    list(tk_send_without_enc('curselection'))\n  end\n  def get(first, last=nil)\n    if last\n      # tk_split_simplelist(_fromUTF8(tk_send_without_enc('get', first, last)))\n      tk_split_simplelist(tk_send_without_enc('get', first, last), \n                          false, true)\n    else\n      _fromUTF8(tk_send_without_enc('get', first))\n    end\n  end\n  def nearest(y)\n    tk_send_without_enc('nearest', y).to_i\n  end\n  def size\n    tk_send_without_enc('size').to_i\n  end\n  def selection_anchor(index)\n    tk_send_without_enc('selection', 'anchor', index)\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send_without_enc('selection', 'clear', first, last)\n    self\n  end\n  def selection_includes(index)\n    bool(tk_send_without_enc('selection', 'includes', index))\n  end\n  def selection_set(first, last=None)\n    tk_send_without_enc('selection', 'set', first, last)\n    self\n  end\n\n  def index(idx)\n    tk_send_without_enc('index', idx).to_i\n  end\n\n  #####################################\n\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\n\n  def yview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('yview'))\n    else\n      tk_send_without_enc('yview', *index)\n      self\n    end\n  end\n  def yview_moveto(*index)\n    yview('moveto', *index)\n  end\n  def yview_scroll(*index)\n    yview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb",
    "content": "#\n#  tkextlib/iwidgets/scrolledtext.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/text'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scrolledtext < Tk::Iwidgets::Scrolledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scrolledtext\n  TkCommandNames = ['::iwidgets::scrolledtext'.freeze].freeze\n  WidgetClassName = 'Scrolledtext'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    super() << 'textfont'\n  end\n  private :__font_optkeys\n\n  ################################\n\n  def initialize(*args)\n    super(*args)\n    @text = component_widget('text')\n  end\n\n  def method_missing(id, *args)\n    if @text.respond_to?(id)\n      @text.__send__(id, *args)\n    else\n      super(id, *args)\n    end\n  end\n\n  ################################\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def clear\n    tk_call(@path, 'clear')\n    self\n  end\n\n  def import(file, idx=nil)\n    if idx\n      tk_call(@path, 'import', file, index(idx))\n    else\n      tk_call(@path, 'import', file)\n    end\n    self\n  end\n\n  def export(file)\n    tk_call(@path, 'export', file)\n    self\n  end\n\n  #####################################\n\n  include TkTextTagConfig\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::Itk::Component)\n      tag.name\n    else\n      super(tag)\n    end\n  end\n  private :tagid\n\n  def bbox(index)\n    list(tk_send('bbox', index))\n  end\n  def compare(idx1, op, idx2)\n    bool(tk_send_without_enc('compare', _get_eval_enc_str(idx1), \n                             op, _get_eval_enc_str(idx2)))\n  end\n\n  def debug\n    bool(tk_send_without_enc('debug'))\n  end\n  def debug=(boolean)\n    tk_send_without_enc('debug', boolean)\n    #self\n    boolean\n  end\n\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n\n  def dlineinfo(index)\n    list(tk_send_without_enc('dlineinfo', _get_eval_enc_str(index)))\n  end\n\n  def get(*index)\n    _fromUTF8(tk_send_without_enc('get', *index))\n  end\n  def get_displaychars(*index)\n    # Tk8.5 feature\n    get('-displaychars', *index)\n  end\n\n  def image_cget_strict(index, slot)\n    case slot.to_s\n    when 'text', 'label', 'show', 'data', 'file'\n      _fromUTF8(tk_send_without_enc('image', 'cget', \n                                    _get_eval_enc_str(index), \"-#{slot}\"))\n    else\n      tk_tcl2ruby(_fromUTF8(tk_send_without_enc('image', 'cget', \n                                                _get_eval_enc_str(index), \n                                                \"-#{slot}\")))\n    end\n  end\n  def image_cget(index, slot)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      image_cget_strict(index, slot)\n    else\n      begin\n        image_cget_strict(index, slot)\n      rescue => e\n        begin\n          if current_image_configinfo.has_key?(slot.to_s)\n            # error on known option\n            fail e\n          else\n            # unknown option\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n\n  def image_configure(index, slot, value=None)\n    if slot.kind_of? Hash\n      _fromUTF8(tk_send_without_enc('image', 'configure', \n                                    _get_eval_enc_str(index), \n                                    *hash_kv(slot, true)))\n    else\n      _fromUTF8(tk_send_without_enc('image', 'configure', \n                                    _get_eval_enc_str(index), \n                                    \"-#{slot}\", \n                                    _get_eval_enc_str(value)))\n    end\n    self\n  end\n\n  def image_configinfo(index, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        case slot.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), false, true)\n        else\n          #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), 0, false, true)\n        end\n        conf[0] = conf[0][1..-1]\n        conf\n      else\n        #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).collect{|conflist|\n        #  conf = tk_split_simplelist(conflist)\n        tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).collect{|conflist|\n          conf = tk_split_simplelist(conflist, false, true)\n          conf[0] = conf[0][1..-1]\n          case conf[0]\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n            if conf[4]\n              if conf[4].index('{')\n                conf[4] = tk_split_list(conf[4]) \n              else\n                conf[4] = tk_tcl2ruby(conf[4]) \n              end\n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        case slot.to_s\n        when 'text', 'label', 'show', 'data', 'file'\n          #conf = tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), false, true)\n        else\n          #conf = tk_split_list(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\")))\n          conf = tk_split_list(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index), \"-#{slot}\"), 0, false, true)\n        end\n        key = conf.shift[1..-1]\n        { key => conf }\n      else\n        ret = {}\n        #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)))).each{|conflist|\n        #  conf = tk_split_simplelist(conflist)\n        tk_split_simplelist(tk_send_without_enc('image', 'configure', _get_eval_enc_str(index)), false, false).each{|conflist|\n          conf = tk_split_simplelist(conflist, false, true)\n          key = conf.shift[1..-1]\n          case key\n          when 'text', 'label', 'show', 'data', 'file'\n          else\n            if conf[2]\n              if conf[2].index('{')\n                conf[2] = tk_split_list(conf[2]) \n              else\n                conf[2] = tk_tcl2ruby(conf[2]) \n              end\n            end\n            if conf[3]\n              if conf[3].index('{')\n                conf[3] = tk_split_list(conf[3]) \n              else\n                conf[3] = tk_tcl2ruby(conf[3]) \n              end\n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        ret\n      end\n    end\n  end\n\n  def current_image_configinfo(index, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        conf = image_configinfo(index, slot)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        image_configinfo(index).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      image_configinfo(index, slot).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n\n  def image_names\n    #tk_split_simplelist(_fromUTF8(tk_send_without_enc('image', 'names'))).collect{|elt|\n    tk_split_simplelist(tk_send_without_enc('image', 'names'), false, true).collect{|elt|\n      tagid2obj(elt)\n    }\n  end\n\n  def index(idx)\n    tk_send_without_enc('index', _get_eval_enc_str(idx))\n  end\n\n  def insert(index, *args)\n    tk_send('insert', index, *args)\n    self\n  end\n\n  def mark_names\n    #tk_split_simplelist(_fromUTF8(tk_send_without_enc('mark', 'names'))).collect{|elt|\n    tk_split_simplelist(tk_send_without_enc('mark', 'names'), false, true).collect{|elt|\n      tagid2obj(elt)\n    }\n  end\n\n  def mark_gravity(mark, direction=nil)\n    if direction\n      tk_send_without_enc('mark', 'gravity', \n                          _get_eval_enc_str(mark), direction)\n      self\n    else\n      tk_send_without_enc('mark', 'gravity', _get_eval_enc_str(mark))\n    end\n  end\n\n  def mark_set(mark, index)\n    tk_send_without_enc('mark', 'set', _get_eval_enc_str(mark), \n                        _get_eval_enc_str(index))\n    self\n  end\n  alias set_mark mark_set\n\n  def mark_unset(*marks)\n    tk_send_without_enc('mark', 'unset', \n                        *(marks.collect{|mark| _get_eval_enc_str(mark)}))\n    self\n  end\n  alias unset_mark mark_unset\n\n  def mark_next(index)\n    tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'next', \n                                            _get_eval_enc_str(index))))\n  end\n  alias next_mark mark_next\n\n  def mark_previous(index)\n    tagid2obj(_fromUTF8(tk_send_without_enc('mark', 'previous', \n                                            _get_eval_enc_str(index))))\n  end\n  alias previous_mark mark_previous\n\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n\n\n  def _ktext_length(txt)\n    if TkCore::WITH_ENCODING ### Ruby 1.9 !!!!!!!!!!!!!\n      return txt.length\n    end\n    ###########################\n\n    if $KCODE !~ /n/i\n      return txt.gsub(/[^\\Wa-zA-Z_\\d]/, ' ').length\n    end\n\n    # $KCODE == 'NONE'\n    if JAPANIZED_TK\n      tk_call_without_enc('kstring', 'length', \n                          _get_eval_enc_str(txt)).to_i\n    else\n      begin\n        tk_call_without_enc('encoding', 'convertto', 'ascii', \n                            _get_eval_enc_str(txt)).length\n      rescue StandardError, NameError\n        # sorry, I have no plan\n        txt.length\n      end\n    end\n  end\n  private :_ktext_length\n\n  def tksearch(*args)\n    # call 'search' subcommand of text widget\n    #   args ::= [<array_of_opts>] <pattern> <start_index> [<stop_index>]\n    # If <pattern> is regexp, then it must be a regular expression of Tcl\n    if args[0].kind_of?(Array)\n      opts = args.shift.collect{|opt| '-' + opt.to_s }\n    else\n      opts = []\n    end\n\n    opts << '--'\n\n    ret = tk_send('search', *(opts + args))\n    if ret == \"\"\n      nil\n    else\n      ret\n    end\n  end\n\n  def tksearch_with_count(*args)\n    # call 'search' subcommand of text widget\n    #   args ::= [<array_of_opts>] <var> <pattern> <start_index> [<stop_index>]\n    # If <pattern> is regexp, then it must be a regular expression of Tcl\n    if args[0].kind_of?(Array)\n      opts = args.shift.collect{|opt| '-' + opt.to_s }\n    else\n      opts = []\n    end\n\n    opts << '-count' << args.shift << '--'\n\n    ret = tk_send('search', *(opts + args))\n    if ret == \"\"\n      nil\n    else\n      ret\n    end\n  end\n\n  def search_with_length(pat,start,stop=None)\n    pat = pat.chr if pat.kind_of? Integer\n    if stop != None\n      return [\"\", 0] if compare(start,'>=',stop)\n      txt = get(start,stop)\n      if (pos = txt.index(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of? String\n          #return [index(start + \" + #{pos} chars\"), pat.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(pat), pat.dup]\n        else\n          #return [index(start + \" + #{pos} chars\"), $&.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(match), match]\n        end\n      else\n        return [\"\", 0]\n      end\n    else\n      txt = get(start,'end - 1 char')\n      if (pos = txt.index(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of? String\n          #return [index(start + \" + #{pos} chars\"), pat.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(pat), pat.dup]\n        else\n          #return [index(start + \" + #{pos} chars\"), $&.split('').length]\n          return [index(start + \" + #{pos} chars\"), \n                  _ktext_length(match), match]\n        end\n      else\n        txt = get('1.0','end - 1 char')\n        if (pos = txt.index(pat))\n          match = $&\n          #pos = txt[0..(pos-1)].split('').length if pos > 0\n          pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n          if pat.kind_of? String\n            #return [index(\"1.0 + #{pos} chars\"), pat.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), \n                    _ktext_length(pat), pat.dup]\n          else\n            #return [index(\"1.0 + #{pos} chars\"), $&.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), _ktext_length(match), match]\n          end\n        else\n          return [\"\", 0]\n        end\n      end\n    end\n  end\n\n  def search(pat,start,stop=None)\n    search_with_length(pat,start,stop)[0]\n  end\n\n  def rsearch_with_length(pat,start,stop=None)\n    pat = pat.chr if pat.kind_of? Integer\n    if stop != None\n      return [\"\", 0] if compare(start,'<=',stop)\n      txt = get(stop,start)\n      if (pos = txt.rindex(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of? String\n          #return [index(stop + \" + #{pos} chars\"), pat.split('').length]\n          return [index(stop + \" + #{pos} chars\"), _ktext_length(pat), pat.dup]\n        else\n          #return [index(stop + \" + #{pos} chars\"), $&.split('').length]\n          return [index(stop + \" + #{pos} chars\"), _ktext_length(match), match]\n        end\n      else\n        return [\"\", 0]\n      end\n    else\n      txt = get('1.0',start)\n      if (pos = txt.rindex(pat))\n        match = $&\n        #pos = txt[0..(pos-1)].split('').length if pos > 0\n        pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n        if pat.kind_of? String\n          #return [index(\"1.0 + #{pos} chars\"), pat.split('').length]\n          return [index(\"1.0 + #{pos} chars\"), _ktext_length(pat), pat.dup]\n        else\n          #return [index(\"1.0 + #{pos} chars\"), $&.split('').length]\n          return [index(\"1.0 + #{pos} chars\"), _ktext_length(match), match]\n        end\n      else\n        txt = get('1.0','end - 1 char')\n        if (pos = txt.rindex(pat))\n          match = $&\n          #pos = txt[0..(pos-1)].split('').length if pos > 0\n          pos = _ktext_length(txt[0..(pos-1)]) if pos > 0\n          if pat.kind_of? String\n            #return [index(\"1.0 + #{pos} chars\"), pat.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), _ktext_length(pat), pat.dup]\n          else\n            #return [index(\"1.0 + #{pos} chars\"), $&.split('').length]\n            return [index(\"1.0 + #{pos} chars\"), _ktext_length(match), match]\n          end\n        else\n          return [\"\", 0]\n        end\n      end\n    end\n  end\n\n  def rsearch(pat,start,stop=None)\n    rsearch_with_length(pat,start,stop)[0]\n  end\n\n  def see(index)\n    tk_send_without_enc('see', index)\n    self\n  end\n\n  ###############################\n\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\n\n  def yview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('yview'))\n    else\n      tk_send_without_enc('yview', *index)\n      self\n    end\n  end\n  def yview_moveto(*index)\n    yview('moveto', *index)\n  end\n  def yview_scroll(*index)\n    yview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb",
    "content": "#\n#  tkextlib/iwidgets/scrolledwidget.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Scrolledwidget < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Scrolledwidget\n  TkCommandNames = ['::iwidgets::scrolledwidget'.freeze].freeze\n  WidgetClassName = 'Scrolledwidget'.freeze\n  WidgetClassNames[WidgetClassName] = self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/selectionbox.rb",
    "content": "#\n#  tkextlib/iwidgets/selectionbox.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Selectionbox < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Selectionbox\n  TkCommandNames = ['::iwidgets::selectionbox'.freeze].freeze\n  WidgetClassName = 'Selectionbox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'itemson' << 'selectionon'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'itemslabel' << 'selectionlabel'\n  end\n  private :__strval_optkeys\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def clear_items\n    tk_call(@path, 'clear', 'items')\n    self\n  end\n\n  def clear_selection\n    tk_call(@path, 'clear', 'selection')\n    self\n  end\n\n  def get\n    tk_call(@path, 'get')\n  end\n\n  def insert_items(idx, *args)\n    tk_call(@path, 'insert', 'items', idx, *args)\n  end\n\n  def insert_selection(pos, text)\n    tk_call(@path, 'insert', 'selection', pos, text)\n  end\n\n  def select_item\n    tk_call(@path, 'selectitem')\n    self\n  end\n\n  # based on Tk::Listbox ( and TkTextWin )\n  def curselection\n    list(tk_send_without_enc('curselection'))\n  end\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n  def index(idx)\n    tk_send_without_enc('index', idx).to_i\n  end\n  def nearest(y)\n    tk_send_without_enc('nearest', y).to_i\n  end\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n  def selection_anchor(index)\n    tk_send_without_enc('selection', 'anchor', index)\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send_without_enc('selection', 'clear', first, last)\n    self\n  end\n  def selection_includes(index)\n    bool(tk_send_without_enc('selection', 'includes', index))\n  end\n  def selection_set(first, last=None)\n    tk_send_without_enc('selection', 'set', first, last)\n    self\n  end\n  def size\n    tk_send_without_enc('size').to_i\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb",
    "content": "#\n#  tkextlib/iwidgets/selectiondialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Selectiondialog < Tk::Iwidgets::Dialog\n    end\n  end\nend\n\nclass Tk::Iwidgets::Selectiondialog\n  TkCommandNames = ['::iwidgets::selectiondialog'.freeze].freeze\n  WidgetClassName = 'Selectiondialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def clear_items\n    tk_call(@path, 'clear', 'items')\n    self\n  end\n\n  def clear_selection\n    tk_call(@path, 'clear', 'selection')\n    self\n  end\n\n  def get\n    tk_call(@path, 'get')\n  end\n\n  def insert_items(idx, *args)\n    tk_call(@path, 'insert', 'items', idx, *args)\n  end\n\n  def insert_selection(pos, text)\n    tk_call(@path, 'insert', 'selection', pos, text)\n  end\n\n  def select_item\n    tk_call(@path, 'selectitem')\n    self\n  end\n\n  # based on Tk::Listbox ( and TkTextWin )\n  def curselection\n    list(tk_send_without_enc('curselection'))\n  end\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n  def index(idx)\n    tk_send_without_enc('index', idx).to_i\n  end\n  def nearest(y)\n    tk_send_without_enc('nearest', y).to_i\n  end\n  def scan_mark(x, y)\n    tk_send_without_enc('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send_without_enc('scan', 'dragto', x, y)\n    self\n  end\n  def selection_anchor(index)\n    tk_send_without_enc('selection', 'anchor', index)\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send_without_enc('selection', 'clear', first, last)\n    self\n  end\n  def selection_includes(index)\n    bool(tk_send_without_enc('selection', 'includes', index))\n  end\n  def selection_set(first, last=None)\n    tk_send_without_enc('selection', 'set', first, last)\n    self\n  end\n  def size\n    tk_send_without_enc('size').to_i\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/shell.rb",
    "content": "#\n#  tkextlib/iwidgets/shell.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Shell < Tk::Itk::Toplevel\n    end\n  end\nend\n\nclass Tk::Iwidgets::Shell\n  TkCommandNames = ['::iwidgets::shell'.freeze].freeze\n  WidgetClassName = 'Shell'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def activate\n    tk_call(@path, 'activate')  # may return val of deactibate method\n  end\n\n  def center(win=None)\n    tk_call(@path, 'center', win)\n    self\n  end\n\n  def child_site\n    window(tk_call(@path, 'childsite'))\n  end\n\n  def deactivate(val=None)\n    tk_call(@path, 'deactivate', val)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/spindate.rb",
    "content": "#\n#  tkextlib/iwidgets/spindate.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Spindate < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Spindate\n  TkCommandNames = ['::iwidgets::spindate'.freeze].freeze\n  WidgetClassName = 'Spindate'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'dayon' << 'monthon' << 'yearon'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'daylabel' << 'monthformat' << 'monthlabel' << 'yearlabel'\n  end\n  private :__strval_optkeys\n\n  def get_string\n    tk_call(@path, 'get', '-string')\n  end\n  alias get get_string\n\n  def get_clicks\n    number(tk_call(@path, 'get', '-clicks'))\n  end\n\n  def show(date=None)\n    tk_call(@path, 'show', date)\n    self\n  end\n  def show_now\n    tk_call(@path, 'show', 'now')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/spinint.rb",
    "content": "#\n#  tkextlib/iwidgets/spinint.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Spinint < Tk::Iwidgets::Spinner\n    end\n  end\nend\n\nclass Tk::Iwidgets::Spinint\n  TkCommandNames = ['::iwidgets::spinint'.freeze].freeze\n  WidgetClassName = 'Spinint'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'wrap'\n  end\n  private :__boolval_optkeys\n\n  def __numlistval_optkeys\n    super() << 'range'\n  end\n  private :__numlistval_optkeys\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/spinner.rb",
    "content": "#\n#  tkextlib/iwidgets/spinner.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Spinner < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Spinner\n  TkCommandNames = ['::iwidgets::spinner'.freeze].freeze\n  WidgetClassName = 'Spinner'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include Tk::ValidateConfigure\n\n  class EntryfieldValidate < TkValidateCommand\n    #class CalCmdArgs < TkUtil::CallbackSubst\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL  = [ \n        [ ?c, ?s, :char ], \n        [ ?P, ?s, :post ], \n        [ ?S, ?s, :current ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n      PROC_TBL = [ \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n    end\n\n    def self._config_keys\n      ['validate', 'invalid']\n    end\n  end\n\n  def __validation_class_list\n    super() << EntryfieldValidate\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, EntryfieldValidate)\n\n  ####################################\n\n  def up\n    tk_call_without_enc(@path, 'up')\n    self\n  end\n\n  def down\n    tk_call_without_enc(@path, 'down')\n    self\n  end\n\n  def clear\n    tk_call_without_enc(@path, 'clear')\n    self\n  end\n\n  def delete(first, last=None)\n    tk_send_without_enc('delete', first, last)\n    self\n  end\n\n  def value\n    _fromUTF8(tk_send_without_enc('get'))\n  end\n  def value= (val)\n    tk_send_without_enc('delete', 0, 'end')\n    tk_send_without_enc('insert', 0, _get_eval_enc_str(val))\n    val\n  end\n  alias get value\n  alias set value=\n\n  def cursor=(index)\n    tk_send_without_enc('icursor', index)\n    #self\n    index\n  end\n  alias icursor cursor=\n\n  def index(idx)\n    number(tk_send_without_enc('index', idx))\n  end\n\n  def insert(pos,text)\n    tk_send_without_enc('insert', pos, _get_eval_enc_str(text))\n    self\n  end\n\n  def mark(pos)\n    tk_send_without_enc('scan', 'mark', pos)\n    self\n  end\n  def dragto(pos)\n    tk_send_without_enc('scan', 'dragto', pos)\n    self\n  end\n  def selection_adjust(index)\n    tk_send_without_enc('selection', 'adjust', index)\n    self\n  end\n  def selection_clear\n    tk_send_without_enc('selection', 'clear')\n    self\n  end\n  def selection_from(index)\n    tk_send_without_enc('selection', 'from', index)\n    self\n  end\n  def selection_present()\n    bool(tk_send_without_enc('selection', 'present'))\n  end\n  def selection_range(s, e)\n    tk_send_without_enc('selection', 'range', s, e)\n    self\n  end\n  def selection_to(index)\n    tk_send_without_enc('selection', 'to', index)\n    self\n  end\n\n  # based on tk/scrollable.rb\n  def xview(*index)\n    if index.size == 0\n      list(tk_send_without_enc('xview'))\n    else\n      tk_send_without_enc('xview', *index)\n      self\n    end\n  end\n  def xview_moveto(*index)\n    xview('moveto', *index)\n  end\n  def xview_scroll(*index)\n    xview('scroll', *index)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/spintime.rb",
    "content": "#\n#  tkextlib/iwidgets/spintime.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Spintime < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Spintime\n  TkCommandNames = ['::iwidgets::spintime'.freeze].freeze\n  WidgetClassName = 'Spintime'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'houron' << 'militaryon' << 'minutelabel' << 'secondlabel'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'hourlabel' << 'minuteon' << 'secondon'\n  end\n  private :__strval_optkeys\n\n  def get_string\n    tk_call(@path, 'get', '-string')\n  end\n  alias get get_string\n\n  def get_clicks\n    number(tk_call(@path, 'get', '-clicks'))\n  end\n\n  def show(date=None)\n    tk_call(@path, 'show', date)\n    self\n  end\n  def show_now\n    tk_call(@path, 'show', 'now')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb",
    "content": "#\n#  tkextlib/iwidgets/tabnotebook.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Tabnotebook < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Tabnotebook\n  TkCommandNames = ['::iwidgets::tabnotebook'.freeze].freeze\n  WidgetClassName = 'Tabnotebook'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'pagecget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'pageconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def __item_strval_optkeys(id)\n    super(id) << 'tabbackground' << 'tabforeground'\n  end\n  private :__item_strval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias pagecget itemcget\n  alias pagecget_strict itemcget_strict\n  alias pageconfigure itemconfigure\n  alias pageconfiginfo itemconfiginfo\n  alias current_pageconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def __boolval_optkeys\n    super() << 'auto' << 'equaltabs' << 'raiseselect' << 'tabborders'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'backdrop' << 'tabbackground' << 'tabforeground'\n  end\n  private :__strval_optkeys\n\n  def initialize(*args)\n    super(*args)\n    @tabset = self.component_widget('tabset')\n  end\n\n  def add(keys={})\n    window(tk_call(@path, 'add', *hash_kv(keys)))\n  end\n\n  def child_site_list\n    list(tk_call(@path, 'childsite'))\n  end\n\n  def child_site(idx)\n    window(tk_call(@path, 'childsite', index(idx)))\n  end\n\n  def delete(idx1, idx2=nil)\n    if idx2\n      tk_call(@path, 'delete', index(idx1), index(idx2))\n    else\n      tk_call(@path, 'delete', index(idx1))\n    end\n    self\n  end\n\n  def index(idx)\n    #number(tk_call(@path, 'index', tagid(idx)))\n    @tabset.index(tagid(idx))\n  end\n\n  def insert(idx, keys={})\n    window(tk_call(@path, 'insert', index(idx), *hash_kv(keys)))\n  end\n\n  def next\n    tk_call(@path, 'next')\n    self\n  end\n\n  def prev\n    tk_call(@path, 'prev')\n    self\n  end\n\n  def select(idx)\n    tk_call(@path, 'select', index(idx))\n    self\n  end\n\n  def show_tab(idx)\n    @tabset.show_tab(idx)\n    self\n  end\n\n  def scrollcommand(cmd=Proc.new)\n    configure_cmd 'scrollcommand', cmd\n    self\n  end\n  alias xscrollcommand scrollcommand\n  alias yscrollcommand scrollcommand\n\n  def xscrollbar(bar=nil)\n    if bar\n      @scrollbar = bar\n      @scrollbar.orient 'horizontal'\n      self.scrollcommand {|*arg| @scrollbar.set(*arg)}\n      @scrollbar.command {|*arg| self.xview(*arg)}\n      Tk.update  # avoid scrollbar trouble\n    end\n    @scrollbar\n  end\n  def yscrollbar(bar=nil)\n    if bar\n      @scrollbar = bar\n      @scrollbar.orient 'vertical'\n      self.scrollcommand {|*arg| @scrollbar.set(*arg)}\n      @scrollbar.command {|*arg| self.yview(*arg)}\n      Tk.update  # avoid scrollbar trouble\n    end\n    @scrollbar\n  end\n  alias scrollbar yscrollbar\n\n  def view(*index)\n    if index.size == 0\n      idx = num_or_str(tk_send_without_enc('view'))\n      if idx.kind_of?(Fixnum) && idx < 0\n        nil\n      else\n        idx\n      end\n    else\n      tk_send_without_enc('view', *index)\n      self\n    end\n  end\n  alias xview view\n  alias yview view\n\n  def view_moveto(*index)\n    view('moveto', *index)\n  end\n  alias xview_moveto view_moveto\n  alias yview_moveto view_moveto\n  def view_scroll(index, what='pages')\n    view('scroll', index, what)\n  end\n  alias xview_scroll view_scroll\n  alias yview_scroll view_scroll\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/tabset.rb",
    "content": "#\n#  tkextlib/iwidgets/tabset.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Tabset < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Tabset\n  TkCommandNames = ['::iwidgets::tabset'.freeze].freeze\n  WidgetClassName = 'Tabset'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'tabcget', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'tabconfigure', id]\n  end\n  private :__item_config_cmd\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  alias tabcget itemcget\n  alias tabcget_strict itemcget_strict\n  alias tabconfigure itemconfigure\n  alias tabconfiginfo itemconfiginfo\n  alias current_tabconfiginfo current_itemconfiginfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\n\n  ####################################\n\n  def __boolval_optkeys\n    super() << 'equaltabs' << 'raiseselect' << 'tabborders'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'backdrop'\n  end\n  private :__strval_optkeys\n\n  def add(keys={})\n    window(tk_call(@path, 'add', *hash_kv(keys)))\n  end\n\n  def delete(idx1, idx2=nil)\n    if idx2\n      tk_call(@path, 'delete', index(idx1), index(idx2))\n    else\n      tk_call(@path, 'delete', index(idx1))\n    end\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, keys={})\n    window(tk_call(@path, 'insert', index(idx), *hash_kv(keys)))\n  end\n\n  def next\n    tk_call(@path, 'next')\n    self\n  end\n\n  def prev\n    tk_call(@path, 'prev')\n    self\n  end\n\n  def select(idx)\n    tk_call(@path, 'select', index(idx))\n    self\n  end\n\n  def show_tab(idx)\n    if index(idx) == 0\n      self.start = 0\n      return\n    end\n\n    reutrn unless @canvas ||= self.winfo_children[0]\n\n    delta = 1 if (delta = cget(:gap)) == 'overlap' ||\n                   (delta = self.winfo_pixels(delta) + 1) <= 0\n\n    case cget(:tabpos)\n    when 's', 'n'\n      if (head = tabcget(idx, :left)) < 0\n        self.start -= head\n        return\n      end\n      tabs_size = @canvas.winfo_width\n      tab_start, tab_end = @canvas . \n        find_overlapping(head, 0, head + delta, @canvas.winfo_height) . \n        find_all{|id| @canvas.itemtype(id) == TkcPolygon} . \n        map!{|id| bbox = @canvas.bbox(id); [bbox[0], bbox[2]]} . max\n\n    when 'e', 'w'\n      if (head = tabcget(idx, :top)) < 0\n        self.start -= head\n        return\n      end\n      tabs_size = @canvas.winfo_height\n      tab_start, tab_end = @canvas . \n        find_overlapping(0, head, @canvas.winfo_width, head + delta) . \n        find_all{|id| @canvas.itemtype(id) == TkcPolygon} . \n        map!{|id| bbox = @canvas.bbox(id); [bbox[1], bbox[3]]} . max\n    end\n\n    if (size = tab_end - tab_start + 1) > tabs_size\n      self.start -= tab_start\n    elsif head + size > tabs_size\n      self.start -= head + size - tabs_size\n    end\n\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/timeentry.rb",
    "content": "#\n#  tkextlib/iwidgets/timeentry.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Timeentry < Tk::Iwidgets::Timefield\n    end\n  end\nend\n\nclass Tk::Iwidgets::Timeentry\n  TkCommandNames = ['::iwidgets::timeentry'.freeze].freeze\n  WidgetClassName = 'Timeentry'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __strval_optkeys\n    super() << 'closetext'\n  end\n  private :__strval_optkeys\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/timefield.rb",
    "content": "#\n#  tkextlib/iwidgets/timefield.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class  Timefield < Tk::Iwidgets::Labeledwidget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Timefield\n  TkCommandNames = ['::iwidgets::timefield'.freeze].freeze\n  WidgetClassName = 'Timefield'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'gmt'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'textbackground'\n  end\n  private :__strval_optkeys\n\n  def __font_optkeys\n    super() << 'textfont'\n  end\n  private :__font_optkeys\n\n  def get_string\n    tk_call(@path, 'get', '-string')\n  end\n  alias get get_string\n\n  def get_clicks\n    number(tk_call(@path, 'get', '-clicks'))\n  end\n\n  def valid?\n    bool(tk_call(@path, 'isvalid'))\n  end\n  alias isvalid? valid?\n\n  def show(time=None)\n    tk_call(@path, 'show', time)\n    self\n  end\n  def show_now\n    tk_call(@path, 'show', 'now')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/toolbar.rb",
    "content": "#\n#  tkextlib/iwidgets/toolbar.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Toolbar < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Toolbar\n  TkCommandNames = ['::iwidgets::toolbar'.freeze].freeze\n  WidgetClassName = 'Toolbar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __tkvariable_optkeys\n    super() << 'helpvariable'\n  end\n  private :__tkvariable_optkeys\n\n  ####################################\n\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)\n    [self.path, 'itemcget', self.index(id)]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'itemconfigure', self.index(id)]\n  end\n  private :__item_config_cmd\n\n  def __item_strval_optkeys(id)\n    super(id) << 'helpstr' << 'balloonstr'\n  end\n  private :__item_strval_optkeys\n\n  def tagid(tagOrId)\n    if tagOrId.kind_of?(Tk::Itk::Component)\n      tagOrId.name\n    else\n      #_get_eval_string(tagOrId)\n      tagOrId\n    end\n  end\n\n  ####################################\n\n  def __strval_optkeys\n    super() << 'balloonbackground' << 'balloonforeground'\n  end\n  private :__strval_optkeys\n\n  def __tkvariable_optkeys\n    super() << 'helpvariable'\n  end\n  private :__tkvariable_optkeys\n\n  def __font_optkeys\n    super() << 'balloonfont'\n  end\n  private :__font_optkeys\n\n  def add(type, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    window(tk_call(@path, 'add', type, tagid(tag), *hash_kv(keys)))\n    tag\n  end\n\n  def delete(idx1, idx2=nil)\n    if idx2\n      tk_call(@path, 'delete', index(idx1), index(idx2))\n    else\n      tk_call(@path, 'delete', index(idx1))\n    end\n    self\n  end\n\n  def index(idx)\n    number(tk_call(@path, 'index', tagid(idx)))\n  end\n\n  def insert(idx, type, tag=nil, keys={})\n    if tag.kind_of?(Hash)\n      keys = tag\n      tag = nil\n    end\n    if tag\n      tag = Tk::Itk::Component.new(self, tagid(tag))\n    else\n      tag = Tk::Itk::Component.new(self)\n    end\n    window(tk_call(@path, 'insert', index(idx), type, \n                   tagid(tag), *hash_kv(keys)))\n    tag\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets/watch.rb",
    "content": "#\n#  tkextlib/iwidgets/watch.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets.rb'\n\nmodule Tk\n  module Iwidgets\n    class Watch < Tk::Itk::Widget\n    end\n  end\nend\n\nclass Tk::Iwidgets::Watch\n  TkCommandNames = ['::iwidgets::watch'.freeze].freeze\n  WidgetClassName = 'Watch'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'showampm'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'clockcolor' << 'hourcolor' << 'minutecolor' << \n      'pivotcolor' << 'secondcolor' << 'tickcolor'\n  end\n  private :__strval_optkeys\n\n  def get_string\n    tk_call(@path, 'get', '-string')\n  end\n  alias get get_string\n\n  def get_clicks\n    number(tk_call(@path, 'get', '-clicks'))\n  end\n\n  def show(time=None)\n    tk_call(@path, 'show', time)\n    self\n  end\n  def show_now\n    tk_call(@path, 'show', 'now')\n    self\n  end\n\n  def watch(*args)\n    unless args.empty?\n      tk_call(@path, 'watch', *args)\n    end\n    component_path('canvas')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/iwidgets.rb",
    "content": "#\n#  [incr Widgets] support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tkextlib/itcl'\nrequire 'tkextlib/itk'\n\n# call setup script for general 'tkextlib' libraries\n#require 'tkextlib/setup.rb'\n\n# call setup script\n#require 'tkextlib/iwidgets/setup.rb'\n\n# load all image format handlers\n#TkPackage.require('Iwidgets', '4.0')\nTkPackage.require('Iwidgets')\n\nmodule Tk\n  module Iwidgets\n    TkComm::TkExtlibAutoloadModule.unshift(self)\n\n    extend TkCore\n\n    PACKAGE_NAME = 'Iwidgets'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Iwidgets')\n      rescue\n        ''\n      end\n    end\n\n    ####################################################\n\n    autoload :Buttonbox,             'tkextlib/iwidgets/buttonbox'\n    autoload :Calendar,              'tkextlib/iwidgets/calendar'\n    autoload :Canvasprintbox,        'tkextlib/iwidgets/canvasprintbox'\n    autoload :Canvasprintdialog,     'tkextlib/iwidgets/canvasprintdialog'\n    autoload :Checkbox,              'tkextlib/iwidgets/checkbox'\n    autoload :Combobox,              'tkextlib/iwidgets/combobox'\n    autoload :Dateentry,             'tkextlib/iwidgets/dateentry'\n    autoload :Datefield,             'tkextlib/iwidgets/datefield'\n    autoload :Dialog,                'tkextlib/iwidgets/dialog'\n    autoload :Dialogshell,           'tkextlib/iwidgets/dialogshell'\n    autoload :Disjointlistbox,       'tkextlib/iwidgets/disjointlistbox'\n    autoload :Entryfield,            'tkextlib/iwidgets/entryfield'\n    autoload :Extbutton,             'tkextlib/iwidgets/extbutton'\n    autoload :Extfileselectionbox,   'tkextlib/iwidgets/extfileselectionbox'\n    autoload :Extfileselectiondialog,'tkextlib/iwidgets/extfileselectiondialog'\n    autoload :Feedback,              'tkextlib/iwidgets/feedback'\n    autoload :Fileselectionbox,      'tkextlib/iwidgets/fileselectionbox'\n    autoload :Fileselectiondialog,   'tkextlib/iwidgets/fileselectiondialog'\n    autoload :Finddialog,            'tkextlib/iwidgets/finddialog'\n    autoload :Hierarchy,             'tkextlib/iwidgets/hierarchy'\n    autoload :Hyperhelp,             'tkextlib/iwidgets/hyperhelp'\n    autoload :Labeledframe,          'tkextlib/iwidgets/labeledframe'\n    autoload :Labeledwidget,         'tkextlib/iwidgets/labeledwidget'\n    autoload :Mainwindow,            'tkextlib/iwidgets/mainwindow'\n    autoload :Menubar,               'tkextlib/iwidgets/menubar'\n    autoload :Messagebox,            'tkextlib/iwidgets/messagebox'\n    autoload :Messagedialog,         'tkextlib/iwidgets/messagedialog'\n    autoload :Notebook,              'tkextlib/iwidgets/notebook'\n    autoload :Optionmenu,            'tkextlib/iwidgets/optionmenu'\n    autoload :Panedwindow,           'tkextlib/iwidgets/panedwindow'\n    autoload :Pushbutton,            'tkextlib/iwidgets/pushbutton'\n    autoload :Promptdialog,          'tkextlib/iwidgets/promptdialog'\n    autoload :Radiobox,              'tkextlib/iwidgets/radiobox'\n    autoload :Scrolledcanvas,        'tkextlib/iwidgets/scrolledcanvas'\n    autoload :Scrolledframe,         'tkextlib/iwidgets/scrolledframe'\n    autoload :Scrolledhtml,          'tkextlib/iwidgets/scrolledhtml'\n    autoload :Scrolledlistbox,       'tkextlib/iwidgets/scrolledlistbox'\n    autoload :Scrolledtext,          'tkextlib/iwidgets/scrolledtext'\n    autoload :Scrolledwidget,        'tkextlib/iwidgets/scrolledwidget'\n    autoload :Selectionbox,          'tkextlib/iwidgets/selectionbox'\n    autoload :Selectiondialog,       'tkextlib/iwidgets/selectiondialog'\n    autoload :Shell,                 'tkextlib/iwidgets/shell'\n    autoload :Spindate,              'tkextlib/iwidgets/spindate'\n    autoload :Spinint,               'tkextlib/iwidgets/spinint'\n    autoload :Spinner,               'tkextlib/iwidgets/spinner'\n    autoload :Spintime,              'tkextlib/iwidgets/spintime'\n    autoload :Tabnotebook,           'tkextlib/iwidgets/tabnotebook'\n    autoload :Tabset,                'tkextlib/iwidgets/tabset'\n    autoload :Timeentry,             'tkextlib/iwidgets/timeentry'\n    autoload :Timefield,             'tkextlib/iwidgets/timefield'\n    autoload :Toolbar,               'tkextlib/iwidgets/toolbar'\n    autoload :Watch,                 'tkextlib/iwidgets/watch'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/pkg_checker.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  Ruby/Tk extension library checker\n#\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nTkRoot.new.withdraw  # hide root window\n\nname = File.basename(__FILE__)\n\nadd_path = false\nverbose  = false\n\ndef help_msg\n  print \"Usage: #{$0} [-l] [-v] [-h] [--] [dir]\\n\"\n  print \"\\tIf dir is omitted, check the directry that this command exists.\\n\"\n  print \"\\tAvailable options are \\n\"\n  print \"\\t  -l : Add dir to $LOAD_PATH\\n\"\n  print \"\\t       (If dir == '<parent>/tkextlib', add <parent> also.)\\n\"\n  print \"\\t  -v : Verbose mode (show reason of fail)\\n\"\n  print \"\\t  -h : Show this message\\n\"\n  print \"\\t  -- : End of options\\n\"\nend\n\nwhile(ARGV[0] && ARGV[0][0] == ?-)\n  case ARGV[0]\n  when '--'\n    ARGV.shift\n    break;\n  when '-l'\n    ARGV.shift\n    add_path = true\n  when '-v'\n    ARGV.shift\n    verbose = true\n  when '-h'\n    help_msg\n    exit(0)\n  else\n    print \"Argument Error!! : unknown option '#{ARGV[0]}'\\n\"\n    help_msg\n    exit(1)\n  end\nend\n\nif ARGV[0]\n  dir = File.expand_path(ARGV[0])\nelse\n  dir = File.dirname(File.expand_path(__FILE__))\nend\n\nif add_path\n  $LOAD_PATH.unshift(dir)\n  if File.basename(dir) == 'tkextlib'\n    $LOAD_PATH.unshift(File.dirname(dir))\n  end\nend\n\nprint \"\\nRuby/Tk extension library checker\\n\"\nprint \"( Note:: This check is very simple one. Shown status may be wrong. )\\n\"\nprint \"\\n check directory :: #{dir}\"\nprint \"\\n $LOAD_PATH :: #{$LOAD_PATH.inspect}\\n\"\n\ndef get_pkg_list(file)\n  pkg_list = []\n\n  File.foreach(file){|l|\n    if l =~ /^(?:[^#]+\\s|\\s*)(?:|;\\s*)TkPackage\\s*\\.\\s*require\\s*\\(?\\s*([\"'])((\\w|:)+)\\1/\n      pkg = [$2, :package]\n      pkg_list << pkg unless pkg_list.member?(pkg)\n    end\n    if l =~ /^(?:[^#]+\\s|\\s*)(?:|;\\s*)Tk\\s*\\.\\s*load_tcllibrary\\s*\\(?\\s*([\"'])((\\w|:)+)\\1/\n      pkg = [$2, :library]\n      pkg_list << pkg unless pkg_list.member?(pkg)\n    end\n    if l =~ /^(?:[^#]+\\s|\\s*)(?:|;\\s*)Tk\\s*\\.\\s*load_tclscript\\s*\\(?\\s*([\"'])((\\w|:)+)\\1/\n      pkg = [$2, :script]\n      pkg_list << pkg unless pkg_list.member?(pkg)\n    end\n    if l =~ /^(?:[^#]+\\s|\\s*)(?:|;\\s*)require\\s*\\(?\\s*([\"'])((\\w|\\/|:)+)\\1/\n      pkg = [$2, :require_ruby_lib]\n      pkg_list << pkg unless pkg_list.member?(pkg)\n    end\n  }\n\n  pkg_list\nend\n\ndef check_pkg(file, verbose=false)\n  pkg_list = get_pkg_list(file)\n\n  error_list = []\n  success_list = {}\n\n  pkg_list.each{|name, type|\n    next if success_list[name]\n\n    begin\n      case type\n      when :package\n        ver = TkPackage.require(name)\n        success_list[name] = ver\n        error_list.delete_if{|n, t| n == name}\n\n      when :library\n        Tk.load_tcllibrary(name)\n        success_list[name] = :library\n        error_list.delete_if{|n, t| n == name}\n\n      when :script\n        Tk.load_tclscript(name)\n        success_list[name] = :script\n        error_list.delete_if{|n, t| n == name}\n\n      when :require_ruby_lib\n        require name\n\n      end\n    rescue => e\n      if verbose\n        error_list << [name, type, e.message]\n      else\n        error_list << [name, type]\n      end\n    end\n  }\n\n  success_list.dup.each{|name, ver|\n    unless ver.kind_of?(String)\n      begin\n        ver = TkPackage.require(name)\n        sccess_list[name] = ver\n      rescue\n      end\n    end\n  }\n\n  [success_list, error_list]\nend\n\ndef subdir_check(dir, verbose=false)\n  Dir.foreach(dir){|f|\n    next if f == '.' || f == '..'\n    if File.directory?(f)\n      subdir_check(File.join(dir, f))\n    elsif File.extname(f) == '.rb'\n      path = File.join(dir, f)\n      suc, err = check_pkg(path, verbose)\n      if err.empty?\n        print 'Ready : ', path, ' : require->', suc.inspect, \"\\n\"\n      else\n        print '*LACK : ', path, ' : require->', suc.inspect, \n          '  FAIL->', err.inspect, \"\\n\"\n      end\n    end\n  }\nend\n\nDir.chdir(dir)\n\n(Dir['*.rb'] - ['setup.rb', name]).each{|f|\n  subdir = File.basename(f, '.*')\n=begin\n  begin\n    # read 'setup.rb' as if the library has standard structure\n    require File.join(subdir, 'setup.rb')\n  rescue LoadError\n    # ignore error\n  end\n=end\n  print \"\\n\"\n\n  suc, err = check_pkg(f, verbose)\n  if err.empty?\n    print 'Ready : ', f, ' : require->', suc.inspect, \"\\n\"\n  else\n    print '*LACK : ', f, ' : require->', suc.inspect, \n      '  FAIL->', err.inspect, \"\\n\"\n  end\n\n  subdir_check(subdir, verbose) if File.directory?(subdir)\n}\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before using Tk extension libraries\n#\n#    If you need some setup operations for Tk extensions (for example, \n#    modify the dynamic library path) required, please write the setup \n#    operations in this file. This file is required at the last of \n#    \"require 'tk'\". \n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/README",
    "content": "\n [ tcllib extension support files ]\n\nTcllib includes many utilities. But currently, supports TKLib part\nonly (see the following 'tcllib contents').\n\nIf you request to support others, please send your message to one of \nruby-talk/ruby-list/ruby-dev/ruby-ext mailing lists. \n\n-----<from \"What is tcllib?\">----------------------------\nTcllib is a collection of utility modules for Tcl. These modules provide \na wide variety of functionality, from implementations of standard data \nstructures to implementations of common networking protocols. The intent \nis to collect commonly used function into a single library, which users \ncan rely on to be available and stable.\n---------------------------------------------------------\n\n-----< tcllib contents (based on tcllib-1.6.1) >---------\nProgramming tools\n    * cmdline - Procedures to process command lines and options.\n    * comm - A remote communications facility for Tcl (7.6, 8.0, and later)\n    * control - Procedures for control flow structures.\n    * fileutil - Procedures implementing some file utilities\n    * log - Procedures to log messages of libraries and applications.\n    * logger - System to control logging of events.\n    * multiplexer - One-to-many communication with sockets.\n    * snit - Snit's Not Incr Tcl\n    * snitfaq - Snit Frequently Asked Questions\n    * stooop - Object oriented extension.\n    * stoop - Simple Tcl Only Object Oriented Programming\n    * switched - stooop switched class\n    * profiler - Tcl source code profiler\n\nMathematics\n    * math::statistics - Basic statistical functions and procedures\n    * math::calculus - Integration and ordinary differential equations\n    * math::optimize - Optimisation routines\n    * math::fuzzy - Fuzzy comparison of floating-point numbers\n    * counter - Procedures for counters and histograms\n    * combinatorics - Combinatorial functions in the Tcl Math Library\n\nData structures\n    * struct::list - Procedures for manipulating lists\n    * struct::set - Procedures for manipulating sets\n    * struct::stack - Create and manipulate stack objects\n    * struct::queue - Create and manipulate queue objects\n    * struct::prioqueue - Create and manipulate prioqueue objects\n    * struct::skiplist - Create and manipulate skiplists\n    * struct::tree - Create and manipulate tree objects\n    * struct::graph - Create and manipulate directed graph objects\n    * struct::record - Define and create records (similar to 'C' structures)\n    * struct::matrix - Create and manipulate matrix objects\n    * struct::pool - Create and manipulate pool objects (of discrete items)\n    * report - Create and manipulate report objects\n\nText processing\n    * expander - Procedures to process templates and expand text.\n    * base64 - Procedures to encode and decode base64\n    * yencode - encode/decoding a binary file\n    * uuencode - encode/decoding a binary file\n    * csv - Procedures to handle CSV data.\n    * inifile - Parsing of Windows INI files\n    * htmlparse - Procedures to parse HTML strings\n    * mime - Manipulation of MIME body parts\n    * Tcl MIME - generates and parses MIME body parts\n    * textutil - Procedures to manipulate texts and strings.\n    * exif - Tcl EXIF extracts and parses EXIF fields from digital images\n    * EXIF - extract and parse EXIF fields from digital images\n\nHashes, checksums, and encryption\n    * cksum - calculate a cksum(1) compatible checksum\n    * crc16 - Perform a 16bit Cyclic Redundancy Check\n    * crc32 - Perform a 32bit Cyclic Redundancy Check\n    * des - Perform DES encryption of Tcl data\n    * md4 - MD4 Message-Digest Algorithm\n    * md5 - MD5 Message-Digest Algorithm\n    * ripemd160 - RIPEMD-160 Message-Digest Algorithm\n    * ripemd128 - RIPEMD-128 Message-Digest Algorithm\n    * md5crypt - MD5-based password encryption\n    * sha1 - Perform sha1 hashing\n    * sum - calculate a sum(1) compatible checksum\n    * soundex - Soundex\n\nDocumentation tools\n    * mpexpand - Markup processor\n    * doctools - Create and manipulate doctools converter object\n    * doctoc_fmt - Specification of simple tcl markup for table of contents\n    * doctools_api - Interface specification for formatter code\n    * doctools_fmt - Specification of simple tcl markup for manpages\n    * docidx - Create and manipulate docidx converter objects\n    * docidx_api - Interface specification for index formatting code\n    * docidx_fmt - Specification of simple tcl markup for an index\n    * doctoc - Create and manipulate doctoc converter objects\n    * doctoc_api - Interface specification for toc formatting code\n    * doctools::changelog - Handle text in Emacs ChangeLog format\n    * doctools::cvs - Handle text in 'cvs log' format\n\nNetworking\n    * uri - URI utilities\n    * dns - Tcl Domain Name Service Client\n    * ntp_time - Tcl Time Service Client\n    * nntp - Tcl client for the NNTP protocol\n    * pop3 - Tcl client for POP3 email protocol\n    * pop3d - Tcl POP3 server implementation\n    * pop3d::udb - Simple user database for pop3d\n    * pop3d::dbox - Simple mailbox database for pop3d\n    * ftp - Client-side tcl implementation of the ftp protocol\n    * ftp - Client-side tcl implementation of the ftp protocol\n    * ftpd - Tcl FTP server implementation\n    * smtp - Client-side tcl implementation of the smtp protocol\n    * smtpd - Tcl SMTP server implementation\n    * irc - Create IRC connection and interface.\n\nCGI programming\n    * ncgi - Procedures to manipulate CGI values.\n    * html - Procedures to generate HTML structures\n    * javascript - Procedures to generate HTML and Java Script structures.\n\nGrammars and finite automata\n    * grammar::fa - Create and manipulate finite automatons\n    * grammar::fa::op - Operations on finite automatons\n    * grammar::dacceptor - Create and use deterministic acceptors\n    * grammar::dexec - Execute deterministic finite automatons\n\nTKLib\n    * Plotchart - Simple plotting and charting package\n    * autoscroll - Provides for a scrollbar to automatically mapped and \n                   unmapped as needed\n    * ctext - An extended text widget with customizable Syntax highlighting\n    * cursor - Procedures to handle CURSOR data\n    * datefield - Tk datefield widget\n    * style - Changes default Tk look&feel\n    * ipentry - An IP address entry widget\n    * tkpiechart - Creates and dynamically updates 2D or 3D pie charts\n---------------------------------------------------------\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/autoscroll.rb",
    "content": "#\n#  tkextlib/tcllib/autoscroll.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Provides for a scrollbar to automatically mapped and unmapped as needed\n#\n# (The following is the original description of the library.)\n#\n# This package allows scrollbars to be mapped and unmapped as needed \n# depending on the size and content of the scrollbars scrolled widget. \n# The scrollbar must be managed by either pack or grid, other geometry \n# managers are not supported.\n#\n# When managed by pack, any geometry changes made in the scrollbars parent \n# between the time a scrollbar is unmapped, and when it is mapped will be \n# lost. It is an error to destroy any of the scrollbars siblings while the \n# scrollbar is unmapped. When managed by grid, if anything becomes gridded \n# in the same row and column the scrollbar occupied it will be replaced by \n# the scrollbar when remapped.\n#\n# This package may be used on any scrollbar-like widget as long as it \n# supports the set subcommand in the same style as scrollbar. If the set \n# subcommand is not used then this package will have no effect.\n#\n\nrequire 'tk'\nrequire 'tk/scrollbar'\nrequire 'tkextlib/tcllib.rb'\n\nmodule Tk\n  module Tcllib\n    module Autoscroll\n      PACKAGE_NAME = 'autoscroll'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('autoscroll')\n        rescue\n          ''\n        end\n      end\n\n      def self.not_available\n        fail RuntimeError, \"'tkextlib/tcllib/autoscroll' extension is not available on your current environment.\"\n      end\n\n      def self.autoscroll(win)\n        Tk::Tcllib::Autoscroll.not_available\n      end\n\n      def self.unautoscroll(win)\n        Tk::Tcllib::Autoscroll.not_available\n      end\n    end\n  end\nend\n\nmodule Tk\n  module Scrollable\n    def autoscroll(mode = nil)\n      case mode\n      when :x, 'x'\n        if @xscrollbar\n          Tk::Tcllib::Autoscroll.autoscroll(@xscrollbar)\n        end\n      when :y, 'y'\n        if @yscrollbar\n          Tk::Tcllib::Autoscroll.autoscroll(@yscrollbar)\n        end\n      when nil, :both, 'both'\n        if @xscrollbar\n          Tk::Tcllib::Autoscroll.autoscroll(@xscrollbar)\n        end\n        if @yscrollbar\n          Tk::Tcllib::Autoscroll.autoscroll(@yscrollbar)\n        end\n      else\n        fail ArgumentError, \"'x', 'y' or 'both' (String or Symbol) is expected\"\n      end\n      self\n    end\n    def unautoscroll(mode = nil)\n      case mode\n      when :x, 'x'\n        if @xscrollbar\n          Tk::Tcllib::Autoscroll.unautoscroll(@xscrollbar)\n        end\n      when :y, 'y'\n        if @yscrollbar\n          Tk::Tcllib::Autoscroll.unautoscroll(@yscrollbar)\n        end\n      when nil, :both, 'both'\n        if @xscrollbar\n          Tk::Tcllib::Autoscroll.unautoscroll(@xscrollbar)\n        end\n        if @yscrollbar\n          Tk::Tcllib::Autoscroll.unautoscroll(@yscrollbar)\n        end\n      else\n        fail ArgumentError, \"'x', 'y' or 'both' (String or Symbol) is expected\"\n      end\n      self\n    end\n  end\nend\n\nclass Tk::Scrollbar\n  def autoscroll\n    # Arranges for the already existing scrollbar to be mapped \n    # and unmapped as needed.\n    #tk_call_without_enc('::autoscroll::autoscroll', @path)\n    Tk::Tcllib::Autoscroll.autoscroll(self)\n    self\n  end\n  def unautoscroll\n    #     Returns the scrollbar to its original static state. \n    #tk_call_without_enc('::autoscroll::unautoscroll', @path)\n    Tk::Tcllib::Autoscroll.unautoscroll(self)\n    self\n  end\nend\n\n# TkPackage.require('autoscroll', '1.0')\n# TkPackage.require('autoscroll', '1.1')\nTkPackage.require('autoscroll')\n\nmodule Tk\n  module Tcllib\n    class << Autoscroll\n      undef not_available\n    end\n\n    module Autoscroll\n      extend TkCore\n      def self.autoscroll(win)\n        tk_call_without_enc('::autoscroll::autoscroll', win.path)\n      end\n\n      def self.unautoscroll(win)\n        tk_call_without_enc('::autoscroll::unautoscroll', win.path)\n      end\n\n      def self.wrap\n        # v1.1\n        tk_call_without_enc('::autoscroll::wrap')\n      end\n\n      def self.unwrap\n        # v1.1\n        tk_call_without_enc('::autoscroll::unwrap')\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/ctext.rb",
    "content": "#\n#  tkextlib/tcllib/ctext.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Overloads the text widget and provides new commands\n#\n\nrequire 'tk'\nrequire 'tk/text'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('ctext', '3.1')\nTkPackage.require('ctext')\n\nmodule Tk\n  module Tcllib\n    class CText < Tk::Text\n      PACKAGE_NAME = 'ctext'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('ctext')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n\nclass Tk::Tcllib::CText\n  TkCommandNames = ['ctext'.freeze].freeze\n  WidgetClassName = 'Ctext'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def __strval_optkeys\n    super() << 'linemapfg' << 'linemapbg' << \n      'linemap_select_fg' << 'linemap_select_bg'\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() << 'highlight' << 'linemap_markable'\n  end\n  private :__boolval_optkeys\n\n  def append(*args)\n    tk_send('append', *args)\n  end\n\n  def copy\n    tk_send('copy')\n  end\n\n  def cut\n    tk_send('cut')\n  end\n\n  def fast_delete(*args)\n    tk_send('fastdelete', *args)\n  end\n\n  def fast_insert(*args)\n    tk_send('fastinsert', *args)\n  end\n\n  def highlight(*args)\n    tk_send('highlight', *args)\n  end\n\n  def paste\n    tk_send('paste')\n  end\n\n  def edit(*args)\n    tk_send('edit', *args)\n  end\n\n  def add_highlight_class(klass, col, *keywords)\n    tk_call('ctext::addHighlightClass', @path, klass, col, keywords.flatten)\n    self\n  end\n\n  def add_highlight_class_for_special_chars(klass, col, *chrs)\n    tk_call('ctext::addHighlightClassForSpecialChars', \n            @path, klass, col, chrs.join(''))\n    self\n  end\n\n  def add_highlight_class_for_regexp(klass, col, tcl_regexp)\n    tk_call('ctext::addHighlightClassForRegexp', \n            @path, klass, col, tcl_regexp)\n    self\n  end\n\n  def add_highlight_class_with_only_char_start(klass, col, chr)\n    tk_call('ctext::addHighlightClassWithOnlyCharStart', \n            @path, klass, col, chr)\n    self\n  end\n\n  def clear_highlight_classes\n    tk_call('ctext::clearHighlightClasses', @path)\n    self\n  end\n\n  def get_highlight_classes\n    tk_split_simplelist(tk_call('ctext::getHighlightClasses', @path))\n  end\n\n  def delete_highlight_class(klass)\n    tk_call('ctext::deleteHighlightClass', @path, klass)\n    self\n  end\n\n  def enable_C_comments\n    tk_call('ctext::enableComments', @path)\n    self\n  end\n\n  def disable_C_comments\n    tk_call('ctext::disableComments', @path)\n    self\n  end\n\n  def find_next_char(idx, chr)\n    tk_call('ctext::findNextChar', @path, idx, chr)\n  end\n\n  def find_next_space(idx)\n    tk_call('ctext::findNextSpace', @path, idx)\n  end\n\n  def find_previous_space(idx)\n    tk_call('ctext::findPreviousSpace', @path, idx)\n  end\n\n  def set_update_proc(cmd=Proc.new)\n    tk_call('proc', 'ctext::update', '', cmd)\n    self\n  end\n\n  def modified?(mode)\n    bool(tk_call('ctext::modified', @path, mode))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/cursor.rb",
    "content": "#\n#  tkextlib/tcllib/cursor.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Procedures to handle CURSOR data\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\nmodule Tk\n  module Tcllib\n    module Cursor\n      PACKAGE_NAME = 'cursor'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('cursor')\n        rescue\n          ''\n        end\n      end\n\n      def self.not_available\n        fail RuntimeError, \"'tkextlib/tcllib/cursor' extension is not available on your current environment.\"\n      end\n\n      def self.cursor_display(win=None)\n        Tk::Tcllib::Cursor.not_available\n      end\n\n      def self.cursor_propagate(win, cursor)\n        Tk::Tcllib::Cursor.not_available\n      end\n\n      def self.cursor_restore(win, cursor = None)\n        Tk::Tcllib::Cursor.not_available\n      end\n    end\n  end\n\n  def self.cursor_display(parent=None)\n    # Pops up a dialog with a listbox containing all the cursor names. \n    # Selecting a cursor name will display it in that dialog. \n    # This is simply for viewing any available cursors on the platform .\n    #tk_call_without_enc('::cursor::display', parent)\n    Tk::Tcllib::Cursor.cursor_display(parent)\n  end\nend\n\nclass TkWindow\n  def cursor_propagate(cursor)\n    # Sets the cursor for self and all its descendants to cursor. \n    #tk_call_without_enc('::cursor::propagate', @path, cursor)\n    Tk::Tcllib::Cursor.cursor_propagate(self, cursor)\n  end\n  def cursor_restore(cursor = None)\n    # Restore the original or previously set cursor for self and all its \n    # descendants. If cursor is specified, that will be used if on any \n    # widget that did not have a preset cursor (set by a previous call \n    # to TkWindow#cursor_propagate). \n    #tk_call_without_enc('::cursor::restore', @path, cursor)\n    Tk::Tcllib::Cursor.cursor_restore(self, cursor)\n  end\nend\n\n# TkPackage.require('cursor', '0.1')\nTkPackage.require('cursor')\n\nmodule Tk\n  module Tcllib\n    class << Cursor\n      undef not_available\n    end\n\n    module Cursor\n      extend TkCore\n      def self.cursor_display(win=None)\n        tk_call_without_enc('::cursor::display', _epath(win))\n      end\n\n      def self.cursor_propagate(win, cursor)\n        #tk_call_without_enc('::cursor::propagate', win.path, cursor)\n        tk_call_without_enc('::cursor::propagate', _epath(win), cursor)\n      end\n\n      def self.cursor_restore(win, cursor = None)\n        #tk_call_without_enc('::cursor::restore', win.path, cursor)\n        tk_call_without_enc('::cursor::restore', _epath(win), cursor)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/datefield.rb",
    "content": "#\n#  tkextlib/tcllib/datefield.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Tk datefield widget\n#\n# (The following is the original description of the library.)\n#\n# The datefield package provides the datefield widget which is an enhanced \n# text entry widget for the purpose of date entry. Only valid dates of the \n# form MM/DD/YYYY can be entered.\n# \n# The datefield widget is, in fact, just an entry widget with specialized \n# bindings. This means all the command and options for an entry widget apply \n# equally here.\n\nrequire 'tk'\nrequire 'tk/entry'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('datefield', '0.1')\nTkPackage.require('datefield')\n\nmodule Tk\n  module Tcllib\n    class Datefield < Tk::Entry\n      PACKAGE_NAME = 'datefield'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('datefield')\n        rescue\n          ''\n        end\n      end\n    end\n    DateField = Datefield\n  end\nend\n\nclass Tk::Tcllib::Datefield\n  TkCommandNames = ['::datefield::datefield'.freeze].freeze\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/dialog.rb",
    "content": "#\n#  tkextlib/tcllib/dialog.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Generic dialog widget (themed)\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget::dialog', '1.2')\nTkPackage.require('widget::dialog')\n\nmodule Tk::Tcllib\n  module Widget\n    class Dialog < TkWindow\n      PACKAGE_NAME = 'widget::dialog'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('widget::dialog')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n\nclass Tk::Tcllib::Widget::Dialog\n  TkCommandNames = ['::widget::dialog'.freeze].freeze\n\n  def __boolval_optkeys\n    ['separator', 'synchronous', 'transient']\n  end\n  private :__boolval_optkeys\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def add(what, *args)\n    window(tk_send('add', *args))\n  end\n\n  def get_frame\n    window(tk_send('getframe'))\n  end\n\n  def set_widget(widget)\n    tk_send('setwidget', widget)\n    self\n  end\n\n  def display\n    tk_send('display')\n    self\n  end\n  alias show display\n\n  def cancel\n    tk_send('cancel')\n    self\n  end\n\n  def close(reason = None)\n    tk_send('close', reason)\n  end\n\n  def withdraw\n    tk_send('withdraw')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/getstring.rb",
    "content": "#\n#  tkextlib/tcllib/getstring.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * A dialog which consists of an Entry, OK, and Cancel buttons.\n#\n\nrequire 'tk'\nrequire 'tk/entry'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('getstring', '0.1')\nTkPackage.require('getstring')\n\nmodule Tk::Tcllib\n  class GetString_Dialog < TkWindow\n    PACKAGE_NAME = 'getstring'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('getstring')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\n\nclass Tk::Tcllib::GetString_Dialog\n  TkCommandNames = ['::getstring::tk_getString'.freeze].freeze\n  WidgetClassName = 'TkSDialog'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.show(*args)\n    dialog = self.new(*args)\n    dialog.show\n    [dialog.status, dialog.value]\n  end\n  def self.display(*args)\n    self.show(*args)\n  end\n\n  def initialize(*args)   # args = (parent=nil, text='', keys=nil)\n    keys = args.pop\n    if keys.kind_of?(Hash)\n      text = args.pop\n      @keys = _symbolkey2str(keys)\n      args.push(keys)\n    else\n      text = keys\n      @keys = {}\n    end\n    if text\n      @text = text.dup\n    else\n      @text = ''\n    end\n\n    @variable = TkVariable.new\n    @status = nil\n\n    super(*args)\n  end\n\n  def create_self(keys)\n    # dummy\n  end\n  private :create_self\n\n  def show\n    @variable.value = ''\n    @status = bool(tk_call(self.class::TkCommandNames[0], \n                           @path, @variable, @text, *hash_kv(@keys)))\n  end\n  alias display show\n\n  def status\n    @status\n  end\n\n  def value\n    @variable.value\n  end\n\n  def cget_strict(slot)\n    slot = slot.to_s\n    if slot == 'text'\n      @text\n    else\n      @keys[slot]\n    end\n  end\n  def cget(slot)\n    cget_strict(slot)\n  end\n\n  def configure(slot, value=None)\n    if slot.kind_of?(Hash)\n      slot.each{|k, v| configure(k, v)}\n    else\n      slot = slot.to_s\n      value = _symbolkey2str(value) if value.kind_of?(Hash)\n      if value && value != None\n        if slot == 'text'\n          @text = value.to_s\n        else\n          @keys[slot] = value\n        end\n      else\n        if slot == 'text'\n          @text = ''\n        else\n          @keys.delete(slot)\n        end\n      end\n    end\n    self\n  end\n\n  def configinfo(slot = nil)\n    if slot\n      slot = slot.to_s\n      [ slot, nil, nil, nil, ( (slot == 'text')? @text: @keys[slot] ) ]\n    else\n      @keys.collect{|k, v| [ k, nil, nil, nil, v ] }   \\\n      << [ 'text', nil, nil, nil, @text ]\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/history.rb",
    "content": "#\n#  tkextlib/tcllib/history.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Provides a history for Entry widgets\n#\n\nrequire 'tk'\nrequire 'tk/entry'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('history', '0.1')\nTkPackage.require('history')\n\nmodule Tk::Tcllib\n  module History\n    PACKAGE_NAME = 'history'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('history')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\nmodule Tk::Tcllib::History\n  extend TkCore\n\n  def self.init(entry, length=None)\n    tk_call_without_enc('::history::init', entry.path, length)\n    entry.extend(self)  # add methods to treat history to the entry widget\n  end\n\n  def self.remove(entry)\n    tk_call_without_enc('::history::remove', entry.path)\n    entry\n  end\n\n  def history_remove\n    tk_call_without_enc('::history::remove', @path)\n    self\n  end\n\n  def history_add(text)\n    tk_call('::history::add', @path, text)\n    self\n  end\n\n  def history_get\n    simplelist(tk_call_without_enc('::history::get', @path))\n  end\n\n  def history_clear\n    tk_call_without_enc('::history::clear', @path)\n    self\n  end\n\n  def history_configure(opt, value)\n    tk_call('::history::configure', @path, opt, value)\n    self\n  end\n\n  def history_configinfo(opt)\n    tk_call('::history::configure', @path, opt)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/ico.rb",
    "content": "#\n#  tkextlib/tcllib/ico.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Reading and writing windows icons\n#\n\nrequire 'tk'\nrequire 'tk/image'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('ico', '0.3')\nTkPackage.require('ico')\n\nmodule Tk\n  module Tcllib\n    class ICO < TkImage\n      PACKAGE_NAME = 'ico'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('ico')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n\nclass Tk::Tcllib::ICO\n  def self.list(file, keys=nil)\n    tk_split_list(tk_call_without_enc('::ico::getIconList', file,\n                                      *hash_kv(keys, true)))\n  end\n\n  def self.get(file, index, keys=nil)\n    tk_call_without_enc('::ico::getIcon', file, index, *hash_kv(keys, true))\n  end\n\n  def self.get_image(file, index, keys={})\n    keys = _symbolkey2str(keys)\n    keys.delete('format')\n    self.new(file, index, keys)\n  end\n\n  def self.get_data(file, index, keys={})\n    keys['format'] = 'data'\n    tk_split_list(tk_call_without_enc('::ico::getIcon', file, index, \n                                      *hash_kv(keys, true)))\n  end\n\n  def self.write(file, index, depth, data, keys=nil)\n    tk_call_without_enc('::ico::writeIcon', file, index, depth, data, \n                        *hash_kv(keys, true))\n  end\n\n  def self.copy(from_file, from_index, to_file, to_index, keys=nil)\n    tk_call_without_enc('::ico::copyIcon', \n                        from_file, from_index, to_file, to_index, \n                        *hash_kv(keys, true))\n  end\n\n  def self.exe_to_ico(exe_file, ico_file, keys=nil)\n    tk_call_without_enc('::ico::copyIcon', exe_file, ico_file, \n                        *hash_kv(keys, true))\n  end\n\n  def self.clear_cache(file=None)\n    tk_call_without_enc('::ico::clearCache', file)\n  end\n\n  def self.transparent_color(image, color)\n    if image.kind_of?(Array)\n      tk_split_list(tk_call_without_enc('::ico::transparentColor', \n                                        image, color))\n    else\n      tk_call_without_enc('::ico::transparentColor', image, color)\n    end\n  end\n\n  def self.show(file, keys=nil)\n    tk_call_without_enc('::ico::Show', file, *hash_kv(keys, true))\n  end\n\n  ###########################\n\n  def initialize(file, index, keys=nil)\n    keys = _symbolkey2str(keys)\n    if keys.key?('name')\n      @path = keys['name'].to_s\n    else\n      Tk_Image_ID.mutex.synchronize{\n        @path = Tk_Image_ID.join(TkCore::INTERP._ip_id_)\n        Tk_Image_ID[1].succ!\n      }\n    end\n    tk_call_without_enc('::ico::getIcon', file, index, '-name', @path, \n                        '-format', 'image', *hash_kv(keys, true))\n    Tk_IMGTBL[@path] = self\n  end\n\n  def write(file, index, depth, keys=nil)\n    Tk::Tcllib::ICO.write(file, index, depth, @path, keys=nil)\n    self\n  end\n\n  def transparent_color(color)\n    tk_call_without_enc('::ico::transparentColor', @path, color)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/ip_entry.rb",
    "content": "#\n#  tkextlib/tcllib/ip_entry.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * An IP address entry widget\n#\n# (The following is the original description of the library.)\n#\n# This package provides a widget for the entering of a IP address. \n# It guarantees a valid address at all times.\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('ipentry', '0.1')\nTkPackage.require('ipentry')\n\nmodule Tk\n  module Tcllib\n    class IP_Entry < Tk::Entry\n      PACKAGE_NAME = 'ipentry'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('ipentry')\n        rescue\n          ''\n        end\n      end\n    end\n    IPEntry = IP_Entry\n  end\nend\n\nclass Tk::Tcllib::IP_Entry\n  TkCommandNames = ['::ipentry::ipentry'.freeze].freeze\n  WidgetClassName = 'IPEntry'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def __strval_optkeys\n    super() << 'fg' << 'bg' << 'insertbackground'\n  end\n  private :__strval_optkeys\n\n  def complete?\n    bool(tk_send_without_enc('complete'))\n  end\n\n  def insert(*ip)\n    tk_send_without_enc('insert', array2tk_list(ip.flatten))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/panelframe.rb",
    "content": "#\n#  tkextlib/tcllib/panelframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Create PanelFrame widgets.\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget::panelframe', '1.0')\nTkPackage.require('widget::panelframe')\n\nmodule Tk::Tcllib\n  module Widget\n    class PanelFrame < TkWindow\n      PACKAGE_NAME = 'widget::panelframe'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('widget::panelframe')\n        rescue\n          ''\n        end\n      end\n    end\n    Panelframe = PanelFrame\n  end\nend\n\nclass Tk::Tcllib::Widget::PanelFrame\n  TkCommandNames = ['::widget::panelframe'.freeze].freeze\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def add(what, *args)\n    window(tk_send('add', *args))\n  end\n\n  #def get_frame\n  #  window(tk_send('getframe'))\n  #end\n\n  def set_widget(widget)\n    tk_send('setwidget', widget)\n    self\n  end\n\n  def remove(*wins)\n    tk_send('remove', *wins)\n  end\n  def remove_destroy(*wins)\n    tk_send('remove', '-destroy', *wins)\n  end\n  alias delete remove_destroy\n\n  def items\n    simplelist(tk_send('items')).collect!{|w| window(w)}\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/plotchart.rb",
    "content": "#\n#  tkextlib/tcllib/plotchart.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Simple plotting and charting package\n#\n# (The following is the original description of the library.)\n#\n# Plotchart is a Tcl-only package that focuses on the easy creation of \n# xy-plots, barcharts and other common types of graphical presentations. \n# The emphasis is on ease of use, rather than flexibility. The procedures \n# that create a plot use the entire canvas window, making the layout of the \n# plot completely automatic.\n#\n# This results in the creation of an xy-plot in, say, ten lines of code:\n# --------------------------------------------------------------------\n#    package require Plotchart\n#\n#    canvas .c -background white -width 400 -height 200\n#    pack   .c -fill both\n#\n#    #\n#    # Create the plot with its x- and y-axes\n#    #\n#    set s [::Plotchart::createXYPlot .c {0.0 100.0 10.0} {0.0 100.0 20.0}]\n#\n#    foreach {x y} {0.0 32.0 10.0 50.0 25.0 60.0 78.0 11.0 } {\n#        $s plot series1 $x $y\n#    }\n#\n#    $s title \"Data series\"\n# --------------------------------------------------------------------\n#\n# A drawback of the package might be that it does not do any data management. \n# So if the canvas that holds the plot is to be resized, the whole plot must \n# be redrawn. The advantage, though, is that it offers a number of plot and \n# chart types:\n#\n#    * XY-plots like the one shown above with any number of data series.\n#    * Stripcharts, a kind of XY-plots where the horizontal axis is adjusted \n#      automatically. The result is a kind of sliding window on the data \n#      series.\n#    * Polar plots, where the coordinates are polar instead of cartesian.\n#    * Isometric plots, where the scale of the coordinates in the two \n#      directions is always the same, i.e. a circle in world coordinates \n#      appears as a circle on the screen.\n#      You can zoom in and out, as well as pan with these plots (Note: this \n#      works best if no axes are drawn, the zooming and panning routines do \n#      not distinguish the axes), using the mouse buttons with the control \n#      key and the arrow keys with the control key.\n#    * Piecharts, with automatic scaling to indicate the proportions.\n#    * Barcharts, with either vertical or horizontal bars, stacked bars or \n#      bars side by side.\n#    * Timecharts, where bars indicate a time period and milestones or other \n#      important moments in time are represented by triangles.\n#    * 3D plots (both for displaying surfaces and 3D bars)\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('Plotchart', '0.9')\n# TkPackage.require('Plotchart', '1.1')\nTkPackage.require('Plotchart')\n\nmodule Tk\n  module Tcllib\n    module Plotchart\n      PACKAGE_NAME = 'Plotchart'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('Plotchart')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n\nmodule Tk::Tcllib::Plotchart\n  extend TkCore\n  ############################\n  def self.view_port(w, *args) # args := pxmin, pymin, pxmax, pymax\n    tk_call_without_enc('::Plotchart::viewPort', w.path, *(args.flatten))\n  end\n\n  def self.world_coordinates(w, *args) # args := xmin, ymin, xmax, ymax\n    tk_call_without_enc('::Plotchart::worldCoordinates', \n                        w.path, *(args.flatten))\n  end\n\n  def self.world_3D_coordinates(w, *args) \n    # args := xmin, ymin, zmin, xmax, ymax, zmax\n    tk_call_without_enc('::Plotchart::world3DCoordinates', \n                        w.path, *(args.flatten))\n  end\n\n  def self.coords_to_pixel(w, x, y)\n    list(tk_call_without_enc('::Plotchart::coordsToPixel', w.path, x, y))\n  end\n\n  def self.coords_3D_to_pixel(w, x, y, z)\n    list(tk_call_without_enc('::Plotchart::coords3DToPixel', w.path, x, y, z))\n  end\n\n  def self.polar_coordinates(w, radmax)\n    tk_call_without_enc('::Plotchart::polarCoordinates', w.path, radmax)\n  end\n\n  def self.polar_to_pixel(w, rad, phi)\n    list(tk_call_without_enc('::Plotchart::polarToPixel', w.path, rad, phi))\n  end\n\n  def self.pixel_to_coords(w, x, y)\n    list(tk_call_without_enc('::Plotchart::coordsToPixel', w.path, x, y))\n  end\n\n  def self.determine_scale(w, xmax, ymax)\n    tk_call_without_enc('::Plotchart::determineScale', w.path, xmax, ymax)\n  end\n\n  def self.set_zoom_pan(w)\n    tk_call_without_enc('::Plotchart::setZoomPan', w.path)\n  end\n\n  ############################\n  module ChartMethod\n    include TkCore\n\n    def title(str)\n      tk_call_without_enc(@chart, 'title', _get_eval_enc_str(str))\n      self\n    end\n\n    def save_plot(filename)\n      tk_call_without_enc(@chart, 'saveplot', filename)\n      self\n    end\n\n    def xtext(str)\n      tk_call_without_enc(@chart, 'xtext', _get_eval_enc_str(str))\n      self\n    end\n\n    def ytext(str)\n      tk_call_without_enc(@chart, 'ytext', _get_eval_enc_str(str))\n      self\n    end\n\n    def xconfig(key, value=None)\n      if key.kind_of?(Hash)\n        tk_call_without_enc(@chart, 'xconfig', *hash_kv(key, true))\n      else\n        tk_call_without_enc(@chart, 'xconfig', \n                            \"-#{key}\", _get_eval_enc_str(value))\n      end\n      self\n    end\n\n    def yconfig(key, value=None)\n      if key.kind_of?(Hash)\n        tk_call_without_enc(@chart, 'yconfig', *hash_kv(key, true))\n      else\n        tk_call_without_enc(@chart, 'yconfig', \n                            \"-#{key}\", _get_eval_enc_str(value))\n      end\n      self\n    end\n\n    ############################\n    def view_port(*args) # args := pxmin, pymin, pxmax, pymax\n      tk_call_without_enc('::Plotchart::viewPort', @path, *(args.flatten))\n      self\n    end\n\n    def world_coordinates(*args) # args := xmin, ymin, xmax, ymax\n      tk_call_without_enc('::Plotchart::worldCoordinates', \n                          @path, *(args.flatten))\n      self\n    end\n\n    def world_3D_coordinates(*args) \n      # args := xmin, ymin, zmin, xmax, ymax, zmax\n      tk_call_without_enc('::Plotchart::world3DCoordinates', \n                          @path, *(args.flatten))\n      self\n    end\n\n    def coords_to_pixel(x, y)\n      list(tk_call_without_enc('::Plotchart::coordsToPixel', @path, x, y))\n    end\n\n    def coords_3D_to_pixel(x, y, z)\n      list(tk_call_without_enc('::Plotchart::coords3DToPixel', @path, x, y, z))\n    end\n\n    def polar_coordinates(radmax)\n      tk_call_without_enc('::Plotchart::polarCoordinates', @path, radmax)\n      self\n    end\n\n    def polar_to_pixel(rad, phi)\n      list(tk_call_without_enc('::Plotchart::polarToPixel', @path, rad, phi))\n    end\n\n    def pixel_to_coords(x, y)\n      list(tk_call_without_enc('::Plotchart::coordsToPixel', @path, x, y))\n    end\n\n    def determine_scale(xmax, ymax)\n      tk_call_without_enc('::Plotchart::determineScale', @path, xmax, ymax)\n      self\n    end\n\n    def set_zoom_pan()\n      tk_call_without_enc('::Plotchart::setZoomPan', @path)\n      self\n    end\n  end\n\n  ############################\n  class XYPlot < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createXYPlot'.freeze\n    ].freeze\n\n    def initialize(*args) # args := ([parent,] xaxis, yaxis [, keys])\n                          # xaxis := Array of [minimum, maximum, stepsize]\n                          # yaxis := Array of [minimum, maximum, stepsize]\n      if args[0].kind_of?(Array)\n        @xaxis = args.shift\n        @yaxis = args.shift\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @xaxis = args.shift\n        @yaxis = args.shift\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          array2tk_list(@xaxis), array2tk_list(@yaxis))\n    end\n    private :_create_chart\n\n    def __destroy_hook__\n      Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.mutex.synchronize{\n        Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path)\n      }\n    end\n\n    def plot(series, x, y)\n      tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(series), x, y)\n      self\n    end\n\n    def contourlines(xcrd, ycrd, vals, clss=None)\n      xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array)\n      ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array)\n      vals = array2tk_list(vals) if vals.kind_of?(Array)\n      clss = array2tk_list(clss) if clss.kind_of?(Array)\n\n      tk_call_without_enc(@chart, 'contourlines', xcrd, ycrd, vals, clss)\n      self\n    end\n\n    def contourfill(xcrd, ycrd, vals, klasses=None)\n      xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array)\n      ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array)\n      vals = array2tk_list(vals) if vals.kind_of?(Array)\n      clss = array2tk_list(clss) if clss.kind_of?(Array)\n\n      tk_call_without_enc(@chart, 'contourfill', xcrd, ycrd, vals, clss)\n      self\n    end\n\n    def contourbox(xcrd, ycrd, vals, klasses=None)\n      xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array)\n      ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array)\n      vals = array2tk_list(vals) if vals.kind_of?(Array)\n      clss = array2tk_list(clss) if clss.kind_of?(Array)\n\n      tk_call_without_enc(@chart, 'contourbox', xcrd, ycrd, vals, clss)\n      self\n    end\n\n    def color_map(colors)\n      colors = array2tk_list(colors) if colors.kind_of?(Array)\n\n      tk_call_without_enc(@chart, 'colorMap', colors)\n      self\n    end\n\n    def grid_cells(xcrd, ycrd)\n      xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array)\n      ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array)\n\n      tk_call_without_enc(@chart, 'grid', xcrd, ycrd)\n      self\n    end\n\n    def dataconfig(series, key, value=None)\n      if key.kind_of?(Hash)\n        tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true))\n      else\n        tk_call_without_enc(@chart, 'dataconfig', series, \n                            \"-#{key}\", _get_eval_enc_str(value))\n      end\n    end\n  end\n\n  ############################\n  class Stripchart < XYPlot\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createStripchart'.freeze\n    ].freeze\n  end\n\n  ############################\n  class PolarPlot < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createPolarplot'.freeze\n    ].freeze\n\n    def initialize(*args) # args := ([parent,] radius_data [, keys])\n                          # radius_data := Array of [maximum_radius, stepsize]\n      if args[0].kind_of?(Array)\n        @radius_data = args.shift\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @radius_data = args.shift\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          array2tk_list(@radius_data))\n    end\n    private :_create_chart\n\n    def __destroy_hook__\n      Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.mutex.synchronize{\n        Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path)\n      }\n    end\n\n    def plot(series, radius, angle)\n      tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(series), \n                          radius, angle)\n      self\n    end\n\n    def dataconfig(series, key, value=None)\n      if key.kind_of?(Hash)\n        tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true))\n      else\n        tk_call_without_enc(@chart, 'dataconfig', series, \n                            \"-#{key}\", _get_eval_enc_str(value))\n      end\n    end\n  end\n  Polarplot = PolarPlot\n\n  ############################\n  class IsometricPlot < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createIsometricPlot'.freeze\n    ].freeze\n\n    def initialize(*args) # args := ([parent,] xaxis, yaxis, [, step] [, keys])\n                          # xaxis := Array of [minimum, maximum]\n                          # yaxis := Array of [minimum, maximum]\n                          # step := Float of stepsize | \"noaxes\" | :noaxes\n      if args[0].kind_of?(Array)\n        @xaxis = args.shift\n        @yaxis = args.shift\n\n        if args[0].kind_of?(Hash)\n          @stepsize = :noaxes\n        else\n          @stepsize = args.shift\n        end\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @xaxis = args.shift\n        @yaxis = args.shift\n\n        if args[0].kind_of?(Hash)\n          @stepsize = :noaxes\n        else\n          @stepsize = args.shift\n        end\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          array2tk_list(@xaxis), array2tk_list(@yaxis), \n                          @stepsize)\n    end\n    private :_create_chart\n\n    def plot(type, *args)\n      self.__send__(\"plot_#{type.to_s.tr('-', '_')}\", *args)\n    end\n\n    def plot_rectangle(*args) # args := x1, y1, x2, y2, color\n      tk_call_without_enc(@chart, 'plot', 'rectangle', *(args.flatten))\n      self\n    end\n\n    def plot_filled_rectangle(*args) # args := x1, y1, x2, y2, color\n      tk_call_without_enc(@chart, 'plot', 'filled-rectangle', *(args.flatten))\n      self\n    end\n\n    def plot_circle(*args) # args := xc, yc, radius, color\n      tk_call_without_enc(@chart, 'plot', 'circle', *(args.flatten))\n      self\n    end\n\n    def plot_filled_circle(*args) # args := xc, yc, radius, color\n      tk_call_without_enc(@chart, 'plot', 'filled-circle', *(args.flatten))\n      self\n    end\n  end\n  Isometricplot = IsometricPlot\n\n  ############################\n  class Plot3D < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::create3DPlot'.freeze\n    ].freeze\n\n    def initialize(*args) # args := ([parent,] xaxis, yaxis, zaxis [, keys])\n                          # xaxis := Array of [minimum, maximum, stepsize]\n                          # yaxis := Array of [minimum, maximum, stepsize]\n                          # zaxis := Array of [minimum, maximum, stepsize]\n      if args[0].kind_of?(Array)\n        @xaxis = args.shift\n        @yaxis = args.shift\n        @zaxis = args.shift\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @xaxis = args.shift\n        @yaxis = args.shift\n        @zaxis = args.shift\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          array2tk_list(@xaxis), \n                          array2tk_list(@yaxis), \n                          array2tk_list(@zaxis))\n    end\n    private :_create_chart\n\n    def plot_function(cmd=Proc.new)\n      Tk.ip_eval(\"proc #{@path}_#{@chart} {x y} {#{install_cmd(cmd)} $x $y}\")\n      tk_call_without_enc(@chart, 'plotfunc', \"#{@path}_#{@chart}\")\n      self\n    end\n\n    def plot_funcont(conts, cmd=Proc.new)\n      conts = array2tk_list(conts) if conts.kind_of?(Array)\n      Tk.ip_eval(\"proc #{@path}_#{@chart} {x y} {#{install_cmd(cmd)} $x $y}\")\n      tk_call_without_enc(@chart, 'plotfuncont', \"#{@path}_#{@chart}\", conts)\n      self\n    end\n\n    def grid_size(nxcells, nycells)\n      tk_call_without_enc(@chart, 'gridsize', nxcells, nycells)\n      self\n    end\n\n    def plot_data(dat)\n      # dat has to be provided as a 2 level array. \n      # 1st level contains rows, drawn in y-direction, \n      # and each row is an array whose elements are drawn in x-direction, \n      # for the columns. \n      tk_call_without_enc(@chart, 'plotdata', dat)\n      self\n    end\n\n    def colour(fill, border)\n      # configure the colours to use for polygon borders and inner area\n      tk_call_without_enc(@chart, 'colour', fill, border)\n      self\n    end\n    alias colours colour\n    alias colors  colour\n    alias color   colour\n  end\n\n  ############################\n  class Piechart < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createPiechart'.freeze\n    ].freeze\n\n    def initialize(*args) # args := ([parent] [, keys])\n      if args[0].kind_of?(Tk::Canvas)\n        parent = args.shift\n        @path = parent.path\n      else\n        super(*args) # create canvas widget\n      end\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path)\n    end\n    private :_create_chart\n\n    def plot(*dat)  # argument is a list of [label, value]\n      tk_call_without_enc(@chart, 'plot', dat.flatten)\n      self\n    end\n  end\n\n  ############################\n  class Barchart < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createBarchart'.freeze\n    ].freeze\n\n    def initialize(*args) \n      # args := ([parent,] xlabels, ylabels [, series] [, keys])\n      # xlabels, ylabels := labels | axis ( depend on normal or horizontal )\n      # labels := Array of [label, label, ...]\n      #   (It determines the number of bars that will be plotted per series.)\n      # axis := Array of [minimum, maximum, stepsize]\n      # series := Integer number of data series | 'stacked' | :stacked\n      if args[0].kind_of?(Array)\n        @xlabels = args.shift\n        @ylabels  = args.shift\n\n        if args[0].kind_of?(Hash)\n          @series_size = :stacked\n        else\n          @series_size  = args.shift\n        end\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @xlabels = args.shift\n        @ylabels = args.shift\n\n        if args[0].kind_of?(Hash)\n          @series_size = :stacked\n        else\n          @series_size  = args.shift\n        end\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          array2tk_list(@xlabels), array2tk_list(@ylabels), \n                          @series_size)\n    end\n    private :_create_chart\n\n    def __destroy_hook__\n      Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.mutex.synchronize{\n        Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path)\n      }\n    end\n\n    def plot(series, dat, col=None)\n      tk_call_without_enc(@chart, 'plot', series, dat, col)\n      self\n    end\n\n    def colours(*cols)\n      # set the colours to be used\n      tk_call_without_enc(@chart, 'colours', *cols)\n      self\n    end\n    alias colour colours\n    alias colors colours\n    alias color  colours\n  end\n\n  ############################\n  class HorizontalBarchart < Barchart\n    TkCommandNames = [\n      'canvas'.freeze, \n      '::Plotchart::createHorizontalBarchart'.freeze\n    ].freeze\n  end\n\n  ############################\n  class Timechart < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze,\n      '::Plotchart::createTimechart'.freeze\n    ].freeze\n\n    def initialize(*args)\n      # args := ([parent,] time_begin, time_end, items [, keys])\n      # time_begin := String of time format (e.g. \"1 january 2004\")\n      # time_end   := String of time format (e.g. \"1 january 2004\")\n      # items := Expected/maximum number of items\n      #          ( This determines the vertical spacing. )\n      if args[0].kind_of?(String)\n        @time_begin = args.shift\n        @time_end   = args.shift\n        @items      = args.shift\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @time_begin = args.shift\n        @time_end   = args.shift\n        @items      = args.shift\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          @time_begin, @time_end, @items)\n    end\n    private :_create_chart\n\n    def period(txt, time_begin, time_end, col=None)\n      tk_call_without_enc(@chart, 'period', txt, time_begin, time_end, col)\n      self\n    end\n\n    def milestone(txt, time, col=None)\n      tk_call_without_enc(@chart, 'milestone', txt, time, col)\n      self\n    end\n\n    def vertline(txt, time)\n      tk_call_without_enc(@chart, 'vertline', txt, time)\n      self\n    end\n  end\n\n  ############################\n  class Gnattchart < Tk::Canvas\n    include ChartMethod\n\n    TkCommandNames = [\n      'canvas'.freeze,\n      '::Plotchart::createGnattchart'.freeze\n    ].freeze\n\n    def initialize(*args)\n      # args := ([parent,] time_begin, time_end, items [, text_width] [, keys])\n      # time_begin := String of time format (e.g. \"1 january 2004\")\n      # time_end   := String of time format (e.g. \"1 january 2004\")\n      # items := Expected/maximum number of items\n      #          ( This determines the vertical spacing. )\n      if args[0].kind_of?(String)\n        @time_begin = args.shift\n        @time_end   = args.shift\n        @items      = args.shift\n\n        if args[0].kind_of?(Fixnum)\n          @text_width = args.shift\n        else\n          @text_width = None\n        end\n\n        super(*args) # create canvas widget\n      else\n        parent = args.shift\n\n        @time_begin = args.shift\n        @time_end   = args.shift\n        @items      = args.shift\n\n        if args[0].kind_of?(Fixnum)\n          @text_width = args.shift\n        else\n          @text_width = None\n        end\n\n        if parent.kind_of?(Tk::Canvas)\n          @path = parent.path\n        else\n          super(parent, *args) # create canvas widget\n        end\n      end\n\n      @chart = _create_chart\n    end\n\n    def _create_chart\n      p self.class::TkCommandNames[1] if $DEBUG\n      tk_call_without_enc(self.class::TkCommandNames[1], @path, \n                          @time_begin, @time_end, @items, @text_width)\n    end\n    private :_create_chart\n\n    def task(txt, time_begin, time_end, completed=0.0)\n      list(tk_call_without_enc(@chart, 'task', txt, time_begin, time_end, \n                               completed)).collect!{|id|\n        TkcItem.id2obj(self, id)\n      }\n    end\n\n    def milestone(txt, time, col=None)\n      tk_call_without_enc(@chart, 'milestone', txt, time, col)\n      self\n    end\n\n    def vertline(txt, time)\n      tk_call_without_enc(@chart, 'vertline', txt, time)\n      self\n    end\n\n    def connect(from_task, to_task)\n      from_task = array2tk_list(from_task) if from_task.kind_of?(Array)\n      to_task   = array2tk_list(to_task)   if to_task.kind_of?(Array)\n\n      tk_call_without_enc(@chart, 'connect', from_task, to_task)\n      self\n    end\n\n    def summary(txt, tasks)\n      tasks = array2tk_list(tasks) if tasks.kind_of?(Array)\n      tk_call_without_enc(@chart, 'summary', tasks)\n      self\n    end\n\n    def color_of_part(keyword, newcolor)\n      tk_call_without_enc(@chart, 'color', keyword, newcolor)\n      self\n    end\n\n    def font_of_part(keyword, newfont)\n      tk_call_without_enc(@chart, 'font', keyword, newfont)\n      self\n    end\n  end\n\n  ############################\n  class PlotSeries < TkObject\n    SeriesID_TBL = TkCore::INTERP.create_table\n\n    (Series_ID = ['series'.freeze, '00000'.taint]).instance_eval{\n      @mutex = Mutex.new\n      def mutex; @mutex; end\n      freeze\n    }\n    TkCore::INTERP.init_ip_env{\n      SeriesID_TBL.mutex.synchronize{ SeriesID_TBL.clear }\n    }\n\n    def self.id2obj(chart, id)\n      path = chart.path\n      SeriesID_TBL.mutex.synchronize{\n        if SeriesID_TBL[path]\n          SeriesID_TBL[path][id]? SeriesID_TBL[path][id]: id\n        else\n          id\n        end\n      }\n    end\n\n    def initialize(chart, keys=nil)\n      @parent = @chart_obj = chart\n      @ppath = @chart_obj.path\n      Series_ID.mutex.synchronize{\n        @path = @series = @id = Series_ID.join(TkCore::INTERP._ip_id_)\n        Series_ID[1].succ!\n      }\n      SeriesID_TBL.mutex.synchronize{\n        SeriesID_TBL[@ppath] ||= {}\n        SeriesID_TBL[@ppath][@id] = self\n      }\n      dataconfig(keys) if keys.kind_of?(Hash)\n    end\n\n    def plot(*args)\n      @chart_obj.plot(@series, *args)\n    end\n\n    def dataconfig(key, value=None)\n      @chart_obj.dataconfig(@series, key, value)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/ruler.rb",
    "content": "#\n#  tkextlib/tcllib/ruler.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * ruler widget\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget::ruler', '1.0')\nTkPackage.require('widget::ruler')\n\nmodule Tk::Tcllib\n  module Widget\n    class Ruler < TkWindow\n      PACKAGE_NAME = 'widget::ruler'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('widget::ruler')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n\nclass Tk::Tcllib::Widget::Ruler\n  TkCommandNames = ['::widget::ruler'.freeze].freeze\n\n  def __boolval_optkeys\n    ['showvalues', 'outline', 'grid']\n  end\n  private :__boolval_optkeys\n\n  def __numlistval_optkeys\n    ['interval', 'sizes']\n  end\n  private :__numlistval_optkeys\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def redraw\n    tk_send('redraw')\n    self\n  end\n\n  def shade(org, dest, frac)\n    tk_send('shade', org, dest, frac)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/screenruler.rb",
    "content": "#\n#  tkextlib/tcllib/screenruler.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * screenruler dialog\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget::screenruler', '1.1')\nTkPackage.require('widget::screenruler')\n\nmodule Tk::Tcllib\n  module Widget\n    class ScreenRuler < TkWindow\n      PACKAGE_NAME = 'widget::ruler'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('widget::screenruler')\n        rescue\n          ''\n        end\n      end\n    end\n    Screenruler = ScreenRuler\n  end\nend\n\nclass Tk::Tcllib::Widget::ScreenRuler\n  TkCommandNames = ['::widget::screenruler'.freeze].freeze\n\n  def __boolval_optkeys\n    ['topmost', 'reflect']\n  end\n  private :__boolval_optkeys\n\n  def __numlistval_optkeys\n    ['alpha']\n  end\n  private :__numlistval_optkeys\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def display\n    tk_send('display')\n    self\n  end\n  alias show display\n\n  def hide\n    tk_send('hide')\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/scrollwin.rb",
    "content": "#\n#  tkextlib/tcllib/scrollwin.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Scrolled widget\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget::scrolledwindow', '1.0')\nTkPackage.require('widget::scrolledwindow')\n\nmodule Tk::Tcllib\n  module Widget\n    class ScrolledWindow < TkWindow\n      PACKAGE_NAME = 'widget::scrolledwindow'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('widget::scrolledwindow')\n        rescue\n          ''\n        end\n      end\n    end\n    Scrolledwindow = ScrolledWindow\n  end\nend\n\nclass Tk::Tcllib::Widget::ScrolledWindow\n  TkCommandNames = ['::widget::scrolledwindow'.freeze].freeze\n\n  def __numlistval_optkeys\n    ['ipad']\n  end\n  private :__numlistval_optkeys\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def get_frame\n    window(tk_send('getframe'))\n  end\n\n  def set_widget(widget)\n    tk_send('setwidget', widget)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/style.rb",
    "content": "#\n#  tkextlib/tcllib/style.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * select and use some 'style' of option (resource) DB\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\nmodule Tk::Tcllib\n  module Style\n    PACKAGE_NAME = 'style'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('style')\n      rescue\n        ''\n      end\n    end\n\n    def self.not_available\n      fail RuntimeError, \"'tkextlib/tcllib/style' extension is not available on your current environment.\"\n    end\n\n    def self.names\n      Tk::Tcllib::Style.not_available\n    end\n\n    def self.use(style)\n      Tk::Tcllib::Style.not_available\n    end\n  end\nend\n\n# TkPackage.require('style', '0.1')\n# TkPackage.require('style', '0.3')\nTkPackage.require('style')\n\nmodule Tk::Tcllib\n  class << Style\n    undef not_available\n  end\n\n  module Style\n    extend TkCore\n\n    def self.names\n      tk_split_simplelist(tk_call('style::names'))\n    end\n\n    def self.use(style)\n      tk_call('style::use', style)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/superframe.rb",
    "content": "#\n#  tkextlib/tcllib/superframe.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Superframe widget - enhanced labelframe widget\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget::superframe', '1.0')\nTkPackage.require('widget::superframe')\n\nmodule Tk::Tcllib\n  module Widget\n    class SuperFrame < TkWindow\n      PACKAGE_NAME = 'widget::superframe'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('widget::superframe')\n        rescue\n          ''\n        end\n      end\n    end\n    Superframe = SuperlFrame\n  end\nend\n\nclass Tk::Tcllib::Widget::SuperFrame\n  TkCommandNames = ['::widget::superframe'.freeze].freeze\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def labelwidget\n    window(tk_send('labelwidget'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/swaplist.rb",
    "content": "#\n#  tkextlib/tcllib/swaplist.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * A dialog which allows a user to move options between two lists\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('swaplist', '0.1')\nTkPackage.require('swaplist')\n\nmodule Tk::Tcllib\n  class Swaplist_Dialog < TkWindow\n    PACKAGE_NAME = 'swaplist'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('swaplist')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\n\nclass Tk::Tcllib::Swaplist_Dialog\n  TkCommandNames = ['::swaplist::swaplist'.freeze].freeze\n  WidgetClassName = 'Swaplist'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.show(*args)\n    dialog = self.new(*args)\n    dialog.show\n    [dialog.status, dialog.value]\n  end\n  def self.display(*args)\n    self.show(*args)\n  end\n\n  def initialize(*args) \n    # args = (parent=nil, complete_list=[], selected_list=[], keys=nil)\n    keys = args.pop\n    if keys.kind_of?(Hash)\n      @selected_list = args.pop\n      @complete_list = args.pop\n      @keys = _symbolkey2str(keys)\n      args.push(keys)\n    else\n      @selected_list = keys\n      @complete_list = args.pop\n      @keys = {}\n    end\n\n    @selected_list = [] unless @selected_list\n    @complete_list = [] unless @complete_list\n\n    @variable = TkVariable.new\n    @status = nil\n\n    super(*args)\n  end\n\n  def create_self(keys)\n    # dummy\n  end\n  private :create_self\n\n  def show\n    @variable.value = ''\n    @status = bool(tk_call(self.class::TkCommandNames[0], \n                           @path, @variable, \n                           @complete_list, @selected_list, \n                           *hash_kv(@keys)))\n  end\n  alias display show\n\n  def status\n    @status\n  end\n\n  def value\n    @variable.list\n  end\n  alias selected value\n\n  def cget_strict(slot)\n    slot = slot.to_s\n    if slot == 'complete_list'\n      @complete_list\n    elsif slot == 'selected_list'\n      @selected_list\n    else\n      @keys[slot]\n    end\n  end\n  def cget(slot)\n    cget_strict(slot)\n  end\n\n  def configure(slot, value=None)\n    if slot.kind_of?(Hash)\n      slot.each{|k, v| configure(k, v)}\n    else\n      slot = slot.to_s\n      value = _symbolkey2str(value) if value.kind_of?(Hash)\n      if value && value != None\n        if slot == 'complete_list'\n          @complete_list = value\n        elsif slot == 'selected_list'\n          @selected_list = value\n        else\n          @keys[slot] = value\n        end\n      else\n        if slot == 'complete_list'\n          @complete_list = []\n        elsif slot == 'selected_list'\n          @selected_list = []\n        else\n          @keys.delete(slot)\n        end\n      end\n    end\n    self\n  end\n\n  def configinfo(slot = nil)\n    if slot\n      slot = slot.to_s\n      if slot == 'complete_list'\n        [ slot, nil, nil, nil, @complete_list ]\n      elsif slot == 'selected_list'\n        [ slot, nil, nil, nil, @selected_list ]\n      else\n        [ slot, nil, nil, nil, @keys[slot] ]\n      end\n    else\n      @keys.collect{|k, v| [ k, nil, nil, nil, v ] }           \\\n      << [ 'complete_list', nil, nil, nil, @complete_list ]   \\\n      << [ 'selected_list', nil, nil, nil, @selected_list ]\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/tablelist.rb",
    "content": "#\n#  tkextlib/tcllib/tablelist.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * A multi-column listbox\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# check Tile extension :: If already loaded, use tablelist_tile.\nunless defined? Tk::Tcllib::Tablelist_usingTile\n  Tk::Tcllib::Tablelist_usingTile = TkPackage.provide('tile')\nend\n\nif Tk::Tcllib::Tablelist_usingTile\n  # with Tile\n  require 'tkextlib/tcllib/tablelist_tile'\n\nelse\n  # without Tile\n\n  # TkPackage.require('Tablelist', '4.2')\n  TkPackage.require('Tablelist')\n\n  require 'tkextlib/tcllib/tablelist_core'\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/tablelist_core.rb",
    "content": "#\n#  tkextlib/tcllib/tablelist_core.rb\n#\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * This file is required by 'tkextlib/tcllib/tablelist.rb' or \n#     'tkextlib/tcllib/tablelist_tile.rb'.\n#\n\nmodule Tk\n  module Tcllib\n    class Tablelist < TkWindow\n      if Tk::Tcllib::Tablelist_usingTile\n        PACKAGE_NAME = 'Tablelist_tile'.freeze\n      else\n        PACKAGE_NAME = 'Tablelist'.freeze\n      end\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require(self.package_name)\n        rescue\n          ''\n        end\n      end\n\n      def self.use_Tile?\n        (Tk::Tcllib::Tablelist_usingTile)? true: false\n      end\n    end\n    TableList = Tablelist\n  end\nend\n\nmodule Tk::Tcllib::TablelistItemConfig\n  include TkItemConfigMethod\n\n  def _to_idx(idx)\n    if idx.kind_of?(Array)\n      idx.collect{|elem| _get_eval_string(elem)}.join(',')\n    else\n      idx\n    end\n  end\n  def _from_idx(idx)\n    return idx unless idx.kind_of?(String)\n\n    if idx[0] == ?@  # '@x,y'\n      idx\n    elsif idx =~ /([^,]+),([^,]+)/\n      row = $1, column = $2\n      [num_or_str(row), num_or_str(column)]\n    else \n      num_or_str(idx)\n    end\n  end\n  private :_to_idx, :_from_idx\n\n  def __item_cget_cmd(mixed_id)\n    [self.path, mixed_id[0] + 'cget', _to_idx(mixed_id[1])]\n  end\n  def __item_config_cmd(mixed_id)\n    [self.path, mixed_id[0] + 'configure', _to_idx(mixed_id[1])]\n  end\n\n  def cell_cget(tagOrId, option)\n    itemcget(['cell', tagOrId], option)\n  end\n  def cell_cget_strict(tagOrId, option)\n    itemcget_strict(['cell', tagOrId], option)\n  end\n  def cell_configure(tagOrId, slot, value=None)\n    itemconfigure(['cell', tagOrId], slot, value)\n  end\n  def cell_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['cell', tagOrId], slot)\n  end\n  def current_cell_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['cell', tagOrId], slot)\n  end\n  alias cellcget cell_cget\n  alias cellcget_strict cell_cget_strict\n  alias cellconfigure cell_configure\n  alias cellconfiginfo cell_configinfo\n  alias current_cellconfiginfo current_cell_configinfo\n\n  def column_cget(tagOrId, option)\n    itemcget(['column', tagOrId], option)\n  end\n  def column_cget_strict(tagOrId, option)\n    itemcget_strict(['column', tagOrId], option)\n  end\n  def column_configure(tagOrId, slot, value=None)\n    itemconfigure(['column', tagOrId], slot, value)\n  end\n  def column_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['column', tagOrId], slot)\n  end\n  def current_column_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['column', tagOrId], slot)\n  end\n  alias columncget column_cget\n  alias columncget_strict column_cget_strict\n  alias columnconfigure column_configure\n  alias columnconfiginfo column_configinfo\n  alias current_columnconfiginfo current_column_configinfo\n\n  def row_cget(tagOrId, option)\n    itemcget(['row', tagOrId], option)\n  end\n  def row_cget_strict(tagOrId, option)\n    itemcget_strict(['row', tagOrId], option)\n  end\n  def row_configure(tagOrId, slot, value=None)\n    itemconfigure(['row', tagOrId], slot, value)\n  end\n  def row_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['row', tagOrId], slot)\n  end\n  def current_row_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['row', tagOrId], slot)\n  end\n  alias rowcget row_cget\n  alias rowcget_strict row_cget_strict\n  alias rowconfigure row_configure\n  alias rowconfiginfo row_configinfo\n  alias current_rowconfiginfo current_row_configinfo\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\nend\n\nclass Tk::Tcllib::Tablelist\n  include Tk::Tcllib::TablelistItemConfig\n  include Scrollable\n\n  TkCommandNames = ['::tablelist::tablelist'.freeze].freeze\n  WidgetClassName = 'Tablelist'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  ##########################\n\n  def __numval_optkeys\n    super() + ['titlecolumns']\n  end\n  private :__numval_optkeys\n\n  def __strval_optkeys\n    super() + ['snipstring']\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    super() + [\n      'forceeditendcommand', 'movablecolumns', 'movablerows', \n      'protecttitlecolumns', 'resizablecolumns', \n      'showarrow', 'showlabels', 'showseparators'\n    ]\n  end\n  private :__boolval_optkeys\n\n  def __listval_optkeys\n    super() + ['columns']\n  end\n  private :__listval_optkeys\n\n  def __tkvariable_optkeys\n    super() + ['listvariable']\n  end\n  private :__tkvariable_optkeys\n\n  def __val2ruby_optkeys  # { key=>proc, ... }\n    # The method is used to convert a opt-value to a ruby's object.\n    # When get the value of the option \"key\", \"proc.call(value)\" is called.\n    super().update('stretch'=>proc{|v| (v == 'all')? v: simplelist(v)})\n  end\n  private :__val2ruby_optkeys\n\n  def __ruby2val_optkeys  # { key=>proc, ... }\n    # The method is used to convert a ruby's object to a opt-value.\n    # When set the value of the option \"key\", \"proc.call(value)\" is called.\n    # That is, \"-#{key} #{proc.call(value)}\".\n    super().update('stretch'=>proc{|v| \n                     (v.kind_of?(Array))? v.collect{|e| _to_idx(e)}: v\n                   })\n  end\n  private :__ruby2val_optkeys\n\n  def __font_optkeys\n    super() + ['labelfont']\n  end\n  private :__font_optkeys\n\n  ##########################\n\n  def __item_strval_optkeys(id)\n    if id[0] == 'cell'\n      super(id) + ['title']\n    else\n      super(id) - ['text'] + ['title']\n    end\n  end\n  private :__item_strval_optkeys\n\n  def __item_boolval_optkeys(id)\n    super(id) + [\n      'editable', 'hide', 'resizable', 'showarrow', 'stretchable', \n    ]\n  end\n  private :__item_boolval_optkeys\n\n  def __item_listval_optkeys(id)\n    if id[0] == 'cell'\n      super(id)\n    else\n      super(id) + ['text']\n    end\n  end\n  private :__item_listval_optkeys\n\n  def __item_font_optkeys(id)\n    # maybe need to override\n    super(id) + ['labelfont']\n  end\n  private :__item_font_optkeys\n\n  ##########################\n\n  def activate(index)\n    tk_send('activate', _to_idx(index))\n    self\n  end\n\n  def activate_cell(index)\n    tk_send('activatecell', _to_idx(index))\n    self\n  end\n  alias activatecell activate_cell \n\n  def get_attrib(name=nil)\n    if name && name != None\n      tk_send('attrib', name)\n    else\n      ret = []\n      lst = simplelist(tk_send('attrib'))\n      until lst.empty?\n        ret << ( [lst.shift] << lst.shift )\n      end\n      ret\n    end\n  end\n  def set_attrib(*args)\n    tk_send('attrib', *(args.flatten))\n    self\n  end\n\n  def bbox(index)\n    list(tk_send('bbox', _to_idx(index)))\n  end\n\n  def bodypath\n    window(tk_send('bodypath'))\n  end\n\n  def bodytag\n    TkBindTag.new_by_name(tk_send('bodytag'))\n  end\n\n  def cancel_editing \n    tk_send('cancelediting')\n    self\n  end\n  alias cancelediting cancel_editing\n\n  def cellindex(idx)\n    _from_idx(tk_send('cellindex', _to_idx(idx)))\n  end\n\n  def cellselection_anchor(idx)\n    tk_send('cellselection', 'anchor', _to_idx(idx))\n    self\n  end\n\n  def cellselection_clear(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('cellselection', 'clear', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('cellselection', 'clear', first, last)\n    end\n    self\n  end\n\n  def cellselection_includes(idx)\n    bool(tk_send('cellselection', 'includes', _to_idx(idx)))\n  end\n\n  def cellselection_set(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('cellselection', 'set', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('cellselection', 'set', first, last)\n    end\n    self\n  end\n\n  def columncount\n    number(tk_send('columncount'))\n  end\n\n  def columnindex(idx)\n    number(tk_send('columnindex', _to_idx(idx)))\n  end\n\n  def containing(y)\n    idx = num_or_str(tk_send('containing', y))\n    (idx.kind_of?(Fixnum) && idx < 0)?  nil: idx\n  end\n\n  def containing_cell(x, y)\n    idx = _from_idx(tk_send('containingcell', x, y))\n    if idx.kind_of?(Array)\n      [\n        ((idx[0].kind_of?(Fixnum) && idx[0] < 0)?  nil: idx[0]), \n        ((idx[1].kind_of?(Fixnum) && idx[1] < 0)?  nil: idx[1])\n      ]\n    else\n      idx\n    end\n  end\n  alias containingcell containing_cell\n\n  def containing_column(x)\n    idx = num_or_str(tk_send('containingcolumn', x))\n    (idx.kind_of?(Fixnum) && idx < 0)?  nil: idx\n  end\n  alias containingcolumn containing_column\n\n  def curcellselection\n    simplelist(tk_send('curcellselection')).collect!{|idx| _from_idx(idx)}\n  end\n\n  def curselection\n    list(tk_send('curselection'))\n  end\n\n  def delete_items(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('delete', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('delete', first, last)\n    end\n    self\n  end\n  alias delete delete_items\n  alias deleteitems delete_items\n\n  def delete_columns(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('deletecolumns', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('deletecolumns', first, last)\n    end\n    self\n  end\n  alias deletecolumns delete_columns\n\n  def edit_cell(idx)\n    tk_send('editcell', _to_idx(idx))\n    self\n  end\n  alias editcell edit_cell\n\n  def editwinpath\n    window(tk_send('editwinpath'))\n  end\n\n  def entrypath\n    window(tk_send('entrypath'))\n  end\n\n  def fill_column(idx, txt)\n    tk_send('fillcolumn', _to_idx(idx), txt)\n    self\n  end\n  alias fillcolumn fill_column\n\n  def finish_editing\n    tk_send('finishediting')\n    self\n  end\n  alias finishediting finish_editing\n\n  def get(first, last=nil)\n    if first.kind_of?(Array)\n      simplelist(tk_send('get', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) }\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      simplelist(tk_send('get', first, last))\n    end\n  end\n\n  def get_cells(first, last=nil)\n    if first.kind_of?(Array)\n      simplelist(tk_send('getcells', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) }\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      simplelist(tk_send('getcells', first, last))\n    end\n  end\n  alias getcells get_cells\n\n  def get_columns(first, last=nil)\n    if first.kind_of?(Array)\n      simplelist(tk_send('getcolumns', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) }\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      simplelist(tk_send('getcolumns', first, last))\n    end\n  end\n  alias getcolumns get_columns\n\n  def get_keys(first, last=nil)\n    if first.kind_of?(Array)\n      simplelist(tk_send('getkeys', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) }\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      simplelist(tk_send('getkeys', first, last))\n    end\n  end\n  alias getkeys get_keys\n\n  def imagelabelpath(idx)\n    window(tk_send('imagelabelpath', _to_idx(idx)))\n  end\n\n  def index(idx)\n    number(tk_send('index', _to_idx(idx)))\n  end\n\n  def insert(idx, *items)\n    tk_send('insert', _to_idx(idx), *items)\n    self\n  end\n\n  def insert_columnlist(idx, columnlist)\n    tk_send('insertcolumnlist', _to_idx(idx), columnlist)\n    self\n  end\n  alias insertcolumnlist insert_columnlist\n\n  def insert_columns(idx, *args)\n    tk_send('insertcolums', _to_idx(idx), *args)\n    self\n  end\n  alias insertcolumns insert_columns\n\n  def insert_list(idx, list)\n    tk_send('insertlist', _to_idx(idx), list)\n    self\n  end\n  alias insertlist insert_list\n\n  def itemlistvar\n    TkVarAccess.new(tk_send('itemlistvar'))\n  end\n\n  def labelpath(idx)\n    window(tk_send('labelpath', _to_idx(idx)))\n  end\n\n  def labels\n    simplelist(tk_send('labels'))\n  end\n\n  def move(src, target)\n    tk_send('move', _to_idx(src), _to_idx(target))\n    self\n  end\n\n  def move_column(src, target)\n    tk_send('movecolumn', _to_idx(src), _to_idx(target))\n    self\n  end\n  alias movecolumn move_column\n\n  def nearest(y)\n    _from_idx(tk_send('nearest', y))\n  end\n\n  def nearest_cell(x, y)\n    _from_idx(tk_send('nearestcell', x, y))\n  end\n  alias nearestcell nearest_cell\n\n  def nearest_column(x)\n    _from_idx(tk_send('nearestcolumn', x))\n  end\n  alias nearestcolumn nearest_column\n\n  def reject_input\n    tk_send('rejectinput')\n    self\n  end\n  alias rejectinput reject_input\n\n  def reset_sortinfo\n    tk_send('resetsortinfo')\n    self\n  end\n  alias resetsortinfo reset_sortinfo\n\n  def scan_mark(x, y)\n    tk_send('scan', 'mark', x, y)\n    self\n  end\n\n  def scan_dragto(x, y)\n    tk_send('scan', 'dragto', x, y)\n    self\n  end\n\n  def see(idx)\n    tk_send('see', _to_idx(idx))\n    self\n  end\n\n  def see_cell(idx)\n    tk_send('seecell', _to_idx(idx))\n    self\n  end\n  alias seecell see_cell\n\n  def see_column(idx)\n    tk_send('seecolumn', _to_idx(idx))\n    self\n  end\n  alias seecolumn see_column\n\n  def selection_anchor(idx)\n    tk_send('selection', 'anchor', _to_idx(idx))\n    self\n  end\n\n  def selection_clear(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('selection', 'clear', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('selection', 'clear', first, last)\n    end\n    self\n  end\n\n  def selection_includes(idx)\n    bool(tk_send('selection', 'includes', _to_idx(idx)))\n  end\n\n  def selection_set(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('selection', 'set', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('selection', 'set', first, last)\n    end\n    self\n  end\n\n  def separatorpath(idx=nil)\n    if idx\n      window(tk_send('separatorpath', _to_idx(idx)))\n    else\n      window(tk_send('separatorpath'))\n    end\n  end\n\n  def separators\n    simplelist(tk_send('separators')).collect!{|w| window(w)}\n  end\n\n  def size\n    number(tk_send('size'))\n  end\n\n  def sort(order=nil)\n    if order\n      order = order.to_s\n      order = '-' << order if order[0] != ?-\n      if order.length < 2\n        order = nil\n      end\n    end\n    if order\n      tk_send('sort', order)\n    else\n      tk_send('sort')\n    end\n    self\n  end\n  def sort_increasing\n    tk_send('sort', '-increasing')\n    self\n  end\n  def sort_decreasing\n    tk_send('sort', '-decreasing')\n    self\n  end\n\n  DEFAULT_sortByColumn_cmd = '::tablelist::sortByColumn'\n\n  def sort_by_column(idx, order=nil)\n    if order\n      order = order.to_s\n      order = '-' << order if order[0] != ?-\n      if order.length < 2\n        order = nil\n      end\n    end\n    if order\n      tk_send('sortbycolumn', _to_idx(idx), order)\n    else\n      tk_send('sortbycolumn', _to_idx(idx))\n    end\n    self\n  end\n  def sort_by_column_increasing(idx)\n    tk_send('sortbycolumn', _to_idx(idx), '-increasing')\n    self\n  end\n  def sort_by_column_decreasing(idx)\n    tk_send('sortbycolumn', _to_idx(idx), '-decreasing')\n    self\n  end\n\n  def sortcolumn\n    idx = num_or_str(tk_send('sortcolum'))\n    (idx.kind_of?(Fixnum) && idx < 0)?  nil: idx\n  end\n\n  def sortorder\n    tk_send('sortorder')\n  end\n\n  def toggle_visibility(first, last=nil)\n    if first.kind_of?(Array)\n      tk_send('togglevisibility', first.collect{|idx| _to_idx(idx)})\n    else\n      first = _to_idx(first)\n      last = (last)? _to_idx(last): first\n      tk_send('togglevisibility', first, last)\n    end\n    self\n  end\n  alias togglevisibility toggle_visibility\n\n  def windowpath(idx)\n    window(tk_send('windowpath', _to_idx(idx)))\n  end\nend\n\nclass << Tk::Tcllib::Tablelist\n  ############################################################\n  # helper commands\n  def getTablelistPath(descendant)\n    window(Tk.tk_call('::tablelist::getTablelistPath', descendant))\n  end\n\n  def convEventFields(descendant, x, y)\n    window(Tk.tk_call('::tablelist::convEventFields', descendant, x, y))\n  end\n\n\n  ############################################################\n  # with the BWidget package \n  def addBWidgetEntry(name=None)\n    Tk.tk_call('::tablelist::addBWidgetEntry', name)\n  end\n\n  def addBWidgetSpinBox(name=None)\n    Tk.tk_call('::tablelist::addBWidgetSpinBox', name)\n  end\n\n  def addBWidgetComboBox(name=None)\n    Tk.tk_call('::tablelist::addBWidgetComboBox', name)\n  end\n\n\n  ############################################################\n  # with the Iwidgets ([incr Widgets]) package \n  def addIncrEntryfield(name=None)\n    Tk.tk_call('::tablelist::addIncrEntry', name)\n  end\n\n  def addIncrDateTimeWidget(type, seconds=false, name=None)\n    # type := 'datefield'|'dateentry'|timefield'|'timeentry'\n    if seconds && seconds != None\n      seconds = '-seconds'\n    else\n      seconds = None\n    end\n    Tk.tk_call('::tablelist::addDateTimeWidget', type, seconds, name)\n  end\n\n  def addIncrSpinner(name=None)\n    Tk.tk_call('::tablelist::addIncrSpinner', name)\n  end\n\n  def addIncrSpinint(name=None)\n    Tk.tk_call('::tablelist::addIncrSpinint', name)\n  end\n\n  def addIncrCombobox(name=None)\n    Tk.tk_call('::tablelist::addIncrCombobox', name)\n  end\n\n\n  ############################################################\n  # with Bryan Oakley's combobox package\n  def addOakleyCombobox(name=None)\n    Tk.tk_call('::tablelist::addOakleyCombobox', name)\n  end\n\n  ############################################################\n  # with the multi-entry package Mentry is a library extension\n  def addDateMentry(format, separator, gmt=false, name=None)\n    if gmt && gmt != None\n      gmt = '-gmt'\n    else\n      gmt = None\n    end\n    Tk.tk_call('::tablelist::addDateMentry', format, separator, gmt, name)\n  end\n\n  def addTimeMentry(format, separator, gmt=false, name=None)\n    if gmt && gmt != None\n      gmt = '-gmt'\n    else\n      gmt = None\n    end\n    Tk.tk_call('::tablelist::addTimeMentry', format, separator, gmt, name)\n  end\n\n  def addFixedPointMentry(count1, count2, comma=false, name=None)\n    if comma && comma != None\n      comma = '-comma'\n    else\n      comma = None\n    end\n    Tk.tk_call('::tablelist::addFixedPoingMentry', count1, count2, comma, name)\n  end\n\n  def addIPAddrMentry(name=None)\n    Tk.tk_call('::tablelist::addIPAddrMentry', name)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb",
    "content": "#\n#  tkextlib/tcllib/tablelist_tlie.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * A multi-column listbox\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('tablelist_tile', '4.2')\nTkPackage.require('Tablelist_tile')\n\nunless defined? Tk::Tcllib::Tablelist_usingTile\n  Tk::Tcllib::Tablelist_usingTile = true\nend\n\nrequrie 'tkextlib/tcllib/tablelist_core'\n\nmodule Tk\n  module Tcllib\n    Tablelist_Tile = Tablelist\n    TableList_Tile = Tablelist\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/tkpiechart.rb",
    "content": "#\n#  tkextlib/tcllib/tkpiechart.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Create 2D or 3D pies with labels in Tcl canvases\n#\n\nrequire 'tk'\nrequire 'tk/canvas'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('tkpiechart', '6.6')\nTkPackage.require('tkpiechart')\n\nmodule Tk\n  module Tcllib\n    module Tkpiechart\n    end\n  end\nend\n\nmodule Tk::Tcllib::Tkpiechart\n  PACKAGE_NAME = 'tkpiechart'.freeze\n  def self.package_name\n    PACKAGE_NAME\n  end\n\n  def self.package_version\n    begin\n      TkPackage.require('tkpiechart')\n    rescue\n      ''\n    end\n  end\n\n  module ConfigMethod\n    include TkConfigMethod\n\n    def __pathname\n      self.path + ';' + self.tag\n    end\n    private :__pathname\n\n    def __cget_cmd\n      ['::switched::cget', self.tag]\n    end\n\n    def __config_cmd\n      ['::switched::configure', self.tag]\n    end\n    private :__config_cmd\n\n    def __configinfo_struct\n      {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, \n        :default_value=>1, :current_value=>2}\n    end\n    private :__configinfo_struct\n\n    def __boolval_optkeys\n      super() << 'select' << 'autoupdate' << 'selectable'\n    end\n    private :__boolval_optkeys\n\n    def __strval_optkeys\n      super() << 'bordercolor' << 'textbackground' << \n        'widestvaluetext' << 'title'\n    end\n    private :__strval_optkeys\n\n    def __listval_optkeys\n      super() << 'colors'\n    end\n    private :__listval_optkeys\n  end\n\n  ####################################\n  class PieChartObj < TkcItem\n    include ConfigMethod\n\n    def __font_optkeys\n      ['titlefont']\n    end\n    private :__font_optkeys\n  end\n\n  ####################################\n  class Pie < TkcItem\n    include ConfigMethod\n\n    def create_self(x, y, width, height, keys=None)\n      if keys and keys != None\n        @tag_key = tk_call_without_enc('::stooop::new', 'pie', \n                                       @c, x, y, *hash_kv(keys, true))\n      else\n        @tag_key = tk_call_without_enc('::stooop::new', 'pie', @c, x, y)\n      end\n\n      @slice_tbl = {}\n\n      id = \"pie(#{@tag_key})\"\n\n      @tag = @tag_pie = TkcNamedTag(@c, id)\n      @tag_slices = TkcNamedTag(@c, \"pieSlices(#{@tag_key})\")\n\n      id\n    end\n    private :create_self\n\n    def tag_key\n      @tag_key\n    end\n    def tag\n      @tag\n    end\n    def canvas\n      @c\n    end\n    def _entry_slice(slice)\n      @slice_tbl[slice.to_eval] = slice\n    end\n    def _delete_slice(slice)\n      @slice_tbl.delete(slice.to_eval)\n    end\n\n    def delete\n      tk_call_without_enc('::stooop::delete', @tag_key)\n      CItemID_TBL.mutex.synchronize{\n        CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]\n      }\n      self\n    end\n\n    def new_slice(text=None)\n      Slice.new(self, text)\n    end\n\n    def delete_slice(slice)\n      unless slice.kind_of?(Slice)\n        unless (slice = @slice_tbl[slice])\n          return tk_call_without_enc('pie::deleteSlice', @tag_key, slice)\n        end\n      end\n      unless slice.kind_of?(Slice) && slice.pie == self\n        fail ArgumentError, \"argument is not a slice of self\"\n      end\n      slice.delete\n    end\n\n    def selected_slices\n      tk_split_simplelist(tk_call_without_enc('pie::selectedSlices', \n                                              @tag_key)).collect{|slice|\n        @slice_tbl[slice] || Slice.new(:no_create, self, slice)\n      }\n    end\n  end\n\n  ####################################\n  class Slice < TkcItem\n    include ConfigMethod\n\n    def __config_cmd\n      ['::switched::configure', self.tag]\n    end\n    private :__config_cmd\n\n    #------------------------\n\n    def initialize(pie, *args)\n      unless pie.kind_of?(Pie) && pie != :no_create\n        fail ArgumentError, \"expects TkPiechart::Pie for 1st argument\"\n      end\n\n      if pie == :no_create\n        @pie, @tag_key = args\n      else\n        text = args[0] || None\n        @pie = pie\n        @tag_key = tk_call_without_enc('pie::newSlice', @pie.tag_key, text)\n      end\n      @parent = @c = @pie.canvas\n      @path = @parent.path\n\n      @pie._entry_slice(self)\n\n      @id = \"slices(#{@tag_key})\"\n      @tag = TkcNamedTag.new(@pie.canvas, @id)\n\n      CItemID_TBL.mutex.synchronize{\n        CItemID_TBL[@path] = {} unless CItemID_TBL[@path]\n        CItemID_TBL[@path][@id] = self\n      }\n    end\n\n    def tag_key\n      @tag_key\n    end\n    def tag\n      @tag\n    end\n    def pie\n      @pie\n    end\n\n    def delete\n      tk_call_without_enc('pie::deleteSlice', @pie.tag_key, @tag_key)\n      CItemID_TBL.mutex.synchronize{\n        CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]\n      }\n      @pie._delete_slice(self)\n      self\n    end\n\n    def size(share, disp=None)\n      tk_call_without_enc('pie::sizeSlice', \n                          @pie.tag_key, @tag_key, share, disp)\n      self\n    end\n\n    def label(text)\n      tk_call_without_enc('pie::labelSlice', @pie.tag_key, @tag_key, text)\n      self\n    end\n  end\n\n  ####################################\n  class BoxLabeler < TkcItem\n    include ConfigMethod\n\n    def __config_cmd\n      ['::switched::configure', self.tag]\n    end\n    private :__config_cmd\n\n    #------------------------\n\n    def create_self(keys=None)\n      if keys and keys != None\n        @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler', \n                                       *hash_kv(keys, true))\n      else\n        @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler')\n      end\n\n      id = \"pieBoxLabeler(#{@tag_key})\"\n      @tag = TkcNamedTag(@c, id)\n\n      id\n    end\n    private :create_self\n  end\n\n  ####################################\n  class PeripheralLabeler < TkcItem\n    include ConfigMethod\n\n    def __font_optkeys\n      ['font', 'smallfont']\n    end\n    private :__font_optkeys\n\n    def __config_cmd\n      ['::switched::configure', self.tag]\n    end\n    private :__config_cmd\n\n    #------------------------\n\n    def create_self(keys=None)\n      if keys and keys != None\n        @tag_key = tk_call_without_enc('::stooop::new', \n                                       'piePeripheralLabeler', \n                                       *hash_kv(keys, true))\n      else\n        @tag_key = tk_call_without_enc('::stooop::new', 'piePeripheralLabeler')\n      end\n\n      id = \"piePeripheralLabeler(#{@tag_key})\"\n      @tag = TkcNamedTag(@c, id)\n\n      id\n    end\n    private :create_self\n  end\n\n  ####################################\n  class Label < TkcItem\n    include ConfigMethod\n\n    def __config_cmd\n      ['::switched::configure', self.tag]\n    end\n    private :__config_cmd\n\n    #------------------------\n\n    def create_self(x, y, keys=None)\n      if keys and keys != None\n        @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel', \n                                       @c, x, y, width, height, \n                                       *hash_kv(keys, true))\n      else\n        @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel', \n                                       @c, x, y, width, height)\n      end\n\n      id = \"canvasLabel(#{@tag_key})\"\n      @tag = TkcNamedTag(@c, id)\n\n      id\n    end\n    private :create_self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/tooltip.rb",
    "content": "#\n#  tkextlib/tcllib/tooltip.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * Provides tooltips, a small text message that is displayed when the \n#     mouse hovers over a widget.\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('tooltip', '1.1')\nTkPackage.require('tooltip')\n\nmodule Tk::Tcllib\n  module Tooltip\n    PACKAGE_NAME = 'tooltip'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('tooltip')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\nmodule Tk::Tcllib::Tooltip\n  extend TkCore\n\n  WidgetClassName = 'Tooltip'.freeze\n  def self.database_classname\n    self::WidgetClassName\n  end\n  def self.database_class\n    WidgetClassNames[self::WidgetClassName]\n  end\n\n  def self.clear(glob_path_pat = None)\n    self.clear_glob(glob_path_pat)\n  end\n\n  def self.clear_glob(glob_path_pat)\n    tk_call_without_enc('::tooltip::tooltip', 'clear', glob_path_pat)\n  end\n\n  def self.clear_widgets(*args)\n    self.clear_glob(\"{#{args.collect{|w| _get_eval_string(w)}.join(',')}}\")\n  end\n\n  def self.clear_children(*args)\n    self.clear_glob(\"{#{args.collect{|w| s = _get_eval_string(w); \"#{s},#{s}.*\"}.join(',')}}\")\n  end\n\n  def self.delay(millisecs=None)\n    number(tk_call_without_enc('::tooltip::tooltip', 'delay', millisecs))\n  end\n  def self.delay=(millisecs)\n    self.delay(millisecs)\n  end\n\n  def self.disable\n    tk_call_without_enc('::tooltip::tooltip', 'disable')\n    false\n  end\n  def self.off\n    self.disable\n  end\n\n  def self.enable\n    tk_call_without_enc('::tooltip::tooltip', 'enable')\n    true\n  end\n  def self.on\n    self.enable\n  end\n\n  def self.register(widget, msg, keys=nil)\n    if keys.kind_of?(Hash)\n      args = hash_kv(keys) << msg\n    else\n      args = msg\n    end\n    tk_call_without_enc('::tooltip::tooltip', widget.path, *args)\n  end\n\n  def self.erase(widget)\n    tk_call_without_enc('::tooltip::tooltip', widget.path, '')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib/widget.rb",
    "content": "#\n#  tkextlib/tcllib/widget.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#   * Part of tcllib extension\n#   * megawidget package that uses snit as the object system (snidgets)\n#\n\nrequire 'tk'\nrequire 'tkextlib/tcllib.rb'\n\n# TkPackage.require('widget', '3.0')\nTkPackage.require('widget')\n\nmodule Tk::Tcllib\n  module Widget\n    PACKAGE_NAME = 'widget'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('widget')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\nmodule Tk::Tcllib::Widget\n  autoload :Dialog,             'tkextlib/tcllib/dialog'\n\n  autoload :Panelframe,         'tkextlib/tcllib/panelframe'\n  autoload :PanelFrame,         'tkextlib/tcllib/panelframe'\n\n  autoload :Ruler,              'tkextlib/tcllib/ruler'\n\n  autoload :Screenruler,        'tkextlib/tcllib/screenruler'\n  autoload :ScreenRuler,        'tkextlib/tcllib/screenruler'\n\n  autoload :Scrolledwindow,     'tkextlib/tcllib/scrollwin'\n  autoload :ScrolledWindow,     'tkextlib/tcllib/scrollwin'\n\n  autoload :Superframe,         'tkextlib/tcllib/superframe'\n  autoload :SuperFrame,         'tkextlib/tcllib/superframe'\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tcllib.rb",
    "content": "#\n#  tcllib extension support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tcllib/setup.rb'\n\nerr = ''\n\n# package:: autoscroll\ntarget = 'tkextlib/tcllib/autoscroll'\nbegin\n  require target\nrescue => e\n  err << \"\\n  ['\" << target << \"'] \"  << e.class.name << ' : ' << e.message\nend\n\n# package:: cursor\ntarget = 'tkextlib/tcllib/cursor'\nbegin\n  require target\nrescue => e\n  err << \"\\n  ['\" << target << \"'] \"  << e.class.name << ' : ' << e.message\nend\n\n# package:: style\ntarget = 'tkextlib/tcllib/style'\nbegin\n  require target\nrescue => e\n  err << \"\\n  ['\" << target << \"'] \"  << e.class.name << ' : ' << e.message\nend\n\n# autoload\nmodule Tk\n  module Tcllib\n    TkComm::TkExtlibAutoloadModule.unshift(self)\n\n    # package:: ctext\n    autoload :CText,              'tkextlib/tcllib/ctext'\n\n    # package:: getstring\n    autoload :GetString_Dialog,   'tkextlib/tcllib/getstring'\n\n    # package:: history\n    autoload :History,            'tkextlib/tcllib/history'\n\n    # package:: datefield\n    autoload :Datefield,          'tkextlib/tcllib/datefield'\n    autoload :DateField,          'tkextlib/tcllib/datefield'\n\n    # package:: ico\n    autoload :ICO,                'tkextlib/tcllib/ico'\n\n    # package:: ipentry\n    autoload :IP_Entry,           'tkextlib/tcllib/ip_entry'\n    autoload :IPEntry,            'tkextlib/tcllib/ip_entry'\n\n    # package:: swaplist\n    autoload :Swaplist_Dialog,    'tkextlib/tcllib/swaplist'\n\n    # package:: Plotchart\n    autoload :Plotchart,          'tkextlib/tcllib/plotchart'\n\n    # package:: tablelist\n    autoload :Tablelist,           'tkextlib/tcllib/tablelist'\n    autoload :TableList,           'tkextlib/tcllib/tablelist'\n    autoload :Tablelist_Tile,      'tkextlib/tcllib/tablelist_tile'\n    autoload :TableList_Tile,      'tkextlib/tcllib/tablelist_tile'\n\n    # package:: tkpiechart\n    autoload :Tkpiechart,         'tkextlib/tcllib/tkpiechart'\n\n    # package:: tooltip\n    autoload :Tooltip,            'tkextlib/tcllib/tooltip'\n\n    # package:: widget\n    autoload :Wdiget,             'tkextlib/tcllib/widget'\n  end\nend\n\nif $VERBOSE && !err.empty?\n  warn(\"Warning: some sub-packages are failed to require : \" + err)\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tclx/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tclx/tclx.rb",
    "content": "#\n#  tclx/tclx.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tclx/setup.rb'\n\n# TkPackage.require('Tclx', '8.0')\nTkPackage.require('Tclx')\n\nmodule Tk\n  module TclX\n    PACKAGE_NAME = 'Tclx'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Tclx')\n      rescue\n        ''\n      end\n    end\n\n    def self.infox(*args)\n      Tk.tk_call('infox', *args)\n    end\n\n    def self.signal(*args)\n      warn(\"Warning: Don't recommend to use TclX's 'signal' command. Please use Ruby's 'Signal.trap' method\")\n      Tk.tk_call('signal', *args)\n    end\n\n    def self.signal_restart(*args)\n      warn(\"Warning: Don't recommend to use TclX's 'signal' command. Please use Ruby's 'Signal.trap' method\")\n      Tk.tk_call('signal', '-restart', *args)\n    end\n\n    ##############################\n\n    class XPG3_MsgCat\n      class << self\n        alias open new\n      end\n\n      def initialize(catname, fail_mode=false)\n        if fail_mode\n          @msgcat_id = Tk.tk_call('catopen', '-fail', catname)\n        else\n          @msgcat_id = Tk.tk_call('catopen', '-nofail', catname)\n        end\n      end\n\n      def close(fail_mode=false)\n        if fail_mode\n          Tk.tk_call('catclose', '-fail', @msgcat_id)\n        else\n          Tk.tk_call('catclose', '-nofail', @msgcat_id)\n        end\n        self\n      end\n\n      def get(setnum, msgnum, defaultstr)\n        Tk.tk_call('catgets', @msgcat_id, setnum, msgnum, defaultstr)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tclx.rb",
    "content": "#\n#  TclX support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tclx/setup.rb'\n\n# load library\nrequire 'tkextlib/tclx/tclx'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/dialog.rb",
    "content": "#\n#  ttk::dialog  (tile-0.7+)\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class Dialog < TkWindow\n    end\n  end\nend\n\nclass Tk::Tile::Dialog\n  TkCommandNames = ['::ttk::dialog'.freeze].freeze\n\n  def self.show(*args)\n    dialog = self.new(*args)\n    dialog.show\n    [dialog.status, dialog.value]\n  end\n  def self.display(*args)\n    self.show(*args)\n  end\n\n  def self.define_dialog_type(name, keys)\n    Tk.tk_call('::ttk::dialog::define', name, keys)\n    name\n  end\n\n  def self.style(*args)\n    ['Dialog', *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\n\n  #########################\n\n  def initialize(keys={})\n    @keys = _symbolkey2str(keys)\n    super(*args)\n  end\n\n  def create_self(keys)\n    # dummy\n  end\n  private :create_self\n\n  def show\n    tk_call(self.class::TkCommandNames[0], @path, *hash_kv(@keys))\n  end\n  alias display show\n\n  def client_frame\n    window(tk_call_without_enc('::ttk::dialog::clientframe', @path))\n  end\n\n  def cget_strict(slot)\n    @keys[slot.to_s]\n  end\n  def cget(slot)\n    @keys[slot.to_s]\n  end\n=begin\n  def cget(slot)\n    unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      cget_strict(slot)\n    else\n      cget_strict(slot) rescue nil\n    end\n  end\n=end\n\n  def configure(slot, value=None)\n    if slot.kind_of?(Hash)\n      slot.each{|k, v| configure(k, v)}\n    else\n      slot = slot.to_s\n      value = _symbolkey2str(value) if value.kind_of?(Hash)\n      if value && value != None\n        @keys[slot] = value\n      else\n        @keys.delete(slot)\n      end\n    end\n    self\n  end\n\n  def configinfo(slot = nil)\n    if slot\n      slot = slot.to_s\n      [ slot, nil, nil, nil, @keys[slot] ]\n    else\n      @keys.collect{|k, v| [ k, nil, nil, nil, v ] }\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/sizegrip.rb",
    "content": "#\n#  ttk::sizegrip widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class SizeGrip < TkWindow\n    end\n    Sizegrip = SizeGrip\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Sizegrip, :TkSizegrip, :TkSizeGrip)\n\n\nclass Tk::Tile::SizeGrip < TkWindow\n  include Tk::Tile::TileWidget\n\n  TkCommandNames = ['::ttk::sizegrip'.freeze].freeze\n  WidgetClassName = 'TSizegrip'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/style.rb",
    "content": "#\n#  style commands\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    module Style\n    end\n  end\nend\n\nmodule Tk::Tile::Style\n  extend TkCore\nend\n\nclass << Tk::Tile::Style\n  if Tk::Tile::TILE_SPEC_VERSION_ID < 8\n    TkCommandNames = ['style'.freeze].freeze\n\n    # --- Tk::Tile::Style.__define_wrapper_proc_for_compatibility__! ---\n    # On Ttk (Tile) extension, 'style' command has imcompatible changes \n    # depend on the version of the extention. It requires modifying the \n    # Tcl/Tk scripts to define local styles. The rule for modification \n    # is a simple one. But, if users want to keep compatibility between \n    # versions of the extension, they will have to contrive to do that. \n    # It may be troublesome, especially for Ruby/Tk users.\n    # This method may help such work. This method make some definitions \n    # on the Tcl/Tk interpreter to work with different version of style \n    # command format. Please give attention to use this method. It may \n    # conflict with some definitions on Tcl/Tk scripts. \n    if Tk::Tile::TILE_SPEC_VERSION_ID < 7\n      def __define_wrapper_proc_for_compatibility__!\n        __define_themes_and_setTheme_proc__!\n\n        unless Tk.info(:commands, '::ttk::style').empty?\n          # fail RuntimeError,\n          #      \"can't define '::ttk::style' command (already exist)\"\n\n          # do nothing !!!\n          warn \"Warning: can't define '::ttk::style' command (already exist)\" if $DEBUG\n          return\n        end\n        TkCore::INTERP.add_tk_procs('::ttk::style', 'args', <<-'EOS')\n        if [string equal [lrange $args 0 1] {element create}] {\n          if [string equal [lindex $args 3] image] {\n            set spec [lindex $args 4]\n            set map  [lrange $spec 1 end]\n            if [llength $map] {\n              # return [eval [concat [list ::style element create [lindex $args 2] image [lindex $spec 0] -map $map] [lrange $args 5 end]]]\n              return [uplevel 1 [list ::style element create [lindex $args 2] image [lindex $spec 0] -map $map] [lrange $args 5 end]]\n            }\n          }\n        }\n        # return [eval \"::style $args\"]\n        return [uplevel 1 ::style $args]\n      EOS\n        #########################\n      end\n    else ### TILE_SPEC_VERSION_ID == 7\n      def __define_wrapper_proc_for_compatibility__!\n        __define_themes_and_setTheme_proc__!\n\n        unless Tk.info(:commands, '::ttk::style').empty?\n          # fail RuntimeError,\n          #     \"can't define '::ttk::style' command (already exist)\"\n\n          # do nothing !!!\n          warn \"Warning: can't define '::ttk::style' command (already exist)\" if $DEBUG\n          return\n        end\n        TkCore::INTERP.add_tk_procs('::ttk::style', 'args', <<-'EOS')\n        if [string equal [lrange $args 0 1] {element create}] {\n          if [string equal [lindex $args 3] image] {\n            set spec [lindex $args 4]\n            set map  [lrange $spec 1 end]\n            if [llength $map] {\n              # return [eval [concat [list ::style element create [lindex $args 2] image [lindex $spec 0] -map $map] [lrange $args 5 end]]]\n              return [uplevel 1 [list ::style element create [lindex $args 2] image [lindex $spec 0] -map $map] [lrange $args 5 end]]]\n            }\n          }\n        } elseif [string equal [lindex $args 0] default] {\n          # return [eval \"::style [lreplace $args 0 0 configure]\"]\n          return [uplevel 1 ::style [lreplace $args 0 0 configure]]\n        }\n        # return [eval \"::style $args\"]\n        return [uplevel 1 ::style $args]\n      EOS\n        #########################\n      end\n    end\n  else ### TILE_SPEC_VERSION_ID >= 8\n    TkCommandNames = ['::ttk::style'.freeze].freeze\n\n    def __define_wrapper_proc_for_compatibility__!\n      __define_themes_and_setTheme_proc__!\n\n      unless Tk.info(:commands, '::style').empty?\n        # fail RuntimeError, \"can't define '::style' command (already exist)\"\n\n        # do nothing !!!\n        warn \"Warning: can't define '::style' command (already exist)\" if $DEBUG\n        return\n      end\n      TkCore::INTERP.add_tk_procs('::style', 'args', <<-'EOS')\n        if [string equal [lrange $args 0 1] {element create}] {\n          if [string equal [lindex $args 3] image] {\n            set name [lindex $args 4]\n            set opts [lrange $args 5 end]\n            set idx [lsearch $opts -map]\n            if {$idx >= 0 && [expr $idx % 2 == 0]} {\n             # return [eval [concat [list ::ttk::style element create [lindex $args 2] image [concat $name [lindex $opts [expr $idx + 1]]]] [lreplace $opts $idx [expr $idx + 1]]]]\n              return [uplevel 1 [list ::ttk::style element create [lindex $args 2] image [concat $name [lindex $opts [expr $idx + 1]]]] [lreplace $opts $idx [expr $idx + 1]]]\n            }\n          }\n        } elseif [string equal [lindex $args 0] default] {\n          # return [eval \"::ttk::style [lreplace $args 0 0 configure]\"]\n          return [uplevel 1 ::ttk::style [lreplace $args 0 0 configure]]\n        }\n        # return [eval \"::ttk::style $args\"]\n        return [uplevel 1 ::ttk::style $args]\n      EOS\n      #########################\n    end\n  end\n\n  def __define_themes_and_setTheme_proc__!\n    TkCore::INTERP.add_tk_procs('::ttk::themes', '{ptn *}', <<-'EOS')\n      #set themes [list]\n      set themes [::ttk::style theme names]\n      foreach pkg [lsearch -inline -all -glob [package names] ttk::theme::$ptn] {\n          set theme [namespace tail $pkg]\n          if {[lsearch -exact $themes $theme] < 0} {\n              lappend themes $theme\n          }\n      }\n      foreach pkg [lsearch -inline -all -glob [package names] tile::theme::$ptn] {\n          set theme [namespace tail $pkg]\n          if {[lsearch -exact $themes $theme] < 0} {\n              lappend themes $theme\n          }\n      }\n      return $themes\n    EOS\n    #########################\n    TkCore::INTERP.add_tk_procs('::ttk::setTheme', 'theme', <<-'EOS')\n      variable currentTheme\n      if {[lsearch -exact [::ttk::style theme names] $theme] < 0} {\n          package require [lsearch -inline -regexp [package names] (ttk|tile)::theme::$theme]\n      }\n      ::ttk::style theme use $theme\n      set currentTheme $theme\n    EOS\n  end\n  private :__define_themes_and_setTheme_proc__!\n\n  def configure(style=nil, keys=nil)\n    if style.kind_of?(Hash)\n      keys = style\n      style = nil\n    end\n    style = '.' unless style\n\n    if Tk::Tile::TILE_SPEC_VERSION_ID < 7\n      sub_cmd = 'default'\n    else\n      sub_cmd = 'configure'\n    end\n\n    if keys && keys != None\n      tk_call(TkCommandNames[0], sub_cmd, style, *hash_kv(keys))\n    else\n      tk_call(TkCommandNames[0], sub_cmd, style)\n    end\n  end\n  alias default configure\n\n  def map(style=nil, keys=nil)\n    if style.kind_of?(Hash)\n      keys = style\n      style = nil\n    end\n    style = '.' unless style\n\n    if keys && keys != None\n      if keys.kind_of?(Hash)\n        tk_call(TkCommandNames[0], 'map', style, *hash_kv(keys))\n      else\n        simplelist(tk_call(TkCommandNames[0], 'map', style, '-' << keys.to_s))\n      end\n    else\n      ret = {}\n      Hash[*(simplelist(tk_call(TkCommandNames[0], 'map', style)))].each{|k, v|\n        ret[k[1..-1]] = list(v)\n      }\n      ret\n    end\n  end\n  alias map_configure map\n\n  def map_configinfo(style=nil, key=None)\n    style = '.' unless style\n    map(style, key)\n  end\n\n  def map_default_configinfo(key=None)\n    map('.', key)\n  end\n\n  def lookup(style, opt, state=None, fallback_value=None)\n    tk_call(TkCommandNames[0], 'lookup', style, \n            '-' << opt.to_s, state, fallback_value)\n  end\n\n  include Tk::Tile::ParseStyleLayout\n\n  def layout(style=nil, spec=nil)\n    if style.kind_of?(Hash)\n      spec = style\n      style = nil\n    end\n    style = '.' unless style\n\n    if spec\n      tk_call(TkCommandNames[0], 'layout', style, spec)\n    else\n      _style_layout(list(tk_call(TkCommandNames[0], 'layout', style)))\n    end\n  end\n\n  def element_create(name, type, *args)\n    if type == 'image' || type == :image\n      element_create_image(name, *args)\n    else\n      tk_call(TkCommandNames[0], 'element', 'create', name, type, *args)\n    end\n  end\n\n  def element_create_image(name, *args)\n    fail ArgumentError, 'Must supply a base image' unless (spec = args.shift)\n    if (opts = args.shift)\n      if opts.kind_of?(Hash)\n        opts = _symbolkey2str(opts)\n      else\n        fail ArgumentError, 'bad option'\n      end\n    end\n    fail ArgumentError, 'too many arguments' unless args.empty?\n\n    if spec.kind_of?(Array)\n      # probably, command format is tile 0.8+ (Tcl/Tk8.5+) style\n      if Tk::Tile::TILE_SPEC_VERSION_ID >= 8\n        if opts\n          tk_call(TkCommandNames[0], \n                  'element', 'create', name, 'image', spec, opts)\n        else\n          tk_call(TkCommandNames[0], 'element', 'create', name, 'image', spec)\n        end\n      else\n        fail ArgumentError, 'illegal arguments' if opts.key?('map')\n        base = spec.shift\n        opts['map'] = spec\n        tk_call(TkCommandNames[0], \n                'element', 'create', name, 'image', base, opts)\n      end\n    else\n      # probably, command format is tile 0.7.8 or older style\n      if Tk::Tile::TILE_SPEC_VERSION_ID >= 8\n        spec = [spec, *(opts.delete('map'))] if opts.key?('map')\n      end\n      if opts\n        tk_call(TkCommandNames[0], \n                'element', 'create', name, 'image', spec, opts)\n      else\n        tk_call(TkCommandNames[0], 'element', 'create', name, 'image', spec)\n      end\n    end\n  end\n\n  def element_names()\n    list(tk_call(TkCommandNames[0], 'element', 'names'))\n  end\n\n  def element_options(elem)\n    simplelist(tk_call(TkCommandNames[0], 'element', 'options', elem))\n  end\n\n  def theme_create(name, keys=nil)\n    name = name.to_s\n    if keys && keys != None\n      tk_call(TkCommandNames[0], 'theme', 'create', name, *hash_kv(keys))\n    else\n      tk_call(TkCommandNames[0], 'theme', 'create', name)\n    end\n    name\n  end\n\n  def theme_settings(name, cmd=nil, &b)\n    name = name.to_s\n    cmd = Proc.new(&b) if !cmd && b\n    tk_call(TkCommandNames[0], 'theme', 'settings', name, cmd)\n    name\n  end\n\n  def theme_names()\n    list(tk_call(TkCommandNames[0], 'theme', 'names'))\n  end\n\n  def theme_use(name)\n    name = name.to_s\n    tk_call(TkCommandNames[0], 'theme', 'use', name)\n    name\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tbutton.rb",
    "content": "#\n#  tbutton widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TButton < Tk::Button\n    end\n    Button = TButton\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Button, :TkButton)\n\n\nclass Tk::Tile::TButton < Tk::Button\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::button'.freeze].freeze\n  else\n    TkCommandNames = ['::tbutton'.freeze].freeze\n  end\n  WidgetClassName = 'TButton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tcheckbutton.rb",
    "content": "#\n#  tcheckbutton widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TCheckButton < Tk::CheckButton\n    end\n    TCheckbutton = TCheckButton\n    CheckButton  = TCheckButton\n    Checkbutton  = TCheckButton\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Checkbutton, \n                            :TkCheckbutton, :TkCheckButton)\n\n\nclass Tk::Tile::TCheckButton < Tk::CheckButton\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::checkbutton'.freeze].freeze\n  else\n    TkCommandNames = ['::tcheckbutton'.freeze].freeze\n  end\n  WidgetClassName = 'TCheckbutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tcombobox.rb",
    "content": "#\n#  tcombobox widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TCombobox < Tk::Tile::TEntry\n    end\n    Combobox = TCombobox\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Combobox, :TkCombobox)\n\n\nclass Tk::Tile::TCombobox < Tk::Tile::TEntry\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::combobox'.freeze].freeze\n  else\n    TkCommandNames = ['::tcombobox'.freeze].freeze\n  end\n  WidgetClassName = 'TCombobox'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __boolval_optkeys\n    super() << 'exportselection'\n  end\n  private :__boolval_optkeys\n\n  def __listval_optkeys\n    super() << 'values'\n  end\n  private :__listval_optkeys\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\n\n  def current\n    number(tk_send_without_enc('current'))\n  end\n  def current=(idx)\n    tk_send_without_enc('current', idx)\n  end\n\n  def set(val)\n    tk_send('set', val)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tentry.rb",
    "content": "#\n#  tentry widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TEntry < Tk::Entry\n    end\n    Entry = TEntry\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Entry, :TkEntry)\n\n\nclass Tk::Tile::TEntry < Tk::Entry\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::entry'.freeze].freeze\n  else\n    TkCommandNames = ['::tentry'.freeze].freeze\n  end\n  WidgetClassName = 'TEntry'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __optkey_aliases\n    {:vcmd=>:validatecommand, :invcmd=>:invalidcommand}\n  end\n  private :__optkey_aliases\n\n  def __boolval_optkeys\n    super() << 'exportselection'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'show'\n  end\n  private :__strval_optkeys\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tframe.rb",
    "content": "#\n#  tframe widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TFrame < Tk::Frame\n    end\n    Frame = TFrame\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Frame, :TkFrame)\n\n\nclass Tk::Tile::TFrame < Tk::Frame\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::frame'.freeze].freeze\n  else\n    TkCommandNames = ['::tframe'.freeze].freeze\n  end\n  WidgetClassName = 'TFrame'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tlabel.rb",
    "content": "#\n#  tlabel widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TLabel < Tk::Label\n    end\n    Label = TLabel\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Label, :TkLabel)\n\n\nclass Tk::Tile::TLabel < Tk::Label\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::label'.freeze].freeze\n  else\n    TkCommandNames = ['::tlabel'.freeze].freeze\n  end\n  WidgetClassName = 'TLabel'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tlabelframe.rb",
    "content": "#\n#  tlabelframe widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TLabelframe < Tk::Tile::TFrame\n    end\n    TLabelFrame = TLabelframe\n    Labelframe  = TLabelframe\n    LabelFrame  = TLabelframe\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Labelframe, \n                            :TkLabelframe, :TkLabelFrame)\n\n\nclass Tk::Tile::TLabelframe < Tk::Tile::TFrame\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::labelframe'.freeze].freeze\n  else\n    TkCommandNames = ['::tlabelframe'.freeze].freeze\n  end\n  WidgetClassName = 'TLabelframe'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tmenubutton.rb",
    "content": "#\n#  tmenubutton widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TMenubutton < Tk::Menubutton\n    end\n    TMenuButton = TMenubutton\n    Menubutton  = TMenubutton\n    MenuButton  = TMenubutton\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Menubutton, \n                            :TkMenubutton, :TkMenuButton)\n\n\nclass Tk::Tile::TMenubutton < Tk::Menubutton\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::menubutton'.freeze].freeze\n  else\n    TkCommandNames = ['::tmenubutton'.freeze].freeze\n  end\n  WidgetClassName = 'TMenubutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tnotebook.rb",
    "content": "#\n#  tnotebook widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TNotebook < TkWindow\n    end\n    Notebook = TNotebook\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Notebook, :TkNotebook)\n\n\nclass Tk::Tile::TNotebook < TkWindow\n  ################################\n  include TkItemConfigMethod\n  \n  def __item_cget_cmd(id)\n    [self.path, 'tab', id]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, 'tab', id]\n  end\n  private :__item_config_cmd\n\n  def __item_listval_optkeys(id)\n    []\n  end\n  private :__item_listval_optkeys\n\n  def __item_methodcall_optkeys(id)  # { key=>method, ... }\n    {}\n  end\n  private :__item_methodcall_optkeys\n\n  #alias tabcget itemcget\n  #alias tabcget_strict itemcget_strict\n  alias tabconfigure itemconfigure\n  alias tabconfiginfo itemconfiginfo\n  alias current_tabconfiginfo current_itemconfiginfo\n\n  def tabcget_strict(tagOrId, option)\n    tabconfigure(tagOrId, option)[-1]\n  end\n  def tabcget(tagOrId, option)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      tabcget_strict(tagOrId, option)\n    else\n      begin\n        tabcget_strict(tagOrId, option)\n      rescue => e\n        begin\n          if current_tabconfiginfo(tagOrId).has_key?(option.to_s)\n            # not tag error & option is known -> error on known option\n            fail e\n          else\n            # not tag error & option is unknown\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n  ################################\n\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::notebook'.freeze].freeze\n  else\n    TkCommandNames = ['::tnotebook'.freeze].freeze\n  end\n  WidgetClassName = 'TNotebook'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\n\n  def enable_traversal()\n    if Tk::Tile::TILE_SPEC_VERSION_ID < 5\n      tk_call_without_enc('::tile::enableNotebookTraversal', @path)\n    elsif Tk::Tile::TILE_SPEC_VERSION_ID < 7\n      tk_call_without_enc('::tile::notebook::enableTraversal', @path)\n    else\n      tk_call_without_enc('::ttk::notebook::enableTraversal', @path)\n    end\n    self\n  end\n\n  def add(child, keys=nil)\n    if keys && keys != None\n      tk_send('add', _epath(child), *hash_kv(keys))\n    else\n      tk_send('add', _epath(child))\n    end\n    self\n  end\n\n  def forget(idx)\n    tk_send('forget', idx)\n    self\n  end    \n\n  def index(idx)\n    number(tk_send('index', idx))\n  end\n\n  def insert(idx, subwin, keys=nil)\n    if keys && keys != None\n      tk_send('insert', idx, subwin, *hash_kv(keys))\n    else\n      tk_send('insert', idx, subwin)\n    end\n    self\n  end\n\n  def select(idx)\n    tk_send('select', idx)\n    self\n  end\n\n  def selected\n    window(tk_send_without_enc('select'))\n  end\n\n  def tabs\n    list(tk_send('tabs'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tpaned.rb",
    "content": "#\n#  tpaned widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TPaned < TkWindow\n    end\n    PanedWindow = Panedwindow = Paned = TPaned\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Panedwindow, \n                            :TkPanedwindow, :TkPanedWindow)\n\n\nclass Tk::Tile::TPaned < TkWindow\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    if Tk::Tile::TILE_SPEC_VERSION_ID < 8\n      TkCommandNames = ['::ttk::paned'.freeze].freeze\n    else\n      TkCommandNames = ['::ttk::panedwindow'.freeze].freeze\n    end\n  else\n    TkCommandNames = ['::tpaned'.freeze].freeze\n  end\n  WidgetClassName = 'TPaned'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\n\n  def add(*args)\n    keys = args.pop\n    fail ArgumentError, \"no window in arguments\" unless keys\n\n    if keys && keys.kind_of?(Hash)\n      fail ArgumentError, \"no window in arguments\" if args == []\n      opts = hash_kv(keys)\n    else\n      args.push(keys) if keys\n      opts = []\n    end\n\n    args.each{|win|\n      tk_send_without_enc('add', _epath(win), *opts)\n    }\n    self\n  end\n\n  def forget(pane)\n    pane = _epath(pane)\n    tk_send_without_enc('forget', pane)\n    self\n  end\n\n  def insert(pos, win, keys)\n    win = _epath(win)\n    tk_send_without_enc('insert', pos, win, *hash_kv(keys))\n    self\n  end\n\n  def panecget_strict(pane, slot)\n    pane = _epath(pane)\n    tk_tcl2ruby(tk_send_without_enc('pane', pane, \"-#{slot}\"))\n  end\n  alias pane_cget_strict panecget_strict\n\n  def panecget(pane, slot)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      panecget_strict(pane, slot)\n    else\n      begin\n        panecget_strict(pane, slot)\n      rescue => e\n        begin\n          if current_paneconfiginfo(pane).has_key?(slot.to_s)\n            # not tag error & option is known -> error on known option\n            fail e\n          else\n            # not tag error & option is unknown\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n  alias pane_cget panecget\n\n  def paneconfigure(pane, key, value=nil)\n    pane = _epath(pane)\n    if key.kind_of? Hash\n      params = []\n      key.each{|k, v|\n        params.push(\"-#{k}\")\n        # params.push((v.kind_of?(TkObject))? v.epath: v)\n        params.push(_epath(v))\n      }\n      tk_send_without_enc('pane', pane, *params)\n    else\n      # value = value.epath if value.kind_of?(TkObject)\n      value = _epath(value)\n      tk_send_without_enc('pane', pane, \"-#{key}\", value)\n    end\n    self\n  end\n  alias pane_config paneconfigure\n  alias pane_configure paneconfigure\n\n  def paneconfiginfo(win)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      win = _epath(win)\n      if key\n        conf = tk_split_list(tk_send_without_enc('pane', win, \"-#{key}\"))\n        conf[0] = conf[0][1..-1]\n        if conf[0] == 'hide'\n          conf[3] = bool(conf[3]) unless conf[3].empty?\n          conf[4] = bool(conf[4]) unless conf[4].empty?\n        end\n        conf\n      else\n        tk_split_simplelist(tk_send_without_enc('pane', \n                                                win)).collect{|conflist|\n          conf = tk_split_simplelist(conflist)\n          conf[0] = conf[0][1..-1]\n          if conf[3]\n            if conf[0] == 'hide'\n              conf[3] = bool(conf[3]) unless conf[3].empty?\n            elsif conf[3].index('{')\n              conf[3] = tk_split_list(conf[3]) \n            else\n              conf[3] = tk_tcl2ruby(conf[3]) \n            end\n          end\n          if conf[4]\n            if conf[0] == 'hide'\n              conf[4] = bool(conf[4]) unless conf[4].empty?\n            elsif conf[4].index('{')\n              conf[4] = tk_split_list(conf[4]) \n            else\n              conf[4] = tk_tcl2ruby(conf[4]) \n            end\n          end\n          conf[1] = conf[1][1..-1] if conf.size == 2 # alias info\n          conf\n        }\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      win = _epath(win)\n      if key\n        conf = tk_split_list(tk_send_without_enc('pane', win, \"-#{key}\"))\n        key = conf.shift[1..-1]\n        if key == 'hide'\n          conf[2] = bool(conf[2]) unless conf[2].empty?\n          conf[3] = bool(conf[3]) unless conf[3].empty?\n        end\n        { key => conf }\n      else\n        ret = {}\n        tk_split_simplelist(tk_send_without_enc('pane', \n                                                win)).each{|conflist|\n          conf = tk_split_simplelist(conflist)\n          key = conf.shift[1..-1]\n          if key\n            if key == 'hide'\n              conf[2] = bool(conf[2]) unless conf[2].empty?\n            elsif conf[2].index('{')\n              conf[2] = tk_split_list(conf[2]) \n            else\n              conf[2] = tk_tcl2ruby(conf[2]) \n            end\n          end\n          if conf[3]\n            if key == 'hide'\n              conf[3] = bool(conf[3]) unless conf[3].empty?\n            elsif conf[3].index('{')\n              conf[3] = tk_split_list(conf[3]) \n            else\n              conf[3] = tk_tcl2ruby(conf[3]) \n            end\n          end\n          if conf.size == 1\n            ret[key] = conf[0][1..-1]  # alias info\n          else\n            ret[key] = conf\n          end\n        }\n        ret\n      end\n    end\n  end\n  alias pane_configinfo paneconfiginfo\n\n  def current_paneconfiginfo(win, key=nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if key\n        conf = paneconfiginfo(win, key)\n        {conf[0] => conf[4]}\n      else\n        ret = {}\n        paneconfiginfo(win).each{|conf|\n          ret[conf[0]] = conf[4] if conf.size > 2\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      paneconfiginfo(win, key).each{|k, conf|\n        ret[k] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n  alias current_pane_configinfo current_paneconfiginfo\n\n  def identify(x, y)\n    list(tk_send_without_enc('identify', x, y))\n  end\n\n  def sashpos(idx, newpos=None)\n    num_or_str(tk_send_without_enc('sashpos', idx, newpos))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tprogressbar.rb",
    "content": "#\n#  tprogressbar widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TProgressbar < TkWindow\n    end\n    Progressbar = TProgressbar\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Progressbar, :TkProgressbar)\n\n\nclass Tk::Tile::TProgressbar\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::progressbar'.freeze].freeze\n  else\n    TkCommandNames = ['::tprogressbar'.freeze].freeze\n  end\n  WidgetClassName = 'TProgressbar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\n\n  def step(amount=None)\n    tk_send_without_enc('step', amount).to_f\n  end\n  #def step=(amount)\n  #  tk_send_without_enc('step', amount)\n  #end\n\n  def start(interval=None)\n    if Tk::Tile::TILE_SPEC_VERSION_ID < 5\n      tk_call_without_enc('::tile::progressbar::start', @path, interval)\n    else\n      tk_send_without_enc('start', interval)\n    end\n  end\n\n  def stop(amount=None)\n    if Tk::Tile::TILE_SPEC_VERSION_ID < 5\n      tk_call_without_enc('::tile::progressbar::stop', @path)\n    else\n      tk_send_without_enc('stop', amount)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tradiobutton.rb",
    "content": "#\n#  tradiobutton widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TRadioButton < Tk::RadioButton\n    end\n    TRadiobutton = TRadioButton\n    RadioButton  = TRadioButton\n    Radiobutton  = TRadioButton\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Radiobutton, \n                            :TkRadiobutton, :TkRadioButton)\n\n\nclass Tk::Tile::TRadioButton < Tk::RadioButton\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::radiobutton'.freeze].freeze\n  else\n    TkCommandNames = ['::tradiobutton'.freeze].freeze\n  end\n  WidgetClassName = 'TRadiobutton'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/treeview.rb",
    "content": "#\n#  treeview widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class Treeview < TkWindow\n    end\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Treeview, :TkTreeview)\n\n\nmodule Tk::Tile::TreeviewConfig\n  include TkItemConfigMethod\n\n  def __item_configinfo_struct(id)\n    # maybe need to override\n    {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, \n      :default_value=>nil, :current_value=>1}\n  end\n  private :__item_configinfo_struct\n\n  def __itemconfiginfo_core(tagOrId, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)\n        fontkey  = $2\n        return [slot.to_s, tagfontobj(tagid(tagOrId), fontkey)]\n      else\n        if slot\n          slot = slot.to_s\n\n          alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot}\n          if real_name\n            slot = real_name.to_s\n          end\n\n          case slot\n          when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/\n            begin\n              # On tile-0.7.{2-8}, 'state' options has no '-' at its head.\n              val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot))\n            rescue\n              # Maybe, 'state' option has '-' in future.\n              val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            end\n            return [slot, val]\n\n          when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot]\n            optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            begin\n              val = method.call(tagOrId, optval)\n            rescue => e\n              warn(\"Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n              val = optval\n            end\n            return [slot, val]\n\n          when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot]\n            return [slot, self.__send__(method, tagOrId)]\n\n          when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n            begin\n              val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            rescue\n              val = nil\n            end\n            return [slot, val]\n\n          when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            return [slot, val]\n\n          when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n            begin\n              val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            rescue\n              val = nil\n            end\n            return [slot, val]\n\n          when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            return [slot, val]\n\n          when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            if val =~ /^[0-9]/\n              return [slot, list(val)]\n            else\n              return [slot, val]\n            end\n\n          when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            return [slot, val]\n\n          when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            if val.empty?\n              return [slot, nil]\n            else\n              return [slot, TkVarAccess.new(val)]\n            end\n\n          else\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            if val.index('{')\n              return [slot, tk_split_list(val)]\n            else\n              return [slot, tk_tcl2ruby(val)]\n            end\n          end\n\n        else # ! slot\n          ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf|\n            conf[0] = conf[0][1..-1] if conf[0][0] == ?-\n            case conf[0]\n            when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n              method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[conf[0]]\n              optval = conf[1]\n              begin\n                val = method.call(tagOrId, optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[1] = val\n\n            when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n              # do nothing\n\n            when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n              begin\n                conf[1] = number(conf[1])\n              rescue\n                conf[1] = nil\n              end\n\n            when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n              conf[1] = num_or_str(conf[1])\n\n            when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n              begin\n                conf[1] = bool(conf[1])\n              rescue\n                conf[1] = nil\n              end\n\n            when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n              conf[1] = simplelist(conf[1])\n\n            when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n              if conf[1] =~ /^[0-9]/\n                conf[1] = list(conf[1])\n              end\n\n            when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n              if conf[1].empty?\n                conf[1] = nil\n              else\n                conf[1] = TkVarAccess.new(conf[1])\n              end\n\n            else\n              if conf[1].index('{')\n                conf[1] = tk_split_list(conf[1])\n              else\n                conf[1] = tk_tcl2ruby(conf[1])\n              end\n            end\n\n            conf\n          }\n\n          __item_font_optkeys(tagid(tagOrId)).each{|optkey|\n            optkey = optkey.to_s\n            fontconf = ret.assoc(optkey)\n            if fontconf\n              ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/}\n              fontconf[1] = tagfontobj(tagid(tagOrId), optkey)\n              ret.push(fontconf)\n            end\n          }\n\n          __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method|\n            ret << [optkey.to_s, self.__send__(method, tagOrId)]\n          }\n\n          ret\n        end\n      end\n\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)\n        fontkey  = $2\n        return {slot.to_s => tagfontobj(tagid(tagOrId), fontkey)}\n      else\n        if slot\n          slot = slot.to_s\n\n          alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot}\n          if real_name\n            slot = real_name.to_s\n          end\n\n          case slot\n          when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/\n            begin\n              # On tile-0.7.{2-8}, 'state' option has no '-' at its head.\n              val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot))\n            rescue\n              # Maybe, 'state' option has '-' in future.\n              val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            end\n            return {slot => val}\n\n          when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot]\n            optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            begin\n              val = method.call(tagOrId, optval)\n            rescue => e\n              warn(\"Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n              val = optval\n            end\n            return {slot => val}\n\n          when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/\n            method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot]\n            return {slot => self.__send__(method, tagOrId)}\n\n          when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n            begin\n              val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            rescue\n              val = nil\n            end\n            return {slot => val}\n\n          when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            return {slot => val}\n\n          when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n            begin\n              val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            rescue\n              val = nil\n            end\n            return {slot => val}\n\n          when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\")))\n            return {slot => val}\n\n          when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            if val =~ /^[0-9]/\n              return {slot => list(val)}\n            else\n              return {slot => val}\n            end\n\n          when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            return {slot => val}\n\n          when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            if val.empty?\n              return {slot => nil}\n            else\n              return {slot => TkVarAccess.new(val)}\n            end\n\n          else\n            val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << \"-#{slot}\"))\n            if val.index('{')\n              return {slot => tk_split_list(val)}\n            else\n              return {slot => tk_tcl2ruby(val)}\n            end\n          end\n\n        else # ! slot\n          ret = {}\n          ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf|\n            conf[0] = conf[0][1..-1] if conf[0][0] == ?-\n\n            optkey = conf[0]\n            case optkey\n            when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/\n              method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey]\n              optval = conf[1]\n              begin\n                val = method.call(tagOrId, optval)\n              rescue => e\n                warn(\"Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})\") if $DEBUG\n                val = optval\n              end\n              conf[1] = val\n\n            when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/\n              # do nothing\n\n            when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/\n              begin\n                conf[1] = number(conf[1])\n              rescue\n                conf[1] = nil\n              end\n\n            when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/\n              conf[1] = num_or_str(conf[1])\n\n            when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/\n              begin\n                conf[1] = bool(conf[1])\n              rescue\n                conf[1] = nil\n              end\n\n            when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/\n              conf[1] = simplelist(conf[1])\n\n            when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/\n              if conf[1] =~ /^[0-9]/\n                conf[1] = list(conf[1])\n              end\n\n            when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/\n              if conf[1].empty?\n                conf[1] = nil\n              else\n                conf[1] = TkVarAccess.new(conf[1])\n              end\n\n            else\n              if conf[1].index('{')\n                return [slot, tk_split_list(conf[1])]\n              else\n                return [slot, tk_tcl2ruby(conf[1])]\n              end\n            end\n\n            ret[conf[0]] = conf[1]\n          }\n\n          __item_font_optkeys(tagid(tagOrId)).each{|optkey|\n            optkey = optkey.to_s\n            fontconf = ret[optkey]\n            if fontconf.kind_of?(Array)\n              ret.delete(optkey)\n              ret.delete('latin' << optkey)\n              ret.delete('ascii' << optkey)\n              ret.delete('kanji' << optkey)\n              fontconf[1] = tagfontobj(tagid(tagOrId), optkey)\n              ret[optkey] = fontconf\n            end\n          }\n\n          __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method|\n            ret[optkey.to_s] = self.__send__(method, tagOrId)\n          }\n\n          ret\n        end\n      end\n    end\n  end\n\n  ###################\n\n  def __item_cget_cmd(id)\n    [self.path, id[0], id[1]]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)\n    [self.path, id[0], id[1]]\n  end\n  private :__item_config_cmd\n\n  def __item_numstrval_optkeys(id)\n    case id[0]\n    when :item, 'item'\n      ['width']\n    when :column, 'column'\n      super(id[1]) + ['minwidth']\n    when :tag, 'tag'\n      super(id[1])\n    when :heading, 'heading'\n      super(id[1])\n    else\n      super(id[1])\n    end\n  end\n  private :__item_numstrval_optkeys\n\n  def __item_strval_optkeys(id)\n    case id[0]\n    when :item, 'item'\n      super(id) + ['id']\n    when :column, 'column'\n      super(id[1])\n    when :tag, 'tag'\n      super(id[1])\n    when :heading, 'heading'\n      super(id[1])\n    else\n      super(id[1])\n    end\n  end\n  private :__item_strval_optkeys\n\n  def __item_boolval_optkeys(id)\n    case id[0]\n    when :item, 'item'\n      ['open']\n    when :column, 'column'\n      super(id[1]) + ['stretch']\n    when :tag, 'tag'\n      super(id[1])\n    when :heading, 'heading'\n      super(id[1])\n    end\n  end\n  private :__item_boolval_optkeys\n\n  def __item_listval_optkeys(id)\n    case id[0]\n    when :item, 'item'\n      ['values']\n    when :column, 'column'\n      []\n    when :heading, 'heading'\n      []\n    else\n      []\n    end\n  end\n  private :__item_listval_optkeys\n\n  def __item_val2ruby_optkeys(id)\n    case id[0]\n    when :item, 'item'\n      { \n        'tags'=>proc{|arg_id, val|\n          simplelist(val).collect{|tag|\n            Tk::Tile::Treeview::Tag.id2obj(self, tag)\n          }\n        }\n      }\n    when :column, 'column'\n      {}\n    when :heading, 'heading'\n      {}\n    else\n      {}\n    end\n  end\n  private :__item_val2ruby_optkeys\n\n  def __tile_specific_item_optkeys(id)\n    case id[0]\n    when :item, 'item'\n      []\n    when :column, 'column'\n      []\n    when :heading, 'heading'\n      ['state']  # On tile-0.7.{2-8}, 'state' options has no '-' at its head.\n    else\n      []\n    end\n  end\n  private :__item_val2ruby_optkeys\n\n  def itemconfiginfo(tagOrId, slot = nil)\n    __itemconfiginfo_core(tagOrId, slot)\n  end\n\n  def current_itemconfiginfo(tagOrId, slot = nil)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      if slot\n        org_slot = slot\n        begin\n          conf = __itemconfiginfo_core(tagOrId, slot)\n          if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n              || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n            return {conf[0] => conf[-1]}\n          end\n          slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]]\n        end while(org_slot != slot)\n        fail RuntimeError, \n          \"there is a configure alias loop about '#{org_slot}'\"\n      else\n        ret = {}\n        __itemconfiginfo_core(tagOrId).each{|conf|\n          if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \\\n              || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )\n            ret[conf[0]] = conf[-1]\n          end\n        }\n        ret\n      end\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      ret = {}\n      __itemconfiginfo_core(tagOrId, slot).each{|key, conf|\n        ret[key] = conf[-1] if conf.kind_of?(Array)\n      }\n      ret\n    end\n  end\n\n  alias __itemcget itemcget\n  alias __itemcget_strict itemcget_strict\n  alias __itemconfigure itemconfigure\n  alias __itemconfiginfo itemconfiginfo\n  alias __current_itemconfiginfo current_itemconfiginfo\n\n  private :__itemcget, :__itemcget_strict\n  private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo\n\n  # Treeview Item\n  def itemcget(tagOrId, option)\n    __itemcget([:item, tagOrId], option)\n  end\n  def itemcget_strict(tagOrId, option)\n    __itemcget_strict([:item, tagOrId], option)\n  end\n  def itemconfigure(tagOrId, slot, value=None)\n    __itemconfigure([:item, tagOrId], slot, value)\n  end\n  def itemconfiginfo(tagOrId, slot=nil)\n    __itemconfiginfo([:item, tagOrId], slot)\n  end\n  def current_itemconfiginfo(tagOrId, slot=nil)\n    __current_itemconfiginfo([:item, tagOrId], slot)\n  end\n\n  # Treeview Column\n  def columncget(tagOrId, option)\n    __itemcget([:column, tagOrId], option)\n  end\n  def columncget_strict(tagOrId, option)\n    __itemcget_strict([:column, tagOrId], option)\n  end\n  def columnconfigure(tagOrId, slot, value=None)\n    __itemconfigure([:column, tagOrId], slot, value)\n  end\n  def columnconfiginfo(tagOrId, slot=nil)\n    __itemconfiginfo([:column, tagOrId], slot)\n  end\n  def current_columnconfiginfo(tagOrId, slot=nil)\n    __current_itemconfiginfo([:column, tagOrId], slot)\n  end\n  alias column_cget columncget\n  alias column_cget_strict columncget_strict\n  alias column_configure columnconfigure\n  alias column_configinfo columnconfiginfo\n  alias current_column_configinfo current_columnconfiginfo\n\n  # Treeview Heading\n  def headingcget_strict(tagOrId, option)\n    if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s)\n      begin\n        # On tile-0.7.{2-8}, 'state' options has no '-' at its head.\n        tk_call(*(__item_cget_cmd([:heading, tagOrId]) << option.to_s))\n      rescue\n        # Maybe, 'state' option has '-' in future.\n        tk_call(*(__item_cget_cmd([:heading, tagOrId]) << \"-#{option}\"))\n      end\n    else\n      __itemcget_strict([:heading, tagOrId], option)\n    end\n  end\n  def headingcget(tagOrId, option)\n    unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__\n      headingcget_strict(tagOrId, option)\n    else\n      begin\n        headingcget_strict(tagOrId, option)\n      rescue => e\n        begin\n          if current_headingconfiginfo(tagOrId).has_key?(option.to_s)\n            # not tag error & option is known -> error on known option\n            fail e\n          else\n            # not tag error & option is unknown\n            nil\n          end\n        rescue\n          fail e  # tag error\n        end\n      end\n    end\n  end\n  def headingconfigure(tagOrId, slot, value=None)\n    if slot.kind_of?(Hash)\n      slot = _symbolkey2str(slot)\n      sp_kv = []\n      __tile_specific_item_optkeys([:heading, tagOrId]).each{|k|\n        sp_kv << k << _get_eval_string(slot.delete(k)) if slot.has_key?(k)\n      }\n      tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(sp_kv)))\n      tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(hash_kv(slot))))\n    elsif __tile_specific_item_optkeys([:heading, tagOrId]).index(slot.to_s)\n      begin\n        # On tile-0.7.{2-8}, 'state' options has no '-' at its head.\n        tk_call(*(__item_cget_cmd([:heading, tagOrId]) << slot.to_s << value))\n      rescue\n        # Maybe, 'state' option has '-' in future.\n        tk_call(*(__item_cget_cmd([:heading, tagOrId]) << \"-#{slot}\" << value))\n      end\n    else\n      __itemconfigure([:heading, tagOrId], slot, value)\n    end\n    self\n  end\n  def headingconfiginfo(tagOrId, slot=nil)\n    __itemconfiginfo([:heading, tagOrId], slot)\n  end\n  def current_headingconfiginfo(tagOrId, slot=nil)\n    __current_itemconfiginfo([:heading, tagOrId], slot)\n  end\n  alias heading_cget headingcget\n  alias heading_cget_strict headingcget_strict\n  alias heading_configure headingconfigure\n  alias heading_configinfo headingconfiginfo\n  alias current_heading_configinfo current_headingconfiginfo\n\n  # Treeview Tag\n  def tagcget(tagOrId, option)\n    __itemcget([:tag, tagOrId], option)\n  end\n  def tagcget_strict(tagOrId, option)\n    __itemcget_strict([:tag, tagOrId], option)\n  end\n  def tagconfigure(tagOrId, slot, value=None)\n    __itemconfigure([:tag, tagOrId], slot, value)\n  end\n  def tagconfiginfo(tagOrId, slot=nil)\n    __itemconfiginfo([:tag, tagOrId], slot)\n  end\n  def current_tagconfiginfo(tagOrId, slot=nil)\n    __current_itemconfiginfo([:tag, tagOrId], slot)\n  end\n  alias tag_cget tagcget\n  alias tag_cget_strict tagcget_strict\n  alias tag_configure tagconfigure\n  alias tag_configinfo tagconfiginfo\n  alias current_tag_configinfo current_tagconfiginfo\nend\n\n########################\n\nclass Tk::Tile::Treeview::Item < TkObject\n  ItemID_TBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      Tk::Tile::Treeview::Item::ItemID_TBL.clear\n    }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      if Tk::Tile::Treeview::Item::ItemID_TBL[tpath]\n        (Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id])? \\\n             Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]: id\n      else\n        id\n      end\n    }\n  end\n\n  def self.assign(tree, id)\n    tpath = tree.path\n    obj = nil\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] &&\n          Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]\n        return Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]\n      end\n\n      obj = self.allocate\n      obj.instance_eval{\n        @parent = @t = tree\n        @tpath = tpath\n        @path = @id = id\n      }\n      Tk::Tile::Treeview::Item::ItemID_TBL[tpath] ||= {}\n      Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] = obj\n    }\n    obj\n  end\n\n  def _insert_item(tree, parent_item, idx, keys={})\n    keys = _symbolkey2str(keys)\n    id = keys.delete('id')\n    if id\n      num_or_str(tk_call(tree, 'insert', \n                         parent_item, idx, '-id', id, *hash_kv(keys)))\n    else\n      num_or_str(tk_call(tree, 'insert', parent_item, idx, *hash_kv(keys)))\n    end\n  end\n  private :_insert_item\n\n  def initialize(tree, parent_item = '', idx = 'end', keys = {})\n    if parent_item.kind_of?(Hash)\n      keys = parent_item\n      idx = 'end'\n      parent_item = ''\n    elsif idx.kind_of?(Hash)\n      keys = idx\n      idx = 'end'\n    end\n\n    @parent = @t = tree\n    @tpath = tree.path\n    @path = @id = _insert_item(@t, parent_item, idx, keys)\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      ItemID_TBL[@tpath] = {} unless ItemID_TBL[@tpath]\n      ItemID_TBL[@tpath][@id] = self\n    }\n  end\n  def id\n    @id\n  end\n\n  def cget(option)\n    @t.itemcget(@id, option)\n  end\n  def cget_strict(option)\n    @t.itemcget_strict(@id, option)\n  end\n\n  def configure(key, value=None)\n    @t.itemconfigure(@id, key, value)\n    self\n  end\n\n  def configinfo(key=nil)\n    @t.itemconfiginfo(@id, key)\n  end\n\n  def current_configinfo(key=nil)\n    @t.current_itemconfiginfo(@id, key)\n  end\n\n  def open?\n    cget('open')\n  end\n  def open\n    configure('open', true)\n    self\n  end\n  def close\n    configure('open', false)\n    self\n  end\n\n  def bbox(column=None)\n    @t.bbox(@id, column)\n  end\n\n  def children\n    @t.children(@id)\n  end\n  def set_children(*items)\n    @t.set_children(@id, *items)\n    self\n  end\n\n  def delete\n    @t.delete(@id)\n    self\n  end\n\n  def detach\n    @t.detach(@id)\n    self\n  end\n\n  def exist?\n    @t.exist?(@id)\n  end\n\n  def focus\n    @t.focus_item(@id)\n  end\n\n  def index\n    @t.index(@id)\n  end\n\n  def insert(idx='end', keys={})\n    @t.insert(@id, idx, keys)\n  end\n\n  def move(parent, idx)\n    @t.move(@id, parent, idx)\n    self\n  end\n\n  def next_item\n    @t.next_item(@id)\n  end\n\n  def parent_item\n    @t.parent_item(@id)\n  end\n\n  def prev_item\n    @t.prev_item(@id)\n  end\n\n  def see\n    @t.see(@id)\n    self\n  end\n\n  def selection_add\n    @t.selection_add(@id)\n    self\n  end\n\n  def selection_remove\n    @t.selection_remove(@id)\n    self\n  end\n\n  def selection_set\n    @t.selection_set(@id)\n    self\n  end\n\n  def selection_toggle\n    @t.selection_toggle(@id)\n    self\n  end\n\n  def get_directory\n    @t.get_directory(@id)\n  end\n  alias get_dictionary get_directory\n\n  def get(col)\n    @t.get(@id, col)\n  end\n\n  def set(col, value)\n    @t.set(@id, col, value)\n  end\nend\n\n########################\n\nclass Tk::Tile::Treeview::Root < Tk::Tile::Treeview::Item\n  def self.new(tree, keys = {})\n    tpath = tree.path\n    obj = nil\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] &&\n          Tk::Tile::Treeview::Item::ItemID_TBL[tpath]['']\n        obj = Tk::Tile::Treeview::Item::ItemID_TBL[tpath]['']\n      else\n        #super(tree, keys)\n        (obj = self.allocate).instance_eval{\n          @parent = @t = tree\n          @tpath = tree.path\n          @path = @id = ''\n          Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] ||= {}\n          Tk::Tile::Treeview::Item::ItemID_TBL[@tpath][@id] = self\n        }\n      end\n    }\n    obj.configure(keys) if keys && ! keys.empty?\n    obj\n  end\n\n  def initialize(tree, keys = {})\n    # dummy:: not called by 'new' method\n    @parent = @t = tree\n    @tpath = tree.path\n    @path = @id = ''\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] ||= {}\n      Tk::Tile::Treeview::Item::ItemID_TBL[@tpath][@id] = self\n    }\n  end\nend\n\n########################\n\nclass Tk::Tile::Treeview::Tag < TkObject\n  include TkTreatTagFont\n\n  TagID_TBL = TkCore::INTERP.create_table\n\n  (Tag_ID = ['tile_treeview_tag'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    Tk::Tile::Treeview::Tag::TagID_TBL.mutex.synchronize{\n      Tk::Tile::Treeview::Tag::TagID_TBL.clear\n    }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    Tk::Tile::Treeview::Tag::TagID_TBL.mutex.synchronize{\n      if Tk::Tile::Treeview::Tag::TagID_TBL[tpath]\n        (Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id])? \\\n               Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id]: id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(tree, keys=nil)\n    @parent = @t = tree\n    @tpath = tree.path\n    Tag_ID.mutex.synchronize{\n      @path = @id = Tag_ID.join(TkCore::INTERP._ip_id_)\n      Tag_ID[1].succ!\n    }\n    TagID_TBL.mutex.synchronize{\n      TagID_TBL[@tpath] = {} unless TagID_TBL[@tpath]\n      TagID_TBL[@tpath][@id] = self\n    }\n    if keys && keys != None\n      tk_call_without_enc(@tpath, 'tag', 'configure', *hash_kv(keys, true))\n    end\n  end\n  def id\n    @id\n  end\n\n  def bind(seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    @t.tag_bind(@id, seq, cmd, *args)\n    self\n  end\n\n  def bind_append(seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    @t.tag_bind_append(@id, seq, cmd, *args)\n    self\n  end\n\n  def bind_remove(seq)\n    @t.tag_bind_remove(@id, seq)\n    self\n  end\n\n  def bindinfo(seq=nil)\n    @t.tag_bindinfo(@id, seq)\n  end\n\n  def cget(option)\n    @t.tagcget(@id, option)\n  end\n  def cget_strict(option)\n    @t.tagcget_strict(@id, option)\n  end\n\n  def configure(key, value=None)\n    @t.tagconfigure(@id, key, value)\n    self\n  end\n\n  def configinfo(key=nil)\n    @t.tagconfiginfo(@id, key)\n  end\n\n  def current_configinfo(key=nil)\n    @t.current_tagconfiginfo(@id, key)\n  end\nend\n\n########################\n\nclass Tk::Tile::Treeview < TkWindow\n  include Tk::Tile::TileWidget\n  include Scrollable\n\n  include Tk::Tile::TreeviewConfig\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::treeview'.freeze].freeze\n  else\n    TkCommandNames = ['::treeview'.freeze].freeze\n  end\n  WidgetClassName = 'Treeview'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __destroy_hook__\n    Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{\n      Tk::Tile::Treeview::Item::ItemID_TBL.delete(@path)\n    }\n    Tk::Tile::Treeview::Tag::ItemID_TBL.mutex.synchronize{\n      Tk::Tile::Treeview::Tag::ItemID_TBL.delete(@path)\n    }\n  end\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\n\n  def tagid(id)\n    if id.kind_of?(Tk::Tile::Treeview::Item) || \n        id.kind_of?(Tk::Tile::Treeview::Tag)\n      id.id\n    elsif id.kind_of?(Array)\n      [id[0], _get_eval_string(id[1])]\n    else\n      _get_eval_string(id)\n    end\n  end\n\n  def root\n    Tk::Tile::Treeview::Root.new(self)\n  end\n\n  def bbox(item, column=None)\n    list(tk_send('item', 'bbox', item, column))\n  end\n\n  def children(item)\n    simplelist(tk_send_without_enc('children', item)).collect{|id|\n      Tk::Tile::Treeview::Item.id2obj(self, id)\n    }\n  end\n  def set_children(item, *items)\n    tk_send_without_enc('children', item, \n                        array2tk_list(items.flatten, true))\n    self\n  end\n\n  def delete(*items)\n    tk_send_without_enc('delete', array2tk_list(items.flatten, true))\n    self\n  end\n\n  def detach(*items)\n    tk_send_without_enc('detach', array2tk_list(items.flatten, true))\n    self\n  end\n\n  def exist?(item)\n    bool(tk_send_without_enc('exists', _get_eval_enc_str(item)))\n  end\n\n  def focus_item(item = nil)\n    if item\n      tk_send('focus', item)\n      item\n    else\n      id = tk_send('focus')\n      (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)\n    end\n  end\n\n  def identify(x, y)\n    # tile-0.7.2 or previous\n    ret = simplelist(tk_send('identify', x, y))\n    case ret[0]\n    when 'heading', 'separator'\n      ret[-1] = num_or_str(ret[-1])\n    when 'cell'\n      ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1])\n      ret[-1] = num_or_str(ret[-1])\n    when 'item', 'row'\n      ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1])\n    end\n  end\n\n  def row_identify(x, y)\n    id = tk_send('identify', 'row', x, y)\n    (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)\n  end\n\n  def column_identify(x, y)\n    tk_send('identify', 'column', x, y)\n  end\n\n  def index(item)\n    number(tk_send('index', item))\n  end\n\n  # def insert(parent, idx='end', keys={})\n  #   keys = _symbolkey2str(keys)\n  #   id = keys.delete('id')\n  #   if id\n  #     num_or_str(tk_send('insert', parent, idx, '-id', id, *hash_kv(keys)))\n  #   else\n  #     num_or_str(tk_send('insert', parent, idx, *hash_kv(keys)))\n  #   end\n  # end\n  def insert(parent, idx='end', keys={})\n    Tk::Tile::Treeview::Item.new(self, parent, idx, keys)\n  end\n\n  # def instate(spec, cmd=Proc.new)\n  #   tk_send('instate', spec, cmd)\n  # end\n  # def state(spec=None)\n  #   tk_send('state', spec)\n  # end\n\n  def move(item, parent, idx)\n    tk_send('move', item, parent, idx)\n    self\n  end\n\n  def next_item(item)\n    id = tk_send('next', item)\n    (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)\n  end\n\n  def parent_item(item)\n    if (id = tk_send('parent', item)).empty?\n      Tk::Tile::Treeview::Root.new(self)\n    else\n      Tk::Tile::Treeview::Item.id2obj(self, id)\n    end\n  end\n\n  def prev_item(item)\n    id = tk_send('prev', item)\n    (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)\n  end\n\n  def see(item)\n    tk_send('see', item)\n    self\n  end\n\n  def selection\n    simplelist(tk_send('selection')).collect{|id|\n      Tk::Tile::Treeview::Item.id2obj(self, id)\n    }\n  end\n  alias selection_get selection\n\n  def selection_add(*items)\n    tk_send('selection', 'add', array2tk_list(items.flatten, true))\n    self\n  end\n  def selection_remove(*items)\n    tk_send('selection', 'remove', array2tk_list(items.flatten, true))\n    self\n  end\n  def selection_set(*items)\n    tk_send('selection', 'set', array2tk_list(items.flatten, true))\n    self\n  end\n  def selection_toggle(*items)\n    tk_send('selection', 'toggle', array2tk_list(items.flatten, true))\n    self\n  end\n\n  def get_directory(item)\n    # tile-0.7+\n    ret = []\n    lst = simplelist(tk_send('set', item))\n    until lst.empty?\n      col = lst.shift\n      val = lst.shift\n      ret << [col, val]\n    end\n    ret\n  end\n  alias get_dictionary get_directory\n\n  def get(item, col)\n    tk_send('set', item, col)\n  end\n  def set(item, col, value)\n    tk_send('set', item, col, value)\n    self\n  end\n\n  def tag_bind(tag, seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([@path, 'tag', 'bind', tag], seq, cmd, *args)\n    self\n  end\n  alias tagbind tag_bind\n\n  def tag_bind_append(tag, seq, *args)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args)\n    self\n  end\n  alias tagbind_append tag_bind_append\n\n  def tag_bind_remove(tag, seq)\n    _bind_remove([@path, 'tag', 'bind', tag], seq)\n    self\n  end\n  alias tagbind_remove tag_bind_remove\n\n  def tag_bindinfo(tag, context=nil)\n    _bindinfo([@path, 'tag', 'bind', tag], context)\n  end\n  alias tagbindinfo tag_bindinfo\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tscale.rb",
    "content": "#\n#  tscale & tprogress widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TScale < Tk::Scale\n    end\n    Scale = TScale\n\n    class TProgress < TScale\n    end\n    Progress = TProgress\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Scale, :TkScale)\n\n\nclass Tk::Tile::TScale < Tk::Scale\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::scale'.freeze].freeze\n  else\n    TkCommandNames = ['::tscale'.freeze].freeze\n  end\n  WidgetClassName = 'TScale'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n\nclass Tk::Tile::TProgress < Tk::Tile::TScale\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::progress'.freeze].freeze\n  else\n    TkCommandNames = ['::tprogress'.freeze].freeze\n  end\n  WidgetClassName = 'TProgress'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tscrollbar.rb",
    "content": "#\n#  tscrollbar widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TScrollbar < Tk::Scrollbar\n    end\n    Scrollbar = TScrollbar\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Scrollbar, :TkScrollbar)\n\n\nclass Tk::Tile::TScrollbar < Tk::Scrollbar\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::scrollbar'.freeze].freeze\n  else\n    TkCommandNames = ['::tscrollbar'.freeze].freeze\n  end\n  WidgetClassName = 'TScrollbar'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n\nclass Tk::Tile::XScrollbar < Tk::Tile::TScrollbar\n  def create_self(keys)\n    keys = {} unless keys\n    keys['orient'] = 'horizontal'\n    super(keys)\n  end\n  private :create_self\nend\n\nclass Tk::Tile::YScrollbar < Tk::Tile::TScrollbar\n  def create_self(keys)\n    keys = {} unless keys\n    keys['orient'] = 'vertical'\n    super(keys)\n  end\n  private :create_self\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::XScrollbar, :TkXScrollbar)\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::YScrollbar, :TkYScrollbar)\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tseparator.rb",
    "content": "#\n#  tseparator widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TSeparator < TkWindow\n    end\n    Separator = TSeparator\n  end\nend\n\nTk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Separator, :TkSeparator)\n\n\nclass Tk::Tile::TSeparator < TkWindow\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::separator'.freeze].freeze\n  else\n    TkCommandNames = ['::tseparator'.freeze].freeze\n  end\n  WidgetClassName = 'TSeparator'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile/tsquare.rb",
    "content": "#\n#  tsquare widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tkextlib/tile.rb'\n\nmodule Tk\n  module Tile\n    class TSquare < TkWindow\n    end\n    Square = TSquare\n  end\nend\n\nclass Tk::Tile::TSquare < TkWindow\n  include Tk::Tile::TileWidget\n\n  if Tk::Tile::USE_TTK_NAMESPACE\n    TkCommandNames = ['::ttk::square'.freeze].freeze\n  else\n    TkCommandNames = ['::tsquare'.freeze].freeze\n  end\n  WidgetClassName = 'TSquare'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def self.style(*args)\n    [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tile.rb",
    "content": "#\n#  Tile theme engin (tile widget set) support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/ttk_selector'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# library directory\nrequire 'tkextlib/tile/setup.rb'\n\n# load package\n# TkPackage.require('tile', '0.4')\n# TkPackage.require('tile', '0.6')\n# TkPackage.require('tile', '0.7')\nif Tk::TK_MAJOR_VERSION > 8 || \n    (Tk::TK_MAJOR_VERSION == 8 && Tk::TK_MINOR_VERSION >= 5)\n  TkPackage.require('tile') # for compatibility (version check of 'tile')\n  verstr = TkPackage.require('Ttk')\nelse\n  verstr = TkPackage.require('tile')\nend\n\nver = verstr.split('.')\nif ver[0].to_i == 0\n  # Tile extension package\n  if ver[1].to_i <= 4\n    # version 0.4 or former\n    module Tk\n      module Tile\n        USE_TILE_NAMESPACE = true\n        USE_TTK_NAMESPACE  = false\n        TILE_SPEC_VERSION_ID = 0\n      end\n    end\n  elsif ver[1].to_i <= 6\n    # version 0.5 -- version 0.6\n    module Tk\n      module Tile\n        USE_TILE_NAMESPACE = true\n        USE_TTK_NAMESPACE  = true\n        TILE_SPEC_VERSION_ID = 5\n      end\n    end\n  elsif ver[1].to_i <= 7\n    module Tk\n      module Tile\n        USE_TILE_NAMESPACE = false\n        USE_TTK_NAMESPACE  = true\n        TILE_SPEC_VERSION_ID = 7\n      end\n    end\n  else\n    # version 0.8 or later\n    module Tk\n      module Tile\n        USE_TILE_NAMESPACE = false\n        USE_TTK_NAMESPACE  = true\n        TILE_SPEC_VERSION_ID = 8\n      end\n    end\n  end\n\n  module Tk::Tile\n    PACKAGE_NAME = 'tile'.freeze\n  end\nelse\n  # Ttk package merged Tcl/Tk core (Tcl/Tk 8.5+)\n  module Tk\n    module Tile\n      USE_TILE_NAMESPACE = false\n      USE_TTK_NAMESPACE  = true\n      TILE_SPEC_VERSION_ID = 8\n\n      PACKAGE_NAME = 'Ttk'.freeze\n    end\n  end\nend\n\n# autoload\nmodule Tk\n  module Tile\n    TkComm::TkExtlibAutoloadModule.unshift(self)\n\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require(PACKAGE_NAME)\n      rescue\n        ''\n      end\n    end\n\n    def self.__Import_Tile_Widgets__!\n      warn 'Warning: \"Tk::Tile::__Import_Tile_Widgets__!\" is obsolete.' <<\n           ' To control default widget set, use \"Tk.default_widget_set = :Ttk\"'\n      Tk.tk_call('namespace', 'import', '-force', 'ttk::*')\n    end\n\n    def self.__define_LoadImages_proc_for_compatibility__!\n      # Ttk 8.5 (Tile 0.8) lost 'LoadImages' utility procedure.\n      # So, some old scripts doen't work, because those scripts use the \n      # procedure to define local styles. \n      # Of course, rewriting such Tcl/Tk scripts isn't difficult for \n      # Tcl/Tk users. However, it may be troublesome for Ruby/Tk users \n      # who use such Tcl/Tk scripts as it is.\n      # This method may help Ruby/Tk users who don't want to modify old \n      # Tcl/Tk scripts for the latest version of Ttk (Tile) extension.\n      # This method defines a comaptible 'LoadImages' procedure on the \n      # Tcl/Tk interpreter working under Ruby/Tk. \n      # Please give attention to use this method. It may conflict with \n      # some definitions on Tcl/Tk scripts. \n      klass_name = self.name\n      proc_name = 'LoadImages'\n      if Tk::Tile::USE_TTK_NAMESPACE\n        ns_list = ['::tile']\n        if Tk.info(:commands, \"::ttk::#{proc_name}\").empty?\n          ns_list << '::ttk'\n        end\n      else # Tk::Tile::USE_TILE_NAMESPACE\n        ns_list = ['::ttk']\n        if Tk.info(:commands, \"::tile::#{proc_name}\").empty?\n          ns_list << '::tile'\n        end\n      end\n\n      ns_list.each{|ns|\n        cmd = \"#{ns}::#{proc_name}\"\n        unless Tk.info(:commands, cmd).empty?\n          #fail RuntimeError, \"can't define '#{cmd}' command (already exist)\"\n\n          # do nothing !!!\n          warn \"Warning: can't define '#{cmd}' command (already exist)\" if $DEBUG\n          next\n        end\n        TkNamespace.eval(ns){\n          TkCore::INTERP.add_tk_procs(proc_name, 'imgdir {patterns {*.gif}}', \n                                      <<-'EOS')\n            foreach pattern $patterns {\n              foreach file [glob -directory $imgdir $pattern] {\n                set img [file tail [file rootname $file]]\n                if {![info exists images($img)]} {\n                  set images($img) [image create photo -file $file]\n                }\n              }\n            }\n            return [array get images]\n          EOS\n        }\n      }\n    end\n\n    def self.load_images(imgdir, pat=nil)\n      if Tk::Tile::TILE_SPEC_VERSION_ID < 8\n        if Tk::Tile::USE_TTK_NAMESPACE\n          cmd = '::ttk::LoadImages'\n        else # Tk::Tile::USE_TILE_NAMESPACE\n          cmd = '::tile::LoadImages'\n        end\n        pat ||= TkComm::None\n        images = Hash[*TkComm.simplelist(Tk.tk_call(cmd, imgdir, pat))]\n        images.keys.each{|k|\n          images[k] = TkPhotoImage.new(:imagename=>images[k], \n                                       :without_creating=>true)\n        }\n      else ## TILE_SPEC_VERSION_ID >= 8\n        pat ||= '*.gif'\n        if pat.kind_of?(Array)\n          pat_list = pat\n        else\n          pat_list = [ pat ]\n        end\n        Dir.chdir(imgdir){\n          pat_list.each{|pat|\n            Dir.glob(pat).each{|f|\n              img = File.basename(f, '.*')\n              unless TkComm.bool(Tk.info('exists', \"images(#{img})\"))\n                Tk.tk_call('set', \"images(#{img})\", \n                           Tk.tk_call('image', 'create', 'photo', '-file', f))\n              end\n            }\n          }\n        }\n        images = Hash[*TkComm.simplelist(Tk.tk_call('array', 'get', 'images'))]\n        images.keys.each{|k|\n          images[k] = TkPhotoImage.new(:imagename=>images[k], \n                                       :without_creating=>true)\n        }\n      end\n\n      images\n    end\n\n    def self.style(*args)\n      args.map!{|arg| TkComm._get_eval_string(arg)}.join('.')\n    end\n\n    def self.themes(glob_ptn = nil)\n      if TILE_SPEC_VERSION_ID < 8 && Tk.info(:commands, '::ttk::themes').empty?\n        fail RuntimeError, 'not support glob option' if glob_ptn\n        cmd = ['::tile::availableThemes']\n      else\n        glob_ptn = '*' unless glob_ptn\n        cmd = ['::ttk::themes', glob_ptn]\n      end\n\n      begin\n        TkComm.simplelist(Tk.tk_call_without_enc(*cmd))\n      rescue\n        TkComm.simplelist(Tk.tk_call('lsearch', '-all', '-inline', \n                                     Tk::Tile::Style.theme_names, \n                                     glob_ptn))\n      end\n    end\n\n    def self.set_theme(theme)\n      if TILE_SPEC_VERSION_ID < 8 && Tk.info(:commands, '::ttk::setTheme').empty?\n        cmd = '::tile::setTheme'\n      else\n        cmd = '::ttk::setTheme'\n      end\n\n      begin\n        Tk.tk_call_without_enc(cmd, theme)\n      rescue\n        Tk::Tile::Style.theme_use(theme)\n      end\n    end\n\n    module KeyNav\n      if Tk::Tile::TILE_SPEC_VERSION_ID < 8\n        def self.enableMnemonics(w)\n          Tk.tk_call('::keynav::enableMnemonics', w)\n        end\n        def self.defaultButton(w)\n          Tk.tk_call('::keynav::defaultButton', w)\n        end\n      else # dummy\n        def self.enableMnemonics(w)\n          \"\"\n        end\n        def self.defaultButton(w)\n          \"\"\n        end\n      end\n    end\n\n    module Font\n      Default      = 'TkDefaultFont'\n      Text         = 'TkTextFont'\n      Heading      = 'TkHeadingFont'\n      Caption      = 'TkCaptionFont'\n      Tooltip      = 'TkTooltipFont'\n\n      Fixed        = 'TkFixedFont'\n      Menu         = 'TkMenuFont'\n      SmallCaption = 'TkSmallCaptionFont'\n      Icon         = 'TkIconFont'\n\n      TkFont::SYSTEM_FONT_NAMES.add [\n        'TkDefaultFont', 'TkTextFont', 'TkHeadingFont', \n        'TkCaptionFont', 'TkTooltipFont', 'TkFixedFont', \n        'TkMenuFont', 'TkSmallCaptionFont', 'TkIconFont'\n      ]\n    end\n\n    module ParseStyleLayout\n      def _style_layout(lst)\n        ret = []\n        until lst.empty?\n          sub = [lst.shift]\n          keys = {}\n\n          until lst.empty?\n            if lst[0][0] == ?-\n              k = lst.shift[1..-1]\n              children = lst.shift \n              children = _style_layout(children) if children.kind_of?(Array)\n              keys[k] = children\n            else\n              break\n            end\n          end\n\n          sub << keys unless keys.empty?\n          ret << sub\n        end\n        ret\n      end\n      private :_style_layout\n    end\n\n    module TileWidget\n      include Tk::Tile::ParseStyleLayout\n\n      def __val2ruby_optkeys  # { key=>proc, ... }\n        # The method is used to convert a opt-value to a ruby's object.\n        # When get the value of the option \"key\", \"proc.call(value)\" is called.\n        super().update('style'=>proc{|v| _style_layout(list(v))})\n      end\n      private :__val2ruby_optkeys\n\n      def ttk_instate(state, script=nil, &b)\n        if script\n          tk_send('instate', state, script)\n        elsif b\n          tk_send('instate', state, Proc.new(&b))\n        else\n          bool(tk_send('instate', state))\n        end\n      end\n      alias tile_instate ttk_instate\n\n      def ttk_state(state=nil)\n        if state\n          tk_send('state', state)\n        else\n          list(tk_send('state'))\n        end\n      end\n      alias tile_state ttk_state\n\n      def ttk_identify(x, y)\n        ret = tk_send_without_enc('identify', x, y)\n        (ret.empty?)? nil: ret\n      end\n      alias tile_identify ttk_identify\n\n      # remove instate/state/identify method \n      # to avoid the conflict with widget options\n      if Tk.const_defined?(:USE_OBSOLETE_TILE_STATE_METHOD) && Tk::USE_OBSOLETE_TILE_STATE_METHOD\n        alias instate  ttk_instate\n        alias state    ttk_state\n        alias identify ttk_identify\n      end\n    end\n\n    ######################################\n\n    autoload :TButton,       'tkextlib/tile/tbutton'\n    autoload :Button,        'tkextlib/tile/tbutton'\n\n    autoload :TCheckButton,  'tkextlib/tile/tcheckbutton'\n    autoload :CheckButton,   'tkextlib/tile/tcheckbutton'\n    autoload :TCheckbutton,  'tkextlib/tile/tcheckbutton'\n    autoload :Checkbutton,   'tkextlib/tile/tcheckbutton'\n\n    autoload :Dialog,        'tkextlib/tile/dialog'\n\n    autoload :TEntry,        'tkextlib/tile/tentry'\n    autoload :Entry,         'tkextlib/tile/tentry'\n\n    autoload :TCombobox,     'tkextlib/tile/tcombobox'\n    autoload :Combobox,      'tkextlib/tile/tcombobox'\n\n    autoload :TFrame,        'tkextlib/tile/tframe'\n    autoload :Frame,         'tkextlib/tile/tframe'\n\n    autoload :TLabelframe,   'tkextlib/tile/tlabelframe'\n    autoload :Labelframe,    'tkextlib/tile/tlabelframe'\n    autoload :TLabelFrame,   'tkextlib/tile/tlabelframe'\n    autoload :LabelFrame,    'tkextlib/tile/tlabelframe'\n\n    autoload :TLabel,        'tkextlib/tile/tlabel'\n    autoload :Label,         'tkextlib/tile/tlabel'\n\n    autoload :TMenubutton,   'tkextlib/tile/tmenubutton'\n    autoload :Menubutton,    'tkextlib/tile/tmenubutton'\n    autoload :TMenuButton,   'tkextlib/tile/tmenubutton'\n    autoload :MenuButton,    'tkextlib/tile/tmenubutton'\n\n    autoload :TNotebook,     'tkextlib/tile/tnotebook'\n    autoload :Notebook,      'tkextlib/tile/tnotebook'\n\n    autoload :TPaned,        'tkextlib/tile/tpaned'\n    autoload :Paned,         'tkextlib/tile/tpaned'\n    autoload :PanedWindow,   'tkextlib/tile/tpaned'\n    autoload :Panedwindow,   'tkextlib/tile/tpaned'\n\n    autoload :TProgressbar,  'tkextlib/tile/tprogressbar'\n    autoload :Progressbar,   'tkextlib/tile/tprogressbar'\n\n    autoload :TRadioButton,  'tkextlib/tile/tradiobutton'\n    autoload :RadioButton,   'tkextlib/tile/tradiobutton'\n    autoload :TRadiobutton,  'tkextlib/tile/tradiobutton'\n    autoload :Radiobutton,   'tkextlib/tile/tradiobutton'\n\n    autoload :TScale,        'tkextlib/tile/tscale'\n    autoload :Scale,         'tkextlib/tile/tscale'\n    autoload :TProgress,     'tkextlib/tile/tscale'\n    autoload :Progress,      'tkextlib/tile/tscale'\n\n    autoload :TScrollbar,    'tkextlib/tile/tscrollbar'\n    autoload :Scrollbar,     'tkextlib/tile/tscrollbar'\n    autoload :XScrollbar,    'tkextlib/tile/tscrollbar'\n    autoload :YScrollbar,    'tkextlib/tile/tscrollbar'\n\n    autoload :TSeparator,    'tkextlib/tile/tseparator'\n    autoload :Separator,     'tkextlib/tile/tseparator'\n\n    autoload :TSquare,       'tkextlib/tile/tsquare'\n    autoload :Square,        'tkextlib/tile/tsquare'\n\n    autoload :SizeGrip,      'tkextlib/tile/sizegrip'\n    autoload :Sizegrip,      'tkextlib/tile/sizegrip'\n\n    autoload :Treeview,      'tkextlib/tile/treeview'\n\n    autoload :Style,         'tkextlib/tile/style'\n  end\nend\n\nTtk = Tk::Tile\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkDND/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkDND/shape.rb",
    "content": "#\n#  tkextlib/tkDND/shape.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkDND/setup.rb'\n\n# TkPackage.require('Shape', '0.3')\nTkPackage.require('Shape')\n\nmodule Tk\n  module TkDND\n    module Shape\n      extend TkCore\n\n      PACKAGE_NAME = 'Shape'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n=begin\n      def self.package_version\n        begin\n          TkPackage.require('Shape')\n        rescue\n          ''\n        end\n      end\n=end\n      class << self\n        def package_version\n          Tk.tk_call('set', 'shape_version')\n        end\n        alias shape_version package_version\n\n        def package_patchlevel\n          Tk.tk_call('set', 'shape_patchLevel')\n        end\n        alias shape_patchlevel package_patchlevel\n\n        def version\n          tk_call('shape', 'version')\n        end\n        alias xshape_version version\n      end\n\n      ############################\n\n      def shape_bounds(kind=nil)\n        if kind\n          ret = tk_call('shape', 'bounds', @path, \"-#{kind}\")\n        else\n          ret = tk_call('shape', 'bounds', @path)\n        end\n        if ret == \"\"\n          nil\n        else\n          list(ret)\n        end\n      end\n\n      def shape_get(kind=nil)\n        if kind\n          list(tk_call('shape', 'get', @path, \"-#{kind}\"))\n        else\n          list(tk_call('shape', 'get', @path))\n        end\n      end\n\n      def shape_offset(x, y, kind=nil)\n        if kind\n          tk_call('shape', 'get', @path, \"-#{kind}\", x, y)\n        else\n          tk_call('shape', 'get', @path, x, y)\n        end\n        self\n      end\n\n      def _parse_shapespec_param(args)\n        cmd = []\n\n        kind_keys    = ['bounding', 'clip', 'both']\n        offset_keys  = ['offset']\n        srckind_keys = ['bitmap', 'rectangles', 'reset', 'test', 'window']\n\n        cmd << \"-#{args.shift}\" if kind_keys.member?(args[0].to_s)\n\n        if offset_keys.member?(args[0].to_s)\n          cmd << \"-#{args.shift}\"\n          cmd << args.shift # xOffset\n          cmd << args.shift # yOffset\n        end\n\n        if srckind_keys.member?(args[0].to_s)\n          cmd << \"-#{args.shift}\"\n        end\n\n        cmd.concat(args)\n\n        cmd\n      end\n      private :_parse_shapespec_param\n\n      def shape_set(*args) # ?kind? ?offset <x> <y>? srckind ?arg ...?\n        tk_call('shape', 'set', @path, *(_parse_shapespec_param(args)))\n        self\n      end\n\n      def shape_update(op, *args) # ?kind? ?offset <x> <y>? srckind ?arg ...?\n        tk_call('shape', 'update', @path, op, *(_parse_shapespec_param(args)))\n        self\n      end\n    end\n  end\nend\n\nclass TkWindow\n  include Tk::TkDND::Shape\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkDND/tkdnd.rb",
    "content": "#\n#  tkextlib/tkDND/tkdnd.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkDND/setup.rb'\n\nTkPackage.require('tkdnd')\n\nmodule Tk\n  module TkDND\n    PACKAGE_NAME = 'tkdnd'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('tkdnd')\n      rescue\n        ''\n      end\n    end\n\n    class DND_Subst < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?a, ?l, :actions ], \n        [ ?A, ?s, :action ], \n        [ ?b, ?L, :codes ], \n        [ ?c, ?s, :code ], \n        [ ?d, ?l, :descriptions ], \n        [ ?D, ?l, :data ], \n        [ ?L, ?l, :source_types ], \n        [ ?m, ?l, :modifiers ], \n        [ ?t, ?l, :types ], \n        [ ?T, ?s, :type ], \n        [ ?W, ?w, :widget ], \n        [ ?x, ?n, :x ], \n        [ ?X, ?n, :x_root ], \n        [ ?y, ?n, :y ], \n        [ ?Y, ?n, :y_root ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?n, TkComm.method(:num_or_str) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?l, TkComm.method(:list) ], \n        [ ?L, TkComm.method(:simplelist) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      # setup tables\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n    end\n\n    module DND\n      def self.version\n        begin\n          TkPackage.require('tkdnd')\n        rescue\n          ''\n        end\n      end\n\n      def dnd_bindtarget_info(type=nil, event=nil)\n        if event\n          procedure(tk_call('dnd', 'bindtarget', @path, type, event))\n        elsif type\n          procedure(tk_call('dnd', 'bindtarget', @path, type))\n        else\n          simplelist(tk_call('dnd', 'bindtarget', @path))\n        end\n      end\n\n      #def dnd_bindtarget(type, event, cmd=Proc.new, prior=50, *args)\n      #  event = tk_event_sequence(event)\n      #  if prior.kind_of?(Numeric)\n      #    tk_call('dnd', 'bindtarget', @path, type, event, \n      #            install_bind_for_event_class(DND_Subst, cmd, *args), \n      #            prior)\n      #  else\n      #    tk_call('dnd', 'bindtarget', @path, type, event, \n      #            install_bind_for_event_class(DND_Subst, cmd, prior, *args))\n      #  end\n      #  self\n      #end\n      def dnd_bindtarget(type, event, *args)\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0]) || !block_given?\n          cmd = args.shift\n        else\n          cmd = Proc.new\n        end\n\n        prior = 50\n        prior = args.shift unless args.empty?\n\n        event = tk_event_sequence(event)\n        if prior.kind_of?(Numeric)\n          tk_call('dnd', 'bindtarget', @path, type, event, \n                  install_bind_for_event_class(DND_Subst, cmd, *args), \n                  prior)\n        else\n          tk_call('dnd', 'bindtarget', @path, type, event, \n                  install_bind_for_event_class(DND_Subst, cmd, prior, *args))\n        end\n        self\n      end\n\n      def dnd_cleartarget\n        tk_call('dnd', 'cleartarget', @path)\n        self\n      end\n\n      def dnd_bindsource_info(type=nil)\n        if type\n          procedure(tk_call('dnd', 'bindsource', @path, type))\n        else\n          simplelist(tk_call('dnd', 'bindsource', @path))\n        end\n      end\n\n      #def dnd_bindsource(type, cmd=Proc.new, prior=None)\n      #  tk_call('dnd', 'bindsource', @path, type, cmd, prior)\n      #  self\n      #end\n      def dnd_bindsource(type, *args)\n        # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n        if TkComm._callback_entry?(args[0]) || !block_given?\n          cmd = args.shift\n        else\n          cmd = Proc.new\n        end\n\n        args = [None] if args.empty\n\n        tk_call('dnd', 'bindsource', @path, type, cmd, *args)\n        self\n      end\n\n      def dnd_clearsource()\n        tk_call('dnd', 'clearsource', @path)\n        self\n      end\n\n      def dnd_drag(keys=nil)\n        tk_call('dnd', 'drag', @path, *hash_kv(keys))\n        self\n      end\n    end\n  end\nend\n\nclass TkWindow\n  include Tk::TkDND::DND\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkDND.rb",
    "content": "#\n#  TkDND (Tk Drag & Drop Extension) support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkDND/setup.rb'\n\nmodule Tk\n  module TkDND\n    autoload :DND,   'tkextlib/tkDND/tkdnd'\n    autoload :Shape, 'tkextlib/tkDND/shape'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb",
    "content": "#\n#  tkextlib/tkHTML/htmlwidget.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkHTML/setup.rb'\n\n# TkPackage.require('Tkhtml', '2.0')\nTkPackage.require('Tkhtml')\n\nmodule Tk\n  class HTML_Widget < TkWindow\n    PACKAGE_NAME = 'Tkhtml'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Tkhtml')\n      rescue\n        ''\n      end\n    end\n\n    class ClippingWindow < TkWindow\n    end\n  end\nend\n\nclass Tk::HTML_Widget::ClippingWindow\n  WidgetClassName = 'HtmlClip'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  HtmlClip_TBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    HtmlClip_TBL.mutex.synchronize{ HtmlClip_TBL.clear }\n  }\n\n  def self.new(parent, keys={})\n    if parent.kind_of?(Hash)\n      keys = TkComm._symbolkey2str(parent)\n      parent = keys.delete('parent')\n    end\n\n    if parent.kind_of?(String)\n      ppath = parent.path\n    elsif parent\n      ppath = parent\n    else\n      ppath = ''\n    end\n    HtmlClip_TBL.mutex.synchronize{\n      return HtmlClip_TBL[ppath] if HtmlClip_TBL[ppath]\n    }\n\n    widgetname = keys.delete('widgetname')\n    if widgetname =~ /^(.*)\\.[^.]+$/\n      ppath2 = $1\n      if ppath2[0] != ?.\n        ppath2 = ppath + '.' + ppath2\n      end\n      HtmlClip_TBL.mutex.synchronize{\n        return HtmlClip_TBL[ppath2] if HtmlClip_TBL[ppath2]\n      }\n\n      ppath = ppath2\n    end\n    \n    parent = TkComm._genobj_for_tkwidget(ppath)\n    unless parent.kind_of?(Tk::HTML_Widget)\n      fail ArgumentError, \"parent must be a Tk::HTML_Widget instance\"\n    end\n\n    super(parent)\n  end\n\n  def initialize(parent)\n    @parent = parent\n    @ppath = parent.path\n    @path = @id = @ppath + '.x'\n    HtmlClip_TBL.mutex.synchronize{\n      HtmlClip_TBL[@ppath] = self\n    }\n  end\n\n  def method_missing(m, *args, &b)\n    @parent.__send__(m, *args, &b)\n  end\nend\n\nclass Tk::HTML_Widget\n  include Scrollable\n\n  TkCommandNames = ['html'.freeze].freeze\n  WidgetClassName = 'Html'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  def __strval_optkeys\n    super() << 'base' << 'selectioncolor' << 'unvisitedcolor' << 'visitedcolor'\n  end\n  private :__strval_optkeys\n\n  ###################################\n  #  class methods\n  ###################################\n  def self.reformat(src, dst, txt)\n    tk_call('html', 'reformat', src, dst, txt)\n  end\n\n  def self.url_join(*args) # args := sheme authority path query fragment\n    tk_call('html', 'urljoin', *args)\n  end\n\n  def self.url_split(uri)\n    tk_call('html', 'urlsplit', uri)\n  end\n\n  def self.lockcopy(src, dst)\n    tk_call('html', 'lockcopy', src, dst)\n  end\n\n  def self.gzip_file(file, dat)\n    tk_call('html', 'gzip', 'file', file, dat)\n  end\n\n  def self.gunzip_file(file, dat)\n    tk_call('html', 'gunzip', 'file', filet)\n  end\n\n  def self.gzip_data(dat)\n    tk_call('html', 'gzip', 'data', file, dat)\n  end\n\n  def self.gunzip_data(dat)\n    tk_call('html', 'gunzip', 'data', filet)\n  end\n\n  def self.base64_encode(dat)\n    tk_call('html', 'base64', 'encode', dat)\n  end\n\n  def self.base64_decode(dat)\n    tk_call('html', 'base64', 'encode', dat)\n  end\n\n  def self.text_format(dat, len)\n    tk_call('html', 'text', 'format', dat, len)\n  end\n\n  def self.xor(cmd, *args)\n    tk_call('html', 'xor', cmd, *args)\n  end\n\n  def self.stdchan(cmd, channel)\n    tk_call('html', 'stdchan', cmd, channel)\n  end\n\n  def self.crc32(data)\n    tk_call('html', 'crc32', data)\n  end\n\n  ###################################\n  #  instance methods\n  ###################################\n  def clipping_window\n    ClippingWindow.new(self)\n  end\n  alias clipwin  clipping_window\n  alias htmlclip clipping_window\n\n  def bgimage(image, tid=None)\n    tk_send('bgimage', image, tid)\n    self\n  end\n\n  def clear()\n    tk_send('clear')\n    self\n  end\n\n  def coords(index=None, percent=None)\n    tk_send('coords', index, percent)\n  end\n\n  def forminfo(*args)\n    tk_send('forminfo', *args)\n  end\n  alias form_info forminfo\n\n  def href(x, y)\n    simplelist(tk_send('href', x, y))\n  end\n\n  def image_add(id, img)\n    tk_send('imageadd', id, img)\n    self\n  end\n\n  def image_at(x, y)\n    tk_send('imageat', x, y)\n  end\n\n  def images()\n    list(tk_send('images'))\n  end\n\n  def image_set(id, num)\n    tk_send('imageset', id, num)\n    self\n  end\n\n  def image_update(id, imgs)\n    tk_send('imageupdate', id, imgs)\n    self\n  end\n\n  def index(idx, count=None, unit=None)\n    tk_send('index', idx, count, unit)\n  end\n\n  def insert_cursor(idx)\n    tk_send('insert', idx)\n  end\n\n  def names()\n    simple_list(tk_send('names'))\n  end\n\n  def on_screen(id, x, y)\n    bool(tk_send('onscreen', id, x, y))\n  end\n\n  def over(x, y)\n    list(tk_send('over', x, y))\n  end\n\n  def over_markup(x, y)\n    list(tk_send('over', x, y, '-muponly'))\n  end\n\n  def over_attr(x, y, attrs)\n    list(tk_send('overattr', x, y, attrs))\n  end\n\n  def parse(txt)\n    tk_send('parse', txt)\n    self\n  end\n\n  def resolver(*uri_args)\n    tk_send('resolver', *uri_args)\n  end\n\n  def selection_clear()\n    tk_send('selection', 'clear')\n    self\n  end\n\n  def selection_set(first, last)\n    tk_send('selection', 'set', first, last)\n    self\n  end\n\n  def refresh(*opts)\n    tk_send('refresh', *opts)\n  end\n\n  def layout()\n    tk_send('layout')\n  end\n\n  def sizewindow(*args)\n    tk_send('sizewindow', *args)\n  end\n\n  def postscript(*args)\n    tk_send('postscript', *args)\n  end\n\n  def source()\n    tk_send('source')\n  end\n\n  def plain_text(first, last)\n    tk_send('text', 'ascii', first, last)\n  end\n  alias ascii_text plain_text\n  alias text_ascii plain_text\n\n  def text_delete(first, last)\n    tk_send('text', 'delete', first, last)\n    self\n  end\n\n  def html_text(first, last)\n    tk_send('text', 'html', first, last)\n  end\n  alias text_html html_text\n\n  def text_insert(idx, txt)\n    tk_send('text', 'insert', idx, txt)\n    self\n  end\n\n  def break_text(idx)\n    tk_send('text', 'break', idx)\n  end\n  alias text_break break_text\n\n  def text_find(txt, *args)\n    tk_send('text', 'find', txt, *args)\n  end\n\n  def text_table(idx, imgs=None, attrs=None)\n    tk_send('text', 'table', idx, imgs, attrs)\n  end\n\n  def token_append(tag, *args)\n    tk_send('token', 'append', tag, *args)\n    self\n  end\n\n  def token_delete(first, last=None)\n    tk_send('token', 'delete', first, last)\n    self\n  end\n\n  def token_define(*args)\n    tk_send('token', 'defile', *args)\n    self\n  end\n\n  def token_find(tag, *args)\n    list(tk_send('token', 'find', tag, *args))\n  end\n\n  def token_get(first, last=None)\n    list(tk_send('token', 'get', first, last))\n  end\n\n  def token_list(first, last=None)\n    list(tk_send('token', 'list', first, last))\n  end\n\n  def token_markup(first, last=None)\n    list(tk_send('token', 'markup', first, last))\n  end\n\n  def token_DOM(first, last=None)\n    list(tk_send('token', 'domtokens', first, last))\n  end\n  alias token_dom token_DOM\n  alias token_domtokens token_DOM\n  alias token_dom_tokens token_DOM\n\n  def token_get_end(idx)\n    tk_send('token', 'getend', idx)\n  end\n  alias token_getend token_get_end\n\n  def token_offset(start, num1, num2)\n    list(tk_send('token', 'offset', start, num1, num2))\n  end\n\n  def token_get_attr(idx, name=None)\n    list(tk_send('token', 'attr', idx, name))\n  end\n\n  def token_set_attr(idx, name=None, val=None)\n    tk_send('token', 'attr', idx, name, val)\n    self\n  end\n\n  def token_handler(tag, cmd=nil, &b)\n    cmd = Proc.new(&b) if !cmd && b\n    if cmd\n      tk_send('token', 'handler', tag, cmd)\n      return self\n    else\n      return tk_send('token', 'handler', tag)\n    end\n  end\n\n  def token_insert(idx, tag, *args)\n    tk_send('token', 'insert', idx, tag, *args)\n    self\n  end\n\n  def token_attrs(*args)\n    list(tk_send('token', 'attrs', *args))\n  end\n\n  def token_unique(*args)\n    list(tk_send('token', 'unique', *args))\n  end\n\n  def token_on_events(*args)\n    list(tk_send('token', 'onEvents', *args))\n  end\n\n  def dom_nameidx(tag, name)\n    number(tk_send('dom', 'nameidx', tag, name))\n  end\n  alias dom_name_index dom_nameidx\n\n  def dom_radioidx(tag, name)\n    number(tk_send('dom', 'radioidx', tag, name))\n  end\n  alias dom_radio_index dom_radioidx\n\n  def dom_id(*spec)\n    tk_send('dom', 'id', *spec)\n  end\n\n  def dom_ids(*spec)\n    list(tk_send('dom', 'ids', *spec))\n  end\n\n  def dom_value(*spec)\n    list(tk_send('dom', 'value', *spec))\n  end\n\n  def dom_attr(idx)\n    tk_send('dom', 'attr', idx)\n  end\n\n  def dom_formel(name)\n    tk_send('dom', 'formel', name)\n  end\n  alias dom_form_element dom_formel\n\n  def dom_tree(idx, val)\n    list(tk_send('dom', 'tree', idx, val))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkHTML/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkHTML.rb",
    "content": "#\n#  TkHtml support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkHTML/setup.rb'\n\n# load library\nrequire 'tkextlib/tkHTML/htmlwidget'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/README",
    "content": "\n [ Tcl/Tk Image formats (TkImg) support ]\n\nTkImg contains a collection of format handlers for the Tk photo\nimage type, and a new image type, pixmaps.  \n\nSupported formats of TkImg version 1.3 are\n-------------------------------------------------------\n   bmp    : Windows Bitmap Format\n   gif    : Graphics Interchange Format\n   ico    : Windows Icon Format\n   jpeg   : Joint Picture Expert Group format\n   pcx    : Paintbrush Format\n   pixmap : Pixmap Image type\n   png    : Portable Network Graphics format\n   ppm    : Portable Pixmap format\n   ps     : Adobe PostScript Format\n   sgi    : SGI Native Format\n   sun    : Sun Raster Format\n   tga    : Truevision Targa Format\n   tiff   : Tagged Image File Format\n   window : Tk Windows\n   xbm    : X Window Bitmap Format\n   xpm    : X Window Pixmap Format\n-------------------------------------------------------\n\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/bmp.rb",
    "content": "#\n#  TkImg - format 'bmp'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n#TkPackage.require('img::bmp', '1.3')\nTkPackage.require('img::bmp')\n\nmodule Tk\n  module Img\n    module BMP\n      PACKAGE_NAME = 'img::bmp'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::bmp')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/gif.rb",
    "content": "#\n#  TkImg - format 'gif'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::gif', '1.3')\nTkPackage.require('img::gif')\n\nmodule Tk\n  module Img\n    module GIF\n      PACKAGE_NAME = 'img::gif'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::gif')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/ico.rb",
    "content": "#\n#  TkImg - format 'ico'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::ico', '1.3')\nTkPackage.require('img::ico')\n\nmodule Tk\n  module Img\n    module ICO\n      PACKAGE_NAME = 'img::ico'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::ico')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/jpeg.rb",
    "content": "#\n#  TkImg - format 'jpeg'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::jpeg', '1.3')\nTkPackage.require('img::jpeg')\n\nmodule Tk\n  module Img\n    module JPEG\n      PACKAGE_NAME = 'img::jpeg'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::jpeg')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/pcx.rb",
    "content": "#\n#  TkImg - format 'pcx'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::pcx', '1.3')\nTkPackage.require('img::pcx')\n\nmodule Tk\n  module Img\n    module PCX\n      PACKAGE_NAME = 'img::pcx'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::pcx')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/pixmap.rb",
    "content": "#\n#  TkImg - format 'pixmap'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::pixmap', '1.3')\nTkPackage.require('img::pixmap')\n\nmodule Tk\n  module Img\n    module PIXMAP\n      PACKAGE_NAME = 'img::pixmap'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::pixmap')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n\nclass TkPixmapImage<TkImage\n  def self.version\n    Tk::Img::PIXMAP.version\n  end\n\n  def initialize(*args)\n    @type = 'pixmap'\n    super(*args)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/png.rb",
    "content": "#\n#  TkImg - format 'png'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::png', '1.3')\nTkPackage.require('img::png')\n\nmodule Tk\n  module Img\n    module PNG\n      PACKAGE_NAME = 'img::png'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::png')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/ppm.rb",
    "content": "#\n#  TkImg - format 'ppm'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::ppm', '1.3')\nTkPackage.require('img::ppm')\n\nmodule Tk\n  module Img\n    module PPM\n      PACKAGE_NAME = 'img::ppm'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::ppm')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/ps.rb",
    "content": "#\n#  TkImg - format 'ps'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::ps', '1.3')\nTkPackage.require('img::ps')\n\nmodule Tk\n  module Img\n    module PS\n      PACKAGE_NAME = 'img::ps'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::ps')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/sgi.rb",
    "content": "#\n#  TkImg - format 'sgi'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::sgi', '1.3')\nTkPackage.require('img::sgi')\n\nmodule Tk\n  module Img\n    module SGI\n      PACKAGE_NAME = 'img::sgi'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::sgi')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/sun.rb",
    "content": "#\n#  TkImg - format 'sun'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::sun', '1.3')\nTkPackage.require('img::sun')\n\nmodule Tk\n  module Img\n    module SUN\n      PACKAGE_NAME = 'img::sun'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::sun')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/tga.rb",
    "content": "#\n#  TkImg - format 'tga'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::tga', '1.3')\nTkPackage.require('img::tga')\n\nmodule Tk\n  module Img\n    module TGA\n      PACKAGE_NAME = 'img::tga'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::tga')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/tiff.rb",
    "content": "#\n#  TkImg - format 'tiff'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::tiff', '1.3')\nTkPackage.require('img::tiff')\n\nmodule Tk\n  module Img\n    module TIFF\n      PACKAGE_NAME = 'img::tiff'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::tiff')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/window.rb",
    "content": "#\n#  TkImg - format 'window'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::window', '1.3')\nTkPackage.require('img::window')\n\nmodule Tk\n  module Img\n    module WINDOW\n      PACKAGE_NAME = 'img::window'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::window')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/xbm.rb",
    "content": "#\n#  TkImg - format 'xbm'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::xbm', '1.3')\nTkPackage.require('img::xbm')\n\nmodule Tk\n  module Img\n    module XBM\n      PACKAGE_NAME = 'img::xbm'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::xbm')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg/xpm.rb",
    "content": "#\n#  TkImg - format 'xpm'\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# TkPackage.require('img::xpm', '1.3')\nTkPackage.require('img::xpm')\n\nmodule Tk\n  module Img\n    module XPM\n      PACKAGE_NAME = 'img::xpm'.freeze\n      def self.package_name\n        PACKAGE_NAME\n      end\n\n      def self.package_version\n        begin\n          TkPackage.require('img::xpm')\n        rescue\n          ''\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tkimg.rb",
    "content": "#\n#  TkImg extension support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tkimg/setup.rb'\n\n# load all image format handlers\n#TkPackage.require('Img', '1.3')\nTkPackage.require('Img')\n\nmodule Tk\n  module Img\n    PACKAGE_NAME = 'Img'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Img')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\n# autoload\nautoload :TkPixmapImage, 'tkextlib/tkimg/pixmap'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tktable/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tktable/tktable.rb",
    "content": "#\n#  tkextlib/tktable/tktable.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\nrequire 'tk/validation'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tktable/setup.rb'\n\n# TkPackage.require('Tktable', '2.8')\nTkPackage.require('Tktable')\n\nmodule Tk\n  class TkTable < TkWindow\n    PACKAGE_NAME = 'Tktable'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('Tktable')\n      rescue\n        ''\n      end\n    end\n\n    class CellTag < TkObject\n    end\n\n    module ConfigMethod\n    end\n  end\nend\n\nmodule Tk::TkTable::ConfigMethod\n  include TkItemConfigMethod\n\n  def __item_cget_cmd(id)  # id := [ type, tagOrId ]\n    [self.path, id[0], 'cget', id[1]]\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(id)  # id := [ type, tagOrId ]\n    [self.path, id[0], 'configure', id[1]]\n  end\n  private :__item_config_cmd\n\n  def __item_pathname(id)\n    if id.kind_of?(Array)\n      id = tagid(id[1])\n    end\n    [self.path, id].join(';')\n  end\n  private :__item_pathname\n\n  def __item_boolval_optkeys(id)\n    super(id) << 'multiline' << 'showtext' << 'wrap'\n  end\n  private :__item_boolval_optkeys\n\n  def __item_strval_optkeys(id)\n    super(id) << 'ellipsis'\n  end\n  private :__item_strval_optkeys\n\n  def __item_val2ruby_optkeys(id)  # { key=>method, ... }\n    super(id).update('window'=>proc{|v| window(v)})\n  end\n  private :__item_val2ruby_optkeys\n\n  def tag_cget(tagOrId, option)\n    itemcget(['tag', tagid(tagOrId)], option)\n  end\n  def tag_cget_strict(tagOrId, option)\n    itemcget_strict(['tag', tagid(tagOrId)], option)\n  end\n  def tag_configure(tagOrId, slot, value=None)\n    itemconfigure(['tag', tagid(tagOrId)], slot, value)\n  end\n  def tag_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['tag', tagid(tagOrId)], slot)\n  end\n  def current_tag_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['tag', tagid(tagOrId)], slot)\n  end\n\n  def window_cget(tagOrId, option)\n    itemcget(['window', tagid(tagOrId)], option)\n  end\n  def window_cget_strict(tagOrId, option)\n    itemcget_strict(['window', tagid(tagOrId)], option)\n  end\n  def window_configure(tagOrId, slot, value=None)\n    if slot == :window || slot == 'window'\n      value = _epath(value)\n    elsif slot.kind_of?(Hash)\n      if slot.key?(:window) || slot.key?('window')\n        slot = _symbolkey2str(slot)\n        slot['window'] = _epath(slot['window'])\n      end\n    end\n    itemconfigure(['window', tagid(tagOrId)], slot, value)\n  end\n  def window_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['window', tagid(tagOrId)], slot)\n  end\n  def current_window_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['window', tagid(tagOrId)], slot)\n  end\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\nend\n\n#####################################################\n\nclass Tk::TkTable::CellTag\n  include TkTreatTagFont\n\n  CellTagID_TBL = TkCore::INTERP.create_table\n\n  (CellTag_ID = ['tktbl:celltag'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    CellTagID_TBL.mutex.synchronize{ CellTagID_TBL.clear }\n  }\n\n  def self.id2obj(table, id)\n    tpath = table.path\n    CellTagID_TBL.mutex.synchronize{\n      if CellTagID_TBL[tpath]\n        CellTagID_TBL[tpath][id]? CellTagID_TBL[tpath][id] : id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(parent, keys=nil)\n    @parent = @t = parent\n    @tpath - parent.path\n    CellTag_ID.mutex.synchronize{\n      @path = @id = CellTag_ID.join(TkCore::INTERP._ip_id_)\n      CellTag_ID[1].succ!\n    }\n    CellTagID_TBL.mutex.synchronize{\n      CellTagID_TBL[@tpath] = {} unless CellTagID_TBL[@tpath]\n      CellTagID_TBL[@tpath][@id] = self\n    }\n    configure(keys) if keys\n  end\n\n  def id\n    @id\n  end\n\n  def destroy\n    tk_call(@tpath, 'tag', 'delete', @id)\n    CellTagID_TBL.mutex.synchronize{\n      CellTagID_TBL[@tpath].delete(@id) if CellTagID_TBL[@tpath]\n    }\n    self\n  end\n  alias delete destroy\n\n  def exist?\n    @t.tag_exist?(@id)\n  end\n  def include?(idx)\n    @t.tag_include?(@id, idx)\n  end\n\n  def add_cell(*args)\n    @t.tag_cell(@id, *args)\n  end\n  def add_col(*args)\n    @t.tag_col(@id, *args)\n  end\n  def add_row(*args)\n    @t.tag_row(@id, *args)\n  end\n\n  def raise(target=None)\n    @t.tag_raise(@id, target)\n  end\n  def lower(target=None)\n    @t.tag_lower(@id, target)\n  end\n\n  def cget(key)\n    @t.tag_cget(@id, key)\n  end\n  def cget_strict(key)\n    @t.tag_cget_strict(@id, key)\n  end\n  def configure(key, val=None)\n    @t.tag_configure(@id, key, val)\n  end\n  def configinfo(key=nil)\n    @t.tag_configinfo(@id, key)\n  end\n  def current_configinfo(key=nil)\n    @t.current_tag_configinfo(@id, key)\n  end\nend\n\nclass Tk::TkTable::NamedCellTag < Tk::TkTable::CellTag\n  def self.new(parent, name, keys=nil)\n    obj = nil\n    CellTagID_TBL.mutex.synchronize{\n      if CellTagID_TBL[parent.path] && CellTagID_TBL[parent.path][name]\n        obj = CellTagID_TBL[parent.path][name]\n      else\n        #super(parent, name, keys)\n        (obj = self.allocate).instance_eval{\n          @parent = @t = parent\n          @tpath = parent.path\n          @path = @id = name\n          CellTagID_TBL[@tpath] = {} unless CellTagID_TBL[@tpath]\n          CellTagID_TBL[@tpath][@id] = self\n        }\n      end\n    }\n    obj.configure(keys) if keys && ! keys.empty?\n    obj\n  end\n\n  def initialize(parent, name, keys=nil)\n    # dummy:: not called by 'new' method\n    @parent = @t = parent\n    @tpath = parent.path\n    @path = @id = name\n    CellTagID_TBL.mutex.synchronize{\n      CellTagID_TBL[@tpath] = {} unless CellTagID_TBL[@tpath]\n      CellTagID_TBL[@tpath][@id] = self\n    }\n    configure(keys) if keys && ! keys.empty?\n  end\nend\n\n#####################################################\n\nclass Tk::TkTable\n  TkCommandNames = ['table'.freeze].freeze\n  WidgetClassName = 'Table'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  include Scrollable\n  include Tk::TkTable::ConfigMethod\n  include Tk::ValidateConfigure\n\n  def __destroy_hook__\n    Tk::TkTable::CelTag::CellTagID_TBL.mutex.synchronize{\n      Tk::TkTable::CelTag::CellTagID_TBL.delete(@path)\n    }\n  end\n\n  def __boolval_optkeys\n    super() << 'autoclear' << 'flashmode' << 'invertselected' <<\n      'multiline' << 'selecttitle' << 'wrap'\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() << 'colseparator' << 'ellipsis' << 'rowseparator' << 'sparsearray'\n  end\n  private :__strval_optkeys\n\n\n  #################################\n\n  class BrowseCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?c, ?n, :column ], \n        [ ?C, ?s, :index ], \n        [ ?i, ?x, :cursor ], \n        [ ?r, ?n, :row ], \n        [ ?s, ?s, :last_index ], \n        [ ?S, ?s, :new_index ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?n, TkComm.method(:number) ], \n        [ ?x, TkComm.method(:num_or_str) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      ['browsecommand', 'browsecmd']\n    end\n  end\n  #--------------------------------\n  class CellCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?c, ?n, :column ], \n        [ ?C, ?s, :index ], \n        [ ?i, ?m, :rw_mode ], \n        [ ?r, ?n, :row ], \n        [ ?s, ?v, :value ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?n, TkComm.method(:number) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        [ ?m, proc{|val| (val == '0')? (:r) : (:w)} ], \n        [ ?v, proc{|val| TkComm.tk_tcl2ruby(val, true, false)} ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        TkComm._get_eval_string(val)\n      end\n    end\n\n    def self._config_keys\n      ['command']\n    end\n  end\n  #--------------------------------\n  class SelectionCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?c, ?n, :sel_columns ], \n        [ ?C, ?s, :sel_area ], \n        [ ?i, ?n, :total ], \n        [ ?r, ?n, :sel_rows ], \n        [ ?s, ?s, :value ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?n, TkComm.method(:number) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val.to_s\n      end\n    end\n\n    def self._config_keys\n      ['selectioncommand', 'selcmd']\n    end\n  end\n  #--------------------------------\n  class ValidateCommand < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?c, ?n, :column ], \n        [ ?C, ?s, :index ], \n        [ ?i, ?x, :cursor ], \n        [ ?r, ?n, :row ], \n        [ ?s, ?v, :current_value ], \n        [ ?S, ?v, :new_value ], \n        [ ?W, ?w, :widget ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?n, TkComm.method(:number) ], \n        [ ?x, TkComm.method(:num_or_str) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?w, TkComm.method(:window) ], \n        [ ?v, proc{|val| TkComm.tk_tcl2ruby(val, true, false)} ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n    end\n\n    def self._config_keys\n      ['vcmd', 'validatecommand']\n    end\n  end\n\n  #################################\n\n  def __validation_class_list\n    super() << \n      BrowseCommand << CellCommand << SelectionCommand << ValidateCommand\n  end\n\n  Tk::ValidateConfigure.__def_validcmd(binding, BrowseCommand)\n  Tk::ValidateConfigure.__def_validcmd(binding, CellCommand)\n  Tk::ValidateConfigure.__def_validcmd(binding, SelectionCommand)\n  Tk::ValidateConfigure.__def_validcmd(binding, ValidateCommand)\n\n  #################################\n\n  def activate(idx)\n    tk_send('activate', tagid(idx))\n  end\n\n  def bbox(idx)\n    list(tk_send('bbox', tagid(idx)))\n  end\n\n  def border_mark(x, y)\n    simplelist(tk_send('border', 'mark', x, y))\n  end\n  def border_mark_row(x, y)\n    tk_send('border', 'mark', x, y, 'row')\n  end\n  def border_mark_col(x, y)\n    tk_send('border', 'mark', x, y, 'col')\n  end\n  def border_dragto(x, y)\n    tk_send('border', 'dragto', x, y)\n  end\n\n  def clear_cache(first=None, last=None)\n    tk_send('clear', 'cache', tagid(first), tagid(last))\n    self\n  end\n  def clear_sizes(first=None, last=None)\n    tk_send('clear', 'sizes', tagid(first), tagid(last))\n    self\n  end\n  def clear_tags(first=None, last=None)\n    tk_send('clear', 'tags', tagid(first), tagid(last))\n    self\n  end\n  def clear_all(first=None, last=None)\n    tk_send('clear', 'all', tagid(first), tagid(last))\n    self\n  end\n\n  def curselection\n    simplelist(tk_send('curselection'))\n  end\n  def curselection=(val)\n    tk_send('curselection', val)\n    val\n  end\n\n  def curvalue\n    tk_tcl2ruby(tk_send('curvalue'), true, false)\n  end\n  def curvalue=(val)\n    tk_send('curvalue', val)\n    val\n  end\n\n  def delete_active(idx1, idx2=None)\n    tk_send('delete', 'active', tagid(idx1), tagid(idx2))\n    self\n  end\n  def delete_cols(*args) # ?switches_array?, index, ?count?\n    params = []\n    if args[0].kind_of?(Array)\n      switches = args.shift\n      switches.each{|k| params << \"-#{k}\"}\n    end\n    params << '--'\n    params << tagid(args.shift)\n    params.concat(args)\n    tk_send('delete', 'cols', *params)\n    self\n  end\n  def delete_rows(*args) # ?switches_array?, index, ?count?\n    params = []\n    if args[0].kind_of?(Array)\n      switches = args.shift\n      switches.each{|k| params << \"-#{k}\"}\n    end\n    params << '--'\n    params << tagid(args.shift)\n    params.concat(args)\n    tk_send('delete', 'rows', *params)\n    self\n  end\n\n  def get(idx)\n    tk_tcl2ruby(tk_send('get', tagid(idx)), true, false)\n  end\n  def get_area(idx1, idx2)\n    simplelist(tk_send('get', tagid(idx1), tagid(idx2))).collect{|v|\n      tk_tcl2ruby(v, true, false)\n    }\n  end\n\n  def height_list\n    list(tk_send('height'))\n  end\n  def height(row)\n    number(tk_send('height', row))\n  end\n  def set_height(*pairs)\n    tk_send('height', *(pairs.flatten))\n    self\n  end\n\n  def hidden_list\n    simplelist(tk_send('hidden'))\n  end \n  def hidden?(idx, *args)\n    if args.empty?\n      if (ret = tk_send('hidden', tagid(idx))) == ''\n        false\n      else\n        ret\n      end\n    else\n      bool(tk_send('hidden', tagid(idx), *(args.collect{|i| tagid(i)})))\n    end\n  end\n\n  def icursor\n    number(tk_send('icursor'))\n  end\n  def icursor_set(idx)\n    number(tk_send('icursor', tagid(idx)))\n  end\n\n  def index(idx)\n    tk_send('index', tagid(idx))\n  end\n  def row_index(idx)\n    number(tk_send('index', tagid(idx), 'row'))\n  end\n  def col_index(idx)\n    number(tk_send('index', tagid(idx), 'col'))\n  end\n\n  def insert_active(idx, val)\n    tk_send('insert', 'active', tagid(idx), val)\n    self\n  end\n  def insert_cols(*args) # ?switches_array?, index, ?count?\n    params = []\n    if args[0].kind_of?(Array)\n      switches = args.shift\n      switches.each{|k| params << \"-#{k}\"}\n    end\n    params << '--'\n    params.concat(args)\n    params << tagid(args.shift)\n    tk_send('insert', 'cols', *params)\n    self\n  end\n  def insert_rows(*args) # ?switches_array?, index, ?count?\n    params = []\n    if args[0].kind_of?(Array)\n      switches = args.shift\n      switches.each{|k| params << \"-#{k}\"}\n    end\n    params << '--'\n    params << tagid(args.shift)\n    params.concat(args)\n    tk_send('insert', 'rows', *params)\n    self\n  end\n\n  # def postscript(*args)\n  #   tk_send('postscript', *args)\n  # end\n\n  def reread\n    tk_send('reread')\n    self\n  end\n\n  def scan_mark(x, y)\n    tk_send('scan', 'mark', x, y)\n    self\n  end\n  def scan_dragto(x, y)\n    tk_send('scan', 'dragto', x, y)\n    self\n  end\n\n  def see(idx)\n    tk_send('see', tagid(idx))\n    self\n  end\n\n  def selection_anchor(idx)\n    tk_send('selection', 'anchor', tagid(idx))\n    self\n  end\n  def selection_clear(first, last=None)\n    tk_send('selection', 'clear', tagid(first), tagid(last))\n    self\n  end\n  def selection_clear_all\n    selection_clear('all')\n  end\n  def selection_include?(idx)\n    bool(tk_send('selection', 'includes', tagid(idx)))\n  end\n  def selection_present\n    bool(tk_send('selection', 'present'))\n  end\n  def selection_set(first, last=None)\n    tk_send('selection', 'set', tagid(first), tagid(last))\n    self\n  end\n\n  def set(*pairs) # idx, val, idx, val, ... \n    args = []\n    0.step(pairs.size-1, 2){|i|\n      args << tagid(pairs[i])\n      args << pairs[i+1]\n    }\n    tk_send('set', *args)\n    self\n  end\n  def set_row(*pairs) # idx, val, idx, val, ... \n    args = []\n    0.step(pairs.size-1, 2){|i|\n      args << tagid(pairs[i])\n      args << pairs[i+1]\n    }\n    tk_send('set', 'row', *args)\n    self\n  end\n  def set_col(*pairs) # idx, val, idx, val, ... \n    args = []\n    0.step(pairs.size-1, 2){|i|\n      args << tagid(pairs[i])\n      args << pairs[i+1]\n    }\n    tk_send('set', 'col', *args)\n    self\n  end\n=begin\n  def set(*pairs) # idx, val, idx, val, ...  OR [idx, val], [idx, val], ...\n    if pairs[0].kind_of?(Array)\n      # [idx, val], [idx, val], ...\n      args = []\n      pairs.each{|idx, val| args << tagid(idx) << val }\n      tk_send('set', *args)\n    else\n      # idx, val, idx, val, ... \n      args = []\n      0.step(pairs.size-1, 2){|i|\n        args << tagid(pairs[i])\n        args << pairs[i+1]\n      }\n      tk_send('set', *args)\n    end\n    self\n  end\n  def set_row(*pairs)\n    if pairs[0].kind_of?(Array)\n      # [idx, val], [idx, val], ...\n      args = []\n      pairs.each{|idx, val| args << tagid(idx) << val }\n      tk_send('set', 'row', *args)\n    else\n      # idx, val, idx, val, ... \n      args = []\n      0.step(pairs.size-1, 2){|i|\n        args << tagid(pairs[i])\n        args << pairs[i+1]\n      }\n      tk_send('set', 'row', *args)\n    end\n    self\n  end\n  def set_col(*pairs)\n    if pairs[0].kind_of?(Array)\n      # [idx, val], [idx, val], ...\n      args = []\n      pairs.each{|idx, val| args << idx << val }\n      tk_send('set', 'col', *args)\n    else\n      # idx, val, idx, val, ... \n      args = []\n      0.step(pairs.size-1, 2){|i|\n        args << tagid(pairs[i])\n        args << pairs[i+1]\n      }\n      tk_send('set', 'col', *args)\n    end\n    self\n  end\n=end\n\n  def spans\n    simplelist(tk_send('spans')).collect{|inf|\n      lst = simplelist(inf)\n      idx = lst[0]\n      rows, cols = lst[1].split(',').map!{|n| Integer(n)}\n      [idx [rows, cols]]\n    }\n  end\n  alias span_list spans\n  def span(idx)\n    lst = simplelist(tk_send('spans', tagid(idx)))\n    idx = lst[0]\n    rows, cols = lst[1].split(',').map!{|n| Integer(n)}\n    [idx [rows, cols]]\n  end\n  def set_spans(*pairs)\n    # idx, val, idx, val, ... \n    args = []\n    0.step(pairs.size-1, 2){|i|\n      args << tagid(pairs[i])\n      val = pairs[i+1]\n      if val.kind_of?(Array)\n        args << val.join(',')\n      else\n        args << val\n      end\n    }\n    tk_send('spans', *args)\n    self\n  end\n=begin\n  def set_spans(*pairs)\n    if pairs[0].kind_of?(Array)\n      # [idx, val], [idx, val], ...\n      args = []\n      pairs.each{|idx, val|\n        args << tagid(idx)\n        if val.kind_of?(Array)\n          args << val.join(',')\n        else\n          args << val\n        end\n      }\n      tk_send('spans', *args)\n    else\n      # idx, val, idx, val, ... \n      args = []\n      0.step(pairs.size-1, 2){|i|\n        args << tagid(pairs[i])\n        val = pairs[i+1]\n        if val.kind_of?(Array)\n          args << val.join(',')\n        else\n          args << val\n        end\n      }\n      tk_send('spans', *args)\n    end\n    self\n  end\n=end\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::TkTable::CellTag)\n      tag.id\n    elsif tag.kind_of?(Array)\n      if tag[0].kind_of?(Integer) && tag[1].kind_of?(Integer)\n        # [row, col]\n        tag.join(',')\n      else\n        tag\n      end\n    else\n      tag\n    end\n  end\n\n  def tagid2obj(tagid)\n    Tk::TkTable::CellTag::CellTagID_TBL.mutex.synchronize{\n      if Tk::TkTable::CellTag::CellTagID_TBL.key?(@path)\n        if Tk::TkTable::CellTag::CellTagID_TBL[@path].key?(tagid)\n          Tk::TkTable::CellTag::CellTagID_TBL[@path][tagid]\n        else\n          tagid\n        end\n      else\n        tagid\n      end\n    }\n  end\n\n  def tag_cell(tag, *cells)\n    tk_send('tag', 'cell', tagid(tag), *(cells.collect{|idx| tagid(idx)}))\n    self\n  end\n  def tag_reset(*cells)\n    tk_send('tag', 'cell', '', *(cells.collect{|idx| tagid(idx)}))\n    self\n  end\n  def tag_col(tag, *cols)\n    tk_send('tag', 'col', tagid(tag), *cols)\n    self\n  end\n  def tag_col_reset(*cols)\n    tk_send('tag', 'col', '', *cols)\n    self\n  end\n  def tag_delete(tag)\n    tk_send('tag', 'delete', tagid(tag))\n    Tk::TkTable::CellTag::CellTagID_TBL.mutex.synchronize{\n      if Tk::TkTable::CellTag::CellTagID_TBL[@path]\n        if tag.kind_of? Tk::TkTable::CellTag\n          Tk::TkTable::CellTag::CellTagID_TBL[@path].delete(tag.id) \n        else\n          Tk::TkTable::CellTag::CellTagID_TBL[@path].delete(tag) \n        end\n      end\n    }\n    self\n  end\n  def tag_exist?(tag)\n    bool(tk_send('tag', 'exists', tagid(tag)))\n  end\n  def tag_include?(tag, idx)\n    bool(tk_send('tag', 'includes', tagid(tag), tagid(idx)))\n  end\n  def tag_lower(tag, target=None)\n    tk_send('tag', 'lower', tagid(tag), tagid(target))\n    self\n  end\n  def tag_names(pat=None)\n    simplelist(tk_send('tag', 'names', pat)).collect{|tag| tagid2obj(tag)}\n  end\n  def tag_raise(tag, target=None)\n    tk_send('tag', 'raise', tagid(tag), tagid(target))\n    self\n  end\n  def tag_row(tag, *rows)\n    tk_send('tag', 'row', tagid(tag), *rows)\n    self\n  end\n  def tag_row_reset(*rows)\n    tk_send('tag', 'row', '', *rows)\n    self\n  end\n\n  def validate(idx)\n    bool(tk_send('validate', tagid(idx)))\n  end\n\n  def width_list\n    list(tk_send('width'))\n  end\n  def width(row)\n    number(tk_send('width', row))\n  end\n  def set_width(*pairs)\n    tk_send('width', *(pairs.flatten))\n    self\n  end\n\n  def window_delete(*args)\n    tk_send('window', 'delete', *(args.collect{|idx| tagid(idx)}))\n    self\n  end\n  def window_move(from_idx, to_idx)\n    tk_send('window', 'move', tagid(from_idx), tagid(to_idx))\n    self\n  end\n  def window_names(pat=None)\n    simplelist(tk_send('window', 'names', pat))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tktable.rb",
    "content": "#\n#  TkTable support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tktable/setup.rb'\n\n# load library\nrequire 'tkextlib/tktable/tktable'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tktrans/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tktrans/tktrans.rb",
    "content": "#\n#  TkTrans support (win32 only)\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tktrans/setup.rb'\n\nTkPackage.require('tktrans') rescue Tk.load_tcllibrary('tktrans')\n\nmodule Tk\n  module TkTrans\n    PACKAGE_NAME = 'tktrans'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('tktrans')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\nclass TkWindow\n  def tktrans_set_image(img)\n    tk_send('tktrans::setwidget', @path, img)\n    self\n  end\n  def tktrans_get_image()\n    tk_send('tktrans::setwidget', @path)\n  end\nend\n\nclass Tk::Root\n  undef tktrans_set_image, tktrans_get_image\n\n  def tktrans_set_image(img)\n    tk_send('tktrans::settoplevel', @path, img)\n    self\n  end\n  def tktrans_get_image()\n    tk_send('tktrans::settoplevel', @path)\n  end\nend\n\nclass Tk::Toplevel\n  undef tktrans_set_image, tktrans_get_image\n\n  def tktrans_set_image(img)\n    tk_send('tktrans::settoplevel', @path, img)\n    self\n  end\n  def tktrans_get_image()\n    tk_send('tktrans::settoplevel', @path)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/tktrans.rb",
    "content": "#\n#  TkTrans support (win32 only)\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tktrans/setup.rb'\n\n# load library\nrequire 'tkextlib/tktrans/tktrans'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/treectrl/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/treectrl/tktreectrl.rb",
    "content": "#\n#  tkextlib/treectrl/tktreectrl.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/treectrl/setup.rb'\n\n# TkPackage.require('treectrl', '1.0')\n# TkPackage.require('treectrl', '1.1')\nTkPackage.require('treectrl')\n\nmodule Tk\n  class TreeCtrl < TkWindow\n    BindTag_FileList = TkBindTag.new_by_name('TreeCtrlFileList')\n\n    PACKAGE_NAME = 'treectrl'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('treectrl')\n      rescue\n        ''\n      end\n    end\n\n    HasColumnCreateCommand = \n      (TkPackage.vcompare(self.package_version, '1.1') >= 0)\n\n    # dummy :: \n    #  pkgIndex.tcl of TreeCtrl-1.0 doesn't support auto_load for \n    #  'loupe' command (probably it is bug, I think). \n    #  So, calling a 'treectrl' command for loading the dll with \n    #  the auto_load facility. \n    begin\n      tk_call('treectrl')\n    rescue\n    end\n    def self.loupe(img, x, y, w, h, zoom)\n      # NOTE: platform == 'unix' only\n\n      # img  => TkPhotoImage\n      # x, y => screen coords \n      # w, h => magnifier width and height\n      # zoom => zooming rate\n      Tk.tk_call_without_enc('loupe', img, x, y, w, h, zoom)\n    end\n\n    def self.text_layout(font, text, keys={})\n      TkComm.list(Tk.tk_call_without_enc('textlayout', font, text, keys))\n    end\n\n    def self.image_tint(img, color, alpha)\n      Tk.tk_call_without_enc('imagetint', img, color, alpha)\n    end\n\n    class NotifyEvent < TkUtil::CallbackSubst\n    end\n\n    module ConfigMethod\n    end\n  end\n  TreeCtrl_Widget = TreeCtrl\nend\n\n##############################################\n\nclass Tk::TreeCtrl::NotifyEvent\n  # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>]\n  KEY_TBL = [\n    [ ?c, ?n, :item_num ], \n    [ ?d, ?s, :detail ], \n    [ ?D, ?l, :items ], \n    [ ?e, ?e, :event ], \n    [ ?I, ?n, :id ], \n    [ ?l, ?n, :lower_bound ], \n    [ ?p, ?n, :active_id ], \n    [ ?P, ?e, :pattern ], \n    [ ?S, ?l, :sel_items ], \n    [ ?T, ?w, :widget ], \n    [ ?u, ?n, :upper_bound ], \n    [ ?W, ?o, :object ], \n    [ ??, ?x, :parm_info ], \n    nil\n  ]\n\n  # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>]\n  PROC_TBL = [\n    [ ?n, TkComm.method(:num_or_str) ], \n    [ ?s, TkComm.method(:string) ], \n    [ ?l, TkComm.method(:list) ], \n    [ ?w, TkComm.method(:window) ], \n\n    [ ?e, proc{|val|\n        case val\n        when /^<<[^<>]+>>$/\n          TkVirtualEvent.getobj(val[1..-2])\n        when /^<[^<>]+>$/\n          val[1..-2]\n        else\n          val\n        end\n      }\n    ], \n\n    [ ?o, proc{|val| TkComm.tk_tcl2ruby(val)} ], \n\n    [ ?x, proc{|val|\n        begin\n          inf = {}\n          Hash[*(TkComm.list(val))].each{|k, v|\n            if keyinfo = KEY_TBL.assoc(k[0])\n              if cmd = PROC_TBL.assoc(keyinfo[1])\n                begin\n                  new_v = cmd.call(v)\n                  v = new_v\n                rescue\n                end\n              end\n            end\n            inf[k] = v\n          }\n          inf\n        rescue\n          val\n        end\n      } ], \n\n    nil\n  ]\n\n=begin\n  # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n  KEY_TBL.map!{|inf|\n    if inf.kind_of?(Array)\n      inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n      inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n    end\n    inf\n  }\n\n  PROC_TBL.map!{|inf|\n    if inf.kind_of?(Array)\n      inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n    end\n    inf\n  }\n=end\n\n  # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys\n  #\n  #     _get_subst_key() and _get_all_subst_keys() generates key-string \n  #     which describe how to convert callback arguments to ruby objects. \n  #     When binding parameters are given, use _get_subst_key(). \n  #     But when no parameters are given, use _get_all_subst_keys() to \n  #     create a Event class object as a callback parameter. \n  #\n  #     scan_args() is used when doing callback. It convert arguments \n  #     ( which are Tcl strings ) to ruby objects based on the key string \n  #     that is generated by _get_subst_key() or _get_all_subst_keys(). \n  #\n  _setup_subst_table(KEY_TBL, PROC_TBL);\nend\n\n##############################################\n\nmodule Tk::TreeCtrl::ConfigMethod\n  include TkItemConfigMethod\n\n  def treectrl_tagid(key, obj)\n    if key.kind_of?(Array)\n      key = key.join(' ')\n    else\n      key = key.to_s\n    end\n\n    if (obj.kind_of?(Tk::TreeCtrl::Column) ||\n        obj.kind_of?(Tk::TreeCtrl::Element) ||\n        obj.kind_of?(Tk::TreeCtrl::Item) ||\n        obj.kind_of?(Tk::TreeCtrl::Style)) \n      obj = obj.id\n    end\n\n    case key\n    when 'column'\n      obj\n\n    when 'debug'\n      None\n\n    when 'dragimage'\n      None\n\n    when 'element'\n      obj\n\n    when 'item element'\n      obj\n\n    when 'marquee'\n      None\n\n    when 'notify'\n      obj\n\n    when 'style'\n      obj\n\n    else\n      obj\n    end\n  end\n\n  def tagid(mixed_id)\n    if mixed_id == 'debug'\n      ['debug', None]\n    elsif mixed_id == 'dragimage'\n      ['dragimage', None]\n    elsif mixed_id == 'marquee'\n      ['marquee', None]\n    elsif mixed_id.kind_of?(Array)\n      [mixed_id[0], treectrl_tagid(*mixed_id)]\n    else\n      tagid(mixed_id.split(':'))\n    end\n  end\n\n  def __item_cget_cmd(mixed_id)\n    if mixed_id[0] == 'column' && mixed_id[1] == 'drag'\n      return [self.path, 'column', 'dragcget']\n    end \n\n    if mixed_id[1].kind_of?(Array)\n      id = mixed_id[1]\n    else\n      id = [mixed_id[1]]\n    end\n\n    if mixed_id[0].kind_of?(Array)\n      ([self.path].concat(mixed_id[0]) << 'cget').concat(id)\n    else\n      [self.path, mixed_id[0], 'cget'].concat(id)\n    end\n  end\n  private :__item_cget_cmd\n\n  def __item_config_cmd(mixed_id)\n    if mixed_id[0] == 'column' && mixed_id[1] == 'drag'\n      return [self.path, 'column', 'dragconfigure']\n    end \n\n    if mixed_id[1].kind_of?(Array)\n      id = mixed_id[1]\n    else\n      id = [mixed_id[1]]\n    end\n\n    if mixed_id[0].kind_of?(Array)\n      ([self.path].concat(mixed_id[0]) << 'configure').concat(id)\n    else\n      [self.path, mixed_id[0], 'configure'].concat(id)\n    end\n  end\n  private :__item_config_cmd\n\n  def __item_pathname(id)\n    if id.kind_of?(Array)\n      key = id[0]\n      if key.kind_of?(Array)\n        key = key.join(' ')\n      end\n\n      tag = id[1]\n      if tag.kind_of?(Array)\n        tag = tag.join(' ')\n      end\n\n      id = [key, tag].join(':')\n    end\n    [self.path, id].join(';')\n  end\n  private :__item_pathname\n\n  def __item_configinfo_struct(id)\n    if id.kind_of?(Array) && id[0].to_s == 'notify'\n      {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, \n        :default_value=>nil, :current_value=>1}\n    else\n      {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, \n        :default_value=>3, :current_value=>4}\n    end\n  end\n  private :__item_configinfo_struct\n\n\n  def __item_font_optkeys(id)\n    if id.kind_of?(Array) && (id[0] == 'element' || \n                              (id[0].kind_of?(Array) && id[0][1] == 'element'))\n      []\n    else\n      ['font']\n    end\n  end\n  private :__item_font_optkeys\n\n  def __item_numstrval_optkeys(id)\n    if id == 'debug'\n      ['displaydelay']\n    else\n      super(id)\n    end\n  end\n  private :__item_numstrval_optkeys\n\n  def __item_boolval_optkeys(id)\n    if id == 'debug'\n      ['data', 'display', 'enable']\n    elsif id == 'dragimage'\n      ['visible']\n    elsif id == 'marquee'\n      ['visible']\n    elsif id.kind_of?(Array)\n      case id[0]\n      when 'item'\n        ['button', 'visible']\n      when 'column'\n        if id[1] == 'drag'\n          ['enable']\n        else\n          ['button', 'expand', 'resize', 'squeeze', 'sunken', \n            'visible', 'widthhack']\n        end\n      when 'element'\n        ['draw', 'filled', 'showfocus', 'destroy']\n      when 'notify'\n        ['active']\n      when 'style'\n        ['detach']\n      else\n        if id[0].kind_of?(Array) && id[0][1] == 'element'\n          ['filled', 'showfocus']\n        else\n          super(id)\n        end\n      end\n    else\n      super(id)\n    end\n  end\n  private :__item_boolval_optkeys\n\n  def __item_strval_optkeys(id)\n    if id == 'debug'\n      ['erasecolor']\n    elsif id.kind_of?(Array)\n      case id[0]\n      when 'column'\n        if id[1] == 'drag'\n          ['indicatorcolor']\n        else\n          super(id) << 'textcolor'\n        end\n      when 'element'\n        super(id) << 'fill' << 'outline' << 'format'\n      else\n        super(id)\n      end\n    else\n      super(id)\n    end\n  end\n  private :__item_strval_optkeys\n\n  def __item_listval_optkeys(id)\n    if id.kind_of?(Array)\n      case id[0]\n      when 'column'\n        ['itembackground']\n      when 'element'\n        ['relief']\n      when 'style'\n        ['union']\n      else\n        if id[0].kind_of?(Array) && id[0][1] == 'element'\n          ['relief']\n        else\n          []\n        end\n      end\n    else\n      []\n    end\n  end\n  private :__item_listval_optkeys\n\n  def __item_keyonly_optkeys(id)  # { def_key=>(undef_key|nil), ... }\n    {\n      'notreally'=>nil, \n      'increasing'=>'decreasing',\n      'decreasing'=>'increasing', \n      'ascii'=>nil,\n      'dictionary'=>nil, \n      'integer'=>nil, \n      'real'=>nil\n    }\n  end\n  private :__item_keyonly_optkeys\n\n  def column_cget(tagOrId, option)\n    itemcget(['column', tagOrId], option)\n  end\n  def column_cget_strict(tagOrId, option)\n    itemcget_strict(['column', tagOrId], option)\n  end\n  def column_configure(tagOrId, slot, value=None)\n    itemconfigure(['column', tagOrId], slot, value)\n  end\n  def column_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['column', tagOrId], slot)\n  end\n  def current_column_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['column', tagOrId], slot)\n  end\n\n  def column_dragcget(option)\n    itemcget(['column', 'drag'], option)\n  end\n  def column_dragcget_strict(option)\n    itemcget_strict(['column', 'drag'], option)\n  end\n  def column_dragconfigure(slot, value=None)\n    itemconfigure(['column', 'drag'], slot, value)\n  end\n  def column_dragconfiginfo(slot=nil)\n    itemconfiginfo(['column', 'drag'], slot)\n  end\n  def current_column_dragconfiginfo(slot=nil)\n    current_itemconfiginfo(['column', 'drag'], slot)\n  end\n\n  def debug_cget(option)\n    itemcget('debug', option)\n  end\n  def debug_cget_strict(option)\n    itemcget_strict('debug', option)\n  end\n  def debug_configure(slot, value=None)\n    itemconfigure('debug', slot, value)\n  end\n  def debug_configinfo(slot=nil)\n    itemconfiginfo('debug', slot)\n  end\n  def current_debug_configinfo(slot=nil)\n    current_itemconfiginfo('debug', slot)\n  end\n\n  def dragimage_cget(option)\n    itemcget('dragimage', option)\n  end\n  def dragimage_cget_strict(option)\n    itemcget_strict('dragimage', option)\n  end\n  def dragimage_configure(slot, value=None)\n    itemconfigure('dragimage', slot, value)\n  end\n  def dragimage_configinfo(slot=nil)\n    itemconfiginfo('dragimage', slot)\n  end\n  def current_dragimage_configinfo(slot=nil)\n    current_itemconfiginfo('dragimage', slot)\n  end\n\n  def element_cget(tagOrId, option)\n    itemcget(['element', tagOrId], option)\n  end\n  def element_cget_strict(tagOrId, option)\n    itemcget_strict(['element', tagOrId], option)\n  end\n  def element_configure(tagOrId, slot, value=None)\n    itemconfigure(['element', tagOrId], slot, value)\n  end\n  def element_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['element', tagOrId], slot)\n  end\n  def current_element_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['element', tagOrId], slot)\n  end\n\n  def item_cget(tagOrId, option)\n    itemcget(['item', tagOrId], option)\n  end\n  def item_cget_strict(tagOrId, option)\n    itemcget_strict(['item', tagOrId], option)\n  end\n  def item_configure(tagOrId, slot, value=None)\n    itemconfigure(['item', tagOrId], slot, value)\n  end\n  def item_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['item', tagOrId], slot)\n  end\n  def current_item_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['item', tagOrId], slot)\n  end\n\n  def item_element_cget(item, column, elem, option)\n    itemcget([['item', 'element'], [item, column, elem]], option)\n  end\n  def item_element_cget_strict(item, column, elem, option)\n    itemcget_strict([['item', 'element'], [item, column, elem]], option)\n  end\n  def item_element_configure(item, column, elem, slot, value=None)\n    itemconfigure([['item', 'element'], [item, column, elem]], slot, value)\n  end\n  def item_element_configinfo(item, column, elem, slot=nil)\n    itemconfiginfo([['item', 'element'], [item, column, elem]], slot)\n  end\n  def current_item_element_configinfo(item, column, elem, slot=nil)\n    current_itemconfiginfo([['item', 'element'], [item, column, elem]], slot)\n  end\n\n  def marquee_cget(option)\n    itemcget('marquee', option)\n  end\n  def marquee_cget_strict(option)\n    itemcget_strict('marquee', option)\n  end\n  def marquee_configure(slot, value=None)\n    itemconfigure('marquee', slot, value)\n  end\n  def marquee_configinfo(slot=nil)\n    itemconfiginfo('marquee', slot)\n  end\n  def current_marquee_configinfo(slot=nil)\n    current_itemconfiginfo('marquee', slot)\n  end\n\n  def notify_cget(win, pattern, option)\n    pattern = \"<#{pattern}>\"\n    # \"notify\" doesn't have cget subcommand.\n    current_itemconfiginfo(['notify', [win, pattern]])[option.to_s]\n  end\n  def notify_cget_strict(win, pattern, option)\n    pattern = \"<#{pattern}>\"\n    # \"notify\" doesn't have cget subcommand.\n    info = current_itemconfiginfo(['notify', [win, pattern]])\n    option = option.to_s\n    unless info.has_key?(option)\n      fail RuntimeError, \"unknown option \\\"#{option}\\\"\"\n    else\n      info[option]\n    end\n  end\n  def notify_configure(win, pattern, slot, value=None)\n    pattern = \"<#{pattern}>\"\n    itemconfigure(['notify', [win, pattern]], slot, value)\n  end\n  def notify_configinfo(win, pattern, slot=nil)\n    pattern = \"<#{pattern}>\"\n    itemconfiginfo(['notify', [win, pattern]], slot)\n  end\n  def current_notify_configinfo(tagOrId, slot=nil)\n    pattern = \"<#{pattern}>\"\n    current_itemconfiginfo(['notify', [win, pattern]], slot)\n  end\n\n  def style_cget(tagOrId, option)\n    itemcget(['style', tagOrId], option)\n  end\n  def style_cget_strict(tagOrId, option)\n    itemcget_strict(['style', tagOrId], option)\n  end\n  def style_configure(tagOrId, slot, value=None)\n    itemconfigure(['style', tagOrId], slot, value)\n  end\n  def style_configinfo(tagOrId, slot=nil)\n    itemconfiginfo(['style', tagOrId], slot)\n  end\n  def current_style_configinfo(tagOrId, slot=nil)\n    current_itemconfiginfo(['style', tagOrId], slot)\n  end\n\n  private :itemcget, :itemcget_strict\n  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo\nend\n\n##############################################\n\nclass Tk::TreeCtrl\n  include Tk::TreeCtrl::ConfigMethod\n  include Scrollable\n\n  TkCommandNames = ['treectrl'.freeze].freeze\n  WidgetClassName = 'TreeCtrl'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  #########################\n\n  def __destroy_hook__\n    Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.delete(@path)\n    }\n    Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.delete(@path)\n    }\n    Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.delete(@path)\n    }\n    Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.delete(@path)\n    }\n  end\n\n  #########################\n\n  def __strval_optkeys\n    super() + [\n      'buttoncolor', 'columnprefix', 'itemprefix', 'linecolor'\n    ]\n  end\n  private :__strval_optkeys\n\n  def __boolval_optkeys\n    [\n      'itemwidthequal', 'usetheme', \n      'showbuttons', 'showheader', 'showlines', 'showroot', \n      'showrootbutton', 'showrootlines',\n    ]\n  end\n  private :__boolval_optkeys\n\n  def __listval_optkeys\n    [ 'defaultstyle' ]\n  end\n  private :__listval_optkeys\n\n  #########################\n\n  def install_bind(cmd, *args)\n    install_bind_for_event_class(Tk::TreeCtrl::NotifyEvent, cmd, *args)\n  end\n\n  #########################\n\n  def create_self(keys)\n    if keys and keys != None\n      tk_call_without_enc(self.class::TkCommandNames[0], @path, \n                          *hash_kv(keys, true))\n    else\n      tk_call_without_enc(self.class::TkCommandNames[0], @path)\n    end\n  end\n  private :create_self\n\n  #########################\n\n  def activate(desc)\n    tk_send('activate', desc)\n    self\n  end\n\n  def canvasx(x)\n    number(tk_send('canvasx', x))\n  end\n\n  def canvasy(y)\n    number(tk_send('canvasy', y))\n  end\n\n  def collapse(*dsc)\n    tk_send_without_enc('collapse', *(dsc.map!{|d| _get_eval_string(d, true)}))\n    self\n  end\n\n  def collapse_recurse(*dsc)\n    tk_send_without_enc('collapse', '-recurse', \n                        *(dsc.map!{|d| _get_eval_string(d, true)}))\n    self\n  end\n\n  def column_bbox(idx)\n    list(tk_send('column', 'bbox', idx))\n  end\n\n  def column_compare(column1, op, column2)\n    bool(tk_send('column', 'compare', column1, op, column2))\n  end\n\n  def column_count\n    num_or_str(tk_send('column', 'count'))\n  end\n\n  def column_create(keys=nil)\n    if keys && keys.kind_of?(Hash)\n      num_or_str(tk_send('column', 'create', *hash_kv(keys)))\n    else\n      num_or_str(tk_send('column', 'create'))\n    end\n  end\n\n  def column_delete(idx)\n    Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[self.path]\n        Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[self.path].delete(idx)\n      end\n    }\n    tk_send('column', 'delete', idx)\n    self\n  end\n\n  def column_index(idx)\n    num_or_str(tk_send('column', 'index', idx))\n  end\n\n  def column_id(idx)\n    tk_send('column', 'id', idx)\n  end\n\n  def column_list(visible=false)\n    if visible\n      simplelist(tk_send('column', 'list', '-visible'))\n    else\n      simplelist(tk_send('column', 'list'))\n    end\n  end\n  def column_visible_list\n    column_list(true)\n  end\n\n  def column_move(idx, before)\n    tk_send('column', 'move', idx, before)\n    self\n  end\n\n  def column_needed_width(idx)\n    num_or_str(tk_send('column', 'neededwidth', idx))\n  end\n  alias column_neededwidth column_needed_width\n\n  def column_order(column, visible=false)\n    if visible\n      num_or_str(tk_send('column', 'order', column, '-visible'))\n    else\n      num_or_str(tk_send('column', 'order', column))\n    end\n  end\n  def column_visible_order(column)\n    column_order(column, true)\n  end\n\n  def column_width(idx)\n    num_or_str(tk_send('column', 'width', idx))\n  end\n\n  def compare(item1, op, item2)\n    bool(tk_send('compare', item1, op, item2))\n  end\n\n  def contentbox()\n    list(tk_send('contentbox'))\n  end\n\n  def depth(item=None)\n    num_or_str(tk_send_without_enc('depth', _get_eval_string(item, true)))\n  end\n\n  def dragimage_add(item, *args)\n    tk_send('dragimage', 'add', item, *args)\n    self\n  end\n\n  def dragimage_clear()\n    tk_send('dragimage', 'clear')\n    self\n  end\n\n  def dragimage_offset(*args) # x, y\n    if args.empty?\n      list(tk_send('dragimage', 'offset'))\n    else\n      tk_send('dragimage', 'offset', *args)\n      self\n    end\n  end\n\n  def dragimage_visible(*args) # mode\n    if args..empty?\n      bool(tk_send('dragimage', 'visible'))\n    else\n      tk_send('dragimage', 'visible', *args)\n      self\n    end\n  end\n  def dragimage_visible?\n    dragimage_visible()\n  end\n\n  def debug_dinfo\n    tk_send('debug', 'dinfo')\n    self\n  end\n\n  def debug_scroll\n    tk_send('debug', 'scroll')\n  end\n\n  def element_create(elem, type, keys=nil)\n    if keys && keys.kind_of?(Hash)\n      tk_send('element', 'create', elem, type, *hash_kv(keys))\n    else\n      tk_send('element', 'create', elem, type)\n    end\n  end\n\n  def element_delete(*elems)\n    Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[self.path]\n        elems.each{|elem|\n          Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[self.path].delete(elem)\n        }\n      end\n    }\n    tk_send('element', 'delete', *elems)\n    self\n  end\n\n  def element_names()\n    list(tk_send('element', 'names')).collect!{|elem|\n      Tk::TreeCtrl::Element.id2obj(self, elem)\n    }\n  end\n\n  def _conv_element_perstate_val(opt, val)\n    case opt\n    when 'background', 'foreground', 'fill', 'outline', 'format'\n      val\n    when 'draw', 'filled', 'showfocus', 'destroy'\n      bool(val)\n    else\n      tk_tcl2ruby(val)\n    end\n  end\n  private :_conv_element_perstate_val\n\n  def element_perstate(elem, opt, st_list)\n    tk_send('element', 'perstate', elem, \"-{opt}\", st_list)\n  end\n\n  def element_type(elem)\n    tk_send('element', 'type', elem)\n  end\n\n  def element_class(elem)\n    Tk::TreeCtrl::Element.type2class(element_type(elem))\n  end\n\n  def expand(*dsc)\n    tk_send('expand', *dsc)\n    self\n  end\n\n  def expand_recurse(*dsc)\n    tk_send('expand', '-recurse', *dsc)\n    self\n  end\n\n  def identify(x, y)\n    lst = list(tk_send('identify', x, y))\n\n    if lst[0] == 'item'\n      lst[1] = Tk::TreeCtrl::Item.id2obj(self, lst[1])\n      size = lst.size\n      i = 2\n      while i < size\n        case lst[i]\n        when 'line'\n          i += 1\n          lst[i] = Tk::TreeCtrl::Item.id2obj(self, lst[i])\n          i += 1\n\n        when 'button'\n          i += 1\n\n        when 'column'\n          i += 2\n\n        when 'elem'\n          i += 1\n          lst[i] = Tk::TreeCtrl::Element.id2obj(self, lst[i])\n          i += 1\n\n        else\n          i += 1\n        end\n      end\n    end\n\n    lst\n  end\n\n  def index(idx)\n    num_or_str(tk_send('index', idx))\n  end\n\n  def item_ancestors(item)\n    list(tk_send('item', 'ancestors', item)).collect!{|id|\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    }\n  end\n\n  def item_bbox(item, *args)\n    list(tk_send('item', 'bbox', item, *args))\n  end\n\n  def item_children(item)\n    list(tk_send('item', 'children', item)).collect!{|id|\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    }\n  end\n\n  def item_collapse(item)\n    tk_send_without_enc('item', 'collapse', _get_eval_string(item, true))\n    self\n  end\n\n  def item_collapse_recurse(item)\n    tk_send_without_enc('item', 'collapse', \n                        _get_eval_string(item, true), '-recurse')\n    self\n  end\n\n  def item_compare(item1, op, item2)\n    bool(tk_send('item', 'compare', item1, op, item2))\n  end\n\n  def item_complex(item, *args)\n    tk_send_without_enc('item', 'complex', \n                        _get_eval_string(item, true), \n                        *(args.map!{|arg| _get_eval_string(arg, true)}))\n    self\n  end\n\n  def item_count\n    num_or_str(tk_send('item', 'count'))\n  end\n\n  def item_create(keys={})\n    num_or_str(tk_send_without_enc('item', 'create', *hash_kv(keys, true)))\n  end\n\n  def _erase_children(item)\n    item_children(item).each{|i| _erase_children(i)}\n    # table is already locked\n    Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path].delete(item)\n  end\n  private :_erase_children\n\n  def item_delete(first, last=None)\n    Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path]\n        if first == 'all' || first == :all || last == 'all' || last == :all\n          Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[self.path].clear\n        elsif last == None\n          _erase_children(first)\n        else\n          self.range(first, last).each{|id|\n            _erase_children(id)\n          }\n        end\n      end\n    }\n    tk_send('item', 'delete', first, last)\n    self\n  end\n\n  def item_dump(item)\n    list(tk_send('item', 'dump', item))\n  end\n\n  def item_dump_hash(item)\n    Hash[*list(tk_send('item', 'dump', item))]\n  end\n\n  def item_element_actual(item, column, elem, key)\n    tk_send('item', 'element', 'actual', item, column, elem, \"-#{key}\")\n  end\n\n  def item_element_perstate(elem, opt, st_list)\n    tk_send('item', 'element', 'perstate', elem, \"-{opt}\", st_list)\n  end\n\n  def item_expand(item)\n    tk_send('item', 'expand', item)\n    self\n  end\n\n  def item_expand_recurse(item)\n    tk_send('item', 'expand', item, '-recurse')\n    self\n  end\n\n  def item_firstchild(parent, child=nil)\n    if child\n      tk_send_without_enc('item', 'firstchild', \n                          _get_eval_string(parent, true), \n                          _get_eval_string(child, true))\n      self\n    else\n      id = num_or_str(tk_send_without_enc('item', 'firstchild', \n                                          _get_eval_string(parent, true)))\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    end\n  end\n  alias item_first_child item_firstchild\n\n  def item_hasbutton(item, st=None)\n    if st == None\n      bool(tk_send_without_enc('item', 'hasbutton', \n                               _get_eval_string(item, true)))\n    else\n      tk_send_without_enc('item', 'hasbutton', \n                          _get_eval_string(item, true), \n                          _get_eval_string(st))\n      self\n    end\n  end\n  alias item_has_button item_hasbutton\n\n  def item_hasbutton?(item)\n    item_hasbutton(item)\n  end\n  alias item_has_button? item_hasbutton?\n\n  def item_id(item)\n    tk_send('item', 'id', item)\n  end\n\n  def item_image(item, column=nil, *args)\n    if args.empty?\n      if column\n        img = tk_send('item', 'image', item, column)\n        TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img\n      else\n        simplelist(tk_send('item', 'image', item)).collect!{|img|\n          TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img\n        }\n      end\n    else\n      tk_send('item', 'image', item, column, *args)\n      self\n    end\n  end\n  def get_item_image(item, column=nil)\n    item_image(item, column)\n  end\n  def set_item_image(item, col, img, *args)\n    item_image(item, col, img, *args)\n  end\n\n  def item_index(item)\n    list(tk_send('item', 'index', item))\n  end\n\n  def item_isancestor(item, des)\n    bool(tk_send('item', 'isancestor', item, des))\n  end\n  alias item_is_ancestor  item_isancestor\n  alias item_isancestor?  item_isancestor\n  alias item_is_ancestor? item_isancestor\n\n  def item_isopen(item)\n    bool(tk_send('item', 'isopen', item))\n  end\n  alias item_is_open    item_isopen\n  alias item_isopen?    item_isopen\n  alias item_is_open?   item_isopen\n  alias item_isopened?  item_isopen\n  alias item_is_opened? item_isopen\n\n  def item_lastchild(parent, child=nil)\n    if child\n      tk_send_without_enc('item', 'lastchild', \n                          _get_eval_string(parent, true),\n                          _get_eval_string(child, true))\n      self\n    else\n      id = num_or_str(tk_send_without_enc('item', 'lastchild', \n                                          _get_eval_string(parent, true)))\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    end\n  end\n  alias item_last_child item_lastchild\n\n  def item_nextsibling(sibling, nxt=nil)\n    if nxt\n      tk_send('item', 'nextsibling', sibling, nxt)\n      self\n    else\n      id = num_or_str(tk_send('item', 'nextsibling', sibling))\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    end\n  end\n  alias item_next_sibling item_nextsibling\n\n  def item_numchildren(item)\n    number(tk_send_without_enc('item', 'numchildren', \n                               _get_eval_string(item, true)))\n  end\n  alias item_num_children  item_numchildren\n  alias item_children_size item_numchildren\n\n  def item_order(item, visible=false)\n    if visible\n      ret = num_or_str(tk_send('item', 'order', item, '-visible'))\n    else\n      ret = num_or_str(tk_send('item', 'order', item))\n    end\n\n    (ret.kind_of?(Fixnum) && ret < 0)? nil: ret\n  end\n  def item_visible_order(item)\n    item_order(item, true)\n  end\n\n  def item_parent(item)\n    id = num_or_str(tk_send('item', 'parent', item))\n    Tk::TreeCtrl::Item.id2obj(self, id)\n  end\n\n  def item_prevsibling(sibling, prev=nil)\n    if prev\n      tk_send('item', 'prevsibling', sibling, prev)\n      self\n    else\n      id = num_or_str(tk_send('item', 'prevsibling', sibling))\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    end\n  end\n  alias item_prev_sibling item_prevsibling\n\n  def item_range(first, last)\n    simplelist(tk_send('item', 'range', first, last))\n  end\n\n  def item_remove(item)\n    tk_send('item', 'remove', item)\n    self\n  end\n\n  def item_rnc(item)\n    list(tk_send('item', 'rnc', item))\n  end\n\n  def _item_sort_core(real_sort, item, *opts)\n    # opts ::= sort_param [, sort_param, ... ]\n    # sort_param ::= {key=>val, ...}\n    #                [type, desc, {key=>val, ...}]\n    #                param\n    opts = opts.collect{|param|\n      if param.kind_of?(Hash)\n        param = _symbolkey2str(param)\n        if param.key?('column')\n          key = '-column'\n          desc = param.delete('column')\n        elsif param.key?('element')\n          key = '-element'\n          desc = param.delete('element')\n        else\n          key = nil\n        end\n\n        if param.empty?\n          param = None\n        else\n          param = hash_kv(__conv_item_keyonly_opts(item, param))\n        end\n\n        if key\n          [key, desc].concat(param)\n        else\n          param\n        end\n\n      elsif param.kind_of?(Array)\n        if param[2].kind_of?(Hash)\n          param[2] = hash_kv(__conv_item_keyonly_opts(item, param[2]))\n        end\n        param\n\n      elsif param.kind_of?(String) && param =~ /\\A[a-z]+\\Z/\n        '-' << param\n\n      elsif param.kind_of?(Symbol)\n        '-' << param.to_s\n\n      else\n        param\n      end\n    }.flatten\n\n    if real_sort\n      tk_send('item', 'sort', item, *opts)\n      self\n    else\n      list(tk_send('item', 'sort', item, '-notreally', *opts))\n    end\n  end\n  private :_item_sort_core\n\n  def item_sort(item, *opts)\n    _item_sort_core(true, item, *opts)\n  end\n  def item_sort_not_really(item, *opts)\n    _item_sort_core(false, item, *opts)\n  end\n\n  def item_span(item, column=nil, *args)\n    if args.empty?\n      if column\n        list(tk_send('item', 'span', item, column))\n      else\n        simplelist(tk_send('item', 'span', item)).collect!{|elem| list(elem)}\n      end\n    else\n      tk_send('item', 'span', item, column, *args)\n      self\n    end\n  end\n  def get_item_span(item, column=nil)\n    item_span(item, column)\n  end\n  def set_item_span(item, col, num, *args)\n    item_span(item, col, num, *args)\n  end\n\n  def item_state_forcolumn(item, column, *args)\n    tk_send('item', 'state', 'forcolumn', item, column, *args)\n  end\n  alias item_state_for_column item_state_forcolumn\n\n  def item_state_get(item, *args)\n    if args.empty?\n      list(tk_send('item', 'state', 'get', item *args))\n    else\n      bool(tk_send('item', 'state', 'get', item))\n    end\n  end\n\n  def item_state_set(item, *args)\n    tk_send('item', 'state', 'set', item, *args)\n  end\n\n  def item_style_elements(item, column)\n    list(tk_send('item', 'style', 'elements', item, column)).collect!{|id|\n      Tk::TreeCtrl::Style.id2obj(self, id)\n    }\n  end\n\n  def item_style_map(item, column, style, map)\n    tk_send('item', 'style', 'map', item, column, style, map)\n    self\n  end\n\n  def item_style_set(item, column=nil, *args)\n    if args.empty?\n      if column\n        id = tk_send_without_enc('item', 'style', 'set', \n                                 _get_eval_string(item, true), \n                                 _get_eval_string(column, true))\n        Tk::TreeCtrl::Style.id2obj(self, id)\n      else\n        list(tk_send_without_enc('item', 'style', 'set', \n                                 _get_eval_string(item, true))).collect!{|id|\n          Tk::TreeCtrl::Style.id2obj(self, id)\n        }\n      end\n    else\n      tk_send_without_enc('item', 'style', 'set', \n                          _get_eval_string(item, true), \n                          _get_eval_string(column, true), \n                          *(args.flatten.map!{|arg|\n                              _get_eval_string(arg, true)\n                            }))\n      self\n    end\n  end\n\n  def item_text(item, column, txt=nil, *args)\n    if args.empty?\n      if txt\n        tk_send('item', 'text', item, column, txt)\n        self\n      else\n        tk_send('item', 'text', item, column)\n      end\n    else\n      tk_send('item', 'text', item, column, txt, *args)\n      self\n    end\n  end\n\n  def item_toggle(item)\n    tk_send('item', 'toggle', item)\n    self\n  end\n\n  def item_toggle_recurse(item)\n    tk_send('item', 'toggle', item, '-recurse')\n    self\n  end\n\n  def item_visible(item, st=None)\n    if st == None\n      bool(tk_send('item', 'visible', item))\n    else\n      tk_send('item', 'visible', item, st)\n      self\n    end\n  end\n  def item_visible?(item)\n    item_visible(item)\n  end\n\n  def marquee_anchor(*args)\n    if args.empty?\n      list(tk_send('marquee', 'anchor'))\n    else\n      tk_send('marquee', 'anchor', *args)\n      self\n    end\n  end\n\n  def marquee_coords(*args)\n    if args.empty?\n      list(tk_send('marquee', 'coords'))\n    else\n      tk_send('marquee', 'coords', *args)\n      self\n    end\n  end\n\n  def marquee_corner(*args)\n    if args.empty?\n      tk_send('marquee', 'corner')\n    else\n      tk_send('marquee', 'corner', *args)\n      self\n    end\n  end\n\n  def marquee_identify()\n    list(tk_send('marquee', 'identify')).collect!{|id|\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    }\n  end\n\n  def marquee_visible(st=None)\n    if st == None\n      bool(tk_send('marquee', 'visible'))\n    else\n      tk_send('marquee', 'visible', st)\n      self\n    end\n  end\n  def marquee_visible?()\n    marquee_visible()\n  end\n\n  #def notify_bind(obj, event, cmd=Proc.new, *args)\n  #  _bind([@path, 'notify', 'bind', obj], event, cmd, *args)\n  #  self\n  #end\n  def notify_bind(obj, event, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind([@path, 'notify', 'bind', obj], event, cmd, *args)\n    self\n  end\n\n  #def notify_bind_append(obj, event, cmd=Proc.new, *args)\n  #  _bind_append([@path, 'notify', 'bind', obj], event, cmd, *args)\n  #  self\n  #end\n  def notify_bind_append(obj, event, *args)\n    # if args[0].kind_of?(Proc) || args[0].kind_of?(Method)\n    if TkComm._callback_entry?(args[0]) || !block_given?\n      cmd = args.shift\n    else\n      cmd = Proc.new\n    end\n    _bind_append([@path, 'notify', 'bind', obj], event, cmd, *args)\n    self\n  end\n\n  def notify_bind_remove(obj, event)\n    _bind_remove([@path, 'notify', 'bind', obj], event)\n    self\n  end\n\n  def notify_bindinfo(obj, event=nil)\n    _bindinfo([@path, 'notify', 'bind', obj], event)\n  end\n\n  def notify_detailnames(event)\n    list(tk_send('notify', 'detailnames', event))\n  end\n\n  def notify_eventnames()\n    list(tk_send('notify', 'eventnames'))\n  end\n\n  def notify_generate(pattern, char_map=None, percents_cmd=None)\n    pattern = \"<#{pattern}>\"\n    tk_send('notify', 'generate', pattern, char_map, percents_cmd)\n    self\n  end\n\n  def notify_install(pattern, percents_cmd=nil, &b)\n    pattern = \"<#{pattern}>\"\n    percents_cmd = Proc.new(&b) if !percents_cmd && b\n    if percents_cmd\n      procedure(tk_send('notify', 'install', pattern, percents_cmd))\n    else\n      procedure(tk_send('notify', 'install', pattern))\n    end\n  end\n\n  def notify_install_detail(event, detail, percents_cmd=nil, &b)\n    percents_cmd = Proc.new(&b) if !percents_cmd && b\n    if percents_cmd\n      tk_send('notify', 'install', 'detail', event, detail, percents_cmd)\n    else\n      tk_send('notify', 'install', 'detail', event, detail)\n    end\n  end\n\n  def notify_install_event(event, percents_cmd=nil, &b)\n    percents_cmd = Proc.new(&b) if !percents_cmd && b\n    if percents_cmd\n      tk_send('notify', 'install', 'event', event, percents_cmd)\n    else\n      tk_send('notify', 'install', 'event', event)\n    end\n  end\n\n  def notify_linkage(pattern, detail=None)\n    if detail != None\n      tk_send('notify', 'linkage', pattern, detail)\n    else\n      begin\n        if pattern.to_s.index(?-)\n          # TreeCtrl 1.1 format?\n          begin\n            tk_send('notify', 'linkage', \"<#{pattern}>\")\n          rescue\n            # TreeCtrl 1.0?\n            tk_send('notify', 'linkage', pattern)\n          end\n        else\n          # TreeCtrl 1.0 format?\n          begin\n            tk_send('notify', 'linkage', pattern)\n          rescue\n            # TreeCtrl 1.1?\n            tk_send('notify', 'linkage', \"<#{pattern}>\")\n          end\n        end\n      end\n    end\n  end\n\n  def notify_unbind(pattern=nil)\n    if pattern\n      tk_send('notify', 'unbind', \"<#{pattern}>\")\n    else\n      tk_send('notify', 'unbind')\n    end\n    self\n  end\n\n  def notify_uninstall(pattern)\n    pattern = \"<#{pattern}>\"\n    tk_send('notify', 'uninstall', pattern)\n    self\n  end\n\n  def notify_uninstall_detail(event, detail)\n    tk_send('notify', 'uninstall', 'detail', event, detail)\n    self\n  end\n\n  def notify_uninstall_event(event)\n    tk_send('notify', 'uninstall', 'event', event)\n    self\n  end\n\n  def numcolumns()\n    num_or_str(tk_send('numcolumns'))\n  end\n  alias num_columns  numcolumns\n  alias columns_size numcolumns\n\n  def numitems()\n    num_or_str(tk_send('numitems'))\n  end\n  alias num_items  numitems\n  alias items_size numitems\n\n  def orphans()\n    list(tk_send('orphans')).collect!{|id|\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    }\n  end\n\n  def range(first, last)\n    list(tk_send('range', first, last)).collect!{|id|\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    }\n  end\n\n  def state_define(name)\n    tk_send('state', 'define', name)\n    self\n  end\n\n  def state_linkage(name)\n    tk_send('state', 'linkage', name)\n  end\n\n  def state_names()\n    list(tk_send('state', 'names'))\n  end\n\n  def state_undefine(*names)\n    tk_send('state', 'undefine', *names)\n    self\n  end\n\n  def see(item)\n    tk_send('see', item)\n    self\n  end\n\n  def selection_add(first, last=None)\n    tk_send('selection', 'add', first, last)\n    self\n  end\n\n  def selection_anchor(item=None)\n    id = num_or_str(tk_send('selection', 'anchor', item))\n    Tk::TreeCtrl::Item.id2obj(self, id)\n  end\n\n  def selection_clear(*args) # first, last\n    tk_send('selection', 'clear', *args)\n    self\n  end\n\n  def selection_count()\n    number(tk_send('selection', 'count'))\n  end\n\n  def selection_get()\n    list(tk_send('selection', 'get')).collect!{|id|\n      Tk::TreeCtrl::Item.id2obj(self, id)\n    }\n  end\n\n  def selection_includes(item)\n    bool(tk_send('selection', 'includes', item))\n  end\n\n  def selection_modify(sel, desel)\n    tk_send('selection', 'modify', sel, desel)\n    self\n  end\n\n  def style_create(style, keys=None)\n    if keys && keys != None\n      tk_send('style', 'create', style, *hash_kv(keys))\n    else\n      tk_send('style', 'create', style)\n    end\n  end\n\n  def style_delete(*args)\n    Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[self.path]\n        args.each{|sty|\n          Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[self.path].delete(sty)\n        }\n      end\n    }\n    tk_send('style', 'delete', *args)\n    self\n  end\n\n  def style_elements(style, *elems)\n    if elems.empty?\n      list(tk_send('style', 'elements', style)).collect!{|id|\n        Tk::TreeCtrl::Element.id2obj(self, id)\n      }\n    else\n      tk_send('style', 'elements', style, elems.flatten)\n      self\n    end\n  end\n\n  def _conv_style_layout_val(sty, val)\n    case sty.to_s\n    when 'padx', 'pady', 'ipadx', 'ipady'\n      lst = list(val)\n      (lst.size == 1)? lst[0]: lst\n    when 'detach', 'indent'\n      bool(val)\n    when 'union'\n      simplelist(val).collect!{|elem|\n        Tk::TreeCtrl::Element.id2obj(self, elem)\n      }\n    else\n      val\n    end\n  end\n  private :_conv_style_layout_val\n\n  def style_layout(style, elem, keys=None)\n    if keys && keys != None\n      if keys.kind_of?(Hash)\n        tk_send('style', 'layout', style, elem, *hash_kv(keys))\n        self\n      else\n        _conv_style_layout_val(keys, \n                               tk_send('style', 'layout', \n                                       style, elem, \"-#{keys}\"))\n      end\n    else\n      ret = Hash.new\n      Hash[*simplelist(tk_send('style', 'layout', style, elem))].each{|k, v|\n        k = k[1..-1]\n        ret[k] = _conv_style_layout_val(k, v)\n      }\n      ret\n    end\n  end\n  def get_style_layout(style, elem, opt=None)\n    style_layout(style, elem, opt)\n  end\n  def set_style_layout(style, elem, slot, value=None)\n    if slot.kind_of?(Hash)\n      style_layout(style, elem, slot)\n    else\n      style_layout(style, elem, {slot=>value})\n    end\n  end\n\n  def style_names()\n    list(tk_send('style', 'names')).collect!{|id|\n      Tk::TreeCtrl::Style.id2obj(self, id)\n    }\n  end\n\n  def toggle(*items)\n    tk_send('toggle', *items)\n    self\n  end\n\n  def toggle_recurse()\n    tk_send('toggle', '-recurse', *items)\n    self\n  end\nend\n\n#####################\n\nclass Tk::TreeCtrl::Column < TkObject\n  TreeCtrlColumnID_TBL = TkCore::INTERP.create_table\n\n  (TreeCtrlColumnID = ['treectrl_column'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.clear\n    }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath]\n        Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath][id]? \\\n                   Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[tpath][id] : id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(parent, keys={})\n    @tree = parent\n    @tpath = parent.path\n\n    keys = _symbolkey2str(keys)\n\n    Tk::TreeCtrl::Column::TreeCtrlColumnID.mutex.synchronize{\n      @path = @id = \n        keys.delete('tag') ||\n        Tk::TreeCtrl::Column::TreeCtrlColumnID.join(TkCore::INTERP._ip_id_)\n      Tk::TreeCtrl::Column::TreeCtrlColumnID[1].succ!\n    }\n\n    keys['tag'] = @id\n\n    Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath] ||= {} \n      Tk::TreeCtrl::Column::TreeCtrlColumnID_TBL[@tpath][@id] = self\n    }\n\n    @tree.column_create(keys)\n  end\n\n  def id\n    @id\n  end\n\n  def to_s\n    @id.to_s.dup\n  end\n\n  def cget(opt)\n    @tree.column_cget(@tree.column_index(@id), opt)\n  end\n  def cget_strict(opt)\n    @tree.column_cget_strict(@tree.column_index(@id), opt)\n  end\n\n  def configure(*args)\n    @tree.column_configure(@tree.column_index(@id), *args)\n  end\n\n  def configinfo(*args)\n    @tree.column_configinfo(@tree.column_index(@id), *args)\n  end\n\n  def current_configinfo(*args)\n    @tree.current_column_configinfo(@tree.column_index(@id), *args)\n  end\n\n  def delete\n    @tree.column_delete(@tree.column_index(@id))\n    self\n  end\n\n  def index\n    @tree.column_index(@id)\n  end\n\n  def move(before)\n    @tree.column_move(@tree.column_index(@id), before)\n    self\n  end\n\n  def needed_width\n    @tree.column_needed_width(@tree.column_index(@id))\n  end\n  alias neededwidth needed_width\n\n  def current_width\n    @tree.column_width(@tree.column_index(@id))\n  end\nend\n\n#####################\n\nclass Tk::TreeCtrl::Element < TkObject\n  TreeCtrlElementID_TBL = TkCore::INTERP.create_table\n\n  (TreeCtrlElementID = ['treectrl_element'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n  TreeCtrlElemTypeToClass = {}\n\n  TkCore::INTERP.init_ip_env{\n    Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.clear\n    }\n  }\n\n  def self.type2class(type)\n    TreeCtrlElemTypeToClass[type] || type\n  end\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath]\n        Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath][id]? \\\n                 Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[tpath][id] : id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(parent, type, keys=nil)\n    @tree = parent\n    @tpath = parent.path\n    @type = type.to_s\n    Tk::TreeCtrl::Element::TreeCtrlElementID.mutex.synchronize{\n      @path = @id = \n        Tk::TreeCtrl::Element::TreeCtrlElementID.join(TkCore::INTERP._ip_id_)\n      Tk::TreeCtrl::Element::TreeCtrlElementID[1].succ!\n    }\n\n    Tk::TreeCtrl::Element::TreeCtrlElementID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath] ||= {} \n      Tk::TreeCtrl::Element::TreeCtrlElementID_TBL[@tpath][@id] = self\n    }\n\n    @tree.element_create(@id, @type, keys)\n  end\n\n  def id\n    @id\n  end\n\n  def to_s\n    @id.dup\n  end\n\n  def cget(opt)\n    @tree.element_cget(@id, opt)\n  end\n  def cget_strict(opt)\n    @tree.element_cget_strict(@id, opt)\n  end\n\n  def configure(*args)\n    @tree.element_configure(@id, *args)\n  end\n\n  def configinfo(*args)\n    @tree.element_configinfo(@id, *args)\n  end\n\n  def current_configinfo(*args)\n    @tree.current_element_configinfo(@id, *args)\n  end\n\n  def delete\n    @tree.element_delete(@id)\n    self\n  end\n\n  def element_type\n    @tree.element_type(@id)\n  end\n\n  def element_class\n    @tree.element_class(@id)\n  end\nend\n\nclass Tk::TreeCtrl::BitmapElement < Tk::TreeCtrl::Element\n  TreeCtrlElemTypeToClass['bitmap'] = self\n\n  def initialize(parent, keys=nil)\n    super(parent, 'bitmap', keys)\n  end\nend\n\nclass Tk::TreeCtrl::BorderElement < Tk::TreeCtrl::Element\n  TreeCtrlElemTypeToClass['border'] = self\n\n  def initialize(parent, keys=nil)\n    super(parent, 'border', keys)\n  end\nend\n\nclass Tk::TreeCtrl::ImageElement < Tk::TreeCtrl::Element\n  TreeCtrlElemTypeToClass['image'] = self\n\n  def initialize(parent, keys=nil)\n    super(parent, 'image', keys)\n  end\nend\n\nclass Tk::TreeCtrl::RectangleElement < Tk::TreeCtrl::Element\n  TreeCtrlElemTypeToClass['rect'] = self\n\n  def initialize(parent, keys=nil)\n    super(parent, 'rect', keys)\n  end\nend\n\n#####################\n\nclass Tk::TreeCtrl::Item < TkObject\n  TreeCtrlItemID_TBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.clear\n    }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath]\n        Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath][id]? \\\n                        Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[tpath][id] : id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(parent, keys={})\n    @tree = parent\n    @tpath = parent.path\n    @path = @id = @tree.item_create(keys)\n\n    Tk::TreeCtrl::Item::TreeCtrlItemID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath] ||= {} \n      Tk::TreeCtrl::Item::TreeCtrlItemID_TBL[@tpath][@id] = self\n    }\n  end\n\n  def id\n    @id\n  end\n\n  def to_s\n    @id.to_s.dup\n  end\n\n  def ancestors\n    @tree.item_ancestors(@id)\n  end\n\n  def bbox(*args)\n    @tree.item_bbox(@id, *args)\n  end\n\n  def children\n    @tree.item_children(@id)\n  end\n\n  def collapse\n    @tree.item_collapse(@id)\n    self\n  end\n\n  def collapse_recurse\n    @tree.item_collapse_recurse(@id)\n    self\n  end\n\n  def complex(*args)\n    @tree.item_complex(@id, *args)\n    self\n  end\n\n  def cget(opt)\n    @tree.item_cget(@id, opt)\n  end\n  def cget_strict(opt)\n    @tree.item_cget_strict(@id, opt)\n  end\n\n  def configure(*args)\n    @tree.item_configure(@id, *args)\n  end\n\n  def configinfo(*args)\n    @tree.item_configinfo(@id, *args)\n  end\n\n  def current_configinfo(*args)\n    @tree.current_item_configinfo(@id, *args)\n  end\n\n  def delete\n    @tree.item_delete(@id)\n    self\n  end\n\n  def element_dump\n    @tree.item_dump(@id)\n  end\n\n  def element_dump_hash\n    @tree.item_dump_hash(@id)\n  end\n\n  def element_actual(column, elem, key)\n    @tree.item_element_actual(@id, column, elem, key)\n  end\n\n  def element_cget(opt)\n    @tree.item_element_cget(@id, opt)\n  end\n  def element_cget_strict(opt)\n    @tree.item_element_cget_strict(@id, opt)\n  end\n\n  def element_configure(*args)\n    @tree.item_element_configure(@id, *args)\n  end\n\n  def element_configinfo(*args)\n    @tree.item_element_configinfo(@id, *args)\n  end\n\n  def current_element_configinfo(*args)\n    @tree.current_item_element_configinfo(@id, *args)\n  end\n\n  def expand\n    @tree.item_expand(@id)\n    self\n  end\n\n  def expand_recurse\n    @tree.item_expand_recurse(@id)\n    self\n  end\n\n  def firstchild(child=nil)\n    if child\n      @tree.item_firstchild(@id, child)\n      self\n    else\n      @tree.item_firstchild(@id)\n    end\n  end\n  alias first_child firstchild\n\n  def hasbutton(st=None)\n    if st == None\n      @tree.item_hasbutton(@id)\n    else\n      @tree.item_hasbutton(@id, st)\n      self\n    end\n  end\n  alias has_button hasbutton\n\n  def hasbutton?\n    @tree.item_hasbutton(@id)\n  end\n  alias has_button? hasbutton?\n\n  def index\n    @tree.item_index(@id)\n  end\n\n  def isancestor(des)\n    @tree.item_isancestor(@id, des)\n  end\n  alias is_ancestor  isancestor\n  alias isancestor?  isancestor\n  alias is_ancestor? isancestor\n  alias ancestor?    isancestor\n\n  def isopen\n    @tree.item_isopen(@id)\n  end\n  alias is_open    isopen\n  alias isopen?    isopen\n  alias is_open?   isopen\n  alias isopened?  isopen\n  alias is_opened? isopen\n  alias open?      isopen\n\n  def lastchild(child=nil)\n    if child\n      @tree.item_lastchild(@id, child)\n      self\n    else\n      @tree.item_lastchild(@id)\n    end\n  end\n  alias last_child lastchild\n\n  def nextsibling(nxt=nil)\n    if nxt\n      @tree.item_nextsibling(@id, nxt)\n      self\n    else\n      @tree.item_nextsibling(@id)\n    end\n  end\n  alias next_sibling nextsibling\n\n  def numchildren\n    @tree.item_numchildren(@id)\n  end\n  alias num_children  numchildren\n  alias children_size numchildren\n\n  def parent_index\n    @tree.item_parent(@id)\n  end\n\n  def prevsibling(nxt=nil)\n    if nxt\n      @tree.item_prevsibling(@id, nxt)\n      self\n    else\n      @tree.item_prevsibling(@id)\n    end\n  end\n  alias prev_sibling prevsibling\n\n  def remove\n    @tree.item_remove(@id)\n  end\n\n  def rnc\n    @tree.item_rnc(@id)\n  end\n\n  def sort(*opts)\n    @tree.item_sort(@id, *opts)\n  end\n  def sort_not_really(*opts)\n    @tree.item_sort_not_really(@id, *opts)\n    self\n  end\n\n  def state_forcolumn(column, *args)\n    @tree.item_state_forcolumn(@id, column, *args)\n    self\n  end\n  alias state_for_column state_forcolumn\n\n  def state_get(*args)\n    @tree.item_state_get(@id, *args)\n  end\n\n  def state_set(*args)\n    @tree.item_state_set(@id, *args)\n    self\n  end\n\n  def style_elements(column)\n    @tree.item_style_elements(@id, column)\n  end\n\n  def style_map(column, style, map)\n    @tree.item_style_map(@id, column, style, map)\n    self\n  end\n\n  def style_set(column=nil, *args)\n    if args.empty?\n      @tree.item_style_set(@id, column)\n    else\n      @tree.item_style_set(@id, column, *args)\n      self\n    end\n  end\n\n  def item_text(column, txt=nil, *args)\n    if args.empty?\n      if txt\n        @tree.item_text(@id, column, txt)\n        self\n      else\n        @tree.item_text(@id, column)\n      end\n    else\n      @tree.item_text(@id, column, txt, *args)\n      self\n    end\n  end\n\n  def toggle\n    @tree.item_toggle(@id)\n    self\n  end\n\n  def toggle_recurse\n    @tree.item_toggle_recurse(@id)\n    self\n  end\n\n  def visible(st=None)\n    if st == None\n      @tree.item_visible(@id)\n    else\n      @tree.item_visible(@id, st)\n      self\n    end\n  end\nend\n\n#####################\n\nclass Tk::TreeCtrl::Style < TkObject\n  TreeCtrlStyleID_TBL = TkCore::INTERP.create_table\n\n  (TreeCtrlStyleID = ['treectrl_style'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.clear\n    }\n  }\n\n  def self.id2obj(tree, id)\n    tpath = tree.path\n    Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{\n      if Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath]\n        Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath][id]? \\\n                     Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[tpath][id] : id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(parent, keys=nil)\n    @tree = parent\n    @tpath = parent.path\n\n    Tk::TreeCtrl::Style::TreeCtrlStyleID.mutex.synchronize{\n      @path = @id = \n        Tk::TreeCtrl::Style::TreeCtrlStyleID.join(TkCore::INTERP._ip_id_)\n      Tk::TreeCtrl::Style::TreeCtrlStyleID[1].succ!\n    }\n\n    Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL.mutex.synchronize{\n      Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath] ||= {} \n      Tk::TreeCtrl::Style::TreeCtrlStyleID_TBL[@tpath][@id] = self\n    }\n\n    @tree.style_create(@id, keys)\n  end\n\n  def id\n    @id\n  end\n\n  def to_s\n    @id.dup\n  end\n\n  def cget(opt)\n    @tree.style_cget(@id, opt)\n  end\n  def cget_strict(opt)\n    @tree.style_cget_strict(@id, opt)\n  end\n\n  def configure(*args)\n    @tree.style_configure(@id, *args)\n  end\n\n  def configinfo(*args)\n    @tree.style_configinfo(@id, *args)\n  end\n\n  def current_configinfo(*args)\n    @tree.current_style_configinfo(@id, *args)\n  end\n\n  def delete\n    @tree.style_delete(@id)\n    self\n  end\n\n  def elements(*elems)\n    if elems.empty?\n      @tree.style_elements(@id)\n    else\n      @tree.style_elements(@id, *elems)\n      self\n    end\n  end\n\n  def layout(elem, keys=None)\n    if keys && keys != None && keys.kind_of?(Hash)\n      @tree.style_layout(@id, elem, keys)\n      self\n    else\n      @tree.style_layout(@id, elem, keys)\n    end\n  end\nend\n\nmodule Tk::TreeCtrl::BindCallback\n  include Tk\n  extend Tk\nend\n\nclass << Tk::TreeCtrl::BindCallback\n  def percentsCmd(*args)\n    tk_call('::TreeCtrl::PercentsCmd', *args)\n  end\n  def cursorCheck(w, x, y)\n    tk_call('::TreeCtrl::CursorCheck', w, x, y)\n  end\n  def cursorCheckAux(w)\n    tk_call('::TreeCtrl::CursorCheckAux', w)\n  end\n  def cursorCancel(w)\n    tk_call('::TreeCtrl::CursorCancel', w)\n  end\n  def buttonPress1(w, x, y)\n    tk_call('::TreeCtrl::ButtonPress1', w, x, y)\n  end\n  def doubleButton1(w, x, y)\n    tk_call('::TreeCtrl::DoubleButton1', w, x, y)\n  end\n  def motion1(w, x, y)\n    tk_call('::TreeCtrl::Motion1', w, x, y)\n  end\n  def leave1(w, x, y)\n    tk_call('::TreeCtrl::Leave1', w, x, y)\n  end\n  def release1(w, x, y)\n    tk_call('::TreeCtrl::Release1', w, x, y)\n  end\n  def beginSelect(w, el)\n    tk_call('::TreeCtrl::BeginSelect', w, el)\n  end\n  def motion(w, le)\n    tk_call('::TreeCtrl::Motion', w, el)\n  end\n  def beginExtend(w, el)\n    tk_call('::TreeCtrl::BeginExtend', w, el)\n  end\n  def beginToggle(w, el)\n    tk_call('::TreeCtrl::BeginToggle', w, el)\n  end\n  def cancelRepeat\n    tk_call('::TreeCtrl::CancelRepeat')\n  end\n  def autoScanCheck(w, x, y)\n    tk_call('::TreeCtrl::AutoScanCheck', w, x, y)\n  end\n  def autoScanCheckAux(w)\n    tk_call('::TreeCtrl::AutoScanCheckAux', w)\n  end\n  def autoScanCancel(w)\n    tk_call('::TreeCtrl::AutoScanCancel', w)\n  end\n  def up_down(w, n)\n    tk_call('::TreeCtrl::UpDown', w, n)\n  end\n  def left_right(w, n)\n    tk_call('::TreeCtrl::LeftRight', w, n)\n  end\n  def setActiveItem(w, idx)\n    tk_call('::TreeCtrl::SetActiveItem', w, idx)\n  end\n  def extendUpDown(w, amount)\n    tk_call('::TreeCtrl::ExtendUpDown', w, amount)\n  end\n  def dataExtend(w, el)\n    tk_call('::TreeCtrl::DataExtend', w, el)\n  end\n  def cancel(w)\n    tk_call('::TreeCtrl::Cancel', w)\n  end\n  def selectAll(w)\n    tk_call('::TreeCtrl::selectAll', w)\n  end\n  def marqueeBegin(w, x, y)\n    tk_call('::TreeCtrl::MarqueeBegin', w, x, y)\n  end\n  def marqueeUpdate(w, x, y)\n    tk_call('::TreeCtrl::MarqueeUpdate', w, x, y)\n  end\n  def marqueeEnd(w, x, y)\n    tk_call('::TreeCtrl::MarqueeEnd', w, x, y)\n  end\n  def scanMark(w, x, y)\n    tk_call('::TreeCtrl::ScanMark', w, x, y)\n  end\n  def scanDrag(w, x, y)\n    tk_call('::TreeCtrl::ScanDrag', w, x, y)\n  end\n\n  # filelist-bindings\n  def fileList_button1(w, x, y)\n    tk_call('::TreeCtrl::FileListButton1', w, x, y)\n  end\n  def fileList_motion1(w, x, y)\n    tk_call('::TreeCtrl::FileListMotion1', w, x, y)\n  end\n  def fileList_motion(w, x, y)\n    tk_call('::TreeCtrl::FileListMotion', w, x, y)\n  end\n  def fileList_leave1(w, x, y)\n    tk_call('::TreeCtrl::FileListLeave1', w, x, y)\n  end\n  def fileList_release1(w, x, y)\n    tk_call('::TreeCtrl::FileListRelease1', w, x, y)\n  end\n  def fileList_edit(w, i, s, e)\n    tk_call('::TreeCtrl::FileListEdit', w, i, s, e)\n  end\n  def fileList_editCancel(w)\n    tk_call('::TreeCtrl::FileListEditCancel', w)\n  end\n  def fileList_autoScanCheck(w, x, y)\n    tk_call('::TreeCtrl::FileListAutoScanCheck', w, x, y)\n  end\n  def fileList_autoScanCheckAux(w)\n    tk_call('::TreeCtrl::FileListAutoScanCheckAux', w)\n  end\n\n  def entryOpen(w, item, col, elem)\n    tk_call('::TreeCtrl::EntryOpen', w, item, col, elem)\n  end\n  def entryExpanderOpen(w, item, col, elem)\n    tk_call('::TreeCtrl::EntryExpanderOpen', w, item, col, elem)\n  end\n  def entryClose(w, accept)\n    tk_call('::TreeCtrl::EntryClose', w, accept)\n  end\n  def entryExpanderKeypress(w)\n    tk_call('::TreeCtrl::EntryExpanderKeypress', w)\n  end\n  def textOpen(w, item, col, elem, width=0, height=0)\n    tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width, height)\n  end\n  def textExpanderOpen(w, item, col, elem, width)\n    tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width)\n  end\n  def textClose(w, accept)\n    tk_call('::TreeCtrl::TextClose', w, accept)\n  end\n  def textExpanderKeypress(w)\n    tk_call('::TreeCtrl::TextExpanderKeypress', w)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/treectrl.rb",
    "content": "#\n#  TkTreeCtrl support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/treectrl/setup.rb'\n\n# load library\nrequire 'tkextlib/treectrl/tktreectrl'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/trofs/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/trofs/trofs.rb",
    "content": "#\n#  tkextlib/trofs/trofs.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/trofs/setup.rb'\n\n# TkPackage.require('trofs', '0.4')\nTkPackage.require('trofs')\n\nmodule Tk\n  module Trofs\n    extend TkCore\n\n    PACKAGE_NAME = 'trofs'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('trofs')\n      rescue\n        ''\n      end\n    end\n\n    ##############################################\n\n    def self.create_archive(dir, archive)\n      tk_call('::trofs::archive', dir, archive)\n      archive\n    end\n\n    def self.mount(archive, mountpoint=None)\n      # returns the normalized path to mountpoint\n      tk_call('::trofs::mount', archive, mountpoint)\n    end\n\n    def self.umount(mountpoint)\n      tk_call('::trofs::umount', mountpoint)\n      mountpoint\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/trofs.rb",
    "content": "#\n#  trofs support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/trofs/setup.rb'\n\n# load library\nrequire 'tkextlib/trofs/trofs.rb'\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/version.rb",
    "content": "#\n# release date of tkextlib\n#\nmodule Tk\n  Tkextlib_RELEASE_DATE = '2008-05-23'.freeze\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu/bargraph.rb",
    "content": "#\n#  ::vu::bargraph widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# create module/class\nmodule Tk\n  module Vu\n    class Bargraph < TkWindow\n    end\n  end\nend\n\n\n# call setup script  --  <libdir>/tkextlib/vu.rb\nrequire 'tkextlib/vu.rb'\n\nclass Tk::Vu::Bargraph < TkWindow\n  TkCommandNames = ['::vu::bargraph'.freeze].freeze\n  WidgetClassName = 'Bargraph'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ###############################\n\n  def __boolval_optkeys\n    ['showminmax', 'showvalue']\n  end\n  private :__boolval_optkeys\n\n  def __strval_optkeys\n    super() + [\n      'title', \n      'barbackground', 'barcolor', 'barcolour', \n      'tickcolor', 'tickcolour', \n      'textcolor', 'textcolour', \n    ]\n  end\n  private :__strval_optkeys\n\n  def __listval_optkeys\n    ['alabels', 'blabels']\n  end\n  private :__listval_optkeys\n\n  def __font_optkeys\n    ['alabfont', 'blabfont']\n  end\n  private :__font_optkeys\n\n  ###############################\n\n  def set(val = None)\n    tk_call_without_enc(@path, 'set', val)\n    self\n  end\n\n  def get()\n    num_or_str(tk_call_without_enc(@path, 'get'))\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu/charts.rb",
    "content": "#\n#  charts -- Create and manipulate canvas Add-On Items\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\nrequire 'tk/canvas'\n\n# call setup script  --  <libdir>/tkextlib/vu.rb\nrequire 'tkextlib/vu.rb'\n\nmodule Tk\n  module Vu\n    module ChartsConfig\n      include TkItemConfigOptkeys\n      def __item_boolval_optkeys(id)\n        super(id) << 'lefttrunc' << 'autocolor'\n      end\n      private :__item_boolval_optkeys\n\n      def __item_strval_optkeys(id)\n        super(id) << 'bar' << 'color' << 'outline' << \n          'fill' << 'scaleline' << 'stripline'\n      end\n      private :__item_strval_optkeys\n\n      def __item_listval_optkeys(id)\n        super(id) << 'values' << 'tags'\n      end\n      private :__item_listval_optkeys\n    end\n\n    class TkcSticker < TkcItem\n      include ChartsConfig\n\n      CItemTypeName = 'sticker'.freeze\n      CItemTypeToClass[CItemTypeName] = self\n    end\n\n    class TkcStripchart < TkcItem\n      include ChartsConfig\n\n      CItemTypeName = 'stripchart'.freeze\n      CItemTypeToClass[CItemTypeName] = self\n    end\n\n    class TkcBarchart < TkcItem\n      include ChartsConfig\n\n      CItemTypeName = 'barchart'.freeze\n      CItemTypeToClass[CItemTypeName] = self\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu/dial.rb",
    "content": "#\n#  ::vu::dial widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# create module/class\nmodule Tk\n  module Vu\n    class Dial < TkWindow\n    end\n  end\nend\n\n# call setup script  --  <libdir>/tkextlib/vu.rb\nrequire 'tkextlib/vu.rb'\n\n# define module/class\nclass Tk::Vu::Dial < TkWindow\n  TkCommandNames = ['::vu::dial'.freeze].freeze\n  WidgetClassName = 'Dial'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  ###############################\n\n  def __methodcall_optkeys  # { key=>method, ... }\n    {'coords'=>'coords'}\n  end\n  private :__methodcall_optkeys\n\n  ###############################\n\n  def coords(val = nil)\n    if val\n      tk_split_list(tk_send_without_enc('coords'))\n    else\n      tk_send_without_enc('coords', val)\n      self\n    end\n  end\n\n  def constrain(val = None)\n    num_or_str(tk_call(@path, 'constrain', val))\n  end\n\n  def get(*args)\n    num_or_str(tk_call(@path, 'get', *args))\n  end\n\n  def identify(x, y)\n    tk_call(@path, 'identify', x, y)\n  end\n\n  def get_label(val=nil)\n    if val\n      tk_call(@path, 'label', val)\n    else\n      ret = []\n      lst = simplelist(tk_call(@path, 'label'))\n      while lst.size > 0\n        ret << ([num_or_str(lst.shift)] << lst.shift)\n      end\n    end\n  end\n\n  def set_label(val, str, *args)\n    tk_call(@path, 'label', val, str, *args)\n    self\n  end\n\n  def set_label_constrain(val, str, *args)\n    tk_call(@path, 'label', '-constrain', val, str, *args)\n    self\n  end\n\n  def get_tag(val=nil)\n    if val\n      tk_call(@path, 'tag', val)\n    else\n      ret = []\n      lst = simplelist(tk_call(@path, 'tag'))\n      while lst.size > 0\n        ret << ([num_or_str(lst.shift)] << lst.shift)\n      end\n    end\n  end\n\n  def set_tag(val, str, *args)\n    tk_call(@path, 'tag', val, str, *args)\n    self\n  end\n\n  def set_tag_constrain(val, str, *args)\n    tk_call(@path, 'tag', '-constrain', val, str, *args)\n    self\n  end\n\n  def set(val = None)\n    tk_call_without_enc(@path, 'set', val)\n    self\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu/pie.rb",
    "content": "#\n#  ::vu::pie widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# create module/class\nmodule Tk\n  module Vu\n    module PieSliceConfigMethod\n    end\n    class Pie < TkWindow\n    end\n    class PieSlice < TkObject\n    end\n    class NamedPieSlice < PieSlice\n    end\n  end\nend\n\n# call setup script  --  <libdir>/tkextlib/vu.rb\nrequire 'tkextlib/vu.rb'\n\nmodule Tk::Vu::PieSliceConfigMethod\n  include TkItemConfigMethod\n\n  def __item_pathname(tagOrId)\n    if tagOrId.kind_of?(Tk::Vu::PieSlice)\n      self.path + ';' + tagOrId.id.to_s\n    else\n      self.path + ';' + tagOrId.to_s\n    end\n  end\n  private :__item_pathname\nend\n\nclass Tk::Vu::Pie < TkWindow\n  TkCommandNames = ['::vu::pie'.freeze].freeze\n  WidgetClassName = 'Pie'.freeze\n  WidgetClassNames[WidgetClassName] = self\n\n  def __destroy_hook__\n    Tk::Vu::PieSlice::SliceID_TBL.delete(@path)\n  end\n\n  ###############################\n\n  include Tk::Vu::PieSliceConfigMethod\n\n  def tagid(tag)\n    if tag.kind_of?(Tk::Vu::PieSlice)\n      tag.id\n    else\n      # tag\n      _get_eval_string(tag)\n    end\n  end\n\n  ###############################\n\n  def delete(*glob_pats)\n    tk_call(@path, 'delete', *glob_pats)\n    self\n  end\n\n  def explode(slice, *args)\n    tk_call(@path, 'explode', slice, *args)\n    self\n  end\n\n  def explode_value(slice)\n    num_or_str(tk_call(@path, 'explode', slice))\n  end\n\n  def lower(slice, below=None)\n    tk_call(@path, 'lower', slice, below)\n    self\n  end\n\n  def names(*glob_pats)\n    simplelist(tk_call(@path, 'names', *glob_pats))\n  end\n  alias slices names\n\n  def order(*args)\n    tk_call(@path, 'order', *args)\n    self\n  end\n\n  def raise(slice, above=None)\n    tk_call(@path, 'raise', slice, above)\n    self\n  end\n\n  def swap(slice1, slice2)\n    tk_call(@path, 'swap', slice1, slice2)\n    self\n  end\n\n  def set(slice, *args)\n    num_or_str(tk_call(@path, 'set', slice, *args))\n  end\n  alias set_value  set\n  alias set_values set\n  alias create     set\n\n  def slice_value(slice)\n    num_or_str(tk_call(@path, 'set', slice))\n  end\n\n  def value(val = None)\n    num_or_str(tk_call_without_enc(@path, 'value'))\n  end\n  alias sum_value value\nend\n\nclass Tk::Vu::PieSlice\n  SliceID_TBL = TkCore::INTERP.create_table\n\n  (Pie_Slice_ID = ['vu:pie'.freeze, '00000'.taint]).instance_eval{\n    @mutex = Mutex.new\n    def mutex; @mutex; end\n    freeze\n  }\n\n  TkCore::INTERP.init_ip_env{\n    SliceID_TBL.mutex.synchronize{ SliceID_TBL.clear }\n  }\n\n  def self.id2obj(pie, id)\n    pie_path = pie.path\n    SliceID_TBL.mutex.synchronize{\n      if SliceID_TBL[pie_path]\n        SliceID_TBL[pie_path][id]? SliceID_TBL[pie_path][id]: id\n      else\n        id\n      end\n    }\n  end\n\n  def initialize(parent, *args)\n    unless parent.kind_of?(Tk::Vu::Pie)\n      fail ArgumentError, \"expect a Tk::Vu::Pie instance for 1st argument\"\n    end\n    @parent = @pie = parent\n    @ppath = parent.path\n    Pie_Slice_ID.mutex.synchronize{\n      @path = @id = Pie_Slice_ID.join(TkCore::INTERP._ip_id_)\n      Pie_Slice_ID[1].succ!\n    }\n    SliceID_TBL.mutex.synchronize{\n      SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath]\n      SliceID_TBL[@ppath][@id] = self\n    }\n\n    if args[-1].kind_of?(Hash)\n      keys = args.unshift\n    end\n    @pie.set(@id, *args)\n    configure(keys)\n  end\n\n  def id\n    @id\n  end\n\n  def [](key)\n    cget key\n  end\n\n  def []=(key,val)\n    configure key, val\n    val\n  end\n\n  def cget(slot)\n    @pie.itemcget(@id, slot)\n  end\n\n  def cget_strict(slot)\n    @pie.itemcget_strict(@id, slot)\n  end\n\n  def configure(*args)\n    @pie.itemconfigure(@id, *args)\n    self\n  end\n\n  def configinfo(*args)\n    @pie.itemconfiginfo(@id, *args)\n  end\n\n  def current_configinfo(*args)\n    @pie.current_itemconfiginfo(@id, *args)\n  end\n\n  def delete\n    @pie.delete(@id)\n  end\n\n  def explode(value)\n    @pie.explode(@id, value)\n    self\n  end\n\n  def explode_value\n    @pie.explode_value(@id)\n  end\n\n  def lower(other=None)\n    @pie.lower(@id, other)\n    self\n  end\n\n  def raise(other=None)\n    @pie.raise(@id, other)\n    self\n  end\n\n  def set(value)\n    @pie.set(@id, value)\n    self\n  end\n  alias set_value set\n\n  def value\n    @pie.set(@id)\n  end\nend\n\nclass Tk::Vu::NamedPieSlice\n  def self.new(parent, name, *args)\n    obj = nil\n    SliceID_TBL.mutex.synchronize{\n      if SliceID_TBL[parent.path] && SliceID_TBL[parent.path][name]\n        obj = SliceID_TBL[parent.path][name]\n      else\n        #super(parent, name, *args)\n        unless parent.kind_of?(Tk::Vu::Pie)\n          fail ArgumentError, \"expect a Tk::Vu::Pie instance for 1st argument\"\n        end\n        obj = self.allocate\n        obj.instance_eval{\n          @parent = @pie = parent\n          @ppath = parent.path\n          @path = @id = name.to_s\n          SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath]\n          SliceID_TBL[@ppath][@id] = self\n        }\n      end\n    }\n    obj.instance_eval{\n      if args[-1].kind_of?(Hash)\n        keys = args.unshift\n      end\n      @pie.set(@id, *args)\n      configure(keys)\n    }\n\n    obj\n  end\n\n  def initialize(parent, name, *args)\n    # dummy:: not called by 'new' method\n    unless parent.kind_of?(Tk::Vu::Pie)\n      fail ArgumentError, \"expect a Tk::Vu::Pie instance for 1st argument\"\n    end\n    @parent = @pie = parent\n    @ppath = parent.path\n    @path = @id = name.to_s\n    SliceID_TBL.mutex.synchronize{\n      SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath]\n      SliceID_TBL[@ppath][@id] = self\n    }\n\n    if args[-1].kind_of?(Hash)\n      keys = args.unshift\n    end\n    @pie.set(@id, *args)\n    configure(keys)\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu/spinbox.rb",
    "content": "#\n#  ::vu::spinbox widget\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#  a standard spinbox (<= 8.3)\n#  This is the same as the 8.4 core spinbox widget.\n#\nrequire 'tk'\n\nif (Tk::TK_MAJOR_VERSION < 8 || \n    (Tk::TK_MAJOR_VERSION == 8 && Tk::TK_MINOR_VERSION < 4))\n  # call setup script  --  <libdir>/tkextlib/vu.rb\n  require 'tkextlib/vu.rb'\n\n  Tk.tk_call('namespace', 'import', '::vu::spinbox')\nend\n\nmodule Tk\n  module Vu\n    Spinbox = Tk::Spinbox\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/vu.rb",
    "content": "#\n#  The vu widget set support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/vu/setup.rb'\n\n# load package\n# TkPackage.require('vu', '2.1')\nTkPackage.require('vu')\n\n# autoload\nmodule Tk\n  module Vu\n    TkComm::TkExtlibAutoloadModule.unshift(self)\n\n    PACKAGE_NAME = 'vu'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('vu')\n      rescue\n        ''\n      end\n    end\n\n    ##########################################\n\n    autoload :Dial,          'tkextlib/vu/dial'\n\n    autoload :Pie,           'tkextlib/vu/pie'\n    autoload :PieSlice,      'tkextlib/vu/pie'\n    autoload :NamedPieSlice, 'tkextlib/vu/pie'\n\n    autoload :Spinbox,       'tkextlib/vu/spinbox'\n\n    autoload :Bargraph,      'tkextlib/vu/bargraph'\n  end\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/winico/setup.rb",
    "content": "#\n#  setup.rb   --   setup script before calling TkPackage.require()\n#\n#    If you need some setup operations (for example, add a library path\n#    to the library search path) before using Tcl/Tk library packages \n#    wrapped by Ruby scripts in this directory, please write the setup \n#    operations in this file.\n#\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/winico/winico.rb",
    "content": "#\n#  tkextlib/winico/winico.rb\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/winico/setup.rb'\n\n# TkPackage.require('winico', '0.5')\n# TkPackage.require('winico', '0.6')\nTkPackage.require('winico')\n\nmodule Tk\n  class Winico < TkObject\n    PACKAGE_NAME = 'winico'.freeze\n    def self.package_name\n      PACKAGE_NAME\n    end\n\n    def self.package_version\n      begin\n        TkPackage.require('winico')\n      rescue\n        ''\n      end\n    end\n  end\nend\n\nclass Tk::Winico\n  WinicoID_TBL = TkCore::INTERP.create_table\n\n  TkCore::INTERP.init_ip_env{\n    WinicoID_TBL.mutex.synchronize{ WinicoID_TBL.clear }\n  }\n\n  def self.id2obj(id)\n    WinicoID_TBL.mutex.synchronize{\n      (WinicoID_TBL.key?(id))? WinicoID_TBL[id] : id\n    }\n  end\n\n  def self.info\n    simplelist(Tk.tk_call('winico', 'info')).collect{|id| \n      Tk::Winico.id2obj(id)\n    }\n  end\n\n  def self.icon_info(id)\n    simplelist(Tk.tk_call('winico', 'info', id)).collect{|inf|\n      h = Hash[*list(inf)]\n      h.keys.each{|k| h[k[1..-1]] = h.delete(k)}\n    }\n  end\n\n  #################################\n\n  def self.new_from_file(file_name)\n    self.new(file_name)\n  end\n\n  def self.new_from_resource(resource_name, file_name = nil)\n    self.new(file_name, resource_name)\n  end\n\n  def initialize(file_name, resource_name=nil, winico_id=nil)\n    if resource_name\n      # from resource\n      if file_name\n        @id = Tk.tk_call('winico', 'load', resource_name, file_name)\n      else\n        @id = Tk.tk_call('winico', 'load', resource_name)\n      end\n    elsif file_name\n      # from .ico file\n      @id = Tk.tk_call('winico', 'createfrom', file_name)\n    elsif winico_id\n      @id = winico_id\n    else\n      fail ArgumentError, \n           \"must be given proper information from where loading icons\"\n    end\n    @path = @id\n    WinicoID_TBL.mutex.synchronize{\n      WinicoID_TBL[@id] = self\n    }\n  end\n\n  def id\n    @id\n  end\n\n  def set_window(win_id, *opts) # opts := ?'big'|'small'?, ?pos?\n    # NOTE:: the window, which is denoted by win_id, MUST BE MAPPED. \n    #        If not, then this may fail or crash.\n    tk_call('winico', 'setwindow', win_id, @id, *opts)\n  end\n\n  def delete\n    tk_call('winico', 'delete', @id)\n    WinicoID_TBL.mutex.synchronize{\n      WinicoID_TBL.delete(@id)\n    }\n    self\n  end\n  alias destroy delete\n\n  def info\n    Tk::Winico.icon_info(@id)\n  end\n\n  #################################\n\n  class Winico_callback < TkValidateCommand\n    class ValidateArgs < TkUtil::CallbackSubst\n      KEY_TBL = [\n        [ ?m, ?s, :message ], \n        [ ?i, ?x, :icon ], \n        [ ?x, ?n, :x ], \n        [ ?y, ?n, :y ], \n        [ ?X, ?n, :last_x ], \n        [ ?Y, ?n, :last_y ], \n        [ ?t, ?n, :tickcount ], \n        [ ?w, ?n, :icon_idnum ], \n        [ ?l, ?n, :msg_idnum ], \n        nil\n      ]\n\n      PROC_TBL = [\n        [ ?n, TkComm.method(:number) ], \n        [ ?s, TkComm.method(:string) ], \n        [ ?x, proc{|id| \n            Tk::Winico::WinicoID_TBL.mutex.synchronize{\n              if Tk::Winico::WinicoID_TBL.key?(id)\n                obj = Tk::Winico::WinicoID_TBL[id]\n              else\n                # Tk::Winico.new(nil, nil, id)\n                obj = Tk::Winico.allocate\n                obj.instance_eval{ @path = @id = id }\n                Tk::Winico::WinicoID_TBL[id] = obj\n              end\n              obj\n            }\n          } ], \n        nil\n      ]\n\n=begin\n      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )\n      KEY_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)\n        end\n        inf\n      }\n\n      PROC_TBL.map!{|inf|\n        if inf.kind_of?(Array)\n          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)\n        end\n        inf\n      }\n=end\n\n      _setup_subst_table(KEY_TBL, PROC_TBL);\n\n      def self.ret_val(val)\n        val\n      end\n    end\n\n    def self._config_keys\n      ['callback']\n    end\n  end\n\n  #################################\n\n  def add_to_taskbar(keys = {})\n    keys = _symbolkey2str(keys)\n    Winico_callback._config_keys.each{|k|\n      if keys[k].kind_of?(Array)\n        cmd, *args = keys[k]\n        #keys[k] = Winico_callback.new(cmd, args.join(' '))\n        keys[k] = Winico_callback.new(cmd, *args)\n       # elsif keys[k].kind_of?(Proc)\n      elsif TkComm._callback_entry?(keys[k])\n        keys[k] = Winico_callback.new(keys[k])\n      end\n    }\n    tk_call('winico', 'taskbar', 'add', @id, *(hash_kv(keys)))\n    self\n  end\n  alias taskbar_add add_to_taskbar\n\n  def modify_taskbar(keys = {})\n    keys = _symbolkey2str(keys)\n    Winico_callback._config_keys.each{|k|\n      if keys[k].kind_of?(Array)\n        cmd, *args = keys[k]\n        #keys[k] = Winico_callback.new(cmd, args.join(' '))\n        keys[k] = Winico_callback.new(cmd, *args)\n      # elsif keys[k].kind_of?(Proc)\n      elsif TkComm._callback_entry?(keys[k])\n        keys[k] = Winico_callback.new(keys[k])\n      end\n    }\n    tk_call('winico', 'taskbar', 'modify', @id, *(hash_kv(keys)))\n    self\n  end\n  alias taskbar_modify modify_taskbar\n\n  def delete_from_taskbar\n    tk_call('winico', 'taskbar', 'delete', @id)\n    self\n  end\n  alias taskbar_delete delete_from_taskbar\nend\n"
  },
  {
    "path": "ext/tk/lib/tkextlib/winico.rb",
    "content": "#\n#  winico -- Windows Icon extension support\n#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\n# call setup script for general 'tkextlib' libraries\nrequire 'tkextlib/setup.rb'\n\n# call setup script\nrequire 'tkextlib/tktable/setup.rb'\n\n# load library\nrequire 'tkextlib/winico/winico'\n"
  },
  {
    "path": "ext/tk/lib/tkfont.rb",
    "content": "#\n#   tkfont.rb - load tk/font.rb\n#\nrequire 'tk/font'\n"
  },
  {
    "path": "ext/tk/lib/tkmacpkg.rb",
    "content": "#\n#   tkmacpkg.rb - load tk/macpkg.rb\n#\nrequire 'tk/macpkg'\n"
  },
  {
    "path": "ext/tk/lib/tkmenubar.rb",
    "content": "#\n#   tkmenubar.rb - load tk/menubar.rb\n#\nrequire 'tk/menubar'\n"
  },
  {
    "path": "ext/tk/lib/tkmngfocus.rb",
    "content": "#\n#   tkmngfocus.rb - load tk/mngfocus.rb\n#\nrequire 'tk/mngfocus'\n"
  },
  {
    "path": "ext/tk/lib/tkpalette.rb",
    "content": "#\n#   tkpalette.rb - load tk/palette.rb\n#\nrequire 'tk/palette'\n"
  },
  {
    "path": "ext/tk/lib/tkscrollbox.rb",
    "content": "#\n#   tkscrollbox.rb - load tk/scrollbox.rb\n#\nrequire 'tk/scrollbox'\n"
  },
  {
    "path": "ext/tk/lib/tktext.rb",
    "content": "#\n#   tktext.rb - load tk/text.rb\n#\nrequire 'tk/text'\n"
  },
  {
    "path": "ext/tk/lib/tkvirtevent.rb",
    "content": "#\n#   tkvirtevent.rb - load tk/virtevent.rb\n#\nrequire 'tk/virtevent'\n"
  },
  {
    "path": "ext/tk/lib/tkwinpkg.rb",
    "content": "#\n#   tkwinpkg.rb - load tk/winpkg.rb\n#\nrequire 'tk/winpkg'\n"
  },
  {
    "path": "ext/tk/old-README.tcltklib.eucj",
    "content": "(tof)\n                                    2003/06/19  Hidetoshi NAGAI\n\nܥɥȤˤϸŤ tcltk 饤֥ꡤtcltklib 饤֥\nޤޤƤޤεƤϸŤΤȤʤäƤޤ\n\nޤߤ Ruby/Tk 濴Ǥ tk.rb  wish ƤӽФϤ\ntcltklib 饤֥ wrap ưΤȤʤäƤޤ\nᡤŤҤǽҤ٤Ƥ褦ʥץ̿ˤ륪\nإåɤ¸ߤޤ\n\nߤ tcltklib 饤֥Ǥ⡤Tcl/Tk  C 饤֥󥯤\nľܤưȤǡХإåɤ򲡤Ĥ Tcl/Tk 󥿡ץ꥿\nΤۤǽʳĥ饤֥ޤˤȤƱǤ\nϤۤܡtk.rb ʲΥ饤֥ŪƯ뤿ΤΡ\nȸʤƤꡤŪǥƥʥ󥹤Ƥޤ\n\ntk.rb ιⵡǽȼäơΥ饤֥Ǥ tcltk 饤֥\ntcltk.rbˤϤ¸߰յ򸺤ƤꡤߤǤϥƥʥ󥹤ϹԤ\nƤޤ\n\nʤŤǤϥХǥ󥰤ˤ륹ץȤɲäϤǤʤ\nȤȤʤäƤޤߤ tk.rb ǤϤǽǤ뤳Ȥ­\nޤ\n\nʲ饤֥θŤʸǤ\n==============================================================\n\ttcltk 饤֥\n\ttcltklib 饤֥\n\t\tSep. 19, 1997\tY. Shigehiro\n\nʲ, tcl/tkפȤɽ, tclsh  wish ¸Ƥ, ̤Ǥ\nȤ tcl/tk ؤޤ. tcltk 饤֥, tcltklib 饤֥\nפȤɽ, ܥѥå˴ޤޤ ruby ѤΥ饤֥ؤޤ.\n\n[եˤĤ]\n\nREADME.euc : Υե(, ħ, 󥹥ȡˡ).\nMANUAL.euc : ޥ˥奢.\n\nlib/, ext/ : 饤֥μ.\n\nsample/ : ޥ˥奢Υץץ.\nsample/sample0.rb : tcltklib 饤֥Υƥ.\nsample/sample1.rb : tcltk 饤֥Υƥ.\n    tcl/tk (wish) ǤǤʤȤ̤񤤤Ƥߤޤ.\nsample/sample2.rb : tcltk 饤֥Υץ.\n    maeda shugo (shugo@po.aianet.ne.jp) ˤ\n    (`rb.tk' ǽ񤫤Ƥ) ruby Υץץ\n\thttp://www.aianet.or.jp/~shugo/ruby/othello.rb.gz\n     tcltk 饤֥Ȥ褦, ŪѹƤߤޤ.\n\ndemo/ : 100 ܤ 100 ǥץ.\n    ǽ˶롼פλ֤¬ꤷ, ³Ƽºݤ֤¬ꤷޤ.\n    tcl/tk ()ΤȤ backing store Ȥ鷺Χ 10000 (?)\n    Τ, ()Ϥ, ޥ󤬤ʤŤʤޤ.\ndemo/lines0.tcl : wish ѤΥץ.\ndemo/lines1.rb : `tk.rb' ѤΥץ.\ndemo/lines2.rb : tcltk 饤֥ѤΥץ.\n\n[]\n\nѥ/¹Ԥˤ, tcl/tk  C 饤֥꤬ɬפǤ.\n\nΥ饤֥,\n\n\truby-1.0-970701, ruby-1.0-970911, ruby-1.0-970919\n\tFreeBSD 2.2.2-RELEASE\n\tӤΥѥå jp-tcl-7.6.tgz, jp-tk-4.2.tgz\n\nǺ/ưǧޤ. ¾δĶǤư뤫ɤ狼ޤ.\n\nTclTkLib.mainloop ¹ Control-C ʤΤؤʤΤ, ruby \nΥ򻲹ͤ, #include \"sig.h\"  trap_immediate Ƥ\n, ruby  README.EXT ˤ񤤤ƤʤΤ, ʤȤ򤷤ɤΤ\nɤ狼ޤ.\n\n-d ץǥǥХåɽ뤿, ruby Υ򻲹ͤ,\ndebug Ȥѿ򻲾ȤƤޤ, ruby  README.EXT ˤ񤤤\nʤΤ, ʤȤ򤷤ɤΤɤ狼ޤ.\n\nextconf.rb Ͻ񤭤ޤ, (ʰ̣)ɤΤɤʬ\nޤ.\n\n[ħ]\n\nruby  tcl/tk 饤֥ѤǤޤ.\n\ntcl/tk 󥿥ץ꥿ΥץȤ, Ū tcltk 饤֥Ѥ ruby \nץȤѴǤޤ.\n\n(`tk.rb' Ȥΰ㤤)\n\n1. tcl/tk 󥿥ץ꥿ΥץȤ, ɤΤ褦, tcltk 饤֥Ѥ \n   ruby ץȤѴ뤫Ǥ, ޥ˥奢ब̵\n    `tk.rb' Ȥϰۤʤ\n\n\ttcl/tk Υޥ˥奢䥪饤ɥȤѤ\n\n   Ψɤץߥ󥰤ԤȤǤޤ.\n   ˡ狼ʤ, ޥɤͿѥ᡼狼ʤ...\n     - Canvas.new { ... } , ʤƥ졼֥å񤱤??\n     - Canvas  bbox ϿͤΥꥹȤ֤Τ, xview ʸ֤??\n   , , 饤֥ΥɤɬפϤޤ.\n\n2. ġεǽ(ץ)̽ˤꥵݡȤƤ, Τ᥵\n   ݡȤƤʤǽϻȤȤǤʤ(ϻȤʤȤʤ\n   Ǥ) `tk.rb' Ȥϰۤʤ, tcl/tk 󥿥ץ꥿ǲǽʤȤ\n\n\tۤȤ\n\n   ruby ¹ԤǤޤ. , ruby ¹ԤǤʤȤǧ\n   ƤΤ,\n\n\tbind ޥɤǥץȤɲä빽ʸ\n\tbind tag sequence +script\n                            ^\n\n   ΤߤǤ.\n     - `. configure -width' 򤷤褦Ȥ, `Tk.root.height()' Ƚ\n      Τ, `undefined method `height'' ܤƤޤä. tk.rb \n      ɤǤߤ, . ǤʤΤ...\n   ȤȤϤޤ.\n\n3. wish ץưץ̿ wish Ѥ `tk.rb' Ȥ\n   ۤʤ, tcl/tk  C 饤֥󥯤\n\n\t® (ȤäƤ, פä®ʤǤ)\n\n   Ԥޤ.\n\n4. `tk.rb' ۤ, ʥ󥿡եƤʤ, tcl/tk \n   󥿥ץ꥿\n\n\t鲿ޤǼʬǵ\n\n   ʤФʤޤ(, tcl/tk 饤֥λ̤,\n   tcl/tk 󥿥ץ꥿ʣ뤳ȤǤޤ).\n   󥿡ե(餯) ruby λۤ˱äΤǤϤޤ. \n   ޤ, ץȤεҤ\n\n\t\n\n   Ǥ. ץȤ, 츫, ɤߤŤ餤ΤȤʤޤ. , 񤯿ͤˤȤ\n   Ƥ, ۤѤ路ΤǤϤʤȻפޤ.\n\n[󥹥ȡˡ]\n\n0. ruby Υե(ruby-1.0-ʤ󤿤.tgz)ŸƤޤ.\n\n1. ruby-1.0-ʤ󤿤/ext  ext/tcltklib 򥳥ԡޤ.\n\tcp -r ext/tcltklib ???/ruby-1.0-ʤ󤿤/ext/\n\n2. ruby Υ󥹥ȡˡ˽ make 򤷤ޤ.\n\n3. ruby Υ饤֥־ lib/* 򥳥ԡޤ.\n\tcp lib/* /usr/local/lib/ruby/\n\n(eof)\n"
  },
  {
    "path": "ext/tk/sample/24hr_clock.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\n\nclass Clock\n  def initialize(clock24 = true)\n    @clock = (clock24)? 24: 12\n\n    @size = 200\n    @cdot_size = 5\n\n    @cdot_color        = 'black'\n    @hour_hand_color   = 'black'\n    @minute_hand_color = 'gray25'\n    @second_hand_color = 'gray50'\n\n    @mark_font     = 'Helvetica -14'\n    @mark_width    = 3\n    @mark_color    = 'black'\n    @submark_color = 'gray50'\n\n    @c = TkCanvas.new(:width=>2*@size, :height=>2*@size, \n                     :scrollregion=>[-@size, -@size, @size, @size]\n                     ).pack(:fill=>:both, :expand=>true)\n\n    @tag = TkcTag.new(@c)\n    @hand_tag = TkcTag.new(@c)\n\n    @circle_coords = [[-0.9*@size, -0.9*@size], [0.9*@size, 0.9*@size]]\n    @oval = TkcOval.new(@c, @circle_coords, :fill=>'white', :tags=>[@tag])\n\n    f = TkFrame.new.pack\n    TkLabel.new(f, :text=>'CURRENT:').pack(:side=>:left)\n    @now = TkLabel.new(f, :text=>'00:00:00').pack(:side=>:left, :padx=>2)\n    TkLabel.new(f, :text=>'  ').pack(:side=>:left)\n    TkLabel.new(f, :text=>'  ').pack(:side=>:right)\n    @l = TkLabel.new(f, :text=>'00:00').pack(:side=>:right, :padx=>2)\n    TkLabel.new(f, :text=>'MOUSE-POINTER:').pack(:side=>:right)\n\n    cmd = proc{|x, y|\n      @l.text = '%02d:%02d' % coords_to_time(@c.canvasx(x), @c.canvasy(y))\n    }\n    @c.bind('Motion', cmd, '%x %y')\n    @tag.bind('Motion', cmd, '%x %y')\n\n    _create_hands\n    _create_marks\n\n    timer_proc = proc{\n      t = Time.now\n      @now.text = '%02d:%02d:%02d' % [t.hour, t.min, t.sec]\n      set_hands(t.hour, t.min, t.sec)\n    }\n\n    timer_proc.call\n    @timer = TkRTTimer.start(100, -1, timer_proc)\n  end\n\n  def _create_marks\n    @mark_tag = TkcTag.new(@c)\n\n    TkcLine.new(@c, 0, -0.90*@size, 0, -0.85*@size, \n                :tags=>[@tag, @mark_tag], \n                :width=>@mark_width, :fill=>@mark_color)\n    TkcLine.new(@c, 0.90*@size, 0, 0.85*@size, 0, \n                :tags=>[@tag, @mark_tag], \n                :width=>@mark_width, :fill=>@mark_color)\n    TkcLine.new(@c, 0, 0.90*@size, 0, 0.85*@size, \n                :tags=>[@tag, @mark_tag], \n                :width=>@mark_width, :fill=>@mark_color)\n    TkcLine.new(@c, -0.90*@size, 0, -0.85*@size, 0, \n                :tags=>[@tag, @mark_tag], \n                :width=>@mark_width, :fill=>@mark_color)\n\n    TkcText.new(@c, [0, -0.92*@size], :text=>0, \n                :anchor=>'s', :fill=>@mark_color)\n    TkcText.new(@c, [0.92*@size, 0], :text=>@clock.div(4), \n                :anchor=>'w', :fill=>@mark_color)\n    TkcText.new(@c, [0, 0.92*@size], :text=>@clock.div(2), \n                :anchor=>'n', :fill=>@mark_color)\n    TkcText.new(@c, [-0.92*@size, 0], :text=>@clock.div(4)*3, \n                :anchor=>'e', :fill=>@mark_color)\n\n    [30.0, 60.0].each{|angle|\n      rad = Math::PI * angle / 180.0\n      x_base = @size*Math::sin(rad)\n      y_base = @size*Math::cos(rad)\n\n      x1 = 0.90*x_base\n      y1 = 0.90*y_base\n\n      x2 = 0.85*x_base\n      y2 = 0.85*y_base\n\n      TkcLine.new(@c, x1, y1, x2, y2, \n                  :tags=>[@tag, @mark_tag], \n                  :width=>@mark_width, :fill=>@mark_color)\n      TkcLine.new(@c, x1, -y1, x2, -y2, \n                  :tags=>[@tag, @mark_tag], \n                  :width=>@mark_width, :fill=>@mark_color)\n      TkcLine.new(@c, -x1, y1, -x2, y2, \n                  :tags=>[@tag, @mark_tag], \n                  :width=>@mark_width, :fill=>@mark_color)\n      TkcLine.new(@c, -x1, -y1, -x2, -y2, \n                  :tags=>[@tag, @mark_tag], \n                  :width=>@mark_width, :fill=>@mark_color)\n\n      x3 = 0.92*x_base\n      y3 = 0.92*y_base\n\n      if @clock == 24\n        dh = angle.to_i/15\n      else # @clock == 12\n        dh = angle.to_i/30\n      end\n\n      TkcText.new(@c, x3, -y3, :text=>dh, \n                  :anchor=>'sw', :fill=>@mark_color)\n      TkcText.new(@c, x3, y3, :text=>@clock.div(2)-dh, \n                  :anchor=>'nw', :fill=>@mark_color)\n      TkcText.new(@c, -x3, y3, :text=>@clock.div(2)+dh, \n                  :anchor=>'ne', :fill=>@mark_color)\n      TkcText.new(@c, -x3, -y3, :text=>@clock-dh, \n                  :anchor=>'se', :fill=>@mark_color)\n    }\n\n    if @clock == 24\n      [15.0, 45.0, 75.0].each{|angle|\n        rad = Math::PI * angle / 180.0\n        x_base = @size*Math::sin(rad)\n        y_base = @size*Math::cos(rad)\n\n        x1 = 0.90*x_base\n        y1 = 0.90*y_base\n\n        x2 = 0.875*x_base\n        y2 = 0.875*y_base\n\n        TkcLine.new(@c, x1, y1, x2, y2, \n                    :tags=>[@tag, @mark_tag], \n                    :width=>@mark_width, :fill=>@submark_color)\n        TkcLine.new(@c, x1, -y1, x2, -y2, \n                    :tags=>[@tag, @mark_tag], \n                    :width=>@mark_width, :fill=>@submark_color)\n        TkcLine.new(@c, -x1, y1, -x2, y2, \n                    :tags=>[@tag, @mark_tag], \n                    :width=>@mark_width, :fill=>@submark_color)\n        TkcLine.new(@c, -x1, -y1, -x2, -y2, \n                    :tags=>[@tag, @mark_tag], \n                    :width=>@mark_width, :fill=>@submark_color)\n      }\n    end\n  end\n\n  def _create_hands\n    hour_hand_len   = 0.55*@size\n    minute_hand_len = 0.85*@size\n    second_hand_len = 0.88*@size\n\n    hour_hand_width   = 1.8*@cdot_size\n    minute_hand_width = 1.0*@cdot_size\n    second_hand_width = 1 # 0.4*@cdot_size\n\n    @hour_hand_coords = [\n      [0, -0.5*@cdot_size], \n      [hour_hand_width, -0.5*@cdot_size-hour_hand_width], \n      [hour_hand_width, -hour_hand_len+hour_hand_width], \n      [0, -hour_hand_len], \n      [-hour_hand_width, -hour_hand_len+hour_hand_width], \n      [-hour_hand_width, -0.5*@cdot_size-hour_hand_width], \n    ]\n    @minute_hand_coords = [\n      [0, -0.5*@cdot_size], \n      [minute_hand_width, -0.5*@cdot_size - minute_hand_width], \n      [minute_hand_width, -minute_hand_len+minute_hand_width], \n      [0, -minute_hand_len], \n      [-minute_hand_width, -minute_hand_len+minute_hand_width], \n      [-minute_hand_width, -0.5*@cdot_size-minute_hand_width], \n    ]\n    @second_hand_coords = [\n      [0, -0.5*@cdot_size], \n      [second_hand_width, -0.5*@cdot_size - second_hand_width], \n      [second_hand_width, -second_hand_len+second_hand_width], \n      [0, -second_hand_len], \n      [-second_hand_width, -second_hand_len+second_hand_width], \n      [-second_hand_width, -0.5*@cdot_size-second_hand_width], \n    ]\n\n    @hour_hand = TkcPolygon.new(@c, @hour_hand_coords, \n                                :tags=>[@tag, @hand_tag], \n                                :outline=>@hour_hand_color, \n                                :fill=>@hour_hand_color)\n\n    @minute_hand = TkcPolygon.new(@c, @minute_hand_coords, \n                                  :tags=>[@tag, @hand_tag], \n                                  :outline=>@minute_hand_color, \n                                  :fill=>@minute_hand_color)\n\n    @second_hand = TkcPolygon.new(@c, @second_hand_coords, \n                                  :tags=>[@tag, @hand_tag], \n                                  :outline=>@second_hand_color, \n                                  :fill=>@second_hand_color)\n\n    @center_dot = TkcOval.new(@c, \n                              [-@cdot_size, -@cdot_size], \n                              [@cdot_size, @cdot_size], \n                              :outline=>@cdot_color, :fill=>@cdot_color)\n  end\n  private :_create_hands\n\n  def _raise_hands\n    @hour_hand.raise\n    @minute_hand.raise\n    @second_hand.raise\n    @center_dot.raise\n  end\n  private :_raise_hands\n\n  def _raise_marks\n    @mark_tag.raise\n  end\n  private :_raise_marks\n\n  def set_hands(hh, mm, ss)\n    ss_angle = Math::PI * ss / 30.0\n    mm_angle = Math::PI * (mm + ss/60.0) / 30.0\n    hh_angle = Math::PI * (hh + (mm + ss/60.0)/60.0) / (@clock.div(2))\n\n    @second_hand.coords = @second_hand_coords.collect{|x, y|\n      r = Math::hypot(y, x)\n      a = Math::atan2(y, x) + ss_angle\n      [Math::cos(a) * r, Math::sin(a) * r]\n    }\n\n    @minute_hand.coords = @minute_hand_coords.collect{|x, y|\n      r = Math::hypot(y, x)\n      a = Math::atan2(y, x) + mm_angle\n      [Math::cos(a) * r, Math::sin(a) * r]\n    }\n\n    @hour_hand.coords = @hour_hand_coords.collect{|x, y|\n      r = Math::hypot(y, x)\n      a = Math::atan2(y, x) + hh_angle\n      [Math::cos(a) * r, Math::sin(a) * r]\n    }\n\n    _raise_hands\n    _raise_marks\n  end\n\n  def coords_to_time(x, y)\n    return ((y < 0)? [0, 0]: [@clock.div(2), 0])  if x == 0\n    if @clock == 24\n      offset = (x<0&&y<0)? 1800.0: 360.0\n      m_half = 720.0\n    else # @clock == 12\n      offset = (x<0&&y<0)? 900.0: 180.0\n      m_half = 360.0\n    end\n    (offset + m_half*Math.atan2(y,x)/Math::PI).round.divmod(60)\n  end\n\n  def create_pie(hh, mm, span, color='red')\n    if @clock == 24\n      start  = 90.0 - (hh*60 + mm)/4.0  # 360.0*(hh*60+mm)/(24*60)\n      extent = -span/4.0\n    else # @clock == 12\n      start  = 90.0 - (hh*60 + mm)/2.0  # 360.0*(hh*60+mm)/(12*60)\n      extent = -span/2.0\n    end\n\n    pie = TkcArc.new(@c, @circle_coords, :tags=>[@tag], \n                     :outline=>'black', 'fill'=>color, \n                     :start=>start, :extent=>extent)\n    _raise_hands\n    _raise_marks\n    pie\n  end\nend\n\nsched = Clock.new\nsched.create_pie(0,0, 60)            #  60 minutes from 00:00\nsched.create_pie(6,30, 280, 'green') # 280 minutes from 06:30\nsched.create_pie(15,20, 90, 'blue')  #  90 minutes from 15:20\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/binding_sample.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\n\nclass Button_clone < TkLabel\n  def initialize(*args)\n    @command = nil\n\n    if args[-1].kind_of?(Hash)\n      keys = _symbolkey2str(args.pop)\n      @command = keys.delete('command')\n\n      keys['highlightthickness'] = 1 unless keys.key?('highlightthickness')\n      keys['padx'] = '3m' unless keys.key?('padx')\n      keys['pady'] = '1m' unless keys.key?('pady')\n      keys['relief'] = 'raised' unless keys.key?('relief')\n\n      args.push(keys)\n    end\n\n    super(*args)\n\n    @press = false\n\n    self.bind('Enter', proc{self.background(self.activebackground)})\n    self.bind('Leave', proc{\n                @press = false\n                self.background(self.highlightbackground)\n                self.relief('raised')\n              })\n\n    self.bind('ButtonPress-1', proc{@press = true; self.relief('sunken')})\n    self.bind('ButtonRelease-1', proc{\n                self.relief('raised')\n                @command.call if @press && @command\n                @press = false\n              })\n  end\n\n  def command(cmd = Proc.new)\n    @command = cmd\n  end\n\n  def invoke\n    if @command\n      @command.call \n    else\n      ''\n    end\n  end\nend\n\nTkLabel.new(:text=><<EOT).pack\nThis is a sample of 'event binding'.\nThe first button is a normal button widget.\nAnd the second one is a normal label widget \nbut with some bindings like a button widget.\nEOT\n\nlbl = TkLabel.new(:foreground=>'red').pack(:pady=>3)\n\nv = TkVariable.new(0)\n\nTkFrame.new{|f|\n  TkLabel.new(f, :text=>'click count : ').pack(:side=>:left)\n  TkLabel.new(f, :textvariable=>v).pack(:side=>:left)\n}.pack\n\nTkButton.new(:text=>'normal Button widget', \n             :command=>proc{\n               puts 'button is clicked!!'\n               lbl.text 'button is clicked!!'\n               v.numeric += 1\n             }){\n  pack(:fill=>:x, :expand=>true)\n}\n\nButton_clone.new(:text=>'Label with Button binding', \n                 :command=>proc{\n                   puts 'label is clicked!!'\n                   lbl.text 'label is clicked!!'\n                   v.numeric += 1\n                 }){\n  pack(:fill=>:x, :expand=>true)\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/bindtag_sample.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\n\nTkLabel.new(:text=><<EOT, :justify=>:left).pack\nThis is a sample of bindtags and usage of \nTk.callback_break/Tk.callback_continue. \nPlease check the work of following buttons \n(attend the difference between before/after \n pressing the bottom button), and see the \nsource code.\nEOT\n\ndef set_class_bind\n  TkButton.bind('ButtonPress-1', \n                proc{puts 'bind \"ButtonPress-1\" of TkButton class'})\n  TkButton.bind('ButtonRelease-1', \n                proc{puts 'bind \"ButtonRelease-1\" of TkButton class'})\nend\n\n# set root binding\nr = TkRoot.new\nr.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of root widget'})\nr.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of root widget'})\n\n# set 'all' binding\nTkBindTag::ALL.bind('ButtonPress-1', \n                    proc{puts 'bind \"ButtonPress-1\" of the tag \"all\"'})\nTkBindTag::ALL.bind('ButtonRelease-1', \n                    proc{puts 'bind \"ButtonRelease-1\" of the tag \"all\"'})\n\n# create buttons\nb1 = TkButton.new(:text=>'button-1', \n                  :command=>proc{puts \"command of button-1\"}).pack\nb2 = TkButton.new(:text=>'button-2', \n                  :command=>proc{puts \"command of button-2\"}).pack\nb3 = TkButton.new(:text=>'button-3', \n                  :command=>proc{puts \"command of button-3\"}).pack\nb4 = TkButton.new(:text=>'button-4', \n                  :command=>proc{puts \"command of button-4\"}).pack\nb5 = TkButton.new(:text=>'button-5', \n                  :command=>proc{puts \"command of button-5\"}).pack\n\n# set button binding\nb1.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of button-1'})\nb1.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of button-1'})\n\nb2.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of button-2'})\nb2.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of button-2'})\n\nb3.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of button-3'})\nb3.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of button-3'})\n\nb4.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of button-4'})\nb4.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of button-4'})\n\nb5.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of button-5'})\nb5.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of button-5'})\n\n# create bindtag and set binding\ntag1 = TkBindTag.new\ntag1.bind('ButtonPress-1',   proc{puts 'bind \"ButtonPress-1\" of tag1'})\ntag1.bind('ButtonRelease-1', proc{puts 'bind \"ButtonRelease-1\" of tag1'})\n\ntag2 = TkBindTag.new\ntag2.bind('ButtonPress-1',   \n          proc{\n            puts 'bind \"ButtonPress-1\" of tag2'\n            puts 'call Tk.callback_continue'\n            Tk.callback_continue\n            puts 'never see this message'\n          })\ntag2.bind('ButtonRelease-1', \n          proc{\n            puts 'bind \"ButtonRelease-1\" of tag2'\n            puts 'call Tk.callback_continue'\n            Tk.callback_continue\n            puts 'never see this message'\n          })\n\ntag3 = TkBindTag.new\ntag3.bind('ButtonPress-1',   \n          proc{\n            puts 'bind \"ButtonPress-1\" of tag3'\n            puts 'call Tk.callback_break'\n            Tk.callback_break\n            puts 'never see this message'\n          })\ntag3.bind('ButtonRelease-1', \n          proc{\n            puts 'bind \"ButtonRelease-1\" of tag3'\n            puts 'call Tk.callback_break'\n            Tk.callback_break\n            puts 'never see this message'\n          })\n\n# set bindtags\np b1.bindtags\n\ntags = b2.bindtags\ntags[2,0] = tag1\ntags[0,0] = tag1\nb2.bindtags(tags)\np b2.bindtags\n\ntags = b3.bindtags\ntags[2,0] = tag2\ntags[0,0] = tag2\nb3.bindtags(tags)\np b3.bindtags\n\ntags = b4.bindtags\ntags[2,0] = tag3\ntags[0,0] = tag3\nb4.bindtags(tags)\np b4.bindtags\n\nb5.bindtags([tag1, TkButton, tag2, b5])\n\n# create button to set button class binding\nTkButton.new(:text=>'set binding to TkButton class', \n             :command=>proc{\n               puts 'call \"set_class_bind\"'\n               set_class_bind\n             }).pack(:pady=>7)\n\n# start event-loop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/binstr_usage.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"tk\"\n\nTkMessage.new(:width=>360, :text=><<EOM).pack\nThis sample shows how to use a binary sequence between Ruby and Tk. \\\nThis reads the image data from the file as the binary sequence.\n\nTo treat the difference of encodings between on Ruby and on Tk seamlessly, \\\nRuby/Tk converts the encoding of string arguments automatically. \\\nI think it is comfortable for users on almost all situations. \\\nHowever, when treats a binary sequence, the convert process makes troubles.\n\nTk::BinaryString class (subclass of Tk::EncodedString class) is the class \\\nto avoid such troubles. Please see the source code of this sample. \\\nA Tk::BinaryString instance is used to create the image for the center button. \nEOM\n\nImgFile=[File.dirname(__FILE__), 'images','tcllogo.gif'].join(File::Separator)\n\nph1 = TkPhotoImage.new(:file=>ImgFile)\np ph1.configinfo\n\nb_str = Tk::BinaryString(IO.read(ImgFile))\np [b_str, b_str.encoding]\n\nph2 = TkPhotoImage.new(:data=>b_str)\np ph2.configinfo\np ph2.data(:grayscale=>true)\n\nph3 = TkPhotoImage.new(:palette=>256)\nph3.put(ph2.data)\n\nph4 = TkPhotoImage.new()\nph4.put(ph2.data(:grayscale=>true))\n\n#p [b_str.encoding, b_str.rb_encoding]\n\nf = TkFrame.new.pack\nTkButton.new(:parent=>f, :image=>ph1, :command=>proc{exit}).pack(:side=>:left)\nTkButton.new(:parent=>f, :image=>ph2, :command=>proc{exit}).pack(:side=>:left)\nTkButton.new(:parent=>f, :image=>ph3, :command=>proc{exit}).pack(:side=>:left)\nTkButton.new(:parent=>f, :image=>ph4, :command=>proc{exit}).pack(:side=>:left)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/btn_with_frame.rb",
    "content": "require 'tk'\n\nclass Button_with_Frame < TkButton\n  def create_self(keys)\n    @frame = TkFrame.new('widgetname'=>@path, 'background'=>'yellow')\n    install_win(@path) # create new @path which is a daughter of old @path\n    super(keys)\n    TkPack(@path, :padx=>7, :pady=>7)\n    @epath = @frame.path\n  end\n  def epath\n    @epath\n  end\nend\n\nButton_with_Frame.new(:text=>'QUIT', :command=>proc{exit}) {\n  pack(:padx=>15, :pady=>5)\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/cd_timer.rb",
    "content": "#!/usr/bin/env ruby\n#\n#   countdown timer\n#     usage: cd_timer min [, min ... ]\n#            ( e.g. cd_timer 0.5 1 3 5 10 )\n#\nrequire 'tk'\n\nif ARGV.empty?\n  $stderr.puts 'Error:: No time arguments for counting down' \n  exit(1)\nend\n\nwidth = 10\n\nTkButton.new(:text=>'exit', \n             :command=>proc{exit}).pack(:side=>:bottom, :fill=>:x)\n\nb = TkButton.new(:text=>'start').pack(:side=>:top, :fill=>:x)\n\nf = TkFrame.new(:relief=>:ridge, :borderwidth=>2).pack(:fill=>:x)\nTkLabel.new(f, :relief=>:flat, :pady=>3, \n            :background=>'black', :foreground=>'white', \n            :text=>'  elapsed: ').pack(:fill=>:x, :side=>:left, :expand=>true)\nnow = TkLabel.new(f, :width=>width, :relief=>:flat, :pady=>3, :anchor=>:w, \n                  :background=>'black', :foreground=>'white', \n                  :text=>'%4d:%02d.00' % [0, 0]).pack(:side=>:right)\n\ntimers = [ TkRTTimer.new(10){|tm|\n    t = (tm.return_value || 0) + 1\n    s, u = t.divmod(100)\n    m, s = s.divmod(60)\n    now.text('%4d:%02d.%02d' % [m, s, u])\n    t\n  }.set_start_proc(0, proc{\n                     now.text('%4d:%02d.00' % [0,0])\n                     now.foreground('white')\n                     0\n                   })\n]\n\nARGV.collect{|arg| (Float(arg) * 60).to_i}.sort.each_with_index{|time, idx|\n  f = TkFrame.new(:relief=>:ridge, :borderwidth=>2).pack(:fill=>:x)\n  TkLabel.new(f, :relief=>:flat, :pady=>3, \n              :text=>'  %4d:%02d  --> ' % (time.divmod(60))).pack(:side=>:left)\n  l = TkLabel.new(f, :width=>width, :relief=>:flat, :pady=>3, :anchor=>:w, \n                  :text=>'%4d:%02d' % (time.divmod(60))).pack(:side=>:right)\n  timers << TkRTTimer.new(1000){|tm|\n    t = (tm.return_value || time) - 1\n    if t < 0\n      l.text('%4d:%02d' % ((-t).divmod(60)))\n    else\n      l.text('%4d:%02d' % (t.divmod(60)))\n    end\n    if t.zero?\n      l.foreground('red')\n      idx.times{Tk.bell}\n    end\n    t\n  }.set_start_proc(0, proc{\n                     l.text('%4d:%02d' % (time.divmod(60)))\n                     l.foreground('black')\n                     time\n                   })\n}\n\nmode = :start\nb.command(proc{\n            if mode == :start\n              timers.each{|timer| timer.restart}\n              b.text('reset')\n              mode = :reset\n            else\n              timers.each{|timer| timer.stop.reset}\n              b.text('start')\n              mode = :start\n            end\n          })\n\nTk.mainloop\n\n"
  },
  {
    "path": "ext/tk/sample/cmd_res_test.rb",
    "content": "require 'tk'\nTkOptionDB.readfile(File.expand_path('cmd_resource', \n                                     File.dirname(__FILE__)))\nf = TkFrame.new(:class=>'BtnFrame').pack\nb = TkButton.new(:parent=>f, :widgetname=>'hello').pack\ncmd1 = TkOptionDB.new_proc_class(b, [:show_msg, :bye_msg], 3)\ncmd2 = TkOptionDB.new_proc_class(:ZZZ, [:show_msg, :bye_msg], 3, false, cmd1)\ncmd3 = TkOptionDB.new_proc_class(:ZZZ, [:show_msg, :bye_msg], 3, false, b)\ncmd4 = TkOptionDB.new_proc_class(:BTN_CMD, [:show_msg, :bye_msg], 3){\n  def self.__check_proc_string__(str)\n    \"{|arg| print [arg, $SAFE].inspect, ': '; Proc.new#{str}.call(arg)}\"\n  end\n}\ncmd1.show_msg('cmd1')\ncmd2.show_msg('cmd2')\ncmd3.show_msg('cmd3')\ncmd4.show_msg('cmd4')\n"
  },
  {
    "path": "ext/tk/sample/cmd_resource",
    "content": "*BtnFrame.hello.text: HELLO\n*BtnFrame.hello.command: ruby {puts \"Hello World!!\"}\n*BTN_CMD.show_msg: {|arg| print \"Hello, #{arg}!!\\n\"}\n*hello.show_msg: {|arg| print \"Hello, Hello, #{arg}!!\\n\"}\n*hello.ZZZ.show_msg: {|arg| print \"Hello, Hello, ZZZ:#{arg}!!\\n\"}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ChangeLog",
    "content": "2002-08-29 16:30  matt\n\n\t* ChangeLog: ChangeLog is auto-generated *from* CVS log.\n\n2002-08-29 16:27  matt\n\n\t* ChangeLog.prev: [no log message]\n\n2002-08-28 18:07  matt\n\n\t* browse1, browse2, hello, ixset, rmt, rolodex, rolodex-j, square,\n\ttcolor, timer, widget: Changed #! lines to the slightly more\n\tportable '#!/usr/bin/env ruby'.\n\n2002-08-28 17:56  matt\n\n\t* icon.rb, items.rb, label.rb, menu.rb, ruler.rb: Changed bitmap\n\tfile extensions from .bmp to .xbm.\n\n2002-08-28 17:55  matt\n\n\t* images/: face.bmp, face.xbm, flagdown.bmp, flagdown.xbm,\n\tflagup.bmp, flagup.xbm, gray25.bmp, gray25.xbm, letters.bmp,\n\tletters.xbm, noletter.bmp, noletter.xbm, pattern.bmp, pattern.xbm:\n\tChanged X bitmap file extensions from .bmp to the more intuitive\n\t.xbm.\n\n2002-08-28 17:35  matt\n\n\t* bitmap.rb, colors.rb, cscroll.rb, ctext.rb, hello, ixset,\n\tmenubu.rb, patch_1.1c1, rmt, style.rb, timer, ChangeLog, README,\n\tREADME.tkencoding, arrow.rb, bind.rb, browse1, browse2, button.rb,\n\tcheck.rb, clrpick.rb, dialog1.rb, dialog2.rb, entry1.rb, entry2.rb,\n\tfilebox.rb, floor.rb, form.rb, hscale.rb, icon.rb, image1.rb,\n\timage2.rb, items.rb, label.rb, menu.rb, msgbox.rb, plot.rb,\n\tpuzzle.rb, radio.rb, rolodex, rolodex-j, ruler.rb, sayings.rb,\n\tsearch.rb, square, states.rb, tcolor, text.rb, tkencoding.rb,\n\ttwind.rb, vscale.rb, widget, doc.org/README, doc.org/README.JP,\n\tdoc.org/README.tk80, doc.org/license.terms,\n\tdoc.org/license.terms.tk80, images/earth.gif, images/earthris.gif,\n\timages/face.bmp, images/flagdown.bmp, images/flagup.bmp,\n\timages/gray25.bmp, images/grey.25, images/grey.5,\n\timages/letters.bmp, images/noletter.bmp, images/pattern.bmp,\n\timages/tcllogo.gif, images/teapot.ppm: Initial revision\n\n2002-08-28 17:35  matt\n\n\t* bitmap.rb, colors.rb, cscroll.rb, ctext.rb, hello, ixset,\n\tmenubu.rb, patch_1.1c1, rmt, style.rb, timer, ChangeLog, README,\n\tREADME.tkencoding, arrow.rb, bind.rb, browse1, browse2, button.rb,\n\tcheck.rb, clrpick.rb, dialog1.rb, dialog2.rb, entry1.rb, entry2.rb,\n\tfilebox.rb, floor.rb, form.rb, hscale.rb, icon.rb, image1.rb,\n\timage2.rb, items.rb, label.rb, menu.rb, msgbox.rb, plot.rb,\n\tpuzzle.rb, radio.rb, rolodex, rolodex-j, ruler.rb, sayings.rb,\n\tsearch.rb, square, states.rb, tcolor, text.rb, tkencoding.rb,\n\ttwind.rb, vscale.rb, widget, doc.org/README, doc.org/README.JP,\n\tdoc.org/README.tk80, doc.org/license.terms,\n\tdoc.org/license.terms.tk80, images/earth.gif, images/earthris.gif,\n\timages/face.bmp, images/flagdown.bmp, images/flagup.bmp,\n\timages/gray25.bmp, images/grey.25, images/grey.5,\n\timages/letters.bmp, images/noletter.bmp, images/pattern.bmp,\n\timages/tcllogo.gif, images/teapot.ppm: Taking over demo package\n\tfrom Jonathan Conway.\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ChangeLog.prev",
    "content": "2001-07-26      <rise@leannan.knavery.net>\n\n\t* Moved files to directory ruby-tk81-demos-english in tarball.\n\n2001-07-26      <rise@knavery.net>\n\n\t* Added test to widget and hello versus Tk::TCL_VERSION & Tk::JAPANIZED_TK (per Guy Decoux in [ruby-talk:18559]) before requiring tkencoding.rb.\n\n\t"
  },
  {
    "path": "ext/tk/sample/demos-en/README",
    "content": "Current Maintainer: \n\tJonathan Conway\n\trise@knavery.net\n\n\tPlease direct all bug reports/requests/suggestions to the above \n\taddress.\n\n\nNotes:\n\n* \tThe files hello and widget have been changed to test Tk::TCL_VERSION \n\tand Tk::JAPANIZED_TK before requiring tkencoding.rb to prevent an\n\tinfinite loop.  This test was taken from a message in\n\t[ruby-talk:18559] by Guy Decoux.\n\n*\tThe .bmp files in the images directory are X bitmaps (i.e. XBM to many\n\tgraphics packages), not Windows bitmaps (.bmp).  You will not be\n\table to use images exported by a graphics program as Windows\n\tbitmaps with this demo collection nor will you be able to edit the\n\tincluded images without setting the file type correctly.\n\t\n-- Jonathan Conway, 2001-07-26\n\n\n#------------------------------------------------------------------------------\n# ==== Introduction. ====\n#\n# To create this version of the Ruby/Tk widget demo, I took the\n# ruby-tk81-demos and removed all the Kanji strings and comments.  I\n# have tried to restore the original English strings and comments\n# using the Tcl/Tk8.2.2 version of the widget demo. \n#\n# When I tried running the Kanji version, all I got was a mostly blank\n# panel with a non-functional \"File\" button. I disovered that if all\n# non-ASCII characters were replaced with blanks, then I could get the\n# gutted stuff running.  \n#\n# Since English Ruby/Tk documentation is lacking and I needed this\n# code to see how it worked and to use as the basis of my try-it\n# prototype (The Ruby Yielding Interactive Toolkit), plus the fact\n# that no help was forthcoming for making the Kanji version work (plus\n# the fact that I can't read Kanji anyway), I decided to embark on\n# this English restoration project. \n#\n# Thanks to everyone who worked on the original Ruby/Tk widget demo\n# (and the preceding Tcl/Tk version for that matter).  The\n# comparatively simple task of changing text strings and comments has\n# made me appreciate the great amount of original work that went into\n# this.\n#\n# -- Conrad Schneiker, 2000-07-23.\n#------------------------------------------------------------------------------\n\n#------------------------------------------------------------------------------\n# ==== Known bugs. ====\n#\n# ^C-ing the demo gives Ruby interrupt and stack message; clean exit needed.\n# Font settings don't work correctly.\n# Dismissing the embedded windows demo (tkwind.rb) kills the widget demo.\n# Rerunning the canvas item demo from the code widow get errors.\n# The \"press me\" button in the canvas item demo doesn't time out.\n# The simple 2 d plot starts up extremely slow compared to the Tcl version.\n# The first item message on the icon menu on the menu and cascades demo doesn't work.\n#------------------------------------------------------------------------------\n\n\n###################### Original README ########################################\n\n  Ruby/Tk81 widget-demo\t\t\t1999/08/13\n\n\t\t\t\t\tΦüʳظ\n\t\t\t\t\tΩ <ttate@jaist.ac.jp>\n\nTcl/Tk8.1Ǥunicode(UTF8)Ѥ졢unicodeѴ줿ܸǤ\nWidgetɽ뤳ȤǽǤܥ֤ˤϰ˱ʰ椵濴\nʤƺ줿Ruby/TkΥץ˽äʲδĶˤƤư\nǧΤǤ\n\n* ruby-1.3.7,ruby-1.4.0\n* tcl8.1, tk8.1\n* linux-2.2\n\nWindows(Cygwin)ˤơץưˤruby-KeȤץ\nƵưɤǤ\n\t\t\t\t\t󶡡դ\n\t\t\t\t\t<eban@os.rim.or.jp>\n\n----------------------------------------------------------------------------\n  Ruby/Tk widget-demo \n                              version 1.1 ( 1998/07/24 )\n                              ʰǽ幩 (nagai@ai.kyutech.ac.jp)\n\nɸۤ Tcl/Tk ĥѥå Ruby (ʲ Ruby/Tk ȸƤӤޤ) \nǤϡTk widget Ѥ GUI κԤȤǤޤºݤ GUI \nƤˤ͡ʼ㤬ץȤ¸ߤʤΤǤRuby/Tk \nˤϤΤ褦Ŭʥץ륹ץȽ¸ߤޤǤФ\nĥѥåθǤ Tcl/Tk ˤϡTk widget ѤƤɤΤ褦ʤȤ\n뤫򼨤ΤȤ widget-demo ¸ߤꡤTcl/Tk Ѥ GUI κ\nݤɽŪץȤʤäƤޤܥ֤ϡRuby/Tk ν\nɽŪʥץ륹ץȤȤ٤Tcl/Tk  widget-demo ܿ\nΤǤ\n\nܥ֤˴ޤޤ륹ץȤ¹Ԥ뤿ˤϡruby-1.1c2 ʾǤ뤳\nȤɬפǤ1.1c1 ξϡܥ֤˴ޤޤ patck_1.1c1  Ruby \n饤֥ˤƤƤȤ߹ Tk ΥСϡ4.2 Ǥ 8.0 Ǥ⽤\nʤưϤǤܸǤǤΰܿȤʤäƤ뤿ᡤܸ첽\n줿 Tk ѤץȤΥƥȤϡTk4.2jp  Tk8.0jp ξǹ\nޤ (ˤǤϤʤǤ)\n\nܥ֤˴ޤޤ륹ץȤ¿ϡȤʤäƤ Tcl/Tk ǤŪ\nץȵҤȤʤ褦ˤƤޤΤᡤRuby/Tk Υץȸ\nϡޤ Ruby 餷ʤȤǤ礦ˤ⤫餺Τ褦ʵ\näƤͳϡRuby/Tk Υɥ­ˤޤ\n\nTcl/Tk ˤŬʻͽ񤬲¸ߤƤޤ顤Ruby/Tk ץȤ\nݤϡΤ褦 Tcl/Tk λͽǾ䤤ʤ뤳ȤˤʤȻ\nޤ widget λȤơTcl/Tk  widget-demo 򻲾Ȥ뤳Ȥ⤢\nǤ礦Ruby/Tk ǤεҤ widget-demo  Tcl/Tk ǤεҤ˶ᤤΤˤ\nСˤäơRuby/Tk 뤳ȤǤȹͤޤ\nö Ruby/Tk Ǥ  widget λˡƤޤСRuby 餷\nץȤ뤳Ȥ񤷤ʤǤ礦ܥ֤ΥץȤϡRuby/Tk \nǽ˽ޤǤƧȤѤƤйǤ\n\nwidget-demo ΰܿˤäƤϡˤܿץȤ󶡤Ƥ\nޤ˴դΰդɽޤ\n\n    ΩСJAIST (ttate@jaist.ac.jp)  \n    ʿͻ (hiramatu@cdrom.co.jp) \n\nʿˤ Ruby/Tk  Web page (http://www.cdrom.co.jp/~hiramatu/) \n Ruby/Tk νͭѤȻפޤΤǡҤȤ\n\nޤ (maebashi@iij.ad.jp) ϤȤơwidget-demo ΰܿ˺ݤ\nɬפȤʤä Ruby  Tk Ϣ饤֥꽤ˤĤơХλŦ\nƤˤⴶפޤ\n\nƺǸ˺δդ Ruby ߷׼Ԥ ޤĤ 椭Ҥ (matz@netlab.co.jp) \nȻפޤ\n"
  },
  {
    "path": "ext/tk/sample/demos-en/README.1st",
    "content": "There are Ruby/Tk demo scripts.\n\nFiles with '.rb' extension are sub-scripts which are launched 'widget'\nscript. Those files don't work independently. Please call them from \n'widget' script.\n\nIf you want start some sub-scripts at same time when the launcher\nscript tarts, please give the sub-script names as arguments. \n(e.g. /usr/local/bin/ruby widget button.rb entry1.rb text.rb )\nYou can ommit '.rb' of the sub-scripts\n(e.g. /usr/local/bin/ruby widget button entry1 text )\n\nIf you don't need launcher's main window, give -n option. \n(e.g. /usr/local/bin/ruby widget -n button.rb entry1.rb text.rb )\n\nOthers (browse1, hello, and so on) are standalone scripts. \n\n          2004/04/14  Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/README.tkencoding",
    "content": "This is a original document of 'tkencoding.rb'. \nThe library 'tkencoding.rb' is obsolete. \nFunctions of tkencoding.rb is already included into Ruby/Tk.\n\n-------------------------------------------------\ntkencoding.rbѤܸɽˤĤ\n\nCopyright (C) 1999/07, Takaaki Tateishi <ttate@jaist.ac.jp>\n\n\n1. tkencoding.rbȤϡ\n\ntkencoding.rbTcl/Tk8.1ѤRuby/TkΤΥ饤֥\nǤtkencoding.rbrequire뤳ȤˤäWedgetɽ\nƥȤunicode(UTF8)Ѵޤ\n\n\n2. Ȥ\n\ntkencoding.rbrequireTk.encodingǻѤƤʸ\nꤷƲ㤨аʲΤ褦ʴˤʤޤ\n\n----\nrequire 'tk'\nrequire 'tkencoding'\n\nTk.encoding = \"euc-jp\"\n# Tk.encoding = \"shiftjis\"\n---\n"
  },
  {
    "path": "ext/tk/sample/demos-en/anilabel.rb",
    "content": "#\n# animated label widget demo (called by 'widget')\n#\n# based on Tcl/Tk8.5a2 widget demos\n\nif defined?($anilabel_demo) && $anilabel_demo\n  $anilabel_demo.destroy \n  $anilabel_demo = nil\nend\n\n# demo toplevel widget\n$anilabel_demo = TkToplevel.new {|w|\n  title(\"Animated Label Demonstration\")\n  iconname(\"anilabel\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($anilabel_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"Four animated labels are displayed below; each of the labels on the left is animated by making the text message inside it appear to scroll, and the label on the right is animated by animating the image that it displays.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $anilabel_demo\n      $anilabel_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Code'\n    command proc{showCode 'anilabel'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# create frame for label demo\nf_left = TkLabelFrame.new(base_frame,  :text=>'Scrolling Texts')\nf_right = TkLabelFrame.new(base_frame, :text=>'GIF Image')\nTk.pack(f_left, f_right, 'side'=>'left', 'expand'=>'yes', 'fill'=>'both', \n        'padx'=>10, 'pady'=>10)\n\n# animated label\nclass AnimatedTextLabel < TkLabel\n  def initialize(*args)\n    super(*args)\n    @timer = TkTimer.new{ _animation_callback }\n    @timer.loop_exec = -1\n    # bind('Destroy'){ @timer.stop }\n    @btag = TkBindTag.new('Destroy'){ @timer.stop }\n    self.bindtags_unshift(@btag)\n  end\n\n  def _animation_callback()\n    txt = self.text\n    self.text = (txt[1..-1] << txt[0])\n  end\n  private :_animation_callback\n\n  def start(interval)\n    @timer.set_interval(interval)\n    @timer.start\n  end\n\n  def stop\n    @timer.stop\n  end\nend\n\n# animated image\nclass AnimatedImageLabel < AnimatedTextLabel\n  def initialize(*args)\n    super(*args)\n    @destroy_image = false\n    @btag.bind_append('Destroy'){\n      if @destroy_image\n        begin\n          self.image.delete \n        rescue\n        end\n      end\n    }\n  end\n  attr_accessor :destroy_image\n\n  def _animation_callback()\n    img = self.image\n\n    fmt = img.format\n    if fmt.kind_of?(Array)\n      if fmt[1].kind_of?(Hash)\n        # fmt == ['GIF', {'index'=>idx}]\n        idx = fmt[1]['index']\n      else\n        # fmt == ['GIF', '-index', idx]  :: Ruby1.8.2 returns this.\n        idx = fmt[2]\n      end\n    elsif fmt.kind_of?(String) && fmt =~ /GIF -index (\\d+)/\n      idx = $1.to_i\n    else\n      idx = -1\n    end\n\n    begin\n      img.format(\"GIF -index #{idx + 1}\")\n    rescue => e\n      img.format(\"GIF -index 0\")\n    end\n  end\n  private :_animation_callback\nend\n\n# create labels\nl1 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:ridge, \n                           :font=>{:family=>'Courier', :size=>10})\nl2 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:groove, \n                           :font=>{:family=>'Courier', :size=>10})\nl3 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:flat, \n                           :font=>{:family=>'Courier', :size=>10}, :width=>18)\nTk.pack(l1, l2, l3, \n        :side=>:top, :expand=>true, :anchor=>:w, :padx=>10, :pady=>10)\n\nlimg = AnimatedImageLabel.new(f_right, :borderwidth=>0)\nlimg.pack(:side=>:top, :expand=>true, :padx=>10, :pady=>10)\n\n# base64-encoded animated GIF file\ntclPowerdData = <<EOD\n    R0lGODlhKgBAAPQAAP//////zP//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM\n    zMyZmcyZZsxmZsxmAMwzAJnMzJmZzJmZmZlmmZlmZplmM5kzM2aZzGZmzGZm\n    mWZmZmYzZmYzMzNmzDMzZgAzmSH+IE1hZGUgd2l0aCBHSU1QIGJ5IExARGVt\n    YWlsbHkuY29tACH5BAVkAAEALAAAAAAqAEAAAAX+YCCOZEkyTKM2jOm66yPP\n    dF03bx7YcuHIDkGBR7SZeIyhTID4FZ+4Es8nQyCe2EeUNJ0peY2s9mi7PhAM\n    ngEAMGRbUpvzSxskLh1J+Hkg134OdDIDEB+GHxtYMEQMTjMGEYeGFoomezaC\n    DZGSHFmLXTQKkh8eNQVpZ2afmDQGHaOYSoEyhhcklzVmMpuHnaZmDqiGJbg0\n    qFqvh6UNAwB7VA+OwydEjgujkgrPNhbTI8dFvNgEYcHcHx0lB1kX2IYeA2G6\n    NN0YfkXJ2BsAMuAzHB9cZMk3qoEbRzUACsRCUBK5JxsC3iMiKd8GN088SIyT\n    0RAFSROyeEg38caDiB/+JEgqxsODrZJ1BkT0oHKSmI0ceQxo94HDpg0qsuDk\n    UmRAMgu8OgwQ+uIJgUMVeGXA+IQkzEeHGvD8cIGlDXsLiRjQ+EHroQhea7xY\n    8IQBSgYYDi1IS+OFBCgaDMGVS3fGi5BPJpBaENdQ0EomKGD56IHwO39EXiSC\n    Ysgxor5+Xfgq0qByYUpiXmwuoredB2aYH4gWWda0B7SeNENpEJHC1ghi+pS4\n    AJpIAwWvKPBi+8YEht5EriEqpFfMlhEdkBNpx0HUhwypx5T4IB1MBg/Ws2sn\n    wV3MSQOkzI8fUd48Aw3dOZto71x85hHtHijYv18Gf/3GqCdDCXHNoICBobSo\n    IqBqJLyCoH8JPrLgdh88CKCFD0CGmAiGYPgffwceZh6FC2ohIIklnkhehTNY\n    4CIHHGzgwYw01ujBBhvAqKOLLq5AAk9kuSPkkKO40NB+h1gnypJIIvkBf09a\n    N5QIRz5p5ZJXJpmlIVhOGQA2TmIJZZhKKmmll2BqyWSXWUrZpQtpatlmk1c2\n    KaWRHeTZEJF8SqLDn/hhsOeQgBbqAh6DGqronxeARUIIACH5BAUeAAAALAUA\n    LgAFAAUAAAUM4CeKz/OV5YmqaRkCACH5BAUeAAEALAUALgAKAAUAAAUUICCK\n    z/OdJVCaa7p+7aOWcDvTZwgAIfkEBR4AAQAsCwAuAAkABQAABRPgA4zP95zA\n    eZqoWqqpyqLkZ38hACH5BAUKAAEALAcALgANAA4AAAU7ICA+jwiUJEqeKau+\n    r+vGaTmac63v/GP9HM7GQyx+jsgkkoRUHJ3Qx0cK/VQVTKtWwbVKn9suNunc\n    WkMAIfkEBQoAAAAsBwA3AAcABQAABRGgIHzk842j+Yjlt5KuO8JmCAAh+QQF\n    CgAAACwLADcABwAFAAAFEeAnfN9TjqP5oOWziq05lmUIACH5BAUKAAAALA8A\n    NwAHAAUAAAUPoPCJTymS3yiQj4qOcPmEACH5BAUKAAAALBMANwAHAAUAAAUR\n    oCB+z/MJX2o+I2miKimiawgAIfkEBQoAAAAsFwA3AAcABQAABRGgIHzfY47j\n    Q4qk+aHl+pZmCAAh+QQFCgAAACwbADcABwAFAAAFEaAgfs/zCV9qPiNJouo7\n    ll8IACH5BAUKAAAALB8ANwADAAUAAAUIoCB8o0iWZggAOw==\nEOD\n\nl1.text('* Slow Animation *').start(300)\nl2.text('* Fast Animation *').start(80)\nl3.text('This is a longer scrolling text in a widget that will not show the whole message at once. ').start(150)\n\nlimg.destroy_image = true\nlimg.image(TkPhotoImage.new(:format=>'GIF', :data=>tclPowerdData)).start(100)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/aniwave.rb",
    "content": "#\n# animated wave demo (called by 'widget')\n#\n# based on Tcl/Tk8.5a2 widget demos\n\n# destroy toplevel widget for this demo script\nif defined?($aniwave_demo) && $aniwave_demo\n  $aniwave_demo.destroy \n  $aniwave_demo = nil\nend\n\n# create toplevel widget\n$aniwave_demo = TkToplevel.new {|w|\n  title(\"Animated Wave Demonstration\")\n  iconname(\"aniwave\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($aniwave_demo).pack(:fill=>:both, :expand=>true)\n\n# create label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text 'This demonstration contains a canvas widget with a line item inside it. The animation routines work by adjusting the coordinates list of the line.'\n}\nmsg.pack('side'=>'top')\n\n# create frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $aniwave_demo\n      $aniwave_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Code'\n    command proc{showCode 'aniwave'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# animated wave\nclass AnimatedWaveDemo\n  def initialize(frame, dir=:left)\n    @direction = dir\n\n    # create canvas widget\n    @c = TkCanvas.new(frame, :width=>300, :height=>200, \n                      :background=>'black')\n    @c.pack(:padx=>10, :pady=>10, :expand=>true)\n\n    # Creates a coordinates list of a wave. \n    @waveCoords = []\n    @backupCoords = []\n    n = 0\n    (-10..300).step(5){|n| @waveCoords << [n, 100]; @backupCoords << [n, 100] }\n    n = 305\n    @waveCoords << [n, 0]; @backupCoords << [n, 0]\n    @waveCoords << [n+5, 200]; @backupCoords << [n+5, 200]\n    @coordsLen = @waveCoords.length\n\n    # Create a smoothed line and arrange for its coordinates to be the\n    # contents of the variable waveCoords.\n    @line = TkcLine.new(@c, @waveCoords, \n                        :width=>1, :fill=>'green', :smooth=>true)\n\n    # Main animation \"loop\". \n    # Theoretically 100 frames-per-second (==10ms between frames)\n    @timer = TkTimer.new(10){ basicMotion; reverser }\n\n    # Arrange for the animation loop to stop when the canvas is deleted\n    @c.bindtags_unshift(TkBindTag.new('Destroy'){ @timer.stop })\n  end\n\n  # Basic motion handler. Given what direction the wave is travelling\n  # in, it advances the y coordinates in the coordinate-list one step in\n  # that direction.\n  def basicMotion\n    @backupCoords, @waveCoords = @waveCoords, @backupCoords\n    (0...@coordsLen).each{|idx|\n      if @direction == :left\n        @waveCoords[idx][1] = @backupCoords[(idx+1 == @coordsLen)? 0: idx+1][1]\n      else\n        @waveCoords[idx][1] = @backupCoords[(idx == 0)? -1: idx-1][1]\n      end\n    }\n    @line.coords(@waveCoords)\n  end\n\n  # Oscillation handler. This detects whether to reverse the direction\n  # of the wave by checking to see if the peak of the wave has moved off\n  # the screen (whose size we know already.)\n  def reverser\n    if @waveCoords[0][1] < 10\n      @direction = :right\n    elsif @waveCoords[-1][1] < 10\n      @direction = :left\n    end\n  end\n\n  # animation control\n  def move\n    @timer.start\n  end\n\n  def stop\n    @timer.stop\n  end\nend\n\n# Start the animation processing\nAnimatedWaveDemo.new(base_frame, :left).move\n"
  },
  {
    "path": "ext/tk/sample/demos-en/arrow.rb",
    "content": "# arrow.rb\n#\n# This demonstration script creates a canvas widget that displays a\n# large line with an arrowhead whose shape can be edited interactively.\n#\n# arrowhead widget demo (called by 'widget')\n#\n\n# arrowSetup --\n# This method regenerates all the text and graphics in the canvas\n# window.  It's called when the canvas is initially created, and also\n# whenever any of the parameters of the arrow head are changed\n# interactively.\n#\n# Arguments:\n# c -           Name of the canvas widget.\n\ndef arrowSetup(c)\n  v = $demo_arrowInfo\n\n  # Remember the current box, if there is one.\n  tags = c.gettags('current')\n  if tags != []\n    cur = tags.find{|t| t.kind_of?(String) && t =~ /^box[1-3]$/ }\n  else\n    cur = nil\n  end\n\n  # Create the arrow and outline.\n  c.delete('all')\n  TkcLine.new(c, v.x1, v.y, v.x2, v.y, \n              { 'width'=>10 * v.width, \n                'arrowshape'=>[10*v.a, 10*v.b, 10*v.c], \n                'arrow'=>'last' \n              }.update(v.bigLineStyle) )\n  xtip = v.x2 - 10*v.b\n  deltaY = 10*v.c + 5*v.width\n  TkcLine.new(c, v.x2, v.y, xtip, v.y + deltaY, \n              v.x2 - 10*v.a, v.y, xtip, v.y - deltaY, v.x2, v.y, \n              'width'=>2, 'capstyle'=>'round', 'joinstyle'=>'round')\n\n  # Create the boxes for reshaping the line and arrowhead.\n  TkcRectangle.new(c, v.x2-10*v.a-5, v.y-5, v.x2-10*v.a+5, v.y+5, \n                   {'tags'=>['box1', $arrowTag_box]}.update(v.boxStyle) )\n  TkcRectangle.new(c, xtip-5, v.y-deltaY-5, xtip+5, v.y-deltaY+5, \n                   {'tags'=>['box2', $arrowTag_box]}.update(v.boxStyle) )\n  TkcRectangle.new(c, v.x1-5, v.y-5*v.width-5, v.x1+5, v.y-5*v.width+5, \n                   {'tags'=>['box3', $arrowTag_box]}.update(v.boxStyle) )\n  c.itemconfigure cur, v.activeStyle if cur\n\n  # Create three arrows in actual size with the same parameters\n  TkcLine.new(c, v.x2+50, 0, v.x2+50, 1000, 'width'=>2)\n  tmp = v.x2+100\n  TkcLine.new(c, tmp, v.y-125, tmp, v.y-75, 'width'=>v.width, \n              'arrow'=>'both', 'arrowshape'=>[v.a, v.b, v.c])\n  TkcLine.new(c, tmp-25, v.y, tmp+25, v.y, 'width'=>v.width, \n              'arrow'=>'both', 'arrowshape'=>[v.a, v.b, v.c])\n  TkcLine.new(c, tmp-25, v.y+75, tmp+25, v.y+125, 'width'=>v.width, \n              'arrow'=>'both', 'arrowshape'=>[v.a, v.b, v.c])\n\n  # Create a bunch of other arrows and text items showing the \n  # current dimensions.\n  tmp = v.x2+10\n  TkcLine.new(c, tmp, v.y-5*v.width, tmp, v.y-deltaY, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x2+15, v.y-deltaY+5*v.c, 'text'=>v.c, 'anchor'=>'w')\n  tmp = v.x1-10\n  TkcLine.new(c, tmp, v.y-5*v.width, tmp, v.y+5*v.width, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x1-15, v.y, 'text'=>v.width, 'anchor'=>'e')\n  tmp = v.y+5*v.width+10*v.c+10\n  TkcLine.new(c, v.x2-10*v.a, tmp, v.x2, tmp, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x2-5*v.a, tmp+5, 'text'=>v.a, 'anchor'=>'n')\n  tmp = tmp+25\n  TkcLine.new(c, v.x2-10*v.b, tmp, v.x2, tmp, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x2-5*v.b, tmp+5, 'text'=>v.b, 'anchor'=>'n')\n\n  if $tk_version =~ /^4.*/\n    TkcText.new(c, v.x1, 310, 'text'=>\"'width'=>#{v.width}\", 'anchor'=>'w', \n                'font'=>'-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*')\n    TkcText.new(c, v.x1, 330, \n                'text'=>\"'arrowshape'=>[#{v.a}, #{v.b}, #{v.c}]\",'anchor'=>'w',\n                'font'=>'-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*')\n  else\n    TkcText.new(c, v.x1, 310, 'text'=>\"'width'=>#{v.width}\", 'anchor'=>'w', \n                'font'=>'Helvetica 18')\n    TkcText.new(c, v.x1, 330, \n                'text'=>\"'arrowshape'=>[#{v.a}, #{v.b}, #{v.c}]\",\n                'anchor'=>'w', 'font'=>'Helvetica 18')\n  end\n\n  v.count += 1\nend\n\n# toplevel widget\nif defined?($arrow_demo) && $arrow_demo\n  $arrow_demo.destroy \n  $arrow_demo = nil\nend\n\n# demo toplevel widget\n$arrow_demo = TkToplevel.new {|w|\n  title(\"Arrowhead Editor Demonstration\")\n  iconname(\"arrow\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($arrow_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', \n            'text'=>\"This widget allows you to experiment with different widths and arrowhead shapes for lines in canvases.  To change the line width or the shape of the arrowhead, drag any of the three boxes attached to the oversized arrow.  The arrows on the right give examples at normal scale.  The text at the bottom shows the configuration options as you'd enter them for a canvas line item.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$arrow_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $arrow_demo\n      $arrow_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'arrow'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$arrow_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# canvas \n$arrow_canvas = TkCanvas.new(base_frame, 'width'=>500, 'height'=>350, \n                             'relief'=>'sunken', 'borderwidth'=>2)\n$arrow_canvas.pack('expand'=>'yes', 'fill'=>'both')\n\n# \nunless Struct.const_defined?(\"ArrowInfo\")\n  $demo_arrowInfo = Struct.new(\"ArrowInfo\", :a, :b, :c, :width, :motionProc, \n                               :x1, :x2, :y, :smallTips, :count, \n                               :bigLineStyle, :boxStyle, :activeStyle).new\nend\n$demo_arrowInfo.a = 8\n$demo_arrowInfo.b = 10\n$demo_arrowInfo.c = 3\n$demo_arrowInfo.width = 2\n$demo_arrowInfo.motionProc = proc{}\n$demo_arrowInfo.x1 = 40\n$demo_arrowInfo.x2 = 350\n$demo_arrowInfo.y = 150\n$demo_arrowInfo.smallTips = [5, 5, 2]\n$demo_arrowInfo.count = 0\nif TkWinfo.depth($arrow_canvas) > 1\n  $demo_arrowInfo.bigLineStyle = {'fill'=>'SkyBlue1'}\n  $demo_arrowInfo.boxStyle = {'fill'=>'', 'outline'=>'black', 'width'=>1}\n  $demo_arrowInfo.activeStyle = {'fill'=>'red', 'outline'=>'black', 'width'=>1}\nelse\n  $demo_arrowInfo.bigLineStyle = {'fill'=>'black', \n    'stipple'=>'@'+[$demo_dir,'..','images','grey.25'].join(File::Separator)}\n  $demo_arrowInfo.boxStyle = {'fill'=>'', 'outline'=>'black', 'width'=>1}\n  $demo_arrowInfo.activeStyle = {'fill'=>'black','outline'=>'black','width'=>1}\nend\n$arrowTag_box = TkcTag.new($arrow_canvas)\narrowSetup $arrow_canvas\n$arrowTag_box.bind('Enter', proc{$arrow_canvas.itemconfigure('current', $demo_arrowInfo.activeStyle)})\n$arrowTag_box.bind('Leave', proc{$arrow_canvas.itemconfigure('current', $demo_arrowInfo.boxStyle)})\n$arrowTag_box.bind('B1-Enter', proc{})\n$arrowTag_box.bind('B1-Leave', proc{})\n$arrow_canvas.itembind('box1', '1', \n                       proc{$demo_arrowInfo.motionProc \\\n                         = proc{|x,y| arrowMove1 $arrow_canvas, x, y}})\n$arrow_canvas.itembind('box2', '1', \n                       proc{$demo_arrowInfo.motionProc \\\n                         = proc{|x,y| arrowMove2 $arrow_canvas, x, y}})\n$arrow_canvas.itembind('box3', '1', \n                       proc{$demo_arrowInfo.motionProc \\\n                         = proc{|x,y| arrowMove3 $arrow_canvas, x, y}})\n$arrowTag_box.bind('B1-Motion', \n                  proc{|x,y| $demo_arrowInfo.motionProc.call(x,y)}, \"%x %y\")\n$arrow_canvas.bind('Any-ButtonRelease-1', proc{arrowSetup $arrow_canvas})\n\n# arrowMove1 --\n# This method is called for each mouse motion event on box1 (the\n# one at the vertex of the arrow).  It updates the controlling parameters\n# for the line and arrowhead.\n#\n# Arguments:\n# c -           The name of the canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef arrowMove1(c,x,y)\n  v = $demo_arrowInfo\n  newA = (v.x2+5-c.canvasx(x).round)/10\n  newA = 0 if newA < 0\n  newA = 25 if newA > 25\n  if newA != v.a\n    c.move('box1', 10*(v.a-newA), 0)\n    v.a = newA\n  end\nend\n\n# arrowMove2 --\n# This method is called for each mouse motion event on box2 (the\n# one at the trailing tip of the arrowhead).  It updates the controlling\n# parameters for the line and arrowhead.\n#\n# Arguments:\n# c -           The name of the canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef arrowMove2(c,x,y)\n  v = $demo_arrowInfo\n  newB = (v.x2+5-c.canvasx(x).round)/10\n  newB = 0 if newB < 0\n  newB = 25 if newB > 25\n  newC = (v.y+5-c.canvasy(y).round-5*v.width)/10\n  newC = 0 if newC < 0\n  newC = 20 if newC > 20\n  if newB != v.b || newC != v.c\n    c.move('box2', 10*(v.b-newB), 10*(v.c-newC))\n    v.b = newB\n    v.c = newC\n  end\nend\n\n# arrowMove3 --\n# This method is called for each mouse motion event on box3 (the\n# one that controls the thickness of the line).  It updates the\n# controlling parameters for the line and arrowhead.\n#\n# Arguments:\n# c -           The name of the canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef arrowMove3(c,x,y)\n  v = $demo_arrowInfo\n  newWidth = (v.y+2-c.canvasy(y).round)/5\n  newWidth = 0 if newWidth < 0\n  newWidth = 20 if newWidth > 20\n  if newWidth != v.width\n    c.move('box3', 0, 5*(v.width-newWidth))\n    v.width = newWidth\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/bind.rb",
    "content": "# bind.rb\n#\n# This demonstration script creates a text widget with bindings set\n# up for hypertext-like effects.\n#\n# text (tag bindings) widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($bind_demo) && $bind_demo\n  $bind_demo.destroy \n  $bind_demo = nil\nend\n\n# demo toplevel widget\n$bind_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Tag Bindings\")\n  iconname(\"bind\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($bind_demo).pack(:fill=>:both, :expand=>true)\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $bind_demo\n      $bind_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'bind'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# bind \ndef tag_binding_for_bind_demo(tag, enter_style, leave_style)\n  tag.bind('Any-Enter', proc{tag.configure enter_style})\n  tag.bind('Any-Leave', proc{tag.configure leave_style})\nend\n\n# text \ntxt = TkText.new(base_frame){|t|\n  # \n  setgrid 'true'\n  #width  60\n  #height 24\n  font $font\n  wrap 'word'\n  TkScrollbar.new(base_frame) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    command proc{|*args| t.yview(*args)}\n    t.yscrollcommand proc{|first,last| s.set first,last}\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n\n  # \n  if TkWinfo.depth($root).to_i > 1\n    tagstyle_bold = {'background'=>'#43ce80', 'relief'=>'raised', \n                     'borderwidth'=>1}\n    tagstyle_normal = {'background'=>'', 'relief'=>'flat'}\n  else\n    tagstyle_bold = {'foreground'=>'white', 'background'=>'black'}\n    tagstyle_normal = {'foreground'=>'', 'background'=>''}\n  end\n\n  # insert text\n  insert 'insert', \"The same tag mechanism that controls display styles in text widgets can also be used to associate Tcl commands with regions of text, so that mouse or keyboard actions on the text cause particular Tcl commands to be invoked.  For example, in the text below the descriptions of the canvas demonstrations have been tagged.  When you move the mouse over a demo description the description lights up, and when you press button 1 over a description then that particular demonstration is invoked.\n\n\"\n  insert('end', '1. Samples of all the different types of items that can be created in canvas widgets.', (d1 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '2. A simple two-dimensional plot that allows you to adjust the positions of the data points.', (d2 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '3. Anchoring and justification modes for text items.', \n         (d3 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '4. An editor for arrow-head shapes for line items.', \n         (d4 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '5. A ruler with facilities for editing tab stops.', \n         (d5 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', \n         '6. A grid that demonstrates how canvases can be scrolled.', \n         (d6 = TkTextTag.new(t)) )\n\n  # binding\n  [d1, d2, d3, d4, d5, d6].each{|tag|\n    tag_binding_for_bind_demo(tag, tagstyle_bold, tagstyle_normal)\n  }\n  d1.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'items.rb'].join(File::Separator)}`, 'items.rb')\n          })\n  d2.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'plot.rb'].join(File::Separator)}`, 'plot.rb')\n          })\n  d3.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'ctext.rb'].join(File::Separator)}`, 'ctext.rb')\n          })\n  d4.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'arrow.rb'].join(File::Separator)}`, 'arrow.rb')\n          })\n  d5.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'ruler.rb'].join(File::Separator)}`, 'ruler.rb')\n          })\n  d6.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'cscroll.rb'].join(File::Separator)}`, 'cscroll.rb')\n          })\n\n  TkTextMarkInsert.new(t, '0.0')\n  configure('state','disabled')\n}\n\ntxt.width  60\ntxt.height 24\n"
  },
  {
    "path": "ext/tk/sample/demos-en/bitmap.rb",
    "content": "# bitmap.rb\n#\n# This demonstration script creates a toplevel window that displays\n# all of Tk's built-in bitmaps.#\n# bitmap widget demo (called by 'widget')\n#\n\n# bitmapRow --\n# Create a row of bitmap items in a window.\n#\n# Arguments:\n# w -           The parent window that is to contain the row.\n# args -        The names of one or more bitmaps, which will be displayed\n#               in a new row across the bottom of w along with their\n#               names.\n\ndef bitmapRow(w,*args)\n  TkFrame.new(w){|row|\n    pack('side'=>'top', 'fill'=>'both')\n    for bitmap in args \n      TkFrame.new(row){|base|\n        pack('side'=>'left', 'fill'=>'both', 'pady'=>'.25c', 'padx'=>'.25c')\n        TkLabel.new(base, 'text'=>bitmap, 'width'=>9).pack('side'=>'bottom')\n        Tk::Label.new(base, 'bitmap'=>bitmap).pack('side'=>'bottom')\n      }\n    end\n  }\nend\n\n# toplevel widget\nif defined?($bitmap_demo) && $bitmap_demo\n  $bitmap_demo.destroy \n  $bitmap_demo = nil\nend\n\n# demo toplevel widget\n$bitmap_demo = TkToplevel.new {|w|\n  title(\"Bitmap Demonstration\")\n  iconname(\"bitmap\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($bitmap_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left', \n            'text'=>\"This window displays all of Tk's built-in bitmaps, along with the names you can use for them in Tcl scripts.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$bitmap_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $bitmap_demo\n      $bitmap_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'bitmap'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$bitmap_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nTkFrame.new(base_frame){|f|\n  bitmapRow(f,'error','gray25','gray50','hourglass')\n  bitmapRow(f,'info','question','questhead','warning')\n  pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both')\n}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/browse1",
    "content": "#!/usr/bin/env ruby\n\n# browse --\n# This script generates a directory browser, which lists the working \n# directory and allow you to open files or subdirectories by \n# double-clicking. \n\nrequire 'tk'\n\n# Create a scrollbar on the right side of the main window and a listbox \n# on the left side.\n\nlistbox = TkListbox.new(nil, 'relief'=>'sunken', \n\t\t\t'width'=>20, 'height'=>20, 'setgrid'=>'yes') {|l|\n  TkScrollbar.new(nil, 'command'=>proc{|*args| l.yview *args}) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    l.yscrollcommand(proc{|first,last| s.set(first,last)})\n  }\n\n  pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n}\n\nroot = TkRoot.new\nroot.minsize(1,1)\n\n# The procedure below is invoked to open a browser on a given file;  if the \n# file is a directory then another instance of this program is invoked; if \n# the file is a regular file then the Mx editor is invoked to display \n# the file. \n\ndef browse (dir, file)\n  file = dir + File::Separator + file if dir != '.'\n  type = File.ftype(file)\n  if type == 'directory'\n    system($0 + ' ' + file + ' &')\n  else\n    if type == 'file'\n      if ENV['EDITOR']\n\tsystem(ENV['EDITOR'] + ' ' + file + ' &')\n      else\n\tsystem('xedit ' + file + ' &')\n      end\n    else\n      STDOUT.print \"\\\"#{file}\\\" isn't a directory or regular file\"\n    end\n  end\nend\n\n# Fill the listbox with a list of all the files in the directory (run \n# the \"ls\" command to get that information).\n\ndir = ARGV[0] ?  ARGV[0] : '.'\nopen(\"|ls -a #{dir}\", 'r'){|fid| fid.readlines}.each{|fname|\n  listbox.insert('end', fname.chomp)\n}\n\n# Set up bindings for the browser.\n\nTk.bind_all('Control-c', proc{root.destroy})\nlistbox.bind('Double-Button-1', \n\t     proc{TkSelection.get.each{|f| browse dir, f}})\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/browse2",
    "content": "#!/usr/bin/env ruby\n\n# browse --\n# This script generates a directory browser, which lists the working \n# directory and allow you to open files or subdirectories by \n# double-clicking. \n\nrequire 'tk'\n\nclass Browse\n  BROWSE_WIN_COUNTER = TkVariable.new(0)\n\n  def initialize(dir)\n    BROWSE_WIN_COUNTER.value = BROWSE_WIN_COUNTER.to_i + 1\n\n    # create base frame\n    base = TkToplevel.new {\n      minsize(1,1)\n      title('Browse : ' + dir)\n    }\n\n    # Create a scrollbar on the right side of the main window and a listbox \n    # on the left side.\n    list = TkListbox.new(base, 'relief'=>'sunken', \n\t\t\t 'width'=>20, 'height'=>20, 'setgrid'=>'yes') {|l|\n      TkScrollbar.new(base, 'command'=>proc{|*args| l.yview *args}) {|s|\n\tpack('side'=>'right', 'fill'=>'y')\n\tl.yscrollcommand(proc{|first,last| s.set(first,last)})\n      }\n\n      pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n\n      # Fill the listbox with a list of all the files in the directory (run \n      # the \"ls\" command to get that information).\n      open(\"|ls -a #{dir}\", 'r'){|fid| fid.readlines}.each{|fname|\n\tl.insert('end', fname.chomp)\n      }\n\n    }\n\n    # Set up bindings for the browser.\n    base.bind('Destroy', proc{\n\t\tBrowse::BROWSE_WIN_COUNTER.value = \\\n\t\t                Browse::BROWSE_WIN_COUNTER.to_i - 1\n\t      })\n    base.bind('Control-c', proc{base.destroy})\n    list.bind('Double-Button-1', \n\t proc{TkSelection.get.each{|f| self.browse dir, f}})\n  end\n\n  # The method below is invoked to open a browser on a given file;  if the \n  # file is a directory then another instance of this program is invoked; if \n  # the file is a regular file then the Mx editor is invoked to display \n  # the file. \n  def browse (dir, file)\n    file = dir + File::Separator + file if dir != '.'\n    type = File.ftype(file)\n    if type == 'directory'\n      Browse.new(file)\n    else\n      if type == 'file'\n\tif ENV['EDITOR']\n\t  system(ENV['EDITOR'] + ' ' + file + ' &')\n\telse\n\t  system('xedit ' + file + ' &')\n\tend\n      else\n\tSTDOUT.print \"\\\"#{file}\\\" isn't a directory or regular file\"\n      end\n    end\n  end\n\nend\n\nBrowse.new(ARGV[0] ? ARGV[0] : '.')\n\nTkRoot.new {\n  withdraw\n  Browse::BROWSE_WIN_COUNTER.trace('w', proc{exit if Browse::BROWSE_WIN_COUNTER.to_i == 0})\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/button.rb",
    "content": "# button.rb\n#\n# This demonstration script creates a toplevel window containing\n# several button widgets.\n#\n# button widget demo (called by 'widget')\n#\n\n# toplevel widget \nif defined?($button_demo) && $button_demo\n  $button_demo.destroy \n  $button_demo = nil\nend\n\n# demo toplevel widget \n$button_demo = TkToplevel.new {|w|\n  title(\"Button Demonstration\")\n  iconname(\"button\")\n  positionWindow(w)\n}\n\n# label \nmsg = TkLabel.new($button_demo) {\n  font $kanji_font\n  wraplength '4i'\n  justify 'left'\n  text \"If you click on any of the four buttons below, the background of the button area will change to the color indicated in the button.  You can press Tab to move among the buttons, then press Space to invoke the current button.\"\n}\nmsg.pack('side'=>'top')\n\n# frame \n$button_buttons = Tk::Frame.new($button_demo) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $button_demo\n      $button_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Code'\n    command proc{showCode 'button'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# button\nTkButton.new($button_demo){\n  text \"Peach Puff\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','PeachPuff1')\n    $button_buttons.configure('bg','PeachPuff1')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n\nTkButton.new($button_demo){\n  text \"Light Blue\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','LightBlue1')\n    $button_buttons.configure('bg','LightBlue1')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n\nTkButton.new($button_demo){\n  text \"Sea Green\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','SeaGreen2')\n    $button_buttons.configure('bg','SeaGreen2')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n\nTkButton.new($button_demo){\n  text \"Yellow\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','Yellow1')\n    $button_buttons.configure('bg','Yellow1')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/check.rb",
    "content": "# check.rb\n#\n# This demonstration script creates a toplevel window containing\n# several checkbuttons.\n#\n# checkbutton widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($check_demo) && $check_demo\n  $check_demo.destroy \n  $check_demo = nil\nend\n\n# demo toplevel widget\n$check_demo = TkToplevel.new {|w|\n  title(\"Checkbutton Demonstration\")\n  iconname(\"check\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($check_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"Three checkbuttons are displayed below.  If you click on a button, it will toggle the button's selection state and set a Tcl variable to a value indicating the state of the checkbutton.  Click the \\\"See Variables\\\" button to see the current values of the variables.\"\n}\nmsg.pack('side'=>'top')\n\n# \nwipers = TkVariable.new(0)\nbrakes = TkVariable.new(0)\nsober  = TkVariable.new(0)\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $check_demo\n      $check_demo = nil\n      $showVarsWin[tmppath.path] = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'check'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n\n  TkButton.new(frame) {\n    text 'See Variables'\n    command proc{\n      showVars(base_frame, \n               ['wipers', wipers], ['brakes', brakes], ['sober', sober])\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n\n# checkbutton\n[ TkCheckButton.new(base_frame, 'text'=>'Wipers  OK', 'variable'=>wipers),\n  TkCheckButton.new(base_frame, 'text'=>'Brakes  OK', 'variable'=>brakes),\n  TkCheckButton.new(base_frame, 'text'=>'Driver Sober', 'variable'=>sober)\n].each{|w| w.relief('flat'); w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/check2.rb",
    "content": "#\n# checkbutton widget demo2 (called by 'widget')\n#\n\n# delete old toplevel widget\nif defined?($check2_demo) && $check2_demo\n  $check2_demo.destroy \n  $check2_demo = nil\nend\n\n# create demo toplevel widget\n$check2_demo = TkToplevel.new {|w|\n  title(\"Checkbutton Demonstration 2\")\n  iconname(\"check2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($check2_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"Four checkbuttons are displayed below.  If you click on a button, it will toggle the button's selection state and set a Tcl variable to a value indicating the state of the checkbutton.  The first button also follows the state of the other three.  If only some of the three are checked, the first button will display the tri-state mode. Click the \\\"See Variables\\\" button to see the current values of the variables.\"\n}\nmsg.pack('side'=>'top')\n\n# variable\nsafety = TkVariable.new(0)\nwipers = TkVariable.new(0)\nbrakes = TkVariable.new(0)\nsober  = TkVariable.new(0)\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), \n         :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         TkButton.new(frame, :text=>'See Variables', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{\n                        showVars($check2_demo, \n                                 ['safety', safety], ['wipers', wipers], \n                                 ['brakes', brakes], ['sober', sober])\n                      }), \n         TkButton.new(frame, :text=>'See Code', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{showCode 'check2'}), \n         TkButton.new(frame, :text=>'Dismiss', \n                      :image=>$image['delete'], :compound=>:left, \n                      :command=>proc{\n                        tmppath = $check2_demo\n                        $check2_demo = nil\n                        $showVarsWin[tmppath.path] = nil\n                        tmppath.destroy\n                      }), \n         :padx=>4, :pady=>4)\n  frame.grid_columnconfigure(0, :weight=>1)\n}.pack('side'=>'bottom', 'fill'=>'x')\n\n\n# checkbutton\nTkCheckButton.new(base_frame, :text=>'Safety Check', :variable=>safety, \n                  :relief=>:flat, :onvalue=>'all', :offvalue=>'none', \n                  :tristatevalue=>'partial'){\n  pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')\n}\n\n[ TkCheckButton.new(base_frame, 'text'=>'Wipers OK', 'variable'=>wipers),\n  TkCheckButton.new(base_frame, 'text'=>'Brakes OK', 'variable'=>brakes),\n  TkCheckButton.new(base_frame, 'text'=>'Driver Sober', 'variable'=>sober)\n].each{|w| \n  w.relief('flat')\n  w.pack('side'=>'top', 'padx'=>15, 'pady'=>2, 'anchor'=>'w')\n}\n\n# tristate check\nin_check = false\ntristate_check = proc{|n1,n2,op|\n  unless in_check\n    in_check = true\n    begin\n      if n1 == safety\n        if safety == 'none'\n          wipers.value = 0\n          brakes.value = 0\n          sober.value  = 0\n        elsif safety == 'all'\n          wipers.value = 1\n          brakes.value = 1\n          sober.value  = 1\n        end\n      else\n        if wipers == 1 && brakes == 1 && sober == 1\n          safety.value = 'all'\n        elsif wipers == 1 || brakes == 1 || sober == 1\n          safety.value = 'partial'\n        else\n          safety.value = 'none'\n        end\n      end\n    ensure\n      in_check = false\n    end\n  end\n}\n\n[wipers, brakes, sober, safety].each{|v| v.trace('w', tristate_check)}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/clrpick.rb",
    "content": "# clrpick.rb\n#\n# This demonstration script prompts the user to select a color.\n#\n# widget demo prompts the user to select a color (called by 'widget')\n#\n#  Note: don't support ttk_wrapper. work with standard widgets only.\n#\n\n# toplevel widget\nif defined?($clrpick_demo) && $clrpick_demo\n  $clrpick_demo.destroy \n  $clrpick_demo = nil\nend\n\n# demo toplevel widget\n$clrpick_demo = TkToplevel.new {|w|\n  title(\"Color Selection Dialogs\")\n  iconname(\"colors\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($clrpick_demo).pack(:fill=>:both, :expand=>true)\n\n# label\n#TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left',\nTk::Label.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left',\n            'text'=>\"Press the buttons below to choose the foreground and background colors for the widgets in this window.\").pack('side'=>'top')\n\n# frame\n#TkFrame.new($clrpick_demo) {|frame|\nTk::Frame.new($clrpick_demo) {|frame|\n  # TkButton.new(frame) {\n  Tk::Button.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $clrpick_demo\n      $clrpick_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  # TkButton.new(frame) {\n  Tk::Button.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'clrpick'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# button \n# TkButton.new($clrpick_demo, 'text'=>'Set background color ...') {|b|\nTk::Button.new($clrpick_demo, 'text'=>'Set background color ...') {|b|\n  command(proc{setColor $clrpick_demo, b, 'background', \n              ['background', 'highlightbackground']})\n  pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m')\n}\n\n# TkButton.new($clrpick_demo, 'text'=>'Set foreground color ...') {|b|\nTk::Button.new($clrpick_demo, 'text'=>'Set foreground color ...') {|b|\n  command(proc{setColor $clrpick_demo, b, 'foreground', ['foreground']})\n  pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m')\n}\n\ndef setColor(w,button,name,options)\n  w.grab\n  initialColor = button[name]\n  color = Tk.chooseColor('title'=>\"Choose a #{name} color\", 'parent'=>w, \n                         'initialcolor'=>initialColor)\n  if color != \"\"\n    setColor_helper(w,options,color)\n  end\n\n  w.grab('release')\nend\n\ndef setColor_helper(w, options, color)\n  options.each{|opt|\n    begin\n      w[opt] = color\n    rescue\n    end\n  }\n  TkWinfo.children(w).each{|child|\n    setColor_helper child, options, color\n  }\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/colors.rb",
    "content": "# colors.rb\n#\n# This demonstration script creates a listbox widget that displays\n# many of the colors from the X color database.  You can click on\n# a color to change the application's palette.\n#\n# listbox widget demo 'colors' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($colors_demo) && $colors_demo\n  $colors_demo.destroy \n  $colors_demo = nil\nend\n\n# demo toplevel widget\n$colors_demo = TkToplevel.new {|w|\n  title(\"Listbox Demonstration (colors)\")\n  iconname(\"colors\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($colors_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"A listbox containing several color names is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by dragging in the listbox window with button 2 pressed.  If you double-click button 1 on a color, then the application's color palette will be set to match that color\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $colors_demo\n      $colors_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'colors'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\ncolors_lbox = nil\nTkFrame.new(base_frame, 'borderwidth'=>10) {|w|\n  s = TkScrollbar.new(w)\n  colors_lbox = TkListbox.new(w) {\n    setgrid 1\n    width  10\n    height 12\n    yscrollcommand proc{|first,last| s.set first,last}\n  }\n  s.command(proc{|*args| colors_lbox.yview(*args)})\n  s.pack('side'=>'right', 'fill'=>'y')\n  colors_lbox.pack('side'=>'left', 'expand'=>1, 'fill'=>'both')\n}.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y')\n\n#colors_lbox.bind('Double-1', proc{TkPalette.setPalette TkSelection.get})\ncolors_lbox.bind('Double-1', proc{\n                   begin\n                     TkPalette.setPalette TkSelection.get\n                   rescue => e\n                     p e\n                     Tk.tk_call_without_enc('destroy', '.___tk_set_palette')\n                   end\n                 })\n\nins_data = [\n  'gray60','gray70','gray80','gray85','gray90','gray95',\n  'snow1','snow2','snow3','snow4','seashell1','seashell2',\n  'seashell3','seashell4','AntiqueWhite1','AntiqueWhite2',\n  'AntiqueWhite3','AntiqueWhite4','bisque1','bisque2',\n  'bisque3','bisque4','PeachPuff1','PeachPuff2',\n  'PeachPuff3','PeachPuff4','NavajoWhite1','NavajoWhite2',\n  'NavajoWhite3','NavajoWhite4','LemonChiffon1',\n  'LemonChiffon2','LemonChiffon3','LemonChiffon4',\n  'cornsilk1','cornsilk2','cornsilk3','cornsilk4',\n  'ivory1','ivory2','ivory3','ivory4','honeydew1',\n  'honeydew2','honeydew3','honeydew4','LavenderBlush1',\n  'LavenderBlush2','LavenderBlush3','LavenderBlush4',\n  'MistyRose1','MistyRose2','MistyRose3','MistyRose4',\n  'azure1','azure2','azure3','azure4','SlateBlue1',\n  'SlateBlue2','SlateBlue3','SlateBlue4','RoyalBlue1',\n  'RoyalBlue2','RoyalBlue3','RoyalBlue4','blue1','blue2',\n  'blue3','blue4','DodgerBlue1','DodgerBlue2',\n  'DodgerBlue3','DodgerBlue4','SteelBlue1','SteelBlue2',\n  'SteelBlue3','SteelBlue4','DeepSkyBlue1','DeepSkyBlue2',\n  'DeepSkyBlue3','DeepSkyBlue4','SkyBlue1','SkyBlue2',\n  'SkyBlue3','SkyBlue4','LightSkyBlue1','LightSkyBlue2',\n  'LightSkyBlue3','LightSkyBlue4','SlateGray1',\n  'SlateGray2','SlateGray3','SlateGray4',\n  'LightSteelBlue1','LightSteelBlue2','LightSteelBlue3',\n  'LightSteelBlue4','LightBlue1','LightBlue2',\n  'LightBlue3','LightBlue4','LightCyan1','LightCyan2',\n  'LightCyan3','LightCyan4','PaleTurquoise1',\n  'PaleTurquoise2','PaleTurquoise3','PaleTurquoise4',\n  'CadetBlue1','CadetBlue2','CadetBlue3','CadetBlue4',\n  'turquoise1','turquoise2','turquoise3','turquoise4',\n  'cyan1','cyan2','cyan3','cyan4','DarkSlateGray1',\n  'DarkSlateGray2','DarkSlateGray3','DarkSlateGray4',\n  'aquamarine1','aquamarine2','aquamarine3','aquamarine4',\n  'DarkSeaGreen1','DarkSeaGreen2','DarkSeaGreen3',\n  'DarkSeaGreen4','SeaGreen1','SeaGreen2','SeaGreen3',\n  'SeaGreen4','PaleGreen1','PaleGreen2','PaleGreen3',\n  'PaleGreen4','SpringGreen1','SpringGreen2',\n  'SpringGreen3','SpringGreen4','green1','green2',\n  'green3','green4','chartreuse1','chartreuse2',\n  'chartreuse3','chartreuse4','OliveDrab1','OliveDrab2',\n  'OliveDrab3','OliveDrab4','DarkOliveGreen1',\n  'DarkOliveGreen2','DarkOliveGreen3','DarkOliveGreen4',\n  'khaki1','khaki2','khaki3','khaki4','LightGoldenrod1',\n  'LightGoldenrod2','LightGoldenrod3','LightGoldenrod4',\n  'LightYellow1','LightYellow2','LightYellow3',\n  'LightYellow4','yellow1','yellow2','yellow3','yellow4',\n  'gold1','gold2','gold3','gold4','goldenrod1',\n  'goldenrod2','goldenrod3','goldenrod4','DarkGoldenrod1',\n  'DarkGoldenrod2','DarkGoldenrod3','DarkGoldenrod4',\n  'RosyBrown1','RosyBrown2','RosyBrown3','RosyBrown4',\n  'IndianRed1','IndianRed2','IndianRed3','IndianRed4',\n  'sienna1','sienna2','sienna3','sienna4','burlywood1',\n  'burlywood2','burlywood3','burlywood4','wheat1',\n  'wheat2','wheat3','wheat4','tan1','tan2','tan3','tan4',\n  'chocolate1','chocolate2','chocolate3','chocolate4',\n  'firebrick1','firebrick2','firebrick3','firebrick4',\n  'brown1','brown2','brown3','brown4','salmon1','salmon2',\n  'salmon3','salmon4','LightSalmon1','LightSalmon2',\n  'LightSalmon3','LightSalmon4','orange1','orange2',\n  'orange3','orange4','DarkOrange1','DarkOrange2',\n  'DarkOrange3','DarkOrange4','coral1','coral2','coral3',\n  'coral4','tomato1','tomato2','tomato3','tomato4',\n  'OrangeRed1','OrangeRed2','OrangeRed3','OrangeRed4',\n  'red1','red2','red3','red4','DeepPink1','DeepPink2',\n  'DeepPink3','DeepPink4','HotPink1','HotPink2',\n  'HotPink3','HotPink4','pink1','pink2','pink3','pink4',\n  'LightPink1','LightPink2','LightPink3','LightPink4',\n  'PaleVioletRed1','PaleVioletRed2','PaleVioletRed3',\n  'PaleVioletRed4','maroon1','maroon2','maroon3',\n  'maroon4','VioletRed1','VioletRed2','VioletRed3',\n  'VioletRed4','magenta1','magenta2','magenta3',\n  'magenta4','orchid1','orchid2','orchid3','orchid4',\n  'plum1','plum2','plum3','plum4','MediumOrchid1',\n  'MediumOrchid2','MediumOrchid3','MediumOrchid4',\n  'DarkOrchid1','DarkOrchid2','DarkOrchid3',\n  'DarkOrchid4','purple1','purple2','purple3','purple4',\n  'MediumPurple1','MediumPurple2','MediumPurple3',\n  'MediumPurple4','thistle1','thistle2','thistle3', 'thistle4'\n]\n\ncolors_lbox.insert(0, *ins_data)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/combo.rb",
    "content": "# combo.rb --\n#\n# This demonstration script creates several combobox widgets.\n#\n# based on \"Id: combo.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($combo_demo) && $combo_demo\n  $combo_demo.destroy \n  $combo_demo = nil\nend\n\n$combo_demo = TkToplevel.new {|w|\n  title(\"Combobox Demonstration\")\n  iconname(\"combo\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($combo_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nThree different combo-boxes are displayed below. \\\nYou can add characters to the first \\\none by pointing, clicking and typing, just as with an entry; pressing \\\nReturn will cause the current value to be added to the list that is \\\nselectable from the drop-down list, and you can choose other values \\\nby pressing the Down key, using the arrow keys to pick another one, \\\nand pressing Return again. The second combo-box is fixed to a \\\nparticular value, and cannot be modified at all. The third one only \\\nallows you to select values from its drop-down list of Australian \\\ncities.\nEOL\n\n## variables\nfirstValue  = TkVariable.new\nsecondValue = TkVariable.new\nozCity      = TkVariable.new\n\n## See Code / Dismiss buttons\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Variables', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{\n                           showVars(base_frame, \n                                    ['firstVariable', firstValue], \n                                    ['secondVariable', secondValue], \n                                    ['ozCity', ozCity])\n                         }), \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'combo'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $combo_demo.destroy\n                           $combo_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nframe = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\naustralianCities = [\n  'Canberra', 'Sydney', 'Melbourne', 'Perth', 'Adelaide', 'Brisbane', \n  'Hobart', 'Darwin', 'Alice Springs'\n]\n\n\nsecondValue.value = 'unchangable'\nozCity.value = 'Sydney'\n\nTk.pack(Ttk::Labelframe.new(frame, :text=>'Fully Editable'){|f|\n          Ttk::Combobox.new(f, :textvariable=>firstValue){|b|\n            b.bind('Return', '%W'){|w|\n              w.values <<= w.value unless w.values.include?(w.value)\n            }\n          }.pack(:pady=>5, :padx=>10)\n        }, \n\n        Ttk::LabelFrame.new(frame, :text=>'Disabled'){|f|\n          Ttk::Combobox.new(f, :textvariable=>secondValue, :state=>:disabled) .\n            pack(:pady=>5, :padx=>10)\n        }, \n\n        Ttk::LabelFrame.new(frame, :text=>'Defined List Only'){|f|\n          Ttk::Combobox.new(f, :textvariable=>ozCity, :state=>:readonly, \n                            :values=>australianCities) .\n            pack(:pady=>5, :padx=>10)\n        }, \n\n        :side=>:top, :pady=>5, :padx=>10)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/cscroll.rb",
    "content": "# cscroll.rb\n#\n# This demonstration script creates a simple canvas that can be\n# scrolled in two dimensions.\n#\n# simple scrollable canvas widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($cscroll_demo) && $cscroll_demo\n  $cscroll_demo.destroy \n  $cscroll_demo = nil\nend\n\n# demo toplevel widget\n$cscroll_demo = TkToplevel.new {|w|\n  title(\"Scrollable Canvas Demonstration\")\n  iconname(\"cscroll\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($cscroll_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', \n            'justify'=>'left', 'text'=>\"This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with button 2 in the canvas.  If you click button 1 on one of the rectangles, its indices will be printed on stdout.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$cscroll_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $cscroll_demo\n      $cscroll_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'cscroll'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$cscroll_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nunless $tk_version =~ /^4\\.[01]/\n  $cscroll_grid = TkFrame.new(base_frame) {\n    pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n  }\n  TkGrid.rowconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0)\n  TkGrid.columnconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0)\nend\n\n# canvas\n$cscroll_canvas = TkCanvas.new(base_frame, \n                               'relief'=>'sunken', 'borderwidth'=>2,\n                               'scrollregion'=>['-11c', '-11c', '50c', '20c']\n                               ) {|c|\n  if $tk_version =~ /^4\\.[01]/\n    pack('expand'=>'yes', 'fill'=>'both') \n  else\n    grid('in'=>$cscroll_grid, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n         'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n  end\n\n  TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}) {|vs|\n    c.yscrollcommand(proc{|first,last| vs.set first,last})\n    if $tk_version =~ /^4\\.[01]/\n      pack('side'=>'right', 'fill'=>'y')\n    else\n      grid('in'=>$cscroll_grid, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    end\n  }\n\n  TkScrollbar.new(base_frame, 'orient'=>'horiz', \n                  'command'=>proc{|*args| c.xview(*args)}) {|hs|\n    c.xscrollcommand(proc{|first,last| hs.set first,last})\n    if $tk_version =~ /^4\\.[01]/\n      pack('side'=>'bottom', 'fill'=>'x') \n    else\n      grid('in'=>$cscroll_grid, 'padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    end\n  }\n}\n\nbg = $cscroll_canvas.configinfo('bg')[4]\n(0..19).each{|i|\n  x = -10+3*i\n  y = -10\n  (0..9).each{|j|\n    TkcRectangle.new($cscroll_canvas, \"#{x}c\", \"#{y}c\", \"#{x+2}c\", \"#{y+2}c\", \n                     'outline'=>'black', 'fill'=>bg, 'tags'=>'rect')\n    TkcText.new($cscroll_canvas, \"#{x+1}c\", \"#{y+1}c\", \n                'text'=>\"#{i},#{j}\", 'anchor'=>'center', 'tags'=>'text')\n    y += 3\n  }\n}\n\n$cscroll_canvas.itembind('all', 'Any-Enter', proc{scrollEnter $cscroll_canvas})\n$cscroll_canvas.itembind('all', 'Any-Leave', proc{scrollLeave $cscroll_canvas})\n$cscroll_canvas.itembind('all', '1', proc{scrollButton $cscroll_canvas})\n$cscroll_canvas.itembind('all', 'Any-Enter', proc{scrollEnter $cscroll_canvas})\n$cscroll_canvas.bind('2', proc{|x,y| $cscroll_canvas.scan_mark(x,y)}, '%x %y')\n$cscroll_canvas.bind('B2-Motion', \n                     proc{|x,y| $cscroll_canvas.scan_dragto(x,y)}, '%x %y')\n\ndef scrollEnter(c)\n  id = c.find_withtag('current')[0].id\n  id -= 1 if c.gettags('current').include?('text')\n  $oldFill = c.itemconfiginfo(id, 'fill')[4]\n  if TkWinfo.depth(c) > 1\n    c.itemconfigure(id, 'fill'=>'SeaGreen1')\n  else\n    c.itemconfigure(id, 'fill'=>'black')\n    c.itemconfigure(id+1, 'fill'=>'white')\n  end\nend\n\ndef scrollLeave(c)\n  id = c.find_withtag('current')[0].id\n  id -= 1 if c.gettags('current').include?('text')\n  c.itemconfigure(id, 'fill'=>$oldFill)\n  c.itemconfigure(id+1, 'fill'=>'black')\nend\n\ndef scrollButton(c)\n  id = c.find_withtag('current')[0].id\n  id += 1 unless c.gettags('current').include?('text')\n  print \"You buttoned at #{c.itemconfiginfo(id,'text')[4]}\\n\"\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ctext.rb",
    "content": "# ctext.rb\n#\n# This demonstration script creates a canvas widget with a text\n# item that can be edited and reconfigured in various ways.\n#\n# Canvas Text widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($ctext_demo) && $ctext_demo\n  $ctext_demo.destroy \n  $ctext_demo = nil\nend\n\n# demo toplevel widget\n$ctext_demo = TkToplevel.new {|w|\n  title(\"Canvas Text Demonstration\")\n  iconname(\"Text\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ctext_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', \n            'text'=>\"This window displays a string of text to demonstrate the text facilities of canvas widgets.  You can click in the boxes to adjust the position of the text relative to its positioning point or change its justification.  The text also supports the following simple bindings for editing:\n  1. You can point, click, and type.\n  2. You can also select with button 1.\n  3. You can copy the selection to the mouse position with button 2.\n  4. Backspace and Control+h delete the selection if there is one;\n     otherwise they delete the character just before the insertion cursor.\n  5. Delete deletes the selection if there is one; otherwise it deletes\n     the character just after the insertion cursor.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$ctext_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $ctext_demo\n      $ctext_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'ctext'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$ctext_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# canvas \n$ctext_canvas = TkCanvas.new(base_frame, 'relief'=>'flat', \n                             'borderwidth'=>0, 'width'=>500, 'height'=>350)\n$ctext_canvas.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both')\n\n# font \nif $tk_version =~ /^4.*/\n  textFont = '-*-Helvetica-Medium-R-Normal--*-240-*-*-*-*-*-*'\nelse\n  textFont = 'Helvetica 24'\nend\n\n# canvas \nTkcRectangle.new($ctext_canvas, 245, 195, 255, 205, \n                 'outline'=>'black', 'fill'=>'red')\n\nctag_text_param = {\n  'text'=>\"This is just a string of text to demonstrate the text facilities of canvas widgets. Bindings have been been defined to support editing (see above).\",\n  'width'=>440, 'anchor'=>'n', 'justify'=>'left'\n}\nif $tk_version =~ /^4.*/\n  ctag_text_param['font'] = '-*-Helvetica-Medium-R-Normal--*-240-*-*-*-*-*-*'\nelse\n  ctag_text_param['font'] = 'Helvetica 24'\nend\n\n$ctag_text = TkcTag.new($ctext_canvas)\n$ctag_text.withtag(TkcText.new($ctext_canvas, 250, 200, ctag_text_param))\n\n$ctag_text.bind('1', proc{|x,y| textB1Press $ctext_canvas,x,y}, \"%x %y\")\n$ctag_text.bind('B1-Motion', proc{|x,y| textB1Move $ctext_canvas,x,y}, \"%x %y\")\n$ctag_text.bind('Shift-1', \n        proc{|x,y| $ctext_canvas.seleect_adjust 'current', \"@#{x},#{y}\"}, \n        \"%x %y\")\n$ctag_text.bind('Shift-B1-Motion', \n                proc{|x,y| textB1Move $ctext_canvas,x,y}, \"%x %y\")\n$ctag_text.bind('KeyPress', proc{|a| textInsert $ctext_canvas,a}, \"%A\")\n$ctag_text.bind('Return', proc{textInsert $ctext_canvas,\"\\n\"})\n$ctag_text.bind('Control-h', proc{textBs $ctext_canvas})\n$ctag_text.bind('BackSpace', proc{textBs $ctext_canvas})\n$ctag_text.bind('Delete', proc{textDel $ctext_canvas})\n$ctag_text.bind('2', proc{|x,y| textPaste $ctext_canvas, \"@#{x},#{y}\"}, \n                \"%x %y\")\n\n# Next, create some items that allow the text's anchor position \n# to be edited.\n\ndef mkTextConfig(w,x,y,option,value,color)\n  item = TkcRectangle.new(w, x, y, x+30, y+30, \n                          'outline'=>'black', 'fill'=>color, 'width'=>1)\n  item.bind('1', proc{$ctag_text.configure option, value})\n  w.addtag_withtag('config', item)\nend\n\nx = 50\ny = 50\ncolor = 'LightSkyBlue1'\nmkTextConfig $ctext_canvas, x, y, 'anchor', 'se', color\nmkTextConfig $ctext_canvas, x+30, y, 'anchor', 's', color\nmkTextConfig $ctext_canvas, x+60, y, 'anchor', 'sw', color\nmkTextConfig $ctext_canvas, x, y+30, 'anchor', 'e', color\nmkTextConfig $ctext_canvas, x+30, y+30, 'anchor', 'center', color\nmkTextConfig $ctext_canvas, x+60, y+30, 'anchor', 'w', color\nmkTextConfig $ctext_canvas, x, y+60, 'anchor', 'ne', color\nmkTextConfig $ctext_canvas, x+30, y+60, 'anchor', 'n', color\nmkTextConfig $ctext_canvas, x+60, y+60, 'anchor', 'nw', color\nitem = TkcRectangle.new($ctext_canvas, x+40, y+40, x+50, y+50, \n                        'outline'=>'black', 'fill'=>'red')\nitem.bind('1', proc{$ctag_text.configure 'anchor', 'center'})\nif $tk_version =~ /^4.*/\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Text Position', \n              'font'=>'-*-times-medium-r-normal--*-240-*-*-*-*-*-*', \n              'anchor'=>'s', 'fill'=>'brown')\nelse\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Text Position', \n              'font'=>'Times 24', 'anchor'=>'s', 'fill'=>'brown')\nend\n\n# Lastly, create some items that allow the text's justification to be\n# changed.\n\nx = 350\ny = 50\ncolor = 'SeaGreen2'\nmkTextConfig $ctext_canvas, x, y, 'justify', 'left', color\nmkTextConfig $ctext_canvas, x+30, y, 'justify', 'center', color\nmkTextConfig $ctext_canvas, x+60, y, 'justify', 'right', color\nif $tk_version =~ /^4.*/\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Justification', \n              'font'=>'-*-times-medium-r-normal--*-240-*-*-*-*-*-*', \n              'anchor'=>'s', 'fill'=>'brown')\nelse\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Justification', \n              'font'=>'Times 24', 'anchor'=>'s', 'fill'=>'brown')\nend\n\n$ctext_canvas.itembind('config', 'Enter', proc{textEnter $ctext_canvas})\n$ctext_canvas.itembind('config', 'Leave', \n                       proc{$ctext_canvas\\\n                             .itemconfigure('current', \n                                            'fill'=>$textConfigFill)})\n\n$textConfigFill = ''\n\ndef textEnter(w)\n  $textConfigFill = (w.itemconfiginfo 'current', 'fill')[4]\n  w.itemconfigure 'current', 'fill', 'black'\nend\n\ndef textInsert(w, string)\n  return if string == \"\"\n  begin\n    $ctag_text.dchars 'sel.first', 'sel.last'\n  rescue\n  end\n  $ctag_text.insert 'insert', string\nend\n\ndef textPaste(w, pos)\n  begin\n    $ctag_text.insert pos, TkSelection.get\n  rescue\n  end\nend\n\ndef textB1Press(w,x,y)\n  w.icursor 'current', \"@#{x},#{y}\"\n  w.itemfocus 'current'\n  w.focus\n  w.select_from 'current', \"@#{x},#{y}\"\nend\n\ndef textB1Move(w,x,y)\n  w.select_to 'current', \"@#{x},#{y}\"\nend\n\ndef textBs(w)\n  begin\n    $ctag_text.dchars 'sel.first', 'sel.last'\n  rescue\n    char = $ctag_text.index('insert').to_i - 1\n    $ctag_text.dchars(char) if char >= 0\n  end\nend\n\ndef textDel(w)\n  begin\n    $ctag_text.dchars 'sel.first', 'sel.last'\n  rescue\n    $ctag_text.dchars 'insert'\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/dialog1.rb",
    "content": "#\n# a dialog box with a local grab (called by 'widget')\n#\nclass TkDialog_Demo1 < TkDialog\n  ###############\n  private\n  ###############\n  def title\n    \"Dialog with local grab\"\n  end\n\n  def message\n    'This is a modal dialog box.  It uses Tk\\'s \"grab\" command to create a \"local grab\" on the dialog box.  The grab prevents any pointer-related events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below.  However, you can still interact with other applications.'\n  end\n\n  def bitmap\n    'info'\n  end\n\n  def default_button\n    0\n  end\n\n  def buttons\n    # [\"Dismiss\", \"\", \"Show Code\"]\n    [\"OK\", \"Cancel\", \"Show Code\"]\n  end\nend\n\nret =  TkDialog_Demo1.new('message_config'=>{'wraplength'=>'4i'}).value\ncase ret\nwhen 0\n  print \"You pressed OK\\n\"\nwhen 1\n  print \"You pressed Cancel\\n\"\nwhen 2\n  showCode 'dialog1'\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/dialog2.rb",
    "content": "#\n# a dialog box with a global grab (called by 'widget')\n#\nclass TkDialog_Demo2 < TkDialog\n  ###############\n  private\n  ###############\n  def title\n    \"Dialog with global grab\"\n  end\n\n  def message\n    \"This dialog box uses a global grab, so it prevents you from interacting with anything on your display until you invoke one of the buttons below.  Global grabs are almost always a bad idea; don't use them unless you're truly desperate.\"\n  end\n\n  def bitmap\n    'info'\n  end\n\n  def default_button\n    0\n  end\n\n  def buttons\n    [\"OK\", \"Cancel\", \"Show Code\"]\n  end\nend\n\nret =  TkDialog_Demo2.new('message_config'=>{'wraplength'=>'4i'},\n                          'prev_command'=>proc{|dialog|\n                            Tk.after 100, proc{dialog.grab('global')}\n                          }).value\ncase ret\nwhen 0\n  print \"\\You pressed OK\\n\"\nwhen 1\n  print \"You pressed Cancel\\n\"\nwhen 2\n  showCode 'dialog2'\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/doc.org/README",
    "content": "This directory contains a collection of demonstration programs that\nare translated into Japanese.  You need to use a Japanized \"wish\" to\nsee these Japanese-translated demonstration programs.  You also need\nto put this directory (\"demos.jp\") at the next to \"demos\" since some\nof the programs refer to the image files at \"demos\".\n\nPlease refer to the README file at \"demos\" for more detail.\n"
  },
  {
    "path": "ext/tk/sample/demos-en/doc.org/README.JP",
    "content": "This directory contains \"widget\" demo for the Japanized Tcl7.6/Tk4.2.\nMost of the messages in the original are translated to Japanese.\nBut other tools in this directory are not translated.\n\nFollowing 2 kanji fonts are defined at the beginning of the file \"widget.\"\n\n\t-*--24-*-jisx0208.1983-0\n\t-*--16-*-jisx0208.1983-0\n\nThese fonts are all part of the core distribution of X11R5, so\nif you are running X11R5, you don't have to modify the file.\n\nBut if you don't have these fonts, replace them with appropriate ones.\n\"-*--14-*-jisx0208.1983-0\" will be a good choice.\n"
  },
  {
    "path": "ext/tk/sample/demos-en/doc.org/README.tk80",
    "content": "This directory contains a collection of programs to demonstrate\nthe features of the Tk toolkit.  The programs are all scripts for\n\"wish\", a windowing shell.  If wish has been installed in /usr/local\nthen you can invoke any of the programs in this directory just\nby typing its file name to your command shell.  Otherwise invoke\nwish with the file as its first argument, e.g., \"wish hello\".\nThe rest of this file contains a brief description of each program.\nFiles with names ending in \".tcl\" are procedure packages used by one\nor more of the demo programs;  they can't be used as programs by\nthemselves so they aren't described below.\n\nhello -\t\tCreates a single button;  if you click on it, a message\n\t\tis typed and the application terminates.\n\nwidget -\tContains a collection of demonstrations of the widgets\n\t\tcurrently available in the Tk library.  Most of the .tcl\n\t\tfiles are scripts for individual demos available through\n\t\tthe \"widget\" program.\n\nixset -\t\tA simple Tk-based wrapper for the \"xset\" program, which\n\t\tallows you to interactively query and set various X options\n\t\tsuch as mouse acceleration and bell volume.  Thanks to\n\t\tPierre David for contributing this example.\n\nrolodex -\tA mock-up of a simple rolodex application.  It has much of\n\t\tthe user interface for such an application but no back-end\n\t\tdatabase.  This program was written in response to Tom\n\t\tLaStrange's toolkit benchmark challenge.\n\ntcolor -\tA color editor.  Allows you to edit colors in several\n\t\tdifferent ways, and will also perform automatic updates\n\t\tusing \"send\".\n\nrmt -\t\tAllows you to \"hook-up\" remotely to any Tk application\n\t\ton the display.  Select an application with the menu,\n\t\tthen just type commands:  they'll go to that application.\n\ntimer -\t\tDisplays a seconds timer with start and stop buttons.\n\t\tControl-c and control-q cause it to exit.\n\nbrowse -\tA simple directory browser.  Invoke it with and argument\n\t\tgiving the name of the directory you'd like to browse.\n\t\tDouble-click on files or subdirectories to browse them.\n\t\tControl-c and control-q cause the program to exit.\n\nsccs id = SCCS: @(#) README 1.3 96/02/16 10:49:14\n"
  },
  {
    "path": "ext/tk/sample/demos-en/doc.org/license.terms",
    "content": "This software is copyrighted by the Regents of the University of\nCalifornia, Sun Microsystems, Inc., and other parties.  The following\nterms apply to all files associated with the software unless explicitly\ndisclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license.\n"
  },
  {
    "path": "ext/tk/sample/demos-en/doc.org/license.terms.tk80",
    "content": "This software is copyrighted by the Regents of the University of\nCalifornia, Sun Microsystems, Inc., and other parties.  The following\nterms apply to all files associated with the software unless explicitly\ndisclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license.\n"
  },
  {
    "path": "ext/tk/sample/demos-en/entry1.rb",
    "content": "#\n# entry (no scrollbars) widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($entry1_demo) && $entry1_demo\n  $entry1_demo.destroy \n  $entry1_demo = nil\nend\n\n# demo toplevel widget\n$entry1_demo = TkToplevel.new {|w|\n  title(\"Entry Demonstration (no scrollbars)\")\n  iconname(\"entry1\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($entry1_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"Three different entries are displayed below.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse button2 pressed.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $entry1_demo\n      $entry1_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'entry1'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# \ne1 = TkEntry.new(base_frame, 'relief'=>'sunken')\ne2 = TkEntry.new(base_frame, 'relief'=>'sunken')\ne3 = TkEntry.new(base_frame, 'relief'=>'sunken')\n[e1,e2,e3].each{|w| w.pack('side'=>'top', 'padx'=>10, 'pady'=>5, 'fill'=>'x')}\n\n# \ne1.insert(0, 'Initial value')\ne2.insert('end', \"This entry contains a long value, much too long \")\ne2.insert('end', \"to fit in the window at one time, so long in fact \")\ne2.insert('end', \"that you'll have to scan or scroll to see the end.\")\ne2.insert('end', \"\")\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/entry2.rb",
    "content": "# entry2.rb\n#\n# This demonstration script is the same as the entry1.tcl script\n# except that it creates scrollbars for the entries.\n#\n# entry (with scrollbars) widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($entry2_demo) && $entry2_demo\n  $entry2_demo.destroy \n  $entry2_demo = nil\nend\n\n# demo toplevel widget\n$entry2_demo = TkToplevel.new {|w|\n  title(\"Entry Demonstration (with scrollbars)\")\n  iconname(\"entry2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($entry2_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"Three different entries are displayed below, with a scrollbar for each entry.  You can add characters by pointing, clicking and typing.  The normal Motif editing characters are supported, along with many Emacs bindings.  For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor.  For entries that are too large to fit in the window all at once, you can scan through the entries with the scrollbars, or by dragging with mouse button2 pressed.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $entry2_demo\n      $entry2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'entry2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\nTkFrame.new(base_frame, 'borderwidth'=>10) {|w|\n  # entry 1\n  s1 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz')\n  e1 = TkEntry.new(w, 'relief'=>'sunken') {\n    xscrollcommand proc{|first,last| s1.set first,last}\n  }\n  s1.command(proc{|*args| e1.xview(*args)})\n  e1.pack('side'=>'top', 'fill'=>'x')\n  s1.pack('side'=>'top', 'fill'=>'x')\n\n  # spacer\n  TkFrame.new(w, 'width'=>20, 'height'=>10).pack('side'=>'top', 'fill'=>'x')\n\n  # entry 2\n  s2 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz')\n  e2 = TkEntry.new(w, 'relief'=>'sunken') {\n    xscrollcommand proc{|first,last| s2.set first,last}\n  }\n  s2.command(proc{|*args| e2.xview(*args)})\n  e2.pack('side'=>'top', 'fill'=>'x')\n  s2.pack('side'=>'top', 'fill'=>'x')\n\n  # spacer\n  TkFrame.new(w, 'width'=>20, 'height'=>10).pack('side'=>'top', 'fill'=>'x')\n\n  # entry 3\n  s3 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz')\n  e3 = TkEntry.new(w, 'relief'=>'sunken') {\n    xscrollcommand proc{|first,last| s3.set first,last}\n  }\n  s3.command(proc{|*args| e3.xview(*args)})\n  e3.pack('side'=>'top', 'fill'=>'x')\n  s3.pack('side'=>'top', 'fill'=>'x')\n\n  # \n  e1.insert(0, 'Initial value')\n  e2.insert('end', \"This entry contains a long value, much too long \")\n  e2.insert('end', \"to fit in the window at one time, so long in fact \")\n  e2.insert('end', \"that you'll have to scan or scroll to see the end.\")\n  e2.insert('end', \"\")\n\n}.pack('side'=>'top', 'fill'=>'x', 'expand'=>'yes')\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/entry3.rb",
    "content": "# entry3.rb --\n#\n# This demonstration script creates several entry widgets whose\n# permitted input is constrained in some way.  It also shows off a\n# password entry.\n#\n# based on Tcl/Tk8.4.4 widget demos\n\nif defined?($entry3_demo) && $entry3_demo\n  $entry3_demo.destroy \n  $entry3_demo = nil\nend\n\n$entry3_demo = TkToplevel.new {|w|\n  title(\"Constrained Entry Demonstration\")\n  iconname(\"entry3\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($entry3_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'5i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nFour different entries are displayed below.  You can add characters \\\nby pointing, clicking and typing, though each is constrained in what \\\nit will accept.  The first only accepts integers or the empty string \\\n(checking when focus leaves it) and will flash to indicate any \\\nproblem.  The second only accepts strings with fewer than ten \\\ncharacters and sounds the bell when an attempt to go over the limit \\\nis made.  The third accepts US phone numbers, mapping letters to \\\ntheir digit equivalent and sounding the bell on encountering an \\\ninvalid character or if trying to type over a character that is not \\\na digit.  The fourth is a password field that accepts up to eight \\\ncharacters (silently ignoring further ones), and displaying them as \\\nasterisk characters.\nEOL\n\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $entry3_demo.destroy\n                 $entry3_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'entry3'\n               }).pack(:side=>:left, :expand=>true)\n}\n\n# focusAndFlash --\n# Error handler for entry widgets that forces the focus onto the\n# widget and makes the widget flash by exchanging the foreground and\n# background colours at intervals of 200ms (i.e. at approximately\n# 2.5Hz).\n#\n# Arguments:\n# widget -      entry widget to flash\n# fg -          Initial foreground colour\n# bg -          Initial background colour\n# count -       Counter to control the number of times flashed\ndef focusAndFlash(widget, fg, bg, count=5)\n  return if count <= 0\n  if fg && !fg.empty? && bg && !bg.empty?\n    TkTimer.new(200, count, \n                proc{widget.configure(:foreground=>bg, :background=>fg)}, \n                proc{widget.configure(:foreground=>fg, :background=>bg)}\n                ).start\n  else\n    # TkTimer.new(150, 3){Tk.bell}.start\n    Tk.bell\n    TkTimer.new(200, count,\n                proc{widget.configure(:foreground=>'white',\n                                      :background=>'black')},\n                proc{widget.configure(:foreground=>'black',\n                                      :background=>'white')}\n                ).at_end{begin\n                           widget.configure(:foreground=>fg,\n                                            :background=>bg)\n                         rescue\n                           # ignore\n                         end}.start\n  end\n  widget.focus(true)\nend\n\nl1 = TkLabelFrame.new(base_frame, :text=>\"Integer Entry\")\nTkEntry.new(l1, :validate=>:focus, \n            :vcmd=>[\n              proc{|s| s == '' || /^[+-]?\\d+$/ =~ s }, '%P'\n            ]) {|e|\n  fg = e.foreground\n  bg = e.background\n  invalidcommand [proc{|w| focusAndFlash(w, fg, bg)}, '%W']\n  pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n}\n\nl2 = TkLabelFrame.new(base_frame, :text=>\"Length-Constrained Entry\")\nTkEntry.new(l2, :validate=>:key, :invcmd=>proc{Tk.bell}, \n            :vcmd=>[proc{|s| s.length < 10}, '%P']\n            ).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n\n### PHONE NUMBER ENTRY ###\n# Note that the source to this is quite a bit longer as the behaviour\n# demonstrated is a lot more ambitious than with the others.\n\n# Initial content for the third entry widget\nentry3content = TkVariable.new(\"1-(000)-000-0000\")\n\n# Mapping from alphabetic characters to numbers.\n$phoneNumberMap = {}\nHash[*(%w(abc 2 def 3 ghi 4 jkl 5 mno 6 pqrs 7 tuv 8 wxyz 9))].each{|chars, n|\n  chars.split('').each{|c|\n    $phoneNumberMap[c] = n\n    $phoneNumberMap[c.upcase] = n\n  }\n}\n\n# phoneSkipLeft --\n# Skip over fixed characters in a phone-number string when moving left.\n#\n# Arguments:\n# widget -      The entry widget containing the phone-number.\ndef phoneSkipLeft(widget)\n  idx = widget.index('insert')\n  if idx == 8\n    # Skip back two extra characters\n    widget.cursor = idx - 2\n  elsif idx == 7 || idx == 12\n    # Skip back one extra character\n    widget.cursor = idx - 1\n  elsif idx <= 3\n    # Can't move any further\n    Tk.bell\n    Tk.callback_break\n  end\nend\n\n# phoneSkipRight --\n# Skip over fixed characters in a phone-number string when moving right.\n#\n# Arguments:\n# widget -      The entry widget containing the phone-number.\n# add - Offset to add to index before calculation (used by validation.)\ndef phoneSkipRight(widget, add = 0)\n  idx = widget.index('insert')\n  if (idx + add == 5)\n    # Skip forward two extra characters\n    widget.cursor = idx + 2\n  elsif (idx + add == 6 || idx + add == 10)\n    # Skip forward one extra character\n    widget.cursor = idx + 1\n  elsif (idx + add == 15 && add == 0)\n    # Can't move any further\n    Tk.bell\n    Tk.callback_break\n  end\nend\n\n# validatePhoneChange --\n# Checks that the replacement (mapped to a digit) of the given\n# character in an entry widget at the given position will leave a\n# valid phone number in the widget.\n#\n# widget - entry widget to validate\n# vmode -  The widget's validation mode\n# idx -    The index where replacement is to occur\n# char -   The character (or string, though that will always be\n#          refused) to be overwritten at that point.\n\ndef validatePhoneChange(widget, vmode, idx, char)\n  return true if idx == nil\n  Tk.after_idle(proc{widget.configure(:validate=>vmode, \n                                      :invcmd=>proc{Tk.bell})})\n  if !(idx<3 || idx==6 || idx==7 || idx==11 || idx>15) && char =~ /[0-9A-Za-z]/\n    widget.delete(idx)\n    widget.insert(idx, $phoneNumberMap[char] || char)\n    Tk.after_idle(proc{phoneSkipRight(widget, -1)})\n    return true\n    # Tk.update(true) # <- Don't work 'update' inter validation callback.\n                      #    It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). \n  end\n  return false\nend\n\n\nl3 = TkLabelFrame.new(base_frame, :text=>\"US Phone-Number Entry\")\nTkEntry.new(l3, :validate=>:key, :invcmd=>proc{Tk.bell}, \n            :textvariable=>entry3content, \n            :vcmd=>[\n              proc{|w,v,i,s| validatePhoneChange(w,v,i,s)}, \n              \"%W %v %i %S\"\n            ]){|e|\n  # Click to focus goes to the first editable character...\n  bind('FocusIn', proc{|d,w|\n         if d != \"NotifyAncestor\"\n           w.cursor = 3\n           Tk.after_idle(proc{w.selection_clear})\n         end\n       }, '%d %W')\n  bind('Left',  proc{|w| phoneSkipLeft(w)},  '%W')\n  bind('Right', proc{|w| phoneSkipRight(w)}, '%W')\n  pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n}\n\nl4 = TkLabelFrame.new(base_frame, :text=>\"Password Entry\")\nTkEntry.new(l4, :validate=>:key, :show=>'*', \n            :vcmd=>[\n              proc{|s| s.length <= 8}, \n              '%P'\n            ]).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n\nTkFrame.new(base_frame){|f|\n  lower\n  TkGrid.configure(l1, l2, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew)\n  TkGrid.configure(l3, l4, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew)\n  TkGrid.columnconfigure(f, [0,1], :uniform=>1)\n  pack(:fill=>:both, :expand=>true)\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/filebox.rb",
    "content": "# filebox.rb\n#\n# This demonstration script prompts the user to select a file.#\n# widget demo prompts the user to select a file (called by 'widget')\n#\n\n# toplevel widget\nif defined?($filebox_demo) && $filebox_demo\n  $filebox_demo.destroy \n  $filebox_demo = nil\nend\n\n# demo toplevel widget\n$filebox_demo = TkToplevel.new {|w|\n  title(\"File Selection Dialogs\")\n  iconname(\"filebox\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($filebox_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left',\n            'text'=>\"Enter a file name in the entry box or click on the \\\"Browse\\\" buttons to select a file name using the file selection dialog.\").pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $filebox_demo\n      $filebox_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'filebox'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\n['open', 'save'].each{|type|\n  TkFrame.new(base_frame) {|f|\n    TkLabel.new(f, 'text'=>\"Select a file to #{type}: \", 'anchor'=>'e')\\\n    .pack('side'=>'left')\n\n    TkEntry.new(f, 'width'=>20) {|e|\n      pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x')\n\n      TkButton.new(f, 'text'=>'Browse ...', \n                   'command'=>proc{fileDialog base_frame,e,type})\\\n      .pack('side'=>'left')\n    }\n\n    pack('fill'=>'x', 'padx'=>'1c', 'pady'=>3)\n  }\n}\n\n$tk_strictMotif = TkVarAccess.new('tk_strictMotif')\nif ($tk_platform['platform'] == 'unix')\n  TkCheckButton.new(base_frame, \n                    'text'=>'Use Motif Style Dialog', \n                    'variable'=>$tk_strictMotif, \n                    'onvalue'=>1, 'offvalue'=>0 ).pack('anchor'=>'c')\nend\n\ndef fileDialog(w,ent,operation)\n  #    Type names         Extension(s)             Mac File Type(s)\n  #\n  #--------------------------------------------------------\n  types = [\n    ['Text files',       ['.txt','.doc']          ], \n    ['Text files',       [],                      'TEXT' ], \n    ['Ruby Scripts',     ['.rb'],                 'TEXT' ], \n    ['Tcl Scripts',      ['.tcl'],                'TEXT' ], \n    ['C Source Files',   ['.c','.h']              ], \n    ['All Source Files', ['.rb','.tcl','.c','.h'] ], \n    ['Image Files',      ['.gif']                 ], \n    ['Image Files',      ['.jpeg','.jpg']         ], \n    ['Image Files',      [],                      ['GIFF','JPEG']], \n    ['All files',        '*'                      ]\n  ]\n\n  if operation == 'open'\n    file = Tk.getOpenFile('filetypes'=>types, 'parent'=>w)\n  else\n    file = Tk.getSaveFile('filetypes'=>types, 'parent'=>w, \n                          'initialfile'=>'Untitled', \n                          'defaultextension'=>'.txt')\n  end\n  if file != \"\"\n    ent.delete 0, 'end'\n    ent.insert 0, file\n    # ent.xview 'end'\n    Tk.update_idletasks # need this for Tk::Tile::Entry\n                        # (to find right position of 'xview').\n    ent.xview(ent.index('end'))\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/floor.rb",
    "content": "# floor.rb\n#\n# This demonstration script creates a canvas widet that displays the\n# floorplan for DEC's Western Research Laboratory.\n#\n# floorDisplay widget demo (called by 'widget')\n#\n\n# floorDisplay --\n# Recreate the floorplan display in the canvas given by \"w\".  The\n# floor given by \"active\" is displayed on top with its office structure\n# visible.\n#\n# Arguments:\n# w -           Name of the canvas window.\n# active -      Number of active floor (1, 2, or 3).\n\ndef floorDisplay(w,active)\n  return if $activeFloor == active\n\n  w.delete('all')\n  $activeFloor = active\n\n  # First go through the three floors, displaying the backgrounds for \n  # each floor.\n\n  floor_bg1(w,$floor_colors['bg1'],$floor_colors['outline1'])\n  floor_bg2(w,$floor_colors['bg2'],$floor_colors['outline2'])\n  floor_bg3(w,$floor_colors['bg3'],$floor_colors['outline3'])\n\n  # Raise the background for the active floor so that it's on top.\n\n  w.raise(\"floor#{active}\")\n\n  # Create a dummy item just to mark this point in the display list, \n  # so we can insert highlights here.\n\n  TkcRectangle.new(w,0,100,1,101, 'fill'=>'', 'outline'=>'', 'tags'=>'marker')\n\n  # Add the walls and labels for the active floor, along with \n  # transparent polygons that define the rooms on the floor.\n  # Make sure that the room polygons are on top.\n\n  $floorLabels.clear\n  $floorItems.clear\n  send(\"floor_fg#{active}\", w, $floor_colors['offices'])\n  w.raise('room')\n\n  # Offset the floors diagonally from each other.\n\n  w.move('floor1', '2c', '2c')\n  w.move('floor2', '1c', '1c')\n\n  # Create items for the room entry and its label.\n  TkcWindow.new(w, 600, 100, 'anchor'=>'w', 'window'=>$floor_entry)\n  TkcText.new(w, 600, 100, 'anchor'=>'e', 'text'=>\"Room: \")\n  w['scrollregion'] = w.bbox('all')\nend\n\n# newRoom --\n# This method is invoked whenever the mouse enters a room\n# in the floorplan.  It changes tags so that the current room is\n# highlighted.\n#\n# Arguments:\n# w  -          The name of the canvas window.\n\ndef newRoom(w)\n  id = w.find_withtag('current')[0]\n  $currentRoom.value = $floorLabels[id.id] if id != \"\"\n  Tk.update(true)\nend\n\n# roomChanged --\n# This method is invoked whenever the currentRoom variable changes.\n# It highlights the current room and unhighlights any previous room.\n#\n# Arguments:\n# w -           The canvas window displaying the floorplan.\n# args -        Not used.\n\ndef roomChanged(w,*args)\n  w.delete('highlight')\n  item = $floorItems[$currentRoom.value]\n  return if item == nil\n  new = TkcPolygon.new(w, *(w.coords(item)))\n  new.configure('fill'=>$floor_colors['active'], 'tags'=>'highlight')\n  w.raise(new, 'marker')\nend\n\n# floor_bg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor_bg1(w,fill,outline)\n  TkcPolygon.new(w,347,80,349,82,351,84,353,85,363,92,375,99,386,104,\n                 386,129,398,129,398,162,484,162,484,129,559,129,559,133,725,\n                 133,725,129,802,129,802,389,644,389,644,391,559,391,559,327,\n                 508,327,508,311,484,311,484,278,395,278,395,288,400,288,404,\n                 288,409,290,413,292,418,297,421,302,422,309,421,318,417,325,\n                 411,330,405,332,397,333,344,333,340,334,336,336,335,338,332,\n                 342,331,347,332,351,334,354,336,357,341,359,340,360,335,363,\n                 331,365,326,366,304,366,304,355,258,355,258,387,60,387,60,391,\n                 0,391,0,337,3,337,3,114,8,114,8,25,30,25,30,5,93,5,98,5,104,7,\n                 110,10,116,16,119,20,122,28,123,32,123,68,220,68,220,34,221,\n                 22,223,17,227,13,231,8,236,4,242,2,246,0,260,0,283,1,300,5,\n                 321,14,335,22,348,25,365,29,363,39,358,48,352,56,337,70,\n                 344,76,347,80, 'tags'=>['floor1','bg'], 'fill'=>fill)\n  TkcLine.new(w,386,129,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,258,355,258,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,0,337,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,3,114,3,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,162,398,162, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,398,162,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,278,484,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,327,508,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,644,391,559,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,644,389,644,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,725,133,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,725,129,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,802,389,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,3,337,0,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,391,559,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,802,389,644,389, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,725,133,725,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,8,25,8,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,8,114,3,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,30,25,8,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,278,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,30,25,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,93,5,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,98,5,93,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,104,7,98,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,110,10,104,7, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,116,16,110,10, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,119,20,116,16, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,122,28,119,20, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,123,32,122,28, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,123,68,123,32, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,220,68,123,68, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,386,129,386,104, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,386,104,375,99, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,375,99,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,353,85,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,220,68,220,34, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,337,70,352,56, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,352,56,358,48, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,358,48,363,39, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,363,39,365,29, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,365,29,348,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,348,25,335,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,335,22,321,14, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,321,14,300,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,300,5,283,1, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,283,1,260,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,260,0,246,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,246,0,242,2, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,242,2,236,4, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,236,4,231,8, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,231,8,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,223,17,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,221,22,223,17, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,220,34,221,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,340,360,335,363, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,335,363,331,365, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,331,365,326,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,326,366,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,304,355,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,395,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,404,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,409,290,404,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,413,292,409,290, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,418,297,413,292, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,421,302,418,297, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,422,309,421,302, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,421,318,422,309, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,421,318,417,325, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,417,325,411,330, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,411,330,405,332, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,405,332,397,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,397,333,344,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,344,333,340,334, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,340,334,336,336, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,336,336,335,338, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,335,338,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,331,347,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,332,351,331,347, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,334,354,332,351, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,336,357,334,354, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,341,359,336,357, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,341,359,340,360, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,395,288,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,304,355,258,355, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,347,80,344,76, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,344,76,337,70, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,349,82,347,80, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,351,84,349,82, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,353,85,351,84, 'fill'=>outline, 'tags'=>['floor1','bg'])\nend\n\n# floor_bg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor_bg2(w,fill,outline)\n  TkcPolygon.new(w,559,129,484,129,484,162,398,162,398,129,315,129,\n                 315,133,176,133,176,129,96,129,96,133,3,133,3,339,0,339,0,391,\n                 60,391,60,387,258,387,258,329,350,329,350,311,395,311,395,280,\n                 484,280,484,311,508,311,508,327,558,327,558,391,644,391,644,\n                 367,802,367,802,129,725,129,725,133,559,133,559,129,\n                 'tags'=>['floor2','bg'], 'fill'=>fill)\n  TkcLine.new(w,350,311,350,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,398,129,398,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,802,367,802,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,802,129,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,725,133,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,559,133,725,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,802,367,644,367, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,644,367,644,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,644,391,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,558,327,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,558,327,508,327, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,280,484,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,398,162,484,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,280,395,280, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,395,280,395,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,3,133,3,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,3,339,0,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,0,339,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,258,329,258,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,395,311,350,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,398,129,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,176,133,315,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,3,133,96,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,315,133,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,176,133,176,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,96,133,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\nend\n\n# floor_bg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor_bg3(w,fill,outline)\n  TkcPolygon.new(w,159,300,107,300,107,248,159,248,159,129,96,129,96,\n                 133,21,133,21,331,0,331,0,391,60,391,60,370,159,370,159,300,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  TkcPolygon.new(w,258,370,258,329,350,329,350,311,399,311,399,129,\n                 315,129,315,133,176,133,176,129,159,129,159,370,258,370,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  TkcLine.new(w,96,133,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,176,129,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,315,133,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,315,133,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,399,129,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,399,311,399,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,399,311,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,350,329,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,258,370,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,60,370,258,370, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,60,370,60,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,0,391,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,21,331,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,21,331,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,96,133,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,107,300,159,300,159,248,107,248,107,300, \n              'fill'=>outline, 'tags'=>['floor3','bg'])\nend\n\n# floor_fg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the first\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor_fg1(w,color)\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '101'\n  $floorItems['101'] = i\n  TkcText.new(w,358,209, 'text'=>'101', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Pub Lift1'\n  $floorItems['Pub Lift1'] = i\n  TkcText.new(w,323,223, 'text'=>'Pub Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Priv Lift1'\n  $floorItems['Priv Lift1'] = i\n  TkcText.new(w,323,188, 'text'=>'Priv Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,42,389,42,337,1,337,1,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '110'\n  $floorItems['110'] = i\n  TkcText.new(w,21.5,363, 'text'=>'110', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,59,389,59,385,90,385,90,337,44,337,44,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '109'\n  $floorItems['109'] = i\n  TkcText.new(w,67,363, 'text'=>'109', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,300,51,253,6,253,6,300, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '111'\n  $floorItems['111'] = i\n  TkcText.new(w,28.5,276.5, 'text'=>'111', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,98,248,98,309,79,309,79,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '117B'\n  $floorItems['117B'] = i\n  TkcText.new(w,88.5,278.5, 'text'=>'117B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,251,51,204,6,204,6,251, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '112'\n  $floorItems['112'] = i\n  TkcText.new(w,28.5,227.5, 'text'=>'112', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,6,156,51,156,51,203,6,203, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '113'\n  $floorItems['113'] = i\n  TkcText.new(w,28.5,179.5, 'text'=>'113', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,85,169,79,169,79,192,85,192, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '117A'\n  $floorItems['117A'] = i\n  TkcText.new(w,82,180.5, 'text'=>'117A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,77,302,77,168,53,168,53,302, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '117'\n  $floorItems['117'] = i\n  TkcText.new(w,65,235, 'text'=>'117', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,155,51,115,6,115,6,155, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '114'\n  $floorItems['114'] = i\n  TkcText.new(w,28.5,135, 'text'=>'114', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,95,115,53,115,53,168,95,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '115'\n  $floorItems['115'] = i\n  TkcText.new(w,74,141.5, 'text'=>'115', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,87,113,87,27,10,27,10,113, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '116'\n  $floorItems['116'] = i\n  TkcText.new(w,48.5,70, 'text'=>'116', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,89,91,128,91,128,113,89,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '118'\n  $floorItems['118'] = i\n  TkcText.new(w,108.5,102, 'text'=>'118', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,178,128,178,132,216,132,216,91,\n                     163,91,163,112,149,112,149,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '120'\n  $floorItems['120'] = i\n  TkcText.new(w,189.5,111.5, 'text'=>'120', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,79,193,87,193,87,169,136,169,136,192,\n                     156,192,156,169,175,169,175,246,79,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '122'\n  $floorItems['122'] = i\n  TkcText.new(w,131,207.5, 'text'=>'122', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,169,154,169,154,191,138,191, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '121'\n  $floorItems['121'] = i\n  TkcText.new(w,146,180, 'text'=>'121', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,99,300,126,300,126,309,99,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '106A'\n  $floorItems['106A'] = i\n  TkcText.new(w,112.5,304.5, 'text'=>'106A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,128,299,128,309,150,309,150,248,99,248,99,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '105'\n  $floorItems['105'] = i\n  TkcText.new(w,124.5,278.5, 'text'=>'105', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,174,309,174,300,152,300,152,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '106B'\n  $floorItems['106B'] = i\n  TkcText.new(w,163,304.5, 'text'=>'106B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,176,299,176,309,216,309,216,248,152,248,152,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '104'\n  $floorItems['104'] = i\n  TkcText.new(w,184,278.5, 'text'=>'104', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,385,138,337,91,337,91,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '108'\n  $floorItems['108'] = i\n  TkcText.new(w,114.5,361, 'text'=>'108', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,256,337,140,337,140,385,256,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '107'\n  $floorItems['107'] = i\n  TkcText.new(w,198,361, 'text'=>'107', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,300,353,300,329,260,329,260,353, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Smoking'\n  $floorItems['Smoking'] = i\n  TkcText.new(w,280,341, 'text'=>'Smoking', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,314,135,314,170,306,170,306,246,177,246,177,135, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '123'\n  $floorItems['123'] = i\n  TkcText.new(w,245.5,190.5, 'text'=>'123', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,217,248,301,248,301,326,257,326,257,310,217,310, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '103'\n  $floorItems['103'] = i\n  TkcText.new(w,259,287, 'text'=>'103', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,396,188,377,188,377,169,316,169,316,131,396,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '124'\n  $floorItems['124'] = i\n  TkcText.new(w,356,150, 'text'=>'124', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,226,407,226,407,189,377,189,377,246,397,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '125'\n  $floorItems['125'] = i\n  TkcText.new(w,392,217.5, 'text'=>'125', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,399,187,409,187,409,207,474,207,474,164,399,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '126'\n  $floorItems['126'] = i\n  TkcText.new(w,436.5,185.5, 'text'=>'126', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,409,209,409,229,399,229,399,253,\n                     486,253,486,239,474,239,474,209, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '127'\n  $floorItems['127'] = i\n  TkcText.new(w,436.5,'231', 'text'=>'127', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,501,164,501,174,495,174,495,188,\n                     490,188,490,204,476,204,476,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'MShower'\n  $floorItems['MShower'] = i\n  TkcText.new(w,488.5,'184', 'text'=>'MShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,497,176,513,176,513,204,492,204,492,190,497,190, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Closet'\n  $floorItems['Closet'] = i\n  TkcText.new(w,502.5,190, 'text'=>'Closet', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,476,237,476,206,513,206,513,254,488,254,488,237, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'WShower'\n  $floorItems['WShower'] = i\n  TkcText.new(w,494.5,230, 'text'=>'WShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,486,131,558,131,558,135,724,135,724,166,\n                     697,166,697,275,553,275,531,254,515,254,\n                     515,174,503,174,503,161,486,161, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '130'\n  $floorItems['130'] = i\n  TkcText.new(w,638.5,205, 'text'=>'130', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,308,242,339,242,339,248,342,248,\n                     342,246,397,246,397,276,393,276,\n                     393,309,300,309,300,248,308,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '102'\n  $floorItems['102'] = i\n  TkcText.new(w,367.5,278.5, 'text'=>'102', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,255,486,255,486,276,397,276, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '128'\n  $floorItems['128'] = i\n  TkcText.new(w,441.5,265.5, 'text'=>'128', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,510,309,486,309,486,255,530,255,\n                     552,277,561,277,561,325,510,325,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '129'\n  $floorItems['129'] = i\n  TkcText.new(w,535.5,293, 'text'=>'129', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,696,281,740,281,740,387,642,387,\n                     642,389,561,389,561,277,696,277, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '133'\n  $floorItems['133'] = i\n  TkcText.new(w,628.5,335, 'text'=>'133', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,742,387,742,281,800,281,800,387, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '132'\n  $floorItems['132'] = i\n  TkcText.new(w,771,334, 'text'=>'132', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,800,168,800,280,699,280,699,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '134'\n  $floorItems['134'] = i\n  TkcText.new(w,749.5,224, 'text'=>'134', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,726,131,726,166,800,166,800,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '135'\n  $floorItems['135'] = i\n  TkcText.new(w,763,148.5, 'text'=>'135', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,340,360,335,363,331,365,326,366,304,366,\n                     304,312,396,312,396,288,400,288,404,288,\n                     409,290,413,292,418,297,421,302,422,309,\n                     421,318,417,325,411,330,405,332,397,333,\n                     344,333,340,334,336,336,335,338,332,342,\n                     331,347,332,351,334,354,336,357,341,359, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Ramona Stair'\n  $floorItems['Ramona Stair'] = i\n  TkcText.new(w,368,323, 'text'=>'Ramona Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,30,23,30,5,93,5,98,5,104,7,110,10,116,16,119,20,\n                     122,28,123,32,123,68,220,68,220,87,90,87,90,23, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'University Stair'\n  $floorItems['University Stair'] = i\n  TkcText.new(w,155,77.5, 'text'=>'University Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,282,37,295,40,312,49,323,56,337,70,352,56,\n                     358,48,363,39,365,29,348,25,335,22,321,14,\n                     300,5,283,1,260,0,246,0,242,2,236,4,231,8,\n                     227,13,223,17,221,22,220,34,260,34, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Plaza Stair'\n  $floorItems['Plaza Stair'] = i\n  TkcText.new(w,317.5,28.5, 'text'=>'Plaza Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,220,34,260,34,282,37,295,40,312,49,\n                     323,56,337,70,350,83,365,94,377,100,\n                     386,104,386,128,220,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Plaza Deck'\n  $floorItems['Plaza Deck'] = i\n  TkcText.new(w,303,81, 'text'=>'Plaza Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,257,336,77,336,6,336,6,301,77,301,77,310,257,310,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '106'\n  $floorItems['106'] = i\n  TkcText.new(w,131.5,318.5, 'text'=>'106', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,146,110,162,110,162,91,130,91,130,115,95,115,\n                     95,128,114,128,114,151,157,151,157,153,112,153,\n                     112,130,97,130,97,168,175,168,175,131,146,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '119'\n  $floorItems['119'] = i\n  TkcText.new(w,143.5,133, 'text'=>'119', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  TkcLine.new(w,155,191,155,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,155,177,155,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,96,129,96,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,169,176,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,176,247,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,206,307,206, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,187,340,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,210,340,201, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,247,340,224, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,241,307,241, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,376,246,376,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,307,247,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,376,170,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,315,129,315,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,147,129,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,202,133,176,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,398,129,315,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,352,258,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,0,337,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,3,114,3,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,237,52,273, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,189,52,225, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,140,52,177, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,395,306,395,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,531,254,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,475,178,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,502,162,398,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,398,129,398,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,383,188,376,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,188,408,194, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,398,227,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,227,398,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,222,408,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,206,408,210, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,208,475,208, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,278,484,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,327,508,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,644,391,559,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,644,389,644,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,514,205,475,205, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,496,189,496,187, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,133,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,149,725,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,129,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,802,389,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,739,167,802,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,396,188,408,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,0,337,9,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,58,337,21,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,43,391,43,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,105,337,75,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,91,387,91,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,154,337,117,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,139,387,139,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,227,337,166,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,337,251,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,328,302,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,302,355,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,395,311,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,278,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,395,294,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,473,278,473,275, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,473,256,473,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,533,257,531,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,553,276,551,274, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,698,276,553,276, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,391,559,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,802,389,644,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,741,314,741,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,698,280,698,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,707,280,698,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,802,280,731,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,741,280,741,302, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,698,167,727,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,137,725,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,514,254,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,496,175,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,502,175,502,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,475,166,475,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,496,176,496,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,491,189,496,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,491,205,491,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,487,238,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,487,240,487,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,487,252,487,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,315,133,304,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,256,133,280,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,247,270,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,307,247,294,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,214,133,232,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,217,247,217,266, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,217,309,217,291, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,217,309,172,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,154,309,148,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,175,300,175,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,151,300,175,300, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,151,247,151,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,237,78,265, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,286,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,106,309,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,130,309,125,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,99,309,99,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,127,299,99,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,127,309,127,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,155,191,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,137,169,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,171,78,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,190,78,218, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,86,192,86,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,86,192,78,192, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,301,3,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,286,52,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,252,3,252, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,203,3,203, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,3,156,52,156, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,8,25,8,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,63,114,3,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,75,114,97,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,108,114,129,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,129,114,129,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,114,52,128, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,132,89,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,88,25,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,88,114,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,218,89,144,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,147,111,147,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,162,111,147,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,162,109,162,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,162,96,162,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,218,89,218,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,218,89,218,119, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,8,25,88,25, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,337,258,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,129,96,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,302,355,258,355, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,386,104,386,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,377,100,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,365,94,377,100, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,350,83,365,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,337,70,350,83, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,337,70,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,312,49,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,295,40,312,49, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,282,37,295,40, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,260,34,282,37, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,253,34,260,34, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,386,128,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,152,113,129, 'fill'=>color, 'tags'=>['floor1','wall'])\nend\n\n# floor_fg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the second\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor_fg2(w,color)\n  i = TkcPolygon.new(w,748,188,755,188,755,205,758,205,758,222,\n                     800,222,800,168,748,168, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '238'\n  $floorItems['238'] = i\n  TkcText.new(w,774,195, 'text'=>'238', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,726,188,746,188,746,166,800,166,800,131,726,131,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '237'\n  $floorItems['237'] = i\n  TkcText.new(w,763,148.5, 'text'=>'237', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,497,187,497,204,559,204,559,324,641,324,\n                     643,324,643,291,641,291,641,205,696,205,\n                     696,291,694,291,694,314,715,314,715,291,\n                     715,205,755,205,755,190,724,190,724,187, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '246'\n  $floorItems['246'] = i\n  TkcText.new(w,600,264, 'text'=>'246', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,694,279,643,279,643,314,694,314, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '247'\n  $floorItems['247'] = i\n  TkcText.new(w,668.5,296.5, 'text'=>'247', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,232,250,308,250,308,242,339,242,339,246,\n                     397,246,397,255,476,255,476,250,482,250,559,250,\n                     559,274,482,274,482,278,396,278,396,274,232,274, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '202'\n  $floorItems['202'] = i\n  TkcText.new(w,285.5,260, 'text'=>'202', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,53,228,53,338,176,338,233,338,233,196,\n                     306,196,306,180,175,180,175,169,156,169,\n                     156,196,176,196,176,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '206'\n  $floorItems['206'] = i\n  TkcText.new(w,143,267, 'text'=>'206', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,277,6,277,6,338,51,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '212'\n  $floorItems['212'] = i\n  TkcText.new(w,28.5,307.5, 'text'=>'212', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,276,486,276,486,309,510,309,510,325,557,325, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '245'\n  $floorItems['245'] = i\n  TkcText.new(w,521.5,300.5, 'text'=>'245', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,560,389,599,389,599,326,560,326, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '244'\n  $floorItems['244'] = i\n  TkcText.new(w,579.5,357.5, 'text'=>'244', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,601,389,601,326,643,326,643,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '243'\n  $floorItems['243'] = i\n  TkcText.new(w,622,357.5, 'text'=>'243', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,688,316,645,316,645,365,688,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '242'\n  $floorItems['242'] = i\n  TkcText.new(w,666.5,340.5, 'text'=>'242', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,802,367,759,367,759,226,802,226, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = 'Barbecue Deck'\n  $floorItems['Barbecue Deck'] = i\n  TkcText.new(w,780.5,296.5, 'text'=>'Barbecue Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,262,755,314,717,314,717,262, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '240'\n  $floorItems['240'] = i\n  TkcText.new(w,736,288, 'text'=>'240', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,316,689,316,689,365,755,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '241'\n  $floorItems['241'] = i\n  TkcText.new(w,722,340.5, 'text'=>'241', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,206,717,206,717,261,755,261, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '239'\n  $floorItems['239'] = i\n  TkcText.new(w,736,233.5, 'text'=>'239', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,695,277,643,277,643,206,695,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '248'\n  $floorItems['248'] = i\n  TkcText.new(w,669,241.5, 'text'=>'248', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,676,135,676,185,724,185,724,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '236'\n  $floorItems['236'] = i\n  TkcText.new(w,700,160, 'text'=>'236', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,675,135,635,135,635,145,628,145,628,185,675,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '235'\n  $floorItems['235'] = i\n  TkcText.new(w,651.5,160, 'text'=>'235', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,626,143,633,143,633,135,572,135,\n                     572,143,579,143,579,185,626,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '234'\n  $floorItems['234'] = i\n  TkcText.new(w,606,160, 'text'=>'234', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,135,571,135,571,145,578,145,\n                     578,185,527,185,527,131,557,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '233'\n  $floorItems['233'] = i\n  TkcText.new(w,552.5,158, 'text'=>'233', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,249,557,249,557,205,476,205,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '230'\n  $floorItems['230'] = i\n  TkcText.new(w,516.5,227, 'text'=>'230', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,164,486,164,486,131,525,131,525,185,476,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '232'\n  $floorItems['232'] = i\n  TkcText.new(w,500.5,158, 'text'=>'232', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,186,495,186,495,204,476,204, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '229'\n  $floorItems['229'] = i\n  TkcText.new(w,485.5,195, 'text'=>'229', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,474,207,409,207,409,187,399,187,399,164,474,164, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '227'\n  $floorItems['227'] = i\n  TkcText.new(w,436.5,185.5, 'text'=>'227', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,399,228,399,253,474,253,474,209,409,209,409,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '228'\n  $floorItems['228'] = i\n  TkcText.new(w,436.5,231, 'text'=>'228', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,397,246,397,226,407,226,407,189,377,189,377,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '226'\n  $floorItems['226'] = i\n  TkcText.new(w,392,217.5, 'text'=>'226', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,377,169,316,169,316,131,397,131,397,188,377,188, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '225'\n  $floorItems['225'] = i\n  TkcText.new(w,356.5,150, 'text'=>'225', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,198,306,198,306,249,234,249, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '224'\n  $floorItems['224'] = i\n  TkcText.new(w,270,223.5, 'text'=>'224', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,270,179,306,179,306,170,314,170,314,135,270,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '223'\n  $floorItems['223'] = i\n  TkcText.new(w,292,157, 'text'=>'223', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,268,179,221,179,221,135,268,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '222'\n  $floorItems['222'] = i\n  TkcText.new(w,244.5,157, 'text'=>'222', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,177,179,219,179,219,135,177,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '221'\n  $floorItems['221'] = i\n  TkcText.new(w,198,157, 'text'=>'221', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,299,327,349,327,349,284,341,284,341,276,299,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '204'\n  $floorItems['204'] = i\n  TkcText.new(w,324,301.5, 'text'=>'204', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,276,297,276,297,327,257,327,257,338,234,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '205'\n  $floorItems['205'] = i\n  TkcText.new(w,265.5,307, 'text'=>'205', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,256,385,256,340,212,340,212,385,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '207'\n  $floorItems['207'] = i\n  TkcText.new(w,234,362.5, 'text'=>'207', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,210,340,164,340,164,385,210,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '208'\n  $floorItems['208'] = i\n  TkcText.new(w,187,362.5, 'text'=>'208', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,115,340,162,340,162,385,115,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '209'\n  $floorItems['209'] = i\n  TkcText.new(w,138.5,362.5, 'text'=>'209', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,228,89,156,53,156,53,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '217'\n  $floorItems['217'] = i\n  TkcText.new(w,71,192, 'text'=>'217', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,169,97,169,97,190,89,190, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '217A'\n  $floorItems['217A'] = i\n  TkcText.new(w,93,179.5, 'text'=>'217A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,156,89,168,95,168,95,135,53,135,53,156, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '216'\n  $floorItems['216'] = i\n  TkcText.new(w,71,145.5, 'text'=>'216', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,179,51,135,6,135,6,179, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '215'\n  $floorItems['215'] = i\n  TkcText.new(w,28.5,157, 'text'=>'215', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,227,6,227,6,180,51,180, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '214'\n  $floorItems['214'] = i\n  TkcText.new(w,28.5,203.5, 'text'=>'214', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,275,6,275,6,229,51,229, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '213'\n  $floorItems['213'] = i\n  TkcText.new(w,28.5,252, 'text'=>'213', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,114,340,67,340,67,385,114,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '210'\n  $floorItems['210'] = i\n  TkcText.new(w,90.5,362.5, 'text'=>'210', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,59,389,59,385,65,385,65,340,1,340,1,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '211'\n  $floorItems['211'] = i\n  TkcText.new(w,33,364.5, 'text'=>'211', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,393,309,350,309,350,282,342,282,342,276,393,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '203'\n  $floorItems['203'] = i\n  TkcText.new(w,367.5,292.5, 'text'=>'203', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,99,191,91,191,91,226,174,226,174,198,\n                     154,198,154,192,109,192,109,169,99,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '220'\n  $floorItems['220'] = i\n  TkcText.new(w,132.5,208.5, 'text'=>'220', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = 'Priv Lift2'\n  $floorItems['Priv Lift2'] = i\n  TkcText.new(w,323,188, 'text'=>'Priv Lift2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = 'Pub Lift 2'\n  $floorItems['Pub Lift 2'] = i\n  TkcText.new(w,323,223, 'text'=>'Pub Lift 2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '218'\n  $floorItems['218'] = i\n  TkcText.new(w,136,149.5, 'text'=>'218', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '219'\n  $floorItems['219'] = i\n  TkcText.new(w,132.5,180, 'text'=>'219', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '201'\n  $floorItems['201'] = i\n  TkcText.new(w,358,209, 'text'=>'201', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  TkcLine.new(w,641,186,678,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,350,757,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,634,133,634,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,634,144,627,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,572,133,572,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,572,144,579,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,129,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,174,197,175,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,175,197,175,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,206,757,221, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,396,188,408,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,727,189,725,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,747,167,802,167, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,747,167,747,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,755,189,739,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,769,224,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,802,224,802,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,802,129,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,725,189,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,725,186,690,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,676,133,676,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,627,144,627,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,629,186,593,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,579,144,579,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,725,133,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,526,129,526,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,540,186,581,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,528,186,523,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,511,186,475,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,496,190,496,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,496,205,496,202, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,475,205,527,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,205,539,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,205,558,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,249,475,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,662,206,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,695,206,675,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,695,278,642,278, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,642,291,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,695,291,695,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,716,208,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,206,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,221,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,793,224,802,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,262,716,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,716,220,716,264, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,716,315,716,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,315,703,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,325,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,367,644,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,689,367,689,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,647,315,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,659,315,691,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,600,325,600,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,627,325,644,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,644,391,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,615,325,575,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,644,391,558,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,563,325,558,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,391,558,314, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,327,508,327, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,275,484,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,302,558,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,275,484,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,475,208,408,208, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,206,408,210, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,222,408,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,227,398,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,227,398,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,188,408,194, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,383,188,376,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,188,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,162,484,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,475,162,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,254,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,280,395,280, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,395,311,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,307,197,293,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,278,197,233,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,233,197,233,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,307,179,284,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,233,249,278,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,269,179,269,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,220,179,220,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,155,191,110,191, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,90,190,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,98,169,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,133,52,165, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,214,52,177, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,226,52,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,274,52,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,234,275,234,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,226,339,258,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,211,387,211,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,214,339,177,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,3,133,3,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,165,339,129,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,117,339,80,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,68,339,59,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,0,339,46,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,0,339,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,258,329,258,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,395,311,350,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,129,315,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,176,133,315,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,3,133,96,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,66,387,66,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,115,387,115,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,163,387,163,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,234,275,276,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,288,275,309,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,298,275,298,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,341,283,350,283, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,321,275,341,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,375,275,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,315,129,315,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,376,170,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,307,250,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,376,245,376,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,241,307,241, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,245,340,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,210,340,201, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,187,340,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,206,307,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,293,250,307,250, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,271,179,238,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,226,179,195,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,176,129,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,182,179,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,174,169,176,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,162,169,90,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,96,169,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,175,227,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,90,190,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,179,3,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,228,3,228, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,276,3,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,155,177,155,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,110,191,110,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,155,189,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,350,283,350,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,162,197,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,341,275,341,283, 'fill'=>color, 'tags'=>['floor2','wall'])\nend\n\n# floor_fg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the third\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor_fg3(w,color)\n  i = TkcPolygon.new(w,89,228,89,180,70,180,70,228,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '316'\n  $floorItems['316'] = i\n  TkcText.new(w,79.5,204, 'text'=>'316', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,115,368,162,368,162,323,115,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '309'\n  $floorItems['309'] = i\n  TkcText.new(w,138.5,345.5, 'text'=>'309', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,164,323,164,368,211,368,211,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '308'\n  $floorItems['308'] = i\n  TkcText.new(w,187.5,345.5, 'text'=>'308', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,256,368,212,368,212,323,256,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '307'\n  $floorItems['307'] = i\n  TkcText.new(w,234,345.5, 'text'=>'307', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,244,276,297,276,297,327,260,327,260,321,244,321, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '305'\n  $floorItems['305'] = i\n  TkcText.new(w,270.5,301.5, 'text'=>'305', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,219,251,203,244,203,244,219,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '324B'\n  $floorItems['324B'] = i\n  TkcText.new(w,247.5,211, 'text'=>'324B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,249,244,249,244,232,251,232, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '324A'\n  $floorItems['324A'] = i\n  TkcText.new(w,247.5,240.5, 'text'=>'324A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,223,135,223,179,177,179,177,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '320'\n  $floorItems['320'] = i\n  TkcText.new(w,200,157, 'text'=>'320', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,114,368,114,323,67,323,67,368, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '310'\n  $floorItems['310'] = i\n  TkcText.new(w,90.5,345.5, 'text'=>'310', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,277,23,321,68,321,68,277, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '312'\n  $floorItems['312'] = i\n  TkcText.new(w,45.5,299, 'text'=>'312', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,229,68,229,68,275,23,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '313'\n  $floorItems['313'] = i\n  TkcText.new(w,45.5,252, 'text'=>'313', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,68,227,23,227,23,180,68,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '314'\n  $floorItems['314'] = i\n  TkcText.new(w,40.5,203.5, 'text'=>'314', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,95,179,95,135,23,135,23,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '315'\n  $floorItems['315'] = i\n  TkcText.new(w,59,157, 'text'=>'315', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,99,226,99,204,91,204,91,226, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '316B'\n  $floorItems['316B'] = i\n  TkcText.new(w,95,215, 'text'=>'316B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,91,202,99,202,99,180,91,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '316A'\n  $floorItems['316A'] = i\n  TkcText.new(w,95,191, 'text'=>'316A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,97,169,109,169,109,192,154,192,154,198,\n                     174,198,174,226,101,226,101,179,97,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '319'\n  $floorItems['319'] = i\n  TkcText.new(w,141.5,209, 'text'=>'319', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,65,368,58,368,58,389,1,389,1,333,23,333,23,323,65,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '311'\n  $floorItems['311'] = i\n  TkcText.new(w,29.5,361, 'text'=>'311', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '318'\n  $floorItems['318'] = i\n  TkcText.new(w,132.5,180, 'text'=>'318', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '317'\n  $floorItems['317'] = i\n  TkcText.new(w,136,149.5, 'text'=>'317', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,274,194,274,221,306,221,306,194, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '323'\n  $floorItems['323'] = i\n  TkcText.new(w,290,207.5, 'text'=>'323', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,306,222,274,222,274,249,306,249, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '325'\n  $floorItems['325'] = i\n  TkcText.new(w,290,235.5, 'text'=>'325', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,263,179,224,179,224,135,263,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '321'\n  $floorItems['321'] = i\n  TkcText.new(w,243.5,157, 'text'=>'321', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,314,169,306,169,306,192,273,192,\n                     264,181,264,135,314,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '322'\n  $floorItems['322'] = i\n  TkcText.new(w,293.5,163.5, 'text'=>'322', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = 'Pub Lift3'\n  $floorItems['Pub Lift3'] = i\n  TkcText.new(w,323,223, 'text'=>'Pub Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = 'Priv Lift3'\n  $floorItems['Priv Lift3'] = i\n  TkcText.new(w,323,188, 'text'=>'Priv Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,350,284,376,284,376,276,397,276,397,309,350,309, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '303'\n  $floorItems['303'] = i\n  TkcText.new(w,373.5,292.5, 'text'=>'303', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,272,203,272,249,252,249,252,230,\n                     244,230,244,221,252,221,252,203, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '324'\n  $floorItems['324'] = i\n  TkcText.new(w,262,226, 'text'=>'324', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,299,276,299,327,349,327,349,284,341,284,341,276, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '304'\n  $floorItems['304'] = i\n  TkcText.new(w,324,301.5, 'text'=>'304', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '301'\n  $floorItems['301'] = i\n  TkcText.new(w,358,209, 'text'=>'301', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,397,246,377,246,377,185,397,185, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '327'\n  $floorItems['327'] = i\n  TkcText.new(w,387,215.5, 'text'=>'327', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,316,131,316,169,377,169,377,185,397,185,397,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '326'\n  $floorItems['326'] = i\n  TkcText.new(w,365.5,150, 'text'=>'326', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,308,251,242,251,242,274,342,274,342,282,375, 282,\n                     375,274,397,274,397,248,339,248,339,242,308,242, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '302'\n  $floorItems['302'] = i\n  TkcText.new(w,319.5,261, 'text'=>'302', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,70,321,242,321,242,200,259,200,259,203,272,203,\n                     272,193,263,180,242,180,175,180,175,169,156,169,\n                     156,196,177,196,177,228,107,228,70,228,70,275,107,275,\n                     107,248,160,248,160,301,107,301,107,275,70,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '306'\n  $floorItems['306'] = i\n  TkcText.new(w,200.5,284.5, 'text'=>'306', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  TkcLine.new(w,341,275,341,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,162,197,155,197, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,396,247,399,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,399,129,399,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,202,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,350,283,350,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,251,231,243,231, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,220,251,220, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,250,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,155,197,155,190, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,110,192,110,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,155,192,110,192, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,155,177,155,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,176,197,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,69,280,69,274, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,276,69,276, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,69,262,69,226, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,228,69,228, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,179,75,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,69,179,69,214, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,220,90,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,204,90,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,203,100,203, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,187,90,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,227,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,100,179,100,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,100,179,87,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,96,179,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,162,169,96,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,173,169,176,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,182,179,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,176,129,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,195,179,226,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,224,133,224,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,264,179,264,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,238,179,264,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,207,273,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,235,273,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,224,273,219, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,193,307,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,222,307,222, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,384,247,376,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,206,307,206, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,187,340,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,210,340,201, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,247,340,224, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,241,307,241, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,247,376,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,307,250,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,170,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,315,129,315,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,283,366,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,283,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,399,275,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,341,275,320,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,341,283,350,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,298,275,298,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,308,275,298,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,322,243,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,275,284,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,322,226,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,212,370,212,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,214,322,177,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,163,370,163,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,165,322,129,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,84,322,117,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,71,322,64,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,115,322,115,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,66,322,66,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,52,322,21,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,331,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,331,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,96,133,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,315,133,176,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,315,129,399,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,399,311,350,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,322,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,60,370,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,60,370,60,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,0,391,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,307,250,307,242, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,250,243,250, 'fill'=>color, 'tags'=>['floor3','wall'])\nend\n\n# Below is the \"main program\" that creates the floorplan demonstration.\n\n# toplevel widget\nif defined?($floor_demo) && $floor_demo\n  $floor_demo.destroy \n  $floor_demo = nil\nend\n\n# demo toplevel widget\n$floor_demo = TkToplevel.new {|w|\n  title(\"Floorplan Canvas Demonstration\")\n  iconname(\"Floorplan\")\n  positionWindow(w)\n  geometry('+20+20')\n  minsize(100,100)\n}\n\nbase_frame = TkFrame.new($floor_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', \n            'text'=>\"This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory.  It has three levels.  At any given time one of the levels is active, meaning that you can see its room structure.  To activate a level, click the left mouse button anywhere on it.  As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \\\"Room:\\\" entry.  You can also type a room number in the entry and the room will light up.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$floor_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $floor_demo\n      $floor_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'floor'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$floor_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# \n$floorLabels = {}\n$floorItems = {}\n\n# canvas \nif $tk_version =~ /^4\\.[01]/\n  $floor_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken',\n                                    'highlightthickness'=>2)\n  $floor_canvas = TkCanvas.new($floor_canvas_frame, \n                               'width'=>900, 'height'=>500, 'borderwidth'=>0, \n                               'highlightthickness'=>0) {|c|\n    TkScrollbar.new(base_frame, 'orient'=>'horiz', \n                    'command'=>proc{|*args| c.xview(*args)}){|hs|\n      c.xscrollcommand(proc{|first,last| hs.set first,last})\n      pack('side'=>'bottom', 'fill'=>'x')\n    }\n    TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs|\n      c.yscrollcommand(proc{|first,last| vs.set first,last})\n      pack('side'=>'right', 'fill'=>'y')\n    }\n  }\n  $floor_canvas_frame.pack('side'=>'top','fill'=>'both', 'expand'=>'yes')\n  $floor_canvas.pack('expand'=>'yes', 'fill'=>'both')\n\nelse\n  TkFrame.new(base_frame) {|f|\n    pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\n    h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal')\n    v = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'vertical')\n\n    TkFrame.new(f, 'bd'=>2, 'relief'=>'sunken') {|f1|\n      $floor_canvas = TkCanvas.new(f1, 'width'=>900, 'height'=>500, \n                                   'borderwidth'=>0, \n                                   'highlightthickness'=>0) {\n        xscrollcommand(proc{|first,last| h.set first,last})\n        yscrollcommand(proc{|first,last| v.set first,last})\n        pack('expand'=>'yes', 'fill'=>'both')\n      }\n      grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    }\n\n    v.grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    h.grid('padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n\n    TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n\n    pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n\n    v.command(proc{|*args| $floor_canvas.yview(*args)})\n    h.command(proc{|*args| $floor_canvas.xview(*args)})\n  }\nend\n\n\n# Create an entry for displaying and typing in current room.\n\n$currentRoom = TkVariable.new\n$floor_entry = TkEntry.new($floor_canvas, 'width'=>10, 'relief'=>'sunken', \n                           'bd'=>2, 'textvariable'=>$currentRoom)\n\n# Choose colors, then fill in the floorplan.\n\n$floor_colors = {}\nif TkWinfo.depth($floor_canvas) > 1\n  $floor_colors['bg1'] = '#a9c1da'\n  $floor_colors['outline1'] = '#77889a'\n  $floor_colors['bg2'] = '#9ab0c6'\n  $floor_colors['outline2'] = '#687786'\n  $floor_colors['bg3'] = '#8ba0b3'\n  $floor_colors['outline3'] = '#596673'\n  $floor_colors['offices'] = 'Black'\n  $floor_colors['active'] = '#c4d1df'\nelse\n  $floor_colors['bg1'] = 'white'\n  $floor_colors['outline1'] = 'black'\n  $floor_colors['bg2'] = 'white'\n  $floor_colors['outline2'] = 'black'\n  $floor_colors['bg3'] = 'white'\n  $floor_colors['outline3'] = 'black'\n  $floor_colors['offices'] = 'Black'\n  $floor_colors['active'] = 'black'\nend\n\n$activeFloor = ''\nfloorDisplay $floor_canvas,3\n\n# Set up event bindings for canvas:\n\n$floor_canvas.itembind('floor1', '1', proc{floorDisplay $floor_canvas,1})\n$floor_canvas.itembind('floor2', '1', proc{floorDisplay $floor_canvas,2})\n$floor_canvas.itembind('floor3', '1', proc{floorDisplay $floor_canvas,3})\n$floor_canvas.itembind('room', 'Enter', proc{newRoom $floor_canvas})\n$floor_canvas.itembind('room', 'Leave', proc{$currentRoom.value = ''})\n$floor_canvas.bind('2', proc{|x,y| $floor_canvas.scan_mark x,y}, '%x %y')\n$floor_canvas.bind('B2-Motion', \n                   proc{|x,y| $floor_canvas.scan_dragto x,y}, '%x %y')\n$floor_canvas.bind('Destroy', proc{$currentRoom.unset})\n$currentRoom.value = ''\n$currentRoom.trace('w',proc{roomChanged $floor_canvas})\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/floor2.rb",
    "content": "%# floor2.rb\n#\n# This demonstration script creates a canvas widet that displays the\n# floorplan for DEC's Western Research Laboratory.\n#\n# floorDisplay widget demo (called by 'widget')\n#\n\n# floorDisplay2 --\n# Recreate the floorplan display in the canvas given by \"w\".  The\n# floor given by \"active\" is displayed on top with its office structure\n# visible.\n#\n# Arguments:\n# w -           Name of the canvas window.\n# active -      Number of active floor (1, 2, or 3).\n\ndef floorDisplay2(w,active)\n  return if $activeFloor2 == active\n\n  w.delete('all')\n  $activeFloor2 = active\n\n  # First go through the three floors, displaying the backgrounds for \n  # each floor.\n\n  floor2_bg1(w,$floor2_colors['bg1'],$floor2_colors['outline1'])\n  floor2_bg2(w,$floor2_colors['bg2'],$floor2_colors['outline2'])\n  floor2_bg3(w,$floor2_colors['bg3'],$floor2_colors['outline3'])\n\n  # Raise the background for the active floor so that it's on top.\n\n  w.raise(\"floor#{active}\")\n\n  # Create a dummy item just to mark this point in the display list, \n  # so we can insert highlights here.\n\n  w.create(TkcRectangle,0,100,1,101,'fill'=>'','outline'=>'','tags'=>'marker')\n\n  # Add the walls and labels for the active floor, along with \n  # transparent polygons that define the rooms on the floor.\n  # Make sure that the room polygons are on top.\n\n  $floorLabels2.clear\n  $floorItems2.clear\n  send(\"floor2_fg#{active}\", w, $floor2_colors['offices'])\n  w.raise('room')\n\n  # Offset the floors diagonally from each other.\n\n  w.move('floor1', '2c', '2c')\n  w.move('floor2', '1c', '1c')\n\n  # Create items for the room entry and its label.\n  w.create(TkcWindow, 600, 100, 'anchor'=>'w', 'window'=>$floor2_entry)\n  w.create(TkcText, 600, 100, 'anchor'=>'e', 'text'=>\"Room: \")\n  w['scrollregion'] = w.bbox('all')\nend\n\n# newRoom2 --\n# This method is invoked whenever the mouse enters a room\n# in the floorplan.  It changes tags so that the current room is\n# highlighted.\n#\n# Arguments:\n# w  -          The name of the canvas window.\n\ndef newRoom2(w)\n  id = w.find_withtag('current')[0]\n  $currentRoom2.value = $floorLabels2[id.id] if id != \"\"\n  Tk.update(true)\nend\n\n# roomChanged2 --\n# This method is invoked whenever the currentRoom variable changes.\n# It highlights the current room and unhighlights any previous room.\n#\n# Arguments:\n# w -           The canvas window displaying the floorplan.\n# args -        Not used.\n\ndef roomChanged2(w,*args)\n  w.delete('highlight')\n  item = $floorItems2[$currentRoom2.value]\n  return if item == nil\n  new = TkcPolygon.new(w, *(w.coords(item)))\n  new.configure('fill'=>$floor2_colors['active'], 'tags'=>'highlight')\n  w.raise(new, 'marker')\nend\n\n# floor2_bg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor2_bg1(w,fill,outline)\n  w.create(TkcPolygon,347,80,349,82,351,84,353,85,363,92,375,99,386,104,\n                 386,129,398,129,398,162,484,162,484,129,559,129,559,133,725,\n                 133,725,129,802,129,802,389,644,389,644,391,559,391,559,327,\n                 508,327,508,311,484,311,484,278,395,278,395,288,400,288,404,\n                 288,409,290,413,292,418,297,421,302,422,309,421,318,417,325,\n                 411,330,405,332,397,333,344,333,340,334,336,336,335,338,332,\n                 342,331,347,332,351,334,354,336,357,341,359,340,360,335,363,\n                 331,365,326,366,304,366,304,355,258,355,258,387,60,387,60,391,\n                 0,391,0,337,3,337,3,114,8,114,8,25,30,25,30,5,93,5,98,5,104,7,\n                 110,10,116,16,119,20,122,28,123,32,123,68,220,68,220,34,221,\n                 22,223,17,227,13,231,8,236,4,242,2,246,0,260,0,283,1,300,5,\n                 321,14,335,22,348,25,365,29,363,39,358,48,352,56,337,70,\n                 344,76,347,80, 'tags'=>['floor1','bg'], 'fill'=>fill)\n  w.create(TkcLine,386,129,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,258,355,258,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,0,337,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,3,114,3,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,162,398,162, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,398,162,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,278,484,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,327,508,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,644,391,559,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,644,389,644,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,725,133,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,725,129,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,802,389,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,3,337,0,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,391,559,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,802,389,644,389, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,8,25,8,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,8,114,3,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,30,25,8,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,278,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,30,25,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,93,5,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,98,5,93,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,104,7,98,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,110,10,104,7, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,116,16,110,10, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,119,20,116,16, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,122,28,119,20, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,123,32,122,28, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,123,68,123,32, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,220,68,123,68, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,386,129,386,104, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,386,104,375,99, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,375,99,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,353,85,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,220,68,220,34, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,337,70,352,56, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,352,56,358,48, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,358,48,363,39, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,363,39,365,29, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,365,29,348,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,348,25,335,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,335,22,321,14, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,321,14,300,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,300,5,283,1, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,283,1,260,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,260,0,246,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,246,0,242,2, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,242,2,236,4, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,236,4,231,8, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,231,8,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,223,17,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,221,22,223,17, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,220,34,221,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,340,360,335,363, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,335,363,331,365, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,331,365,326,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,326,366,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,304,355,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,395,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,404,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,409,290,404,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,413,292,409,290, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,418,297,413,292, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,421,302,418,297, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,422,309,421,302, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,421,318,422,309, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,421,318,417,325, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,417,325,411,330, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,411,330,405,332, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,405,332,397,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,397,333,344,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,344,333,340,334, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,340,334,336,336, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,336,336,335,338, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,335,338,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,331,347,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,332,351,331,347, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,334,354,332,351, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,336,357,334,354, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,341,359,336,357, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,341,359,340,360, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,395,288,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,304,355,258,355, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,347,80,344,76, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,344,76,337,70, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,349,82,347,80, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,351,84,349,82, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,353,85,351,84, 'fill'=>outline, 'tags'=>['floor1','bg'])\nend\n\n# floor2_bg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor2_bg2(w,fill,outline)\n  w.create(TkcPolygon,559,129,484,129,484,162,398,162,398,129,315,129,\n                 315,133,176,133,176,129,96,129,96,133,3,133,3,339,0,339,0,391,\n                 60,391,60,387,258,387,258,329,350,329,350,311,395,311,395,280,\n                 484,280,484,311,508,311,508,327,558,327,558,391,644,391,644,\n                 367,802,367,802,129,725,129,725,133,559,133,559,129,\n                 'tags'=>['floor2','bg'], 'fill'=>fill)\n  w.create(TkcLine,350,311,350,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,398,129,398,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,802,367,802,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,802,129,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,559,133,725,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,802,367,644,367, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,644,367,644,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,644,391,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,558,327,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,558,327,508,327, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,280,484,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,398,162,484,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,280,395,280, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,395,280,395,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,3,133,3,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,3,339,0,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,0,339,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,258,329,258,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,395,311,350,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,398,129,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,176,133,315,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,3,133,96,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,176,133,176,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\nend\n\n# floor2_bg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor2_bg3(w,fill,outline)\n  w.create(TkcPolygon,159,300,107,300,107,248,159,248,159,129,96,129,96,\n                 133,21,133,21,331,0,331,0,391,60,391,60,370,159,370,159,300,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  w.create(TkcPolygon,258,370,258,329,350,329,350,311,399,311,399,129,\n                 315,129,315,133,176,133,176,129,159,129,159,370,258,370,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,176,129,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,315,133,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,399,129,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,399,311,399,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,399,311,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,350,329,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,258,370,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,60,370,258,370, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,60,370,60,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,0,391,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,21,331,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,21,331,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,96,133,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,107,300,159,300,159,248,107,248,107,300, \n              'fill'=>outline, 'tags'=>['floor3','bg'])\nend\n\n# floor2_fg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the first\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor2_fg1(w,color)\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '101'\n  $floorItems2['101'] = i\n  w.create(TkcText,358,209, 'text'=>'101', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Pub Lift1'\n  $floorItems2['Pub Lift1'] = i\n  w.create(TkcText,323,223, 'text'=>'Pub Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Priv Lift1'\n  $floorItems2['Priv Lift1'] = i\n  w.create(TkcText,323,188, 'text'=>'Priv Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,42,389,42,337,1,337,1,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '110'\n  $floorItems2['110'] = i\n  w.create(TkcText,21.5,363, 'text'=>'110', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,59,389,59,385,90,385,90,337,44,337,44,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '109'\n  $floorItems2['109'] = i\n  w.create(TkcText,67,363, 'text'=>'109', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,300,51,253,6,253,6,300, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '111'\n  $floorItems2['111'] = i\n  w.create(TkcText,28.5,276.5, 'text'=>'111', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,98,248,98,309,79,309,79,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '117B'\n  $floorItems2['117B'] = i\n  w.create(TkcText,88.5,278.5, 'text'=>'117B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,251,51,204,6,204,6,251, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '112'\n  $floorItems2['112'] = i\n  w.create(TkcText,28.5,227.5, 'text'=>'112', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,6,156,51,156,51,203,6,203, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '113'\n  $floorItems2['113'] = i\n  w.create(TkcText,28.5,179.5, 'text'=>'113', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,85,169,79,169,79,192,85,192, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '117A'\n  $floorItems2['117A'] = i\n  w.create(TkcText,82,180.5, 'text'=>'117A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,77,302,77,168,53,168,53,302, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '117'\n  $floorItems2['117'] = i\n  w.create(TkcText,65,235, 'text'=>'117', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,155,51,115,6,115,6,155, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '114'\n  $floorItems2['114'] = i\n  w.create(TkcText,28.5,135, 'text'=>'114', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,95,115,53,115,53,168,95,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '115'\n  $floorItems2['115'] = i\n  w.create(TkcText,74,141.5, 'text'=>'115', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,87,113,87,27,10,27,10,113, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '116'\n  $floorItems2['116'] = i\n  w.create(TkcText,48.5,70, 'text'=>'116', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,89,91,128,91,128,113,89,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '118'\n  $floorItems2['118'] = i\n  w.create(TkcText,108.5,102, 'text'=>'118', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,178,128,178,132,216,132,216,91,\n                     163,91,163,112,149,112,149,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '120'\n  $floorItems2['120'] = i\n  w.create(TkcText,189.5,111.5, 'text'=>'120', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,79,193,87,193,87,169,136,169,136,192,\n                     156,192,156,169,175,169,175,246,79,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '122'\n  $floorItems2['122'] = i\n  w.create(TkcText,131,207.5, 'text'=>'122', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,169,154,169,154,191,138,191, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '121'\n  $floorItems2['121'] = i\n  w.create(TkcText,146,180, 'text'=>'121', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,99,300,126,300,126,309,99,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '106A'\n  $floorItems2['106A'] = i\n  w.create(TkcText,112.5,304.5, 'text'=>'106A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,128,299,128,309,150,309,150,248,99,248,99,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '105'\n  $floorItems2['105'] = i\n  w.create(TkcText,124.5,278.5, 'text'=>'105', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,174,309,174,300,152,300,152,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '106B'\n  $floorItems2['106B'] = i\n  w.create(TkcText,163,304.5, 'text'=>'106B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,176,299,176,309,216,309,216,248,152,248,152,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '104'\n  $floorItems2['104'] = i\n  w.create(TkcText,184,278.5, 'text'=>'104', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,385,138,337,91,337,91,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '108'\n  $floorItems2['108'] = i\n  w.create(TkcText,114.5,361, 'text'=>'108', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,256,337,140,337,140,385,256,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '107'\n  $floorItems2['107'] = i\n  w.create(TkcText,198,361, 'text'=>'107', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,300,353,300,329,260,329,260,353, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Smoking'\n  $floorItems2['Smoking'] = i\n  w.create(TkcText,280,341, 'text'=>'Smoking', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,314,135,314,170,306,170,306,246,177,246,177,135, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '123'\n  $floorItems2['123'] = i\n  w.create(TkcText,245.5,190.5, 'text'=>'123', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,217,248,301,248,301,326,257,326,257,310,217,310, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '103'\n  $floorItems2['103'] = i\n  w.create(TkcText,259,287, 'text'=>'103', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,396,188,377,188,377,169,316,169,316,131,396,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '124'\n  $floorItems2['124'] = i\n  w.create(TkcText,356,150, 'text'=>'124', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,226,407,226,407,189,377,189,377,246,397,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '125'\n  $floorItems2['125'] = i\n  w.create(TkcText,392,217.5, 'text'=>'125', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,399,187,409,187,409,207,474,207,474,164,399,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '126'\n  $floorItems2['126'] = i\n  w.create(TkcText,436.5,185.5, 'text'=>'126', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,409,209,409,229,399,229,399,253,\n                     486,253,486,239,474,239,474,209, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '127'\n  $floorItems2['127'] = i\n  w.create(TkcText,436.5,'231', 'text'=>'127', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,501,164,501,174,495,174,495,188,\n                     490,188,490,204,476,204,476,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'MShower'\n  $floorItems2['MShower'] = i\n  w.create(TkcText,488.5,'184', 'text'=>'MShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,497,176,513,176,513,204,492,204,492,190,497,190, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Closet'\n  $floorItems2['Closet'] = i\n  w.create(TkcText,502.5,190, 'text'=>'Closet', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,476,237,476,206,513,206,513,254,488,254,488,237, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'WShower'\n  $floorItems2['WShower'] = i\n  w.create(TkcText,494.5,230, 'text'=>'WShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,486,131,558,131,558,135,724,135,724,166,\n                     697,166,697,275,553,275,531,254,515,254,\n                     515,174,503,174,503,161,486,161, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '130'\n  $floorItems2['130'] = i\n  w.create(TkcText,638.5,205, 'text'=>'130', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,308,242,339,242,339,248,342,248,\n                     342,246,397,246,397,276,393,276,\n                     393,309,300,309,300,248,308,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '102'\n  $floorItems2['102'] = i\n  w.create(TkcText,367.5,278.5, 'text'=>'102', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,255,486,255,486,276,397,276, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '128'\n  $floorItems2['128'] = i\n  w.create(TkcText,441.5,265.5, 'text'=>'128', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,510,309,486,309,486,255,530,255,\n                     552,277,561,277,561,325,510,325,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '129'\n  $floorItems2['129'] = i\n  w.create(TkcText,535.5,293, 'text'=>'129', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,696,281,740,281,740,387,642,387,\n                     642,389,561,389,561,277,696,277, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '133'\n  $floorItems2['133'] = i\n  w.create(TkcText,628.5,335, 'text'=>'133', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,742,387,742,281,800,281,800,387, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '132'\n  $floorItems2['132'] = i\n  w.create(TkcText,771,334, 'text'=>'132', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,800,168,800,280,699,280,699,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '134'\n  $floorItems2['134'] = i\n  w.create(TkcText,749.5,224, 'text'=>'134', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,726,131,726,166,800,166,800,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '135'\n  $floorItems2['135'] = i\n  w.create(TkcText,763,148.5, 'text'=>'135', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,340,360,335,363,331,365,326,366,304,366,\n                     304,312,396,312,396,288,400,288,404,288,\n                     409,290,413,292,418,297,421,302,422,309,\n                     421,318,417,325,411,330,405,332,397,333,\n                     344,333,340,334,336,336,335,338,332,342,\n                     331,347,332,351,334,354,336,357,341,359, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Ramona Stair'\n  $floorItems2['Ramona Stair'] = i\n  w.create(TkcText,368,323, 'text'=>'Ramona Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,30,23,30,5,93,5,98,5,104,7,110,10,116,16,119,20,\n                     122,28,123,32,123,68,220,68,220,87,90,87,90,23, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'University Stair'\n  $floorItems2['University Stair'] = i\n  w.create(TkcText,155,77.5, 'text'=>'University Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,282,37,295,40,312,49,323,56,337,70,352,56,\n                     358,48,363,39,365,29,348,25,335,22,321,14,\n                     300,5,283,1,260,0,246,0,242,2,236,4,231,8,\n                     227,13,223,17,221,22,220,34,260,34, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Plaza Stair'\n  $floorItems2['Plaza Stair'] = i\n  w.create(TkcText,317.5,28.5, 'text'=>'Plaza Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,220,34,260,34,282,37,295,40,312,49,\n                     323,56,337,70,350,83,365,94,377,100,\n                     386,104,386,128,220,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Plaza Deck'\n  $floorItems2['Plaza Deck'] = i\n  w.create(TkcText,303,81, 'text'=>'Plaza Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,257,336,77,336,6,336,6,301,77,301,77,310,257,310,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '106'\n  $floorItems2['106'] = i\n  w.create(TkcText,131.5,318.5, 'text'=>'106', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,146,110,162,110,162,91,130,91,130,115,95,115,\n                     95,128,114,128,114,151,157,151,157,153,112,153,\n                     112,130,97,130,97,168,175,168,175,131,146,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '119'\n  $floorItems2['119'] = i\n  w.create(TkcText,143.5,133, 'text'=>'119', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  w.create(TkcLine,155,191,155,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,96,129,96,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,169,176,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,176,247,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,376,246,376,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,307,247,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,147,129,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,202,133,176,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,352,258,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,0,337,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,3,114,3,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,237,52,273, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,189,52,225, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,140,52,177, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,395,306,395,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,531,254,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,475,178,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,502,162,398,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,398,129,398,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,208,475,208, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,278,484,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,327,508,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,644,391,559,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,644,389,644,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,514,205,475,205, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,496,189,496,187, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,149,725,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,129,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,802,389,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,739,167,802,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,0,337,9,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,58,337,21,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,43,391,43,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,105,337,75,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,91,387,91,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,154,337,117,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,139,387,139,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,227,337,166,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,337,251,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,328,302,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,302,355,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,395,311,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,278,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,395,294,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,473,278,473,275, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,473,256,473,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,533,257,531,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,553,276,551,274, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,698,276,553,276, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,391,559,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,802,389,644,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,741,314,741,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,698,280,698,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,707,280,698,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,802,280,731,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,741,280,741,302, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,698,167,727,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,137,725,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,514,254,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,496,175,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,502,175,502,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,475,166,475,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,496,176,496,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,491,189,496,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,491,205,491,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,487,238,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,487,240,487,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,487,252,487,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,315,133,304,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,256,133,280,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,247,270,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,307,247,294,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,214,133,232,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,217,247,217,266, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,217,309,217,291, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,217,309,172,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,154,309,148,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,175,300,175,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,151,300,175,300, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,151,247,151,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,237,78,265, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,286,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,106,309,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,130,309,125,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,99,309,99,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,127,299,99,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,127,309,127,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,155,191,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,137,169,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,171,78,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,190,78,218, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,86,192,86,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,86,192,78,192, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,301,3,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,286,52,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,252,3,252, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,203,3,203, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,3,156,52,156, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,8,25,8,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,63,114,3,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,75,114,97,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,108,114,129,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,129,114,129,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,114,52,128, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,132,89,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,88,25,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,88,114,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,218,89,144,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,147,111,147,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,162,111,147,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,162,109,162,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,162,96,162,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,218,89,218,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,218,89,218,119, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,8,25,88,25, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,337,258,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,129,96,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,302,355,258,355, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,386,104,386,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,377,100,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,365,94,377,100, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,350,83,365,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,337,70,350,83, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,337,70,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,312,49,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,295,40,312,49, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,282,37,295,40, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,260,34,282,37, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,253,34,260,34, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,386,128,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,152,113,129, 'fill'=>color, 'tags'=>['floor1','wall'])\nend\n\n# floor2_fg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the second\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor2_fg2(w,color)\n  i = TkcPolygon.new(w,748,188,755,188,755,205,758,205,758,222,\n                     800,222,800,168,748,168, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '238'\n  $floorItems2['238'] = i\n  w.create(TkcText,774,195, 'text'=>'238', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,726,188,746,188,746,166,800,166,800,131,726,131,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '237'\n  $floorItems2['237'] = i\n  w.create(TkcText,763,148.5, 'text'=>'237', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,497,187,497,204,559,204,559,324,641,324,\n                     643,324,643,291,641,291,641,205,696,205,\n                     696,291,694,291,694,314,715,314,715,291,\n                     715,205,755,205,755,190,724,190,724,187, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '246'\n  $floorItems2['246'] = i\n  w.create(TkcText,600,264, 'text'=>'246', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,694,279,643,279,643,314,694,314, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '247'\n  $floorItems2['247'] = i\n  w.create(TkcText,668.5,296.5, 'text'=>'247', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,232,250,308,250,308,242,339,242,339,246,\n                     397,246,397,255,476,255,476,250,482,250,559,250,\n                     559,274,482,274,482,278,396,278,396,274,232,274, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '202'\n  $floorItems2['202'] = i\n  w.create(TkcText,285.5,260, 'text'=>'202', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,53,228,53,338,176,338,233,338,233,196,\n                     306,196,306,180,175,180,175,169,156,169,\n                     156,196,176,196,176,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '206'\n  $floorItems2['206'] = i\n  w.create(TkcText,143,267, 'text'=>'206', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,277,6,277,6,338,51,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '212'\n  $floorItems2['212'] = i\n  w.create(TkcText,28.5,307.5, 'text'=>'212', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,276,486,276,486,309,510,309,510,325,557,325, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '245'\n  $floorItems2['245'] = i\n  w.create(TkcText,521.5,300.5, 'text'=>'245', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,560,389,599,389,599,326,560,326, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '244'\n  $floorItems2['244'] = i\n  w.create(TkcText,579.5,357.5, 'text'=>'244', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,601,389,601,326,643,326,643,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '243'\n  $floorItems2['243'] = i\n  w.create(TkcText,622,357.5, 'text'=>'243', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,688,316,645,316,645,365,688,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '242'\n  $floorItems2['242'] = i\n  w.create(TkcText,666.5,340.5, 'text'=>'242', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,802,367,759,367,759,226,802,226, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = 'Barbecue Deck'\n  $floorItems2['Barbecue Deck'] = i\n  w.create(TkcText,780.5,296.5, 'text'=>'Barbecue Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,262,755,314,717,314,717,262, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '240'\n  $floorItems2['240'] = i\n  w.create(TkcText,736,288, 'text'=>'240', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,316,689,316,689,365,755,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '241'\n  $floorItems2['241'] = i\n  w.create(TkcText,722,340.5, 'text'=>'241', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,206,717,206,717,261,755,261, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '239'\n  $floorItems2['239'] = i\n  w.create(TkcText,736,233.5, 'text'=>'239', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,695,277,643,277,643,206,695,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '248'\n  $floorItems2['248'] = i\n  w.create(TkcText,669,241.5, 'text'=>'248', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,676,135,676,185,724,185,724,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '236'\n  $floorItems2['236'] = i\n  w.create(TkcText,700,160, 'text'=>'236', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,675,135,635,135,635,145,628,145,628,185,675,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '235'\n  $floorItems2['235'] = i\n  w.create(TkcText,651.5,160, 'text'=>'235', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,626,143,633,143,633,135,572,135,\n                     572,143,579,143,579,185,626,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '234'\n  $floorItems2['234'] = i\n  w.create(TkcText,606,160, 'text'=>'234', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,135,571,135,571,145,578,145,\n                     578,185,527,185,527,131,557,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '233'\n  $floorItems2['233'] = i\n  w.create(TkcText,552.5,158, 'text'=>'233', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,249,557,249,557,205,476,205,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '230'\n  $floorItems2['230'] = i\n  w.create(TkcText,516.5,227, 'text'=>'230', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,164,486,164,486,131,525,131,525,185,476,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '232'\n  $floorItems2['232'] = i\n  w.create(TkcText,500.5,158, 'text'=>'232', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,186,495,186,495,204,476,204, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '229'\n  $floorItems2['229'] = i\n  w.create(TkcText,485.5,195, 'text'=>'229', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,474,207,409,207,409,187,399,187,399,164,474,164, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '227'\n  $floorItems2['227'] = i\n  w.create(TkcText,436.5,185.5, 'text'=>'227', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,399,228,399,253,474,253,474,209,409,209,409,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '228'\n  $floorItems2['228'] = i\n  w.create(TkcText,436.5,231, 'text'=>'228', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,397,246,397,226,407,226,407,189,377,189,377,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '226'\n  $floorItems2['226'] = i\n  w.create(TkcText,392,217.5, 'text'=>'226', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,377,169,316,169,316,131,397,131,397,188,377,188, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '225'\n  $floorItems2['225'] = i\n  w.create(TkcText,356.5,150, 'text'=>'225', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,198,306,198,306,249,234,249, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '224'\n  $floorItems2['224'] = i\n  w.create(TkcText,270,223.5, 'text'=>'224', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,270,179,306,179,306,170,314,170,314,135,270,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '223'\n  $floorItems2['223'] = i\n  w.create(TkcText,292,157, 'text'=>'223', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,268,179,221,179,221,135,268,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '222'\n  $floorItems2['222'] = i\n  w.create(TkcText,244.5,157, 'text'=>'222', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,177,179,219,179,219,135,177,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '221'\n  $floorItems2['221'] = i\n  w.create(TkcText,198,157, 'text'=>'221', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,299,327,349,327,349,284,341,284,341,276,299,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '204'\n  $floorItems2['204'] = i\n  w.create(TkcText,324,301.5, 'text'=>'204', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,276,297,276,297,327,257,327,257,338,234,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '205'\n  $floorItems2['205'] = i\n  w.create(TkcText,265.5,307, 'text'=>'205', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,256,385,256,340,212,340,212,385,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '207'\n  $floorItems2['207'] = i\n  w.create(TkcText,234,362.5, 'text'=>'207', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,210,340,164,340,164,385,210,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '208'\n  $floorItems2['208'] = i\n  w.create(TkcText,187,362.5, 'text'=>'208', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,115,340,162,340,162,385,115,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '209'\n  $floorItems2['209'] = i\n  w.create(TkcText,138.5,362.5, 'text'=>'209', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,228,89,156,53,156,53,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '217'\n  $floorItems2['217'] = i\n  w.create(TkcText,71,192, 'text'=>'217', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,169,97,169,97,190,89,190, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '217A'\n  $floorItems2['217A'] = i\n  w.create(TkcText,93,179.5, 'text'=>'217A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,156,89,168,95,168,95,135,53,135,53,156, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '216'\n  $floorItems2['216'] = i\n  w.create(TkcText,71,145.5, 'text'=>'216', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,179,51,135,6,135,6,179, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '215'\n  $floorItems2['215'] = i\n  w.create(TkcText,28.5,157, 'text'=>'215', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,227,6,227,6,180,51,180, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '214'\n  $floorItems2['214'] = i\n  w.create(TkcText,28.5,203.5, 'text'=>'214', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,275,6,275,6,229,51,229, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '213'\n  $floorItems2['213'] = i\n  w.create(TkcText,28.5,252, 'text'=>'213', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,114,340,67,340,67,385,114,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '210'\n  $floorItems2['210'] = i\n  w.create(TkcText,90.5,362.5, 'text'=>'210', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,59,389,59,385,65,385,65,340,1,340,1,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '211'\n  $floorItems2['211'] = i\n  w.create(TkcText,33,364.5, 'text'=>'211', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,393,309,350,309,350,282,342,282,342,276,393,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '203'\n  $floorItems2['203'] = i\n  w.create(TkcText,367.5,292.5, 'text'=>'203', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,99,191,91,191,91,226,174,226,174,198,\n                     154,198,154,192,109,192,109,169,99,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '220'\n  $floorItems2['220'] = i\n  w.create(TkcText,132.5,208.5, 'text'=>'220', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = 'Priv Lift2'\n  $floorItems2['Priv Lift2'] = i\n  w.create(TkcText,323,188, 'text'=>'Priv Lift2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = 'Pub Lift 2'\n  $floorItems2['Pub Lift 2'] = i\n  w.create(TkcText,323,223, 'text'=>'Pub Lift 2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '218'\n  $floorItems2['218'] = i\n  w.create(TkcText,136,149.5, 'text'=>'218', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '219'\n  $floorItems2['219'] = i\n  w.create(TkcText,132.5,180, 'text'=>'219', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '201'\n  $floorItems2['201'] = i\n  w.create(TkcText,358,209, 'text'=>'201', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  w.create(TkcLine,641,186,678,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,350,757,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,634,133,634,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,634,144,627,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,572,133,572,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,572,144,579,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,129,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,174,197,175,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,175,197,175,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,206,757,221, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,727,189,725,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,747,167,802,167, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,747,167,747,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,755,189,739,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,769,224,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,802,224,802,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,802,129,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,725,189,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,725,186,690,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,676,133,676,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,627,144,627,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,629,186,593,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,579,144,579,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,526,129,526,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,540,186,581,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,528,186,523,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,511,186,475,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,496,190,496,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,496,205,496,202, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,475,205,527,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,205,539,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,205,558,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,249,475,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,662,206,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,695,206,675,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,695,278,642,278, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,642,291,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,695,291,695,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,716,208,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,206,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,221,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,793,224,802,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,262,716,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,716,220,716,264, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,716,315,716,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,315,703,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,325,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,367,644,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,689,367,689,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,647,315,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,659,315,691,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,600,325,600,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,627,325,644,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,644,391,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,615,325,575,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,644,391,558,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,563,325,558,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,391,558,314, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,327,508,327, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,275,484,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,302,558,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,275,484,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,475,208,408,208, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,188,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,162,484,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,475,162,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,254,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,280,395,280, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,395,311,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,307,197,293,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,278,197,233,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,233,197,233,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,307,179,284,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,233,249,278,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,269,179,269,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,220,179,220,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,155,191,110,191, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,90,190,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,98,169,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,133,52,165, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,214,52,177, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,226,52,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,274,52,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,234,275,234,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,226,339,258,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,211,387,211,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,214,339,177,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,3,133,3,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,165,339,129,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,117,339,80,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,68,339,59,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,0,339,46,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,0,339,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,258,329,258,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,395,311,350,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,176,133,315,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,3,133,96,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,66,387,66,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,115,387,115,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,163,387,163,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,234,275,276,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,288,275,309,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,321,275,341,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,375,275,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,376,245,376,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,245,340,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,293,250,307,250, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,271,179,238,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,226,179,195,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,174,169,176,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,162,169,90,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,96,169,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,175,227,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,90,190,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,179,3,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,228,3,228, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,276,3,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,110,191,110,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,155,189,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor2','wall'])\nend\n\n# floor2_fg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the third\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor2_fg3(w,color)\n  i = TkcPolygon.new(w,89,228,89,180,70,180,70,228,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '316'\n  $floorItems2['316'] = i\n  w.create(TkcText,79.5,204, 'text'=>'316', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,115,368,162,368,162,323,115,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '309'\n  $floorItems2['309'] = i\n  w.create(TkcText,138.5,345.5, 'text'=>'309', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,164,323,164,368,211,368,211,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '308'\n  $floorItems2['308'] = i\n  w.create(TkcText,187.5,345.5, 'text'=>'308', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,256,368,212,368,212,323,256,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '307'\n  $floorItems2['307'] = i\n  w.create(TkcText,234,345.5, 'text'=>'307', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,244,276,297,276,297,327,260,327,260,321,244,321, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '305'\n  $floorItems2['305'] = i\n  w.create(TkcText,270.5,301.5, 'text'=>'305', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,219,251,203,244,203,244,219,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '324B'\n  $floorItems2['324B'] = i\n  w.create(TkcText,247.5,211, 'text'=>'324B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,249,244,249,244,232,251,232, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '324A'\n  $floorItems2['324A'] = i\n  w.create(TkcText,247.5,240.5, 'text'=>'324A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,223,135,223,179,177,179,177,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '320'\n  $floorItems2['320'] = i\n  w.create(TkcText,200,157, 'text'=>'320', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,114,368,114,323,67,323,67,368, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '310'\n  $floorItems2['310'] = i\n  w.create(TkcText,90.5,345.5, 'text'=>'310', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,277,23,321,68,321,68,277, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '312'\n  $floorItems2['312'] = i\n  w.create(TkcText,45.5,299, 'text'=>'312', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,229,68,229,68,275,23,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '313'\n  $floorItems2['313'] = i\n  w.create(TkcText,45.5,252, 'text'=>'313', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,68,227,23,227,23,180,68,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '314'\n  $floorItems2['314'] = i\n  w.create(TkcText,40.5,203.5, 'text'=>'314', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,95,179,95,135,23,135,23,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '315'\n  $floorItems2['315'] = i\n  w.create(TkcText,59,157, 'text'=>'315', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,99,226,99,204,91,204,91,226, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '316B'\n  $floorItems2['316B'] = i\n  w.create(TkcText,95,215, 'text'=>'316B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,91,202,99,202,99,180,91,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '316A'\n  $floorItems2['316A'] = i\n  w.create(TkcText,95,191, 'text'=>'316A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,97,169,109,169,109,192,154,192,154,198,\n                     174,198,174,226,101,226,101,179,97,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '319'\n  $floorItems2['319'] = i\n  w.create(TkcText,141.5,209, 'text'=>'319', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,65,368,58,368,58,389,1,389,1,333,23,333,23,323,65,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '311'\n  $floorItems2['311'] = i\n  w.create(TkcText,29.5,361, 'text'=>'311', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '318'\n  $floorItems2['318'] = i\n  w.create(TkcText,132.5,180, 'text'=>'318', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '317'\n  $floorItems2['317'] = i\n  w.create(TkcText,136,149.5, 'text'=>'317', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,274,194,274,221,306,221,306,194, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '323'\n  $floorItems2['323'] = i\n  w.create(TkcText,290,207.5, 'text'=>'323', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,306,222,274,222,274,249,306,249, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '325'\n  $floorItems2['325'] = i\n  w.create(TkcText,290,235.5, 'text'=>'325', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,263,179,224,179,224,135,263,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '321'\n  $floorItems2['321'] = i\n  w.create(TkcText,243.5,157, 'text'=>'321', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,314,169,306,169,306,192,273,192,\n                     264,181,264,135,314,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '322'\n  $floorItems2['322'] = i\n  w.create(TkcText,293.5,163.5, 'text'=>'322', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = 'Pub Lift3'\n  $floorItems2['Pub Lift3'] = i\n  w.create(TkcText,323,223, 'text'=>'Pub Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = 'Priv Lift3'\n  $floorItems2['Priv Lift3'] = i\n  w.create(TkcText,323,188, 'text'=>'Priv Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,350,284,376,284,376,276,397,276,397,309,350,309, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '303'\n  $floorItems2['303'] = i\n  w.create(TkcText,373.5,292.5, 'text'=>'303', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,272,203,272,249,252,249,252,230,\n                     244,230,244,221,252,221,252,203, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '324'\n  $floorItems2['324'] = i\n  w.create(TkcText,262,226, 'text'=>'324', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,299,276,299,327,349,327,349,284,341,284,341,276, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '304'\n  $floorItems2['304'] = i\n  w.create(TkcText,324,301.5, 'text'=>'304', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '301'\n  $floorItems2['301'] = i\n  w.create(TkcText,358,209, 'text'=>'301', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,397,246,377,246,377,185,397,185, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '327'\n  $floorItems2['327'] = i\n  w.create(TkcText,387,215.5, 'text'=>'327', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,316,131,316,169,377,169,377,185,397,185,397,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '326'\n  $floorItems2['326'] = i\n  w.create(TkcText,365.5,150, 'text'=>'326', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,308,251,242,251,242,274,342,274,342,282,375, 282,\n                     375,274,397,274,397,248,339,248,339,242,308,242, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '302'\n  $floorItems2['302'] = i\n  w.create(TkcText,319.5,261, 'text'=>'302', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,70,321,242,321,242,200,259,200,259,203,272,203,\n                     272,193,263,180,242,180,175,180,175,169,156,169,\n                     156,196,177,196,177,228,107,228,70,228,70,275,107,275,\n                     107,248,160,248,160,301,107,301,107,275,70,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '306'\n  $floorItems2['306'] = i\n  w.create(TkcText,200.5,284.5, 'text'=>'306', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,396,247,399,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,399,129,399,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,202,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,251,231,243,231, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,220,251,220, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,250,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,155,197,155,190, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,110,192,110,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,155,192,110,192, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,176,197,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,69,280,69,274, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,276,69,276, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,69,262,69,226, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,228,69,228, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,179,75,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,69,179,69,214, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,220,90,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,204,90,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,203,100,203, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,187,90,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,227,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,100,179,100,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,100,179,87,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,96,179,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,162,169,96,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,173,169,176,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,195,179,226,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,224,133,224,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,264,179,264,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,238,179,264,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,207,273,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,235,273,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,224,273,219, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,193,307,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,222,307,222, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,384,247,376,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,247,376,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,283,366,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,283,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,399,275,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,341,275,320,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,308,275,298,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,322,243,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,275,284,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,322,226,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,212,370,212,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,214,322,177,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,163,370,163,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,165,322,129,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,84,322,117,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,71,322,64,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,115,322,115,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,66,322,66,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,52,322,21,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,331,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,331,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,96,133,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,315,133,176,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,315,129,399,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,399,311,350,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,322,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,60,370,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,60,370,60,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,0,391,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,307,250,307,242, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,250,243,250, 'fill'=>color, 'tags'=>['floor3','wall'])\nend\n\n# Below is the \"main program\" that creates the floorplan demonstration.\n\n# toplevel widget\nif defined?($floor2_demo) && $floor2_demo\n  $floor2_demo.destroy \n  $floor2_demo = nil\nend\n\n# demo toplevel widget\n$floor2_demo = TkToplevel.new {|w|\n  title(\"Floorplan Canvas Demonstration 2\")\n  iconname(\"Floorplan2\")\n  positionWindow(w)\n  geometry('+20+20')\n  minsize(100,100)\n}\n\nbase_frame = TkFrame.new($floor2_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', \n            'text'=>\"This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory.  It has three levels.  At any given time one of the levels is active, meaning that you can see its room structure.  To activate a level, click the left mouse button anywhere on it.  As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \\\"Room:\\\" entry.  You can also type a room number in the entry and the room will light up.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$floor2_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $floor2_demo\n      $floor2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'floor2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$floor2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# \n$floorLabels2 = {}\n$floorItems2 = {}\n\n# canvas \nif $tk_version =~ /^4\\.[01]/\n  $floor2_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken',\n                                    'highlightthickness'=>2)\n  $floor2_canvas = TkCanvas.new($floor2_canvas_frame, \n                               'width'=>900, 'height'=>500, 'borderwidth'=>0, \n                               'highlightthickness'=>0) {|c|\n    TkScrollbar.new(base_frame, 'orient'=>'horiz', \n                    'command'=>proc{|*args| c.xview(*args)}){|hs|\n      c.xscrollcommand(proc{|first,last| hs.set first,last})\n      pack('side'=>'bottom', 'fill'=>'x')\n    }\n    TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs|\n      c.yscrollcommand(proc{|first,last| vs.set first,last})\n      pack('side'=>'right', 'fill'=>'y')\n    }\n  }\n  $floor2_canvas_frame.pack('side'=>'top','fill'=>'both', 'expand'=>'yes')\n  $floor2_canvas.pack('expand'=>'yes', 'fill'=>'both')\n\nelse\n  TkFrame.new(base_frame) {|f|\n    pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\n    h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal')\n    v = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'vertical')\n\n    TkFrame.new(f, 'bd'=>2, 'relief'=>'sunken') {|f1|\n      $floor2_canvas = TkCanvas.new(f1, 'width'=>900, 'height'=>500, \n                                   'borderwidth'=>0, \n                                   'highlightthickness'=>0) {\n        xscrollcommand(proc{|first,last| h.set first,last})\n        yscrollcommand(proc{|first,last| v.set first,last})\n        pack('expand'=>'yes', 'fill'=>'both')\n      }\n      grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    }\n\n    v.grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    h.grid('padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n\n    TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n\n    pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n\n    v.command(proc{|*args| $floor2_canvas.yview(*args)})\n    h.command(proc{|*args| $floor2_canvas.xview(*args)})\n  }\nend\n\n\n# Create an entry for displaying and typing in current room.\n\n$currentRoom2 = TkVariable.new\n$floor2_entry = TkEntry.new($floor2_canvas, 'width'=>10, 'relief'=>'sunken', \n                           'bd'=>2, 'textvariable'=>$currentRoom2)\n\n# Choose colors, then fill in the floorplan.\n\n$floor2_colors = {}\nif TkWinfo.depth($floor2_canvas) > 1\n  $floor2_colors['bg1'] = '#a9c1da'\n  $floor2_colors['outline1'] = '#77889a'\n  $floor2_colors['bg2'] = '#9ab0c6'\n  $floor2_colors['outline2'] = '#687786'\n  $floor2_colors['bg3'] = '#8ba0b3'\n  $floor2_colors['outline3'] = '#596673'\n  $floor2_colors['offices'] = 'Black'\n  $floor2_colors['active'] = '#c4d1df'\nelse\n  $floor2_colors['bg1'] = 'white'\n  $floor2_colors['outline1'] = 'black'\n  $floor2_colors['bg2'] = 'white'\n  $floor2_colors['outline2'] = 'black'\n  $floor2_colors['bg3'] = 'white'\n  $floor2_colors['outline3'] = 'black'\n  $floor2_colors['offices'] = 'Black'\n  $floor2_colors['active'] = 'black'\nend\n\n$activeFloor2 = ''\nfloorDisplay2 $floor2_canvas,3\n\n# Set up event bindings for canvas:\n\n$floor2_canvas.itembind('floor1', '1', proc{floorDisplay2 $floor2_canvas,1})\n$floor2_canvas.itembind('floor2', '1', proc{floorDisplay2 $floor2_canvas,2})\n$floor2_canvas.itembind('floor3', '1', proc{floorDisplay2 $floor2_canvas,3})\n$floor2_canvas.itembind('room', 'Enter', proc{newRoom2 $floor2_canvas})\n$floor2_canvas.itembind('room', 'Leave', proc{$currentRoom2.value = ''})\n$floor2_canvas.bind('2', proc{|x,y| $floor2_canvas.scan_mark x,y}, '%x %y')\n$floor2_canvas.bind('B2-Motion', \n                   proc{|x,y| $floor2_canvas.scan_dragto x,y}, '%x %y')\n$floor2_canvas.bind('Destroy', proc{$currentRoom2.unset})\n$currentRoom2.value = ''\n$currentRoom2.trace('w',proc{roomChanged2 $floor2_canvas})\n"
  },
  {
    "path": "ext/tk/sample/demos-en/form.rb",
    "content": "#\n# form widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($form_demo) && $form_demo\n  $form_demo.destroy \n  $form_demo = nil\nend\n\n# demo toplevel widget\n$form_demo = TkToplevel.new {|w|\n  title(\"Form Demonstration\")\n  iconname(\"form\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($form_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"This window contains a simple form where you can type in the various entries and use tabs to move circularly between the entries.\"\n}\nmsg.pack('side'=>'top', 'fill'=>'x')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $form_demo\n      $form_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'form'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# entry \nform_data = []\n(1..5).each{|i|\n  f = TkFrame.new(base_frame, 'bd'=>2)\n  e = TkEntry.new(f, 'relief'=>'sunken', 'width'=>40)\n  l = TkLabel.new(f)\n  e.pack('side'=>'right')\n  l.pack('side'=>'left')\n  form_data[i] = {'frame'=>f, 'entry'=>e, 'label'=>l}\n}\n\n# \nform_data[1]['label'].text('Name:')\nform_data[2]['label'].text('Address:')\nform_data[5]['label'].text('Phone:')\n\n# pack\n(1..5).each{|i| form_data[i]['frame'].pack('side'=>'top', 'fill'=>'x')}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/goldberg.rb",
    "content": "#\n# Ruby/Tk Goldverg demo (called by 'widget')\n#\n# Based on Tcl/Tk8.5a2 widget demos.\n# The following is the original comment of TkGoldberg.tcl.\n#\n#>>##+#################################################################\n#>>#\n#>># TkGoldberg.tcl\n#>># by Keith Vetter, March 13, 2003\n#>>#\n#>># \"Man will always find a difficult means to perform a simple task\"\n#>># Rube Goldberg\n#>>#\n#>># Reproduced here with permission.\n#>>#\n#>>##+#################################################################\n#>>#\n#>># Keith Vetter 2003-03-21: this started out as a simple little program\n#>># but was so much fun that it grew and grew. So I apologize about the\n#>># size but I just couldn't resist sharing it.\n#>>#\n#>># This is a whizzlet that does a Rube Goldberg type animation, the\n#>># design of which comes from an New Years e-card from IncrediMail.\n#>># That version had nice sound effects which I eschewed. On the other\n#>># hand, that version was in black and white (actually dark blue and\n#>># light blue) and this one is fully colorized.\n#>>#\n#>># One thing I learned from this project is that drawing filled complex\n#>># objects on a canvas is really hard. More often than not I had to\n#>># draw each item twice--once with the desired fill color but no\n#>># outline, and once with no fill but with the outline. Another trick\n#>># is erasing by drawing with the background color. Having a flood fill\n#>># command would have been extremely helpful.\n#>>#\n#>># Two wiki pages were extremely helpful: Drawing rounded rectangles\n#>># which I generalized into Drawing rounded polygons, and regular\n#>># polygons which allowed me to convert ovals and arcs into polygons\n#>># which could then be rotated (see Canvas Rotation). I also wrote\n#>># Named Colors to aid in the color selection.\n#>>#\n#>># I could comment on the code, but it's just 26 state machines with\n#>># lots of canvas create and move calls.\n\nif defined?($goldberg_demo) && $goldberg_demo\n  $goldberg_demo.destroy \n  $goldberg_demo = nil\nend\n\n# demo toplevel widget\n$goldberg_demo = TkToplevel.new {|w|\n  title(\"Tk Goldberg (demonstration)\")\n  iconname(\"goldberg\")\n#  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($goldberg_demo).pack(:fill=>:both, :expand=>true)\n\n=begin\n# label\nmsg = TkLabel.new($goldberg_demo) {\n  font 'Arial 10'\n  wraplength '4i'\n  justify 'left'\n  text \"This is a demonstration of just how complex you can make your animations become. Click the ball to start things moving!\\n\\n\\\"Man will always find a difficult means to perform a simple task\\\"\\n - Rube Goldberg\"\n}\nmsg.pack('side'=>'top')\n=end\n\n=begin\n# frame\nTkFrame.new($goldberg_demo) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $goldberg_demo\n      $goldberg_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Code'\n    command proc{showCode 'goldberg'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n=end\n\n#########################################\n\nclass TkGoldberg_Demo\n  def initialize(parent)\n    @parent = parent\n\n    @S = {}\n    @S['title']   = 'Tk Goldberg'\n    @S['speed']   = TkVariable.new(5)\n    @S['cnt']     = TkVariable.new(0)\n    @S['message'] = TkVariable.new(\"\\\\nWelcome\\\\nto\\\\nRuby/Tk\")\n    @S['pause']   = TkVariable.new\n    @S['details'] = TkVariable.new(true)\n\n    @S['mode'] = TkVariable.new(:MSTART, :symbol) \n    #            :MSTART, :MGO, :MPAUSE, :MSSTEP, :MBSTEP, :MDONE, :MDEBUG\n\n    #         0,  1,  2,  3,  4,  5,   6,   7,   8,   9,  10\n    @speed = [1, 10, 20, 50, 80, 100, 150, 200, 300, 400, 500]\n\n    # colors\n    @C = {}\n    @C['fg'] = 'black'\n    # @C['bg'] = 'gray75'\n    @C['bg'] = 'cornflowerblue'\n\n    @C['0'] = 'white';         @C['1a'] = 'darkgreen';   @C['1b'] = 'yellow'\n    @C['2'] = 'red';           @C['3a'] = 'green';       @C['3b'] = 'darkblue'\n    @C['4'] = @C['fg'];        @C['5a'] = 'brown';       @C['5b'] = 'white'\n    @C['6'] = 'magenta';       @C['7'] = 'green';        @C['8'] = @C['fg']\n    @C['9'] = 'blue4';         @C['10a'] = 'white';      @C['10b'] = 'cyan'\n    @C['11a'] = 'yellow';      @C['11b'] = 'mediumblue'; @C['12'] = 'tan2'\n    @C['13a'] = 'yellow';      @C['13b'] = 'red';        @C['14'] = 'white'\n    @C['15a'] = 'green';       @C['15b'] = 'yellow';     @C['16'] = 'gray65'\n    @C['17'] = '#A65353';     @C['18'] = @C['fg'];      @C['19'] = 'gray50'\n    @C['20'] = 'cyan';         @C['21'] = 'gray65';      @C['22'] = @C['20']\n    @C['23a'] = 'blue';        @C['23b'] = 'red';        @C['23c'] = 'yellow'\n    @C['24a'] = 'red';         @C['24b'] = 'white';\n\n    @STEP = TkVariable.new_hash\n    @STEP.default_value_type = :numeric\n\n    @XY = {}\n\n    @XY6 = {\n      '-1'=>[366, 207], '-2'=>[349, 204], '-3'=>[359, 193], '-4'=>[375, 192], \n      '-5'=>[340, 190], '-6'=>[349, 177], '-7'=>[366, 177], '-8'=>[380, 176],\n      '-9'=>[332, 172], '-10'=>[342, 161], '-11'=>[357, 164], \n      '-12'=>[372, 163], '-13'=>[381, 149], '-14'=>[364, 151], \n      '-15'=>[349, 146], '-16'=>[333, 148], '0'=>[357, 219], \n      '1'=>[359, 261], '2'=>[359, 291], '3'=>[359, 318], '4'=>[361, 324], \n      '5'=>[365, 329], '6'=>[367, 334], '7'=>[367, 340], '8'=>[366, 346], \n      '9'=>[364, 350], '10'=>[361, 355], '11'=>[359, 370], '12'=>[359, 391], \n      '13,0'=>[360, 456], '13,1'=>[376, 456], '13,2'=>[346, 456], \n      '13,3'=>[330, 456], '13,4'=>[353, 444], '13,5'=>[368, 443], \n      '13,6'=>[339, 442], '13,7'=>[359, 431], '13,8'=>[380, 437], \n      '13,9'=>[345, 428], '13,10'=>[328, 434], '13,11'=>[373, 424], \n      '13,12'=>[331, 420], '13,13'=>[360, 417], '13,14'=>[345, 412], \n      '13,15'=>[376, 410], '13,16'=>[360, 403]\n    }\n\n    @timer = TkTimer.new(@speed[@S['speed'].numeric]){|timer|\n      timer.set_interval(go)\n    }\n\n    do_display\n    reset\n\n    # Start everything going\n    @timer.start\n  end\n\n  def do_display()\n    @ctrl = TkFrame.new(@parent, :relief=>:ridge, :bd=>2, :padx=>5, :pady=>5)\n    @screen = TkFrame.new(@parent, :bd=>2, \n                         :relief=>:raised).pack(:side=>:left, :fill=>:both, \n                                                :expand=>true)\n\n    @canvas = TkCanvas.new(@parent, :width=>850, :height=>700, \n                          :bg=>@C['bg'], :highlightthickness=>0){\n      scrollregion([0, 0, 1000, 1000]) # Kludge to move everything up\n      yview_moveto(0.05)\n    }.pack(:in=>@screen, :side=>:top, :fill=>:both, :expand=>true)\n\n    @canvas.bind('3'){ @pause.invoke }\n    @canvas.bind('Destroy'){ @timer.stop }\n\n    do_ctrl_frame\n    do_detail_frame\n\n    # msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') {\n    msg = Tk::Label.new(@parent, :bg=>@C['bg'], :fg=>'white') {\n      font 'Arial 10'\n      wraplength 600\n      justify 'left'\n      text \"This is a demonstration of just how complex you can make your animations become. Click the ball to start things moving!\\n\\\"Man will always find a difficult means to perform a simple task\\\" - Rube Goldberg\"\n    }\n    msg.place(:in=>@canvas, :relx=>0, :rely=>0, :anchor=>:nw)\n\n    frame = TkFrame.new(@parent, :bg=>@C['bg'])\n\n    # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n    Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n      text 'Dismiss'\n      command proc{\n        tmppath = $goldberg_demo\n        $goldberg_demo = nil\n        tmppath.destroy\n      }\n    }.pack('side'=>'left')\n\n    # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n    Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n      text 'See Code'\n      command proc{showCode 'goldberg'}\n    }.pack('side'=>'left', 'padx'=>5)\n\n    # @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl}, \n    @show = Tk::Button.new(frame, :text=>'>>', :command=>proc{show_ctrl}, \n                         :bg=>@C['bg'], :activebackground=>@C['bg'])\n    @show.pack('side'=>'left')\n    frame.place(:in=>@canvas, :relx=>1, :rely=>0, :anchor=>:ne)\n\n    Tk.update\n  end\n\n  def do_ctrl_frame\n    @start = Tk::Button.new(@parent, :text=>'Start', :bd=>6, \n                          :command=>proc{do_button(0)})\n    if font = @start['font']\n      @start.font(font.weight('bold'))\n    end\n\n    @pause = TkCheckbutton.new(@parent, :text=>'Pause', :font=>font, \n                               :command=>proc{do_button(1)}, :relief=>:raised, \n                               :variable=>@S['pause'])\n\n    @step  = TkButton.new(@parent, :text=>'Single Step', :font=>font, \n                          :command=>proc{do_button(2)})\n    @bstep = TkButton.new(@parent, :text=>'Big Step', :font=>font, \n                          :command=>proc{do_button(4)})\n    @reset = TkButton.new(@parent, :text=>'Reset', :font=>font, \n                          :command=>proc{do_button(3)})\n\n    @details = TkFrame.new(@parent, :bd=>2, :relief=>:ridge)\n    @detail = TkCheckbutton.new(@parent, :text=>'Details', :font=>font, \n                               :relief=>:raised, :variable=>@S['details'])\n\n    @msg_entry = TkEntry.new(@parent, :textvariable=>@S['message'], \n                             :justify=>:center)\n    @speed_scale = TkScale.new(@parent, :orient=>:horizontal, \n                               :from=>1, :to=>10, :font=>font, \n                               :variable=>@S['speed'], :bd=>2, \n                               :relief=>:ridge, :showvalue=>false)\n    @about = TkButton.new(@parent, :text=>'About', \n                          :command=>proc{about}, :font=>font)\n\n    Tk.grid(@start, :in=>@ctrl, :row=>0, :sticky=>:ew)\n    @ctrl.grid_rowconfigure(1, :minsize=>10)\n    Tk.grid(@pause, :in=>@ctrl, :row=>2, :sticky=>:ew)\n    Tk.grid(@step,  :in=>@ctrl, :sticky=>:ew)\n    Tk.grid(@bstep, :in=>@ctrl, :sticky=>:ew)\n    Tk.grid(@reset, :in=>@ctrl, :sticky=>:ew)\n    @ctrl.grid_rowconfigure(10, :minsize=>20)\n    Tk.grid(@details, :in=>@ctrl, :row=>11, :sticky=>:ew)\n    Tk.grid(@detail, :in=>@details, :row=>0, :sticky=>:ew)\n    @ctrl.grid_rowconfigure(50, :weight=>1)\n\n    @S['mode'].trace('w', proc{|*args| active_GUI(*args)})\n    @S['details'].trace('w', proc{|*args| active_GUI(*args)})\n    @S['speed'].trace('w', proc{|*args| active_GUI(*args)})\n\n    Tk.grid(@msg_entry, :in=>@ctrl, :row=>98, :sticky=>:ew, :pady=>5)\n    Tk.grid(@speed_scale, :in=>@ctrl, :row=>99, :sticky=>:ew)\n    Tk.grid(@about, :in=>@ctrl, :row=>100, :sticky=>:ew)\n\n    @reset.bind('3'){@S['mode'].value = -1}  # Debugging\n  end\n\n  def do_detail_frame\n    @f_details = TkFrame.new(@details)\n\n    @label = TkLabel.new(@f_details, :textvariable=>@S['cnt'], \n                         :bd=>1, :relief=>:solid, :bg=>'white')\n    Tk.grid(@label, '-', '-', '-', :sticky=>:ew, :row=>0)\n\n    idx = 1\n    loop {\n      break unless respond_to?(\"move#{idx}\")\n      l = TkLabel.new(@f_details, :text=>idx, :anchor=>:e, \n                      :width=>2, :bd=>1, :relief=>:solid, :bg=>'white')\n      @STEP[idx] = 0\n      ll = TkLabel.new(@f_details, :textvariable=>@STEP.ref(idx), \n                       :width=>5, :bd=>1, :relief=>:solid, :bg=>'white')\n      row = (idx + 1)/2\n      col = ((idx + 1) & 1) * 2\n      Tk.grid(l, :sticky=>:ew, :row=>row, :column=>col)\n      Tk.grid(ll, :sticky=>:ew, :row=>row, :column=>(col + 1))\n      idx += 1\n    }\n    @f_details.grid_columnconfigure(1, :weight=>1)\n  end\n\n  def show_ctrl\n    if @ctrl.winfo_mapped?\n      @ctrl.pack_forget\n      @show.text('>>')\n    else\n      @ctrl.pack(:side=>:right, :fill=>:both, :ipady=>5)\n      @show.text('<<')\n    end\n  end\n\n  def draw_all\n    reset_step\n    @canvas.delete(:all)\n    idx = 0\n    loop{\n      m = \"draw#{idx}\"\n      break unless respond_to?(m)\n      send(m)\n      idx += 1\n    }\n  end\n\n  def active_GUI(var1, var2, op)\n    st = {false=>:disabled, true=>:normal}\n\n    m = @S['mode'].to_sym\n    @S['pause'].value = (m == :MPAUSE)\n    @start.state(st[m != :MGO])\n    @pause.state(st[m != :MSTART && m != :MDONE])\n    @step.state(st[m != :MGO && m != :MDONE])\n    @bstep.state(st[m != :MGO && m != :MDONE])\n    @reset.state(st[m != :MSTART])\n\n    if @S['details'].bool\n      Tk.grid(@f_details, :in=>@details, :row=>2, :sticky=>:ew)\n    else\n      Tk.grid_forget(@f_details)\n    end\n    @speed_scale.label(\"Speed: #{@S['speed'].value}\")\n  end\n\n  def start\n    @S['mode'].value = :MGO\n  end\n\n  def do_button(what)\n    case what\n    when 0  # Start\n      reset if @S['mode'].to_sym == :MDONE\n      @S['mode'].value = :MGO\n\n    when 1  # Pause\n      @S['mode'].value = ((@S['pause'].bool)? :MPAUSE: :MGO)\n\n    when 2  # Step\n      @S['mode'].value = :MSSTEP\n\n    when 3  # Reset\n      reset\n\n    when 4  # Big step\n      @S['mode'].value = :MBSTEP\n    end\n  end\n\n  def go(who = nil)\n    now = Tk::Clock.clicks(:miliseconds)\n    if who  # Start here for debugging\n      @S['active'] = [who]\n      @S['mode'].value = :MGO\n    end\n    return if @S['mode'].to_sym == :MDEBUG  # Debugging\n    # If not paused, do the next move\n    n = next_step if @S['mode'].to_sym != :MPAUSE\n    @S['mode'].value = :MPAUSE if @S['mode'].to_sym == :MSSTEP  # Single step\n    @S['mode'].value = :MSSTEP if @S['mode'].to_sym == :MBSTEP && n  # big step\n    elapsed = Tk::Clock.clicks(:miliseconds) - now\n    delay = @speed[@S['speed'].to_i] - elapsed\n    delay = 1 if delay <= 0\n    return delay\n  end\n\n  def next_step\n    retval = false   # Return value\n\n    if @S['mode'].to_sym != :MSTART && @S['mode'].to_sym != :MDONE\n      @S['cnt'].numeric += 1\n    end\n    alive = []\n    @S['active'].each{|who|\n      who = who.to_i\n      n = send(\"move#{who}\")\n      if (n & 1).nonzero?          # This guy still alive\n        alive << who \n      end\n      if (n & 2).nonzero?          # Next guy is active\n        alive << (who + 1)\n        retval = true\n      end\n      if (n & 4).nonzero?          # End of puzzle flag\n        @S['mode'].value = :MDONE  # Done mode\n        @S['active'] = []          # No more animation\n        return true\n      end\n    }\n    @S['active'] = alive\n    return retval\n  end\n\n  def about\n    msg = \"Ruby/Tk Version ::\\nby Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\\n\\n\"\n    msg += \"Original Version ::\\n\"\n    msg += \"#{@S['title']}\\nby Keith Vetter, March 2003\\n(Reproduced by kind permission of the author)\\n\\n\"\n    msg += \"Man will always find a difficult means to perform a simple task\"\n    msg += \"\\nRube Goldberg\"\n    Tk.messageBox(:message=>msg, :title=>'About')\n  end\n\n  ################################################################\n  #\n  # All the drawing and moving routines\n  #\n\n  # START HERE! banner\n  def draw0\n    color = @C['0']\n    TkcText.new(@canvas, [579, 119], :text=>'START HERE!', \n                :fill=>color, :anchor=>:w, \n                :tag=>'I0', :font=>['Times Roman', 12, :italic, :bold])\n    TkcLine.new(@canvas, [719, 119, 763, 119], :tag=>'I0', :fill=>color, \n                :width=>5, :arrow=>:last, :arrowshape=>[18, 18, 5])\n    @canvas.itembind('I0', '1'){ start }\n  end\n\n  def move0(step = nil)\n    step = get_step(0, step)\n\n    if @S['mode'].to_sym != :MSTART    # Start the ball rolling\n      move_abs('I0', [-100, -100])     # Hide the banner\n      return 2\n    end\n\n    pos = [\n      [673, 119], [678, 119], [683, 119], [688, 119], \n      [693, 119], [688, 119], [683, 119], [678, 119]\n    ]\n    step = step % pos.length\n    move_abs('I0', pos[step])\n    return 1\n  end\n\n  # Dropping ball\n  def draw1\n    color = @C['1a']\n    color2 = @C['1b']\n    TkcPolygon.new(@canvas, \n                   [ 844, 133, 800, 133, 800, 346, 820, 346, \n                     820, 168, 844, 168, 844, 133 ], \n                   :width=>3, :fill=>color, :outline=>'')\n    TkcPolygon.new(@canvas, \n                   [ 771, 133, 685, 133, 685, 168, 751, 168, \n                     751, 346, 771, 346, 771, 133 ], \n                   :width=>3, :fill=>color, :outline=>'')\n    TkcOval.new(@canvas, box(812, 122, 9), \n                :tag=>'I1', :fill=>color2, :outline=>'')\n\n    @canvas.itembind('I1', '1'){ start }\n  end\n\n  def move1(step = nil)\n    step = get_step(1, step)\n    pos = [\n      [807, 122], [802, 122], [797, 123], [793, 124], [789, 129], [785, 153], \n      [785, 203], [785, 278, :x], [785, 367], [810, 392], [816, 438], \n      [821, 503], [824, 585, :y], [838, 587], [848, 593], [857, 601], \n      [-100, -100]\n    ]\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I1', where)\n    move15a if where[2] == :y\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Lighting the match\n  def draw2\n    color = @C['2']\n\n    # Fulcrum\n    TkcPolygon.new(@canvas, [750, 369, 740, 392, 760, 392], \n                   :fill=>@C['fg'], :outline=>@C['fg'])\n\n    # Strike box\n    TkcRectangle.new(@canvas, [628, 335, 660, 383], \n                     :fill=>'', :outline=>@C['fg'])\n    (0..2).each{|y|\n      yy = 335 + y*16\n      TkcBitmap.new(@canvas, [628, yy], :bitmap=>'gray25', \n                    :anchor=>:nw, :foreground=>@C['fg'])\n      TkcBitmap.new(@canvas, [644, yy], :bitmap=>'gray25', \n                    :anchor=>:nw, :foreground=>@C['fg'])\n    }\n\n    # Lever\n    TkcLine.new(@canvas, [702, 366, 798, 366], \n                :fill=>@C['fg'], :width=>6, :tag=>'I2_0')\n\n    # R strap\n    TkcLine.new(@canvas, [712, 363, 712, 355], \n                :fill=>@C['fg'], :width=>3, :tag=>'I2_1')\n\n    # L strap\n    TkcLine.new(@canvas, [705, 363, 705, 355], \n                :fill=>@C['fg'], :width=>3, :tag=>'I2_2')\n\n    # Match stick\n    TkcLine.new(@canvas, [679, 356, 679, 360, 717, 360, 717, 356, 679, 356], \n                :fill=>@C['fg'], :width=>3, :tag=>'I2_3')\n\n    # Match head\n    TkcPolygon.new(@canvas, \n                   [ 671, 352, 677.4, 353.9, 680, 358.5, 677.4, 363.1, \n                     671, 365, 664.6, 363.1, 662, 358.5, 664.6, 353.9 ], \n                   :fill=>color, :outline=>color, :tag=>'I2_4')\n  end\n\n  def move2(step = nil)\n    step = get_step(2, step)\n\n    stages = [0, 0, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 1]\n    xy = []\n    xy[0] = [\n      686, 333, 692, 323, 682, 316, 674, 309, 671, 295, 668, 307, \n      662, 318, 662, 328, 671, 336\n    ]\n    xy[1] = [\n      687, 331, 698, 322, 703, 295, 680, 320, 668, 297, 663, 311, \n      661, 327, 671, 335\n    ]\n    xy[2] = [\n      686, 331, 704, 322, 688, 300, 678, 283, 678, 283, 674, 298, \n      666, 309, 660, 324, 672, 336\n    ]\n\n    if step >= stages.length\n      @canvas.delete('I2')\n      return 0\n    end\n\n    if step == 0  # Rotate the match\n      beta = 20\n      \n      ox, oy = anchor('I2_0', :s)  # Where to pivot\n\n      i = 0\n      until @canvas.find_withtag(\"I2_#{i}\").empty?\n        rotate_item(\"I2_#{i}\", ox, oy, beta)\n        i += 1\n      end\n\n      # For the flame\n      TkcPolygon.new(@canvas, [], :tag=>'I2', :smooth=>true, :fill=>@C['2'])\n\n      return 1\n    end\n    @canvas.coords('I2', xy[stages[step]])\n    return ((step == 7)? 3: 1)\n  end\n\n  # Weight and pulleys\n  def draw3\n    color = @C['3a']\n    color2 = @C['3b']\n\n    xy = [ [602, 296], [577, 174], [518, 174] ]\n    xy.each{|x, y| # 3 Pulleys\n      TkcOval.new(@canvas, box(x, y, 13), \n                  :fill=>color, :outline=>@C['fg'], :width=>3)\n      TkcOval.new(@canvas, box(x, y, 2), :fill=>@C['fg'], :outline=>@C['fg'])\n    }\n\n    # Wall to flame\n    TkcLine.new(@canvas, [750, 309, 670, 309], :tag=>'I3_s', \n                :width=>3, :fill=>@C['fg'], :smooth=>true)\n\n    # Flame to pulley 1\n    TkcLine.new(@canvas, [670, 309, 650, 309], :tag=>'I3_0', \n                :width=>3, :fill=>@C['fg'], :smooth=>true)\n    TkcLine.new(@canvas, [650, 309, 600, 309], :tag=>'I3_1', \n                :width=>3, :fill=>@C['fg'], :smooth=>true)\n\n    # Pulley 1 half way to 2\n    TkcLine.new(@canvas, [589, 296, 589, 235], :tag=>'I3_2', \n                :width=>3, :fill=>@C['fg'])\n\n    # Pulley 1 other half to 2\n    TkcLine.new(@canvas, [589, 235, 589, 174], :width=>3, :fill=>@C['fg'])\n\n    # Across the top\n    TkcLine.new(@canvas, [577, 161, 518, 161], :width=>3, :fill=>@C['fg'])\n\n    # Down to weight\n    TkcLine.new(@canvas, [505, 174, 505, 205], :tag=>'I3_w', \n                :width=>3, :fill=>@C['fg'])\n\n    # Draw the weight as 2 circles, two rectangles and 1 rounded rectangle\n    x1, y1, x2, y2 = [515, 207, 495, 207]\n    TkcOval.new(@canvas, box(x1, y1, 6), \n                :tag=>'I3_', :fill=>color2, :outline=>color2)\n    TkcOval.new(@canvas, box(x2, y2, 6), \n                :tag=>'I3_', :fill=>color2, :outline=>color2)\n    TkcRectangle.new(@canvas, x1, y1 - 6, x2, y2 + 6, \n                     :tag=>'I3_', :fill=>color2, :outline=>color2)\n    \n    TkcPolygon.new(@canvas, round_rect([492, 220, 518, 263], 15), \n                   :smooth=>true, :tag=>'I3_', :fill=>color2, :outline=>color2)\n\n    TkcLine.new(@canvas, [500, 217, 511, 217], \n                :tag=>'I3_', :fill=>color2, :width=>10)\n\n    # Bottom weight target\n    TkcLine.new(@canvas, [502, 393, 522, 393, 522, 465], \n                :tag=>'I3__', :fill=>@C['fg'], :joinstyle=>:miter, :width=>10)\n  end\n\n  def move3(step = nil)\n    step = get_step(3, step)\n\n    pos = [ [505, 247], [505, 297], [505, 386.5], [505, 386.5] ]\n    rope = []\n    rope[0] = [750, 309, 729, 301, 711, 324, 690, 300]\n    rope[1] = [750, 309, 737, 292, 736, 335, 717, 315, 712, 320]\n    rope[2] = [750, 309, 737, 309, 740, 343, 736, 351, 725, 340]\n    rope[3] = [750, 309, 738, 321, 746, 345, 742, 356]\n\n    return 0 if step >= pos.length\n\n    @canvas.delete(\"I3_#{step}\")        # Delete part of the rope\n    move_abs('I3_', pos[step])          # Move weight down\n    @canvas.coords('I3_s', rope[step])  # Flapping rope end\n    @canvas.coords('I3_w', [505, 174].concat(pos[step]))\n    if step == 2\n      @canvas.move('I3__', 0, 30)\n      return 2\n    end\n    return 1\n  end\n\n  # Cage and door\n  def draw4\n    color = @C['4']\n    x0, y0, x1, y1 = [527, 356, 611, 464]\n\n    # Horizontal bars\n    y0.step(y1, 12){|y|\n      TkcLine.new(@canvas, [x0, y, x1, y], :fill=>color, :width=>1)\n    }\n\n    # Vertical bars\n    x0.step(x1, 12){|x|\n      TkcLine.new(@canvas, [x, y0, x, y1], :fill=>color, :width=>1)\n    }\n\n    # Swing gate\n    TkcLine.new(@canvas, [518, 464, 518, 428], \n                :tag=>'I4', :fill=>color, :width=>1)\n  end\n\n  def move4(step = nil)\n    step = get_step(4, step)\n\n    angles = [-10, -20, -30, -30]\n    return 0 if step >= angles.length\n\n    rotate_item('I4', 518, 464, angles[step])\n    @canvas.raise('I4')\n\n    return((step == 3)? 3: 1)\n  end\n\n  # Mouse\n  def draw5\n    color  = @C['5a']\n    color2 = @C['5b']\n\n    xy = [377, 248, 410, 248, 410, 465, 518, 465]  # Mouse course\n    xy.concat [518, 428, 451, 428, 451, 212, 377, 212]\n\n    TkcPolygon.new(@canvas, xy, :fill=>color2, :outline=>@C['fg'], :width=>3)\n\n    xy = [\n      534.5, 445.5, 541, 440, 552, 436, 560, 436, 569, 440, 574, 446, \n      575, 452, 574, 454, 566, 456, 554, 456, 545, 456, 537, 454, 530, 452\n    ]\n    TkcPolygon.new(@canvas, xy, :tag=>['I5', 'I5_0'], :fill=>color)\n\n    TkcLine.new(@canvas, [573, 452, 592, 458, 601, 460, 613, 456], # Tail\n                :tag=>['I5', 'I5_1'], :fill=>color, :smooth=>true, :width=>3)\n\n    xy = box(540, 446, 2)   # Eye\n    xy = [540, 444, 541, 445, 541, 447, 540, 448, 538, 447, 538, 445]\n    TkcPolygon.new(@canvas, xy, :tag=>['I5', 'I5_2'], :fill=>@C['bg'], \n                   :outline=>'', :smooth=>true)\n\n    xy = [538, 454, 535, 461] # Front leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_3'], :fill=>color, :width=>2)\n\n    xy = [566, 455, 569, 462] # Back leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_4'], :fill=>color, :width=>2)\n\n    xy = [544, 455, 545, 460] # 2nd front leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_5'], :fill=>color, :width=>2)\n\n    xy = [560, 455, 558, 460] # 2nd back leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_6'], :fill=>color, :width=>2)\n  end\n\n  def move5(step = nil)\n    step = get_step(5, step)\n\n    pos = [\n      [553, 452], [533, 452], [513, 452], [493, 452], [473, 452], \n      [463, 442, 30], [445.5, 441.5, 30], [425.5, 434.5, 30], [422, 414], \n      [422, 394], [422, 374], [422, 354], [422, 334], [422, 314], [422, 294], \n      [422, 274, -30], [422, 260.5, -30, :x], [422.5, 248.5, -28], [425, 237]\n    ]\n\n    return 0 if step >= pos.length\n\n    x, y, beta, nxt = pos[step]\n    move_abs('I5', [x, y])\n    if beta\n      ox, oy = centroid('I5_0')\n      (0..6).each{|id| rotate_item(\"I5_#{id}\", ox, oy, beta) }\n    end\n    return 3 if nxt == :x\n    return 1\n  end\n\n  # Dropping gumballs\n  def draw6\n    color = @C['6']\n    xy = [324, 130, 391, 204] # Ball holder\n    xy = round_rect(xy, 10)\n    TkcPolygon.new(@canvas, xy, :smooth=>true, \n                   :outline=>@C['fg'], :width=>3, :fill=>color)\n    xy = [339, 204, 376, 253] # Below the ball holder\n    TkcRectangle.new(@canvas, xy, :outline=>@C['fg'], :width=>3, \n                     :fill=>color, :tag=>'I6c')\n    xy = box(346, 339, 28)\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'') # Roter\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>2, :style=>:arc, \n               :start=>80, :extent=>205)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>2, :style=>:arc, \n               :start=>-41, :extent=>85)\n\n    xy = box(346, 339, 15) # Center of rotor\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['fg'], :tag=>'I6m')\n    xy = [352, 312, 352, 254, 368, 254, 368, 322] # Top drop to rotor\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'')\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2)\n\n    xy = [353, 240, 367, 300] # Poke bottom hole\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')\n    xy = [341, 190, 375, 210] # Poke another hole\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')\n\n    xy = [\n      368, 356, 368, 403, 389, 403, 389, 464, 320, 464, 320, 403, \n      352, 403, 352, 366\n    ]\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'', \n                   :width=>2) # Below rotor\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2)\n    xy = box(275, 342, 7) # On/off rotor\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['fg'])\n    xy = [276, 334, 342, 325] # Fan belt top\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = [276, 349, 342, 353] # Fan belt bottom\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n\n    xy = [337, 212, 337, 247] # What the mouse pushes\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I6_')\n    xy = [392, 212, 392, 247]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I6_')\n    xy = [337, 230, 392, 230]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>7, :tag=>'I6_')\n\n    who = -1 # All the balls\n    colors = %w(red cyan orange green blue darkblue)\n    colors *= 3\n\n    (0..16).each{|i|\n      loc = -i\n      color = colors[i]\n      x, y = @XY6[\"#{loc}\"]\n      TkcOval.new(@canvas, box(x, y, 5), \n                  :fill=>color, :outline=>color, :tag=>\"I6_b#{i}\")\n    }\n    draw6a(12) # The wheel\n  end\n\n  def draw6a(beta)\n    @canvas.delete('I6_0')\n    ox, oy = [346, 339]\n    (0..3).each{|i|\n      b = beta + i * 45\n      x, y = rotate_c(28, 0, 0, 0, b)\n      xy = [ox + x, oy + y, ox - x, oy - y]\n      TkcLine.new(@canvas, xy, :tag=>'I6_0', :fill=>@C['fg'], :width=>2)\n    }\n  end\n\n  def move6(step = nil)\n    step = get_step(6, step)\n\n    return 0 if step > 62\n\n    if step < 2  # Open gate for balls to drop\n      @canvas.move('I6_', -7, 0)\n      if step == 1  # Poke a hole\n        xy = [348, 226, 365, 240]\n        TkcRectangle.new(@canvas, xy, :fill=>@canvas.itemcget('I6c', :fill), \n                         :outline=>'')\n      end\n      return 1\n    end\n\n    s = step - 1  # Do the gumball drop dance\n    (0..(((s - 1)/3).to_i)).each{|i|\n      tag = \"I6_b#{i}\"\n      break if @canvas.find_withtag(tag).empty?\n      loc = s - 3*i\n\n      if @XY6[\"#{loc},#{i}\"]\n        move_abs(tag, @XY6[\"#{loc},#{i}\"])\n      elsif @XY6[\"#{loc}\"]\n        move_abs(tag, @XY6[\"#{loc}\"])\n      end\n    }\n    if s % 3 == 1\n      first = (s + 2)/3\n      i = first\n      loop {\n        tag = \"I6_b#{i}\"\n        break if @canvas.find_withtag(tag).empty?\n        loc = first - i\n        move_abs(tag, @XY6[\"#{loc}\"])\n        i += 1\n      }\n    end\n    if s >= 3  # Rotate the motor\n      idx = s % 3\n      draw6a(12 + s * 15)\n    end\n    return((s == 3)? 3 : 1)\n  end\n\n  # On/off switch\n  def draw7\n    color = @C['7']\n    xy = [198, 306, 277, 374]  # Box\n    TkcRectangle.new(@canvas, xy, :outline=>@C['fg'], :width=>2, \n                     :fill=>color, :tag=>'I7z')\n    @canvas.lower('I7z')\n    xy = [275, 343, 230, 349]\n    TkcLine.new(@canvas, xy, :tag=>'I7', :fill=>@C['fg'], :arrow=>:last, \n                :arrowshape=>[23, 23, 8], :width=>6)\n    xy = [225, 324]  # On button\n    x, y = xy\n    TkcOval.new(@canvas, box(x, y, 3), :fill=>@C['fg'], :outline=>@C['fg'])\n    xy = [218, 323]  # On text\n    font = ['Times Roman', 8]\n    TkcText.new(@canvas, xy, :text=>'on', :anchor=>:e, \n                :fill=>@C['fg'], :font=>font)\n    xy = [225, 350]  # Off button\n    x, y = xy\n    TkcOval.new(@canvas, box(x, y, 3), :fill=>@C['fg'], :outline=>@C['fg'])\n    xy = [218, 349]  # Off text\n    TkcText.new(@canvas, xy, :text=>'off', :anchor=>:e, \n                :fill=>@C['fg'], :font=>font)\n  end\n\n  def move7(step = nil)\n    step = get_step(7, step)\n\n    numsteps = 30\n    return 0 if step > numsteps\n    beta = 30.0 / numsteps\n    rotate_item('I7', 275, 343, beta)\n\n    return((step == numsteps)? 3: 1)\n  end\n\n  # Electricity to the fan\n  def draw8\n    sine([271, 248, 271, 306], 5, 8, :tag=>'I8_s', :fill=>@C['8'], :width=>3)\n  end\n\n  def move8(step = nil)\n    step = get_step(8, step)\n\n    return 0 if step > 3\n    if step == 0\n      sparkle(anchor('I8_s', :s), 'I8')\n      return 1\n    elsif step == 1\n      move_abs('I8', anchor('I8_s', :c))\n    elsif step == 2\n      move_abs('I8', anchor('I8_s', :n))\n    else\n      @canvas.delete('I8')\n    end\n    return((step == 2)? 3: 1)\n  end\n\n  # Fan\n  def draw9\n    color = @C['9']\n    xy = [266, 194, 310, 220]\n    TkcOval.new(@canvas, xy, :outline=>color, :fill=>color)\n    xy = [280, 209, 296, 248]\n    TkcOval.new(@canvas, xy, :outline=>color, :fill=>color)\n    xy = [\n      288, 249, 252, 249, 260, 240, 280, 234, \n      296, 234, 316, 240, 324, 249, 288, 249\n    ]\n    TkcPolygon.new(@canvas, xy, :fill=>color, :smooth=>true)\n\n    xy = [248, 205, 265, 214, 264, 205, 265, 196]  # Spinner\n    TkcPolygon.new(@canvas, xy, :fill=>color)\n\n    xy = [255, 206, 265, 234]  # Fan blades\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>3, :tag=>'I9_0')\n    xy = [255, 176, 265, 204]\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>3, :tag=>'I9_0')\n    xy = [255, 206, 265, 220]\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>1, :tag=>'I9_1')\n    xy = [255, 190, 265, 204]\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>1, :tag=>'I9_1')\n  end\n\n  def move9(step = nil)\n    step = get_step(9, step)\n\n    if (step & 1).nonzero?\n      @canvas.itemconfigure('I9_0', :width=>4)\n      @canvas.itemconfigure('I9_1', :width=>1)\n      @canvas.lower('I9_1', 'I9_0')\n    else\n      @canvas.itemconfigure('I9_0', :width=>1)\n      @canvas.itemconfigure('I9_1', :width=>4)\n      @canvas.lower('I9_0', 'I9_1')\n    end\n    return 3 if step == 0\n    return 1\n  end\n\n  # Boat\n  def draw10\n    color  = @C['10a']\n    color2 = @C['10b']\n    xy = [191, 230, 233, 230, 233, 178, 191, 178]  # Sail\n    TkcPolygon.new(@canvas, xy, :fill=>color, :width=>3, :outline=>@C['fg'], \n                   :tag=>'I10')\n    xy = box(209, 204, 31)  # Front\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :style=>:pie, \n               :start=>120, :extent=>120, :tag=>'I10')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>120, :extent=>120, :tag=>'I10')\n    xy = box(249, 204, 31)  # Back\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>3, \n               :style=>:pie, :start=>120, :extent=>120, :tag=>'I10')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>120, :extent=>120, :tag=>'I10')\n\n    xy = [200, 171, 200, 249]  # Mast\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I10')\n    xy = [159, 234, 182, 234]  # Bow sprit\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I10')\n    xy = [180, 234, 180, 251, 220, 251]  # Hull\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>6, :tag=>'I10')\n\n    xy = [92, 255, 221, 255]  # Waves\n    sine(xy, 2, 25, :fill=>color2, :width=>1, :tag=>'I10w')\n\n    xy = @canvas.coords('I10w')[4..-5]  # Water\n    xy.concat([222, 266, 222, 277, 99, 277])\n    TkcPolygon.new(@canvas, xy, :fill=>color2, :outline=>color2)\n    xy = [222, 266, 222, 277, 97, 277, 97, 266]  # Water bottom\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n\n    xy = box(239, 262, 17)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>95, :extent=>103)\n    xy = box(76, 266, 21)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :extent=>190)\n  end\n\n  def move10(step = nil)\n    step = get_step(10, step)\n\n    pos = [\n      [195, 212], [193, 212], [190, 212], [186, 212], [181, 212], [176, 212], \n      [171, 212], [166, 212], [161, 212], [156, 212], [151, 212], [147, 212], \n      [142, 212], [137, 212], [132, 212, :x], [127, 212], [121, 212], \n      [116, 212], [111, 212]\n    ]\n\n    return 0 if step >= pos.length\n\n    where = pos[step]\n    move_abs('I10', where)\n\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # 2nd ball drop\n  def draw11\n    color  = @C['11a']\n    color2 = @C['11b']\n    xy = [23, 264, 55, 591]  # Color the down tube\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')\n    xy = box(71, 460, 48)    # Color the outer loop\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'')\n\n    xy = [55, 264, 55, 458]  # Top right side\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = [55, 504, 55, 591]  # Bottom right side\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = box(71, 460, 48)    # Outer loop\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>110, :extent=>-290, :tag=>'I11i')\n    xy = box(71, 460, 16)    # Inner loop\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>'', \n                :width=>3, :tag=>'I11i')\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['bg'], :width=>3)\n\n    xy = [23, 264, 23, 591]  # Left side\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = box(1, 266, 23)     # Top left curve\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, \n               :style=>:arc, :extent=>90)\n\n    xy = box(75, 235, 9)     # The ball\n    TkcOval.new(@canvas, xy, :fill=>color2, :outline=>'', \n                :width=>3, :tag=>'I11')\n  end\n\n  def move11(step = nil)\n    step = get_step(11, step)\n\n    pos = [\n      [75, 235], [70, 235], [65, 237], [56, 240], [46, 247], [38, 266], \n      [38, 296], [38, 333], [38, 399], [38, 475], [74, 496], [105, 472], \n      [100, 437], [65, 423], [-100, -100], [38, 505], [38, 527, :x], [38, 591]\n    ]\n\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I11', where)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Hand\n  def draw12\n    xy = [\n      20, 637, 20, 617, 20, 610, 20, 590, 40, 590, 40, 590, \n      60, 590, 60, 610, 60, 610\n    ]\n    xy.concat([60, 610, 65, 620, 60, 631])  # Thumb\n    xy.concat([60, 631, 60, 637, 60, 662, 60, 669, 52, 669, \n                56, 669, 50, 669, 50, 662, 50, 637])\n\n    y0 = 637  # Bumps for fingers\n    y1 = 645\n    50.step(21, -10){|x|\n      x1 = x - 5\n      x2 = x - 10\n      xy << x << y0 << x1 << y1 << x2 << y0\n    }\n    TkcPolygon.new(@canvas, xy, :fill=>@C['12'], :outline=>@C['fg'], \n                   :smooth=>true, :tag=>'I12', :width=>3)\n  end\n\n  def move12(step = nil)\n    step = get_step(12, step)\n\n    pos = [[42.5, 641, :x]]\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I12', where)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Fax\n  def draw13\n    color = @C['13a']\n    xy = [86, 663, 149, 663, 149, 704, 50, 704, 50, 681, 64, 681, 86, 671]\n    xy2 = [\n      784, 663, 721, 663, 721, 704, 820, 704, 820, 681, 806, 681, 784, 671\n    ]\n    radii = [2, 9, 9, 8, 5, 5, 2]\n\n    round_poly(@canvas, xy, radii, :width=>3, \n               :outline=>@C['fg'], :fill=>color)\n    round_poly(@canvas, xy2, radii, :width=>3, \n               :outline=>@C['fg'], :fill=>color)\n\n    xy = [56, 677]\n    x, y = xy\n    TkcRectangle.new(@canvas, box(x, y, 4), :fill=>'', :outline=>@C['fg'], \n                     :width=>3, :tag=>'I13')\n    xy = [809, 677]\n    x, y = xy\n    TkcRectangle.new(@canvas, box(x, y, 4), :fill=>'', :outline=>@C['fg'], \n                     :width=>3, :tag=>'I13R')\n\n    xy = [112, 687]  # Label\n    TkcText.new(@canvas, xy, :text=>'FAX', :fill=>@C['fg'], \n                :font=>['Times Roman', 12, :bold])\n    xy = [762, 687]\n    TkcText.new(@canvas, xy, :text=>'FAX', :fill=>@C['fg'], \n                :font=>['Times Roman', 12, :bold])\n\n    xy = [138, 663, 148, 636, 178, 636]  # Paper guide\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>@C['fg'], :width=>3)\n    xy = [732, 663, 722, 636, 692, 636]\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>@C['fg'], :width=>3)\n\n    sine([149, 688, 720, 688], 5, 15, \n         :tag=>'I13_s', :fill=>@C['fg'],  :width=>3)\n  end\n\n  def move13(step = nil)\n    step = get_step(13, step)\n\n    numsteps = 7\n\n    if step == numsteps + 2\n      move_abs('I13_star', [-100, -100])\n      @canvas.itemconfigure('I13R', :fill=>@C['13b'], :width=>2)\n      return 2\n    end\n    if step == 0  # Button down\n      @canvas.delete('I13')\n      sparkle([-100, -100], 'I13_star')  # Create off screen\n      return 1\n    end\n    x0, y0 = anchor('I13_s', :w)\n    x1, y1 = anchor('I13_s', :e)\n    x = x0 + (x1 - x0) * (step - 1) / numsteps.to_f\n    move_abs('I13_star', [x, y0])\n    return 1\n  end\n\n  # Paper in fax\n  def draw14\n    color = @C['14']\n    xy = [102, 661, 113, 632, 130, 618]  # Left paper edge\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14L_0')\n    xy = [148, 629, 125, 640, 124, 662]  # Right paper edge\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14L_1')\n    draw14a('L')\n\n    xy = [\n      768.0, 662.5, 767.991316225, 662.433786215, 767.926187912, 662.396880171\n    ]\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14R_0')\n    @canvas.lower('I14R_0')\n    # NB. these numbers are VERY sensitive, you must start with final size\n    # and shrink down to get the values\n    xy = [\n      745.947897349, 662.428358855, 745.997829056, 662.452239237, 746.0, 662.5\n    ]\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14R_1')\n    @canvas.lower('I14R_1')\n  end\n\n  def draw14a(side)\n    color = @C['14']\n    xy = @canvas.coords(\"I14#{side}_0\")\n    xy2 = @canvas.coords(\"I14#{side}_1\")\n    x0, y0, x1, y1, x2, y2 = xy\n    x3, y3, x4, y4, x5, y5 = xy2\n\n    zz = [\n      x0, y0, x0, y0, xy, x2, y2, x2, y2, \n      x3, y3, x3, y3, xy2, x5, y5, x5, y5\n    ].flatten\n    @canvas.delete(\"I14#{side}\")\n    TkcPolygon.new(@canvas, zz, :tag=>\"I14#{side}\", :smooth=>true, \n                   :fill=>color, :outline=>color, :width=>3)\n    @canvas.lower(\"I14#{side}\")\n  end\n\n  def move14(step = nil)\n    step = get_step(14, step)\n\n    # Paper going down\n    sc = 0.9 - 0.05*step\n    if sc < 0.3\n      @canvas.delete('I14L')\n      return 0\n    end\n\n    ox, oy = @canvas.coords('I14L_0')\n    @canvas.scale('I14L_0', ox, oy, sc, sc)\n    ox, oy = @canvas.coords('I14L_1')[-2..-1]\n    @canvas.scale('I14L_1', ox, oy, sc, sc)\n    draw14a('L')\n\n    # Paper going up\n    sc = 0.35 + 0.05*step\n    sc = 1/sc\n\n    ox, oy = @canvas.coords('I14R_0')\n    @canvas.scale('I14R_0', ox, oy, sc, sc)\n    ox, oy = @canvas.coords('I14R_1')[-2..-1]\n    @canvas.scale('I14R_1', ox, oy, sc, sc)\n    draw14a('R')\n\n    return((step == 10)? 3: 1)\n  end\n\n  # Light beam\n  def draw15\n    color = @C['15a']\n    xy = [824, 599, 824, 585, 820, 585, 829, 585]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I15a')\n    xy = [789, 599, 836, 643]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n    xy = [778, 610, 788, 632]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n    xy = [766, 617, 776, 625]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n\n    xy = [633, 600, 681, 640]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n    xy = [635, 567, 657, 599]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2)\n    xy = [765, 557, 784, 583]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2)\n\n    sine([658, 580, 765, 580], 3, 15, \n         :tag=>'I15_s', :fill=>@C['fg'], :width=>3)\n  end\n\n  def move15a\n    color = @C['15b']\n    @canvas.scale('I15a', 824, 599, 1, 0.3)  # Button down\n    xy = [765, 621, 681, 621]\n    TkcLine.new(@canvas, xy, :dash=>'-', :width=>3, :fill=>color, :tag=>'I15')\n  end\n\n  def move15(step = nil)\n    step = get_step(15, step)\n\n    numsteps = 6\n\n    if step == numsteps + 2\n      move_abs('I15_star', [-100, -100])\n      return 2\n    end\n    if step == 0  # Break the light beam\n      sparkle([-100, -100], 'I15_star')\n      xy = [765, 621, 745, 621]\n      @canvas.coords('I15', xy)\n      return 1\n    end\n    x0, y0 = anchor('I15_s', :w)\n    x1, y1 = anchor('I15_s', :e)\n    x = x0 + (x1 - x0) * (step - 1) / numsteps.to_f\n    move_abs('I15_star', [x, y0])\n    return 1\n  end\n\n  # Bell\n  def draw16\n    color = @C['16']\n    xy = [722, 485, 791, 556]\n    TkcRectangle.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], :width=>3)\n    xy = box(752, 515, 25)  # Bell\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'black', \n                :tag=>'I16b', :width=>2)\n    xy = box(752, 515, 5)   # Bell button\n    TkcOval.new(@canvas, xy, :fill=>'black', :outline=>'black', :tag=>'I16b')\n\n    xy = [784, 523, 764, 549]  # Clapper\n    TkcLine.new(@canvas, xy, :width=>3, :tag=>'I16c', :fill=>@C['fg'])\n    xy = box(784, 523, 4)\n    TkcOval.new(@canvas, xy, :fill=>@C['fg'], :outline=>@C['fg'], :tag=>'I16d')\n  end\n\n  def move16(step = nil)\n    step = get_step(16, step)\n\n    # Note: we never stop\n    ox, oy = [760, 553]\n    if (step & 1).nonzero?\n      beta = 12\n      @canvas.move('I16b', 3, 0)\n    else\n      beta = -12\n      @canvas.move('I16b', -3, 0)\n    end\n    rotate_item('I16c', ox, oy, beta)\n    rotate_item('I16d', ox, oy, beta)\n\n    return ((step == 1)? 3: 1)\n  end\n\n  # Cat\n  def draw17\n    color = @C['17']\n\n    xy = [584, 556, 722, 556]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = [584, 485, 722, 485]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n\n    xy = [664, 523, 717, 549]  # Body\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, :width=>3, \n               :style=>:chord, :start=>128, :extent=>260, :tag=>'I17')\n\n    xy = [709, 554, 690, 543]  # Paw\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, \n                :width=>3, :tag=>'I17')\n    xy = [657, 544, 676, 555]\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, \n                :width=>3, :tag=>'I17')\n\n    xy = box(660, 535, 15)     # Lower face\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>150, :extent=>240, :tag=>'I17_')\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:chord, :start=>150, :extent=>240, :tag=>'I17_')\n    xy = [674, 529, 670, 513, 662, 521, 658, 521, 650, 513, 647, 529]  # Ears\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'', :width=>1, \n                   :tag=>['I17_', 'I17_c'])\n    xy = [652, 542, 628, 539]  # Whiskers\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n    xy = [652, 543, 632, 545]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n    xy = [652, 546, 632, 552]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n\n    xy = [668, 543, 687, 538]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                :tag=>['I17_', 'I17_w'])\n    xy = [668, 544, 688, 546]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                :tag=>['I17_', 'I17_w'])\n    xy = [668, 547, 688, 553]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                :tag=>['I17_', 'I17_w'])\n\n    xy = [649, 530, 654, 538, 659, 530]  # Left eye\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, \n                :smooth=>true, :tag=>'I17')\n    xy = [671, 530, 666, 538, 661, 530]  # Right eye\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, \n                :smooth=>true, :tag=>'I17')\n    xy = [655, 543, 660, 551, 665, 543]  # Mouth\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, \n                :smooth=>true, :tag=>'I17')\n  end\n\n  def move17(step = nil)\n    step = get_step(17, step)\n\n    if step == 0\n      @canvas.delete('I17')  # Delete most of the cat\n      xy = [655, 543, 660, 535, 665, 543]  # Mouth\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,\n                  :smooth=>true, :tag=>'I17_')\n      xy = box(654, 530, 4)  # Left eye\n      TkcOval.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :fill=>'', \n                  :tag=>'I17_')\n      xy = box(666, 530, 4)  # Right eye\n      TkcOval.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :fill=>'', \n                  :tag=>'I17_')\n\n      @canvas.move('I17_', 0, -20) # Move face up\n      xy = [652, 528, 652, 554]    # Front leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n      xy = [670, 528, 670, 554]    # 2nd front leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n\n      xy = [ # Body\n        675, 506, 694, 489, 715, 513, 715, 513, 715, 513, 716, 525, \n        716, 525, 716, 525, 706, 530, 695, 530, 679, 535, 668, 527, \n        668, 527, 668, 527, 675, 522, 676, 517, 677, 512\n      ]\n      TkcPolygon.new(@canvas, xy, :fill=>@canvas.itemcget('I17_c', :fill), \n                     :outline=>@C['fg'], :width=>3, :smooth=>true, \n                     :tag=>'I17_')\n      xy = [716, 514, 716, 554]  # Back leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n      xy = [694, 532, 694, 554]  # 2nd back leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n      xy = [715, 514, 718, 506, 719, 495, 716, 488]  # Tail\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                  :smooth=>true, :tag=>'I17_')\n\n      @canvas.raise('I17w')       # Make whiskers visible\n      @canvas.move('I17_', -5, 0) # Move away from the wall a bit\n      return 2\n    end\n    return 0\n  end\n\n  # Sling shot\n  def draw18\n    color = @C['18']\n    xy = [721, 506, 627, 506]  # Sling hold\n    TkcLine.new(@canvas, xy, :width=>4, :fill=>@C['fg'], :tag=>'I18')\n\n    xy = [607, 500, 628, 513]  # Sling rock\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'', :tag=>'I18a')\n\n    xy = [526, 513, 606, 507, 494, 502]  # Sling band\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>4, :tag=>'I18b')\n    xy = [485, 490, 510, 540, 510, 575, 510, 540, 535, 491]  # Sling\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>6)\n  end\n\n  def move18(step = nil)\n    step = get_step(18, step)\n\n    pos = [\n      [587, 506], [537, 506], [466, 506], [376, 506], [266, 506, :x], \n      [136, 506], [16, 506], [-100, -100]\n    ]\n\n    b = []\n    b[0] = [490, 502, 719, 507, 524, 512]  # Band collapsing\n    b[1] = [\n      491, 503, 524, 557, 563, 505, 559, 496, 546, 506, 551, 525, \n      553, 536, 538, 534, 532, 519, 529, 499\n    ]\n    b[2] = [\n      491, 503, 508, 563, 542, 533, 551, 526, 561, 539, 549, 550, 530, 500\n    ]\n    b[3] = [\n      491, 503, 508, 563, 530, 554, 541, 562, 525, 568, 519, 544, 530, 501\n    ]\n\n    return 0 if step >= pos.length\n\n    if step == 0\n      @canvas.delete('I18')\n      @canvas.itemconfigure('I18b', :smooth=>true)\n    end\n    if b[step]\n      @canvas.coords('I18b', b[step])\n    end\n\n    where = pos[step]\n    move_abs('I18a', where)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Water pipe\n  def draw19\n    color = @C['19']\n    xx = [[249, 181], [155, 118], [86, 55], [22, 0]]\n    xx.each{|x1, x2|\n      TkcRectangle.new(@canvas, x1, 453, x2, 467, \n                       :fill=>color, :outline=>'', :tag=>'I19')\n      TkcLine.new(@canvas, x1, 453, x2, 453, \n                  :fill=>@C['fg'], :width=>1) # Pipe top\n      TkcLine.new(@canvas, x1, 467, x2, 467, \n                  :fill=>@C['fg'], :width=>1) # Pipe bottom\n    }\n    @canvas.raise('I11i')\n\n    xy = box(168, 460, 16)  # Bulge by the joint\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, :style=>:arc, \n               :start=>21, :extent=>136)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, :style=>:arc, \n               :start=>-21, :extent=>-130)\n\n    xy = [249, 447, 255, 473]  # First joint 26x6\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n\n    xy = box(257, 433, 34)     # Bend up\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:pie, :start=>0, :extent=>-91)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>-90)\n    xy = box(257, 433, 20)\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1, \n               :style=>:pie, :start=>0, :extent=>-92)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>-90)\n    xy = box(257, 421, 34)     # Bend left\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:pie, :start=>0, :extent=>91)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>90)\n    xy = box(257, 421, 20)\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1, \n               :style=>:pie, :start=>0, :extent=>90)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>90)\n    xy = box(243, 421, 34)     # Bend down\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:pie, :start=>90, :extent=>90)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>90, :extent=>90)\n    xy = box(243, 421, 20)\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1, \n               :style=>:pie, :start=>90, :extent=>90)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>90, :extent=>90)\n\n    xy = [270, 427, 296, 433]  # 2nd joint bottom\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [270, 421, 296, 427]  # 2nd joint top\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [249, 382, 255, 408]  # Third joint right\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [243, 382, 249, 408]  # Third joint left\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [203, 420, 229, 426]  # Last joint\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n\n    xy = box(168, 460, 6)      # Handle joint\n    TkcOval.new(@canvas, xy, :fill=>@C['fg'], :outline=>'', :tag=>'I19a')\n    xy = [168, 460, 168, 512]  # Handle bar\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>5, :tag=>'I19b')\n  end\n\n  def move19(step = nil)\n    step = get_step(19, step)\n\n     angles = [30, 30, 30]\n    return 2 if step == angles.length\n    ox, oy = centroid('I19a')\n    rotate_item('I19b', ox, oy, angles[step])\n\n    return 1\n  end\n\n  # Water pouring\n  def draw20\n    # do nothing\n  end\n\n  def move20(step = nil)\n    step = get_step(20, step)\n\n    pos  = [451, 462, 473, 484, 496, 504, 513, 523, 532]\n    freq  = [20,  40,  40,  40,  40,  40,  40,  40,  40]\n    pos = [\n      [451, 20], [462, 40], [473, 40], [484, 40], [496, 40], \n      [504, 40], [513, 40], [523, 40], [532, 40, :x]\n    ]\n    return 0 if step >= pos.length\n\n    @canvas.delete('I20')\n    where = pos[step]\n    y, f = where\n    h20(y, f)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  def h20(y, f)\n    color = @C['20']\n    @canvas.delete('I20')\n\n    sine([208, 428, 208, y], 4, f, :tag=>['I20', 'I20s'], \n         :width=>3, :fill=>color, :smooth=>true)\n    TkcLine.new(@canvas, @canvas.coords('I20s'), :width=>3, \n                :fill=>color, :smooth=>1, :tag=>['I20', 'I20a'])\n    TkcLine.new(@canvas, @canvas.coords('I20s'), :width=>3, \n                :fill=>color, :smooth=>1, :tag=>['I20', 'I20b'])\n    @canvas.move('I20a', 8, 0)\n    @canvas.move('I20b', 16, 0)\n  end\n\n  # Bucket\n  def draw21\n    color = @C['21']\n    xy = [217, 451, 244, 490]  # Right handle\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21_a')\n    xy = [201, 467, 182, 490]  # Left handle\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21_a')\n\n    xy = [245, 490, 237, 535]  # Right side\n    xy2 = [189, 535, 181, 490] # Left side\n    TkcPolygon.new(@canvas, xy + xy2, :fill=>color, :outline=>'', \n                   :tag=>['I21', 'I21f'])\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21')\n    TkcLine.new(@canvas, xy2, :fill=>@C['fg'], :width=>2, :tag=>'I21')\n\n    xy = [182, 486, 244, 498]  # Top\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'', :width=>2, \n                :tag=>['I21', 'I21f'])\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], :width=>2, \n                :tag=>['I21', 'I21t'])\n    xy = [189, 532, 237, 540]  # Bottom\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2, \n                :tag=>['I21', 'I21b'])\n  end\n\n  def move21(step = nil)\n    step = get_step(21, step)\n\n    numsteps = 30\n    return 0 if step >= numsteps\n\n    x1, y1, x2, y2 = @canvas.coords('I21b')\n    # lx1, ly1, lx2, ly2 = @canvas.coords('I21t')\n    lx1, ly1, lx2, ly2 = [183, 492, 243, 504]\n\n    f = step / numsteps.to_f\n    y2 = y2 - 3\n    xx1 = x1 + (lx1 - x1) * f\n    yy1 = y1 + (ly1 - y1) * f\n    xx2 = x2 + (lx2 - x2) * f\n    yy2 = y2 + (ly2 - y2) * f\n\n    @canvas.itemconfigure('I21b', :fill=>@C['20'])\n    @canvas.delete('I21w')\n    TkcPolygon.new(@canvas, x2, y2, x1, y1, xx1, yy1, xx2, yy1, \n                   :tag=>['I21', 'I21w'], :outline=>'', :fill=>@C['20'])\n    @canvas.lower('I21w', 'I21')\n    @canvas.raise('I21b')\n    @canvas.lower('I21f')\n\n    return((step == numsteps - 1)? 3: 1)\n  end\n\n  # Bucket drop\n  def draw22\n    # do nothing\n  end\n\n  def move22(step = nil)\n    step = get_step(22, step)\n    pos = [[213, 513], [213, 523], [213, 543, :x], [213, 583], [213, 593]]\n\n    @canvas.itemconfigure('I21f', :fill=>@C['22']) if step == 0\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I21', where)\n    h20(where[1], 40)\n    @canvas.delete('I21_a')  # Delete handles\n\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Blow dart\n  def draw23\n    color  = @C['23a']\n    color2 = @C['23b']\n    color3 = @C['23c']\n\n    xy = [185, 623, 253, 650]  # Block\n    TkcRectangle.new(@canvas, xy, :fill=>'black', :outline=>@C['fg'], \n                     :width=>2, :tag=>'I23a')\n    xy = [187, 592, 241, 623]  # Balloon\n    TkcOval.new(@canvas, xy, :outline=>'', :fill=>color, :tag=>'I23b')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :tag=>'I23b', \n               :style=>:arc, :start=>12, :extent=>336)\n    xy = [239, 604, 258, 589, 258, 625, 239, 610]  # Balloon nozzle\n    TkcPolygon.new(@canvas, xy, :outline=>'', :fill=>color, :tag=>'I23b')\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23b')\n\n    xy = [285, 611, 250, 603]  # Dart body\n    TkcOval.new(@canvas, xy, :fill=>color2, :outline=>@C['fg'], \n                :width=>3, :tag=>'I23d')\n    xy = [249, 596, 249, 618, 264, 607, 249, 596]  # Dart tail\n    TkcPolygon.new(@canvas, xy, :fill=>color3, :outline=>@C['fg'], \n                   :width=>3, :tag=>'I23d')\n    xy = [249, 607, 268, 607]  # Dart detail\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23d')\n    xy = [285, 607, 305, 607]  # Dart needle\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23d')\n  end\n\n  def move23(step = nil)\n    step = get_step(23, step)\n\n    pos = [\n      [277, 607], [287, 607], [307, 607, :x], [347, 607], [407, 607], \n      [487, 607], [587, 607], [687, 607], [787, 607], [-100, -100]\n    ]\n\n    return 0 if step >= pos.length\n    if step <= 1\n      ox, oy = anchor('I23a', :n)\n      @canvas.scale('I23b', ox, oy, 0.9, 0.5)\n    end\n    where = pos[step]\n    move_abs('I23d', where)\n\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Balloon\n  def draw24\n    color = @C['24a']\n    xy = [366, 518, 462, 665]  # Balloon\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], \n                :width=>3, :tag=>'I24')\n    xy = [414, 666, 414, 729]  # String\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I24')\n    xy = [410, 666, 404, 673, 422, 673, 418, 666]  # Nozzle\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>@C['fg'],\n                   :width=>3, :tag=>'I24')\n\n    xy = [387, 567, 390, 549, 404, 542]  # Reflections\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n    xy = [395, 568, 399, 554, 413, 547]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n    xy = [403, 570, 396, 555, 381, 553]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n    xy = [408, 564, 402, 547, 386, 545]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n  end\n\n  def move24(step = nil)\n    step = get_step(24, step)\n\n    return 0 if step > 4\n    return 2 if step == 4\n\n    if step == 0\n      @canvas.delete('I24')  # Exploding balloon\n      xy = [\n        347, 465, 361, 557, 271, 503, 272, 503, 342, 574, 259, 594, \n        259, 593, 362, 626, 320, 737, 320, 740, 398, 691, 436, 738, \n        436, 739, 476, 679, 528, 701, 527, 702, 494, 627, 548, 613, \n        548, 613, 480, 574, 577, 473, 577, 473, 474, 538, 445, 508, \n        431, 441, 431, 440, 400, 502, 347, 465, 347, 465\n      ]\n      TkcPolygon.new(@canvas, xy, :tag=>'I24', :fill=>@C['24b'], \n                     :outline=>@C['24a'], :width=>10, :smooth=>true)\n      msg = Tk.subst(@S['message'].value)\n      TkcText.new(@canvas, centroid('I24'), :text=>msg, :tag=>['I24', 'I24t'], \n                  :justify=>:center, :font=>['Times Roman', 18, :bold])\n      return 1\n    end\n\n    @canvas.itemconfigure('I24t', :font=>['Times Roman', 18 + 6*step, :bold])\n    @canvas.move('I24', 0, -60)\n    ox, oy = centroid('I24')\n    @canvas.scale('I24', ox, oy, 1.25, 1.25)\n    return 1\n  end\n\n  # Displaying the message\n  def move25(step = nil)\n    step = get_step(25, step)\n\n    if step == 0\n      @XY['25'] = Tk::Clock.clicks(:miliseconds)\n      return 1\n    end\n    elapsed = Tk::Clock.clicks(:miliseconds) - @XY['25']\n    return 1 if elapsed < 5000\n    return 2\n  end\n\n  # Collapsing balloon\n  def move26(step = nil)\n    step = get_step(26, step)\n\n    if step >= 3\n      @canvas.delete('I24', 'I26')\n      TkcText.new(@canvas, 430, 740, :anchor=>:s, :tag=>'I26', \n                  :text=>'click to continue', \n                  :font=>['Times Roman', 24, :bold])\n      @canvas.bind('1', proc{reset})\n      return 4\n    end\n\n    ox, oy = centroid('I24')\n    @canvas.scale('I24', ox, oy, 0.8, 0.8)\n    @canvas.move('I24', 0, 60)\n    @canvas.itemconfigure('I24t', :font=>['Times Roman', 30 - 6*step, :bold])\n    return 1\n  end\n\n  ################################################################\n  #\n  # Helper functions\n  #\n  def box(x, y, r)\n    [x - r, y - r, x + r, y + r]\n  end\n\n  def move_abs(item, xy)\n    x, y = xy\n    ox, oy = centroid(item)\n    dx = x - ox\n    dy = y - oy\n    @canvas.move(item, dx, dy)\n  end\n\n  def rotate_item(item, ox, oy, beta)\n    xy = @canvas.coords(item)\n    xy2 = []\n    0.step(xy.length - 1, 2){|idx|\n      x, y = xy[idx, 2]\n      xy2.concat(rotate_c(x, y, ox, oy, beta))\n    }\n    @canvas.coords(item, xy2)\n  end\n\n  def rotate_c(x, y, ox, oy, beta)\n    # rotates vector (ox,oy)->(x,y) by beta degrees clockwise\n\n    x -= ox    # Shift to origin\n    y -= oy\n\n    beta = beta * Math.atan(1) * 4 / 180.0        # Radians\n    xx = x * Math.cos(beta) - y * Math.sin(beta)  # Rotate\n    yy = x * Math.sin(beta) + y * Math.cos(beta)\n\n    xx += ox  # Shift back\n    yy += oy\n\n    [xx, yy]\n  end\n\n  def reset\n    draw_all\n    @canvas.bind_remove('1')\n    @S['mode'].value = :MSTART\n    @S['active'] = [0]\n  end\n\n  # Each Move## keeps its state info in STEP, this retrieves and increments it\n  def get_step(who, step)\n    if step\n      @STEP[who] = step\n    else\n      if !@STEP.exist?(who) || @STEP[who] == \"\"\n        @STEP[who] = 0\n      else\n        @STEP[who] += 1\n      end\n    end\n    @STEP[who]\n  end\n\n  def reset_step\n    @S['cnt'].value = 0\n    @STEP.keys.each{|k| @STEP[k] = ''}\n  end\n\n  def sine(xy0, amp, freq, opts = {})\n    x0, y0, x1, y1 = xy0\n    step = 2\n    xy = []\n    if y0 == y1  # Horizontal\n      x0.step(x1, step){|x|\n        beta = (x - x0) * 2 * Math::PI / freq\n        y = y0 + amp * Math.sin(beta)\n        xy << x << y\n      }\n    else\n      y0.step(y1, step){|y|\n        beta = (y - y0) * 2 * Math::PI / freq\n        x = x0 + amp * Math.sin(beta)\n        xy << x << y\n      }\n    end\n    TkcLine.new(@canvas, xy, opts)\n  end\n\n  def round_rect(xy, radius, opts={})\n    x0, y0, x3, y3 = xy\n    r = @canvas.winfo_pixels(radius)\n    d = 2 * r\n\n    # Make sure that the radius of the curve is less than 3/8 size of the box!\n    maxr = 0.75\n    if d > maxr * (x3 - x0)\n      d = maxr * (x3 - x0)\n    end\n    if d > maxr * (y3 - y0)\n      d = maxr * (y3 - y0)\n    end\n\n    x1 = x0 + d\n    x2 = x3 - d\n    y1 = y0 + d\n    y2 = y3 - d\n\n    xy = [x0, y0, x1, y0, x2, y0, x3, y0, x3, y1, x3, y2]\n    xy.concat([x3, y3, x2, y3, x1, y3, x0, y3, x0, y2, x0, y1])\n    return xy\n  end\n\n  def round_poly(canv, xy, radii, opts)\n    lenXY = xy.length\n    lenR = radii.length\n    if lenXY != 2*lenR\n      raise \"wrong number of vertices and radii\"\n    end\n\n    knots = []\n    x0 = xy[-2]; y0 = xy[-1]\n    x1 = xy[0];  y1 = xy[1]\n    xy << xy[0] << xy[1]\n\n    0.step(lenXY - 1, 2){|i|\n      radius = radii[i/2]\n      r = canv.winfo_pixels(radius)\n\n      x2 = xy[i+2];  y2 = xy[i+3]\n      z = _round_poly2(x0, y0, x1, y1, x2, y2, r)\n      knots.concat(z)\n\n      x0 = x1;  y0 = y1\n      x1 = x2;  y1 = y2\n    }\n    TkcPolygon.new(canv, knots, {:smooth=>true}.update(opts))\n  end\n\n  def _round_poly2(x0, y0, x1, y1, x2, y2, radius)\n    d = 2 * radius\n    maxr = 0.75\n\n    v1x = x0 - x1\n    v1y = y0 - y1\n    v2x = x2 - x1\n    v2y = y2 - y1\n\n    vlen1 = Math.sqrt(v1x*v1x + v1y*v1y)\n    vlen2 = Math.sqrt(v2x*v2x + v2y*v2y)\n\n    if d > maxr * vlen1\n      d = maxr * vlen1\n    end\n    if d > maxr * vlen2\n      d = maxr * vlen2\n    end\n\n    xy = []\n    xy << (x1 + d * v1x / vlen1) << (y1 + d * v1y / vlen1)\n    xy << x1 << y1\n    xy << (x1 + d * v2x / vlen2) << (y1 + d * v2y / vlen2)\n\n    return xy\n  end\n\n  def sparkle(oxy, tag)\n    xy = [\n      [299, 283], [298, 302], [295, 314], [271, 331], \n      [239, 310], [242, 292], [256, 274], [281, 273]\n    ]\n    xy.each{|x, y|\n      TkcLine.new(@canvas, 271, 304, x, y, \n                  :fill=>'white', :width=>3, :tag=>tag)\n    }\n    move_abs(tag, oxy)\n  end\n\n  def centroid(item)\n    anchor(item, :c)\n  end\n\n  def anchor(item, where)\n    x1, y1, x2, y2 = @canvas.bbox(item)\n    case(where)\n    when :n\n      y = y1\n    when :s\n      y = y2\n    else\n      y = (y1 + y2) / 2.0\n    end\n    case(where)\n    when :w\n      x = x1\n    when :e\n      x = x2\n    else\n      x = (x1 + x2) / 2.0\n    end\n    return [x, y]\n  end\nend\n\nTkGoldberg_Demo.new(base_frame)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/hello",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\n\n#unless /^8\\.[1-9]/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK\n#  require 'tkencoding'\n#end\n\nTkButton.new(nil,\n\t'text'=>\"Hello Ruby world!\",\n\t'font'=>TkFont.new('k14'),\n\t'command'=>proc{print \"Hello Ruby world!\\n\"; exit}\n).pack\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/hscale.rb",
    "content": "require \"tkcanvas\"\n\nif defined?($hscale_demo) && $hscale_demo\n  $hscale_demo.destroy\n  $hscale_demo = nil\nend\n\n$hscale_demo = TkToplevel.new {|w|\n  title(\"Horizontal Scale Demonstration\")\n  iconname(\"hscale\")\n}\npositionWindow($hscale_demo)\n\nbase_frame = TkFrame.new($hscale_demo).pack(:fill=>:both, :expand=>true)\n\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '3.5i'\n  justify 'left'\n  text \"An arrow and a horizontal scale are displayed below.  If you click or drag mouse button 1 in the scale, you can change the length of the arrow.\"\n}\nmsg.pack('side'=>'top')\n\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc {\n      tmppath = $hscale_demo\n      $hscale_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc { showCode 'hscale' }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n\ndef setWidth(w, width)\n  width = width + 21\n  x2 = width - 30\n  if x2 < 21\n    x2 = 21\n  end\n  w.coords 'poly',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15\n  w.coords 'line',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15\nend\n\nTkFrame.new(base_frame) {|frame|\n  canvas = TkCanvas.new(frame) {|c|\n    width 50\n    height 50\n    bd 0\n    highlightthickness 0\n    TkcPolygon.new(c, '0', '0', '1', '1', '2', '2') {\n      fill 'DeepSkyBlue'\n      tags 'poly'\n    }\n    TkcLine.new(c, '0', '0', '1', '1', '2', '2', '0', '0') {\n      fill 'black'\n      tags 'line'\n    }\n  }.pack('side'=>'top', 'expand'=>'yes', 'anchor'=>'s', 'fill'=>'x', 'padx'=>'15')\n  scale = TkScale.new(frame) {\n    orient 'horizontal'\n    length 284\n    from 0\n    to 250\n    command proc{|value| setWidth(canvas, value)}\n    tickinterval 50\n  }.pack('side'=>'bottom', 'expand'=>'yes', 'anchor'=>'n')\n  scale.set 75\n}.pack('side'=>'top', 'fill'=>'x')\n"
  },
  {
    "path": "ext/tk/sample/demos-en/icon.rb",
    "content": "# icon.rb\n#\n# This demonstration script creates a toplevel window containing\n# buttons that display bitmaps instead of text.\n#\n# iconic button widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($icon_demo) && $icon_demo\n  $icon_demo.destroy \n  $icon_demo = nil\nend\n\n# demo toplevel widget\n$icon_demo = TkToplevel.new {|w|\n  title(\"Iconic Button Demonstration\")\n  iconname(\"icon\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($icon_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"This window shows three ways of using bitmaps or images in radiobuttons and checkbuttons.  On the left are two radiobuttons, each of which displays a bitmap and an indicator.  In the middle is a checkbutton that displays a different image depending on whether it is selected or not.  On the right is a checkbutton that displays a single bitmap but changes its background color to indicate whether or not it is selected. (This change is visible when the mouse pointer is not directy over the button.)\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $icon_demo\n      $icon_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'icon'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# image \nflagup = \\\nTkBitmapImage.new('file'=>[$demo_dir,'..',\n                           'images','flagup.xbm'].join(File::Separator),\n                  'maskfile'=>\\\n                  [$demo_dir,'..','images','flagup.xbm'].join(File::Separator))\nflagdown = \\\nTkBitmapImage.new('file'=>[$demo_dir,'..',\n                           'images','flagdown.xbm'].join(File::Separator),\n                  'maskfile'=>\\\n                  [$demo_dir,'..',\n                    'images','flagdown.xbm'].join(File::Separator))\n\n# create variable\nletters = TkVariable.new\n\n# frame\nTkFrame.new(base_frame, 'borderwidth'=>10){|w|\n  TkFrame.new(w) {|f|\n    # TkRadioButton.new(f){\n    Tk::RadioButton.new(f){\n      bitmap '@' + [$demo_dir,'..',\n                    'images','letters.xbm'].join(File::Separator)\n      variable letters\n      value 'full'\n    }.pack('side'=>'top', 'expand'=>'yes')\n\n    # TkRadioButton.new(f){\n    Tk::RadioButton.new(f){\n      bitmap '@' + [$demo_dir,'..',\n                     'images','noletter.xbm'].join(File::Separator)\n      variable letters\n      value 'empty'\n    }.pack('side'=>'top', 'expand'=>'yes')\n\n  }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m')\n\n  # TkCheckButton.new(w) {\n  Tk::CheckButton.new(w) {\n    image flagdown\n    selectimage flagup\n    indicatoron 0\n    selectcolor self['background']\n  }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m')\n\n  # TkCheckButton.new(w) {\n  Tk::CheckButton.new(w) {\n    bitmap '@' + [$demo_dir,'..',\n                   'images','letters.xbm'].join(File::Separator)\n    indicatoron 0\n    selectcolor 'SeaGreen1'\n  }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m')\n\n}.pack('side'=>'top')\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/image1.rb",
    "content": "## image1.rb\n#\n# This demonstration script displays two image widgets.\n#\n# two image widgets demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($image1_demo) && $image1_demo\n  $image1_demo.destroy \n  $image1_demo = nil\nend\n\n# demo toplevel widget\n$image1_demo = TkToplevel.new {|w|\n  title('Image Demonstration #1')\n  iconname(\"Image1\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($image1_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"This demonstration displays two images, each in a separate label widget.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $image1_demo\n      $image1_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'image1'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# image\nimage1a = \\\nTkPhotoImage.new('file'=>[$demo_dir,'..',\n                          'images','earth.gif'].join(File::Separator))\nimage1b = \\\nTkPhotoImage.new('file'=>[$demo_dir,'..',\n                          'images','earthris.gif'].join(File::Separator))\n\n# label\n#[ TkLabel.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'),\n#  TkLabel.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken')\n#].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')}\n[ Tk::Label.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'),\n  Tk::Label.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken')\n].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/image2.rb",
    "content": "# image2.rb\n#\n# This demonstration script creates a simple collection of widgets\n# that allow you to select and view images in a Tk label.\n#\n# widget demo 'load image' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($image2_demo) && $image2_demo\n  $image2_demo.destroy \n  $image2_demo = nil\nend\n\n# demo toplevel widget\n$image2_demo = TkToplevel.new {|w|\n  title('Image Demonstration #2')\n  iconname(\"Image2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($image2_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"This demonstration allows you to view images using a Tk \\\"photo\\\" image.  First type a directory name in the listbox, then press Enter to load the directory into the listbox.  Then double-click on a file name in the listbox to see that image.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $image2_demo\n      $image2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'image2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# create variable\n$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator))\n\n# image\n$image2a = TkPhotoImage.new\n\n#\nTkLabel.new(base_frame, 'text'=>'Directory:')\\\n.pack('side'=>'top', 'anchor'=>'w')\n\nimage2_e = TkEntry.new(base_frame) {\n  width 30\n  textvariable $dirName\n}.pack('side'=>'top', 'anchor'=>'w')\n\nTkFrame.new(base_frame, 'height'=>'3m', 'width'=>20)\\\n.pack('side'=>'top', 'anchor'=>'w')\n\nTkLabel.new(base_frame, 'text'=>'File:')\\\n.pack('side'=>'top', 'anchor'=>'w')\n\nTkFrame.new(base_frame){|w|\n  s = TkScrollbar.new(w)\n  l = TkListbox.new(w) {\n    width 20\n    height 10\n    yscrollcommand proc{|first,last| s.set first,last}\n  }\n  s.command(proc{|*args| l.yview(*args)})\n  l.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y')\n  s.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y')\n  #l.insert(0,'earth.gif', 'earthris.gif', 'mickey.gif', 'teapot.ppm')\n  l.insert(0,'earth.gif', 'earthris.gif', 'teapot.ppm')\n  l.bind('Double-1', proc{|x,y| loadImage $image2a,l,x,y}, '%x %y')\n\n  image2_e.bind 'Return', proc{loadDir l}\n\n}.pack('side'=>'top', 'anchor'=>'w')\n\n# image \n[ TkFrame.new(base_frame, 'height'=>'3m', 'width'=>20),\n  TkLabel.new(base_frame, 'text'=>'Image:'),\n  TkLabel.new(base_frame, 'image'=>$image2a)\n].each{|w| w.pack('side'=>'top', 'anchor'=>'w')}\n\n# \ndef loadDir(w)\n  w.delete(0,'end')\n  Dir.glob([$dirName,'*'].join(File::Separator)).sort.each{|f|\n    w.insert('end',File.basename(f))\n  }\nend\n\ndef loadImage(img,w,x,y)\n  img.file([$dirName, w.get(\"@#{x},#{y}\")].join(File::Separator))\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/image3.rb",
    "content": "# image3.rb\n#\n# This demonstration script creates a simple collection of widgets\n# that allow you to select and view images in a Tk label.\n#\n# widget demo 'load image' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($image3_demo) && $image3_demo\n  $image3_demo.destroy \n  $image3_demo = nil\nend\n\n# demo toplevel widget\n$image3_demo = TkToplevel.new {|w|\n  title('Image Demonstration #3')\n  iconname(\"Image3\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true)\n\n# \ndef loadDir3(w)\n  w.delete(0,'end')\n  Dir.glob([$dirName,'*'].join(File::Separator)).sort.each{|f|\n    w.insert('end',File.basename(f))\n  }\nend\n\n# selectAndLoadDir3 --\n# This procedure pops up a dialog to ask for a directory to load into\n# the listobx and (if the user presses OK) reloads the directory\n# listbox from the directory named in the demo's entry.\n#\n# Arguments:\n# w -                   Name of the toplevel window of the demo.\ndef selectAndLoadDir3(w, lbox)\n  dir = Tk.chooseDirectory(:initialdir=>$dirName.value, \n                           :parent=>w, :mustexist=>true)\n  if dir.length > 0\n    $dirName.value = dir \n    loadDir3(lbox)\n  end\nend\n\ndef loadImage(w,x,y)\n  $image3a.file([$dirName, w.get(\"@#{x},#{y}\")].join(File::Separator))\nend\n\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"This demonstration allows you to view images using a Tk \\\"photo\\\" image.  First type a directory name in the listbox, then type Return to load the directory into the listbox.  Then double-click on a file name in the listbox to see that image.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $image3_demo\n      $image3_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'image3'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# variable\n$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator))\n\n# image\nbegin\n  $image3a.delete\nrescue\nend\n$image3a = TkPhotoImage.new\n\n#\nimage3_f = TkFrame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\nimage3_df = TkLabelFrame.new(base_frame, :text=>'Directory:')\n\nimage3_ff = TkLabelFrame.new(base_frame, :text=>'File:', \n                             :padx=>'2m', :pady=>'2m')\nimage3_lbx = TkListbox.new(image3_ff, :width=>20, :height=>10) {\n  pack(:side=>:left, :fill=>:y, :expand=>true)\n  yscrollbar(TkScrollbar.new(image3_ff).pack(:side=>:left, :fill=>:y, \n                                             :expand=>true))\n  insert(0, *(%w(earth.gif earthris.gif teapot.ppm)))\n  bind('Double-1', proc{|x,y| loadImage(self, x, y)}, '%x %y')\n}\n\nimage3_ent = TkEntry.new(image3_df, :width=>30, :textvariable=>$dirName){\n  pack(:side=>:left, :fill=>:both, :padx=>'2m', :pady=>'2m', :expand=>true)\n  bind('Return', proc{loadDir3(image3_lbx)})\n}\n\nTkButton.new(image3_df, :pady=>0, :padx=>'2m', :text=>\"Select Dir.\", \n             :command=>proc{selectAndLoadDir3(image3_ent, image3_lbx)}) {\n  pack(:side=>:left, :fill=>:y, :padx=>[0, '2m'], :pady=>'2m')\n}\n\nimage3_if = TkLabelFrame.new(base_frame, :text=>'Image:') {|f|\n  # TkLabel.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m')\n  Tk::Label.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m')\n}\n\nTk.grid(image3_df,  '-',\n        :sticky=>:ew, :padx=>'1m', :pady=>'1m', :in=>image3_f)\nTk.grid(image3_ff, image3_if, \n        :sticky=>:nw, :padx=>'1m', :pady=>'1m', :in=>image3_f)\nTkGrid.columnconfigure(image3_f, 1, :weight=>1)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/items.rb",
    "content": "# items.rb\n#\n# This demonstration script creates a canvas that displays the\n# canvas item types.\n#\n# canvas item types widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($items_demo) && $items_demo\n  $items_demo.destroy \n  $items_demo = nil\nend\n\n# demo toplevel widget\n$items_demo = TkToplevel.new {|w|\n  title(\"Canvas Item Demonstration\")\n  iconname(\"Items\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($items_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"This window contains a canvas widget with examples of the various kinds of items supported by canvases.  The following operations are supported:\\n  Button-1 drag:\\tmoves item under pointer.\\n  Button-2 drag:\\trepositions view.\\n  Button-3 drag:\\tstrokes out area.\\n  Ctrl+f:\\t\\tprints items under area.\"\n}.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $items_demo\n      $items_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'items'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\ncvs = nil\nTkFrame.new(base_frame) {|cf|\n  # canvas \n  cvs = TkCanvas.new(cf) {|c|\n    focus\n    scrollregion '0c 0c 30c 24c'\n    width  '15c'\n    height '10c'\n    relief 'sunken'\n    borderwidth 2\n\n    hs = TkScrollbar.new(cf) {|s|\n      orient 'horizontal'\n      command proc{|*args| c.xview(*args)}\n      c.xscrollcommand proc{|first,last| s.set first,last}\n    }\n\n    vs = TkScrollbar.new(cf) {|s|\n      command proc{|*args| c.yview(*args)}\n      c.yscrollcommand proc{|first,last| s.set first,last}\n    }\n\n    if $tk_version =~ /^4\\.[01]/\n      hs.pack('side'=>'bottom', 'fill'=>'x')\n      vs.pack('side'=>'right', 'fill'=>'y')\n      c.pack('in'=>cf, 'expand'=>'yes', 'fill'=>'both')\n\n    else\n      c.grid('in'=>cf, 'row'=>0, 'column'=>0, \n             'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n      vs.grid('row'=>0, 'column'=>1, \n              'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n      hs.grid('row'=>1, 'column'=>0, \n              'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n      TkGrid.rowconfigure(cf, 0, 'weight'=>1, 'minsize'=>0)\n      TkGrid.columnconfigure(cf, 0, 'weight'=>1, 'minsize'=>0)\n\n    end\n\n  }\n}.pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\n# Display a 3x3 rectangular grid\nTkcRectangle.new(cvs, '0c', '0c', '30c', '24c', 'width'=>2)\nTkcLine.new(cvs, '0c', '8c', '30c', '8c', 'width'=>2)\nTkcLine.new(cvs, '0c', '16c', '30c', '16c', 'width'=>2)\nTkcLine.new(cvs, '10c', '0c', '10c', '24c', 'width'=>2)\nTkcLine.new(cvs, '20c', '0c', '20c', '24c', 'width'=>2)\n\nif $tk_version =~ /^4.*/\n  font1 = '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*'\n  font2 = '-Adobe-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*'\nelse\n  font1 = 'Helvetica 12'\n  font2 = 'Helvetica 24 bold'\nend\nif TkWinfo.depth($root).to_i > 1\n  blue   = 'DeepSkyBlue3'\n  red    = 'red'\n  bisque = 'bisque3'\n  green  = 'SeaGreen3'\nelse\n  blue   = 'black'\n  red    = 'black'\n  bisque = 'black'\n  green  = 'black'\nend\n\n# tag \n$tag_item = TkcGroup.new(cvs)\n\n# Set up demos within each of the areas of the grid.\nTkcText.new(cvs, '5c', '.2c', 'text'=>'Lines', 'anchor'=>'n')\nTkcLine.new(cvs, '1c', '1c', '3c', '1c', '1c', '4c', '3c', '4c', \n            'width'=>2, 'fill'=>blue, 'capstyle'=>'butt', \n            'join'=>'miter', 'tags'=>$tag_item )\nTkcLine.new(cvs, '4.67c','1c','4.67c','4c', 'arrow'=>'last', 'tags'=>$tag_item)\nTkcLine.new(cvs, '6.33c','1c','6.33c','4c', 'arrow'=>'both', 'tags'=>$tag_item)\nTkcLine.new(cvs, '5c','6c','9c','6c','9c','1c','8c','1c','8c','4.8c','8.8c',\n            '4.8c','8.8c','1.2c','8.2c','1.2c','8.2c','4.6c','8.6c','4.6c',\n            '8.6c','1.4c','8.4c','1.4c','8.4c','4.4c',\n            'width'=>3, 'fill'=>red, 'tags'=>$tag_item )\nTkcLine.new(cvs, '1c','5c','7c','5c','7c','7c','9c','7c', 'width'=>'.5c', \n            'stipple'=>'@'+[$demo_dir,'..',\n                            'images','gray25.xbm'].join(File::Separator), \n            'arrow'=>'both', 'arrowshape'=>'15 15 7', 'tags'=>$tag_item )\nTkcLine.new(cvs, '1c','7c','1.75c','5.8c','2.5c','7c','3.25c','5.8c','4c','7c',\n            'width'=>'.5c', 'capstyle'=>'round', 'join'=>'round', \n            'tags'=>$tag_item )\n\nTkcText.new(cvs, '15c', '.2c', \n            'text'=>'Curves (smoothed lines)', 'anchor'=>'n')\nTkcLine.new(cvs, '11c','4c','11.5c','1c','13.5c','1c','14c','4c', \n            'smooth'=>'on', 'fill'=>blue, 'tags'=>$tag_item )\nTkcLine.new(cvs, '15.5c','1c','19.5c','1.5c','15.5c','4.5c','19.5c','4c', \n            'smooth'=>'on', 'arrow'=>'both', 'width'=>3, 'tags'=>$tag_item )\nTkcLine.new(cvs, '12c','6c','13.5c','4.5c','16.5c','7.5c','18c','6c', \n            '16.5c','4.5c','13.5c','7.5c','12c','6c',\n            'smooth'=>'on', 'width'=>'3m', 'capstyle'=>'round', \n            'stipple'=>'@'+[$demo_dir, '..',\n                            'images', 'gray25.xbm'].join(File::Separator), \n            'fill'=>red, 'tags'=>$tag_item )\n\nTkcText.new(cvs, '25c', '.2c', 'text'=>'Polygons', 'anchor'=>'n')\nTkcPolygon.new(cvs, '21c','1.0c','22.5c','1.75c','24c','1.0c','23.25c','2.5c',\n               '24c','4.0c','22.5c','3.25c','21c','4.0c','21.75c','2.5c',\n               'fill'=>'green', 'outline'=>'black', 'width'=>4, \n               'tags'=>$tag_item )\nTkcPolygon.new(cvs, '25c','4c','25c','4c','25c','1c','26c','1c','27c','4c',\n               '28c','1c','29c','1c','29c','4c','29c','4c',\n               'fill'=>red, 'smooth'=>'on', 'tags'=> $tag_item)\nTkcPolygon.new(cvs, '22c','4.5c','25c','4.5c','25c','6.75c','28c','6.75c',\n               '28c','5.25c','24c','5.25c','24c','6.0c','26c','6c','26c',\n               '7.5c','22c','7.5c', \n               'stipple'=>'@' + [$demo_dir, '..',\n                                 'images', 'gray25.xbm'].join(File::Separator),\n               'outline'=>'black', 'tags'=>$tag_item )\n\nTkcText.new(cvs, '5c', '8.2c', 'text'=>'Rectangles', 'anchor'=>'n')\nTkcRectangle.new(cvs, '1c','9.5c','4c','12.5c',\n                 'outline'=>red, 'width'=>'3m', 'tags'=>$tag_item)\nTkcRectangle.new(cvs, '0.5c','13.5c','4.5c','15.5c', \n                 'fill'=>green, 'tags'=>$tag_item )\nTkcRectangle.new(cvs, '6c','10c','9c','15c', 'outline'=>'',\n                 'stipple'=>'@'+[$demo_dir,'..',\n                                 'images','gray25.xbm'].join(File::Separator),\n                 'fill'=>blue, 'tags'=>$tag_item )\n\nTkcText.new(cvs, '15c', '8.2c', 'text'=>'Ovals', 'anchor'=>'n')\nTkcOval.new(cvs, '11c','9.5c','14c','12.5c',\n                 'outline'=>red, 'width'=>'3m', 'tags'=>$tag_item)\nTkcOval.new(cvs, '10.5c','13.5c','14.5c','15.5c', \n                 'fill'=>green, 'tags'=>$tag_item )\nTkcOval.new(cvs, '16c','10c','19c','15c', 'outline'=>'',\n                 'stipple'=>'@'+[$demo_dir,'..',\n                                 'images','gray25.xbm'].join(File::Separator),\n                 'fill'=>blue, 'tags'=>$tag_item )\n\nTkcText.new(cvs, '25c', '8.2c', 'text'=>'Text', 'anchor'=>'n')\nTkcRectangle.new(cvs, '22.4c','8.9c','22.6c','9.1c')\nTkcText.new(cvs, '22.5c', '9c', 'anchor'=>'n', 'font'=>font1, 'width'=>'4c', \n            'text'=>'A short string of text, word-wrapped, justified left, and anchored north (at the top).  The rectangles show the anchor points for each piece of text.', 'tags'=>$tag_item )\nTkcRectangle.new(cvs, '25.4c','10.9c','25.6c','11.1c')\nTkcText.new(cvs, '25.5c', '11c', 'anchor'=>'w', 'font'=>font1, 'fill'=>blue, \n            'text'=>\"Several lines,\\n each centered\\nindividually,\\nand all anchored\\nat the left edge.\", 'justify'=>'center', 'tags'=>$tag_item )\nTkcRectangle.new(cvs, '24.9c','13.9c','25.1c','14.1c')\nif $tk_version =~ /^4\\.[01]/\n  TkcText.new(cvs, '25c', '14c', 'anchor'=>'c', 'font'=>font2, 'fill'=>red, \n              'stipple'=>'@' + [$demo_dir, '..',\n                                'images', 'grey.5'].join(File::Separator),\n              'text'=>'Stippled characters', 'tags'=>$tag_item )\nelse\n  TkcText.new(cvs, '25c', '14c', 'anchor'=>'c', 'font'=>font2, 'fill'=>red, \n              'stipple'=>'gray50', 'text'=>'Stippled characters', \n              'tags'=>$tag_item )\nend\n\nTkcText.new(cvs, '5c', '16.2c', 'text'=>'Arcs', 'anchor'=>'n')\nTkcArc.new(cvs, '0.5c','17c','7c','20c', 'fill'=>green, 'outline'=>'black', \n           'start'=>45, 'extent'=>270, 'style'=>'pieslice', 'tags'=>$tag_item)\n#TkcArc.new(cvs, '6.5c','17c','9.5c','20c', 'width'=>'4m', 'style'=>'arc', \n#          'outline'=>blue, 'start'=>135, 'extent'=>270, \n#          'outlinestipple'=>'@' + ['images', 'grey.25'].join(File::Separator),\n#          'tags'=>$tag_item)\nTkcArc.new(cvs, '6.5c','17c','9.5c','20c', 'width'=>'4m', 'style'=>'arc', \n           'outline'=>blue, 'start'=>135, 'extent'=>270, \n           'outlinestipple'=>'@'+[$demo_dir, '..',\n                                  'images','gray25.xbm'].join(File::Separator),\n           'tags'=>$tag_item)\nTkcArc.new(cvs, '0.5c','20c','9.5c','24c', 'width'=>'4m', 'style'=>'pieslice', \n           'fill'=>'', 'outline'=>red, 'start'=>225, 'extent'=>90, \n           'tags'=>$tag_item)\nTkcArc.new(cvs, '5.5c','20.5c','9.5c','23.5c', 'width'=>'4m', 'style'=>'chord',\n           'fill'=>blue, 'outline'=>'', 'start'=>45, 'extent'=>270, \n           'tags'=>$tag_item)\n\nTkcText.new(cvs, '15c', '16.2c', 'text'=>'Bitmaps', 'anchor'=>'n')\n#TkcBitmap.new(cvs, '13c','20c',\n#             'bitmap'=>'@' + ['images', 'face'].join(File::Separator),\n#             'tags'=>$tag_item)\nTkcBitmap.new(cvs, '13c','20c',\n              'bitmap'=>'@' + [$demo_dir, '..',\n                               'images', 'face.xbm'].join(File::Separator),\n              'tags'=>$tag_item)\n#TkcBitmap.new(cvs, '17c','18.5c',\n#             'bitmap'=>'@' + ['images', 'noletters'].join(File::Separator),\n#             'tags'=>$tag_item)\nTkcBitmap.new(cvs, '17c','18.5c',\n              'bitmap'=>'@' + [$demo_dir, '..',\n                               'images', 'noletter.xbm'].join(File::Separator),\n              'tags'=>$tag_item)\n#TkcBitmap.new(cvs, '17c','21.5c',\n#             'bitmap'=>'@' + ['images', 'letters'].join(File::Separator),\n#             'tags'=>$tag_item)\n# \nTkcBitmap.new(cvs, '17c','21.5c') {\n  bitmap '@' + [$demo_dir, '..', 'images', 'letters.xbm'].join(File::Separator)\n  tags $tag_item\n}\n#TkcBitmap.new(cvs, '17c','21.5c') {\n#  bitmap '@' + ['images', 'letters'].join(File::Separator)\n#  tags $tag_item\n#}\n\nTkcText.new(cvs, '25c', '16.2c', 'text'=>'Windows', 'anchor'=>'n')\nTkButton.new(cvs) {|b|\n  text 'Press Me'\n  command proc{butPress cvs, red}\n  TkcWindow.new(cvs, '21c','18c', \n                'window'=>b, 'anchor'=>'nw', 'tags'=>$tag_item)\n}\nTkEntry.new(cvs, 'width'=>20, 'relief'=>'sunken') {|e|\n  insert 'end', 'Edit this text'\n  TkcWindow.new(cvs, '21c','21c', \n                'window'=>e, 'anchor'=>'nw', 'tags'=>$tag_item)\n}\nTkScale.new(cvs, 'from'=>0, 'to'=>100, 'length'=>'6c', 'sliderlength'=>'.4c', \n            'width'=>'.5c', 'tickinterval'=>0 ) {|scl|\n  TkcWindow.new(cvs, '28.5c','17.5c', \n                'window'=>scl, 'anchor'=>'n', 'tags'=>$tag_item)\n}\nTkcText.new(cvs, '21c', '17.9c', 'text'=>'Button:', 'anchor'=>'sw')\nTkcText.new(cvs, '21c', '20.9c', 'text'=>'Entry:', 'anchor'=>'sw')\nTkcText.new(cvs, '28.5c', '17.4c', 'text'=>'Scale:', 'anchor'=>'s')\n\n# Set up event bindings for canvas:\ncvs.itembind($tag_item, 'Any-Enter', proc{itemEnter cvs})\ncvs.itembind($tag_item, 'Any-Leave', proc{itemLeave cvs})\ncvs.bind('2', proc{|x,y| cvs.scan_mark x,y}, '%x %y')\ncvs.bind('B2-Motion', proc{|x,y| cvs.scan_dragto x,y}, '%x %y')\ncvs.bind('3', proc{|x,y| itemMark cvs,x,y}, '%x %y')\ncvs.bind('B3-Motion', proc{|x,y| itemStroke cvs,x,y}, '%x %y')\ncvs.bind('Control-f', proc{itemsUnderArea cvs})\ncvs.bind('1', proc{|x,y| itemStartDrag cvs,x,y}, '%x %y')\ncvs.bind('B1-Motion', proc{|x,y| itemDrag cvs,x,y}, '%x %y')\n# Utility methods for highlighting the item under the pointer\n\n$restoreCmd = nil\ndef itemEnter (c)\n  if TkWinfo.depth(c).to_i == 1\n    $restoreCmd = nil\n    return\n  end\n  type = c.itemtype('current')\n  if type == TkcWindow\n    $restoreCmd = nil\n    return\n  end\n  if type == TkcBitmap\n    bg = (c.itemconfiginfo('current', 'background'))[4]\n    $restoreCmd = proc{c.itemconfigure 'current', 'background', bg}\n    c.itemconfigure 'current', 'background', 'SteelBlue2'\n    return\n  end\n  fill = (c.itemconfiginfo('current', 'fill'))[4]\n  if (type == TkcRectangle || type == TkcOval || type == TkcArc) && fill == []\n    outline = (c.itemconfiginfo('current', 'outline'))[4]\n    $restoreCmd = proc{c.itemconfigure 'current', 'outline', outline}\n    c.itemconfigure 'current', 'outline', 'SteelBlue2'\n  else\n    $restoreCmd = proc{c.itemconfigure 'current', 'fill', fill}\n    c.itemconfigure 'current', 'fill', 'SteelBlue2'\n  end\nend\n\ndef itemLeave(c)\n  $restoreCmd.call if $restoreCmd\nend\n\n# Utility methods for stroking out a rectangle and printing what's \n# underneath the rectangle's area.\n\ndef itemMark(c,x,y)\n  $areaX1 = c.canvasx(x)\n  $areaY1 = c.canvasy(y)\n  c.delete 'area'\nend\n\ndef itemStroke(c,x,y)\n  x = c.canvasx(x)\n  y = c.canvasy(y)\n  if $areaX1 != x && $areaY1 != y\n    c.delete 'area'\n    c.addtag_withtag 'area', TkcRectangle.new(c, $areaX1, $areaY1, x, y, \n                                              '-outline', 'black')\n    $areaX2 = x\n    $areaY2 = y\n  end\nend\n\ndef itemsUnderArea(c)\n  area = c.find_withtag('area')\n  items = []\n  c.find_enclosed($areaX1,$areaY1,$areaX2,$areaY2).each{|i|\n    items.push(i) if i.gettags.include?($tag_item)\n  }\n  print \"Items enclosed by area: #{items.inspect}\\n\"; STDOUT.flush\n  items.clear\n  c.find_overlapping($areaX1,$areaY1,$areaX2,$areaY2).each{|i|\n    items.push(i) if i.gettags.include?($tag_item)\n  }\n  print \"Items overlapping area: #{items.inspect}\\n\"; STDOUT.flush\nend\n\n$areaX1 = 0\n$areaY1 = 0\n$areaX2 = 0\n$areaY2 = 0\n\n# Utility methods to support dragging of items.\n\ndef itemStartDrag(c,x,y)\n  $lastX = c.canvasx(x)\n  $lastY = c.canvasy(y)\nend\n\ndef itemDrag(c,x,y)\n  x = c.canvasx(x)\n  y = c.canvasy(y)\n  c.move 'current', x - $lastX, y - $lastY\n  $lastX = x\n  $lastY = y\nend\n\n# Method that's invoked when the button embedded in the canvas \n# is invoked.\n\ndef butPress(w,color)\n  i = TkcText.new(w, '25c', '18.1c', \n                  'text'=>'Ouch!!', 'fill'=>color, 'anchor'=>'n')\n  Tk.after(500, proc{w.delete i})\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ixset",
    "content": "#!/usr/bin/env ruby\n\n# ixset --\n# A nice interface to \"xset\" to change X server settings\n#\n\nrequire 'tk'\n\nclass Xsettings\n  #\n  # Button actions\n  #\n  def quit\n    @root.destroy\n  end\n\n  def ok\n    writesettings\n    quit\n  end\n\n  def cancel\n    readsettings\n    dispsettings\n  end\n\n  # apply is just \"writesettings\"\n\n\n  #\n  # Read current settings\n  #\n  def readsettings\n    xfd = open(\"|xset q\", 'r')\n    xfd.readlines.each{|line|\n      fields = line.chomp.strip.split(/\\s+/)\n      case fields[0]\n      when \"auto\"\n\tif fields[1] == 'repeat:'\n\t  @kbdrep = fields[2]\n\t  @w_kbdrep.set(@kbdrep)\n\t  @kbdcli = fields[6]\n\tend\n\n      when \"bell\"\n\t@bellvol = fields[2]\n\t@bellpit = fields[5]\n\t@belldur = fields[8]\n\n      when \"acceleration:\"\n\t@mouseacc = fields[1]\n\t@mousethr = fields[3]\n\n      when \"prefer\"\n\tif fields[2] == 'yes'\n\t  @screenbla = 'blank'\n\telse\n\t  @screenbla = 'noblank'\n\tend\n\t@w_screenbla.set(@screenbla)\n\n      when \"timeout:\"\n\t@screentim = fields[1]\n\t@screencyc = fields[3]\n\n      end\n    }\n\n    xfd.close\n  end\n\n  #\n  # Write settings into the X server\n  #\n  def writesettings\n    @bellvol = @w_bellvol.get\n    @bellpit = @w_bellpit.get\n    @belldur = @w_belldur.get\n\n    @kbdrep = @w_kbdrep.get\n    if @kbdrep == 'on'\n      @kbdcli = @w_kbdcli.get\n    else\n      @kbdcli = 'off'\n    end\n\n    @mouseacc = @w_mouseacc.get\n    @mousethr = @w_mousethr.get\n\n    @screentim = @w_screentim.get\n    @screencyc = @w_screencyc.get\n    @screenbla = @w_screenbla.get\n\n    system(\"xset \\\n            b #{@bellvol} #{@bellpit} #{@belldur} \\\n            c #{@kbdcli} \\\n            r #{@kbdrep} \\\n            m #{@mouseacc} #{@mousethr} \\\n            s #{@screentim} #{@screencyc} \\\n            s #{@screenbla}\")\n  end\n\n  #\n  # Sends all settings to the window\n  #\n  def dispsettings\n    @w_bellvol.set(@bellvol)\n    @w_bellpit.set(@bellpit)\n    @w_belldur.set(@belldur)\n\n    @w_kbdonoff.set(@w_kbdrep.get)\n    @w_kbdcli.set(@kbdcli)\n\n    @w_mouseacc.set(@mouseacc)\n    @w_mousethr.set(@mousethr)\n\n    @w_screenblank.set(@w_screenbla.get)\n    @w_screenpat.set(@w_screenbla.get)\n\n    @w_screentim.set(@screentim)\n    @w_screencyc.set(@screencyc)\n  end\n\n  #\n  # Create all windows, and pack them\n  #\n  class LabelEntry\n    def initialize(parent, text, length)\n      @frame = TkFrame.new(parent)\n      TkLabel.new(@frame, 'text'=>text).pack('side'=>'left','expand'=>'y')\n      @entry = TkEntry.new(@frame, 'width'=>length, 'relief'=>'sunken') {\n\tpack('side'=>'left','expand'=>'y')\n      }\n    end\n    def pack(keys)\n      @frame.pack(keys)\n    end\n    def get\n      @entry.value\n    end\n    def set(value)\n      @entry.delete(0,'end')\n      @entry.insert(0, value)\n    end\n  end\n\n  def createwindows\n    win = self\n\n    #\n    # Buttons\n    #\n    buttons = TkFrame.new(@root) {|f|\n      [ TkButton.new(f, 'command'=>proc{win.ok}, 'text'=>'Ok'),\n\tTkButton.new(f, 'command'=>proc{win.writesettings}, 'text'=>'Apply'),\n\tTkButton.new(f, 'command'=>proc{win.cancel}, 'text'=>'Cancel'),\n\tTkButton.new(f, 'command'=>proc{win.quit}, 'text'=>'Quit') ].each{|b|\n\tb.pack('side'=>'left', 'expand'=>'yes', 'pady'=>5)\n      }\n    }\n\n    #\n    # Bell settings\n    #\n    bell = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(bell, 'text'=>'Bell Settings')\n    @w_bellvol = TkScale.new(bell, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t     'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t     'label'=>\"Volume (%)\")\n\n    f = TkFrame.new(bell)\n    @w_bellpit = LabelEntry.new(f, \"Pitch (Hz)\", 6)\n    @w_bellpit.pack('side'=>'left', 'padx'=>5)\n    @w_belldur = LabelEntry.new(f, \"Duration (ms)\", 6)\n    @w_belldur.pack('side'=>'right', 'padx'=>5)\n\n    l.pack('side'=>'top', 'expand'=>'yes')\n    @w_bellvol.pack('side'=>'top', 'expand'=>'yes')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Keyboard settings\n    # \n    kbdonoff = nil\n    kbdcli = nil\n    kbd = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(kbd, 'text'=>'Keyboard Repeat Settings')\n    f = TkFrame.new(kbd)\n    @w_kbdonoff = TkCheckButton.new(f, 'text'=>'On', 'relief'=>'flat', \n\t\t\t\t    'onvalue'=>'on', 'offvalue'=>'off',\n\t\t\t\t    'variable'=>@w_kbdrep ) {\n      def self.set(value)\n\tif value == 'on'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n      pack('side'=>'left', 'expand'=>'yes', 'fill'=>'both')\n    }\n    @w_kbdcli = TkScale.new(f, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t 'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t 'label'=>'Click Volume (%)')\n    @w_kbdcli.pack('side'=>'left', 'expand'=>'yes')\n    l.pack('side'=>'top', 'expand'=>'yes')\n    f.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'fill'=>'x')\n\n    #\n    # Mouse settings\n    #\n    mouse = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(mouse, 'text'=>'Mouse Settings')\n    f = TkFrame.new(mouse)\n    @w_mouseacc = LabelEntry.new(f, 'Acceleration', 3)\n    @w_mouseacc.pack('side'=>'left')\n    @w_mousethr = LabelEntry.new(f, 'Threshold (pixels)', 3)\n    @w_mousethr.pack('side'=>'right')\n    l.pack('side'=>'top')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Screen Saver settings\n    #\n    screen = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(screen, 'text'=>'Screen-saver Settings')\n    f = TkFrame.new(screen)\n    ff1 = TkFrame.new(f)\n    [ @w_screenblank = TkRadioButton.new(ff1, 'text'=>'Blank', \n\t\t\t\t\t 'relief'=>'flat', \n\t\t\t\t\t 'variable'=>@w_screenbla, \n\t\t\t\t\t 'value'=>'blank') {\n\tdef self.set(value)\n\t  if value == 'blank'\n\t    self.select\n\t  else\n\t    self.deselect\n\t  end\n\tend\n      }, \n      @w_screenpat = TkRadioButton.new(ff1, 'text'=>'Pattern', \n\t\t\t\t       'relief'=>'flat', \n\t\t\t\t       'variable'=>@w_screenbla, \n\t\t\t\t       'value'=>'noblank') {\n\tdef self.set(value)\n\t  if value != 'blank'\n\t    self.select\n\t  else\n\t    self.deselect\n\t  end\n\tend\n      }\n    ].each {|w| w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w') }\n\n    ff2 = TkFrame.new(f)\n    [ @w_screentim = LabelEntry.new(ff2, 'Timeout (s)', 5), \n      @w_screencyc = LabelEntry.new(ff2, 'Cycle (s)', 5) ].each{|w|\n      w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'e')\n    }\n\n    ff1.pack('side'=>'left')\n    ff2.pack('side'=>'left')\n\n    l.pack('side'=>'top')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Main window\n    #\n    buttons.pack('side'=>'top', 'fill'=>'both')\n    bell.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n    kbd.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n    mouse.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n    screen.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n\n    #\n    # Let the user resize our window\n    #\n    @root.minsize(10,10)\n  end\n\n  def initialize\n    @root = TkRoot.new\n\n    @kbdrep = 'on'\n    @w_kbdrep = TkVariable.new(@kbdrep)\n    def @w_kbdrep.get\n      self.value\n    end\n    def @w_kbdrep.set(val)\n      self.value=val\n    end\n\n    @kbdcli = 0\n\n    @bellvol = 100\n    @bellpit = 440\n    @belldur = 100\n\n    @mouseacc = \"3/1\"\n    @mousethr = 4\n\n    @screenbla = \"blank\"\n    @w_screenbla = TkVariable.new(@screenbla)\n    def @w_screenbla.get\n      self.value\n    end\n    def @w_screenbla.set(val)\n      self.value=val\n    end\n\n    @screentim = 600\n    @screencyc = 600\n\n    #\n    # Listen what \"xset\" tells us...\n    #\n    readsettings\n\n    #\n    # Create all windows\n    #\n    createwindows\n\n    #\n    # Write xset parameters\n    #\n    dispsettings\n  end\nend\n\nXsettings.new\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ixset2",
    "content": "#!/usr/bin/env ruby\n#\n# ixset --\n# A nice interface to \"xset\" to change X server settings\n#\n\nrequire 'tk'\n\nclass Xsettings\n  #\n  # Button actions\n  #\n  def quit\n    @root.destroy\n  end\n\n  def ok\n    writesettings\n    quit\n  end\n\n  def cancel\n    readsettings\n    dispsettings\n    @btn_APPLY.state(:disabled)\n    @btn_CANCEL.state(:disabled)\n  end\n\n  # apply is just \"writesettings\"\n  def apply\n    writesettings\n    @btn_APPLY.state(:disabled)\n    @btn_CANCEL.state(:disabled)\n  end\n\n  #\n  # Read current settings\n  #\n  def readsettings\n    xfd = open(\"|xset q\", 'r')\n    xfd.readlines.each{|line|\n      fields = line.chomp.strip.split(/\\s+/)\n      case fields[0]\n      when \"auto\"\n\tif fields[1] == 'repeat:'\n\t  @kbdrep = fields[2]\n\t  @w_kbdrep.set(@kbdrep)\n\t  @kbdcli = fields[6]\n\tend\n\n      when \"bell\"\n\t@bellvol = fields[2]\n\t@bellpit = fields[5]\n\t@belldur = fields[8]\n\n      when \"acceleration:\"\n\t@mouseacc = fields[1]\n\t@mousethr = fields[3]\n\n      when \"prefer\"\n\tif fields[2] == 'yes'\n\t  @screenbla = 'blank'\n\telse\n\t  @screenbla = 'noblank'\n\tend\n\t@w_screenbla.set(@screenbla)\n\n      when \"timeout:\"\n\t@screentim = fields[1]\n\t@screencyc = fields[3]\n\n      end\n    }\n\n    xfd.close\n  end\n\n  #\n  # Write settings into the X server\n  #\n  def writesettings\n    @bellvol = @w_bellvol.get\n    @bellpit = @w_bellpit.get\n    @belldur = @w_belldur.get\n\n    @kbdrep = @w_kbdrep.get\n    if @kbdrep == 'on'\n      @kbdcli = @w_kbdcli.get\n    else\n      @kbdcli = 'off'\n    end\n\n    @mouseacc = @w_mouseacc.get\n    @mousethr = @w_mousethr.get\n\n    @screentim = @w_screentim.get\n    @screencyc = @w_screencyc.get\n    @screenbla = @w_screenbla.get\n\n    system(\"xset \\\n            b #{@bellvol} #{@bellpit} #{@belldur} \\\n            c #{@kbdcli} \\\n            r #{@kbdrep} \\\n            m #{@mouseacc} #{@mousethr} \\\n            s #{@screentim} #{@screencyc} \\\n            s #{@screenbla}\")\n  end\n\n  #\n  # Sends all settings to the window\n  #\n  def dispsettings\n    @w_bellvol.set(@bellvol)\n    @w_bellpit.set(@bellpit)\n    @w_belldur.set(@belldur)\n\n    @w_kbdonoff.set(@w_kbdrep.get)\n    @w_kbdcli.set(@kbdcli)\n\n    @w_mouseacc.set(@mouseacc)\n    @w_mousethr.set(@mousethr)\n\n    @w_screenblank.set(@w_screenbla.get)\n    @w_screenpat.set(@w_screenbla.get)\n\n    @w_screentim.set(@screentim)\n    @w_screencyc.set(@screencyc)\n  end\n\n  #\n  # Create all windows, and pack them\n  #\n  class LabelEntry\n    def initialize(parent, text, length, range=[])\n      @frame = TkFrame.new(parent)\n      TkLabel.new(@frame, 'text'=>text).pack('side'=>'left')\n      if range.size > 0 \n\t@entry = TkSpinbox.new(@frame, 'width'=>length, 'relief'=>'sunken', \n\t\t\t       'from'=>range[0], 'to'=>range[1])\n      else\n\t@entry = TkEntry.new(@frame, 'width'=>length, 'relief'=>'sunken')\n      end\n      @entry.pack('side'=>'right','expand'=>'y', 'fill'=>'x')\n    end\n    def epath\n      @frame\n    end\n    def pack(keys)\n      @frame.pack(keys)\n    end\n    def get\n      @entry.value\n    end\n    def set(value)\n      @entry.delete(0,'end')\n      @entry.insert(0, value)\n    end\n  end\n\n  def createwindows\n    win = self\n\n    #\n    # Buttons\n    #\n    btn_frame = TkFrame.new(@root)\n    buttons = [ \n      @btn_OK = TkButton.new(btn_frame, 'command'=>proc{win.ok}, \n\t\t\t     'default'=>'active', 'text'=>'Ok'),\n      @btn_APPLY = TkButton.new(btn_frame, 'command'=>proc{win.writesettings}, \n\t\t\t\t'default'=>'normal', 'text'=>'Apply', \n\t\t\t\t'state'=>'disabled'),\n      @btn_CANCEL = TkButton.new(btn_frame, 'command'=>proc{win.cancel}, \n\t\t\t\t 'default'=>'normal', 'text'=>'Cancel', \n\t\t\t\t'state'=>'disabled'),\n      @btn_QUIT = TkButton.new(btn_frame, 'command'=>proc{win.quit}, \n\t\t\t       'default'=>'normal', 'text'=>'Quit')\n    ]\n    buttons.each{|b| b.pack('side'=>'left', 'expand'=>'yes', 'pady'=>5) }\n\n    @root.bind('Return', proc{@btn_OK.flash; @btn_OK.invoke})\n    @root.bind('Escape', proc{@btn_QUIT.flash; @btn_QUIT.invoke})\n    @root.bind('1', proc{|w|\n\t\t unless buttons.index(w)\n\t\t   @btn_APPLY.state(:normal)\n\t\t   @btn_CANCEL.state(:normal)\n\t\t end\n\t       }, '%W')\n    @root.bind('Key', proc{|w, k|\n\t\t unless buttons.index(w)\n\t\t   case k\n\t\t   when 'Return', 'Escape', 'Tab', /.*Shift.*/\n\t\t     # do nothing\n\t\t   else\n\t\t     @btn_APPLY.state(:normal)\n\t\t     @btn_CANCEL.state(:normal)\n\t\t   end\n\t\t end\n\t       }, '%W %K')\n\n    #\n    # Bell settings\n    #\n    bell = TkLabelframe.new(@root, 'text'=>'Bell Settings', \n\t\t\t    'padx'=>'1.5m', 'pady'=>'1.5m')\n    @w_bellvol = TkScale.new(bell, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t     'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t     'label'=>\"Volume (%)\")\n\n    f = TkFrame.new(bell)\n    @w_bellpit = LabelEntry.new(f, \"Pitch (Hz)\", 6, [25, 20000])\n    @w_bellpit.pack('side'=>'left', 'padx'=>5)\n    @w_belldur = LabelEntry.new(f, \"Duration (ms)\", 6, [1, 10000])\n    @w_belldur.pack('side'=>'right', 'padx'=>5)\n\n    @w_bellvol.pack('side'=>'top', 'expand'=>'yes')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Keyboard settings\n    # \n    kbdonoff = nil\n    kbdcli = nil\n    kbd = TkLabelframe.new(@root, 'text'=>'Keyboard Repeat Settings', \n\t\t\t   'padx'=>'1.5m', 'pady'=>'1.5m')\n    f = TkFrame.new(kbd)\n    @w_kbdonoff = TkCheckButton.new(f, 'text'=>'On', 'relief'=>'flat', \n\t\t\t\t    'onvalue'=>'on', 'offvalue'=>'off',\n\t\t\t\t    'variable'=>@w_kbdrep ) {\n      def self.set(value)\n\tif value == 'on'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n      pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x', 'padx'=>[0, '1m'])\n    }\n    @w_kbdcli = TkScale.new(f, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t 'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t 'label'=>'Click Volume (%)')\n    @w_kbdcli.pack('side'=>'left', 'expand'=>'yes', \n\t\t   'fill'=>'x', 'padx'=>['1m', 0])\n    f.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'fill'=>'x')\n\n    #\n    # Mouse settings\n    #\n    mouse = TkLabelframe.new(@root, 'text'=>'Mouse Settings', \n\t\t\t     'padx'=>'1.5m', 'pady'=>'1.5m')\n    f = TkFrame.new(mouse)\n    @w_mouseacc = LabelEntry.new(f, 'Acceleration', 5)\n    @w_mouseacc.pack('side'=>'left', 'padx'=>[0, '1m'])\n    @w_mousethr = LabelEntry.new(f, 'Threshold (pixels)', 3, [1, 2000])\n    @w_mousethr.pack('side'=>'right', 'padx'=>['1m', 0])\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Screen Saver settings\n    #\n    screen = TkLabelframe.new(@root, 'text'=>'Screen-saver Settings', \n\t\t\t     'padx'=>'1.5m', 'pady'=>'1.5m')\n    @w_screenblank = TkRadioButton.new(screen, 'text'=>'Blank', \n\t\t\t\t       'relief'=>'flat', 'anchor'=>'w', \n\t\t\t\t       'variable'=>@w_screenbla, \n\t\t\t\t       'value'=>'blank') {\n      def self.set(value)\n\tif value == 'blank'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n    }\n\n    @w_screenpat = TkRadioButton.new(screen, 'text'=>'Pattern', \n\t\t\t\t     'relief'=>'flat', 'anchor'=>'w', \n\t\t\t\t     'variable'=>@w_screenbla, \n\t\t\t\t     'value'=>'noblank') {\n      def self.set(value)\n\tif value != 'blank'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n    }\n\n    @w_screentim = LabelEntry.new(screen, 'Timeout (s)', 5, [1, 100000])\n    @w_screencyc = LabelEntry.new(screen, 'Cycle (s)', 5, [1, 100000])\n\n    Tk.grid(@w_screenblank, @w_screentim, 'sticky'=>'e')\n    Tk.grid(@w_screenpat, @w_screencyc, 'sticky'=>'e')\n    TkGrid.configure(@w_screenblank, @w_screenpat, 'sticky'=>'ew')\n\n    #\n    # Main window\n    #\n    param = {\n      'side'=>'top', 'fill'=>'both', 'expand'=>'yes', \n      'padx'=>'1m', 'pady'=>'1m'\n    }\n    btn_frame.pack('side'=>'top', 'fill'=>'both')\n    bell.pack(param)\n    kbd.pack(param)\n    mouse.pack(param)\n    screen.pack(param)\n\n    #\n    # Let the user resize our window\n    #\n    @root.minsize(10,10)\n  end\n\n  def initialize(title)\n    @root = TkRoot.new('title'=>title)\n\n    @kbdrep = 'on'\n    @w_kbdrep = TkVariable.new(@kbdrep)\n    def @w_kbdrep.get\n      self.value\n    end\n    def @w_kbdrep.set(val)\n      self.value=val\n    end\n\n    @kbdcli = 0\n\n    @bellvol = 100\n    @bellpit = 440\n    @belldur = 100\n\n    @mouseacc = \"3/1\"\n    @mousethr = 4\n\n    @screenbla = \"blank\"\n    @w_screenbla = TkVariable.new(@screenbla)\n    def @w_screenbla.get\n      self.value\n    end\n    def @w_screenbla.set(val)\n      self.value=val\n    end\n\n    @screentim = 600\n    @screencyc = 600\n\n    #\n    # Listen what \"xset\" tells us...\n    #\n    readsettings\n\n    #\n    # Create all windows\n    #\n    createwindows\n\n    #\n    # Write xset parameters\n    #\n    dispsettings\n  end\nend\n\nXsettings.new(File.basename($0,'.rb'))\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/knightstour.rb",
    "content": "# Based on the widget demo of Tcl/Tk8.5.2\n# The following is the original copyright text.\n#----------------------------------------------------------------------------\n# Copyright (C) 2008 Pat Thoyts <patthoyts@users.sourceforge.net>\n#\n#\tCalculate a Knight's tour of a chessboard.\n#\n#\tThis uses Warnsdorff's rule to calculate the next square each\n#\ttime. This specifies that the next square should be the one that\n#\thas the least number of available moves.\n#\n#\tUsing this rule it is possible to get to a position where\n#\tthere are no squares available to move into. In this implementation\n#\tthis occurs when the starting square is d6.\n#\n#\tTo solve this fault an enhancement to the rule is that if we\n#\thave a choice of squares with an equal score, we should choose\n#\tthe one nearest the edge of the board.\n#\n#\tIf the call to the Edgemost function is commented out you can see\n#\tthis occur.\n#\n#\tYou can drag the knight to a specific square to start if you wish.\n#\tIf you let it repeat then it will choose random start positions\n#\tfor each new tour.\n#----------------------------------------------------------------------------\nrequire 'tk'\n\nclass Knights_Tour\n  # Return a list of accessible squares from a given square\n  def valid_moves(square)\n    moves = []\n    [\n      [-1,-2], [-2,-1], [-2,1], [-1,2], [1,2], [2,1], [2,-1], [1,-2]\n    ].each{|col_delta, row_delta|\n      col = (square % 8) + col_delta\n      row = (square.div(8)) + row_delta\n      moves << (row * 8 + col) if row > -1 && row < 8 && col > -1 && col < 8\n    }\n    moves\n  end\n\n  # Return the number of available moves for this square\n  def check_square(square)\n    valid_moves(square).find_all{|pos| ! @visited.include?(pos)}.length\n  end\n\n  # Select the next square to move to. Returns -1 if there are no available\n  # squares remaining that we can move to.\n  def next_square(square)\n    minimum = 9\n    nxt = -1\n    valid_moves(square).each{|pos|\n      unless @visited.include?(pos)\n        cnt = check_square(pos)\n        if cnt < minimum\n          minimum = cnt\n          nxt = pos\n        elsif cnt == minimum\n          nxt = edgemost(nxt, pos)\n        end\n      end\n    }\n    nxt\n  end\n\n  # Select the square nearest the edge of the board\n  def edgemost(nxt, pos)\n    col_A = 3 - ((3.5 - nxt % 8).abs.to_i)\n    col_B = 3 - ((3.5 - pos % 8).abs.to_i)\n    row_A = 3 - ((3.5 - nxt.div(8)).abs.to_i)\n    row_B = 3 - ((3.5 - pos.div(8)).abs.to_i)\n    (col_A * row_A < col_B * row_B)? nxt : pos\n  end\n\n  # Display a square number as a standard chess square notation.\n  def _N(square)\n    '%c%d' % [(97 + square % 8), (square.div(8) + 1)]\n  end\n\n  # Perform a Knight's move and schedule the next move.\n  def move_piece(last, square)\n    @log.insert(:end, \"#{@visited.length}. #{_N last} -> #{_N square}\\n\", '')\n    @log.see(:end)\n    @board.itemconfigure(1+last, :state=>:normal, :outline=>'black')\n    @board.itemconfigure(1+square, :state=>:normal, :outline=>'red')\n    @knight.coords(@board.coords(1+square)[0..1])\n    @visited << square\n    if (nxt = next_square(square)) != -1\n      @after_id = Tk.after(@delay.numeric){move_piece(square, nxt) rescue nil}\n    else\n      @start_btn.state :normal\n      if @visited.length == 64\n        if @initial == square\n          @log.insert :end, 'Closed tour!'\n        else\n          @log.insert :end, \"Success\\n\", {}\n          Tk.after(@delay.numeric * 2){tour(rand(64))} if @continuous.bool\n        end\n      else\n        @log.insert :end, \"FAILED!\\n\", {}\n      end\n    end\n  end\n\n  # Begin a new tour of the board given a random start position\n  def tour(square = nil)\n    @visited.clear\n    @log.clear\n    @start_btn.state :disabled\n    1.upto(64){|n|\n      @board.itemconfigure(n, :state=>:disabled, :outline=>'black')\n    }\n    unless square\n      square = @board.find_closest(*(@knight.coords << 0 << 65))[0].to_i - 1\n    end\n    @initial = square\n    Tk.after_idle{ move_piece(@initial, @initial) rescue nil }\n  end\n\n  def _stop\n    Tk.after_cancel(@after_id) rescue nil\n  end\n\n  def _exit\n    _stop\n    $knightstour.destroy\n  end\n\n  def set_delay(new)\n    @delay.numeric = new.to_i\n  end\n\n  def drag_start(w, x, y)\n    w.dtag('selected')\n    w.addtag('selected', :withtag, 'current')\n    @dragging = [x, y]\n  end\n\n  def drag_motion(w, x, y)\n    return unless @dragging\n    w.move('selected', x - @dragging[0], y - @dragging[1])\n    @dragging = [x, y]\n  end\n\n  def drag_end(w, x, y)\n    square = w.find_closest(x, y, 0, 65)\n    w.coords('selected', w.coords(square)[0..1])\n    w.dtag('selected')\n    @dragging = nil\n  end\n\n  def make_SeeDismiss\n    ## See Code / Dismiss\n    frame = Ttk::Frame.new($knightstour)\n    sep = Ttk::Separator.new(frame)\n    Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n    TkGrid('x', \n           Ttk::Button.new(frame, :text=>'See Code', \n                           :image=>$image['view'], :compound=>:left, \n                           :command=>proc{showCode 'knightstour'}), \n           Ttk::Button.new(frame, :text=>'Dismiss', \n                           :image=>$image['delete'], :compound=>:left, \n                           :command=>proc{\n                             $knightstour.destroy\n                             $knightstour = nil\n                           }), \n           :padx=>4, :pady=>4)\n    frame.grid_columnconfigure(0, :weight=>1)\n    frame\n  end\n\n  def create_gui(parent = nil)\n    $knightstour.destroy rescue nil\n    $knightstour = Tk::Toplevel.new(parent, :title=>\"Knight's tour\")\n    $knightstour.withdraw\n    base_f = Ttk::Frame.new($knightstour)\n    @board = Tk::Canvas.new(base_f, :width=>240, :height=>240)\n    @log = Tk::Text.new(base_f, :width=>12, :height=>1, \n                        :font=>'Arial 8', :background=>'white')\n    scr = @log.yscrollbar(Ttk::Scrollbar.new(base_f))\n\n    @visited = []\n    @delay = TkVariable.new(600)\n    @continuous = TkVariable.new(false)\n\n    tool_f = Ttk::Frame.new($knightstour)\n    label = Ttk::Label.new(tool_f, :text=>'Speed')\n    scale = Ttk::Scale.new(tool_f, :from=>8, :to=>2000, :variable=>@delay, \n                           :command=>proc{|n| set_delay(n)})\n    check = Ttk::Checkbutton.new(tool_f, :text=>'Repeat', \n                                 :variable=>@continuous)\n    @start_btn = Ttk::Button.new(tool_f, :text=>'Start', \n                                 :command=>proc{tour()})\n    @exit_btn = Ttk::Button.new(tool_f, :text=>'Exit', \n                                :command=>proc{_exit()})\n\n    7.downto(0){|row|\n      0.upto(7){|col|\n        if ((col & 1) ^ (row & 1)).zero?\n          fill  = 'bisque'\n          dfill = 'bisque3'\n        else\n          fill  = 'tan3'\n          dfill = 'tan4'\n        end\n        coords = [col * 30 + 4, row * 30 + 4, col * 30 + 30, row * 30 + 30]\n        @board.create(TkcRectangle, coords, \n                      :fill=>fill, :disabledfill=>dfill,\n                      :width=>2, :state=>:disabled)\n      }\n    }\n\n    @knight_font = TkFont.new(:size=>-24)\n    @knight = TkcText.new(@board, 0, 0, :font=>@knight_font, \n                          :text=>Tk::UTF8_String.new('\\u265e'), \n                          :anchor=>'nw', # :tags=>'knight', \n                          :fill=>'black', :activefill=>'#600000')\n    @knight.coords(@board.coords(rand(64)+1)[0..1])\n    @knight.bind('ButtonPress-1', '%W %x %y'){|w,x,y| drag_start(w,x,y)}\n    @knight.bind('Motion', '%W %x %y'){|w,x,y| drag_motion(w,x,y)}\n    @knight.bind('ButtonRelease-1', '%W %x %y'){|w,x,y| drag_end(w,x,y)}\n\n    Tk.grid(@board, @log, scr, :sticky=>'news')\n    base_f.grid_rowconfigure(0, :weight=>1)\n    base_f.grid_columnconfigure(0, :weight=>1)\n\n    Tk.grid(base_f, '-', '-', '-', '-', '-', :sticky=>'news')\n    widgets = [label, scale, check, @start_btn]\n    sg = nil\n    unless $RubyTk_WidgetDemo\n      widgets << @exit_btn\n      if Tk.windowingsystem != 'aqua'\n        #widgets.unshift(Ttk::SizeGrip.new(tool_f))\n        Ttk::SizeGrip.new(tool_f).pack(:side=>:right, :anchor=>'se')\n      end\n    end\n    Tk.pack(widgets, :side=>:right)\n    if Tk.windowingsystem == 'aqua'\n      TkPack.configure(widgets, :padx=>[4, 4], :pady=>[12, 12])\n      TkPack.configure(widgets[0], :padx=>[4, 24])\n      TkPack.configure(widgets[-1], :padx=>[16, 4])\n    end\n\n    Tk.grid(tool_f, '-', '-', '-', '-', '-', :sticky=>'ew')\n\n    if $RubyTk_WidgetDemo\n      Tk.grid(make_SeeDismiss(), '-', '-', '-', '-', '-', :sticky=>'ew')\n    end\n\n    $knightstour.grid_rowconfigure(0, :weight=>1)\n    $knightstour.grid_columnconfigure(0, :weight=>1)\n\n    $knightstour.bind('Control-F2'){TkConsole.show}\n    $knightstour.bind('Return'){@start_btn.invoke}\n    $knightstour.bind('Escape'){@exit_btn.invoke}\n    $knightstour.bind('Destroy'){ _stop }\n    $knightstour.protocol('WM_DELETE_WINDOW'){ _exit }\n\n    $knightstour.deiconify\n    $knightstour.tkwait_destroy\n  end\n\n  def initialize(parent = nil)\n    create_gui(parent)\n  end\nend\n\nTk.root.withdraw unless $RubyTk_WidgetDemo\nThread.new{Tk.mainloop} if __FILE__ == $0\nKnights_Tour.new\n"
  },
  {
    "path": "ext/tk/sample/demos-en/label.rb",
    "content": "# label.rb\n#\n# This demonstration script creates a toplevel window containing\n# several label widgets.\n#\n# label widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($label_demo) && $label_demo\n  $label_demo.destroy \n  $label_demo = nil\nend\n\n# demo toplevel widget \n$label_demo = TkToplevel.new {|w|\n  title(\"Label Demonstration\")\n  iconname(\"label\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($label_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"Five labels are displayed below: three textual ones on the left, and a bitmap label and a text label on the right.  Labels are pretty boring because you can't do anything with them.\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $label_demo\n      $label_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Code'\n    command proc{showCode 'label'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# label demo \nf_left = TkFrame.new(base_frame)\nf_right = TkFrame.new(base_frame)\n[f_left, f_right].each{|w| w.pack('side'=>'left', 'expand'=>'yes', \n                                  'padx'=>10, 'pady'=>10, 'fill'=>'both')}\n\n# label \n[ TkLabel.new(f_left, 'text'=>'First label'),\n  TkLabel.new(f_left, 'text'=>'Second label, raised', \n              'relief'=>'raised'),\n  TkLabel.new(f_left, 'text'=>'Third label, sunken', 'relief'=>'sunken')\n].each{|w| w.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'anchor'=>'w')}\n\n# TkLabel.new(f_right) {\nTk::Label.new(f_right) {\n  bitmap('@' + [$demo_dir,'..','images','face.xbm'].join(File::Separator))\n  borderwidth 2\n  relief 'sunken'\n}.pack('side'=>'top')\n\nTkLabel.new(f_right) { text 'Tcl/Tk Proprietor' }.pack('side'=>'top')\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/labelframe.rb",
    "content": "# labelframe.rb\n#\n# This demonstration script creates a toplevel window containing\n# several labelframe widgets.\n#\n# based on \"Id: labelframe.tcl,v 1.2 2001/10/30 11:21:50 dkf Exp\"\n\n\nif defined?($labelframe_demo) && $labelframe_demo\n  $labelframe_demo.destroy \n  $labelframe_demo = nil\nend\n\n$labelframe_demo = TkToplevel.new {|w|\n  title(\"Labelframe Demonstration\")\n  iconname(\"labelframe\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($labelframe_demo).pack(:fill=>:both, :expand=>true)\n\n# Some information\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nLabelframes are used to group related widgets together. \\\nThe label may be either plain text or another widget. \\\nIf your Tk library linked to Ruby doesn't include a 'labelframe' widget, \\\nthis demo doesn't work. Please use later version of Tk \\\nwhich supports a 'labelframe' widget.\nEOL\n\n# The bottom buttons\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $labelframe_demo.destroy\n                 $labelframe_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'labelframe'\n               }).pack(:side=>:left, :expand=>true)\n}\n\n# Demo area\nw = TkFrame.new(base_frame).pack(:side=>:bottom, :fill=>:both, \n                                       :expand=>true)\n\n# A group of radiobuttons in a labelframe\nTkLabelFrame.new(w, :text=>'Value', \n                 :padx=>2, :pady=>2) {|f|\n  grid(:row=>0, :column=>0, :pady=>'2m', :padx=>'2m')\n\n  v = TkVariable.new\n  (1..4).each{|i|\n    TkRadiobutton.new(f, :text=>\"This is value #{i}\", \n                      :variable=>v, :value=>i) {\n      pack(:side=>:top, :fill=>:x, :pady=>2)\n    }\n  }\n}\n\n\n# Using a label window to control a group of options.\n$lfdummy = TkVariable.new(0)\n\ndef lfEnableButtons(w)\n  TkWinfo.children(w).each{|child|\n    next if child.path =~ /\\.cb$/\n    if $lfdummy == 1\n      child.state(:normal)\n    else\n      child.state(:disabled)\n    end\n  }\nend\n\nTkLabelFrame.new(w, :pady=>2, :padx=>2){|f|\n  TkCheckButton.new(f, :widgetname=>'cb', :variable=>$lfdummy, \n                    :text=>\"Use this option.\", :padx=>0) {|cb|\n    command proc{lfEnableButtons(f)}\n    f.labelwidget(cb)\n  }\n  grid(:row=>0, :column=>1, :pady=>'2m', :padx=>'2m')\n\n  %w(Option1 Option2 Option3).each{|str|\n    TkCheckbutton.new(f, :text=>str).pack(:side=>:top, :fill=>:x, :pady=>2)\n  }\n\n  lfEnableButtons(f)\n}\n\nTkGrid.columnconfigure(w, [0,1], :weight=>1)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/mclist.rb",
    "content": "# mclist.rb --\n#\n# This demonstration script creates a toplevel window containing a Ttk\n# tree widget configured as a multi-column listbox.\n#\n# based on \"Id: mclist.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($mclist_demo) && $mclist_demo\n  $mclist_demo.destroy \n  $mclist_demo = nil\nend\n\n$mclist_demo = TkToplevel.new {|w|\n  title(\"Multi-Column List\")\n  iconname(\"mclist\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($mclist_demo).pack(:fill=>:both, :expand=>true)\n\n## Explanatory text\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', \n               :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], \n               :text=><<EOL).pack(:fill=>:x)\nTtk is the new Tk themed widget set. \\\nOne of the widgets it includes is a tree widget, \\\nwhich can be configured to display multiple columns of informational data \\\nwithout displaying the tree itself. \\\nThis is a simple way to build a listbox that has multiple columns. \\\nClicking on the heading for a column will sort the data by that column. \\\nYou can also change the width of the columns \\\nby dragging the boundary between them.\nEOL\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'mclist'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $mclist_demo.destroy\n                           $mclist_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\ncontainer = Ttk::Frame.new(base_frame)\ntree = Ttk::Treeview.new(base_frame, :columns=>%w(country capital currency), \n                          :show=>:headings)\nif Tk.windowingsystem != 'aqua'\n  vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame))\nelse\n  vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame))\nend\n\ncontainer.pack(:fill=>:both, :expand=>true)\nTk.grid(tree, vsb, :in=>container, :sticky=>'nsew')\nTk.grid(hsb,       :in=>container, :sticky=>'nsew')\ncontainer.grid_columnconfigure(0, :weight=>1)\ncontainer.grid_rowconfigure(0, :weight=>1)\n\n## The data we're going to insert\ndata = [\n  ['Argentina', \t'Buenos Aires', \t'ARS'], \n  ['Australia',\t\t'Canberra',\t\t'AUD'], \n  ['Brazil', \t\t'Brazilia', \t\t'BRL'], \n  ['Canada', \t\t'Ottawa', \t\t'CAD'], \n  ['China',\t\t'Beijing', \t\t'CNY'], \n  ['France',\t\t'Paris', \t\t'EUR'], \n  ['Germany', \t\t'Berlin',\t\t'EUR'], \n  ['India', \t\t'New Delhi',\t\t'INR'], \n  ['Italy', \t\t'Rome', \t\t'EUR'], \n  ['Japan', \t\t'Tokyo', \t\t'JPY'], \n  ['Mexico', \t\t'Mexico City', \t\t'MXN'], \n  ['Russia', \t\t'Moscow', \t\t'RUB'], \n  ['South Africa',\t'Pretoria', \t\t'ZAR'], \n  ['United Kingdom', \t'London', \t\t'GBP'], \n  ['United States', \t'Washington, D.C.', \t'USD'],\n]\n\n## Code to insert the data nicely\nfont = Ttk::Style.lookup(tree[:style], :font)\ncols = %w(country capital currency)\ncols.zip(%w(Country Capital Currency)).each{|col, name|\n  tree.heading_configure(col, :text=>name, \n                         :command=>proc{sort_by(tree, col, false)})\n  tree.column_configure(col, :width=>TkFont.measure(font, name))\n}\n\ndata.each{|country, capital, currency|\n  #tree.insert('', :end, :values=>[country, capital, currency])\n  tree.insert(nil, :end, :values=>[country, capital, currency])\n  cols.zip([country, capital, currency]).each{|col, val|\n    len = TkFont.measure(font, \"#{val}  \")\n    if tree.column_cget(col, :width) < len\n      tree.column_configure(col, :width=>len)\n    end\n  }\n}\n\n## Code to do the sorting of the tree contents when clicked on\ndef sort_by(tree, col, direction)\n  tree.children(nil).map!{|row| [tree.get(row, col), row.id]} . \n    sort(&((direction)? proc{|x, y| y <=> x}: proc{|x, y| x <=> y})) . \n    each_with_index{|info, idx| tree.move(info[1], nil, idx)}\n\n  tree.heading_configure(col, :command=>proc{sort_by(tree, col, ! direction)})\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/menu.rb",
    "content": "#\n# menus widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($menu_demo) && $menu_demo\n  $menu_demo.destroy \n  $menu_demo = nil\nend\n\n# demo toplevel widget\n$menu_demo = TkToplevel.new {|w|\n  title(\"File Selection Dialogs\")\n  iconname(\"menu\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($menu_demo).pack(:fill=>:both, :expand=>true)\n\n# menu frame\n$menu_frame = TkFrame.new(base_frame, 'relief'=>'raised', 'bd'=>2)\n$menu_frame.pack('side'=>'top', 'fill'=>'x')\n\nbegin\n  windowingsystem = Tk.windowingsystem()\nrescue\n  windowingsystem = \"\"\nend\n\n# label\nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n  if $tk_platform['platform'] == 'macintosh' ||\n      windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    text(\"This window contains a menubar with cascaded menus.  You can invoke entries with an accelerator by typing Command+x, where \\\"x\\\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by dragging outside of its bounds and releasing the mouse.\")\n  else\n    text(\"This window contains a menubar with cascaded menus.  You can post a menu from the keyboard by typing Alt+x, where \\\"x\\\" is the character underlined on the menu.  You can then traverse among the menus using the arrow keys.  When a menu is posted, you can invoke the current entry by typing space, or you can invoke any entry by typing its underlined character.  If a menu entry has an accelerator, you can invoke the entry without posting the menu just by typing the accelerator. The rightmost menu can be torn off into a palette by selecting the first item in the menu.\")\n  end\n}.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $menu_demo\n      $menu_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'menu'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# menu \nTkMenubutton.new($menu_frame, 'text'=>'File', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|file_menu|\n    m.configure('menu'=>file_menu)\n    add('command', 'label'=>'Open...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Open...\" entry'})\n    add('command', 'label'=>'New', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"New\" entry'})\n    add('command', 'label'=>'Save', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Save\" entry'})\n    add('command', 'label'=>'Save As...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Save As...\" entry'})\n    add('separator')\n    add('command', 'label'=>'Print Setup...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Print Setup...\" entry'})\n    add('command', 'label'=>'Print...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Print...\" entry'})\n    add('separator')\n    add('command', 'label'=>'Dismiss Menus Demo', 'command'=>proc{$menu_demo.destroy})\n  }\n}\n\nif $tk_platform['platform'] == 'macintosh' ||\n    windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n  modifier = 'Command'\nelsif $tk_platform['platform'] == 'windows'\n  modifier = 'Control'\nelse\n  modifier = 'Meta'\nend\n\nTkMenubutton.new($menu_frame, 'text'=>'Basic', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|basic_menu|\n    m.configure('menu'=>basic_menu)\n    add('command', 'label'=>'Long entry that does nothing')\n    ['A','B','C','D','E','F','G'].each{|c|\n      add('command', 'label'=>\"Print letter \\\"#{c}\\\"\", \n          'underline'=>14, 'accelerator'=>\"Meta+#{c}\", \n          'command'=>proc{print c,\"\\n\"}, 'accelerator'=>\"#{modifier}+#{c}\")\n      $menu_demo.bind(\"#{modifier}-#{c.downcase}\", proc{print c,\"\\n\"})\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'Cascades', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_menu|\n    m.configure('menu'=>cascade_menu)\n    add('command', 'label'=>'Print hello', \n        'command'=>proc{print \"Hello\\n\"}, \n        'accelerator'=>\"#{modifier}+H\", 'underline'=>6)\n    $menu_demo.bind(\"#{modifier}-h\", proc{print \"Hello\\n\"})\n    add('command', 'label'=>'Print goodbye', \n        'command'=>proc{print \"Goodbye\\n\"}, \n        'accelerator'=>\"#{modifier}+G\", 'underline'=>6)\n    $menu_demo.bind(\"#{modifier}-g\", proc{print \"Goodbye\\n\"})\n\n    TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_check|\n      cascade_menu.add('cascade', 'label'=>'Check buttons', \n                       'menu'=>cascade_check, 'underline'=>0)\n      oil = TkVariable.new(0)\n      add('check', 'label'=>'Oil checked', 'variable'=>oil)\n      trans = TkVariable.new(0)\n      add('check', 'label'=>'Transmission checked', 'variable'=>trans)\n      brakes = TkVariable.new(0)\n      add('check', 'label'=>'Brakes checked', 'variable'=>brakes)\n      lights = TkVariable.new(0)\n      add('check', 'label'=>'Lights checked', 'variable'=>lights)\n      add('separator')\n      add('command', 'label'=>'Show current values', \n          'command'=>proc{showVars($menu_demo, \n                                   ['oil', oil], \n                                   ['trans', trans], \n                                   ['brakes', brakes], \n                                   ['lights', lights])} )\n      invoke 1\n      invoke 3\n    }\n\n    TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_radio|\n      cascade_menu.add('cascade', 'label'=>'Radio buttons', \n                       'menu'=>cascade_radio, 'underline'=>0)\n      pointSize = TkVariable.new\n      add('radio', 'label'=>'10 point', 'variable'=>pointSize, 'value'=>10)\n      add('radio', 'label'=>'14 point', 'variable'=>pointSize, 'value'=>14)\n      add('radio', 'label'=>'18 point', 'variable'=>pointSize, 'value'=>18)\n      add('radio', 'label'=>'24 point', 'variable'=>pointSize, 'value'=>24)\n      add('radio', 'label'=>'32 point', 'variable'=>pointSize, 'value'=>32)\n      add('separator')\n      style = TkVariable.new\n      add('radio', 'label'=>'Roman', 'variable'=>style, 'value'=>'roman')\n      add('radio', 'label'=>'Bold', 'variable'=>style, 'value'=>'bold')\n      add('radio', 'label'=>'Italic', 'variable'=>style, 'value'=>'italic')\n      add('separator')\n      add('command', 'label'=>'Show current values', \n          'command'=>proc{showVars($menu_demo, \n                                   ['pointSize', pointSize], \n                                   ['style', style])} )\n      invoke 1\n      invoke 7\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'Icons', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|icon_menu|\n    m.configure('menu'=>icon_menu)\n    add('command', \n        'bitmap'=>'@'+[$demo_dir,'..',\n                        'images','pattern.xbm'].join(File::Separator),\n        'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', \n                                     'text'=>'The menu entry you invoked displays a bitmap rather than a text string.  Other than this, it is just like any other menu entry.',\n                                     'bitmap'=>'', 'default'=>0, \n                                     'buttons'=>'Dismiss')} )\n    ['info', 'questhead', 'error'].each{|icon|\n      add('command', 'bitmap'=>icon, \n          'command'=>proc{print \"You invoked the #{icon} bitmap\\n\"})\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'More', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|more_menu|\n    m.configure('menu'=>more_menu)\n    [ 'An entry','Another entry','Does nothing','Does almost nothing',\n      'Make life meaningful' ].each{|i|\n      add('command', 'label'=>i, \n          'command'=>proc{print \"You invoked \\\"#{i}\\\"\\n\"})\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'Colors', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m) {|colors_menu|\n    m.configure('menu'=>colors_menu)\n    ['red', 'orange', 'yellow', 'green', 'blue'].each{|c|\n      add('command', 'label'=>c, 'background'=>c, \n          'command'=>proc{print \"You invoked \\\"#{c}\\\"\\n\"})\n    }\n  }\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/menu84.rb",
    "content": "#\n# menus widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($menu84_demo) && $menu84_demo\n  $menu84_demo.destroy \n  $menu84_demo = nil\nend\n\n# demo toplevel widget\n$menu84_demo = TkToplevel.new {|w|\n  title(\"File Selection Dialogs\")\n  iconname(\"menu84\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($menu84_demo).pack(:fill=>:both, :expand=>true)\n\nbegin\n  windowingsystem = Tk.windowingsystem()\nrescue\n  windowingsystem = \"\"\nend\n\n# label\nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n  if $tk_platform['platform'] == 'macintosh' ||\n      windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    text(\"This window contains a menubar with cascaded menus.  You can invoke entries with an accelerator by typing Command+x, where \\\"x\\\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by dragging outside of its bounds and releasing the mouse.\")\n  else\n    text(\"This window contains a menubar with cascaded menus.  You can post a menu from the keyboard by typing Alt+x, where \\\"x\\\" is the character underlined on the menu.  You can then traverse among the menus using the arrow keys.  When a menu is posted, you can invoke the current entry by typing space, or you can invoke any entry by typing its underlined character.  If a menu entry has an accelerator, you can invoke the entry without posting the menu just by typing the accelerator. The rightmost menu can be torn off into a palette by selecting the first item in the menu.\")\n  end\n}.pack('side'=>'top')\n\n\nmenustatus = TkVariable.new(\"    \")\nTkFrame.new(base_frame) {|frame|\n  TkLabel.new(frame, 'textvariable'=>menustatus, 'relief'=>'sunken', \n              'bd'=>1, 'font'=>['Helvetica', '10'], \n              'anchor'=>'w').pack('side'=>'left', 'padx'=>2, \n                                  'expand'=>true, 'fill'=>'both')\n  pack('side'=>'bottom', 'fill'=>'x', 'pady'=>2)\n}\n\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $menu84_demo\n      $menu84_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'menu84'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n\n# create menu frame\n$menu84_frame = TkMenu.new($menu84_demo, 'tearoff'=>false)\n\n# menu\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'File', 'menu'=>m, 'underline'=>0)\n  add('command', 'label'=>'Open...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Open...\" entry'})\n  add('command', 'label'=>'New', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"New\" entry'})\n  add('command', 'label'=>'Save', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Save\" entry'})\n  add('command', 'label'=>'Save As...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Save As...\" entry'})\n  add('separator')\n  add('command', 'label'=>'Print Setup...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Print Setup...\" entry'})\n  add('command', 'label'=>'Print...', 'command'=>proc{fail 'this is just a demo: no action has been defined for the \"Print...\" entry'})\n  add('separator')\n  add('command', 'label'=>'Dismiss Menus Demo', 'command'=>proc{$menu84_demo.destroy})\n}\n\nif $tk_platform['platform'] == 'macintosh' ||\n    windowingsystem = \"classic\" || windowingsystem = \"aqua\"\n  modifier = 'Command'\nelsif $tk_platform['platform'] == 'windows'\n  modifier = 'Control'\nelse\n  modifier = 'Meta'\nend\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Basic', 'menu'=>m, 'underline'=>0)\n  add('command', 'label'=>'Long entry that does nothing')\n  ['A','B','C','D','E','F','G'].each{|c|\n    add('command', 'label'=>\"Print letter \\\"#{c}\\\"\", \n        'underline'=>14, 'accelerator'=>\"Meta+#{c}\", \n        'command'=>proc{print c,\"\\n\"}, 'accelerator'=>\"#{modifier}+#{c}\")\n    $menu84_demo.bind(\"#{modifier}-#{c.downcase}\", proc{print c,\"\\n\"})\n  }\n}\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Cascades', 'menu'=>m, 'underline'=>0)\n  add('command', 'label'=>'Print hello', \n      'command'=>proc{print \"Hello\\n\"}, \n      'accelerator'=>\"#{modifier}+H\", 'underline'=>6)\n  $menu84_demo.bind(\"#{modifier}-h\", proc{print \"Hello\\n\"})\n  add('command', 'label'=>'Print goodbye', \n      'command'=>proc{print \"Goodbye\\n\"}, \n      'accelerator'=>\"#{modifier}+G\", 'underline'=>6)\n  $menu84_demo.bind(\"#{modifier}-g\", proc{print \"Goodbye\\n\"})\n\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_check|\n    m.add('cascade', 'label'=>'Check buttons', \n          'menu'=>cascade_check, 'underline'=>0)\n    oil = TkVariable.new(0)\n    add('check', 'label'=>'Oil checked', 'variable'=>oil)\n    trans = TkVariable.new(0)\n    add('check', 'label'=>'Transmission checked', 'variable'=>trans)\n    brakes = TkVariable.new(0)\n    add('check', 'label'=>'Brakes checked', 'variable'=>brakes)\n    lights = TkVariable.new(0)\n    add('check', 'label'=>'Lights checked', 'variable'=>lights)\n    add('separator')\n    add('command', 'label'=>'Show current values', \n        'command'=>proc{showVars($menu84_demo, \n                                 ['oil', oil], \n                                 ['trans', trans], \n                                 ['brakes', brakes], \n                                 ['lights', lights])} )\n    invoke 1\n    invoke 3\n  }\n\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_radio|\n    m.add('cascade', 'label'=>'Radio buttons', \n          'menu'=>cascade_radio, 'underline'=>0)\n    pointSize = TkVariable.new\n    add('radio', 'label'=>'10 point', 'variable'=>pointSize, 'value'=>10)\n    add('radio', 'label'=>'14 point', 'variable'=>pointSize, 'value'=>14)\n    add('radio', 'label'=>'18 point', 'variable'=>pointSize, 'value'=>18)\n    add('radio', 'label'=>'24 point', 'variable'=>pointSize, 'value'=>24)\n    add('radio', 'label'=>'32 point', 'variable'=>pointSize, 'value'=>32)\n    add('separator')\n    style = TkVariable.new\n    add('radio', 'label'=>'Roman', 'variable'=>style, 'value'=>'roman')\n    add('radio', 'label'=>'Bold', 'variable'=>style, 'value'=>'bold')\n    add('radio', 'label'=>'Italic', 'variable'=>style, 'value'=>'italic')\n    add('separator')\n    add('command', 'label'=>'Show current values', \n        'command'=>proc{showVars($menu84_demo, \n                                 ['pointSize', pointSize], \n                                 ['style', style])} )\n    invoke 1\n    invoke 7\n  }\n}\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Icons', 'menu'=>m, 'underline'=>0)\n  add('command', 'hidemargin'=>1, \n      'bitmap'=>'@'+[$demo_dir,'..',\n                      'images','pattern.xbm'].join(File::Separator),\n      'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', \n                                   'text'=>'The menu entry you invoked displays a bitmap rather than a text string.  Other than this, it is just like any other menu entry.',\n                                   'bitmap'=>'', 'default'=>0, \n                                   'buttons'=>'Dismiss')} )\n  ['info', 'questhead', 'error'].each{|icon|\n    add('command', 'bitmap'=>icon, 'hidemargin'=>1, \n        'command'=>proc{print \"You invoked the #{icon} bitmap\\n\"})\n  }\n\n  entryconfigure(2, :columnbreak=>true)\n}\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'More', 'menu'=>m, 'underline'=>0)\n  [ 'An entry','Another entry','Does nothing','Does almost nothing',\n    'Make life meaningful' ].each{|i|\n    add('command', 'label'=>i, \n        'command'=>proc{print \"You invoked \\\"#{i}\\\"\\n\"})\n  }\n\n  m.entryconfigure('Does almost nothing', \n                   'bitmap'=>'questhead', 'compound'=>'left', \n                   'command'=>proc{\n                     TkDialog.new('title'=>'Compound Menu Entry', \n                                  'message'=>'The menu entry you invoked'+\n                                             'displays both a bitmap and '+\n                                             'a text string.  Other than '+\n                                             'this, it isjust like any '+\n                                             'other menu entry.', \n                                  'buttons'=>['OK'], 'bitmap'=>'')\n                   })\n}\n\nTkMenu.new($menu84_frame) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Colors', 'menu'=>m, 'underline'=>0)\n  ['red', 'orange', 'yellow', 'green', 'blue'].each{|c|\n    add('command', 'label'=>c, 'background'=>c, \n        'command'=>proc{print \"You invoked \\\"#{c}\\\"\\n\"})\n  }\n}\n\n$menu84_demo.menu($menu84_frame)\n\nTkMenu.bind('<MenuSelect>', proc{|w|\n              begin\n                label = w.entrycget('active', 'label')\n              rescue\n                label = \"    \"\n              end\n              menustatus.value = label\n              Tk.update(true)\n            }, '%W')\n"
  },
  {
    "path": "ext/tk/sample/demos-en/menubu.rb",
    "content": "# menubutton.rb\n#\n# This demonstration script creates a window with a bunch of menus\n# and cascaded menus using menubuttons.\n\nrequire \"tkcanvas\"\n\ndef optionMenu(menubutton, varName, firstValue, *rest)\n  varName.value = firstValue\n  configoptions = {'textvariable'=>varName,'indicatoron'=>'on',\n    'relief'=>'raised','borderwidth'=>2,'highlightthickness'=>2,\n    'anchor'=>'c','direction'=>'flush'}\n  configoptions.each {|key, value|\n    menubutton.configure(key, value)\n  }\n  menu = TkMenu.new(menubutton) {\n    tearoff 'off'\n    add 'radio', 'label'=>firstValue, 'variable'=>varName\n  }\n  menubutton.menu(menu)\n  for i in rest\n    menu.add 'radio', 'label'=>i, 'variable'=>varName\n  end\n  \n  return menu\nend\n\nif defined?($menubu_demo) && $menubu_demo\n  $menubu_demo.destroy\n  $menubu_demo = nil\nend\n\n$menubu_demo = TkToplevel.new {|w|\n  title(\"Menu Button Demonstration\")\n  iconname(\"menubutton\")\n}\n\npositionWindow($menubu_demo)\n\nbase_frame = TkFrame.new($menubu_demo).pack(:fill=>:both, :expand=>true)\n\n# version check\nif $tk_version.to_f < 8.0\n\n# label\nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n    text(\"This is a demonstration of menubuttons. The \\\"Below\\\" menubutton pops its menu below the button; the \\\"Right\\\" button pops to the right, etc. There are two option menus directly below this text; one is just a standard menu and the other is a 16-color palette.\")\n}.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $menubu_demo\n      $menubu_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'menubu'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\nelse ; # Tk8.x\n\nbody = TkFrame.new(base_frame)\nbody.pack('expand'=>'yes', 'fill'=>'both')\n\nbelow = TkMenubutton.new(body) {\n  text \"Below\"\n  underline 0\n  direction 'below'\n  relief 'raised'\n}\nbelowMenu = TkMenu.new(below) {\n  tearoff 0\n  add 'command', 'label'=>\"Below menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Below menu.\\\"\"}\n  add 'command', 'label'=>\"Below menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Below menu.\\\"\"}\n}\nbelow.menu(belowMenu)\nbelow.grid('row'=>0, 'column'=>1, 'sticky'=>'n')\n\nbelow = TkMenubutton.new(body) {\n  text \"Below\"\n  underline 0\n  direction 'below'\n  relief 'raised'\n}\nbelowMenu = TkMenu.new(below) {\n  tearoff 0\n  add 'command', 'label'=>\"Below menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Below menu.\\\"\"}\n  add 'command', 'label'=>\"Below menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Below menu.\\\"\"}\n}\nbelow.menu(belowMenu)\nbelow.grid('row'=>0, 'column'=>1, 'sticky'=>'n')\n\nbelow = TkMenubutton.new(body) {\n  text \"Below\"\n  underline 0\n  direction 'below'\n  relief 'raised'\n}\nbelowMenu = TkMenu.new(below) {\n  tearoff 0\n  add 'command', 'label'=>\"Below menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Below menu.\\\"\"}\n  add 'command', 'label'=>\"Below menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Below menu.\\\"\"}\n}\nbelow.menu(belowMenu)\nbelow.grid('row'=>0, 'column'=>1, 'sticky'=>'n')\n\nright = TkMenubutton.new(body) {\n  text \"Right\"\n  underline 0\n  direction 'right'\n  relief 'raised'\n}\nrightMenu = TkMenu.new(right) {\n  tearoff 0\n  add 'command', 'label'=>\"Right menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Left menu.\\\"\"}\n  add 'command', 'label'=>\"Right menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Right menu.\\\"\"}\n}\nright.menu(rightMenu)\nright.grid('row'=>1, 'column'=>0, 'sticky'=>'w')\n\nleft = TkMenubutton.new(body) {\n  text \"Left\"\n  underline 0\n  direction 'left'\n  relief 'raised'\n}\nleftMenu = TkMenu.new(left) {\n  tearoff 0\n  add 'command', 'label'=>\"Left menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Left menu.\\\"\"}\n  add 'command', 'label'=>\"Left menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Left menu.\\\"\"}\n}\nleft.menu(leftMenu)\nleft.grid('row'=>1, 'column'=>2, 'sticky'=>'e')\n\ncenter = TkFrame.new(body) {\n  grid('row'=>1, 'column'=>1, 'sticky'=>'news')\n}\n\nabove = TkMenubutton.new(body) {\n  text \"Above\"\n  underline 0\n  direction 'above'\n  relief 'raised'\n}\naboveMenu = TkMenu.new(above) {\n  tearoff 0\n  add 'command', 'label'=>\"Above menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Above menu.\\\"\"}\n  add 'command', 'label'=>\"Above menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Above menu.\\\"\"}\n}\nabove.menu(aboveMenu)\nabove.grid('row'=>2, 'column'=>1, 'sticky'=>'s')\n\ncenter = TkFrame.new(body) {\n  grid('row'=>1, 'column'=>1, 'sticky'=>'news')\n}\n\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc {\n      tmppath = $menubu_demo\n      $menubu_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc { showCode 'menubu' }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'expand'=>'yes', 'fill'=>'x', 'pady'=>'2m')\n\nmsg = TkLabel.new(center) {\n#  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"This is a demonstration of menubuttons. The \\\"Below\\\" menubutton pops its menu below the button; the \\\"Right\\\" button pops to the right, etc. There are two option menus directly below this text; one is just a standard menu and the other is a 16-color palette.\"\n}\nmsg.pack('side'=>'top', 'padx'=>25, 'pady'=>25)\n\nTkFrame.new(center) {|f|\n  menubuttonoptions = TkVariable.new\n  mbutton = TkMenubutton.new(f)\n  options = optionMenu(mbutton, menubuttonoptions, \n                       'one', 'two', 'three')\n  mbutton.pack('side'=>'left', 'padx'=>25, 'pady'=>25)\n  paletteColor = TkVariable.new\n  colors = ['Black','red4','DarkGreen','NavyBlue', 'gray75',\n    'Red','Green','Blue','gray50','Yellow','Cyan','Magenta',\n    'White','Brown','DarkSeaGreen','DarkViolet']\n  colorMenuButton = TkMenubutton.new(f)\n  m = optionMenu(colorMenuButton, paletteColor, *colors)\n  begin\n    windowingsystem = Tk.windowingsystem()\n  rescue\n    windowingsystem = \"\"\n  end\n  if windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    topBorderColor = 'Black'\n    bottomBorderColor = 'Black'\n  else\n    topBorderColor = 'gray50'\n    bottomBorderColor = 'gray75'\n  end\n  for i in 0..15\n    image = TkPhotoImage.new('height'=>16, 'width'=>16)\n    image.put(topBorderColor, 0, 0, 16, 1)\n    image.put(topBorderColor, 0, 1, 1, 16)\n    image.put(bottomBorderColor, 0, 15, 16, 16)\n    image.put(bottomBorderColor, 15, 1, 16, 16)\n    image.put(colors[i], 1, 1, 15, 15)\n\n    selectimage = TkPhotoImage.new('height'=>16, 'width'=>16)\n    selectimage.put('Black', 0, 0, 16, 2)\n    selectimage.put('Black', 0, 2, 2, 16)\n    selectimage.put('Black', 2, 14, 16, 16)\n    selectimage.put('Black', 14, 2, 16, 14)\n    selectimage.put(colors[i], 2, 2, 14, 14)\n\n    m.entryconfigure(i, 'image'=>image, 'selectimage'=>selectimage, 'hidemargin'=>'on')\n  end\n  m.configure('tearoff', 'on')\n  for c in ['Black', 'gray75', 'gray50', 'White']\n    m.entryconfigure(c, 'columnbreak'=>1)\n  end\n  colorMenuButton.pack('side'=>'left', 'padx'=>25, 'pady'=>25)\n  pack 'padx'=>25, 'pady'=>25\n}\n\nend ; # Tk8.x\n"
  },
  {
    "path": "ext/tk/sample/demos-en/msgbox.rb",
    "content": "# msgbox.rb\n#\n# This demonstration script creates message boxes of various type\n#\n# message boxes widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($msgbox_demo) && $msgbox_demo\n  $msgbox_demo.destroy \n  $msgbox_demo = nil\nend\n\n# demo toplevel widget\n$msgbox_demo = TkToplevel.new {|w|\n  title(\"Message Box Demonstration\")\n  iconname(\"messagebox\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($msgbox_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left',\n            'text'=>\"Choose the icon and type option of the message box. Then press the \\\"Message Box\\\" button to see the message box.\").pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $msgbox_demo\n      $msgbox_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'msgbox'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Message Box'\n    command proc{showMessageBox $msgbox_demo}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\n$msgbox_leftframe  = TkFrame.new(base_frame)\n$msgbox_rightframe = TkFrame.new(base_frame)\n$msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n$msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n\nTkLabel.new($msgbox_leftframe, 'text'=>'Icon').pack('side'=>'top')\nTkFrame.new($msgbox_leftframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxIcon = TkVariable.new('info')\n['error', 'info', 'question', 'warning'].each {|icon|\n  TkRadioButton.new($msgbox_leftframe, 'text'=>icon, 'variable'=>$msgboxIcon, \n                    'relief'=>'flat', 'value'=>icon, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\nTkLabel.new($msgbox_rightframe, 'text'=>'Type').pack('side'=>'top')\nTkFrame.new($msgbox_rightframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxType = TkVariable.new('ok')\n['abortretryignore', 'ok', 'okcancel', \n  'retrycancel', 'yesno', 'yesnocancel'].each {|type|\n  TkRadioButton.new($msgbox_rightframe, 'text'=>type, 'variable'=>$msgboxType, \n                    'relief'=>'flat', 'value'=>type, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\ndef showMessageBox(w)\n  button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, \n                         'title'=>'Message', 'parent'=>w,\n                         'message'=>\"This is a \\\"#{$msgboxType.value}\\\" type messagebox with the \\\"#{$msgboxIcon.value}\\\" icon\")\n\n  Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, \n                'message'=>\"You have selected  \\\"#{button}\\\"\")\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/msgbox2.rb",
    "content": "# msgbox2.rb\n#\n# This demonstration script creates message boxes of various type\n#\n# message boxes widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($msgbox2_demo) && $msgbox2_demo\n  $msgbox2_demo.destroy \n  $msgbox2_demo = nil\nend\n\n# demo toplevel widget\n$msgbox2_demo = TkToplevel.new {|w|\n  title(\"Message Box Demonstration\")\n  iconname(\"messagebox\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($msgbox2_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left',\n            'text'=>\"Choose the icon and type option of the message box. Then press the \\\"Message Box\\\" button to see the message box with both of a message and a detail.\").pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $msgbox2_demo\n      $msgbox2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'msgbox2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Message Box'\n    command proc{showMessageBox $msgbox2_demo}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\n$msgbox_leftframe  = TkFrame.new(base_frame)\n$msgbox_rightframe = TkFrame.new(base_frame)\n$msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n$msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n\nTkLabel.new($msgbox_leftframe, 'text'=>'Icon').pack('side'=>'top')\nTkFrame.new($msgbox_leftframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxIcon = TkVariable.new('info')\n['error', 'info', 'question', 'warning'].each {|icon|\n  TkRadioButton.new($msgbox_leftframe, 'text'=>icon, 'variable'=>$msgboxIcon, \n                    'relief'=>'flat', 'value'=>icon, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\nTkLabel.new($msgbox_rightframe, 'text'=>'Type').pack('side'=>'top')\nTkFrame.new($msgbox_rightframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxType = TkVariable.new('ok')\n['abortretryignore', 'ok', 'okcancel', \n  'retrycancel', 'yesno', 'yesnocancel'].each {|type|\n  TkRadioButton.new($msgbox_rightframe, 'text'=>type, 'variable'=>$msgboxType, \n                    'relief'=>'flat', 'value'=>type, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\ndef showMessageBox(w)\n  button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, \n                         'title'=>'Message', 'parent'=>w,\n                         'message'=>\"\\\"#{$msgboxType.value}\\\" Type MessageBox\",\n                         'detail'=>\"This is a \\\"#{$msgboxType.value}\\\" type messagebox with the \\\"#{$msgboxIcon.value}\\\" icon. Please click one of the following button.\")\n\n  Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, \n                'message'=>\"You have selected  \\\"#{button}\\\"\")\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/paned1.rb",
    "content": "# paned1.rb\n#\n# This demonstration script creates a toplevel window containing\n# a paned window that separates two windows horizontally.\n#\n# based on \"Id: paned1.tcl,v 1.1 2002/02/22 14:07:01 dkf Exp\"\n\nif defined?($paned1_demo) && $paned1_demo\n  $paned1_demo.destroy \n  $paned1_demo = nil\nend\n\n$paned1_demo = TkToplevel.new {|w|\n  title(\"Horizontal Paned Window Demonstration\")\n  iconname(\"paned1\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($paned1_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nThe sash between the two coloured windows below can be used to divide the area between them.  Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.)\nIf your Tk library linked to Ruby doesn't include a 'panedwindow', this demo doesn't work. Please use later version of Tk which supports a 'panedwindow'.\nEOL\n\n# The bottom buttons\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $paned1_demo.destroy\n                 $paned1_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'paned1'\n               }).pack(:side=>:left, :expand=>true)\n}\n\nTkPanedwindow.new(base_frame, :orient=>:horizontal){|f|\n  add(Tk::Label.new(f, :text=>\"This is the\\nleft side\", :bg=>'yellow'), \n      Tk::Label.new(f, :text=>\"This is the\\nright side\", :bg=>'cyan'))\n\n  pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m')\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/paned2.rb",
    "content": "# paned2.rb --\n#\n# This demonstration script creates a toplevel window containing\n# a paned window that separates two windows vertically.\n#\n# based on \"Id: paned2.tcl,v 1.1 2002/02/22 14:07:01 dkf Exp\"\n\nif defined?($paned2_demo) && $paned2_demo\n  $paned2_demo.destroy \n  $paned2_demo = nil\nend\n\n$paned2_demo = TkToplevel.new {|w|\n  title(\"Vertical Paned Window Demonstration\")\n  iconname(\"paned2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($paned2_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nThe sash between the two scrolled windows below can be used to divide the area between them.  Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.)\nIf your Tk library linked to Ruby doesn't include a 'panedwindow', this demo doesn't work. Please use later version of Tk which supports a 'panedwindow'.\nEOL\n\n# The bottom buttons\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $paned2_demo.destroy\n                 $paned2_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'paned2'\n               }).pack(:side=>:left, :expand=>true)\n}\n\npaneList = TkVariable.new  # define as normal variable (not array)\npaneList.value = [         # ruby's array --> tcl's list\n    'List of Ruby/Tk Widgets',\n    'TkButton', \n    'TkCanvas', \n    'TkCheckbutton', \n    'TkEntry', \n    'TkFrame', \n    'TkLabel', \n    'TkLabelframe', \n    'TkListbox', \n    'TkMenu', \n    'TkMenubutton', \n    'TkMessage', \n    'TkPanedwindow', \n    'TkRadiobutton', \n    'TkScale', \n    'TkScrollbar', \n    'TkSpinbox', \n    'TkText', \n    'TkToplevel'\n]\n\n# Create the pane itself\nTkPanedwindow.new(base_frame, :orient=>:vertical){|f|\n  pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m')\n\n  add(TkFrame.new(f){|paned2_top|\n        TkListbox.new(paned2_top, :listvariable=>paneList) {\n          # Invert the first item to highlight it\n          itemconfigure(0, :background=>self.cget(:foreground), \n                           :foreground=>self.cget(:background) )\n          yscrollbar(TkScrollbar.new(paned2_top).pack(:side=>:right, \n                                                      :fill=>:y))\n          pack(:fill=>:both, :expand=>true)\n        }\n      }, \n\n      TkFrame.new(f, :height=>120) {|paned2_bottom|\n        # The bottom window is a text widget with scrollbar\n        paned2_xscr = TkScrollbar.new(paned2_bottom)\n        paned2_yscr = TkScrollbar.new(paned2_bottom)\n        paned2_text = TkText.new(paned2_bottom, :width=>30, :wrap=>:non) {\n          insert('1.0', \"This is just a normal text widget\")\n          xscrollbar(paned2_xscr)\n          yscrollbar(paned2_yscr)\n        }\n        Tk.grid(paned2_text, paned2_yscr, :sticky=>'nsew')\n        Tk.grid(paned2_xscr, :sticky=>'nsew')\n        TkGrid.columnconfigure(paned2_bottom, 0, :weight=>1)\n        TkGrid.rowconfigure(paned2_bottom, 0, :weight=>1)\n      } )\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/pendulum.rb",
    "content": "#\n# This demonstration illustrates how Tcl/Tk can be used to construct\n# simulations of physical systems.\n# (called by 'widget')\n#\n# based on Tcl/Tk8.5a2 widget demos\n\n# destroy toplevel widget for this demo script\nif defined?($pendulum_demo) && $pendulum_demo\n  $pendulum_demo.destroy \n  $pendulum_demo = nil\nend\n\n# create toplevel widget\n$pendulum_demo = TkToplevel.new {|w|\n  title(\"Pendulum Animation Demonstration\")\n  iconname(\"pendulum\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($pendulum_demo).pack(:fill=>:both, :expand=>true)\n\n# create label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text 'This demonstration shows how Ruby/Tk can be used to carry out animations that are linked to simulations of physical systems. In the left canvas is a graphical representation of the physical system itself, a simple pendulum, and in the right canvas is a graph of the phase space of the system, which is a plot of the angle (relative to the vertical) against the angular velocity. The pendulum bob may be repositioned by clicking and dragging anywhere on the left canvas.'\n}\nmsg.pack('side'=>'top')\n\n# create frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $pendulum_demo\n      $pendulum_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Code'\n    command proc{showCode 'pendulum'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# animated wave\nclass PendulumAnimationDemo\n  def initialize(frame)\n    # Create some structural widgets\n    @pane = TkPanedWindow.new(frame, :orient=>:horizontal).pack(:fill=>:both, :expand=>true)\n#    @pane.add(@lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation'))\n#    @pane.add(@lf2 = TkLabelFrame.new(@pane, :text=>'Phase Space'))\n    @lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation')\n    @lf2 = TkLabelFrame.new(@pane, :text=>'Phase Space')\n\n    # Create the canvas containing the graphical representation of the\n    # simulated system.\n    @c = TkCanvas.new(@lf1, :width=>320, :height=>200, :background=>'white', \n                      :borderwidth=>2, :relief=>:sunken)\n    TkcText.new(@c, 5, 5, :anchor=>:nw, \n                :text=>'Click to Adjust Bob Start Position')\n    # Coordinates of these items don't matter; they will be set properly below\n    @plate = TkcLine.new(@c, 0, 25, 320, 25, :width=>2, :fill=>'grey50')\n    @rod = TkcLine.new(@c, 1, 1, 1, 1, :width=>3, :fill=>'black')\n    @bob = TkcOval.new(@c, 1, 1, 2, 2, \n                       :width=>3, :fill=>'yellow', :outline=>'black')\n    TkcOval.new(@c, 155, 20, 165, 30, :fill=>'grey50', :outline=>'')\n\n    # pack\n    @c.pack(:fill=>:both, :expand=>true)\n\n    # Create the canvas containing the phase space graph; this consists of\n    # a line that gets gradually paler as it ages, which is an extremely\n    # effective visual trick.\n    @k = TkCanvas.new(@lf2, :width=>320, :height=>200, :background=>'white', \n                      :borderwidth=>2, :relief=>:sunken)\n    @y_axis = TkcLine.new(@k, 160, 200, 160, 0, :fill=>'grey75', :arrow=>:last)\n    @x_axis = TkcLine.new(@k, 0, 100, 320, 100, :fill=>'grey75', :arrow=>:last)\n\n    @graph = {}\n    90.step(0, -10){|i|\n      # Coordinates of these items don't matter; \n      # they will be set properly below\n      @graph[i] = TkcLine.new(@k, 0, 0, 1, 1, :smooth=>true, :fill=>\"grey#{i}\")\n    }\n\n    # labels\n    @label_theta = TkcText.new(@k, 0, 0, :anchor=>:ne, \n                               :text=>'q', :font=>'Symbol 8')\n    @label_dtheta = TkcText.new(@k, 0, 0, :anchor=>:ne, \n                               :text=>'dq', :font=>'Symbol 8')\n\n    # pack\n    @k.pack(:fill=>:both, :expand=>true)\n\n    # Initialize some variables\n    @points = []\n    @theta = 45.0\n    @dTheta = 0.0\n    @length = 150\n\n    # animation loop\n    @timer = TkTimer.new(15){ repeat }\n\n    # binding\n    @c.bindtags_unshift(btag = TkBindTag.new)\n    btag.bind('Destroy'){ @timer.stop }\n    btag.bind('1', proc{|x, y| @timer.stop; showPendulum(x.to_i, y.to_i)}, \n              '%x %y')\n    btag.bind('B1-Motion', proc{|x, y| showPendulum(x.to_i, y.to_i)}, '%x %y')\n    btag.bind('ButtonRelease-1', \n              proc{|x, y| showPendulum(x.to_i, y.to_i); @timer.start }, \n              '%x %y')\n\n    btag.bind('Configure', proc{|w| @plate.coords(0, 25, w.to_i, 25)}, '%w')\n\n    @k.bind('Configure', proc{|h, w| \n              h = h.to_i\n              w = w.to_i\n              @psh = h/2; \n              @psw = w/2\n              @x_axis.coords(2, @psh, w-2, @psh)\n              @y_axis.coords(@psw, h-2, @psw, 2)\n              @label_theta.coords(@psw-4, 6)\n              @label_dtheta.coords(w-6, @psh+4)\n            }, '%h %w')\n\n    # add\n    Tk.update\n    @pane.add(@lf1)\n    @pane.add(@lf2)\n\n    # init display\n    showPendulum\n\n    # animation start\n    @timer.start(500)\n  end\n\n  # This procedure makes the pendulum appear at the correct place on the\n  # canvas. If the additional arguments x, y are passed instead of computing \n  # the position of the pendulum from the length of the pendulum rod and its \n  # angle, the length and angle are computed in reverse from the given \n  # location (which is taken to be the centre of the pendulum bob.)\n  def showPendulum(x=nil, y=nil)\n    if x && y && (x != 160 || y != 25)\n      @dTheta = 0.0\n      x2 = x - 160\n      y2 = y - 25\n      @length = Math.hypot(x2, y2)\n      @theta = Math.atan2(x2,y2)*180/Math::PI\n    else\n      angle = @theta*Math::PI/180\n      x = 160 + @length*Math.sin(angle)\n      y = 25 + @length*Math.cos(angle)\n    end\n\n    @rod.coords(160, 25, x, y)\n    @bob.coords(x-15, y-15, x+15, y+15)\n  end\n\n  # Update the phase-space graph according to the current angle and the\n  # rate at which the angle is changing (the first derivative with\n  # respect to time.)\n  def showPhase\n    unless @psw && @psh\n      @psw = @k.width/2\n      @psh = @k.height/2\n    end\n    @points << @theta + @psw << -20*@dTheta + @psh\n    if @points.length > 100\n      @points = @points[-100..-1]\n    end\n    (0...100).step(10){|i|\n      first = - i\n      last = 11 - i\n      last = -1 if last >= 0\n      next if first > last\n      lst = @points[first..last]\n      @graph[i].coords(lst) if lst && lst.length >= 4\n    }\n  end\n\n  # This procedure is the \"business\" part of the simulation that does\n  # simple numerical integration of the formula for a simple rotational\n  # pendulum.\n  def recomputeAngle\n    scaling = 3000.0/@length/@length\n\n    # To estimate the integration accurately, we really need to\n    # compute the end-point of our time-step.  But to do *that*, we\n    # need to estimate the integration accurately!  So we try this\n    # technique, which is inaccurate, but better than doing it in a\n    # single step.  What we really want is bound up in the\n    # differential equation:\n    #       ..             - sin theta\n    #      theta + theta = -----------\n    #                         length\n    # But my math skills are not good enough to solve this!\n\n    # first estimate\n    firstDDTheta = -Math.sin(@theta * Math::PI/180) * scaling\n    midDTheta = @dTheta + firstDDTheta\n    midTheta = @theta + (@dTheta + midDTheta)/2\n    # second estimate\n    midDDTheta = -Math.sin(midTheta * Math::PI/180) * scaling\n    midDTheta = @dTheta + (firstDDTheta + midDDTheta)/2\n    midTheta = @theta + (@dTheta + midDTheta)/2\n    # Now we do a double-estimate approach for getting the final value\n    # first estimate\n    midDDTheta = -Math.sin(midTheta * Math::PI/180) * scaling\n    lastDTheta = midDTheta + midDDTheta\n    lastTheta = midTheta + (midDTheta+ lastDTheta)/2\n    # second estimate\n    lastDDTheta = -Math.sin(lastTheta * Math::PI/180) * scaling\n    lastDTheta = midDTheta + (midDDTheta + lastDDTheta)/2\n    lastTheta = midTheta + (midDTheta + lastDTheta)/2\n    # Now put the values back in our globals\n    @dTheta = lastDTheta\n    @theta = lastTheta\n  end\n\n  # This method ties together the simulation engine and the graphical\n  # display code that visualizes it.\n  def repeat\n    # Simulate\n    recomputeAngle\n\n    # Update the display\n    showPendulum\n    showPhase\n  end\nend\n\n# Start the animation processing\nPendulumAnimationDemo.new(base_frame)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/plot.rb",
    "content": "# plot.rb\n#\n# This demonstration script creates a canvas widget showing a 2-D\n# plot with data points that can be dragged with the mouse.\n#\n# 2-D plot widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($plot_demo) && $plot_demo\n  $plot_demo.destroy \n  $plot_demo = nil\nend\n\n# demo toplevel widget\n$plot_demo = TkToplevel.new {|w|\n  title(\"Plot Demonstration\")\n  iconname(\"Plot\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($plot_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', \n            'text'=>\"This window displays a canvas widget containing a simple 2-dimensional plot.  You can doctor the data by dragging any of the points with mouse button 1.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$plot_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $plot_demo\n      $plot_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'plot'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$plot_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# font \nplotFont = '-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'\n\n# canvas \n$plot_canvas = TkCanvas.new(base_frame,'relief'=>'raised','width'=>450,'height'=>300)\n$plot_canvas.pack('side'=>'top', 'fill'=>'x')\n\n# plot \nTkcLine.new($plot_canvas, 100, 250, 400, 250, 'width'=>2)\nTkcLine.new($plot_canvas, 100, 250, 100,  50, 'width'=>2)\nTkcText.new($plot_canvas, 225, 20, \n            'text'=>\"A Simple Plot\", 'font'=>plotFont, 'fill'=>'brown')\n\n(0..10).each {|i|\n  x = 100 + (i * 30)\n  TkcLine.new($plot_canvas, x, 250, x, 245, 'width'=>2)\n  TkcText.new($plot_canvas, x, 254, \n              'text'=>10*i, 'font'=>plotFont, 'anchor'=>'n')\n}\n(0..5).each {|i|\n  y = 250 - (i * 40)\n  TkcLine.new($plot_canvas, 100, y, 105, y, 'width'=>2)\n  TkcText.new($plot_canvas, 96, y, \n              'text'=>\"#{i*50}.0\", 'font'=>plotFont, 'anchor'=>'e')\n}\n\nfor xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]\n  x = 100 + (3*xx)\n  y = 250 - (4*yy)/5\n  item = TkcOval.new($plot_canvas, x-6, y-6, x+6, y+6, \n                     'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')\n  item.addtag 'point'\nend\n\n$plot_canvas.itembind('point', 'Any-Enter', \n                      proc{$plot_canvas.itemconfigure 'current','fill','red'})\n$plot_canvas.itembind('point', 'Any-Leave', \n                      proc{$plot_canvas.itemconfigure 'current','fill','SkyBlue2'})\n$plot_canvas.itembind('point', '1', \n                      proc{|x,y| plotDown $plot_canvas,x,y}, \"%x %y\")\n$plot_canvas.itembind('point', 'ButtonRelease-1', \n                      proc{$plot_canvas.dtag 'selected'})\n$plot_canvas.bind('B1-Motion', \n                  proc{|x,y| plotMove $plot_canvas,x,y}, \"%x %y\")\n\n$plot = {'lastX'=>0, 'lastY'=>0}\n\n# plotDown --\n# This method is invoked when the mouse is pressed over one of the \n# data points.  It sets up state to allow the point to be dragged.\n#\n# Arguments:\n# w -           The canvas window.\n# x, y -        The coordinates of the mouse press.\n\ndef plotDown (w, x, y)\n  w.dtag 'selected'\n  w.addtag_withtag 'selected', 'current'\n  w.raise 'current'\n  $plot['lastX'] = x\n  $plot['lastY'] = y\nend\n\n# plotMove --\n# This method is invoked during mouse motion events.  It drags the\n# current item.\n#\n# Arguments:\n# w -           The canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef plotMove (w, x, y)\n  w.move 'selected', x - $plot['lastX'], y - $plot['lastY']\n  $plot['lastX'] = x\n  $plot['lastY'] = y\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/puzzle.rb",
    "content": "# puzzle.rb\n#\n# This demonstration script creates a 15-puzzle game using a collection\n# of buttons.\n#\n# widet demo 'puzzle' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($puzzle_demo) && $puzzle_demo\n  $puzzle_demo.destroy \n  $puzzle_demo = nil\nend\n\n# demo toplevel widget\n$puzzle_demo = TkToplevel.new {|w|\n  title(\"15-Puzzle Demonstration\")\n  iconname(\"15-Puzzle\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($puzzle_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"A 15-puzzle appears below as a collection of buttons.  Click on any of the pieces next to the space, and that piece will slide over the space.  Continue this until the pieces are arranged in numerical order from upper-left to lower-right.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $puzzle_demo\n      $puzzle_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'puzzle'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\n\n# Special trick: select a darker color for the space by creating a\n# scrollbar widget and using its trough color.\nbegin\n  if Tk.windowingsystem() == 'aqua'\n    frameWidth  = 168\n    frameHeight = 168\n  elsif Tk.default_widget_set == :Ttk\n    frameWidth  = 148\n    frameHeight = 124\n  else\n    frameWidth  = 120\n    frameHeight = 120\n  end\nrescue\n  frameWidth  = 120\n  frameHeight = 120\nend\n\n# depend_on_button_width = true\ndepend_on_button_width = false\n \ns = TkScrollbar.new(base_frame)\nbase = TkFrame.new(base_frame) {\n  width  frameWidth\n  height frameHeight\n  borderwidth 2\n  relief 'sunken'\n  bg s['troughcolor']\n}\ns.destroy\nbase.pack('side'=>'top', 'padx'=>'1c', 'pady'=>'1c')\n\ndef def_puzzleswitch_proc(w, num)\n  proc{puzzleSwitch w, num}\nend\n\n$xpos = {}\n$ypos = {}\norder = [3,1,6,2,5,7,15,13,4,11,8,9,14,10,12]\n(0..14).each{|i|\n  num = order[i]\n  $xpos[num] = (i % 4) * 0.25\n  $ypos[num] = (i / 4) * 0.25\n  TkButton.new(base) {|w|\n    relief 'raised'\n    text num\n    highlightthickness 0\n    command def_puzzleswitch_proc(w, num)\n    if depend_on_button_width && (w.winfo_reqwidth * 4 > base.width)\n      base.width = w.winfo_reqwidth * 4\n    end\n  }.place('relx'=>$xpos[num], 'rely'=>$ypos[num], \n          'relwidth'=>0.25, 'relheight'=>0.25)\n}\n$xpos['space'] = 0.75\n$ypos['space'] = 0.75\n\n\n# puzzleSwitch --\n# This procedure is invoked when the user clicks on a particular button;\n# if the button is next to the empty space, it moves the button into the\n# empty space.\n\ndef puzzleSwitch(w, num)\n  if ( ($ypos[num] >= ($ypos['space'] - 0.01))     \\\n      && ($ypos[num] <= ($ypos['space'] + 0.01))   \\\n      && ($xpos[num] >= ($xpos['space'] - 0.26))   \\\n      && ($xpos[num] <= ($xpos['space'] + 0.26)))  \\\n    || (($xpos[num] >= ($xpos['space'] - 0.01))    \\\n        && ($xpos[num] <= ($xpos['space'] + 0.01)) \\\n        && ($ypos[num] >= ($ypos['space'] - 0.26)) \\\n        && ($ypos[num] <= ($ypos['space'] + 0.26)))\n    tmp = $xpos['space']\n    $xpos['space'] = $xpos[num]\n    $xpos[num] = tmp\n    tmp = $ypos['space']\n    $ypos['space'] = $ypos[num]\n    $ypos[num] = tmp\n    w.place('relx'=>$xpos[num], 'rely'=>$ypos[num])\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/radio.rb",
    "content": "# radio.rb\n#\n# This demonstration script creates a toplevel window containing\n# several radiobutton widgets.\n#\n# radiobutton widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($radio_demo) && $radio_demo\n  $radio_demo.destroy \n  $radio_demo = nil\nend\n\n# demo toplevel widget\n$radio_demo = TkToplevel.new {|w|\n  title(\"Radiobutton Demonstration\")\n  iconname(\"radio\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($radio_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"Two groups of radiobuttons are displayed below.  If you click on a button then the button will become selected exclusively among all the buttons in its group.  A Tcl variable is associated with each group to indicate which of the group's buttons is selected.  Click the \\\"See Variables\\\" button to see the current values of the variables.\"\n}\nmsg.pack('side'=>'top')\n\n# \nsize = TkVariable.new\ncolor = TkVariable.new\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $radio_demo\n      $radio_demo = nil\n      $showVarsWin[tmppath.path] = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'radio'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Variables'\n    command proc{\n      showVars(base_frame, ['size', size], ['color', color])\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nf_left = TkFrame.new(base_frame)\nf_right = TkFrame.new(base_frame)\nf_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\nf_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\n\n# radiobutton \n[10, 12, 18, 24].each {|sz|\n  TkRadioButton.new(f_left) {\n    text \"Point Size #{sz}\"\n    variable size\n    relief 'flat'\n    value sz\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')\n}\n\n['Red', 'Green', 'Blue', 'Yellow', 'Orange', 'Purple'].each {|col|\n  TkRadioButton.new(f_right) {\n    text col\n    variable color\n    relief 'flat'\n    value col.downcase\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')\n}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/radio2.rb",
    "content": "# radio2.rb\n#\n# This demonstration script creates a toplevel window containing\n# several radiobutton widgets.\n#\n# radiobutton widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($radio2_demo) && $radio2_demo\n  $radio2_demo.destroy \n  $radio2_demo = nil\nend\n\n# demo toplevel widget\n$radio2_demo = TkToplevel.new {|w|\n  title(\"Radiobutton Demonstration 2\")\n  iconname(\"radio2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($radio2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"Three groups of radiobuttons are displayed below.  If you click on a button then the button will become selected exclusively among all the buttons in its group.  A Tcl variable is associated with each group to indicate which of the group's buttons is selected.  Click the \\\"See Variables\\\" button to see the current values of the variables.\"\n}\nmsg.pack('side'=>'top')\n\n# \nsize = TkVariable.new\ncolor = TkVariable.new\nalign = TkVariable.new\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $radio2_demo\n      $radio2_demo = nil\n      $showVarsWin[tmppath.path] = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'radio2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'See Variables'\n    command proc{\n      showVars(base_frame, \n               ['size', size], ['color', color], ['compound', align])\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nf_left  = TkLabelFrame.new(base_frame, 'text'=>'Point Size', \n                           'pady'=>2, 'padx'=>2)\nf_mid   = TkLabelFrame.new(base_frame, 'text'=>'Color', \n                           'pady'=>2, 'padx'=>2)\nf_right = TkLabelFrame.new(base_frame, 'text'=>'Alignment', \n                           'pady'=>2, 'padx'=>2)\nf_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\nf_mid.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\nf_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\n\n# radiobutton \n[10, 12, 18, 24].each {|sz|\n  TkRadioButton.new(f_left) {\n    text \"Point Size #{sz}\"\n    variable size\n    relief 'flat'\n    value sz\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w', 'fill'=>'x')\n}\n\n['Red', 'Green', 'Blue', 'Yellow', 'Orange', 'Purple'].each {|col|\n  TkRadioButton.new(f_mid) {\n    text col\n    variable color\n    relief 'flat'\n    value col.downcase\n    anchor 'w'\n  }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x')\n}\n\n# label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', \nlabel = Tk::Label.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', \n                    'compound'=>'left')\nlabel.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top')\nlabel.height(TkWinfo.reqheight(label))\nabtn = ['Top', 'Left', 'Right', 'Bottom'].collect{|a|\n  lower = a.downcase\n  TkRadioButton.new(f_right, 'text'=>a, 'variable'=>align, 'relief'=>'flat', \n                    'value'=>lower, 'indicatoron'=>0, 'width'=>7, \n                    'command'=>proc{label.compound(align.value)})\n}\n\nTk.grid('x', abtn[0])\nTk.grid(abtn[1], label, abtn[2])\nTk.grid('x', abtn[3])\n"
  },
  {
    "path": "ext/tk/sample/demos-en/radio3.rb",
    "content": "# radio3.rb\n#\n# This demonstration script creates a toplevel window containing\n# several radiobutton widgets.\n#\n# radiobutton widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($radio3_demo) && $radio3_demo\n  $radio3_demo.destroy \n  $radio3_demo = nil\nend\n\n# demo toplevel widget\n$radio3_demo = TkToplevel.new {|w|\n  title(\"Radiobutton Demonstration 3\")\n  iconname(\"radio3\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($radio3_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"Three groups of radiobuttons are displayed below.  If you click on a button then the button will become selected exclusively among all the buttons in its group.  A Tcl variable is associated with each group to indicate which of the group's buttons is selected.  When the 'Tristate' button is pressed, the radio buttons will display the tri-state mode. Selecting any radio button will return the buttons to their respective on/off state. Click the \\\"See Variables\\\" button to see the current values of the variables.\"\n}\nmsg.grid(:row=>0, :column=>0, :columnspan=>3, :sticky=>'nsew')\n\n# variable\nsize = TkVariable.new\ncolor = TkVariable.new\nalign = TkVariable.new\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), \n         :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         TkButton.new(frame, :text=>'See Variables', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{\n                        showVars(base_frame, ['size', size], \n                                 ['color', color], ['compound', align])\n                      }), \n         TkButton.new(frame, :text=>'See Code', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{showCode 'radio3'}), \n         TkButton.new(frame, :text=>'Dismiss', \n                      :image=>$image['delete'], :compound=>:left, \n                      :command=>proc{\n                        tmppath = $radio3_demo\n                        $radio3_demo = nil\n                        $showVarsWin[tmppath.path] = nil\n                        tmppath.destroy\n                      }), \n         :padx=>4, :pady=>4)\n  frame.grid_columnconfigure(0, :weight=>1)\n  TkGrid(frame, :row=>3, :column=>0, :columnspan=>3, :sticky=>'nsew')\n}\n\n# frame \nf_left  = TkLabelFrame.new(base_frame, 'text'=>'Point Size', \n                           'pady'=>2, 'padx'=>2)\nf_mid   = TkLabelFrame.new(base_frame, 'text'=>'Color', \n                           'pady'=>2, 'padx'=>2)\nf_right = TkLabelFrame.new(base_frame, 'text'=>'Alignment', \n                           'pady'=>2, 'padx'=>2)\nf_left .grid('column'=>0, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2)\nf_mid  .grid('column'=>1, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2)\nf_right.grid('column'=>2, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c')\n\nTkButton.new(base_frame, 'text'=>'Tristate', \n             'command'=>proc{size.value = 'multi'; color.value = 'multi'}){\n  grid('column'=>2, 'row'=>2, 'pady'=>'.5c', 'padx'=>'.5c')\n}\n\n# radiobutton \n[10, 12, 14, 18, 24].each {|sz|\n  TkRadioButton.new(f_left) {\n    text \"Point Size #{sz}\"\n    variable size\n    relief 'flat'\n    value sz\n    tristatevalue 'multi'\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w', 'fill'=>'x')\n}\n\n['Red', 'Green', 'Blue', 'Yellow', 'Orange', 'Purple'].each {|col|\n  TkRadioButton.new(f_mid) {\n    text col\n    variable color\n    relief 'flat'\n    value col.downcase\n    anchor 'w'\n    tristatevalue 'multi'\n    command proc{f_mid.fg(color.value)}\n  }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x')\n}\n\n# label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', \nlabel = Tk::Label.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', \n                    'compound'=>'left')\nlabel.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top')\nlabel.height(TkWinfo.reqheight(label))\na_btn = ['Top', 'Left', 'Right', 'Bottom'].collect{|a|\n  TkRadioButton.new(f_right, 'text'=>a, 'variable'=>align, 'relief'=>'flat', \n                    'value'=>a.downcase, 'indicatoron'=>0, 'width'=>7, \n                    'command'=>proc{label.compound(align.value)})\n}\n\nTk.grid('x', a_btn[0])\nTk.grid(a_btn[1], label, a_btn[2])\nTk.grid('x', a_btn[3])\n"
  },
  {
    "path": "ext/tk/sample/demos-en/rmt",
    "content": "#!/usr/bin/env ruby\n\n# rmt -- \n# This script implements a simple remote-control mechanism for \n# Tk applications.  It allows you to select an application and \n# then type commands to that application. \n\nrequire 'tk'\n\nclass Rmt\n  def initialize(parent=nil)\n    win = self\n\n    unless parent\n      parent = TkRoot.new\n    end\n    root = TkWinfo.toplevel(parent)\n    root.minsize(1,1)\n\n    # The instance variable below keeps track of the remote application \n    # that we're sending to.  If it's an empty string then we execute \n    # the commands locally. \n    @app = 'local'\n    @mode = 'Ruby'\n\n    # The instance variable below keeps track of whether we're in the \n    # middle of executing a command entered via the text. \n    @executing = 0\n\n    # The instance variable below keeps track of the last command executed, \n    # so it can be re-executed in response to !! commands. \n    @lastCommand = \"\"\n\n    # Create menu bar.  Arrange to recreate all the information in the \n    # applications sub-menu whenever it is cascaded to. \n\n    TkFrame.new(root, 'relief'=>'raised', 'bd'=>2) {|f|\n      pack('side'=>'top', 'fill'=>'x')\n      TkMenubutton.new(f, 'text'=>'File', 'underline'=>0) {|mb|\n\tTkMenu.new(mb) {|mf|\n\t  mb.menu(mf)\n\t  TkMenu.new(mf) {|ma| \n\t    postcommand proc{win.fillAppsMenu ma}\n\t    mf.add('cascade', 'label'=>'Select Application', \n\t\t   'menu'=>ma, 'underline'=>0)\n\t  }\n\t  add('command', 'label'=>'Quit', \n\t      'command'=>proc{root.destroy}, 'underline'=>0)\n\t}\n\tpack('side'=>'left')\n      }\n    }\n\n    # Create text window and scrollbar. \n\n    @txt = TkText.new(root, 'relief'=>'sunken', 'bd'=>2, 'setgrid'=>true) {\n      yscrollbar(TkScrollbar.new(root){pack('side'=>'right', 'fill'=>'y')})\n      pack('side'=>'left')\n    }\n\n    @promptEnd = TkTextMark.new(@txt, 'insert')\n\n    # Create a binding to forward commands to the target application, \n    # plus modify many of the built-in bindings so that only information \n    # in the current command can be deleted (can still set the cursor \n    # earlier in the text and select and insert;  just can't delete).\n\n    @txt.bindtags([@txt, TkText, root, 'all'])\n    @txt.bind('Return', proc{\n\t\t@txt.set_insert('end - 1c')\n\t\t@txt.insert('insert', \"\\n\")\n\t\twin.invoke\n\t\tTk.callback_break\n\t      })\n    @txt.bind('Delete', proc{\n\t\tbegin\n\t\t  @txt.tag_remove('sel', 'sel.first', @promptEnd)\n\t\trescue\n\t\tend\n\t\tif @txt.tag_nextrange('sel', '1.0', 'end') == []\n\t\t  if @txt.compare('insert', '<', @promptEnd)\n\t\t    Tk.callback_break\n\t\t  end\n\t\tend\n\t      })\n    @txt.bind('BackSpace', proc{\n\t\tbegin\n\t\t  @txt.tag_remove('sel', 'sel.first', @promptEnd)\n\t\trescue\n\t\tend\n\t\tif @txt.tag_nextrange('sel', '1.0', 'end') == []\n\t\t  if @txt.compare('insert', '<', @promptEnd)\n\t\t    Tk.callback_break\n\t\t  end\n\t\tend\n\t      })\n    @txt.bind('Control-d', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Control-k', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  @txt.set_insert(@promptEnd)\n\t\tend\n\t      })\n    @txt.bind('Control-t', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Meta-d', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Meta-BackSpace', proc{\n\t\tif @txt.compare('insert', '<=', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Control-h', proc{\n\t\tif @txt.compare('insert', '<=', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n\n    @txt.tag_configure('bold', 'font'=>['Courier', 12, 'bold'])\n\n    @app = Tk.appname('rmt')\n    if (@app =~ /^rmt(.*)$/)\n      root.title(\"Tk Remote Controller#{$1}\")\n      root.iconname(\"Tk Remote#{$1}\")\n    end\n    prompt\n    @txt.focus\n    #@app = TkWinfo.appname(TkRoot.new)\n  end\n\n  def tkTextInsert(w,s)\n    return if s == \"\"\n    begin\n      if w.compare('sel.first','<=','insert') \\\n\t&& w.compare('sel.last','>=','insert')\n\tw.tag_remove('sel', 'sel.first', @promptEnd)\n\tw.delete('sel.first', 'sel.last')\n      end\n    rescue\n    end\n    w.insert('insert', s)\n    w.see('insert')\n  end\n\n  # The method below is used to print out a prompt at the \n  # insertion point (which should be at the beginning of a line \n  # right now).\n\n  def prompt\n    @txt.insert('insert', \"#{@app}: \")\n    @promptEnd.set('insert')\n    @promptEnd.gravity = 'left'\n    @txt.tag_add('bold', \"#{@promptEnd.path} linestart\", @promptEnd)\n  end\n\n  # The method below executes a command (it takes everything on the \n  # current line after the prompt and either sends it to the remote \n  # application or executes it locally, depending on \"app\".\n\n  def invoke\n    cmd = @txt.get(@promptEnd, 'insert')\n    @executing += 1\n    case (@mode)\n    when 'Tcl'\n      if Tk.info('complete', cmd)\n\tif (cmd == \"!!\\n\")\n\t  cmd = @lastCommand\n\telse\n\t  @lastCommand = cmd\n\tend\n\tbegin\n\t  msg = Tk.appsend(@app, false, cmd)\n\trescue\n\t  msg = \"Error: #{$!}\"\n\tend\n\t@txt.insert('insert', msg + \"\\n\") if msg != \"\"\n\tprompt\n\t@promptEnd.set('insert')\n      end\n\n    when 'Ruby'\n      if (cmd == \"!!\\n\")\n\tcmd = @lastCommand\n      end\n      complete = true\n      begin\n\teval(\"proc{#{cmd}}\")\n      rescue\n\tcomplete = false\n      end\n      if complete\n\t@lastCommand = cmd\n\tbegin\n#\t  msg = Tk.appsend(@app, false, \n#\t\t\t   'ruby', \n#\t\t\t   '\"(' + cmd.gsub(/[][$\"]/, '\\\\\\\\\\&') + ').to_s\"')\n\t  msg = Tk.rb_appsend(@app, false, cmd)\n\trescue\n\t  msg = \"Error: #{$!}\"\n\tend\n\t@txt.insert('insert', msg + \"\\n\") if msg != \"\"\n\tprompt\n\t@promptEnd.set('insert')\n      end\n    end\n\n    @executing -= 1\n    @txt.yview_pickplace('insert')\n  end\n\n  # The following method is invoked to change the application that\n  # we're talking to.  It also updates the prompt for the current \n  # command, unless we're in the middle of executing a command from \n  # the text item (in which case a new prompt is about to be output \n  # so there's no need to change the old one). \n\n  def newApp(appName, mode)\n    @app = appName\n    @mode = mode\n    if @executing == 0\n      @promptEnd.gravity = 'right'\n      @txt.delete(\"#{@promptEnd.path} linestart\", @promptEnd)\n      @txt.insert(@promptEnd, \"#{appName}: \")\n      @txt.tag_add('bold', \"#{@promptEnd.path} linestart\", @promptEnd)\n      @promptEnd.gravity = 'left'\n    end\n  end\n\n  # The method below will fill in the applications sub-menu with a list\n  # of all the applications that currently exist. \n\n  def fillAppsMenu(menu)\n    win = self\n    begin\n      menu.delete(0,'last')\n    rescue\n    end\n    TkWinfo.interps.sort.each{|ip|\n      begin\n\tif Tk.appsend(ip, false, 'info commands ruby') == \"\"\n\t  mode = 'Tcl'\n\telse\n\t  mode = 'Ruby'\n\tend\n\tmenu.add('command', 'label'=>format(\"%s    (#{mode}/Tk)\", ip), \n\t\t 'command'=>proc{win.newApp ip, mode})\n      rescue\n\tmenu.add('command', 'label'=>format(\"%s (unknown Tk)\", ip), \n\t\t 'command'=>proc{win.newApp ip, mode}, 'state'=>'disabled')\n      end\n    }\n    menu.add('command', 'label'=>format(\"local    (Ruby/Tk)\"), \n\t     'command'=>proc{win.newApp 'local', 'Ruby'})\n  end\nend\n\nRmt.new\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/rolodex",
    "content": "#!/usr/bin/env ruby\n#\n# rolodex --\n# This script is a part of Tom LaStrange's rolodex\n# \n# Copyright (C) 1998 by Takaaki Tateishi <ttate@jaist.ac.jp>\n# Time-stamp: \"03/08/02 06:23:06 nagai\"\n#\n\nrequire \"tk\"\n\n\ndef show_help(topic,x=0,y=0)\n  if( topic.is_a?(TkWindow) )\n    w = TkWinfo.containing(x,y)\n    if( TkWinfo.exist?(w) )\n      topic = w\n    end\n  end\n  \n  if( $helpTopics.include?(topic) )\n    msg = $helpTopics[topic]\n  else\n    msg = \"Sorry, but no help is available for this topic\"\n  end\n  TkDialog.new(\"title\"=>\"Rolodex Help\",\n\t       \"message\"=>\"Information on #{topic}:\\n\\n#{msg}\",\n\t       \"default_button\"=>0,\n\t       \"buttons\"=>[\"OK\"])\nend\n\ndef fillCard\n  clearAction\n  $root.frame.entry[1].insert(0,\"Takaaki Tateishi\")\n  $root.frame.entry[2].insert(0,\"Japan Advanced Institute of Science and Techonology\")\n  $root.frame.entry[3].insert(0,\"1-1 Asahidai, Tatsunokuchi\")\n  $root.frame.entry[4].insert(0,\"Ishikawa 923-1292, Japan\")\n  $root.frame.entry[5].insert(0,\"private\")\n    $root.frame.entry[6].insert(0,\"***-***-****\")\n  $root.frame.entry[7].insert(0,\"***-***-****\")\nend\n\ndef addAction\n  for i in 1..7\n    STDERR.print format(\"%-12s %s\\n\",\n\t\t\tRolodexFrame::LABEL[i],\n\t\t\t$root.frame.entry[i].value)\n  end\nend\n\ndef clearAction\n  for i in 1..7\n    $root.frame.entry[i].delete(0,\"end\")\n  end\nend\n\ndef fileAction\n  TkDialog.new(\"title\"=>\"File Selection\",\n\t       \"message\"=>\"This is a dummy file selection dialog box.\\n\",\n\t       \"default_button\"=>0,\n\t       \"buttons\"=>[\"OK\"])\n  STDERR.print \"dummy file name\\n\"\nend\n\ndef deleteAction\n  result = TkDialog.new(\"title\"=>\"Confirm Action\",\n\t\t\t\"message\"=>\"Are you sure?\",\n\t\t\t\"default_button\"=>0,\n\t\t\t\"buttons\"=>[\"Cancel\"])\n  if( result.value == 0 )\n    clearAction\n  end\nend\n\n\nclass RolodexFrame < TkFrame\n  attr_reader :entry, :label\n\n  LABEL = [\"\",\"Name:\",\"Address:\",\"\",\"\",\"Home Phone:\",\"Work Phone:\",\"Fax:\"]\n\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n    self[\"relief\"] = \"flat\"\n    \n    @i = []\n    @label = []\n    @entry = []\n    for i in 1..7\n      @i[i] = TkFrame.new(self)\n      @i[i].pack(\"side\"=>\"top\",\n\t\t \"pady\"=>2,\n\t\t \"anchor\"=>\"e\")\n      @label[i] = TkLabel.new(@i[i],\n\t\t\t      \"text\"=>LABEL[i],\n\t\t\t      \"anchor\"=>\"e\")\n      @entry[i] = TkEntry.new(@i[i],\n\t\t\t      \"width\"=>30,\n\t\t\t      \"relief\"=>\"sunken\")\n      @entry[i].pack(\"side\"=>\"right\")\n      @label[i].pack(\"side\"=>\"right\")\n    end\n  end\nend\n\nclass RolodexButtons < TkFrame\n  attr_reader :clear, :add, :search, :delete\n\n  def initialize(parent,keys=nil)\n    super(parent,keys)\n    @clear = TkButton.new(self,\n\t\t\t  \"text\" => \"Clear\")\n    @add = TkButton.new(self,\n\t\t\t\"text\" => \"Add\")\n    @search = TkButton.new(self,\n\t\t\t   \"text\" => \"Search\")\n    @delete = TkButton.new(self,\n\t\t\t   \"text\" => \"Delete\")\n    for w in [@clear,@add,@search,@delete]\n      w.pack(\"side\"=>\"left\", \"padx\"=>2)\n    end\n  end\nend\n\nclass RolodexMenuFrame < TkFrame\n  attr_reader :file_menu, :help_menu, :file, :help\n\n  def initialize(parent,keys=nil)\n    super(parent,keys)\n    configure(\"relief\"=>\"raised\",\n\t      \"borderwidth\"=>1)\n\n    @file = TkMenubutton.new(self,\n\t\t\t     \"text\"=>\"File\",\n\t\t\t     \"underline\"=>0)\n    @file_menu = TkMenu.new(@file)\n    @file_menu.add(\"command\",\n\t\t   \"label\" => \"Load ...\",\n\t\t   \"command\" => proc{fileAction},\n\t\t   \"underline\" => 0)\n    @file_menu.add(\"command\",\n\t\t   \"label\" => \"Exit\",\n\t\t   \"command\" => proc{$root.destroy},\n\t\t   \"underline\" => 0)\n    @file.menu(@file_menu)\n    @file.pack(\"side\"=>\"left\")\n\n    @help = TkMenubutton.new(self,\n\t\t\t     \"text\"=>\"Help\",\n\t\t\t     \"underline\"=>0)\n    @help_menu = TkMenu.new(@help)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Context...\",\n\t\t   \"command\"=>proc{show_help(\"context\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Help...\",\n\t\t   \"command\"=>proc{show_help(\"help\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Window...\",\n\t\t   \"command\"=>proc{show_help(\"window\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Keys...\",\n\t\t   \"command\"=>proc{show_help(\"keys\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On version...\",\n\t\t   \"command\"=>proc{show_help(\"version\")},\n\t\t   \"underline\"=>3)\n    @help.menu(@help_menu)\n    @help.pack(\"side\"=>\"right\")\n  end\nend\n\nclass Rolodex < TkRoot\n  attr_reader :frame, :buttons, :menu\n\n  def initialize(*args)\n    super(*args)\n    @frame = RolodexFrame.new(self)\n    @frame.pack(\"side\"=>\"top\",\n\t\t\"fill\"=>\"y\",\n\t\t\"anchor\"=>\"center\")\n    @buttons = RolodexButtons.new(self)\n    @buttons.pack(\"side\"=>\"bottom\",\n\t\t  \"pady\"=>2,\n\t\t  \"anchor\"=>\"center\")\n    @menu = RolodexMenuFrame.new(self)\n    @menu.pack(\"before\"=>@frame,\n\t       \"side\"=>\"top\",\n\t       \"fill\"=>\"x\")\n  end\nend\n\n$root = Rolodex.new\n\n$root.buttons.delete.configure(\"command\"=>proc{deleteAction})\n$root.buttons.add.configure(\"command\"=>proc{addAction})\n$root.buttons.clear.configure(\"command\"=>proc{clearAction})\n$root.buttons.search.configure(\"command\"=>proc{addAction; fillCard})\n\n$root.buttons.clear.configure(\"text\"=>\"Clear   Ctrl+C\")\n$root.bind(\"Control-c\",proc{clearAction})\n\n$root.buttons.add.configure(\"text\"=>\"Add   Ctrl+A\")\n$root.bind(\"Control-a\",proc{addAction})\n\n$root.buttons.search.configure(\"text\"=>\"Search   Ctrl+S\")\n$root.bind(\"Control-s\",proc{addAction; fillCard})\n\n$root.buttons.delete.configure(\"text\"=>\"Delete...   Ctrl+D\")\n$root.bind(\"Control-d\",proc{deleteAction})\n\n$root.menu.file_menu.entryconfigure(1, \"accel\"=>\"Ctrl+F\")\n$root.bind(\"Control-f\",proc{fileAction})\n\n$root.menu.file_menu.entryconfigure(2, \"accel\"=>\"Ctrl+Q\")\n$root.bind(\"Control-q\",proc{$root.destroy})\n\n$root.frame.entry[1].focus\n\n$root.bind(\"Any-F1\",\n\t   proc{|event| show_help(event.widget, event.x_root, event.y_root)})\n$root.bind(\"Any-Help\",\n\t   proc{|event| show_help(event.widget, event.x_root, event.y_root)})\n\n\n$helpTopics = {}\n\n$helpTopics[$root.menu.file] = <<EOF\nThis is the \"file\" menu. It can be used to invoke\\\nsome overall operations on the rolodex applications,\\\nsuch as loading a file or exiting.\nEOF\n\n$helpTopics[$root.menu.file_menu.index(0)] = <<EOF\nThe \"Load\" entry in the \"File\" menu posts a dialog box\\\nthat you can use to select a rolodex file\nEOF\n\n$helpTopics[$root.menu.file_menu.index(1)] = <<EOF\nThe \"Exit\" entry in the \"File\" menu causes the rolodex\\\napplication to terminate\nEOF\n\n$helpTopics[$root.frame.entry[1]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the person's name\nEOF\n\n$helpTopics[$root.frame.entry[2]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the first line of the person's address\nEOF\n\n$helpTopics[$root.frame.entry[3]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the second line of the person's address\nEOF\n\n$helpTopics[$root.frame.entry[4]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the third line of the person's address\nEOF\n\n$helpTopics[$root.frame.entry[5]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the person's home phone number, or \"private\"\\\nif the person doesn't want his or he number publicized\nEOF\n\n$helpTopics[$root.frame.entry[6]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the person's work phone number\nEOF\n\n$helpTopics[$root.frame.entry[7]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the phone number for the person's FAX machine\nEOF\n\n$helpTopics[\"context\"] = <<EOF\nUnfortunately, this application doesn't support context-sensitive\\\nhelp in the usual way, because when this demo was written Ruby/Tk\\\ndidn't have a grab mechanism and this is needed for context-sensitive\\\nhelp. Instead, you can achive much the same effect by simply moving\\\nthe mouse over the window you're curious about and pressing the\\\nHelp or F1 keys. You can do this anytime.\nEOF\n\n$helpTopics[\"help\"] = <<EOF\nThis application provides only very crude help. Besides the\\\nentries in this menu, you can get help on individual windows\\\nby moving the mouse cursor over the window and pressing the\\\nHelp or F1 keys.\nEOF\n\n$helpTopics[\"window\"] = <<EOF\nThis window is a dummy rolodex application created as part of\\\nTom LaStrange's toolkit benchmark. It doesn't really do anything\\\nuseful except to demonstrate a few features of the Ruby/Tk.\nEOF\n\n$helpTopics[\"keys\"] = <<EOF\nThe following accelerator keys are defined for this application\\\n(in addition to those already available for the entry windows):\nCtrl+A:\t\tAdd\nCtrl+C:\t\tClear\nCtrl+D:\t\tDelete\nCtrl+F:\t\tEnter file name\nCtrl+Q:\t\tExit application (quit)\nCtrl+S:\t\tSearch (dummy operation)\nEOF\n\n$helpTopics[\"version\"] = <<EOF\nThis is version 1.0.1.\nEOF\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ruler.rb",
    "content": "# ruler.rb\n#\n# This demonstration script creates a canvas widget that displays a ruler\n# with tab stops that can be set, moved, and deleted.\n#\n# ruler widget demo (called by 'widget')\n#\n\n# rulerMkTab --\n# This method creates a new triangular polygon in a canvas to\n# represent a tab stop.\n#\n# Arguments:\n# c -           The canvas window.\n# x, y -        Coordinates at which to create the tab stop.\n\ndef rulerMkTab(c,x,y)\n  v = $demo_rulerInfo\n  TkcPolygon.new(c, x, y, x+v.size, y+v.size, x-v.size, y+v.size)\nend\n\n# toplevel widget\nif defined?($ruler_demo) && $ruler_demo\n  $ruler_demo.destroy \n  $ruler_demo = nil\nend\n\n# demo toplevel widget\n$ruler_demo = TkToplevel.new {|w|\n  title(\"Ruler Demonstration\")\n  iconname(\"ruler\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ruler_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', \n            'text'=>\"This canvas widget shows a mock-up of a ruler.  You can create tab stops by dragging them out of the well to the right of the ruler.  You can also drag existing tab stops.  If you drag a tab stop far enough up or down so that it turns dim, it will be deleted when you release the mouse button.\"){\n  pack('side'=>'top')\n}\n\n# frame\n$ruler_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $ruler_demo\n      $ruler_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'ruler'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$ruler_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# canvas \n$ruler_canvas = TkCanvas.new(base_frame, 'width'=>'14.8c', 'height'=>'2.5c')\n$ruler_canvas.pack('side'=>'top', 'fill'=>'x')\n\n# \nunless Struct.const_defined?(\"RulerInfo\")\n  $demo_rulerInfo = Struct.new(\"RulerInfo\", :grid, :left, :right, :x, :y, \n                               :top, :bottom, :size, :normalStyle, \n                               :activeStyle, :deleteStyle).new\nend\n$demo_rulerInfo.grid = '.25c'\n$demo_rulerInfo.left = TkWinfo.fpixels($ruler_canvas, '1c')\n$demo_rulerInfo.right = TkWinfo.fpixels($ruler_canvas, '13c')\n$demo_rulerInfo.top = TkWinfo.fpixels($ruler_canvas, '1c')\n$demo_rulerInfo.bottom = TkWinfo.fpixels($ruler_canvas, '1.5c')\n$demo_rulerInfo.size = TkWinfo.fpixels($ruler_canvas, '.2c')\n$demo_rulerInfo.normalStyle = {'fill'=>'black'}\nif TkWinfo.depth($ruler_canvas) > 1\n  $demo_rulerInfo.activeStyle = {'fill'=>'red', 'stipple'=>''}\n  $demo_rulerInfo.deleteStyle = {'fill'=>'red', \n    'stipple'=>'@'+[$demo_dir, '..', \n                     'images', 'gray25.xbm'].join(File::Separator)}\nelse\n  $demo_rulerInfo.activeStyle = {'fill'=>'black', 'stipple'=>''}\n  $demo_rulerInfo.deleteStyle = {'fill'=>'black', \n    'stipple'=>'@'+[$demo_dir, '..', \n                     'images', 'gray25.xbm'].join(File::Separator)}\nend\n\nTkcLine.new($ruler_canvas, \n            '1c', '0.5c', '1c', '1c', '13c', '1c', '13c', '0.5c', 'width'=>1)\n(0..11).each{|i|\n  x = i+1\n  TkcLine.new($ruler_canvas, \"#{x}c\", '1c', \"#{x}c\", '0.6c', 'width'=>1)\n  TkcLine.new($ruler_canvas, \"#{x}.25c\", '1c', \"#{x}.25c\", '0.8c', 'width'=>1)\n  TkcLine.new($ruler_canvas, \"#{x}.5c\", '1c', \"#{x}.5c\", '0.7c', 'width'=>1)\n  TkcLine.new($ruler_canvas, \"#{x}.75c\", '1c', \"#{x}.75c\", '0.8c', 'width'=>1)\n  TkcText.new($ruler_canvas, \"#{x}.15c\", '0.75c', 'text'=>i, 'anchor'=>'sw')\n}\n\n$rulerTag_well = TkcTag.new($ruler_canvas)\n$ruler_canvas\\\n.addtag_withtag($rulerTag_well,\n                TkcRectangle.new($ruler_canvas, \n                                 '13.2c', '1c', '13.8c', '0.5c', \n                                 'outline'=>'black', \n                                 'fill'=>($ruler_canvas\\\n                                          .configinfo('background'))[4]) )\n$ruler_canvas\\\n.addtag_withtag($rulerTag_well,\n                rulerMkTab($ruler_canvas, \n                           TkWinfo.pixels($ruler_canvas, '13.5c'), \n                           TkWinfo.pixels($ruler_canvas, '.65c') ) )\n\n$rulerTag_well.bind('1', proc{|x,y| rulerNewTab($ruler_canvas,x,y)}, '%x %y')\n$ruler_canvas.itembind('tab', '1', \n                       proc{|x,y| rulerSelectTab($ruler_canvas,x,y)}, '%x %y')\n$ruler_canvas.bind('B1-Motion', \n                   proc{|x,y| rulerMoveTab($ruler_canvas,x,y)}, '%x %y')\n$ruler_canvas.bind('Any-ButtonRelease-1', proc{rulerReleaseTab($ruler_canvas)})\n\n# rulerNewTab --\n# Does all the work of creating a tab stop, including creating the\n# triangle object and adding tags to it to give it tab behavior.\n#\n# Arguments:\n# c -           The canvas window.\n# x, y -        The coordinates of the tab stop.\n\ndef rulerNewTab(c,x,y)\n  v = $demo_rulerInfo\n  c.addtag_withtag('active', rulerMkTab(c,x,y))\n  c.addtag_withtag('tab', 'active')\n  v.x = x\n  v.y = y\n  rulerMoveTab(c,x,y)\nend\n\n# rulerSelectTab --\n# This method is invoked when mouse button 1 is pressed over\n# a tab.  It remembers information about the tab so that it can\n# be dragged interactively.\n#\n# Arguments:\n# c -           The canvas widget.\n# x, y -        The coordinates of the mouse (identifies the point by\n#               which the tab was picked up for dragging).\n\ndef rulerSelectTab(c,x,y)\n  v = $demo_rulerInfo\n  v.x = c.canvasx(x, v.grid)\n  v.y = v.top+2\n  c.addtag_withtag('active', 'current')\n  c.itemconfigure('active', v.activeStyle)\n  c.raise('active')\nend\n\n# rulerMoveTab --\n# This method is invoked during mouse motion events to drag a tab.\n# It adjusts the position of the tab, and changes its appearance if\n# it is about to be dragged out of the ruler.\n#\n# Arguments:\n# c -           The canvas widget.\n# x, y -        The coordinates of the mouse.\n\ndef rulerMoveTab(c,x,y)\n  v = $demo_rulerInfo\n  return if c.find_withtag('active') == []\n  cx = c.canvasx(x,v.grid)\n  cy = c.canvasy(y)\n  cx = v.left if cx < v.left\n  cx = v.right if cx > v.right\n  if (cy >= v.top && cy <= v.bottom)\n    cy = v.top+2\n    c.itemconfigure('active', v.activeStyle)\n  else\n    cy = cy-v.size-2\n    c.itemconfigure('active', v.deleteStyle)\n  end\n  c.move('active', cx-v.x, cy-v.y)\n  v.x = cx\n  v.y = cy\nend\n\n# rulerReleaseTab --\n# This method is invoked during button release events that end\n# a tab drag operation.  It deselects the tab and deletes the tab if\n# it was dragged out of the ruler.\n#\n# Arguments:\n# c -           The canvas widget.\n# x, y -        The coordinates of the mouse.\n\ndef rulerReleaseTab(c)\n  v = $demo_rulerInfo\n  return if c.find_withtag('active') == []\n  if v.y != v.top+2\n    c.delete('active')\n  else\n    c.itemconfigure('active', v.normalStyle)\n    c.dtag('active')\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/sayings.rb",
    "content": "# sayings.rb\n#\n# This demonstration script creates a listbox that can be scrolled\n# both horizontally and vertically.  It displays a collection of\n# well-known sayings.\n#\n# listbox widget demo 'sayings' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($sayings_demo) && $sayings_demo\n  $sayings_demo.destroy \n  $sayings_demo = nil\nend\n\n# demo toplevel widget\n$sayings_demo = TkToplevel.new {|w|\n  title(\"Listbox Demonstration (well-known sayings)\")\n  iconname(\"sayings\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($sayings_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"The listbox below contains a collection of well-known sayings.  You can scan the list using either of the scrollbars or by dragging in the listbox window with button 2 pressed.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $sayings_demo\n      $sayings_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'sayings'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\nsayings_lbox = nil\nTkFrame.new(base_frame, 'borderwidth'=>10) {|w|\n  sv = TkScrollbar.new(w)\n  sh = TkScrollbar.new(w, 'orient'=>'horizontal')\n  sayings_lbox = TkListbox.new(w) {\n    setgrid 1\n    width  20\n    height 10\n    yscrollcommand proc{|first,last| sv.set first,last}\n    xscrollcommand proc{|first,last| sh.set first,last}\n  }\n  sv.command(proc{|*args| sayings_lbox.yview(*args)})\n  sh.command(proc{|*args| sayings_lbox.xview(*args)})\n\n  if $tk_version =~ /^4\\.[01]/\n    sv.pack('side'=>'right', 'fill'=>'y')\n    sh.pack('side'=>'bottom', 'fill'=>'x')\n    sayings_lbox.pack('expand'=>'yes', 'fill'=>'y')\n\n  else\n    sayings_lbox.grid('row'=>0, 'column'=>0, \n                      'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    sv.grid('row'=>0, 'column'=>1, \n            'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    sh.grid('row'=>1, 'column'=>0, \n            'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    TkGrid.rowconfigure(w, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(w, 0, 'weight'=>1, 'minsize'=>0)\n  end\n\n}.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y')\n\nsayings_lbox.insert(0,\n\"Waste not, want not\",\n\"Early to bed and early to rise makes a man healthy, wealthy, and wise\",\n\"Ask not what your country can do for you, ask what you can do for your country\",\n\"I shall return\",\n\"NOT\",\n\"A picture is worth a thousand words\",\n\"User interfaces are hard to build\",\n\"Thou shalt not steal\",\n\"A penny for your thoughts\",\n\"Fool me once, shame on you;  fool me twice, shame on me\",\n\"Every cloud has a silver lining\",\n\"Where there's smoke there's fire\",\n\"It takes one to know one\",\n\"Curiosity killed the cat; but satisfaction brought it back\",\n\"Take this job and shove it\",\n\"Up a creek without a paddle\",\n\"I'm mad as hell and I'm not going to take it any more\",\n\"An apple a day keeps the doctor away\",\n\"Don't look a gift horse in the mouth\"\n)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/search.rb",
    "content": "# search.rb\n#\n# This demonstration script creates a collection of widgets that\n# allow you to load a file into a text widget, then perform searches\n# on that file.\n#\n# Text Search widget demo (called by 'widget')\n#\n\n# textLoadFile --\n# This method below loads a file into a text widget, discarding\n# the previous contents of the widget. Tags for the old widget are\n# not affected, however.\n#\n# Arguments:\n# w -           The window into which to load the file.  Must be a\n#               text widget.\n# file -        The name of the file to load.  Must be readable.\n\ndef textLoadFile(w,file)\n  w.delete('1.0', 'end')\n  f = open(file, 'r')\n  while(!f.eof?)\n    w.insert('end', f.read(1000))\n  end\n  f.close\nend\n\n# textSearch --\n# Search for all instances of a given string in a text widget and\n# apply a given tag to each instance found.\n#\n# Arguments:\n# w -           The window in which to search.  Must be a text widget.\n# string -      The string to search for.  The search is done using\n#               exact matching only;  no special characters.\n# tag -         Tag to apply to each instance of a matching string.\n\ndef textSearch(w, string, tag)\n  tag.remove('0.0', 'end')\n  return if string == \"\"\n  cur = '1.0'\n  loop {\n    cur, len = w.search_with_length(string, cur, 'end')\n    break if cur == \"\"\n    tag.add(cur, \"#{cur} + #{len} char\")\n    cur = w.index(\"#{cur} + #{len} char\")\n  }\nend\n\n# textToggle --\n# This method is invoked repeatedly to invoke two commands at\n# periodic intervals.  It normally reschedules itself after each\n# execution but if an error occurs (e.g. because the window was\n# deleted) then it doesn't reschedule itself.\n#\n# Arguments:\n# cmd1 -        Command to execute when method is called.\n# sleep1 -      Ms to sleep after executing cmd1 before executing cmd2.\n# cmd2 -        Command to execute in the *next* invocation of this method.\n# sleep2 -      Ms to sleep after executing cmd2 before executing cmd1 again.\n\ndef textToggle(cmd1,sleep1,cmd2,sleep2)\n  sleep_list = [sleep2, sleep1]\n  TkAfter.new(proc{sleep = sleep_list.shift; sleep_list.push(sleep); sleep}, \n              -1, cmd1, cmd2).start(sleep1)\nend\n\n# toplevel widget\nif defined?($search_demo) && $search_demo\n  $search_demo.destroy \n  $search_demo = nil\nend\n\n# demo toplevel widget\n$search_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Search and Highlight\")\n  iconname(\"search\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($search_demo).pack(:fill=>:both, :expand=>true)\n\n# frame\n$search_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $search_demo\n      $search_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'search'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$search_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\nTkFrame.new(base_frame) {|f|\n  TkLabel.new(f, 'text'=>'File name:', \n              'width'=>13, 'anchor'=>'w').pack('side'=>'left')\n  $search_fileName = TkVariable.new\n  TkEntry.new(f, 'width'=>40, \n              'textvariable'=>$search_fileName) {\n    pack('side'=>'left')\n    bind('Return', proc{textLoadFile($search_text, $search_fileName.value)\n                        $search_string_entry.focus})\n    focus\n  }\n  TkButton.new(f, 'text'=>'Load File', \n               'command'=>proc{textLoadFile($search_text, \n                                            $search_fileName.value)})\\\n  .pack('side'=>'left', 'pady'=>5, 'padx'=>10)\n}.pack('side'=>'top', 'fill'=>'x')\n\nTkFrame.new(base_frame) {|f|\n  TkLabel.new(f, 'text'=>'Search string:', \n              'width'=>13, 'anchor'=>'w').pack('side'=>'left')\n  $search_searchString = TkVariable.new\n  $search_string_entry = TkEntry.new(f, 'width'=>40, \n                                     'textvariable'=>$search_searchString) {\n    pack('side'=>'left')\n    bind('Return', proc{textSearch($search_text, $search_searchString.value, \n                                   $search_Tag)})\n  }\n  TkButton.new(f, 'text'=>'Highlight', \n               'command'=>proc{textSearch($search_text, \n                                          $search_searchString.value, \n                                          $search_Tag)}) {\n    pack('side'=>'left', 'pady'=>5, 'padx'=>10)\n  }\n}.pack('side'=>'top', 'fill'=>'x')\n\n$search_text = TkText.new(base_frame, 'setgrid'=>true, 'wrap'=>'word') {|t|\n  $search_Tag = TkTextTag.new(t)\n  TkScrollbar.new(base_frame, 'command'=>proc{|*args| t.yview(*args)}) {|sc|\n    t.yscrollcommand(proc{|first,last| sc.set first,last})\n    pack('side'=>'right', 'fill'=>'y')\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n}\n\n# Set up display styles for text highlighting.\n\nif TkWinfo.depth($search_demo) > 1\n  textToggle(proc{\n               $search_Tag.configure('background'=>'#ce5555', \n                                     'foreground'=>'white')\n             },\n             800, \n             proc{\n               $search_Tag.configure('background'=>'', 'foreground'=>'')\n             },\n             200 )\nelse\n  textToggle(proc{\n               $search_Tag.configure('background'=>'black', \n                                     'foreground'=>'white')\n             },\n             800, \n             proc{\n               $search_Tag.configure('background'=>'', 'foreground'=>'')\n             },\n             200 )\nend\n$search_text.insert('1.0', \"\\\nThis window demonstrates how to use the tagging facilities in text \\\nwidgets to implement a searching mechanism.  First, type a file name \\\nin the top entry, then type <Return> or click on \\\"Load File\\\".  Then \\\ntype a string in the lower entry and type <Return> or click on \\\n\\\"Load File\\\".  This will cause all of the instances of the string to \\\nbe tagged with the tag \\\"search\\\", and it will arrange for the tag\\'s \\\ndisplay attributes to change to make all of the strings blink.\")\n$search_text.insert('end', \"\\\nThe current directory to load a file is \\\"#{Dir.pwd}\\\".\\\n\")\n$search_text.set_insert '0.0'\n\n$search_fileName.value = ''\n$search_searchString.value = ''\n\n$search_text.width = 60\n$search_text.height = 20\n"
  },
  {
    "path": "ext/tk/sample/demos-en/spin.rb",
    "content": "# spin.rb --\n#\n# This demonstration script creates several spinbox widgets.\n#\n# based on Tcl/Tk8.4.4 widget demos\n\nif defined?($spin_demo) && $spin_demo\n  $spin_demo.destroy \n  $spin_demo = nil\nend\n\n$spin_demo = TkToplevel.new {|w|\n  title(\"Spinbox Demonstration\")\n  iconname(\"spin\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($spin_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'5i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nThree different spin-boxes are displayed below.  \\\nYou can add characters by pointing, clicking and typing.  \\\nThe normal Motif editing characters are supported, along with \\\nmany Emacs bindings.  For example, Backspace and Control-h \\\ndelete the character to the left of the insertion cursor and \\\nDelete and Control-d delete the chararacter to the right of the \\\ninsertion cursor.  For values that are too large to fit in the \\\nwindow all at once, you can scan through the value by dragging \\\nwith mouse button2 pressed.  Note that the first spin-box will \\\nonly permit you to type in integers, and the third selects from \\\na list of Australian cities.\nIf your Tk library linked to Ruby doesn't include a 'spinbox' widget, \\\nthis demo doesn't work. Please use later version of Tk \\\nwhich supports a 'spinbox' widget.\nEOL\n\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $spin_demo.destroy\n                 $spin_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'spin'\n               }).pack(:side=>:left, :expand=>true)\n}\n\naustralianCities = [\n    'Canberra', 'Sydney', 'Melbourne', 'Perth', 'Adelaide', \n    'Brisbane', 'Hobart', 'Darwin', 'Alice Springs'\n]\n\n[\n  TkSpinbox.new(base_frame, :from=>1, :to=>10, :width=>10, :validate=>:key, \n                :validatecommand=>[\n                  proc{|s| s == '' || /^[+-]?\\d+$/ =~ s }, '%P'\n                ]), \n  TkSpinbox.new(base_frame, :from=>0, :to=>3, :increment=>0.5, \n                :format=>'%05.2f', :width=>10), \n  TkSpinbox.new(base_frame, :values=>australianCities, :width=>10)\n].each{|sbox| sbox.pack(:side=>:top, :pady=>5, :padx=>10)}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/square",
    "content": "#!/usr/bin/env ruby\n\n# square --\n# This script generates a demo application containing only \n# a \"square\" widget.  It's only usable if Tk has been compiled \n# with tkSquare.c and with the -DSQUARE_DEMO compiler switch. \n# This demo arranges the following bindings for the widget: \n#\n# Button-1 press/drag:          moves square to mouse\n# \"a\":                          toggle size animation on/off\n#\n\nrequire 'tk'\nrequire 'tkafter'\n\nclass TkSquare<TkWindow\n  def create_self\n    begin\n      tk_call 'square', path\n    rescue\n      STDERR.print \"\\nSorry. Your Tk interpreter does not contain \" +\n\t'a \"square\" demonstration widget.' + \n\t\"\\n ( See documents included the Tcl/Tk source archive. )\\n\\n\"\n      exit\n    end\n  end\n  def size(amount=nil)\n    if amount\n      tk_send 'size', amount\n    else\n      number(tk_send('size'))\n    end\n  end\n  def position(x,y)\n    tk_send 'position', x, y\n  end\nend\n\n$s = TkSquare.new{\n  pack('expand'=>'yes', 'fill'=>'both')\n  bind('1', proc{|x,y| center(x,y)}, '%s %y')\n  bind('B1-Motion', proc{|x,y| center(x,y)}, '%s %y')\n  bind('a', proc{animate})\n  focus\n}\nTkRoot.new.minsize(1,1)\n\n# The procedure below centers the square on a given position.\n\ndef center(x,y)\n  a = $s.size\n  $s.position(x-(a/2), y-(a/2))\nend\n\n# The procedures below provide a simple form of animation where\n# the box changes size in a pulsing pattern: larger, smaller, larger, \n# and so on.\n\n$inc = 0\n\ndef timer_proc\n  a = $s.size\n  return if $inc == 0\n  $inc = -3 if a >= 40\n  $inc =  3 if a <= 10\n  $s.size(a+$inc)\nend\n\n$timer = TkAfter.new(30, -1, proc{timer_proc})\n\ndef animate\n  if $inc == 0\n    $inc = 3\n    $timer.start\n  else\n    $inc = 0\n    $timer.stop\n  end\nend\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/states.rb",
    "content": "# states.rb\n#\n# This demonstration script creates a listbox widget that displays\n# the names of the 50 states in the United States of America.\n#\n# listbox widget demo 'states' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($states_demo) && $states_demo\n  $states_demo.destroy \n  $states_demo = nil\nend\n\n# demo toplevel widget\n$states_demo = TkToplevel.new {|w|\n  title(\"Listbox Demonstration (states)\")\n  iconname(\"states\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($states_demo).pack(:fill=>:both, :expand=>true)\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"A listbox containing the 50 states is displayed below, along with a scrollbar.  You can scan the list either using the scrollbar or by scanning.  To scan, press button 2 in the widget and drag up or down.\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $states_demo\n      $states_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'states'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\nstates_lbox = nil\nTkFrame.new(base_frame, 'borderwidth'=>'.5c') {|w|\n  s = TkScrollbar.new(w)\n  states_lbox = TkListbox.new(w) {\n    setgrid 1\n    height 12\n    yscrollcommand proc{|first,last| s.set first,last}\n  }\n  s.command(proc{|*args| states_lbox.yview(*args)})\n  s.pack('side'=>'right', 'fill'=>'y')\n  states_lbox.pack('side'=>'left', 'expand'=>1, 'fill'=>'both')\n}.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y')\n\nins_data = [\n  'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', \n  'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', \n  'Hawaii', 'Idaho', 'Illinois', \n  'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', \n  'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', \n  'Montana', 'Nebraska', 'Nevada', 'New_Hampshire', 'New_Jersey', 'New_Mexico', \n  'New_York', 'North_Carolina', 'North_Dakota', \n  'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode_Island', \n  'South_Carolina', 'South_Dakota', \n  'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', \n  'West_Virginia', 'Wisconsin', 'Wyoming'\n]\n\nstates_lbox.insert(0, *ins_data)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/style.rb",
    "content": "# style.rb\n#\n# This demonstration script creates a text widget that illustrates the\n# various display styles that may be set for tags.\n#\n# text (display styles) widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($style_demo) && $style_demo\n  $style_demo.destroy \n  $style_demo = nil\nend\n\n# demo toplevel widget\n$style_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Display Styles\")\n  iconname(\"style\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($style_demo).pack(:fill=>:both, :expand=>true)\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $style_demo\n      $style_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'style'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# text \ntxt = TkText.new(base_frame){|t|\n  # \n  setgrid 'true'\n  #width  70\n  #height 32\n  wrap 'word'\n  font $font\n  TkScrollbar.new(base_frame) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    command proc{|*args| t.yview(*args)}\n    t.yscrollcommand proc{|first,last| s.set first,last}\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n\n  # \n  family = 'Courier'\n\n  if $tk_version =~ /^4.*/\n    style_tag_bold = TkTextTag.new(t, 'font'=>'-*-Courier-Bold-O-Normal--*-120-*-*-*-*-*-*')\n    style_tag_big = TkTextTag.new(t, 'font'=>'-*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*', 'kanjifont'=>$msg_kanji_font)\n    style_tag_verybig = TkTextTag.new(t, 'font'=>'-*-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*')\n    #    style_tag_small = TkTextTag.new(t, 'font'=>'-Adobe-Helvetica-Bold-R-Normal-*-100-*', 'kanjifont'=>$kanji_font)\n    style_tag_small = TkTextTag.new(t, 'font'=>'-Adobe-Helvetica-Bold-R-Normal-*-100-*')\n  else\n    style_tag_bold = TkTextTag.new(t, 'font'=>[family, 12, :bold, :italic])\n    style_tag_big = TkTextTag.new(t, 'font'=>[family, 14, :bold])\n    style_tag_verybig = TkTextTag.new(t, 'font'=>['Helvetica', 24, :bold])\n    style_tag_small = TkTextTag.new(t, 'font'=>'Times 8 bold')\n  end\n###\n#  case($tk_version)\n#  when /^4.*/\n#    style_tag_big = TkTextTag.new(t, 'font'=>'-*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*', 'kanjifont'=>$msg_kanji_font)\n#    style_tag_small = TkTextTag.new(t, 'font'=>'-Adobe-Helvetica-Bold-R-Normal-*-100-*', 'kanjifont'=>$kanji_font)\n#  when /^8.*/\n#    unless $style_demo_do_first\n#      $style_demo_do_first = true\n#      Tk.tk_call('font', 'create', '@bigascii', \n#                '-copy', '-*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*')\n#      Tk.tk_call('font', 'create', '@smallascii', \n#                '-copy', '-Adobe-Helvetica-Bold-R-Normal-*-100-*')\n#      Tk.tk_call('font', 'create', '@cBigFont', \n#                '-compound', '@bigascii @msg_knj')\n#      Tk.tk_call('font', 'create', '@cSmallFont', \n#                '-compound', '@smallascii @kanji')\n#    end\n#    style_tag_big = TkTextTag.new(t, 'font'=>'@cBigFont')\n#    style_tag_small = TkTextTag.new(t, 'font'=>'@cSmallFont')\n#  end\n\n  # \n  if TkWinfo.depth($root).to_i > 1\n    style_tag_color1 = TkTextTag.new(t, 'background'=>'#a0b7ce')\n    style_tag_color2 = TkTextTag.new(t, 'foreground'=>'red')\n    style_tag_raised = TkTextTag.new(t, 'relief'=>'raised', 'borderwidth'=>1)\n    style_tag_sunken = TkTextTag.new(t, 'relief'=>'sunken', 'borderwidth'=>1)\n  else\n    style_tag_color1 = TkTextTag.new(t, 'background'=>'black', \n                                     'foreground'=>'white')\n    style_tag_color2 = TkTextTag.new(t, 'background'=>'black', \n                                     'foreground'=>'white')\n    style_tag_raised = TkTextTag.new(t, 'background'=>'white', \n                                     'relief'=>'raised', 'borderwidth'=>1)\n    style_tag_sunken = TkTextTag.new(t, 'background'=>'white', \n                                     'relief'=>'sunken', 'borderwidth'=>1)\n  end\n\n  # \n  if $tk_version =~ /^4\\.[01]/\n    style_tag_bgstipple = TkTextTag.new(t, 'background'=>'black', \n                                        'borderwidth'=>0, \n                                        'bgstipple'=>'gray25')\n  else\n    style_tag_bgstipple = TkTextTag.new(t, 'background'=>'black', \n                                        'borderwidth'=>0, \n                                        'bgstipple'=>'gray12')\n  end\n  style_tag_fgstipple = TkTextTag.new(t, 'fgstipple'=>'gray50')\n  style_tag_underline = TkTextTag.new(t, 'underline'=>'on')\n  style_tag_overstrike = TkTextTag.new(t, 'overstrike'=>'on')\n  style_tag_right  = TkTextTag.new(t, 'justify'=>'right')\n  style_tag_center = TkTextTag.new(t, 'justify'=>'center')\n  if $tk_version =~ /^4.*/\n    style_tag_super = TkTextTag.new(t, 'offset'=>'4p', 'font'=>'-Adobe-Courier-Medium-R-Normal--*-100-*-*-*-*-*-*')\n    style_tag_sub = TkTextTag.new(t, 'offset'=>'-2p', 'font'=>'-Adobe-Courier-Medium-R-Normal--*-100-*-*-*-*-*-*')\n  else\n    style_tag_super = TkTextTag.new(t, 'offset'=>'4p', 'font'=>[family, 10])\n    style_tag_sub = TkTextTag.new(t, 'offset'=>'-2p', 'font'=>[family, 10])\n  end\n  style_tag_margins = TkTextTag.new(t, 'lmargin1'=>'12m', 'lmargin2'=>'6m',\n                                    'rmargin'=>'10m')\n  style_tag_spacing = TkTextTag.new(t, 'spacing1'=>'10p', 'spacing2'=>'2p',\n                                    'lmargin1'=>'12m', 'lmargin2'=>'6m',\n                                    'rmargin'=>'10m')\n\n  # \n  insert('end', 'Text widgets like this one allow you to display information in a\nvariety of styles.  Display styles are controlled using a mechanism\ncalled ')\n  insert('end', 'tags', style_tag_big)\n  insert('end', '. Tags are just textual names that you can apply to one\nor more ranges of characters within a text widget.  You can configure\ntags with various display styles.  If you do this, then the tagged\ncharacters will be displayed with the styles you chose.  The\navailable display styles are:\n')\n  insert('end', \"\\n1. Font.\", style_tag_big)\n  insert('end', \"  You can choose any X font, \")\n  insert('end', \"large\", style_tag_verybig)\n  insert('end', \" or \")\n  insert('end', \"small\", style_tag_small)\n  insert('end', \".\\n\")\n  insert('end', \"\\n2. Color.\", style_tag_big)\n  insert('end', \"  You can change either the \")\n  insert('end', \"background\", style_tag_color1)\n  insert('end', \" or \")\n  insert('end', \"foreground\", style_tag_color2)\n  insert('end', \"\\ncolor, or \")\n  insert('end', \"both\", style_tag_color1, style_tag_color2)\n  insert('end', \".\\n\")\n  insert('end', \"\\n3. Stippling.\", style_tag_big)\n  insert('end', \"  You can cause either the \")\n  insert('end', \"background\", style_tag_bgstipple)\n  insert('end', \" or \")\n  insert('end', \"foreground\", style_tag_fgstipple)\n  insert('end', \"\\ninformation to be drawn with a stipple fill instead of a solid fill.\\n\")\n  insert('end', \"\\n4. Underlining.\", style_tag_big)\n  insert('end', \"  You can \")\n  insert('end', \"underline\", style_tag_underline)\n  insert('end', \" ranges of text.\\n\")\n  insert('end', \"\\n5. Overstrikes.\", style_tag_big)\n  insert('end', \"  You can \")\n  insert('end', \"draw lines through\", style_tag_overstrike)\n  insert('end', \" ranges of text.\\n\")\n  insert('end', \"\\n6. 3-D effects.\", style_tag_big)\n  insert('end', \"  You can arrange for the background to be drawn\\nwith a border that makes characters appear either\\n\")\n  insert('end', \"raised\", style_tag_raised)\n  insert('end', \" or \")\n  insert('end', \"sunken\", style_tag_sunken)\n  insert('end', \".\\n\")\n  insert('end', \"\\n7. Justification.\", style_tag_big)\n  insert('end', \" You can arrange for lines to be displayed\\n\")\n  insert('end', \"left-justified,\\n\")\n  insert('end', \"right-justified, or\\n\", style_tag_right)\n  insert('end', \"centered.\\n\", style_tag_center)\n  insert('end', \"\\n8. Superscripts and subscripts.\", style_tag_big)\n  insert('end', \" You can control the vertical\\n\")\n  insert('end', \"position of text to generate superscript effects like 10\")\n  insert('end', \"n\", style_tag_super)\n  insert('end', \" or\\nsubscript effects like X\")\n  insert('end', \"i\", style_tag_sub)\n  insert('end', \".\\n\")\n  insert('end', \"\\n9. Margins.\", style_tag_big)\n  insert('end', \" You can control the amount of extra space left\")\n  insert('end', \" on\\neach side of the text:\\n\")\n  insert('end', \"This paragraph is an example of the use of \", style_tag_margins)\n  insert('end', \"margins.  It consists of a single line of text \", style_tag_margins)\n  insert('end', \"that wraps around on the screen.  There are two \", style_tag_margins)\n  insert('end', \"separate left margin values, one for the first \", style_tag_margins)\n  insert('end', \"display line associated with the text line, \", style_tag_margins)\n  insert('end', \"and one for the subsequent display lines, which \", style_tag_margins)\n  insert('end', \"occur because of wrapping.  There is also a \", style_tag_margins)\n  insert('end', \"separate specification for the right margin, \", style_tag_margins)\n  insert('end', \"which is used to choose wrap points for lines.\\n\", style_tag_margins)\n  insert('end', \"\\n10. Spacing.\", style_tag_big)\n  insert('end', \" You can control the spacing of lines with three\\n\")\n  insert('end', \"separate parameters.  \\\"Spacing1\\\" tells how much \")\n  insert('end', \"extra space to leave\\nabove a line, \\\"spacing3\\\" \")\n  insert('end', \"tells how much space to leave below a line,\\nand \")\n  insert('end', \"if a text line wraps, \\\"spacing2\\\" tells how much \")\n  insert('end', \"space to leave\\nbetween the display lines that \")\n  insert('end', \"make up the text line.\\n\")\n  insert('end', \"These indented paragraphs illustrate how spacing \", style_tag_spacing)\n  insert('end', \"can be used.  Each paragraph is actually a \", style_tag_spacing)\n  insert('end', \"single line in the text widget, which is \", style_tag_spacing)\n  insert('end', \"word-wrapped by the widget.\\n\", style_tag_spacing)\n  insert('end', \"Spacing1 is set to 10 points for this text, \", style_tag_spacing)\n  insert('end', \"which results in relatively large gaps between \", style_tag_spacing)\n  insert('end', \"the paragraphs.  Spacing2 is set to 2 points, \", style_tag_spacing)\n  insert('end', \"which results in just a bit of extra space \", style_tag_spacing)\n  insert('end', \"within a pararaph.  Spacing3 isn't used \", style_tag_spacing)\n  insert('end', \"in this example.\\n\", style_tag_spacing)\n  insert('end', \"To see where the space is, select ranges of \", style_tag_spacing)\n  insert('end', \"text within these paragraphs.  The selection \", style_tag_spacing)\n  insert('end', \"highlight will cover the extra space.\", style_tag_spacing)\n\n}\n\ntxt.width 70\ntxt.height 32\n"
  },
  {
    "path": "ext/tk/sample/demos-en/tcolor",
    "content": "#!/usr/bin/env ruby\n#\n# tcolor --\n#   simple color editor which supports RGB, HSB and CYM color space\n#\n# Copyright (C) 1998 Takaaki Tateishi(ttate@jaist.ac.jp)\n# last update: Thu Jun 18 06:32:35 JST 1998\n#\n\nrequire \"tk\"\n\n\n# use TkVariable instance for the variable which is changed by Tk interpreter\n\n$colorSpace = TkVariable.new(:rgb)\n$master = nil\n$red = 65535\n$green = 0\n$blue = 0\n$color = \"#ffff00000000\"\n$updating = TkVariable.new(0)\n$autoUpdate = TkVariable.new(1)\n$name = TkVariable.new($color)\n$command = TkVariable.new(\"print(%%,\\\"\\n\\\")\")\n# $command = TkVariable.new(\"\")\n$label1 = TkVariable.new(\"label1\")\n$label2 = TkVariable.new(\"label2\")\n$label3 = TkVariable.new(\"label3\")\n\n\n# setup the entry of the resourc database\nif (TkVarAccess.new('tcl_platform')['platform'] == 'unix')\n  TkOptionDB.add('*Entry.background', 'white')\nend\n\n\n# methods for events\n\ndef rgbToHsv(red,green,blue)\n\n  if ( red > green )\n    max = red\n    min = green\n  else\n    max = green\n    min = red\n  end\n\n  if ( blue > max )\n    max = blue\n  else\n    if ( blue < min )\n      min = blue\n    end\n  end\n\n  range = max - min\n\n  if ( max == 0 )\n    sat = 0.0\n  else\n    sat = (max-min)/max\n  end\n\n  if ( sat == 0 )\n    hue = 0.0\n  else\n    rc = (max-red)/range\n    gc = (max-green)/range\n    bc = (max-blue)/range\n    if ( red == max )\n      hue = 0.166667 * (bc - gc)\n    else\n      if ( green == max )\n\thue = 0.166667 * (2.0 + rc - bc)\n      else\n\thue = 0.166667 * (4.0 + gc - rc)\n      end\n    end\n    if ( hue < 0.0 )\n      hue = hue + 1.0\n    end\n  end\n\n  [hue,sat,max/65535]\nend\n\n\ndef hsbToRgb(hue,sat,value)\n  v = 65535.0 * value\n  if( sat == 0 )\n    ans = [v,v,v]\n  else\n    hue = hue*6.0\n    if ( hue >= 6 )\n      hue = 0.0\n    end\n    i = hue.to_i\n    f = hue - i\n    p = 65535.0 * value * (1.0 - sat)\n    q = 65535.0 * value * (1.0 - (sat * f))\n    t = 65535.0 * value * (1.0 - (sat * (1.0 - f)))\n    case i\n    when 0\n      ans = [v,t,p]\n    when 1\n      ans = [q,v,p]\n    when 2\n      ans = [p,v,t]\n    when 3\n      ans = [p,q,v]\n    when 4\n      ans = [t,p,v]\n    when 5\n      ans = [v,p,q]\n    else\n      raise(eException,\"i value #{i} is out of range\")\n    end\n  end\n  return ans\nend\n\n\ndef _null_binding\n  Module.new.instance_eval{binding}\nend\nprivate :_null_binding\n\ndef doUpdate \n  newCmd = $command.to_s.gsub(\"%%\",\"\\\"#{$color}\\\"\")\n  eval(newCmd, _null_binding)\nend\n\n\ndef tc_scaleChanged\n  if( $updating.to_i == 1 )\n    return \n  end\n\n  $master = :scale if $master == nil\n\n  scale1 = $root.middle.middle.scale1\n  scale2 = $root.middle.middle.scale2\n  scale3 = $root.middle.middle.scale3\n\n  case $colorSpace.value.intern\n  when :rgb\n    $red = (scale1.get * 65.535).to_i\n    $green = (scale2.get * 65.535).to_i\n    $blue = (scale3.get * 65.535).to_i\n  when :cmy\n    $red = (65535 - scale1.get * 65.535).to_i\n    $green = (65535 - scale2.get * 65.535).to_i\n    $blue = (65535 - scale3.get * 65.535).to_i        \n  when :hsb\n    list = hsbToRgb(scale1.get / 1000.0,\n\t\t    scale2.get / 1000.0,\n\t\t    scale3.get / 1000.0)\n    $red = list[0]\n    $green = list[1]\n    $blue = list[2]\n  else\n    raise(Exception,\"unknown colorSpace\")\n  end\n  $color = format(\"#%04x%04x%04x\",$red.to_i,$green.to_i,$blue.to_i)\n  $name.value = $color if $master == :scale\n  $root.middle.right.set_color($color)\n  if( $autoUpdate.to_i == 1 )\n    doUpdate\n  end\n  Tk.update(true)\n  $master = nil if $master == :scale\nend\n\n\ndef tc_setScales\n  $updating.value = 1\n\n  scale1 = $root.middle.middle.scale1\n  scale2 = $root.middle.middle.scale2\n  scale3 = $root.middle.middle.scale3\n  \n  case $colorSpace.value.intern\n  when :rgb\n    scale1.set($red / 65.535)\n    scale2.set($green / 65.535)\n    scale3.set($blue / 65.535)\n  when :cmy\n    scale1.set((65535 - $red) / 65.535)\n    scale2.set((65535 - $green) / 65.535)\n    scale3.set((65535 - $blue) / 65.535)\n  when :hsb\n    list = rgbToHsv($red,$green,$blue)\n    scale1.set( list[0] * 1000.0 )\n    scale2.set( list[1] * 1000.0 )\n    scale3.set( list[2] * 1000.0 )\n  else\n    raise(Exception,\"unknown colorSpace\")\n  end\n\n  $updating.value = 0\nend\n\n\ndef tc_loadNamedColor(name)\n  $name.value = name\n  $master = :name if $master == nil\n  if name[0,1] != \"#\" \n    list = TkWinfo.rgb($root.middle.right.swatch,name)\n    $red = list[0]\n    $green = list[1]\n    $blue = list[2]\n  else\n    case name.length\n    when 4\n      fmt = /#(.{1})(.{1})(.{1})/\n      shift = 12\n    when 7\n      fmt = /#(.{2})(.{2})(.{2})/\n      shift = 8\n    when 10\n      fmt = /#(.{3})(.{3})(.{3})/\n      shift = 4\n    when 13\n      fmt = /#(.{4})(.{4})(.{4})/\n      shift = 0\n    else\n      raise(eException,\"syntax error in color name \\\"#{name}\\\"\")\n    end\n    name.scan(fmt){|strlist|\n      if strlist.length != 3\n\traise(eException,\"syntax error in color name \\\"#{name}\\\"\")\n      end\n      $red = strlist[0].hex\n      $green = strlist[1].hex\n      $blue = strlist[2].hex\n    }\n    $red = $red << shift\n    $green = $green << shift\n    $blue = $blue << shift\n  end\n  \n  tc_setScales\n  $color = format(\"#%04x%04x%04x\",$red,$green,$blue)\n  $root.middle.right.set_color($color)\n  if $autoUpdate.to_i == 1\n    doUpdate\n  end\n  Tk.update(true)\n  $master = nil if $master == :name\nend\n\n\ndef changeColorSpace(space)\n  case space\n  when :rgb\n    $label1.value = \"Red\"\n    $label2.value = \"Green\"\n    $label3.value = \"Blue\"\n  when :cmy\n    $label1.value = \"Cyan\"\n    $label2.value = \"Magenta\"\n    $label3.value = \"Yellow\"\n  when :hsb\n    $label1.value = \"Hue\"\n    $label2.value = \"Saturation\"\n    $label3.value = \"Brightness\"\n  end\n  tc_setScales\nend\n\n\n# menu\n\nclass TkColorMenuFrame<TkFrame\n  def initialize(parent)\n    super(parent,\n\t  \"relief\"=>\"raised\",\n\t  \"borderwidth\"=>\"2\")\n\n    # File menubutton\n    @file = TkMenubutton.new(self){|button|\n\n      # File menu\n      @file_menu = TkMenu.new(button){\n\tadd \"radio\",\n\t  \"label\" => \"RGB color space\",\n\t  \"variable\" => $colorSpace,\n\t  \"value\" => :rgb,\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{changeColorSpace(:rgb)}\n\tadd \"radio\",\n\t  \"label\" => \"CMY color space\",\n\t  \"variable\" => $colorSpace,\n\t  \"value\" => :cmy,\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{changeColorSpace(:cmy)}\n\tadd \"radio\",\n\t  \"label\" => \"HSB color space\",\n\t  \"variable\" => $colorSpace,\n\t  \"value\" => :hsb,\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{changeColorSpace(:hsb)}\n\tadd \"separator\"\n\tadd \"radio\",\n\t  \"label\" => \"Automatic updates\",\n\t  \"variable\" => $autoUpdate,\n\t  \"value\" => \"1\",\n\t  \"underline\" => \"0\"\n\tadd \"radio\",\n\t  \"label\" => \"Manual updates\",\n\t  \"variable\" => $autoUpdate,\n\t  \"value\" => \"0\",\n\t  \"underline\" => \"0\"\n\tadd \"separator\"\n\tadd \"command\",\n\t  \"label\" => \"Exit program\",\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{exit}\n      }\n      \n      # assign File menu to File button\n      menu @file_menu\n\n      text \"File\"\n      underline \"0\"\n    }.pack(\"side\"=>\"left\")\n\n    self\n  end\nend\n\n\n# bottom frame\nclass TkColorBotFrame<TkFrame\n  def initialize(parent)\n    super(parent,\n\t  \"relief\"=> \"raised\",\n\t  \"borderwidth\"=> 2)\n\n    @commandLabel = TkLabel.new(self,\n\t\t\t\t\"text\"=> \"Command:\")\n    @command = TkEntry.new(self,\n\t\t\t   \"relief\"=> \"sunken\",\n\t\t\t   \"borderwidth\"=> \"2\",\n\t\t\t   \"textvariable\"=> $command,\n\t\t\t   \"font\"=> \"-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*\")\n    @update = TkButton.new(self,\n\t\t\t   \"text\"=> \"Update\",\n\t\t\t   \"command\"=> proc{doUpdate})\n    @commandLabel.pack(\"side\"=>\"left\")\n    @update.pack(\"side\"=>\"right\",\"pady\"=>\".1c\",\"padx\"=>\".25c\")\n    @command.pack(\"expand\"=>\"yes\",\"fill\"=>\"x\",\"ipadx\"=>\".25c\")\n\n    self\n  end\nend    \n\n\n# left side frame of middle level\nclass TkColorMiddleLeftFrame<TkFrame\n  def initialize(parent)\n    super(parent)\n\n    for i in [\"/usr/local/lib/X11rgb.txt\",\"/usr/lib/X11/rgb.txt\",\n\t\"/X11/R5/lib/X11/rgb.txt\",\"/X11/R4/lib/rgb/rgb.txt\",\n\t\"/usr/openwin/lib/X11/rgb.txt\"]\n      if !File.readable?(i)\n\tnext\n      end\n      f = File.open(i)\n      @scroll = TkScrollbar.new(self,\n\t\t\t\t\"orient\"=>\"vertical\",\n\t\t\t\t\"relief\"=>\"sunken\",\n\t\t\t\t\"borderwidth\"=>\"2\")\n      @scroll.pack(\"side\"=>\"right\",\"fill\"=>\"y\")\n      @names = TkListbox.new(self,\n\t\t\t     \"width\"=>\"20\",\n\t\t\t     \"height\"=>\"12\",\n\t\t\t     \"yscrollcommand\"=> proc{|first,last| @scroll.set first,last},\n\t\t\t     \"relief\"=>\"sunken\",\n\t\t\t     \"borderwidth\"=>\"2\",\n\t\t\t     \"exportselection\"=>\"false\")\n      @scroll.command(proc{|*args| @names.yview(*args)})\n      @names.bind(\"Double-1\",proc{\n\t\t    tc_loadNamedColor(@names.get(@names.curselection))})\n      @names.pack(\"side\"=>\"left\")\n      while (line = f.gets)\n\tline.chop!\n\tlinelist = line.split(/[ \\t]+/)\n\tif linelist.length == 4\n\t  @names.insert(\"end\",linelist[3])\n\tend\n      end\n      f.close\n      break\n    end\n\n    self\n  end\nend\n\n\n# middle frame of middle level\nclass TkColorMiddleMiddleFrame<TkFrame\n  attr_reader :scale1, :scale2, :scale3\n\n  def initialize(parent)\n    super(parent)\n\n    @f1 = TkFrame.new(self)\n    @f2 = TkFrame.new(self)\n    @f3 = TkFrame.new(self)\n    @f4 = TkFrame.new(self)\n\n    for f in [@f1,@f2,@f3]\n      f.pack(\"side\"=>\"top\",\"expand\"=>\"yes\")\n    end\n    @f4.pack(\"side\"=>\"top\",\"expand\"=>\"yes\",\"fill\"=>\"x\")\n\n    @label1 = TkLabel.new(self,\"textvariable\"=>$label1)\n    @scale1 = TkScale.new(self,\"from\"=>\"0\",\"to\"=>\"1000\",\"length\"=>\"6c\",\n\t\t\t  \"orient\"=>\"horizontal\",\n\t\t\t  \"command\"=>proc{tc_scaleChanged})\n    @scale1.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n    @label1.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n\n    @label2 = TkLabel.new(self,\"textvariable\"=>$label2)\n    @scale2 = TkScale.new(self,\"from\"=>\"0\",\"to\"=>\"1000\",\"length\"=>\"6c\",\n\t\t\t  \"orient\"=>\"horizontal\",\n\t\t\t  \"command\"=>proc{tc_scaleChanged})\n    @scale2.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n    @label2.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n\n    @label3 = TkLabel.new(self,\"textvariable\"=>$label3)\n    @scale3 = TkScale.new(self,\"from\"=>\"0\",\"to\"=>\"1000\",\"length\"=>\"6c\",\n\t\t\t  \"orient\"=>\"horizontal\",\n\t\t\t  \"command\"=>proc{tc_scaleChanged})\n    @scale3.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n    @label3.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n\n    @nameLabel = TkLabel.new(self,\"text\"=>\"Name:\")\n    @name = TkEntry.new(self,\"relief\"=>\"sunken\",\"borderwidth\"=>\"2\",\n\t\t\t\"textvariable\"=>$name,\"width\"=>\"10\",\n\t\t\t\"font\"=>\"-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*\")\n    @nameLabel.pack(\"side\"=>\"left\")\n    @name.pack(\"side\"=>\"right\", \"expand\"=>\"1\", \"fill\"=>\"x\")\n    @name.bind(\"Return\",proc{tc_loadNamedColor $name.to_s})\n\n    self\n  end\nend\n\n\nclass TkColorMiddleRightFrame<TkFrame\n  attr_reader :swatch\n\n  def initialize(parent)\n    super(parent)\n    @swatch = TkFrame.new(self, \"width\"=>\"2c\", \"height\"=>\"5c\",\n\t\t\t  \"background\"=>$color)\n    @value = TkLabel.new(self, \n\t\t\t \"text\"=>$color,\n\t\t\t \"width\"=>\"13\",\n\t\t\t \"font\"=>\"-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*\")\n    @swatch.pack(\"side\"=>\"top\",\"expand\"=>\"yes\",\"fill\"=>\"both\")\n    @value.pack(\"side\"=>\"bottom\",\"pady\"=>\".25c\")\n\n    self\n  end\n\n  def set_color(color)\n    @swatch[\"background\"] = color\n    @value[\"text\"] = color\n  end\nend\n\n\n\n# middle level frame\nclass TkColorMiddleFrame<TkFrame\n  attr_reader :left, :middle, :right\n\n  def initialize(parent)\n    super(parent,\n\t  \"relief\"=> \"raised\",\n\t  \"borderwidth\"=> \"2\")\n\n    @left = TkColorMiddleLeftFrame.new(self)\n    @left.pack(\"side\"=>\"left\",\"padx\"=>\".25c\",\"pady\"=>\".25c\")\n\n    @middle = TkColorMiddleMiddleFrame.new(self)\n    @middle.pack(\"side\"=>\"left\",\"expand\"=>\"yes\",\"fill\"=>\"y\")\n\n    @right = TkColorMiddleRightFrame.new(self)\n    @right.pack(\"side\"=>\"left\",\"padx\"=>\".25c\",\"pady\"=>\".25c\",\"anchor\"=>\"s\")\n\n    self\n  end\nend\n\n\nclass TkColor<TkRoot\n  attr_reader :menu, :bottom, :middle\n\n  def initialize(*args)\n    super(*args)\n    @menu = TkColorMenuFrame.new(self)\n    @menu.pack(\"side\"=>\"top\", \"fill\"=>\"x\")\n\n    @bottom = TkColorBotFrame.new(self)\n    @bottom.pack(\"side\"=>\"bottom\",\"fill\"=>\"x\")\n\n    @middle = TkColorMiddleFrame.new(self)\n    @middle.pack(\"side\"=>\"top\",\"fill\"=>\"both\")\n\n    self\n  end\nend\n\n\n$root = TkColor.new\nchangeColorSpace :rgb\n\n# start eventloop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/text.rb",
    "content": "# text.rb\n#\n# This demonstration script creates a text widget that describes\n# the basic editing functions.\n#\n# text (basic facilities) widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($text_demo) && $text_demo\n  $text_demo.destroy \n  $text_demo = nil\nend\n\n# demo toplevel widget\n$text_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Basic Facilities\")\n  iconname(\"text\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($text_demo).pack(:fill=>:both, :expand=>true)\n\n# version check\nif ((Tk::TK_VERSION.split('.').collect{|n| n.to_i} <=> [8,4]) < 0)\n  undo_support = false\nelse\n  undo_support = true\nend\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $text_demo\n      $text_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'text'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# text \nTkText.new(base_frame){|t|\n  relief 'sunken'\n  bd 2\n  setgrid 1\n  height 30\n  if undo_support\n    undo true\n    autoseparators true\n  end\n  TkScrollbar.new(base_frame) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    command proc{|*args| t.yview(*args)}\n    t.yscrollcommand proc{|first,last| s.set first,last}\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n\n  # \n  insert('0.0', <<EOT)\nThis window is a text widget.  It displays one or more lines of text\nand allows you to edit the text.  Here is a summary of the things you\ncan do to a text widget:\n\n1. Scrolling. Use the scrollbar to adjust the view in the text window.\n\n2. Scanning. Press mouse button 2 in the text window and drag up or down.\nThis will drag the text at high speed to allow you to scan its contents.\n\n3. Insert text. Press mouse button 1 to set the insertion cursor, then\ntype text.  What you type will be added to the widget.\n\n4. Select. Press mouse button 1 and drag to select a range of characters.\nOnce you've released the button, you can adjust the selection by pressing\nbutton 1 with the shift key down.  This will reset the end of the\nselection nearest the mouse cursor and you can drag that end of the\nselection by dragging the mouse before releasing the mouse button.\nYou can double-click to select whole words or triple-click to select\nwhole lines.\n\n5. Delete and replace. To delete text, select the characters you'd like\nto delete and type Backspace or Delete.  Alternatively, you can type new\ntext, in which case it will replace the selected text.\n\n6. Copy the selection. To copy the selection into this window, select\nwhat you want to copy (either here or in another application), then\nclick button 2 to copy the selection to the point of the mouse cursor.\n\n7. Edit.  Text widgets support the standard Motif editing characters\nplus many Emacs editing characters.  Backspace and Control-h erase the\ncharacter to the left of the insertion cursor.  Delete and Control-d\nerase the character to the right of the insertion cursor.  Meta-backspace\ndeletes the word to the left of the insertion cursor, and Meta-d deletes\nthe word to the right of the insertion cursor.  Control-k deletes from\nthe insertion cursor to the end of the line, or it deletes the newline\ncharacter if that is the only thing left on the line.  Control-o opens\na new line by inserting a newline character to the right of the insertion\ncursor.  Control-t transposes the two characters on either side of the\ninsertion cursor. #{\n      if undo_support\n        undo_text = \"Control-z undoes the last editing action performed,\\nand \"\n        case $tk_platform['platform']\n        when \"unix\", \"macintosh\"\n          undo_text << \"Control-Shift-z\"\n        else # 'windows'\n          undo_text << \"Control-y\"\n        end\n        undo_text << \"redoes undone edits.\"\n      else\n        \"\"\n      end\n}\n\n7. Resize the window.  This widget has been configured with the \"setGrid\"\noption on, so that if you resize the window it will always resize to an\neven number of characters high and wide.  Also, if you make the window\nnarrow you can see that long lines automatically wrap around onto\nadditional lines so that all the information is always visible.\nEOT\n\n  set_insert('0.0')\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/textpeer.rb",
    "content": "#\n# text widget peering demo (called by 'widget')\n#\n# based on Tcl/Tk8.5.0 widget demos\n\nif defined?($textpeer_demo) && $textpeer_demo\n  $textpeer_demo.destroy \n  $textpeer_demo = nil\nend\n\n# demo toplevel widget\n$textpeer_demo = TkToplevel.new {|w|\n  title(\"Text Wdget Peering Demonstration\")\n  iconname(\"textpeer\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($textpeer_demo).pack(:fill=>:both, :expand=>true)\n\ncount = [0]\n\n## Define a widget that we peer from; it won't ever actually be shown though\nfirst = TkText.new(base_frame, :widgetname=>\"text#{count[0] += 1}\")\nfirst.insert :end,\"This is a coupled pair of text widgets; they are peers to \"\nfirst.insert :end,\"each other. They have the same underlying data model, but \"\nfirst.insert :end,\"can show different locations, have different current edit \"\nfirst.insert :end,\"locations, and have different selections. You can also \"\nfirst.insert :end,\"create additional peers of any of these text widgets using \"\nfirst.insert :end,\"the Make Peer button beside the text widget to clone, and \"\nfirst.insert :end,\"delete a particular peer widget using the Delete Peer \"\nfirst.insert :end,\"button.\"\n\nTk.update_idletasks  ## for 'first' widget\n\n## Procedures to make and kill clones; most of this is just so that the demo\n## looks nice...\ndef makeClone(count, win, txt)\n  cnt = (count[0] += 1)\n  peer = TkText::Peer.new(txt, win, :widgetname=>\"text#{cnt}\")\n  sbar = TkScrollbar.new(win, :widgetname=>\"sb#{cnt}\")\n  peer.yscrollbar sbar\n  b1 = TkButton.new(win, :widgetname=>\"clone#{cnt}\", :text=>'Make Peer', \n                    :command=>proc{makeClone(count, win, peer)})\n  b2 = TkButton.new(win, :widgetname=>\"kill#{cnt}\", :text=>'Delete Peer', \n                    :command=>proc{killClone(win, cnt)})\n  row = cnt * 2\n  TkGrid.configure(peer, sbar, b1, :sticky=>'nsew', :row=>row)\n  TkGrid.configure('^',  '^',  b2, :sticky=>'nsew', :row=>(row+=1))\n  TkGrid.configure(b1,  b2, :sticky=>'new')\n  TkGrid.rowconfigure(win,  b2, :weight=>1)\nend\n\ndef killClone(win, cnt)\n  Tk.destroy(\"#{win.path}.text#{cnt}\",  \"#{win.path}.sb#{cnt}\", \n             \"#{win.path}.clone#{cnt}\", \"#{win.path}.kill#{cnt}\")\nend\n\n## Now set up the GUI\nmakeClone(count, base_frame, first)\nmakeClone(count, base_frame, first)\nfirst.destroy\n\n## See Code / Dismiss buttons\nTkFrame.new(base_frame){|f|\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $textpeer_demo.destroy\n                 $textpeer_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'textpeer'\n               }).pack(:side=>:left, :expand=>true)\n\n  TkGrid.configure(f, '-', '-', :sticky=>'ew', :row=>5000)\n}\nTkGrid.columnconfigure(base_frame, 0, :weight=>1)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/timer",
    "content": "#!/usr/bin/env ruby\n#\n# timer --\n# This script generates a counter with start,stop and reset buttons.\n#\n# Copyright (C) 1998 Takaaki Tateishi (ttate@jaist.ac.jp)\n# last update: Sat Jun 27 12:24:14 JST 1998\n#\n\nrequire \"tk\"\nrequire \"thread\"\nrequire \"tkafter\"\n\n$time = \"0.00\"\n$m = Mutex.new\n$loop = false\n\ndef timer_stop\n  $loop = false\n  $m.lock\nend\n\ndef timer_start\n  $loop = true\n  $m.unlock\nend\n\ndef timer_reset\n  $time = \"0.00\"\n  $root.countframe.counter['text'] = $time\nend\n\ndef timer_loop\n  if $loop\n    $time = $time.succ\n    $root.countframe.counter['text'] = $time\n  end\n  Tk.after(10,proc{timer_loop})\nend\n\n\n#\n# thread version\n#\ndef timer_loop2\n  while true\n    $m.lock\n    $time = $time.succ\n    $root.countframe.counter['text'] = $time\n    sleep(0.01)\n    $m.unlock\n  end\nend\n\n#\n# TkAfter\n#\ndef timer_loop3\n  if $loop\n    $time = $time.succ\n    $root.countframe.counter['text'] = $time\n  end\nend\n\n\nclass CountFrame < TkFrame\n  attr_reader :counter\n\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n    @counter = TkLabel.new(self,\n\t\t\t   'text'=>$time, \n\t\t\t   'relief'=>'raised')\n    @counter.pack('fill'=>'both')\n    self\n  end\nend\n\n\nclass ButtonFrame < TkFrame\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n=begin\n    @stop = TkButton.new(self,\n\t\t\t 'text'=>'Stop',\n\t\t\t 'command'=>proc{timer_stop})\n    @start = TkButton.new(self,\n\t\t\t  'text'=>'Start',\n\t\t\t  'command'=>proc{timer_start})\n=end\n    @stop  = TkButton.new(self, :text=>'Stop',  :state=>:disabled)\n    @start = TkButton.new(self, :text=>'Start', :state=>:normal)\n\n    @stop.command proc{\n      timer_stop\n      @start.state(:normal)\n      @stop.state(:disabled)\n    }\n    @start.command proc{\n      timer_start\n      @stop.state(:normal)\n      @start.state(:disabled)\n    }\n\n    @reset = TkButton.new(self,\n\t\t\t  'text'=>'Reset',\n\t\t\t  'command'=>proc{timer_reset})\n    for b in [@stop,@start,@reset]\n      b.pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n    end\n  end\nend\n\n\nclass Timer < TkRoot\n  attr_reader :countframe\n\n  def initialize(*args)\n    super(*args)\n    @countframe = CountFrame.new(self)\n    @buttonframe = ButtonFrame.new(self)\n    for f in [@buttonframe,@countframe]\n      f.pack('side'=>'top', 'fill'=>'both')\n    end\n    self\n  end\nend\n\n\n$root = Timer.new\n\n#$thread = Thread.start{timer_loop2}\n#timer_loop\nTkAfter.new(10,-1,proc{timer_loop3}).start\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-en/tkencoding.rb",
    "content": "# -*- ruby -*-\n#\n# tkencoding.rb\n# written by ttate@jaist.ac.jp\n\nclass TclTkIp\n  alias __eval _eval\n  alias __invoke _invoke\n  private :__eval\n  private :__invoke\n\n  attr_accessor :encoding\n\n  def _eval(cmd)\n    if( @encoding )\n      _fromUTF8(__eval(_toUTF8(cmd,@encoding)),@encoding)\n    else\n      __eval(cmd)\n    end\n  end\n\n  def _invoke(*cmds)\n    if( @encoding )\n      cmds = cmds.collect{|cmd| _toUTF8(cmd,@encoding)}\n      _fromUTF8(__invoke(*cmds),@encoding)\n    else\n      __invoke(*cmds)\n    end\n  end\nend\n\nmodule Tk\n  INTERP = TkCore::INTERP\n\n  def encoding=(name)\n    INTERP.encoding = name\n  end\n\n  def encoding\n    INTERP.encoding\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/toolbar.rb",
    "content": "# toolbar.rb --\n#\n# This demonstration script creates a toolbar that can be torn off.\n#\n# based on \"Id: toolbar.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($toolbar_demo) && $toolbar_demo\n  $toolbar_demo.destroy \n  $toolbar_demo = nil\nend\n\n$toolbar_demo = TkToplevel.new {|w|\n  title(\"Ttk Menu Buttons\")\n  iconname(\"toolbar\")\n  positionWindow(w)\n}\n\nbase_frame = Ttk::Frame.new($toolbar_demo).pack(:fill=>:both, :expand=>true)\n\nif Tk.windowingsystem != 'aqua'\n  msg = Ttk::Label.new(base_frame, :wraplength=>'4i', \n                       :text=>Tk::UTF8_String.new(<<EOL))\nThis is a demonstration of how to do \\\na toolbar that is styled correctly \\\nand which can be torn off (this feature reqrires Tcl/Tk8.5). \\\nThe buttons are configured to be \\\\u201Ctoolbar style\\\\u201D buttons by \\\ntelling them that they are to use the Toolbutton style. At the left \\\nend of the toolbar is a simple marker that the cursor changes to a \\\nmovement icon over; drag that away from the toolbar to tear off the \\\nwhole toolbar into a separate toplevel widget. When the dragged-off \\\ntoolbar is no longer needed, just close it like any normal toplevel \\\nand it will reattach to the window it was torn off from.\nEOL\nelse\n  msg = Ttk::Label.new(base_frame, :wraplength=>'4i', \n                       :text=>Tk::UTF8_String.new(<<EOL))\nThis is a demonstration of how to do \\\na toolbar that is styled correctly. The buttons are configured to \\\nbe \\\\u201Ctoolbar style\\\\u201D buttons by telling them that they are \\\nto use the Toolbutton style.\nEOL\nend\n\n## Set up the toolbar hull\ntbar_base = Tk::Frame.new(base_frame, # Must be a starndard Tk frame!\n                          :widgetname=>'toolbar') # for window title\nsep = Ttk::Separator.new(base_frame)\nto_base = Ttk::Frame.new(tbar_base, :cursor=>'fleur')\nif Tk.windowingsystem != 'aqua'\n  to  = Ttk::Separator.new(to_base, :orient=>:vertical)\n  to2 = Ttk::Separator.new(to_base, :orient=>:vertical)\n  to.pack(:fill=>:y, :expand=>true, :padx=>2, :side=>:left)\n  to2.pack(:fill=>:y, :expand=>true, :side=>:left)\nend\n\ncontents = Ttk::Frame.new(tbar_base)\nTk.grid(to_base, contents, :sticky=>'nsew')\ntbar_base.grid_columnconfigure(contents, :weight=>1)\ncontents.grid_columnconfigure(1000, :weight=>1)\n\nif Tk.windowingsystem != 'aqua'\n  ## Bindings so that the toolbar can be torn off and reattached\n  to_base.bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)}\n  to.     bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)}\n  to2.    bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)}\n  def tbar_base.tearoff(w, x, y)\n    on_win = TkWinfo.containing(x, y)\n    return unless (on_win && on_win.path =~ /^#{@path}(\\.|$)/)\n    self.grid_remove\n    w.grid_remove\n    self.wm_manage\n    # self.wm_title('Toolbar') # if you don't want to use its widget name as a window title.\n    self.wm_protocol('WM_DELETE_WINDOW'){ self.untearoff(self) }\n  end\n  def tbar_base.untearoff(w)\n    self.wm_forget\n    w.grid\n    self.grid\n  end\nend\n\n## Some content for the rest of the toplevel\ntext = TkText.new(base_frame, :width=>40, :height=>10)\n\n## Toolbar contents\ntb_btn = Ttk::Button.new(tbar_base, :text=>'Button', :style=>'Toolbutton', \n                         :command=>proc{text.insert(:end, \"Button Pressed\\n\")})\ntb_chk = Ttk::Checkbutton.new(tbar_base, :text=>'Check', :style=>'Toolbutton', \n                              :variable=>(check = TkVariable.new), \n                              :command=>proc{\n                                text.insert(:end, \"Check is #{check.value}\\n\")\n                              })\ntb_mbtn = Ttk::Menubutton.new(tbar_base, :text=>'Menu')\ntb_combo = Ttk::Combobox.new(tbar_base, :value=>TkFont.families, \n                             :state=>:readonly)\ntb_mbtn.menu(menu = Tk::Menu.new(tb_mbtn))\nmenu.add(:command, :label=>'Just', :command=>proc{text.insert(:end, \"Just\\n\")})\nmenu.add(:command, :label=>'An', :command=>proc{text.insert(:end, \"An\\n\")})\nmenu.add(:command, :label=>'Example', \n         :command=>proc{text.insert(:end, \"Example\\n\")})\ntb_combo.bind('<ComboboxSelected>'){ text.font.family = tb_combo.get }\n\n## Arrange contents\nTk.grid(tb_btn, tb_chk, tb_mbtn, tb_combo, \n        :in=>contents, :padx=>2, :sticky=>'ns')\nTk.grid(tbar_base, :sticky=>'ew')\nTk.grid(sep, :sticky=>'ew')\nTk.grid(msg, :sticky=>'ew')\nTk.grid(text, :sticky=>'nsew')\nbase_frame.grid_rowconfigure(text, :weight=>1)\nbase_frame.grid_columnconfigure(text, :weight=>1)\n\n## See Code / Dismiss buttons\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'toolbar'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $toolbar_demo.destroy\n                           $toolbar_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  Tk.grid(frame, :sticky=>'ew')\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-en/tree.rb",
    "content": "# tree.rb --\n#\n# This demonstration script creates a toplevel window containing a Ttk\n# tree widget.\n#\n# based on \"Id: tree.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($tree_demo) && $tree_demo\n  $tree_demo.destroy \n  $tree_demo = nil\nend\n\n$tree_demo = TkToplevel.new {|w|\n  title(\"Directory Browser\")\n  iconname(\"tree\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($tree_demo).pack(:fill=>:both, :expand=>true)\n\n## Explanatory text\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', \n               :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], \n               :text=><<EOL).pack(:fill=>:x)\nTtk is the new Tk themed widget set. \\\nOne of the widgets it includes is a tree widget, \\\nwhich allows the user to browse a hierarchical data-set such as a filesystem. \\\nThe tree widget not only allows for the tree part itself, \\\nbut it also supports an arbitrary number of additional columns \\\nwhich can show additional data (in this case, the size of the files \\\nfound in your filesystem). \\\nYou can also change the width of the columns \\\nby dragging the boundary between them.\nEOL\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'tree'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $tree_demo.destroy\n                           $tree_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\n## Code to populate the roots of the tree (can be more than one on Windows)\ndef populate_roots(tree)\n  TkComm.simplelist(Tk.tk_call('file', 'volumes')).sort.each{|dir|\n    populate_tree(tree, tree.insert(nil, :end, :text=>dir, \n                                    :values=>[dir, 'directory']))\n  }\nend\n\n## Code to populate a node of the tree\ndef populate_tree(tree, node)\n  return if tree.get(node, :type) != 'directory'\n\n  path = tree.get(node, :fullpath)\n  tree.delete(tree.children(node))\n  Dir.glob(\"#{path}/*\").sort.each{|f|\n    type = File.ftype(f)\n    id = tree.insert(node, :end, \n                     :text=>File.basename(f), :values=>[f, type]).id\n    if type == 'directory'\n      ## Make it so that this node is openable\n      tree.insert(id, 0, :text=>'dummy')\n      tree.itemconfigure(id, :text=>File.basename(f))\n    elsif type == 'file'\n      size = File.size(f)\n      if size >= 1024*1024*1024\n        size = '%.1f GB' % (size.to_f/1024/1024/1024)\n      elsif size >= 1024*1024\n        size = '%.1f MB' % (size.to_f/1024/1024)\n      elsif size >= 1024\n        size = '%.1f KB' % (size.to_f/1024)\n      else\n        size = '%.1f bytes' % (size.to_f/1024)\n      end\n      tree.set(id, :size, size)\n    end\n  }\n\n  # Stop this code from rerunning on the current node\n  tree.set(node, :type, 'processed_directory')\nend\n\n## Create the tree and set it up\ntree = Ttk::Treeview.new(base_frame, :columns=>%w(fullpath type size), \n                         :displaycolumns=>['size'])\nif Tk.windowingsystem != 'aqua'\n  vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame))\nelse\n  vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame))\nend\n\ntree.heading_configure('#0', :text=>'Directory Structure')\ntree.heading_configure('size', :text=>'File Size')\ntree.column_configure('size', :stretch=>0, :width=>70)\npopulate_roots(tree)\ntree.bind('<TreeviewOpen>', '%W'){|w| populate_tree(w, w.focus_item)}\n\n## Arrange the tree and its scrollbars in the toplevel\ncontainer = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\ncontainer.lower\nTk.grid(tree, vsb, :in=>container, :sticky=>'nsew')\nTk.grid(hsb,       :in=>container, :sticky=>'nsew')\ncontainer.grid_columnconfigure(0, :weight=>1)\ncontainer.grid_rowconfigure(0, :weight=>1)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ttkbut.rb",
    "content": "# ttkbut.rb\n#\n# This demonstration script creates a toplevel window containing several\n# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and\n# radiobuttons.\n#\n# based on \"Id: ttkbut.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkbut_demo) && $ttkbut_demo\n  $ttkbut_demo.destroy \n  $ttkbut_demo = nil\nend\n\n$ttkbut_demo = TkToplevel.new {|w|\n  title(\"Simple Ttk Widgets\")\n  iconname(\"ttkbut\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ttkbut_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nTtk is the new Tk themed widget set. This is a Ttk themed label, \\\nand below are three groups of Ttk widgets in Ttk labelframes. \\\nThe first group are all buttons that set the current application theme \\\nwhen pressed. The second group contains three sets of checkbuttons, \\\nwith a separator widget between the sets. Note that the \"Enabled\" \\\nbutton controls whether all the other themed widgets in this toplevel are \\\nin the disabled state. The third group has a collection of linked \\\nradiobuttons.\nEOL\n\n## Add buttons for setting the theme\nbuttons = Ttk::Labelframe.new(base_frame, :text=>'Buttons')\n# Ttk::Style.theme_names.each{|theme|\n#   Ttk::Button.new(buttons, :text=>theme, \n#                   :command=>proc{Ttk::Style.theme_use theme}).pack(:pady=>2)\n# }\nTtk.themes.each{|theme|\n  Ttk::Button.new(buttons, :text=>theme, \n                  :command=>proc{Ttk.set_theme theme}).pack(:pady=>2)\n}\n\n## Helper procedure for the top checkbutton\ndef setState(root, value, *excepts)\n  return if excepts.member?(root)\n\n  ## Non-Ttk widgets (e.g. the toplevel) will fail, so make it silent\n  begin\n    root.state = value\n  rescue\n  end\n\n  ## Recursively invoke on all children of this root that are in the same\n  ## toplevel widget\n  root.winfo_children.each{|w|\n    setState(w, value, *excepts) if w.winfo_toplevel == root.winfo_toplevel\n  }\nend\n\n## Set up the checkbutton group\nchecks = Ttk::Labelframe.new(base_frame, :text=>'Checkbuttons')\nenabled = TkVariable.new(true)\ne = Ttk::Checkbutton.new(checks, :text=>'Enabled', :variable=>enabled, \n                         :command=>proc{\n                           setState($ttkbut_demo, \n                                    ((enabled.bool)? \"!disabled\" : \"disabled\"),\n                                    e)\n                         })\n\n## See ttk_widget(n) for other possible state flags\nsep1 = Ttk::Separator.new(checks)\nsep2 = Ttk::Separator.new(checks)\n\ncheese  = TkVariable.new\ntomato  = TkVariable.new\nbasil   = TkVariable.new\noregano = TkVariable.new\n\nc1 = Ttk::Checkbutton.new(checks, :text=>'Cheese',  :variable=>cheese)\nc2 = Ttk::Checkbutton.new(checks, :text=>'Tomato',  :variable=>tomato)\nc3 = Ttk::Checkbutton.new(checks, :text=>'Basil',   :variable=>basil)\nc4 = Ttk::Checkbutton.new(checks, :text=>'Oregano', :variable=>oregano)\n\nTk.pack(e, sep1, c1, c2, sep2, c3, c4, :fill=>:x, :pady=>2)\n\n## Set up the radiobutton group\nradios = Ttk::Labelframe.new(base_frame, :text=>'Radiobuttons')\n\nhappyness = TkVariable.new\n\nr1 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Great', :value=>'great')\nr2 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Good', :value=>'good')\nr3 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Ok', :value=>'ok')\nr4 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Poor', :value=>'poor')\nr5 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Awful', :value=>'awful')\n\nTk.pack(r1, r2, r3, r4, r5, :fill=>:x, :padx=>3, :pady=>2)\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Variables', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{\n                           showVars(base_frame, ['enabled', enabled], \n                                    ['cheese', cheese], ['tomato', tomato], \n                                    ['basil', basil], ['oregano', oregano], \n                                    ['happyness', happyness])\n                         }), \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkbut'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           tmppath = $ttkbut_demo\n                           $ttkbut_demo = nil\n                           $showVarsWin[tmppath.path] = nil\n                           tmppath.destroy\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x, :expand=>true)\n}\n\n## Arrange things neatly\nf = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\nf.lower\nTk.grid(buttons, checks, radios, :in=>f, :sticky=>'nwe', :pady=>2, :padx=>3)\nf.grid_columnconfigure([0, 1, 2], :weight=>1, :uniform=>:yes)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ttkmenu.rb",
    "content": "# ttkmenu.rb --\n#\n# This demonstration script creates a toplevel window containing several Ttk\n# menubutton widgets.\n#\n# based on \"Id: ttkmenu.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkmenu_demo) && $ttkmenu_demo\n  $ttkmenu_demo.destroy \n  $ttkmenu_demo = nil\nend\n\n$ttkmenu_demo = TkToplevel.new {|w|\n  title(\"Ttk Menu Buttons\")\n  iconname(\"ttkmenu\")\n  positionWindow(w)\n}\n\nbase_frame = Ttk::Frame.new($ttkmenu_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nTtk is the new Tk themed widget set, \\\nand one widget that is available in themed form is the menubutton. \\\nBelow are some themed menu buttons \\\nthat allow you to pick the current theme in use. \\\nNotice how picking a theme changes the way \\\nthat the menu buttons themselves look, \\\nand that the central menu button is styled differently \\\n(in a way that is normally suitable for toolbars). \\\nHowever, there are no themed menus; the standard Tk menus were judged \\\nto have a sufficiently good look-and-feel on all platforms, \\\nespecially as they are implemented as native controls in many places.\nEOL\n\nTtk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x)\n\n## See Code / Dismiss\nTtk::Frame.new($ttkmenu_demo) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkmenu'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttkmenu_demo.destroy\n                           $ttkmenu_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nb1 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:above)\nb2 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:left)\nb3 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:right)\nb4 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:flush,\n                         :style=>Ttk::Menubutton.style('Toolbutton'))\nb5 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:below)\n\nb1.menu(m1 = Tk::Menu.new(b1, :tearoff=>false))\nb2.menu(m2 = Tk::Menu.new(b2, :tearoff=>false))\nb3.menu(m3 = Tk::Menu.new(b3, :tearoff=>false))\nb4.menu(m4 = Tk::Menu.new(b4, :tearoff=>false))\nb5.menu(m5 = Tk::Menu.new(b5, :tearoff=>false))\n\nTtk.themes.each{|theme|\n  m1.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m2.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m3.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m4.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m5.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n}\n\nf = Ttk::Frame.new(base_frame).pack(:fill=>:x)\nf1 = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\nf.lower\n\nf.grid_anchor(:center)\nTkGrid('x', b1, 'x', :in=>f, :padx=>3, :pady=>2)\nTkGrid(b2,  b4, b3,  :in=>f, :padx=>3, :pady=>2)\nTkGrid('x', b5, 'x', :in=>f, :padx=>3, :pady=>2)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ttknote.rb",
    "content": "# ttknote.rb --\n#\n# This demonstration script creates a toplevel window containing a Ttk\n# notebook widget.\n#\n# based on \"Id: ttknote.tcl,v 1.5 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttknote_demo) && $ttknote_demo\n  $ttknote_demo.destroy \n  $ttknote_demo = nil\nend\n\n$ttknote_demo = TkToplevel.new {|w|\n  title(\"Ttk Notebook Widget\")\n  iconname(\"ttknote\")\n  positionWindow(w)\n}\n\n## See Code / Dismiss\nTtk::Frame.new($ttknote_demo) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttknote'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttknote_demo.destroy\n                           $ttknote_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nbase_frame = Ttk::Frame.new($ttknote_demo).pack(:fill=>:both, :expand=>true)\n\n## Make the notebook and set up Ctrl+Tab traversal\nnotebook = Ttk::Notebook.new(base_frame).pack(:fill=>:both, :expand=>true, \n                                              :padx=>2, :pady=>3)\nnotebook.enable_traversal\n\n## Popuplate the first pane\nf_msg = Ttk::Frame.new(notebook)\nmsg_m = Ttk::Label.new(f_msg, :font=>$font, :wraplength=>'4i', \n                       :justify=>:left, :anchor=>'n', :text=><<EOL)\nTtk is the new Tk themed widget set. \\\nOne of the widgets it includes is the notebook widget, \\\nwhich provides a set of tabs that allow the selection of a group of panels, \\\neach with distinct content. \\\nThey are a feature of many modern user interfaces. \\\nNot only can the tabs be selected with the mouse, \\\nbut they can also be switched between using Ctrl+Tab \\\nwhen the notebook page heading itself is selected. \\\nNote that the second tab is disabled, and cannot be selected.\nEOL\nneat = TkVariable.new\nafter_id = nil\nmsg_b = Ttk::Button.new(f_msg, :text=>'Neat!', :underline=>0, \n                        :command=>proc{\n                          neat.value = 'Yeah, I know...'\n                          Tk.after_cancel(after_id) if after_id\n                          after_id = Tk.after(500){neat.value = ''}\n                        })\nmsg_b.winfo_toplevel.bind('Alt-n'){ msg_b.focus; msg_b.invoke }\nmsg_l = Ttk::Label.new(f_msg, :textvariable=>neat)\nnotebook.add(f_msg, :text=>'Description', :underline=>0, :padding=>2)\nTk.grid(msg_m, '-', :sticky=>'new', :pady=>2)\nTk.grid(msg_b, msg_l, :pady=>[2, 4])\nf_msg.grid_rowconfigure(1, :weight=>1)\nf_msg.grid_columnconfigure([0, 1], :weight=>1, :uniform=>1)\n\n## Populate the second pane. Note that the content doesn't really matter\nf_disabled = Ttk::Frame.new(notebook)\nnotebook.add(f_disabled, :text=>'Disabled', :state=>:disabled)\n\n## Popuplate the third pane\nf_editor = Ttk::Frame.new(notebook)\nnotebook.add(f_editor, :text=>'Text Editor', :underline=>0)\neditor_t = Tk::Text.new(f_editor, :width=>40, :height=>10, :wrap=>:char)\nif Tk.windowingsystem != 'aqua'\n  editor_s = editor_t.yscrollbar(Ttk::Scrollbar.new(f_editor))\nelse\n  editor_s = editor_t.yscrollbar(Tk::Scrollbar.new(f_editor))\nend\neditor_s.pack(:side=>:right, :fill=>:y, :padx=>[0,2], :pady=>2)\neditor_t.pack(:fill=>:both, :expand=>true, :padx=>[2,0], :pady=>2)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ttkpane.rb",
    "content": "# ttkpane.rb --\n#\n# This demonstration script creates a Ttk pane with some content.\n#\n# based on \"Id: ttkpane.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkpane_demo) && $ttkpane_demo\n  $ttkpane_demo.destroy \n  $ttkpane_demo = nil\nend\n\n$ttkpane_demo = TkToplevel.new {|w|\n  title(\"Themed Nested Panes\")\n  iconname(\"ttkpane\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ttkpane_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nThis demonstration shows off a nested set of themed paned windows. \\\nTheir sizes can be changed by grabbing the area \\\nbetween each contained pane and dragging the divider.\nEOL\n\nTtk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x)\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkpane'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttkpane_demo.destroy\n                           $ttkpane_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nframe = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\nouter = Ttk::Panedwindow.new(frame, :orient=>:horizontal)\nouter.add(in_left = Ttk::Panedwindow.new(outer, :orient=>:vertical))\nouter.add(in_right = Ttk::Panedwindow.new(outer, :orient=>:vertical))\nin_left.add(left_top = Ttk::Labelframe.new(in_left, :text=>'Button'))\nin_left.add(left_bot = Ttk::Labelframe.new(in_left, :text=>'Clocks'))\nin_right.add(right_top = Ttk::Labelframe.new(in_right, :text=>'Progress'))\nin_right.add(right_bot = Ttk::Labelframe.new(in_right, :text=>'Text'))\nif Tk.windowingsystem == 'aqua'\n  [left_top, left_bot, right_top, right_bot].each{|w| w.padding(3) }\nend\n\n# Fill the button pane\nTtk::Button.new(left_top, :text=>'Press Me', \n                :command=>proc{\n                  Tk.messageBox(:type=>'ok', :icon=>'info', :message=>'Ouch!', \n                                :detail=>'That hurt...', :parent=>base_frame, \n                                :title=>'Button Pressed')\n                }).pack(:padx=>2, :pady=>5)\n\n\nzones_list = [\n  [':Europe/Berlin'], \n  [':America/Argentina/Buenos_Aires', ':America/Buenos_Aires'], \n  [':Africa/Johannesburg'], \n  [':Europe/London'], \n  [':America/Los_Angeles'], \n  [':Europe/Moscow'],\n  [':America/New_York'], \n  [':Asia/Singapore'], \n  [':Australia/Sydney'], \n  [':Asia/Tokyo'], \n]\n\nzones = []\n\n# Check tzinfo support\nif $tk_major_ver > 8 || ($tk_major_ver == 8 && $tk_minor_ver >= 5)\n  tzinfo = :tcl\n\n  # Force a pre-load of all the timezones needed; otherwise can end up\n  # poor-looking synch problems!\n  zones_list.each{|list|\n    list.each{|zone|\n      begin\n        Tk.tk_call('clock', 'format', '0', '-timezone', zone)\n      rescue RuntimeError\n        # ignore\n      else\n        zones << [zone, zone[%r<[^/:]+$>].tr('_', ' ')]\n        break\n      end\n    }\n  }\n\nelse\n  begin\n    require 'tzinfo'\n    tzinfo = :tzinfo\n  rescue Exception\n    begin\n      require 'tzfile'\n      tzinfo = :tzfile\n    rescue Exception\n      tzinfo = nil\n    end\n  end\n\n  case tzinfo\n  when :tzinfo\n    zones_list.each{|list|\n      list.each{|zone|\n        begin\n          tz = TZInfo::Timezone.get(zone[%r<[^:]+$>])\n        rescue Exception\n          # ignore\n        else\n          zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')]\n          break\n        end\n      }\n    }\n\n  when :tzfile\n    zones_list.each{|list|\n      list.each{|zone|\n        begin\n          tz = TZFile.create(zone[%r<[^:]+$>])\n        rescue Exception\n          # ignore\n        else\n          zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')]\n          break\n        end\n      }\n    }\n\n  else\n    [ -7, -4, -2, -1, 0, +1, +3, +8, +9, +10 ].each{|zone|\n      zones << [zone, 'UTC%+03d00' % zone]\n    }\n  end\nend\n\ntime = TkVariable.new_hash\n\ncase tzinfo\nwhen :tcl\n  update_proc = proc{|now, tz, label|\n    time[label] = Tk.tk_call('clock', 'format', now.tv_sec, \n                             '-timezone', tz, '-format', '%T')\n  }\nwhen :tzinfo\n  update_proc = proc{|now, tz, label|\n    time[label] = tz.utc_to_local(now).strftime('%H:%M:%S')\n  }\nwhen :tzfile\n  update_proc = proc{|now, tz, label|\n    time[label] = tz.at(now.tv_sec).strftime('%H:%M:%S')\n  }\nelse\n  update_proc = proc{|now, tz, label|\n    time[label] = (now + (tz * 3600)).strftime('%H:%M:%S')\n  }\nend\n\n# Fill the clocks pane\nzones.each_with_index{|(zone, label), idx|\n  Ttk::Separator.new(left_bot).pack(:fill=>:x) if idx > 0\n  Ttk::Label.new(left_bot, :text=>label, :anchor=>'w').pack(:fill=>:x)\n  Ttk::Label.new(left_bot, :textvariable=>time.ref(label), \n                 :anchor=>'w').pack(:fill=>:x)\n}\n\n# Timer start\nevery = proc{\n  now = Time.now.utc\n  zones.each{|zone, label| update_proc.call(now, zone, label) }\n}\nTkRTTimer.new(1000, -1, every).start(0, every)\n\n# Fill the progress pane\nTtk::Progressbar.new(right_top, :mode=>:indeterminate).pack(:fill=>:both, :expand=>true).start\n\n# Fill the text pane\nif Tk.windowingsystem != 'aqua'\n  # The trick with the ttk::frame makes the text widget look like it fits with\n  # the current Ttk theme despite not being a themed widget itself. It is done\n  # by styling the frame like an entry, turning off the border in the text\n  # widget, and putting the text widget in the frame with enough space to allow\n  # the surrounding border to show through (2 pixels seems to be enough).\n  f = Ttk::Frame.new(right_bot, :style=>Ttk::Entry)\n  txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0)\n  txt.pack(:fill=>:both, :expand=>true, :in=>f, :pady=>2, :padx=>2)\n  scr = txt.yscrollbar(Ttk::Scrollbar.new(frame))\n  scr.pack(:side=>:right, :fill=>:y, :in=>right_bot)\n  f.pack(:fill=>:both, :expand=>true)\n  outer.pack(:fill=>:both, :expand=>true)\nelse\n  txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0)\n  scr = txt.yscrollbar(TkScrollbar.new(frame))\n  scr.pack(:side=>:right, :fill=>:y, :in=>right_bot)\n  txt.pack(:fill=>:both, :expand=>true, :in=>right_bot)\n  outer.pack(:fill=>:both, :expand=>true, :padx=>10, :pady=>[6, 10])\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/ttkprogress.rb",
    "content": "# ttkprogress.rb --\n#\n# This demonstration script creates several progress bar widgets.\n#\n# based on \"Id: ttkprogress.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkprogress_demo) && $ttkprogress_demo\n  $ttkprogress_demo.destroy \n  $ttkprogress_demo = nil\nend\n\n$ttkprogress_demo = TkToplevel.new {|w|\n  title(\"Progress Bar Demonstration\")\n  iconname(\"ttkprogress\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ttkprogress_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=>Tk::UTF8_String.new(<<EOL)).pack(:side=>:top, :fill=>:x)\nBelow are two progress bars. \\\nThe top one is a \\\\u201Cdeterminate\\\\u201D progress bar, \\\nwhich is used for showing how far through a defined task the program has got. \\\nThe bottom one is an \\\\u201Cindeterminate\\\\u201D progress bar, \\\nwhich is used to show that the program is busy \\\nbut does not know how long for. Both are run here in self-animated mode, \\\nwhich can be turned on and off using the buttons underneath.\nEOL\n\n## See Code / Dismiss buttons\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'See Code', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkprogress'}), \n         Ttk::Button.new(frame, :text=>'Dismiss', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttkprogress_demo.destroy\n                           $ttkprogress_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nframe = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\np1 = Ttk::Progressbar.new(frame, :mode=>:determinate)\np2 = Ttk::Progressbar.new(frame, :mode=>:indeterminate)\n\nstart = Ttk::Button.new(frame, :text=>'Start Progress', \n                        :command=>proc{ p1.start; p2.start })\nstop  = Ttk::Button.new(frame, :text=>'Stop Progress', \n                        :command=>proc{ p1.stop; p2.stop })\n\nTk.grid(p1, '-', :pady=>5, :padx=>10)\nTk.grid(p2, '-', :pady=>5, :padx=>10)\nTk.grid(start, stop, :padx=>10, :pady=>5)\nstart.grid_configure(:sticky=>'e')\nstop.grid_configure(:sticky=>'w')\nframe.grid_columnconfigure(:all, :weight=>1)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-en/twind.rb",
    "content": "# twind.rb\n#\n# This demonstration script creates a text widget with a bunch of\n# embedded windows.\n#\n# text (embedded windows) widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($twind_demo) && $twind_demo\n  $twind_demo.destroy \n  $twind_demo = nil\nend\n\n# demo toplevel widget\n$twind_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Embedded Windows\")\n  iconname(\"Embedded Windows\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($twind_demo).pack(:fill=>:both, :expand=>true)\n\n# frame\n$twind_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc{\n      tmppath = $twind_demo\n      $twind_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc{showCode 'twind'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$twind_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\n$twind_text = nil\nTkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, \n            'relief'=>'sunken') {|f|\n  $twind_text = TkText.new(f, 'setgrid'=>'true', 'font'=>$font, \n                          'width'=>'70', 'height'=>35, 'wrap'=>'word', \n                          'highlightthickness'=>0, 'borderwidth'=>0 ){|t|\n    TkScrollbar.new(f) {|s|\n      command proc{|*args| t.yview(*args)}\n      t.yscrollcommand proc{|first,last| s.set first,last}\n    }.pack('side'=>'right', 'fill'=>'y')\n  }.pack('expand'=>'yes', 'fill'=>'both')\n}.pack('expand'=>'yes', 'fill'=>'both')\n\n# \n$tag_center = TkTextTag.new($twind_text, \n                            'justify' =>'center',\n                            'spacing1'=>'5m',\n                            'spacing3'=>'5m'  )\n$tag_buttons = TkTextTag.new($twind_text, \n                             'lmargin1'=>'1c',\n                             'lmargin2'=>'1c',\n                             'rmargin' =>'1c',\n                             'spacing1'=>'3m',\n                             'spacing2'=>0,\n                             'spacing3'=>0 )\n\n$twind_text.insert('end', \"A text widget can contain other widgets embedded \")\n$twind_text.insert('end', \"it.  These are called \\\"embedded windows\\\", \")\n$twind_text.insert('end', \"and they can consist of arbitrary widgets.  \")\n$twind_text.insert('end', \"For example, here are two embedded button \")\n$twind_text.insert('end', \"widgets.  You can click on the first button to \")\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   #text 'ON'\n                   text 'Turn On'\n                   command proc{textWindOn $twind_text,$twind_buttons}\n                   cursor 'top_left_arrow'\n                 })\n$twind_text.insert('end', \" horizontal scrolling, which also turns off \")\n$twind_text.insert('end', \"word wrapping.  Or, you can click on the second \")\n$twind_text.insert('end', \"button to\\n\")\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   #text 'OFF'\n                   text 'Turn Off'\n                   command proc{textWindOff $twind_text}\n                   cursor 'top_left_arrow'\n                 })\n\n$twind_text.insert('end', \" horizontal scrolling and turn back on word wrapping.\\n\\n\")\n$twind_text.insert('end', \"Or, here is another example.  If you \")\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   text 'Click Here'\n                   command proc{textWindPlot $twind_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind_text.insert('end', \" a canvas displaying an x-y plot will appear right here.\")\n$mark_plot = TkTextMark.new($twind_text, 'insert')\n$mark_plot.gravity='left'\n$twind_text.insert('end', \"  You can drag the data points around with the mouse, \")\n$twind_text.insert('end', \"or you can click here to \")\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   text 'Delete'\n                   command proc{textWindDel $twind_text}\n                   cursor 'top_left_arrow'\n                 })\n\n$twind_text.insert('end', \" the plot again.\\n\\n\")\n$twind_text.insert('end', \"You may also find it useful to put embedded windows in \")\n$twind_text.insert('end', \"a text without any actual text.  In this case the \")\n$twind_text.insert('end', \"text widget acts like a geometry manager.  For \")\n$twind_text.insert('end', \"example, here is a collection of buttons laid out \")\n$twind_text.insert('end', \"neatly into rows by the text widget.  These buttons \")\n$twind_text.insert('end', \"can be used to change the background color of the \")\n$twind_text.insert('end', \"text widget (\\\"Default\\\" restores the color to \")\n$twind_text.insert('end', \"its default).  If you click on the button labeled \")\n$twind_text.insert('end', \"\\\"Short\\\", it changes to a longer string so that \")\n$twind_text.insert('end', \"you can see how the text widget automatically \")\n$twind_text.insert('end', \"changes the layout.  Click on the button again \")\n$twind_text.insert('end', \"to restore the short string.\\n\")\n\n\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {|b|\n                   text 'Default'\n                   command proc{embDefBg $twind_text}\n                   cursor 'top_left_arrow'\n                   $tag_buttons.add('end')\n                 },\n                 'padx'=>3 )\nembToggle = TkVariable.new('Short')\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkCheckButton.new($twind_text) {\n                   textvariable embToggle\n                   indicatoron 0\n                   variable embToggle\n                   onvalue 'A much longer string'\n                   offvalue 'Short'\n                   cursor 'top_left_arrow'\n                   pady 5\n                   padx 2\n                 },\n                 'padx'=>3, \n                 'pady'=>2 )\n\n[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4', \n  'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1', \n  'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1', \n  'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4' \n].each{|twind_color|\n  TkTextWindow.new($twind_text, 'end', \n                   'window'=>TkButton.new($twind_text) {\n                     text twind_color\n                     cursor 'top_left_arrow'\n                     command proc{$twind_text.bg twind_color}\n                   },\n                   'padx'=>3, \n                   'pady'=>2 )\n}\n\n# \ndef textWindOn (w,f)\n  if defined? $twind_scroll\n    begin\n      $twind_scroll.destroy\n    rescue\n    end\n    $twind_scroll = nil\n  end\n\n  base = TkWinfo.parent( TkWinfo.parent(w) )\n  $twind_scroll = TkScrollbar.new(base) {|s|\n    orient 'horizontal'\n    command proc{|*args| w.xview(*args)}\n    w.xscrollcommand proc{|first,last| s.set first,last}\n    w.wrap 'none'\n    pack('after'=>f, 'side'=>'bottom', 'fill'=>'x')\n  }\n\n  return nil\nend\n\ndef textWindOff (w)\n  if defined? $twind_scroll\n    begin\n      $twind_scroll.destroy\n    rescue\n    end\n    $twind_scroll = nil\n  end\n  w.xscrollcommand ''\n  w.wrap 'word'\nend\n\ndef textWindPlot (t)\n  if (defined? $twind_plot) && TkWinfo.exist?($twind_plot)\n    return\n  end\n\n  $twind_plot = TkCanvas.new(t) {\n    relief 'sunken'\n    width  450\n    height 300\n    cursor 'top_left_arrow'\n  }\n\n  if $tk_version =~ /^4.*/\n    font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'\n  else\n    font = 'Helvetica 18'\n  end\n\n  TkcLine.new($twind_plot, 100, 250, 400, 250, 'width'=>2)\n  TkcLine.new($twind_plot, 100, 250, 100,  50, 'width'=>2)\n  TkcText.new($twind_plot, 225, 20, \n              'text'=>\"A Simple Plot\", 'font'=>font, 'fill'=>'brown')\n\n  (0..10).each {|i|\n    x = 100 + (i * 30)\n    TkcLine.new($twind_plot, x, 250, x, 245, 'width'=>2)\n    TkcText.new($twind_plot, x, 254, \n                'text'=>10*i, 'font'=>font, 'anchor'=>'n')\n  }\n  (0..5).each {|i|\n    y = 250 - (i * 40)\n    TkcLine.new($twind_plot, 100, y, 105, y, 'width'=>2)\n    TkcText.new($twind_plot, 96, y, \n                'text'=>\"#{i*50}.0\", 'font'=>font, 'anchor'=>'e')\n  }\n\n  for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]\n    x = 100 + (3*xx)\n    y = 250 - (4*yy)/5\n    item = TkcOval.new($twind_plot, x-6, y-6, x+6, y+6, \n                       'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')\n    item.addtag 'point'\n  end\n\n  $twind_plot.itembind('point', 'Any-Enter', \n                        proc{$twind_plot.itemconfigure 'current', 'fill', 'red'})\n  $twind_plot.itembind('point', 'Any-Leave', \n                        proc{$twind_plot.itemconfigure 'current', 'fill', 'SkyBlue2'})\n  $twind_plot.itembind('point', '1', \n                        proc{|x,y| embPlotDown $twind_plot,x,y}, \"%x %y\")\n  $twind_plot.itembind('point', 'ButtonRelease-1', \n                        proc{$twind_plot.dtag 'selected'})\n  $twind_plot.bind('B1-Motion', \n                    proc{|x,y| embPlotMove $twind_plot,x,y}, \"%x %y\")\n  while ($twind_text.get($mark_plot) =~ /[ \\t\\n]/)\n    $twind_text.delete $mark_plot\n  end\n  $twind_text.insert $mark_plot,\"\\n\"\n  TkTextWindow.new($twind_text, $mark_plot, 'window'=>$twind_plot)\n  $tag_center.add $mark_plot\n  $twind_text.insert $mark_plot,\"\\n\"\nend\n\n$embPlot = {'lastX'=>0, 'lastY'=>0}\n\ndef embPlotDown (w, x, y)\n  w.dtag 'selected'\n  w.addtag_withtag 'selected', 'current'\n  w.raise 'current'\n  $embPlot['lastX'] = x\n  $embPlot['lastY'] = y\nend\n\ndef embPlotMove (w, x, y)\n  w.move 'selected', x - $embPlot['lastX'], y - $embPlot['lastY']\n  $embPlot['lastX'] = x\n  $embPlot['lastY'] = y\nend\n\ndef textWindDel (w)\n  if (defined? $twind_text) && TkWinfo.exist?($twind_plot)\n    $twind_text.delete $twind_plot\n    $twind_plot = nil\n    while ($twind_text.get($mark_plot) =~ /[ \\t\\n]/)\n      $twind_text.delete $mark_plot\n    end\n    $twind_text.insert $mark_plot,\"  \"\n  end\nend\n\ndef embDefBg (w)\n  w['background'] = w.configinfo('background')[3]\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/twind2.rb",
    "content": "#\n# text (embedded windows) widget demo 2 (called by 'widget')\n#\n\n# delete toplevel widget\nif defined?($twind2_demo) && $twind2_demo\n  $twind2_demo.destroy \n  $twind2_demo = nil\nend\n\n# demo toplevel widget\n$twind2_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Embedded Windows 2\")\n  iconname(\"Embedded Windows\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($twind2_demo).pack(:fill=>:both, :expand=>true)\n\n# frame\n$twind2_buttons = TkFrame.new(base_frame) {|frame|\n  TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), \n         :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         TkButton.new(frame, :text=>'See Code', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{showCode 'twind2'}), \n         TkButton.new(frame, :text=>'Dismiss', \n                      :image=>$image['delete'], :compound=>:left, \n                      :command=>proc{\n                        tmppath = $twind2_demo\n                        $twind2_demo = nil\n                        $showVarsWin[tmppath.path] = nil\n                        tmppath.destroy\n                      }), \n         :padx=>4, :pady=>4)\n  frame.grid_columnconfigure(0, :weight=>1)\n}\n$twind2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame\n$twind2_text = nil\nTkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, \n            'relief'=>'sunken') {|f|\n  $twind2_text = TkText.new(f, 'setgrid'=>true, 'font'=>$font,\n                            # 'width'=>'70', 'height'=>35, 'wrap'=>'word', \n                            'width'=>'70', 'height'=>35, 'wrap'=>'char', \n                            'highlightthickness'=>0, 'borderwidth'=>0 ){|t|\n    TkScrollbar.new(f) {|s|\n      command proc{|*args| t.yview(*args)}\n      t.yscrollcommand proc{|first,last| s.set first,last}\n    }.pack('side'=>'right', 'fill'=>'y')\n  }.pack('expand'=>'yes', 'fill'=>'both')\n}.pack('expand'=>'yes', 'fill'=>'both')\n\n# text tags\n$tag2_center = TkTextTag.new($twind2_text, \n                            'justify' =>'center',\n                            'spacing1'=>'5m',\n                            'spacing3'=>'5m'  )\n$tag2_buttons = TkTextTag.new($twind2_text, \n                             'lmargin1'=>'1c',\n                             'lmargin2'=>'1c',\n                             'rmargin' =>'1c',\n                             'spacing1'=>'3m',\n                             'spacing2'=>0,\n                             'spacing3'=>0 )\n\n# insert text\n$twind2_text.insert('end', \n                  'A text widget can contain many different kinds of items, ')\n$twind2_text.insert('end',\n                  \"both active and passive.  It can lay these out in various \")\n$twind2_text.insert('end',\n                   \"ways, with wrapping, tabs, centering, etc.  In addition, \")\n$twind2_text.insert('end',\n                    \"when the contents are too big for the window, smooth \")\n$twind2_text.insert('end', \"scrolling in all directions is provided.\\n\\n\")\n\n$twind2_text.insert('end', \"A text widget can contain other widgets embedded \")\n$twind2_text.insert('end', \"it.  These are called \\\"embedded windows\\\", \")\n$twind2_text.insert('end', \"and they can consist of arbitrary widgets.  \")\n$twind2_text.insert('end', \"For example, here are two embedded button \")\n$twind2_text.insert('end', \"widgets.  You can click on the first button to \")\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   text 'ON'\n                   command proc{textWindOn2 $twind2_text,$twind2_buttons}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', \" horizontal scrolling, which also turns off \")\n$twind2_text.insert('end', \"word wrapping.  Or, you can click on the second \")\n$twind2_text.insert('end', \"button to\\n\")\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   text 'OFF'\n                   command proc{textWindOff2 $twind2_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', \n                   \" horizontal scrolling and turn back on word wrapping.\\n\\n\")\n\n$twind2_text.insert('end', \"Or, here is another example.  If you \")\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   text 'Click Here'\n                   command proc{textWindPlot2 $twind2_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', \n                    \" a canvas displaying an x-y plot will appear right here.\")\n$mark2_plot = TkTextMark.new($twind2_text, 'insert')\n$mark2_plot.gravity='left'\n$twind2_text.insert('end', \n                    \"  You can drag the data points around with the mouse, \")\n$twind2_text.insert('end', \"or you can click here to \")\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   text 'Delete'\n                   command proc{textWindDel2 $twind2_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', \" the plot again.\\n\\n\")\n\n$twind2_text.insert('end', \n                    \"You may also find it useful to put embedded windows in \")\n$twind2_text.insert('end', \n                    \"a text without any actual text.  In this case the \")\n$twind2_text.insert('end', \"text widget acts like a geometry manager.  For \")\n$twind2_text.insert('end', \n                    \"example, here is a collection of buttons laid out \")\n$twind2_text.insert('end', \n                    \"neatly into rows by the text widget.  These buttons \")\n$twind2_text.insert('end', \n                    \"can be used to change the background color of the \")\n$twind2_text.insert('end', \"text widget (\\\"Default\\\" restores the color to \")\n$twind2_text.insert('end', \n                    \"its default).  If you click on the button labeled \")\n$twind2_text.insert('end', \"\\\"Short\\\", it changes to a longer string so that \")\n$twind2_text.insert('end', \"you can see how the text widget automatically \")\n$twind2_text.insert('end', \"changes the layout.  Click on the button again \")\n$twind2_text.insert('end', \"to restore the short string.\\n\")\n\nbtn_default = TkButton.new($twind2_text) {|b|\n  text 'Default'\n  command proc{embDefBg2 $twind2_text}\n  cursor 'top_left_arrow'\n}\nTkTextWindow.new($twind2_text, 'end', 'window'=>btn_default, 'padx'=>3)\nembToggle = TkVariable.new('Short')\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkCheckButton.new($twind2_text) {\n                   textvariable embToggle\n                   indicatoron 0\n                   variable embToggle\n                   onvalue 'A much longer string'\n                   offvalue 'Short'\n                   cursor 'top_left_arrow'\n                   pady 5\n                   padx 2\n                 },\n                 'padx'=>3, \n                 'pady'=>2 )\n\n[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4', \n  'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1', \n  'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1', \n  'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4' \n].each{|twind_color|\n  TkTextWindow.new($twind2_text, 'end', \n                   'window'=>TkButton.new($twind2_text) {\n                     text twind_color\n                     cursor 'top_left_arrow'\n                     command proc{$twind2_text.bg twind_color}\n                   },\n                   'padx'=>3, \n                   'pady'=>2 )\n}\n\n$tag2_buttons.add(btn_default, 'end')\n\n$text_normal2 = {}\n$text_normal2['border'] = $twind2_text.cget('borderwidth')\n$text_normal2['highlight'] = $twind2_text.cget('highlightthickness')\n$text_normal2['pad'] = $twind2_text.cget('padx')\n\n$twind2_text.insert('end', \"\\nYou can also change the usual border width and \")\n$twind2_text.insert('end', \"highlightthickness and padding.\\n\")\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Big borders\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinBigB2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Small borders\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinSmallB2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Big highlight\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinBigH2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Small highlight\",\n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinSmallH2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Big pad\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinBigP2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Small pad\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinSmallP2 $twind2_text\n                                        }))\n\n$twind2_text.insert('end', \n                    \"\\n\\nFinally, images fit comfortably in text widgets too:\")\n\nTkTextImage.new($twind2_text, 'end', \n                'image'=>TkBitmapImage.new(:file=>[\n                                             $demo_dir, '..', \n                                             'images', 'face.xbm'\n                                           ].join(File::Separator)))\n\n# methods\ndef textWinBigB2(w)\n  w.borderwidth 15\nend\ndef textWinSmallB2(w)\n  w.borderwidth $text_normal2['border']\nend\ndef textWinBigH2(w)\n  w.highlightthickness 15\nend\ndef textWinSmallH2(w)\n  w.highlightthickness $text_normal2['highlight']\nend\ndef textWinBigP2(w)\n  w.configure(:padx=>15, :pady=>15)\nend\ndef textWinSmallP2(w)\n  w.configure(:padx=>$text_normal2['pad'], :pady=>$text_normal2['pad'])\nend\n\ndef textWindOn2 (w,f)\n  if defined? $twind2_scroll\n    begin\n      $twind2_scroll.destroy\n    rescue\n    end\n    $twind2_scroll = nil\n  end\n\n  base = TkWinfo.parent( TkWinfo.parent(w) )\n  $twind2_scroll = TkScrollbar.new(base) {|s|\n    orient 'horizontal'\n    command proc{|*args| w.xview(*args)}\n    w.xscrollcommand proc{|first,last| s.set first,last}\n    w.wrap 'none'\n    pack('after'=>f, 'side'=>'bottom', 'fill'=>'x')\n  }\n\n  return nil\nend\n\ndef textWindOff2 (w)\n  if defined? $twind2_scroll\n    begin\n      $twind2_scroll.destroy\n    rescue\n    end\n    $twind2_scroll = nil\n  end\n  w.xscrollcommand ''\n  #w.wrap 'word'\n  w.wrap 'char'\nend\n\ndef textWindPlot2 (t)\n  if (defined? $twind2_plot) && (TkWinfo.exist?($twind2_plot))\n    return\n  end\n\n  $twind2_plot = TkCanvas.new(t) {\n    relief 'sunken'\n    width  450\n    height 300\n    cursor 'top_left_arrow'\n  }\n\n  #font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'\n  font = 'Helvetica 18'\n\n  TkcLine.new($twind2_plot, 100, 250, 400, 250, 'width'=>2)\n  TkcLine.new($twind2_plot, 100, 250, 100,  50, 'width'=>2)\n  TkcText.new($twind2_plot, 225, 20, \n              'text'=>\"A Simple Plot\", 'font'=>font, 'fill'=>'brown')\n\n  (0..10).each {|i|\n    x = 100 + (i * 30)\n    TkcLine.new($twind2_plot, x, 250, x, 245, 'width'=>2)\n    TkcText.new($twind2_plot, x, 254, \n                'text'=>10*i, 'font'=>font, 'anchor'=>'n')\n  }\n  (0..5).each {|i|\n    y = 250 - (i * 40)\n    TkcLine.new($twind2_plot, 100, y, 105, y, 'width'=>2)\n    TkcText.new($twind2_plot, 96, y, \n                'text'=>\"#{i*50}.0\", 'font'=>font, 'anchor'=>'e')\n  }\n\n  for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]\n    x = 100 + (3*xx)\n    y = 250 - (4*yy)/5\n    item = TkcOval.new($twind2_plot, x-6, y-6, x+6, y+6, \n                       'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')\n    item.addtag 'point'\n  end\n\n  $twind2_plot.itembind('point', 'Any-Enter', \n                        proc{$twind2_plot.itemconfigure 'current', 'fill', 'red'})\n  $twind2_plot.itembind('point', 'Any-Leave', \n                        proc{$twind2_plot.itemconfigure 'current', 'fill', 'SkyBlue2'})\n  $twind2_plot.itembind('point', '1', \n                        proc{|x,y| embPlotDown2 $twind2_plot,x,y}, \"%x %y\")\n  $twind2_plot.itembind('point', 'ButtonRelease-1', \n                        proc{$twind2_plot.dtag 'selected'})\n  $twind2_plot.bind('B1-Motion', \n                    proc{|x,y| embPlotMove2 $twind2_plot,x,y}, \"%x %y\")\n  while ($twind2_text.get($mark2_plot) =~ /[ \\t\\n]/)\n    $twind2_text.delete $mark2_plot\n  end\n  $twind2_text.insert $mark2_plot,\"\\n\"\n  TkTextWindow.new($twind2_text, $mark2_plot, 'window'=>$twind2_plot)\n  $tag2_center.add $mark2_plot\n  $twind2_text.insert $mark2_plot,\"\\n\"\nend\n\n$embPlot2 = {'lastX'=>0, 'lastY'=>0}\n\ndef embPlotDown2 (w, x, y)\n  w.dtag 'selected'\n  w.addtag_withtag 'selected', 'current'\n  w.raise 'current'\n  $embPlot2['lastX'] = x\n  $embPlot2['lastY'] = y\nend\n\ndef embPlotMove2 (w, x, y)\n  w.move 'selected', x - $embPlot2['lastX'], y - $embPlot2['lastY']\n  $embPlot2['lastX'] = x\n  $embPlot2['lastY'] = y\nend\n\ndef textWindDel2 (w)\n  if (defined? $twind2_text) && TkWinfo.exist?($twind2_plot)\n    $twind2_text.delete $twind2_plot\n    $twind2_plot = nil\n    while ($twind2_text.get($mark2_plot) =~ /[ \\t\\n]/)\n      $twind2_text.delete $mark2_plot\n    end\n    $twind2_text.insert $mark2_plot,\"  \"\n  end\nend\n\ndef embDefBg2 (w)\n  w['background'] = w.configinfo('background')[3]\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-en/unicodeout.rb",
    "content": "# unicodeout.rb --\n#\n# This demonstration script shows how you can produce output (in label\n# widgets) using many different alphabets.\n#\n# based on Tcl/Tk8.4.4 widget demos\n\nif defined?($unicodeout_demo) && $unicodeout_demo\n  $unicodeout_demo.destroy \n  $unicodeout_demo = nil\nend\n\n$unicodeout_demo = TkToplevel.new {|w|\n  title(\"Unicode Label Demonstration\")\n  iconname(\"unicodeout\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($unicodeout_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'5.4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nThis is a sample of Tk's support for languages that use non-Western \\\ncharacter sets.  However, what you will actually see below depends \\\nlargely on what character sets you have installed, and what you see \\\nfor characters that are not present varies greatly between platforms as well. \\\nPlease try to click the 'See Code' button, \\\nand click the 'Rerun Demo' button after editing \\\n(the source file is not changed) \\\nthe definition of @@font on the Unicodeout_SampleFrame class.\nThe strings are written in Tcl using UNICODE characters \\\nusing the \\\\uXXXX escape so as to do so in a portable fashion.\n\nATTENTION: \nThe strings are converted to the encoded string objects \\\n(completed to rewrite Tcl's escapes) by Tk::UTF8_String method. \\\nAnd the Tk::UTF8_String objects are passed to the label widgets. \nEOL\n\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{\n                 $unicodeout_demo.destroy\n                 $unicodeout_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'See Code', :width=>15, :command=>proc{\n                 showCode 'unicodeout'\n               }).pack(:side=>:left, :expand=>true)\n}\n\nwait_msg = TkLabel.new(base_frame, \n                       :text=>\"Please wait while loading fonts...\", \n                       :font=>\"Helvetica 12 italic\").pack\n\nclass Unicodeout_SampleFrame < TkFrame\n  @@font = $font\n  # @@font = 'Helvetica 14'\n  # @@font = 'Courier 12'\n  # @@font = 'clearlyu 16'\n  # @@font = 'fixed 12'\n  # @@font = 'Times 12'\n  # @@font = 'Newspaper 12'\n  # @@font = '{New century schoolbook} 12'\n\n  def initialize(base)\n    super(base)\n    grid_columnconfig(1, :weight=>1)\n  end\n\n  def add_sample(lang, *args)\n    sample_txt = Tk::UTF8_String(args.join(''))\n    l = TkLabel.new(self, :font=>@@font, :text=>lang+':', \n                    :anchor=>:nw, :pady=>0)\n    #s = TkLabel.new(self, :font=>@@font, :text=>sample_txt, \n    s = TkLabel.new(self, :font=>TkFont.new(@@font), :text=>sample_txt, \n                    :anchor=>:nw, :width=>30, :pady=>0)\n    Tk.grid(l, s, :sticky=>:ew, :pady=>0)\n    l.grid_config(:padx, '1m')\n  end\nend\nf = Unicodeout_SampleFrame.new(base_frame)\nf.pack(:expand=>true, :fill=>:both, :padx=>'2m', :pady=>'1m')\n\n# Processing when some characters are missing might take a while, so make\n# sure we're displaying something in the meantime...\n\noldCursor = $unicodeout_demo.cursor\n$unicodeout_demo.cursor('watch')\nTk.update\n\nf.add_sample('Arabic', \n             '\\uFE94\\uFEF4\\uFE91\\uFEAE\\uFECC\\uFEDF\\uFE8D\\uFE94', \n             '\\uFEE4\\uFEE0\\uFEDC\\uFEDF\\uFE8D')\nf.add_sample('Trad. Chinese', '\\u4E2D\\u570B\\u7684\\u6F22\\u5B57')\nf.add_sample('Simpl. Chinese', '\\u6C49\\u8BED')\nf.add_sample('Greek', \n             '\\u0395\\u03BB\\u03BB\\u03B7\\u03BD\\u03B9\\u03BA\\u03AE ', \n             '\\u03B3\\u03BB\\u03CE\\u03C3\\u03C3\\u03B1')\nf.add_sample('Hebrew', \n             '\\u05DD\\u05D9\\u05DC\\u05E9\\u05D5\\u05E8\\u05D9 ', \n             '\\u05DC\\u05D9\\u05D0\\u05E8\\u05E9\\u05D9')\nf.add_sample('Japanese', \n             '\\u65E5\\u672C\\u8A9E\\u306E\\u3072\\u3089\\u304C\\u306A, ', \n             '\\u6F22\\u5B57\\u3068\\u30AB\\u30BF\\u30AB\\u30CA')\nf.add_sample('Korean', '\\uB300\\uD55C\\uBBFC\\uAD6D\\uC758 \\uD55C\\uAE00')\nf.add_sample('Russian', \n             '\\u0420\\u0443\\u0441\\u0441\\u043A\\u0438\\u0439 ', \n             '\\u044F\\u0437\\u044B\\u043A')\n\nwait_msg.destroy\n$unicodeout_demo.cursor(oldCursor)\n"
  },
  {
    "path": "ext/tk/sample/demos-en/vscale.rb",
    "content": "# vscale.rb\n#\n# This demonstration script shows an example with a vertical scale.\n\nrequire \"tkcanvas\"\n\nif defined?($vscale_demo) && $vscale_demo\n  $vscale_demo.destroy\n  $vscale_demo = nil\nend\n\n$vscale_demo = TkToplevel.new {|w|\n  title(\"Vertical Scale Demonstration\")\n  iconname(\"vscale\")\n}\npositionWindow($vscale_demo)\n\nbase_frame = TkFrame.new($vscale_demo).pack(:fill=>:both, :expand=>true)\n\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '3.5i'\n  justify 'left'\n  text \"An arrow and a vertical scale are displayed below.  If you click or drag mouse button 1 in the scale, you can change the size of the arrow.\"\n}\nmsg.pack('side'=>'top', 'padx'=>'.5c')\n\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    text 'Dismiss'\n    command proc {\n      tmppath = $vscale_demo\n      $vscale_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'Show Code'\n    command proc { showCode 'vscale' }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\ndef setHeight(w, height)\n  height = height + 21\n  y2 = height - 30\n  if y2 < 21\n    y2 = 21\n  end\n  w.coords 'poly',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20\n  w.coords 'line',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20\nend\n\nTkFrame.new(base_frame) {|frame|\n  borderwidth 10\n  canvas = TkCanvas.new(frame) {|c|\n    width 50\n    height 50\n    bd 0\n    highlightthickness 0\n    TkcPolygon.new(c, 0, 0, 1, 1, 2, 2) {\n      fill 'SeaGreen3'\n      tags 'poly'\n    }\n    TkcLine.new(c, 0, 0, 1, 1, 2, 2, 0, 0) {\n      fill 'black'\n      tags 'line'\n    }\n  }.pack('side'=>'left',  'anchor'=>'nw', 'fill'=>'y')\n  scale = TkScale.new(frame) {\n    orient 'vertical'\n    length 284\n    from 0\n    to 250\n    command proc{|value| setHeight(canvas, value)}\n    tickinterval 50\n  }.pack('side'=>'left', 'anchor'=>'ne')\n  scale.set 75\n}.pack\n"
  },
  {
    "path": "ext/tk/sample/demos-en/widget",
    "content": "#!/usr/bin/env ruby\n\n# widget --\n# This script demonstrates the various widgets provided by Tk,\n# along with many of the features of the Tk toolkit.  This file\n# only contains code to generate the main window for the\n# application, which invokes individual demonstrations.  The\n# code for the actual demonstrations is contained in separate\n# \".rb\" files is this directory, which are sourced by this script\n# as needed.\n\nrequire 'tk'\n# require 'tkafter'\n\n### $DEBUG=1 ##########\n\n$RubyTk_WidgetDemo = true\n\n#----------------------------------------------------------------\n# The code below create the main window, consisting of a menu bar\n# and a text widget that explains how to use the program, plus lists\n# all of the demos as hypertext items.\n#----------------------------------------------------------------\n\n# widget demo directory\n# $demo_dir = File.dirname($0)\n$demo_dir = File.dirname(__FILE__)\n\n# root \n$root = TkRoot.new{title \"Ruby/Tk Widget Demonstration\"}\n\n# tk \n$tk_version = Tk::TK_VERSION\n$tk_major_ver, $tk_minor_ver = $tk_version.split('.').map{|n| n.to_i}\n$tk_patchlevel = Tk::TK_PATCHLEVEL\n\n# tcl_platform \n$tk_platform = TkVarAccess.new('tcl_platform')\n\n#\ncase($tk_version)\nwhen /^4.*/\n  $font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil)\nelse\n  $font = TkFont.new('Helvetica -12')\nend\n\n# images\n$image = {}\n\nif $tk_major_ver >= 8\n$image['refresh'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><<EOD)\n    R0lGODlhEAAQAPMAAMz/zCpnKdb/1z9mPypbKBtLGy9NMPL/9Or+6+P+4j1Y\n    PwQKBP7//xMLFAYBCAEBASH5BAEAAAAALAAAAAAQABAAAwR0EAD3Gn0Vyw0e\n    ++CncU7IIAezMA/nhUqSLJizvSdCEEjy2ZIV46AwDAoDHwPYGSoEiUJAAGJ6\n    EDHBNCFINW5OqABKSFk/B9lUa94IDwIFgewFMwQDQwCZQCztTgM9Sl8SOEMG\n    KSAthiaOjBMPDhQONBiXABEAOw==\nEOD\nend\n\nif $tk_major_ver >= 8\n$image['view'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><<EOD)\n    R0lGODlhEAAQAPMAAMz/zP///8DAwICAgH9/fwAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAwRIcMhJB7h3hM33\n    KFjWdQQYap1QrCaGBmrRrS4nj5b53jOgbwXBKGACoYLDIuAoHCmZyYvR1rT5\n    RMAq8LqcIYGsrjPsW1XOmFUEADs=\nEOD\nend\n\nif $tk_major_ver >= 8\n$image['delete'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><<EOD)\n    R0lGODlhEAAOAKEAAIQAAO/n3v///////yH5BAEKAAIALAAAAAAQAA4AAAIm\n    lI9pAKHbIHNoVhYhTdjlJ2AWKG2g+CldmB6rxo2uybYhbS80eRQAOw==\nEOD\nend\n\nif $tk_major_ver >= 8\n$image['print'] = TkPhotoImage.new(:height=>19, :format=>'GIF', :data=><<EOD)\n    R0lGODlhGgATAPcAACEQOTEpQjEpUkIpc0IxY0I5c0oxjEo5SlJCY1JCe1JK\n    UlpChFpCjFpGkFpSc1paa2NKc2NKnGNja2tapWtjc29KnHNanHNjc3NjrXNr\n    jHNrnHNzc3tjpXtrtXtzhICAgIRzvYSEjIZzqox7tYyEnIyMjJSEtZSEvZSM\n    lJyMtZyMvZyUlJyUrZyUvZycnKWctaWlpa2czq2lzrWtvbWtzrW1tb21xr21\n    1sa9zs693s7OztbO3tbO597W1t7W7+fe7+fn5////+/n7+/v7+/v9////wAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAACH5BAEAAEEALAAAAAAaABMAQAj/AIMIHBhkg0GC\n    CBMGIQEiQgseQT4oeCBBAokgRYYQ0JBixg8hRIiUUEBBYYmTByBwiCBCRYwH\n    CxY8cKFw4AogRXLqLAJkQ80gCBBg3BkxZswTNGh4MGqgQQUMJRHCwMkTSE+D\n    Pn8eCKBhxIMhO3ei2OHDBw6sWSlMMMoWgwwfMDZI8GBjx44NARZwEGGi5MkS\n    PcIWKRGz5YgLbAco+KkQBQoJIRgjdGEVq+SaJajqtNrzMgsPCmoIzqmDgmWE\n    KOBuUKAAwYabYTfs4OHjY0giGyhk4MAWRI4eKyRQqPgggYUXPH4A+XBAgwoK\n    DiIsCFxjA9sFEVQQCRJCAYAFDJxiKhAxvMTonEFimrhhYinTBgWiCvxLNX3M\n    DkkpsKV5OYhjBxCMYAICAigUEAA7\nEOD\nend\n\n# \nif $tk_major_ver >= 8\n  $root.add_menubar([[['File', 0], \n                        ['About ... ', proc{aboutBox}, 0, '<F1>'],\n                        '---', \n                        ['Quit', proc{exit}, 0, 'Ctrl-Q']\n                      ]])\nelse\n  TkMenubar.new($root, \n                [[['File', 0], \n                    ['About ... ', proc{aboutBox}, 0, '<F1>'],\n                    '---', \n                    ['Quit', proc{exit}, 0, 'Ctrl-Q']\n                  ]]).pack('side'=>'top', 'fill'=>'x')\nend\n$root.bind('F1', proc{aboutBox})\n$root.bind('Control-q', proc{exit})\n\n=begin\nTkFrame.new($root){|frame|\n  TkMenubutton.new(frame){|button|\n    m = TkMenu.new(button) {\n      add 'command', 'label'=>'Quit', 'command'=>proc{exit}, 'underline'=>0\n    }\n    menu m\n    text 'File'\n    underline 0\n  }.pack('side'=>'left')\n}.pack('side'=>'top', 'fill'=>'x')\n=end\n\n# \nif $tk_version =~ /^4\\.[01]/\n  scr = TkScrollbar.new($root, 'orient'=>'vertical')\n  txt = TkText.new($root) {\n    wrap 'word'\n    width 70\n    height 30\n    font $font\n    setgrid 'yes'\n    yscrollcommand proc{|first,last| scr.set first,last}\n  }\n  scr.command(proc{|*args| txt.yview(*args)})\n  scr.pack('side'=>'right', 'fill'=>'y')\n  txt.pack('expand'=>'yes', 'fill'=>'both')\nelse\n  textFrame = TkFrame.new($root)\n  scr = TkScrollbar.new($root, 'orient'=>'vertical', \n                        'highlightthickness'=>0, 'takefocus'=>1) {\n    pack('in'=>textFrame, 'side'=>'right', 'fill'=>'y', 'padx'=>1)\n  }\n  txt = TkText.new($root) {\n    wrap 'word'\n    width 70\n    height 30\n    font $font\n    setgrid 'yes'\n    highlightthickness 0\n    padx 4\n    pady 2\n    takefocus 0\n    bd 1\n    yscrollcommand proc{|first,last| scr.set first,last}\n  }\n  scr.command(proc{|*args| txt.yview(*args)})\n#  txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both', 'padx'=>1)\n  txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')\n#  textFrame.pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>2)\n  textFrame.pack('expand'=>'yes', 'fill'=>'both')\n\n  statusBar = TkFrame.new($root) {|f|\n    if $tk_version =~ /^4.*/\n      statusfont = '-*-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*'\n    else\n      statusfont = 'Helvetica 10'\n    end\n    $statusBarLabel = \\\n    TkLabel.new(f, 'text'=>\"   \", 'relief'=>'sunken', 'bd'=>1, 'anchor'=>'w', \n                'font'=>statusfont) \\\n        .pack('side'=>'left', 'padx'=>2, 'expand'=>'yes', 'fill'=>'both')\n    TkLabel.new(f, 'width'=>8, 'relief'=>'sunken', 'bd'=>1, 'anchor'=>'w', \n                'font'=>statusfont) \\\n        .pack('side'=>'left', 'padx'=>2)\n  }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>2)\nend\n\n# Create a bunch of tags to use in the text widget, such as those for\n# section titles and demo descriptions.  Also define the bindings for\n# tags.\n  \nif $tk_version =~ /^4.*/\n  tag_title = TkTextTag.new(txt, 'font'=>'-*-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*')\nelse\n  tag_title = TkTextTag.new(txt, 'font'=>'Helvetica 18 bold')\nend\n\n# We put some \"space\" characters to the left and right of each demo description\n# so that the descriptions are highlighted only when the mouse cursor\n# is right over them (but not when the cursor is to their left or right)\n\ntag_demospace = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c')\n\nif TkWinfo.depth($root) == 1\n  tag_demo = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                           'underline'=>1)\n  $tag_visited = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                              'underline'=>1)\n  tag_hot = TkTextTag.new(txt, 'background'=>'black', 'foreground'=>'white')\nelse\n  tag_demo = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                           'foreground'=>'blue', 'underline'=>1)\n  $tag_visited = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                              'foreground'=>'#303080', 'underline'=>1)\n#  tag_hot = TkTextTag.new(txt, 'relief'=>'raised', 'borderwidth'=>1, \n#                         'background'=>'SeaGreen3')\n  tag_hot = TkTextTag.new(txt, 'borderwidth'=>1, 'foreground'=>'red')\nend\n\n#tag_demo.bind('Button-1', proc{invoke txt, txt.index('current')})\ntag_demo.bind('ButtonRelease-1', \n              proc{|x,y|invoke txt, txt.index(\"@#{x},#{y}\")}, '%x %y')\n\nlastLine = TkVariable.new(\"\")\nnewLine  = TkVariable.new(\"\")\ntag_demo.bind('Enter', proc{|x,y|\n                lastLine.value = txt.index(\"@#{x},#{y} linestart\")\n                tag_hot.add(lastLine.value, \"#{lastLine.value} lineend\")\n                showStatus txt, txt.index(\"@#{x},#{y}\")\n              },\n              '%x %y')\ntag_demo.bind('Leave', \n              proc{\n                tag_hot.remove('1.0','end')\n                txt.configure('cursor','xterm')\n                $statusBarLabel.configure('text'=>\"\")\n              })\ntag_demo.bind('Motion', proc{|x, y|\n                newLine.value = txt.index(\"@#{x},#{y} linestart\")\n                if newLine.value != lastLine.value\n                  tag_hot.remove('1.0','end')\n                  lastLine.value = newLine.value\n                  if ( txt.tag_names(\"@#{x},#{y}\").find{|t| \n                        t.kind_of?(String) && t =~ /^demo-/\n                      } )\n                    tag_hot.add(lastLine.value, \n                                \"#{lastLine.value} lineend -1 chars\")\n                  end\n                end\n                showStatus txt, txt.index(\"@#{x},#{y}\")\n              },\n              '%x %y')\n\n# Create the text for the text widget.\n\ntxt.insert('end', \"Ruby/Tk Widget Demonstrations\\n\\n\", tag_title)\ntxt.insert('end', <<EOT)\nThis application provides a front end for several short scripts that \\\ndemonstrate what you can do with Tk widgets.  Each of the numbered \\\nlines below describes a demonstration;  you can click on it to invoke \\\nthe demonstration.  Once the demonstration window appears, you can \\\nclick the \"See Code\" button to see the Ruby/Tk code that created the \\\ndemonstration.  If you wish, you can edit the code and click the \\\n\"Rerun Demo\" button in the code window to reinvoke the demonstration \\\nwith the modified code. \\\nDon't worry about breaking the source code. \\\nYour modifications are not reflected on the original file. \\\nPlease try many kind of changes. \n\nSome demo scripts require the recent version of Tk library \\\n(e.g. Tk8.4 or later) \\\nIf your Tk library linked to Ruby doesn't support the functions \\\nrequired by the demo script, the demo doesn't work. \\\nIn such a case, please re-compile tcltklib with the later Tk library \\\nwhich supports the required functions.\n\nIf your Tk supports Ttk (Tile) extension (included or installed), \\\nplease try the demo of Ttk extension (sample/tkextlib/tile/demo.rb) too.\n( Probably, Ttk extension \\\n#{\nbegin\n  require 'tkextlib/tile'\n  \"is already installed on your environment\"\nrescue\n  \"is not installed on your environment yet\"\nend\n}\\\n. )\nTtk extension is a standard feature of Tk8.5 or later.\n\n\nEOT\n\ntxt.insert('end', \"Labels, buttons, checkbuttons, and radiobuttons.\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Labels (text and bitmaps).\\n\", tag_demo, \"demo-label\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Labels and UNICODE text. (if supported)\\n\", tag_demo, \"demo-unicodeout\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Buttons.\\n\", tag_demo, \"demo-button\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. Checkbuttons (select any of a group).\\n\", tag_demo, \"demo-check\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. Checkbuttons (if supported).\\n\", tag_demo, \"demo-check2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. Radiobuttons (select one of a group).\\n\", tag_demo, \"demo-radio\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"7. Radiobuttons (if supported 'compound' option).\\n\", tag_demo, \"demo-radio2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"8. Radiobuttons (if supported).\\n\", tag_demo, \"demo-radio3\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"9. A 15-puzzle game made out of buttons.\\n\", tag_demo, \"demo-puzzle\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"10. Iconic buttons that use bitmaps.\\n\", tag_demo, \"demo-icon\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"11. Two labels displaying images.\\n\", tag_demo, \"demo-image1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"12. A simple user interface for viewing images.\\n\", tag_demo, \"demo-image2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"13. A simple user interface for viewing images. (if supported)\\n\", tag_demo, \"demo-image3\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"14. Labelled frames (if supported)\\n\", tag_demo, \"demo-labelframe\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"15. The simple Themed Tk widgets (require Tile/Ttk extension)\\n\", tag_demo, \"demo-ttkbut\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Listboxes\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. 50 states.\\n\", tag_demo, \"demo-states\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Colors: change the color scheme for the application.\\n\", \"#{tag_demo.id} demo-colors\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. A collection of famous sayings.\\n\", tag_demo, \"demo-sayings\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. A multi-column list of contries. (require Tile/Ttk extension)\\n\", tag_demo, \"demo-mclist\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. A directory browser tree. (require Tile/Ttk extension)\\n\", tag_demo, \"demo-tree\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Entries and Spin-boxes\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Without scrollbars.\\n\", tag_demo, \"demo-entry1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. With scrollbars.\\n\", tag_demo, \"demo-entry2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \n           \"3. Validated entries and password fields. (if supported)\\n\", \n           tag_demo, \"demo-entry3\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. Spin-boxes. (if supported)\\n\", tag_demo, \"demo-spin\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. Combo-boxes. (require Tile/Ttk extension)\\n\", tag_demo, \"demo-combo\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. Simple Rolodex-like form.\\n\", tag_demo, \"demo-form\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Text\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Basic editable text.\\n\", tag_demo, \"demo-text\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Text display styles.\\n\", tag_demo, \"demo-style\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Hypertext (tag bindings).\\n\", tag_demo, \"demo-bind\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. A text widget with embedded windows.\\n\", tag_demo, \"demo-twind\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. A text widget with embedded windows. (if supported)\\n\", tag_demo, \"demo-twind2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. A search tool built with a text widget.\\n\", tag_demo, \"demo-search\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"7. Peering text widgets. (if supported)\\n\", tag_demo, \"demo-textpeer\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Canvases\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. The canvas item types.\\n\", tag_demo, \"demo-items\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. A simple 2-D plot.\\n\", tag_demo, \"demo-plot\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Text items in canvases.\\n\", tag_demo, \"demo-ctext\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. An editor for arrowheads on canvas lines.\\n\", tag_demo, \"demo-arrow\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. A ruler with adjustable tab stops.\\n\", tag_demo, \"demo-ruler\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. A building floor plan.\\n\", tag_demo, \"demo-floor\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"7. A building floor plan. (another way to create canvas items)\\n\", tag_demo, \"demo-floor2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"8. A simple scrollable canvas.\\n\", tag_demo, \"demo-cscroll\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"9. A Knight's tour of the chess board. (require Tile/Ttk extension)\\n\", tag_demo, \"demo-knightstour\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Scales and Progress Bars\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Vertical scale.\\n\", tag_demo.id, \"demo-vscale\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Horizontal scale.\\n\", tag_demo.id, \"demo-hscale\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Progress bar. (require Tile/Ttk extension)\\n\", tag_demo.id, \"demo-ttkprogress\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Paned Windows and Notebooks\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Horizontal paned window. (if supported)\\n\", tag_demo.id, \"demo-paned1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Vertical paned window. (if supported)\\n\", tag_demo.id, \"demo-paned2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Themed nested panes. (require Tile/Ttk extension)\\n\", tag_demo.id, \"demo-ttkpane\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. Notebook widget. (require Tile/Ttk extension)\\n\", tag_demo.id, \"demo-ttknote\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Menus and Toolbars\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Menus and cascades.\\n\", tag_demo, \"demo-menu\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Menus and cascades. (if supported)\\n\", tag_demo, \"demo-menu84\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Menubuttons.\\n\", tag_demo, \"demo-menubu\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. Themed menu buttons. (require Tile/Ttk extension)\\n\", tag_demo, \"demo-ttkmenu\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. Themed toolbar. (require Tile/Ttk extension)\\n\", tag_demo, \"demo-toolbar\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Common Dialogs\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Message boxes.\\n\", tag_demo, \"demo-msgbox\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Message boxes with detail text. (if supported)\\n\", tag_demo, \"demo-msgbox2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. File selection dialog.\\n\", tag_demo, \"demo-filebox\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. Color picker.\\n\", tag_demo, \"demo-clrpick\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Animation\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Animated labels (if supported)\\n\", tag_demo, \"demo-anilabel\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. Animated wave (if supported)\\n\", tag_demo, \"demo-aniwave\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. Pendulum simulation (if supported)\\n\", tag_demo, \"demo-pendulum\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. A celebration of Rube Goldberg (if supported)\\n\", tag_demo, \"demo-goldberg\")\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"Miscellaneous\\n\", tag_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. The built-in bitmaps.\\n\", tag_demo, \"demo-bitmap\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. A dialog box with a local grab.\\n\", tag_demo, \"demo-dialog1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. A dialog box with a global grab.\\n\", tag_demo, \"demo-dialog2\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.state('disabled')\nscr.focus\n\n# positionWindow --\n# This procedure is invoked by most of the demos to position a\n# new demo window.\n#\n# Arguments:\n# w -           The name of the window to position.\n\ndef positionWindow(w)\n  w.geometry('+300+300')\nend\n\n# showVars --\n# Displays the values of one or more variables in a window, and\n# updates the display whenever any of the variables changes.\n#\n# Arguments:\n# w -           Name of new window to create for display.\n# args -        Any number of names of variables.\n\n$showVarsWin = {}\ndef showVars1(parent, *args)\n  if $showVarsWin[parent.path]\n    begin\n      $showVarsWin[parent.path].destroy \n    rescue\n    end\n  end\n  w = TkToplevel.new(parent) {|w|\n    title \"Variable values\"\n    base = TkFrame.new(w).pack(:fill=>:both, :expand=>true)\n    TkLabel.new(base) {\n      text \"Variable values:\"\n      width 20\n      anchor 'center'\n      if $tk_version =~ /^4.*/\n        font '-Adobe-helvetica-medium-r-normal--*-180-*-*-*-*-*-*'\n      else\n        font 'Helvetica 14'\n      end\n    }.pack('side'=>'top', 'fill'=>'x')\n    len = 1\n    args.each{|vnam,vbody|\n      len = vnam.to_s.length if vnam.to_s.length > len\n    }\n    args.each{|vnam,vbody|\n      TkFrame.new(w){|f|\n        #TkLabel.new(f, 'text'=>\"#{vnam}: \").pack('side'=>'left')\n        TkLabel.new(f, 'text'=>\"#{vnam}: \",'width'=>len+2).pack('side'=>'left')\n        TkLabel.new(f, 'textvariable'=>vbody, 'anchor'=>'w')\\\n                   .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x')\n      }.pack('side'=>'top', 'anchor'=>'w', 'fill'=>'x')\n    }\n    TkButton.new(base) {\n      text \"OK\"\n      command proc{w.destroy}\n    }.pack('side'=>'bottom', 'pady'=>2)\n  }\n  $showVarsWin[parent.path] = w\nend\n\ndef showVars2(parent, *args)\n  if $showVarsWin[parent.path]\n    begin\n      $showVarsWin[parent.path].destroy \n    rescue\n    end\n  end\n  $showVarsWin[parent.path] = TkToplevel.new(parent) {|top|\n    title \"Variable values\"\n\n    base = TkFrame.new(top).pack(:fill=>:both, :expand=>true)\n\n    TkLabelFrame.new(base, :text=>\"Variable values:\", \n                     :font=>{:family=>'Helvetica', :size=>14}){|f|\n      args.each{|vnam,vbody|\n        TkGrid(TkLabel.new(f, :text=>\"#{vnam}: \", :anchor=>'w'), \n               TkLabel.new(f, :textvariable=>vbody, :anchor=>'w'), \n               :padx=>2, :pady=>2, :sticky=>'w')\n      }\n\n      f.grid(:sticky=>'news', :padx=>4)\n      f.grid_columnconfig(1, :weight=>1)\n      f.grid_rowconfig(100, :weight=>1)\n    }\n    TkButton.new(base, :text=>\"OK\", :width=>8, :default=>:active, \n                 :command=>proc{top.destroy}){|b|\n      top.bind('Return', proc{b.invoke})\n      top.bind('Escape', proc{b.invoke})\n\n      b.grid(:sticky=>'e', :padx=>4, :pady=>[6, 4])\n    }\n    base.grid_columnconfig(0, :weight=>1)\n    base.grid_rowconfig(0, :weight=>1)\n  }\nend\n\nif $tk_major_ver < 8\n  alias showVars showVars1\nelsif $tk_major_ver == 8 && $tk_minor_ver < 4\n  alias showVars showVars1\nelse # ver >= 8.4\n  alias showVars showVars2\nend\n\n# Pseudo-Toplevel support\nmodule PseudoToplevel_Evaluable\n  def pseudo_toplevel_eval(body = Proc.new)\n    Thread.current[:TOPLEVEL] = self\n    begin\n      body.call\n    ensure\n      Thread.current[:TOPLEVEL] = nil\n    end\n  end\n\n  def pseudo_toplevel_evaluable?\n    @pseudo_toplevel_evaluable\n  end\n  def pseudo_toplevel_evaluable=(mode)\n    @pseudo_toplevel_evaluable = (mode)? true: false\n  end\n\n  def self.extended(mod)\n    mod.__send__(:extend_object, mod)\n    mod.instance_variable_set('@pseudo_toplevel_evaluable', true)\n  end\nend\n\nclass Object\n  alias __method_missing__ method_missing\n  private :__method_missing__\n\n  def method_missing(id, *args)\n    begin\n      has_top = (top = Thread.current[:TOPLEVEL]) && \n                   top.respond_to?(:pseudo_toplevel_evaluable?) && \n                   top.pseudo_toplevel_evaluable? && \n                   top.respond_to?(id)\n    rescue Exception => e\n      has_top = false\n    end\n\n    if has_top\n      top.__send__(id, *args)\n    else\n      __method_missing__(id, *args)\n    end\n  end\nend\n\nclass Proc\n  def initialize(*args, &b)\n    super\n    @__pseudo_toplevel__ = Thread.current[:TOPLEVEL]\n  end\n\n  alias __call__ call\n  def call(*args, &b)\n    if top = @__pseudo_toplevel__\n      orig_top = Thread.current[:TOPLEVEL]\n      Thread.current[:TOPLEVEL] = top\n      begin\n        __call__(*args, &b)\n      ensure\n        Thread.current[:TOPLEVEL] = orig_top\n      end\n    else\n      __call__(*args, &b)\n    end\n  end\nend\n\ndef proc(&b)\n  Proc.new(&b)\nend\ndef lambda(&b)\n  Proc.new(&b)\nend\n\ndef _null_binding\n  Module.new.instance_eval{extend PseudoToplevel_Evaluable}\n  # binding\n  # Module.new.instance_eval{binding}\nend\nprivate :_null_binding\n\ndef eval_samplecode(code, file=nil)\n  #eval(code)\n  #_null_binding.pseudo_toplevel_eval{ eval(code) }\n  #Thread.new{ _null_binding.pseudo_toplevel_eval{ eval(code) } }\n  Thread.new{\n    _null_binding.pseudo_toplevel_eval{\n      begin\n        if file\n          eval(code, binding, \"(eval:#{file})\")\n        else\n          eval(code)\n        end\n      rescue Exception=>e\n        #p e\n        TkBgError.show(e.class.inspect + ': ' + e.message + \"\\n\" +\n                         \"\\n---< backtrace of Ruby side >-----\\n\" +\n                         e.backtrace.join(\"\\n\") +\n                         \"\\n---< backtrace of Tk side >-------\")\n      end\n    }\n  }\n  Tk.update\nend\n\n# invoke --\n# This procedure is called when the user clicks on a demo description.\n# It is responsible for invoking the demonstration.\n#\n# Arguments:\n# txt -         Name of text widget\n# index -       The index of the character that the user clicked on.\ndef invoke(txt, idx)\n  tag = txt.tag_names(idx).find{|t| t.kind_of?(String) && t =~ /^demo-/}\n  return unless tag\n\n  cursor = txt.cget('cursor')\n  txt.cursor('watch')\n  Tk.update\n  # eval(IO.readlines(\"#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb\").join, _null_binding)\n  # Tk.update\n  eval_samplecode(IO.readlines(\"#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb\").join, tag[5..-1] + '.rb')\n  txt.cursor(cursor)\n\n  $tag_visited.add(\"#{idx} linestart +1 chars\", \"#{idx} lineend +1 chars\")\nend\n=begin\ndef invoke (txt, idx)\n  tag = txt.tag_names(idx).find{|t| t.kind_of?(String) && t =~ /^demo-/}\n  return unless tag\n  current_cursor = txt.cget('cursor')\n  txt.cursor('watch')\n  Tk.update\n#  eval `cat #{tag[5..-1]}.rb`\n#  eval `cat #{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb`\n  eval IO.readlines(\"#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb\").join\n  Tk.update\n#  txt.cursor('xterm')\n  txt.cursor(current_cursor)\n\n  $tag_visited.add(\"#{idx} linestart +1 chars\", \"#{idx} lineend +1 chars\")\nend\n=end\n# showStatus --\n#\n#       Show the name of the demo program in the status bar. This procedure\n#       is called when the user moves the cursor over a demo description.\n#\n\ndef showStatus (txt, index)\n  tag = txt.tag_names(index).find{|t| t.kind_of?(String) && t =~ /^demo-/}\n  cursor = txt.cget('cursor')\n  unless tag\n    $statusBarLabel.configure('text', \" \")\n    newcursor = 'xterm'\n  else\n    demoname = tag[5..-1]\n    $statusBarLabel.configure('text', \n                             \"Run the \\\"#{demoname}\\\" sample program\")\n    newcursor = 'hand2'\n  end\n  txt.configure('cursor'=>newcursor) if cursor != newcursor\nend\n\n# showCode --\n# This procedure creates a toplevel window that displays the code for\n# a demonstration and allows it to be edited and reinvoked.\n#\n# Arguments:\n# demo -        The name of the demonstration's window, which can be\n#               used to derive the name of the file containing its code.\n\ndef showCode1(demo)\n  file = \"#{demo}.rb\"\n  $code_window = nil unless defined? $code_window\n  if $code_window == nil || TkWinfo.exist?($code_window) == false\n    $code_window = TkToplevel.new(nil)\n    f = TkFrame.new($code_window)\n\n    TkButton.new(f) {\n      text \"Dismiss\"\n      command proc{\n        $code_window.destroy\n        $code_window = nil\n      }\n    }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2, 'padx'=>25)\n    TkButton.new(f) {\n      text \"Rerun Demo\"\n      # command proc{eval($code_text.get('1.0','end'), _null_binding)}\n      command proc{eval_samplecode($code_text.get('1.0','end'), '<viewer>')}\n    }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2)\n\n    TkLabel.new(f,'text'=>'line:').pack('side'=>'left')\n    linenum =TkLabel.new(f,'text'=>'').pack('side'=>'left')\n    TkLabel.new(f,'text'=>'  pos:').pack('side'=>'left')\n    posnum =TkLabel.new(f,'text'=>'').pack('side'=>'left')\n\n    $set_linenum = proc{|w|\n      line, pos = w.index('insert').split('.')\n      linenum.text = line\n      posnum.text  = pos\n    }\n\n    f.pack('side'=>'bottom', 'expand'=>'true', 'fill'=>'x')\n\n    if $tk_version =~ /^4\\.[01]/\n      s = TkScrollbar.new($code_window, 'orient'=>'vertical')\n      $code_text = TkText.new($code_window) {\n        height 40\n        setgrid 'yes'\n        yscrollcommand proc{|first,last| s.set first,last}\n      }\n      s.command(proc{|*args| $code_text.yview(*args)})\n      s.pack('side'=>'right', 'fill'=>'y')\n      $code_text.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'both')\n    else\n      TkFrame.new($code_window) {|f|\n        pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n\n        hs = TkScrollbar.new($code_window, 'highlightthickness'=>0, \n                             'orient'=>'horizontal')\n        vs = TkScrollbar.new($code_window, 'highlightthickness'=>0, \n                             'orient'=>'vertical')\n        $code_text = TkText.new($code_window) {|t|\n          height 40\n          wrap 'word'\n          xscrollcommand proc{|first,last| hs.set first,last}\n          yscrollcommand proc{|first,last| vs.set first,last}\n          setgrid 'yes'\n          highlightthickness 0\n          pady 2\n          padx 3\n          hs.command(proc{|*args| $code_text.xview(*args)})\n          vs.command(proc{|*args| $code_text.yview(*args)})\n        }\n\n        $code_text.grid('in'=>f, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n                        'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n        vs.grid('in'=>f, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n                'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n#       xs.grid('in'=>f, 'padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n#               'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n\n# JKC 2001-07-26: segfaults under 1.7.1 (2001-06-19) [i686-linux]\n        TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n        TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n      }\n    end\n\n    btag = TkBindTag.new\n\n    btag.bind('Key', $set_linenum, '%W')\n    btag.bind('Button', $set_linenum, '%W')\n\n    btags = $code_text.bindtags\n    btags.insert(btags.index($code_text.class) + 1, btag)\n    $code_text.bindtags = btags\n\n  else\n    $code_window.deiconify\n    $code_window.raise\n  end\n\n  $code_window.title(\"Demo code: #{file}\")\n  $code_window.iconname(file)\n#  fid = open(file, 'r')\n  fid = open([$demo_dir, file].join(File::Separator), 'r')\n  $code_text.delete('1.0', 'end')\n  #$code_text.insert('1.0', `cat #{file}`)\n  $code_text.insert('1.0', fid.read)\n  #$code_mark = TkTextMark.new($code_text, '1.0')\n  #$code_text.set_insert('1.0')\n  TkTextMarkInsert.new($code_text,'1.0')\n\n  $set_linenum.call($code_text)\n\n  fid.close\nend\n\ndef showCode2(demo)\n  file = \"#{demo}.rb\"\n  $code_window = nil unless defined? $code_window\n  if $code_window == nil || TkWinfo.exist?($code_window) == false\n    $code_window = TkToplevel.new(nil)\n    tf = TkFrame.new($code_window)\n    $code_text = TkText.new(tf, :font=>'Courier 10', :height=>30, \n                            :wrap=>'word', :bd=>1, :setgrid=>true, \n                            :highlightthickness=>0, :pady=>2, :padx=>3)\n    xscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)}\n    yscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)}\n    TkGrid($code_text, yscr, :sticky=>'news')\n    #TkGrid(xscr)\n    tf.grid_rowconfigure(0, :weight=>1)\n    tf.grid_columnconfigure(0, :weight=>1)\n\n    bf = TkFrame.new($code_window)\n\n    lf = TkFrame.new(bf)\n    TkLabel.new(lf, :text=>'line:').pack(:side=>:left)\n    linenum =TkLabel.new(lf, :text=>'').pack(:side=>:left)\n    TkLabel.new(lf, :text=>'  pos:').pack(:side=>:left)\n    posnum =TkLabel.new(lf, :text=>'').pack(:side=>:left)\n\n    $set_linenum = proc{|w|\n      line, pos = w.index('insert').split('.')\n      linenum.text = line\n      posnum.text  = pos\n    }\n\n    b_dis = TkButton.new(bf, :text=>'Dismiss', :default=>:active, \n                         :command=>proc{\n                           $code_window.destroy\n                           $code_window = nil\n                         }, \n                         :image=>$image['delete'], :compound=>:left)\n    b_prn = TkButton.new(bf, :text=>'Print Code', \n                         :command=>proc{printCode($code_text, file)}, \n                         :image=>$image['print'], :compound=>:left)\n    b_run = TkButton.new(bf, :text=>'Rerun Demo', \n                         :command=>proc{\n                           # eval($code_text.get('1.0','end'), _null_binding)\n                           eval_samplecode($code_text.get('1.0','end'), '<viewer>')\n                         }, \n                         :image=>$image['refresh'], :compound=>:left)\n\n    TkGrid(lf, 'x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4])\n    bf.grid_columnconfigure(1, :weight=>1)\n\n    TkGrid(tf, :sticky=>'news')\n    TkGrid(bf, :sticky=>'ew')\n    $code_window.grid_columnconfigure(0, :weight=>1)\n    $code_window.grid_rowconfigure(0, :weight=>1)\n\n    $code_window.bind('Return', proc{|win|\n                        b_dis.invoke unless win.kind_of?(TkText)\n                      }, '%W')\n    $code_window.bindinfo('Return').each{|cmd, arg|\n      $code_window.bind_append('Escape', cmd, arg)\n    }\n\n    btag = TkBindTag.new\n\n    btag.bind('Key', $set_linenum, '%W')\n    btag.bind('Button', $set_linenum, '%W')\n    btag.bind('Configure', $set_linenum, '%W')\n\n    btags = $code_text.bindtags\n    btags.insert(btags.index($code_text.class) + 1, btag)\n    $code_text.bindtags = btags\n\n  else\n    $code_window.deiconify\n    $code_window.raise\n  end\n\n  $code_window.title(\"Demo code: #{file}\")\n  $code_window.iconname(file)\n  fid = open([$demo_dir, file].join(File::Separator), 'r')\n  $code_text.delete('1.0', 'end')\n  $code_text.insert('1.0', fid.read)\n  TkTextMarkInsert.new($code_text,'1.0')\n\n  $set_linenum.call($code_text)\n\n  fid.close\nend\n\nif $tk_major_ver < 8\n  alias showCode showCode1\nelsif $tk_major_ver == 8 && $tk_minor_ver < 4\n  alias showCode showCode1\nelse # ver >= 8.4\n  alias showCode showCode2\nend\n\n\n# printCode --\n# Prints the source code currently displayed in the See Code dialog.\n# Much thanks to Arjen Markus for this.\n#\n# Arguments:\n# txt -         Name of text widget containing code to print\n# file -        Name of the original file (implicitly for title)\n\ndef printCode(txt, file)\n  code = txt.get('1.0', 'end - 1c')\n  dir = '.'\n  dir = ENV['HOME'] if ENV['HOME']\n  dir = ENV['TMP'] if ENV['TMP']\n  dir = ENV['TEMP'] if ENV['TEMP']\n\n  fname = [dir, 'tkdemo-' + file].join(File::Separator)\n  open(fname, 'w'){|fid| fid.print(code)}\n  begin\n    case Tk::TCL_PLATFORM('platform')\n    when 'unix'\n      msg = `lp -c #{fname}`\n      unless $?.exitstatus == 0\n        Tk.messageBox(:title=>'Print spooling failure', \n                      :message=>'Print spooling probably failed: ' + msg)\n      end\n    when 'windows'\n      begin\n        printTextWin32(fname)\n      rescue => e\n        Tk.messageBox(:title=>'Print spooling failure', \n                      :message=>'Print spooling probably failed: ' + \n                      e.message)\n      end      \n    when 'macintosh'\n      Tk.messageBox(:title=>'Operation not Implemented', \n                    :message=>'Oops, sorry: not implemented yet!')\n    else\n      Tk.messageBox(:title=>'Operation not Implemented', \n                    :message=>'Wow! Unknown platform: ' + \n                    Tk::TCL_PLATFORM('platform'))\n    end\n  ensure\n    File.delete(fname)\n  end\nend\n\n# printTextWin32 --\n#    Print a file under Windows\n#\n# Arguments:\n# filename -            Name of the file\n#\ndef printTextWin32(fname)\n  require 'win32/registry'\n  begin\n    app = Win32::Registry::HKEY_CLASSES_ROOT['.txt']\n    pcmd = nil\n    Win32::Registry::HKEY_CLASSES_ROOT.open(\"#{app}\\\\shell\\\\print\"){|reg|\n      pcmd = reg['command']\n    }\n  rescue\n    app = Tk.tk_call('auto_execok', 'notepad.exe')\n    pcmd = \"#{app} /p %1\"\n  end\n\n  pcmd.gsub!('%1', fname)\n  puts pcmd\n  cmd = Tk.tk_call('auto_execok', 'start') + ' /min ' + pcmd\n  \n  msg = `#{cmd}`\n  unless $?.exitstatus == 0\n    fail RuntimeError, msg\n  end\nend\n\n# aboutBox\n#\n#      Pops up a message box with an \"about\" message\n#\ndef aboutBox\n  Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', \n                'message'=>\"Ruby/Tk widget demonstration Ver.1.7.0-en\\n\\n\" + \n                           \"based on demos of Tk8.1 -- 8.5  \" + \n                           \"( Copyright of Tcl/Tk demos:: \" + \n                           \"(c) 1996-1997 Sun Microsystems, Inc. / \" + \n                           \"(c) 1997-2000 Ajuba Solutions, Inc. / \" + \n                           \"(c) 2001-2007 Donal K. Fellows / \" + \n                           \"(c) 2002-2007 Daniel A. Steffen )\\n\\n\" +\n                           \"Your Ruby & Tk Version ::\\n\" + \n                           \"Ruby#{RUBY_VERSION}(#{RUBY_RELEASE_DATE})[#{RUBY_PLATFORM}] / Tk#{$tk_patchlevel}#{(Tk::JAPANIZED_TK)? '-jp': ''}\\n\\n\" + \n                           \"Ruby/Tk release date :: tcltklib #{TclTkLib::RELEASE_DATE}; tk #{Tk::RELEASE_DATE}\")\nend\n\n#########################################\n# start demos if given at command line\nno_launcher = false\nif ARGV[0] == '-n'\n  ARGV.shift\n  no_launcher = true if ARGV.size > 0\nelse\n  # show the root widget to make it lower then demo windows\n  Tk.update\nend\nARGV.each{|cmd| \n  if cmd =~ /(.*).rb/\n    cmd = $1\n  end\n  #eval(IO.readlines(\"#{[$demo_dir, cmd].join(File::Separator)}.rb\").join, \n  #     _null_binding)\n  eval_samplecode(IO.readlines(\"#{[$demo_dir, cmd].join(File::Separator)}.rb\").join, cmd + '.rb')\n}\nif no_launcher\n  $root.withdraw  # hide root window\n  Thread.start{\n    loop do\n      count = 0\n      $root.winfo_children.each{|w|\n        count += 1 if w.kind_of?(TkToplevel)\n      }\n      $root.destroy if count == 0\n    end\n  }\nend\n\n#########################################\n# start eventloop\nTk.mainloop\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/README",
    "content": "\n  Ruby/Tk widget-demo \n                              version 1.2 ( 2000/04/08 )\n                              ʰǽ幩 (nagai@ai.kyutech.ac.jp)\n\nɸۤ Tcl/Tk ĥѥå Ruby (ʲ Ruby/Tk ȸƤӤޤ) \nǤϡTk widget Ѥ GUI κԤȤǤޤºݤ GUI \nƤˤ͡ʼ㤬ץȤ¸ߤʤΤǤRuby/Tk \nˤϤΤ褦Ŭʥץ륹ץȽ¸ߤޤǤФ\nĥѥåθǤ Tcl/Tk ˤϡTk widget ѤƤɤΤ褦ʤȤ\n뤫򼨤ΤȤ widget-demo ¸ߤꡤTcl/Tk Ѥ GUI κ\nݤɽŪץȤʤäƤޤܥ֤ϡRuby/Tk ν\nɽŪʥץ륹ץȤȤ٤Tcl/Tk  widget-demo ܿ\nΤǤ\n\nΥС ruby-1.4.x бȤƤޤС٤ơ\nۤȤѹϤޤruby-1.1c2 ʾʤưȻפޤruby-1.5.x ˤ\nƤϥƥȤƤޤ󡥤ΤᡤߴαƶФ뤳Ȥ뤫⤷ޤ\n󤬡ξǤ⾯νưȻפޤȤ߹ Tk ΥСϡ\n4.2 Ǥ 8.0 Ǥ⽤ʤưϤǤܸǤǤΰܿȤʤä\n뤿ᡤܸ첽줿 Tk ѤץȤΥƥȤϡС\nκݤ Tk4.2jp  Tk8.0jp ξǹԤäƤޤ (ˤǤϤʤǤ)\nΥСǤ ruby-1.4.x + Tk8.0jp ǤδñʥƥȤԤäƤޤ󤬡\nȤۤɤνϤƤޤΤϤʤȹͤƤޤ\n\nܥ֤˴ޤޤ륹ץȤ¿ϡȤʤäƤ Tcl/Tk ǤŪ\nץȵҤȤʤ褦ˤƤޤΤᡤRuby/Tk Υץȸ\nϡޤ Ruby 餷ʤȤǤ礦ˤ⤫餺Τ褦ʵ\näƤͳϡRuby/Tk Υɥ­ˤޤ\n\nTcl/Tk ˤŬʻͽ񤬲¸ߤƤޤ顤Ruby/Tk ץȤ\nݤϡΤ褦 Tcl/Tk λͽǾ䤤ʤ뤳ȤˤʤȻ\nޤ widget λȤơTcl/Tk  widget-demo 򻲾Ȥ뤳Ȥ⤢\nǤ礦Ruby/Tk ǤεҤ widget-demo  Tcl/Tk ǤεҤ˶ᤤΤˤ\nСˤäơRuby/Tk 뤳ȤǤȹͤޤ\nö Ruby/Tk Ǥ  widget λˡƤޤСRuby 餷\nץȤ뤳Ȥ񤷤ʤǤ礦ܥ֤ΥץȤϡRuby/Tk \nǽ˽ޤǤƧȤѤƤйǤ\n\nwidget-demo ΰܿˤäƤϡˤܿץȤ󶡤Ƥ\nޤ˴դΰդɽޤ\n\n    ΩСJAIST (ttate@jaist.ac.jp)  \n    ʿͻ (hiramatu@cdrom.co.jp) \n\nʿˤ Ruby/Tk  Web page (http://www.cdrom.co.jp/~hiramatu/) \n Ruby/Tk νͭѤȻפޤΤǡҤȤ\n\nޤ (maebashi@iij.ad.jp) ϤȤơwidget-demo ΰܿ˺ݤ\nɬפȤʤä Ruby  Tk Ϣ饤֥꽤ˤĤơХλŦ\nƤˤⴶפޤ\n\nƺǸ˺δդ Ruby ߷׼Ԥ ޤĤ 椭Ҥ (matz@netlab.co.jp) \nȻפޤ\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/README.1st",
    "content": "Υǥ쥯ȥˤ Ruby/Tk Υǥ⥹ץȤƤޤ\n\n'.rb' ȤĥҤäƤեϡ㨡ץȤ\n 'widget' ƤӽФ륵֥ץȤǤ줾Ω\nưޤ'widget' ץȤƤӽФƤ\n\n⤷㨡ץ 'widget' εưƱˤĤΥ֥\nץȤưСΥ֥ץȤ̾ȤͿ\nƤ\n( : /usr/local/bin/ruby widget button.rb entry1.rb text.rb )\n֥ץȤγĥ '.rb' Ͼά뤳ȤǤޤ\n( : /usr/local/bin/ruby widget button entry1 text )\n\n⤷㨡ץȤΥɥɬפʤˤϡ'-n' \nץͿƤ\n( : /usr/local/bin/ruby widget -n button.rb entry1.rb text.rb )\n\n¾Υե (browse1  hello ʤ) ñȤưȤǽǤ\n\n          2004/04/14  Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/anilabel.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# animated label widget demo (called by 'widget')\n#\n# based on Tcl/Tk8.5a2 widget demos\n\n# toplevel widget ¸ߤк\nif defined?($anilabel_demo) && $anilabel_demo\n  $anilabel_demo.destroy \n  $anilabel_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$anilabel_demo = TkToplevel.new {|w|\n  title(\"Animated Label Demonstration\")\n  iconname(\"anilabel\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($anilabel_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤ4ĤΥ˥᡼٥뤬ɽƤޤ¦ˤ٥ϡΥƥȥå򥹥뤷褦˸뤳ȤưդƤޤ¦Υ٥ϡɽ륤᡼Ѳ뤳ȤưͿƤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $anilabel_demo\n      $anilabel_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'anilabel'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# label demo ѥե졼\nf_left = TkLabelFrame.new(base_frame,  :text=>'Scrolling Texts')\nf_right = TkLabelFrame.new(base_frame, :text=>'GIF Image')\nTk.pack(f_left, f_right, 'side'=>'left', 'expand'=>'yes', 'fill'=>'both', \n        'padx'=>10, 'pady'=>10)\n\n# animated label\nclass AnimatedTextLabel < TkLabel\n  def initialize(*args)\n    super(*args)\n    @timer = TkTimer.new{ _animation_callback }\n    @timer.loop_exec = -1\n    # bind('Destroy'){ @timer.stop }\n    @btag = TkBindTag.new('Destroy'){ @timer.stop }\n    self.bindtags_unshift(@btag)\n  end\n\n  def _animation_callback()\n    txt = self.text\n    self.text = (txt[1..-1] << txt[0])\n  end\n  private :_animation_callback\n\n  def start(interval)\n    @timer.set_interval(interval)\n    @timer.start\n  end\n\n  def stop\n    @timer.stop\n  end\nend\n\n# animated image\nclass AnimatedImageLabel < AnimatedTextLabel\n  def initialize(*args)\n    super(*args)\n    @destroy_image = false\n    @btag.bind_append('Destroy'){\n      if @destroy_image\n        begin\n          self.image.delete \n        rescue\n        end\n      end\n    }\n  end\n  attr_accessor :destroy_image\n\n  def _animation_callback()\n    img = self.image\n\n    fmt = img.format\n    if fmt.kind_of?(Array)\n      if fmt[1].kind_of?(Hash)\n        # fmt == ['GIF', {'index'=>idx}]\n        idx = fmt[1]['index']\n      else\n        # fmt == ['GIF', '-index', idx]  :: Ruby1.8.2 returns this.\n        idx = fmt[2]\n      end\n    elsif fmt.kind_of?(String) && fmt =~ /GIF -index (\\d+)/\n      idx = $1.to_i\n    else\n      idx = -1\n    end\n\n    begin\n      img.format(\"GIF -index #{idx + 1}\")\n    rescue => e\n      img.format(\"GIF -index 0\")\n    end\n  end\n  private :_animation_callback\nend\n\n# label \nl1 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:ridge, \n                           :font=>{:family=>'Courier', :size=>10})\nl2 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:groove, \n                           :font=>{:family=>'Courier', :size=>10})\nl3 = AnimatedTextLabel.new(f_left, :borderwidth=>4, :relief=>:flat, \n                           :font=>{:family=>'Courier', :size=>10}, :width=>18)\nTk.pack(l1, l2, l3, \n        :side=>:top, :expand=>true, :anchor=>:w, :padx=>10, :pady=>10)\n\nlimg = AnimatedImageLabel.new(f_right, :borderwidth=>0)\nlimg.pack(:side=>:top, :expand=>true, :padx=>10, :pady=>10)\n\n# base64-encoded animated GIF file\ntclPowerdData = <<EOD\n    R0lGODlhKgBAAPQAAP//////zP//AP/MzP/Mmf/MAP+Zmf+ZZv+ZAMz//8zM\n    zMyZmcyZZsxmZsxmAMwzAJnMzJmZzJmZmZlmmZlmZplmM5kzM2aZzGZmzGZm\n    mWZmZmYzZmYzMzNmzDMzZgAzmSH+IE1hZGUgd2l0aCBHSU1QIGJ5IExARGVt\n    YWlsbHkuY29tACH5BAVkAAEALAAAAAAqAEAAAAX+YCCOZEkyTKM2jOm66yPP\n    dF03bx7YcuHIDkGBR7SZeIyhTID4FZ+4Es8nQyCe2EeUNJ0peY2s9mi7PhAM\n    ngEAMGRbUpvzSxskLh1J+Hkg134OdDIDEB+GHxtYMEQMTjMGEYeGFoomezaC\n    DZGSHFmLXTQKkh8eNQVpZ2afmDQGHaOYSoEyhhcklzVmMpuHnaZmDqiGJbg0\n    qFqvh6UNAwB7VA+OwydEjgujkgrPNhbTI8dFvNgEYcHcHx0lB1kX2IYeA2G6\n    NN0YfkXJ2BsAMuAzHB9cZMk3qoEbRzUACsRCUBK5JxsC3iMiKd8GN088SIyT\n    0RAFSROyeEg38caDiB/+JEgqxsODrZJ1BkT0oHKSmI0ceQxo94HDpg0qsuDk\n    UmRAMgu8OgwQ+uIJgUMVeGXA+IQkzEeHGvD8cIGlDXsLiRjQ+EHroQhea7xY\n    8IQBSgYYDi1IS+OFBCgaDMGVS3fGi5BPJpBaENdQ0EomKGD56IHwO39EXiSC\n    Ysgxor5+Xfgq0qByYUpiXmwuoredB2aYH4gWWda0B7SeNENpEJHC1ghi+pS4\n    AJpIAwWvKPBi+8YEht5EriEqpFfMlhEdkBNpx0HUhwypx5T4IB1MBg/Ws2sn\n    wV3MSQOkzI8fUd48Aw3dOZto71x85hHtHijYv18Gf/3GqCdDCXHNoICBobSo\n    IqBqJLyCoH8JPrLgdh88CKCFD0CGmAiGYPgffwceZh6FC2ohIIklnkhehTNY\n    4CIHHGzgwYw01ujBBhvAqKOLLq5AAk9kuSPkkKO40NB+h1gnypJIIvkBf09a\n    N5QIRz5p5ZJXJpmlIVhOGQA2TmIJZZhKKmmll2BqyWSXWUrZpQtpatlmk1c2\n    KaWRHeTZEJF8SqLDn/hhsOeQgBbqAh6DGqronxeARUIIACH5BAUeAAAALAUA\n    LgAFAAUAAAUM4CeKz/OV5YmqaRkCACH5BAUeAAEALAUALgAKAAUAAAUUICCK\n    z/OdJVCaa7p+7aOWcDvTZwgAIfkEBR4AAQAsCwAuAAkABQAABRPgA4zP95zA\n    eZqoWqqpyqLkZ38hACH5BAUKAAEALAcALgANAA4AAAU7ICA+jwiUJEqeKau+\n    r+vGaTmac63v/GP9HM7GQyx+jsgkkoRUHJ3Qx0cK/VQVTKtWwbVKn9suNunc\n    WkMAIfkEBQoAAAAsBwA3AAcABQAABRGgIHzk842j+Yjlt5KuO8JmCAAh+QQF\n    CgAAACwLADcABwAFAAAFEeAnfN9TjqP5oOWziq05lmUIACH5BAUKAAAALA8A\n    NwAHAAUAAAUPoPCJTymS3yiQj4qOcPmEACH5BAUKAAAALBMANwAHAAUAAAUR\n    oCB+z/MJX2o+I2miKimiawgAIfkEBQoAAAAsFwA3AAcABQAABRGgIHzfY47j\n    Q4qk+aHl+pZmCAAh+QQFCgAAACwbADcABwAFAAAFEaAgfs/zCV9qPiNJouo7\n    ll8IACH5BAUKAAAALB8ANwADAAUAAAUIoCB8o0iWZggAOw==\nEOD\n\nl1.text('* Slow Animation *').start(300)\nl2.text('* Fast Animation *').start(80)\nl3.text('This is a longer scrolling text in a widget that will not show the whole message at once. ').start(150)\n\nlimg.destroy_image = true\nlimg.image(TkPhotoImage.new(:format=>'GIF', :data=>tclPowerdData)).start(100)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/aniwave.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# animated wave demo (called by 'widget')\n#\n# based on Tcl/Tk8.5a2 widget demos\n\n# destroy toplevel widget for this demo script\nif defined?($aniwave_demo) && $aniwave_demo\n  $aniwave_demo.destroy \n  $aniwave_demo = nil\nend\n\n# create toplevel widget\n$aniwave_demo = TkToplevel.new {|w|\n  title(\"Animated Wave Demonstration\")\n  iconname(\"aniwave\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($aniwave_demo).pack(:fill=>:both, :expand=>true)\n\n# create label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text 'ΥǥǤϡ饤󥢥ƥबĤ줿ХåȤɽƤޤ˥᡼ϡΥ饤󥢥ƥκɸͤѹ뤳ȤǼ¸Ƥޤ'\n}\nmsg.pack('side'=>'top')\n\n# create frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $aniwave_demo\n      $aniwave_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'aniwave'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# animated wave\nclass AnimatedWaveDemo\n  def initialize(frame, dir=:left)\n    @direction = dir\n\n    # create canvas widget\n    @c = TkCanvas.new(frame, :width=>300, :height=>200, \n                      :background=>'black')\n    @c.pack(:padx=>10, :pady=>10, :expand=>true)\n\n    # Creates a coordinates list of a wave. \n    @waveCoords = []\n    @backupCoords = []\n    n = 0\n    (-10..300).step(5){|n| @waveCoords << [n, 100]; @backupCoords << [n, 100] }\n    n = 305\n    @waveCoords << [n, 0]; @backupCoords << [n, 0]\n    @waveCoords << [n+5, 200]; @backupCoords << [n+5, 200]\n    @coordsLen = @waveCoords.length\n\n    # Create a smoothed line and arrange for its coordinates to be the\n    # contents of the variable waveCoords.\n    @line = TkcLine.new(@c, @waveCoords, \n                        :width=>1, :fill=>'green', :smooth=>true)\n\n    # Main animation \"loop\". \n    # Theoretically 100 frames-per-second (==10ms between frames)\n    @timer = TkTimer.new(10){ basicMotion; reverser }\n\n    # Arrange for the animation loop to stop when the canvas is deleted\n    @c.bindtags_unshift(TkBindTag.new('Destroy'){ @timer.stop })\n  end\n\n  # Basic motion handler. Given what direction the wave is travelling\n  # in, it advances the y coordinates in the coordinate-list one step in\n  # that direction.\n  def basicMotion\n    @backupCoords, @waveCoords = @waveCoords, @backupCoords\n    (0...@coordsLen).each{|idx|\n      if @direction == :left\n        @waveCoords[idx][1] = @backupCoords[(idx+1 == @coordsLen)? 0: idx+1][1]\n      else\n        @waveCoords[idx][1] = @backupCoords[(idx == 0)? -1: idx-1][1]\n      end\n    }\n    @line.coords(@waveCoords)\n  end\n\n  # Oscillation handler. This detects whether to reverse the direction\n  # of the wave by checking to see if the peak of the wave has moved off\n  # the screen (whose size we know already.)\n  def reverser\n    if @waveCoords[0][1] < 10\n      @direction = :right\n    elsif @waveCoords[-1][1] < 10\n      @direction = :left\n    end\n  end\n\n  # animation control\n  def move\n    @timer.start\n  end\n\n  def stop\n    @timer.stop\n  end\nend\n\n# Start the animation processing\nAnimatedWaveDemo.new(base_frame, :left).move\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/arrow.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# arrowhead widget demo (called by 'widget')\n#\n\n# arrowSetup --\n# This method regenerates all the text and graphics in the canvas\n# window.  It's called when the canvas is initially created, and also\n# whenever any of the parameters of the arrow head are changed\n# interactively.\n#\n# Arguments:\n# c -           Name of the canvas widget.\n\ndef arrowSetup(c)\n  v = $demo_arrowInfo\n\n  # Remember the current box, if there is one.\n  tags = c.gettags('current')\n  if tags != []\n    cur = tags.find{|t| t.kind_of?(String) && t =~ /^box[1-3]$/ }\n  else\n    cur = nil\n  end\n\n  # Create the arrow and outline.\n  c.delete('all')\n  TkcLine.new(c, v.x1, v.y, v.x2, v.y, \n              { 'width'=>10 * v.width, \n                'arrowshape'=>[10*v.a, 10*v.b, 10*v.c], \n                'arrow'=>'last' \n              }.update(v.bigLineStyle) )\n  xtip = v.x2 - 10*v.b\n  deltaY = 10*v.c + 5*v.width\n  TkcLine.new(c, v.x2, v.y, xtip, v.y + deltaY, \n              v.x2 - 10*v.a, v.y, xtip, v.y - deltaY, v.x2, v.y, \n              'width'=>2, 'capstyle'=>'round', 'joinstyle'=>'round')\n\n  # Create the boxes for reshaping the line and arrowhead.\n  TkcRectangle.new(c, v.x2-10*v.a-5, v.y-5, v.x2-10*v.a+5, v.y+5, \n                   {'tags'=>['box1', $arrowTag_box]}.update(v.boxStyle) )\n  TkcRectangle.new(c, xtip-5, v.y-deltaY-5, xtip+5, v.y-deltaY+5, \n                   {'tags'=>['box2', $arrowTag_box]}.update(v.boxStyle) )\n  TkcRectangle.new(c, v.x1-5, v.y-5*v.width-5, v.x1+5, v.y-5*v.width+5, \n                   {'tags'=>['box3', $arrowTag_box]}.update(v.boxStyle) )\n  c.itemconfigure cur, v.activeStyle if cur\n\n  # Create three arrows in actual size with the same parameters\n  TkcLine.new(c, v.x2+50, 0, v.x2+50, 1000, 'width'=>2)\n  tmp = v.x2+100\n  TkcLine.new(c, tmp, v.y-125, tmp, v.y-75, 'width'=>v.width, \n              'arrow'=>'both', 'arrowshape'=>[v.a, v.b, v.c])\n  TkcLine.new(c, tmp-25, v.y, tmp+25, v.y, 'width'=>v.width, \n              'arrow'=>'both', 'arrowshape'=>[v.a, v.b, v.c])\n  TkcLine.new(c, tmp-25, v.y+75, tmp+25, v.y+125, 'width'=>v.width, \n              'arrow'=>'both', 'arrowshape'=>[v.a, v.b, v.c])\n\n  # Create a bunch of other arrows and text items showing the \n  # current dimensions.\n  tmp = v.x2+10\n  TkcLine.new(c, tmp, v.y-5*v.width, tmp, v.y-deltaY, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x2+15, v.y-deltaY+5*v.c, 'text'=>v.c, 'anchor'=>'w')\n  tmp = v.x1-10\n  TkcLine.new(c, tmp, v.y-5*v.width, tmp, v.y+5*v.width, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x1-15, v.y, 'text'=>v.width, 'anchor'=>'e')\n  tmp = v.y+5*v.width+10*v.c+10\n  TkcLine.new(c, v.x2-10*v.a, tmp, v.x2, tmp, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x2-5*v.a, tmp+5, 'text'=>v.a, 'anchor'=>'n')\n  tmp = tmp+25\n  TkcLine.new(c, v.x2-10*v.b, tmp, v.x2, tmp, \n              'arrow'=>'both', 'arrowshape'=>v.smallTips)\n  TkcText.new(c, v.x2-5*v.b, tmp+5, 'text'=>v.b, 'anchor'=>'n')\n\n  if $tk_version =~ /^4.*/\n    TkcText.new(c, v.x1, 310, 'text'=>\"'width'=>#{v.width}\", 'anchor'=>'w', \n                'font'=>'-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*')\n    TkcText.new(c, v.x1, 330, \n                'text'=>\"'arrowshape'=>[#{v.a}, #{v.b}, #{v.c}]\",'anchor'=>'w',\n                'font'=>'-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*')\n  else\n    TkcText.new(c, v.x1, 310, 'text'=>\"'width'=>#{v.width}\", 'anchor'=>'w', \n                'font'=>'Helvetica 18')\n    TkcText.new(c, v.x1, 330, \n                'text'=>\"'arrowshape'=>[#{v.a}, #{v.b}, #{v.c}]\",\n                'anchor'=>'w', 'font'=>'Helvetica 18')\n  end\n\n  v.count += 1\nend\n\n# toplevel widget ¸ߤк\nif defined?($arrow_demo) && $arrow_demo\n  $arrow_demo.destroy \n  $arrow_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$arrow_demo = TkToplevel.new {|w|\n  title(\"Arrowhead Editor Demonstration\")\n  iconname(\"arrow\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($arrow_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', \n            'text'=>\" widget ǡХǻȤ饤ˤĤ͡ƬηƤߤ뤳ȤǤޤηѤˤϡ礵줿ˤĤƤ 3ĤλͳѤɥåƤ¦̤礭ǤΥץ򼨤ƤޤΥƥȤϥ饤󥢥ƥФꥪץǤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$arrow_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $arrow_demo\n      $arrow_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'arrow'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$arrow_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# canvas \n$arrow_canvas = TkCanvas.new(base_frame, 'width'=>500, 'height'=>350, \n                             'relief'=>'sunken', 'borderwidth'=>2)\n$arrow_canvas.pack('expand'=>'yes', 'fill'=>'both')\n\n# \nunless Struct.const_defined?(\"ArrowInfo\")\n  $demo_arrowInfo = Struct.new(\"ArrowInfo\", :a, :b, :c, :width, :motionProc, \n                               :x1, :x2, :y, :smallTips, :count, \n                               :bigLineStyle, :boxStyle, :activeStyle).new\nend\n$demo_arrowInfo.a = 8\n$demo_arrowInfo.b = 10\n$demo_arrowInfo.c = 3\n$demo_arrowInfo.width = 2\n$demo_arrowInfo.motionProc = proc{}\n$demo_arrowInfo.x1 = 40\n$demo_arrowInfo.x2 = 350\n$demo_arrowInfo.y = 150\n$demo_arrowInfo.smallTips = [5, 5, 2]\n$demo_arrowInfo.count = 0\nif TkWinfo.depth($arrow_canvas) > 1\n  $demo_arrowInfo.bigLineStyle = {'fill'=>'SkyBlue1'}\n  $demo_arrowInfo.boxStyle = {'fill'=>'', 'outline'=>'black', 'width'=>1}\n  $demo_arrowInfo.activeStyle = {'fill'=>'red', 'outline'=>'black', 'width'=>1}\nelse\n  $demo_arrowInfo.bigLineStyle = {'fill'=>'black', \n    'stipple'=>'@'+[$demo_dir,'..','images','grey.25'].join(File::Separator)}\n  $demo_arrowInfo.boxStyle = {'fill'=>'', 'outline'=>'black', 'width'=>1}\n  $demo_arrowInfo.activeStyle = {'fill'=>'black','outline'=>'black','width'=>1}\nend\n$arrowTag_box = TkcTag.new($arrow_canvas)\narrowSetup $arrow_canvas\n$arrowTag_box.bind('Enter', proc{$arrow_canvas.itemconfigure('current', $demo_arrowInfo.activeStyle)})\n$arrowTag_box.bind('Leave', proc{$arrow_canvas.itemconfigure('current', $demo_arrowInfo.boxStyle)})\n$arrowTag_box.bind('B1-Enter', proc{})\n$arrowTag_box.bind('B1-Leave', proc{})\n$arrow_canvas.itembind('box1', '1', \n                       proc{$demo_arrowInfo.motionProc \\\n                         = proc{|x,y| arrowMove1 $arrow_canvas, x, y}})\n$arrow_canvas.itembind('box2', '1', \n                       proc{$demo_arrowInfo.motionProc \\\n                         = proc{|x,y| arrowMove2 $arrow_canvas, x, y}})\n$arrow_canvas.itembind('box3', '1', \n                       proc{$demo_arrowInfo.motionProc \\\n                         = proc{|x,y| arrowMove3 $arrow_canvas, x, y}})\n$arrowTag_box.bind('B1-Motion', \n                  proc{|x,y| $demo_arrowInfo.motionProc.call(x,y)}, \"%x %y\")\n$arrow_canvas.bind('Any-ButtonRelease-1', proc{arrowSetup $arrow_canvas})\n\n# arrowMove1 --\n# This method is called for each mouse motion event on box1 (the\n# one at the vertex of the arrow).  It updates the controlling parameters\n# for the line and arrowhead.\n#\n# Arguments:\n# c -           The name of the canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef arrowMove1(c,x,y)\n  v = $demo_arrowInfo\n  newA = (v.x2+5-c.canvasx(x).round)/10\n  newA = 0 if newA < 0\n  newA = 25 if newA > 25\n  if newA != v.a\n    c.move('box1', 10*(v.a-newA), 0)\n    v.a = newA\n  end\nend\n\n# arrowMove2 --\n# This method is called for each mouse motion event on box2 (the\n# one at the trailing tip of the arrowhead).  It updates the controlling\n# parameters for the line and arrowhead.\n#\n# Arguments:\n# c -           The name of the canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef arrowMove2(c,x,y)\n  v = $demo_arrowInfo\n  newB = (v.x2+5-c.canvasx(x).round)/10\n  newB = 0 if newB < 0\n  newB = 25 if newB > 25\n  newC = (v.y+5-c.canvasy(y).round-5*v.width)/10\n  newC = 0 if newC < 0\n  newC = 20 if newC > 20\n  if newB != v.b || newC != v.c\n    c.move('box2', 10*(v.b-newB), 10*(v.c-newC))\n    v.b = newB\n    v.c = newC\n  end\nend\n\n# arrowMove3 --\n# This method is called for each mouse motion event on box3 (the\n# one that controls the thickness of the line).  It updates the\n# controlling parameters for the line and arrowhead.\n#\n# Arguments:\n# c -           The name of the canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef arrowMove3(c,x,y)\n  v = $demo_arrowInfo\n  newWidth = (v.y+2-c.canvasy(y).round)/5\n  newWidth = 0 if newWidth < 0\n  newWidth = 20 if newWidth > 20\n  if newWidth != v.width\n    c.move('box3', 0, 5*(v.width-newWidth))\n    v.width = newWidth\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/bind.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# text (tag bindings) widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($bind_demo) && $bind_demo\n  $bind_demo.destroy \n  $bind_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$bind_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Tag Bindings\")\n  iconname(\"bind\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($bind_demo).pack(:fill=>:both, :expand=>true)\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $bind_demo\n      $bind_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'bind'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# bind ѥ᥽å\ndef tag_binding_for_bind_demo(tag, enter_style, leave_style)\n  tag.bind('Any-Enter', proc{tag.configure enter_style})\n  tag.bind('Any-Leave', proc{tag.configure leave_style})\nend\n\n# text \ntxt = TkText.new(base_frame){|t|\n  # \n  setgrid 'true'\n  #width  60\n  #height 24\n  font $font\n  wrap 'word'\n  TkScrollbar.new(base_frame) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    command proc{|*args| t.yview(*args)}\n    t.yscrollcommand proc{|first,last| s.set first,last}\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n\n  # \n  if TkWinfo.depth($root).to_i > 1\n    tagstyle_bold = {'background'=>'#43ce80', 'relief'=>'raised', \n                     'borderwidth'=>1}\n    tagstyle_normal = {'background'=>'', 'relief'=>'flat'}\n  else\n    tagstyle_bold = {'foreground'=>'white', 'background'=>'black'}\n    tagstyle_normal = {'foreground'=>'', 'background'=>''}\n  end\n\n  # ƥ\n  insert 'insert', \"ƥwidgetɽ椹ΤƱΥᥫ˥ȤäơƥȤTclΥޥɤƤ뤳ȤǤޤˤꡢޥ䥭ܡɤΥTclΥޥɤ¹Ԥ褦ˤʤޤ㤨СΥХΥǥץˤĤƤʸˤϤΤ褦ʥĤƤޤޥʸξ˻äƤʸꡢܥ1򲡤ȤΥǥ⤬Ϥޤޤ\n\n\"\n  insert('end', '1. Х widget ˺뤳ȤΤǤ륢ƥμƤ˴ؤ륵ץ롣', (d1 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '2. ñ 2ΥץåȡǡɽưȤǤ롣', (d2 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '3. ƥȥƥΥ󥫡ȹ·', \n         (d3 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '4. 饤󥢥ƥΤƬηΥǥ', \n         (d4 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', '5. ֥ȥåפѹ뤿εǽĤΥ롼顼', \n         (d5 = TkTextTag.new(t)) )\n  insert('end', \"\\n\\n\")\n  insert('end', \n         '6. Хɤäƥ뤹Τ򼨤åɡ', \n         (d6 = TkTextTag.new(t)) )\n\n  # binding\n  [d1, d2, d3, d4, d5, d6].each{|tag|\n    tag_binding_for_bind_demo(tag, tagstyle_bold, tagstyle_normal)\n  }\n  d1.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'items.rb'].join(File::Separator)}`, 'items.rb')\n          })\n  d2.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'plot.rb'].join(File::Separator)}`, 'plot.rb')\n          })\n  d3.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'ctext.rb'].join(File::Separator)}`, 'ctext.rb')\n          })\n  d4.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'arrow.rb'].join(File::Separator)}`, 'arrow.rb')\n          })\n  d5.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'ruler.rb'].join(File::Separator)}`, 'ruler.rb')\n          })\n  d6.bind('1', \n          proc{\n            eval_samplecode(`cat #{[$demo_dir,'cscroll.rb'].join(File::Separator)}`, 'cscroll.rb')\n          })\n\n  TkTextMarkInsert.new(t, '0.0')\n  configure('state','disabled')\n}\n\ntxt.width  60\ntxt.height 24\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/bitmap.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# bitmap widget demo (called by 'widget')\n#\n\n# bitmapRow --\n# Create a row of bitmap items in a window.\n#\n# Arguments:\n# w -           The parent window that is to contain the row.\n# args -        The names of one or more bitmaps, which will be displayed\n#               in a new row across the bottom of w along with their\n#               names.\n\ndef bitmapRow(w,*args)\n  TkFrame.new(w){|row|\n    pack('side'=>'top', 'fill'=>'both')\n    for bitmap in args \n      TkFrame.new(row){|base|\n        pack('side'=>'left', 'fill'=>'both', 'pady'=>'.25c', 'padx'=>'.25c')\n        TkLabel.new(base, 'text'=>bitmap, 'width'=>9).pack('side'=>'bottom')\n        Tk::Label.new(base, 'bitmap'=>bitmap).pack('side'=>'bottom')\n      }\n    end\n  }\nend\n\n# toplevel widget ¸ߤк\nif defined?($bitmap_demo) && $bitmap_demo\n  $bitmap_demo.destroy \n  $bitmap_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$bitmap_demo = TkToplevel.new {|w|\n  title(\"Bitmap Demonstration\")\n  iconname(\"bitmap\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($bitmap_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left', \n            'text'=>\"ΥɥˤϡTk Ȥ߹ޤ줿٤ƤΥӥåȥޥåפ̾ȶɽƤޤTcl ΥץǤϡ줾̾ѤƻȤޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$bitmap_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $bitmap_demo\n      $bitmap_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'bitmap'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$bitmap_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nTkFrame.new(base_frame){|f|\n  bitmapRow(f,'error','gray25','gray50','hourglass')\n  bitmapRow(f,'info','question','questhead','warning')\n  pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both')\n}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/browse1",
    "content": "#!/usr/bin/env ruby\n\n# browse --\n# This script generates a directory browser, which lists the working \n# directory and allow you to open files or subdirectories by \n# double-clicking. \n\nrequire 'tk'\n\n# Create a scrollbar on the right side of the main window and a listbox \n# on the left side.\n\nlistbox = TkListbox.new(nil, 'relief'=>'sunken', \n\t\t\t'width'=>20, 'height'=>20, 'setgrid'=>'yes') {|l|\n  TkScrollbar.new(nil, 'command'=>proc{|*args| l.yview *args}) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    l.yscrollcommand(proc{|first,last| s.set(first,last)})\n  }\n\n  pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n}\n\nroot = TkRoot.new\nroot.minsize(1,1)\n\n# The procedure below is invoked to open a browser on a given file;  if the \n# file is a directory then another instance of this program is invoked; if \n# the file is a regular file then the Mx editor is invoked to display \n# the file. \n\ndef browse (dir, file)\n  file = dir + File::Separator + file if dir != '.'\n  type = File.ftype(file)\n  if type == 'directory'\n    system($0 + ' ' + file + ' &')\n  else\n    if type == 'file'\n      if ENV['EDITOR']\n\tsystem(ENV['EDITOR'] + ' ' + file + ' &')\n      else\n\tsystem('xedit ' + file + ' &')\n      end\n    else\n      STDOUT.print \"\\\"#{file}\\\" isn't a directory or regular file\"\n    end\n  end\nend\n\n# Fill the listbox with a list of all the files in the directory (run \n# the \"ls\" command to get that information).\n\ndir = ARGV[0] ?  ARGV[0] : '.'\nopen(\"|ls -a #{dir}\", 'r'){|fid| fid.readlines}.each{|fname|\n  listbox.insert('end', fname.chomp)\n}\n\n# Set up bindings for the browser.\n\nTk.bind_all('Control-c', proc{root.destroy})\nlistbox.bind('Double-Button-1', \n\t     proc{TkSelection.get.each{|f| browse dir, f}})\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/browse2",
    "content": "#!/usr/bin/env ruby\n\n# browse --\n# This script generates a directory browser, which lists the working \n# directory and allow you to open files or subdirectories by \n# double-clicking. \n\nrequire 'tk'\n\nclass Browse\n  BROWSE_WIN_COUNTER = TkVariable.new(0)\n\n  def initialize(dir)\n    BROWSE_WIN_COUNTER.value = BROWSE_WIN_COUNTER.to_i + 1\n\n    # create base frame\n    base = TkToplevel.new {\n      minsize(1,1)\n      title('Browse : ' + dir)\n    }\n\n    # Create a scrollbar on the right side of the main window and a listbox \n    # on the left side.\n    list = TkListbox.new(base, 'relief'=>'sunken', \n\t\t\t 'width'=>20, 'height'=>20, 'setgrid'=>'yes') {|l|\n      TkScrollbar.new(base, 'command'=>proc{|*args| l.yview *args}) {|s|\n\tpack('side'=>'right', 'fill'=>'y')\n\tl.yscrollcommand(proc{|first,last| s.set(first,last)})\n      }\n\n      pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n\n      # Fill the listbox with a list of all the files in the directory (run \n      # the \"ls\" command to get that information).\n      open(\"|ls -a #{dir}\", 'r'){|fid| fid.readlines}.each{|fname|\n\tl.insert('end', fname.chomp)\n      }\n\n    }\n\n    # Set up bindings for the browser.\n    base.bind('Destroy', proc{\n\t\tBrowse::BROWSE_WIN_COUNTER.value = \\\n\t\t                Browse::BROWSE_WIN_COUNTER.to_i - 1\n\t      })\n    base.bind('Control-c', proc{base.destroy})\n    list.bind('Double-Button-1', \n\t proc{TkSelection.get.each{|f| self.browse dir, f}})\n  end\n\n  # The method below is invoked to open a browser on a given file;  if the \n  # file is a directory then another instance of this program is invoked; if \n  # the file is a regular file then the Mx editor is invoked to display \n  # the file. \n  def browse (dir, file)\n    file = dir + File::Separator + file if dir != '.'\n    type = File.ftype(file)\n    if type == 'directory'\n      Browse.new(file)\n    else\n      if type == 'file'\n\tif ENV['EDITOR']\n\t  system(ENV['EDITOR'] + ' ' + file + ' &')\n\telse\n\t  system('xedit ' + file + ' &')\n\tend\n      else\n\tSTDOUT.print \"\\\"#{file}\\\" isn't a directory or regular file\"\n      end\n    end\n  end\n\nend\n\nBrowse.new(ARGV[0] ? ARGV[0] : '.')\n\nTkRoot.new {\n  withdraw\n  Browse::BROWSE_WIN_COUNTER.trace('w', proc{exit if Browse::BROWSE_WIN_COUNTER.to_i == 0})\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/button.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# button widget demo (called by 'widget')\n#\n#\n\n# toplevel widget ¸ߤк\nif defined?($button_demo) && $button_demo\n  $button_demo.destroy \n  $button_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$button_demo = TkToplevel.new {|w|\n  title(\"Button Demonstration\")\n  iconname(\"button\")\n  positionWindow(w)\n}\n\n# label \nmsg = TkLabel.new($button_demo) {\n  font $kanji_font\n  wraplength '4i'\n  justify 'left'\n  text \"ܥ򥯥åȡܥطʿΥܥ˽񤫤Ƥ뿧ˤʤޤܥ󤫤ܥؤΰưϥ֤򲡤ȤǤǽǤޤڡǼ¹Ԥ뤳ȤǤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \n$button_buttons = Tk::Frame.new($button_demo) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $button_demo\n      $button_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'button'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# button \nTkButton.new($button_demo){\n  text \"Peach Puff\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','PeachPuff1')\n    $button_buttons.configure('bg','PeachPuff1')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n\nTkButton.new($button_demo){\n  text \"Light Blue\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','LightBlue1')\n    $button_buttons.configure('bg','LightBlue1')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n\nTkButton.new($button_demo){\n  text \"Sea Green\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','SeaGreen2')\n    $button_buttons.configure('bg','SeaGreen2')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n\nTkButton.new($button_demo){\n  text \"Yellow\"\n  width 10\n  command proc{\n    $button_demo.configure('bg','Yellow1')\n    $button_buttons.configure('bg','Yellow1')\n  }\n}.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/check.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# checkbutton widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($check_demo) && $check_demo\n  $check_demo.destroy \n  $check_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$check_demo = TkToplevel.new {|w|\n  title(\"Checkbutton Demonstration\")\n  iconname(\"check\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($check_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤ 3 ĤΥåܥɽƤޤåȥܥ֤ѤꡢTcl ѿ ( TkVariable ֥ȤǥǤޤ ) ˤΥܥξ֤򼨤ͤꤷޤߤѿͤ򸫤ˤϡѿȡץܥ򥯥åƤ\"\n}\nmsg.pack('side'=>'top')\n\n# ѿ\nwipers = TkVariable.new(0)\nbrakes = TkVariable.new(0)\nsober  = TkVariable.new(0)\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $check_demo\n      $check_demo = nil\n      $showVarsWin[tmppath.path] = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'check'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n\n  TkButton.new(frame) {\n    text 'ѿ'\n    command proc{\n      showVars(base_frame, \n               ['wipers', wipers], ['brakes', brakes], ['sober', sober])\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n\n# checkbutton \n[ TkCheckButton.new(base_frame, 'text'=>'磻ѡ OK', 'variable'=>wipers),\n  TkCheckButton.new(base_frame, 'text'=>'֥졼 OK', 'variable'=>brakes),\n  TkCheckButton.new(base_frame, 'text'=>'ž ', 'variable'=>sober)\n].each{|w| w.relief('flat'); w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/check2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# checkbutton widget demo2 (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($check2_demo) && $check2_demo\n  $check2_demo.destroy \n  $check2_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$check2_demo = TkToplevel.new {|w|\n  title(\"Checkbutton Demonstration 2\")\n  iconname(\"check2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($check2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤϣĤΥåܥɽƤޤåȥܥ֤ѤꡢTclѿTkVariable֥ȤǥǤޤˤˤΥܥξ֤򼨤ͤꤷޤǽΥܥξ֤¾ΣĤΥܥξ֤ˤ¸Ѳޤ⤷ĤΥܥΰ˥åդƤ硢ǽΥܥϥȥ饤ơȡʣ֡˥⡼ɤǤɽԤޤߤѿͤ򸫤ˤϡѿȡץܥ򥯥åƤ\"\n}\nmsg.pack('side'=>'top')\n\n# ѿ\nsafety = TkVariable.new(0)\nwipers = TkVariable.new(0)\nbrakes = TkVariable.new(0)\nsober  = TkVariable.new(0)\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), \n         :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         TkButton.new(frame, :text=>'ѿ', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{\n                        showVars($check2_demo, \n                                 ['safety', safety], ['wipers', wipers], \n                                 ['brakes', brakes], ['sober', sober])\n                      }), \n         TkButton.new(frame, :text=>'ɻ', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{showCode 'check2'}), \n         TkButton.new(frame, :text=>'Ĥ', \n                      :image=>$image['delete'], :compound=>:left, \n                      :command=>proc{\n                        tmppath = $check2_demo\n                        $check2_demo = nil\n                        $showVarsWin[tmppath.path] = nil\n                        tmppath.destroy\n                      }), \n         :padx=>4, :pady=>4)\n  frame.grid_columnconfigure(0, :weight=>1)\n}.pack('side'=>'bottom', 'fill'=>'x')\n\n\n# checkbutton \nTkCheckButton.new(base_frame, :text=>'', :variable=>safety, \n                  :relief=>:flat, :onvalue=>'all', :offvalue=>'none', \n                  :tristatevalue=>'partial'){\n  pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')\n}\n\n[ TkCheckButton.new(base_frame, 'text'=>'磻ѡ OK', 'variable'=>wipers),\n  TkCheckButton.new(base_frame, 'text'=>'֥졼 OK', 'variable'=>brakes),\n  TkCheckButton.new(base_frame, 'text'=>'ž ', 'variable'=>sober)\n].each{|w| \n  w.relief('flat')\n  w.pack('side'=>'top', 'padx'=>15, 'pady'=>2, 'anchor'=>'w')\n}\n\n# tristate check\nin_check = false\ntristate_check = proc{|n1,n2,op|\n  unless in_check\n    in_check = true\n    begin\n      if n1 == safety\n        if safety == 'none'\n          wipers.value = 0\n          brakes.value = 0\n          sober.value  = 0\n        elsif safety == 'all'\n          wipers.value = 1\n          brakes.value = 1\n          sober.value  = 1\n        end\n      else\n        if wipers == 1 && brakes == 1 && sober == 1\n          safety.value = 'all'\n        elsif wipers == 1 || brakes == 1 || sober == 1\n          safety.value = 'partial'\n        else\n          safety.value = 'none'\n        end\n      end\n    ensure\n      in_check = false\n    end\n  end\n}\n\n[wipers, brakes, sober, safety].each{|v| v.trace('w', tristate_check)}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/clrpick.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# widget demo prompts the user to select a color (called by 'widget')\n#\n#  Note: don't support ttk_wrapper. work with standard widgets only.\n#\n\n# toplevel widget ¸ߤк\nif defined?($clrpick_demo) && $clrpick_demo\n  $clrpick_demo.destroy \n  $clrpick_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$clrpick_demo = TkToplevel.new {|w|\n  title(\"Color Selection Dialogs\")\n  iconname(\"colors\")\n  positionWindow(w)\n}\n\n# label \n#TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left',\nTk::Label.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left',\n            'text'=>\"ʲΥܥ򲡤ơΥɥˤ륦åȤʿطʿ򤷤Ʋ\").pack('side'=>'top')\n\n# frame \n# TkFrame.new($clrpick_demo) {|frame|\nTk::Frame.new($clrpick_demo) {|frame|\n  # TkButton.new(frame) {\n  Tk::Button.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $clrpick_demo\n      $clrpick_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  # TkButton.new(frame) {\n  Tk::Button.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'clrpick'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# button \n# TkButton.new($clrpick_demo, 'text'=>'طʿ ...') {|b|\nTk::Button.new($clrpick_demo, 'text'=>'طʿ ...') {|b|\n  command(proc{setColor $clrpick_demo, b, 'background', \n              ['background', 'highlightbackground']})\n  pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m')\n}\n\n# TkButton.new($clrpick_demo, 'text'=>'ʿ ...') {|b|\nTk::Button.new($clrpick_demo, 'text'=>'ʿ ...') {|b|\n  command(proc{setColor $clrpick_demo, b, 'foreground', ['foreground']})\n  pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m')\n}\n\ndef setColor(w,button,name,options)\n  w.grab\n  initialColor = button[name]\n  color = Tk.chooseColor('title'=>\"Choose a #{name} color\", 'parent'=>w, \n                         'initialcolor'=>initialColor)\n  if color != \"\"\n    setColor_helper(w,options,color)\n  end\n\n  w.grab('release')\nend\n\ndef setColor_helper(w, options, color)\n  options.each{|opt|\n    begin\n      w[opt] = color\n    rescue\n    end\n  }\n  TkWinfo.children(w).each{|child|\n    setColor_helper child, options, color\n  }\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/colors.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# listbox widget demo 'colors' (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($colors_demo) && $colors_demo\n  $colors_demo.destroy \n  $colors_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$colors_demo = TkToplevel.new {|w|\n  title(\"Listbox Demonstration (colors)\")\n  iconname(\"colors\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($colors_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤϿ̾äСդΥꥹȥܥåɽƤޤꥹȤ򥹥뤵ΤϥСǤǤޤꥹȥܥåǥޥΥܥ2(ܥ)򲡤ޤޥɥåƤǤޤ뿧ܥ1(ܥ)ǥ֥륯åȥץꥱΤοˤʤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $colors_demo\n      $colors_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'colors'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \ncolors_lbox = nil\nTkFrame.new(base_frame, 'borderwidth'=>10) {|w|\n  s = TkScrollbar.new(w)\n  colors_lbox = TkListbox.new(w) {\n    setgrid 1\n    width  10\n    height 12\n    yscrollcommand proc{|first,last| s.set first,last}\n  }\n  s.command(proc{|*args| colors_lbox.yview(*args)})\n  s.pack('side'=>'right', 'fill'=>'y')\n  colors_lbox.pack('side'=>'left', 'expand'=>1, 'fill'=>'both')\n}.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y')\n\n#colors_lbox.bind('Double-1', proc{TkPalette.setPalette TkSelection.get})\ncolors_lbox.bind('Double-1', proc{\n                   begin\n                     TkPalette.setPalette TkSelection.get\n                   rescue => e\n                     p e\n                     Tk.tk_call_without_enc('destroy', '.___tk_set_palette')\n                   end\n                   })\n\nins_data = [\n  'gray60','gray70','gray80','gray85','gray90','gray95',\n  'snow1','snow2','snow3','snow4','seashell1','seashell2',\n  'seashell3','seashell4','AntiqueWhite1','AntiqueWhite2',\n  'AntiqueWhite3','AntiqueWhite4','bisque1','bisque2',\n  'bisque3','bisque4','PeachPuff1','PeachPuff2',\n  'PeachPuff3','PeachPuff4','NavajoWhite1','NavajoWhite2',\n  'NavajoWhite3','NavajoWhite4','LemonChiffon1',\n  'LemonChiffon2','LemonChiffon3','LemonChiffon4',\n  'cornsilk1','cornsilk2','cornsilk3','cornsilk4',\n  'ivory1','ivory2','ivory3','ivory4','honeydew1',\n  'honeydew2','honeydew3','honeydew4','LavenderBlush1',\n  'LavenderBlush2','LavenderBlush3','LavenderBlush4',\n  'MistyRose1','MistyRose2','MistyRose3','MistyRose4',\n  'azure1','azure2','azure3','azure4','SlateBlue1',\n  'SlateBlue2','SlateBlue3','SlateBlue4','RoyalBlue1',\n  'RoyalBlue2','RoyalBlue3','RoyalBlue4','blue1','blue2',\n  'blue3','blue4','DodgerBlue1','DodgerBlue2',\n  'DodgerBlue3','DodgerBlue4','SteelBlue1','SteelBlue2',\n  'SteelBlue3','SteelBlue4','DeepSkyBlue1','DeepSkyBlue2',\n  'DeepSkyBlue3','DeepSkyBlue4','SkyBlue1','SkyBlue2',\n  'SkyBlue3','SkyBlue4','LightSkyBlue1','LightSkyBlue2',\n  'LightSkyBlue3','LightSkyBlue4','SlateGray1',\n  'SlateGray2','SlateGray3','SlateGray4',\n  'LightSteelBlue1','LightSteelBlue2','LightSteelBlue3',\n  'LightSteelBlue4','LightBlue1','LightBlue2',\n  'LightBlue3','LightBlue4','LightCyan1','LightCyan2',\n  'LightCyan3','LightCyan4','PaleTurquoise1',\n  'PaleTurquoise2','PaleTurquoise3','PaleTurquoise4',\n  'CadetBlue1','CadetBlue2','CadetBlue3','CadetBlue4',\n  'turquoise1','turquoise2','turquoise3','turquoise4',\n  'cyan1','cyan2','cyan3','cyan4','DarkSlateGray1',\n  'DarkSlateGray2','DarkSlateGray3','DarkSlateGray4',\n  'aquamarine1','aquamarine2','aquamarine3','aquamarine4',\n  'DarkSeaGreen1','DarkSeaGreen2','DarkSeaGreen3',\n  'DarkSeaGreen4','SeaGreen1','SeaGreen2','SeaGreen3',\n  'SeaGreen4','PaleGreen1','PaleGreen2','PaleGreen3',\n  'PaleGreen4','SpringGreen1','SpringGreen2',\n  'SpringGreen3','SpringGreen4','green1','green2',\n  'green3','green4','chartreuse1','chartreuse2',\n  'chartreuse3','chartreuse4','OliveDrab1','OliveDrab2',\n  'OliveDrab3','OliveDrab4','DarkOliveGreen1',\n  'DarkOliveGreen2','DarkOliveGreen3','DarkOliveGreen4',\n  'khaki1','khaki2','khaki3','khaki4','LightGoldenrod1',\n  'LightGoldenrod2','LightGoldenrod3','LightGoldenrod4',\n  'LightYellow1','LightYellow2','LightYellow3',\n  'LightYellow4','yellow1','yellow2','yellow3','yellow4',\n  'gold1','gold2','gold3','gold4','goldenrod1',\n  'goldenrod2','goldenrod3','goldenrod4','DarkGoldenrod1',\n  'DarkGoldenrod2','DarkGoldenrod3','DarkGoldenrod4',\n  'RosyBrown1','RosyBrown2','RosyBrown3','RosyBrown4',\n  'IndianRed1','IndianRed2','IndianRed3','IndianRed4',\n  'sienna1','sienna2','sienna3','sienna4','burlywood1',\n  'burlywood2','burlywood3','burlywood4','wheat1',\n  'wheat2','wheat3','wheat4','tan1','tan2','tan3','tan4',\n  'chocolate1','chocolate2','chocolate3','chocolate4',\n  'firebrick1','firebrick2','firebrick3','firebrick4',\n  'brown1','brown2','brown3','brown4','salmon1','salmon2',\n  'salmon3','salmon4','LightSalmon1','LightSalmon2',\n  'LightSalmon3','LightSalmon4','orange1','orange2',\n  'orange3','orange4','DarkOrange1','DarkOrange2',\n  'DarkOrange3','DarkOrange4','coral1','coral2','coral3',\n  'coral4','tomato1','tomato2','tomato3','tomato4',\n  'OrangeRed1','OrangeRed2','OrangeRed3','OrangeRed4',\n  'red1','red2','red3','red4','DeepPink1','DeepPink2',\n  'DeepPink3','DeepPink4','HotPink1','HotPink2',\n  'HotPink3','HotPink4','pink1','pink2','pink3','pink4',\n  'LightPink1','LightPink2','LightPink3','LightPink4',\n  'PaleVioletRed1','PaleVioletRed2','PaleVioletRed3',\n  'PaleVioletRed4','maroon1','maroon2','maroon3',\n  'maroon4','VioletRed1','VioletRed2','VioletRed3',\n  'VioletRed4','magenta1','magenta2','magenta3',\n  'magenta4','orchid1','orchid2','orchid3','orchid4',\n  'plum1','plum2','plum3','plum4','MediumOrchid1',\n  'MediumOrchid2','MediumOrchid3','MediumOrchid4',\n  'DarkOrchid1','DarkOrchid2','DarkOrchid3',\n  'DarkOrchid4','purple1','purple2','purple3','purple4',\n  'MediumPurple1','MediumPurple2','MediumPurple3',\n  'MediumPurple4','thistle1','thistle2','thistle3', 'thistle4'\n]\n\ncolors_lbox.insert(0, *ins_data)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/combo.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# combo.rb --\n#\n# This demonstration script creates several combobox widgets.\n#\n# based on \"Id: combo.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($combo_demo) && $combo_demo\n  $combo_demo.destroy \n  $combo_demo = nil\nend\n\n$combo_demo = TkToplevel.new {|w|\n  title(\"Combobox Demonstration\")\n  iconname(\"combo\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($combo_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nʲǤ3ΥܥܥåɽƤޤ\\\nǽΤΤϡȥꥦåȤƱͤˡ\\\nݥȤꡤåꡤפꤹ뤳ȤǤޤ\\\nޤReturnϤиߤͤꥹȤɲä졤\\\nɥåץꥹȤ򤹤뤳ȤǤ褦ˤʤޤ\\\n()򲡤ɽ줿ꥹȤ\\\n¾θReturn򲡤СͤǤޤ\\\n2ܤΥܥܥåͤ˸ꤵƤꡤѹǤޤ\\\n3ܤΤΤϥȥꥢԻԤΥɥåץꥹȤ\\\n򤹤뤳ȤǽȤʤäƤޤ\nEOL\n\n## variables\nfirstValue  = TkVariable.new\nsecondValue = TkVariable.new\nozCity      = TkVariable.new\n\n## See Code / Dismiss buttons\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ѿ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{\n                           showVars(base_frame, \n                                    ['firstVariable', firstValue], \n                                    ['secondVariable', secondValue], \n                                    ['ozCity', ozCity])\n                         }), \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'combo'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $combo_demo.destroy\n                           $combo_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nframe = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\naustralianCities = [\n  '٥', 'ɥˡ', 'ܥ', 'ѡ', 'ǥ졼', \n  '֥ꥹ١', 'ۥС', '', 'ꥹ ץ󥰥'\n]\n\n\nsecondValue.value = 'ѹԲ'\nozCity.value = 'ɥˡ'\n\nTk.pack(Ttk::Labelframe.new(frame, :text=>'Fully Editable'){|f|\n          Ttk::Combobox.new(f, :textvariable=>firstValue){|b|\n            b.bind('Return', '%W'){|w|\n              w.values <<= w.value unless w.values.include?(w.value)\n            }\n          }.pack(:pady=>5, :padx=>10)\n        }, \n\n        Ttk::LabelFrame.new(frame, :text=>'Disabled'){|f|\n          Ttk::Combobox.new(f, :textvariable=>secondValue, :state=>:disabled) .\n            pack(:pady=>5, :padx=>10)\n        }, \n\n        Ttk::LabelFrame.new(frame, :text=>'Defined List Only'){|f|\n          Ttk::Combobox.new(f, :textvariable=>ozCity, :state=>:readonly, \n                            :values=>australianCities) .\n            pack(:pady=>5, :padx=>10)\n        }, \n\n        :side=>:top, :pady=>5, :padx=>10)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/cscroll.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# simple scrollable canvas widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($cscroll_demo) && $cscroll_demo\n  $cscroll_demo.destroy \n  $cscroll_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$cscroll_demo = TkToplevel.new {|w|\n  title(\"Scrollable Canvas Demonstration\")\n  iconname(\"cscroll\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($cscroll_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', \n            'justify'=>'left', 'text'=>\"ΥɥˤϥСޥΥܥ2 ǥǤ륭Х widget ɽƤޤͳѤξǥܥ1 򥯥åȡΥǥåɸϤ˽Ϥޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$cscroll_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $cscroll_demo\n      $cscroll_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'cscroll'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$cscroll_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nunless $tk_version =~ /^4\\.[01]/\n  $cscroll_grid = TkFrame.new(base_frame) {\n    pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n  }\n  TkGrid.rowconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0)\n  TkGrid.columnconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0)\nend\n\n# canvas \n$cscroll_canvas = TkCanvas.new(base_frame, \n                               'relief'=>'sunken', 'borderwidth'=>2,\n                               'scrollregion'=>['-11c', '-11c', '50c', '20c']\n                               ) {|c|\n  if $tk_version =~ /^4\\.[01]/\n    pack('expand'=>'yes', 'fill'=>'both') \n  else\n    grid('in'=>$cscroll_grid, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n         'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n  end\n\n  TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}) {|vs|\n    c.yscrollcommand(proc{|first,last| vs.set first,last})\n    if $tk_version =~ /^4\\.[01]/\n      pack('side'=>'right', 'fill'=>'y')\n    else\n      grid('in'=>$cscroll_grid, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    end\n  }\n\n  TkScrollbar.new(base_frame, 'orient'=>'horiz', \n                  'command'=>proc{|*args| c.xview(*args)}) {|hs|\n    c.xscrollcommand(proc{|first,last| hs.set first,last})\n    if $tk_version =~ /^4\\.[01]/\n      pack('side'=>'bottom', 'fill'=>'x') \n    else\n      grid('in'=>$cscroll_grid, 'padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    end\n  }\n}\n\nbg = $cscroll_canvas.configinfo('bg')[4]\n(0..19).each{|i|\n  x = -10+3*i\n  y = -10\n  (0..9).each{|j|\n    TkcRectangle.new($cscroll_canvas, \"#{x}c\", \"#{y}c\", \"#{x+2}c\", \"#{y+2}c\", \n                     'outline'=>'black', 'fill'=>bg, 'tags'=>'rect')\n    TkcText.new($cscroll_canvas, \"#{x+1}c\", \"#{y+1}c\", \n                'text'=>\"#{i},#{j}\", 'anchor'=>'center', 'tags'=>'text')\n    y += 3\n  }\n}\n\n$cscroll_canvas.itembind('all', 'Any-Enter', proc{scrollEnter $cscroll_canvas})\n$cscroll_canvas.itembind('all', 'Any-Leave', proc{scrollLeave $cscroll_canvas})\n$cscroll_canvas.itembind('all', '1', proc{scrollButton $cscroll_canvas})\n$cscroll_canvas.itembind('all', 'Any-Enter', proc{scrollEnter $cscroll_canvas})\n$cscroll_canvas.bind('2', proc{|x,y| $cscroll_canvas.scan_mark(x,y)}, '%x %y')\n$cscroll_canvas.bind('B2-Motion', \n                     proc{|x,y| $cscroll_canvas.scan_dragto(x,y)}, '%x %y')\n\ndef scrollEnter(c)\n  id = c.find_withtag('current')[0].id\n  id -= 1 if c.gettags('current').include?('text')\n  $oldFill = c.itemconfiginfo(id, 'fill')[4]\n  if TkWinfo.depth(c) > 1\n    c.itemconfigure(id, 'fill'=>'SeaGreen1')\n  else\n    c.itemconfigure(id, 'fill'=>'black')\n    c.itemconfigure(id+1, 'fill'=>'white')\n  end\nend\n\ndef scrollLeave(c)\n  id = c.find_withtag('current')[0].id\n  id -= 1 if c.gettags('current').include?('text')\n  c.itemconfigure(id, 'fill'=>$oldFill)\n  c.itemconfigure(id+1, 'fill'=>'black')\nend\n\ndef scrollButton(c)\n  id = c.find_withtag('current')[0].id\n  id += 1 unless c.gettags('current').include?('text')\n  print \"You buttoned at #{c.itemconfiginfo(id,'text')[4]}\\n\"\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ctext.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# Canvas Text widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($ctext_demo) && $ctext_demo\n  $ctext_demo.destroy \n  $ctext_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$ctext_demo = TkToplevel.new {|w|\n  title(\"Canvas Text Demonstration\")\n  iconname(\"Text\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ctext_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', \n            'text'=>\"ΥɥˤϥХwidgetΥƥȵǽǥ⤹뤿ΥƥʸɽƤޤޥͳѤ˻äƤåȰ֤Ѥа֤Ѥꡢ·Ѥꤹ뤳ȤǤޤޤʲΤ褦ԽΤδñʥХǥ󥰤򥵥ݡȤƤޤ\n\n  1. ޥäƤåϤǤޤ\n  2. ܥ1Ǥޤ\n  3. ޥΰ֤˥ܥ2򤷤ƥȤ򥳥ԡǤޤ\n  4.Хåڡ򥳥ȥ-Hľʸޤ\n  5. Deleteľʸޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$ctext_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $ctext_demo\n      $ctext_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'ctext'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$ctext_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# canvas \n$ctext_canvas = TkCanvas.new(base_frame, 'relief'=>'flat', \n                             'borderwidth'=>0, 'width'=>500, 'height'=>350)\n$ctext_canvas.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both')\n\n# font \nif $tk_version =~ /^4.*/\n  textFont = '-*-Helvetica-Medium-R-Normal--*-240-*-*-*-*-*-*'\nelse\n  textFont = 'Helvetica 24'\nend\n\n# canvas \nTkcRectangle.new($ctext_canvas, 245, 195, 255, 205, \n                 'outline'=>'black', 'fill'=>'red')\n\nctag_text_param = {\n  'text'=>\"ϥХwidgetΥƥȵǽǥ⤹뤿ʸǤ\\nǽҤ٤褦ԽǽȤ뤿ΥХǥ󥰤ܤƤޤ\",\n  'width'=>440, 'anchor'=>'n', 'justify'=>'left'\n}\nif $tk_version =~ /^4.*/\n  ctag_text_param['font'] = '-*-Helvetica-Medium-R-Normal--*-240-*-*-*-*-*-*'\n  ctag_text_param['kanjifont'] = '-*-r-*--24-*-jisx0208.1983-0'\nelse\n  ctag_text_param['font'] = 'Helvetica 24'\nend\n$ctag_text = TkcTag.new($ctext_canvas)\n$ctag_text.withtag(TkcText.new($ctext_canvas, 250, 200, ctag_text_param))\n\n$ctag_text.bind('1', proc{|x,y| textB1Press $ctext_canvas,x,y}, \"%x %y\")\n$ctag_text.bind('B1-Motion', proc{|x,y| textB1Move $ctext_canvas,x,y}, \"%x %y\")\n$ctag_text.bind('Shift-1', \n        proc{|x,y| $ctext_canvas.seleect_adjust 'current', \"@#{x},#{y}\"}, \n        \"%x %y\")\n$ctag_text.bind('Shift-B1-Motion', \n                proc{|x,y| textB1Move $ctext_canvas,x,y}, \"%x %y\")\n$ctag_text.bind('KeyPress', proc{|a| textInsert $ctext_canvas,a}, \"%A\")\n$ctag_text.bind('Return', proc{textInsert $ctext_canvas,\"\\n\"})\n$ctag_text.bind('Control-h', proc{textBs $ctext_canvas})\n$ctag_text.bind('BackSpace', proc{textBs $ctext_canvas})\n$ctag_text.bind('Delete', proc{textDel $ctext_canvas})\n$ctag_text.bind('2', proc{|x,y| textPaste $ctext_canvas, \"@#{x},#{y}\"}, \n                \"%x %y\")\n\n# Next, create some items that allow the text's anchor position \n# to be edited.\n\ndef mkTextConfig(w,x,y,option,value,color)\n  item = TkcRectangle.new(w, x, y, x+30, y+30, \n                          'outline'=>'black', 'fill'=>color, 'width'=>1)\n  item.bind('1', proc{$ctag_text.configure option, value})\n  w.addtag_withtag('config', item)\nend\n\nx = 50\ny = 50\ncolor = 'LightSkyBlue1'\nmkTextConfig $ctext_canvas, x, y, 'anchor', 'se', color\nmkTextConfig $ctext_canvas, x+30, y, 'anchor', 's', color\nmkTextConfig $ctext_canvas, x+60, y, 'anchor', 'sw', color\nmkTextConfig $ctext_canvas, x, y+30, 'anchor', 'e', color\nmkTextConfig $ctext_canvas, x+30, y+30, 'anchor', 'center', color\nmkTextConfig $ctext_canvas, x+60, y+30, 'anchor', 'w', color\nmkTextConfig $ctext_canvas, x, y+60, 'anchor', 'ne', color\nmkTextConfig $ctext_canvas, x+30, y+60, 'anchor', 'n', color\nmkTextConfig $ctext_canvas, x+60, y+60, 'anchor', 'nw', color\nitem = TkcRectangle.new($ctext_canvas, x+40, y+40, x+50, y+50, \n                        'outline'=>'black', 'fill'=>'red')\nitem.bind('1', proc{$ctag_text.configure 'anchor', 'center'})\nif $tk_version =~ /^4.*/\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Text Position', \n              'font'=>'-*-times-medium-r-normal--*-240-*-*-*-*-*-*', \n              'anchor'=>'s', 'fill'=>'brown')\nelse\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Text Position', \n              'font'=>'Times 24', 'anchor'=>'s', 'fill'=>'brown')\nend\n\n# Lastly, create some items that allow the text's justification to be\n# changed.\n\nx = 350\ny = 50\ncolor = 'SeaGreen2'\nmkTextConfig $ctext_canvas, x, y, 'justify', 'left', color\nmkTextConfig $ctext_canvas, x+30, y, 'justify', 'center', color\nmkTextConfig $ctext_canvas, x+60, y, 'justify', 'right', color\nif $tk_version =~ /^4.*/\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Justification', \n              'font'=>'-*-times-medium-r-normal--*-240-*-*-*-*-*-*', \n              'anchor'=>'s', 'fill'=>'brown')\nelse\n  TkcText.new($ctext_canvas, x+45, y-5, 'text'=>'Justification', \n              'font'=>'Times 24', 'anchor'=>'s', 'fill'=>'brown')\nend\n\n$ctext_canvas.itembind('config', 'Enter', proc{textEnter $ctext_canvas})\n$ctext_canvas.itembind('config', 'Leave', \n                       proc{$ctext_canvas\\\n                             .itemconfigure('current', \n                                            'fill'=>$textConfigFill)})\n\n$textConfigFill = ''\n\ndef textEnter(w)\n  $textConfigFill = (w.itemconfiginfo 'current', 'fill')[4]\n  w.itemconfigure 'current', 'fill', 'black'\nend\n\ndef textInsert(w, string)\n  return if string == \"\"\n  begin\n    $ctag_text.dchars 'sel.first', 'sel.last'\n  rescue\n  end\n  $ctag_text.insert 'insert', string\nend\n\ndef textPaste(w, pos)\n  begin\n    $ctag_text.insert pos, TkSelection.get\n  rescue\n  end\nend\n\ndef textB1Press(w,x,y)\n  w.icursor 'current', \"@#{x},#{y}\"\n  w.itemfocus 'current'\n  w.focus\n  w.select_from 'current', \"@#{x},#{y}\"\nend\n\ndef textB1Move(w,x,y)\n  w.select_to 'current', \"@#{x},#{y}\"\nend\n\ndef textBs(w)\n  begin\n    $ctag_text.dchars 'sel.first', 'sel.last'\n  rescue\n    char = $ctag_text.index('insert').to_i - 1\n    $ctag_text.dchars(char) if char >= 0\n  end\nend\n\ndef textDel(w)\n  begin\n    $ctag_text.dchars 'sel.first', 'sel.last'\n  rescue\n    $ctag_text.dchars 'insert'\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/dialog1.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# a dialog box with a local grab (called by 'widget')\n#\nclass TkDialog_Demo1 < TkDialog\n  ###############\n  private\n  ###############\n  def title\n    \"Dialog with local grab\"\n  end\n\n  def message\n    '⡼ܥåǤTk  \"grab\" ޥɤѤƥܥåǡ֥륰֡פƤޤΤ줫Υܥ¹Ԥ뤳ȤˤäơΥޤǡΥ֤ˤäƥץꥱ¾ΥɥǤϡݥ󥿴طΥ٥Ȥ뤳ȤǤʤʤäƤޤ'\n  end\n\n  def bitmap\n    'info'\n  end\n\n  def default_button\n    0\n  end\n\n  def buttons\n#    \"λ 󥻥 ɻ\"\n    [\"λ\", \"󥻥\", \"ɻ\"]\n  end\nend\n\nret =  TkDialog_Demo1.new('message_config'=>{'wraplength'=>'4i'}).value\ncase ret\nwhen 0\n  print \"ʤϡλפ򲡤ޤ͡\\n\"\nwhen 1\n  print \"ʤϡ֥󥻥פ򲡤ޤ͡\\n\"\nwhen 2\n  showCode 'dialog1'\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/dialog2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# a dialog box with a global grab (called by 'widget')\n#\nclass TkDialog_Demo2 < TkDialog\n  ###############\n  private\n  ###############\n  def title\n    \"Dialog with global grab\"\n  end\n\n  def message\n    'ΥܥåϥХ륰֤ѤƤޤΥܥ¹Ԥޤǡǥץ쥤ΤʤΤȤäǤޤ󡣥Х륰֤Ѥ뤳ȤϡޤɤͤǤϤޤ󡣤ɤƤɬפˤʤޤǻȤȻפʤǲ'\n  end\n\n  def bitmap\n    'info'\n  end\n\n  def default_button\n    0\n  end\n\n  def buttons\n#    \"λ 󥻥 ɻ\"\n    [\"λ\", \"󥻥\", \"ɻ\"]\n  end\nend\n\nret =  TkDialog_Demo2.new('message_config'=>{'wraplength'=>'4i'},\n                          'prev_command'=>proc{|dialog|\n                            Tk.after 100, proc{dialog.grab('global')}\n                          }).value\ncase ret\nwhen 0\n  print \"ʤϡλפ򲡤ޤ͡\\n\"\nwhen 1\n  print \"ʤϡ֥󥻥פ򲡤ޤ͡\\n\"\nwhen 2\n  showCode 'dialog2'\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/doc.org/README",
    "content": "This directory contains a collection of demonstration programs that\nare translated into Japanese.  You need to use a Japanized \"wish\" to\nsee these Japanese-translated demonstration programs.  You also need\nto put this directory (\"demos.jp\") at the next to \"demos\" since some\nof the programs refer to the image files at \"demos\".\n\nPlease refer to the README file at \"demos\" for more detail.\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/doc.org/README.JP",
    "content": "This directory contains \"widget\" demo for the Japanized Tcl7.6/Tk4.2.\nMost of the messages in the original are translated to Japanese.\nBut other tools in this directory are not translated.\n\nFollowing 2 kanji fonts are defined at the beginning of the file \"widget.\"\n\n\t-*--24-*-jisx0208.1983-0\n\t-*--16-*-jisx0208.1983-0\n\nThese fonts are all part of the core distribution of X11R5, so\nif you are running X11R5, you don't have to modify the file.\n\nBut if you don't have these fonts, replace them with appropriate ones.\n\"-*--14-*-jisx0208.1983-0\" will be a good choice.\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/doc.org/README.tk80",
    "content": "This directory contains a collection of programs to demonstrate\nthe features of the Tk toolkit.  The programs are all scripts for\n\"wish\", a windowing shell.  If wish has been installed in /usr/local\nthen you can invoke any of the programs in this directory just\nby typing its file name to your command shell.  Otherwise invoke\nwish with the file as its first argument, e.g., \"wish hello\".\nThe rest of this file contains a brief description of each program.\nFiles with names ending in \".tcl\" are procedure packages used by one\nor more of the demo programs;  they can't be used as programs by\nthemselves so they aren't described below.\n\nhello -\t\tCreates a single button;  if you click on it, a message\n\t\tis typed and the application terminates.\n\nwidget -\tContains a collection of demonstrations of the widgets\n\t\tcurrently available in the Tk library.  Most of the .tcl\n\t\tfiles are scripts for individual demos available through\n\t\tthe \"widget\" program.\n\nixset -\t\tA simple Tk-based wrapper for the \"xset\" program, which\n\t\tallows you to interactively query and set various X options\n\t\tsuch as mouse acceleration and bell volume.  Thanks to\n\t\tPierre David for contributing this example.\n\nrolodex -\tA mock-up of a simple rolodex application.  It has much of\n\t\tthe user interface for such an application but no back-end\n\t\tdatabase.  This program was written in response to Tom\n\t\tLaStrange's toolkit benchmark challenge.\n\ntcolor -\tA color editor.  Allows you to edit colors in several\n\t\tdifferent ways, and will also perform automatic updates\n\t\tusing \"send\".\n\nrmt -\t\tAllows you to \"hook-up\" remotely to any Tk application\n\t\ton the display.  Select an application with the menu,\n\t\tthen just type commands:  they'll go to that application.\n\ntimer -\t\tDisplays a seconds timer with start and stop buttons.\n\t\tControl-c and control-q cause it to exit.\n\nbrowse -\tA simple directory browser.  Invoke it with and argument\n\t\tgiving the name of the directory you'd like to browse.\n\t\tDouble-click on files or subdirectories to browse them.\n\t\tControl-c and control-q cause the program to exit.\n\nsccs id = SCCS: @(#) README 1.3 96/02/16 10:49:14\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/doc.org/license.terms",
    "content": "This software is copyrighted by the Regents of the University of\nCalifornia, Sun Microsystems, Inc., and other parties.  The following\nterms apply to all files associated with the software unless explicitly\ndisclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license.\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/doc.org/license.terms.tk80",
    "content": "This software is copyrighted by the Regents of the University of\nCalifornia, Sun Microsystems, Inc., and other parties.  The following\nterms apply to all files associated with the software unless explicitly\ndisclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license.\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/entry1.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# entry (no scrollbars) widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($entry1_demo) && $entry1_demo\n  $entry1_demo.destroy \n  $entry1_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$entry1_demo = TkToplevel.new {|w|\n  title(\"Entry Demonstration (no scrollbars)\")\n  iconname(\"entry1\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($entry1_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"3ΰۤʤ륨ȥ꤬ɽƤޤʸϤˤϥݥ󥿤äƹԤåƤ饿פƤɸŪMotifԽǽEmacsΥХɤȤȤˡݡȤƤޤ㤨СХåڡȥȥ-Hϥκʸǥ꡼ȥȥȥ-Dϥα¦ʸޤĹ᤮ƥɥڤʤΤϡޥΥܥ2򲡤ޤޥɥå뤳Ȥǥ뤵뤳ȤǤޤܸϤΤϥȥ-ХååǤkinput2ưƤϤ뤳ȤǤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $entry1_demo\n      $entry1_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'entry1'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# entry \ne1 = TkEntry.new(base_frame, 'relief'=>'sunken')\ne2 = TkEntry.new(base_frame, 'relief'=>'sunken')\ne3 = TkEntry.new(base_frame, 'relief'=>'sunken')\n[e1,e2,e3].each{|w| w.pack('side'=>'top', 'padx'=>10, 'pady'=>5, 'fill'=>'x')}\n\n# \ne1.insert(0, '')\ne2.insert('end', \"ΥȥˤĹʸäƤơ\")\ne2.insert('end', \"ĹƥɥˤڤʤΤǡ\")\ne2.insert('end', \"ºݤν꽪ޤǸˤϥ뤵ʤ\")\ne2.insert('end', \"ʤʤǤ礦\")\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/entry2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# entry (with scrollbars) widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($entry2_demo) && $entry2_demo\n  $entry2_demo.destroy \n  $entry2_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$entry2_demo = TkToplevel.new {|w|\n  title(\"Entry Demonstration (with scrollbars)\")\n  iconname(\"entry2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($entry2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"3ΰۤʤ륨ȥ꤬ơСդɽƤޤʸϤˤϥݥ󥿤äƹԤåƤ饿פƤɸŪMotifԽǽEmacsΥХɤȤȤˡݡȤƤޤ㤨СХåڡȥȥ-Hϥκʸǥ꡼ȥȥȥ-Dϥα¦ʸޤĹ᤮ƥɥڤʤΤϡޥΥܥ2򲡤ޤޥɥå뤳Ȥǥ뤵뤳ȤǤޤܸϤΤϥȥ-ХååǤkinput2ưƤϤ뤳ȤǤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $entry2_demo\n      $entry2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'entry2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nTkFrame.new(base_frame, 'borderwidth'=>10) {|w|\n  # entry 1\n  s1 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz')\n  e1 = TkEntry.new(w, 'relief'=>'sunken') {\n    xscrollcommand proc{|first,last| s1.set first,last}\n  }\n  s1.command(proc{|*args| e1.xview(*args)})\n  e1.pack('side'=>'top', 'fill'=>'x')\n  s1.pack('side'=>'top', 'fill'=>'x')\n\n  # spacer\n  TkFrame.new(w, 'width'=>20, 'height'=>10).pack('side'=>'top', 'fill'=>'x')\n\n  # entry 2\n  s2 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz')\n  e2 = TkEntry.new(w, 'relief'=>'sunken') {\n    xscrollcommand proc{|first,last| s2.set first,last}\n  }\n  s2.command(proc{|*args| e2.xview(*args)})\n  e2.pack('side'=>'top', 'fill'=>'x')\n  s2.pack('side'=>'top', 'fill'=>'x')\n\n  # spacer\n  TkFrame.new(w, 'width'=>20, 'height'=>10).pack('side'=>'top', 'fill'=>'x')\n\n  # entry 3\n  s3 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz')\n  e3 = TkEntry.new(w, 'relief'=>'sunken') {\n    xscrollcommand proc{|first,last| s3.set first,last}\n  }\n  s3.command(proc{|*args| e3.xview(*args)})\n  e3.pack('side'=>'top', 'fill'=>'x')\n  s3.pack('side'=>'top', 'fill'=>'x')\n\n  # \n  e1.insert(0, '')\n  e2.insert('end', \"ΥȥˤĹʸäƤơ\")\n  e2.insert('end', \"ĹƥɥˤڤʤΤǡ\")\n  e2.insert('end', \"ºݤν꽪ޤǸˤϥ뤵ʤ\")\n  e2.insert('end', \"ʤʤǤ礦\")\n\n}.pack('side'=>'top', 'fill'=>'x', 'expand'=>'yes')\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/entry3.rb",
    "content": "# -*- coding: euc-jp -*-\n# entry3.rb --\n#\n# This demonstration script creates several entry widgets whose\n# permitted input is constrained in some way.  It also shows off a\n# password entry.\n#\n# based on Tcl/Tk8.4.4 widget demos\n\nif defined?($entry3_demo) && $entry3_demo\n  $entry3_demo.destroy \n  $entry3_demo = nil\nend\n\n$entry3_demo = TkToplevel.new {|w|\n  title(\"Constrained Entry Demonstration\")\n  iconname(\"entry3\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($entry3_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'5i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nʲˤϣΥȥܥåɽƤޤƥȥܥåϡ\\\nޥåʸǤळȤǽǤ줾줬ɤΤ褦\\\nϤդ뤳ȤǤ뤫ˤߤƤޤ\\\nĤΥȥܥåȸʤʸʸʤξ֤\\\nξդ꤬ϥȥܥåǤޤ\\\nʥե˥åޤˡ\\\nĤΥȥܥåϡϤ줿ʸĹ\\\nʸ̤ξդ¤ۤƽ񤭹⤦ȤȤˤ\\\n٥Ĥ餷Τ餻ޤ\\\nĤƹֹդ륨ȥܥåǤ\\\nե٥åȤϡõΥбŤƤѴޤ\\\nŬڤʸϤ줿ʳʸΰ֤˿Ϥ褦Ȥ\\\nˤϷٹΥ٥뤬Ĥޤ\\\nͤĤΥȥܥåϡʸޤǤϤդ\\\nѥɥեɤǤʣʸʾä˷ٹФȤʤ̵뤵ޤˡ\\\nϤ줿ʸϥꥹ֤ɽޤ\nEOL\n\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $entry3_demo.destroy\n                 $entry3_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'entry3'\n               }).pack(:side=>:left, :expand=>true)\n}\n\n# focusAndFlash --\n# Error handler for entry widgets that forces the focus onto the\n# widget and makes the widget flash by exchanging the foreground and\n# background colours at intervals of 200ms (i.e. at approximately\n# 2.5Hz).\n#\n# Arguments:\n# widget -      entry widget to flash\n# fg -          Initial foreground colour\n# bg -          Initial background colour\n# count -       Counter to control the number of times flashed\ndef focusAndFlash(widget, fg, bg, count=5)\n  return if count <= 0\n  if fg && !fg.empty? && bg && !bg.empty?\n    TkTimer.new(200, count, \n                proc{widget.configure(:foreground=>bg, :background=>fg)}, \n                proc{widget.configure(:foreground=>fg, :background=>bg)}\n                ).start\n  else\n    # TkTimer.new(150, 3){Tk.bell}.start\n    Tk.bell\n    TkTimer.new(200, count, \n                proc{widget.configure(:foreground=>'white', \n                                      :background=>'black')}, \n                proc{widget.configure(:foreground=>'black', \n                                      :background=>'white')}\n                ).at_end{begin\n                           widget.configure(:foreground=>fg, \n                                            :background=>bg)\n                         rescue\n                           # ignore\n                         end}.start\n  end\n  widget.focus(true)\nend\n\nl1 = TkLabelFrame.new(base_frame, :text=>\"ȥ\")\nTkEntry.new(l1, :validate=>:focus, \n            :vcmd=>[\n              proc{|s| s == '' || /^[+-]?\\d+$/ =~ s }, '%P'\n            ]) {|e|\n  fg = e.foreground\n  bg = e.background\n  invalidcommand [proc{|w| focusAndFlash(w, fg, bg)}, '%W']\n  pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n}\n\nl2 = TkLabelFrame.new(base_frame, :text=>\"Ĺդȥ\")\nTkEntry.new(l2, :validate=>:key, :invcmd=>proc{Tk.bell}, \n            :vcmd=>[proc{|s| s.length < 10}, '%P']\n            ).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n\n### PHONE NUMBER ENTRY ###\n# Note that the source to this is quite a bit longer as the behaviour\n# demonstrated is a lot more ambitious than with the others.\n\n# Initial content for the third entry widget\nentry3content = TkVariable.new(\"1-(000)-000-0000\")\n\n# Mapping from alphabetic characters to numbers.\n$phoneNumberMap = {}\nHash[*(%w(abc 2 def 3 ghi 4 jkl 5 mno 6 pqrs 7 tuv 8 wxyz 9))].each{|chars, n|\n  chars.split('').each{|c|\n    $phoneNumberMap[c] = n\n    $phoneNumberMap[c.upcase] = n\n  }\n}\n\n# phoneSkipLeft --\n# Skip over fixed characters in a phone-number string when moving left.\n#\n# Arguments:\n# widget -      The entry widget containing the phone-number.\ndef phoneSkipLeft(widget)\n  idx = widget.index('insert')\n  if idx == 8\n    # Skip back two extra characters\n    widget.cursor = idx - 2\n  elsif idx == 7 || idx == 12\n    # Skip back one extra character\n    widget.cursor = idx - 1\n  elsif idx <= 3\n    # Can't move any further\n    Tk.bell\n    Tk.callback_break\n  end\nend\n\n# phoneSkipRight --\n# Skip over fixed characters in a phone-number string when moving right.\n#\n# Arguments:\n# widget -      The entry widget containing the phone-number.\n# add - Offset to add to index before calculation (used by validation.)\ndef phoneSkipRight(widget, add = 0)\n  idx = widget.index('insert')\n  if (idx + add == 5)\n    # Skip forward two extra characters\n    widget.cursor = idx + 2\n  elsif (idx + add == 6 || idx + add == 10)\n    # Skip forward one extra character\n    widget.cursor = idx + 1\n  elsif (idx + add == 15 && add == 0)\n    # Can't move any further\n    Tk.bell\n    Tk.callback_break\n  end\nend\n\n# validatePhoneChange --\n# Checks that the replacement (mapped to a digit) of the given\n# character in an entry widget at the given position will leave a\n# valid phone number in the widget.\n#\n# widget - entry widget to validate\n# vmode -  The widget's validation mode\n# idx -    The index where replacement is to occur\n# char -   The character (or string, though that will always be\n#          refused) to be overwritten at that point.\n\ndef validatePhoneChange(widget, vmode, idx, char)\n  return true if idx == nil\n  Tk.after_idle(proc{widget.configure(:validate=>vmode, \n                                      :invcmd=>proc{Tk.bell})})\n  if !(idx<3 || idx==6 || idx==7 || idx==11 || idx>15) && char =~ /[0-9A-Za-z]/\n    widget.delete(idx)\n    widget.insert(idx, $phoneNumberMap[char] || char)\n    Tk.after_idle(proc{phoneSkipRight(widget, -1)})\n    # Tk.update(true)  # <- Don't work 'update' inter validation callback.\n                       #    It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1).\n    return true\n  end\n  return false\nend\n\n\nl3 = TkLabelFrame.new(base_frame, :text=>\"ƹֹ楨ȥ\")\nTkEntry.new(l3, :validate=>:key, :invcmd=>proc{Tk.bell}, \n            :textvariable=>entry3content, \n            :vcmd=>[\n              proc{|w,v,i,s| validatePhoneChange(w,v,i,s)}, \n              \"%W %v %i %S\"\n            ]){|e|\n  # Click to focus goes to the first editable character...\n  bind('FocusIn', proc{|d,w|\n         if d != \"NotifyAncestor\"\n           w.cursor = 3\n           Tk.after_idle(proc{w.selection_clear})\n         end\n       }, '%d %W')\n  bind('Left',  proc{|w| phoneSkipLeft(w)},  '%W')\n  bind('Right', proc{|w| phoneSkipRight(w)}, '%W')\n  pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n}\n\nl4 = TkLabelFrame.new(base_frame, :text=>\"ѥɥȥ\")\nTkEntry.new(l4, :validate=>:key, :show=>'*', \n            :vcmd=>[\n              proc{|s| s.length <= 8}, \n              '%P'\n            ]).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m')\n\nTkFrame.new(base_frame){|f|\n  lower\n  TkGrid.configure(l1, l2, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew)\n  TkGrid.configure(l3, l4, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew)\n  TkGrid.columnconfigure(f, [0,1], :uniform=>1)\n  pack(:fill=>:both, :expand=>true)\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/filebox.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# widget demo prompts the user to select a file (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($filebox_demo) && $entry2_demo\n  $filebox_demo.destroy \n  $filebox_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$filebox_demo = TkToplevel.new {|w|\n  title(\"File Selection Dialogs\")\n  iconname(\"filebox\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($filebox_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left',\n            'text'=>\"ȥ˥ե̾ľϤ뤫\\\"Browse\\\" ܥ򲡤ƥեե̾ǲ\").pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $filebox_demo\n      $filebox_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'filebox'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \n['', '¸'].each{|type|\n  TkFrame.new(base_frame) {|f|\n    TkLabel.new(f, 'text'=>\"ե#{type}: \", 'anchor'=>'e')\\\n    .pack('side'=>'left')\n\n    TkEntry.new(f, 'width'=>20) {|e|\n      pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x')\n\n      TkButton.new(f, 'text'=>'Browse ...', \n                   'command'=>proc{fileDialog base_frame,e,type})\\\n      .pack('side'=>'left')\n    }\n\n    pack('fill'=>'x', 'padx'=>'1c', 'pady'=>3)\n  }\n}\n\n$tk_strictMotif = TkVarAccess.new('tk_strictMotif')\nif ($tk_platform['platform'] == 'unix')\n  TkCheckButton.new(base_frame, \n                    'text'=>'MotifΥѤ', \n                    'variable'=>$tk_strictMotif, \n                    'onvalue'=>1, 'offvalue'=>0 ).pack('anchor'=>'c')\nend\n\ndef fileDialog(w,ent,operation)\n  #    Type names         Extension(s)             Mac File Type(s)\n  #\n  #--------------------------------------------------------\n  types = [\n    ['Text files',       ['.txt','.doc']          ], \n    ['Text files',       [],                      'TEXT' ], \n    ['Ruby Scripts',     ['.rb'],                 'TEXT' ], \n    ['Tcl Scripts',      ['.tcl'],                'TEXT' ], \n    ['C Source Files',   ['.c','.h']              ], \n    ['All Source Files', ['.rb','.tcl','.c','.h'] ], \n    ['Image Files',      ['.gif']                 ], \n    ['Image Files',      ['.jpeg','.jpg']         ], \n    ['Image Files',      [],                      ['GIFF','JPEG']], \n    ['All files',        '*'                      ]\n  ]\n\n  if operation == ''\n    file = Tk.getOpenFile('filetypes'=>types, 'parent'=>w)\n  else\n    file = Tk.getSaveFile('filetypes'=>types, 'parent'=>w, \n                          'initialfile'=>'Untitled', \n                          'defaultextension'=>'.txt')\n  end\n  if file != \"\"\n    ent.delete 0, 'end'\n    ent.insert 0, file\n    # ent.xview 'end'\n    Tk.update_idletasks # need this for Tk::Tile::Entry\n                        # (to find right position of 'xview').\n    ent.xview(ent.index('end'))\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/floor.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# floorDisplay widget demo (called by 'widget')\n#\n\n# floorDisplay --\n# Recreate the floorplan display in the canvas given by \"w\".  The\n# floor given by \"active\" is displayed on top with its office structure\n# visible.\n#\n# Arguments:\n# w -           Name of the canvas window.\n# active -      Number of active floor (1, 2, or 3).\n\ndef floorDisplay(w,active)\n  return if $activeFloor == active\n\n  w.delete('all')\n  $activeFloor = active\n\n  # First go through the three floors, displaying the backgrounds for \n  # each floor.\n\n  floor_bg1(w,$floor_colors['bg1'],$floor_colors['outline1'])\n  floor_bg2(w,$floor_colors['bg2'],$floor_colors['outline2'])\n  floor_bg3(w,$floor_colors['bg3'],$floor_colors['outline3'])\n\n  # Raise the background for the active floor so that it's on top.\n\n  w.raise(\"floor#{active}\")\n\n  # Create a dummy item just to mark this point in the display list, \n  # so we can insert highlights here.\n\n  TkcRectangle.new(w,0,100,1,101, 'fill'=>'', 'outline'=>'', 'tags'=>'marker')\n\n  # Add the walls and labels for the active floor, along with \n  # transparent polygons that define the rooms on the floor.\n  # Make sure that the room polygons are on top.\n\n  $floorLabels.clear\n  $floorItems.clear\n  send(\"floor_fg#{active}\", w, $floor_colors['offices'])\n  w.raise('room')\n\n  # Offset the floors diagonally from each other.\n\n  w.move('floor1', '2c', '2c')\n  w.move('floor2', '1c', '1c')\n\n  # Create items for the room entry and its label.\n  TkcWindow.new(w, 600, 100, 'anchor'=>'w', 'window'=>$floor_entry)\n  TkcText.new(w, 600, 100, 'anchor'=>'e', 'text'=>\"ֹ: \")\n  w['scrollregion'] = w.bbox('all')\nend\n\n# newRoom --\n# This method is invoked whenever the mouse enters a room\n# in the floorplan.  It changes tags so that the current room is\n# highlighted.\n#\n# Arguments:\n# w  -          The name of the canvas window.\n\ndef newRoom(w)\n  id = w.find_withtag('current')[0]\n  $currentRoom.value = $floorLabels[id.id] if id != \"\"\n  Tk.update(true)\nend\n\n# roomChanged --\n# This method is invoked whenever the currentRoom variable changes.\n# It highlights the current room and unhighlights any previous room.\n#\n# Arguments:\n# w -           The canvas window displaying the floorplan.\n# args -        Not used.\n\ndef roomChanged(w,*args)\n  w.delete('highlight')\n  item = $floorItems[$currentRoom.value]\n  return if item == nil\n  new = TkcPolygon.new(w, *(w.coords(item)))\n  new.configure('fill'=>$floor_colors['active'], 'tags'=>'highlight')\n  w.raise(new, 'marker')\nend\n\n# floor_bg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor_bg1(w,fill,outline)\n  TkcPolygon.new(w,347,80,349,82,351,84,353,85,363,92,375,99,386,104,\n                 386,129,398,129,398,162,484,162,484,129,559,129,559,133,725,\n                 133,725,129,802,129,802,389,644,389,644,391,559,391,559,327,\n                 508,327,508,311,484,311,484,278,395,278,395,288,400,288,404,\n                 288,409,290,413,292,418,297,421,302,422,309,421,318,417,325,\n                 411,330,405,332,397,333,344,333,340,334,336,336,335,338,332,\n                 342,331,347,332,351,334,354,336,357,341,359,340,360,335,363,\n                 331,365,326,366,304,366,304,355,258,355,258,387,60,387,60,391,\n                 0,391,0,337,3,337,3,114,8,114,8,25,30,25,30,5,93,5,98,5,104,7,\n                 110,10,116,16,119,20,122,28,123,32,123,68,220,68,220,34,221,\n                 22,223,17,227,13,231,8,236,4,242,2,246,0,260,0,283,1,300,5,\n                 321,14,335,22,348,25,365,29,363,39,358,48,352,56,337,70,\n                 344,76,347,80, 'tags'=>['floor1','bg'], 'fill'=>fill)\n  TkcLine.new(w,386,129,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,258,355,258,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,0,337,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,3,114,3,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,162,398,162, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,398,162,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,278,484,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,327,508,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,644,391,559,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,644,389,644,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,725,133,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,725,129,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,802,389,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,3,337,0,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,559,391,559,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,802,389,644,389, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,725,133,725,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,8,25,8,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,8,114,3,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,30,25,8,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,484,278,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,30,25,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,93,5,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,98,5,93,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,104,7,98,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,110,10,104,7, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,116,16,110,10, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,119,20,116,16, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,122,28,119,20, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,123,32,122,28, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,123,68,123,32, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,220,68,123,68, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,386,129,386,104, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,386,104,375,99, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,375,99,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,353,85,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,220,68,220,34, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,337,70,352,56, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,352,56,358,48, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,358,48,363,39, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,363,39,365,29, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,365,29,348,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,348,25,335,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,335,22,321,14, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,321,14,300,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,300,5,283,1, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,283,1,260,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,260,0,246,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,246,0,242,2, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,242,2,236,4, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,236,4,231,8, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,231,8,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,223,17,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,221,22,223,17, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,220,34,221,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,340,360,335,363, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,335,363,331,365, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,331,365,326,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,326,366,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,304,355,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,395,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,404,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,409,290,404,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,413,292,409,290, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,418,297,413,292, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,421,302,418,297, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,422,309,421,302, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,421,318,422,309, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,421,318,417,325, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,417,325,411,330, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,411,330,405,332, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,405,332,397,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,397,333,344,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,344,333,340,334, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,340,334,336,336, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,336,336,335,338, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,335,338,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,331,347,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,332,351,331,347, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,334,354,332,351, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,336,357,334,354, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,341,359,336,357, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,341,359,340,360, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,395,288,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,304,355,258,355, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,347,80,344,76, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,344,76,337,70, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,349,82,347,80, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,351,84,349,82, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  TkcLine.new(w,353,85,351,84, 'fill'=>outline, 'tags'=>['floor1','bg'])\nend\n\n# floor_bg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor_bg2(w,fill,outline)\n  TkcPolygon.new(w,559,129,484,129,484,162,398,162,398,129,315,129,\n                 315,133,176,133,176,129,96,129,96,133,3,133,3,339,0,339,0,391,\n                 60,391,60,387,258,387,258,329,350,329,350,311,395,311,395,280,\n                 484,280,484,311,508,311,508,327,558,327,558,391,644,391,644,\n                 367,802,367,802,129,725,129,725,133,559,133,559,129,\n                 'tags'=>['floor2','bg'], 'fill'=>fill)\n  TkcLine.new(w,350,311,350,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,398,129,398,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,802,367,802,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,802,129,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,725,133,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,559,133,725,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,802,367,644,367, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,644,367,644,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,644,391,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,558,327,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,558,327,508,327, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,280,484,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,398,162,484,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,484,280,395,280, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,395,280,395,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,3,133,3,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,3,339,0,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,0,339,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,258,329,258,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,395,311,350,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,398,129,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,176,133,315,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,3,133,96,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,315,133,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,176,133,176,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  TkcLine.new(w,96,133,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\nend\n\n# floor_bg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor_bg3(w,fill,outline)\n  TkcPolygon.new(w,159,300,107,300,107,248,159,248,159,129,96,129,96,\n                 133,21,133,21,331,0,331,0,391,60,391,60,370,159,370,159,300,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  TkcPolygon.new(w,258,370,258,329,350,329,350,311,399,311,399,129,\n                 315,129,315,133,176,133,176,129,159,129,159,370,258,370,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  TkcLine.new(w,96,133,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,176,129,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,315,133,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,315,133,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,399,129,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,399,311,399,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,399,311,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,350,329,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,258,370,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,60,370,258,370, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,60,370,60,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,0,391,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,21,331,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,21,331,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,96,133,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  TkcLine.new(w,107,300,159,300,159,248,107,248,107,300, \n              'fill'=>outline, 'tags'=>['floor3','bg'])\nend\n\n# floor_fg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the first\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor_fg1(w,color)\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '101'\n  $floorItems['101'] = i\n  TkcText.new(w,358,209, 'text'=>'101', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Pub Lift1'\n  $floorItems['Pub Lift1'] = i\n  TkcText.new(w,323,223, 'text'=>'Pub Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Priv Lift1'\n  $floorItems['Priv Lift1'] = i\n  TkcText.new(w,323,188, 'text'=>'Priv Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,42,389,42,337,1,337,1,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '110'\n  $floorItems['110'] = i\n  TkcText.new(w,21.5,363, 'text'=>'110', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,59,389,59,385,90,385,90,337,44,337,44,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '109'\n  $floorItems['109'] = i\n  TkcText.new(w,67,363, 'text'=>'109', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,300,51,253,6,253,6,300, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '111'\n  $floorItems['111'] = i\n  TkcText.new(w,28.5,276.5, 'text'=>'111', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,98,248,98,309,79,309,79,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '117B'\n  $floorItems['117B'] = i\n  TkcText.new(w,88.5,278.5, 'text'=>'117B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,251,51,204,6,204,6,251, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '112'\n  $floorItems['112'] = i\n  TkcText.new(w,28.5,227.5, 'text'=>'112', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,6,156,51,156,51,203,6,203, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '113'\n  $floorItems['113'] = i\n  TkcText.new(w,28.5,179.5, 'text'=>'113', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,85,169,79,169,79,192,85,192, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '117A'\n  $floorItems['117A'] = i\n  TkcText.new(w,82,180.5, 'text'=>'117A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,77,302,77,168,53,168,53,302, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '117'\n  $floorItems['117'] = i\n  TkcText.new(w,65,235, 'text'=>'117', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,155,51,115,6,115,6,155, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '114'\n  $floorItems['114'] = i\n  TkcText.new(w,28.5,135, 'text'=>'114', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,95,115,53,115,53,168,95,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '115'\n  $floorItems['115'] = i\n  TkcText.new(w,74,141.5, 'text'=>'115', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,87,113,87,27,10,27,10,113, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '116'\n  $floorItems['116'] = i\n  TkcText.new(w,48.5,70, 'text'=>'116', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,89,91,128,91,128,113,89,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '118'\n  $floorItems['118'] = i\n  TkcText.new(w,108.5,102, 'text'=>'118', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,178,128,178,132,216,132,216,91,\n                     163,91,163,112,149,112,149,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '120'\n  $floorItems['120'] = i\n  TkcText.new(w,189.5,111.5, 'text'=>'120', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,79,193,87,193,87,169,136,169,136,192,\n                     156,192,156,169,175,169,175,246,79,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '122'\n  $floorItems['122'] = i\n  TkcText.new(w,131,207.5, 'text'=>'122', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,169,154,169,154,191,138,191, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '121'\n  $floorItems['121'] = i\n  TkcText.new(w,146,180, 'text'=>'121', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,99,300,126,300,126,309,99,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '106A'\n  $floorItems['106A'] = i\n  TkcText.new(w,112.5,304.5, 'text'=>'106A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,128,299,128,309,150,309,150,248,99,248,99,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '105'\n  $floorItems['105'] = i\n  TkcText.new(w,124.5,278.5, 'text'=>'105', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,174,309,174,300,152,300,152,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '106B'\n  $floorItems['106B'] = i\n  TkcText.new(w,163,304.5, 'text'=>'106B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,176,299,176,309,216,309,216,248,152,248,152,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '104'\n  $floorItems['104'] = i\n  TkcText.new(w,184,278.5, 'text'=>'104', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,385,138,337,91,337,91,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '108'\n  $floorItems['108'] = i\n  TkcText.new(w,114.5,361, 'text'=>'108', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,256,337,140,337,140,385,256,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '107'\n  $floorItems['107'] = i\n  TkcText.new(w,198,361, 'text'=>'107', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,300,353,300,329,260,329,260,353, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Smoking'\n  $floorItems['Smoking'] = i\n  TkcText.new(w,280,341, 'text'=>'Smoking', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,314,135,314,170,306,170,306,246,177,246,177,135, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '123'\n  $floorItems['123'] = i\n  TkcText.new(w,245.5,190.5, 'text'=>'123', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,217,248,301,248,301,326,257,326,257,310,217,310, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '103'\n  $floorItems['103'] = i\n  TkcText.new(w,259,287, 'text'=>'103', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,396,188,377,188,377,169,316,169,316,131,396,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '124'\n  $floorItems['124'] = i\n  TkcText.new(w,356,150, 'text'=>'124', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,226,407,226,407,189,377,189,377,246,397,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '125'\n  $floorItems['125'] = i\n  TkcText.new(w,392,217.5, 'text'=>'125', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,399,187,409,187,409,207,474,207,474,164,399,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '126'\n  $floorItems['126'] = i\n  TkcText.new(w,436.5,185.5, 'text'=>'126', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,409,209,409,229,399,229,399,253,\n                     486,253,486,239,474,239,474,209, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '127'\n  $floorItems['127'] = i\n  TkcText.new(w,436.5,'231', 'text'=>'127', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,501,164,501,174,495,174,495,188,\n                     490,188,490,204,476,204,476,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'MShower'\n  $floorItems['MShower'] = i\n  TkcText.new(w,488.5,'184', 'text'=>'MShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,497,176,513,176,513,204,492,204,492,190,497,190, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Closet'\n  $floorItems['Closet'] = i\n  TkcText.new(w,502.5,190, 'text'=>'Closet', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,476,237,476,206,513,206,513,254,488,254,488,237, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'WShower'\n  $floorItems['WShower'] = i\n  TkcText.new(w,494.5,230, 'text'=>'WShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,486,131,558,131,558,135,724,135,724,166,\n                     697,166,697,275,553,275,531,254,515,254,\n                     515,174,503,174,503,161,486,161, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '130'\n  $floorItems['130'] = i\n  TkcText.new(w,638.5,205, 'text'=>'130', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,308,242,339,242,339,248,342,248,\n                     342,246,397,246,397,276,393,276,\n                     393,309,300,309,300,248,308,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '102'\n  $floorItems['102'] = i\n  TkcText.new(w,367.5,278.5, 'text'=>'102', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,255,486,255,486,276,397,276, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '128'\n  $floorItems['128'] = i\n  TkcText.new(w,441.5,265.5, 'text'=>'128', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,510,309,486,309,486,255,530,255,\n                     552,277,561,277,561,325,510,325,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '129'\n  $floorItems['129'] = i\n  TkcText.new(w,535.5,293, 'text'=>'129', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,696,281,740,281,740,387,642,387,\n                     642,389,561,389,561,277,696,277, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '133'\n  $floorItems['133'] = i\n  TkcText.new(w,628.5,335, 'text'=>'133', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,742,387,742,281,800,281,800,387, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '132'\n  $floorItems['132'] = i\n  TkcText.new(w,771,334, 'text'=>'132', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,800,168,800,280,699,280,699,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '134'\n  $floorItems['134'] = i\n  TkcText.new(w,749.5,224, 'text'=>'134', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,726,131,726,166,800,166,800,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '135'\n  $floorItems['135'] = i\n  TkcText.new(w,763,148.5, 'text'=>'135', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,340,360,335,363,331,365,326,366,304,366,\n                     304,312,396,312,396,288,400,288,404,288,\n                     409,290,413,292,418,297,421,302,422,309,\n                     421,318,417,325,411,330,405,332,397,333,\n                     344,333,340,334,336,336,335,338,332,342,\n                     331,347,332,351,334,354,336,357,341,359, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Ramona Stair'\n  $floorItems['Ramona Stair'] = i\n  TkcText.new(w,368,323, 'text'=>'Ramona Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,30,23,30,5,93,5,98,5,104,7,110,10,116,16,119,20,\n                     122,28,123,32,123,68,220,68,220,87,90,87,90,23, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'University Stair'\n  $floorItems['University Stair'] = i\n  TkcText.new(w,155,77.5, 'text'=>'University Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,282,37,295,40,312,49,323,56,337,70,352,56,\n                     358,48,363,39,365,29,348,25,335,22,321,14,\n                     300,5,283,1,260,0,246,0,242,2,236,4,231,8,\n                     227,13,223,17,221,22,220,34,260,34, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Plaza Stair'\n  $floorItems['Plaza Stair'] = i\n  TkcText.new(w,317.5,28.5, 'text'=>'Plaza Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,220,34,260,34,282,37,295,40,312,49,\n                     323,56,337,70,350,83,365,94,377,100,\n                     386,104,386,128,220,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = 'Plaza Deck'\n  $floorItems['Plaza Deck'] = i\n  TkcText.new(w,303,81, 'text'=>'Plaza Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,257,336,77,336,6,336,6,301,77,301,77,310,257,310,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '106'\n  $floorItems['106'] = i\n  TkcText.new(w,131.5,318.5, 'text'=>'106', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,146,110,162,110,162,91,130,91,130,115,95,115,\n                     95,128,114,128,114,151,157,151,157,153,112,153,\n                     112,130,97,130,97,168,175,168,175,131,146,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels[i.id] = '119'\n  $floorItems['119'] = i\n  TkcText.new(w,143.5,133, 'text'=>'119', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  TkcLine.new(w,155,191,155,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,155,177,155,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,96,129,96,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,169,176,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,176,247,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,206,307,206, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,187,340,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,210,340,201, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,247,340,224, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,340,241,307,241, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,376,246,376,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,307,247,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,376,170,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,315,129,315,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,147,129,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,202,133,176,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,398,129,315,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,352,258,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,0,337,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,3,114,3,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,237,52,273, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,189,52,225, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,140,52,177, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,395,306,395,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,531,254,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,475,178,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,502,162,398,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,398,129,398,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,383,188,376,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,188,408,194, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,398,227,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,227,398,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,222,408,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,206,408,210, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,408,208,475,208, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,278,484,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,327,508,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,644,391,559,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,644,389,644,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,514,205,475,205, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,496,189,496,187, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,133,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,149,725,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,129,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,802,389,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,739,167,802,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,396,188,408,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,0,337,9,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,58,337,21,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,43,391,43,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,105,337,75,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,91,387,91,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,154,337,117,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,139,387,139,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,227,337,166,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,337,251,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,328,302,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,302,355,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,395,311,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,484,278,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,395,294,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,473,278,473,275, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,473,256,473,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,533,257,531,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,553,276,551,274, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,698,276,553,276, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,559,391,559,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,802,389,644,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,741,314,741,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,698,280,698,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,707,280,698,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,802,280,731,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,741,280,741,302, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,698,167,727,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,725,137,725,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,514,254,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,496,175,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,502,175,502,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,475,166,475,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,496,176,496,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,491,189,496,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,491,205,491,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,487,238,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,487,240,487,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,487,252,487,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,315,133,304,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,256,133,280,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,247,270,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,307,247,294,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,214,133,232,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,217,247,217,266, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,217,309,217,291, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,217,309,172,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,154,309,148,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,175,300,175,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,151,300,175,300, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,151,247,151,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,237,78,265, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,286,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,106,309,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,130,309,125,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,99,309,99,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,127,299,99,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,127,309,127,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,155,191,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,137,169,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,171,78,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,78,190,78,218, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,86,192,86,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,86,192,78,192, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,301,3,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,286,52,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,252,3,252, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,203,3,203, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,3,156,52,156, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,8,25,8,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,63,114,3,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,75,114,97,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,108,114,129,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,129,114,129,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,52,114,52,128, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,132,89,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,88,25,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,88,114,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,218,89,144,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,147,111,147,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,162,111,147,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,162,109,162,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,162,96,162,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,218,89,218,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,218,89,218,119, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,8,25,88,25, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,258,337,258,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,129,96,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,302,355,258,355, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,386,104,386,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,377,100,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,365,94,377,100, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,350,83,365,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,337,70,350,83, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,337,70,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,312,49,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,295,40,312,49, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,282,37,295,40, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,260,34,282,37, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,253,34,260,34, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,386,128,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  TkcLine.new(w,113,152,113,129, 'fill'=>color, 'tags'=>['floor1','wall'])\nend\n\n# floor_fg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the second\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor_fg2(w,color)\n  i = TkcPolygon.new(w,748,188,755,188,755,205,758,205,758,222,\n                     800,222,800,168,748,168, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '238'\n  $floorItems['238'] = i\n  TkcText.new(w,774,195, 'text'=>'238', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,726,188,746,188,746,166,800,166,800,131,726,131,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '237'\n  $floorItems['237'] = i\n  TkcText.new(w,763,148.5, 'text'=>'237', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,497,187,497,204,559,204,559,324,641,324,\n                     643,324,643,291,641,291,641,205,696,205,\n                     696,291,694,291,694,314,715,314,715,291,\n                     715,205,755,205,755,190,724,190,724,187, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '246'\n  $floorItems['246'] = i\n  TkcText.new(w,600,264, 'text'=>'246', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,694,279,643,279,643,314,694,314, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '247'\n  $floorItems['247'] = i\n  TkcText.new(w,668.5,296.5, 'text'=>'247', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,232,250,308,250,308,242,339,242,339,246,\n                     397,246,397,255,476,255,476,250,482,250,559,250,\n                     559,274,482,274,482,278,396,278,396,274,232,274, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '202'\n  $floorItems['202'] = i\n  TkcText.new(w,285.5,260, 'text'=>'202', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,53,228,53,338,176,338,233,338,233,196,\n                     306,196,306,180,175,180,175,169,156,169,\n                     156,196,176,196,176,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '206'\n  $floorItems['206'] = i\n  TkcText.new(w,143,267, 'text'=>'206', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,277,6,277,6,338,51,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '212'\n  $floorItems['212'] = i\n  TkcText.new(w,28.5,307.5, 'text'=>'212', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,276,486,276,486,309,510,309,510,325,557,325, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '245'\n  $floorItems['245'] = i\n  TkcText.new(w,521.5,300.5, 'text'=>'245', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,560,389,599,389,599,326,560,326, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '244'\n  $floorItems['244'] = i\n  TkcText.new(w,579.5,357.5, 'text'=>'244', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,601,389,601,326,643,326,643,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '243'\n  $floorItems['243'] = i\n  TkcText.new(w,622,357.5, 'text'=>'243', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,688,316,645,316,645,365,688,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '242'\n  $floorItems['242'] = i\n  TkcText.new(w,666.5,340.5, 'text'=>'242', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,802,367,759,367,759,226,802,226, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = 'Barbecue Deck'\n  $floorItems['Barbecue Deck'] = i\n  TkcText.new(w,780.5,296.5, 'text'=>'Barbecue Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,262,755,314,717,314,717,262, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '240'\n  $floorItems['240'] = i\n  TkcText.new(w,736,288, 'text'=>'240', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,316,689,316,689,365,755,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '241'\n  $floorItems['241'] = i\n  TkcText.new(w,722,340.5, 'text'=>'241', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,206,717,206,717,261,755,261, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '239'\n  $floorItems['239'] = i\n  TkcText.new(w,736,233.5, 'text'=>'239', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,695,277,643,277,643,206,695,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '248'\n  $floorItems['248'] = i\n  TkcText.new(w,669,241.5, 'text'=>'248', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,676,135,676,185,724,185,724,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '236'\n  $floorItems['236'] = i\n  TkcText.new(w,700,160, 'text'=>'236', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,675,135,635,135,635,145,628,145,628,185,675,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '235'\n  $floorItems['235'] = i\n  TkcText.new(w,651.5,160, 'text'=>'235', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,626,143,633,143,633,135,572,135,\n                     572,143,579,143,579,185,626,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '234'\n  $floorItems['234'] = i\n  TkcText.new(w,606,160, 'text'=>'234', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,135,571,135,571,145,578,145,\n                     578,185,527,185,527,131,557,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '233'\n  $floorItems['233'] = i\n  TkcText.new(w,552.5,158, 'text'=>'233', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,249,557,249,557,205,476,205,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '230'\n  $floorItems['230'] = i\n  TkcText.new(w,516.5,227, 'text'=>'230', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,164,486,164,486,131,525,131,525,185,476,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '232'\n  $floorItems['232'] = i\n  TkcText.new(w,500.5,158, 'text'=>'232', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,186,495,186,495,204,476,204, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '229'\n  $floorItems['229'] = i\n  TkcText.new(w,485.5,195, 'text'=>'229', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,474,207,409,207,409,187,399,187,399,164,474,164, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '227'\n  $floorItems['227'] = i\n  TkcText.new(w,436.5,185.5, 'text'=>'227', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,399,228,399,253,474,253,474,209,409,209,409,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '228'\n  $floorItems['228'] = i\n  TkcText.new(w,436.5,231, 'text'=>'228', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,397,246,397,226,407,226,407,189,377,189,377,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '226'\n  $floorItems['226'] = i\n  TkcText.new(w,392,217.5, 'text'=>'226', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,377,169,316,169,316,131,397,131,397,188,377,188, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '225'\n  $floorItems['225'] = i\n  TkcText.new(w,356.5,150, 'text'=>'225', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,198,306,198,306,249,234,249, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '224'\n  $floorItems['224'] = i\n  TkcText.new(w,270,223.5, 'text'=>'224', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,270,179,306,179,306,170,314,170,314,135,270,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '223'\n  $floorItems['223'] = i\n  TkcText.new(w,292,157, 'text'=>'223', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,268,179,221,179,221,135,268,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '222'\n  $floorItems['222'] = i\n  TkcText.new(w,244.5,157, 'text'=>'222', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,177,179,219,179,219,135,177,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '221'\n  $floorItems['221'] = i\n  TkcText.new(w,198,157, 'text'=>'221', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,299,327,349,327,349,284,341,284,341,276,299,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '204'\n  $floorItems['204'] = i\n  TkcText.new(w,324,301.5, 'text'=>'204', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,276,297,276,297,327,257,327,257,338,234,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '205'\n  $floorItems['205'] = i\n  TkcText.new(w,265.5,307, 'text'=>'205', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,256,385,256,340,212,340,212,385,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '207'\n  $floorItems['207'] = i\n  TkcText.new(w,234,362.5, 'text'=>'207', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,210,340,164,340,164,385,210,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '208'\n  $floorItems['208'] = i\n  TkcText.new(w,187,362.5, 'text'=>'208', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,115,340,162,340,162,385,115,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '209'\n  $floorItems['209'] = i\n  TkcText.new(w,138.5,362.5, 'text'=>'209', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,228,89,156,53,156,53,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '217'\n  $floorItems['217'] = i\n  TkcText.new(w,71,192, 'text'=>'217', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,169,97,169,97,190,89,190, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '217A'\n  $floorItems['217A'] = i\n  TkcText.new(w,93,179.5, 'text'=>'217A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,156,89,168,95,168,95,135,53,135,53,156, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '216'\n  $floorItems['216'] = i\n  TkcText.new(w,71,145.5, 'text'=>'216', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,179,51,135,6,135,6,179, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '215'\n  $floorItems['215'] = i\n  TkcText.new(w,28.5,157, 'text'=>'215', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,227,6,227,6,180,51,180, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '214'\n  $floorItems['214'] = i\n  TkcText.new(w,28.5,203.5, 'text'=>'214', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,275,6,275,6,229,51,229, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '213'\n  $floorItems['213'] = i\n  TkcText.new(w,28.5,252, 'text'=>'213', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,114,340,67,340,67,385,114,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '210'\n  $floorItems['210'] = i\n  TkcText.new(w,90.5,362.5, 'text'=>'210', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,59,389,59,385,65,385,65,340,1,340,1,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '211'\n  $floorItems['211'] = i\n  TkcText.new(w,33,364.5, 'text'=>'211', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,393,309,350,309,350,282,342,282,342,276,393,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '203'\n  $floorItems['203'] = i\n  TkcText.new(w,367.5,292.5, 'text'=>'203', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,99,191,91,191,91,226,174,226,174,198,\n                     154,198,154,192,109,192,109,169,99,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '220'\n  $floorItems['220'] = i\n  TkcText.new(w,132.5,208.5, 'text'=>'220', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = 'Priv Lift2'\n  $floorItems['Priv Lift2'] = i\n  TkcText.new(w,323,188, 'text'=>'Priv Lift2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = 'Pub Lift 2'\n  $floorItems['Pub Lift 2'] = i\n  TkcText.new(w,323,223, 'text'=>'Pub Lift 2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '218'\n  $floorItems['218'] = i\n  TkcText.new(w,136,149.5, 'text'=>'218', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '219'\n  $floorItems['219'] = i\n  TkcText.new(w,132.5,180, 'text'=>'219', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels[i.id] = '201'\n  $floorItems['201'] = i\n  TkcText.new(w,358,209, 'text'=>'201', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  TkcLine.new(w,641,186,678,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,350,757,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,634,133,634,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,634,144,627,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,572,133,572,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,572,144,579,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,129,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,174,197,175,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,175,197,175,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,206,757,221, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,396,188,408,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,727,189,725,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,747,167,802,167, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,747,167,747,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,755,189,739,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,769,224,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,802,224,802,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,802,129,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,725,189,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,725,186,690,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,676,133,676,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,627,144,627,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,629,186,593,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,579,144,579,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,559,129,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,725,133,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,162,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,559,129,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,526,129,526,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,540,186,581,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,528,186,523,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,511,186,475,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,496,190,496,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,496,205,496,202, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,475,205,527,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,205,539,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,205,558,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,249,475,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,662,206,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,695,206,675,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,695,278,642,278, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,642,291,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,695,291,695,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,716,208,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,206,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,221,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,793,224,802,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,262,716,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,716,220,716,264, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,716,315,716,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,315,703,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,325,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,757,367,644,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,689,367,689,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,647,315,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,659,315,691,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,600,325,600,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,627,325,644,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,644,391,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,615,325,575,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,644,391,558,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,563,325,558,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,391,558,314, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,327,508,327, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,275,484,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,558,302,558,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,508,327,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,311,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,275,484,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,475,208,408,208, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,206,408,210, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,222,408,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,227,398,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,227,398,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,408,188,408,194, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,383,188,376,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,188,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,162,484,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,475,162,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,254,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,484,280,395,280, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,395,311,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,307,197,293,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,278,197,233,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,233,197,233,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,307,179,284,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,233,249,278,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,269,179,269,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,220,179,220,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,155,191,110,191, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,90,190,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,98,169,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,133,52,165, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,214,52,177, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,226,52,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,274,52,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,234,275,234,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,226,339,258,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,211,387,211,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,214,339,177,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,258,387,60,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,3,133,3,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,165,339,129,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,117,339,80,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,68,339,59,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,0,339,46,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,0,339,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,60,387,60,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,258,329,258,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,395,311,350,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,398,129,315,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,176,133,315,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,3,133,96,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,66,387,66,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,115,387,115,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,163,387,163,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,234,275,276,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,288,275,309,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,298,275,298,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,341,283,350,283, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,321,275,341,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,375,275,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,315,129,315,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,376,170,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,307,250,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,376,245,376,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,241,307,241, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,245,340,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,210,340,201, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,187,340,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,340,206,307,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,293,250,307,250, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,271,179,238,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,226,179,195,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,176,129,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,182,179,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,174,169,176,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,162,169,90,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,96,169,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,175,227,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,90,190,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,179,3,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,228,3,228, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,52,276,3,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,155,177,155,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,110,191,110,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,155,189,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,350,283,350,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,162,197,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  TkcLine.new(w,341,275,341,283, 'fill'=>color, 'tags'=>['floor2','wall'])\nend\n\n# floor_fg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the third\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor_fg3(w,color)\n  i = TkcPolygon.new(w,89,228,89,180,70,180,70,228,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '316'\n  $floorItems['316'] = i\n  TkcText.new(w,79.5,204, 'text'=>'316', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,115,368,162,368,162,323,115,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '309'\n  $floorItems['309'] = i\n  TkcText.new(w,138.5,345.5, 'text'=>'309', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,164,323,164,368,211,368,211,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '308'\n  $floorItems['308'] = i\n  TkcText.new(w,187.5,345.5, 'text'=>'308', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,256,368,212,368,212,323,256,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '307'\n  $floorItems['307'] = i\n  TkcText.new(w,234,345.5, 'text'=>'307', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,244,276,297,276,297,327,260,327,260,321,244,321, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '305'\n  $floorItems['305'] = i\n  TkcText.new(w,270.5,301.5, 'text'=>'305', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,219,251,203,244,203,244,219,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '324B'\n  $floorItems['324B'] = i\n  TkcText.new(w,247.5,211, 'text'=>'324B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,249,244,249,244,232,251,232, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '324A'\n  $floorItems['324A'] = i\n  TkcText.new(w,247.5,240.5, 'text'=>'324A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,223,135,223,179,177,179,177,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '320'\n  $floorItems['320'] = i\n  TkcText.new(w,200,157, 'text'=>'320', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,114,368,114,323,67,323,67,368, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '310'\n  $floorItems['310'] = i\n  TkcText.new(w,90.5,345.5, 'text'=>'310', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,277,23,321,68,321,68,277, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '312'\n  $floorItems['312'] = i\n  TkcText.new(w,45.5,299, 'text'=>'312', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,229,68,229,68,275,23,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '313'\n  $floorItems['313'] = i\n  TkcText.new(w,45.5,252, 'text'=>'313', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,68,227,23,227,23,180,68,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '314'\n  $floorItems['314'] = i\n  TkcText.new(w,40.5,203.5, 'text'=>'314', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,95,179,95,135,23,135,23,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '315'\n  $floorItems['315'] = i\n  TkcText.new(w,59,157, 'text'=>'315', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,99,226,99,204,91,204,91,226, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '316B'\n  $floorItems['316B'] = i\n  TkcText.new(w,95,215, 'text'=>'316B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,91,202,99,202,99,180,91,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '316A'\n  $floorItems['316A'] = i\n  TkcText.new(w,95,191, 'text'=>'316A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,97,169,109,169,109,192,154,192,154,198,\n                     174,198,174,226,101,226,101,179,97,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '319'\n  $floorItems['319'] = i\n  TkcText.new(w,141.5,209, 'text'=>'319', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,65,368,58,368,58,389,1,389,1,333,23,333,23,323,65,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '311'\n  $floorItems['311'] = i\n  TkcText.new(w,29.5,361, 'text'=>'311', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '318'\n  $floorItems['318'] = i\n  TkcText.new(w,132.5,180, 'text'=>'318', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '317'\n  $floorItems['317'] = i\n  TkcText.new(w,136,149.5, 'text'=>'317', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,274,194,274,221,306,221,306,194, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '323'\n  $floorItems['323'] = i\n  TkcText.new(w,290,207.5, 'text'=>'323', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,306,222,274,222,274,249,306,249, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '325'\n  $floorItems['325'] = i\n  TkcText.new(w,290,235.5, 'text'=>'325', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,263,179,224,179,224,135,263,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '321'\n  $floorItems['321'] = i\n  TkcText.new(w,243.5,157, 'text'=>'321', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,314,169,306,169,306,192,273,192,\n                     264,181,264,135,314,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '322'\n  $floorItems['322'] = i\n  TkcText.new(w,293.5,163.5, 'text'=>'322', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = 'Pub Lift3'\n  $floorItems['Pub Lift3'] = i\n  TkcText.new(w,323,223, 'text'=>'Pub Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = 'Priv Lift3'\n  $floorItems['Priv Lift3'] = i\n  TkcText.new(w,323,188, 'text'=>'Priv Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,350,284,376,284,376,276,397,276,397,309,350,309, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '303'\n  $floorItems['303'] = i\n  TkcText.new(w,373.5,292.5, 'text'=>'303', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,272,203,272,249,252,249,252,230,\n                     244,230,244,221,252,221,252,203, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '324'\n  $floorItems['324'] = i\n  TkcText.new(w,262,226, 'text'=>'324', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,299,276,299,327,349,327,349,284,341,284,341,276, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '304'\n  $floorItems['304'] = i\n  TkcText.new(w,324,301.5, 'text'=>'304', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '301'\n  $floorItems['301'] = i\n  TkcText.new(w,358,209, 'text'=>'301', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,397,246,377,246,377,185,397,185, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '327'\n  $floorItems['327'] = i\n  TkcText.new(w,387,215.5, 'text'=>'327', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,316,131,316,169,377,169,377,185,397,185,397,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '326'\n  $floorItems['326'] = i\n  TkcText.new(w,365.5,150, 'text'=>'326', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,308,251,242,251,242,274,342,274,342,282,375, 282,\n                     375,274,397,274,397,248,339,248,339,242,308,242, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '302'\n  $floorItems['302'] = i\n  TkcText.new(w,319.5,261, 'text'=>'302', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,70,321,242,321,242,200,259,200,259,203,272,203,\n                     272,193,263,180,242,180,175,180,175,169,156,169,\n                     156,196,177,196,177,228,107,228,70,228,70,275,107,275,\n                     107,248,160,248,160,301,107,301,107,275,70,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels[i.id] = '306'\n  $floorItems['306'] = i\n  TkcText.new(w,200.5,284.5, 'text'=>'306', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  TkcLine.new(w,341,275,341,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,162,197,155,197, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,396,247,399,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,399,129,399,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,202,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,350,283,350,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,251,231,243,231, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,220,251,220, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,250,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,155,197,155,190, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,110,192,110,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,155,192,110,192, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,155,177,155,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,176,197,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,69,280,69,274, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,276,69,276, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,69,262,69,226, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,228,69,228, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,179,75,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,69,179,69,214, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,220,90,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,204,90,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,203,100,203, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,187,90,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,90,227,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,100,179,100,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,100,179,87,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,96,179,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,162,169,96,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,173,169,176,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,182,179,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,176,129,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,195,179,226,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,224,133,224,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,264,179,264,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,238,179,264,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,207,273,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,235,273,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,224,273,219, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,193,307,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,222,307,222, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,384,247,376,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,206,307,206, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,187,340,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,210,340,201, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,247,340,224, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,340,241,307,241, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,247,376,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,307,250,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,170,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,315,129,315,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,283,366,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,376,283,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,399,275,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,341,275,320,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,341,283,350,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,298,275,298,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,308,275,298,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,322,243,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,243,275,284,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,322,226,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,212,370,212,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,214,322,177,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,163,370,163,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,165,322,129,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,84,322,117,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,71,322,64,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,115,322,115,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,66,322,66,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,52,322,21,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,331,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,21,331,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,96,133,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,176,129,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,315,133,176,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,315,129,399,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,399,311,350,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,350,329,258,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,322,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,60,370,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,60,370,60,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,0,391,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,60,391,0,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,307,250,307,242, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  TkcLine.new(w,258,250,243,250, 'fill'=>color, 'tags'=>['floor3','wall'])\nend\n\n# Below is the \"main program\" that creates the floorplan demonstration.\n\n# toplevel widget ¸ߤк\nif defined?($floor_demo) && $floor_demo\n  $floor_demo.destroy \n  $floor_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$floor_demo = TkToplevel.new {|w|\n  title(\"Floorplan Canvas Demonstration\")\n  iconname(\"Floorplan\")\n  positionWindow(w)\n  geometry('+20+20')\n  minsize(100,100)\n}\n\nbase_frame = TkFrame.new($floor_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', \n            'text'=>\"Υɥˤϥǥ륨åץȼҤΥꥵܥȥ (DECWRL) δּ꤬񤫤줿Х widget äƤޤ 3ƤǡˤΤ1ʬ򡢤Ĥޤꤽδּ꤬ɽ褦ˤʤäƤޤ볬򤹤ˤϡξǥޥκܥ򥯥åƤޥ򤵤Ƥ볬ξưȡβˤοѤꡢֹ椬ֹ:ץȥɽޤޤȥֹ񤯤ȤοѤޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$floor_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $floor_demo\n      $floor_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'floor'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$floor_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# ѿ\n$floorLabels = {}\n$floorItems = {}\n\n# canvas \nif $tk_version =~ /^4\\.[01]/\n  $floor_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken',\n                                    'highlightthickness'=>2)\n  $floor_canvas = TkCanvas.new($floor_canvas_frame, \n                               'width'=>900, 'height'=>500, 'borderwidth'=>0, \n                               'highlightthickness'=>0) {|c|\n    TkScrollbar.new(base_frame, 'orient'=>'horiz', \n                    'command'=>proc{|*args| c.xview(*args)}){|hs|\n      c.xscrollcommand(proc{|first,last| hs.set first,last})\n      pack('side'=>'bottom', 'fill'=>'x')\n    }\n    TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs|\n      c.yscrollcommand(proc{|first,last| vs.set first,last})\n      pack('side'=>'right', 'fill'=>'y')\n    }\n  }\n  $floor_canvas_frame.pack('side'=>'top','fill'=>'both', 'expand'=>'yes')\n  $floor_canvas.pack('expand'=>'yes', 'fill'=>'both')\n\nelse\n  TkFrame.new(base_frame) {|f|\n    pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\n    h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal')\n    v = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'vertical')\n\n    TkFrame.new(f, 'bd'=>2, 'relief'=>'sunken') {|f1|\n      $floor_canvas = TkCanvas.new(f1, 'width'=>900, 'height'=>500, \n                                   'borderwidth'=>0, \n                                   'highlightthickness'=>0) {\n        xscrollcommand(proc{|first,last| h.set first,last})\n        yscrollcommand(proc{|first,last| v.set first,last})\n        pack('expand'=>'yes', 'fill'=>'both')\n      }\n      grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    }\n\n    v.grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    h.grid('padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n\n    TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n\n    pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n\n    v.command(proc{|*args| $floor_canvas.yview(*args)})\n    h.command(proc{|*args| $floor_canvas.xview(*args)})\n  }\nend\n\n\n# Create an entry for displaying and typing in current room.\n\n$currentRoom = TkVariable.new\n$floor_entry = TkEntry.new($floor_canvas, 'width'=>10, 'relief'=>'sunken', \n                           'bd'=>2, 'textvariable'=>$currentRoom)\n\n# Choose colors, then fill in the floorplan.\n\n$floor_colors = {}\nif TkWinfo.depth($floor_canvas) > 1\n  $floor_colors['bg1'] = '#a9c1da'\n  $floor_colors['outline1'] = '#77889a'\n  $floor_colors['bg2'] = '#9ab0c6'\n  $floor_colors['outline2'] = '#687786'\n  $floor_colors['bg3'] = '#8ba0b3'\n  $floor_colors['outline3'] = '#596673'\n  $floor_colors['offices'] = 'Black'\n  $floor_colors['active'] = '#c4d1df'\nelse\n  $floor_colors['bg1'] = 'white'\n  $floor_colors['outline1'] = 'black'\n  $floor_colors['bg2'] = 'white'\n  $floor_colors['outline2'] = 'black'\n  $floor_colors['bg3'] = 'white'\n  $floor_colors['outline3'] = 'black'\n  $floor_colors['offices'] = 'Black'\n  $floor_colors['active'] = 'black'\nend\n\n$activeFloor = ''\nfloorDisplay $floor_canvas,3\n\n# Set up event bindings for canvas:\n\n$floor_canvas.itembind('floor1', '1', proc{floorDisplay $floor_canvas,1})\n$floor_canvas.itembind('floor2', '1', proc{floorDisplay $floor_canvas,2})\n$floor_canvas.itembind('floor3', '1', proc{floorDisplay $floor_canvas,3})\n$floor_canvas.itembind('room', 'Enter', proc{newRoom $floor_canvas})\n$floor_canvas.itembind('room', 'Leave', proc{$currentRoom.value = ''})\n$floor_canvas.bind('2', proc{|x,y| $floor_canvas.scan_mark x,y}, '%x %y')\n$floor_canvas.bind('B2-Motion', \n                   proc{|x,y| $floor_canvas.scan_dragto x,y}, '%x %y')\n$floor_canvas.bind('Destroy', proc{$currentRoom.unset})\n$currentRoom.value = ''\n$currentRoom.trace('w',proc{roomChanged $floor_canvas})\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/floor2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# floorDisplay widget demo 2 (called by 'widget')\n#\n\n# floorDisplay2 --\n# Recreate the floorplan display in the canvas given by \"w\".  The\n# floor given by \"active\" is displayed on top with its office structure\n# visible.\n#\n# Arguments:\n# w -           Name of the canvas window.\n# active -      Number of active floor (1, 2, or 3).\n\ndef floorDisplay2(w,active)\n  return if $activeFloor2 == active\n\n  w.delete('all')\n  $activeFloor2 = active\n\n  # First go through the three floors, displaying the backgrounds for \n  # each floor.\n\n  floor2_bg1(w,$floor2_colors['bg1'],$floor2_colors['outline1'])\n  floor2_bg2(w,$floor2_colors['bg2'],$floor2_colors['outline2'])\n  floor2_bg3(w,$floor2_colors['bg3'],$floor2_colors['outline3'])\n\n  # Raise the background for the active floor so that it's on top.\n\n  w.raise(\"floor#{active}\")\n\n  # Create a dummy item just to mark this point in the display list, \n  # so we can insert highlights here.\n\n  w.create(TkcRectangle,0,100,1,101,'fill'=>'','outline'=>'','tags'=>'marker')\n\n  # Add the walls and labels for the active floor, along with \n  # transparent polygons that define the rooms on the floor.\n  # Make sure that the room polygons are on top.\n\n  $floorLabels2.clear\n  $floorItems2.clear\n  send(\"floor2_fg#{active}\", w, $floor2_colors['offices'])\n  w.raise('room')\n\n  # Offset the floors diagonally from each other.\n\n  w.move('floor1', '2c', '2c')\n  w.move('floor2', '1c', '1c')\n\n  # Create items for the room entry and its label.\n  w.create(TkcWindow, 600, 100, 'anchor'=>'w', 'window'=>$floor2_entry)\n  w.create(TkcText, 600, 100, 'anchor'=>'e', 'text'=>\"ֹ: \")\n  w['scrollregion'] = w.bbox('all')\nend\n\n# newRoom2 --\n# This method is invoked whenever the mouse enters a room\n# in the floorplan.  It changes tags so that the current room is\n# highlighted.\n#\n# Arguments:\n# w  -          The name of the canvas window.\n\ndef newRoom2(w)\n  id = w.find_withtag('current')[0]\n  $currentRoom2.value = $floorLabels2[id.id] if id != \"\"\n  Tk.update(true)\nend\n\n# roomChanged2 --\n# This method is invoked whenever the currentRoom variable changes.\n# It highlights the current room and unhighlights any previous room.\n#\n# Arguments:\n# w -           The canvas window displaying the floorplan.\n# args -        Not used.\n\ndef roomChanged2(w,*args)\n  w.delete('highlight')\n  item = $floorItems2[$currentRoom2.value]\n  return if item == nil\n  new = TkcPolygon.new(w, *(w.coords(item)))\n  new.configure('fill'=>$floor2_colors['active'], 'tags'=>'highlight')\n  w.raise(new, 'marker')\nend\n\n# floor2_bg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor2_bg1(w,fill,outline)\n  w.create(TkcPolygon,347,80,349,82,351,84,353,85,363,92,375,99,386,104,\n                 386,129,398,129,398,162,484,162,484,129,559,129,559,133,725,\n                 133,725,129,802,129,802,389,644,389,644,391,559,391,559,327,\n                 508,327,508,311,484,311,484,278,395,278,395,288,400,288,404,\n                 288,409,290,413,292,418,297,421,302,422,309,421,318,417,325,\n                 411,330,405,332,397,333,344,333,340,334,336,336,335,338,332,\n                 342,331,347,332,351,334,354,336,357,341,359,340,360,335,363,\n                 331,365,326,366,304,366,304,355,258,355,258,387,60,387,60,391,\n                 0,391,0,337,3,337,3,114,8,114,8,25,30,25,30,5,93,5,98,5,104,7,\n                 110,10,116,16,119,20,122,28,123,32,123,68,220,68,220,34,221,\n                 22,223,17,227,13,231,8,236,4,242,2,246,0,260,0,283,1,300,5,\n                 321,14,335,22,348,25,365,29,363,39,358,48,352,56,337,70,\n                 344,76,347,80, 'tags'=>['floor1','bg'], 'fill'=>fill)\n  w.create(TkcLine,386,129,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,258,355,258,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,0,337,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,3,114,3,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,162,398,162, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,398,162,398,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,278,484,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,327,508,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,644,391,559,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,644,389,644,391, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,725,133,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,725,129,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,802,389,802,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,3,337,0,337, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,559,391,559,327, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,802,389,644,389, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,8,25,8,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,8,114,3,114, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,30,25,8,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,484,278,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,30,25,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,93,5,30,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,98,5,93,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,104,7,98,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,110,10,104,7, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,116,16,110,10, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,119,20,116,16, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,122,28,119,20, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,123,32,122,28, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,123,68,123,32, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,220,68,123,68, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,386,129,386,104, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,386,104,375,99, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,375,99,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,353,85,363,92, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,220,68,220,34, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,337,70,352,56, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,352,56,358,48, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,358,48,363,39, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,363,39,365,29, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,365,29,348,25, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,348,25,335,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,335,22,321,14, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,321,14,300,5, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,300,5,283,1, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,283,1,260,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,260,0,246,0, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,246,0,242,2, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,242,2,236,4, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,236,4,231,8, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,231,8,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,223,17,227,13, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,221,22,223,17, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,220,34,221,22, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,340,360,335,363, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,335,363,331,365, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,331,365,326,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,326,366,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,304,355,304,366, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,395,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,404,288,400,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,409,290,404,288, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,413,292,409,290, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,418,297,413,292, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,421,302,418,297, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,422,309,421,302, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,421,318,422,309, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,421,318,417,325, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,417,325,411,330, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,411,330,405,332, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,405,332,397,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,397,333,344,333, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,344,333,340,334, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,340,334,336,336, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,336,336,335,338, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,335,338,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,331,347,332,342, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,332,351,331,347, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,334,354,332,351, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,336,357,334,354, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,341,359,336,357, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,341,359,340,360, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,395,288,395,278, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,304,355,258,355, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,347,80,344,76, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,344,76,337,70, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,349,82,347,80, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,351,84,349,82, 'fill'=>outline, 'tags'=>['floor1','bg'])\n  w.create(TkcLine,353,85,351,84, 'fill'=>outline, 'tags'=>['floor1','bg'])\nend\n\n# floor2_bg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor2_bg2(w,fill,outline)\n  w.create(TkcPolygon,559,129,484,129,484,162,398,162,398,129,315,129,\n                 315,133,176,133,176,129,96,129,96,133,3,133,3,339,0,339,0,391,\n                 60,391,60,387,258,387,258,329,350,329,350,311,395,311,395,280,\n                 484,280,484,311,508,311,508,327,558,327,558,391,644,391,644,\n                 367,802,367,802,129,725,129,725,133,559,133,559,129,\n                 'tags'=>['floor2','bg'], 'fill'=>fill)\n  w.create(TkcLine,350,311,350,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,398,129,398,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,802,367,802,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,802,129,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,725,133,725,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,559,133,725,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,802,367,644,367, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,644,367,644,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,644,391,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,558,327,558,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,558,327,508,327, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,280,484,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,398,162,484,162, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,484,280,395,280, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,395,280,395,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,3,133,3,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,3,339,0,339, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,0,339,0,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,258,329,258,387, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,395,311,350,311, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,398,129,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,176,133,315,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,3,133,96,133, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,176,133,176,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\n  w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor2','bg'])\nend\n\n# floor2_bg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the background information for the first\n# floor.\n#\n# Arguments:\n# w -           The canvas window.\n# fill -        Fill color to use for the floor's background.\n# outline -     Color to use for the floor's outline.\n\ndef floor2_bg3(w,fill,outline)\n  w.create(TkcPolygon,159,300,107,300,107,248,159,248,159,129,96,129,96,\n                 133,21,133,21,331,0,331,0,391,60,391,60,370,159,370,159,300,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  w.create(TkcPolygon,258,370,258,329,350,329,350,311,399,311,399,129,\n                 315,129,315,133,176,133,176,129,159,129,159,370,258,370,\n                 'tags'=>['floor3','bg'], 'fill'=>fill)\n  w.create(TkcLine,96,133,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,176,129,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,315,133,176,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,315,133,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,399,129,315,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,399,311,399,129, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,399,311,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,350,329,350,311, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,258,370,258,329, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,60,370,258,370, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,60,370,60,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,0,391,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,21,331,0,331, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,21,331,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,96,133,21,133, 'fill'=>outline, 'tags'=>['floor3','bg'])\n  w.create(TkcLine,107,300,159,300,159,248,107,248,107,300, \n              'fill'=>outline, 'tags'=>['floor3','bg'])\nend\n\n# floor2_fg1 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the first\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor2_fg1(w,color)\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '101'\n  $floorItems2['101'] = i\n  w.create(TkcText,358,209, 'text'=>'101', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Pub Lift1'\n  $floorItems2['Pub Lift1'] = i\n  w.create(TkcText,323,223, 'text'=>'Pub Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Priv Lift1'\n  $floorItems2['Priv Lift1'] = i\n  w.create(TkcText,323,188, 'text'=>'Priv Lift1', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,42,389,42,337,1,337,1,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '110'\n  $floorItems2['110'] = i\n  w.create(TkcText,21.5,363, 'text'=>'110', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,59,389,59,385,90,385,90,337,44,337,44,389, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '109'\n  $floorItems2['109'] = i\n  w.create(TkcText,67,363, 'text'=>'109', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,300,51,253,6,253,6,300, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '111'\n  $floorItems2['111'] = i\n  w.create(TkcText,28.5,276.5, 'text'=>'111', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,98,248,98,309,79,309,79,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '117B'\n  $floorItems2['117B'] = i\n  w.create(TkcText,88.5,278.5, 'text'=>'117B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,251,51,204,6,204,6,251, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '112'\n  $floorItems2['112'] = i\n  w.create(TkcText,28.5,227.5, 'text'=>'112', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,6,156,51,156,51,203,6,203, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '113'\n  $floorItems2['113'] = i\n  w.create(TkcText,28.5,179.5, 'text'=>'113', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,85,169,79,169,79,192,85,192, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '117A'\n  $floorItems2['117A'] = i\n  w.create(TkcText,82,180.5, 'text'=>'117A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,77,302,77,168,53,168,53,302, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '117'\n  $floorItems2['117'] = i\n  w.create(TkcText,65,235, 'text'=>'117', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,51,155,51,115,6,115,6,155, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '114'\n  $floorItems2['114'] = i\n  w.create(TkcText,28.5,135, 'text'=>'114', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,95,115,53,115,53,168,95,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '115'\n  $floorItems2['115'] = i\n  w.create(TkcText,74,141.5, 'text'=>'115', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,87,113,87,27,10,27,10,113, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '116'\n  $floorItems2['116'] = i\n  w.create(TkcText,48.5,70, 'text'=>'116', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,89,91,128,91,128,113,89,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '118'\n  $floorItems2['118'] = i\n  w.create(TkcText,108.5,102, 'text'=>'118', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,178,128,178,132,216,132,216,91,\n                     163,91,163,112,149,112,149,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '120'\n  $floorItems2['120'] = i\n  w.create(TkcText,189.5,111.5, 'text'=>'120', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,79,193,87,193,87,169,136,169,136,192,\n                     156,192,156,169,175,169,175,246,79,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '122'\n  $floorItems2['122'] = i\n  w.create(TkcText,131,207.5, 'text'=>'122', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,169,154,169,154,191,138,191, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '121'\n  $floorItems2['121'] = i\n  w.create(TkcText,146,180, 'text'=>'121', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,99,300,126,300,126,309,99,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '106A'\n  $floorItems2['106A'] = i\n  w.create(TkcText,112.5,304.5, 'text'=>'106A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,128,299,128,309,150,309,150,248,99,248,99,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '105'\n  $floorItems2['105'] = i\n  w.create(TkcText,124.5,278.5, 'text'=>'105', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,174,309,174,300,152,300,152,309, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '106B'\n  $floorItems2['106B'] = i\n  w.create(TkcText,163,304.5, 'text'=>'106B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,176,299,176,309,216,309,216,248,152,248,152,299, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '104'\n  $floorItems2['104'] = i\n  w.create(TkcText,184,278.5, 'text'=>'104', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,138,385,138,337,91,337,91,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '108'\n  $floorItems2['108'] = i\n  w.create(TkcText,114.5,361, 'text'=>'108', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,256,337,140,337,140,385,256,385, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '107'\n  $floorItems2['107'] = i\n  w.create(TkcText,198,361, 'text'=>'107', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,300,353,300,329,260,329,260,353, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Smoking'\n  $floorItems2['Smoking'] = i\n  w.create(TkcText,280,341, 'text'=>'Smoking', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,314,135,314,170,306,170,306,246,177,246,177,135, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '123'\n  $floorItems2['123'] = i\n  w.create(TkcText,245.5,190.5, 'text'=>'123', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,217,248,301,248,301,326,257,326,257,310,217,310, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '103'\n  $floorItems2['103'] = i\n  w.create(TkcText,259,287, 'text'=>'103', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,396,188,377,188,377,169,316,169,316,131,396,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '124'\n  $floorItems2['124'] = i\n  w.create(TkcText,356,150, 'text'=>'124', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,226,407,226,407,189,377,189,377,246,397,246, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '125'\n  $floorItems2['125'] = i\n  w.create(TkcText,392,217.5, 'text'=>'125', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,399,187,409,187,409,207,474,207,474,164,399,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '126'\n  $floorItems2['126'] = i\n  w.create(TkcText,436.5,185.5, 'text'=>'126', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,409,209,409,229,399,229,399,253,\n                     486,253,486,239,474,239,474,209, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '127'\n  $floorItems2['127'] = i\n  w.create(TkcText,436.5,'231', 'text'=>'127', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,501,164,501,174,495,174,495,188,\n                     490,188,490,204,476,204,476,164, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'MShower'\n  $floorItems2['MShower'] = i\n  w.create(TkcText,488.5,'184', 'text'=>'MShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,497,176,513,176,513,204,492,204,492,190,497,190, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Closet'\n  $floorItems2['Closet'] = i\n  w.create(TkcText,502.5,190, 'text'=>'Closet', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,476,237,476,206,513,206,513,254,488,254,488,237, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'WShower'\n  $floorItems2['WShower'] = i\n  w.create(TkcText,494.5,230, 'text'=>'WShower', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,486,131,558,131,558,135,724,135,724,166,\n                     697,166,697,275,553,275,531,254,515,254,\n                     515,174,503,174,503,161,486,161, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '130'\n  $floorItems2['130'] = i\n  w.create(TkcText,638.5,205, 'text'=>'130', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,308,242,339,242,339,248,342,248,\n                     342,246,397,246,397,276,393,276,\n                     393,309,300,309,300,248,308,248, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '102'\n  $floorItems2['102'] = i\n  w.create(TkcText,367.5,278.5, 'text'=>'102', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,397,255,486,255,486,276,397,276, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '128'\n  $floorItems2['128'] = i\n  w.create(TkcText,441.5,265.5, 'text'=>'128', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,510,309,486,309,486,255,530,255,\n                     552,277,561,277,561,325,510,325,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '129'\n  $floorItems2['129'] = i\n  w.create(TkcText,535.5,293, 'text'=>'129', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,696,281,740,281,740,387,642,387,\n                     642,389,561,389,561,277,696,277, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '133'\n  $floorItems2['133'] = i\n  w.create(TkcText,628.5,335, 'text'=>'133', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,742,387,742,281,800,281,800,387, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '132'\n  $floorItems2['132'] = i\n  w.create(TkcText,771,334, 'text'=>'132', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,800,168,800,280,699,280,699,168, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '134'\n  $floorItems2['134'] = i\n  w.create(TkcText,749.5,224, 'text'=>'134', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,726,131,726,166,800,166,800,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '135'\n  $floorItems2['135'] = i\n  w.create(TkcText,763,148.5, 'text'=>'135', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,340,360,335,363,331,365,326,366,304,366,\n                     304,312,396,312,396,288,400,288,404,288,\n                     409,290,413,292,418,297,421,302,422,309,\n                     421,318,417,325,411,330,405,332,397,333,\n                     344,333,340,334,336,336,335,338,332,342,\n                     331,347,332,351,334,354,336,357,341,359, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Ramona Stair'\n  $floorItems2['Ramona Stair'] = i\n  w.create(TkcText,368,323, 'text'=>'Ramona Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,30,23,30,5,93,5,98,5,104,7,110,10,116,16,119,20,\n                     122,28,123,32,123,68,220,68,220,87,90,87,90,23, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'University Stair'\n  $floorItems2['University Stair'] = i\n  w.create(TkcText,155,77.5, 'text'=>'University Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,282,37,295,40,312,49,323,56,337,70,352,56,\n                     358,48,363,39,365,29,348,25,335,22,321,14,\n                     300,5,283,1,260,0,246,0,242,2,236,4,231,8,\n                     227,13,223,17,221,22,220,34,260,34, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Plaza Stair'\n  $floorItems2['Plaza Stair'] = i\n  w.create(TkcText,317.5,28.5, 'text'=>'Plaza Stair', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,220,34,260,34,282,37,295,40,312,49,\n                     323,56,337,70,350,83,365,94,377,100,\n                     386,104,386,128,220,128, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = 'Plaza Deck'\n  $floorItems2['Plaza Deck'] = i\n  w.create(TkcText,303,81, 'text'=>'Plaza Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,257,336,77,336,6,336,6,301,77,301,77,310,257,310,\n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '106'\n  $floorItems2['106'] = i\n  w.create(TkcText,131.5,318.5, 'text'=>'106', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  i = TkcPolygon.new(w,146,110,162,110,162,91,130,91,130,115,95,115,\n                     95,128,114,128,114,151,157,151,157,153,112,153,\n                     112,130,97,130,97,168,175,168,175,131,146,131, \n                     'fill'=>'', 'tags'=>['floor1','room'])\n  $floorLabels2[i.id] = '119'\n  $floorItems2['119'] = i\n  w.create(TkcText,143.5,133, 'text'=>'119', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor1','label'])\n  w.create(TkcLine,155,191,155,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,96,129,96,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,169,176,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,176,247,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,376,246,376,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,307,247,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,147,129,176,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,202,133,176,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,352,258,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,0,337,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,3,114,3,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,237,52,273, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,189,52,225, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,140,52,177, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,395,306,395,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,531,254,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,475,178,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,502,162,398,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,398,129,398,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,408,208,475,208, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,278,484,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,327,508,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,644,391,559,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,644,389,644,391, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,514,205,475,205, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,496,189,496,187, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,149,725,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,129,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,802,389,802,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,739,167,802,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,0,337,9,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,58,337,21,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,43,391,43,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,105,337,75,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,91,387,91,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,154,337,117,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,139,387,139,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,227,337,166,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,337,251,337, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,328,302,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,302,355,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,395,311,302,311, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,484,278,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,395,294,395,278, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,473,278,473,275, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,473,256,473,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,533,257,531,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,553,276,551,274, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,698,276,553,276, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,559,391,559,327, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,802,389,644,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,741,314,741,389, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,698,280,698,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,707,280,698,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,802,280,731,280, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,741,280,741,302, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,698,167,727,167, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,725,137,725,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,514,254,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,496,175,514,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,502,175,502,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,475,166,475,162, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,496,176,496,175, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,491,189,496,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,491,205,491,189, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,487,238,475,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,487,240,487,238, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,487,252,487,254, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,315,133,304,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,256,133,280,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,247,270,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,307,247,294,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,214,133,232,133, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,217,247,217,266, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,217,309,217,291, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,217,309,172,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,154,309,148,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,175,300,175,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,151,300,175,300, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,151,247,151,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,237,78,265, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,286,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,106,309,78,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,130,309,125,309, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,99,309,99,247, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,127,299,99,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,127,309,127,299, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,155,191,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,137,169,137,191, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,171,78,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,78,190,78,218, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,86,192,86,169, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,86,192,78,192, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,301,3,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,286,52,301, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,252,3,252, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,203,3,203, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,3,156,52,156, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,8,25,8,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,63,114,3,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,75,114,97,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,108,114,129,114, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,129,114,129,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,52,114,52,128, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,132,89,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,88,25,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,88,114,88,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,218,89,144,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,147,111,147,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,162,111,147,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,162,109,162,111, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,162,96,162,89, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,218,89,218,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,218,89,218,119, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,8,25,88,25, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,258,337,258,328, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,129,96,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,302,355,258,355, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,386,104,386,129, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,377,100,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,365,94,377,100, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,350,83,365,94, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,337,70,350,83, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,337,70,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,312,49,323,56, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,295,40,312,49, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,282,37,295,40, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,260,34,282,37, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,253,34,260,34, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,386,128,386,104, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,152,156,152, 'fill'=>color, 'tags'=>['floor1','wall'])\n  w.create(TkcLine,113,152,113,129, 'fill'=>color, 'tags'=>['floor1','wall'])\nend\n\n# floor2_fg2 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the second\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor2_fg2(w,color)\n  i = TkcPolygon.new(w,748,188,755,188,755,205,758,205,758,222,\n                     800,222,800,168,748,168, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '238'\n  $floorItems2['238'] = i\n  w.create(TkcText,774,195, 'text'=>'238', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,726,188,746,188,746,166,800,166,800,131,726,131,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '237'\n  $floorItems2['237'] = i\n  w.create(TkcText,763,148.5, 'text'=>'237', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,497,187,497,204,559,204,559,324,641,324,\n                     643,324,643,291,641,291,641,205,696,205,\n                     696,291,694,291,694,314,715,314,715,291,\n                     715,205,755,205,755,190,724,190,724,187, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '246'\n  $floorItems2['246'] = i\n  w.create(TkcText,600,264, 'text'=>'246', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,694,279,643,279,643,314,694,314, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '247'\n  $floorItems2['247'] = i\n  w.create(TkcText,668.5,296.5, 'text'=>'247', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,232,250,308,250,308,242,339,242,339,246,\n                     397,246,397,255,476,255,476,250,482,250,559,250,\n                     559,274,482,274,482,278,396,278,396,274,232,274, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '202'\n  $floorItems2['202'] = i\n  w.create(TkcText,285.5,260, 'text'=>'202', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,53,228,53,338,176,338,233,338,233,196,\n                     306,196,306,180,175,180,175,169,156,169,\n                     156,196,176,196,176,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '206'\n  $floorItems2['206'] = i\n  w.create(TkcText,143,267, 'text'=>'206', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,277,6,277,6,338,51,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '212'\n  $floorItems2['212'] = i\n  w.create(TkcText,28.5,307.5, 'text'=>'212', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,276,486,276,486,309,510,309,510,325,557,325, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '245'\n  $floorItems2['245'] = i\n  w.create(TkcText,521.5,300.5, 'text'=>'245', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,560,389,599,389,599,326,560,326, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '244'\n  $floorItems2['244'] = i\n  w.create(TkcText,579.5,357.5, 'text'=>'244', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,601,389,601,326,643,326,643,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '243'\n  $floorItems2['243'] = i\n  w.create(TkcText,622,357.5, 'text'=>'243', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,688,316,645,316,645,365,688,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '242'\n  $floorItems2['242'] = i\n  w.create(TkcText,666.5,340.5, 'text'=>'242', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,802,367,759,367,759,226,802,226, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = 'Barbecue Deck'\n  $floorItems2['Barbecue Deck'] = i\n  w.create(TkcText,780.5,296.5, 'text'=>'Barbecue Deck', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,262,755,314,717,314,717,262, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '240'\n  $floorItems2['240'] = i\n  w.create(TkcText,736,288, 'text'=>'240', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,316,689,316,689,365,755,365, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '241'\n  $floorItems2['241'] = i\n  w.create(TkcText,722,340.5, 'text'=>'241', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,755,206,717,206,717,261,755,261, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '239'\n  $floorItems2['239'] = i\n  w.create(TkcText,736,233.5, 'text'=>'239', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,695,277,643,277,643,206,695,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '248'\n  $floorItems2['248'] = i\n  w.create(TkcText,669,241.5, 'text'=>'248', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,676,135,676,185,724,185,724,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '236'\n  $floorItems2['236'] = i\n  w.create(TkcText,700,160, 'text'=>'236', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,675,135,635,135,635,145,628,145,628,185,675,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '235'\n  $floorItems2['235'] = i\n  w.create(TkcText,651.5,160, 'text'=>'235', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,626,143,633,143,633,135,572,135,\n                     572,143,579,143,579,185,626,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '234'\n  $floorItems2['234'] = i\n  w.create(TkcText,606,160, 'text'=>'234', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,557,135,571,135,571,145,578,145,\n                     578,185,527,185,527,131,557,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '233'\n  $floorItems2['233'] = i\n  w.create(TkcText,552.5,158, 'text'=>'233', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,249,557,249,557,205,476,205,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '230'\n  $floorItems2['230'] = i\n  w.create(TkcText,516.5,227, 'text'=>'230', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,164,486,164,486,131,525,131,525,185,476,185, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '232'\n  $floorItems2['232'] = i\n  w.create(TkcText,500.5,158, 'text'=>'232', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,476,186,495,186,495,204,476,204, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '229'\n  $floorItems2['229'] = i\n  w.create(TkcText,485.5,195, 'text'=>'229', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,474,207,409,207,409,187,399,187,399,164,474,164, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '227'\n  $floorItems2['227'] = i\n  w.create(TkcText,436.5,185.5, 'text'=>'227', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,399,228,399,253,474,253,474,209,409,209,409,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '228'\n  $floorItems2['228'] = i\n  w.create(TkcText,436.5,231, 'text'=>'228', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,397,246,397,226,407,226,407,189,377,189,377,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '226'\n  $floorItems2['226'] = i\n  w.create(TkcText,392,217.5, 'text'=>'226', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,377,169,316,169,316,131,397,131,397,188,377,188, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '225'\n  $floorItems2['225'] = i\n  w.create(TkcText,356.5,150, 'text'=>'225', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,198,306,198,306,249,234,249, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '224'\n  $floorItems2['224'] = i\n  w.create(TkcText,270,223.5, 'text'=>'224', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,270,179,306,179,306,170,314,170,314,135,270,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '223'\n  $floorItems2['223'] = i\n  w.create(TkcText,292,157, 'text'=>'223', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,268,179,221,179,221,135,268,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '222'\n  $floorItems2['222'] = i\n  w.create(TkcText,244.5,157, 'text'=>'222', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,177,179,219,179,219,135,177,135, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '221'\n  $floorItems2['221'] = i\n  w.create(TkcText,198,157, 'text'=>'221', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,299,327,349,327,349,284,341,284,341,276,299,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '204'\n  $floorItems2['204'] = i\n  w.create(TkcText,324,301.5, 'text'=>'204', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,234,276,297,276,297,327,257,327,257,338,234,338, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '205'\n  $floorItems2['205'] = i\n  w.create(TkcText,265.5,307, 'text'=>'205', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,256,385,256,340,212,340,212,385,\n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '207'\n  $floorItems2['207'] = i\n  w.create(TkcText,234,362.5, 'text'=>'207', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,210,340,164,340,164,385,210,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '208'\n  $floorItems2['208'] = i\n  w.create(TkcText,187,362.5, 'text'=>'208', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,115,340,162,340,162,385,115,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '209'\n  $floorItems2['209'] = i\n  w.create(TkcText,138.5,362.5, 'text'=>'209', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,228,89,156,53,156,53,228, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '217'\n  $floorItems2['217'] = i\n  w.create(TkcText,71,192, 'text'=>'217', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,169,97,169,97,190,89,190, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '217A'\n  $floorItems2['217A'] = i\n  w.create(TkcText,93,179.5, 'text'=>'217A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,89,156,89,168,95,168,95,135,53,135,53,156, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '216'\n  $floorItems2['216'] = i\n  w.create(TkcText,71,145.5, 'text'=>'216', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,179,51,135,6,135,6,179, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '215'\n  $floorItems2['215'] = i\n  w.create(TkcText,28.5,157, 'text'=>'215', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,227,6,227,6,180,51,180, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '214'\n  $floorItems2['214'] = i\n  w.create(TkcText,28.5,203.5, 'text'=>'214', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,51,275,6,275,6,229,51,229, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '213'\n  $floorItems2['213'] = i\n  w.create(TkcText,28.5,252, 'text'=>'213', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,114,340,67,340,67,385,114,385, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '210'\n  $floorItems2['210'] = i\n  w.create(TkcText,90.5,362.5, 'text'=>'210', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,59,389,59,385,65,385,65,340,1,340,1,389, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '211'\n  $floorItems2['211'] = i\n  w.create(TkcText,33,364.5, 'text'=>'211', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,393,309,350,309,350,282,342,282,342,276,393,276, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '203'\n  $floorItems2['203'] = i\n  w.create(TkcText,367.5,292.5, 'text'=>'203', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,99,191,91,191,91,226,174,226,174,198,\n                     154,198,154,192,109,192,109,169,99,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '220'\n  $floorItems2['220'] = i\n  w.create(TkcText,132.5,208.5, 'text'=>'220', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = 'Priv Lift2'\n  $floorItems2['Priv Lift2'] = i\n  w.create(TkcText,323,188, 'text'=>'Priv Lift2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = 'Pub Lift 2'\n  $floorItems2['Pub Lift 2'] = i\n  w.create(TkcText,323,223, 'text'=>'Pub Lift 2', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '218'\n  $floorItems2['218'] = i\n  w.create(TkcText,136,149.5, 'text'=>'218', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '219'\n  $floorItems2['219'] = i\n  w.create(TkcText,132.5,180, 'text'=>'219', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor2','room'])\n  $floorLabels2[i.id] = '201'\n  $floorItems2['201'] = i\n  w.create(TkcText,358,209, 'text'=>'201', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor2','label'])\n  w.create(TkcLine,641,186,678,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,350,757,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,634,133,634,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,634,144,627,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,572,133,572,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,572,144,579,144, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,129,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,174,197,175,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,175,197,175,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,206,757,221, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,396,188,408,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,727,189,725,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,747,167,802,167, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,747,167,747,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,755,189,739,189, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,769,224,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,802,224,802,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,802,129,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,725,189,725,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,725,186,690,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,676,133,676,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,627,144,627,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,629,186,593,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,579,144,579,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,559,129,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,725,133,559,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,162,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,559,129,484,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,526,129,526,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,540,186,581,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,528,186,523,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,511,186,475,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,496,190,496,186, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,496,205,496,202, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,475,205,527,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,205,539,205, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,205,558,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,249,475,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,662,206,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,695,206,675,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,695,278,642,278, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,642,291,642,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,695,291,695,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,716,208,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,206,716,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,221,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,793,224,802,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,262,716,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,716,220,716,264, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,716,315,716,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,315,703,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,325,757,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,757,367,644,367, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,689,367,689,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,647,315,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,659,315,691,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,600,325,600,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,627,325,644,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,644,391,644,315, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,615,325,575,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,644,391,558,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,563,325,558,325, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,391,558,314, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,327,508,327, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,275,484,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,558,302,558,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,508,327,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,311,508,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,275,484,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,475,208,408,208, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,206,408,210, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,222,408,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,227,398,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,227,398,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,408,188,408,194, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,383,188,376,188, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,188,398,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,162,484,162, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,475,162,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,254,475,254, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,484,280,395,280, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,395,311,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,307,197,293,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,278,197,233,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,233,197,233,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,307,179,284,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,233,249,278,249, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,269,179,269,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,220,179,220,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,155,191,110,191, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,90,190,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,98,169,98,190, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,133,52,165, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,214,52,177, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,226,52,262, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,274,52,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,234,275,234,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,226,339,258,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,211,387,211,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,214,339,177,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,258,387,60,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,3,133,3,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,165,339,129,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,117,339,80,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,68,339,59,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,0,339,46,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,0,339,0,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,60,387,60,391, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,258,329,258,387, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,395,311,350,311, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,398,129,315,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,176,133,315,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,3,133,96,133, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,66,387,66,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,115,387,115,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,163,387,163,339, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,234,275,276,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,288,275,309,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,321,275,341,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,375,275,395,275, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,376,245,376,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,245,340,224, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,293,250,307,250, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,271,179,238,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,226,179,195,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,174,169,176,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,162,169,90,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,96,169,96,129, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,175,227,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,90,190,90,227, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,179,3,179, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,228,3,228, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,52,276,3,276, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,110,191,110,169, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,155,189,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor2','wall'])\n  w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor2','wall'])\nend\n\n# floor2_fg3 --\n# This method represents part of the floorplan database.  When\n# invoked, it instantiates the foreground information for the third\n# floor (office outlines and numbers).\n#\n# Arguments:\n# w -           The canvas window.\n# color -       Color to use for drawing foreground information.\n\ndef floor2_fg3(w,color)\n  i = TkcPolygon.new(w,89,228,89,180,70,180,70,228,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '316'\n  $floorItems2['316'] = i\n  w.create(TkcText,79.5,204, 'text'=>'316', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,115,368,162,368,162,323,115,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '309'\n  $floorItems2['309'] = i\n  w.create(TkcText,138.5,345.5, 'text'=>'309', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,164,323,164,368,211,368,211,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '308'\n  $floorItems2['308'] = i\n  w.create(TkcText,187.5,345.5, 'text'=>'308', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,256,368,212,368,212,323,256,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '307'\n  $floorItems2['307'] = i\n  w.create(TkcText,234,345.5, 'text'=>'307', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,244,276,297,276,297,327,260,327,260,321,244,321, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '305'\n  $floorItems2['305'] = i\n  w.create(TkcText,270.5,301.5, 'text'=>'305', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,219,251,203,244,203,244,219,\n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '324B'\n  $floorItems2['324B'] = i\n  w.create(TkcText,247.5,211, 'text'=>'324B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,251,249,244,249,244,232,251,232, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '324A'\n  $floorItems2['324A'] = i\n  w.create(TkcText,247.5,240.5, 'text'=>'324A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,223,135,223,179,177,179,177,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '320'\n  $floorItems2['320'] = i\n  w.create(TkcText,200,157, 'text'=>'320', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,114,368,114,323,67,323,67,368, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '310'\n  $floorItems2['310'] = i\n  w.create(TkcText,90.5,345.5, 'text'=>'310', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,277,23,321,68,321,68,277, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '312'\n  $floorItems2['312'] = i\n  w.create(TkcText,45.5,299, 'text'=>'312', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,23,229,68,229,68,275,23,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '313'\n  $floorItems2['313'] = i\n  w.create(TkcText,45.5,252, 'text'=>'313', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,68,227,23,227,23,180,68,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '314'\n  $floorItems2['314'] = i\n  w.create(TkcText,40.5,203.5, 'text'=>'314', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,95,179,95,135,23,135,23,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '315'\n  $floorItems2['315'] = i\n  w.create(TkcText,59,157, 'text'=>'315', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,99,226,99,204,91,204,91,226, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '316B'\n  $floorItems2['316B'] = i\n  w.create(TkcText,95,215, 'text'=>'316B', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,91,202,99,202,99,180,91,180, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '316A'\n  $floorItems2['316A'] = i\n  w.create(TkcText,95,191, 'text'=>'316A', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,97,169,109,169,109,192,154,192,154,198,\n                     174,198,174,226,101,226,101,179,97,179, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '319'\n  $floorItems2['319'] = i\n  w.create(TkcText,141.5,209, 'text'=>'319', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,65,368,58,368,58,389,1,389,1,333,23,333,23,323,65,323, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '311'\n  $floorItems2['311'] = i\n  w.create(TkcText,29.5,361, 'text'=>'311', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,154,191,111,191,111,169,154,169, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '318'\n  $floorItems2['318'] = i\n  w.create(TkcText,132.5,180, 'text'=>'318', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,175,168,97,168,97,131,175,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '317'\n  $floorItems2['317'] = i\n  w.create(TkcText,136,149.5, 'text'=>'317', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,274,194,274,221,306,221,306,194, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '323'\n  $floorItems2['323'] = i\n  w.create(TkcText,290,207.5, 'text'=>'323', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,306,222,274,222,274,249,306,249, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '325'\n  $floorItems2['325'] = i\n  w.create(TkcText,290,235.5, 'text'=>'325', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,263,179,224,179,224,135,263,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '321'\n  $floorItems2['321'] = i\n  w.create(TkcText,243.5,157, 'text'=>'321', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,314,169,306,169,306,192,273,192,\n                     264,181,264,135,314,135, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '322'\n  $floorItems2['322'] = i\n  w.create(TkcText,293.5,163.5, 'text'=>'322', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,307,240,339,240,339,206,307,206, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = 'Pub Lift3'\n  $floorItems2['Pub Lift3'] = i\n  w.create(TkcText,323,223, 'text'=>'Pub Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,339,205,307,205,307,171,339,171, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = 'Priv Lift3'\n  $floorItems2['Priv Lift3'] = i\n  w.create(TkcText,323,188, 'text'=>'Priv Lift3', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,350,284,376,284,376,276,397,276,397,309,350,309, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '303'\n  $floorItems2['303'] = i\n  w.create(TkcText,373.5,292.5, 'text'=>'303', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,272,203,272,249,252,249,252,230,\n                     244,230,244,221,252,221,252,203, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '324'\n  $floorItems2['324'] = i\n  w.create(TkcText,262,226, 'text'=>'324', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,299,276,299,327,349,327,349,284,341,284,341,276, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '304'\n  $floorItems2['304'] = i\n  w.create(TkcText,324,301.5, 'text'=>'304', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,375,246,375,172,341,172,341,246, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '301'\n  $floorItems2['301'] = i\n  w.create(TkcText,358,209, 'text'=>'301', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,397,246,377,246,377,185,397,185, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '327'\n  $floorItems2['327'] = i\n  w.create(TkcText,387,215.5, 'text'=>'327', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,316,131,316,169,377,169,377,185,397,185,397,131, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '326'\n  $floorItems2['326'] = i\n  w.create(TkcText,365.5,150, 'text'=>'326', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,308,251,242,251,242,274,342,274,342,282,375, 282,\n                     375,274,397,274,397,248,339,248,339,242,308,242, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '302'\n  $floorItems2['302'] = i\n  w.create(TkcText,319.5,261, 'text'=>'302', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  i = TkcPolygon.new(w,70,321,242,321,242,200,259,200,259,203,272,203,\n                     272,193,263,180,242,180,175,180,175,169,156,169,\n                     156,196,177,196,177,228,107,228,70,228,70,275,107,275,\n                     107,248,160,248,160,301,107,301,107,275,70,275, \n                     'fill'=>'', 'tags'=>['floor3','room'])\n  $floorLabels2[i.id] = '306'\n  $floorItems2['306'] = i\n  w.create(TkcText,200.5,284.5, 'text'=>'306', 'fill'=>color, \n              'anchor'=>'c', 'tags'=>['floor3','label'])\n  w.create(TkcLine,341,275,341,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,162,197,155,197, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,396,247,399,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,399,129,399,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,202,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,350,283,350,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,251,231,243,231, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,220,251,220, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,250,243,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,155,197,155,190, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,110,192,110,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,155,192,110,192, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,155,177,155,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,176,197,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,69,280,69,274, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,276,69,276, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,69,262,69,226, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,228,69,228, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,179,75,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,69,179,69,214, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,220,90,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,204,90,202, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,203,100,203, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,187,90,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,90,227,176,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,100,179,100,227, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,100,179,87,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,96,179,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,162,169,96,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,173,169,176,169, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,182,179,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,176,129,176,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,195,179,226,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,224,133,224,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,264,179,264,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,238,179,264,179, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,207,273,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,235,273,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,224,273,219, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,193,307,193, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,222,307,222, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,384,247,376,247, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,206,307,206, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,187,340,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,210,340,201, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,247,340,224, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,340,241,307,241, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,247,376,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,307,250,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,170,307,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,315,129,315,170, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,283,366,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,376,283,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,399,275,376,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,341,275,320,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,341,283,350,283, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,298,275,298,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,308,275,298,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,322,243,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,243,275,284,275, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,322,226,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,212,370,212,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,214,322,177,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,163,370,163,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,165,322,129,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,84,322,117,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,71,322,64,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,115,322,115,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,66,322,66,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,52,322,21,322, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,331,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,21,331,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,96,133,21,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,176,129,96,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,315,133,176,133, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,315,129,399,129, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,399,311,350,311, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,350,329,258,329, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,322,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,60,370,258,370, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,60,370,60,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,0,391,0,331, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,60,391,0,391, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,307,250,307,242, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,273,250,307,250, 'fill'=>color, 'tags'=>['floor3','wall'])\n  w.create(TkcLine,258,250,243,250, 'fill'=>color, 'tags'=>['floor3','wall'])\nend\n\n# Below is the \"main program\" that creates the floorplan demonstration.\n\n# toplevel widget ¸ߤк\nif defined?($floor2_demo) && $floor2_demo\n  $floor2_demo.destroy \n  $floor2_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$floor2_demo = TkToplevel.new {|w|\n  title(\"Floorplan Canvas Demonstration 2\")\n  iconname(\"Floorplan2\")\n  positionWindow(w)\n  geometry('+20+20')\n  minsize(100,100)\n}\n\nbase_frame = TkFrame.new($floor2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', \n            'text'=>\"Υɥˤϥǥ륨åץȼҤΥꥵܥȥ (DECWRL) δּ꤬񤫤줿Х widget äƤޤ 3ƤǡˤΤ1ʬ򡢤Ĥޤꤽδּ꤬ɽ褦ˤʤäƤޤ볬򤹤ˤϡξǥޥκܥ򥯥åƤޥ򤵤Ƥ볬ξưȡβˤοѤꡢֹ椬ֹ:ץȥɽޤޤȥֹ񤯤ȤοѤޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$floor2_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $floor2_demo\n      $floor2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'floor2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$floor2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# ѿ\n$floorLabels2 = {}\n$floorItems2 = {}\n\n# canvas \nif $tk_version =~ /^4\\.[01]/\n  $floor2_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken',\n                                    'highlightthickness'=>2)\n  $floor2_canvas = TkCanvas.new($floor2_canvas_frame, \n                               'width'=>900, 'height'=>500, 'borderwidth'=>0, \n                               'highlightthickness'=>0) {|c|\n    TkScrollbar.new(base_frame, 'orient'=>'horiz', \n                    'command'=>proc{|*args| c.xview(*args)}){|hs|\n      c.xscrollcommand(proc{|first,last| hs.set first,last})\n      pack('side'=>'bottom', 'fill'=>'x')\n    }\n    TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs|\n      c.yscrollcommand(proc{|first,last| vs.set first,last})\n      pack('side'=>'right', 'fill'=>'y')\n    }\n  }\n  $floor2_canvas_frame.pack('side'=>'top','fill'=>'both', 'expand'=>'yes')\n  $floor2_canvas.pack('expand'=>'yes', 'fill'=>'both')\n\nelse\n  TkFrame.new(base_frame) {|f|\n    pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\n    h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal')\n    v = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'vertical')\n\n    TkFrame.new(f, 'bd'=>2, 'relief'=>'sunken') {|f1|\n      $floor2_canvas = TkCanvas.new(f1, 'width'=>900, 'height'=>500, \n                                   'borderwidth'=>0, \n                                   'highlightthickness'=>0) {\n        xscrollcommand(proc{|first,last| h.set first,last})\n        yscrollcommand(proc{|first,last| v.set first,last})\n        pack('expand'=>'yes', 'fill'=>'both')\n      }\n      grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    }\n\n    v.grid('padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    h.grid('padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n           'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n\n    TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n\n    pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n\n    v.command(proc{|*args| $floor2_canvas.yview(*args)})\n    h.command(proc{|*args| $floor2_canvas.xview(*args)})\n  }\nend\n\n# Create an entry for displaying and typing in current room.\n\n$currentRoom2 = TkVariable.new\n$floor2_entry = TkEntry.new($floor2_canvas, 'width'=>10, 'relief'=>'sunken', \n                           'bd'=>2, 'textvariable'=>$currentRoom2)\n\n# Choose colors, then fill in the floorplan.\n\n$floor2_colors = {}\nif TkWinfo.depth($floor2_canvas) > 1\n  $floor2_colors['bg1'] = '#a9c1da'\n  $floor2_colors['outline1'] = '#77889a'\n  $floor2_colors['bg2'] = '#9ab0c6'\n  $floor2_colors['outline2'] = '#687786'\n  $floor2_colors['bg3'] = '#8ba0b3'\n  $floor2_colors['outline3'] = '#596673'\n  $floor2_colors['offices'] = 'Black'\n  $floor2_colors['active'] = '#c4d1df'\nelse\n  $floor2_colors['bg1'] = 'white'\n  $floor2_colors['outline1'] = 'black'\n  $floor2_colors['bg2'] = 'white'\n  $floor2_colors['outline2'] = 'black'\n  $floor2_colors['bg3'] = 'white'\n  $floor2_colors['outline3'] = 'black'\n  $floor2_colors['offices'] = 'Black'\n  $floor2_colors['active'] = 'black'\nend\n\n$activeFloor2 = ''\nfloorDisplay2 $floor2_canvas,3\n\n# Set up event bindings for canvas:\n\n$floor2_canvas.itembind('floor1', '1', proc{floorDisplay2 $floor2_canvas,1})\n$floor2_canvas.itembind('floor2', '1', proc{floorDisplay2 $floor2_canvas,2})\n$floor2_canvas.itembind('floor3', '1', proc{floorDisplay2 $floor2_canvas,3})\n$floor2_canvas.itembind('room', 'Enter', proc{newRoom2 $floor2_canvas})\n$floor2_canvas.itembind('room', 'Leave', proc{$currentRoom2.value = ''})\n$floor2_canvas.bind('2', proc{|x,y| $floor2_canvas.scan_mark x,y}, '%x %y')\n$floor2_canvas.bind('B2-Motion', \n                   proc{|x,y| $floor2_canvas.scan_dragto x,y}, '%x %y')\n$floor2_canvas.bind('Destroy', proc{$currentRoom2.unset})\n$currentRoom2.value = ''\n$currentRoom2.trace('w',proc{roomChanged2 $floor2_canvas})\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/form.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# form widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($form_demo) && $form_demo\n  $form_demo.destroy \n  $form_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$form_demo = TkToplevel.new {|w|\n  title(\"Form Demonstration\")\n  iconname(\"form\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($form_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ΥɥϴñʥեѤˤʤäƤơޤޤʥȥϤǤޤ֤ǥȥؤǤޤ\"\n}\nmsg.pack('side'=>'top', 'fill'=>'x')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $form_demo\n      $form_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'form'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# entry \nform_data = []\n(1..5).each{|i|\n  f = TkFrame.new(base_frame, 'bd'=>2)\n  e = TkEntry.new(f, 'relief'=>'sunken', 'width'=>40)\n  l = TkLabel.new(f)\n  e.pack('side'=>'right')\n  l.pack('side'=>'left')\n  form_data[i] = {'frame'=>f, 'entry'=>e, 'label'=>l}\n}\n\n# ʸ\nform_data[1]['label'].text('̾:')\nform_data[2]['label'].text(':')\nform_data[5]['label'].text(':')\n\n# pack\n(1..5).each{|i| form_data[i]['frame'].pack('side'=>'top', 'fill'=>'x')}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/goldberg.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# Ruby/Tk Goldverg demo (called by 'widget')\n#\n# Based on Tcl/Tk8.5a2 widget demos.\n# The following is the original comment of TkGoldberg.tcl.\n#\n#>>##+#################################################################\n#>>#\n#>># TkGoldberg.tcl\n#>># by Keith Vetter, March 13, 2003\n#>>#\n#>># \"Man will always find a difficult means to perform a simple task\"\n#>># Rube Goldberg\n#>>#\n#>># Reproduced here with permission.\n#>>#\n#>>##+#################################################################\n#>>#\n#>># Keith Vetter 2003-03-21: this started out as a simple little program\n#>># but was so much fun that it grew and grew. So I apologize about the\n#>># size but I just couldn't resist sharing it.\n#>>#\n#>># This is a whizzlet that does a Rube Goldberg type animation, the\n#>># design of which comes from an New Years e-card from IncrediMail.\n#>># That version had nice sound effects which I eschewed. On the other\n#>># hand, that version was in black and white (actually dark blue and\n#>># light blue) and this one is fully colorized.\n#>>#\n#>># One thing I learned from this project is that drawing filled complex\n#>># objects on a canvas is really hard. More often than not I had to\n#>># draw each item twice--once with the desired fill color but no\n#>># outline, and once with no fill but with the outline. Another trick\n#>># is erasing by drawing with the background color. Having a flood fill\n#>># command would have been extremely helpful.\n#>>#\n#>># Two wiki pages were extremely helpful: Drawing rounded rectangles\n#>># which I generalized into Drawing rounded polygons, and regular\n#>># polygons which allowed me to convert ovals and arcs into polygons\n#>># which could then be rotated (see Canvas Rotation). I also wrote\n#>># Named Colors to aid in the color selection.\n#>>#\n#>># I could comment on the code, but it's just 26 state machines with\n#>># lots of canvas create and move calls.\n\nif defined?($goldberg_demo) && $goldberg_demo\n  $goldberg_demo.destroy \n  $goldberg_demo = nil\nend\n\n# demo toplevel widget\n$goldberg_demo = TkToplevel.new {|w|\n  title(\"Tk Goldberg (demonstration)\")\n  iconname(\"goldberg\")\n#  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($goldberg_demo).pack(:fill=>:both, :expand=>true)\n\n=begin\n# label\nmsg = TkLabel.new($goldberg_demo) {\n  font 'Arial 10'\n  wraplength '4i'\n  justify 'left'\n  text \"ϡʤʬΥ˥᡼򤤤ȤΤˤǤ뤫򼨤ȤΤΥǥǤܡ򥯥åʪưϤޤ\\n\\n\\\"Man will always find a difficult means to perform a simple task\\\"\\n - Rube Goldberg\"\n}\nmsg.pack('side'=>'top')\n=end\n\n=begin\n# frame\nTkFrame.new($goldberg_demo) {|frame|\n  TkButton.new(frame) {\n    text 'Ĥ'\n    command proc{\n      tmppath = $goldberg_demo\n      $goldberg_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'goldberg'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n=end\n\n#########################################\n\nclass TkGoldberg_Demo\n  def initialize(parent)\n    @parent = parent\n\n    @S = {}\n    @S['title']   = 'Tk Goldberg'\n    @S['speed']   = TkVariable.new(5)\n    @S['cnt']     = TkVariable.new(0)\n    # @S['message'] = TkVariable.new(\"\\\\nWelcome\\\\nto\\\\nRuby/Tk\")\n    @S['message'] = TkVariable.new(\"\\\\n 褦\\\\nRuby/Tk\\\\n\\\\n\")\n    @S['pause']   = TkVariable.new\n    @S['details'] = TkVariable.new(true)\n\n    @S['mode'] = TkVariable.new(:MSTART, :symbol) \n    #            :MSTART, :MGO, :MPAUSE, :MSSTEP, :MBSTEP, :MDONE, :MDEBUG\n\n    #         0,  1,  2,  3,  4,  5,   6,   7,   8,   9,  10\n    @speed = [1, 10, 20, 50, 80, 100, 150, 200, 300, 400, 500]\n\n    # colors\n    @C = {}\n    @C['fg'] = 'black'\n    # @C['bg'] = 'gray75'\n    @C['bg'] = 'cornflowerblue'\n\n    @C['0'] = 'white';         @C['1a'] = 'darkgreen';   @C['1b'] = 'yellow'\n    @C['2'] = 'red';           @C['3a'] = 'green';       @C['3b'] = 'darkblue'\n    @C['4'] = @C['fg'];        @C['5a'] = 'brown';       @C['5b'] = 'white'\n    @C['6'] = 'magenta';       @C['7'] = 'green';        @C['8'] = @C['fg']\n    @C['9'] = 'blue4';         @C['10a'] = 'white';      @C['10b'] = 'cyan'\n    @C['11a'] = 'yellow';      @C['11b'] = 'mediumblue'; @C['12'] = 'tan2'\n    @C['13a'] = 'yellow';      @C['13b'] = 'red';        @C['14'] = 'white'\n    @C['15a'] = 'green';       @C['15b'] = 'yellow';     @C['16'] = 'gray65'\n    @C['17'] = '#A65353';     @C['18'] = @C['fg'];      @C['19'] = 'gray50'\n    @C['20'] = 'cyan';         @C['21'] = 'gray65';      @C['22'] = @C['20']\n    @C['23a'] = 'blue';        @C['23b'] = 'red';        @C['23c'] = 'yellow'\n    @C['24a'] = 'red';         @C['24b'] = 'white';\n\n    @STEP = TkVariable.new_hash\n    @STEP.default_value_type = :numeric\n\n    @XY = {}\n\n    @XY6 = {\n      '-1'=>[366, 207], '-2'=>[349, 204], '-3'=>[359, 193], '-4'=>[375, 192], \n      '-5'=>[340, 190], '-6'=>[349, 177], '-7'=>[366, 177], '-8'=>[380, 176],\n      '-9'=>[332, 172], '-10'=>[342, 161], '-11'=>[357, 164], \n      '-12'=>[372, 163], '-13'=>[381, 149], '-14'=>[364, 151], \n      '-15'=>[349, 146], '-16'=>[333, 148], '0'=>[357, 219], \n      '1'=>[359, 261], '2'=>[359, 291], '3'=>[359, 318], '4'=>[361, 324], \n      '5'=>[365, 329], '6'=>[367, 334], '7'=>[367, 340], '8'=>[366, 346], \n      '9'=>[364, 350], '10'=>[361, 355], '11'=>[359, 370], '12'=>[359, 391], \n      '13,0'=>[360, 456], '13,1'=>[376, 456], '13,2'=>[346, 456], \n      '13,3'=>[330, 456], '13,4'=>[353, 444], '13,5'=>[368, 443], \n      '13,6'=>[339, 442], '13,7'=>[359, 431], '13,8'=>[380, 437], \n      '13,9'=>[345, 428], '13,10'=>[328, 434], '13,11'=>[373, 424], \n      '13,12'=>[331, 420], '13,13'=>[360, 417], '13,14'=>[345, 412], \n      '13,15'=>[376, 410], '13,16'=>[360, 403]\n    }\n\n    @timer = TkTimer.new(@speed[@S['speed'].numeric]){|timer|\n      timer.set_interval(go)\n    }\n\n    do_display\n    reset\n\n    # Start everything going\n    @timer.start\n  end\n\n  def do_display()\n    @ctrl = TkFrame.new(@parent, :relief=>:ridge, :bd=>2, :padx=>5, :pady=>5)\n    @screen = TkFrame.new(@parent, :bd=>2, \n                         :relief=>:raised).pack(:side=>:left, :fill=>:both, \n                                                :expand=>true)\n\n    @canvas = TkCanvas.new(@parent, :width=>850, :height=>700, \n                          :bg=>@C['bg'], :highlightthickness=>0){\n      scrollregion([0, 0, 1000, 1000]) # Kludge to move everything up\n      yview_moveto(0.05)\n    }.pack(:in=>@screen, :side=>:top, :fill=>:both, :expand=>true)\n\n    @canvas.bind('3'){ @pause.invoke }\n    @canvas.bind('Destroy'){ @timer.stop }\n\n    do_ctrl_frame\n    do_detail_frame\n\n    # msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') {\n    msg = Tk::Label.new(@parent, :bg=>@C['bg'], :fg=>'white') {\n      font 'Arial 10'\n      wraplength 600\n      justify 'left'\n      text \"ϡʤʬΥ˥᡼򤤤ȤΤˤǤ뤫򼨤ȤΤΥǥǤܡ򥯥åʪưϤޤ\\n\\\"Man will always find a difficult means to perform a simple task\\\" - Rube Goldberg\"\n    }\n    msg.place(:in=>@canvas, :relx=>0, :rely=>0, :anchor=>:nw)\n\n    frame = TkFrame.new(@parent, :bg=>@C['bg'])\n\n    # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n    Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n      text 'Ĥ'\n      command proc{\n        tmppath = $goldberg_demo\n        $goldberg_demo = nil\n        tmppath.destroy\n      }\n    }.pack('side'=>'left')\n\n    # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n    Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) {\n      text 'ɻ'\n      command proc{showCode 'goldberg'}\n    }.pack('side'=>'left', 'padx'=>5)\n\n    # @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl}, \n    @show = Tk::Button.new(frame, :text=>'>>', :command=>proc{show_ctrl}, \n                         :bg=>@C['bg'], :activebackground=>@C['bg'])\n    @show.pack('side'=>'left')\n    frame.place(:in=>@canvas, :relx=>1, :rely=>0, :anchor=>:ne)\n\n    Tk.update\n  end\n\n  def do_ctrl_frame\n    @start = Tk::Button.new(@parent, :text=>'Start', :bd=>6, \n                          :command=>proc{do_button(0)})\n    if font = @start['font']\n      @start.font(font.weight('bold'))\n    end\n\n    @pause = TkCheckbutton.new(@parent, :text=>'Pause', :font=>font, \n                               :command=>proc{do_button(1)}, :relief=>:raised, \n                               :variable=>@S['pause'])\n\n    @step  = TkButton.new(@parent, :text=>'Single Step', :font=>font, \n                          :command=>proc{do_button(2)})\n    @bstep = TkButton.new(@parent, :text=>'Big Step', :font=>font, \n                          :command=>proc{do_button(4)})\n    @reset = TkButton.new(@parent, :text=>'Reset', :font=>font, \n                          :command=>proc{do_button(3)})\n\n    @details = TkFrame.new(@parent, :bd=>2, :relief=>:ridge)\n    @detail = TkCheckbutton.new(@parent, :text=>'Details', :font=>font, \n                               :relief=>:raised, :variable=>@S['details'])\n\n    @msg_entry = TkEntry.new(@parent, :textvariable=>@S['message'], \n                             :justify=>:center)\n    @speed_scale = TkScale.new(@parent, :orient=>:horizontal, \n                               :from=>1, :to=>10, :font=>font, \n                               :variable=>@S['speed'], :bd=>2, \n                               :relief=>:ridge, :showvalue=>false)\n    @about = TkButton.new(@parent, :text=>'About', \n                          :command=>proc{about}, :font=>font)\n\n    Tk.grid(@start, :in=>@ctrl, :row=>0, :sticky=>:ew)\n    @ctrl.grid_rowconfigure(1, :minsize=>10)\n    Tk.grid(@pause, :in=>@ctrl, :row=>2, :sticky=>:ew)\n    Tk.grid(@step,  :in=>@ctrl, :sticky=>:ew)\n    Tk.grid(@bstep, :in=>@ctrl, :sticky=>:ew)\n    Tk.grid(@reset, :in=>@ctrl, :sticky=>:ew)\n    @ctrl.grid_rowconfigure(10, :minsize=>20)\n    Tk.grid(@details, :in=>@ctrl, :row=>11, :sticky=>:ew)\n    Tk.grid(@detail, :in=>@details, :row=>0, :sticky=>:ew)\n    @ctrl.grid_rowconfigure(50, :weight=>1)\n\n    @S['mode'].trace('w', proc{|*args| active_GUI(*args)})\n    @S['details'].trace('w', proc{|*args| active_GUI(*args)})\n    @S['speed'].trace('w', proc{|*args| active_GUI(*args)})\n\n    Tk.grid(@msg_entry, :in=>@ctrl, :row=>98, :sticky=>:ew, :pady=>5)\n    Tk.grid(@speed_scale, :in=>@ctrl, :row=>99, :sticky=>:ew)\n    Tk.grid(@about, :in=>@ctrl, :row=>100, :sticky=>:ew)\n\n    @reset.bind('3'){@S['mode'].value = -1}  # Debugging\n  end\n\n  def do_detail_frame\n    @f_details = TkFrame.new(@details)\n\n    @label = TkLabel.new(@f_details, :textvariable=>@S['cnt'], \n                         :bd=>1, :relief=>:solid, :bg=>'white')\n    Tk.grid(@label, '-', '-', '-', :sticky=>:ew, :row=>0)\n\n    idx = 1\n    loop {\n      break unless respond_to?(\"move#{idx}\")\n      l = TkLabel.new(@f_details, :text=>idx, :anchor=>:e, \n                      :width=>2, :bd=>1, :relief=>:solid, :bg=>'white')\n      @STEP[idx] = 0\n      ll = TkLabel.new(@f_details, :textvariable=>@STEP.ref(idx), \n                       :width=>5, :bd=>1, :relief=>:solid, :bg=>'white')\n      row = (idx + 1)/2\n      col = ((idx + 1) & 1) * 2\n      Tk.grid(l, :sticky=>:ew, :row=>row, :column=>col)\n      Tk.grid(ll, :sticky=>:ew, :row=>row, :column=>(col + 1))\n      idx += 1\n    }\n    @f_details.grid_columnconfigure(1, :weight=>1)\n  end\n\n  def show_ctrl\n    if @ctrl.winfo_mapped?\n      @ctrl.pack_forget\n      @show.text('>>')\n    else\n      @ctrl.pack(:side=>:right, :fill=>:both, :ipady=>5)\n      @show.text('<<')\n    end\n  end\n\n  def draw_all\n    reset_step\n    @canvas.delete(:all)\n    idx = 0\n    loop{\n      m = \"draw#{idx}\"\n      break unless respond_to?(m)\n      send(m)\n      idx += 1\n    }\n  end\n\n  def active_GUI(var1, var2, op)\n    st = {false=>:disabled, true=>:normal}\n\n    m = @S['mode'].to_sym\n    @S['pause'].value = (m == :MPAUSE)\n    @start.state(st[m != :MGO])\n    @pause.state(st[m != :MSTART && m != :MDONE])\n    @step.state(st[m != :MGO && m != :MDONE])\n    @bstep.state(st[m != :MGO && m != :MDONE])\n    @reset.state(st[m != :MSTART])\n\n    if @S['details'].bool\n      Tk.grid(@f_details, :in=>@details, :row=>2, :sticky=>:ew)\n    else\n      Tk.grid_forget(@f_details)\n    end\n    @speed_scale.label(\"Speed: #{@S['speed'].value}\")\n  end\n\n  def start\n    @S['mode'].value = :MGO\n  end\n\n  def do_button(what)\n    case what\n    when 0  # Start\n      reset if @S['mode'].to_sym == :MDONE\n      @S['mode'].value = :MGO\n\n    when 1  # Pause\n      @S['mode'].value = ((@S['pause'].bool)? :MPAUSE: :MGO)\n\n    when 2  # Step\n      @S['mode'].value = :MSSTEP\n\n    when 3  # Reset\n      reset\n\n    when 4  # Big step\n      @S['mode'].value = :MBSTEP\n    end\n  end\n\n  def go(who = nil)\n    now = Tk::Clock.clicks(:miliseconds)\n    if who  # Start here for debugging\n      @S['active'] = [who]\n      @S['mode'].value = :MGO\n    end\n    return if @S['mode'].to_sym == :MDEBUG  # Debugging\n    # If not paused, do the next move\n    n = next_step if @S['mode'].to_sym != :MPAUSE\n    @S['mode'].value = :MPAUSE if @S['mode'].to_sym == :MSSTEP  # Single step\n    @S['mode'].value = :MSSTEP if @S['mode'].to_sym == :MBSTEP && n  # big step\n    elapsed = Tk::Clock.clicks(:miliseconds) - now\n    delay = @speed[@S['speed'].to_i] - elapsed\n    delay = 1 if delay <= 0\n    return delay\n  end\n\n  def next_step\n    retval = false   # Return value\n\n    if @S['mode'].to_sym != :MSTART && @S['mode'].to_sym != :MDONE\n      @S['cnt'].numeric += 1\n    end\n    alive = []\n    @S['active'].each{|who|\n      who = who.to_i\n      n = send(\"move#{who}\")\n      if (n & 1).nonzero?          # This guy still alive\n        alive << who \n      end\n      if (n & 2).nonzero?          # Next guy is active\n        alive << (who + 1)\n        retval = true\n      end\n      if (n & 4).nonzero?          # End of puzzle flag\n        @S['mode'].value = :MDONE  # Done mode\n        @S['active'] = []          # No more animation\n        return true\n      end\n    }\n    @S['active'] = alive\n    return retval\n  end\n\n  def about\n    msg = \"Ruby/Tk Version ::\\nby Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\\n\\n\"\n    msg += \"Original Version ::\\n\"\n    msg += \"#{@S['title']}\\nby Keith Vetter, March 2003\\n(Reproduced by kind permission of the author)\\n\\n\"\n    msg += \"Man will always find a difficult means to perform a simple task\"\n    msg += \"\\nRube Goldberg\"\n    Tk.messageBox(:message=>msg, :title=>'About')\n  end\n\n  ################################################################\n  #\n  # All the drawing and moving routines\n  #\n\n  # START HERE! banner\n  def draw0\n    color = @C['0']\n    TkcText.new(@canvas, \n                # [579, 119], :text=>'START HERE!', \n                [558, 119], :text=>'饹ȡ', \n                :fill=>color, :anchor=>:w, \n                :tag=>'I0', :font=>['Times Roman', 12, :italic, :bold])\n    TkcLine.new(@canvas, [719, 119, 763, 119], :tag=>'I0', :fill=>color, \n                :width=>5, :arrow=>:last, :arrowshape=>[18, 18, 5])\n    @canvas.itembind('I0', '1'){ start }\n  end\n\n  def move0(step = nil)\n    step = get_step(0, step)\n\n    if @S['mode'].to_sym != :MSTART    # Start the ball rolling\n      move_abs('I0', [-100, -100])     # Hide the banner\n      return 2\n    end\n\n    pos = [\n      [673, 119], [678, 119], [683, 119], [688, 119], \n      [693, 119], [688, 119], [683, 119], [678, 119]\n    ]\n    step = step % pos.length\n    move_abs('I0', pos[step])\n    return 1\n  end\n\n  # Dropping ball\n  def draw1\n    color = @C['1a']\n    color2 = @C['1b']\n    TkcPolygon.new(@canvas, \n                   [ 844, 133, 800, 133, 800, 346, 820, 346, \n                     820, 168, 844, 168, 844, 133 ], \n                   :width=>3, :fill=>color, :outline=>'')\n    TkcPolygon.new(@canvas, \n                   [ 771, 133, 685, 133, 685, 168, 751, 168, \n                     751, 346, 771, 346, 771, 133 ], \n                   :width=>3, :fill=>color, :outline=>'')\n    TkcOval.new(@canvas, box(812, 122, 9), \n                :tag=>'I1', :fill=>color2, :outline=>'')\n\n    @canvas.itembind('I1', '1'){ start }\n  end\n\n  def move1(step = nil)\n    step = get_step(1, step)\n    pos = [\n      [807, 122], [802, 122], [797, 123], [793, 124], [789, 129], [785, 153], \n      [785, 203], [785, 278, :x], [785, 367], [810, 392], [816, 438], \n      [821, 503], [824, 585, :y], [838, 587], [848, 593], [857, 601], \n      [-100, -100]\n    ]\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I1', where)\n    move15a if where[2] == :y\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Lighting the match\n  def draw2\n    color = @C['2']\n\n    # Fulcrum\n    TkcPolygon.new(@canvas, [750, 369, 740, 392, 760, 392], \n                   :fill=>@C['fg'], :outline=>@C['fg'])\n\n    # Strike box\n    TkcRectangle.new(@canvas, [628, 335, 660, 383], \n                     :fill=>'', :outline=>@C['fg'])\n    (0..2).each{|y|\n      yy = 335 + y*16\n      TkcBitmap.new(@canvas, [628, yy], :bitmap=>'gray25', \n                    :anchor=>:nw, :foreground=>@C['fg'])\n      TkcBitmap.new(@canvas, [644, yy], :bitmap=>'gray25', \n                    :anchor=>:nw, :foreground=>@C['fg'])\n    }\n\n    # Lever\n    TkcLine.new(@canvas, [702, 366, 798, 366], \n                :fill=>@C['fg'], :width=>6, :tag=>'I2_0')\n\n    # R strap\n    TkcLine.new(@canvas, [712, 363, 712, 355], \n                :fill=>@C['fg'], :width=>3, :tag=>'I2_1')\n\n    # L strap\n    TkcLine.new(@canvas, [705, 363, 705, 355], \n                :fill=>@C['fg'], :width=>3, :tag=>'I2_2')\n\n    # Match stick\n    TkcLine.new(@canvas, [679, 356, 679, 360, 717, 360, 717, 356, 679, 356], \n                :fill=>@C['fg'], :width=>3, :tag=>'I2_3')\n\n    # Match head\n    TkcPolygon.new(@canvas, \n                   [ 671, 352, 677.4, 353.9, 680, 358.5, 677.4, 363.1, \n                     671, 365, 664.6, 363.1, 662, 358.5, 664.6, 353.9 ], \n                   :fill=>color, :outline=>color, :tag=>'I2_4')\n  end\n\n  def move2(step = nil)\n    step = get_step(2, step)\n\n    stages = [0, 0, 1, 2, 0, 2, 1, 0, 1, 2, 0, 2, 1]\n    xy = []\n    xy[0] = [\n      686, 333, 692, 323, 682, 316, 674, 309, 671, 295, 668, 307, \n      662, 318, 662, 328, 671, 336\n    ]\n    xy[1] = [\n      687, 331, 698, 322, 703, 295, 680, 320, 668, 297, 663, 311, \n      661, 327, 671, 335\n    ]\n    xy[2] = [\n      686, 331, 704, 322, 688, 300, 678, 283, 678, 283, 674, 298, \n      666, 309, 660, 324, 672, 336\n    ]\n\n    if step >= stages.length\n      @canvas.delete('I2')\n      return 0\n    end\n\n    if step == 0  # Rotate the match\n      beta = 20\n      \n      ox, oy = anchor('I2_0', :s)  # Where to pivot\n\n      i = 0\n      until @canvas.find_withtag(\"I2_#{i}\").empty?\n        rotate_item(\"I2_#{i}\", ox, oy, beta)\n        i += 1\n      end\n\n      # For the flame\n      TkcPolygon.new(@canvas, [], :tag=>'I2', :smooth=>true, :fill=>@C['2'])\n\n      return 1\n    end\n    @canvas.coords('I2', xy[stages[step]])\n    return ((step == 7)? 3: 1)\n  end\n\n  # Weight and pulleys\n  def draw3\n    color = @C['3a']\n    color2 = @C['3b']\n\n    xy = [ [602, 296], [577, 174], [518, 174] ]\n    xy.each{|x, y| # 3 Pulleys\n      TkcOval.new(@canvas, box(x, y, 13), \n                  :fill=>color, :outline=>@C['fg'], :width=>3)\n      TkcOval.new(@canvas, box(x, y, 2), :fill=>@C['fg'], :outline=>@C['fg'])\n    }\n\n    # Wall to flame\n    TkcLine.new(@canvas, [750, 309, 670, 309], :tag=>'I3_s', \n                :width=>3, :fill=>@C['fg'], :smooth=>true)\n\n    # Flame to pulley 1\n    TkcLine.new(@canvas, [670, 309, 650, 309], :tag=>'I3_0', \n                :width=>3, :fill=>@C['fg'], :smooth=>true)\n    TkcLine.new(@canvas, [650, 309, 600, 309], :tag=>'I3_1', \n                :width=>3, :fill=>@C['fg'], :smooth=>true)\n\n    # Pulley 1 half way to 2\n    TkcLine.new(@canvas, [589, 296, 589, 235], :tag=>'I3_2', \n                :width=>3, :fill=>@C['fg'])\n\n    # Pulley 1 other half to 2\n    TkcLine.new(@canvas, [589, 235, 589, 174], :width=>3, :fill=>@C['fg'])\n\n    # Across the top\n    TkcLine.new(@canvas, [577, 161, 518, 161], :width=>3, :fill=>@C['fg'])\n\n    # Down to weight\n    TkcLine.new(@canvas, [505, 174, 505, 205], :tag=>'I3_w', \n                :width=>3, :fill=>@C['fg'])\n\n    # Draw the weight as 2 circles, two rectangles and 1 rounded rectangle\n    x1, y1, x2, y2 = [515, 207, 495, 207]\n    TkcOval.new(@canvas, box(x1, y1, 6), \n                :tag=>'I3_', :fill=>color2, :outline=>color2)\n    TkcOval.new(@canvas, box(x2, y2, 6), \n                :tag=>'I3_', :fill=>color2, :outline=>color2)\n    TkcRectangle.new(@canvas, x1, y1 - 6, x2, y2 + 6, \n                     :tag=>'I3_', :fill=>color2, :outline=>color2)\n    \n    TkcPolygon.new(@canvas, round_rect([492, 220, 518, 263], 15), \n                   :smooth=>true, :tag=>'I3_', :fill=>color2, :outline=>color2)\n\n    TkcLine.new(@canvas, [500, 217, 511, 217], \n                :tag=>'I3_', :fill=>color2, :width=>10)\n\n    # Bottom weight target\n    TkcLine.new(@canvas, [502, 393, 522, 393, 522, 465], \n                :tag=>'I3__', :fill=>@C['fg'], :joinstyle=>:miter, :width=>10)\n  end\n\n  def move3(step = nil)\n    step = get_step(3, step)\n\n    pos = [ [505, 247], [505, 297], [505, 386.5], [505, 386.5] ]\n    rope = []\n    rope[0] = [750, 309, 729, 301, 711, 324, 690, 300]\n    rope[1] = [750, 309, 737, 292, 736, 335, 717, 315, 712, 320]\n    rope[2] = [750, 309, 737, 309, 740, 343, 736, 351, 725, 340]\n    rope[3] = [750, 309, 738, 321, 746, 345, 742, 356]\n\n    return 0 if step >= pos.length\n\n    @canvas.delete(\"I3_#{step}\")        # Delete part of the rope\n    move_abs('I3_', pos[step])          # Move weight down\n    @canvas.coords('I3_s', rope[step])  # Flapping rope end\n    @canvas.coords('I3_w', [505, 174].concat(pos[step]))\n    if step == 2\n      @canvas.move('I3__', 0, 30)\n      return 2\n    end\n    return 1\n  end\n\n  # Cage and door\n  def draw4\n    color = @C['4']\n    x0, y0, x1, y1 = [527, 356, 611, 464]\n\n    # Horizontal bars\n    y0.step(y1, 12){|y|\n      TkcLine.new(@canvas, [x0, y, x1, y], :fill=>color, :width=>1)\n    }\n\n    # Vertical bars\n    x0.step(x1, 12){|x|\n      TkcLine.new(@canvas, [x, y0, x, y1], :fill=>color, :width=>1)\n    }\n\n    # Swing gate\n    TkcLine.new(@canvas, [518, 464, 518, 428], \n                :tag=>'I4', :fill=>color, :width=>1)\n  end\n\n  def move4(step = nil)\n    step = get_step(4, step)\n\n    angles = [-10, -20, -30, -30]\n    return 0 if step >= angles.length\n\n    rotate_item('I4', 518, 464, angles[step])\n    @canvas.raise('I4')\n\n    return((step == 3)? 3: 1)\n  end\n\n  # Mouse\n  def draw5\n    color  = @C['5a']\n    color2 = @C['5b']\n\n    xy = [377, 248, 410, 248, 410, 465, 518, 465]  # Mouse course\n    xy.concat [518, 428, 451, 428, 451, 212, 377, 212]\n\n    TkcPolygon.new(@canvas, xy, :fill=>color2, :outline=>@C['fg'], :width=>3)\n\n    xy = [\n      534.5, 445.5, 541, 440, 552, 436, 560, 436, 569, 440, 574, 446, \n      575, 452, 574, 454, 566, 456, 554, 456, 545, 456, 537, 454, 530, 452\n    ]\n    TkcPolygon.new(@canvas, xy, :tag=>['I5', 'I5_0'], :fill=>color)\n\n    TkcLine.new(@canvas, [573, 452, 592, 458, 601, 460, 613, 456], # Tail\n                :tag=>['I5', 'I5_1'], :fill=>color, :smooth=>true, :width=>3)\n\n    xy = box(540, 446, 2)   # Eye\n    xy = [540, 444, 541, 445, 541, 447, 540, 448, 538, 447, 538, 445]\n    TkcPolygon.new(@canvas, xy, :tag=>['I5', 'I5_2'], :fill=>@C['bg'], \n                   :outline=>'', :smooth=>true)\n\n    xy = [538, 454, 535, 461] # Front leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_3'], :fill=>color, :width=>2)\n\n    xy = [566, 455, 569, 462] # Back leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_4'], :fill=>color, :width=>2)\n\n    xy = [544, 455, 545, 460] # 2nd front leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_5'], :fill=>color, :width=>2)\n\n    xy = [560, 455, 558, 460] # 2nd back leg\n    TkcLine.new(@canvas, xy, :tag=>['I5', 'I5_6'], :fill=>color, :width=>2)\n  end\n\n  def move5(step = nil)\n    step = get_step(5, step)\n\n    pos = [\n      [553, 452], [533, 452], [513, 452], [493, 452], [473, 452], \n      [463, 442, 30], [445.5, 441.5, 30], [425.5, 434.5, 30], [422, 414], \n      [422, 394], [422, 374], [422, 354], [422, 334], [422, 314], [422, 294], \n      [422, 274, -30], [422, 260.5, -30, :x], [422.5, 248.5, -28], [425, 237]\n    ]\n\n    return 0 if step >= pos.length\n\n    x, y, beta, nxt = pos[step]\n    move_abs('I5', [x, y])\n    if beta\n      ox, oy = centroid('I5_0')\n      (0..6).each{|id| rotate_item(\"I5_#{id}\", ox, oy, beta) }\n    end\n    return 3 if nxt == :x\n    return 1\n  end\n\n  # Dropping gumballs\n  def draw6\n    color = @C['6']\n    xy = [324, 130, 391, 204] # Ball holder\n    xy = round_rect(xy, 10)\n    TkcPolygon.new(@canvas, xy, :smooth=>true, \n                   :outline=>@C['fg'], :width=>3, :fill=>color)\n    xy = [339, 204, 376, 253] # Below the ball holder\n    TkcRectangle.new(@canvas, xy, :outline=>@C['fg'], :width=>3, \n                     :fill=>color, :tag=>'I6c')\n    xy = box(346, 339, 28)\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'') # Roter\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>2, :style=>:arc, \n               :start=>80, :extent=>205)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>2, :style=>:arc, \n               :start=>-41, :extent=>85)\n\n    xy = box(346, 339, 15) # Center of rotor\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['fg'], :tag=>'I6m')\n    xy = [352, 312, 352, 254, 368, 254, 368, 322] # Top drop to rotor\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'')\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2)\n\n    xy = [353, 240, 367, 300] # Poke bottom hole\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')\n    xy = [341, 190, 375, 210] # Poke another hole\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')\n\n    xy = [\n      368, 356, 368, 403, 389, 403, 389, 464, 320, 464, 320, 403, \n      352, 403, 352, 366\n    ]\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'', \n                   :width=>2) # Below rotor\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2)\n    xy = box(275, 342, 7) # On/off rotor\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['fg'])\n    xy = [276, 334, 342, 325] # Fan belt top\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = [276, 349, 342, 353] # Fan belt bottom\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n\n    xy = [337, 212, 337, 247] # What the mouse pushes\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I6_')\n    xy = [392, 212, 392, 247]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I6_')\n    xy = [337, 230, 392, 230]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>7, :tag=>'I6_')\n\n    who = -1 # All the balls\n    colors = %w(red cyan orange green blue darkblue)\n    colors *= 3\n\n    (0..16).each{|i|\n      loc = -i\n      color = colors[i]\n      x, y = @XY6[\"#{loc}\"]\n      TkcOval.new(@canvas, box(x, y, 5), \n                  :fill=>color, :outline=>color, :tag=>\"I6_b#{i}\")\n    }\n    draw6a(12) # The wheel\n  end\n\n  def draw6a(beta)\n    @canvas.delete('I6_0')\n    ox, oy = [346, 339]\n    (0..3).each{|i|\n      b = beta + i * 45\n      x, y = rotate_c(28, 0, 0, 0, b)\n      xy = [ox + x, oy + y, ox - x, oy - y]\n      TkcLine.new(@canvas, xy, :tag=>'I6_0', :fill=>@C['fg'], :width=>2)\n    }\n  end\n\n  def move6(step = nil)\n    step = get_step(6, step)\n\n    return 0 if step > 62\n\n    if step < 2  # Open gate for balls to drop\n      @canvas.move('I6_', -7, 0)\n      if step == 1  # Poke a hole\n        xy = [348, 226, 365, 240]\n        TkcRectangle.new(@canvas, xy, :fill=>@canvas.itemcget('I6c', :fill), \n                         :outline=>'')\n      end\n      return 1\n    end\n\n    s = step - 1  # Do the gumball drop dance\n    (0..(((s - 1)/3).to_i)).each{|i|\n      tag = \"I6_b#{i}\"\n      break if @canvas.find_withtag(tag).empty?\n      loc = s - 3*i\n\n      if @XY6[\"#{loc},#{i}\"]\n        move_abs(tag, @XY6[\"#{loc},#{i}\"])\n      elsif @XY6[\"#{loc}\"]\n        move_abs(tag, @XY6[\"#{loc}\"])\n      end\n    }\n    if s % 3 == 1\n      first = (s + 2)/3\n      i = first\n      loop {\n        tag = \"I6_b#{i}\"\n        break if @canvas.find_withtag(tag).empty?\n        loc = first - i\n        move_abs(tag, @XY6[\"#{loc}\"])\n        i += 1\n      }\n    end\n    if s >= 3  # Rotate the motor\n      idx = s % 3\n      draw6a(12 + s * 15)\n    end\n    return((s == 3)? 3 : 1)\n  end\n\n  # On/off switch\n  def draw7\n    color = @C['7']\n    xy = [198, 306, 277, 374]  # Box\n    TkcRectangle.new(@canvas, xy, :outline=>@C['fg'], :width=>2, \n                     :fill=>color, :tag=>'I7z')\n    @canvas.lower('I7z')\n    xy = [275, 343, 230, 349]\n    TkcLine.new(@canvas, xy, :tag=>'I7', :fill=>@C['fg'], :arrow=>:last, \n                :arrowshape=>[23, 23, 8], :width=>6)\n    xy = [225, 324]  # On button\n    x, y = xy\n    TkcOval.new(@canvas, box(x, y, 3), :fill=>@C['fg'], :outline=>@C['fg'])\n    xy = [218, 323]  # On text\n    font = ['Times Roman', 8]\n    TkcText.new(@canvas, xy, :text=>'on', :anchor=>:e, \n                :fill=>@C['fg'], :font=>font)\n    xy = [225, 350]  # Off button\n    x, y = xy\n    TkcOval.new(@canvas, box(x, y, 3), :fill=>@C['fg'], :outline=>@C['fg'])\n    xy = [218, 349]  # Off text\n    TkcText.new(@canvas, xy, :text=>'off', :anchor=>:e, \n                :fill=>@C['fg'], :font=>font)\n  end\n\n  def move7(step = nil)\n    step = get_step(7, step)\n\n    numsteps = 30\n    return 0 if step > numsteps\n    beta = 30.0 / numsteps\n    rotate_item('I7', 275, 343, beta)\n\n    return((step == numsteps)? 3: 1)\n  end\n\n  # Electricity to the fan\n  def draw8\n    sine([271, 248, 271, 306], 5, 8, :tag=>'I8_s', :fill=>@C['8'], :width=>3)\n  end\n\n  def move8(step = nil)\n    step = get_step(8, step)\n\n    return 0 if step > 3\n    if step == 0\n      sparkle(anchor('I8_s', :s), 'I8')\n      return 1\n    elsif step == 1\n      move_abs('I8', anchor('I8_s', :c))\n    elsif step == 2\n      move_abs('I8', anchor('I8_s', :n))\n    else\n      @canvas.delete('I8')\n    end\n    return((step == 2)? 3: 1)\n  end\n\n  # Fan\n  def draw9\n    color = @C['9']\n    xy = [266, 194, 310, 220]\n    TkcOval.new(@canvas, xy, :outline=>color, :fill=>color)\n    xy = [280, 209, 296, 248]\n    TkcOval.new(@canvas, xy, :outline=>color, :fill=>color)\n    xy = [\n      288, 249, 252, 249, 260, 240, 280, 234, \n      296, 234, 316, 240, 324, 249, 288, 249\n    ]\n    TkcPolygon.new(@canvas, xy, :fill=>color, :smooth=>true)\n\n    xy = [248, 205, 265, 214, 264, 205, 265, 196]  # Spinner\n    TkcPolygon.new(@canvas, xy, :fill=>color)\n\n    xy = [255, 206, 265, 234]  # Fan blades\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>3, :tag=>'I9_0')\n    xy = [255, 176, 265, 204]\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>3, :tag=>'I9_0')\n    xy = [255, 206, 265, 220]\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>1, :tag=>'I9_1')\n    xy = [255, 190, 265, 204]\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], \n                :width=>1, :tag=>'I9_1')\n  end\n\n  def move9(step = nil)\n    step = get_step(9, step)\n\n    if (step & 1).nonzero?\n      @canvas.itemconfigure('I9_0', :width=>4)\n      @canvas.itemconfigure('I9_1', :width=>1)\n      @canvas.lower('I9_1', 'I9_0')\n    else\n      @canvas.itemconfigure('I9_0', :width=>1)\n      @canvas.itemconfigure('I9_1', :width=>4)\n      @canvas.lower('I9_0', 'I9_1')\n    end\n    return 3 if step == 0\n    return 1\n  end\n\n  # Boat\n  def draw10\n    color  = @C['10a']\n    color2 = @C['10b']\n    xy = [191, 230, 233, 230, 233, 178, 191, 178]  # Sail\n    TkcPolygon.new(@canvas, xy, :fill=>color, :width=>3, :outline=>@C['fg'], \n                   :tag=>'I10')\n    xy = box(209, 204, 31)  # Front\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :style=>:pie, \n               :start=>120, :extent=>120, :tag=>'I10')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>120, :extent=>120, :tag=>'I10')\n    xy = box(249, 204, 31)  # Back\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>3, \n               :style=>:pie, :start=>120, :extent=>120, :tag=>'I10')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>120, :extent=>120, :tag=>'I10')\n\n    xy = [200, 171, 200, 249]  # Mast\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I10')\n    xy = [159, 234, 182, 234]  # Bow sprit\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I10')\n    xy = [180, 234, 180, 251, 220, 251]  # Hull\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>6, :tag=>'I10')\n\n    xy = [92, 255, 221, 255]  # Waves\n    sine(xy, 2, 25, :fill=>color2, :width=>1, :tag=>'I10w')\n\n    xy = @canvas.coords('I10w')[4..-5]  # Water\n    xy.concat([222, 266, 222, 277, 99, 277])\n    TkcPolygon.new(@canvas, xy, :fill=>color2, :outline=>color2)\n    xy = [222, 266, 222, 277, 97, 277, 97, 266]  # Water bottom\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n\n    xy = box(239, 262, 17)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>95, :extent=>103)\n    xy = box(76, 266, 21)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :extent=>190)\n  end\n\n  def move10(step = nil)\n    step = get_step(10, step)\n\n    pos = [\n      [195, 212], [193, 212], [190, 212], [186, 212], [181, 212], [176, 212], \n      [171, 212], [166, 212], [161, 212], [156, 212], [151, 212], [147, 212], \n      [142, 212], [137, 212], [132, 212, :x], [127, 212], [121, 212], \n      [116, 212], [111, 212]\n    ]\n\n    return 0 if step >= pos.length\n\n    where = pos[step]\n    move_abs('I10', where)\n\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # 2nd ball drop\n  def draw11\n    color  = @C['11a']\n    color2 = @C['11b']\n    xy = [23, 264, 55, 591]  # Color the down tube\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>'')\n    xy = box(71, 460, 48)    # Color the outer loop\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'')\n\n    xy = [55, 264, 55, 458]  # Top right side\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = [55, 504, 55, 591]  # Bottom right side\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = box(71, 460, 48)    # Outer loop\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>110, :extent=>-290, :tag=>'I11i')\n    xy = box(71, 460, 16)    # Inner loop\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>'', \n                :width=>3, :tag=>'I11i')\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>@C['bg'], :width=>3)\n\n    xy = [23, 264, 23, 591]  # Left side\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = box(1, 266, 23)     # Top left curve\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, \n               :style=>:arc, :extent=>90)\n\n    xy = box(75, 235, 9)     # The ball\n    TkcOval.new(@canvas, xy, :fill=>color2, :outline=>'', \n                :width=>3, :tag=>'I11')\n  end\n\n  def move11(step = nil)\n    step = get_step(11, step)\n\n    pos = [\n      [75, 235], [70, 235], [65, 237], [56, 240], [46, 247], [38, 266], \n      [38, 296], [38, 333], [38, 399], [38, 475], [74, 496], [105, 472], \n      [100, 437], [65, 423], [-100, -100], [38, 505], [38, 527, :x], [38, 591]\n    ]\n\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I11', where)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Hand\n  def draw12\n    xy = [\n      20, 637, 20, 617, 20, 610, 20, 590, 40, 590, 40, 590, \n      60, 590, 60, 610, 60, 610\n    ]\n    xy.concat([60, 610, 65, 620, 60, 631])  # Thumb\n    xy.concat([60, 631, 60, 637, 60, 662, 60, 669, 52, 669, \n                56, 669, 50, 669, 50, 662, 50, 637])\n\n    y0 = 637  # Bumps for fingers\n    y1 = 645\n    50.step(21, -10){|x|\n      x1 = x - 5\n      x2 = x - 10\n      xy << x << y0 << x1 << y1 << x2 << y0\n    }\n    TkcPolygon.new(@canvas, xy, :fill=>@C['12'], :outline=>@C['fg'], \n                   :smooth=>true, :tag=>'I12', :width=>3)\n  end\n\n  def move12(step = nil)\n    step = get_step(12, step)\n\n    pos = [[42.5, 641, :x]]\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I12', where)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Fax\n  def draw13\n    color = @C['13a']\n    xy = [86, 663, 149, 663, 149, 704, 50, 704, 50, 681, 64, 681, 86, 671]\n    xy2 = [\n      784, 663, 721, 663, 721, 704, 820, 704, 820, 681, 806, 681, 784, 671\n    ]\n    radii = [2, 9, 9, 8, 5, 5, 2]\n\n    round_poly(@canvas, xy, radii, :width=>3, \n               :outline=>@C['fg'], :fill=>color)\n    round_poly(@canvas, xy2, radii, :width=>3, \n               :outline=>@C['fg'], :fill=>color)\n\n    xy = [56, 677]\n    x, y = xy\n    TkcRectangle.new(@canvas, box(x, y, 4), :fill=>'', :outline=>@C['fg'], \n                     :width=>3, :tag=>'I13')\n    xy = [809, 677]\n    x, y = xy\n    TkcRectangle.new(@canvas, box(x, y, 4), :fill=>'', :outline=>@C['fg'], \n                     :width=>3, :tag=>'I13R')\n\n    xy = [112, 687]  # Label\n    TkcText.new(@canvas, xy, :text=>'FAX', :fill=>@C['fg'], \n                :font=>['Times Roman', 12, :bold])\n    xy = [762, 687]\n    TkcText.new(@canvas, xy, :text=>'FAX', :fill=>@C['fg'], \n                :font=>['Times Roman', 12, :bold])\n\n    xy = [138, 663, 148, 636, 178, 636]  # Paper guide\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>@C['fg'], :width=>3)\n    xy = [732, 663, 722, 636, 692, 636]\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>@C['fg'], :width=>3)\n\n    sine([149, 688, 720, 688], 5, 15, \n         :tag=>'I13_s', :fill=>@C['fg'],  :width=>3)\n  end\n\n  def move13(step = nil)\n    step = get_step(13, step)\n\n    numsteps = 7\n\n    if step == numsteps + 2\n      move_abs('I13_star', [-100, -100])\n      @canvas.itemconfigure('I13R', :fill=>@C['13b'], :width=>2)\n      return 2\n    end\n    if step == 0  # Button down\n      @canvas.delete('I13')\n      sparkle([-100, -100], 'I13_star')  # Create off screen\n      return 1\n    end\n    x0, y0 = anchor('I13_s', :w)\n    x1, y1 = anchor('I13_s', :e)\n    x = x0 + (x1 - x0) * (step - 1) / numsteps.to_f\n    move_abs('I13_star', [x, y0])\n    return 1\n  end\n\n  # Paper in fax\n  def draw14\n    color = @C['14']\n    xy = [102, 661, 113, 632, 130, 618]  # Left paper edge\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14L_0')\n    xy = [148, 629, 125, 640, 124, 662]  # Right paper edge\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14L_1')\n    draw14a('L')\n\n    xy = [\n      768.0, 662.5, 767.991316225, 662.433786215, 767.926187912, 662.396880171\n    ]\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14R_0')\n    @canvas.lower('I14R_0')\n    # NB. these numbers are VERY sensitive, you must start with final size\n    # and shrink down to get the values\n    xy = [\n      745.947897349, 662.428358855, 745.997829056, 662.452239237, 746.0, 662.5\n    ]\n    TkcLine.new(@canvas, xy, :smooth=>true, :fill=>color, \n                :width=>3, :tag=>'I14R_1')\n    @canvas.lower('I14R_1')\n  end\n\n  def draw14a(side)\n    color = @C['14']\n    xy = @canvas.coords(\"I14#{side}_0\")\n    xy2 = @canvas.coords(\"I14#{side}_1\")\n    x0, y0, x1, y1, x2, y2 = xy\n    x3, y3, x4, y4, x5, y5 = xy2\n\n    zz = [\n      x0, y0, x0, y0, xy, x2, y2, x2, y2, \n      x3, y3, x3, y3, xy2, x5, y5, x5, y5\n    ].flatten\n    @canvas.delete(\"I14#{side}\")\n    TkcPolygon.new(@canvas, zz, :tag=>\"I14#{side}\", :smooth=>true, \n                   :fill=>color, :outline=>color, :width=>3)\n    @canvas.lower(\"I14#{side}\")\n  end\n\n  def move14(step = nil)\n    step = get_step(14, step)\n\n    # Paper going down\n    sc = 0.9 - 0.05*step\n    if sc < 0.3\n      @canvas.delete('I14L')\n      return 0\n    end\n\n    ox, oy = @canvas.coords('I14L_0')\n    @canvas.scale('I14L_0', ox, oy, sc, sc)\n    ox, oy = @canvas.coords('I14L_1')[-2..-1]\n    @canvas.scale('I14L_1', ox, oy, sc, sc)\n    draw14a('L')\n\n    # Paper going up\n    sc = 0.35 + 0.05*step\n    sc = 1/sc\n\n    ox, oy = @canvas.coords('I14R_0')\n    @canvas.scale('I14R_0', ox, oy, sc, sc)\n    ox, oy = @canvas.coords('I14R_1')[-2..-1]\n    @canvas.scale('I14R_1', ox, oy, sc, sc)\n    draw14a('R')\n\n    return((step == 10)? 3: 1)\n  end\n\n  # Light beam\n  def draw15\n    color = @C['15a']\n    xy = [824, 599, 824, 585, 820, 585, 829, 585]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I15a')\n    xy = [789, 599, 836, 643]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n    xy = [778, 610, 788, 632]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n    xy = [766, 617, 776, 625]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n\n    xy = [633, 600, 681, 640]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>3)\n    xy = [635, 567, 657, 599]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2)\n    xy = [765, 557, 784, 583]\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2)\n\n    sine([658, 580, 765, 580], 3, 15, \n         :tag=>'I15_s', :fill=>@C['fg'], :width=>3)\n  end\n\n  def move15a\n    color = @C['15b']\n    @canvas.scale('I15a', 824, 599, 1, 0.3)  # Button down\n    xy = [765, 621, 681, 621]\n    TkcLine.new(@canvas, xy, :dash=>'-', :width=>3, :fill=>color, :tag=>'I15')\n  end\n\n  def move15(step = nil)\n    step = get_step(15, step)\n\n    numsteps = 6\n\n    if step == numsteps + 2\n      move_abs('I15_star', [-100, -100])\n      return 2\n    end\n    if step == 0  # Break the light beam\n      sparkle([-100, -100], 'I15_star')\n      xy = [765, 621, 745, 621]\n      @canvas.coords('I15', xy)\n      return 1\n    end\n    x0, y0 = anchor('I15_s', :w)\n    x1, y1 = anchor('I15_s', :e)\n    x = x0 + (x1 - x0) * (step - 1) / numsteps.to_f\n    move_abs('I15_star', [x, y0])\n    return 1\n  end\n\n  # Bell\n  def draw16\n    color = @C['16']\n    xy = [722, 485, 791, 556]\n    TkcRectangle.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], :width=>3)\n    xy = box(752, 515, 25)  # Bell\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'black', \n                :tag=>'I16b', :width=>2)\n    xy = box(752, 515, 5)   # Bell button\n    TkcOval.new(@canvas, xy, :fill=>'black', :outline=>'black', :tag=>'I16b')\n\n    xy = [784, 523, 764, 549]  # Clapper\n    TkcLine.new(@canvas, xy, :width=>3, :tag=>'I16c', :fill=>@C['fg'])\n    xy = box(784, 523, 4)\n    TkcOval.new(@canvas, xy, :fill=>@C['fg'], :outline=>@C['fg'], :tag=>'I16d')\n  end\n\n  def move16(step = nil)\n    step = get_step(16, step)\n\n    # Note: we never stop\n    ox, oy = [760, 553]\n    if (step & 1).nonzero?\n      beta = 12\n      @canvas.move('I16b', 3, 0)\n    else\n      beta = -12\n      @canvas.move('I16b', -3, 0)\n    end\n    rotate_item('I16c', ox, oy, beta)\n    rotate_item('I16d', ox, oy, beta)\n\n    return ((step == 1)? 3: 1)\n  end\n\n  # Cat\n  def draw17\n    color = @C['17']\n\n    xy = [584, 556, 722, 556]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n    xy = [584, 485, 722, 485]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3)\n\n    xy = [664, 523, 717, 549]  # Body\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, :width=>3, \n               :style=>:chord, :start=>128, :extent=>260, :tag=>'I17')\n\n    xy = [709, 554, 690, 543]  # Paw\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, \n                :width=>3, :tag=>'I17')\n    xy = [657, 544, 676, 555]\n    TkcOval.new(@canvas, xy, :outline=>@C['fg'], :fill=>color, \n                :width=>3, :tag=>'I17')\n\n    xy = box(660, 535, 15)     # Lower face\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :style=>:arc, \n               :start=>150, :extent=>240, :tag=>'I17_')\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:chord, :start=>150, :extent=>240, :tag=>'I17_')\n    xy = [674, 529, 670, 513, 662, 521, 658, 521, 650, 513, 647, 529]  # Ears\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>'', :width=>1, \n                   :tag=>['I17_', 'I17_c'])\n    xy = [652, 542, 628, 539]  # Whiskers\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n    xy = [652, 543, 632, 545]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n    xy = [652, 546, 632, 552]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n\n    xy = [668, 543, 687, 538]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                :tag=>['I17_', 'I17_w'])\n    xy = [668, 544, 688, 546]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                :tag=>['I17_', 'I17_w'])\n    xy = [668, 547, 688, 553]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                :tag=>['I17_', 'I17_w'])\n\n    xy = [649, 530, 654, 538, 659, 530]  # Left eye\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, \n                :smooth=>true, :tag=>'I17')\n    xy = [671, 530, 666, 538, 661, 530]  # Right eye\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, \n                :smooth=>true, :tag=>'I17')\n    xy = [655, 543, 660, 551, 665, 543]  # Mouth\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, \n                :smooth=>true, :tag=>'I17')\n  end\n\n  def move17(step = nil)\n    step = get_step(17, step)\n\n    if step == 0\n      @canvas.delete('I17')  # Delete most of the cat\n      xy = [655, 543, 660, 535, 665, 543]  # Mouth\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3,\n                  :smooth=>true, :tag=>'I17_')\n      xy = box(654, 530, 4)  # Left eye\n      TkcOval.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :fill=>'', \n                  :tag=>'I17_')\n      xy = box(666, 530, 4)  # Right eye\n      TkcOval.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :fill=>'', \n                  :tag=>'I17_')\n\n      @canvas.move('I17_', 0, -20) # Move face up\n      xy = [652, 528, 652, 554]    # Front leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n      xy = [670, 528, 670, 554]    # 2nd front leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n\n      xy = [ # Body\n        675, 506, 694, 489, 715, 513, 715, 513, 715, 513, 716, 525, \n        716, 525, 716, 525, 706, 530, 695, 530, 679, 535, 668, 527, \n        668, 527, 668, 527, 675, 522, 676, 517, 677, 512\n      ]\n      TkcPolygon.new(@canvas, xy, :fill=>@canvas.itemcget('I17_c', :fill), \n                     :outline=>@C['fg'], :width=>3, :smooth=>true, \n                     :tag=>'I17_')\n      xy = [716, 514, 716, 554]  # Back leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n      xy = [694, 532, 694, 554]  # 2nd back leg\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I17_')\n      xy = [715, 514, 718, 506, 719, 495, 716, 488]  # Tail\n      TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, \n                  :smooth=>true, :tag=>'I17_')\n\n      @canvas.raise('I17w')       # Make whiskers visible\n      @canvas.move('I17_', -5, 0) # Move away from the wall a bit\n      return 2\n    end\n    return 0\n  end\n\n  # Sling shot\n  def draw18\n    color = @C['18']\n    xy = [721, 506, 627, 506]  # Sling hold\n    TkcLine.new(@canvas, xy, :width=>4, :fill=>@C['fg'], :tag=>'I18')\n\n    xy = [607, 500, 628, 513]  # Sling rock\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'', :tag=>'I18a')\n\n    xy = [526, 513, 606, 507, 494, 502]  # Sling band\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>4, :tag=>'I18b')\n    xy = [485, 490, 510, 540, 510, 575, 510, 540, 535, 491]  # Sling\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>6)\n  end\n\n  def move18(step = nil)\n    step = get_step(18, step)\n\n    pos = [\n      [587, 506], [537, 506], [466, 506], [376, 506], [266, 506, :x], \n      [136, 506], [16, 506], [-100, -100]\n    ]\n\n    b = []\n    b[0] = [490, 502, 719, 507, 524, 512]  # Band collapsing\n    b[1] = [\n      491, 503, 524, 557, 563, 505, 559, 496, 546, 506, 551, 525, \n      553, 536, 538, 534, 532, 519, 529, 499\n    ]\n    b[2] = [\n      491, 503, 508, 563, 542, 533, 551, 526, 561, 539, 549, 550, 530, 500\n    ]\n    b[3] = [\n      491, 503, 508, 563, 530, 554, 541, 562, 525, 568, 519, 544, 530, 501\n    ]\n\n    return 0 if step >= pos.length\n\n    if step == 0\n      @canvas.delete('I18')\n      @canvas.itemconfigure('I18b', :smooth=>true)\n    end\n    if b[step]\n      @canvas.coords('I18b', b[step])\n    end\n\n    where = pos[step]\n    move_abs('I18a', where)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Water pipe\n  def draw19\n    color = @C['19']\n    xx = [[249, 181], [155, 118], [86, 55], [22, 0]]\n    xx.each{|x1, x2|\n      TkcRectangle.new(@canvas, x1, 453, x2, 467, \n                       :fill=>color, :outline=>'', :tag=>'I19')\n      TkcLine.new(@canvas, x1, 453, x2, 453, \n                  :fill=>@C['fg'], :width=>1) # Pipe top\n      TkcLine.new(@canvas, x1, 467, x2, 467, \n                  :fill=>@C['fg'], :width=>1) # Pipe bottom\n    }\n    @canvas.raise('I11i')\n\n    xy = box(168, 460, 16)  # Bulge by the joint\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, :style=>:arc, \n               :start=>21, :extent=>136)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, :style=>:arc, \n               :start=>-21, :extent=>-130)\n\n    xy = [249, 447, 255, 473]  # First joint 26x6\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n\n    xy = box(257, 433, 34)     # Bend up\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:pie, :start=>0, :extent=>-91)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>-90)\n    xy = box(257, 433, 20)\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1, \n               :style=>:pie, :start=>0, :extent=>-92)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>-90)\n    xy = box(257, 421, 34)     # Bend left\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:pie, :start=>0, :extent=>91)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>90)\n    xy = box(257, 421, 20)\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1, \n               :style=>:pie, :start=>0, :extent=>90)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>0, :extent=>90)\n    xy = box(243, 421, 34)     # Bend down\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>color, :width=>1, \n               :style=>:pie, :start=>90, :extent=>90)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>90, :extent=>90)\n    xy = box(243, 421, 20)\n    TkcArc.new(@canvas, xy, :outline=>'', :fill=>@C['bg'], :width=>1, \n               :style=>:pie, :start=>90, :extent=>90)\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>1, \n               :style=>:arc, :start=>90, :extent=>90)\n\n    xy = [270, 427, 296, 433]  # 2nd joint bottom\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [270, 421, 296, 427]  # 2nd joint top\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [249, 382, 255, 408]  # Third joint right\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [243, 382, 249, 408]  # Third joint left\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n    xy = [203, 420, 229, 426]  # Last joint\n    TkcRectangle.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>1)\n\n    xy = box(168, 460, 6)      # Handle joint\n    TkcOval.new(@canvas, xy, :fill=>@C['fg'], :outline=>'', :tag=>'I19a')\n    xy = [168, 460, 168, 512]  # Handle bar\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>5, :tag=>'I19b')\n  end\n\n  def move19(step = nil)\n    step = get_step(19, step)\n\n     angles = [30, 30, 30]\n    return 2 if step == angles.length\n    ox, oy = centroid('I19a')\n    rotate_item('I19b', ox, oy, angles[step])\n\n    return 1\n  end\n\n  # Water pouring\n  def draw20\n    # do nothing\n  end\n\n  def move20(step = nil)\n    step = get_step(20, step)\n\n    pos  = [451, 462, 473, 484, 496, 504, 513, 523, 532]\n    freq  = [20,  40,  40,  40,  40,  40,  40,  40,  40]\n    pos = [\n      [451, 20], [462, 40], [473, 40], [484, 40], [496, 40], \n      [504, 40], [513, 40], [523, 40], [532, 40, :x]\n    ]\n    return 0 if step >= pos.length\n\n    @canvas.delete('I20')\n    where = pos[step]\n    y, f = where\n    h20(y, f)\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  def h20(y, f)\n    color = @C['20']\n    @canvas.delete('I20')\n\n    sine([208, 428, 208, y], 4, f, :tag=>['I20', 'I20s'], \n         :width=>3, :fill=>color, :smooth=>true)\n    TkcLine.new(@canvas, @canvas.coords('I20s'), :width=>3, \n                :fill=>color, :smooth=>1, :tag=>['I20', 'I20a'])\n    TkcLine.new(@canvas, @canvas.coords('I20s'), :width=>3, \n                :fill=>color, :smooth=>1, :tag=>['I20', 'I20b'])\n    @canvas.move('I20a', 8, 0)\n    @canvas.move('I20b', 16, 0)\n  end\n\n  # Bucket\n  def draw21\n    color = @C['21']\n    xy = [217, 451, 244, 490]  # Right handle\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21_a')\n    xy = [201, 467, 182, 490]  # Left handle\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21_a')\n\n    xy = [245, 490, 237, 535]  # Right side\n    xy2 = [189, 535, 181, 490] # Left side\n    TkcPolygon.new(@canvas, xy + xy2, :fill=>color, :outline=>'', \n                   :tag=>['I21', 'I21f'])\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>2, :tag=>'I21')\n    TkcLine.new(@canvas, xy2, :fill=>@C['fg'], :width=>2, :tag=>'I21')\n\n    xy = [182, 486, 244, 498]  # Top\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>'', :width=>2, \n                :tag=>['I21', 'I21f'])\n    TkcOval.new(@canvas, xy, :fill=>'', :outline=>@C['fg'], :width=>2, \n                :tag=>['I21', 'I21t'])\n    xy = [189, 532, 237, 540]  # Bottom\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], :width=>2, \n                :tag=>['I21', 'I21b'])\n  end\n\n  def move21(step = nil)\n    step = get_step(21, step)\n\n    numsteps = 30\n    return 0 if step >= numsteps\n\n    x1, y1, x2, y2 = @canvas.coords('I21b')\n    # lx1, ly1, lx2, ly2 = @canvas.coords('I21t')\n    lx1, ly1, lx2, ly2 = [183, 492, 243, 504]\n\n    f = step / numsteps.to_f\n    y2 = y2 - 3\n    xx1 = x1 + (lx1 - x1) * f\n    yy1 = y1 + (ly1 - y1) * f\n    xx2 = x2 + (lx2 - x2) * f\n    yy2 = y2 + (ly2 - y2) * f\n\n    @canvas.itemconfigure('I21b', :fill=>@C['20'])\n    @canvas.delete('I21w')\n    TkcPolygon.new(@canvas, x2, y2, x1, y1, xx1, yy1, xx2, yy1, \n                   :tag=>['I21', 'I21w'], :outline=>'', :fill=>@C['20'])\n    @canvas.lower('I21w', 'I21')\n    @canvas.raise('I21b')\n    @canvas.lower('I21f')\n\n    return((step == numsteps - 1)? 3: 1)\n  end\n\n  # Bucket drop\n  def draw22\n    # do nothing\n  end\n\n  def move22(step = nil)\n    step = get_step(22, step)\n    pos = [[213, 513], [213, 523], [213, 543, :x], [213, 583], [213, 593]]\n\n    @canvas.itemconfigure('I21f', :fill=>@C['22']) if step == 0\n    return 0 if step >= pos.length\n    where = pos[step]\n    move_abs('I21', where)\n    h20(where[1], 40)\n    @canvas.delete('I21_a')  # Delete handles\n\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Blow dart\n  def draw23\n    color  = @C['23a']\n    color2 = @C['23b']\n    color3 = @C['23c']\n\n    xy = [185, 623, 253, 650]  # Block\n    TkcRectangle.new(@canvas, xy, :fill=>'black', :outline=>@C['fg'], \n                     :width=>2, :tag=>'I23a')\n    xy = [187, 592, 241, 623]  # Balloon\n    TkcOval.new(@canvas, xy, :outline=>'', :fill=>color, :tag=>'I23b')\n    TkcArc.new(@canvas, xy, :outline=>@C['fg'], :width=>3, :tag=>'I23b', \n               :style=>:arc, :start=>12, :extent=>336)\n    xy = [239, 604, 258, 589, 258, 625, 239, 610]  # Balloon nozzle\n    TkcPolygon.new(@canvas, xy, :outline=>'', :fill=>color, :tag=>'I23b')\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23b')\n\n    xy = [285, 611, 250, 603]  # Dart body\n    TkcOval.new(@canvas, xy, :fill=>color2, :outline=>@C['fg'], \n                :width=>3, :tag=>'I23d')\n    xy = [249, 596, 249, 618, 264, 607, 249, 596]  # Dart tail\n    TkcPolygon.new(@canvas, xy, :fill=>color3, :outline=>@C['fg'], \n                   :width=>3, :tag=>'I23d')\n    xy = [249, 607, 268, 607]  # Dart detail\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23d')\n    xy = [285, 607, 305, 607]  # Dart needle\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I23d')\n  end\n\n  def move23(step = nil)\n    step = get_step(23, step)\n\n    pos = [\n      [277, 607], [287, 607], [307, 607, :x], [347, 607], [407, 607], \n      [487, 607], [587, 607], [687, 607], [787, 607], [-100, -100]\n    ]\n\n    return 0 if step >= pos.length\n    if step <= 1\n      ox, oy = anchor('I23a', :n)\n      @canvas.scale('I23b', ox, oy, 0.9, 0.5)\n    end\n    where = pos[step]\n    move_abs('I23d', where)\n\n    return 3 if where[2] == :x\n    return 1\n  end\n\n  # Balloon\n  def draw24\n    color = @C['24a']\n    xy = [366, 518, 462, 665]  # Balloon\n    TkcOval.new(@canvas, xy, :fill=>color, :outline=>@C['fg'], \n                :width=>3, :tag=>'I24')\n    xy = [414, 666, 414, 729]  # String\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :width=>3, :tag=>'I24')\n    xy = [410, 666, 404, 673, 422, 673, 418, 666]  # Nozzle\n    TkcPolygon.new(@canvas, xy, :fill=>color, :outline=>@C['fg'],\n                   :width=>3, :tag=>'I24')\n\n    xy = [387, 567, 390, 549, 404, 542]  # Reflections\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n    xy = [395, 568, 399, 554, 413, 547]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n    xy = [403, 570, 396, 555, 381, 553]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n    xy = [408, 564, 402, 547, 386, 545]\n    TkcLine.new(@canvas, xy, :fill=>@C['fg'], :smooth=>true, \n                :width=>2, :tag=>'I24')\n  end\n\n  def move24(step = nil)\n    step = get_step(24, step)\n\n    return 0 if step > 4\n    return 2 if step == 4\n\n    if step == 0\n      @canvas.delete('I24')  # Exploding balloon\n      xy = [\n        347, 465, 361, 557, 271, 503, 272, 503, 342, 574, 259, 594, \n        259, 593, 362, 626, 320, 737, 320, 740, 398, 691, 436, 738, \n        436, 739, 476, 679, 528, 701, 527, 702, 494, 627, 548, 613, \n        548, 613, 480, 574, 577, 473, 577, 473, 474, 538, 445, 508, \n        431, 441, 431, 440, 400, 502, 347, 465, 347, 465\n      ]\n      TkcPolygon.new(@canvas, xy, :tag=>'I24', :fill=>@C['24b'], \n                     :outline=>@C['24a'], :width=>10, :smooth=>true)\n      msg = Tk.subst(@S['message'].value)\n      TkcText.new(@canvas, centroid('I24'), :text=>msg, :tag=>['I24', 'I24t'], \n                  :justify=>:center, :font=>['Times Roman', 18, :bold])\n      return 1\n    end\n\n    @canvas.itemconfigure('I24t', :font=>['Times Roman', 18 + 6*step, :bold])\n    @canvas.move('I24', 0, -60)\n    ox, oy = centroid('I24')\n    @canvas.scale('I24', ox, oy, 1.25, 1.25)\n    return 1\n  end\n\n  # Displaying the message\n  def move25(step = nil)\n    step = get_step(25, step)\n\n    if step == 0\n      @XY['25'] = Tk::Clock.clicks(:miliseconds)\n      return 1\n    end\n    elapsed = Tk::Clock.clicks(:miliseconds) - @XY['25']\n    return 1 if elapsed < 5000\n    return 2\n  end\n\n  # Collapsing balloon\n  def move26(step = nil)\n    step = get_step(26, step)\n\n    if step >= 3\n      @canvas.delete('I24', 'I26')\n      TkcText.new(@canvas, 430, 735, :anchor=>:s, :tag=>'I26', \n                  #:text=>'click to continue', \n                  :text=>'åǥꥻåȤޤ', \n                  :font=>['Times Roman', 20, :bold])\n      @canvas.bind('1', proc{reset})\n      return 4\n    end\n\n    ox, oy = centroid('I24')\n    @canvas.scale('I24', ox, oy, 0.8, 0.8)\n    @canvas.move('I24', 0, 60)\n    @canvas.itemconfigure('I24t', :font=>['Times Roman', 30 - 6*step, :bold])\n    return 1\n  end\n\n  ################################################################\n  #\n  # Helper functions\n  #\n  def box(x, y, r)\n    [x - r, y - r, x + r, y + r]\n  end\n\n  def move_abs(item, xy)\n    x, y = xy\n    ox, oy = centroid(item)\n    dx = x - ox\n    dy = y - oy\n    @canvas.move(item, dx, dy)\n  end\n\n  def rotate_item(item, ox, oy, beta)\n    xy = @canvas.coords(item)\n    xy2 = []\n    0.step(xy.length - 1, 2){|idx|\n      x, y = xy[idx, 2]\n      xy2.concat(rotate_c(x, y, ox, oy, beta))\n    }\n    @canvas.coords(item, xy2)\n  end\n\n  def rotate_c(x, y, ox, oy, beta)\n    # rotates vector (ox,oy)->(x,y) by beta degrees clockwise\n\n    x -= ox    # Shift to origin\n    y -= oy\n\n    beta = beta * Math.atan(1) * 4 / 180.0        # Radians\n    xx = x * Math.cos(beta) - y * Math.sin(beta)  # Rotate\n    yy = x * Math.sin(beta) + y * Math.cos(beta)\n\n    xx += ox  # Shift back\n    yy += oy\n\n    [xx, yy]\n  end\n\n  def reset\n    draw_all\n    @canvas.bind_remove('1')\n    @S['mode'].value = :MSTART\n    @S['active'] = [0]\n  end\n\n  # Each Move## keeps its state info in STEP, this retrieves and increments it\n  def get_step(who, step)\n    if step\n      @STEP[who] = step\n    else\n      if !@STEP.exist?(who) || @STEP[who] == \"\"\n        @STEP[who] = 0\n      else\n        @STEP[who] += 1\n      end\n    end\n    @STEP[who]\n  end\n\n  def reset_step\n    @S['cnt'].value = 0\n    @STEP.keys.each{|k| @STEP[k] = ''}\n  end\n\n  def sine(xy0, amp, freq, opts = {})\n    x0, y0, x1, y1 = xy0\n    step = 2\n    xy = []\n    if y0 == y1  # Horizontal\n      x0.step(x1, step){|x|\n        beta = (x - x0) * 2 * Math::PI / freq\n        y = y0 + amp * Math.sin(beta)\n        xy << x << y\n      }\n    else\n      y0.step(y1, step){|y|\n        beta = (y - y0) * 2 * Math::PI / freq\n        x = x0 + amp * Math.sin(beta)\n        xy << x << y\n      }\n    end\n    TkcLine.new(@canvas, xy, opts)\n  end\n\n  def round_rect(xy, radius, opts={})\n    x0, y0, x3, y3 = xy\n    r = @canvas.winfo_pixels(radius)\n    d = 2 * r\n\n    # Make sure that the radius of the curve is less than 3/8 size of the box!\n    maxr = 0.75\n    if d > maxr * (x3 - x0)\n      d = maxr * (x3 - x0)\n    end\n    if d > maxr * (y3 - y0)\n      d = maxr * (y3 - y0)\n    end\n\n    x1 = x0 + d\n    x2 = x3 - d\n    y1 = y0 + d\n    y2 = y3 - d\n\n    xy = [x0, y0, x1, y0, x2, y0, x3, y0, x3, y1, x3, y2]\n    xy.concat([x3, y3, x2, y3, x1, y3, x0, y3, x0, y2, x0, y1])\n    return xy\n  end\n\n  def round_poly(canv, xy, radii, opts)\n    lenXY = xy.length\n    lenR = radii.length\n    if lenXY != 2*lenR\n      raise \"wrong number of vertices and radii\"\n    end\n\n    knots = []\n    x0 = xy[-2]; y0 = xy[-1]\n    x1 = xy[0];  y1 = xy[1]\n    xy << xy[0] << xy[1]\n\n    0.step(lenXY - 1, 2){|i|\n      radius = radii[i/2]\n      r = canv.winfo_pixels(radius)\n\n      x2 = xy[i+2];  y2 = xy[i+3]\n      z = _round_poly2(x0, y0, x1, y1, x2, y2, r)\n      knots.concat(z)\n\n      x0 = x1;  y0 = y1\n      x1 = x2;  y1 = y2\n    }\n    TkcPolygon.new(canv, knots, {:smooth=>true}.update(opts))\n  end\n\n  def _round_poly2(x0, y0, x1, y1, x2, y2, radius)\n    d = 2 * radius\n    maxr = 0.75\n\n    v1x = x0 - x1\n    v1y = y0 - y1\n    v2x = x2 - x1\n    v2y = y2 - y1\n\n    vlen1 = Math.sqrt(v1x*v1x + v1y*v1y)\n    vlen2 = Math.sqrt(v2x*v2x + v2y*v2y)\n\n    if d > maxr * vlen1\n      d = maxr * vlen1\n    end\n    if d > maxr * vlen2\n      d = maxr * vlen2\n    end\n\n    xy = []\n    xy << (x1 + d * v1x / vlen1) << (y1 + d * v1y / vlen1)\n    xy << x1 << y1\n    xy << (x1 + d * v2x / vlen2) << (y1 + d * v2y / vlen2)\n\n    return xy\n  end\n\n  def sparkle(oxy, tag)\n    xy = [\n      [299, 283], [298, 302], [295, 314], [271, 331], \n      [239, 310], [242, 292], [256, 274], [281, 273]\n    ]\n    xy.each{|x, y|\n      TkcLine.new(@canvas, 271, 304, x, y, \n                  :fill=>'white', :width=>3, :tag=>tag)\n    }\n    move_abs(tag, oxy)\n  end\n\n  def centroid(item)\n    anchor(item, :c)\n  end\n\n  def anchor(item, where)\n    x1, y1, x2, y2 = @canvas.bbox(item)\n    case(where)\n    when :n\n      y = y1\n    when :s\n      y = y2\n    else\n      y = (y1 + y2) / 2.0\n    end\n    case(where)\n    when :w\n      x = x1\n    when :e\n      x = x2\n    else\n      x = (x1 + x2) / 2.0\n    end\n    return [x, y]\n  end\nend\n\nTkGoldberg_Demo.new(base_frame)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/hello",
    "content": "#!/usr/bin/env ruby\n# -*- coding: euc-jp -*-\nrequire 'tk'\n\nTkButton.new(nil,\n\t'text'=>\"ˤϡ\",\n\t'command'=>proc{print \"ˤϡ\\n\"; exit}\n).pack\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/hscale.rb",
    "content": "# -*- coding: euc-jp -*-\nrequire \"tkcanvas\"\n\nif defined?($hscale_demo) && $hscale_deom\n  $hscale_demo.destroy\n  $hscale_demo = nil\nend\n\n$hscale_demo = TkToplevel.new {|w|\n  title(\"Horizontal Scale Demonstration\")\n  iconname(\"hscale\")\n}\npositionWindow($hscale_demo)\n\nbase_frame = TkFrame.new($hscale_demo).pack(:fill=>:both, :expand=>true)\n\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '3.5i'\n  justify 'left'\n  text \"ˤ1Ĥȿʿʥ뤬ɽƤޤ\\\nǥޥܥ1򥯥åޤϥɥå\\\nĹѤ뤳ȤǤޤ\"\n}\nmsg.pack('side'=>'top')\n\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc {\n      tmppath = $hscale_demo\n      $hscale_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc { showCode 'hscale' }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\ndef setWidth(w, width)\n  width = width + 21\n  x2 = width - 30\n  if x2 < 21\n    x2 = 21\n  end\n  w.coords 'poly',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15\n  w.coords 'line',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15\nend\n\nTkFrame.new(base_frame) {|frame|\n  canvas = TkCanvas.new(frame) {|c|\n    width 50\n    height 50\n    bd 0\n    highlightthickness 0\n    TkcPolygon.new(c, '0', '0', '1', '1', '2', '2') {\n      fill 'DeepSkyBlue'\n      tags 'poly'\n    }\n    TkcLine.new(c, '0', '0', '1', '1', '2', '2', '0', '0') {\n      fill 'black'\n      tags 'line'\n    }\n  }.pack('side'=>'top', 'expand'=>'yes', 'anchor'=>'s', 'fill'=>'x', 'padx'=>'15')\n  scale = TkScale.new(frame) {\n    orient 'horizontal'\n    length 284\n    from 0\n    to 250\n    command proc{|value| setWidth(canvas, value)}\n    tickinterval 50\n  }.pack('side'=>'bottom', 'expand'=>'yes', 'anchor'=>'n')\n  scale.set 75\n}.pack('side'=>'top', 'fill'=>'x')\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/icon.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# iconic button widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($icon_demo) && $icon_demo\n  $icon_demo.destroy \n  $icon_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$icon_demo = TkToplevel.new {|w|\n  title(\"Iconic Button Demonstration\")\n  iconname(\"icon\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($icon_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"Υɥˤϥ饸ܥȥåܥ˥ӥåȥޥåפɽ 3 Ĥˡ򼨤ƤޤˤΤ2ĤΥ饸ܥǡ줾줬ӥåȥޥåפ򼨤󥸥ǤǤƤޤˤΤϡѤߤɤˤäưۤʤɽåܥǤ¦ˤΤѤߤɤˤäطʿѤӥåȥޥåפɽåܥǤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $icon_demo\n      $icon_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'icon'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# image \nflagup = \\\nTkBitmapImage.new('file'=>[$demo_dir,'..',\n                           'images','flagup.xbm'].join(File::Separator),\n                  'maskfile'=>\\\n                  [$demo_dir,'..','images','flagup.xbm'].join(File::Separator))\nflagdown = \\\nTkBitmapImage.new('file'=>[$demo_dir,'..',\n                           'images','flagdown.xbm'].join(File::Separator),\n                  'maskfile'=>\\\n                  [$demo_dir,'..',\n                    'images','flagdown.xbm'].join(File::Separator))\n\n# ѿ\nletters = TkVariable.new\n\n# frame \nTkFrame.new(base_frame, 'borderwidth'=>10){|w|\n  TkFrame.new(w) {|f|\n    # TkRadioButton.new(f){\n    Tk::RadioButton.new(f){\n      bitmap '@' + [$demo_dir,'..',\n                     'images','letters.xbm'].join(File::Separator)\n      variable letters\n      value 'full'\n    }.pack('side'=>'top', 'expand'=>'yes')\n\n    # TkRadioButton.new(f){\n    Tk::RadioButton.new(f){\n      bitmap '@' + [$demo_dir,'..',\n                     'images','noletter.xbm'].join(File::Separator)\n      variable letters\n      value 'empty'\n    }.pack('side'=>'top', 'expand'=>'yes')\n\n  }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m')\n\n  # TkCheckButton.new(w) {\n  Tk::CheckButton.new(w) {\n    image flagdown\n    selectimage flagup\n    indicatoron 0\n    selectcolor self['background']\n  }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m')\n\n  # TkCheckButton.new(w) {\n  Tk::CheckButton.new(w) {\n    bitmap '@' + [$demo_dir,'..',\n                   'images','letters.xbm'].join(File::Separator)\n    indicatoron 0\n    selectcolor 'SeaGreen1'\n  }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m')\n\n}.pack('side'=>'top')\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/image1.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# two image widgets demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($image1_demo) && $image1_demo\n  $image1_demo.destroy \n  $image1_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$image1_demo = TkToplevel.new {|w|\n  title('Image Demonstration #1')\n  iconname(\"Image1\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($image1_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ΥǥǤ2ĤΥ٥˲򤽤줾ɽƤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $image1_demo\n      $image1_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'image1'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# image \nimage1a = \\\nTkPhotoImage.new('file'=>[$demo_dir,'..',\n                          'images','earth.gif'].join(File::Separator))\nimage1b = \\\nTkPhotoImage.new('file'=>[$demo_dir,'..',\n                          'images','earthris.gif'].join(File::Separator))\n\n# label \n#[ TkLabel.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'),\n#  TkLabel.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken')\n#].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')}\n[ Tk::Label.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'),\n  Tk::Label.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken')\n].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/image2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# widget demo 'load image' (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($image2_demo) && $image2_demo\n  $image2_demo.destroy \n  $image2_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$image2_demo = TkToplevel.new {|w|\n  title('Image Demonstration #2')\n  iconname(\"Image2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($image2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ΥǥǤTk photo image ѤƲ򸫤뤳ȤǤޤǽ˥ȥˤ˥ǥ쥯ȥ̾Ʋ˲ΥꥹȥܥåˤΥǥ쥯ȥɤ뤿ᡢ꥿򲡤Ƥθ塢򤹤뤿˥ꥹȥܥåΥե֥̾륯åƲ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $image2_demo\n      $image2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'image2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# ѿ\n$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator))\n\n# image \n$image2a = TkPhotoImage.new\n\n# ե̾\nTkLabel.new(base_frame, 'text'=>'ǥ쥯ȥ:')\\\n.pack('side'=>'top', 'anchor'=>'w')\n\nimage2_e = TkEntry.new(base_frame) {\n  width 30\n  textvariable $dirName\n}.pack('side'=>'top', 'anchor'=>'w')\n\nTkFrame.new(base_frame, 'height'=>'3m', 'width'=>20)\\\n.pack('side'=>'top', 'anchor'=>'w')\n\nTkLabel.new(base_frame, 'text'=>'ե:')\\\n.pack('side'=>'top', 'anchor'=>'w')\n\nTkFrame.new(base_frame){|w|\n  s = TkScrollbar.new(w)\n  l = TkListbox.new(w) {\n    width 20\n    height 10\n    yscrollcommand proc{|first,last| s.set first,last}\n  }\n  s.command(proc{|*args| l.yview(*args)})\n  l.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y')\n  s.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y')\n  #l.insert(0,'earth.gif', 'earthris.gif', 'mickey.gif', 'teapot.ppm')\n  l.insert(0,'earth.gif', 'earthris.gif', 'teapot.ppm')\n  l.bind('Double-1', proc{|x,y| loadImage $image2a,l,x,y}, '%x %y')\n\n  image2_e.bind 'Return', proc{loadDir l}\n\n}.pack('side'=>'top', 'anchor'=>'w')\n\n# image \n[ TkFrame.new(base_frame, 'height'=>'3m', 'width'=>20),\n  TkLabel.new(base_frame, 'text'=>':'),\n  # TkLabel.new(base_frame, 'image'=>$image2a)\n  Tk::Label.new(base_frame, 'image'=>$image2a)\n].each{|w| w.pack('side'=>'top', 'anchor'=>'w')}\n\n# ᥽å\ndef loadDir(w)\n  w.delete(0,'end')\n  Dir.glob([$dirName,'*'].join(File::Separator)).sort.each{|f|\n    w.insert('end',File.basename(f))\n  }\nend\n\ndef loadImage(img,w,x,y)\n  img.file([$dirName, w.get(\"@#{x},#{y}\")].join(File::Separator))\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/image3.rb",
    "content": "# -*- coding: euc-jp -*-\n# image3.rb\n#\n# This demonstration script creates a simple collection of widgets\n# that allow you to select and view images in a Tk label.\n#\n# widget demo 'load image' (called by 'widget')\n#\n\n# toplevel widget\nif defined?($image3_demo) && $image3_demo\n  $image3_demo.destroy \n  $image3_demo = nil\nend\n\n# demo toplevel widget\n$image3_demo = TkToplevel.new {|w|\n  title('Image Demonstration #3')\n  iconname(\"Image3\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true)\n\n# \ndef loadDir3(w)\n  w.delete(0,'end')\n  Dir.glob([$dirName,'*'].join(File::Separator)).sort.each{|f|\n    w.insert('end',File.basename(f))\n  }\nend\n\n# selectAndLoadDir3 --\n# This procedure pops up a dialog to ask for a directory to load into\n# the listobx and (if the user presses OK) reloads the directory\n# listbox from the directory named in the demo's entry.\n#\n# Arguments:\n# w -                   Name of the toplevel window of the demo.\ndef selectAndLoadDir3(w, lbox)\n  dir = Tk.chooseDirectory(:initialdir=>$dirName.value, \n                           :parent=>w, :mustexist=>true)\n  if dir.length > 0\n    $dirName.value = dir \n    loadDir3(lbox)\n  end\nend\n\ndef loadImage3(w,x,y)\n  $image3a.file([$dirName, w.get(\"@#{x},#{y}\")].join(File::Separator))\nend\n\n\n# label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ΥǥǤTk photo image ѤƲ 뤳ȤǤޤǽ˥ȥˤ˥ǥ쥯ȥ̾Ʋ˲ΥꥹȥܥåˤΥǥ쥯ȥɤ뤿ᡢ꥿򲡤Ƥθ塢򤹤뤿˥ꥹȥܥåΥե֥̾륯åƲ\"\n}\nmsg.pack('side'=>'top')\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $image3_demo\n      $image3_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'image3'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# variable\n$dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator))\n\n# image\nbegin\n  $image3a.delete\nrescue\nend\n$image3a = TkPhotoImage.new\n\n#\nimage3_f = TkFrame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\nimage3_df = TkLabelFrame.new(base_frame, :text=>'ǥ쥯ȥ:')\n\nimage3_ff = TkLabelFrame.new(base_frame, :text=>'ե:', \n                             :padx=>'2m', :pady=>'2m')\nimage3_lbx = TkListbox.new(image3_ff, :width=>20, :height=>10) {\n  pack(:side=>:left, :fill=>:y, :expand=>true)\n  yscrollbar(TkScrollbar.new(image3_ff).pack(:side=>:left, :fill=>:y, \n                                             :expand=>true))\n  insert(0, *(%w(earth.gif earthris.gif teapot.ppm)))\n  bind('Double-1', proc{|x,y| loadImage3(self, x, y)}, '%x %y')\n}\n\nimage3_ent = TkEntry.new(image3_df, :width=>30, :textvariable=>$dirName){\n  pack(:side=>:left, :fill=>:both, :padx=>'2m', :pady=>'2m', :expand=>true)\n  bind('Return', proc{loadDir3(image3_lbx)})\n}\n\nTkButton.new(image3_df, :pady=>0, :padx=>'2m', :text=>\"ǥ쥯ȥ\", \n             :command=>proc{selectAndLoadDir3(image3_ent, image3_lbx)}) {\n  pack(:side=>:left, :fill=>:y, :padx=>[0, '2m'], :pady=>'2m')\n}\n\nimage3_if = TkLabelFrame.new(base_frame, :text=>'᡼:') {|f|\n  # TkLabel.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m')\n  Tk::Label.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m')\n}\n\nTk.grid(image3_df,  '-',\n        :sticky=>:ew, :padx=>'1m', :pady=>'1m', :in=>image3_f)\nTk.grid(image3_ff, image3_if, \n        :sticky=>:nw, :padx=>'1m', :pady=>'1m', :in=>image3_f)\nTkGrid.columnconfigure(image3_f, 1, :weight=>1)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/items.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# canvas item types widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($items_demo) && $items_demo\n  $items_demo.destroy \n  $items_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$items_demo = TkToplevel.new {|w|\n  title(\"Canvas Item Demonstration\")\n  iconname(\"Items\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($items_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"ΥɥˤϥХ widget äƤꡢˤϥХ widget ݡȤ͡ʥפΥƥ㤬äƤޤΤ褦Ǥޤ\\n  ܥ-1 ɥå:\\tƥư\\n  ܥ-2 ɥå:\\tƤʬ򤺤餹\\n  ܥ-3 ɥå:\\tΰϤ\\n  ȥ-F:\\tΰβΥƥɽ롣\"\n}.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $items_demo\n      $items_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'items'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \ncvs = nil\nTkFrame.new(base_frame) {|cf|\n  # canvas \n  cvs = TkCanvas.new(cf) {|c|\n    focus\n    scrollregion '0c 0c 30c 24c'\n    width  '15c'\n    height '10c'\n    relief 'sunken'\n    borderwidth 2\n\n    hs = TkScrollbar.new(cf) {|s|\n      orient 'horizontal'\n      command proc{|*args| c.xview(*args)}\n      c.xscrollcommand proc{|first,last| s.set first,last}\n    }\n\n    vs = TkScrollbar.new(cf) {|s|\n      command proc{|*args| c.yview(*args)}\n      c.yscrollcommand proc{|first,last| s.set first,last}\n    }\n\n    if $tk_version =~ /^4\\.[01]/\n      hs.pack('side'=>'bottom', 'fill'=>'x')\n      vs.pack('side'=>'right', 'fill'=>'y')\n      c.pack('in'=>cf, 'expand'=>'yes', 'fill'=>'both')\n\n    else\n      c.grid('in'=>cf, 'row'=>0, 'column'=>0, \n             'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n      vs.grid('row'=>0, 'column'=>1, \n              'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n      hs.grid('row'=>1, 'column'=>0, \n              'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n      TkGrid.rowconfigure(cf, 0, 'weight'=>1, 'minsize'=>0)\n      TkGrid.columnconfigure(cf, 0, 'weight'=>1, 'minsize'=>0)\n\n    end\n\n  }\n}.pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\n# Display a 3x3 rectangular grid\nTkcRectangle.new(cvs, '0c', '0c', '30c', '24c', 'width'=>2)\nTkcLine.new(cvs, '0c', '8c', '30c', '8c', 'width'=>2)\nTkcLine.new(cvs, '0c', '16c', '30c', '16c', 'width'=>2)\nTkcLine.new(cvs, '10c', '0c', '10c', '24c', 'width'=>2)\nTkcLine.new(cvs, '20c', '0c', '20c', '24c', 'width'=>2)\n\nif $tk_version =~ /^4.*/\n  font1 = '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*'\n  font2 = '-Adobe-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*'\nelse\n  font1 = 'Helvetica 12'\n  font2 = 'Helvetica 24 bold'\nend\nif TkWinfo.depth($root).to_i > 1\n  blue   = 'DeepSkyBlue3'\n  red    = 'red'\n  bisque = 'bisque3'\n  green  = 'SeaGreen3'\nelse\n  blue   = 'black'\n  red    = 'black'\n  bisque = 'black'\n  green  = 'black'\nend\n\n# tag ֥Ȥ\n$tag_item = TkcGroup.new(cvs)\n\n# Set up demos within each of the areas of the grid.\nTkcText.new(cvs, '5c', '.2c', 'text'=>'饤', 'anchor'=>'n')\nTkcLine.new(cvs, '1c', '1c', '3c', '1c', '1c', '4c', '3c', '4c', \n            'width'=>2, 'fill'=>blue, 'capstyle'=>'butt', \n            'join'=>'miter', 'tags'=>$tag_item )\nTkcLine.new(cvs, '4.67c','1c','4.67c','4c', 'arrow'=>'last', 'tags'=>$tag_item)\nTkcLine.new(cvs, '6.33c','1c','6.33c','4c', 'arrow'=>'both', 'tags'=>$tag_item)\nTkcLine.new(cvs, '5c','6c','9c','6c','9c','1c','8c','1c','8c','4.8c','8.8c',\n            '4.8c','8.8c','1.2c','8.2c','1.2c','8.2c','4.6c','8.6c','4.6c',\n            '8.6c','1.4c','8.4c','1.4c','8.4c','4.4c',\n            'width'=>3, 'fill'=>red, 'tags'=>$tag_item )\nTkcLine.new(cvs, '1c','5c','7c','5c','7c','7c','9c','7c', 'width'=>'.5c', \n            'stipple'=>'@'+[$demo_dir,'..',\n                            'images','gray25.xbm'].join(File::Separator), \n            'arrow'=>'both', 'arrowshape'=>'15 15 7', 'tags'=>$tag_item )\nTkcLine.new(cvs, '1c','7c','1.75c','5.8c','2.5c','7c','3.25c','5.8c','4c','7c',\n            'width'=>'.5c', 'capstyle'=>'round', 'join'=>'round', \n            'tags'=>$tag_item )\n\nTkcText.new(cvs, '15c', '.2c', \n            'text'=>' (餫ˤĤʤľ)', 'anchor'=>'n')\nTkcLine.new(cvs, '11c','4c','11.5c','1c','13.5c','1c','14c','4c', \n            'smooth'=>'on', 'fill'=>blue, 'tags'=>$tag_item )\nTkcLine.new(cvs, '15.5c','1c','19.5c','1.5c','15.5c','4.5c','19.5c','4c', \n            'smooth'=>'on', 'arrow'=>'both', 'width'=>3, 'tags'=>$tag_item )\nTkcLine.new(cvs, '12c','6c','13.5c','4.5c','16.5c','7.5c','18c','6c', \n            '16.5c','4.5c','13.5c','7.5c','12c','6c',\n            'smooth'=>'on', 'width'=>'3m', 'capstyle'=>'round', \n            'stipple'=>'@'+[$demo_dir, '..',\n                            'images', 'gray25.xbm'].join(File::Separator), \n            'fill'=>red, 'tags'=>$tag_item )\n\nTkcText.new(cvs, '25c', '.2c', 'text'=>'¿ѷ', 'anchor'=>'n')\nTkcPolygon.new(cvs, '21c','1.0c','22.5c','1.75c','24c','1.0c','23.25c','2.5c',\n               '24c','4.0c','22.5c','3.25c','21c','4.0c','21.75c','2.5c',\n               'fill'=>'green', 'outline'=>'black', 'width'=>4, \n               'tags'=>$tag_item )\nTkcPolygon.new(cvs, '25c','4c','25c','4c','25c','1c','26c','1c','27c','4c',\n               '28c','1c','29c','1c','29c','4c','29c','4c',\n               'fill'=>red, 'smooth'=>'on', 'tags'=> $tag_item)\nTkcPolygon.new(cvs, '22c','4.5c','25c','4.5c','25c','6.75c','28c','6.75c',\n               '28c','5.25c','24c','5.25c','24c','6.0c','26c','6c','26c',\n               '7.5c','22c','7.5c', \n               'stipple'=>'@' + [$demo_dir, '..',\n                                 'images', 'gray25.xbm'].join(File::Separator),\n               'outline'=>'black', 'tags'=>$tag_item )\n\nTkcText.new(cvs, '5c', '8.2c', 'text'=>'', 'anchor'=>'n')\nTkcRectangle.new(cvs, '1c','9.5c','4c','12.5c',\n                 'outline'=>red, 'width'=>'3m', 'tags'=>$tag_item)\nTkcRectangle.new(cvs, '0.5c','13.5c','4.5c','15.5c', \n                 'fill'=>green, 'tags'=>$tag_item )\nTkcRectangle.new(cvs, '6c','10c','9c','15c', 'outline'=>'',\n                 'stipple'=>'@'+[$demo_dir,'..',\n                                 'images','gray25.xbm'].join(File::Separator),\n                 'fill'=>blue, 'tags'=>$tag_item )\n\nTkcText.new(cvs, '15c', '8.2c', 'text'=>'ʱ', 'anchor'=>'n')\nTkcOval.new(cvs, '11c','9.5c','14c','12.5c',\n                 'outline'=>red, 'width'=>'3m', 'tags'=>$tag_item)\nTkcOval.new(cvs, '10.5c','13.5c','14.5c','15.5c', \n                 'fill'=>green, 'tags'=>$tag_item )\nTkcOval.new(cvs, '16c','10c','19c','15c', 'outline'=>'',\n                 'stipple'=>'@'+[$demo_dir,'..',\n                                 'images','gray25.xbm'].join(File::Separator),\n                 'fill'=>blue, 'tags'=>$tag_item )\n\nTkcText.new(cvs, '25c', '8.2c', 'text'=>'ƥ', 'anchor'=>'n')\nTkcRectangle.new(cvs, '22.4c','8.9c','22.6c','9.1c')\nTkcText.new(cvs, '22.5c', '9c', 'anchor'=>'n', 'font'=>font1, 'width'=>'4c', \n            'text'=>'ûƥȡɥåס·󥫡()ϳƥƥȤΥ󥫡ݥȤ򼨤', 'tags'=>$tag_item )\nTkcRectangle.new(cvs, '25.4c','10.9c','25.6c','11.1c')\nTkcText.new(cvs, '25.5c', '11c', 'anchor'=>'w', 'font'=>font1, 'fill'=>blue, \n            'text'=>\"Ĥιԡ\\n줾Ω\\n·\\nƺü󥫡Ƥ롣\", 'justify'=>'center', 'tags'=>$tag_item )\nTkcRectangle.new(cvs, '24.9c','13.9c','25.1c','14.1c')\nif $tk_version =~ /^4\\.[01]/\n  TkcText.new(cvs, '25c', '14c', 'anchor'=>'c', 'font'=>font2, 'fill'=>red, \n              'stipple'=>'@' + [$demo_dir, '..',\n                                'images', 'grey.5'].join(File::Separator),\n              'text'=>'Stippled characters', 'tags'=>$tag_item )\nelse\n  TkcText.new(cvs, '25c', '14c', 'anchor'=>'c', 'font'=>font2, 'fill'=>red, \n              'stipple'=>'gray50', 'text'=>'Stippled characters', \n              'tags'=>$tag_item )\nend\n\nTkcText.new(cvs, '5c', '16.2c', 'text'=>'', 'anchor'=>'n')\nTkcArc.new(cvs, '0.5c','17c','7c','20c', 'fill'=>green, 'outline'=>'black', \n           'start'=>45, 'extent'=>270, 'style'=>'pieslice', 'tags'=>$tag_item)\n#TkcArc.new(cvs, '6.5c','17c','9.5c','20c', 'width'=>'4m', 'style'=>'arc', \n#          'outline'=>blue, 'start'=>135, 'extent'=>270, \n#          'outlinestipple'=>'@' + ['images', 'grey.25'].join(File::Separator),\n#          'tags'=>$tag_item)\nTkcArc.new(cvs, '6.5c','17c','9.5c','20c', 'width'=>'4m', 'style'=>'arc', \n           'outline'=>blue, 'start'=>135, 'extent'=>270, \n           'outlinestipple'=>'@'+[$demo_dir, '..',\n                                  'images','gray25.xbm'].join(File::Separator),\n           'tags'=>$tag_item)\nTkcArc.new(cvs, '0.5c','20c','9.5c','24c', 'width'=>'4m', 'style'=>'pieslice', \n           'fill'=>'', 'outline'=>red, 'start'=>225, 'extent'=>90, \n           'tags'=>$tag_item)\nTkcArc.new(cvs, '5.5c','20.5c','9.5c','23.5c', 'width'=>'4m', 'style'=>'chord',\n           'fill'=>blue, 'outline'=>'', 'start'=>45, 'extent'=>270, \n           'tags'=>$tag_item)\n\nTkcText.new(cvs, '15c', '16.2c', 'text'=>'ӥåȥޥå', 'anchor'=>'n')\n#TkcBitmap.new(cvs, '13c','20c',\n#             'bitmap'=>'@' + ['images', 'face'].join(File::Separator),\n#             'tags'=>$tag_item)\nTkcBitmap.new(cvs, '13c','20c',\n              'bitmap'=>'@' + [$demo_dir, '..',\n                               'images', 'face.xbm'].join(File::Separator),\n              'tags'=>$tag_item)\n#TkcBitmap.new(cvs, '17c','18.5c',\n#             'bitmap'=>'@' + ['images', 'noletters'].join(File::Separator),\n#             'tags'=>$tag_item)\nTkcBitmap.new(cvs, '17c','18.5c',\n              'bitmap'=>'@' + [$demo_dir, '..',\n                               'images', 'noletter.xbm'].join(File::Separator),\n              'tags'=>$tag_item)\n#TkcBitmap.new(cvs, '17c','21.5c',\n#             'bitmap'=>'@' + ['images', 'letters'].join(File::Separator),\n#             'tags'=>$tag_item)\n# ηǤǽ\nTkcBitmap.new(cvs, '17c','21.5c') {\n  bitmap '@' + [$demo_dir, '..', 'images', 'letters.xbm'].join(File::Separator)\n  tags $tag_item\n}\n#TkcBitmap.new(cvs, '17c','21.5c') {\n#  bitmap '@' + ['images', 'letters'].join(File::Separator)\n#  tags $tag_item\n#}\n\nTkcText.new(cvs, '25c', '16.2c', 'text'=>'ɥ', 'anchor'=>'n')\nTkButton.new(cvs) {|b|\n  text 'Ƥ'\n  command proc{butPress cvs, red}\n  TkcWindow.new(cvs, '21c','18c', \n                'window'=>b, 'anchor'=>'nw', 'tags'=>$tag_item)\n}\nTkEntry.new(cvs, 'width'=>20, 'relief'=>'sunken') {|e|\n  insert 'end', 'ԽƤ'\n  TkcWindow.new(cvs, '21c','21c', \n                'window'=>e, 'anchor'=>'nw', 'tags'=>$tag_item)\n}\nTkScale.new(cvs, 'from'=>0, 'to'=>100, 'length'=>'6c', 'sliderlength'=>'.4c', \n            'width'=>'.5c', 'tickinterval'=>0 ) {|scl|\n  TkcWindow.new(cvs, '28.5c','17.5c', \n                'window'=>scl, 'anchor'=>'n', 'tags'=>$tag_item)\n}\nTkcText.new(cvs, '21c', '17.9c', 'text'=>'ܥ:', 'anchor'=>'sw')\nTkcText.new(cvs, '21c', '20.9c', 'text'=>'ȥ:', 'anchor'=>'sw')\nTkcText.new(cvs, '28.5c', '17.4c', 'text'=>':', 'anchor'=>'s')\n\n# Set up event bindings for canvas:\ncvs.itembind($tag_item, 'Any-Enter', proc{itemEnter cvs})\ncvs.itembind($tag_item, 'Any-Leave', proc{itemLeave cvs})\ncvs.bind('2', proc{|x,y| cvs.scan_mark x,y}, '%x %y')\ncvs.bind('B2-Motion', proc{|x,y| cvs.scan_dragto x,y}, '%x %y')\ncvs.bind('3', proc{|x,y| itemMark cvs,x,y}, '%x %y')\ncvs.bind('B3-Motion', proc{|x,y| itemStroke cvs,x,y}, '%x %y')\ncvs.bind('Control-f', proc{itemsUnderArea cvs})\ncvs.bind('1', proc{|x,y| itemStartDrag cvs,x,y}, '%x %y')\ncvs.bind('B1-Motion', proc{|x,y| itemDrag cvs,x,y}, '%x %y')\n# Utility methods for highlighting the item under the pointer\n\n$restoreCmd = nil\ndef itemEnter (c)\n  if TkWinfo.depth(c).to_i == 1\n    $restoreCmd = nil\n    return\n  end\n  type = c.itemtype('current')\n  if type == TkcWindow\n    $restoreCmd = nil\n    return\n  end\n  if type == TkcBitmap\n    bg = (c.itemconfiginfo('current', 'background'))[4]\n    $restoreCmd = proc{c.itemconfigure 'current', 'background', bg}\n    c.itemconfigure 'current', 'background', 'SteelBlue2'\n    return\n  end\n  fill = (c.itemconfiginfo('current', 'fill'))[4]\n  if (type == TkcRectangle || type == TkcOval || type == TkcArc) && fill == []\n    outline = (c.itemconfiginfo('current', 'outline'))[4]\n    $restoreCmd = proc{c.itemconfigure 'current', 'outline', outline}\n    c.itemconfigure 'current', 'outline', 'SteelBlue2'\n  else\n    $restoreCmd = proc{c.itemconfigure 'current', 'fill', fill}\n    c.itemconfigure 'current', 'fill', 'SteelBlue2'\n  end\nend\n\ndef itemLeave(c)\n  $restoreCmd.call if $restoreCmd\nend\n\n# Utility methods for stroking out a rectangle and printing what's \n# underneath the rectangle's area.\n\ndef itemMark(c,x,y)\n  $areaX1 = c.canvasx(x)\n  $areaY1 = c.canvasy(y)\n  c.delete 'area'\nend\n\ndef itemStroke(c,x,y)\n  x = c.canvasx(x)\n  y = c.canvasy(y)\n  if $areaX1 != x && $areaY1 != y\n    c.delete 'area'\n    c.addtag_withtag 'area', TkcRectangle.new(c, $areaX1, $areaY1, x, y, \n                                              '-outline', 'black')\n    $areaX2 = x\n    $areaY2 = y\n  end\nend\n\ndef itemsUnderArea(c)\n  area = c.find_withtag('area')\n  items = []\n  c.find_enclosed($areaX1,$areaY1,$areaX2,$areaY2).each{|i|\n    items.push(i) if i.gettags.include?($tag_item)\n  }\n  print \"Items enclosed by area: #{items.inspect}\\n\"; STDOUT.flush\n  items.clear\n  c.find_overlapping($areaX1,$areaY1,$areaX2,$areaY2).each{|i|\n    items.push(i) if i.gettags.include?($tag_item)\n  }\n  print \"Items overlapping area: #{items.inspect}\\n\"; STDOUT.flush\nend\n\n$areaX1 = 0\n$areaY1 = 0\n$areaX2 = 0\n$areaY2 = 0\n\n# Utility methods to support dragging of items.\n\ndef itemStartDrag(c,x,y)\n  $lastX = c.canvasx(x)\n  $lastY = c.canvasy(y)\nend\n\ndef itemDrag(c,x,y)\n  x = c.canvasx(x)\n  y = c.canvasy(y)\n  c.move('current', x - $lastX, y - $lastY)\n  $lastX = x\n  $lastY = y\nend\n\n# Method that's invoked when the button embedded in the canvas \n# is invoked.\n\ndef butPress(w,color)\n  i = TkcText.new(w, '25c', '18.1c', \n                  'text'=>'Ƥ!!', 'fill'=>color, 'anchor'=>'n')\n  Tk.after(500, proc{w.delete i})\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ixset",
    "content": "#!/usr/bin/env ruby\n\n# ixset --\n# A nice interface to \"xset\" to change X server settings\n#\n\nrequire 'tk'\n\nclass Xsettings\n  #\n  # Button actions\n  #\n  def quit\n    @root.destroy\n  end\n\n  def ok\n    writesettings\n    quit\n  end\n\n  def cancel\n    readsettings\n    dispsettings\n  end\n\n  # apply is just \"writesettings\"\n\n\n  #\n  # Read current settings\n  #\n  def readsettings\n    xfd = open(\"|xset q\", 'r')\n    xfd.readlines.each{|line|\n      fields = line.chomp.strip.split(/\\s+/)\n      case fields[0]\n      when \"auto\"\n\tif fields[1] == 'repeat:'\n\t  @kbdrep = fields[2]\n\t  @w_kbdrep.set(@kbdrep)\n\t  @kbdcli = fields[6]\n\tend\n\n      when \"bell\"\n\t@bellvol = fields[2]\n\t@bellpit = fields[5]\n\t@belldur = fields[8]\n\n      when \"acceleration:\"\n\t@mouseacc = fields[1]\n\t@mousethr = fields[3]\n\n      when \"prefer\"\n\tif fields[2] == 'yes'\n\t  @screenbla = 'blank'\n\telse\n\t  @screenbla = 'noblank'\n\tend\n\t@w_screenbla.set(@screenbla)\n\n      when \"timeout:\"\n\t@screentim = fields[1]\n\t@screencyc = fields[3]\n\n      end\n    }\n\n    xfd.close\n  end\n\n  #\n  # Write settings into the X server\n  #\n  def writesettings\n    @bellvol = @w_bellvol.get\n    @bellpit = @w_bellpit.get\n    @belldur = @w_belldur.get\n\n    @kbdrep = @w_kbdrep.get\n    if @kbdrep == 'on'\n      @kbdcli = @w_kbdcli.get\n    else\n      @kbdcli = 'off'\n    end\n\n    @mouseacc = @w_mouseacc.get\n    @mousethr = @w_mousethr.get\n\n    @screentim = @w_screentim.get\n    @screencyc = @w_screencyc.get\n    @screenbla = @w_screenbla.get\n\n    system(\"xset \\\n            b #{@bellvol} #{@bellpit} #{@belldur} \\\n            c #{@kbdcli} \\\n            r #{@kbdrep} \\\n            m #{@mouseacc} #{@mousethr} \\\n            s #{@screentim} #{@screencyc} \\\n            s #{@screenbla}\")\n  end\n\n  #\n  # Sends all settings to the window\n  #\n  def dispsettings\n    @w_bellvol.set(@bellvol)\n    @w_bellpit.set(@bellpit)\n    @w_belldur.set(@belldur)\n\n    @w_kbdonoff.set(@w_kbdrep.get)\n    @w_kbdcli.set(@kbdcli)\n\n    @w_mouseacc.set(@mouseacc)\n    @w_mousethr.set(@mousethr)\n\n    @w_screenblank.set(@w_screenbla.get)\n    @w_screenpat.set(@w_screenbla.get)\n\n    @w_screentim.set(@screentim)\n    @w_screencyc.set(@screencyc)\n  end\n\n  #\n  # Create all windows, and pack them\n  #\n  class LabelEntry\n    def initialize(parent, text, length)\n      @frame = TkFrame.new(parent)\n      TkLabel.new(@frame, 'text'=>text).pack('side'=>'left','expand'=>'y')\n      @entry = TkEntry.new(@frame, 'width'=>length, 'relief'=>'sunken') {\n\tpack('side'=>'left','expand'=>'y')\n      }\n    end\n    def pack(keys)\n      @frame.pack(keys)\n    end\n    def get\n      @entry.value\n    end\n    def set(value)\n      @entry.delete(0,'end')\n      @entry.insert(0, value)\n    end\n  end\n\n  def createwindows\n    win = self\n\n    #\n    # Buttons\n    #\n    buttons = TkFrame.new(@root) {|f|\n      [ TkButton.new(f, 'command'=>proc{win.ok}, 'text'=>'Ok'),\n\tTkButton.new(f, 'command'=>proc{win.writesettings}, 'text'=>'Apply'),\n\tTkButton.new(f, 'command'=>proc{win.cancel}, 'text'=>'Cancel'),\n\tTkButton.new(f, 'command'=>proc{win.quit}, 'text'=>'Quit') ].each{|b|\n\tb.pack('side'=>'left', 'expand'=>'yes', 'pady'=>5)\n      }\n    }\n\n    #\n    # Bell settings\n    #\n    bell = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(bell, 'text'=>'Bell Settings')\n    @w_bellvol = TkScale.new(bell, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t     'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t     'label'=>\"Volume (%)\") \n\n    f = TkFrame.new(bell)\n    @w_bellpit = LabelEntry.new(f, \"Pitch (Hz)\", 6)\n    @w_bellpit.pack('side'=>'left', 'padx'=>5)\n    @w_belldur = LabelEntry.new(f, \"Duration (ms)\", 6)\n    @w_belldur.pack('side'=>'right', 'padx'=>5)\n\n    l.pack('side'=>'top', 'expand'=>'yes')\n    @w_bellvol.pack('side'=>'top', 'expand'=>'yes')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Keyboard settings\n    # \n    kbdonoff = nil\n    kbdcli = nil\n    kbd = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(kbd, 'text'=>'Keyboard Repeat Settings')\n    f = TkFrame.new(kbd)\n    @w_kbdonoff = TkCheckButton.new(f, 'text'=>'On', 'relief'=>'flat', \n\t\t\t\t    'onvalue'=>'on', 'offvalue'=>'off',\n\t\t\t\t    'variable'=>@w_kbdrep ) {\n      def self.set(value)\n\tif value == 'on'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n      pack('side'=>'left', 'expand'=>'yes', 'fill'=>'both')\n    }\n    @w_kbdcli = TkScale.new(f, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t 'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t 'label'=>'Click Volume (%)')\n    @w_kbdcli.pack('side'=>'left', 'expand'=>'yes')\n    l.pack('side'=>'top', 'expand'=>'yes')\n    f.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'fill'=>'x')\n\n    #\n    # Mouse settings\n    #\n    mouse = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(mouse, 'text'=>'Mouse Settings')\n    f = TkFrame.new(mouse)\n    @w_mouseacc = LabelEntry.new(f, 'Acceleration', 3)\n    @w_mouseacc.pack('side'=>'left')\n    @w_mousethr = LabelEntry.new(f, 'Threshold (pixels)', 3)\n    @w_mousethr.pack('side'=>'right')\n    l.pack('side'=>'top')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Screen Saver settings\n    #\n    screen = TkFrame.new(@root, 'relief'=>'raised', 'borderwidth'=>2)\n    l = TkLabel.new(screen, 'text'=>'Screen-saver Settings')\n    f = TkFrame.new(screen)\n    ff1 = TkFrame.new(f)\n    [ @w_screenblank = TkRadioButton.new(ff1, 'text'=>'Blank', \n\t\t\t\t\t 'relief'=>'flat', \n\t\t\t\t\t 'variable'=>@w_screenbla, \n\t\t\t\t\t 'value'=>'blank') {\n\tdef self.set(value)\n\t  if value == 'blank'\n\t    self.select\n\t  else\n\t    self.deselect\n\t  end\n\tend\n      }, \n      @w_screenpat = TkRadioButton.new(ff1, 'text'=>'Pattern', \n\t\t\t\t       'relief'=>'flat', \n\t\t\t\t       'variable'=>@w_screenbla, \n\t\t\t\t       'value'=>'noblank') {\n\tdef self.set(value)\n\t  if value != 'blank'\n\t    self.select\n\t  else\n\t    self.deselect\n\t  end\n\tend\n      }\n    ].each {|w| w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w') }\n\n    ff2 = TkFrame.new(f)\n    [ @w_screentim = LabelEntry.new(ff2, 'Timeout (s)', 5), \n      @w_screencyc = LabelEntry.new(ff2, 'Cycle (s)', 5) ].each{|w|\n      w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'e')\n    }\n\n    ff1.pack('side'=>'left')\n    ff2.pack('side'=>'left')\n\n    l.pack('side'=>'top')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Main window\n    #\n    buttons.pack('side'=>'top', 'fill'=>'both')\n    bell.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n    kbd.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n    mouse.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n    screen.pack('side'=>'top', 'fill'=>'both', 'ipady'=>5, 'expand'=>'yes')\n\n    #\n    # Let the user resize our window\n    #\n    @root.minsize(10,10)\n  end\n\n  def initialize\n    @root = TkRoot.new\n\n    @kbdrep = 'on'\n    @w_kbdrep = TkVariable.new(@kbdrep)\n    def @w_kbdrep.get\n      self.value\n    end\n    def @w_kbdrep.set(val)\n      self.value=val\n    end\n\n    @kbdcli = 0\n\n    @bellvol = 100\n    @bellpit = 440\n    @belldur = 100\n\n    @mouseacc = \"3/1\"\n    @mousethr = 4\n\n    @screenbla = \"blank\"\n    @w_screenbla = TkVariable.new(@screenbla)\n    def @w_screenbla.get\n      self.value\n    end\n    def @w_screenbla.set(val)\n      self.value=val\n    end\n\n    @screentim = 600\n    @screencyc = 600\n\n    #\n    # Listen what \"xset\" tells us...\n    #\n    readsettings\n\n    #\n    # Create all windows\n    #\n    createwindows\n\n    #\n    # Write xset parameters\n    #\n    dispsettings\n  end\nend\n\nXsettings.new\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ixset2",
    "content": "#!/usr/bin/env ruby\n# -*- coding: euc-jp -*-\n#\n# ixset --\n# A nice interface to \"xset\" to change X server settings\n#\n\nrequire 'tk'\n\nclass Xsettings\n  #\n  # Button actions\n  #\n  def quit\n    @root.destroy\n  end\n\n  def ok\n    writesettings\n    quit\n  end\n\n  def cancel\n    readsettings\n    dispsettings\n    @btn_APPLY.state(:disabled)\n    @btn_CANCEL.state(:disabled)\n  end\n\n  # apply is just \"writesettings\"\n  def apply\n    writesettings\n    @btn_APPLY.state(:disabled)\n    @btn_CANCEL.state(:disabled)\n  end\n\n  #\n  # Read current settings\n  #\n  def readsettings\n    xfd = open(\"|xset q\", 'r')\n    xfd.readlines.each{|line|\n      fields = line.chomp.strip.split(/\\s+/)\n      case fields[0]\n      when \"auto\"\n\tif fields[1] == 'repeat:'\n\t  @kbdrep = fields[2]\n\t  @w_kbdrep.set(@kbdrep)\n\t  @kbdcli = fields[6]\n\tend\n\n      when \"bell\"\n\t@bellvol = fields[2]\n\t@bellpit = fields[5]\n\t@belldur = fields[8]\n\n      when \"acceleration:\"\n\t@mouseacc = fields[1]\n\t@mousethr = fields[3]\n\n      when \"prefer\"\n\tif fields[2] == 'yes'\n\t  @screenbla = 'blank'\n\telse\n\t  @screenbla = 'noblank'\n\tend\n\t@w_screenbla.set(@screenbla)\n\n      when \"timeout:\"\n\t@screentim = fields[1]\n\t@screencyc = fields[3]\n\n      end\n    }\n\n    xfd.close\n  end\n\n  #\n  # Write settings into the X server\n  #\n  def writesettings\n    @bellvol = @w_bellvol.get\n    @bellpit = @w_bellpit.get\n    @belldur = @w_belldur.get\n\n    @kbdrep = @w_kbdrep.get\n    if @kbdrep == 'on'\n      @kbdcli = @w_kbdcli.get\n    else\n      @kbdcli = 'off'\n    end\n\n    @mouseacc = @w_mouseacc.get\n    @mousethr = @w_mousethr.get\n\n    @screentim = @w_screentim.get\n    @screencyc = @w_screencyc.get\n    @screenbla = @w_screenbla.get\n\n    system(\"xset \\\n            b #{@bellvol} #{@bellpit} #{@belldur} \\\n            c #{@kbdcli} \\\n            r #{@kbdrep} \\\n            m #{@mouseacc} #{@mousethr} \\\n            s #{@screentim} #{@screencyc} \\\n            s #{@screenbla}\")\n  end\n\n  #\n  # Sends all settings to the window\n  #\n  def dispsettings\n    @w_bellvol.set(@bellvol)\n    @w_bellpit.set(@bellpit)\n    @w_belldur.set(@belldur)\n\n    @w_kbdonoff.set(@w_kbdrep.get)\n    @w_kbdcli.set(@kbdcli)\n\n    @w_mouseacc.set(@mouseacc)\n    @w_mousethr.set(@mousethr)\n\n    @w_screenblank.set(@w_screenbla.get)\n    @w_screenpat.set(@w_screenbla.get)\n\n    @w_screentim.set(@screentim)\n    @w_screencyc.set(@screencyc)\n  end\n\n  #\n  # Create all windows, and pack them\n  #\n  class LabelEntry\n    def initialize(parent, text, length, range=[])\n      @frame = TkFrame.new(parent)\n      TkLabel.new(@frame, 'text'=>text).pack('side'=>'left')\n      if range.size > 0 \n\t@entry = TkSpinbox.new(@frame, 'width'=>length, 'relief'=>'sunken', \n\t\t\t       'from'=>range[0], 'to'=>range[1])\n      else\n\t@entry = TkEntry.new(@frame, 'width'=>length, 'relief'=>'sunken')\n      end\n      @entry.pack('side'=>'right','expand'=>'y', 'fill'=>'x')\n    end\n    def epath\n      @frame\n    end\n    def pack(keys)\n      @frame.pack(keys)\n    end\n    def get\n      @entry.value\n    end\n    def set(value)\n      @entry.delete(0,'end')\n      @entry.insert(0, value)\n    end\n  end\n\n  def createwindows\n    win = self\n\n    #\n    # Buttons\n    #\n    btn_frame = TkFrame.new(@root)\n    buttons = [ \n      @btn_OK = TkButton.new(btn_frame, 'command'=>proc{win.ok}, \n\t\t\t     'default'=>'active', 'text'=>'λ'),\n      @btn_APPLY = TkButton.new(btn_frame, 'command'=>proc{win.writesettings}, \n\t\t\t\t'default'=>'normal', 'text'=>'Ŭ', \n\t\t\t\t'state'=>'disabled'),\n      @btn_CANCEL = TkButton.new(btn_frame, 'command'=>proc{win.cancel}, \n\t\t\t\t 'default'=>'normal', 'text'=>'', \n\t\t\t\t'state'=>'disabled'),\n      @btn_QUIT = TkButton.new(btn_frame, 'command'=>proc{win.quit}, \n\t\t\t       'default'=>'normal', 'text'=>'')\n    ]\n    buttons.each{|b| b.pack('side'=>'left', 'expand'=>'yes', 'pady'=>5) }\n\n    @root.bind('Return', proc{@btn_OK.flash; @btn_OK.invoke})\n    @root.bind('Escape', proc{@btn_QUIT.flash; @btn_QUIT.invoke})\n    @root.bind('1', proc{|w|\n\t\t unless buttons.index(w)\n\t\t   @btn_APPLY.state(:normal)\n\t\t   @btn_CANCEL.state(:normal)\n\t\t end\n\t       }, '%W')\n    @root.bind('Key', proc{|w, k|\n\t\t unless buttons.index(w)\n\t\t   case k\n\t\t   when 'Return', 'Escape', 'Tab', /.*Shift.*/\n\t\t     # do nothing\n\t\t   else\n\t\t     @btn_APPLY.state(:normal)\n\t\t     @btn_CANCEL.state(:normal)\n\t\t   end\n\t\t end\n\t       }, '%W %K')\n\n    #\n    # Bell settings\n    #\n    bell = TkLabelframe.new(@root, 'text'=>'٥', \n\t\t\t    'padx'=>'1.5m', 'pady'=>'1.5m')\n    @w_bellvol = TkScale.new(bell, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t     'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t     'label'=>\" (%)\")\n\n    f = TkFrame.new(bell)\n    @w_bellpit = LabelEntry.new(f, \" (Hz)\", 6, [25, 20000])\n    @w_bellpit.pack('side'=>'left', 'padx'=>5)\n    @w_belldur = LabelEntry.new(f, \"³ (ms)\", 6, [1, 10000])\n    @w_belldur.pack('side'=>'right', 'padx'=>5)\n\n    @w_bellvol.pack('side'=>'top', 'expand'=>'yes')\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Keyboard settings\n    # \n    kbdonoff = nil\n    kbdcli = nil\n    kbd = TkLabelframe.new(@root, 'text'=>'ܡɥԡ', \n\t\t\t   'padx'=>'1.5m', 'pady'=>'1.5m')\n    f = TkFrame.new(kbd)\n    @w_kbdonoff = TkCheckButton.new(f, 'text'=>'å', \n\t\t\t\t    'relief'=>'flat', \n\t\t\t\t    'onvalue'=>'on', 'offvalue'=>'off',\n\t\t\t\t    'variable'=>@w_kbdrep ) {\n      def self.set(value)\n\tif value == 'on'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n      pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x', 'padx'=>[0, '1m'])\n    }\n    @w_kbdcli = TkScale.new(f, 'from'=>0, 'to'=>100, 'length'=>200, \n\t\t\t 'tickinterval'=>20, 'orient'=>'horizontal', \n\t\t\t 'label'=>'å (%)')\n    @w_kbdcli.pack('side'=>'left', 'expand'=>'yes', \n\t\t   'fill'=>'x', 'padx'=>['1m', 0])\n    f.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'fill'=>'x')\n\n    #\n    # Mouse settings\n    #\n    mouse = TkLabelframe.new(@root, 'text'=>'ޥ', \n\t\t\t     'padx'=>'1.5m', 'pady'=>'1.5m')\n    f = TkFrame.new(mouse)\n    @w_mouseacc = LabelEntry.new(f, '®', 5)\n    @w_mouseacc.pack('side'=>'left', 'padx'=>[0, '1m'])\n    @w_mousethr = LabelEntry.new(f, ' (pixels)', 3, [1, 2000])\n    @w_mousethr.pack('side'=>'right', 'padx'=>['1m', 0])\n    f.pack('side'=>'top', 'expand'=>'yes')\n\n    #\n    # Screen Saver settings\n    #\n    screen = TkLabelframe.new(@root, 'text'=>'꡼󥻡', \n\t\t\t     'padx'=>'1.5m', 'pady'=>'1.5m')\n    @w_screenblank = TkRadioButton.new(screen, 'text'=>'֥ɽ', \n\t\t\t\t       'relief'=>'flat', 'anchor'=>'w', \n\t\t\t\t       'variable'=>@w_screenbla, \n\t\t\t\t       'value'=>'blank') {\n      def self.set(value)\n\tif value == 'blank'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n    }\n\n    @w_screenpat = TkRadioButton.new(screen, 'text'=>'ѥɽ', \n\t\t\t\t     'relief'=>'flat', 'anchor'=>'w', \n\t\t\t\t     'variable'=>@w_screenbla, \n\t\t\t\t     'value'=>'noblank') {\n      def self.set(value)\n\tif value != 'blank'\n\t  self.select\n\telse\n\t  self.deselect\n\tend\n      end\n    }\n\n    @w_screentim = LabelEntry.new(screen, 'ॢ (s)', 5, [1, 100000])\n    @w_screencyc = LabelEntry.new(screen, ' (s)', 5, [1, 100000])\n\n    Tk.grid(@w_screenblank, @w_screentim, 'sticky'=>'e')\n    Tk.grid(@w_screenpat, @w_screencyc, 'sticky'=>'e')\n    TkGrid.configure(@w_screenblank, @w_screenpat, 'sticky'=>'ew')\n\n    #\n    # Main window\n    #\n    param = {\n      'side'=>'top', 'fill'=>'both', 'expand'=>'yes', \n      'padx'=>'1m', 'pady'=>'1m'\n    }\n    btn_frame.pack('side'=>'top', 'fill'=>'both')\n    bell.pack(param)\n    kbd.pack(param)\n    mouse.pack(param)\n    screen.pack(param)\n\n    #\n    # Let the user resize our window\n    #\n    @root.minsize(10,10)\n  end\n\n  def initialize(title)\n    @root = TkRoot.new('title'=>title)\n\n    @kbdrep = 'on'\n    @w_kbdrep = TkVariable.new(@kbdrep)\n    def @w_kbdrep.get\n      self.value\n    end\n    def @w_kbdrep.set(val)\n      self.value=val\n    end\n\n    @kbdcli = 0\n\n    @bellvol = 100\n    @bellpit = 440\n    @belldur = 100\n\n    @mouseacc = \"3/1\"\n    @mousethr = 4\n\n    @screenbla = \"blank\"\n    @w_screenbla = TkVariable.new(@screenbla)\n    def @w_screenbla.get\n      self.value\n    end\n    def @w_screenbla.set(val)\n      self.value=val\n    end\n\n    @screentim = 600\n    @screencyc = 600\n\n    #\n    # Listen what \"xset\" tells us...\n    #\n    readsettings\n\n    #\n    # Create all windows\n    #\n    createwindows\n\n    #\n    # Write xset parameters\n    #\n    dispsettings\n  end\nend\n\nXsettings.new(File.basename($0,'.rb'))\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/knightstour.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# Based on the widget demo of Tcl/Tk8.5.2\n# The following is the original copyright text.\n#----------------------------------------------------------------------------\n# Copyright (C) 2008 Pat Thoyts <patthoyts@users.sourceforge.net>\n#\n#\tCalculate a Knight's tour of a chessboard.\n#\n#\tThis uses Warnsdorff's rule to calculate the next square each\n#\ttime. This specifies that the next square should be the one that\n#\thas the least number of available moves.\n#\n#\tUsing this rule it is possible to get to a position where\n#\tthere are no squares available to move into. In this implementation\n#\tthis occurs when the starting square is d6.\n#\n#\tTo solve this fault an enhancement to the rule is that if we\n#\thave a choice of squares with an equal score, we should choose\n#\tthe one nearest the edge of the board.\n#\n#\tIf the call to the Edgemost function is commented out you can see\n#\tthis occur.\n#\n#\tYou can drag the knight to a specific square to start if you wish.\n#\tIf you let it repeat then it will choose random start positions\n#\tfor each new tour.\n#----------------------------------------------------------------------------\nrequire 'tk'\n\nclass Knights_Tour\n  # Return a list of accessible squares from a given square\n  def valid_moves(square)\n    moves = []\n    [\n      [-1,-2], [-2,-1], [-2,1], [-1,2], [1,2], [2,1], [2,-1], [1,-2]\n    ].each{|col_delta, row_delta|\n      col = (square % 8) + col_delta\n      row = (square.div(8)) + row_delta\n      moves << (row * 8 + col) if row > -1 && row < 8 && col > -1 && col < 8\n    }\n    moves\n  end\n\n  # Return the number of available moves for this square\n  def check_square(square)\n    valid_moves(square).find_all{|pos| ! @visited.include?(pos)}.length\n  end\n\n  # Select the next square to move to. Returns -1 if there are no available\n  # squares remaining that we can move to.\n  def next_square(square)\n    minimum = 9\n    nxt = -1\n    valid_moves(square).each{|pos|\n      unless @visited.include?(pos)\n        cnt = check_square(pos)\n        if cnt < minimum\n          minimum = cnt\n          nxt = pos\n        elsif cnt == minimum\n          nxt = edgemost(nxt, pos)\n        end\n      end\n    }\n    nxt\n  end\n\n  # Select the square nearest the edge of the board\n  def edgemost(nxt, pos)\n    col_A = 3 - ((3.5 - nxt % 8).abs.to_i)\n    col_B = 3 - ((3.5 - pos % 8).abs.to_i)\n    row_A = 3 - ((3.5 - nxt.div(8)).abs.to_i)\n    row_B = 3 - ((3.5 - pos.div(8)).abs.to_i)\n    (col_A * row_A < col_B * row_B)? nxt : pos\n  end\n\n  # Display a square number as a standard chess square notation.\n  def _N(square)\n    '%c%d' % [(97 + square % 8), (square.div(8) + 1)]\n  end\n\n  # Perform a Knight's move and schedule the next move.\n  def move_piece(last, square)\n    @log.insert(:end, \"#{@visited.length}. #{_N last} -> #{_N square}\\n\", '')\n    @log.see(:end)\n    @board.itemconfigure(1+last, :state=>:normal, :outline=>'black')\n    @board.itemconfigure(1+square, :state=>:normal, :outline=>'red')\n    @knight.coords(@board.coords(1+square)[0..1])\n    @visited << square\n    if (nxt = next_square(square)) != -1\n      @after_id = Tk.after(@delay.numeric){move_piece(square, nxt) rescue nil}\n    else\n      @start_btn.state :normal\n      if @visited.length == 64\n        if @initial == square\n          @log.insert :end, 'ͷ(closed tour)'\n        else\n          @log.insert :end, \"\\n\", {}\n          Tk.after(@delay.numeric * 2){tour(rand(64))} if @continuous.bool\n        end\n      else\n        @log.insert :end, \"ԡ\\n\", {}\n      end\n    end\n  end\n\n  # Begin a new tour of the board given a random start position\n  def tour(square = nil)\n    @visited.clear\n    @log.clear\n    @start_btn.state :disabled\n    1.upto(64){|n|\n      @board.itemconfigure(n, :state=>:disabled, :outline=>'black')\n    }\n    unless square\n      square = @board.find_closest(*(@knight.coords << 0 << 65))[0].to_i - 1\n    end\n    @initial = square\n    Tk.after_idle{ move_piece(@initial, @initial) rescue nil }\n  end\n\n  def _stop\n    Tk.after_cancel(@after_id) rescue nil\n  end\n\n  def _exit\n    _stop\n    $knightstour.destroy\n  end\n\n  def set_delay(new)\n    @delay.numeric = new.to_i\n  end\n\n  def drag_start(w, x, y)\n    w.dtag('selected')\n    w.addtag('selected', :withtag, 'current')\n    @dragging = [x, y]\n  end\n\n  def drag_motion(w, x, y)\n    return unless @dragging\n    w.move('selected', x - @dragging[0], y - @dragging[1])\n    @dragging = [x, y]\n  end\n\n  def drag_end(w, x, y)\n    square = w.find_closest(x, y, 0, 65)\n    w.coords('selected', w.coords(square)[0..1])\n    w.dtag('selected')\n    @dragging = nil\n  end\n\n  def make_SeeDismiss\n    ## See Code / Dismiss\n    frame = Ttk::Frame.new($knightstour)\n    sep = Ttk::Separator.new(frame)\n    Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n    TkGrid('x', \n           Ttk::Button.new(frame, :text=>'ɻ', \n                           :image=>$image['view'], :compound=>:left, \n                           :command=>proc{showCode 'knightstour'}), \n           Ttk::Button.new(frame, :text=>'Ĥ', \n                           :image=>$image['delete'], :compound=>:left, \n                           :command=>proc{\n                             $knightstour.destroy\n                             $knightstour = nil\n                           }), \n           :padx=>4, :pady=>4)\n    frame.grid_columnconfigure(0, :weight=>1)\n    frame\n  end\n\n  def create_gui(parent = nil)\n    $knightstour.destroy rescue nil\n    $knightstour = Tk::Toplevel.new(parent, :title=>\"Knight's tour\")\n    $knightstour.withdraw\n    base_f = Ttk::Frame.new($knightstour)\n    @board = Tk::Canvas.new(base_f, :width=>240, :height=>240)\n    @log = Tk::Text.new(base_f, :width=>12, :height=>1, \n                        :font=>'Arial 8', :background=>'white')\n    scr = @log.yscrollbar(Ttk::Scrollbar.new(base_f))\n\n    @visited = []\n    @delay = TkVariable.new(600)\n    @continuous = TkVariable.new(false)\n\n    tool_f = Ttk::Frame.new($knightstour)\n    label = Ttk::Label.new(tool_f, :text=>'¹®')\n    scale = Ttk::Scale.new(tool_f, :from=>8, :to=>2000, :variable=>@delay, \n                           :command=>proc{|n| set_delay(n)})\n    check = Ttk::Checkbutton.new(tool_f, :text=>'ȿ', \n                                 :variable=>@continuous)\n    @start_btn = Ttk::Button.new(tool_f, :text=>'', \n                                 :command=>proc{tour()})\n    @exit_btn = Ttk::Button.new(tool_f, :text=>'λ', \n                                :command=>proc{_exit()})\n\n    7.downto(0){|row|\n      0.upto(7){|col|\n        if ((col & 1) ^ (row & 1)).zero?\n          fill  = 'bisque'\n          dfill = 'bisque3'\n        else\n          fill  = 'tan3'\n          dfill = 'tan4'\n        end\n        coords = [col * 30 + 4, row * 30 + 4, col * 30 + 30, row * 30 + 30]\n        @board.create(TkcRectangle, coords, \n                      :fill=>fill, :disabledfill=>dfill,\n                      :width=>2, :state=>:disabled)\n      }\n    }\n\n    @knight_font = TkFont.new(:size=>-24)\n    @knight = TkcText.new(@board, 0, 0, :font=>@knight_font, \n                          :text=>Tk::UTF8_String.new('\\u265e'), \n                          :anchor=>'nw', # :tags=>'knight', \n                          :fill=>'black', :activefill=>'#600000')\n    @knight.coords(@board.coords(rand(64)+1)[0..1])\n    @knight.bind('ButtonPress-1', '%W %x %y'){|w,x,y| drag_start(w,x,y)}\n    @knight.bind('Motion', '%W %x %y'){|w,x,y| drag_motion(w,x,y)}\n    @knight.bind('ButtonRelease-1', '%W %x %y'){|w,x,y| drag_end(w,x,y)}\n\n    Tk.grid(@board, @log, scr, :sticky=>'news')\n    base_f.grid_rowconfigure(0, :weight=>1)\n    base_f.grid_columnconfigure(0, :weight=>1)\n\n    Tk.grid(base_f, '-', '-', '-', '-', '-', :sticky=>'news')\n    widgets = [label, scale, check, @start_btn]\n    sg = nil\n    unless $RubyTk_WidgetDemo\n      widgets << @exit_btn\n      if Tk.windowingsystem != 'aqua'\n        #widgets.unshift(Ttk::SizeGrip.new(tool_f))\n        Ttk::SizeGrip.new(tool_f).pack(:side=>:right, :anchor=>'se')\n      end\n    end\n    Tk.pack(widgets, :side=>:right)\n    if Tk.windowingsystem == 'aqua'\n      TkPack.configure(widgets, :padx=>[4, 4], :pady=>[12, 12])\n      TkPack.configure(widgets[0], :padx=>[4, 24])\n      TkPack.configure(widgets[-1], :padx=>[16, 4])\n    end\n\n    Tk.grid(tool_f, '-', '-', '-', '-', '-', :sticky=>'ew')\n\n    if $RubyTk_WidgetDemo\n      Tk.grid(make_SeeDismiss(), '-', '-', '-', '-', '-', :sticky=>'ew')\n    end\n\n    $knightstour.grid_rowconfigure(0, :weight=>1)\n    $knightstour.grid_columnconfigure(0, :weight=>1)\n\n    $knightstour.bind('Control-F2'){TkConsole.show}\n    $knightstour.bind('Return'){@start_btn.invoke}\n    $knightstour.bind('Escape'){@exit_btn.invoke}\n    $knightstour.bind('Destroy'){ _stop }\n    $knightstour.protocol('WM_DELETE_WINDOW'){ _exit }\n\n    $knightstour.deiconify\n    $knightstour.tkwait_destroy\n  end\n\n  def initialize(parent = nil)\n    create_gui(parent)\n  end\nend\n\nTk.root.withdraw unless $RubyTk_WidgetDemo\nThread.new{Tk.mainloop} if __FILE__ == $0\nKnights_Tour.new\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/label.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# label widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($label_demo) && $label_demo\n  $label_demo.destroy \n  $label_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$label_demo = TkToplevel.new {|w|\n  title(\"Label Demonstration\")\n  iconname(\"label\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($label_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤ5ĤΥ٥뤬ɽƤޤ¦ˤϥƥȥ٥뤬3Ĥꡢ¦ˤϥӥåȥޥåץ٥ȥƥȥ٥뤬ޤ٥ȤΤϤޤ򤤤ΤǤϤޤ󡣤ʤʤįʳǤʤǤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $label_demo\n      $label_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'label'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# label demo ѥե졼\nf_left = TkFrame.new(base_frame)\nf_right = TkFrame.new(base_frame)\n[f_left, f_right].each{|w| w.pack('side'=>'left', 'expand'=>'yes', \n                                  'padx'=>10, 'pady'=>10, 'fill'=>'both')}\n\n# label \n[ TkLabel.new(f_left, 'text'=>'ǽΥ٥'),\n  TkLabel.new(f_left, 'text'=>'2 ܡä⤭夬餻Ƥߤޤ', \n              'relief'=>'raised'),\n  TkLabel.new(f_left, 'text'=>'3 ܡǤޤ ', 'relief'=>'sunken')\n].each{|w| w.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'anchor'=>'w')}\n\n# TkLabel.new(f_right) {\nTk::Label.new(f_right) {\n  bitmap('@' + [$demo_dir,'..','images','face.xbm'].join(File::Separator))\n  borderwidth 2\n  relief 'sunken'\n}.pack('side'=>'top')\n\nTkLabel.new(f_right) { text 'Tcl/Tk ͭ' }.pack('side'=>'top')\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/labelframe.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# labelframe.rb\n#\n# This demonstration script creates a toplevel window containing\n# several labelframe widgets.\n#\n# based on \"Id: labelframe.tcl,v 1.2 2001/10/30 11:21:50 dkf Exp\"\n\n\nif defined?($labelframe_demo) && $labelframe_demo\n  $labelframe_demo.destroy \n  $labelframe_demo = nil\nend\n\n$labelframe_demo = TkToplevel.new {|w|\n  title(\"Labelframe Demonstration\")\n  iconname(\"labelframe\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($labelframe_demo).pack(:fill=>:both, :expand=>true)\n\n# Some information\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nTkLabelFrame åȤϴϢ widget \nޤȤƼ갷Ѥޤ\n٥̾ʸǤⲿ餫Υå\nǤ⤫ޤޤ󡣤⤷ʤȤäƤ \nRuby ˥󥯤Ƥ Tk 饤֥꤬ \nlabelframe åȤƤʤ\n硢ΥǥϤޤưʤϤǤ\nξˤ labelframe åȤ\nƤ褦ʤ꿷С Tk \nȤ߹碌ƻ褦ˤƤ\nEOL\n\n# The bottom buttons\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $labelframe_demo.destroy\n                 $labelframe_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'labelframe'\n               }).pack(:side=>:left, :expand=>true)\n}\n\n# Demo area\nw = TkFrame.new(base_frame).pack(:side=>:bottom, :fill=>:both, \n                                       :expand=>true)\n\n# A group of radiobuttons in a labelframe\nTkLabelFrame.new(w, :text=>'', \n                 :padx=>2, :pady=>2) {|f|\n  grid(:row=>0, :column=>0, :pady=>'2m', :padx=>'2m')\n\n  v = TkVariable.new\n  (1..4).each{|i|\n    TkRadiobutton.new(f, :text=>\"This is value #{i}\", \n                      :variable=>v, :value=>i) {\n      pack(:side=>:top, :fill=>:x, :pady=>2)\n    }\n  }\n}\n\n\n# Using a label window to control a group of options.\n$lfdummy = TkVariable.new(0)\n\ndef lfEnableButtons(w)\n  TkWinfo.children(w).each{|child|\n    next if child.path =~ /\\.cb$/\n    if $lfdummy == 1\n      child.state(:normal)\n    else\n      child.state(:disabled)\n    end\n  }\nend\n\nTkLabelFrame.new(w, :pady=>2, :padx=>2){|f|\n  TkCheckButton.new(f, :widgetname=>'cb', :variable=>$lfdummy, \n                    :text=>\"ץ\", :padx=>0) {|cb|\n    command proc{lfEnableButtons(f)}\n    f.labelwidget(cb)\n  }\n  grid(:row=>0, :column=>1, :pady=>'2m', :padx=>'2m')\n\n  %w(ץ1 ץ2 ץ3).each{|str|\n    TkCheckbutton.new(f, :text=>str).pack(:side=>:top, :fill=>:x, :pady=>2)\n  }\n\n  lfEnableButtons(f)\n}\n\nTkGrid.columnconfigure(w, [0,1], :weight=>1)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/mclist.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# mclist.rb --\n#\n# This demonstration script creates a toplevel window containing a Ttk\n# tree widget configured as a multi-column listbox.\n#\n# based on \"Id: mclist.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($mclist_demo) && $mclist_demo\n  $mclist_demo.destroy \n  $mclist_demo = nil\nend\n\n$mclist_demo = TkToplevel.new {|w|\n  title(\"Multi-Column List\")\n  iconname(\"mclist\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($mclist_demo).pack(:fill=>:both, :expand=>true)\n\n## Explanatory text\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', \n               :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], \n               :text=><<EOL).pack(:fill=>:x)\nTtkȤϡơ޻ǽʿåȽǤ\\\nTtk::TreeviewåȤ\\\nTtkåȥåȤ˴ޤޤ륦åȤΰĤǡ\\\n줬ݻڹ¤ΥǡΤΤޤǤɽ뤳Ȥʤ\\\nޥɽ뤳ȤǤޤ\nΥץϡʣΥäꥹȥܥåñǤ\nƥΥȥ(heading)򥯥åС\\\nΥξ˴ŤƥꥹȤ¤ؤʤϤǤ\\\nޤΥȥ֤ζڤʬɥå뤳Ȥǡ\\\nѹ뤳ȤǽǤ\nEOL\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'mclist'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $mclist_demo.destroy\n                           $mclist_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\ncontainer = Ttk::Frame.new(base_frame)\ntree = Ttk::Treeview.new(base_frame, :columns=>%w(country capital currency), \n                          :show=>:headings)\nif Tk.windowingsystem != 'aquq'\n  vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame))\nelse\n  vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame))\nend\n\ncontainer.pack(:fill=>:both, :expand=>true)\nTk.grid(tree, vsb, :in=>container, :sticky=>'nsew')\nTk.grid(hsb,       :in=>container, :sticky=>'nsew')\ncontainer.grid_columnconfigure(0, :weight=>1)\ncontainer.grid_rowconfigure(0, :weight=>1)\n\n## The data we're going to insert\ndata = [\n  ['를', \t'֥Υ쥹', \t'ARS'], \n  ['ȥꥢ',\t'٥',\t\t'AUD'], \n  ['֥饸', \t\t'֥饸ꥢ', \t\t'BRL'], \n  ['ʥ', \t\t'', \t\t'CAD'], \n  ['',\t\t'̵', \t\t'CNY'], \n  ['ե',\t\t'ѥ', \t\t'EUR'], \n  ['ɥ', \t\t'٥',\t\t'EUR'], \n  ['', \t\t'˥塼ǥ꡼',\t\t'INR'], \n  ['ꥢ', \t\t'', \t\t'EUR'], \n  ['', \t\t'', \t\t'JPY'], \n  ['ᥭ', \t\t'ᥭƥ', \t'MXN'], \n  ['', \t\t'⥹', \t\t'RUB'], \n  ['եꥫ',\t'ץȥꥢ', \t\t'ZAR'], \n  ['ѹ', \t\t'ɥ', \t\t'GBP'], \n  ['ꥫ', \t\t'亮ȥ D.C.', \t'USD'],\n]\n\n## Code to insert the data nicely\nfont = Ttk::Style.lookup(tree[:style], :font)\ncols = %w(country capital currency)\ncols.zip(%w(̾  ̲)).each{|col, name|\n  tree.heading_configure(col, :text=>name, \n                         :command=>proc{sort_by(tree, col, false)})\n  tree.column_configure(col, :width=>TkFont.measure(font, name))\n}\n\ndata.each{|country, capital, currency|\n  #tree.insert('', :end, :values=>[country, capital, currency])\n  tree.insert(nil, :end, :values=>[country, capital, currency])\n  cols.zip([country, capital, currency]).each{|col, val|\n    len = TkFont.measure(font, \"#{val}  \")\n    if tree.column_cget(col, :width) < len\n      tree.column_configure(col, :width=>len)\n    end\n  }\n}\n\n## Code to do the sorting of the tree contents when clicked on\ndef sort_by(tree, col, direction)\n  tree.children(nil).map!{|row| [tree.get(row, col), row.id]} . \n    sort(&((direction)? proc{|x, y| y <=> x}: proc{|x, y| x <=> y})) . \n    each_with_index{|info, idx| tree.move(info[1], nil, idx)}\n\n  tree.heading_configure(col, :command=>proc{sort_by(tree, col, ! direction)})\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/menu.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# menus widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($menu_demo) && $menu_demo\n  $menu_demo.destroy \n  $menu_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$menu_demo = TkToplevel.new {|w|\n  title(\"File Selection Dialogs\")\n  iconname(\"menu\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($menu_demo).pack(:fill=>:both, :expand=>true)\n\n# menu frame \n$menu_frame = TkFrame.new(base_frame, 'relief'=>'raised', 'bd'=>2)\n$menu_frame.pack('side'=>'top', 'fill'=>'x')\n\nbegin\n  windowingsystem = Tk.windowingsystem()\nrescue\n  windowingsystem = \"\"\nend\n\n# label \nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n  if $tk_platform['platform'] == 'macintosh' ||\n      windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    text(\"Υɥ͡ʥ˥塼ȥɥ˥塼鹽ƤޤCommand-X ϤȡXޥɥ³ɽƤʸʤС졼ȤäܵưԤȤǤޤ˥塼桢ǸΤΤϡΥ˥塼κǽιܤ򤹤뤳ȤΩ뤳ȤǤޤ\")\n  else\n    text(\"Υɥ͡ʥ˥塼ȥɥ˥塼鹽ƤޤAlt-X ϤȡX˥塼˥饤դɽƤʸʤСܡɤλ꤬Ǥޤǥ˥塼ΥȥСǽǤ˥塼ꤵ줿ݤˤϡڡǼ¹Ԥ뤳ȤǤޤ뤤ϡ饤դʸϤ뤳ȤǤ¹ԤǤޤ˥塼Υȥ꤬졼äƤϡΥ졼Ϥ뤳Ȥǥ˥塼ꤹ뤳Ȥʤ˼¹Ԥ뤳ȤǤޤ˥塼桢ǸΤΤϡΥ˥塼κǽιܤ򤹤뤳ȤΩ뤳ȤǤޤ\")\n  end\n}.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $menu_demo\n      $menu_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'menu'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# menu \nTkMenubutton.new($menu_frame, 'text'=>'File', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|file_menu|\n    m.configure('menu'=>file_menu)\n    add('command', 'label'=>' ...', 'command'=>proc{fail 'ϡǥǤΤ\" ...\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'', 'command'=>proc{fail 'ϡǥǤΤ\"\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'¸', 'command'=>proc{fail 'ϡǥǤΤ\"¸\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'¸() ...', 'command'=>proc{fail 'ϡǥǤΤ\"¸() ...\"Ф륢Ƥޤ'})\n    add('separator')\n    add('command', 'label'=>'ץ ...', 'command'=>proc{fail 'ϡǥǤΤ\"ץ ...\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'ץ ...', 'command'=>proc{fail 'ϡǥǤΤ\"ץ ...\"Ф륢Ƥޤ'})\n    add('separator')\n    add('command', 'label'=>'λ', 'command'=>proc{$menu_demo.destroy})\n  }\n}\n\nif $tk_platform['platform'] == 'macintosh' ||\n    windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n  modifier = 'Command'\nelsif $tk_platform['platform'] == 'windows'\n  modifier = 'Control'\nelse\n  modifier = 'Meta'\nend\n\nTkMenubutton.new($menu_frame, 'text'=>'Basic', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|basic_menu|\n    m.configure('menu'=>basic_menu)\n    add('command', 'label'=>'⤷ʤĹȥ')\n    ['A','B','C','D','E','F','G'].each{|c|\n      # add('command', 'label'=>\"ʸ \\\"#{c}\\\" \", 'underline'=>4, \n      add('command', 'label'=>\"Print letter \\\"#{c}\\\" (ʸ \\\"#{c}\\\" )\", \n          'underline'=>14, 'accelerator'=>\"Meta+#{c}\", \n          'command'=>proc{print c,\"\\n\"}, 'accelerator'=>\"#{modifier}+#{c}\")\n      $menu_demo.bind(\"#{modifier}-#{c.downcase}\", proc{print c,\"\\n\"})\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'Cascades', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_menu|\n    m.configure('menu'=>cascade_menu)\n    add('command', 'label'=>'Print hello(ˤ)', \n        'command'=>proc{print \"Hello(ˤ)\\n\"}, \n        'accelerator'=>\"#{modifier}+H\", 'underline'=>6)\n    $menu_demo.bind(\"#{modifier}-h\", proc{print \"Hello(ˤ)\\n\"})\n    add('command', 'label'=>'Print goodbye(褦ʤ)', \n        'command'=>proc{print \"Goodbye(褦ʤ)\\n\"}, \n        'accelerator'=>\"#{modifier}+G\", 'underline'=>6)\n    $menu_demo.bind(\"#{modifier}-g\", proc{print \"Goodbye(褦ʤ)\\n\"})\n\n    # TkMenu.new(m, 'tearoff'=>false) {|cascade_check|\n    TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_check|\n      cascade_menu.add('cascade', 'label'=>'Check buttons(åܥ)', \n                       'menu'=>cascade_check, 'underline'=>0)\n      oil = TkVariable.new(0)\n      add('check', 'label'=>'', 'variable'=>oil)\n      trans = TkVariable.new(0)\n      add('check', 'label'=>'ȥ󥹥ߥå', 'variable'=>trans)\n      brakes = TkVariable.new(0)\n      add('check', 'label'=>'֥졼', 'variable'=>brakes)\n      lights = TkVariable.new(0)\n      add('check', 'label'=>'饤', 'variable'=>lights)\n      add('separator')\n      add('command', 'label'=>'ߤͤɽ', \n          'command'=>proc{showVars($menu_demo, \n                                   ['', oil], \n                                   ['ȥ󥹥ߥå', trans], \n                                   ['֥졼', brakes], \n                                   ['饤', lights])} )\n      invoke 1\n      invoke 3\n    }\n\n    #TkMenu.new(m, 'tearoff'=>false) {|cascade_radio|\n    TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_radio|\n      cascade_menu.add('cascade', 'label'=>'Radio buttons(饸ܥ)', \n                       'menu'=>cascade_radio, 'underline'=>0)\n      pointSize = TkVariable.new\n      add('radio', 'label'=>'10 ݥ', 'variable'=>pointSize, 'value'=>10)\n      add('radio', 'label'=>'14 ݥ', 'variable'=>pointSize, 'value'=>14)\n      add('radio', 'label'=>'18 ݥ', 'variable'=>pointSize, 'value'=>18)\n      add('radio', 'label'=>'24 ݥ', 'variable'=>pointSize, 'value'=>24)\n      add('radio', 'label'=>'32 ݥ', 'variable'=>pointSize, 'value'=>32)\n      add('separator')\n      style = TkVariable.new\n      add('radio', 'label'=>'ޥ', 'variable'=>style, 'value'=>'roman')\n      add('radio', 'label'=>'ܡ', 'variable'=>style, 'value'=>'bold')\n      add('radio', 'label'=>'å', 'variable'=>style, 'value'=>'italic')\n      add('separator')\n      add('command', 'label'=>'ߤͤɽ', \n          'command'=>proc{showVars($menu_demo, \n                                   ['ݥȥ', pointSize], \n                                   ['', style])} )\n      invoke 1\n      invoke 7\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'Icons', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|icon_menu|\n    m.configure('menu'=>icon_menu)\n    add('command', \n        'bitmap'=>'@'+[$demo_dir,'..',\n                        'images','pattern.xbm'].join(File::Separator),\n        'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', \n                                     'text'=>'ʤ򤷤˥塼ιܤϥƥȤǤϤʤӥåȥޥåפɽƤޤʳǤ¾Υ˥塼ܤѤޤ',\n                                     'bitmap'=>'', 'default'=>0, \n                                     'buttons'=>'λ')} )\n    ['info', 'questhead', 'error'].each{|icon|\n      add('command', 'bitmap'=>icon, \n          'command'=>proc{print \"You invoked the #{icon} bitmap\\n\"})\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'More', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m, 'tearoff'=>false) {|more_menu|\n    m.configure('menu'=>more_menu)\n    [ 'ȥ','̤Υȥ','⤷ʤ','ۤȤɲ⤷ʤ',\n      'յΤ' ].each{|i|\n      add('command', 'label'=>i, \n          'command'=>proc{print \"You invoked \\\"#{i}\\\"\\n\"})\n    }\n  }\n}\n\nTkMenubutton.new($menu_frame, 'text'=>'Colors', 'underline'=>0) {|m|\n  pack('side'=>'left')\n  TkMenu.new(m) {|colors_menu|\n    m.configure('menu'=>colors_menu)\n    ['red', 'orange', 'yellow', 'green', 'blue'].each{|c|\n      add('command', 'label'=>c, 'background'=>c, \n          'command'=>proc{print \"You invoked \\\"#{c}\\\"\\n\"})\n    }\n  }\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/menu84.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# menus widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($menu84_demo) && $menu84_demo\n  $menu84_demo.destroy \n  $menu84_demo = nil\nend\n\n# demo toplevel widget\n$menu84_demo = TkToplevel.new {|w|\n  title(\"File Selection Dialogs\")\n  iconname(\"menu84\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($menu84_demo).pack(:fill=>:both, :expand=>true)\n\nbegin\n  windowingsystem = Tk.windowingsystem()\nrescue\n  windowingsystem = \"\"\nend\n\n# label\nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n  if $tk_platform['platform'] == 'macintosh' ||\n      windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    text(\"Υɥˤϥɥ˥塼ĥ˥塼СդƤޤCommand+x ('x'ϥޥɥܥ³ɽƤʸǤ) ȥפ뤳ȤˤäƤܤεǽƤӽФȤǤޤǸΥ˥塼ϡޥǥɥγ˥ɥå뤳ȤˤäơΩѥåȤȤʤ褦ڤȤǽǤ\")\n  else\n    text(\"Υɥˤϥɥ˥塼ĥ˥塼СդƤޤAlt+x ('x'ϥ˥塼ǲ줿ʸǤ) ȥפ뤳ȤˤäƤ˥塼ƤӽФȤǤޤȤäơ˥塼֤ư뤳ȤǽǤ˥塼ɽƤˤϡ֤߰ιܤ򥹥ڡ򤷤ꡢ줿ʸϤ뤳ȤǤιܤ򤷤ꤹ뤳ȤǤޤ⤷ܤ˥졼λ꤬ʤƤʤСλꤵ줿ϤԤȤǡ˥塼ɽ뤳ȤʤľܤιܤεǽƤӽФޤǸΥ˥塼ϡ˥塼κǽιܤ򤹤뤳ȤˤäơΩѥåȤȤʤ褦ڤȤǽǤ\")\n  end\n}.pack('side'=>'top')\n\n\nmenustatus = TkVariable.new(\"    \")\nTkFrame.new(base_frame) {|frame|\n  TkLabel.new(frame, 'textvariable'=>menustatus, 'relief'=>'sunken', \n              'bd'=>1, 'font'=>['Helvetica', '10'], \n              'anchor'=>'w').pack('side'=>'left', 'padx'=>2, \n                                  'expand'=>true, 'fill'=>'both')\n  pack('side'=>'bottom', 'fill'=>'x', 'pady'=>2)\n}\n\n\n# frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $menu84_demo\n      $menu84_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'menu84'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n\n# create menu frame\n$menu84_frame = TkMenu.new($menu84_demo, 'tearoff'=>false)\n\n# menu\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'File', 'menu'=>m, 'underline'=>0)\n  add('command', 'label'=>'Open...', 'command'=>proc{fail 'ñʤǥǤ顢\"Open...\" ܤεǽäƤϤޤ'})\n  add('command', 'label'=>'New', 'command'=>proc{fail 'ñʤǥǤ顢\"New\" ܤεǽäƤϤޤ'})\n  add('command', 'label'=>'Save', 'command'=>proc{fail 'ñʤǥǤ顢\"Save\" ܤεǽäƤϤޤ'})\n  add('command', 'label'=>'Save As...', 'command'=>proc{fail 'ñʤǥǤ顢\"Save As...\" ܤεǽäƤϤޤ'})\n  add('separator')\n  add('command', 'label'=>'Print Setup...', 'command'=>proc{fail 'ñʤǥǤ顢\"Print Setup...\" ܤεǽäƤϤޤ'})\n  add('command', 'label'=>'Print...', 'command'=>proc{fail 'ñʤǥǤ顢\"Print...\" ܤεǽäƤϤޤ'})\n  add('separator')\n  add('command', 'label'=>'Dismiss Menus Demo', 'command'=>proc{$menu84_demo.destroy})\n}\n\nif $tk_platform['platform'] == 'macintosh' ||\n    windowingsystem = \"classic\" || windowingsystem = \"aqua\"\n  modifier = 'Command'\nelsif $tk_platform['platform'] == 'windows'\n  modifier = 'Control'\nelse\n  modifier = 'Meta'\nend\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Basic', 'menu'=>m, 'underline'=>0)\n  add('command', 'label'=>'Long entry that does nothing')\n  ['A','B','C','D','E','F','G'].each{|c|\n    add('command', 'label'=>\"Print letter \\\"#{c}\\\"\", \n        'underline'=>14, 'accelerator'=>\"Meta+#{c}\", \n        'command'=>proc{print c,\"\\n\"}, 'accelerator'=>\"#{modifier}+#{c}\")\n    $menu84_demo.bind(\"#{modifier}-#{c.downcase}\", proc{print c,\"\\n\"})\n  }\n}\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Cascades', 'menu'=>m, 'underline'=>0)\n  add('command', 'label'=>'Print hello', \n      'command'=>proc{print \"Hello\\n\"}, \n      'accelerator'=>\"#{modifier}+H\", 'underline'=>6)\n  $menu84_demo.bind(\"#{modifier}-h\", proc{print \"Hello\\n\"})\n  add('command', 'label'=>'Print goodbye', \n      'command'=>proc{print \"Goodbye\\n\"}, \n      'accelerator'=>\"#{modifier}+G\", 'underline'=>6)\n  $menu84_demo.bind(\"#{modifier}-g\", proc{print \"Goodbye\\n\"})\n\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_check|\n    m.add('cascade', 'label'=>'Check button', \n          'menu'=>cascade_check, 'underline'=>0)\n    oil = TkVariable.new(0)\n    add('check', 'label'=>'븡', 'variable'=>oil)\n    trans = TkVariable.new(0)\n    add('check', 'label'=>'ȥ󥹥ߥå󸡺', 'variable'=>trans)\n    brakes = TkVariable.new(0)\n    add('check', 'label'=>'֥졼', 'variable'=>brakes)\n    lights = TkVariable.new(0)\n    add('check', 'label'=>'饤ȸ', 'variable'=>lights)\n    add('separator')\n    add('command', 'label'=>'Show current values', \n        'command'=>proc{showVars($menu84_demo, \n                                 ['', oil], \n                                 ['ȥ󥹥ߥå', trans], \n                                 ['֥졼', brakes], \n                                 ['饤', lights])} )\n    invoke 1\n    invoke 3\n  }\n\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_radio|\n    m.add('cascade', 'label'=>'Radio buttons', \n          'menu'=>cascade_radio, 'underline'=>0)\n    pointSize = TkVariable.new\n    add('radio', 'label'=>'10 point', 'variable'=>pointSize, 'value'=>10)\n    add('radio', 'label'=>'14 point', 'variable'=>pointSize, 'value'=>14)\n    add('radio', 'label'=>'18 point', 'variable'=>pointSize, 'value'=>18)\n    add('radio', 'label'=>'24 point', 'variable'=>pointSize, 'value'=>24)\n    add('radio', 'label'=>'32 point', 'variable'=>pointSize, 'value'=>32)\n    add('separator')\n    style = TkVariable.new\n    add('radio', 'label'=>'Roman', 'variable'=>style, 'value'=>'roman')\n    add('radio', 'label'=>'Bold', 'variable'=>style, 'value'=>'bold')\n    add('radio', 'label'=>'Italic', 'variable'=>style, 'value'=>'italic')\n    add('separator')\n    add('command', 'label'=>'ͤɽ', \n        'command'=>proc{showVars($menu84_demo, \n                                 ['pointSize', pointSize], \n                                 ['style', style])} )\n    invoke 1\n    invoke 7\n  }\n}\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Icons', 'menu'=>m, 'underline'=>0)\n  add('command', 'hidemargin'=>1, \n      'bitmap'=>'@'+[$demo_dir,'..',\n                      'images','pattern.xbm'].join(File::Separator),\n      'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', \n                                   'text'=>'ʤ򤷤˥塼ܤϡʸ˥ӥåȥޥåץ᡼ǹܤɽΤǤʳǤϡۤΥ˥塼ܤȤδ֤ä˰㤤櫓ǤϤޤ',\n                                   'bitmap'=>'', 'default'=>0, \n                                   'buttons'=>'Ĥ')} )\n  ['info', 'questhead', 'error'].each{|icon|\n    add('command', 'bitmap'=>icon, 'hidemargin'=>1, \n        'command'=>proc{print \"You invoked the #{icon} bitmap\\n\"})\n  }\n\n  entryconfigure(2, :columnbreak=>true)\n}\n\nTkMenu.new($menu84_frame, 'tearoff'=>false) {|m|\n  $menu84_frame.add('cascade', 'label'=>'More', 'menu'=>m, 'underline'=>0)\n  [ 'An entry','Another entry','Does nothing','Does almost nothing',\n    'Make life meaningful' ].each{|i|\n    add('command', 'label'=>i, \n        'command'=>proc{print \"You invoked \\\"#{i}\\\"\\n\"})\n  }\n\n  m.entryconfigure('Does almost nothing', \n                   'bitmap'=>'questhead', 'compound'=>'left', \n                   'command'=>proc{\n                     TkDialog.new('title'=>'Compound Menu Entry', \n                                  'message'=>'ʤ򤷤˥塼ܤϡӥåȥޥåץ᡼ʸȤƱ˰Ĥιܤɽ褦ˤΤǤʳǤϡۤΥ˥塼ܤȤδ֤ä˰㤤櫓ǤϤޤ',\n                                  'buttons'=>['λ'], 'bitmap'=>'')\n                   })\n}\n\nTkMenu.new($menu84_frame) {|m|\n  $menu84_frame.add('cascade', 'label'=>'Colors', 'menu'=>m, 'underline'=>0)\n  ['red', 'orange', 'yellow', 'green', 'blue'].each{|c|\n    add('command', 'label'=>c, 'background'=>c, \n        'command'=>proc{print \"You invoked \\\"#{c}\\\"\\n\"})\n  }\n}\n\n$menu84_demo.menu($menu84_frame)\n\nTkMenu.bind('<MenuSelect>', proc{|w|\n              begin\n                label = w.entrycget('active', 'label')\n              rescue\n                label = \"    \"\n              end\n              menustatus.value = label\n              Tk.update(true)\n            }, '%W')\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/menu8x.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# menus widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($menu8x_demo) && $menu8x_demo\n  $menu8x_demo.destroy \n  $menu8x_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$menu8x_demo = TkToplevel.new {|w|\n  title(\"Menu Demonstration (Tk8.x)\")\n  iconname(\"menu\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($menu8x_demo).pack(:fill=>:both, :expand=>true)\n\n# version check\nif $tk_version.to_f < 8.0\n\n# label \nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n    text(\"¹Ԥ褦ȤץȤ Tk8.0 ʾѤǤ뵡ǽѤƤ뤿ᡢʤ Ruby#{VERSION}/Tk#{$tk_version}#{(Tk::JAPANIZED_TK)? 'jp': ''} Ǥ˼¹ԤǤޤ󡣤äƥǥμ¹ԤߤޤΥɻȥܥ򲡤Ȥǡ¹Ԥߤ줿ץȤΥ򻲾Ȥ뤳ȤϲǽǤ\")\n}.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $menu8x_demo\n      $menu8x_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'menu8x'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\nelse ; # Tk8.x\n\nbegin\n  windowingsystem = Tk.windowingsystem()\nrescue\n  windowingsystem = \"\"\nend\n\n# label \nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n  if $tk_platform['platform'] == 'macintosh' ||\n      windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    text(\"Υɥ͡ʥ˥塼ȥɥ˥塼鹽ƤޤCommand-X ϤȡXޥɥ³ɽƤʸʤС졼ȤäܵưԤȤǤޤ˥塼桢ǸΤΤϡΥ˥塼κǽιܤ򤹤뤳ȤΩ뤳ȤǤޤ\")\n  else\n    text(\"Υɥ͡ʥ˥塼ȥɥ˥塼鹽ƤޤAlt-X ϤȡX˥塼˥饤դɽƤʸʤСܡɤλ꤬Ǥޤǥ˥塼ΥȥСǽǤ˥塼ꤵ줿ݤˤϡڡǼ¹Ԥ뤳ȤǤޤ뤤ϡ饤դʸϤ뤳ȤǤ¹ԤǤޤ˥塼Υȥ꤬졼äƤϡΥ졼Ϥ뤳Ȥǥ˥塼ꤹ뤳Ȥʤ˼¹Ԥ뤳ȤǤޤ˥塼桢ǸΤΤϡΥ˥塼κǽιܤ򤹤뤳ȤΩ뤳ȤǤޤ\")\n  end\n}.pack('side'=>'top')\n\n# ɽ\n$menu8xstatus = TkVariable.new(\"    \")\nTkFrame.new(base_frame) {|frame|\n  TkLabel.new(frame, 'textvariable'=>$menu8xstatus, 'relief'=>'sunken', \n              'bd'=>1, 'font'=>['Helvetica', '10'], 'anchor'=>'w')\\\n  .pack('side'=>'left', 'padx'=>2, 'expand'=>'yes', 'fill'=>'both')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>2)\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $menu8x_demo\n      $menu8x_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'menu8x'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# menu \nTkMenu.new($menu8x_demo, 'tearoff'=>false) {|m|\n  TkMenu.new(m, 'tearoff'=>false) {|file_menu|\n    m.add('cascade', 'label'=>'File', 'menu'=>file_menu, 'underline'=>0)\n    add('command', 'label'=>' ...', 'command'=>proc{fail 'ϡǥǤΤ\" ...\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'', 'command'=>proc{fail 'ϡǥǤΤ\"\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'¸', 'command'=>proc{fail 'ϡǥǤΤ\"¸\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'¸() ...', 'command'=>proc{fail 'ϡǥǤΤ\"¸() ...\"Ф륢Ƥޤ'})\n    add('separator')\n    add('command', 'label'=>'ץ ...', 'command'=>proc{fail 'ϡǥǤΤ\"ץ ...\"Ф륢Ƥޤ'})\n    add('command', 'label'=>'ץ ...', 'command'=>proc{fail 'ϡǥǤΤ\"ץ ...\"Ф륢Ƥޤ'})\n    add('separator')\n    add('command', 'label'=>'λ', 'command'=>proc{$menu8x_demo.destroy})\n  }\n\n  if $tk_platform['platform'] == 'macintosh' ||\n      windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    modifier = 'Command'\n  elsif $tk_platform['platform'] == 'windows'\n    modifier = 'Control'\n  else\n    modifier = 'Meta'\n  end\n\n  TkMenu.new(m, 'tearoff'=>false) {|basic_menu|\n    m.add('cascade', 'label'=>'Basic', 'menu'=>basic_menu, 'underline'=>0)\n    add('command', 'label'=>'⤷ʤĹȥ')\n    ['A','B','C','D','E','F','G'].each{|c|\n      # add('command', 'label'=>\"ʸ \\\"#{c}\\\" \", 'underline'=>4, \n      add('command', 'label'=>\"Print letter \\\"#{c}\\\" (ʸ \\\"#{c}\\\" )\", \n          'underline'=>14, 'accelerator'=>\"Meta+#{c}\", \n          'command'=>proc{print c,\"\\n\"}, 'accelerator'=>\"#{modifier}+#{c}\")\n      $menu8x_demo.bind(\"#{modifier}-#{c.downcase}\", proc{print c,\"\\n\"})\n    }\n  }\n\n  TkMenu.new(m, 'tearoff'=>false) {|cascade_menu|\n    m.add('cascade', 'label'=>'Cascades', 'menu'=>cascade_menu, 'underline'=>0)\n    add('command', 'label'=>'Print hello(ˤ)', \n        'command'=>proc{print \"Hello(ˤ)\\n\"}, \n        'accelerator'=>\"#{modifier}+H\", 'underline'=>6)\n    $menu8x_demo.bind(\"#{modifier}-h\", proc{print \"Hello(ˤ)\\n\"})\n    add('command', 'label'=>'Print goodbye(褦ʤ)', \n        'command'=>proc{print \"Goodbye(褦ʤ)\\n\"}, \n        'accelerator'=>\"#{modifier}+G\", 'underline'=>6)\n    $menu8x_demo.bind(\"#{modifier}-g\", proc{print \"Goodbye(褦ʤ)\\n\"})\n\n    TkMenu.new(m, 'tearoff'=>false) {|cascade_check|\n      cascade_menu.add('cascade', 'label'=>'Check buttons(åܥ)', \n                       'menu'=>cascade_check, 'underline'=>0)\n      oil = TkVariable.new(0)\n      add('check', 'label'=>'', 'variable'=>oil)\n      trans = TkVariable.new(0)\n      add('check', 'label'=>'ȥ󥹥ߥå', 'variable'=>trans)\n      brakes = TkVariable.new(0)\n      add('check', 'label'=>'֥졼', 'variable'=>brakes)\n      lights = TkVariable.new(0)\n      add('check', 'label'=>'饤', 'variable'=>lights)\n      add('separator')\n      add('command', 'label'=>'ߤͤɽ', \n          'command'=>proc{showVars($menu8x_demo, \n                                   ['', oil], \n                                   ['ȥ󥹥ߥå', trans], \n                                   ['֥졼', brakes], \n                                   ['饤', lights])} )\n      invoke 1\n      invoke 3\n    }\n\n    TkMenu.new(m, 'tearoff'=>false) {|cascade_radio|\n      cascade_menu.add('cascade', 'label'=>'Radio buttons(饸ܥ)', \n                       'menu'=>cascade_radio, 'underline'=>0)\n      pointSize = TkVariable.new\n      add('radio', 'label'=>'10 ݥ', 'variable'=>pointSize, 'value'=>10)\n      add('radio', 'label'=>'14 ݥ', 'variable'=>pointSize, 'value'=>14)\n      add('radio', 'label'=>'18 ݥ', 'variable'=>pointSize, 'value'=>18)\n      add('radio', 'label'=>'24 ݥ', 'variable'=>pointSize, 'value'=>24)\n      add('radio', 'label'=>'32 ݥ', 'variable'=>pointSize, 'value'=>32)\n      add('separator')\n      style = TkVariable.new\n      add('radio', 'label'=>'ޥ', 'variable'=>style, 'value'=>'roman')\n      add('radio', 'label'=>'ܡ', 'variable'=>style, 'value'=>'bold')\n      add('radio', 'label'=>'å', 'variable'=>style, 'value'=>'italic')\n      add('separator')\n      add('command', 'label'=>'ߤͤɽ', \n          'command'=>proc{showVars($menu8x_demo, \n                                   ['ݥȥ', pointSize], \n                                   ['', style])} )\n      invoke 1\n      invoke 7\n    }\n  }\n\n  TkMenu.new(m, 'tearoff'=>false) {|icon_menu|\n    m.add('cascade', 'label'=>'Icons', 'menu'=>icon_menu, 'underline'=>0)\n    add('command', \n        'bitmap'=>'@'+[$demo_dir,'..',\n                        'images','pattern.xbm'].join(File::Separator),\n        'hidemargin'=>1, \n        'command'=>proc{TkDialog.new('title'=>'Bitmap Menu Entry', \n                                     'text'=>'ʤ򤷤˥塼ιܤϥƥȤǤϤʤӥåȥޥåפɽƤޤʳǤ¾Υ˥塼ܤѤޤ',\n                                     'bitmap'=>'', 'default'=>0, \n                                     'buttons'=>'λ')} )\n    ['info', 'questhead', 'error'].each{|icon|\n      add('command', 'bitmap'=>icon, 'hidemargin'=>1, \n          'command'=>proc{print \"You invoked the #{icon} bitmap\\n\"})\n    }\n\n    entryconfigure(2, 'columnbreak'=>1)\n  }\n\n  TkMenu.new(m, 'tearoff'=>false) {|more_menu|\n    m.add('cascade', 'label'=>'More', 'menu'=>more_menu, 'underline'=>0)\n    [ 'ȥ','̤Υȥ','⤷ʤ','ۤȤɲ⤷ʤ',\n      'յΤ' ].each{|i|\n      add('command', 'label'=>i, \n          'command'=>proc{print \"You invoked \\\"#{i}\\\"\\n\"})\n    }\n  }\n\n  TkMenu.new(m) {|colors_menu|\n    m.add('cascade', 'label'=>'Colors', 'menu'=>colors_menu, 'underline'=>1)\n    ['red', 'orange', 'yellow', 'green', 'blue'].each{|c|\n      add('command', 'label'=>c, 'background'=>c, \n          'command'=>proc{print \"You invoked \\\"#{c}\\\"\\n\"})\n    }\n  }\n\n  $menu8x_demo.configure('menu'=>m)\n}\n\nTkMenu.bind('<MenuSelect>', \n            proc{|w| \n              begin\n                label = w.entrycget('active', 'label')\n              rescue\n                label = '    '\n              end\n              $menu8xstatus.value = label\n              Tk.update('idletasks')\n            }, '%W')\n\nend ; # Tk 8.x\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/menubu.rb",
    "content": "# -*- coding: euc-jp -*-\nrequire \"tkcanvas\"\n\ndef optionMenu(menubutton, varName, firstValue, *rest)\n  varName.value = firstValue\n  configoptions = {'textvariable'=>varName,'indicatoron'=>'on',\n    'relief'=>'raised','borderwidth'=>2,'highlightthickness'=>2,\n    'anchor'=>'c','direction'=>'flush'}\n  configoptions.each {|key, value|\n    menubutton.configure(key, value)\n  }\n  menu = TkMenu.new(menubutton) {\n    tearoff 'off'\n    add 'radio', 'label'=>firstValue, 'variable'=>varName\n  }\n  menubutton.menu(menu)\n  for i in rest\n    menu.add 'radio', 'label'=>i, 'variable'=>varName\n  end\n  \n  return menu\nend\n\nif defined?($menubu_demo) && $menubu_demo\n  $menubu_demo.destroy\n  $menubu_demo = nil\nend\n\n$menubu_demo = TkToplevel.new {|w|\n  title(\"Menu Button Demonstration\")\n  iconname(\"menubutton\")\n}\n\npositionWindow($menubu_demo)\n\nbase_frame = TkFrame.new($menubu_demo).pack(:fill=>:both, :expand=>true)\n\n# version check\nif $tk_version.to_f < 8.0\n\n# label \nTkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') {\n    text(\"¹Ԥ褦ȤץȤ Tk8.0 ʾѤǤ뵡ǽѤƤ뤿ᡢʤ Ruby#{VERSION}/Tk#{$tk_version}#{(Tk::JAPANIZED_TK)? 'jp': ''} Ǥ˼¹ԤǤޤ󡣤äƥǥμ¹ԤߤޤΥɻȥܥ򲡤Ȥǡ¹Ԥߤ줿ץȤΥ򻲾Ȥ뤳ȤϲǽǤ\")\n}.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $menubu_demo\n      $menubu_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'menubu'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\nelse ; # Tk8.x\n\nbody = TkFrame.new(base_frame)\nbody.pack('expand'=>'yes', 'fill'=>'both')\n\nbelow = TkMenubutton.new(body) {\n  text \"Below\"\n  underline 0\n  direction 'below'\n  relief 'raised'\n}\nbelowMenu = TkMenu.new(below) {\n  tearoff 0\n  add 'command', 'label'=>\"Below menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Below menu.\\\"\"}\n  add 'command', 'label'=>\"Below menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Below menu.\\\"\"}\n}\nbelow.menu(belowMenu)\nbelow.grid('row'=>0, 'column'=>1, 'sticky'=>'n')\n\nbelow = TkMenubutton.new(body) {\n  text \"Below\"\n  underline 0\n  direction 'below'\n  relief 'raised'\n}\nbelowMenu = TkMenu.new(below) {\n  tearoff 0\n  add 'command', 'label'=>\"Below menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Below menu.\\\"\"}\n  add 'command', 'label'=>\"Below menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Below menu.\\\"\"}\n}\nbelow.menu(belowMenu)\nbelow.grid('row'=>0, 'column'=>1, 'sticky'=>'n')\n\nbelow = TkMenubutton.new(body) {\n  text \"Below\"\n  underline 0\n  direction 'below'\n  relief 'raised'\n}\nbelowMenu = TkMenu.new(below) {\n  tearoff 0\n  add 'command', 'label'=>\"Below menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Below menu.\\\"\"}\n  add 'command', 'label'=>\"Below menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Below menu.\\\"\"}\n}\nbelow.menu(belowMenu)\nbelow.grid('row'=>0, 'column'=>1, 'sticky'=>'n')\n\nright = TkMenubutton.new(body) {\n  text \"Right\"\n  underline 0\n  direction 'right'\n  relief 'raised'\n}\nrightMenu = TkMenu.new(right) {\n  tearoff 0\n  add 'command', 'label'=>\"Right menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Left menu.\\\"\"}\n  add 'command', 'label'=>\"Right menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Right menu.\\\"\"}\n}\nright.menu(rightMenu)\nright.grid('row'=>1, 'column'=>0, 'sticky'=>'w')\n\nleft = TkMenubutton.new(body) {\n  text \"Left\"\n  underline 0\n  direction 'left'\n  relief 'raised'\n}\nleftMenu = TkMenu.new(left) {\n  tearoff 0\n  add 'command', 'label'=>\"Left menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Left menu.\\\"\"}\n  add 'command', 'label'=>\"Left menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Left menu.\\\"\"}\n}\nleft.menu(leftMenu)\nleft.grid('row'=>1, 'column'=>2, 'sticky'=>'e')\n\ncenter = TkFrame.new(body) {\n  grid('row'=>1, 'column'=>1, 'sticky'=>'news')\n}\n\nabove = TkMenubutton.new(body) {\n  text \"Above\"\n  underline 0\n  direction 'above'\n  relief 'raised'\n}\naboveMenu = TkMenu.new(above) {\n  tearoff 0\n  add 'command', 'label'=>\"Above menu: first item\", 'command'=>proc {puts \"\\\"You have selected the first item from the Above menu.\\\"\"}\n  add 'command', 'label'=>\"Above menu: second item\", 'command'=>proc {puts \"\\\"You have selected the second item from the Above menu.\\\"\"}\n}\nabove.menu(aboveMenu)\nabove.grid('row'=>2, 'column'=>1, 'sticky'=>'s')\n\ncenter = TkFrame.new(body) {\n  grid('row'=>1, 'column'=>1, 'sticky'=>'news')\n}\n\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc {\n      tmppath = $menubu_demo\n      $menubu_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc { showCode 'menubu' }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'expand'=>'yes', 'fill'=>'x', 'pady'=>'2m')\n\nmsg = TkLabel.new(center) {\n#  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ϥ˥塼ܥΥǥǤ\\\"Below\\\"Υܥ\\\n˥˥塼Ф\\\"Right\\\"Υܥϱ˥˥塼Фơ\\\nġĤȤʤޤʸϤβˤ2ĤΥץ˥塼ޤ\\\n1Ĥ̤Υ˥塼ǡ⤦1Ĥ16ΥѥåȤǤ\"\n}\nmsg.pack('side'=>'top', 'padx'=>25, 'pady'=>25)\n\nTkFrame.new(center) {|f|\n  menubuttonoptions = TkVariable.new\n  mbutton = TkMenubutton.new(f)\n  options = optionMenu(mbutton, menubuttonoptions, \n                       'one', 'two', 'three')\n  mbutton.pack('side'=>'left', 'padx'=>25, 'pady'=>25)\n  paletteColor = TkVariable.new\n  colors = ['Black','red4','DarkGreen','NavyBlue', 'gray75',\n    'Red','Green','Blue','gray50','Yellow','Cyan','Magenta',\n    'White','Brown','DarkSeaGreen','DarkViolet']\n  colorMenuButton = TkMenubutton.new(f)\n  m = optionMenu(colorMenuButton, paletteColor, *colors)\n  begin\n    windowingsystem = Tk.windowingsystem()\n  rescue\n    windowingsystem = \"\"\n  end\n  if windowingsystem == \"classic\" || windowingsystem == \"aqua\"\n    topBorderColor = 'Black'\n    bottomBorderColor = 'Black'\n  else\n    topBorderColor = 'gray50'\n    bottomBorderColor = 'gray75'\n  end\n  for i in 0..15\n    image = TkPhotoImage.new('height'=>16, 'width'=>16)\n    image.put(topBorderColor, 0, 0, 16, 1)\n    image.put(topBorderColor, 0, 1, 1, 16)\n    image.put(bottomBorderColor, 0, 15, 16, 16)\n    image.put(bottomBorderColor, 15, 1, 16, 16)\n    image.put(colors[i], 1, 1, 15, 15)\n\n    selectimage = TkPhotoImage.new('height'=>16, 'width'=>16)\n    selectimage.put('Black', 0, 0, 16, 2)\n    selectimage.put('Black', 0, 2, 2, 16)\n    selectimage.put('Black', 2, 14, 16, 16)\n    selectimage.put('Black', 14, 2, 16, 14)\n    selectimage.put(colors[i], 2, 2, 14, 14)\n\n    m.entryconfigure(i, 'image'=>image, 'selectimage'=>selectimage, 'hidemargin'=>'on')\n  end\n  m.configure('tearoff', 'on')\n  for c in ['Black', 'gray75', 'gray50', 'White']\n    m.entryconfigure(c, 'columnbreak'=>1)\n  end\n  colorMenuButton.pack('side'=>'left', 'padx'=>25, 'pady'=>25)\n  pack 'padx'=>25, 'pady'=>25\n}\n\nend ; # Tk8.x\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/msgbox.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# message boxes widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($msgbox_demo) && $msgbox_demo\n  $msgbox_demo.destroy \n  $msgbox_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$msgbox_demo = TkToplevel.new {|w|\n  title(\"Message Box Demonstration\")\n  iconname(\"messagebox\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($msgbox_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left',\n            'text'=>\"ޤɽ륢ȥåܥåμǲθ\\\"åܥå\\\"ܥ򲡤ȡꤷåܥåɽޤ\").pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $msgbox_demo\n      $msgbox_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'msgbox'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'åܥå'\n    command proc{showMessageBox $msgbox_demo}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \n$msgbox_leftframe  = TkFrame.new(base_frame)\n$msgbox_rightframe = TkFrame.new(base_frame)\n$msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n$msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n\nTkLabel.new($msgbox_leftframe, 'text'=>'').pack('side'=>'top')\nTkFrame.new($msgbox_leftframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxIcon = TkVariable.new('info')\n['error', 'info', 'question', 'warning'].each {|icon|\n  TkRadioButton.new($msgbox_leftframe, 'text'=>icon, 'variable'=>$msgboxIcon, \n                    'relief'=>'flat', 'value'=>icon, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\nTkLabel.new($msgbox_rightframe, 'text'=>'').pack('side'=>'top')\nTkFrame.new($msgbox_rightframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxType = TkVariable.new('ok')\n['abortretryignore', 'ok', 'okcancel', \n  'retrycancel', 'yesno', 'yesnocancel'].each {|type|\n  TkRadioButton.new($msgbox_rightframe, 'text'=>type, 'variable'=>$msgboxType, \n                    'relief'=>'flat', 'value'=>type, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\ndef showMessageBox(w)\n  button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, \n                         'title'=>'Message', 'parent'=>w,\n                         'message'=>\"\\\"#{$msgboxType.value}\\\"ȤΥåܥåǡ\\\"#{$msgboxIcon.value}\\\"ΥɽƤޤ\")\n\n  Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, \n                'message'=>\"ʤ \\\"#{button}\\\" 򲡤ޤ͡\")\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/msgbox2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# message boxes widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($msgbox2_demo) && $msgbox2_demo\n  $msgbox2_demo.destroy \n  $msgbox2_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$msgbox2_demo = TkToplevel.new {|w|\n  title(\"Message Box Demonstration\")\n  iconname(\"messagebox\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($msgbox2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left',\n            'text'=>\"ޤɽ륢ȥåܥåμǲθ\\\"åܥå\\\"ܥ򲡤ȡꤵ줿ǡåȾܺ٥ƥȤȤäåܥåɽޤ\").pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $msgbox2_demo\n      $msgbox2_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'msgbox2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'åܥå'\n    command proc{showMessageBox $msgbox2_demo}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \n$msgbox_leftframe  = TkFrame.new(base_frame)\n$msgbox_rightframe = TkFrame.new(base_frame)\n$msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n$msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', \n                        'pady'=>'.5c', 'padx'=>'.5c')\n\nTkLabel.new($msgbox_leftframe, 'text'=>'').pack('side'=>'top')\nTkFrame.new($msgbox_leftframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxIcon = TkVariable.new('info')\n['error', 'info', 'question', 'warning'].each {|icon|\n  TkRadioButton.new($msgbox_leftframe, 'text'=>icon, 'variable'=>$msgboxIcon, \n                    'relief'=>'flat', 'value'=>icon, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\nTkLabel.new($msgbox_rightframe, 'text'=>'').pack('side'=>'top')\nTkFrame.new($msgbox_rightframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\\\n.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no')\n\n$msgboxType = TkVariable.new('ok')\n['abortretryignore', 'ok', 'okcancel', \n  'retrycancel', 'yesno', 'yesnocancel'].each {|type|\n  TkRadioButton.new($msgbox_rightframe, 'text'=>type, 'variable'=>$msgboxType, \n                    'relief'=>'flat', 'value'=>type, 'width'=>16, \n                    'anchor'=>'w').pack('side'=>'top', 'pady'=>2, \n                                        'anchor'=>'w', 'fill'=>'x')\n}\n\ndef showMessageBox(w)\n  button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, \n                         'title'=>'Message', 'parent'=>w,\n                         'message'=>\"\\\"#{$msgboxType.value}\\\"פΥåܥå\", \n                         'detail'=>\"\\\"#{$msgboxType.value}\\\"ȤΥåܥåǡ\\\"#{$msgboxIcon.value}\\\"ΥɽƤޤΥܥΤ줫򤷤ƥåƤ\")\n\n  Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, \n                'message'=>\"ʤ \\\"#{button}\\\" 򲡤ޤ͡\")\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/paned1.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# paned1.rb\n#\n# This demonstration script creates a toplevel window containing\n# a paned window that separates two windows horizontally.\n#\n# based on \"Id: paned1.tcl,v 1.1 2002/02/22 14:07:01 dkf Exp\"\n\nif defined?($paned1_demo) && $paned1_demo\n  $paned1_demo.destroy \n  $paned1_demo = nil\nend\n\n$paned1_demo = TkToplevel.new {|w|\n  title(\"Horizontal Paned Window Demonstration\")\n  iconname(\"paned1\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($paned1_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nοդ줿ĤΥɥδ֤λڤȤϡĤΰ򤽤줾ΥɥΤʬ䤹뤿ΤΤǤܥǻڤȡʬ䥵ѹǤϺɽϤʤ줺ꤵȤɽޤޥˤڤɿ路ƥѹɽʤ褦ˤϡޥܥȤäƤ\n⤷ʤȤäƤ Ruby ˥󥯤Ƥ Tk 饤֥꤬ panedwindow Ƥʤ\n硢ΥǥϤޤưʤϤǤξˤ panedwindow Ƥ褦\n꿷С Tk Ȥ߹碌ƻ\n褦ˤƤ\nEOL\n\n# The bottom buttons\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $paned1_demo.destroy\n                 $paned1_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'paned1'\n               }).pack(:side=>:left, :expand=>true)\n}\n\nTkPanedwindow.new(base_frame, :orient=>:horizontal){|f|\n  add(Tk::Label.new(f, :text=>\"This is the\\nleft side\", :bg=>'yellow'), \n      Tk::Label.new(f, :text=>\"This is the\\nright side\", :bg=>'cyan'))\n\n  pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m')\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/paned2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# paned2.rb --\n#\n# This demonstration script creates a toplevel window containing\n# a paned window that separates two windows vertically.\n#\n# based on \"Id: paned2.tcl,v 1.1 2002/02/22 14:07:01 dkf Exp\"\n\nif defined?($paned2_demo) && $paned2_demo\n  $paned2_demo.destroy \n  $paned2_demo = nil\nend\n\n$paned2_demo = TkToplevel.new {|w|\n  title(\"Vertical Paned Window Demonstration\")\n  iconname(\"paned2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($paned2_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nΥСդΥåȤ֤줿ĤΥɥδ֤λڤȤϡĤΰ򤽤줾ΥɥΤʬ䤹뤿ΤΤǤܥǻڤȡʬ䥵ѹǤϺɽϤʤ줺ꤵȤɽޤޥˤڤɿ路ƥѹɽʤ褦ˤϡޥܥȤäƤ\n⤷ʤȤäƤ Ruby ˥󥯤Ƥ Tk 饤֥꤬ panedwindow Ƥʤ\n硢ΥǥϤޤưʤϤǤξˤ panedwindow Ƥ褦\n꿷С Tk Ȥ߹碌ƻ\n褦ˤƤ\nEOL\n\n# The bottom buttons\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $paned2_demo.destroy\n                 $paned2_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'paned2'\n               }).pack(:side=>:left, :expand=>true)\n}\n\npaneList = TkVariable.new  # define as normal variable (not array)\npaneList.value = [         # ruby's array --> tcl's list\n    'Ruby/Tk ΥåȰ',\n    'TkButton', \n    'TkCanvas', \n    'TkCheckbutton', \n    'TkEntry', \n    'TkFrame', \n    'TkLabel', \n    'TkLabelframe', \n    'TkListbox', \n    'TkMenu', \n    'TkMenubutton', \n    'TkMessage', \n    'TkPanedwindow', \n    'TkRadiobutton', \n    'TkScale', \n    'TkScrollbar', \n    'TkSpinbox', \n    'TkText', \n    'TkToplevel'\n]\n\n# Create the pane itself\nTkPanedwindow.new(base_frame, :orient=>:vertical){|f|\n  pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m')\n\n  add(TkFrame.new(f){|paned2_top|\n        TkListbox.new(paned2_top, :listvariable=>paneList) {\n          # Invert the first item to highlight it\n          itemconfigure(0, :background=>self.cget(:foreground), \n                           :foreground=>self.cget(:background) )\n          yscrollbar(TkScrollbar.new(paned2_top).pack(:side=>:right, \n                                                      :fill=>:y))\n          pack(:fill=>:both, :expand=>true)\n        }\n      }, \n\n      TkFrame.new(f, :height=>120) {|paned2_bottom|\n        # The bottom window is a text widget with scrollbar\n        paned2_xscr = TkScrollbar.new(paned2_bottom)\n        paned2_yscr = TkScrollbar.new(paned2_bottom)\n        paned2_text = TkText.new(paned2_bottom, :width=>30, :wrap=>:non) {\n          insert('1.0', '֤ƤΤϡ' + \n                        '̤ΥƥȥåȤǤ')\n          xscrollbar(paned2_xscr)\n          yscrollbar(paned2_yscr)\n        }\n        Tk.grid(paned2_text, paned2_yscr, :sticky=>'nsew')\n        Tk.grid(paned2_xscr, :sticky=>'nsew')\n        TkGrid.columnconfigure(paned2_bottom, 0, :weight=>1)\n        TkGrid.rowconfigure(paned2_bottom, 0, :weight=>1)\n      } )\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/pendulum.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# This demonstration illustrates how Tcl/Tk can be used to construct\n# simulations of physical systems.\n# (called by 'widget')\n#\n# based on Tcl/Tk8.5a2 widget demos\n\n# destroy toplevel widget for this demo script\nif defined?($pendulum_demo) && $pendulum_demo\n  $pendulum_demo.destroy \n  $pendulum_demo = nil\nend\n\n# create toplevel widget\n$pendulum_demo = TkToplevel.new {|w|\n  title(\"Pendulum Animation Demonstration\")\n  iconname(\"pendulum\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($pendulum_demo).pack(:fill=>:both, :expand=>true)\n\n# create label\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text 'ΥǥϡʪϤΥߥ졼˴ؤ褦ʥ˥᡼¹Ԥ뤿 Ruby/Tk ɤΤ褦Ѥ뤳ȤǤ뤫򼨤Ƥޤ¦ΥХñʿҤǤʪϼΤΥեɽǤΤФ¦ΥХϷϤΰ֤Υաʳ®٤ȳ٤ȤץåȤΡˤˤʤäƤޤ¦ΥХǥåӥɥåԤäƿҤνŤΰ֤ѤƤߤƤ'\n}\nmsg.pack('side'=>'top')\n\n# create frame\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $pendulum_demo\n      $pendulum_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'pendulum'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# animated wave\nclass PendulumAnimationDemo\n  def initialize(frame)\n    # Create some structural widgets\n    @pane = TkPanedWindow.new(frame, :orient=>:horizontal).pack(:fill=>:both, :expand=>true)\n#    @pane.add(@lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation'))\n#    @pane.add(@lf2 = TkLabelFrame.new(@pane, :text=>'Phase Space'))\n    @lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation')\n    @lf2 = TkLabelFrame.new(@pane, :text=>'Phase Space')\n\n    # Create the canvas containing the graphical representation of the\n    # simulated system.\n    @c = TkCanvas.new(@lf1, :width=>320, :height=>200, :background=>'white', \n                      :borderwidth=>2, :relief=>:sunken)\n    TkcText.new(@c, 5, 5, :anchor=>:nw, \n                :text=>'Click to Adjust Bob Start Position')\n    # Coordinates of these items don't matter; they will be set properly below\n    @plate = TkcLine.new(@c, 0, 25, 320, 25, :width=>2, :fill=>'grey50')\n    @rod = TkcLine.new(@c, 1, 1, 1, 1, :width=>3, :fill=>'black')\n    @bob = TkcOval.new(@c, 1, 1, 2, 2, \n                       :width=>3, :fill=>'yellow', :outline=>'black')\n    TkcOval.new(@c, 155, 20, 165, 30, :fill=>'grey50', :outline=>'')\n\n    # pack\n    @c.pack(:fill=>:both, :expand=>true)\n\n    # Create the canvas containing the phase space graph; this consists of\n    # a line that gets gradually paler as it ages, which is an extremely\n    # effective visual trick.\n    @k = TkCanvas.new(@lf2, :width=>320, :height=>200, :background=>'white', \n                      :borderwidth=>2, :relief=>:sunken)\n    @y_axis = TkcLine.new(@k, 160, 200, 160, 0, :fill=>'grey75', :arrow=>:last)\n    @x_axis = TkcLine.new(@k, 0, 100, 320, 100, :fill=>'grey75', :arrow=>:last)\n\n    @graph = {}\n    90.step(0, -10){|i|\n      # Coordinates of these items don't matter; \n      # they will be set properly below\n      @graph[i] = TkcLine.new(@k, 0, 0, 1, 1, :smooth=>true, :fill=>\"grey#{i}\")\n    }\n\n    # labels\n    @label_theta = TkcText.new(@k, 0, 0, :anchor=>:ne, \n                               :text=>'q', :font=>'Symbol 8')\n    @label_dtheta = TkcText.new(@k, 0, 0, :anchor=>:ne, \n                               :text=>'dq', :font=>'Symbol 8')\n\n    # pack\n    @k.pack(:fill=>:both, :expand=>true)\n\n    # Initialize some variables\n    @points = []\n    @theta = 45.0\n    @dTheta = 0.0\n    @length = 150\n\n    # animation loop\n    @timer = TkTimer.new(15){ repeat }\n\n    # binding\n    @c.bindtags_unshift(btag = TkBindTag.new)\n    btag.bind('Destroy'){ @timer.stop }\n    btag.bind('1', proc{|x, y| @timer.stop; showPendulum(x.to_i, y.to_i)}, \n              '%x %y')\n    btag.bind('B1-Motion', proc{|x, y| showPendulum(x.to_i, y.to_i)}, '%x %y')\n    btag.bind('ButtonRelease-1', \n              proc{|x, y| showPendulum(x.to_i, y.to_i); @timer.start }, \n              '%x %y')\n\n    btag.bind('Configure', proc{|w| @plate.coords(0, 25, w.to_i, 25)}, '%w')\n\n    @k.bind('Configure', proc{|h, w| \n              h = h.to_i\n              w = w.to_i\n              @psh = h/2; \n              @psw = w/2\n              @x_axis.coords(2, @psh, w-2, @psh)\n              @y_axis.coords(@psw, h-2, @psw, 2)\n              @label_theta.coords(@psw-4, 6)\n              @label_dtheta.coords(w-6, @psh+4)\n            }, '%h %w')\n\n    # add\n    Tk.update\n    @pane.add(@lf1)\n    @pane.add(@lf2)\n\n    # init display\n    showPendulum\n\n    # animation start\n    @timer.start(500)\n  end\n\n  # This procedure makes the pendulum appear at the correct place on the\n  # canvas. If the additional arguments x, y are passed instead of computing \n  # the position of the pendulum from the length of the pendulum rod and its \n  # angle, the length and angle are computed in reverse from the given \n  # location (which is taken to be the centre of the pendulum bob.)\n  def showPendulum(x=nil, y=nil)\n    if x && y && (x != 160 || y != 25)\n      @dTheta = 0.0\n      x2 = x - 160\n      y2 = y - 25\n      @length = Math.hypot(x2, y2)\n      @theta = Math.atan2(x2,y2)*180/Math::PI\n    else\n      angle = @theta*Math::PI/180\n      x = 160 + @length*Math.sin(angle)\n      y = 25 + @length*Math.cos(angle)\n    end\n\n    @rod.coords(160, 25, x, y)\n    @bob.coords(x-15, y-15, x+15, y+15)\n  end\n\n  # Update the phase-space graph according to the current angle and the\n  # rate at which the angle is changing (the first derivative with\n  # respect to time.)\n  def showPhase\n    unless @psw && @psh\n      @psw = @k.width/2\n      @psh = @k.height/2\n    end\n    @points << @theta + @psw << -20*@dTheta + @psh\n    if @points.length > 100\n      @points = @points[-100..-1]\n    end\n    (0...100).step(10){|i|\n      first = - i\n      last = 11 - i\n      last = -1 if last >= 0\n      next if first > last\n      lst = @points[first..last]\n      @graph[i].coords(lst) if lst && lst.length >= 4\n    }\n  end\n\n  # This procedure is the \"business\" part of the simulation that does\n  # simple numerical integration of the formula for a simple rotational\n  # pendulum.\n  def recomputeAngle\n    scaling = 3000.0/@length/@length\n\n    # To estimate the integration accurately, we really need to\n    # compute the end-point of our time-step.  But to do *that*, we\n    # need to estimate the integration accurately!  So we try this\n    # technique, which is inaccurate, but better than doing it in a\n    # single step.  What we really want is bound up in the\n    # differential equation:\n    #       ..             - sin theta\n    #      theta + theta = -----------\n    #                         length\n    # But my math skills are not good enough to solve this!\n\n    # first estimate\n    firstDDTheta = -Math.sin(@theta * Math::PI/180) * scaling\n    midDTheta = @dTheta + firstDDTheta\n    midTheta = @theta + (@dTheta + midDTheta)/2\n    # second estimate\n    midDDTheta = -Math.sin(midTheta * Math::PI/180) * scaling\n    midDTheta = @dTheta + (firstDDTheta + midDDTheta)/2\n    midTheta = @theta + (@dTheta + midDTheta)/2\n    # Now we do a double-estimate approach for getting the final value\n    # first estimate\n    midDDTheta = -Math.sin(midTheta * Math::PI/180) * scaling\n    lastDTheta = midDTheta + midDDTheta\n    lastTheta = midTheta + (midDTheta+ lastDTheta)/2\n    # second estimate\n    lastDDTheta = -Math.sin(lastTheta * Math::PI/180) * scaling\n    lastDTheta = midDTheta + (midDDTheta + lastDDTheta)/2\n    lastTheta = midTheta + (midDTheta + lastDTheta)/2\n    # Now put the values back in our globals\n    @dTheta = lastDTheta\n    @theta = lastTheta\n  end\n\n  # This method ties together the simulation engine and the graphical\n  # display code that visualizes it.\n  def repeat\n    # Simulate\n    recomputeAngle\n\n    # Update the display\n    showPendulum\n    showPhase\n  end\nend\n\n# Start the animation processing\nPendulumAnimationDemo.new(base_frame)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/plot.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# 2-D plot widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($plot_demo) && $plot_demo\n  $plot_demo.destroy \n  $plot_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$plot_demo = TkToplevel.new {|w|\n  title(\"Plot Demonstration\")\n  iconname(\"Plot\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($plot_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', \n            'text'=>\"Υɥϴñ2ΥץåȤޤХ widgetǤɽ줿ޥܥ1ǥɥåƥǡ򤤤뤳ȤǤޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$plot_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $plot_demo\n      $plot_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'plot'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$plot_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# font \n  if $tk_version =~ /^4.*/\n    plotFont = '-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'\n  else\n    font = 'Helvetica 18'\n  end\n\n# canvas \n$plot_canvas = TkCanvas.new(base_frame,'relief'=>'raised','width'=>450,'height'=>300)\n$plot_canvas.pack('side'=>'top', 'fill'=>'x')\n\n# plot \nTkcLine.new($plot_canvas, 100, 250, 400, 250, 'width'=>2)\nTkcLine.new($plot_canvas, 100, 250, 100,  50, 'width'=>2)\nTkcText.new($plot_canvas, 225, 20, \n            'text'=>\"ñʥץå\", 'font'=>plotFont, 'fill'=>'brown')\n\n(0..10).each {|i|\n  x = 100 + (i * 30)\n  TkcLine.new($plot_canvas, x, 250, x, 245, 'width'=>2)\n  TkcText.new($plot_canvas, x, 254, \n              'text'=>10*i, 'font'=>plotFont, 'anchor'=>'n')\n}\n(0..5).each {|i|\n  y = 250 - (i * 40)\n  TkcLine.new($plot_canvas, 100, y, 105, y, 'width'=>2)\n  TkcText.new($plot_canvas, 96, y, \n              'text'=>\"#{i*50}.0\", 'font'=>plotFont, 'anchor'=>'e')\n}\n\nfor xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]\n  x = 100 + (3*xx)\n  y = 250 - (4*yy)/5\n  item = TkcOval.new($plot_canvas, x-6, y-6, x+6, y+6, \n                     'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')\n  item.addtag 'point'\nend\n\n$plot_canvas.itembind('point', 'Any-Enter', \n                      proc{$plot_canvas.itemconfigure 'current','fill','red'})\n$plot_canvas.itembind('point', 'Any-Leave', \n                      proc{$plot_canvas.itemconfigure 'current','fill','SkyBlue2'})\n$plot_canvas.itembind('point', '1', \n                      proc{|x,y| plotDown $plot_canvas,x,y}, \"%x %y\")\n$plot_canvas.itembind('point', 'ButtonRelease-1', \n                      proc{$plot_canvas.dtag 'selected'})\n$plot_canvas.bind('B1-Motion', \n                  proc{|x,y| plotMove $plot_canvas,x,y}, \"%x %y\")\n\n$plot = {'lastX'=>0, 'lastY'=>0}\n\n# plotDown --\n# This method is invoked when the mouse is pressed over one of the \n# data points.  It sets up state to allow the point to be dragged.\n#\n# Arguments:\n# w -           The canvas window.\n# x, y -        The coordinates of the mouse press.\n\ndef plotDown (w, x, y)\n  w.dtag 'selected'\n  w.addtag_withtag 'selected', 'current'\n  w.raise 'current'\n  $plot['lastX'] = x\n  $plot['lastY'] = y\nend\n\n# plotMove --\n# This method is invoked during mouse motion events.  It drags the\n# current item.\n#\n# Arguments:\n# w -           The canvas window.\n# x, y -        The coordinates of the mouse.\n\ndef plotMove (w, x, y)\n  w.move 'selected', x - $plot['lastX'], y - $plot['lastY']\n  $plot['lastX'] = x\n  $plot['lastY'] = y\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/puzzle.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# widet demo 'puzzle' (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($puzzle_demo) && $puzzle_demo\n  $puzzle_demo.destroy \n  $puzzle_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$puzzle_demo = TkToplevel.new {|w|\n  title(\"15-Puzzle Demonstration\")\n  iconname(\"15-Puzzle\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($puzzle_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"15-ѥϥܥ򽸤ƤǤƤޤƤ٤Υԡ򥯥åȡΥԡζƤ˥饤ɤޤ³ԡον˾夫鲼鱦¤֤褦ˤƤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $puzzle_demo\n      $puzzle_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'puzzle'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \n#\n# Special trick: scrollbar widget Ƥ trough color Ѥ뤳Ȥ\n#                ʬΤΰſ򤷡ꤹ \n#\nbegin\n  if Tk.windowingsystem() == 'aqua'\n    frameWidth  = 168\n    frameHeight = 168\n  elsif Tk.default_widget_set == :Ttk\n    frameWidth  = 148\n    frameHeight = 124\n  else\n    frameWidth  = 120\n    frameHeight = 120\n  end\nrescue\n  frameWidth  = 120\n  frameHeight = 120\nend\n\n# depend_on_button_width = true\ndepend_on_button_width = false\n \ns = TkScrollbar.new(base_frame)\nbase = TkFrame.new(base_frame) {\n  width  frameWidth\n  height frameHeight\n  borderwidth 2\n  relief 'sunken'\n  bg s['troughcolor']\n}\ns.destroy\nbase.pack('side'=>'top', 'padx'=>'1c', 'pady'=>'1c')\n\n# proc ΥפĤ뤿ᡤproc ᥽åɤѰ\n# ƤͤС롼ͤѲ num αƶ\n# puzzleSwitch  2 ѲƤޤ̤ˤϤʤʤ\ndef def_puzzleswitch_proc(w, num)\n  proc{puzzleSwitch w, num}\nend\n\n$xpos = {}\n$ypos = {}\norder = [3,1,6,2,5,7,15,13,4,11,8,9,14,10,12]\n(0..14).each{|i|\n  num = order[i]\n  $xpos[num] = (i % 4) * 0.25\n  $ypos[num] = (i / 4) * 0.25\n  TkButton.new(base) {|w|\n    relief 'raised'\n    text num\n    highlightthickness 0\n    command def_puzzleswitch_proc(w, num)\n    if depend_on_button_width && (w.winfo_reqwidth * 4 > base.width)\n      base.width = w.winfo_reqwidth * 4\n    end\n  }.place('relx'=>$xpos[num], 'rely'=>$ypos[num], \n          'relwidth'=>0.25, 'relheight'=>0.25)\n}\n$xpos['space'] = 0.75\n$ypos['space'] = 0.75\n\n############\ndef puzzleSwitch(w, num)\n  if ( ($ypos[num] >= ($ypos['space'] - 0.01))     \\\n      && ($ypos[num] <= ($ypos['space'] + 0.01))   \\\n      && ($xpos[num] >= ($xpos['space'] - 0.26))   \\\n      && ($xpos[num] <= ($xpos['space'] + 0.26)))  \\\n    || (($xpos[num] >= ($xpos['space'] - 0.01))    \\\n        && ($xpos[num] <= ($xpos['space'] + 0.01)) \\\n        && ($ypos[num] >= ($ypos['space'] - 0.26)) \\\n        && ($ypos[num] <= ($ypos['space'] + 0.26)))\n    tmp = $xpos['space']\n    $xpos['space'] = $xpos[num]\n    $xpos[num] = tmp\n    tmp = $ypos['space']\n    $ypos['space'] = $ypos[num]\n    $ypos[num] = tmp\n    w.place('relx'=>$xpos[num], 'rely'=>$ypos[num])\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/radio.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# radiobutton widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($radio_demo) && $radio_demo\n  $radio_demo.destroy \n  $radio_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$radio_demo = TkToplevel.new {|w|\n  title(\"Radiobutton Demonstration\")\n  iconname(\"radio\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($radio_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤ2ĤΥ饸ܥ󥰥롼פɽƤޤܥ򥯥åȡΥܥΥ롼פ򤵤ޤƥ롼פФƤΥ롼פΤɤΥܥ򤵤Ƥ뤫򼨤ѿƤƤޤߤѿͤ򸫤ˤϡѿȡץܥ򥯥åƤ\"\n}\nmsg.pack('side'=>'top')\n\n# ѿ\nsize = TkVariable.new\ncolor = TkVariable.new\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $radio_demo\n      $radio_demo = nil\n      $showVarsWin[tmppath.path] = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'radio'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ѿ'\n    command proc{\n      showVars(base_frame, ['size', size], ['color', color])\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nf_left = TkFrame.new(base_frame)\nf_right = TkFrame.new(base_frame)\nf_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\nf_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\n\n# radiobutton \n[10, 12, 18, 24].each {|sz|\n  TkRadioButton.new(f_left) {\n    text \"ݥȥ #{sz}\"\n    variable size\n    relief 'flat'\n    value sz\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')\n}\n\n['', '', '', '', '', ''].each {|col|\n  TkRadioButton.new(f_right) {\n    text col\n    variable color\n    relief 'flat'\n    value col.downcase\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')\n}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/radio2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# radio2.rb\n#\n# This demonstration script creates a toplevel window containing\n# several radiobutton widgets.\n#\n# radiobutton widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($radio2_demo) && $radio2_demo\n  $radio2_demo.destroy \n  $radio2_demo = nil\nend\n\n# demo toplevel widget\n$radio2_demo = TkToplevel.new {|w|\n  title(\"Radiobutton Demonstration 2\")\n  iconname(\"radio2\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($radio2_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text \"ˤ3ĤΥ饸ܥ󥰥롼פɽƤޤܥ򥯥åȡΥܥΥ롼פ򤵤ޤƥ롼פФƤΥ롼פΤɤΥܥ򤵤Ƥ뤫򼨤ѿƤƤޤߤѿͤ򸫤ˤϡѿȡץܥ򥯥åƤ\"\n}\nmsg.pack('side'=>'top')\n\n# \nsize = TkVariable.new\ncolor = TkVariable.new\nalign = TkVariable.new\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $radio2_demo\n      $radio2_demo = nil\n      $showVarsWin[tmppath.path] = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'radio2'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ѿ'\n    command proc{\n      showVars(base_frame, \n               ['size', size], ['color', color], ['compound', align])\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nf_left  = TkLabelFrame.new(base_frame, 'text'=>'ʸ', \n                           'pady'=>2, 'padx'=>2)\nf_mid   = TkLabelFrame.new(base_frame, 'text'=>'', \n                           'pady'=>2, 'padx'=>2)\nf_right = TkLabelFrame.new(base_frame, 'text'=>'ӥåȥޥå', \n                           'pady'=>2, 'padx'=>2)\nf_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\nf_mid.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\nf_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c')\n\n# radiobutton \n[10, 12, 18, 24].each {|sz|\n  TkRadioButton.new(f_left) {\n    text \"ݥȥ #{sz}\"\n    variable size\n    relief 'flat'\n    value sz\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w', 'fill'=>'x')\n}\n\n['', '', '', '', '', ''].each {|col|\n  TkRadioButton.new(f_mid) {\n    text col\n    variable color\n    relief 'flat'\n    value col.downcase\n    anchor 'w'\n  }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x')\n}\n\n# label = TkLabel.new(f_right, 'text'=>'٥', 'bitmap'=>'questhead', \nlabel = Tk::Label.new(f_right, 'text'=>'٥', 'bitmap'=>'questhead', \n                    'compound'=>'left')\nlabel.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top')\nlabel.height(TkWinfo.reqheight(label))\nabtn = ['Top', 'Left', 'Right', 'Bottom'].collect{|a|\n  lower = a.downcase\n  TkRadioButton.new(f_right, 'text'=>a, 'variable'=>align, 'relief'=>'flat', \n                    'value'=>lower, 'indicatoron'=>0, 'width'=>7, \n                    'command'=>proc{label.compound(align.value)})\n}\n\nTk.grid('x', abtn[0])\nTk.grid(abtn[1], label, abtn[2])\nTk.grid('x', abtn[3])\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/radio3.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# radio3.rb\n#\n# This demonstration script creates a toplevel window containing\n# several radiobutton widgets.\n#\n# radiobutton widget demo (called by 'widget')\n#\n\n# toplevel widget\nif defined?($radio3_demo) && $radio3_demo\n  $radio3_demo.destroy \n  $radio3_demo = nil\nend\n\n# demo toplevel widget\n$radio3_demo = TkToplevel.new {|w|\n  title(\"Radiobutton Demonstration 3\")\n  iconname(\"radio3\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($radio3_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '5i'\n  justify 'left'\n  text 'ˤ3ĤΥ饸ܥ󥰥롼פɽƤޤܥ򥯥åȡΥ롼פ°뤹٤ƤΥܥǥåܥ򤵤줿֤ˤʤޤƥ롼פˤϡΥ롼פΤɤΥܥ򤵤Ƥ뤫򼨤ѿƤƤޤ֥ȥ饤ơȡץܥ󤬲줿Ȥˤϡ饸ܥɽȥ饤ơȥ⡼ɤˤʤޤ줫Υܥ򤹤Сܥξ֤ϸΤ褦˸ġΥܥon/off֤򼨤褦ˤʤޤߤѿͤ򸫤ˤϡѿȡץܥ򥯥åƤ'\n}\nmsg.grid(:row=>0, :column=>0, :columnspan=>3, :sticky=>'nsew')\n\n# variable\nsize = TkVariable.new\ncolor = TkVariable.new\nalign = TkVariable.new\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), \n         :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         TkButton.new(frame, :text=>'ѿ', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{\n                        showVars(base_frame, ['size', size], \n                                 ['color', color], ['compound', align])\n                      }), \n         TkButton.new(frame, :text=>'ɻ', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{showCode 'radio3'}), \n         TkButton.new(frame, :text=>'Ĥ', \n                      :image=>$image['delete'], :compound=>:left, \n                      :command=>proc{\n                        tmppath = $radio3_demo\n                        $radio3_demo = nil\n                        $showVarsWin[tmppath.path] = nil\n                        tmppath.destroy\n                      }), \n         :padx=>4, :pady=>4)\n  frame.grid_columnconfigure(0, :weight=>1)\n  TkGrid(frame, :row=>3, :column=>0, :columnspan=>3, :sticky=>'nsew')\n}\n\n# frame \nf_left  = TkLabelFrame.new(base_frame, 'text'=>'ʸ', \n                           'pady'=>2, 'padx'=>2)\nf_mid   = TkLabelFrame.new(base_frame, 'text'=>'', \n                           'pady'=>2, 'padx'=>2)\nf_right = TkLabelFrame.new(base_frame, 'text'=>'ӥåȥޥå', \n                           'pady'=>2, 'padx'=>2)\nf_left .grid('column'=>0, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2)\nf_mid  .grid('column'=>1, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2)\nf_right.grid('column'=>2, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c')\n\nTkButton.new(base_frame, 'text'=>'ȥ饤ơ', \n             'command'=>proc{size.value = 'multi'; color.value = 'multi'}){\n  grid('column'=>2, 'row'=>2, 'pady'=>'.5c', 'padx'=>'.5c')\n}\n\n# radiobutton \n[10, 12, 14, 18, 24].each {|sz|\n  TkRadioButton.new(f_left) {\n    text \"ݥȥ #{sz}\"\n    variable size\n    relief 'flat'\n    value sz\n    tristatevalue 'multi'\n  }.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w', 'fill'=>'x')\n}\n\n['Red', 'Green', 'Blue', 'Yellow', 'Orange', 'Purple'].each {|col|\n  TkRadioButton.new(f_mid) {\n    text col\n    variable color\n    relief 'flat'\n    value col.downcase\n    anchor 'w'\n    tristatevalue 'multi'\n    command proc{f_mid.fg(color.value)}\n  }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x')\n}\n\n# label = TkLabel.new(f_right, 'text'=>'٥', 'bitmap'=>'questhead', \nlabel = Tk::Label.new(f_right, 'text'=>'٥', 'bitmap'=>'questhead', \n                    'compound'=>'left')\nlabel.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top')\nlabel.height(TkWinfo.reqheight(label))\na_btn = ['Top', 'Left', 'Right', 'Bottom'].collect{|a|\n  TkRadioButton.new(f_right, 'text'=>a, 'variable'=>align, 'relief'=>'flat', \n                    'value'=>a.downcase, 'indicatoron'=>0, 'width'=>7, \n                    'command'=>proc{label.compound(align.value)})\n}\n\nTk.grid('x', a_btn[0])\nTk.grid(a_btn[1], label, a_btn[2])\nTk.grid('x', a_btn[3])\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/rmt",
    "content": "#!/usr/bin/env ruby\n\n# rmt -- \n# This script implements a simple remote-control mechanism for \n# Tk applications.  It allows you to select an application and \n# then type commands to that application. \n\nrequire 'tk'\n\nclass Rmt\n  def initialize(parent=nil)\n    win = self\n\n    unless parent\n      parent = TkRoot.new\n    end\n    root = TkWinfo.toplevel(parent)\n    root.minsize(1,1)\n\n    # The instance variable below keeps track of the remote application \n    # that we're sending to.  If it's an empty string then we execute \n    # the commands locally. \n    @app = 'local'\n    @mode = 'Ruby'\n\n    # The instance variable below keeps track of whether we're in the \n    # middle of executing a command entered via the text. \n    @executing = 0\n\n    # The instance variable below keeps track of the last command executed, \n    # so it can be re-executed in response to !! commands. \n    @lastCommand = \"\"\n\n    # Create menu bar.  Arrange to recreate all the information in the \n    # applications sub-menu whenever it is cascaded to. \n\n    TkFrame.new(root, 'relief'=>'raised', 'bd'=>2) {|f|\n      pack('side'=>'top', 'fill'=>'x')\n      TkMenubutton.new(f, 'text'=>'File', 'underline'=>0) {|mb|\n\tTkMenu.new(mb) {|mf|\n\t  mb.menu(mf)\n\t  TkMenu.new(mf) {|ma| \n\t    postcommand proc{win.fillAppsMenu ma}\n\t    mf.add('cascade', 'label'=>'Select Application', \n\t\t   'menu'=>ma, 'underline'=>0)\n\t  }\n\t  add('command', 'label'=>'Quit', \n\t      'command'=>proc{root.destroy}, 'underline'=>0)\n\t}\n\tpack('side'=>'left')\n      }\n    }\n\n    # Create text window and scrollbar. \n\n    @txt = TkText.new(root, 'relief'=>'sunken', 'bd'=>2, 'setgrid'=>true) {\n      yscrollbar(TkScrollbar.new(root){pack('side'=>'right', 'fill'=>'y')})\n      pack('side'=>'left')\n    }\n\n    @promptEnd = TkTextMark.new(@txt, 'insert')\n\n    # Create a binding to forward commands to the target application, \n    # plus modify many of the built-in bindings so that only information \n    # in the current command can be deleted (can still set the cursor \n    # earlier in the text and select and insert;  just can't delete).\n\n    @txt.bindtags([@txt, TkText, root, 'all'])\n    @txt.bind('Return', proc{\n\t\t@txt.set_insert('end - 1c')\n\t\t@txt.insert('insert', \"\\n\")\n\t\twin.invoke\n\t\tTk.callback_break\n\t      })\n    @txt.bind('Delete', proc{\n\t\tbegin\n\t\t  @txt.tag_remove('sel', 'sel.first', @promptEnd)\n\t\trescue\n\t\tend\n\t\tif @txt.tag_nextrange('sel', '1.0', 'end') == []\n\t\t  if @txt.compare('insert', '<', @promptEnd)\n\t\t    Tk.callback_break\n\t\t  end\n\t\tend\n\t      })\n    @txt.bind('BackSpace', proc{\n\t\tbegin\n\t\t  @txt.tag_remove('sel', 'sel.first', @promptEnd)\n\t\trescue\n\t\tend\n\t\tif @txt.tag_nextrange('sel', '1.0', 'end') == []\n\t\t  if @txt.compare('insert', '<', @promptEnd)\n\t\t    Tk.callback_break\n\t\t  end\n\t\tend\n\t      })\n    @txt.bind('Control-d', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Control-k', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  @txt.set_insert(@promptEnd)\n\t\tend\n\t      })\n    @txt.bind('Control-t', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Meta-d', proc{\n\t\tif @txt.compare('insert', '<', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Meta-BackSpace', proc{\n\t\tif @txt.compare('insert', '<=', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n    @txt.bind('Control-h', proc{\n\t\tif @txt.compare('insert', '<=', @promptEnd)\n\t\t  Tk.callback_break\n\t\tend\n\t      })\n\n    @txt.tag_configure('bold', 'font'=>['Courier', 12, 'bold'])\n\n    @app = Tk.appname('rmt')\n    if (@app =~ /^rmt(.*)$/)\n      root.title(\"Tk Remote Controller#{$1}\")\n      root.iconname(\"Tk Remote#{$1}\")\n    end\n    prompt\n    @txt.focus\n    #@app = TkWinfo.appname(TkRoot.new)\n  end\n\n  def tkTextInsert(w,s)\n    return if s == \"\"\n    begin\n      if w.compare('sel.first','<=','insert') \\\n\t&& w.compare('sel.last','>=','insert')\n\tw.tag_remove('sel', 'sel.first', @promptEnd)\n\tw.delete('sel.first', 'sel.last')\n      end\n    rescue\n    end\n    w.insert('insert', s)\n    w.see('insert')\n  end\n\n  # The method below is used to print out a prompt at the \n  # insertion point (which should be at the beginning of a line \n  # right now).\n\n  def prompt\n    @txt.insert('insert', \"#{@app}: \")\n    @promptEnd.set('insert')\n    @promptEnd.gravity = 'left'\n    @txt.tag_add('bold', \"#{@promptEnd.path} linestart\", @promptEnd)\n  end\n\n  # The method below executes a command (it takes everything on the \n  # current line after the prompt and either sends it to the remote \n  # application or executes it locally, depending on \"app\".\n\n  def invoke\n    cmd = @txt.get(@promptEnd, 'insert')\n    @executing += 1\n    case (@mode)\n    when 'Tcl'\n      if Tk.info('complete', cmd)\n\tif (cmd == \"!!\\n\")\n\t  cmd = @lastCommand\n\telse\n\t  @lastCommand = cmd\n\tend\n\tbegin\n\t  msg = Tk.appsend(@app, false, cmd)\n\trescue\n\t  msg = \"Error: #{$!}\"\n\tend\n\t@txt.insert('insert', msg + \"\\n\") if msg != \"\"\n\tprompt\n\t@promptEnd.set('insert')\n      end\n\n    when 'Ruby'\n      if (cmd == \"!!\\n\")\n\tcmd = @lastCommand\n      end\n      complete = true\n      begin\n\teval(\"proc{#{cmd}}\")\n      rescue\n\tcomplete = false\n      end\n      if complete\n\t@lastCommand = cmd\n\tbegin\n#\t  msg = Tk.appsend(@app, false, \n#\t\t\t   'ruby', \n#\t\t\t   '\"(' + cmd.gsub(/[][$\"]/, '\\\\\\\\\\&') + ').to_s\"')\n\t  msg = Tk.rb_appsend(@app, false, cmd)\n\trescue\n\t  msg = \"Error: #{$!}\"\n\tend\n\t@txt.insert('insert', msg + \"\\n\") if msg != \"\"\n\tprompt\n\t@promptEnd.set('insert')\n      end\n    end\n\n    @executing -= 1\n    @txt.yview_pickplace('insert')\n  end\n\n  # The following method is invoked to change the application that\n  # we're talking to.  It also updates the prompt for the current \n  # command, unless we're in the middle of executing a command from \n  # the text item (in which case a new prompt is about to be output \n  # so there's no need to change the old one). \n\n  def newApp(appName, mode)\n    @app = appName\n    @mode = mode\n    if @executing == 0\n      @promptEnd.gravity = 'right'\n      @txt.delete(\"#{@promptEnd.path} linestart\", @promptEnd)\n      @txt.insert(@promptEnd, \"#{appName}: \")\n      @txt.tag_add('bold', \"#{@promptEnd.path} linestart\", @promptEnd)\n      @promptEnd.gravity = 'left'\n    end\n  end\n\n  # The method below will fill in the applications sub-menu with a list\n  # of all the applications that currently exist. \n\n  def fillAppsMenu(menu)\n    win = self\n    begin\n      menu.delete(0,'last')\n    rescue\n    end\n    TkWinfo.interps.sort.each{|ip|\n      begin\n\tif Tk.appsend(ip, false, 'info commands ruby') == \"\"\n\t  mode = 'Tcl'\n\telse\n\t  mode = 'Ruby'\n\tend\n\tmenu.add('command', 'label'=>format(\"%s    (#{mode}/Tk)\", ip), \n\t\t 'command'=>proc{win.newApp ip, mode})\n      rescue\n\tmenu.add('command', 'label'=>format(\"%s (unknown Tk)\", ip), \n\t\t 'command'=>proc{win.newApp ip, mode}, 'state'=>'disabled')\n      end\n    }\n    menu.add('command', 'label'=>format(\"local    (Ruby/Tk)\"), \n\t     'command'=>proc{win.newApp 'local', 'Ruby'})\n  end\nend\n\nRmt.new\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/rolodex",
    "content": "#!/usr/bin/env ruby\n#\n# rolodex --\n# This script is a part of Tom LaStrange's rolodex\n# \n# Copyright (C) 1998 by Takaaki Tateishi <ttate@jaist.ac.jp>\n# Time-stamp: \"03/08/02 12:45:21 nagai\"\n#\n\nrequire \"tk\"\n\n\ndef show_help(topic,x=0,y=0)\n  if( topic.is_a?(TkWindow) )\n    w = TkWinfo.containing(x,y)\n    if( TkWinfo.exist?(w) )\n      topic = w\n    end\n  end\n  \n  if( $helpTopics.include?(topic) )\n    msg = $helpTopics[topic]\n  else\n    msg = \"Sorry, but no help is available for this topic\"\n  end\n  TkDialog.new(\"title\"=>\"Rolodex Help\",\n\t       \"message\"=>\"Information on #{topic}:\\n\\n#{msg}\",\n\t       \"default_button\"=>0,\n\t       \"buttons\"=>[\"OK\"])\nend\n\ndef fillCard\n  clearAction\n  $root.frame.entry[1].insert(0,\"Takaaki Tateishi\")\n  $root.frame.entry[2].insert(0,\"Japan Advanced Institute of Science and Techonology\")\n  $root.frame.entry[3].insert(0,\"1-1 Asahidai, Tatsunokuchi\")\n  $root.frame.entry[4].insert(0,\"Ishikawa 923-1292, Japan\")\n  $root.frame.entry[5].insert(0,\"private\")\n    $root.frame.entry[6].insert(0,\"***-***-****\")\n  $root.frame.entry[7].insert(0,\"***-***-****\")\nend\n\ndef addAction\n  for i in 1..7\n    STDERR.print format(\"%-12s %s\\n\",\n\t\t\tRolodexFrame::LABEL[i],\n\t\t\t$root.frame.entry[i].value)\n  end\nend\n\ndef clearAction\n  for i in 1..7\n    $root.frame.entry[i].delete(0,\"end\")\n  end\nend\n\ndef fileAction\n  TkDialog.new(\"title\"=>\"File Selection\",\n\t       \"message\"=>\"This is a dummy file selection dialog box.\\n\",\n\t       \"default_button\"=>0,\n\t       \"buttons\"=>[\"OK\"])\n  STDERR.print \"dummy file name\\n\"\nend\n\ndef deleteAction\n  result = TkDialog.new(\"title\"=>\"Confirm Action\",\n\t\t\t\"message\"=>\"Are you sure?\",\n\t\t\t\"default_button\"=>0,\n\t\t\t\"buttons\"=>[\"Cancel\"])\n  if( result.value == 0 )\n    clearAction\n  end\nend\n\n\nclass RolodexFrame < TkFrame\n  attr_reader :entry, :label\n\n  LABEL = [\"\",\"Name:\",\"Address:\",\"\",\"\",\"Home Phone:\",\"Work Phone:\",\"Fax:\"]\n\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n    self[\"relief\"] = \"flat\"\n    \n    @i = []\n    @label = []\n    @entry = []\n    for i in 1..7\n      @i[i] = TkFrame.new(self)\n      @i[i].pack(\"side\"=>\"top\",\n\t\t \"pady\"=>2,\n\t\t \"anchor\"=>\"e\")\n      @label[i] = TkLabel.new(@i[i],\n\t\t\t      \"text\"=>LABEL[i],\n\t\t\t      \"anchor\"=>\"e\")\n      @entry[i] = TkEntry.new(@i[i],\n\t\t\t      \"width\"=>30,\n\t\t\t      \"relief\"=>\"sunken\")\n      @entry[i].pack(\"side\"=>\"right\")\n      @label[i].pack(\"side\"=>\"right\")\n    end\n  end\nend\n\nclass RolodexButtons < TkFrame\n  attr_reader :clear, :add, :search, :delete\n\n  def initialize(parent,keys=nil)\n    super(parent,keys)\n    @clear = TkButton.new(self,\n\t\t\t  \"text\" => \"Clear\")\n    @add = TkButton.new(self,\n\t\t\t\"text\" => \"Add\")\n    @search = TkButton.new(self,\n\t\t\t   \"text\" => \"Search\")\n    @delete = TkButton.new(self,\n\t\t\t   \"text\" => \"Delete\")\n    for w in [@clear,@add,@search,@delete]\n      w.pack(\"side\"=>\"left\", \"padx\"=>2)\n    end\n  end\nend\n\nclass RolodexMenuFrame < TkFrame\n  attr_reader :file_menu, :help_menu, :file, :help\n\n  def initialize(parent,keys=nil)\n    super(parent,keys)\n    configure(\"relief\"=>\"raised\",\n\t      \"borderwidth\"=>1)\n\n    @file = TkMenubutton.new(self,\n\t\t\t     \"text\"=>\"File\",\n\t\t\t     \"underline\"=>0)\n    @file_menu = TkMenu.new(@file)\n    @file_menu.add(\"command\",\n\t\t   \"label\" => \"Load ...\",\n\t\t   \"command\" => proc{fileAction},\n\t\t   \"underline\" => 0)\n    @file_menu.add(\"command\",\n\t\t   \"label\" => \"Exit\",\n\t\t   \"command\" => proc{$root.destroy},\n\t\t   \"underline\" => 0)\n    @file.menu(@file_menu)\n    @file.pack(\"side\"=>\"left\")\n\n    @help = TkMenubutton.new(self,\n\t\t\t     \"text\"=>\"Help\",\n\t\t\t     \"underline\"=>0)\n    @help_menu = TkMenu.new(@help)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Context...\",\n\t\t   \"command\"=>proc{show_help(\"context\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Help...\",\n\t\t   \"command\"=>proc{show_help(\"help\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Window...\",\n\t\t   \"command\"=>proc{show_help(\"window\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On Keys...\",\n\t\t   \"command\"=>proc{show_help(\"keys\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=>\"On version...\",\n\t\t   \"command\"=>proc{show_help(\"version\")},\n\t\t   \"underline\"=>3)\n    @help.menu(@help_menu)\n    @help.pack(\"side\"=>\"right\")\n  end\nend\n\nclass Rolodex < TkRoot\n  attr_reader :frame, :buttons, :menu\n\n  def initialize(*args)\n    super(*args)\n    @frame = RolodexFrame.new(self)\n    @frame.pack(\"side\"=>\"top\",\n\t\t\"fill\"=>\"y\",\n\t\t\"anchor\"=>\"center\")\n    @buttons = RolodexButtons.new(self)\n    @buttons.pack(\"side\"=>\"bottom\",\n\t\t  \"pady\"=>2,\n\t\t  \"anchor\"=>\"center\")\n    @menu = RolodexMenuFrame.new(self)\n    @menu.pack(\"before\"=>@frame,\n\t       \"side\"=>\"top\",\n\t       \"fill\"=>\"x\")\n  end\nend\n\n$root = Rolodex.new\n\n$root.buttons.delete.configure(\"command\"=>proc{deleteAction})\n$root.buttons.add.configure(\"command\"=>proc{addAction})\n$root.buttons.clear.configure(\"command\"=>proc{clearAction})\n$root.buttons.search.configure(\"command\"=>proc{addAction; fillCard})\n\n$root.buttons.clear.configure(\"text\"=>\"Clear   Ctrl+C\")\n$root.bind(\"Control-c\",proc{clearAction})\n\n$root.buttons.add.configure(\"text\"=>\"Add   Ctrl+A\")\n$root.bind(\"Control-a\",proc{addAction})\n\n$root.buttons.search.configure(\"text\"=>\"Search   Ctrl+S\")\n$root.bind(\"Control-s\",proc{addAction; fillCard})\n\n$root.buttons.delete.configure(\"text\"=>\"Delete...   Ctrl+D\")\n$root.bind(\"Control-d\",proc{deleteAction})\n\n$root.menu.file_menu.entryconfigure(1, \"accel\"=>\"Ctrl+F\")\n$root.bind(\"Control-f\",proc{fileAction})\n\n$root.menu.file_menu.entryconfigure(2, \"accel\"=>\"Ctrl+Q\")\n$root.bind(\"Control-q\",proc{$root.destroy})\n\n$root.frame.entry[1].focus\n\n$root.bind(\"Any-F1\",\n\t   proc{|event| show_help(event.widget, event.x_root, event.y_root)})\n$root.bind(\"Any-Help\",\n\t   proc{|event| show_help(event.widget, event.x_root, event.y_root)})\n\n\n$helpTopics = {}\n\n$helpTopics[$root.menu.file] = <<EOF\nThis is the \"file\" menu. It can be used to invoke\\\nsome overall operations on the rolodex applications,\\\nsuch as loading a file or exiting.\nEOF\n\n$helpTopics[$root.menu.file_menu.index(0)] = <<EOF\nThe \"Load\" entry in the \"File\" menu posts a dialog box\\\nthat you can use to select a rolodex file\nEOF\n\n$helpTopics[$root.menu.file_menu.index(1)] = <<EOF\nThe \"Exit\" entry in the \"File\" menu causes the rolodex\\\napplication to terminate\nEOF\n\n$helpTopics[$root.frame.entry[1]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the person's name\nEOF\n\n$helpTopics[$root.frame.entry[2]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the first line of the person's address\nEOF\n\n$helpTopics[$root.frame.entry[3]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the second line of the person's address\nEOF\n\n$helpTopics[$root.frame.entry[4]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the third line of the person's address\nEOF\n\n$helpTopics[$root.frame.entry[5]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the person's home phone number, or \"private\"\\\nif the person doesn't want his or he number publicized\nEOF\n\n$helpTopics[$root.frame.entry[6]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the person's work phone number\nEOF\n\n$helpTopics[$root.frame.entry[7]] = <<EOF\nIn this field of the rolodex entry you should\\\ntype the phone number for the person's FAX machine\nEOF\n\n$helpTopics[\"context\"] = <<EOF\nUnfortunately, this application doesn't support context-sensitive\\\nhelp in the usual way, because when this demo was written Ruby/Tk\\\ndidn't have a grab mechanism and this is needed for context-sensitive\\\nhelp. Instead, you can achive much the same effect by simply moving\\\nthe mouse over the window you're curious about and pressing the\\\nHelp or F1 keys. You can do this anytime.\nEOF\n\n$helpTopics[\"help\"] = <<EOF\nThis application provides only very crude help. Besides the\\\nentries in this menu, you can get help on individual windows\\\nby moving the mouse cursor over the window and pressing the\\\nHelp or F1 keys.\nEOF\n\n$helpTopics[\"window\"] = <<EOF\nThis window is a dummy rolodex application created as part of\\\nTom LaStrange's toolkit benchmark. It doesn't really do anything\\\nuseful except to demonstrate a few features of the Ruby/Tk.\nEOF\n\n$helpTopics[\"keys\"] = <<EOF\nThe following accelerator keys are defined for this application\\\n(in addition to those already available for the entry windows):\nCtrl+A:\t\tAdd\nCtrl+C:\t\tClear\nCtrl+D:\t\tDelete\nCtrl+F:\t\tEnter file name\nCtrl+Q:\t\tExit application (quit)\nCtrl+S:\t\tSearch (dummy operation)\nEOF\n\n$helpTopics[\"version\"] = <<EOF\nThis is version 1.0.1.\nEOF\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/rolodex-j",
    "content": "#!/usr/bin/env ruby\n# -*- coding: euc-jp -*-\n#\n# rolodex --\n# ΥץȤ Tom LaStrange  rolodex ΰǤ\n# \n# Copyright (C) 1998 by Takaaki Tateishi <ttate@jaist.ac.jp>\n# Time-stamp: \"04/04/09 00:32:12 nagai\"\n#\n\nrequire \"tk\"\nTk.encoding = \"euc-jp\"\n\ndef show_help(topic,x=0,y=0)\n  if( topic.is_a?(TkWindow) )\n    w = TkWinfo.containing(x,y)\n    if( w.is_a?(TkWindow) )\n      if( TkWinfo.exist?(w) )\n\ttopic = w\n      end\n    end\n  end\n  \n  if( $helpTopics.include?(topic) )\n    msg = $helpTopics[topic]\n  else\n    msg = \"ΥȥԥåˤĤƤΥإפϤޤѤǤޤ\"\n  end\n  TkDialog.new(\"title\"=>\"Rolodex Help\",\n\t       \"message\"=>\"#{topic}\\n\\n#{msg}\",\n\t       \"default_button\"=>0,\n\t       \"buttons\"=>[\"OK\"])\nend\n\ndef fillCard\n  clearAction\n  $root.frame.entry[1].insert(0, \"Ω \")\n  $root.frame.entry[2].insert(0, \"923-1292 \")\n  $root.frame.entry[3].insert(0, \"äĮ  1-1\")\n  $root.frame.entry[4].insert(0, \"Φüʳصر\")\n  $root.frame.entry[5].insert(0,\"private\")\n  $root.frame.entry[6].insert(0,\"***-***-****\")\n  $root.frame.entry[7].insert(0,\"***-***-****\")\nend\n\ndef addAction\n  for i in 1..7\n    STDERR.print format(\"%-12s %s\\n\",\n\t\t\tRolodexFrame::LABEL[i],\n\t\t\t$root.frame.entry[i].value)\n  end\nend\n\ndef clearAction\n  for i in 1..7\n    $root.frame.entry[i].delete(0,\"end\")\n  end\nend\n\ndef fileAction\n  TkDialog.new(\"title\"=>\"File Selection\",\n\t       \"message\"=>\"ϥեΥߡǤ\\n\",\n\t       \"default_button\"=>0,\n\t       \"buttons\"=>[\"OK\"])\n  STDERR.print \"dummy file name\\n\"\nend\n\ndef deleteAction\n  result = TkDialog.new(\"title\"=>\"Confirm Action\",\n\t\t\t\"message\"=>\"Ǥ\",\n\t\t\t\"default_button\"=>0,\n\t\t\t\"buttons\"=>[\"󥻥\"])\n  if( result.value == 0 )\n    clearAction\n  end\nend\n\n\nclass RolodexFrame < TkFrame\n  attr_reader :entry, :label\n\n  LABEL = [\"\",\"̾:\",\"\",\"\",\"\",\"():\",\"():\",\"Fax:\"]\n\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n    self[\"relief\"] = \"flat\"\n    @i = []\n    @label = []\n    @entry = []\n    for i in 1..7\n      @i[i] = TkFrame.new(self)\n      @i[i].pack(\"side\"=>\"top\",\n\t\t \"pady\"=>2,\n\t\t \"anchor\"=>\"e\")\n      @label[i] = TkLabel.new(@i[i],\n\t\t\t      \"text\"=>LABEL[i],\n\t\t\t      \"anchor\"=>\"e\")\n      @entry[i] = TkEntry.new(@i[i],\n\t\t\t      \"width\"=>30,\n\t\t\t      \"relief\"=>\"sunken\")\n      @entry[i].pack(\"side\"=>\"right\")\n      @label[i].pack(\"side\"=>\"right\")\n    end\n  end\nend\n\nclass RolodexButtons < TkFrame\n  attr_reader :clear, :add, :search, :delete\n\n  def initialize(parent,keys=nil)\n    super(parent,keys)\n    @clear = TkButton.new(self,\"text\" => \"ꥢ\")\n    @add = TkButton.new(self,  \"text\" => \"ɲ\")\n    @search = TkButton.new(self, \"text\" => \"\")\n    @delete = TkButton.new(self,  \"text\" => \"õ\")\n    for w in [@clear,@add,@search,@delete]\n      w.pack(\"side\"=>\"left\", \"padx\"=>2)\n    end\n  end\nend\n\nclass RolodexMenuFrame < TkFrame\n  attr_reader :file_menu, :help_menu, :file, :help\n\n  def initialize(parent,keys=nil)\n    super(parent,keys)\n    configure(\"relief\"=>\"raised\",\n\t      \"borderwidth\"=>1)\n\n    @file = TkMenubutton.new(self,\n\t\t\t     \"text\"=> \"ե\",\n\t\t\t     \"underline\"=>0)\n    @file_menu = TkMenu.new(@file)\n    @file_menu.add(\"command\",\n\t\t   \"label\" => \"ɤ߹ ...\",\n\t\t   \"command\" => proc{fileAction},\n\t\t   \"underline\" => 0)\n    @file_menu.add(\"command\",\n\t\t   \"label\" => \"λ\",\n\t\t   \"command\" => proc{$root.destroy},\n\t\t   \"underline\" => 0)\n    @file.menu(@file_menu)\n    @file.pack(\"side\"=>\"left\")\n\n    @help = TkMenubutton.new(self,\n\t\t\t     \"text\"=> \"إ\",\n\t\t\t     \"underline\"=>0)\n    @help_menu = TkMenu.new(@help)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=> \"ƥȤˤĤ\",\n\t\t   \"command\"=>proc{show_help(\"ƥ\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=> \"إפˤĤ\",\n\t\t   \"command\"=>proc{show_help(\"إ\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=> \"ɥˤĤ\",\n\t\t   \"command\"=>proc{show_help(\"ɥ\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=> \"ˤĤ\",\n\t\t   \"command\"=>proc{show_help(\"\")},\n\t\t   \"underline\"=>3)\n    @help_menu.add(\"command\",\n\t\t   \"label\"=> \"С\",\n\t\t   \"command\"=>proc{show_help(\"С\")},\n\t\t   \"underline\"=>3)\n    @help.menu(@help_menu)\n    @help.pack(\"side\"=>\"right\")\n  end\nend\n\nclass Rolodex < TkRoot\n  attr_reader :frame, :buttons, :menu\n\n  def initialize(*args)\n    super(*args)\n    @frame = RolodexFrame.new(self)\n    @frame.pack(\"side\"=>\"top\",\n\t\t\"fill\"=>\"y\",\n\t\t\"anchor\"=>\"center\")\n    @buttons = RolodexButtons.new(self)\n    @buttons.pack(\"side\"=>\"bottom\",\n\t\t  \"pady\"=>2,\n\t\t  \"anchor\"=>\"center\")\n    @menu = RolodexMenuFrame.new(self)\n    @menu.pack(\"before\"=>@frame,\n\t       \"side\"=>\"top\",\n\t       \"fill\"=>\"x\")\n  end\nend\n\n$root = Rolodex.new\n\n$root.buttons.delete.configure(\"command\"=>proc{deleteAction})\n$root.buttons.add.configure(\"command\"=>proc{addAction})\n$root.buttons.clear.configure(\"command\"=>proc{clearAction})\n$root.buttons.search.configure(\"command\"=>proc{addAction; fillCard})\n\n$root.buttons.clear.configure(\"text\"=> \"ꥢ   Ctrl+C\")\n$root.bind(\"Control-c\",proc{clearAction})\n\n$root.buttons.add.configure(\"text\"=> \"ɲ   Ctrl+A\")\n$root.bind(\"Control-a\",proc{addAction})\n\n$root.buttons.search.configure(\"text\"=> \"   Ctrl+S\")\n$root.bind(\"Control-s\",proc{addAction; fillCard})\n\n$root.buttons.delete.configure(\"text\"=> \"õ   Ctrl+D\")\n$root.bind(\"Control-d\",proc{deleteAction})\n\n$root.menu.file_menu.entryconfigure(1, \"accel\"=>\"Ctrl+F\")\n$root.bind(\"Control-f\",proc{fileAction})\n\n$root.menu.file_menu.entryconfigure(2, \"accel\"=>\"Ctrl+Q\")\n$root.bind(\"Control-q\",proc{$root.destroy})\n\n$root.frame.entry[1].focus\n\n$root.bind(\"Any-F1\",\n\t   proc{|event| show_help(event.widget, event.x_root, event.y_root)})\n$root.bind(\"Any-Help\",\n\t   proc{|event| show_help(event.widget, event.x_root, event.y_root)})\n\n\n$helpTopics = {}\n\n$helpTopics[$root.menu.file] = <<EOF\nϡ֥եץ˥塼Ǥɤ߹ߡפֽλפʤɤ\nԤʤȤǤޤ\nEOF\n\n$helpTopics[$root.menu.file_menu.index(0)] = <<EOF\nեɤ߹ߤԤʤȤ˻Ȥޤ\nEOF\n\n$helpTopics[$root.menu.file_menu.index(1)] = <<EOF\nץꥱλȤ˻Ȥޤ\nEOF\n\n$helpTopics[$root.frame.entry[1]] = <<EOF\n̾륨ȥǤ\nEOF\n\n$helpTopics[$root.frame.entry[2]] = <<EOF\n륨ȥǤ\nEOF\n\n$helpTopics[$root.frame.entry[3]] = <<EOF\n륨ȥǤ\nEOF\n\n$helpTopics[$root.frame.entry[4]] = <<EOF\n륨ȥǤ\nEOF\n\n$helpTopics[$root.frame.entry[5]] = <<EOF\nֹ륨ȥǤ\\\nʤȤ private ȵޤ\nEOF\n\n$helpTopics[$root.frame.entry[6]] = <<EOF\nҤֹ륨ȥǤ\nEOF\n\n$helpTopics[$root.frame.entry[7]] = <<EOF\nFAXֹ륨ȥǤ\nEOF\n\n$helpTopics[\"ƥ\"] = <<EOF\nRuby/TkǤgrabεʤᤳΥץꥱǤ\\\nƥȥإפϥݡȤƤޤ\nƱ褦ʸ̤bindȥޥΰ֤WedgetΤ\\\nȤ뤳ȤǤޤ\nEOF\n\n$helpTopics[\"إ\"] = <<EOF\nޥ򥦥ɥˤ碌F1򲡤Ȥˤä\\\nΥإפ򸫤뤳ȤǤޤ\nEOF\n\n$helpTopics[\"ɥ\"] = <<EOF\nΥɥϥߡǤ\nEOF\n\n$helpTopics[\"\"] = <<EOF\nCtrl+A:\t\tɲ\nCtrl+C:\t\tꥢ\nCtrl+D:\t\tõ\nCtrl+F:\t\tե\nCtrl+Q:\t\tλ\nCtrl+S:\t\t\nEOF\n\n$helpTopics[\"С\"] = <<EOF\nС 1.0.1j Ǥ\nEOF\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ruler.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# ruler widget demo (called by 'widget')\n#\n\n# rulerMkTab --\n# This method creates a new triangular polygon in a canvas to\n# represent a tab stop.\n#\n# Arguments:\n# c -           The canvas window.\n# x, y -        Coordinates at which to create the tab stop.\n\ndef rulerMkTab(c,x,y)\n  v = $demo_rulerInfo\n  TkcPolygon.new(c, x, y, x+v.size, y+v.size, x-v.size, y+v.size)\nend\n\n# toplevel widget ¸ߤк\nif defined?($ruler_demo) && $ruler_demo\n  $ruler_demo.destroy \n  $ruler_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$ruler_demo = TkToplevel.new {|w|\n  title(\"Ruler Demonstration\")\n  iconname(\"ruler\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ruler_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nTkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', \n            'text'=>\"ΥХwidgetϥ롼顼ϷǤ롼顼αˤΤϥ֥ȥåפΰͤǡĥäƤ뤳Ȥˤäƥ֥ȥåפ뤳ȤǤޤޤǤˤ륿֥ȥåפưȤǤޤ֥ȥåפޤϲˤɽޤǥɥåȡޥܥΥˤΥ֥ȥåפϾäޤ\"){\n  pack('side'=>'top')\n}\n\n# frame \n$ruler_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $ruler_demo\n      $ruler_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'ruler'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$ruler_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# canvas \n$ruler_canvas = TkCanvas.new(base_frame, 'width'=>'14.8c', 'height'=>'2.5c')\n$ruler_canvas.pack('side'=>'top', 'fill'=>'x')\n\n# \nunless Struct.const_defined?(\"RulerInfo\")\n  $demo_rulerInfo = Struct.new(\"RulerInfo\", :grid, :left, :right, :x, :y, \n                               :top, :bottom, :size, :normalStyle, \n                               :activeStyle, :deleteStyle).new\nend\n$demo_rulerInfo.grid = '.25c'\n$demo_rulerInfo.left = TkWinfo.fpixels($ruler_canvas, '1c')\n$demo_rulerInfo.right = TkWinfo.fpixels($ruler_canvas, '13c')\n$demo_rulerInfo.top = TkWinfo.fpixels($ruler_canvas, '1c')\n$demo_rulerInfo.bottom = TkWinfo.fpixels($ruler_canvas, '1.5c')\n$demo_rulerInfo.size = TkWinfo.fpixels($ruler_canvas, '.2c')\n$demo_rulerInfo.normalStyle = {'fill'=>'black'}\nif TkWinfo.depth($ruler_canvas) > 1\n  $demo_rulerInfo.activeStyle = {'fill'=>'red', 'stipple'=>''}\n  $demo_rulerInfo.deleteStyle = {'fill'=>'red', \n    'stipple'=>'@'+[$demo_dir, '..', \n                     'images', 'gray25.xbm'].join(File::Separator)}\nelse\n  $demo_rulerInfo.activeStyle = {'fill'=>'black', 'stipple'=>''}\n  $demo_rulerInfo.deleteStyle = {'fill'=>'black', \n    'stipple'=>'@'+[$demo_dir, '..', \n                     'images', 'gray25.xbm'].join(File::Separator)}\nend\n\nTkcLine.new($ruler_canvas, \n            '1c', '0.5c', '1c', '1c', '13c', '1c', '13c', '0.5c', 'width'=>1)\n(0..11).each{|i|\n  x = i+1\n  TkcLine.new($ruler_canvas, \"#{x}c\", '1c', \"#{x}c\", '0.6c', 'width'=>1)\n  TkcLine.new($ruler_canvas, \"#{x}.25c\", '1c', \"#{x}.25c\", '0.8c', 'width'=>1)\n  TkcLine.new($ruler_canvas, \"#{x}.5c\", '1c', \"#{x}.5c\", '0.7c', 'width'=>1)\n  TkcLine.new($ruler_canvas, \"#{x}.75c\", '1c', \"#{x}.75c\", '0.8c', 'width'=>1)\n  TkcText.new($ruler_canvas, \"#{x}.15c\", '0.75c', 'text'=>i, 'anchor'=>'sw')\n}\n\n$rulerTag_well = TkcTag.new($ruler_canvas)\n$ruler_canvas\\\n.addtag_withtag($rulerTag_well,\n                TkcRectangle.new($ruler_canvas, \n                                 '13.2c', '1c', '13.8c', '0.5c', \n                                 'outline'=>'black', \n                                 'fill'=>($ruler_canvas\\\n                                          .configinfo('background'))[4]) )\n$ruler_canvas\\\n.addtag_withtag($rulerTag_well,\n                rulerMkTab($ruler_canvas, \n                           TkWinfo.pixels($ruler_canvas, '13.5c'), \n                           TkWinfo.pixels($ruler_canvas, '.65c') ) )\n\n$rulerTag_well.bind('1', proc{|x,y| rulerNewTab($ruler_canvas,x,y)}, '%x %y')\n$ruler_canvas.itembind('tab', '1', \n                       proc{|x,y| rulerSelectTab($ruler_canvas,x,y)}, '%x %y')\n$ruler_canvas.bind('B1-Motion', \n                   proc{|x,y| rulerMoveTab($ruler_canvas,x,y)}, '%x %y')\n$ruler_canvas.bind('Any-ButtonRelease-1', proc{rulerReleaseTab($ruler_canvas)})\n\n# rulerNewTab --\n# Does all the work of creating a tab stop, including creating the\n# triangle object and adding tags to it to give it tab behavior.\n#\n# Arguments:\n# c -           The canvas window.\n# x, y -        The coordinates of the tab stop.\n\ndef rulerNewTab(c,x,y)\n  v = $demo_rulerInfo\n  c.addtag_withtag('active', rulerMkTab(c,x,y))\n  c.addtag_withtag('tab', 'active')\n  v.x = x\n  v.y = y\n  rulerMoveTab(c,x,y)\nend\n\n# rulerSelectTab --\n# This method is invoked when mouse button 1 is pressed over\n# a tab.  It remembers information about the tab so that it can\n# be dragged interactively.\n#\n# Arguments:\n# c -           The canvas widget.\n# x, y -        The coordinates of the mouse (identifies the point by\n#               which the tab was picked up for dragging).\n\ndef rulerSelectTab(c,x,y)\n  v = $demo_rulerInfo\n  v.x = c.canvasx(x, v.grid)\n  v.y = v.top+2\n  c.addtag_withtag('active', 'current')\n  c.itemconfigure('active', v.activeStyle)\n  c.raise('active')\nend\n\n# rulerMoveTab --\n# This method is invoked during mouse motion events to drag a tab.\n# It adjusts the position of the tab, and changes its appearance if\n# it is about to be dragged out of the ruler.\n#\n# Arguments:\n# c -           The canvas widget.\n# x, y -        The coordinates of the mouse.\n\ndef rulerMoveTab(c,x,y)\n  v = $demo_rulerInfo\n  return if c.find_withtag('active') == []\n  cx = c.canvasx(x,v.grid)\n  cy = c.canvasy(y)\n  cx = v.left if cx < v.left\n  cx = v.right if cx > v.right\n  if (cy >= v.top && cy <= v.bottom)\n    cy = v.top+2\n    c.itemconfigure('active', v.activeStyle)\n  else\n    cy = cy-v.size-2\n    c.itemconfigure('active', v.deleteStyle)\n  end\n  c.move('active', cx-v.x, cy-v.y)\n  v.x = cx\n  v.y = cy\nend\n\n# rulerReleaseTab --\n# This method is invoked during button release events that end\n# a tab drag operation.  It deselects the tab and deletes the tab if\n# it was dragged out of the ruler.\n#\n# Arguments:\n# c -           The canvas widget.\n# x, y -        The coordinates of the mouse.\n\ndef rulerReleaseTab(c)\n  v = $demo_rulerInfo\n  return if c.find_withtag('active') == []\n  if v.y != v.top+2\n    c.delete('active')\n  else\n    c.itemconfigure('active', v.normalStyle)\n    c.dtag('active')\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/sayings.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# listbox widget demo 'sayings' (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($sayings_demo) && $sayings_demo\n  $sayings_demo.destroy \n  $sayings_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$sayings_demo = TkToplevel.new {|w|\n  title(\"Listbox Demonstration (well-known sayings)\")\n  iconname(\"sayings\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($sayings_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ΥꥹȥܥåˤϤʳʸäƤޤꥹȤ򥹥뤵ΤϥСǤǤޤꥹȥܥåǥޥΥܥ2(ܥ)򲡤ޤޥɥåƤǤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $sayings_demo\n      $sayings_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'sayings'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nsayings_lbox = nil\nTkFrame.new(base_frame, 'borderwidth'=>10) {|w|\n  sv = TkScrollbar.new(w)\n  sh = TkScrollbar.new(w, 'orient'=>'horizontal')\n  sayings_lbox = TkListbox.new(w) {\n    setgrid 1\n    width  20\n    height 10\n    yscrollcommand proc{|first,last| sv.set first,last}\n    xscrollcommand proc{|first,last| sh.set first,last}\n  }\n  sv.command(proc{|*args| sayings_lbox.yview(*args)})\n  sh.command(proc{|*args| sayings_lbox.xview(*args)})\n\n  if $tk_version =~ /^4\\.[01]/\n    sv.pack('side'=>'right', 'fill'=>'y')\n    sh.pack('side'=>'bottom', 'fill'=>'x')\n    sayings_lbox.pack('expand'=>'yes', 'fill'=>'y')\n\n  else\n    sayings_lbox.grid('row'=>0, 'column'=>0, \n                      'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    sv.grid('row'=>0, 'column'=>1, \n            'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    sh.grid('row'=>1, 'column'=>0, \n            'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n    TkGrid.rowconfigure(w, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(w, 0, 'weight'=>1, 'minsize'=>0)\n  end\n\n}.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y')\n\nsayings_lbox.insert(0,\n\"Waste not, want not\",\n\"Early to bed and early to rise makes a man healthy, wealthy, and wise\",\n\"Ask not what your country can do for you, ask what you can do for your country\",\n\"I shall return\",\n\"NOT\",\n\"A picture is worth a thousand words\",\n\"User interfaces are hard to build\",\n\"Thou shalt not steal\",\n\"A penny for your thoughts\",\n\"Fool me once, shame on you;  fool me twice, shame on me\",\n\"Every cloud has a silver lining\",\n\"Where there's smoke there's fire\",\n\"It takes one to know one\",\n\"Curiosity killed the cat\",\n\"Take this job and shove it\",\n\"Up a creek without a paddle\",\n\"I'm mad as hell and I'm not going to take it any more\",\n\"An apple a day keeps the doctor away\",\n\"Don't look a gift horse in the mouth\"\n)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/search.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# Text Search widget demo (called by 'widget')\n#\n\n# textLoadFile --\n# This method below loads a file into a text widget, discarding\n# the previous contents of the widget. Tags for the old widget are\n# not affected, however.\n#\n# Arguments:\n# w -           The window into which to load the file.  Must be a\n#               text widget.\n# file -        The name of the file to load.  Must be readable.\n\ndef textLoadFile(w,file)\n  w.delete('1.0', 'end')\n  f = open(file, 'r')\n  while(!f.eof?)\n    w.insert('end', f.read(1000))\n  end\n  f.close\nend\n\n# textSearch --\n# Search for all instances of a given string in a text widget and\n# apply a given tag to each instance found.\n#\n# Arguments:\n# w -           The window in which to search.  Must be a text widget.\n# string -      The string to search for.  The search is done using\n#               exact matching only;  no special characters.\n# tag -         Tag to apply to each instance of a matching string.\n\ndef textSearch(w, string, tag)\n  tag.remove('0.0', 'end')\n  return if string == \"\"\n  cur = '1.0'\n  loop {\n    cur, len = w.search_with_length(string, cur, 'end')\n    break if cur == \"\"\n    tag.add(cur, \"#{cur} + #{len} char\")\n    cur = w.index(\"#{cur} + #{len} char\")\n  }\nend\n\n# textToggle --\n# This method is invoked repeatedly to invoke two commands at\n# periodic intervals.  It normally reschedules itself after each\n# execution but if an error occurs (e.g. because the window was\n# deleted) then it doesn't reschedule itself.\n#\n# Arguments:\n# cmd1 -        Command to execute when method is called.\n# sleep1 -      Ms to sleep after executing cmd1 before executing cmd2.\n# cmd2 -        Command to execute in the *next* invocation of this method.\n# sleep2 -      Ms to sleep after executing cmd2 before executing cmd1 again.\n\ndef textToggle(cmd1,sleep1,cmd2,sleep2)\n  sleep_list = [sleep2, sleep1]\n  TkAfter.new(proc{sleep = sleep_list.shift; sleep_list.push(sleep); sleep}, \n              -1, cmd1, cmd2).start(sleep1)\nend\n\n# toplevel widget ¸ߤк\nif defined?($search_demo) && $search_demo\n  $search_demo.destroy \n  $search_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$search_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Search and Highlight\")\n  iconname(\"search\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($search_demo).pack(:fill=>:both, :expand=>true)\n\n# frame \n$search_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $search_demo\n      $search_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'search'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$search_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nTkFrame.new(base_frame) {|f|\n  TkLabel.new(f, 'text'=>'ե̾:', \n              'width'=>13, 'anchor'=>'w').pack('side'=>'left')\n  $search_fileName = TkVariable.new\n  TkEntry.new(f, 'width'=>40, \n              'textvariable'=>$search_fileName) {\n    pack('side'=>'left')\n    bind('Return', proc{textLoadFile($search_text, $search_fileName.value)\n                        $search_string_entry.focus})\n    focus\n  }\n  TkButton.new(f, 'text'=>'ɤ߹', \n               'command'=>proc{textLoadFile($search_text, \n                                            $search_fileName.value)})\\\n  .pack('side'=>'left', 'pady'=>5, 'padx'=>10)\n}.pack('side'=>'top', 'fill'=>'x')\n\nTkFrame.new(base_frame) {|f|\n  TkLabel.new(f, 'text'=>'ʸ:', \n              'width'=>13, 'anchor'=>'w').pack('side'=>'left')\n  $search_searchString = TkVariable.new\n  $search_string_entry = TkEntry.new(f, 'width'=>40, \n                                     'textvariable'=>$search_searchString) {\n    pack('side'=>'left')\n    bind('Return', proc{textSearch($search_text, $search_searchString.value, \n                                   $search_Tag)})\n  }\n  TkButton.new(f, 'text'=>'ȿž', \n               'command'=>proc{textSearch($search_text, \n                                          $search_searchString.value, \n                                          $search_Tag)}) {\n    pack('side'=>'left', 'pady'=>5, 'padx'=>10)\n  }\n}.pack('side'=>'top', 'fill'=>'x')\n\n$search_text = TkText.new(base_frame, 'setgrid'=>true) {|t|\n  $search_Tag = TkTextTag.new(t)\n  TkScrollbar.new(base_frame, 'command'=>proc{|*args| t.yview(*args)}) {|sc|\n    t.yscrollcommand(proc{|first,last| sc.set first,last})\n    pack('side'=>'right', 'fill'=>'y')\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n}  \n\n# Set up display styles for text highlighting.\n\nif TkWinfo.depth($search_demo) > 1\n  textToggle(proc{\n               $search_Tag.configure('background'=>'#ce5555', \n                                     'foreground'=>'white')\n             },\n             800, \n             proc{\n               $search_Tag.configure('background'=>'', 'foreground'=>'')\n             },\n             200 )\nelse\n  textToggle(proc{\n               $search_Tag.configure('background'=>'black', \n                                     'foreground'=>'white')\n             },\n             800, \n             proc{\n               $search_Tag.configure('background'=>'', 'foreground'=>'')\n             },\n             200 )\nend\n$search_text.insert('1.0', \"\\\nΥɥϸ¸Τ˥ƥ widget Υǽɤ \\\n褦˻ȤΤǥ⤹ΤǤޤΥȥ˥ե̾ \\\n졢<꥿> 򲡤֥ɡץܥ򲡤Ƥˤβ \\\nȥʸϤ<꥿> 򲡤ȿžץܥ򲡤Ƥ \\\nȥեΡʸȰפʬ \\\"search_Tag\\\" \\\nȤĤ졢ɽ°ȤƤʸǤ褦 \\\nꤵޤ\\n\")\n$search_text.insert('end', \"\\\nեɤ߹ߤΥȥǥ쥯ȥ \\\"#{Dir.pwd}\\\" Ǥ\\\n\")\n$search_text.set_insert '0.0'\n\n$search_fileName.value = ''\n$search_searchString.value = ''\n\n$search_text.width = 60\n$search_text.height = 20\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/spin.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# spin.rb --\n#\n# This demonstration script creates several spinbox widgets.\n#\n# based on Tcl/Tk8.4.4 widget demos\n\nif defined?($spin_demo) && $spin_demo\n  $spin_demo.destroy \n  $spin_demo = nil\nend\n\n$spin_demo = TkToplevel.new {|w|\n  title(\"Spinbox Demonstration\")\n  iconname(\"spin\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($spin_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'5i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nˤϣΥԥܥåɽƤޤ\n줾졢ޥ򤷤ʸϤ뤳ȤǤޤ\nԽȤƤϡEmacs ¿˲äơŪ\nMotif ΥݡȤƤޤȤС\nBackspace  Control-h Ȥϥκ¦ʸ\nDelete  Control-d Ȥϱ¦ʸޤ\nȤĹۤ褦ĹʸϤˤϡ\nޥΥܥ󣲤򲡤ƥɥå뤳Ȥǡʸ\n򥹥󤹤뤳ȤǽǤ\nʤǽΥԥܥåϡͤȤߤʤ褦\nʸ󤷤ϤʤȤդƤޤ\nܤΥԥܥå˸Τϥȥ\nꥢԻ̾ΥꥹȤȤʤäƤޤ\n⤷ʤȤäƤ Ruby ˥󥯤Ƥ Tk 饤\n֥꤬ spinbox åȤƤʤ硢\nǥϤޤưʤϤǤξˤ spinbox \nåȤƤ褦ʤ꿷С Tk \nȤ߹碌ƻ褦ˤƤ\nEOL\n\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $spin_demo.destroy\n                 $spin_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'spin'\n               }).pack(:side=>:left, :expand=>true)\n}\n\naustralianCities = [\n    'Canberra', 'Sydney', 'Melbourne', 'Perth', 'Adelaide', \n    'Brisbane', 'Hobart', 'Darwin', 'Alice Springs'\n]\n\n[\n  TkSpinbox.new(base_frame, :from=>1, :to=>10, :width=>10, :validate=>:key, \n                :validatecommand=>[\n                  proc{|s| s == '' || /^[+-]?\\d+$/ =~ s }, '%P'\n                ]), \n  TkSpinbox.new(base_frame, :from=>0, :to=>3, :increment=>0.5, \n                :format=>'%05.2f', :width=>10), \n  TkSpinbox.new(base_frame, :values=>australianCities, :width=>10)\n].each{|sbox| sbox.pack(:side=>:top, :pady=>5, :padx=>10)}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/square",
    "content": "#!/usr/bin/env ruby\n\n# square --\n# This script generates a demo application containing only \n# a \"square\" widget.  It's only usable if Tk has been compiled \n# with tkSquare.c and with the -DSQUARE_DEMO compiler switch. \n# This demo arranges the following bindings for the widget: \n#\n# Button-1 press/drag:          moves square to mouse\n# \"a\":                          toggle size animation on/off\n#\n\nrequire 'tk'\nrequire 'tkafter'\n\nclass TkSquare<TkWindow\n  def create_self\n    begin\n      tk_call 'square', path\n    rescue\n      STDERR.print \"\\nSorry. Your Tk interpreter does not contain \" +\n\t'a \"square\" demonstration widget.' + \n\t\"\\n ( See documents included the Tcl/Tk source archive. )\\n\\n\"\n      exit\n    end\n  end\n  def size(amount=nil)\n    if amount\n      tk_send 'size', amount\n    else\n      number(tk_send('size'))\n    end\n  end\n  def position(x,y)\n    tk_send 'position', x, y\n  end\nend\n\n$s = TkSquare.new{\n  pack('expand'=>'yes', 'fill'=>'both')\n  bind('1', proc{|x,y| center(x,y)}, '%s %y')\n  bind('B1-Motion', proc{|x,y| center(x,y)}, '%s %y')\n  bind('a', proc{animate})\n  focus\n}\nTkRoot.new.minsize(1,1)\n\n# The procedure below centers the square on a given position.\n\ndef center(x,y)\n  a = $s.size\n  $s.position(x-(a/2), y-(a/2))\nend\n\n# The procedures below provide a simple form of animation where\n# the box changes size in a pulsing pattern: larger, smaller, larger, \n# and so on.\n\n$inc = 0\n\ndef timer_proc\n  a = $s.size\n  return if $inc == 0\n  $inc = -3 if a >= 40\n  $inc =  3 if a <= 10\n  $s.size(a+$inc)\nend\n\n$timer = TkAfter.new(30, -1, proc{timer_proc})\n\ndef animate\n  if $inc == 0\n    $inc = 3\n    $timer.start\n  else\n    $inc = 0\n    $timer.stop\n  end\nend\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/states.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# listbox widget demo 'states' (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($states_demo) && $states_demo\n  $states_demo.destroy \n  $states_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$states_demo = TkToplevel.new {|w|\n  title(\"Listbox Demonstration (states)\")\n  iconname(\"states\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($states_demo).pack(:fill=>:both, :expand=>true)\n\n# label \nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '4i'\n  justify 'left'\n  text \"ˤΤƻܸ̾äСդΥꥹȥܥåǤꥹȤ򥹥뤵ΤϥСǤǤޤꥹȥܥåǥޥΥܥ2(ܥ)򲡤ޤޥɥåƤǤޤ\"\n}\nmsg.pack('side'=>'top')\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $states_demo\n      $states_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'states'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \nstates_lbox = nil\nTkFrame.new(base_frame, 'borderwidth'=>'.5c') {|w|\n  s = TkScrollbar.new(w)\n  states_lbox = TkListbox.new(w) {\n    setgrid 1\n    height 12\n    yscrollcommand proc{|first,last| s.set first,last}\n  }\n  s.command(proc{|*args| states_lbox.yview(*args)})\n  s.pack('side'=>'right', 'fill'=>'y')\n  states_lbox.pack('side'=>'left', 'expand'=>1, 'fill'=>'both')\n}.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y')\n\nins_data = [\n  '','Ŀ','','','','','ɲ',\n  'ʬ','','','','','','',\n  '','','','','','','',\n  '','Ų','纬','','','','',\n  'Ļ','ٻ','Ĺ','Ĺ','','','ʼ',\n  '','ʡ','ʡ','ʡ','̳ƻ','','ܾ',\n  'ܺ','','','','²λ'\n]\n\nstates_lbox.insert(0, *ins_data)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/style.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# text (display styles) widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($style_demo) && $style_demo\n  $style_demo.destroy \n  $style_demo = nil\nend\n\n\n# demo Ѥ toplevel widget \n$style_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Display Styles\")\n  iconname(\"style\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($style_demo).pack(:fill=>:both, :expand=>true)\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $style_demo\n      $style_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'style'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n\n# text \ntxt = TkText.new(base_frame){|t|\n  # \n  setgrid 'true'\n  #width  70\n  #height 32\n  wrap 'word'\n  font $font\n  TkScrollbar.new(base_frame) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    command proc{|*args| t.yview(*args)}\n    t.yscrollcommand proc{|first,last| s.set first,last}\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n\n  # ƥȥ (եȴϢ)\n  family = 'Courier'\n\n  if $tk_version =~ /^4.*/\n    style_tag_bold = TkTextTag.new(t, 'font'=>'-*-Courier-Bold-O-Normal--*-120-*-*-*-*-*-*')\n    style_tag_big = TkTextTag.new(t, 'font'=>'-*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*', 'kanjifont'=>$msg_kanji_font)\n    style_tag_verybig = TkTextTag.new(t, 'font'=>'-*-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*')\n    # style_tag_small = TkTextTag.new(t, 'font'=>'-Adobe-Helvetica-Bold-R-Normal-*-100-*', 'kanjifont'=>$kanji_font)\n    style_tag_small = TkTextTag.new(t, 'font'=>'-Adobe-Helvetica-Bold-R-Normal-*-100-*')\n  else\n    style_tag_bold = TkTextTag.new(t, 'font'=>[family, 12, :bold, :italic])\n    style_tag_big = TkTextTag.new(t, 'font'=>[family, 14, :bold])\n    style_tag_verybig = TkTextTag.new(t, 'font'=>['Helvetica', 24, :bold])\n    style_tag_small = TkTextTag.new(t, 'font'=>'Times 8 bold')\n  end\n###\n#  case($tk_version)\n#  when /^4.*/\n#    style_tag_big = TkTextTag.new(t, 'font'=>'-*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*', 'kanjifont'=>$msg_kanji_font)\n#    style_tag_small = TkTextTag.new(t, 'font'=>'-Adobe-Helvetica-Bold-R-Normal-*-100-*', 'kanjifont'=>$kanji_font)\n#  when /^8.*/\n#    unless $style_demo_do_first\n#      $style_demo_do_first = true\n#      Tk.tk_call('font', 'create', '@bigascii', \n#                '-copy', '-*-Courier-Bold-R-Normal--*-140-*-*-*-*-*-*')\n#      Tk.tk_call('font', 'create', '@smallascii', \n#                '-copy', '-Adobe-Helvetica-Bold-R-Normal-*-100-*')\n#      Tk.tk_call('font', 'create', '@cBigFont', \n#                '-compound', '@bigascii @msg_knj')\n#      Tk.tk_call('font', 'create', '@cSmallFont', \n#                '-compound', '@smallascii @kanji')\n#    end\n#    style_tag_big = TkTextTag.new(t, 'font'=>'@cBigFont')\n#    style_tag_small = TkTextTag.new(t, 'font'=>'@cSmallFont')\n#  end\n\n  # ƥȥ (꡼մϢ)\n  if TkWinfo.depth($root).to_i > 1\n    style_tag_color1 = TkTextTag.new(t, 'background'=>'#a0b7ce')\n    style_tag_color2 = TkTextTag.new(t, 'foreground'=>'red')\n    style_tag_raised = TkTextTag.new(t, 'relief'=>'raised', 'borderwidth'=>1)\n    style_tag_sunken = TkTextTag.new(t, 'relief'=>'sunken', 'borderwidth'=>1)\n  else\n    style_tag_color1 = TkTextTag.new(t, 'background'=>'black', \n                                     'foreground'=>'white')\n    style_tag_color2 = TkTextTag.new(t, 'background'=>'black', \n                                     'foreground'=>'white')\n    style_tag_raised = TkTextTag.new(t, 'background'=>'white', \n                                     'relief'=>'raised', 'borderwidth'=>1)\n    style_tag_sunken = TkTextTag.new(t, 'background'=>'white', \n                                     'relief'=>'sunken', 'borderwidth'=>1)\n  end\n\n  # ƥȥ (¾)\n  if $tk_version =~ /^4\\.[01]/\n    style_tag_bgstipple = TkTextTag.new(t, 'background'=>'black', \n                                        'borderwidth'=>0, \n                                        'bgstipple'=>'gray25')\n  else\n    style_tag_bgstipple = TkTextTag.new(t, 'background'=>'black', \n                                        'borderwidth'=>0, \n                                        'bgstipple'=>'gray12')\n  end\n  style_tag_fgstipple = TkTextTag.new(t, 'fgstipple'=>'gray50')\n  style_tag_underline = TkTextTag.new(t, 'underline'=>'on')\n  style_tag_overstrike = TkTextTag.new(t, 'overstrike'=>'on')\n  style_tag_right  = TkTextTag.new(t, 'justify'=>'right')\n  style_tag_center = TkTextTag.new(t, 'justify'=>'center')\n  if $tk_version =~ /^4.*/\n    style_tag_super = TkTextTag.new(t, 'offset'=>'4p', 'font'=>'-Adobe-Courier-Medium-R-Normal--*-100-*-*-*-*-*-*')\n    style_tag_sub = TkTextTag.new(t, 'offset'=>'-2p', 'font'=>'-Adobe-Courier-Medium-R-Normal--*-100-*-*-*-*-*-*')\n  else\n    style_tag_super = TkTextTag.new(t, 'offset'=>'4p', 'font'=>[family, 10])\n    style_tag_sub = TkTextTag.new(t, 'offset'=>'-2p', 'font'=>[family, 10])\n  end\n  style_tag_margins = TkTextTag.new(t, 'lmargin1'=>'12m', 'lmargin2'=>'6m',\n                                    'rmargin'=>'10m')\n  style_tag_spacing = TkTextTag.new(t, 'spacing1'=>'10p', 'spacing2'=>'2p',\n                                    'lmargin1'=>'12m', 'lmargin2'=>'6m',\n                                    'rmargin'=>'10m')\n\n  # ƥ\n  insert('end', 'Τ褦˥ƥ widget Ͼ͡ʥɽ뤳\nǤޤ')\n  insert('end', '', style_tag_big)\n  insert('end', 'Ȥᥫ˥ǥȥ뤵ޤ\nȤϥƥ widget Τʸ (ϰ)ФŬѤǤ\nñʤ̾ΤȤǤ͡ɽǤޤ\nꤹȡΥΤĤʸϻꤷɽ\n褦ˤʤޤѤǤɽϼ̤Ǥ\n')\n  insert('end', '\n1. ե', style_tag_big)\n  insert('end', '    ɤ X ΥեȤǤȤޤ')\n  insert('end', 'large', style_tag_verybig)\n  insert('end', '\nȤ')\n#  insert('end', '', style_tag_small)\n  insert('end', 'small', style_tag_small)\n  insert('end', 'Ȥ\n')\n  insert('end', '\n2. ', style_tag_big)\n  insert('end', '  ')\n  insert('end', 'طʿ', style_tag_color1)\n  insert('end', '')\n  insert('end', 'ʿ', style_tag_color2)\n  insert('end', '')\n  insert('end', 'ξ', style_tag_color1, style_tag_color2)\n  insert('end', 'ȤѤ뤳ȤǤޤ\n')\n  insert('end', '\n3. ֤', style_tag_big)\n  insert('end', '  Τ褦κݤ')\n  insert('end', 'طʤ', style_tag_bgstipple)\n  insert('end', 'ʸ', style_tag_fgstipple)\n  insert('end', 'ñʤɤĤ֤\nǤʤ֤ȤȤǤޤ\n')\n  insert('end', '\n4. ', style_tag_big)\n  insert('end', '  Τ褦')\n  insert('end', 'ʸ˲', style_tag_underline)\n  insert('end', 'ȤǤޤ\n')\n  insert('end', '\n5. Ǥä', style_tag_big)\n  insert('end', '  Τ褦')\n  insert('end', 'ʸ˽Ťͤ', style_tag_overstrike)\n  insert('end', 'ȤǤޤ\n')\n  insert('end', '\n6. 3D ', style_tag_big)\n  insert('end', '  طʤȤĤơʸ')\n  insert('end', 'ӽФ', style_tag_raised)\n  insert('end', '褦ˤ')\n  insert('end', '', style_tag_sunken)\n  insert('end', '\n褦ˤǤޤ\n')\n  insert('end', '\n7. ·', style_tag_big)\n  insert('end', ' Τ褦˹Ԥ\n')\n  insert('end', '·\n')\n  insert('end', '·\n', style_tag_right)\n  insert('end', '·Ǥޤ\n', style_tag_center)\n  insert('end', '\n8. դʸź', style_tag_big)\n  insert('end', '  10')\n  insert('end', 'n', style_tag_super)\n  insert('end', ' Τ褦˸դʸθ̤䡢')\n  insert('end', '\nX')\n  insert('end', 'i', style_tag_sub)\n  insert('end', 'Τ褦źθ̤ФȤǤޤ\n')\n  insert('end', '\n9. ޡ', style_tag_big)\n  insert('end', 'ƥȤκ¦;ʬʶ֤ȤǤޤ:\n')\n  insert('end', 'ϥޡλǤ꡼', \n         style_tag_margins)\n  insert('end', 'ޤ֤ɽƤ1ԤΥƥȤǤ', \n         style_tag_margins)\n  insert('end', '¦ˤ2Υޡޤ', style_tag_margins)\n  insert('end', '1ܤФΤȡ', style_tag_margins)\n  insert('end', '2ܰʹߤϢ³ޡ', style_tag_margins)\n  insert('end', 'Ǥޤ¦ˤޡ󤬤ޤ', style_tag_margins)\n  insert('end', 'Ԥޤ֤֤뤿˻Ѥ뤳ȤǤޤ\n', style_tag_margins)\n  insert('end', '\n10. ڡ', style_tag_big)\n  insert('end', '3ĤΥѥ᡼ǹԤΥڡ󥰤')\n  insert('end', '椹\n뤳ȤǤޤSpacing1ǡԤ')\n  insert('end', 'ˤɤΤ餤ζ֤֤\nspacing3')\n  insert('end', 'ǹԤβˤɤΤ餤ζ֤֤')\n  insert('end', 'Ԥޤ֤Ƥʤ\nСspacing2ǡ')\n  insert('end', 'ƥȹԤƤԤδ֤ˤɤΤ餤')\n  insert('end', 'ζ֤\n򼨤ޤ\n')\n  insert('end', 'ΥǥȤ줿ϤɤΤ褦', \n         style_tag_spacing)\n  insert('end', 'ڡ󥰤ԤΤ򼨤ޤ', \n         style_tag_spacing)\n  insert('end', 'ϼºݤϥƥwidget', style_tag_spacing)\n  insert('end', '1ԤǡwidgetˤäޤޤƤޤ\n', style_tag_spacing)\n  insert('end', 'Spacing1ϤΥƥȤǤ10point', style_tag_spacing)\n  insert('end', 'ꤵƤޤ', style_tag_spacing)\n  insert('end', 'ˤꡢδ֤礭ʴֳ֤', style_tag_spacing)\n  insert('end', '¸ߤƤޤ', style_tag_spacing)\n  insert('end', 'Spacing22pointꤵƤޤ', style_tag_spacing)\n  insert('end', 'ˤۤξֳ֤¸ߤƤޤ', \n         style_tag_spacing)\n  insert('end', 'Spacing3ϤǤϻѤƤޤ\n', style_tag_spacing)\n  insert('end', 'ֳ֤ɤˤ뤫򸫤С', \n         style_tag_spacing)\n  insert('end', 'ʤǥƥȤ򤷤Ƥ', style_tag_spacing)\n  insert('end', 'ȿžʬˤ;ʬˤȤ줿ֳ֤', style_tag_spacing)\n  insert('end', 'ޤޤƤޤ\n', style_tag_spacing)\n\n}\n\ntxt.width 70\ntxt.height 32\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/tcolor",
    "content": "#!/usr/bin/env ruby\n# -*- coding: euc-jp -*-\n#\n# tcolor --\n# ΥץȤRGB,HSB,CYM򥵥ݡȤ\n# ʰץ顼ǥǤ\n#\n# Copyright (C) 1998 Takaaki Tateishi(ttate@jaist.ac.jp)\n# last update: Thu Jun 18 06:32:35 JST 1998\n#\n\n# ޤtk.rbɤ߹ࡣ\n\nrequire \"tk\"\n\n\n# TkˤäѹѿTkVariableΥ󥹥󥹤Ȥ\n\n$colorSpace = TkVariable.new(:rgb)\n$master = nil\n$red = 65535\n$green = 0\n$blue = 0\n$color = \"#ffff00000000\"\n$updating = TkVariable.new(0)\n$autoUpdate = TkVariable.new(1)\n$name = TkVariable.new($color)\n$command = TkVariable.new(\"print(%%,\\\"\\n\\\")\")\n# $command = TkVariable.new(\"\")\n$label1 = TkVariable.new(\"label1\")\n$label2 = TkVariable.new(\"label2\")\n$label3 = TkVariable.new(\"label3\")\n\n\n# ꥽ǡ١\nif (TkVarAccess.new('tcl_platform')['platform'] == 'unix')\n  TkOptionDB.add('*Entry.background', 'white')\nend\n\n\n# ƥ٥ѤΥ᥽å\n\ndef rgbToHsv(red,green,blue)\n\n  if ( red > green )\n    max = red\n    min = green\n  else\n    max = green\n    min = red\n  end\n\n  if ( blue > max )\n    max = blue\n  else\n    if ( blue < min )\n      min = blue\n    end\n  end\n\n  range = max - min\n\n  if ( max == 0 )\n    sat = 0.0\n  else\n    sat = (max-min)/max\n  end\n\n  if ( sat == 0 )\n    hue = 0.0\n  else\n    rc = (max-red)/range\n    gc = (max-green)/range\n    bc = (max-blue)/range\n    if ( red == max )\n      hue = 0.166667 * (bc - gc)\n    else\n      if ( green == max )\n\thue = 0.166667 * (2.0 + rc - bc)\n      else\n\thue = 0.166667 * (4.0 + gc - rc)\n      end\n    end\n    if ( hue < 0.0 )\n      hue = hue + 1.0\n    end\n  end\n\n  [hue,sat,max/65535]\nend\n\n\ndef hsbToRgb(hue,sat,value)\n  v = 65535.0 * value\n  if( sat == 0 )\n    ans = [v,v,v]\n  else\n    hue = hue*6.0\n    if ( hue >= 6 )\n      hue = 0.0\n    end\n    i = hue.to_i\n    f = hue - i\n    p = 65535.0 * value * (1.0 - sat)\n    q = 65535.0 * value * (1.0 - (sat * f))\n    t = 65535.0 * value * (1.0 - (sat * (1.0 - f)))\n    case i\n    when 0\n      ans = [v,t,p]\n    when 1\n      ans = [q,v,p]\n    when 2\n      ans = [p,v,t]\n    when 3\n      ans = [p,q,v]\n    when 4\n      ans = [t,p,v]\n    when 5\n      ans = [v,p,q]\n    else\n      raise(eException,\"i value #{i} is out of range\")\n    end\n  end\n  return ans\nend\n\n\ndef _null_binding\n  Module.new.instance_eval{binding}\nend\nprivate :_null_binding\n\ndef doUpdate \n  newCmd = $command.to_s.gsub(\"%%\",\"\\\"#{$color}\\\"\")\n  eval(newCmd, _null_binding)\nend\n\n\ndef tc_scaleChanged\n  if( $updating.to_i == 1 )\n    return \n  end\n\n  $master = :scale if $master == nil\n\n  scale1 = $root.middle.middle.scale1\n  scale2 = $root.middle.middle.scale2\n  scale3 = $root.middle.middle.scale3\n\n  case $colorSpace.value.intern\n  when :rgb\n    $red = (scale1.get * 65.535).to_i\n    $green = (scale2.get * 65.535).to_i\n    $blue = (scale3.get * 65.535).to_i\n  when :cmy\n    $red = (65535 - scale1.get * 65.535).to_i\n    $green = (65535 - scale2.get * 65.535).to_i\n    $blue = (65535 - scale3.get * 65.535).to_i        \n  when :hsb\n    list = hsbToRgb(scale1.get / 1000.0,\n\t\t    scale2.get / 1000.0,\n\t\t    scale3.get / 1000.0)\n    $red = list[0]\n    $green = list[1]\n    $blue = list[2]\n  else\n    raise(Exception,\"unknown colorSpace\")\n  end\n  $color = format(\"#%04x%04x%04x\",$red.to_i,$green.to_i,$blue.to_i)\n  $name.value = $color if $master == :scale\n  $root.middle.right.set_color($color)\n  if( $autoUpdate.to_i == 1 )\n    doUpdate\n  end\n  Tk.update(true)\n  $master = nil if $master == :scale\nend\n\n\ndef tc_setScales\n  $updating.value = 1\n\n  scale1 = $root.middle.middle.scale1\n  scale2 = $root.middle.middle.scale2\n  scale3 = $root.middle.middle.scale3\n  \n  case $colorSpace.value.intern\n  when :rgb\n    scale1.set($red / 65.535)\n    scale2.set($green / 65.535)\n    scale3.set($blue / 65.535)\n  when :cmy\n    scale1.set((65535 - $red) / 65.535)\n    scale2.set((65535 - $green) / 65.535)\n    scale3.set((65535 - $blue) / 65.535)\n  when :hsb\n    list = rgbToHsv($red,$green,$blue)\n    scale1.set( list[0] * 1000.0 )\n    scale2.set( list[1] * 1000.0 )\n    scale3.set( list[2] * 1000.0 )\n  else\n    raise(Exception,\"unknown colorSpace\")\n  end\n\n  $updating.value = 0\nend\n\n\ndef tc_loadNamedColor(name)\n  $name.value = name\n  $master = :name if $master == nil\n  if name[0,1] != \"#\" \n    list = TkWinfo.rgb($root.middle.right.swatch,name)\n    $red = list[0]\n    $green = list[1]\n    $blue = list[2]\n  else\n    case name.length\n    when 4\n      fmt = /#(.{1})(.{1})(.{1})/\n      shift = 12\n    when 7\n      fmt = /#(.{2})(.{2})(.{2})/\n      shift = 8\n    when 10\n      fmt = /#(.{3})(.{3})(.{3})/\n      shift = 4\n    when 13\n      fmt = /#(.{4})(.{4})(.{4})/\n      shift = 0\n    else\n      raise(eException,\"syntax error in color name \\\"#{name}\\\"\")\n    end\n    name.scan(fmt){|strlist|\n      if strlist.length != 3\n\traise(eException,\"syntax error in color name \\\"#{name}\\\"\")\n      end\n      $red = strlist[0].hex\n      $green = strlist[1].hex\n      $blue = strlist[2].hex\n    }\n    $red = $red << shift\n    $green = $green << shift\n    $blue = $blue << shift\n  end\n  \n  tc_setScales\n  $color = format(\"#%04x%04x%04x\",$red,$green,$blue)\n  $root.middle.right.set_color($color)\n  if $autoUpdate.to_i == 1\n    doUpdate\n  end\n  Tk.update(true)\n  $master = nil if $master == :name\nend\n\n\ndef changeColorSpace(space)\n  case space\n  when :rgb\n    $label1.value = \"Red\"\n    $label2.value = \"Green\"\n    $label3.value = \"Blue\"\n  when :cmy\n    $label1.value = \"Cyan\"\n    $label2.value = \"Magenta\"\n    $label3.value = \"Yellow\"\n  when :hsb\n    $label1.value = \"Hue\"\n    $label2.value = \"Saturation\"\n    $label3.value = \"Brightness\"\n  end\n  tc_setScales\nend\n\n\n\n\n\n# tcolorѤΥ˥塼\n\nclass TkColorMenuFrame<TkFrame\n  def initialize(parent)\n    super(parent,\n\t  \"relief\"=>\"raised\",\n\t  \"borderwidth\"=>\"2\")\n\n    # File˥塼ܥ\n    @file = TkMenubutton.new(self){|button|\n\n      # File˥塼κ\n      @file_menu = TkMenu.new(button){\n\tadd \"radio\",\n\t  \"label\" => \"RGB color space\",\n\t  \"variable\" => $colorSpace,\n\t  \"value\" => :rgb,\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{changeColorSpace(:rgb)}\n\tadd \"radio\",\n\t  \"label\" => \"CMY color space\",\n\t  \"variable\" => $colorSpace,\n\t  \"value\" => :cmy,\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{changeColorSpace(:cmy)}\n\tadd \"radio\",\n\t  \"label\" => \"HSB color space\",\n\t  \"variable\" => $colorSpace,\n\t  \"value\" => :hsb,\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{changeColorSpace(:hsb)}\n\tadd \"separator\"\n\tadd \"radio\",\n\t  \"label\" => \"Automatic updates\",\n\t  \"variable\" => $autoUpdate,\n\t  \"value\" => \"1\",\n\t  \"underline\" => \"0\"\n\tadd \"radio\",\n\t  \"label\" => \"Manual updates\",\n\t  \"variable\" => $autoUpdate,\n\t  \"value\" => \"0\",\n\t  \"underline\" => \"0\"\n\tadd \"separator\"\n\tadd \"command\",\n\t  \"label\" => \"Exit program\",\n\t  \"underline\" => \"0\",\n\t  \"command\" => proc{exit}\n      }\n      \n      # File˥塼FileܥϢդ\n      menu @file_menu\n\n      text \"File\"\n      underline \"0\"\n    }.pack(\"side\"=>\"left\")\n\n    self\n  end\nend\n\n\n# Υե졼ΤΥ饹\nclass TkColorBotFrame<TkFrame\n  def initialize(parent)\n    super(parent,\n\t  \"relief\"=> \"raised\",\n\t  \"borderwidth\"=> 2)\n\n    @commandLabel = TkLabel.new(self,\n\t\t\t\t\"text\"=> \"Command:\")\n    @command = TkEntry.new(self,\n\t\t\t   \"relief\"=> \"sunken\",\n\t\t\t   \"borderwidth\"=> \"2\",\n\t\t\t   \"textvariable\"=> $command,\n\t\t\t   \"font\"=> \"-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*\")\n    @update = TkButton.new(self,\n\t\t\t   \"text\"=> \"Update\",\n\t\t\t   \"command\"=> proc{doUpdate})\n    @commandLabel.pack(\"side\"=>\"left\")\n    @update.pack(\"side\"=>\"right\",\"pady\"=>\".1c\",\"padx\"=>\".25c\")\n    @command.pack(\"expand\"=>\"yes\",\"fill\"=>\"x\",\"ipadx\"=>\".25c\")\n\n    self\n  end\nend    \n\n\n# ʺΥե졼\nclass TkColorMiddleLeftFrame<TkFrame\n  def initialize(parent)\n    super(parent)\n\n    for i in [\"/usr/local/lib/X11rgb.txt\",\"/usr/lib/X11/rgb.txt\",\n\t\"/X11/R5/lib/X11/rgb.txt\",\"/X11/R4/lib/rgb/rgb.txt\",\n\t\"/usr/openwin/lib/X11/rgb.txt\"]\n      if !File.readable?(i)\n\tnext\n      end\n      f = File.open(i)\n      @scroll = TkScrollbar.new(self,\n\t\t\t\t\"orient\"=>\"vertical\",\n\t\t\t\t\"relief\"=>\"sunken\",\n\t\t\t\t\"borderwidth\"=>\"2\")\n      @scroll.pack(\"side\"=>\"right\",\"fill\"=>\"y\")\n      @names = TkListbox.new(self,\n\t\t\t     \"width\"=>\"20\",\n\t\t\t     \"height\"=>\"12\",\n\t\t\t     \"yscrollcommand\"=> proc{|first,last| @scroll.set first,last},\n\t\t\t     \"relief\"=>\"sunken\",\n\t\t\t     \"borderwidth\"=>\"2\",\n\t\t\t     \"exportselection\"=>\"false\")\n      @scroll.command(proc{|*args| @names.yview(*args)})\n      @names.bind(\"Double-1\",proc{\n\t\t    tc_loadNamedColor(@names.get(@names.curselection))})\n      @names.pack(\"side\"=>\"left\")\n      while (line = f.gets)\n\tline.chop!\n\tlinelist = line.split(/[ \\t]+/)\n\tif linelist.length == 4\n\t  @names.insert(\"end\",linelist[3])\n\tend\n      end\n      f.close\n      break\n    end\n\n    self\n  end\nend\n\n\n# Υե졼\nclass TkColorMiddleMiddleFrame<TkFrame\n  # @scale1,@scale2,@scale3黲ȤΤߵĤ롣(ѹԲ)\n  attr_reader :scale1, :scale2, :scale3\n\n  def initialize(parent)\n    super(parent)\n\n    @f1 = TkFrame.new(self)\n    @f2 = TkFrame.new(self)\n    @f3 = TkFrame.new(self)\n    @f4 = TkFrame.new(self)\n\n    for f in [@f1,@f2,@f3]\n      f.pack(\"side\"=>\"top\",\"expand\"=>\"yes\")\n    end\n    @f4.pack(\"side\"=>\"top\",\"expand\"=>\"yes\",\"fill\"=>\"x\")\n\n    @label1 = TkLabel.new(self,\"textvariable\"=>$label1)\n    @scale1 = TkScale.new(self,\"from\"=>\"0\",\"to\"=>\"1000\",\"length\"=>\"6c\",\n\t\t\t  \"orient\"=>\"horizontal\",\n\t\t\t  \"command\"=>proc{tc_scaleChanged})\n    @scale1.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n    @label1.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n\n    @label2 = TkLabel.new(self,\"textvariable\"=>$label2)\n    @scale2 = TkScale.new(self,\"from\"=>\"0\",\"to\"=>\"1000\",\"length\"=>\"6c\",\n\t\t\t  \"orient\"=>\"horizontal\",\n\t\t\t  \"command\"=>proc{tc_scaleChanged})\n    @scale2.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n    @label2.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n\n    @label3 = TkLabel.new(self,\"textvariable\"=>$label3)\n    @scale3 = TkScale.new(self,\"from\"=>\"0\",\"to\"=>\"1000\",\"length\"=>\"6c\",\n\t\t\t  \"orient\"=>\"horizontal\",\n\t\t\t  \"command\"=>proc{tc_scaleChanged})\n    @scale3.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n    @label3.pack(\"side\"=>\"top\",\"anchor\"=>\"w\")\n\n    @nameLabel = TkLabel.new(self,\"text\"=>\"Name:\")\n    @name = TkEntry.new(self,\"relief\"=>\"sunken\",\"borderwidth\"=>\"2\",\n\t\t\t\"textvariable\"=>$name,\"width\"=>\"10\",\n\t\t\t\"font\"=>\"-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*\")\n    @nameLabel.pack(\"side\"=>\"left\")\n    @name.pack(\"side\"=>\"right\", \"expand\"=>\"1\", \"fill\"=>\"x\")\n    @name.bind(\"Return\",proc{tc_loadNamedColor $name.to_s})\n\n    self\n  end\nend\n\n\nclass TkColorMiddleRightFrame<TkFrame\n  attr_reader :swatch\n\n  def initialize(parent)\n    super(parent)\n    @swatch = TkFrame.new(self, \"width\"=>\"2c\", \"height\"=>\"5c\",\n\t\t\t  \"background\"=>$color)\n    @value = TkLabel.new(self, \n\t\t\t \"text\"=>$color,\n\t\t\t \"width\"=>\"13\",\n\t\t\t \"font\"=>\"-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*\")\n    @swatch.pack(\"side\"=>\"top\",\"expand\"=>\"yes\",\"fill\"=>\"both\")\n    @value.pack(\"side\"=>\"bottom\",\"pady\"=>\".25c\")\n\n    self\n  end\n\n  def set_color(color)\n    @swatch[\"background\"] = color\n    @value[\"text\"] = color\n  end\nend\n\n\n\n# ʤΥե졼\nclass TkColorMiddleFrame<TkFrame\n  attr_reader :left, :middle, :right\n\n  def initialize(parent)\n    super(parent,\n\t  \"relief\"=> \"raised\",\n\t  \"borderwidth\"=> \"2\")\n\n    @left = TkColorMiddleLeftFrame.new(self)\n    @left.pack(\"side\"=>\"left\",\"padx\"=>\".25c\",\"pady\"=>\".25c\")\n\n    @middle = TkColorMiddleMiddleFrame.new(self)\n    @middle.pack(\"side\"=>\"left\",\"expand\"=>\"yes\",\"fill\"=>\"y\")\n\n    @right = TkColorMiddleRightFrame.new(self)\n    @right.pack(\"side\"=>\"left\",\"padx\"=>\".25c\",\"pady\"=>\".25c\",\"anchor\"=>\"s\")\n\n    self\n  end\nend\n\n\nclass TkColor<TkRoot\n  attr_reader :menu, :bottom, :middle\n\n  def initialize(*args)\n    super(*args)\n    @menu = TkColorMenuFrame.new(self)\n    @menu.pack(\"side\"=>\"top\", \"fill\"=>\"x\")\n\n    @bottom = TkColorBotFrame.new(self)\n    @bottom.pack(\"side\"=>\"bottom\",\"fill\"=>\"x\")\n\n    @middle = TkColorMiddleFrame.new(self)\n    @middle.pack(\"side\"=>\"top\",\"fill\"=>\"both\")\n\n    self\n  end\nend\n\n\n$root = TkColor.new\n\n# ٥ȤԤİ٤˥롼פ롣\nchangeColorSpace :rgb\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/text.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# text (basic facilities) widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($text_demo) && $text_demo\n  $text_demo.destroy \n  $text_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$text_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Basic Facilities\")\n  iconname(\"text\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($text_demo).pack(:fill=>:both, :expand=>true)\n\n# version check\nif ((Tk::TK_VERSION.split('.').collect{|n| n.to_i} <=> [8,4]) < 0)\n  undo_support = false\nelse\n  undo_support = true\nend\n\n# frame \nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $text_demo\n      $text_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'text'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# text \nTkText.new(base_frame){|t|\n  # \n  relief 'sunken'\n  bd 2\n  setgrid 1\n  height 30\n  TkScrollbar.new(base_frame) {|s|\n    pack('side'=>'right', 'fill'=>'y')\n    command proc{|*args| t.yview(*args)}\n    t.yscrollcommand proc{|first,last| s.set first,last}\n  }\n  pack('expand'=>'yes', 'fill'=>'both')\n\n  # ƥ\n  insert('0.0', <<EOT)\nΥɥϥƥ widget Ǥ1ԤޤϤʾΥƥȤɽ\nԽ뤳ȤǤޤʲϥƥ widget ǤǤˤĤ\nޤȤ᤿ΤǤ\n\n1. 롣СǥƥȤɽʬưȤǤޤ\n\n2. ˥󥰡ƥȤΥɥǥޥܥ2 (ܥ) \nƾ岼˥ɥåƤȥƥȤ®ǥɥå졢\nƤ򤶤äį뤳ȤǤޤ\n\n3. ƥȤޥܥ1 (ܥ) 򲡤򥻥\nȤƤƥȤϤƤϤΤ widget ޤ\n\n4. 򡣤ϰϤʸ򤹤ˤϥޥܥ1 򲡤ɥå\nƤ٥ܥΥ顢եȥ򲡤ʤܥ1 򲡤\nȤϰϤĴǤޤϰϤκǸޥ\nǤᤤ֤˥ꥻåȤܥΥ˥ޥɥå뤳ȤǤ\nϰϤĴǤޤ֥륯åǥɤ򡢤ޤȥץ륯\nǹΤ򤹤뤳ȤǤޤ\n\n5. õִƥȤõˤϡõʸ򤷤ƥХå\nڡǥ꡼ȥϤƤ뤤ϡƥȤ\nϤ򤵤줿ƥȤִޤ\n\n6. ʬΥԡʬ򤳤ΥɥΤɤ˥ԡ\nˤϡޤԡ(ǡ뤤̤Υץꥱ)\nܥ 2 򥯥åơΰ֤˥ԡƤ\n\n7. Խƥ widget  Emacs ΥХɤ˲äɸŪʤ Motif\nԽǽ򥵥ݡȤƤޤХåڡȥȥ-H \nκ¦ʸޤǥ꡼ȥȥȥ-D \nα¦ʸޤMeta-Хåڡ\n¦ñMeta-D κ¦ñޤ\nȥ-K 뤫ޤǤΰ֤˲\nʤäϡԤޤ#{\n      if undo_support\n        undo_text = \"Control-z ϺǸ˹Ԥäѹμä(undo)Ԥ\"\n        case $tk_platform['platform']\n        when \"unix\", \"macintosh\"\n          undo_text << \"Control-Shift-z\"\n        else # 'windows'\n          undo_text << \"Control-y\"\n        end\n        undo_text << \"undoѹκŬ(redo)Ԥޤ\"\n      else\n        \"\"\n      end\n}\n\n\n8. ɥΥꥵ widget  \"setGrid\" ץ򥪥ˤ\nƤޤΤǡɥꥵˤϹ⤵Ͼʸʸ\nܤˤʤޤޤɥ򶹤ˤĹԤư\nŪޤ֤졢ƤƤ褦ˤʤäƤޤ\nEOT\n\n  set_insert('0.0')\n}\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/textpeer.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# text widget peering demo (called by 'widget')\n#\n# based on Tcl/Tk8.5.0 widget demos\n\nif defined?($textpeer_demo) && $textpeer_demo\n  $textpeer_demo.destroy \n  $textpeer_demo = nil\nend\n\n# demo toplevel widget\n$textpeer_demo = TkToplevel.new {|w|\n  title(\"Text Wdget Peering Demonstration\")\n  iconname(\"textpeer\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($textpeer_demo).pack(:fill=>:both, :expand=>true)\n\ncount = [0]\n\n## Define a widget that we peer from; it won't ever actually be shown though\nfirst = TkText.new(base_frame, :widgetname=>\"text#{count[0] += 1}\")\nfirst.insert :end,\"ΥǥϰĤȤƥȥåȤ򼨤ޤ\"\nfirst.insert :end,\"ΥƥȥåȤ(ԥ;peer)δط\"\nfirst.insert :end,\"ʤäƤޤ\"\nfirst.insert :end,\"ϡפȤʤǡǥ϶̤ΤΤޤ\"\nfirst.insert :end,\"ɽ֡Խ֡ϰ(selection)ˤĤƤ\"\nfirst.insert :end,\"Ω˻ĤȤǤޤ\"\nfirst.insert :end,\"ƥƥȥåȤƤˤ\"\nfirst.insert :end,\"֥ԥ(peer)κץܥȤС\"\nfirst.insert :end,\"ʥԥɲä뤳ȤǽǤ\"\nfirst.insert :end,\"ޤ֥ԥ(peer)ξõץܥȤС\"\nfirst.insert :end,\"ΥԥåȤõ뤳ȤǤޤ\"\n\nTk.update_idletasks  ## for 'first' widget\n\n## Procedures to make and kill clones; most of this is just so that the demo\n## looks nice...\ndef makeClone(count, win, txt)\n  cnt = (count[0] += 1)\n  peer = TkText::Peer.new(txt, win, :widgetname=>\"text#{cnt}\")\n  sbar = TkScrollbar.new(win, :widgetname=>\"sb#{cnt}\")\n  peer.yscrollbar sbar\n  b1 = TkButton.new(win, :widgetname=>\"clone#{cnt}\", \n                    :text=>'ԥ(peer)κ', \n                    :command=>proc{makeClone(count, win, peer)})\n  b2 = TkButton.new(win, :widgetname=>\"kill#{cnt}\", \n                    :text=>'ԥ(peer)ξõ', \n                    :command=>proc{killClone(win, cnt)})\n  row = cnt * 2\n  TkGrid.configure(peer, sbar, b1, :sticky=>'nsew', :row=>row)\n  TkGrid.configure('^',  '^',  b2, :sticky=>'nsew', :row=>(row+=1))\n  TkGrid.configure(b1,  b2, :sticky=>'new')\n  TkGrid.rowconfigure(win,  b2, :weight=>1)\nend\n\ndef killClone(win, cnt)\n  Tk.destroy(\"#{win.path}.text#{cnt}\",  \"#{win.path}.sb#{cnt}\", \n             \"#{win.path}.clone#{cnt}\", \"#{win.path}.kill#{cnt}\")\nend\n\n## Now set up the GUI\nmakeClone(count, base_frame, first)\nmakeClone(count, base_frame, first)\nfirst.destroy\n\n## See Code / Dismiss buttons\nTkFrame.new(base_frame){|f|\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $textpeer_demo.destroy\n                 $textpeer_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'textpeer'\n               }).pack(:side=>:left, :expand=>true)\n\n  TkGrid.configure(f, '-', '-', :sticky=>'ew', :row=>5000)\n}\nTkGrid.columnconfigure(base_frame, 0, :weight=>1)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/timer",
    "content": "#!/usr/bin/env ruby\n#\n# timer --\n# This script generates a counter with start,stop and reset buttons.\n#\n# Copyright (C) 1998 Takaaki Tateishi (ttate@jaist.ac.jp)\n# last update: Sat Jun 27 12:24:14 JST 1998\n#\n\nrequire \"tk\"\nrequire \"thread\"\nrequire \"tkafter\"\n\n$time = \"0.00\"\n$m = Mutex.new\n$loop = false\n\ndef timer_stop\n  $loop = false\n  $m.lock\nend\n\ndef timer_start\n  $loop = true\n  $m.unlock\nend\n\ndef timer_reset\n  $time = \"0.00\"\n  $root.countframe.counter['text'] = $time\nend\n\ndef timer_loop\n  if $loop\n    $time = $time.succ\n    $root.countframe.counter['text'] = $time\n  end\n  Tk.after(10,proc{timer_loop})\nend\n\n\n#\n# thread version\n#\ndef timer_loop2\n  while true\n    $m.lock\n    $time = $time.succ\n    $root.countframe.counter['text'] = $time\n    sleep(0.01)\n    $m.unlock\n  end\nend\n\n#\n# TkAfter\n#\ndef timer_loop3\n  if $loop\n    $time = $time.succ\n    $root.countframe.counter['text'] = $time\n  end\nend\n\n\nclass CountFrame < TkFrame\n  attr_reader :counter\n\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n    @counter = TkLabel.new(self,\n\t\t\t   'text'=>$time, \n\t\t\t   'relief'=>'raised')\n    @counter.pack('fill'=>'both')\n    self\n  end\nend\n\n\nclass ButtonFrame < TkFrame\n  def initialize(parent=nil,keys=nil)\n    super(parent,keys)\n=begin\n    @stop = TkButton.new(self,\n\t\t\t 'text'=>'Stop',\n\t\t\t 'command'=>proc{timer_stop})\n    @start = TkButton.new(self,\n\t\t\t  'text'=>'Start',\n\t\t\t  'command'=>proc{timer_start})\n=end\n    @stop  = TkButton.new(self, :text=>'Stop',  :state=>:disabled)\n    @start = TkButton.new(self, :text=>'Start', :state=>:normal)\n\n    @stop.command proc{\n      timer_stop\n      @start.state(:normal)\n      @stop.state(:disabled)\n    }\n    @start.command proc{\n      timer_start\n      @stop.state(:normal)\n      @start.state(:disabled)\n    }\n\n    @reset = TkButton.new(self,\n\t\t\t  'text'=>'Reset',\n\t\t\t  'command'=>proc{timer_reset})\n    for b in [@stop,@start,@reset]\n      b.pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n    end\n  end\nend\n\n\nclass Timer < TkRoot\n  attr_reader :countframe\n\n  def initialize(*args)\n    super(*args)\n    @countframe = CountFrame.new(self)\n    @buttonframe = ButtonFrame.new(self)\n    for f in [@buttonframe,@countframe]\n      f.pack('side'=>'top', 'fill'=>'both')\n    end\n    self\n  end\nend\n\n\n$root = Timer.new\n\n#$thread = Thread.start{timer_loop2}\n#timer_loop\nTkAfter.new(10,-1,proc{timer_loop3}).start\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/toolbar.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# toolbar.rb --\n#\n# This demonstration script creates a toolbar that can be torn off.\n#\n# based on \"Id: toolbar.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($toolbar_demo) && $toolbar_demo\n  $toolbar_demo.destroy \n  $toolbar_demo = nil\nend\n\n$toolbar_demo = TkToplevel.new {|w|\n  title(\"Ttk Menu Buttons\")\n  iconname(\"toolbar\")\n  positionWindow(w)\n}\n\nbase_frame = Ttk::Frame.new($toolbar_demo).pack(:fill=>:both, :expand=>true)\n\nif Tk.windowingsystem != 'aqua'\n  msg = Ttk::Label.new(base_frame, :wraplength=>'4i', :text=><<EOL)\nΥǥǤϡġСɤΤ褦ˤŬڤ˥ơб뤫\\\nޤɤΤ褦ˤڤΥǽˤ뤫򼨤Ƥޤ\\\nʤġСڤΥˤTcl/Tk8.5ʾεǽɬפǤˡ\\\nġСΥܥϡ'Toolbutton'Ѥ褦뤳Ȥǡ\\\n\"toolbar style\"ܥȤʤ褦°ꤵƤޤ\\\nġСκüˤϴñʥޡ֤Ƥޤ\\\nޡ˥ޥ뤬Ȱư˥뤬Ѳޤ\\\nǥġСư褦˥ɥåȡ\\\nġСΤڤΥΩȥåץ٥륦åȤ\\\n뤳ȤǤޤ\\\nڤΥġСפȤʤäˤϡ\\\nŪʥȥåץ٥륦åȤƱͤñĤ뤳Ȥǡ\nƤӸΥɥĥդǤ礦\nEOL\nelse\n  msg = Ttk::Label.new(base_frame, :wraplength=>'4i', :text=><<EOL)\nΥǥǤϡġСɤΤ褦ˤŬڤ˥ơб뤫\\\nƤޤ\\\nġСΥܥϡ'Toolbutton'Ѥ褦뤳Ȥǡ\\\n\"toolbar style\"ܥȤʤ褦°ꤵƤޤ\nEOL\nend\n\n## Set up the toolbar hull\ntbar_base = Tk::Frame.new(base_frame,  # Tk ɸ frame ǤʤФʤޤ\n                          :widgetname=>'toolbar') # ɥȥʸȤ뤿ˡå̾Ƥޤ\nsep = Ttk::Separator.new(base_frame)\nto_base = Ttk::Frame.new(tbar_base, :cursor=>'fleur')\nif Tk.windowingsystem != 'aqua'\n  to  = Ttk::Separator.new(to_base, :orient=>:vertical)\n  to2 = Ttk::Separator.new(to_base, :orient=>:vertical)\n  to.pack(:fill=>:y, :expand=>true, :padx=>2, :side=>:left)\n  to2.pack(:fill=>:y, :expand=>true, :side=>:left)\nend\n\ncontents = Ttk::Frame.new(tbar_base)\nTk.grid(to_base, contents, :sticky=>'nsew')\ntbar_base.grid_columnconfigure(contents, :weight=>1)\ncontents.grid_columnconfigure(1000, :weight=>1)\n\nif Tk.windowingsystem != 'aqua'\n  ## Bindings so that the toolbar can be torn off and reattached\n  to_base.bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)}\n  to.     bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)}\n  to2.    bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)}\n  def tbar_base.tearoff(w, x, y)\n    on_win = TkWinfo.containing(x, y)\n    return unless (on_win && on_win.path =~ /^#{@path}(\\.|$)/)\n    self.grid_remove\n    w.grid_remove\n    self.wm_manage\n    # self.wm_title('Toolbar') # ⤷å̾򥦥ɥȥˤʤʤ顤ꤷƤ\n    self.wm_protocol('WM_DELETE_WINDOW'){ self.untearoff(self) }\n  end\n  def tbar_base.untearoff(w)\n    self.wm_forget\n    w.grid\n    self.grid\n  end\nend\n\n## Some content for the rest of the toplevel\ntext = TkText.new(base_frame, :width=>40, :height=>10)\n\n## Toolbar contents\ntb_btn = Ttk::Button.new(tbar_base, :text=>'ܥ', :style=>'Toolbutton', \n                         :command=>proc{\n                           text.insert(:end, \"ܥ󤬲ޤ\\n\")\n                         })\ntb_chk = Ttk::Checkbutton.new(tbar_base, :text=>'åܥ', \n                              :style=>'Toolbutton', \n                              :variable=>(check = TkVariable.new), \n                              :command=>proc{\n                                text.insert(:end, \"åܥͤ#{check.value}Ǥ\\n\")\n                              })\ntb_mbtn = Ttk::Menubutton.new(tbar_base, :text=>'˥塼')\ntb_combo = Ttk::Combobox.new(tbar_base, :value=>TkFont.families, \n                             :state=>:readonly)\ntb_mbtn.menu(menu = Tk::Menu.new(tb_mbtn))\nmenu.add(:command, :label=>'Just', :command=>proc{text.insert(:end, \"Just\\n\")})\nmenu.add(:command, :label=>'An', :command=>proc{text.insert(:end, \"An\\n\")})\nmenu.add(:command, :label=>'Example', \n         :command=>proc{text.insert(:end, \"Example\\n\")})\ntb_combo.bind('<ComboboxSelected>'){ text.font.family = tb_combo.get }\n\n## Arrange contents\nTk.grid(tb_btn, tb_chk, tb_mbtn, tb_combo, \n        :in=>contents, :padx=>2, :sticky=>'ns')\nTk.grid(tbar_base, :sticky=>'ew')\nTk.grid(sep, :sticky=>'ew')\nTk.grid(msg, :sticky=>'ew')\nTk.grid(text, :sticky=>'nsew')\nbase_frame.grid_rowconfigure(text, :weight=>1)\nbase_frame.grid_columnconfigure(text, :weight=>1)\n\n## See Code / Dismiss buttons\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'toolbar'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $toolbar_demo.destroy\n                           $toolbar_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  Tk.grid(frame, :sticky=>'ew')\n}\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/tree.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# tree.rb --\n#\n# This demonstration script creates a toplevel window containing a Ttk\n# tree widget.\n#\n# based on \"Id: tree.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($tree_demo) && $tree_demo\n  $tree_demo.destroy \n  $tree_demo = nil\nend\n\n$tree_demo = TkToplevel.new {|w|\n  title(\"Directory Browser\")\n  iconname(\"tree\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($tree_demo).pack(:fill=>:both, :expand=>true)\n\n## Explanatory text\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', \n               :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], \n               :text=><<EOL).pack(:fill=>:x)\nTtkȤϡơ޻ǽʿåȽǤ\\\nΥץϡե륷ƥΤ褦ʳŪʥǡ\\\nȤǤ褦ˤTtk::TreeviewåȤޤǤޤ\\\nTtk::TreeviewåȤϡڹ¤ΤɽǽˤǤʤ\\\nɲþ(Υץξϥե륵)ɽ뤿\\\nǤդθĿɲåⰷȤǤޤ\\\nޤΥȥ֤ζڤʬɥå뤳Ȥǡ\\\nѹ뤳ȤǽǤ\nEOL\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'tree'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $tree_demo.destroy\n                           $tree_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\n## Code to populate the roots of the tree (can be more than one on Windows)\ndef populate_roots(tree)\n  TkComm.simplelist(Tk.tk_call('file', 'volumes')).sort.each{|dir|\n    populate_tree(tree, tree.insert(nil, :end, :text=>dir, \n                                    :values=>[dir, 'directory']))\n  }\nend\n\n## Code to populate a node of the tree\ndef populate_tree(tree, node)\n  return if tree.get(node, :type) != 'directory'\n\n  path = tree.get(node, :fullpath)\n  tree.delete(tree.children(node))\n  Dir.glob(\"#{path}/*\").sort.each{|f|\n    type = File.ftype(f)\n    id = tree.insert(node, :end, \n                     :text=>File.basename(f), :values=>[f, type]).id\n    if type == 'directory'\n      ## Make it so that this node is openable\n      tree.insert(id, 0, :text=>'dummy')\n      tree.itemconfigure(id, :text=>File.basename(f))\n    elsif type == 'file'\n      size = File.size(f)\n      if size >= 1024*1024*1024\n        size = '%.1f GB' % (size.to_f/1024/1024/1024)\n      elsif size >= 1024*1024\n        size = '%.1f MB' % (size.to_f/1024/1024)\n      elsif size >= 1024\n        size = '%.1f KB' % (size.to_f/1024)\n      else\n        size = '%.1f bytes' % (size.to_f/1024)\n      end\n      tree.set(id, :size, size)\n    end\n  }\n\n  # Stop this code from rerunning on the current node\n  tree.set(node, :type, 'processed_directory')\nend\n\n## Create the tree and set it up\ntree = Ttk::Treeview.new(base_frame, :columns=>%w(fullpath type size), \n                         :displaycolumns=>['size'])\nif Tk.windowingsystem != 'aqua'\n  vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame))\nelse\n  vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame))\n  hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame))\nend\n\ntree.heading_configure('#0', :text=>'Directory Structure')\ntree.heading_configure('size', :text=>'File Size')\ntree.column_configure('size', :stretch=>0, :width=>70)\npopulate_roots(tree)\ntree.bind('<TreeviewOpen>', '%W'){|w| populate_tree(w, w.focus_item)}\n\n## Arrange the tree and its scrollbars in the toplevel\ncontainer = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\ncontainer.lower\nTk.grid(tree, vsb, :in=>container, :sticky=>'nsew')\nTk.grid(hsb,       :in=>container, :sticky=>'nsew')\ncontainer.grid_columnconfigure(0, :weight=>1)\ncontainer.grid_rowconfigure(0, :weight=>1)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ttkbut.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# ttkbut.rb\n#\n# This demonstration script creates a toplevel window containing several\n# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and\n# radiobuttons.\n#\n# based on \"Id: ttkbut.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkbut_demo) && $ttkbut_demo\n  $ttkbut_demo.destroy \n  $ttkbut_demo = nil\nend\n\n$ttkbut_demo = TkToplevel.new {|w|\n  title(\"Simple Ttk Widgets\")\n  iconname(\"ttkbut\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ttkbut_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nTtkȤϡơ޻ǽʿåȽǤ\\\nʤܤˤƤΤTtkΥơ޲٥ǡ\\\nˤTtkΥ٥ե졼˻ĤΥ롼פTtkåȤ\\\nɽƤޤ\nǽΥ롼פƥܥǤꡤ\\\n줾쥯åиߤΥץꥱΥơޤꤵޤ\nܤΥ롼פϻĤΥåܥ󽸹Ǥ\\\nƽδ֤ˤϡѥ졼åȤ֤Ƥޤ\\\nʤͭץܥϡΥȥåץ٥륦å\\\n¾Τ٤ƤΥơ޲åȤξ(state)\"disabled\"ɤ\\\nȥ뤹뤳ȤդƤ\nܤΥ롼פϴϢդ줿饸ܥ󽸹ȤʤäƤޤ\nEOL\n\n## Add buttons for setting the theme\nbuttons = Ttk::Labelframe.new(base_frame, :text=>'ܥ')\n# Ttk::Style.theme_names.each{|theme|\n#   Ttk::Button.new(buttons, :text=>theme, \n#                   :command=>proc{Ttk::Style.theme_use theme}).pack(:pady=>2)\n# }\nTtk.themes.each{|theme|\n  Ttk::Button.new(buttons, :text=>theme, \n                  :command=>proc{Ttk.set_theme theme}).pack(:pady=>2)\n}\n\n## Helper procedure for the top checkbutton\ndef setState(root, value, *excepts)\n  return if excepts.member?(root)\n\n  ## Non-Ttk widgets (e.g. the toplevel) will fail, so make it silent\n  begin\n    root.state = value\n  rescue\n  end\n\n  ## Recursively invoke on all children of this root that are in the same\n  ## toplevel widget\n  root.winfo_children.each{|w|\n    setState(w, value, *excepts) if w.winfo_toplevel == root.winfo_toplevel\n  }\nend\n\n## Set up the checkbutton group\nchecks = Ttk::Labelframe.new(base_frame, :text=>'åܥ')\nenabled = TkVariable.new(true)\ne = Ttk::Checkbutton.new(checks, :text=>'ͭ', :variable=>enabled, \n                         :command=>proc{\n                           setState($ttkbut_demo, \n                                    ((enabled.bool)? \"!disabled\" : \"disabled\"),\n                                    e)\n                         })\n\n## See ttk_widget(n) for other possible state flags\nsep1 = Ttk::Separator.new(checks)\nsep2 = Ttk::Separator.new(checks)\n\ncheese  = TkVariable.new\ntomato  = TkVariable.new\nbasil   = TkVariable.new\noregano = TkVariable.new\n\nc1 = Ttk::Checkbutton.new(checks, :text=>'',   :variable=>cheese)\nc2 = Ttk::Checkbutton.new(checks, :text=>'ȥޥ',   :variable=>tomato)\nc3 = Ttk::Checkbutton.new(checks, :text=>'Х',   :variable=>basil)\nc4 = Ttk::Checkbutton.new(checks, :text=>'쥬', :variable=>oregano)\n\nTk.pack(e, sep1, c1, c2, sep2, c3, c4, :fill=>:x, :pady=>2)\n\n## Set up the radiobutton group\nradios = Ttk::Labelframe.new(base_frame, :text=>'饸ܥ')\n\nhappyness = TkVariable.new\n\nr1 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Great', :value=>'great')\nr2 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Good', :value=>'good')\nr3 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Ok', :value=>'ok')\nr4 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Poor', :value=>'poor')\nr5 = Ttk::Radiobutton.new(radios, :variable=>happyness, \n                          :text=>'Awful', :value=>'awful')\n\nTk.pack(r1, r2, r3, r4, r5, :fill=>:x, :padx=>3, :pady=>2)\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ѿ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{\n                           showVars(base_frame, ['ͭ', enabled], \n                                    ['', cheese], ['ȥޥ', tomato], \n                                    ['Х', basil], ['쥬', oregano], \n                                    ['ʡ', happyness])\n                         }), \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkbut'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           tmppath = $ttkbut_demo\n                           $ttkbut_demo = nil\n                           $showVarsWin[tmppath.path] = nil\n                           tmppath.destroy\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x, :expand=>true)\n}\n\n## Arrange things neatly\nf = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\nf.lower\nTk.grid(buttons, checks, radios, :in=>f, :sticky=>'nwe', :pady=>2, :padx=>3)\nf.grid_columnconfigure([0, 1, 2], :weight=>1, :uniform=>:yes)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ttkmenu.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# ttkmenu.rb --\n#\n# This demonstration script creates a toplevel window containing several Ttk\n# menubutton widgets.\n#\n# based on \"Id: ttkmenu.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkmenu_demo) && $ttkmenu_demo\n  $ttkmenu_demo.destroy \n  $ttkmenu_demo = nil\nend\n\n$ttkmenu_demo = TkToplevel.new {|w|\n  title(\"Ttk Menu Buttons\")\n  iconname(\"ttkmenu\")\n  positionWindow(w)\n}\n\nbase_frame = Ttk::Frame.new($ttkmenu_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nTtkȤϡơ޻ǽʿåȽǤ\\\nˤơޤб뤳ȤǤ褦ˤʤäåȤΤҤȤĤ\\\n˥塼ܥ󤬤ޤ\\\nʲǤϡơޤб˥塼ܥ󤬤ĤɽƤޤ\\\nȤäơ߻Υơޤѹ뤳ȤǽǤ\\\nơޤ򤬥˥塼ܥ󼫿ȤθݤѲͻҤ䡤\\\nΥ˥塼ܥۤʤ륹\\\n(ġСǤΰŪɽŬ)ɽƤͻҤ\\\nܤƤ\\\nʤ˥塼ܥˤĤƤϥơޤбåȤޤ\\\n˥塼ˤĤƤϥơޤбåȤϴޤޤƤޤ\\\nͳϡɸTkΥ˥塼åȤ\\\n٤ƤΥץåȥۡǽʬɹʸݤäƤ롤\\\näˡ¿δĶǤδĶηϤȤʤ褦˼Ƥ\\\nȽǤ줿Ȥˤޤ\nEOL\n\nTtk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x)\n\n## See Code / Dismiss\nTtk::Frame.new($ttkmenu_demo) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkmenu'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttkmenu_demo.destroy\n                           $ttkmenu_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nb1 = Ttk::Menubutton.new(base_frame,:text=>'ơޤ',:direction=>:above)\nb2 = Ttk::Menubutton.new(base_frame,:text=>'ơޤ',:direction=>:left)\nb3 = Ttk::Menubutton.new(base_frame,:text=>'ơޤ',:direction=>:right)\nb4 = Ttk::Menubutton.new(base_frame,:text=>'ơޤ',:direction=>:flush,\n                         :style=>Ttk::Menubutton.style('Toolbutton'))\nb5 = Ttk::Menubutton.new(base_frame,:text=>'ơޤ',:direction=>:below)\n\nb1.menu(m1 = Tk::Menu.new(b1, :tearoff=>false))\nb2.menu(m2 = Tk::Menu.new(b2, :tearoff=>false))\nb3.menu(m3 = Tk::Menu.new(b3, :tearoff=>false))\nb4.menu(m4 = Tk::Menu.new(b4, :tearoff=>false))\nb5.menu(m5 = Tk::Menu.new(b5, :tearoff=>false))\n\nTtk.themes.each{|theme|\n  m1.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m2.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m3.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m4.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n  m5.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme})\n}\n\nf = Ttk::Frame.new(base_frame).pack(:fill=>:x)\nf1 = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\nf.lower\n\nf.grid_anchor(:center)\nTkGrid('x', b1, 'x', :in=>f, :padx=>3, :pady=>2)\nTkGrid(b2,  b4, b3,  :in=>f, :padx=>3, :pady=>2)\nTkGrid('x', b5, 'x', :in=>f, :padx=>3, :pady=>2)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ttknote.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# ttknote.rb --\n#\n# This demonstration script creates a toplevel window containing a Ttk\n# notebook widget.\n#\n# based on \"Id: ttknote.tcl,v 1.5 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttknote_demo) && $ttknote_demo\n  $ttknote_demo.destroy \n  $ttknote_demo = nil\nend\n\n$ttknote_demo = TkToplevel.new {|w|\n  title(\"Ttk Notebook Widget\")\n  iconname(\"ttknote\")\n  positionWindow(w)\n}\n\n## See Code / Dismiss\nTtk::Frame.new($ttknote_demo) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttknote'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttknote_demo.destroy\n                           $ttknote_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nbase_frame = Ttk::Frame.new($ttknote_demo).pack(:fill=>:both, :expand=>true)\n\n## Make the notebook and set up Ctrl+Tab traversal\nnotebook = Ttk::Notebook.new(base_frame).pack(:fill=>:both, :expand=>true, \n                                              :padx=>2, :pady=>3)\nnotebook.enable_traversal\n\n## Popuplate the first pane\nf_msg = Ttk::Frame.new(notebook)\nmsg_m = Ttk::Label.new(f_msg, :font=>$font, :wraplength=>'5i', \n                       :justify=>:left, :anchor=>'n', :text=><<EOL)\nTtkȤϡơ޻ǽʿåȽǤ\\\n˴ޤޤ륦åȤΤҤȤĤ˥Ρȥ֥ååȤޤ\\\nΡȥ֥ååȤϡ\\\n̤Ƥäѥͥ뤫ǽˤ褦\\\n֤νʥ֥åȡˤޤ\\\n֥åȤϺǶ¿Υ桼󥿡եǸ뵡ǽǤ\\\n֤ϡޥˤǤʤ\\\nΡȥ֥ååȤΥڡθФ򤵤ƤǤ\\\nCtrl+TabϤˤäƤԤȤǤޤ\\\nΥǥǤϡФǲդʸΥAltȤȤ߹碌뤳Ȥ\\\nڡ򤹤뤳ȤǤ褦ˤꤷƤޤ\\\nܤΥ̵֤Ǥʤ褦ˤʤäƤ뤳Ȥˤ\\\nդƤ\nEOL\nneat = TkVariable.new\nafter_id = nil\nmsg_b = Ttk::Button.new(f_msg, :text=>'Ƥ(Neat!)', :underline=>6, \n                        :command=>proc{\n                          neat.value = 'ΤȤꤵ'\n                          Tk.after_cancel(after_id) if after_id\n                          after_id = Tk.after(500){neat.value = ''}\n                        })\nmsg_b.winfo_toplevel.bind('Alt-n'){ msg_b.focus; msg_b.invoke }\nmsg_l = Ttk::Label.new(f_msg, :textvariable=>neat)\nnotebook.add(f_msg, :text=>'(Description)', :underline=>3, :padding=>2)\nTk.grid(msg_m, '-', :sticky=>'new', :pady=>2)\nTk.grid(msg_b, msg_l, :pady=>[2, 4], :padx=>20)\nmsg_b.grid_configure(:sticky=>'e')\nmsg_l.grid_configure(:sticky=>'w')\nf_msg.grid_rowconfigure(1, :weight=>1)\nf_msg.grid_columnconfigure([0, 1], :weight=>1, :uniform=>1)\n\n## Populate the second pane. Note that the content doesn't really matter\nf_disabled = Ttk::Frame.new(notebook)\nnotebook.add(f_disabled, :text=>'̵줿', :state=>:disabled)\n\n## Popuplate the third pane\nf_editor = Ttk::Frame.new(notebook)\nnotebook.add(f_editor, :text=>'ƥȥǥ(Text Editor)', :underline=>9)\neditor_t = Tk::Text.new(f_editor, :width=>40, :height=>10, :wrap=>:char)\nif Tk.windowingsystem != 'aqua'\n  editor_s = editor_t.yscrollbar(Ttk::Scrollbar.new(f_editor))\nelse\n  editor_s = editor_t.yscrollbar(Tk::Scrollbar.new(f_editor))\nend\neditor_s.pack(:side=>:right, :fill=>:y, :padx=>[0,2], :pady=>2)\neditor_t.pack(:fill=>:both, :expand=>true, :padx=>[2,0], :pady=>2)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ttkpane.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# ttkpane.rb --\n#\n# This demonstration script creates a Ttk pane with some content.\n#\n# based on \"Id: ttkpane.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkpane_demo) && $ttkpane_demo\n  $ttkpane_demo.destroy \n  $ttkpane_demo = nil\nend\n\n$ttkpane_demo = TkToplevel.new {|w|\n  title(\"Themed Nested Panes\")\n  iconname(\"ttkpane\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ttkpane_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nΥǥϡߴطˤơդڥɥɥ򼨤Ƥޤ\\\n줾礭ϡޤޤƤڥδ֤ˤ륨ꥢĤ\\\nɥå뤳ȤѹǤޤ\nEOL\n\nTtk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x)\n\n## See Code / Dismiss\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkpane'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttkpane_demo.destroy\n                           $ttkpane_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nframe = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\nouter = Ttk::Panedwindow.new(frame, :orient=>:horizontal)\nouter.add(in_left = Ttk::Panedwindow.new(outer, :orient=>:vertical))\nouter.add(in_right = Ttk::Panedwindow.new(outer, :orient=>:vertical))\nin_left.add(left_top = Ttk::Labelframe.new(in_left, :text=>'ܥ'))\nin_left.add(left_bot = Ttk::Labelframe.new(in_left, :text=>''))\nin_right.add(right_top = Ttk::Labelframe.new(in_right, :text=>'ץ쥹'))\nin_right.add(right_bot = Ttk::Labelframe.new(in_right, :text=>'ƥ'))\nif Tk.windowingsystem == 'aqua'\n  [left_top, left_bot, right_top, right_bot].each{|w| w.padding(3) }\nend\n\n# Fill the button pane\nTtk::Button.new(left_top, :text=>'Ƥ', \n                :command=>proc{\n                  Tk.messageBox(:type=>'ok', :icon=>'info', \n                                :message=>'Ƥơ', \n                                :detail=>'That hurt...', :parent=>base_frame, \n                                :title=>'Button Pressed')\n                }).pack(:padx=>2, :pady=>5)\n\n\nzones_list = [\n  [':Europe/Berlin'], \n  [':America/Argentina/Buenos_Aires', ':America/Buenos_Aires'], \n  [':Africa/Johannesburg'], \n  [':Europe/London'], \n  [':America/Los_Angeles'], \n  [':Europe/Moscow'],\n  [':America/New_York'], \n  [':Asia/Singapore'], \n  [':Australia/Sydney'], \n  [':Asia/Tokyo'], \n]\n\nzones = []\n\n# Check tzinfo support\nif $tk_major_ver > 8 || ($tk_major_ver == 8 && $tk_minor_ver >= 5)\n  tzinfo = :tcl\n\n  zones_list.each{|list|\n    list.each{|zone|\n      begin\n        # Force a pre-load of all the timezones needed; otherwise can end up\n        # poor-looking synch problems!\n        Tk.tk_call('clock', 'format', '0', '-timezone', zone)\n      rescue RuntimeError\n        # ignore\n      else\n        zones << [zone, zone[%r<[^/:]+$>].tr('_', ' ')]\n        break\n      end\n    }\n  }\n\nelse\n  begin\n    require 'tzinfo'\n    tzinfo = :tzinfo\n  rescue Exception\n    begin\n      require 'tzfile'\n      tzinfo = :tzfile\n    rescue Exception\n      tzinfo = nil\n    end\n  end\n\n  case tzinfo\n  when :tzinfo\n    zones_list.each{|list|\n      list.each{|zone|\n        begin\n          tz = TZInfo::Timezone.get(zone[%r<[^:]+$>])\n        rescue Exception\n          # ignore\n        else\n          zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')]\n          break\n        end\n      }\n    }\n\n  when :tzfile\n    zones_list.each{|list|\n      list.each{|zone|\n        begin\n          tz = TZFile.create(zone[%r<[^:]+$>])\n        rescue Exception\n          # ignore\n        else\n          zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')]\n          break\n        end\n      }\n    }\n\n  else\n    [ -7, -4, -2, -1, 0, +1, +3, +8, +9, +10 ].each{|zone|\n      zones << [zone, 'UTC%+03d00' % zone]\n    }\n  end\nend\n\ntime = TkVariable.new_hash\n\ncase tzinfo\nwhen :tcl\n  update_proc = proc{|now, tz, label|\n    time[label] = Tk.tk_call('clock', 'format', now.tv_sec, \n                             '-timezone', tz, '-format', '%T')\n  }\nwhen :tzinfo\n  update_proc = proc{|now, tz, label|\n    time[label] = tz.utc_to_local(now).strftime('%H:%M:%S')\n  }\nwhen :tzfile\n  update_proc = proc{|now, tz, label|\n    time[label] = tz.at(now.tv_sec).strftime('%H:%M:%S')\n  }\nelse\n  update_proc = proc{|now, tz, label|\n    time[label] = (now + (tz * 3600)).strftime('%H:%M:%S')\n  }\nend\n\n# Fill the clocks pane\nzones.each_with_index{|(zone, label), idx|\n  Ttk::Separator.new(left_bot).pack(:fill=>:x) if idx > 0\n  Ttk::Label.new(left_bot, :text=>label, :anchor=>'w').pack(:fill=>:x)\n  Ttk::Label.new(left_bot, :textvariable=>time.ref(label), \n                 :anchor=>'w').pack(:fill=>:x)\n}\n\n# Timer start\nevery = proc{\n  now = Time.now.utc\n  zones.each{|zone, label| update_proc.call(now, zone, label) }\n}\nTkRTTimer.new(1000, -1, every).start(0, every)\n\n# Fill the progress pane\nTtk::Progressbar.new(right_top, :mode=>:indeterminate).pack(:fill=>:both, :expand=>true).start\n\n# Fill the text pane\nif Tk.windowingsystem != 'aqua'\n  # The trick with the ttk::frame makes the text widget look like it fits with\n  # the current Ttk theme despite not being a themed widget itself. It is done\n  # by styling the frame like an entry, turning off the border in the text\n  # widget, and putting the text widget in the frame with enough space to allow\n  # the surrounding border to show through (2 pixels seems to be enough).\n  f = Ttk::Frame.new(right_bot, :style=>Ttk::Entry)\n  txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0)\n  txt.pack(:fill=>:both, :expand=>true, :in=>f, :pady=>2, :padx=>2)\n  scr = txt.yscrollbar(Ttk::Scrollbar.new(frame))\n  scr.pack(:side=>:right, :fill=>:y, :in=>right_bot)\n  f.pack(:fill=>:both, :expand=>true)\n  outer.pack(:fill=>:both, :expand=>true)\nelse\n  txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0)\n  scr = txt.yscrollbar(TkScrollbar.new(frame))\n  scr.pack(:side=>:right, :fill=>:y, :in=>right_bot)\n  txt.pack(:fill=>:both, :expand=>true, :in=>right_bot)\n  outer.pack(:fill=>:both, :expand=>true, :padx=>10, :pady=>[6, 10])\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/ttkprogress.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# ttkprogress.rb --\n#\n# This demonstration script creates several progress bar widgets.\n#\n# based on \"Id: ttkprogress.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp\"\n\nif defined?($ttkprogress_demo) && $ttkprogress_demo\n  $ttkprogress_demo.destroy \n  $ttkprogress_demo = nil\nend\n\n$ttkprogress_demo = TkToplevel.new {|w|\n  title(\"Progress Bar Demonstration\")\n  iconname(\"ttkprogress\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($ttkprogress_demo).pack(:fill=>:both, :expand=>true)\n\nTtk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, \n               :text=><<EOL).pack(:side=>:top, :fill=>:x)\nˤΤĤΥץ쥹СǤ\\\nΤΤ\"determinate\"פΥץ쥹Сǡ\\\n㤨ХץबͿ줿λޤǤˤɤΤ餤뤫\\\nȤʤɤѤޤ\\\nΤΤ\"indeterminate\"פΥץ쥹Сǡ\\\n㤨Хץब¹(busy)ǤΤ\\\nλޤǤˤɤ줯餤뤫ʬʤȤ֤\\\nȤʤɤѤޤ\\\nΥץ쥹С⡤ˤܥȤȤ\\\nư˥᡼⡼ɤON/OFFؤ뤳ȤǤޤ\nEOL\n\n## See Code / Dismiss buttons\nTtk::Frame.new(base_frame) {|frame|\n  sep = Ttk::Separator.new(frame)\n  Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         Ttk::Button.new(frame, :text=>'ɻ', \n                         :image=>$image['view'], :compound=>:left, \n                         :command=>proc{showCode 'ttkprogress'}), \n         Ttk::Button.new(frame, :text=>'Ĥ', \n                         :image=>$image['delete'], :compound=>:left, \n                         :command=>proc{\n                           $ttkprogress_demo.destroy\n                           $ttkprogress_demo = nil\n                         }), \n         :padx=>4, :pady=>4)\n  grid_columnconfigure(0, :weight=>1)\n  pack(:side=>:bottom, :fill=>:x)\n}\n\nframe = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true)\n\np1 = Ttk::Progressbar.new(frame, :mode=>:determinate)\np2 = Ttk::Progressbar.new(frame, :mode=>:indeterminate)\n\nstart = Ttk::Button.new(frame, :text=>'Start Progress', \n                        :command=>proc{ p1.start; p2.start })\nstop  = Ttk::Button.new(frame, :text=>'Stop Progress', \n                        :command=>proc{ p1.stop; p2.stop })\n\nTk.grid(p1, '-', :pady=>5, :padx=>10)\nTk.grid(p2, '-', :pady=>5, :padx=>10)\nTk.grid(start, stop, :padx=>10, :pady=>5)\nstart.grid_configure(:sticky=>'e')\nstop.grid_configure(:sticky=>'w')\nframe.grid_columnconfigure(:all, :weight=>1)\n\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/twind.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# text (embedded windows) widget demo (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($twind_demo) && $twind_demo\n  $twind_demo.destroy \n  $twind_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$twind_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Embedded Windows\")\n  iconname(\"Embedded Windows\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($twind_demo).pack(:fill=>:both, :expand=>true)\n\n# frame \n$twind_buttons = TkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc{\n      tmppath = $twind_demo\n      $twind_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc{showCode 'twind'}\n  }.pack('side'=>'left', 'expand'=>'yes')\n}\n$twind_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \n$twind_text = nil\nTkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, \n            'relief'=>'sunken') {|f|\n  $twind_text = TkText.new(f, 'setgrid'=>'true', 'font'=>$font, \n                          'width'=>'70', 'height'=>35, 'wrap'=>'word', \n                          'highlightthickness'=>0, 'borderwidth'=>0 ){|t|\n    TkScrollbar.new(f) {|s|\n      command proc{|*args| t.yview(*args)}\n      t.yscrollcommand proc{|first,last| s.set first,last}\n    }.pack('side'=>'right', 'fill'=>'y')\n  }.pack('expand'=>'yes', 'fill'=>'both')\n}.pack('expand'=>'yes', 'fill'=>'both')\n\n# \n$tag_center = TkTextTag.new($twind_text, \n                            'justify' =>'center',\n                            'spacing1'=>'5m',\n                            'spacing3'=>'5m'  )\n$tag_buttons = TkTextTag.new($twind_text, \n                             'lmargin1'=>'1c',\n                             'lmargin2'=>'1c',\n                             'rmargin' =>'1c',\n                             'spacing1'=>'3m',\n                             'spacing2'=>0,\n                             'spacing3'=>0 )\n\n# ƥȤ\n$twind_text.insert('end', \n                  'ƥwidget¾widgetȤ߹ळȤǤޤ')\n$twind_text.insert('end',\n                  'Ȥ߹ߥɥȸƤФ졢ǤդwidgetǽǤ')\n$twind_text.insert('end',\n                  '㤨С2ĤΥܥwidgetȤ߹ޤƤޤ')\n$twind_text.insert('end', 'ǽΥܥ򥯥åȿʿΥ')\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   #text 'ON'\n                   text ''\n                   command proc{textWindOn $twind_text,$twind_buttons}\n                   cursor 'top_left_arrow'\n                 })\n$twind_text.insert('end', \"ˤޤޤ2ĤΥܥ򥯥å\\n\")\n$twind_text.insert('end', 'ʿΥ')\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   #text 'OFF'\n                   text ''\n                   command proc{textWindOff $twind_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind_text.insert('end', 'ˤޤ')\n\n$twind_text.insert('end', '⤦ҤȤĤǤ')\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   text '򥯥å'\n                   command proc{textWindPlot $twind_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind_text.insert('end', 'ȡx-yץåȤ˸ޤ')\n$mark_plot = TkTextMark.new($twind_text, 'insert')\n$mark_plot.gravity='left'\n$twind_text.insert('end', 'ޥǥǡ褹뤳ȤǤޤ')\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {\n                   text 'õ'\n                   command proc{textWindDel $twind_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind_text.insert('end', '򥯥åȸޤ\n\n')\n\n$twind_text.insert('end', 'Ȥ߹ߥɥƥwidgetˡºݤ')\n$twind_text.insert('end', 'ƥȤϤʤȤ߹ळȤǤ')\n$twind_text.insert('end', 'ξϡƥwidgetϥɥޥ͡')\n$twind_text.insert('end', '褦ưޤ㤨Сˤϥƥwidget')\n$twind_text.insert('end', 'äƥܥ󤬤줤¤٤Ƥޤ')\n$twind_text.insert('end', 'ΥܥطʿѤ뤳ȤǤޤ')\n$twind_text.insert('end', '(\"Default\"Ǹο᤹ȤǤޤ)')\n$twind_text.insert('end', '\"Short\"Ȥܥ򥯥åʸĹ')\n$twind_text.insert('end', 'ѤޤȼưŪ˥ƥwidget')\n$twind_text.insert('end', '쥤ȤƤޤ')\n$twind_text.insert('end', '⤦Ʊܥ򲡤ȸޤ\n\n')\n\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkButton.new($twind_text) {|b|\n                   text 'ǥե'\n                   command proc{embDefBg $twind_text}\n                   cursor 'top_left_arrow'\n                   $tag_buttons.add('end')\n                 },\n                 'padx'=>3 )\nembToggle = TkVariable.new('Short')\nTkTextWindow.new($twind_text, 'end', \n                 'window'=>TkCheckButton.new($twind_text) {\n                   textvariable embToggle\n                   indicatoron 0\n                   variable embToggle\n                   onvalue 'A much longer string'\n                   offvalue 'Short'\n                   cursor 'top_left_arrow'\n                   pady 5\n                   padx 2\n                 },\n                 'padx'=>3, \n                 'pady'=>2 )\n\n[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4', \n  'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1', \n  'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1', \n  'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4' \n].each{|twind_color|\n  TkTextWindow.new($twind_text, 'end', \n                   'window'=>TkButton.new($twind_text) {\n                     text twind_color\n                     cursor 'top_left_arrow'\n                     command proc{$twind_text.bg twind_color}\n                   },\n                   'padx'=>3, \n                   'pady'=>2 )\n}\n\n# ᥽å\ndef textWindOn (w,f)\n  if defined? $twind_scroll\n    begin\n      $twind_scroll.destroy\n    rescue\n    end\n    $twind_scroll = nil\n  end\n\n  base = TkWinfo.parent( TkWinfo.parent(w) )\n  $twind_scroll = TkScrollbar.new(base) {|s|\n    orient 'horizontal'\n    command proc{|*args| w.xview(*args)}\n    w.xscrollcommand proc{|first,last| s.set first,last}\n    w.wrap 'none'\n    pack('after'=>f, 'side'=>'bottom', 'fill'=>'x')\n  }\n\n  return nil\nend\n\ndef textWindOff (w)\n  if defined? $twind_scroll\n    begin\n      $twind_scroll.destroy\n    rescue\n    end\n    $twind_scroll = nil\n  end\n  w.xscrollcommand ''\n  w.wrap 'word'\nend\n\ndef textWindPlot (t)\n  if (defined? $twind_plot) && (TkWinfo.exist?($twind_plot))\n    return\n  end\n\n  $twind_plot = TkCanvas.new(t) {\n    relief 'sunken'\n    width  450\n    height 300\n    cursor 'top_left_arrow'\n  }\n\n  if $tk_version =~ /^4.*/\n    font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'\n  else\n    font = 'Helvetica 18'\n  end\n\n  TkcLine.new($twind_plot, 100, 250, 400, 250, 'width'=>2)\n  TkcLine.new($twind_plot, 100, 250, 100,  50, 'width'=>2)\n  TkcText.new($twind_plot, 225, 20, \n              'text'=>\"A Simple Plot\", 'font'=>font, 'fill'=>'brown')\n\n  (0..10).each {|i|\n    x = 100 + (i * 30)\n    TkcLine.new($twind_plot, x, 250, x, 245, 'width'=>2)\n    TkcText.new($twind_plot, x, 254, \n                'text'=>10*i, 'font'=>font, 'anchor'=>'n')\n  }\n  (0..5).each {|i|\n    y = 250 - (i * 40)\n    TkcLine.new($twind_plot, 100, y, 105, y, 'width'=>2)\n    TkcText.new($twind_plot, 96, y, \n                'text'=>\"#{i*50}.0\", 'font'=>font, 'anchor'=>'e')\n  }\n\n  for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]\n    x = 100 + (3*xx)\n    y = 250 - (4*yy)/5\n    item = TkcOval.new($twind_plot, x-6, y-6, x+6, y+6, \n                       'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')\n    item.addtag 'point'\n  end\n\n  $twind_plot.itembind('point', 'Any-Enter', \n                        proc{$twind_plot.itemconfigure 'current', 'fill', 'red'})\n  $twind_plot.itembind('point', 'Any-Leave', \n                        proc{$twind_plot.itemconfigure 'current', 'fill', 'SkyBlue2'})\n  $twind_plot.itembind('point', '1', \n                        proc{|x,y| embPlotDown $twind_plot,x,y}, \"%x %y\")\n  $twind_plot.itembind('point', 'ButtonRelease-1', \n                        proc{$twind_plot.dtag 'selected'})\n  $twind_plot.bind('B1-Motion', \n                    proc{|x,y| embPlotMove $twind_plot,x,y}, \"%x %y\")\n  while ($twind_text.get($mark_plot) =~ /[ \\t\\n]/)\n    $twind_text.delete $mark_plot\n  end\n  $twind_text.insert $mark_plot,\"\\n\"\n  TkTextWindow.new($twind_text, $mark_plot, 'window'=>$twind_plot)\n  $tag_center.add $mark_plot\n  $twind_text.insert $mark_plot,\"\\n\"\nend\n\n$embPlot = {'lastX'=>0, 'lastY'=>0}\n\ndef embPlotDown (w, x, y)\n  w.dtag 'selected'\n  w.addtag_withtag 'selected', 'current'\n  w.raise 'current'\n  $embPlot['lastX'] = x\n  $embPlot['lastY'] = y\nend\n\ndef embPlotMove (w, x, y)\n  w.move 'selected', x - $embPlot['lastX'], y - $embPlot['lastY']\n  $embPlot['lastX'] = x\n  $embPlot['lastY'] = y\nend\n\ndef textWindDel (w)\n  if (defined? $twind_text) && TkWinfo.exist?($twind_plot)\n    $twind_text.delete $twind_plot\n    $twind_plot = nil\n    while ($twind_text.get($mark_plot) =~ /[ \\t\\n]/)\n      $twind_text.delete $mark_plot\n    end\n    $twind_text.insert $mark_plot,\"  \"\n  end\nend\n\ndef embDefBg (w)\n  w['background'] = w.configinfo('background')[3]\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/twind2.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# text (embedded windows) widget demo 2 (called by 'widget')\n#\n\n# toplevel widget ¸ߤк\nif defined?($twind2_demo) && $twind2_demo\n  $twind2_demo.destroy \n  $twind2_demo = nil\nend\n\n# demo Ѥ toplevel widget \n$twind2_demo = TkToplevel.new {|w|\n  title(\"Text Demonstration - Embedded Windows 2\")\n  iconname(\"Embedded Windows\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($twind2_demo).pack(:fill=>:both, :expand=>true)\n\n# frame \n$twind2_buttons = TkFrame.new(base_frame) {|frame|\n  TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), \n         :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2)\n  TkGrid('x', \n         TkButton.new(frame, :text=>'ɻ', \n                      :image=>$image['view'], :compound=>:left, \n                      :command=>proc{showCode 'twind2'}), \n         TkButton.new(frame, :text=>'Ĥ', \n                      :image=>$image['delete'], :compound=>:left, \n                      :command=>proc{\n                        tmppath = $twind2_demo\n                        $twind2_demo = nil\n                        $showVarsWin[tmppath.path] = nil\n                        tmppath.destroy\n                      }), \n         :padx=>4, :pady=>4)\n  frame.grid_columnconfigure(0, :weight=>1)\n}\n$twind2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\n# frame \n$twind2_text = nil\nTkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, \n            'relief'=>'sunken') {|f|\n  $twind2_text = TkText.new(f, 'setgrid'=>true, 'font'=>$font,\n                            # 'width'=>'70', 'height'=>35, 'wrap'=>'word', \n                            'width'=>'70', 'height'=>35, 'wrap'=>'char', \n                            'highlightthickness'=>0, 'borderwidth'=>0 ){|t|\n    TkScrollbar.new(f) {|s|\n      command proc{|*args| t.yview(*args)}\n      t.yscrollcommand proc{|first,last| s.set first,last}\n    }.pack('side'=>'right', 'fill'=>'y')\n  }.pack('expand'=>'yes', 'fill'=>'both')\n}.pack('expand'=>'yes', 'fill'=>'both')\n\n# \n$tag2_center = TkTextTag.new($twind2_text, \n                            'justify' =>'center',\n                            'spacing1'=>'5m',\n                            'spacing3'=>'5m'  )\n$tag2_buttons = TkTextTag.new($twind2_text, \n                             'lmargin1'=>'1c',\n                             'lmargin2'=>'1c',\n                             'rmargin' =>'1c',\n                             'spacing1'=>'3m',\n                             'spacing2'=>0,\n                             'spacing3'=>0 )\n\n# ƥȤ\n$twind2_text.insert('end', 'ƥȥåȤˤϿʼΥƥ')\n$twind2_text.insert('end', 'ưŪʤΤŪʤΤξޤˤ')\n$twind2_text.insert('end', '¿ޤ뤳ȤǤޤƥ')\n$twind2_text.insert('end', 'ؤ֡·ʤɤ͡ˡ')\n$twind2_text.insert('end', '֤뤳ȤǤޤ')\n$twind2_text.insert('end', 'äơƥȥåȤʪ')\n$twind2_text.insert('end', 'ɥ٤礭Ǥ')\n$twind2_text.insert('end', '٤Ƥ˥ࡼ˥뤵')\n$twind2_text.insert('end', 'ǧ뤳ȤǽǤ')\n$twind2_text.insert('end', \"\\n\\n\")\n$twind2_text.insert('end', 'ƥȥåȾˤ¾ΥåȤ')\n$twind2_text.insert('end', 'ޤ뤳ȤǤޤΤ')\n$twind2_text.insert('end', 'ߥɥפȸƤФ졢')\n$twind2_text.insert('end', 'ʤ륦åȤǤͤळȤǤޤ')\n$twind2_text.insert('end', '㤨СˤϣĤ')\n$twind2_text.insert('end', 'ܥ󥦥åȤޤƤޤ')\n$twind2_text.insert('end', 'ǽΥܥ򥯥åȡ')\n$twind2_text.insert('end', 'ʿΥ ')\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   #text 'ON'\n                   text ''\n                   command proc{textWindOn2 $twind2_text,$twind2_buttons}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', \"ˤޤޤĤΥܥ򥯥å\\n\")\n$twind2_text.insert('end', 'ʿΥ')\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   #text 'OFF'\n                   text ''\n                   command proc{textWindOff2 $twind2_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', \"ˤޤ\\n\\n\")\n\n$twind2_text.insert('end', 'Ϥ⤦ҤȤĤǤ')\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   text '򥯥å'\n                   command proc{textWindPlot2 $twind2_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', 'ȡx-yץåȤ˸ޤ')\n$mark2_plot = TkTextMark.new($twind2_text, 'insert')\n$mark2_plot.gravity='left'\n$twind2_text.insert('end', 'ޥǥɥå뤳Ȥǡ')\n$twind2_text.insert('end', 'ץåȾΥǡư뤳ȤǤޤ')\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text) {\n                   text 'õ'\n                   command proc{textWindDel2 $twind2_text}\n                   cursor 'top_left_arrow'\n                 })\n$twind2_text.insert('end', '򥯥åȸޤ')\n$twind2_text.insert('end', \"\\n\\n\")\n\n$twind2_text.insert('end', 'ɽƥȤʤߥɥ')\n$twind2_text.insert('end', 'ƥȥåȤ˴ޤ뤳ȤͭѤǤ礦')\n$twind2_text.insert('end', 'ξ硢ƥȥåȤ')\n$twind2_text.insert('end', 'ȥޥ͡Τ褦Ưޤ')\n$twind2_text.insert('end', '㤨СˤϥƥȥåȤ')\n$twind2_text.insert('end', 'äƥܥ󤬤줤󤷤֤Ƥޤ')\n$twind2_text.insert('end', 'Υܥ򥯥å뤳Ȥǡ')\n$twind2_text.insert('end', 'ΥƥȥåȤطʿ')\n$twind2_text.insert('end', 'Ѥ뤳ȤǤޤ(\"ǥե\"ܥ')\n$twind2_text.insert('end', 'ο᤹ȤǤޤ)')\n$twind2_text.insert('end', '\"Short\"Ȥܥ򥯥åʸĹ')\n$twind2_text.insert('end', 'ѤꡢƥȥåȤưŪ')\n$twind2_text.insert('end', '쥤ȤͻҤ򸫤뤳ȤǤޤ')\n$twind2_text.insert('end', '⤦Ʊܥ򲡤ȸޤ')\n$twind2_text.insert('end', \"\\n\")\n\nbtn_default = TkButton.new($twind2_text) {|b|\n  text 'ǥե'\n  command proc{embDefBg2 $twind2_text}\n  cursor 'top_left_arrow'\n}\nTkTextWindow.new($twind2_text, 'end', 'window'=>btn_default, 'padx'=>3)\nembToggle = TkVariable.new('Short')\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkCheckButton.new($twind2_text) {\n                   textvariable embToggle\n                   indicatoron 0\n                   variable embToggle\n                   onvalue 'A much longer string'\n                   offvalue 'Short'\n                   cursor 'top_left_arrow'\n                   pady 5\n                   padx 2\n                 },\n                 'padx'=>3, \n                 'pady'=>2 )\n\n[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4', \n  'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1', \n  'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1', \n  'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4' \n].each{|twind_color|\n  TkTextWindow.new($twind2_text, 'end', \n                   'window'=>TkButton.new($twind2_text) {\n                     text twind_color\n                     cursor 'top_left_arrow'\n                     command proc{$twind2_text.bg twind_color}\n                   },\n                   'padx'=>3, \n                   'pady'=>2 )\n}\n\n$tag2_buttons.add(btn_default, 'end')\n\n$text_normal2 = {}\n$text_normal2['border'] = $twind2_text.cget('borderwidth')\n$text_normal2['highlight'] = $twind2_text.cget('highlightthickness')\n$text_normal2['pad'] = $twind2_text.cget('padx')\n\n$twind2_text.insert('end', \"\\nborder width  highlightthickness, \")\n$twind2_text.insert('end', \"padding ̾ͤѹ뤳ȤǽǤ\\n\")\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Big borders\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinBigB2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Small borders\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinSmallB2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Big highlight\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinBigH2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Small highlight\",\n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinSmallH2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Big pad\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinBigP2 $twind2_text\n                                        }))\n\nTkTextWindow.new($twind2_text, 'end', \n                 'window'=>TkButton.new($twind2_text, :text=>\"Small pad\", \n                                        :cursor=>'top_left_arrow', \n                                        'command'=>proc{\n                                          textWinSmallP2 $twind2_text\n                                        }))\n\n$twind2_text.insert('end', \"\\n\\n˥᡼ƥȥåȤ\")\n$twind2_text.insert('end', \"ޤ֤Ǥޤ\")\n\nTkTextImage.new($twind2_text, 'end', \n                'image'=>TkBitmapImage.new(:file=>[\n                                             $demo_dir, '..', \n                                             'images', 'face.xbm'\n                                           ].join(File::Separator)))\n\n# ᥽å\ndef textWinBigB2(w)\n  w.borderwidth 15\nend\ndef textWinSmallB2(w)\n  w.borderwidth $text_normal2['border']\nend\ndef textWinBigH2(w)\n  w.highlightthickness 15\nend\ndef textWinSmallH2(w)\n  w.highlightthickness $text_normal2['highlight']\nend\ndef textWinBigP2(w)\n  w.configure(:padx=>15, :pady=>15)\nend\ndef textWinSmallP2(w)\n  w.configure(:padx=>$text_normal2['pad'], :pady=>$text_normal2['pad'])\nend\n\ndef textWindOn2 (w,f)\n  if defined? $twind2_scroll\n    begin\n      $twind2_scroll.destroy\n    rescue\n    end\n    $twind2_scroll = nil\n  end\n\n  base = TkWinfo.parent( TkWinfo.parent(w) )\n  $twind2_scroll = TkScrollbar.new(base) {|s|\n    orient 'horizontal'\n    command proc{|*args| w.xview(*args)}\n    w.xscrollcommand proc{|first,last| s.set first,last}\n    w.wrap 'none'\n    pack('after'=>f, 'side'=>'bottom', 'fill'=>'x')\n  }\n\n  return nil\nend\n\ndef textWindOff2 (w)\n  if defined? $twind2_scroll\n    begin\n      $twind2_scroll.destroy\n    rescue\n    end\n    $twind2_scroll = nil\n  end\n  w.xscrollcommand ''\n  #w.wrap 'word'\n  w.wrap 'char'\nend\n\ndef textWindPlot2 (t)\n  if (defined? $twind2_plot) && (TkWinfo.exist?($twind2_plot))\n    return\n  end\n\n  $twind2_plot = TkCanvas.new(t) {\n    relief 'sunken'\n    width  450\n    height 300\n    cursor 'top_left_arrow'\n  }\n\n  #font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'\n  font = 'Helvetica 18'\n\n  TkcLine.new($twind2_plot, 100, 250, 400, 250, 'width'=>2)\n  TkcLine.new($twind2_plot, 100, 250, 100,  50, 'width'=>2)\n  TkcText.new($twind2_plot, 225, 20, \n              'text'=>\"A Simple Plot\", 'font'=>font, 'fill'=>'brown')\n\n  (0..10).each {|i|\n    x = 100 + (i * 30)\n    TkcLine.new($twind2_plot, x, 250, x, 245, 'width'=>2)\n    TkcText.new($twind2_plot, x, 254, \n                'text'=>10*i, 'font'=>font, 'anchor'=>'n')\n  }\n  (0..5).each {|i|\n    y = 250 - (i * 40)\n    TkcLine.new($twind2_plot, 100, y, 105, y, 'width'=>2)\n    TkcText.new($twind2_plot, 96, y, \n                'text'=>\"#{i*50}.0\", 'font'=>font, 'anchor'=>'e')\n  }\n\n  for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]\n    x = 100 + (3*xx)\n    y = 250 - (4*yy)/5\n    item = TkcOval.new($twind2_plot, x-6, y-6, x+6, y+6, \n                       'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')\n    item.addtag 'point'\n  end\n\n  $twind2_plot.itembind('point', 'Any-Enter', \n                        proc{$twind2_plot.itemconfigure 'current', 'fill', 'red'})\n  $twind2_plot.itembind('point', 'Any-Leave', \n                        proc{$twind2_plot.itemconfigure 'current', 'fill', 'SkyBlue2'})\n  $twind2_plot.itembind('point', '1', \n                        proc{|x,y| embPlotDown2 $twind2_plot,x,y}, \"%x %y\")\n  $twind2_plot.itembind('point', 'ButtonRelease-1', \n                        proc{$twind2_plot.dtag 'selected'})\n  $twind2_plot.bind('B1-Motion', \n                    proc{|x,y| embPlotMove2 $twind2_plot,x,y}, \"%x %y\")\n  while ($twind2_text.get($mark2_plot) =~ /[ \\t\\n]/)\n    $twind2_text.delete $mark2_plot\n  end\n  $twind2_text.insert $mark2_plot,\"\\n\"\n  TkTextWindow.new($twind2_text, $mark2_plot, 'window'=>$twind2_plot)\n  $tag2_center.add $mark2_plot\n  $twind2_text.insert $mark2_plot,\"\\n\"\nend\n\n$embPlot2 = {'lastX'=>0, 'lastY'=>0}\n\ndef embPlotDown2 (w, x, y)\n  w.dtag 'selected'\n  w.addtag_withtag 'selected', 'current'\n  w.raise 'current'\n  $embPlot2['lastX'] = x\n  $embPlot2['lastY'] = y\nend\n\ndef embPlotMove2 (w, x, y)\n  w.move 'selected', x - $embPlot2['lastX'], y - $embPlot2['lastY']\n  $embPlot2['lastX'] = x\n  $embPlot2['lastY'] = y\nend\n\ndef textWindDel2 (w)\n  if (defined? $twind2_text) && TkWinfo.exist?($twind2_plot)\n    $twind2_text.delete $twind2_plot\n    $twind2_plot = nil\n    while ($twind2_text.get($mark2_plot) =~ /[ \\t\\n]/)\n      $twind2_text.delete $mark2_plot\n    end\n    $twind2_text.insert $mark2_plot,\"  \"\n  end\nend\n\ndef embDefBg2 (w)\n  w['background'] = w.configinfo('background')[3]\nend\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/unicodeout.rb",
    "content": "# -*- coding: euc-jp -*-\n#\n# unicodeout.rb --\n#\n# This demonstration script shows how you can produce output (in label\n# widgets) using many different alphabets.\n#\n# based on Tcl/Tk8.4.4 widget demos\n\nif defined?($unicodeout_demo) && $unicodeout_demo\n  $unicodeout_demo.destroy \n  $unicodeout_demo = nil\nend\n\n$unicodeout_demo = TkToplevel.new {|w|\n  title(\"Unicode Label Demonstration\")\n  iconname(\"unicodeout\")\n  positionWindow(w)\n}\n\nbase_frame = TkFrame.new($unicodeout_demo).pack(:fill=>:both, :expand=>true)\n\nTkLabel.new(base_frame, \n            :font=>$font, :wraplength=>'5.4i', :justify=>:left, \n            :text=><<EOL).pack(:side=>:top)\nϡTkˤʸѤФ륵ݡȤˤĤƤ\\\nץǤɽˤƤʤºݤˤɤΤ褦ɽ\\\nܤˤ뤫ϡʤδĶˤɤΤ褦ʸ礬󥹥ȡ뤵Ƥ뤫\\\n礭¸ޤޤоݤȤʤʸ礬󥹥ȡ뤵Ƥʤ\\\nɤΤ褦ɽʤ뤫⤢ʤδĶǤ\\\n֥ɻȡץܥ򲡤ƥɽ\\\nUnicodeout_SampleFrame饹@@font񤭴\\\n(եƤѹޤ)\\\nֺƼ¹ԡץܥΥåƤߤƤ\nץȤĤ褦ˡʸ\\\\uXXXXȤ\\\nTclΥɽѤUNICODEʸǽ񤫤Ƥޤ\\\nʸϡTk::UTF8_String᥽åɤˤäơ\\\nUTF8ʸǤפȤ\\\n󥳡ɾդʸ󥪥֥\\\n(TclΥɽѴѤ)Ѵ\\\n٥륦åȤϤƤդƤ\nEOL\n#'\n\nTkFrame.new(base_frame){|f|\n  pack(:side=>:bottom, :fill=>:x, :pady=>'2m')\n\n  TkButton.new(f, :text=>'Ĥ', :width=>15, :command=>proc{\n                 $unicodeout_demo.destroy\n                 $unicodeout_demo = nil\n               }).pack(:side=>:left, :expand=>true)\n\n  TkButton.new(f, :text=>'ɻ', :width=>15, :command=>proc{\n                 showCode 'unicodeout'\n               }).pack(:side=>:left, :expand=>true)\n}\n\nwait_msg = TkLabel.new(base_frame, \n                       :text=>\"եɤ߹ߤδλޤ\" + \n                              \"Ф餯Ԥ\", \n                       :font=>\"Helvetica 12 italic\").pack\n\nclass Unicodeout_SampleFrame < TkFrame\n  @@font = $font\n  # @@font = 'Helvetica 14'\n  # @@font = 'Courier 12'\n  # @@font = 'clearlyu 16'\n  # @@font = 'fixed 12'\n  # @@font = 'Times 12'\n  # @@font = 'Newspaper 12'\n  # @@font = '{New century schoolbook} 12'\n\n  def initialize(base)\n    super(base)\n    grid_columnconfig(1, :weight=>1)\n  end\n\n  def add_sample(lang, *args)\n    sample_txt = Tk::UTF8_String(args.join(''))\n    l = TkLabel.new(self, :font=>@@font, :text=>lang+':', \n                    :anchor=>:nw, :pady=>0)\n    #s = TkLabel.new(self, :font=>@@font, :text=>sample_txt, \n    s = TkLabel.new(self, :font=>TkFont.new(@@font), :text=>sample_txt, \n                    :anchor=>:nw, :width=>30, :pady=>0)\n    Tk.grid(l, s, :sticky=>:ew, :pady=>0)\n    l.grid_config(:padx, '1m')\n  end\nend\nf = Unicodeout_SampleFrame.new(base_frame)\nf.pack(:expand=>true, :fill=>:both, :padx=>'2m', :pady=>'1m')\n\n# Processing when some characters are missing might take a while, so make\n# sure we're displaying something in the meantime...\n\noldCursor = $unicodeout_demo.cursor\n$unicodeout_demo.cursor('watch')\nTk.update\n\nf.add_sample('Arabic', \n             '\\uFE94\\uFEF4\\uFE91\\uFEAE\\uFECC\\uFEDF\\uFE8D\\uFE94', \n             '\\uFEE4\\uFEE0\\uFEDC\\uFEDF\\uFE8D')\nf.add_sample('Trad. Chinese', '\\u4E2D\\u570B\\u7684\\u6F22\\u5B57')\nf.add_sample('Simpl. Chinese', '\\u6C49\\u8BED')\nf.add_sample('Greek', \n             '\\u0395\\u03BB\\u03BB\\u03B7\\u03BD\\u03B9\\u03BA\\u03AE ', \n             '\\u03B3\\u03BB\\u03CE\\u03C3\\u03C3\\u03B1')\nf.add_sample('Hebrew', \n             '\\u05DD\\u05D9\\u05DC\\u05E9\\u05D5\\u05E8\\u05D9 ', \n             '\\u05DC\\u05D9\\u05D0\\u05E8\\u05E9\\u05D9')\nf.add_sample('Japanese', \n             '\\u65E5\\u672C\\u8A9E\\u306E\\u3072\\u3089\\u304C\\u306A, ', \n             '\\u6F22\\u5B57\\u3068\\u30AB\\u30BF\\u30AB\\u30CA')\nf.add_sample('Korean', '\\uB300\\uD55C\\uBBFC\\uAD6D\\uC758 \\uD55C\\uAE00')\nf.add_sample('Russian', \n             '\\u0420\\u0443\\u0441\\u0441\\u043A\\u0438\\u0439 ', \n             '\\u044F\\u0437\\u044B\\u043A')\n\nwait_msg.destroy\n$unicodeout_demo.cursor(oldCursor)\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/vscale.rb",
    "content": "# -*- coding: euc-jp -*-\nrequire \"tkcanvas\"\n\nif defined?($vscale_demo) && $vscale_demo\n  $vscale_demo.destroy\n  $vscale_demo = nil\nend\n\n$vscale_demo = TkToplevel.new {|w|\n  title(\"Vertical Scale Demonstration\")\n  iconname(\"vscale\")\n}\npositionWindow($vscale_demo)\n\nbase_frame = TkFrame.new($vscale_demo).pack(:fill=>:both, :expand=>true)\n\nmsg = TkLabel.new(base_frame) {\n  font $font\n  wraplength '3.5i'\n  justify 'left'\n#  text \"ˤ1ĤȾľʥ뤬ɽƤޤ\\\n#ǥޥܥ1򥯥åޤϥɥå\\\n#ĹѤ뤳ȤǤޤ\"\n  text \"ˤϥСȽķΥ뤬ɽƤޤǥޥΥܥ1 򥯥å뤫ɥåƥСι⤵Ѥ뤳ȤǤޤäλץܥ򲡤Ƥ\"\n}\nmsg.pack('side'=>'top', 'padx'=>'.5c')\n\nTkFrame.new(base_frame) {|frame|\n  TkButton.new(frame) {\n    #text 'λ'\n    text 'Ĥ'\n    command proc {\n      tmppath = $vscale_demo\n      $vscale_demo = nil\n      tmppath.destroy\n    }\n  }.pack('side'=>'left', 'expand'=>'yes')\n\n  TkButton.new(frame) {\n    text 'ɻ'\n    command proc { showCode 'vscale' }\n  }.pack('side'=>'left', 'expand'=>'yes')\n}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')\n\ndef setHeight(w, height)\n  height = height + 21\n  y2 = height - 30\n  if y2 < 21\n    y2 = 21\n  end\n  w.coords 'poly',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20\n  w.coords 'line',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20\nend\n\nTkFrame.new(base_frame) {|frame|\n  borderwidth 10\n  canvas = TkCanvas.new(frame) {|c|\n    width 50\n    height 50\n    bd 0\n    highlightthickness 0\n    TkcPolygon.new(c, 0, 0, 1, 1, 2, 2) {\n      fill 'SeaGreen3'\n      tags 'poly'\n    }\n    TkcLine.new(c, 0, 0, 1, 1, 2, 2, 0, 0) {\n      fill 'black'\n      tags 'line'\n    }\n  }.pack('side'=>'left',  'anchor'=>'nw', 'fill'=>'y')\n  scale = TkScale.new(frame) {\n    orient 'vertical'\n    length 284\n    from 0\n    to 250\n    command proc{|value| setHeight(canvas, value)}\n    tickinterval 50\n  }.pack('side'=>'left', 'anchor'=>'ne')\n  scale.set 75\n}.pack\n"
  },
  {
    "path": "ext/tk/sample/demos-jp/widget",
    "content": "#!/usr/bin/env ruby\n# -*- coding: euc-jp -*-\n\n#  ( tk.rb Υɻ encoding /˻Ȥ )\nif RUBY_VERSION < '1.9.0' ### !!!!!!!!!!!!!!\n  $KCODE = 'euc'\nelse\n  DEFAULT_TK_ENCODING = 'EUC-JP'\nend\n\n# tk ط饤֥ɤ߹\nrequire 'tk'\n# require 'tkafter'\n\n$RubyTk_WidgetDemo = true\n\n# widget demo directory ֤γ\n# $demo_dir = File.dirname($0)\n$demo_dir = File.dirname(__FILE__)\n\n# root \n$root = TkRoot.new{title \"Ruby/Tk Widget Demonstration\"}\n\n# tk Сμ\n$tk_version = Tk::TK_VERSION\n$tk_major_ver, $tk_minor_ver = $tk_version.split('.').map{|n| n.to_i}\n$tk_patchlevel = Tk::TK_PATCHLEVEL\n\n# tcl_platform ؤΥ֥\n$tk_platform = TkVarAccess.new('tcl_platform')\n\n# ե\n#######\ncase($tk_version)\nwhen /^4.*/\n  $font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*', nil)\n  knjfont = '-*--16-*-jisx0208.1983-0'\n  $kanji_font = TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*',\n                           knjfont)\n  TkOption.add('*kanjiFont', knjfont, 'startupFile')\n  $msg_kanji_font=TkFont.new('-*-Helvetica-Medium-R-Normal--*-140-*-*-*-*-*-*',\n                             '-*--24-*-jisx0208.1983-0')\n\n#when '8.0'\n#  $font = TkFont.new('Helvetica -12')\n#  $kanji_font = TkFont.new('Helvetica -12', 'Mincho -12')\n#  TkOption.add('*kanjiFont', knjfont, 'startupFile')\n#  $msg_kanji_font=TkFont.new('Helvetica 16', 'Gothic 16 bold')\n\nwhen /^8.*/\n  $font = TkFont.new('Helvetica -12')\n  $kanji_font = TkFont.new('Helvetica -12', 'Mincho -12')\n  TkOption.add('*kanjiFont', knjfont, 'startupFile')\n  $msg_kanji_font=TkFont.new('Helvetica 14 bold', 'Gothic 14 bold')\n\nelse\n  $font = TkFont.new('Helvetica 14', nil)\n  knjfont = '-*--16-*-jisx0208.1983-0'\n  $kanji_font = TkFont.new('Helvetic 14', knjfont)\n  TkOption.add('*kanjiFont', knjfont, 'startupFile')\n  $msg_kanji_font=TkFont.new('Helvetica 14',\n                             '-*--24-*-jisx0208.1983-0')\nend\n#######\n\n# ᡼\n$image = {}\n\nif $tk_major_ver >= 8\n$image['refresh'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><<EOD)\n    R0lGODlhEAAQAPMAAMz/zCpnKdb/1z9mPypbKBtLGy9NMPL/9Or+6+P+4j1Y\n    PwQKBP7//xMLFAYBCAEBASH5BAEAAAAALAAAAAAQABAAAwR0EAD3Gn0Vyw0e\n    ++CncU7IIAezMA/nhUqSLJizvSdCEEjy2ZIV46AwDAoDHwPYGSoEiUJAAGJ6\n    EDHBNCFINW5OqABKSFk/B9lUa94IDwIFgewFMwQDQwCZQCztTgM9Sl8SOEMG\n    KSAthiaOjBMPDhQONBiXABEAOw==\nEOD\nend\n\nif $tk_major_ver >= 8\n$image['view'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><<EOD)\n    R0lGODlhEAAQAPMAAMz/zP///8DAwICAgH9/fwAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAwRIcMhJB7h3hM33\n    KFjWdQQYap1QrCaGBmrRrS4nj5b53jOgbwXBKGACoYLDIuAoHCmZyYvR1rT5\n    RMAq8LqcIYGsrjPsW1XOmFUEADs=\nEOD\nend\n\nif $tk_major_ver >= 8\n$image['delete'] = TkPhotoImage.new(:height=>16, :format=>'GIF', :data=><<EOD)\n    R0lGODlhEAAOAKEAAIQAAO/n3v///////yH5BAEKAAIALAAAAAAQAA4AAAIm\n    lI9pAKHbIHNoVhYhTdjlJ2AWKG2g+CldmB6rxo2uybYhbS80eRQAOw==\nEOD\nend\n\nif $tk_major_ver >= 8\n$image['print'] = TkPhotoImage.new(:height=>19, :format=>'GIF', :data=><<EOD)\n    R0lGODlhGgATAPcAACEQOTEpQjEpUkIpc0IxY0I5c0oxjEo5SlJCY1JCe1JK\n    UlpChFpCjFpGkFpSc1paa2NKc2NKnGNja2tapWtjc29KnHNanHNjc3NjrXNr\n    jHNrnHNzc3tjpXtrtXtzhICAgIRzvYSEjIZzqox7tYyEnIyMjJSEtZSEvZSM\n    lJyMtZyMvZyUlJyUrZyUvZycnKWctaWlpa2czq2lzrWtvbWtzrW1tb21xr21\n    1sa9zs693s7OztbO3tbO597W1t7W7+fe7+fn5////+/n7+/v7+/v9////wAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n    AAAAAAAAAAAAAAAAAAAAACH5BAEAAEEALAAAAAAaABMAQAj/AIMIHBhkg0GC\n    CBMGIQEiQgseQT4oeCBBAokgRYYQ0JBixg8hRIiUUEBBYYmTByBwiCBCRYwH\n    CxY8cKFw4AogRXLqLAJkQ80gCBBg3BkxZswTNGh4MGqgQQUMJRHCwMkTSE+D\n    Pn8eCKBhxIMhO3ei2OHDBw6sWSlMMMoWgwwfMDZI8GBjx44NARZwEGGi5MkS\n    PcIWKRGz5YgLbAco+KkQBQoJIRgjdGEVq+SaJajqtNrzMgsPCmoIzqmDgmWE\n    KOBuUKAAwYabYTfs4OHjY0giGyhk4MAWRI4eKyRQqPgggYUXPH4A+XBAgwoK\n    DiIsCFxjA9sFEVQQCRJCAYAFDJxiKhAxvMTonEFimrhhYinTBgWiCvxLNX3M\n    DkkpsKV5OYhjBxCMYAICAigUEAA7\nEOD\nend\n\n# ˥塼\nif $tk_major_ver >= 8\n  $root.add_menubar([[['File', 0], \n                        ['About ... ', proc{aboutBox}, 0, '<F1>'],\n                        '---', \n                        ['Quit', proc{exit}, 0, 'Ctrl-Q']\n                      ]])\nelse\n  TkMenubar.new($root, \n                [[['File', 0], \n                    ['About ... ', proc{aboutBox}, 0, '<F1>'],\n                    '---', \n                    ['Quit', proc{exit}, 0, 'Ctrl-Q']\n                  ]]).pack('side'=>'top', 'fill'=>'x')\nend\n$root.bind('F1', proc{aboutBox})\n$root.bind('Control-q', proc{exit})\n\n=begin\nTkFrame.new($root){|frame|\n  TkMenubutton.new(frame){|button|\n    m = TkMenu.new(button) {\n      add 'command', 'label'=>'Quit', 'command'=>proc{exit}, 'underline'=>0\n    }\n    menu m\n    text 'File'\n    underline 0\n  }.pack('side'=>'left')\n}.pack('side'=>'top', 'fill'=>'x')\n=end\n\n# ƥȥܥå\nif $tk_version =~ /^4\\.[01]/\n  scr = TkScrollbar.new($root, 'orient'=>'vertical')\n  txt = TkText.new($root) {\n    #wrap 'word'\n    wrap 'char'\n    width 70\n    height 30\n    font $font\n    setgrid 'yes'\n    yscrollcommand proc{|first,last| scr.set first,last}\n  }\n  scr.command(proc{|*args| txt.yview(*args)})\n  scr.pack('side'=>'right', 'fill'=>'y')\n  txt.pack('expand'=>'yes', 'fill'=>'both')\nelse\n  textFrame = TkFrame.new($root)\n  scr = TkScrollbar.new($root, 'orient'=>'vertical', \n                        'highlightthickness'=>0, 'takefocus'=>1) {\n    pack('in'=>textFrame, 'side'=>'right', 'fill'=>'y', 'padx'=>1)\n  }\n  txt = TkText.new($root) {\n    #wrap 'word'\n    wrap 'char'\n    width 70\n    height 30\n    font $font\n    setgrid 'yes'\n    highlightthickness 0\n    padx 4\n    pady 2\n    takefocus 0\n    bd 1\n    yscrollcommand proc{|first,last| scr.set first,last}\n  }\n  scr.command(proc{|*args| txt.yview(*args)})\n#  txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both', 'padx'=>1)\n  txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')\n#  textFrame.pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>2)\n  textFrame.pack('expand'=>'yes', 'fill'=>'both')\n\n  statusBar = TkFrame.new($root) {|f|\n    if $tk_version =~ /^4.*/\n      statusfont = '-*-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*'\n    else\n      statusfont = 'Helvetica 10'\n    end\n    $statusBarLabel = \\\n    TkLabel.new(f, 'text'=>\"   \", 'relief'=>'sunken', 'bd'=>1, 'anchor'=>'w', \n                'font'=>statusfont) \\\n    .pack('side'=>'left', 'padx'=>2, 'expand'=>'yes', 'fill'=>'both')\n    TkLabel.new(f, 'width'=>8, 'relief'=>'sunken', 'bd'=>1, 'anchor'=>'w', \n                'font'=>statusfont) \\\n    .pack('side'=>'left', 'padx'=>2)\n  }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>2)\nend\n\n# ƥȥ\nif $tk_version =~ /^4.*/\n  tag_title = TkTextTag.new(txt, 'font'=>'-*-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*')\nelse\n  tag_title = TkTextTag.new(txt, 'font'=>'Helvetica 18 bold')\nend\n#tag_kanji_title = TkTextTag.new(txt, 'kanjifont'=>$msg_kanji_font)\n#tag_middle = TkTextTag.new(txt, 'kanjifont'=>$kanji_font)\ntag_kanji_title = TkTextTag.new(txt, 'font'=>$msg_kanji_font)\ntag_middle = TkTextTag.new(txt, 'font'=>$kanji_font)\ntag_demospace = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c')\n\nif TkWinfo.depth($root) == 1\n  tag_demo = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                           'underline'=>1)\n  $tag_visited = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                              'underline'=>1)\n  tag_hot = TkTextTag.new(txt, 'background'=>'black', 'foreground'=>'white')\nelse\n  tag_demo = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                           'foreground'=>'blue', 'underline'=>1)\n  $tag_visited = TkTextTag.new(txt, 'lmargin1'=>'1c', 'lmargin2'=>'1c', \n                              'foreground'=>'#303080', 'underline'=>1)\n#  tag_hot = TkTextTag.new(txt, 'relief'=>'raised', 'borderwidth'=>1, \n#                         'background'=>'SeaGreen3')\n  tag_hot = TkTextTag.new(txt, 'borderwidth'=>1, 'foreground'=>'red')\nend\n\n#tag_demo.bind('Button-1', proc{invoke txt, txt.index('current')})\ntag_demo.bind('ButtonRelease-1', \n              proc{|x,y|invoke txt, txt.index(\"@#{x},#{y}\")}, '%x %y')\n\nlastLine = TkVariable.new(\"\")\nnewLine  = TkVariable.new(\"\")\ntag_demo.bind('Enter', proc{|x,y|\n                lastLine.value = txt.index(\"@#{x},#{y} linestart\")\n                tag_hot.add(lastLine.value, \"#{lastLine.value} lineend\")\n                showStatus txt, txt.index(\"@#{x},#{y}\")\n              },\n              '%x %y')\ntag_demo.bind('Leave', \n              proc{\n                tag_hot.remove('1.0','end')\n                txt.configure('cursor','xterm')\n                $statusBarLabel.configure('text'=>\"\")\n              })\ntag_demo.bind('Motion', proc{|x, y|\n                newLine.value = txt.index(\"@#{x},#{y} linestart\")\n                if newLine.value != lastLine.value\n                  tag_hot.remove('1.0','end')\n                  lastLine.value = newLine.value\n                  if ( txt.tag_names(\"@#{x},#{y}\").find{|t| \n                        t.kind_of?(String) && t =~ /^demo-/\n                      } )\n                    tag_hot.add(lastLine.value, \n                                \"#{lastLine.value} lineend -1 chars\")\n                  end\n                end\n                showStatus txt, txt.index(\"@#{x},#{y}\")\n              },\n              '%x %y')\n\n# ƥ\ntxt.insert('end', 'Ruby/Tk : Widget', tag_title)\n#txt.insert('end', \"  ǥ󥹥ȥ졼\\n\", tag_middle)\ntxt.insert('end', \"  ǥ󥹥ȥ졼\\n\", tag_kanji_title)\ntxt.insert('end', <<\"EOT\")\n\nΥץꥱϡTk Widget ѤƤɤΤ褦ʤȤǤ뤫\\\n򼨤ΡĤξʥץȤФեȥɤ\\\nƤޤʲ˽֤˵󤲤Ƥǥ󥹥ȥ졼¹\\\nˤϥޥǥåƤǥ󥹥ȥ졼Υ\\\nɥȡǥ󥹥ȥ졼 Ruby/Tk Υɤ\\\n뤿ˡ\"ɻ\"ܥ򥯥å뤳ȤǤޤʤ\\\n˾ʤ顢Υɤ뤳ȤǤޤɤǥǥ\\\n󥹥ȥ졼Ƽ¹Ԥ뤿ˤϡɤ񤫤줿ɥ\\\n\"ǥƼ¹\" ܥ򥯥åƤ\\\nɤƤ⥪ꥸʥΥե뤬񤭴뤳Ȥ\\\nޤ󤫤顢ۤ˿ѹƤߤƤ\n\nΥǥǤϡŪǶΥС Tk ǤʤХݡȤ\\\nʤǽȤäƼƤޤ(㤨 Tk8.4 ʾʤ)Τᡢ\\\nǽʤ Tk 饤֥ȤäƤˤϡ\\\nǥưޤ󡣤Τ褦ʵǽɬפǤС򥵥ݡ\\\nƤ Tk 饤֥Ȥ褦 tcltklib 򥳥ѥ뤷ʤ\\\n\n\n⤷ʤ Tk  (ǽ餫ޤफ󥹥ȡ뤷ˤ) \\\nTtk (Tile) ĥѤǤ֤Ǥʤ顢\\\nTtk ĥΥǥ (sample/tkextlib/tile/demo.rb) ⤼һƤߤƤ\n( ¿ʬߤΤʤδĶˤ Ttk ĥ\\\n#{\nbegin\n  require 'tkextlib/tile'\n  \"ǤƳƤޤ\"\nrescue\n  \"ޤ󥹥ȡ뤵Ƥޤ\"\nend\n}\\\n)\nTtk ĥϡTk8.5 ʾǤɸεǽȤȤ߹ޤƤޤ\n\n\nEOT\n\n#txt.insert('end',\"٥, ܥ, åܥ, 饸ܥ\\n\",tag_middle)\ntxt.insert('end', \"٥, ܥ, åܥ, 饸ܥ\\n\", \n           tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ٥ (ƥ, ӥåȥޥå)\\n\", \n           tag_demo, \"demo-label\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ٥UNICODEƥ (ǽбСTkɬ)\\n\", tag_demo, \"demo-unicodeout\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ܥ \\n\", tag_demo, \"demo-button\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. åܥ (ʣǽ)\\n\", \n           tag_demo, \"demo-check\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. ֥åܥ (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-check2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. 饸ܥ (ǤդΰĤǽ)\\n\", \n           tag_demo, \"demo-radio\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"7. 饸ܥ (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-radio2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"8. ֥饸ܥ (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-radio3\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"9. ܥǺ줿15-ѥ륲\\n\", \n           tag_demo, \"demo-puzzle\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"10. ӥåȥޥåפѤܥ\\n\", \n           tag_demo, \"demo-icon\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"11. ɽĤΥ٥\\n\", \n           tag_demo, \"demo-image1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"12. 򸫤뤿δñʥ桼󥿡ե\\n\", \n           tag_demo, \"demo-image2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"13. 򸫤뤿δñʥ桼󥿡ե (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-image3\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"14. ٥դե졼 (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-labelframe\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"15. ơޤбåȤδñ (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo, \"demo-ttkbut\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"ꥹȥܥå\\n\", tag_middle)\ntxt.insert('end', \"ꥹȥܥå\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ƻܸ.\\n\", tag_demo, \"demo-states\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. : ץꥱΤۿѤ\\n\", \n           \"#{tag_demo.id} demo-colors\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ʸ\\n\", tag_demo, \"demo-sayings\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. ˤĤƤΥޥꥹ (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo, \"demo-mclist\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. ǥ쥯ȥ֥饦 (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo, \"demo-tree\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"ȥȥԥܥå\\n\", tag_middle)\ntxt.insert('end', \"ȥ\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Сʤ\\n\", tag_demo, \"demo-entry1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. С\\n\", tag_demo, \"demo-entry2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ǧڽդΥȥܥåȥѥɥե (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-entry3\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. ԥܥå (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-spin\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. ܥܥå (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo, \"demo-combo\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. ñʥե\\n\", tag_demo, \"demo-form\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"ƥ\\n\", tag_middle)\ntxt.insert('end', \"ƥ\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Ūʥƥ\\n\", tag_demo, \"demo-text\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ɽ.\\n\", tag_demo, \"demo-style\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ϥѡƥ(Х).\\n\", \n           tag_demo, \"demo-bind\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. ɥƥ\\n\", \n           tag_demo, \"demo-twind\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. ɥƥ (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-twind2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. \\n\", tag_demo, \"demo-search\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"7. ƥȥåȤ(peering) (ǽбСTkɬ)\\n\", tag_demo, \"demo-textpeer\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"Х\\n\", tag_middle)\ntxt.insert('end', \"Х\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ƥη\\n\", tag_demo, \"demo-items\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. 2 Υץå\\n\", tag_demo, \"demo-plot\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ƥ\\n\", tag_demo, \"demo-ctext\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. η\\n\", tag_demo, \"demo-arrow\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. 롼顼\\n\", tag_demo, \"demo-ruler\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. եץ\\n\", tag_demo, \"demo-floor\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"7. եץ (ۤʤ륭Хƥˡ)\\n\", tag_demo, \"demo-floor2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"8. ǽʥХ\\n\", \n           tag_demo, \"demo-cscroll\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"9. ܡɾεΤν (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo, \"demo-knightstour\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"ȥץ쥹С\\n\", tag_middle)\ntxt.insert('end', \"ȥץ쥹С\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ľ\\n\", tag_demo.id, \"demo-vscale\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ʿ\\n\", tag_demo.id, \"demo-hscale\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ץ쥹С (Tile/Ttkĥؤбɬ)\\n\", tag_demo.id, \"demo-ttkprogress\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\ntxt.insert('end', \"ڥɥɥȥΡȥ֥å\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ʿ (ǽбСTkɬ)\\n\", \n           tag_demo.id, \"demo-paned1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ľ (ǽбСTkɬ)\\n\", \n           tag_demo.id, \"demo-paned2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ơޤбߥڥ (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo.id, \"demo-ttkpane\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. Ρȥ֥åå (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo.id, \"demo-ttknote\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"˥塼ȥġС\\n\", tag_middle)\ntxt.insert('end', \"˥塼ȥġС\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ˥塼ȥɤޤɥ\\n\", \n           tag_demo, \"demo-menu\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ˥塼ȥɤޤɥ (Tk8.x )\\n\", \n           tag_demo, \"demo-menu8x\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3.                                 (ǽбСTkɬ)\\n\", \n           tag_demo, \"demo-menu84\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. ˥塼ܥ (Tk8.x )\\n\", \n           tag_demo, \"demo-menubu\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"5. ơޤб˥塼ܥ (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo.id, \"demo-ttkmenu\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"6. ơޤбġС (Tile/Ttkĥؤбɬ)\\n\", \n           tag_demo.id, \"demo-toolbar\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"ɥ\\n\", tag_middle)\ntxt.insert('end', \"ɥ\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. åܥå\\n\", tag_demo, \"demo-msgbox\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ܺ٥ƥդΥåܥå (ǽбСTkɬ)\\n\", tag_demo, \"demo-msgbox2\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ե\\n\", tag_demo, \"demo-filebox\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. \\n\", tag_demo, \"demo-clrpick\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"˥᡼\\n\", tag_middle)\ntxt.insert('end', \"˥᡼\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. ˥᡼٥ (ǽбСTkɬ)\\n\", tag_demo, \"demo-anilabel\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ȷΥ˥᡼ (ǽбСTkɬ)\\n\", tag_demo, \"demo-aniwave\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ҤΥߥ졼 (ǽбСTkɬ)\\n\", tag_demo, \"demo-pendulum\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"4. A celebration of Rube Goldberg (ǽбСTkɬ)\\n\", tag_demo, \"demo-goldberg\")\n\ntxt.insert('end', \"\\n\")\n#txt.insert('end', \"¾\\n\", tag_middle)\ntxt.insert('end', \"¾\\n\", tag_kanji_title)\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"1. Ȥ߹ߤΥӥåȥޥå\\n\", tag_demo, \"demo-bitmap\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"2. ⡼(륰)\\n\", \n           tag_demo, \"demo-dialog1\")\ntxt.insert('end', \" \\n \", tag_demospace)\ntxt.insert('end', \"3. ⡼(Х륰)\\n\", \n           tag_demo, \"demo-dialog2\")\ntxt.insert('end', \" \\n \", tag_demospace)\n\ntxt.state('disabled')\nscr.focus\n\n################################\n# method \n################################\ndef positionWindow(w)\n  w.geometry('+300+300')\nend\n\n# ƥåȤȡѿ̾ TkVariable Ȥ()¤ӤϤ\n$showVarsWin = {}\ndef showVars1(parent, *args)\n  if $showVarsWin[parent.path]\n    begin\n      $showVarsWin[parent.path].destroy \n    rescue\n    end\n  end\n  top = TkToplevel.new(parent) {|w|\n    title \"Variable values\"\n    base = TkFrame.new(w).pack(:fill=>:both, :expand=>true)\n    TkLabel.new(base) {\n      text \"ѿ:\"\n      width 20\n      anchor 'center'\n      if $tk_version =~ /^4.*/\n        font '-Adobe-helvetica-medium-r-normal--*-180-*-*-*-*-*-*'\n      else\n        font 'Helvetica 14'\n      end\n    }.pack('side'=>'top', 'fill'=>'x')\n    len = 1\n    args.each{|vnam,vbody|\n      len = vnam.to_s.length if vnam.to_s.length > len\n    }\n    args.each{|vnam,vbody|\n      TkFrame.new(base){|f|\n        #TkLabel.new(f, 'text'=>\"#{vnam}: \").pack('side'=>'left')\n        TkLabel.new(f, 'text'=>\"#{vnam}: \",'width'=>len+2).pack('side'=>'left')\n        TkLabel.new(f, 'textvariable'=>vbody, 'anchor'=>'w')\\\n                   .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x')\n      }.pack('side'=>'top', 'anchor'=>'w', 'fill'=>'x')\n    }\n    TkButton.new(base) {\n      text \"λ\"\n      command proc{w.destroy}\n    }.pack('side'=>'bottom', 'pady'=>2)\n  }\n  $showVarsWin[parent.path] = top\nend\n\ndef showVars2(parent, *args)\n  if $showVarsWin[parent.path]\n    begin\n      $showVarsWin[parent.path].destroy \n    rescue\n    end\n  end\n  $showVarsWin[parent.path] = TkToplevel.new(parent) {|top|\n    title \"Variable values\"\n\n    base = TkFrame.new(top).pack(:fill=>:both, :expand=>true)\n\n    TkLabelFrame.new(base, :text=>\"ѿ:\", \n                     :font=>{:family=>'Helvetica', :size=>14}){|f|\n      args.each{|vnam,vbody|\n        TkGrid(TkLabel.new(f, :text=>\"#{vnam}: \", :anchor=>'w'), \n               TkLabel.new(f, :textvariable=>vbody, :anchor=>'w'), \n               :padx=>2, :pady=>2, :sticky=>'w')\n      }\n\n      f.grid(:sticky=>'news', :padx=>4)\n      f.grid_columnconfig(1, :weight=>1)\n      f.grid_rowconfig(100, :weight=>1)\n    }\n    TkButton.new(base, :text=>\"λ\", :width=>8, :default=>:active, \n                 :command=>proc{top.destroy}){|b|\n      top.bind('Return', proc{b.invoke})\n      top.bind('Escape', proc{b.invoke})\n\n      b.grid(:sticky=>'e', :padx=>4, :pady=>[6, 4])\n    }\n    base.grid_columnconfig(0, :weight=>1)\n    base.grid_rowconfig(0, :weight=>1)\n  }\nend\n\nif $tk_major_ver < 8\n  alias showVars showVars1\nelsif $tk_major_ver == 8 && $tk_minor_ver < 4\n  alias showVars showVars1\nelse # ver >= 8.4\n  alias showVars showVars2\nend\n\n# ȥåץ٥륵ݡ\nmodule PseudoToplevel_Evaluable\n  def pseudo_toplevel_eval(body = Proc.new)\n    Thread.current[:TOPLEVEL] = self\n    begin\n      body.call\n    ensure\n      Thread.current[:TOPLEVEL] = nil\n    end\n  end\n\n  def pseudo_toplevel_evaluable?\n    @pseudo_toplevel_evaluable\n  end\n  def pseudo_toplevel_evaluable=(mode)\n    @pseudo_toplevel_evaluable = (mode)? true: false\n  end\n\n  def self.extended(mod)\n    mod.__send__(:extend_object, mod)\n    mod.instance_variable_set('@pseudo_toplevel_evaluable', true)\n  end\nend\n\nclass Object\n  alias __method_missing__ method_missing\n  private :__method_missing__\n\n  def method_missing(id, *args)\n    begin\n      has_top = (top = Thread.current[:TOPLEVEL]) && \n                   top.respond_to?(:pseudo_toplevel_evaluable?) && \n                   top.pseudo_toplevel_evaluable? && \n                   top.respond_to?(id)\n    rescue Exception => e\n      has_top = false\n    end\n\n    if has_top\n      top.__send__(id, *args)\n    else\n      __method_missing__(id, *args)\n    end\n  end\nend\n\nclass Proc\n  def initialize(*args, &b)\n    super\n    @__pseudo_toplevel__ = Thread.current[:TOPLEVEL]\n  end\n\n  alias __call__ call\n  def call(*args, &b)\n    if top = @__pseudo_toplevel__\n      orig_top = Thread.current[:TOPLEVEL]\n      Thread.current[:TOPLEVEL] = top\n      begin\n        __call__(*args, &b)\n      ensure\n        Thread.current[:TOPLEVEL] = orig_top\n      end\n    else\n      __call__(*args, &b)\n    end\n  end\nend\n\ndef proc(&b)\n  Proc.new(&b)\nend\ndef lambda(&b)\n  Proc.new(&b)\nend\n\ndef _null_binding\n  Module.new.instance_eval{extend PseudoToplevel_Evaluable}\n  # binding\n  # Module.new.instance_eval{binding}\nend\nprivate :_null_binding\n\ndef eval_samplecode(code, file=nil)\n  #eval(code)\n  #_null_binding.pseudo_toplevel_eval{ eval(code) }\n  #Thread.new{ _null_binding.pseudo_toplevel_eval{ eval(code) } }\n  Thread.new{\n    _null_binding.pseudo_toplevel_eval{\n      begin\n        if file\n          eval(code, binding, \"(eval:#{file})\")\n        else\n          eval(code)\n        end\n      rescue Exception=>e\n        #p e\n        TkBgError.show(e.message + \"\\n\" + \n                         \"\\n---< backtrace of Ruby side >-----\\n\" + \n                         e.backtrace.join(\"\\n\") + \n                         \"\\n---< backtrace of Tk side >-------\")\n      end\n    }\n  }\n  Tk.update\nend\n\n# ƥȾǤ click Фư\ndef invoke(txt, idx)\n  tag = txt.tag_names(idx).find{|t| t.kind_of?(String) && t =~ /^demo-/}\n  return unless tag\n\n  cursor = txt.cget('cursor')\n  txt.cursor('watch')\n  Tk.update\n  # eval(IO.readlines(\"#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb\").join, _null_binding)\n  # Tk.update\n  eval_samplecode(IO.readlines(\"#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb\").join, tag[5..-1] + '.rb')\n  txt.cursor(cursor)\n\n  $tag_visited.add(\"#{idx} linestart +1 chars\", \"#{idx} lineend +1 chars\")\nend\n=begin\ndef invoke (txt, idx)\n  tag = txt.tag_names(idx).find{|t| t.kind_of?(String) && t =~ /^demo-/}\n  return unless tag\n  current_cursor = txt.cget('cursor')\n  txt.cursor('watch')\n  Tk.update\n#  eval `cat #{tag[5..-1]}.rb`\n#  eval `cat #{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb`\n  eval IO.readlines(\"#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb\").join\n  Tk.update\n#  txt.cursor('xterm')\n  txt.cursor(current_cursor)\n\n  $tag_visited.add(\"#{idx} linestart +1 chars\", \"#{idx} lineend +1 chars\")\nend\n=end\n\n# ɽ\ndef showStatus (txt, index)\n  tag = txt.tag_names(index).find{|t| t.kind_of?(String) && t =~ /^demo-/}\n  cursor = txt.cget('cursor')\n  unless tag\n    $statusBarLabel.configure('text', \" \")\n    newcursor = 'xterm'\n  else\n    demoname = tag[5..-1]\n    $statusBarLabel.configure('text', \n                             \"ץץ \\\"#{demoname}\\\" μ¹ \")\n    newcursor = 'hand2'\n  end\n  txt.configure('cursor'=>newcursor) if cursor != newcursor\nend\n\n# ɤɽ\ndef showCode1(demo)\n  file = \"#{demo}.rb\"\n  $code_window = nil unless defined? $code_window\n  if $code_window == nil || TkWinfo.exist?($code_window) == false\n    $code_window = TkToplevel.new(nil)\n    f = TkFrame.new($code_window)\n\n    TkButton.new(f) {\n      #text \"λ\"\n      text \"Ĥ\"\n      command proc{\n        $code_window.destroy\n        $code_window = nil\n      }\n    }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2)\n    TkButton.new(f) {\n      text \"Ƽ¹\"\n      # command proc{eval($code_text.get('1.0','end'), _null_binding)}\n      command proc{eval_samplecode($code_text.get('1.0','end'), '<viewer>')}\n    }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2)\n\n    TkLabel.new(f,'text'=>'line:').pack('side'=>'left')\n    linenum =TkLabel.new(f,'text'=>'').pack('side'=>'left')\n    TkLabel.new(f,'text'=>'  pos:').pack('side'=>'left')\n    posnum =TkLabel.new(f,'text'=>'').pack('side'=>'left')\n\n    $set_linenum = proc{|w|\n      line, pos = w.index('insert').split('.')\n      linenum.text = line\n      posnum.text  = pos\n    }\n\n    f.pack('side'=>'bottom', 'expand'=>'true', 'fill'=>'x')\n\n    if $tk_version =~ /^4\\.[01]/\n      s = TkScrollbar.new($code_window, 'orient'=>'vertical')\n      $code_text = TkText.new($code_window) {\n        height 40\n        setgrid 'yes'\n        yscrollcommand proc{|first,last| s.set first,last}\n      }\n      s.command(proc{|*args| $code_text.yview(*args)})\n      s.pack('side'=>'right', 'fill'=>'y')\n      $code_text.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'both')\n    else\n      TkFrame.new($code_window) {|f|\n        pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1)\n\n        hs = TkScrollbar.new($code_window, 'highlightthickness'=>0, \n                             'orient'=>'horizontal')\n        vs = TkScrollbar.new($code_window, 'highlightthickness'=>0, \n                             'orient'=>'vertical')\n        $code_text = TkText.new($code_window) {|t|\n          height 40\n          #wrap 'word'\n          wrap 'char'\n          xscrollcommand proc{|first,last| hs.set first,last}\n          yscrollcommand proc{|first,last| vs.set first,last}\n          setgrid 'yes'\n          highlightthickness 0\n          pady 2\n          padx 3\n          hs.command(proc{|*args| $code_text.xview(*args)})\n          vs.command(proc{|*args| $code_text.yview(*args)})\n        }\n\n        $code_text.grid('in'=>f, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>0, \n                        'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n        vs.grid('in'=>f, 'padx'=>1, 'pady'=>1, 'row'=>0, 'column'=>1, \n                'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n#       xs.grid('in'=>f, 'padx'=>1, 'pady'=>1, 'row'=>1, 'column'=>0, \n#               'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news')\n        TkGrid.rowconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n        TkGrid.columnconfigure(f, 0, 'weight'=>1, 'minsize'=>0)\n      }\n    end\n\n    btag = TkBindTag.new\n\n    btag.bind('Key', $set_linenum, '%W')\n    btag.bind('Button', $set_linenum, '%W')\n\n    btags = $code_text.bindtags\n    btags.insert(btags.index($code_text.class) + 1, btag)\n    $code_text.bindtags = btags\n\n  else\n    $code_window.deiconify\n    $code_window.raise\n  end\n\n  $code_window.title(\"Demo code: #{file}\")\n  $code_window.iconname(file)\n#  fid = open(file, 'r')\n  fid = open([$demo_dir, file].join(File::Separator), 'r')\n  $code_text.delete('1.0', 'end')\n  #$code_text.insert('1.0', `cat #{file}`)\n  $code_text.insert('1.0', fid.read)\n  #$code_mark = TkTextMark.new($code_text, '1.0')\n  #$code_text.set_insert('1.0')\n  TkTextMarkInsert.new($code_text,'1.0')\n\n  $set_linenum.call($code_text)\n\n  fid.close\nend\n\ndef showCode2(demo)\n  file = \"#{demo}.rb\"\n  $code_window = nil unless defined? $code_window\n  if $code_window == nil || TkWinfo.exist?($code_window) == false\n    $code_window = TkToplevel.new(nil)\n    tf = TkFrame.new($code_window)\n    $code_text = TkText.new(tf, :font=>'Courier 10', :height=>30, \n                           :wrap=>'word', :bd=>1, :setgrid=>true, \n                           :highlightthickness=>0, :pady=>2, :padx=>3)\n    xscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)}\n    yscr = TkScrollbar.new(tf, :bd=>1){assign($code_text)}\n    TkGrid($code_text, yscr, :sticky=>'news')\n    #TkGrid(xscr)\n    tf.grid_rowconfigure(0, :weight=>1)\n    tf.grid_columnconfigure(0, :weight=>1)\n\n    bf = TkFrame.new($code_window)\n\n    lf = TkFrame.new(bf)\n    TkLabel.new(lf, :text=>'line:').pack(:side=>:left)\n    linenum =TkLabel.new(lf, :text=>'').pack(:side=>:left)\n    TkLabel.new(lf, :text=>'  pos:').pack(:side=>:left)\n    posnum =TkLabel.new(lf, :text=>'').pack(:side=>:left)\n\n    $set_linenum = proc{|w|\n      line, pos = w.index('insert').split('.')\n      linenum.text = line\n      posnum.text  = pos\n    }\n\n    #b_dis = TkButton.new(bf, :text=>'λ', :default=>:active, \n    b_dis = TkButton.new(bf, :text=>'Ĥ', :default=>:active, \n                         :command=>proc{\n                           $code_window.destroy\n                           $code_window = nil\n                         }, \n                         :image=>$image['delete'], :compound=>:left)\n    b_prn = TkButton.new(bf, :text=>'', \n                         :command=>proc{printCode($code_text, file)}, \n                         :image=>$image['print'], :compound=>:left)\n    b_run = TkButton.new(bf, :text=>'Ƽ¹', \n                         :command=>proc{\n                           # eval($code_text.get('1.0','end'), _null_binding)\n                           eval_samplecode($code_text.get('1.0','end'), '<viewer>')\n                         }, \n                         :image=>$image['refresh'], :compound=>:left)\n\n    TkGrid(lf, 'x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4])\n    bf.grid_columnconfigure(1, :weight=>1)\n\n    TkGrid(tf, :sticky=>'news')\n    TkGrid(bf, :sticky=>'ew')\n    $code_window.grid_columnconfigure(0, :weight=>1)\n    $code_window.grid_rowconfigure(0, :weight=>1)\n\n    $code_window.bind('Return', proc{|win|\n                        b_dis.invoke unless win.kind_of?(TkText)\n                      }, '%W')\n    $code_window.bindinfo('Return').each{|cmd, arg|\n      $code_window.bind_append('Escape', cmd, arg)\n    }\n\n    btag = TkBindTag.new\n\n    btag.bind('Key', $set_linenum, '%W')\n    btag.bind('Button', $set_linenum, '%W')\n\n    btags = $code_text.bindtags\n    btags.insert(btags.index($code_text.class) + 1, btag)\n    $code_text.bindtags = btags\n\n  else\n    $code_window.deiconify\n    $code_window.raise\n  end\n\n  $code_window.title(\"Demo code: #{file}\")\n  $code_window.iconname(file)\n  fid = open([$demo_dir, file].join(File::Separator), 'r')\n  $code_text.delete('1.0', 'end')\n  $code_text.insert('1.0', fid.read)\n  TkTextMarkInsert.new($code_text,'1.0')\n\n  $set_linenum.call($code_text)\n\n  fid.close\nend\n\nif $tk_major_ver < 8\n  alias showCode showCode1\nelsif $tk_major_ver == 8 && $tk_minor_ver < 4\n  alias showCode showCode1\nelse # ver >= 8.4\n  alias showCode showCode2\nend\n\n\n# printCode --\n# Prints the source code currently displayed in the See Code dialog.\n# Much thanks to Arjen Markus for this.\n#\n# Arguments:\n# txt -         Name of text widget containing code to print\n# file -        Name of the original file (implicitly for title)\n\ndef printCode(txt, file)\n  code = txt.get('1.0', 'end - 1c')\n  dir = '.'\n  dir = ENV['HOME'] if ENV['HOME']\n  dir = ENV['TMP'] if ENV['TMP']\n  dir = ENV['TEMP'] if ENV['TEMP']\n\n  fname = [dir, 'tkdemo-' + file].join(File::Separator)\n  open(fname, 'w'){|fid| fid.print(code)}\n  begin\n    case Tk::TCL_PLATFORM('platform')\n    when 'unix'\n      msg = `lp -c #{fname}`\n      unless $?.exitstatus == 0\n        Tk.messageBox(:title=>'Print spooling failure', \n                      :message=>'顼ȯޤ' + \n                                '˼ԤΤȻפޤ : ' + msg)\n      end\n    when 'windows'\n      begin\n        printTextWin32(fname)\n      rescue => e\n        Tk.messageBox(:title=>'Print spooling failure', \n                      :message=>'顼ȯޤ' + \n                                '˼ԤΤȻפޤ : ' + \n                                e.message)\n      end      \n    when 'macintosh'\n      Tk.messageBox(:title=>'Operation not Implemented', \n                    :message=>'ǽϤޤƤޤ')\n    else\n      Tk.messageBox(:title=>'Operation not Implemented', \n                    :message=>'Ф줿Ķ ' + \n                              Tk::TCL_PLATFORM('platform') + \n                              ' ̤ΤδĶǤ뤿ᡤ' + \n                              'ǽϼƤޤ: ')\n    end\n  ensure\n    File.delete(fname)\n  end\nend\n\n# printTextWin32 --\n#    Print a file under Windows\n#\n# Arguments:\n# filename -            Name of the file\n#\ndef printTextWin32(fname)\n  require 'win32/registry'\n  begin\n    app = Win32::Registry::HKEY_CLASSES_ROOT['.txt']\n    pcmd = nil\n    Win32::Registry::HKEY_CLASSES_ROOT.open(\"#{app}\\\\shell\\\\print\"){|reg|\n      pcmd = reg['command']\n    }\n  rescue\n    app = Tk.tk_call('auto_execok', 'notepad.exe')\n    pcmd = \"#{app} /p %1\"\n  end\n\n  pcmd.gsub!('%1', fname)\n  puts pcmd\n  cmd = Tk.tk_call('auto_execok', 'start') + ' /min ' + pcmd\n  \n  msg = `#{cmd}`\n  unless $?.exitstatus == 0\n    fail RuntimeError, msg\n  end\nend\n\n# aboutBox\n#\n#      Pops up a message box with an \"about\" message\n#\ndef aboutBox\n  Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', \n                'message'=>\"Ruby/Tk åȥǥ Ver.1.7.0-jp\\n\\n\" + \n                           \"based on demos of Tk8.1 -- 8.5  \" + \n                           \"( Copyright of Tcl/Tk demos:: \" + \n                           \"(c) 1996-1997 Sun Microsystems, Inc. / \" + \n                           \"(c) 1997-2000 Ajuba Solutions, Inc. / \" + \n                           \"(c) 2001-2007 Donal K. Fellows / \" + \n                           \"(c) 2002-2007 Daniel A. Steffen )\\n\\n\" +\n                           \"Your Ruby & Tk Version ::\\n\" + \n                           \"Ruby#{RUBY_VERSION}(#{RUBY_RELEASE_DATE})[#{RUBY_PLATFORM}] / Tk#{$tk_patchlevel}#{(Tk::JAPANIZED_TK)? '-jp': ''}\\n\\n\" + \n                           \"Ruby/Tk release date :: tcltklib #{TclTkLib::RELEASE_DATE}; tk #{Tk::RELEASE_DATE}\")\nend\n\n####################################\n# ǻꤵ줿ǥư\nno_launcher = false\nif ARGV[0] == '-n'\n  ARGV.shift\n  no_launcher = true if ARGV.size > 0\nelse\n  # show the root widget to make it lower then demo windows\n  Tk.update\nend\nARGV.each{|cmd| \n  if cmd =~ /(.*).rb/\n    cmd = $1\n  end\n  #eval(IO.readlines(\"#{[$demo_dir, cmd].join(File::Separator)}.rb\").join, \n  #     _null_binding)\n  eval_samplecode(IO.readlines(\"#{[$demo_dir, cmd].join(File::Separator)}.rb\").join, cmd + '.rb')\n}\nif no_launcher\n  $root.withdraw  # hide root window\n  Thread.start{\n    loop do\n      count = 0\n      $root.winfo_children.each{|w|\n        count += 1 if w.kind_of?(TkToplevel)\n      }\n      $root.destroy if count == 0\n    end\n  }\nend\n\n################################\n# ٥Ԥ\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/editable_listbox.rb",
    "content": "#\n# Editable_TkListbox class\n#\n#   When \"DoubleClick-1\" on a listbox item, the entry box is opend on the\n#   item. And when hit \"Return\" key on the entry box after modifying the\n#   text, the entry box is closed and the item is changed. Or when hit \n#   \"Escape\" key, the entry box is closed without modification.\n#\n#                              by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass Editable_TkListbox < TkListbox\n  def _ebox_placer(coord_y)\n    idx = self.nearest(coord_y)\n    x, y, w, h = self.bbox(idx)\n    @ebox.place(:x => 0, :relwidth => 1.0, \n                :y => y - self.selectborderwidth, \n                :height => h + 2 * self.selectborderwidth)\n    @ebox.pos = idx\n    @ebox.value = self.listvariable.list[idx]\n    @ebox.focus\n  end\n  private :_ebox_placer\n\n\n  def create_self(keys)\n    super(keys)\n\n    unless self.listvariable\n      self.listvariable = TkVariable.new(self.get(0, :end))\n    end\n\n    @ebox = TkEntry.new(self){\n      @pos = -1\n      def self.pos; @pos; end\n      def self.pos=(idx); @pos = idx; end\n    }\n\n    @ebox.bind('Return'){\n      list = self.listvariable.list\n      list[@ebox.pos] = @ebox.value\n      self.listvariable.value = list\n      @ebox.place_forget\n      @ebox.pos = -1\n    }\n\n    @ebox.bind('Escape'){\n      @ebox.place_forget\n      @ebox.pos = -1\n    }\n\n    self.bind('Double-1', '%y'){|y| _ebox_placer(y) }\n  end\nend\n\nif $0 == __FILE__\n  scr = TkScrollbar.new.pack(:side=>:right, :fill=>:y)\n\n  lbox1 = Editable_TkListbox.new.pack(:side=>:left)\n  lbox2 = Editable_TkListbox.new.pack(:side=>:left)\n\n  scr.assign(lbox1, lbox2)\n\n  lbox1.insert(:end, *%w(a b c d e f g h i j k l m n))\n  lbox2.insert(:end,     0,1,2,3,4,5,6,7,8,9,0,1,2,3)\n\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/encstr_usage.rb",
    "content": "require 'tk'\n\nTkMessage.new(:width=>400, :text=><<EOM).pack\nThis sample shows how to use Tk::EncodedString class. \\\nThis reads 'iso2022-kr' text (from discription of \\\nKorean language environment of GNU Emacs 20.7.2) \\\nand inserts the text into the text widget.\nEOM\n\nt1 = TkText.new(:height=>5).pack\nt2 = TkText.new(:height=>5).pack\nt3 = TkText.new(:height=>5).pack\n\nsrc_str = IO.readlines(File.join(File.dirname(__FILE__),'iso2022-kr.txt')).join\n\nt1.insert('end', \n          \"use neither Tk::EncodedString class nor Tk.encoding= method\\n\\n\")\nt1.insert('end', src_str)\n\nenc_str = Tk::EncodedString(src_str, 'iso2022-kr')\nt2.insert('end', \n          \"use Tk::EncodedString class (Tk.encoding => '#{Tk.encoding}')\\n\\n\")\nt2.insert('end', enc_str)\n\nTk.encoding = 'iso2022-kr'\nt3.insert('end', \"use Tk.encoding = 'iso2022-kr' (Tk.force_default_encoding? == #{Tk.force_default_encoding?})\\n\\n\")\n\nt3.insert('end', src_str)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/figmemo_sample.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\n\nbegin\n  # try to use Img extension\n  require 'tkextlib/tkimg'\nrescue Exception\n  # cannot use Img extention --> ignore\nend\n\n\n############################\n# scrolled_canvas\nclass TkScrolledCanvas < TkCanvas\n  include TkComposite\n\n  def initialize_composite(keys={})\n    @h_scr = TkScrollbar.new(@frame)\n    @v_scr = TkScrollbar.new(@frame)\n\n    @canvas = TkCanvas.new(@frame)\n    @path = @canvas.path\n\n    @canvas.xscrollbar(@h_scr)\n    @canvas.yscrollbar(@v_scr)\n\n    TkGrid.rowconfigure(@frame, 0, :weight=>1, :minsize=>0)\n    TkGrid.columnconfigure(@frame, 0, :weight=>1, :minsize=>0)\n\n    @canvas.grid(:row=>0, :column=>0, :sticky=>'news')\n    @h_scr.grid(:row=>1, :column=>0, :sticky=>'ew')\n    @v_scr.grid(:row=>0, :column=>1, :sticky=>'ns')\n\n    delegate('DEFAULT', @canvas)\n    delegate('background', @canvas, @h_scr, @v_scr)\n    delegate('activebackground', @h_scr, @v_scr)\n    delegate('troughcolor', @h_scr, @v_scr)\n    delegate('repeatdelay', @h_scr, @v_scr)\n    delegate('repeatinterval', @h_scr, @v_scr)\n    delegate('borderwidth', @frame)\n    delegate('relief', @frame)\n\n    delegate_alias('canvasborderwidth', 'borderwidth', @canvas)\n    delegate_alias('canvasrelief', 'relief', @canvas)\n\n    delegate_alias('scrollbarborderwidth', 'borderwidth', @h_scr, @v_scr)\n    delegate_alias('scrollbarrelief', 'relief', @h_scr, @v_scr)\n\n    configure(keys) unless keys.empty?\n  end\nend\n\n############################\nclass PhotoCanvas < TkScrolledCanvas\n\nUSAGE = <<EOT\n--- WHAT IS ---\nYou can write comments on the loaded image, and save it as a Postscipt \nfile (original image file is not modified). Each comment is drawn as a \nset of an indicator circle, an arrow, and a memo text. See the following \nhow to write comments.\nThis can save the list of memo texts to another file. It may useful to \nsearch the saved Postscript file by the comments on them.\nThis may not support multibyte characters (multibyte texts are broken on \na Postscript file). It depends on features of canvas widgets of Tcl/Tk \nlibraries linked your Ruby/Tk. If you use Tcl/Tk8.0-jp (Japanized Tcl/Tk),\nyou can (possibly) get a Japanese Postscript file.\n\n--- BINDINGS ---\n* Button-1 : draw comments by following steps\n    1st - Set center of a indicator circle.\n    2nd - Set head position of an arrow.\n    3rd - Set tail position of an arrow, and show an entry box.\n          Input a memo text and hit 'Enter' key to entry the comment.\n\n* Button-2-drag : scroll the canvas\n\n* Button-3 : when drawing, cancel current drawing\n\n* Double-Button-3 : delete the clicked comment (text, arrow, and circle)\nEOT\n\n  def initialize(*args)\n    super(*args)\n\n    self.highlightthickness = 0\n    self.selectborderwidth = 0\n\n    @photo = TkPhotoImage.new\n    @img = TkcImage.new(self, 0, 0, :image=>@photo)\n\n    width  = self.width\n    height = self.height\n    @scr_region = [-width, -height, width, height]\n    self.scrollregion(@scr_region)\n    self.xview_moveto(0.25)\n    self.yview_moveto(0.25)\n\n    @col = 'red'\n    @font = 'Helvetica -12'\n\n    @memo_id_num = -1\n    @memo_id_head = 'memo_'\n    @memo_id_tag = nil\n    @overlap_d = 2\n\n    @state = TkVariable.new\n    @border = 2\n    @selectborder = 1\n    @delta = @border + @selectborder\n    @entry = TkEntry.new(self, :relief=>:ridge, :borderwidth=>@border, \n                         :selectborderwidth=>@selectborder, \n                         :highlightthickness=>0)\n    @entry.bind('Return'){@state.value = 0}\n\n    @mode = old_mode = 0\n\n    _state0()\n\n    bind('2', :x, :y){|x,y| scan_mark(x,y)}\n    bind('B2-Motion', :x, :y){|x,y| scan_dragto(x,y)}\n\n    bind('3'){\n      next if (old_mode = @mode) == 0\n      @items.each{|item| item.delete }\n      _state0()\n    }\n\n    bind('Double-3', :widget, :x, :y){|w, x, y|\n      next if old_mode != 0\n      x = w.canvasx(x)\n      y = w.canvasy(y)\n      tag = nil\n      w.find_overlapping(x - @overlap_d, y - @overlap_d, \n                         x + @overlap_d, y + @overlap_d).find{|item|\n        ! (item.tags.find{|name|\n             if name =~ /^(#{@memo_id_head}\\d+)$/\n               tag = $1\n             end\n           }.empty?)\n      }\n      w.delete(tag) if tag\n    }\n  end\n\n  #-----------------------------------\n  private\n  def _state0() # init\n    @mode = 0\n\n    @memo_id_num += 1\n    @memo_id_tag = @memo_id_head + @memo_id_num.to_s\n\n    @target = nil\n    @items = []\n    @mark = [0, 0]\n    bind_remove('Motion')\n    bind('ButtonRelease-1', proc{|x,y| _state1(x,y)}, '%x', '%y')\n  end\n\n  def _state1(x,y) # set center\n    @mode = 1\n\n    @target = TkcOval.new(self, \n                          [canvasx(x), canvasy(y)], [canvasx(x), canvasy(y)], \n                          :outline=>@col, :width=>3, :tags=>[@memo_id_tag])\n    @items << @target\n    @mark = [x,y]\n\n    bind('Motion', proc{|x,y| _state2(x,y)}, '%x', '%y')\n    bind('ButtonRelease-1', proc{|x,y| _state3(x,y)}, '%x', '%y')\n  end\n\n  def _state2(x,y) # create circle\n    @mode = 2\n\n    r = Integer(Math.sqrt((x-@mark[0])**2 + (y-@mark[1])**2))\n    @target.coords([canvasx(@mark[0] - r), canvasy(@mark[1] - r)], \n                   [canvasx(@mark[0] + r), canvasy(@mark[1] + r)])\n  end\n\n  def _state3(x,y) # set line start\n    @mode = 3\n\n    @target = TkcLine.new(self, \n                          [canvasx(x), canvasy(y)], [canvasx(x), canvasy(y)], \n                          :arrow=>:first, :arrowshape=>[10, 14, 5], \n                          :fill=>@col, :tags=>[@memo_id_tag])\n    @items << @target\n    @mark = [x, y]\n\n    bind('Motion', proc{|x,y| _state4(x,y)}, '%x', '%y')\n    bind('ButtonRelease-1', proc{|x,y| _state5(x,y)}, '%x', '%y')\n  end\n\n  def _state4(x,y) # create line\n    @mode = 4\n\n    @target.coords([canvasx(@mark[0]), canvasy(@mark[1])], \n                   [canvasx(x), canvasy(y)])\n  end\n\n  def _state5(x,y) # set text\n    @mode = 5\n\n    if x - @mark[0] >= 0\n      justify = 'left'\n      dx = - @delta\n\n      if y - @mark[1] >= 0\n        anchor = 'nw'\n        dy = - @delta\n      else\n        anchor = 'sw'\n        dy = @delta\n      end\n    else\n      justify = 'right'\n      dx = @delta\n\n      if y - @mark[1] >= 0\n        anchor = 'ne'\n        dy = - @delta\n      else\n        anchor = 'se'\n        dy = @delta\n      end\n    end\n\n    bind_remove('Motion')\n\n    @entry.value = ''\n    @entry.configure(:justify=>justify, :font=>@font, :foreground=>@col)\n\n    ewin = TkcWindow.new(self, [canvasx(x)+dx, canvasy(y)+dy], \n                         :window=>@entry, :state=>:normal, :anchor=>anchor, \n                         :tags=>[@memo_id_tag])\n\n    @entry.focus\n    @entry.grab\n    @state.wait\n    @entry.grab_release\n\n    ewin.delete\n\n    @target = TkcText.new(self, [canvasx(x), canvasy(y)], \n                          :anchor=>anchor, :justify=>justify, \n                          :fill=>@col, :font=>@font, :text=>@entry.value, \n                          :tags=>[@memo_id_tag])\n\n    _state0()\n  end\n\n  #-----------------------------------\n  public\n  def load_photo(filename)\n    @photo.configure(:file=>filename)\n  end\n\n  def modified?\n    ! ((find_withtag('all') - [@img]).empty?)\n  end\n\n  def fig_erase\n    (find_withtag('all') - [@img]).each{|item| item.delete}\n  end\n\n  def reset_region\n    width = @photo.width\n    height = @photo.height\n\n    if width > @scr_region[2]\n      @scr_region[0] = -width\n      @scr_region[2] = width\n    end\n\n    if height > @scr_region[3]\n      @scr_region[1] = -height\n      @scr_region[3] = height\n    end\n\n    self.scrollregion(@scr_region)\n    self.xview_moveto(0.25)\n    self.yview_moveto(0.25)\n  end\n\n  def get_texts\n    ret = []\n    find_withtag('all').each{|item|\n      if item.kind_of?(TkcText)\n        ret << item[:text]\n      end\n    }\n    ret\n  end\nend\n############################\n\n# define methods for menu\ndef open_file(canvas, fname)\n  if canvas.modified?\n    ret = Tk.messageBox(:icon=>'warning',:type=>'okcancel',:default=>'cancel',\n                        :message=>'Canvas may be modified. Realy erase? ')\n    return if ret == 'cancel'\n  end\n\n  filetypes = [\n    ['GIF Files', '.gif'], \n    ['GIF Files', [], 'GIFF'], \n    ['PPM Files', '.ppm'], \n    ['PGM Files', '.pgm']\n  ]\n\n  begin\n    if Tk::Img::package_version != ''\n      filetypes << ['JPEG Files', ['.jpg', '.jpeg']]\n      filetypes << ['PNG Files', '.png']\n      filetypes << ['PostScript Files', '.ps']\n      filetypes << ['PDF Files', '.pdf']\n      filetypes << ['Windows Bitmap Files', '.bmp']\n      filetypes << ['Windows Icon Files', '.ico']\n      filetypes << ['PCX Files', '.pcx']\n      filetypes << ['Pixmap Files', '.pixmap']\n      filetypes << ['SGI Files', '.sgi']\n      filetypes << ['Sun Raster Files', '.sun']\n      filetypes << ['TGA Files', '.tga']\n      filetypes << ['TIFF Files', '.tiff']\n      filetypes << ['XBM Files', '.xbm']\n      filetypes << ['XPM Files', '.xpm']\n    end\n  rescue\n  end\n\n  filetypes << ['ALL Files', '*']\n\n  fpath = Tk.getOpenFile(:filetypes=>filetypes)\n  return if fpath.empty?\n\n  begin\n    canvas.load_photo(fpath)\n  rescue => e\n    Tk.messageBox(:icon=>'error', :type=>'ok', \n                  :message=>\"Fail to read '#{fpath}'.\\n#{e.message}\")\n  end\n\n  canvas.fig_erase\n  canvas.reset_region\n\n  fname.value = fpath\nend\n\n# --------------------------------\ndef save_memo(canvas, fname)\n  initname = fname.value\n  if initname != '-'\n    initname = File.basename(initname, File.extname(initname))\n    fpath = Tk.getSaveFile(:filetypes=>[ ['Text Files', '.txt'], \n                                         ['ALL Files', '*'] ], \n                           :initialfile=>initname)\n  else\n    fpath = Tk.getSaveFile(:filetypes=>[ ['Text Files', '.txt'], \n                                         ['ALL Files', '*'] ])\n  end\n  return if fpath.empty?\n\n  begin\n    fid = open(fpath, 'w')\n  rescue => e\n    Tk.messageBox(:icon=>'error', :type=>'ok', \n                  :message=>\"Fail to open '#{fname.value}'.\\n#{e.message}\")\n  end\n\n  begin\n    canvas.get_texts.each{|txt|\n      fid.print(txt, \"\\n\")\n    }\n  ensure\n    fid.close\n  end\nend\n\n# --------------------------------\ndef ps_print(canvas, fname)\n  initname = fname.value\n  if initname != '-'\n    initname = File.basename(initname, File.extname(initname))\n    fpath = Tk.getSaveFile(:filetypes=>[ ['Postscript Files', '.ps'], \n                                         ['ALL Files', '*'] ], \n                           :initialfile=>initname)\n  else\n    fpath = Tk.getSaveFile(:filetypes=>[ ['Postscript Files', '.ps'], \n                                         ['ALL Files', '*'] ])\n  end\n  return if fpath.empty?\n\n  bbox = canvas.bbox('all')\n  canvas.postscript(:file=>fpath, :x=>bbox[0], :y=>bbox[1], \n                    :width=>bbox[2] - bbox[0], :height=>bbox[3] - bbox[1])\nend\n\n# --------------------------------\ndef quit(canvas)\n  ret = Tk.messageBox(:icon=>'warning', :type=>'okcancel', \n                      :default=>'cancel', \n                      :message=>'Realy quit? ')\n  exit if ret == 'ok'\nend\n\n# --------------------------------\n# setup root\nroot = TkRoot.new(:title=>'Fig Memo')\n\n# create canvas frame\ncanvas = PhotoCanvas.new(root).pack(:fill=>:both, :expand=>true)\nusage_frame = TkFrame.new(root, :relief=>:ridge, :borderwidth=>2)\nhide_btn = TkButton.new(usage_frame, :text=>'hide usage', \n                        :font=>{:size=>8}, :pady=>1, \n                        :command=>proc{usage_frame.unpack})\nhide_btn.pack(:anchor=>'e', :padx=>5)\nusage = TkLabel.new(usage_frame, :text=>PhotoCanvas::USAGE, \n                    :font=>'Helvetica 8', :justify=>:left).pack\n\nshow_usage = proc{\n  usage_frame.pack(:before=>canvas, :fill=>:x, :expand=>true)\n}\n\nfname = TkVariable.new('-')\nf = TkFrame.new(root, :relief=>:sunken, :borderwidth=>1).pack(:fill=>:x)\nlabel = TkLabel.new(f, :textvariable=>fname, \n                    :font=>{:size=>-12, :weight=>:bold}, \n                    :anchor=>'w').pack(:side=>:left, :fill=>:x, :padx=>10)\n\n# create menu\nmspec = [\n  [ ['File', 0], \n    ['Show Usage',      proc{show_usage.call}, 5], \n    '---', \n    ['Open Image File', proc{open_file(canvas, fname)}, 0], \n    ['Save Memo Texts', proc{save_memo(canvas, fname)}, 0], \n    '---', \n    ['Save Postscript', proc{ps_print(canvas, fname)}, 5], \n    '---', \n    ['Quit', proc{quit(canvas)}, 0]\n  ]\n]\nroot.add_menubar(mspec)\n\n# manage wm_protocol\nroot.protocol(:WM_DELETE_WINDOW){quit(canvas)}\n\n# show usage\nshow_usage.call\n\n# --------------------------------\n# start eventloop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/images/face.xbm",
    "content": "#define face_width 108\n#define face_height 144\n#define face_x_hot 48\n#define face_y_hot 80\nstatic char face_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09,\n   0x20, 0x80, 0x24, 0x05, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x88,\n   0x24, 0x20, 0x80, 0x24, 0x00, 0x00, 0x00, 0x10, 0x80, 0x04, 0x00, 0x01,\n   0x00, 0x01, 0x40, 0x0a, 0x09, 0x00, 0x92, 0x04, 0x80, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x10, 0x40, 0x12, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x84,\n   0x24, 0x40, 0x22, 0xa8, 0x02, 0x14, 0x84, 0x92, 0x40, 0x42, 0x12, 0x04,\n   0x10, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x52, 0x11, 0x00, 0x12, 0x00,\n   0x40, 0x02, 0x00, 0x20, 0x00, 0x08, 0x00, 0xaa, 0x02, 0x54, 0x85, 0x24,\n   0x00, 0x10, 0x12, 0x00, 0x00, 0x81, 0x44, 0x00, 0x90, 0x5a, 0x00, 0xea,\n   0x1b, 0x00, 0x80, 0x40, 0x40, 0x02, 0x00, 0x08, 0x00, 0x20, 0xa2, 0x05,\n   0x8a, 0xb4, 0x6e, 0x45, 0x12, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10, 0x02,\n   0xa8, 0x92, 0x00, 0xda, 0x5f, 0x10, 0x00, 0x10, 0xa1, 0x04, 0x20, 0x41,\n   0x02, 0x00, 0x5a, 0x25, 0xa0, 0xff, 0xfb, 0x05, 0x41, 0x02, 0x04, 0x00,\n   0x00, 0x08, 0x40, 0x80, 0xec, 0x9b, 0xec, 0xfe, 0x7f, 0x01, 0x04, 0x20,\n   0x90, 0x02, 0x04, 0x00, 0x08, 0x20, 0xfb, 0x2e, 0xf5, 0xff, 0xff, 0x57,\n   0x00, 0x04, 0x02, 0x00, 0x00, 0x20, 0x01, 0xc1, 0x6e, 0xab, 0xfa, 0xff,\n   0xff, 0x05, 0x90, 0x20, 0x48, 0x02, 0x00, 0x04, 0x20, 0xa8, 0xdf, 0xb5,\n   0xfe, 0xff, 0xff, 0x0b, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x04, 0xe0,\n   0xbb, 0xef, 0xff, 0xff, 0x7f, 0x01, 0x00, 0x04, 0x48, 0x02, 0x00, 0x20,\n   0x80, 0xf4, 0x6f, 0xfb, 0xff, 0xff, 0xff, 0x20, 0x90, 0x40, 0x02, 0x00,\n   0x00, 0x04, 0x08, 0xb8, 0xf6, 0xff, 0xff, 0xdf, 0xbe, 0x12, 0x45, 0x10,\n   0x90, 0x04, 0x90, 0x00, 0x22, 0xfa, 0xff, 0xff, 0xff, 0xbb, 0xd7, 0xe9,\n   0x3a, 0x02, 0x02, 0x00, 0x04, 0x90, 0x80, 0xfe, 0xdf, 0xf6, 0xb7, 0xef,\n   0xbe, 0x56, 0x57, 0x40, 0x48, 0x09, 0x00, 0x04, 0x00, 0xfa, 0xf5, 0xdf,\n   0xed, 0x5a, 0xd5, 0xea, 0xbd, 0x09, 0x00, 0x00, 0x40, 0x00, 0x92, 0xfe,\n   0xbf, 0x7d, 0xb7, 0x6a, 0x55, 0xbf, 0xf7, 0x02, 0x11, 0x01, 0x00, 0x91,\n   0x00, 0xff, 0xff, 0xaf, 0x55, 0x55, 0x5b, 0xeb, 0xef, 0x22, 0x04, 0x04,\n   0x04, 0x00, 0xa4, 0xff, 0xf7, 0xad, 0xaa, 0xaa, 0xaa, 0xbe, 0xfe, 0x03,\n   0x20, 0x00, 0x10, 0x44, 0x80, 0xff, 0x7f, 0x55, 0x12, 0x91, 0x2a, 0xeb,\n   0xbf, 0x0b, 0x82, 0x02, 0x00, 0x00, 0xd1, 0x7f, 0xdf, 0xa2, 0xa4, 0x54,\n   0x55, 0xfd, 0xfd, 0x47, 0x08, 0x08, 0x00, 0x21, 0xe4, 0xff, 0x37, 0x11,\n   0x09, 0xa5, 0xaa, 0xb6, 0xff, 0x0d, 0x80, 0x00, 0x00, 0x04, 0xd0, 0xff,\n   0x4f, 0x44, 0x20, 0x48, 0x55, 0xfb, 0xff, 0x27, 0x11, 0x02, 0x40, 0x40,\n   0xe2, 0xfb, 0x15, 0x11, 0x4a, 0x55, 0x4a, 0x7d, 0xf7, 0x0f, 0x00, 0x00,\n   0x04, 0x08, 0xf8, 0xdf, 0x52, 0x44, 0x01, 0x52, 0xb5, 0xfa, 0xff, 0x0f,\n   0x49, 0x02, 0x00, 0x02, 0xe9, 0xf6, 0x0a, 0x11, 0xa4, 0x88, 0x4a, 0x6d,\n   0xff, 0x5f, 0x00, 0x00, 0x10, 0x20, 0xf0, 0x2f, 0x21, 0x44, 0x10, 0x52,\n   0xb5, 0xfa, 0xff, 0x0f, 0x44, 0x04, 0x80, 0x08, 0xf8, 0xab, 0x8a, 0x00,\n   0x81, 0xa4, 0xd4, 0xd6, 0xfe, 0x2f, 0x00, 0x00, 0x04, 0x40, 0xb5, 0x2d,\n   0x21, 0x08, 0x04, 0x90, 0xaa, 0xfa, 0xff, 0x1f, 0x11, 0x01, 0x00, 0x04,\n   0xf0, 0x57, 0x0a, 0x22, 0x40, 0x4a, 0xda, 0x5e, 0xfb, 0x1f, 0x40, 0x00,\n   0x40, 0x20, 0xba, 0x95, 0x90, 0x00, 0x01, 0xa0, 0xaa, 0xea, 0xff, 0x5f,\n   0x02, 0x02, 0x00, 0x01, 0xe8, 0x57, 0x05, 0x00, 0x00, 0x12, 0xd5, 0xfe,\n   0xfd, 0x1f, 0x48, 0x00, 0x04, 0x48, 0x7a, 0x95, 0x08, 0x02, 0x10, 0x40,\n   0xaa, 0x55, 0xf7, 0x1f, 0x00, 0x09, 0x20, 0x00, 0xf8, 0x57, 0x22, 0x10,\n   0x00, 0x28, 0xa9, 0xfa, 0xff, 0x5f, 0x02, 0x00, 0x00, 0x49, 0xdd, 0x29,\n   0x01, 0x00, 0x80, 0x80, 0xaa, 0xd7, 0xff, 0x0f, 0x10, 0x00, 0x08, 0x00,\n   0xf8, 0x96, 0x08, 0x00, 0x00, 0x20, 0x54, 0xfa, 0xee, 0x3f, 0x81, 0x04,\n   0x40, 0x24, 0xfe, 0x55, 0x82, 0x00, 0x00, 0x82, 0xd2, 0xad, 0xff, 0x0f,\n   0x08, 0x00, 0x04, 0x80, 0x6c, 0x97, 0x00, 0x00, 0x02, 0x20, 0xa9, 0xf6,\n   0xdf, 0x5f, 0x00, 0x02, 0x20, 0x09, 0xfa, 0x49, 0x12, 0x00, 0x20, 0x84,\n   0x54, 0xdb, 0xfe, 0x1f, 0x91, 0x00, 0x00, 0x00, 0xf8, 0x2b, 0x00, 0x20,\n   0x00, 0x40, 0xa4, 0xf6, 0xbb, 0x1f, 0x04, 0x00, 0x44, 0x92, 0x7e, 0x95,\n   0x02, 0x00, 0x00, 0x89, 0xaa, 0xdd, 0xff, 0x1f, 0x20, 0x09, 0x10, 0x00,\n   0xf4, 0x57, 0x20, 0x01, 0x08, 0x20, 0xa9, 0x76, 0xff, 0x5f, 0x02, 0x00,\n   0x00, 0x21, 0xfc, 0x4a, 0x05, 0x00, 0x01, 0x80, 0x54, 0xdb, 0xff, 0x1e,\n   0x08, 0x02, 0x04, 0x08, 0xf9, 0x2b, 0x00, 0x00, 0x40, 0x28, 0xd2, 0xf6,\n   0xff, 0xbf, 0x80, 0x00, 0x90, 0x00, 0xbc, 0x92, 0x08, 0x10, 0x00, 0x82,\n   0x54, 0xdb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x44, 0xf9, 0x55, 0x02, 0x01,\n   0x00, 0x20, 0xaa, 0xbd, 0xfd, 0x3f, 0x08, 0x04, 0x04, 0x10, 0xf4, 0x2a,\n   0x01, 0x00, 0x22, 0x80, 0xd4, 0xf6, 0xff, 0x5f, 0x82, 0x00, 0x40, 0x02,\n   0xf8, 0x55, 0x20, 0x00, 0x00, 0x50, 0x6a, 0xdf, 0xfe, 0x3f, 0x00, 0x00,\n   0x00, 0x48, 0xe9, 0x4a, 0x05, 0x08, 0x00, 0xa5, 0xd5, 0xf5, 0xff, 0x3f,\n   0x10, 0x01, 0x10, 0x01, 0xb0, 0xab, 0x92, 0x02, 0x40, 0xf8, 0xbf, 0xde,\n   0xfe, 0x5f, 0x02, 0x04, 0x04, 0x48, 0xfa, 0xd4, 0x6f, 0x20, 0x84, 0xef,\n   0xff, 0xfb, 0xff, 0x1f, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xed, 0xbf, 0x0b,\n   0xa1, 0x7e, 0xff, 0xbf, 0xfd, 0x5f, 0x04, 0x01, 0x20, 0x49, 0xd2, 0xfb,\n   0xfe, 0x55, 0xd4, 0xff, 0xff, 0xf6, 0xff, 0x07, 0x00, 0x04, 0x00, 0x00,\n   0xc0, 0xaa, 0xfb, 0x2b, 0xa2, 0xfe, 0xff, 0xdf, 0xee, 0x1f, 0x91, 0x00,\n   0x82, 0xa4, 0xa4, 0xf5, 0xff, 0x57, 0xd5, 0xff, 0xbf, 0xfd, 0xff, 0x4d,\n   0x00, 0x00, 0x20, 0x00, 0x88, 0x5b, 0xff, 0x2f, 0x69, 0xff, 0xff, 0xdb,\n   0xfe, 0x1f, 0x24, 0x02, 0x00, 0x49, 0xa2, 0xd6, 0xff, 0x5f, 0xea, 0xff,\n   0x7f, 0x7f, 0x7f, 0x0d, 0x00, 0x00, 0x10, 0x00, 0x40, 0xab, 0xf7, 0xbb,\n   0xf0, 0xdf, 0xff, 0xd5, 0xff, 0xbf, 0x82, 0x04, 0x42, 0x24, 0x91, 0xd5,\n   0xaa, 0xae, 0xd4, 0xaa, 0x52, 0x7b, 0xff, 0x15, 0x08, 0x00, 0x00, 0x01,\n   0x04, 0x55, 0xd5, 0x55, 0x70, 0x5b, 0x75, 0xdd, 0xdf, 0x1f, 0x40, 0x00,\n   0x08, 0x48, 0xa0, 0x4a, 0xa9, 0x56, 0xea, 0x56, 0xad, 0x6a, 0x7d, 0x9b,\n   0x04, 0x01, 0x00, 0x02, 0x42, 0x2a, 0xd5, 0xaa, 0xa8, 0xaa, 0xaa, 0xfa,\n   0xdf, 0x2f, 0x10, 0x04, 0x22, 0x48, 0x08, 0x45, 0x2a, 0x15, 0x68, 0x55,\n   0x55, 0xd7, 0x76, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x40, 0x2a, 0x80, 0xa0,\n   0xb2, 0x09, 0x48, 0xb9, 0xdf, 0x17, 0x22, 0x01, 0x00, 0x24, 0x45, 0x8a,\n   0x24, 0x4a, 0x54, 0x51, 0x91, 0xf6, 0x6e, 0x4b, 0x00, 0x04, 0x90, 0x00,\n   0x80, 0x52, 0x00, 0x20, 0x69, 0x05, 0xa4, 0xaa, 0xff, 0x1e, 0x48, 0x00,\n   0x02, 0x92, 0x08, 0x05, 0x81, 0x94, 0xd4, 0x92, 0x40, 0xfd, 0xb6, 0x8b,\n   0x00, 0x01, 0x40, 0x00, 0x82, 0x54, 0x00, 0x48, 0x68, 0x05, 0x90, 0xa4,\n   0xef, 0x06, 0x24, 0x00, 0x08, 0x12, 0x10, 0x05, 0x00, 0x10, 0xb5, 0x01,\n   0x42, 0xfb, 0xbf, 0x43, 0x00, 0x09, 0x00, 0x40, 0x81, 0xa8, 0x08, 0x4a,\n   0xaa, 0x96, 0x90, 0xac, 0x6d, 0x15, 0x22, 0x00, 0x20, 0x09, 0x04, 0x15,\n   0x80, 0x28, 0xdc, 0x01, 0x24, 0xfb, 0xbf, 0x01, 0x80, 0x04, 0x09, 0x00,\n   0x40, 0x48, 0x02, 0x45, 0xb2, 0x2e, 0x41, 0x6d, 0xef, 0x05, 0x11, 0x00,\n   0x40, 0x52, 0x02, 0x15, 0x29, 0x2a, 0xac, 0x42, 0x54, 0xfb, 0x3b, 0x51,\n   0x84, 0x00, 0x08, 0x00, 0x20, 0x54, 0x80, 0x05, 0xb5, 0x3d, 0xa2, 0xb6,\n   0xdf, 0x00, 0x20, 0x04, 0x20, 0x49, 0x89, 0xa8, 0x6a, 0x29, 0xac, 0xd6,\n   0x54, 0xff, 0x3f, 0x84, 0x00, 0x01, 0x04, 0x10, 0x00, 0x94, 0xa8, 0x56,\n   0xda, 0x5f, 0xab, 0xd5, 0x1e, 0x10, 0x48, 0x00, 0x90, 0x82, 0x48, 0xa8,\n   0xb2, 0xac, 0xfd, 0x55, 0xd5, 0xfe, 0x9f, 0x80, 0x00, 0x0a, 0x02, 0x08,\n   0x02, 0x55, 0x5a, 0x75, 0xff, 0xaf, 0xb6, 0xf7, 0x2d, 0x12, 0x92, 0x00,\n   0x10, 0x20, 0x10, 0xa8, 0x54, 0xd5, 0xbf, 0x5d, 0xad, 0xdd, 0x0f, 0x00,\n   0x00, 0x04, 0x40, 0x09, 0x84, 0xa8, 0xaa, 0x5a, 0xed, 0xeb, 0x6a, 0xff,\n   0x9f, 0xa4, 0x24, 0x01, 0x02, 0xa0, 0x20, 0x50, 0x55, 0xd5, 0xbe, 0xae,\n   0xad, 0xfd, 0x16, 0x00, 0x10, 0x04, 0x20, 0x0a, 0x08, 0xb4, 0xaa, 0x95,\n   0xaa, 0x7b, 0xb7, 0xdb, 0x5f, 0x92, 0x04, 0x01, 0x84, 0x20, 0x21, 0x51,\n   0xd5, 0x2a, 0xa9, 0xee, 0xd5, 0xfe, 0x0d, 0x00, 0x20, 0x04, 0x10, 0x00,\n   0x08, 0x50, 0xe9, 0xd7, 0xd4, 0xfb, 0xb5, 0xff, 0x9f, 0x24, 0x09, 0x01,\n   0x42, 0x4a, 0xa2, 0x64, 0xd5, 0x55, 0x7b, 0x7f, 0xda, 0x7d, 0x4f, 0x00,\n   0x20, 0x04, 0x00, 0x80, 0x00, 0xa0, 0x2a, 0x13, 0x84, 0x6a, 0x55, 0xff,\n   0x1d, 0x48, 0x8a, 0x00, 0x94, 0x24, 0x8a, 0xc8, 0xaa, 0x42, 0x20, 0x5d,\n   0xf5, 0xff, 0x5f, 0x01, 0x00, 0x02, 0x01, 0x00, 0x20, 0xa2, 0x4a, 0x1a,\n   0x82, 0x56, 0xda, 0xbd, 0x3f, 0x92, 0x92, 0x00, 0x90, 0x92, 0x00, 0x40,\n   0x95, 0x6a, 0xf4, 0x55, 0x6d, 0xff, 0xd6, 0x00, 0x00, 0x0a, 0x04, 0x20,\n   0x14, 0x49, 0x4b, 0xaa, 0xaa, 0x56, 0xf5, 0xff, 0xbf, 0xab, 0xa4, 0x00,\n   0x20, 0x89, 0x40, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 0xde, 0xbf, 0xeb, 0x03,\n   0x00, 0x02, 0x04, 0x02, 0x0a, 0x10, 0x2b, 0x2a, 0x55, 0x5b, 0xf5, 0xff,\n   0xd7, 0x2f, 0x92, 0x00, 0x10, 0x28, 0x21, 0x01, 0x56, 0x95, 0xa0, 0x56,\n   0xdf, 0xef, 0xea, 0x87, 0x40, 0x0a, 0x42, 0x41, 0x00, 0x90, 0xaa, 0x52,\n   0xb6, 0xad, 0xfa, 0xff, 0xd5, 0x2f, 0x14, 0x00, 0x00, 0x04, 0x95, 0x04,\n   0xaa, 0xac, 0x55, 0x6b, 0xff, 0xb7, 0xea, 0x9f, 0x40, 0x02, 0x28, 0x51,\n   0x00, 0x40, 0x58, 0xd5, 0xda, 0xd6, 0x6e, 0x7f, 0xf9, 0x3f, 0x12, 0x04,\n   0x02, 0x04, 0x49, 0x25, 0x55, 0xaa, 0x77, 0xab, 0xff, 0x2b, 0xfd, 0x3f,\n   0x48, 0x01, 0x20, 0x41, 0x00, 0x00, 0x58, 0xa9, 0xda, 0xea, 0xfd, 0xaf,\n   0xfa, 0xff, 0x02, 0x04, 0x08, 0x14, 0x29, 0x49, 0x52, 0x55, 0x55, 0x55,\n   0xff, 0x8d, 0xfe, 0x3f, 0xa8, 0x00, 0x02, 0x41, 0x00, 0x02, 0xa0, 0xa2,\n   0xaa, 0xea, 0xff, 0x53, 0xfd, 0xff, 0x02, 0x04, 0x50, 0x04, 0x25, 0xa8,\n   0x54, 0x49, 0x52, 0xb5, 0xbf, 0x8a, 0xfe, 0xff, 0xa9, 0x08, 0x04, 0x50,\n   0x80, 0x02, 0xa1, 0x2a, 0x95, 0xea, 0xff, 0xa1, 0xff, 0xff, 0x03, 0x02,\n   0x90, 0x02, 0x09, 0x08, 0x44, 0x49, 0x52, 0xbd, 0x7f, 0xca, 0xff, 0xff,\n   0x2b, 0x09, 0x04, 0x48, 0x40, 0x82, 0x90, 0x56, 0xa9, 0xf6, 0xbf, 0xd0,\n   0xff, 0xff, 0x47, 0x00, 0x50, 0x02, 0x15, 0x11, 0x40, 0x95, 0xaa, 0xfd,\n   0x2f, 0xe9, 0xff, 0xff, 0x8f, 0x0a, 0x84, 0x50, 0x40, 0x84, 0x14, 0xaa,\n   0x6a, 0xff, 0x5f, 0xf2, 0xff, 0xff, 0x7f, 0x00, 0x10, 0x02, 0x09, 0x10,\n   0x40, 0x7d, 0xf7, 0xff, 0x0b, 0xfc, 0xff, 0xff, 0xaf, 0x02, 0x84, 0x50,\n   0x42, 0x85, 0x12, 0xd0, 0xdd, 0xff, 0xa7, 0xf2, 0xff, 0xff, 0xff, 0x04,\n   0x00, 0x0a, 0x08, 0x10, 0x48, 0xf8, 0xff, 0xff, 0x0a, 0xfe, 0xff, 0xff,\n   0x7f, 0x03, 0xa4, 0x80, 0xa2, 0x8a, 0x02, 0x68, 0xff, 0xff, 0x52, 0xfd,\n   0xff, 0xff, 0xff, 0x07, 0x00, 0x2a, 0x08, 0x20, 0x28, 0xdc, 0xff, 0x5f,\n   0x05, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x92, 0x40, 0x22, 0x09, 0x02, 0xea,\n   0xfb, 0xaf, 0x48, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x12, 0x81, 0xa0,\n   0x48, 0x9c, 0x6e, 0x93, 0xa2, 0xff, 0xff, 0xff, 0xff, 0x07, 0xa8, 0x40,\n   0x28, 0x0a, 0x02, 0x74, 0xb5, 0x45, 0x81, 0xff, 0xff, 0xff, 0xff, 0x0f,\n   0x02, 0x0a, 0x81, 0x20, 0x08, 0xae, 0xaa, 0x90, 0xe8, 0xff, 0xff, 0xff,\n   0xff, 0x0f, 0x90, 0x40, 0x28, 0x88, 0x12, 0x58, 0x15, 0x50, 0xd0, 0xff,\n   0xff, 0xff, 0xff, 0x0f, 0x44, 0x0a, 0x41, 0x21, 0x08, 0xae, 0x04, 0x14,\n   0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40, 0x14, 0x88, 0x04, 0xba,\n   0x02, 0x28, 0xe8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x42, 0x15, 0x41, 0x21,\n   0x05, 0xad, 0x00, 0x05, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x40,\n   0x24, 0x8a, 0x0e, 0x36, 0x00, 0x0a, 0xf4, 0xff, 0xff, 0xff, 0xff, 0x0f,\n   0x42, 0x25, 0x90, 0xd0, 0x8b, 0xc2, 0x41, 0x05, 0xfc, 0xff, 0xff, 0xff,\n   0xff, 0x0f, 0x10, 0x08, 0x05, 0xe8, 0x8e, 0x58, 0x80, 0x02, 0xfa, 0xff,\n   0xff, 0xff, 0xff, 0x0f, 0x4a, 0x20, 0xa8, 0xba, 0x0b, 0x2b, 0x51, 0x01,\n   0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x8a, 0x02, 0xe8, 0xaf, 0x84,\n   0x90, 0x04, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x52, 0x21, 0x54, 0xbf,\n   0x1f, 0x15, 0xa5, 0x02, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x08,\n   0x01, 0xfa, 0xb6, 0xa4, 0x52, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,\n   0x4a, 0xa2, 0x54, 0xef, 0x5f, 0x4b, 0xa4, 0x80, 0xff, 0xff, 0xff, 0xff,\n   0xff, 0x0f, 0x80, 0x10, 0x82, 0xfe, 0xbf, 0x92, 0x52, 0x42, 0xff, 0xff,\n   0xff, 0xff, 0xff, 0x0f, 0x12, 0x42, 0xa8, 0xbf, 0x1f, 0x24, 0x80, 0xa0,\n   0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28, 0x8a, 0xf7, 0x37, 0x80,\n   0x52, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x10, 0x82, 0xe0, 0xff,\n   0x1f, 0x00, 0x20, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x84, 0x28,\n   0xca, 0xff, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,\n   0x10, 0x42, 0xf0, 0xfd, 0x1b, 0x00, 0x50, 0xf0, 0xff, 0xff, 0xff, 0xff,\n   0xff, 0x0f, 0xa4, 0x10, 0xc5, 0xff, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0xff,\n   0xff, 0xff, 0xff, 0x0f, 0x00, 0x22, 0xf8, 0xff, 0x0e, 0x00, 0x00, 0xf0,\n   0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xaa, 0x88, 0xe2, 0xff, 0x0f, 0x10,\n   0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x25, 0xfa, 0xff,\n   0x0f, 0x01, 0x11, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xfb,\n   0xfb, 0xff, 0x7f, 0x5d, 0xd5, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f};\n"
  },
  {
    "path": "ext/tk/sample/images/flagdown.xbm",
    "content": "#define flagdown_width 48\n#define flagdown_height 48\nstatic char flagdown_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,\n   0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe1, 0x00, 0x00,\n   0x00, 0x00, 0x70, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00,\n   0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04,\n   0x00, 0x00, 0x03, 0x00, 0x06, 0x06, 0x00, 0x80, 0x01, 0x00, 0x06, 0x07,\n   0x00, 0xc0, 0x1f, 0x00, 0x87, 0x07, 0x00, 0xe0, 0x7f, 0x80, 0xc7, 0x07,\n   0x00, 0x70, 0xe0, 0xc0, 0xe5, 0x07, 0x00, 0x38, 0x80, 0xe1, 0x74, 0x07,\n   0x00, 0x18, 0x80, 0x71, 0x3c, 0x07, 0x00, 0x0c, 0x00, 0x3b, 0x1e, 0x03,\n   0x00, 0x0c, 0x00, 0x1f, 0x0f, 0x00, 0x00, 0x86, 0x1f, 0x8e, 0x07, 0x00,\n   0x00, 0x06, 0x06, 0xc6, 0x05, 0x00, 0x00, 0x06, 0x00, 0xc6, 0x05, 0x00,\n   0x00, 0x06, 0x00, 0xc6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00,\n   0x7f, 0x06, 0x00, 0x06, 0xe4, 0xff, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00,\n   0x00, 0x06, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x06, 0x00,\n   0x00, 0x06, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00,\n   0x00, 0x06, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x66, 0x00, 0x00,\n   0x00, 0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00,\n   0x00, 0xfe, 0xff, 0x2f, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x27, 0x00, 0x00,\n   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,\n   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,\n   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,\n   0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00,\n   0xf7, 0xbf, 0x8e, 0xfc, 0xdf, 0xf8, 0x9d, 0xeb, 0x9b, 0x76, 0xd2, 0x7a,\n   0x46, 0x30, 0xe2, 0x0f, 0xe1, 0x47, 0x55, 0x84, 0x48, 0x11, 0x84, 0x19};\n"
  },
  {
    "path": "ext/tk/sample/images/flagup.xbm",
    "content": "#define flagup_width 48\n#define flagup_height 48\nstatic char flagup_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00,\n   0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xef, 0x6a, 0x00,\n   0x00, 0x00, 0xc0, 0x7b, 0x75, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x6a, 0x00,\n   0x00, 0x00, 0x30, 0x60, 0x75, 0x00, 0x00, 0x00, 0x18, 0xe0, 0x7f, 0x00,\n   0x00, 0x00, 0x0c, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x06, 0xe0, 0x04, 0x00,\n   0x00, 0x00, 0x03, 0xe0, 0x04, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00,\n   0x00, 0xc0, 0x1f, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x7f, 0xe0, 0x07, 0x00,\n   0x00, 0x70, 0xe0, 0xe0, 0x05, 0x00, 0x00, 0x38, 0x80, 0xe1, 0x04, 0x00,\n   0x00, 0x18, 0x80, 0xf1, 0x04, 0x00, 0x00, 0x0c, 0x00, 0xfb, 0x04, 0x00,\n   0x00, 0x0c, 0x00, 0xff, 0x04, 0x00, 0x00, 0x86, 0x1f, 0xee, 0x04, 0x00,\n   0x00, 0x06, 0x06, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0xe6, 0x04, 0x00,\n   0x00, 0x06, 0x00, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x66, 0x04, 0x00,\n   0x7f, 0x56, 0x52, 0x06, 0xe4, 0xff, 0x00, 0x76, 0x55, 0x06, 0x04, 0x00,\n   0x00, 0x56, 0x57, 0x06, 0x04, 0x00, 0x00, 0x56, 0x55, 0x06, 0x06, 0x00,\n   0x00, 0x56, 0xd5, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00,\n   0x54, 0x06, 0x00, 0xc6, 0x54, 0x55, 0xaa, 0x06, 0x00, 0x66, 0xaa, 0x2a,\n   0x54, 0x06, 0x00, 0x36, 0x55, 0x55, 0xaa, 0x06, 0x00, 0xbe, 0xaa, 0x2a,\n   0x54, 0xfe, 0xff, 0x6f, 0x55, 0x55, 0xaa, 0xfc, 0xff, 0xa7, 0xaa, 0x2a,\n   0x54, 0x01, 0x88, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a,\n   0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a,\n   0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a,\n   0x54, 0x55, 0x8d, 0x50, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa8, 0xaa, 0x2a,\n   0x54, 0x55, 0x95, 0x54, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a,\n   0x54, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\n"
  },
  {
    "path": "ext/tk/sample/images/gray25.xbm",
    "content": "#define grey_width 16\n#define grey_height 16\nstatic char grey_bits[] = {\n   0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44,\n   0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44,\n   0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44};\n"
  },
  {
    "path": "ext/tk/sample/images/grey.25",
    "content": "#define grey_width 16\n#define grey_height 16\nstatic char grey_bits[] = {\n   0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44,\n   0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44,\n   0x11, 0x11, 0x44, 0x44, 0x11, 0x11, 0x44, 0x44};\n"
  },
  {
    "path": "ext/tk/sample/images/grey.5",
    "content": "#define grey_width 16\n#define grey_height 16\nstatic char grey_bits[] = {\n   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,\n   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,\n   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};\n"
  },
  {
    "path": "ext/tk/sample/images/letters.xbm",
    "content": "#define letters_width 48\n#define letters_height 48\nstatic char letters_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20,\n   0x00, 0xfa, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a,\n   0x00, 0x3a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2e,\n   0xe0, 0xff, 0xff, 0xff, 0xff, 0x21, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21,\n   0xa0, 0x03, 0x00, 0x00, 0x70, 0x21, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21,\n   0xa0, 0x1f, 0x00, 0x00, 0x50, 0x21, 0x20, 0x00, 0x00, 0x00, 0x70, 0x21,\n   0xfe, 0xff, 0xff, 0xff, 0x0f, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x21,\n   0xfa, 0x01, 0x00, 0x80, 0x0b, 0x21, 0x02, 0x00, 0x00, 0x80, 0x0a, 0x21,\n   0xba, 0x01, 0x00, 0x80, 0x0a, 0x21, 0x02, 0x00, 0x00, 0x80, 0x0b, 0x21,\n   0x3a, 0x00, 0x00, 0x00, 0x08, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x21,\n   0x02, 0xc0, 0xfb, 0x03, 0x08, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x3f,\n   0x02, 0xc0, 0xbd, 0x0f, 0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x01,\n   0x02, 0xc0, 0x7f, 0x7b, 0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x01,\n   0x02, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00,\n   0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00,\n   0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00,\n   0xfe, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\n"
  },
  {
    "path": "ext/tk/sample/images/noletter.xbm",
    "content": "#define noletters_width 48\n#define noletters_height 48\nstatic char noletters_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00,\n   0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00,\n   0x00, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x7f, 0x00,\n   0x00, 0x3e, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x01,\n   0x80, 0x07, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0xe0, 0x07,\n   0xe0, 0x01, 0x00, 0x00, 0xf0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x0e,\n   0xf0, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x1e, 0x1c,\n   0x38, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x38, 0x00, 0x00, 0x80, 0x07, 0x38,\n   0x3c, 0xfc, 0xff, 0xff, 0x7f, 0x78, 0x1c, 0x04, 0x00, 0xe0, 0x41, 0x70,\n   0x1c, 0x04, 0x00, 0xf0, 0x40, 0x70, 0x1c, 0x74, 0x00, 0x78, 0x4e, 0x70,\n   0x0e, 0x04, 0x00, 0x3c, 0x4a, 0xe0, 0x0e, 0x74, 0x03, 0x1e, 0x4a, 0xe0,\n   0x0e, 0x04, 0x00, 0x0f, 0x4e, 0xe0, 0x0e, 0x04, 0x80, 0x07, 0x40, 0xe0,\n   0x0e, 0x04, 0xf8, 0x0f, 0x40, 0xe0, 0x0e, 0x04, 0xe0, 0x01, 0x40, 0xe0,\n   0x0e, 0x04, 0xf8, 0x00, 0x40, 0xe0, 0x0e, 0x04, 0x78, 0x00, 0x40, 0xe0,\n   0x0e, 0x04, 0xfc, 0xf3, 0x40, 0xe0, 0x1c, 0x04, 0x1e, 0x00, 0x40, 0x70,\n   0x1c, 0x04, 0x0f, 0x00, 0x40, 0x70, 0x1c, 0x84, 0x07, 0x00, 0x40, 0x70,\n   0x3c, 0xfc, 0xff, 0xff, 0x7f, 0x78, 0x38, 0xe0, 0x01, 0x00, 0x00, 0x38,\n   0x38, 0xf0, 0x00, 0x00, 0x00, 0x38, 0x70, 0x78, 0x00, 0x00, 0x00, 0x1c,\n   0xf0, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x1e, 0x00, 0x00, 0x00, 0x0e,\n   0xe0, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x07, 0x00, 0x00, 0x80, 0x07,\n   0x80, 0x07, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x01,\n   0x00, 0x3e, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x7f, 0x00,\n   0x00, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00,\n   0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00};\n"
  },
  {
    "path": "ext/tk/sample/images/pattern.xbm",
    "content": "#define foo_width 16\n#define foo_height 16\nstatic char foo_bits[] = {\n   0x60, 0x06, 0x90, 0x09, 0x90, 0x09, 0xb0, 0x0d, 0x4e, 0x72, 0x49, 0x92,\n   0x71, 0x8e, 0x8e, 0x71, 0x8e, 0x71, 0x71, 0x8e, 0x49, 0x92, 0x4e, 0x72,\n   0xb0, 0x0d, 0x90, 0x09, 0x90, 0x09, 0x60, 0x06};\n"
  },
  {
    "path": "ext/tk/sample/images/teapot.ppm",
    "content": "P6\n256 256\n255\n\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\[7 eOLjQLmSMoTMnSMlRMhPL_9 \u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\nSMtVMzYN~[N~[N\\N\\O\\O]O]O]O]O\\O\\O}[NyYNtVM\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\G-\u001ewXN}[N]O^O_O`O`O`O`OaOaOaOaOaOaOaOaO`O_O^O\\N\u000b\u000f\u0018\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\aMLyYN_OaPbPcPcPdPdPdPdPdPdPdPdPdPePePePePePdPcP_OpUM\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\wXN_OdPfPgQhQhQiQiQiQiQiQjQjQjQjQjQjQjQjQjQjQiQfP`O\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\NCJiQLbPhQkQmRnRoRoRoRoRoRoRoRoRpRpSqSqSrSrSrSqSoRjQ]O\\KK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\fOLrUMcPlRqStSuTwTxTxTyTyTzTzUzUzUzUzUyTxTwTtSmRaOhPL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\a0\tcNLqUM\\OfQpSwVzV|V}VVVǀVɂW̅[ՏewꪅĈgqTfQ{ZNYIK9\u001c\u0005\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\O1\u001e{G#J\u0011kRMqUMtVNiSv\\dbzZvUuTsSqSnRjQeP^OrUMH\u0011h>!T4\u001f\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\G-\u001eV5\u001fwE\"~I#M%U+e7l:g2b*a(`(^(])^-]1S,qC$`9 R3\u001fG-\u001e\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@)\u001dJ/\u001ei>!pA\"tD\"wF$yH&xH&tE$wE#yG%}M+T4S5mE*Z7!K/\u001eB*\u001d;'\u001c\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\aOoR{UǀVυX<(\u001dF-\u001ea: e<!h>!j@#k@$h>\"d<!c=$hD-fF2[<)K0\u001f@)\u001d;'\u001c5$\u001c˂VǀV|U_LKYIK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\_OxTɂW֒k|X>f-^(Z'W&T&N\u000f>)\u001dF-\u001eJ/\u001eb; g>#nD(jB&c<!b=%jH2_A/I0!<(\u001d8&\u001c5$\u001cJ\u000eY\u001dS%8&\u001c;'\u001c?)\u001dE,\u001d<:HA=HE?IJAISFJYIKXIK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\nR}UܘqʊevUe,V&V\u0018C\r@\f|>\fy<\fu:\u000br9\u000bo7\u000bl6\nj5\nh4\ng3\n5$\u001cD,\u001dK/\u001eb; h>\"wM1tK.e=\"a<#cA,U8&E-\u001e<(\u001d9&\u001c.!\u001ba0\tb1\tc1\t\u0011\b\u0001\u0011\b\u0001\u0011\b\u0001\u0011\b\u0001\u0012\t\u0001\u0012\t\u0001\u0012\t\u0001\u0014\n\u0002\u001d\u0012\n+\u001f\u001b3#\u001c@)\u001d46G<:HMCIXHK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\U*\bvT~X{Yk+W&N$|>\fu:\u000bp8\u000bk5\nf3\na0\t_/\t].\t[-\tI\u0011\\*_(L\u0016kRMmSMmSMnSMnSMD,\u001dR3\u001fW5\u001fmA\"|O0|P1j?\"c<!a=%Y7\"N1\u001eF,\u001e;'\u001cNCJNCJNDJODJODJODJh>!a: X/\u0010K%\u0007\u0005\u0002\u0000\u0005\u0002\u0000\u0000\u0000\u0000\u0006\u0003\u0001\u0002\u0001\u0000\u0003\u0001\u0000\u0004\u0002\u0000\u0006\u0003\u0000\u0017\u0015\u0019&\u001d\u001a4$\u001c+2F=;HPEJL&\u0007\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\lRxTsTd)O$w;\u000bm6\ng3\na0\tZ-\t\\/\fT*\bQ(\bH\u0015m8kRMmSMnTMoTMpTMpUM15G15G05G04G04GpUMpTM5\u001a\u0005^9 d<!yF#O+N,rC#qB\"pB#k?\"a: Z7 6\u001b\u0005ODJPDJPEJQEJQEJREJREJREJRFJSFJSFJSFJSFJe<!X/\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0004\b\u0000\u0000\u0000\u0002\u000b\u0017\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0001\u0000\u0015\u0014\u0019- \u001b'0FqSgQ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\fPtSmRR%B\u000ff3\n^/\tV+\bQ(\bL&\u0007I$\u0007r9\u000bT\u0018lRMnSM46G47G47G46G46G46G46G46G36G36G25G25G15G04G/4F.3F\u0000\u0000\u0000oA\"N$O%S)R)T&T%R%O$J#xE#\u0003\u0001\u0000PDJQEJREJRFJSFJTFJTFJTGJUGJUGJUGJUGJVGJVGJVGJVGJVGJVGJY6\u001fN'\u0007\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0002\u0000\u0000\u0000t;\u000eO$dPoRdP\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\pSkQS%x=\u000e[-\tR)\bI$\u0007E\"\u0006@ \u0006\u0000\u0000\u0000M\u0017]'pTM68G78G78G78G78G78G78G78G78G68G67G67G57G57G47G36G36G25Gp9\u000e8\u001c\u0005eOLpUMtVMn7\u000bf+i,i*i*h*B\r`O~[NqUM[-\tH\u0016UGJUGJVGJVGJVHJWHJWHJWHKWHKXHKXHKXHKXHKXHKXIKXIKXIKXIKXIKh>!Y0\u0010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000W+\b].\ts=\u0013M$dPlR\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\oTMoRdPvE\"V+\bK%\u0007A \u00069\u001c\u00059\u001c\u0005\u0000\u0000\u0000F\u0015['qUMtVM99H:9H:9H:9H:9H:9H:9H:9H:9H:9H99H99H99H99H99H99H:9H;:H>;HB=HPDJ\\JKmSMwXN|ZNy[ᦆ֘u{WyU]btUnRhQaO{ZNvWNtVMvXNwXNyYNzYN{ZN|ZN}[N}[N~[N~[N~[N~[N~[N~[N~[N}[N}[N{ZNzYNxXNL$f3\n\u0000\u0000\u0000I$\u0007L&\u0007P(\bU*\b\\.\tJ#\\OjQ\b\u000e\u0017\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\kRaOo9\rL&\u0007C!\u0006:\u001d\u00054\u001a\u0005\u0000\u0000\u0000f3\nX&pUMuWMwXNxXN<:H<:H<:H<:H<;H<;H<;H<;H=;H=;H=;H=;H>;H>;H?<H@<HA=HC>HG@ILBIREJ[JKcNLjQLpRuTzU~VȁW˂X֎csҎe{VvTpSkRgQbP_O^O]O\\O\\O\\O\\O]O]O]O]O]O]O]O]O]O]O]O\\O\\O~\\N}[N|ZNxXNT%H$\u0007\u0000\u0000\u0000G#\u0007K%\u0007Q(\bW+\bzG#nTMiQ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\dOLrUMuWNwXNyYN{ZN}[N{ZNwXNsVM\u0002\u000b\u0017\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\`OcPnA\"M&\u0007@ \u00068\u001c\u0005F#\u0007\u0000\u0000\u0000m6\nW&rVMvWNyYNzYN|ZN}[N}[N><H?<H?<H?<H?<H?<H@<H@<H@<HA=HA=HB=HC>HE?IG@IIAIKBIODJSFJWHKhQlRpRb(i*n+|7|6r,q+p-l+g)b(sSpSlRiQgQePcPaPaO`O`O_O_O_O_O_O_O_O_O_O_O^O^O^O^O]O]O\\O~[N{ZNT%\u0000\u0000\u0000F#\u0007B!\u0006Y,\bL&\u0007U*\b~I#^O`O\u0013\\\u0013\\\u0013\\\u0013\\cNLrUMzYN\\O^O`ObPcPdPePfPfPfQfQfQePcPaP~[N\u0000\u0003\b\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\fPsVM^/\tC!\u00067\u001b\u0005\u001b\r\u0002\u0000\u0000\u0000\u0000\u0000\u0000Q%tVMwXNzYN|ZN}[N\\N\\O\\O]O]O]O]OA=HB=HB=HB>HC>HC>ID?IE?IF@IG@IIAIKBIcPdPePgQiQlRnR\\'d)i*m+s/s/o+n+l*i*g)c(_(qSoRmRkQiQgQfPePdPcPbPbPbPaPaPaOaOaO`O`O`O`O`O`O_O_O^O^O]O\\O}[NQ\u0017\u0001\u0000\u0000D\"\u0006?\u001f\u0006D\"\u0006K%\u0007_/\tkRLfPODJSFJ_ObPcPePfQgQiQjQkRlRmRnRnRoRoRoRnRmRlRiQeP_O\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\B+\u001dePI#L&\u00079\u001c\u00050\u0018\u0004\u0000\u0000\u0000\u001c\u000e\u0002y<\fP\u0017xXN{ZN}[N\\N\\O]O]O^O^O^O_O_O_O_O`O`O`O`OaOaPbPbPcPdPePfPgQhQiQkRmRZ'_(e)h)k*n,n,m*l*j*f)e)c(_(]'pRnRmRkRjQiQgQgQfPePdPdPdPcPcPcPbPbPbPbPbPaPaPaOaO`O`O_O_O^O]O_(@\f\u0000\u0000\u0000B!\u0006I$\u0007B!\u0006N'\u0007w=\u000feP`LKbNLeOLkRmRnRoRpSqSrSsStStStSuSuStStSsSrSpSmRjQbPjQL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\bPpTME\"\u00065\u001a\u0005\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000M$tVM{ZN}[N\\O]O^O^O_O_O_O`O`O`O`OaOaPaPbPbPbPcPcPdPdPePfPgQhQiQjQkRlRmRZ'`(d)g)g\u001bj*j*i*i*g)d)c(a(_(\\'pRoRnRmRkRjQiQiQhQgQgQfPePePePdPdPdPcPcPcPcPcPbPbPbPbPaPaO`O_O^O\\NQ\u0017\u0000\u0000\u0000\b\u0004\u0000@ \u0006<\u001e\u0006G#\u0007_LKcPlSMnTMpUMsVMtSuTvTwTwTxTxTwTwTvTuTtSsSqSpSoRnRkRhQbPeOL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\wXN\\NJ%\u00070\u0018\u0004\u0000\u0000\u0000\u0000\u0000\u00001\u0018\u0004J\u0016vWN}[N\\O]O^O_O_O`O`O`OaOaPaPbPbPbPbPcPcPdPdPdPePePfQgQgQhQiQjQkQlRmRY&]'`(c(e)c\u001b\\\u0012\\\u0012\\\u0012]\u0012]\u0013^\u001aa(`(^'['['oRnRmRlRkRkQjQiQiQhQgQgQgQfQfPePePePePdPdPdPdPdPcPcPcPbPbPaPaO`O]OO\u0017\u0000\u0000\u0000\u0000\u0000\u0000G#\u00077\u001b\u0005F#\u0007uWM^OwXNxXNzYN{ZN|ZNyTyTxTwTuTsSpSmRjQgQdPbPaPaPbPcPePcP|ZN\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\[JKbP^/\t1\u0018\u0004\f\u0006\u00010\u0018\u00041\u0018\u0004|>\fwXN}[N]O^O_O`O`OaOaPaPbPbPbPcPcPcPcPdPdPdPePePfPfQgQgQhQhQiQjQkQkRlRmRY&]'`(b([\u0012g\u001ci\u001dh\u001df\u001bd\u001be\u001bc\u001bU\u0011_(]'['Z'nRnRmRmRlRkRkQjQjQiQiQhQhQgQgQgQfQfQfPfPePePePePePdPdPdPcPcPbPbP`O^OD\r\u0000\u0000\u0000\u0000\u0003\b\u0000\u0003\b4\u001a\u0005M&\u0007dPnSM|[N|[O|[OzZOxXNrSnRhQcP^OvXNiQL^KKRFJMCJJAIKBISFJ\\JKnSMxYN_O\\OaMK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\B!\u0006qUMaPC!\u0006/\u0017\u00040\u0018\u00040\u0018\u0004a0\tuWN}[N]O_O`O`OaPaPbPbPcPcPcPcPdPdPdPePePePfPfQfQgQgQhQhQiQiQjQjQkRlRlRX&['^'`(Z\u0012d\u001bf\u001ci\u001eg\u001dd\u001bc\u001bc\u001ba\u001a_\u001aT\u0010\\'['Z'Y&nRmRmRlRlRkRkQjQjQjQiQiQhQhQhQhQgQgQgQgQfQfQfQfPfPePePePdPdPcPbPaO^Ox<\f\u0000\u0000\u0000\u0004\u0002\u0000\u0000\u0000\u0000:\u001d\u0005aP]Oj8\u0012sVMmSMfOL^KKUGJIAIQEJ?<H*1F(\u001e\u001b\u0015\u000e\n\n\b\t\b\u0007\b\u0007\u0006\b\u0011\n\u0005@%\u0010<-$G?@pfdNLuWM\\NdNL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\TFJvWNaP.\u0017\u0004/\u0017\u00040\u0018\u00041\u0018\u0004E\u0015}[N]O_O`OaPbPbPcPcPcPdPdPdPePePePePfPfQfQgQgQgQhQhQhQiQiQjQjQkQkRlRlRY&\\'^'^\u001ab\u001ac\u001be\u001ci g\u001ec\u001bb\u001aa\u001b`\u001a^\u001a]\u001aX\u0014['Z'Y&mRmRmRlRlRlRkRkQkQjQjQjQiQiQiQiQhQhQhQhQgQgQgQgQgQfQfQfQfPePePdPcPaPO\u0017\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000`O`OoTMQEJC>IeZY638*\u0019\u000e\u0005\f\u0017\u0006 B\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u000e\u001b,\u0001\u0005\u000b\u0001\u0005\u000b4\u001c\t.\u0017\u0004G1!\\TUrsVM{ZN`MK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\[JKyYNbP/\u0017\u00040\u0018\u0004\u0000\u0000\u0000\u0000\u0000\u0000N$]O_O`ObPbPcPcPdPdPdPePePePfPfPfQfQgQgQgQgQhQhQhQiQiQiQjQjQkQkRkRlRO\u0012Z'\\'^'V\u0011a\u001ab\u001be\u001di!f\u001eb\u001ba\u001a`\u001a_\u001b]\u001a\\\u0019Z\u0012['Z'Y&Q\u0017mRmRmRlRlRlRkRkRkQkQjQjQjQjQiQiQiQiQiQhQhQhQhQhQhQgQgQgQgQfQfPdPcPW&\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000dPaPrUM\u001b\u0011\n\u0006 B\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0019%7\u0003\u0010!\u0003\u0010!C*\u0019F#\u0007P)\f{dYzep\\OgPL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SFJ`LKvWNaPm6\n\f\u0006\u0001\u0000\u0000\u0000X,\buWM]O`ObPcPdPdPdPePePfPfPfQfQgQgQgQgQgQhQhQhQiQiQiQiQjQjQjQkQkQkRlRlRZ'\\']'_\u001a`\u001aa\u001ab\u001be\u001ei\"e\u001ea\u001b`\u001a_\u001b_\u001b]\u001a\\\u0019\\\u0019Y\u0019Z'Z'Z'mRmRmRlRlRlRlRlRkRkRkRkQkQjQjQjQjQjQjQiQiQiQiQiQiQiQhQhQhQgQgQfQdP_Oq8\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000gQ`OuWMT%\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B\u0003\u0010!\u0003\u0010!T,\u000ec5\u0011F\u0016T3ț~Ɠq^OfOL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\XHK_LKsVM`OcP\u0000\u0000\u0000\u0000\u0000\u0000\u0013\t\u0001S%]ObPcPdPePePfPfQfQgQgQgQgQgQhQhQhQhQiQiQiQiQiQjQjQjQjQkQkRkRlRlRlR\\']'^'V\u0011`\u001aa\u001ab\u001bf\u001ei\"e\u001ea\u001b`\u001a_\u001b_\u001b]\u001a\\\u0019\\\u0019R\u0010Z'Z'['mRmRmRmRmRlRlRlRlRlRlRkRkRkRkRkQkQjQjQjQjQjQjQjQjQjQjQiQiQiQhQgQePS\u0010q8\u000b\u0000\u0000\u0000\u0000\u0000\u0000aOgQ`OtVMX&\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B\u0006 B\u0002\u000b\u0017l@!{A\u0014L$Y'afPaO]KK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ODJ[JKaMKqUM\\OcP^O\u0000\u0000\u0000\u0000\u0000\u0000vE\"]OaPdPePfPfQgQgQgQhQhQhQhQhQiQiQiQiQiQjQjQjQjQjQkQkQkRkRkRlRlRlRlR^'^'_(W\u0011a\u001aa\u001ac\u001cg i\"e\u001ea\u001b`\u001a_\u001b_\u001c^\u001b\\\u001a\\\u0019R\u0010['[']'mRmRmRmRmRmRmRlRlRlRlRlRlRlRlRlRlRkRkRkRkRkRkRkRkRkQkQkQjQjQiQhQePW&M&\u0007\u0000\u0000\u0000oTMiQeP_OtVMmSMdOL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B\u0006 B\u0002\u000b\u0017\u001a\u0017\u0019J\u0011Z'_(kQiQ`OSFJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\TFJ\\JKcNLlRMzYN`OePzZN\u0000\u0000\u0000\t\u0004\u0000\\N`OdPfQgQgQhQhQhQiQiQiQiQiQiQjQjQjQjQjQjQkQkQkRkRkRlRlRlRlRlRlRmRa(`(`([\u0012a\u001ab\u001bd\u001ch!i\"d\u001da\u001b`\u001a_\u001b_\u001b^\u001b]\u001a]\u0019S\u0010\\']'_(nRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRlRlRlRlRlRlRlRlRlRlRlRlRlRkRkQiQePt:\u000b\u0000\u0000\u0000\u0000\u0000\u0000kQhQcP]OtVMlSMa2\r\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B\n\u000f\u0018\u0012\u0013\u0018$\u001c\u001a5 \u000f`(e)nRjQ^OJAI\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\XIK^KKdNLhPLuWM]ObPfQeP\r\u0006\u0001m6\n`OcPfQhQhQiQiQjQjQjQjQjQjQjQkQkQkQkRkRkRkRlRlRlRlRlRlRlRmRmRmRmRg)c(c(b(V\u0011c\u001be\u001di!i!d\u001db\u001b`\u001a`\u001a_\u001b_\u001b^\u001aQ\u0010]'_(`(f)nRnRnRnRnRnRnRnRnRnRnRnRnRmRmRmRmRmRmRmRmRmRnRmRmRnRmRmRmRmRkRhQG\u0015a0\tbPmRjQfQaP}[NrUMmSML$\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B\r#C\u0012\u0013\u0018\u0018\u0016\u0019, \u001b8&\u001cH.\u001fZ7 pRjQ{ZN\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\QEJ[JK`LKdNLhQLqUM{ZN_OcPgQhQ\u0000\u0000\u0000\u0018\u000f\nbPePhQiQjQjQkQkQkRkRkRlRlRlRlRlRlRlRlRlRlRmRmRmRmRmRmRmRmRmRnRnRj*g)e)d)d\u001bX\u0011g\u001dh\u001fe\u001cc\u001bb\u001ab\u001bb\u001bU\u0011`(a(a(c(i*oRoRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRoRoRoRoRoRoRoRoRoRoRoRoRnRmRjQQ%Z-\tjQnRlRhQdP_OuWMpTMnSMkRLa: \u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B\u0013&D\u001b\u0017\u0019\u001e\u0019\u001a2\u001c\r@*\u001dS6#G@IPDJhQmSM\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\VGJ]KKbMLeOLiQLlRMvWN\\OaOePhQjQgQ\u0007\u0003\u0000oTMgQiQkQlRlRlRmRmRmRmRmRmRmRmRmRmRmRmRmRmRnRnRnRnRnRnRnRnRnRnRnRnRl*l+j+g)f)e)d)e)e)e)e)f)i*s0s.oRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRpRpRpRpRpRpSpSpSqSqSqSqSpSqSpSnRlRI\u0011hQpRoRmRiQePaP\\OsVMpTMnTMlRMX)\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0011%C\u001a)D\u001d\u0018\u0019$\u001c\u001a;\u001d\u0005J/\u001f[8\"LBITGJYIKWHK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\NCJYIK_LKcNLgPLjQLlRMpUMzYN^ObPePhQkQlRfQ- \u001bhQjQlRmRnRnRnRnRnRnRnRnRnRnRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRoRpRpRpRp\u0016y-w-w-y.{-u\u001epSpSpSpSpSpSpSpSpSpSpSpSpSpSpSqSqSqSqSqSqSqSqSqSrSrSrSrSrSrSrSsSrSqSoRiQiQqSqSpRmRjQgQcP_O{ZNtVMpUMoTMmSMjQL_9 \u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u000b\"C\u0017(D\u001b\u0017\u0019#\u001b\u001a*\u001f\u001bA$\u000e[<)d<!QEJWHKXHKD>I\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SFJ[JKaMKeOLhPLkRLmSMoTMuWM}[N_ObPePhQkRmRnRkR!-EkRmRnRoRpRpRpSpSpSpSpSpSpSpRpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSpSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSqSrSrSrSrSrSrSrSrSrSrSsSsSsSsStStStStStSuStSsSrSnRoRsSsSrSpRmRjQgQdPaO\\OyYNuWMqUMoTMnSMkRLo8\r\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0015'D\u001e+E$\u001c\u001a(\u001e\u001b1\u001b\u000bJ/\u001ejH1NCJUGJYIKUGJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\XHK]KKbNLfOLiQLkRMmSMoTMqUMxXN\\N_ObPfPhQkQmRoRpSpRhQmRoRpSqSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSrSsSsSsSsSsSsSsSsSsSsSsSsStStStSuSuSuTuTuTuTuTvTwTvTvTuTtSmRtSuTuStSrSpRmRkQhQePaP^O\\N{ZNvXNqUMpTMnSMlRMP%\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u000e#C\u001b*E$.E- \u001b.!\u001bG$\u0007Y:%d<\"SFJYIKZIKNCJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\PDJZIK_LKdNLgPLjQLlRMnSMpTMqUMuWMyYN\\O`OcPfPhQjQmRoRqSrSrSrSmR\u0002\u0001\u0000rSsStStStStStStStStStStStStStStStSsSsSsSsSsSsSsSsSsStStStStStStStStStStStStStStStStSuSuSuTuTvTvTvTvTvTwTwTwTwTxTxTxTyTyUxU\\'qSvTwTwTvTuTtTrSoRmRkQhQePbP`O^O\\O|ZNxXNtVMpTMoTMmSMjQLh7\u0012\u0013\\\u0013\\\u0013\\\u0006 B\u0018(D\"-E*1F, \u001b4#\u001cK)\u000fpL5PEJWHK[JKXHK:9H\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\UGJ\\JKaMLeOLhPLkRLmSMoTMpUMrVMvWNyYN|ZN]O`OcPePhQjQlRnRpSqSsStSuStSsSmR^/\tvTvTvTwTwTwTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTvTwTwTwTwTwTwTwTxTxTxTxTxTxTxTyTyTzUzU{U{V|VgQrSwTxTyUyUzVyVxVvUtTqSoSmRjQhQePcPbP`O_O]O}[NyYNuWMpUMoTMmSMkRL}H#\u0013\\\u0013\\\u0002\u000b\u0017\u0012&D -E(1F/!\u001b2#\u001c8\u001d\tW7\"iA&UGJ[JK\\JKREJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\MCIXIK^KKcNLfOLiQLkRMmSMoTMqUMsVMwXNzYN}[N\\O^O`ObPePgQjQkRmRoRqSrStSuSvTvTwTwTuTsSlR_(yTyTyTyTyTyTyTyTyTyTxTxTxTxTxTxTyTyTyTyTyTyTyTyTyTyTyTyTyTyTyTzTzTzU{U{U{U|U|U}V~VWÀYiQrSwTyTzU|V}XZ]]]~[zYwWtUqSnSlRjQgQfPePcPbP`O_O]O~\\NzZNvXNqUMoTMnSMlRMiQLg=!\u0013\\\n!C\u001d+E'0F.4F7%\u001c8%\u001cU/\u0012lG.SFJZIK]KKZIKB=H\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\REJZJK`LKdNLgPLjQLlRMnSMpTMqUMtWMxXN{ZN~[N]O^O`OaObPdPgQiQkQlRnRpSrSsStTuTvTwTxTyTyTyTyTyTxTvTrSnRhQ|U|U|U|U|U|U|U|U|U|U|U|U|U|U}U}U}U}U}U}U}U~U~U~V~VVŀWƁXa(lRrSvTyTzU|U~VXƂ[Ɇ_΋dӑjԓmԓnБlʌhĆd_{[vWsUpSnRkRiQhQgQfQePdPbPaO_O^O\\O|ZNxXNsVMpTMnTMmSMjQLC\u0015\u0006 B\u0019)D&/F-3F47G6%\u001c>\"\fY7 kA$YIK]KK^KKSFJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\VGJ\\KKbMLeOLhPLkRLmSMnTMpTMrUMuWNyYN|ZN\\N]O_O`OaPbPcPePfPhQjQlRnRoSqTsTuUvUwVxVyVyUzUzU{U{U{U|U|U|U|U|U{U{U{UzUzTyTyTxTwTvTvTvTvTwTwTwTxTyTzTzU{U{U|U|U}UVŀWǂYɄ\\͈_ьdٔlu|쩂ﬅ명榁ޟ{՗sˎld^yZuWqUoSlRkRjQiQhQgQfQePdPcPaP`O^O]O}[NyYNuWMpTMoTMmSMkRLgPL\u0013&D#.E,3F46G;'\u001c<(\u001dD\"\u0007iB(VGJ]KK`LK[JKB>H\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\NCJYIK^LKcNLfOLiQLkRMmSMoTMqUMsVMvXNzYN}[N\\O^O_O`OaPcPdPePfQgQhQiQkRmSoTrUtWwYzZ}\\]^^^^\\ZYX~W~W~V~V~V~V~U~U~U~UUUVVVVVƀVƀVǀWǁWȂXɃZ˅[͇^ЊaӍdؒiܗntz驅~֘vˏmÇf`z[vXrUpToSnSlRkRkRjQiQhQfQePdPcPbP`O_O]O~[NzYNvWNpTMoTMnSMkRMhQLo7\u000b,2F36G99HC+\u001d@ \u0006]8 nA\"\\JK`ML_LKSFJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SFJ[JK`LKdNLgPLjQLlRMnSMpTMqUMtVMwXNzZN}[N]O^O_OaObPcPdPePfQgQhQiQjRlRmSoUrWvZ{]afŊjˏnГqӕsՖsՖrՖqՔoӒmяjύg͊cˈaɆ^Ȅ\\ǂ[ƁYŀXŀWWWVVWŀWƀWǁXȂYɃ[ʅ\\͇_ϊaҍeՑhٕmݙqvz}꧀멃몄騃奀ߠ|ٛwӕȑmƉhc~^yZvXtWsVqUpToSnSmRlRkRjQiQhQgQfPePcPbPaO_O^O\\N{ZNwXNsVMoTMnSMlRMiQL~I#26G99G?<HA*\u001dE$\ti@$ZIKaMLbML[JK;:H\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\WHJ]KKbMLeOLhPLjRLlSMnTMpTMrUMuWMxXN{ZN~\\N]O^O`OaObPcPdPePfQgQhQiQkRlSmToUrWuZy]~afl˒sԚzܡ㧆諉뮋묈訄~ߞyڙt֕oҐjΌfˈbȅ_ƃ\\ŁZĀYXW~W~W~WXÀXĀYŁZƃ\\ǅ^Ɇ`ˈb̊d͋f΍gΎiΎjΎj͎jˌiǉgÆda^}]|\\{[yZxYvXtWsVqUpToSnSmRlRkRjQiQhQgQfPePdPbPaO_O^O\\O|ZNxXNtVMpTMnSMmSMjQLgPL99G?<HG-\u001eE&\u000eb;!YIK`MLdOM`LKNCJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\lRyT~UʂXʃYX{WtUW'[(hQlRcP\\OhQL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\NCJYIK^LKcNLfOLiQLkRLmSMoTMqUMrVMvWNyYN|ZN\\N]O_O`OaPbPcPdPfPgQhQiQjRkRlSnTpUsWvZz]bglɑsИy؞ޤ㩊譍챐ﳑﳑ뭊穅⣀ݞzؘtғn΍iɉdƅ`Â][~Y}X|W|V{V{V{V{V{V|W|W}X}Y~Z~Z~Z}[}[}[~\\~\\~]~]~]~]}]|\\z[yZwYvXtWsVrUpToSnSmRlRkRjQiQhQgQfQePdPcPaP`O^O]O}[NyYNuWNpTMnTMmSMkRLhPL|H$D>IQ2\u001fP+\u0010XHK_LLfQOcNLXIK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\qSyT~VΈ`遲ޜv]qSL\u0011G\u000e|>\fg3\nS)\b?\u001f\u0006*\u0015\u0004%\u0012\u0003.\u0017\u0004hQhQeP`OuWM\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SFJ[JK`LKdNLgPLjQLlRMnSMoTMqUMsVMwXNzYN}[N\\O^O_O`OaPbPdPePfPgQhQiQjRkRlSnTpVsXvZz^bgËmʒsјz؟ޤ㩊譍ꯏ및ꯎ謋娇ं۞|֙wѓq̎lǉgÅb_\\}Z{XzWyVyUxUxUxTxTxUxUxUyVyVyWzW{X{Y|Z}[}[}\\~\\~]~]}]|\\{\\z[yZwYvXtWsVrUpToSnSmRlRkRjQiQhQgQfQePdPcPbP`O_O]O~[NzZNvWNrUMoTMmSMlRMiQLeOLJAIJ(\u000fh>!]KKfQOgQN_LKD>I\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\iQtSyT{UYΌeרּ՗u|\\Z'L\u000fD\r|>\f\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000ePoRqSoRmRjQeP^OhPL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\WHJ\\KKaMLeOLhPLjQLlRMnSMpTMqUMtVMwXNzZN}[N]O^O_O`ObPcPdPePfQgQhQiQjRkRmSnTqVsXw[{_chČn˒tҙz؟ޥ㩉筍ꯎꯎꮍ竊䧆ߣ۞|՘vГpˎkǉfÅb_\\}Y{XzWyVxUxUxTxTxTxUxUxUxUyVyVzWzX{Y|Y|Z}[}[}\\}\\}\\}\\|\\{[zZyZwYvXtWsVrUpToSnSmRlRkRjQiQhQgQfQePdPcPbP`O_O^O\\N{ZNwXNsVMoTMnSMlRMiQLfOLJ(\u000fV.\u0010]KKePNkUQcNLQEJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\]OmRqSrStSvTwTxU{WĆbғqךxʏo\u0012\n\u0004\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000K\u0016rSvTwTvTuTsSqSnRkQgQ`OuWNY,\b\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\NCJYIK^KKbNLfOLhQLkRLmSMoTMpUMrUMuWMxXN{ZN~[N]O^O_OaObPcPdPePfQgQhQiQjRkRmSoTqVtXw[|_diČn˓tҙz؟ޥ㩉笌鮎ꮎ魌檉㧅ߢڝ{՗uϒpˍjƈfb^\\|Y{XzVyVxUxUxTxTxTxUxUxUxUyVyVyWzW{X{Y|Z|Z|[}[}\\}\\|\\|[{[zZxYwXvXtWsVrUpToSnSmRlRkRjQjQiQhQgQfPdPcPbPaO_O^O\\O|ZNxXNtVMoTMnSMlRMjQLgPLzG#\\JKcOMoXUgPMZIK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\fPgQgQhQiQkQlRnRpRqSsStS\u0000\u0000\u0000\u0000\u0000\u0000:\"\u0010r<\u0010zYNsSyT|U~WƄ^ˊeˋgƈeaz[tVpSmRkQgQbPzYNkRL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\RFJZJK`LKcNLfPLiQLkRMmSMoTMqUMrVMvWNyYN|ZN\\N]O^O`OaObPcPdPePfQgQhQiQjRlRmSoUqVtYx\\|`diōo˓uҙ{ٟޥ㩉笌鮍鮍謋婈⦄ޡٜzԗtϑoʌjƈea^~[|Y{XzVyVxUxUxTxTxTxTxUxUxUxVyVyWzWzX{Y{Y|Z|Z|[|[|[|[{[z[yZxYwXvWtWsVrUpToSnSmRlRkRkRjQiQhQgQfPePdPbPaP`O^O]O}[NyYNuWNqUMnSMlSMkRLhPLcNLbNLpYVlUP`LK>;H\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\jQ`O{ZN^'^'`(e)h)k*o+b(nRyT~UǁXҍdw詅ݟ}Ԙvȍme}_x[y\\x[tWqTmRjQgQbP}[NlRM\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\VGJ\\JKaMKdNLgPLjQLlRMnSMpTMqUMsVMvXNzYN|[N\\O]O_O`OaPbPcPdPePfQgQhQiQjRlSmSoUrWuYx\\|`djōo̓uҚ{٠ޥ㩉欋譍譌竊婇᥃ݠ~؛yӖtΑoʌjňea^~[|Y{WzVyVxUxUxTxTxTxTxUxUxUxUxVyVyWzXzX{Y{Z{Z|Z|[|[{[{[zZyZxYwXuWtVsVrUpToSnSmRlRkRkRjQiQhQgQfQePdPcPaP`O^O]O~[NzYNvWNrUMnSMmSMkRLiQLeOLoXUu]XdOLKBI\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\:9H\\NhQ}\\uUsTtTtSqSnRnRnRlRjQiQhQhQgQfQePePhQkRmSpUtXuYsWqUmSjQgQB\u000fS%jQL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LBIXHK^KKbMLeOLhPLjRLlSMnSMpTMqUMtVMwXNzYN}[N\\O^O_O`OaPbPcPePfPfQgQhQiRkRlSnTpUrWuYy]}`ejŎp̔vӚ{٠ޤ⨉櫋笌笋櫊䨆ंܟ~ךxҕsΐnɌiŇea^~[|Y{WyVyVxUxUxTwTwTwTxTxUxUxUxVyVyWzWzXzY{Y{Z{Z{Z{Z{ZzZyZyYxYvXuWtVsUrUpToSnSmRlRlRkRjQiQhQgQfQePdPcPaP`O_O]O\\N{ZNwXNsVMnSMmSMkRMiQLfOL_LKhQMUGJ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ (6BFP>=DKHMqjktrwf`~kcndqesete{w`v[\\N_OcPfPiQjRlSoTqVqVoTlRiQ^\u0015`OQ%hPL\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\QEJZIK_LKcNLfOLiQLkRLmSMoTMpUMrUMuWMxXN{ZN~[N]O^O_O`OaPcPdPePfPgQhQiQjRkRlSnTpUrWuZy]}aekƎp̔vӚ{ٟޤ⨈媊櫋櫊婈⦅ߣ۞}֚xѕr͐mȋićda]~[|YzWyVyUxUxUwTwTwTwTwTxUxUxUxUxVyVyWzXzXzYzY{Y{Z{ZzZzZyYxYwXvXuWtVsUrUpToSnSmSmRlRkRjQiQhQgQfQePdPcPbP`O_O]O\\O|ZNxXNtVMoTMmSMlRMjQLgPLbML[JK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0010\b\u0001\u001a%5 (6\u001f$/79CEEKjgkrc_{uf{w_q]O`OcPfQhQjRlRnToTnTkRhQdP]'Q%\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\UGJ[JK`MKdNLgPLiQLkRMmSMoTMqUMrUMuWNxXN{ZN~[N]O^O_O`ObPcPdP['d)gQhQiQjRkRlSnTpUrWvZy]~afkƎp̔vӚ{؟ݤᧇ䩉媊媉䨇᥄ޡڝ|՘wДȑmȊhĆd`]}[|YzWyVxUxUxUwTwTwTwTwTwUwUxUxUxVxVyWyWyXzXzYzYzYzYzYyYyYxYwXvWuWtVsUqUpToSnSmSmRlRkRjQiQhQgQfQePdPcPbPaO_O^O\\O|[NxYNtWMpUMmSMlRMjQLgPLcNLA;=\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\#*6+.8;:AHEJmgjd\\]pe}xcw^p^OaPePgQiQlRmSnTmSjRgQh*X&M$\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\C+\u001dWHJ]KKaMLdOLgPLjQLlRMnSMoTMqUMrVMvWNyYN|ZN\\N]O^O_OaObPcPY&_(c(gQhQiQjRkRlSnTpVsXvZz^~bfkƎp̔vҚ{؟ݣই㩉䩉䩈⧆ःܠ؜{ԗvϓqˎlǉgÆc`]}Z{YzWyVxUxUwUwTwTwTwTwTwTwUwUxUxVxVxVyWyWyXyXyYzYyYyYyYxYwXwXvWuVtVrUqUpToSnSmSmRlRkRjQiQhQgQfQePdPcPbPaO_O^O\\O}[NyYNuWNqUMmSMlRMjQLhPLdNL\\1\u000f\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\+.775;ICFphhztre}yavZ]OaPePgQiQkRlSnTlSiQq.b*S%zG#\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\MCJXHK^KKbMLeOLhPLjRLlSMnSMpTMqUMsVMvWNyYN|ZN\\N]O^O`OaObPU&\\'a(g)r/hQiQjRkRmSnTpVsXv[z^~bfkƎp̔vҙ{מܣআ⨈㨈㨇ᦅޣ۟~כyӖuΒpʍkƉgc_]}Z{XzWyVxUxUwTwTwTwTwTwTwTwUwUwUxUxVxVxWyWyWyXyXyXyYyYxXxXwXvWuWtVsVrUqTpToSnSmRmRlRkRjQiQhQgQfQePdPcPbPaO`O^O]O}[NzYNvWNrUMmSMlRMjQLhQLeOL_LK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\,)/ZTVXONuqod}ybs]OaPePgQiQkRlRlSkRhQg*\\(Q%`LK\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B_LKcNLfOLiQLkRLmSMoTMpTMrUMtVMwXNzYN}[N\\O]O_O`OaOQ%Y&^'b(i*{8hQiQjRkRmSnTqVsXv[z^~bfkƎp̔vҙ{מۢߥᧇ⧇ᦆऄݢڞ}֚xҕt͑oɌjňfb_\\}Z{XzWyVxUxUwTwTwTwTwTwTwTwTwUwUwUxVxVxVxWxWyWyXyXxXxXxXwXwWvWuWtVsUrUqTpToSnSmRmRlRkRjQiQhQgQgQfPdPcPbPaP`O^O]O~[N{ZNvXNrVMnSMlRMjRLhQLeOLaML+O+O\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\HFLXQRTJH~pmla}zcttTaPdPgQiQjRlRlSjR|:e*V&N$\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0006 B\u0006 B`LKdNLgPLiQLkRMmSMoTMpUMrUMtVMwXNzYN}[N\\O]O_O`OaPW&['_(d)l,݃@t.iQjRkRmSoUqVsXw[z^bgkƎp̔uљz֝~ڡޤॆআॅޣܠ؝{ՙwєs̐nȌjňfb_~\\|Z{XyWyVxUwUwTwTwTwTwTwTwTwTwUwUwUwUwVxVxVxWxWxWxWxXxXwXwWvWuWuVtVsUrUqTpToSnSmRlRlRkRjQiQhQhQgQfPdPcPbPaP`O^O]O~[N{ZNwXNsVMoTMlRMjRLiQLfOLbML+O+O+O+O\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\6./fZXeVRHAIZIKiQLuWMtUaOdPgQjQkRlRkRiQn/b,R%rC\"\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\"Fx\"Fx!Fx!Fx\u0006 B\u0006 B\u0006 BdNLgPLjQLlRMmSMoTMqUMrUMtWMwXNzZN}[N\\O^O_O`OS%X&\\'a(g+s2{9j*iQjRkSmSoUqVsXw[z^bgkƎp˓uИy՜}٠ܢޤߤޣݡڟ~כzӗvϓrˏmǋićea^~\\|ZzXyWxVxUwUwTwTwTwTwTwTwTwTwTwUwUwUwUwVwVxVxWxWwWwWwWwWvWvWuVtVsUsUrTqTpToSnSmRlRlRkRjQiQhQgQgQfPePcPbPaP`O_O]O~\\N{ZNxXNsVMoTMlRMjRLiQLfPLbNL\u0005\t\u000f+O+O+P+P+P\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@89dWT@<HE?IXHKiQLvWN]ObPePhQjQlRlRkRp+f*[)O$\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\:^:^:^:^\"Fx\"Fx\"Fx\u0006 B\u0006 B\u0006 B\u0006 BeOLhPLjQLlRMnSMoTMqUMrUMuWMxXN{ZN~[N\\O^O_OO$V&Z']'d+g+}<h*hQiQjRkSmSoUqVtYw[z_bgkōpʒtЗyԛ}؟ۡݣݣܢ۠؝|՚yҖuΒpʎlƊhÆda^~[|YzXyWxVxUwUwTwTwTvTvTvTvTvTvTvTwUwUwUwUwVwVwVwVwWwWwWvWvWuVuVtVsUrUqTqTpSoSnSmRlRlRkRjQiQhQgQgQfPePdPbPaP`O_O]O\\N|ZNxXNtVMpTMlRMjRLiQLgPLcNL\\JK+P+P+P+P+P+P,P\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\D::hZUC>IIAI\\JKlRMyYN^OcPgQiQkRlRkRiRt3d-S%I#\u0013\\\u0013\\\u0013\\:^:^:^:^:^:^:^:^:^\"Fx\"Fx\u0006 B\u0006 B\u0006 B\u0006 BeOLhPLjRLlSMnSMpTMqUMrVMuWMxXN{ZN~[N]O^O_OS%W&['^(k2i+{:gQhQiQjRkSmToUqVtYw[{_bfkčoʒtϖxӚ|ם~٠ۡۡ۠ٞ~כ{ԘwДs̐oɌkŉgc`]}[{YzXyVxVwUwUwTwTvTvTvTvTvTvTvTvTvUvUvUwUwUwVwVwVwVvVvVvVuVuVtVtUsUrUqTpTpSoSnSmRlRlRkRjQiQhQgQgQfPePdPbPaP`O_O]O\\N|ZNxYNtWMpTMlRMjRLiQLgPLcNL_LK+P+P+P,P,P,P,P,PNr\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\]QNl\\VG@IMCI_LKoTM|ZN`OdPgQjQkRlRkRhQh*^,P%X3\u0019:_:_:_:_:_:_:_:_:^:^:^:^\"Fx\u0006 B\u0006 B\u0006 B\u0006 BfOLiQLkRLmSMnTMpTMqUMrVMuWNxYN{ZN~[N]O^OP%U&X&['`)n4n/j*gQhQiQjRkSmToUqWtYw[z^~bfjČoɑsΕwҙ{՜}؞ٟڟٞ~ל|՚yҗvϓrˏnǋjĈfc`]}[{YzWxVxUwUwTwTvTvTvTvTvTvTvTvTvTvTvUvUvUvUvUvVvVvVvVvVuVuVuVtUsUrUrTqTpToSoSnSmRlRkRkRjQiQhQgQgQfPePdPbPaP`O_O]O\\N|ZNyYNuWMpUMlRMjQLiQLgPLdNL_LK,P,P,P,P,PNrNrNrNrNrNr\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\aSOD>IJAIQEJbNLrUM~[NaOePhQjQkRlRjRs0e,T&K$;_;_;_;_;_;_;_:_:_:_:_:_:_\u0006 B\u0006 B\u0006 B\u0006 BgPLiQLkRLmSMoTMpTMqUMsVMuWNxYN{ZN~[N]OM$S%V&Y&\\'e-j/z:fQgQhQiRjRkSmToUqWtYw[z^~bfjÌnȐr͔vјyԛ|֝~מ~؞~ם}՛{ӘxЕt͒qʎmƊiÇeb_~\\|Z{YyWxVxUwUwTvTvTvTvTvTvTvTvTvTvTvTvTvUvUvUvUvUvUvVvVuVuVuVtUsUsUrUqTqTpSoSnSnRmRlRkRkRjQiQhQgQgQfPePdPbPaP`O_O]O\\O|ZNyYNuWMqUMlSMjQLhQLfPLdNL_LK,P,PNrNrNrNrNrNrNrNsNsNsNs\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\dUOG@IMCITFJeOLtWM]ObPfPiQkRlRkRiQj,c/P%[JK;_;_;_;_;_;_;_;_;_;_;_;_\u0006 B\u0006 B\u0006 B\u0006 BgPLiQLkRMmSMoTMpTMqUMsVMvWNyYN{ZN~[N|H#Q%T%W&Z']'m5f*v5fQgQhQiRjRkSmToUqWsYv[z^~beinǏq˓uϖxҙzԛ|֜}֜|՛{ԙyіvϓs̐oȍlŉhea_~\\|ZzXyWxVwUwUvTvTvTvTvTvTvTvTvTvTvTvTvTvTvUvUvUuUuUuUuUuUtUtUtUsUrUrTqTpTpSoSnSmRmRlRkRjRjQiQhQgQfQfPePcPbPaP`O_O^O\\O|ZNyYNuWNqUMmSMjQLhQLfPLdNL`LKNrNrNrNrNrNsNsNsNsOsOsOsOsOsOs\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\2#\u001cTB<JBIODJXHKiQLxXN^OcPgQjQlRlRkRo,d+U'L$;_;_;_;_;_;_;_;_;_;_;_\u0007\u000b\u0011\u0006 B\u0006 B\u0006 B\u0006 BgPLiQLkRMmSMoTMpUMrUMsVMtVMyYN|ZN~[NO$S%U&X&['_(s;h+`\u001afQgQhQiRjRkSmToUqWsYv[z^}aeimŎpʒt͕wЗyҙzӚ{Ԛzәyїwϔt͒qʏnǋjĈgda^}\\{ZzXyWxVwUwUvTvTvTvTvTvTvTvTuTuTuTuTuTuTuTuUuUuUuUuUuUtUtUtUsUsUrTqTqTpSoSoSnSmRmRlRkRjQjQiQhQgQfQePdPcPbPaP`O_O]O\\O|ZNyYNuWNqUMmSMiQLhPLfOLdNL`LKkPANrNsNsNsNsOsOsOsOsOsOsOsOsOsOsOs\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\#Gy#GybSNP<3NCJRFJ^LKoTM}[NaOePiQkQlRlRiQm-g2Q%]8 ;_;_;_;_;_;_;_;_;_;_\u0014!2\u0006 B\u0006 B\u0006 B\u0006 BgPLjQLlRMmSMoTMpUMrUMsVMtVMyYN|ZNM$Q%T%V&Y&['b+q8r3ePfQgQhQiRjRkSmToUqVsYv[y^}adhlčoȐr˓uΖwЗxјyјxїwϕu͒rːpȍlŊifc`~]|[{YyXxWwVwUvUvTvTvTvTuTuTuTuTuTuTuTuTuTuTuTuTuTuUuUtUtUtUtUsUsTrTrTqTqTpSoSoSnSmRlRlRkRjQiQiQhQgQfQePdPcPbPaP`O_O]O\\N|ZNyYNvWNqUMmSMiQLhPLfOLdNL`LKZIKNsNsOsOsOsOsOsOsOsOsOsOsOsOsOsOtOtOt\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@d@d#Gy#Gy#Gy#Gy#GyhVPKBIQEJUGJeOLtVM]ObPgQjQlRlRkRgQd*X)N$;`;`;`;`;`;`;`\"Gy\"Gy\"Gy\u0014!2\u0006 B\u0006 B\u0006 B\u0006 B\u0006 BjQLlRMnSMoTMpUMrUMsVMtVMyYNK$P%S%U&W&Y&\\'i2h.x8ePfQgQhQiQjRkSmTnUqVsXv[y]|`dgkËnƏqʒs̔uΕvϖwϖvΕu͓sˑqɎnƋkÈheb_~]|[zYyWxVwVwUvTvTvTuTuTuTuTuTuTuTuTuTuTuTuTuTuTtTtTtTtTtTtTsTsTrTrTqTqTpSpSoSnSnRmRlRkRkRjQiQiQhQgQfQePdPcPbPaP`O_O]O\\N|ZNyYNuWNqUMmSMiQLgPLfOLcNL`MKZIKOsOsOsOsOsOsOsOsOsOsOsOsOtOtOtOtPtPtPtPt\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\vvvv#Gy#Gy#Gy#Gy#Gy#Gy#Gy#GyYE<NDJTFJYIKkRLyYN_OdPhQkQlRlRjRo.h2R%c; <`<`#Gy#Gy#Gy#Gy\"Gy\"Gy\"Gy\f\u0018*\u0006 B\u0006 B\u0006 B\u0006 B\u0006 BjQLlRMnSMoTMqUMrUMsVMtVM~I#N$R%T%V&X&Z'^(q9e*j+ePfQgQhQiQjRkSmTnUpVsXuZx]|`cfjmōpȐrʒt̓u͔u͓t̒sˑqɏoǌlĊifda^}\\{ZzXxWwVwUvUvTvTuTuTuTuTuTuTuTuTuTuTuTtTtTtTtTtTtTtTtTsTsTsTrTrTrTqTpSpSoSoSnSmRmRlRkRkRjQiQhQhQgQfQePdPcPbPaO`O_O]O\\N|ZNyYNuWNqUMmSMhQLgPLeOLcNL`LKZIK,P,POsOsOsOsOsOsOsOtOtOtOtPtPtPtPt-Q-Q-Q-Q-Q\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\vvvvvv=a#Gy#Gy#Gy#Gy#Gy#Gy#Gy#GygUOT>3REJVGJ`LKpTM}[NaOePiQkRlRlRhQe)^.P%^8 #Gy#Gy#Gy#Gy#Gy#Gy#Gy#Gy\f\u0018*\u0006 B\u0006 B\u0006 B\u0006 B\u0006 BjQLlRMnSMoTMpUMrUMsVMxF#M$Q%S%U&W&Y&['a+s;g+dPePfQgQhQiQjRkSlSnUpVrXuZx]{_~beikÌnƎpȐrʑs˒sˑrʐqɏoǍmŋkÈheb`~^|[{ZyXxWwVvUvUvTuTuTuTuTuTuTuTuTuTuTtTtTtTtTtTtTtTtTsTsTsTsTrTrTrTqTqSpSpSoSnSnRmRlRlRkRjQjQiQhQgQgQfPePdPcPbPaO`O^O]O\\N|ZNxXNuWMqUMmSMhPLgPLeOLcNL`LKZIK,P,P,QOsOsOtOtOtOtPtPtPtPtPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\vvvvvvvww=a=a=a#Gy#Gy#Gy#Gy#Gy#Gy#Gy#GymYPODJUGJXIKeOLtWM]OcPgQjQlRmRkRp.g0T&N$]8 #Gy#Gy#Gy#Gy#Gy#Gy#Gy\f\u0018*\u0006 B\u0006 B\u0006 B\u0006 B\u0006 BjQLlRMnSMoTMpUMrUMv>\u0013L$P%R%T%V&X&Z'\\'f0m5q3dPePfQgQgQhQjRkSlSnTpVrXtZw\\z_}adgjlČnƎpǏqȏqȏpǎoƍmŋkÉigda_}]|[zYyXxWwVvUvUuTuTuTuTuTuTuSuStStStStStTtTtTtTtTsTsTsTsTsTrTrTrTqTqSpSpSoSoSnSmRmRlRlRkRjQjQiQhQgQfQfPePdPcPbPaO`O^O]O~\\N{ZNxXNuWMqUMiQLgPLfOLeOLbNL_LKZIK,Q,Q,Q,Q,QOtPtPtPtPtPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\vvvvwwwwwwww=a=a=a=a=a#Gz#Gz#Gz#Gz#Gz#Gz#GzgUOS=2RFJWHJ[JKlRMzYN`OePiQkRmRlRiQh*h4R%N$^9 [JK#Gy#Gy#Gy#Gy#Gy\f\u0018*\u0006 B\u0006 B\u0006 B\u0006 B\u0006 BjQLlRMnSMoTMpUMI#L$O$Q%S%U&W&X&Z'](l5f,t5dPePfPfQgQhQiRkRlSmToVqWtYv[y^|acfhklÌnōnōoōnŌmċkigec`~^|\\{ZyYxWwVvUvUuTuTuTuTuTtStStStStStStStStStStSsSsTsTsTsTrTrTrTrSqSqSpSpSoSoSnSnRmRmRlRkRkRjQiQiQhQgQfQePePdPcPbP`O_O^O]O~[N{ZNxXNtVMqUMhPLgPLfOLdNLbML_LKbE6,Q,Q,Q,Q-Q-Q-QPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@dwwwwwwwwwwwwww=a=a=a=a=a=a=a#Hz#Gz#Gz#Gz#Gz#Gz#GzmYPPDJUGJYIKbMLqUM\\NbPfQjQlRmRlRp,e+\\+R%N$b; ]8 [7 XHKO+\u000fN1\u001eL/\u001eL/\u001eL/\u001eK/\u001eK/\u001e\u0002\u000b\u0017e<!J#{=\fJ$L$N$O$P%S%T%V&X&Y&['`+m7d)h*dPdPePfQgQhQiRjRlSmToUqWsYv[x]{`~begijllËlÊlkihfca_}]{[zYxXwWwVvUuUuTuTuTtTtTtStStStStStStStStSsSsSsSsSsSsSrSrSrSrSqSqSqSpSpSoSoSnRnRmRlRlRkRjQjQiQhQhQgQfQePdPcPbPaP`O_O^O]O~[NzZNwXNtVMpTMgPLfOLeOLcNLaMK^KKbE6,Q-Q-Q-Q-Q-QPtPtPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-R-R\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@d@d@d@d@d@dwwwwwwwwwwwxx=b=b=b=b=b=b=b=b#Hz#Hz#Hz#Hz=a=agUOS=2RFJWHKZJKiQLvXN^OcPhQkRmRmRkRm-j3W(R%O$e<!c; a: ^9 ]8 [7 X6\u001fX6\u001fX6\u001fK$M$_(yF#U&N$N$O$P%R%S%U&W&X&Z'\\(d.j2f*bPcPdPePfQgQhQiRjRkSmTnUpWsXuZw\\z_}acegijjjjigfdb`~^|\\zZyYxXwWvVuUuUuTtTtTtTtStStStStStStSsSsSsSsSsSsSsSrSrSrSrSrSqSqSqSpSpSoSoSnRnRmRmRlRkRkRjQiQiQhQgQgQfPePdPcPbPaP`O_O^O\\O}[NzYNwXNsVMoTMgPLfOLdOLcNL`MK]KKaE6-Q-Q-QPtPtPtPtPtPtPtPt-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-R-R-R-R-R-R-R\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@d@d@d@d@d@d@e@e@e@e@ewwwxxxxxxxx>b>b>b>b>b>b>b>b=b=b=b=b=b=b=b=bYE<bJ>UGJYIK_LKnSM|ZN`OePiQlRmRmRiQg*j4W'R%Q%h>!g=!f=!d<!c; b; `: N$`(b(d)f)|H#X&X&W&Q%R%T%V&W&Y&['](d.e,n1bPcPdPePfQgQhQiRjRkSlTnUpVrXtZv\\y^{`~bdeghhhhgfdba~_|]{[yZxXwWvVvUuUuTtTtTtTtStStStStStSsSsSsSsSsSsSsSsSrSrSrSrSqSqSqSqSpSpSoSoSnRnRmRmRlRlRkRkQjQiQiQhQgQfQfPePdPcPbPaO`O^O]O\\O}[NyYNvWNrVMoTMfOLeOLdNLbML`LK\\KKaE6PtPtPtPtPtPtPtPtPuPuPuQuQu-Q-Q-Q-Q-Q-Q-Q-Q-R-R-R-R-R-R-R-R-R.R.R~~\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@d@d@d@e@e@e@e@e@e@e@eAeAeAexxxxxxxxxx>b>b>b>b>b>b>b$Hz$Hz$Hz$Hz$Hz>b>b>b>b>bgVOS=2RFJWHK[JKeOLsVM]ObPgQjQlRmRlRr/g*h2U&S%R%Q%Q%P%[']'`(b(d)f)g)i*j*I#Z'Z'Z'Z'Z'['['\\']'_)d,d)q3bPcPdPePfQfQgQhQiRkSlSmUoVqWsYu[x]z^|`~bdeffffedba~_}^{\\zZyYwXwWvVuUuUtTtTtTtStStSsSsSsSsSsSsSsSsSsSsSrSrSrSrSrSqSqSqSpSpSpSoSoSoRnRnRmRmRlRkRkRjQjQiQhQhQgQfQePdPcPcPbP`O_O^O]O\\N|ZNyYNuWNrUMnSMjQLdNLcNLaMK_LK[JK`D6PtPtPtPtPtPuPuPuPuQuQuQuQuQuQu-Q-Q-Q-R-R-R-R-R-R-R-R-R.R.RRvRvRv~~~~\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\@e@e@e@eAeAeAeAeAeAeAeAeAeAeAexxxxxxxyy>b>b>b$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>b>b>b>b>bYD<W?3UGJYIK\\JKjRLxXN_OdPhQkRmRmRkRp.h,f/[(X&X&Z'\\'^'`(c(e)g)i*j*l*m*o+\\'\\'\\'\\'\\']']'^'_(a)c*e*i+bPcPdPdPePfQgQhQiRjRkSmTnUpWrXtZv[x]z_|`~bcddddcba~_}^{\\z[yZxXwWvVuUuUtTtTtTtTsSsSsSsSsSsSsSsSsSsSsSrSrSrSrSrSqSqSqSqSpSpSpSoSoSoRnRnRmRmRlRlRkRkQjQiQiQhQgQfQfPePdPcPbPaP`O_O^O]O~[N{ZNxXNtWMqUMmSMiQLcNLbML`LK^KKbR_D5PtPtPuPuPuPuQuQuQuQuQuQuQuQuQuQuQu-R-R-R-R-R-R-R.R.RRvRvRvRvRv~~~~~~~~\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\AeAeAeAeAeAeAeAeAeAeAeAeAeAeAeAeyyyyyyyAe$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>b>b>b>bQ@:R<2fL@WHJZJKaMKoTM|ZN`OePiQlRmRmRjRo-i-h0`)]']'`(b(d)f)h)j*k*m*n+p+q+r,]']']'^'_(_(`(`(b)c)i.`OaPbPcPdPePfQgQhQiRjRkSlTnUoVqWsYuZw\\y]{_|`}a~bbbba~`}_|^{]z[yZxYwXvWuVuUtUtTtTsTsSsSsSsSsSsSsSsSsSrSrSrSrSrSrSrSqSqSqSqSpSpSpSoSoRoRnRnRmRmRlRlRkRkRjQjQiQhQhQgQfQePdPdPcPbPaO`O_O]O\\O}[NzYNwXNtVMpTMlRMhPLcNLaMK_LK]KKbR]C5PuPuPuQuQuQuQuQuQuQuQuQuQuQuQuQuQvQvQv-R-R.R.R.RRvRvRvRvRvRvRv\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\AeAeAeAeAeAeAeAeAeAeAeAeAeAeAeAeAeyyyAfAfAf$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>b>b>b>bWD<V>3TFJXHK[JKfOLsVM]ObPgQjQlRmRmRkRm,i,j/d+c)c(e)f)h*j*l*n+o+q+r+s,t,K$^(_(_(`(a(a)b)d*f+m1`OaPbPcPdPePfQfQgQhRiRkSlTmToVpWrXtYv[w\\y]z^{_|`}`}`}`}_|^{^{\\z[yZxYwXvWuVtUtUtTsTsTsSsSsSsSsSrSrSrSrSrSrSrSrSrSrSqSqSqSqSqSpSpSpSoSoRoRnRnRmRmRmRlRlRkRjQjQiQiQhQgQfQfPePdPcPbPaP`O_O^O]O\\N|ZNyYNvWNsVMoTMkRLgPLbML`LK^KK\\JK~aR[B5PuQuQuQuQuQuQuQuQuQuQuQuQuQuQvQvQvRvRvRvRvRvRvRvRvRvRvRvRvRv\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\AeAeAeAeAeAeAeAeAeAeAeAeAeAfAfAfyAfAfAfAfAfBf$H{$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>c>c>b>bO?:[E<dK?UGJYIK\\KKjRLxXN^OcPhQkQlRmRmRt.q.j+k-i,h*h*j*k*l*n+p+q+s,t,u,v,w,`(`(a)b)c*d+f+g,k0m1`OaObPcPcPdPePfQgQhQiRjRkSlTnUoVqWsXtZv[w\\y]z^z^{^{^{^{^z]z\\y[xZwYvXvWuVtVtUsTsTsTsTsSrSrSrSrSrSrSrSrSrSrSrSrSqSqSqSqSqSpSpSpSpSoRoRoRnRnRmRmRmRlRlRkRkQjQiQiQhQgQgQfQePePdPcPbPaP`O_O^O\\O~[N{ZNxYNuWNqUMmSMiQLeOLaMK_LK]KKlN>|aRZA5-QQuQuQuQuQuQuQuQuQuQuQvQvQvQvRvRvRvRv.R.R.R.RRvRvRvRvRvRw\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\AeAeAeAeAeAeAeAfAfAfAfAfyyyzzzBfBfBfBfBf$H{$H{$H{$H{$H{$H{$H{$H{$H{$Hz$Hz$Hz$Hz$Hz$Hz$Hz$Hz>c>c>c>cVC<T=3}cVWHJZIKaMLoTM|ZN`OePhQkQlRnRnSt.v2m+l+l+l+m+n+o+p+r+s,u,u,v,w-x-y-b*c+e,g-i/k0m2p4i-_O`OaPbPcPdPePfQfQgQhRiRjSlTmTnUpVqWsYtZv[w[x\\y]y]y]y]y\\y\\x[xZwYvXuWuWtVtUsUsTsTrTrSrSrSrSrSrSrSrSrSrSrSqSqSqSqSqSqSpSpSpSpSpRoRoRoRnRnRmRmRmRlRlRkRkQjQjQiQhQhQgQfQfPePdPcPbPaP`O_O^O]O\\O}[NzYNwXNtVMpTMlRMhPLdNL`LK^KKmO?kN>^C6W@5-Q-QQuQuQuQuQuQuQvQvQvQvRvRvRvRv.R.R.R.R.R.R.R.R.RRvRwRwRwրրրրրրրրրրր\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\AfAfAfAfAfAfAfAfzzzzzzzzzzzBfBfBfBf$I{$I{$I{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$H{$Hz$Hz$Hz$Hz$Hz\u0007\u000b\u0011YE<W?4gYXHKZJKfOLsVM\\NaOePiQkRmRnSnSmS|7s/o,o,p+q+r,s,t,v,w-x-y-z.{/|/e-g/j1m3o5o5r7n3c)_O`OaPbPcPdPdPeQfQgQhQiRjRkSlTmUoVpVqWsXtYuZv[w[w[w[w[w[wZwZvYvXuWtWtVsUsUsTrTrTrSrSrSrSrSrSrSqSqSqSqSqSqSqSqSqSpSpSpSpSpRoRoRoRnRnRnRmRmRmRlRlRkRkQjQjQiQiQhQgQgQfQePdPdPcPbPaO`O_O^O]O~[N{ZNyYNvWNsVMoTMkRLgPLbML^LKnP?lO?iM>\\C6T>4-Q-Q-Q-RQuQuQvQvQvQvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.RRwSwրրրրրրրրրրրրրրրրրEiEiEi\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\AfAfBfBfBfzzzzzzzzzzzzzzzBfBfBf$I{$I{$I{$I{$I{$I{$I{$I{$I{$I{$I{$H{$H{$H{$H{?c?c?c?c$H{$H{$H{SB;R<2zbVUGJXIK[JK[JKuWN\\OaPfPiQlRmRnSnSpT99w2w0v/v.x/z0z0|1~235688m4o7q8u;s9s8j0]O^O_O`OaPbPcPdPePfQfQgQhRiRjSkSlTnUoVpVqWrXsYtYuYuZuZvZvYuYuXuXtWtVsVsUsUrTrTrTrSqSqSqSqSqSqSqSqSqSqSqSqSqSqSpSpSpSpRpRoRoRoRoRnRnRnRmRmRmRlRlRkRkRjQjQiQiQhQgQgQfQePePdPcPbPaP`O_O^O]O\\O}[NzYNwXNtVMqUMnSMiQLeOL`LK]KKmP?kN?|aSZA5P<4-R-R-R-R-R-RQvRvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R׀׀׀׀׀׀׀׀׀׀׀׀׀׀׀EiEiEiEiEiEiEi\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\Bfzzzzzzzzzzzzz{{{{{{BfBfBf%I{$I{$I{$I{$I{$I{$I{$I{$I{$I{$I{?c?c?c?c?c?c?c?c?c$H{$H{$H{jXP^H=}dXUGJXHKZIKkRLwXN]ObPfQiQkRmRnSpTqUrU;>?<9;==>ADHKEr:t;t;t<t:n4f,]O^O_O`OaObPcPcPdPePfQgQhQiRjRkSlSmTnUoVpVqWrWrXsXtXtXtXtXtXtWsWsVsVrUrUrTqTqTqSqSqSqSqSqSqSqSqSqSqSpSpSpSpSpSpSpRpRoRoRoRoRnRnRnRnRmRmRmRlRlRkRkRjQjQiQiQhQhQgQfQfPePdPcPcPbPaO`O_O^O]O~[N{ZNyYNvWNsVMpTMlRMgPLcNLgUeUlO?~bT{`SW@5-R-R-R-R-R-R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.REiEiEi׀׀׀׀׀׀׀׀׀׀׀EiEiEiEiEiEiEiEiEiEiEi\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\zzzzzzzz{{{{{{{{{{{{{BgBgBg%I{%I{%I{%I{%I{%I{%I{@d?d?d?d?d?d?d?d?d?c?c?c?c$I{$I{L=:WD<v_TgZuZLWHKYIKmSMyYN^OcPfQiQkQmRnSpTqTsVwX8CIJNRTUVZ_Su=t=s;q9o6h.a)\\O]O_O_O`OaPbPcPdPePeQfQgQhRiRjRkSlTmTnUoUpVpVqWrWrWrWrWrWrWrVrVrUrUqUqTqTqTqSqSpSpSpSpSpSpSpSpSpSpSpSpSpRpRpRoRoRoRoRoRoRnRnRnRmRmRmRlRlRlRkRkQjQjQiQiQhQhQgQfQfPePdPdPcPbPaP`O_O^O]O\\O}[NzYNwXNtWMqUMnSMjQLeOLiVfUeUcT|bTcK>`KA-R-R-R.R.R.R.RRvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.R.R.R.REiEiEiEiEiEiׁׁׁׁׁׁEiEiEiEiEiEiEiEiEiEiEiEiEiEiEiEi\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\zz{{{{{{{{{{{{{{{{{{{|CgCg%I{%I{%I{@d@d@d@d@d@d@d@d@d@d@d@d?d?d?d?d?d?d$I{$I{dUPYE<xaVlSGw]OVHJbMLoTMzYN^OvRePhQjQmRnRpSqTuVyZ{[^acʌiΏlђnX_aSUq:n7k3h0c*^(\\N]O^O_O`OaObPbPcPdPePfQfQgQhRiRjRkSlSmTmTnUoUpVpVqVqVqVqVqVqUqUqUqTqTpTpTpSpSpSpSpSpSpSpSpSpRpRpRpRpRpRoRoRoRoRoRoRoRnRnRnRnRmRmRmRlRlRlRkRkQjQjQiQiQhQhQgQfQfPePdPdPcPbPaP`O_O^O]O\\O~[N{ZNyYNvWNrVMoTMlRM|WBwUAhVfVlO@~cTzaTaI>XG@-R.R.R.RRvRvRvRvRvRvRvRv.R.R.R.R.R.R.R.R.R.R.R.R.R.R.SEiEiEiEjEjEjEjEjׁׁEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEiEiEi\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\{{{{{{{{{{{{{{|||||||||Cg@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d?d$I{$I{RA;P<3zcXnVIuh~pdNLpUMwzZvSePgQjQlRmRoSpTuVvWxY|\\_ÆdƉgȊhʌi̎kΏlRFk4g1d-b+_(Z'}[N\\O]O^O_O`OaPbPcPcPdPeQfQgQgQhRiRjRkSkSlTmTnTnUoUoUpUpUpUpUpUpTpTpTpTpSpSoSoSoSoSoSoSoRoRoRoRoRoRoRoRoRoRoRoRoRnRnRnRnRnRmRmRmRlRlRlRkRkRkQjQjQiQiQhQhQgQgQfPePePdPcPbPbPaO`O_O^O]O~\\N|[NzYNwXNtVMpUMpYoXzWBuUBgVlP@jO@|bUx`TcMB3!\u0014.RRvRvRvRvRvRvRvRvRvRvRwRwRw.R.R.R.R.R.R.R.R.R.S.S.SEjEjEjEjEjEjEjEjEj؁EjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEjEj\u0013\\\u0013\\\u0013\\\u0013\\Bg{{{{{{{||||||||||||CgCgCgCg|@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d%I{;0/SB;R=4fODpXLxkrvbzx{[ÏldPgQiQjQlRnRpSqTrTtUwW{Z}\\|\\}\\~]]}+~6d.a+_)^(\\'zYN|ZN~\\N]O^O_O_O`OaPbPcPdPdPeQfQgQgQhRiRjRjSkSlSlTmTmTnTnTnToToToToToToSoSoSoSoSoSoSoRoRoRoRoRoRoRoRoRoRoRoRnRnRnRnRnRnRmRmRmRmRlRlRlRlRkRkQjQjQjQiQiQhQhQgQgQfQePePdPcPbPbPaO`O_O^O]O\\N}[NzZNxXNuWMrUMrZpY|XCxVCsTBmQAkOA~cVzaU`I>\\IARvRvRvRvRvRvRvRvRvRvRwRwRwSwSwSwSw.R.R.R.R.R.S.S.S.SFjFjFjFjFjFjFjFj؂؂؂؂؂FjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFj\u0013\\\u0013\\Bg{||||||||||||||CgCgCgCgCgCgCgCg}@e@e@e@e@e@e@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d@d%I{<1/J82^I@gQFqYNxlsvc{dy{\\wUčiePgQhQkQmRmRnRoSpSrTtUtUtUtUtUtUt.L&](['Z'Y&xYN{ZN}[N\\N]O^O_O`OaOaPbPcPdPePeQfQgQgQhRiRiRjRkSkSlSlSmSmSmSnSnSnSnSnSnSnSnSnSnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRnRmRmRmRmRmRlRlRlRlRkRkRkQjQjQiQiQiQhQhQgQfQfPePePdPcPbPbPaO`O_O^O]O\\O}[N{ZNxYNvWNsVMs[rZ~ZDnYkYqSBkPAiOA|cVbK?\\G>NB?RvRvRvRvRvRvRvRvRwRwRwSwSwSwSwSwSwSwSw.S.S.S.S.S.SFjFjFjFjFjFj؂؂؂؂؂؂؂؂؂؂FjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjCgCg|||||||||||CgCgCgCgCgCgCgCgCgCgCgCg}AeAeAe@e@e@e@e@e@e@e@e@d@d@d@d@d@d@d@d@d@d%I{@d@d<1/H72\\I@ePGpYNxmtvc{ezupwUuQePgQiQjQjQlRmRnRnRoRoRoRoRoRg\u001cb; Z'Y&W&S%vXNyYN{ZN~[N\\O]O^O_O`OaOaPbPcPdPdPeQfQgQgQhQiRiRjRjRkSkSlSlSlSlSmSmSmSmSmSmRmRmRmRmRmRnRnRnRnRnRnRnRnRnRnRmRmRmRmRmRmRmRmRlRlRlRlRkRkRkQjQjQjQiQiQhQhQgQgQfQfPePdPdPcPbPbPaO`O_O^O]O\\O}[N{ZNyYNvXNtVMu\\]E[EoZmZkYnRBjOB}cVdL@`I?XGARvRvRvRvRvRvRwRwRwRwSwSwSwSwSwSwSwSwSwSwSw.S.S.S.S/SFjFjFjFjققققققققققققققFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjقCgCg|||||||CgCgCgCgCgCgCgCgCgCgCgCgChChChChCh}AeAeAeAeAeAeAeAeAe@e@e@e@e@e@e@e@d%I{%I{%I{%I{%I{@d@d<10F61o]Vye]oexmuud{e}d|atpÏluQdPePfQgQiQjQjQjQjQjQkQkQkQ_9 X&V&T%rUMuWMwXNzYN|ZN~[N\\O]O^O_O`OaObPbPcPdPdPeQfQfQgQhQhRiRiRjRjRkRkRkRlRlRlRlRlRlRlRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRmRlRlRlRlRlRkRkRkRkQjQjQjQiQiQiQhQhQgQgQfQfPePdPdPcPbPbPaO`O_O^O]O\\O~[N{ZNyYNwXNtVMrUM^F]Fq\\o[lZqTDfX}dWeMAbK@O=6NB@RvRvRvRvRwRwRwRwSwSwSwSwSwSwSwSwSwSwSwSwSxSxSx/S/SFjFjFjككككككككككككككككككFjFjFjFjFjFjFjFjFjFjFjFjFjFjFjكككCgCgCg}}}CgCgCgCgCgCgCgCgChChChChChChChChChChDhDhDh~AeAeAeAeAeAeAeAeAeAeAeAeAe%I{%I{%I{%I{%I{%I{%I{%I{%I{@d@dE:9D61m\\Vwe]lXOuaXk_z||e|c|`z]yXnÏlĎkĎidPePfPfPfPfPfPfPfP[7 U&T%P%pTMsVMuWMxXNzYN|ZN~[N\\O]O^O_O`OaObPbPcPdPdPePeQfQgQgQhQhQiRiRjRjRjRkRkRkRkRkRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRlRkRkRkRkQkQjQjQjQiQiQiQhQhQgQgQfQfPePePdPdPcPbPbPaO`O_O^O]O\\O~[N|ZNyYNwXNuWMrUM`G^Gr]|ZFxXFtVEgY~eY{cXbLA[H?REA.R.RRvRwRwRwSwSwSwSwSwSwSwSwSwSwSwSwSxSxSxSxTxTxTxككككككككككككككككككككككككFjFjFjFjFjFjFjFjFjFjFjكككككCgCg}}CgCgCgCgChChChChChChChChChDhDhDhDhDhDhDhDhDhDh~AeAeAeAeAeAeAeAeAe%I|%I|%I|%I{%I{%I{%I{%I{%I{%I{%I{%I{%I{%I{@e@eB99B51k[Vud]iWPr_Wye]y|}|e|cw{^z\\yZpxWwUwUwUwUÎlÎlllkD(S%P%nSMoTMqUMsVMvWNxXNzYN|ZN~[N\\O]O^O_O`OaOaPbPcPcPdPePeQfQfQgQgQhQhQiQiRiRjRjRjRjRkRkRkRkRkRkRkRlRlRlRlRlRlRlRlRlRlRlRlRkRkRkRkRkQkQkQjQjQjQjQiQiQiQhQhQgQgQgQfQfPePePdPcPcPbPaPaO`O_O^O]O\\O~[N|ZNyYNwXNuWMrUMw_v_t^~\\GzYGvWFj[fZ|dYybX\\I@VGB5/2.R.R.R.RSwSwSwSwSwSwSwSwSwSwSwSwSxSxSxSxTxTxTxTxFkFkFkFkڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃFkFkFkFkFkFkFkFkڃڃڃڃڃڃڃ}}}}ChChChChChChChDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDh~AeAeAeAeAe%J|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I{%I{%I{%I{%I{%I{@e@e<68?31gYVpa\\bRMjYTq`Zj`z}}|{zxwz^tsssrrrrh2O$L$mSMnSMnTMoTMtVMvWNxXNzYN|ZN~[N\\O]O^O_O`OaOaPbPcPcPdPdPePeQfQfQgQgQhQhQhQiQiQiQiQjQjQjQjQjQkQkQkQkRkRkRkRkRkRkRkRkRkQkQkQkQjQjQjQjQjQjQiQiQiQhQhQhQgQgQgQfQfPePePdPdPcPbPbPaP`O`O_O^O]O\\O~[N|ZNyYNwXNtWMz`y`w`u_]I|[HwXGl\\i[}eZycYr_WjZU;23.R.R.R.R.R.R.RSwSwSwSwSwSwSwSwSxSxSxTxTxTxTx/S/SGkGkGkGkGkGkGkڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃڃGkGkGkڃڃڃڃڃڃڃڃڃڃ}}}}~DhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhAf%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I|%I{%I{AeAeAe?89H=<gZXpb_aSPi[Vud]x{ufwfyf||{yyzbzbzayayaya^=%V)kRLlRMmSMmSMnSMoTMoTMvWNxXNzYN|ZN~[N\\O]O^O_O`O`OaPbPbPcPdPdPePePfQfQfQgQgQhQhQhQhQiQiQiQiQiQjQjQjQjQjQjQjQjQjQjQjQjQjQjQjQjQjQjQjQiQiQiQiQiQhQhQhQgQgQgQfQfPePePdPdPcPcPbPaPaO`O_O^O^O]O\\O}[N{ZNyYNwXNtVM{bzaxawa_J~\\IyZItWHj]g[dNDr`Xj[VOCB.R.R.R.R.R.R.R.R.SSwSwSwSwSxSxSxSxTxTxTxTx/S/S/SGkGkGkGkGkGkGkGkGkڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄGkڄڄڄڄڄڄڄڄڄڄڄ~~~~~~DhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDh%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|%I|%I|%I|%I|AeAeAe4285.0G??g\\[XMK`TRg[Yyt{h`lbodreufvfwfwewe{{{zzbD.T+\\EkRLkRMlRMmSMnSMnSMsVMvWNxXNzYN|ZN~[N\\O]O^O_O_O`OaOaPbPcPcPdPdPePePfQfQfQgQgQgQhQhQhQhQhQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQiQhQhQhQhQgQgQgQfQfQfPePePdPdPcPcPbPbPaP`O`O_O^O]O]O\\N}[N{ZNyYNvXNtVMfLdLcLbLvbtar`o_pVHkSGcOE]KDj[WNCB\u0000\u0000\u0000.R.R.R.R.R.S.S.S.S.S.SSxSxSxSxTxTxTx/S/S/S/S/SGkGkGkGkGkGkGkGkGkGkGkGkڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄGkGkGkGkGkڄڄڄڄڄڄڄڄڄ~~~~~~DhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDhDi&J|&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|AeAeAe\u001a\u0015\u0014-*.3-0G@Ae\\]jabs`Ssjk|qovrtd_{halcmcmcncncyyyy\\A.~ZE[F]G^GkRLlRMlSMmSMqUMsVMuWNwXNyYN{ZN}[N\\O]O]O^O_O`O`OaPaPbPcPcPdPdPdPePePfQfQfQgQgQgQgQhQhQhQhQhQhQhQiQiQiQiQiQiQiQiQiQhQhQhQhQhQhQgQgQgQgQfQfQfPePePePdPdPcPcPbPbPaPaO`O_O_O^O]O\\O~[N|ZNzYNxXNvWNsVMgNfMdMcMwcubsbparWIkSHbOF]KEj\\X_UT@<?.R.R.R.R.S.S.S.S.S.S/S/S/S/STxTxTx/S/S/S/S/S/SGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkۄۄۄۄۄۄۄۄۄۄۄۄۄۄGkGkGkGkGkGkGkGkGkۄۄۄۄۄۄۄ~~~~~~DhDhDhDhDhDhDhDhDhDhDhDiDiրրրEiEi&J|&J|&J|&J|&J|&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|%I|('.,*/>:?YUY`QGfVLudXjeitlm{po|qp}rp~rpsqsqtqr_=1+xJ)o[~[F\\G^H_I`IkRLlRMnSMpTMrVMuWMwXNyYN{ZN}[N~\\N\\O]O^O_O_O`O`OaPbPbPcPcPcPdPdPePePePfPfQfQfQgQgQgQgQgQgQgQhQhQhQhQhQhQhQhQhQgQgQgQgQgQgQfQfQfQfPePePePdPdPdPcPcPbPbPaPaO`O_O_O^O]O\\O~\\N}[N{ZNyYNwXNuWMiOhOgOeOzeydwdtcrbtYKjTIaOG[KFj]Y^UU?;@.R.R.S.S.S.S.S.S/S/S/S/S/S/S/S/S/S/S/S/S/S/S/SGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkGkۅۅۅۅۅۅۅۅۅۅGlGlGlGlGlGlGlGlGlGlGlGlGlۅۅۅۅۅDhDhDhDhDiDiDiDiDiրրրրրրրրրրրEiEi&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|AfAeAe%J|%J|%J|%I|%I|%I|%I|\u0000\u0000\u0000\u001f#-#%.()1MEAQIEUMI]SL]TM=4.1+(=.#6,&5( 1%\u001e\"\u001d\u001blYn[p\\r]]H_I`JwaybkRLmSMpTMrUMtVMvWNxXNzYN|ZN}[N\\N]O]O^O_O_O`OaOaPaPbPbPcPcPdPdPdPePePePePfPfPfQfQfQfQfQgQgQgQgQgQgQgQgQfQfQfQfQfQfPfPePePePePdPdPdPcPcPcPbPbPaPaO`O_O_O^O]O]O\\O}[N|ZNzYNxXNvWNggghPfP|fzfxevdscsYLiTK_NHYKFh\\Z]UV=;@.R.S.S.S.S.S.S/S/S/S/S/S/S/STxTxTxTxTx/S/S/S/SGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlۅۅۅۅۅۅGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlGlۅۅۅDiDiDiDiDiDiրրրրրրրրրրրրրրր׀׀׀Ei&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|BfBfAfAfAfAfAf%J|%J|%J|%J|%J|%J|%I|%I|%I|\u0007\u0006\u0005\u0017\u001e,\r\u001a+\u000e\u001b,\u001b!.\u0018\u0016\u0018! \"\u0016\u0015\u0018\u0015\u0015\u0018\u0014\u0014\u0017\u0014\u0015\u0018\u0015\u0017\u0019`E6iYlZo\\q]s^^Jvawbyczd{e}foTMqUMsVMuWNwXNyYN{ZN|ZN~[N\\O]O]O^O_O_O`O`OaOaPbPbPcPcPcPdPdPdPdPePePePePePePePePfPfPfPfPfPfPfPePePePePePePePdPdPdPdPcPcPcPbPbPaPaO`O`O_O_O^O]O]O\\O~[N|[N{ZNyYNwXNiiiihhRfQdQbPwfx]Opdkbtd_m`]OEDG?A;:@.S.S.S.S.S/S/S/S/S/S/S/S/STxTxTxTxTxTxTxTxTy/SGlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl܅܅HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl܅Eiրրրրրրրրրրրր׀׀׀׀׀׀BgBgBgBgBg&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|BfBfBfBfBfBfBfBfBfAfAf%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|%I|\u0000\u0000\u0000\u0014\u0018\u001e\r\u001a+\u000e\u001b,YA5jPBpSDl[o]q^t`_Kwbycze{f}ghilSrVMtWMvWNxXNyYN{ZN|[N~[N\\O]O]O^O_O_O`O`O`OaPaPbPbPbPcPcPcPcPdPdPdPdPdPdPdPdPePePePePePdPdPdPdPdPdPdPcPcPcPcPbPbPbPaPaO`O`O`O_O^O^O]O]O\\O~[N|[N{ZNyYNxXNjjjjjjhSgSeRcR|`Qsfoe}jcrd`k_]LCDC=@,,3(4F(4F.S.S/S/S/S/S/S/S/STxTxTxTxTxTxTxTxTxTyTyTyHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlChChրրրրEiEiEiրրրրրր׀׀׀CgCgCgCgCgCgCgCgCgCgCgCgBgBg&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|BfBfBfBfBfBfBfBfBfBfBfBfBfBfBf&J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|%I|%I|%I|\u0017#5H71O;3V?4iOBoSDsVFo]{[I^K`LbNdO{f}g~hjkTmUoVqWrWwXNxXNzYN{ZN}[N~[N\\O]O]O^O^O_O_O`O`O`OaOaPaPbPbPbPbPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPbPbPbPbPaPaPaO`O`O_O_O_O^O^O]O\\O\\N~[N|ZN{ZNyYNoToToTnTllljUiThTfTcSvirgnfyidqdah^^HBD?<@)+3OZkMYk(5F(5F(5F/S/S/S/S/STxTxTxTxTxTxTxTxTyTyTyTyUy܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlDhDhDhCh&K}&K}&K}&K}&K}&K}ChChCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCg&J|&J|&J|&J|&J|&J|BgBgBgBfBfBfBfBfBfBfBfBfBfBfBfBfBfBfBf&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%J|%I|%I|A99N?;L:2T>4gNBlRDk\\n^z[J~^LaNcOdPfQgRhTjUlVnWpXrXsYqqrrrsz[z[z[{[{[{ZœrŒqŒqŒpŒpőoyVxVxUwTwTaPbPbPbPbPbPbPbPbPbPbPbPbPbPaPaPaPaPaOaO`O`O`O_O_O^O^O^O]O]O\\O~\\N}[N|ZNzYNpTpUpUpUoVoVnVmVlVkVjVhVfU~cUujqh~mfugdkaad\\^E@D98?$(2minffm^blV^lMYk(5F(5F/STxTxTxTxTxTxTxTxTxTyTyTyUyUy܆܆܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHl݆݆݆݆݆݆݆݆݆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}ChChChChChChChCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCg&J|CgCgCgCgCgBgBgBgBgBgBgBfBfBfBfBfBfBfBfBfBfBfBfBf&J|&J|&J|&J|&J|&J|&J|%J|%J|%J|%J|%J|%J|%J|AeAe;GY<68I=:I82Q=4XA6~fZj\\m^p`|]L`NcPeQgSjlmnoXqYrZt[rsstttz]{]{]{\\{\\{\\{[ēsērĒrĒqĒpđpyWĐoÐnÏmÏllkkaOaOaOaOaOaOaO`O`O`O`O`O`O_O_O_O_O^O^O]O]O]O\\O~\\N}[N|ZNllmqVqVqVpWpWoWnnnnn~neWxltkpiykfodcf_`JDG@>C*,5\u001d$1MYktr~tstmolinadmX_lNZkMZkTxTxTxTxTxTxTxTyTyTyUyUyUy݆݆݆݆݆݆݆݆݆HlHlHmHmHmHmHmHmHmHmHmHm݆݆݇݇݇݇݇݇݇݇݇݇HmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhChChChChChChChCgCgCgCgCgCgCgCgCgCgCg&J}&J}&J}CgCgCgCgCgCgCgCgCgCgBgBgBgBgBgBgBfBfBfBfBfBfBfBfBf&J|&J|&J|&J|&J|&J|&J|&J|&J|&J|AfAfAfAf;GY;GY;GY1'!D:9N?;N;3]I?zdYh[l^oascuebQdRfTlmnopqrsv]w]uuuuv{^{^|^|]|]{\\{\\{[{[zZzZyYyXxXonnmmuTuStStStRsRsQ_O_O_O^O^O^O^O^O]O]O]OrSrSrSkllmmmnnqWqXqXooppppp}o{cXv`Vp]U}nishfhaba\\_DAF::B$)4\u0002\u0001\u0000MYkMYkMYktctq\\QPPIKFDI;>H/8GMZkTxTxTxTxTyTyTyUyUyUy݆݆݇݇݇݇݇݇݇݇݇݇݇HmHmHmImImImImIm݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇ImImImImImImImImImImImImImImImImImIm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDhDhChChChChChChChChCgCg&K}&K}&K}&K}&J}&J}CgCgCgCgCgCgCgCgCgCgCgCgCgCgBgBgBgBgBgBgBfBfBfBfBfBf&J|&J|&J|&J|&J|&J|BfBfBfBfBfBf;HY;HY;GY;GY;GY;GY;,#I=:H82YF?^JA|e[j]n`qctewgyi|k~lnopqssu]v^w^x_y_z_z_{_wwvvvuut{\\{\\z[zZyZyYxXpowWvVvVuUuUuTtTlkkkkkksTrTrTrTrTrUrUrVnnnoooppqYqqrrrrqgZ{dYvaXp^WiYU`TRVNOb]aEBH<<D36@\u0019\u0019\u001cMYkMYkMYkMYkMZk-.1W>+[NL^SQWNNKFJ?AI2:HTxTyTyTyUyUyUyUyUy݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇ImImImIm݇݇݇݇އއއއއއއއއއއއއއއއImImImImImImImImImImImImImImImIm'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDhDhDhDhDhDhDhCh&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}CgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgBgBgBgBgBgBgBfBfBf&J|&J|BfBfBfBfBfBfBfBfBf;HY;HY;HY;HY;HY;HY;GY3(\"D::B41RB=YG@wcZ}g\\k_nbrdug}aRdTgViXkYqrstp^q^w`x`y`z`za{axxwwwvvvuutssrrqqppoovWnnnnnnmtVsVsVsVsVsWsWsXsXpppsYsYrZr[r\\q\\p]ttssh\\{e[vbYo^XhZV`USXPQNJMECJRS[47A+((\u000f\u0013\u0019MYkMYkMYkMZk(5F(5F(5FOHJT=+YML_SRZQQMGJABI2:H/TUyUyUyUyUyUy݇݇݇݇݇އއއއއއއއއއއއއއއއއއއއއއއއއއއއއއއއވވވވވވވImImImImImImImImImImImImވ'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDhDhDhDhDh'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}CgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgBgBgBgBg&J|&J|BfBfBfBfBfBfBfBfBf;HY;HY;HY;HY;HY;HY>DM>DM;HY89<:+#9&\u001aB52I94ZHAxd[}g^k`ncrey_R}bTeVgXiYk[l\\n]o^vvvawaxaybzb{b{axx|a|a|`{`{_{_{^z^uttssrrwZwZvYvYvYuXuXuXuXpppppppqqtZt[s\\s\\s]r]r^q^p^o^n^l^j^h]{f\\ub[n^YgZW_UTWPQOKOEEKST]JNY>=?\u0015\u0017\u001cJJIMYkMYk(5F(5F(5F(5F(5F)5G)5GK=4S<*XMLbWVYPPLGJ@AI/T/TUyUyUyއއއއއއއއއއއވވވވވވވImImImImވވވވވވވވވވވވވވވވވވވވވވވވވImImImImImImImImވވވ'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhDhDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}ChChCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCgCg&J|&J|&J|&J|&J|BgBgBgBfBfBfBfBfBf;HY;HY;HY;HY;HY;HYCIR>DMCIR;HYCIR.$\u001d0\"\u00198&\u001a?*\u001cG/\u001fV=+w[F{g^kanXMs\\Px_S{bU~dWfYhZj\\l]m^vwxyyzzzzz{b{b{b{b{a{a{`{`z_z_z^uy]y]x]x\\w\\w[w[v[v[v[v[rrrsssstuut^s_s_r_r`q`p`wvvu~twd]sb[l^ZeYW]TUUORLJOYYaRU^JOZ>>@!$)\u0010\u0012\u0015RXaMYk39B-3<-3<(5F)5G)5G)5G)5G)5GFDJK9*^K=YONg\\\\TLMIFJ:>I0T0TImވވވވވވވވވވވވވވވވވImImInInInInInInވވވވވވވވވ߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈InInInInIn߈߈߈߈߈'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DiDiDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}ChChChChChCgCgCgCgCgCgCgCgCgCgCg&J}&J}&J}&J}&J|&J|&J|&J|&J|BgBgBgBgBgBfBf<HZ<HZ<HZ<HZ;HY;HYCIR>EM>EMCIR;HY;HYCIRCIR)\u001d\u00156&\u001a8&\u001b@*\u0019H0\u001dI1!\\B0}_JhTKjM8q[Pt]Sw`U{cW~eYg[i\\k^m_vwxyzz{{{{{zdzdzczczcyyyxxxwwwww_w_w_vvvvwwwwwwxxxxxxxxwv~v|tysvrh\\YcXX[TUSNRIHOUXaNS^JFE>>A')+\"%(\u0001\b\u00104:C(5F(5F3:B3:B-3<-3<)5G)5G)5G)5G)5G)5GE:4O:*TKLbXWcZZPIKDCJImImImImވވވވވވވވވވވ߈߈߈InInInInInInJnJnJnJnJn߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈߈߉߉߉߉߉Jn߉߉߉߈߈߈߈'K~'K~'K~'K~'K~'K~'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhChChChChChChCgCgCgCg&K}&K}&J}&J}&J}&J}&J}&J}&J}&J}&J|&J|&J|CgCgCgBgBgBg<HZ<HZ<HZ<HZ<HZMS\\CIR>EMCIRCIRCIR888DGNCJRCIRBBB(\u001d\u00150 \u00158&\u001b<)\u001cG0\u001fM5\"X@0z^KbFkUlXPp[Rs^TvaVzcX}fZg\\i]uvwxyzz{{vevewewe||{{{{{{zzzzzyvbvbvbububuctctcsbscrcqcyyyxxww|uytvs~sqyooslmVQTOLR[\\dQU`KHHAAD:<@68;\u001c &\u0001\u0001\u0001\u0000\u0002\u0005Z`i-4<%');AJ4:C4:C4:C-4<)5G)5G)5G)5G)6G)6G@84H8-N?5YPQmccoghd`dInInInInInIn߈߈߈߈߈߈߈߈߈JnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJn߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉߉JnJnJn߉߉߉߉߉߉'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~EiEiEiEi'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDhDhChChCh&K}&K}&K}&K}&K}&K}&K}&K}&J}&J}&J}&J}&J}&J}&J}&J}&J}CgCgCgCg<IZ<IZ<HZ<HZ<HZ<HZ?EN?ENCJRCJRCJRCJRCJRUU\\CJRCJRBDG''''''(\u001c\u0014. \u00159(\u001c:(\u001cB-\u001eO8'kUFt[IhQyic}leogrjtlwnypzq|s|g]~h_j`kalaobpcqdrdrdseteteue||||||||ueududtdtdsdsdrdrdqdqdpcocncyyx~w}w{vyuvs}srxopqknkgkdbhGGOVYcPLLBCF;>B9;>68;\u001b\u001d\u001f\u0000\u0000\u0000\u0002\u0002\u0002\u0000\u0002\u0005Z`iZ`iMZk)5G4:C-4<4:C4:C-4<;BJ)5G)6G)6G)6G)6G)6GC6-L;.leg{{ypqhbeVYcJnJnJnJnJnJnJn߉߉߉߉߉JnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJn߉߉߉߉߉߉JnJnJnJnJnJnJn'L~'L~'L~'L~'L~'L~'K~'K~'K~EiEiEiEiEiEiEiEi'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDhDhDhDh'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&J}&J}&J}&J}&J}&J}CgCgCg<IZ<IZ<IZ<IZ<IZ<IZ?ENDJSDJSDJS?EN?EN?EN<HZ04?'.6'.6&(+''''''\u001d\u001d\u001d,\u001f\u0018)\u001d\u00151#\u00187&\u0019;)\u001dM8)S;+mVGdKseawhc{kfnhpjrltmvotaZvc[wd]yf^zg_{h`|i`~jakblbmcncodpdpdpdpdpe{pepepepepdododndmdmclckc}jc|jbyhb}w{wyvwuut}sryqqunpojmhfkKKRDFOD><535=AG=?D?AD<?B&(+\"$'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0005KRZTZcMZkKOVRYaSYb.4=.4=4:C.4=4:C)6G)6G)6G)6G)6G)6GWMFaRGhbe{su}}kde_^dJnJnJnJnJnJnJnJn߉߉JnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJoJoJoJoJoJoJoJoJoJoFjFjFjFjFj'L~EiEiEiEiEiEiEiEiEiEiEi'K~'K~'K~'K~'K~'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}Dh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&J}&J}&J}&J}Cg>==<IZ<IZ<IZ<IZ<IZMT\\DJS?ENDJS?EN?EN?EN\")1\")1C5+//3(.7&),'''''''''\"\"\"\u001c\u001c\u001c\u001a\u0012\r.\u001e\u0011, \u00187(\u001d8'\u001bA1&F4(L8*oXIw]Jpdasfcvhexkg{mi~ojqll\\Xn^Yp`Zpa[qa\\rb]rc^sc^sd_ue`wf`xgayhayhayhbxyyyyyy~ywgbvfateasd`qd`pc`nb_la_ut|ssxqrunpZUXVRWROUMMSHIRIC@967-/3'+0(*-ACF?AD;=@#%(\u0001\u0001\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001JMPU[dSYbKPVW]fY`hSYbSYb.4=4;C4:C.4=)6G)6G)6GCPaCPaCPaFED]PGdaesmomefb_dJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJoJoJoJoJoJoJoJoJoJoJoJoJoJoJoJoJoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoFjFjكككڃڃڃڃEiEiEiEiEiEiEiEi'K~'K~'K~'K~'K~'K~'K~'K~'K~'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}DhDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&K}&J}@K[=IZ<IZ<IZ<IZ<IZNT]DJS?ENDJS#)2#)2#)2#)2#)2'.6A4+028(.7'),)))######\"\"\"\u001c\u001c\u001c6$\u0016nP?\u001a\u0013\r.\u001e\u0011+\u001f\u0017>1(B3)B2&F4'E4)gTGlXJs^OzcTzaPqfethgvjhbVTcWUdXVeYWfZXg[Yh\\Zi]Zi][j^\\usususts~tt~tt}tt|st{stut~tt|sszrsyqrwpquoqsmpqloXTXTQWPOULLSSJEA<:=99757335./2113)+.'),)+.8:=\u001e\"(\u0000\u0000\u00003@Q\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0001\u0001JMPV\\eT[cNZlNZlZ`iZ`iZ`iZ`iSYbY`h4;C.4=)6GCPaCPaCPaCPaCPaEQbZOGa_emhknfgeaeJnJnJnJnJnJnJoJoJoJoJoJoJoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoኮኮኮኮኮኮKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoڃڃڃڃڃڃڃڄڄڄڄڄڄEjEiEiEiEi'L~'L~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K}'K}'K}'K}'K}'K}'K}DiDiDiDiDhDh'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}&K}&K}&K}&K}$.>=I[=I[<IZ<IZ<IZ?FN'.6#)2#)2#)2#)2#)2#)2(.7#)2\u001f,=@<A348)/8\"$'\"$'######\"\"\"\u001c\u001c\u001c\u001c\u001c\u001c\"\u0014\tkF+;(\u0019\u001a\u0013\r\"\u001b\u00166*#5*\">2)>0&A2'C3(I8-^OFbRHfUJjXMq^RwcVzfYfRDfQCdN@zdTqijrjksklrklrklrklqjmpjmpjmojmojmnimmimkhliflscYm`Xg\\VbYT^VRE>;A<:>98:77645:873220/0,-/)+.*,/#%(\u001b &\u0000\u0000\u0000\u0000\u0000\u000015;5BS\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000KKKJMP]dlU[dNZlNZlZ`iTZcZaiZaiZ`iZ`iSZbLS[V]eDPbDPbDPbDPbDPbDPbWMF^^dieirkeaeJoJoJoJoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoኯኯኯKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoڃڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄڄۄGk'L~'L~'L~'L~'L~'L~'K~'K~'K~'K~'K~'K~'K~'K~'K~'K~EiEiEiEiEiDiDiDiDiDi'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}&K}&K}&K}&K}%/> ,>=I[=I[ ,> ,>#)2(.7#)2(.7#)2#)2#)2#)2(.7(.7(.767@D>A214$+3#%(\"$'###\"\"\"\"\"\"&&&\u001c\u001c\u001c888888cB*}\\I@!\b\u001b\u0017\u0014%\u001e\u0019+%!5*$:/(;0)<1*>3+@4+>1(bUKN@6OA6L=3QB8M?4_RKaTLbUMcVNcVNcVObVOaVOaUO`UO_UO^UO^TO\\SOYRNWPNUOMWPKYSOWRN;63953:76755333,/2'),%(+\"%(\u001c!'\t\t\t\u0000\u0000\u0000\u000f\u0010\u0012\"&,KXi04:\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003\u0003\u0003JMP]_b^emU[dNZlNZlT[cU[dU[dU[d[ajW]fDPbDPbDPbDPbDPbDPbnSw|mqjKoKoKoኮኮኮኮኮኯኯኯKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpڄڄڄڄڄڄڄڄڄڄڄۄۄۄۄۄۄۄۄGkGkGkGkGkGk'L~'L~'L~'L~'K~'K~'K~EiEiEiEiEiEiEiEiEiEiEiEiDiDi'K}'K}'K}'K}HlHlHlHlHlHlHlHl'K}'K}'K}'K}'K}'K}'K}'K}'K}'K}&K}*2? ->=I[=I[ ,> ,> ,>#)2#)2#)2(.7(.7#)2#)2(.7(.7(.7(.7/28:79G@A<89',4#%(#%(######\"\"\"\"\"\"\u001c\u001c\u001c8888888887'\u001avS:jW;)\u001c\b\u0004\u0000\u000f\f\n\u0016\u0011\r\u0019\u0013\u000e\u001e\u0016\u0011&\u001e\u001a3#\u0018.$\u001e-% .% .& /&!,#\u001d,#\u001d@70A71XNHXNHWNHWNHZRLYQLYQLXQLWQLWPLUOLSNLQMKOLJMJJ0//.-.,,-&(+\u001e\"(\u001d!'\u0013\u0016\u0019\u000b\u000b\u000b\t\t\t\u0000\u0000\u0000\u0014\u0018\u001e\u0013\u0014\u001615;6CT37=\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000MMMKMP^ad_enY`hNZlNZlU\\dV\\eDQbDQbDQbDQbDQbMUcyl|oiKoኯኯኯኯኯኯዯዯዯዯዯዯዯዯዯKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpKpKpKpKpKpKpKp⋯⋯⋯LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpڄڄڄڄڄۄۄۄۄۄۄۄۄۄۅۅۅۅۅۅGkGkGkGkGkGkGkGkGkۅ܅܅܅܅܅܅܅܅܅܅܅܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHl'K}'K}'K}'K}'K}'K}'K}'K}'K}HO\\=J[=J[=J[ -> ,> ,>(.7#)2#)2(.7(.7(.7#)2(.7(.7(/7(/7)/8/28114H7,99@.05&,5$&)$$$######\"\"\"(((8888888888888884\"\u0014nO9gXjZE/ (\u0019\u000e\u0007\u0003\u0000-\"\u001c\r\u000b\n\u0012\u000f\f\u0015\u0011\u000e\u0016\u0012\u000e\u0018\u0013\u000f\u0019\u0014\u0010\u001c\u0017\u0012\u001c\u0019\u0017%\u001f\u001b' \u001c%\u001a\u0012$\u0019\u0012#\u0019\u0011\"\u0018\u0011 \u0017\u0011\u001f\u0016\u0010\u001c\u0019\u0018\u001b\u0019\u0018\u001a\u0019\u0018!\u001f \u001f!$\u0017\u001a\u001d\r\r\r\f\f\f\f\f\f\u000b\u000b\u000b\t\t\t\t\t\t\u0004\u0006\b\u0001\u0001\u0001\u0000\u0000\u0000\u0013\u0015\u001748>7CU:GX\u000b\u000f\u0015\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000JJJLLLKMPagp_enNZlLPVDQbDQbDQbDQbNVcuorjѼዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯKpKpKpKpKpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLp⋰⋰⋰⌰⌰⌰LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpۄۄۄۄۄۄۄۄۅۅۅۅۅۅۅۅۅۅۅۅGkGkGkGlGlGl܅܅܅܅܅܅܅܅܆܆܆܆܆܆܆܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHl'K}'K}'K}'K}DhDhDhIP\\=J[=J[=J[=J[ -> ->(.7#)2#)2(.7(.7(.7#)2(.7(/7(/7)/8)/8)/803966:E?AC>A856,07%'*%')$$$######(((DDDBBB888888888\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c0 \u0014cF1w]OcS{`QS;+5\u001b\u00067'\u001c\u0017\r\u0004\r\u0006\u0001\u0017\r\u0005\u001c\u0011\b* \u001b\u001f\u0016\u000f\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\u0005\u0003\u0001\u0004\u0002\u0000\u0004\u0002\u0000\t\u0007\u0004\f\r\u000f\f\u0010\u0016\b\b\b\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0006\u0007\t\u0011\u0014\u0017;?E7CU;HY=I[\f\u0011\u0017\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000JJJMMMKMPacfbhqEQcHScNVdȵዯዯዯዯዯዯዯ⋯⋯⋯⋯⋯⋰⋰⋰⋰⋰⋰⋰LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLp⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpۄۄۅۅۅۅۅۅۅۅۅۅۅۅۅۅۅۅۅ܅܅GlGl܅܅܅܅܅܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHl݇DhDhDhDh=J[=J[=J[=J[=J[=J[ ->(/7#)2#)2(.7(.7(.7#*2(/7)/8)/8)/8)/8)08*0903:56:88@KBB=;@348*08&(+'(*%%%$$$(((EEE(((&&&\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u0000\u0000\u0000\"\u0018\u0010>-\"bF3oXMs[Ow]Py^PqbpXMdH5R<,Q;,\u001b &\u001b\u001f%\u001a\u001e%#'-\"'-&3DS_qP\\nR_p>J\\?K]<AG\u0010\u0015\u001b\u000e\u0010\u0013\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000%%%DDDACF⋯⋯⋰⋰⋰⋰⋰⋰⋰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰LpLpLpLpLpLpLpLpLpLpLpLpLp⌰㌰㌰㌰㌰㌰㌰㌰㌰㌰㌰㌰㌰㌰LqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqۅۅۅۅۅۅۅۅۅۅۅۅ܅܅܅܅܅܅܅܅GlGl܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆܆݆݆݆݆݆݆݆݆HlHlHlHlHlHlHlHlHlHlHl݇݇݇݇݇݇DhDh=J[=J[=J[=J[=J[=J[=J[(/739B#)2(.7(/7(/7#*2$*3)/8)/8)/8)08*09+19(-5*.5/16437D>AG@B::@66:-29'),)'%BBBFFFEEE)))))))))&&&\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b@@@FFFACFZ\\_[ajagpEQcGRcKTdPWd⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰㌰㌰㌰㌰LpLpLqLqLqLqLqLqLq㌱㌱㌱㌱㌱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱MqMqMqMqMqMqMqMqMqMqMqMqMqMqMqۅۅۅۅۅۅ܅܅܅܅܅܅܅܅܅܅܆HlHlHlHlHl܆܆܆܆܆܆܆܆܆܆܆݆݆݆݆݆݆݆݆݆݆݆݇݇݇݇݇HlHlHlHlHlHlHl݇݇݇݇݇݇݇݇އއއށ>J\\>J\\=J[=J[=J[=J[FLU39B#*2(/7)/7)/8$*3$*3$*3)/8)08*09*09*19',5(-5*.6.17338@<=G@BH@BXW]UUXLPWFHKDFHKKKHHH+++%%%%%%$$$###!!!!!!\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b777777777777777777777\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001bAAAFFFACFACF\\^aeltbhqDQbDQbDQbERcERcERcERcHScLUdRXd|nj⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰㌰㌰㌰㌰㌱㌱㌱㌱㌱㌱㌱㌱㍱㍱㍱㍱MqMqMqMqMqMq㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱MqMqMqMqMqMqMqMqMqMqMqMqMq܅܅܅܅܅܅܅܅܅܅܆܆܆܆HlHlHlHlHlHlHlHlHl܆܆܆݆݆݆݆݆݆݆݆݆݆݆݇݇݇݇݇݇݇݇݇݇݇݇HlHlHlHlHl݇݇݇އއއއއއއއއއށ>J\\=J[=J[FLUFLU(/7(/7*08*08%+3$*3$+3$+3*09*09*19&,5&,5'-6).6*/7-18NPURRVXUVc]^f^_[X]\\XYTUZLQYKMPFHJ)))(((&&&%%%%%%$$$$$$###!!!!!!!!!\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b777777777\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001bBBBEEEACGADGFIL\\ckZ`iTZcDQbDQbDQbagpbiqcircirY`hY_hERcERcERcGSdJTdNVdTYeLpLp㌰㌰㌰㌱㌱㌱㌱㌱㌱㌱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱MqMq㍱㍱㍱䍱䍱䍱䍱䍱䍱䍱䍱䍱䍲䍲䍲䍲䍲䍲䍲䍲䍲䍲䍲䍲䍲MqMqMqMqMqMqMqMqMqMqMq܅܅܅܆܆܆܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHl݆݆݆݆݆݆݆݆݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇HmއއއއއއއއއއއވވވވވށFLUFLUFLU)/8+08+08&+3&+3%+4%+4%+4*19+1:&,5'-5'-6(.6FLTHMTINUKOVOQWSTXYWX`[^lbac]_f_\\a_aY\\aRX_,.1*,.*+-***((('''&&&%%%%%%$$$$$$$$$###!!!!!!!!!!!!!!!\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001c\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b\u001b%%%%%%%%%%%%\"\"\"\"\"\"\"\"\"KKKJJJFFFGIL]_b^dm\\bkV]eDQbEQcEQcEQccirdjsdksektdjsdjscir[ajZ`iOU^ERcERcFRdFRdITdLUdPWeVZeLpLqLqLq㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱䍱䍱䍱䍱䍱䍲䍲䍲Mq䍲䍲䍲䍲䍲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲MrMrMrMrMrMrMrMrMrMr܆܆܆܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇݇އއއއHmHmHmއއއއވވވވވވވވވވވވށ-18,18',3',4',4&,4%,4+1:,2:'-5DJSEKSEKTFLTFLUHMUINVKOWLPWQSYTUZWWZpjje^`offb\\_h`]eaaCCG8;A27?-/2+-/.+)******)))((('''&&&&&&%%%%%%$$$$$$$$$$$$$$$$$$######???EEEEEEEEE((((((###&&&%%%HJMHJMHJMHJM_en]dlZ`i_enEQcEQcEQcEQcbhqektflufluflufluektektdksdjscjr\\ckQW`[ajZaiOU^FRdFRdFRdHSdKUdNVeRXeX\\fLqMqMqMqMq㍱㍱㍱㍱㍱䍱䍱䍱䍱䍲䍲䍲䍲䍲䍲䍲䍲䎲䎲䎲䎲䎲MrMrMrMrMr䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲厲厲厲厲厲厲厲厲NrNrNrNrNrNrNrNr܆܆܆܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl݇݇݇݇݇݇݇݇݇݇݇݇އއއއއއއއHmHmHmHmImImImވވވވވވވވވވވވވވވނPT[KOVJOV(-4(-4'-5'-5JOXEKSEKSEKTFLTFLTGMUGMUHNVIOWKPWLQXMRYPTZTV[\\]a_^asljd^azporjkE@CLEBIEFEDG29A28A17@135,.1+-0+,/./1..0'),)))++++++++++++***FFFFFFACFACFEEEACFACFJLOJLOKQZ_en]clY_hU[dEQcEQcEQcEQcEQcagp[aj\\bk\\bkgnvgnvgmvgmvfluflueltektdksdjscjrcirTZcSYbRYaRXaQW`[bj[ajZ`iFSdFSdGSdJTdLVePXeTZfZ]fMqMqMqMqMqMqMq䍲䍲䍲䍲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲NrNrNrNrNrNrNrNrNr厲厲厲厳厳厳厳厳厳厳厳厳厳厳厳厳厳厳厳右右右右右右右NrNrNrNrNr右冪܆܆HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHl݇݇݇݇݇އއއއއއއއއއއއImImImImImImImImImImވވވވވވވވވ߈߈߈߈߈߈߂LPVLPWKPWFLTFLTFLUGMUGMUHMVHNVINWIOWKPXLQYMRYNSZTX`X[a[]b]^c__ccacib`JDGi__aYYPJLD@C=;AKEDTQR@?A>>A;<A17@06?/6>/5>.4=-4<IOXHOWMS\\QX`EQcEQcEQcEQcEQcEQc`fo[bj\\bk]cl]dl^dm^dm]dlhnwhnwgnvgmvgmvfluflueltektdksdjscircirV\\eU[d_fn^emSYbRXaQX`[bjPV_OV^FSdGSdITeLVeNWeRYfW[f\\^gMqMqMqMqMqMqMqMq䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲䎲厲厲厲厲NrNrNrNrNrNrNrNrNrNrNrNr右右右右右右右右右右右右右右右右右右右右右右右右右右右Ns右右右HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHmHmHmއއއއއއއއއވވވވވImImImImImImImImImImImImImވ߈߈߈߈߈߈߈߈߈߈߈߈߉߂JPXJPXKQYQW_RW_SX`TY`UZaW[bZ]c\\^c^_dCDHDDHTRSWQO@=BNHKbYZ^VWUNPMGJFAEgcgcafEQc`go[aj]cl]cl^dm^em_en_en_en_en^em^dm^dmioxhnwhnwgnvgmvgmvfluflueltektdjsdjscirW]fagp`go`fo_enSYbRXa\\ck[bj[ajFSdGSdITeKUeNWeQXfTZfY]g``gMqMqMrMrMrMrMrMrNr厲厲厲厲厳厳厳厳厳厳右右NrNrNrNrNrNrNrNrNrNrNrNrNsNsNsNs右右右右右揳揳揳揳揳揳揳揳揳揳揳揳援援援援援援援援OsOs援援HlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHlHmHmHmHmHmHmHmHmHmHmHmއވވވވވވވވވImImImImImImImImImImImImImImImImIm߈߈߈߈߈߉߉߉߉߉߉߉߉߂PRWOQWTW\\`dkbek^af_ag`bgabgiko_en^emhnw`fo`fo`fo`fo`fo`fo`fo_fn_fn_en_en^em^dm^dmioxhowhnwgnvgmvgmvflufluektektahpagp`foTZcSYbRYa\\ck\\bkPV_GSeITeKUeMWePXfSZfW[f\\^gdbhMrNrNrNrNrNrNrNrNrNrNr右右右右右右右右NrNrNrNsNsNsNsNsNsNsNsOsOsOsOsOsOsOsOs援援援援搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴OsOsOsOsOs搴HlHlHlHlHlHlHlHlHlHlHlHmHmHmHmHmHmHmHmHmHmHmHmHmImImImImވވވވވވވImImImImImImImImImImImImImImImImImImImImIm߉߉߉߉߉߉߉߉߉߉߉߉߉߃CPaCPaOVbRSWQRWPRWUW]U[dU\\dW]eW]eX]eV\\eagpagp`go`go`fo`fo`fo`fo_fn_en_en^em^dmioxioxhowhnwgnvgmvgmv`foTZcSZbRYaQX`\\bkGSeITeKUeMWfPXfSYfV[gZ]g_`hNrNrNrNrNrNrNrNrNrNrNrNrNr右右右右右NsNsNsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOs搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴OsOsOsOsOsOsOsOsOsHlHlHlHlHlHmHmHmHmHmHmHmHmHmHmHmHmHmImImImImImImImImImImImވވވImImImImImImImImImImImImImImImImImImImImImImImImIm߉߉߉߉߉߉߉߉߉߉CPaCPaCPaCPaCPaQWcYY\\XX\\RSXWX]bdiU[dU[dU[dagpagpagp`go`go`fo`fo`fo_fn_en_en_enipxioxioxhowhnwTZcSYbRYa\\ck\\bjIUeKVeMWfOXfRYfU[gX\\g\\^gcbhNrNrNrNrNrNrNrNrNsNsNsNsNsNsOs援OsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOtOt琴琴琵琵琵琵琵琵琵琵琵琵琵琵琵PtPtPtPtPtPtPtPtPtPtPt\u0013\\HmHmHmHmHmHmHmHmHmHmHmImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImImIm߉߉߉KQZFLUFMUCPaCPaCPaCPaSXcRWcddgddhddiceicejU[dagpagpagp`go`fo`fo`fo_fn_en_enjpyipxioxSYbRXa]ckIUeKVfMWfOXfQYfT[gX\\g[^h_`hgdiNrNrNsNsNsNsNsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOsOtOtOtOtOtOtOtOtPtPtPtPtPtPtPtPt瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵PtPtPtPtPtPtPtPtPtPtPtPtPt\u0013\\HmHmHmHmHmImImImImImImImImImImImImImImImImImImImImIm߈߈ImImImImImImImImImImImImImImImImImImImImImImInInInInInInInCPaCPaKQZFMUKRZKRZCPaCPaCPaCPaUYcTXcRWceeheeieeiefjefkZ`iZ`iZ`iU[dagpagpagp`go`fo`fo`fo_fn_enjpyJUfKVfMWfOXfRYgTZgW\\g[^h^`hcbijfiNsOsOsOsOsOsOsOsOsOsOsOs搴搴搴琴OsOsOsOtOtOtOtOtOtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPt瑵瑵葵葵葵葵葵葵PtPtPtPtPtPtPtPtPtPtPtPtPtPtPt\u0013\\\u0013\\ImImImImImImImImImImImImImImImImImImImImImImIm߈߈߈߈߉ImImImImImImImImImImImImImImImInInInInInInInInInInInInJnJnCPaCPaT[cKQZFMUKRZKRZLR[GMV@BDCPaDPbWZcVYcTXcSXcgfi\\[_ggjggkfglioxioxipxjpyjpyjqy`foagpagpagp`go`fo`foNWfPXgRYgT[gW\\gZ]h^_hbaigdimgjOsOsOsOsOsOsOsOsOsOs琵琵琵琵琵瑵瑵瑵PtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPtPuPuPuPu蒶蒶蒶蒶PuPuPuPuPuPuQuQuQuQuQuQuQuQuQuQuQu\u0013\\\u0013\\ImImImImImImImImImImImImImImImImImImImIm߉߉߉߉߉߉߉߉߉ImImImImImImImImInInInInInInInInInInInInInJnJnJnJnJnJnJnJnJnJnCPaCPaU[dKRZGMVLR[LR[LR[GMVGNVHNWDPbDPbY[dWZdVZdUYcTYchgi]\\_hhkhhl]^bjowjpxjpxjpxjpyjpykqykqzkqzkqz`foagpagpagpRZgU[gW\\hZ^h]_haaiecijfjOsOsOsOsOsOsOsOtOt瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵PtPtPtPtPtPtPtPtPtPtPtPtPuPuPuPuPuPuPuPuQuQuQuQuQuQuQuQuQu蒶QuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQu\u0013\\\u0013\\\u0013\\ImImImImImImImImImImImImImImImIm߉߉߉߉߉߉߉߉߉߉߉߉ImImInInInInInInInInInInInInInJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnCPaCPaCPaKRZV\\eGMVLR[LR[LR[GNVHNWHOWIOXIOXDPb[\\dZ[dX[dWZdVZdUYd_]__]`jil_^b__clpwlpwlpxlqxlqylqylqylqylqzlrzlrzlr{lr{agpW\\hZ^h]_i`aidciiejmgjOsOtOtOtOtPtPt瑵瑵瑵瑵瑵瑵瑵葵葵葵葶葶葶葶葶PtPuPuPuPuPuPuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQu\u0013\\\u0013\\\u0013\\ImImImImImImImImImImImImIm߉߉߉߉߉߉߉߉߉߉߉߉߉߉InInInInInInInInJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnኮJnJnAFLCPaDPbLR[LR[V]eLR[LR[LS[HNWHOWIOXIPXJPYKQZBFL^]d\\]d[\\dY[dX[dWZdVZd`^``_akjma`ca`dmpvmpwmqwmqxmqxmqxmrymrymrymrzmrzmrzmr{ms{ms{ms{ahpms|ahpagplr{`aiccihejlgjpikPtPtPtPtPt瑵葵葵葵葶葶葶葶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶QuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQuQvQvQv铷铷铷QvQvQvQvQvQvQvRvRvRvRvRvRvRvRvRvRvRv\u0013\\\u0013\\\u0013\\\u0013\\ImImImImImImImImIm߉߉߉߉߉߉߉߉߉߉InInInJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnኮኮኯኯኯJnDPbDPbLR[LR[W]fLR[LS[MS\\HNWIOXIPXJPYKQZLR[PRUQSVDQb^^e]]e\\]eZ\\dY[dX[dWZdb_ab`bb`cbadcekcfkoqwoqworxorxoryoryosyoszoszoszns{ns{ns{ns{chpchqchqchqnt|bhqms|ms|ls{lr{lr{gejlgkohkPtPtPtPt葶葶葶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶钶钶钶钷钷QuQuQuQuQuQuQuQuQuQvQvQvQvQvQvQvQvRvRvRvRvRv铷ꓷꓷꓷꓷꓷꓷRvRvRvRvRvRvRvRvRvRvRvRvRvRvRvRv\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ImImImImImIm߉߉߉߉߉߉JnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnኯኯኯኯዯዯዯᄑDPbDPbV\\eW]fLR[GNVHNWHOWIOXJPYQW`RXaSYbRYaTUXTUXBFLa_e`^e^^e]]e\\]eZ\\eY[eX[dW[dnlmomndbdeeiefjefkefkegleglegmpsxpsypsypszptzptzpt{pt{pt{pt{pt|diqdiqdiqdiqdiqdiqot}bhqbhqms|ms|ms|ls{lr{lr{krzkqzkqznhkqjkPtPt蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶钶钶钶钷钷钷钷铷铷铷铷铷铷铷铷QvQvQvQvRvRvRvRvRvRvRvRvRvRvRvRvRvRvꓸꔸꔸꔸꔸꔸꔸꔸꔸꔸRvRvRvRvRvRvRvRvRvRvRvRvRvRvRv\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ImImIm߉߉߉JnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnJnኯዯዯዯዯዯዯዯዯᄑU\\dV]eLS[HNWHNWIOXOU^JQYQW`RYaTZcagpacfmjiflugnvaVPb`ea_e_^e^^e]]e[]eZ\\eZ\\eY[epmnpnoecefehffigfjggjggkgglghlghmghmghnrtyrtzrtzrtzru{ru{ru{qu{fjpfjqfjqejqejqejqejqejrdjrou}mt|bhqms|ms|ms|ls{ls{lr{lr{krzkqzkqzjqyjpyPu蒶蒶蒶蒶蒶蒶钶钶钷钷钷钷铷铷铷铷铷铷铷铷铷铷铷铷铷ꓷꓷꓷRvRvRvRvRvRvRvRvRvRvRvRvRvRvRvꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸSwSwSwSwSwSwSwSwSwSwSwSwSw\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\JnJnJnJnJnJnJnJnJnJnJnJnJnJnዯዯዯዯዯዯዯዯዯዯዯᄑLR[GNVHNWHNWIOXOU^[ajRXaSYbU[dahpcirektgmvioxjpyBGMbWPc`fb`f`_e_^e^^e]]e\\]e[\\eZ\\eY[eropgegsqssqtsruhgjhhkhhlhhlhimhimhinhjnhjosuzsu{su{sv{hjphkqgkqgkqgkqgkqgkqfkrfkrfjrfjrejrpu}mt|bhqbhqbhqms|ls{ls{lr{lr{krzkqzkqzjqyjpyjpyioxioxsklQuQu钷钷钷钷铷铷铷铷铷铷铷铷铷铷铷铷ꓷꓷꓸꓸꓸꓸꓸꔸꔸꔸꔸꔸꔸRvRvRvRvRvRwRwRwRwRwRw딸딸딸딹딹딹딹딹딹딹딹딹딹땹땹땹땹SwSwSwSwSwSwSwSwSwSwSwSw\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ኮኮኮኮኮJnJnJnJnJnJnJnJnJnJnJnዯዯዯዯዯዯዯዯዯዯዯዯዯ⅑HNWHNWIOXOU^\\bk]cl^emU\\dbhqdjsfluhnwipxkqzlr{ahpeXPdWPdafc`fa`f`_f__f^^e]^eifgtrsurtusuutvjiljiljimjjmjjnjjnjkojkojkpikpikpikpikqikqikqhkqhkqhkqhkrgkrgkrgkrgkrfkrqv}bhqbhqbhqahpahpagpagplr{lr{krzkqzkqzjqyjpyjpyioxiox]cl\\ckgnvpjlrklulmQuQuQu铷铷铷铷铷铷铷铷ꓷꓷꓸꓸꓸꓸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸ딸RwSwSwSwSwSwSwSw땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹땹SwSwSwSxSxSxSxSxSxSx\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ኮኮኮኮኮኯኯኯኯኯኯኯJnJnJnJnJnJnJnዯዯዯዯዯዯዯዯዯዯ⋯⋯⋯⋯⋰⅑NT]OV^[bj]cl_enagpX^gdksfmuhnwjpykrzagpbhqahphZQfYQgcfebfdafc`fb`fjghkgivsuvtvvtwvuwkjmkjmkknkknkkovwzvw{vw{vw{klpjlqjlqjlqjlqilqilqilqhkrhkrhkrhkrgkrgkrfkrbhqbhqahpahpbhpagpagp`go`go`fokqzkqzjqyjpyjpyipxioxiox]cl\\ck\\bk[bjfmuflunilpjlrklulmQuQuQuQuQv铷ꓷꓸꓸꓸꓸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸꔸ딸딸딸딹딹딹딹딹땹땹땹SwSwSwSwSwSw땹땹땹땹땹땹땹앹앹앹앹앹앹앺앺앺앺앺앺앺앺앺앺앺TxTxTxTxTxTxTxTx\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ኮኮኮኮኮኯኯኯኯኯኯኯዯዯዯዯዯዯJnJnJnJnዯዯዯዯዯዯዯዯ⋯⋯⋯⋯⋰⋰⋰⋰⋰⋰→[aj]cl_enagpX^gZ`i\\bkioxjqylr{ahpbhqahpagp_fnj[QiZQhcgkghlhiwtuxuvxuwxvxxvxmkmxwyxwzxwzxw{ww{ww{ww{wx|klqklqklqjlqjlqjlqjlqilqikqhkqhkqhkqgkqgjqeiqeipdipdipchpchpbhobgoagoafo_en_en_enjpyipxioxiox]cl]cl\\bk\\bk[aj[ajfluZ`iY_hZ_hlhlnilpjlrkmtlmwnmQvQvRvRvRvRvRvꔸꔸꔸꔸꔸꔸꔸꔸꔸ딸딸딹딹딹딹땹땹땹땹땹땹땹땹땹땹땹땹땹땹SxSx앺앺앺앺앺앺앺얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺TxTxTxTxTxTxTx\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ኮኮኮኮኮኯኯኯኯኯኯኯኯዯዯዯዯዯዯዯዯዯዯዯዯዯJoዯዯዯዯ⋯⋯⋯⋯⋰⋰⋰⋰⋰⋰⌰⌰⌰⌰⌰⅒QX`_emagpY_gZai\\bk^dm`folr{ahpahpchpbgolqyhnwl\\Q\\]fmiimijmjknjknklnkmnkmywyywzywzyx{xx{xx{xx{xx{wx|llpklpklqklqjlqjlqjkqikqikqhkpsv|sv|su|ru{fipfipeipeiodhodhocgocgnbgnbfnafn^dm^dm]dliox]cl^cl]ck]bk\\bj[aj[aifltektY_hX_gIVgMXhNXhlhmojmqjmpjmskmtlmvmmRvRvRvRvRvRvRvRvRvꔸ딸딸딹딹딹딹땹땹땹땹땹땹땹땹땹땹땹땹앹앹앹앺앺앺앺앺얺Tx얺얺얺얺얺얺얺얺얺얺얺얺얺얺얺햺햺햺햺햺햺햺햻햻햻햻햻햻햻햻TyTyTyTyTy\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ኮኮኯኯኯኯኯኯኯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯJoJoJo⋯⋯⋯⋰⋰⋰⋰⋰⋰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⋕choZ_g\\ai^dk^dm`folr{ls{agpdipchomqx]^f]^f\\^fzvvzvwoklokmolmolnnlnzxzzxzyxzyx{yx{xx{xx{xx{llpllpklpklpvw{uw{uv{tv{tv{ruzfiofhnehnehndgncgmcgmbfmbfmaellpxlpwkpwkov^cj^cj]bj]bihmugltgltfksKWhKWhOYhPYhQZhR[iS[iU\\ilimojmrknslmtlmrkmvmmvmnyonRvRvRvRvRvRvRwRwRwRw땹땹땹땹땹땹땹땹땹땹앹앹앹앺앺앺앺얺얺얺얺얺얺얺얺TxTxTxTxTx햺햺햺햺햻햻햻햻햻햻햻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻UyUyUyUy\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ኯኯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯ⋯⋯JoJoJoJoJo⋰⋰⋰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰→^bi`dkbfmdhokrzlr{lr{qt{psy__g^_g^_g]^g{vv{ww{wxolmolmolmolnzxzzxzzxzyxzyxzmlomlollolkowwzvwzvvzrtyqsyegmegmdglorxoqwnqwmqwmpvlpvlovkouknu_bijntimtimthlsNXhNXhPZhQZhR[iS[iT\\iU\\iW]iX^jY^j[_jnjnpkorlotmnumnvmnvnnwnnxnnyonRvRvRwRwRwRwSwSwSwSwSwSw땹땹땹앹앹앺앺앺얺얺얺얺얺얺얺얺얺얺얺얺얺햺TxTxTxTyTyTyTyTy헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻헻UyUy\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯዯ⋯⋯⋯⋯⋯JoJoJoKoKoKoKoKoKo⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰⌰㌰㌰㌰㏗dglfhnru{krzsu{rtzªĬ©baga`g``g``g__g^_g]_gpkkpklpll{wx{wx{wyzwynlmnlnnlnmknmknlknlknfglegkefkdfkoqvoqvnpunpumoumou`ci`bh_bh_bhPYhPYhQZhRZiS[iT[iU\\iV]iW]iX^jY^jZ_j[_j\\`j^ak`bkackokormpunpvopwoownoxnnxonyonzon{pn{poRwSwSwSwSwSwSwSwSwSwSwSwSwSx얺얺얺얺얺얺얺얺얺얺얺햺햺햻햻햻햻헻TyTyUyUyUyUyUyUyUyUyUy헻헻Vz\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ዯዯዯዯዯዯዯዯዯ⋯⋯⋯⋯⋯⋰⋰⋰KoKoKoKoKoKoKoKoKoKoKoKoKo⌰⌰⌰⌰⌰⌰⌰⌰㌰㌰㌰㌱㌱㌱㌱㌱㑘rtyhjotv{Ȯϳϳǫdbhcbhbahaaha`h``h_`g__g^_g]_gokkokk{wxzwxzwxzwxyvxmjlefjeeideioptoptnotbchachabgS[hS[hS[iT[iU\\iU\\iV\\iW]iW]iX^jY^jZ_j[_j\\`j]aj_ak`bkbckcdkeelgfligmqlptoqwpryqrzqqzppzppzpozpo{po|po|qo|qoSwSwSwSwSwSwSwSwSwSxSxSxTxTxTxTx얺얺얺햺햺햻햻햻햻헻헻헻헻헻헻UyUyUyUyUyUyUyUyUyUyUyUyUyUyUz\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ዯዯዯ⋯⋯⋯⋯⋯⋰⋰⋰⋰⋰⋰⋰KoKoKoKoKoKoKoKoKoKoKoKoKoKoKo⌰⌰⌰㌰㌰㌰㌱㌱㌱㌱㌱㌱㍱㍱㍱㌇ͱҵҳаfciechdbhcbhbahbahaahaah``h_`h_`h^_h]_hzvvzvvqptppsV\\iV\\iV\\iU\\iU\\iV\\iV]iW]iX]iX^iY^jZ_jZ_j[_j\\`j]`j^aj_ak`bkbckcckddkeelgfligmkinnjoqlpwpszst}tu~tt}ss}rr|rq|qp}qo}qo~qo~ro~roSwSwSwSwSwSxSxSxTxTxTxTxTxTxTxTxTxTx햻헻헻헻헻헻헻헻헻헻헻헻UyUyUyUyUyUyUyUyUzUzUzUzUzVzVzVzVzVz\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\⋰⋰⋰⋰⋰⋰⋰⋰⌰⌰⌰KoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKo㌱㌱㌱㌱㌱㌱㍱㍱㍱㍱㍱㍱㍱㍱㔚TYeSYekjmvvyŸĬҳұұѰiejhejfdieciecidbicbicbhbahaahaahY^iX^iY^iY^iY^iZ^iZ_i[_j\\_j\\`j]`j^aj^aj_aj`bkabkbckcdkddkfelgflhfljgmkhmnjnplo¹xxwvvuustrsqrprpspspspspSwSxSxSxTxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUy헻헻헻UyUyUzUzUzUzVzVzVzVzVzVzVzVzVzVzVzVzVzVzVz\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\⋰⌰⌰⌰⌰⌰⌰⌰KoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKo㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱㗛VZeVZeVZeVZeVZeVZeVZe̾ĢұԬήѰmilkgljfkhejgejfdjfdieci]`j]`j^`j^aj^aj_aj`aj`bjabkbckcckcdkddkedkfelgflifljglkhmmimnjnpkosmpżȾʿɾȽǻwuustrtqtptptptptpSxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyUzVzVzVzVzVzVzVzVzVzVzVzVzVzVzVzVzV{V{V{V{V{W{W{\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\⌰⌰⌰⌰⌰KoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKp㍱㍱㍱㍱㍱㍱㍱㍱㍱㍱䍱䍱䍱䙜Y\\eY\\eX\\eX\\eX\\fX\\fX\\fX\\fX\\fY\\fY\\fŷþźֲŪɬ̮ٲrmqpkoojnmimkhlbcjbckcckcckddkedkeekfekgelhflifljgljglkhmmimnjmpknrlotnpwprż¿ʾɼǺvruququpupuquqTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyUyUyUyUzUzVzVzVzVzVzVzVzVzVzVzVzV{V{V{V{W{W{W{W{W{W{W{W{W{W{W{W{\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\⌰⌰KoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKpKpKpKpKpKp㍱㍱㍱㍱䍱䍱䍱䍱䍲䍲䍲䍲䛞[]f[]f[]f[]f[]f[]f[]f[]f[]f[]f[]f[]fa`g˼ɾ꽛ĥ˭ѰӳúĻżĽüztvxruhfkhfkiflifljglkgllhllhlmimnimojmpjmqknsmovopyqr|st¹Ƽ̾ʼɺȹvqvqvqvqvqvqTxTxTxTxTyTyUyUyUyUyUyUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVzVzVzVzVzV{V{V{V{W{W{W{W{W{W{W{W{W{W{W{W{W{W{W{W{W|W|W|W|W|\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\KoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpLpLp䍱䍱䍱䍲䍲䍲䍲䍲䎲䎲䎲䘜]^f]^f]^f]^f]^f]^f]^f]^f]^f]^f]^f]^f]^f]^fdbghdhmfhõ÷ؾͮղĹƽɿňƿýnilnilnilojmpjmqkmrkmslntmnvnowopzqq}sswvǽÿ;˼ʺɺɹwqwqwqwqTxTyTyUyUyUyUyUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVzVzVzV{V{V{W{W{W{W{W{W{W{W{W{W{W{W{W{W{W|W|W|W|W|X|X|X|X|X|X|X|X|X|\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\KoKoKoKoKoKoKoKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpKpLpLpLpLpLpLpLpLp䍲䍲䎲䎲䎲䎲䎲䎲䎲䎲䛞]^f^^f^_f^_f^_f__f__f__f__f__g__g__g__g__g__gfchkehoghtjizmjƶüǼٿ۾öŹȻ˿žºslmtlmumnvnnwnoyoo{qp|rrtsvuzx½Ͽͽ̼˻˺˺˺xrxrUyUyUyUyUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVzVzVzVzV{W{W{W{W{W{W{W{W{W{W|W|W|W|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X}X}\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\KoKoKoKoKoKoKoKoKpKpKpKpKpKpKpKpKpKpLpLpLpLpLpLpLpLpLpLpLpLpLpLp䎲䎲䎲䎲䎲䎲䎲䎲Lp[]f^^f__f``f``g``ga`ga`ga`ga`ga`ga`gbagbagbaghdhmfiqiivki|okvpz¶پ搴濱´öŷǺzw~z~ɿƽúzpo|qo}rptrusxu{x~{ľпνμͼͻͻͻͻxrUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVzVzVzV{V{V{W{W{W{W|W|W|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X}X}X}X}X}Y}Y}Y}Y}Y}Y}Y}\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\KoKoKpKpKpKpKpKpKpKpKpKpKpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLp䎲䎲䎲䎲䎲LpLpLqLq]^f__f``ga`gbagbagcagcagcagcagdbgdbhdbhechieiogisjixljpkxqz}ۿ°搴搴濱²²³³³³³³óóôôĵtpvrxt{w~z}¿˿ȼƺĸ¶µöķvsxu{w~y|ž¼оϽϽϼϼϼμͼUyUyUzUzUzVzVzVzVzVzVzVzVzVzV{V{V{W{W{W{X|X|X|X|X|X|X|X|X|X|X|X}X}X}X}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\KpKpKpKpKpKpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLp厲厲LqLqLqLqLqLq__fa`gb`gcagcagdbgdbgebgebhfchfchhdihejlgkqikukjzmjqkxqzy}o}m搴搴搴搴搴²óóĴĴĴŴĴŴŴŴrlsmsntoupwqys{v}x{~þͿ˽ɻǹƸŷŷĶĶĶõõĶĶŷƷǸȹɺʻ̼ξ~y{ƿüҿѾѾѾѽннϽVzVzVzVzVzVzVzVzV{V{V{W{W{W{W{W{W{X|X|X|X}X}X}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y~Y~Y~Y~Y~Y~Z~Z~Z~Z~Z~\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLqLqLqLqLqMqMqMqMq``gbagcagdbgebgfchfchgchgdhhdijfjlhlpjnumnxml|olqkwpyv|n}nNrNr琴琴琵琵琵ĳŴŴƵƵƵƵǵslslsmsmtmtnuovpwqys{u}wy{}~Ŀýξ̽˼ʻʺɹɹȸȸȸȸȸɹʹʺ˻̼νϿ¼|ǿļºӿӿҿҾҾҾѾVzVzVzV{V{W{W{W{W{W{W{W{W{W{Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y}Y~Y~Y~Y~Y~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLqLqLqLq厳右MqMqMqMqMqMqMqMqa`gcagdbgebhfchgchhdhidhjeikgjnjmqmpzrr}rq~qnrlwowu|n~nNrNrNrNr琵瑵瑵瑵瑵ĴŴƵǵȶȶtltmtmtmtmtmtmununvowoxpyrzs|u}wxy{{ſƿƿſľý¼пνͼͼ̻̻˺˺˺˺˺̺̻ͼνϾѿ»z}ǿżúԿԿӿҿV{W{W{W{W{W{W{W{W{W|W|Y}Y}Y}Y}Y~Y~Y~Y~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~ZZZ\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLqLqLqLqLq右右右右右右MqMqMqMqMqMqMqa`gdbgfchfchhdhhdhjehkfilgjpknups~vwwvuqsmvnuu|nNrNrNrNrNrNrNr瑵瑵瑵瑵盖ŵǶȶtmtmumumumumumumumvnvnvnwowoxpyqzr{s|t}v~wwxûüû»ºҿѿоϽϽμμμλλμμϼнѾҿºyz|Ⱦżú¹ѾW{W{W{W{W|W|W|X|Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~ZZZZZ[[[[[\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LpLpLpLpLpLpLpLpLpLpLpLpLpLpLpLqLqLqLqLqLqLqMq右右右右右右右右右MqMqMqMqMq[QIbagebhgchhdhidhjehkfimgjqkmwqs~wz~}{wuovm}rt|nNrNrNrNrNrNsNsNs瑵瑵葵葶葶qlsltmumumumvmvmvmvnvnvnvnwnwnwoxoxoypyqzq{r{s|t}t}u~uӿҿҾѾѽѽнннѽѽѾҾӿwxz|~ȾƼĺù¸¸W|W|X|X|X|Z~Z~Z~Z~Z~ZZZZ[[[[[[[[[[[[\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LpLpLpLpLpLpLpLpLpLqLqLqLqLqLqLqLqMqMqMq右右右右右右右揳揳揳援MqMqMqMqMq]^gcahechgdhiehjeikfimgioikvoqyz{uvnzpt|nNrNrNrNsNsNsNsOsOsOs葶葶OsOsOsrltmumvmvmvnwnwnwnwnwnwnxnxnxoxoxoyoypzpzq{q{r|r|s|s}sԿԿԿԿӿӾӾӾӾӾӾӾӾԿԿvwxy{}~ʿȽƻźĹøø¸¸¸¸X|X|Z[[[[[[[[[[[[[[[[[\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LpLpLpLqLqLqLqLqLqLqLqLqMqMqMqMqMq右右右右右揳揳揳援援援援援搴搴MqMqMrMr^_gdbhfchhdhjeilfimgiohjslm|uw|xpyot}o{nNsNsNsNsOsOsOsOsOsOsOsOsOsOsOsOtOtsmumvmvnwnwnxnxnxnxnxoxoyoyoyoyoyozpzpzp{q{q{q|r|r|r|rտտտտտտտտտտտտտtuvwxz{}~ɾȽƻźĹĸøøøøø¸X|X|[[[[[[[[[[\\\\\\\\\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\LqLqLqLqLqLqMqMqMqMqMqMqMqMq右右揳揳揳援援援援援搴搴搴搴搴搴搴搴MrMrNr_`gdbhgdhieikfimgiohjqjkxpq|}}vxn}r~q{nNsNsOsOsOsOsOsOsOsOs蒶蒶OsOtOtOtPtPttmvnwnwnxnxnxnyoyoyoyozozozozozpzp{p{p{p{q|q|q|q|q|r|rֿ~ttuvvwxz{|}~~˿ʾɽȼǻƺŹĹĸĸĸĸøø¸X}X}Y}Y}[\\\\\\\\\\\\\\\\\\\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\MqMqMqMqMqMqMqMqMqMqMq揳揳揳援援援援援搴搴搴搴搴搴搴搴搴搴搴搴搴NrNrNr``hechhdijeilfingipijtlm~uv~yp{or{nOsOsOsOsOsOsOsOs蒶蒶蒶蒶蒶OtPtPtPtPtPtPtunwnxnxnyoyoyozozozozo{o{p{p{p{p{p|p|p|q|q|q}q}q}q}r}rssttuvvwxyz{|}}}~}}}|{zȼȻǻƺƹŹŹŹŹĹĹĹùY}Y}Y}Y}Y}Y}Y}\\\\\\\\\\\\\\\\\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\MqMqMqMqMqMqMqMq援援援援援搴搴搴搴搴搴搴搴搴搴搴搴搴搴琴琴琴琵琵NrNraahechheikfimgiohjrjkxop}|~vynr|oYTROsOsOsOsOsOs蒶蒶蒶钶钷钷钷铷PtPtPtPtPtPtPtvnxnxoyozozozo{o{p{p{p|p|p|p|p|p|q}q}q}q}q}q}q~q~r~rµ¶ssssttuuvvwxyyz{{{{{{{{zyxxǺǺƺƹƹƹŹŹŹŹĹY}Y}Y}Y}Y}Y}Y~Y~Y~Z~\\\\]]]]\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\MqMqMqMqMq援援援搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴琴琴琵琵琵琵琵瑵瑵瑵Nraahfciieilfingjpijtlm}tu~zp|pqznOsOsOsOsOs蒶蒶钶钷钷钷铷铷铷铷铷PtPtPtPtPuPuPuwnxoyozozo{p{p|p|p|p|p}p}q}q}q}q}q~q~q~q~q~r~rrrrµµ¶¶ssssstttuuvvwwxxyyzzzzyyyxxwwwǺǺƹƹƹƹƹŹĹY}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~]]\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\MqMq搴搴搴搴搴搴搴搴搴搴搴搴搴搴搴琴琴琴琵琵琵琵瑵瑵瑵瑵瑵瑵瑵瑵X\\gbahfdiieilgjohjqjkvno{{vzor|oOsOsOsOs钶钷钷钷铷铷铷铷铷铷铷铷铷ꓷPuPuPuQuQuQuQuxoyozo{p{p|p|p|p}p}q}q~q~q~q~q~q~qrrrrrrrrrösssssttttuuuvvvwwxxxxyyxxxxwwwwwvǺǺǺǺƺƺźY}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~Z~ZZ[\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\搴搴搴搴搴搴搴搴搴搴搴搴琴琴琴琵琵琵琵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵蝡bbigdijeimgjohjskl{rr~{q|p~qynOs钶钷钷钷铷铷铷铷铷铷铷铷铷ꓷꓸꓸꓸQuQuQuQuQuQuQuQuxozp{p{p|p}p}q}q~q~q~q~qqrrrrrrrrrssĶĶsssstttttuuuvvvwwwwxxxxxxxwwwwwwwwȺǺǺǺƺĺY}Y}Y~Y~Z~Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\搴搴搴搴搴琴琴琴琵琵琵琵琵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵葵葵葶葶蠢cbigdijfjmgjpikvmnyyvzor|o钷钷铷铷铷铷铷铷铷铷铷ꓷꓷꓸꓸꔸꔸꔸꔸꔸQuQuQuQuQuQuQvQvypzp{p|q}q}q~q~q~qqrrrrrrrrsssŶŶŶŷŷttttttuuuuuvvvvwwwwwwwwwwwwwwwwwwwȺǺƺY}Y~Y~Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[[[\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\琴琴琴琵琵琵琵琵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵葵葵葶葶葶葶蒶蒶蒶蠢hdikfjnhjrjlyqr{q|p´Լ铷铷铷铷铷铷铷铷ꓷꓸꓸꓸꔸꔸꔸꔸꔸꔸꔸꔸ딸QuQuQvQvQvRvRvRvzp{p|q}q~q~qqrrrrrrrssssŶŷŷƷƷƷƷƷtttuuuuuuvvvvvwwwwwwwwwwwwwwwwwwwwǻY~Y~Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[[\\\\\\\\\\\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\琵琵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵葵葵葵葶葶葶葶蒶蒶蒶蒶蒶蒶蒍lgjohktlnvwwվµʸ铷铷铷铷ꓷꓷꓸꓸꓸꔸꔸꔸꔸꔸꔸꔸꔸ딸딹딹땹땹QvRvRvRvRvRvRvRvzp|q}q~q~rrrrrrsssssŷƷƷƷƷƷǷǷǸǸǸuuuuuuuvvvvvwwwwwwwwwwwwwwwwxxxxxY}Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[[\\\\\\\\\\\\\\\\\\]\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵瑵葵葵葵葶葶葶葶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蚟lgjpikwoqԿõ־铷铷ꓷꓸꓸꓸꔸꔸꔸꔸꔸꔸꔸꔸꔸ딸딹딹땹땹땹땹땹땹RvRvRvRvRvRvRwRw|q|q~r~rrrrrssssƷƷƷƷǷǷǷǸǸȸȸȸȸȸuuuuvvvvvvwwwwwwwwwwxxxxxxxxxxY}Y}Y}Y}Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[[\\\\\\\\\\\\\\\\\\]]]]]\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\瑵瑵瑵瑵瑵葵葵葵葶葶葶葶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶钶钶钷霡rkmûԾµлꓸꓸꔸꔸꔸꔸꔸꔸꔸꔸꔸ딸딹딹딹땹땹땹땹땹땹땹땹앹RvRvRvRvRwRwSwSwSwSw}r~rrrssssŷƷƷƷǷǷǸǸȸȸȸȸȸɹɹɹɹvvvvvvvwwwwwwwwxxxxxxxxxxxxxY}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[\\\\\\\\\\\\\\\\\\]]]]]]]]]^\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\葵葵葶葶葶葶葶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶钶钶钶钷钷钷铷锜mhkunqӾöؿꔸꔸꔸꔸꔸꔸꔸꔸꔸ딸딹딹딹땹땹땹땹땹땹땹땹앹앺앺얺얺RwRwRwSwSwSwSwSwSwSwSwrsssŷŷƷƷǷǸǸȸȸȸȸɸɹɹɹɹʹʹʹʹvvvvwwwwwwwwxxxxxxxxxxxxxY}Y}Y~Y~Z~Z~Z~ZZ[[[[[[[[\\\\\\\\\\\\\\\\\\]]]]]]]]]^^^^^\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\葶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶钶钶钷钷钷钷铷铷铷铷铷闞edjifknilzsuԾöԽꔸꔸꔸꔸꔸ딸딹딹딹땹땹땹땹땹땹땹땹앹앺앺앺얺얺얺얺얺얺SwSwSwSwSwSwSwSxSxTxTxTxķŷŷƷƷǸǸǸȸȸȸɸɹɹɹʹʹʹʹʺ˺˺vvwwwwwwwxxxxxxxxxxxyyyY}Y}Y~Y~Z~Z~[[[[[[[\\\\\\\\\\\\\\\\\\]]]]]]]]^^^^^^^^^^_\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\蒶蒶蒶蒶蒶蒶蒶蒶蒶蒶钶钶钷钷钷钷铷铷铷铷铷铷铷铷铷鍙\\_iabjfdjjfkpkn~xzҽķꔸꔸ딸딸딹딹딹땹땹땹땹땹땹땹땹앹앺앺앺얺얺얺얺얺얺얺햺햻햻SwSwSwSwSxSxTxTxTxŷƷƸǸǸȸȸɹɹɹɹʹʹʹʺ˺˺˺˺˺̺wwwwwwxxxxxxxxxyyyyyY}Y~Y~Z~Z~Z~[[[[\\\\\\\\\\\\\\\\]]]]]]]]^^^^^^^^^______\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\蒶蒶蒶钶钶钶钷钷钷钷钷铷铷铷铷铷铷铷铷铷铷铷ꓷPtPYhW]i]`ibbjfekkgltnr{tӾĸµվ딹딹딹땹땹땹땹땹땹땹땹땹앹앺앺얺얺얺얺얺얺얺얺햺햻햻헻헻헻SwSxSxTxTxTxTxɸǸȸȹɹɹɹʹʹʺʺ˺˺˺˺̺̻̻̻̻wwxxxxxxxxyyyyyyY}Y}Y~Z~Z~Z~Z~\\\\\\\\\\\\\\\\]]]]]]]]^^^^^^^^__________`\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\钶钷钷钷钷铷铷铷铷铷铷铷铷铷铷铷铷铷ꓷꓷꓸPtPtJVhRZhX]i]`jbcjgekmimwru~|wyp·ķ땹땹땹땹땹땹땹땹땹앹앺앺앺얺얺얺얺얺얺얺얺햺햻햻헻헻헻헻헻헻헻TxTxTxTxɹɹʹʺʺ˺˺˺˺̺̻̻̻ͻͻͻͻxxxxxxyyyyyyY}Y}Y~Y~Z~Z~Z~Z~\\\\\\\\]]]]]]]]^^^^^^^^_________``````\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\铷铷铷铷铷铷铷铷铷铷铷铷ꓷꓷꓸꓸꓸꓸPtPtPtJVhMXhT[iY^i^ajccjgeknjo}uwzwxq{rvֿ땹땹땹땹땹땹앹앺앺앺얺얺얺얺얺얺얺햺햻햻햻헻헻헻헻헻헻헻Tx̺˺˺̻̻̻̻ͻͻͻͼͼμμxxxyyyyY}Y}Y}Y}Y~Z~Z~Z~Z~Z~Z~]]]]]]]]^^^^^^^^________`````````aa\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\铷铷铷铷铷铷铷ꓷꓷꓷꓸꓸꓸꓸꔸꔸPtPtPtPuJVhJVhOYiU\\iZ_j_ajcckhflpkputvqxpws}p땹땹땹앹앺앺앺얺얺얺얺얺얺얺얺햺햻햻햻헻헻헻헻헻헻헻TxTx򕓒мѼѽѽѽX}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~]]]]^^^^^^^^________`````````aaa\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\铷ꓷꓷꓷꓸꓸꓸꓸꔸꔸꔸꔸPtPuPuPuPuPuJWhJWhJWhQZiV]i[_j`bkddkhglunpsqvpuv~qQv앹앺앺얺얺얺얺얺얺얺얺얺햺햻햻헻헻헻헻헻헻헻헻TxTxTyTyUyY}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z^^^^^^^^________````````aaaaa\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ꓸꓸꓸꔸꔸꔸꔸꔸꔸꔸPuPuPuPuQuQuQuJWhJWhJWhJWhR[iW]j\\`jabkedknjmzpoto|ty~qRvRvRv얺얺얺얺얺얺얺햺햻햻햻헻헻헻헻헻헻헻TxTyTyUyUyUyUyY~Y~Z~Z~Z~Z~Z~Z~Z^^^^________````````aaaaaaa\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ꔸꔸꔸꔸꔸꔸꔸPuPuQuQuQuQuQuQuJWhJWhJWhKWiKWiS\\iX^j]`kackgeltlnroyrzrIMSRvRvRv얺얺얺얺햺햻햻헻헻헻헻헻헻헻헻TxTyTyTyUyUyUyUyUyUyUyZ~Z~Z~Z~Z~Z________````````aaaaaaaa\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\ꔸꔸꔸꔸ딸QuQuQuQuQuQuQuQuQuKWiKWiKWiKWiKWiOZiT\\jY_j^akbcknimzonvp|sqRvRvRvRvRw햻햻햻헻헻헻헻헻헻헻헻TxTyTyUyUyUyUyUyUyUyUyUzUzVzZ~ZZ____````````aaaaaaaab\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\딹QuQuQuQuQuQuQuQuQuQuQuKWiKWiKWiKWiKWiMXiQ[jV]jZ_k_akbclumntp|trRvRvRwRwRwSwSw헻헻헻헻헻헻TyTyUyUyUyUyUyUyUyUyUzUzVzVzVzVzVz[````````aaaaaaabbb\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\QuQuQuQuQuQuQuQuQuQuQuQvKWiKWiKXiKXiKXiKXiNYjS\\jW^k\\`k_bkqkm~ro{vRwRwRwRwSwSwSwSwSw헻헻헻TyTyUyUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVz[````aaaaaaabbbbb\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\QuQuQuQuQuQuQvQvQvQvKXiKXiKXiKXiKXiKXiLXiPZjT]jY_k]akmim{pozuRwSwSwSwSwSwSwSwSwSwSwTyUyUyUyUyUyUyUyUyUzUzVzVzVzVzVzVzVzV{V{W{W{[[[[aaaaaaabbbbbb\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\QvQvQvQvQvRvRvRvKXiKXiKXiKXiKXiKXiLXjMYjQ[jV]kZ`kigmwnn|sSwSwSwSwSwSwSwSwSwSxSxSxTxUyUyUyUyUyUyUyUyUzUzVzVzVzVzVzVzVzVzV{V{W{W{W{W{W{[[[[\\\\\\aaabbbbbbb\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\RvRvRvRvRvRvRvRvKXiKXiLXjLXjLXjLXjLXjOZjS\\kW^kigmtpsSwSwSwSwSwSwSwSwSxSxSxTxTxTxTxUyUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVzV{V{W{W{W{W{W{W{W{W|W|[[[[\\\\\\\\\\\\bbbbbbbc\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\RvRvRvRvRvRvRvLXjLXjLXjLXjLXjMYjR[kW^k]alrosSwSwSwSwSwSwSwSxSxSxTxTxTxTxTxTxTxTxUyUyUyUyUyUyUzUzUzVzVzVzVzVzVzVzV{V{W{W{W{W{W{W{W{W|W|X|X|X|[[[[\\\\\\\\\\\\\\]]bbbcc\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\RvRvRvRvRvRwRwLYjLYjLYjLYjT]kZ_lhfmuqSwSwSwSwSwSwSxSxSxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUzUzVzVzVzVzVzVzVzVzV{V{W{W{W{W{W{W{W{W|W|X|X|X|X|X|X|[[[\\\\\\\\\\\\\\]]]]]]cc\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\RwRwRwRwSwSwSwddmaclupr{SwSwSwSwSwSxSxSxSxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyUzUzVzVzVzVzVzVzVzVzV{V{W{W{W{W{W{W{W{W|W|X|X|X|X|X|X|X|X}Y}Y}[[[\\\\\\\\\\\\\\]]]]]]]^^\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SwSwSwSwSwSwSwSwSwSwSwSwSwSxSxSxTxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUzUzVzVzVzVzVzVzVzVzV{V{W{W{W{W{W{W{W{W|W|X|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}[[[\\\\\\\\\\\\\\]]]]]]]^^^^^\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SwSwSwSwSwSwSwSwSxSxSxTxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyVzVzVzVzVzVzVzVzV{V{W{W{W{W{W{W{W{W{W|W|X|X|X|X|X|X|X|X}Y}Y}Y}Y}Y}Y}Y}Y~Y~[\\\\\\\\\\\\\\]]]]]]]^^^^^^^__\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SwSwSwSxSxSxSxTxTxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyVzVzVzVzVzV{V{V{W{W{W{W{W{W{W{W|W|X|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~[\\\\\\\\\\\\\\]]]]]]]^^^^^^^____\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\SxSxTxTxTxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyUyUyVzV{V{V{W{W{W{W{W{W{W{W|W|X|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~[\\\\\\\\\\\\\\]]]]]]]^^^^^^_______`\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\TxTxTxTxTxTxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyUyUyUyUzW{W{W{W{W{W{W{W|W|W|X|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~ZZ[[\\\\\\\\\\\\\\]]]]]]]^^^^^^^_______````\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\TxTxTxTxTxTyTyTyUyUyUyUyUyUyUyUyUyUyUyUzUzUzW{W{W{W{W{W|W|X|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y}Y~Z~Z~Z~Z~Z~Z~Z~Z[[[[[[\\\\\\\\\\\\\\]]]]]]]^^^^^^^______```````a\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\TxTyTyTyUyUyUyUyUyUyUyUyUyUyUyUyUzUzVzVzW{W|W|X|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[\\\\\\\\\\\\\\\\]]]]]]]^^^^^^_______``````aaaaa\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\UyUyUyUyUyUyUyUyUyUyUyUzUzUzVzVzVzX|X|X|X|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~Z~Z[[[[[[[[\\\\\\\\]]]]]]]^^^^^^^_______``````aaaaaabb\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\UyUyUyUyUyUyUyUzUzUzVzVzVzVzX|X|X|X|X}X}Y}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[\\\\]]]]]]]^^^^^^^______```````aaaaaabbbbb\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\UyUyUzUzUzVzVzVzVzVzVzX}X}Y}Y}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[\\\\\\]]]]^^^^^^_______``````aaaaaaabbbbbbcc\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\UzVzVzVzVzVzVzVzVzY}Y}Y}Y}Y}Y}Y~Y~Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[\\\\\\^^^^^^^_______``````aaaaaabbbbbbbccccc\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\VzVzVzVzVzVzY}Y}Y~Y~Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[\\\\\\\\^^^^^______```````aaaaaabbbbbbcccccccd\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\VzVzVzV{Z~Z~Z~Z~Z~Z~Z~ZZ[[[[[[[[\\\\\\\\\\^_______``````aaaaaaabbbbbbccccccddddd\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\V{Z~Z~Z~Z~ZZ[[[[[[[[[\\\\\\\\\\_____``````aaaaaabbbbbbbccccccddddddee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\Z~ZZ[[[[[[[[\\\\\\\\\\\\_```````aaaaaabbbbbbcccccccddddddee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\[[[[[[[\\\\\\\\\\\\\\`````aaaaaaabbbbbbccccccddddddeeee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\[[[[[\\\\\\\\\\\\\\\\``aaaaaaabbbbbbccccccddddddeeee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\[\\\\\\\\\\\\\\\\]aaaaabbbbbbbccccccddddddeeee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\\\\\\\\\\]]aabbbbbbccccccddddddeeeeee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\\\\]]]bbbbbbccccccddddddeeeeee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\]]bbbccccccddddddeeeeee\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\]ccccccddddddeeeeeef\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\]]]ccddddddeeeeeeff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\]]^^^^dddddeeeeeeff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\^^^^^^^dddeeeeeefff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\^^^^^^^^__eeeeeffff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\^^^^^^^______eeffff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\^^^^^^________`ffff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\^^^^^________`````ff\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\\u0013\\"
  },
  {
    "path": "ext/tk/sample/irbtk.rb",
    "content": "#!/usr/local/bin/ruby\n#\n#   irbtk.rb - irb with Ruby/Tk\n#\n#   If you want to use 'multi-tk.rb', give option '--multi-tk'.\n#   And if you want to use 'remote-tk.rb', give option '--remote-tk'.\n#   If you want both, you don't need to give both options, because \n#   'remote-tk.rb' includes 'multi-tk.rb'. \n#   ( There is no trouble even if you give both options. )\n#\nrequire 'remote-tk' if ARGV.delete('--remote-tk')\nrequire 'multi-tk'  if ARGV.delete('--multi-tk')\n\nrequire \"tk\"\nmodule Tk\n  MAINLOOP = Thread.new{ mainloop }\nend\n\nrequire \"irb\"\n\nif __FILE__ == $0\n  IRB.start(__FILE__)\nelse\n  # check -e option\n  if /^-e$/ =~ $0\n    IRB.start(__FILE__)\n  else\n    IRB.setup(__FILE__)\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/irbtkw.rbw",
    "content": "#!/usr/bin/env ruby\n#\n#  irbtkw.rb : IRB console with Ruby/Tk\n#\n#                                 by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrelease = '2008/03/08'\n\nrequire 'tk'\nbegin\n  require 'tktextio'\nrescue LoadError\n  require File.join(File.dirname(File.expand_path(__FILE__)), 'tktextio.rb')\nend\n\nrequire 'irb'\n\nif TkCore::WITH_ENCODING\nelse\n  # $KCODE setup\n  case Tk.encoding\n  when 'shiftjis', 'cp932'\n    $KCODE='SJIS'\n  when 'euc-jp'\n    $KCODE='EUC'\n  when 'utf-8', 'unicode'\n    $KCODE='UTF8'\n  else\n    # unknown\n  end\nend\n\n# console setup\ntop = TkToplevel.new(:title=>'IRB console')\ntop.protocol(:WM_DELETE_WINDOW){ Tk.exit }\n\ncase (Tk.windowingsystem)\nwhen 'win32'\n  fnt = ['MS Gothic', '-12']\nelse\n  fnt = ['courier', '-12']\nend\n\nconsole = TkTextIO.new(top, :mode=>:console, \n                       :width=>80).pack(:side=>:left, \n                                        :expand=>true, :fill=>:both)\nconsole.yscrollbar(TkScrollbar.new(top, :width=>10).pack(:before=>console, \n                                                         :side=>:right, \n                                                         :expand=>false, \n                                                         :fill=>:y))\nirb_thread = nil\nev_loop = Thread.new{\n  Tk.mainloop\n  irb_thread.kill if irb_thread\n}\n\n# window position control\nroot = Tk.root\n\nr_x = root.winfo_rootx\nr_y = root.winfo_rooty\nr_w = root.winfo_width\n\nt_x = top.winfo_rootx\nt_y = top.winfo_rooty\nt_w = top.winfo_width\n\ndelta = 10\n\nratio = 0.8\ns_w = (ratio * root.winfo_screenwidth).to_i\n\nif r_x < t_x\n  r_x, t_x = t_x, r_x\nend\nif t_x + t_w + r_w + delta < s_w\n  r_x = t_x + t_w + delta\nelsif t_w + r_w + delta < s_w\n  r_x = s_w - r_w\n  t_x = r_x - t_w\nelse\n  r_x = s_w - r_w\n  t_x = 0\nend\n\nroot.geometry(\"+#{r_x}+#{r_y}\")\ntop.geometry(\"+#{t_x}+#{t_y}\")\n\nroot.raise\nconsole.focus\n\n# I/O setup\n$stdin  = console\n$stdout = console\n$stderr = console\n\n# dummy for rubyw.exe on Windows\ndef STDIN.tty?\n  true\nend\n\n# IRB setup\nIRB.init_config(nil)\nIRB.conf[:USE_READLINE] = false\nIRB.init_error\nirb = IRB::Irb.new\nIRB.conf[:MAIN_CONTEXT] = irb.context\n\nclass IRB::StdioInputMethod\n  def gets\n    prompt = \"\\n\" << @prompt\n    $stdin.instance_eval{\n      flush\n      @prompt = prompt\n      _set_console_line\n      @prompt = nil\n      _see_pos\n    }\n\n    @line[@line_no += 1] = $stdin.gets\n  end\nend\n\n# IRB start\n$stdout.print(\"*** IRB console on Ruby/Tk (#{release})  \")\nirb_thread = Thread.new{\n  catch(:IRB_EXIT){\n    loop {\n      begin\n        irb.eval_input\n      rescue Exception\n      end\n    }\n  }\n}\n\nconsole.bind('Control-c'){\n  console.insert('end', \"^C\\n\")\n  irb_thread.raise RubyLex::TerminateLineInput\n}\n\nirb_thread.join\n\n# exit\nev_thread.kill\nTk.exit\n"
  },
  {
    "path": "ext/tk/sample/iso2022-kr.txt",
    "content": "Sample text:\n\u001b$)C  Hangul (\u000eGQ1[\u000f)\t\u000e>H3gGO<<?d\u000f, \u000e>H3gGO=J4O1n\u000f\n"
  },
  {
    "path": "ext/tk/sample/menubar1.rb",
    "content": "#\n# menubar sample 1 : use frame and menubuttons\n#\n\nrequire 'tk'\n\nradio_var = TkVariable.new('y')\n\nmenu_spec = [\n  [['File', 0],\n    {:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0},\n    '---',\n    ['Check_A', TkVariable.new(true), 6],\n    {:type=>'checkbutton', :label=>'Check_B', \n                :variable=>TkVariable.new, :underline=>6},\n    '---',\n    ['Radio_X', [radio_var, 'x'], 6, '', {:foreground=>'black'}],\n    ['Radio_Y', [radio_var, 'y'], 6],\n    ['Radio_Z', [radio_var, 'z'], 6],\n    '---',\n    ['cascade', [ \n                   ['sss', proc{p 'sss'}, 0], \n                   ['ttt', proc{p 'ttt'}, 0], \n                   ['uuu', proc{p 'uuu'}, 0], \n                   ['vvv', proc{p 'vvv'}, 0], \n                ], \n      0, '', \n      {:font=>'Courier 16 italic', \n       :menu_config=>{:font=>'Times -18 bold', :foreground=>'black'}}],\n    '---',\n    ['Quit', proc{exit}, 0]],\n\n  [['Edit', 0],\n    ['Cut', proc{puts('Cut clicked')}, 2],\n    ['Copy', proc{puts('Copy clicked')}, 0],\n    ['Paste', proc{puts('Paste clicked')}, 0]], \n\n  [['Help', 0, {:menu_name=>'help'}],\n    ['About This', proc{puts('Ruby/Tk menubar sample 1')}, 6]]\n]\n\nmenubar = TkMenubar.new(nil, menu_spec,\n                       'tearoff'=>false,\n                       'foreground'=>'grey40',\n                       'activeforeground'=>'red',\n                       'font'=>'Helvetia 12 bold')\nmenubar.pack('side'=>'top', 'fill'=>'x')\n\nTkText.new(:wrap=>'word').pack.insert('1.0', 'Please read the sample source, and check how to override default configure options of menu entries on a menu_spec. Maybe, on windows, this menubar does not work properly about keyboard shortcuts. Then, please use \"menu\" option of root/toplevel widget (see sample/menubar2.rb).')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/menubar2.rb",
    "content": "#\n# menubar sample 2 : use 'menu' option of root/toplevel widget\n#\n\nrequire 'tk'\n\nradio_var = TkVariable.new('y')\n\nmenu_spec = [\n  [['File', 0],\n    {:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0},\n    '---',\n    ['Check_A', TkVariable.new(true), 6],\n    {:type=>'checkbutton', :label=>'Check_B', \n                :variable=>TkVariable.new, :underline=>6},\n    '---',\n    ['Radio_X', [radio_var, 'x'], 6, '', {:foreground=>'black'}],\n    ['Radio_Y', [radio_var, 'y'], 6],\n    ['Radio_Z', [radio_var, 'z'], 6],\n    '---',\n    ['cascade', [ \n                   ['sss', proc{p 'sss'}, 0], \n                   ['ttt', proc{p 'ttt'}, 0], \n                   ['uuu', proc{p 'uuu'}, 0], \n                   ['vvv', proc{p 'vvv'}, 0], \n                ], \n      0, '', \n      {:font=>'Courier 16 italic', \n       :menu_config=>{:font=>'Times -18 bold', :foreground=>'black'}}],\n    '---',\n    ['Quit', proc{exit}, 0]],\n\n  [['Edit', 0],\n    ['Cut', proc{puts('Cut clicked')}, 2],\n    ['Copy', proc{puts('Copy clicked')}, 0],\n    ['Paste', proc{puts('Paste clicked')}, 0]], \n\n  [['Help', 0, {:menu_name=>'help'}],\n    ['About This', proc{puts('Ruby/Tk menubar sample 2')}, 6]]\n]\n\nmbar = Tk.root.add_menubar(menu_spec, \n                           # followings are default configure options\n                           'tearoff'=>'false',\n                           'foreground'=>'grey40', \n                           'activeforeground'=>'red',\n                           'font'=>'Helvetia 12 bold')\n# This (default configure options) is NOT same the following.\n#\n#  mbar = Tk.root.add_menubar(menu_spec)\n#  mbar.configure('foreground'=>'grey40', 'activeforeground'=>'red',\n#                 'font'=>'Helvetia 12 bold')\n\nTkText.new(:wrap=>'word').pack.insert('1.0', 'Please read the sample source, and check how to override default configure options of menu entries on a menu_spec.')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/README",
    "content": "Message catalogs in this directory depend on Tcl/Tk's message catalogs. \nTexts of each locale are copied from Tcl/Tk8.5a1 widget demos.\nPlease refer '../msgs_tk/README'. \n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/cs.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    cs \"Application Error\", \"Chyba programu\"\n    cs \"Blue\", \"Modr\\341\"\n    cs \"Color\", \"Barva\"\n    cs \"Delete\", \"Smazat\"\n    cs \"Error\", \"Chyba\"\n    cs \"Exit\", \"Konec\"\n    cs \"Green\", \"Zelen\\341\"\n    cs \"Red\", \"\\\\u010cerven\\341\"\n    cs \"blue\", \"modr\\341\"\n    cs \"green\", \"zelen\\341\"\n    cs \"red\", \"\\\\u010derven\\341\"\n}\n\nTkMsgCatalog.new('::tk') {\n    cs \"&Abort\", \"&P\\\\u0159eru\\\\u0161it\"\n    cs \"About...\", \"O programu...\"\n    cs \"All Files\", \"V\\\\u0161echny soubory\"\n    cs \"Application Error\", \"Chyba programu\"\n    cs \"&Blue\", \"&Modr\\341\"\n    cs \"&Cancel\", \"&Zru\\\\u0161it\"\n    cs \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"Nemohu zm\\\\u011bnit atku\\341ln\\355 adres\\341\\\\u0159 na \\\"%1\\$s\\\".\\nP\\\\u0159\\355stup odm\\355tnut.\"\n    cs \"Choose Directory\", \"V\\375b\\\\u011br adres\\341\\\\u0159e\"\n    cs \"Clear\", \"Smazat\"\n    cs \"Color\", \"Barva\"\n    cs \"Console\", \"Konzole\"\n    cs \"Copy\", \"Kop\\355rovat\"\n    cs \"Cut\", \"Vy\\\\u0159\\355znout\"\n    cs \"Delete\", \"Smazat\"\n    cs \"Details >>\", \"Detaily >>\"\n    cs \"Directory \\\"%1\\$s\\\" does not exist.\", \"Adres\\341\\\\u0159 \\\"%1\\$s\\\" neexistuje.\"\n    cs \"&Directory:\", \"&Adres\\341\\\\u0159:\"\n    cs \"Error: %1\\$s\", \"Chyba: %1\\$s\"\n    cs \"Exit\", \"Konec\"\n    cs \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"Soubor \\\"%1\\$s\\\" ji\\\\u017e existuje.\\n\\n\"\n    cs \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"Soubor \\\"%1\\$s\\\" ji\\\\u017e existuje.\\nChcete jej p\\\\u0159epsat?\"\n    cs \"File \\\"%1\\$s\\\" does not exist.\", \"Soubor \\\"%1\\$s\\\" neexistuje.\"\n    cs \"File &name:\", \"&Jm\\351no souboru:\"\n    cs \"File &names:\", \"&Jm\\351na soubor\\\\u016f:\"\n    cs \"Files of &type:\", \"&Typy soubor\\\\u016f:\"\n    cs \"Fi&les:\", \"Sou&bory:\"\n    cs \"&Filter\", \"&Filtr\"\n    cs \"Fil&ter:\", \"Fil&tr:\"\n    cs \"&Green\", \"Ze&len\\341\"\n    cs \"Hi\"\n    cs \"Hide Console\", \"Skr\\375t konsolu\"\n    cs \"&Ignore\", \"&Ignorovat\"\n    cs \"Invalid file name \\\"%1\\$s\\\".\", \"\\\\u0160patn\\351 jm\\351no souboru \\\"%1\\$s\\\".\"\n    cs \"Log Files\", \"Log soubory\"\n    cs \"&No\", \"&Ne\"\n    cs \"&OK\"\n    cs \"Ok\"\n    cs \"Open\", \"Otev\\\\u0159\\355t\"\n    cs \"&Open\", \"&Otev\\\\u0159\\355t\"\n    cs \"Open Multiple Files\", \"Otev\\\\u0159\\355t v\\355ce soubor\\\\u016f\"\n    cs \"Paste\", \"Vlo\\\\u017eit\"\n    cs \"Quit\", \"Skon\\\\u010dit\"\n    cs \"&Red\", \" \\\\u010ce&rven\\341\"\n    cs \"Replace existing file?\", \"Nahradit st\\341vaj\\355c\\355 soubor?\"\n    cs \"&Retry\", \"Z&novu\"\n    cs \"&Save\", \"&Ulo\\\\u017eit\"\n    cs \"Save As\", \"Ulo\\\\u017eit jako\"\n    cs \"Save To Log\", \"Ulo\\\\u017eit do logu\"\n    cs \"Select Log File\", \"Vybrat log soubor\"\n    cs \"Select a file to source\", \"Vybrat soubor k nahr\\341n\\355\"\n    cs \"&Selection:\", \"&V\\375b\\\\u011br:\"\n    cs \"Skip Messages\", \"P\\\\u0159esko\\\\u010dit zpr\\341vy\"\n    cs \"Source...\", \"Nahr\\341t...\"\n    cs \"Tcl Scripts\", \"Tcl skripty\"\n    cs \"Tcl for Windows\", \"Tcl pro Windows\"\n    cs \"Text Files\", \"Textov\\351 soubory\"\n    cs \"&Yes\", \"&Ano\"\n    cs \"abort\", \"p\\\\u0159eru\\\\u0161it\"\n    cs \"blue\", \"modr\\341\"\n    cs \"cancel\", \"zru\\\\u0161it\"\n    cs \"extension\", \"p\\\\u0159\\355pona\"\n    cs \"extensions\", \"p\\\\u0159\\355pony\"\n    cs \"green\", \"zelen\\341\"\n    cs \"ignore\", \"ignorovat\"\n    cs \"ok\"\n    cs \"red\", \"\\\\u010derven\\341\"\n    cs \"retry\", \"znovu\"\n    cs \"yes\", \"ano\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/de.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    de \"Application Error\", \"Applikationsfehler\"\n    de \"Blue\", \"Blau\"\n    de \"Color\", \"Farbe\"\n    de \"Delete\", \"L\\\\u00f6schen\"\n    de \"Error\", \"Fehler\"\n    de \"Exit\", \"Ende\"\n    de \"Green\", \"Gr\\\\u00fcn\"\n    de \"Red\", \"Rot\"\n    de \"blue\", \"blau\"\n    de \"green\", \"gr\\\\u00fcn\"\n    de \"red\", \"rot\"\n}\n\nTkMsgCatalog.new('::tk') {\n    de \"&Abort\", \"&Abbruch\"\n    de \"&About...\", \"&\\\\u00dcber...\"\n    de \"All Files\", \"Alle Dateien\"\n    de \"Application Error\", \"Applikationsfehler\"\n    de \"&Blue\", \"&Blau\"\n    de \"&Cancel\", \"&Abbruch\"\n    de \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"Kann nicht in das Verzeichnis \\\"%1\\$s\\\" wechseln.\\nKeine Rechte vorhanden.\"\n    de \"Choose Directory\", \"W\\\\u00e4hle Verzeichnis\"\n    de \"&Clear\", \"&R\\\\u00fccksetzen\"\n    de \"&Clear Console\", \"&Konsole l\\\\u00f6schen\"\n    de \"Color\", \"Farbe\"\n    de \"Console\", \"Konsole\"\n    de \"&Copy\", \"&Kopieren\"\n    de \"Cu&t\", \"Aus&schneiden\"\n    de \"&Delete\", \"&L\\\\u00f6schen\"\n    de \"Details >>\"\n    de \"Directory \\\"%1\\$s\\\" does not exist.\", \"Das Verzeichnis \\\"%1\\$s\\\" existiert nicht.\"\n    de \"&Directory:\", \"&Verzeichnis:\"\n    de \"&Edit\", \"&Bearbieten\"\n    de \"Error: %1\\$s\", \"Fehler: %1\\$s\"\n    de \"E&xit\", \"&Ende\"\n    de \"&File\", \"&Datei\"\n    de \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"Die Datei \\\"%1\\$s\\\" ist bereits vorhanden.\\nWollen sie diese Datei \\\\u00fcberschreiben ?\"\n    de \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"Die Datei \\\"%1\\$s\\\" ist bereits vorhanden.\\n\\n\"\n    de \"File \\\"%1\\$s\\\" does not exist.\", \"Die Datei \\\"%1\\$s\\\" existiert nicht.\"\n    de \"File &name:\", \"Datei&name:\"\n    de \"File &names:\", \"Datei&namen:\"\n    de \"Files of &type:\", \"Dateien des &Typs:\"\n    de \"Fi&les:\", \"Dat&eien:\"\n    de \"&Filter\"\n    de \"Fil&ter:\"\n    de \"&Green\", \"&Gr\\\\u00fcn\"\n    de \"&Help\", \"&Hilfe\"\n    de \"Hi\", \"Hallo\"\n    de \"&Hide Console\", \"&Konsole unsichtbar machen\"\n    de \"&Ignore\", \"&Ignorieren\"\n    de \"Invalid file name \\\"%1\\$s\\\".\", \"Ung\\\\u00fcltiger Dateiname \\\"%1\\$s\\\".\"\n    de \"Log Files\", \"Protokolldatei\"\n    de \"&No\", \"&Nein\"\n    de \"OK\"\n    de \"Ok\"\n    de \"Open\", \"\\\\u00d6ffnen\"\n    de \"&Open\", \"\\\\u00d6&ffnen\"\n    de \"Open Multiple Files\"\n    de \"P&aste\", \"E&inf\\\\u00fcgen\"\n    de \"&Quit\", \"&Beenden\"\n    de \"&Red\", \"&Rot\"\n    de \"Replace existing file?\", \"Existierende Datei ersetzen?\"\n    de \"&Retry\", \"&Wiederholen\"\n    de \"&Save\", \"&Speichern\"\n    de \"Save As\", \"Speichern unter\"\n    de \"Save To Log\", \"In Protokoll speichern\"\n    de \"Select Log File\", \"Protokolldatei ausw\\\\u00e4hlen\"\n    de \"Select a file to source\", \"Auszuf\\\\u00fchrende Datei ausw\\\\u00e4hlen\"\n    de \"&Selection:\", \"Auswah&l:\"\n    de \"Skip Messages\", \"Weitere Nachrichten \\\\u00fcberspringen\"\n    de \"&Source...\", \"&Ausf\\\\u00fchren...\"\n    de \"Tcl Scripts\", \"Tcl-Skripte\"\n    de \"Tcl for Windows\", \"Tcl f\\\\u00fcr Windows\"\n    de \"Text Files\", \"Textdateien\"\n    de \"&Yes\", \"&Ja\"\n    de \"abort\", \"abbrechen\"\n    de \"blue\", \"blau\"\n    de \"cancel\", \"abbrechen\"\n    de \"extension\", \"Erweiterung\"\n    de \"extensions\", \"Erweiterungen\"\n    de \"green\", \"gr\\\\u00fcn\"\n    de \"ignore\", \"ignorieren\"\n    de \"ok\"\n    de \"red\", \"rot\"\n    de \"retry\", \"wiederholen\"\n    de \"yes\", \"ja\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/el.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    el 'Application Error',  '\\u039b\\u03ac\\u03b8\\u03bf\\u03c2 \\u0395\\u03c6\\u03b1\\u03c1\\u03bc\\u03bf\\u03b3\\u03ae\\u03c2'\n    el 'Blue',     '\\u039c\\u03c0\\u03bb\\u03b5'\n    el 'Color',    '\\u03a7\\u03c1\\u03ce\\u03bc\\u03b1'\n    el 'Delete',   '\\u0394\\u03b9\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae'\n    el 'Error',    '\\u039b\\u03ac\\u03b8\\u03bf\\u03c2'\n    el 'Exit',     '\\u0388\\u03be\\u03bf\\u03b4\\u03bf\\u03c2'\n    el 'Green',    '\\u03a0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf'\n    el 'Red',      '\\u039a\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf'\n    el 'blue',     '\\u03bc\\u03c0\\u03bb\\u03b5'\n    el 'green',    '\\u03c0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf'\n    el 'red',      '\\u03ba\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf'\n}\n\nTkMsgCatalog.new('::tk') {\n    el '&Abort',             '\\u03a4\\u03b5\\u03c1\\u03bc\\u03b1\\u03c4\\u03b9\\u03c3\\u03bc\\u03cc\\u03c2'\n    el 'About...',           '\\u03a3\\u03c7\\u03b5\\u03c4\\u03b9\\u03ba\\u03ac...'\n    el 'All Files',          '\\u038c\\u03bb\\u03b1 \\u03c4\\u03b1 \\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1'\n    el 'Application Error',  '\\u039b\\u03ac\\u03b8\\u03bf\\u03c2 \\u0395\\u03c6\\u03b1\\u03c1\\u03bc\\u03bf\\u03b3\\u03ae\\u03c2'\n    el '&Blue',              '\\u039c\\u03c0\\u03bb\\u03b5'\n    el '&Cancel',            '\\u0391\\u03ba\\u03cd\\u03c1\\u03c9\\u03c3\\u03b7'\n    el 'Cannot change to the directory \"%1\\$s\".' \"\\n\" 'Permission denied.', \\\n          '\\u0394\\u03b5\\u03bd \\u03b5\\u03af\\u03bd\\u03b1\\u03b9 \\u03b4\\u03c5\\u03bd\\u03b1\\u03c4\\u03ae \\u03b7 \\u03b1\\u03bb\\u03bb\\u03b1\\u03b3\\u03ae \\u03ba\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5 \\u03c3\\u03b5 \"%1\\$s\".' \\\n          \"\\n\" \\\n          '\\u0397 \\u03c0\\u03c1\\u03cc\\u03c3\\u03b2\\u03b1\\u03c3\\u03b7 \\u03b4\\u03b5\\u03bd \\u03b5\\u03c0\\u03b9\\u03c4\\u03c1\\u03ad\\u03c0\\u03b5\\u03c4\\u03b1\\u03b9.'\n    el 'Choose Directory',   '\\u0395\\u03c0\\u03b9\\u03bb\\u03bf\\u03b3\\u03ae \\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5'\n    el 'Clear',              '\\u039a\\u03b1\\u03b8\\u03b1\\u03c1\\u03b9\\u03c3\\u03bc\\u03cc\\u03c2'\n    el 'Color',              '\\u03a7\\u03c1\\u03ce\\u03bc\\u03b1'\n    el 'Console',            '\\u039a\\u03bf\\u03bd\\u03c3\\u03cc\\u03bb\\u03b1'\n    el 'Copy',               '\\u0391\\u03bd\\u03c4\\u03b9\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae'\n    el 'Cut',                '\\u0391\\u03c0\\u03bf\\u03ba\\u03bf\\u03c0\\u03ae'\n    el 'Delete',             '\\u0394\\u03b9\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae'\n    el 'Details >>',         '\\u039b\\u03b5\\u03c0\\u03c4\\u03bf\\u03bc\\u03ad\\u03c1\\u03b5\\u03b9\\u03b5\\u03c2 >>'\n    el 'Directory \"%1\\$s\", does not exist.', \\\n          '\\u039f \\u03ba\\u03b1\\u03c4\\u03ac\\u03bb\\u03bf\\u03b3\\u03bf\\u03c2 \\'%1\\$s\\' \\u03b4\\u03b5\\u03bd \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.'\n    el '&Directory:',        '&\\u039a\\u03b1\\u03c4\\u03ac\\u03bb\\u03bf\\u03b3\\u03bf\\u03c2:'\n    el 'Error: %1\\$s',       '\\u039b\\u03ac\\u03b8\\u03bf\\u03c2: %1\\$s'\n    el 'Exit',               '\\u0388\\u03be\\u03bf\\u03b4\\u03bf\\u03c2'\n    el 'File \"%1\\$s\" already exists.' \"\\n\" 'Do you want to overwrite it?', \\\n          '\\u03a4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \"%1\\$s\" \\u03ae\\u03b4\\u03b7 \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.' \\\n          \"\\n\" \\\n          '\\u0398\\u03ad\\u03bb\\u03b5\\u03c4\\u03b5 \\u03bd\\u03b1 \\u03b5\\u03c0\\u03b9\\u03ba\\u03b1\\u03bb\\u03c5\\u03c6\\u03b8\\u03b5\\u03af;'\n    el 'File \"%1\\$s\" already exists.' \"\\n\\n\",  \\\n          '\\u03a4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \"%1\\$s\" \\u03ae\\u03b4\\u03b7 \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.' \"\\n\\n\"\n    el 'File \"%1\\$s\" does not exist.', \\\n          '\\u03a4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \"%1\\$s\" \\u03b4\\u03b5\\u03bd \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.'\n    el 'File &name:',        '\\u038c&\\u03bd\\u03bf\\u03bc\\u03b1 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5:'\n    el 'File &names:',       '\\u038c&\\u03bd\\u03bf\\u03bc\\u03b1 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03c9\\u03bd:'\n    el 'Files of &type:',    '\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1 \\u03c4\\u03bf\\u03c5 &\\u03c4\\u03cd\\u03c0\\u03bf\\u03c5:'\n    el 'Fi&les:',            '\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1:'\n    el '&Filter',            '\\u03a6\\u03af\\u03bb\\u03c4\\u03c1\\u03bf'\n    el 'Fil&ter:',           '\\u03a6\\u03af\\u03bb\\u03c4\\u03c1\\u03bf:'\n    el '&Green',             '\\u03a0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf'\n    el 'Hi',                 '\\u0393\\u03b5\\u03b9\\u03b1'\n    el 'Hide Console',       '\\u0391\\u03c0\\u03cc\\u03ba\\u03c1\\u03c5\\u03c8\\u03b7 \\u03ba\\u03bf\\u03bd\\u03c3\\u03cc\\u03bb\\u03b1\\u03c2'\n    el '&Ignore',            '\\u0391\\u03b3\\u03bd\\u03cc\\u03b7\\u03c3\\u03b7'\n    el 'Invalid file name \"%1\\$s\".', \\\n          '\\u0386\\u03ba\\u03c5\\u03c1\\u03bf \\u03cc\\u03bd\\u03bf\\u03bc\\u03b1 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5 \"%1\\$s\".'\n    el 'Log Files',          '\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1 \\u039a\\u03b1\\u03c4\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\\u03c2'\n    el '&No',                '\\u038c\\u03c7\\u03b9'\n    el '&OK',                '\\u0395\\u03bd\\u03c4\\u03ac\\u03be\\u03b5\\u03b9'\n    el '&Ok',                '\\u0395\\u03bd\\u03c4\\u03ac\\u03be\\u03b5\\u03b9'\n    el 'Open',               '\\u0386\\u03bd\\u03bf\\u03b9\\u03b3\\u03bc\\u03b1'\n    el '&Open',              '\\u0386\\u03bd\\u03bf\\u03b9\\u03b3\\u03bc\\u03b1'\n    el 'Open Multiple Files', \\\n          '\\u0386\\u03bd\\u03bf\\u03b9\\u03b3\\u03bc\\u03b1 \\u03c0\\u03bf\\u03bb\\u03bb\\u03b1\\u03c0\\u03bb\\u03ce\\u03bd \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03c9\\u03bd'\n    el 'Paste',              '\\u0395\\u03c0\\u03b9\\u03ba\\u03cc\\u03bb\\u03bb\\u03b7\\u03c3\\u03b7'\n    el 'Quit',               '\\u0388\\u03be\\u03bf\\u03b4\\u03bf\\u03c2'\n    el '&Red',               '\\u039a\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf'\n    el 'Replace existing file?', \\\n          '\\u0395\\u03c0\\u03b9\\u03ba\\u03ac\\u03bb\\u03c5\\u03c8\\u03b7 \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03bf\\u03bd\\u03c4\\u03bf\\u03c2 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5;'\n    el '&Retry',             '\\u03a0\\u03c1\\u03bf\\u03c3\\u03c0\\u03ac\\u03b8\\u03b7\\u03c3\\u03b5 \\u03be\\u03b1\\u03bd\\u03ac'\n    el '&Save',              '\\u0391\\u03c0\\u03bf\\u03b8\\u03ae\\u03ba\\u03b5\\u03c5\\u03c3\\u03b7'\n    el 'Save As',            '\\u0391\\u03c0\\u03bf\\u03b8\\u03ae\\u03ba\\u03b5\\u03c5\\u03c3\\u03b7 \\u03c3\\u03b1\\u03bd'\n    el 'Save To Log',        '\\u0391\\u03c0\\u03bf\\u03b8\\u03ae\\u03ba\\u03b5\\u03c5\\u03c3\\u03b7 \\u03c3\\u03c4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\u03ba\\u03b1\\u03c4\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\\u03c2'\n    el 'Select Log File',    '\\u0395\\u03c0\\u03b9\\u03bb\\u03bf\\u03b3\\u03ae \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5 \\u03ba\\u03b1\\u03c4\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\\u03c2'\n    el 'Select a file to source', \\\n          '\\u0395\\u03c0\\u03b9\\u03bb\\u03ad\\u03be\\u03c4\\u03b5 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\u03b3\\u03b9\\u03b1 \\u03b5\\u03ba\\u03c4\\u03ad\\u03bb\\u03b5\\u03c3\\u03b7'\n    el '&Selection:',        '\\u0395\\u03c0\\u03b9\\u03bb\\u03bf\\u03b3\\u03ae:'\n    el 'Skip Messages',      '\\u0391\\u03c0\\u03bf\\u03c6\\u03c5\\u03b3\\u03ae \\u03bc\\u03c5\\u03bd\\u03b7\\u03bc\\u03ac\\u03c4\\u03c9\\u03bd'\n    el 'Source...',          '\\u0395\\u03ba\\u03c4\\u03ad\\u03bb\\u03b5\\u03c3\\u03b7...'\n    el 'Tcl Scripts',        'Tcl Scripts'\n    el 'Tcl for Windows',    'Tcl \\u03b3\\u03b9\\u03b1 Windows'\n    el 'Text Files',         '\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1 \\u039a\\u03b5\\u03b9\\u03bc\\u03ad\\u03bd\\u03bf\\u03c5'\n    el '&Yes',               '\\u039d\\u03b1\\u03b9'\n    el 'abort',              '\\u03c4\\u03b5\\u03c1\\u03bc\\u03b1\\u03c4\\u03b9\\u03c3\\u03bc\\u03cc\\u03c2'\n    el 'blue',               '\\u03bc\\u03c0\\u03bb\\u03b5'\n    el 'cancel',             '\\u03b1\\u03ba\\u03cd\\u03c1\\u03c9\\u03c3\\u03b7'\n    el 'extension',          '\\u03b5\\u03c0\\u03ad\\u03ba\\u03c4\\u03b1\\u03c3\\u03b7'\n    el 'extensions',         '\\u03b5\\u03c0\\u03b5\\u03ba\\u03c4\\u03ac\\u03c3\\u03b5\\u03b9\\u03c2'\n    el 'green',              '\\u03c0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf'\n    el 'ignore',             '\\u03b1\\u03b3\\u03bd\\u03cc\\u03b7\\u03c3\\u03b7'\n    el 'ok',                 '\\u03b5\\u03bd\\u03c4\\u03ac\\u03be\\u03b5\\u03b9'\n    el 'red',                '\\u03ba\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf'\n    el 'retry',              '\\u03c0\\u03c1\\u03bf\\u03c3\\u03c0\\u03ac\\u03b8\\u03b7\\u03c3\\u03b5 \\u03be\\u03b1\\u03bd\\u03ac'\n    el 'yes',                '\\u03bd\\u03b1\\u03b9'\n}\n\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/en.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    en \"Application Error\"\n    en \"Blue\"\n    en \"Color\"\n    en \"Delete\"\n    en \"Error\"\n    en \"Green\"\n    en \"Red\"\n    en \"blue\"\n    en \"green\"\n    en \"red\"\n}\n\nTkMsgCatalog.new('::tk') {\n    en \"&Abort\"\n    en \"About...\"\n    en \"All Files\"\n    en \"Application Error\"\n    en \"&Blue\"\n    en \"&Cancel\"\n    en \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\"\n    en \"Choose Directory\"\n    en \"Clear\"\n    en \"Color\"\n    en \"Console\"\n    en \"Copy\"\n    en \"Cut\"\n    en \"Delete\"\n    en \"Details >>\"\n    en \"Directory \\\"%1\\$s\\\" does not exist.\"\n    en \"&Directory:\"\n    en \"Error: %1\\$s\"\n    en \"Exit\"\n    en \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\"\n    en \"File \\\"%1\\$s\\\" already exists.\\n\\n\"\n    en \"File \\\"%1\\$s\\\" does not exist.\"\n    en \"File &name:\"\n    en \"File &names:\"\n    en \"Files of &type:\"\n    en \"Fi&les:\"\n    en \"&Filter\"\n    en \"Fil&ter:\"\n    en \"&Green\"\n    en \"Hi\"\n    en \"Hide Console\"\n    en \"&Ignore\"\n    en \"Invalid file name \\\"%1\\$s\\\".\"\n    en \"Log Files\"\n    en \"&No\"\n    en \"&OK\"\n    en \"Ok\"\n    en \"Open\"\n    en \"&Open\"\n    en \"Open Multiple Files\"\n    en \"Paste\"\n    en \"Quit\"\n    en \"&Red\"\n    en \"Replace existing file?\"\n    en \"&Retry\"\n    en \"&Save\"\n    en \"Save As\"\n    en \"Save To Log\"\n    en \"Select Log File\"\n    en \"Select a file to source\"\n    en \"&Selection:\"\n    en \"Skip Messages\"\n    en \"Source...\"\n    en \"Tcl Scripts\"\n    en \"Tcl for Windows\"\n    en \"Text Files\"\n    en \"&Yes\"\n    en \"abort\"\n    en \"blue\"\n    en \"cancel\"\n    en \"extension\"\n    en \"extensions\"\n    en \"green\"\n    en \"ignore\"\n    en \"ok\"\n    en \"red\"\n    en \"retry\"\n    en \"yes\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/en_gb.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    en_gb 'Color', 'Colour'\n}\n\nTkMsgCatalog.new('::tk') {\n    en_gb 'Color', 'Colour'\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/eo.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    eo 'Application Error', 'Aplikoerraro'\n    eo 'Blue', 'Blua'\n    eo 'Color', 'Farbo'\n    eo 'Delete', 'Forprenu'\n    eo 'Error', 'Eraro'\n    eo 'Exit', 'Eliru'\n    eo 'Green', 'Verda'\n    eo 'Red', 'Rosa'\n    eo 'blue', 'blua'\n    eo 'green', 'verda'\n    eo 'red', 'ru\\u011da'\n}\n\nTkMsgCatalog.new('::tk') {\n    eo '&Abort', '&\\u0108esigo'\n    eo '&About...', 'Pri...'\n    eo 'All Files', '\\u0108ioj dosieroj'\n    eo 'Application Error', 'Aplikoerraro'\n    eo '&Blue', '&Blua'\n    eo '&Cancel', '&Rezignu'\n    eo 'Cannot change to the directory \"%1\\$s\".' \"\\n\" 'Permission denied.', 'Neeble \\u0109angi al dosierulon \"%1\\$s\".' \"\\n\" 'Vi ne rajtas tion.'\n    eo 'Choose Directory', 'Elektu Dosierujo'\n    eo '&Clear', '&Klaru'\n    eo '&Clear Console', '&Klaru konzolon'\n    eo 'Color', 'Farbo'\n    eo 'Console', 'Konzolo'\n    eo '&Copy', '&Kopiu'\n    eo 'Cu&t', '&Enpo\\u015digu'\n    eo '&Delete', '&Forprenu'\n    eo 'Details >>', 'Detaloj >>'\n    eo 'Directory \"%1\\$s\" does not exist.', 'La dosierujo \"%1\\$s\" ne ekzistas.'\n    eo '&Directory:', '&Dosierujo:'\n    eo '&Edit', '&Redaktu'\n    eo 'Error: %1\\$s', 'Eraro: %1\\$s'\n    eo 'E&xit', '&Eliru'\n    eo '&File', '&Dosiero'\n    eo 'File \"%1\\$s\" already exists.' \"\\n\" 'Do you want to overwrite it?', 'La dosiero \"%1\\$s\" jam ekzistas.' \"\\n\" '\\u0108u vi volas anstata\\u00fbigi la dosieron?'\n    eo 'File \"%1\\$s\" already exists.' \"\\n\\n\", 'La dosiero \"%1\\$s\" jam egzistas.' \"\\n\\n\"\n    eo 'File \"%1\\$s\" does not exist.', 'La dosierp \"%1\\$s\" ne estas.'\n    eo 'File &name:', 'Dosiero&nomo:'\n    eo 'File &names:', 'Dosiero&nomoj:'\n    eo 'Files of &type:', 'Dosieroj de &Typo:'\n    eo 'Fi&les:', 'Do&sieroj:'\n    eo '&Filter', '&Filtrilo'\n    eo 'Fil&ter:', '&Filtrilo:'\n    eo '&Green', '&Verda'\n    eo '&Help', '&Helpu'\n    eo 'Hi', 'Saluton'\n    eo '&Hide Console', '&Ka\\u015du konzolon'\n    eo '&Ignore', '&Ignoru'\n    eo 'Invalid file name \"%1\\$s\".', 'Malvalida dosieronomo \"%1\\$s\".'\n    eo 'Log Files', 'Protokolo'\n    eo '&No', '&Ne'\n    eo 'OK'\n    eo 'Ok'\n    eo 'Open', 'Malfermu'\n    eo '&Open', '&Malfermu'\n    eo 'Open Multiple Files', 'Melfermu multan dosierojn'\n    eo 'P&aste', '&Elpo\\u015digi'\n    eo '&Quit', '&Finigu'\n    eo '&Red', '&Rosa'\n    eo 'Replace existing file?', '\\u0108u anstata\\u00fbu ekzistantan dosieron?'\n    eo '&Retry', '&Ripetu'\n    eo '&Save', '&Savu'\n    eo 'Save As', 'Savu kiel'\n    eo 'Save To Log', 'Savu en protokolon'\n    eo 'Select Log File', 'Elektu prokolodosieron'\n    eo 'Select a file to source', 'Elektu dosieron por interpreti'\n    eo '&Selection:', '&Elekto:'\n    eo 'Skip Messages', 'transsaltu pluajn mesa\\u011dojn'\n    eo '&Source...', '&Fontoprogramo...'\n    eo 'Tcl Scripts', 'Tcl-skriptoj'\n    eo 'Tcl for Windows', 'Tcl por vindoso'\n    eo 'Text Files', 'Tekstodosierojn'\n    eo '&Yes', '&Jes'\n    eo 'abort', '\\u0109esigo'\n    eo 'blue', 'blua'\n    eo 'cancel', 'rezignu'\n    eo 'extension', 'ekspansio'\n    eo 'extensions', 'ekspansioj'\n    eo 'green', 'verda'\n    eo 'ignore', 'ignorieren'\n    eo 'red', 'ru\\u011da'\n    eo 'retry', 'ripetu'\n    eo 'yes', 'jes'\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/es.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    es \"Application Error\", \"Error de la aplicaci\\\\u00f3n\"\n    es \"Blue\", \"Azul\"\n    es \"Color\", \"Color\"\n    es \"Delete\", \"Borrar\"\n    es \"Error\", \"Error\"\n    es \"Exit\", \"Salir\"\n    es \"Green\", \"Verde\"\n    es \"Red\", \"Rojo\"\n    es \"blue\", \"azul\"\n    es \"green\", \"verde\"\n    es \"red\", \"rojo\"\n}\n\nTkMsgCatalog.new('::tk') {\n    es \"&Abort\", \"&Abortar\"\n    es \"About...\", \"Acerca de ...\"\n    es \"All Files\", \"Todos los archivos\"\n    es \"Application Error\", \"Error de la aplicaci\\\\u00f3n\"\n    es \"&Blue\", \"&Azul\"\n    es \"&Cancel\", \"&Cancelar\"\n    es \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"No es posible acceder al directorio \\\"%1\\$s\\\".\\nPermiso denegado.\"\n    es \"Choose Directory\", \"Elegir directorio\"\n    es \"Clear\", \"Borrar\"\n    es \"Color\", \"Color\"\n    es \"Console\", \"Consola\"\n    es \"Copy\", \"Copiar\"\n    es \"Cut\", \"Cortar\"\n    es \"Delete\", \"Borrar\"\n    es \"Details >>\", \"Detalles >>\"\n    es \"Directory \\\"%1\\$s\\\" does not exist.\", \"El directorio \\\"%1\\$s\\\" no existe.\"\n    es \"&Directory:\", \"&Directorio:\"\n    es \"Error: %1\\$s\", \"Error: %1\\$s\"\n    es \"Exit\", \"Salir\"\n    es \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"El archivo \\\"%1\\$s\\\" ya existe.\\nDesea sobreescribirlo?\"\n    es \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"El archivo \\\"%1\\$s\\\" ya existe.\\n\\n\"\n    es \"File \\\"%1\\$s\\\" does not exist.\", \"El archivo \\\"%1\\$s\\\" no existe.\"\n    es \"File &name:\", \"&Nombre de archivo:\"\n    es \"File &names:\", \"&Nombres de archivo:\"\n    es \"Files of &type:\", \"Archivos de &tipo:\"\n    es \"Fi&les:\", \"&Archivos:\"\n    es \"&Filter\", \"&Filtro\"\n    es \"Fil&ter:\", \"Fil&tro:\"\n    es \"&Green\", \"&Verde\"\n    es \"Hi\", \"Hola\"\n    es \"Hide Console\", \"Esconder la consola\"\n    es \"&Ignore\", \"&Ignorar\"\n    es \"Invalid file name \\\"%1\\$s\\\".\", \"Nombre de archivo inv\\\\u00e1lido \\\"%1\\$s\\\".\"\n    es \"Log Files\", \"Ficheros de traza\"\n    es \"&No\", \"&No\"\n    es \"&OK\", \"&OK\"\n    es \"Ok\", \"Ok\"\n    es \"Open\", \"Abrir\"\n    es \"&Open\", \"&Abrir\"\n    es \"Open Multiple Files\", \"Abrir m\\\\u00faltiples archivos\"\n    es \"Paste\", \"Pegar\"\n    es \"Quit\", \"Abandonar\"\n    es \"&Red\", \"&Rojo\"\n    es \"Replace existing file?\", \"Reemplazar el archivo existente?\"\n    es \"&Retry\", \"&Reintentar\"\n    es \"&Save\", \"&Salvar\"\n    es \"Save As\", \"Salvar como\"\n    es \"Save To Log\", \"Salvar al archivo de traza\"\n    es \"Select Log File\", \"Elegir un archivo de traza\"\n    es \"Select a file to source\", \"Seleccionar un archivo a evaluar\"\n    es \"&Selection:\", \"&Selecci\\\\u00f3n:\"\n    es \"Skip Messages\", \"Omitir los mensajes\"\n    es \"Source...\", \"Evaluar...\"\n    es \"Tcl Scripts\", \"Scripts Tcl\"\n    es \"Tcl for Windows\", \"Tcl para Windows\"\n    es \"Text Files\", \"Archivos de texto\"\n    es \"&Yes\", \"&S\\\\u00ed\" \n    es \"abort\", \"abortar\"\n    es \"blue\", \"azul\"\n    es \"cancel\", \"cancelar\"\n    es \"extension\", \"extensi\\\\u00f3n\"\n    es \"extensions\", \"extensiones\"\n    es \"green\", \"verde\"\n    es \"ignore\", \"ignorar\"\n    es \"ok\", \"ok\"\n    es \"red\", \"rojo\"\n    es \"retry\", \"reintentar\"\n    es \"yes\", \"s\\\\u00ed\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/fr.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    fr 'Application Error', \"Erreur d'application\"\n    fr 'Blue', 'Bleu'\n    fr 'Color', 'Couleur'\n    fr 'Delete', 'Effacer'\n    fr 'Error', 'Erreur'\n    fr 'Exit', 'Quitter'\n    fr 'Green', 'Vert'\n    fr 'Red', 'Rouge'\n    fr 'blue', 'bleu'\n    fr 'green', 'vert'\n    fr 'red', 'rouge'\n}\n\nTkMsgCatalog.new('::tk') {\n    fr '&Abort', '&Annuler'\n    fr 'About...', '\\u00c0 propos...'\n    fr 'All Files', 'Tous les fichiers'\n    fr 'Application Error', \"Erreur d'application\"\n    fr '&Blue', '&Bleu'\n    fr '&Cancel', '&Annuler'\n    fr 'Cannot change to the directory \"%1\\$s\".' \"\\n\" 'Permission denied.', 'Impossible d\\'acc\\u00e9der au r\\u00e9pertoire \"%1\\$s\".' \"\\n\" 'Permission refus\\u00e9e.'\n    fr 'Choose Directory', 'Choisir r\\u00e9pertoire'\n    fr 'Clear', 'Effacer'\n    fr 'Color', 'Couleur'\n    fr 'Console'\n    fr 'Copy', 'Copier'\n    fr 'Cut', 'Couper'\n    fr 'Delete', 'Effacer'\n    fr 'Details >>', 'D\\u00e9tails >>'\n    fr 'Directory \"%1\\$s\" does not exist.', 'Le r\\u00e9pertoire \"%1\\$s\" n\\'existe pas.'\n    fr '&Directory:', '&R\\u00e9pertoire:'\n    fr 'Error: %1\\$s', 'Erreur: %1\\$s'\n    fr 'Exit', 'Quitter'\n    fr 'File \"%1\\$s\" already exists.' \"\\n\" 'Do you want to overwrite it?', 'Le fichier \"%1\\$s\" existe d\\u00e9j\\u00e0.' \"\\n\" 'Voulez-vous l\\'\\u00e9craser?'\n    fr 'File \"%1\\$s\" already exists.' \"\\n\\n\", 'Le fichier \"%1\\$s\" existe d\\u00e9j\\u00e0.' \"\\n\\n\"\n    fr 'File \"%1\\$s\" does not exist.', 'Le fichier \"%1\\$s\" n\\'existe pas.'\n    fr 'File &name:', '&Nom de fichier:'\n    fr 'File &names:', '&Noms de fichiers:'\n    fr 'Files of &type:', '&Type de fichiers:'\n    fr 'Fi&les:', 'Fich&iers:'\n    fr '&Filter', '&Filtre'\n    fr 'Fil&ter:', 'Fil&tre:'\n    fr '&Green', '&Vert'\n    fr 'Hi', 'Salut'\n    fr 'Hide Console', 'Cacher la Console'\n    fr '&Ignore', '&Ignorer'\n    fr 'Invalid file name \"%1\\$s\".', 'Nom de fichier invalide \"%1\\$s\".'\n    fr 'Log Files', 'Fichiers de trace'\n    fr '&No', '&Non'\n    fr '&OK'\n    fr 'Ok'\n    fr 'Open', 'Ouvrir'\n    fr '&Open', '&Ouvrir'\n    fr 'Open Multiple Files', 'Ouvrir plusieurs fichiers'\n    fr 'Paste', 'Coller'\n    fr 'Quit', 'Quitter'\n    fr '&Red', '&Rouge'\n    fr 'Replace existing file?', 'Remplacer le fichier existant?'\n    fr '&Retry', '&R\\u00e9-essayer'\n    fr '&Save', '&Sauvegarder'\n    fr 'Save As', 'Sauvegarder sous'\n    fr 'Save To Log', 'Sauvegarde au fichier de trace'\n    fr 'Select Log File', 'Choisir un fichier de trace'\n    fr 'Select a file to source', 'Choisir un fichier \\u00e0 \\u00e9valuer'\n    fr '&Selection:', '&S\\u00e9lection:'\n    fr 'Skip Messages', 'Omettre les messages'\n    fr 'Source...', '\\u00c9valuer...'\n    fr 'Tcl Scripts', 'Scripts Tcl'\n    fr 'Tcl for Windows', 'Tcl pour Windows'\n    fr 'Text Files', 'Fichiers texte'\n    fr '&Yes', '&Oui'\n    fr 'abort', 'abandonner'\n    fr 'blue', 'bleu'\n    fr 'cancel', 'annuler'\n    fr 'extension'\n    fr 'extensions'\n    fr 'green', 'vert'\n    fr 'ignore', 'ignorer'\n    fr 'ok'\n    fr 'red', 'rouge'\n    fr 'retry', 'r\\u00e9essayer'\n    fr 'yes', 'oui'\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/it.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    it \"Application Error\", \"Errore dell' applicazione\"\n    it \"Blue\", \"Blu\"\n    it \"Color\", \"Colore\"\n    it \"Delete\", \"Incolla\"\n    it \"Error\", \"Errore\"\n    it \"Exit\", \"Esci\"\n    it \"Green\", \"Verde\"\n    it \"Red\", \"Rosso\"\n    it \"blue\", \"blu\"\n    it \"green\", \"verde\"\n    it \"red\", \"rosso\"\n}\n\nTkMsgCatalog.new('::tk') {\n    it \"&Abort\", \"&Interrompi\"\n    it \"About...\", \"Informazioni ...\"\n    it \"All Files\", \"Tutti i file\"\n    it \"Application Error\", \"Errore dell' applicazione\"\n    it \"&Blue\", \"&Blu\"\n    it \"&Cancel\", \"&Annulla\"\n    it \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"Impossibile accedere alla directory \\\"%1\\$s\\\".\\nPermesso negato.\"\n    it \"Choose Directory\", \"Scegli directory\"\n    it \"Clear\", \"Azzera\"\n    it \"Color\", \"Colore\"\n    it \"Console\"\n    it \"Copy\", \"Copia\"\n    it \"Cut\", \"Taglia\"\n    it \"Delete\", \"Incolla\"\n    it \"Details >>\", \"Dettagli >>\"\n    it \"Directory \\\"%1\\$s\\\" does not exist.\", \"La directory \\\"%1\\$s\\\" non esiste.\"\n    it \"&Directory:\"\n    it \"Error: %1\\$s\", \"Errore: %1\\$s\"\n    it \"Exit\", \"Esci\"\n    it \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"Il file \\\"%1\\$s\\\" esiste gi\\\\u00e0.\\nVuoi sovrascriverlo?\"\n    it \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"Il file \\\"%1\\$s\\\" esiste gi\\\\u00e0.\\n\\n\"\n    it \"File \\\"%1\\$s\\\" does not exist.\", \"Il file \\\"%1\\$s\\\" non esiste.\"\n    it \"File &name:\", \"&Nome del file:\"\n    it \"File &names:\", \"&Nomi dei file:\"\n    it \"Files of &type:\", \"File di &tipo:\"\n    it \"Fi&les:\", \"Fi&le:\"\n    it \"&Filter\", \"&Filtro\"\n    it \"Fil&ter:\", \"Fil&tro:\"\n    it \"&Green\", \"&Verde\"\n    it \"Hi\", \"Salve\"\n    it \"Hide Console\", \"Nascondi la console\"\n    it \"&Ignore\", \"&Ignora\"\n    it \"Invalid file name \\\"%1\\$s\\\".\", \"Nome di file non valido \\\"%1\\$s\\\".\"\n    it \"Log Files\", \"File di log\"\n    it \"&No\"\n    it \"&OK\"\n    it \"Ok\"\n    it \"&Open\", \"A&pri\"\n    it \"Open\", \"Apri\"\n    it \"Open Multiple Files\", \"Apri file multipli\"\n    it \"Paste\", \"Incolla\"\n    it \"Quit\", \"Esci\"\n    it \"&Red\", \"&Rosso\"\n    it \"Replace existing file?\", \"Sostituisci il file esistente?\"\n    it \"&Retry\", \"&Riprova\"\n    it \"&Save\", \"&Salva\"\n    it \"Save As\", \"Salva come\"\n    it \"Save To Log\", \"Salva il log\"\n    it \"Select Log File\", \"Scegli un file di log\"\n    it \"Select a file to source\", \"Scegli un file da eseguire\"\n    it \"&Selection:\", \"&Selezione:\"\n    it \"Skip Messages\", \"Salta i messaggi\"\n    it \"Source...\", \"Esegui...\"\n    it \"Tcl Scripts\", \"Scripts Tcl\"\n    it \"Tcl for Windows\", \"Tcl per Windows\"\n    it \"Text Files\", \"File di testo\"\n    it \"&Yes\", \"&Si\"\n    it \"abort\", \"interrompi\"\n    it \"blue\", \"blu\"\n    it \"cancel\", \"annulla\"\n    it \"extension\", \"estensione\"\n    it \"extensions\", \"estensioni\"\n    it \"green\", \"verde\"\n    it \"ignore\", \"ignora\"\n    it \"ok\"\n    it \"red\", \"rosso\"\n    it \"retry\", \"riprova\"\n    it \"yes\", \"si\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/ja.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    ja 'Application Error', '\\u30A2\\u30D7\\u30EA\\u30B1\\u30FC\\u30B7\\u30E7\\u30F3\\u30A8\\u30E9\\u30FC'\n    ja 'Blue',   '\\u9752'\n    ja 'Color',  '\\u80CC\\u666F\\u8272'\n    ja 'Delete', '\\u6D88\\u53BB'\n    ja 'Error',  '\\u30A8\\u30E9\\u30FC'\n    ja 'Exit',   '\\u7D42\\u4E86'\n    ja 'Green',  '\\u7DD1'\n    ja 'Red',    '\\u8D64'\n    ja 'blue',   '\\u9752'\n    ja 'green',  '\\u7DD1'\n    ja 'red',    '\\u8D64'\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/nl.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    nl \"Application Error\", \"Toepassingsfout\"\n    nl \"Blue\", \"Blauw\"\n    nl \"Color\", \"Kleur\"\n    nl \"Delete\", \"Wissen\"\n    nl \"Error\", \"Fout\"\n    nl \"Exit\", \"Be\\\\u00ebindigen\"\n    nl \"Green\", \"Groen\"\n    nl \"Red\", \"Rood\"\n    nl \"blue\", \"blauw\"\n    nl \"green\", \"groen\"\n    nl \"red\", \"rood\"\n}\n\nTkMsgCatalog.new('::tk') {\n    nl \"\\\"%1\\$s\\\" must be an absolute pathname\", \"\\\"%1\\$s\\\" moet een absolute pad-naam zijn\"\n    nl \"%1\\$s is not a toplevel window\", \"%1\\$s is geen toplevel window\"\n    nl \", or\", \", of\"\n    nl \"-default, -icon, -message, -parent, -title, or -type\", \"-default, -icon, -message, -parent, -title, of -type\"\n    nl \"-initialdir, -mustexist, -parent, or -title\", \"-initialdir, -mustexist, -parent, of -title\"\n    nl \"&Abort\", \"&Afbreken\"\n    nl \"About...\", \"Over...\"\n    nl \"All Files\", \"Alle Bestanden\"\n    nl \"Application Error\", \"Toepassingsfout\"\n    nl \"&Blue\", \"&Blauw\"\n    nl \"&Cancel\", \"&Annuleren\"\n    nl \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"Kan niet naar map \\\"%1\\$s\\\" gaan.\\nU heeft hiervoor geen toestemming.\"\n    nl \"Choose Directory\", \"Kies map\"\n    nl \"Clear\", \"Wissen\"\n    nl \"Clear entry, Press OK; Enter %1\\$s, press OK\", \"Wis veld, Druk op OK; typ %1\\$s in, druk op OK\"\n    nl \"&Clear Console\", \"&Wis Console\"\n    nl \"Color\", \"Kleur\"\n    nl \"Console\"\n    nl \"Copy\", \"Kopi\\\\u00ebren\"\n    nl \"Cut\", \"Knippen\"\n    nl \"Delete\", \"Wissen\"\n    nl \"Details\"\n    nl \"Details >>\"\n    nl \"Directory \\\"%1\\$s\\\" does not exist.\", \"Map \\\"%1\\$s\\\" bestaat niet.\"\n    nl \"&Directory:\", \"&Map:\"\n    nl \"Edit\", \"Bewerken\"\n    nl \"Enter \\\"%1\\$s\\\", press OK\", \"Typ \\\"%1\\$s\\\", druk op OK\"\n    nl \"Enter \\\"%1\\$s\\\", press OK, enter \\\"%2\\$s\\\", press OK\", \"Typ \\\"%1\\$s\\\", druk op OK, typ \\\"%2\\$s\\\", druk op OK\"\n    nl \"Error: %1\\$s\", \"Fout: %1\\$s\"\n    nl \"Exit\", \"Be\\\\u00ebindigen\"\n    nl \"File\", \"Bestand\"\n    nl \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"Bestand \\\"%1\\$s\\\" bestaat al.\\n\\n\"\n    nl \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"Bestand \\\"%1\\$s\\\" bestaat al.\\nWilt u het overschrijven?\"\n    nl \"File \\\"%1\\$s\\\" does not exist.\", \"Bestand \\\"%1\\$s\\\" bestaat niet.\"\n    nl \"File &name:\", \"Bestands&naam:\"\n    nl \"File &names:\", \"Bestands&namen:\"\n    nl \"Files of &type:\", \"Bestanden van het &type:\"\n    nl \"Fi&les:\", \"&Bestanden:\"\n    nl \"&Filter\"\n    nl \"Fil&ter:\"\n    nl \"&Green\", \"&Groen\"\n    nl \"Hi\", \"H\\\\u00e9\"\n    nl \"Hide Console\", \"Verberg Console\"\n    nl \"&Ignore\", \"&Negeren\"\n    nl \"Invalid file name \\\"%1\\$s\\\".\", \"Ongeldige bestandsnaam \\\"%1\\$s\\\".\"\n    nl \"Log Files\", \"Log Bestanden\"\n    nl \"&No\", \"&Nee\"\n    nl \"&OK\"\n    nl \"Ok\"\n    nl \"&Open\", \"&Openen\"\n    nl \"Open\", \"Openen\"\n    nl \"Open Multiple Files\", \"Open meerdere bestanden\"\n    nl \"Paste\", \"Plakken\"\n    nl \"Please press %1\\$s\", \"Druk op %1\\$s, A.U.B.\"\n    nl \"Please press ok\", \"Druk op ok, A.U.B.\"\n    nl \"Press Cancel\", \"Druk op Annuleren\"\n    nl \"Press Ok\", \"Druk op Ok\"\n    nl \"Quit\", \"Stoppen\"\n    nl \"&Red\", \"&Rood\"\n    nl \"Replace existing file?\", \"Vervang bestaand bestand?\"\n    nl \"&Retry\", \"&Herhalen\"\n    nl \"&Save\", \"Op&slaan\"\n    nl \"Save As\", \"Opslaan als\"\n    nl \"Save To Log\", \"Opslaan naar Log\"\n    nl \"Select Log File\", \"Selecteer Log bestand\"\n    nl \"Select a file to source\", \"Selecteer bronbestand\"\n    nl \"&Selection:\", \"&Selectie:\"\n    nl \"Skip Messages\", \"Berichten overslaan\"\n    nl \"Source...\", \"Bron...\"\n    nl \"Tcl Scripts\"\n    nl \"Tcl for Windows\", \"Tcl voor Windows\"\n    nl \"Text Files\", \"Tekstbestanden\"\n    nl \"&Yes\", \"&Ja\"\n    nl \"abort\", \"afbreken\"\n    nl \"abort, retry, ignore, ok, cancel, no, or yes\", \"afbreken, opnieuw, negeren, ok, annuleren, nee, of ja\"\n    nl \"abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel\", \"abortretryignore, ok, okcancel, retrycancel, yesno, of yesnocancel\"\n    nl \"bad %1\\$s value \\\"%2\\$s\\\": must be %3\\$s\", \"verkeerde %1\\$s waarde \\\"%2\\$s\\\": moet zijn %3\\$s\"\n    nl \"bad file type \\\"%1\\$s\\\", should be\", \"verkeerd bestandstype \\\"%1\\$s\\\", moet zijn\"\n    nl \"bad option \\\"%1\\$s\\\": should be %2\\$s\", \"verkeerde optie \\\"%1\\$s\\\": moet zijn %2\\$s\"\n    nl \"bad window path name \\\"%1\\$s\\\"\", \"verkeerde window-padnaam \\\"%1\\$s\\\"\"\n    nl \"blue\", \"blauw\"\n    nl \"can't post %1\\$s:  it isn't a descendant of %2\\$s (this is a new requirement in Tk versions 3.0 and later)\", \"kan %1\\$s niet verzenden:  het is geen afstammeling van %2\\$s (dit is een nieuwe eis in Tk versies 3.0 en later)\"\n    nl \"cancel\", \"annuleren\"\n    nl \"default button index greater than number of buttons specified for tk_dialog\", \"default knop index is groter dan het aantal knoppen beschikbaar voor tk_dialog\"\n    nl \"display name to use (current one otherwise)\", \"te gebruiken schermnaam (anders huidige scherm)\"\n    nl \"error, info, question, or warning\", \"error, info, question, of warning\"\n    nl \"extension\"\n    nl \"extensions\"\n    nl \"focus group \\\"%1\\$s\\\" doesn't exist\", \"focusgroep \\\"%1\\$s\\\" bestaat niet\"\n    nl \"green\", \"groen\"\n    nl \"history event %1\\$s\"\n    nl \"ignore\", \"negeren\"\n    nl \"invalid default button \\\"%1\\$s\\\"\", \"ongeldige default knop \\\"%1\\$s\\\"\"\n    nl \"macType\"\n    nl \"macTypes\"\n    nl \"must specify a background color\", \"een achtergrondkleur is verplicht\"\n    nl \"name of the slave interpreter\", \"naam van de slaaf-interpreter\"\n    nl \"no winfo screen . nor env(DISPLAY)\", \"geen winfo scherm . noch env(DISPLAY)\"\n    nl \"ok\"\n    nl \"red\", \"rood\"\n    nl \"retry\", \"opnieuw\"\n    nl \"should contain 5 or 4 elements\", \"moet 4 of 5 elementen bevatten\"\n    nl \"spec\"\n    nl \"tk_chooseDirectory command\", \"tk_chooseDirectory opdracht\"\n    nl \"tk_chooseDirectory command, cancel gives null\", \"tk_chooseDirectory opdracht, annuleren geeft lege waarde\"\n    nl \"tk_chooseDirectory command, initialdir\", \"tk_chooseDirectory opdracht, initi\\\\u00eble map\"\n    nl \"yes\", \"ja\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/pl.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    pl 'Application Error', 'Bl\\u0105d w Programie'\n    pl 'Blue', 'Niebieski'\n    pl 'Color', 'Kolor'\n    pl 'Delete', 'Usu\\u0144'\n    pl 'Error', 'B\\u0142\\u0105d'\n    pl 'Exit', 'Zako\\u0144cz'\n    pl 'Green', 'Zielony'\n    pl 'Red', 'Czerwonz'\n    pl 'blue', 'niebieski'\n    pl 'green', 'zielony'\n    pl 'red', 'czerwony'\n}\n\nTkMsgCatalog.new('::tk') {\n    pl '&Abort', '&Anuluj'\n    pl '&About...', 'O Programie...'\n    pl 'All Files', 'Wszystkie pliki'\n    pl 'Application Error', 'Bl\\u0105d w Programie'\n    pl '&Blue', '&Niebieski'\n    pl '&Cancel', '&Anuluj'\n    pl 'Cannot change to the directory \"%1\\$s\".' \"\\n\" 'Permission denied.', 'Katalog \"%1\\$s\" nie mo\\u017ce zosta\\u0107 odczytany lub nie istnieje.'\n    pl 'Choose Directory', 'Wybierz katalog'\n    pl '&Clear', '&Wyczy\\u015b\\u0107'\n    pl '&Clear Console', '&Wyczy\\u015b\\u0107 konsol\\u0119'\n    pl 'Color', 'Kolor'\n    pl 'Console', 'Konsola'\n    pl '&Copy', '&Kopiuj'\n    pl 'Cu&t', '&Wytnij'\n    pl '&Delete', '&Usu\\u0144'\n    pl 'Details >>', 'Detale >>'\n    pl 'Directory \"%1\\$s\" does not exist.', 'Katalog \"%1\\$s\" nie istniej.'\n    pl '&Directory:', '&Katalog:'\n    pl '&Edit', '&Edytuj'\n    pl 'Error: %1\\$s', 'B\\u0142\\u0105d: %1\\$s'\n    pl 'E&xit', '&Zako\\u0144cz'\n    pl '&File', '&Plik'\n    pl 'File \"%1\\$s\" already exists.' \"\\n\" 'Do you want to overwrite it?', 'Plik \"%1\\$s\" ju\\u017c istnieje.' \"\\n\" 'Czy chcesz go zast\\u0105pi\\u0107?'\n    pl 'File \"%1\\$s\" already exists.' \"\\n\\n\", 'Plik \"%1\\$s\" ju\\u017c istnieje. ' \"\\n\\n\"\n    pl 'File \"%1\\$s\" does not exist.', 'Plik \"%1\\$s\" nie istnieje.'\n    pl 'File &name:', 'Nazwa &pliku:'\n    pl 'File &names:', 'Nazwy &plik\\u00f3w:'\n    pl 'Files of &type:', 'Pliki &typu:'\n    pl 'Fi&les:', 'Pli&ki:'\n    pl '&Filter', '&Filter'\n    pl 'Fil&ter:', '&Filter:'\n    pl '&Green', '&Zielony'\n    pl '&Help', '&Pomoc'\n    pl 'Hi', 'Witaj'\n    pl '&Hide Console', '&Schowaj konsol\\u0119'\n    pl '&Ignore', '&Ignoruj'\n    pl 'Invalid file name \"%1\\$s\".', 'Niew\\u0142a\\u015bciwa nazwa pliku \"%1\\$s\".'\n    pl 'Log Files', 'Protoko\\u0142uj'\n    pl '&No', '&Nie'\n    pl 'OK'\n    pl 'Ok'\n    pl 'Open', 'Wczytaj'\n    pl '&Open', '&Wczytaj'\n    pl 'Open Multiple Files', 'Wczytuj wiele plik\\u00f3w'\n    pl 'P&aste', '&Wklej'\n    pl '&Quit', '&Zako\\u0144cz'\n    pl '&Red', '&Czerwonz'\n    pl 'Replace existing file?', 'Czy zost\\u0105pi\\u0107 instniej\\u0105cy plik?'\n    pl '&Retry', '&Powt\\u00f3rz'\n    pl '&Save', '&Zapisz'\n    pl 'Save As', 'Zapisz jako'\n    pl 'Save To Log', 'Wpisz do protoko\\u0142u'\n    pl 'Select Log File', 'Wybierz plik proko\\u0142u'\n    pl 'Select a file to source', 'Wybierz plik do wykonania'\n    pl '&Selection:', '&Wyb\\u00f3r:'\n    pl 'Skip Messages', 'Omi\\u0144 pozosta\\u0142e komunikaty'\n    pl '&Source...', '&Kod \\u017ar\\u00f3d\\u0142owy...'\n    pl 'Tcl Scripts', 'Tcl-skrypty'\n    pl 'Tcl for Windows', 'Tcl dla Okienek (Windows)'\n    pl 'Text Files', 'Pliki Tekstowe'\n    pl '&Yes', '&Tak'\n    pl 'abort', 'zako\\u0144cz'\n    pl 'blue', 'niebieski'\n    pl 'cancel', 'anuluj'\n    pl 'extension', 'rozszerzenie'\n    pl 'extensions', 'rozszerzenia'\n    pl 'green', 'zielony'\n    pl 'ignore', 'ignoruj'\n    pl 'red', 'czerwony'\n    pl 'retry', 'potw\\u00f3rz'\n    pl 'yes', 'tak'\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb/ru.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    ru 'Application Error', '\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430 \\u0432 \\u043f\\u0440\\u043e\\u0433\\u0440\\u0430\\u043c\\u043c\\u0435'\n    ru 'Blue', ' \\u0413\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439'\n    ru 'Color', '\\u0426\\u0432\\u0435\\u0442'\n    ru 'Delete', '\\u0423\\u0434\\u0430\\u043b\\u0438\\u0442\\u044c'\n    ru 'Error', '\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430'\n    ru 'Exit', '\\u0412\\u044b\\u0445\\u043e\\u0434'\n    ru 'Green', '\\u0417\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439'\n    ru 'Red', '\\u041a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439'\n    ru 'blue', ' \\u0433\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439'\n    ru 'green', ' \\u0437\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439'\n    ru 'red', ' \\u043a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439'\n}\n\nTkMsgCatalog.new('::tk') {\n    ru '&Abort', '&\\u041e\\u0442\\u043c\\u0435\\u043d\\u0438\\u0442\\u044c'\n    ru 'About...', '\\u041f\\u0440\\u043e...'\n    ru 'All Files', '\\u0412\\u0441\\u0435 \\u0444\\u0430\\u0439\\u043b\\u044b'\n    ru 'Application Error', '\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430 \\u0432 \\u043f\\u0440\\u043e\\u0433\\u0440\\u0430\\u043c\\u043c\\u0435'\n    ru '&Blue', ' &\\u0413\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439'\n    ru '&Cancel', '\\u041e\\u0442&\\u043c\\u0435\\u043d\\u0430'\n    ru 'Cannot change to the directory \"%1\\$s\".' \"\\n\" 'Permission denied.' \\\n                        '\\u041d\\u0435 \\u043c\\u043e\\u0433\\u0443 \\u043f\\u0435\\u0440\\u0435\\u0439\\u0442\\u0438 \\u0432 \\u043a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433 \"%1\\$s\".' \"\\n\" '\\u041d\\u0435\\u0434\\u043e\\u0441\\u0442\\u0430\\u0442\\u043e\\u0447\\u043d\\u043e \\u043f\\u0440\\u0430\\u0432 \\u0434\\u043e\\u0441\\u0442\\u0443\\u043f\\u0430'\n    ru 'Choose Directory', '\\u0412\\u044b\\u0431\\u0435\\u0440\\u0438\\u0442\\u0435 \\u043a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433'\n    ru 'Clear', '\\u041e\\u0447\\u0438\\u0441\\u0442\\u0438\\u0442\\u044c'\n    ru 'Color', '\\u0426\\u0432\\u0435\\u0442'\n    ru 'Console', '\\u041a\\u043e\\u043d\\u0441\\u043e\\u043b\\u044c'\n    ru 'Copy', '\\u041a\\u043e\\u043f\\u0438\\u0440\\u043e\\u0432\\u0430\\u0442\\u044c'\n    ru 'Cut', '\\u0412\\u044b\\u0440\\u0435\\u0437\\u0430\\u0442\\u044c'\n    ru 'Delete', '\\u0423\\u0434\\u0430\\u043b\\u0438\\u0442\\u044c'\n    ru 'Details >>', '\\u041f\\u043e\\u0434\\u0440\\u043e\\u0431\\u043d\\u0435\\u0435 >>'\n    ru 'Directory \"%1\\$s\" does not exist.', '\\u041a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433\\u0430 \"%1\\$s\" \\u043d\\u0435 \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442.'\n    ru '&Directory:', '&\\u041a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433:'\n    ru 'Error: %1\\$s', '\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430: %1\\$s' \n    ru 'Exit', '\\u0412\\u044b\\u0445\\u043e\\u0434'\n    ru 'File \"%1\\$s\" already exists.' \"\\n\" 'Do you want to overwrite it?' \\\n                            '\\u0424\\u0430\\u0439\\u043b \"%1\\$s\" \\u0443\\u0436\\u0435 \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442.' \"\\n\" '\\u0417\\u0430\\u043c\\u0435\\u043d\\u0438\\u0442\\u044c \\u0435\\u0433\\u043e?'\n    ru 'File \"%1\\$s\" already exists.' \"\\n\\n\", '\\u0424\\u0430\\u0439\\u043b \"%1\\$s\" \\u0443\\u0436\\u0435 \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442.' \"\\n\\n\"\n    ru 'File \"%1\\$s\" does not exist.', '\\u0424\\u0430\\u0439\\u043b \"%1\\$s\" \\u043d\\u0435 \\u043d\\u0430\\u0439\\u0434\\u0435\\u043d.'\n    ru 'File &name:', '&\\u0418\\u043c\\u044f \\u0444\\u0430\\u0439\\u043b\\u0430:'\n    ru 'File &names:', '&\\u0418\\u043c\\u0435\\u043d\\u0430 \\u0444\\u0430\\u0439\\u043b\\u043e\\u0432:'\n    ru 'Files of &type:', '&\\u0422\\u0438\\u043f \\u0444\\u0430\\u0439\\u043b\\u043e\\u0432:'\n    ru 'Fi&les:', '\\u0424\\u0430\\u0439&\\u043b\\u044b:'\n    ru '&Filter', '&\\u0424\\u0438\\u043b\\u044c\\u0442\\u0440'\n    ru 'Fil&ter:', '\\u0424\\u0438\\u043b\\u044c&\\u0442\\u0440:'\n    ru '&Green', ' &\\u0417\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439'\n    ru 'Hi', '\\u041f\\u0440\\u0438\\u0432\\u0435\\u0442'\n    ru 'Hide Console', '\\u0421\\u043f\\u0440\\u044f\\u0442\\u0430\\u0442\\u044c \\u043a\\u043e\\u043d\\u0441\\u043e\\u043b\\u044c'\n    ru '&Ignore', '&\\u0418\\u0433\\u043d\\u043e\\u0440\\u0438\\u0440\\u043e\\u0432\\u0430\\u0442\\u044c'\n    ru 'Invalid file name \"%1\\$s\".', '\\u041d\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0435 \\u0438\\u043c\\u044f \\u0444\\u0430\\u0439\\u043b\\u0430 \"%1\\$s\".' \n    ru 'Log Files', '\\u0424\\u0430\\u0439\\u043b\\u044b \\u0436\\u0443\\u0440\\u043d\\u0430\\u043b\\u0430'\n    ru '&No', '&\\u041d\\u0435\\u0442'\n    ru '&OK', '&\\u041e\\u041a'\n    ru 'Ok', '\\u0414\\u0430'\n    ru 'Open', '\\u041e\\u0442\\u043a\\u0440\\u044b\\u0442\\u044c'\n    ru '&Open', '&\\u041e\\u0442\\u043a\\u0440\\u044b\\u0442\\u044c'\n    ru 'Open Multiple Files', '\\u041e\\u0442\\u043a\\u0440\\u044b\\u0442\\u044c \\u043d\\u0435\\u0441\\u043a\\u043e\\u043b\\u044c\\u043a\\u043e \\u0444\\u0430\\u0439\\u043b\\u043e\\u0432'\n    ru 'Paste', '\\u0412\\u0441\\u0442\\u0430\\u0432\\u0438\\u0442\\u044c'\n    ru 'Quit', '\\u0412\\u044b\\u0445\\u043e\\u0434'\n    ru '&Red', ' &\\u041a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439'\n    ru 'Replace existing file?', '\\u0417\\u0430\\u043c\\u0435\\u043d\\u0438\\u0442\\u044c \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u044e\\u0449\\u0438\\u0439 \\u0444\\u0430\\u0439\\u043b?'\n    ru '&Retry', '&\\u041f\\u043e\\u0432\\u0442\\u043e\\u0440\\u0438\\u0442\\u044c'\n    ru '&Save', '&\\u0421\\u043e\\u0445\\u0440\\u0430\\u043d\\u0438\\u0442\\u044c'\n    ru 'Save As', '\\u0421\\u043e\\u0445\\u0440\\u0430\\u043d\\u0438\\u0442\\u044c \\u043a\\u0430\\u043a'\n    ru 'Save To Log', '\\u0421\\u043e\\u0445\\u0440\\u0430\\u043d\\u0438\\u0442\\u044c \\u0432 \\u0436\\u0443\\u0440\\u043d\\u0430\\u043b'\n    ru 'Select Log File', '\\u0412\\u044b\\u0431\\u0440\\u0430\\u0442\\u044c \\u0436\\u0443\\u0440\\u043d\\u0430\\u043b'\n    ru 'Select a file to source', '\\u0412\\u044b\\u0431\\u0435\\u0440\\u0438\\u0442\\u0435 \\u0444\\u0430\\u0439\\u043b \\u0434\\u043b\\u044f \\u0438\\u043d\\u0442\\u0435\\u0440\\u043f\\u0440\\u0435\\u0442\\u0430\\u0446\\u0438\\u0438'\n    ru '&Selection:', '&Selection:'\n    ru 'Skip Messages', '\\u041f\\u0440\\u043e\\u043f\\u0443\\u0441\\u0442\\u0438\\u0442\\u044c \\u0441\\u043e\\u043e\\u0431\\u0449\\u0435\\u043d\\u0438\\u044f'\n    ru 'Source...', '\\u0418\\u043d\\u0442\\u0435\\u0440\\u043f\\u0440\\u0435\\u0442\\u0438\\u0440\\u043e\\u0432\\u0430\\u0442\\u044c \\u0444\\u0430\\u0439\\u043b...'\n    ru 'Tcl Scripts', '\\u041f\\u0440\\u043e\\u0433\\u0440\\u0430\\u043c\\u043c\\u0430 \\u043d\\u0430 \\u044f\\u0437\\u044b\\u043a\\u0435 TCL'\n    ru 'Tcl for Windows', 'TCL \\u0434\\u043b\\u044f Windows'\n    ru 'Text Files', '\\u0422\\u0435\\u043a\\u0441\\u0442\\u043e\\u0432\\u044b\\u0435 \\u0444\\u0430\\u0439\\u043b\\u044b'\n    ru '&Yes', '&\\u0414\\u0430'\n    ru 'abort', '\\u043e\\u0442\\u043c\\u0435\\u043d\\u0430'\n    ru 'blue', ' \\u0433\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439'\n    ru 'cancel', '\\u043e\\u0442\\u043c\\u0435\\u043d\\u0430'\n    ru 'extension', '\\u0440\\u0430\\u0441\\u0448\\u0438\\u0440\\u0435\\u043d\\u0438\\u0435'\n    ru 'extensions', '\\u0440\\u0430\\u0441\\u0448\\u0438\\u0440\\u0435\\u043d\\u0438\\u044f'\n    ru 'green', ' \\u0437\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439'\n    ru 'ignore', '\\u043f\\u0440\\u043e\\u043f\\u0443\\u0441\\u0442\\u0438\\u0442\\u044c'\n    ru 'ok', '\\u043e\\u043a'\n    ru 'red', ' \\u043a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439'\n    ru 'retry', '\\u043f\\u043e\\u0432\\u0442\\u043e\\u0440\\u0438\\u0442\\u044c'\n    ru 'yes', '\\u0434\\u0430'\n}\n\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb2/README",
    "content": "Message catalogs in this directory are written in encodings except\nUTF-8. As if you have a trouble to edit UTF-8 text, you can write \nmessage catalogs in your familier encoding.\n\nPlease see '../msgs_rb/README' too.\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb2/de.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    de 'Application Error', 'Applikationsfehler'\n    de 'Blue', 'Blau'\n    de 'Color', 'Farbe'\n    de 'Delete', 'Lschen', 'iso8859-1'\n    de 'Error', 'Fehler'\n    de 'Exit', 'Ende'\n    de 'Green', 'Grn', 'iso8859-1'\n    de 'Red', 'Rot'\n    de 'blue', 'blau'\n    de 'green', 'grn', 'iso8859-1'\n    de 'red', 'rot'\n}\n\nTkMsgCatalog.new('::tk') {\n    de \"&Abort\", \"&Abbruch\"\n    de \"&About...\", \"&ber...\", 'iso8859-1'\n    de \"All Files\", \"Alle Dateien\"\n    de \"Application Error\", \"Applikationsfehler\"\n    de \"&Blue\", \"&Blau\"\n    de \"&Cancel\", \"&Abbruch\"\n    de \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"Kann nicht in das Verzeichnis \\\"%1\\$s\\\" wechseln.\\nKeine Rechte vorhanden.\"\n    de \"Choose Directory\", \"Whle Verzeichnis\", 'iso8859-1'\n    de \"&Clear\", \"&Rcksetzen\", 'iso8859-1'\n    de \"&Clear Console\", \"&Konsole lschen\", 'iso8859-1'\n    de \"Color\", \"Farbe\"\n    de \"Console\", \"Konsole\"\n    de \"&Copy\", \"&Kopieren\"\n    de \"Cu&t\", \"Aus&schneiden\"\n    de '&Delete', '&Lschen', 'iso8859-1'\n    de \"Details >>\"\n    de \"Directory \\\"%1\\$s\\\" does not exist.\", \"Das Verzeichnis \\\"%1\\$s\\\" existiert nicht.\"\n    de \"&Directory:\", \"&Verzeichnis:\"\n    de \"&Edit\", \"&Bearbieten\"\n    de \"Error: %1\\$s\", \"Fehler: %1\\$s\"\n    de \"E&xit\", \"&Ende\"\n    de \"&File\", \"&Datei\"\n    de \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"Die Datei \\\"%1\\$s\\\" ist bereits vorhanden.\\nWollen sie diese Datei berschreiben ?\", 'iso8859-1'\n    de \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"Die Datei \\\"%1\\$s\\\" ist bereits vorhanden.\\n\\n\"\n    de \"File \\\"%1\\$s\\\" does not exist.\", \"Die Datei \\\"%1\\$s\\\" existiert nicht.\"\n    de \"File &name:\", \"Datei&name:\"\n    de \"File &names:\", \"Datei&namen:\"\n    de \"Files of &type:\", \"Dateien des &Typs:\"\n    de \"Fi&les:\", \"Dat&eien:\"\n    de \"&Filter\"\n    de \"Fil&ter:\"\n    de '&Green', '&Grn', 'iso8859-1'\n    de \"&Help\", \"&Hilfe\"\n    de \"Hi\", \"Hallo\"\n    de \"&Hide Console\", \"&Konsole unsichtbar machen\"\n    de \"&Ignore\", \"&Ignorieren\"\n    de \"Invalid file name \\\"%1\\$s\\\".\", \"Ungltiger Dateiname \\\"%1\\$s\\\".\", 'iso8859-1'\n    de \"Log Files\", \"Protokolldatei\"\n    de \"&No\", \"&Nein\"\n    de \"OK\"\n    de \"Ok\"\n    de \"Open\", \"ffnen\", 'iso8859-1'\n    de \"&Open\", \"&ffnen\", 'iso8859-1'\n    de \"Open Multiple Files\"\n    de \"P&aste\", \"E&infgen\", 'iso8859-1'\n    de \"&Quit\", \"&Beenden\"\n    de \"&Red\", \"&Rot\"\n    de \"Replace existing file?\", \"Existierende Datei ersetzen?\"\n    de \"&Retry\", \"&Wiederholen\"\n    de \"&Save\", \"&Speichern\"\n    de \"Save As\", \"Speichern unter\"\n    de \"Save To Log\", \"In Protokoll speichern\"\n    de \"Select Log File\", \"Protokolldatei auswhlen\", 'iso8859-1'\n    de \"Select a file to source\", \"Auszufhrende Datei auswhlen\", 'iso8859-1'\n    de \"&Selection:\", \"Auswah&l:\"\n    de \"Skip Messages\", \"Weitere Nachrichten berspringen\", 'iso8859-1'\n    de \"&Source...\", \"&Ausfhren...\", 'iso8859-1'\n    de \"Tcl Scripts\", \"Tcl-Skripte\"\n    de \"Tcl for Windows\", \"Tcl fr Windows\", 'iso8859-1'\n    de \"Text Files\", \"Textdateien\"\n    de \"&Yes\", \"&Ja\"\n    de \"abort\", \"abbrechen\"\n    de \"blue\", \"blau\"\n    de \"cancel\", \"abbrechen\"\n    de \"extension\", \"Erweiterung\"\n    de \"extensions\", \"Erweiterungen\"\n    de 'green', 'grn', 'iso8859-1'\n    de \"ignore\", \"ignorieren\"\n    de \"ok\"\n    de \"red\", \"rot\"\n    de \"retry\", \"wiederholen\"\n    de \"yes\", \"ja\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_rb2/ja.msg",
    "content": "TkMsgCatalog.new('::tkmsgcat_demo') {\n    ja 'Application Error', 'ץꥱ󥨥顼', 'euc-jp'\n    ja 'Blue',   '',     'euc-jp'\n    ja 'Color',  '', 'euc-jp'\n    ja 'Delete', 'õ',   'euc-jp'\n    ja 'Error',  '顼', 'euc-jp'\n    ja 'Exit',   'λ',   'euc-jp'\n    ja 'Green',  '',     'euc-jp'\n    ja 'Red',    '',     'euc-jp'\n    ja 'blue',   '',     'euc-jp'\n    ja 'green',  '',     'euc-jp'\n    ja 'red',    '',     'euc-jp'\n}\n\nTkMsgCatalog.new('::tk') {\n    ja \"&Abort\", '', 'euc-jp'\n    ja \"About...\"\n    ja \"All Files\", '٤ƤΥե', 'euc-jp'\n    ja \"Application Error\", 'ץꥱ󥨥顼', 'euc-jp'\n    ja \"&Blue\", '', 'euc-jp'\n    ja \"&Cancel\", 'ä', 'euc-jp'\n    ja \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\", \"ǥ쥯ȥ \\\"%1\\$s\\\" ѹǤޤ\\nĤޤ\", 'euc-jp'\n    ja \"Choose Directory\", 'ǥ쥯ȥ', 'euc-jp'\n    ja \"Clear\", 'õ', 'euc-jp'\n    ja \"Color\", '', 'euc-jp'\n    ja \"Console\", '󥽡', 'euc-jp'\n    ja \"Copy\", 'ԡ', 'euc-jp'\n    ja \"Cut\", 'ڤ', 'euc-jp'\n    ja \"Delete\", 'õ', 'euc-jp'\n    ja \"Details >>\", 'ܺ >>', 'euc-jp'\n    ja \"Directory \\\"%1\\$s\\\" does not exist.\", '\"%1$s\" Ȥǥ쥯ȥ¸ߤޤ', 'euc-jp'\n    ja \"&Directory:\", 'ǥ쥯ȥ', 'euc-jp'\n    ja \"Error: %1\\$s\"\n    ja \"Exit\", 'λ', 'euc-jp'\n    ja \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\", \"\\\"%1\\$s\\\" Ȥեϴ¸ߤƤޤ\\n񤭴ޤ\", 'euc-jp'\n    ja \"File \\\"%1\\$s\\\" already exists.\\n\\n\", \"\\\"%1\\$s\\\" Ȥեϴ¸ߤƤޤ\\n\\n\", 'euc-jp'\n    ja \"File \\\"%1\\$s\\\" does not exist.\", '\"%1$s\" Ȥե¸ߤޤ', 'euc-jp'\n    ja \"File &name:\", 'ե̾', 'euc-jp'\n    ja \"File &names:\", 'ե̾', 'euc-jp'\n    ja \"Files of &type:\", 'ե', 'euc-jp'\n    ja \"Fi&les:\", 'ե', 'euc-jp'\n    ja \"&Filter\", 'ե륿', 'euc-jp'\n    ja \"Fil&ter:\", 'ե륿', 'euc-jp'\n    ja \"&Green\", '', 'euc-jp'\n    ja \"Hi\", 'ˤ', 'euc-jp'\n    ja \"Hide Console\", '󥽡򱣤', 'euc-jp'\n    ja \"&Ignore\", '̵', 'euc-jp'\n    ja \"Invalid file name \\\"%1\\$s\\\".\", '\"%1$s\" ʥե̾Ǥ', 'euc-jp'\n    ja \"Log Files\", 'ե', 'euc-jp'\n    ja \"&No\", '', 'euc-jp'\n    ja \"&OK\", 'λ', 'euc-jp'\n    ja \"OK\", 'λ', 'euc-jp'\n    ja \"Ok\", 'λ', 'euc-jp'\n    ja \"Open\", '', 'euc-jp'\n    ja \"&Open\", '', 'euc-jp'\n    ja \"Open Multiple Files\", 'ʣΥե򳫤', 'euc-jp'\n    ja \"Paste\", 'Žդ', 'euc-jp'\n    ja \"Quit\", 'λ', 'euc-jp'\n    ja \"&Red\", '', 'euc-jp'\n    ja \"Replace existing file?\", '¸Υե֤ޤ', 'euc-jp'\n    ja \"&Retry\", 'Ƽ¹', 'euc-jp'\n    ja \"&Save\", '¸', 'euc-jp'\n    ja \"Save As\", '̾դ¸', 'euc-jp'\n    ja \"Save To Log\", '¸', 'euc-jp'\n    ja \"Select Log File\", 'ե', 'euc-jp'\n    ja \"Select a file to source\", 'ե', 'euc-jp'\n    ja \"&Selection:\", '', 'euc-jp'\n    ja \"Skip Messages\", 'åȤФ', 'euc-jp'\n    ja \"Source...\", '...', 'euc-jp'\n    ja \"Tcl Scripts\", 'Tcl ץ', 'euc-jp'\n    ja \"Tcl for Windows\"\n    ja \"Text Files\", 'ƥȥե', 'euc-jp'\n    ja \"&Yes\", 'Ϥ', 'euc-jp'\n    ja \"abort\", '', 'euc-jp'\n    ja \"blue\", '', 'euc-jp'\n    ja \"cancel\", 'ä', 'euc-jp'\n    ja \"extension\", 'ĥ', 'euc-jp'\n    ja \"extensions\", 'ĥ', 'euc-jp'\n    ja \"green\", '', 'euc-jp'\n    ja \"ignore\", '̵', 'euc-jp'\n    ja \"ok\", 'λ', 'euc-jp'\n    ja \"red\", '', 'euc-jp'\n    ja \"retry\", 'Ƽ¹', 'euc-jp'\n    ja \"yes\", 'Ϥ', 'euc-jp'\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/README",
    "content": "Almost all of Message-Catalog files in this directory are quoted \nfrom Tcl/Tk8.5a1 source archive (only a little are modified for\n'tkmsgcat-load_tk.rb'). Please read the file 'license.terms' in\nthis directry (That was included in demo directory of Tcl/Tk8.5a1).\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/cs.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset cs \"Application Error\" \"Chyba programu\"\n    ::msgcat::mcset cs \"Blue\" \"Modr\\341\"\n    ::msgcat::mcset cs \"Color\" \"Barva\"\n    ::msgcat::mcset cs \"Delete\" \"Smazat\"\n    ::msgcat::mcset cs \"Error\" \"Chyba\"\n    ::msgcat::mcset cs \"Exit\" \"Konec\"\n    ::msgcat::mcset cs \"Green\" \"Zelen\\341\"\n    ::msgcat::mcset cs \"Red\" \"\\u010cerven\\341\"\n    ::msgcat::mcset cs \"blue\" \"modr\\341\"\n    ::msgcat::mcset cs \"green\" \"zelen\\341\"\n    ::msgcat::mcset cs \"red\" \"\\u010derven\\341\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset cs \"&Abort\" \"&P\\u0159eru\\u0161it\"\n    ::msgcat::mcset cs \"About...\" \"O programu...\"\n    ::msgcat::mcset cs \"All Files\" \"V\\u0161echny soubory\"\n    ::msgcat::mcset cs \"Application Error\" \"Chyba programu\"\n    ::msgcat::mcset cs \"&Blue\" \"&Modr\\341\"\n    ::msgcat::mcset cs \"&Cancel\" \"&Zru\\u0161it\"\n    ::msgcat::mcset cs \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Nemohu zm\\u011bnit atku\\341ln\\355 adres\\341\\u0159 na \\\"%1\\$s\\\".\\nP\\u0159\\355stup odm\\355tnut.\"\n    ::msgcat::mcset cs \"Choose Directory\" \"V\\375b\\u011br adres\\341\\u0159e\"\n    ::msgcat::mcset cs \"Clear\" \"Smazat\"\n    ::msgcat::mcset cs \"Color\" \"Barva\"\n    ::msgcat::mcset cs \"Console\" \"Konzole\"\n    ::msgcat::mcset cs \"Copy\" \"Kop\\355rovat\"\n    ::msgcat::mcset cs \"Cut\" \"Vy\\u0159\\355znout\"\n    ::msgcat::mcset cs \"Delete\" \"Smazat\"\n    ::msgcat::mcset cs \"Details >>\" \"Detaily >>\"\n    ::msgcat::mcset cs \"Directory \\\"%1\\$s\\\" does not exist.\" \"Adres\\341\\u0159 \\\"%1\\$s\\\" neexistuje.\"\n    ::msgcat::mcset cs \"&Directory:\" \"&Adres\\341\\u0159:\"\n    ::msgcat::mcset cs \"Error: %1\\$s\" \"Chyba: %1\\$s\"\n    ::msgcat::mcset cs \"Exit\" \"Konec\"\n    ::msgcat::mcset cs \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"Soubor \\\"%1\\$s\\\" ji\\u017e existuje.\\n\\n\"\n    ::msgcat::mcset cs \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"Soubor \\\"%1\\$s\\\" ji\\u017e existuje.\\nChcete jej p\\u0159epsat?\"\n    ::msgcat::mcset cs \"File \\\"%1\\$s\\\" does not exist.\" \"Soubor \\\"%1\\$s\\\" neexistuje.\"\n    ::msgcat::mcset cs \"File &name:\" \"&Jm\\351no souboru:\"\n    ::msgcat::mcset cs \"File &names:\" \"&Jm\\351na soubor\\u016f:\"\n    ::msgcat::mcset cs \"Files of &type:\" \"&Typy soubor\\u016f:\"\n    ::msgcat::mcset cs \"Fi&les:\" \"Sou&bory:\"\n    ::msgcat::mcset cs \"&Filter\" \"&Filtr\"\n    ::msgcat::mcset cs \"Fil&ter:\" \"Fil&tr:\"\n    ::msgcat::mcset cs \"&Green\" \"Ze&len\\341\"\n    ::msgcat::mcset cs \"Hi\"\n    ::msgcat::mcset cs \"Hide Console\" \"Skr\\375t konsolu\"\n    ::msgcat::mcset cs \"&Ignore\" \"&Ignorovat\"\n    ::msgcat::mcset cs \"Invalid file name \\\"%1\\$s\\\".\" \"\\u0160patn\\351 jm\\351no souboru \\\"%1\\$s\\\".\"\n    ::msgcat::mcset cs \"Log Files\" \"Log soubory\"\n    ::msgcat::mcset cs \"&No\" \"&Ne\"\n    ::msgcat::mcset cs \"&OK\"\n    ::msgcat::mcset cs \"Ok\"\n    ::msgcat::mcset cs \"Open\" \"Otev\\u0159\\355t\"\n    ::msgcat::mcset cs \"&Open\" \"&Otev\\u0159\\355t\"\n    ::msgcat::mcset cs \"Open Multiple Files\" \"Otev\\u0159\\355t v\\355ce soubor\\u016f\"\n    ::msgcat::mcset cs \"Paste\" \"Vlo\\u017eit\"\n    ::msgcat::mcset cs \"Quit\" \"Skon\\u010dit\"\n    ::msgcat::mcset cs \"&Red\" \" \\u010ce&rven\\341\"\n    ::msgcat::mcset cs \"Replace existing file?\" \"Nahradit st\\341vaj\\355c\\355 soubor?\"\n    ::msgcat::mcset cs \"&Retry\" \"Z&novu\"\n    ::msgcat::mcset cs \"&Save\" \"&Ulo\\u017eit\"\n    ::msgcat::mcset cs \"Save As\" \"Ulo\\u017eit jako\"\n    ::msgcat::mcset cs \"Save To Log\" \"Ulo\\u017eit do logu\"\n    ::msgcat::mcset cs \"Select Log File\" \"Vybrat log soubor\"\n    ::msgcat::mcset cs \"Select a file to source\" \"Vybrat soubor k nahr\\341n\\355\"\n    ::msgcat::mcset cs \"&Selection:\" \"&V\\375b\\u011br:\"\n    ::msgcat::mcset cs \"Skip Messages\" \"P\\u0159esko\\u010dit zpr\\341vy\"\n    ::msgcat::mcset cs \"Source...\" \"Nahr\\341t...\"\n    ::msgcat::mcset cs \"Tcl Scripts\" \"Tcl skripty\"\n    ::msgcat::mcset cs \"Tcl for Windows\" \"Tcl pro Windows\"\n    ::msgcat::mcset cs \"Text Files\" \"Textov\\351 soubory\"\n    ::msgcat::mcset cs \"&Yes\" \"&Ano\"\n    ::msgcat::mcset cs \"abort\" \"p\\u0159eru\\u0161it\"\n    ::msgcat::mcset cs \"blue\" \"modr\\341\"\n    ::msgcat::mcset cs \"cancel\" \"zru\\u0161it\"\n    ::msgcat::mcset cs \"extension\" \"p\\u0159\\355pona\"\n    ::msgcat::mcset cs \"extensions\" \"p\\u0159\\355pony\"\n    ::msgcat::mcset cs \"green\" \"zelen\\341\"\n    ::msgcat::mcset cs \"ignore\" \"ignorovat\"\n    ::msgcat::mcset cs \"ok\"\n    ::msgcat::mcset cs \"red\" \"\\u010derven\\341\"\n    ::msgcat::mcset cs \"retry\" \"znovu\"\n    ::msgcat::mcset cs \"yes\" \"ano\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/de.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset de \"Application Error\" \"Applikationsfehler\"\n    ::msgcat::mcset de \"Blue\" \"Blau\"\n    ::msgcat::mcset de \"Color\" \"Farbe\"\n    ::msgcat::mcset de \"Delete\" \"L\\u00f6schen\"\n    ::msgcat::mcset de \"Error\" \"Fehler\"\n    ::msgcat::mcset de \"Exit\" \"Ende\"\n    ::msgcat::mcset de \"Green\" \"Gr\\u00fcn\"\n    ::msgcat::mcset de \"Red\" \"Rot\"\n    ::msgcat::mcset de \"blue\" \"blau\"\n    ::msgcat::mcset de \"green\" \"gr\\u00fcn\"\n    ::msgcat::mcset de \"red\" \"rot\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset de \"&Abort\" \"&Abbruch\"\n    ::msgcat::mcset de \"&About...\" \"&\\u00dcber...\"\n    ::msgcat::mcset de \"All Files\" \"Alle Dateien\"\n    ::msgcat::mcset de \"Application Error\" \"Applikationsfehler\"\n    ::msgcat::mcset de \"&Blue\" \"&Blau\"\n    ::msgcat::mcset de \"&Cancel\" \"&Abbruch\"\n    ::msgcat::mcset de \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Kann nicht in das Verzeichnis \\\"%1\\$s\\\" wechseln.\\nKeine Rechte vorhanden.\"\n    ::msgcat::mcset de \"Choose Directory\" \"W\\u00e4hle Verzeichnis\"\n    ::msgcat::mcset de \"&Clear\" \"&R\\u00fccksetzen\"\n    ::msgcat::mcset de \"&Clear Console\" \"&Konsole l\\u00f6schen\"\n    ::msgcat::mcset de \"Color\" \"Farbe\"\n    ::msgcat::mcset de \"Console\" \"Konsole\"\n    ::msgcat::mcset de \"&Copy\" \"&Kopieren\"\n    ::msgcat::mcset de \"Cu&t\" \"Aus&schneiden\"\n    ::msgcat::mcset de \"&Delete\" \"&L\\u00f6schen\"\n    ::msgcat::mcset de \"Details >>\"\n    ::msgcat::mcset de \"Directory \\\"%1\\$s\\\" does not exist.\" \"Das Verzeichnis \\\"%1\\$s\\\" existiert nicht.\"\n    ::msgcat::mcset de \"&Directory:\" \"&Verzeichnis:\"\n    ::msgcat::mcset de \"&Edit\" \"&Bearbieten\"\n    ::msgcat::mcset de \"Error: %1\\$s\" \"Fehler: %1\\$s\"\n    ::msgcat::mcset de \"E&xit\" \"&Ende\"\n    ::msgcat::mcset de \"&File\" \"&Datei\"\n    ::msgcat::mcset de \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"Die Datei \\\"%1\\$s\\\" ist bereits vorhanden.\\nWollen sie diese Datei \\u00fcberschreiben ?\"\n    ::msgcat::mcset de \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"Die Datei \\\"%1\\$s\\\" ist bereits vorhanden.\\n\\n\"\n    ::msgcat::mcset de \"File \\\"%1\\$s\\\" does not exist.\" \"Die Datei \\\"%1\\$s\\\" existiert nicht.\"\n    ::msgcat::mcset de \"File &name:\" \"Datei&name:\"\n    ::msgcat::mcset de \"File &names:\" \"Datei&namen:\"\n    ::msgcat::mcset de \"Files of &type:\" \"Dateien des &Typs:\"\n    ::msgcat::mcset de \"Fi&les:\" \"Dat&eien:\"\n    ::msgcat::mcset de \"&Filter\"\n    ::msgcat::mcset de \"Fil&ter:\"\n    ::msgcat::mcset de \"&Green\" \"&Gr\\u00fcn\"\n    ::msgcat::mcset de \"&Help\" \"&Hilfe\"\n    ::msgcat::mcset de \"Hi\" \"Hallo\"\n    ::msgcat::mcset de \"&Hide Console\" \"&Konsole unsichtbar machen\"\n    ::msgcat::mcset de \"&Ignore\" \"&Ignorieren\"\n    ::msgcat::mcset de \"Invalid file name \\\"%1\\$s\\\".\" \"Ung\\u00fcltiger Dateiname \\\"%1\\$s\\\".\"\n    ::msgcat::mcset de \"Log Files\" \"Protokolldatei\"\n    ::msgcat::mcset de \"&No\" \"&Nein\"\n    ::msgcat::mcset de \"OK\"\n    ::msgcat::mcset de \"Ok\"\n    ::msgcat::mcset de \"Open\" \"\\u00d6ffnen\"\n    ::msgcat::mcset de \"&Open\" \"\\u00d6&ffnen\"\n    ::msgcat::mcset de \"Open Multiple Files\"\n    ::msgcat::mcset de \"P&aste\" \"E&inf\\u00fcgen\"\n    ::msgcat::mcset de \"&Quit\" \"&Beenden\"\n    ::msgcat::mcset de \"&Red\" \"&Rot\"\n    ::msgcat::mcset de \"Replace existing file?\" \"Existierende Datei ersetzen?\"\n    ::msgcat::mcset de \"&Retry\" \"&Wiederholen\"\n    ::msgcat::mcset de \"&Save\" \"&Speichern\"\n    ::msgcat::mcset de \"Save As\" \"Speichern unter\"\n    ::msgcat::mcset de \"Save To Log\" \"In Protokoll speichern\"\n    ::msgcat::mcset de \"Select Log File\" \"Protokolldatei ausw\\u00e4hlen\"\n    ::msgcat::mcset de \"Select a file to source\" \"Auszuf\\u00fchrende Datei ausw\\u00e4hlen\"\n    ::msgcat::mcset de \"&Selection:\" \"Auswah&l:\"\n    ::msgcat::mcset de \"Skip Messages\" \"Weitere Nachrichten \\u00fcberspringen\"\n    ::msgcat::mcset de \"&Source...\" \"&Ausf\\u00fchren...\"\n    ::msgcat::mcset de \"Tcl Scripts\" \"Tcl-Skripte\"\n    ::msgcat::mcset de \"Tcl for Windows\" \"Tcl f\\u00fcr Windows\"\n    ::msgcat::mcset de \"Text Files\" \"Textdateien\"\n    ::msgcat::mcset de \"&Yes\" \"&Ja\"\n    ::msgcat::mcset de \"abort\" \"abbrechen\"\n    ::msgcat::mcset de \"blue\" \"blau\"\n    ::msgcat::mcset de \"cancel\" \"abbrechen\"\n    ::msgcat::mcset de \"extension\" \"Erweiterung\"\n    ::msgcat::mcset de \"extensions\" \"Erweiterungen\"\n    ::msgcat::mcset de \"green\" \"gr\\u00fcn\"\n    ::msgcat::mcset de \"ignore\" \"ignorieren\"\n    ::msgcat::mcset de \"ok\"\n    ::msgcat::mcset de \"red\" \"rot\"\n    ::msgcat::mcset de \"retry\" \"wiederholen\"\n    ::msgcat::mcset de \"yes\" \"ja\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/el.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset el \"Application Error\"  \"\\u039b\\u03ac\\u03b8\\u03bf\\u03c2 \\u0395\\u03c6\\u03b1\\u03c1\\u03bc\\u03bf\\u03b3\\u03ae\\u03c2\"\n    ::msgcat::mcset el \"Blue\"     \"\\u039c\\u03c0\\u03bb\\u03b5\"\n    ::msgcat::mcset el \"Color\"    \"\\u03a7\\u03c1\\u03ce\\u03bc\\u03b1\"\n    ::msgcat::mcset el \"Delete\"   \"\\u0394\\u03b9\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\"\n    ::msgcat::mcset el \"Error\"\t  \"\\u039b\\u03ac\\u03b8\\u03bf\\u03c2\"\n    ::msgcat::mcset el \"Exit\"     \"\\u0388\\u03be\\u03bf\\u03b4\\u03bf\\u03c2\"\n    ::msgcat::mcset el \"Green\"    \"\\u03a0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"Red\"      \"\\u039a\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"blue\"     \"\\u03bc\\u03c0\\u03bb\\u03b5\"\n    ::msgcat::mcset el \"green\"    \"\\u03c0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"red\"      \"\\u03ba\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf\"\n}\n\n\n# followings are same to original file included into Tk8.5a1's widget demos. \n\n## Messages for the Greek (Hellenic - \"el\") language.\n## Please report any changes/suggestions to:\n##    petasis@iit.demokritos.gr\n\nnamespace eval ::tk {\n    ::msgcat::mcset el \"&Abort\"              \"\\u03a4\\u03b5\\u03c1\\u03bc\\u03b1\\u03c4\\u03b9\\u03c3\\u03bc\\u03cc\\u03c2\"\n    ::msgcat::mcset el \"About...\"           \"\\u03a3\\u03c7\\u03b5\\u03c4\\u03b9\\u03ba\\u03ac...\"\n    ::msgcat::mcset el \"All Files\"          \"\\u038c\\u03bb\\u03b1 \\u03c4\\u03b1 \\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1\"\n    ::msgcat::mcset el \"Application Error\"  \"\\u039b\\u03ac\\u03b8\\u03bf\\u03c2 \\u0395\\u03c6\\u03b1\\u03c1\\u03bc\\u03bf\\u03b3\\u03ae\\u03c2\"\n    ::msgcat::mcset el \"&Blue\"               \"\\u039c\\u03c0\\u03bb\\u03b5\"\n    ::msgcat::mcset el \"&Cancel\"             \"\\u0391\\u03ba\\u03cd\\u03c1\\u03c9\\u03c3\\u03b7\"\n    ::msgcat::mcset el \\\n\"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \\\n\"\\u0394\\u03b5\\u03bd \\u03b5\\u03af\\u03bd\\u03b1\\u03b9 \\u03b4\\u03c5\\u03bd\\u03b1\\u03c4\\u03ae \\u03b7 \\u03b1\\u03bb\\u03bb\\u03b1\\u03b3\\u03ae \\u03ba\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5 \\u03c3\\u03b5 \\\"%1\\$s\\\".\\n\\u0397 \\u03c0\\u03c1\\u03cc\\u03c3\\u03b2\\u03b1\\u03c3\\u03b7 \\u03b4\\u03b5\\u03bd \\u03b5\\u03c0\\u03b9\\u03c4\\u03c1\\u03ad\\u03c0\\u03b5\\u03c4\\u03b1\\u03b9.\"\n    ::msgcat::mcset el \"Choose Directory\"   \"\\u0395\\u03c0\\u03b9\\u03bb\\u03bf\\u03b3\\u03ae \\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03cc\\u03b3\\u03bf\\u03c5\"\n    ::msgcat::mcset el \"Clear\"              \"\\u039a\\u03b1\\u03b8\\u03b1\\u03c1\\u03b9\\u03c3\\u03bc\\u03cc\\u03c2\"\n    ::msgcat::mcset el \"Color\"              \"\\u03a7\\u03c1\\u03ce\\u03bc\\u03b1\"\n    ::msgcat::mcset el \"Console\"            \"\\u039a\\u03bf\\u03bd\\u03c3\\u03cc\\u03bb\\u03b1\"\n    ::msgcat::mcset el \"Copy\"               \"\\u0391\\u03bd\\u03c4\\u03b9\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\"\n    ::msgcat::mcset el \"Cut\"                \"\\u0391\\u03c0\\u03bf\\u03ba\\u03bf\\u03c0\\u03ae\"\n    ::msgcat::mcset el \"Delete\"             \"\\u0394\\u03b9\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\"\n    ::msgcat::mcset el \"Details >>\"         \"\\u039b\\u03b5\\u03c0\\u03c4\\u03bf\\u03bc\\u03ad\\u03c1\\u03b5\\u03b9\\u03b5\\u03c2 >>\"\n    ::msgcat::mcset el \"Directory \\\"%1\\$s\\\" does not exist.\" \\\n                                        \"\\u039f \\u03ba\\u03b1\\u03c4\\u03ac\\u03bb\\u03bf\\u03b3\\u03bf\\u03c2 \\\"%1\\$s\\\" \\u03b4\\u03b5\\u03bd \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.\"\n    ::msgcat::mcset el \"&Directory:\"         \"&\\u039a\\u03b1\\u03c4\\u03ac\\u03bb\\u03bf\\u03b3\\u03bf\\u03c2:\"\n    ::msgcat::mcset el \"Error: %1\\$s\"       \"\\u039b\\u03ac\\u03b8\\u03bf\\u03c2: %1\\$s\"\n    ::msgcat::mcset el \"Exit\"               \"\\u0388\\u03be\\u03bf\\u03b4\\u03bf\\u03c2\"\n    ::msgcat::mcset el \\\n               \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \\\n               \"\\u03a4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\\"%1\\$s\\\" \\u03ae\\u03b4\\u03b7 \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.\\n\\u0398\\u03ad\\u03bb\\u03b5\\u03c4\\u03b5 \\u03bd\\u03b1 \\u03b5\\u03c0\\u03b9\\u03ba\\u03b1\\u03bb\\u03c5\\u03c6\\u03b8\\u03b5\\u03af;\"\n    ::msgcat::mcset el \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \\\n                   \"\\u03a4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\\"%1\\$s\\\" \\u03ae\\u03b4\\u03b7 \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.\\n\\n\"\n    ::msgcat::mcset el \"File \\\"%1\\$s\\\" does not exist.\" \\\n                   \"\\u03a4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\\"%1\\$s\\\" \\u03b4\\u03b5\\u03bd \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03b5\\u03b9.\"\n    ::msgcat::mcset el \"File &name:\"         \"\\u038c&\\u03bd\\u03bf\\u03bc\\u03b1 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5:\"\n    ::msgcat::mcset el \"File &names:\"        \"\\u038c&\\u03bd\\u03bf\\u03bc\\u03b1 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03c9\\u03bd:\"\n    ::msgcat::mcset el \"Files of &type:\"     \"\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1 \\u03c4\\u03bf\\u03c5 &\\u03c4\\u03cd\\u03c0\\u03bf\\u03c5:\"\n    ::msgcat::mcset el \"Fi&les:\"             \"\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1:\"\n    ::msgcat::mcset el \"&Filter\"             \"\\u03a6\\u03af\\u03bb\\u03c4\\u03c1\\u03bf\"\n    ::msgcat::mcset el \"Fil&ter:\"            \"\\u03a6\\u03af\\u03bb\\u03c4\\u03c1\\u03bf:\"\n    ::msgcat::mcset el \"&Green\"              \"\\u03a0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"Hi\"                 \"\\u0393\\u03b5\\u03b9\\u03b1\"\n    ::msgcat::mcset el \"Hide Console\"       \"\\u0391\\u03c0\\u03cc\\u03ba\\u03c1\\u03c5\\u03c8\\u03b7 \\u03ba\\u03bf\\u03bd\\u03c3\\u03cc\\u03bb\\u03b1\\u03c2\"\n    ::msgcat::mcset el \"&Ignore\"             \"\\u0391\\u03b3\\u03bd\\u03cc\\u03b7\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"Invalid file name \\\"%1\\$s\\\".\" \\\n                   \"\\u0386\\u03ba\\u03c5\\u03c1\\u03bf \\u03cc\\u03bd\\u03bf\\u03bc\\u03b1 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5 \\\"%1\\$s\\\".\"\n    ::msgcat::mcset el \"Log Files\"          \"\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1 \\u039a\\u03b1\\u03c4\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\\u03c2\"\n    ::msgcat::mcset el \"&No\"                 \"\\u038c\\u03c7\\u03b9\"\n    ::msgcat::mcset el \"&OK\"                 \"\\u0395\\u03bd\\u03c4\\u03ac\\u03be\\u03b5\\u03b9\"\n    ::msgcat::mcset el \"&Ok\"                 \"\\u0395\\u03bd\\u03c4\\u03ac\\u03be\\u03b5\\u03b9\"\n    ::msgcat::mcset el \"Open\"               \"\\u0386\\u03bd\\u03bf\\u03b9\\u03b3\\u03bc\\u03b1\"\n    ::msgcat::mcset el \"&Open\"               \"\\u0386\\u03bd\\u03bf\\u03b9\\u03b3\\u03bc\\u03b1\"\n    ::msgcat::mcset el \"Open Multiple Files\" \\\n                                        \"\\u0386\\u03bd\\u03bf\\u03b9\\u03b3\\u03bc\\u03b1 \\u03c0\\u03bf\\u03bb\\u03bb\\u03b1\\u03c0\\u03bb\\u03ce\\u03bd \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03c9\\u03bd\"\n    ::msgcat::mcset el \"Paste\"              \"\\u0395\\u03c0\\u03b9\\u03ba\\u03cc\\u03bb\\u03bb\\u03b7\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"Quit\"               \"\\u0388\\u03be\\u03bf\\u03b4\\u03bf\\u03c2\"\n    ::msgcat::mcset el \"&Red\"                \"\\u039a\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"Replace existing file?\" \\\n                                        \"\\u0395\\u03c0\\u03b9\\u03ba\\u03ac\\u03bb\\u03c5\\u03c8\\u03b7 \\u03c5\\u03c0\\u03ac\\u03c1\\u03c7\\u03bf\\u03bd\\u03c4\\u03bf\\u03c2 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5;\"\n    ::msgcat::mcset el \"&Retry\"              \"\\u03a0\\u03c1\\u03bf\\u03c3\\u03c0\\u03ac\\u03b8\\u03b7\\u03c3\\u03b5 \\u03be\\u03b1\\u03bd\\u03ac\"\n    ::msgcat::mcset el \"&Save\"               \"\\u0391\\u03c0\\u03bf\\u03b8\\u03ae\\u03ba\\u03b5\\u03c5\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"Save As\"            \"\\u0391\\u03c0\\u03bf\\u03b8\\u03ae\\u03ba\\u03b5\\u03c5\\u03c3\\u03b7 \\u03c3\\u03b1\\u03bd\"\n    ::msgcat::mcset el \"Save To Log\"        \"\\u0391\\u03c0\\u03bf\\u03b8\\u03ae\\u03ba\\u03b5\\u03c5\\u03c3\\u03b7 \\u03c3\\u03c4\\u03bf \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\u03ba\\u03b1\\u03c4\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\\u03c2\"\n    ::msgcat::mcset el \"Select Log File\"    \"\\u0395\\u03c0\\u03b9\\u03bb\\u03bf\\u03b3\\u03ae \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf\\u03c5 \\u03ba\\u03b1\\u03c4\\u03b1\\u03b3\\u03c1\\u03b1\\u03c6\\u03ae\\u03c2\"\n    ::msgcat::mcset el \"Select a file to source\" \\\n                                        \"\\u0395\\u03c0\\u03b9\\u03bb\\u03ad\\u03be\\u03c4\\u03b5 \\u03b1\\u03c1\\u03c7\\u03b5\\u03af\\u03bf \\u03b3\\u03b9\\u03b1 \\u03b5\\u03ba\\u03c4\\u03ad\\u03bb\\u03b5\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"&Selection:\"         \"\\u0395\\u03c0\\u03b9\\u03bb\\u03bf\\u03b3\\u03ae:\"\n    ::msgcat::mcset el \"Skip Messages\"      \"\\u0391\\u03c0\\u03bf\\u03c6\\u03c5\\u03b3\\u03ae \\u03bc\\u03c5\\u03bd\\u03b7\\u03bc\\u03ac\\u03c4\\u03c9\\u03bd\"\n    ::msgcat::mcset el \"Source...\"          \"\\u0395\\u03ba\\u03c4\\u03ad\\u03bb\\u03b5\\u03c3\\u03b7...\"\n    ::msgcat::mcset el \"Tcl Scripts\"        \"Tcl Scripts\"\n    ::msgcat::mcset el \"Tcl for Windows\"    \"Tcl \\u03b3\\u03b9\\u03b1 Windows\"\n    ::msgcat::mcset el \"Text Files\"         \"\\u0391\\u03c1\\u03c7\\u03b5\\u03af\\u03b1 \\u039a\\u03b5\\u03b9\\u03bc\\u03ad\\u03bd\\u03bf\\u03c5\"\n    ::msgcat::mcset el \"&Yes\"                \"\\u039d\\u03b1\\u03b9\"\n    ::msgcat::mcset el \"abort\"              \"\\u03c4\\u03b5\\u03c1\\u03bc\\u03b1\\u03c4\\u03b9\\u03c3\\u03bc\\u03cc\\u03c2\"\n    ::msgcat::mcset el \"blue\"               \"\\u03bc\\u03c0\\u03bb\\u03b5\"\n    ::msgcat::mcset el \"cancel\"             \"\\u03b1\\u03ba\\u03cd\\u03c1\\u03c9\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"extension\"          \"\\u03b5\\u03c0\\u03ad\\u03ba\\u03c4\\u03b1\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"extensions\"         \"\\u03b5\\u03c0\\u03b5\\u03ba\\u03c4\\u03ac\\u03c3\\u03b5\\u03b9\\u03c2\"\n    ::msgcat::mcset el \"green\"              \"\\u03c0\\u03c1\\u03ac\\u03c3\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"ignore\"             \"\\u03b1\\u03b3\\u03bd\\u03cc\\u03b7\\u03c3\\u03b7\"\n    ::msgcat::mcset el \"ok\"                 \"\\u03b5\\u03bd\\u03c4\\u03ac\\u03be\\u03b5\\u03b9\"\n    ::msgcat::mcset el \"red\"                \"\\u03ba\\u03cc\\u03ba\\u03ba\\u03b9\\u03bd\\u03bf\"\n    ::msgcat::mcset el \"retry\"              \"\\u03c0\\u03c1\\u03bf\\u03c3\\u03c0\\u03ac\\u03b8\\u03b7\\u03c3\\u03b5 \\u03be\\u03b1\\u03bd\\u03ac\"\n    ::msgcat::mcset el \"yes\"                \"\\u03bd\\u03b1\\u03b9\"\n}\n\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/en.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset en \"Application Error\"\n    ::msgcat::mcset en \"Blue\"\n    ::msgcat::mcset en \"Color\"\n    ::msgcat::mcset en \"Delete\"\n    ::msgcat::mcset en \"Error\"\n    ::msgcat::mcset en \"Green\"\n    ::msgcat::mcset en \"Red\"\n    ::msgcat::mcset en \"blue\"\n    ::msgcat::mcset en \"green\"\n    ::msgcat::mcset en \"red\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset en \"&Abort\"\n    ::msgcat::mcset en \"About...\"\n    ::msgcat::mcset en \"All Files\"\n    ::msgcat::mcset en \"Application Error\"\n    ::msgcat::mcset en \"&Blue\"\n    ::msgcat::mcset en \"&Cancel\"\n    ::msgcat::mcset en \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\"\n    ::msgcat::mcset en \"Choose Directory\"\n    ::msgcat::mcset en \"Clear\"\n    ::msgcat::mcset en \"Color\"\n    ::msgcat::mcset en \"Console\"\n    ::msgcat::mcset en \"Copy\"\n    ::msgcat::mcset en \"Cut\"\n    ::msgcat::mcset en \"Delete\"\n    ::msgcat::mcset en \"Details >>\"\n    ::msgcat::mcset en \"Directory \\\"%1\\$s\\\" does not exist.\"\n    ::msgcat::mcset en \"&Directory:\"\n    ::msgcat::mcset en \"Error: %1\\$s\"\n    ::msgcat::mcset en \"Exit\"\n    ::msgcat::mcset en \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\"\n    ::msgcat::mcset en \"File \\\"%1\\$s\\\" already exists.\\n\\n\"\n    ::msgcat::mcset en \"File \\\"%1\\$s\\\" does not exist.\"\n    ::msgcat::mcset en \"File &name:\"\n    ::msgcat::mcset en \"File &names:\"\n    ::msgcat::mcset en \"Files of &type:\"\n    ::msgcat::mcset en \"Fi&les:\"\n    ::msgcat::mcset en \"&Filter\"\n    ::msgcat::mcset en \"Fil&ter:\"\n    ::msgcat::mcset en \"&Green\"\n    ::msgcat::mcset en \"Hi\"\n    ::msgcat::mcset en \"Hide Console\"\n    ::msgcat::mcset en \"&Ignore\"\n    ::msgcat::mcset en \"Invalid file name \\\"%1\\$s\\\".\"\n    ::msgcat::mcset en \"Log Files\"\n    ::msgcat::mcset en \"&No\"\n    ::msgcat::mcset en \"&OK\"\n    ::msgcat::mcset en \"Ok\"\n    ::msgcat::mcset en \"Open\"\n    ::msgcat::mcset en \"&Open\"\n    ::msgcat::mcset en \"Open Multiple Files\"\n    ::msgcat::mcset en \"Paste\"\n    ::msgcat::mcset en \"Quit\"\n    ::msgcat::mcset en \"&Red\"\n    ::msgcat::mcset en \"Replace existing file?\"\n    ::msgcat::mcset en \"&Retry\"\n    ::msgcat::mcset en \"&Save\"\n    ::msgcat::mcset en \"Save As\"\n    ::msgcat::mcset en \"Save To Log\"\n    ::msgcat::mcset en \"Select Log File\"\n    ::msgcat::mcset en \"Select a file to source\"\n    ::msgcat::mcset en \"&Selection:\"\n    ::msgcat::mcset en \"Skip Messages\"\n    ::msgcat::mcset en \"Source...\"\n    ::msgcat::mcset en \"Tcl Scripts\"\n    ::msgcat::mcset en \"Tcl for Windows\"\n    ::msgcat::mcset en \"Text Files\"\n    ::msgcat::mcset en \"&Yes\"\n    ::msgcat::mcset en \"abort\"\n    ::msgcat::mcset en \"blue\"\n    ::msgcat::mcset en \"cancel\"\n    ::msgcat::mcset en \"extension\"\n    ::msgcat::mcset en \"extensions\"\n    ::msgcat::mcset en \"green\"\n    ::msgcat::mcset en \"ignore\"\n    ::msgcat::mcset en \"ok\"\n    ::msgcat::mcset en \"red\"\n    ::msgcat::mcset en \"retry\"\n    ::msgcat::mcset en \"yes\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/en_gb.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset en_gb Color Colour\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset en_gb Color Colour\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/eo.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset eo \"Application Error\" \"Aplikoerraro\"\n    ::msgcat::mcset eo \"Blue\" \"Blua\"\n    ::msgcat::mcset eo \"Color\" \"Farbo\"\n    ::msgcat::mcset eo \"Delete\" \"Forprenu\"\n    ::msgcat::mcset eo \"Error\" \"Eraro\"\n    ::msgcat::mcset eo \"Exit\" \"Eliru\"\n    ::msgcat::mcset eo \"Green\" \"Verda\"\n    ::msgcat::mcset eo \"Red\" \"Rosa\"\n    ::msgcat::mcset eo \"blue\" \"blua\"\n    ::msgcat::mcset eo \"green\" \"verda\"\n    ::msgcat::mcset eo \"red\" \"ru\\u011da\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset eo \"&Abort\" \"&\\u0108esigo\"\n    ::msgcat::mcset eo \"&About...\" \"Pri...\"\n    ::msgcat::mcset eo \"All Files\" \"\\u0108ioj dosieroj\"\n    ::msgcat::mcset eo \"Application Error\" \"Aplikoerraro\"\n    ::msgcat::mcset eo \"&Blue\" \"&Blua\"\n    ::msgcat::mcset eo \"&Cancel\" \"&Rezignu\"\n    ::msgcat::mcset eo \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Neeble \\u0109angi al dosierulon \\\"%1\\$s\\\".\\nVi ne rajtas tion.\"\n    ::msgcat::mcset eo \"Choose Directory\" \"Elektu Dosierujo\"\n    ::msgcat::mcset eo \"&Clear\" \"&Klaru\"\n    ::msgcat::mcset eo \"&Clear Console\" \"&Klaru konzolon\"\n    ::msgcat::mcset eo \"Color\" \"Farbo\"\n    ::msgcat::mcset eo \"Console\" \"Konzolo\"\n    ::msgcat::mcset eo \"&Copy\" \"&Kopiu\"\n    ::msgcat::mcset eo \"Cu&t\" \"&Enpo\\u015digu\"\n    ::msgcat::mcset eo \"&Delete\" \"&Forprenu\"\n    ::msgcat::mcset eo \"Details >>\" \"Detaloj >>\"\n    ::msgcat::mcset eo \"Directory \\\"%1\\$s\\\" does not exist.\" \"La dosierujo \\\"%1\\$s\\\" ne ekzistas.\"\n    ::msgcat::mcset eo \"&Directory:\" \"&Dosierujo:\"\n    ::msgcat::mcset eo \"&Edit\" \"&Redaktu\"\n    ::msgcat::mcset eo \"Error: %1\\$s\" \"Eraro: %1\\$s\"\n    ::msgcat::mcset eo \"E&xit\" \"&Eliru\"\n    ::msgcat::mcset eo \"&File\" \"&Dosiero\"\n    ::msgcat::mcset eo \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"La dosiero \\\"%1\\$s\\\" jam ekzistas.\\n\\u0108u vi volas anstata\\u00fbigi la dosieron?\"\n    ::msgcat::mcset eo \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"La dosiero \\\"%1\\$s\\\" jam egzistas. \\n\\n\"\n    ::msgcat::mcset eo \"File \\\"%1\\$s\\\" does not exist.\" \"La dosierp \\\"%1\\$s\\\" ne estas.\"\n    ::msgcat::mcset eo \"File &name:\" \"Dosiero&nomo:\"\n    ::msgcat::mcset eo \"File &names:\" \"Dosiero&nomoj:\"\n    ::msgcat::mcset eo \"Files of &type:\" \"Dosieroj de &Typo:\"\n    ::msgcat::mcset eo \"Fi&les:\" \"Do&sieroj:\"\n    ::msgcat::mcset eo \"&Filter\" \"&Filtrilo\"\n    ::msgcat::mcset eo \"Fil&ter:\" \"&Filtrilo:\"\n    ::msgcat::mcset eo \"&Green\" \"&Verda\"\n    ::msgcat::mcset eo \"&Help\" \"&Helpu\"\n    ::msgcat::mcset eo \"Hi\" \"Saluton\"\n    ::msgcat::mcset eo \"&Hide Console\" \"&Ka\\u015du konzolon\"\n    ::msgcat::mcset eo \"&Ignore\" \"&Ignoru\"\n    ::msgcat::mcset eo \"Invalid file name \\\"%1\\$s\\\".\" \"Malvalida dosieronomo \\\"%1\\$s\\\".\"\n    ::msgcat::mcset eo \"Log Files\" \"Protokolo\"\n    ::msgcat::mcset eo \"&No\" \"&Ne\"\n    ::msgcat::mcset eo \"OK\"\n    ::msgcat::mcset eo \"Ok\"\n    ::msgcat::mcset eo \"Open\" \"Malfermu\"\n    ::msgcat::mcset eo \"&Open\" \"&Malfermu\"\n    ::msgcat::mcset eo \"Open Multiple Files\" \"Melfermu multan dosierojn\"\n    ::msgcat::mcset eo \"P&aste\" \"&Elpo\\u015digi\"\n    ::msgcat::mcset eo \"&Quit\" \"&Finigu\"\n    ::msgcat::mcset eo \"&Red\" \"&Rosa\"\n    ::msgcat::mcset eo \"Replace existing file?\" \"\\u0108u anstata\\u00fbu ekzistantan dosieron?\"\n    ::msgcat::mcset eo \"&Retry\" \"&Ripetu\"\n    ::msgcat::mcset eo \"&Save\" \"&Savu\"\n    ::msgcat::mcset eo \"Save As\" \"Savu kiel\"\n    ::msgcat::mcset eo \"Save To Log\" \"Savu en protokolon\"\n    ::msgcat::mcset eo \"Select Log File\" \"Elektu prokolodosieron\"\n    ::msgcat::mcset eo \"Select a file to source\" \"Elektu dosieron por interpreti\"\n    ::msgcat::mcset eo \"&Selection:\" \"&Elekto:\"\n    ::msgcat::mcset eo \"Skip Messages\" \"transsaltu pluajn mesa\\u011dojn\"\n    ::msgcat::mcset eo \"&Source...\" \"&Fontoprogramo...\"\n    ::msgcat::mcset eo \"Tcl Scripts\" \"Tcl-skriptoj\"\n    ::msgcat::mcset eo \"Tcl for Windows\" \"Tcl por vindoso\"\n    ::msgcat::mcset eo \"Text Files\" \"Tekstodosierojn\"\n    ::msgcat::mcset eo \"&Yes\" \"&Jes\"\n    ::msgcat::mcset eo \"abort\" \"\\u0109esigo\"\n    ::msgcat::mcset eo \"blue\" \"blua\"\n    ::msgcat::mcset eo \"cancel\" \"rezignu\"\n    ::msgcat::mcset eo \"extension\" \"ekspansio\"\n    ::msgcat::mcset eo \"extensions\" \"ekspansioj\"\n    ::msgcat::mcset eo \"green\" \"verda\"\n    ::msgcat::mcset eo \"ignore\" \"ignorieren\"\n    ::msgcat::mcset eo \"red\" \"ru\\u011da\"\n    ::msgcat::mcset eo \"retry\" \"ripetu\"\n    ::msgcat::mcset eo \"yes\" \"jes\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/es.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset es \"Application Error\" \"Error de la aplicaci\\u00f3n\"\n    ::msgcat::mcset es \"Blue\" \"Azul\"\n    ::msgcat::mcset es \"Color\" \"Color\"\n    ::msgcat::mcset es \"Delete\" \"Borrar\"\n    ::msgcat::mcset es \"Error\" \"Error\"\n    ::msgcat::mcset es \"Exit\" \"Salir\"\n    ::msgcat::mcset es \"Green\" \"Verde\"\n    ::msgcat::mcset es \"Red\" \"Rojo\"\n    ::msgcat::mcset es \"blue\" \"azul\"\n    ::msgcat::mcset es \"green\" \"verde\"\n    ::msgcat::mcset es \"red\" \"rojo\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset es \"&Abort\" \"&Abortar\"\n    ::msgcat::mcset es \"About...\" \"Acerca de ...\"\n    ::msgcat::mcset es \"All Files\" \"Todos los archivos\"\n    ::msgcat::mcset es \"Application Error\" \"Error de la aplicaci\\u00f3n\"\n    ::msgcat::mcset es \"&Blue\" \"&Azul\"\n    ::msgcat::mcset es \"&Cancel\" \"&Cancelar\"\n    ::msgcat::mcset es \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"No es posible acceder al directorio \\\"%1\\$s\\\".\\nPermiso denegado.\"\n    ::msgcat::mcset es \"Choose Directory\" \"Elegir directorio\"\n    ::msgcat::mcset es \"Clear\" \"Borrar\"\n    ::msgcat::mcset es \"Color\" \"Color\"\n    ::msgcat::mcset es \"Console\" \"Consola\"\n    ::msgcat::mcset es \"Copy\" \"Copiar\"\n    ::msgcat::mcset es \"Cut\" \"Cortar\"\n    ::msgcat::mcset es \"Delete\" \"Borrar\"\n    ::msgcat::mcset es \"Details >>\" \"Detalles >>\"\n    ::msgcat::mcset es \"Directory \\\"%1\\$s\\\" does not exist.\" \"El directorio \\\"%1\\$s\\\" no existe.\"\n    ::msgcat::mcset es \"&Directory:\" \"&Directorio:\"\n    ::msgcat::mcset es \"Error: %1\\$s\" \"Error: %1\\$s\"\n    ::msgcat::mcset es \"Exit\" \"Salir\"\n    ::msgcat::mcset es \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"El archivo \\\"%1\\$s\\\" ya existe.\\nDesea sobreescribirlo?\"\n    ::msgcat::mcset es \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"El archivo \\\"%1\\$s\\\" ya existe.\\n\\n\"\n    ::msgcat::mcset es \"File \\\"%1\\$s\\\" does not exist.\" \"El archivo \\\"%1\\$s\\\" no existe.\"\n    ::msgcat::mcset es \"File &name:\" \"&Nombre de archivo:\"\n    ::msgcat::mcset es \"File &names:\" \"&Nombres de archivo:\"\n    ::msgcat::mcset es \"Files of &type:\" \"Archivos de &tipo:\"\n    ::msgcat::mcset es \"Fi&les:\" \"&Archivos:\"\n    ::msgcat::mcset es \"&Filter\" \"&Filtro\"\n    ::msgcat::mcset es \"Fil&ter:\" \"Fil&tro:\"\n    ::msgcat::mcset es \"&Green\" \"&Verde\"\n    ::msgcat::mcset es \"Hi\" \"Hola\"\n    ::msgcat::mcset es \"Hide Console\" \"Esconder la consola\"\n    ::msgcat::mcset es \"&Ignore\" \"&Ignorar\"\n    ::msgcat::mcset es \"Invalid file name \\\"%1\\$s\\\".\" \"Nombre de archivo inv\\u00e1lido \\\"%1\\$s\\\".\"\n    ::msgcat::mcset es \"Log Files\" \"Ficheros de traza\"\n    ::msgcat::mcset es \"&No\" \"&No\"\n    ::msgcat::mcset es \"&OK\" \"&OK\"\n    ::msgcat::mcset es \"Ok\" \"Ok\"\n    ::msgcat::mcset es \"Open\" \"Abrir\"\n    ::msgcat::mcset es \"&Open\" \"&Abrir\"\n    ::msgcat::mcset es \"Open Multiple Files\" \"Abrir m\\u00faltiples archivos\"\n    ::msgcat::mcset es \"Paste\" \"Pegar\"\n    ::msgcat::mcset es \"Quit\" \"Abandonar\"\n    ::msgcat::mcset es \"&Red\" \"&Rojo\"\n    ::msgcat::mcset es \"Replace existing file?\" \"Reemplazar el archivo existente?\"\n    ::msgcat::mcset es \"&Retry\" \"&Reintentar\"\n    ::msgcat::mcset es \"&Save\" \"&Salvar\"\n    ::msgcat::mcset es \"Save As\" \"Salvar como\"\n    ::msgcat::mcset es \"Save To Log\" \"Salvar al archivo de traza\"\n    ::msgcat::mcset es \"Select Log File\" \"Elegir un archivo de traza\"\n    ::msgcat::mcset es \"Select a file to source\" \"Seleccionar un archivo a evaluar\"\n    ::msgcat::mcset es \"&Selection:\" \"&Selecci\\u00f3n:\"\n    ::msgcat::mcset es \"Skip Messages\" \"Omitir los mensajes\"\n    ::msgcat::mcset es \"Source...\" \"Evaluar...\"\n    ::msgcat::mcset es \"Tcl Scripts\" \"Scripts Tcl\"\n    ::msgcat::mcset es \"Tcl for Windows\" \"Tcl para Windows\"\n    ::msgcat::mcset es \"Text Files\" \"Archivos de texto\"\n    ::msgcat::mcset es \"&Yes\" \"&S\\u00ed\" \n    ::msgcat::mcset es \"abort\" \"abortar\"\n    ::msgcat::mcset es \"blue\" \"azul\"\n    ::msgcat::mcset es \"cancel\" \"cancelar\"\n    ::msgcat::mcset es \"extension\" \"extensi\\u00f3n\"\n    ::msgcat::mcset es \"extensions\" \"extensiones\"\n    ::msgcat::mcset es \"green\" \"verde\"\n    ::msgcat::mcset es \"ignore\" \"ignorar\"\n    ::msgcat::mcset es \"ok\" \"ok\"\n    ::msgcat::mcset es \"red\" \"rojo\"\n    ::msgcat::mcset es \"retry\" \"reintentar\"\n    ::msgcat::mcset es \"yes\" \"s\\u00ed\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/fr.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset fr \"Application Error\" \"Erreur d'application\"\n    ::msgcat::mcset fr \"Blue\" \"Bleu\"\n    ::msgcat::mcset fr \"Color\" \"Couleur\"\n    ::msgcat::mcset fr \"Delete\" \"Effacer\"\n    ::msgcat::mcset fr \"Error\" \"Erreur\"\n    ::msgcat::mcset fr \"Exit\" \"Quitter\"\n    ::msgcat::mcset fr \"Green\" \"Vert\"\n    ::msgcat::mcset fr \"Red\" \"Rouge\"\n    ::msgcat::mcset fr \"blue\" \"bleu\"\n    ::msgcat::mcset fr \"green\" \"vert\"\n    ::msgcat::mcset fr \"red\" \"rouge\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset fr \"&Abort\" \"&Annuler\"\n    ::msgcat::mcset fr \"About...\" \"\\u00c0 propos...\"\n    ::msgcat::mcset fr \"All Files\" \"Tous les fichiers\"\n    ::msgcat::mcset fr \"Application Error\" \"Erreur d'application\"\n    ::msgcat::mcset fr \"&Blue\" \"&Bleu\"\n    ::msgcat::mcset fr \"&Cancel\" \"&Annuler\"\n    ::msgcat::mcset fr \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Impossible d'acc\\u00e9der au r\\u00e9pertoire \\\"%1\\$s\\\".\\nPermission refus\\u00e9e.\"\n    ::msgcat::mcset fr \"Choose Directory\" \"Choisir r\\u00e9pertoire\"\n    ::msgcat::mcset fr \"Clear\" \"Effacer\"\n    ::msgcat::mcset fr \"Color\" \"Couleur\"\n    ::msgcat::mcset fr \"Console\"\n    ::msgcat::mcset fr \"Copy\" \"Copier\"\n    ::msgcat::mcset fr \"Cut\" \"Couper\"\n    ::msgcat::mcset fr \"Delete\" \"Effacer\"\n    ::msgcat::mcset fr \"Details >>\" \"D\\u00e9tails >>\"\n    ::msgcat::mcset fr \"Directory \\\"%1\\$s\\\" does not exist.\" \"Le r\\u00e9pertoire \\\"%1\\$s\\\" n'existe pas.\"\n    ::msgcat::mcset fr \"&Directory:\" \"&R\\u00e9pertoire:\"\n    ::msgcat::mcset fr \"Error: %1\\$s\" \"Erreur: %1\\$s\"\n    ::msgcat::mcset fr \"Exit\" \"Quitter\"\n    ::msgcat::mcset fr \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"Le fichier \\\"%1\\$s\\\" existe d\\u00e9j\\u00e0.\\nVoulez-vous l'\\u00e9craser?\"\n    ::msgcat::mcset fr \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"Le fichier \\\"%1\\$s\\\" existe d\\u00e9j\\u00e0.\\n\\n\"\n    ::msgcat::mcset fr \"File \\\"%1\\$s\\\" does not exist.\" \"Le fichier \\\"%1\\$s\\\" n'existe pas.\"\n    ::msgcat::mcset fr \"File &name:\" \"&Nom de fichier:\"\n    ::msgcat::mcset fr \"File &names:\" \"&Noms de fichiers:\"\n    ::msgcat::mcset fr \"Files of &type:\" \"&Type de fichiers:\"\n    ::msgcat::mcset fr \"Fi&les:\" \"Fich&iers:\"\n    ::msgcat::mcset fr \"&Filter\" \"&Filtre\"\n    ::msgcat::mcset fr \"Fil&ter:\" \"Fil&tre:\"\n    ::msgcat::mcset fr \"&Green\" \"&Vert\"\n    ::msgcat::mcset fr \"Hi\" \"Salut\"\n    ::msgcat::mcset fr \"Hide Console\" \"Cacher la Console\"\n    ::msgcat::mcset fr \"&Ignore\" \"&Ignorer\"\n    ::msgcat::mcset fr \"Invalid file name \\\"%1\\$s\\\".\" \"Nom de fichier invalide \\\"%1\\$s\\\".\"\n    ::msgcat::mcset fr \"Log Files\" \"Fichiers de trace\"\n    ::msgcat::mcset fr \"&No\" \"&Non\"\n    ::msgcat::mcset fr \"&OK\"\n    ::msgcat::mcset fr \"Ok\"\n    ::msgcat::mcset fr \"Open\" \"Ouvrir\"\n    ::msgcat::mcset fr \"&Open\" \"&Ouvrir\"\n    ::msgcat::mcset fr \"Open Multiple Files\" \"Ouvrir plusieurs fichiers\"\n    ::msgcat::mcset fr \"Paste\" \"Coller\"\n    ::msgcat::mcset fr \"Quit\" \"Quitter\"\n    ::msgcat::mcset fr \"&Red\" \"&Rouge\"\n    ::msgcat::mcset fr \"Replace existing file?\" \"Remplacer le fichier existant?\"\n    ::msgcat::mcset fr \"&Retry\" \"&R\\u00e9-essayer\"\n    ::msgcat::mcset fr \"&Save\" \"&Sauvegarder\"\n    ::msgcat::mcset fr \"Save As\" \"Sauvegarder sous\"\n    ::msgcat::mcset fr \"Save To Log\" \"Sauvegarde au fichier de trace\"\n    ::msgcat::mcset fr \"Select Log File\" \"Choisir un fichier de trace\"\n    ::msgcat::mcset fr \"Select a file to source\" \"Choisir un fichier \\u00e0 \\u00e9valuer\"\n    ::msgcat::mcset fr \"&Selection:\" \"&S\\u00e9lection:\"\n    ::msgcat::mcset fr \"Skip Messages\" \"Omettre les messages\"\n    ::msgcat::mcset fr \"Source...\" \"\\u00c9valuer...\"\n    ::msgcat::mcset fr \"Tcl Scripts\" \"Scripts Tcl\"\n    ::msgcat::mcset fr \"Tcl for Windows\" \"Tcl pour Windows\"\n    ::msgcat::mcset fr \"Text Files\" \"Fichiers texte\"\n    ::msgcat::mcset fr \"&Yes\" \"&Oui\"\n    ::msgcat::mcset fr \"abort\" \"abandonner\"\n    ::msgcat::mcset fr \"blue\" \"bleu\"\n    ::msgcat::mcset fr \"cancel\" \"annuler\"\n    ::msgcat::mcset fr \"extension\"\n    ::msgcat::mcset fr \"extensions\"\n    ::msgcat::mcset fr \"green\" \"vert\"\n    ::msgcat::mcset fr \"ignore\" \"ignorer\"\n    ::msgcat::mcset fr \"ok\"\n    ::msgcat::mcset fr \"red\" \"rouge\"\n    ::msgcat::mcset fr \"retry\" \"r\\u00e9essayer\"\n    ::msgcat::mcset fr \"yes\" \"oui\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/it.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset it \"Application Error\" \"Errore dell' applicazione\"\n    ::msgcat::mcset it \"Blue\" \"Blu\"\n    ::msgcat::mcset it \"Color\" \"Colore\"\n    ::msgcat::mcset it \"Delete\" \"Incolla\"\n    ::msgcat::mcset it \"Error\" \"Errore\"\n    ::msgcat::mcset it \"Exit\" \"Esci\"\n    ::msgcat::mcset it \"Green\" \"Verde\"\n    ::msgcat::mcset it \"Red\" \"Rosso\"\n    ::msgcat::mcset it \"blue\" \"blu\"\n    ::msgcat::mcset it \"green\" \"verde\"\n    ::msgcat::mcset it \"red\" \"rosso\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset it \"&Abort\" \"&Interrompi\"\n    ::msgcat::mcset it \"About...\" \"Informazioni ...\"\n    ::msgcat::mcset it \"All Files\" \"Tutti i file\"\n    ::msgcat::mcset it \"Application Error\" \"Errore dell' applicazione\"\n    ::msgcat::mcset it \"&Blue\" \"&Blu\"\n    ::msgcat::mcset it \"&Cancel\" \"&Annulla\"\n    ::msgcat::mcset it \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Impossibile accedere alla directory \\\"%1\\$s\\\".\\nPermesso negato.\"\n    ::msgcat::mcset it \"Choose Directory\" \"Scegli directory\"\n    ::msgcat::mcset it \"Clear\" \"Azzera\"\n    ::msgcat::mcset it \"Color\" \"Colore\"\n    ::msgcat::mcset it \"Console\"\n    ::msgcat::mcset it \"Copy\" \"Copia\"\n    ::msgcat::mcset it \"Cut\" \"Taglia\"\n    ::msgcat::mcset it \"Delete\" \"Incolla\"\n    ::msgcat::mcset it \"Details >>\" \"Dettagli >>\"\n    ::msgcat::mcset it \"Directory \\\"%1\\$s\\\" does not exist.\" \"La directory \\\"%1\\$s\\\" non esiste.\"\n    ::msgcat::mcset it \"&Directory:\"\n    ::msgcat::mcset it \"Error: %1\\$s\" \"Errore: %1\\$s\"\n    ::msgcat::mcset it \"Exit\" \"Esci\"\n    ::msgcat::mcset it \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"Il file \\\"%1\\$s\\\" esiste gi\\u00e0.\\nVuoi sovrascriverlo?\"\n    ::msgcat::mcset it \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"Il file \\\"%1\\$s\\\" esiste gi\\u00e0.\\n\\n\"\n    ::msgcat::mcset it \"File \\\"%1\\$s\\\" does not exist.\" \"Il file \\\"%1\\$s\\\" non esiste.\"\n    ::msgcat::mcset it \"File &name:\" \"&Nome del file:\"\n    ::msgcat::mcset it \"File &names:\" \"&Nomi dei file:\"\n    ::msgcat::mcset it \"Files of &type:\" \"File di &tipo:\"\n    ::msgcat::mcset it \"Fi&les:\" \"Fi&le:\"\n    ::msgcat::mcset it \"&Filter\" \"&Filtro\"\n    ::msgcat::mcset it \"Fil&ter:\" \"Fil&tro:\"\n    ::msgcat::mcset it \"&Green\" \"&Verde\"\n    ::msgcat::mcset it \"Hi\" \"Salve\"\n    ::msgcat::mcset it \"Hide Console\" \"Nascondi la console\"\n    ::msgcat::mcset it \"&Ignore\" \"&Ignora\"\n    ::msgcat::mcset it \"Invalid file name \\\"%1\\$s\\\".\" \"Nome di file non valido \\\"%1\\$s\\\".\"\n    ::msgcat::mcset it \"Log Files\" \"File di log\"\n    ::msgcat::mcset it \"&No\"\n    ::msgcat::mcset it \"&OK\"\n    ::msgcat::mcset it \"Ok\"\n    ::msgcat::mcset it \"&Open\" \"A&pri\"\n    ::msgcat::mcset it \"Open\" \"Apri\"\n    ::msgcat::mcset it \"Open Multiple Files\" \"Apri file multipli\"\n    ::msgcat::mcset it \"Paste\" \"Incolla\"\n    ::msgcat::mcset it \"Quit\" \"Esci\"\n    ::msgcat::mcset it \"&Red\" \"&Rosso\"\n    ::msgcat::mcset it \"Replace existing file?\" \"Sostituisci il file esistente?\"\n    ::msgcat::mcset it \"&Retry\" \"&Riprova\"\n    ::msgcat::mcset it \"&Save\" \"&Salva\"\n    ::msgcat::mcset it \"Save As\" \"Salva come\"\n    ::msgcat::mcset it \"Save To Log\" \"Salva il log\"\n    ::msgcat::mcset it \"Select Log File\" \"Scegli un file di log\"\n    ::msgcat::mcset it \"Select a file to source\" \"Scegli un file da eseguire\"\n    ::msgcat::mcset it \"&Selection:\" \"&Selezione:\"\n    ::msgcat::mcset it \"Skip Messages\" \"Salta i messaggi\"\n    ::msgcat::mcset it \"Source...\" \"Esegui...\"\n    ::msgcat::mcset it \"Tcl Scripts\" \"Scripts Tcl\"\n    ::msgcat::mcset it \"Tcl for Windows\" \"Tcl per Windows\"\n    ::msgcat::mcset it \"Text Files\" \"File di testo\"\n    ::msgcat::mcset it \"&Yes\" \"&Si\"\n    ::msgcat::mcset it \"abort\" \"interrompi\"\n    ::msgcat::mcset it \"blue\" \"blu\"\n    ::msgcat::mcset it \"cancel\" \"annulla\"\n    ::msgcat::mcset it \"extension\" \"estensione\"\n    ::msgcat::mcset it \"extensions\" \"estensioni\"\n    ::msgcat::mcset it \"green\" \"verde\"\n    ::msgcat::mcset it \"ignore\" \"ignora\"\n    ::msgcat::mcset it \"ok\"\n    ::msgcat::mcset it \"red\" \"rosso\"\n    ::msgcat::mcset it \"retry\" \"riprova\"\n    ::msgcat::mcset it \"yes\" \"si\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/ja.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset ja \"Application Error\"  \"\\u30A2\\u30D7\\u30EA\\u30B1\\u30FC\\u30B7\\u30E7\\u30F3\\u30A8\\u30E9\\u30FC\"\n    ::msgcat::mcset ja \"Blue\"    \"\\u9752\"\n    ::msgcat::mcset ja \"Color\"   \"\\u80CC\\u666F\\u8272\"\n    ::msgcat::mcset ja \"Delete\"  \"\\u6D88\\u53BB\"\n    ::msgcat::mcset ja \"Error\"   \"\\u30A8\\u30E9\\u30FC\"\n    ::msgcat::mcset ja \"Exit\"    \"\\u7D42\\u4E86\"\n    ::msgcat::mcset ja \"Green\"   \"\\u7DD1\"\n    ::msgcat::mcset ja \"Red\"     \"\\u8D64\"\n    ::msgcat::mcset ja \"blue\"    \"\\u9752\"\n    ::msgcat::mcset ja \"green\"   \"\\u7DD1\"\n    ::msgcat::mcset ja \"red\"     \"\\u8D64\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/license.terms",
    "content": "This software is copyrighted by the Regents of the University of\nCalifornia, Sun Microsystems, Inc., and other parties.  The following\nterms apply to all files associated with the software unless explicitly\ndisclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license.\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/nl.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset nl \"Application Error\" \"Toepassingsfout\"\n    ::msgcat::mcset nl \"Blue\" \"Blauw\"\n    ::msgcat::mcset nl \"Color\" \"Kleur\"\n    ::msgcat::mcset nl \"Delete\" \"Wissen\"\n    ::msgcat::mcset nl \"Error\" \"Fout\"\n    ::msgcat::mcset nl \"Exit\" \"Be\\u00ebindigen\"\n    ::msgcat::mcset nl \"Green\" \"Groen\"\n    ::msgcat::mcset nl \"Red\" \"Rood\"\n    ::msgcat::mcset nl \"blue\" \"blauw\"\n    ::msgcat::mcset nl \"green\" \"groen\"\n    ::msgcat::mcset nl \"red\" \"rood\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset nl \"\\\"%1\\$s\\\" must be an absolute pathname\" \"\\\"%1\\$s\\\" moet een absolute pad-naam zijn\"\n    ::msgcat::mcset nl \"%1\\$s is not a toplevel window\" \"%1\\$s is geen toplevel window\"\n    ::msgcat::mcset nl \", or\" \", of\"\n    ::msgcat::mcset nl \"-default, -icon, -message, -parent, -title, or -type\" \"-default, -icon, -message, -parent, -title, of -type\"\n    ::msgcat::mcset nl \"-initialdir, -mustexist, -parent, or -title\" \"-initialdir, -mustexist, -parent, of -title\"\n    ::msgcat::mcset nl \"&Abort\" \"&Afbreken\"\n    ::msgcat::mcset nl \"About...\" \"Over...\"\n    ::msgcat::mcset nl \"All Files\" \"Alle Bestanden\"\n    ::msgcat::mcset nl \"Application Error\" \"Toepassingsfout\"\n    ::msgcat::mcset nl \"&Blue\" \"&Blauw\"\n    ::msgcat::mcset nl \"&Cancel\" \"&Annuleren\"\n    ::msgcat::mcset nl \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Kan niet naar map \\\"%1\\$s\\\" gaan.\\nU heeft hiervoor geen toestemming.\"\n    ::msgcat::mcset nl \"Choose Directory\" \"Kies map\"\n    ::msgcat::mcset nl \"Clear\" \"Wissen\"\n    ::msgcat::mcset nl \"Clear entry, Press OK; Enter %1\\$s, press OK\" \"Wis veld, Druk op OK; typ %1\\$s in, druk op OK\"\n    ::msgcat::mcset nl \"&Clear Console\" \"&Wis Console\"\n    ::msgcat::mcset nl \"Color\" \"Kleur\"\n    ::msgcat::mcset nl \"Console\"\n    ::msgcat::mcset nl \"Copy\" \"Kopi\\u00ebren\"\n    ::msgcat::mcset nl \"Cut\" \"Knippen\"\n    ::msgcat::mcset nl \"Delete\" \"Wissen\"\n    ::msgcat::mcset nl \"Details\"\n    ::msgcat::mcset nl \"Details >>\"\n    ::msgcat::mcset nl \"Directory \\\"%1\\$s\\\" does not exist.\" \"Map \\\"%1\\$s\\\" bestaat niet.\"\n    ::msgcat::mcset nl \"&Directory:\" \"&Map:\"\n    ::msgcat::mcset nl \"Edit\" \"Bewerken\"\n    ::msgcat::mcset nl \"Enter \\\"%1\\$s\\\", press OK\" \"Typ \\\"%1\\$s\\\", druk op OK\"\n    ::msgcat::mcset nl \"Enter \\\"%1\\$s\\\", press OK, enter \\\"%2\\$s\\\", press OK\" \"Typ \\\"%1\\$s\\\", druk op OK, typ \\\"%2\\$s\\\", druk op OK\"\n    ::msgcat::mcset nl \"Error: %1\\$s\" \"Fout: %1\\$s\"\n    ::msgcat::mcset nl \"Exit\" \"Be\\u00ebindigen\"\n    ::msgcat::mcset nl \"File\" \"Bestand\"\n    ::msgcat::mcset nl \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"Bestand \\\"%1\\$s\\\" bestaat al.\\n\\n\"\n    ::msgcat::mcset nl \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"Bestand \\\"%1\\$s\\\" bestaat al.\\nWilt u het overschrijven?\"\n    ::msgcat::mcset nl \"File \\\"%1\\$s\\\" does not exist.\" \"Bestand \\\"%1\\$s\\\" bestaat niet.\"\n    ::msgcat::mcset nl \"File &name:\" \"Bestands&naam:\"\n    ::msgcat::mcset nl \"File &names:\" \"Bestands&namen:\"\n    ::msgcat::mcset nl \"Files of &type:\" \"Bestanden van het &type:\"\n    ::msgcat::mcset nl \"Fi&les:\" \"&Bestanden:\"\n    ::msgcat::mcset nl \"&Filter\"\n    ::msgcat::mcset nl \"Fil&ter:\"\n    ::msgcat::mcset nl \"&Green\" \"&Groen\"\n    ::msgcat::mcset nl \"Hi\" \"H\\u00e9\"\n    ::msgcat::mcset nl \"Hide Console\" \"Verberg Console\"\n    ::msgcat::mcset nl \"&Ignore\" \"&Negeren\"\n    ::msgcat::mcset nl \"Invalid file name \\\"%1\\$s\\\".\" \"Ongeldige bestandsnaam \\\"%1\\$s\\\".\"\n    ::msgcat::mcset nl \"Log Files\" \"Log Bestanden\"\n    ::msgcat::mcset nl \"&No\" \"&Nee\"\n    ::msgcat::mcset nl \"&OK\"\n    ::msgcat::mcset nl \"Ok\"\n    ::msgcat::mcset nl \"&Open\" \"&Openen\"\n    ::msgcat::mcset nl \"Open\" \"Openen\"\n    ::msgcat::mcset nl \"Open Multiple Files\" \"Open meerdere bestanden\"\n    ::msgcat::mcset nl \"Paste\" \"Plakken\"\n    ::msgcat::mcset nl \"Please press %1\\$s\" \"Druk op %1\\$s, A.U.B.\"\n    ::msgcat::mcset nl \"Please press ok\" \"Druk op ok, A.U.B.\"\n    ::msgcat::mcset nl \"Press Cancel\" \"Druk op Annuleren\"\n    ::msgcat::mcset nl \"Press Ok\" \"Druk op Ok\"\n    ::msgcat::mcset nl \"Quit\" \"Stoppen\"\n    ::msgcat::mcset nl \"&Red\" \"&Rood\"\n    ::msgcat::mcset nl \"Replace existing file?\" \"Vervang bestaand bestand?\"\n    ::msgcat::mcset nl \"&Retry\" \"&Herhalen\"\n    ::msgcat::mcset nl \"&Save\" \"Op&slaan\"\n    ::msgcat::mcset nl \"Save As\" \"Opslaan als\"\n    ::msgcat::mcset nl \"Save To Log\" \"Opslaan naar Log\"\n    ::msgcat::mcset nl \"Select Log File\" \"Selecteer Log bestand\"\n    ::msgcat::mcset nl \"Select a file to source\" \"Selecteer bronbestand\"\n    ::msgcat::mcset nl \"&Selection:\" \"&Selectie:\"\n    ::msgcat::mcset nl \"Skip Messages\" \"Berichten overslaan\"\n    ::msgcat::mcset nl \"Source...\" \"Bron...\"\n    ::msgcat::mcset nl \"Tcl Scripts\"\n    ::msgcat::mcset nl \"Tcl for Windows\" \"Tcl voor Windows\"\n    ::msgcat::mcset nl \"Text Files\" \"Tekstbestanden\"\n    ::msgcat::mcset nl \"&Yes\" \"&Ja\"\n    ::msgcat::mcset nl \"abort\" \"afbreken\"\n    ::msgcat::mcset nl \"abort, retry, ignore, ok, cancel, no, or yes\" \"afbreken, opnieuw, negeren, ok, annuleren, nee, of ja\"\n    ::msgcat::mcset nl \"abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel\" \"abortretryignore, ok, okcancel, retrycancel, yesno, of yesnocancel\"\n    ::msgcat::mcset nl \"bad %1\\$s value \\\"%2\\$s\\\": must be %3\\$s\" \"verkeerde %1\\$s waarde \\\"%2\\$s\\\": moet zijn %3\\$s\"\n    ::msgcat::mcset nl \"bad file type \\\"%1\\$s\\\", should be\" \"verkeerd bestandstype \\\"%1\\$s\\\", moet zijn\"\n    ::msgcat::mcset nl \"bad option \\\"%1\\$s\\\": should be %2\\$s\" \"verkeerde optie \\\"%1\\$s\\\": moet zijn %2\\$s\"\n    ::msgcat::mcset nl \"bad window path name \\\"%1\\$s\\\"\" \"verkeerde window-padnaam \\\"%1\\$s\\\"\"\n    ::msgcat::mcset nl \"blue\" \"blauw\"\n    ::msgcat::mcset nl \"can't post %1\\$s:  it isn't a descendant of %2\\$s (this is a new requirement in Tk versions 3.0 and later)\" \"kan %1\\$s niet verzenden:  het is geen afstammeling van %2\\$s (dit is een nieuwe eis in Tk versies 3.0 en later)\"\n    ::msgcat::mcset nl \"cancel\" \"annuleren\"\n    ::msgcat::mcset nl \"default button index greater than number of buttons specified for tk_dialog\" \"default knop index is groter dan het aantal knoppen beschikbaar voor tk_dialog\"\n    ::msgcat::mcset nl \"display name to use (current one otherwise)\" \"te gebruiken schermnaam (anders huidige scherm)\"\n    ::msgcat::mcset nl \"error, info, question, or warning\" \"error, info, question, of warning\"\n    ::msgcat::mcset nl \"extension\"\n    ::msgcat::mcset nl \"extensions\"\n    ::msgcat::mcset nl \"focus group \\\"%1\\$s\\\" doesn't exist\" \"focusgroep \\\"%1\\$s\\\" bestaat niet\"\n    ::msgcat::mcset nl \"green\" \"groen\"\n    ::msgcat::mcset nl \"history event %1\\$s\"\n    ::msgcat::mcset nl \"ignore\" \"negeren\"\n    ::msgcat::mcset nl \"invalid default button \\\"%1\\$s\\\"\" \"ongeldige default knop \\\"%1\\$s\\\"\"\n    ::msgcat::mcset nl \"macType\"\n    ::msgcat::mcset nl \"macTypes\"\n    ::msgcat::mcset nl \"must specify a background color\" \"een achtergrondkleur is verplicht\"\n    ::msgcat::mcset nl \"name of the slave interpreter\" \"naam van de slaaf-interpreter\"\n    ::msgcat::mcset nl \"no winfo screen . nor env(DISPLAY)\" \"geen winfo scherm . noch env(DISPLAY)\"\n    ::msgcat::mcset nl \"ok\"\n    ::msgcat::mcset nl \"red\" \"rood\"\n    ::msgcat::mcset nl \"retry\" \"opnieuw\"\n    ::msgcat::mcset nl \"should contain 5 or 4 elements\" \"moet 4 of 5 elementen bevatten\"\n    ::msgcat::mcset nl \"spec\"\n    ::msgcat::mcset nl \"tk_chooseDirectory command\" \"tk_chooseDirectory opdracht\"\n    ::msgcat::mcset nl \"tk_chooseDirectory command, cancel gives null\" \"tk_chooseDirectory opdracht, annuleren geeft lege waarde\"\n    ::msgcat::mcset nl \"tk_chooseDirectory command, initialdir\" \"tk_chooseDirectory opdracht, initi\\u00eble map\"\n    ::msgcat::mcset nl \"yes\" \"ja\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/pl.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset pl \"Application Error\" \"Bl\\u0105d w Programie\"\n    ::msgcat::mcset pl \"Blue\" \"Niebieski\"\n    ::msgcat::mcset pl \"Color\" \"Kolor\"\n    ::msgcat::mcset pl \"Delete\" \"Usu\\u0144\"\n    ::msgcat::mcset pl \"Error\" \"B\\u0142\\u0105d\"\n    ::msgcat::mcset pl \"Exit\" \"Zako\\u0144cz\"\n    ::msgcat::mcset pl \"Green\" \"Zielony\"\n    ::msgcat::mcset pl \"Red\" \"Czerwonz\"\n    ::msgcat::mcset pl \"blue\" \"niebieski\"\n    ::msgcat::mcset pl \"green\" \"zielony\"\n    ::msgcat::mcset pl \"red\" \"czerwony\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset pl \"&Abort\" \"&Anuluj\"\n    ::msgcat::mcset pl \"&About...\" \"O Programie...\"\n    ::msgcat::mcset pl \"All Files\" \"Wszystkie pliki\"\n    ::msgcat::mcset pl \"Application Error\" \"Bl\\u0105d w Programie\"\n    ::msgcat::mcset pl \"&Blue\" \"&Niebieski\"\n    ::msgcat::mcset pl \"&Cancel\" \"&Anuluj\"\n    ::msgcat::mcset pl \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \"Katalog \\\"%1\\$s\\\" nie mo\\u017ce zosta\\u0107 odczytany lub nie istnieje.\"\n    ::msgcat::mcset pl \"Choose Directory\" \"Wybierz katalog\"\n    ::msgcat::mcset pl \"&Clear\" \"&Wyczy\\u015b\\u0107\"\n    ::msgcat::mcset pl \"&Clear Console\" \"&Wyczy\\u015b\\u0107 konsol\\u0119\"\n    ::msgcat::mcset pl \"Color\" \"Kolor\"\n    ::msgcat::mcset pl \"Console\" \"Konsola\"\n    ::msgcat::mcset pl \"&Copy\" \"&Kopiuj\"\n    ::msgcat::mcset pl \"Cu&t\" \"&Wytnij\"\n    ::msgcat::mcset pl \"&Delete\" \"&Usu\\u0144\"\n    ::msgcat::mcset pl \"Details >>\" \"Detale >>\"\n    ::msgcat::mcset pl \"Directory \\\"%1\\$s\\\" does not exist.\" \"Katalog \\\"%1\\$s\\\" nie istniej.\"\n    ::msgcat::mcset pl \"&Directory:\" \"&Katalog:\"\n    ::msgcat::mcset pl \"&Edit\" \"&Edytuj\"\n    ::msgcat::mcset pl \"Error: %1\\$s\" \"B\\u0142\\u0105d: %1\\$s\"\n    ::msgcat::mcset pl \"E&xit\" \"&Zako\\u0144cz\"\n    ::msgcat::mcset pl \"&File\" \"&Plik\"\n    ::msgcat::mcset pl \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \"Plik \\\"%1\\$s\\\" ju\\u017c istnieje.\\nCzy chcesz go zast\\u0105pi\\u0107?\"\n    ::msgcat::mcset pl \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"Plik \\\"%1\\$s\\\" ju\\u017c istnieje. \\n\\n\"\n    ::msgcat::mcset pl \"File \\\"%1\\$s\\\" does not exist.\" \"Plik \\\"%1\\$s\\\" nie istnieje.\"\n    ::msgcat::mcset pl \"File &name:\" \"Nazwa &pliku:\"\n    ::msgcat::mcset pl \"File &names:\" \"Nazwy &plik\\u00f3w:\"\n    ::msgcat::mcset pl \"Files of &type:\" \"Pliki &typu:\"\n    ::msgcat::mcset pl \"Fi&les:\" \"Pli&ki:\"\n    ::msgcat::mcset pl \"&Filter\" \"&Filter\"\n    ::msgcat::mcset pl \"Fil&ter:\" \"&Filter:\"\n    ::msgcat::mcset pl \"&Green\" \"&Zielony\"\n    ::msgcat::mcset pl \"&Help\" \"&Pomoc\"\n    ::msgcat::mcset pl \"Hi\" \"Witaj\"\n    ::msgcat::mcset pl \"&Hide Console\" \"&Schowaj konsol\\u0119\"\n    ::msgcat::mcset pl \"&Ignore\" \"&Ignoruj\"\n    ::msgcat::mcset pl \"Invalid file name \\\"%1\\$s\\\".\" \"Niew\\u0142a\\u015bciwa nazwa pliku \\\"%1\\$s\\\".\"\n    ::msgcat::mcset pl \"Log Files\" \"Protoko\\u0142uj\"\n    ::msgcat::mcset pl \"&No\" \"&Nie\"\n    ::msgcat::mcset pl \"OK\"\n    ::msgcat::mcset pl \"Ok\"\n    ::msgcat::mcset pl \"Open\" \"Wczytaj\"\n    ::msgcat::mcset pl \"&Open\" \"&Wczytaj\"\n    ::msgcat::mcset pl \"Open Multiple Files\" \"Wczytuj wiele plik\\u00f3w\"\n    ::msgcat::mcset pl \"P&aste\" \"&Wklej\"\n    ::msgcat::mcset pl \"&Quit\" \"&Zako\\u0144cz\"\n    ::msgcat::mcset pl \"&Red\" \"&Czerwonz\"\n    ::msgcat::mcset pl \"Replace existing file?\" \"Czy zost\\u0105pi\\u0107 instniej\\u0105cy plik?\"\n    ::msgcat::mcset pl \"&Retry\" \"&Powt\\u00f3rz\"\n    ::msgcat::mcset pl \"&Save\" \"&Zapisz\"\n    ::msgcat::mcset pl \"Save As\" \"Zapisz jako\"\n    ::msgcat::mcset pl \"Save To Log\" \"Wpisz do protoko\\u0142u\"\n    ::msgcat::mcset pl \"Select Log File\" \"Wybierz plik proko\\u0142u\"\n    ::msgcat::mcset pl \"Select a file to source\" \"Wybierz plik do wykonania\"\n    ::msgcat::mcset pl \"&Selection:\" \"&Wyb\\u00f3r:\"\n    ::msgcat::mcset pl \"Skip Messages\" \"Omi\\u0144 pozosta\\u0142e komunikaty\"\n    ::msgcat::mcset pl \"&Source...\" \"&Kod \\u017ar\\u00f3d\\u0142owy...\"\n    ::msgcat::mcset pl \"Tcl Scripts\" \"Tcl-skrypty\"\n    ::msgcat::mcset pl \"Tcl for Windows\" \"Tcl dla Okienek (Windows)\"\n    ::msgcat::mcset pl \"Text Files\" \"Pliki Tekstowe\"\n    ::msgcat::mcset pl \"&Yes\" \"&Tak\"\n    ::msgcat::mcset pl \"abort\" \"zako\\u0144cz\"\n    ::msgcat::mcset pl \"blue\" \"niebieski\"\n    ::msgcat::mcset pl \"cancel\" \"anuluj\"\n    ::msgcat::mcset pl \"extension\" \"rozszerzenie\"\n    ::msgcat::mcset pl \"extensions\" \"rozszerzenia\"\n    ::msgcat::mcset pl \"green\" \"zielony\"\n    ::msgcat::mcset pl \"ignore\" \"ignoruj\"\n    ::msgcat::mcset pl \"red\" \"czerwony\"\n    ::msgcat::mcset pl \"retry\" \"potw\\u00f3rz\"\n    ::msgcat::mcset pl \"yes\" \"tak\"\n}\n"
  },
  {
    "path": "ext/tk/sample/msgs_tk/ru.msg",
    "content": "namespace eval ::tkmsgcat_demo {\n    ::msgcat::mcset ru \"Application Error\" \"\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430 \\u0432 \\u043f\\u0440\\u043e\\u0433\\u0440\\u0430\\u043c\\u043c\\u0435\"\n    ::msgcat::mcset ru \"Blue\" \" \\u0413\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439\"\n    ::msgcat::mcset ru \"Color\" \"\\u0426\\u0432\\u0435\\u0442\"\n    ::msgcat::mcset ru \"Delete\" \"\\u0423\\u0434\\u0430\\u043b\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Error\" \"\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430\"\n    ::msgcat::mcset ru \"Exit\" \"\\u0412\\u044b\\u0445\\u043e\\u0434\"\n    ::msgcat::mcset ru \"Green\" \"\\u0417\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"Red\" \"\\u041a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"blue\" \" \\u0433\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439\"\n    ::msgcat::mcset ru \"green\" \" \\u0437\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"red\" \" \\u043a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439\"\n}\n\nnamespace eval ::tk {\n    ::msgcat::mcset ru \"&Abort\" \"&\\u041e\\u0442\\u043c\\u0435\\u043d\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"About...\" \"\\u041f\\u0440\\u043e...\"\n    ::msgcat::mcset ru \"All Files\" \"\\u0412\\u0441\\u0435 \\u0444\\u0430\\u0439\\u043b\\u044b\"\n    ::msgcat::mcset ru \"Application Error\" \"\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430 \\u0432 \\u043f\\u0440\\u043e\\u0433\\u0440\\u0430\\u043c\\u043c\\u0435\"\n    ::msgcat::mcset ru \"&Blue\" \" &\\u0413\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439\"\n    ::msgcat::mcset ru \"&Cancel\" \"\\u041e\\u0442&\\u043c\\u0435\\u043d\\u0430\"\n    ::msgcat::mcset ru \"Cannot change to the directory \\\"%1\\$s\\\".\\nPermission denied.\" \\\n\t\t\t\"\\u041d\\u0435 \\u043c\\u043e\\u0433\\u0443 \\u043f\\u0435\\u0440\\u0435\\u0439\\u0442\\u0438 \\u0432 \\u043a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433 \\\"%1\\$s\\\".\\n\\u041d\\u0435\\u0434\\u043e\\u0441\\u0442\\u0430\\u0442\\u043e\\u0447\\u043d\\u043e \\u043f\\u0440\\u0430\\u0432 \\u0434\\u043e\\u0441\\u0442\\u0443\\u043f\\u0430\"\n    ::msgcat::mcset ru \"Choose Directory\" \"\\u0412\\u044b\\u0431\\u0435\\u0440\\u0438\\u0442\\u0435 \\u043a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433\"\n    ::msgcat::mcset ru \"Clear\" \"\\u041e\\u0447\\u0438\\u0441\\u0442\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Color\" \"\\u0426\\u0432\\u0435\\u0442\"\n    ::msgcat::mcset ru \"Console\" \"\\u041a\\u043e\\u043d\\u0441\\u043e\\u043b\\u044c\"\n    ::msgcat::mcset ru \"Copy\" \"\\u041a\\u043e\\u043f\\u0438\\u0440\\u043e\\u0432\\u0430\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Cut\" \"\\u0412\\u044b\\u0440\\u0435\\u0437\\u0430\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Delete\" \"\\u0423\\u0434\\u0430\\u043b\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Details >>\" \"\\u041f\\u043e\\u0434\\u0440\\u043e\\u0431\\u043d\\u0435\\u0435 >>\"\n    ::msgcat::mcset ru \"Directory \\\"%1\\$s\\\" does not exist.\" \"\\u041a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433\\u0430 \\\"%1\\$s\\\" \\u043d\\u0435 \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442.\"\n    ::msgcat::mcset ru \"&Directory:\" \"&\\u041a\\u0430\\u0442\\u0430\\u043b\\u043e\\u0433:\"\n    ::msgcat::mcset ru \"Error: %1\\$s\" \"\\u041e\\u0448\\u0438\\u0431\\u043a\\u0430: %1\\$s\" \n    ::msgcat::mcset ru \"Exit\" \"\\u0412\\u044b\\u0445\\u043e\\u0434\"\n    ::msgcat::mcset ru \"File \\\"%1\\$s\\\" already exists.\\nDo you want to overwrite it?\" \\\n\t\t\t    \"\\u0424\\u0430\\u0439\\u043b \\\"%1\\$s\\\" \\u0443\\u0436\\u0435 \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442.\\n\\u0417\\u0430\\u043c\\u0435\\u043d\\u0438\\u0442\\u044c \\u0435\\u0433\\u043e?\"\n    ::msgcat::mcset ru \"File \\\"%1\\$s\\\" already exists.\\n\\n\" \"\\u0424\\u0430\\u0439\\u043b \\\"%1\\$s\\\" \\u0443\\u0436\\u0435 \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442.\\n\\n\"\n    ::msgcat::mcset ru \"File \\\"%1\\$s\\\" does not exist.\" \"\\u0424\\u0430\\u0439\\u043b \\\"%1\\$s\\\" \\u043d\\u0435 \\u043d\\u0430\\u0439\\u0434\\u0435\\u043d.\"\n    ::msgcat::mcset ru \"File &name:\" \"&\\u0418\\u043c\\u044f \\u0444\\u0430\\u0439\\u043b\\u0430:\"\n    ::msgcat::mcset ru \"File &names:\" \"&\\u0418\\u043c\\u0435\\u043d\\u0430 \\u0444\\u0430\\u0439\\u043b\\u043e\\u0432:\"\n    ::msgcat::mcset ru \"Files of &type:\" \"&\\u0422\\u0438\\u043f \\u0444\\u0430\\u0439\\u043b\\u043e\\u0432:\"\n    ::msgcat::mcset ru \"Fi&les:\" \"\\u0424\\u0430\\u0439&\\u043b\\u044b:\"\n    ::msgcat::mcset ru \"&Filter\" \"&\\u0424\\u0438\\u043b\\u044c\\u0442\\u0440\"\n    ::msgcat::mcset ru \"Fil&ter:\" \"\\u0424\\u0438\\u043b\\u044c&\\u0442\\u0440:\"\n    ::msgcat::mcset ru \"&Green\" \" &\\u0417\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"Hi\" \"\\u041f\\u0440\\u0438\\u0432\\u0435\\u0442\"\n    ::msgcat::mcset ru \"Hide Console\" \"\\u0421\\u043f\\u0440\\u044f\\u0442\\u0430\\u0442\\u044c \\u043a\\u043e\\u043d\\u0441\\u043e\\u043b\\u044c\"\n    ::msgcat::mcset ru \"&Ignore\" \"&\\u0418\\u0433\\u043d\\u043e\\u0440\\u0438\\u0440\\u043e\\u0432\\u0430\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Invalid file name \\\"%1\\$s\\\".\" \"\\u041d\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0435 \\u0438\\u043c\\u044f \\u0444\\u0430\\u0439\\u043b\\u0430 \\\"%1\\$s\\\".\" \n    ::msgcat::mcset ru \"Log Files\" \"\\u0424\\u0430\\u0439\\u043b\\u044b \\u0436\\u0443\\u0440\\u043d\\u0430\\u043b\\u0430\"\n    ::msgcat::mcset ru \"&No\" \"&\\u041d\\u0435\\u0442\"\n    ::msgcat::mcset ru \"&OK\" \"&\\u041e\\u041a\"\n    ::msgcat::mcset ru \"Ok\" \"\\u0414\\u0430\"\n    ::msgcat::mcset ru \"Open\" \"\\u041e\\u0442\\u043a\\u0440\\u044b\\u0442\\u044c\"\n    ::msgcat::mcset ru \"&Open\" \"&\\u041e\\u0442\\u043a\\u0440\\u044b\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Open Multiple Files\" \"\\u041e\\u0442\\u043a\\u0440\\u044b\\u0442\\u044c \\u043d\\u0435\\u0441\\u043a\\u043e\\u043b\\u044c\\u043a\\u043e \\u0444\\u0430\\u0439\\u043b\\u043e\\u0432\"\n    ::msgcat::mcset ru \"Paste\" \"\\u0412\\u0441\\u0442\\u0430\\u0432\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Quit\" \"\\u0412\\u044b\\u0445\\u043e\\u0434\"\n    ::msgcat::mcset ru \"&Red\" \" &\\u041a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"Replace existing file?\" \"\\u0417\\u0430\\u043c\\u0435\\u043d\\u0438\\u0442\\u044c \\u0441\\u0443\\u0449\\u0435\\u0441\\u0442\\u0432\\u0443\\u044e\\u0449\\u0438\\u0439 \\u0444\\u0430\\u0439\\u043b?\"\n    ::msgcat::mcset ru \"&Retry\" \"&\\u041f\\u043e\\u0432\\u0442\\u043e\\u0440\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"&Save\" \"&\\u0421\\u043e\\u0445\\u0440\\u0430\\u043d\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"Save As\" \"\\u0421\\u043e\\u0445\\u0440\\u0430\\u043d\\u0438\\u0442\\u044c \\u043a\\u0430\\u043a\"\n    ::msgcat::mcset ru \"Save To Log\" \"\\u0421\\u043e\\u0445\\u0440\\u0430\\u043d\\u0438\\u0442\\u044c \\u0432 \\u0436\\u0443\\u0440\\u043d\\u0430\\u043b\"\n    ::msgcat::mcset ru \"Select Log File\" \"\\u0412\\u044b\\u0431\\u0440\\u0430\\u0442\\u044c \\u0436\\u0443\\u0440\\u043d\\u0430\\u043b\"\n    ::msgcat::mcset ru \"Select a file to source\" \"\\u0412\\u044b\\u0431\\u0435\\u0440\\u0438\\u0442\\u0435 \\u0444\\u0430\\u0439\\u043b \\u0434\\u043b\\u044f \\u0438\\u043d\\u0442\\u0435\\u0440\\u043f\\u0440\\u0435\\u0442\\u0430\\u0446\\u0438\\u0438\"\n    ::msgcat::mcset ru \"&Selection:\" \"&Selection:\"\n    ::msgcat::mcset ru \"Skip Messages\" \"\\u041f\\u0440\\u043e\\u043f\\u0443\\u0441\\u0442\\u0438\\u0442\\u044c \\u0441\\u043e\\u043e\\u0431\\u0449\\u0435\\u043d\\u0438\\u044f\"\n    ::msgcat::mcset ru \"Source...\" \"\\u0418\\u043d\\u0442\\u0435\\u0440\\u043f\\u0440\\u0435\\u0442\\u0438\\u0440\\u043e\\u0432\\u0430\\u0442\\u044c \\u0444\\u0430\\u0439\\u043b...\"\n    ::msgcat::mcset ru \"Tcl Scripts\" \"\\u041f\\u0440\\u043e\\u0433\\u0440\\u0430\\u043c\\u043c\\u0430 \\u043d\\u0430 \\u044f\\u0437\\u044b\\u043a\\u0435 TCL\"\n    ::msgcat::mcset ru \"Tcl for Windows\" \"TCL \\u0434\\u043b\\u044f Windows\"\n    ::msgcat::mcset ru \"Text Files\" \"\\u0422\\u0435\\u043a\\u0441\\u0442\\u043e\\u0432\\u044b\\u0435 \\u0444\\u0430\\u0439\\u043b\\u044b\"\n    ::msgcat::mcset ru \"&Yes\" \"&\\u0414\\u0430\"\n    ::msgcat::mcset ru \"abort\" \"\\u043e\\u0442\\u043c\\u0435\\u043d\\u0430\"\n    ::msgcat::mcset ru \"blue\" \" \\u0433\\u043e\\u043b\\u0443\\u0431\\u043e\\u0439\"\n    ::msgcat::mcset ru \"cancel\" \"\\u043e\\u0442\\u043c\\u0435\\u043d\\u0430\"\n    ::msgcat::mcset ru \"extension\" \"\\u0440\\u0430\\u0441\\u0448\\u0438\\u0440\\u0435\\u043d\\u0438\\u0435\"\n    ::msgcat::mcset ru \"extensions\" \"\\u0440\\u0430\\u0441\\u0448\\u0438\\u0440\\u0435\\u043d\\u0438\\u044f\"\n    ::msgcat::mcset ru \"green\" \" \\u0437\\u0435\\u043b\\u0435\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"ignore\" \"\\u043f\\u0440\\u043e\\u043f\\u0443\\u0441\\u0442\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"ok\" \"\\u043e\\u043a\"\n    ::msgcat::mcset ru \"red\" \" \\u043a\\u0440\\u0430\\u0441\\u043d\\u044b\\u0439\"\n    ::msgcat::mcset ru \"retry\" \"\\u043f\\u043e\\u0432\\u0442\\u043e\\u0440\\u0438\\u0442\\u044c\"\n    ::msgcat::mcset ru \"yes\" \"\\u0434\\u0430\"\n}\n\n"
  },
  {
    "path": "ext/tk/sample/multi-ip_sample.rb",
    "content": "#!/usr/bin/env ruby\n# This script is a sample of MultiTkIp class\n\nrequire \"multi-tk\"\n\n# create slave interpreters\ntrusted_slave = MultiTkIp.new_slave\nsafe_slave1   = MultiTkIp.new_safeTk\nsafe_slave2   = MultiTkIp.new_safeTk('fill'=>:none, 'expand'=>false)\n#safe_slave2   = MultiTkIp.new_safeTk('fill'=>:none)\n#safe_slave2   = MultiTkIp.new_safeTk('expand'=>false)\n\ncmd = Proc.new{|txt|\n  #####################\n  ## from TkTimer2.rb\n\n  if TkCore::INTERP.safe?\n    # safeTk doesn't have permission to call 'wm' command\n  else\n    root = TkRoot.new(:title=>'timer sample')\n  end\n\n  label = TkLabel.new(:parent=>root, :relief=>:raised, :width=>10) \\\n                  .pack(:side=>:bottom, :fill=>:both)\n\n  tick = proc{|aobj|\n    cnt = aobj.return_value + 5\n    label.text format(\"%d.%02d\", *(cnt.divmod(100)))\n    cnt\n  }\n\n  timer = TkTimer.new(50, -1, tick).start(0, proc{ label.text('0.00'); 0 })\n\n=begin\n  TkButton.new(:text=>'Start') {\n    command proc{ timer.continue unless timer.running? }\n    pack(:side=>:left, :fill=>:both, :expand=>true)\n  }\n  TkButton.new(:text=>'Restart') {\n    command proc{ timer.restart(0, proc{ label.text('0.00'); 0 }) }\n    pack('side'=>'right','fill'=>'both','expand'=>'yes')\n  }\n  TkButton.new(:text=>'Stop') {\n    command proc{ timer.stop if timer.running? }\n    pack('side'=>'right','fill'=>'both','expand'=>'yes')\n  }\n=end\n  b_start = TkButton.new(:text=>'Start', :state=>:disabled) {\n    pack(:side=>:left, :fill=>:both, :expand=>true)\n  }\n  b_stop  = TkButton.new(:text=>'Stop', :state=>:normal) {\n    pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n  }\n\n  b_start.command {\n    timer.continue\n    b_stop.state(:normal)\n    b_start.state(:disabled)\n  }\n\n  b_stop.command {\n    timer.stop\n    b_start.state(:normal)\n    b_stop.state(:disabled)\n  }\n\n  TkButton.new(:text=>'Reset', :state=>:normal) {\n    command { timer.reset }\n    pack('side'=>'right', 'fill'=>'both', 'expand'=>'yes')\n  }\n\n  ev_quit = TkVirtualEvent.new('Control-c', 'Control-q')\n  Tk.root.bind(ev_quit, proc{Tk.exit}).focus\n}\n\n# call on the default master interpreter\ntrusted_slave.eval_proc(cmd, 'trusted')  # label -> .w00012\nsafe_slave1.eval_proc(cmd, 'safe1')      # label -> .w00016\nsafe_slave2.eval_proc(cmd, 'safe2')      # label -> .w00020\ncmd.call('master')                       # label -> .w00024\n\n#second_master = MultiTkIp.new(&cmd)\n\nTkTimer.new(2000, -1, proc{p ['safe1', safe_slave1.deleted?]}).start\nTkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start\nTkTimer.new(2000, -1, proc{p ['trusted', trusted_slave.deleted?]}).start\n\nTkTimer.new(5000, 1, \n            proc{\n              safe_slave1.eval_proc{Tk.root.destroy}\n              safe_slave1.delete\n              print \"*** The safe_slave1 is deleted by the timer.\\n\"\n            }).start\n\nTkTimer.new(10000, 1, \n            proc{\n              trusted_slave.eval_proc{Tk.root.destroy}\n              trusted_slave.delete\n              print \"*** The trusted_slave is deleted by the timer.\\n\"\n            }).start\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/multi-ip_sample2.rb",
    "content": "require 'multi-tk.rb'\n\nth = Thread.new{Tk.mainloop}\n\nTkLabel.new(:text=>'this is a primary master').pack\n\nip1 = MultiTkIp.new_slave(:safe=>1)\nip2 = MultiTkIp.new_slave(:safe=>2)\n\ncmd = proc{|s|\n  require 'tk'\n\n  TkButton.new(:text=>'b1: p self', :command=>proc{p self}).pack(:fill=>:x)\n  sleep s\n  TkButton.new(:text=>'b2: p $SAFE', :command=>proc{p $SAFE}).pack(:fill=>:x)\n  sleep s\n  TkButton.new(:text=>'b3: p MultiTkIp.ip_name', \n               :command=>proc{p MultiTkIp.ip_name}).pack(:fill=>:x)\n  sleep s\n  TkButton.new(:text=>'EXIT', :command=>proc{exit}).pack(:fill=>:x)\n\n  Tk.mainloop\n}\n\nThread.new{ip1.eval_proc(cmd, 1.1)}\nThread.new{ip2.eval_proc(cmd, 0.3)}\ncmd.call(0.7)\n\nth.join\n"
  },
  {
    "path": "ext/tk/sample/optobj_sample.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  sample script of Tk::OptionObj\n#\nrequire \"tk\"\n\noptobj = Tk::OptionObj.new('foreground'=>'red', 'background'=>'black')\n\nf = TkFrame.new.pack(:side=>:left, :anchor=>:n, :padx=>5, :pady=>30)\n\nb1 = TkButton.new(f, :text=>'AAA').pack(:fill=>:x)\nb2 = TkButton.new(f, :text=>'BBB').pack(:fill=>:x)\nb3 = TkButton.new(f, :text=>'CCC').pack(:fill=>:x)\n\noptobj.assign( b1, \n              [ b2, 'configure', \n                { 'foreground'=>'background', \n                  'background'=>'foreground' } ], \n              [ b3, nil, \n                { 'foreground'=>'background', \n                  'activeforeground'=>nil, \n                  'background'=>['foreground', 'activeforeground'] } ] )\n\noptobj.update('activeforeground'=>'yellow')\n\nTkButton.new(f){\n  configure( optobj.assign(self) + {:text=>'DDD'} )\n  pack(:fill=>:x)\n}\n\nTkButton.new(f){\n  configure( optobj.assign([self, nil, \n                             {'foreground'=>'activeforeground', \n                              'background'=>'foreground', \n                              'activeforeground'=>'background'}]) \\\n             + {:text=>'EEE', :relief=>:groove, :borderwidth=>5} )\n  pack(:fill=>:x)\n}\n\noptobj.notify  # To apply the convert_key ( 3rd element of widget info \n               # (that is, {'foreground'=>'activeforeground', ,,, } ) \n               # of the 'EEE' button \n\nTkButton.new(f, :text=>'toggle', \n             :command=>proc{\n               fg = optobj['foreground']\n               bg = optobj['background']\n               optobj.configure('foreground'=>bg, 'background'=>fg)\n             }).pack(:fill=>:x, :pady=>10)\n\nTkButton.new(f, :text=>'exit', \n                :command=>proc{exit}).pack(:fill=>:x, :pady=>10)\n\nTkFrame.new{|f|\n  pack(:side=>:right, :expand=>true, :fill=>:both)\n  TkLabel.new(f, :text=>'source::').pack(:anchor=>:w)\n  TkFrame.new(f){|ff|\n    TkText.new(ff){\n      yscrollbar(TkScrollbar.new(ff){pack(:fill=>:y, :side=>:right)})\n      insert('end', File.read(__FILE__))\n      pack(:side=>:left, :expand=>true, :fill=>:both)\n    }\n    pack(:expand=>true, :fill=>:both)\n  }\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/propagate.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\n\nTkLabel.new(:text=>\"Please click the bottom frame\").pack\n\nf = TkFrame.new(:width=>400, :height=>100, :background=>'yellow', \n                :relief=>'ridge', :borderwidth=>5).pack\n\n# TkPack.propagate(f, false) # <== important!!\nf.pack_propagate(false)      # <== important!!\n\nlist = (1..3).collect{|n|\n  TkButton.new(f, :text=>\"button#{'-X'*n}\"){\n    command proc{\n      puts \"button#{'-X'*n}\"\n      self.unpack\n    }\n  }\n}\n\nlist.unshift(nil)\n\nf.bind('1', proc{\n         w = list.shift\n         w.unpack if w\n         list.push(w)\n         list[0].pack(:expand=>true, :anchor=>:center) if list[0]\n       })\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/remote-ip_sample.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'remote-tk'\n\nputs <<EOM\nThis sample controls the other Tk interpreter (Ruby/Tk, Tcl/Tk, and so on)\nwhich running on the other process. For this purpose, Ruby/Tk uses Tcl/Tk's \n'send' command. Availability of the command depends on your GUI environment. \nIf this script doesn't work, please check your environment (see Tcl/Tk FAQ).\nEOM\n#'\n\nunless (wish = TkWinfo.interps.find{|ip| ip =~ /^wish/})\n  puts ''\n  puts 'Please start \"wish\" (Tcl/Tk shell) before running this sample script.'\n  exit 1\nend\n\nip = RemoteTkIp.new(wish)\nip.eval_proc{TkButton.new(:command=>proc{puts 'This procesure is on the controller-ip (Ruby/Tk)'}, :text=>'print on Ruby/Tk (controller-ip)').pack(:fill=>:x)}\nip.eval_proc{TkButton.new(:command=>'puts {This procesure is on the remote-ip (wish)}', :text=>'print on wish (remote-ip)').pack(:fill=>:x)}\n\n# If your remote-ip is Ruby/Tk, you can control the remote Ruby by \n# 'ruby' or 'ruby_eval' or 'ruby_cmd' on the Tk interpreter. \nif ip.is_rubytk?\n  ip.eval_proc{TkButton.new(:command=>'ruby {p 111; p Array.new(3,\"ruby\")}', :text=>'ruby cmd on the remote-ip').pack(:fill=>:x)}\nend\n\nip.eval_proc{TkButton.new(:command=>'exit', :text=>'QUIT').pack(:fill=>:x)}\n\nTkButton.new(:command=>proc{exit}, :text=>'QUIT', \n             :padx=>10, :pady=>7).pack(:padx=>10, :pady=>7)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/remote-ip_sample2.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'remote-tk'\n\n# start sub-process\nip_name = 'remote_ip'\nip_list = TkWinfo.interps\nfork{\n  exec \"/usr/bin/env ruby -r tk -e \\\"Tk.appname('#{ip_name}');Tk.mainloop\\\"\"\n}\nsleep 1 until (app = (TkWinfo.interps - ip_list)[0]) && app =~ /^#{ip_name}/\np TkWinfo.interps\n\n# create RemoteTkIp object\nip = RemoteTkIp.new(app)\n\n# setup remote-ip window\nbtns = []\nip.eval_proc{\n  btns << \n    TkButton.new(:command=>proc{\n                   puts 'This procesure is on the controller-ip (Ruby-side)'\n                 }, \n                 :text=>'print on controller-ip (Ruby-side)').pack(:fill=>:x)\n\n  btns << \n    TkButton.new(:command=>\n                   'puts {This procesure is on the remote-ip (Tk-side)}',\n                 :text=>'print on remote-ip (Tk-side)').pack(:fill=>:x)\n\n  btns << \n    TkButton.new(:command=>\n                   'ruby {\n                     puts \"This procedure is on the remote-ip (Ruby-side)\"\n                     p Array.new(3,\"ruby\")\n                    }', \n                 :text=>'ruby cmd on the remote-ip').pack(:fill=>:x)\n\n  TkButton.new(:command=>'exit', :text=>'QUIT').pack(:fill=>:x)\n}\n\n# setup controller-ip window\nbtns.each_with_index{|btn, idx|\n  # The scope of the eval-block of 'eval_proc' method is different from \n  # the enternal. If you want to pass local values to the eval-block, \n  # use arguments of eval_proc method. They are passed to block-arguments.\n  TkButton.new(:command=>proc{ip.eval_proc(btn){|b| b.flash}}, \n               :text=>\"flash button-#{idx}\", \n               :padx=>10).pack(:padx=>10, :pady=>2)\n}\n\nTkButton.new(:command=>proc{exit}, :text=>'QUIT', \n             :padx=>10, :pady=>7).pack(:padx=>10, :pady=>7)\n\n# start eventloop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/resource.en",
    "content": "!\n!  see Tcl/Tk's \"options\" manual for \"Database Name\" and \"Database Class\"\n!\n*BtnFrame.borderWidth: 5\n*BtnFrame.relief: ridge\n*BtnFrame.Button.background: wheat\n*BtnFrame.Button.foreground: red\n*hello.text: HELLO\n*quit.text: QUIT\n*BTN_CMD.show_msg: {|arg| print \"($SAFE=#{$SAFE}) \";\\\n                          print \"Hello!! This is a sample of #{arg}.\";\\\n                          print \"(<<< $SAFE=#{$SAFE})\\n\"}\n*BTN_CMD.bye_msg:  {print \"($SAFE=#{$SAFE} >>>) Good-bye(<<< $SAFE=#{$SAFE})\\n\"}\n"
  },
  {
    "path": "ext/tk/sample/resource.ja",
    "content": "!\n!  see Tcl/Tk's \"options\" manual for \"Database Name\" and \"Database Class\"\n!\n*BtnFrame.borderWidth: 5\n*BtnFrame.relief: ridge\n*BtnFrame.Button.background: wheat\n*BtnFrame.Button.foreground: red\n*hello.text: ˤ\n*quit.text: λ\n*BTN_CMD.show_msg: {|arg| print \"($SAFE=#{$SAFE} >>>) \";\\\n                          print \"ˤϡ #{arg} ΥץǤ\";\\\n                          print \"(<<< $SAFE=#{$SAFE})\\n\"}\n*BTN_CMD.bye_msg:  {print \"($SAFE=#{$SAFE} >>>) 褦ʤ顥(<<< $SAFE=#{$SAFE})\\n\"}\n"
  },
  {
    "path": "ext/tk/sample/safe-tk.rb",
    "content": "#!/usr/bin/env ruby\n# This script is a sample of MultiTkIp class\n\nrequire \"multi-tk\"\n\n###############################\n\nTkLabel.new(:text=>'This is the Default Master Ipnterpreter').pack(:padx=>5, :pady=>3)\nTkButton.new(:text=>'QUIT', :command=>proc{exit}).pack(:pady=>3)\nTkFrame.new(:borderwidth=>2, :height=>3, \n            :relief=>:sunken).pack(:fill=>:x, :expand=>true,\n                                   :padx=>10, :pady=>7)\n\n###############################\n\nputs \"---- create a safe slave IP with Ruby's safe-level == 1 ----------\"\nip = MultiTkIp.new_safe_slave(1)\n\nputs \"\\n---- create procs ----------\"\nputs 'x = proc{p [\\'proc x\\', \"$SAFE==#{$SAFE}\"]; exit}'\nx = proc{p ['proc x', \"$SAFE==#{$SAFE}\"]; exit}\nTkLabel.new(:text=>'x = proc{p [\\'proc x\\', \"$SAFE==#{$SAFE}\"]; exit}', \n            :anchor=>:w).pack(:fill=>:x)\n\nputs 'y = proc{|label| p [\\'proc y\\', \"$SAFE==#{$SAFE}\", label]; label.text($SAFE)}'\ny = proc{|label| p ['proc y', \"$SAFE==#{$SAFE}\", label]; label.text($SAFE)}\nTkLabel.new(:text=>'y = proc{|label| p [\\'proc y\\', \"$SAFE==#{$SAFE}\", label]; label.text($SAFE)}', \n            :anchor=>:w).pack(:fill=>:x)\n\nputs 'z = proc{p [\\'proc z\\', \"$SAFE==#{$SAFE}\"]; exit}'\nz = proc{p ['proc z', \"$SAFE==#{$SAFE}\"]; exit}\nTkLabel.new(:text=>'z = proc{p [\\'proc z\\', \"$SAFE==#{$SAFE}\"]; exit}', \n            :anchor=>:w).pack(:fill=>:x)\n\nputs \"\\n---- call 1st eval_proc ----------\"\nprint 'lbl = '\np lbl = ip.eval_proc{\n  TkLabel.new(:text=>\"1st eval_proc : $SAFE == #{$SAFE}\").pack\n\n  f = TkFrame.new.pack\n  TkLabel.new(f, :text=>\"$SAFE == \").pack(:side=>:left)\n  # TkLabel.new(f, :text=>\" (<-- 'lbl' widget is here)\").pack(:side=>:right)\n  l = TkLabel.new(f).pack(:side=>:right)\n\n  TkButton.new(:text=>':command=>proc{l.text($SAFE)}', \n               :command=>proc{l.text($SAFE)}).pack(:fill=>:x, :padx=>5)\n  TkButton.new(:text=>':command=>x', :command=>x).pack(:fill=>:x, :padx=>5)\n  TkButton.new(:text=>':command=>proc{exit}', \n               :command=>proc{exit}).pack(:fill=>:x, :padx=>5)\n  TkFrame.new(:borderwidth=>2, :height=>3, \n              :relief=>:sunken).pack(:fill=>:x, :expand=>true,\n                                     :padx=>10, :pady=>7)\n  l # return the label widget\n}\n\nputs \"\\n---- change the safe slave IP's safe-level ==> 3 ----------\"\nip.safe_level = 3\n\nputs \"\\n---- call 2nd eval_proc ----------\"\np ip.eval_proc(proc{\n                 TkLabel.new(:text=>\"2nd eval_proc : $SAFE == #{$SAFE}\").pack\n                 f = TkFrame.new.pack\n                 TkLabel.new(f, :text=>\"$SAFE == \").pack(:side=>:left)\n                 l = TkLabel.new(f, :text=>$SAFE).pack(:side=>:right)\n                 TkButton.new(:text=>':command=>proc{l.text($SAFE)}', \n                              :command=>proc{l.text($SAFE)}).pack(:fill=>:x, \n                                                                  :padx=>5)\n                 TkButton.new(:text=>':command=>proc{y.call(l)}', \n                              :command=>proc{y.call(l)}).pack(:fill=>:x, \n                                                              :padx=>5)\n                 TkButton.new(:text=>':command=>proc{Thread.new(l, &y).value}',\n                              :command=>proc{\n                                Thread.new(l, &y).value\n                              }).pack(:fill=>:x, :padx=>5)\n                 TkButton.new(:text=>':command=>proc{z.call}', \n                              :command=>proc{z.call}).pack(:fill=>:x, :padx=>5)\n                 TkFrame.new(:borderwidth=>2, :height=>3, \n                             :relief=>:sunken).pack(:fill=>:x, :expand=>true,\n                                                    :padx=>10, :pady=>7)\n               })\n\nputs \"\\n---- call 1st and 2nd eval_str ----------\"\np bind = ip.eval_str('\n  TkLabel.new(:text=>\"1st and 2nd eval_str : $SAFE == #{$SAFE}\").pack\n  f = TkFrame.new.pack\n  TkLabel.new(f, :text=>\"$SAFE == \").pack(:side=>:left)\n  l = TkLabel.new(f, :text=>$SAFE).pack(:side=>:right)\n  TkButton.new(:text=>\":command=>proc{y.call(l)}\", \n               :command=>proc{y.call(l)}).pack(:fill=>:x, :padx=>5)\n  binding\n', binding)\n\np ip.eval_str(\"\n  TkButton.new(:text=>':command=>proc{ l.text = $SAFE }', \n               :command=>proc{ l.text = $SAFE }).pack(:fill=>:x, :padx=>5)\n  TkFrame.new(:borderwidth=>2, :height=>3, \n              :relief=>:sunken).pack(:fill=>:x, :expand=>true,\n                                     :padx=>10, :pady=>7)\n\", bind)\n\nputs \"\\n---- change the safe slave IP's safe-level ==> 4 ----------\"\nip.safe_level = 4\n\nputs \"\\n---- call 3rd and 4th eval_proc ----------\"\np ip.eval_proc{\n  TkLabel.new(:text=>\"3rd and 4th eval_proc : $SAFE == #{$SAFE}\").pack\n}\np ip.eval_proc{\n  TkButton.new(:text=>':command=>proc{ lbl.text = $SAFE }', \n               :command=>proc{ lbl.text = $SAFE }).pack(:fill=>:x, :padx=>5)\n}\n\nputs \"\\n---- start event-loop ( current $SAFE == #{$SAFE} ) ----------\"\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/scrollframe.rb",
    "content": "#\n#  Tk::ScrollFrame class\n#\n#    This widget class is a frame widget with scrollbars.\n#    The ScrollFrame doesn't propagate the size of embedded widgets.\n#    When it is configured, scrollregion of the container is changed.\n#\n#    Scrollbars can be toggled by Tk::ScrollFrame#vscroll & hscroll.\n#    If horizontal or virtical scrollbar is turned off, the horizontal \n#    or virtical size of embedded widgets is propagated.\n#\n#                         Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass Tk::ScrollFrame < TkFrame\n  include TkComposite\n\n  DEFAULT_WIDTH  = 200\n  DEFAULT_HEIGHT = 200\n\n  def initialize_composite(keys={})\n    @frame.configure(:width=>DEFAULT_WIDTH, :height=>DEFAULT_HEIGHT)\n\n    # create scrollbars\n    @h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal')\n    @v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')\n\n    # create a canvas widget\n    @canvas = TkCanvas.new(@frame, \n                           :borderwidth=>0, :selectborderwidth=>0, \n                           :highlightthickness=>0)\n\n    # allignment\n    TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)\n    @canvas.grid('row'=>0, 'column'=>0, 'sticky'=>'news')\n    @frame.grid_propagate(false)\n\n    # assign scrollbars\n    @canvas.xscrollbar(@h_scroll)\n    @canvas.yscrollbar(@v_scroll)\n\n    # convert hash keys\n    keys = _symbolkey2str(keys)\n\n    # check options for the frame\n    framekeys = {}\n    if keys.key?('classname')\n       keys['class'] = keys.delete('classname')\n    end\n    if @classname = keys.delete('class')\n      framekeys['class'] = @classname\n    end\n    if @colormap  = keys.delete('colormap')\n      framekeys['colormap'] = @colormap\n    end\n    if @container = keys.delete('container')\n      framekeys['container'] = @container\n    end\n    if @visual    = keys.delete('visual')\n      framekeys['visual'] = @visual\n    end\n    if @classname.kind_of? TkBindTag\n      @db_class = @classname\n      @classname = @classname.id\n    elsif @classname\n      @db_class = TkDatabaseClass.new(@classname)\n    else\n      @db_class = self.class\n      @classname = @db_class::WidgetClassName\n    end\n\n    # create base frame\n    @base = TkFrame.new(@canvas, framekeys)\n\n    # embed base frame\n    @cwin = TkcWindow.new(@canvas, [0, 0], :window=>@base, :anchor=>'nw')\n    @canvas.scrollregion(@cwin.bbox)\n\n    # binding to reset scrollregion\n    @base.bind('Configure'){ _reset_scrollregion(nil, nil) }\n\n    # set default receiver of method calls\n    @path = @base.path\n\n    # scrollbars ON\n    vscroll(keys.delete('vscroll'){true})\n    hscroll(keys.delete('hscroll'){true})\n\n    # please check the differences of the following definitions\n    option_methods(\n      :scrollbarwidth\n    )\n\n    # set receiver widgets for configure methods (with alias)\n    delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll)\n\n    # set receiver widgets for configure methods\n    delegate('DEFAULT', @base)\n    delegate('background', @frame, @base, @canvas, @h_scroll, @v_scroll)\n    delegate('width', @frame)\n    delegate('height', @frame)\n    delegate('activebackground', @h_scroll, @v_scroll)\n    delegate('troughcolor', @h_scroll, @v_scroll)\n    delegate('repeatdelay', @h_scroll, @v_scroll)\n    delegate('repeatinterval', @h_scroll, @v_scroll)\n    delegate('borderwidth', @frame)\n    delegate('relief', @frame)\n\n    # do configure\n    configure keys unless keys.empty?\n  end\n\n  # callback for Configure event\n  def _reset_scrollregion(h_mod=nil, v_mod=nil)\n    cx1, cy1, cx2, cy2 = @canvas.scrollregion\n    x1, y1, x2, y2 = @cwin.bbox\n    @canvas.scrollregion([x1, y1, x2, y2])\n\n    if h_mod.nil? && v_mod.nil?\n      if x2 != cx2 && TkGrid.info(@h_scroll).size == 0\n        @frame.grid_propagate(true)\n        @canvas.width  = x2\n        Tk.update_idletasks\n        @frame.grid_propagate(false)\n      end\n      if y2 != cy2 && TkGrid.info(@v_scroll).size == 0\n        @frame.grid_propagate(true)\n        @canvas.height = y2\n        Tk.update_idletasks\n        @frame.grid_propagate(false)\n      end\n    else\n      @h_scroll.ungrid if h_mod == false\n      @v_scroll.ungrid if v_mod == false\n\n      h_flag = (TkGrid.info(@h_scroll).size == 0)\n      v_flag = (TkGrid.info(@v_scroll).size == 0)\n\n      @frame.grid_propagate(true)\n\n      @canvas.width  = (h_flag)? x2: @canvas.winfo_width\n      @canvas.height = (v_flag)? y2: @canvas.winfo_height\n\n      @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew') if h_mod\n      @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns') if v_mod\n\n      Tk.update_idletasks\n\n      @frame.grid_propagate(false)\n    end\n  end\n  private :_reset_scrollregion\n\n  # forbid to change binding of @base frame\n  def bind(*args)\n    @frame.bind(*args)\n  end\n  def bind_append(*args)\n    @frame.bind_append(*args)\n  end\n  def bind_remove(*args)\n    @frame.bind_remove(*args)\n  end\n  def bindinfo(*args)\n    @frame.bindinfo(*args)\n  end\n\n  # set width of scrollbar\n  def scrollbarwidth(width = nil)\n    if width\n      @h_scroll.width(width)\n      @v_scroll.width(width)\n    else\n      @h_scroll.width\n    end\n  end\n\n  # vertical scrollbar : ON/OFF\n  def vscroll(mode)\n    Tk.update_idletasks\n    st = TkGrid.info(@v_scroll)\n    if mode && st.size == 0 then\n      @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')\n      _reset_scrollregion(nil, true)\n    elsif !mode && st.size != 0 then\n      _reset_scrollregion(nil, false)\n    else\n      _reset_scrollregion(nil, nil)\n    end\n    self\n  end\n\n  # horizontal scrollbar : ON/OFF\n  def hscroll(mode)\n    Tk.update_idletasks\n    st = TkGrid.info(@h_scroll)\n    if mode && st.size == 0 then\n      _reset_scrollregion(true, nil)\n    elsif !mode && st.size != 0 then\n      _reset_scrollregion(false, nil)\n    else\n      _reset_scrollregion(nil, nil)\n    end\n    self\n  end\nend\n\n# test\nif __FILE__ == $0\n  f = Tk::ScrollFrame.new(:scrollbarwidth=>10, :width=>300, :height=>200)\n  f.pack(:expand=>true, :fill=>:both)\n\n  TkButton.new(f, :text=>'foo button', :command=>proc{puts 'foo'}).pack\n  TkButton.new(f, :text=>'baaar button', :command=>proc{puts 'baaar'}).pack\n  TkButton.new(f, :text=>'baz button', :command=>proc{puts 'baz'}).pack\n  TkButton.new(f, :text=>'hoge hoge button', \n               :command=>proc{puts 'hoge hoge'}).pack(:side=>:bottom)\n\n  # f.hscroll(false)\n\n  Tk.after(3000){\n    t = TkText.new(f).pack(:expand=>true, :fill=>:both)\n    t.insert(:end, 'Here is a text widget')\n  }\n\n  Tk.after(6000){ f.vscroll(false) }\n\n  Tk.after(9000){ f.vscroll(true) }\n\n  Tk.after(12000){ f.hscroll(false) }\n\n  Tk.after(15000){ f.hscroll(true) }\n\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/lines0.tcl",
    "content": "#! /usr/local/bin/wish\n\nproc drawlines {} {\n    puts [clock format [clock seconds]]\n\n    for {set j 0} {$j < 100} {incr j} {\n\tputs -nonewline \"*\"\n\tflush stdout\n\tif {$j & 1} {\n\t    set c \"blue\"\n\t} {\n\t    set c \"red\"\n\t}\n\tfor {set i 0} {$i < 100} {incr i} {\n#\t    .a create line $i 0 0 [expr 500 - $i] -fill $c\n\t}\n    }\n\n    puts [clock format [clock seconds]]\n\n    for {set j 0} {$j < 100} {incr j} {\n\tputs -nonewline \"*\"\n\tflush stdout\n\tif {$j & 1} {\n\t    set c \"blue\"\n\t} {\n\t    set c \"red\"\n\t}\n\tfor {set i 0} {$i < 100} {incr i} {\n\t    .a create line $i 0 0 [expr 500 - $i] -fill $c\n\t}\n    }\n\n    puts [clock format [clock seconds]]\n#    destroy .\n}\n\ncanvas .a -height 500 -width 500\nbutton .b -text draw -command drawlines\npack .a .b -side left\n\n# eof\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/lines1.rb",
    "content": "#! /usr/local/bin/ruby\n\nrequire \"tcltk\"\n\ndef drawlines()\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n#      $a.e(\"create line\", i, 0, 0, 500 - i, \"-fill\", col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n      $a.e(\"create line\", i, 0, 0, 500 - i, \"-fill\", col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n#  $ip.commands()[\"destroy\"].e($root)\nend\n\n$ip = TclTkInterpreter.new()\n$root = $ip.rootwidget()\n$a = TclTkWidget.new($ip, $root, \"canvas\", \"-height 500 -width 500\")\n$c = TclTkCallback.new($ip, proc{drawlines()})\n$b = TclTkWidget.new($ip, $root, \"button\", \"-text draw -command\", $c)\n\n$ip.commands()[\"pack\"].e($a, $b, \"-side left\")\n\nTclTk.mainloop\n\n# eof\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/lines2.rb",
    "content": "#! /usr/local/bin/ruby\n\nrequire \"tk\"\n\ndef drawlines()\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n#      TkcLine.new($a, i, 0, 0, 500 - i, \"-fill\", col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n      TkcLine.new($a, i, 0, 0, 500 - i, \"-fill\", col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n#  Tk.root.destroy\nend\n\n$a = TkCanvas.new{\n  height(500)\n  width(500)\n}\n\n$b = TkButton.new{\n  text(\"draw\")\n  command(proc{drawlines()})\n}\n\nTkPack.configure($a, $b, {\"side\"=>\"left\"})\n\nTk.mainloop\n\n# eof\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/lines3.rb",
    "content": "#! /usr/local/bin/ruby\n\nrequire \"tk\"\n\ndef drawlines()\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n#      $a.create(TkcLine, i, 0, 0, 500 - i, \"fill\"=>col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n      $a.create(TkcLine, i, 0, 0, 500 - i, \"fill\"=>col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n#  Tk.root.destroy\nend\n\n$a = TkCanvas.new{\n  height(500)\n  width(500)\n}\n\n$b = TkButton.new{\n  text(\"draw\")\n  command(proc{drawlines()})\n}\n\nTkPack.configure($a, $b, {\"side\"=>\"left\"})\n\nTk.mainloop\n\n# eof\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/lines4.rb",
    "content": "#! /usr/local/bin/ruby\n\nrequire \"tk\"\n\ndef drawlines()\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n#      TkCore::INTERP.__invoke($a.path, \"create\", \"line\", i.to_s, '0', '0', (500 - i).to_s, \"-fill\", col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n\n  for j in 0 .. 99\n    print \"*\"\n    $stdout.flush\n    if (j & 1) != 0\n      col = \"blue\"\n    else\n      col = \"red\"\n    end\n    for i in 0 .. 99\n      TkCore::INTERP.__invoke($a.path, \"create\", \"line\", i.to_s, '0', '0', (500 - i).to_s, \"-fill\", col)\n    end\n  end\n\n  print Time.now, \"\\n\"\n#  Tk.root.destroy\nend\n\n$a = TkCanvas.new{\n  height(500)\n  width(500)\n}\n\n$b = TkButton.new{\n  text(\"draw\")\n  command(proc{drawlines()})\n}\n\nTkPack.configure($a, $b, {\"side\"=>\"left\"})\n\nTk.mainloop\n\n# eof\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/safeTk.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tcltklib'\n\nmaster = TclTkIp.new\nslave_name = 'slave0'\nslave = master.create_slave(slave_name, true)\nmaster._eval(\"::safe::interpInit #{slave_name}\")\nmaster._eval(\"::safe::loadTk #{slave_name}\")\n\nmaster._invoke('label', '.l1', '-text', 'master')\nmaster._invoke('pack', '.l1', '-padx', '30', '-pady', '50')\nmaster._eval('label .l2 -text {root widget of master-ip}')\nmaster._eval('pack .l2 -padx 30 -pady 50')\n\nslave._invoke('label', '.l1', '-text', 'slave')\nslave._invoke('pack', '.l1', '-padx', '30', '-pady', '50')\nslave._eval('label .l2 -text {root widget of slave-ip}')\nslave._eval('pack .l2 -padx 30 -pady 20')\nslave._eval('label .l3 -text {( container frame widget of master-ip )}')\nslave._eval('pack .l3 -padx 30 -pady 20')\n\nTclTkLib.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/sample0.rb",
    "content": "#! /usr/local/bin/ruby -vd\n\n# tcltklib 饤֥Υƥ\n\nrequire \"tcltklib\"\n\ndef test\n  # 󥿥ץ꥿\n  ip1 = TclTkIp.new()\n\n  # ɾƤߤ\n  print ip1._return_value().inspect, \"\\n\"\n  print ip1._eval(\"puts {abc}\").inspect, \"\\n\"\n\n  # ܥäƤߤ\n  print ip1._return_value().inspect, \"\\n\"\n  print ip1._eval(\"button .lab -text exit -command \\\"destroy .\\\"\").inspect,\n    \"\\n\"\n  print ip1._return_value().inspect, \"\\n\"\n  print ip1._eval(\"pack .lab\").inspect, \"\\n\"\n  print ip1._return_value().inspect, \"\\n\"\n\n  # 󥿥ץ꥿ ruby ޥɤɾƤߤ\n#  print ip1._eval(%q/ruby {print \"print by ruby\\n\"}/).inspect, \"\\n\"\n  print ip1._eval(%q+puts [ruby {print \"print by ruby\\n\"; \"puts by tcl/tk\"}]+).inspect, \"\\n\"\n  print ip1._return_value().inspect, \"\\n\"\n\n  # ⤦ĥ󥿥ץ꥿Ƥߤ\n  ip2 = TclTkIp.new()\n  ip2._eval(\"button .lab -text test -command \\\"puts test ; destroy .\\\"\")\n  ip2._eval(\"pack .lab\")\n\n  TclTkLib.mainloop\nend\n\ntest\nGC.start\n\nprint \"exit\\n\"\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/sample1.rb",
    "content": "#! /usr/local/bin/ruby -d\n#! /usr/local/bin/ruby\n# -d ץդ, ǥХåɽ.\n\n# tcltk 饤֥Υץ\n\n# ޤ, 饤֥ require .\nrequire \"tcltk\"\n\n# ʲ, Test1 Υ󥹥󥹤 initialize() ,\n# tcl/tk ˴ؤԤǤ.\n# ɬ⤽Τ褦ˤɬפ̵,\n# (⤷, ) class γ tcl/tk ˴ؤԤäƤɤ.\n\nclass Test1\n  # (󥿥ץ꥿ƥåȤ).\n  def initialize()\n\n    #### ȤΤޤʤ\n\n    # 󥿥ץ꥿.\n    ip = TclTkInterpreter.new()\n    # ޥɤб륪֥Ȥ c ꤷƤ.\n    c = ip.commands()\n    # Ѥ륳ޥɤб륪֥ȤѿƤ.\n    append, bind, button, destroy, incr, info, label, place, set, wm =\n      c.values_at(\n      \"append\", \"bind\", \"button\", \"destroy\", \"incr\", \"info\", \"label\", \"place\",\n      \"set\", \"wm\")\n\n    #### tcl/tk Υޥɤб륪֥(TclTkCommand)\n\n    # ¹Ԥ, e() ᥽åɤȤ.\n    # (ʲ, tcl/tk ˤ info command r* ¹.)\n    print info.e(\"command\", \"r*\"), \"\\n\"\n    # , ޤȤ᤿ʸˤƤƱ.\n    print info.e(\"command r*\"), \"\\n\"\n    # ѿѤʤȤ¹ԤǤ뤬, ᤬.\n    print c[\"info\"].e(\"command\", \"r*\"), \"\\n\"\n    # 󥿥ץ꥿Υ᥽åɤȤƤ¹ԤǤ뤬, Ψ.\n    print ip.info(\"command\", \"r*\"), \"\\n\"\n\n    ####\n\n    # ʲ, ֥ȤѿƤʤ\n    # GC оݤˤʤäƤޤ.\n\n    #### tcl/tk ѿб륪֥(TclTkVariable)\n\n    # Ʊͤꤹ.\n    v1 = TclTkVariable.new(ip, \"20\")\n    # ɤ߽Ф get ᥽åɤȤ.\n    print v1.get(), \"\\n\"\n    #  set ᥽åɤȤ.\n    v1.set(40)\n    print v1.get(), \"\\n\"\n    # set ޥɤȤäɤ߽Ф, ϲǽ᤬.\n    # e() ᥽åΰľ TclTkObject ͤ񤤤Ƥɤ.\n    set.e(v1, 30)\n    print set.e(v1), \"\\n\"\n    # tcl/tk ΥޥɤѿǤ.\n    incr.e(v1)\n    print v1.get(), \"\\n\"\n    append.e(v1, 10)\n    print v1.get(), \"\\n\"\n\n    #### tcl/tk ΥåȤб륪֥(TclTkWidget)\n\n    # 롼ȥåȤФ.\n    root = ip.rootwidget()\n    # åȤ.\n    root.e(\"configure -height 300 -width 300\")\n    # ȥդȤ wm Ȥ.\n    wm.e(\"title\", root, $0)\n    # ƥåȤȥޥɤꤷ, åȤ.\n    l1 = TclTkWidget.new(ip, root, label, \"-text {type `x' to print}\")\n    # place ɽ.\n    place.e(l1, \"-x 0 -rely 0.0 -relwidth 1 -relheight 0.1\")\n    # ޥ̾ʸǻꤷƤɤ, ᤬.\n    # (ޥ̾ΩǤʤФʤʤ.)\n    l2 = TclTkWidget.new(ip, root, \"label\")\n    # åȤ.\n    l2.e(\"configure -text {type `q' to exit}\")\n    place.e(l2, \"-x 0 -rely 0.1 -relwidth 1 -relheight 0.1\")\n\n    #### tcl/tk ΥХåб륪֥(TclTkCallback)\n\n    # Хå.\n    c1 = TclTkCallback.new(ip, proc{sample(ip, root)})\n    # ХåĥåȤ.\n    b1 = TclTkWidget.new(ip, root, button, \"-text sample -command\", c1)\n    place.e(b1, \"-x 0 -rely 0.2 -relwidth 1 -relheight 0.1\")\n    # ٥ȥ롼פȴˤ destroy.e(root) .\n    c2 = TclTkCallback.new(ip, proc{destroy.e(root)})\n    b2 = TclTkWidget.new(ip, root, button, \"-text exit -command\", c2)\n    place.e(b2, \"-x 0 -rely 0.3 -relwidth 1 -relheight 0.1\")\n\n    #### ٥ȤΥХ\n    # script ɲ (bind tag sequence +script) ϺΤȤǤʤ.\n    # (ƥ졼ѿ꤬ޤʤ.)\n\n    # ŪˤϥåȤФ륳ХåƱ.\n    c3 = TclTkCallback.new(ip, proc{print(\"q pressed\\n\"); destroy.e(root)})\n    bind.e(root, \"q\", c3)\n    # bind ޥɤ % ִˤѥ᡼ꤿȤ,\n    # proc{} θʸǻꤹ,\n    # ִ̤򥤥ƥ졼ѿ̤Ƽ뤳ȤǤ.\n    #  proc{} θʸ,\n    # bind ޥɤͿ륳ХåʳǻꤷƤϤʤ.\n    c4 = TclTkCallback.new(ip, proc{|i| print(\"#{i} pressed\\n\")}, \"%A\")\n    bind.e(root, \"x\", c4)\n    # TclTkCallback  GC оݤˤ,\n    # dcb() (ޤ deletecallbackkeys()) ɬפ.\n    cb = [c1, c2, c3, c4]\n    c5 = TclTkCallback.new(ip, proc{|w| TclTk.dcb(cb, root, w)}, \"%W\")\n    bind.e(root, \"<Destroy>\", c5)\n    cb.push(c5)\n\n    #### tcl/tk Υ᡼б륪֥(TclTkImage)\n\n    # ǡꤷ.\n    i1 = TclTkImage.new(ip, \"photo\", \"-file maru.gif\")\n    # ٥ĥդƤߤ.\n    l3 = TclTkWidget.new(ip, root, label, \"-relief raised -image\", i1)\n    place.e(l3, \"-x 0 -rely 0.4 -relwidth 0.2 -relheight 0.2\")\n    # Υ᡼Ƹ.\n    i2 = TclTkImage.new(ip, \"photo\")\n    # ᡼.\n    i2.e(\"copy\", i1)\n    i2.e(\"configure -gamma 0.5\")\n    l4 = TclTkWidget.new(ip, root, label, \"-relief raised -image\", i2)\n    place.e(l4, \"-relx 0.2 -rely 0.4 -relwidth 0.2 -relheight 0.2\")\n\n    ####\n  end\n\n  # ץΤΥåȤ.\n  def sample(ip, parent)\n    bind, button, destroy, grid, toplevel, wm = ip.commands().values_at(\n      \"bind\", \"button\", \"destroy\", \"grid\", \"toplevel\", \"wm\")\n\n    ## toplevel\n\n    # ɥ򳫤ˤ, toplevel Ȥ.\n    t1 = TclTkWidget.new(ip, parent, toplevel)\n    # ȥդƤ\n    wm.e(\"title\", t1, \"sample\")\n\n    # åȤ˲줿Ȥ, Хå GC оݤˤʤ褦ˤ.\n    cb = []\n    cb.push(c = TclTkCallback.new(ip, proc{|w| TclTk.dcb(cb, t1, w)}, \"%W\"))\n    bind.e(t1, \"<Destroy>\", c)\n\n    # ܥ.\n    wid = []\n    # toplevel åȤ˲ˤ destroy .\n    cb.push(c = TclTkCallback.new(ip, proc{destroy.e(t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text close -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_label(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text label -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_button(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text button -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_checkbutton(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text checkbutton -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_radiobutton(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text radiobutton -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_scale(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text scale -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_entry(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text entry -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_text(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text text -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_raise(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text raise/lower -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_modal(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text message/modal -command\",\n      c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_menu(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text menu -command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_listbox(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text listbox/scrollbar\",\n      \"-command\", c))\n    cb.push(c = TclTkCallback.new(ip, proc{test_canvas(ip, t1)}))\n    wid.push(TclTkWidget.new(ip, t1, button, \"-text canvas -command\", c))\n\n    # grid ɽ.\n    ro = co = 0\n    wid.each{|w|\n      grid.e(w, \"-row\", ro, \"-column\", co, \"-sticky news\")\n      ro += 1\n      if ro == 7\n        ro = 0\n        co += 1\n      end\n    }\n  end\n\n  # inittoplevel(ip, parent, title)\n  #   ʲνޤȤƹԤ.\n  #       1. toplevel åȤ.\n  #       2. ХåϿѰդ, toplevel åȤ\n  #         <Destroy> ٥Ȥ˥Хå³Ͽ.\n  #       3. ܥ.\n  #      toplevel å, ܥ, ХåϿѿ\n  #     ֤.\n  #   ip: 󥿥ץ꥿\n  #   parent: ƥå\n  #   title: toplevel åȤΥɥΥȥ\n  def inittoplevel(ip, parent, title)\n    bind, button, destroy, toplevel, wm = ip.commands().values_at(\n      \"bind\", \"button\", \"destroy\", \"toplevel\", \"wm\")\n\n    # ɥ򳫤ˤ, toplevel Ȥ.\n    t1 = TclTkWidget.new(ip, parent, toplevel)\n    # ȥդƤ\n    wm.e(\"title\", t1, title)\n\n    # åȤ˲줿Ȥ, Хå GC оݤˤʤ褦ˤ.\n    cb = []\n    cb.push(c = TclTkCallback.new(ip, proc{|w| TclTk.dcb(cb, t1, w)}, \"%W\"))\n    bind.e(t1, \"<Destroy>\", c)\n    # close ܥäƤ.\n    # toplevel åȤ˲ˤ destroy .\n    cb.push(c = TclTkCallback.new(ip, proc{destroy.e(t1)}))\n    b1 = TclTkWidget.new(ip, t1, button, \"-text close -command\", c)\n\n    return t1, b1, cb\n  end\n\n  # label Υץ.\n  def test_label(ip, parent)\n    button, global, label, pack = ip.commands().values_at(\n      \"button\", \"global\", \"label\", \"pack\")\n    t1, b1, cb = inittoplevel(ip, parent, \"label\")\n\n    ## label\n\n    # ʷΥ٥.\n    l1 = TclTkWidget.new(ip, t1, label, \"-text {default(flat)}\")\n    l2 = TclTkWidget.new(ip, t1, label, \"-text raised -relief raised\")\n    l3 = TclTkWidget.new(ip, t1, label, \"-text sunken -relief sunken\")\n    l4 = TclTkWidget.new(ip, t1, label, \"-text groove -relief groove\")\n    l5 = TclTkWidget.new(ip, t1, label, \"-text ridge -relief ridge\")\n    l6 = TclTkWidget.new(ip, t1, label, \"-bitmap error\")\n    l7 = TclTkWidget.new(ip, t1, label, \"-bitmap questhead\")\n\n    # pack Ƥɽ.\n    pack.e(b1, l1, l2, l3, l4, l5, l6, l7, \"-pady 3\")\n\n    ## -textvariable\n\n    # tcltk 饤֥μǤ, Хå tcl/tk ``³''̤\n    # ƤФ. ä, Хå()ѿ˥Ȥ,\n    # global ɬפ.\n    # global ѿͤꤷƤޤȥ顼ˤʤΤ,\n    # tcl/tk ˤɽ, ºݤͤꤷʤ褦,\n    # 2 ܤΰˤ nil Ϳ.\n    v1 = TclTkVariable.new(ip, nil)\n    global.e(v1)\n    v1.set(100)\n    # -textvariable ѿꤹ.\n    l6 = TclTkWidget.new(ip, t1, label, \"-textvariable\", v1)\n    # Хå椫ѿ.\n    cb.push(c = TclTkCallback.new(ip, proc{\n      global.e(v1); v1.set(v1.get().to_i + 10)}))\n    b2 = TclTkWidget.new(ip, t1, button, \"-text +10 -command\", c)\n    cb.push(c = TclTkCallback.new(ip, proc{\n      global.e(v1); v1.set(v1.get().to_i - 10)}))\n    b3 = TclTkWidget.new(ip, t1, button, \"-text -10 -command\", c)\n    pack.e(l6, b2, b3)\n  end\n\n  # button Υץ.\n  def test_button(ip, parent)\n    button, pack = ip.commands().values_at(\"button\", \"pack\")\n    t1, b1, cb = inittoplevel(ip, parent, \"button\")\n\n    ## button\n\n    # ХåǻȤѿƤʤФʤʤ.\n    b3 = b4 = nil\n    cb.push(c = TclTkCallback.new(ip, proc{b3.e(\"flash\"); b4.e(\"flash\")}))\n    b2 = TclTkWidget.new(ip, t1, button, \"-text flash -command\", c)\n    cb.push(c = TclTkCallback.new(ip, proc{b2.e(\"configure -state normal\")}))\n    b3 = TclTkWidget.new(ip, t1, button, \"-text normal -command\", c)\n    cb.push(c = TclTkCallback.new(ip, proc{b2.e(\"configure -state disabled\")}))\n    b4 = TclTkWidget.new(ip, t1, button, \"-text disable -command\", c)\n    pack.e(b1, b2, b3, b4)\n  end\n\n  # checkbutton Υץ.\n  def test_checkbutton(ip, parent)\n    checkbutton, global, pack = ip.commands().values_at(\n      \"checkbutton\", \"global\", \"pack\")\n    t1, b1, cb = inittoplevel(ip, parent, \"checkbutton\")\n\n    ## checkbutton\n\n    v1 = TclTkVariable.new(ip, nil)\n    global.e(v1)\n    # -variable ѿꤹ.\n    ch1 = TclTkWidget.new(ip, t1, checkbutton, \"-onvalue on -offvalue off\",\n      \"-textvariable\", v1, \"-variable\", v1)\n    pack.e(b1, ch1)\n  end\n\n  # radiobutton Υץ.\n  def test_radiobutton(ip, parent)\n    global, label, pack, radiobutton = ip.commands().values_at(\n      \"global\", \"label\", \"pack\", \"radiobutton\")\n    t1, b1, cb = inittoplevel(ip, parent, \"radiobutton\")\n\n    ## radiobutton\n\n    v1 = TclTkVariable.new(ip, nil)\n    global.e(v1)\n    # ̥륹ȥ󥰤 \"{}\" ǻꤹ.\n    v1.set(\"{}\")\n    l1 = TclTkWidget.new(ip, t1, label, \"-textvariable\", v1)\n    # -variable ƱѿꤹƱ롼פˤʤ.\n    ra1 = TclTkWidget.new(ip, t1, radiobutton,\n      \"-text radio1 -value r1 -variable\", v1)\n    ra2 = TclTkWidget.new(ip, t1, radiobutton,\n      \"-text radio2 -value r2 -variable\", v1)\n    cb.push(c = TclTkCallback.new(ip, proc{global.e(v1); v1.set(\"{}\")}))\n    ra3 = TclTkWidget.new(ip, t1, radiobutton,\n      \"-text clear -value r3 -variable\", v1, \"-command\", c)\n    pack.e(b1, l1, ra1, ra2, ra3)\n  end\n\n  # scale Υץ.\n  def test_scale(ip, parent)\n    global, pack, scale = ip.commands().values_at(\n      \"global\", \"pack\", \"scale\")\n    t1, b1, cb = inittoplevel(ip, parent, \"scale\")\n\n    ## scale\n\n    v1 = TclTkVariable.new(ip, nil)\n    global.e(v1)\n    v1.set(219)\n    # ХåǻȤѿƤʤФʤʤ.\n    sca1 = nil\n    cb.push(c = TclTkCallback.new(ip, proc{global.e(v1); v = v1.get();\n      sca1.e(\"configure -background\", format(\"#%02x%02x%02x\", v, v, v))}))\n    sca1 = TclTkWidget.new(ip, t1, scale,\n      \"-label scale -orient h -from 0 -to 255 -variable\", v1, \"-command\", c)\n    pack.e(b1, sca1)\n  end\n\n  # entry Υץ.\n  def test_entry(ip, parent)\n    button, entry, global, pack = ip.commands().values_at(\n      \"button\", \"entry\", \"global\", \"pack\")\n    t1, b1, cb = inittoplevel(ip, parent, \"entry\")\n\n    ## entry\n\n    v1 = TclTkVariable.new(ip, nil)\n    global.e(v1)\n    # ̥륹ȥ󥰤 \"{}\" ǻꤹ.\n    v1.set(\"{}\")\n    en1 = TclTkWidget.new(ip, t1, entry, \"-textvariable\", v1)\n    cb.push(c = TclTkCallback.new(ip, proc{\n      global.e(v1); print(v1.get(), \"\\n\"); v1.set(\"{}\")}))\n    b2 = TclTkWidget.new(ip, t1, button, \"-text print -command\", c)\n    pack.e(b1, en1, b2)\n  end\n\n  # text Υץ.\n  def test_text(ip, parent)\n    button, pack, text = ip.commands().values_at(\n      \"button\", \"pack\", \"text\")\n    t1, b1, cb = inittoplevel(ip, parent, \"text\")\n\n    ## text\n\n    te1 = TclTkWidget.new(ip, t1, text)\n    cb.push(c = TclTkCallback.new(ip, proc{\n      # 1 ܤ 0 ʸܤǸޤǤɽ, .\n      print(te1.e(\"get 1.0 end\")); te1.e(\"delete 1.0 end\")}))\n    b2 = TclTkWidget.new(ip, t1, button, \"-text print -command\", c)\n    pack.e(b1, te1, b2)\n  end\n\n  # raise/lower Υץ.\n  def test_raise(ip, parent)\n    button, frame, lower, pack, raise = ip.commands().values_at(\n      \"button\", \"frame\", \"lower\", \"pack\", \"raise\")\n    t1, b1, cb = inittoplevel(ip, parent, \"raise/lower\")\n\n    ## raise/lower\n\n    # button 򱣤ƥȤΤ, frame Ȥ.\n    f1 = TclTkWidget.new(ip, t1, frame)\n    # ХåǻȤѿƤʤФʤʤ.\n    b2 = nil\n    cb.push(c = TclTkCallback.new(ip, proc{raise.e(f1, b2)}))\n    b2 = TclTkWidget.new(ip, t1, button, \"-text raise -command\", c)\n    cb.push(c = TclTkCallback.new(ip, proc{lower.e(f1, b2)}))\n    b3 = TclTkWidget.new(ip, t1, button, \"-text lower -command\", c)\n    lower.e(f1, b3)\n\n    pack.e(b2, b3, \"-in\", f1)\n    pack.e(b1, f1)\n  end\n\n  # modal ʥåȤΥץ.\n  def test_modal(ip, parent)\n    button, frame, message, pack, tk_chooseColor, tk_getOpenFile,\n      tk_messageBox = ip.commands().values_at(\n      \"button\", \"frame\", \"message\", \"pack\", \"tk_chooseColor\",\n      \"tk_getOpenFile\", \"tk_messageBox\")\n    # ǽ load Ƥʤ饤֥ ip.commands() ¸ߤʤΤ,\n    # TclTkLibCommand ɬפ.\n    tk_dialog = TclTkLibCommand.new(ip, \"tk_dialog\")\n    t1, b1, cb = inittoplevel(ip, parent, \"message/modal\")\n\n    ## message\n\n    mes = \" message åȤΥƥȤǤ.\"\n    mes += \"ʲ modal ʥåȤΥƥȤǤ.\"\n    me1 = TclTkWidget.new(ip, t1, message, \"-text {#{mes}}\")\n\n    ## modal\n\n    # tk_messageBox\n    cb.push(c = TclTkCallback.new(ip, proc{\n      print tk_messageBox.e(\"-type yesnocancel -message messageBox\",\n      \"-icon error -default cancel -title messageBox\"), \"\\n\"}))\n    b2 = TclTkWidget.new(ip, t1, button, \"-text messageBox -command\", c)\n    # tk_dialog\n    cb.push(c = TclTkCallback.new(ip, proc{\n      # å̾뤿˥ߡ frame .\n      print tk_dialog.e(TclTkWidget.new(ip, t1, frame),\n      \"dialog dialog error 2 yes no cancel\"), \"\\n\"}))\n    b3 = TclTkWidget.new(ip, t1, button, \"-text dialog -command\", c)\n    # tk_chooseColor\n    cb.push(c = TclTkCallback.new(ip, proc{\n      print tk_chooseColor.e(\"-title chooseColor\"), \"\\n\"}))\n    b4 = TclTkWidget.new(ip, t1, button, \"-text chooseColor -command\", c)\n    # tk_getOpenFile\n    cb.push(c = TclTkCallback.new(ip, proc{\n      print tk_getOpenFile.e(\"-defaultextension .rb\",\n      \"-filetypes {{{Ruby Script} {.rb}} {{All Files} {*}}}\",\n      \"-title getOpenFile\"), \"\\n\"}))\n    b5 = TclTkWidget.new(ip, t1, button, \"-text getOpenFile -command\", c)\n\n    pack.e(b1, me1, b2, b3, b4, b5)\n  end\n\n  # menu Υץ.\n  def test_menu(ip, parent)\n    global, menu, menubutton, pack = ip.commands().values_at(\n      \"global\", \"menu\", \"menubutton\", \"pack\")\n    tk_optionMenu = TclTkLibCommand.new(ip, \"tk_optionMenu\")\n    t1, b1, cb = inittoplevel(ip, parent, \"menu\")\n\n    ## menu\n\n    # menubutton .\n    mb1 = TclTkWidget.new(ip, t1, menubutton, \"-text menu\")\n    # menu .\n    me1 = TclTkWidget.new(ip, mb1, menu)\n    # mb1  me1 ư褦ˤ.\n    mb1.e(\"configure -menu\", me1)\n\n    # cascade ǵư menu .\n    me11 = TclTkWidget.new(ip, me1, menu)\n    # radiobutton Υץ.\n    v1 = TclTkVariable.new(ip, nil); global.e(v1); v1.set(\"r1\")\n    me11.e(\"add radiobutton -label radio1 -value r1 -variable\", v1)\n    me11.e(\"add radiobutton -label radio2 -value r2 -variable\", v1)\n    me11.e(\"add radiobutton -label radio3 -value r3 -variable\", v1)\n    # cascade ˤ mb11 ư褦ˤ.\n    me1.e(\"add cascade -label cascade -menu\", me11)\n\n    # checkbutton Υץ.\n    v2 = TclTkVariable.new(ip, nil); global.e(v2); v2.set(\"none\")\n    me1.e(\"add checkbutton -label check -variable\", v2)\n    # separator Υץ.\n    me1.e(\"add separator\")\n    # command Υץ.\n    v3 = nil\n    cb.push(c = TclTkCallback.new(ip, proc{\n      global.e(v1, v2, v3); print \"v1: \", v1.get(), \", v2: \", v2.get(),\n      \", v3: \", v3.get(), \"\\n\"}))\n    me1.e(\"add command -label print -command\", c)\n\n    ## tk_optionMenu\n\n    v3 = TclTkVariable.new(ip, nil); global.e(v3); v3.set(\"opt2\")\n    om1 = TclTkWidget.new(ip, t1, tk_optionMenu, v3, \"opt1 opt2 opt3 opt4\")\n\n    pack.e(b1, mb1, om1, \"-side left\")\n  end\n\n  # listbox Υץ.\n  def test_listbox(ip, parent)\n    clipboard, frame, grid, listbox, lower, menu, menubutton, pack, scrollbar,\n      selection = ip.commands().values_at(\n      \"clipboard\", \"frame\", \"grid\", \"listbox\", \"lower\", \"menu\", \"menubutton\",\n      \"pack\", \"scrollbar\", \"selection\")\n    t1, b1, cb = inittoplevel(ip, parent, \"listbox\")\n\n    ## listbox/scrollbar\n\n    f1 = TclTkWidget.new(ip, t1, frame)\n    # ХåǻȤѿƤʤФʤʤ.\n    li1 = sc1 = sc2 = nil\n    # ¹Ի, ˥ѥ᡼ĤХå,\n    # ƥ졼ѿǤΥѥ᡼뤳ȤǤ.\n    # (ʣΥѥ᡼ϤҤȤĤʸˤޤȤ.)\n    cb.push(c1 = TclTkCallback.new(ip, proc{|i| li1.e(\"xview\", i)}))\n    cb.push(c2 = TclTkCallback.new(ip, proc{|i| li1.e(\"yview\", i)}))\n    cb.push(c3 = TclTkCallback.new(ip, proc{|i| sc1.e(\"set\", i)}))\n    cb.push(c4 = TclTkCallback.new(ip, proc{|i| sc2.e(\"set\", i)}))\n    # listbox\n    li1 = TclTkWidget.new(ip, f1, listbox,\n      \"-xscrollcommand\", c3, \"-yscrollcommand\", c4,\n      \"-selectmode extended -exportselection true\")\n    for i in 1..20\n      li1.e(\"insert end {line #{i} line #{i} line #{i} line #{i} line #{i}}\")\n    end\n    # scrollbar\n    sc1 = TclTkWidget.new(ip, f1, scrollbar, \"-orient horizontal -command\", c1)\n    sc2 = TclTkWidget.new(ip, f1, scrollbar, \"-orient vertical -command\", c2)\n\n    ## selection/clipboard\n\n    mb1 = TclTkWidget.new(ip, t1, menubutton, \"-text edit\")\n    me1 = TclTkWidget.new(ip, mb1, menu)\n    mb1.e(\"configure -menu\", me1)\n    cb.push(c = TclTkCallback.new(ip, proc{\n      # clipboard 򥯥ꥢ.\n      clipboard.e(\"clear\")\n      # selection ʸɤ߹ clipboard ɲä.\n      clipboard.e(\"append {#{selection.e('get')}}\")}))\n    me1.e(\"add command -label {selection -> clipboard} -command\",c)\n    cb.push(c = TclTkCallback.new(ip, proc{\n      # li1 򥯥ꥢ.\n      li1.e(\"delete 0 end\")\n      # clipboard ʸФ, 1 Ԥ\n      selection.e(\"get -selection CLIPBOARD\").split(/\\n/).each{|line|\n        # li1 .\n        li1.e(\"insert end {#{line}}\")}}))\n    me1.e(\"add command -label {clipboard -> listbox} -command\",c)\n\n    grid.e(li1, \"-row 0 -column 0 -sticky news\")\n    grid.e(sc1, \"-row 1 -column 0 -sticky ew\")\n    grid.e(sc2, \"-row 0 -column 1 -sticky ns\")\n    grid.e(\"rowconfigure\", f1, \"0 -weight 100\")\n    grid.e(\"columnconfigure\", f1, \"0 -weight 100\")\n    f2 = TclTkWidget.new(ip, t1, frame)\n    lower.e(f2, b1)\n    pack.e(b1, mb1, \"-in\", f2, \"-side left\")\n    pack.e(f2, f1)\n  end\n\n  # canvas Υץ.\n  def test_canvas(ip, parent)\n    canvas, lower, pack = ip.commands().values_at(\"canvas\", \"lower\", \"pack\")\n    t1, b1, cb = inittoplevel(ip, parent, \"canvas\")\n\n    ## canvas\n\n    ca1 = TclTkWidget.new(ip, t1, canvas, \"-width 400 -height 300\")\n    lower.e(ca1, b1)\n    # rectangle .\n    idr = ca1.e(\"create rectangle 10 10 20 20\")\n    # oval .\n    ca1.e(\"create oval 60 10 100 50\")\n    # polygon .\n    ca1.e(\"create polygon 110 10 110 30 140 10\")\n    # line .\n    ca1.e(\"create line 150 10 150 30 190 10\")\n    # arc .\n    ca1.e(\"create arc 200 10 250 50 -start 0 -extent 90 -style pieslice\")\n    # i1 , ɤ˲ʤФʤʤ, ݤʤΤäƤ.\n    i1 = TclTkImage.new(ip, \"photo\", \"-file maru.gif\")\n    # image .\n    ca1.e(\"create image 100 100 -image\", i1)\n    # bitmap .\n    ca1.e(\"create bitmap 260 50 -bitmap questhead\")\n    # text .\n    ca1.e(\"create text 320 50 -text {drag rectangle}\")\n    # window (ܥ).\n    ca1.e(\"create window 200 200 -window\", b1)\n\n    # bind ˤ rectangle  drag Ǥ褦ˤ.\n    cb.push(c = TclTkCallback.new(ip, proc{|i|\n      # i  x  y Τ, Ф.\n      x, y = i.split(/ /); x = x.to_f; y = y.to_f\n      # ɸѹ.\n      ca1.e(\"coords current #{x - 5} #{y - 5} #{x + 5} #{y + 5}\")},\n      # x, y ɸǶڤäΤ򥤥ƥ졼ѿϤ褦˻.\n      \"%x %y\"))\n    # rectangle  bind .\n    ca1.e(\"bind\", idr, \"<B1-Motion>\", c)\n\n    pack.e(ca1)\n  end\nend\n\n# test driver\n\nif ARGV.size == 0\n  print \"#{$0} n , n ĤΥ󥿥ץ꥿ưޤ.\\n\"\n  n = 1\nelse\n  n = ARGV[0].to_i\nend\n\nprint \"start\\n\"\nip = []\n\n# 󥿥ץ꥿, å.\nfor i in 1 .. n\n  ip.push(Test1.new())\nend\n\n# ѰդǤ饤٥ȥ롼פ.\nTclTk.mainloop()\nprint \"exit from mainloop\\n\"\n\n# 󥿥ץ꥿ GC 뤫Υƥ.\nip = []\nprint \"GC.start\\n\" if $DEBUG\nGC.start() if $DEBUG\nprint \"end\\n\"\n\nexit\n\n# end\n"
  },
  {
    "path": "ext/tk/sample/tcltklib/sample2.rb",
    "content": "#!/usr/local/bin/ruby\n#----------------------> pretty simple othello game <-----------------------\n# othello.rb\n#\n# version 0.3\n# maeda shugo (shuto@po.aianet.ne.jp)\n#---------------------------------------------------------------------------\n\n#       Sep. 17, 1997   modified by Y. Shigehiro for tcltk library\n#          maeda shugo (shugo@po.aianet.ne.jp) ˤ\n#          (ruby/tk ǽ񤫤Ƥ) ruby Υץץ\n#               http://www.aianet.or.jp/~shugo/ruby/othello.rb.gz\n#           tcltk 饤֥Ȥ褦, ŪѹƤߤޤ.\n#\n#          ʤ٤ꥸʥƱˤʤ褦ˤƤޤ.\n\nrequire \"observer\"\nrequire \"tcltk\"\n$ip = TclTkInterpreter.new()\n$root = $ip.rootwidget()\n$button, $canvas, $checkbutton, $frame, $label, $pack, $update, $wm =\n   $ip.commands().values_at(\n   \"button\", \"canvas\", \"checkbutton\", \"frame\", \"label\", \"pack\", \"update\", \"wm\")\n\nclass Othello\n   \n   EMPTY = 0\n   BLACK = 1\n   WHITE = - BLACK\n   \n   attr :in_com_turn\n   attr :game_over\n   \n   class Board\n   \n      include Observable\n      \n      DIRECTIONS = [\n         [-1, -1], [-1, 0], [-1, 1],\n         [ 0, -1],          [ 0, 1],\n         [ 1, -1], [ 1, 0], [ 1, 1]\n      ]\n      \n      attr_accessor :com_disk\n   \n      def initialize(othello)\n         @othello = othello\n         reset\n      end\n   \n      def notify_observers(*arg)\n         if @observer_peers != nil\n            super(*arg)\n         end\n      end\n      \n      def reset\n         @data = [\n            [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, WHITE, BLACK, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, BLACK, WHITE, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],\n            [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY]\n         ]\n         changed\n         notify_observers\n      end\n      \n      def man_disk\n         return - @com_disk\n      end\n      \n      def other_disk(disk)\n         return - disk\n      end\n      \n      def get_disk(row, col)\n         return @data[row][col]\n      end\n      \n      def reverse_to(row, col, my_disk, dir_y, dir_x)\n         y = row\n         x = col\n         begin\n            y += dir_y\n            x += dir_x\n            if y < 0 || x < 0 || y > 7 || x > 7 ||\n                  @data[y][x] == EMPTY\n               return\n            end\n         end until @data[y][x] == my_disk\n         begin\n            @data[y][x] = my_disk\n            changed\n            notify_observers(y, x)\n            y -= dir_y\n            x -= dir_x\n         end until y == row && x == col\n      end\n      \n      def put_disk(row, col, disk)\n         @data[row][col] = disk\n         changed\n         notify_observers(row, col)\n         DIRECTIONS.each do |dir|\n            reverse_to(row, col, disk, *dir)\n         end\n      end\n      \n      def count_disk(disk)\n         num = 0\n         @data.each do |rows|\n            rows.each do |d|\n               if d == disk\n                  num += 1\n               end\n            end\n         end\n         return num\n      end\n      \n      def count_point_to(row, col, my_disk, dir_y, dir_x)\n         return 0 if @data[row][col] != EMPTY\n         count = 0\n         loop do\n            row += dir_y\n            col += dir_x\n            break if row < 0 || col < 0 || row > 7 || col > 7\n            case @data[row][col]\n            when my_disk\n               return count\n            when other_disk(my_disk)\n               count += 1\n            when EMPTY\n               break\n            end\n         end\n         return 0\n      end\n      \n      def count_point(row, col, my_disk)\n         count = 0\n         DIRECTIONS.each do |dir|\n            count += count_point_to(row, col, my_disk, *dir)\n         end\n         return count\n      end\n      \n      def corner?(row, col)\n         return (row == 0 && col == 0) ||\n            (row == 0 && col == 7) ||\n            (row == 7 && col == 0) ||\n            (row == 7 && col == 7)\n      end\n      \n      def search(my_disk)\n         max = 0\n         max_row = nil\n         max_col = nil\n         for row in 0 .. 7\n            for col in 0 .. 7\n               buf = count_point(row, col, my_disk)\n               if (corner?(row, col) && buf > 0) || max < buf\n                  max = buf\n                  max_row = row\n                  max_col = col\n               end\n            end\n         end\n         return max_row, max_col\n      end\n   end #--------------------------> class Board ends here\n   \n   class BoardView < TclTkWidget\n      \n      BACK_GROUND_COLOR = \"DarkGreen\"\n      HILIT_BG_COLOR = \"green\"\n      BORDER_COLOR = \"black\"\n      BLACK_COLOR = \"black\"\n      WHITE_COLOR = \"white\"\n      STOP_COLOR = \"red\"\n      \n      attr :left\n      attr :top\n      attr :right\n      attr :bottom\n      \n      class Square\n         \n         attr :oval, TRUE\n         attr :row\n         attr :col\n         \n         def initialize(view, row, col)\n            @view = view\n            @id = @view.e(\"create rectangle\", \n                          *(view.tk_rect(view.left + col,\n                                         view.top + row,\n                                         view.left + col + 1,\n                                         view.top + row + 1) \\\n                            << \"-fill #{BACK_GROUND_COLOR}\") )\n            @row = row\n            @col = col\n            @view.e(\"itemconfigure\", @id,\n              \"-width 0.5m -outline #{BORDER_COLOR}\")\n            @view.e(\"bind\", @id, \"<Any-Enter>\", TclTkCallback.new($ip, proc{\n               if @oval == nil\n                  view.e(\"itemconfigure\", @id, \"-fill #{HILIT_BG_COLOR}\")\n               end\n            }))\n            @view.e(\"bind\", @id, \"<Any-Leave>\", TclTkCallback.new($ip, proc{\n               view.e(\"itemconfigure\", @id, \"-fill #{BACK_GROUND_COLOR}\")\n            }))\n            @view.e(\"bind\", @id, \"<ButtonRelease-1>\", TclTkCallback.new($ip,\n               proc{\n               view.click_square(self)\n            }))\n         end\n         \n         def blink(color)\n            @view.e(\"itemconfigure\", @id, \"-fill #{color}\")\n            $update.e()\n            sleep(0.1)\n            @view.e(\"itemconfigure\", @id, \"-fill #{BACK_GROUND_COLOR}\")\n         end\n      end #-----------------------> class Square ends here\n   \n      def initialize(othello, board)\n         super($ip, $root, $canvas)\n         @othello = othello\n         @board = board\n         @board.add_observer(self)\n         \n         @squares = Array.new(8)\n         for i in 0 .. 7\n            @squares[i] = Array.new(8)\n         end\n         @left = 1\n         @top = 0.5\n         @right = @left + 8\n         @bottom = @top + 8\n         \n         i = self.e(\"create rectangle\", *tk_rect(@left, @top, @right, @bottom))\n         self.e(\"itemconfigure\", i,\n            \"-width 1m -outline #{BORDER_COLOR} -fill #{BACK_GROUND_COLOR}\")\n\n         for row in 0 .. 7\n            for col in 0 .. 7\n               @squares[row][col] = Square.new(self, row, col)\n            end\n         end\n         \n         update\n      end\n      \n      def tk_rect(left, top, right, bottom)\n         return left.to_s + \"c\", top.to_s + \"c\",\n            right.to_s + \"c\", bottom.to_s + \"c\"\n      end\n      \n      def clear\n         each_square do |square|\n            if square.oval != nil\n               self.e(\"delete\", square.oval)\n               square.oval = nil\n            end\n         end\n      end\n      \n      def draw_disk(row, col, disk)\n         if disk == EMPTY\n            if @squares[row][col].oval != nil\n               self.e(\"delete\", @squares[row][col].oval)\n               @squares[row][col].oval = nil\n            end\n            return\n         end\n            \n         $update.e()\n         sleep(0.05)\n         oval = @squares[row][col].oval\n         if oval == nil\n            oval = self.e(\"create oval\", *tk_rect(@left + col + 0.2,\n                                           @top + row + 0.2,\n                                           @left + col + 0.8,\n                                           @top + row + 0.8))\n            @squares[row][col].oval = oval\n         end\n         case disk\n         when BLACK\n            color = BLACK_COLOR\n         when WHITE\n            color = WHITE_COLOR\n         else\n            fail format(\"Unknown disk type: %d\", disk)\n         end\n         self.e(\"itemconfigure\", oval, \"-outline #{color} -fill #{color}\")\n      end\n      \n      def update(row = nil, col = nil)\n         if row && col\n            draw_disk(row, col, @board.get_disk(row, col))\n         else\n            each_square do |square|\n               draw_disk(square.row, square.col,\n                         @board.get_disk(square.row, square.col))\n            end\n         end\n         @othello.show_point\n      end\n      \n      def each_square\n         @squares.each do |rows|\n            rows.each do |square|\n               yield(square)\n            end\n         end\n      end\n      \n      def click_square(square)\n         if @othello.in_com_turn || @othello.game_over ||\n               @board.count_point(square.row,\n                                  square.col,\n                                  @board.man_disk) == 0\n            square.blink(STOP_COLOR)\n            return\n         end\n         @board.put_disk(square.row, square.col, @board.man_disk)\n         @othello.com_turn\n      end\n      \n      private :draw_disk\n      public :update\n   end #----------------------> class BoardView ends here\n   \n   def initialize\n      @msg_label = TclTkWidget.new($ip, $root, $label)\n      $pack.e(@msg_label)\n      \n      @board = Board.new(self)\n      @board_view = BoardView.new(self, @board)\n      #### added by Y. Shigehiro\n      ## board_view 礭ꤹ.\n      x1, y1, x2, y2 = @board_view.e(\"bbox all\").split(/ /).collect{|i| i.to_f}\n      @board_view.e(\"configure -width\", x2 - x1)\n      @board_view.e(\"configure -height\", y2 - y1)\n      ## scrollregion ꤹ.\n      @board_view.e(\"configure -scrollregion {\", @board_view.e(\"bbox all\"),\n         \"}\")\n      #### ޤ\n      $pack.e(@board_view, \"-fill both -expand true\")\n      \n      panel = TclTkWidget.new($ip, $root, $frame)\n      \n      @play_black = TclTkWidget.new($ip, panel, $checkbutton,\n        \"-text {com is black} -command\", TclTkCallback.new($ip, proc{\n         switch_side\n      }))\n      $pack.e(@play_black, \"-side left\")\n            \n      quit = TclTkWidget.new($ip, panel, $button, \"-text Quit -command\",\n         TclTkCallback.new($ip, proc{\n         exit\n      }))\n      $pack.e(quit, \"-side right -fill x\")\n      \n      reset = TclTkWidget.new($ip, panel, $button, \"-text Reset -command\",\n         TclTkCallback.new($ip, proc{\n         reset_game\n      }))\n      $pack.e(reset, \"-side right -fill x\")\n      \n      $pack.e(panel, \"-side bottom -fill x\")\n      \n#      root = Tk.root\n      $wm.e(\"title\", $root, \"Othello\")\n      $wm.e(\"iconname\", $root, \"Othello\")\n      \n      @board.com_disk = WHITE\n      @game_over = FALSE\n      \n      TclTk.mainloop\n   end\n   \n   def switch_side\n      if @in_com_turn\n         @play_black.e(\"toggle\")\n      else\n         @board.com_disk = @board.man_disk\n         com_turn unless @game_over\n      end\n   end\n   \n   def reset_game\n      if @board.com_disk == BLACK\n         @board.com_disk = WHITE\n         @play_black.e(\"toggle\")\n      end\n      @board_view.clear\n      @board.reset\n      $wm.e(\"title\", $root, \"Othello\")\n      @game_over = FALSE\n   end\n      \n   def com_turn\n      @in_com_turn = TRUE\n      $update.e()\n      sleep(0.5)\n      begin\n         com_disk = @board.count_disk(@board.com_disk)\n         man_disk = @board.count_disk(@board.man_disk)\n         if @board.count_disk(EMPTY) == 0\n            if man_disk == com_disk\n               $wm.e(\"title\", $root, \"{Othello - Draw!}\")\n            elsif man_disk > com_disk\n               $wm.e(\"title\", $root, \"{Othello - You Win!}\")\n            else\n               $wm.e(\"title\", $root, \"{Othello - You Loose!}\")\n            end\n            @game_over = TRUE\n            break\n         elsif com_disk == 0\n            $wm.e(\"title\", $root, \"{Othello - You Win!}\")\n            @game_over = TRUE\n            break\n         elsif man_disk == 0\n            $wm.e(\"title\", $root, \"{Othello - You Loose!}\")\n            @game_over = TRUE\n            break\n         end\n         row, col = @board.search(@board.com_disk)\n         break if row == nil || col == nil\n         @board.put_disk(row, col, @board.com_disk)\n      end while @board.search(@board.man_disk) == [nil, nil]\n      @in_com_turn = FALSE\n   end\n\n   def show_point\n      black = @board.count_disk(BLACK)\n      white = @board.count_disk(WHITE)\n      @msg_label.e(\"configure -text\",\n         %Q/{#{format(\"BLACK: %.2d    WHITE: %.2d\", black, white)}}/)\n   end\nend #----------------------> class Othello ends here\n\nOthello.new\n\n#----------------------------------------------> othello.rb ends here\n"
  },
  {
    "path": "ext/tk/sample/tkalignbox.rb",
    "content": "#\n#  tkalignbox.rb : align widgets with same width/height\n# \n#                                            by Hidetoshi NAGAI\n#\n#  The box size depends on 'reqheight' and 'reqwidth' of contained widgets. \n#  If you want to give the box size when those requested sizes are 0, \n#  please set box.propagate = false (See the test routine at the tail of \n#  this file).\n\nrequire 'tk'\n\nclass TkAlignBox < TkFrame\n  def initialize(*args)\n    if self.class == TkAlignBox\n      fail RuntimeError, \"TkAlignBox is an abstract class\"\n    end\n    @padx = 0\n    @pady = 0\n    if args[-1].kind_of? Hash\n      keys = _symbolkey2str(args.pop)\n      @padx = keys.delete('padx') || 0\n      @pady = keys.delete('pady') || 0\n      args.push(keys)\n    end\n    super(*args)\n    @max_width = 0\n    @max_height = 0\n    @propagate = true\n    @widgets = []\n  end\n\n  def _set_framesize\n    fail RuntimeError, \"TkAlignBox is an abstract class\"\n  end\n  private :_set_framesize\n\n  def _place_config(widget, idx, cnt)\n    fail RuntimeError, \"TkAlignBox is an abstract class\"\n  end\n  private :_place_config\n\n  def align\n    widgets = []\n    @widgets.each{|w| widgets << w if w.winfo_exist?}\n    @widgets = widgets\n    cnt = @widgets.size.to_f\n    @widgets.each_with_index{|w, idx| _place_config(w, idx, cnt)}\n    @widgets = widgets\n    _set_framesize if @propagate\n    self\n  end\n\n  def add(*widgets)\n    widgets.each{|w|\n      unless w.kind_of? TkWindow\n        fail RuntimeError, \"#{w.inspect} is not a widget instance.\"\n      end\n      @widgets.delete(w)\n      @widgets << w\n      sz = w.winfo_reqwidth\n      @max_width = sz if @max_width < sz\n      sz = w.winfo_reqheight\n      @max_height = sz if @max_height < sz\n    }\n    align\n  end\n\n  def <<(widget)\n    add(widget)\n  end\n\n  def insert(idx, widget)\n    unless widget.kind_of? TkWindow\n      fail RuntimeError, \"#{widget.inspect} is not a widget instance.\"\n    end\n    @widgets.delete(widget)\n    @widgets[idx,0] = widget\n    sz = widget.winfo_reqwidth\n    @max_width = sz if @max_width < sz\n    sz = widget.winfo_reqheight\n    @max_height = sz if @max_height < sz\n    align\n  end\n\n  def delete(idx)\n    ret = @widgets.delete_at(idx)\n    @req_size = 0\n    @widget.each{|w|\n      sz = w.winfo_reqwidth\n      @max_width = sz if @max_width < sz\n      sz = w.winfo_reqheight\n      @max_height = sz if @max_height < sz\n    }\n    align\n    ret\n  end\n\n  def padx(size = nil)\n    if size\n      @padx = size\n      align\n    else\n      @padx\n    end\n  end\n\n  def pady(size = nil)\n    if size\n      @pady = size\n      align\n    else\n      @pady\n    end\n  end\n\n  attr_accessor :propagate\nend\n\nclass TkHBox < TkAlignBox\n  def _set_framesize\n    bd = self.borderwidth\n    self.width((@max_width + 2*@padx) * @widgets.size + 2*bd)\n    self.height(@max_height + 2*@pady + 2*bd)\n  end\n  private :_set_framesize\n\n  def _place_config(widget, idx, cnt)\n    widget.place_in(self, \n                    'relx'=>idx/cnt, 'x'=>@padx, \n                    'rely'=>0, 'y'=>@pady, \n                    'relwidth'=>1.0/cnt, 'width'=>-2*@padx, \n                    'relheight'=>1.0, 'height'=>-2*@pady)\n  end\n  private :_place_config\nend\nTkHLBox = TkHBox\n\nclass TkHRBox < TkHBox\n  def _place_config(widget, idx, cnt)\n    widget.place_in(self, \n                    'relx'=>(cnt - idx - 1)/cnt, 'x'=>@padx, \n                    'rely'=>0, 'y'=>@pady, \n                    'relwidth'=>1.0/cnt, 'width'=>-2*@padx, \n                    'relheight'=>1.0, 'height'=>-2*@pady)\n  end\n  private :_place_config\nend\n\nclass TkVBox < TkAlignBox\n  def _set_framesize\n    bd = self.borderwidth\n    self.width(@max_width + 2*@padx + 2*bd)\n    self.height((@max_height + 2*@pady) * @widgets.size + 2*bd)\n  end\n  private :_set_framesize\n\n  def _place_config(widget, idx, cnt)\n    widget.place_in(self, \n                    'relx'=>0, 'x'=>@padx, \n                    'rely'=>idx/cnt, 'y'=>@pady, \n                    'relwidth'=>1.0, 'width'=>-2*@padx, \n                    'relheight'=>1.0/cnt, 'height'=>-2*@pady)\n  end\n  private :_place_config\nend\nTkVTBox = TkVBox\n\nclass TkVBBox < TkVBox\n  def _place_config(widget, idx, cnt)\n    widget.place_in(self, \n                    'relx'=>0, 'x'=>@padx, \n                    'rely'=>(cnt - idx - 1)/cnt, 'y'=>@pady, \n                    'relwidth'=>1.0, 'width'=>-2*@padx, \n                    'relheight'=>1.0/cnt, 'height'=>-2*@pady)\n  end\n  private :_place_config\nend\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  f = TkHBox.new(:borderwidth=>3, :relief=>'ridge').pack\n  f.add(TkButton.new(f, :text=>'a'),\n        TkButton.new(f, :text=>'aa', :font=>'Helvetica 16'),\n        TkButton.new(f, :text=>'aaa'),\n        TkButton.new(f, :text=>'aaaa'))\n\n  f = TkHBox.new(:borderwidth=>3, :relief=>'ridge', \n                 :padx=>7, :pady=>3, :background=>'yellow').pack\n  f.add(TkButton.new(f, :text=>'a'),\n        TkButton.new(f, :text=>'aa', :font=>'Helvetica 16'),\n        TkButton.new(f, :text=>'aaa'),\n        TkButton.new(f, :text=>'aaaa'))\n\n  f = TkVBox.new(:borderwidth=>5, :relief=>'groove').pack\n  f.add(TkButton.new(f, :text=>'a'),\n        TkButton.new(f, :text=>'aa', :font=>'Helvetica 30'),\n        TkButton.new(f, :text=>'aaa'),\n        TkButton.new(f, :text=>'aaaa'))\n\n  f = TkHRBox.new(:borderwidth=>3, :relief=>'raised').pack(:fill=>:x)\n  f.add(TkButton.new(f, :text=>'a'),\n        TkButton.new(f, :text=>'aa'), \n        TkButton.new(f, :text=>'aaa'))\n\n  f = TkVBBox.new(:borderwidth=>3, :relief=>'ridge').pack(:fill=>:x)\n  f.propagate = false\n  f.height 100\n  f.add(TkFrame.new(f){|ff| \n          TkButton.new(ff, :text=>'a').pack(:pady=>4, :padx=>6, \n                                            :fill=>:both, :expand=>true)\n        }, \n        TkFrame.new(f){|ff| \n          TkButton.new(ff, :text=>'aa').pack(:pady=>4, :padx=>6, \n                                             :fill=>:both, :expand=>true)\n        }, \n        TkFrame.new(f){|ff| \n          TkButton.new(ff, :text=>'aaaa').pack(:pady=>4, :padx=>6, \n                                               :fill=>:both, :expand=>true)\n        })\n\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tkballoonhelp.rb",
    "content": "#\n# tkballoonhelp.rb : simple balloon help widget\n#                       by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n# Add a balloon help to a widget. \n# This widget has only poor featureas. If you need more useful features, \n# please try to use the Tix extension of Tcl/Tk under Ruby/Tk.\n# \n# The interval time to display a balloon help is defined 'interval' option\n# (default is 1000ms). \n#\nrequire 'tk'\n\nclass TkBalloonHelp<TkLabel\n  def _balloon_binding(interval)\n    @timer = TkAfter.new(interval, 1, proc{show})\n    def @timer.interval(val)\n      @sleep_time = val\n    end\n    @bindtag = TkBindTag.new\n    @bindtag.bind('Enter',  proc{@timer.start})\n    @bindtag.bind('Motion', proc{@timer.restart; erase})\n    @bindtag.bind('Any-ButtonPress', proc{@timer.restart; erase})\n    @bindtag.bind('Leave',  proc{@timer.stop; erase})\n    tags = @parent.bindtags\n    idx = tags.index(@parent)\n    unless idx\n      ppath = TkComm.window(@parent.path)\n      idx = tags.index(ppath) || 0\n    end\n    tags[idx,0] = @bindtag\n    @parent.bindtags(tags)\n  end\n  private :_balloon_binding\n\n  def initialize(parent=nil, keys={})\n    @parent = parent || Tk.root\n\n    @frame = TkToplevel.new(@parent)\n    @frame.withdraw\n    @frame.overrideredirect(true)\n    @frame.transient(TkWinfo.toplevel(@parent))\n    @epath = @frame.path\n\n    if keys\n      keys = _symbolkey2str(keys)\n    else\n      keys = {}\n    end\n\n    @command = keys.delete('command')\n\n    @interval = keys.delete('interval'){1000}\n    _balloon_binding(@interval)\n\n    @label = TkLabel.new(@frame, 'background'=>'bisque').pack\n    @label.configure(_symbolkey2str(keys)) unless keys.empty?\n    @path = @label\n  end\n\n  def epath\n    @epath\n  end\n\n  def interval(val)\n    if val\n      @timer.interval(val)\n    else\n      @interval\n    end\n  end\n\n  def command(cmd = Proc.new)\n    @command = cmd\n    self\n  end\n\n  def show\n    x = TkWinfo.pointerx(@parent)\n    y = TkWinfo.pointery(@parent)\n    @frame.geometry(\"+#{x+1}+#{y+1}\")\n\n    if @command\n      case @command.arity\n      when 0\n        @command.call\n      when 2\n        @command.call(x - TkWinfo.rootx(@parent), y - TkWinfo.rooty(@parent))\n      when 3\n        @command.call(x - TkWinfo.rootx(@parent), y - TkWinfo.rooty(@parent), \n                      self)\n      else\n        @command.call(x - TkWinfo.rootx(@parent), y - TkWinfo.rooty(@parent), \n                      self, @parent)\n      end\n    end\n\n    @frame.deiconify\n    @frame.raise\n\n    @org_cursor = @parent['cursor']\n    @parent.cursor('crosshair') \n  end\n\n  def erase\n    @parent.cursor(@org_cursor) \n    @frame.withdraw\n  end\n\n  def destroy\n    @frame.destroy\n  end\nend\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  TkButton.new('text'=>'This button has a balloon help') {|b|\n    pack('fill'=>'x')\n    TkBalloonHelp.new(b, 'text'=>' Message ')\n  }\n  TkButton.new('text'=>'This button has another balloon help') {|b|\n    pack('fill'=>'x')\n    TkBalloonHelp.new(b, 'text'=>'configured message', \n                      'interval'=>200, 'font'=>'courier', \n                      'background'=>'gray', 'foreground'=>'red')\n  }\n\n  sb = TkScrollbox.new.pack(:fill=>:x)\n  sb.insert(:end, *%w(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm))\n=begin\n  # CASE1 : command takes no arguemnt\n  bh = TkBalloonHelp.new(sb, :interval=>500, \n                         :relief=>:ridge, :background=>'white', \n                         :command=>proc{\n                           y = TkWinfo.pointery(sb) - TkWinfo.rooty(sb)\n                           bh.text \"current index == #{sb.nearest(y)}\"\n                         })\n=end\n=begin\n  # CASE2 : command takes 2 arguemnts\n  bh = TkBalloonHelp.new(sb, :interval=>500, \n                         :relief=>:ridge, :background=>'white', \n                         :command=>proc{|x, y|\n                           bh.text \"current index == #{sb.nearest(y)}\"\n                         })\n=end\n=begin\n  # CASE3 : command takes 3 arguemnts\n  TkBalloonHelp.new(sb, :interval=>500, \n                    :relief=>:ridge, :background=>'white', \n                    :command=>proc{|x, y, bhelp|\n                      bhelp.text \"current index == #{sb.nearest(y)}\"\n                    })\n=end\n=begin\n  # CASE4a : command is a Proc object and takes 4 arguemnts\n  cmd = proc{|x, y, bhelp, parent|\n    bhelp.text \"current index == #{parent.nearest(y)}\"\n  }\n\n  TkBalloonHelp.new(sb, :interval=>500, \n                    :relief=>:ridge, :background=>'white', \n                    :command=>cmd)\n\n  sb2 = TkScrollbox.new.pack(:fill=>:x)\n  sb2.insert(:end, *%w(AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK LLL MMM))\n  TkBalloonHelp.new(sb2, :interval=>500, \n                    :padx=>5, :relief=>:raised, \n                    :background=>'gray25', :foreground=>'white',\n                    :command=>cmd)\n=end\n#=begin\n  # CASE4b : command is a Method object and takes 4 arguemnts\n  def set_msg(x, y, bhelp, parent)\n    bhelp.text \"current index == #{parent.nearest(y)}\"\n  end\n  cmd = self.method(:set_msg)\n\n  TkBalloonHelp.new(sb, :interval=>500, \n                    :relief=>:ridge, :background=>'white', \n                    :command=>cmd)\n\n  sb2 = TkScrollbox.new.pack(:fill=>:x)\n  sb2.insert(:end, *%w(AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK LLL MMM))\n  TkBalloonHelp.new(sb2, :interval=>500, \n                    :padx=>5, :relief=>:raised, \n                    :background=>'gray25', :foreground=>'white',\n                    :command=>cmd)\n#=end\n\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tkbiff.rb",
    "content": "#!/usr/bin/env ruby\n\nif ARGV[0] != '-d'\n  unless $DEBUG\n    exit if fork\n  end\nelse\n  ARGV.shift\nend\n\nif ARGV.length == 0\n  if ENV['MAIL']\n    $spool = ENV['MAIL']\n  else  \n    $spool = '/var/spool/mail/' + ENV['USER']\n  end\nelse \n  $spool = ARGV[0]\nend\n\nrequire \"parsedate\"\nrequire \"base64\"\n\ninclude ParseDate\n\nclass Mail\n  def Mail.new(f)\n    if !f.kind_of?(IO)\n      f = open(f, \"r\")\n      me = super\n      f.close\n    else\n      me = super\n    end\n    return me\n  end\n\n  def initialize(f)\n    @header = {}\n    @body = []\n    while line = f.gets()\n      line.chop!\n      next if /^From / =~ line  # skip From-line  \n      break if /^$/ =~ line     # end of header\n      if /^(\\S+):\\s*(.*)/ =~ line\n        @header[attr = $1.capitalize] = $2\n      elsif attr\n        sub(/^\\s*/, '')\n        @header[attr] += \"\\n\" + $_\n      end\n    end\n\n    return unless $_\n\n    while line = f.gets()\n      break if /^From / =~ line\n      @body.push($_)\n    end\n  end\n\n  def header\n    return @header\n  end\n\n  def body\n    return @body\n  end\n\nend\n\nrequire \"tkscrollbox\"\n\nmy_appname = Tk.appname('tkbiff')\n$top = TkRoot.new\nif ((TkWinfo.interps($top) - [my_appname]).find{|ip| ip =~ /^tkbiff/})\n  STDERR.print(\"Probably other 'tkbiff's are running. Bye.\\n\")\n  exit\nend\n\n$top.withdraw\n$list = TkScrollbox.new($top) {\n  relief 'raised'\n  width 80\n  height 8\n  setgrid 'yes'\n  pack\n}\nTkButton.new($top) {\n  text 'Dismiss'\n  command proc {$top.withdraw}\n  pack('fill'=>'both','expand'=>'yes')\n}\n$top.bind \"Control-c\", proc{exit}\n$top.bind \"Control-q\", proc{exit}\n$top.bind \"space\", proc{exit}\n\n$spool_size = 0\n$check_time = Time.now\n\ndef check\n  $check_time = Time.now\n  size = File.size($spool)\n  if size and size != $spool_size\n    $spool_size = size\n    pop_up if size > 0\n  end\n  Tk.after 5000, proc{check}\nend\n\nif defined? Thread\n  Thread.start do\n    loop do\n      sleep 600\n      if Time.now - $check_time > 200\n        Tk.after 5000, proc{check}\n      end\n    end\n  end\nend\n\ndef pop_up\n  outcount = 0;\n  $list.delete 0, 'end'\n  f = open($spool, \"r\")\n  while !f.eof?\n    mail = Mail.new(f)\n    date, from, subj =  mail.header['Date'], mail.header['From'], mail.header['Subject']\n    next if !date\n    y = m = d = 0\n    y, m, d = parsedate(date) if date\n    from = \"sombody@somewhere\" if ! from\n    subj = \"(nil)\" if ! subj\n    from = decode_b(from)\n    subj = decode_b(subj)\n    $list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj)\n    outcount += 1\n  end\n  f.close\n  if outcount == 0\n    $list.insert 'end', \"You have no mail.\"\n  else\n    $list.see 'end'\n  end\n  $top.deiconify\n  Tk.after 2000, proc{$top.iconify}\nend\n\n$list.insert 'end', \"You have no mail.\"\ncheck\nTk.after 2000, proc{$top.iconify}\nbegin\n  Tk.mainloop\nrescue\n  `echo #$! > /tmp/tkbiff`\nend\n"
  },
  {
    "path": "ext/tk/sample/tkbrowse.rb",
    "content": "#!/usr/bin/env ruby\n#\n# This script generates a directory browser, which lists the working\n# directory and allows you to open files or subdirectories by\n# double-clicking.\n\n# Create a scrollbar on the right side of the main window and a listbox\n# on the left side.\n\nrequire \"tkscrollbox\"\n\n# The procedure below is invoked to open a browser on a given file;  if the\n# file is a directory then another instance of this program is invoked; if\n# the file is a regular file then the Mx editor is invoked to display\n# the file.\n\n$dirlist = {}\n\ndef browsedir (dir)\n  if $dirlist.key? dir\n    $dirlist[dir]\n  else\n    top = if $dirlist.size > 0 then TkToplevel.new else nil end\n    list = TkScrollbox.new(top) {\n      relief 'raised'\n      width 20\n      height 20\n      setgrid 'yes'\n      pack\n    }\n    list.insert 'end', *`ls #{dir}`.split\n\n    # Set up bindings for the browser.\n\n    list.focus\n    list.bind \"Control-q\", proc{exit}\n    list.bind \"Control-c\", proc{exit}\n    list.bind \"Control-p\", proc{\n      print \"selection <\", TkSelection.get, \">\\n\"\n    }\n\n    list.bind \"Double-Button-1\", proc{\n      for i in TkSelection.get.split\n        print \"clicked \", i, \"\\n\"\n        browse dir, i\n      end\n    }\n    $dirlist[dir] = list\n  end\nend\n\ndef browse (dir, file)\n  file=\"#{dir}/#{file}\"\n  if File.directory? file\n    browsedir(file)\n  else\n    if File.file? file\n      if ENV['EDITOR']\n        system format(\"%s %s&\", ENV['EDITOR'], file)\n      else\n        system \"xedit #{file}&\"\n      end\n    else\n      STDERR.print \"\\\"#{file}\\\" isn't a directory or regular file\"\n    end\n  end\nend\n\n# Fill the listbox with a list of all the files in the directory (run\n# the \"ls\" command to get that information).\n\nif ARGV.length>0 \n  dir = ARGV[0]\nelse\n  dir=\".\"\nend\n\nbrowsedir(dir)\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkcombobox.rb",
    "content": "#\n#  tkcombobox.rb : TkAutoScrollbox & TkCombobox\n# \n#                         by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass TkAutoScrollbox < TkListbox\n  include TkComposite\n\n  @@up_bmp = TkBitmapImage.new(:data=><<EOD)\n#define up_arrow_width 9\n#define up_arrow_height 9\nstatic unsigned char up_arrow_bits[] = {\n   0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7c, 0x00,\n   0x7c, 0x00, 0xfe, 0x00, 0x00, 0x00};\nEOD\n\n  @@down_bmp = TkBitmapImage.new(:data=><<EOD)\n#define up_arrow_width 9\n#define up_arrow_height 9\nstatic unsigned char down_arrow_bits[] = {\n   0x00, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x38, 0x00,\n   0x10, 0x00, 0x10, 0x00, 0x00, 0x00};\nEOD\n\n  ############################\n  private\n  ############################\n  def initialize_composite(keys={})\n    keys = _symbolkey2str(keys)\n\n    @initwait = keys.delete('startwait'){300}\n    @interval = keys.delete('interval'){150}\n    @initwait -= @interval\n    @initwait = 0 if @initwait < 0\n\n    @lbox = TkListbox.new(@frame, :borderwidth=>0)\n    @path = @lbox.path\n    TkPack.propagate(@lbox, false)\n\n    @scr = TkScrollbar.new(@frame, :width=>10)\n\n    @lbox.yscrollcommand(proc{|*args| @scr.set(*args); _config_proc})\n    @scr.command(proc{|*args| @lbox.yview(*args); _config_proc})\n\n    @up_arrow   = TkLabel.new(@lbox, :image=>@@up_bmp, \n                              :relief=>:raised, :borderwidth=>1)\n    @down_arrow = TkLabel.new(@lbox, :image=>@@down_bmp, \n                              :relief=>:raised, :borderwidth=>1)\n\n    _init_binding\n\n    @lbox.pack(:side=>:left, :fill=>:both, :expand=>:true)\n\n    delegate('DEFAULT', @lbox)\n    delegate('background', @frame, @scr)\n    delegate('activebackground', @scr)\n    delegate('troughcolor', @scr)\n    delegate('repeatdelay', @scr)\n    delegate('repeatinterval', @scr)\n    delegate('relief', @frame)\n    delegate('borderwidth', @frame)\n\n    delegate_alias('arrowrelief', 'relief', @up_arrow, @down_arrow)\n    delegate_alias('arrowborderwidth', 'borderwidth', @up_arrow, @down_arrow)\n\n    scrollbar(keys.delete('scrollbar')){false}\n\n    configure keys unless keys.empty?\n  end\n\n  def _show_up_arrow\n    unless @up_arrow.winfo_mapped?\n      @up_arrow.pack(:side=>:top, :fill=>:x)\n    end\n  end\n\n  def _show_down_arrow\n    unless @down_arrow.winfo_mapped?\n      @down_arrow.pack(:side=>:bottom, :fill=>:x) \n    end\n  end\n\n  def _set_sel(idx)\n      @lbox.activate(idx)\n      @lbox.selection_clear(0, 'end')\n      @lbox.selection_set(idx)\n  end\n\n  def _check_sel(cidx, tidx = nil, bidx = nil)\n    _set_sel(cidx)\n    unless tidx\n      tidx = @lbox.nearest(0) \n      tidx += 1 if tidx > 0\n    end\n    unless bidx\n      bidx = @lbox.nearest(10000) \n      bidx -= 1 if bidx < @lbox.index('end') - 1\n    end\n    if cidx > bidx\n      _set_sel(bidx)\n    end\n    if cidx < tidx\n      _set_sel(tidx)\n    end\n  end\n\n  def _up_proc\n    cidx = @lbox.curselection[0]\n    idx = @lbox.nearest(0)\n    if idx >= 0\n      @lbox.see(idx - 1)\n      _set_sel(idx)\n      @up_arrow.pack_forget if idx == 1\n      @up_timer.stop if idx == 0\n      _show_down_arrow if @lbox.bbox('end') == []\n    end\n    if cidx && cidx > 0 && (idx == 0 || cidx == @lbox.nearest(10000))\n      _set_sel(cidx - 1)\n    end\n  end\n\n  def _down_proc\n    cidx = @lbox.curselection[0]\n    eidx = @lbox.index('end') - 1\n    idx = @lbox.nearest(10000)\n    if idx <= eidx\n      @lbox.see(idx + 1)\n      _set_sel(cidx + 1) if cidx < eidx\n      @down_arrow.pack_forget if idx + 1 == eidx\n      @down_timer.stop if idx == eidx\n      _show_up_arrow if @lbox.bbox(0) == []\n    end\n    if cidx && cidx < eidx && (eidx == idx || cidx == @lbox.nearest(0))\n      _set_sel(cidx + 1)\n    end\n  end\n\n  def _key_UP_proc\n    cidx = @lbox.curselection[0]\n    _set_sel(cidx = @lbox.index('activate')) unless cidx\n    cidx -= 1\n    if cidx == 0\n      @up_arrow.pack_forget\n    elsif cidx == @lbox.nearest(0)\n      @lbox.see(cidx - 1)\n    end\n  end\n\n  def _key_DOWN_proc\n    cidx = @lbox.curselection[0]\n    _set_sel(cidx = @lbox.index('activate')) unless cidx\n    cidx += 1\n    if cidx == @lbox.index('end') - 1\n      @down_arrow.pack_forget\n    elsif cidx == @lbox.nearest(10000)\n      @lbox.see(cidx + 1)\n    end\n  end\n\n  def _config_proc\n    if @lbox.size == 0\n      @up_arrow.pack_forget\n      @down_arrow.pack_forget\n      return\n    end\n    tidx = @lbox.nearest(0)\n    bidx = @lbox.nearest(10000)\n    if tidx > 0\n      _show_up_arrow\n      tidx += 1\n    else\n      @up_arrow.pack_forget unless @up_timer.running?\n    end\n    if bidx < @lbox.index('end') - 1\n      _show_down_arrow\n      bidx -= 1\n    else\n      @down_arrow.pack_forget unless @down_timer.running?\n    end\n    cidx = @lbox.curselection[0]\n    _check_sel(cidx, tidx, bidx) if cidx\n  end\n\n  def _init_binding\n    @up_timer = TkAfter.new(@interval, -1, proc{_up_proc})\n    @down_timer = TkAfter.new(@interval, -1, proc{_down_proc})\n\n    @up_timer.set_start_proc(@initwait, proc{})\n    @down_timer.set_start_proc(@initwait, proc{})\n\n    @up_arrow.bind('Enter', proc{@up_timer.start})\n    @up_arrow.bind('Leave', proc{@up_timer.stop if @up_arrow.winfo_mapped?})\n    @down_arrow.bind('Enter', proc{@down_timer.start})\n    @down_arrow.bind('Leave', proc{@down_timer.stop if @down_arrow.winfo_mapped?})\n\n    @lbox.bind('Configure', proc{_config_proc})\n    @lbox.bind('Enter', proc{|y| _set_sel(@lbox.nearest(y))}, '%y')\n    @lbox.bind('Motion', proc{|y| \n                 @up_timer.stop if @up_timer.running?\n                 @down_timer.stop if @down_timer.running?\n                 _check_sel(@lbox.nearest(y))\n               }, '%y')\n\n    @lbox.bind('Up', proc{_key_UP_proc})\n    @lbox.bind('Down', proc{_key_DOWN_proc})\n  end\n\n  ############################\n  public\n  ############################\n  def scrollbar(mode)\n    if mode\n      @scr.pack(:side=>:right, :fill=>:y)\n    else\n      @scr.pack_forget\n    end\n  end\nend\n\n################################################\n\nclass TkCombobox < TkEntry\n  include TkComposite\n\n  @@down_btn_bmp = TkBitmapImage.new(:data=><<EOD)\n#define down_arrow_width 11\n#define down_arrow_height 11\nstatic unsigned char down_arrow_bits[] = {\n   0x00, 0x00, 0xfe, 0x03, 0xfc, 0x01, 0xfc, 0x01, 0xf8, 0x00, 0xf8, 0x00,\n   0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00};\nEOD\n\n  @@up_btn_bmp = TkBitmapImage.new(:data=><<EOD)\n#define up_arrow_width 11\n#define up_arrow_height 11\nstatic unsigned char up_arrow_bits[] = {\n   0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, 0x70, 0x00, 0xf8, 0x00,\n   0xf8, 0x00, 0xfc, 0x01, 0xfc, 0x01, 0xfe, 0x03, 0x00, 0x00};\nEOD\n\n  def _button_proc(dir = true)\n    @btn.relief(:sunken)\n    x = @frame.winfo_rootx\n    y = @frame.winfo_rooty\n    if dir\n      @top.geometry(\"+#{x}+#{y + @frame.winfo_height}\")\n    else\n      @btn.image(@@up_btn_bmp)\n      @top.geometry(\"+#{x}+#{y - @top.winfo_reqheight}\")\n    end\n    @top.deiconify\n    @lst.focus\n\n    if (idx = values.index(@ent.value))\n      @lst.see(idx - 1)\n      @lst.activate(idx)\n      @lst.selection_set(idx)\n    elsif @lst.size > 0\n      @lst.see(0)\n      @lst.activate(0)\n      @lst.selection_set(0)\n    end\n    @top.grab\n\n    begin\n      @var.tkwait\n      if (idx = @var.to_i) >= 0\n        @ent.value = @lst.get(idx)\n      end\n      @top.withdraw\n      @btn.relief(:raised)\n      @btn.image(@@down_btn_bmp)\n    rescue\n    ensure\n      begin\n        @top.grab(:release)\n        @ent.focus\n      rescue\n      end\n    end\n  end\n  private :_button_proc\n\n  def _init_bindings\n    @btn.bind('1', proc{_button_proc(true)})\n    @btn.bind('3', proc{_button_proc(false)})\n\n    @lst.bind('1', proc{|y| @var.value = @lst.nearest(y)}, '%y')\n    @lst.bind('Return', proc{@var.value = @lst.curselection[0]})\n\n    cancel = TkVirtualEvent.new('2', '3', 'Escape')\n    @lst.bind(cancel, proc{@var.value = -1})\n  end\n  private :_init_bindings\n\n  def initialize_composite(keys={})\n    keys = _symbolkey2str(keys)\n\n    @btn = TkLabel.new(@frame, :relief=>:raised, :borderwidth=>3, \n                       :image=>@@down_btn_bmp).pack(:side=>:right, \n                                                    :ipadx=>2, :fill=>:y)\n    @ent = TkEntry.new(@frame).pack(:side=>:left)\n    @path = @ent.path\n\n    @top = TkToplevel.new(@btn, :borderwidth=>1, :relief=>:raised) {\n      withdraw\n      transient\n      overrideredirect(true)\n    }\n\n    startwait = keys.delete('startwait'){300}\n    interval = keys.delete('interval'){150}\n    @lst = TkAutoScrollbox.new(@top, \n                               :startwait=>startwait, \n                               :interval=>interval).pack(:fill=>:both, \n                                                         :expand=>true)\n    @ent_list = []\n\n    @var = TkVariable.new\n\n    _init_bindings\n\n    delegate('DEFAULT', @ent)\n    delegate('height', @lst)\n    delegate('relief', @frame)\n    delegate('borderwidth', @frame)\n\n    delegate('arrowrelief', @lst)\n    delegate('arrowborderwidth', @lst)\n\n    if mode = keys.delete('scrollbar')\n      scrollbar(mode)\n    end\n\n    configure keys unless keys.empty?\n  end\n  private :initialize_composite\n\n  def scrollbar(mode)\n    @lst.scrollbar(mode)\n  end\n\n  def _reset_width\n    len = @ent.width\n    @lst.get(0, 'end').each{|l| len = l.length if l.length > len}\n    @lst.width(len + 1)\n  end\n  private :_reset_width\n\n  def add(ent)\n    ent = ent.to_s\n    unless @ent_list.index(ent)\n      @ent_list << ent\n      @lst.insert('end', ent)\n    end\n    _reset_width\n    self\n  end\n\n  def remove(ent)\n    ent = ent.to_s\n    @ent_list.delete(ent)\n    if idx = @lst.get(0, 'end').index(ent)\n      @lst.delete(idx)\n    end\n    _reset_width\n    self\n  end\n\n  def values(ary = nil)\n    if ary\n      @lst.delete(0, 'end')\n      @ent_list.clear\n      ary.each{|ent| add(ent)}\n      _reset_width\n      self\n    else\n      @lst.get(0, 'end')\n    end\n  end\n\n  def see(idx)\n    @lst.see(@lst.index(idx) - 1)\n  end\n\n  def list_index(idx)\n    @lst.index(idx)\n  end\nend\n\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  v = TkVariable.new\n  e = TkCombobox.new(:height=>7, :scrollbar=>true, :textvariable=>v, \n                     :arrowrelief=>:flat, :arrowborderwidth=>0, \n                     :startwait=>400, :interval=>200).pack\n  e.values(%w(aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu))\n  #e.see(e.list_index('end') - 2)\n  e.value = 'cc'\n  TkFrame.new{|f|\n    fnt = TkFont.new('Helvetica 10')\n    TkLabel.new(f, :font=>fnt, :text=>'TkCombobox value :').pack(:side=>:left)\n    TkLabel.new(f, :font=>fnt, :textvariable=>v).pack(:side=>:left)\n  }.pack\n\n  TkFrame.new(:relief=>:raised, :borderwidth=>2, \n              :height=>3).pack(:fill=>:x, :expand=>true, :padx=>5, :pady=>3)\n\n  l = TkAutoScrollbox.new(nil, :relief=>:groove, :borderwidth=>4, \n                          :width=>20).pack(:fill=>:both, :expand=>true)\n  (0..20).each{|i| l.insert('end', \"line #{i}\")}\n\n  TkFrame.new(:relief=>:ridge, :borderwidth=>3){\n    TkButton.new(self, :text=>'ON', \n                 :command=>proc{l.scrollbar(true)}).pack(:side=>:left)\n    TkButton.new(self, :text=>'OFF', \n                 :command=>proc{l.scrollbar(false)}).pack(:side=>:right)\n    pack(:fill=>:x)\n  }\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tkdialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire \"tk\"\n\nroot = TkFrame.new\ntop = TkFrame.new(root) {\n  relief 'raised'\n  border 1\n}\nmsg = TkMessage.new(top) {\n  text \"File main.c hasn't been saved to disk since \\\nit was last modified.  What should I do?\" \n  justify 'center'\n  aspect 200\n  font '-Adobe-helvetica-medium-r-normal--*-240*'\n  pack('padx'=>5, 'pady'=>5, 'expand'=>'yes')\n}\ntop.pack('fill'=>'both')\nroot.pack\n\nbot = TkFrame.new(root) {\n  relief 'raised'\n  border 1\n}\n\nTkFrame.new(bot) { |left|\n  relief 'sunken'\n  border 1\n  pack('side'=>'left', 'expand'=>'yes', 'padx'=>10, 'pady'=> 10)\n  TkButton.new(left) {\n    text \"Save File\"\n    command \"quit 'save'\"\n    pack('expand'=>'yes','padx'=>6,'pady'=> 6)\n    top.bind \"Enter\", proc{state 'active'}\n    msg.bind \"Enter\", proc{state 'active'}\n    bot.bind \"Enter\", proc{state 'active'}\n    top.bind \"Leave\", proc{state 'normal'}\n    msg.bind \"Leave\", proc{state 'normal'}\n    bot.bind \"Leave\", proc{state 'normal'}\n    Tk.root.bind \"ButtonRelease-1\", proc{quit 'save'}\n    Tk.root.bind \"Return\", proc{quit 'save'}\n  }\n}\nTkButton.new(bot) {\n  text \"Quit Anyway\"\n  command \"quit 'quit'\"\n  pack('side'=>'left', 'expand'=>'yes', 'padx'=>10)\n}\nTkButton.new(bot) {\n  text \"Return To Editor\"\n  command \"quit 'return'\"\n  pack('side'=>'left', 'expand'=>'yes', 'padx'=>10)\n}\nbot.pack\nroot.pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')\n\ndef quit(button)\n  print \"You pressed the \\\"#{button}\\\" button;  bye-bye!\\n\"\n  exit\nend\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/ICONS/Orig_LICENSE.txt",
    "content": "\n  #########################################################################\n  ### The following text is the original file of the Tcl/Tk extension.  ###\n  ### Icon data files ( those are 'tkIcons', 'tkIcons-sample.kde', and  ###\n  ### 'tkIcons.kde' ) are quoted from the source archive of ICONS       ###\n  ### extension. As the following document describes, those icon images ###\n  ### are not applied the license.                                      ###\n  #########################################################################\n\n\nIMPORTANT LICENSE INFORMATION\n=============================\n\nThe following terms (based on the standard TCL/TK license) apply to all files\ncontained in this package, <b>except</b> the icon images.\n\nThe icon images can be freely distributed. If you require clarification of\ncopyright/license details for the images, please contact the appropriate\ncreator/maintainer.\n\nICONS: LICENSE TERMS\n====================\n\nThis software (ICONS) is Copyright 2002 by Adrian Davis (adrian@satisoft.com).\nThe following terms apply to all files associated with the software except\nwhere noted above. \n\nThe author hereby grants permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that\nthis notice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file\nwhere they apply. \n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY\nOF SUCH DAMAGE. \n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,\nOR MODIFICATIONS. \n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal\nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you\nare acquiring the software on behalf of the Department of Defense,\nthe software shall be classified as \"Commercial Computer Software\"\nand the Government shall have only \"Restricted Rights\" as defined in\nClause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing,\nthe authors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license.\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/ICONS/tkIcons",
    "content": "actattach16:act act16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBPz+/AQCBAAAACH5BAEAAAAALAAAAAAQABAAAAI2hAOCxg2h0nJHyEshi9HpxU1GOCLdZoKpQ15nibUoprKp9lh2oucUxsBRXsJh4Hjs/QTMpr8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactbookmark16:act act16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy+vERGRFRWVDQ2NKSmpAQCBKyurMTGxISChJyanHR2dIyKjGxubHRydGRmZIyOjFxeXHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICACwWieY1CibCCsrBkMb0zchSEcNYskCtqBBzshFkOGQFk0IRqOxqPBODRHCMhCQKteRc9FI/KQWGOIyFYgkDC+gPR4snCcfRGKOIKIgSMQE31+f4OEYCZ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactbookmarknew16:act act16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy6vERGRFRWVDQyNKSipAQCBMTGxKyurISChJSSlJyanHR2dIyKjPz+xISGhPz+BGxubMTCBHx+fPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVfICACwWieY1CibCCsrBkMb0zchTEcNYsIiYHiwIOdEAvigdFQGE0Ix4NBbSAgsWjk+jBIAlcUYrJASChnSXZSoUDelKfoKpFALJA61ueGI2IAZmhogGFmCGGAgXsifiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactcheck16:act act16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBMT+xATCBASCBARCBAQCBEQCBAAAACH5BAEAAAAALAAAAAAQABAAAAM2CLrc/itAF8RkdVyVye4FpzUgJwijORCGUhDDOZbLG6Nd2xjwibIQ2y80sRGIl4IBuWk6Af4EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactcross16:act act16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/PwCBMQCBEQCBIQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMuCLrc/hCGFyYLQjQsquLDQ2ScEEJjZkYfyQKlJa2j7AQnMM7NfucLze1FLD78CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactexit16:act act16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBDQyNHR2dCH5BAEAAAAALAAAAAAQABAAAAI4hI+pFrHb3nEg1iWiDiINCwYDko0V9XUTda6I1TIsUMpGinyzbB6ZeGuoEr+GUDL4CXqSphPhLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nacthelp16:act act16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQ6XAQCBCyCvARSjAQ+ZGSm1ARCbEyWzESOxIy63ARalAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ/EEgQqhUz00GEJx2WFUY3BZw5HYh4cu6mSkEy06B72LHkiYFST0NRLIaa4I0oQyZhTKInSq2eAlaaMAuYEv0RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactitemadd16:act act16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBARCZPz+/Mzq9BTC3ITC1HSyzGSivAw+XBSStIS6zHy2zAQCDFyatAQOHFSStEyOtAQSJBSq1DR2nCxunCRmlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICCOQTmeaCAMRIC+AVu47xkTBl2Ld16XQNYBQTQBVIOkMHFQJBeMI4tAbSSu2IRDSnhAvFfI97sFRM6RwOMacbjLKckVvgvIJ5EdSU7J648VgXQ7Dmd/hyJ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactitemdelete16:act act16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBARCZPz+/Mzq9BTC3AQCDAQOHFSStAQSJAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQwEMhJq704681n+GAISoEwnGg6EAUQrEQsz4ThEkeu77kNIAagMEj0dY7IpHI58UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactlock16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJEQ+FExGHCQiDBwaDGxiLHxyNHRuPIR+TIyGZJSSfFxaRFxWJGRiLJyaXNzWpNTOnMzGnLy2hJSKTGReLKyqjPTu1NzarMS+jLSyfKyibJySXIyGVCQeDLSytPT29Ozu7OTi5NTS1KyurJSSjGxqVFxaXLS2tKSebOzuzLSufJSOXExGLGRiTExONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwGCgGhkhkQDBoEpLKQoBACAyOUID1qTVwoQGvMPxNFgVjAxp6QCQUicSCwVgkG44HJCKRRCYUCAxIFRYXhxgZGhYbHINEHR4fGCAhIiMkFSVKJicoKSoFKwMsLZtDLison6GjLA92qCueoAUvpC2xQhWqrLYDErmEMDEXlDIwMxAHukI0NS01EzY2NAmPAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactredo16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBxOHBxSHBRGHKzCtNzu3MTSzBQ2FLzSxIzCjCSKFCyeHDzCLAxGHAwuFDSCNBxKLES+NHSmfBQ6FBxWJAQaDAQWFAw+HDSyLJzOnISyjMTexAQOBAwmDAw+FMzizAQODDymNKzWrAQKDAwaDEy6TFTGTFSyXDyKTAQCBAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ2QIBwSCwaj0hAICBICgcDQsEgaB4PiIRiW0AEiE3sdsFgcK2CBsCheEAcjgYjoigwJRM2pUK0XDAKGRobDRwKHUcegAsfExUdIEcVCgshImojfEUkCiUmJygHACkqHEQpqKkpogAgK5FOQywtprFDKRwptrZ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactreload16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCRaJBxWJBxOHBRGBCxeLLTatCSKFCymJBQ6BAwmBNzu3AQCBAQOBCRSJKzWrGy+ZDy+NBxSHFSmTBxWHLTWtCyaHCSSFCx6PETKNBQ+FBwaHCRKJMTixLy6vExOTKyqrFxaXDQyNDw+PBQSFHx6fCwuLJyenDQ2NISChLSytJSSlFxeXAwODCQmJBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIBQGBAMBALCcCksGA4IQkJBUDIDC6gVwGhshY5HlMn9DiCRL1MyYE8iiapaSKlALBdMRiPckDkdeXt9HgxkGhWDXB4fH4ZMGnxcICEiI45kQiQkDCUmJZskmUIiJyiPQgyoQwwpH35LqqgMKiEjq5obqh8rLCMtowAkLqovuH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactrun16:act act16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/ISChKSipMTCxLS2tLy+vMzOzMTGxNTS1AAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARlEMgJQqDYyiDGrR8oWJxnCcQXDMU4GEYqFN4UEHB+FEhtv7EBIYEohkjBkwJBqggEMB+ncHhaBsDUZmbAXq67EecQ02x2CMWzkAs504gCO3qcDZjkl11FMJVIN0cqHSpuGYYSfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactstop16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/Gw6NGQuLHQ6NGQmJFweHFQaFPTm5PTa3PTW1Oy+vOS6tNSinKReVDQWFPz+/Nx6fNyCfNyGhNR+dMxybMRiXLxGRIwWFNx2dNx+fNx2bMxuZLQWFBwWFPTu7Pzy9NRqZNRuZMRSVLwmJGwWFNR2dMQiHPTKxMxmXMQyLMxmZNx6dMxiXMRSRMRaVKxybMxaVEQWFMQuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaaQIAQEBAMCAWDYcgkHhAJxYLRcDQBggckIplQKpaLdRh4YDIaSWa94Vw6woAHgv6AMKGPaMQhwQMJJRkfhHmEJhdvRCcgGSCEkCgpbnAECiorGYYfLCItlAAFCygQj5AfbYlwBQwVE5AukG6KBi8tMC0fLi0pHxyzcAAxFxwmMny/wEwOxMm/qlcdJCSJ1H5XQh3a28HY3kx+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactundo16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBxSHBxOHMTSzNzu3KzCtBRGHCSKFIzCjLzSxBQ2FAxGHDzCLCyeHBQ+FHSmfAwuFBxKLDSCNMzizISyjJzOnDSyLAw+FAQSDAQeDBxWJAwmDAQOBKzWrDymNAQaDAQODAwaDDyKTFSyXFTGTEy6TAQCBAQKDAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ1QIBwSCwaj0hiQCBICpcDQsFgGAaIguhhi0gohIsrQEDYMhiNrRfgeAQC5fMCAolIDhD2hFI5WC4YRBkaBxsOE2l/RxsHHA4dHmkfRyAbIQ4iIyQlB5NFGCAACiakpSZEJyinTgAcKSesACorgU4mJ6uxR35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactunlock16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJExGHEQ+FCQiDBwaDBweDGxiLHxyNHRuPIR+RIyGZJSSfFxaRGxmLJyaXNzWpNTOnMzGnMS+jJSKTGReLKyqjPTu1NzarLSufKyibJySXIyGVGxiNFxaXLSytPT29Ozu7OTi5NTS1KyurGxqVCQeDJSSjLS2tNTW1KSmpGRiLKSebOzuzJSOXExONExGLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaVQIBwOAwYA8SkMCAYOAnKYiFAIAQGyOgVCggYuEovVxztMpdnwAGRSCgUCwOjIeQ6HpCIZDKRUNYMRBUWF4UYGRoWGxyBRR0eHxgaICEiIyR0QyUmJygpKgUrAxMsLUQlKyieoKIuEAunK52fBS8DLiywQySpnjC1Mbi6QjIzNBeSIBY1EQfDQgosLAEUNjY3Co1DfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappbook16:app app16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBDyKhDSChGSinFSWlEySjCx+fHSqrGSipESOjCR6dKTGxISytIy6vFSalBxydAQeHHyurAxubARmZCR+fBx2dDyKjPz+/MzKzLTS1IyOjAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVkICCOZGmKQXCWqTCoa0oUxnDAZIrsSaEMCxwgwGggHI3E47eA4AKRogQxcy0mFFhgEW3MCoOKBZsdUrhFxSUMyT7P3bAlhcnk4BoHvb4RBuABGHwpJn+BGX1CLAGJKzmKjpF+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappbookopen16:app app16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExCNGSenHRmVCwqJPTq1GxeTHRqXPz+/DwyJPTq3Ny+lOzexPzy5HRuVFSWlNzClPTexIR2ZOzevPz29AxqbPz6/IR+ZDyKjPTy5IyCZPz27ESOjJySfDSGhPTm1PTizJSKdDSChNzWxMS2nIR6ZKyijNzOrOzWtIx+bLSifNTGrMy6lIx+ZCRWRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQEAAQCwWBYJiYEAoGAFIw0E5QCScAIVikUgQqNargtFwdB9KSDhxiEjMiUlgHlB3E48IpdKdLCxzEAQJFxUTblwJGH9zGQgVGhUbbhxdG4wBHQQaCwaTb10emB8EBiAhInp8CSKYIw8kDRSfDiUmJ4xCIxMoKSoRJRMrJyy5uhMtLisTLCQkC8bHGBMj1daARgEjLyN03kPZc09FfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappboxes16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMT+xAT+BASCBATCBMT+/AT+/ASChATCxPz+xPz+BISCBMTCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEEgZwrwYBCFqvhs3DNYXjChRlWBRjIRqGN4UuEUczMZxsDeXykdEsDQVVSLhQxhBCkVlmXA+KVHFYhFYOoHbMGN6pTQaW8YYiQmcG+q16a0+Zipw+4e9B/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappbox16:app app16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+xISCBMTCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANECKoR6ys2IVqokF08yMTA1gwkYX5WQK5ma4VceTYPxXnBWdtY6+0834/Bowgzm6APWRQcH4TiMhPK2WYRiZWW7XK7/gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappbrowser16:app app16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxONCROfCRKfKx6LNy+bNTOpGSS1DRupAwyXBRSnPTSjPTqvOzqzMzSvHSSlKy6ZDxutAxCpBQ2XBxepLTKvPzqzPzy5OTShLS2dLSqRFR2jBRerBQ+jOTixOzetNS2XHx6XDR2tCRexBwyTDyKzOTavPzq1OzKdCx23BRKtCQ6VCQmHFSa7IyirOzSnGSGpIR+bFSO1DyK7DR+5CRixBw2VDQuHFye7IS27NzGXISuhEyS5DR25BRWxBQ+lBQyXCQqPCxSfGyu7GyerKy2ZFR+rERqfCRmxBROtBQ+fBwuTBwmNDSW9JyabLyqRIx+TExSXBQ6bAQCBBQ6ZBxapDR+zBxq3LyaLJySRHxqPGxeNBxGbCRmrHRyRERONDRKNDQ2JCQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAeygACCg4SFhgABAQIDh4MBBAUGBwgDCYcKCwwNDg8QERIThRQVFhcNGBkaGxwdoYMDHhcXHxggISIjEiSvJSYXJwsoISkpIyorLIIDLS4WLzAxMjM0NSo2N8o4OS46OzwzPSk+P0BBgkI8Q0NERUZHCEhJSktMgwk4Qy1NTk9QUVJLphCiUsWKlStYsmjZQiJgIS4KuijQ4iXAFxYCDVFJwGUFmDBhMjYSw0KMyEYoBfkJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappcalc16:app app16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBISChPz+/AQCBCH5BAEAAAAALAAAAAAQABAAAAI4hI9pwe0Ogpi00hHF2LzzzFlTsIHD45SSx6oCeW4wjK2tl83y7t64pIsJaxrfh2bEAJIlhRPhLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappclock16:app app16 16:photo:16 16:R0lGODlhEAAQAIIAALy+vAQCBPwCBMQCBIQCBISChPz+/MTCxCH5BAAAAAAALAAAAAAQABAAAANbCLHcrSLKOZcYmDSCsR1aUABAsXDDJwJGa5SBFwgaWxbCG3CWaBwG3C8Y67FawpYiNQscg65fsVkYuoAmJs1pBR522lQB6ILJLqHRwQQOZzYdZnw+dzruDIA/AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappdate16:app app16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBPzerPyqXMRaBIQCBISChPz+/KSipMTCxPz+BMTCBPwCBPz+xPzCxMQCBISCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVxICCOQGCeJjkGwkC8RFEEavkax2G8dB0QuRyhhzoBg8MSYsncJXKJZIDZHCoWP1ogGIwGrtnSgUFmHLyNRHhrdpjRamnO/SYkromHdnxwnwkKVxByZW8DgQsQM2JcfwZXO0MBCZSVBgMuLzJaRZ0pfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\napppencil16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/IQCBMQCBPzCxAQCBPz+/MTCxISChDQyNKSipEQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARDEMhJZRBD1H2z3lMnjKCFjUJQimOgcmcbELCXzjXq0hV785WCQYcDFQjDXeloMByKG6YTAdwIDAlqSZJSVFeKLcUfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappsheet16:app app16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBAT+/Pz+/KSipPz+BAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANFCBDc7iqIKUW98WkWpx1DAIphR41ouWya+YVpoBAaCKtMoRfsyue8WGC3YxBii5+RtiEWmASFdDVs6GRTKfCa7UK6AH8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\napptool16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBISChGRmZMTCxKSipLS2tHx6fPz+/OTm5FxaXOzu7DQyNMzOzAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMhAq7wYBDECKVSGBcbRfcEYauSZXgFCrEEXgDCSeIEyzKSXZoBYVCoJVIqBGByKu0Cy8QHxmgNngWCkGgqsGWFseu6oMApoXHAWhWnKrv0UqeYDe0YO10/6fhJ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\napptools16:app app16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBExKTERCRAQCBOzu7Nze3MzKzLy+vCxqZBQ2NJyanKyqrGRiZDRydKza3FRWVPT29LSytDw6PMTm5EySjCxaXGRaJFSanCRSVGxqbPTmvMSqVJTW1GSurHS6vOzq7KSipISChFRKHJSGNPz23GxKFBQ6PKyurCwqLMyufJx2RAQGBJSWlEwyDIRiLNy+lLSKVDwmDJRuNOTOrLyabGRCFDx2dKSCVOzWtHzCxOTGnNSyhAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAahQIBwCAgIBAOiUiggFAyHASKxDAwUC8Zg0HAglA9IZPGQABoTSqJCFTIOEIsFgHBcEhhHUpKJFCwaGxYYHB0VEx4IEh8gIQwiIyQbJRMcHokmEicfDygAkCkqJQgIGG0rLElCLS4vMCWqQwMCQg0UMTIzNDVLQjaIGDE3ODQlS785CEkxKjowvEOHybG4O6JDCdNKuDUxRAmxRDHeveUAfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappuser16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MTCxISChMT+/ATCxASChFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMg5gw00yyDGIAR1YUDggeFWFIZhnSBZrsZxdIOFEGTA2oeBAHeyuGwvzxBlYdUOLROMFzDQntJPrNoqAKUBaqnV+k57ZORruykHDj2LqIzUVKp1u0iuB/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappusers16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxISChAT+BMRaBPyqXARCBPz+/FxaXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARLEIRJa5Ui673nsGAgeKE1Bl9AUEXbiqTlFlZaGUZoszm4BzhDAVf5BYbAXI+TAR6CS2ZGSZSEiIIqYIsSIEaJ7GRrlY7J1lKA7I8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappwp16:app app16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBKSinJyOfPz27Pzy7AwKDExOTJyWlERCRKSelPz69LyyrKymnPz+/MS2fDQyJAQCBOTazLSiXOzivMS2jKSSVOzmxPz25NzSpPTu5KyebOzixNTGjOTWpMSydMSybCwqFGReVKyaXNzSnGxeNJSCVMS2nPz23MSuZIR+bJyShLyqnOTOtGxiXIR6XOTSvIx6RMSubIyCdKSalMS6pOTWxMzKvKSabJyKTOzezHxuPGRmZKyurMTCvPTq3AAAACH5BAEAAAAALAAAAAAQABAAAAajQIBwCAgIiEhiYEA4FgwHRDKhIBAWz4OhgGQ0FAPHA7qFEBONb0Qy0ULeQ2+aUrFcMI+3GYBOZzQbHB0eHyAhIQByDREiEwMjFRIkJQImAgJ+jScjHigkKSorLC0AKg2NFSMoki4qCy+IQgITKDAxkjIzNDWkQxQoJaskMgk2Eb1DNzgoOCoHDDY5yEIwJToAOzw9ET7TQiREAhkZ3kmy5QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncal1day16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANOCLrMEUDIOUS9AFLLhx8LIRZjKYZmMRCkaChFLHty/AIiS3y6q+QtT49wq8VotRtQJGwRf6Zmrlj7DJLQXsupTJmeEIN4TB5nII20wp8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncal5days16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANMCLrMEUDIOUS9AFLLhx8LIRZjKYbj55GioRRwoQ5x4QIiIdMmcec7jy53q81qP9OO5VMAj8RXTFWzOZW95HDLdEEM4LA4nIE0zgp/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncal7days16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANPCLrMEUDIOUS9AFLLhx8LIRZjKYbj55GioRRwoQ5x4QIiwcp0fucsj873qvGMv5Jw2FIACUsW4WakGW1O046I05qmGYBhTC6TM5CGWuFPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalappointment16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/MTCxPz+BISCBISChKSipAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARbEMhJaQhA6D1E/wDGeeRgDhOhFoTBEi+REgdrIHScSEVvAD9Xr7cDqGSGpFEnQSqTv2NxCFQOiU1VEAiTZmstHFg1vQKuw+LxxfYaV/AuOQRI2O/4ewhT6Uv8EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalbell16:cal cal16 16:photo:16 16:R0lGODlhDwAOAIIAAPwCBISCBPz+BIQCBMTCxISChPz+/AQCBCH5BAEAAAAALAAAAAAPAA4AAAM+CLrR+zCIAWsgLVRGRBhOVQiG94WPVAbHaZHYAWqRYLbge88RsbInGuBCEhRYrZYm4xk4nYdoKzKIbiKHawIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncallist16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/KSipPzerMRaBEQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARDEMhJaQhA6D1E/wDGeeRgDhOhruyatjBRSIRxxOsMEAdC0BUZDcfSEYvDo3Bn++2Cxt7RqFxWhZiCdsvdhjCVsMQfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalmonth16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANSCLrMEUDIOUS9AFLLhx8LIRZjKYbiRxLFIBpK0Q6z7MkwkJIe8b0KEeuWchFysuStVsjtfMbeMQitWpG25YfmNK1WU53XNIUYzug0OgNpuBX+BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncaltoday16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/MTCxKSipPyCBMRaBPyqXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARTEMhJaQhA6D1E/wDGeeRgDhOhFmurpi5LyIQhFfiBIAfuFzaAioBIJBCummRYPCaDPh3vhwsOZdihNfa8Ub/AJXemFZPPNBvGwG672yFMZS7xRwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncaltodo16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBAT+BAQC/AQCjPz+/MTCxPzCxKSipPwCBMQCBIQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARaEMhJaQhA6D1E/wDGeeRgDhOhFmurpi5LyMYhFXiuFwZiA6qZYbbqJX5BIw2RAPxwAAWCyWMCCsiXFGEEErKz6LQZfOqiTR1YJiGq1rFyyHmo2+/1EKbCl/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnecting16:connect connect16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBPz+BMTCBISCBAQCBPz+/MTCxMTGxISChFxaXMzGzKSipAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJZbihUiz60FPnfaA0iBpBVGdHEYWxToEoSHBRHHM9AgSEQRcj+AYkYAJxIPKQFUJiOdTJQFIDU6dYzKKFhTCM+E5g4mXaDAyrlogEG+DGTecA7wsP8EcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnectno16:connect connect16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBPz+BMTCBAQCBERCBPz+/MTCxMTGxISChFxaXMzGzKSipAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARPEMhJq704axBEHoPUEdhQGMNYFuwxkKInDYjBniEnwMCQIIebSzXx/WwsFK+YMABZikWuYlrUCtZpEYv4WRPaHhb064YB41kCfJFSQBh/BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnectyes16:connect connect16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/KSipDQyNMTCxMTGxISChFxaXMzGzAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJZxCjgsAtDtUlCOA1gJQ4kl/IDatAoF7xxkS6GgEBr6jAobCyBX42SQBxMOx6A8MhiGASR8YDgrYsNEeJ0zaEGZY7uoH2oB6nOUwtbdLaVOeTUwo/8UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevcdmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tOzOvNTqvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/LzKvMTCxDQyNASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAa0QIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTBqUiuUCVmAeiYzmsKlwOt/AAKFIFAIIFx4WHyAhUwIDIgsZFyMkFxchJSYmiBkSBBoIJJwIGgOhiCYFJSEnFyQjFwNZewABISAfFiYnCAEmCREIrwAIFhwVGwcaBAkPGApsQsAVFA0GBQMRbxBTKM0ODQwTEq192ClDgROkBHvYKuNJUu5CKCorX1RDKCkpUn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevcdunmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tNzmvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/MTCxLy6vDQyNOTm5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAapQIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTLqUigWsuDwSmMxBQ9lwvoEBQpEoBBAWHRseHyBTAgMhCxgWIiMWFiASJCSHEgQSGQgjmwglGKCHBQUSICYWIyIWAwshIVMBIB8eFSQmCAEFCREIekIIFRsUGgcZEgkPFydrvxUUDg0GBSEREGJfv9AMEySsJxDYQ4DcEhh64UpS6lTs7QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevdiskmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBDQyNIRuVKyCXMSKROzSrOzKpOTGnLSafLySZKxuLMSOVPTWvPzixLSehNyibOzOrGxaVJx+XOzGnFw2FJRuPKx+TPTSrHRWPKyKZPTOpHxOJKyKXFw+HKSipISChMTCxFxaXIRiPNSWXExOTOS2hLR+PLRyLPTWtMyOTASCBARCBPz+/DTSJIyKjIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwCAgYA8SkMCAYDARI5ZJQMBwQiWgyoFgwrA3HQ7scQAqFAcEQOUi0zAkFUSFYLghMBloUCDQNGxwdHhwHekcfICEhICIfIxkLJBABJUYCICABIhAOBiYnKJaXmH4CGSkYCCqkSAEfTKenrkOwsrQll0IrS7G5uwArLLaxLbXCLsTFLyDBKy4wZEVHvCwsRn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevdiskunmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBDQyNIRuVKyCXMSKRPTWtOzKpOTGnLSafLySZKxuLMSOVOzOrPzm1LSehNyibGxaVJx+XOzGnFw2FJRuPKx+TPTSrHRWPKyKZPTWvHxOJKyKXFw+HPTOpKSipISChMTCxFxaXIRiPHxaNLRyLNSWXExOTPzixOS2hLR+PMyOTPz+/IyKjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaIQIBwCAgYA8SkMCAYDARI5ZJQMBwQiWgyoFgwGgiD46FdDiCFwoDQAEe0TMkEQSFULIcLBloUCDIaDRscHRsNHhhHHyAhISAiHyMkJSYQASdGAiAgASIQKA0pKguXmJl+AiQGFwgrpUgBH0yoqK9DsbO1J5hbsrq8SrgstlJFHy0gwMVFR1J+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevfloppymount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBMTCxARmZPz+/FSWlLSytKSipERCRIyOjISChOTm5HRydNza3GRiZFRSVASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVrICCOQBCQKBkIw5mqLFG47zoQ+FwbN57TosDhgPD5dMEEIqE04kwlBWKBUEiNVYFpyqAyGEUCgqEtERiNNMLhQKzLQYJg7n7Y4aMAwbCUPvAQeWNgfzQQETAIhSMQEogwgBITQEGGEREmfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevfloppyunmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxARmZPz+/FSWlLSytKSipERCRIyOjISChOTm5HRydNza3GRiZFRSVCH5BAEAAAAALAAAAAAQABAAAARcEMgJQqCYBjFu1hxReN82EOhYGieaklJwHIjrqnGCJLqNWhUFYoFQCG1FgWXIIDIYNQKCoawQGI0swuFAbKsxgmDsfZjBkwDBsNM90Jot9A3DbBD0Dwiur9QnfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevnetwork16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBISChPz+/Nza3ARaZESanCyKlARudARGTLy+vNzq7ARmbMTCxARufAROVMzOzKSipARyfOzq7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVmICAGZFmKQiACweCSBImq41AYB5IodLq2hwWO0ejRWDac48Gb/QKNqNRoqspmrVcAUuIJBANS8sBIFCORUgooPEh4J8B67NgdsVBp9C5XWfl9LRMTCyReX19hARNojWlWLH+AAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevpc16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBISChHx+fPz+/AQCBAQC/AT+/AQCxAQChAT+BLy+vAR+BAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARYEIAgqK1YzsG754QUDERpmkEpkkXrtoK6EcVgHIibhnNx564Yb0TDvQq7FQ34EiqPOhnREqhWSUPsyZSQAbbg7GcMEgwUiYVivTa1R+y4XEGoWO/4AMAfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevscanner16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MT+/ASChARCRATCxMTCxFxaXKSipDQyNAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEMgJgqWBVivEldkUdKSXhVjZfenommglDERh3Tc4E4ZRHAGgkEPr9X6H5AHBERSMRyWzkug8jQXFEhWoOo8dRYxqLXSmGjIJnVaz29Q3fAP3RwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevscreen16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXFRSVPz+/PT29OTm5OTi5DQyNDw+PERGRExKTHx+fISChIyKjHRydFxeXDQ2NCQmJBQSFAQCBERCRMTGxHR2dGRiZExOTDw6PCQiJAwODCwuLFRWVOzu7BweHAwKDCwqLHx6fBQWFGxqbGRmZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAanQIBwSCwKAwKkMslEAgSDqDRKqBYKhkNgcDggEorkMrDQchkNhuOhgEQkk0l5S2lUGpYLJqPZTAwMHB0DCmhqAW0Rfh5zAxgOkBcCFAcfIBMECxwBBAEPFw8dChkhcBMDDAcdnQqtFKSWcQMimx4dGRkQBxGxsg6bBQEawx8jl3GnJFoFHRNXVVNRJYIFDAsL1tgiDiQXFx0HABwcXeQH5OjkRutEfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevspeaker16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXAT+/DQyNATCxMTCxPz+/AQCBKSipASChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEMgJQqCXziDG2JoUEENhZBkmHIWJVptAmqcIW/Js1MiF56TBzkckAAcHoa9nMRKeA4TyJk0knsHhTeK5khBaH2VwLYVh40TJhQ6RzeIQV32Quz8hfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditcopy16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAFxaXPwCBNze3GxubERCRPz+/Pz29Pzy5OTe3LS2tAQCBPTq3PTizLyulKyqrOzexLymhLy+vPTy9OzWvLyifMTCxHRydOzSrLyihPz6/OTKpLyabOzu7OTm5MS2nMSqjKSipDQyNJyenLSytOTi5NTS1JyanNTW1JSWlLy6vKyurAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAaUQIBwCAgYj0eAYLkcEJBIZWFaGBie0ICUOnBiowKq4YBIKIbJcGG8YDQUDoHTKGU/HhBFpHrVIiQHbQ8TFAoVBRZeSoEIgxcYhhkSAmZKghcXGht6EhwdDmcRHh4NHxgbmwkcCwIgZwqwsbAhCR0CCiIKWQAOCQkjJAolJrpQShK2wicoxVEJKSMqDiAizLuysiF+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditcut16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAQABAAAAIwhI9pwaHrGFRBNDdPlYB3bWHQ1YXPtYln+iCpmqCDp6El7Ylsp6ssR1uYSKuW0V8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neditdelete16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPT29GxubMzOzDQyNIyKjHRydERCROTi3IyKhPz29Ox6bPzCxPzy7PTm3NS6rIQCBMxCNPTq3PTi1PTezMyynPTm1PTaxOzWvMyulOzGrMymhPTq5OzOtNTKxNTOzNTCtNS+rMSehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaKQAAgQCwahcihYMkcBAiBpLJApRoOBWgyIKhSEQkFgrBAcr1URiPhKAsDD3QB8RhA3FM0IlLHnyUTVBMSFBUWfl0XGBMTGBcZGodmcQWKjpAbHIgIBY2LHRoempOdjooTGx8giIOPFYofISJ+DyMXI6AfFySyfiUmJSUnKBYcICIpfgELzM3OZX5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedit16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaVMR+RPzKjNze3AQCBMR6RPzGjPyODPz+/MzOzPyKDPyKBPz29OTWzPyGDPyGBOx6BOza1OR2BKROBNSOXKRKBBwOBOzu7PTWxPzizOySZPyCDFxaXOy2lNRyRMxmJCQOBPTm1OzStPTKrMR+XIRWLFxGNCQSBDQyNIRSNDQuJERGRLyqlNzSvIx6ZKRuVEw6LLSyrLymhKSShBwaFFROTJyWjMS+vNzW1OTazNzKrHRqXOzezOTOpPTq3OzWvOTStLyedMS+rLy2pMSynMSulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAewgAAAAYSFhoQCA4IBBI2OjgUGBwiLBAmXlpcKkgsMlZcJBA0JDpIPEBGVjwkSBgOnExSfmBIVBxAMExYXswkYGRobHLq8gh2PHhoeHyAWIYKzIiMkJSYnKCnQg5YNHtQqKywtK9qMBC4vMDEBMjIz2dCMDTQ1Njc4OToz5PEEOzw3ZPToMcLHO23HfogQ0QMIkCA+hPBbhAPHECJFjMyYIUQIvEUpUqwQOXKkSEF+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditpaste16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQiFHRqNIx+LFxSBDw6PKSaRPz+/NTOjKyiZDw+POTe3AQCBIR2HPT23Ly2dIR2FMTCxLS2tCQmJKSipExGLHx+fHR2dJyenJyanJSSlERCRGRmZNTW1ERGRNze3GxubBweHMzOzJSWlIyOjHRydPz29MzKzIyKjPTq3Ly2rLy+vISGhPzy5LymhISChPTizOzWvKyurPTexOzSrDQyNHx6fCwuLGxqbOzKpMSabAQGBMS2nLyulMSidAAAACH5BAEAAAAALAAAAAAQABAAAAa7QIBQGBAMCMMkoMAsGA6IBKFZECoWDEbDgXgYIIRIRDJZMigUMKHCrlgul7KCgcloNJu8fsMpFzoZgRoeHx0fHwsgGyEACiIjIxokhAeVByUmG0snkpIbC5YHF4obBREkJCgon5YmKQsqDAUrqiwsrAcmLSkpLrISLC/CrCYOKTAxvgUywhYvGx+6xzM0vjUSNhdvn7zIMdUMNxw4IByKH8fINDk6DABZWTsbYzw9Li4+7UoAHvD+4X6CAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditshred16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbGxubMzOzPz69DQyNIyKjERCRPz29PT29OTi3IyKhPz27PTu5PTy5Pz6/Pzy7PTq3OzexLyqlPTm1PTizOzavLyqjOzWvOzaxLyifOzizOTOpAQCBOzezAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaEQAAgQCwahcihYMkcBAiBpLJApRoOBWgyIKhWEQkFYYHkeqkMxKFBFpq9jgdkEGlPqwrJhCIY2N8FFRYUFxcYGX9dgRKEGhiHiYEOhBcbGBwdiQEOARcBGwEeAZllAgEUnQEfoQEgmp4hrCKtrwEYsrRlTiMBJAG8syN/IyMAxMXHSH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedittrash16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipFxaXPz+/MTCxISChDQyNCH5BAEAAAAALAAAAAAQABAAAANQCKrRsZA5EYZ7K5BdugkdlQVCsRHdoGLMRwqw8UWvIKvGwTICQdmGgY7W+92GEJKPdNwBlMYgMlNkSp3QgOxKXAKFWE0UHHlObI3yyFH2JwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfileclose16:file file16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCQiJBwaHAQCBDQyNDw6PFxaXFRSVERGRCwqLAwODGRiZHx6fPz+/GxqbAwKDCQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVaICCOZGmeqBgEwjCkRGEcSKK4JrEcBrMgAdeLVDg0GguGsYEbBQyGYyN6FDoPDIf0+LCKBIgetQERDgGDBGIpNY8GioAU0m6KXFw883w3+/l9f4AkfimGIn4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfiledocument16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJSWjPz+/Ozq7GxqbJyanPT29HRydMzOzDQyNIyKjERCROTi3Pz69PTy7Pzy7PTu5Ozm3LyqlJyWlJSSjJSOhOzi1LyulPz27PTq3PTm1OzezLyqjIyKhJSKfOzaxPz29OzizLyidIyGdIyCdOTOpLymhOzavOTStMTCtMS+rMS6pMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaQQIAQECgajcNkQMBkDgKEQFK4LFgLhkMBIVUKroWEYlEgMLxbBKLQUBwc52HgAQ4LBo049atWQyIPA3pEdFcQEhMUFYNVagQWFxgZGoxfYRsTHB0eH5UJCJAYICEinUoPIxIcHCQkIiIllQYEGCEhJicoKYwPmiQeKisrKLFKLCwtLi8wHyUlMYwM0tPUDH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfilefind16:file file16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBCQmJDw+PBQSFAQCBMza3NTm5MTW1HyChOT29Ozq7MTq7Kze5Kzm7Oz6/NTy9Iza5GzGzKzS1Nzy9Nz29Kzq9HTGzHTK1Lza3AwKDLzu9JTi7HTW5GTCzITO1Mzq7Hza5FTK1ESyvHzKzKzW3DQyNDyqtDw6PIzW5HzGzAT+/Dw+RKyurNTOzMTGxMS+tJSGdATCxHRydLSqpLymnLSijBweHERCRNze3Pz69PTy9Oze1OTSxOTGrMSqlLy+vPTu5OzSvMymjNTGvNS+tMy2pMyunMSefAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe4gACCAAECA4OIiAIEBQYHBAKJgwIICQoLDA0IkZIECQ4PCxARCwSSAxITFA8VEBYXGBmJAQYLGhUbHB0eH7KIGRIMEBAgISIjJKaIJQQLFxERIialkieUGigpKRoIBCqJKyyLBwvJAioEyoICLS4v6QQwMQQyLuqLli8zNDU2BCf1lN3AkUPHDh49fAQAAEnGD1MCCALZEaSHkIUMBQS8wWMIkSJGhBzBmFEGgRsBUqpMiSgdAD+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilenew16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPz6/GxubNTKxDQyNIyKhHRydERCROTi3PT29Pz29Pzy7PTq3My2pPzu5PTi1NS+rPTq5PTezMyynPTm1Pz69OzWvMyqjPTu5PTm3OzOtOzGrMSehNTCtNS+tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ/QAAgQCwWhUhhQMBkDgKEQFIpKFgLhgMiOl1eC4iEYrtIer+MxsFRRgYe3wLkMWC0qXE5/T6sfiMSExR8Z1YRFRMWF4RwYIcYFhkahH6AGBuRk2YCCBwSFZgdHR6UgB8gkR0hpJsSGCAZoiEiI4QKtyQlFBQeHrVmC8HCw21+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileopen16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBOSmZPzSnPzChPzGhPyuZEwyHExOTFROTFxaVFRSTMSGTPT29Ozu7Nze3NTS1MzKzMTGxLy6vLS2tLSytDQyNOTm5OTi5Ly+vKyqrKSmpIyOjLR+RNTW1MzOzJyenGxqZBweHKSinJSWlExKTMTCxKyurGxubBQSFAwKDJyanERCRERGRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaRQIBwGCgGhkhkEWA8HpNPojFJFU6ryitTiw0IBgRBkxsYFAiGtDodDZwPCERCEV8sEk0CI9FoOB4BEBESExQVFgEEBw8PFxcYEBIZGhscCEwdCxAPGA8eHxkUGyAhIkwHEREQqxEZExUjJCVWCBAZJhEmGRUnoygpQioZGxsnxsQrHByzQiJxz3EsLSwWpkJ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileprint16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFRKNAQCBPz+/MTCxExKLPTq5Pz29Pz6/OzezPT29PTu7PTy7NzClOzm1PTu5LSabJyanPTm3FxaXOzCjOTKrOzi1OzaxOTSvJyenGRmZLyyTKSipDQyNERCROTi5Hx+fMzKzJSSlIyOjISChLS2tAT+BDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaYQIBwKAwIBMTkMDAYEApIpVBgOCAOg4RRGlAoEAuGIdGITgWOq4LxcCQgZkEkIHksHgYJOR6ZQCgVFhYJFxgTBVMZihoCfxUYDWUbUBGKGREcjBoQEB2TAB4CAx+Vl5WMhyACHiEhH6IfIiMktCQgE0cZJQStr6O2t6EARxO6vK6iEx4dZsMCxbsmBB4nzUTEutVSSUdmfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilesave16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBFRSVMTCxKyurPz+/JSWlFRWVJyenKSipJSSlOzu7ISChISGhIyOjHR2dJyanIyKjHx6fMzOzGRiZAQGBFxeXGRmZHRydGxqbAwODOTm5ExOTERGRExKTHx+fGxubNza3Dw+PDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaAQIAQECgOj0jBgFAoBpBHpaFAbRqRh0F1a30ClAhuNZHwZhViqgFhJizSjIZXQCAoHOKHYw5xRBiAElQTFAoVQgINFBYXGBkZFxYHGRqIDBQbmRwdHgKeH2YgHpmkIR0HAhFeTqSZIhwCFIdIrBsjAgcPXlBERZ4Gu7xCRZVDfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLARqnAQ+ZHR2dKyqrNTOzHx2fCQiJMTi9NTu9HzC3AxmnAQ+XPTm7Dy67DymzITC3IzG5AxypHRydKymrMzOzOzu7BweHByy9AyGtFyy1IzG3NTu/ARupFRSVByazBR6rAyGvFyuzJTK3MTm9BR+tAxWhHS61MTi7Pz+/IymvCxulBRelAx2rHS63Pz6/PTy9PTu9Nza3ISitBRupFSixNTS1CxqnDQyNMzGzOTi5MTCxMTGxGxubGxqbLy2vLSutGRiZLy6vLSytKyurDQuNFxaXKSipDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYHCImDBgkKCwwNBQIBBw4Bhw8QERITFJYEFQUFnoIPFhcYoRkaFBscHR4Ggh8gIRciEiMQJBkltCa6JyUoKSkXKhIrLCQYuQAPLS4TEyUhKb0qLzDVAjEFMjMuNBMoNcw21QY3ODkFOjs82RM1PfDzFRU3fOggcM7Fj2pAgggRokOHDx9DhhAZUqQaISBGhjwMEvEIkiIHEgUAkgSJkiNLmFSMJChAEydPGBSBwvJQgAc0/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolderhtml16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBERGRBQWFMzKzOzq7CwqLDw6NARqnAQ+XHR2dKyqrOTm5ExKTERCRHRydMTi7NTu9HS+1KSmpBweHDy67DyixHS61ITG3AxypByu7DxinBw+ZERmdIySjITC3ARypExOTDRurIR2RPTSdJyulEyGvBw+bFSyzJTK3LzKvPzivOTixNTChLSybGyCfCRSnBQqRASGtFyuzDw+PCRShPzy5OzerOTShKyaTEx6pCxerGRufBR+rOTezPTShNy6bER+1BxCfBQuRAxelFSixBw2VISq3GySrPTWlHyanIyitFSO3IymtCRujAxWhCRqlCQ6XGyWvNS2bFyGvDxuvCRSpLy+vMS+vGxqbFyO1GSi3EyO1FRaVCQuPLS2tDxyzKyWNFxaNCQyPGxubCxajERSVExKNJyenAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfZgACCAAECg4eIAAMEBQICBomDBwgJCgsEDA0BDg8BhwYQERKUDxOYDAyeghQVFhehGBmVlwwOqxobHB0eH6EfIAkPIYIiIyQlJhsnKBcpvrYiKissLS4vMDEyFjOvNAA1LDY3ODk6Oyc8PTIyFzQ1Jj42P0A6QTtCQ0REIEUORkdIkihZwsSekBhNnDyBciCKiSNSplDRUcWKkRhXCGDJYgiGli1cpuTocsILjytfFmRpACAGRTBhRogZgzHlAjKGWnIoY+bMgRgBDHRBo/LAIZoxuhwKatRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolderlocked16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQSFMzKzOTm5CwuLERCRARqnAQ+XHR2dKSmpOzm5GxqbCQiJMTi7NTu9HS+1HRydOTm1Ozq7Dy67DyixHS61ITC3AxypERGRBweHByu7ASGtFyy1DSOtDRmfExOTBSazBR+rCwqLAxWhAxelByGtDSaxAwODHy+1Dw+PPT29IyqvCxujOzu7NTW1Nza3ExGJJyebKyqfMTCpFRSPOTi5DQqHOTezDw2NMTGxKyqhMTGrGxmXDQ2NMTCxMTGpHx6bHx2bBQWFIyOXDQuDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQICBomDBwgJCgsEDAKFDQGHDg8QEZQSlxMUDJ2CDhUWF6AYGZWXFBqCGxwdFh4XGK8fIAohtiIIIx25EZwBDREHgiQjJSYmGScoKSoRKQ8rggIsDC0uJS4oGygoAyjdAAcsLxQUMDEyMzQ1EzapBy8MDDc36tFwgONFjlQ6dgCEEZBHDx8+ctRIRehHAyAwZASZIGRIEBoUBwUwIGMCiwFEaBQJichIjo9FZLBsacRIAB0A/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfoldernew16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBPz+hPz+BOSmZPzSnPzChFxaXMTCBPyuZPz+xPzGhEwyHExOTPz+/MSGTFROTPT29OTm5KyurDQyNNza3Ozq5Nze3LR+RLy+vJyenMzKzNTS1Ly6vJSWlFRSTMzOzMTGxLS2tKSmpGxubBQSFAwKDKSinJyanIyOjCQiJERCRERGRBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaNQIBwSCwaj8ikcokMCIqBaEDoBAQG1meAUDAQpIcBQoy1dg2JdBqhECgQ1IWB0WgcBIOBwIHXBwwPEBEREhIBbG4IExR/DBUVFhIXV2NjDVYYDY8SFU4ZVxpVAQwbGxynGxkdTh6XVh8gGSGzGSITIxokJUImGSMTwLcnKCkprgAqDSt1zCssKxQtQ35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolderopen16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOzi1Ozq7ERCRCwqLPz+/PT29Ozu7OTm5FRSVHRydIR+fISCfMTCvAQ6XARqnJSKfIx6XPz6/MzKxJTa9Mzq9JzO5PTy7OzizJSOhIyCdOTi5Dy65FTC7HS2zMzm7OTSvNTCnIRyVNza3Dw+PASq5BSGrFyqzMyyjMzOzAR+zBRejBxqnBx+rHRmTPTy9IyqvDRylFxaXNze3DRujAQ2VLSyrDQ2NNTW1NTS1AQ6VJyenGxqbMTGxLy6vGRiZKyurKyqrKSmpDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfCgACCAAECg4eIAAMEBQYCB4mHAQgJCgsLDAEGDQGIkw4PBQkJBYwQnRESEREIoRMUE6IVChYGERcYGaoRGhsbHBQdHgu2HyAhGSK6qxsjJCUmJwARKCkpKsjKqislLNIRLS4vLykw2MkRMRAGhDIJMzTiLzDXETUQ0gAGCgU2HjM35N3AkYMdAB0EbCjcwcPCDBguevjIR0jHDwgWLACBECRIBB8GJekQMiRIjhxEIlBMFOBADR9FIhiJ5OnAEQB+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailforward16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRydHxubHxmZGxiXHRmZFxOTFxGPFxKTPwCBLymlMy+pOze3PTq3PTu5Pzy7LSmnOTaxOzm5LyqlNzOtPz69Pz27MzCtLyqrPT27IRubPzuzNTGvNTCxLSelPz25Bw+ZFxKPPzy1Pz65LyupBxKdCxWfPTm1Pz23LyinBxGbGzO5DRafBxWfBxajCymxHTS5BxSdBxKbFTK3EzG1CSGvCyKvCSSxCSavGTO5GRaVPzqzFzK5EzG3BSCtAwiPGxaVPTivPzy3NzKpBxObCRefBxqlPTmzJR2bKyahAwyRPzmvOTOpKyObNS+nPz21AQOFKyOfPzuxAQCBGRORLSadPzyzLymjMy2lOzetDwuJFRCPEw6NEQ6LEQyLEQ6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAAAQABAAAAfhgAABAgIDBAQFBgcIBwmOCQIKCwwNDg8OEBESjY8CDBMUFRYVFxgZDJyOGhsPChwVHR4fFSAhjwkaIiMOJBQQDRUVJSa3GicoHw4pEA8SGSorLI8tLtQu19gqLzDECTEyMzQ14zY1Njc3ODkqCTo7MjIxNCs5PD03PjctPwlAQUIihhBpQbCIihtG+CUocASFkAhIkogQ8kFJwkcFlogIkoRJEydPnkBR6GiAxiQLgiiIIkXElFQJqESoMsRKkAhXqkhhApNKFSxZggTJ4nHIEJhaDhzYwoVLFy1avHyB6ScQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailget16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAxKdBRSfCyGvFSm1BxKfCSWzCyWzBRCXCRKfBwuRAQGDDw6PHy23Cym1CSSxByCxBxunBQSFKyurMTCxExihNza3NTW1JSSlMzKzFxaXLS2tNze3KSipCQmJGxmbNTS1KSepLy2vISGhJSWlHx+fERGRPz6/IyKjDw+POzq7JyenMzOzKSmpCwuLDQyNIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQIBwGBAIAsOkUjAgFJRQQMHgjC4PBIEVgAh4D4aEYrGAMhINxwPyiCgYSsmEUmk82grLRZJkYCgXaAEKFxYZcEISGhsZFxwFeY0WHR5CDB8dGCAXG5shGxQicBIMpSMUGxgTGSQlpQwSJicnEwwdI7gdKAwTsykpKiobr8QMKxeHDBcsGRvOzxsT0i0uL9HSHdkT2ZkoMJXF4a8AfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBGxaVOTe1Oze3OTWxOTWvNzStNzKpEQ6LOTezPz+/Pzy7Pz69Pz27Pz25Pz21PzuzPzuxEQyLLyinLSmnPz67Pz23LSafKyObDwuJMzCtLSelPzy1My6nLymjNTCxLyqnPzq1LyihKyOfOzavOzetEQ6NPTq3NzOtLymnNTGxJR2bOTOpPTivNTGvLymlKSShKyahEw+NOTe3PTm1Pzu1Pzy3FRCPPz65LSadFxGPOzm3PzqzPTmzPzmvEw6NCH5BAEAAAAALAAAAAAQABAAAAaqQIBwSCwaj8ikMhloOp/QpmAgqAoIhELBUDgcEIGEYrFgNBoLx+IBiRwkgQnFoWAwKhWLhX3BZAILGhsCDXgODhwdGB5vgAofICBlDiEiIx4kJSYBJ2UoEykqHSMrLC0nLWAnFS4UCycvMAcEMR0RLTIBMwaSahw0NTYtFwclNwEdLws4eoc2DxwQOR06ASk7PBAhIRE9Pj0tLSUY1T8I5gjn6Qgy7D8SfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailreplyall16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTFRCPFxKTFxGPPwCBLymlMy6pOTa1PTq3PTu5Pz27Dw+POzi3PTm1OTWvPz25FRSVERCRLympPzuzPTu7NTGvFxaXKSmpPzu1Pz65Hx6fHxqZPzq1Pz23HR2dBw+ZHx+fISChJSWlDQmJHRydCxWfBxGbJyenExKTHRiXPzqzPzy3CQmJDRafGTO5ExOTERKTGxWVCRSfHTS5CymxBxajBxWfPTmvPzy1CyixCSaxCySxDSaxDSWxDSSvDyaxGS21PTmzPz21AwiPBRejCSavByGtCSezEzG3FzK5FzG3GzO5FTK3CQ2bPTixBxqlCRefBxSdBxSfBx2nCQ+dHxmXPzmvLSafAwmRAwyRPzyzDw6POzavNzKpAQOFPzuxBwWTBw2ZGRORLyWdMy2lOzetPTivAQCBKyObOTOpAweNBwWVEQyLEw2LEQ2LDwuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAf4gAABAgMEBQUGBwgJCguOCwEMDQ4PEBESDA4TjY8DFAwVERYXGBkRm4+QGhsMHB0eGB8bDpyOARogEBceIRgXv8COIiMkGB4lJSYnIcwoKb/DGyoXKywtKS4pHinMLzAxJDIzNDUtNjcv6B0hLzgfMh85OjstPDw99zwd7T4/LTVAgggZQqSIECNHevSAgSSJkiVMmjh5AiWKlClAiFARUeVHFSVWmLS40gNLlh5agGzh0kWDlwZfrIDREKaCAjEqrFA5MMYLmTAxlJTxYoZMozNozqRRs4ZNmy5s3LwhA0dBnDNn5MxBoAABnTp17IitowDrmQV+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailreply16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTEw+NFxKTFxGPPwCBLymnMy6pOTa1PTm1Pzy7LymlOzi3HxqZOTWvPz69Pz25My+tLympFRGRHxuZPzu1LymjNTGvNTCxBw+ZPz23PzuzPz65PTu5NzOtCxWfBxKbPzq1DRafGTO5BxGbPzy9HTS5CymxBxajHRiXPzqzCyixCSaxCySxDSaxDSSvGS21GxWVAwmRBRejCSavByGtCSezEzG3FzK5FzG3CQ2bPzuxAwiPBxqlBxKdCRefBxWfBxSdBxSfBx2nCQ+dPzy1CRqlAwyRDQmJPTmvPTixLSafOTOpAQOFPz21BwWTBw2ZPzmvNS6nPTivAQCBAweNBwWVNzKpPzyzLyihGRORLyWdMy2lOzetKyObEQyLEw6NEw2LDwuJEQ2LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAfqgAABAgMEBQUGBwgJCguOCwEMDQ4PEJYRDhKNjxMPDBQVFhAXGBUSGY8LGhsQHB0VHh8gFQ6bjgEhIiMMJCUmFbS2CwMnG6IoKSorI7WpEycWFiUsLSou1yXXji8wFiopMTIzNDUz4zbZNxsbODk6Ozw9Pj8pPzEzQDdB60JDOkRFjBw5giRJDCWdlmxwIIRJExAWKDRyMgTIiydLoESRImQKlSUSF1SxUoXAlSBRsGSJoCVICIlbqlThcoBClC5eYFD4EiVIFwUyqywAE0ZMlqNjpJDpIkUBl0dlFChAYOZMmTJoyqQR5icQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailsend16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTFRCPFxKTFxGPPwCBHxqZLyqlMy6pOze3PTq3PTu5Pz27Pzy7LyinOTaxOzi3Ozq3LymlOTOtPz69Pzy5My+tLympPzqzNTGvLSelPzy3BxGbBQ6VPzuzPz65LyupNzOtPz+/GzO5BRejPzq1Pz23LymjHTS5CyixCSavBxqlPz25LymnGTO5CymxCSaxByGtHRiXPzy1CySxCSezGxWVPzuxKyOhMy6nDSaxEzG3PTivNzKpKyOfPzu1FzK5PTmzJR2ZLyihLSWfKyObOzmzPzmvDyaxOzavLSafGRORMy2lOzetDwuJEw6NEw2LEQyLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAfUgAABAgMEBQUGBwgJCguOCwwNDg8QERITFBUWjY8DFxgZGhsaHB0aD5yODB4TGB+kICEaIiOPCwEkJRcmJyYPKCIpKrWqKywTmC0SIi4vMDHEDCsyMg8zEyI0NTY3z7U4Hhs5Mx+0IyI6OyPrIzw9Gys+PxIy2EBBxAs8Qjk5Q0RFWFxAZySfgSMsilRAkiRECHQ08hHgJ0TJkCU/mECU2ISEkowUlpAQ4QTfowNPoAzJIeRJCyjm8kVRIkWIzSkXhwxJtYAKgp9VrFi5QoWKFZ5+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1downarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PUZi0zmTtypflV0VdRJbm6fgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnav1leftarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAP///wAAACH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxqdwoNGTmgvy9px/IEWBWRkKZ2oWrKu4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1rightarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxCtwoNHTmpvy3rxnnwQh1mUI52o6rCu6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1uparrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PWwhxzmetzFpxnnxfRJbmufgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnav2downarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+pq+EPXYpxUckoO3AjbF3dJwahllXe6AFgC8d+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2leftarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pyxf5VohmSlsxmpjTzAHeN5ak6UHpqKRi2GpwvH3Q3eT64RcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav2rightarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pq5HOAjQyVnqfhHue7oAaKH5kiW0AmnLqaHomkj02g+e6XwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav2uparrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIghI+pyxfR0HsRzNnuXVqn3mVQZWFRyIDjp65Ga5Ly4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavback16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRSdBRObCQ2TBxObISevAQCBNzu/BRGZPz6/FzC3Pz+/HTS5ByyzJze7Mzq9ITC3AQWLAyWvBSavFyuxAwaLAwSHBRafBSOrDzW5AyixCS61ETW3CzG1AQeLAweLAxefBSStEze7CSWtCyatBSCnBRWfAwmPBRWdByixAQSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZiQIBwSCwah4HjUTBQFgkFg3MoKBykU0QhoUAIAuAksbpgNByPxQMSGVsVDYlkIqdUiJYLJqORbDgcHRseRR8gISIaEyMkGCVYRBEmeyAnlgaQkSgpmU4RAZ1OKqFOpFNGfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavdown16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObCRKZBxCXAwyTKTK3Ozy/NTm9GSivAQWHNzu/FzC3IzO5CySrAQOHAyuzETS3CSWtAyOtETa5Aw2VLze7ByWtBy61BSavAxWdBRCXAwqPAQCBDR+nKTe7FS+1Eze7ByixBRmjPz+/AyexAyixAQKFBRqjAQGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZeQIBwSCwaj0hAYCkYEJLKguGASEADigWj4bgaHpBINykwSCYRa5HCFFQsF0xGo9lwhpSOwfORYC4gISJ3RAQdIyQYJSAlImNrh4uNJkl5CoKUUBQnjlB4KJ6hokN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnavforward16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAwyTBRObAw2VDR+nCRKZOzy/KTe7Pz+/KTK3Nzu/Lze7FS+1AyexAyuzBSavAyOtBSmzOTy/BRqjNTm9IzO5ETS3ETa5By61AyixByixBRmjAQGDBxCXGSivCySrCSWtBTC3AQOHAQWHAxWdEze7AQKFBRCXAwqPAQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZjQIBwSCwahYGjUjBQGgWEpHNYMBCaT4G2UDggos+EwmBYMBpf6VBgYDgeEMgjIpmoAQVKxXLBPDIXGhscRB0eHyAgDSGBGyJFASMiIiMkJYImUwAnmJqbjp4AKCmhAKSlTn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnavhome16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBDw6PBQWFCQiJAQCBFxeXMTCxJyanDwyLDQqLFRSVLSytJSSlISChCQmJERGRFRWVGxubKSmpJyenGRmZLy+vOzq7OTi5Ly6vGRiZPTy9Pz6/OTm5ExOTPT29BwaHNza3NS6tJRqRGQqBNy6pIyKjDwGBPTe1JSWlDQyNOTGrNRiBGwmBIRaLNymdLxWBHxGFNySXCwqLKyqrNR6LKxGBNTS1NTW1Jw+BEweDDQ2NAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaoQIBwCAgIiEjAgAAoGA6I5DBBUBgWjIZDqnwYGgVIoTGQQgyRiGRCgZCR1nTFcsFkHm9hBp2paDYbHAsZHW9eERkYGh4eGx4ag3gfSgMTIBshIiMkGyAlCCZTEpciJyQjGxcoKUQBEhcbIiorLB4XEltDrhcaLS4vtbcJra8bMDHAGrcyrTMXHjA0NSypEsO6EzY3IzU4OdoTzK0BCAkDMgkIOjJlAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnavup16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObAwSHBRSdISevBRWfAweLNzu/BSOrAQWLPz6/FzC3DzW5BxObHTS5ByyzAyixEze7BSStBRWdAyWvByixAQSHCQ2TAQCBBRGZJze7CS61BSavAxefMzq9ETW3CSWtAwmPPz+/CzG1ITC3FyuxBSCnAQeLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZfQIBwSCwaj8hhQJAkDggFQxMQIBwQhUSyqlgwsFpjg6BwPCARySSstC4eFAqEURlYhoMLBpPRUDYcHXt7RgUeFB8gIU0BIoiKjAcUIwiLSQUkJRsmGIwJJwmEU6OkfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplayeject16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+py+0R3IFQUtruXVqn3kkWyIARR4rqKvoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplayend16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+py8Eb3ENRggrxjRnrVIWcIoYd91FaenysMU6wTNeLXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplaypause16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+py+1vgoxzyUCxrZd18ClfmIyVyJ1lqkHuC0N+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplaystart16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pyxudwlNyguqkqRZh3h0gl43hpoElqlHt9UKw7NG27BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplaystop16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+1vgpySUWpvXXqrHmSaeJEYhKYq6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextblock16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py40Bo5SOzRvrwlgrfnkJOIkPaaaJXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextbold16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIihI+py70BowPQ1HZpwNv212Vg9IGHmIjoWa4ey5DSRNd+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextbottom16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIVhI+py+0Po5y0hYtzrkB7zH0fN/kFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextcenter16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsnRkqtDnhu1zHfFSpjaY4PavgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextitalic16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+0BgztwUmmjBXX3jE0auHHhM5Yq4xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextleft16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsgRoqr3Vnt102fFSJjUC6nlPoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextmiddle16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIXhI+py+0PT5i01pisphjt3UmfFZYm5hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextmove16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsg2kfZvblXbwTg10WlA4rjyvgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextright16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+pm+EPIZstSrqsDhhv1ylfFE5jiYwX6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextsortdec16:text text16 16:photo:16 16:R0lGODlhEAAQAIIAAAT+BPwCBAQCBAQC/FxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM5CBDM+uKp8KiMsmaAs82dtnGeCHnNp4TjNQ4jq8CbDNOroIe3ROyEx2A4vOgkOBzgFxQ6Xa0owJ8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextsortinc16:text text16 16:photo:16 16:R0lGODlhEAAQAIIAAAT+BAQC/AQCBPwCBFxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM4CAqxLm61CGBs81FMrQxgpnhKJlaXFJHUGg0w7DrDUmvtPQo8qyuEHoHW6hEVv+DQFvuhWtCFPwEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIlhI8Jwe2/AmpTynqPTXSqrnBM+I0kdmpmGmUp+K4nPMvhYx9+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntexttop16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIWhI9pwe2uYnq0yQtqxbz7D4biSIZ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextunder16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pu+FxXoOIKpds1oBH7hlYxYxRCaIZ01lhJbHy9tTv7BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewchoose16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMzCLrcGlAs6UAYgwLdLtEcI4ygQo7VVp2oupGpG4vmaUVTemX523qlFcw0a4RqNlkx5k8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewdetailed16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMmCLrc/i1IAVkYg1Z1iRYUKCqitp1oikqBWV3ZOnhkWNagqu+qnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewicon16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCLrcG1AwGOQbw6qANeCEB3pCSZpO6pgowJZqLKuUGE0dnuEhf8IL1kz1shSHDX8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmag-16:view view16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ+QIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6eUAFCusJSzr7Kmpl0CtLGLvbW2Zn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmag16:view view16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ8QIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6eUAFCusJSzr7GLArS5Q7O1tmZ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmag+16:view view16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6cAsLECrqeys7WxpqZdtK9Ct8C0fsHAZn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmulticolumn16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCLrc/ixI0WSgKoyBl+beQFACpo1AqXbKCr1wLAMWS08hGG3dSZqin4sxnBmPD38CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewtext16:view view16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIchI+py40BTQSwuovp3DXkv1ia1IHmIXLiyWJ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewtree16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBDQyNPz+/PzerAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAMuCLHcri4yGISlj4kxcANgNRBQCIbL6U1Su7bB62rXvGydG25kqpwfIGxILBr9CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactattach22:act act22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBMTCxPz+/DQyNKSipAQCBISChFxaXDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARrEMgJgqA4zzus/gLhFd5HCcZAXqsphYPUdhcYFNRcZnvdtpnDqPTbUWgAJKBYwzBlw+bRo3xmkNWoBgm0OrVLn3GC9RgCk8DhUw7c0rHPr4CDu5SYQNyEt7uSY3p/UAKFhYKDSQOLiwgFdhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactbookmark22:act act22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBCQmJCwqLMTGxAQCBBwaHMTCxLSytERGRFRWVLy+vKyqrKSmpHR2dJSSlJyanISGhGxubIyOjKyurGxqbFxeXGRmZHx+fKSipLy6vGRiZLS2tFRSVHRydJSWlHx6fCH5BAEAAAAALAAAAAAWABYAAAWWICCOZGmewamaQrq+wUC8azHINGocOI38iIRAceDNaISFYklkGHOEhoNBfUAOhuOLEJE8HoPiRKFdESiQBqViuTDIUAsEcyAeGJmyiqC5RCwJGg0YcEh9D0V3Dxt6JwQVDRYVHBUdi40mjw0PTgwQHgeYJQQJfxUXFxAOoTkFpQ0fsRSimQkWEQ0VtI62HLt7vjl7JQYhACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactbookmarknew22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCwqLCQiJCQmJMTGxAQCBLy+vLSytERGRFRWVKyurKyqrLS2tKSmpHR2dJSWlKSipISGhGxubIyOjGxqbIyKjFxaXGRmZHx+fPz+NGRiZPz+ZPz+HMTCBKSiHPz+jFxeXPz+XPz+tPz+zPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAamQIBwSCwaj4Gj0hgQLJ+AAaEAVQoI06pRYDhkoYgwIhEgKBTfZ2FhaBsYDS8VWnA8Go0FJIKeqyUTDw8EDHBpSwUUFQ4UFhcYDQYFfkoFFxEQDG8KEAUZlEeWGBIakw4FG1STiBoYBRwdBR4fHgUdHKBEBSCnIR8iIyIfIblFu6ceIyQjtcXGCbLKzAUKzrq+wMLEVa+xs7W31kOTk6nkWuOf6Ea5QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactexit22:act act22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBHR2dDQyNCH5BAEAAAAALAAAAAAWABYAAAJOhI+py90RnIMyRUOxhDfzJkACdoXBuEDDkQFDi5go0MrKx16kns80b7qdELCgBYaEGWwL5nG1ePFiKp9A6kuYRNuho8vxVrrZivmMRtMLACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nacthelp22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBCQuNBwiJAwiLAwaJAwSHAwSFIy+3ERynCw2PCQuPAwmPCxOZCxWdJzG3FSazBwmNAQKDAQGBDRmhBQyTDxujDR2rIy21AwWJDyGxCxmjAwmNDRihAQOFDxmhCxunBQWFAwaLCRahDR6rESGvDQ2PCRWdDRunDSGvCRSdAwWHCwuLDSOzHSmxDyKxBxCZBwqNHSu1DyOzAQSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAahQIBwCAgIBAPCoGAgOoeBAyKhWCwYDUf0CX1AIhLiJEGpBLiAAaRxdgYsl7Ybk8igBZoN5xmAdDxoanp8HyANISF8EBsiXBMjJBolBEQmGHFoRScbKHIKDykqK5lFAZRCnyknTaROLA8tq61OChgtKqyzQgEYEJi6UC4vI3LAASkbMBPARAEBdszR0sACEaPSMTIQM8W6KzNl3bo0NOJDdEEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactlock22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBHRudFxaXExGTERCRAwGDGxubPz+/Pz2/Ozm7Nza3NTS1KympFRSVHR2dNTO1JSSlKyqrKSipDQyNMTGxDw+PLSutKymrMTCxAQCBHRqLBQODJyanDQuFFxSJFRSJFRGJERCHExCHISChHxyLEQ6HGRaJExKHLSmbLy2fOzitPz23KSiZHxuNHxyNJSOTNTOnMTCjLSudKSaXJSKRJyOTOTetNzWpHxuPOTi5MzKzLS2tFxWXOzq7Ly6vOTe5Ix+RLSqdNzSpLyydKyqbKyiZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBAgMEBQKEjI0GBwgJCgsMDY2XjwkOAgQBDxCLl4QNCaGCBBGWooINCAqqrBKgqwATFKaDFRYVtBMXsIMNGBm0GRADjQIJxKIaGxwdHh8gISIhGyMZzIwkGholJiYfJiAfJyEZISDbg90oKCkqKwcHKyooLC0f7IIuLzD2YMSQgW8GDRri+AFoUMOGvRsxUhSsQQPHvmQSchyQtEAHhh0WJHDQcJERjwsKDvRI0BGDjwgicXhQyCOjSgUKPO6AObIkIQESfmxk6REDT4s0bfaYpDNkT4VAha5s+TLmzEYtatwIOHAiDZIKNQAJYk9IjCFEisyoocFEB4UACtBpm0t3LiF4gQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactredo22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCReDJzGjMzivOTu3Pz+/JTWbHy+VHTCTMTivPT69BxGDESuJDyiHESiHEymJIzKZAQCBFS2LFzKNGzWPDRqHCxqDFSqLHy2XESCHAwaBAQOBBQqBDyWJHyqZDyKFGSiVESeJBQ6BAwSBGTGPFyWPFSSLEyOLESGJBQiDAwiBBQmDCRGFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaoQIBwSCwaj8hkMcBkKpcBwYAwEDif0YLhwEUkFItFMkAwMBoOR+PxgHwjRDggamhIJpQ8ZbKGKOQLcgEFdhUWEYgRF3sNfhELBHALAhgZFhobRBwREhQdEAIEHpIKHwsaSJwUDQgQIJINARxKESESDQ0dgCIjSpAkDAwPco+ZSJAlJicnKHIAIrNHidOIQxunT0kpCyrZSCss0d5Fj6jjRonn6uvs2QZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactreload22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBCRSFCRSHBw+DBxCFCQ6FBwyDBQWBBxGFCxyLGTChMzqzLzmvHzKjDyOTER+RERyNDSqXNzy3LzivFS+fCyCPBQmBCQiBBxKFBQqDOTy3LTitES2dDR+PCxuJOT25KTarCx+PESSTCxKHDSeVCyKRNT21ESWVDSGPBQyDAQCBBQSFDRuLDSyZDySTGzChCRiJKSmpExKTDS2ZGzGhLy+vGxqbISChDSKRMzKzGxubDQ2NIyOjCQiJCwqLBQWFCwuLKSipERCRERGRHR2dAwKDDw6PFRWVIyKjCQmJFRSVBwaHKyurAQGBExOTBweHFxeXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf9gACCg4IBAgMEBQYHhI2ECAkKCwwNDg8QBAOOhAQREhMUFQgWBxcHGBmbggkaGxwPB4yDB6SbBJIKHQaqtY0eHyAhsqrDgx4aCiKpqoQHAyMjJBMKJaSxzAAHIRsmJgonKA0LHSmDKiuOBywRLSQuLyEwwyoxMuiN6iUzNBXy5jU2bsgoJugABBz95uXQsUMGD3vpPPgTpKIGwx4+HMr4kW4YkCA2hAzxAQSIECI+imBTwVIFESNHerRUgc0cEiFHkjiiyYzeDiVLdvLcySSkkKGEWiZVweSGkIHMmvQosoQlkaZOjvhosvKJjIAxoOAsgpRZkQNLnvSoqspAIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactrun22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAwKDAwKBCQiHNze3AQCBBwWFDw6NPTy9PTy/Dw2NKyytOTi3LS2tMTKzMzOxLy+tLy+vBQODNze5NTS1JyalIyCbIx6VIRyVISGfJyelOTq7EQ+NMTGxKyurGxeRLyKPOSmROSuVOy2XOSiTLzCzNTOzDw+NCwqLHxuVOy6bPzGfOSuXNTW1LSyrMSWRNymTOSmTKSCTPTGjPzSnPzWnMyaVBQSDMTCxPz+/KyahNSeRHxeLJRyTPzmtPzarOy6fJyajNza1Ly6vLyulFRCJPzirPTOlMS2pNTSzMTCvJyenBQWFNzKtPz6vPzyvPzqtOzGlOTe1AwGBFxWTLy6tPTm1PzSpPzutPz2xPTSnOTSxOy2dPzapPzerOzm5IR+dPzu5Pzu1PzqxPzy5Pz+9GRiXGxuZKympHR2bOTm5Pz6/MzSzBwaFJSSjCQmHPz2/AwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeEAQKIjIIDBAQDjYMFBoMHCAkKgwYFhwULDAUKCg0ODxCkBQgRnoUSExMUDxUWFxgZGpAbFIuGHB0eHyAhIiMkIB8lJieIKCUpJCTGIyorLCktKIUDpC4YLzAxIjIyMzQ1NhgdpJI3ODktJTowOyM8Ejc9Pj9AQUIEclAocCMIBQhDiOwgoaKIoCI+jBxBkkSJkCWemIyq0GSHCBVHihRx8gRKFCmpKhGaQqWKFYZXsGR5kkXLFgRUXBUqkCGCFS5AjnTx0sXKlyA6CRVgAAHMAilhxIwhU6ZFkBY5kgKYUoXBAzMKzixZ4AJNGgVm1KxhM0WpmQpUMtooaOPGxAM3Nw60oYLGjNYCbzYJOgAnRzNBJ95oPYQCgpJtkwzFoULlRuRPiy9fNhAIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactstop22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAASC/CQKDBwKDCwODNyKjPzq7My+vIxiXAQCBOSOjPz6/OSelNySjNyGhMR+fLRaTGQ2LPz+/Nx+dNR2bNRybMxuZMxeXMxiZLQSFJQaHFwqJNyKhOSCfNyCfNR6dMxmXMxWVMRORLQODOR+fOSSjNR2dMQ2LJQWFMRWTLwWDNSCfMxeVLwaFKQODNR+fNx+fMxiXKQSDOSWlMRSTMxaVMQ6NMxORMQyJOTS1MxqXLwWFLRORMxKPMQaHMxKTLQWFCH5BAEAAAAALAAAAAAWABYAAAb2QIBwSCwajwGBcikIHIsDQmFKNRwQT2EgoVgsGOCG4wHBIgmRhWRCqVQsF0xGYyYGNgoGh9PpeCQfICEic3UAAWgLIxwRJBsbHSUREyYYJ3RDAQULexGejhueESgpl3WaCxsqJKKsChEUKywtmFoFDC4vCayikzCyMbWHt38NCTKiHhUfMyzBdQIFKsodob0VNDWzwppuKxMRrx6iNjcitNA4bh+iEzkwojc66JkOOxcf7G35PBE9KS1MEUGgIQOIFfk++KjRw9wJgUUIZvhRoyLDFCliQDQisUWLGCJOeNx4hKCGkyhPGnqCoKVLl1liypyZxUAQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactundo22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCReDJzGjMzivOTu3PT69MTivHy+VJTWbIzKZEymJESmFESiHDyiHESqLAQCBFzKNGzWPFS2LNTmzCxqDDRqHPz+/KTGnBQqBAQOBAwaBESCHHy2XBxGDOzy7HTCTEyyJDSqFHzWTAwSBBQ6BIy+dESKJFySPFSSNAwiBCRGFBQmDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAalQIBwSCwaj8ikMsBkKotMwYAwEDiXgYLhwD0gCFZiQKxNKBYMRqPh+D6G16y5AYnYIxBJAyF4AwITTAUJdBESD4gPFBV6Fn6ABBcJDIYPGEQZGhQbHAIdfx4JHw2VSBodGwWfAR4LDSALfkgYAQurBiAhICKfSSMkvQElGyYnGyi9Rxkdj4nOskUYyU9FpxnURikdGtjRKivdRKfQ2Inh5+jpRwZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactunlock22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBGxqbFxaXExOTEQ+RAQCBPz+/PTy9Ozq7Nza3NTS1KSipFRSVOTi5Hx2fJSSlKyqrJyenJyWnDw6PMzKzKyurDQyNFxWXMTCxJyanHRuLHxuLGReJFxSLFROJFxWJExCHERCHBQODISChHxyLHRqNIRyNHRmLLSqbKyiZLy6fOTarPz67Pzy3OzitKymZFxSJJySTNTSnPTy3NzSpMTChLSydKyqbKSaXJySVIyGRGReLPz23NTOnMzCjHxuPLy2vKSmpOTe5LS2tLSutHxuNHRuPMS+xFxWLIR+RDw2HFRKJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SDAQIDBAUChY2EAQYHCAkKCwyOjZANDgIEAQoPjJiDAg2iggQQp5gMBwmrDBESl6MTFKuoFQSjABYRF40CGAW8BRm7hQwNxBobHB0eHx4gISIjBdiEAhYFJBslHOHSHh4hBSHlxIUmJygpKissBiwtLi8pGjDqhBoxMjMuaNSwcSMFjhw6dnjYRyrGCh4ueviw4Q5HDB0/PjAUJCBCAwMIGiiggAEIBFk/FgYLIgRkggQkhxAJkqGExkYMFnxsIGRkSQgLHhRRWUjAggQgG8AsSWRBBiP6VrYMOfKIyaBDNwLo+HHSUplOSyDRqiEHjRkretRQkcLgxayNF0wksQGQxsSKMTIq0QpgCba/gAE7IhMIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappbook22:app app22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBDyGhCyCfFSWlESOjDyKjDSGhCx+fGSinGSenFyanEySjHSqpHSqrGympEySlBx2dISytHyyrCR6dKTGxHyurHSurHyytGSipCR6fARmZFSalEyWlBRubAxubBRydDyKhDSChLSytPz+/MzKzIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbFQIBwSCwaj8ikMhBQIpmCQdM5ZBIKhgNiugwkFAsCI7pNMhuOxkNBgBgEiAi3GkBLJpJHYgEpaClyREwVFhcSEhgOGQoMfgMaERtcARQBFRMYExZ6HB0FUYAekkIBHxqWFmlrC1haESAfG6MBGx+VFRgKYH0hInGRklO0ppYXCwwMWQiQHkwjgrWnFRdYZHIBJCTP0LaWGAcDW9jZ2nMAw9IWTOQkJSZMRsOV49nu8E+19PbmR7TY+1TovONH5V7Ag0QMBAEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappbookopen22:app app22 22:photo:22 22:R0lGODlhFgAWAIYAAAQCBAQ2NPwCBHSurIS2tBx2dBweHPz+/Ozm1GxiTGyqpPz6/Pz69GSqpOzaxPzy5HxuVLSmlOTazPz27PT29NzClPTexHxuXLSmjAxqbFSinPTy9KyehNy+lPTy5Pz29HxyXNzWxKSahOzexPzy7IR2ZOTWtESenPTy7KSWfIyCbKyijAQGBDyalPTu3KSSdDSOjJyOdCSGhPzu3OzizJSGdPTq1PTq3JySdMy6lAyKhOzWtOzi1OTOrJyKbMS2nJySfMS+rAwCBNzOrNTCpNzKpJSGZKyafLSifLyylIx+ZHx6ZDSChAQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAWABYAAAf/gAABAoSFhoeHAAMAiI2IAAQFjI6EAAaJkQeTjwAICYkKBQcLm5WdBwyfhgChB66bp64HCQC1lQ2irqQCAA4PowsLEBESE4wAuLIHFAAVFr+uDBcYxRm1GrmuGxwdFh4Mrh8gGCET1gDYyhsiFSMkDAsMDCUYJhvnJ9kHKCnODwwfPlBQsULCPRYAWogK9sHFiwoOPEyQh0JFPXO1YBSYwBEFghjdHkwQOYGgwQwIZRR44GHGDBogabhAsYEEihrUMAIoUMCEDRs3HODIYQHFA6MPcJA7KICFjgw7eIzo4cOfiwc/gKwIUm2SkKdDdlDt4AABDaU/iIRwwbTSUyJFOow4S3Hkx9oNDDZgXPU0h1wcSIgEGUw4ibVET5WoWMKksePHpdxmyKADAEIWly9HJtQkQJMmlAgZCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\napppencil22:app app22 22:photo:22 22:R0lGODlhFgAWAIMAAASC/IQCBPwCBPyChMQCBPzCxAQCBPz+/MzKzISChKyqrDQyNEQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARYEMhJ6wxiEMtpIAWxddwXiqRlikSQeiAbuC+wirNR322gv7zcLobzDU+9XypoBBKTR1lz+RTWDgip8nUwZK1XLyIx5XoVicX2RUAo1DVKi7GOBxjxfNwQAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\napptool22:app app22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBISChFxaXNze3NTS1Ly6vKSipNTO1Ly2vNza3Pz+/MzOzOTe5DQyNOzu7MTCxGRmZMTGxPTy9Ozm7Hx6fPTu9MzGzGxmbAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAW1ICCOZGmeaEoGbBsI6joMRGEcbQwESDIrtVtAF1gwDLNaAmfKiVgLBJKgwB1KxQZrBHU0FAXmavFoQLYiB6TxFXMj5AZBwnJI2I3wcNWALyYEcgoKXxRhOHs7XxEVCwsWFgoUDRYUFwwQB25ZCxiNjo6GkwUXN2NsCxEYqhUHoQ0MEglYRQQXErcHrI55FycuB2YSmoyOBTEtB2sXuhU6XAENC2a6z9AKCwq+1tAN3E2J3ySkIQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnecting22:connect connect22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBPz+BMTCBISCBAQCBPz+/MTCxOTi5AQGBNze3Ly6vISChNza3FxaXKSipAAAACH5BAEAAAAALAAAAAAWABYAAAR4EMhJqwzY6omD+MNGdR8YilNZnug0qGzrqrL1lnV1fyJBVB6VQEMoGH4ADGwQkxQPBwMiKGA2J8VEAnq0tgiKg5aL/C7C2gTjKCM0zowDQ8tuNQznNL7cKzjOUQsNfER+gguIg19+Pm6ChBZFDmWNi5M5FIyYFHQRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnectno22:connect connect22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBPz+BMTCBERCBAQCBPz+/MTCxOTi5Nze3OTm5Ly6vNza3ISChFxaXKSipAAAACH5BAEAAAAALAAAAAAWABYAAARiEMhJq7046827/+AVCKE0Dh9BAGdaGISAToFGFMcBU+11I4hDYseSZQiKwwKoI/QwBIYiuFDCZseGdIlYEjUNg1SpY6w2N4cUIW6cjwW1lsFwo+MqgtZuw0/ydw5vH34lBhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nconnectyes22:connect connect22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBKyirPz+/KymrOTi5KSipMzCzNza3OTe5Ozi7MzGzPTq9OTm5ISChMS+xFxaXNze3GReZIyCjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWLICCOZGmeaBkAQpoGg7C6JizTQT7CxPwOwFWgYPChYIXkIHC4uQKGAiKRKCyNpxxUUVViVYNFLkqtLo+DAkMMLXQPXwAy2WCTF4544FGtKuwPDhB6DnxuUmyCcXIQhV1uYoMuEAcOBxEKCHg6TzGFCJUSizuejROKOAM9OY2SnUU7nD89NCcDsLUnIQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevscreen22:dev dev22 22:photo:22 22:R0lGODlhFgAWAIcAAPwCBAQCBPTy9PTu9Ozq7OTi5Nze3OTe5Nza3NzW3NTS1MzOzMzKzMzGzMTCxMTGxOzm7AwGDBQOFBQSFCQeHCwmLCwuLDQyNDw6PERCRFROVEQ+RDQ2NLy+vKSipISChGxqbExKTOzu7OTm5Pz+/GRiZMS+xLy6vBQWFLy2vCwiHFQ+NMSmfNSyhIxmTDwuLJx+bLS2tCwmHMyyhMyqfPTqpPzyvLSWbLSWfPzitIx+ZDw2PAwKDCQiJGxWRPTmrPTerMyuhPzqtPz63PTWnPz6zNy+nIRiVDQuLKyWbOTanPz21NS2jNS6lDQqJHRaTPzmrPTSnPzyxOTClPz2xNSuhPTqxPzuvOzSpAQGDOTKnMy2jOzSrPTu1NzKnOzOnBwWHJRuXLSWdPTatPzqvNzClCwmJOzSnOTOnPTuxOzKlOzerOzarOzitJR6ZNTO1IxmXPTWrNSyjPzOjPTSpLSehHRqZOzirOTCjPS+fPzGhOy6bOzKhGROPMy2lPz+1PzmtKRyRHRiNNTCdPz+zNzCjEQ2NKySdDQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAj/AAEIHEiwoMGBARIqXMhQIUIBAwYQIFCggIEDCBIoULBgAYMGDgIIDEBAwMSKBRBk3NjxAciQIwdACBBBwgQKFSxcwJBBwwYMHBx0EAmA5EwPH0CEsCChoYgOQ0cSGCHhA4kSS5syJGDiBNEAFVGUKKEBAwWFFM6SNJHi64gDFEKE4FBBggoKK1i0cPECxokYXw0gsECYggQZM2jAqGHjBo4cOtqOxLhDAg8ePXz8ABJEyBAWRIoYOfJipEoMCZEkuaFkSAslS5jUGJKkSRAnRREo0JDwCZQoTKQAmUKlihQrVa5gKZ1lI+oAK7QM2cJlSZMuU4Z4+TJEx0iNOwKAggkjZkyOFmS8kClzpcUQLRRGbjRD4MgZNEzSqKG+ZgobI2248dUbDDDwABzcxSEHEFpgEcUcdMRRhx1fFejAAx0cgcYdSxiBRx566LEHH0d8QFRRNC3Uhx985CHEH0MAEkhCBxWkgiCDFEFIEYUYUmONMhyCRxVH/PgjBYioYJAdAQEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditcopy22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFPz+/DQyNISChDw6PMzKzMTGxERGRIyKjFxaXMTCvKSmpHR2dPz6/Pz29PTq3MS2rPz69MTCxFxWVHx6dJyWjNzSzPz27Pzy7Pzu5PTm3NTKvIR+fJyGfHxuZHxqXNTCtPTq5PTi1PTezNS+rExOTFRORMyylPTaxOzWxOzSvNze3NTOxMy2nMyulMyqjAQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbYQIBwSCwahYGkUnk0BgTQ6IAQaBKfUWhBYKhaAU+CgXAQIAyChLeJzSIQhcH6GFaM0QtGY5kstqEODw8QEQELAhJTc08KBBMEFBUWDRcBE1pca20SGBkaEBscAY5maFRIAgoLHRQRHh8gIQFlZnByqA8ZGSIQIyQjJQEmYgJ5p2ACrK4gJx4gKIZZAgdeAQ4ZI9kjKSor0AwEjeAs1S0cHAslLi4vMDDRWeRIfEsxMeET4ATyVoYLC5fizXEiAR84BeMG+pEm8EsAFhAjSlR4hR6fLxiF0AkCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neditcut22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBAwCBPz+/OTi5JyanOzq7DQyNGxqbAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARbEMhJq704gxBE0Bf3cZo4kRJqBQNRfBucyudgvJS6VaxLzyMa6/bLiWA9HOg4VIIkL5vzuRkcpkvRIIAorphJLzBW84WEuRZWp6uaT7J2Sh1Hit3OY/ZO7WvsEQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditdelete22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIYAAASC/FRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwKDAQCBExOTNze3NTW1MTGxLS2tJyanPz+/Ozu7BQSFCwqLDw+POTi5PTu7MzKxIR+fCQmJPz6/Oze1NTGvPz69Pzy7Pz29LyyrPy+vPyupPTm1BQWFIQCBPwCBMS6rPzSzNTOxPTi1NS+rPTezNzOxPTizOzWxMy2pOzaxMy2nPTaxOzOtMyynOzSvMyqjPx+fOzGpMSihPTq3OzKrOTCpNzKxNTCtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf8gACCAQIDBAUGBwgJCgsLgpCRAAwNlZYODxALEY+SkAMNEqKjEw0UD5yegqCjrRMVEqidkgWhraMWF7GptLa3EgEWFRSOnhW+vxgZEBqzkBvItxwdHryRCNGjHyAhHSLOgtgSI60c2yQjJd+eJqEnKK0hJCgnJSngAO0SF+8qEvL0VrBogW+BLX4oVKgIyMIFQU8KfDV4R+8FDBcxZBREthAFiRIsOsygsVEUh4Un3pGoUcPGjZInK65QicPlxg8oX5RwqNJGjo0hdJwQ6EIkjRM6dvDYCKIHSBc1Ztjw4eOH0oIrsgIJEqSFDBo0cuTgsdSTo7No0xYTZCcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedit22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBISGhISChHx+fHx6fHR2dGxqbGxubGRmZGRiZFxeXFxaXFRSVIxSLPyuXMzKzMzKxMTCtExOTPzqrPz+/NTS1MS+tOSaVPyWNPz6/IxeNPzavPyKBNTW1PyCBPyGBJxmNPzOpLx6PNRqBMSCRNySTPyCDPSGBMxiBKROBHRydPSylOyydMxmBJxKBAwODPS2lPTq3OyabJxGBPTy5PTGrOyOXPR+DPz69PzmzPzevNxuPORqLMReFPzy7MyCXKxiNIRKHBQWFNTOxPzixJRaPFxONHRqVPz27PTy7PzStCwqJDQyLJSGdIx6ZPz29PTu5HRmTLSKbMSGZHROPFxKPJSKfJyShKyehMyuhDQmHEQuJJyOfLSijMSynMS6pLSefDQyNHx2bKSahLyqhLymhOzi1FRGNIR+bNzKtOTOtOTKrOTKpLyedAQCBFRWVPTq5NzOvLyunLSmlNTCrOTOrNzGrLyidMS+rLyynKyijLymjLyqjAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gAAAAQECAwQFBQYHBggJCgsLDAwADQ6CAQ8QD5ydEJ+gERKWE4ICDxSpqhWqqhYNFxMYphCtqaytGRoXGxgcggSoth25u70eH8APFR0VzMzNziAXIRjIvwAFwq3EqSLUGB/iI4LathS4JCXVJh8nKCmCKrXDFCss1eIfLS4v8ssdmgWsAGNDDBnt3s3wJ+jAtlUhaNSwccNEi4WCBBl4SAHHihw6ZOzg0QNjRgAG6KXK4CNEjBU/gDQI8kLISQAIADobAoMIzCINjLw4YvNkAno4kCRRUuNHESNLmDRxUjSjAlRPfECJImUKlSpMrFzBIqWqoKtJaWSJomULAy5XXrp4+QKGYcYFoCBEWRImi5gmY7CQyVLGriAGD2jEMHMmCxc0Xb6kUbOGTRs3N988gLM4jpw5Y+iwqcOGjZ07mE8yiGABz5c8c/Ts4cOnDJkybS7fdMO7t+/fvDMaCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditpaste22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQWFDw6FHRuFGRaBFxSBAQCBAQKBCQiBIx6HPz6/NTOfKyiXDQuFOTm5Pz+/Ozu7PTq5Pz63PTyxNTOjKSeRExGLMTGxMzKzNTS1NTW1Dw2NKSmpKyqrKSipJyanNzWlLy6ZLSuVIx6FISChIyKhJSSlCQiJLS2tDw6NDQyNCQiFCQmHBQSDGRiZHRydGxubHx6dGxqbFxeXGRmZFxaXCwuLOzq7KyurHx+fDwmFEQuFCweFCQWDBQODBwaHBweHKSinJSWlOTi5JyepHR2dDw6PBQSFNze3ERGRIyKjIyOjISGhPz29Pzy7MS2rMzOzFRWVHx2dHxybDQiFPz27Pzu5PTq3PTm1NTCtJyGdHxuZHxqXPzq3PTaxNS6pFxWVFRKRNS2nPTi1PTStNSulNzOxNSynMymhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCgwABAgMEBYSLggaOjgcICQoLDA2Pj4MGDg8QEZ4FDxITFBUWFxcYGRobjQ8cHR4fCQ8gCyEiFSMWJCUkJieNEB4dKB4pKissK8wrLS4vMDHBAAYQHx8dFx0fJDIzNDU0M+IyHzaNNyg43Ng5Ojs7Ojw9Pj9AMkCNDiZB/h9CSOx4QLCgihItqBkYgqIDESElitAYWJCgkQcXjjRCgi1Ihw4BB5LAQOLCgyQYHihpUU3DBw5ElpAgAYNixSRJjKjQaECDCRPZPDB5IbIGSQwKLnh4wbInLA4kmJB4oaPiAwVNnER40hRK1BIAaVatUZJEFCkmpmjgCeWDCalFe4q4oFKwSRUrEa5gycLzwq8lUnPQ4PEgSpYcUZ5o2cIlS1O/JHLEDdfjQZMIVrpgweLFy5e+M6WSmBGlxYMYYBRzCaOFi5imHWBIfOEiShLTVjaP6eyFTBmN1TA5OvLDjJksWb58OVMGDRqWjAYdmU79SIvpjqJr104nEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditshred22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBFRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwKDAQCBExOTNze3NTW1MTGxLS2tJyanOze1Pz+/Ozu7BQSFCwqLDw+POTi5MzKxPTu7LyyrIR+fCQmJPz6/Pz69Pzy7Pz29OzaxPTu5PTq3PTm3My6pPzu5PTq5NS+rPTm1PTi1PTezOzWxPz27MyynOzSvMyulOzOtOzKrMymhOzGpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbpQIAwIBgMCAXDAZFQLBbCqJTRqFobjgdkEYFKowPJZEyeUBqVR/crHDTKZYplovZKCW84+YKZZNZSBXl6EwEEBhVPXxZihGMaGRscdkIdg4QeEnVfCH2OHyAhIhuUAAiXZSEhIyQlJqWnjiEnKCWupRWoYyEgJK0SKaUKjam0JCorLMFfC6iqx8giLa/MGAsT1wsuCyULKwssC9RSzdkfCyALKuALLQsvpeXYIQso3gsiCzALMfENC+dGcMNHUAY/f+jq3ctncMYCGggFrsvHcEGNh/EyPFmg8cmrJxAVkVO0EUDJklHoBAEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nedittrash22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBERGRExOTDQyNISChBQSFCQiJCwuLPT29Nze3GxqbDw6PGxubHR2dJyanLSytJSWlJSSlOzq7Pz6/Nza3Ly6vFRWVBQWFIyKjMTCxHx6fIyOjLS2tOTi5PTy9OTm5Hx+fNTW1KyurKSmpJyenExKTMzKzKSipFxeXCwqLMzOzKyqrMTGxLy+vHRydBwaHNTS1DQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb8QIBwSCwaj8KAMoA8LgUDQsFwQByay4RiwWg4GA9IRGk0SCYJSsUCsVwwGQ1EsmESD5xOp+L5gDwhBRIZDhcDdkMGDgEiIxAkJQ8Ok5MmAohDAQ1xJxUlKCUlEg0pKpiZJRoLCxmtCw1eURhOcR4rbQ8cGRwLAwgGtBYTDywtGRKjvQTARgEZLhMcKC0OrQMvAirMRc7CHCTU1g2+20TO0NIn1RwDCya/wdHT1Rnt5LToKOq79trx0tR02YPX7Jm8fRxMOIhSLhOJE/LCJSTlr5kFEBQsWDiR4UGGBgsuHDg1BEYAfTE6oEBR4AIBAiS5yWBAAAGBAyaPGAgCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfileclose22:file file22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBERGRERCRDw6PCwqLExOTFRWVHRydGxqbGRiZCQiJISChIyKjHx6fDQyNBwaHJSWlKSipBQWFJyanPz+/JSSlCQmJAwKDCwuLBweHBQSFGxubExKTISGhDQ2NFxeXFRSVDw+PAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbZQIBwSCwaj8jkMSAYDAgEJbFgOBwQCUOAoJAaFgvGonHIBhyP5BcSgUAYDWxggD4WFmx3e3HQngkSRgYMEBMUFG4MCId0BGlEAQeEhocVDYcUdBYKF0QCB3gRlJgUAQEYBBkaRAMbDZMMpAYcT46rQwMJrgsdC6QcfwoPnUMOBgkIV6SHHg6bw0QEAQYfBpggBZjPGsRD0gEchxwCIR6HChnQRQ8DIU4DTR4Em+ncRw8O+fmoXPXdRg+gQLFgIYM/KRIkoDP4QMKFf0o0aBAh4qGUixgzCrETBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilefind22:file file22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQSFJyanLS6vLzCxISChNTe3OTu9Oz6/Nzy9Nzy/NTy/OT2/Nzi5Mzu9Lzq9KTe7LTq9PT+/Pz+/Nz2/Mzu/Kzm9Jza5HzK1LTi9PTu9IzW5ITO3FxaXNT2/KTi7Iza7GzC1LzW3FRSVMzO1MTq7HTS3Fy6zFS2vKzm7Lze5MTGzHzS5FTG1Ey2xEyyvJze7JzW3ITa5FTK3EymrGS+zFxWXKymrMzi7ESirEyqvLSyrKze7MzOzMTCxKSepAz+/NzW3MzKzBwWHLzS3ERCRAzi3KyurNze3MzGzLy2vLSutCQiJAyytHRydOTe5MTGxLy6tLyqpKyelJSCdOze3NS+tLyupLSmnKSOhCwuLPzy9Pzu7Oze1OzazOTOvMyihOTi5PTm3Pzi1PTazPTWxOzOtNSunDQyNPzy7Pzu5OzKrNzSzNzGvNS6rMyynMymjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCgwGFhYOIiYQBAgMEAwKHiokBBQYHCAkKCwwFAZOEBQ0IDAsODxARCZ6gAAEGEhMSFBUWFxgZCJ+TjBoMEpkRERscGBGRih0BBAgeFBQOER8gISEfIruIIwEkCCUVwhcgJicoKSrZg9srCRkRGdMsLS4vMNiK2wIKMRsbMiwzXtCocSydIBs3AuCIwIFDiBMucugAoWvSiB2VNPDg0ELHwA0MkCXr4aNSggg8NoDIQOFHgBtAkgURMiDAEAFEVBCJFKCIkSMGOyDRkETJEkOFmABoUsRJQkQdnkzQACWKlBtTplBR6qopxkFRJ0ytYuWKFCxZtBBq+hRA2AlbRrh08fLlCxi1a51g+dQhDFwuYsaQKWPmDBpKXgNETaNGjJgyhNfcVdTTiWI2XpK0cePmzRk4YA5T5otGixY0qFOXbgXAQCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilenew22:file file22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBExOTERCRDw6PCwuLBwaHAwODAQCBOze1NTW1OTi5Nze3MTGxLS2tJyanPz+/Ozu7OTi3BQSFCwqLDw+PDQyNFRSVPTu7MzKxLyyrIR+fCQmJPz6/NTOxPz69Pzy7PTu5Pz29Pzu5PTq5PTm1My6pBQWFPTq3PTm3NS+rAwKDPTi1PTezOzWxMy2pPz27PTazOzSvMyynOzaxOzOtPTaxOzKrMyqjOzGpMymhPTizOTCpNzSzNTGvMymjMSihCH5BAEAAAAALAAAAAAWABYAAAboQIBwSCwaiYGAYEAgFAqGg/Q4DCASCsTiymgcHAcqQLB4mM+QiIQBppLPcMjkwQ4bB2X4maKgt4sVCHpnFhQTElNFE3mDDxcYGRp2RBuMgxwIHX9EBZZwHh8gCBmTQ52NISEiIyQlpUImng8hHyInKAgprwAqgnC0IKwrLLpGB4wctLYkwy0uuwd9Z8AnJywsLcVFx2YcL7UnJCwwLTEy0GXJoSgrCCwzNDTnxgjeH9UrKzXwNDY36LRGhEOwLx4NHDmgJbh3QoeOgv127EhojEeHDj16pEhRQoZHHzl+QJNCsqTJSXaCAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileopen22:file file22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAQCBCQWDCwaDDwmFPSubPzGhPzCfPy2dOSmZPzKlPzSnPzOlPzKjBQODPzChPzWnPy2bPSmXPyuZOyeXIRSLEQuFEwyHEQqFDQiFCweDKRuPFRSTPT29PTy9Ozq7OTi3Nze3NTW1MzOzMTGxMTCxLy6tLSytKyurDQyNMzKxOTm5OTi5Nza1NTS1MTCvLS2tLSyrKSmpJyenJSWlIyKjHx+fFxeXBwaHKxuPMzKzLy6vIyOjHx6fDw6NPy6dGxubLy+vISChCQmJNza3KyqrBQSFLR2RKSinJyanGxqZAwGBJSSlCwqLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeDAYqKiIeLj4wBjQCMhY+NkoiLk5qbhQIDoJyGBAUGBwgEo4MECQoLDA2pDrS1tKQPEAwHERITE77AvxKqhAQNDA8UFRYXFs8YBAQZGqGPxw0RGxwdHR4eHyAhIiMkJSYnKCgpBAYPEhcqHyssLS4kLzAxMjM0NTY3cBA4UCAHBw8gVnhgEcKFjhc7UPDj0cMHAAI/KFgY4YLFio/jRpTYsW8GDyCSCEQw2DChOHIqgsCQSEPIEEEEJFhAoUNECCJEyOk4d6KIyRtGcB7hIJKjixEjHu4oimSGEIs4d8IIUoKECnNB0ElMwkNJJgBLlJBAcQKGiR07KGAURVGViY0mhIwwSTKjr99+THjUoIg0r48hTRIrRtxkiOMhDgrZCQQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfileprint22:file file22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBFxaXDQyNFxSTPTizOzi1FxORDw2NExKLPTi1Pzy9Pz6/FRWVPz29Pz2/PTy7PTu9OzezPzu5OzavAQCBPzy7PTm3OzazOzKrPTu5FxSRERCRGReXPTq5Pzu7ExGTMS+xKSmpOTKpPTq3JSCDNzSfHRydLyadOzCjOzOtOzSvLyyTMTCxKSipGRiZFROLPz+/KyurJyenJyWnGxmbLSabOzClOzm7LSutJSWlJSSlJyanGxqbNze3OTm5IyGjNTO1Nza3NzW3OTe5IyKjHx6fMzGzMTGxMzOzNTW1IR+hISGhKymrLy6vLSytERGRGxubKyqrLy2vLS2tDQ2NEQ+RASKBAT+BFxeXHRudAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAgOEiYqEAgQFBgcGi5MICQoLmAQDh5OEDA2YCw4ODxARApKUCaGYEAsSCRMUnQysCwoVEhYXGLOLCBCgDqK5GQUXGooCAhscBB0euBUZEAUJvQgIgx8gIR8iCSPiHuIFEREDJCXaANwhJhsnKCnWERcRKiopFCvsBywhQrRwQWGAPAz5EhpQ9wIABRgKYsiYMTEEDQocatiwkUIEP18fbkCAAcMBjhwzdOyQwYNCgBMfKJSgMItBjxs+btwgCSGGjhw/ZoRgQKGZCRMUPgABEgSIkCE3SZok8qNqkR85NtDUEcPIkaVAkCR5SrJBDCVKlmzQ6pCCiRlMTJo4YUH3K5AeMBYYWctW0BOaUH60cBJFypQmII6wyEpFQBVFMSm4UAI3hJUrOGh8oOJrklYKWIromJGDR99Ogz5j4ZGlM+pEnwmBCwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilesave22:file file22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBGxqbAQCBLy+vERCRExKTHRydIyKjMTCxFxaXGRiZFRSVFRWVPz6/Nze3Nzm5Pz+/JyanDw+PExOTHR2dMTGxBQWFLSytHx+fISChOzy9Ly6vAQGBJSWlMzKzAwODJSSlHx6fIyOjOTi5DQ2NISGhGxubCwuLOzq7ERGRFxeXNTW1CwqLPT29Dw6PGRmZKSmpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb/QIBQGBAMj8ikUDAgFAzKKCBwQCQUCcICKh0SEAhGw5EIZAmBrgCxeDQgcDJWyz0GIggJfL+XGwQJRxNgC3yGDwwUFUZDFhdthnwMGAZNQwEZFwQakXANBBQbHIIdERIBnRAOiR4ERx8gsSEMBBmGCyEGG3YGBwcgIr8UCwQHECOgG4xCtRkEJAvBJRklJgkSFBQeJ68hJiEoESkFKiEZIbkGARsLlwEGExENGhorGSkpFAYm66NDLAECpGiBYsUIFA8wLHBBQMWLVkdUCFCwaYVFBOymkVCgYEMgOykEpICBccMBAhhELFigTEqAAgIIwCiQ4eRKDyS6EAlJIAI0EpaudF4iIKDAAn9CkRT5eMROEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfoldernew22:folder folder22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBNzaTPT2FISCBCQaDPz+BExKBDwmFPSubPzChPzCfPy2dPz6BMzOTAQCBOSmZPzKlPzSnPzOlPzKjBQODPz+rPz+3PzWnPyuZPSmXNyaXPTyhISCLIRSLEQuFEwyHPy2bKRuPFRSTPT29PTy9Ozq7Pz+xJyanDQyNPzGhMzKzOTi3Nza3OTiVBQWFDwqFKxuPOTi5JSSjISChHR2dGRmZFxeXPS2dNTSzNTS1OTm5KSipLS2tLSytKyqpIyKhGRiZNze3NTW1MTGxMTCvLy6tIyKjCQmJMTCxMzOzMzKxJyenHx6fLR2RLy6vJSSlHx+fDw6NLy+vIyOjAwGBGxqZKyurCwuLBQSFJSWlCwqLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeIiYqLjI2MAY6HAgOHBJYEhJCDBQaDmgcICQoLB4MGDA0OAQUBDg2cAAcPEBESE6QUuQasFRYVq5SxCRcSCggYGRjIGgYbFs8bHIMHExIJGR0eHx7cB83PFhsDDuTUEyAhIiMjJCQluwEmvsAnKAcp1x4qKyUrLLupWrByxcnFiwQIYIggEaNEiRgBZMyYQaNADRs2REA6cCODBxw5+OnQgWMHjx4+BND4MQOIg1gI0gUREkTHiplDhhApEoCGkRlHBL3I8MEHEhz+WAhJogTJySVMfthwIehAExE5jubAkYQpESc8fOx4AiXKNA8+ekhBgqSpzh5hPHcsmVLjpSAqVZBY6VGkiJMiPQKLnTvjCiEsWU4o3nGC8YksMmT8YCmC6iAXKLRc2cz5yGYtR0JjKWQgEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmailforward22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBJR2dLyijPTixPz69Pzq3Pzy3Pzu5PTu7Ozi1LyelOzavPz+/DwqLLyafPTmvPz67Pz29Pzy7LSWlPzmzPz6/LyajPTitOTSzMyurPz25PTatPTi3KyOjPzuxAwqVDQiJHxiZPTetKySlPzqvPz27BQ6bAwmTPTexLyinNzGxDRunPzy5KySjCQ+ZNzq9KTO7JzC3Nzq/Ozu/LzW7FSm1BR6vGSWvFyq1AyGxAxytAx6vBSKxAxSjMyujLSunES+5BSi1ByGvAQCBNzCrOTaxNTOvMS6rKyelCx6rBx6tBQKDOTWvPzu1PTq1OzezAQOHAxGdBROhAQGFPzy1NzOvIRqXLyynOzarPz21Jx2XPTWrLSShAw2XKSCbPzuzAwePAQCDPzyzPzqzPTmxOzWtAwGBKyObOTSrNzGrKyGbOzatEQyNKyCZOzWrOTGpNS2lCweHCQaHCQWFBwSFBQODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBhBwgQKFSpY0HgBQwYNGzh0mDhRAAUPHziACEGBpYgRJDiUGEkSwoCQJk6opNASRQoOFETQJDkggwoOJlYApcCihQuVL2DUhBDjhIqjJmRwwDCDhswaNm5MjYHjKggOOU7o0CGTA9gdYknG2KCCBw8VJVL0uBgihAUfP+CSNGCjsI/DiBPbAMJBsEQbQYQM+UG5smUiRYw0jlvYxhEkSYyIHm1EyRLTTH40EZvAyZPOR4pAmU07ipIkUKQ0mQIhAZUqVq5gKXzkSBYtyLVEyd1ki8QFXLp4+WJFQowbYLJnD5NbzJiJCjaQnhnvpYwZM0/OPFlvQ/f3iQvQpBlvQc0aCWy4VKnCpY0Y5yQxgEYXZFjghgwZUOHGCW90YQEccUwloBwGyjAHHXUoSAMZb0xhx1QOoMHDHSfIwSEOdTjhAQ1d4MFbTQ6Q4MYacrzxhhx04JCHHhvQsMeLJPHRBxpr+LHCGnusgccfgKixQR1ATtTBlDDAEIggggxCCCGFbLGFHVFKZEdAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailget22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQ6bCQ+ZAwePKTC5Ozu/NTi9GSWvAwSJGSu3JS+5CR+rAQOHPTy/AyKzES23AwOHCw+bOTq/BR6xES+5AwmTBw6ZMTW9Ax6tByi1BRGdAw2XAQCBDQuNDRupKzS9FSm1BR2vBym3EzC7CSGxBROhNTW1Pz+/OTm5NTO1AQGFNzW3Ozq7Ozm7IyKjJyWnMzOzNzq9Nze3OTa5Ly6vCQiJGReZISChKyqrAwqVBRWlOTi5MS6xJSWlNza3OTe5Ly2vGxmbKymrIyGjMzGzISGhKSepCQmJDw6PHR2dJSOlPTy9MTGxLy+vLS2tMzKzLSutMTCxLSytKSipJyenKyurJyanCwqLCwmLCwuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBhgIBA4SLjAABBAUGBwiNlY4FCQoLDJaNAQ0ODwsQnYwREhMUE5ylFYYRFhcYGRgaGxsDHJUdFR4SHyAhEyIjJCUcuo0cJr0nExihxgwoyYscKSnMHicOIw4lKissLdWDHC4vMCu9McYqMjMyNOUANTY3OPEoOTolDCszdrSgwaMcBxs9TMxYOCMHBx8zfPj48QNINQ5BbMBIIUShDIUoTAhR94PHPEEHbQwZckOGjBQviMxYUWQIDCMmdXE4gqRnkiFETAxR8iKFjJU2evZEdmLJkgJIbqS4wXJIUapImj5FtuSEVyRVV1IVi4RIChhEkLVAgcJHEqVwVJUmYdKkiRNkALMRecKECRG/ff8CEQJFCA5kMKJEoUHDCQ/HkB9LmWKECpUeyKoIMSLEyosen0OD7iH2xg1dV7BkqXGlBpbWNTq4Zn2khu0aAAwEAgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmail22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBDQyNCwqLCQiJBwaHBQSFAwKDAQCBDw6PPz+/Pz69Pz27PTy7PTy5PTu5PTu3PTu1PTq1PTqzOzmzPzuvOzitPTmvOzivAQGBDw+POzevPz67Pz25Pz23Pzy1PzyzPzqvOTavERCRKSilPz21OTevIR+ZExKTOTi3JyanLS2tPz6/Pz65KyihJSKbMS6lExOTNTW1JSWlJSKZMSylNTOrNTKpFRSVPz29MTCxPTmzKymjIyCdOTWxOzexOTWrBQWFFRWVOzu7MzKxJyalOzatLSulMzKtOzmxOTarFxaXKyqnPTmtIyGdIR+bOzetOzixBweHGRiZOzm3NzWzNzSrOTetGRmZOzizOTexOzm1JSKdGxqbHRydJySdHR2dOzapHx6fKyijOTixCwuLHx+fFxeXERGRDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeIiYqLAQECjwORAwSUBZYFBpkHmwgJCgsMDA0OD6UQERITFBMVFhcVGBkangq1ChsLGxwcHQ0dHR4fICEGIiMSCbS3uLq8wCQUJSYGJygpKhQJKyvLLM4Nwi0uLwUwDQsxMtmeuQveHR8UMzQ1NgU3Dgo41jk6ns0cKOzgYaOHjx9AgjTAUUvIECLZNmxoUISHkSM9KiBJQkCJA4kKEoBQoWJJAiYtmjh5AmVCsCJRpHzckKCCySlUUvBYUqUHDysSPnxIEuXKA5pPRiRwxwFLFhRaIEDYUoEChCcDuECoOWKFuwW7nHkg4WELkw8/BHRRwESpt10dU8SSHevlRxIBX6C0WBE27q8GZMkKbTADjIAwYlb4GLMYShYoPTRo6FGiSJEKPyzMIFMmzJcvXbhwkSLFjJkbQW6cOHNGhAgEAdAsmk27tm0ABgIBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailreplyall22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBLyejPTixPz29PTu3Pzu5Pzy7Ozi1LyelPTavPz+/DwqLPz67PTetPz69ERCRLSWlPTmzPz6/OzexLyajPzqvDw+PDQ2NMyurDQiJPz23PTatJyenAQCBPTevPz25LSajOzq7HxiZPTexPz65JyanBQ6bKSmpBwuTOTi5OzaxBRCdHySvGRiZHx6fBQSFERGRNzq9IyOjHx+fGxqbPzu3BwaHFSq3Aw6XAxKfPzy3Gy63ByWzJzO7Mzi9OzavBRytAx6vCSazGRKTPzy1AQKHBRGdBRyrDy63ES+3Cym1CR6rBwWVAQSLAx+xCyCtBRmnPzuzAQWLAwePPzyzKSCbAQOJByGvOTWvPTmxBQODFQ6PPTWrPzqzOzatAwGBKyObLSWfPTivKyCZEQyNKyGZOzWrOzWtOTSrOTGpNS2lJx2XDQmJCweHCQaHCQWFBwSFBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpkzGjhAoYMGjZMpMghQgcNFjh4mODhA4gQGkSIHAmBwAgNJEpo8KDSxAkUGjhMSEGz5gUVIiKs2PmBRQudHiwQpUnAxYsXImB0aBqjBcuoU0fKmPGChgUNH2qIqGHjg9u3bicWIFs2rYgbNnDkyGFhb8cccQ3ouJqWQo0dPFr0WMy4h48LFj4gsKriB5AeNngEaSGks+chPnwQOXFAh4oXRYxk9nAEyY7XO2wksWHDx5ATCDIoUXEBsYclTJo4cWJhuIjhSXacSPBEiZLMQY4wgRKluvXqUpyIsDElAxUqVaxcwcGCPQuWLOixaNHCZAsXBU+oqKDSxQqULF6ifNmyn/8VMOtxwcAK36kQRhdJQIFFEmKM4eCDYGyhhYAEkqFEGSuYYcUZLaDxXRpqSNRCEu6twYaFZXTQhgRd2NCCG9918AYELTjoXgNuKAFHB2RQEUYHVbQQRwlUpPHGGFwkyQUEDsgxx4lh9BhCBy2U8UQJcrSg5JIQ0FEHG3bc0QGYK+CRhx57PEGlkhM9sAEffKTQhx9+/AEIIIGoEUgLLRRFR0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailreply22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBMSihPTixPz69PTq5Pzy1Pzu5PTq1Pzy7Pzu7Ozi1LyelPTavPz+/DwqLLSajPTetPz27LSWlPzmzPz6/PTexPz67Pz29OTSzMyurPz25LyajBRCdPzuvDQmJOzexPTevOzq5BQ6bBwuTDQiJHxiZPz23Pz65LyinPzmvBxCbHySvAQCBOTi3OTq9CweHOzaxFSq3Aw6XGy63ByWzJzO7Mzi9OzavNzq9BRytAx6vBR6tPzy3AwOHDy63Ax+xCSazCym1CR6rBwWVOzizAQSLES+3CyCtBRyrBRmnGRKTPzu1MzGtAxKfAQWLAwePPTizMy6nByGvNzWxOzWrNzOtBQKDJR2ZNS2lPTmvBQODPTatKSCbOTaxLyqlAQKHFQ6PPzyzPzqzPTu1PTivOzWtKyObPzuzOTOtLSWfPzqvAwGBKyCZPTWrPTmxNzKrEQyNOzatOTGpJx2XCQaHCQWFBwSFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpYuIDBQgYNGzh08DCR4oQPIDqEmDBhJQYRIzqQIFkSAoESJCKkDGFiwgkUKTpMwECz5IASKjqsSMlSA4sWQjG4qGnzhYoQSmF0iCFjBgmWGWhQrVHCxg2sOHLo2MGjB0sLYmsWQHq1p4wdPtqemGDhB1UDQFSouKHi7oQgQmSwUMyYxcQDZQWz2EFiCJEiRoyQyLzZyGIIB47YKLwDSRAiSZSoXq1kCRHNLBK8YGKjCYskTp4ogeKkt+8oUaBImZKAAxMmVKrctqL7ihTnz7FkAT5FC4cKFbZwadIFdxcvX8KLss8iJcoUBUcq2KgAJoxyMTy4jCFTxoxEHl2GLyCDncmWM2hUIQMPY2CXhhoTfTEcA2tgVwEba7Thxhs88FdBD/ZB8MUUHMJBRhw2sAGCHBKU4UaFc1RAhxnhcdhhHUzYAUIcFdxRAh4R5KGHinu4OIVEDqTBRx81xhGHHzD8wQYQetDRI4cTAcIHGWT0EQgZa1ApCBqDcBAID1Q94IEHLtBAAyGEFGKIIWqYYQYPYNZkQEAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailsend22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAIR6fIRydHxubHRqbHRmZGxeXGxaXGRWVFxSVFxOTFRGRExCREw+PEQ6PDw2NDwuLPwCBLSijOzixPz69PTq3PTu5PTu3PTu7OTi1KyelOzavPz+/DQqLPz67LSafOzetPz27Pz29KyajPTmzPz6/NzSzLyurCwiJPz25Ozi3JyOjPzuxBRGbAwSHOzexPz23KSSlPzqvBROdISavBxSdAwaLHRiZLSinNTGxMy+vBxGZNzu9BSGrAwWJMSyrKSSjFy61ETO3BRWfPz65PTqzHTK3ByqzBSWxEzW5AQWJOTWxBRCXOTu9BSOvDzO3ByavBRKbOzaxOzizKSWlCQ2TAQCBJza7BRWdNzSxJSCbMzq9BSOtCSKrAwiPOTavPzy3LymlCySrAwmPFRKTPzy1NTGrPzu1JR+bOzatPzyzCy61ByGpOzWtJyCbPTmvPzuzIS+3FymxCSuzBR6nJyCZOTWvKSObMSujOzivAwKDOTSrNzKrJyGbDwyNOzWrMy2lIx2XBwWFBQSFBQODAwGBAQGBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpYqMDxAoYMGjZwmEixg4cPGzqA6BBiAggRIzaQGEkSwgAMJCKgnNBhQogSJlKGOFHTpgYUG0TsnJBCxQoSE1i0KErAxYsOJJRuuAAjhkwZM2jUqGnDBQoUHTbciIEjx4YNOmbs4CGjB8kCZlGAALHBx4+YcTcACcJDyFSJBo6iGNIhhQkiG8BOKGLkCBK6SSQisHoWhZIbG5bMYALECI8mTZw8gTL1QJQXZ6VMiUylSpUlVpoYaXLFtm0EGmCjwJLlA2O9MrRsccKlC8kEXr7AdgEmwtkhX2SQ2BIkjBiSYzSQr/nyhUKZLIrJJOcexvlEBV7IvCBjRkmAMzHOaufhxDvJBWiQISAFxUUQQRovJNeEGmu4JxEDbKQhXxsfuFDGGW68IQMcccgxRxUkNRDhC3R8QMQIdZwXQ11JJGFbiB+QYccHaaTxhgt13OFBDGTgkUdRDrhAhx5k2JjGCB/swYcXMXwAYk190OGHHx/4wUaVepTxByAaoPEkSQ5wwMEJZAZipiCDDJIHIYV8OZEdAQEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1downarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBBQSFAQGBDQyNExKTHx6fGxqbFxeXGRiZFRWVDw+PAwKDJSWlOzu7LSytJyenJSSlISGhISChIyOjFxaXDw6PPz+/MTCxLS2tIyKjKSmpKSipJyanAwODDQ2NHRydERCRFRSVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZzQIBwSCwaj8ikcslsOp/OgHRKlQoCgymRUDAcEIkwYgxWFBYERpHQcDwgEclEQmk8DhWL2kiIXDBwExMNGRoJaUkEEH8bEQ0cGgcWAksEHX8QHBKSHk1sfxMHH5ROBBsOICGkT2wiq1CIULKztLW2t0h2QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav1leftarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExKTJSSlHx6fAQGBOzu7GxqbJyenPz+/LSytFxaXMTCxGRiZKSmpISGhFxeXISChAwKDFRWVHRydJSWlBQSFERCRIyKjDQ2NIyOjLS2tDw6PBwaHFRSVDw+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZ5QIBwSCwaj8ikchgQLJGBgfNZDBAKBirRekBMtYGEYsHIgsWNhOO7tCrShDU18Hg/CJAIG0o4wCUQcksTFBUSCRYSEnpUFxgIGQkJGYyNGggbHBaVjR2QCxEeWkITHQ4IH3tPFwEMA2ajAKUgqlQTTbFEE7W5vUgGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav1rightarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNGReZAQCBMTCxGRiZMzGzOTm5LSytPTy9Pz+/CwqLOTi5Ly6vCwmLMzKzJyanJSSlBQWFKymrIyGjCQeJJyWnISChISGhHx2fKyurDw6PAwODHx6fHRydDw2PERCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZ2QIBwSCwaj8hkMRBQKgOCgRMZIBSk06XhEM0SA4iE4uoVLhCMhqLrdSAekMgYO5VM4BQ521mxIC4UFxBWdEkSERYYFxETGQGFSBKCGBEaGRuQSBwdeZaPXpsQCB6YZQMdEI6ZSgMepKusHh+wrCC0rLdlursGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav1uparrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBFxeXDw+PMTGxHRudPz+/JSSlLSytIyKjHR2dISChIyGjIyOjLSutLy6vKSepJyanISGhJSOlOzm7Ozu7MzGzKyurJyenDQyNGReZKSmpIR+hCwuLCQiJBwaHBQSFAwKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZtQIBwSCwaj8ikcslsOp9QYyAQFQYEAyr0Sihkn1fDAeHVLsOJNELxVaITC0bDUU6GH5AIQ8KYrNtFVxQVFBYWFxgRCREYdUQZGhYEDwgIGxAHCQocCgWOQhmhGR0epR8gqCFTq1Wtrq+wsUt0QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2downarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAQGBBwaHDQyNExKTHx6fGxqbFxeXGRiZFRSVDw+PAwKDJSWlOzu7LSytJyenJSSlISGhISChIyOjFRWVDw6PPz+/MTCxLS2tGRmZDQ2NAwODJyanKSmpKSipIyKjHRydBQSFERCRExOTFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAasQIBwSCwah4FkQKBsDpoBIqFgOCASCYRWm1AUFgRGkdBwPCARiWRCaTwOFYvYSIhcMOiJpJGZaDYcR0IEHXceEQ0fICEWIoJDhHcQHxIHgI9SEHeVG46YUh8OISOen1INCqWmUnOYTUxQAU9NUlRWWFtbCiRgrYNlZ2lriG8lYUd1khETE24gCZeCkRgeFBAQIAeNn9OTlXKrBJoYnKrcoaPmpmSpq3S+7u50QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2leftarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExKTJSSlHx6fAQGBOzu7GxqbJyenPz+/LSytFxaXMTCxGRiZKSmpISGhFxeXISChAwKDFRWVHRydJSWlBQSFERCRIyKjDQ2NIyOjLS2tDw6PBwaHFRSVDw+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAavQIBwSCwaj8gkMiBYNpeDZzEQXRIKBmPgmtUSDgipcAsWjxOKBaN7Tq+n6EbCIQ3E5+KtQk6gjwl7CX11D3sPBBARTQGFDYeJT2R8EhB0koKUfgATFBUSCRYSEoqcnqCiikMXGAgZCQkZqautr7FiFxoIGxwWqQC4ury+qh2tCxEexMbIRhMdDggfYs7Q0kcXAQwDbELY2txEziBmmx3jSRNMR+nk4e2b70ry80QGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2rightarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNFxeXAQCBMTGxOzm7CwqLLy2vPTy9Pz+/Ly6vCQiJLSytLS2tLSutOTi5MzGzKSepIyKjJSOlKSmpMzKzJyanIyOjBwaHIyGjISGhJSSlISChBQSFJyenIR+hGxubDw+PHRydHR2dEQ+RHx6fERCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa6QIBwSCwaj8hkIIBcJgEBweAYnTYJUmMAa9USClniFtwlGg6IRFhoUKTXwwWj0FB3F46Hwl6UQyISfAB+EROCQgsUFRYSF3yJEIyBaxgWDBkaGRtclQwSHBIbEGEdGx4fGhcOICEDGBsWHBmqIq1CHRIWGRMMIyRTHRy6Er22tyONq8YdJRe0xkIDwr2/QwMfliMmZQADIxasZd4e4UYDIr7c59rc0eVFA+/m0EQD9PDt0flP/P3+BkEAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnav2uparrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBGReZDQyNMTCxHx6fPz+/JyWnKyurHx2fDw6PJSSlISGhIyKjIyGjISChLy6vJyanOTm5PTy9OTi5MzKzLSytKSepMTGxMzGzLS2tLSutKymrHRydCQiJCwmLBwWHAwODLy2vHx+fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAajQIBwSCwaj8RAAMkUBgSDZdP4JBSi06TAcEAkFNLp07BgLLzY5njRcDzO3zB1C4lEGI83Wj58SiYUFRUWdg0XEXFFAwIYGRoWGxwRZQUFHZdgRAObmx4fHiChISFKpVlKWUdPaalOAlasp1sHG4myZGZ7Yltsbgu1mUhjdRF5egmxfQJ/gYOFdrZDi40iFgiSCw8jBQmYcpydn6Ego6WorUwGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnavback22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRGZAxCZGyavExmjHyatOTy9CxihISevPz+/KzO3BRylAw+XAQCBDRWbPz6/FzC3CSuzDyexJzO5Mzq9CxSdAQOFISmxNzu9HTS5BSmxAyexDSuzJTa7Mzu9Kzi7GS21CRmjAQOHHSWtLze7AyWvHzG3BRihAQKFCTO3BS+1AyixBSWvBSOtBSStAQWJBSixDzW5BTC3BSqzBS21CTC1ETW3AQSHEze7BRqlBRmjAQCDBR+pBRefBRSdCH5BAEAAAAALAAAAAAWABYAAAalQIBwSCwaj8ikMqBcMpvHgGAANQYIhWdVGDAcENQtIJBQLBgNx0MQaDuQXcghIplQDhBIxXKJYiAZGhscHR4VHyAhIiNWJBklGhIbJoQnFCcTKIxFKSgbKissJi0mJi4vLiYoMEcXKDEyMzQ1Nje2NisoOEg4KDU5K6g6OwwoKAN9SCOeMmgwz884PEq9PT4NYkPLP9jZQikN3d4AKVrjKePp3gZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnavdown22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRKZDRSbBxCXJTC1Mzi7Nzq9NTm9Bx2nAQCBNzu9JzG3Hy+1HzG3IzO5BRmjPz6/LTe7Dy61AyStCTC1FzC1AyGrETS3ETC1ETa5BRulAyuzBRylAw+XMTe7Gy+3CSqzAyexBTC3DR+nIS21KTW5Nzu/KzO3FzC3Pz+/ByixEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaRQIBwSCwaj8ikcnkMBAQDgjPAFAYKhsMBkVBUAYEFo+F4QLzVQEQyoVTOX/XBcsHA0+vMRbNBMwkRDhxuHX5GTlIeHh8gISIjFAEeiVRECiQlDAUmgxQjIhwiJHdFlycoKSIUFCEjGiGkRpcqCxYijxorsUezcxYsuoZJsxLAu0qXB7DCTJfHVQrMX9PU1Uh0QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnavforward22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBBxCXDR+nIS21Aw+XJTC1Nzu/KzO3Pz+/Nzq9Pz6/MTe7KTW5FzC1Nzu9CRKZMzi7IzK3Lzi7LTe7HzG3Gy+3AyuzAyexFzC3DRSbHy+1Dy61CSqzAySvAyStLze7IzO5AyGrETa5ByixBRmjCTC1ETS3BTC3Bx2nAyWvEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaYQIBwSCwaj8hkMqBsBgTN5IAAjRoDBaq1aDggtMuAWDzoJhTgY+CwYLgZDccDwkgXI5IJZVGxXDAZGnR2QxsLHB0PHRgeHyAZDyFfVUQDCyIgIyCPIB+QJCUmlEMBEiInKCQnKSkeKSQeomoqJrUmKiArKSwZsmoCwMEBGCyxo1EGHr3HUQEEvltCBtDRAAbMW0zV29xDBkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavhome22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAQCBCQiJNze3ERCROTi5MzGzLy6vDw6PKyqrKyurBQSFGRiZGxqbGRmZISChEQ+RExKTExOTHRydDQyNOTe5FROVLSurCwqLMTCxPT29Pz6/LSutFxeXLyytLSytPz+/JSWlKympPTq7KSipNzW3BwaHHx6fKx2VJRWNHQmBFweDOzq7Ly+vNTW1JxWNLSajPTe1Ny6pKxWJNTS1IyOjJRmbPTi3OzKrNSSXMSGVHQiBHx+fJSSlPzy9IxOVOzWxOSyjNSCPLxeDJyWnIRGTOTGtMxmDLRWBHwqBIxGTLRSDDQuNNSunKxKBGwyNMSafMxqHMReDKRGDPTu9LxuPLxaDJQ+DIR+hGQqNIQyBGQiBNTO1EQKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAYSIiYQCAwQCiokEhwACBQYHBAiQhAiHlQYJCgkEC5uCkp8MDQ4NDwylmwgQlgQRERIEBBOkmxQVBgQWFwUFFxEEDLyJGAUZtQoFGhsFHLYdyoOVHsEf0SAbIAUex8mwlAUhtSIFG+3uIyTWvAIGJMEkJe76GyXbEeWUBJg4USKaBhQpVKzYoIFFiwYUBBJa8MAFCw0vYMSQMWOhBhoTKCQSUKMEiw02buDIoWOHBg0GeIhEFKAHDR8afgAJImSIioYliMws1MPkhiJGchxBkmTDCBo1hg4KQMTiBiUyhBxZ8pNFiR5MEtU0WqSJVidJNDyNKraHC5xPNKBEkTLlJ5WvUgWNvfikyhArV34+7ZEXQAAsB2iUyHLlihYtW0pwOYAFgyJDmDNr7jIIWiAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavup22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBHSWtBRmjAQOHISmxNzu9BSmxBRihHyatPz6/Lze7CTO3BSixHTS5BTC3DzW5ByyzPz+/OTy9AyexEze7ByixGyavKzO3FzC3AyWvBS+1BR+pAQKFCRGZExmjCxihBRylCSuzBSWvBS21BSOtBRSdAw+XAxCZDyexDSyzCTC1JzO5JTa7DSuzETW3BRqlAQWJDRWbOT2/Mzq9HzG3JzS5Kzi7BSStGS21CxSdCRmjAQOFAQSHAAAACH5BAEAAAAALAAAAAAWABYAAAaeQIBwSCwaj8ikcqkMCJjHwIBQgBIDhgMiUbUGFAtGw0GFfheHByQi4S6/E8pDUoFYLm5kAEPJaBAVGxIcER0JHlEfICEiIxUkGyUmIgknKIhXASkonCorgSwmKQGcKE9IAi0uLxUwMTJWMzQ1NiYwBLBQHws1N7avXgs4NjkcCblMATU6KhvGyG87PAnUKV1MAj0+2zIFp1bg4eJJdkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplayeject22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAwKDJSWlFRSVBQSFKymrOzq7HRydERCRPz+/MzGzISGhJyenKSmpGxqbJyWnJSOlKSepLy2vIyOjGRiZPTu9IyGjLSutFxaXExOTHx2fGReZAQCBAQGBBwaHCQiJLSytKyurJSSlFxeXNze3LS2tIyKjFxWXHRudAwGDBQOFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa1QIBwSCwaj8ikcqkMCJjHwIBQgBIDhgMiUbVKFQsGItBdBhpgh4PxIJvRC8cA4oiMy8bvQhJhMAYTFBVOURAWEw0QFxcMERAYCBluVxobDxkVHJocmBwEGgmEQx0dHh0CpKmkH6odVlanBR8FtAIFtiCkSB0LISEiGCIGIxAPDySuRwIOBwrOzwoHJRHJRh0jJgMj2gMnERQUCNVFHQQoCBvo6CkICATjRB0qp7b1K6qv+foyQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplayend22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNFxeXAQCBMTCxGReZBQSFOzm7AwKDKymrJSSlFRSVCwqLLy6vPTy9OTe5Ozq7CQiJLSytOTi5BwaHPz+/HRydMzKzKSepJSOlKSipJyanIyGjIyKjKyurISGhMzGzJyWnHR2dISChIyOjLSutDw+PERCRHx6fJSWlIR+hJyenGRmZHx2fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa6QIBwSCwaj8ikMBBQKgOCgRMZIBSkxYHWoDVWD9EigpBQLLBERsPxCA8NDUhjgTBGJJNGG02RVBQWdUV3FxgZe0IGfoAGdhoXGxwdiAYef4FGFBoeHB8dGSBRihUhIo1FBhkbIyMkJRYmAwYal4JEBh2RChIWJ1IIGxUZFqdECCgkHR6wWAYpFR2YWSobvL5vFgfDaEMDIivMRBEsD9HcQgMWvecDLB0tZ0btsfJa9vLXU/X6/P3+b0EAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplaypause22:play play22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBAwODMTCxKSmpJSWlFRSVAQGBBwaHLSutOzq7Ly6vCQeJPz+/Hx2fBQWFGxubLSytJSOlBQOFAwKDJSSlJyWnIyOjHRydNze3GRiZAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWBICCOZGmeaKqubOumQSDEgRjPMSoMRGEcol3vh0IkFAtDDWBEKlGMRKPgEIii0yrqIS1ArADu9KuLNCSOSdCMVp8ohEZFC4DL6SaBpXGh6/l4JX8XZACDhXkYCn1LAoqMUBAZEhBLDJKUSyYBGmhPAJyemiU0NDaloy+qq6ytI8whACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplaystart22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExOTAwKDAQGBJSSlHx+fBQSFMTCxKymrFRSVOzu7GxqbLSytLy6vJyanPz+/GReZBwaHHRydKSepKSipGRiZJyWnAwODLSutKSmpISChPTu9ISGhFxaXJSWlIyGjJSOlERCRIyKjDw2PIyOjLy2vOzm7Dw6PLS2tCQmJOTe5GxmbDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa7QIBwSCwaj8ik0hgQLJGBgbMoqBIKU2LAcMgOEQmFYeEFbBmNMgDhYDwWBC0k4pCoJ46IgRIXBioRCRYXamwRGBQIfgaBFhiERhkaenxmCoEbBhyQRYaIGVsdghgem4UWegcEBB8UHhsgIaZGBBgRIpUIIxQhChginEQIIBEklWslFyYnBsFfFCi4WQgpFBwqFxNGKxcsxl4IAS0NZEYCF3vlwgEfUuZV8JEuI2pPAARN9kcE9fr+SwaCAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplaystop22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAwKDBQSFBwaHCQmJJSSlISChJSOlJSWlGxqbGRiZNTS1PTy9Pz+/Ozm7OTi5FRSVIyKjOTe5MTCxIR+hExOTHR2dLy6vLSytLy2vHRydFxWXIyGjIyOjPz2/FRWVHx6fExKTMzOzJyanKSmpKyqrKSipAQGBLSutHx2fDw6PAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa1QIBwSCwaj8ikcslsAgKCAWEQjQ4KgSwyYDAcugZEQqFYYJECA6PhaLcfEEUkgJZAGJB8fkKpWOhHAxcOGBQZGBoaGQgbHIBGAhUOGR0SBxISBh4Xf0iCHxQSlRIIXhsgj0UCIaCXmJgHGyKpRJ+hmB5dHQqOaCENIx0epBIkBhdzngoPGCQlJifQJBvJRygRKRcKGxcXGypys1srEREc5SLnICLiR1koLFVUWfRO9vf4+UwyQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextblock22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUWzvNzo33GfFl5jVlonlTrr1DbvFi9vjeeNUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextbold22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIxhI+py+0Powm0VnknjVkH2AEhE45LZ55Wqn6e65TsMc5eYosbksswubJIhsSiccgvAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextcenter22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUbz3Sh7yIWfFHKjVl4nmFrr1Lpr7LwkjeeIUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextitalic22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py+0P4wqUSlQvttrkDnyaOHIdeaGRupplAIauVM3xjeeOUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextleft22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+pyw0Bo5zB2UXz3Sp7yG2fFJajVjonmIor2TJvfL0wjecIXQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextright22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUfz3SZ7yIXdF4kWqZkbCqoMO7kXLC+wVOe6YRQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext22:text text22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBBwaHAwKDBQSFLy+vLS2tJSWlBQWFKyqrFRSVCwqLDQyNNTS1GxqbFxaXJyanIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAVcICCOZGmKQSoMaZsShBsQBdAapHvgaIDUqUPJlRjSbAoT0fRDKgODRbF0PLUYjZO2F2Bst9evNix+dsvDlGKK5jraudQb7qbX6a2HEJ+ycyF+LRE8ZTI+fX5oGCEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextunder22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIvhI+py+0PowmUnhpeVVnb1DkbCI1I2JhX+Z0sOr2cTHpwK7a4rUr+hAnufsTirwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewchoose22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBFRSVExKTDQyNPz69PTq5Pz+/OzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq70466Cl+AMxBVwnFIVRAmQHCIeBrC1L3tQgJ/SaEbeeC1PLBHE2ybFI9A1HzstHEIK6YCmhDTmBybQaHYJn7QC5zKeytIQe1+pKNE6P2yMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewdetailed22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz+/Pz69PTq5AQCBOzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAQ+EMhJq7046817+MLQUQFRGMc4lQaSAkcMx3QltMmrDrSu/sCgEPgJhIiFk89DaL1qPRnlhsgBebWhdstVESIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewicon22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz69PTq5AQCBPz+/OzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARWEMhJq7046z2DF0PlBeAVEERhiKhqHgWyUgEsX0KczFOO7JeBYciTCImc5ITIXDKHyqhU9AnRqq9UEVDTvmLbGhin2/qAliOUot5OLc81IO5+2+8WewQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewmag-22:view view22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAbKQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/47vrq9P3s/avno2BBf/MCClSob4iBIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmag22:view view22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbIQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/47vrq9P3s/cunr9S8gAIRFhTCLAgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewmag+22:view view22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAbQQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/4zT766vRI+fvHD4CPgwcJ9qg0UB85JA0dDjEQBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmulticolumn22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz+/Pz69PTq5AQCBOzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq7046813+MJQfUF4BURhHGO6noSBsEcNoDJtS4KcsJQe4ncZ1HYT47HDbDqfUAnJRJmKLIGCCjjJbmE5wBI3EyOFxKCPS1EiJW52dE6vZyIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewtext22:view view22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIkhI+py+0Po2ShBlOxzbP7n2yaJoLm+ZTcxqHuC6hXzML2HVEFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewtree22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBFRSVExKTDQyNPz+/Pz69Pzu5PTq5OzaxBQOFOzKpFRWVFxWXOzexPTexCH5BAEAAAAALAAAAAAWABYAAARPEMhJq704g6A779kHCORAgNskFMYhakE8FkjyBcoWv+JwJItXaELYCTFHlCSpZKKcoB5jYHpOGgUadLKbIRw3jhEzQDyCSuI4zW673yhDBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/ICONS/tkIcons-sample.kde",
    "content": "1downarrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PUZi0zmTtypflV0VdRJbm6fgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\n1leftarrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAP///wAAACH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxqdwoNGTmgvy9px/IEWBWRkKZ2oWrKu4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\n1rightarrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxCtwoNHTmpvy3rxnnwQh1mUI52o6rCu6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\n1uparrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PWwhxzmetzFpxnnxfRJbmufgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\n2downarrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+pq+EPXYpxUckoO3AjbF3dJwahllXe6AFgC8d+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n2leftarrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pyxf5VohmSlsxmpjTzAHeN5ak6UHpqKRi2GpwvH3Q3eT64RcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\n2rightarrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pq5HOAjQyVnqfhHue7oAaKH5kiW0AmnLqaHomkj02g+e6XwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\n2uparrow-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIghI+pyxfR0HsRzNnuXVqn3mVQZWFRyIDjp65Ga5Ly4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nabs-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAQABAAAAIwhI95ocn2GlySTiME1iC+DIKdNWxANl4HaqWr055cy6Bs6dahmJsyXVFFJJ7gyF8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nairbrush-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBPzCxMQCBIQCBPz+/MTCxKSipFxaXDQyNISChAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARUEMhJZxCjanBH3hY2EFJgVt0YcEW7liLxBoVxzPHL2msqUzSeT2c5HBC5jQmROKgAhCgKEVBQo6YAqVQIHBQ93ZbmBWt+nDJRgiYMvmuoThWXT/wRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nattach-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBPz+/AQCBAAAACH5BAEAAAAALAAAAAAQABAAAAI2hAOCxg2h0nJHyEshi9HpxU1GOCLdZoKpQ15nibUoprKp9lh2oucUxsBRXsJh4Hjs/QTMpr8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nback-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRSdBRObCQ2TBxObISevAQCBNzu/BRGZPz6/FzC3Pz+/HTS5ByyzJze7Mzq9ITC3AQWLAyWvBSavFyuxAwaLAwSHBRafBSOrDzW5AyixCS61ETW3CzG1AQeLAweLAxefBSStEze7CSWtCyatBSCnBRWfAwmPBRWdByixAQSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZiQIBwSCwah4HjUTBQFgkFg3MoKBykU0QhoUAIAuAksbpgNByPxQMSGVsVDYlkIqdUiJYLJqORbDgcHRseRR8gISIaEyMkGCVYRBEmeyAnlgaQkSgpmU4RAZ1OKqFOpFNGfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nblend-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBARCRAQCBASChATCxATCBASCBAAAACH5BAEAAAAALAAAAAAQABAAAANHCLrc/izISauYI5NduvlXMIjEQBSnUYCYxnmsSJrouhqh6J4wLo0mWuqWy5heN58seBrGdEdeMgQsNW0ggXbL7Qog4HDDnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nbookmark_add-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy6vERGRFRWVDQyNKSipAQCBMTGxKyurISChJSSlJyanHR2dIyKjPz+xISGhPz+BGxubMTCBHx+fPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVfICACwWieY1CibCCsrBkMb0zchTEcNYsIiYHiwIOdEAvigdFQGE0Ix4NBbSAgsWjk+jBIAlcUYrJASChnSXZSoUDelKfoKpFALJA61ueGI2IAZmhogGFmCGGAgXsifiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nbookmark_folder-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExKTBQWFOTi5OTm5CwqLPz+/PTy9Ozu7FRSVNza3PT29KSmpAQ6XARqnNTS1JyenGRiZJTa9Mzq9JzO5MTGxIyOjKSipFxeXMzOzDw+PDy65FTC7HS2zMzm7MzKzKSenASq5Bx+rBSGrFyqzLSytDw6NAR+zBRejBxqnLSyrERCRIyqvDRujKyurMTCvOzq7AQ2VDQ2NNze3KyqrGxqbLS2tLy6vCwuLDw6PAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAawQIAQEBAMh4GjcEAoCAQGYSCpDBwQiQJBEVhQj1YGo1DoNqZTx8PhODAWZUik0ZAkHRNKZe0IWC4RGBkBGhsOHB0eFR97bBdcICEbAA4iIyQlioxrGhEmJ5QoKSoqJCOZiw4rGixEYi0uo6WYDi8wkwAsCTFksLIuMi+tADMLNAsLEBAgLSMpMjW4RCc2MCAgFjA3MA4R0kgzGS84Ny8vDqBKSDkKETUOOurqAQagfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nbookmark-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy+vERGRFRWVDQ2NKSmpAQCBKyurMTGxISChJyanHR2dIyKjGxubHRydGRmZIyOjFxeXHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICACwWieY1CibCCsrBkMb0zchSEcNYskCtqBBzshFkOGQFk0IRqOxqPBODRHCMhCQKteRc9FI/KQWGOIyFYgkDC+gPR4snCcfRGKOIKIgSMQE31+f4OEYCZ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nbookmark_toolbar-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy6vERGRFRWVDQ2NKSipAQCBKyqrMTCxKyurISGhJSSlJyanHR2dIyKjGxubIyOjISChHx+fPz+/MTGxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVpICACwWieY1CibCCsrBkMb0zchTEcNYskCsXiwIOdEAzioeFIGE2IB6RBbT5HiAhEIpk6Y9kJBMJoHK6iLIU8kZxFlXhlIp/XJ4BKUIGoWIJ9f3x5e32FeoB5goGAfokTCJEIFJKTlX4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nbottom-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObCRKZBxCXAwyTKTK3Ozy/NTm9GSivAQWHNzu/FzC3IzO5CySrAQOHAyuzETS3CSWtAyOtETa5Aw2VLze7ByWtBy61BSavAxWdBRCXAwqPAQCBDR+nKTe7FS+1Eze7ByixBRmjPz+/AyexAyixAQKFBRqjAQGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZhQIBwSCwaj0hAYCkYEJLKguGASEADigWj4bgaHpBINykwSCYRa5HCFFQsF0xGo9lwhpSOwfORYC4gISJ3RAQdIyQYJSAlImNrh4uNJkl5CoKUUBQnjlB4KFAcoqOknkh+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nbrace-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAQABAAAAI2hI9pEXq8mnsNzggsEMJwbHGimFXS4HUfpKUIq3QJ036vuakyWvbjCJLYbL2WgyW5WIw3g78AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nbrackets-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAQABAAAAIzhI8JwXocllMxTlSREGY/2W2iJ1nAEAJklpCfeXAJG8sY6JGowY7jW0sBL0NiqTGBAPwFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncharset-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAInhI+pqxH8kFsvsgtm1vvEaoBZSH6j5FSaRY4me4pyq1ochuf6fvgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncolorize-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAPz+BAQCBPz+/MTCxISC/AQChMTC/ERCBPyqXMRaBATCxASChPzerKSipMT+/MQCBATCBASCBARCRISChMT+xDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVnICAGgWieZyCQKGuqZPkGgwyv60gONRDvNlqt9Pv5BgRCYVj8IQ3L4qE4KFiZzRiP90MgEj+FYtGLIRiJQaMxUDjIxFoi8YBAIo3FQjIJ7iAUERNqDTI6PBGJfT0oFVpsMSgzkSh+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncolorpicker-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBARCBDQyNMT+xATCBASCBPz+/FxaXISChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ/EMhJZRCjahBIMdlmeV8gBl3xCabWGarBihwBz+eB2O0WHIFEp1f5BU1EilFI4wCZtGWy+JwWj00OynrNTvwRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncompletion-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/Ly+vHx+fAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM/CLrcGjBKCYK4+NoMs+jWIBIdZ50QuWGgMASD+oGnO5beR+x7UE3AyGKV0wxnpeSxyDoGN74Hszl8QhxYhj8BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconfigure-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBISChGRmZMTCxKSipLS2tHx6fPz+/OTm5FxaXOzu7DQyNMzOzAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMhAq7wYBDECKVSGBcbRfcEYauSZXgFCrEEXgDCSeIEyzKSXZoBYVCoJVIqBGByKu0Cy8QHxmgNngWCkGgqsGWFseu6oMApoXHAWhWnKrv0UqeYDe0YO10/6fhJ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnect_creating-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBPz+BMTCBISCBAQCBPz+/MTCxMTGxISChFxaXMzGzKSipAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJZbihUiz60FPnfaA0iBpBVGdHEYWxToEoSHBRHHM9AgSEQRcj+AYkYAJxIPKQFUJiOdTJQFIDU6dYzKKFhTCM+E5g4mXaDAyrlogEG+DGTecA7wsP8EcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnect_established-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/KSipDQyNMTCxMTGxISChFxaXMzGzAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJZxCjgsAtDtUlCOA1gJQ4kl/IDatAoF7xxkS6GgEBr6jAobCyBX42SQBxMOx6A8MhiGASR8YDgrYsNEeJ0zaEGZY7uoH2oB6nOUwtbdLaVOeTUwo/8UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnect_no-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBPz+BMTCBAQCBERCBPz+/MTCxMTGxISChFxaXMzGzKSipAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARPEMhJq704axBEHoPUEdhQGMNYFuwxkKInDYjBniEnwMCQIIebSzXx/WwsFK+YMABZikWuYlrUCtZpEYv4WRPaHhb064YB41kCfJFSQBh/BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncontents2-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBDyKhDSChGSinFSWlEySjCx+fHSqrGSipESOjCR6dKTGxISytIy6vFSalBxydAQeHHyurAxubARmZCR+fBx2dDyKjPz+/MzKzLTS1IyOjAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVkICCOZGmKQXCWqTCoa0oUxnDAZIrsSaEMCxwgwGggHI3E47eA4AKRogQxcy0mFFhgEW3MCoOKBZsdUrhFxSUMyT7P3bAlhcnk4BoHvb4RBuABGHwpJn+BGX1CLAGJKzmKjpF+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncontents-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExCNGSenHRmVCwqJPTq1GxeTHRqXPz+/DwyJPTq3Ny+lOzexPzy5HRuVFSWlNzClPTexIR2ZOzevPz29AxqbPz6/IR+ZDyKjPTy5IyCZPz27ESOjJySfDSGhPTm1PTizJSKdDSChNzWxMS2nIR6ZKyijNzOrOzWtIx+bLSifNTGrMy6lIx+ZCRWRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQEAAQCwWBYJiYEAoGAFIw0E5QCScAIVikUgQqNargtFwdB9KSDhxiEjMiUlgHlB3E48IpdKdLCxzEAQJFxUTblwJGH9zGQgVGhUbbhxdG4wBHQQaCwaTb10emB8EBiAhInp8CSKYIw8kDRSfDiUmJ4xCIxMoKSoRJRMrJyy5uhMtLisTLCQkC8bHGBMj1daARgEjLyN03kPZc09FfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncontexthelp-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQChAQCBAAAACH5BAEAAAAALAAAAAAQABAAAAIzhH+hIeiwVmtOUcjENaxqjVjhByaBSZZVl24Y1V6iEVMzkD4bqD700bshgh1fzwd0IfwFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncrop-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMT+xATCBASCBISChPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAM0CLrc/iG+FsQgYapKbp7c4IFCZ2FQOQQE6oSl9Koxabrz/eVDDXat3atAlEEMSKFmyfAnAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndecrypted-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJExGHEQ+FCQiDBwaDBweDGxiLHxyNHRuPIR+RIyGZJSSfFxaRGxmLJyaXNzWpNTOnMzGnMS+jJSKTGReLKyqjPTu1NzarLSufKyibJySXIyGVGxiNFxaXLSytPT29Ozu7OTi5NTS1KyurGxqVCQeDJSSjLS2tNTW1KSmpGRiLKSebOzuzJSOXExONExGLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaVQIBwOAwYA8SkMCAYOAnKYiFAIAQGyOgVCggYuEovVxztMpdnwAGRSCgUCwOjIeQ6HpCIZDKRUNYMRBUWF4UYGRoWGxyBRR0eHxgaICEiIyR0QyUmJygpKgUrAxMsLUQlKyieoKIuEAunK52fBS8DLiywQySpnjC1Mbi6QjIzNBeSIBY1EQfDQgosLAEUNjY3Co1DfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndown-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObCRKZBxCXAwyTKTK3Ozy/NTm9GSivAQWHNzu/FzC3IzO5CySrAQOHAyuzETS3CSWtAyOtETa5Aw2VLze7ByWtBy61BSavAxWdBRCXAwqPAQCBDR+nKTe7FS+1Eze7ByixBRmjPz+/AyexAyixAQKFBRqjAQGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZeQIBwSCwaj0hAYCkYEJLKguGASEADigWj4bgaHpBINykwSCYRa5HCFFQsF0xGo9lwhpSOwfORYC4gISJ3RAQdIyQYJSAlImNrh4uNJkl5CoKUUBQnjlB4KJ6hokN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditclear-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAQABAAAAIuhI+pm+EPnwmi2msDoLgLzQWDV4HlSJof6qki+W0n7LKdCpdyrm/Rr2EIhwp/AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditcopy-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAFxaXPwCBNze3GxubERCRPz+/Pz29Pzy5OTe3LS2tAQCBPTq3PTizLyulKyqrOzexLymhLy+vPTy9OzWvLyifMTCxHRydOzSrLyihPz6/OTKpLyabOzu7OTm5MS2nMSqjKSipDQyNJyenLSytOTi5NTS1JyanNTW1JSWlLy6vKyurAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAaUQIBwCAgYj0eAYLkcEJBIZWFaGBie0ICUOnBiowKq4YBIKIbJcGG8YDQUDoHTKGU/HhBFpHrVIiQHbQ8TFAoVBRZeSoEIgxcYhhkSAmZKghcXGht6EhwdDmcRHh4NHxgbmwkcCwIgZwqwsbAhCR0CCiIKWQAOCQkjJAolJrpQShK2wicoxVEJKSMqDiAizLuysiF+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditcut-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAQABAAAAIwhI9pwaHrGFRBNDdPlYB3bWHQ1YXPtYln+iCpmqCDp6El7Ylsp6ssR1uYSKuW0V8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neditdelete-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPT29GxubMzOzDQyNIyKjHRydERCROTi3IyKhPz29Ox6bPzCxPzy7PTm3NS6rIQCBMxCNPTq3PTi1PTezMyynPTm1PTaxOzWvMyulOzGrMymhPTq5OzOtNTKxNTOzNTCtNS+rMSehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaKQAAgQCwahcihYMkcBAiBpLJApRoOBWgyIKhSEQkFgrBAcr1URiPhKAsDD3QB8RhA3FM0IlLHnyUTVBMSFBUWfl0XGBMTGBcZGodmcQWKjpAbHIgIBY2LHRoempOdjooTGx8giIOPFYofISJ+DyMXI6AfFySyfiUmJSUnKBYcICIpfgELzM3OZX5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedit-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaVMR+RPzKjNze3AQCBMR6RPzGjPyODPz+/MzOzPyKDPyKBPz29OTWzPyGDPyGBOx6BOza1OR2BKROBNSOXKRKBBwOBOzu7PTWxPzizOySZPyCDFxaXOy2lNRyRMxmJCQOBPTm1OzStPTKrMR+XIRWLFxGNCQSBDQyNIRSNDQuJERGRLyqlNzSvIx6ZKRuVEw6LLSyrLymhKSShBwaFFROTJyWjMS+vNzW1OTazNzKrHRqXOzezOTOpPTq3OzWvOTStLyedMS+rLy2pMSynMSulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAewgAAAAYSFhoQCA4IBBI2OjgUGBwiLBAmXlpcKkgsMlZcJBA0JDpIPEBGVjwkSBgOnExSfmBIVBxAMExYXswkYGRobHLq8gh2PHhoeHyAWIYKzIiMkJSYnKCnQg5YNHtQqKywtK9qMBC4vMDEBMjIz2dCMDTQ1Njc4OToz5PEEOzw3ZPToMcLHO23HfogQ0QMIkCA+hPBbhAPHECJFjMyYIUQIvEUpUqwQOXKkSEF+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditpaste-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQiFHRqNIx+LFxSBDw6PKSaRPz+/NTOjKyiZDw+POTe3AQCBIR2HPT23Ly2dIR2FMTCxLS2tCQmJKSipExGLHx+fHR2dJyenJyanJSSlERCRGRmZNTW1ERGRNze3GxubBweHMzOzJSWlIyOjHRydPz29MzKzIyKjPTq3Ly2rLy+vISGhPzy5LymhISChPTizOzWvKyurPTexOzSrDQyNHx6fCwuLGxqbOzKpMSabAQGBMS2nLyulMSidAAAACH5BAEAAAAALAAAAAAQABAAAAa7QIBQGBAMCMMkoMAsGA6IBKFZECoWDEbDgXgYIIRIRDJZMigUMKHCrlgul7KCgcloNJu8fsMpFzoZgRoeHx0fHwsgGyEACiIjIxokhAeVByUmG0snkpIbC5YHF4obBREkJCgon5YmKQsqDAUrqiwsrAcmLSkpLrISLC/CrCYOKTAxvgUywhYvGx+6xzM0vjUSNhdvn7zIMdUMNxw4IByKH8fINDk6DABZWTsbYzw9Li4+7UoAHvD+4X6CAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditshred-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbGxubMzOzPz69DQyNIyKjERCRPz29PT29OTi3IyKhPz27PTu5PTy5Pz6/Pzy7PTq3OzexLyqlPTm1PTizOzavLyqjOzWvOzaxLyifOzizOTOpAQCBOzezAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaEQAAgQCwahcihYMkcBAiBpLJApRoOBWgyIKhWEQkFYYHkeqkMxKFBFpq9jgdkEGlPqwrJhCIY2N8FFRYUFxcYGX9dgRKEGhiHiYEOhBcbGBwdiQEOARcBGwEeAZllAgEUnQEfoQEgmp4hrCKtrwEYsrRlTiMBJAG8syN/IyMAxMXHSH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedittrash-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipFxaXPz+/MTCxISChDQyNCH5BAEAAAAALAAAAAAQABAAAANQCKrRsZA5EYZ7K5BdugkdlQVCsRHdoGLMRwqw8UWvIKvGwTICQdmGgY7W+92GEJKPdNwBlMYgMlNkSp3QgOxKXAKFWE0UHHlObI3yyFH2JwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nencrypted-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJEQ+FExGHCQiDBwaDGxiLHxyNHRuPIR+TIyGZJSSfFxaRFxWJGRiLJyaXNzWpNTOnMzGnLy2hJSKTGReLKyqjPTu1NzarMS+jLSyfKyibJySXIyGVCQeDLSytPT29Ozu7OTi5NTS1KyurJSSjGxqVFxaXLS2tKSebOzuzLSufJSOXExGLGRiTExONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwGCgGhkhkQDBoEpLKQoBACAyOUID1qTVwoQGvMPxNFgVjAxp6QCQUicSCwVgkG44HJCKRRCYUCAxIFRYXhxgZGhYbHINEHR4fGCAhIiMkFSVKJicoKSoFKwMsLZtDLison6GjLA92qCueoAUvpC2xQhWqrLYDErmEMDEXlDIwMxAHukI0NS01EzY2NAmPAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neraser-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAAT+BMTC/AQCBISC/AQChPzCxPz+/MQCBIQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ/EMhJZRA120GwnsEgdh8QiqKXnSi5oqNKsbFWGEYrT8Vx4JydpOf7uSrEIkIISPqWtkIS+pH2qCUptgTYavwRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nexec-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBEQ+PBwaHLy+vMzOzGxqZHx+dKyqnKymnIR+dNTW1MTCxJyOfLySVMSaVMSeVMSebJyWhOSmTOSuVNyubPS+dKSWhHR2dDw+PIyKhNymTNSaTEw+JOy+fPzSnLSyrISChDQyNDw6NMzKzLy2rMyiXGxWLAQCBHRqTPzerNy+lMzGvCwuLAwKDDQyLJyWlNy6jPTGhGxaRGxiRPz2vOTStLy2tFRSTMS+tOzGlPzmtPTixGRiXCwqJLy6tOTWxPTq1MzKxMzOxISCfHRybLS2tHR2bCQmJExORMTCvMTGxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAeogACCg4SFhoIBAYeDAogDA4oAjYQCBAEFBgcICQUBCpODAQsMDQ4PEBGWhgUMDxITFBUUFheDGAYZCA0aGxwcHR4QHwwgISILIyQlGiYnJygpKisEIywALS4vMBoxMjM0KTU2LC2ENzg5wDo6Owo8hT0+Lx8/OztAQR9C1oInQz4FMBAp8sEIhgIEMpwYdASJCwAYkihR5OLGkUUAMmTACK8Hx4+C/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nexit-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBDQyNHR2dCH5BAEAAAAALAAAAAAQABAAAAI4hI+pFrHb3nEg1iWiDiINCwYDko0V9XUTda6I1TIsUMpGinyzbB6ZeGuoEr+GUDL4CXqSphPhLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfileclose-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCQiJBwaHAQCBDQyNDw6PFxaXFRSVERGRCwqLAwODGRiZHx6fPz+/GxqbAwKDCQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVaICCOZGmeqBgEwjCkRGEcSKK4JrEcBrMgAdeLVDg0GguGsYEbBQyGYyN6FDoPDIf0+LCKBIgetQERDgGDBGIpNY8GioAU0m6KXFw883w3+/l9f4AkfimGIn4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfilefind-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBCQmJDw+PBQSFAQCBMza3NTm5MTW1HyChOT29Ozq7MTq7Kze5Kzm7Oz6/NTy9Iza5GzGzKzS1Nzy9Nz29Kzq9HTGzHTK1Lza3AwKDLzu9JTi7HTW5GTCzITO1Mzq7Hza5FTK1ESyvHzKzKzW3DQyNDyqtDw6PIzW5HzGzAT+/Dw+RKyurNTOzMTGxMS+tJSGdATCxHRydLSqpLymnLSijBweHERCRNze3Pz69PTy9Oze1OTSxOTGrMSqlLy+vPTu5OzSvMymjNTGvNS+tMy2pMyunMSefAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe4gACCAAECA4OIiAIEBQYHBAKJgwIICQoLDA0IkZIECQ4PCxARCwSSAxITFA8VEBYXGBmJAQYLGhUbHB0eH7KIGRIMEBAgISIjJKaIJQQLFxERIialkieUGigpKRoIBCqJKyyLBwvJAioEyoICLS4v6QQwMQQyLuqLli8zNDU2BCf1lN3AkUPHDh49fAQAAEnGD1MCCALZEaSHkIUMBQS8wWMIkSJGhBzBmFEGgRsBUqpMiSgdAD+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilenew-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPz6/GxubNTKxDQyNIyKhHRydERCROTi3PT29Pz29Pzy7PTq3My2pPzu5PTi1NS+rPTq5PTezMyynPTm1Pz69OzWvMyqjPTu5PTm3OzOtOzGrMSehNTCtNS+tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ/QAAgQCwWhUhhQMBkDgKEQFIpKFgLhgMiOl1eC4iEYrtIer+MxsFRRgYe3wLkMWC0qXE5/T6sfiMSExR8Z1YRFRMWF4RwYIcYFhkahH6AGBuRk2YCCBwSFZgdHR6UgB8gkR0hpJsSGCAZoiEiI4QKtyQlFBQeHrVmC8HCw21+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileopen-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBOSmZPzSnPzChPzGhPyuZEwyHExOTFROTFxaVFRSTMSGTPT29Ozu7Nze3NTS1MzKzMTGxLy6vLS2tLSytDQyNOTm5OTi5Ly+vKyqrKSmpIyOjLR+RNTW1MzOzJyenGxqZBweHKSinJSWlExKTMTCxKyurGxubBQSFAwKDJyanERCRERGRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaRQIBwGCgGhkhkEWA8HpNPojFJFU6ryitTiw0IBgRBkxsYFAiGtDodDZwPCERCEV8sEk0CI9FoOB4BEBESExQVFgEEBw8PFxcYEBIZGhscCEwdCxAPGA8eHxkUGyAhIkwHEREQqxEZExUjJCVWCBAZJhEmGRUnoygpQioZGxsnxsQrHByzQiJxz3EsLSwWpkJ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileprint-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFRKNAQCBPz+/MTCxExKLPTq5Pz29Pz6/OzezPT29PTu7PTy7NzClOzm1PTu5LSabJyanPTm3FxaXOzCjOTKrOzi1OzaxOTSvJyenGRmZLyyTKSipDQyNERCROTi5Hx+fMzKzJSSlIyOjISChLS2tAT+BDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaYQIBwKAwIBMTkMDAYEApIpVBgOCAOg4RRGlAoEAuGIdGITgWOq4LxcCQgZkEkIHksHgYJOR6ZQCgVFhYJFxgTBVMZihoCfxUYDWUbUBGKGREcjBoQEB2TAB4CAx+Vl5WMhyACHiEhH6IfIiMktCQgE0cZJQStr6O2t6EARxO6vK6iEx4dZsMCxbsmBB4nzUTEutVSSUdmfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilequickprint-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBPz+/ISChERCBDQyNPz+xPz+BFxaXPwCBMTCxAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEMhAq5UYBME7D9kkBMNGjqHmeWBoDhwsEIS7coVx1NhbCrmdzROk9SyU4GEJ2twECISOUNokEopsVrobKCgCrZa73IHFYy4VyZ5WNIO4vBhvse8gfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilesave-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBFRSVMTCxKyurPz+/JSWlFRWVJyenKSipJSSlOzu7ISChISGhIyOjHR2dJyanIyKjHx6fMzOzGRiZAQGBFxeXGRmZHRydGxqbAwODOTm5ExOTERGRExKTHx+fGxubNza3Dw+PDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaAQIAQECgOj0jBgFAoBpBHpaFAbRqRh0F1a30ClAhuNZHwZhViqgFhJizSjIZXQCAoHOKHYw5xRBiAElQTFAoVQgINFBYXGBkZFxYHGRqIDBQbmRwdHgKeH2YgHpmkIR0HAhFeTqSZIhwCFIdIrBsjAgcPXlBERZ4Gu7xCRZVDfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfill-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBMT+xASCBMQCBATCBPwCBIQCBISCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARSEMhJq50hXBvE0JsUEMXwhYFBmOeVDsVqgpS6luRc32RR6hLCTSCQ/VqEwwDhK5Z+Ao3wEPAViL6BR6PSZKyCa6uLAbcAZEznLDHQ1BZDiOKPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilter-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipMTCxISChMTGxAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM3CLrcDiGGt6IQQ7pI8PjSVHUeqFVBNxRfFjXSZYqwENoUNFx4rve+wI6WEwKLQ5/CSCw2lQ9/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfind-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1ISChOTy9Mzq7Kze5Kzm7HyChOT29Oz6/Nzy9Lzu7JTW3GTCzERCRLza3NTy9Nz29Mzu9Kzq9Ize7HTGzHzK1AwKDMTq7JTi7HTW5HzGzKzS1IzW5Hza5FTK1ESyvLTa3HTK1GzG1DyqtLzu9IzK1AT+/Dw+RAQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaSQIAQEBAMhkjBUEAoGA4EJXKJSCQUC0ZDCmg0hATHAxKRTCIEYYMiMFYsF0xGs+FUOl0BJRAweCIRHyATIRhpRAEAHSILIyQgJSYhJ4dIBBEoISkmKiuVSQgRIyEsEQgELVNCLgQVCiJRLQSfli9pMAQxMrRcQ1G6tAC9AL+7al+qxALACG1Kw8oxBGt7yWBpfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfinish-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAwyTBRObAw2VDR+nAQCBCRKZOzy/KTe7Pz+/KTK3Nzu/Lze7FS+1AyexAyuzBSavAyOtBSmzOTy/BRqjNTm9IzO5ETS3ETa5By61AyixByixBRmjAQGDBxCXGSivCySrCSWtBTC3AQOHAQWHAxWdEze7AQKFBRCXAwqPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZtQIBwSCwahYGjUjBQGgWE5LCgNBwITSFVKOgKDAZEIqodChSLw4HRcIyTW4Dg0HhAIhGIZEIJxA0VFhcYGRAaGBscHXEeHyAhIQ4iiBwjAHEBJCMjJCUmiSdlRyigU0oolURxRSmrTpevsUN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nflag-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBMTCxPz+/MQCBPzCxPwCBAAAACH5BAEAAAAALAAAAAAQABAAAAM5CLrcruG9QCULokqKR44NJQykQGgXSRaEcYJLsLLu6wSFoRMvCuk1kO9ni8GMt6MForQMl89NxJ8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_new-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBPz+hPz+BOSmZPzSnPzChFxaXMTCBPyuZPz+xPzGhEwyHExOTPz+/MSGTFROTPT29OTm5KyurDQyNNza3Ozq5Nze3LR+RLy+vJyenMzKzNTS1Ly6vJSWlFRSTMzOzMTGxLS2tKSmpGxubBQSFAwKDKSinJyanIyOjCQiJERCRERGRBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaNQIBwSCwaj8ikcokMCIqBaEDoBAQG1meAUDAQpIcBQoy1dg2JdBqhECgQ1IWB0WgcBIOBwIHXBwwPEBEREhIBbG4IExR/DBUVFhIXV2NjDVYYDY8SFU4ZVxpVAQwbGxynGxkdTh6XVh8gGSGzGSITIxokJUImGSMTwLcnKCkprgAqDSt1zCssKxQtQ35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nforward-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAwyTBRObAw2VDR+nCRKZOzy/KTe7Pz+/KTK3Nzu/Lze7FS+1AyexAyuzBSavAyOtBSmzOTy/BRqjNTm9IzO5ETS3ETa5By61AyixByixBRmjAQGDBxCXGSivCySrCSWtBTC3AQOHAQWHAxWdEze7AQKFBRCXAwqPAQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZjQIBwSCwahYGjUjBQGgWEpHNYMBCaT4G2UDggos+EwmBYMBpf6VBgYDgeEMgjIpmoAQVKxXLBPDIXGhscRB0eHyAgDSGBGyJFASMiIiMkJYImUwAnmJqbjp4AKCmhAKSlTn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfrac-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBAQGBIQChCH5BAEAAAAALAAAAAAQABAAAAInhA9hig0SAmQOxeouPrFTzHzbCAzmiZ4k2S1ryHKsoo3tptXg3fgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nframeprint-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFRKNAQCBPz+/MTCxExKLPTq5Pz29Pz6/OzezPTy7PT29NzClPTu7PTu5PTm3LSabJyanOzi1FxaXOzCjOTKrOTSvJyenGRmZLyyTKSipDQyNERCROTi5MzKzIyOjLS2tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaPQIBwKAwIBMTkMDAYEApIpVBgOCAOg4RRGlAsEAqFIcGITqnWRcPxSEDMgkhAonA4DO3yMD6BUCoSCYIWEwVTF4gYAhAMFRUMZRlQEYgXERqKGBAQG5IAHAIDHYiUEUcDpwIcHh4doR0fH02zqAIXIASsrqi0TQBHE7e5HqG0Zr8CwSC9qFJHxbRSU7W1fkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ngear-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChMTCxDQyNFxaXKSipPz+/CH5BAEAAAAALAAAAAAQABAAAANdCLobwbAFMciLwBFSihBEFHSG8QnmpQQEBX6loI5G5QTlcMgrZSmEmsGxKqRWNV3hMrFlBtDoA1eTEaKHJdMYhR6+gxkF++UMGbiDzvDVioyHAJSHcchuGLQq4k8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ngohome-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBDw6PBQWFCQiJAQCBFxeXMTCxJyanDwyLDQqLFRSVLSytJSSlISChCQmJERGRFRWVGxubKSmpJyenGRmZLy+vOzq7OTi5Ly6vGRiZPTy9Pz6/OTm5ExOTPT29BwaHNza3NS6tJRqRGQqBNy6pIyKjDwGBPTe1JSWlDQyNOTGrNRiBGwmBIRaLNymdLxWBHxGFNySXCwqLKyqrNR6LKxGBNTS1NTW1Jw+BEweDDQ2NAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaoQIBwCAgIiEjAgAAoGA6I5DBBUBgWjIZDqnwYGgVIoTGQQgyRiGRCgZCR1nTFcsFkHm9hBp2paDYbHAsZHW9eERkYGh4eGx4ag3gfSgMTIBshIiMkGyAlCCZTEpciJyQjGxcoKUQBEhcbIiorLB4XEltDrhcaLS4vtbcJra8bMDHAGrcyrTMXHjA0NSypEsO6EzY3IzU4OdoTzK0BCAkDMgkIOjJlAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ngoto-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBEQCBAAAACH5BAEAAAAALAAAAAAQABAAAAIohI8RyKciVnMwTlrlDfkm5QFgaHBWMo0lp22dZ57wO8vpGrLk2iJ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nhelp-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQ6XAQCBCyCvARSjAQ+ZGSm1ARCbEyWzESOxIy63ARalAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ/EEgQqhUz00GEJx2WFUY3BZw5HYh4cu6mSkEy06B72LHkiYFST0NRLIaa4I0oQyZhTKInSq2eAlaaMAuYEv0RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nhistory-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBEQ2LEw6POTSrOzWtNS2lAQCBOzatPTm3PTq3MyyjEw+NOzm1Pz29Pz+/Pz6/Pz27FRGPFxKRPTu3Pzy7Pz69Pz67KSGbPzy3Pzu3PTizPzu1Pzq1PTmzOzaxPTixPTmxOzWvOTOtKyWdOTGpOTStNS+nIRmVLymhNzCnOzavLyefAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIBwGCgOj0jBgFAwGJDJAyJBUDihwgWj4XhAqhEJNDKhVLwUSUDyPJIrlgYlLSG0hYELhgLJTBJOd1kaGxgYHB0egkQfHBwgHyEigkUBIwMkBwcEJSZ3ARYWJCcnKCYpJJ5HAQUqFhSjJysoKItOCgehJBISI4tCtyERa79HTrx2WEiBUH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nidea-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+BPzerPz+xPyqXPz+/ISChFxaXKSipDQyNAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARMEEgZap14BjG6CJkmEMVQCF+4mQPBpthWtuYJxkJJGK6dbQRCgMBB3XCDzQamMhpDGlvuCFUyoQDLBUsJHBDUKuKQCKsUCIVZtc34IwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nint-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBIQChAQCBAwODAQGBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCKqx/iw0CNukzuJ8d1yCAAziIyliCKjck1ZuaV4igZ1r+raongE4j8YT6QiJC38CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nlocationbar_erase-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAIshI+py40Bo1SywgSFiDq+oG3hZHDhVpUmagFrl7pgN3oqPNuqpe+8Awwi/AUAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlock-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJEQ+FExGHCQiDBwaDGxiLHxyNHRuPIR+TIyGZJSSfFxaRFxWJGRiLJyaXNzWpNTOnMzGnLy2hJSKTGReLKyqjPTu1NzarMS+jLSyfKyibJySXIyGVCQeDLSytPT29Ozu7OTi5NTS1KyurJSSjGxqVFxaXLS2tKSebOzuzLSufJSOXExGLGRiTExONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwGCgGhkhkQDBoEpLKQoBACAyOUID1qTVwoQGvMPxNFgVjAxp6QCQUicSCwVgkG44HJCKRRCYUCAxIFRYXhxgZGhYbHINEHR4fGCAhIiMkFSVKJicoKSoFKwMsLZtDLison6GjLA92qCueoAUvpC2xQhWqrLYDErmEMDEXlDIwMxAHukI0NS01EzY2NAmPAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nlsub-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBIQChAAAACH5BAEAAAAALAAAAAAQABAAAAImhI+pFu2+QpxKVppsxkh3fnhh9DyGcC6IwLbqir4HK58tLcfx6xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlsup-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBIQChAQCBAAAACH5BAEAAAAALAAAAAAQABAAAAIlhI95YawYonwp0uoukFO7rCXCSJKPcKYKuqqii7BvS892XJZ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmail_forward-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRydHxubHxmZGxiXHRmZFxOTFxGPFxKTPwCBLymlMy+pOze3PTq3PTu5Pzy7LSmnOTaxOzm5LyqlNzOtPz69Pz27MzCtLyqrPT27IRubPzuzNTGvNTCxLSelPz25Bw+ZFxKPPzy1Pz65LyupBxKdCxWfPTm1Pz23LyinBxGbGzO5DRafBxWfBxajCymxHTS5BxSdBxKbFTK3EzG1CSGvCyKvCSSxCSavGTO5GRaVPzqzFzK5EzG3BSCtAwiPGxaVPTivPzy3NzKpBxObCRefBxqlPTmzJR2bKyahAwyRPzmvOTOpKyObNS+nPz21AQOFKyOfPzuxAQCBGRORLSadPzyzLymjMy2lOzetDwuJFRCPEw6NEQ6LEQyLEQ6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAAAQABAAAAfhgAABAgIDBAQFBgcIBwmOCQIKCwwNDg8OEBESjY8CDBMUFRYVFxgZDJyOGhsPChwVHR4fFSAhjwkaIiMOJBQQDRUVJSa3GicoHw4pEA8SGSorLI8tLtQu19gqLzDECTEyMzQ14zY1Njc3ODkqCTo7MjIxNCs5PD03PjctPwlAQUIihhBpQbCIihtG+CUocASFkAhIkogQ8kFJwkcFlogIkoRJEydPnkBR6GiAxiQLgiiIIkXElFQJqESoMsRKkAhXqkhhApNKFSxZggTJ4nHIEJhaDhzYwoVLFy1avHyB6ScQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmail_generic-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBGxaVOTe1Oze3OTWxOTWvNzStNzKpEQ6LOTezPz+/Pzy7Pz69Pz27Pz25Pz21PzuzPzuxEQyLLyinLSmnPz67Pz23LSafKyObDwuJMzCtLSelPzy1My6nLymjNTCxLyqnPzq1LyihKyOfOzavOzetEQ6NPTq3NzOtLymnNTGxJR2bOTOpPTivNTGvLymlKSShKyahEw+NOTe3PTm1Pzu1Pzy3FRCPPz65LSadFxGPOzm3PzqzPTmzPzmvEw6NCH5BAEAAAAALAAAAAAQABAAAAaqQIBwSCwaj8ikMhloOp/QpmAgqAoIhELBUDgcEIGEYrFgNBoLx+IBiRwkgQnFoWAwKhWLhX3BZAILGhsCDXgODhwdGB5vgAofICBlDiEiIx4kJSYBJ2UoEykqHSMrLC0nLWAnFS4UCycvMAcEMR0RLTIBMwaSahw0NTYtFwclNwEdLws4eoc2DxwQOR06ASk7PBAhIRE9Pj0tLSUY1T8I5gjn6Qgy7D8SfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail_get-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAxKdBRSfCyGvFSm1BxKfCSWzCyWzBRCXCRKfBwuRAQGDDw6PHy23Cym1CSSxByCxBxunBQSFKyurMTCxExihNza3NTW1JSSlMzKzFxaXLS2tNze3KSipCQmJGxmbNTS1KSepLy2vISGhJSWlHx+fERGRPz6/IyKjDw+POzq7JyenMzOzKSmpCwuLDQyNIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQIBwGBAIAsOkUjAgFJRQQMHgjC4PBIEVgAh4D4aEYrGAMhINxwPyiCgYSsmEUmk82grLRZJkYCgXaAEKFxYZcEISGhsZFxwFeY0WHR5CDB8dGCAXG5shGxQicBIMpSMUGxgTGSQlpQwSJicnEwwdI7gdKAwTsykpKiobr8QMKxeHDBcsGRvOzxsT0i0uL9HSHdkT2ZkoMJXF4a8AfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail_replyall-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTFRCPFxKTFxGPPwCBLymlMy6pOTa1PTq3PTu5Pz27Dw+POzi3PTm1OTWvPz25FRSVERCRLympPzuzPTu7NTGvFxaXKSmpPzu1Pz65Hx6fHxqZPzq1Pz23HR2dBw+ZHx+fISChJSWlDQmJHRydCxWfBxGbJyenExKTHRiXPzqzPzy3CQmJDRafGTO5ExOTERKTGxWVCRSfHTS5CymxBxajBxWfPTmvPzy1CyixCSaxCySxDSaxDSWxDSSvDyaxGS21PTmzPz21AwiPBRejCSavByGtCSezEzG3FzK5FzG3GzO5FTK3CQ2bPTixBxqlCRefBxSdBxSfBx2nCQ+dHxmXPzmvLSafAwmRAwyRPzyzDw6POzavNzKpAQOFPzuxBwWTBw2ZGRORLyWdMy2lOzetPTivAQCBKyObOTOpAweNBwWVEQyLEw2LEQ2LDwuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAf4gAABAgMEBQUGBwgJCguOCwEMDQ4PEBESDA4TjY8DFAwVERYXGBkRm4+QGhsMHB0eGB8bDpyOARogEBceIRgXv8COIiMkGB4lJSYnIcwoKb/DGyoXKywtKS4pHinMLzAxJDIzNDUtNjcv6B0hLzgfMh85OjstPDw99zwd7T4/LTVAgggZQqSIECNHevSAgSSJkiVMmjh5AiWKlClAiFARUeVHFSVWmLS40gNLlh5agGzh0kWDlwZfrIDREKaCAjEqrFA5MMYLmTAxlJTxYoZMozNozqRRs4ZNmy5s3LwhA0dBnDNn5MxBoAABnTp17IitowDrmQV+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail_reply-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTEw+NFxKTFxGPPwCBLymnMy6pOTa1PTm1Pzy7LymlOzi3HxqZOTWvPz69Pz25My+tLympFRGRHxuZPzu1LymjNTGvNTCxBw+ZPz23PzuzPz65PTu5NzOtCxWfBxKbPzq1DRafGTO5BxGbPzy9HTS5CymxBxajHRiXPzqzCyixCSaxCySxDSaxDSSvGS21GxWVAwmRBRejCSavByGtCSezEzG3FzK5FzG3CQ2bPzuxAwiPBxqlBxKdCRefBxWfBxSdBxSfBx2nCQ+dPzy1CRqlAwyRDQmJPTmvPTixLSafOTOpAQOFPz21BwWTBw2ZPzmvNS6nPTivAQCBAweNBwWVNzKpPzyzLyihGRORLyWdMy2lOzetKyObEQyLEw6NEw2LDwuJEQ2LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAfqgAABAgMEBQUGBwgJCguOCwEMDQ4PEJYRDhKNjxMPDBQVFhAXGBUSGY8LGhsQHB0VHh8gFQ6bjgEhIiMMJCUmFbS2CwMnG6IoKSorI7WpEycWFiUsLSou1yXXji8wFiopMTIzNDUz4zbZNxsbODk6Ozw9Pj8pPzEzQDdB60JDOkRFjBw5giRJDCWdlmxwIIRJExAWKDRyMgTIiydLoESRImQKlSUSF1SxUoXAlSBRsGSJoCVICIlbqlThcoBClC5eYFD4EiVIFwUyqywAE0ZMlqNjpJDpIkUBl0dlFChAYOZMmTJoyqQR5icQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmail_send-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTFRCPFxKTFxGPPwCBHxqZLyqlMy6pOze3PTq3PTu5Pz27Pzy7LyinOTaxOzi3Ozq3LymlOTOtPz69Pzy5My+tLympPzqzNTGvLSelPzy3BxGbBQ6VPzuzPz65LyupNzOtPz+/GzO5BRejPzq1Pz23LymjHTS5CyixCSavBxqlPz25LymnGTO5CymxCSaxByGtHRiXPzy1CySxCSezGxWVPzuxKyOhMy6nDSaxEzG3PTivNzKpKyOfPzu1FzK5PTmzJR2ZLyihLSWfKyObOzmzPzmvDyaxOzavLSafGRORMy2lOzetDwuJEw6NEw2LEQyLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAfUgAABAgMEBQUGBwgJCguOCwwNDg8QERITFBUWjY8DFxgZGhsaHB0aD5yODB4TGB+kICEaIiOPCwEkJRcmJyYPKCIpKrWqKywTmC0SIi4vMDHEDCsyMg8zEyI0NTY3z7U4Hhs5Mx+0IyI6OyPrIzw9Gys+PxIy2EBBxAs8Qjk5Q0RFWFxAZySfgSMsilRAkiRECHQ08hHgJ0TJkCU/mECU2ISEkowUlpAQ4QTfowNPoAzJIeRJCyjm8kVRIkWIzSkXhwxJtYAKgp9VrFi5QoWKFZ5+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmatrix-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBIQChCH5BAEAAAAALAAAAAAQABAAAAIrhI9pwQHt4Jru2Vsjna919lXKeEimh6UZp1lrCEvkfILyirOby3q1OEv4CwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmisc-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChMTCxDQyNFxaXKSipPz+/CH5BAEAAAAALAAAAAAQABAAAANdCLobwbAFMciLwBFSihBEFHSG8QnmpQQEBX6loI5G5QTlcMgrZSmEmsGxKqRWNV3hMrFlBtDoA1eTEaKHJdMYhR6+gxkF++UMGbiDzvDVioyHAJSHcchuGLQq4k8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmove-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhA8RyKja2HtRrmrxNfDszm3JMpXmiULg6Hyto4kYO49Tfdc04xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnews_subscribe-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/ERCBDQyNAQCBPz+/FxaXIQCBMQCBKSipMTCxATCBMT+xISChASCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARsEEgZxLxYDlJsvsJGDN0nFQRhpKR3DSJxrGMphYQgpDI9WLhdTtjjAFApXZI30m2UQwICVigcEzzolKAYIAIFBAKbQjQX3YGGISZvFtzFQr1uDxT4PH0yYE8FCg0/Jn0MAwsNOiY3IQMBEn4RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnews_unsubscribe-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/ERCBDQyNAQCBPz+/FxaXIQCBMQCBMTCxPzCxKSipAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARiEEgZxLxYDlJsvsJGDN0nFQRhpKR3DSJxrGMphYQgpDI9WLhdTtjjAFApXZI30m2UwxjsiOApB4kNLFtQKKopxeCQxR4GAJIXPCInzmhN9zvCljNq8ZvswmzhZHEfOhpofhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnext-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFwyXAQCBOze9BwCHNx21LQCvPSi5NRi7AAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ3EMhJqwUhAMG7DQOxdVwFFuI1nYZIethwIK0aFwjtwrfh15cAYUjcvWyvkm1Z4TGfkyN0avFHAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nok-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBMT+xATCBASCBARCBAQCBEQCBAAAACH5BAEAAAAALAAAAAAQABAAAAM2CLrc/itAF8RkdVyVye4FpzUgJwijORCGUhDDOZbLG6Nd2xjwibIQ2y80sRGIl4IBuWk6Af4EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nopenterm-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXFRSVPz+/PT29OTm5OTi5DQyNDw+PERGRExKTHx+fISChIyKjHRydFxeXDQ2NCQmJBQSFAQCBERCRMTGxHR2dGRiZExOTDw6PCQiJAwODCwuLFRWVOzu7BweHAwKDCwqLHx6fBQWFGxqbGRmZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAanQIBwSCwKAwKkMslEAgSDqDRKqBYKhkNgcDggEorkMrDQchkNhuOhgEQkk0l5S2lUGpYLJqPZTAwMHB0DCmhqAW0Rfh5zAxgOkBcCFAcfIBMECxwBBAEPFw8dChkhcBMDDAcdnQqtFKSWcQMimx4dGRkQBxGxsg6bBQEawx8jl3GnJFoFHRNXVVNRJYIFDAsL1tgiDiQXFx0HABwcXeQH5OjkRutEfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npaintbrush-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTC/AQChPz+/MTCxKSipDQyNCH5BAEAAAAALAAAAAAQABAAAAM7CLrMIS2qN2Sj1U4xugaYZxFE1wUaURQnKpFBYQTuFRiyXDsCd8y7RYhmCQ2IkiHywmkFN84ibfrxJwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nparen-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAQABAAAAI3hI+JEQq8mnvyzSOhEWJ3CgLcOILV4IlfUx1cwirfYiEvXL83arANSer5UipM5tIzXjRCh8ZfAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npencil-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/IQCBMQCBPzCxAQCBPz+/MTCxISChDQyNKSipEQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARDEMhJZRBD1H2z3lMnjKCFjUJQimOgcmcbELCXzjXq0hV785WCQYcDFQjDXeloMByKG6YTAdwIDAlqSZJSVFeKLcUfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplayer_eject-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+py+0R3IFQUtruXVqn3kkWyIARR4rqKvoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplayer_end-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+py8Eb3ENRggrxjRnrVIWcIoYd91FaenysMU6wTNeLXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplayer_pause-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+py+1vgoxzyUCxrZd18ClfmIyVyJ1lqkHuC0N+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplayer_start-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pyxudwlNyguqkqRZh3h0gl43hpoElqlHt9UKw7NG27BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplayer_stop-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+1vgpySUWpvXXqrHmSaeJEYhKYq6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nprevious-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBFwyXOzC7PTq9OTK7IQyhBwCHNRi7LQCzPSi5IQ6jLwKzORy7AAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ8EMhJKwg4W5o1EGAIbt8wEERhHJ0mIEmiLAH5IYxi1JcnvTOeTdDYcVo1gfHY+hxs0IkvSpV2qtgswB8BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nprod-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBIQChCH5BAEAAAAALAAAAAAQABAAAAIihI+py50Bo4SKHlsDwk9fn21gJzIcV37miKpuZ0nOTBt+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nqueue-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBMTC/Pz+/CH5BAEAAAAALAAAAAAQABAAAAI5hI+pFrEahGgPtCinS2GMlknU0Xkflm2l6YEiw8aRGssTXLe3lZsznvuRViwholEcLZCfynGT8BcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nredo-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBxOHBxSHBRGHKzCtNzu3MTSzBQ2FLzSxIzCjCSKFCyeHDzCLAxGHAwuFDSCNBxKLES+NHSmfBQ6FBxWJAQaDAQWFAw+HDSyLJzOnISyjMTexAQOBAwmDAw+FMzizAQODDymNKzWrAQKDAwaDEy6TFTGTFSyXDyKTAQCBAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ2QIBwSCwaj0hAICBICgcDQsEgaB4PiIRiW0AEiE3sdsFgcK2CBsCheEAcjgYjoigwJRM2pUK0XDAKGRobDRwKHUcegAsfExUdIEcVCgshImojfEUkCiUmJygHACkqHEQpqKkpogAgK5FOQywtprFDKRwptrZ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nreload-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCRaJBxWJBxOHBRGBCxeLLTatCSKFCymJBQ6BAwmBNzu3AQCBAQOBCRSJKzWrGy+ZDy+NBxSHFSmTBxWHLTWtCyaHCSSFCx6PETKNBQ+FBwaHCRKJMTixLy6vExOTKyqrFxaXDQyNDw+PBQSFHx6fCwuLJyenDQ2NISChLSytJSSlFxeXAwODCQmJBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIBQGBAMBALCcCksGA4IQkJBUDIDC6gVwGhshY5HlMn9DiCRL1MyYE8iiapaSKlALBdMRiPckDkdeXt9HgxkGhWDXB4fH4ZMGnxcICEiI45kQiQkDCUmJZskmUIiJyiPQgyoQwwpH35LqqgMKiEjq5obqh8rLCMtowAkLqovuH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nremove-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/PwCBMQCBEQCBIQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMuCLrc/hCGFyYLQjQsquLDQ2ScEEJjZkYfyQKlJa2j7AQnMM7NfucLze1FLD78CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrevert-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAAQCBPwCBPz+/PTizCQeHDQyNBweHAQGBAwKBDQ2NPzu5PTi3ERGRCQiJHR2dPTi1CwqLPz6/Mya/Mxm/GQCzFRWVGRmZAwODFxeXExOTExKTERCRBQWFMTCxKSipMzKzCH5BAEAAAEALAAAAAAQABAAAAV9ICCOQWkGIiqsQloCKCqy7UC8MC4URSsMhsDBNWOJEK4TYJfoGU8vmmJBGI5SyyYj0XDQjMvVQwBxRCQTilowFGwrjG5kTo+0x4OdpcLvV0YXIhcGGH0ZFRobOSccfB2PHR4FiyYAGQwdAI8eEAdQKBsZmR+RBpSVVyMHfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nrotate_ccw-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBFxaXIQChEQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM0CLrcHjA6JcK4ET68MrNDoIgjOYbdJ4IXagIa3IqVFAMEOqpfn067ErBxG0qGsCJyyQT4EwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrotate_cw-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBIQChFxaXEQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMzCLrcHjA6FaG4YbS6At5BR31UKI4mADGhd31rpbmCuZ6qQLA8XvqT2+QhHLKKxqSy4U8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nrotate-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBFxaXIQChEQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM0CLrcHjA6JcK4ET68MrNDoIgjOYbdJ4IXagIa3IqVFAMEOqpfn067ErBxG0qGsCJyyQT4EwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrsub-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBIQChAAAACH5BAEAAAAALAAAAAAQABAAAAInhI8Jwd26YJBUTVvT1Rlt3x2f6DjQeQiGigLCC7crK7+yC9sty/oFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nrsup-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBIQChAQCBAAAACH5BAEAAAAALAAAAAAQABAAAAImhI+pGtZ7gpwQyWofnnQ7I4SiuAjlqZgpmqgti7gxfMh1OY6LXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nrun-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/ISChKSipMTCxLS2tLy+vMzOzMTGxNTS1AAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARlEMgJQqDYyiDGrR8oWJxnCcQXDMU4GEYqFN4UEHB+FEhtv7EBIYEohkjBkwJBqggEMB+ncHhaBsDUZmbAXq67EecQ02x2CMWzkAs504gCO3qcDZjkl11FMJVIN0cqHSpuGYYSfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsignature-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAFxaXPwCBAQCBDQyNPz+/KSipERCBAQChISCBMTCBPz+xMTC/AQC/MTCxPzerAAAACH5BAEAAAEALAAAAAAQABAAAARwEMhJZwgCiM17DoMkEGRpAmGhmSxhAOrakim6DgeLJApRhCPCgJRT8AhGEVFIQigAxgSQsBgwms8oIrDKDZNGxJY7GuYQULHhQj4shAmAuNAQsFc9xY4uUNgvMiQOBIMOfncjeUhICocXAx6RfwF+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nspellcheck-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPzCxPwCBMQCBIQCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLrcGuHBNZ+NIOJ9O4MTaH2e1nDoiFYZJjgwIAzwy8yEgy84RhWDQa4HCwAHxJgxSPApC83YyQnwJwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsqrt-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBIQChAQCBAwODAQGBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMyCLrcDiHK6eIL9WmsmwWCAAyiwkGKGILihzLq8p1s9onE9a48Iy28ko/WgRCLyGTDnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nstamp-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+xMTCBISCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANCCLrR+zAIMQKMguh6GR2g1QEBCBLiGGjo+DSpS3IqXNqxNAnwzisSk3BowRltM8IAZVMqi84lLNoqUVfLrOhoVPgTACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nstart-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRSdBRObCQ2TAQCBBxObISevNzu/BRGZPz6/FzC3Pz+/HTS5ByyzJze7Mzq9ITC3AQWLAyWvBSavFyuxAwaLAQSHBRWfBSOrDzW5AyixCS61ETW3CzG1AQeLAweLAxefBSStEze7CSWtCyatBSCnAwmPBRWdByixAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZrQIBwSCwah4HjUTBQEogFw/M4BQgMh2pxijAkFAhBYJwUPq8LRsPxWDwgkSHhelA0JJIJnlKRWy4YGRoSGxwcHRsecgAfICEiGhMjJBglVVMRgBkgJp0El0MRJyhaRFqipUoAFqmqrapHfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nstop-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/Gw6NGQuLHQ6NGQmJFweHFQaFPTm5PTa3PTW1Oy+vOS6tNSinKReVDQWFPz+/Nx6fNyCfNyGhNR+dMxybMRiXLxGRIwWFNx2dNx+fNx2bMxuZLQWFBwWFPTu7Pzy9NRqZNRuZMRSVLwmJGwWFNR2dMQiHPTKxMxmXMQyLMxmZNx6dMxiXMRSRMRaVKxybMxaVEQWFMQuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaaQIAQEBAMCAWDYcgkHhAJxYLRcDQBggckIplQKpaLdRh4YDIaSWa94Vw6woAHgv6AMKGPaMQhwQMJJRkfhHmEJhdvRCcgGSCEkCgpbnAECiorGYYfLCItlAAFCygQj5AfbYlwBQwVE5AukG6KBi8tMC0fLi0pHxyzcAAxFxwmMny/wEwOxMm/qlcdJCSJ1H5XQh3a28HY3kx+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsum-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBIQChCH5BAEAAAAALAAAAAAQABAAAAIdhI+py60BowyPJriwQ3qb7oGNyJCZtZHixHpu4xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_block-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py40Bo5SOzRvrwlgrfnkJOIkPaaaJXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_bold-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIihI+py70BowPQ1HZpwNv212Vg9IGHmIjoWa4ey5DSRNd+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntext-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIlhI8Jwe2/AmpTynqPTXSqrnBM+I0kdmpmGmUp+K4nPMvhYx9+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntext_italic-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+0BgztwUmmjBXX3jE0auHHhM5Yq4xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_under-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pu+FxXoOIKpds1oBH7hlYxYxRCaIZ01lhJbHy9tTv7BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntoggle_log-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBATCxMTCBPz+xPz+/ERCBASChISCBARCRAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEIQJqpXBBjFI1oGncYU4EUXxSWQZlum6DXDQpeo0tR6KqqgdLXiLBWepHgyYIxF/TKHv9XvtDDfb0So5YHuTgThYCXgH4Q6hqvEGEIm4PLGSyHX4OkZv8UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntop-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBBRObAQSHBRSdISevBRWfAweLNzu/BSOrAQWLPz6/FzC3DzW5BxObHTS5ByyzAyixEze7BSStBRWdAyWvByixCQ2TBRGZJze7CS61BSavAxefMzq9ETW3CSWtAwmPPz+/CzG1ITC3FyuxBSCnAQeLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZjQIBwSCwSA8ik0kgUDJhGQsFwgA4FBUTCoLBiF4zGtmt0FBYPSEQyoZCvWQakUok0LISnkHBBYjIVGhscS0UGHRUeHyBWAAIhiYuNAggVIgmMVgYjJBolAZMKJgpIjaanRH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntransform-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTCBPz+/Pz+xFxaXAQChAAAACH5BAEAAAAALAAAAAAQABAAAANOCLrcEDAGt4K4F46wmcVCQIzE4F1DukksehVkiUlDYcdfCAyEGI+D2aP3G+UmPF/MAJpwnpuNgMmcKHKgabWSvRi+ums3a32wzmWKw58AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nundo-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBxSHBxOHMTSzNzu3KzCtBRGHCSKFIzCjLzSxBQ2FAxGHDzCLCyeHBQ+FHSmfAwuFBxKLDSCNMzizISyjJzOnDSyLAw+FAQSDAQeDBxWJAwmDAQOBKzWrDymNAQaDAQODAwaDDyKTFSyXFTGTEy6TAQCBAQKDAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ1QIBwSCwaj0hiQCBICpcDQsFgGAaIguhhi0gohIsrQEDYMhiNrRfgeAQC5fMCAolIDhD2hFI5WC4YRBkaBxsOE2l/RxsHHA4dHmkfRyAbIQ4iIyQlB5NFGCAACiakpSZEJyinTgAcKSesACorgU4mJ6uxR35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nunlock-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJExGHEQ+FCQiDBwaDBweDGxiLHxyNHRuPIR+RIyGZJSSfFxaRGxmLJyaXNzWpNTOnMzGnMS+jJSKTGReLKyqjPTu1NzarLSufKyibJySXIyGVGxiNFxaXLSytPT29Ozu7OTi5NTS1KyurGxqVCQeDJSSjLS2tNTW1KSmpGRiLKSebOzuzJSOXExONExGLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaVQIBwOAwYA8SkMCAYOAnKYiFAIAQGyOgVCggYuEovVxztMpdnwAGRSCgUCwOjIeQ6HpCIZDKRUNYMRBUWF4UYGRoWGxyBRR0eHxgaICEiIyR0QyUmJygpKgUrAxMsLUQlKyieoKIuEAunK52fBS8DLiywQySpnjC1Mbi6QjIzNBeSIBY1EQfDQgosLAEUNjY3Co1DfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nup-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObAwSHBRSdISevBRWfAweLNzu/BSOrAQWLPz6/FzC3DzW5BxObHTS5ByyzAyixEze7BSStBRWdAyWvByixAQSHCQ2TAQCBBRGZJze7CS61BSavAxefMzq9ETW3CSWtAwmPPz+/CzG1ITC3FyuxBSCnAQeLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZfQIBwSCwaj8hhQJAkDggFQxMQIBwQhUSyqlgwsFpjg6BwPCARySSstC4eFAqEURlYhoMLBpPRUDYcHXt7RgUeFB8gIU0BIoiKjAcUIwiLSQUkJRsmGIwJJwmEU6OkfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nview_choose-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMzCLrcGlAs6UAYgwLdLtEcI4ygQo7VVp2oupGpG4vmaUVTemX523qlFcw0a4RqNlkx5k8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nview_detailed-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMmCLrc/i1IAVkYg1Z1iRYUKCqitp1oikqBWV3ZOnhkWNagqu+qnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nview_icon-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCLrcG1AwGOQbw6qANeCEB3pCSZpO6pgowJZqLKuUGE0dnuEhf8IL1kz1shSHDX8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmag--16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ+QIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6eUAFCusJSzr7Kmpl0CtLGLvbW2Zn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmag-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ8QIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6eUAFCusJSzr7GLArS5Q7O1tmZ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmag+-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6cAsLECrqeys7WxpqZdtK9Ct8C0fsHAZn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nview_multicolumn-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCLrc/ixI0WSgKoyBl+beQFACpo1AqXbKCr1wLAMWS08hGG3dSZqin4sxnBmPD38CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nview_text-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIchI+py40BTQSwuovp3DXkv1ia1IHmIXLiyWJ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nview_tree-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBDQyNPz+/PzerAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAMuCLHcri4yGISlj4kxcANgNRBQCIbL6U1Su7bB62rXvGydG25kqpwfIGxILBr9CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nwindow_fullscreen-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBNTW1MzOzMTGxLy6vKyurJyenHR2dOTm5Pz+/IQCBOTm1Pz+9Pz+7Pz+5OTmzOTmxOTm3Pz+3OTmvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVuICCOZAkEaKquqzAQRWEYR32gSK7vO5oowKAQmPAtjkPFccEwLoaNhuPYDCSeT2B0+lhAfMHF1kF+PL5W7ZhrjqAk4gW53J0s3AG4nP6Y2BcUKAxLZn1+S4EBDAwQEIsUDBQRFJSJLJcoJpojfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nwindow_new-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIUAAFxaXGRmZFRWVGQmhFwmfFxeXOTm5MTCxLyWzLySzKyCvKSCvJxyrJRmrIxipIxWpNze3AQCBMTGxJRWtJRatIxOrIRCpHw+pHw6nHQ2lGwulOzu7Pz+/Pz+9Ozu5Pz+7NzexPz+5Pz+hPz+3NzevPz+BMTCBNzetMTCDPz+xNze1NzezPwCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACwALAAAAAAQABAAAAaVQEBAMCAUj0aCYFkwHBAJhWLBYDQcD8ghIjhIJhRKxXLBZDQaiYQLABDe8PiSu+HY7/dOh+PhQvB4eh8fIH6Adh2DHyGFAn+BiQAiISMkhnmSIQAlI5KXHIkfAiUmpCUnhoKLISgpIikmAlwqtCArkiUlIhwiuSKyEcHCESausMEsycrJEaaly9ARIizN1NPQ0dfJfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nwindow_nofullscreen-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBNTW1MzOzMTGxLy6vKyurJyenHR2dIQCBPz+/OTm5Pz+9OTm1Pz+7OTmzPz+5OTmxPz+3OTmvOTm3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVsICCOZAkEaKquqzAQRWEYR32gSK7vO5oowKAQmEAtfr9hgpFoGBWJpDDqcAaOUSHDEU08nkOG2AGBfK/aMYQMiRi7Ywe5674yE3I2JCqZoChLeGwSEgmFfgFNDQ8NjQ0TEROSRSyVKSaYI34hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwizard-16:actions actions16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+xPz+BMTCBPz+/MTCxISChDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAREEMhJg6BYWhAGv5k2EKMXToSgEqc1DEIhvGAWpOvJFSXZyoXOxxY0BDahQDGg4xgOxmbgiWDqpoeqlGrVcZuSbLfpjwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nabbrowser-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBKSipMTCxISChPyqXPzerPz+xPz+/FxaXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARhEMgJQqC4Xms1tkIgDEMYXpMYEEJRCIT6Ea5R2DHFtQZBG6dNoHQrsAyH14DDWiENBsQhBtskEs4Dohe4oiqE5So2zElECEKCrCYgQmcRVnRKnFIdC0L4/az7GXiBg4N+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\naccess-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBGRufLzi7PT6/NTq9OTy9MTm7LTW5LTS5LTO5KzC1FyGrExSXHzG3Gy+3FSStPz+/ESGpFSmxEySvEyKrER6nERylExqjFSSrKze7EyCrDxulKzG3GSuzGSitEyWvER2nEx6pKzO5DxmhLze7DxqjExihERadLS6xERulEyOrLTC1KzK3ERWbERujFRefGR+nKTO3LS6zLS+zFRmbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAQABAAAAa1QEBgSCwWhYIBocA0CA6IhEKwYAQKDccDAolIJpSK5aKwFhyYDGSQoWgqm4uFYyV0PAeIIPIeayZlVw4OFV19FxoSGoFnH1tcayASIRciVgYfEWoQIxcLk4gHlxQCnJBcJBUSdAEHhQediSV5ExWBBxYQGSZelLkHJyhWsHmSISkHKpsrViwWJ1xPXCAtesIBCiUaGHm6LiYvLybXMAQCMQosBwcoMjIzMTQMAC0M9vf49wB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nacroread-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAASC/PwCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAIlhI+pELshmkOhzmTvyZrFDglRxVEiGUoUualtx7gOC36gDGt+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nagent-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipISChPz+BMTCBISCBERCBCH5BAEAAAAALAAAAAAQABAAAANLCLrcHkFBt4IY8EYKYCAT9xVBYRhbM5KFeaRVy56oSsgQ/TLrB567ym10ChiCnRIRaJx8lDdd86UkEWjHaURZwlKRHpM0xPOYGf4EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\naktion-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAI5hG+hIuigAmMvLTlfnJiePQndt4SMFFioeaagaEbvySlQF6I2BLPRwYntDLlaylH8VXLDpaiJ8BcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nalevt-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/Pz+/AQCBAT+BPwCBAT+/Pz+BMTCxCH5BAEAAAAALAAAAAAQABAAAANFCLrc/i3ISadQYQhSehFecAGiYJ6oiJmaZrymSrKCJhinXLYmHo+l2skn0KGOPwyBUHPhOrqKVIWsmhqHyqhhPUG+Cn8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\napplixware-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBKSipAAAACH5BAEAAAAALAAAAAAQABAAAAIyhI+pGbsBHYtHCGARbMhms1HVB0TieJhcl23liXkinAmhy7732UL9GnsZeixczChB+AsAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nark-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/PwCBAQCBPyCBPzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANCCLoQwTBK6dy8WNQgptAbB33DQGzlx3xE65RpBwgtCw9sR7e1gO8EGYs3DMoUH5rPqFylSrzaygcjHqdQVUYL8ScAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\narts-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPz+/KSipPwCBISChAT+BARCBMTCxDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAMALAAAAAAQABAAAARTEIQ5xbgYAwJksFhhaFTVdeLpURYwAOL7cp6gpmcZHEQPGyIOLRAkiI4GTqmIDG5QwGihuRIBU8boasLzZbEd082QK7VkrvTwo2pvP5m4GxHP+CMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nbackground-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAAQCBJx6NJR2LIxyNJR6NKSORKyaTJyGRJyORKSWTJyKRKSWRKyOPKSKPHRKLEwiFDwSDEQeDGxGJLSeTKSSRKyaVLyaPLyaTGQqFFwyHGwyFEQWFDQKDDQKFEwmFMSiTMyiVJRuNLx+LOS2VOy2ZNSKTFQeFGRGJLyqXMymVOSiVOy6ZOymZKxyTEQODDQOFLymVKxuNMRyJOSeNMx2FLxiJLRiHFQaDDwOFDQODFw+HLSiVHxSLFQiFIQ+HKxmNJxOLJRSLIxGHDwODGw+HNSSPOSWNNRyFOyyVOSOPARihNSORKRSFLR6TPz+/MTCxKTi9JTW7GSy1Lx2THw+FNSOXJRWNISChASq3ASWxARynEQaFMx+JJRSJFRWVARafARSdHxeLFw6HPz+7Pz+5GxKJDwSFIRSNHxGNPz+3MSCPNSWTMyGNPz+9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAQABAAAAfXgACCg4SFggECAgMEBQYHBwgJCAoLggsMDA0ODxAREg0TCxQVghYWFxgZGhscHR4LE7GCHyAhIiMkJSatJyi+giApGCokKywtLhwvBzAwgiMxGDIzNDU2Nzg5OjsTghc8PT4/QEFC2EMeCZUARKpFRkdISUr09YIYET0qS0wqTUpOnkCJIkWQhxsbpsigUsWKkidXsGTRIkjHgy0YuMjoYkKJFy9KvoARFEZMBAg3UkIA6MTJGDKCBpQ5aebMGTQsx4xJU/FBBIxq1rAB4KTNS56Gkg7yEwgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nbell-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBEwuFLR6PLRqJHQ6DNyuhLx6LKxiHDwiDMSOXLx2NKxaHAQCBHxSLGw+FKRyLFRSHLR6NIRKFExGHNTStOzm1KyqfIRmNHx6PIyGRFxeJNzavOzq1MTGpKymfKyqhKSmdGxqNDw+FPTy7KyuhNzevISGTJSSXLy6jOzq3Ly+lJyabHRyNCQmDKSifAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ6QIBwGCgOj8iAYEAIIJ+BguGAeCYTigXDegw0DI4tl/gQj4WB8hkAgUQeEsaEC6FULBdMRjN/QjYcHR4fICEiVn8jFCAkHxiHfiUjHRYfHyZmR4kdICAeJ5lCECgVKSorJysrLC1IEBgVFSgunSAaoWwTIi28DL5HfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nblender-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBDwiDPSyNOyKLDweBFQuDFQyDPSeNEQmDIxSHFQ2DEQqDARWjARGdASO5AR6xAQiPOymNAQ2XARqtAQKHOSmNEQiDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVqICCOQBCQKBkIA5G+63C+RW3UrIsSQt8fA+CMREAQgIkaUEdSsBK6hZBUeJ4YjRLQIKoOBgVAw/GAAAqRk+EJBkgmDQrAUDGxTAMBAgCR89oFOgF5YQAWdy8EeTeILyV5jY5nBAGFkpJ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nclock-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBPzerPyqXMRaBIQCBISChPz+/KSipMTCxPz+BMTCBPwCBPz+xPzCxMQCBISCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVxICCOQGCeJjkGwkC8RFEEavkax2G8dB0QuRyhhzoBg8MSYsncJXKJZIDZHCoWP1ogGIwGrtnSgUFmHLyNRHhrdpjRamnO/SYkromHdnxwnwkKVxByZW8DgQsQM2JcfwZXO0MBCZSVBgMuLzJaRZ0pfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncolors-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBAQC/MQCxATCxATCBPyqXPwCBPzerAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEMgZ6rwYBCFsvtXWeWA1DBU3ggRhomJQBm14dlJYFFXrbjKNwVDZ9Vw4TWWoKyCDgcNhyXQClVLpMmANIRAhLdGa+36j07GrfM4GiKTAGfsOlmYZfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncookie-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBNzeDJR+BOzmVNSqPOSmBNSCBKRCJFwuBOSOjMRSTLRaXFQODMxiXOS6vIwiJGwKDHx6fKyqrMSOjNRWVLRaVFwCBJyanJSKhHRydPTy9PT29OyytIQSFPz+/JSSlOTGxIQyLMTGxNTW1Nze3Ozq7OTe3FxSTGxqZNza3Ozu7OTm5MzKzLy6vLS2tNTS1FRKPGxWRMSypJyOhKSOfPTu7LyupFQ6HMzOzEw+NJR2XKyOdFxGNHRSNJx6XGRCLHRCDMy+tGxONDwaBHRiVDwyLEQuHJRyVJyCZLSilIxiPIRePHxOJIRWJFwyFEwqDCwWBBQOBDweBKSCbHRKLHRKHIROHGQyBFwyDDQaBIxqTHxOLGQ2DDwiDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe4gACCgwABAoSIiAMEiY0ABQaHjoQHCJOECQoLDJeCDQ4PEJMRERITFBUWFxgZhKQaGhsKHB0WHrcfEQARGxu3HiAKIRgiIyQlJicoGym+KissLRIuIi8jJTAwJjEyGzIYKxszNDU2Nzg5MDY6OyQ8PT4jP0BBQkNERUZHOkhJSktMZDQBcsTJEyhRpOybcuSIEipVrFxBgEVKFigATkiRgkSLki1UgFzh8kRKFEQbN3aR0qULIT+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndate-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBPzerPyqXMRaBIQCBISChPz+/KSipMTCxPz+BMTCBPwCBPz+xPzCxMQCBISCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVxICCOQGCeJjkGwkC8RFEEavkax2G8dB0QuRyhhzoBg8MSYsncJXKJZIDZHCoWP1ogGIwGrtnSgUFmHLyNRHhrdpjRamnO/SYkromHdnxwnwkKVxByZW8DgQsQM2JcfwZXO0MBCZSVBgMuLzJaRZ0pfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndlgedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTCxFxaXKSipPz+/AQChAAAACH5BAEAAAAALAAAAAAQABAAAANLCLHcrSLKOVccAuvMLf2Rlw0bYRKFGBGZWQioRc4kPKfB+qFFL9ODF+EmKxh6vZOreETCbLiMESkcxnIgATXK2XgFqmxI4SgvAP4EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nemacs-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBDQyNKSipPz+/FxaXISChMTCxCH5BAEAAAAALAAAAAAQABAAAANJCBASoXCFoVi8VdL6HHQeB4YjSAxnYQygSLzoSTjbEs9vMF86cbyH34NX+AELQ4zO+Nopm6cBC1PBEQwG6gd3SGo7Xa1STIb4EwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nemail-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBGRWVAQCBOTWvKSShDwyLOTazOTaxPTuzLSilOzi1OzezPzy7Pzu1NTKtKySfPzy5Ozm3Pzy3PTq1NTCrMS2rNzWvNzOvMy+rLSmlPz69LSejIx2bPz29ISChPz6/Oze1HR2dOTi5Pz+/EQyLJyanKSipOTm5MTCxHx+fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaGQIBwSAQEAoJi8RgYEApK49FgOCAS0CFTsVAwEA2CIysMJB6QCEQyoVQsZOMFk3loJoeNAk4MGBQOFAQcDw8IfFoLDB0cEBMICIRxAV6NEB4aHwICk4wLIBYhIiObSxwLBSQkJaOlfQUFpCYnIyMoSVGbtQK3UQCbKCYprkq8m8S+uL4AfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nenergy-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBBQSFASiBHS2/JzK/KzW/JzO/ASWBATCBASKBHy+/Hy6/ByuHASCBAR+BATOBARyBIzC/MS+BASeBASOBARaBFym/Pz6BASuBEyW5AR2BJS+7Gyq7PT2BARKBDyC1FSS3IR+BJyaBLy2BPz+BCxuxAQ+BDw+BOzmBARiBCxyxBxetPTyBAQCPAxOpAQ6BAQ6jAQ2fAQ2hLy6BAQubAQydAQmXAQmVAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAahQIBwSCwaj0hAYBkQBJDLAaFgOBCWxcAAkVAsGIyG4/EUBh4ICCIicUAgkwTZjKBULISL3oHJzAMaDhscHYEODhMeExEfSyAhGxsgICIYHiMWJCUYSyYYJw8kIigoKSomKxgmSywYfC0YGCJ8rSwuS7EYJBYYLi+xE5tkARMoMCoYEzEiJDIzMjQiSzExMxGkNTY2NTc4NTNPTOLjWElHfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nenhanced_browsing-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBOTWzIyCrFRSTMy+tCQmVOzi3ExKhAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARFEMhJq6UhyHy3GNmnAeNEFAZwpuRRBiIMkkOBjKuKTsHtgbISybTLYX6hGc+lSxk3tVtMVOkFck9MMNjB7jqkEQdMlvgjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfiletypes-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMT+/ISChKSipPz+/PyqXMTCxFxaXPzerPz+xAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARfEEgZqg0zV8EHF5XWEUMxkBwGBB9REIZLfBgrkEaen+l6F4cYgpA4vEC+ASIYSxQRnlrncEgoFFQP0laCHpSmnk+AEJQ8ZeRkw0mDVJT3JZQZw+trC77Ouu8pfn8AfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfonts-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPz+/KSipMTCxPwCBFxaXMQCBCH5BAEAAAAALAAAAAAQABAAAANBCLoQ/C+I4GAMY1ZGN80UJ2jA0BFbUxhjF6BWsQroawEyWhN37vKxQo0ChPhOPaGDIhhADr5FinE4TG5PrBbiTwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ngimp-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChPz+/FxaXMTCxAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM6CLrc/izAJVWoD4MgtL2R0F2k6HFiOgjDSRBq0FLUKxYDTmKBnf6gGqz3egWFhEvSQ9kxJ9CotOFPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ngo-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBERGRFRSVDw6PDQ2NDw+PPz+/ERCROTi5Pz6/AQCBKyurERGPOzq7ISGhNTS1DQyNLSytExKTLy+vKx+RGRiZPTipEQ6LOzu7PT29JSOjOzWlEw+LIyKjIx+dLy6vOy6ZEwuFHQ+DCwqLGQ6HNSWPMymfIxmPMyqjKSipCwuLMzKzHx+fBweHOTm5GxubJSSlAQGBHR2dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAadQIBwGAgIiMXhgAAoGAwH4QCRKAgVCwSB8AwwCo2n9ZpwMMSFhyEBGQoLEa5BMnkO3G/Kef2sMIdfCxYXT2oGGAIHCk0ZCBobHE8dHk8MFR+LgSAhXSIRdmNCBxScBiObCAYZI25wJE8SJSYECVVDCg8dERchJygPKSqsQgQNKwQFCw8fLC0KLi+LxH9YMDFX0ngAzzLZ2m4K3kN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ngv-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAIxhI+pwaHZ2jNMWMFmvXk1GznHF4DhWF4cJlKpynpwB73ms3Etiq00EAr+hJGJ0eAvAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ngvim-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBAT+BPz+/ASCBMTCxISChAQChCH5BAEAAAAALAAAAAAQABAAAANUCBDMEqupNWoNJNgBV/mfwYCFqASgmA1h57VaO71lXLtPytZEBggZ0E7Vy2BQJEaRcDghP6iGb/IsNKBWKghZzb5EUau4g1KFz1QId+ydRRZwiD8BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nhelp_index-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBPwCBAQC/IQCBATCxMT+/Pz+/ISChAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEIRJJZ1ACjF3GGAYaKNFDNfXldLJqmQWcKhcW6tkl1NhFJhdRmIwHIq8m8R3LAIlykCxiZQNl8XsU3eVZg0Y2LD3CyAQlassbEaz1N32Gz5m+SMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nhwinfo-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBBQ+XBRCZAw+XAw6XBRCXCRObCxihCxqjCRijBRSfAwyVCxehDx6nER+pPz+/BxKZAwmPFyWtGyevCRSbBxWfAxGbHSqxGSatCxulBxahBRKbAQiNEyKrBRKdAw6ZAwiNESSLCyCDBxWBDRulBwyRHS6ZDSWHCyKFDQyNCxqlAQmRAwiPMzalPyCBMQCBCx+DAwuRBQqPITCdFxaXCyOFAQeNAwmRAxKdPz6/GyyVMTCxKSirAQCBGzKZAwqTAweNFyuRDyeJFzCTITOdAQiPAQaNHzCbES6NEy6PESyNDyqLDymJPz+xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfBgACCAAECAwSDiYMFBgcICQoLC4qCBQwNDg8PEJERlAYNEhOaFBUWnokBBw4SFxgOGRobCxyJBQkNHZoPpR4fICEiIiMBCSSYmgoKFgslJicoKQQKCSoZmgW+KywtLi8pMDEbFRqaAcwyMyc0NSkiNjc4ObsrKyU6Ozw97j4lNhGSfsgAEkQIDxr7YAwh0qKIDSM2jgRpgbDHPhFIMiZRsoTJkhMgobUDMKKkySYjUKockYJSypcrWypKQbOmTT+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nicons-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBPz+/ISChIQChFxaXKSipPzCxPzC/MQCBISCBPyqXMT+/MTCxPwCBMQCxMT+xPz+xMTCBPzerPz+BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAV+IBCMZBkAqCgMa8uyJxoMRFHUtz3Eqk0MBhxBwJsRaqTcLhUQ3AyHAMI0EtEI0pGrpU38SANFQazYGY+LqUChYDQUxCbB8YjOFJAIpGEePOpZAhITIxJxAg8JDwQPMxISERESfXSVTRIQAZKHLyuOFI8US1RNnTApqCJUAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\niconthemes-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBPz+xISCBPz+/ISChPz+BIQChFxaXMRaBPyqXIQCBPzC/MT+/MTCxMQCxPzCxMT+xMTCBPzerMQCBPwCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAWLIBCMwhgMJqCKRBEIpWAMBRGsQXG8sIAiLpwNZpAFEAcbjlc0OI9BVcAWSDgHT9MtF1AsZrmamNpNBAyjwgCxpo0U5h1jOhg0HAMbPHB4QNIDEQIRDi5xfgFzBBITIxJUBQ8UD305EhIwEi45FQ+dFVMSES+PIy2nLgUSBpcGQVomqKc3K7WwIwB+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ninput_devices_settings-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MTCxHx+fISChKSipKSirATCxAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARQEMgQpL03iEEx1gOxdR5YbCJXZUbqjusUhGitZkFri0VFUodXoTfjWCi6oY8Skxl6k4FhxZRRRxMC1TBdWn0CAbcZQFAH4WnGjDPiPICYPwIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkab-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChFxaXKSipDQyNAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANICLocHiyqIMQYUE5Ses8S1V0FGInFIJTalKpsS5FxKDxB/EzV4GUBQsXR87BQnRtNtxphfJ9FAAqbRqUXVfPaMH5MDRx44U8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkappfinder-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBExOTDw+PExKTPz+/ISChAQCBPz6/FRSVIyKjJSSlIyOjGRmZNTS1Ozq7Ozu7AxyzPTy9ERCRBQWFIyqxPT29AQ2vOTi5IzG7DR2zNze3Nza3BQSFISy5CRyvBQenISmvBQitMzOzAQGBAw6rDR61Hx6fMzKzAz+/IzW7ASyvCwuLMTGxMTCxBwWFDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAahQAAgEBAYj0ahckAoEJ5QgkE5fBYO0SeCOigkFE2DeEFgUAUNBwGBeBAcCMHirF4gnhBCBCE5PydqBBQVFhdTSgJPBk8YGRQaG4dCiQQcDh0eHyAhIiN+BHYXJCUNIggmfhUOAQgbJ6YCKGcVKSUaChwGHCYqCyuIDhkhGyIsLcccCL6TFxsNJ8fRLS7KvyNi2GIrAQwK1AsvVOJULi4AfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkarm-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBPz+/ISChMTC/MTCxPzCxMQCBPwCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEIRJa5Ui66H3FETHdcTwdcIofkVbUIJbmAEoZl95aoXxUrNdpnAIDFomgRA3yxxhIdxAlaKhAgUNYshyYVGxnMZInS6VzVSQPG0bkWaJZT4B+CMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcalc-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBATCxARCRASChAT+BMTCxFxaXEQCBPzCxPwCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARPEIBAq5U4iM17wJMwjORIfJkYFCs7nKA2rJQLp0Su66ikGcAg8OYTGA6BA/KAIIYsFudPGJQal8uAFVqxUg2JxBYbUGh7k5J6BppwKyB/BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkcharselect-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChPz+/MTCxAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANBCLrR+zCIGWCcI1cLpNCa5YHZsCmj2QTlxrZmmRFVSs4E7X13TqMTXsl36gSHuSIQQ+QYP0kncPCTokzWh3LhTwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkchart-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBPz+/ATCBAS6BPyqXPzerPz6/Pz+BPwC/MQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARcEMgJQqB4WiFulhvXfaEwiJ4mEgExFCMVcENgBEXepdVhG7dcABGr/IJCQ8ICAt4IUIuSKAW2XMOD0qC42AIHV4277YIqKHKCy5txbIoyDy2Nr80yjyVwn5OYfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcmdevices-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPyCBPyqXPzerPz+xPz+/AAAACH5BAEAAAAALAAAAAAQABAAAANMCLrcHjA6BcW4Q8AWLL7EFSwdOIRoOAKBiZ5EPJYvBMeDba5BQfg52ik4KPgKOVYqZiwYjLzb7/c0JCnSo3VFasFEXE5kMymbzwp/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkcmdf-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMT+xAT+BASCBATCBMT+/AT+/ASChATCxPz+xPz+BISCBMTCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEEgZwrwYBCFqvhs3DNYXjChRlWBRjIRqGN4UuEUczMZxsDeXykdEsDQVVSLhQxhBCkVlmXA+KVHFYhFYOoHbMGN6pTQaW8YYiQmcG+q16a0+Zipw+4e9B/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkcmdrkonqi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPzerPz+/PyqXMTCxPz+xAAAACH5BAEAAAAALAAAAAAQABAAAANKCAoRy+6pIESkVuLaKl8b53lOaA3EyIXBUBjpWHKDYNhxNrWv/aaRiWBwKwoIDZCH2EN+TMQjyzR0yhgqiyo4vT4wl48E8g0C/AkAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcmkicker-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBFxaXPz+/ISChMTCxPzerPyqXDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEEgQqr11AjG6/4FGDEVZBOapWSXbToFhoKkZUjJGEEJvyUDDYQaKATElBOJklB0OgY5SWgnmpFJm4PkMjDxLFYXFGSCyN8mocDaD0xsSO6wUS6K1FBzDD/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkcmkwm-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCRiXCRaVPz+/CRmZFRWVISGhMTCxESSjPT29DR6dDyOhDyCfPTy9CxqZOzu7Ozq7ERubOTm5ARehAxefPz6/ByaxBSOvBSGrAxynAxqlBR6nBRylAxmhARWdFxaXCH5BAEAAAAALAAAAAAQABAAAAWHICCKQTCeqCgMhJCihXEYSPuKRWIoC6PYsEZikHA4FA4CEJdoJh4QgXRwiOAeQudDIpEZIpPwhCImhyGGAmBSOVgumExG055w1ZPZhpPpUDwzExBqAAUDhxUVTQ0QEgWOOIcDiU1QjoSFFYiKDZYFmAWJlE9bkCM5iouWpiIfBa6frrKYAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkcmmemory-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBISChAQCBMTCxCH5BAEAAAAALAAAAAAQABAAAAI6hA+Bu+HCmgiiRuNoHZBRXQlc84TmcHzm2WVryE1YvMaZIdbVd2zw7lj4bDKGbxK8hHgX3K2JUDD8BQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkcmmidi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBFxaXKSipMTCxPz+/AAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLEL/pDJAONs1V2W1ebWJ46kKJxomi5D2QZEwRSyVMNyngf7Eg8FYHAIZMRoyCSNMSA0n85oszTxJwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcmpartitions-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMT+xAT+BASCBATCBMT+/AT+/ASChATCxPz+xPz+BISCBMTCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEEgZwrwYBCFqvhs3DNYXjChRlWBRjIRqGN4UuEUczMZxsDeXykdEsDQVVSLhQxhBCkVlmXA+KVHFYhFYOoHbMGN6pTQaW8YYiQmcG+q16a0+Zipw+4e9B/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkcmpci-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAADQyNATCBASCBKSipFxaXAQCBMTC/ISChAQC/IQCBPyCBPz+xPwCBMTCxPz+/AAAACH5BAEAAAwALAAAAAAQABAAAARVEMhJqww4a33F+EL4jUI3EEXoEWzaFbAKzyUQeLihDqrpHQhBQkHyqY49iWCxbDKfJQbASYUCpJbslcHter+NQ3gsLo8bBYd6zWYf0u24GjWr22f+CAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkcmprocessor-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipMTCxISChFxaXDQyNAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLrc/jDGQCWgIleH88jCdgXgB4JVQJxsVgQXIQvrWdwwJc/0jcOG0Y7gqwQVQR3R+EgyJcGjZUoF+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcmscsi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/MTCxKSipISChAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANCCLoQwZAFIV6UYgxi79Qa52WDE3bKV6YOpFpO3L5pJcckLBB8/wQEDezWAQpZqIWxFNAUkqkg6HmJOqGuArUqwfoTACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkcmsound-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQC/AQCxFxaXAQChAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLrcDiE+F4SQU4UBLH6VoHjT1okQR6mnuTYuJMWaGlkXW2u4QOipRYDws82AjJsHKez9MgrigAkF+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcmsystem-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBGxqFAQCBPz+/PTqtOTOfMSyPNze3Ozi5KyeLMTCxMzGzKSipOTe5MTGxAAAACH5BAEAAAAALAAAAAAQABAAAARfEMhJQah4ihFunsFAEIVXCVJACIJhoBK6CerawsA8HAhbuAnYZrBDKBYMWpCy4S2QSRazyBIwrrjcoNFQzK4KR1bQcHhZjGM2BgWLMYJ2enForHPJtNj+kfHvcB8AfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkcmx-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIAAAASC/PwCBCH5BAEAAAAALAAAAAAQABAAAAIlhI+pm+HB4HkS1flszOCq7C2Qw0wdJ2Lk16BGeK5dSZX2jS9+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkcontrol-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/CRyBBxSBExOTNzipOTijOz67NT21LzutJTmlGzaXPz+/OTi5AQCBLy+JKSiJES2NES2LESyLDQyNLy+vLzWhLzWjLS2tGRiZDymJASChIQCBDyuLLzShDyiJMQ2LATCxMQKDDSaHDSWFCQ6tMT+/PzCxLzuvCyKDDSSFKyqrMTCxGzabDw+PISChASSBAT+BDzOPNTW3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAacQEBgSAwIBsikkFAwHBAJhWBBpTIaAccDAolEJIKJWEzBMiuWCyYjaLjd5exDIsE02A1NY9OIMzkcHRkebW99WFoVahkfbSANIYdCBh52IiOFb2VCByIWIh0kbSUNJpIBJ6CgKJlwDUIJKSooswIUt7crrwEsKC2+rC7CLzAuuzEoycmtbgAAAtDR0DLGztYALbm426/Wht9vzn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkcron-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAADxePARCBAQuBNTS1OTi3LSytAQeBMTC/Pz+/AQCBOTi5MTCtISCZAQiBISCfKSipFRWZGRiZERCRHRyZMTOxDxOPMTCxIyCjCQiJAQOBLS2tAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAQABAAAAWFIBCMpCCQpDgQLFusLVEYAXEgOJIQOXIkNF5v19MFWQrCgsFYxIC1InEYvOWmuF9QKrw2aoSkYtksOBwEaBeXeEAiiIdD8rUNJw8EBUGobIcQFggXLglgCohLGA95CQMOGVFDEQ4YGhERdAEWCZ2dDwsSEHMOEA0ABqmqGRkGDQ2pDRV+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkdevelop-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBGSKXEx6RFR+RFSORISidJzCjJS+hISydHSqZDxuNIyuhKzOpLTSrKTGlHyybGyqVDx2LHyedKzKpLzWtMzexLzavIS2fFyWTDyCLCxiHNTmzPT29PT69NTm1GSWVESKNCRmFOz27Pz69PT27MTKxJymnIS6dESGNDR6HFyCTIy2fNzm1Ozy5JyenISKhISOhMTKvESGLBxaFOzy7JSWlIySjCx2FBxGDIyOjOTu5BQ+DFSGRDR+JCx6FBxODDx2NGyaXCRyFCx2HCRqFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAexgACCg4SFhgABAgMEh4MFBQYHCAkCCocLDA0MDgcPEAQRhRITFBUWDAcXEBgZGoQIFBscHRweBgkfICGDAQcUIiMdJCUmJxgoKbsAKissLSQuLzAxFgQyKTOCKgk0NS/fNiQtBBk3OIIEEC0cMDkvJiQ6ICk3O4M8FCQcNjAcJBM9fPwgBCQICxI0XtBgQeCGEHuEFGCYwILFBAJCHh7SEGJIRiI/IDaagSNko5OF/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkdisknav-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBERCBBQWFPz+xPz+BISCBERCRPz+/OTm5HRydAQ+XHR2dKSmpNTS1Hy+1AxypNTu9ITC3ARypExOTFSyzHS61JTK3MTi7CwqLBR+rASGtDyixFyuzDw+PAxWhAxmnBRypISitCRujAxelAxmlFSixMzKzCRqlMzOzMTGxMS+vGxubLy+vLy6vKyurCwuLGRiZLSytFxaXJyenGxqbDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAafQIAQEBAYh0jkQEAoFAxJ5EGAaAoSh8BBEUBSrQtGw5EodwHfgsBgeEAWijGW2XTaDRHJJExBrwl1AhUWFxgRDwdCGWkCGhsbHB0WGB5CjB8fICGOGxaJaWwGIiMfJCUTJh50dk4ODiejHyiff2oGDikqK7osiUIGai0pJyouxi+9v2pEMDEyLTIyDckCy0gBMDM0DTU2flFDARk3AH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkdmconfig-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MTCxISChMT+/ATCxASChFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMg5gw00yyDGIAR1YUDggeFWFIZhnSBZrsZxdIOFEGTA2oeBAHeyuGwvzxBlYdUOLROMFzDQntJPrNoqAKUBaqnV+k57ZORruykHDj2LqIzUVKp1u0iuB/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkdvi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/MTCxCH5BAEAAAAALAAAAAAQABAAAAJCRI4ZwCYPo1gsiIHHxY86KXmWdiGkCA1Wp6Htc07NOsEv2oVyldLHbuBgEhORJhOxGEkkiLJybCZ3iqrD08hmF/4CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkeditbookmarks-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy+vERGRFRWVDQ2NKSmpAQCBKyurMTGxISChJyanHR2dIyKjGxubHRydGRmZIyOjFxeXHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICACwWieY1CibCCsrBkMb0zchSEcNYskCtqBBzshFkOGQFk0IRqOxqPBODRHCMhCQKteRc9FI/KQWGOIyFYgkDC+gPR4snCcfRGKOIKIgSMQE31+f4OEYCZ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBASCBPz+xPyqXERCBARCBISChMTCxPz+/FxaXAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARXEMgpQ6B4WnGzDgJHWWMYdkAwEF1QFKe2oqDZztr7GpfKjrvAAeFDpQq8ISIRYBotSoTUkiC2ostqYps49BSKIVfaBbcC4MMWcTAbU+iw21NBk+gjuj8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkey_bindings-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChPz+/MTCxAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANMCAoRy2IEuYIQDsrBld0NN4XaJF5iCppWxBGtCscEAbkDfH2wh+ogiudD5AhvoZWoJEFtckBTE1dzKKfQjMtUjfQUzizjeBN7HgB/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkeyboard-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChPz+/MTCxAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANBCLrR+zCIGWCcI1cLpNCa5YHZsCmj2QTlxrZmmRFVSs4E7X13TqMTXsl36gSHuSIQQ+QYP0kncPCTokzWh3LhTwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkeyboard_layout-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBPwCBMT+/AQC/Pz+/PzCxKSipISChAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARSEEgZqr1hUjFIEQXBZVogDt/XYWxgoEVFzEUt3MGNm7SND4aarPfBFQYCQmtpiTErh+ahMK1SqVHoYcvtUptX67SWDXTPXWltva5q0WfEs+WPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkeystone-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTCxISChPz+/MT+/AAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM/CBDcHkoFQasVUIrBe8fRNDwMAWpjUThmtmxk0IYwOaPx/V6XG3hAjmsRa0Qkg6NSOVo6F0nG88g4TUNDpT8BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkfax-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBPz+/MTCxISChERCBFxaXPwCBAT+BARCRAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARVEMhJQ6C4imEzDkLIXR4ADqFAThYRoFu4ti6YbhfdFm+aEzWgAWhB5QyGAMEwWA4PlpyFCWwOkAhCgla1EqxXKbD7vSJnyuUXyV5JuOxtqZV0z+3+CAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkfind-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBExOTDw+PExKTPz+/ISChAQCBPz6/FRSVIyKjJSSlIyOjGRmZNTS1Ozq7Ozu7AxyzPTy9ERCRBQWFIyqxPT29AQ2vOTi5IzG7DR2zNze3Nza3BQSFISy5CRyvBQenISmvBQitMzOzAQGBAw6rDR61Hx6fMzKzAz+/IzW7ASyvCwuLMTGxMTCxBwWFDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAahQAAgEBAYj0ahckAoEJ5QgkE5fBYO0SeCOigkFE2DeEFgUAUNBwGBeBAcCMHirF4gnhBCBCE5PydqBBQVFhdTSgJPBk8YGRQaG4dCiQQcDh0eHyAhIiN+BHYXJCUNIggmfhUOAQgbJ6YCKGcVKSUaChwGHCYqCyuIDhkhGyIsLcccCL6TFxsNJ8fRLS7KvyNi2GIrAQwK1AsvVOJULi4AfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkfloppy-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBISChKSipFxaXPyCBAQChMQCBPz+/AQC/MTCxATCxAQCxAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEMgZgggz5zAIBp9GFV8oSqRkikFanapBVgccGAiJBDWL74jd4UUxGBI/IcJQMigSimPSsMDcEFCFVkptKhCDgSBB7m4sA2y5eqqMF2YYKMBgys8nfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkfm-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBGRiZERGRPz+/MTCxAQCBMTGxPzerLy+vLy6vPyqXLS2tLSytKyurKyqrKSmpKSipJyenISChJyanJSWlJSSlIyOjIyKjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAV+IBCMZCAIQKoGw0C8MFEUqmgYrTwXL50GhtegcCgedr4AIpEYHhQKopEWSCwYw1fUeBQxGo3hiBCIUR2OxyAwG8OoD0hkICFABMiZKBKZ0GNkPiIUFBUuEoiIMisVFRZ/MWwqAheVfxICdZIpmZZ1kYIAMxcuJWWhKXl5Kn4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkfm_home-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBDw6PBQWFCQiJAQCBFxeXMTCxJyanDwyLDQqLFRSVLSytJSSlISChCQmJERGRFRWVGxubKSmpJyenGRmZLy+vOzq7OTi5Ly6vGRiZPTy9Pz6/OTm5ExOTPT29BwaHNza3NS6tJRqRGQqBNy6pIyKjDwGBPTe1JSWlDQyNOTGrNRiBGwmBIRaLNymdLxWBHxGFNySXCwqLKyqrNR6LKxGBNTS1NTW1Jw+BEweDDQ2NAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaoQIBwCAgIiEjAgAAoGA6I5DBBUBgWjIZDqnwYGgVIoTGQQgyRiGRCgZCR1nTFcsFkHm9hBp2paDYbHAsZHW9eERkYGh4eGx4ag3gfSgMTIBshIiMkGyAlCCZTEpciJyQjGxcoKUQBEhcbIiorLB4XEltDrhcaLS4vtbcJra8bMDHAGrcyrTMXHjA0NSypEsO6EzY3IzU4OdoTzK0BCAkDMgkIOjJlAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkfract-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBAQCxAAAACH5BAEAAAAALAAAAAAQABAAAAInhI+pyxudwoNACiFbuBzHt3XeEYbiBF5mN5HpyayqVrY0hdj4vvgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkghostview-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/MTCxCH5BAEAAAAALAAAAAAQABAAAAJCRI4ZwCYPo1gsiIHHxY86KXmWdiGkCA1Wp6Htc07NOsEv2oVyldLHbuBgEhORJhOxGEkkiLJybCZ3iqrD08hmF/4CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkhelpcenter-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/FRWVExOTKwCBJQCBIwaHFRSVPz6/LxSVOSqrNyanIQKDHwKDHwCBPz+/OTm5Ozu7JwCBMRKTMxubLxCRNTW1IyOjDQyNEwCBGQCBJyanMRaXNyOjKQODIRydKQqLOzCxEQCBNze3Ly6vJQKDDQ2NIQCBCwCBGwCBFwCBDw6PNyipDwCBKSipEQ6PDw+PJR2dMRiZHwSFPz29BQSFIwODJwuLMTGxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAabQIBwSCwaAQHBgFA4Cg2BwwGRUCwYxobD8YBEBpLJoEGMUA4VywWTaUQOmstww+l45MKM5/DAf0AIDSFFBiIHI3IEHCSDRgEOFSUAJhQNJ0coYikAKpB4RQwrJiycWy0uRQ2AKKQAL3wwKEMCMDEdGEMvWxIKDTICIzMQKZdDKQ0dMSAxBzMPGjRGGCkoNTYaNzTRThgnJ9pFfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkhexedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTC/Pz+/MTCxFxaXPz+xPyCBKSipAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARZEEgZ6rw4CB3wrJUggt03nANIoCUQoDDcvqJAaHXqunBxywFDZWArDHy4lOEwTBEKgYJRyeQJEIEnYrQsvU63abBKIYq2m+4s5mTeTLVRSFdmyy6kvGXijwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkicker-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/FxaXMTCxDQyNAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANECLrcEDDKGYQV4+qbie9eGIJEVxTe+QmjUFgnXLLr615oF8x2v0I8DWpF2GV6slkLKSMdYT4nS0WgSkXYAWUbcXgX/gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkiconedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwC/AQCBMRaBPyqXPzerPyCBPzCxPwCBPz+xMTCBPz+BISCBMT+xATCBAT+BASCBMTC/AQCxAQC/AQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVkICCOpBicZQoEwjAE6hgQQwvH81AU8OnfuR3QYDgcgAKhjGj8+UgzQkHHw+2mQlQpgEAkFInEYnGDhr/h8VPGYDQcjcZj/iiv4u84vQ6FQCISERETgxN2AX6AgoQThlBOkCR+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkillustrator-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBAT+/Pz+/KSipPzerPyqXAAAACH5BAEAAAAALAAAAAAQABAAAANHCLrcGzBK+YK4OAcAx4AXIURj4J2fJYhWh35pOHKoG8+mFxS5HimmXU8HBH4MQyJD+FI+kM3Ug9eENALQk9VhDW4c1y/YnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCxCH5BAEAAAAALAAAAAAQABAAAAIghI+pFrHbXmpRMmoBxXB75IWcKIKk022ZunJtdlSw5BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkjots-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPzerISChPz+/MTCxMTC/AAAACH5BAEAAAAALAAAAAAQABAAAAM8CAHc7kGsR1mc9d1Md/icIgXDB1YXMZQnZBJEIbdKABPGTbSfnuc8mw8W1OlotYER2fgod5iMKRqiNvwJACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nklaptopdaemon-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/KSipAT+BISChFxaXPz+BMRaBPyCBMTCBDQyNAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARtEIBAq5w1TBGEGIM2ESTlVUNhaAFJUAcXgAXCZkFyJEoiIArWYQjj+Xi2yfBA0SU6CuAts4MCk4EdcxbznFhOCsjrWUxRhbRBBk48Z6kCZ2GeuN9xucF8FqcEBnt1OW4saSp7IoRPEjgiGBV+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nklipper-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFQyDEwuFEQuDISGhFRSVEQqFEQuFPz+/PTy7Nze3PT29Ozu7DQyNJx6VIxuRIRiLEwuDIxSFHxSHKSipLSytGRiZGRCHDwmFOzm3HxOHIRWHOTazHRCFHxOFEwyFNTKvHROHFxeXJRqLIxWFFw6DFQ2DNTCrIRaJJxuPMSynHRKHIxqRMSqjGRGHMSifJxeFKyGXHxKFLyaXKyObGxGFEwyDKyOXIxeHKSOdFQ6FIx2THRKFFw+FKx6NKRmFKxuFLyCPLyOTLyabLSefLyijFw6FJRmJIxWHHRGFFQ2FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfFgAAAAQIDBAWIiAMGA4IABwgJCgUICwwKDQ4PEBGCEQsSEwUUFQQWDRepGJ4ZEggIDbENrxobAZ4cHa+7uxAeH4IGICEIIsbGFggjJCWCJicovLwpIcAAGCorCBbc3AoILB2rgy2u0q8OLrcAJS8wr8nJrzEy6yUz79sivDQ1jQA2buB4tU8eghw6xgnYwePcqxcdbAjq4eMHECA+ggiZMYRIESPjShyBgQPJBB48OsiokaTDOoACItgwYULJhw8BbIzzEwgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkljettool-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MTCxKSipISChFxaXATCBDQyNATCxASChAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMg5Q6CYBiFsxhvXXZklimRlDWenBQNRzKJRXCsxHPFcIDGcILYbGHqzAY41NCQSiuNgMLPAmNTElFoFWKecqe8mCRAIq6nt5imb0TC2wZByny3zdslMr3+8fgB+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nklpq-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxFxaXISChPz+/ISCBPz+BKSipAT+BAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJqwUh3xqEz8EWDKT3aVNAFAVBDqYQYitbjARhGDJt34Nc4SBAZAomoDAhKAwyTZZp5XE+O0lp9QVFeLNWUpflJXheTww2ijiLKSBPW/C+xOmzjQRU8UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkmail-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPyqXPz+/PzerMTCxFxaXIQCBPyCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMgJgrWU4iAGIUFWFYMldF+okUPJeeAUDEY7FFzXqnNdkIGDgHAKzWgsDuJAFBhbtd1peTAWDFjpaZg6skonYfOZzC3HlduuMj1UZUDZ6RMblTTDokylQYsyFwB+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkmenuedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxAT+/ATCxASChPyqXPz+xMRaBISChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARLEMhAq5UY2B3yFGDIYcFgnuNErGwQCl1VzHSJBsbBUSxBIbnEC0YrxICHhFKZCiATlldn8gSlNE7YEurRQHdd19Aa3m6nmV0F448AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkmid-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBKSipISChMTCxPz+BAT+BFxaXPwCBATCxARCRAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARUEMgJgqVYWsFv3lwoeFMwEIQYkkFhouoQlIFhHvCgz9oxjoeDblc6+Q4B4ZBXCSBQx+GIZhNAOURaACsYypq0kNeSSLC2uxm5fGZqAgqFO0OjT/wRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkmidi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/Lz+/CH5BAEAAAAALAAAAAAQABAAAAIzhI+By7oBo5RH2GvDRRhre0xiVHXZVpqfEI5iKkQxalzQIIPGhI+pSAN4cjqA68VIHvwFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkmix-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXAT+/DQyNATCxMTCxPz+/AQCBKSipASChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEMgJQqCXziDG2JoUEENhZBkmHIWJVptAmqcIW/Js1MiF56TBzkckAAcHoa9nMRKeA4TyJk0knsHhTeK5khBaH2VwLYVh40TJhQ6RzeIQV32Quz8hfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nknewsticker-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBMTCBPz+xPzCxISCBKSipISChCH5BAEAAAEALAAAAAAQABAAAANTCBCsysEpseQDI08KSPdYNmwUYSraUDRC64iAMbIuLGtOS423BhKFmgj2C+5EhsOoWEsOnB0FsKl0jnLUp3IG0O2sMNpRVHBAJpjyA8KOmNsMfwIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nknode-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAABwaDAQCBPwCBDw6NERCFJSWJAwGBLy+rPz+7IyOJJyeLBQWDIRqZIxydPzCxDQuHPTWzOSypBweDKyqLJyWJKySjPTOxKSCfOyCfOyKhJSSJJSSLFRWTDw+NOSqnOR+dOyWjOzGvNza1ERGFJSWLLy+ZPTGvOTOxOSSjOy6rLSypJSWjKSinAwODHR2HISCJOTWtPTe1Pz+9Ozu5IyKfNzazPy6tExCHMzKfPTy7KyupKSmnEQ2HHx+HKSiLKSiJPz65OzuzOTmrKSmLIyKJLS2TPTyxOzuvNTSlLy6fHx6RLy+RJyaNLS2NNTSnLy6lLy6dMzKpGxqXCQiDKyuNMS+PLy6VMTGPMzKrOzq1CwmDLy+PMzGTNTWxMzOxERCPKSiNCQmJERCRERCHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAQABAAAAffgAABAoQBhoOEAgOGBAUEAocBBoOLBwgBBAkKBAsMAQ0ODwOWEBEBEhMUFAQVFhejCBYYGRCGGhsKFBwdlh4fICEIIoMjBRQkJSYnKCkWCCorLIMtLgUvCjAxMjIzNCw1KoY2NxovFDjbMjk6OjuHNjw9Pj8lMggIQEFCATaDBD4JhhApgsDIESFIkigxJGDEkiJFmDQB4uQJFBxPokgRMIVKkypFrFxBgCVjlnuXtARQUGTLFS4yunipgRLBF0I3moChgsQeAg5hxDBMNCUAlyAcOCBKxJTQmKVNBfgJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nknotes-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBISChMTCxPz+xPwCBPz+/ISCBPz+BMTCBIQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARIEMhJZQg1z6vzxR0VCKE4gCE2lhcRnF1LuAInBjNRfDMn64WCQRCcHS6IRE6nyB0Sx0ACkcwloFiflKp8Pm2bbRblkYJZHX8EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nknotify-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/Pz+BPyqXMRaBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMyCLoQznAFIUKE09krZ+VS9XBaMBBbZKIBUaSYa40kTIPNhyvazje+G2gFI8l8jaLCnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkonqueror-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxONCROfCRKfKx6LNy+bNTOpGSS1DRupAwyXBRSnPTSjPTqvOzqzMzSvHSSlKy6ZDxutAxCpBQ2XBxepLTKvPzqzPzy5OTShLS2dLSqRFR2jBRerBQ+jOTixOzetNS2XHx6XDR2tCRexBwyTDyKzOTavPzq1OzKdCx23BRKtCQ6VCQmHFSa7IyirOzSnGSGpIR+bFSO1DyK7DR+5CRixBw2VDQuHFye7IS27NzGXISuhEyS5DR25BRWxBQ+lBQyXCQqPCxSfGyu7GyerKy2ZFR+rERqfCRmxBROtBQ+fBwuTBwmNDSW9JyabLyqRIx+TExSXBQ6bAQCBBQ6ZBxapDR+zBxq3LyaLJySRHxqPGxeNBxGbCRmrHRyRERONDRKNDQ2JCQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAeygACCg4SFhgABAQIDh4MBBAUGBwgDCYcKCwwNDg8QERIThRQVFhcNGBkaGxwdoYMDHhcXHxggISIjEiSvJSYXJwsoISkpIyorLIIDLS4WLzAxMjM0NSo2N8o4OS46OzwzPSk+P0BBgkI8Q0NERUZHCEhJSktMgwk4Qy1NTk9QUVJLphCiUsWKlStYsmjZQiJgIS4KuijQ4iXAFxYCDVFJwGUFmDBhMjYSw0KMyEYoBfkJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkonsole-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXFRSVPz+/PT29OTm5OTi5DQyNDw+PERGRExKTHx+fISChIyKjHRydFxeXDQ2NCQmJBQSFAQCBERCRMTGxHR2dGRiZExOTDw6PCQiJAwODCwuLFRWVOzu7BweHAwKDCwqLHx6fBQWFGxqbGRmZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAanQIBwSCwKAwKkMslEAgSDqDRKqBYKhkNgcDggEorkMrDQchkNhuOhgEQkk0l5S2lUGpYLJqPZTAwMHB0DCmhqAW0Rfh5zAxgOkBcCFAcfIBMECxwBBAEPFw8dChkhcBMDDAcdnQqtFKSWcQMimx4dGRkQBxGxsg6bBQEawx8jl3GnJFoFHRNXVVNRJYIFDAsL1tgiDiQXFx0HABwcXeQH5OjkRutEfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkorganizer-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBASCBISChFxaXPz+/Pz+vKSipLy+/MTCxPz+BPyqXLxaBAQ+BPy+vAAAACH5BAEAAAAALAAAAAAQABAAAARmEIRJqw1ikM37FsFQjMZ4lAVKBESBjCYsFiuBkkk5KG1dJL+CZjBYMES+l2x3RCBqtxHBOFD6DkHmAQj0yXgzmFdIhY2erBJBwTiczDSWq0Eg1gvYrvyHxcMdUEojYWIYHocbDX4RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkorn-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBMTCxPz+/PwCBMQCBFxaXISChKSipAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARSEMgQpL03CEExDkO4dR6ghSFBkJa2CSlRcNX0voNQ5Ebn3pvdAWHo/W6IHUJwGFCAm+SrSTm+ZgcY6XnDhlim3wwxKNYymiX17HmCSxO4/OKPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkpackage-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+xERCBMTCBISCBDQyNAAAACH5BAEAAAAALAAAAAAQABAAAANPCLoR+7AJ0SALYkxd79za12FgOTlAQBDhRxUFqrKEG8PyOqwEfMeKwGDI8zVGul0vFsAFdaxB43ecKZfUKm1lZD6ERZgBZWn0OpYvGeJPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkpager-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBFxaXISChASChATCxKSipMTCxDQyNERCBPz+/MTC/AAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARWEMhJZ7hADFI4+RpwBYBxFJ1HmMiYJUgiJPI8Bwmp7HyvyBOfMCHR+QwzhAAhMvZKSFgRIOwtJczqboFoBasGGVNUKVNGaEyTlEYL1sX2pYXOyO8XfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkpaint-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPz+BAQCBMTCxPz+/PwCBPzCxPz+xPyqXASCBMQCxAQC/AQChPyCBATCBMT+/ATCxASChIQCBKSipISChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAV1ICCOYxCI5kmigTCYBKGW7WAH8QyYrn3LNFesYDgEjCVXIRYzGgWqgA2BICQUx9pMSkUssgsbFOWighW+7c24KDAKDccjCjVCHAEGo/GYl+wPLwwRfF8oT2mDAwuGWVJiARERAxITJkhaJhMSlJY7NDQpAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkpixmap2bitmap-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwC/AQCBMRaBPyqXPzerPyCBPzCxPwCBPz+xMTCBPz+BISCBMT+xATCBAT+BASCBMTC/AQCxAQC/AQChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVkICCOpBicZQoEwjAE6hgQQwvH81AU8OnfuR3QYDgcgAKhjGj8+UgzQkHHw+2mQlQpgEAkFInEYnGDhr/h8VPGYDQcjcZj/iiv4u84vQ6FQCISERETgxN2AX6AgoQThlBOkCR+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkpm-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxKSipPz+/ISChAQChMTCBATCBPyqXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARbEIBAa5BYUsHF+FQ2EUTHfUOoFQVpeuAVGAbrnmg603U7FD8UxXDgGQgoYMyAIBoSyI9Sx2seoj/lRlDFTmUBDs0L0gg2CGwFs93oWJdMOwCPiybhguout2f8EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkppp-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAAT+BGSOhERadDxKbDRKZExWXKzG/KzO9KS+tER+lBQyNERaVOTu5PT6/OTy9Lza5LTatISylHSilCQ6LNzq9MTa/LzevKzKzIS6dBwuZISi9MzizLTW3Iyy1IymjHyGbCwuLDRGXHya3HSe9Jy+/MTe5Pz+nPzmhOTSbGyGXGx+XCwyLHyinISe/NzifFRKTFRqXCQmJExSVFyafFyC9MTCvAQCBMTCxExKTDw+PMTGxLy+vNTS1Ly6vMzOzNza3MzKzHRybERCPDQyNPzCxPQODHR6dAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAengACCggECAwQBg4qDBQIGBwgJCouDCwwNDg8QERITlIUUDhUWFxgBC4mKGRoGFQcbHB0eHyCLISIjJCUmJygpKiuLEywjLRYuLy8pMDGLATIzNMk1Nck2lCDJN9TcLziKOTg63DvcPD0ygjk+P9zcQDVBQekAQkMgPjzcPfLy1wAgiBQBAYIHkH5BbPwTBGKIQBBBjAQBsXCRDYJGZFSkJOhIM45+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkpresenter-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwC/AQCBMQCxPwCBAT+/MTCBASChATCxPz+BPz+/ASCBAT+BKSipAQC/AQChARCBCH5BAEAAAAALAAAAAAQABAAAARhEMhJq70YhM2D5UIYDARHBUWxEcRgHKgncWyLuPEc1MOAJLfBRsNSEBYbH8kw3BEUyABjZHzJdsiGI6AYLBQG5qykDSy+jwdLpimj1aVhe7tIr00a6Q4uP02dfRVygRZ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkruler-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBFRGDPTijPzmnKSGDOzWdPTahOTGXOzOZOTKXNzCTNy6RNS2NMyqHNSuJCH5BAEAAAAALAAAAAAQABAAAARkEMhJKwg4643FEIQHimHRfaiYmoFxvMLhwi5r3IaA37rBIomgABhEDBM/hHLJVCBYCwFjYVxQBdYFi8GQertSLqshaJgFZbK5wXI4BO63W/Bwt+HzON7BKvj/gIAcgxoWhhN+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkscd-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBKSipFxaXARCRPyqXPwCBAT+BMTCxMT+/AT+/PzCxASCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARbEIRJa5Ui672nsNYgegFhFoRhCuJAEgcsE+wYfHIc0y3JbT2QsOJCGG+/zyShMCICregEsUgEnNCe6/rsPkPTY2LxZLEOh4DEqbBmRQyGen0kjgB4ySSPp+D9EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkscreensaver-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXAQCBOzu7Ozq7OTi5Pz+7Pz+xISChHx+fMTCBARWlARepOTm5ISCBNze3ARalARanKSmpARSlHzC9ARGfLy+vKSipARKhAROhARKfJyenNTW1AROjARSjMTCxJyanNTS1JSWlMzOzNza3MzKzJSSlMTGxLy6vLSytKyqrAT+BIyOjPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAalQEBgOBQYj0fhYEAoCAyHqPRgDAyIggPikOAeFFVCYMHImqnfaiPAKH8VcLij+ghAGJFFlnuUCAJ1ExR5AnACFRUWF39/CxETXQoYGRoaFht/HAEdE2AeGRgVFBUfIH8hmx4doBihGokifyMPAiQcISEjJR+7HyZ/JScfFigpKSoSFxsiKywCAEjR0QDU1AIJFi0tFgnP1dYJ4QgJ4+Xe1tLTAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nksirc-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAAT+BMROTPz+/KQGBFxaXAQCBDQyNGSGzDRivAw6lAQmbCRGlAw2jHSS1BxGpAwiVGyO1CRWvBRKtJSq3AxCrEx2xAxGtAw+pAw6nDRmxAQmZAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVYICCOQBCQKCoMaRsMbCvPNE3cRA0QRWEciIQigQLyfAtGqtFwPI6GFgQReex60WJEYr36UpOtQgQlUQAVieUyLoskY8Bhi3liEZJ6MaOmWCgJGjYGhCl+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nksnapshot-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBATCBFxaXISChAT+BASCBAT+/PwCBPzCxAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARLEMhJKw3YViw6HkRgBUVnCkG4GUV5otthsO6A3KJEHm6R3AOYTtAy2QqzHCDwMpiSk8DsxIFGpc6T9YJ9GpSb7laDSYI1yzNa448AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkspreadcalc-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBATCxARCRASChAT+BMTCxFxaXEQCBPzCxPwCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARPEIBAq5U4iM17wJMwjORIfJkYFCs7nKA2rJQLp0Su66ikGcAg8OYTGA6BA/KAIIYsFudPGJQal8uAFVqxUg2JxBYbUGh7k5J6BppwKyB/BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkspread-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBAT+/Pz+/KSipPz+BAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANFCBDc7iqIKUW98WkWpx1DAIphR41ouWya+YVpoBAaCKtMoRfsyue8WGC3YxBii5+RtiEWmASFdDVs6GRTKfCa7UK6AH8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nksysctrl-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBISChHx+fPz+/AQCBAQC/AT+/AQCxAQChAT+BLy+vAR+BAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARYEIAgqK1YzsG754QUDERpmkEpkkXrtoK6EcVgHIibhnNx564Yb0TDvQq7FQ34EiqPOhnREqhWSUPsyZSQAbbg7GcMEgwUiYVivTa1R+y4XEGoWO/4AMAfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nksysguard-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBExKTERCRERGRAQCBFxeXKSinIyOjJSWlKyurKyqrKSqxPTy9LSmxNzS1Nzm7JyitJyipMzOzLS2tOz6/OzW1Ozy9Oy6vNyCjNRydMR+lNza3LSurFReZMTG3Pz29OSmrMx6hDw6PKS2zMTCvOyytOSWnMzi5MTa3NTS1LzCvNTe5Pzm7PTK1PS6vOSapMyKjNTy9KzCzMzS1GxqbISKxOzq7Ozm5Oza3MyytLzS1Nz29OTy9LTS5GyGtOTe3MzKzOT29OTm5KS2vKSurNzy9LTW5OTi5Mza7NTm5KS61KyytOT2/HyChHSChHx6fNTy/LzKzMTCxLS+vMze5KSmpLzS3Ky61JSSlLTGzLTa5FRSVJyanKSipJSWnJyWlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfagACCggECAQEDBIOLAAEFBgcHCAgJAYqLAQoICwwNDg8QERKXjQYTFBUWFxgZGhsJHJcdHB4fHxUgrCEiIyQCjRwWthUlJiG7IycoKQQBKisfLC0uLzACJzExMjMBNBI1Njc4FTkBOjs8PT4/3UBBQjc8FkNEQTtFRUZHhyQySEkHOAyxgOCcEhkSLC1ZwSRGEx1OnBx4EgNKFCmKAkyh0uNADBpDOpyQ0YNEAEJVIFjBZg/bFRIRSAXAwiFLDyNaesiYEJMRgS1cupDg4OXLFlI+DwkQgBSAn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nksysv-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/MTCxISChIQCBAT+BAAAACH5BAEAAAAALAAAAAAQABAAAANWCLoQzlA5IVyIK1S9L7PDsFHBIJXDFFaViYYEUQpy6orEqq12Aw+FmkjQQxEKwQCBSCz5BrGYkuc06nKU4s8gW4q0UAN3+q3CZJfJRhJ6fDwZOGbhTwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nktalkd-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBKSipMTCxARCRFxaXASChDQyNATCxISChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARYEMgZqqXU6gCuDIJQDQTBBQX3hUFpmN2hFaxhIPCJDrRo46dPglf7BTvDXsB2OwaSCd8tZ0kWgZ3Uk+hDvHRV5bfyybACPNmkY2EVZKpM5UBPre8fD94fAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkthememgr-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBASCBATCBAQCBDQyNPz+/MTCBPz+xISCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMhJaw1V6Bs0HgIWYFMnhSERkiU6ekM1FO9IGMcxIFK3jgGDzRADhAypQipI7A0OId1IaGhKntHDjWogTLCB3JbpvULD2ir5i0SPDYjy9ZgWDuQUwqBLLFq+ehZ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nktimemon-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPz+BHSG5PxSVDRW9PwuLPQKDFze1AQi7CH5BAEAAAAALAAAAAAQABAAAANDCLrc/lCFGeKi1YktAH5c92mcR4HloA4P4RLAyjovLLdvvD5FX+gqgGFoUPh+N2IRcAQcngch0ehzQqVDas/6xBb9CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nktip-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBGxubFxeXAQCBOzu7OTi5NTS1PT29Pz6/Ozq7Nza3PTy9Pz+/Nze3MzKzMzOzOTm5MTCxLS2tKSipNTW1Ly+vKyqrMTGxJyenISChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVwICCOQRkIY0oORFEYqCoGw4EcSaHEarAgDESu4RioBIMfA1doPIwpZGJBhTQMEWh04GoqDBLtCKkYNL5hGUAwoZQfFYs46lBQLnK1SICJUCR5egMZGBgZcyoDGAwTh3oiAxMMhogpioyOjwADnIh+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nkuser-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxISChAT+BMRaBPyqXARCBPz+/FxaXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARLEIRJa5Ui673nsGAgeKE1Bl9AUEXbiqTlFlZaGUZoszm4BzhDAVf5BYbAXI+TAR6CS2ZGSZSEiIIqYIsSIEaJ7GRrlY7J1lKA7I8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkview-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPz+BAQCBPz+/PzCxFxaXPwCBPyCBPzerPz+xASCBMTC/PyqXATCxMT+/ATCBASChIQCBAQChISChMTCxKSipARCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAV0ICCOYxCQaBkIwpmKJsu6qDkIREDMZFwUAYNwRVuxgLfDAUGEsRIJo2LRapUE0ABDsa1aAcZoo+stsnIMwcDQcDQUV9MjF4Q4GJFiQJJuGSYOFHkwezJ+ExUUEicmYDITARATAoomLiuQJhKTlTRgepYBfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkwin-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBFxaXISChASChATCxKSipMTCxDQyNERCBPz+/MTC/AAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARWEMhJZ7hADFI4+RpwBYBxFJ1HmMiYJUgiJPI8Bwmp7HyvyBOfMCHR+QwzhAAhMvZKSFgRIOwtJczqboFoBasGGVNUKVNGaEyTlEYL1sX2pYXOyO8XfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkword-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBPz+/FxaXISChPwCBEQCBIQCBMQCBMTC/ASChARCRAQC/AQChMTCxAAAACH5BAEAAAAALAAAAAAQABAAAARiEMgpQ6B4WnGzDkLIeVs4DAIBWFcpnKJVzCUcz8ZxVOKN/AWNKRQo5HQYELHwQxQSHR7HqDuwMIRisxBQLBbRFdUaYCwYjUZHywIxGI53K0jolRkJdLkhtKwaeWpJYW0AfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nkwrite-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBKSinJyOfPz27Pzy7AwKDExOTJyWlERCRKSelPz69LyyrKymnPz+/MS2fDQyJAQCBOTazLSiXOzivMS2jKSSVOzmxPz25NzSpPTu5KyebOzixNTGjOTWpMSydMSybCwqFGReVKyaXNzSnGxeNJSCVMS2nPz23MSuZIR+bJyShLyqnOTOtGxiXIR6XOTSvIx6RMSubIyCdKSalMS6pOTWxMzKvKSabJyKTOzezHxuPGRmZKyurMTCvPTq3AAAACH5BAEAAAAALAAAAAAQABAAAAajQIBwCAgIiEhiYEA4FgwHRDKhIBAWz4OhgGQ0FAPHA7qFEBONb0Qy0ULeQ2+aUrFcMI+3GYBOZzQbHB0eHyAhIQByDREiEwMjFRIkJQImAgJ+jScjHigkKSorLC0AKg2NFSMoki4qCy+IQgITKDAxkjIzNDWkQxQoJaskMgk2Eb1DNzgoOCoHDDY5yEIwJToAOzw9ET7TQiREAhkZ3kmy5QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nlaptop_battery-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/KSipAT+BISChFxaXPz+BMRaBPyCBMTCBDQyNAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARtEIBAq5w1TBGEGIM2ESTlVUNhaAFJUAcXgAXCZkFyJEoiIArWYQjj+Xi2yfBA0SU6CuAts4MCk4EdcxbznFhOCsjrWUxRhbRBBk48Z6kCZ2GeuN9xucF8FqcEBnt1OW4saSp7IoRPEjgiGBV+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nlaptop_pcmcia-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwC/AQCBMRaBMTCxPyqXKSipFxaXASChISChMTCBPz+BPz+/PwCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARfEMhJaw3Y2iDGyJoUEIVRfIHGEcaBHCc4jcWbGG2cAuuhKIZE4mX68EgI3M/wORgQGAHr4HICD4NCKoBIJqsv7w6DKDgNi0VuN+O+GIxFl00hlxjakIhbo4cwfnoWfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlocale-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/AQCBPz+/MTCxISChMxKTKSipFxaXERGRGxqbCQiJDQ2NJQaHMwmJDQyNFRSVOR6fGwSFNxSVKQqLFQODJwaHOyGhOySlNRCRMSuBPz65PzupPyCBJyOLMxyJOTKRLSiNIR6JExCFGxaHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaPQEBgGAAYhcWjUMAUEAMDQtIIZRauBaZhKhwIsFjBgFu9HgKHrHNI9QYQCQQarWB313D5Ik68BxgIDQwOCgcJD2wBWwENEBANEQwMEBITFEIOQhWNkhENFhcYl0l/GRobHB0MGBAeo1QdHxsaICEfpyAiQlQhICMiHyMgs8FKASMjRiK/yLrGStDRXNFGfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlooknfeel-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/ERGRExKTLy+vKSmpAQCBPTy9Pz+/IwKFLQWNPT29GwOFExOTIyKPHx2NPz2pIQSHLwWNMzGXFxaLLSytERCHCQmJNze3GxubLS2tHR2dAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAWNICCKgVCWYwoEwUAMhXEQhhocRuHCMpIgiJVBptC9DojDIrFYwRS4wgGJZAIYuwL00Ej6FjOGEXZwPByQCNjAyrnKj4NkAqYUBIIoXC5pVGYUFgIXU2Z8fgdGFhgZiRqHf1EDFgCJGAcafX9aUSIFlxoFBX8vMYmemKJSY6Ijn6oHF26tKbAEGCaUKX4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nlyx-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBAQChARCRKSipASChFxaXISChPyCBATCxPyqXMT+/Pz+xPzerPz+/AAAACH5BAEAAAAALAAAAAAQABAAAARZEMg5Q6C4BnGzHsRgeVZRGIbYaekxuAFijUGRBOqMKPxlJQsLQxjoVWyWBsMxNEp+iRuj2VvVCklHLCZjiRrawGFmNQUajQ129RwYyCMSau2pcNh1AB7jjwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmathematica-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBISChPwC/FxaXIQCBAQCxAQC/KSipAQChPyqXPyCBEQCBARCBASCBDQyNCH5BAEAAAAALAAAAAAQABAAAARlEMhJ6wxChiFFCBUhENtQGIcBUghWDsHxWck7wMpKfXz/ZYBAYeCpKRQLWwkjMCpQJQ3TE8gdUgxPUMDlflINhzfocJB6BNEDqLnKpgRLTJZjBuIUAf1TExR0EyRASWmAFocAfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmouse-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBDQyNKSipPz+/MTCxISChPzCxATCBISC/MTC/AAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARSEIRJqw0Sg32rAANBFNwlhIQhGkNGAaSaouW0iYUBEIdYgzsUIqHAuWAoQlGEE9gMJKaU8IPupqLWy3qVkioAFqkLc9nCg3G5oxFr2ecavOOPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmozilla-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/JxqBHRKBGw6BHwuBHQuBKwmBKQmBIRWBGRGBMQeBKwaBHxSBFQ6BDwaBEwqBEQuBGQuBFQOBGwSBGxGBHQ+BOQiBPQmBLQaBKQaBCQGBIwWBLQeBDwKBHQSBGQ+BIRaBHweBIQWBNQiBKQeBJw6BPxGBNQuBLwiBPwmBKweBIQiBJQmBHwyBIxeBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZzQIBwSCwahYHA8SgYLI2EwpMoMBwQU2FCsRAYGQ3HwwGJSCYPCNnRoAgrlgsmo8hkLJpNpEjhbBYdHhYZEh9HICEiGRMjJAxPJSYmJxkoSocjKSorExYNSwMXLAwgDhYVSwUtRAMORwGfRR8uRpdGWEJ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmultimedia-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBIR+hKSipPz+/MTCxMRaBMTGxOTe5MzGzNyytPyqrPyurLz+tKzqrPTy9LSytNTS1Pz6/Nze3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAWAICCKQWmOKFAKQ9uWacAOJcEWQjDKrxHYJZxONRAQaL+c76DjyY4D4A+RC9B8xkPiQKCySsjAQZAojHMva9pk8iGrCsWC0Wg4HCvT4wApyO0FEAcRJhKGhzUEioolDw8TgYQBEYITCIQqE4IRCnQOEXyYJAFxCwt1dzAxbCcjfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAAQChPwCBAQCBPz+/MTCxKSipFxaXAAAACH5BAEAAAEALAAAAAAQABAAAANDCBoK8TAC8Vy8QUyGr9BaFwmDZonZp66sIhBwLBMFlRl4rhv1IxiDoHDYuw1yw2Dxl0wugTqnjdkUPmezJWv7QXX8CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnetscape-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAEyStPwCBNTKrHRqPAxSfLR6VNzWvAQCBEyOrFxGPMSWdKx6XPz69Ozm1PTy7NTOtOTOxKRqRGxCJPz6/MzGnMS6jDwmHEyGpPz+/Hx2bGxiPOTexFxWNLSmhMy6jLyGXNSqjHxSLLyuhMSyhLSqhDQeDJyWdJyOVNTKtPTu5KSONMS+rLyqdMy+lFxSNOTezKySPEw+FEQ6JKSOPDw6LNSylHxSNKyWPLSeXExGLDQuFIRiRCRCVEwyJAwODLyyjIx+TNzaxMy+jBwaHNzGvMS2hMS2jKSWXGw+JFw6LKR2XCQ6TDw2HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAfVgAABg4QCA4SIBAQFiAYHiIQICQoLAQwNDg0PgxARg4oSChMOBg0UAgYVBRaDFxcIGA4ZGhscHB0eHISKoxkfARsHICEiI7oBrg0kGiUfpCEBJiIngygbKQ0bG5kjKisbFSwtAi4HLx0cBwYiMDEyJh4zMjSKKBQuNTY3Mb8vODk6kLky0GEHjxUyeiigMMPHJ0UCKvw4sQFIECEqhgQUSCSChRFFWhg5MkMjkk9JlJRY4uIEixk5fOhAsuOkqyFLXF1oQYOJTiQIAigaqohCD6JD/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnoatun-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBCQ2PARehAwODASCtASi5ASq7JTK5PT29MzS1JyipISGjAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARlEMgJgrg3zDHkCEQoEhrnVYXBDUVRdmagHjT7AnExHPtg3LldzYXr4FA6juHnMXZkqaiGMpEtOdOmETpAIEy473fV9Xphq7P6DEgMFIpFWm1sJ+4JBec8SFAnd3pveH+AeHcSfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npackage_applications-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAFxaXGRmZFRWVARehAxehFxeXOTm5MTGxKze7JzO3ITC1HSyzGSmvFSWtESKpCx6nBxulNze3MTCxAQCBByezByWxBSOtBSGrAx2nAxqlARijARafARWdARSdARKbARGZARCXOzu7Pz+/Pz+9Ozu5Nza3Pz+7NzexPz+5NzivGxqbGxubNze1NS+vPTCvMzKzLz6vLzevPwCBNzevAwOBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAADIALAAAAAAQABAAAAamQEBAMCAMikfjQMAsGA6IhGLBaDgeEEJEMhFIJBRKxXLBYDKajeTQBQAGG05n7vl8QABBNyTq+/8iIyRdJSJrgCMjJiYnhCIHEn+JiygpXQaGB32JKgErKiuNAoV+iQIGLBItLhOOgYkrmAYvLikwl6+Lo5gTtjFdLMHCKy8vEyITxV2tzBMFMTCWIgYlEzLX2NcwMy4vstngAS4tLyUGNODprdl+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npackage_development-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/GxKFAQCBNSyhFQ2FOTGnJRuNOzWtPz23FRWVERGRJSGNMyyZHRydOzu7PTy9Ly6vOzq7Nza3JyanMTCxHQCBLxWVKQaHOTm5NyOjMxqbJQSFHwGBDw+POTi5LQiJJwWFPz+/Pz6/PT29NyWlMReXNyenLQqLIwSFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ9QIBwSCQGBMWkMDAgKIuBgsH5FBIO0+oSka0mFAsGtdpwLMbPxONBgCDJEQkEMnkn1RLKRGF3+CtCDRJ7AoUSEgAWFw+AChB8hYUYGRobHIwAHZGbHh8gayEhIqGiIw9+GBgSJBoliiGUrhcOJq0WJyAbKBUhnrocDr4ofkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npackage_editors-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBLS2tHx6fOTm5Ozq7OTi5Hx+fPTy9Ozu7PT29Ly+vMTCxPz6/IRuPHROLPz+/LyOdLSCTNSmnOS6vPzmzISGhExOTJSCZPTSxPTKtPS6jPSujNyKZGxqbDQyNDw+PHRaTKRqVLRqRLxqTMxmPOR6NKyurDQqLExCRFxKLKRSFNza3KyqrKSmpDQ6PGwyBNze3NTS1LSytAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaWQIBwSCwahwFA8kgMOAVLpjMgGBCixamgECAYsELtoUAuXJtPRCCRMBu44ecBoVC0F2aC8qkIKBAICQx5X3INh3UMbQMOD05/AQ0QDQoMERITFBUVThZ1Cg0XFxgZGhobHB1KHp4NCR8gISIjJCQlJmGsCAULAicoKSoqDytIrAkGBCwMLS4vKTBNrAUJCzEBMjMuM35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\npackage_favourite-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBPz+xISCBMTCBPyCBMQCBIQCBPwCBPzCxAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARYEEgZwrQzVyFq6Bj1gQOxgcBYDSzhnl7Azm7tpWT7VhdHmoFXzweqmYZE4I5C5AQKhkMAYbCMfM9EIWBAIKzNLNRbTRHCBUT6ewn6TOlyJuX2sOftS8YfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npackage_games-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBPz+xISCBMTCBPwCBMTCxMQCBPz+/KSipISChAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEEgZwrQzVyFq6Bj1gQMxgsBYDSxhqunKtu5bpSQdFDfFkS9DgHD5cTwBIdFnFLiSw2IzGGX+AocDNHQ6GhCJQCJsGRqThm/CoMBUCNc1W9HWmD2Jdsh+CfkjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\npackage-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+xISCBMTCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANECKoR6ys2IVqokF08yMTA1gwkYX5WQK5ma4VceTYPxXnBWdtY6+0834/Bowgzm6APWRQcH4TiMhPK2WYRiZWW7XK7/gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npackage_graphics-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAASC/MQmJPz+/LwuLLw2NLQiJNTKVNTOZOyydNRaXMxGRJQmJFQuXFRypFySdHS+VLTOfNzWhJQeHFwCBGyGtHyqlIzKdPTapAQCBGRCbKTSjOzqxLzG3MzmxJyanBQSFJSSlBwaHCQmJGxqbFxaXNzmxPzmzOSenExKTLSytAwKDAQGBMTS5LzerOSaTFRWVHR2dJzOhLTKdNyiNDw6PFxeXDw+PLSmvKS2zIyynLzSjNTKXNSGNIx2lIx6tISavNzSbLwmJHRWfNzWfIRurIyexOSmPJweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAejgACCg4SFAYWIgwECAQMEA4mCBYwGBwgICQoFhowLDA0ODxARCAQSkp0TgwwUFRYHFxeLARITGIUZFBobEgUBC7aRHB0eBcC3iRgfGAIgISKRGCMeIhgkJSYniBkoKSgqKywtES6bgy8iMCgYyhwxMjOb7Bg0NTYr7Dc4OTo7PPIrQoRgJ6iHjx8xgMwIEgmAkIMxhsw4lYgBkSI5LEQwcsRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npackage_multimedia-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXHx+fHR2dGxubISChNTS1MzKzLS2tLSmpNSytAQCBOzu7Ozm1Nza3MTGxNS+vOy6vPy2tOTStOzq7Pz6/Nze3MTCxOzOvNTqvLT2tDw+BOTm5MzOzPy+tLz+tLz2tOTi5LSynLz6tPz+/NTW1KSipMy6THx6fMTKxKyOLNTGVPTmbLTOtBQOBBQSBKySLHReFLzKvLzavAQGBCQiDNzKVOTSXLSWLNzGVLyiPNTCTOTaZLymPMSqROzebOzeZMSuPBwaDMyyRFRKHAwKBOzibMSmPMy6RLSaNLyaNDwyFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfKgACCgwECAwQBg4qCBQUGBwgJCgsLiwAFDA0OBg8QERITlYMFFBUMFgYXEBIYGRoboxwMFRQdCAoeGR8glAABBgshFA8BCxsiI5QklY4lJQYbJiQbypQnACgpB5ALy92UKissAAQXDyktlBUuLzALMeG+MjPKNDU2LDc47yqC1Qs5dODYwYJHj3f/Yrxb4QPHiR9Aqr0I4kNFDCExdgxRQaSItyA8jJw4YvFFjBdCGtCotECFjhssVgRR8W8QkgVJlOBb8k3UID+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npackage_network-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBPz+/CRKfERCRAQCBFxONKx6LDw+PDR2rAwyXMzOzOzq7AwKDHSSlKy2ZDxutAxCpExOTBRavBQ+fBQ2XOTi5OzWhFRSVBw2VGRmZDw6POzKdCQ6ZBRKrCQmHAwODIyirGSGpIR+bCRixBRKtCQ6VDQ2JBw2XIS27DRKNISuhESK5DR+5BQ+jCQqPCxSfFSa5Gyu7GyerOzetBw+XBwuTBwmNFSa7Eye7DSW9JyabLyqRBQ+dBRerDR+zDx+3Bxq3LyaLJySRHxqPGxeNBRSnCRmrHRyRERONDw+NCQuLCwqHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAeygACCg4SFhoeEAQGJigIChQEDBIIFBgEHBAgCCYMBCgQBCwyhDA0ODxCcAAqRihGXiooSExSCsYoVDBYEFwEEEBiCrBmgGgUbigMcHRgeth8gAR8hIgQECyMkJSaCAicoICkqASssvi0YLoIvMDExMg4zrjQTNTaDCTcxODk6OwQYJmCYNIhHDx8/gAQRMoRIDRcEBwkoYqTIkSMFkNiISCjBCR40UiQxwdGQEg9LSvoJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npackage_settings-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBISChGRmZMTCxKSipLS2tHx6fPz+/OTm5FxaXOzu7DQyNMzOzAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMhAq7wYBDECKVSGBcbRfcEYauSZXgFCrEEXgDCSeIEyzKSXZoBYVCoJVIqBGByKu0Cy8QHxmgNngWCkGgqsGWFseu6oMApoXHAWhWnKrv0UqeYDe0YO10/6fhJ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npackage_system-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBGxqFAQCBPz+/PTqtOTOfMSyPNze3Ozi5KyeLMTCxMzGzKSipOTe5MTGxAAAACH5BAEAAAAALAAAAAAQABAAAARfEMhJQah4ihFunsFAEIVXCVJACIJhoBK6CerawsA8HAhbuAnYZrBDKBYMWpCy4S2QSRazyBIwrrjcoNFQzK4KR1bQcHhZjGM2BgWLMYJ2enForHPJtNj+kfHvcB8AfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npackage_toys-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBJxyLJRqJGxKFIReHKR6NJx2NMSmbEwyFKyGTMSibFw6FMSqdCQWDIxeHNS6hAQCBDQiDNS+jOzexCwiDCQiHLyeXFxGHLSWXJwuJGweFHQiFMx2bLRGNGQeFNTClOzSrLxKPLQ+LLxOPGxOHIxmLEwWDOzatNS+lKyKTIRiJJx2PIRmPJRuNKyGRIReJJxuLKyKRMSqbKSCPEw6HNzKnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAauQIAQEBAMhITCcTg0CA6IhGJwICyYwgWjEQg4HIgHBCuMBCCSM6FBHiIOk4cg0hYiKAFFxUJBtC8YGQgBFhAaBVdMAw8bHB0eHh0cGh9LAAMgAxAhHiKPIxAkH1cXEiVjJiQnKCljECoWCAgEFGUrKBYsYwARKnQIRxG0Ky0QtAAIvwcuAwQpLxDCGDAIMTKyMSczs7sQATQz2mMIMyAXu0IQNDUu6AgQ6EPwu35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\npackage_utilities-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBExKTERCRAQCBOzu7Nze3MzKzLy+vCxqZBQ2NJyanKyqrGRiZDRydKza3FRWVPT29LSytDw6PMTm5EySjCxaXGRaJFSanCRSVGxqbPTmvMSqVJTW1GSurHS6vOzq7KSipISChFRKHJSGNPz23GxKFBQ6PKyurCwqLMyufJx2RAQGBJSWlEwyDIRiLNy+lLSKVDwmDJRuNOTOrLyabGRCFDx2dKSCVOzWtHzCxOTGnNSyhAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAahQIBwCAgIBAOiUiggFAyHASKxDAwUC8Zg0HAglA9IZPGQABoTSqJCFTIOEIsFgHBcEhhHUpKJFCwaGxYYHB0VEx4IEh8gIQwiIyQbJRMcHokmEicfDygAkCkqJQgIGG0rLElCLS4vMCWqQwMCQg0UMTIzNDVLQjaIGDE3ODQlS785CEkxKjowvEOHybG4O6JDCdNKuDUxRAmxRDHeveUAfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npackage_wordprocessing-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBHx6fPT29FxaXPTy9AQCBHRydPT25Pz6/ERGRIR6PJyORHR2LDQyNLy+vNTW1Ozq7Ozu7LSiVKSiTIyKJJyenMTCxMTGxNTGlNTSjLyyRExGTExKTBwaHOzivMy+XBQWFExOTNzOhIyKjFxeXDQuNMSyjNzOnBQSFNTGjDQuLCQiJAwODCwqLGRmZHR2dAwKDCwmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAafQIAwQCwWhcihYMkUDJLIAKG5fEILhoOAgGAmCgXFgsEoNByOxwMCiTTAEsmEAq5ULJbLxQEuYCQZGn0JGwkcCR1gCUIeHyCJfX2JIUIHIiANCQMGIwYkCSUgi0KPHSYdJyAnKCkdHQ1IrhgdGCC1s7UqSCsdKLi0wL2xHY/FxMcssS0JIS4vIy8uIQktHUkgKygsMNwwKCAxUOLjAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\npanel-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/FxaXMTCxDQyNAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANECLrcEDDKGYQV4+qbie9eGIJEVxTe+QmjUFgnXLLr615oF8x2v0I8DWpF2GV6slkLKSMdYT4nS0WgSkXYAWUbcXgX/gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npanel_settings-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTCxPz+/PzerISChPyqXAAAACH5BAEAAAAALAAAAAAQABAAAANKCLobwRAG4SJw7w5BswoEkQXbRn0h5ggF14FhbIhb68SiOgnbLRsPEovjwwVLRIdhCfwMiR/VZ1A7WS4tntWyynquq+01+h1//AkAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npassword-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/MTCBPz+BISCBPz+xAAAACH5BAEAAAAALAAAAAAQABAAAANECLrcGi6CIAKUKwxSb/ZasXWPMFwBQRQiZwlqAVnEGbRwKz/ndMep3QNUqKV6kpQh6HFoCIaBMDmQTpOsJsaC6XoZ/gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npenguin-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/ISChPz+BMTCBISCBAAAACH5BAEAAAAALAAAAAAQABAAAANHCLrRsTC6F6UId1TYiNtMQRQNqARDOlAgJrzlhr7vqlUufbHMoMO8k+8XY4yGtc9pREIORKRTYVoYDgxUVmBqmGCLJzDYnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npixie-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXPz+/DQyNAQCBKSipPz+xPzerPyqXPyCBERCBISCBMTCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARdEMg5Q6C4BjEGyZIlCEFHfJQonEERnB8sE6RxIMkAnGtPBzacjqBQLBiMxS+Y2xmRx+WtSTgmkwQLcwhNKqRCz3VRBOeGvh5wqpPMzO3JQFBguWAYxeiNwnRAEn4RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplan-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxPz+/Pz+xMTCBISChASCBMRaBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEIRJKwU4iD23FwEmDeAwBGYaZiehWutEFK6JqtlM7KZhHhOJbuizIUKBHVGFOOaUPgPlGEsSDNjbKWBgcT0oX5CV2qakIg24OTGA0sxjeSWpUC2ivESf90cAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nproxy-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/KSipFxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANGCAHcziuIuFy44045WxhZpkxCB4GEKA1lpIAiVG7XB1bjPMHxqds3y++S6nGOL1ikpYlkbBSZM/oYfXBVaS8LuXCr2IY/AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npybliographic-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBMTG5OTi7Nze/NTS5LSuxOTm/MTCxGxaFIRmFJR6JLy+zOzq9IRqJJR2HLSaNKSirNTOxKySLIR6VLS2vOzu/LSqhNzOXHxqNMzK1KSGJHxmFKSabLy2pIx2JJyCJIRyNNS+VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZhQIBwSCwaj8WAEplULpkAZ0AQgEaVA4K0alQWDAdEQrHgNguMRsHxgJiJgcEg0pA4Jk84ZVCoWC4TGG9CAQkZGnUIG3lDAQocCh0eFB+MjRsgIAsLIYNwASKCnk2WVkR+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrealplayer-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIYAAAwWVBwC7BwC9BQC3BQOvBQCtBQCrBQCvBQO1AwKPAwOVBwC/AwGnAwCXAQGNAQCJAQCHAQGLAQGTAwKjBwG7AQCNAQKRAQGDAQCBAQGJAQGPAQGFAQKVAQGBGRiZBweHFxaXDw+PExKRBQSFERGPFxeXCQqJLy+vAwCjJSanFRSVLzCxJSSjIyGhGxubNTW1KyurAQGHAwODKyqrHR2dBwO7AwSZCwqRDQyLCwuLAQKFAwSjAQCLAQCFAQCDAwSbAwGbBQKvBQCzBQC1AQSNBQKtAwOdBQKnBQCxAQabCwOLDQSNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAQABAAAAe/gAABAgGFAwQFBgcIgwEJCguRDA0ODxCXERITFBUWCwMNDxcYpKUYGRobFQEcFx0dGLCxrx6kFQcYHyAhIiIhIyQlJiekESgYHikqKywtLi0vIDCkMQQbLiQyMzQgLDQzJSCkMjU2NzIYOCYyOSYmH+gYOjUBOzw9PT6mGD4P/AORahj4IaECBFI9gAQhJSSSw0g2fGggsEAIw4eRhhBhEGBBgCKkjAgZSRLFESFIRibZx5KlkpYtlbyEuW+Jn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nremote-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBDQyNISChJyGPGReLAQCBMy+hERCHKSipAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARFEEgZqp0Y1KxD9twEapg1kqhwBgKFvqIIjgMRdy4wFIaNbiiCYXDIAUcH328EQsxiIBXAqWn9MtTSTZLNybizEweY8UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsamba-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIUAAAQCBDQyNFRWVASC/Pz+/PTW1OyytNTW9LSy7PTGxOSenNx2dMTG9Jye5OSKjNxiZMw6PIyK5GRi3AwODMwmJLQCBCQmzPS+DPTejPTaJLR+DPT21OzqtNT21MTCxPTyxOTmnNzedMTyxPz6/ISChOTijNzaZMzOPIzijMzKJLS2BPT29Nza3PTmxKSipOzu7LyGJPTKRNSeDFxaXERCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAMALAAAAAAQABAAAAacQIBwCAgIBsjkAEAoGJgHxFC5TCgWAEajyFUCHA8IICJhTggAr4NSGVsAF8wlnSQWBYLMRUNHMjccTB0AGh5dfh8gIQAiAAJCIyRCfiUmJwEokARok0slKSqPApukAZNDRpqbkZMjSROOI5srLAGwS34tGgEuBCMvAjCBA64ALRgxuyzAMnItQmgaMRcypjMByNR9QjQ0adzeaX5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nscsi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/MTCxKSipISChAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANCCLoQwZAFIV6UYgxi79Qa52WDE3bKV6YOpFpO3L5pJcckLBB8/wQEDezWAQpZqIWxFNAUkqkg6HmJOqGuArUqwfoTACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nstyle-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBOzqBLS2BPz+HPz+rPz+BPz+lPz+zPz+9Pz+1Pz+nPz+hNyuhPz+pIQCBMTCBIQyBPz+/MTCxFwmfCQiJIxOrHw6nJRWtJxmvJxuvJxyvAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVvICACwWieYiCUwVCiKVEEhjHA6YEcxooHBURCsXihaAYGglEzngKBhsMmMDhH0YcBAu16SY2IKiApm81RMXTCblPelDCrXJlI6hSL5SJOSewVdRMUGHtGZICChHsmZHeAgxkaG41/bWxnjV6bUH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nterminal-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTCxISChPz+/MT+/AAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM/CBDcHkoFQasVUIrBe8fRNDwMAWpjUThmtmxk0IYwOaPx/V6XG3hAjmsRa0Qkg6NSOVo6F0nG88g4TUNDpT8BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwabi-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/ISChPz+xAQC/AQCxPz+BFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARUEMhJgw20XsHxvIEwcKQHBESaDkShmqhKsMb7tW1RHPwOH4ZdYcBDGH+8A2JgLH2MzZHAJgmRBAgZAabNqg7cJMGb5BKSZF4Yfb5Uzmp3piqfS/wRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwindow_list-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCRiXCRaVPz+/CRmZFRWVISGhMTCxESSjPT29DR6dDyOhDyCfPTy9CxqZOzu7Ozq7ERubOTm5ARehAxefPz6/ByaxBSOvBSGrAxynAxqlBR6nBRylAxmhARWdFxaXCH5BAEAAAAALAAAAAAQABAAAAWHICCKQTCeqCgMhJCihXEYSPuKRWIoC6PYsEZikHA4FA4CEJdoJh4QgXRwiOAeQudDIpEZIpPwhCImhyGGAmBSOVgumExG055w1ZPZhpPpUDwzExBqAAUDhxUVTQ0QEgWOOIcDiU1QjoSFFYiKDZYFmAWJlE9bkCM5iouWpiIfBa6frrKYAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwinprops-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPz+/ASChATCxISChFxaXKSipPz+xMTCxMTCBPwCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAoALAAAAAAQABAAAARXEMhJqwxAjM23wBMhjGQJEFKhriwrGUcsE3JsvPWBFAAiT7BaIYAA/HAxWk9CO9wAwd0SkJA9g8NiomnDoYqnHDAGroqRyVy3F2i7326LnKKo2+94hT8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwp-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBAQCxAQChKSipPz+xPz+/ARCRFxaXEQCBMTCxPyqXDQyNPzerISChISCBASCBERCBMTC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAV1ICCOZDkGgSgMg0AUZWAExyHc7YCQclLYtxtieAoUEApFUIBgnRYMhUHRCDYcDoUIRUhOlYLkYwcIDLvSpAsBiYx0CPQUgXNv4V0ZWEByDBgRcTMGDislTX+CMgISJk1+AQ4zWiYiCCiRDmRbmJ2eKZWhAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nxapp-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBISChAQCBAAAACH5BAEAAAAALAAAAAAQABAAAAIyhI9pIa0nYAtPUGlTRszJ10UA8xiNRZZmJKoA25boqW7npeHvlKRHyIn9aKYaz6XwFwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nxcalc-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBISChPz+/AQCBCH5BAEAAAAALAAAAAAQABAAAAI4hI9pwe0Ogpi00hHF2LzzzFlTsIHD45SSx6oCeW4wjK2tl83y7t64pIsJaxrfh2bEAJIlhRPhLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nxclipboard-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/MTCxPz+xPzerMRaBISChCH5BAEAAAAALAAAAAAQABAAAANICLoQwdBJIaRjgYbBR66Lo1nfowTER61aWGRd1y5GyrLm+QrxMJ81FQ4T2MV+jUPwBgpVdrdcQ6AUIj8Ha/N06Hq/UpLY5E8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nxclock-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAALy+vAQCBPwCBMQCBIQCBISChPz+/MTCxCH5BAAAAAAALAAAAAAQABAAAANbCLHcrSLKOZcYmDSCsR1aUABAsXDDJwJGa5SBFwgaWxbCG3CWaBwG3C8Y67FawpYiNQscg65fsVkYuoAmJs1pBR522lQB6ILJLqHRwQQOZzYdZnw+dzruDIA/AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nxconsole-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/ISChMTCxAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLrcGjBKCYK4OGcohv/gxw2aRgyjYJXCmVpr5loke82dfaO03vI5Ha5mwxGOyOSRF2qKKpMoxEFl+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nxedit-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBMRaBPyCBMQCBMTCxPz+BPz+/KSipFxaXPzerPyqXIQCBARCRDQyNISChCH5BAEAAAAALAAAAAAQABAAAARnEMg5gw00yyDGIJi2FUHhDWEWeEXrgaphHEOBJF8KBLKyLINEIAHbyA6/hbDACDSMBt9PIBA6n4HfIElFXTeKg2LbtTSeu7BiPegIvuA1mwrfOB5r4PusCjimZmgUF4F8IhJnhiJ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nxemacs-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBDQyNKSipPz+/FxaXISChMTCxCH5BAEAAAAALAAAAAAQABAAAANJCBASoXCFoVi8VdL6HHQeB4YjSAxnYQygSLzoSTjbEs9vMF86cbyH34NX+AELQ4zO+Nopm6cBC1PBEQwG6gd3SGo7Xa1STIb4EwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nxeyes-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAQABAAAAI4hI+py50Bw4lyBiEggFjvi2VcqIFhdnaDSabZKrbjS3W1OHz2CkJD/vHlKD/Er2g4Ah3MptPgLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nxfig-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+BMTCBISCBARCBATCBASCBCH5BAEAAAAALAAAAAAQABAAAANQCLocwbAJ8SIMYgwHHO9Opk2V5xGEplZK0alaui0eDLOB8QTykOKGQ6mnKQWFPILDN8sdng7l69c5CjuKAHNnZb2KnUOhcG3MsmMv7aK2+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nxfmail-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPyqXMRaBPz+/AAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANACLHcAVCJSWcYLwaxSPAXBj2bswyiIlUWSr5muGhbdaZjTd1ZzvKMFaOFcbCIpiOnGGs2FM5gLkLrTalQLMCfAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nxload-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+py+3hEoxnUmBpyBjNzWXfJnkGKJ4dBlbjS7Jni9Zsjec66hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nxmag-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipMTCxPz+/IQCBPyCBMRaBCH5BAEAAAAALAAAAAAQABAAAANICKrR+6+JIRxkc4RBww1TQBBNB21io2rRRKpltaDvis4hvJmzBmuslo+zkZ0yu0rBcwJ1AgXD8gJQMaJTaqRwyGqvzO9M4U8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nxosview-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIMAAPwC/AQCBPz+/MTCxAQChPyCBAT+BPz+BAT+/PwCBAQC/AAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARFEIRJa5Ui663HFEQojqEXCAVhrCxLmGB4kCJM03aIHEdC5rfaJ6UotlavT3AEIxaNLuAyd2wlT0thYMDter0BiWU8AfgjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nxpaint-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBPzerMQCBPz+/AQCxPz+BMTCBASCBPyCBPzC/PyqXMQCxIQChKSipMRaBDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVtICCOYmCaZGoKLBuMbykMA1EURFwCgWAQwKBAxxMQDocgAjEkrYAsoS6QGEYJCgWhWVq4tgJGY+iAVbcBB5jLq/aMbzJsYXK0Arky7JFY+BcJDyckDgEPh4d1aUSFJ2l6ARApDpSUKkQpmSJ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nxv-16:apps apps16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPyqXPz+xPyCBPwCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM8CLrc/jC+oIK9Lgg7RuietWhCSWkkVZUbEBBnWxXFSVP1eLt7kPM3X86nEhJrtx/P0tuNilCVZEqtNvwJACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\n3floppy_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBMTCxARmZPz+/FSWlLSytKSipERCRIyOjISChOTm5HRydNza3GRiZFRSVASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVrICCOQBCQKBkIw5mqLFG47zoQ+FwbN57TosDhgPD5dMEEIqE04kwlBWKBUEiNVYFpyqAyGEUCgqEtERiNNMLhQKzLQYJg7n7Y4aMAwbCUPvAQeWNgfzQQETAIhSMQEogwgBITQEGGEREmfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\n3floppy_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxARmZPz+/FSWlLSytKSipERCRIyOjISChOTm5HRydNza3GRiZFRSVCH5BAEAAAAALAAAAAAQABAAAARcEMgJQqCYBjFu1hxReN82EOhYGieaklJwHIjrqnGCJLqNWhUFYoFQCG1FgWXIIDIYNQKCoawQGI0swuFAbKsxgmDsfZjBkwDBsNM90Jot9A3DbBD0Dwiur9QnfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\n5floppy_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBFxaXPz+/DQyNISChASCBARCBMT+xAT+BAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARMEMgJQqCYBiFu1sIwdJ+0hSKZnZw4ehPLoW88c0Q7X7JABLlbp+eT/UyzgpADqwgKxKYpeIMZQNWJ4YBhWRHcrgpgQCSkJu3hYPFHAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n5floppy_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBFxaXPz+/DQyNISChAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM+CLoQwZAFIV6UYox61cwaF32UtlkLSYFnulJEuT6qQATxW9W2enurgo6CaggKvKIn91K6mh0gMepydqwAfwIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncdaudio_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tOzOvNTqvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/LzKvMTCxDQyNASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAa0QIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTBqUiuUCVmAeiYzmsKlwOt/AAKFIFAIIFx4WHyAhUwIDIgsZFyMkFxchJSYmiBkSBBoIJJwIGgOhiCYFJSEnFyQjFwNZewABISAfFiYnCAEmCREIrwAIFhwVGwcaBAkPGApsQsAVFA0GBQMRbxBTKM0ODQwTEq192ClDgROkBHvYKuNJUu5CKCorX1RDKCkpUn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncdaudio_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tNzmvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/MTCxLy6vDQyNOTm5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAapQIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTLqUigWsuDwSmMxBQ9lwvoEBQpEoBBAWHRseHyBTAgMhCxgWIiMWFiASJCSHEgQSGQgjmwglGKCHBQUSICYWIyIWAwshIVMBIB8eFSQmCAEFCREIekIIFRsUGgcZEgkPFydrvxUUDg0GBSEREGJfv9AMEySsJxDYQ4DcEhh64UpS6lTs7QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncdrom_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tOzOvNTqvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/LzKvMTCxDQyNASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAa0QIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTBqUiuUCVmAeiYzmsKlwOt/AAKFIFAIIFx4WHyAhUwIDIgsZFyMkFxchJSYmiBkSBBoIJJwIGgOhiCYFJSEnFyQjFwNZewABISAfFiYnCAEmCREIrwAIFhwVGwcaBAkPGApsQsAVFA0GBQMRbxBTKM0ODQwTEq192ClDgROkBHvYKuNJUu5CKCorX1RDKCkpUn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncdrom_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tNzmvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/MTCxLy6vDQyNOTm5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAapQIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTLqUigWsuDwSmMxBQ9lwvoEBQpEoBBAWHRseHyBTAgMhCxgWIiMWFiASJCSHEgQSGQgjmwglGKCHBQUSICYWIyIWAwshIVMBIB8eFSQmCAEFCREIekIIFRsUGgcZEgkPFydrvxUUDg0GBSEREGJfv9AMEySsJxDYQ4DcEhh64UpS6lTs7QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncdwriter_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBFxaXISChERCBMTCxKSipAQCBMTCBPzCxPz+xPzerMT+xDQyNMTC/ASCBPyqXPz+BARCBAT+BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAWIICCKgWAGYyoKA+EWhGGogOAaB6Lr8ygUCYWCkEMoEovBSHZUFI8LGYloODJkhWijMbMdiAwBQEbYxmpExFlkgN3QrliXAcvNAuVt4coYKtQ9BlwLCQQFMAlVSmwEUX8IB1UJiQAObEE6BA9VEDMOEUsDDzoHkZ4LoCkyqyIOCxI9NCOfETJ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncdwriter_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXISChERCBMTCxKSipAQCBMTCBPzCxPz+xPzerMT+xDQyNMTC/PyqXPz+BCH5BAEAAAAALAAAAAAQABAAAAR3EEgZhA0zSzGIL4RhaIDgGQeiquMkFImiECmiJMswibdS3wsRhWa4MUSFYKMxMh1oDAFARFiGSjTEVWIAnbCeUJMBSo0C1WXhyJgptC0Dc5EgFECJoo5LCL4RB0UJeRkGMSoEDkUPLYUDDioHgY0kIpYkmJkAfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndvd_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tOzOvNTqvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/LzKvMTCxDQyNASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAa0QIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTBqUiuUCVmAeiYzmsKlwOt/AAKFIFAIIFx4WHyAhUwIDIgsZFyMkFxchJSYmiBkSBBoIJJwIGgOhiCYFJSEnFyQjFwNZewABISAfFiYnCAEmCREIrwAIFhwVGwcaBAkPGApsQsAVFA0GBQMRbxBTKM0ODQwTEq192ClDgROkBHvYKuNJUu5CKCorX1RDKCkpUn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndvd_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tNzmvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/MTCxLy6vDQyNOTm5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAapQIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTLqUigWsuDwSmMxBQ9lwvoEBQpEoBBAWHRseHyBTAgMhCxgWIiMWFiASJCSHEgQSGQgjmwglGKCHBQUSICYWIyIWAwshIVMBIB8eFSQmCAEFCREIekIIFRsUGgcZEgkPFydrvxUUDg0GBSEREGJfv9AMEySsJxDYQ4DcEhh64UpS6lTs7QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nhdd_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBDQyNIRuVKyCXMSKROzSrOzKpOTGnLSafLySZKxuLMSOVPTWvPzixLSehNyibOzOrGxaVJx+XOzGnFw2FJRuPKx+TPTSrHRWPKyKZPTOpHxOJKyKXFw+HKSipISChMTCxFxaXIRiPNSWXExOTOS2hLR+PLRyLPTWtMyOTASCBARCBPz+/DTSJIyKjIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwCAgYA8SkMCAYDARI5ZJQMBwQiWgyoFgwrA3HQ7scQAqFAcEQOUi0zAkFUSFYLghMBloUCDQNGxwdHhwHekcfICEhICIfIxkLJBABJUYCICABIhAOBiYnKJaXmH4CGSkYCCqkSAEfTKenrkOwsrQll0IrS7G5uwArLLaxLbXCLsTFLyDBKy4wZEVHvCwsRn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nhdd_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBDQyNIRuVKyCXMSKRPTWtOzKpOTGnLSafLySZKxuLMSOVOzOrPzm1LSehNyibGxaVJx+XOzGnFw2FJRuPKx+TPTSrHRWPKyKZPTWvHxOJKyKXFw+HPTOpKSipISChMTCxFxaXIRiPHxaNLRyLNSWXExOTPzixOS2hLR+PMyOTPz+/IyKjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaIQIBwCAgYA8SkMCAYDARI5ZJQMBwQiWgyoFgwGgiD46FdDiCFwoDQAEe0TMkEQSFULIcLBloUCDIaDRscHRsNHhhHHyAhISAiHyMkJSYQASdGAiAgASIQKA0pKguXmJl+AiQGFwgrpUgBH0yoqK9DsbO1J5hbsrq8SrgstlJFHy0gwMVFR1J+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmemory-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBISChAQCBMTCxCH5BAEAAAAALAAAAAAQABAAAAI6hA+Bu+HCmgiiRuNoHZBRXQlc84TmcHzm2WVryE1YvMaZIdbVd2zw7lj4bDKGbxK8hHgX3K2JUDD8BQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmo_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBKSipDQyNPz+/MTC/PzC/ISChASCBARCBMT+xAT+BAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEMgJQqCYBjFu1hxBeN82iCIJDgWaYhtntC4ZCzItdhWOD7mdwHLrAAczoKViIh6Vto5lcDjglppp9UpCTALULRaASGS5E4TCnB2rFyqJO5Gw+CMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmo_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipDQyNPz+/MTC/PzC/ISChCH5BAEAAAAALAAAAAAQABAAAANHCLoQwZAFMV6UlBB759Aahw0FGEITZZQmlwoqq1UNDA/xLDhvhQ8rnKPh4f2EropjcDjAhpJl8ylaBJhTaCelvRC7XqLXnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnfs_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBExKTGRmZPz+/ExOTMTCxAQCBDw6PCwqLIyCRHxyNCQiJOzmxMSybFxSHHRmLIx+NFROHERCRFxaXASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVWICCOZGmeaEoGKiCwwUAI5zsUBnAUQ0CLNhxLFEDwDAnFzTAsBRYJRsORSwUeDUiEWYtJIhFj7+eKCUdPHmxyNj0nFABXRam0RBSLvZW/VFN1FQYGfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnfs_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBExKTGRmZPz+/ExOTMTCxAQCBDw6PCwqLIyCRHxyNCQiJOzmxMSybFxSHHRmLIx+NFROHERCRFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVLICCOZGmeaEoGKiCwwUAI5zsUBnAUQ0CLNhxLFEDwDAnFzTAsBRYJRsORSwUeDUiEWYtJIhFj7+eKCUdPHmxyNj0nOa6q2qrbW/4QACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nprinter1-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBFRWVPz+/Ly+vISChMTCxFxaXPT29DQyNJSSlHR2dERCRFRSVERGRBSmnExOTExKTAT+/NTW1MzOzMzKzMTGxLy6vLS2tGRiZFxeXOTm5IyKjISGhLSytKyqrGRmZNTS1Nze3Nza3Hx6fKSmpKSipAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaUQIBwSCwaA0ikkRgQDJCE5LFgOAicUKUwUCAgBuDE9RkFcL3ggbgQUCwYyIIA8VU32ASDwoEcIAoHCQkHbA8EBBARSX0DXQEPEgQCDYpJExQVAWCHBwcNDUkKChQWBBcYARkanaABExsbHB0FGB4fIKoHAWYhpCIBIyQLJSAJGbtbULUTISa4yEVJJSbO0EtmUkR+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nprinter2-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBKSipAQCBPz+xPz+/MTCBISCBISChMTCxFxaXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMggqrwYVDGGzRLXEZ0HhgMpFIXxZZzRBsHxXquAUHqCCBgB6YcoFhNAXMWISCQOv6Dt6DMmQwQntHjwXTVL6mH83Ry31qBO8CSQSmVg2GM74aAVij2UTPojACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nscanner-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MT+/ASChARCRATCxMTCxFxaXKSipDQyNAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEMgJgqWBVivEldkUdKSXhVjZfenommglDERh3Tc4E4ZRHAGgkEPr9X6H5AHBERSMRyWzkug8jQXFEhWoOo8dRYxqLXSmGjIJnVaz29Q3fAP3RwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntablet-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBMTC/Pz+/MTCxFxaXKSipAAAACH5BAEAAAAALAAAAAAQABAAAANECLrc/iosCUEQlEYdRp6dZ4lgKBBEp1kmmpLRMBQu6qWLEdYBn+81F0wnC8oCK+LAQDgGDIaG0vOMPnRIaEUBtW6//gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nzip_mount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BAQCBFxaXMTCxPz+/ASChPwCBKSipASCBARCBMT+xAT+BAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEMgJQqCYBiFs1lwwdF8VEsR4YVuXoirYFcWbkmY31wPqma2ZwReqBEODQutwEY04oeWqMniGOEzW4HAVZAEImVSCSLDGYIX5/EMoFtNSOWHxRwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nzip_unmount-16:devices devices16 16:photo:16 16:R0lGODlhEAAQAIIAAPz+BAQCBFxaXMTCxPz+/ASChPwCBKSipCH5BAEAAAAALAAAAAAQABAAAANICLoQwZAFIVyUNIx6WybE9kBTFYIiVhXFGXJetbYDaHnlathZk2eDQunw0GwomeGoMThmKETS4PAURCMlZccHXXYct60Y4E8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nblockdevice-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMT+xAT+BASCBMT+/ATCBAT+/ARCRPz+xARCBPz+BATCxISCBDQyNMTCBCH5BAEAAAAALAAAAAAQABAAAARhEMgZwrwYBCFsvhs3eF8wDMJAVBVmnupazKRmGDFxzMVBBjcDQXfYHRA/QmKpKBYRSMoysVgwGEeoJ1ClLhpXhlbiqJobjcA1Sn48qug06+JwP+I1UMCNzmcqaR8lghN+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nchardevice-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBMTCxISChPz+/MQCBPwCBAAAACH5BAEAAAAALAAAAAAQABAAAANCCBDcHkoFQasVUIrBe8fRNDwMAWojMTZmtmzByp6v7LQhTOLadbkxj3AUWZAcxcUgyYwQm8wYoOCCLgoGK5Nq9ScAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndesktop-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBExKTDQyNHRydFRWVKyqpGxubExOTERCRLy6vFxaXBweHFRKPFxeXAQCBIyKjCwqLMS+tKyurDw+PNze3ERGPPTu5Pz+/Pz6/Nza3MzOzKSipISChOzq7NTW1Ly+vHx2ZOzm3Ix2XJx2XIyOjKyqrJSSlPTexPTixKR2VKxyPCQiJPTy9JSWlHRmTOzSrMzKzJyCbKR+XCwuLOTi5CQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQIBwKAwIiEjkgJBsAgoGwcE5RCQUgAWj0WwcHA8FRLhAcIcKhyIiMSwcwglc2ABTDA2Eo9KQoy0PFxgYGRobDxwBDHRgF44YHQ4bHgkfHBUMHQ8gFp2dISIjEQwfBwIkJR0mICcoJycpKgweCisAEAcPGSwtLi8vsQkNtkMrBxswCQ8uMTINY0kzBCQwNB/DVAArBC0NNdlDM9BDfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfile_broken-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXDQyNAQCBMTCxPz+/KSipPz+xPzerAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEEgQahVijMmD/oRAbBw1FCgaFFrppeo5didsZTSMDoRBSi/dgfUz6Va7HPIQGB6KnpW0EEB4Oshp5ZlTFRBfFs3ZLDihtTAYwZ14nGbzoS3JfO4ffwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfile_important-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBExGTKQqLPz+/KQqNAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLoQwZAFIV6Es15Jqd2ZtzXUMIhXZqJYaZ5aK7zwp6h0zc05i+c6Eg8oCnWOR0eHQGEKnEWHdDoF+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfile_locked-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXDQyNAQCBMTCxPz+/KSipPz+xISCBERCBAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEEgQahVijMmD/oRAbBw1FCgaFFrppeo5didsZTSMDoRBSi/dgfUz6Sq7XGp1CByKQZUUWjsgrtcENYXNUodWhAahVRa65G9hmGgnnpzMZ/7xRwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_blue-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLARqnAQ+ZHR2dKyqrNTOzHx2fCQiJMTi9NTu9HzC3AxmnAQ+XPTm7Dy67DymzITC3IzG5AxypHRydKymrMzOzOzu7BweHByy9AyGtFyy1IzG3NTu/ARupFRSVByazBR6rAyGvFyuzJTK3MTm9BR+tAxWhHS61MTi7Pz+/IymvCxulBRelAx2rHS63Pz6/PTy9PTu9Nza3ISitBRupFSixNTS1CxqnDQyNMzGzOTi5MTCxMTGxGxubGxqbLy2vLSutGRiZLy6vLSytKyurDQuNFxaXKSipDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYHCImDBgkKCwwNBQIBBw4Bhw8QERITFJYEFQUFnoIPFhcYoRkaFBscHR4Ggh8gIRciEiMQJBkltCa6JyUoKSkXKhIrLCQYuQAPLS4TEyUhKb0qLzDVAjEFMjMuNBMoNcw21QY3ODkFOjs82RM1PfDzFRU3fOggcM7Fj2pAgggRokOHDx9DhhAZUqQaISBGhjwMEvEIkiIHEgUAkgSJkiNLmFSMJChAEydPGBSBwvJQgAc0/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_blue_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOzi1Ozq7ERCRCwqLPz+/PT29Ozu7OTm5FRSVHRydIR+fISCfMTCvAQ6XARqnJSKfIx6XPz6/MzKxJTa9Mzq9JzO5PTy7OzizJSOhIyCdOTi5Dy65FTC7HS2zMzm7OTSvNTCnIRyVNza3Dw+PASq5BSGrFyqzMyyjMzOzAR+zBRejBxqnBx+rHRmTPTy9IyqvDRylFxaXNze3DRujAQ2VLSyrDQ2NNTW1NTS1AQ6VJyenGxqbMTGxLy6vGRiZKyurKyqrKSmpDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfCgACCAAECg4eIAAMEBQYCB4mHAQgJCgsLDAEGDQGIkw4PBQkJBYwQnRESEREIoRMUE6IVChYGERcYGaoRGhsbHBQdHgu2HyAhGSK6qxsjJCUmJwARKCkpKsjKqislLNIRLS4vLykw2MkRMRAGhDIJMzTiLzDXETUQ0gAGCgU2HjM35N3AkYMdAB0EbCjcwcPCDBguevjIR0jHDwgWLACBECRIBB8GJekQMiRIjhxEIlBMFOBADR9FIhiJ5OnAEQB+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_cyan-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHNTKzOzq7ExGTCwqLERCRBSKjBRSVGxubKymrNTS1Hx2fCQiJMzq7NTy7IzKxHR2dFTW1Ey2rITKzNzy9JTSzBySlHRydKSipDTW1ByelGzCvIzOzByOjFRSVCy2rCSalGS+tJzSzBxudCR6hCSCjITGxMTm5Pz+/JSutDyChBxydCyOlITKxPz6/PTy9Nza3ISqrGSyrOzm7MzKzDQyNMzGzNze3OTi5MTCxNTO1Ly6vLSutGRiZKyurHRudDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe2gACCAAECg4eIAAMEBQYGB4mDCAkKCwwNjYUOAYcPEBESlBMMjAUFnIIPFBUWEBcYGQoaG5gGggMcHRUeFh+fGCCVIakiICMduiQWJa4fCKkdJicoCcjJKSrPAAIrBSwtLtMv1jDaCDEyMgUzNC3SKCA12gYFMjY2KzMzN98uLdo4cujYoa9BAx4IeSywJSgAjgU8evTIgdDHj4WJHAL54cPiDyAMIzkMsSGIkCGREAU4gAOAn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_cyan_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFNze3Ozq7ERCRCwqLPz+/PT29Ozu7OTm5FRSVHRydIR+fIyCdMzGxAxOTBSGhIx6XJSKfMzKzERGRAxOVKTq5Mzy7KTW1Ozi1OzizEzSxGTWzHzCvNTq5OTSvNTCnIRyVNTS1BzKvCSalGy6tAQ6XMyyjMzOzDw+PByqtCR6fCyGjHRmTMS+vJSytDyChCyWlGReVOTi5AxGRKyurDQ2NNza3NTW1AxKTJyenGxqbMTCxMTGxLy6vLS2tLSurKyqrCwuLFxaXKSmpDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfEgACCAAECg4eIAAMEBQYCB4mHAQgJCgsLDAEGDQGIkw4PBQkJBZcQnRESEREIDwoPExSipBUWFxgZGhIXFwkbHBQToQQGFx0eHxoguhEXHCEiIyQGABclJiYnycsSKCkjKisAESwtLi7Y2soXLzDUAaMxMuYuM9kXNDDiAAYFBTU15NGTYeMGNQA4ahAgkEMHiQoxZrTYwWMfIRw9fKio8MMHECAReByUhIPGDSBBhAyJYDFRACJFeBi5cCSSpwM4APgJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLARqnAQ+ZHR2dKyqrNTOzHx2fCQiJMTi9NTu9HzC3AxmnAQ+XPTm7Dy67DymzITC3IzG5AxypHRydKymrMzOzOzu7BweHByy9AyGtFyy1IzG3NTu/ARupFRSVByazBR6rAyGvFyuzJTK3MTm9BR+tAxWhHS61MTi7Pz+/IymvCxulBRelAx2rHS63Pz6/PTy9PTu9Nza3ISitBRupFSixNTS1CxqnDQyNMzGzOTi5MTCxMTGxGxubGxqbLy2vLSutGRiZLy6vLSytKyurDQuNFxaXKSipDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYHCImDBgkKCwwNBQIBBw4Bhw8QERITFJYEFQUFnoIPFhcYoRkaFBscHR4Ggh8gIRciEiMQJBkltCa6JyUoKSkXKhIrLCQYuQAPLS4TEyUhKb0qLzDVAjEFMjMuNBMoNcw21QY3ODkFOjs82RM1PfDzFRU3fOggcM7Fj2pAgggRokOHDx9DhhAZUqQaISBGhjwMEvEIkiIHEgUAkgSJkiNLmFSMJChAEydPGBSBwvJQgAc0/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_green-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHNTK1Ozq7ExGTCwqLERCRByGRBROLGxubKymrNTS1Hx2fCQiJMzm1NTy3ITGnKSipFzShFSydIzKnMzq1Nzy5JzSrByKTBweHDzOdCSaTGy+jJTOrFRSVDSuZCySVMzq3IzKpBxuRCR+TCSCVGy6hPz+/JSunDyCXCSOTCyWVCyeVPz6/PTy9IyqlCSCTGSuhPTu9Ozm7Nza3Dx+VBxyRDQyNMzGzNze3OTi5MTGxMTCxLy6vLSutGRiZLSytDQuNKyqrHRudDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe+gACCAAECg4eIAAMEBQYGB4mDCAkKCwwNjYUOAYcPEBESlA4TjAUFnIIPFBUWFxgZGpWXjYIbHB0VHhKtER+UCyC1ISIdxbkSGSMYJAiCByIlJicaxbgoEhDNAAYpBSorJScnLC0uHRLaCC8wMAUNMeAnMgkz2gY0NDUFKTYNBDE3cKzQlkPHDh42djRo0KNhjwUGBgXIscAHgQY6fPz4AQRioolBhGwUIiRIxEiEhoCYQKSIEZSHAhzIAcBPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_green_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFNze3Ozq7ERCRCwqLPz+/PTy9PT29FRSVHRydIR+fISCfOzu7OTm5OTi5MzGxAxOLByCRJSKfIRyVERGRKTmvNTu3KTWvOzi1OzizIx6XIyCdFTOfGzSjITClAxGJOTSvNTCnNTW1Dw+PAxKJCTCVCyWVGy2jAQ6XMyyjMzKzByuZCR+TCyGVNTm3HRmTLy6vJSypESCXGReVLSurDQ2NNTS1MzOzKSipGRiZMTGxMTCxJyanDQyNLSytKyqrCwuLDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfCgACCAAECg4eIAAMEBQYCB4mHAQgJCowLAQYMAYiTDQ4FCgoPEBESnBMUExMIoBUWFaEKBRIXExgZGqoTChscFR0epQYTHyAhGrkUIhMcIyQWJSYAJygpKSrIyissFi0GABMuLzAv19kaMRMyM+ABojQ15ObYEzYz0wAGBQUbBPHkYNQQcQMcABwEEhLIkUMHjRQvTuzIRwgHjx45evTwMWPGiR8GJQGxcWNGkBtCTlBMFGDIgh9CJhCJ1OkADgB+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_grey-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLHx2fKyqrNTS1PTy9CQiJNza3OTi5GxubJSSlISChLSytFxWXDQuNKSipBweHISGhFxaXIR+hLSutFROVHR2dFRSVGReZKymrLy6vFxeXNTW1Pz+/KSepERGRPz6/PTu9Ozm7DQyNMzGzMTCxMTGxGxqbNTO1Ly2vHRydKyurHRudDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAawQIAQEBAMj0jAgFAwHBDJoUGASCgWDEMxETg2HA8FFaJgFgpdYSMiUYAnlErCsmgKL5iMJqJwPzYcCB0eahAZH4gSESAhYAoGQggiBh4eFB8iehEWI5AABiQFFpMeHCIiiCWeJicMDAUOEZMcHBkSngYMKCkpJA4OBCWTk0IqKw8PvwsLLCwtLBCeRCouLC8vK80wGzEHSQEqHxMhMBMyLtLfKh4WCjM0UUgBCCoAfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_grey_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExOTBQWFNze3Ozq7ERGRCwqLPz+/PTy9Ozu7OTi5HRydIR+fISCfPT29Pz6/PTy7MTCxCwuLJSKfIx6XMzKzDQyNOzizJSOhIyCdOTm5Dw+PJSSlKSipLy+vOzi1OTSvNTCnIRyVNTW1GRiZFxaXAQ6XMyyjNTS1GRmZFxeXHRmTFRWVKSmpKyurMzOzGxqbMTGxLS2tJyenKyqrDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAauQIAQEBAMj0jAgFAwCA7JYwCRUCwWgoCBEUBOG47CAxJhSrqT5wERplQoC8ijYDEcJASJ4HKIYDAZFRoFGxwXHR4eH3lqICEiIyQcAAcMJSaIeHonKCMpkxMqAismKyuIixMsH5MBDw8eJS0mJpcdByYSkwAcEQUEBC4lo7UHL7sXwMAkKTAeogceu0QXMRIwFjISMxITNNNDARcmLx8zNTUH4F64NDUTNlHsk35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_home-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBDw6PBQWFCQiJAQCBFxeXMTCxJyanDwyLDQqLFRSVLSytJSSlISChCQmJERGRFRWVGxubKSmpJyenGRmZLy+vOzq7OTi5Ly6vGRiZPTy9Pz6/OTm5ExOTPT29BwaHNza3NS6tKx6XGQqBNy6pIyKjDwGBOzOvJSWlDQyNIRaLNRiBGwmBNyidLxWBHxGFNySXCwqLKyqrNR6LKxGBNTS1NTW1Jw+BEweDDQ2NAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaoQIBwCAgIiEjAgAAoGA6I5DBBUBgWjIZDqnwYGgVIoTGQQgyRiGRCgZCR1nTFcsFkHm9hBp2paDYbHAsZHW9eERkYGh4eGx4ag3gfSgMTIBshIiMkGyAlCCZTEpciJyQjGxcoKUQBEhcbKiQrLB4XEltDrhcaKi0utbcJra8bLzDAGrcxrTIXHi8zNCypEsO6EzU2IzQ3ONoTzK0BCAkDMQkIOTFlAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_html-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBERGRBQWFMzKzOzq7CwqLDw6NARqnAQ+XHR2dKyqrOTm5ExKTERCRHRydMTi7NTu9HS+1KSmpBweHDy67DyixHS61ITG3AxypByu7DxinBw+ZERmdIySjITC3ARypExOTDRurIR2RPTSdJyulEyGvBw+bFSyzJTK3LzKvPzivOTixNTChLSybGyCfCRSnBQqRASGtFyuzDw+PCRShPzy5OzerOTShKyaTEx6pCxerGRufBR+rOTezPTShNy6bER+1BxCfBQuRAxelFSixBw2VISq3GySrPTWlHyanIyitFSO3IymtCRujAxWhCRqlCQ6XGyWvNS2bFyGvDxuvCRSpLy+vMS+vGxqbFyO1GSi3EyO1FRaVCQuPLS2tDxyzKyWNFxaNCQyPGxubCxajERSVExKNJyenAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfZgACCAAECg4eIAAMEBQICBomDBwgJCgsEDA0BDg8BhwYQERKUDxOYDAyeghQVFhehGBmVlwwOqxobHB0eH6EfIAkPIYIiIyQlJhsnKBcpvrYiKissLS4vMDEyFjOvNAA1LDY3ODk6Oyc8PTIyFzQ1Jj42P0A6QTtCQ0REIEUORkdIkihZwsSekBhNnDyBciCKiSNSplDRUcWKkRhXCGDJYgiGli1cpuTocsILjytfFmRpACAGRTBhRogZgzHlAjKGWnIoY+bMgRgBDHRBo/LAIZoxuhwKatRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_image-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPz+BAQCBExKTBQWFMzKzOTm5CwuLERCRARqnAQ+XHR2dKSmpHRydCQiJMTi7NTu9HS+1Dy67DyixITC3BR2pBweHByu7ASGtFSyzHS61AxypExOTBSazBRupJQOFBSCtDxKfKTa9AxelNz61MTaxDw+PPzGpLweHJTO3ESu3DRilFymXCxKRBRypBR+rDwCBNxmVORiRKQWFCyKvJTWhDSOPCRONFSixDQaHNROPNQ2JLRubHTC5DR6rHx6fFSqRCRyLGRmXGxqbIymtCRujAxWhMySjMQ2JMyqrKTW5ERijJSenFSGXGRmZLy+vMTGxMTCvERGRMxCNOzq7NTe5LSurISKhHR2fLy6vLS2tKyurGxubCwqLOSKfOzy9Nza3KSmrIyGjGxmZKyqrIRqZIyKjFxaXJyenDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAffgACCAAECg4eIAAMEBQICBomDBwgJCguMAoUMAYcNDg8QlAyXBaWcgg0REhCfExSVpIYAFRYXEhgZE60aCQwbghUcHRQXtri6DxMHgh4fICEiIyTFtxkOJQAeJicoKSojKywtLsUZJS8wMTIpMyA0NTYKIiIaNwc4OTo7PD0+P0BBhAwhUkTFAQNGjiBJomQJExsMmjh5AkVIFANQpEyhsqSKlStXmmDJomVLFC5Gunj5QiALmDAKxGSpMsYiAC5kqjhZUOaKmUdmzoAJgkaQgQYCmogJEmRQAC5pAPgJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_important-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBExGTKQqLPz+/KQqNAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM7CLoQwZAFIV6Es15Jqd2ZtzXUMIhXZqJYaZ5aK7zwp6h0zc05i+c6Eg8oCnWOR0eHQGEKnEWHdDoF+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_locked-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQSFMzKzOTm5CwuLERCRARqnAQ+XHR2dKSmpOzm5GxqbCQiJMTi7NTu9HS+1HRydOTm1Ozq7Dy67DyixHS61ITC3AxypERGRBweHByu7ASGtFyy1DSOtDRmfExOTBSazBR+rCwqLAxWhAxelByGtDSaxAwODHy+1Dw+PPT29IyqvCxujOzu7NTW1Nza3ExGJJyebKyqfMTCpFRSPOTi5DQqHOTezDw2NMTGxKyqhMTGrGxmXDQ2NMTCxMTGpHx6bHx2bBQWFIyOXDQuDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQICBomDBwgJCgsEDAKFDQGHDg8QEZQSlxMUDJ2CDhUWF6AYGZWXFBqCGxwdFh4XGK8fIAohtiIIIx25EZwBDREHgiQjJSYmGScoKSoRKQ8rggIsDC0uJS4oGygoAyjdAAcsLxQUMDEyMzQ1EzapBy8MDDc36tFwgONFjlQ6dgCEEZBHDx8+ctRIRehHAyAwZASZIGRIEBoUBwUwIGMCiwFEaBQJichIjo9FZLBsacRIAB0A/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_man-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFMzKzOzq5ERCRCwqLARqnAQ+XHR2dKSmpHRydCQiJMTi7NTu9HS+1KyqrMzOzOTi5Ozu5Dy67DyixHS61ITC3ARypOzq7ERGRFRWVJyanByu7ASGtFyy1Hy+1FRSVOzu7BSazBR+rFSyzJTK3Dw+PFxaXPTy7LSyrAxWhAxelLy6vMTGxNTS1Ly6tFyuzMS+vPz69NTW1MTCvIyOjPT29OTm5HRybFSixLy+tLS2tISGhGxubIymtCRujCRqlHx6fNza1GRiZMTCxGxqZLy+vFxeXLSytKyurGxqbISChFxeZDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAffgACCAAECg4eIAAMEBQYCB4mDBggJCguMBgEGDAGHDQ4PEJQKERITFBOdgg0VFhegGBmVlxobABwdHh8WIBchsLIKIiIjCyQZJR+7JhcnoBAoKSoqKywtLi8wMbsyrwYpGhowHTMqNCqkyR8XKBwTNTY3KjgFOTopLS0ZO98wPD0+JhR490MAkCAshHyTsCLCEAlEYEgoIsCIjRlHDNzy0UFBDBtIbBzZ4KJHBB0aAQhIoqCHESQ9dAjooWQJE1uCBBRpkoSDExEcUnRYwOTJIQECNmwQwEFQgANQAPgJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOzi1Ozq7ERCRCwqLPz+/PT29Ozu7OTm5FRSVHRydIR+fISCfMTCvAQ6XARqnJSKfIx6XPz6/MzKxJTa9Mzq9JzO5PTy7OzizJSOhIyCdOTi5Dy65FTC7HS2zMzm7OTSvNTCnIRyVNza3Dw+PASq5BSGrFyqzMyyjMzOzAR+zBRejBxqnBx+rHRmTPTy9IyqvDRylFxaXNze3DRujAQ2VLSyrDQ2NNTW1NTS1AQ6VJyenGxqbMTGxLy6vGRiZKyurKyqrKSmpDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfCgACCAAECg4eIAAMEBQYCB4mHAQgJCgsLDAEGDQGIkw4PBQkJBYwQnRESEREIoRMUE6IVChYGERcYGaoRGhsbHBQdHgu2HyAhGSK6qxsjJCUmJwARKCkpKsjKqislLNIRLS4vLykw2MkRMRAGhDIJMzTiLzDXETUQ0gAGCgU2HjM35N3AkYMdAB0EbCjcwcPCDBguevjIR0jHDwgWLACBECRIBB8GJekQMiRIjhxEIlBMFOBADR9FIhiJ5OnAEQB+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_orange-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHNTO1Ozq7ExGTDQuNERCRJxmDFw6DGxubKymrMzOzOzu7Hx2fCwqLOzaxPTm1NSyfKSipBweHOSmRMSKRNy2jJxuFFw+DKyqrOSeJKxqFMyaXNSyhNSufFRSVMSCJKRyHLRuFMSORNy6nPTezHxaFIxmFJxqDJxyHPz+/LyqjJR2NPz6/NTS1KyehIxqNJRmDLyWXPTu9PTy9Ozm7Nza3MzKzMzK1OTi5MTCxMTGxDQ2NMzGzLy+vLy2vKyurGRiZLSytLy6vFxaXHRudDw6PDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe/gACCAAECg4eIAAMEBQYGB4mDCAkKCwwNDgYBBg8BhxAREhOUDxSMBQWeghUWFxOhGBkaCxuMBqscHRceHyCwCbMhqyIZIx0kJR4gJicSIAiCECMoKSorKyS6yhHQAAYsBS0uKSkZHSsdHc+CCC8vqDAxMtQzJDTdBjU2NwUsODg5Wsxz0e2ADhw7/sEgwKOHwwW3BAXwsYAHARg/eAAJIgRiogAHhhApEoSIkCERI4E0QmHDESSREAWAkASAn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_orange_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOTm5ERCRCwqLPz+/PTy9PTy7OTi5FRSVHRydISCfIR+fPT29Ozu7MTCxFw+BJxqBFQ+BJSOhIRyVMTGxPzSlPzmxOTGnOzizIx6XIyCdOyeLPSuTNSubOTSvNTCnNza3Dw+POSGBLRyDMyeXAQ6XMyyjMzKzMyWBKx6FJx2FHRmTLy+xDw6PLyqjJR2LJRyDFxaXOzq7JRuLEw2BKyurDQyNNze3NTW1NTS1MzOzJyenDQ2NGxqbLy6vJyanGRiZLS2tKyqrCwuLKSmpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfEgACCAAECg4eIAAMEBAUCBomHAQcICQoECwEFDAGIkw0OBA8PEIwRnRITFBIHDRAVFhWipBcFEhgZGhMSEg8bGxUcHQQKth4fIBoburwbISIWIyQAEiUmJicnyrooKRYqBdQrEywt1yfJGxQuLzCEozEyM+XnEjQv4QAFEDUKCjE2JrRoYeMGjmkAchAYoWPEDh49YrBQ5SMfoR9AXvRQcSFCkBcUhFgcFCDHEBxBiOAoQgFhpABGaPg4IiFHJE8GbPoJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_red-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExKTBwWHMzKzOzm7ERCRExGTCwqLIw6FFQiDHx2fKyqrOzu7CQiJOzOxPTe1MySfKymrOzq7Nx2TLxmTNSelJQ+FMzOzNxiNKw+HMR6ZMyWhNSajHRydFRSVLxSLJRKJKRKJKQ+HNSWhNSmnHQ6FIRGHJRCHPz6/LSajIRONPTu9Nza3KyShLR6ZPz+/DQyNOTi5NTS1MTCxGxubGxqbMzGzLy6vLSytGRiZHRudDw6PAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAanQIAQEBAMj0jAgFAwHBDJoSGhWDAIDUHgsAgcHQ9IhLqQMAsTr9BBqUTClktVgmkYhIOMprLhdOBUHh9rICEiIyN8JCVwdwAOIiYnJyiHiRtvjgYpBSorJgknIpYRmikpLAUtLp+hIy+aLKkFMC0tGJ4mK44xBDKqLTMEBDTFNY5EMTY0MzM3NDg4OR7IQwExOjnROTk6B1FC1x8SEjs84EcBCDEAfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_red_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOTi5OTm5CwqLPz+/PTy9Ozu7Nze3Ozq7HRydISCfPT29PTy7MTGxFQiDIw6FJSKfIx6XPz6/MzKzERGRNyypPTWzOzi1OzizIyCdDw+PNRuTNyCZMSSfOzW1OTSvNTCnIRyVNTS1ERCRMxGFJxGJIRKJLyCbAQ6XMyyjLRWFHRmTLy+xLSelIxWPEQeBGReVIxOJIRSPKyurDQyNNTW1JxOLEwiDKSipGRiZMTCxLy6vJyenLS2tCwuLFxaXKSmpDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe+gACCAAECg4eIAAMEBQICBomHAQcICQoLAoUMAYiTDQ0LDg4PCgQQnBESEREHoBMUEwUVDgsWFxEYGRiqEQ8aG68cBQQdER4fIBghu6saIiMkJSYAEScoKSrJyxIrLNEd1C0p1ygo2coRLi/gAaIwMSnx5SoyM+uCHQ8LChrv8TQ1ZNiYBuCGgoMKcJSwACNHCh07wAkK0IFHj4UQevjwEeGHREk3ZtjwAcSGjQgfEwUIIuTHEJSROhkgAsBPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_sound-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFMzOzOTm5ERCRCwqLARqnAQ+XHR2dKyqrMzKzHRydCQiJMTi7NTu9HS61KSmpDy67DyexExSVITC3AxypBweHByu7FRiZDRiZHy+1ARypExaXBy2xGRqZFSyzJTK3AQ+RByqtASCtASGtFyuzDw+PATC1ByGlFxeXISGhJSWlFRWVAxmlBR2pBR+rAQ2PAS2xHS2vMTCxJyenLS2tCRujAxWhAxelFSixAQaHARibARudAR2hEySnPTy9Nza3GRiZNTS1IymtCRqlARWXDyCjPz6/MTGxLy+vMS+vGxqbAQiJARaZEx+hLy6vKyurERGRBQuNCw6PISanFxaXDw6PCQ2NDRGRDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfYgACCAAECg4eIAAMEBQYCB4mDBggJCgsMBQIBBg0Bhw4PEBGUDRKMBQWegg4TFBUVEBYXlZeNghgZGhsCFRyhFh0JDRWCAx4fGg0gCiERIqEcBoIjHyQeDcMlJhQnEQ8oANQpKissLS4vMDEmJhEoMjPxNDU2Ny44OTo6FzsGPD0+fgABEUTIECIMiuAzIk3GkR5IbgRJMoSAkiVKmDSRBsDJEyg1hBQYUqNGlBtSGkwZRGUDEyILWCxYcmPBgiYrB1WxEsBTgANXbCwYggVRFi2Ifm4B4CcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_tar-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFMzKzOTm5ERCRCwqLARqnAQ+XHR2dKSmpHRydCQiJMTi7NTu9Hy+1ARypDy67DyixHS61ITC3Ozq7BweHJySbJyWbAxypExOTPz21KyqjPz67OzmxFSyzJTK3LSujASGtDw+PKSehPz69Pz23OzitPTqvOzerKSaZBR2pBR+rKSefMy+dKyeTIR2NAxWhAxelFSixJyadOzirLyubLyqVJySPHRmJIymtCRujCRqlPTqzOzW5OzSzNzSrLyqXLSeTJSGNMTGxMS+vLy6vGxqbJSKZOzOxNzGtNzOhKSSRIR+LGReHLy+vKyurOTWlHxyJFxSFLS2tKyqrERGRHRuRNzKfNTGdGxeJGxiNFxaXJyenDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfcgACCAAECg4eIAAMEBQYCB4mDBggJCguMAgEGDAGHDQ4PEBEJDJcFp52CDRITFKAVo6UEFgaCFxgZGRgUFa8apBsAuhwdHh+5IBQhrwYZIh3PHdAdGSMTyQ4kJR4mJycdKCkqKywtIyMUJC4cKR7EKC8wMTIzMxE0BjUmJjY2NzgwcuggsIOHjB7NfPwAEkTIkBxEdBQxUuQIEgNJgihZwgRGEyJOnhyBciTKxSRSpDBh0iRGjClUjlSJYgXJFQBYbmTREmOLDi4BDnTxsgDJl0E5uXBBFBQMAD+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_txt-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAMR6RPwCBAQCBExKTPzGjBQWFMzOzOTm5ERCRCwqLPyGBPzKjARqnAQ+XHR2dKSmpMzKzHRydPyGDNTu9Hy+1OR2BNSOXHS+1MTi7ITC3AxypOzq7KRKBPyCDOySZPzizPTWxFSyzHS61ITG3FROTCQSBMxmJNRyROy2lOy2nASGtDyixJTK3FxGNIRWLMR+XPzStPTKrBRupBR+tFyuzDw+PDQuJIRSNAxWhAxmnBR2pBR+rPT29FxaVEw6LKRuVIx6ZISitCRujAxelAxmlFSixOzu7JyWjBwaFKSShNTW1MTGxDQ2NMTCxNze3Nza3HRqXMS+vGxubGRiZLSytCwuLERGRJyenGxqbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAfLgAABgwIDg4eIAQSCBQYHCAMJiYMKCwAMDQ4PEAcDAggRApQSlhMUmJqOBweiFQoKBBYXGBMZGpkPBhsIHBUdHh8gISIjtCOoJCUcJicoHykqK8MstBQIASUtLi8wMTIzKtE0Ihg1gwg2Ny8xKDg5OjvhItcBCDw9Pj9AQUI4Q0QMipirZ2TDERJIkihZwg+HEHpMmjg58OQIFANLomSUQi+AACZTohiAkDEKFSocJwmoMoWKSSoPpFiZdEhAgh5XHmBhQjORTZ5+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_video-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExOTBQWFMzKzOTm5ERCRCwqLARqnAQ+XHR2dKSmpHRydCQiJMTi7NTu9Hy+1Hx6dJyenLy6vIyOjDy67DyixHS61ITC3ARypOzq7ERGRFxaPKyqrBweHByu7ASGtFSyzITG3KSOPKyurBSazBR+rJTK3HS+1Hx6ZNzObAxWhAxelAxmlBRupBR+tFyuzDw+POzibNzOZIyqvCRujLyiPJyCPJSWlNTS1ISitFSixHxiFGxeJFxWLExKNCRqlDw2BFROHHxqPMSqVISChMzOzGxqZISCbLSaRKSWTFxWPNzGZNTCZLy+vLSytGxubJSSfGRiTMyyVLymTLyiRMSqTEQ+JGxqbNS+XNzKZOTWbLy2ZFxaXDw6PIyGbOzidOzifMy6XCwmFGxmXDw6LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfigACCAAECg4eIAAMEBQYCB4mDBggJCguMAgEGDAGHDQ4PEJQREowFBZ0TFA0VFhegGBkJEZcaGxwdHh8gFiEXGKAiowIjHCQlCCYgvL4noCgGKSoGCyssLS4vyxYwrzEyM9MSNDUrK9jKIBcGNiMjNwY4Gjk65dcIOwY8PT0+PwYUAuTIQaDeCiAGgggZMoQDEQNFchghMIHiEQNIkihZwoRJkx8RCDhxMuEJFAMGokiZQoRKFStXjpQk0QHLBgDRrEzJomULlwFHukhYgMWLIANfwIAJw+WKmDFkAjQoA8BPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolder_violet-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLHQWhEQOVHR2dKyqrNTS1PTy9Hx2fCQiJOTK7OzW9LyKzGxubLRW1JxOtLyCzMSS1HwijKSipLQ61HwinKxuvHQajFRSVJQytIQqlKRqvMSe1GQebHQihLSCxNzG5Pz+/KyStHQ6hPz6/PTu9Nza3KSGrJxmrOzm7MzOzDw6PDQyNOTi5MzGzMTCxGxqbLy6vLSytHRudGRiZLy2vDQuNFxaXDQ6NCH5BAEAAAAALAAAAAAQABAAAAaoQIAQEBAMj0jAgFAwHBDJoSGhWDAaDkPxEThCIpIJlcJgFgpdIaRiuYAxGcVD02gKBxuOpXPBvD1VH2ogISEceiIXI2ATBmohJAklGYaIJieOAAIoBSkqJCUlHJUmmQYrDiwFLS6foRwvpqkwMCstDTGtJCoyQjMELTQttw01Nsc3B0MBMxQ2DSfGNjg5OplHzDs5ODw5DMlRQgE9PhoMOjPh2BA/AH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_violet_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOTi5OTm5CwqLPz+/PTy7Ozu7HRydISCfPT29Ozq7Nze3MTGxEQOTGwahDwKRJSKfIx6XOzi1Pz6/MTKxNSi5OTS7Mym1OzizJSOhIyCdDw+PKxSzLRq1LSCxOTSvNTCnIRyVNTW1JwixHwqlKRutOTS5AQ6XMyyjNTS1JwerHQmfIQylHRmTLzCvKyWtHRChHwuhFxaXERCRHQ+fLSytDQ2NKSmpGxqbLy6vDwOTJyenDQyNKyqrCwuLDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQICBomHAQcICYwChQoBiJMLCwUMBw0NDg+bEBESEAcLDRMUExUMFggXAhAYGRoREBAIGxscFB0EBB4QHyAhGrq8EBsiIyQlHgAQJicnKMspuyorJCzVEi0uLy7Z2xopEDAx1QEMDDIzLjTZ2hI174I2CQ0EHMi4ge7EDQk4qgHI4aChAxYsLsg4J0GHQkI5dsSIeCFGDB49fFwcFOBHDRw8cOAAAmEkpyA1fOjoISQSJwPV/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_wordprocessing-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExOTBQSFMzKzOTm5ERCRDQuLARqnAQ+XHRydKSmpExKTCQiHMTi7NTu9HS+1HR2dCQiJDy67DyixHS61ITC3AxypKyqrBweHGxqbGRmZFxaXFRSVERGRPz+/ITG3JyalOze1PTm3Ozi1PTm1Hx2bJTK3IyOjPTy9CQqJFyuzDw+PNTGnDQyNPTq3Ozq7MS2hASGtKyaXCwqHBwaHFxWTKyahLSijKyehHRmXHRqNFSixHxyNAwKDERCPAQGBCwqLIymtCRujAxWhCRqlMS+vMTGxIyCVJSSfLy6vLS2tLSytGxubCwqJExGJEQ+JBQWFJyanDw6NDQ2NBQaFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfUgACCAAECg4eIAAMEBQIGB4mDBggJCguMDAEGCgGHDQ4PEJQRlwWmnYISExQVoBYXCREYjAaCGREaGxwdHh8PIJQKhgAhIiMkJSQkJhUnrrUGKCkf1B8pGyoUK60sLSouIS8vMCUhBw0xMjIVBjM0NTY3ODk5Og0NOwgXPCw9AD4BBvwwMABIgCBChhApUqtBhgw1INaIWMPIESMaGiIRsbFjkhpKlmDQYKgGx5MdDyxhgqFJLSdPoMiU+YRGFA5SRk4RRCWDix9TnFRxISiAE6J+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_yellow-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ExGTCwqLERCRJSSDFxWDGxubKyqrNTS1Hx2fCQiJOzqzPTy1NTKfHRydOTWTMSyTNTKjNzOjJyWFHR2dKymrOTaLKyaFLyyRMS6ZFRSVLy2JKSeHNTOnNTKhHR2FISGHIyKHKyeFOzmxPz+/LS2lIyCNJSWJMzKfPz6/PTy9Nze3KyqhLS2XPTu9Ozm7Nza3MzK1LSyjIyONDQyNOTi5NTO1MTGxMTCxMzGzLy6vLSutGRiZLy2vKyurKSipAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe0gACCAAECg4eIAAMEBQYGB4mDCAkKCwwNjYUOAYcPEBESlBMMjAUFnIIPFBUWnxcYChkajAaCAxscHR4SrREWlBkfqSAYIRy5uyKfIwipISQlJhgnx7oSKM0ABikFKivQCSwn1C3ZCC4vLwUwMd/RGDLZBjPqNCk1NTY33zjZOQQ1dOBrsIMHjx49FtQSFCDHgh47GvhA+AOIwkQNgwARUnHIxUiEcnwgwmBBDpCHAjw46ScQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolder_yellow_open-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFNze3Ozq7ERCRCwqLPz+/PTy9PT29FRSVHRydIR+fISCfOzu7OTm5MTCxFRWBIyOFFRSBJSKfIRyVOzqnPTuzNzapOzi1OzizIx6XIyCdNzORNzSZMTCfOzqzOTSvNTCnNTW1NTGFKSaHLy6ZAQ6XMyyjMzKzDw+PLS+DHyGHIySJHRmTLy+xLS2lIyKPISGJGReVOTi5ISGNExKBKyqrDQyNNza3NTS1JyeJKSipGxqbMzOzLS2tJyanKyurLy6vKyutCwuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYCB4mHAQgJCowLAQYMAYiTDQ4FCgoPEBARnBITFBIIoBUWFaEKBREGFBcYGaoUChobFRwdBRAGEh4fIBkhuqsbIiMWJAYAFCUmJifJG7ooKRYqK9QsLS4T19kZGxIvMNMBojEyMy4u5xQ0EeEABgUFBDUxbJBzYeMGjmkAchBYqGPHjggxeMy40UMfoRw+IvxQoSICEBgUgiCUlIOGkCFAiOCgYDFRgCILgqxsGYnQgRwA/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nftp-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3LSyrJyanPz+/Ozq7GxqbDxinBw+ZERmdIySjHRydMzOzPT29CwuNDRurIR2RPTSdJyulEyGvBw+bLzCxIyKhGxubERCRLzKvPzivPTmxNTChLSybGyCfCRSnBQqPLy6vLy2rCRShOTixPzy5OzerOTShLyaVEx6nCxerGRyhOTi3OzaxPTShNy6bEx6rER6zDRitBxCfPTq3LyulBw2VISq3GySrPTWlHyanIyitFSO3PTm1Ozi1LyqjDQyNCQ6XHSq3GyWvDxuvCRSpLSqpOzezAQCBCxGZCRKZExGLDQuHAwaLBQWHKymnOzexARCBJzOnGy2bDyePCxKJOzWvLymhAx6DAyGDDROLOTOpHRmVLyidLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfRgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFkZMICQoLlwwNDgQPghAREhMUCBUWBRcMGBmnEBobHB0eHyAhIg4CIxenJCUmJygpKisVLAIGLSMPJBQuJi8wMTIzNCEWJjU2Dzc4OTo7PD0yK94DPj9AQUIUQ0QwFDFFRjchRz5IbARJEkLJkiVMmDRx8uQBlCgbgDyQMmUKlYpTqlSsYsXFFSwTK2bRMmWkyCxbuICkmKVlySwvpXTh4mWilJs4c3bB8uXLqUEBHggdSvSBn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlink-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBFxaXPz+/AQCBKSipAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMgCLrc/jDKSau9OL/AuwxCKAzfOIwlcZIRKLJQMMyz5CcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnetwork-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBISChPz+/Nza3ARaZESanCyKlARudARGTLy+vNzq7ARmbMTCxARufAROVMzOzKSipARyfOzq7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVmICAGZFmKQiACweCSBImq41AYB5IodLq2hwWO0ejRWDac48Gb/QKNqNRoqspmrVcAUuIJBANS8sBIFCORUgooPEh4J8B67NgdsVBp9C5XWfl9LRMTCyReX19hARNojWlWLH+AAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\npipe-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBISChMTCxPz+/ARCBFxaXASChCH5BAEAAAAALAAAAAAQABAAAAM2CLoazpAFIV6UYZB6Yd5BtwRbEYqkYIqAQRir6KpnN8cdCddXivcbAy+S2qEOAuPx8MtZRP4EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nshredder-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBERCBAQCBMTCBPz+xFxaXPz+/AQChISCBISC/DQyNPz+BARCRAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARcEMgZhBUzgzuIH4G2FYThnZUlCab5Ed0hC6nZ3Yh8JIKyLjCYboeZKIK6BDHTGwyViopEoWAkdwfqoKhIKLFUwXY79coUtLG4CFAcOOstWyNWyEXMO57p2/vxfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsocket-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+xMTCBFxaXKSipDQyNPz+/MTCxISChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARKEMgZpr1SjFqx1QHoTaA4AuV2EmmHEUUxsKoHB7FMGPbhI7gCgnchII6+AyJBtBhjx0KC2TsIp9QXcpm1HafNEQF8mhAOCdfEHwEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntrashcan_empty-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBKSipERCBARCRPz+/MTCxISChFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARREEgZapiYWjGIvVNQjEZ5BKUAApVgjEWJzCtAnIGgC8eZ5bre7ICosQQFVY9Y/CGVwiYmlwwsac7qVRp6WqNGKpQZ9m7DojH2t+lVMtMP3B8BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntrashcan_full-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/Pz+xATCxMTCxMTCBKSipPyqXISCBFxaXISChAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARbEIAQJJU4BzEoIdSFbcNQnIVhBJ02GAeFIGxZjUl8KoHRagfeYqgo3kaxQOEwXPAyk4Mgtgg6jxYp1foETgPEKzSgBXOx0W9VIfZu2d3R5t3WhA5BEdQSQgP8EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nwww-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3LSyrJyanPz+/Ozq7GxqbDxinBw+ZERmdIySjHRydMzOzPT29CwuNDRurIR2RPTSdJyulEyGvBw+bLzCxIyKhGxubERCPLzKvPzivOTixNTChLSybGyCfCRSnBQqPLy6vOTi3Ly2rCRShPzy5OzerLyaVEx6nCxerGRyhOTezPTShNy6bEx6rER6zDRitBxCfPTu5PTq3LyqjBw2VISq3GySrPTWlHyanIyitFSO3LSqpPTm1DQyNCQ6XHSq3GyWvDxuvCRSpKyurOzizAQCBCxGZCRKZExGLDQuHAwaLBQWHKymnPTmxOzaxHx+fMTCvOzWvLymhHRmVExGPOTOpExOTERCRLyedBwaHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfWgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFkZMICQoLlwwNDgQPghAREhMUCBUWBRcMGBmnEBobHB0eHyAhIg4jJBenJRwmJxIoKSoVKwIGwg8lFCwmLS4vMDEyIRYzNDUPNjc4OTo7PDAq3T0+Pj0/QBRBQi4UL0NENiFFPkbijoRAkiSJEiVLmDR54OQJFHEPREQRIWWihYlRMkCZQuXBgyIBihSpIjLAowBWroj7gaUIlpYvXWLJUuWKlgdbHvz44XHnzgdVami5qUinR50/efoJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nzip-16:filesystems filesystems16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBIQChPzC/AQCBMQCxAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMeCBCh/i+IAesShNo4+v5gKI5kaZ7oxzCilLVvq/kJACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncal1day-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANOCLrMEUDIOUS9AFLLhx8LIRZjKYZmMRCkaChFLHty/AIiS3y6q+QtT49wq8VotRtQJGwRf6Zmrlj7DJLQXsupTJmeEIN4TB5nII20wp8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncal5days-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANMCLrMEUDIOUS9AFLLhx8LIRZjKYbj55GioRRwoQ5x4QIiIdMmcec7jy53q81qP9OO5VMAj8RXTFWzOZW95HDLdEEM4LA4nIE0zgp/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncal7days-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANPCLrMEUDIOUS9AFLLhx8LIRZjKYbj55GioRRwoQ5x4QIiwcp0fucsj873qvGMv5Jw2FIACUsW4WakGW1O046I05qmGYBhTC6TM5CGWuFPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalappointment-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/MTCxPz+BISCBISChKSipAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARbEMhJaQhA6D1E/wDGeeRgDhOhFoTBEi+REgdrIHScSEVvAD9Xr7cDqGSGpFEnQSqTv2NxCFQOiU1VEAiTZmstHFg1vQKuw+LxxfYaV/AuOQRI2O/4ewhT6Uv8EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalbell-16:korganizer korganizer16 16:photo:16 16:R0lGODlhDwAOAIIAAPwCBISCBPz+BIQCBMTCxISChPz+/AQCBCH5BAEAAAAALAAAAAAPAA4AAAM+CLrR+zCIAWsgLVRGRBhOVQiG94WPVAbHaZHYAWqRYLbge88RsbInGuBCEhRYrZYm4xk4nYdoKzKIbiKHawIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncallist-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/KSipPzerMRaBEQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARDEMhJaQhA6D1E/wDGeeRgDhOhruyatjBRSIRxxOsMEAdC0BUZDcfSEYvDo3Bn++2Cxt7RqFxWhZiCdsvdhjCVsMQfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalmonth-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANSCLrMEUDIOUS9AFLLhx8LIRZjKYbiRxLFIBpK0Q6z7MkwkJIe8b0KEeuWchFysuStVsjtfMbeMQitWpG25YfmNK1WU53XNIUYzug0OgNpuBX+BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncaltoday-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/MTCxKSipPyCBMRaBPyqXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARTEMhJaQhA6D1E/wDGeeRgDhOhFmurpi5LyIQhFfiBIAfuFzaAioBIJBCummRYPCaDPh3vhwsOZdihNfa8Ub/AJXemFZPPNBvGwG672yFMZS7xRwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncaltodo-16:korganizer korganizer16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBAT+BAQC/AQCjPz+/MTCxPzCxKSipPwCBMQCBIQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARaEMhJaQhA6D1E/wDGeeRgDhOhFmurpi5LyMYhFXiuFwZiA6qZYbbqJX5BIw2RAPxwAAWCyWMCCsiXFGEEErKz6LQZfOqiTR1YJiGq1rFyyHmo2+/1EKbCl/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nadjustcol-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBGRiZAQCBPz+/CH5BAEAAAAALAAAAAAQABAAAAI7hI8JAWL+IgvwUSSY2Lz7VTXXkS2NdJ6TwiSaB3PNQNdCbc/4cO9OjwPmhDQiTxfcHY1MpE35g0IB/gIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nadjustrow-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBGRiZAQCBPz+/CH5BAEAAAAALAAAAAAQABAAAAI5hI8JEcItooxG1oEzBoJ7oWlHd4VbNZpbx3LqUFGuajTPhI8kSLfsO0rRUCXT5wPkyHhGhsOJs/gLACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nblack_sum-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIdhI+py60BY2QwhVYdytpw/WFXF1LjcW6S1LVu6xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_all-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAIjhI+pq+FuHjwyRInqfRkDTXkgQ5YLOH6it00pyqqcPJk26RcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_bottom-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAInRIynGe0PFTQz2kdxzHf72iSiRDpc2F1niaafBroYQNe2fdx6HfgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_fall-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAIrRIyneRYP4wPUKWmr3E5b+DVh9GkYuFALiqnsJp6nObYZB5ow2a3Jvwv6CwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nborder_horizontal-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAImRIynGe0PFTQz2kdxzHf7CoTiSB7kKUpa1Vlc86rtSjvxnOSL4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_inside-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAIrRIygxxYPF4zzyenqxfVk2m0g9lnKiabqqoYl43YwGcqiFWv22zRnD/AXAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nborder_left-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAInBHKJmxYPY3TyVCozsjMbrk3gM27KyZDlioVQS3qwO7Nl6KC6q/kFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_outline-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAIrhI8ZybgQYoTy2YqtwVTunVVfN3HQsaTnc5Kp2Ibw5Zm0PHJ2w7O8I5P5CwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nborder_remove-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAIjRIynGe0PFTQz2kdxzHf72iSiRDpc2F1niaafBrraSMuQXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_right-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAInRIynaOEPH5hRRVrzbJBLn32g1TXJuWBdpYYiy47hBl+yRqH6HfoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_top-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAImhI8ZyRgPo3xgVnmnprbvnUEhx1XmgpLRmH7e+rowFssleuaBXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_up-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAItRIynwOEPH0vRuGkjnFKjpmgX2FVkuBwNhapZKZ3VyMKcGJPv5eJmAkz5RP4CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_vertical-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAAQCBPwCBCH5BAEAAAEALAAAAAAQABAAAAIrRIygxxYPF4zzyenqxfVk2m0g9llmsiCmVjJh65Jh59GtGMuzqqQNDQz4CwAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncell_edit-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAQABAAAAIshI+pm+EPnwmi2msDoLgLzQWDV4HlSJof6qki+W0nrMKlbN9bxGvMDwwG/QUAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncell_layout-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+/PzerMTCxPyqXHx+fAAAACH5BAEAAAAALAAAAAAQABAAAANCCLrc/i3ISacKIuutA8ACxWUeJg0DqBHhd6ZiRpQBag9F2n13FRis0q1QUAmCvFuKRTAYWhIi0bhz+SqQrHbL9ScAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nchart-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBAQCxAQC/AT+/MTC/Pz+BAAAACH5BAEAAAAALAAAAAAQABAAAANMCLocHiyuIASU6lE7Xx7DdgEBQVwBKE4mqlZjeT4vl7VFkYZUjOuGkMFiuJ1yKUNAWTQGkEKDknUESpdXkkYjnWIWzOVX0SyPJwx/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncomment-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+BPz+/Hx+BAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM5CLrc/i3ISacKYuStuwhAMBATKRHkAGJeu60qagqmuHK4B6Pn3N0u147Ha8FyOVCowlRCntAo1J8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndeletecell-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPz+/PwCBMQCBISChAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANICLrc/i3ISacKIuutA8BcKAwfNwwmQYDZoJ6tWrBZoRKuXIb2XRS7UG4wC25yOIGHFvu9PJ8KcRbQOVzAheoxbRCyDOKj4E8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndelete_table-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPz+/PwCBMQCBISChAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANPCLHcDDCIOSUVAaqLeY5O+G2XRQVDdA0DNxCEwrwEu9AFORVw3ee6Cu8HFKFgA2AQQ6uNTJNXYZgCNZKFBay4IhQuMBUFW/LKZlkHoOBPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndissociatecell-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAASC/AQCBPz+/PwCBCH5BAEAAAAALAAAAAAQABAAAAI0hI+pm+EPoQlC0GqxnfV2HUzR6HDWgA5Bqppr+qIhcMUqO5Oki+M87KN1ejCRTsJIKhP+AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfirst_letter_upper-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIohI+py72RIJOHRmBt3QaGz2GVBGJfKW4aiXhX2sHxbKKneDv6zht+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfontsizedown-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAInhI+pELHqmIkQNZrwfXYvzE1fBUrWoZniOjWdp0agjLL2i7rhDvgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfontsizeup-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pEeoNIFyIzXStw3q/T4VVhJHHlDGjgZ6n1bLyCrqPyuJe4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfunct-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+py60R3IkRVHQzo9BwD1qhqGneRU4gSqlVJ8Zy0mKPhOe6XwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ninsertcell-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBPz+/Pz+BATCBAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAM7CLoa/k7IKQCEdNobc+UOMCijCD5jGjAMOowrIc/Wm77ATIe2leuETcrEYpSOJ88HpNxwmqdi40Tl+BMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ninserttable-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAIuRI6JwCH/HBSBmUlxbarvO0nQJ0aa5XWodjZsiKbJGrbgaMuzW8M87jPoDgx/AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nlower-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIqhI+pELHqmIkQNZrwfXYvzE0QKGniQWmNhbYSeqXn6zJOBJLTuuuh4i8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmergecell-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ATCBCH5BAEAAAAALAAAAAAQABAAAAIyhI+pm+EPoQlC0GqxnfV2HUzR6HDWgKZpCFyBCrMurMoPvZovPsgd39MBbaQI44hU+AsAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmoney-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPz+BPwCBASCBATCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM+CLrcHMHJIEaUD16sqIUcQAne5pQaBglkZS6lxb6dRoIAQTzuphcFXWeW0xl/utIPGDQOSUdnA7IUhoocfwIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\noscilloscope-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBOTm5Hx+fLy+vAQCfAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANKCLrcGjDK+IS9494AgrbEJ3CeUBRWpp2daaHhhZKuq75jh8pxTRaEQbAgFAIHv1VvR/vsdrnSCmdpagYnjfXS27Q+N29nQuYA/AkAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npercent-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIkhI+py70RUHxxQmosu6BOdWkNR35PVm1etqEsaKXnwTn2DfgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nprecminus-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAIthH8RiJvrmHogVoXNtFRDpjUf6JWkeUoXlpGBAMfC+cowbd+uwL54/rMFZf4CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nprecplus-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAQABAAAAI2hG8Rp4y9IGgszqhyspLueYHih43hiX7Iui5XprGTQNeCPNNBje86L9vBdr2a7xY0AllHm78AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nremovecell-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAAQCBASC/Pz+/PwCBCH5BAEAAAEALAAAAAAQABAAAAI5hG+hq+IvAGPwydlqxAohvnjHMChkR6YDcKaougZqCMdyGYqSG+jXKQtoNkGTUHPBDJMTH+jJ8RcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nremovecomment-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/AQCBPz+BPz+/Hx+BPwCBMQCBISChCH5BAEAAAAALAAAAAAQABAAAANVCLrc/i3ISacKYuStuwhAMBATKRHkUIScUBSeahhigBbzK+HGgXmHmYHXC41MqKDwcGDFMryCz4gi3YQwkKiFY+ZAoYrUF5g1HV3G7DFuFBvSx8GfAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nresizecol-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBFxaXAQCBDQyNPz+/AAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMyCLrcG0A4CZ90saohuv+XEgxYxkDhQp2lyIBwKhB0bct2TuB6zfe7F5D26xV1x9zFnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nresizerow-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBFxaXAQCBPz+/CH5BAEAAAAALAAAAAAQABAAAAIyhI+pmxHinph0GnqH3hoIDwocd3zZ2F0lmoInWq5s/I60xw5hmF8WPnNAhJUK44hM+AsAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nseries-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBGRiZAAAACH5BAEAAAAALAAAAAAQABAAAAIjhI+py+0fUGRhGrswVtr1FgiGsGlhZVWAuarr9byyB8f24hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsort_decrease-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAAT+BPwCBAQCBAQC/FxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM5CBDM+uKp8KiMsmaAs82dtnGeCHnNp4TjNQ4jq8CbDNOroIe3ROyEx2A4vOgkOBzgFxQ6Xa0owJ8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsort_incr-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIIAAAT+BAQC/AQCBPwCBFxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM4CAqxLm61CGBs81FMrQxgpnhKJlaXFJHUGg0w7DrDUmvtPQo8qyuEHoHW6hEVv+DQFvuhWtCFPwEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nspecial_paste-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+xPz+BNTS1MzGLMRaBMzOzPz+rPyqXPz+/MzGNDQyNKSipAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARoEMgJQhBySGx7IEQwFKMWGKgRHNZRIAJSVAm6usIwCEo+BDWVJ/CKzYAplWJZItGSgSVPZBEgU9EFQyGyWoK25XJ4DTO2iob6CxVLe2ys4rw9e8HKd8ybVJ7ndgEVQz09e1YUEmQefhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nstrike_out-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBGRiZAAAACH5BAEAAAAALAAAAAAQABAAAAIghI+py+0BgwOS1gXnuS/b6ClCpCUcclJMmKIGWcby5BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_bottom-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIVhI+py+0Po5y0hYtzrkB7zH0fN/kFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntext_center-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsnRkqtDnhu1zHfFSpjaY4PavgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntext_left-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsgRoqr3Vnt102fFSJjUC6nlPoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntext_middle-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIXhI+py+0PT5i01pisphjt3UmfFZYm5hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_multirow-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsg2kfZvblXbwTg10WlA4rjyvgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntext_right-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+pm+EPIZstSrqsDhhv1ylfFE5jiYwX6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_top-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIWhI9pwe2uYnq0yQtqxbz7D4biSIZ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nupper-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pEeoNIFyIzXStw3q/dR2hhEVcJqamuq6Z9brlNtKMeHuKXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nvertical_text-16:kspread kspread16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIihI+pFrHqQHynTRrvyxQ12YWQWJGMpC0f2E1psr4eaj5+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\napplix-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFRSVFxaXFxeXNze3Ly2rJyanOTi3Pz+/Ozq7HRydFxaVISGhGxubMzOzDQuLExKTCwqLIyKjGxqbERCRCwuLJSSlOTi5BQSFPT29IyKhDQyNISChDw6PBweHMS6pPz69Pz29PTq3Ozm3MSynMTGxAwKDPTu5Ozi1LyulExOTCQiJPTm1OzezLyqlLSyrDw2NOTazOzizOzaxLyqjKSipBwaHOTStLymhLymfGRmXNzKtOTOpLyidMTCtMS+rCH5BAEAAAAALAAAAAAQABAAAAa9QIAQEBAMikfjcCkgOJ2FgCGwFAYOiCwioUAYFtUrgtFFNBzeB5OAgESyEsWEUjFYAJYJ4hLBoDMHBRobAAaGehwdHnoZCQcfEUKHCBQBAxsgISIjJIRCeSUmHAYmJSInKCmRkgYqGw4ZKxMiLC0unoUvFBQQMBQRMTIzNBVDFjUrGwO9Nh8zNzi4BhM2LyIvGhgLNzc5akM6DsEyMjsfPDw9uAALPj4/HyQ0ND31q0ICFRv6FTAb/xE2+AkCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nbinary2-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRSVFxaXFxeXFRWVNze3Ly2tJyalHR2dISCfLSyrPTy9Pz+/Ozq7GxubJyanKSmpMTCxMzKzLy6vNTS1JSSlCwuLLy6tMzGxOTi3KSipKyurHx6fOTi5IyKjGxqbERGRDQyNMzOzOzu7GxmZIyKhHRydLS2tNTW1ERCROzm5MS6pIyOjDw+PPTu5PTq3LSqnOTazOzi1GRmZJSWlCQeHPTm1OzizLyqjISGhExOTGxqZDw6PNzSxOzaxGRiZExKTCQiHEQ+NLyulOzavOzWvLymhHRybLyypNTGtOTOpOzexLyidMTCtMS+rMSynLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfqgACCAAECAwQCiIiDjAIFj48GAgcBjIIICQoLDAwNDgwPA4MIBhAREgkTmw4UDBUWAxcYFAUZGggbHB0eDh8gIQkiHSMeFRoUDyQRIxkGJRYmFScTKCcHCCkgJyoNGSsWHCwKCCgIASAgLQoZLi8wISUbEyQUJAEDKQEKMS8yMBYeZmCgMcEcghog9tm4gSNEjgEPdEDYEQJEDR4aetzwgcPCjw8VfiAAwqNFECFDehApYiSEoCMQBVjQkQBJkpVKjFhgNGBGzSRLVhZRwsTloAFNmjhZ8WQIDiZQoOwcFMCCVQshrmYN4ScQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nbinary-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPz69HRydMzOzDQyNIyKhERCRPT29GxubPTy7Pzy7PTu5Ozm3LyulPTq3Ozi1OzezLyqjPz27OzaxLymhPz29OTStLyifPTm1OzavOTOpLyedMS+rMS6pMSynAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaJQIAQECgajcNkQMBkDgKEQFK4LFgLhgMiOq0WDgVEQrFdKAXfhJWRODTMQ6+64BAMGHAq+pB4hCF2eURoVwgREhMUgl5/EBUWimdWB4cVDxcYiwJiGQcVfBobmhwPEgkWFg8dmWcQEgcWFw99HpoVFR8XGiAhISKLI8EkJRgYGyK/SgvLzM0LfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncolorscm-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIcAAPz+BFxaXNze3Ly2rJyanPz+/Ozq7GxqbJxaLLxOFLQ+HLQ6NMSOnOzi5GxubMzOzDQyNMx6JOSSXOSedNx+ZMxaXLQ6ZKRalNzW3IyKjERCRNSWPPTKnNReNMRGVLxalJRGpHRanNTS3PTy9OTi3ISGfLySNOzCfPTatOy2dNxuFMw6DJxGrHROvEROnHyKrMSmTOzanNzShOSqRNyCFMxCHJxGnFxavDxqxCRmrCxijPTq3Ozm3LyulLyyZOTenNTGZMS6VISKbCyCzASGxAR6rBxmhKyqpOzi1JyuXLTShJzKdHS+XES2XCy6pDSy3Bym3AySxAR2pBxadKyinPTm1OzezLyqjGSWTHS6ZFy+ZCyyVCS2dDy61Dyq1CSOtBRqjExqZKyilOzaxLymhDyeTCSuVByyZCS6hDS2vDSatCx2lCxabIR+dBSKTByeZCSmhCymnCyanCR6hNTCrOTOpLyedCxmVCR+bCR2bCRmZExqbMy+pOTStKSelKyejMSynLyqlLymfLyifAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAjqAAEIBBCgoEGDAxMGEMCQ4YAABAIkFLiwgMUCBg4UiJgQQQIFCxg0sOjgwUYIAiNImEChgoULGApkcHBAA8oNHDhI6ODhA4gQIkaQGFACgokTKFKoWGGBRQsXLwQIHQABRgwZM2jUsHEDRw4dA3bw6AHBxw8ZQIIIGUKESBEjR3YgIZtEyRImTZw8gRJFyhQqVaxcgYAli5YtXJx08fIFTBgxVsaQQVnGzBk0TtKoWcOmzZExklECcPMGThw5czqLoYOijh3RAO7gyaNnTxsxfOr0cQ2boBg/f44AChRI0KDXCiEoX84cgp+AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncore-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAASC/PzuBFxaVNza3Ly2tJyanPyuBPQCBPz+/Ozq7GxqbFRSVHx6dKSmpHRybMzOzDQyNGRiZHRydHx2fExKRCwqLPTy9ISGhERCRCwuLERGTIyOjBQSFGReXJSSlFRSTDQ2NAwKDNze3OTi3Ly2rFxaXAQCBFxeXMzKxOzm3LyqlDw6NCQiJFROTLy2pDw+PGRiXMS2pOzi1CwqJBwaHAwODAQGDJSOhOzWvLymhKSajNTGrJyWhOTOpLSyrKymlKSelMS+rLyidMTCtMS6tMS6pMSynLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfVgAAAAQAChoeHgoqCAgOOjgQCBQKCBoMABwMImwgJCggFC4sGDAQNDZoIDg+gEAcABhESEwoUFQsWFw4KGBmCGhsFGwoLEBwYCRYEFxCEHRceFwofIBwhDSIjJBCCCxISDiUaGRwmJygpKr4AGAIl4issISYtLuncgi8YLxAs5SYwYshQgQ8AixksaNSwYYLDDRc4chS0USMEQxMhHOjYEbEggBUWTQhwwANiD4mLBPj4AYTHjyA9cPQQsq7bkCFEihhRkSPHkSMeBUDIAGFo0aMZ/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndeb-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/FxaXNza3Nze3Ly2rJyanPz+/Ozu7GxqbPz6/JwCBMw+PMQCBLQCBNx6fPT29GxubMzOzIyKhDQyNLwqLLRWVLxaXNyurERCRMzKxOzq5Ozq7MQ2NMRmZLwCDOTi3Ly2tMReXOS2tMTCvPTu5Ozm3LyulMSSlNTOxPTq3Ozi1OSytPTm1OzezLyqjNyqpLxaVNzSxOzaxPTy9Ozm1OzexOzavLymhOzWvOTOpOTStLyidMyShMSulLyifLyedCH5BAEAAAAALAAAAAAQABAAAAa0QIAQECgajcNkQDAYCASEQCGQFC4NWMMBkZhWFQtGw/EwQCIGyWSoaFAqFgblIkEgMGthQ5HRbAQcFAcaBGp6DQEJCx0XFx4ZGx8geQ1ECyECByIMIyQlJnkMRBwnBwYODSgpKqB6RCIcK6gEKiwtLpQKiS8WMAQxKi0yuEOICTM0LSo0NTY2N3kAbhoHBzQ0zjg50EkKHC80LCo2ODo5O9FEBCE8Pe49Pj8/6QET9vf4E35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndocument2-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJSWjPz+/Ozq7GxqbJyanPT29HRydMzOzDQyNIyKjERCROTi3Pz69PTy7Pzy7PTu5Ozm3LyqlJyWlJSSjJSOhOzi1LyulPz27PTq3PTm1OzezLyqjIyKhJSKfOzaxPz29OzizLyidIyGdIyCdOTOpLymhOzavOTStMTCtMS+rMS6pMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaQQIAQECgajcNkQMBkDgKEQFK4LFgLhkMBIVUKroWEYlEgMLxbBKLQUBwc52HgAQ4LBo049atWQyIPA3pEdFcQEhMUFYNVagQWFxgZGoxfYRsTHB0eH5UJCJAYICEinUoPIxIcHCQkIiIllQYEGCEhJicoKYwPmiQeKisrKLFKLCwtLi8wHyUlMYwM0tPUDH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndocument-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPz69HRydMzOzDQyNIyKhERCRFQ6LJSKfNTOxJSOhPT29PTy7PTu5Ozm3LyulOzi1PTq3OzezLyqjOzavPz29Pzy7OzWvLymhOTOpOzaxOTStLyedMS+rMTCtMS6pMSynAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaLQIAQECgajcNkQMBkDgKEQFK4LFgLhgMiOq0WCAREQrFdKAVXKyNxaJgBjgck4khLBAPGm4r+ghETeHtEfVaAFBUWg15gjReKZ4YTFBgYGRpvcQoPDggRnwwMG5hnHB2UFxcbHh+LAh0YDA+zDyCtZ5UXIRsiIiAjiyQlJCYnGhofI8BKC83Ozwt+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndvi-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAASC/FxaXNze3Ly2pJyanKyijPz+/Ozq7GxubIx+RIRyLHRyVGxqbMzOzDQyNHxyTHRqNGxiJHRiLJySVIyKhERCRGQmLMy6ZNS+TMSuPLSePIRaNGReLHRuTPT29FxOFKymdIRmLHRiHGxKLDQuDPTy7Ly2tHQqLLwyPIxqVGw6LIx2LGRSHDwyDDwyFNTOxOzm3LyqlIQuNLy+zKSGdKSSfJRSRKSSNExKJLSmnOzi1LyulIyCZIxiPJyGLExGFOTSvOzezLyqjLyyXAQCBNzGRLyeREw+DFRONNzSvOzaxGxqVKSelJSCNEQ6DFRKFKSajMS2pNzOtOTStLyidEQ+FLSunOTOpIyKdMSulLymhLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfVgACCAAGFhoaDiQECjIwDAQQBiYIBBQUGmAcIBpGTCQqgC5gMDZwOgw8KEBESEwkGFAgMFacAFhcYGRobEBwdHgIDFKcWHwYgBiEhIiMkAyUCJg4nKCgp1SorLC0uBC8wMQ4yMzQnNTM2Nx84LTkNOjunNjY88z0+Hz8kOUBBQqdDiHQoYiREhBZHkORIouSfIAghjCiI8IHEEiYDgAApUAtAEwgfnDzBASWKFCBTqHQE8ONIFRwErFxRcuWKSkU8sBTIkSWLFi1btqwM4KCo0aMO/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfont_bitmap-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAASC/FRWVFxaXNze3Ly2tJyanPz+/Ozq7GxubGxqbNTS1DQyNPS+vPw2NNQeHFw6PPTy9IyKjERCRPzi5PyGhHRWVOTi5PT29OTi3IyKhPza3LySlLQGBGQCBNza3Pz69PTy7MS6pKRubPy6vGQ2NKRSVIxmZPTq3LyqjLQqLHRydPxydHwCBNTSzPTu5Ozi1MSynKQCBOQ+PKwCBIReXJwCBExOTMzGtOzezOzWvEQeHLSytOR+fIxaTOzexLymhEwCBDweHNTOzPTm1LRORIQ6PJyOfOTOpOTe1OTSvLyedMTCtMS+rLyulLyifAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe6gACCAAEChYeGg4oCA42NBAEFAYqCAQMGmAYHCAaSlJaZmAkKnQuKAQwNDg8QBhEJCRKmgwITFA4VFgYXGAQZs5UaGxwdHgYfIAMhwAAiIyQlHCYgECcnKMwpKSoKKywtLicvMMwcHDEyMjM0L+3YgzUsNgH0HCw3ODnvgjU6OwMvBvCQ0cNHjh+zOgAJIqTaECJFOhg5gvAUEmsvksBAAeOIEmYBbixhEgJGExROlHw8taCly5cL/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfont_truetype-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRSTFxaXFxeXNze3Ly6vJyanPz+/Ozq7GxubHx6fCwuLDQyNIyKjKSmpPTy9PT29HRydMzOzCQmJAQCBKyqrFRSVLy+vGRiZNTS1GxqbERCRMzKzJyenOTm5JSWlLy2rIyKhMzK9KSm1Kyq3OTi3OTi5JyezBQSJExOTLy6/CwuXLy+5LyulMTC3LSytHx+7Ly2pLSyxLyqlNza3Gxq1OTWxMS6pLyqjPzy7OzexPTq3LyynOzWvLymhPTy7DQ2bOTOpGRmhERCfNzGpLyedMTCtMy+rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfIgACCAAECA4WHhoOLAgSOjgUBBgGLggEEB5kHCAkHBgKCCgsKBgwNDg8HEBESngwAExQVBhYXGBmZDREaGwuDHB0CHh+4qgQgIa+CBMEiIyQiJNAlIMoAJgYDJygpKisWLAMtvoIe2S4pLzArMTIBM9YHBRUeNAQ1KwU2NzjWFAwDDEDIgS+GDh39Fl3ykGMHPh46evggJ2gAgR87HAKZYSOID2uECGQUMkRIAiJBioAUYMTIkRs8cODwUUSlQgY4GSzQuVOnn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfont_type1-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAASC/FxaXNze3Ly2rJyanExKRPz+/Ozq7GRmZPz6/HRydMzOzDQyNJRmZPSmpIQuLGwWFKxeXPTy7IyKhNxSVGxCRLy6vPQ+PPT29GQ2LPTCxOROTPz69KQ2NPSGhPTq3Ozm5LyqlGwODPxiZOzi1LyulLwKDORydBQSDOx+fNw+PNS2tOzi3PTm1OzezLyqjNQaHPRubJx+fMS6rOzizOzaxMwuLKQWFHRaXOQuLJSShNzOvOzavOzWvLymfCwiHHx6dOzexOTOpOTStLyedMTCtMS+rMS6pMSulLymhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfFgACCAAGFhoaDiQECjIwDAQQBiYIFAgaXBgcIBgQFk4uYBgkKC5wMiQ0ODxAOERITCggFp4MUFRYCFxUCGAIDE7QAFBkWCRobChIcEr60HR0IHAYeHQQYEh8gIbQbIgjGIw8WEtgkJacmJyjfKSoFKywfLS4vpzAxEAgnHSYyJjMkaNSoB0CEChs3cMjIYULHDho8evig9aPiAQFAHAap0UPIREXYPpAIEnGIECLBABQoYmTGESRIfCQhglIRg5s4czLwEwgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ngf-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAPz+BFxaXDQyNAQCBMTCxPz+/ISChKSipERCBMTC/Pz+xPzerMQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARwEEgQahVijMmD/oRAbBw1FCgaFFrppeo5UtILWxlAGNWZHocA4bAxGAnDg9GA8LQCxGTQoHwVNYYEMEHtKYrEA0tctVIOo0Fl2Ct8AQLlKMnzLFg1KIHBCGoUbiR5VSd3C28TThpubgqIEhkfkh9+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nhtml-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRaVNze3Ly2tJyanPz+/Ozq7GxqbDxinBw+ZERmdIySjMzOzPT29DQyNDRurIR2RPTSdJyulFSGxLzCxIyKjHRydERCRLzKvPzivPTmxNTChLSybGyCfCRSpBQqRLy6vPTy7OTi3IyKhCRShOTixPzy5OzerOTShLyaVEx6nCxerGRyhOzi1LSyrEyGvOzaxPTShNy6bEx6rDxyzDRitCRCfPTq3LyulBw2VISq3GySrPTWlHyanIyitEyO1ER6zBxCfLSqnCQ6XHSq3GyWvFyGvDxuvLSqpPTm1OzezLyqjCxajFyO1GSi3NS2bKyaTCQuPGRufOzexLSmlER2vKyWNFxaNHx6dLyunOzWvLymfERSVExKNDRCNKyilMy+pOTOpLyifFxaVLyidMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfYgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFkZMICQoLlwcMDQQOgg8QERITnhQFFRYHF6cPGBkaGxwdHh8gISIDI6ckJSYnKCkqKwksAiEtLg4kLzAhMTIzNDU2HxQ3NzgOOTo7PD0+P0A1QR8uNy1CDkMvREUyRjNHHjkfSElKlpxi0sTJjydQAiSIIkXIFBhUTn14UIWGFQhXHHzAkgWGli2nAHxIwIRLFy8bv4DREkZMSEEfYo4hQAVMGJZkXhIaIERImTJmlogRc0ZnAAdIkyp14CcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nimage-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPz+BFxaXNze3Nza3Nza1LS2tJyanPz+/PTu5GRqZOTi3HRydMzOzDQyNJQOFDxKfKTW5OTy/OT23MTaxISKhGxmZERCRCwuLJQSFPzGpLweHJTO3ESu3DRilNz61FymXCxKRMTCxPTy7Ly2rIyKhDwCBORiRKQWFEy23CyKvJTWhDSOPCRONDQaHNROPNQ2JLRubHTC5DR6rHR+jFSqRCRyLGxqbOzm3LyulCwqLMySjMQ2JMyqrERijJSenFSGXGRmXMS6tPTq3Ozi1MS+vMxCNKyqrHR2dPTm1OzezOSKfNTe5KSmpIyGjLy2pOzWvLyqjIRqZIyKjHR2fExKTHx2bLyynOzexLymhERGRGRmZKSWhMS6pOTOpLyedMTCtMS6rMSulLymfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfcgACCAAGFhoaDiQECAwICBAUBBgGJggEEB5kHCAkHk5UBCpqZCwyeDYIOAA8QERITmRQLFRYXABgZGhscHR4fICEiAiMkDSUmJicoKQ8qKywLAwgKIxctLi8wMTIzNDUJNiEINzgNOTo7PBA9Pj/QQEFCQzg5F0RFEQQ+RhRHswVIkpS7oEMJgiUhCjBpcqSCkyFPoNjKEYVJCCNSpgSgUsXKlSdYUAG4kCOLlgpAgFTZwuVJFyy2Bi0gEsSJzZYuvYi09OULGC44wmAR48VLDkU5zClt0OACUz+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ninfo-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3Ly2rJyanDROXHSSpISetPz+/Nzm7GxqbGyGnMTS3MzW3JyuvERujLzG1HRydMzOzPT29DQyNMze5Iy2zLTS3Cx+pCRijLS+zIyKhGxubERCRFR6lGSivFyavISuxAxajBRejAxGdDxihJyyvCR6pBRqnAxelAxOfPTu5OTi3IyqvFSOtJy+1IyyzFxyhOzm3LyqlGySrAxejAQ6ZFxqfMzKxPTq3Ozi1LyulCxulAQuVISKjMzGvPTm1OzezLyqjBwmLBROdExOTKSinNTOvOzexBQeLAw2XAQmTCwyPLy2pOzaxOTWxLyedCQmJAQKFAQWJKSalOzavOzWvOTOpLymhKyqpMS+rOTStMSulLymfLyidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfVgACCAAGFhoaDiQECjIwDAQQBiYIFBgcImAkKCJGJCwwNDg8QmBESEwQUgg4VFhcYGBkaCBsRHB2qHgwfIAghIiMkAhMCAxsUJSYhJygiKc4qCysrLAPILS4oLwgwKcExEisyMxQFNBg1Nb7ONjc4OTo7yAU8IiIIDiIqPT4/QEFCVA0hooJBAg0eehQxciQIEnKCktiYqGQJEwJNnCB5AkWVoChSpkwpQmXAkypWrmDxKAhSlixaTlrZcqWjIi0/BmjhsgNLFy82BwWgQDQK0aNE/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nkmultiple-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXPz+/AQCBISChPz+xMTCxPzerKSipAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEIRJgb04iLEJwaAmjMTwgVbAjeaESmNcGMGrxmOhDqE8HAOVJ7MSFH4qhOmiOQIPNIGB4JJwnIaDaFaTUL4iYxc0MJidQVvROc4Yfz+a+g3V2sAVfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlog-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3Ly2rJyanPz+/OTm5GxqbMTCxARiTARSPARCNAQ6LAQyJGx+fGxubMzOzDQyNCxGPARyVARqTARaRLSyBCRGHFRuZIyKhERCRDRuXAx+ZPz+BIyOBFRybOTi3AyGbAx2XExaDBROLOzm3PTy7DRORDyeXBx2VEymVHyuJGRyDPTu5LyqlFyGTBxaNAxqVDR6PARKNPTq3Ozi1LyulCRuTCxeNBSCZDxmJEx6bOzWvPTm1OzezLyqjCSSdCSmhBySdBR+ZARqVEx+bNzSxOzizESCdAQCBNzOvOzexLymhOTStOTOpMS6pLyedMS+rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfIgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFkYIICQkKCgsLDA0ODxCbEQASExQJFRYXpBgZDwcaqxscrgkdHqMfBiADGasIIRwiHSMdJB0YJSYCA6snKCkqFgorHSwdIC0lLqsvvx0wMTIWMxgCNDU2xzcdOBw5EzoKOzw9Pj/WgAQRIiTEkAlEihg5wgMgACRBkpwQIpGDRCVLeDCJACGJx48gAzRxspHQoZNPRkJZNSjAkygDntiwwYQJlJWKIujcyTOCn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmake-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxWVFxaVOTi3Nza3LS2tJyalGRmZMTCxPTy9Pz69Pz+/Ozq7GxubJyWnFRWVHx6fHRydMzKzDQyNHx2bHx+dIyKjERCRGRiZKyilLSifMTCtLy+tISGhOS2bPzerPzuvOzetJSSjFxaXOzu7PTy7MS6pGxqbKSWdPS+dMSidOTerPzqtISCfKyurOzq5LSqnMzKxPS6ZEw6HJSKbOTStHR2dMzGvPTq3OzizLyulFRSTOyyVNymXOy+dKyqpPTm1OzezLyqjJyCTOSqTOSmRLSupNzSxOzaxOzexOzWvOTOpKyinMS6rNTGrLyedMSynAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfagACCAAEChoeGg4oCAwQEjQUCBgGKggcICQoKCwwNCg4CiwQPCBAFmRESCwYTghQCEgYHDBUSChYNDRetGAQZGhscHAIFDAoDHB2tAQYeHyAhIiMIJAolBCYTAicoKSorLBItGC4DLy8wExExKjIzNB81CBI2Nzg5Oq07KDw9Ph4mdgj4IQFIECGtHrgYQqRIjQoPjBzJkQMJQgANkrngYGFAhB8UkyjR0EpQAAkUKkQQkCGHEiVLLg6y8IDJhiZOXsJ8UtLkhpsmoAgRouIJT0UPJihdynSCn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nman-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXFRWVNze3OTi3Ly2tJyanNza1Pz+/Ozq7GxubMzOzDQyNOzq5KSmpNTS1IyKjGxqbERCRPTy7PT29LSytOTi5MTCvMTCxLy6vMS6rISChLy+vPz69HR2dLSyrLy2rNTW1IyOjOzu7OTm5HRybHx2ZNTOxLyulLS2tIyKhHRuVMS+tHx6fGRmZLyqjISGhJyenMTCtGxqZGxmVMS2pFxeZGxiTMSynLymhHx6dGRiZFxeXFRSVLyifGxmTKSSfLyidMS+rLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAEChYeGg4oBAwMEjQUCBgGKggEHCJkICQoIBgKKkgSamQoLngyWDQ4PpAgQChESqQACExQVFgkXGA8ZBBobtAENDQsGHB0dEx4fBCC0AhYhGCIjFA0kJSYnKMMPHCkqFg0DIQorLN6WCx8OLQsHIQsuKxovtIQwMR4ZHDIYZtCogU+RjQAeUmDAkELBDRw58hHSsWMDjx4XV6DwIZGYCRc/aNz4AeRFkI4sZAipgePFCx9BhkgUwKCmzZsM/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmetafont-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3Ly2rJSWlPz+/Ozq7GxqbKSajPT29GxubNTS1DQyNIyKjERCROzi5Ly+vKyqrKSipKSmpKyurISChKyinHRybISGhGRiXJyanIyOjFxeXJyenJSSjMzGxMzOzMTGxLS2tISGjExOTLyulMTCxISWpGx6jExifFxufJyepJymrFRSVLSupLyqjERKROza1OTKzNS6vGRmZLy6vPz29Hx6dMTCvHRydJSKfOTStLymhNTCxLSOjKx6fMS6pLyifLSytHx+fOzWvOTOpLyedMSulLyidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFCJKKApcFCQoLBQQMnqAFDQoHDqeDAQ8QERITBhQVFhWnF4IVsxgKGRobHB0DrxUeHyAhIiMeGCQVFCWvACYCJygWKSoTFxcD1oMJGissJiwjFC0ZLi+nMBoLMTIPFDMzDS00FvEAYlyQUMNGiBs4OuQgoWMHj2sDe/j44aNCBh1AdgS5BoCGBhNChlxAQGRHESMcYXCI5sHCkRdIkKBUxKCmzZsM/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmidi-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Nza3Ly2tJyanPz69Pz+/ISChOzm3GxqbKSipAQCBHRydMzOzDQyNIyKhERCRPT29OTi3PTu5PTy7LyqjOzi1OzezOzWvLyidOzaxOTOpMS6pMSynLymhLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaOQIAQECgajcOjUTAYEAKFgDBgOFQNiMHhkFAYosQFg2HNbg0Nx/dB3W7NW0hDEWEjxm+BWzIhINhVbnBUFH12eAeDFRQUFoBuiVoGRRQXjgGQiQQLCwELBZaHZJGMARgLGZeZCARRUKgaom8DCAEZGwscqm5YrZyfHLFKRQQdHhYWHxogD0NED9DR0g9+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmime_empty-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPz69HRydMzOzDQyNIyKhERCRPT29PTy7Pzy7PTu5Ozm3LyulPTq3Ozi1PTm1OzezLyqjOzexOzavPz29OzWvLymhOzizOTOpOTStLyedMS+rMTCtMSynLymfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIAQECgajcNkQMBkDgKEQFK4LFgLhgMiOq1eEQnFdqEUXK2MxKFBHnqvDsGA0aaaz4iHvE68WxEQERITfG+ADxQVhGV/DxEWFBcYhQIIgBEUFBkak2UbgYkZHBwdlIgUHh4aHB+lZZkVF6sgHyGFIiMiAyQYGCUhtkoLw8TFC35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmisc_doc-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRSVFxaXFxeXFRWVOTi3NzW1Nze3Ly2rJyanPz+/Ozq7GxqbMzOzDQyNHRydExKRERGRExKTERCRCQiJIyKjCwuLGxubDw+PDw6PDQ2NBweHAQCBPT29IyKhNz+3HzmfDTCNASaBBxaHCQmJPz69PTu5JTqlGTOZCSmJAR+BBxSHOzm3LyqlFTKVASCBARmBBxGHNTSzPTq3Ozi1MSynAyeDAROBCQ+JBQSFNTOxPTm1OzezLyqjCwuNAQyBCQ2JMzGtOzexAwODOzaxOzWvLymhMzCrOTOpNTKvMS+rLyifMTCtLyulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfcgACCAAECAwQCiIiDjAMFBgeRCAMJAYyCAQUKmwoLDAoJA5eZnJsMDaAOAA8BEBESExETFAsVDwwTFgAXAhgOGBkaGhscHQUIHqoDAR8gISIjJBQGJSbHugMSJygpKisU0x0mLC2qAhEuKS8wMRsbMiYzNDW6ARM26zc4ORQ6Mzs8evgAACGDChg3fgDhF6SAECE9VEXQYKGiDwtDKAQRQqSIEV25KGzIQZIDhSNFiiAxomoQAwM6kgRRgiQlkiW6BgVIwkQJghpNeixx4qQlJiAWHCh1kFSpBT+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnetscape_doc-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNTW1Nze3Ly2rJyanPz+/Ozq7GxubPz6/OTi1Ozq3GxiTMzOzCwuLMSijGROLLSqjGRiZOze1LSOdIyKjEw+NHxGJNSqjMTGxPTy7Ozm1NzWxLSSfFw+LMzKvHRuVKyeZHxybOTazOTi3Ly2tDQyNOzm3MS6jFxaRPTu5LyulOzi1KSehMTCxKSOdHxuRMzCpJSGXOTStLyqlHRqRIR2TFRKLLyedLyqdGxWLIR6XOzezJyCZJySbEQqHKyKdFRONJSKfOzaxNTCpKSWbJSSjExKNHxuNOzWvLymhIyKhOTOpHRydHx6bIR+dOTOrLyidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfVgACCAAGFhoaDiQECA40CBAEFAYmCAQMGmAYHCAmSlAEKCwyZCA2dDoIPEIsREgkTFBUICBaoABcYGRobHAodHhkDBBW2AB8fIBwMESEiIxokJSaDJxAUKAwQESkaKicrqBssLS4vBzAfMTIRMwo00zU2LTc4OToQOzU3DDwr04Ixeljw8QNIiCBCYgyJUIxIESMfjuxAwoDDkCRK/j244CNHjhBIPDxYMoPJA1sXIDRxkuOIkycXHsyAEqUYoRk7GDAh8uJFDhw4/lUy4aCo0aJE/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnews-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/AQCBERCBPz+/FxaXIQCBMQCBMTCxISChKSipDQyNAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARXEEgZwrxYikFsvtUwBN0nEWIhkh4YiIOhjiX1hqIsHlb4jr8VwoJa/XCCBG4ZZA2bRxEi0QkgeLAloUZKYGEDhLgG6H5JBEFrYg4ItmsMCaGomFyEiz8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\npdf-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAASC/FxaXNze3Nza3LyypJSSlPz+/Pz69Pzq5Ozq7GxqbJyanNyGhNx6dGxubMzOzDQyNERCRPz6/My+vLxaVJxeXKSmpNTGxIyKjNTS1OTi5OzCxLRSVMTCxKyWjOTi3Ly2tIyKhLxmZLSWlOTe3MzKzOza3MyytNyOjAQCBKyqrOzm3LyulPSajMRWXOSGhOyGhKxiXOzi1OxyXKRORIxSTNTKzMy6vLyenLRubLwqLMxiZNSurJRybOzezLyqjJxCRGxSTLy6vGQiJMw+LJR+dMzCrOzaxIyOjKyurHxydNxWPNTCrOTStLymhIR2dKyKhIxuZIR+dJyShOTOpHRmZKSKhJyCdKyilMSulNTCpLyedMS+rMS6pLyidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfQgACCAAGFhoaDiQECAwKMBAEFAYmCAQMGBwgHCQoGC5OKAgYMDZcODwYFEIkREhMUFRYXGA4OEauCGRkaGxwZHR4ZHyAhuAAdCQgiFR8aHSMkHwS4JRomIicoJykqHh0rLKstLhQcFC8wMR0FHgQy4TM0HDU2Nzg5Ojs8PQQ+P6tAggjRVaLEjiFEihg58k+QBSQdQCTpoITIkhBMmjgxVsBCxydQokiZYoTKxkRVrFy5EgJLFi1NqGwxRohLBy5dsmT54cXLTEUQggodCsFPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npk-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/IQChFxaXDQyNAQCBPzC/MTCxMQCxPz+/ISChKSipERCBMTC/Pz+xPzerMQCBCH5BAEAAAAALAAAAAAQABAAAAR6EIAQhLVjECJlKISwjcZgcFNxhATiugKyTaP4wu0JiOyNXBqAIWFpvRQKgUHBSTgNS4UzseBxBMxoMiG1NTcJBpLBLTaaTIVM3fXuFKeQMmk7AwbSU5QocsgkFnAPD0kbFBQdO1hELQ4fK4lWLQ0IASsoEhojIwEjfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npostscript-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxWVFRWVFxaXOTi3Nze3LS2tKSajPT29Pz+/Ozq7GxqbJyanISChPz6/HRydNTS1CwqLMTCxISGhOzu7ERCRDQyNERGRLy2rIyKhExOTAQCBKyqrOTm5KSmpHR2dNza3AQGBNzSxOzm3LyulBweHBQSFKSilOzaxAwKDOzezDw6PJSSlDw+PKSelNzOvLymhAwODNzGrOTStLyqjExKRHRqZLymfMTCvMS+tMS6rLyynMS6pOTOpLyifMTCtMS+rMS2pMSynLyidLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfPgACCAAECA4aIA4OLAgSOBQQGAgcBi4KNCAmaCgsJDAKWjQkNCA4JDxCeEYwSDQ4TFKMPCxUWAA0BEQ0GDggQDxcIBBgZthobExwICB0eFRsSHcOrER8QCwYIIA8bIRwiIyS2JSYVHgsQzhsbJygEJKsl6ykeH9zrJyIq4gAp6xsrWLT45+IFChi2YqwLwcLEvxgHZMygsarBOgsCBGioUcNGxBk3bA0SgCOHjh0oeczo4WPVoAA/fgAJIoQGjSFEiIgUNCCCBZ8Wggq14CcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nreadme-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3Ly2rJyanDROXHSSpISetPz+/Nzm7GxqbGyGnMTS3MzW3JyuvERujLzG1HRydMzOzPT29DQyNMze5Iy2zLTS3Cx+pCRijLS+zIyKhGxubERCRFR6lGSivFyavISuxAxajBRejAxGdDxihJyyvCR6pBRqnAxelAxOfPTu5OTi3IyqvFSOtJy+1IyyzFxyhOzm3LyqlGySrAxejAQ6ZFxqfMzKxPTq3Ozi1LyulCxulAQuVISKjMzGvPTm1OzezLyqjBwmLBROdExOTKSinNTOvOzexBQeLAw2XAQmTCwyPLy2pOzaxOTWxLyedCQmJAQKFAQWJKSalOzavOzWvOTOpLymhKyqpMS+rOTStMSulLymfLyidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfVgACCAAGFhoaDiQECjIwDAQQBiYIFBgcImAkKCJGJCwwNDg8QmBESEwQUgg4VFhcYGBkaCBsRHB2qHgwfIAghIiMkAhMCAxsUJSYhJygiKc4qCysrLAPILS4oLwgwKcExEisyMxQFNBg1Nb7ONjc4OTo7yAU8IiIIDiIqPT4/QEFCVA0hooJBAg0eehQxciQIEnKCktiYqGQJEwJNnCB5AkWVoChSpkwpQmXAkypWrmDxKAhSlixaTlrZcqWjIi0/BmjhsgNLFy82BwWgQDQK0aNE/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nrecycled-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3Ly2rJyanGRmZKyqrMTGxPz+/Ozq7KSinOTi3LzatLTGpJSSlMzKzGxubMzWzPT29DQyNMS+rOTy5KzWlEymLDSSDKTClIyKjGxqbERCRGx+bNzu1Hy+ZESeHDSWDCyKDCyGFMTKxHx6fOTi5ISCfFRuVKzGnJzKjDSOFJy2lNTSzJSSjPTy7Ozm3FR6RJzChGSqRFSePHyqdMzOzLSytNTOvLyulExyREyWPESSJMS+vKyurMzKxPTq3Ozi1BxeDDSCHNTS1Ly+vHx+dIyOfPTm1OzezLyqjBw6FBxmDFSKRMzGxERONOzavBQ6DBROBHSOdCxeLDRCJKSelOzexOzWvLymfCw6LBxGHFRiTOTOpERGRKyqpMy+rLyedMTCtLy2pMSynMSulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfWgACCAAGFhoaDiQECjIwDAQQBiYIFBgcImAkFCJGJCgsMDQ4PmBAREgQTghQVFhcYGZYIGhAbHKodHh8gISIjJCUCEiYDJxMoKSogGCsjLC0GLgkvMAMTMTIzIjQ1LDYHNxo4CTA5Ezo7PDstEQ8HPT4nP0BB5jpCQxFE7kU3RkcHkCRRomoJkyYHnBQZ0OEJARxJoBAUFEWKjilUolSxMiDJFSxZVAnSEmVLFC4EBnzE0iVkIi8EvnwBs5JlGJGCAogRQ2EMmTJZsoS5qWiC0aNIJ/gJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nresource-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRSVFxaXFxeXFRWVOTi3NzW1Nze3Ly2rJyanPz+/Ozq7GxqbMzOzDQyNHRydExKRERGRExKTERCRCQiJIyKjCwuLGxubDw+PDw6PDQ2NBweHAQCBPT29IyKhNz+3HzmfDTCNASaBBxaHCQmJPz69PTu5JTqlGTOZCSmJAR+BBxSHOzm3LyqlFTKVASCBARmBBxGHNTSzPTq3Ozi1MSynAyeDAROBCQ+JBQSFNTOxPTm1OzezLyqjCwuNAQyBCQ2JMzGtOzexAwODOzaxOzWvLymhMzCrOTOpNTKvMS+rLyifMTCtLyulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfcgACCAAECAwQCiIiDjAMFBgeRCAMJAYyCAQUKmwoLDAoJA5eZnJsMDaAOAA8BEBESExETFAsVDwwTFgAXAhgOGBkaGhscHQUIHqoDAR8gISIjJBQGJSbHugMSJygpKisU0x0mLC2qAhEuKS8wMRsbMiYzNDW6ARM26zc4ORQ6Mzs8evgAACGDChg3fgDhF6SAECE9VEXQYKGiDwtDKAQRQqSIEV25KGzIQZIDhSNFiiAxomoQAwM6kgRRgiQlkiW6BgVIwkQJghpNeixx4qQlJiAWHCh1kFSpBT+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrpm-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/FRaVNze3Ly2tJyanFRSVOTi3PT29Pz+/Ozq7GxqbFxaXHRydNzazDQyNIyKjERCRGRmZExOTLyipOSytLy6vIyCfBweHMzOzNS+vMRqZMRSTNzGxAQCBLxCPMzGvLyulCQmJPz69IxKRIwWFLSGfLyynAwODERGRMTGxGRiXLyqjHR6dIyOjBQWFLSqnNTCpNTKtLyidPTm1OzezOzavOzWvOTOpMTCtMy+rMSynLymfLyedAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAazQIAQECgajcNkQMBkDgKEQFJYMBwQ2ITiEJ0uDFjsgdHgOpIFQRj7UCggZyEksIgoJBPKwVCxnBUXEgwYBgkGGRobHAYDDgUdFx1fawceHh8gDiEdnEthIgcjJCUmDh0nKJwdCCmcKh0WJiumQh0sFR0tFyYuLycwK5u1nBYsFwMuJicTs0MdEhUpDRkxMRkwMDJxQl8zBjM0NTY3N9poKTg5JjorKzsyPNtEDvT19CH0fkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nshellscript2-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3LyypJyanPz+/Ozq7GxqbPT29HRydMzOzPz69DQyNHRaJKyONJR2LJyCJKyCHKSCHMSqZNTOvIyKjGxubERCRGxSFIxyRKR+HMyeHOTCLMSOHLyWFMzGtIyKhHx2bKSGZNyiFHxeDOTi3Ly2rMyudOTCpOTKxLyqjJR2VJxuDLSGHLSunPTu5Ozm3LyulJx6NNSyXOTCjOzWvPzi3MyqhGxSLFQ2DLSKLNSqTPTWtPzq7NS2nIxyVIx6ZOzezFxCFOy2POSyROTGlPTazPTWxLSiZLSSVMy+rOzaxKyCJMyeNOSyTNy+dLymXLyePNyqPKSWfOTStLymfKR6HMyaPMyaNJR6TMy6pFxKLHxWFKR2FIxiDOTOpLyedMTCtIyCbMSulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfQgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFkZOVlwgJCgsEDIINDg8QERITFAUVFgcXpYIYGRobHB0eHwgCAyC0giEiIg8bIyQCCCUmtCInKCkpKissLS4vMDGlMjM0NQsINjc4OQ0U26U6OzQ8CAg9Pj8uQBRBKgxCQ0QzRUY2jiDRkURJkCX5ADBp4uQJjRNQokhpMSUIlSqlcFjpQOQKESlYWmTRQuUirS1cumy04qWBlhpUvoARRihMGDFaBoxRUQXMTEUMggodysBPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nshellscript-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRWVFxaXNza3OTi3Nze3Ly2tJyanPz+/Ozq7GxubNzSxMzOzMTGxHRybDQyNLy+vHRydHx6fKSipISChIyKjGxqbERCRCwuLLy6vGRiZExKTCQiJAwKDLSytLy2rJSSlHx+fDw6PKyqrBQWFPTu5Ozm3LyulLS2tCQmJAQCBPTq3Ozi1MSynCwqLAQGBOTazOzizOzezLyqjBweHNzSvOzaxKyurHRuZNzOtLymhDw+PIyCdOzWvOTOpLyidNzKtOTStLyifMTCtMS+rLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfZgACCAAEChYeGg4oCAwQFjgYBBwGKggEECJkICQoIkwADCwwNDY2mDA4Lng8QDhESsLARExQVDhYXGBkWExIaGw8cHR4SCQQfFQ8eFgUgIQEiwiMSBMYfGB4atwEXDyQd0wQlJicPKAHoFyIpJCoeDgMrLC0YKBsX6i4kL+4OMDEyZijr5oLGNxUqUCioEcPGDAwjPNyI6MEDChQjcOSwsUDHgw07RIgI4KCkAgs8cvTw8eOBogAxQtXIASTISiEuBwUYMoRIixYnZggpUgTDywdIkWJIitRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsound-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXFRWVExSVNze3Ozi1Ly2rJSWlPz+/Gx6dNTS1Ozq7GxubGxqbDRmbDQyNFRiXBy6xFRmZLy6vIyKjERCRAQ+RBy2xByqtHRydIyOjPT29PTy9OTi3ISGhAQ2PATC1ByGlPz6/MS2pAS2xHS2vMTCxJyenLS2tPTq3Ozm3LSmnAQaHARibARudAR2hEySnOTm5MzGvLyulARKTARWXDyCjOzaxAQiJEx+hNza3MzCtOzexOzavLymhBQuNCxqdLy+vKSelOzWvLymfDxOVISipAQCBNzOtOTOpFRybKSejMS6pOTStLyedMS+rAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfLgACCAAEChYeGg4oDBAUEjwYBBwGKggEICQkKCAsMCJOVAw0OA4wIDZsHD4oQERINDRMIFA0MFauCFhcYARkJGhscHRMeuB8RICEQHgcaBCIcBSOrHyTWJSYnKB4KHCkqK6ssLS4vMA0LMRoyKe0zuDQ1LTYoHBwU7Ck374M4NTkmdHDIsKMAjx4+cAn6ASSIAhRCdvDgMYSIQkJFjBzJsALJjSFJLCoSUKCIkiVMegxpksTJxQATnjwZMWMGER9OXI58wLOnzwd+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsource_c-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMTCtPT29GxubMzOzPz69DQyNHRydERCROTi3IyKhIyOjPzy7PTu5Ozm3LyqjPz29PTq3Ozi1LyqlPTm1OzizOzWvLymhGxudGRmdFxedFRWdERKdDQ+dHR2dFxidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJQC8BXxOEDOw0DkGhYMJHCq4FuYJBQUEQN5RGlWYBQVFheEVWEYFRkaG40RXw2JGX6MaIiRHGCccQKAkRodHh4fjQ+tICEiIyQkJY0mJg8FJwWzJbVKD7gnI7K+v3EOycrLDn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsource_cpp-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMTCtPT29GxubMzOzPz69DQyNHR2bERCROTi3IyKhIyOjPTy7Pz29PTq3Ozm3LyqlPTu5Ozi1LyulPzy7LyqjPTm1OzizOzWvLymhHRydHR2ZHR2XHRyTHRyRHRyPHR2dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJQC8BXxOEDOw0DkGhYMJHCq4FuYJBQUEQN5RGlWYBUWFxiEVWEVGRYaG40RXw0ckV8djYaZFh5gnGgKnx4fICAhjSIPrSMkJCUmJ6woBQ8FJAUlJ7VKDygPD7G9vo0OycrLDn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsource_f-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMTCtPT29GxubMzOzPz69DQyNGR2ZERCROTi3IyKhIyOjPTy7PTm1LyqlPzy7PTq3LyulLyqjPTu5OzexOzWvLymhHRydHR2bFx2XFx2VFR2TEx2RHR2dFR2VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJQC8BXxOEDOw0DkGo4MJHCq4FuYJBQUdnlEaVZgCgYVFoNVYRcYGBEZjBFfDRePEgkajIUXGxgVYJxoCp+hHBwdHowfIK4PDyEiIyStJSUFDwUmJiS2Sq8PILG+v4wOycrLDn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsource-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMS+rPT29GxubMzOzPz69DQyNMTCtHRydERCROTi3IyKhIyOjPzy7PTu5Ozm3LyqjPz29PTq3Ozi1MSynPz27PTm1OzizOzaxOzWvLymhLyifOzexLyedLymfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaJQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJSCx7WAgBwi52FAsi4oBINJnCpAqCkPChUSA3tEEmoFahUWFxiGSwphGRYaGxyQEn4NHZVfj2iLlR5qoHICGYyWHyAhIpB9Dxp+IYAjsGokaiFqJZAJDwkDHBwYJiW+Sg7LzM0OfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsource_h-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxubPT29IyKjMTCtMzOzDQyNHRydERCROTi3IyChIyOjPzy7Pz27PTu5Ozm3LyulPz29PTq3Ozi1Pz69LymhOzizLyqjPTm1OzWvIyGhIR6dIRubIRmZHxaVHxSTHxCPIRydIReXHxWVHxKRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaIQIAQECgajcNkQMBkDgKEQFK4LFgLhgMiOl0mFFbEYVEgMJQC8DXRODjOw8DjGhYMIHCq4FuIKBASDwN5RGlWYBMUFRaEVWEXFBgZjEoPXxoSkX4bjYaZGBxgHZ2AkR4cHx+cSiAJCRAhIiMkJSaNCREgBScFKCkqtkq4sLK0JsFxDMrLzAx+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsource_java-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRWVFxaXNza3OTi3Nze3Ly2tJyanPz+/Ozq7GxubFRWXHRydMzOzDQyLIyKjGxqbERCRCwuLHx6dKSinKymnLyyrNza1PTy9Ly2rIyKhDQyNGReXKyejKSWhIx+bJSCdIRuZCQiJISCfGxaPJSKdHxuVHReRHxiVHxeVGRGPKSajMS+tMSynAQCBFxeXGROLFxCLFxCNFw6LGxiXFxiZMTCtOzi1ERGRLSytJSWlERKTNzSxOzaxKymlOTi5JSSjISChBwaFNzGrLyqjKSmpDw+PMS+rOTStLyqlLyifGRmZKyqpLyidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfWgACCAAEChYeGg4oCAwQFjgYBBwGKggEECJkICQoIk5ULmJoIDA2eDoqXowgPDBAREoIRExQVFhYEBA0XGBkaGwAcHR4dHx4gIRMGDBcEFg4iIyQlJicoISkqISssBC0OLi8lMDAxMiozNDUUNjctEjg5OjklDCEcOy4OFDw9Pg4QfuQAEgTCDglCHAQYMaQHEVRFBhRhIACHAyMLIHg4guShIAg6KDwYMYHBhBVJhiBRgmrQkhxMKlBo0ULlkCYtLbGwYYNmCyJNguYk5KBoUQlGi/oJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsource_l-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMTCtPT29GxubMzOzPz69DQyNHRydERCROTi3IyKhIyOjPzy7PTu5Ozm3LyqjPz29PTq3Ozi1LyqlPTm1OzizOzWvLymhGxudGRmdFxedFRWdERKdDQ+dHR2dFxidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJQC8BXxOEDOw0DkGhYMJHCq4FuYJBQUEQN5RGlWYBQVFheEVWEYFRkaG40RXw2JGX6MaIiRHGCccQKAkRodHh4fjQ+tICEiIyQkJY0mJg8FJwWzJbVKD7gnI7K+v3EOycrLDn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsource_moc-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIQAAPz+BKSipISChERCBPz+/AQCBMTC/MTCxISC/FxaXDQyNASChARCRPzCxAQC/PzerMRaBPyCBPyqXISCBPwC/MQCxIQChATCxMT+xATCBASCBIQCBARCBPwCBMQCBMTCBCH5BAEAAAAALAAAAAAQABAAAAWOICACQRkI6DCuJOG+JysGL1wIMm0YNHEUBNwqsDMgEL5AIqEYIhZPxqtwUI0CzwRDSih4E6KGeLl1vB4FMAASkTC1icmjmxZBKBXL4YLJaAoPgWoQEBsbGX4JHHR1Ih0eChkTGoqADQ9qMwR+GhwcXlSZAAJzDQNogZeiAUBeaAcNHw2iAygocQkCuQN+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsource_o-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMTCtPT29GxubMzOzPz69DQyNGR2ZERCROTi3IyKhIyOjPTy7PTm1LyqlPzy7PTq3LyulLyqjPTu5OzexOzWvLymhHRydHR2bFx2XFx2VFR2TEx2RHR2dFR2VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJQC8BXxOEDOw0DkGo4MJHCq4FuYJBQUdnlEaVZgCgYVFoNVYRcYGBEZjBFfDRePEgkajIUXGxgVYJxoCp+hHBwdHowfIK4PDyEiIyStJSUFDwUmJiS2Sq8PILG+v4wOycrLDn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsource_p-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxDQyNPz+/FxaXKSipPz+xPzerISChATCBARCBASCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARVEEgQqrUz3yqGCJlUESRZEFVooWZAfJpbEkU9gNMqo4KBi7vSAfWjyFxIUnEkJAwPy9EugEDFSE+nMzojVKvLREGsKCgWjMVybDaj0eH2OZ2Objb+CAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsource_pl-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMS+rPT29GxubMzOzPz69DQyNMTCtHRydERCROTi3IyKhIyOjPzy7PTu5Ozm3LyqjPz29PTq3Ozi1MSynPz27PTm1OzizOzaxOzWvLymhLyifOzexLyedLymfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaJQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJSCx7WAgBwi52FAsi4oBINJnCpAqCkPChUSA3tEEmoFahUWFxiGSwphGRYaGxyQEn4NHZVfj2iLlR5qoHICGYyWHyAhIpB9Dxp+IYAjsGokaiFqJZAJDwkDHBwYJiW+Sg7LzM0OfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsource_py-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNza1Nze3Ly2rJyanPz+/Ozq7GxqbPz6/NTSzDQyNKSujIyKhHRydERCRGR2PHyaLLzObIyqNKzCZIymRKy6jPTy7OTi3ISChFx+HISaNKyuPJyaBKTCRKS+VISiVGyKJHSGPLzWdKS+TMzefISCJHRiBGySJJSyNLTGbKzKRHSaHJSWhLyulHSKNJy6RKzCXISWRLTOZJSuVIyuJGyOHHyWLOzaxJSqTGyGJJSmXHySPJS+JHSOHIy2JHR2XLyqlERaHGSGHFRqJHSOJGR+JFxmPNTOxIySbHyORHSWJPTm1ISiHHyiJFRuHMSqjPTu5OzexFx6LMTCtMS+rJyidISqJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfKgACCAAGFhoaDiQECAwMCAgQBBQGJggEDBpkGBwgJk5WXmgYJCAqeC4kFAwysCQYNDggPqIMQERITFBUWFxgEGagaGhsVHB0eH8ggvQQLISIjJCUmJygpKissLRcuCy8wMSMqMhszMzQ1Njc43QA5Njo0Ozw9Pig/LCxAQbRCOkM2iBQxgsLGjyJH+CXKoEABkiRKWCxhQYQBLUsYLhxgwkRJEydPoFwkhCEKRylKbNSYIlIRASpVCFj5UeMKhJaDAizYybPnAj+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsource_s-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbIyKjMTCtPT29GxubMzOzPz69DQyNHRydERCROTi3IyKhIyOjPzy7PTu5Ozm3LyqjPz29PTq3Ozi1LyqlPTm1OzizOzWvLymhGxudGRmdFxedFRWdERKdDQ+dHR2dFxidAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaHQIAQECgajcNkQMBkDgKEQFK4LFgLhkMhOl0iElbFgtEgOJQC8BXxOEDOw0DkGhYMJHCq4FuYJBQUEQN5RGlWYBQVFheEVWEYFRkaG40RXw2JGX6MaIiRHGCccQKAkRodHh4fjQ+tICEiIyQkJY0mJg8FJwWzJbVKD7gnI7K+v3EOycrLDn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsource_y-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxubPT29IyKjMTCtMzOzDQyNHRydERCROTi3IyChIyOjPzy7Pz27PTu5Ozm3LyulPz29PTq3Ozi1Pz69LymhOzizLyqjPTm1OzWvIyGhIR6dIRubIRmZHxaVHxSTHxCPIRydIReXHxWVHxKRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaIQIAQECgajcNkQMBkDgKEQFK4LFgLhgMiOl0mFFbEYVEgMJQC8DXRODjOw8DjGhYMIHCq4FuIKBASDwN5RGlWYBMUFRaEVWEXFBgZjEoPXxoSkX4bjYaZGBxgHZ2AkR4cHx+cSiAJCRAhIiMkJSaNCREgBScFKCkqtkq4sLK0JsFxDMrLzAx+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntar-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaXNze3Ly2tJyanPz+/Ozq7GxqbJySbJyadPT29Pz69GxubMzOzDQyNPz21LSujPz25OzmxNTS1IyKhERCRKyqjLy2rKSehPz67Pz23OzerKSaZMzGxPTy7PTqvOzirMy+dKyeTIR2NPTq3LyubLyqVJySPHxyJOzi1LyunPTqzOzW5OzSzNzOrJSGNGxiNLy2pPTm1OzezLyqjJSKZOTStOzOxNzGtOTSjKSSRIR+LGReHLyynOzexLymhOTWlNzOhFxSFHRuRNzKfNTGdHxuLGxeJIyCbMy6pLyifLyqlNS+pOTOpLyedHRydJySfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfLgACCAAGFhoaDiQECjIwDAQQBiYKLBZYFBgcFkZMICAkICgULDA0LBA6Cnw8QERKgExQHDBWpCBAQFrm4EAkKAhcUqRgRGRqsGxIbHB0eAgOpCRofCw8WICEiIwMkJBDRCwsgICUmIico3CkqtissLS7mJy8wMTIzNKk1Njc4OSI6Xuzg0WOGjx/6gOQIEkTHiB0ohKjwYQOhoCEliBQxcuQIDCRJbNhQkmoQRhgflzAR2cRJSUFPekDpQbMHjR9OXCpywLOnTwd+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntex-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxDQyNPz+/FxaXAQChKSipPz+xPzerAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARgEEgQqrUz3yqGCJlUESRZEFU4lkQREJ/2skU9BEaezzmRCwccwDCc+XwIFGhI0ZEMxiURxzIQkghp0+qjJlDDHdRnQPSyGu4oEfguRTrs9fqmWAjfPHpSkWMReyIbg34RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntgz-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBIQChFxaXMQCxNze3Ly2tJyanPzC/Pz+/OTi3GxubJySbJyWbPT29MzOzPz69DQyNPz21LSujPz67OzmxJyadNTS1IyKjGxqbERCRKyqjLymhLy2rIyKhKSehPz23Pz+9OTevOzmtKSaZMzGxPTu5PTqzMy+dKyeTIR2NPTq3LyulOzirLyubLyqVJySPHxyJOzi1OzW5OzOxNzOrJSGNHRmJOzezJSKZOTSjGReHLyunOzaxOTWlNzOhKSSRIR+LFxSFLyynOzWvHRuRNzKfNTGdGxeJGxiNIyCbMy6pNS+pNzSrAQCBHRydLSunMSynAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfYgACCAQKFhoaCiQOEBI2NBQIGAooHjAiXCAkKCJIAAZ8BCwsMCw2XCg4PBhCCohESExQVCxYXChgZrAsSvBIaGxIbDA0JHB2sHh8gHx8SISIiIyQlBBysFR8mzBIiJygpBSUqK9cPEywiLS4oLzAFKjHkAAwmMjM06y81NgUmNxuscNCYQSIHuxopdOy4wQMgABw9cvjw8SMFEBhBhPAY4hAAkRZFjKQ4cgRJEiWgAiTy2AKJSSFLmAQ4MKDJSidPFggRAmXFhgADNthMJACC0aMQAjRZ6icQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntxt-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaVPzKjMR6RNze3Ly2tJyanPyODPz+/Ozq7GxqbPyKBPyGDPzGjPT29HRydMzOzDQuJOx6BPyGBPyKDOTWzIyKjERGRDQyNKROBOR2BOzezIyKhBwOBKRKBNSOXOza1CQOBPyCDOySZPzizPTWxPTy7Pz69Pz29PTq3LyqlMxmJNRyROy2lPTu5OTi3MSulFxGNIRWLMR+XPTKrOzStPTm3IRSNOzizOzavLymhLSyrEw6LKRuVIx6ZNzSvOzexNzWxNzW1FROTBwaFKSShOzWvOTOpOTazJyWjHRqXNzKrOTStLyifMS+vMS+rMS6pLymfLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfOgACCAAGFhoaDAgOCAQSOjgUBBgGCB4qEBAiaCAkKCJMACwwNA42bCA4PEA4GERITFKQVpwgWDwoXGBkaE6MDG6cOBAUcGB0eGgsTDR8gmw4OGwURACHIIiMkJSYIJygpKSoYgtYrLC0kLdAuKS8w1IIdMTIzNDUbLjYpG+KDABcRbtRrYWMDjhw6xg0KsCMAjx4+fmwAEiShvwBCChgYQqSIkRpHdMBjZCIFkh1JlCxhcqSJQkZOnjyBAgOGjihSpLwkhAFDBJ9Ae0bwEwgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nunknown-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXIyKjNTW1Nze3LS2tJyanER2RGS+VPz+/PTu5GxqbPz69BQ6BCxeLFSqRPT29HRydMzOzDQyNERmPKSypCRWHIyKhERCRDyGPKz2nESiLBxGHCyCHGxubPz6/PTy7Ozi1Ly2rKSipOzm3LyqlKSWhCRyFOzizLymhNTKtNzOvOzaxOTStPz27OzWvOTOpLSupLyedMS+rMS6pMSulLyqjLymfLyifAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAamQIAQECgajcOkYEBoDgoBQyAJOCCuiENCsWBIh9aGw9F4HCARiXciRDQoBUnlYRlcIgsMG5CxXAgMGhscBRAEBRd7AB0eBBoIgxUfICEiikSPgyMMIAokJZcBkBybJgomIaBJAZoMpyCmqkMBFCcVCrgKKAwpoSorKqchKCwtvasIFBIhLiYvLzDHsxQNMcMKLDAwMqEz3jQ1NTY3ONyrE+jp6hN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nvcalendar-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXDQyNAQCBMTCxPz+/ISChAQChKSipAQC/Pz+xPzerPyqXMRaBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARyEEgQahVijMmD/oRAbBw1FCgaFFrpEbB6jt1g3OpFAscxwATUiIAgBRKJXiqIYJEMBQNSWSAYgptrMDo9FJqKrHArTR4WLGisSkbebE12gXFFGRBFyd3eaFSvbx1xCDBXC2E1e1EECo07ABkaBh4fGn4RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nvcard-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXDQyNAQCBMTCxPz+/ISChKSipISC/ERCBMTC/Pz+xPzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARvEEgQahVijMmD/oRAbBw1FCgaFFrppeo5drKhXqQUEIfREyweqWIoHo4GDYtkGxwQ0CjitEkUrCyfYjtdbJoFW/agmLJWWZSY3B0EbGJ4uAwcHlK2HpTg7YgHBgQjDH0THoGBCwULjDkAGR+RH34RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nvideo-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaTFxaXIxuHJyCLHx6ZLy6vJSSlNze3Ly2rMy2RNS+TKyqrMzKzPz+/Ozq7GxubJyanLSePKySNKSSPNTS1JSWlDQyNMSqPLSmVNzKZJyenIyKjHRydGxqbERCROTWXNS6XOzidNzOZPT29MS6rISChLSulMy2TLyeNKSOPJyCPOTi3JSSfHxiFGxaJFxWLFROLPTu5Ozm3ISCdDw2BFRKHHxqPFxWPLymTMzCvPTq3OzezKSWTMzCbNzGZExKNHx6dLyqjMy6XMSqTMSmTEQ+JHRybMSynISCbMyyVOTWbLy2ZBQWFGxqZOzifDw6LCwiDISCZJR6LIRqJBwWDExKRHRuXHxmJGxeJFxSHCQiFFRGFGRSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfhgACCAAECAoWHhoMDBAUGBwiRkQkCBwGCCgsLBQwNDp8ODxAOEQIAChITFJwVoA4QnhYXEhgZBRoFG62fHB0eHxcgIQUiIyO5uyQIJSYXJwUoKSoUKwEWniQkLCUXHy0DLi8vMDEfBw0kMjMnFwAfNDU2Nzc4OTgmOjs87ILvEj04NPj4ASRICR5C2vVrEWAIEQwSihg5giThIHdJiCgJMWIJkyZOLA4K8CHJkycimEAJEcWJQkECEHyQEqIHFAJTqFSxcjGAjhIfrlzAkkWLDS1bel5Y+mELly5YCEyQ4CcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwordprocessing-16:mimetypes mimetypes16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFRSVFxaXFxWTNze3Ly2rJyanPz+/Ozq7GxqbHR2dHRydGRmZERGRMzOzCwqLJyWjOzi1Oze1PTm1PTm3IyKjDQyNERCPPTy7HRmXCwqJPT29DQ2NNTGnOzm3PTq3CQqJMS2hDQuLKyaXCQmHBwaHKyahLSijKyehBQaFCQiHHRqNPTu5LyulCwuLHxyNAQGBBQSFERCRBweHOzezIyCVJSSfOzavLyqjOzexOzWvLymhExGJEQ+JExCJExGLCwqHOTOpDw6POTStLyifMTCtMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfWgACCAAECAwIChYeDjAIEj48FAgYBjIIBBAeaBwgJBwYDjAoLDIkNmgsOnw+CEBESExQSEgsHFQsJDRYAFxWbmhgZGhsEBRUcHQ8cEB4fzhAWICEYxSIjJCUDJicnKBkpKissFC0uLwAwMDEyFzHpDxgfES27DyozMyX6+TMTEzQtWJWoIYGgQRsl/t3AsStFQRoGIYrIkUPHDhcANPDo0cMHxx9AUtzQEWQHKwAcSDy4IAQbh5FDghDZNShAkZsFjBzBgaQnh0YcHojgIMIFBwtBXfgJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n1downarrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBBQSFAQGBDQyNExKTHx6fGxqbFxeXGRiZFRWVDw+PAwKDJSWlOzu7LSytJyenJSSlISGhISChIyOjFxaXDw6PPz+/MTCxLS2tIyKjKSmpKSipJyanAwODDQ2NHRydERCRFRSVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZzQIBwSCwaj8ikcslsOp/OgHRKlQoCgymRUDAcEIkwYgxWFBYERpHQcDwgEclEQmk8DhWL2kiIXDBwExMNGRoJaUkEEH8bEQ0cGgcWAksEHX8QHBKSHk1sfxMHH5ROBBsOICGkT2wiq1CIULKztLW2t0h2QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n1leftarrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExKTJSSlHx6fAQGBOzu7GxqbJyenPz+/LSytFxaXMTCxGRiZKSmpISGhFxeXISChAwKDFRWVHRydJSWlBQSFERCRIyKjDQ2NIyOjLS2tDw6PBwaHFRSVDw+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZ5QIBwSCwaj8ikchgQLJGBgfNZDBAKBirRekBMtYGEYsHIgsWNhOO7tCrShDU18Hg/CJAIG0o4wCUQcksTFBUSCRYSEnpUFxgIGQkJGYyNGggbHBaVjR2QCxEeWkITHQ4IH3tPFwEMA2ajAKUgqlQTTbFEE7W5vUgGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n1rightarrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNGReZAQCBMTCxGRiZMzGzOTm5LSytPTy9Pz+/CwqLOTi5Ly6vCwmLMzKzJyanJSSlBQWFKymrIyGjCQeJJyWnISChISGhHx2fKyurDw6PAwODHx6fHRydDw2PERCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZ2QIBwSCwaj8hkMRBQKgOCgRMZIBSk06XhEM0SA4iE4uoVLhCMhqLrdSAekMgYO5VM4BQ521mxIC4UFxBWdEkSERYYFxETGQGFSBKCGBEaGRuQSBwdeZaPXpsQCB6YZQMdEI6ZSgMepKusHh+wrCC0rLdlursGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n1uparrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBFxeXDw+PMTGxHRudPz+/JSSlLSytIyKjHR2dISChIyGjIyOjLSutLy6vKSepJyanISGhJSOlOzm7Ozu7MzGzKyurJyenDQyNGReZKSmpIR+hCwuLCQiJBwaHBQSFAwKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZtQIBwSCwaj8ikcslsOp9QYyAQFQYEAyr0Sihkn1fDAeHVLsOJNELxVaITC0bDUU6GH5AIQ8KYrNtFVxQVFBYWFxgRCREYdUQZGhYEDwgIGxAHCQocCgWOQhmhGR0epR8gqCFTq1Wtrq+wsUt0QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n2downarrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAQGBBwaHDQyNExKTHx6fGxqbFxeXGRiZFRSVDw+PAwKDJSWlOzu7LSytJyenJSSlISGhISChIyOjFRWVDw6PPz+/MTCxLS2tGRmZDQ2NAwODJyanKSmpKSipIyKjHRydBQSFERCRExOTFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAasQIBwSCwah4FkQKBsDpoBIqFgOCASCYRWm1AUFgRGkdBwPCARiWRCaTwOFYvYSIhcMOiJpJGZaDYcR0IEHXceEQ0fICEWIoJDhHcQHxIHgI9SEHeVG46YUh8OISOen1INCqWmUnOYTUxQAU9NUlRWWFtbCiRgrYNlZ2lriG8lYUd1khETE24gCZeCkRgeFBAQIAeNn9OTlXKrBJoYnKrcoaPmpmSpq3S+7u50QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n2leftarrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExKTJSSlHx6fAQGBOzu7GxqbJyenPz+/LSytFxaXMTCxGRiZKSmpISGhFxeXISChAwKDFRWVHRydJSWlBQSFERCRIyKjDQ2NIyOjLS2tDw6PBwaHFRSVDw+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAavQIBwSCwaj8gkMiBYNpeDZzEQXRIKBmPgmtUSDgipcAsWjxOKBaN7Tq+n6EbCIQ3E5+KtQk6gjwl7CX11D3sPBBARTQGFDYeJT2R8EhB0koKUfgATFBUSCRYSEoqcnqCiikMXGAgZCQkZqautr7FiFxoIGxwWqQC4ury+qh2tCxEexMbIRhMdDggfYs7Q0kcXAQwDbELY2txEziBmmx3jSRNMR+nk4e2b70ry80QGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n2rightarrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNFxeXAQCBMTGxOzm7CwqLLy2vPTy9Pz+/Ly6vCQiJLSytLS2tLSutOTi5MzGzKSepIyKjJSOlKSmpMzKzJyanIyOjBwaHIyGjISGhJSSlISChBQSFJyenIR+hGxubDw+PHRydHR2dEQ+RHx6fERCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa6QIBwSCwaj8hkIIBcJgEBweAYnTYJUmMAa9USClniFtwlGg6IRFhoUKTXwwWj0FB3F46Hwl6UQyISfAB+EROCQgsUFRYSF3yJEIyBaxgWDBkaGRtclQwSHBIbEGEdGx4fGhcOICEDGBsWHBmqIq1CHRIWGRMMIyRTHRy6Er22tyONq8YdJRe0xkIDwr2/QwMfliMmZQADIxasZd4e4UYDIr7c59rc0eVFA+/m0EQD9PDt0flP/P3+BkEAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\n2uparrow-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBGReZDQyNMTCxHx6fPz+/JyWnKyurHx2fDw6PJSSlISGhIyKjIyGjISChLy6vJyanOTm5PTy9OTi5MzKzLSytKSepMTGxMzGzLS2tLSutKymrHRydCQiJCwmLBwWHAwODLy2vHx+fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAajQIBwSCwaj8RAAMkUBgSDZdP4JBSi06TAcEAkFNLp07BgLLzY5njRcDzO3zB1C4lEGI83Wj58SiYUFRUWdg0XEXFFAwIYGRoWGxwRZQUFHZdgRAObmx4fHiChISFKpVlKWUdPaalOAlasp1sHG4myZGZ7Yltsbgu1mUhjdRF5egmxfQJ/gYOFdrZDi40iFgiSCw8jBQmYcpydn6Ego6WorUwGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nabs-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAWABYAAAJLhI+pF+vW4HMR1InqxbJzBiLCeIxCaIkneQJk6rkl+2qlONzeNi+2YvKhEIOW4iczvJSoSDDIbCpbq2oGBXUtd59r7IPshsHdB70AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nairbrush-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAASC/AQCBPyChMwCBIQCBPz+/MzKzKyqrISChDQyNPwCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAR8EMhJKw3BahvEyNvWDV+ojQMBAhgmeukaFHSxTqh6FYZx3CyYbtf7XYRAFs8nQ56WxiBpyOEdjLkkrnA9IAKGqXbnTYAP1NDMe0Z8JYR4nPP1seEqTHpWZMupVHx2by03Q4JXbxuBfYoaaVZ3i4YKbo4WaQAKBCxjcEAGEQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappearance-22:actions actions22 22:photo:22 22:R0lGODlhFwAWAIYAAPz+BAQCBBweHPTy7Ozq5ExKRPTu5NzStLy2lCQmJAQGBOTezNTKrLyylNTKpOzm3NzWvOzm1MTCpNzaxISuvBSGvLy+pKSehOTexISutKTa7IzS7GSarJTW9HTK7CyazBRypMzGpDw2LOTaxEyKpCSSxARGbERCROTizMS6nDx2jARajIR+bOzi1OTi1MzCnLy6lOSupNx6dGS2rJS6pMy+pOS2pNxGTKwaLDSmpHTOzES2tIyuhLSmjPyqrMw6RLSOhLzSrGyqbFSmXJSyhNTOtGTCvLzm5CyOjEQ+NPRqbOxOVKyKfMzizKzepFyuZJSqlBR6fCRmZJSKdDw6NLxqZLQiNIwyNLSejDSCRJzWnEyiVHySbBRiZDQyJMSijGS6ZHSCZJyafDRmPISKbJyifDw6LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAXABYAAAf/gACCg4SFhoYBAgGHjIQBAwQEBYwBlYiQAwYGi4UBBwcInIIJA6WRBAqdCwcMDA2pggEEDpUODwSiAAEQnwwHnI8RwBIGsLoLExQVFg4XiwEPD6IKGBjAExkaGxUcocfSgwHV1uITFR0eHyAhIroRERLAC/PVIxMkJSUgJvHH1RAKTixAgQzZhAkpVKwwwYKWrgnzFrRY4IIgBoMTRryQAGPjs4zzYsgYQdIgsgMzaNRw0CCBLgn2bNzAceMgSZITcujYwaNGj2sjcPjw8QNIECFDiEgoYuSIDiQOkoSTMAGHkiU4mAhp4uQJDyhRjOSQMiUXFQdVrOC4giWLFidbRri8QBKlyxQviIp8udKjRhYwYLKEedFAjJgvucI5cFBEgoMxkMm82PjFmCERix1wLCNmcg8viRGZ6aHZcQ8zoRtVWp16UCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nattach-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBMTCxPz+/DQyNKSipAQCBISChFxaXDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARrEMgJgqA4zzus/gLhFd5HCcZAXqsphYPUdhcYFNRcZnvdtpnDqPTbUWgAJKBYwzBlw+bRo3xmkNWoBgm0OrVLn3GC9RgCk8DhUw7c0rHPr4CDu5SYQNyEt7uSY3p/UAKFhYKDSQOLiwgFdhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nback-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRGZAxCZGyavExmjHyatOTy9CxihISevPz+/KzO3BRylAw+XAQCBDRWbPz6/FzC3CSuzDyexJzO5Mzq9CxSdAQOFISmxNzu9HTS5BSmxAyexDSuzJTa7Mzu9Kzi7GS21CRmjAQOHHSWtLze7AyWvHzG3BRihAQKFCTO3BS+1AyixBSWvBSOtBSStAQWJBSixDzW5BTC3BSqzBS21CTC1ETW3AQSHEze7BRqlBRmjAQCDBR+pBRefBRSdCH5BAEAAAAALAAAAAAWABYAAAalQIBwSCwaj8ikMqBcMpvHgGAANQYIhWdVGDAcENQtIJBQLBgNx0MQaDuQXcghIplQDhBIxXKJYiAZGhscHR4VHyAhIiNWJBklGhIbJoQnFCcTKIxFKSgbKissJi0mJi4vLiYoMEcXKDEyMzQ1Nje2NisoOEg4KDU5K6g6OwwoKAN9SCOeMmgwz884PEq9PT4NYkPLP9jZQikN3d4AKVrjKePp3gZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nblend-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQmJAQyNAQ6PARGRARSVARmZARubARuXARmTARiPAReLARaHARKBAROBAQCBERydESChESOjESanESmpESytES+vETKzETKtETCpES+lES2fESybESqXESiRAQ+PARiZARybASGhASWlASmpAS6tASynASqhASiZASaTASSNASKHAR+BARiBARydAR+fAS2tARKTDRaXARaXASOjASKdASCZAR+TAR2PARuJARqFAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa3QIBwSCwaj8ikcslcBp6CAaFQMBwOiIRiwWg4HA9hAAKJSCaUiuVywWQ0G07H4wkDxp8CKCQakUolJicoKSorLC12eHouL34lMIKEhoiKEFMgLn0kMIGDhSyVYhADjJuAkoWHiaMEMXuOnJ6Tq5alBpp+nSeflKx3l6a6s6CiwKWZm52pvpaue8rEzaPIubLMta2Mscu9ob8BMgIfBDPJNDQ1Njc4OTotDXYP8/T19vZN+fr7SXRBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nbookmark_add-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCwqLCQiJCQmJMTGxAQCBLy+vLSytERGRFRWVKyurKyqrLS2tKSmpHR2dJSWlKSipISGhGxubIyOjGxqbIyKjFxaXGRmZHx+fPz+NGRiZPz+ZPz+HMTCBKSiHPz+jFxeXPz+XPz+tPz+zPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAamQIBwSCwaj4Gj0hgQLJ+AAaEAVQoI06pRYDhkoYgwIhEgKBTfZ2FhaBsYDS8VWnA8Go0FJIKeqyUTDw8EDHBpSwUUFQ4UFhcYDQYFfkoFFxEQDG8KEAUZlEeWGBIakw4FG1STiBoYBRwdBR4fHgUdHKBEBSCnIR8iIyIfIblFu6ceIyQjtcXGCbLKzAUKzrq+wMLEVa+xs7W31kOTk6nkWuOf6Ea5QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nbookmark-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBCQmJCwqLMTGxAQCBBwaHMTCxLSytERGRFRWVLy+vKyqrKSmpHR2dJSSlJyanISGhGxubIyOjKyurGxqbFxeXGRmZHx+fKSipLy6vGRiZLS2tFRSVHRydJSWlHx6fCH5BAEAAAAALAAAAAAWABYAAAWWICCOZGmewamaQrq+wUC8azHINGocOI38iIRAceDNaISFYklkGHOEhoNBfUAOhuOLEJE8HoPiRKFdESiQBqViuTDIUAsEcyAeGJmyiqC5RCwJGg0YcEh9D0V3Dxt6JwQVDRYVHBUdi40mjw0PTgwQHgeYJQQJfxUXFxAOoTkFpQ0fsRSimQkWEQ0VtI62HLt7vjl7JQYhACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_all-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI+hI+pyw0Bo5wR0TttUJDv0yWhRopfaYzguaKt6aasrGFYbVPxM/O7Snv9WEAfTIgMKpNGWU63emYc1GrVUAAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_bottom-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIyhI+pyw3xIpwyOgOv1dvl+2lhMzIlyZ1KQLUVm8Zch4ozbcq6l7L+D4QhgsTf7Xi0FwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_fall-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI/hI+pyw3xIpwypgBRdg/v9h2eyBnZCIKYxX2oEsJruVKjHS8vk3duKZnpHKjeRSTU0HYpTcxWgRqB1KrVYC8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_horizontal-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIyhI+pyw3xIpwyOgOv1dvl+2lhMzIlyZ1KwLbuyybw7KY216Einpv377FRhhUV78igFwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_inside-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI7hI+pyw3xIgxTRvcg1oku3njbBx4liV3dqYbsSsXyLBr0Pad1iCovsmOwgjbdz9TrGHWWSeWZikoXhgIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_left-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI6hI+pyw0Rnox0ygNXdG9z43Xal30gUiYhk5LoenJQRVtti5FwE+Kx4+O9RrIda6gwDmvMi+kJjTIMBQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nborder_outline-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI8hI+pyw0Bo5ww0SttcKci/ymgMTZl+Yjbt3Jn26lautX0A+OizHJkjsrper7XbkZ0ATEYDZPii0qnU3sBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_remove-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIthI+pyw3xIpwyOgOv1dvl+2lhMzIlyZ1KQLUVm8Zch4ozbcq6F7s+fgsKb4YCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_right-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI7hI+pyw3xIpzyQRdVuIZj+3nHhogOiZng+I1qoqIdRVfbWy5y1u5M7MFphB1dsDULGXO15goJjUoRhgIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_top-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIyhI+pyw0Bo5ww0SvdCdrw7oGfNnZlczIpKorc+8RwZbZgXOc2uevOqpjJhrCb8QgwFAAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nborder_up-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI/hI+pyw3xIpwyOgNRyPq+zTkcuIQKaV3T1pgHinmfm7AUedMa64Vw3bLJMr9TiZcSFUsnkw54q0Rl1KrVYSgAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nborder_vertical-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI6hI+pyw3xIgxTRvcg1oku3njbBx4liV3dqYbsalFeJTp1iCovcjNsb9iZhMFcJwXUxTJLYuoJjR7sBQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nbottom-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRKZDRSbBxCXJTC1Mzi7Nzq9NTm9Bx2nAQCBNzu9JzG3Hy+1HzG3IzO5BRmjPz6/LTe7Dy61AyStCTC1FzC1AyGrETS3ETC1ETa5BRulAyuzBRylAw+XMTe7Gy+3CSqzAyexBTC3DR+nIS21KTW5Nzu/KzO3FzC3Pz+/ByixEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaXQIBwSCwaj8ikcnkMBAQDgjPAFAYKhsMBkVBUAYEFo+F4QLzVQEQyoVTOX/XBcsHA0+vMRbNBMwkRDhxuHX5GTlIeHh8gISIjFAEeiVRECiQlDAUmgxQjIhwiJHdFlycoKSIUFCEjGiGkRpcqCxYijxorsUezcxYsuoZJsxLAu0qXB7DCTJfHvArR0tPSSNTX1V/a20J2QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nbrace-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAWABYAAAJRhI+pGbHYVHzQnUnrtXn7/gEYIJRHKRgYZraGuXLp28LcNL/Dqd4cYmJYRqegsKcY5DRIUhHYFDlQJGMuVn1ljdhqjhoiZrogKbMjFh/LHUMBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nbrackets-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAWABYAAAJRhI+pyw0Bg3vxwImu0Zha2XkbaAjmYQrjh6qnCpwcB8evTGp1PKDrnzglZqTWDsg5DI5IUE1Yatpc0BrRFr2xfiljJlecXEPjDjG5iIRDCHsBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncentrejust-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIhhI+py+1vgpy0TogztlT7j3CiBJbZWJlqg4rry7jw/BoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncharset-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIIAAPwCBAQCBAQGBFxaXAwKDBQWFAAAAAAAACH5BAEAAAAALAAAAAAWABYAAANLCLrc/jDKuQK1zmKo3/YVJSpBSZYmKaTkAAwYoQwFELjvpisyaTM7H6AH+3lQMZQwExrOOiBh7/cJGokaXHGpQVaUo7B4TC6bw4AEACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncolorize-22:actions actions22 22:photo:22 22:R0lGODlhFwAWAIYAAPz+BAQCBBweHPTy7Ozq5ExKRPTu5NzStLy2lCQmJAQGBOTezNTKrLyylNTKpOzm3NzWvOzm1MTCpNzaxISuvBSGvLy+pKSehOTexISutKTa7IzS7GSarJTW9HTK7CyazBRypMzGpDw2LOTaxEyKpCSSxARGbERCROTizMS6nDx2jARajIR+bOzi1OTi1MzCnLy6lOSupNx6dGS2rJS6pMy+pOS2pNxGTKwaLDSmpHTOzES2tIyuhLSmjPyqrMw6RLSOhLzSrGyqbFSmXJSyhNTOtGTCvLzm5CyOjEQ+NPRqbOxOVKyKfMzizKzepFyuZJSqlBR6fCRmZJSKdDw6NLxqZLQiNIwyNLSejDSCRJzWnEyiVHySbBRiZDQyJMSijGS6ZHSCZJyafDRmPISKbJyifDw6LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAXABYAAAf/gACCg4SFhoYBAgGHjIQBAwQEBYwBlYiQAwYGi4UBBwcInIIJA6WRBAqdCwcMDA2pggEEDpUODwSiAAEQnwwHnI8RwBIGsLoLExQVFg4XiwEPD6IKGBjAExkaGxUcocfSgwHV1uITFR0eHyAhIroRERLAC/PVIxMkJSUgJvHH1RAKTixAgQzZhAkpVKwwwYKWrgnzFrRY4IIgBoMTRryQAGPjs4zzYsgYQdIgsgMzaNRw0CCBLgn2bNzAceMgSZITcujYwaNGj2sjcPjw8QNIECFDiEgoYuSIDiQOkoSTMAGHkiU4mAhp4uQJDyhRjOSQMiUXFQdVrOC4giWLFidbRri8QBKlyxQviIp8udKjRhYwYLKEedFAjJgvucI5cFBEgoMxkMm82PjFmCERix1wLCNmcg8viRGZ6aHZcQ8zoRtVWp16UCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncolorpicker-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBMT+xASaBASyBASCBARCBPz+/KyqrISChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARZEMhJ6wzBahvEyNvWEcMXcgJBFuApjavRhlgaz6J9u5dQDAUZ73VA+FhDQOAQQCQEQt6ymcjgREznlZatJpXdLZYq1ky137M3qS5zwl8lOR5IIDBx5TpviAAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nconfigure-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBISChFxaXNze3NTS1Ly6vKSipNTO1Ly2vNza3Pz+/MzOzOTe5DQyNOzu7MTCxGRmZMTGxPTy9Ozm7Hx6fPTu9MzGzGxmbAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAW1ICCOZGmeaEoGbBsI6joMRGEcbQwESDIrtVtAF1gwDLNaAmfKiVgLBJKgwB1KxQZrBHU0FAXmavFoQLYiB6TxFXMj5AZBwnJI2I3wcNWALyYEcgoKXxRhOHs7XxEVCwsWFgoUDRYUFwwQB25ZCxiNjo6GkwUXN2NsCxEYqhUHoQ0MEglYRQQXErcHrI55FycuB2YSmoyOBTEtB2sXuhU6XAENC2a6z9AKCwq+1tAN3E2J3ySkIQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnect_creating-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBPz+BMTCBISCBAQCBPz+/MTCxOTi5AQGBNze3Ly6vISChNza3FxaXKSipAAAACH5BAEAAAAALAAAAAAWABYAAAR4EMhJqwzY6omD+MNGdR8YilNZnug0qGzrqrL1lnV1fyJBVB6VQEMoGH4ADGwQkxQPBwMiKGA2J8VEAnq0tgiKg5aL/C7C2gTjKCM0zowDQ8tuNQznNL7cKzjOUQsNfER+gguIg19+Pm6ChBZFDmWNi5M5FIyYFHQRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnect_established-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBKyirPz+/KymrOTi5KSipMzCzNza3OTe5Ozi7MzGzPTq9OTm5ISChMS+xFxaXNze3GReZIyCjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWLICCOZGmeaBkAQpoGg7C6JizTQT7CxPwOwFWgYPChYIXkIHC4uQKGAiKRKCyNpxxUUVViVYNFLkqtLo+DAkMMLXQPXwAy2WCTF4544FGtKuwPDhB6DnxuUmyCcXIQhV1uYoMuEAcOBxEKCHg6TzGFCJUSizuejROKOAM9OY2SnUU7nD89NCcDsLUnIQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnect_no-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBPz+BMTCBERCBAQCBPz+/MTCxOTi5Nze3OTm5Ly6vNza3ISChFxaXKSipAAAACH5BAEAAAAALAAAAAAWABYAAARiEMhJq7046827/+AVCKE0Dh9BAGdaGISAToFGFMcBU+11I4hDYseSZQiKwwKoI/QwBIYiuFDCZseGdIlYEjUNg1SpY6w2N4cUIW6cjwW1lsFwo+MqgtZuw0/ydw5vH34lBhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncontents2-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBDyGhCyCfFSWlESOjDyKjDSGhCx+fGSinGSenFyanEySjHSqpHSqrGympEySlBx2dISytHyyrCR6dKTGxHyurHSurHyytGSipCR6fARmZFSalEyWlBRubAxubBRydDyKhDSChLSytPz+/MzKzIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbFQIBwSCwaj8ikMhBQIpmCQdM5ZBIKhgNiugwkFAsCI7pNMhuOxkNBgBgEiAi3GkBLJpJHYgEpaClyREwVFhcSEhgOGQoMfgMaERtcARQBFRMYExZ6HB0FUYAekkIBHxqWFmlrC1haESAfG6MBGx+VFRgKYH0hInGRklO0ppYXCwwMWQiQHkwjgrWnFRdYZHIBJCTP0LaWGAcDW9jZ2nMAw9IWTOQkJSZMRsOV49nu8E+19PbmR7TY+1TovONH5V7Ag0QMBAEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncontents-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAAQCBAQ2NPwCBHSurIS2tBx2dBweHPz+/Ozm1GxiTGyqpPz6/Pz69GSqpOzaxPzy5HxuVLSmlOTazPz27PT29NzClPTexHxuXLSmjAxqbFSinPTy9KyehNy+lPTy5Pz29HxyXNzWxKSahOzexPzy7IR2ZOTWtESenPTy7KSWfIyCbKyijAQGBDyalPTu3KSSdDSOjJyOdCSGhPzu3OzizJSGdPTq1PTq3JySdMy6lAyKhOzWtOzi1OTOrJyKbMS2nJySfMS+rAwCBNzOrNTCpNzKpJSGZKyafLSifLyylIx+ZHx6ZDSChAQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAWABYAAAf/gAABAoSFhoeHAAMAiI2IAAQFjI6EAAaJkQeTjwAICYkKBQcLm5WdBwyfhgChB66bp64HCQC1lQ2irqQCAA4PowsLEBESE4wAuLIHFAAVFr+uDBcYxRm1GrmuGxwdFh4Mrh8gGCET1gDYyhsiFSMkDAsMDCUYJhvnJ9kHKCnODwwfPlBQsULCPRYAWogK9sHFiwoOPEyQh0JFPXO1YBSYwBEFghjdHkwQOYGgwQwIZRR44GHGDBogabhAsYEEihrUMAIoUMCEDRs3HODIYQHFA6MPcJA7KICFjgw7eIzo4cOfiwc/gKwIUm2SkKdDdlDt4AABDaU/iIRwwbTSUyJFOow4S3Hkx9oNDDZgXPU0h1wcSIgEGUw4ibVET5WoWMKksePHpdxmyKADAEIWly9HJtQkQJMmlAgZCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncontexthelp-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBAQChAAAACH5BAEAAAAALAAAAAAWABYAAAJQhI8Qy5F/ghBsLuOgpHHy+0hZ94HINiqWwoQrtjYpNqJ0A8Hcjbs73yPNZEHVDygTJohJWqiZe0JPM5ajtXxFMkXnklqNgsPiWzmHPatzhgIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncrop-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBMT+xASyBASCBASaBISChMTCxPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARUEMhJq704681r+EFHBcIwEKFImmfKkURhoh1cyO0rxEWZa7bezIUJ7gg04O62A22MyeeyF1XymrUSs5pZmbA61u+FLBOBhrThozq4D2cgYo6IawwRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndecrypted-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBGxqbFxaXExOTEQ+RAQCBPz+/PTy9Ozq7Nza3NTS1KSipFRSVOTi5Hx2fJSSlKyqrJyenJyWnDw6PMzKzKyurDQyNFxWXMTCxJyanHRuLHxuLGReJFxSLFROJFxWJExCHERCHBQODISChHxyLHRqNIRyNHRmLLSqbKyiZLy6fOTarPz67Pzy3OzitKymZFxSJJySTNTSnPTy3NzSpMTChLSydKyqbKSaXJySVIyGRGReLPz23NTOnMzCjHxuPLy2vKSmpOTe5LS2tLSutHxuNHRuPMS+xFxWLIR+RDw2HFRKJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SDAQIDBAUChY2EAQYHCAkKCwyOjZANDgIEAQoPjJiDAg2iggQQp5gMBwmrDBESl6MTFKuoFQSjABYRF40CGAW8BRm7hQwNxBobHB0eHx4gISIjBdiEAhYFJBslHOHSHh4hBSHlxIUmJygpKissBiwtLi8pGjDqhBoxMjMuaNSwcSMFjhw6dnjYRyrGCh4ueviw4Q5HDB0/PjAUJCBCAwMIGiiggAEIBFk/FgYLIgRkggQkhxAJkqGExkYMFnxsIGRkSQgLHhRRWUjAggQgG8AsSWRBBiP6VrYMOfKIyaBDNwLo+HHSUplOSyDRqiEHjRkretRQkcLgxayNF0wksQGQxsSKMTIq0QpgCba/gAE7whEIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndown-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRKZDRSbBxCXJTC1Mzi7Nzq9NTm9Bx2nAQCBNzu9JzG3Hy+1HzG3IzO5BRmjPz6/LTe7Dy61AyStCTC1FzC1AyGrETS3ETC1ETa5BRulAyuzBRylAw+XMTe7Gy+3CSqzAyexBTC3DR+nIS21KTW5Nzu/KzO3FzC3Pz+/ByixEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaRQIBwSCwaj8ikcnkMBAQDgjPAFAYKhsMBkVBUAYEFo+F4QLzVQEQyoVTOX/XBcsHA0+vMRbNBMwkRDhxuHX5GTlIeHh8gISIjFAEeiVRECiQlDAUmgxQjIhwiJHdFlycoKSIUFCEjGiGkRpcqCxYijxorsUezcxYsuoZJsxLAu0qXB7DCTJfHVQrMX9PU1Uh0QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditclear-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAWABYAAAJBhI+py+0PYZi0WnqC2Lx7HhjaR3YhMArBUHpnuramCLLy9tY3TuP2nfPtVD3VTxY0DpNDHqo5E12mlYj1is1e7QUAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditcopy-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFPz+/DQyNISChDw6PMzKzMTGxERGRIyKjFxaXMTCvKSmpHR2dPz6/Pz29PTq3MS2rPz69MTCxFxWVHx6dJyWjNzSzPz27Pzy7Pzu5PTm3NTKvIR+fJyGfHxuZHxqXNTCtPTq5PTi1PTezNS+rExOTFRORMyylPTaxOzWxOzSvNze3NTOxMy2nMyulMyqjAQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbYQIBwSCwahYGkUnk0BgTQ6IAQaBKfUWhBYKhaAU+CgXAQIAyChLeJzSIQhcH6GFaM0QtGY5kstqEODw8QEQELAhJTc08KBBMEFBUWDRcBE1pca20SGBkaEBscAY5maFRIAgoLHRQRHh8gIQFlZnByqA8ZGSIQIyQjJQEmYgJ5p2ACrK4gJx4gKIZZAgdeAQ4ZI9kjKSor0AwEjeAs1S0cHAslLi4vMDDRWeRIfEsxMeET4ATyVoYLC5fizXEiAR84BeMG+pEm8EsAFhAjSlR4hR6fLxiF0AkCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neditcut-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBAwCBPz+/OTi5JyanOzq7DQyNGxqbAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARbEMhJq704gxBE0Bf3cZo4kRJqBQNRfBucyudgvJS6VaxLzyMa6/bLiWA9HOg4VIIkL5vzuRkcpkvRIIAorphJLzBW84WEuRZWp6uaT7J2Sh1Hit3OY/ZO7WvsEQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditdelete-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAASC/FRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwKDAQCBExOTNze3NTW1MTGxLS2tJyanPz+/Ozu7BQSFCwqLDw+POTi5PTu7MzKxIR+fCQmJPz6/Oze1NTGvPz69Pzy7Pz29LyyrPy+vPyupPTm1BQWFIQCBPwCBMS6rPzSzNTOxPTi1NS+rPTezNzOxPTizOzWxMy2pOzaxMy2nPTaxOzOtMyynOzSvMyqjPx+fOzGpMSihPTq3OzKrOTCpNzKxNTCtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf8gACCAQIDBAUGBwgJCgsLgpCRAAwNlZYODxALEY+SkAMNEqKjEw0UD5yegqCjrRMVEqidkgWhraMWF7GptLa3EgEWFRSOnhW+vxgZEBqzkBvItxwdHryRCNGjHyAhHSLOgtgSI60c2yQjJd+eJqEnKK0hJCgnJSngAO0SF+8qEvL0VrBogW+BLX4oVKgIyMIFQU8KfDV4R+8FDBcxZBREthAFiRIsOsygsVEUh4Un3pGoUcPGjZInK65QicPlxg8oX5RwqNJGjo0hdJwQ6EIkjRM6dvDYCKIHSBc1Ztjw4eOH0oIrsgIJEqSFDBo0cuTgsdSTo7No0xYTZCcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedit-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBISGhISChHx+fHx6fHR2dGxqbGxubGRmZGRiZFxeXFxaXFRSVIxSLPyuXMzKzMzKxMTCtExOTPzqrPz+/NTS1MS+tOSaVPyWNPz6/IxeNPzavPyKBNTW1PyCBPyGBJxmNPzOpLx6PNRqBMSCRNySTPyCDPSGBMxiBKROBHRydPSylOyydMxmBJxKBAwODPS2lPTq3OyabJxGBPTy5PTGrOyOXPR+DPz69PzmzPzevNxuPORqLMReFPzy7MyCXKxiNIRKHBQWFNTOxPzixJRaPFxONHRqVPz27PTy7PzStCwqJDQyLJSGdIx6ZPz29PTu5HRmTLSKbMSGZHROPFxKPJSKfJyShKyehMyuhDQmHEQuJJyOfLSijMSynMS6pLSefDQyNHx2bKSahLyqhLymhOzi1FRGNIR+bNzKtOTOtOTKrOTKpLyedAQCBFRWVPTq5NzOvLyunLSmlNTCrOTOrNzGrLyidMS+rLyynKyijLymjLyqjAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gAAAAQECAwQFBQYHBggJCgsLDAwADQ6CAQ8QD5ydEJ+gERKWE4ICDxSpqhWqqhYNFxMYphCtqaytGRoXGxgcggSoth25u70eH8APFR0VzMzNziAXIRjIvwAFwq3EqSLUGB/iI4LathS4JCXVJh8nKCmCKrXDFCss1eIfLS4v8ssdmgWsAGNDDBnt3s3wJ+jAtlUhaNSwccNEi4WCBBl4SAHHihw6ZOzg0QNjRgAG6KXK4CNEjBU/gDQI8kLISQAIADobAoMIzCINjLw4YvNkAno4kCRRUuNHESNLmDRxUjSjAlRPfECJImUKlSpMrFzBIqWqoKtJaWSJomULAy5XXrp4+QKGYcYFoCBEWRImi5gmY7CQyVLGriAGD2jEMHMmCxc0Xb6kUbOGTRs3N988gLM4jpw5Y+iwqcOGjZ07mE8yiGABz5c8c/Ts4cOnDJkybS7fdMO7t+/fvDMaCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditpaste-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQWFDw6FHRuFGRaBFxSBAQCBAQKBCQiBIx6HPz6/NTOfKyiXDQuFOTm5Pz+/Ozu7PTq5Pz63PTyxNTOjKSeRExGLMTGxMzKzNTS1NTW1Dw2NKSmpKyqrKSipJyanNzWlLy6ZLSuVIx6FISChIyKhJSSlCQiJLS2tDw6NDQyNCQiFCQmHBQSDGRiZHRydGxubHx6dGxqbFxeXGRmZFxaXCwuLOzq7KyurHx+fDwmFEQuFCweFCQWDBQODBwaHBweHKSinJSWlOTi5JyepHR2dDw6PBQSFNze3ERGRIyKjIyOjISGhPz29Pzy7MS2rMzOzFRWVHx2dHxybDQiFPz27Pzu5PTq3PTm1NTCtJyGdHxuZHxqXPzq3PTaxNS6pFxWVFRKRNS2nPTi1PTStNSulNzOxNSynMymhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCgwABAgMEBYSLggaOjgcICQoLDA2Pj4MGDg8QEZ4FDxITFBUWFxcYGRobjQ8cHR4fCQ8gCyEiFSMWJCUkJieNEB4dKB4pKissK8wrLS4vMDHBAAYQHx8dFx0fJDIzNDU0M+IyHzaNNyg43Ng5Ojs7Ojw9Pj9AMkCNDiZB/h9CSOx4QLCgihItqBkYgqIDESElitAYWJCgkQcXjjRCgi1Ihw4BB5LAQOLCgyQYHihpUU3DBw5ElpAgAYNixSRJjKjQaECDCRPZPDB5IbIGSQwKLnh4wbInLA4kmJB4oaPiAwVNnER40hRK1BIAaVatUZJEFCkmpmjgCeWDCalFe4q4oFKwSRUrEa5gycLzwq8lUnPQ4PEgSpYcUZ5o2cIlS1O/JHLEDdfjQZMIVrpgweLFy5e+M6WSmBGlxYMYYBRzCaOFi5imHWBIfOEiShLTVjaP6eyFTBmN1TA5OvLDjJksWb58OVMGDRqWjAYdmU79SIvpjqJr104nEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditshred-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBFRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwKDAQCBExOTNze3NTW1MTGxLS2tJyanOze1Pz+/Ozu7BQSFCwqLDw+POTi5MzKxPTu7LyyrIR+fCQmJPz6/Pz69Pzy7Pz29OzaxPTu5PTq3PTm3My6pPzu5PTq5NS+rPTm1PTi1PTezOzWxPz27MyynOzSvMyulOzOtOzKrMymhOzGpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbpQIAwIBgMCAXDAZFQLBbCqJTRqFobjgdkEYFKowPJZEyeUBqVR/crHDTKZYplovZKCW84+YKZZNZSBXl6EwEEBhVPXxZihGMaGRscdkIdg4QeEnVfCH2OHyAhIhuUAAiXZSEhIyQlJqWnjiEnKCWupRWoYyEgJK0SKaUKjam0JCorLMFfC6iqx8giLa/MGAsT1wsuCyULKwssC9RSzdkfCyALKuALLQsvpeXYIQso3gsiCzALMfENC+dGcMNHUAY/f+jq3ctncMYCGggFrsvHcEGNh/EyPFmg8cmrJxAVkVO0EUDJklHoBAEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nedittrash-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBERGRExOTDQyNISChBQSFCQiJCwuLPT29Nze3GxqbDw6PGxubHR2dJyanLSytJSWlJSSlOzq7Pz6/Nza3Ly6vFRWVBQWFIyKjMTCxHx6fIyOjLS2tOTi5PTy9OTm5Hx+fNTW1KyurKSmpJyenExKTMzKzKSipFxeXCwqLMzOzKyqrMTGxLy+vHRydBwaHNTS1DQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb8QIBwSCwaj8KAMoA8LgUDQsFwQByay4RiwWg4GA9IRGk0SCYJSsUCsVwwGQ1EsmESD5xOp+L5gDwhBRIZDhcDdkMGDgEiIxAkJQ8Ok5MmAohDAQ1xJxUlKCUlEg0pKpiZJRoLCxmtCw1eURhOcR4rbQ8cGRwLAwgGtBYTDywtGRKjvQTARgEZLhMcKC0OrQMvAirMRc7CHCTU1g2+20TO0NIn1RwDCya/wdHT1Rnt5LToKOq79trx0tR02YPX7Jm8fRxMOIhSLhOJE/LCJSTlr5kFEBQsWDiR4UGGBgsuHDg1BEYAfTE6oEBR4AIBAiS5yWBAAAGBAyaPGAgCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nencrypted-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBHRudFxaXExGTERCRAwGDGxubPz+/Pz2/Ozm7Nza3NTS1KympFRSVHR2dNTO1JSSlKyqrKSipDQyNMTGxDw+PLSutKymrMTCxAQCBHRqLBQODJyanDQuFFxSJFRSJFRGJERCHExCHISChHxyLEQ6HGRaJExKHLSmbLy2fOzitPz23KSiZHxuNHxyNJSOTNTOnMTCjLSudKSaXJSKRJyOTOTetNzWpHxuPOTi5MzKzLS2tFxWXOzq7Ly6vOTe5Ix+RLSqdNzSpLyydKyqbKyiZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBAgMEBQKEjI0GBwgJCgsMDY2XjwkOAgQBDxCLl4QNCaGCBBGWooINCAqqrBKgqwATFKaDFRYVtBMXsIMNGBm0GRADjQIJxKIaGxwdHh8gISIhGyMZzIwkGholJiYfJiAfJyEZISDbg90oKCkqKwcHKyooLC0f7IIuLzD2YMSQgW8GDRri+AFoUMOGvRsxUhSsQQPHvmQSchyQtEAHhh0WJHDQcJERjwsKDvRI0BGDjwgicXhQyCOjSgUKPO6AObIkIQESfmxk6REDT4s0bfaYpDNkT4VAha5s+TLmzEYtatwIOHAiDZIKNQAJYk9IjCFEisyoocFEB4UACtBpm0t3LiEsgQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neraser-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBMTC/AQChAQCBISC/PzCxPz+/MQCBIQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARfEMhJKwhi2F0DIRnHeR+oiRRZmqikrmD7wgI6r+EI4+d2l7lNwWDYsTiFw4FI61mSymXxE3xGo8xqBXpVGrQUbveAcG7H0bKowEar12wx2SyMp+lI+7s1ie/5fX8tBhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nexec-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAwKDAwKBCQiHNze3AQCBBwWFDw6NPTy9PTy/Dw2NKyytOTi3LS2tMTKzMzOxLy+tLy+vBQODNze5NTS1JyalIyCbIx6VIRyVISGfJyelOTq7EQ+NMTGxKyurGxeRLyKPOSmROSuVOy2XOSiTLzCzNTOzDw+NCwqLHxuVOy6bPzGfOSuXNTW1LSyrMSWRNymTOSmTKSCTPTGjPzSnPzWnMyaVBQSDMTCxPz+/KyahNSeRHxeLJRyTPzmtPzarOy6fJyajNza1Ly6vLyulFRCJPzirPTOlMS2pNTSzMTCvJyenBQWFNzKtPz6vPzyvPzqtOzGlOTe1AwGBFxWTLy6tPTm1PzSpPzutPz2xPTSnOTSxOy2dPzapPzerOzm5IR+dPzu5Pzu1PzqxPzy5Pz+9GRiXGxuZKympHR2bOTm5Pz6/MzSzBwaFJSSjCQmHPz2/AwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeEAQKIjIIDBAQDjYMFBoMHCAkKgwYFhwULDAUKCg0ODxCkBQgRnoUSExMUDxUWFxgZGpAbFIuGHB0eHyAhIiMkIB8lJieIKCUpJCTGIyorLCktKIUDpC4YLzAxIjIyMzQ1NhgdpJI3ODktJTowOyM8Ejc9Pj9AQUIEclAocCMIBQhDiOwgoaKIoCI+jBxBkkSJkCWemIyq0GSHCBVHihRx8gRKFCmpKhGaQqWKFYZXsGR5kkXLFgRUXBUqkCGCFS5AjnTx0sXKlyA6CRVgAAHMAilhxIwhU6ZFkBY5kgKYUoXBAzMKzixZ4AJNGgVm1KxhM0WpmQpUMtooaOPGxAM3Nw60oYLGjNYCbzYJOgAnRzNBJ95oPYQCgpJtkwzFoULlRuRPiy9fNhAIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nexit-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBHR2dDQyNCH5BAEAAAAALAAAAAAWABYAAAJOhI+py90RnIMyRUOxhDfzJkACdoXBuEDDkQFDi5go0MrKx16kns80b7qdELCgBYaEGWwL5nG1ePFiKp9A6kuYRNuho8vxVrrZivmMRtMLACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfileclose-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBERGRERCRDw6PCwqLExOTFRWVHRydGxqbGRiZCQiJISChIyKjHx6fDQyNBwaHJSWlKSipBQWFJyanPz+/JSSlCQmJAwKDCwuLBweHBQSFGxubExKTISGhDQ2NFxeXFRSVDw+PAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbZQIBwSCwaj8jkMSAYDAgEJbFgOBwQCUOAoJAaFgvGonHIBhyP5BcSgUAYDWxggD4WFmx3e3HQngkSRgYMEBMUFG4MCId0BGlEAQeEhocVDYcUdBYKF0QCB3gRlJgUAQEYBBkaRAMbDZMMpAYcT46rQwMJrgsdC6QcfwoPnUMOBgkIV6SHHg6bw0QEAQYfBpggBZjPGsRD0gEchxwCIR6HChnQRQ8DIU4DTR4Em+ncRw8O+fmoXPXdRg+gQLFgIYM/KRIkoDP4QMKFf0o0aBAh4qGUixgzCrETBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilefind-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQSFJyanLS6vLzCxISChNTe3OTu9Oz6/Nzy9Nzy/NTy/OT2/Nzi5Mzu9Lzq9KTe7LTq9PT+/Pz+/Nz2/Mzu/Kzm9Jza5HzK1LTi9PTu9IzW5ITO3FxaXNT2/KTi7Iza7GzC1LzW3FRSVMzO1MTq7HTS3Fy6zFS2vKzm7Lze5MTGzHzS5FTG1Ey2xEyyvJze7JzW3ITa5FTK3EymrGS+zFxWXKymrMzi7ESirEyqvLSyrKze7MzOzMTCxKSepAz+/NzW3MzKzBwWHLzS3ERCRAzi3KyurNze3MzGzLy2vLSutCQiJAyytHRydOTe5MTGxLy6tLyqpKyelJSCdOze3NS+tLyupLSmnKSOhCwuLPzy9Pzu7Oze1OzazOTOvMyihOTi5PTm3Pzi1PTazPTWxOzOtNSunDQyNPzy7Pzu5OzKrNzSzNzGvNS6rMyynMymjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCgwGFhYOIiYQBAgMEAwKHiokBBQYHCAkKCwwFAZOEBQ0IDAsODxARCZ6gAAEGEhMSFBUWFxgZCJ+TjBoMEpkRERscGBGRih0BBAgeFBQOER8gISEfIruIIwEkCCUVwhcgJicoKSrZg9srCRkRGdMsLS4vMNiK2wIKMRsbMiwzXtCocSydIBs3AuCIwIFDiBMucugAoWvSiB2VNPDg0ELHwA0MkCXr4aNSggg8NoDIQOFHgBtAkgURMiDAEAFEVBCJFKCIkSMGOyDRkETJEkOFmABoUsRJQkQdnkzQACWKlBtTplBR6qopxkFRJ0ytYuWKFCxZtBBq+hRA2AlbRrh08fLlCxi1a51g+dQhDFwuYsaQKWPmDBpKXgNETaNGjJgyhNfcVdTTiWI2XpK0cePmzRk4YA5T5otGixY0qFOXbgXAQCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilenew-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBExOTERCRDw6PCwuLBwaHAwODAQCBOze1NTW1OTi5Nze3MTGxLS2tJyanPz+/Ozu7OTi3BQSFCwqLDw+PDQyNFRSVPTu7MzKxLyyrIR+fCQmJPz6/NTOxPz69Pzy7PTu5Pz29Pzu5PTq5PTm1My6pBQWFPTq3PTm3NS+rAwKDPTi1PTezOzWxMy2pPz27PTazOzSvMyynOzaxOzOtPTaxOzKrMyqjOzGpMymhPTizOTCpNzSzNTGvMymjMSihCH5BAEAAAAALAAAAAAWABYAAAboQIBwSCwaiYGAYEAgFAqGg/Q4DCASCsTiymgcHAcqQLB4mM+QiIQBppLPcMjkwQ4bB2X4maKgt4sVCHpnFhQTElNFE3mDDxcYGRp2RBuMgxwIHX9EBZZwHh8gCBmTQ52NISEiIyQlpUImng8hHyInKAgprwAqgnC0IKwrLLpGB4wctLYkwy0uuwd9Z8AnJywsLcVFx2YcL7UnJCwwLTEy0GXJoSgrCCwzNDTnxgjeH9UrKzXwNDY36LRGhEOwLx4NHDmgJbh3QoeOgv127EhojEeHDj16pEhRQoZHHzl+QJNCsqTJSXaCAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileopen-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAQCBCQWDCwaDDwmFPSubPzGhPzCfPy2dOSmZPzKlPzSnPzOlPzKjBQODPzChPzWnPy2bPSmXPyuZOyeXIRSLEQuFEwyHEQqFDQiFCweDKRuPFRSTPT29PTy9Ozq7OTi3Nze3NTW1MzOzMTGxMTCxLy6tLSytKyurDQyNMzKxOTm5OTi5Nza1NTS1MTCvLS2tLSyrKSmpJyenJSWlIyKjHx+fFxeXBwaHKxuPMzKzLy6vIyOjHx6fDw6NPy6dGxubLy+vISChCQmJNza3KyqrBQSFLR2RKSinJyanGxqZAwGBJSSlCwqLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeDAYqKiIeLj4wBjQCMhY+NkoiLk5qbhQIDoJyGBAUGBwgEo4MECQoLDA2pDrS1tKQPEAwHERITE77AvxKqhAQNDA8UFRYXFs8YBAQZGqGPxw0RGxwdHR4eHyAhIiMkJSYnKCgpBAYPEhcqHyssLS4kLzAxMjM0NTY3cBA4UCAHBw8gVnhgEcKFjhc7UPDj0cMHAAI/KFgY4YLFio/jRpTYsW8GDyCSCEQw2DChOHIqgsCQSEPIEEEEJFhAoUNECCJEyOk4d6KIyRtGcB7hIJKjixEjHu4oimSGEIs4d8IIUoKECnNB0ElMwkNJJgBLlJBAcQKGiR07KGAURVGViY0mhIwwSTKjr99+THjUoIg0r48hTRIrRtxkiOMhDgrZCQQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfileprint-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBFxaXDQyNFxSTPTizOzi1FxORDw2NExKLPTi1Pzy9Pz6/FRWVPz29Pz2/PTy7PTu9OzezPzu5OzavAQCBPzy7PTm3OzazOzKrPTu5FxSRERCRGReXPTq5Pzu7ExGTMS+xKSmpOTKpPTq3JSCDNzSfHRydLyadOzCjOzOtOzSvLyyTMTCxKSipGRiZFROLPz+/KyurJyenJyWnGxmbLSabOzClOzm7LSutJSWlJSSlJyanGxqbNze3OTm5IyGjNTO1Nza3NzW3OTe5IyKjHx6fMzGzMTGxMzOzNTW1IR+hISGhKymrLy6vLSytERGRGxubKyqrLy2vLS2tDQ2NEQ+RASKBAT+BFxeXHRudAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAgOEiYqEAgQFBgcGi5MICQoLmAQDh5OEDA2YCw4ODxARApKUCaGYEAsSCRMUnQysCwoVEhYXGLOLCBCgDqK5GQUXGooCAhscBB0euBUZEAUJvQgIgx8gIR8iCSPiHuIFEREDJCXaANwhJhsnKCnWERcRKiopFCvsBywhQrRwQWGAPAz5EhpQ9wIABRgKYsiYMTEEDQocatiwkUIEP18fbkCAAcMBjhwzdOyQwYNCgBMfKJSgMItBjxs+btwgCSGGjhw/ZoRgQKGZCRMUPgABEgSIkCE3SZok8qNqkR85NtDUEcPIkaVAkCR5SrJBDCVKlmzQ6pCCiRlMTJo4YUH3K5AeMBYYWctW0BOaUH60cBJFypQmII6wyEpFQBVFMSm4UAI3hJUrOGh8oOJrklYKWIromJGDR99Ogz5j4ZGlM+pEnwmBCwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilesave-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBGxqbAQCBLy+vERCRExKTHRydIyKjMTCxFxaXGRiZFRSVFRWVPz6/Nze3Nzm5Pz+/JyanDw+PExOTHR2dMTGxBQWFLSytHx+fISChOzy9Ly6vAQGBJSWlMzKzAwODJSSlHx6fIyOjOTi5DQ2NISGhGxubCwuLOzq7ERGRFxeXNTW1CwqLPT29Dw6PGRmZKSmpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb/QIBQGBAMj8ikUDAgFAzKKCBwQCQUCcICKh0SEAhGw5EIZAmBrgCxeDQgcDJWyz0GIggJfL+XGwQJRxNgC3yGDwwUFUZDFhdthnwMGAZNQwEZFwQakXANBBQbHIIdERIBnRAOiR4ERx8gsSEMBBmGCyEGG3YGBwcgIr8UCwQHECOgG4xCtRkEJAvBJRklJgkSFBQeJ68hJiEoESkFKiEZIbkGARsLlwEGExENGhorGSkpFAYm66NDLAECpGiBYsUIFA8wLHBBQMWLVkdUCFCwaYVFBOymkVCgYEMgOykEpICBccMBAhhELFigTEqAAgIIwCiQ4eRKDyS6EAlJIAI0EpaudF4iIKDAAn9CkRT5eMROEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfill-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAASC/AQCBMT+xASCBMQCBASaBPyChASyBATCBPwCBARmBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAASCEMhJq704axB2DkLnVeAwiCNHDMWZcsbaul5ZyCaKBcZwFDcgDRNbHX7AmW4SMx2MSOFQQlitEAhosrVcDQQE7NMXzVGqA6xAgCUckabQpJoIYBFsxBspUKBiHQEHaoNvBQJTgBIBdnh5B4hLihONeJBTc0uMaphMS4uRGQYfny9EEQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilter-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBAwKDMzKzMTGxNTS1MzOzAQGBLS2tLy+vKyqrLSytLy6vMTCxBQWFKyurCQmJBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAV7ICCOZGmeaHoGbKuOAjsQhVG764EgyT7YhaCBVQogFMhFImEABoUBknFxRDAazac2Kg00djystkA0sQ4BgzgYK6+Ch/bBseOmAmMD4gF5ifBCDwoRfiOABgyEhYYFCA6LUo19kH+Nj5QAaQh2kHibmJkFBJydpKCnfnYhACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfind-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQSFJSWlFxaXJyanKy2tLzCxDw+PHyChNTa3Nzq7Nz29NTy9Mzu9OT29Nzi5Oz6/Mzy9Kzi7Jze5Lze5Nzy9JyenIyKjHR2dMTu9Kzm7JzW3ITW3ISChGxubERGROz+/Lzq9IzW5HzK1LTm7FRSVHTS3GS+zLTS1DQ2NMzOzMTq7Lzq7ITW5FS2vMTi5ExOTKTm7EzCzEy2vEyutJTa5FTK1ESirGy+zMzi5ESerESmtITa5OTy9KTe5KyqrAz+/Azi3ASutERCRExKTFRWVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCggGFhYOIAAIDiYUEBQYFAoeJAweKhAgJCgsLDA0OCAGJg4wBCA8QDhENEhMUFaKDFhcYgwEJCxAQDBkaGxwSFaMAFh0eAx8AAQIKECAODCEaIiMjJJMAtQMlygEGEBkVva4mJycTKKMYJd0pyyoOKyssGhMtIycuGi/EMB/vlhmoQEFDjHsmZMygUUMdqWUCGgCbYMKEjRk3cEjI9jBADg3Wzs3QsYOHA2IdO1SQkI/GjRMtFhBA2RFBDwk+OASrMPMHkIe3AhBA8QLFzAAHgvyg2dEQMSEHPCwltQgooSFSmVpSxKjjh6wPtwINgHVqsVpWESEFeywZ17RkED2s40YEgFirlIq4SwvUQCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfinish-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBBxCXDR+nIS21Aw+XJTC1Nzu/KzO3Pz+/Nzq9Pz6/MTe7KTW5FzC1Nzu9CRKZMzi7IzK3Lzi7LTe7HzG3Gy+3AyuzAyexFzC3DRSbHy+1Dy61CSqzAySvAyStLze7IzO5AyGrEze7BRmjCTC1ETS3ETa5BTC3Bx2nAyWvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAakQIBwSCwaj8hkMqBsBgTN5IAAJQqqykCBasUmDQcEV3gtBs7oATihGJeJgcOCQWc0HA8Ig/seRiQTFAsVFhcYGRp6VH1CGwscHQ8dGB4fIBkPIWKMAAMLIiAjIJcgH5gkGSWcARIiJicoJikpHikoHqqrKiW8JSogKymoqgCrV8cCARgkuFWcRwYeqVjPRgEExEPVRQbZ2l5IBuBRQ0zk5+hRBkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder_new-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBNzaTPT2FISCBCQaDPz+BExKBDwmFPSubPzChPzCfPy2dPz6BMzOTAQCBOSmZPzKlPzSnPzOlPzKjBQODPz+rPz+3PzWnPyuZPSmXNyaXPTyhISCLIRSLEQuFEwyHPy2bKRuPFRSTPT29PTy9Ozq7Pz+xJyanDQyNPzGhMzKzOTi3Nza3OTiVBQWFDwqFKxuPOTi5JSSjISChHR2dGRmZFxeXPS2dNTSzNTS1OTm5KSipLS2tLSytKyqpIyKhGRiZNze3NTW1MTGxMTCvLy6tIyKjCQmJMTCxMzOzMzKxJyenHx6fLR2RLy6vJSSlHx+fDw6NLy+vIyOjAwGBGxqZKyurCwuLBQSFJSWlCwqLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeIiYqLjI2MAY6HAgOHBJYEhJCDBQaDmgcICQoLB4MGDA0OAQUBDg2cAAcPEBESE6QUuQasFRYVq5SxCRcSCggYGRjIGgYbFs8bHIMHExIJGR0eHx7cB83PFhsDDuTUEyAhIiMjJCQluwEmvsAnKAcp1x4qKyUrLLupWrByxcnFiwQIYIggEaNEiRgBZMyYQaNADRs2REA6cCODBxw5+OnQgWMHjx4+BND4MQOIg1gI0gUREkTHiplDhhApEoCGkRlHBL3I8MEHEhz+WAhJogTJySVMfthwIehAExE5jubAkYQpESc8fOx4AiXKNA8+ekhBgqSpzh5hPHcsmVLjpSAqVZBY6VGkiJMiPQKLnTvjCiEsWU4o3nGC8YksMmT8YCmC6iAXKLRc2cz5yGYtR0JjKWQgEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nforward-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBBxCXDR+nIS21Aw+XJTC1Nzu/KzO3Pz+/Nzq9Pz6/MTe7KTW5FzC1Nzu9CRKZMzi7IzK3Lzi7LTe7HzG3Gy+3AyuzAyexFzC3DRSbHy+1Dy61CSqzAySvAyStLze7IzO5AyGrETa5ByixBRmjCTC1ETS3BTC3Bx2nAyWvEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaYQIBwSCwaj8hkMqBsBgTN5IAAjRoDBaq1aDggtMuAWDzoJhTgY+CwYLgZDccDwkgXI5IJZVGxXDAZGnR2QxsLHB0PHRgeHyAZDyFfVUQDCyIgIyCPIB+QJCUmlEMBEiInKCQnKSkeKSQeomoqJrUmKiArKSwZsmoCwMEBGCyxo1EGHr3HUQEEvltCBtDRAAbMW0zV29xDBkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfrac-22:actions actions22 22:photo:22 22:R0lGODlhFwAWAIIAAPwCBAQCBAwODAwKDAQGBIQChAAAAAAAACH5BAEAAAAALAAAAAAXABYAAANICLrc/iwEJSEUQA45LcOKMHWeU5XWiUYZsZClOIjj+naqrS9F7/9A326YCYBypREOpMPBVifjkBRw7SpIG+eJIg2IWC5UikoAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nframeprint-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBFxaXDQyNFxSTPTizOzi1FxORDw2NExKLPTi1Pzy9Pz6/FRWVPz29Pz2/PTu9PTu5OzezPzu5OzavAQCBPzy7PTm3OzazOzOtPTu7ERCRGReXPzu7PTq5OzKrExGTMS+xKSmpOTKpPTq3JSCDNzSfHRydLyadOzCjOzSvLyyTMTCxKSipGxmbOzClFROLPz+/LSutJSWlJyWnOzm7JSSlJyenOTe5OTi5MzKzASKBAT+BNzW3OTm5KyurMzGzMTGxMzOzNTW1KyqrLy2vERGRGxubIyGjLSytGRiZISChAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAgOEiYqEAgQFBgcGi5MICQoLmAQDh5OEDA2YCw4LDxARApKUCaGYDwsSCRMUnQysCxUKEhYXGLOLCBCgow4VEhkFF6mMAhobBRAcChUVGR0FCR4UCAiDHyAhHyIJCRAjHOUJEREDJCXcAN4hJhonKBjXESn5Kdkq7wcrQoRg0YLCgBMuRFxIwTCFgXYvAFCA0SCGjBkYQxQMUE8EBhEUVPj6QOMBDBgLLM6oYYMFhYkvYcSkwOAGDho3TyqIUaPGyZ9AKXzIoWMHDx44bvQ4+WAi0KA1fPwAEiTIjyBCkDp9KlMiBRMzhhAhsqLsD64/fQEo8tLIERZIH8Ru5arow8skSmTMDdpJQ0y0XTsJ2gtU8GCZMBMbCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfunct-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI+hI+py+0PIwhUohpMXfl6103h1nTUNproEU6am62v1pLsPX/siO9Jiou9TD2XyHfMGUs65aVmiUqn1CrCUAAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ngear-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFCQiJERGRBwaHFxeXHx+fDw+PGRmZExOTGxubKSipDQyNHx6fIyKjJSSlJyanISGhISChLS2tIyOjHR2dAwKDAQGBJyenAQCBCwqLLy+vKyqrAwODMTGxKyurFRWVLSytLy6vMTCxMzOzGRiZNTW1CwuLMzKzFxaXJSWlOTm5Nze3Ozu7OTi5Ozq7GxqbDw6PHRydAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb/QIBwSBwGBMVkMjAgFAwHBFJpPB4SiQJCsWAQqEJB4prdNhQNx7QYIFwLD0ikQZdMHgelOPGYULQVDg4QEAVfRAEBBwUTEE0WFwcYhAuNF0QDBQULDwwZGUIaEAuVGxgBRAIFEhwHHUQMCxwTHAVrAAwFFRwKFkQZsxseDqBDGXMSHwfFQiAhIiMeJApEBwcOcahDJcLSJCYcGkQKcRAnQhkF0SgmEykHXkObox8q1iEjKN8rENqYD7MmeBCmzwSLFS1I3AqzYIPDESS+sWCxgQMLEgOSJKjozeAKFyskCDigQFwSBhJMjDDhAlyLFyVA+dIzAUUKEi0eaNhAIg8YGiEMenkwASNDDBkLqRQAEEAkup9KDkEFgC4IACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ngohome-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAQCBCQiJNze3ERCROTi5MzGzLy6vDw6PKyqrKyurBQSFGRiZGxqbGRmZISChEQ+RExKTExOTHRydDQyNOTe5FROVLSurCwqLMTCxPT29Pz6/LSutFxeXLyytLSytPz+/JSWlKympPTq7KSipNzW3BwaHHx6fKx2VJRWNHQmBFweDOzq7Ly+vNTW1JxWNLSajPTe1Ny6pKxWJNTS1IyOjJRmbPTi3OzKrNSSXMSGVHQiBHx+fJSSlPzy9IxOVOzWxOSyjNSCPLxeDJyWnIRGTOTGtMxmDLRWBHwqBIxGTLRSDDQuNNSunKxKBGwyNMSafMxqHMReDKRGDPTu9LxuPLxaDJQ+DIR+hGQqNIQyBGQiBNTO1EQKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAYSIiYQCAwQCiokEhwACBQYHBAiQhAiHlQYJCgkEC5uCkp8MDQ4NDwylmwgQlgQRERIEBBOkmxQVBgQWFwUFFxEEDLyJGAUZtQoFGhsFHLYdyoOVHsEf0SAbIAUex8mwlAUhtSIFG+3uIyTWvAIGJMEkJe76GyXbEeWUBJg4USKaBhQpVKzYoIFFiwYUBBJa8MAFCw0vYMSQMWOhBhoTKCQSUKMEiw02buDIoWOHBg0GeIhEFKAHDR8afgAJImSIioYliMws1MPkhiJGchxBkmTDCBo1hg4KQMTiBiUyhBxZ8pNFiR5MEtU0WqSJVidJNDyNKraHC5xPNKBEkTLlJ5WvUgWNvfikyhArV34+7ZEXQAAsB2iUyHLlihYtW0pwOYAFgyJDmDNr7jIIWiAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ngoto-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBBQSDAwODAQCBCwiHDQuJExCNFRCNAwGBDwuJEw+NFxKPBQODEQ6LFxOPEw6NCwmHDQmJBwaFCQaFEQ2LCQeFDwyJBwWFDwyLDQqJAwKBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWSICCOJBkEQqmWA1EYR4Gsq5Aoy2EYKU0yDcPCkSP4SgShw2FoDI6jQeNxYD6MUBFCEXxAelkRgxCRhEWQiW/wXE2CataAUmiXKo+Fwg6YWxQWfCQEAxckUgoYDRSCR4gKB4ZnFVwUCgUMZ30KCRQUhJpzBRQQjUcSnmyaM32mPgQNmZpRBwmSsxAZBBqzUa4iBiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nhelp-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBCQuNBwiJAwiLAwaJAwSHAwSFIy+3ERynCw2PCQuPAwmPCxOZCxWdJzG3FSazBwmNAQKDAQGBDRmhBQyTDxujDR2rIy21AwWJDyGxCxmjAwmNDRihAQOFDxmhCxunBQWFAwaLCRahDR6rESGvDQ2PCRWdDRunDSGvCRSdAwWHCwuLDSOzHSmxDyKxBxCZBwqNHSu1DyOzAQSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAahQIBwCAgIBAPCoGAgOoeBAyKhWCwYDUf0CX1AIhLiJEGpBLiAAaRxdgYsl7Ybk8igBZoN5xmAdDxoanp8HyANISF8EBsiXBMjJBolBEQmGHFoRScbKHIKDykqK5lFAZRCnyknTaROLA8tq61OChgtKqyzQgEYEJi6UC4vI3LAASkbMBPARAEBdszR0sACEaPSMTIQM8W6KzNl3bo0NOJDdEEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nint-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIIAAPwCBIQChAQCBBwaHAQGBAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAANJCLrc/iDAuYKlU0r8NHfXB24iEyrCIAjAynakQLQuDS+vrTcnI1M9HyaIykFOKwUhZ6zEWC5oU9GrRY+kkqdUiXCdWW74SzYkAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nleftjust-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIihI+py+1vgpy0Tohzs1T7z3CiBJbQWJnqg4rre7jwTBtGAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nlocationbar_erase-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBPz+/AAAACH5BAEAAAAALAAAAAAWABYAAAJChI+py+0PX5i0VmbzVboHPgmCJVoJJY5haR5VGsCa+6ZqZ2Sy95E2n0OVdi2A8EacIIS+YpC3WUIpi6kygs1qsYYCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nlock-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBHRudFxaXExGTERCRAwGDGxubPz+/Pz2/Ozm7Nza3NTS1KympFRSVHR2dNTO1JSSlKyqrKSipDQyNMTGxDw+PLSutKymrMTCxAQCBHRqLBQODJyanDQuFFxSJFRSJFRGJERCHExCHISChHxyLEQ6HGRaJExKHLSmbLy2fOzitPz23KSiZHxuNHxyNJSOTNTOnMTCjLSudKSaXJSKRJyOTOTetNzWpHxuPOTi5MzKzLS2tFxWXOzq7Ly6vOTe5Ix+RLSqdNzSpLyydKyqbKyiZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBAgMEBQKEjI0GBwgJCgsMDY2XjwkOAgQBDxCLl4QNCaGCBBGWooINCAqqrBKgqwATFKaDFRYVtBMXsIMNGBm0GRADjQIJxKIaGxwdHh8gISIhGyMZzIwkGholJiYfJiAfJyEZISDbg90oKCkqKwcHKyooLC0f7IIuLzD2YMSQgW8GDRri+AFoUMOGvRsxUhSsQQPHvmQSchyQtEAHhh0WJHDQcJERjwsKDvRI0BGDjwgicXhQyCOjSgUKPO6AObIkIQESfmxk6REDT4s0bfaYpDNkT4VAha5s+TLmzEYtatwIOHAiDZIKNQAJYk9IjCFEisyoocFEB4UACtBpm0t3LiF4gQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nlsub-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBIQChAAAACH5BAEAAAAALAAAAAAWABYAAAI9hI+pe+EPHTNhgjox04srn4CI2FgkZaaZurGd+5nRfAiCYVuJzfN6jbvdfrshEZE7ApNGXa+nZDaVVIOhAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nlsup-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBIQChAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAI5hI+pF2G9YpszKgcgtgtyuX2I44UcRYkM5qmWAMcyzAn1/eKRnfe7vuD9fEGgQlgkHo2JmRPpStgLACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmail_forward-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBJR2dLyijPTixPz69Pzq3Pzy3Pzu5PTu7Ozi1LyelOzavPz+/DwqLLyafPTmvPz67Pz29Pzy7LSWlPzmzPz6/LyajPTitOTSzMyurPz25PTatPTi3KyOjPzuxAwqVDQiJHxiZPTetKySlPzqvPz27BQ6bAwmTPTexLyinNzGxDRunPzy5KySjCQ+ZNzq9KTO7JzC3Nzq/Ozu/LzW7FSm1BR6vGSWvFyq1AyGxAxytAx6vBSKxAxSjMyujLSunES+5BSi1ByGvAQCBNzCrOTaxNTOvMS6rKyelCx6rBx6tBQKDOTWvPzu1PTq1OzezAQOHAxGdBROhAQGFPzy1NzOvIRqXLyynOzarPz21Jx2XPTWrLSShAw2XKSCbPzuzAwePAQCDPzyzPzqzPTmxOzWtAwGBKyObOTSrNzGrKyGbOzatEQyNKyCZOzWrOTGpNS2lCweHCQaHCQWFBwSFBQODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBhBwgQKFSpY0HgBQwYNGzh0mDhRAAUPHziACEGBpYgRJDiUGEkSwoCQJk6opNASRQoOFETQJDkggwoOJlYApcCihQuVL2DUhBDjhIqjJmRwwDCDhswaNm5MjYHjKggOOU7o0CGTA9gdYknG2KCCBw8VJVL0uBgihAUfP+CSNGCjsI/DiBPbAMJBsEQbQYQM+UG5smUiRYw0jlvYxhEkSYyIHm1EyRLTTH40EZvAyZPOR4pAmU07ipIkUKQ0mQIhAZUqVq5gKXzkSBYtyLVEyd1ki8QFXLp4+WJFQowbYLJnD5NbzJiJCjaQnhnvpYwZM0/OPFlvQ/f3iQvQpBlvQc0aCWy4VKnCpY0Y5yQxgEYXZFjghgwZUOHGCW90YQEccUwloBwGyjAHHXUoSAMZb0xhx1QOoMHDHSfIwSEOdTjhAQ1d4MFbTQ6Q4MYacrzxhhx04JCHHhvQsMeLJPHRBxpr+LHCGnusgccfgKixQR1ATtTBlDDAEIggggxCCCGFbLGFHVFKZEdAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmail_generic-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBDQyNCwqLCQiJBwaHBQSFAwKDAQCBDw6PPz+/Pz69Pz27PTy7PTy5PTu5PTu3PTu1PTq1PTqzOzmzPzuvOzitPTmvOzivAQGBDw+POzevPz67Pz25Pz23Pzy1PzyzPzqvOTavERCRKSilPz21OTevIR+ZExKTOTi3JyanLS2tPz6/Pz65KyihJSKbMS6lExOTNTW1JSWlJSKZMSylNTOrNTKpFRSVPz29MTCxPTmzKymjIyCdOTWxOzexOTWrBQWFFRWVOzu7MzKxJyalOzatLSulMzKtOzmxOTarFxaXKyqnPTmtIyGdIR+bOzetOzixBweHGRiZOzm3NzWzNzSrOTetGRmZOzizOTexOzm1JSKdGxqbHRydJySdHR2dOzapHx6fKyijOTixCwuLHx+fFxeXERGRDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeIiYqLAQECjwORAwSUBZYFBpkHmwgJCgsMDA0OD6UQERITFBMVFhcVGBkangq1ChsLGxwcHQ0dHR4fICEGIiMSCbS3uLq8wCQUJSYGJygpKhQJKyvLLM4Nwi0uLwUwDQsxMtmeuQveHR8UMzQ1NgU3Dgo41jk6ns0cKOzgYaOHjx9AgjTAUUvIECLZNmxoUISHkSM9KiBJQkCJA4kKEoBQoWJJAiYtmjh5AmVCsCJRpHzckKCCySlUUvBYUqUHDysSPnxIEuXKA5pPRiRwxwFLFhRaIEDYUoEChCcDuECoOWKFuwW7nHkg4WELkw8/BHRRwESpt10dU8SSHevlRxIBX6C0WBE27q8GZMkKbTADjIAwYlb4GLMYShYoPTRo6FGiSJEKPyzMIFMmzJcvXbhwkSLFjJkbQW6cOHNGhAgEAdAsmk27tm0ABgIBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmail_get-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQ6bCQ+ZAwePKTC5Ozu/NTi9GSWvAwSJGSu3JS+5CR+rAQOHPTy/AyKzES23AwOHCw+bOTq/BR6xES+5AwmTBw6ZMTW9Ax6tByi1BRGdAw2XAQCBDQuNDRupKzS9FSm1BR2vBym3EzC7CSGxBROhNTW1Pz+/OTm5NTO1AQGFNzW3Ozq7Ozm7IyKjJyWnMzOzNzq9Nze3OTa5Ly6vCQiJGReZISChKyqrAwqVBRWlOTi5MS6xJSWlNza3OTe5Ly2vGxmbKymrIyGjMzGzISGhKSepCQmJDw6PHR2dJSOlPTy9MTGxLy+vLS2tMzKzLSutMTCxLSytKSipJyenKyurJyanCwqLCwmLCwuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBhgIBA4SLjAABBAUGBwiNlY4FCQoLDJaNAQ0ODwsQnYwREhMUE5ylFYYRFhcYGRgaGxsDHJUdFR4SHyAhEyIjJCUcuo0cJr0nExihxgwoyYscKSnMHicOIw4lKissLdWDHC4vMCu9McYqMjMyNOUANTY3OPEoOTolDCszdrSgwaMcBxs9TMxYOCMHBx8zfPj48QNINQ5BbMBIIUShDIUoTAhR94PHPEEHbQwZckOGjBQviMxYUWQIDCMmdXE4gqRnkiFETAxR8iKFjJU2evZEdmLJkgJIbqS4wXJIUapImj5FtuSEVyRVV1IVi4RIChhEkLVAgcJHEqVwVJUmYdKkiRNkALMRecKECRG/ff8CEQJFCA5kMKJEoUHDCQ/HkB9LmWKECpUeyKoIMSLEyosen0OD7iH2xg1dV7BkqXGlBpbWNTq4Zn2khu0aAAwEAgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmail_replyall-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBLyejPTixPz29PTu3Pzu5Pzy7Ozi1LyelPTavPz+/DwqLPz67PTetPz69ERCRLSWlPTmzPz6/OzexLyajPzqvDw+PDQ2NMyurDQiJPz23PTatJyenAQCBPTevPz25LSajOzq7HxiZPTexPz65JyanBQ6bKSmpBwuTOTi5OzaxBRCdHySvGRiZHx6fBQSFERGRNzq9IyOjHx+fGxqbPzu3BwaHFSq3Aw6XAxKfPzy3Gy63ByWzJzO7Mzi9OzavBRytAx6vCSazGRKTPzy1AQKHBRGdBRyrDy63ES+3Cym1CR6rBwWVAQSLAx+xCyCtBRmnPzuzAQWLAwePPzyzKSCbAQOJByGvOTWvPTmxBQODFQ6PPTWrPzqzOzatAwGBKyObLSWfPTivKyCZEQyNKyGZOzWrOzWtOTSrOTGpNS2lJx2XDQmJCweHCQaHCQWFBwSFBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpkzGjhAoYMGjZMpMghQgcNFjh4mODhA4gQGkSIHAmBwAgNJEpo8KDSxAkUGjhMSEGz5gUVIiKs2PmBRQudHiwQpUnAxYsXImB0aBqjBcuoU0fKmPGChgUNH2qIqGHjg9u3bicWIFs2rYgbNnDkyGFhb8cccQ3ouJqWQo0dPFr0WMy4h48LFj4gsKriB5AeNngEaSGks+chPnwQOXFAh4oXRYxk9nAEyY7XO2wksWHDx5ATCDIoUXEBsYclTJo4cWJhuIjhSXacSPBEiZLMQY4wgRKluvXqUpyIsDElAxUqVaxcwcGCPQuWLOixaNHCZAsXBU+oqKDSxQqULF6ifNmyn/8VMOtxwcAK36kQRhdJQIFFEmKM4eCDYGyhhYAEkqFEGSuYYcUZLaDxXRpqSNRCEu6twYaFZXTQhgRd2NCCG9918AYELTjoXgNuKAFHB2RQEUYHVbQQRwlUpPHGGFwkyQUEDsgxx4lh9BhCBy2U8UQJcrSg5JIQ0FEHG3bc0QGYK+CRhx57PEGlkhM9sAEffKTQhx9+/AEIIIGoEUgLLRRFR0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail_reply-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBMSihPTixPz69PTq5Pzy1Pzu5PTq1Pzy7Pzu7Ozi1LyelPTavPz+/DwqLLSajPTetPz27LSWlPzmzPz6/PTexPz67Pz29OTSzMyurPz25LyajBRCdPzuvDQmJOzexPTevOzq5BQ6bBwuTDQiJHxiZPz23Pz65LyinPzmvBxCbHySvAQCBOTi3OTq9CweHOzaxFSq3Aw6XGy63ByWzJzO7Mzi9OzavNzq9BRytAx6vBR6tPzy3AwOHDy63Ax+xCSazCym1CR6rBwWVOzizAQSLES+3CyCtBRyrBRmnGRKTPzu1MzGtAxKfAQWLAwePPTizMy6nByGvNzWxOzWrNzOtBQKDJR2ZNS2lPTmvBQODPTatKSCbOTaxLyqlAQKHFQ6PPzyzPzqzPTu1PTivOzWtKyObPzuzOTOtLSWfPzqvAwGBKyCZPTWrPTmxNzKrEQyNOzatOTGpJx2XCQaHCQWFBwSFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpYuIDBQgYNGzh08DCR4oQPIDqEmDBhJQYRIzqQIFkSAoESJCKkDGFiwgkUKTpMwECz5IASKjqsSMlSA4sWQjG4qGnzhYoQSmF0iCFjBgmWGWhQrVHCxg2sOHLo2MGjB0sLYmsWQHq1p4wdPtqemGDhB1UDQFSouKHi7oQgQmSwUMyYxcQDZQWz2EFiCJEiRoyQyLzZyGIIB47YKLwDSRAiSZSoXq1kCRHNLBK8YGKjCYskTp4ogeKkt+8oUaBImZKAAxMmVKrctqL7ihTnz7FkAT5FC4cKFbZwadIFdxcvX8KLss8iJcoUBUcq2KgAJoxyMTy4jCFTxoxEHl2GLyCDncmWM2hUIQMPY2CXhhoTfTEcA2tgVwEba7Thxhs88FdBD/ZB8MUUHMJBRhw2sAGCHBKU4UaFc1RAhxnhcdhhHUzYAUIcFdxRAh4R5KGHinu4OIVEDqTBRx81xhGHHzD8wQYQetDRI4cTAcIHGWT0EQgZa1ApCBqDcBAID1Q94IEHLtBAAyGEFGKIIWqYYQYPYNZkQEAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail_send-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIcAAIR6fIRydHxubHRqbHRmZGxeXGxaXGRWVFxSVFxOTFRGRExCREw+PEQ6PDw2NDwuLPwCBLSijOzixPz69PTq3PTu5PTu3PTu7OTi1KyelOzavPz+/DQqLPz67LSafOzetPz27Pz29KyajPTmzPz6/NzSzLyurCwiJPz25Ozi3JyOjPzuxBRGbAwSHOzexPz23KSSlPzqvBROdISavBxSdAwaLHRiZLSinNTGxMy+vBxGZNzu9BSGrAwWJMSyrKSSjFy61ETO3BRWfPz65PTqzHTK3ByqzBSWxEzW5AQWJOTWxBRCXOTu9BSOvDzO3ByavBRKbOzaxOzizKSWlCQ2TAQCBJza7BRWdNzSxJSCbMzq9BSOtCSKrAwiPOTavPzy3LymlCySrAwmPFRKTPzy1NTGrPzu1JR+bOzatPzyzCy61ByGpOzWtJyCbPTmvPzuzIS+3FymxCSuzBR6nJyCZOTWvKSObMSujOzivAwKDOTSrNzKrJyGbDwyNOzWrMy2lIx2XBwWFBQSFBQODAwGBAQGBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpYqMDxAoYMGjZwmEixg4cPGzqA6BBiAggRIzaQGEkSwgAMJCKgnNBhQogSJlKGOFHTpgYUG0TsnJBCxQoSE1i0KErAxYsOJJRuuAAjhkwZM2jUqGnDBQoUHTbciIEjx4YNOmbs4CGjB8kCZlGAALHBx4+YcTcACcJDyFSJBo6iGNIhhQkiG8BOKGLkCBK6SSQisHoWhZIbG5bMYALECI8mTZw8gTL1QJQXZ6VMiUylSpUlVpoYaXLFtm0EGmCjwJLlA2O9MrRsccKlC8kEXr7AdgEmwtkhX2SQ2BIkjBiSYzSQr/nyhUKZLIrJJOcexvlEBV7IvCBjRkmAMzHOaufhxDvJBWiQISAFxUUQQRovJNeEGmu4JxEDbKQhXxsfuFDGGW68IQMcccgxRxUkNRDhC3R8QMQIdZwXQ11JJGFbiB+QYccHaaTxhgt13OFBDGTgkUdRDrhAhx5k2JjGCB/swYcXMXwAYk190OGHHx/4wUaVepTxByAaoPEkSQ5wwMEJZAZipiCDDJIHIYV8OZEdAQEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmatrix-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBIQChCH5BAEAAAAALAAAAAAWABYAAAJHhI+pyw0Bw4sTVmmw1C/3/20ex2VUtJ2Uwx7oBb9eR45ziNfgy6tW2+pZhJicjXbTiZA7X2q4AjqIsajSuDsuty5n9SddGAoAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmessage_get-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBFxatHx+/Hx69GRixFRWtHR29FxaxHx6/Gxq9ExKxGRm/FRW9Dw+xFxavFxazFRS1ExO9ERC/DQy5CQmzBwaxBQSpCwqLMS+xBwatExK/DQy9CQm/BQW3AQCjJyavAQCBMzGzAwOtDQ21DQy/Cwq/BQW9AwK5JSStOTi5AwKDKyurMTGxLS2xISGpNTS1IyKjJyanMTCxAQC1MzKzNza3MzOzCQiJGxqbHx6fKyqrLy61NTO1JSSlNTW1NzW3Nze3HRydKSipISChDw6PLy+vFxaXPTy9ISGhPz+/Ly6vLSytJSWlHx+fCQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBAgIDBISLjIWHiY2RggWHBgeSkYYICQqYjQUICwwNnoMFDg8QDBESExQVFpgXGBkQERoSGxwdHh8gkiAhGCIjJCUmJx4oKb+NKissIS0iHcgeLi8pzI0gMDEyLzIiM9c0NTU2zYQ3ODk6L/A7yvDnPBjqgiA5PTYvPvU+fvh4AeQFDXwgggTBwEIIOB8sakB0iO7gIH05hvToIeQFBo4eNwoJEaIZiAtEUgbhWGQjRxk9hhhJSeQXiCM4jxBxyXMjEiI5bR5JQnRnT5dDiNCgIcNmCiBAfAShSZVmECVKltgc+MIGCxlgw4pdskKHEJtMZRTJuqStW7dCImLEYGLTrJC4PeYy0asXxpAhTZpdGHzBSWHDiBPfWCzIQCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmisc-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFCQiJERGRBwaHFxeXHx+fDw+PGRmZExOTGxubKSipDQyNHx6fIyKjJSSlJyanISGhISChLS2tIyOjHR2dAwKDAQGBJyenAQCBCwqLLy+vKyqrAwODMTGxKyurFRWVLSytLy6vMTCxMzOzGRiZNTW1CwuLMzKzFxaXJSWlOTm5Nze3Ozu7OTi5Ozq7GxqbDw6PHRydAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb/QIBwSBwGBMVkMjAgFAwHBFJpPB4SiQJCsWAQqEJB4prdNhQNx7QYIFwLD0ikQZdMHgelOPGYULQVDg4QEAVfRAEBBwUTEE0WFwcYhAuNF0QDBQULDwwZGUIaEAuVGxgBRAIFEhwHHUQMCxwTHAVrAAwFFRwKFkQZsxseDqBDGXMSHwfFQiAhIiMeJApEBwcOcahDJcLSJCYcGkQKcRAnQhkF0SgmEykHXkObox8q1iEjKN8rENqYD7MmeBCmzwSLFS1I3AqzYIPDESS+sWCxgQMLEgOSJKjozeAKFyskCDigQFwSBhJMjDDhAlyLFyVA+dIzAUUKEi0eaNhAIg8YGiEMenkwASNDDBkLqRQAEEAkup9KDkEFACUIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmove-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAI6hI8RyJ26nAQQzlbrdWrP7nHRNh5gwpxmaZxWylJdRtf2fcux2rr7n8LsQrxQzyhE9mhIplKjPE5wBQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnews_subscribe-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAASC/Dw6PAQCBHRydPT29GxqbCQiJPz+9PTy9JwCBKwqLPz6/GRiZERCRPz+/FRSVDQyNBQSFBwaHDQ2NKSipJyanHx+fMzOzNza3FTCFGRmZCwqLAwODLzqpCwuLExOTLzqrFTGFAQGBES+BETCBEzCDDSqBBQ+BLTqnBRCBFRWVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb0QIBwCAgIiMgkckAoHJVQgEFAOCCc0WThcEgoDgvGMztFJLiJ83Ws3C4ODIY1jUCIlQ0Bd+FwMLZmCXV3Qw8CCAICfW9wBQhddVgAEIcCCwuJDlxWBQx1AhFPjlyJlwISj1ZWBJQTAImIerGqVwgEiAwUR46ysAeJcKoEoYkTVLGPvrWVDBUWEwEXF1aziMGfAhhiAhAVFdKPyMux2YkAEc3fF3WcdQTAGYkQQxAF3uAIGggbCBwCHfEEeEBiIB0+BB8cgHAQogMIKPXurRMxgkQJExjZELT3jUGDEyhMpDhxIouUOB8qqAhZ0iS9CJMStTQQBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnext-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBOze9ORy7Pzy/PSi5LQCvNSG1JQ2nNx21LQCzMRGzNRy3KQCpLwKzAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq704axC671WAfR8VCOKUbudApCBHksVgHO+5agFiHwVBAuYZ+RQLBmLHatgMS8mMyREsDI7oRipEeLWsKVG8Fce26EspzeaR2vDQNE7PGCIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nopenterm-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIcAAPwCBAQCBPTy9PTu9Ozq7OTi5Nze3OTe5Nza3NzW3NTS1MzOzMzKzMzGzMTCxMTGxOzm7AwGDBQOFBQSFCQeHCwmLCwuLDQyNDw6PERCRFROVEQ+RDQ2NLy+vKSipISChGxqbExKTOzu7OTm5Pz+/GRiZMS+xLy6vBQWFLy2vCwiHFQ+NMSmfNSyhIxmTDwuLJx+bLS2tCwmHMyyhMyqfPTqpPzyvLSWbLSWfPzitIx+ZDw2PAwKDCQiJGxWRPTmrPTerMyuhPzqtPz63PTWnPz6zNy+nIRiVDQuLKyWbOTanPz21NS2jNS6lDQqJHRaTPzmrPTSnPzyxOTClPz2xNSuhPTqxPzuvOzSpAQGDOTKnMy2jOzSrPTu1NzKnOzOnBwWHJRuXLSWdPTatPzqvNzClCwmJOzSnOTOnPTuxOzKlOzerOzarOzitJR6ZNTO1IxmXPTWrNSyjPzOjPTSpLSehHRqZOzirOTCjPS+fPzGhOy6bOzKhGROPMy2lPz+1PzmtKRyRHRiNNTCdPz+zNzCjEQ2NKySdDQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAj/AAEIHEiwoMGBARIqXMhQIUIBAwYQIFCggIEDCBIoULBgAYMGDgIIDEBAwMSKBRBk3NjxAciQIwdACBBBwgQKFSxcwJBBwwYMHBx0EAmA5EwPH0CEsCChoYgOQ0cSGCHhA4kSS5syJGDiBNEAFVGUKKEBAwWFFM6SNJHi64gDFEKE4FBBggoKK1i0cPECxokYXw0gsECYggQZM2jAqGHjBo4cOtqOxLhDAg8ePXz8ABJEyBAWRIoYOfJipEoMCZEkuaFkSAslS5jUGJKkSRAnRREo0JDwCZQoTKQAmUKlihQrVa5gKZ1lI+oAK7QM2cJlSZMuU4Z4+TJEx0iNOwKAggkjZkyOFmS8kClzpcUQLRRGbjRD4MgZNEzSqKG+ZgobI2248dUbDDDwABzcxSEHEFpgEcUcdMRRhx1fFejAAx0cgcYdSxiBRx566LEHH0d8QFRRNC3Uhx985CHEH0MAEkhCBxWkgiCDFEFIEYUYUmONMhyCRxVH/PgjBYioYJAdAQEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npaintbrush-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBMTC/AQCtAQCdPz+/MzKzOzu7KyqrCwuLAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARZEMhJ6wxiDMsp1lvHfRohWuRAmOeVlUTQSukqz3U8A/nd9rtCAWTbAQoGg0q3OyANCOYPA0UgfCdMJnHFimre72sZ7pBWiTLqRUirK5hV7A0P2O3GvD5PjwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nparen-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBIQChAQCBBQSFCH5BAEAAAAALAAAAAAWABYAAAJThI+pGou9oDuS1hlqnkxu/niVQB6kYHzAiJYoUK7paLrxpr6GMJjWeqlFGirEaQhcDHQJnEQX2/1kMBv08Yu1ttNkFRr1ikHjIiYYjDjSWLIbUAAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\npencil-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAASC/IQCBPwCBPyChMQCBPzCxAQCBPz+/MzKzISChKyqrDQyNEQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARYEMhJ6wxiEMtpIAWxddwXiqRlikSQeiAbuC+wirNR322gv7zcLobzDU+9XypoBBKTR1lz+RTWDgip8nUwZK1XLyIx5XoVicX2RUAo1DVKi7GOBxjxfNwQAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\npercent-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIzhI+py+0P4wkU1XfDhBdo/zndF4qh1pkGKYFk2XpTqoJr9G5YfmOz3hixfBZa7IhMJg0FACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplayer_eject-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAwKDJSWlFRSVBQSFKymrOzq7HRydERCRPz+/MzGzISGhJyenKSmpGxqbJyWnJSOlKSepLy2vIyOjGRiZPTu9IyGjLSutFxaXExOTHx2fGReZAQCBAQGBBwaHCQiJLSytKyurJSSlFxeXNze3LS2tIyKjFxWXHRudAwGDBQOFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa1QIBwSCwaj8ikcqkMCJjHwIBQgBIDhgMiUbVKFQsGItBdBhpgh4PxIJvRC8cA4oiMy8bvQhJhMAYTFBVOURAWEw0QFxcMERAYCBluVxobDxkVHJocmBwEGgmEQx0dHh0CpKmkH6odVlanBR8FtAIFtiCkSB0LISEiGCIGIxAPDySuRwIOBwrOzwoHJRHJRh0jJgMj2gMnERQUCNVFHQQoCBvo6CkICATjRB0qp7b1K6qv+foyQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplayer_end-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNFxeXAQCBMTCxGReZBQSFOzm7AwKDKymrJSSlFRSVCwqLLy6vPTy9OTe5Ozq7CQiJLSytOTi5BwaHPz+/HRydMzKzKSepJSOlKSipJyanIyGjIyKjKyurISGhMzGzJyWnHR2dISChIyOjLSutDw+PERCRHx6fJSWlIR+hJyenGRmZHx2fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa6QIBwSCwaj8ikMBBQKgOCgRMZIBSkxYHWoDVWD9EigpBQLLBERsPxCA8NDUhjgTBGJJNGG02RVBQWdUV3FxgZe0IGfoAGdhoXGxwdiAYef4FGFBoeHB8dGSBRihUhIo1FBhkbIyMkJRYmAwYal4JEBh2RChIWJ1IIGxUZFqdECCgkHR6wWAYpFR2YWSobvL5vFgfDaEMDIivMRBEsD9HcQgMWvecDLB0tZ0btsfJa9vLXU/X6/P3+b0EAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplayer_pause-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBAwODMTCxKSmpJSWlFRSVAQGBBwaHLSutOzq7Ly6vCQeJPz+/Hx2fBQWFGxubLSytJSOlBQOFAwKDJSSlJyWnIyOjHRydNze3GRiZAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWBICCOZGmeaKqubOumQSDEgRjPMSoMRGEcol3vh0IkFAtDDWBEKlGMRKPgEIii0yrqIS1ArADu9KuLNCSOSdCMVp8ohEZFC4DL6SaBpXGh6/l4JX8XZACDhXkYCn1LAoqMUBAZEhBLDJKUSyYBGmhPAJyemiU0NDaloy+qq6ytI8whACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplayer_start-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExOTAwKDAQGBJSSlHx+fBQSFMTCxKymrFRSVOzu7GxqbLSytLy6vJyanPz+/GReZBwaHHRydKSepKSipGRiZJyWnAwODLSutKSmpISChPTu9ISGhFxaXJSWlIyGjJSOlERCRIyKjDw2PIyOjLy2vOzm7Dw6PLS2tCQmJOTe5GxmbDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa7QIBwSCwaj8ik0hgQLJGBgbMoqBIKU2LAcMgOEQmFYeEFbBmNMgDhYDwWBC0k4pCoJ46IgRIXBioRCRYXamwRGBQIfgaBFhiERhkaenxmCoEbBhyQRYaIGVsdghgem4UWegcEBB8UHhsgIaZGBBgRIpUIIxQhChginEQIIBEklWslFyYnBsFfFCi4WQgpFBwqFxNGKxcsxl4IAS0NZEYCF3vlwgEfUuZV8JEuI2pPAARN9kcE9fr+SwaCAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplayer_stop-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAwKDBQSFBwaHCQmJJSSlISChJSOlJSWlGxqbGRiZNTS1PTy9Pz+/Ozm7OTi5FRSVIyKjOTe5MTCxIR+hExOTHR2dLy6vLSytLy2vHRydFxWXIyGjIyOjPz2/FRWVHx6fExKTMzOzJyanKSmpKyqrKSipAQGBLSutHx2fDw6PAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa1QIBwSCwaj8ikcslsAgKCAWEQjQ4KgSwyYDAcugZEQqFYYJECA6PhaLcfEEUkgJZAGJB8fkKpWOhHAxcOGBQZGBoaGQgbHIBGAhUOGR0SBxISBh4Xf0iCHxQSlRIIXhsgj0UCIaCXmJgHGyKpRJ+hmB5dHQqOaCENIx0epBIkBhdzngoPGCQlJifQJBvJRygRKRcKGxcXGypys1srEREc5SLnICLiR1koLFVUWfRO9vf4+UwyQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nprec_minus-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBKSipPz+/CH5BAEAAAAALAAAAAAWABYAAAJAhI+py62RgnRnGguZ3BlTYIHdl13jh3goFpIleggvTK8ctw76Pswav/MtAkCd8NHj9HLFY6S4JEGdqdumtjAUAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nprec_plus-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBKSipPz+/CH5BAEAAAAALAAAAAAWABYAAAJHhI+py22hgjwSonktxBZU7GnhkyXc6JmmeDpnG2lg1YCOInT3zrvfxwsMhsSBrkYUDo8MpTEZNH6M0SV058xWi1Tsj9ZjGAoAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nprevious-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBOzC7PTq9NSG1MxW3LQCzNRi7MRGzLQCvPz2/NRq3ORy7HQCdJwClAAAACH5BAEAAAAALAAAAAAWABYAAARUEMhJq70Yh813rl1HheInBYIwrEJwktxJFEbRmuOBJIXivp5LQLcj+HCnBaPBMBhdMBBjw0w8ccEA0/EzdQHaHywmnIyDyDSIrG4LQ+64OSqvx+kRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nprod-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBIQChCH5BAEAAAAALAAAAAAWABYAAAI7hI+py+1/gpy0hlVRZlP19mmSE0YjeIoXuqpkarYYbJQeDdiJrrs77gvOZDVg7Eb8JXtFSpMJiUoB9AIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nqueue-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIIAAPwCBAQCBKSipMTC/Pz+/AAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAANfCLrc/jDKEGQMQlDLKM5aZQXDQIHZ9nhleaLqEhAE1bofKCozXZO3l0bmK9qCQ2LRCDQlAb3lkoTZQaVS6jOKpWmt3O5X2fU6wWXfuBM2mmINCpbKkavho56VI9s7DAkAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nredo-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCReDJzGjMzivOTu3Pz+/JTWbHy+VHTCTMTivPT69BxGDESuJDyiHESiHEymJIzKZAQCBFS2LFzKNGzWPDRqHCxqDFSqLHy2XESCHAwaBAQOBBQqBDyWJHyqZDyKFGSiVESeJBQ6BAwSBGTGPFyWPFSSLEyOLESGJBQiDAwiBBQmDCRGFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaoQIBwSCwaj8hkMcBkKpcBwYAwEDif0YLhwEUkFItFMkAwMBoOR+PxgHwjRDggamhIJpQ8ZbKGKOQLcgEFdhUWEYgRF3sNfhELBHALAhgZFhobRBwREhQdEAIEHpIKHwsaSJwUDQgQIJINARxKESESDQ0dgCIjSpAkDAwPco+ZSJAlJicnKHIAIrNHidOIQxunT0kpCyrZSCss0d5Fj6jjRonn6uvs2QZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nreload-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBCRSFCRSHBw+DBxCFCQ6FBwyDBQWBBxGFCxyLGTChMzqzLzmvHzKjDyOTER+RERyNDSqXNzy3LzivFS+fCyCPBQmBCQiBBxKFBQqDOTy3LTitES2dDR+PCxuJOT25KTarCx+PESSTCxKHDSeVCyKRNT21ESWVDSGPBQyDAQCBBQSFDRuLDSyZDySTGzChCRiJKSmpExKTDS2ZGzGhLy+vGxqbISChDSKRMzKzGxubDQ2NIyOjCQiJCwqLBQWFCwuLKSipERCRERGRHR2dAwKDDw6PFRWVIyKjCQmJFRSVBwaHKyurAQGBExOTBweHFxeXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf9gACCg4IBAgMEBQYHhI2ECAkKCwwNDg8QBAOOhAQREhMUFQgWBxcHGBmbggkaGxwPB4yDB6SbBJIKHQaqtY0eHyAhsqrDgx4aCiKpqoQHAyMjJBMKJaSxzAAHIRsmJgonKA0LHSmDKiuOBywRLSQuLyEwwyoxMuiN6iUzNBXy5jU2bsgoJugABBz95uXQsUMGD3vpPPgTpKIGwx4+HMr4kW4YkCA2hAzxAQSIECI+imBTwVIFESNHerRUgc0cEiFHkjiiyYzeDiVLdvLcySSkkKGEWiZVweSGkIHMmvQosoQlkaZOjvhosvKJjIAxoOAsgpRZkQNLnvSoqspAIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrevert-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAAQCBPwCBPz+/BQSFPTy9CQiJNTW1ERCRLSytAQGBISChMzKzFRWVDQyNCwqLMTCxFxeXOTm1KSipPz69BweHHR2dJSWlMya/Mxm/GQCzOzWxGRmZPzOzMzOzMzOnExOTDw6PNze3Ozq7OTi5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAWABYAAAbrQIBwSAwYAwDjUCloOgUDQlJJFCKfzoLAMF0ih9jmASGQfq3IBECgYC8YCsah4Rgc7+Bw2fCY4pNrCg8QboIIEX5HXXoEjWZ3eAIMgxITcRRVmVdOE50TBRV6TkJsD3EWDBUOoRcXGBmwsAJqT44aoKJNtAoVDAwWFRUFGwKxxhkCQhMEyxEcGrfEuWoGBgsdDwseHhQQvt++Hx8HmUQU4OHiICAJkHcDDB8hBCIj1QYfDomQAOIiHwxCPBiYr507JeNGAOQz8IC+g0YKrAtxAMQDBBgPFDB4EACIAwIHDkQAAhNEKuUStDMQBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrightjust-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIhhI+py+1vgpy0Toizjvbur3WiBJbhSJnqgorri7nwDBoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nrsub-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBIQChAAAACH5BAEAAAAALAAAAAAWABYAAAI+hI+pFu3f1gmSVUBrlnt19SUhMk5XaWnnqrYc+2rQfNWHIBi4feP+zssBdkJez5gAIodDYbH2+yGBymXCUAAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nrsup-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBIQChAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAI6hI+pyxBhXlOv1omggxon6VFdGG1laFmkyQLCC8fvJNB2U+M3k/P70gP+FEHiMFFEHhFJJk0GXUkNBQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nrun-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBOzq5MzOzPTy9KyurNze3PTy7IyOjOTi5MTGxNza3MTCxMzKzHx+fOTm5NTSzNTS1NTW1FxaXAQGBLy+vJSWlGxqbGRmZIyKhDw6PAQGDJyenAwKDLy6vLSytBQSFLy6tKyqrHR2dLS2tJyanJSSlISGhKSmpCQiJISGjCwqLBwaHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbcQIBwSCwaj8RAAMkUBgSDZdMpBQQIharyGDAclsoDYhtIKKrDwMEgUBMWiwSj3HCg0w+DfgGJQAYSDRMUTAELBhJ8fw0KFXdJBwkLEhYXGAUNDBUZj0pXkxYaARsIDRUMHJ5pAgQHkxEYUh0JFR4fHAVZTgMFCAt+sUIgBB4hIggOI1pKCQO8CB0gAgYkJGNbRQEKEYwNCa7VIhOPaRAKCpoV1QUl5E5mDJrFJAW4JuRlCuMnKB+94yVQ2DGi7QSYABcQgACTDF+VFChULJsiZIUCiRS5sMjIsQidIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nshowmenu-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBBwaHERCRIyKjBQi/ERO7HR+1Ly+1Pz+/Ozq7MTCxOzu7NTS1AAAAAAAACH5BAEAAAAALAAAAAAWABYAAARkEMhJq7046z2D/2AoDAQVFGiqqsaBmGH8jWWX3Hiu3+YdKglPMIDrDXc+Is92zAmFi5pECWIkjySj0EkUZplb3JP4nV65WCmAqhR3yeo2Emmc0zsyGc3U6Pv/gAAKHISFhoQGEQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nsignature-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAISGhISChHx+fHx6fHR2dHRydGxubGxqbGRmZGRiZFxeXFxaXFRWVFRSVExOTPwCBAQCBMzKzMzOzMTCtMS2dJSCTCwqLPz+/PTu1MzCtERCRMSydPTqxPz+9Pz6/MS+rNzKlKSSVOTarPz69ISCtGxurJyaxPT29MS6pOzmvNzSnHRyrPz29OTi5LyqXOzavMy6fFxanHR2rOzq5JyKTOzizPTqzKyWVGxqpPTy7LymZGRipLSy1PTu5KSSZFRKLExKTGRaNPz27PTq3LSiXPTq1GRWNDQ2NMTC3FxSNLymXGxqrPzy7IRyPDQyNCQmJGRinJSCdHxuVBQSDPTy5PTm1IR2RJyOfKSSfBweHGRenFxepNzGrKyejNS+pNTCnNzCpLyedBwaFBQWFNzOrOTOtOTOrBQSFOzStOTKpAwKBMS+tMS6rMS2nMSylMSulLymhLymfAQGBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAA8ALAAAAAAWABYAAAf/gAAAAQIDBAUGBwgJCgsMDQ4OD5MPEAEREpmYmJqaE5IPFBUWAxEXp6ipqJ+TFRgVBaaqsxcZGhUVGxwdBrK0qB4fFSAhIiMYCLIkJSa0JygVKSIhKSoJvhcrqh4sLRUuKR4vITAL2DGpMiMzNBs1FzYiKjcMER6oOKglLDkVOinwRMCAAcKBrx33eMTwkKPHPx8/RGxwEaICkIMXcOBgMaJfCgw/fMCgWCGIhoMlSOQQkmMIkSJGUoysGOTBEVlIZMTg16NHhSJJZCqhOenmqSU5cDDB0JJIzJlNak5yYoqHDBY7hmgN8aPGhhslKU16EgHJDiY9oGz9EcJFkChSaKaIfUC2I5UhMarU+GElyJUrWHzIFZslAtqWVbRs4dIFi5cvYMKImTsmQs8qVVrUePGCDJcyZkCEGUzpTAQMmGts5ozGTJo0XEbPVTNhDRsUbdy82Q0HTpwwwNXMlQOhuPHjyIWLNRAIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nspellcheck-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAASC/AQCBFxaXBQWFAwKDPzCxPwaHPwiJNQGBOxKTPQ6PNQCBGwCBPQ+POwCBPwqLMwCBHwCBBwCBFQCBLQCBPwCBBQCBCQCBPQCBOQCBDQCBFwCBJQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWGICCOZGmeaAoErMi+4xuQgQAI8yoKw2rfOZ1LRIgJh0hhDncsyXKypNMIKAKbNGpwFjxukcza7jt8xmCAgkpVMKxRhQOCnTAVFAtGqtBwLEgFDxAREigBExQVFRAibYNdJhaIigmODBdvF4gYDwoZDBpvIhKIGYOFoi4bHBGQogESqKlvBiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nsqrt-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIIAAPwCBIQChAQCBBwaHAQGBAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAANPCLrc/jDCQKutkcqQJeCP5k3g6IjCIAjAynYt0brzUn7gW++i0i8CGcNiuyl0NlyysYKhXgQdUvmcNZtDTo/mmvo+ptMvjDOSzWey+mFIAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nstart-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBCRGZAxCZGyavExmjHyatOTy9CxihISevPz+/KzO3BRylAw+XDRWbPz6/FzC3CSuzDyexJzO5Mzq9CxSdAQOFISmxNzu9HTS5BSmxAyexDSuzJTa7Mzu9Kzi7GS21CRmjAQOHHSWtLze7AyWvHzG3BRihCTO3BS+1AyixBSWvBSOtBSStAQWJDzW5BTC3BSqzBS21CTC1ETW3AQSHEze7BRqlBRmjAQCDBR+pBRefBRSdAQKFAAAACH5BAEAAAAALAAAAAAWABYAAAa0QIBwSCwaj8ikMqBcMpsCQTEwIDQBUWKgYHgqs8LAAZGwQqWAgGLBaDgEj0Fgjh5mxRBERDKhICAQFRYXRVEBGBAZGhscHR4VHyAhIiOFAiQZJRoSGyaNJxQnEyiVRFEoGykqKyYsJiYtLi0mKC+WFygrMDEyMzQ1wDQqKDaWADYoMzcqsjg5DSgoBISmaCOoMG4v29s2OsZCyDs8DldgQtc95WdFPg7rV0Y+XvHt9ff4SXRBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nstop-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAASC/CQKDBwKDCwODNyKjPzq7My+vIxiXAQCBOSOjPz6/OSelNySjNyGhMR+fLRaTGQ2LPz+/Nx+dNR2bNRybMxuZMxeXMxiZLQSFJQaHFwqJNyKhOSCfNyCfNR6dMxmXMxWVMRORLQODOR+fOSSjNR2dMQ2LJQWFMRWTLwWDNSCfMxeVLwaFKQODNR+fNx+fMxiXKQSDOSWlMRSTMxaVMQ6NMxORMQyJOTS1MxqXLwWFLRORMxKPMQaHMxKTLQWFCH5BAEAAAAALAAAAAAWABYAAAb2QIBwSCwajwGBcikIHIsDQmFKNRwQT2EgoVgsGOCG4wHBIgmRhWRCqVQsF0xGYyYGNgoGh9PpeCQfICEic3UAAWgLIxwRJBsbHSUREyYYJ3RDAQULexGejhueESgpl3WaCxsqJKKsChEUKywtmFoFDC4vCayikzCyMbWHt38NCTKiHhUfMyzBdQIFKsodob0VNDWzwppuKxMRrx6iNjcitNA4bh+iEzkwojc66JkOOxcf7G35PBE9KS1MEUGgIQOIFfk++KjRw9wJgUUIZvhRoyLDFCliQDQisUWLGCJOeNx4hKCGkyhPGnqCoKVLl1liypyZxUAQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nsum-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBIQChCH5BAEAAAAALAAAAAAWABYAAAIyhI+py+1/gpyUMrvm1bdhFTgfhIykYZ4pyZ2o5EZwDLSurc7ZFnqZDgLKKsQe7QihFwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_block-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUWzvNzo33GfFl5jVlonlTrr1DbvFi9vjeeNUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_bold-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIxhI+py+0Powm0VnknjVkH2AEhE45LZ55Wqn6e65TsMc5eYosbksswubJIhsSiccgvAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntext_center-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUbz3Sh7yIWfFHKjVl4nmFrr1Lpr7LwkjeeIUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBBwaHAwKDBQSFLy+vLS2tJSWlBQWFKyqrFRSVCwqLDQyNNTS1GxqbFxaXJyanIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAVcICCOZGmKQSoMaZsShBsQBdAapHvgaIDUqUPJlRjSbAoT0fRDKgODRbF0PLUYjZO2F2Bst9evNix+dsvDlGKK5jraudQb7qbX6a2HEJ+ycyF+LRE8ZTI+fX5oGCEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_italic-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py+0P4wqUSlQvttrkDnyaOHIdeaGRupplAIauVM3xjeeOUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_left-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+pyw0Bo5zB2UXz3Sp7yG2fFJajVjonmIor2TJvfL0wjecIXQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_right-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUfz3SZ7yIXdF4kWqZkbCqoMO7kXLC+wVOe6YRQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext_under-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIvhI+py+0PowmUnhpeVVnb1DkbCI1I2JhX+Z0sOr2cTHpwK7a4rUr+hAnufsTirwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntoggle_log-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIYAAAQCBAQ2NPwCBATW1KSWfBweHATS1Pz+/Ozm1GxiTATOzPz6/Pz69ATGxKSahOzaxPzy5HxuVLSmlOTazPz27AS+vPT29NzClPTexHxuXLSmjAyKhPTy9KyehNy+lPTy5Pz29HxyXNzWxAS2tOzexPzy7IR6ZASytPTy7ASurPTu3KSSdIx+bASqrJyOdIyCbASmpJySfPzu3OzizJyKbKyijASipJSGdOTWtPTq1PTq3NS+lJySdOzWtOzi1My6lMS+rOTOrMS2nNTGrNTCpNzKpJSGZKyafLSifIx+ZHx6ZFR6bFR+dAQyNAQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAWABYAAAf/gAABAoSFhoeHAAMAiI2IigSMjoQABYkGBAeSjwAICYkKmQublJ0HDJ+GAA0OB66bpq4HCQC1lA2ZrqMCAA8QBwvBERITFIwAFa2yFgAXGL+uDBkaxRu1FQQLshwdHhgfDK4gIRoiFNYAI8quHA4XJCUMCwwMJhLm6Ce5rigEzhAMQICwYKLcuVopWgUDoWLFhQcfKNCjwOLeQQAtCFDYiAKBC28QKITk8MIgOhgxIHyQIWOGi4cfIHAogYJGjWq1bNzAkSOHjgc0dmBAgQKCUR43S1jjVeFGDx8PcNAAKePDjxg1gOCThOxFEBxBgpJQMQGpkCETEIBYSqkpkSJGOYTyOCJkgg4OIDaybXvjh5ELLpAMUYEAgQ7COPbyTWJEiY3HkCOTaruESYVamDPbQtTESedJhOgEAgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntop-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAw2VHSWtBRihAQOHISmxNzu9BSmxHyatPz6/Lze7CTO3AyixAQSHHTS5BTC3DzW5ByyzPz+/OTy9AyexEze7GyavKzO3FzC3AyWvBSqzBR+pAQKFCRGZExmjCxihBRylCSuzBSWvBS21BSStBRSdAw+XAxCZDyexDSuzCTC1BSOtJzO5JTa7ETW3BRqlAQWJDRWbOT2/Mzq9HzG3BRmjJzS5Kzi7GS21BS+1CxSdCRmjAQOFAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaoQIBwSCwaj8jkMMBsOp3Ip7SpHAoGhELVKDAcENmtNaFYMBoEh1hAPjwgEUlYyZ5QHpIKxALWIgUXFBgZCBUaG3AcBB1HAh4fICEiFRUjJCUhBCYnjEQCAignoikqhissKAKiJwFJAS0uKhovMDFiADIzNDUsLza2Yh4KNDcsEbW3Ago4NSUrBMBbAjQ5KRo60Mk7PATdKH5bAT0xDg4xPa236uvsShRBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nundo-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCReDJzGjMzivOTu3PT69MTivHy+VJTWbIzKZEymJESmFESiHDyiHESqLAQCBFzKNGzWPFS2LNTmzCxqDDRqHPz+/KTGnBQqBAQOBAwaBESCHHy2XBxGDOzy7HTCTEyyJDSqFHzWTAwSBBQ6BIy+dESKJFySPFSSNAwiBCRGFBQmDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAalQIBwSCwaj8ikMsBkKotMwYAwEDiXgYLhwD0gCFZiQKxNKBYMRqPh+D6G16y5AYnYIxBJAyF4AwITTAUJdBESD4gPFBV6Fn6ABBcJDIYPGEQZGhQbHAIdfx4JHw2VSBodGwWfAR4LDSALfkgYAQurBiAhICKfSSMkvQElGyYnGyi9Rxkdj4nOskUYyU9FpxnURikdGtjRKivdRKfQ2Inh5+jpRwZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nup-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBHSWtBRmjAQOHISmxNzu9BSmxBRihHyatPz6/Lze7CTO3BSixHTS5BTC3DzW5ByyzPz+/OTy9AyexEze7ByixGyavKzO3FzC3AyWvBS+1BR+pAQKFCRGZExmjCxihBRylCSuzBSWvBS21BSOtBRSdAw+XAxCZDyexDSyzCTC1JzO5JTa7DSuzETW3BRqlAQWJDRWbOT2/Mzq9HzG3JzS5Kzi7BSStGS21CxSdCRmjAQOFAQSHAAAACH5BAEAAAAALAAAAAAWABYAAAaeQIBwSCwaj8ikcqkMCJjHwIBQgBIDhgMiUbUGFAtGw0GFfheHByQi4S6/E8pDUoFYLm5kAEPJaBAVGxIcER0JHlEfICEiIxUkGyUmIgknKIhXASkonCorgSwmKQGcKE9IAi0uLxUwMTJWMzQ1NiYwBLBQHws1N7avXgs4NjkcCblMATU6KhvGyG87PAnUKV1MAj0+2zIFp1bg4eJJdkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nview_choose-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBFRSVExKTDQyNPz69PTq5Pz+/OzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq70466Cl+AMxBVwnFIVRAmQHCIeBrC1L3tQgJ/SaEbeeC1PLBHE2ybFI9A1HzstHEIK6YCmhDTmBybQaHYJn7QC5zKeytIQe1+pKNE6P2yMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nview_detailed-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz+/Pz69PTq5AQCBOzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAQ+EMhJq7046817+MLQUQFRGMc4lQaSAkcMx3QltMmrDrSu/sCgEPgJhIiFk89DaL1qPRnlhsgBebWhdstVESIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nview_icon-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz69PTq5AQCBPz+/OzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARWEMhJq7046z2DF0PlBeAVEERhiKhqHgWyUgEsX0KczFOO7JeBYciTCImc5ITIXDKHyqhU9AnRqq9UEVDTvmLbGhin2/qAliOUot5OLc81IO5+2+8WewQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewmag--22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAbKQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/47vrq9P3s/avno2BBf/MCClSob4iBIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmag-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbIQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/47vrq9P3s/cunr9S8gAIRFhTCLAgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewmag+-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAbQQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/4zT766vRI+fvHD4CPgwcJ9qg0UB85JA0dDjEQBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nview_multicolumn-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz+/Pz69PTq5AQCBOzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq7046813+MJQfUF4BURhHGO6noSBsEcNoDJtS4KcsJQe4ncZ1HYT47HDbDqfUAnJRJmKLIGCCjjJbmE5wBI3EyOFxKCPS1EiJW52dE6vZyIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nview_sidetree-22:actions actions22 22:photo:22 22:R0lGODlhFgAVAIUAAPwCBFRWVFxWXFxaXExKTNTO1NTS1Nze3Hx6fLSutMzGzLy6vMTCxDQyNMzOzPT29Pz6/Pz+/PTu9Ozq7OTi5Pz2/Ozm7MzKzGxmbIyKjAQCBPTy9FROVFRSVPTq5OzOpMS+xPzu5OTKpExOTJSOlOzu7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABUAAAb/QIBwSCwaAQFBcqlsLgcBAnFQqBqqhwIiUVB4F4wGMeB4QMyPSCFQkEwmlMlCPKRC7pCKmjpxTyxzUwVmEBF6FxiDbxZyUnUFdxERhQUZbX4TDBlEAgUVkQ8DogEDAqYBTwEaAw54eQNusRMPs319Gp0PFZ8PAhMRGpLCwxOrFw/IFRuwwMICHAIEkhK4lxK0A7/Bkh0RHtvFAwp9D27MGugRAh4f29TithIW2c2SBOjgqwxv/AIS9cOEvQPBiBEFetsidOhAQFqEcCDgWLBAwR9AARFCuMPFAMwCEAsQpuMQQkS+EQ1SNkBAwuKwe+kiUDuSzU0JPyUm5HSj4Qi+Bp9A8QEIAgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nview_text-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIkhI+py+0Po2ShBlOxzbP7n2yaJoLm+ZTcxqHuC6hXzML2HVEFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nview_tree-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBFRSVExKTDQyNPz+/Pz69Pzu5PTq5OzaxBQOFOzKpFRWVFxWXOzexPTexCH5BAEAAAAALAAAAAAWABYAAARPEMhJq704g6A779kHCORAgNskFMYhakE8FkjyBcoWv+JwJItXaELYCTFHlCSpZKKcoB5jYHpOGgUadLKbIRw3jhEzQDyCSuI4zW673yhDBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nwindow_fullscreen-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBNTW1NTS1MzOzMTGxLy+vLy6vLS2tKyurKyqrKSmpKSipJyenMzKzMTCxLSytFxaXPz+/Pz+9Pz+7IQCBMzOvMzOtPz+1MzOrPz+5Pz+3MzOpMzOnMzOxAAAACH5BAEAAAAALAAAAAAWABYAAAWxICCOZGmeKBqsbOu+rjAQRFEYxoEkibIwjUZMRnAUHjkEpPcLriLQqHQ6XRUk2Kw2O+lSKIUVoUKubLflikVcPnO75cvKkXZL4HG2pK31lilqc1lmfRNfgBQYGBlidl5fGhobGxqMAQNnXYaQkZOLjVgVmpsUkRoVnpZje2SkphtlGBUcbH+br5NptAF0rYe4G4plHSseaaW4irLDcxYOFtDRFhnU1B3X1zDa2indIwYhACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nwindow_nofullscreen-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBNTW1NTS1MzOzMTGxLy+vLy6vLS2tKyurKyqrKSmpKSipJyenMzKzMTCxLSytFxaXPz+/Pz+9Pz+7IQCBMzOvMzOtPz+5Pz+3MzOrPz+1Pz+zMzOpPz+xMzOxMzOnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbKQIBwSCwaj0hkYMlsOp9OwYBAKBQMhgMikVAsGI1GVEpwFB5ZBKT7DS8j8Lh8Pl8WJPiJfr/PTygUBUsEEhV4h4h+ExUUFoMVkIWJhxWLkBeDhZCGiXqbFRiYAYSanId7mxihSwOlphJ6gJ8ZGksOiqd/gKoYGRmipIh7gBSqvhkbtaOuw7sYn8mseJuxxcabGxwdmZ/EvL6f2o+Qz869yBUem9sBH4sYf7znG/Qb6h4gSx8fDh8W/wA1CBTYoSCIfFASQknCcIiBIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nwizard-22:actions actions22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBNzaTPz6BAQCBPz+BExKBMzOTPz+rPz+3ISCBPTyhISCLISChPz+xOTiVPz+/MTCxKSipKyqrExOTDw+PDQyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAV+ICCOZAkEZqoKqoqKAzHAb1sIxhAQwWAQhRaJd0AcdgkhqaBAOBUL5WjAaD6TUqog0DAildqcg+cDtgaPACTCiM0AOhV6sG4DWOAHnf2uyfV1b1lsgVIwEgwTFHaGA2yKFYJgiJCSQo6JFJGGcJSalkKPn5wimZukAJWoIgYhACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/ICONS/tkIcons.kde",
    "content": "actattach16:act act16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBPz+/AQCBAAAACH5BAEAAAAALAAAAAAQABAAAAI2hAOCxg2h0nJHyEshi9HpxU1GOCLdZoKpQ15nibUoprKp9lh2oucUxsBRXsJh4Hjs/QTMpr8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactbookmark16:act act16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy+vERGRFRWVDQ2NKSmpAQCBKyurMTGxISChJyanHR2dIyKjGxubHRydGRmZIyOjFxeXHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICACwWieY1CibCCsrBkMb0zchSEcNYskCtqBBzshFkOGQFk0IRqOxqPBODRHCMhCQKteRc9FI/KQWGOIyFYgkDC+gPR4snCcfRGKOIKIgSMQE31+f4OEYCZ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactbookmarknew16:act act16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCwqLLSytLy6vERGRFRWVDQyNKSipAQCBMTGxKyurISChJSSlJyanHR2dIyKjPz+xISGhPz+BGxubMTCBHx+fPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVfICACwWieY1CibCCsrBkMb0zchTEcNYsIiYHiwIOdEAvigdFQGE0Ix4NBbSAgsWjk+jBIAlcUYrJASChnSXZSoUDelKfoKpFALJA61ueGI2IAZmhogGFmCGGAgXsifiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactcheck16:act act16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBMT+xATCBASCBARCBAQCBEQCBAAAACH5BAEAAAAALAAAAAAQABAAAAM2CLrc/itAF8RkdVyVye4FpzUgJwijORCGUhDDOZbLG6Nd2xjwibIQ2y80sRGIl4IBuWk6Af4EACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactcross16:act act16 16:photo:16 16:R0lGODlhEAAQAIIAAASC/PwCBMQCBEQCBIQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMuCLrc/hCGFyYLQjQsquLDQ2ScEEJjZkYfyQKlJa2j7AQnMM7NfucLze1FLD78CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactexit16:act act16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBDQyNHR2dCH5BAEAAAAALAAAAAAQABAAAAI4hI+pFrHb3nEg1iWiDiINCwYDko0V9XUTda6I1TIsUMpGinyzbB6ZeGuoEr+GUDL4CXqSphPhLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nacthelp16:act act16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQ6XAQCBCyCvARSjAQ+ZGSm1ARCbEyWzESOxIy63ARalAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQ/EEgQqhUz00GEJx2WFUY3BZw5HYh4cu6mSkEy06B72LHkiYFST0NRLIaa4I0oQyZhTKInSq2eAlaaMAuYEv0RACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactitemadd16:act act16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBARCZPz+/Mzq9BTC3ITC1HSyzGSivAw+XBSStIS6zHy2zAQCDFyatAQOHFSStEyOtAQSJBSq1DR2nCxunCRmlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICCOQTmeaCAMRIC+AVu47xkTBl2Ld16XQNYBQTQBVIOkMHFQJBeMI4tAbSSu2IRDSnhAvFfI97sFRM6RwOMacbjLKckVvgvIJ5EdSU7J648VgXQ7Dmd/hyJ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactitemdelete16:act act16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBARCZPz+/Mzq9BTC3AQCDAQOHFSStAQSJAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAQwEMhJq704681n+GAISoEwnGg6EAUQrEQsz4ThEkeu77kNIAagMEj0dY7IpHI58UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactlock16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJEQ+FExGHCQiDBwaDGxiLHxyNHRuPIR+TIyGZJSSfFxaRFxWJGRiLJyaXNzWpNTOnMzGnLy2hJSKTGReLKyqjPTu1NzarMS+jLSyfKyibJySXIyGVCQeDLSytPT29Ozu7OTi5NTS1KyurJSSjGxqVFxaXLS2tKSebOzuzLSufJSOXExGLGRiTExONAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwGCgGhkhkQDBoEpLKQoBACAyOUID1qTVwoQGvMPxNFgVjAxp6QCQUicSCwVgkG44HJCKRRCYUCAxIFRYXhxgZGhYbHINEHR4fGCAhIiMkFSVKJicoKSoFKwMsLZtDLison6GjLA92qCueoAUvpC2xQhWqrLYDErmEMDEXlDIwMxAHukI0NS01EzY2NAmPAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactredo16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBxOHBxSHBRGHKzCtNzu3MTSzBQ2FLzSxIzCjCSKFCyeHDzCLAxGHAwuFDSCNBxKLES+NHSmfBQ6FBxWJAQaDAQWFAw+HDSyLJzOnISyjMTexAQOBAwmDAw+FMzizAQODDymNKzWrAQKDAwaDEy6TFTGTFSyXDyKTAQCBAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ2QIBwSCwaj0hAICBICgcDQsEgaB4PiIRiW0AEiE3sdsFgcK2CBsCheEAcjgYjoigwJRM2pUK0XDAKGRobDRwKHUcegAsfExUdIEcVCgshImojfEUkCiUmJygHACkqHEQpqKkpogAgK5FOQywtprFDKRwptrZ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactreload16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCRaJBxWJBxOHBRGBCxeLLTatCSKFCymJBQ6BAwmBNzu3AQCBAQOBCRSJKzWrGy+ZDy+NBxSHFSmTBxWHLTWtCyaHCSSFCx6PETKNBQ+FBwaHCRKJMTixLy6vExOTKyqrFxaXDQyNDw+PBQSFHx6fCwuLJyenDQ2NISChLSytJSSlFxeXAwODCQmJBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIBQGBAMBALCcCksGA4IQkJBUDIDC6gVwGhshY5HlMn9DiCRL1MyYE8iiapaSKlALBdMRiPckDkdeXt9HgxkGhWDXB4fH4ZMGnxcICEiI45kQiQkDCUmJZskmUIiJyiPQgyoQwwpH35LqqgMKiEjq5obqh8rLCMtowAkLqovuH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactrun16:act act16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/ISChKSipMTCxLS2tLy+vMzOzMTGxNTS1AAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARlEMgJQqDYyiDGrR8oWJxnCcQXDMU4GEYqFN4UEHB+FEhtv7EBIYEohkjBkwJBqggEMB+ncHhaBsDUZmbAXq67EecQ02x2CMWzkAs504gCO3qcDZjkl11FMJVIN0cqHSpuGYYSfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactstop16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAASC/Gw6NGQuLHQ6NGQmJFweHFQaFPTm5PTa3PTW1Oy+vOS6tNSinKReVDQWFPz+/Nx6fNyCfNyGhNR+dMxybMRiXLxGRIwWFNx2dNx+fNx2bMxuZLQWFBwWFPTu7Pzy9NRqZNRuZMRSVLwmJGwWFNR2dMQiHPTKxMxmXMQyLMxmZNx6dMxiXMRSRMRaVKxybMxaVEQWFMQuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaaQIAQEBAMCAWDYcgkHhAJxYLRcDQBggckIplQKpaLdRh4YDIaSWa94Vw6woAHgv6AMKGPaMQhwQMJJRkfhHmEJhdvRCcgGSCEkCgpbnAECiorGYYfLCItlAAFCygQj5AfbYlwBQwVE5AukG6KBi8tMC0fLi0pHxyzcAAxFxwmMny/wEwOxMm/qlcdJCSJ1H5XQh3a28HY3kx+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactundo16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBxSHBxOHMTSzNzu3KzCtBRGHCSKFIzCjLzSxBQ2FAxGHDzCLCyeHBQ+FHSmfAwuFBxKLDSCNMzizISyjJzOnDSyLAw+FAQSDAQeDBxWJAwmDAQOBKzWrDymNAQaDAQODAwaDDyKTFSyXFTGTEy6TAQCBAQKDAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ1QIBwSCwaj0hiQCBICpcDQsFgGAaIguhhi0gohIsrQEDYMhiNrRfgeAQC5fMCAolIDhD2hFI5WC4YRBkaBxsOE2l/RxsHHA4dHmkfRyAbIQ4iIyQlB5NFGCAACiakpSZEJyinTgAcKSesACorgU4mJ6uxR35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactunlock16:act act16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaVAQCBKSipDQyNMTCxISChFxaLFxSJExGHEQ+FCQiDBwaDBweDGxiLHxyNHRuPIR+RIyGZJSSfFxaRGxmLJyaXNzWpNTOnMzGnMS+jJSKTGReLKyqjPTu1NzarLSufKyibJySXIyGVGxiNFxaXLSytPT29Ozu7OTi5NTS1KyurGxqVCQeDJSSjLS2tNTW1KSmpGRiLKSebOzuzJSOXExONExGLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaVQIBwOAwYA8SkMCAYOAnKYiFAIAQGyOgVCggYuEovVxztMpdnwAGRSCgUCwOjIeQ6HpCIZDKRUNYMRBUWF4UYGRoWGxyBRR0eHxgaICEiIyR0QyUmJygpKgUrAxMsLUQlKyieoKIuEAunK52fBS8DLiywQySpnjC1Mbi6QjIzNBeSIBY1EQfDQgosLAEUNjY3Co1DfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappbook16:app app16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBDyKhDSChGSinFSWlEySjCx+fHSqrGSipESOjCR6dKTGxISytIy6vFSalBxydAQeHHyurAxubARmZCR+fBx2dDyKjPz+/MzKzLTS1IyOjAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVkICCOZGmKQXCWqTCoa0oUxnDAZIrsSaEMCxwgwGggHI3E47eA4AKRogQxcy0mFFhgEW3MCoOKBZsdUrhFxSUMyT7P3bAlhcnk4BoHvb4RBuABGHwpJn+BGX1CLAGJKzmKjpF+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappbookopen16:app app16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBExCNGSenHRmVCwqJPTq1GxeTHRqXPz+/DwyJPTq3Ny+lOzexPzy5HRuVFSWlNzClPTexIR2ZOzevPz29AxqbPz6/IR+ZDyKjPTy5IyCZPz27ESOjJySfDSGhPTm1PTizJSKdDSChNzWxMS2nIR6ZKyijNzOrOzWtIx+bLSifNTGrMy6lIx+ZCRWRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQEAAQCwWBYJiYEAoGAFIw0E5QCScAIVikUgQqNargtFwdB9KSDhxiEjMiUlgHlB3E48IpdKdLCxzEAQJFxUTblwJGH9zGQgVGhUbbhxdG4wBHQQaCwaTb10emB8EBiAhInp8CSKYIw8kDRSfDiUmJ4xCIxMoKSoRJRMrJyy5uhMtLisTLCQkC8bHGBMj1daARgEjLyN03kPZc09FfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappboxes16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMT+xAT+BASCBATCBMT+/AT+/ASChATCxPz+xPz+BISCBMTCBAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEEgZwrwYBCFqvhs3DNYXjChRlWBRjIRqGN4UuEUczMZxsDeXykdEsDQVVSLhQxhBCkVlmXA+KVHFYhFYOoHbMGN6pTQaW8YYiQmcG+q16a0+Zipw+4e9B/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappbox16:app app16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBPz+xISCBMTCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANECKoR6ys2IVqokF08yMTA1gwkYX5WQK5ma4VceTYPxXnBWdtY6+0834/Bowgzm6APWRQcH4TiMhPK2WYRiZWW7XK7/gQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappbrowser16:app app16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxONCROfCRKfKx6LNy+bNTOpGSS1DRupAwyXBRSnPTSjPTqvOzqzMzSvHSSlKy6ZDxutAxCpBQ2XBxepLTKvPzqzPzy5OTShLS2dLSqRFR2jBRerBQ+jOTixOzetNS2XHx6XDR2tCRexBwyTDyKzOTavPzq1OzKdCx23BRKtCQ6VCQmHFSa7IyirOzSnGSGpIR+bFSO1DyK7DR+5CRixBw2VDQuHFye7IS27NzGXISuhEyS5DR25BRWxBQ+lBQyXCQqPCxSfGyu7GyerKy2ZFR+rERqfCRmxBROtBQ+fBwuTBwmNDSW9JyabLyqRIx+TExSXBQ6bAQCBBQ6ZBxapDR+zBxq3LyaLJySRHxqPGxeNBxGbCRmrHRyRERONDRKNDQ2JCQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAeygACCg4SFhgABAQIDh4MBBAUGBwgDCYcKCwwNDg8QERIThRQVFhcNGBkaGxwdoYMDHhcXHxggISIjEiSvJSYXJwsoISkpIyorLIIDLS4WLzAxMjM0NSo2N8o4OS46OzwzPSk+P0BBgkI8Q0NERUZHCEhJSktMgwk4Qy1NTk9QUVJLphCiUsWKlStYsmjZQiJgIS4KuijQ4iXAFxYCDVFJwGUFmDBhMjYSw0KMyEYoBfkJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappcalc16:app app16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBISChPz+/AQCBCH5BAEAAAAALAAAAAAQABAAAAI4hI9pwe0Ogpi00hHF2LzzzFlTsIHD45SSx6oCeW4wjK2tl83y7t64pIsJaxrfh2bEAJIlhRPhLwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappclock16:app app16 16:photo:16 16:R0lGODlhEAAQAIIAALy+vAQCBPwCBMQCBIQCBISChPz+/MTCxCH5BAAAAAAALAAAAAAQABAAAANbCLHcrSLKOZcYmDSCsR1aUABAsXDDJwJGa5SBFwgaWxbCG3CWaBwG3C8Y67FawpYiNQscg65fsVkYuoAmJs1pBR522lQB6ILJLqHRwQQOZzYdZnw+dzruDIA/AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappdate16:app app16 16:photo:16 16:R0lGODlhEAAQAIQAAASC/AQCBPzerPyqXMRaBIQCBISChPz+/KSipMTCxPz+BMTCBPwCBPz+xPzCxMQCBISCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVxICCOQGCeJjkGwkC8RFEEavkax2G8dB0QuRyhhzoBg8MSYsncJXKJZIDZHCoWP1ogGIwGrtnSgUFmHLyNRHhrdpjRamnO/SYkromHdnxwnwkKVxByZW8DgQsQM2JcfwZXO0MBCZSVBgMuLzJaRZ0pfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\napppencil16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAASC/IQCBMQCBPzCxAQCBPz+/MTCxISChDQyNKSipEQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARDEMhJZRBD1H2z3lMnjKCFjUJQimOgcmcbELCXzjXq0hV785WCQYcDFQjDXeloMByKG6YTAdwIDAlqSZJSVFeKLcUfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nappsheet16:app app16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBAT+/Pz+/KSipPz+BAAAAAAAACH5BAEAAAAALAAAAAAQABAAAANFCBDc7iqIKUW98WkWpx1DAIphR41ouWya+YVpoBAaCKtMoRfsyue8WGC3YxBii5+RtiEWmASFdDVs6GRTKfCa7UK6AH8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\napptool16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBISChGRmZMTCxKSipLS2tHx6fPz+/OTm5FxaXOzu7DQyNMzOzAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAReEMhAq7wYBDECKVSGBcbRfcEYauSZXgFCrEEXgDCSeIEyzKSXZoBYVCoJVIqBGByKu0Cy8QHxmgNngWCkGgqsGWFseu6oMApoXHAWhWnKrv0UqeYDe0YO10/6fhJ+EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\napptools16:app app16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBExKTERCRAQCBOzu7Nze3MzKzLy+vCxqZBQ2NJyanKyqrGRiZDRydKza3FRWVPT29LSytDw6PMTm5EySjCxaXGRaJFSanCRSVGxqbPTmvMSqVJTW1GSurHS6vOzq7KSipISChFRKHJSGNPz23GxKFBQ6PKyurCwqLMyufJx2RAQGBJSWlEwyDIRiLNy+lLSKVDwmDJRuNOTOrLyabGRCFDx2dKSCVOzWtHzCxOTGnNSyhAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAahQIBwCAgIBAOiUiggFAyHASKxDAwUC8Zg0HAglA9IZPGQABoTSqJCFTIOEIsFgHBcEhhHUpKJFCwaGxYYHB0VEx4IEh8gIQwiIyQbJRMcHokmEicfDygAkCkqJQgIGG0rLElCLS4vMCWqQwMCQg0UMTIzNDVLQjaIGDE3ODQlS785CEkxKjowvEOHybG4O6JDCdNKuDUxRAmxRDHeveUAfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappuser16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MTCxISChMT+/ATCxASChFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMg5gw00yyDGIAR1YUDggeFWFIZhnSBZrsZxdIOFEGTA2oeBAHeyuGwvzxBlYdUOLROMFzDQntJPrNoqAKUBaqnV+k57ZORruykHDj2LqIzUVKp1u0iuB/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappusers16:app app16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxISChAT+BMRaBPyqXARCBPz+/FxaXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARLEIRJa5Ui673nsGAgeKE1Bl9AUEXbiqTlFlZaGUZoszm4BzhDAVf5BYbAXI+TAR6CS2ZGSZSEiIIqYIsSIEaJ7GRrlY7J1lKA7I8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappwp16:app app16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBKSinJyOfPz27Pzy7AwKDExOTJyWlERCRKSelPz69LyyrKymnPz+/MS2fDQyJAQCBOTazLSiXOzivMS2jKSSVOzmxPz25NzSpPTu5KyebOzixNTGjOTWpMSydMSybCwqFGReVKyaXNzSnGxeNJSCVMS2nPz23MSuZIR+bJyShLyqnOTOtGxiXIR6XOTSvIx6RMSubIyCdKSalMS6pOTWxMzKvKSabJyKTOzezHxuPGRmZKyurMTCvPTq3AAAACH5BAEAAAAALAAAAAAQABAAAAajQIBwCAgIiEhiYEA4FgwHRDKhIBAWz4OhgGQ0FAPHA7qFEBONb0Qy0ULeQ2+aUrFcMI+3GYBOZzQbHB0eHyAhIQByDREiEwMjFRIkJQImAgJ+jScjHigkKSorLC0AKg2NFSMoki4qCy+IQgITKDAxkjIzNDWkQxQoJaskMgk2Eb1DNzgoOCoHDDY5yEIwJToAOzw9ET7TQiREAhkZ3kmy5QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncal1day16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANOCLrMEUDIOUS9AFLLhx8LIRZjKYZmMRCkaChFLHty/AIiS3y6q+QtT49wq8VotRtQJGwRf6Zmrlj7DJLQXsupTJmeEIN4TB5nII20wp8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ncal5days16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANMCLrMEUDIOUS9AFLLhx8LIRZjKYbj55GioRRwoQ5x4QIiIdMmcec7jy53q81qP9OO5VMAj8RXTFWzOZW95HDLdEEM4LA4nIE0zgp/AgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncal7days16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANPCLrMEUDIOUS9AFLLhx8LIRZjKYbj55GioRRwoQ5x4QIiwcp0fucsj873qvGMv5Jw2FIACUsW4WakGW1O046I05qmGYBhTC6TM5CGWuFPAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalappointment16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/MTCxPz+BISCBISChKSipAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARbEMhJaQhA6D1E/wDGeeRgDhOhFoTBEi+REgdrIHScSEVvAD9Xr7cDqGSGpFEnQSqTv2NxCFQOiU1VEAiTZmstHFg1vQKuw+LxxfYaV/AuOQRI2O/4ewhT6Uv8EQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalbell16:cal cal16 16:photo:16 16:R0lGODlhDwAOAIIAAPwCBISCBPz+BIQCBMTCxISChPz+/AQCBCH5BAEAAAAALAAAAAAPAA4AAAM+CLrR+zCIAWsgLVRGRBhOVQiG94WPVAbHaZHYAWqRYLbge88RsbInGuBCEhRYrZYm4xk4nYdoKzKIbiKHawIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncallist16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/KSipPzerMRaBEQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARDEMhJaQhA6D1E/wDGeeRgDhOhruyatjBRSIRxxOsMEAdC0BUZDcfSEYvDo3Bn++2Cxt7RqFxWhZiCdsvdhjCVsMQfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncalmonth16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBAQC/AQCjPz+/MTCxKSipAAAACH5BAEAAAEALAAAAAAQABAAAANSCLrMEUDIOUS9AFLLhx8LIRZjKYbiRxLFIBpK0Q6z7MkwkJIe8b0KEeuWchFysuStVsjtfMbeMQitWpG25YfmNK1WU53XNIUYzug0OgNpuBX+BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ncaltoday16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBPwCBAQC/AQCjPz+/MTCxKSipPyCBMRaBPyqXAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARTEMhJaQhA6D1E/wDGeeRgDhOhFmurpi5LyIQhFfiBIAfuFzaAioBIJBCummRYPCaDPh3vhwsOZdihNfa8Ub/AJXemFZPPNBvGwG672yFMZS7xRwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ncaltodo16:cal cal16 16:photo:16 16:R0lGODlhEAAQAIMAAAQCBAT+BAQC/AQCjPz+/MTCxPzCxKSipPwCBMQCBIQCBAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAARaEMhJaQhA6D1E/wDGeeRgDhOhFmurpi5LyMYhFXiuFwZiA6qZYbbqJX5BIw2RAPxwAAWCyWMCCsiXFGEEErKz6LQZfOqiTR1YJiGq1rFyyHmo2+/1EKbCl/gjACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnecting16:connect connect16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBPz+BMTCBISCBAQCBPz+/MTCxMTGxISChFxaXMzGzKSipAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJZbihUiz60FPnfaA0iBpBVGdHEYWxToEoSHBRHHM9AgSEQRcj+AYkYAJxIPKQFUJiOdTJQFIDU6dYzKKFhTCM+E5g4mXaDAyrlogEG+DGTecA7wsP8EcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnectno16:connect connect16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBPz+BMTCBAQCBERCBPz+/MTCxMTGxISChFxaXMzGzKSipAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARPEMhJq704axBEHoPUEdhQGMNYFuwxkKInDYjBniEnwMCQIIebSzXx/WwsFK+YMABZikWuYlrUCtZpEYv4WRPaHhb064YB41kCfJFSQBh/BAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnectyes16:connect connect16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/KSipDQyNMTCxMTGxISChFxaXMzGzAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARaEMhJZxCjgsAtDtUlCOA1gJQ4kl/IDatAoF7xxkS6GgEBr6jAobCyBX42SQBxMOx6A8MhiGASR8YDgrYsNEeJ0zaEGZY7uoH2oB6nOUwtbdLaVOeTUwo/8UcAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevcdmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tOzOvNTqvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/LzKvMTCxDQyNASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAa0QIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTBqUiuUCVmAeiYzmsKlwOt/AAKFIFAIIFx4WHyAhUwIDIgsZFyMkFxchJSYmiBkSBBoIJJwIGgOhiCYFJSEnFyQjFwNZewABISAfFiYnCAEmCREIrwAIFhwVGwcaBAkPGApsQsAVFA0GBQMRbxBTKM0ODQwTEq192ClDgROkBHvYKuNJUu5CKCorX1RDKCkpUn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevcdunmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXISChNTS1MzKzMTGxMy+vNSytAQCBOzq7OTi5Nza3Oy6vPy2tOTStPz6/Ozu7Nze3MTKxOS2tNzmvLT2tDw+BPTy9MzOzLS2tPy+tLz+tLz2tLSynLzqvLzavLTOtNTW1KSipPz+/MTCxLy6vDQyNOTm5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAapQIBQGBAYA8Ok0DggFAwHBEIJECQUi8GT0XBMh9YHJDKQTLqUigWsuDwSmMxBQ9lwvoEBQpEoBBAWHRseHyBTAgMhCxgWIiMWFiASJCSHEgQSGQgjmwglGKCHBQUSICYWIyIWAwshIVMBIB8eFSQmCAEFCREIekIIFRsUGgcZEgkPFydrvxUUDg0GBSEREGJfv9AMEySsJxDYQ4DcEhh64UpS6lTs7QB+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevdiskmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBDQyNIRuVKyCXMSKROzSrOzKpOTGnLSafLySZKxuLMSOVPTWvPzixLSehNyibOzOrGxaVJx+XOzGnFw2FJRuPKx+TPTSrHRWPKyKZPTOpHxOJKyKXFw+HKSipISChMTCxFxaXIRiPNSWXExOTOS2hLR+PLRyLPTWtMyOTASCBARCBPz+/DTSJIyKjIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaTQIBwCAgYA8SkMCAYDARI5ZJQMBwQiWgyoFgwrA3HQ7scQAqFAcEQOUi0zAkFUSFYLghMBloUCDQNGxwdHhwHekcfICEhICIfIxkLJBABJUYCICABIhAOBiYnKJaXmH4CGSkYCCqkSAEfTKenrkOwsrQll0IrS7G5uwArLLaxLbXCLsTFLyDBKy4wZEVHvCwsRn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevdiskunmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBDQyNIRuVKyCXMSKRPTWtOzKpOTGnLSafLySZKxuLMSOVOzOrPzm1LSehNyibGxaVJx+XOzGnFw2FJRuPKx+TPTSrHRWPKyKZPTWvHxOJKyKXFw+HPTOpKSipISChMTCxFxaXIRiPHxaNLRyLNSWXExOTPzixOS2hLR+PMyOTPz+/IyKjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaIQIBwCAgYA8SkMCAYDARI5ZJQMBwQiWgyoFgwGgiD46FdDiCFwoDQAEe0TMkEQSFULIcLBloUCDIaDRscHRsNHhhHHyAhISAiHyMkJSYQASdGAiAgASIQKA0pKguXmJl+AiQGFwgrpUgBH0yoqK9DsbO1J5hbsrq8SrgstlJFHy0gwMVFR1J+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevfloppymount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBMTCxARmZPz+/FSWlLSytKSipERCRIyOjISChOTm5HRydNza3GRiZFRSVASCBARCBDTSJIT+bAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVrICCOQBCQKBkIw5mqLFG47zoQ+FwbN57TosDhgPD5dMEEIqE04kwlBWKBUEiNVYFpyqAyGEUCgqEtERiNNMLhQKzLQYJg7n7Y4aMAwbCUPvAQeWNgfzQQETAIhSMQEogwgBITQEGGEREmfiEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevfloppyunmount16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBMTCxARmZPz+/FSWlLSytKSipERCRIyOjISChOTm5HRydNza3GRiZFRSVCH5BAEAAAAALAAAAAAQABAAAARcEMgJQqCYBjFu1hxReN82EOhYGieaklJwHIjrqnGCJLqNWhUFYoFQCG1FgWXIIDIYNQKCoawQGI0swuFAbKsxgmDsfZjBkwDBsNM90Jot9A3DbBD0Dwiur9QnfhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevnetwork16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBAQCBISChPz+/Nza3ARaZESanCyKlARudARGTLy+vNzq7ARmbMTCxARufAROVMzOzKSipARyfOzq7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVmICAGZFmKQiACweCSBImq41AYB5IodLq2hwWO0ejRWDac48Gb/QKNqNRoqspmrVcAUuIJBANS8sBIFCORUgooPEh4J8B67NgdsVBp9C5XWfl9LRMTCyReX19hARNojWlWLH+AAH4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ndevpc16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBISChHx+fPz+/AQCBAQC/AT+/AQCxAQChAT+BLy+vAR+BAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARYEIAgqK1YzsG754QUDERpmkEpkkXrtoK6EcVgHIibhnNx564Yb0TDvQq7FQ34EiqPOhnREqhWSUPsyZSQAbbg7GcMEgwUiYVivTa1R+y4XEGoWO/4AMAfAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevscanner16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBAQCBPz+/MT+/ASChARCRATCxMTCxFxaXKSipDQyNAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARTEMgJgqWBVivEldkUdKSXhVjZfenommglDERh3Tc4E4ZRHAGgkEPr9X6H5AHBERSMRyWzkug8jQXFEhWoOo8dRYxqLXSmGjIJnVaz29Q3fAP3RwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevscreen16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXFRSVPz+/PT29OTm5OTi5DQyNDw+PERGRExKTHx+fISChIyKjHRydFxeXDQ2NCQmJBQSFAQCBERCRMTGxHR2dGRiZExOTDw6PCQiJAwODCwuLFRWVOzu7BweHAwKDCwqLHx6fBQWFGxqbGRmZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAanQIBwSCwKAwKkMslEAgSDqDRKqBYKhkNgcDggEorkMrDQchkNhuOhgEQkk0l5S2lUGpYLJqPZTAwMHB0DCmhqAW0Rfh5zAxgOkBcCFAcfIBMECxwBBAEPFw8dChkhcBMDDAcdnQqtFKSWcQMimx4dGRkQBxGxsg6bBQEawx8jl3GnJFoFHRNXVVNRJYIFDAsL1tgiDiQXFx0HABwcXeQH5OjkRutEfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ndevspeaker16:dev dev16 16:photo:16 16:R0lGODlhEAAQAIMAAPwCBFxaXAT+/DQyNATCxMTCxPz+/AQCBKSipASChAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAARWEMgJQqCXziDG2JoUEENhZBkmHIWJVptAmqcIW/Js1MiF56TBzkckAAcHoa9nMRKeA4TyJk0knsHhTeK5khBaH2VwLYVh40TJhQ6RzeIQV32Quz8hfwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditcopy16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAFxaXPwCBNze3GxubERCRPz+/Pz29Pzy5OTe3LS2tAQCBPTq3PTizLyulKyqrOzexLymhLy+vPTy9OzWvLyifMTCxHRydOzSrLyihPz6/OTKpLyabOzu7OTm5MS2nMSqjKSipDQyNJyenLSytOTi5NTS1JyanNTW1JSWlLy6vKyurAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAaUQIBwCAgYj0eAYLkcEJBIZWFaGBie0ICUOnBiowKq4YBIKIbJcGG8YDQUDoHTKGU/HhBFpHrVIiQHbQ8TFAoVBRZeSoEIgxcYhhkSAmZKghcXGht6EhwdDmcRHh4NHxgbmwkcCwIgZwqwsbAhCR0CCiIKWQAOCQkjJAolJrpQShK2wicoxVEJKSMqDiAizLuysiF+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditcut16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIEAAPwCBAQCBPz+/ISChCH5BAEAAAAALAAAAAAQABAAAAIwhI9pwaHrGFRBNDdPlYB3bWHQ1YXPtYln+iCpmqCDp6El7Ylsp6ssR1uYSKuW0V8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neditdelete16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPT29GxubMzOzDQyNIyKjHRydERCROTi3IyKhPz29Ox6bPzCxPzy7PTm3NS6rIQCBMxCNPTq3PTi1PTezMyynPTm1PTaxOzWvMyulOzGrMymhPTq5OzOtNTKxNTOzNTCtNS+rMSehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaKQAAgQCwahcihYMkcBAiBpLJApRoOBWgyIKhSEQkFgrBAcr1URiPhKAsDD3QB8RhA3FM0IlLHnyUTVBMSFBUWfl0XGBMTGBcZGodmcQWKjpAbHIgIBY2LHRoempOdjooTGx8giIOPFYofISJ+DyMXI6AfFySyfiUmJSUnKBYcICIpfgELzM3OZX5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedit16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBFxaVMR+RPzKjNze3AQCBMR6RPzGjPyODPz+/MzOzPyKDPyKBPz29OTWzPyGDPyGBOx6BOza1OR2BKROBNSOXKRKBBwOBOzu7PTWxPzizOySZPyCDFxaXOy2lNRyRMxmJCQOBPTm1OzStPTKrMR+XIRWLFxGNCQSBDQyNIRSNDQuJERGRLyqlNzSvIx6ZKRuVEw6LLSyrLymhKSShBwaFFROTJyWjMS+vNzW1OTazNzKrHRqXOzezOTOpPTq3OzWvOTStLyedMS+rLy2pMSynMSulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAewgAAAAYSFhoQCA4IBBI2OjgUGBwiLBAmXlpcKkgsMlZcJBA0JDpIPEBGVjwkSBgOnExSfmBIVBxAMExYXswkYGRobHLq8gh2PHhoeHyAWIYKzIiMkJSYnKCnQg5YNHtQqKywtK9qMBC4vMDEBMjIz2dCMDTQ1Njc4OToz5PEEOzw3ZPToMcLHO23HfogQ0QMIkCA+hPBbhAPHECJFjMyYIUQIvEUpUqwQOXKkSEF+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditpaste16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQiFHRqNIx+LFxSBDw6PKSaRPz+/NTOjKyiZDw+POTe3AQCBIR2HPT23Ly2dIR2FMTCxLS2tCQmJKSipExGLHx+fHR2dJyenJyanJSSlERCRGRmZNTW1ERGRNze3GxubBweHMzOzJSWlIyOjHRydPz29MzKzIyKjPTq3Ly2rLy+vISGhPzy5LymhISChPTizOzWvKyurPTexOzSrDQyNHx6fCwuLGxqbOzKpMSabAQGBMS2nLyulMSidAAAACH5BAEAAAAALAAAAAAQABAAAAa7QIBQGBAMCMMkoMAsGA6IBKFZECoWDEbDgXgYIIRIRDJZMigUMKHCrlgul7KCgcloNJu8fsMpFzoZgRoeHx0fHwsgGyEACiIjIxokhAeVByUmG0snkpIbC5YHF4obBREkJCgon5YmKQsqDAUrqiwsrAcmLSkpLrISLC/CrCYOKTAxvgUywhYvGx+6xzM0vjUSNhdvn7zIMdUMNxw4IByKH8fINDk6DABZWTsbYzw9Li4+7UoAHvD+4X6CAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditshred16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbGxubMzOzPz69DQyNIyKjERCRPz29PT29OTi3IyKhPz27PTu5PTy5Pz6/Pzy7PTq3OzexLyqlPTm1PTizOzavLyqjOzWvOzaxLyifOzizOTOpAQCBOzezAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaEQAAgQCwahcihYMkcBAiBpLJApRoOBWgyIKhWEQkFYYHkeqkMxKFBFpq9jgdkEGlPqwrJhCIY2N8FFRYUFxcYGX9dgRKEGhiHiYEOhBcbGBwdiQEOARcBGwEeAZllAgEUnQEfoQEgmp4hrCKtrwEYsrRlTiMBJAG8syN/IyMAxMXHSH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedittrash16:edit edit16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBAQCBKSipFxaXPz+/MTCxISChDQyNCH5BAEAAAAALAAAAAAQABAAAANQCKrRsZA5EYZ7K5BdugkdlQVCsRHdoGLMRwqw8UWvIKvGwTICQdmGgY7W+92GEJKPdNwBlMYgMlNkSp3QgOxKXAKFWE0UHHlObI3yyFH2JwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfileclose16:file file16 16:photo:16 16:R0lGODlhEAAQAIQAAPwCBCQiJBwaHAQCBDQyNDw6PFxaXFRSVERGRCwqLAwODGRiZHx6fPz+/GxqbAwKDCQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVaICCOZGmeqBgEwjCkRGEcSKK4JrEcBrMgAdeLVDg0GguGsYEbBQyGYyN6FDoPDIf0+LCKBIgetQERDgGDBGIpNY8GioAU0m6KXFw883w3+/l9f4AkfimGIn4hACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfiledocument16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJSWjPz+/Ozq7GxqbJyanPT29HRydMzOzDQyNIyKjERCROTi3Pz69PTy7Pzy7PTu5Ozm3LyqlJyWlJSSjJSOhOzi1LyulPz27PTq3PTm1OzezLyqjIyKhJSKfOzaxPz29OzizLyidIyGdIyCdOTOpLymhOzavOTStMTCtMS+rMS6pMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaQQIAQECgajcNkQMBkDgKEQFK4LFgLhkMBIVUKroWEYlEgMLxbBKLQUBwc52HgAQ4LBo049atWQyIPA3pEdFcQEhMUFYNVagQWFxgZGoxfYRsTHB0eH5UJCJAYICEinUoPIxIcHCQkIiIllQYEGCEhJicoKYwPmiQeKisrKLFKLCwtLi8wHyUlMYwM0tPUDH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfilefind16:file file16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBCQmJDw+PBQSFAQCBMza3NTm5MTW1HyChOT29Ozq7MTq7Kze5Kzm7Oz6/NTy9Iza5GzGzKzS1Nzy9Nz29Kzq9HTGzHTK1Lza3AwKDLzu9JTi7HTW5GTCzITO1Mzq7Hza5FTK1ESyvHzKzKzW3DQyNDyqtDw6PIzW5HzGzAT+/Dw+RKyurNTOzMTGxMS+tJSGdATCxHRydLSqpLymnLSijBweHERCRNze3Pz69PTy9Oze1OTSxOTGrMSqlLy+vPTu5OzSvMymjNTGvNS+tMy2pMyunMSefAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe4gACCAAECA4OIiAIEBQYHBAKJgwIICQoLDA0IkZIECQ4PCxARCwSSAxITFA8VEBYXGBmJAQYLGhUbHB0eH7KIGRIMEBAgISIjJKaIJQQLFxERIialkieUGigpKRoIBCqJKyyLBwvJAioEyoICLS4v6QQwMQQyLuqLli8zNDU2BCf1lN3AkUPHDh49fAQAAEnGD1MCCALZEaSHkIUMBQS8wWMIkSJGhBzBmFEGgRsBUqpMiSgdAD+BAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilenew16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJyanPz+/Ozq7GxqbPz6/GxubNTKxDQyNIyKhHRydERCROTi3PT29Pz29Pzy7PTq3My2pPzu5PTi1NS+rPTq5PTezMyynPTm1Pz69OzWvMyqjPTu5PTm3OzOtOzGrMSehNTCtNS+tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ/QAAgQCwWhUhhQMBkDgKEQFIpKFgLhgMiOl1eC4iEYrtIer+MxsFRRgYe3wLkMWC0qXE5/T6sfiMSExR8Z1YRFRMWF4RwYIcYFhkahH6AGBuRk2YCCBwSFZgdHR6UgB8gkR0hpJsSGCAZoiEiI4QKtyQlFBQeHrVmC8HCw21+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileopen16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBOSmZPzSnPzChPzGhPyuZEwyHExOTFROTFxaVFRSTMSGTPT29Ozu7Nze3NTS1MzKzMTGxLy6vLS2tLSytDQyNOTm5OTi5Ly+vKyqrKSmpIyOjLR+RNTW1MzOzJyenGxqZBweHKSinJSWlExKTMTCxKyurGxubBQSFAwKDJyanERCRERGRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaRQIBwGCgGhkhkEWA8HpNPojFJFU6ryitTiw0IBgRBkxsYFAiGtDodDZwPCERCEV8sEk0CI9FoOB4BEBESExQVFgEEBw8PFxcYEBIZGhscCEwdCxAPGA8eHxkUGyAhIkwHEREQqxEZExUjJCVWCBAZJhEmGRUnoygpQioZGxsnxsQrHByzQiJxz3EsLSwWpkJ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileprint16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBFRKNAQCBPz+/MTCxExKLPTq5Pz29Pz6/OzezPT29PTu7PTy7NzClOzm1PTu5LSabJyanPTm3FxaXOzCjOTKrOzi1OzaxOTSvJyenGRmZLyyTKSipDQyNERCROTi5Hx+fMzKzJSSlIyOjISChLS2tAT+BDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaYQIBwKAwIBMTkMDAYEApIpVBgOCAOg4RRGlAoEAuGIdGITgWOq4LxcCQgZkEkIHksHgYJOR6ZQCgVFhYJFxgTBVMZihoCfxUYDWUbUBGKGREcjBoQEB2TAB4CAx+Vl5WMhyACHiEhH6IfIiMktCQgE0cZJQStr6O2t6EARxO6vK6iEx4dZsMCxbsmBB4nzUTEutVSSUdmfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilesave16:file file16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBFRSVMTCxKyurPz+/JSWlFRWVJyenKSipJSSlOzu7ISChISGhIyOjHR2dJyanIyKjHx6fMzOzGRiZAQGBFxeXGRmZHRydGxqbAwODOTm5ExOTERGRExKTHx+fGxubNza3Dw+PDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaAQIAQECgOj0jBgFAoBpBHpaFAbRqRh0F1a30ClAhuNZHwZhViqgFhJizSjIZXQCAoHOKHYw5xRBiAElQTFAoVQgINFBYXGBkZFxYHGRqIDBQbmRwdHgKeH2YgHpmkIR0HAhFeTqSZIhwCFIdIrBsjAgcPXlBERZ4Gu7xCRZVDfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfolder16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLARqnAQ+ZHR2dKyqrNTOzHx2fCQiJMTi9NTu9HzC3AxmnAQ+XPTm7Dy67DymzITC3IzG5AxypHRydKymrMzOzOzu7BweHByy9AyGtFyy1IzG3NTu/ARupFRSVByazBR6rAyGvFyuzJTK3MTm9BR+tAxWhHS61MTi7Pz+/IymvCxulBRelAx2rHS63Pz6/PTy9PTu9Nza3ISitBRupFSixNTS1CxqnDQyNMzGzOTi5MTCxMTGxGxubGxqbLy2vLSutGRiZLy6vLSytKyurDQuNFxaXKSipDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYHCImDBgkKCwwNBQIBBw4Bhw8QERITFJYEFQUFnoIPFhcYoRkaFBscHR4Ggh8gIRciEiMQJBkltCa6JyUoKSkXKhIrLCQYuQAPLS4TEyUhKb0qLzDVAjEFMjMuNBMoNcw21QY3ODkFOjs82RM1PfDzFRU3fOggcM7Fj2pAgggRokOHDx9DhhAZUqQaISBGhjwMEvEIkiIHEgUAkgSJkiNLmFSMJChAEydPGBSBwvJQgAc0/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolderhtml16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBERGRBQWFMzKzOzq7CwqLDw6NARqnAQ+XHR2dKyqrOTm5ExKTERCRHRydMTi7NTu9HS+1KSmpBweHDy67DyixHS61ITG3AxypByu7DxinBw+ZERmdIySjITC3ARypExOTDRurIR2RPTSdJyulEyGvBw+bFSyzJTK3LzKvPzivOTixNTChLSybGyCfCRSnBQqRASGtFyuzDw+PCRShPzy5OzerOTShKyaTEx6pCxerGRufBR+rOTezPTShNy6bER+1BxCfBQuRAxelFSixBw2VISq3GySrPTWlHyanIyitFSO3IymtCRujAxWhCRqlCQ6XGyWvNS2bFyGvDxuvCRSpLy+vMS+vGxqbFyO1GSi3EyO1FRaVCQuPLS2tDxyzKyWNFxaNCQyPGxubCxajERSVExKNJyenAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfZgACCAAECg4eIAAMEBQICBomDBwgJCgsEDA0BDg8BhwYQERKUDxOYDAyeghQVFhehGBmVlwwOqxobHB0eH6EfIAkPIYIiIyQlJhsnKBcpvrYiKissLS4vMDEyFjOvNAA1LDY3ODk6Oyc8PTIyFzQ1Jj42P0A6QTtCQ0REIEUORkdIkihZwsSekBhNnDyBciCKiSNSplDRUcWKkRhXCGDJYgiGli1cpuTocsILjytfFmRpACAGRTBhRogZgzHlAjKGWnIoY+bMgRgBDHRBo/LAIZoxuhwKatRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfolderlocked16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQSFMzKzOTm5CwuLERCRARqnAQ+XHR2dKSmpOzm5GxqbCQiJMTi7NTu9HS+1HRydOTm1Ozq7Dy67DyixHS61ITC3AxypERGRBweHByu7ASGtFyy1DSOtDRmfExOTBSazBR+rCwqLAxWhAxelByGtDSaxAwODHy+1Dw+PPT29IyqvCxujOzu7NTW1Nza3ExGJJyebKyqfMTCpFRSPOTi5DQqHOTezDw2NMTGxKyqhMTGrGxmXDQ2NMTCxMTGpHx6bHx2bBQWFIyOXDQuDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQICBomDBwgJCgsEDAKFDQGHDg8QEZQSlxMUDJ2CDhUWF6AYGZWXFBqCGxwdFh4XGK8fIAohtiIIIx25EZwBDREHgiQjJSYmGScoKSoRKQ8rggIsDC0uJS4oGygoAyjdAAcsLxQUMDEyMzQ1EzapBy8MDDc36tFwgONFjlQ6dgCEEZBHDx8+ctRIRehHAyAwZASZIGRIEBoUBwUwIGMCiwFEaBQJichIjo9FZLBsacRIAB0A/AQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfoldernew16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAQCBPz+hPz+BOSmZPzSnPzChFxaXMTCBPyuZPz+xPzGhEwyHExOTPz+/MSGTFROTPT29OTm5KyurDQyNNza3Ozq5Nze3LR+RLy+vJyenMzKzNTS1Ly6vJSWlFRSTMzOzMTGxLS2tKSmpGxubBQSFAwKDKSinJyanIyOjCQiJERCRERGRBweHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaNQIBwSCwaj8ikcokMCIqBaEDoBAQG1meAUDAQpIcBQoy1dg2JdBqhECgQ1IWB0WgcBIOBwIHXBwwPEBEREhIBbG4IExR/DBUVFhIXV2NjDVYYDY8SFU4ZVxpVAQwbGxynGxkdTh6XVh8gGSGzGSITIxokJUImGSMTwLcnKCkprgAqDSt1zCssKxQtQ35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfolderopen16:folder folder16 16:photo:16 16:R0lGODlhEAAQAIYAAPwCBAQCBExKTBQWFOzi1Ozq7ERCRCwqLPz+/PT29Ozu7OTm5FRSVHRydIR+fISCfMTCvAQ6XARqnJSKfIx6XPz6/MzKxJTa9Mzq9JzO5PTy7OzizJSOhIyCdOTi5Dy65FTC7HS2zMzm7OTSvNTCnIRyVNza3Dw+PASq5BSGrFyqzMyyjMzOzAR+zBRejBxqnBx+rHRmTPTy9IyqvDRylFxaXNze3DRujAQ2VLSyrDQ2NNTW1NTS1AQ6VJyenGxqbMTGxLy6vGRiZKyurKyqrKSmpDw6PDw6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfCgACCAAECg4eIAAMEBQYCB4mHAQgJCgsLDAEGDQGIkw4PBQkJBYwQnRESEREIoRMUE6IVChYGERcYGaoRGhsbHBQdHgu2HyAhGSK6qxsjJCUmJwARKCkpKsjKqislLNIRLS4vLykw2MkRMRAGhDIJMzTiLzDXETUQ0gAGCgU2HjM35N3AkYMdAB0EbCjcwcPCDBguevjIR0jHDwgWLACBECRIBB8GJekQMiRIjhxEIlBMFOBADR9FIhiJ5OnAEQB+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailforward16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRydHxubHxmZGxiXHRmZFxOTFxGPFxKTPwCBLymlMy+pOze3PTq3PTu5Pzy7LSmnOTaxOzm5LyqlNzOtPz69Pz27MzCtLyqrPT27IRubPzuzNTGvNTCxLSelPz25Bw+ZFxKPPzy1Pz65LyupBxKdCxWfPTm1Pz23LyinBxGbGzO5DRafBxWfBxajCymxHTS5BxSdBxKbFTK3EzG1CSGvCyKvCSSxCSavGTO5GRaVPzqzFzK5EzG3BSCtAwiPGxaVPTivPzy3NzKpBxObCRefBxqlPTmzJR2bKyahAwyRPzmvOTOpKyObNS+nPz21AQOFKyOfPzuxAQCBGRORLSadPzyzLymjMy2lOzetDwuJFRCPEw6NEQ6LEQyLEQ6NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAAAQABAAAAfhgAABAgIDBAQFBgcIBwmOCQIKCwwNDg8OEBESjY8CDBMUFRYVFxgZDJyOGhsPChwVHR4fFSAhjwkaIiMOJBQQDRUVJSa3GicoHw4pEA8SGSorLI8tLtQu19gqLzDECTEyMzQ14zY1Njc3ODkqCTo7MjIxNCs5PD03PjctPwlAQUIihhBpQbCIihtG+CUocASFkAhIkogQ8kFJwkcFlogIkoRJEydPnkBR6GiAxiQLgiiIIkXElFQJqESoMsRKkAhXqkhhApNKFSxZggTJ4nHIEJhaDhzYwoVLFy1avHyB6ScQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailget16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAxKdBRSfCyGvFSm1BxKfCSWzCyWzBRCXCRKfBwuRAQGDDw6PHy23Cym1CSSxByCxBxunBQSFKyurMTCxExihNza3NTW1JSSlMzKzFxaXLS2tNze3KSipCQmJGxmbNTS1KSepLy2vISGhJSWlHx+fERGRPz6/IyKjDw+POzq7JyenMzOzKSmpCwuLDQyNIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaeQIBwGBAIAsOkUjAgFJRQQMHgjC4PBIEVgAh4D4aEYrGAMhINxwPyiCgYSsmEUmk82grLRZJkYCgXaAEKFxYZcEISGhsZFxwFeY0WHR5CDB8dGCAXG5shGxQicBIMpSMUGxgTGSQlpQwSJicnEwwdI7gdKAwTsykpKiobr8QMKxeHDBcsGRvOzxsT0i0uL9HSHdkT2ZkoMJXF4a8AfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmail16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBGxaVOTe1Oze3OTWxOTWvNzStNzKpEQ6LOTezPz+/Pzy7Pz69Pz27Pz25Pz21PzuzPzuxEQyLLyinLSmnPz67Pz23LSafKyObDwuJMzCtLSelPzy1My6nLymjNTCxLyqnPzq1LyihKyOfOzavOzetEQ6NPTq3NzOtLymnNTGxJR2bOTOpPTivNTGvLymlKSShKyahEw+NOTe3PTm1Pzu1Pzy3FRCPPz65LSadFxGPOzm3PzqzPTmzPzmvEw6NCH5BAEAAAAALAAAAAAQABAAAAaqQIBwSCwaj8ikMhloOp/QpmAgqAoIhELBUDgcEIGEYrFgNBoLx+IBiRwkgQnFoWAwKhWLhX3BZAILGhsCDXgODhwdGB5vgAofICBlDiEiIx4kJSYBJ2UoEykqHSMrLC0nLWAnFS4UCycvMAcEMR0RLTIBMwaSahw0NTYtFwclNwEdLws4eoc2DxwQOR06ASk7PBAhIRE9Pj0tLSUY1T8I5gjn6Qgy7D8SfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailreplyall16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTFRCPFxKTFxGPPwCBLymlMy6pOTa1PTq3PTu5Pz27Dw+POzi3PTm1OTWvPz25FRSVERCRLympPzuzPTu7NTGvFxaXKSmpPzu1Pz65Hx6fHxqZPzq1Pz23HR2dBw+ZHx+fISChJSWlDQmJHRydCxWfBxGbJyenExKTHRiXPzqzPzy3CQmJDRafGTO5ExOTERKTGxWVCRSfHTS5CymxBxajBxWfPTmvPzy1CyixCSaxCySxDSaxDSWxDSSvDyaxGS21PTmzPz21AwiPBRejCSavByGtCSezEzG3FzK5FzG3GzO5FTK3CQ2bPTixBxqlCRefBxSdBxSfBx2nCQ+dHxmXPzmvLSafAwmRAwyRPzyzDw6POzavNzKpAQOFPzuxBwWTBw2ZGRORLyWdMy2lOzetPTivAQCBKyObOTOpAweNBwWVEQyLEw2LEQ2LDwuJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAf4gAABAgMEBQUGBwgJCguOCwEMDQ4PEBESDA4TjY8DFAwVERYXGBkRm4+QGhsMHB0eGB8bDpyOARogEBceIRgXv8COIiMkGB4lJSYnIcwoKb/DGyoXKywtKS4pHinMLzAxJDIzNDUtNjcv6B0hLzgfMh85OjstPDw99zwd7T4/LTVAgggZQqSIECNHevSAgSSJkiVMmjh5AiWKlClAiFARUeVHFSVWmLS40gNLlh5agGzh0kWDlwZfrIDREKaCAjEqrFA5MMYLmTAxlJTxYoZMozNozqRRs4ZNmy5s3LwhA0dBnDNn5MxBoAABnTp17IitowDrmQV+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailreply16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTEw+NFxKTFxGPPwCBLymnMy6pOTa1PTm1Pzy7LymlOzi3HxqZOTWvPz69Pz25My+tLympFRGRHxuZPzu1LymjNTGvNTCxBw+ZPz23PzuzPz65PTu5NzOtCxWfBxKbPzq1DRafGTO5BxGbPzy9HTS5CymxBxajHRiXPzqzCyixCSaxCySxDSaxDSSvGS21GxWVAwmRBRejCSavByGtCSezEzG3FzK5FzG3CQ2bPzuxAwiPBxqlBxKdCRefBxWfBxSdBxSfBx2nCQ+dPzy1CRqlAwyRDQmJPTmvPTixLSafOTOpAQOFPz21BwWTBw2ZPzmvNS6nPTivAQCBAweNBwWVNzKpPzyzLyihGRORLyWdMy2lOzetKyObEQyLEw6NEw2LDwuJEQ2LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAfqgAABAgMEBQUGBwgJCguOCwEMDQ4PEJYRDhKNjxMPDBQVFhAXGBUSGY8LGhsQHB0VHh8gFQ6bjgEhIiMMJCUmFbS2CwMnG6IoKSorI7WpEycWFiUsLSou1yXXji8wFiopMTIzNDUz4zbZNxsbODk6Ozw9Pj8pPzEzQDdB60JDOkRFjBw5giRJDCWdlmxwIIRJExAWKDRyMgTIiydLoESRImQKlSUSF1SxUoXAlSBRsGSJoCVICIlbqlThcoBClC5eYFD4EiVIFwUyqywAE0ZMlqNjpJDpIkUBl0dlFChAYOZMmTJoyqQR5icQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailsend16:mail mail16 16:photo:16 16:R0lGODlhEAAQAIYAAIx+fIRubHxubHxqbHxmZGxeXHRmZGROTFRCPFxKTFxGPPwCBHxqZLyqlMy6pOze3PTq3PTu5Pz27Pzy7LyinOTaxOzi3Ozq3LymlOTOtPz69Pzy5My+tLympPzqzNTGvLSelPzy3BxGbBQ6VPzuzPz65LyupNzOtPz+/GzO5BRejPzq1Pz23LymjHTS5CyixCSavBxqlPz25LymnGTO5CymxCSaxByGtHRiXPzy1CySxCSezGxWVPzuxKyOhMy6nDSaxEzG3PTivNzKpKyOfPzu1FzK5PTmzJR2ZLyihLSWfKyObOzmzPzmvDyaxOzavLSafGRORMy2lOzetDwuJEw6NEw2LEQyLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAsALAAAAAAQABAAAAfUgAABAgMEBQUGBwgJCguOCwwNDg8QERITFBUWjY8DFxgZGhsaHB0aD5yODB4TGB+kICEaIiOPCwEkJRcmJyYPKCIpKrWqKywTmC0SIi4vMDHEDCsyMg8zEyI0NTY3z7U4Hhs5Mx+0IyI6OyPrIzw9Gys+PxIy2EBBxAs8Qjk5Q0RFWFxAZySfgSMsilRAkiRECHQ08hHgJ0TJkCU/mECU2ISEkowUlpAQ4QTfowNPoAzJIeRJCyjm8kVRIkWIzSkXhwxJtYAKgp9VrFi5QoWKFZ5+AgEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1downarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PUZi0zmTtypflV0VdRJbm6fgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnav1leftarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAP///wAAACH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxqdwoNGTmgvy9px/IEWBWRkKZ2oWrKu4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1rightarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIdhI+pyxCtwoNHTmpvy3rxnnwQh1mUI52o6rCu6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1uparrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIYhI+py+0PWwhxzmetzFpxnnxfRJbmufgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnav2downarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+pq+EPXYpxUckoO3AjbF3dJwahllXe6AFgC8d+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2leftarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pyxf5VohmSlsxmpjTzAHeN5ak6UHpqKRi2GpwvH3Q3eT64RcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav2rightarrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAImhI+pq5HOAjQyVnqfhHue7oAaKH5kiW0AmnLqaHomkj02g+e6XwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav2uparrow16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIghI+pyxfR0HsRzNnuXVqn3mVQZWFRyIDjp65Ga5Ly4hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavback16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRSdBRObCQ2TBxObISevAQCBNzu/BRGZPz6/FzC3Pz+/HTS5ByyzJze7Mzq9ITC3AQWLAyWvBSavFyuxAwaLAwSHBRafBSOrDzW5AyixCS61ETW3CzG1AQeLAweLAxefBSStEze7CSWtCyatBSCnBRWfAwmPBRWdByixAQSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZiQIBwSCwah4HjUTBQFgkFg3MoKBykU0QhoUAIAuAksbpgNByPxQMSGVsVDYlkIqdUiJYLJqORbDgcHRseRR8gISIaEyMkGCVYRBEmeyAnlgaQkSgpmU4RAZ1OKqFOpFNGfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavdown16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObCRKZBxCXAwyTKTK3Ozy/NTm9GSivAQWHNzu/FzC3IzO5CySrAQOHAyuzETS3CSWtAyOtETa5Aw2VLze7ByWtBy61BSavAxWdBRCXAwqPAQCBDR+nKTe7FS+1Eze7ByixBRmjPz+/AyexAyixAQKFBRqjAQGDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZeQIBwSCwaj0hAYCkYEJLKguGASEADigWj4bgaHpBINykwSCYRa5HCFFQsF0xGo9lwhpSOwfORYC4gISJ3RAQdIyQYJSAlImNrh4uNJkl5CoKUUBQnjlB4KJ6hokN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnavforward16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBAwyTBRObAw2VDR+nCRKZOzy/KTe7Pz+/KTK3Nzu/Lze7FS+1AyexAyuzBSavAyOtBSmzOTy/BRqjNTm9IzO5ETS3ETa5By61AyixByixBRmjAQGDBxCXGSivCySrCSWtBTC3AQOHAQWHAxWdEze7AQKFBRCXAwqPAQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZjQIBwSCwahYGjUjBQGgWEpHNYMBCaT4G2UDggos+EwmBYMBpf6VBgYDgeEMgjIpmoAQVKxXLBPDIXGhscRB0eHyAgDSGBGyJFASMiIiMkJYImUwAnmJqbjp4AKCmhAKSlTn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnavhome16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBDw6PBQWFCQiJAQCBFxeXMTCxJyanDwyLDQqLFRSVLSytJSSlISChCQmJERGRFRWVGxubKSmpJyenGRmZLy+vOzq7OTi5Ly6vGRiZPTy9Pz6/OTm5ExOTPT29BwaHNza3NS6tJRqRGQqBNy6pIyKjDwGBPTe1JSWlDQyNOTGrNRiBGwmBIRaLNymdLxWBHxGFNySXCwqLKyqrNR6LKxGBNTS1NTW1Jw+BEweDDQ2NAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaoQIBwCAgIiEjAgAAoGA6I5DBBUBgWjIZDqnwYGgVIoTGQQgyRiGRCgZCR1nTFcsFkHm9hBp2paDYbHAsZHW9eERkYGh4eGx4ag3gfSgMTIBshIiMkGyAlCCZTEpciJyQjGxcoKUQBEhcbIiorLB4XEltDrhcaLS4vtbcJra8bMDHAGrcyrTMXHjA0NSypEsO6EzY3IzU4OdoTzK0BCAkDMgkIOjJlAH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnavup16:nav nav16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBBRObAwSHBRSdISevBRWfAweLNzu/BSOrAQWLPz6/FzC3DzW5BxObHTS5ByyzAyixEze7BSStBRWdAyWvByixAQSHCQ2TAQCBBRGZJze7CS61BSavAxefMzq9ETW3CSWtAwmPPz+/CzG1ITC3FyuxBSCnAQeLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZfQIBwSCwaj8hhQJAkDggFQxMQIBwQhUSyqlgwsFpjg6BwPCARySSstC4eFAqEURlYhoMLBpPRUDYcHXt7RgUeFB8gIU0BIoiKjAcUIwiLSQUkJRsmGIwJJwmEU6OkfkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplayeject16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+py+0R3IFQUtruXVqn3kkWyIARR4rqKvoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplayend16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+py8Eb3ENRggrxjRnrVIWcIoYd91FaenysMU6wTNeLXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplaypause16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIfhI+py+1vgoxzyUCxrZd18ClfmIyVyJ1lqkHuC0N+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplaystart16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pyxudwlNyguqkqRZh3h0gl43hpoElqlHt9UKw7NG27BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplaystop16:play play16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+1vgpySUWpvXXqrHmSaeJEYhKYq6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextblock16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py40Bo5SOzRvrwlgrfnkJOIkPaaaJXwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextbold16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIihI+py70BowPQ1HZpwNv212Vg9IGHmIjoWa4ey5DSRNd+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextbottom16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIVhI+py+0Po5y0hYtzrkB7zH0fN/kFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextcenter16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsnRkqtDnhu1zHfFSpjaY4PavgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextitalic16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+py+0BgztwUmmjBXX3jE0auHHhM5Yq4xcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextleft16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsgRoqr3Vnt102fFSJjUC6nlPoFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextmiddle16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIXhI+py+0PT5i01pisphjt3UmfFZYm5hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextmove16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIbhI+pm+EPIZsg2kfZvblXbwTg10WlA4rjyvgFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextright16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIahI+pm+EPIZstSrqsDhhv1ylfFE5jiYwX6hcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextsortdec16:text text16 16:photo:16 16:R0lGODlhEAAQAIIAAAT+BPwCBAQCBAQC/FxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM5CBDM+uKp8KiMsmaAs82dtnGeCHnNp4TjNQ4jq8CbDNOroIe3ROyEx2A4vOgkOBzgFxQ6Xa0owJ8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\ntextsortinc16:text text16 16:photo:16 16:R0lGODlhEAAQAIIAAAT+BAQC/AQCBPwCBFxaXAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAM4CAqxLm61CGBs81FMrQxgpnhKJlaXFJHUGg0w7DrDUmvtPQo8qyuEHoHW6hEVv+DQFvuhWtCFPwEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIlhI8Jwe2/AmpTynqPTXSqrnBM+I0kdmpmGmUp+K4nPMvhYx9+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntexttop16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIWhI9pwe2uYnq0yQtqxbz7D4biSIZ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextunder16:text text16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIjhI+pu+FxXoOIKpds1oBH7hlYxYxRCaIZ01lhJbHy9tTv7BcAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewchoose16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMzCLrcGlAs6UAYgwLdLtEcI4ygQo7VVp2oupGpG4vmaUVTemX523qlFcw0a4RqNlkx5k8AACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewdetailed16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMmCLrc/i1IAVkYg1Z1iRYUKCqitp1oikqBWV3ZOnhkWNagqu+qnwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewicon16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCLrcG1AwGOQbw6qANeCEB3pCSZpO6pgowJZqLKuUGE0dnuEhf8IL1kz1shSHDX8CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmag-16:view view16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ+QIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6eUAFCusJSzr7Kmpl0CtLGLvbW2Zn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmag16:view view16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ8QIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6eUAFCusJSzr7GLArS5Q7O1tmZ+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmag+16:view view16 16:photo:16 16:R0lGODlhEAAQAIUAAPwCBCQmJDw+PAwODAQCBMza3NTm5MTW1HyChOTy9Mzq7Kze5Kzm7OT29Oz6/Nzy9Lzu7JTW3GTCzLza3NTy9Nz29Ize7HTGzHzK1AwKDMTq7Kzq9JTi7HTW5HzGzMzu9KzS1IzW5Iza5FTK1ESyvLTa3HTK1GzGzGzG1DyqtIzK1AT+/AQGBATCxHRydMTCxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaBQIAQEBAMhkikgFAwHAiC5FCASCQUCwYiKiU0HA9IRAIhSAcTSuXBsFwwk0wyYNBANpyOxPMxIzMgCyEiHSMkGCV+SAQQJicoJCllUgBUECEeKhAIBCuUSxMKIFArBIpJBCxmLQQuL6cAsLECrqeys7WxpqZdtK9Ct8C0fsHAZn5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewmulticolumn16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAPwCBDQyNAQCBPz+/PzerAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAMwCLrc/ixI0WSgKoyBl+beQFACpo1AqXbKCr1wLAMWS08hGG3dSZqin4sxnBmPD38CACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewtext16:view view16 16:photo:16 16:R0lGODlhEAAQAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAQABAAAAIchI+py40BTQSwuovp3DXkv1ia1IHmIXLiyWJ+AQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewtree16:view view16 16:photo:16 16:R0lGODlhEAAQAIIAAAQCBPwCBDQyNPz+/PzerAAAAAAAAAAAACH5BAEAAAEALAAAAAAQABAAAAMuCLHcri4yGISlj4kxcANgNRBQCIbL6U1Su7bB62rXvGydG25kqpwfIGxILBr9CQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactattach22:act act22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBMTCxPz+/DQyNKSipAQCBISChFxaXDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARrEMgJgqA4zzus/gLhFd5HCcZAXqsphYPUdhcYFNRcZnvdtpnDqPTbUWgAJKBYwzBlw+bRo3xmkNWoBgm0OrVLn3GC9RgCk8DhUw7c0rHPr4CDu5SYQNyEt7uSY3p/UAKFhYKDSQOLiwgFdhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactbookmark22:act act22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBCQmJCwqLMTGxAQCBBwaHMTCxLSytERGRFRWVLy+vKyqrKSmpHR2dJSSlJyanISGhGxubIyOjKyurGxqbFxeXGRmZHx+fKSipLy6vGRiZLS2tFRSVHRydJSWlHx6fCH5BAEAAAAALAAAAAAWABYAAAWWICCOZGmewamaQrq+wUC8azHINGocOI38iIRAceDNaISFYklkGHOEhoNBfUAOhuOLEJE8HoPiRKFdESiQBqViuTDIUAsEcyAeGJmyiqC5RCwJGg0YcEh9D0V3Dxt6JwQVDRYVHBUdi40mjw0PTgwQHgeYJQQJfxUXFxAOoTkFpQ0fsRSimQkWEQ0VtI62HLt7vjl7JQYhACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactbookmarknew22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCwqLCQiJCQmJMTGxAQCBLy+vLSytERGRFRWVKyurKyqrLS2tKSmpHR2dJSWlKSipISGhGxubIyOjGxqbIyKjFxaXGRmZHx+fPz+NGRiZPz+ZPz+HMTCBKSiHPz+jFxeXPz+XPz+tPz+zPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAamQIBwSCwaj4Gj0hgQLJ+AAaEAVQoI06pRYDhkoYgwIhEgKBTfZ2FhaBsYDS8VWnA8Go0FJIKeqyUTDw8EDHBpSwUUFQ4UFhcYDQYFfkoFFxEQDG8KEAUZlEeWGBIakw4FG1STiBoYBRwdBR4fHgUdHKBEBSCnIR8iIyIfIblFu6ceIyQjtcXGCbLKzAUKzrq+wMLEVa+xs7W31kOTk6nkWuOf6Ea5QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactexit22:act act22 22:photo:22 22:R0lGODlhFgAWAIEAAPwCBAQCBHR2dDQyNCH5BAEAAAAALAAAAAAWABYAAAJOhI+py90RnIMyRUOxhDfzJkACdoXBuEDDkQFDi5go0MrKx16kns80b7qdELCgBYaEGWwL5nG1ePFiKp9A6kuYRNuho8vxVrrZivmMRtMLACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nacthelp22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBCQuNBwiJAwiLAwaJAwSHAwSFIy+3ERynCw2PCQuPAwmPCxOZCxWdJzG3FSazBwmNAQKDAQGBDRmhBQyTDxujDR2rIy21AwWJDyGxCxmjAwmNDRihAQOFDxmhCxunBQWFAwaLCRahDR6rESGvDQ2PCRWdDRunDSGvCRSdAwWHCwuLDSOzHSmxDyKxBxCZBwqNHSu1DyOzAQSHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAahQIBwCAgIBAPCoGAgOoeBAyKhWCwYDUf0CX1AIhLiJEGpBLiAAaRxdgYsl7Ybk8igBZoN5xmAdDxoanp8HyANISF8EBsiXBMjJBolBEQmGHFoRScbKHIKDykqK5lFAZRCnyknTaROLA8tq61OChgtKqyzQgEYEJi6UC4vI3LAASkbMBPARAEBdszR0sACEaPSMTIQM8W6KzNl3bo0NOJDdEEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactlock22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBHRudFxaXExGTERCRAwGDGxubPz+/Pz2/Ozm7Nza3NTS1KympFRSVHR2dNTO1JSSlKyqrKSipDQyNMTGxDw+PLSutKymrMTCxAQCBHRqLBQODJyanDQuFFxSJFRSJFRGJERCHExCHISChHxyLEQ6HGRaJExKHLSmbLy2fOzitPz23KSiZHxuNHxyNJSOTNTOnMTCjLSudKSaXJSKRJyOTOTetNzWpHxuPOTi5MzKzLS2tFxWXOzq7Ly6vOTe5Ix+RLSqdNzSpLyydKyqbKyiZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBAgMEBQKEjI0GBwgJCgsMDY2XjwkOAgQBDxCLl4QNCaGCBBGWooINCAqqrBKgqwATFKaDFRYVtBMXsIMNGBm0GRADjQIJxKIaGxwdHh8gISIhGyMZzIwkGholJiYfJiAfJyEZISDbg90oKCkqKwcHKyooLC0f7IIuLzD2YMSQgW8GDRri+AFoUMOGvRsxUhSsQQPHvmQSchyQtEAHhh0WJHDQcJERjwsKDvRI0BGDjwgicXhQyCOjSgUKPO6AObIkIQESfmxk6REDT4s0bfaYpDNkT4VAha5s+TLmzEYtatwIOHAiDZIKNQAJYk9IjCFEisyoocFEB4UACtBpm0t3LiF4gQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nactredo22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCReDJzGjMzivOTu3Pz+/JTWbHy+VHTCTMTivPT69BxGDESuJDyiHESiHEymJIzKZAQCBFS2LFzKNGzWPDRqHCxqDFSqLHy2XESCHAwaBAQOBBQqBDyWJHyqZDyKFGSiVESeJBQ6BAwSBGTGPFyWPFSSLEyOLESGJBQiDAwiBBQmDCRGFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaoQIBwSCwaj8hkMcBkKpcBwYAwEDif0YLhwEUkFItFMkAwMBoOR+PxgHwjRDggamhIJpQ8ZbKGKOQLcgEFdhUWEYgRF3sNfhELBHALAhgZFhobRBwREhQdEAIEHpIKHwsaSJwUDQgQIJINARxKESESDQ0dgCIjSpAkDAwPco+ZSJAlJicnKHIAIrNHidOIQxunT0kpCyrZSCss0d5Fj6jjRonn6uvs2QZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactreload22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBCRSFCRSHBw+DBxCFCQ6FBwyDBQWBBxGFCxyLGTChMzqzLzmvHzKjDyOTER+RERyNDSqXNzy3LzivFS+fCyCPBQmBCQiBBxKFBQqDOTy3LTitES2dDR+PCxuJOT25KTarCx+PESSTCxKHDSeVCyKRNT21ESWVDSGPBQyDAQCBBQSFDRuLDSyZDySTGzChCRiJKSmpExKTDS2ZGzGhLy+vGxqbISChDSKRMzKzGxubDQ2NIyOjCQiJCwqLBQWFCwuLKSipERCRERGRHR2dAwKDDw6PFRWVIyKjCQmJFRSVBwaHKyurAQGBExOTBweHFxeXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf9gACCg4IBAgMEBQYHhI2ECAkKCwwNDg8QBAOOhAQREhMUFQgWBxcHGBmbggkaGxwPB4yDB6SbBJIKHQaqtY0eHyAhsqrDgx4aCiKpqoQHAyMjJBMKJaSxzAAHIRsmJgonKA0LHSmDKiuOBywRLSQuLyEwwyoxMuiN6iUzNBXy5jU2bsgoJugABBz95uXQsUMGD3vpPPgTpKIGwx4+HMr4kW4YkCA2hAzxAQSIECI+imBTwVIFESNHerRUgc0cEiFHkjiiyYzeDiVLdvLcySSkkKGEWiZVweSGkIHMmvQosoQlkaZOjvhosvKJjIAxoOAsgpRZkQNLnvSoqspAIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nactrun22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAwKDAwKBCQiHNze3AQCBBwWFDw6NPTy9PTy/Dw2NKyytOTi3LS2tMTKzMzOxLy+tLy+vBQODNze5NTS1JyalIyCbIx6VIRyVISGfJyelOTq7EQ+NMTGxKyurGxeRLyKPOSmROSuVOy2XOSiTLzCzNTOzDw+NCwqLHxuVOy6bPzGfOSuXNTW1LSyrMSWRNymTOSmTKSCTPTGjPzSnPzWnMyaVBQSDMTCxPz+/KyahNSeRHxeLJRyTPzmtPzarOy6fJyajNza1Ly6vLyulFRCJPzirPTOlMS2pNTSzMTCvJyenBQWFNzKtPz6vPzyvPzqtOzGlOTe1AwGBFxWTLy6tPTm1PzSpPzutPz2xPTSnOTSxOy2dPzapPzerOzm5IR+dPzu5Pzu1PzqxPzy5Pz+9GRiXGxuZKympHR2bOTm5Pz6/MzSzBwaFJSSjCQmHPz2/AwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeEAQKIjIIDBAQDjYMFBoMHCAkKgwYFhwULDAUKCg0ODxCkBQgRnoUSExMUDxUWFxgZGpAbFIuGHB0eHyAhIiMkIB8lJieIKCUpJCTGIyorLCktKIUDpC4YLzAxIjIyMzQ1NhgdpJI3ODktJTowOyM8Ejc9Pj9AQUIEclAocCMIBQhDiOwgoaKIoCI+jBxBkkSJkCWemIyq0GSHCBVHihRx8gRKFCmpKhGaQqWKFYZXsGR5kkXLFgRUXBUqkCGCFS5AjnTx0sXKlyA6CRVgAAHMAilhxIwhU6ZFkBY5kgKYUoXBAzMKzixZ4AJNGgVm1KxhM0WpmQpUMtooaOPGxAM3Nw60oYLGjNYCbzYJOgAnRzNBJ95oPYQCgpJtkwzFoULlRuRPiy9fNhAIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactstop22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAASC/CQKDBwKDCwODNyKjPzq7My+vIxiXAQCBOSOjPz6/OSelNySjNyGhMR+fLRaTGQ2LPz+/Nx+dNR2bNRybMxuZMxeXMxiZLQSFJQaHFwqJNyKhOSCfNyCfNR6dMxmXMxWVMRORLQODOR+fOSSjNR2dMQ2LJQWFMRWTLwWDNSCfMxeVLwaFKQODNR+fNx+fMxiXKQSDOSWlMRSTMxaVMQ6NMxORMQyJOTS1MxqXLwWFLRORMxKPMQaHMxKTLQWFCH5BAEAAAAALAAAAAAWABYAAAb2QIBwSCwajwGBcikIHIsDQmFKNRwQT2EgoVgsGOCG4wHBIgmRhWRCqVQsF0xGYyYGNgoGh9PpeCQfICEic3UAAWgLIxwRJBsbHSUREyYYJ3RDAQULexGejhueESgpl3WaCxsqJKKsChEUKywtmFoFDC4vCayikzCyMbWHt38NCTKiHhUfMyzBdQIFKsodob0VNDWzwppuKxMRrx6iNjcitNA4bh+iEzkwojc66JkOOxcf7G35PBE9KS1MEUGgIQOIFfk++KjRw9wJgUUIZvhRoyLDFCliQDQisUWLGCJOeNx4hKCGkyhPGnqCoKVLl1liypyZxUAQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactundo22:act act22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBCReDJzGjMzivOTu3PT69MTivHy+VJTWbIzKZEymJESmFESiHDyiHESqLAQCBFzKNGzWPFS2LNTmzCxqDDRqHPz+/KTGnBQqBAQOBAwaBESCHHy2XBxGDOzy7HTCTEyyJDSqFHzWTAwSBBQ6BIy+dESKJFySPFSSNAwiBCRGFBQmDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAalQIBwSCwaj8ikMsBkKotMwYAwEDiXgYLhwD0gCFZiQKxNKBYMRqPh+D6G16y5AYnYIxBJAyF4AwITTAUJdBESD4gPFBV6Fn6ABBcJDIYPGEQZGhQbHAIdfx4JHw2VSBodGwWfAR4LDSALfkgYAQurBiAhICKfSSMkvQElGyYnGyi9Rxkdj4nOskUYyU9FpxnURikdGtjRKivdRKfQ2Inh5+jpRwZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nactunlock22:act act22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBGxqbFxaXExOTEQ+RAQCBPz+/PTy9Ozq7Nza3NTS1KSipFRSVOTi5Hx2fJSSlKyqrJyenJyWnDw6PMzKzKyurDQyNFxWXMTCxJyanHRuLHxuLGReJFxSLFROJFxWJExCHERCHBQODISChHxyLHRqNIRyNHRmLLSqbKyiZLy6fOTarPz67Pzy3OzitKymZFxSJJySTNTSnPTy3NzSpMTChLSydKyqbKSaXJySVIyGRGReLPz23NTOnMzCjHxuPLy2vKSmpOTe5LS2tLSutHxuNHRuPMS+xFxWLIR+RDw2HFRKJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SDAQIDBAUChY2EAQYHCAkKCwyOjZANDgIEAQoPjJiDAg2iggQQp5gMBwmrDBESl6MTFKuoFQSjABYRF40CGAW8BRm7hQwNxBobHB0eHx4gISIjBdiEAhYFJBslHOHSHh4hBSHlxIUmJygpKissBiwtLi8pGjDqhBoxMjMuaNSwcSMFjhw6dnjYRyrGCh4ueviw4Q5HDB0/PjAUJCBCAwMIGiiggAEIBFk/FgYLIgRkggQkhxAJkqGExkYMFnxsIGRkSQgLHhRRWUjAggQgG8AsSWRBBiP6VrYMOfKIyaBDNwLo+HHSUplOSyDRqiEHjRkretRQkcLgxayNF0wksQGQxsSKMTIq0QpgCba/gAE7IhMIACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nappbook22:app app22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBDyGhCyCfFSWlESOjDyKjDSGhCx+fGSinGSenFyanEySjHSqpHSqrGympEySlBx2dISytHyyrCR6dKTGxHyurHSurHyytGSipCR6fARmZFSalEyWlBRubAxubBRydDyKhDSChLSytPz+/MzKzIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbFQIBwSCwaj8ikMhBQIpmCQdM5ZBIKhgNiugwkFAsCI7pNMhuOxkNBgBgEiAi3GkBLJpJHYgEpaClyREwVFhcSEhgOGQoMfgMaERtcARQBFRMYExZ6HB0FUYAekkIBHxqWFmlrC1haESAfG6MBGx+VFRgKYH0hInGRklO0ppYXCwwMWQiQHkwjgrWnFRdYZHIBJCTP0LaWGAcDW9jZ2nMAw9IWTOQkJSZMRsOV49nu8E+19PbmR7TY+1TovONH5V7Ag0QMBAEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nappbookopen22:app app22 22:photo:22 22:R0lGODlhFgAWAIYAAAQCBAQ2NPwCBHSurIS2tBx2dBweHPz+/Ozm1GxiTGyqpPz6/Pz69GSqpOzaxPzy5HxuVLSmlOTazPz27PT29NzClPTexHxuXLSmjAxqbFSinPTy9KyehNy+lPTy5Pz29HxyXNzWxKSahOzexPzy7IR2ZOTWtESenPTy7KSWfIyCbKyijAQGBDyalPTu3KSSdDSOjJyOdCSGhPzu3OzizJSGdPTq1PTq3JySdMy6lAyKhOzWtOzi1OTOrJyKbMS2nJySfMS+rAwCBNzOrNTCpNzKpJSGZKyafLSifLyylIx+ZHx6ZDSChAQuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAIALAAAAAAWABYAAAf/gAABAoSFhoeHAAMAiI2IAAQFjI6EAAaJkQeTjwAICYkKBQcLm5WdBwyfhgChB66bp64HCQC1lQ2irqQCAA4PowsLEBESE4wAuLIHFAAVFr+uDBcYxRm1GrmuGxwdFh4Mrh8gGCET1gDYyhsiFSMkDAsMDCUYJhvnJ9kHKCnODwwfPlBQsULCPRYAWogK9sHFiwoOPEyQh0JFPXO1YBSYwBEFghjdHkwQOYGgwQwIZRR44GHGDBogabhAsYEEihrUMAIoUMCEDRs3HODIYQHFA6MPcJA7KICFjgw7eIzo4cOfiwc/gKwIUm2SkKdDdlDt4AABDaU/iIRwwbTSUyJFOow4S3Hkx9oNDDZgXPU0h1wcSIgEGUw4ibVET5WoWMKksePHpdxmyKADAEIWly9HJtQkQJMmlAgZCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\napppencil22:app app22 22:photo:22 22:R0lGODlhFgAWAIMAAASC/IQCBPwCBPyChMQCBPzCxAQCBPz+/MzKzISChKyqrDQyNEQCBAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARYEMhJ6wxiEMtpIAWxddwXiqRlikSQeiAbuC+wirNR322gv7zcLobzDU+9XypoBBKTR1lz+RTWDgip8nUwZK1XLyIx5XoVicX2RUAo1DVKi7GOBxjxfNwQAQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\napptool22:app app22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBISChFxaXNze3NTS1Ly6vKSipNTO1Ly2vNza3Pz+/MzOzOTe5DQyNOzu7MTCxGRmZMTGxPTy9Ozm7Hx6fPTu9MzGzGxmbAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAW1ICCOZGmeaEoGbBsI6joMRGEcbQwESDIrtVtAF1gwDLNaAmfKiVgLBJKgwB1KxQZrBHU0FAXmavFoQLYiB6TxFXMj5AZBwnJI2I3wcNWALyYEcgoKXxRhOHs7XxEVCwsWFgoUDRYUFwwQB25ZCxiNjo6GkwUXN2NsCxEYqhUHoQ0MEglYRQQXErcHrI55FycuB2YSmoyOBTEtB2sXuhU6XAENC2a6z9AKCwq+1tAN3E2J3ySkIQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nconnecting22:connect connect22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBPz+BMTCBISCBAQCBPz+/MTCxOTi5AQGBNze3Ly6vISChNza3FxaXKSipAAAACH5BAEAAAAALAAAAAAWABYAAAR4EMhJqwzY6omD+MNGdR8YilNZnug0qGzrqrL1lnV1fyJBVB6VQEMoGH4ADGwQkxQPBwMiKGA2J8VEAnq0tgiKg5aL/C7C2gTjKCM0zowDQ8tuNQznNL7cKzjOUQsNfER+gguIg19+Pm6ChBZFDmWNi5M5FIyYFHQRACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nconnectno22:connect connect22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBPz+BMTCBERCBAQCBPz+/MTCxOTi5Nze3OTm5Ly6vNza3ISChFxaXKSipAAAACH5BAEAAAAALAAAAAAWABYAAARiEMhJq7046827/+AVCKE0Dh9BAGdaGISAToFGFMcBU+11I4hDYseSZQiKwwKoI/QwBIYiuFDCZseGdIlYEjUNg1SpY6w2N4cUIW6cjwW1lsFwo+MqgtZuw0/ydw5vH34lBhEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nconnectyes22:connect connect22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBKyirPz+/KymrOTi5KSipMzCzNza3OTe5Ozi7MzGzPTq9OTm5ISChMS+xFxaXNze3GReZIyCjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWLICCOZGmeaBkAQpoGg7C6JizTQT7CxPwOwFWgYPChYIXkIHC4uQKGAiKRKCyNpxxUUVViVYNFLkqtLo+DAkMMLXQPXwAy2WCTF4544FGtKuwPDhB6DnxuUmyCcXIQhV1uYoMuEAcOBxEKCHg6TzGFCJUSizuejROKOAM9OY2SnUU7nD89NCcDsLUnIQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ndevscreen22:dev dev22 22:photo:22 22:R0lGODlhFgAWAIcAAPwCBAQCBPTy9PTu9Ozq7OTi5Nze3OTe5Nza3NzW3NTS1MzOzMzKzMzGzMTCxMTGxOzm7AwGDBQOFBQSFCQeHCwmLCwuLDQyNDw6PERCRFROVEQ+RDQ2NLy+vKSipISChGxqbExKTOzu7OTm5Pz+/GRiZMS+xLy6vBQWFLy2vCwiHFQ+NMSmfNSyhIxmTDwuLJx+bLS2tCwmHMyyhMyqfPTqpPzyvLSWbLSWfPzitIx+ZDw2PAwKDCQiJGxWRPTmrPTerMyuhPzqtPz63PTWnPz6zNy+nIRiVDQuLKyWbOTanPz21NS2jNS6lDQqJHRaTPzmrPTSnPzyxOTClPz2xNSuhPTqxPzuvOzSpAQGDOTKnMy2jOzSrPTu1NzKnOzOnBwWHJRuXLSWdPTatPzqvNzClCwmJOzSnOTOnPTuxOzKlOzerOzarOzitJR6ZNTO1IxmXPTWrNSyjPzOjPTSpLSehHRqZOzirOTCjPS+fPzGhOy6bOzKhGROPMy2lPz+1PzmtKRyRHRiNNTCdPz+zNzCjEQ2NKySdDQmJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAj/AAEIHEiwoMGBARIqXMhQIUIBAwYQIFCggIEDCBIoULBgAYMGDgIIDEBAwMSKBRBk3NjxAciQIwdACBBBwgQKFSxcwJBBwwYMHBx0EAmA5EwPH0CEsCChoYgOQ0cSGCHhA4kSS5syJGDiBNEAFVGUKKEBAwWFFM6SNJHi64gDFEKE4FBBggoKK1i0cPECxokYXw0gsECYggQZM2jAqGHjBo4cOtqOxLhDAg8ePXz8ABJEyBAWRIoYOfJipEoMCZEkuaFkSAslS5jUGJKkSRAnRREo0JDwCZQoTKQAmUKlihQrVa5gKZ1lI+oAK7QM2cJlSZMuU4Z4+TJEx0iNOwKAggkjZkyOFmS8kClzpcUQLRRGbjRD4MgZNEzSqKG+ZgobI2248dUbDDDwABzcxSEHEFpgEcUcdMRRhx1fFejAAx0cgcYdSxiBRx566LEHH0d8QFRRNC3Uhx985CHEH0MAEkhCBxWkgiCDFEFIEYUYUmONMhyCRxVH/PgjBYioYJAdAQEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditcopy22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFPz+/DQyNISChDw6PMzKzMTGxERGRIyKjFxaXMTCvKSmpHR2dPz6/Pz29PTq3MS2rPz69MTCxFxWVHx6dJyWjNzSzPz27Pzy7Pzu5PTm3NTKvIR+fJyGfHxuZHxqXNTCtPTq5PTi1PTezNS+rExOTFRORMyylPTaxOzWxOzSvNze3NTOxMy2nMyulMyqjAQCBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbYQIBwSCwahYGkUnk0BgTQ6IAQaBKfUWhBYKhaAU+CgXAQIAyChLeJzSIQhcH6GFaM0QtGY5kstqEODw8QEQELAhJTc08KBBMEFBUWDRcBE1pca20SGBkaEBscAY5maFRIAgoLHRQRHh8gIQFlZnByqA8ZGSIQIyQjJQEmYgJ5p2ACrK4gJx4gKIZZAgdeAQ4ZI9kjKSor0AwEjeAs1S0cHAslLi4vMDDRWeRIfEsxMeET4ATyVoYLC5fizXEiAR84BeMG+pEm8EsAFhAjSlR4hR6fLxiF0AkCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\neditcut22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBAwCBPz+/OTi5JyanOzq7DQyNGxqbAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARbEMhJq704gxBE0Bf3cZo4kRJqBQNRfBucyudgvJS6VaxLzyMa6/bLiWA9HOg4VIIkL5vzuRkcpkvRIIAorphJLzBW84WEuRZWp6uaT7J2Sh1Hit3OY/ZO7WvsEQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditdelete22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIYAAASC/FRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwKDAQCBExOTNze3NTW1MTGxLS2tJyanPz+/Ozu7BQSFCwqLDw+POTi5PTu7MzKxIR+fCQmJPz6/Oze1NTGvPz69Pzy7Pz29LyyrPy+vPyupPTm1BQWFIQCBPwCBMS6rPzSzNTOxPTi1NS+rPTezNzOxPTizOzWxMy2pOzaxMy2nPTaxOzOtMyynOzSvMyqjPx+fOzGpMSihPTq3OzKrOTCpNzKxNTCtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf8gACCAQIDBAUGBwgJCgsLgpCRAAwNlZYODxALEY+SkAMNEqKjEw0UD5yegqCjrRMVEqidkgWhraMWF7GptLa3EgEWFRSOnhW+vxgZEBqzkBvItxwdHryRCNGjHyAhHSLOgtgSI60c2yQjJd+eJqEnKK0hJCgnJSngAO0SF+8qEvL0VrBogW+BLX4oVKgIyMIFQU8KfDV4R+8FDBcxZBREthAFiRIsOsygsVEUh4Un3pGoUcPGjZInK65QicPlxg8oX5RwqNJGjo0hdJwQ6EIkjRM6dvDYCKIHSBc1Ztjw4eOH0oIrsgIJEqSFDBo0cuTgsdSTo7No0xYTZCcQACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nedit22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBISGhISChHx+fHx6fHR2dGxqbGxubGRmZGRiZFxeXFxaXFRSVIxSLPyuXMzKzMzKxMTCtExOTPzqrPz+/NTS1MS+tOSaVPyWNPz6/IxeNPzavPyKBNTW1PyCBPyGBJxmNPzOpLx6PNRqBMSCRNySTPyCDPSGBMxiBKROBHRydPSylOyydMxmBJxKBAwODPS2lPTq3OyabJxGBPTy5PTGrOyOXPR+DPz69PzmzPzevNxuPORqLMReFPzy7MyCXKxiNIRKHBQWFNTOxPzixJRaPFxONHRqVPz27PTy7PzStCwqJDQyLJSGdIx6ZPz29PTu5HRmTLSKbMSGZHROPFxKPJSKfJyShKyehMyuhDQmHEQuJJyOfLSijMSynMS6pLSefDQyNHx2bKSahLyqhLymhOzi1FRGNIR+bNzKtOTOtOTKrOTKpLyedAQCBFRWVPTq5NzOvLyunLSmlNTCrOTOrNzGrLyidMS+rLyynKyijLymjLyqjAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gAAAAQECAwQFBQYHBggJCgsLDAwADQ6CAQ8QD5ydEJ+gERKWE4ICDxSpqhWqqhYNFxMYphCtqaytGRoXGxgcggSoth25u70eH8APFR0VzMzNziAXIRjIvwAFwq3EqSLUGB/iI4LathS4JCXVJh8nKCmCKrXDFCss1eIfLS4v8ssdmgWsAGNDDBnt3s3wJ+jAtlUhaNSwccNEi4WCBBl4SAHHihw6ZOzg0QNjRgAG6KXK4CNEjBU/gDQI8kLISQAIADobAoMIzCINjLw4YvNkAno4kCRRUuNHESNLmDRxUjSjAlRPfECJImUKlSpMrFzBIqWqoKtJaWSJomULAy5XXrp4+QKGYcYFoCBEWRImi5gmY7CQyVLGriAGD2jEMHMmCxc0Xb6kUbOGTRs3N988gLM4jpw5Y+iwqcOGjZ07mE8yiGABz5c8c/Ts4cOnDJkybS7fdMO7t+/fvDMaCAQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\neditpaste22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQWFDw6FHRuFGRaBFxSBAQCBAQKBCQiBIx6HPz6/NTOfKyiXDQuFOTm5Pz+/Ozu7PTq5Pz63PTyxNTOjKSeRExGLMTGxMzKzNTS1NTW1Dw2NKSmpKyqrKSipJyanNzWlLy6ZLSuVIx6FISChIyKhJSSlCQiJLS2tDw6NDQyNCQiFCQmHBQSDGRiZHRydGxubHx6dGxqbFxeXGRmZFxaXCwuLOzq7KyurHx+fDwmFEQuFCweFCQWDBQODBwaHBweHKSinJSWlOTi5JyepHR2dDw6PBQSFNze3ERGRIyKjIyOjISGhPz29Pzy7MS2rMzOzFRWVHx2dHxybDQiFPz27Pzu5PTq3PTm1NTCtJyGdHxuZHxqXPzq3PTaxNS6pFxWVFRKRNS2nPTi1PTStNSulNzOxNSynMymhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCgwABAgMEBYSLggaOjgcICQoLDA2Pj4MGDg8QEZ4FDxITFBUWFxcYGRobjQ8cHR4fCQ8gCyEiFSMWJCUkJieNEB4dKB4pKissK8wrLS4vMDHBAAYQHx8dFx0fJDIzNDU0M+IyHzaNNyg43Ng5Ojs7Ojw9Pj9AMkCNDiZB/h9CSOx4QLCgihItqBkYgqIDESElitAYWJCgkQcXjjRCgi1Ihw4BB5LAQOLCgyQYHihpUU3DBw5ElpAgAYNixSRJjKjQaECDCRPZPDB5IbIGSQwKLnh4wbInLA4kmJB4oaPiAwVNnER40hRK1BIAaVatUZJEFCkmpmjgCeWDCalFe4q4oFKwSRUrEa5gycLzwq8lUnPQ4PEgSpYcUZ5o2cIlS1O/JHLEDdfjQZMIVrpgweLFy5e+M6WSmBGlxYMYYBRzCaOFi5imHWBIfOEiShLTVjaP6eyFTBmN1TA5OvLDjJksWb58OVMGDRqWjAYdmU79SIvpjqJr104nEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\neditshred22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBFRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwKDAQCBExOTNze3NTW1MTGxLS2tJyanOze1Pz+/Ozu7BQSFCwqLDw+POTi5MzKxPTu7LyyrIR+fCQmJPz6/Pz69Pzy7Pz29OzaxPTu5PTq3PTm3My6pPzu5PTq5NS+rPTm1PTi1PTezOzWxPz27MyynOzSvMyulOzOtOzKrMymhOzGpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbpQIAwIBgMCAXDAZFQLBbCqJTRqFobjgdkEYFKowPJZEyeUBqVR/crHDTKZYplovZKCW84+YKZZNZSBXl6EwEEBhVPXxZihGMaGRscdkIdg4QeEnVfCH2OHyAhIhuUAAiXZSEhIyQlJqWnjiEnKCWupRWoYyEgJK0SKaUKjam0JCorLMFfC6iqx8giLa/MGAsT1wsuCyULKwssC9RSzdkfCyALKuALLQsvpeXYIQso3gsiCzALMfENC+dGcMNHUAY/f+jq3ctncMYCGggFrsvHcEGNh/EyPFmg8cmrJxAVkVO0EUDJklHoBAEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nedittrash22:edit edit22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBERGRExOTDQyNISChBQSFCQiJCwuLPT29Nze3GxqbDw6PGxubHR2dJyanLSytJSWlJSSlOzq7Pz6/Nza3Ly6vFRWVBQWFIyKjMTCxHx6fIyOjLS2tOTi5PTy9OTm5Hx+fNTW1KyurKSmpJyenExKTMzKzKSipFxeXCwqLMzOzKyqrMTGxLy+vHRydBwaHNTS1DQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb8QIBwSCwaj8KAMoA8LgUDQsFwQByay4RiwWg4GA9IRGk0SCYJSsUCsVwwGQ1EsmESD5xOp+L5gDwhBRIZDhcDdkMGDgEiIxAkJQ8Ok5MmAohDAQ1xJxUlKCUlEg0pKpiZJRoLCxmtCw1eURhOcR4rbQ8cGRwLAwgGtBYTDywtGRKjvQTARgEZLhMcKC0OrQMvAirMRc7CHCTU1g2+20TO0NIn1RwDCya/wdHT1Rnt5LToKOq79trx0tR02YPX7Jm8fRxMOIhSLhOJE/LCJSTlr5kFEBQsWDiR4UGGBgsuHDg1BEYAfTE6oEBR4AIBAiS5yWBAAAGBAyaPGAgCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nfileclose22:file file22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBERGRERCRDw6PCwqLExOTFRWVHRydGxqbGRiZCQiJISChIyKjHx6fDQyNBwaHJSWlKSipBQWFJyanPz+/JSSlCQmJAwKDCwuLBweHBQSFGxubExKTISGhDQ2NFxeXFRSVDw+PAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbZQIBwSCwaj8jkMSAYDAgEJbFgOBwQCUOAoJAaFgvGonHIBhyP5BcSgUAYDWxggD4WFmx3e3HQngkSRgYMEBMUFG4MCId0BGlEAQeEhocVDYcUdBYKF0QCB3gRlJgUAQEYBBkaRAMbDZMMpAYcT46rQwMJrgsdC6QcfwoPnUMOBgkIV6SHHg6bw0QEAQYfBpggBZjPGsRD0gEchxwCIR6HChnQRQ8DIU4DTR4Em+ncRw8O+fmoXPXdRg+gQLFgIYM/KRIkoDP4QMKFf0o0aBAh4qGUixgzCrETBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfilefind22:file file22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQSFJyanLS6vLzCxISChNTe3OTu9Oz6/Nzy9Nzy/NTy/OT2/Nzi5Mzu9Lzq9KTe7LTq9PT+/Pz+/Nz2/Mzu/Kzm9Jza5HzK1LTi9PTu9IzW5ITO3FxaXNT2/KTi7Iza7GzC1LzW3FRSVMzO1MTq7HTS3Fy6zFS2vKzm7Lze5MTGzHzS5FTG1Ey2xEyyvJze7JzW3ITa5FTK3EymrGS+zFxWXKymrMzi7ESirEyqvLSyrKze7MzOzMTCxKSepAz+/NzW3MzKzBwWHLzS3ERCRAzi3KyurNze3MzGzLy2vLSutCQiJAyytHRydOTe5MTGxLy6tLyqpKyelJSCdOze3NS+tLyupLSmnKSOhCwuLPzy9Pzu7Oze1OzazOTOvMyihOTi5PTm3Pzi1PTazPTWxOzOtNSunDQyNPzy7Pzu5OzKrNzSzNzGvNS6rMyynMymjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCgwGFhYOIiYQBAgMEAwKHiokBBQYHCAkKCwwFAZOEBQ0IDAsODxARCZ6gAAEGEhMSFBUWFxgZCJ+TjBoMEpkRERscGBGRih0BBAgeFBQOER8gISEfIruIIwEkCCUVwhcgJicoKSrZg9srCRkRGdMsLS4vMNiK2wIKMRsbMiwzXtCocSydIBs3AuCIwIFDiBMucugAoWvSiB2VNPDg0ELHwA0MkCXr4aNSggg8NoDIQOFHgBtAkgURMiDAEAFEVBCJFKCIkSMGOyDRkETJEkOFmABoUsRJQkQdnkzQACWKlBtTplBR6qopxkFRJ0ytYuWKFCxZtBBq+hRA2AlbRrh08fLlCxi1a51g+dQhDFwuYsaQKWPmDBpKXgNETaNGjJgyhNfcVdTTiWI2XpK0cePmzRk4YA5T5otGixY0qFOXbgXAQCAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilenew22:file file22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBExOTERCRDw6PCwuLBwaHAwODAQCBOze1NTW1OTi5Nze3MTGxLS2tJyanPz+/Ozu7OTi3BQSFCwqLDw+PDQyNFRSVPTu7MzKxLyyrIR+fCQmJPz6/NTOxPz69Pzy7PTu5Pz29Pzu5PTq5PTm1My6pBQWFPTq3PTm3NS+rAwKDPTi1PTezOzWxMy2pPz27PTazOzSvMyynOzaxOzOtPTaxOzKrMyqjOzGpMymhPTizOTCpNzSzNTGvMymjMSihCH5BAEAAAAALAAAAAAWABYAAAboQIBwSCwaiYGAYEAgFAqGg/Q4DCASCsTiymgcHAcqQLB4mM+QiIQBppLPcMjkwQ4bB2X4maKgt4sVCHpnFhQTElNFE3mDDxcYGRp2RBuMgxwIHX9EBZZwHh8gCBmTQ52NISEiIyQlpUImng8hHyInKAgprwAqgnC0IKwrLLpGB4wctLYkwy0uuwd9Z8AnJywsLcVFx2YcL7UnJCwwLTEy0GXJoSgrCCwzNDTnxgjeH9UrKzXwNDY36LRGhEOwLx4NHDmgJbh3QoeOgv127EhojEeHDj16pEhRQoZHHzl+QJNCsqTJSXaCAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfileopen22:file file22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAQCBCQWDCwaDDwmFPSubPzGhPzCfPy2dOSmZPzKlPzSnPzOlPzKjBQODPzChPzWnPy2bPSmXPyuZOyeXIRSLEQuFEwyHEQqFDQiFCweDKRuPFRSTPT29PTy9Ozq7OTi3Nze3NTW1MzOzMTGxMTCxLy6tLSytKyurDQyNMzKxOTm5OTi5Nza1NTS1MTCvLS2tLSyrKSmpJyenJSWlIyKjHx+fFxeXBwaHKxuPMzKzLy6vIyOjHx6fDw6NPy6dGxubLy+vISChCQmJNza3KyqrBQSFLR2RKSinJyanGxqZAwGBJSSlCwqLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeDAYqKiIeLj4wBjQCMhY+NkoiLk5qbhQIDoJyGBAUGBwgEo4MECQoLDA2pDrS1tKQPEAwHERITE77AvxKqhAQNDA8UFRYXFs8YBAQZGqGPxw0RGxwdHR4eHyAhIiMkJSYnKCgpBAYPEhcqHyssLS4kLzAxMjM0NTY3cBA4UCAHBw8gVnhgEcKFjhc7UPDj0cMHAAI/KFgY4YLFio/jRpTYsW8GDyCSCEQw2DChOHIqgsCQSEPIEEEEJFhAoUNECCJEyOk4d6KIyRtGcB7hIJKjixEjHu4oimSGEIs4d8IIUoKECnNB0ElMwkNJJgBLlJBAcQKGiR07KGAURVGViY0mhIwwSTKjr99+THjUoIg0r48hTRIrRtxkiOMhDgrZCQQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfileprint22:file file22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBFxaXDQyNFxSTPTizOzi1FxORDw2NExKLPTi1Pzy9Pz6/FRWVPz29Pz2/PTy7PTu9OzezPzu5OzavAQCBPzy7PTm3OzazOzKrPTu5FxSRERCRGReXPTq5Pzu7ExGTMS+xKSmpOTKpPTq3JSCDNzSfHRydLyadOzCjOzOtOzSvLyyTMTCxKSipGRiZFROLPz+/KyurJyenJyWnGxmbLSabOzClOzm7LSutJSWlJSSlJyanGxqbNze3OTm5IyGjNTO1Nza3NzW3OTe5IyKjHx6fMzGzMTGxMzOzNTW1IR+hISGhKymrLy6vLSytERGRGxubKyqrLy2vLS2tDQ2NEQ+RASKBAT+BFxeXHRudAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAgOEiYqEAgQFBgcGi5MICQoLmAQDh5OEDA2YCw4ODxARApKUCaGYEAsSCRMUnQysCwoVEhYXGLOLCBCgDqK5GQUXGooCAhscBB0euBUZEAUJvQgIgx8gIR8iCSPiHuIFEREDJCXaANwhJhsnKCnWERcRKiopFCvsBywhQrRwQWGAPAz5EhpQ9wIABRgKYsiYMTEEDQocatiwkUIEP18fbkCAAcMBjhwzdOyQwYNCgBMfKJSgMItBjxs+btwgCSGGjhw/ZoRgQKGZCRMUPgABEgSIkCE3SZok8qNqkR85NtDUEcPIkaVAkCR5SrJBDCVKlmzQ6pCCiRlMTJo4YUH3K5AeMBYYWctW0BOaUH60cBJFypQmII6wyEpFQBVFMSm4UAI3hJUrOGh8oOJrklYKWIromJGDR99Ogz5j4ZGlM+pEnwmBCwQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nfilesave22:file file22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBGxqbAQCBLy+vERCRExKTHRydIyKjMTCxFxaXGRiZFRSVFRWVPz6/Nze3Nzm5Pz+/JyanDw+PExOTHR2dMTGxBQWFLSytHx+fISChOzy9Ly6vAQGBJSWlMzKzAwODJSSlHx6fIyOjOTi5DQ2NISGhGxubCwuLOzq7ERGRFxeXNTW1CwqLPT29Dw6PGRmZKSmpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAb/QIBQGBAMj8ikUDAgFAzKKCBwQCQUCcICKh0SEAhGw5EIZAmBrgCxeDQgcDJWyz0GIggJfL+XGwQJRxNgC3yGDwwUFUZDFhdthnwMGAZNQwEZFwQakXANBBQbHIIdERIBnRAOiR4ERx8gsSEMBBmGCyEGG3YGBwcgIr8UCwQHECOgG4xCtRkEJAvBJRklJgkSFBQeJ68hJiEoESkFKiEZIbkGARsLlwEGExENGhorGSkpFAYm66NDLAECpGiBYsUIFA8wLHBBQMWLVkdUCFCwaYVFBOymkVCgYEMgOykEpICBccMBAhhELFigTEqAAgIIwCiQ4eRKDyS6EAlJIAI0EpaudF4iIKDAAn9CkRT5eMROEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nfoldernew22:folder folder22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBNzaTPT2FISCBCQaDPz+BExKBDwmFPSubPzChPzCfPy2dPz6BMzOTAQCBOSmZPzKlPzSnPzOlPzKjBQODPz+rPz+3PzWnPyuZPSmXNyaXPTyhISCLIRSLEQuFEwyHPy2bKRuPFRSTPT29PTy9Ozq7Pz+xJyanDQyNPzGhMzKzOTi3Nza3OTiVBQWFDwqFKxuPOTi5JSSjISChHR2dGRmZFxeXPS2dNTSzNTS1OTm5KSipLS2tLSytKyqpIyKhGRiZNze3NTW1MTGxMTCvLy6tIyKjCQmJMTCxMzOzMzKxJyenHx6fLR2RLy6vJSSlHx+fDw6NLy+vIyOjAwGBGxqZKyurCwuLBQSFJSWlCwqLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeIiYqLjI2MAY6HAgOHBJYEhJCDBQaDmgcICQoLB4MGDA0OAQUBDg2cAAcPEBESE6QUuQasFRYVq5SxCRcSCggYGRjIGgYbFs8bHIMHExIJGR0eHx7cB83PFhsDDuTUEyAhIiMjJCQluwEmvsAnKAcp1x4qKyUrLLupWrByxcnFiwQIYIggEaNEiRgBZMyYQaNADRs2REA6cCODBxw5+OnQgWMHjx4+BND4MQOIg1gI0gUREkTHiplDhhApEoCGkRlHBL3I8MEHEhz+WAhJogTJySVMfthwIehAExE5jubAkYQpESc8fOx4AiXKNA8+ekhBgqSpzh5hPHcsmVLjpSAqVZBY6VGkiJMiPQKLnTvjCiEsWU4o3nGC8YksMmT8YCmC6iAXKLRc2cz5yGYtR0JjKWQgEAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmailforward22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBJR2dLyijPTixPz69Pzq3Pzy3Pzu5PTu7Ozi1LyelOzavPz+/DwqLLyafPTmvPz67Pz29Pzy7LSWlPzmzPz6/LyajPTitOTSzMyurPz25PTatPTi3KyOjPzuxAwqVDQiJHxiZPTetKySlPzqvPz27BQ6bAwmTPTexLyinNzGxDRunPzy5KySjCQ+ZNzq9KTO7JzC3Nzq/Ozu/LzW7FSm1BR6vGSWvFyq1AyGxAxytAx6vBSKxAxSjMyujLSunES+5BSi1ByGvAQCBNzCrOTaxNTOvMS6rKyelCx6rBx6tBQKDOTWvPzu1PTq1OzezAQOHAxGdBROhAQGFPzy1NzOvIRqXLyynOzarPz21Jx2XPTWrLSShAw2XKSCbPzuzAwePAQCDPzyzPzqzPTmxOzWtAwGBKyObOTSrNzGrKyGbOzatEQyNKyCZOzWrOTGpNS2lCweHCQaHCQWFBwSFBQODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBhBwgQKFSpY0HgBQwYNGzh0mDhRAAUPHziACEGBpYgRJDiUGEkSwoCQJk6opNASRQoOFETQJDkggwoOJlYApcCihQuVL2DUhBDjhIqjJmRwwDCDhswaNm5MjYHjKggOOU7o0CGTA9gdYknG2KCCBw8VJVL0uBgihAUfP+CSNGCjsI/DiBPbAMJBsEQbQYQM+UG5smUiRYw0jlvYxhEkSYyIHm1EyRLTTH40EZvAyZPOR4pAmU07ipIkUKQ0mQIhAZUqVq5gKXzkSBYtyLVEyd1ki8QFXLp4+WJFQowbYLJnD5NbzJiJCjaQnhnvpYwZM0/OPFlvQ/f3iQvQpBlvQc0aCWy4VKnCpY0Y5yQxgEYXZFjghgwZUOHGCW90YQEccUwloBwGyjAHHXUoSAMZb0xhx1QOoMHDHSfIwSEOdTjhAQ1d4MFbTQ6Q4MYacrzxhhx04JCHHhvQsMeLJPHRBxpr+LHCGnusgccfgKixQR1ATtTBlDDAEIggggxCCCGFbLGFHVFKZEdAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailget22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBBQ6bCQ+ZAwePKTC5Ozu/NTi9GSWvAwSJGSu3JS+5CR+rAQOHPTy/AyKzES23AwOHCw+bOTq/BR6xES+5AwmTBw6ZMTW9Ax6tByi1BRGdAw2XAQCBDQuNDRupKzS9FSm1BR2vBym3EzC7CSGxBROhNTW1Pz+/OTm5NTO1AQGFNzW3Ozq7Ozm7IyKjJyWnMzOzNzq9Nze3OTa5Ly6vCQiJGReZISChKyqrAwqVBRWlOTi5MS6xJSWlNza3OTe5Ly2vGxmbKymrIyGjMzGzISGhKSepCQmJDw6PHR2dJSOlPTy9MTGxLy+vLS2tMzKzLSutMTCxLSytKSipJyenKyurJyanCwqLCwmLCwuLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4IBhgIBA4SLjAABBAUGBwiNlY4FCQoLDJaNAQ0ODwsQnYwREhMUE5ylFYYRFhcYGRgaGxsDHJUdFR4SHyAhEyIjJCUcuo0cJr0nExihxgwoyYscKSnMHicOIw4lKissLdWDHC4vMCu9McYqMjMyNOUANTY3OPEoOTolDCszdrSgwaMcBxs9TMxYOCMHBx8zfPj48QNINQ5BbMBIIUShDIUoTAhR94PHPEEHbQwZckOGjBQviMxYUWQIDCMmdXE4gqRnkiFETAxR8iKFjJU2evZEdmLJkgJIbqS4wXJIUapImj5FtuSEVyRVV1IVi4RIChhEkLVAgcJHEqVwVJUmYdKkiRNkALMRecKECRG/ff8CEQJFCA5kMKJEoUHDCQ/HkB9LmWKECpUeyKoIMSLEyosen0OD7iH2xg1dV7BkqXGlBpbWNTq4Zn2khu0aAAwEAgAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nmail22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBDQyNCwqLCQiJBwaHBQSFAwKDAQCBDw6PPz+/Pz69Pz27PTy7PTy5PTu5PTu3PTu1PTq1PTqzOzmzPzuvOzitPTmvOzivAQGBDw+POzevPz67Pz25Pz23Pzy1PzyzPzqvOTavERCRKSilPz21OTevIR+ZExKTOTi3JyanLS2tPz6/Pz65KyihJSKbMS6lExOTNTW1JSWlJSKZMSylNTOrNTKpFRSVPz29MTCxPTmzKymjIyCdOTWxOzexOTWrBQWFFRWVOzu7MzKxJyalOzatLSulMzKtOzmxOTarFxaXKyqnPTmtIyGdIR+bOzetOzixBweHGRiZOzm3NzWzNzSrOTetGRmZOzizOTexOzm1JSKdGxqbHRydJySdHR2dOzapHx6fKyijOTixCwuLHx+fFxeXERGRDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4SFhoeIiYqLAQECjwORAwSUBZYFBpkHmwgJCgsMDA0OD6UQERITFBMVFhcVGBkangq1ChsLGxwcHQ0dHR4fICEGIiMSCbS3uLq8wCQUJSYGJygpKhQJKyvLLM4Nwi0uLwUwDQsxMtmeuQveHR8UMzQ1NgU3Dgo41jk6ns0cKOzgYaOHjx9AgjTAUUvIECLZNmxoUISHkSM9KiBJQkCJA4kKEoBQoWJJAiYtmjh5AmVCsCJRpHzckKCCySlUUvBYUqUHDysSPnxIEuXKA5pPRiRwxwFLFhRaIEDYUoEChCcDuECoOWKFuwW7nHkg4WELkw8/BHRRwESpt10dU8SSHevlRxIBX6C0WBE27q8GZMkKbTADjIAwYlb4GLMYShYoPTRo6FGiSJEKPyzMIFMmzJcvXbhwkSLFjJkbQW6cOHNGhAgEAdAsmk27tm0ABgIBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nmailreplyall22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBLyejPTixPz29PTu3Pzu5Pzy7Ozi1LyelPTavPz+/DwqLPz67PTetPz69ERCRLSWlPTmzPz6/OzexLyajPzqvDw+PDQ2NMyurDQiJPz23PTatJyenAQCBPTevPz25LSajOzq7HxiZPTexPz65JyanBQ6bKSmpBwuTOTi5OzaxBRCdHySvGRiZHx6fBQSFERGRNzq9IyOjHx+fGxqbPzu3BwaHFSq3Aw6XAxKfPzy3Gy63ByWzJzO7Mzi9OzavBRytAx6vCSazGRKTPzy1AQKHBRGdBRyrDy63ES+3Cym1CR6rBwWVAQSLAx+xCyCtBRmnPzuzAQWLAwePPzyzKSCbAQOJByGvOTWvPTmxBQODFQ6PPTWrPzqzOzatAwGBKyObLSWfPTivKyCZEQyNKyGZOzWrOzWtOTSrOTGpNS2lJx2XDQmJCweHCQaHCQWFBwSFBQKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpkzGjhAoYMGjZMpMghQgcNFjh4mODhA4gQGkSIHAmBwAgNJEpo8KDSxAkUGjhMSEGz5gUVIiKs2PmBRQudHiwQpUnAxYsXImB0aBqjBcuoU0fKmPGChgUNH2qIqGHjg9u3bicWIFs2rYgbNnDkyGFhb8cccQ3ouJqWQo0dPFr0WMy4h48LFj4gsKriB5AeNngEaSGks+chPnwQOXFAh4oXRYxk9nAEyY7XO2wksWHDx5ATCDIoUXEBsYclTJo4cWJhuIjhSXacSPBEiZLMQY4wgRKluvXqUpyIsDElAxUqVaxcwcGCPQuWLOixaNHCZAsXBU+oqKDSxQqULF6ifNmyn/8VMOtxwcAK36kQRhdJQIFFEmKM4eCDYGyhhYAEkqFEGSuYYcUZLaDxXRpqSNRCEu6twYaFZXTQhgRd2NCCG9918AYELTjoXgNuKAFHB2RQEUYHVbQQRwlUpPHGGFwkyQUEDsgxx4lh9BhCBy2U8UQJcrSg5JIQ0FEHG3bc0QGYK+CRhx57PEGlkhM9sAEffKTQhx9+/AEIIIGoEUgLLRRFR0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailreply22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAJR6fIxydIxubIRqbIRmZHxeXHRaXHRWVGxSVGROTFxGRFxCRFQ+PEw6PEw2NEQuLPwCBMSihPTixPz69PTq5Pzy1Pzu5PTq1Pzy7Pzu7Ozi1LyelPTavPz+/DwqLLSajPTetPz27LSWlPzmzPz6/PTexPz67Pz29OTSzMyurPz25LyajBRCdPzuvDQmJOzexPTevOzq5BQ6bBwuTDQiJHxiZPz23Pz65LyinPzmvBxCbHySvAQCBOTi3OTq9CweHOzaxFSq3Aw6XGy63ByWzJzO7Mzi9OzavNzq9BRytAx6vBR6tPzy3AwOHDy63Ax+xCSazCym1CR6rBwWVOzizAQSLES+3CyCtBRyrBRmnGRKTPzu1MzGtAxKfAQWLAwePPTizMy6nByGvNzWxOzWrNzOtBQKDJR2ZNS2lPTmvBQODPTatKSCbOTaxLyqlAQKHFQ6PPzyzPzqzPTu1PTivOzWtKyObPzuzOTOtLSWfPzqvAwGBKyCZPTWrPTmxNzKrEQyNOzatOTGpJx2XCQaHCQWFBwSFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpYuIDBQgYNGzh08DCR4oQPIDqEmDBhJQYRIzqQIFkSAoESJCKkDGFiwgkUKTpMwECz5IASKjqsSMlSA4sWQjG4qGnzhYoQSmF0iCFjBgmWGWhQrVHCxg2sOHLo2MGjB0sLYmsWQHq1p4wdPtqemGDhB1UDQFSouKHi7oQgQmSwUMyYxcQDZQWz2EFiCJEiRoyQyLzZyGIIB47YKLwDSRAiSZSoXq1kCRHNLBK8YGKjCYskTp4ogeKkt+8oUaBImZKAAxMmVKrctqL7ihTnz7FkAT5FC4cKFbZwadIFdxcvX8KLss8iJcoUBUcq2KgAJoxyMTy4jCFTxoxEHl2GLyCDncmWM2hUIQMPY2CXhhoTfTEcA2tgVwEba7Thxhs88FdBD/ZB8MUUHMJBRhw2sAGCHBKU4UaFc1RAhxnhcdhhHUzYAUIcFdxRAh4R5KGHinu4OIVEDqTBRx81xhGHHzD8wQYQetDRI4cTAcIHGWT0EQgZa1ApCBqDcBAID1Q94IEHLtBAAyGEFGKIIWqYYQYPYNZkQEAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nmailsend22:mail mail22 22:photo:22 22:R0lGODlhFgAWAIcAAIR6fIRydHxubHRqbHRmZGxeXGxaXGRWVFxSVFxOTFRGRExCREw+PEQ6PDw2NDwuLPwCBLSijOzixPz69PTq3PTu5PTu3PTu7OTi1KyelOzavPz+/DQqLPz67LSafOzetPz27Pz29KyajPTmzPz6/NzSzLyurCwiJPz25Ozi3JyOjPzuxBRGbAwSHOzexPz23KSSlPzqvBROdISavBxSdAwaLHRiZLSinNTGxMy+vBxGZNzu9BSGrAwWJMSyrKSSjFy61ETO3BRWfPz65PTqzHTK3ByqzBSWxEzW5AQWJOTWxBRCXOTu9BSOvDzO3ByavBRKbOzaxOzizKSWlCQ2TAQCBJza7BRWdNzSxJSCbMzq9BSOtCSKrAwiPOTavPzy3LymlCySrAwmPFRKTPzy1NTGrPzu1JR+bOzatPzyzCy61ByGpOzWtJyCbPTmvPzuzIS+3FymxCSuzBR6nJyCZOTWvKSObMSujOzivAwKDOTSrNzKrJyGbDwyNOzWrMy2lIx2XBwWFBQSFBQODAwGBAQGBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABAALAAAAAAWABYAAAj/AAEEEDCAQAEDBxAkULCAQQMHDyBInBgggoQJFCpYqMDxAoYMGjZwmEixg4cPGzqA6BBiAggRIzaQGEkSwgAMJCKgnNBhQogSJlKGOFHTpgYUG0TsnJBCxQoSE1i0KErAxYsOJJRuuAAjhkwZM2jUqGnDBQoUHTbciIEjx4YNOmbs4CGjB8kCZlGAALHBx4+YcTcACcJDyFSJBo6iGNIhhQkiG8BOKGLkCBK6SSQisHoWhZIbG5bMYALECI8mTZw8gTL1QJQXZ6VMiUylSpUlVpoYaXLFtm0EGmCjwJLlA2O9MrRsccKlC8kEXr7AdgEmwtkhX2SQ2BIkjBiSYzSQr/nyhUKZLIrJJOcexvlEBV7IvCBjRkmAMzHOaufhxDvJBWiQISAFxUUQQRovJNeEGmu4JxEDbKQhXxsfuFDGGW68IQMcccgxRxUkNRDhC3R8QMQIdZwXQ11JJGFbiB+QYccHaaTxhgt13OFBDGTgkUdRDrhAhx5k2JjGCB/swYcXMXwAYk190OGHHx/4wUaVepTxByAaoPEkSQ5wwMEJZAZipiCDDJIHIYV8OZEdAQEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnav1downarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBBQSFAQGBDQyNExKTHx6fGxqbFxeXGRiZFRWVDw+PAwKDJSWlOzu7LSytJyenJSSlISGhISChIyOjFxaXDw6PPz+/MTCxLS2tIyKjKSmpKSipJyanAwODDQ2NHRydERCRFRSVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZzQIBwSCwaj8ikcslsOp/OgHRKlQoCgymRUDAcEIkwYgxWFBYERpHQcDwgEclEQmk8DhWL2kiIXDBwExMNGRoJaUkEEH8bEQ0cGgcWAksEHX8QHBKSHk1sfxMHH5ROBBsOICGkT2wiq1CIULKztLW2t0h2QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav1leftarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExKTJSSlHx6fAQGBOzu7GxqbJyenPz+/LSytFxaXMTCxGRiZKSmpISGhFxeXISChAwKDFRWVHRydJSWlBQSFERCRIyKjDQ2NIyOjLS2tDw6PBwaHFRSVDw+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZ5QIBwSCwaj8ikchgQLJGBgfNZDBAKBirRekBMtYGEYsHIgsWNhOO7tCrShDU18Hg/CJAIG0o4wCUQcksTFBUSCRYSEnpUFxgIGQkJGYyNGggbHBaVjR2QCxEeWkITHQ4IH3tPFwEMA2ajAKUgqlQTTbFEE7W5vUgGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav1rightarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNGReZAQCBMTCxGRiZMzGzOTm5LSytPTy9Pz+/CwqLOTi5Ly6vCwmLMzKzJyanJSSlBQWFKymrIyGjCQeJJyWnISChISGhHx2fKyurDw6PAwODHx6fHRydDw2PERCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZ2QIBwSCwaj8hkMRBQKgOCgRMZIBSk06XhEM0SA4iE4uoVLhCMhqLrdSAekMgYO5VM4BQ521mxIC4UFxBWdEkSERYYFxETGQGFSBKCGBEaGRuQSBwdeZaPXpsQCB6YZQMdEI6ZSgMepKusHh+wrCC0rLdlursGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav1uparrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBFxeXDw+PMTGxHRudPz+/JSSlLSytIyKjHR2dISChIyGjIyOjLSutLy6vKSepJyanISGhJSOlOzm7Ozu7MzGzKyurJyenDQyNGReZKSmpIR+hCwuLCQiJBwaHBQSFAwKDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAZtQIBwSCwaj8ikcslsOp9QYyAQFQYEAyr0Sihkn1fDAeHVLsOJNELxVaITC0bDUU6GH5AIQ8KYrNtFVxQVFBYWFxgRCREYdUQZGhYEDwgIGxAHCQocCgWOQhmhGR0epR8gqCFTq1Wtrq+wsUt0QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2downarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAQGBBwaHDQyNExKTHx6fGxqbFxeXGRiZFRSVDw+PAwKDJSWlOzu7LSytJyenJSSlISGhISChIyOjFRWVDw6PPz+/MTCxLS2tGRmZDQ2NAwODJyanKSmpKSipIyKjHRydBQSFERCRExOTFxaXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAasQIBwSCwah4FkQKBsDpoBIqFgOCASCYRWm1AUFgRGkdBwPCARiWRCaTwOFYvYSIhcMOiJpJGZaDYcR0IEHXceEQ0fICEWIoJDhHcQHxIHgI9SEHeVG46YUh8OISOen1INCqWmUnOYTUxQAU9NUlRWWFtbCiRgrYNlZ2lriG8lYUd1khETE24gCZeCkRgeFBAQIAeNn9OTlXKrBJoYnKrcoaPmpmSpq3S+7u50QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2leftarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExKTJSSlHx6fAQGBOzu7GxqbJyenPz+/LSytFxaXMTCxGRiZKSmpISGhFxeXISChAwKDFRWVHRydJSWlBQSFERCRIyKjDQ2NIyOjLS2tDw6PBwaHFRSVDw+PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAavQIBwSCwaj8gkMiBYNpeDZzEQXRIKBmPgmtUSDgipcAsWjxOKBaN7Tq+n6EbCIQ3E5+KtQk6gjwl7CX11D3sPBBARTQGFDYeJT2R8EhB0koKUfgATFBUSCRYSEoqcnqCiikMXGAgZCQkZqautr7FiFxoIGxwWqQC4ury+qh2tCxEexMbIRhMdDggfYs7Q0kcXAQwDbELY2txEziBmmx3jSRNMR+nk4e2b70ry80QGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnav2rightarrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNFxeXAQCBMTGxOzm7CwqLLy2vPTy9Pz+/Ly6vCQiJLSytLS2tLSutOTi5MzGzKSepIyKjJSOlKSmpMzKzJyanIyOjBwaHIyGjISGhJSSlISChBQSFJyenIR+hGxubDw+PHRydHR2dEQ+RHx6fERCRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa6QIBwSCwaj8hkIIBcJgEBweAYnTYJUmMAa9USClniFtwlGg6IRFhoUKTXwwWj0FB3F46Hwl6UQyISfAB+EROCQgsUFRYSF3yJEIyBaxgWDBkaGRtclQwSHBIbEGEdGx4fGhcOICEDGBsWHBmqIq1CHRIWGRMMIyRTHRy6Er22tyONq8YdJRe0xkIDwr2/QwMfliMmZQADIxasZd4e4UYDIr7c59rc0eVFA+/m0EQD9PDt0flP/P3+BkEAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnav2uparrow22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBGReZDQyNMTCxHx6fPz+/JyWnKyurHx2fDw6PJSSlISGhIyKjIyGjISChLy6vJyanOTm5PTy9OTi5MzKzLSytKSepMTGxMzGzLS2tLSutKymrHRydCQiJCwmLBwWHAwODLy2vHx+fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAajQIBwSCwaj8RAAMkUBgSDZdP4JBSi06TAcEAkFNLp07BgLLzY5njRcDzO3zB1C4lEGI83Wj58SiYUFRUWdg0XEXFFAwIYGRoWGxwRZQUFHZdgRAObmx4fHiChISFKpVlKWUdPaalOAlasp1sHG4myZGZ7Yltsbgu1mUhjdRF5egmxfQJ/gYOFdrZDi40iFgiSCw8jBQmYcpydn6Ego6WorUwGQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnavback22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRGZAxCZGyavExmjHyatOTy9CxihISevPz+/KzO3BRylAw+XAQCBDRWbPz6/FzC3CSuzDyexJzO5Mzq9CxSdAQOFISmxNzu9HTS5BSmxAyexDSuzJTa7Mzu9Kzi7GS21CRmjAQOHHSWtLze7AyWvHzG3BRihAQKFCTO3BS+1AyixBSWvBSOtBSStAQWJBSixDzW5BTC3BSqzBS21CTC1ETW3AQSHEze7BRqlBRmjAQCDBR+pBRefBRSdCH5BAEAAAAALAAAAAAWABYAAAalQIBwSCwaj8ikMqBcMpvHgGAANQYIhWdVGDAcENQtIJBQLBgNx0MQaDuQXcghIplQDhBIxXKJYiAZGhscHR4VHyAhIiNWJBklGhIbJoQnFCcTKIxFKSgbKissJi0mJi4vLiYoMEcXKDEyMzQ1Nje2NisoOEg4KDU5K6g6OwwoKAN9SCOeMmgwz884PEq9PT4NYkPLP9jZQikN3d4AKVrjKePp3gZBACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nnavdown22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VCRKZDRSbBxCXJTC1Mzi7Nzq9NTm9Bx2nAQCBNzu9JzG3Hy+1HzG3IzO5BRmjPz6/LTe7Dy61AyStCTC1FzC1AyGrETS3ETC1ETa5BRulAyuzBRylAw+XMTe7Gy+3CSqzAyexBTC3DR+nIS21KTW5Nzu/KzO3FzC3Pz+/ByixEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaRQIBwSCwaj8ikcnkMBAQDgjPAFAYKhsMBkVBUAYEFo+F4QLzVQEQyoVTOX/XBcsHA0+vMRbNBMwkRDhxuHX5GTlIeHh8gISIjFAEeiVRECiQlDAUmgxQjIhwiJHdFlycoKSIUFCEjGiGkRpcqCxYijxorsUezcxYsuoZJsxLAu0qXB7DCTJfHVQrMX9PU1Uh0QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nnavforward22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBBxCXDR+nIS21Aw+XJTC1Nzu/KzO3Pz+/Nzq9Pz6/MTe7KTW5FzC1Nzu9CRKZMzi7IzK3Lzi7LTe7HzG3Gy+3AyuzAyexFzC3DRSbHy+1Dy61CSqzAySvAyStLze7IzO5AyGrETa5ByixBRmjCTC1ETS3BTC3Bx2nAyWvEze7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAaYQIBwSCwaj8hkMqBsBgTN5IAAjRoDBaq1aDggtMuAWDzoJhTgY+CwYLgZDccDwkgXI5IJZVGxXDAZGnR2QxsLHB0PHRgeHyAZDyFfVUQDCyIgIyCPIB+QJCUmlEMBEiInKCQnKSkeKSQeomoqJrUmKiArKSwZsmoCwMEBGCyxo1EGHr3HUQEEvltCBtDRAAbMW0zV29xDBkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavhome22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIYAAPwCBAQCBCQiJNze3ERCROTi5MzGzLy6vDw6PKyqrKyurBQSFGRiZGxqbGRmZISChEQ+RExKTExOTHRydDQyNOTe5FROVLSurCwqLMTCxPT29Pz6/LSutFxeXLyytLSytPz+/JSWlKympPTq7KSipNzW3BwaHHx6fKx2VJRWNHQmBFweDOzq7Ly+vNTW1JxWNLSajPTe1Ny6pKxWJNTS1IyOjJRmbPTi3OzKrNSSXMSGVHQiBHx+fJSSlPzy9IxOVOzWxOSyjNSCPLxeDJyWnIRGTOTGtMxmDLRWBHwqBIxGTLRSDDQuNNSunKxKBGwyNMSafMxqHMReDKRGDPTu9LxuPLxaDJQ+DIR+hGQqNIQyBGQiBNTO1EQKBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAf/gACCg4QBAYSIiYQCAwQCiokEhwACBQYHBAiQhAiHlQYJCgkEC5uCkp8MDQ4NDwylmwgQlgQRERIEBBOkmxQVBgQWFwUFFxEEDLyJGAUZtQoFGhsFHLYdyoOVHsEf0SAbIAUex8mwlAUhtSIFG+3uIyTWvAIGJMEkJe76GyXbEeWUBJg4USKaBhQpVKzYoIFFiwYUBBJa8MAFCw0vYMSQMWOhBhoTKCQSUKMEiw02buDIoWOHBg0GeIhEFKAHDR8afgAJImSIioYliMws1MPkhiJGchxBkmTDCBo1hg4KQMTiBiUyhBxZ8pNFiR5MEtU0WqSJVidJNDyNKraHC5xPNKBEkTLlJ5WvUgWNvfikyhArV34+7ZEXQAAsB2iUyHLlihYtW0pwOYAFgyJDmDNr7jIIWiAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nnavup22:nav nav22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAw2VAQCBHSWtBRmjAQOHISmxNzu9BSmxBRihHyatPz6/Lze7CTO3BSixHTS5BTC3DzW5ByyzPz+/OTy9AyexEze7ByixGyavKzO3FzC3AyWvBS+1BR+pAQKFCRGZExmjCxihBRylCSuzBSWvBS21BSOtBRSdAw+XAxCZDyexDSyzCTC1JzO5JTa7DSuzETW3BRqlAQWJDRWbOT2/Mzq9HzG3JzS5Kzi7BSStGS21CxSdCRmjAQOFAQSHAAAACH5BAEAAAAALAAAAAAWABYAAAaeQIBwSCwaj8ikcqkMCJjHwIBQgBIDhgMiUbUGFAtGw0GFfheHByQi4S6/E8pDUoFYLm5kAEPJaBAVGxIcER0JHlEfICEiIxUkGyUmIgknKIhXASkonCorgSwmKQGcKE9IAi0uLxUwMTJWMzQ1NiYwBLBQHws1N7avXgs4NjkcCblMATU6KhvGyG87PAnUKV1MAj0+2zIFp1bg4eJJdkEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nplayeject22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAwKDJSWlFRSVBQSFKymrOzq7HRydERCRPz+/MzGzISGhJyenKSmpGxqbJyWnJSOlKSepLy2vIyOjGRiZPTu9IyGjLSutFxaXExOTHx2fGReZAQCBAQGBBwaHCQiJLSytKyurJSSlFxeXNze3LS2tIyKjFxWXHRudAwGDBQOFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa1QIBwSCwaj8ikcqkMCJjHwIBQgBIDhgMiUbVKFQsGItBdBhpgh4PxIJvRC8cA4oiMy8bvQhJhMAYTFBVOURAWEw0QFxcMERAYCBluVxobDxkVHJocmBwEGgmEQx0dHh0CpKmkH6odVlanBR8FtAIFtiCkSB0LISEiGCIGIxAPDySuRwIOBwrOzwoHJRHJRh0jJgMj2gMnERQUCNVFHQQoCBvo6CkICATjRB0qp7b1K6qv+foyQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplayend22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNFxeXAQCBMTCxGReZBQSFOzm7AwKDKymrJSSlFRSVCwqLLy6vPTy9OTe5Ozq7CQiJLSytOTi5BwaHPz+/HRydMzKzKSepJSOlKSipJyanIyGjIyKjKyurISGhMzGzJyWnHR2dISChIyOjLSutDw+PERCRHx6fJSWlIR+hJyenGRmZHx2fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa6QIBwSCwaj8ikMBBQKgOCgRMZIBSkxYHWoDVWD9EigpBQLLBERsPxCA8NDUhjgTBGJJNGG02RVBQWdUV3FxgZe0IGfoAGdhoXGxwdiAYef4FGFBoeHB8dGSBRihUhIo1FBhkbIyMkJRYmAwYal4JEBh2RChIWJ1IIGxUZFqdECCgkHR6wWAYpFR2YWSobvL5vFgfDaEMDIivMRBEsD9HcQgMWvecDLB0tZ0btsfJa9vLXU/X6/P3+b0EAACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplaypause22:play play22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBAwODMTCxKSmpJSWlFRSVAQGBBwaHLSutOzq7Ly6vCQeJPz+/Hx2fBQWFGxubLSytJSOlBQOFAwKDJSSlJyWnIyOjHRydNze3GRiZAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAWBICCOZGmeaKqubOumQSDEgRjPMSoMRGEcol3vh0IkFAtDDWBEKlGMRKPgEIii0yrqIS1ArADu9KuLNCSOSdCMVp8ohEZFC4DL6SaBpXGh6/l4JX8XZACDhXkYCn1LAoqMUBAZEhBLDJKUSyYBGmhPAJyemiU0NDaloy+qq6ytI8whACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nplaystart22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBDQyNAQCBExOTAwKDAQGBJSSlHx+fBQSFMTCxKymrFRSVOzu7GxqbLSytLy6vJyanPz+/GReZBwaHHRydKSepKSipGRiZJyWnAwODLSutKSmpISChPTu9ISGhFxaXJSWlIyGjJSOlERCRIyKjDw2PIyOjLy2vOzm7Dw6PLS2tCQmJOTe5GxmbDQ2NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa7QIBwSCwaj8ik0hgQLJGBgbMoqBIKU2LAcMgOEQmFYeEFbBmNMgDhYDwWBC0k4pCoJ46IgRIXBioRCRYXamwRGBQIfgaBFhiERhkaenxmCoEbBhyQRYaIGVsdghgem4UWegcEBB8UHhsgIaZGBBgRIpUIIxQhChginEQIIBEklWslFyYnBsFfFCi4WQgpFBwqFxNGKxcsxl4IAS0NZEYCF3vlwgEfUuZV8JEuI2pPAARN9kcE9fr+SwaCAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nplaystop22:play play22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBAQCBAwKDBQSFBwaHCQmJJSSlISChJSOlJSWlGxqbGRiZNTS1PTy9Pz+/Ozm7OTi5FRSVIyKjOTe5MTCxIR+hExOTHR2dLy6vLSytLy2vHRydFxWXIyGjIyOjPz2/FRWVHx6fExKTMzOzJyanKSmpKyqrKSipAQGBLSutHx2fDw6PAwODAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAa1QIBwSCwaj8ikcslsAgKCAWEQjQ4KgSwyYDAcugZEQqFYYJECA6PhaLcfEEUkgJZAGJB8fkKpWOhHAxcOGBQZGBoaGQgbHIBGAhUOGR0SBxISBh4Xf0iCHxQSlRIIXhsgj0UCIaCXmJgHGyKpRJ+hmB5dHQqOaCENIx0epBIkBhdzngoPGCQlJifQJBvJRygRKRcKGxcXGypys1srEREc5SLnICLiR1koLFVUWfRO9vf4+UwyQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextblock22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUWzvNzo33GfFl5jVlonlTrr1DbvFi9vjeeNUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextbold22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIxhI+py+0Powm0VnknjVkH2AEhE45LZ55Wqn6e65TsMc5eYosbksswubJIhsSiccgvAAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\ntextcenter22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUbz3Sh7yIWfFHKjVl4nmFrr1Lpr7LwkjeeIUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextitalic22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py+0P4wqUSlQvttrkDnyaOHIdeaGRupplAIauVM3xjeeOUQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextleft22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+pyw0Bo5zB2UXz3Sp7yG2fFJajVjonmIor2TJvfL0wjecIXQAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextright22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAImhI+py30Bo5zBWUfz3SZ7yIXdF4kWqZkbCqoMO7kXLC+wVOe6YRQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntext22:text text22 22:photo:22 22:R0lGODlhFgAWAIQAAPwCBAQCBBwaHAwKDBQSFLy+vLS2tJSWlBQWFKyqrFRSVCwqLDQyNNTS1GxqbFxaXJyanIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAVcICCOZGmKQSoMaZsShBsQBdAapHvgaIDUqUPJlRjSbAoT0fRDKgODRbF0PLUYjZO2F2Bst9evNix+dsvDlGKK5jraudQb7qbX6a2HEJ+ycyF+LRE8ZTI+fX5oGCEAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\ntextunder22:text text22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIvhI+py+0PowmUnhpeVVnb1DkbCI1I2JhX+Z0sOr2cTHpwK7a4rUr+hAnufsTirwAAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewchoose22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBFRSVExKTDQyNPz69PTq5Pz+/OzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq70466Cl+AMxBVwnFIVRAmQHCIeBrC1L3tQgJ/SaEbeeC1PLBHE2ybFI9A1HzstHEIK6YCmhDTmBybQaHYJn7QC5zKeytIQe1+pKNE6P2yMAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewdetailed22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz+/Pz69PTq5AQCBOzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAQ+EMhJq7046817+MLQUQFRGMc4lQaSAkcMx3QltMmrDrSu/sCgEPgJhIiFk89DaL1qPRnlhsgBebWhdstVESIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewicon22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz69PTq5AQCBPz+/OzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARWEMhJq7046z2DF0PlBeAVEERhiKhqHgWyUgEsX0KczFOO7JeBYciTCImc5ITIXDKHyqhU9AnRqq9UEVDTvmLbGhin2/qAliOUot5OLc81IO5+2+8WewQAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewmag-22:view view22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAbKQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/47vrq9P3s/avno2BBf/MCClSob4iBIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmag22:view view22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbIQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/47vrq9P3s/cunr9S8gAIRFhTCLAgAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewmag+22:view view22 22:photo:22 22:R0lGODlhFgAWAIUAAPwCBBQSFJyanKy2tLzCxHyChNTa3Nzq7Nz29Nzy9Mzy9MTu9OTy9Nzi5Oz6/OT29MTi5Kzi7NTy9KTm7JzW3ITO1Lzq7IzW5HzK1LS+vMTq7Jze7ITW3GTCzGS+zLTS1MzOzLzq9Kzm7Jze5ITW5HTS3FS2vLze5EzCzEyyvEyutJTa5NTu9ITa5FTK1ESirLTm7Mzi5FS6xEy2vESerESmtFSutESmrKyqrAz+/Dw+RAzi3ASutHRydAQCBAAAACH5BAEAAAAALAAAAAAWABYAAAbQQIBQGCgWh8jksCgYEAaCozIZKBgOiIRiwSgEpstCw/HYQiKRhBcMCBgQDodkMaFU0t9pQHCIyy0TFxgYEVF6GQ4LCQkaERscHR4RH3lUIAkWCyEiIyQlHiYjEJVIAQQJJ2gjJSUoKSorlHoCLBQcHC0lLikvHjCGejEiHBgeMjM0NRwPpFQFDBHFNjceHAjAYFWoI7cnCVE4OWxtex8QH1EBOjs4zUpGUjw6Pe3j2fP19u/4zT766vRI+fvHD4CPgwcJ9qg0UB85JA0dDjEQBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\nviewmulticolumn22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBFRSVExKTDQyNPz+/Pz69PTq5AQCBOzaxOTKpAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARTEMhJq7046813+MJQfUF4BURhHGO6noSBsEcNoDJtS4KcsJQe4ncZ1HYT47HDbDqfUAnJRJmKLIGCCjjJbmE5wBI3EyOFxKCPS1EiJW52dE6vZyIAIf5oQ3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==\nviewtext22:view view22 22:photo:22 22:R0lGODlhFgAWAIAAAPwCBAQCBCH5BAEAAAAALAAAAAAWABYAAAIkhI+py+0Po2ShBlOxzbP7n2yaJoLm+ZTcxqHuC6hXzML2HVEFACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=\nviewtree22:view view22 22:photo:22 22:R0lGODlhFgAWAIMAAPwCBAQCBFRSVExKTDQyNPz+/Pz69Pzu5PTq5OzaxBQOFOzKpFRWVFxWXOzexPTexCH5BAEAAAAALAAAAAAWABYAAARPEMhJq704g6A779kHCORAgNskFMYhakE8FkjyBcoWv+JwJItXaELYCTFHlCSpZKKcoB5jYHpOGgUadLKbIRw3jhEzQDyCSuI4zW673yhDBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/ICONS/viewIcons.rb",
    "content": "#!/usr/bin/env ruby\n#\n#   viewIcons.rb\n#\n#     --  Display icons from icon library.\n#\n#     --  Copy the clicked icon data (command string of creating \n#         a TkPhotoImage instance) to the clipboard.\n#\nrequire 'tk'\nrequire 'tkextlib/ICONS'\n\nclass ViewIcons\n  #####################################\n  private\n  #####################################\n  def _create_controls\n    @controls = base = TkFrame.new\n    columns = TkFrame.new(base)\n    line1 = TkFrame.new(base, :height=>2, :borderwidth=>1, :relief=>:sunken)\n    line2 = TkFrame.new(base, :height=>2, :borderwidth=>1, :relief=>:sunken)\n\n    lbl_library = TkLabel.new(base, :font=>@boldfont, :text=>'Library')\n    lbl_groups  = TkLabel.new(base, :font=>@boldfont, :text=>'Groups')\n    lbl_columns = TkLabel.new(base, :font=>@boldfont, :text=>'Columns')\n\n    ent_library = TkEntry.new(base, :width=>50, :textvariable=>@library)\n    ent_groups  = TkEntry.new(base, :width=>50, :textvariable=>@groups)\n\n    btn_browse = TkButton.new(base, :text=>'Browse', \n                                    :command=>method(:select_icons))\n    btn_view   = TkButton.new(base, :text=>'View',\n                                    :command=>method(:display_icons))\n    btn_exit   = TkButton.new(base, :text=>'Exit', :command=>proc{exit})\n\n    @column_btns = {}\n    6.step(20, 2){|i|\n      @column_btns[i] = TkButton.new(columns, \n                                     :text=>i.to_s, :width=>2, \n                                     :command=>proc{set_columns(i)}\n                                     ).pack(:side=>:left)\n    }\n    @column_btns[@columns][:relief] = :sunken\n\n    lbl_library.grid(:row=>0, :column=>0, :padx=>4)\n    ent_library.grid(:row=>0, :column=>1)\n    btn_browse.grid(:row=>0, :column=>2, :padx=>4, :pady=>2, :sticky=>:ew)\n\n    line1.grid(:row=>1, :column=>0, :pady=>2, :columnspan=>3, :sticky=>:ew)\n\n    lbl_groups.grid(:row=>2, :column=>0, :padx=>4)\n    ent_groups.grid(:row=>2, :column=>1)\n    btn_view.grid(:row=>2, :column=>2, :padx=>4, :pady=>2, :sticky=>:ew)\n\n    line1.grid(:row=>3, :column=>0, :pady=>2, :columnspan=>3, :sticky=>:ew)\n\n    lbl_columns.grid(:row=>4, :column=>0, :padx=>4)\n    columns.grid(:row=>4, :column=>1, :padx=>2, :sticky=>:ew)\n    btn_exit.grid(:row=>4, :column=>2, :padx=>4, :pady=>2, :sticky=>:ew)\n\n    base.pack\n\n    ent_library.bind('Return', method(:display_icons), '')\n    ent_groups.bind('Return', method(:display_icons), '')\n  end\n\n  def _create_display\n    base = TkFrame.new(:borderwidth=>2, :relief=>:sunken)\n\n    @icons_window = icons = TkCanvas.new(base)\n    xscr = icons.xscrollbar(TkScrollbar.new(base))\n    yscr = icons.yscrollbar(TkScrollbar.new(base))\n\n    icons.grid(:row=>0, :column=>0, :sticky=>:news)\n    yscr.grid(:row=>0, :column=>1, :sticky=>:ns)\n    xscr.grid(:row=>1, :column=>0, :sticky=>:ew)\n    base.grid_columnconfigure(0, :weight=>1)\n    base.grid_columnconfigure(1, :weight=>0)\n    base.grid_rowconfigure(0, :weight=>1)\n    base.grid_rowconfigure(1, :weight=>0)\n    # yscr.pack(:side=>:right, :fill=>:y)\n    # xscr.pack(:side=>:bottom, :fill=>:x)\n    # icons.pack(:side=>:left, :fill=>:both, :expand=>true)\n\n    @icons_layout = TkFrame.new(icons).pack\n    TkcWindow.create(icons, 0, 0, :anchor=>:nw, :window=>@icons_layout)\n    @icons_layout.bind('Configure', method(:layout_resize), '')\n\n    base.pack(:expand=>true, :fill=>:both)\n  end\n\n  def _create_info_window\n    @info_window = TkToplevel.new(:background=>'lightyellow', :borderwidth=>1, \n                                  :relief=>:solid){|w|\n      lbl_name = TkLabel.new(w, :text=>'Name', :background=>'lightyellow', \n                             :font=>@boldfont, :justify=>:left)\n      lbl_grps = TkLabel.new(w, :text=>'Groups', :background=>'lightyellow', \n                             :font=>@boldfont, :justify=>:left)\n      lbl_type = TkLabel.new(w, :text=>'Type', :background=>'lightyellow', \n                             :font=>@boldfont, :justify=>:left)\n      lbl_size = TkLabel.new(w, :text=>'Size', :background=>'lightyellow', \n                             :font=>@boldfont, :justify=>:left)\n\n      lbl_name.grid(:row=>0, :column=>0, :sticky=>:w)\n      lbl_grps.grid(:row=>1, :column=>0, :sticky=>:w)\n      lbl_type.grid(:row=>2, :column=>0, :sticky=>:w)\n      lbl_size.grid(:row=>3, :column=>0, :sticky=>:w)\n\n      @name = TkLabel.new(w, :background=>'lightyellow', :justify=>:left)\n      @grps = TkLabel.new(w, :background=>'lightyellow', :justify=>:left)\n      @type = TkLabel.new(w, :background=>'lightyellow', :justify=>:left)\n      @size = TkLabel.new(w, :background=>'lightyellow', :justify=>:left)\n\n      @name.grid(:row=>0, :column=>1, :sticky=>:w)\n      @grps.grid(:row=>1, :column=>1, :sticky=>:w)\n      @type.grid(:row=>2, :column=>1, :sticky=>:w)\n      @size.grid(:row=>3, :column=>1, :sticky=>:w)\n\n      def name(txt)\n        @name['text'] = txt\n      end\n      def groups(txt)\n        @grps['text'] = txt\n      end\n      def type(txt)\n        @type['text'] = txt\n      end\n      def size(txt)\n        @size['text'] = txt\n      end\n\n      overrideredirect(true)\n      withdraw\n    }\n  end\n\n  def initialize(init_path = Tk::LIBRARY)\n    init_path = Tk::LIBRARY unless init_path\n    init_path = File.expand_path(init_path)\n    if File.directory?(init_path)\n      @initial_dir  = init_path\n      @initial_file = 'tkIcons'\n    else\n      @initial_dir  = File.dirname(init_path)\n      @initial_file = File.basename(init_path)\n    end\n\n    if Tk::PLATFORM['platform'] == 'unix'\n      TkOption.add('*HighlightThickness', 0)\n    end\n\n    @columns = 14\n    @command = \"\"\n\n    @delay_timer = nil\n\n    dummy = TkLabel.new\n    @font = dummy.font\n    @boldfont = TkFont.new(@font, :weight=>:bold)\n    @icons = {}\n    @icon_name = {}\n    @icon_info = {}\n\n    @library = TkVariable.new(File.join(@initial_dir, @initial_file))\n    @groups  = TkVariable.new('*')\n\n    _create_controls\n\n    _create_display\n\n    _create_info_window\n\n    Tk.root.title('viewIcons')\n    layout_resize\n    Tk.root.resizable(false, true)\n\n    display_icons\n  end\n\n  def init_info(item, name)\n    @icon_name[item] = name\n\n    item.bind('Button-1', method(:clip_info),  '%W')\n    item.bind('Enter',    method(:delay_info), '%W')\n    item.bind('Leave',    method(:cancel_info), '')\n  end\n\n  def delay_info(item)\n    cancel_info\n    @delay_timer = TkTimer.new(200, 1, proc{ show_info(item) }).start\n  end\n\n  def cancel_info\n    if @delay_timer\n      @delay_timer.cancel \n      @delay_timer = nil\n    end\n    @info_window.withdraw\n  end\n\n  def show_info(item)\n    name, groups, type, size = @icon_info[@icon_name[item]]\n    @info_window.name(name)\n    @info_window.groups(groups)\n    @info_window.type(type)\n    @info_window.size(size)\n\n    info_x = item.winfo_rootx + 10\n    info_y = item.winfo_rooty + item.winfo_height\n\n    @info_window.geometry(\"+#{info_x}+#{info_y}\")\n    @info_window.deiconify\n\n    @info_window.raise\n\n    @delay_timer = nil\n  end\n\n  def primary_transfer(offset, max_chars)\n    @command\n  end\n\n  def lost_selection\n    @command = \"\"\n  end\n\n  def clip_info(item)\n    name = @icon_name[item]\n    data_width = 60\n\n    cmd = \"#{name} = TkPhotoImage.new(:data=><<'EOD')\\n\"\n\n    icon_data = Tk::ICONS.query(name, :file=>@library.value, :items=>'d')[0][0]\n\n    icon_data.scan(/.{1,#{data_width}}/m){|s| cmd << '   ' << s << \"\\n\"}\n\n    cmd << \"EOD\\n\"\n\n    @command = cmd\n\n    TkClipboard.clear\n    TkClipboard.append(@command)\n\n    if Tk::PLATFORM['platform'] == 'unix'\n      TkSelection.handle(Tk.root, method(:primary_transfer), \n                         :selection=>'PRIMARY')\n      TkSelection.set_owner(Tk.root, :selection=>'PRIMARY', \n                            :command=>method(:lost_selection))\n    end\n\n    Tk.bell\n  end\n\n  def layout_resize\n    Tk.update\n    bbox = @icons_window.bbox('all')\n    width = @controls.winfo_width - @icons_window.yscrollbar.winfo_width - 8\n\n    @icons_window.configure(:width=>width, :scrollregion=>bbox, \n                            :xscrollincrement=>'0.1i', \n                            :yscrollincrement=>'0.1i')\n  end\n\n  def select_icons\n    new_lib = Tk.getOpenFile(:initialdir=>@initial_dir, \n                             :initialfile=>'tkIcons', \n                             :title=>'Select Icon Library', \n                             :filetypes=>[\n                               ['Icon Libraries', ['tkIcons*']], \n                               ['All Files', ['*']]\n                             ])\n\n    @library.value = new_lib if new_lib.length != 0\n    display_icons\n  end\n\n  def display_icons\n    column = 0\n    limit = @columns - 1\n    row = 0\n\n    unless File.exist?(@library.value)\n      Tk.messageBox(:icon=>'warning', :message=>'File does not exist', \n                    :title=>'viewIcons')\n      return\n    end\n\n    cursor = Tk.root[:cursor]\n    Tk.root[:cursor] = 'watch'\n\n    Tk::ICONS.delete(@icons)\n\n    @icons_frame.destroy if @icons_frame\n    @icons_frame = TkFrame.new(@icons_layout).pack\n\n    @icons = Tk::ICONS.create(:file=>@library.value, :group=>@groups.value)\n\n    Tk::ICONS.query(:file=>@library.value, :group=>@groups.value).each{|inf|\n      name = inf[0]\n      @icon_info[name] = inf\n\n      lbl = TkLabel.new(@icons_frame, :image=>\"::icon::#{name}\")\n      lbl.grid(:column=>column, :row=>row, :padx=>3, :pady=>3)\n      # lbl.grid_columnconfigure column\n\n      init_info(lbl, name)\n\n      if column == limit\n        column = 0\n        row += 1\n      else\n        column += 1\n      end\n    }\n\n    Tk.root[:cursor] = cursor\n  end\n\n  def set_columns(columns)\n    @columns = columns\n    6.step(20, 2){|i| @column_btns[i][:relief] = :raised }\n    @column_btns[@columns][:relief] = :sunken\n    display_icons\n  end\nend\n\nViewIcons.new(ARGV[0])\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/barchart5.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nload File.join(File.dirname(File.expand_path(__FILE__)), \n               'scripts', 'stipples.rb')\n\nTkOption.add('*graph.x.Title', 'X Axis Label')\nTkOption.add('*graph.y.Title', 'Y Axis Label')\nTkOption.add('*graph.title', 'A Simple Barchart')\nTkOption.add('*graph.x.Font', 'Times 10')\nTkOption.add('*graph.Element.Relief', :raised)\n\nvisual = Tk.root.winfo_screenvisual\nif visual != 'staticgray' && visual != 'grayscale'\n  TkOption.add('*graph.LineMarker.color', 'yellow')\n  TkOption.add('*graph.Element.Background', 'white')\n  TkOption.add('*graph.Legend.activeForeground', 'pink')\n  TkOption.add('*print.background', 'yellow')\n  TkOption.add('*quit.background',  'red')\n  TkOption.add('*graph.background', 'palegreen')\n  TkOption.add('*graph.plotBackground', 'lightblue')\nend\n\nhtext = Tk::BLT::Htext.new(:widgetname=>'.htext', :text=><<EOD)\n    This is an example of the barchart widget.  The barchart has \n    many components; x and y axis, legend, crosshairs, elements, etc.  \n    To create a postscript file \"bar.ps\", press the %%\n\n    ruby {\n    b = TkButton.new(Tk::BLT::Htext::Htext_Widget.window, \n                     :widgetname=>'print', :text=>'Print', \n                     :command=>proc{\n                        $graph.postsript(:output=>'bar.ps')\n                     })\n    Tk::BLT::Htext::Htext_Widget.window.append(b)\n    }\n\n%% button.  \n%%\n\n    ruby {\n    $graph = Tk::BLT::Barchart.new(:widgetname=>'.htext.graph', \n                                   :relief=>:raised, :borderwidth=>2)\n    $graph.xaxis_configure(:rotate=>90, :stepsize=>0)\n    Tk::BLT::Htext::Htext_Widget.window.append($graph, \n                                               :fill=>:both, :padx=>4)\n    }\n\n%%\n    Hit the %%\n\n    ruby {\n    b = TkButton.new(Tk::BLT::Htext::Htext_Widget.window, \n                     :widgetname=>'quit', :text=>'Quit', \n                     :command=>proc{ exit })\n    Tk::BLT::Htext::Htext_Widget.window.append(b)\n    }\n\n%% button when you've seen enough.%%\n\n    ruby {\n    l = TkLabel.new(Tk::BLT::Htext::Htext_Widget.window, :bitmap=>'BLT')\n    Tk::BLT::Htext::Htext_Widget.window.append(l, :padx=>20)\n    }\n\n%%\nEOD\n\nnames = %w(One Two Three Four Five Six Seven Eight)\nif visual == 'staticgray' || visual == 'grayscale'\n  fgcolors = %w(white white white white white white white white)\n  bgcolors = %w(black black black black black black black black)\nelse\n  fgcolors = %w(yellow orange red magenta purple blue cyan green)\n  bgcolors = %w(yellow4 orange4 red4 magenta4 purple4 blue4 cyan4 green4)\nend\n\nnumColors = names.length\n\nTk::TCL_PRECISION.value = 15\n\nx = Tk::BLT::Vector.new\ny = Tk::BLT::Vector.new\nx.seq(-5.0, 5.0, 0.2)\ny.expr(\"sin(#{x})\")\nbarWidth = 0.19\n\n$graph.element_create('sin', :relief=>:raised, :borderwidth=>1, \n                      :x=>x, :y=>y, :barwidth=>barWidth)\n\nTk::BLT::Table.add(Tk.root, htext, :fill=>:both)\n\nTk.root.minsize(0, 0)\n\nTk::BLT.zoom_stack($graph)\nTk::BLT.crosshairs($graph)\nTk::BLT.active_legend($graph)\nTk::BLT.closest_point($graph)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/calendar.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nrequire 'date'\n\ndir = File.join(File.dirname(File.expand_path(__FILE__)), 'images')\nfile = File.join(dir, 'chalk.gif')\nactive = File.join(dir, 'rain.gif')\n\ntexture1 = TkPhotoImage.new(:file=>file)\ntexture2 = TkPhotoImage.new(:file=>active)\n\nTkOption.add('*Tile', texture1)\n\nTkOption.add('*HighlightThickness', 0)\nTkOption.add('*calendar.weekframe*Tile', texture2)\nTkOption.add('*Calendar.Label.borderWidth', 0)\nTkOption.add('*Calendar.Label.relief', :sunken)\nTkOption.add('*Calendar.Frame.borderWidth', 2)\nTkOption.add('*Calendar.Frame.relief', :raised)\nTkOption.add('*Calendar.Label.font', 'Helvetica 11')\nTkOption.add('*Calendar.Label.foreground', 'navyblue')\nTkOption.add('*button.foreground', 'navyblue')\nTkOption.add('*background', 'grey85')\nTkOption.add('*Label.ipadX', 200)\n\nTkOption.add('*tile', texture2)\n\nclass BLT_Calendar_sample\n  @@monthInfo = [\n    nil,  # dummy\n    ['January', 31], \n    ['February', 28], \n    ['March', 31], \n    ['April', 30], \n    ['May', 31], \n    ['June', 30], \n    ['July', 31], \n    ['August', 31], \n    ['Septembar', 30], \n    ['October', 31], \n    ['November', 30], \n    ['December', 31]\n  ]\n\n  @@abbrDays = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ]\n\n  def initialize()\n    today = Date.today\n\n    if TkComm.bool(Tk.info(:commands, '.calendar'))\n      Tk.destroy('.calendar')\n    end\n    cal = Tk::BLT::Tile::Frame.new(:widgetname=>'.calendar', \n                                   :classname=>'Calendar', \n                                   :width=>'3i', :height=>'3i')\n\n    mon = Tk::BLT::Tile::Label.new(cal, :font=>'Courier 14 bold', \n                                   :text=>\"#{@@monthInfo[today.month][0]} \" + \n                                          \"#{today.year}\")\n    Tk::BLT::Table.add(cal, mon, [1, 0], :cspan=>7, :pady=>10)\n\n    week_f = Tk::BLT::Tile::Frame.new(cal, :widgetname=>'weekframe', \n                                      :relief=>:sunken, :borderwidth=>1)\n    Tk::BLT::Table.add(cal, week_f, [2, 0], :columnspan=>7, :fill=>:both)\n\n    @@abbrDays.each_with_index{|dayName, idx|\n      Tk::BLT::Table.add(cal, \n                         Tk::BLT::Tile::Label.new(cal, :text=>dayName, \n                                                  :font=>'Helvetica 12'), \n                         [2, idx], :pady=>2, :padx=>2)\n    }\n\n    Tk::BLT::Table.itemconfigure(cal, 'c*', 'r2', :pad=>4)\n\n    numDays = @@monthInfo[today.month][1]\n    week = 0\n    cnt = 1\n\n    wkday = today.wday - ((today.day - 1) % 7)\n    wkday += 7 if wkday < 0\n\n    while cnt <= numDays\n      Tk::BLT::Table.add(cal, \n                         Tk::BLT::Tile::Label.new(cal, :text=>cnt){\n                           self.configure(:borderwidth=>1, \n                                          :relief=>:sunken) if cnt == today.day\n                         }, \n                         [week+3, wkday], :fill=>:both, :ipadx=>10, :ipady=>4)\n      cnt += 1\n      wkday += 1\n      if wkday == 7\n        week += 1\n        wkday = 0\n      end\n    end\n\n    Tk::BLT::Tile::Frame.new(cal, :borderwidth=>1, :relief=>:sunken){|f|\n      Tk::BLT::Table.add(f, \n                         Tk::BLT::Tile::Button.new(f, :widgetname=>'button', \n                                                   :command=>proc{exit}, \n                                                   :borderwidth=>2, \n                                                   :text=>'Quit'), \n                         :padx=>4, :pady=>4)\n      Tk::BLT::Table.add(cal, f, [week+4, 5], :cspan=>2, :pady=>4)\n    }\n\n    Tk::BLT::Table.add(Tk.root, cal, :fill=>:both)\n    Tk::BLT::Table.itemconfigure(cal, 'r0', :resize=>:none)\n  end\nend\n\nBLT_Calendar_sample.new\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/graph6.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nTk::TCL_PRECISION.value = 15\n\n[\n  ['*Graph.Width', '10i'], \n  ['*Graph.leftMargin', '.75i'], \n  ['*Graph.Height', '6i'], \n  ['*Graph.plotBackground', 'black'], \n  ['*LineMarker.color', 'white'], \n  ['*LineMarker.Dashes', 5], \n  ['*TextMarker.foreground', 'white'], \n  ['*TextMarker.Background', ''], \n\n  ['*Graph.x.hide', true], \n  ['*Graph.x.title', ''], \n  ['*Graph.y.rotate', 90], \n  # ['*Graph.y.stepSize', 2.0], \n  ['*Graph.title', ''], \n  ['*graph.Title', 'Example s27'], \n  ['*graph.x.hide', false], \n  ['*graph.topMargin', 0], \n  ['*graph.bottomMargin', 0], \n  ['*x.Title', 'Time'], \n  ['*y.Title', 'Signals'], \n  ['*Pixels', 1], \n\n  ['*Reduce', 0.5], \n  ['*bufferElements', false], \n\n  ['*Element.color', 'green4'], \n  ['*Element.ScaleSymbols', true], \n  ['*Element.Color', 'grey70'], \n  ['*Element.Symbol', :none], \n  ['*Element.LineWidth', 1], \n  # ['*Element.Smooth', :natural], \n  ['*Element.Smooth', :catrom], \n\n  ['*activeLine.LineWidth', 2], \n  ['*activeLine.Color', 'white'], \n  ['*activeLine.Color', 'green1'], \n\n  # ['*Legend.Hide', true], \n  ['*Legend.Position', :right], \n  ['*Legend.Relief', :flat], \n  ['*Legend.activeRelief', :sunken], \n  ['*Legend.borderWidth', 2], \n  #['*Legend.Font', '-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*'], \n  ['*Legend.Font', 'Helvetica -10'], \n  ['*Grid.hide', false], \n  ['*Grid.dashes', [1, 5]], \n\n  # ['*foreground', 'white'], \n  ['*zoomOutline.outline', 'yellow'], \n].each{|k, v| TkOption.add(k, v)}\n\n##############################\n\nclass BLT_Graph_Demo\n  def initialize\n    @graph = Tk::BLT::Graph.new(:widgetname=>'graph')\n\n    @root = Tk.root\n    @root.minsize(0, 0)\n\n    _set_vectors()\n    (1..39).each{|i| @graph.element_create(\"V#{i}\", :x=>@x, :y=>@v[i])}\n\n    @top = Tk::BLT::Tile::Toplevel.new\n=begin\n    legend = Tk::BLT::Graph.new(@top, :widgetname=>'legend', \n                                :without_creating=>true)\n    @graph.legend_configure(:position=>legend)\n=end\n    # legend = @graph.legend_window_create(@top, :widgetname=>'legend')\n    legend = @graph.legend_window_create(@top)\n    legend.pack(:fill=>:both, :expand=>true)\n\n    Tk::BLT::Table.add(@root, @graph, [0,0], :fill=>:both)\n\n    @quit_btn = Tk::BLT::Tile::Button.new(:text=>' quit ', :background=>'red', \n                                          :command=>proc{exit})\n    Tk::BLT::Table.add(@root, @quit_btn, [1,0], :anchor=>:e, :padx=>10)\n\n    @graph.zoom_stack\n    @graph.crosshairs\n    @graph.closest_point\n    @graph.print_key\n\n    @graph.legend_bind(:all, 'ButtonRelease-1', \n                       proc{|w| highlightTrace(w)}, '%W')\n    @graph.legend_bind(:all, 'ButtonRelease-3', \n                       proc{|w|\n                         w.legend_deactivate('*')\n                         active = w.element_activate\n                         w.element_deactivate(*active)\n                       }, '%W')\n  end\n\n  private\n\n  def _set_vectors\n    @x = Tk::BLT::Vector.new(:variable=>'')\n    @v = []\n    (1..39).each{|i| @v[i] = Tk::BLT::Vector.new(:variable=>'')}\n\n    @x.set(<<-'EOD')\n    0 1e-10 2e-10 3e-10 4e-10 5e-10 6e-10 7e-10 8e-10 9e-10 \n    1e-09 1.1e-09 1.2e-09 1.3e-09 1.4e-09 1.5e-09 1.6e-09 1.7e-09 \n    1.8e-09 1.9e-09 2e-09 2.1e-09 2.2e-09 2.3e-09 2.4e-09 2.5e-09 \n    2.6e-09 2.7e-09 2.8e-09 2.9e-09 3e-09 3.1e-09 3.2e-09 3.3e-09 \n    3.4e-09 3.5e-09 3.6e-09 3.7e-09 3.8e-09 3.9e-09 4e-09 4.1e-09 \n    4.2e-09 4.3e-09 4.4e-09 4.5e-09 4.6e-09 4.7e-09 4.8e-09 \n    4.9e-09 5e-09 5.1e-09 5.2e-09 5.3e-09 5.4e-09 5.5e-09 5.6e-09 \n    5.7e-09 5.8e-09 5.9e-09 6e-09 6.1e-09 6.2e-09 6.3e-09 6.4e-09 \n    6.5e-09 6.6e-09 6.7e-09 6.8e-09 6.9e-09 7e-09 7.1e-09 7.2e-09 \n    7.3e-09 7.4e-09 7.5e-09 7.6e-09 7.7e-09 7.8e-09 7.9e-09 \n    8e-09 8.1e-09 8.2e-09 8.3e-09 8.4e-09 8.5e-09 8.6e-09 8.7e-09 \n    8.8e-09 8.9e-09 9e-09 9.1e-09 9.2e-09 9.3e-09 9.4e-09 9.5e-09 \n    9.6e-09 9.7e-09 9.8e-09 9.9e-09 1e-08 1.01e-08 1.02e-08 \n    1.03e-08 1.04e-08 1.05e-08 1.06e-08 1.07e-08 1.08e-08 1.09e-08 \n    1.1e-08 1.11e-08 1.12e-08 1.13e-08 1.14e-08 1.15e-08 1.16e-08 \n    1.17e-08 1.18e-08 1.19e-08 1.2e-08 1.21e-08 1.22e-08 1.23e-08 \n    1.24e-08 1.25e-08 1.26e-08 1.27e-08 1.28e-08 1.29e-08 1.3e-08 \n    1.31e-08 1.32e-08 1.33e-08 1.34e-08 1.35e-08 1.36e-08 1.37e-08 \n    1.38e-08 1.39e-08 1.4e-08 1.41e-08 1.42e-08 1.43e-08 1.44e-08 \n    1.45e-08 1.46e-08 1.47e-08 1.48e-08 1.49e-08 1.5e-08 1.51e-08 \n    1.52e-08 1.53e-08 1.54e-08 1.55e-08 1.56e-08 1.57e-08 1.58e-08 \n    1.59e-08 1.6e-08 1.61e-08 1.62e-08 1.63e-08 1.64e-08 1.65e-08 \n    1.66e-08 1.67e-08 1.68e-08 1.69e-08 1.7e-08 1.71e-08 1.72e-08 \n    1.73e-08 1.74e-08 1.75e-08 1.76e-08 1.77e-08 1.78e-08 1.79e-08 \n    1.8e-08 1.81e-08 1.82e-08 1.83e-08 1.84e-08 1.85e-08 1.86e-08 \n    1.87e-08 1.88e-08 1.89e-08 1.9e-08 1.91e-08 1.92e-08 1.93e-08 \n    1.94e-08 1.95e-08 1.96e-08 1.97e-08 1.98e-08 1.99e-08 2e-08 \n    2.01e-08 2.02e-08 2.03e-08 2.04e-08 2.05e-08 2.06e-08 2.07e-08 \n    2.08e-08 2.09e-08 2.1e-08 2.11e-08 2.12e-08 2.13e-08 2.14e-08 \n    2.15e-08 2.16e-08 2.17e-08 2.18e-08 2.19e-08 2.2e-08 2.21e-08 \n    2.22e-08 2.23e-08 2.24e-08 2.25e-08 2.26e-08 2.27e-08 2.28e-08 \n    2.29e-08 2.3e-08 2.31e-08 2.32e-08 2.33e-08 2.34e-08 2.35e-08 \n    2.36e-08 2.37e-08 2.38e-08 2.39e-08 2.4e-08 2.41e-08 2.42e-08 \n    2.43e-08 2.44e-08 2.45e-08 2.46e-08 2.47e-08 2.48e-08 2.49e-08 \n    2.5e-08 2.51e-08 2.52e-08 2.53e-08 2.54e-08 2.55e-08 2.56e-08 \n    2.57e-08 2.58e-08 2.59e-08 2.6e-08 2.61e-08 2.62e-08 2.63e-08 \n    2.64e-08 2.65e-08 2.66e-08 2.67e-08 2.68e-08 2.69e-08 2.7e-08 \n    2.71e-08 2.72e-08 2.73e-08 2.74e-08 2.75e-08 2.76e-08 2.77e-08 \n    2.78e-08 2.79e-08 2.8e-08 2.81e-08 2.82e-08 2.83e-08 2.84e-08 \n    2.85e-08 2.86e-08 2.87e-08 2.88e-08 2.89e-08 2.9e-08 2.91e-08 \n    2.92e-08 2.93e-08 2.94e-08 2.95e-08 2.96e-08 2.97e-08 2.98e-08 \n    2.99e-08 3e-08 3.01e-08 3.02e-08 3.03e-08 3.04e-08 3.05e-08 \n    3.06e-08 3.07e-08 3.08e-08 3.09e-08 3.1e-08 3.11e-08 3.12e-08 \n    3.13e-08 3.14e-08 3.15e-08 3.16e-08 3.17e-08 3.18e-08 3.19e-08 \n    3.2e-08 3.21e-08 3.22e-08 3.23e-08 3.24e-08 3.25e-08 3.26e-08 \n    3.27e-08 3.28e-08 3.29e-08 3.3e-08 3.31e-08 3.32e-08 3.33e-08 \n    3.34e-08 3.35e-08 3.36e-08 3.37e-08 3.38e-08 3.39e-08 3.4e-08 \n    3.41e-08 3.42e-08 3.43e-08 3.44e-08 3.45e-08 3.46e-08 3.47e-08 \n    3.48e-08 3.49e-08 3.5e-08 3.51e-08 3.52e-08 3.53e-08 3.54e-08 \n    3.55e-08 3.56e-08 3.57e-08 3.58e-08 3.59e-08 3.6e-08 \n    EOD\n\n    @v[1].set(<<-'EOD')\n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    EOD\n\n    @v[2].set(<<-'EOD')\n    0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 \n    5.32907e-15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 \n    5 5 5 5 5 5 5 5 5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 \n    EOD\n\n    @v[3].set(<<-'EOD')\n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 8.88178e-16 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 2.13718e-14 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 \n    EOD\n\n    @v[4].set(<<-'EOD')\n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    EOD\n\n    @v[5].set(<<-'EOD')\n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 4 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    EOD\n\n    @v[6].set(<<-'EOD')\n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 8.88178e-16 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 1 2 3 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 4 3 2 1 2.13718e-14 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \n    0 0 0 0 \n    EOD\n\n    @v[7].set(<<-'EOD')\n    5 5.16904 4.84159 3.34542 0.317102 0.103304 0.0275721 0.0221534 \n    0.017689 0.0142639 0.0113974 0.00918238 0.00742541 0.00616602 \n    0.00481195 0.00397049 -0.0659889 -0.025671 0.165495 0.986891 \n    3.05229 4.55511 4.91611 4.98192 4.99428 4.99833 4.99095 \n    4.97295 4.95493 4.93428 4.90723 4.94799 4.98584 4.99566 \n    4.99813 4.99907 4.99947 4.99965 4.99976 4.99984 4.99989 \n    4.99992 4.99994 4.99996 4.99998 5.00002 5.00006 5.00002 \n    4.99996 4.99994 4.99999 5.00003 5.00002 5 4.99997 4.99997 \n    4.99997 4.99997 4.99997 4.99996 4.99997 4.99997 4.99998 \n    4.99998 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99998 4.99998 4.99998 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.16575 \n    4.69986 2.43862 0.0230224 0.035229 -0.0210607 -0.0292766 \n    -0.0172693 -0.00271479 -0.000912251 -0.000349106 -0.000116866 \n    -4.24733e-05 -1.39536e-05 -3.01179e-05 -0.0657192 -0.0204835 \n    0.183378 1.07181 3.118 4.46472 4.84158 4.94795 4.98173 4.99236 \n    4.99762 5.01939 5.0433 5.05332 5.04959 5.03955 5.02851 5.02052 \n    5.01422 5.00965 5.00631 5.00405 5.00248 5.00083 5.00012 \n    5.00209 5.00387 5.00347 4.99917 4.99213 4.98411 4.97521 \n    4.96332 4.94601 4.9304 4.94633 4.97936 4.99264 4.99685 4.99857 \n    4.99925 4.99954 4.9997 4.99973 4.9997 4.99973 4.99979 4.99983 \n    4.99986 4.99988 4.9999 4.9999 4.99992 4.99993 4.99994 4.99995 \n    4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    5 5 5 5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 5 5 5.14242 4.76101 3.16003 0.299374 \n    0.0645506 -0.000498424 -2.45108e-05 -2.27986e-05 -5.24401e-05 \n    -4.9884e-05 -4.92491e-05 -2.93354e-05 -3.21402e-05 -2.11851e-05 \n    -3.37925e-05 -0.0657892 -0.020563 0.182582 1.06058 3.12484 \n    4.46552 4.84146 4.95102 4.98556 4.99472 4.99806 4.99909 \n    4.99955 4.99976 4.99994 4.99992 5.00029 4.99967 4.99849 \n    4.99736 4.99884 5.00099 5.00377 5.00215 4.99994 4.99893 \n    4.99788 4.99862 5.00055 5.00134 5.00127 5.00073 5.00039 \n    5.00018 5.00006 5.00001 4.99985 5.00026 5.00018 5.00003 \n    4.99981 4.99985 4.99987 4.99985 4.99982 4.99982 4.99982 \n    4.99983 4.99985 4.99987 4.99989 4.99991 4.99992 4.99994 \n    4.99995 4.99995 4.99994 4.99994 4.99996 4.99999 5.00002 \n    5.00008 5.00009 5.00006 5.00001 5 4.99999 4.99998 4.99997 \n    4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 \n    4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 4.99998 \n    4.99998 \n    EOD\n\n    @v[8].set(<<-'EOD')\n    5 5.03758 5.04711 4.96911 4.20882 3.96295 4.01117 4.15521 \n    4.2967 4.42274 4.5295 4.6176 4.69014 4.74831 4.7966 4.83537 \n    4.80526 4.787 4.79295 4.88588 5.08978 5.15615 5.10778 5.07718 \n    5.06652 5.08225 4.9744 4.52977 3.77452 2.69426 1.15294 0.245509 \n    0.0981544 0.0567527 0.0367487 0.0252578 0.0180599 0.0133837 \n    0.0101497 0.0078616 0.00620186 0.00499056 0.0041027 0.00344223 \n    0.00295808 0.00260089 0.00229887 0.00200817 0.00176397 0.00160116 \n    0.00147381 0.00134645 0.00125029 0.00116043 0.00107371 0.00101981 \n    0.000965921 0.000912028 0.000858135 0.000804242 0.000761669 \n    0.00072672 0.000691771 0.000656823 0.000621874 0.000588722 \n    0.00057041 0.000552098 0.000533785 0.000515473 0.000497162 \n    0.00047885 0.000460537 0.000442226 0.000423914 0.000405601 \n    0.000388399 0.000378694 0.000368989 0.000359284 0.00034958 \n    0.000339875 0.00033017 0.000320465 0.00031076 0.000301055 \n    0.00029135 0.000282207 0.000276247 0.000270287 0.000264327 \n    0.000258367 0.000252407 0.000246447 0.000240487 0.000234527 \n    0.000228567 0.000222607 0.000217086 0.000213696 0.000210307 \n    0.000206918 0.000203528 0.000200139 0.00019675 0.00019336 \n    0.000189971 0.000186582 0.000183192 0.000179803 0.000176414 \n    0.000173025 0.000169635 0.000166246 0.000162857 0.000159467 \n    0.000156078 0.000152689 0.000149299 0.00014591 0.00014255 \n    0.0316021 0.163272 0.348732 0.603651 0.35745 0.135965 0.0707354 \n    0.0314595 0.0201047 0.00994945 0.00389601 0.00138839 0.00060778 \n    0.000329648 0.000492396 -0.0732035 -0.0844077 -0.0789062 \n    -0.0390837 0.0197559 0.0183094 -0.00180099 -0.0189565 -0.0424144 \n    -0.0735904 -0.0892423 0.285039 1.13702 2.10809 2.95826 3.60164 \n    4.0435 4.35771 4.57254 4.71769 4.81329 4.87534 4.91487 4.94264 \n    4.97375 5.01526 5.06517 5.10154 5.06259 4.89005 4.5787 4.12226 \n    3.46151 2.49023 1.2586 0.32725 0.116753 0.0701865 0.0455509 \n    0.0286914 0.0178176 0.0117599 0.00902715 0.00760583 0.00637745 \n    0.00543811 0.00439377 0.00352448 0.0030151 0.00285771 0.002465 \n    0.00203114 0.00173004 0.0014839 0.00125177 0.00105327 0.000894905 \n    0.000766372 0.000658894 0.000569105 0.000492114 0.000427938 \n    0.000370217 0.000314758 0.000266569 0.000233726 0.000209048 \n    0.000191957 0.000177169 0.000166604 0.000161 0.000157314 \n    0.000143828 0.000130342 0.000116857 0.000103371 8.98855e-05 \n    7.63998e-05 6.29141e-05 5.76583e-05 5.30027e-05 4.8347e-05 \n    4.36913e-05 3.90357e-05 3.438e-05 2.97243e-05 2.72507e-05 \n    2.59083e-05 2.45659e-05 2.32235e-05 2.18811e-05 2.05387e-05 \n    1.91963e-05 1.78539e-05 1.65115e-05 1.51691e-05 1.38267e-05 \n    1.24843e-05 1.11419e-05 9.79954e-06 8.51574e-06 7.69807e-06 \n    6.8804e-06 6.06273e-06 5.24506e-06 0.0287318 0.0317111 -0.0320087 \n    -0.103609 0.0369639 0.0121128 0.00961197 0.00934971 0.00820853 \n    0.00699769 0.00607002 0.00535541 0.00476552 0.00427601 0.00376357 \n    -0.073012 -0.0866964 -0.0809538 -0.038005 0.0277001 0.0188906 \n    0.00614597 0.00373629 0.00489787 0.0146573 0.0191052 0.0151708 \n    0.0124224 0.0105859 0.00879272 0.00729464 0.0070047 0.00449575 \n    -0.00626652 -0.0252417 -0.0147287 0.022538 0.0822905 0.0947372 \n    0.0657516 0.0445506 0.0316753 0.0220971 0.0158101 0.0140971 \n    0.0161498 0.0139876 0.0122447 0.0106994 0.009397 0.00822236 \n    0.00686509 0.00797431 0.00751269 0.00671173 0.00595243 0.00524633 \n    0.00459528 0.00401688 0.00350109 0.00303954 0.00260569 0.00222792 \n    0.00191033 0.00163917 0.00140949 0.00121464 0.0010471 0.000900638 \n    0.000768847 0.000645236 0.000524807 0.000460275 0.000442237 \n    0.000446775 0.000397026 0.000301585 0.000228994 0.000190894 \n    0.000166569 0.000152261 0.000137953 0.000123644 0.000109336 \n    9.50281e-05 8.56557e-05 7.78437e-05 7.00318e-05 6.22198e-05 \n    5.44079e-05 4.87539e-05 4.57761e-05 4.27982e-05 3.98203e-05 \n    3.68425e-05 3.38646e-05 3.08868e-05 2.79089e-05 2.4931e-05 \n    2.19532e-05 1.89753e-05 1.75244e-05 1.64095e-05 1.52946e-05 \n    1.41797e-05 1.30648e-05 1.19499e-05 1.0835e-05 9.72011e-06 \n    8.60521e-06 7.4903e-06 6.5117e-06 6.10334e-06 5.69497e-06 \n    5.2866e-06 4.87824e-06 4.46987e-06 4.06151e-06 3.65314e-06 \n    3.24477e-06 \n    EOD\n\n    @v[9].set(<<-'EOD')\n    1.86175 1.99708 2.07867 2.01211 2.43309 3.27194 3.63896 \n    3.90426 4.11074 4.27932 4.41496 4.52543 4.61491 4.68862 \n    4.7479 4.79666 4.72895 4.68886 4.70354 4.81353 5.01568 5.14184 \n    5.10482 5.07362 5.05143 5.03638 5.02323 5.01465 5.00853 \n    5.00383 4.99985 5.00454 5.00652 5.00546 5.00411 5.003 5.00214 \n    5.00151 5.00106 5.00073 5.0005 5.00034 5.00023 5.00015 5.0001 \n    5.00005 5 5.00001 5.00005 5.00005 5.00003 5 4.99998 4.99996 \n    4.99994 4.99995 4.99997 4.99998 5 5.00001 5.00002 5.00002 \n    5.00003 5.00003 5.00003 5.00003 5.00003 5.00003 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 \n    4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.17392 4.94828 3.78491 \n    1.52079 0.608874 0.244031 0.127087 0.0552995 0.0361032 0.0169025 \n    0.006364 0.00217624 0.000921391 0.000457305 0.000786754 \n    -0.120016 -0.148054 -0.15898 -0.0801463 0.16463 0.174017 \n    0.0799249 0.0318788 0.0129696 0.00483397 0.0025677 0.0042079 \n    0.00350003 0.00178404 -8.72902e-05 -0.00128497 -0.00142213 \n    -0.00130018 -0.00106874 -0.000789207 -0.000824335 -0.00104518 \n    -0.00136799 -0.004366 -0.0102621 -0.0109254 -0.00649259 \n    -0.00194842 0.00029793 0.00148673 0.00221085 0.00228291 \n    0.00185261 0.00139687 0.00148183 0.00562266 0.00844119 0.00754627 \n    0.00657396 0.00591212 0.00539269 0.0049282 0.00448417 0.0040572 \n    0.00363719 0.00320392 0.00279607 0.00243938 0.00211505 0.00182302 \n    0.00156254 0.0013341 0.00113834 0.000971865 0.00082776 0.000706193 \n    0.000602499 0.000515059 0.000441401 0.00037897 0.000325459 \n    0.00028083 0.000242096 0.000207274 0.000176444 0.000150372 \n    0.000126407 0.000103373 9.05522e-05 8.53555e-05 8.63685e-05 \n    9.02593e-05 8.37346e-05 7.72099e-05 7.06852e-05 6.41605e-05 \n    5.76358e-05 5.11112e-05 4.45865e-05 4.08176e-05 3.72497e-05 \n    3.36818e-05 3.01138e-05 2.65459e-05 2.2978e-05 1.94101e-05 \n    1.76154e-05 1.67399e-05 1.58645e-05 1.4989e-05 1.41136e-05 \n    1.32381e-05 1.23626e-05 1.14872e-05 1.06117e-05 9.73629e-06 \n    8.86083e-06 7.98538e-06 7.10993e-06 6.23447e-06 5.44363e-06 \n    5.32578e-06 5.20792e-06 5.09007e-06 4.97222e-06 0.0784323 \n    0.0474527 -0.0764232 -0.151146 0.0615785 0.0144489 0.00974161 \n    0.00947176 0.00849005 0.00728201 0.00630581 0.00554032 0.00487809 \n    0.00441504 0.00384139 -0.118943 -0.149894 -0.161173 -0.0825299 \n    0.171686 0.176912 0.0816085 0.0335236 0.013791 0.0056976 \n    0.00238833 0.00105348 0.000526199 0.00025969 0.000396026 \n    0.000837835 0.00170131 0.00196699 -0.000553314 -0.0061621 \n    -0.0111895 -0.0142698 -0.0124608 -0.00795847 -0.00467822 \n    -0.0043058 -0.00874449 -0.0118584 -0.00871386 -0.00377892 \n    1.95244e-05 0.00218952 0.00325486 0.00386497 0.00422837 \n    0.00446883 0.00447065 0.00486647 0.00547838 0.00565398 0.00559092 \n    0.00538752 0.00507015 0.00466305 0.00420756 0.00373465 0.00328404 \n    0.00287059 0.00250057 0.00216124 0.00184861 0.00156815 0.00134624 \n    0.00117857 0.00103412 0.0008948 0.000761012 0.000619853 \n    0.000462614 0.000319965 0.000287666 0.000356415 0.000379946 \n    0.000339183 0.00027972 0.000252982 0.000226244 0.000199507 \n    0.000172769 0.000146031 0.000130097 0.000117578 0.000105059 \n    9.25401e-05 8.00213e-05 7.11204e-05 6.67061e-05 6.22918e-05 \n    5.78775e-05 5.34632e-05 4.90489e-05 4.46346e-05 4.02203e-05 \n    3.5806e-05 3.13916e-05 2.69773e-05 2.4827e-05 2.31747e-05 \n    2.15225e-05 1.98702e-05 1.8218e-05 1.65658e-05 1.49135e-05 \n    1.32613e-05 1.1609e-05 9.95678e-06 8.50108e-06 7.86765e-06 \n    7.23422e-06 6.60079e-06 5.96736e-06 5.33393e-06 4.7005e-06 \n    4.06707e-06 3.43363e-06 \n    EOD\n\n    @v[10].set(<<-'EOD')\n    1.86175 1.99308 2.16619 2.46661 3.09359 3.76864 4.31299 \n    4.65564 4.83425 4.92153 4.96157 4.98063 4.98649 4.99039 \n    4.9945 4.9972 4.96206 4.89882 4.83865 4.83202 4.91016 5.04479 \n    5.06078 5.04827 5.03474 5.0246 5.01639 5.00996 5.00569 5.00239 \n    5.00043 5.00296 5.00437 5.00382 5.00287 5.00208 5.00148 \n    5.00104 5.00073 5.0005 5.00034 5.00023 5.00016 5.00011 5.00008 \n    5.00007 5.00007 5.00004 5 4.99998 4.99998 4.99997 4.99998 \n    4.99999 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 \n    5.00001 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5.10081 \n    5.10949 4.98359 5.00733 5.15145 4.37298 2.36126 0.470759 \n    0.0577238 0.0115884 0.00262611 0.000671499 0.000389038 0.000291291 \n    0.000317347 -0.0167823 -0.0158344 -0.0140559 0.0104849 0.0865874 \n    0.107813 0.0524688 0.0214369 0.00876443 0.00341595 0.00170778 \n    0.00259042 0.0022241 0.00118519 1.10217e-06 -0.000784506 \n    -0.000948169 -0.000856256 -0.000696719 -0.000485987 -0.000724787 \n    -0.000981491 -0.001454 -0.00552498 -0.0114992 -0.0105266 \n    -0.00543527 -0.000982798 0.00127356 0.00224212 0.00275439 \n    0.00281098 0.0025471 0.00230368 0.00222576 0.00485522 0.00729453 \n    0.00691796 0.0062615 0.00573987 0.0052688 0.00481185 0.00436934 \n    0.00394326 0.00352712 0.00309978 0.00270038 0.00235335 0.00203742 \n    0.00175256 0.00150067 0.00128126 0.00109323 0.000933619 \n    0.000795113 0.000678182 0.00057843 0.000494345 0.000423609 \n    0.000363821 0.000312766 0.000269856 0.000232389 0.000198382 \n    0.000168126 0.00014267 0.000119293 9.69034e-05 8.5669e-05 \n    8.26828e-05 8.64066e-05 9.26665e-05 8.5454e-05 7.82416e-05 \n    7.10291e-05 6.38167e-05 5.66043e-05 4.93918e-05 4.21794e-05 \n    3.86073e-05 3.53007e-05 3.19941e-05 2.86876e-05 2.5381e-05 \n    2.20744e-05 1.87678e-05 1.70933e-05 1.62648e-05 1.54363e-05 \n    1.46079e-05 1.37794e-05 1.2951e-05 1.21225e-05 1.12941e-05 \n    1.04656e-05 9.63716e-06 8.80871e-06 7.98026e-06 7.1518e-06 \n    6.32335e-06 5.5374e-06 5.08959e-06 4.64178e-06 4.19397e-06 \n    3.74616e-06 0.0438026 0.0242078 -0.0602019 -0.0840866 0.00148461 \n    -0.00292489 0.000442098 0.00219489 0.00281478 0.00290756 \n    0.00277945 0.00263896 0.00240099 0.00223283 0.001947 -0.0153629 \n    -0.0148815 -0.0128673 0.0126017 0.0905161 0.11051 0.0538958 \n    0.022562 0.00935726 0.00397422 0.00172534 0.000790207 0.000416322 \n    0.000191632 0.000469721 0.0009779 0.00192566 0.00200688 \n    -0.0016502 -0.00733932 -0.0128113 -0.0147608 -0.0115456 \n    -0.00668995 -0.00401368 -0.00463908 -0.0101197 -0.0118993 \n    -0.0076276 -0.00262656 0.000813059 0.00264455 0.00350796 \n    0.00399494 0.0043049 0.00451658 0.00444739 0.00503842 0.00559516 \n    0.00568213 0.00556459 0.0053176 0.00496654 0.00454337 0.00408592 \n    0.00362171 0.00317793 0.00277001 0.00240394 0.00207009 0.00176575 \n    0.00149725 0.00129045 0.00114257 0.00101135 0.000871672 \n    0.000723764 0.000580438 0.000427507 0.000296956 0.000281834 \n    0.000376628 0.000412266 0.000367547 0.000295305 0.000264513 \n    0.000233721 0.000202929 0.000172137 0.000141345 0.000124721 \n    0.000112577 0.000100433 8.82893e-05 7.61453e-05 6.75517e-05 \n    6.33609e-05 5.91701e-05 5.49792e-05 5.07884e-05 4.65976e-05 \n    4.24067e-05 3.82159e-05 3.40251e-05 2.98342e-05 2.56434e-05 \n    2.36401e-05 2.21181e-05 2.05961e-05 1.90741e-05 1.75521e-05 \n    1.60301e-05 1.45081e-05 1.29861e-05 1.14641e-05 9.94208e-06 \n    8.59252e-06 7.96439e-06 7.33626e-06 6.70813e-06 6.07999e-06 \n    5.45186e-06 4.82373e-06 4.1956e-06 3.56747e-06 \n    EOD\n\n    @v[11].set(<<-'EOD')\n    1.86175 1.73419 1.42874 1.04055 0.943004 0.268275 0.0826455 \n    0.0388346 0.0214104 0.0135431 0.00961322 0.00712846 0.00588262 \n    0.00432397 0.00377774 0.00270134 -0.00393731 -0.00542187 \n    -0.00126596 0.0113777 0.0134522 0.00477056 -0.00211067 -0.00229253 \n    -0.00173355 -0.00122404 -0.00113426 -0.000744931 -0.000520112 \n    -0.000410048 -0.000220439 0.000508104 5.15856e-05 -0.000112593 \n    -0.000118917 -9.57394e-05 -7.15727e-05 -5.11847e-05 -3.58275e-05 \n    -2.47166e-05 -1.68866e-05 -1.14082e-05 -7.66646e-06 -5.12139e-06 \n    -3.63426e-06 -3.01815e-06 -2.64862e-06 -1.4947e-06 -1.91403e-07 \n    -2.5763e-08 -7.73699e-07 -1.52164e-06 -1.07268e-06 -3.81696e-07 \n    2.6727e-07 4.75489e-07 6.83708e-07 8.91926e-07 1.10014e-06 \n    1.30836e-06 1.2482e-06 1.00726e-06 7.66311e-07 5.25364e-07 \n    2.84417e-07 6.27857e-08 7.43904e-10 -6.12979e-08 -1.2334e-07 \n    -1.85382e-07 -2.47423e-07 -3.09465e-07 -3.71507e-07 -4.33549e-07 \n    -4.95591e-07 -5.57633e-07 -6.04571e-07 -5.4944e-07 -4.9431e-07 \n    -4.3918e-07 -3.84049e-07 -3.28919e-07 -2.73789e-07 -2.18659e-07 \n    -1.63528e-07 -1.08398e-07 -5.32678e-08 1.062e-09 5.08502e-08 \n    1.00638e-07 1.50427e-07 2.00215e-07 2.50003e-07 2.99791e-07 \n    3.4958e-07 3.99368e-07 4.49156e-07 4.98944e-07 5.34512e-07 \n    5.01032e-07 4.67553e-07 4.34073e-07 4.00593e-07 3.67113e-07 \n    3.33633e-07 3.00153e-07 2.66674e-07 2.33194e-07 1.99714e-07 \n    1.66234e-07 1.32754e-07 9.92744e-08 6.57945e-08 3.23147e-08 \n    -1.16513e-09 -3.4645e-08 -6.81248e-08 -1.01605e-07 -1.35084e-07 \n    -1.68564e-07 -2.18729e-07 0.0114926 -0.0245378 -0.111828 \n    0.0964775 1.61491 3.22668 4.22041 4.54492 4.82845 4.94868 \n    4.98588 4.99609 4.9981 4.99908 4.99788 4.98395 4.99294 4.99724 \n    5.01939 5.0471 5.00902 4.98194 4.98496 4.99188 4.99623 4.99862 \n    5.00025 4.99974 4.99953 4.99946 4.99958 5.00012 4.99997 \n    4.99992 4.99988 4.99985 4.9998 4.9997 4.9988 4.99806 4.99982 \n    5.00143 5.00159 5.00098 5.00053 5.00028 5.00007 4.99977 \n    4.99992 5.00005 5.00133 5.0009 4.99993 4.99972 4.99975 4.9998 \n    4.99982 4.99983 4.99983 4.99983 4.99983 4.99984 4.99986 \n    4.99987 4.99989 4.9999 4.99991 4.99992 4.99994 4.99995 4.99995 \n    4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99998 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    5 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 5 5 5.01457 4.99482 4.96561 4.99326 \n    5.03452 5.00424 5.00101 5.00045 5.00004 4.99965 4.99997 \n    4.99994 4.99958 4.99999 4.99936 4.9839 4.99248 4.99717 5.01976 \n    5.04869 5.0087 4.98143 4.98488 4.99199 4.99622 4.9983 4.99928 \n    4.99971 4.99986 5.00031 5.00022 5.00035 5.0001 4.99884 4.99811 \n    4.99803 4.99887 5.00078 5.00151 5.00116 5.00007 4.99843 \n    4.99915 5.00107 5.00168 5.00141 5.00092 5.00055 5.0003 5.00016 \n    5.0001 5.00001 5.00016 5.0002 5.00009 4.99993 4.99975 4.99984 \n    4.99991 4.99991 4.99982 4.99974 4.99974 4.99985 4.99995 \n    4.99999 4.99998 5.00004 5.00013 5.00015 5.00007 4.99988 \n    4.99982 4.99985 4.99995 5.00006 5.0002 5.00025 5.0002 5.00009 \n    5.00006 5.00004 5.00002 5 4.99998 4.99997 4.99998 4.99998 \n    4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 \n    4.99998 4.99998 4.99998 \n    EOD\n\n    @v[12].set(<<-'EOD')\n    5 5.16975 4.78685 2.94241 0.126698 0.0487004 -0.00422591 \n    -0.00130689 -0.000486756 -0.000195875 -0.000108988 -6.66736e-05 \n    -7.26005e-05 -5.63608e-05 -3.81859e-05 -2.123e-05 -0.0646846 \n    -0.0184474 0.182248 1.06731 3.10988 4.46133 4.84133 4.95113 \n    4.98364 4.99455 4.99694 4.99727 4.9994 4.99975 5.0001 5.00132 \n    5.00089 5.00039 5.00019 5.00011 5.00006 5.00005 5.00004 \n    5.00001 4.99992 4.99992 5.00002 5.00013 5.00017 5.00009 \n    4.99992 4.99991 4.99994 4.99996 4.99998 4.99999 5.00001 \n    5.00004 5.00006 5.00005 5.00004 5.00003 5.00002 5.00001 \n    5 4.99999 4.99999 4.99998 4.99998 4.99997 4.99997 4.99998 \n    4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 \n    5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 5 5.14699 4.78074 \n    3.19424 0.305663 0.0611255 -0.00179951 -0.0012032 0.000405978 \n    0.000989399 0.000445194 0.000191447 8.30476e-05 3.96236e-05 \n    1.91866e-05 1.70665e-05 -0.0655239 -0.0210234 0.1827 1.06848 \n    3.11554 4.46518 4.84212 4.94853 4.98244 4.99434 4.9997 5.00081 \n    5.00009 4.99972 4.99985 4.99974 4.9995 4.99949 4.99958 4.99973 \n    4.99948 4.99914 4.99874 4.99946 5.00309 5.0091 5.01576 5.01835 \n    5.01852 5.0176 5.01625 5.01479 5.01345 5.01264 5.011 5.01092 \n    5.01344 5.01363 5.01289 5.01184 5.01071 5.00956 5.00848 \n    5.00751 5.00663 5.00577 5.00497 5.00427 5.00365 5.0031 5.00264 \n    5.00224 5.00191 5.00163 5.00138 5.00117 5.00099 5.00083 \n    5.00071 5.00061 5.00053 5.00045 5.00037 5.00029 5.00022 \n    5.00019 5.0002 5.00023 5.00024 5.00023 5.00023 5.00022 5.0002 \n    5.00018 5.00016 5.00014 5.00011 5.00009 5.00007 5.00006 \n    5.00005 5.00005 5.00004 5.00003 5.00002 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5.14298 4.79809 3.32704 \n    0.498385 0.105773 0.0160646 0.0319912 0.0299434 0.0240102 \n    0.0185844 0.0130411 0.0106532 0.00864871 0.00744519 0.00660887 \n    -0.0612913 -0.0203719 0.174998 0.991787 3.06292 4.60005 \n    4.93058 4.98917 5.00033 4.9999 4.99909 4.9966 4.9955 4.99488 \n    4.99374 4.9943 5.00131 5.00506 4.99311 4.96288 4.93567 4.92439 \n    4.94236 4.9732 4.98864 4.99458 5.00031 5.00694 5.01525 5.01945 \n    5.01998 5.01953 5.01874 5.01766 5.0164 5.01509 5.01326 5.01423 \n    5.01455 5.01361 5.01245 5.01122 5.01002 5.00888 5.00783 \n    5.00687 5.00596 5.00514 5.00442 5.00379 5.00325 5.00279 \n    5.0024 5.00208 5.0018 5.00153 5.00126 5.00107 5.00094 5.00085 \n    5.00078 5.00072 5.00063 5.00053 5.00042 5.00038 5.00034 \n    5.0003 5.00027 5.00023 5.00021 5.00019 5.00017 5.00015 5.00013 \n    5.00012 5.00011 5.0001 5.0001 5.00009 5.00008 5.00007 5.00007 \n    5.00006 5.00005 5.00005 5.00004 5.00004 5.00003 5.00003 \n    5.00002 5.00002 5.00002 5.00001 5.00001 5 5 5 5.00001 5.00001 \n    5.00001 5.00002 5.00002 5.00002 5.00002 \n    EOD\n\n    @v[13].set(<<-'EOD')\n    9.73784e-10 0.0189926 0.0926769 0.206309 0.111533 0.0953491 \n    0.0426966 0.0214177 0.0117943 0.00741442 0.00528816 0.00398417 \n    0.0032967 0.00266499 0.00206647 0.00158788 -0.0371391 -0.0439528 \n    -0.0408653 -0.0188706 0.0150241 0.0126852 0.00209817 -0.000239206 \n    -5.31488e-05 0.000876324 -0.00451221 -0.0165223 -0.0284127 \n    -0.0427584 -0.0502453 -0.0257366 -0.00903938 -0.00376456 \n    -0.00233385 -0.00169922 -0.00130397 -0.00102542 -0.000811435 \n    -0.000648115 -0.000529266 -0.00043795 -0.00036574 -0.00030716 \n    -0.00026221 -0.000229662 -0.000205112 -0.000181038 -0.000162045 \n    -0.000148988 -0.000137633 -0.000126278 -0.000115562 -0.000104976 \n    -9.49324e-05 -9.0585e-05 -8.62375e-05 -8.18901e-05 -7.75426e-05 \n    -7.31952e-05 -6.93752e-05 -6.59106e-05 -6.24461e-05 -5.89815e-05 \n    -5.55169e-05 -5.22412e-05 -5.05263e-05 -4.88114e-05 -4.70966e-05 \n    -4.53817e-05 -4.36668e-05 -4.19519e-05 -4.0237e-05 -3.85222e-05 \n    -3.68073e-05 -3.50924e-05 -3.34782e-05 -3.25442e-05 -3.16102e-05 \n    -3.06763e-05 -2.97423e-05 -2.88083e-05 -2.78744e-05 -2.69404e-05 \n    -2.60064e-05 -2.50725e-05 -2.41385e-05 -2.32635e-05 -2.27232e-05 \n    -2.21829e-05 -2.16426e-05 -2.11023e-05 -2.0562e-05 -2.00217e-05 \n    -1.94814e-05 -1.89411e-05 -1.84007e-05 -1.78604e-05 -1.73647e-05 \n    -1.70853e-05 -1.68059e-05 -1.65265e-05 -1.62471e-05 -1.59677e-05 \n    -1.56883e-05 -1.54089e-05 -1.51295e-05 -1.48501e-05 -1.45707e-05 \n    -1.42913e-05 -1.40119e-05 -1.37325e-05 -1.34531e-05 -1.31737e-05 \n    -1.28943e-05 -1.26149e-05 -1.23355e-05 -1.20561e-05 -1.17767e-05 \n    -1.14973e-05 -1.10954e-05 0.0152675 0.0228237 -0.00460678 \n    -0.0341525 0.0232109 -0.0138039 -0.0416538 -0.0458764 -0.0201967 \n    -0.00878316 -0.00379173 -0.00164621 -0.000785131 -0.00037575 \n    -0.000352375 -0.0545586 -0.0746881 -0.0771865 -0.05386 -0.0022199 \n    0.0136703 0.00633526 0.00138826 -0.00108934 0.0038886 0.0298077 \n    0.0475776 0.0481003 0.0464167 0.047818 0.042789 0.035207 \n    0.0264423 0.0193959 0.0151614 0.00624257 -0.00913057 -0.0310696 \n    -0.0430238 0.016426 0.189762 0.49025 0.820116 1.13919 1.43549 \n    1.70658 1.95183 2.17414 2.38506 2.5657 2.73958 2.97905 3.21403 \n    3.43025 3.62645 3.8028 3.96002 4.09996 4.22443 4.33427 4.42886 \n    4.51097 4.5817 4.64326 4.6957 4.74132 4.7797 4.81298 4.84102 \n    4.86512 4.88523 4.90224 4.91649 4.92846 4.93868 4.94755 \n    4.95483 4.96114 4.96682 4.97161 4.97502 4.9776 4.97944 4.98141 \n    4.98319 4.98467 4.98585 4.9869 4.98796 4.98902 4.99008 4.99114 \n    4.9922 4.99326 4.9938 4.99429 4.99479 4.99528 4.99578 4.99628 \n    4.99677 4.99704 4.99718 4.99733 4.99747 4.99762 4.99777 \n    4.99791 4.99806 4.9982 4.99835 4.9985 4.99864 4.99879 4.99893 \n    4.99907 4.99916 4.99925 4.99934 4.99943 5.01473 4.92293 \n    4.61974 4.0316 3.7835 3.74195 3.78344 3.87272 3.97386 4.07319 \n    4.16686 4.25256 4.33126 4.40264 4.46697 4.49249 4.51807 \n    4.55803 4.64055 4.78574 4.86074 4.88334 4.8999 4.91455 4.92814 \n    4.93926 4.94761 4.95433 4.95907 4.9654 4.98317 5.0208 5.05134 \n    4.85852 4.16041 3.00077 1.68376 0.672707 0.240838 0.0794725 \n    -0.0106347 -0.00879443 0.107196 0.368163 0.701424 1.03581 \n    1.3601 1.6678 1.95731 2.22701 2.47544 2.69099 2.92327 3.16648 \n    3.3877 3.59067 3.77344 3.93584 4.08066 4.20863 4.32065 4.41791 \n    4.50211 4.57423 4.63614 4.68888 4.73377 4.7721 4.80519 4.83338 \n    4.85732 4.87815 4.89514 4.90927 4.92108 4.93122 4.94014 \n    4.94845 4.95601 4.96251 4.96576 4.969 4.97225 4.9755 4.97874 \n    4.98087 4.98265 4.98442 4.9862 4.98797 4.98924 4.9899 4.99055 \n    4.9912 4.99186 4.99251 4.99316 4.99381 4.99447 4.99512 4.99577 \n    4.99609 4.99634 4.99659 4.99683 4.99708 4.99732 4.99757 \n    4.99782 4.99806 4.99831 4.99853 4.99863 4.99873 4.99883 \n    4.99893 4.99903 4.99913 4.99923 4.99933 \n    EOD\n\n    @v[14].set(<<-'EOD')\n    1.86175 2.00147 1.85141 1.0654 0.275481 0.205547 0.0712627 \n    0.0313387 0.0151431 0.00864531 0.00593861 0.00438111 0.0037479 \n    0.00305857 0.00221221 0.0017081 -0.0896128 -0.109079 -0.121356 \n    -0.0542001 0.175821 0.177442 0.0814591 0.0333042 0.0134909 \n    0.00625777 0.00100092 -0.00552776 -0.00411139 -0.00150395 \n    -0.000564784 3.48169e-05 -0.000287014 -0.000538515 -0.000456537 \n    -0.000325677 -0.000275468 -0.000166452 -8.27481e-05 -8.28704e-05 \n    -7.47644e-05 -4.60552e-05 -2.61481e-06 2.26359e-05 2.53852e-05 \n    -1.39853e-06 -4.23456e-05 -4.0907e-05 -2.8501e-05 -1.5945e-05 \n    -9.01122e-06 -2.07747e-06 1.49328e-06 4.38398e-06 6.84248e-06 \n    4.76711e-06 2.69173e-06 6.16362e-07 -1.45901e-06 -3.53438e-06 \n    -4.14256e-06 -3.76238e-06 -3.3822e-06 -3.00202e-06 -2.62184e-06 \n    -2.24878e-06 -1.93456e-06 -1.62033e-06 -1.3061e-06 -9.91867e-07 \n    -6.77638e-07 -3.63409e-07 -4.91792e-08 2.6505e-07 5.7928e-07 \n    8.93509e-07 1.16076e-06 1.11055e-06 1.06034e-06 1.01014e-06 \n    9.59927e-07 9.09719e-07 8.59511e-07 8.09302e-07 7.59094e-07 \n    7.08886e-07 6.58678e-07 5.99251e-07 4.87523e-07 3.75795e-07 \n    2.64068e-07 1.5234e-07 4.06119e-08 -7.1116e-08 -1.82844e-07 \n    -2.94572e-07 -4.063e-07 -5.18027e-07 -6.08517e-07 -5.95879e-07 \n    -5.83241e-07 -5.70604e-07 -5.57966e-07 -5.45328e-07 -5.3269e-07 \n    -5.20053e-07 -5.07415e-07 -4.94777e-07 -4.8214e-07 -4.69502e-07 \n    -4.56864e-07 -4.44226e-07 -4.31589e-07 -4.18951e-07 -4.06313e-07 \n    -3.93676e-07 -3.81038e-07 -3.684e-07 -3.55762e-07 -3.43125e-07 \n    1.06736e-05 0.0797407 0.0437947 -0.0645098 -0.0877312 0.0653203 \n    -0.00621184 -0.0353188 -0.0491378 -0.0251957 -0.0110996 \n    -0.00481123 -0.0020941 -0.000998038 -0.000478747 -0.000445332 \n    -0.102046 -0.135753 -0.154351 -0.0827509 0.163348 0.174012 \n    0.0794822 0.0310624 0.0112213 0.00249061 0.00130764 0.00181315 \n    0.00163875 0.00101454 0.000497435 0.000195258 5.31901e-05 \n    2.4607e-05 6.62736e-05 7.90718e-05 4.0372e-05 -0.000141184 \n    -0.000280623 5.5608e-05 0.000799565 0.000920189 0.000931616 \n    0.000494527 0.000162303 -8.24884e-05 -0.000183938 -0.000203899 \n    -0.000144788 -9.87063e-05 -0.000227929 2.93932e-05 0.000208563 \n    1.88958e-06 -7.6335e-05 -0.000172472 -0.000165656 -0.000145889 \n    -0.000177311 -0.000191058 -0.000168287 -0.00015755 -0.00013142 \n    -8.10488e-05 -6.36115e-05 -7.8699e-05 -8.11282e-05 -7.98625e-05 \n    -5.98807e-05 -3.40879e-05 -1.95464e-05 -1.79247e-05 -4.45514e-05 \n    -7.47995e-05 -8.7682e-05 -7.50806e-05 -3.25561e-05 -4.34114e-05 \n    -7.69099e-05 -0.000141101 -0.00018743 -0.000148471 -5.06546e-05 \n    0.000120195 0.000177635 0.000177052 0.000146344 9.75126e-05 \n    8.31233e-05 6.8734e-05 5.43447e-05 3.99554e-05 2.55661e-05 \n    1.11768e-05 -3.21253e-06 -3.88937e-06 -3.56628e-06 -3.24318e-06 \n    -2.92008e-06 -2.59699e-06 -2.27389e-06 -1.9508e-06 -1.73227e-06 \n    -1.56796e-06 -1.40365e-06 -1.23934e-06 -1.07503e-06 -9.10722e-07 \n    -7.46412e-07 -5.82101e-07 -4.1779e-07 -2.5348e-07 -8.91694e-08 \n    7.51412e-08 2.39452e-07 4.03762e-07 5.95733e-07 1.00771e-06 \n    1.41969e-06 1.83167e-06 2.24365e-06 0.0828257 0.231038 0.465438 \n    1.54516 2.8461 3.19221 3.40395 3.6382 3.80758 3.93848 4.04882 \n    4.15428 4.247 4.32917 4.40235 4.36941 4.397 4.48862 4.64552 \n    4.86595 5.03475 5.0348 5.02627 5.01967 5.01542 5.00925 4.98613 \n    4.9519 4.91581 4.87357 4.82302 4.80403 4.82565 4.86102 4.89483 \n    4.92253 4.94428 4.96257 4.97608 4.98373 4.98823 4.99182 \n    4.99437 4.99635 4.99745 4.99802 4.99843 4.99873 4.99895 \n    4.99912 4.99925 4.99931 4.99962 4.99973 4.99972 4.99971 \n    4.9997 4.99969 4.9997 4.99971 4.99973 4.99974 4.99976 4.99978 \n    4.9998 4.99982 4.99985 4.99987 4.99989 4.9999 4.99991 4.99991 \n    4.99993 4.99994 4.99997 5.00001 5.00006 5.00008 5.00006 \n    5.00002 5 4.99999 4.99998 4.99997 4.99995 4.99995 4.99995 \n    4.99995 4.99995 4.99995 4.99995 4.99996 4.99997 4.99997 \n    4.99998 4.99999 5 5 5.00001 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5 5 5 4.99999 4.99999 4.99999 \n    EOD\n\n    @v[15].set(<<-'EOD')\n    1.86175 2.00199 2.08919 1.84314 1.08254 0.214737 0.0377351 \n    0.00952455 0.00232763 0.000563614 0.000263477 0.000148642 \n    0.000285086 0.000242592 7.34699e-05 -1.53467e-05 -0.0161874 \n    -0.0157876 -0.0141194 0.0132576 0.0903272 0.109938 0.0535295 \n    0.0224216 0.00940945 0.00466825 -0.000649972 -0.00654752 \n    -0.00333248 -0.00103671 -0.000508276 -5.8896e-05 -0.00043938 \n    -0.000544704 -0.00044444 -0.000307093 -0.00024517 -0.000154538 \n    -8.78602e-05 -7.10461e-05 -6.06485e-05 -3.91039e-05 -8.45988e-06 \n    9.43442e-06 1.28351e-05 -2.16734e-06 -2.6142e-05 -2.54768e-05 \n    -1.88997e-05 -1.17906e-05 -7.3808e-06 -2.97101e-06 1.19146e-07 \n    2.94246e-06 5.38942e-06 3.88851e-06 2.38761e-06 8.86704e-07 \n    -6.14201e-07 -2.11511e-06 -2.59565e-06 -2.38885e-06 -2.18205e-06 \n    -1.97525e-06 -1.76845e-06 -1.56241e-06 -1.36258e-06 -1.16276e-06 \n    -9.62939e-07 -7.63116e-07 -5.63293e-07 -3.6347e-07 -1.63647e-07 \n    3.61756e-08 2.35999e-07 4.35822e-07 6.07653e-07 5.90323e-07 \n    5.72994e-07 5.55665e-07 5.38336e-07 5.21007e-07 5.03678e-07 \n    4.86349e-07 4.6902e-07 4.51691e-07 4.34361e-07 4.11899e-07 \n    3.60315e-07 3.08731e-07 2.57146e-07 2.05562e-07 1.53977e-07 \n    1.02393e-07 5.08082e-08 -7.76222e-10 -5.23607e-08 -1.03945e-07 \n    -1.47815e-07 -1.54225e-07 -1.60635e-07 -1.67045e-07 -1.73455e-07 \n    -1.79864e-07 -1.86274e-07 -1.92684e-07 -1.99094e-07 -2.05504e-07 \n    -2.11914e-07 -2.18324e-07 -2.24734e-07 -2.31144e-07 -2.37554e-07 \n    -2.43964e-07 -2.50373e-07 -2.56783e-07 -2.63193e-07 -2.69603e-07 \n    -2.76013e-07 -2.82423e-07 2.92534e-06 0.0446777 0.024278 \n    -0.0518987 -0.0636547 0.00983929 -0.000518204 -0.000265194 \n    0.000154772 0.000299538 3.12715e-05 -3.18225e-05 -2.48268e-05 \n    -1.16701e-05 -6.05117e-06 7.61116e-06 -0.0163668 -0.0158244 \n    -0.0141177 0.0100085 0.0857144 0.107784 0.051862 0.0204448 \n    0.00629858 0.000967736 0.00121674 0.00190276 0.00154009 \n    0.000860922 0.000410386 0.000164585 3.99493e-05 1.93797e-05 \n    5.67594e-05 0.000110126 2.49925e-05 -7.17815e-05 -0.000142299 \n    -1.63109e-05 0.000439529 0.000562489 0.000594599 0.000326164 \n    0.000126423 -4.26063e-05 -0.000122927 -0.000114152 -6.72706e-05 \n    -6.41242e-05 -0.000135588 2.61507e-05 0.000134036 6.43734e-06 \n    -4.6223e-05 -0.000112047 -0.000101388 -8.67847e-05 -0.000117664 \n    -0.000133957 -0.000116558 -0.000100873 -7.65448e-05 -4.44964e-05 \n    -3.6677e-05 -5.26632e-05 -5.45172e-05 -5.13545e-05 -3.73869e-05 \n    -1.99732e-05 -1.0907e-05 -1.10081e-05 -3.02609e-05 -5.18517e-05 \n    -6.13597e-05 -5.30706e-05 -2.39572e-05 -3.24146e-05 -5.70062e-05 \n    -0.000103448 -0.000135376 -0.0001024 -2.39007e-05 0.000110929 \n    0.000151226 0.000142044 0.000105922 5.62834e-05 4.78476e-05 \n    3.94117e-05 3.09759e-05 2.25401e-05 1.41042e-05 5.66837e-06 \n    -2.76747e-06 -3.08639e-06 -2.81341e-06 -2.54043e-06 -2.26745e-06 \n    -1.99447e-06 -1.72149e-06 -1.44851e-06 -1.26226e-06 -1.12096e-06 \n    -9.79661e-07 -8.38363e-07 -6.97065e-07 -5.55768e-07 -4.1447e-07 \n    -2.73173e-07 -1.31875e-07 9.42259e-09 1.5072e-07 2.92018e-07 \n    4.33315e-07 5.74613e-07 7.10363e-07 8.01984e-07 8.93604e-07 \n    9.85225e-07 1.07685e-06 0.04474 0.0928765 0.141327 0.0176048 \n    -0.071675 -0.0124613 0.989022 2.28104 3.40619 4.21417 4.67173 \n    4.87438 4.96044 4.98996 4.99858 4.96672 4.89502 4.79391 \n    4.76433 4.8387 4.98612 5.0161 5.01722 5.01437 5.01256 4.99827 \n    4.95807 4.9209 4.88217 4.83006 4.78461 4.80759 4.85548 4.89604 \n    4.9254 4.94617 4.96126 4.97374 4.98255 4.98792 4.99126 4.99361 \n    4.99554 4.99699 4.99792 4.99846 4.99881 4.99905 4.99924 \n    4.99938 4.99949 4.99955 4.9997 4.9998 4.99982 4.99982 4.99982 \n    4.99982 4.99982 4.99983 4.99984 4.99985 4.99986 4.99987 \n    4.99988 4.99989 4.9999 4.99992 4.99993 4.99994 4.99995 4.99995 \n    4.99996 4.99996 4.99998 4.99999 5.00001 5.00002 5.00002 \n    5.00001 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99998 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    EOD\n\n    @v[16].set(<<-'EOD')\n    1.86175 1.73073 1.50572 1.89001 3.39004 4.36034 4.79012 \n    4.93798 4.98305 4.99539 4.9979 4.99904 4.99772 4.9983 4.99935 \n    4.99975 4.98837 4.99456 4.99728 5.01838 5.04568 5.00759 \n    4.98112 4.98479 4.99197 4.99641 4.99747 4.99775 5.00043 \n    5.0007 5.00035 5.00023 4.99976 5.00002 5.00007 5.0002 4.99993 \n    5.00003 5.00021 5.00006 4.99993 4.99992 5.00002 5.00013 \n    5.00017 5.00009 4.99992 4.99991 4.99993 4.99996 4.99998 \n    4.99999 5.00001 5.00003 5.00005 5.00004 5.00004 5.00003 \n    5.00002 5.00001 5 4.99999 4.99999 4.99998 4.99998 4.99997 \n    4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 \n    4.99999 4.99999 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 5 5.01498 4.99342 4.96899 5.00301 5.02627 4.9977 \n    4.99548 4.99757 5.00277 5.00245 5.0014 5.00069 5.00032 5.00014 \n    5.00009 4.9867 4.99262 4.99607 5.01805 5.04713 5.00927 4.98184 \n    4.98483 4.9914 4.99616 4.99902 4.9999 4.99987 4.99979 4.99981 \n    4.99989 4.99994 4.99998 5.0002 5.00001 5.00008 5.00008 5.0001 \n    5.00021 5.00032 5.00025 5.00019 5.00006 5.00007 4.99994 \n    4.99997 4.99999 5.00023 5.00008 4.99993 4.99998 4.99986 \n    4.99982 5.00003 4.99985 4.99996 5.00014 5 4.99984 4.99979 \n    4.99982 4.99993 5.00008 5.00011 5.00002 4.99996 4.9999 4.99994 \n    5.00001 5.00007 5.00009 4.99995 4.99978 4.99971 4.99976 \n    4.99997 4.99996 4.99989 4.99972 4.99955 4.99953 4.99959 \n    4.99976 4.9999 5.00005 5.00023 5.00039 5.00034 5.00029 5.00024 \n    5.00019 5.00014 5.00009 5.00004 5.00003 5.00002 5.00001 \n    5 5 4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 \n    5.00001 5.00002 5.00003 5.00004 5.01564 5.03395 5.04932 \n    5.11868 3.92502 1.31888 0.163888 0.0946876 0.0789578 0.0565084 \n    0.0260333 0.0156986 0.00907667 0.00613629 0.00468417 -0.00174008 \n    -0.0021422 0.000586962 0.0124937 0.0147977 0.00838454 0.00039383 \n    -0.000522021 -0.000426598 -0.000290214 -0.00173713 -0.00384132 \n    -0.00382945 -0.00429219 -0.00580193 -0.00393246 0.0017543 \n    0.00423045 0.00408931 0.0031976 0.00245457 0.00187293 0.00159068 \n    0.00105697 0.000609902 0.000358825 0.000334125 0.000212708 \n    0.000168116 8.97349e-05 5.21578e-05 3.84527e-05 2.93033e-05 \n    2.10067e-05 1.59954e-05 1.13917e-05 5.49738e-06 2.77217e-05 \n    6.51259e-06 -6.65468e-06 2.09837e-06 -6.617e-06 -4.80187e-06 \n    1.55031e-06 4.26536e-06 7.69457e-07 -1.46213e-06 -7.25202e-07 \n    3.26501e-06 6.55807e-06 7.524e-06 6.07209e-06 6.00701e-06 \n    5.41166e-06 3.86573e-06 1.10651e-06 -2.74603e-06 -2.18566e-06 \n    2.3658e-06 8.59956e-06 8.35046e-06 2.90621e-06 -8.75982e-07 \n    -1.87189e-06 -2.1528e-06 -1.94875e-06 -1.74471e-06 -1.54067e-06 \n    -1.33662e-06 -1.13258e-06 -8.40567e-07 -5.20743e-07 -2.00918e-07 \n    1.18906e-07 4.38731e-07 6.11382e-07 6.01529e-07 5.91675e-07 \n    5.81822e-07 5.71968e-07 5.62115e-07 5.52261e-07 5.42407e-07 \n    5.32554e-07 5.227e-07 5.12847e-07 4.72812e-07 4.26137e-07 \n    3.79462e-07 3.32786e-07 2.86111e-07 2.39436e-07 1.92761e-07 \n    1.46086e-07 9.94107e-08 5.27356e-08 -2.77779e-10 -7.98079e-08 \n    -1.59338e-07 -2.38868e-07 -3.18398e-07 -3.97928e-07 -4.77458e-07 \n    -5.56988e-07 -6.36519e-07 \n    EOD\n\n    @v[17].set(<<-'EOD')\n    5 5.16963 4.84136 3.33754 0.316206 0.103113 0.0273341 0.0221102 \n    0.0177008 0.0143758 0.0115203 0.00929231 0.00752716 0.00625439 \n    0.00489872 0.00403656 -0.0657317 -0.0256467 0.165394 0.985963 \n    3.05067 4.55799 4.89728 4.92464 4.8882 4.90592 4.97315 4.99241 \n    4.99694 4.99845 4.99905 4.99939 4.99959 4.99971 4.9998 4.99986 \n    4.9999 4.99993 4.99995 4.99996 4.99997 4.99998 4.99998 4.99999 \n    4.99999 4.99999 4.99999 4.99999 5 5.00001 5.00003 5.00005 \n    5.00004 5.00002 5 4.99999 4.99999 4.99998 4.99998 4.99997 \n    4.99997 4.99998 4.99998 4.99999 4.99999 5 5 5 5 5 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 \n    5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 \n    4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 5 5 5 5 5 5 5.00025 5.1657 4.69981 2.43895 \n    0.0229743 0.0351406 -0.0211974 -0.0312063 -0.0160331 -0.0021718 \n    -0.000766597 -0.000251052 -5.49363e-05 -3.36364e-06 -2.01983e-06 \n    -9.70575e-06 -0.0657007 -0.0205247 0.183332 1.07163 3.11839 \n    4.46213 4.84163 4.95195 4.99159 5.02084 5.04029 5.04138 \n    5.0271 5.00445 4.97957 4.95702 4.95231 4.97819 4.99191 4.9963 \n    4.99822 4.99878 4.99903 4.99925 4.99942 4.9995 4.99954 4.99957 \n    4.99961 4.99966 4.9997 4.99974 4.99977 4.99981 4.99983 4.99986 \n    4.99988 4.9999 4.99991 4.99992 4.99994 4.99995 4.99995 4.99996 \n    4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00001 5.00001 5.00001 \n    5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5 5 5 4.99999 4.99998 4.99997 4.99996 5.14239 4.76219 \n    3.16574 0.299969 0.0631609 -0.00118611 -0.00026052 -5.96333e-05 \n    -1.44904e-05 -4.3859e-06 -2.99454e-06 1.10547e-06 4.84662e-06 \n    1.30971e-05 2.23082e-05 -0.0655844 -0.0204818 0.182507 1.05954 \n    3.12277 4.46735 4.83915 4.94512 4.97679 4.98654 4.9966 5.00833 \n    5.00776 5.00432 5.00199 5.00086 5.00033 5.00008 5 5.00001 \n    5 5.00005 5.00002 4.99981 4.99991 4.99998 4.99979 4.99979 \n    4.99984 4.9998 4.9998 5.00006 5.00002 5.00001 5 5 4.99992 \n    4.99998 4.99999 5.00002 5.00014 4.99999 4.99987 4.99993 \n    5.00003 5.00011 5.00005 4.99996 4.99987 4.99985 4.99994 \n    5.00009 5.0001 5 4.99993 4.99997 5.00008 5.00015 5.00021 \n    5.00021 5.00007 4.99978 4.99965 4.99973 4.9999 4.99992 4.99995 \n    4.99997 4.99999 5.00001 5.00002 5.00001 5.00001 5.00001 \n    5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 5.00001 5.00002 \n    5.00002 5.00002 \n    EOD\n\n    @v[18].set(<<-'EOD')\n    5 5.0333 5.02472 4.92559 4.18383 3.93923 3.9961 4.14293 \n    4.28591 4.41336 4.52157 4.61101 4.68472 4.7439 4.79294 4.83239 \n    4.80697 4.78808 4.79322 4.8838 5.08529 5.21863 4.88852 3.90198 \n    2.14586 0.383977 0.101103 0.0525711 0.0318287 0.020895 0.0146908 \n    0.010831 0.00830272 0.00656377 0.00532066 0.00440078 0.00369956 \n    0.00315713 0.00272614 0.00237965 0.00209659 0.00186339 0.00167014 \n    0.0015081 0.00137172 0.00125607 0.00115393 0.00106076 0.000980166 \n    0.000918015 0.000862837 0.00080766 0.000763488 0.000721541 \n    0.000680825 0.000653026 0.000625226 0.000597426 0.000569627 \n    0.000541827 0.000519087 0.000499756 0.000480424 0.000461093 \n    0.000441761 0.000423291 0.000411941 0.00040059 0.00038924 \n    0.000377889 0.000366539 0.000355188 0.000343838 0.000332487 \n    0.000321137 0.000309786 0.000299055 0.000292509 0.000285963 \n    0.000279417 0.000272871 0.000266325 0.000259779 0.000253233 \n    0.000246686 0.00024014 0.000233594 0.000227387 0.0002231 \n    0.000218813 0.000214526 0.00021024 0.000205953 0.000201666 \n    0.000197379 0.000193092 0.000188805 0.000184519 0.000180526 \n    0.000177963 0.0001754 0.000172837 0.000170274 0.000167711 \n    0.000165148 0.000162585 0.000160022 0.000157459 0.000154895 \n    0.000152332 0.000149769 0.000147206 0.000144643 0.00014208 \n    0.000139517 0.000136954 0.000134391 0.000131828 0.000129265 \n    0.000126702 0.000132838 0.0311184 0.163151 0.34986 0.604501 \n    0.357125 0.136137 0.0711304 0.0346959 0.0212674 0.00872193 \n    0.00252206 0.000455269 7.59332e-05 2.91532e-05 0.000320562 \n    -0.0720911 -0.0840491 -0.0791345 -0.0404143 0.0182035 -0.0235871 \n    -0.0426072 -0.0597501 0.00824773 0.481404 1.32496 2.11949 \n    2.57317 2.58202 2.15054 1.33786 0.45702 0.153772 0.0913584 \n    0.0604989 0.0421591 0.0271456 0.0170021 0.0115815 0.00907886 \n    0.00742466 0.00626096 0.00531127 0.00450501 0.00381927 0.00323718 \n    0.00274374 0.00232494 0.00196885 0.00166686 0.00141134 0.00119437 \n    0.0010109 0.000855534 0.000723378 0.000611408 0.000516704 \n    0.000436769 0.000369523 0.000313026 0.00026526 0.000223976 \n    0.000188972 0.000159042 0.000134148 0.000112688 9.49738e-05 \n    7.97877e-05 6.721e-05 5.65115e-05 4.77194e-05 4.03591e-05 \n    3.42848e-05 2.92627e-05 2.50435e-05 2.1412e-05 1.84532e-05 \n    1.58624e-05 1.34673e-05 1.14461e-05 1.00935e-05 9.12375e-06 \n    8.50202e-06 7.81431e-06 7.20729e-06 6.73936e-06 6.3702e-06 \n    5.90049e-06 5.43077e-06 4.96105e-06 4.49133e-06 4.02162e-06 \n    3.5519e-06 3.08218e-06 2.79099e-06 2.51281e-06 2.23463e-06 \n    1.95645e-06 1.67827e-06 1.40009e-06 1.12191e-06 1.01376e-06 \n    9.9375e-07 9.73741e-07 9.53733e-07 9.33724e-07 9.13715e-07 \n    8.93707e-07 8.73698e-07 8.5369e-07 8.33681e-07 8.13673e-07 \n    7.93664e-07 7.73655e-07 7.53647e-07 7.21781e-07 5.956e-07 \n    4.69419e-07 3.43239e-07 2.17058e-07 0.0284032 0.0374438 \n    -0.0157543 -0.0680497 0.0504768 0.0100294 0.00222261 0.000528697 \n    0.000132929 3.99489e-05 2.46066e-05 4.56327e-06 -6.54853e-06 \n    1.33783e-05 -3.68221e-05 -0.0724498 -0.0843663 -0.0792935 \n    -0.0406426 0.0200019 0.0426259 0.0220753 0.00668555 -0.000968483 \n    0.024662 0.0383437 0.0911513 0.087848 0.0602076 0.0390559 \n    0.0260573 0.0180444 0.012974 0.00985409 0.00788132 0.0064228 \n    0.005545 0.00453571 0.00364245 0.00310278 0.00270523 0.00236439 \n    0.0020945 0.00186808 0.00167493 0.00151731 0.00138594 0.00126945 \n    0.00116695 0.0010762 0.000996366 0.000928387 0.000864414 \n    0.000808258 0.000759574 0.000713865 0.000666712 0.000632716 \n    0.000601262 0.000572163 0.000543986 0.000515253 0.0004897 \n    0.000468112 0.000449313 0.000432981 0.000417911 0.000401307 \n    0.000382712 0.000366678 0.000355736 0.000349171 0.000335727 \n    0.000317091 0.000296086 0.000283543 0.000277366 0.000272233 \n    0.000267001 0.000263147 0.000256699 0.000250251 0.000243803 \n    0.000237355 0.000230907 0.000225424 0.000220247 0.000215069 \n    0.000209892 0.000204714 0.000200213 0.000196548 0.000192884 \n    0.00018922 0.000185556 0.000181892 0.000178228 0.000174564 \n    0.0001709 0.000167236 0.000163572 0.000160824 0.000158279 \n    0.000155733 0.000153187 0.000150641 0.000148095 0.000145549 \n    0.000143003 0.000140457 0.000137911 0.000135457 0.000133386 \n    0.000131315 0.000129245 0.000127174 0.000125103 0.000123032 \n    0.000120961 0.000118891 \n    EOD\n\n    @v[19].set(<<-'EOD')\n    1.86175 1.99994 2.0833 2.01627 2.42503 3.25769 3.62134 3.88827 \n    4.09688 4.26773 4.40529 4.51734 4.60827 4.68313 4.74346 \n    4.79302 4.72815 4.68959 4.70421 4.81316 5.01375 5.14493 \n    5.10305 5.0699 5.04484 5.03751 5.03348 5.02504 5.01799 5.01271 \n    5.00895 5.00628 5.0044 5.00309 5.00216 5.00151 5.00105 5.00073 \n    5.00051 5.00034 5.00023 5.00015 5.0001 5.00007 5.00003 4.99998 \n    4.99993 4.99993 4.99995 4.99999 5.00001 5.00003 5.00002 \n    5.00001 5 5 5 5 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00017 5.17398 \n    4.94779 3.78508 1.52302 0.608808 0.244311 0.126053 0.0597175 \n    0.038422 0.0158174 0.00481338 0.00107847 0.000301256 0.000114861 \n    0.00059489 -0.118904 -0.147478 -0.158986 -0.080544 0.165361 \n    0.171378 0.0776087 0.0435738 0.0428235 0.0423755 0.0347695 \n    0.0225061 0.0155539 0.0121357 0.0107997 0.0103976 0.0124406 \n    0.016814 0.0167556 0.0149852 0.01459 0.0141182 0.0131934 \n    0.0120286 0.0108692 0.0097184 0.00855881 0.00744912 0.00643877 \n    0.00554044 0.00475165 0.00406535 0.00347158 0.00295981 0.00251995 \n    0.00214318 0.00182101 0.00154613 0.00131196 0.0011119 0.000941587 \n    0.000796999 0.000674582 0.000571283 0.000484276 0.000410649 \n    0.000347005 0.000292984 0.000246715 0.000208143 0.00017489 \n    0.000147412 0.000123854 0.000104332 8.77229e-05 7.40686e-05 \n    6.2637e-05 5.32e-05 4.53946e-05 3.88343e-05 3.31864e-05 \n    2.85905e-05 2.45725e-05 2.08671e-05 1.77301e-05 1.55911e-05 \n    1.40153e-05 1.29421e-05 1.18693e-05 1.09815e-05 1.03484e-05 \n    9.87664e-06 9.14446e-06 8.41228e-06 7.68011e-06 6.94793e-06 \n    6.21575e-06 5.48357e-06 4.7514e-06 4.38454e-06 4.04432e-06 \n    3.7041e-06 3.36388e-06 3.02366e-06 2.68344e-06 2.34322e-06 \n    2.15196e-06 2.03791e-06 1.92386e-06 1.80982e-06 1.69577e-06 \n    1.58173e-06 1.46768e-06 1.35363e-06 1.23959e-06 1.12554e-06 \n    1.0115e-06 8.9745e-07 7.83404e-07 6.69358e-07 4.76113e-07 \n    -3.47071e-07 -1.17025e-06 -1.99344e-06 -2.81662e-06 0.0783754 \n    0.0500262 -0.0659563 -0.120914 0.0815957 0.0154255 0.00347177 \n    0.000840357 0.000214582 6.54655e-05 3.91709e-05 8.07396e-06 \n    -4.44265e-07 1.74384e-05 -4.52725e-05 -0.119379 -0.147984 \n    -0.159247 -0.0824604 0.169014 0.177628 0.0758742 0.010558 \n    -0.0346506 -0.0710288 -0.0838952 -0.0599521 -0.034568 -0.0181615 \n    -0.00968034 -0.00547115 -0.00333511 -0.00232468 -0.00181159 \n    -0.00143841 -0.00116601 -0.000839755 -0.000569764 -0.000578683 \n    -0.000490551 -0.000411712 -0.000437859 -0.000408185 -0.000356644 \n    -0.000311332 -0.000269006 -0.000221396 -0.000210054 -0.0001923 \n    -0.000175122 -0.000161039 -0.0001428 -0.000126123 -0.000127893 \n    -8.14516e-05 -0.000120166 -0.000154909 -0.000112733 -8.40377e-05 \n    -7.11342e-05 -8.09538e-05 -9.77789e-05 -9.82402e-05 -7.73531e-05 \n    -5.28255e-05 -3.1096e-05 -1.87967e-05 -1.96552e-05 -4.16655e-05 \n    -5.77185e-05 -5.24142e-05 -2.83153e-05 -1.90012e-05 -1.54415e-05 \n    -2.52569e-05 -6.23747e-05 -0.000130543 -0.000149394 -0.000110886 \n    -4.35517e-05 -4.17084e-05 -3.98651e-05 -3.80218e-05 -3.61785e-05 \n    -3.43352e-05 -3.36249e-05 -3.32729e-05 -3.29208e-05 -3.25687e-05 \n    -3.22166e-05 -3.17143e-05 -3.10258e-05 -3.03372e-05 -2.96486e-05 \n    -2.89601e-05 -2.82715e-05 -2.75829e-05 -2.68944e-05 -2.62058e-05 \n    -2.55173e-05 -2.48287e-05 -2.43043e-05 -2.38159e-05 -2.33276e-05 \n    -2.28393e-05 -2.2351e-05 -2.18626e-05 -2.13743e-05 -2.0886e-05 \n    -2.03977e-05 -1.99093e-05 -1.945e-05 -1.91122e-05 -1.87744e-05 \n    -1.84366e-05 -1.80987e-05 -1.77609e-05 -1.74231e-05 -1.70853e-05 \n    -1.67474e-05 \n    EOD\n\n    @v[20].set(<<-'EOD')\n    1.86175 1.99724 2.17266 2.48439 3.15933 3.85231 4.38091 \n    4.69033 4.85034 4.92851 4.96453 4.98188 4.98736 4.991 4.99482 \n    4.9973 4.96422 4.89989 4.83907 4.83151 4.90868 5.04854 5.06104 \n    5.04571 5.03219 5.03025 5.02273 5.01707 5.0123 5.0087 5.00611 \n    5.00429 5.00301 5.00211 5.00148 5.00103 5.00072 5.0005 5.00035 \n    5.00024 5.00016 5.00011 5.00007 5.00005 5.00003 5.00001 \n    4.99999 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 \n    5 5 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 \n    5 5 4.99981 5.10081 5.10903 4.98404 5.00999 5.14946 4.36501 \n    2.23938 0.325144 0.00660272 -0.0102186 -0.0082401 -0.00556785 \n    -0.00374178 -0.00264763 -0.00202823 -0.0182241 -0.0169551 \n    -0.0150395 0.0103736 0.0877592 0.104382 0.0515938 0.0373818 \n    0.0411547 0.0397009 0.0308946 0.0205793 0.0154037 0.0129191 \n    0.0119327 0.011527 0.0124295 0.0161152 0.0161076 0.0145391 \n    0.0144541 0.0139287 0.0129215 0.0117239 0.0105795 0.00942983 \n    0.00827423 0.00718354 0.00619954 0.00532868 0.00456631 0.00390448 \n    0.00333254 0.00284003 0.00241714 0.00205524 0.0017458 0.00148202 \n    0.00125739 0.0010655 0.000902213 0.000763611 0.000646279 \n    0.000547291 0.000463934 0.000393401 0.000332424 0.000280655 \n    0.000236328 0.000199386 0.000167536 0.000141218 0.000118654 \n    9.99559e-05 8.40479e-05 7.09694e-05 6.00188e-05 5.09786e-05 \n    4.3502e-05 3.72191e-05 3.18114e-05 2.74071e-05 2.35539e-05 \n    1.99967e-05 1.69871e-05 1.49449e-05 1.3451e-05 1.24492e-05 \n    1.14256e-05 1.05669e-05 9.94487e-06 9.47514e-06 8.77318e-06 \n    8.07123e-06 7.36927e-06 6.66731e-06 5.96536e-06 5.2634e-06 \n    4.56144e-06 4.23044e-06 3.92649e-06 3.62254e-06 3.31858e-06 \n    3.01463e-06 2.71068e-06 2.40673e-06 2.23063e-06 2.12082e-06 \n    2.01102e-06 1.90121e-06 1.7914e-06 1.68159e-06 1.57178e-06 \n    1.46197e-06 1.35216e-06 1.24235e-06 1.13255e-06 1.02274e-06 \n    9.12929e-07 8.0312e-07 6.33171e-07 -1.51288e-08 -6.63428e-07 \n    -1.31173e-06 -1.96003e-06 0.0437517 0.0265689 -0.0515377 \n    -0.0658688 0.010727 -0.000511921 -8.36924e-05 2.13278e-05 \n    1.45207e-05 4.54862e-06 -6.14726e-06 2.0062e-06 1.02709e-06 \n    1.4152e-05 -3.08225e-05 -0.0166501 -0.0157139 -0.013957 \n    0.0107537 0.0873717 0.111302 0.0454129 -0.00530142 -0.0468336 \n    -0.0790063 -0.0826944 -0.0534753 -0.0288705 -0.0149009 -0.00801592 \n    -0.0046342 -0.00291835 -0.00213019 -0.00170055 -0.001352 \n    -0.00110593 -0.000742655 -0.000532042 -0.000544742 -0.000479206 \n    -0.000407307 -0.000403575 -0.000366209 -0.000324161 -0.000286183 \n    -0.000247579 -0.000214281 -0.000203435 -0.000186896 -0.000171033 \n    -0.00015779 -0.000145259 -0.000128069 -0.000122647 -9.89398e-05 \n    -0.000114926 -0.000132195 -0.000107872 -8.91015e-05 -7.87996e-05 \n    -8.14061e-05 -8.9098e-05 -8.83368e-05 -7.6122e-05 -6.14668e-05 \n    -4.75402e-05 -3.81855e-05 -3.69696e-05 -4.78656e-05 -5.61346e-05 \n    -5.35007e-05 -4.1459e-05 -3.35411e-05 -2.52374e-05 -2.37479e-05 \n    -4.6406e-05 -9.41884e-05 -0.000109222 -8.52676e-05 -4.25166e-05 \n    -4.10125e-05 -3.95085e-05 -3.80045e-05 -3.65004e-05 -3.49964e-05 \n    -3.41627e-05 -3.3541e-05 -3.29193e-05 -3.22976e-05 -3.16758e-05 \n    -3.10334e-05 -3.03653e-05 -2.96971e-05 -2.9029e-05 -2.83609e-05 \n    -2.76928e-05 -2.70246e-05 -2.63565e-05 -2.56884e-05 -2.50203e-05 \n    -2.43521e-05 -2.38716e-05 -2.34324e-05 -2.29932e-05 -2.25539e-05 \n    -2.21147e-05 -2.16755e-05 -2.12362e-05 -2.0797e-05 -2.03578e-05 \n    -1.99186e-05 -1.95079e-05 -1.9217e-05 -1.8926e-05 -1.8635e-05 \n    -1.8344e-05 -1.8053e-05 -1.7762e-05 -1.74711e-05 -1.71801e-05 \n    EOD\n\n    @v[21].set(<<-'EOD')\n    1.86175 1.73273 1.42016 1.02483 0.944013 0.274107 0.0823742 \n    0.0379366 0.020816 0.0132952 0.00955525 0.00717008 0.00592286 \n    0.00437379 0.00383557 0.00273694 -0.0037467 -0.0054191 -0.00131454 \n    0.0112179 0.0133918 0.00519747 -0.00260113 -0.00252847 -0.00181292 \n    0.000183398 -0.000667607 -0.000750747 -0.000594314 -0.000433904 \n    -0.000308985 -0.000217858 -0.000152926 -0.000107454 -7.54076e-05 \n    -5.2675e-05 -3.66299e-05 -2.54341e-05 -1.75095e-05 -1.18848e-05 \n    -7.97289e-06 -5.30239e-06 -3.53615e-06 -2.38504e-06 -2.40158e-06 \n    -3.84485e-06 -5.29435e-06 -2.57099e-06 1.95189e-06 3.55083e-06 \n    2.06179e-06 5.72753e-07 3.30469e-07 3.40296e-07 3.60221e-07 \n    4.86081e-07 6.1194e-07 7.37799e-07 8.63659e-07 9.89518e-07 \n    9.21274e-07 7.22275e-07 5.23276e-07 3.24277e-07 1.25278e-07 \n    -5.59467e-08 -9.03265e-08 -1.24706e-07 -1.59086e-07 -1.93466e-07 \n    -2.27846e-07 -2.62226e-07 -2.96605e-07 -3.30985e-07 -3.65365e-07 \n    -3.99745e-07 -4.24266e-07 -3.82163e-07 -3.40061e-07 -2.97959e-07 \n    -2.55857e-07 -2.13755e-07 -1.71652e-07 -1.2955e-07 -8.7448e-08 \n    -4.53457e-08 -3.24353e-09 3.76901e-08 7.19937e-08 1.06297e-07 \n    1.40601e-07 1.74904e-07 2.09208e-07 2.43512e-07 2.77815e-07 \n    3.12119e-07 3.46422e-07 3.80726e-07 4.04507e-07 3.77191e-07 \n    3.49876e-07 3.22561e-07 2.95246e-07 2.67931e-07 2.40616e-07 \n    2.13301e-07 1.85986e-07 1.58671e-07 1.31356e-07 1.04041e-07 \n    7.67256e-08 4.94105e-08 2.20955e-08 -5.21962e-09 -3.25347e-08 \n    -5.98498e-08 -8.71649e-08 -1.1448e-07 -1.41795e-07 -1.6911e-07 \n    7.87893e-06 0.0114592 -0.0245712 -0.111637 0.0961324 1.61168 \n    3.22343 4.20442 4.53535 4.83834 4.95464 4.98874 4.99746 \n    4.99883 4.99948 4.99815 4.98431 4.99298 4.99718 5.01948 \n    5.04749 5.008 4.98243 4.98985 4.99781 4.99887 4.99679 4.99616 \n    4.99743 4.99859 4.99936 4.99972 5.00058 5.00123 5.0002 4.99945 \n    4.99983 4.9998 4.99966 4.99958 4.99956 4.99956 4.99956 4.99958 \n    4.99961 4.99965 4.99969 4.99973 4.99977 4.9998 4.99983 4.99985 \n    4.99987 4.99989 4.99991 4.99992 4.99993 4.99994 4.99995 \n    4.99996 4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00001 5.00001 \n    5.00001 5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5 5 5 4.99999 4.99998 4.99997 4.99996 5.01454 \n    4.99566 4.96796 4.99819 5.03232 5.00034 4.99867 4.99937 \n    4.99977 4.99992 4.99997 4.99999 5.00001 5.00021 4.99974 \n    4.98462 4.99301 4.99723 5.01936 5.04807 5.00929 4.9789 4.97876 \n    4.98244 4.9863 4.99575 5.0069 5.00863 5.00624 5.00357 5.0019 \n    5.00098 5.00048 5.00025 5.00016 5.00011 5.00013 5.00009 \n    4.99982 4.99994 5.00005 4.99994 4.99988 4.99989 4.99997 \n    5.00003 5.00005 5.00002 5.00001 5.00001 5.00001 4.99993 \n    4.99999 5 5.00021 4.99997 4.99981 5 5.00009 5.0001 5.00001 \n    4.99991 4.9999 5 5.00011 5.00017 5.00018 5.00018 5.00014 \n    5.00007 4.99999 4.9999 4.9999 5.00001 5.00016 5.00014 4.99999 \n    4.99993 4.99999 5.00009 5.00007 5.00006 5.00004 5.00003 \n    5.00001 5.00001 5 4.99999 4.99998 4.99997 4.99997 4.99997 \n    4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 \n    5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5 5 \n    EOD\n\n    @v[22].set(<<-'EOD')\n    7.10441e-10 0.00107105 0.000637109 -0.00236346 -0.018079 \n    -0.0120077 -0.00217059 0.00266679 0.00403383 0.00403836 \n    0.00356705 0.00303303 0.00244716 0.00198586 0.0016855 0.00136497 \n    -3.96022e-05 -0.000367409 -3.77079e-05 0.00194085 0.00506964 \n    -0.0400214 -0.0402572 0.0524434 0.286234 0.803011 1.44795 \n    2.02473 2.54768 3.02748 3.4415 3.78287 4.09667 4.35152 4.53987 \n    4.67614 4.77407 4.84319 4.89227 4.92702 4.95119 4.96764 \n    4.97846 4.98557 4.98982 4.99209 4.99371 4.99569 4.99727 \n    4.99802 4.99834 4.99867 4.99892 4.99915 4.99936 4.99939 \n    4.99943 4.99946 4.9995 4.99953 4.99957 4.9996 4.99963 4.99967 \n    4.9997 4.99973 4.99974 4.99975 4.99976 4.99977 4.99978 4.9998 \n    4.99981 4.99982 4.99983 4.99984 4.99985 4.99986 4.99986 \n    4.99986 4.99987 4.99987 4.99988 4.99988 4.99989 4.99989 \n    4.9999 4.9999 4.9999 4.9999 4.99991 4.99991 4.99991 4.99991 \n    4.99992 4.99992 4.99992 4.99992 4.99993 4.99993 4.99993 \n    4.99993 4.99993 4.99993 4.99993 4.99993 4.99994 4.99994 \n    4.99994 4.99994 4.99994 4.99994 4.99994 4.99994 4.99995 \n    4.99995 4.99995 4.99995 4.99995 4.99995 4.99995 5.00145 \n    5.00659 5.01209 5.01931 5.00279 4.99273 4.99217 4.99295 \n    4.99471 4.99594 4.99696 4.9978 4.99844 4.99891 4.99924 4.99635 \n    4.99699 4.99813 5.00068 5.00307 5.0588 4.96365 4.54012 3.6307 \n    2.35176 1.0322 0.354379 0.115986 0.0435668 0.0245112 0.020786 \n    0.0164656 0.0118409 0.00849698 0.00597078 0.0040105 0.0026076 \n    0.0016597 0.00118185 0.00121067 0.00153587 0.00174836 0.00136519 \n    -0.000189116 -0.00315555 -0.00646603 -0.00898042 -0.010203 \n    -0.0110896 -0.0123764 -0.00953841 -0.00225795 0.000818314 \n    0.00152252 0.00150269 0.00119025 0.000767068 0.000308852 \n    -3.79272e-05 -0.00019691 -0.000186642 -9.73653e-05 -8.49784e-06 \n    2.04147e-05 -9.91086e-06 -1.55959e-05 -1.80499e-05 -1.77097e-05 \n    -1.51548e-05 -1.1978e-05 -9.84916e-06 -1.29728e-05 -1.67235e-05 \n    -1.74153e-05 -1.39958e-05 -5.92272e-06 -8.08216e-06 -1.53077e-05 \n    -2.92531e-05 -3.91049e-05 -2.98935e-05 -7.32122e-06 3.18534e-05 \n    4.39134e-05 4.18753e-05 3.22759e-05 1.86766e-05 1.58432e-05 \n    1.30098e-05 1.01765e-05 7.34312e-06 4.50975e-06 1.67639e-06 \n    -1.15697e-06 -1.23877e-06 -1.11991e-06 -1.00106e-06 -8.82208e-07 \n    -7.63355e-07 -6.44502e-07 -5.2565e-07 -4.29318e-07 -3.44661e-07 \n    -2.60004e-07 -1.75347e-07 -9.06904e-08 -6.03349e-09 7.86234e-08 \n    1.6328e-07 2.47937e-07 3.32594e-07 4.17251e-07 5.01908e-07 \n    5.86565e-07 6.71222e-07 7.36123e-07 6.43886e-07 5.5165e-07 \n    4.59414e-07 3.67178e-07 0.000334759 -4.60833e-05 -0.00106139 \n    -0.00166624 0.000859563 0.00102606 0.00410037 0.00419931 \n    0.00518997 0.00459791 0.00503125 0.00523877 0.00452158 0.00339924 \n    0.00233399 0.000876915 0.000546439 0.000444299 0.000983968 \n    0.00119304 -0.0429422 -0.0403983 0.0534896 0.288013 0.807345 \n    1.44247 2.03448 2.57021 3.05049 3.47332 3.8131 4.1009 4.34677 \n    4.53512 4.67127 4.76531 4.82526 4.86593 4.89586 4.91904 \n    4.93806 4.95348 4.96597 4.97629 4.9843 4.98983 4.99335 4.9957 \n    4.99741 4.99864 4.99946 4.99994 5.00047 5.00073 5.00086 \n    5.00092 5.00094 5.00091 5.00087 5.00081 5.00074 5.00067 \n    5.00059 5.00052 5.00046 5.0004 5.00034 5.0003 5.00026 5.00022 \n    5.00019 5.00016 5.00014 5.00012 5.0001 5.00009 5.00007 5.00006 \n    5.00006 5.00005 5.00004 5.00004 5.00004 5.00003 5.00003 \n    5.00003 5.00002 5.00002 5.00002 5.00002 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5 5 5 5 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5.00001 5.00001 \n    5.00001 5.00001 5.00002 5.00002 \n    EOD\n\n    @v[23].set(<<-'EOD')\n    5 5.00284 5.01266 5.01895 4.98936 4.99575 4.99217 4.99545 \n    4.99775 4.99894 4.99946 4.99968 4.99975 4.99977 4.99986 \n    4.9999 4.99528 4.99808 5.00039 5.00392 5.00512 4.99985 4.99863 \n    4.99942 4.99992 5.00017 4.99897 4.99803 4.99784 4.99739 \n    4.99883 5.00365 5.00298 5.00133 5.00048 5.00019 5.00008 \n    5.00005 5.00004 5.00003 5.00002 5.00002 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5 5 4.99999 4.99997 4.99995 4.99996 \n    4.99998 5 5.00001 5.00001 5.00002 5.00002 5.00003 5.00003 \n    5.00002 5.00002 5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99998 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00002 \n    5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5 5 5 5 5 5 5 5.00217 5.00108 4.99547 4.99658 5.00667 \n    4.99641 4.99532 4.99938 5.00328 5.00222 5.00114 5.00052 \n    5.00024 5.00011 5.00009 4.99285 4.99591 4.99897 5.00403 \n    5.00786 5.00318 4.99942 4.9992 4.99949 5.001 5.00408 5.00319 \n    5.00063 4.99995 5.00014 4.99982 4.99832 4.99838 4.99865 \n    4.99912 4.99836 4.99735 4.99606 4.99814 5.00958 5.02973 \n    5.05293 5.06103 4.99342 4.80726 4.50744 4.07509 3.41358 \n    2.37924 1.03194 0.261552 0.142392 0.0904482 0.0555071 0.0322869 \n    0.018289 0.0113802 0.00875182 0.00757055 0.00629906 0.00523 \n    0.00403349 0.0031953 0.00280864 0.00286119 0.00250389 0.00202815 \n    0.001723 0.00147312 0.0012411 0.00104401 0.000886204 0.000758277 \n    0.000651915 0.00056348 0.000487966 0.000424048 0.000365613 \n    0.000308178 0.000258725 0.000228061 0.000207976 0.000198491 \n    0.00018518 0.000172716 0.000163197 0.000155007 0.000141734 \n    0.000128461 0.000115188 0.000101915 8.86417e-05 7.53686e-05 \n    6.20956e-05 5.69164e-05 5.23275e-05 4.77385e-05 4.31495e-05 \n    3.85605e-05 3.39716e-05 2.93826e-05 2.69449e-05 2.56224e-05 \n    2.42999e-05 2.29774e-05 2.16549e-05 2.03324e-05 1.90099e-05 \n    1.76873e-05 1.63648e-05 1.50423e-05 1.37198e-05 1.23973e-05 \n    1.10748e-05 9.75232e-06 8.48447e-06 7.65129e-06 6.81811e-06 \n    5.98494e-06 5.15176e-06 0.00056893 -0.00787906 -0.0217381 \n    -0.0370066 -0.00770505 0.00659312 0.00975477 0.00949456 \n    0.00777552 0.00655645 0.00568776 0.00508782 0.00458121 0.00410187 \n    0.00365665 0.0015121 0.00160863 0.00263181 0.00638941 0.00772607 \n    0.00225583 0.0010843 0.000882939 0.000801563 0.00075632 \n    0.000554992 0.000435131 0.0003474 0.000217667 0.000491602 \n    0.0012267 0.00250446 0.000212058 -0.0174972 -0.0527527 -0.0479071 \n    0.194908 1.45838 3.40677 4.49242 4.86894 4.97215 5.01218 \n    5.04342 5.06228 5.03069 4.87169 4.57056 4.11523 3.38264 \n    2.19691 0.715839 0.172818 0.102162 0.0627162 0.0363388 0.020289 \n    0.0119414 0.00826608 0.0066417 0.00549092 0.00492505 0.00439443 \n    0.0037156 0.00306471 0.00247451 0.00195965 0.0014822 0.0010815 \n    0.000904464 0.0010514 0.00152308 0.00120752 0.000228447 \n    -0.00102833 -0.00116644 -0.00042067 4.78758e-05 5.09599e-05 \n    -4.45756e-05 -3.22966e-06 3.81163e-05 7.94622e-05 0.000120808 \n    0.000162154 0.000161895 0.000148481 0.000135068 0.000121654 \n    0.000108241 9.81453e-05 9.2164e-05 8.61827e-05 8.02014e-05 \n    7.42201e-05 6.82388e-05 6.22576e-05 5.62763e-05 5.0295e-05 \n    4.43137e-05 3.83324e-05 3.54323e-05 3.321e-05 3.09877e-05 \n    2.87654e-05 2.65431e-05 2.43209e-05 2.20986e-05 1.98763e-05 \n    1.7654e-05 1.54317e-05 1.34612e-05 1.25441e-05 1.1627e-05 \n    1.07099e-05 9.79276e-06 8.87564e-06 7.95851e-06 7.04139e-06 \n    6.12427e-06 \n    EOD\n\n    @v[24].set(<<-'EOD')\n    5 5.01099 5.00866 4.97845 4.92369 4.9273 4.97413 4.9929 \n    4.99826 4.99958 4.99978 5.00005 4.99968 4.99959 5.00014 \n    4.99979 4.99914 4.99982 5.00023 5.00295 5.00664 4.99854 \n    4.99647 5.00438 5.01722 5.03681 5.04766 5.04799 5.04867 \n    5.04873 5.04685 5.04413 5.0367 5.02505 5.01726 5.01183 5.00806 \n    5.00549 5.00371 5.00246 5.00162 5.00105 5.00069 5.00045 \n    5.00031 5.00024 5.00019 5.00012 5.00007 5.00004 5.00001 \n    4.99998 4.99999 4.99999 5 5.00001 5.00001 5.00002 5.00002 \n    5.00003 5.00003 5.00003 5.00002 5.00002 5.00001 5.00001 \n    5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    5 5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5.00418 4.99953 4.99152 \n    4.99807 5.00497 5.00112 5.00055 5.00038 5.00018 5.00006 \n    5.00006 5.00007 5.00006 5.00004 5.00004 4.99853 4.99945 \n    4.99998 5.00304 5.00935 5.00742 4.99181 4.97421 4.93603 \n    4.8853 4.8927 4.93984 4.97458 4.99039 4.99614 4.99801 4.99851 \n    4.99869 4.99924 5.00108 5.00181 5.00119 5.00059 5.00031 \n    5.00022 5.00018 5.00011 5.00001 5.00006 4.99981 4.99977 \n    4.99982 5.00012 4.99993 5.00008 5.00043 5.00048 5.00024 \n    5.00008 4.99984 4.99993 5.00011 4.99996 4.9998 4.99977 4.9998 \n    4.99993 5.00008 5.00011 5.00002 4.99995 4.99989 4.99993 \n    5 5.00007 5.00009 4.99994 4.99977 4.9997 4.99975 4.99996 \n    4.99996 4.99988 4.9997 4.99952 4.9995 4.99956 4.99973 4.99988 \n    5.00005 5.00025 5.00042 5.00036 5.00031 5.00025 5.0002 5.00014 \n    5.00009 5.00003 5.00002 5.00001 5.00001 5 4.99999 4.99998 \n    4.99998 4.99997 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99998 4.99998 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5.00284 \n    5.00442 5.00381 4.98997 4.99092 5.00733 5.07791 4.98237 \n    4.86434 4.76835 4.74067 4.79278 4.85094 4.90068 4.93603 \n    4.95698 4.96984 4.97856 4.98869 4.99904 5.0005 4.99524 5.00181 \n    5.01878 5.05177 5.07986 4.98917 4.56217 3.68 2.3539 1.18541 \n    0.505772 0.221044 0.115287 0.0760938 0.0589194 0.0476784 \n    0.0457213 0.0412911 0.033889 0.0259741 0.0191452 0.0139018 \n    0.0100235 0.00711788 0.00497657 0.00349368 0.00250021 0.00176179 \n    0.00121843 0.000838368 0.000582711 0.000423458 0.000294608 \n    0.000201251 0.000133748 8.6227e-05 5.44252e-05 3.30514e-05 \n    1.93926e-05 1.09814e-05 5.29857e-06 1.92247e-06 3.08708e-07 \n    -3.74311e-07 -6.11121e-07 -7.27807e-07 -4.87604e-07 -4.80493e-07 \n    -9.15925e-07 -2.03774e-06 -4.01128e-06 -2.46644e-06 2.10626e-06 \n    8.22422e-06 1.04922e-05 9.83047e-06 7.27106e-06 3.29654e-06 \n    -2.06736e-06 -2.18019e-06 -2.29303e-06 -2.40586e-06 -2.51869e-06 \n    -2.63153e-06 -2.24615e-06 -1.70325e-06 -1.16036e-06 -6.17468e-07 \n    -7.45754e-08 2.45198e-07 2.88285e-07 3.31373e-07 3.7446e-07 \n    4.17548e-07 4.60635e-07 5.03723e-07 5.4681e-07 5.89898e-07 \n    6.32985e-07 6.76073e-07 6.19054e-07 5.4001e-07 4.60967e-07 \n    3.81923e-07 3.02879e-07 2.23836e-07 1.44792e-07 6.57488e-08 \n    -1.32948e-08 -9.23383e-08 -1.6698e-07 -2.23206e-07 -2.79432e-07 \n    -3.35658e-07 -3.91884e-07 -4.48109e-07 -5.04335e-07 -5.60561e-07 \n    -6.16787e-07 \n    EOD\n\n    @v[25].set(<<-'EOD')\n    1.34824 1.35838 1.36465 1.34675 1.29167 1.23161 1.2201 1.2185 \n    1.2181 1.21798 1.21793 1.21788 1.21785 1.21782 1.21779 1.21776 \n    1.21655 1.21656 1.21669 1.21871 1.22421 1.22247 1.21858 \n    1.2228 1.23803 1.27737 1.10647 0.395248 0.0600669 0.027687 \n    0.0192374 0.015425 0.0130881 0.00977445 0.00696598 0.00491122 \n    0.00341952 0.00237078 0.00162339 0.00109178 0.000726647 \n    0.000478886 0.00031568 0.000207902 0.000143494 0.000109768 \n    8.62987e-05 5.69775e-05 3.36547e-05 2.30356e-05 1.86108e-05 \n    1.41861e-05 1.08293e-05 7.68835e-06 4.79593e-06 4.51019e-06 \n    4.22444e-06 3.9387e-06 3.65295e-06 3.36721e-06 3.04559e-06 \n    2.69981e-06 2.35403e-06 2.00825e-06 1.66247e-06 1.34508e-06 \n    1.26225e-06 1.17941e-06 1.09657e-06 1.01373e-06 9.30893e-07 \n    8.48054e-07 7.65216e-07 6.82378e-07 5.9954e-07 5.16702e-07 \n    4.37489e-07 3.82774e-07 3.2806e-07 2.73346e-07 2.18632e-07 \n    1.63917e-07 1.09203e-07 5.4489e-08 -2.2523e-10 -5.49395e-08 \n    -1.09654e-07 -1.52862e-07 -1.3079e-07 -1.08718e-07 -8.6646e-08 \n    -6.45739e-08 -4.25019e-08 -2.04298e-08 1.64229e-09 2.37144e-08 \n    4.57864e-08 6.78585e-08 8.71693e-08 9.30725e-08 9.89758e-08 \n    1.04879e-07 1.10782e-07 1.16685e-07 1.22589e-07 1.28492e-07 \n    1.34395e-07 1.40298e-07 1.46201e-07 1.52105e-07 1.58008e-07 \n    1.63911e-07 1.69814e-07 1.75718e-07 1.81621e-07 1.87524e-07 \n    1.93427e-07 1.9933e-07 2.05234e-07 2.11137e-07 2.19788e-07 \n    0.000393944 -0.000218983 -0.00105784 0.00172403 -0.00027134 \n    -0.000204147 8.79968e-06 5.93762e-05 5.83554e-05 4.13815e-05 \n    3.71369e-05 3.03372e-05 2.25336e-05 1.5986e-05 1.07284e-05 \n    -7.5239e-05 5.60593e-05 6.97571e-05 0.000667617 0.000960856 \n    0.00131749 -0.00759564 -0.0217897 -0.0450321 -0.076646 -0.128569 \n    -0.186391 -0.202175 -0.206953 -0.2082 -0.208416 -0.208669 \n    -0.208934 -0.209111 -0.209234 -0.209329 -0.209389 -0.209416 \n    -0.2094 -0.209329 -0.20926 -0.209204 -0.209208 -0.209285 \n    -0.209454 -0.209641 -0.20977 -0.209811 -0.209833 -0.209887 \n    -0.209653 -0.209127 -0.208893 -0.208811 -0.208777 -0.208758 \n    -0.208747 -0.20874 -0.208726 -0.208697 -0.208657 -0.208611 \n    -0.208565 -0.208524 -0.208488 -0.208451 -0.208412 -0.208373 \n    -0.208333 -0.208294 -0.208256 -0.208219 -0.208183 -0.208145 \n    -0.208107 -0.208066 -0.208029 -0.207993 -0.207959 -0.207923 \n    -0.207883 -0.207838 -0.207789 -0.207747 -0.20771 -0.207675 \n    -0.207642 -0.207605 -0.207568 -0.207531 -0.207494 -0.207457 \n    -0.20742 -0.207383 -0.207346 -0.207308 -0.207271 -0.207233 \n    -0.207196 -0.207158 -0.207121 -0.207084 -0.207046 -0.207009 \n    -0.206972 -0.206935 -0.206898 -0.206861 -0.206823 -0.206786 \n    -0.206749 -0.206712 -0.206675 -0.206638 -0.2066 -0.206563 \n    -0.206526 -0.206489 -0.206452 -0.206415 -0.203384 -0.20015 \n    -0.196872 -0.205024 -0.210727 -0.206779 -0.0685263 0.586138 \n    1.4665 2.22945 2.77554 3.076 3.24926 3.34515 3.40164 3.43006 \n    3.43713 3.43075 3.42886 3.4384 3.46567 3.49025 3.51287 3.53821 \n    3.57841 3.39846 2.80753 2.22947 1.7549 1.30429 0.707786 \n    0.303206 0.131352 0.0671706 0.0429955 0.032461 0.0257161 \n    0.0239521 0.0217397 0.0179705 0.0138745 0.0102813 0.00749643 \n    0.0054328 0.00386817 0.0027004 0.00189442 0.00135552 0.000954715 \n    0.000659981 0.000453435 0.000313993 0.000231347 0.000159665 \n    0.000108122 7.10528e-05 4.50233e-05 2.77892e-05 1.62765e-05 \n    8.9893e-06 4.5471e-06 1.54614e-06 -1.6542e-07 -8.68508e-07 \n    -1.04369e-06 -9.63086e-07 -8.44294e-07 -6.57339e-07 -7.35885e-07 \n    -9.80056e-07 -1.39772e-06 -2.10199e-06 -1.37474e-06 6.13269e-07 \n    3.3028e-06 4.60941e-06 4.91053e-06 4.14186e-06 2.45258e-06 \n    -8.7388e-09 -3.59647e-07 -7.10554e-07 -1.06146e-06 -1.41237e-06 \n    -1.76328e-06 -1.63073e-06 -1.34534e-06 -1.05995e-06 -7.74561e-07 \n    -4.8917e-07 -2.95733e-07 -2.16326e-07 -1.3692e-07 -5.75135e-08 \n    2.18929e-08 1.01299e-07 1.80706e-07 2.60112e-07 3.39519e-07 \n    4.18925e-07 4.98332e-07 4.83984e-07 4.4901e-07 4.14035e-07 \n    3.79061e-07 3.44087e-07 3.09112e-07 2.74138e-07 2.39163e-07 \n    2.04189e-07 1.69215e-07 1.26002e-07 4.83213e-08 -2.9359e-08 \n    -1.07039e-07 -1.8472e-07 -2.624e-07 -3.4008e-07 -4.1776e-07 \n    -4.95441e-07 \n    EOD\n\n    @v[26].set(<<-'EOD')\n    7.10441e-10 0.000309731 -0.000308186 -0.001694 -0.00360784 \n    8.40909e-05 0.00203175 0.0012896 0.000596548 0.000277191 \n    0.000161134 0.000120439 8.4915e-05 9.49929e-05 6.18812e-05 \n    1.65433e-05 1.89682e-05 3.97578e-05 4.95446e-05 0.000225325 \n    0.000214579 -0.00230134 -0.000451102 0.00997237 0.0341443 \n    0.0449314 0.0424411 0.0341996 0.0315315 0.0308892 0.0291614 \n    0.024365 0.0190282 0.0188976 0.017238 0.0138526 0.0105645 \n    0.00778548 0.00561753 0.0039871 0.00279554 0.00194075 0.0013468 \n    0.000934775 0.000664723 0.000498911 0.000377384 0.000254183 \n    0.000163421 0.000120773 9.65058e-05 7.22384e-05 5.60316e-05 \n    4.14549e-05 2.79516e-05 2.57096e-05 2.34677e-05 2.12257e-05 \n    1.89837e-05 1.67417e-05 1.46737e-05 1.27228e-05 1.07719e-05 \n    8.82099e-06 6.87009e-06 5.0896e-06 4.71705e-06 4.34451e-06 \n    3.97196e-06 3.59941e-06 3.22686e-06 2.85431e-06 2.48176e-06 \n    2.10921e-06 1.73666e-06 1.36411e-06 1.02855e-06 9.42931e-07 \n    8.57316e-07 7.71701e-07 6.86086e-07 6.00471e-07 5.14856e-07 \n    4.29241e-07 3.43626e-07 2.58011e-07 1.72396e-07 9.85409e-08 \n    9.14091e-08 8.42773e-08 7.71456e-08 7.00138e-08 6.2882e-08 \n    5.57503e-08 4.86185e-08 4.14867e-08 3.4355e-08 2.72232e-08 \n    2.05821e-08 1.63235e-08 1.2065e-08 7.80643e-09 3.54786e-09 \n    -7.10696e-10 -4.96926e-09 -9.22782e-09 -1.34864e-08 -1.77449e-08 \n    -2.20035e-08 -2.62621e-08 -3.05206e-08 -3.47792e-08 -3.90378e-08 \n    -4.32963e-08 -4.75549e-08 -5.18134e-08 -5.6072e-08 -6.03306e-08 \n    -6.45891e-08 -6.88477e-08 -8.76373e-06 0.000131607 -0.00021685 \n    -0.000433027 0.00047234 0.000211593 -0.000189601 3.2492e-05 \n    0.000575955 7.72235e-05 -0.000285172 -0.000242061 -0.000135112 \n    -3.50117e-05 -2.75868e-05 5.48974e-05 1.80604e-07 5.48911e-05 \n    3.97478e-05 0.000192909 0.000297932 0.00402253 -0.0122366 \n    -0.047853 -0.0963082 -0.108071 -0.0567275 -0.0239271 -0.0178628 \n    -0.0233027 -0.031853 -0.0400843 -0.0482725 -0.0576154 -0.0627218 \n    -0.0511236 -0.0279524 -0.0150986 -0.00931091 -0.00652876 \n    -0.00479286 -0.00344346 -0.00249578 -0.0019532 -0.00157977 \n    -0.00131848 -0.00111251 -0.000939229 -0.000797445 -0.000708384 \n    -0.000630452 -0.000539722 -0.000508862 -0.000480596 -0.000439484 \n    -0.000407217 -0.000363866 -0.000329506 -0.000318642 -0.000307362 \n    -0.000286511 -0.000266253 -0.000242943 -0.000218107 -0.000204661 \n    -0.00020241 -0.000194435 -0.000185062 -0.000173042 -0.000160549 \n    -0.000151407 -0.000145626 -0.000145976 -0.000147342 -0.000145288 \n    -0.000137979 -0.000124481 -0.000123218 -0.000127453 -0.000139006 \n    -0.000145486 -0.000129764 -9.82749e-05 -4.72596e-05 -3.08671e-05 \n    -3.28834e-05 -4.52254e-05 -6.25389e-05 -6.32516e-05 -6.39643e-05 \n    -6.4677e-05 -6.53897e-05 -6.61023e-05 -6.6815e-05 -6.75277e-05 \n    -6.61005e-05 -6.45173e-05 -6.29341e-05 -6.13509e-05 -5.97676e-05 \n    -5.81844e-05 -5.66012e-05 -5.54231e-05 -5.4455e-05 -5.3487e-05 \n    -5.25189e-05 -5.15508e-05 -5.05828e-05 -4.96147e-05 -4.86466e-05 \n    -4.76785e-05 -4.67105e-05 -4.57424e-05 -4.47743e-05 -4.38063e-05 \n    -4.28382e-05 -4.18821e-05 -4.10211e-05 -4.016e-05 -3.9299e-05 \n    -3.8438e-05 4.29885e-05 5.14113e-05 -0.000127986 -0.000611463 \n    -0.000149428 0.000882394 0.00297059 -0.00405825 -0.00591067 \n    -0.00546997 -0.00158744 0.00190677 0.00298403 0.00268595 \n    0.00196161 0.00130289 0.000783347 0.000520683 0.000565306 \n    0.00053419 -0.00224696 -0.000920818 0.0132755 0.0322504 \n    0.0442808 0.0638615 0.0701007 0.0539356 0.0247771 0.056244 \n    0.294266 0.831368 1.45424 2.02898 2.54559 2.9937 3.35333 \n    3.72609 4.06363 4.32789 4.52413 4.66504 4.7652 4.83637 4.88631 \n    4.92109 4.94464 4.96046 4.97218 4.98079 4.98679 4.99076 \n    4.99361 4.99555 4.99686 4.99783 4.99853 4.99902 4.99936 \n    4.99959 4.99973 4.99983 4.9999 4.99993 4.99996 4.99998 5 \n    5.00001 5 4.99999 4.99997 4.99994 4.99993 4.99994 4.99996 \n    4.99999 5.00004 5.00006 5.00005 5.00003 5.00002 5.00001 \n    5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    5 5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99998 \n    EOD\n\n    @v[27].set(<<-'EOD')\n    5 4.99984 4.99796 4.99478 4.9889 4.98738 4.98896 4.99087 \n    4.99262 4.99419 4.99552 4.99659 4.99743 4.99807 4.99855 \n    4.9989 4.99894 4.99908 4.99935 5.00001 5.0007 5.00132 5.00032 \n    4.99976 5.00134 5.00339 5.00315 5.00157 5.00091 5.00058 \n    5.00012 4.99944 4.99886 4.9994 4.99934 4.99899 4.99876 4.99868 \n    4.99872 4.99883 4.99898 4.99914 4.9993 4.99944 4.99956 4.99967 \n    4.99976 4.99982 4.99986 4.9999 4.99993 4.99997 4.99997 4.99998 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99999 4.99999 4.99999 4.99999 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5.00009 5.00028 5.00015 4.99983 \n    5.00036 4.99996 4.99834 4.99783 5.00383 5.00734 5.00387 \n    5.00058 4.99893 4.99836 4.99832 4.99854 4.99873 4.99905 \n    4.99927 4.99952 4.99969 4.99834 4.99536 4.99163 4.99073 \n    5.0053 5.03631 5.03103 4.9008 4.62503 4.21887 3.70902 3.09967 \n    2.35791 1.41912 0.519675 0.210458 0.131362 0.0980819 0.0708209 \n    0.0471701 0.0323272 0.0253535 0.0199144 0.0152615 0.0117228 \n    0.00917696 0.00738117 0.00609292 0.00512664 0.00436184 0.0037961 \n    0.00331639 0.00289006 0.0025477 0.00226529 0.00202925 0.00182793 \n    0.00165474 0.00150531 0.00137529 0.00125983 0.00115603 0.00106455 \n    0.000982977 0.000911255 0.000846819 0.000790092 0.000738698 \n    0.000692816 0.00065107 0.000613595 0.000579642 0.000548935 \n    0.00052106 0.000495598 0.000472174 0.000450849 0.000431118 \n    0.000412667 0.000395868 0.000381319 0.000368487 0.000357327 \n    0.000344212 0.000330334 0.00031622 0.000303298 0.000295809 \n    0.00028832 0.000280831 0.000273342 0.000265853 0.000258364 \n    0.000250875 0.000245118 0.000239488 0.000233857 0.000228227 \n    0.000222596 0.000216966 0.000211336 0.000207047 0.000203455 \n    0.000199863 0.00019627 0.000192678 0.000189085 0.000185493 \n    0.0001819 0.000178308 0.000174716 0.000171123 0.000167531 \n    0.000163938 0.000160346 0.000156835 0.000153973 0.00015111 \n    0.000148248 0.000145385 0.000296579 -3.96718e-05 -0.000449085 \n    0.000323433 0.000750086 0.000268264 0.000149028 -0.000100249 \n    7.00956e-05 0.00012605 0.00022592 0.000193036 0.000120453 \n    8.07865e-05 7.65771e-05 -3.27828e-05 0.000116759 0.000169498 \n    0.000409804 0.000414965 0.00092323 -0.00590633 -0.0175477 \n    -0.032433 -0.0559842 -0.0820373 0.0688484 0.626629 1.32929 \n    2.01657 2.60925 3.12329 3.38952 3.14128 2.38463 1.23802 \n    0.316019 0.107832 0.0694707 0.051837 0.035247 0.0209999 \n    0.0116618 0.00967674 0.00789182 0.00574566 0.00386872 0.00258612 \n    0.00167126 0.00104169 0.000641093 0.000401246 0.000277928 \n    0.000171775 0.000102266 5.89376e-05 3.29258e-05 1.80463e-05 \n    1.0057e-05 6.4571e-06 5.10093e-06 4.06791e-06 3.62716e-06 \n    3.63321e-06 3.99625e-06 4.64368e-06 5.20886e-06 4.77728e-06 \n    3.23919e-06 1.14113e-06 -1.29416e-06 -4.15607e-06 -1.88532e-06 \n    5.24411e-06 1.38678e-05 1.28823e-05 3.6758e-06 -2.52285e-06 \n    -3.97133e-06 -4.03071e-06 -3.37154e-06 -2.71238e-06 -2.05321e-06 \n    -1.39404e-06 -7.34872e-07 -3.73325e-07 -1.05873e-07 1.61578e-07 \n    4.2903e-07 6.96482e-07 8.18468e-07 7.60065e-07 7.01662e-07 \n    6.43258e-07 5.84855e-07 5.26452e-07 4.68049e-07 4.09646e-07 \n    3.51243e-07 2.9284e-07 2.34437e-07 1.71213e-07 1.06928e-07 \n    4.2644e-08 -2.16403e-08 -8.59247e-08 -1.50209e-07 -2.14493e-07 \n    -2.78778e-07 -3.43062e-07 -4.07346e-07 -4.55065e-07 -4.3348e-07 \n    -4.11896e-07 -3.90311e-07 -3.68726e-07 -3.47141e-07 -3.25556e-07 \n    -3.03971e-07 -2.82386e-07 \n    EOD\n\n    @v[28].set(<<-'EOD')\n    0.368163 0.361756 0.327463 0.269513 0.149476 0.0805716 0.0501146 \n    0.03403 0.0230886 0.0160474 0.0116071 0.00870013 0.00679614 \n    0.00542384 0.00432512 0.00340653 -0.00129719 -0.00399429 \n    -0.00318719 0.00443085 0.0150156 0.0334147 0.0132288 -0.0189751 \n    -0.0508377 -0.0252174 -0.0142489 -0.00675908 -0.0038653 \n    -0.00243423 -0.00168891 -0.00120901 -0.000900426 -0.000685575 \n    -0.000557595 -0.000457268 -0.000377427 -0.000315269 -0.000266613 \n    -0.000228397 -0.000198283 -0.000174248 -0.000154886 -0.00013892 \n    -0.000125864 -0.000115189 -0.000105841 -9.66611e-05 -8.84262e-05 \n    -8.23872e-05 -7.74668e-05 -7.25463e-05 -6.79992e-05 -6.35276e-05 \n    -5.92413e-05 -5.68994e-05 -5.45574e-05 -5.22154e-05 -4.98735e-05 \n    -4.75315e-05 -4.54981e-05 -4.36726e-05 -4.18471e-05 -4.00216e-05 \n    -3.81961e-05 -3.64559e-05 -3.54209e-05 -3.43858e-05 -3.33508e-05 \n    -3.23157e-05 -3.12807e-05 -3.02456e-05 -2.92105e-05 -2.81755e-05 \n    -2.71404e-05 -2.61054e-05 -2.51232e-05 -2.44984e-05 -2.38736e-05 \n    -2.32487e-05 -2.26239e-05 -2.19991e-05 -2.13742e-05 -2.07494e-05 \n    -2.01246e-05 -1.94998e-05 -1.88749e-05 -1.82865e-05 -1.79044e-05 \n    -1.75224e-05 -1.71403e-05 -1.67582e-05 -1.63762e-05 -1.59941e-05 \n    -1.56121e-05 -1.523e-05 -1.4848e-05 -1.44659e-05 -1.41138e-05 \n    -1.39075e-05 -1.37011e-05 -1.34947e-05 -1.32883e-05 -1.30819e-05 \n    -1.28755e-05 -1.26691e-05 -1.24627e-05 -1.22563e-05 -1.205e-05 \n    -1.18436e-05 -1.16372e-05 -1.14308e-05 -1.12244e-05 -1.1018e-05 \n    -1.08116e-05 -1.06052e-05 -1.03988e-05 -1.01924e-05 -9.98605e-06 \n    -9.77966e-06 -2.85319e-05 0.00281092 0.00180106 -0.000981083 \n    0.00551926 -0.00119763 -0.0295069 -0.0367677 0.064749 0.119022 \n    0.0882007 0.0552062 0.03418 0.0223243 0.015545 0.011949 \n    0.00757134 0.00667655 0.00583243 0.00644443 0.00650959 -0.0302575 \n    -0.0437806 -0.0355466 0.0381776 0.282109 0.674178 1.07582 \n    1.45189 1.789 2.08649 2.34663 2.57245 2.81211 3.04778 3.2523 \n    3.45877 3.65593 3.83396 3.9923 4.13368 4.25864 4.36719 4.46064 \n    4.54086 4.60962 4.66835 4.71838 4.76094 4.79716 4.82796 \n    4.85413 4.87634 4.89518 4.91116 4.92476 4.93631 4.94608 \n    4.95434 4.9613 4.96715 4.97211 4.97638 4.98001 4.98312 4.98571 \n    4.98795 4.98979 4.99138 4.99269 4.99381 4.99474 4.99551 \n    4.99615 4.99668 4.99713 4.99752 4.99783 4.99811 4.99836 \n    4.99858 4.99873 4.99884 4.99892 4.999 4.99907 4.99912 4.99916 \n    4.99921 4.99926 4.99932 4.99937 4.99942 4.99948 4.99953 \n    4.99956 4.99958 4.99961 4.99963 4.99966 4.99968 4.99971 \n    4.99972 4.99973 4.99974 4.99975 4.99976 4.99977 4.99978 \n    4.99979 4.9998 4.9998 4.99981 4.99982 4.99983 4.99984 4.99985 \n    4.99986 4.99986 4.99987 4.99987 5.00498 5.00354 4.99359 \n    4.98981 5.00498 5.00099 5.00041 5.00022 5.00015 5.00012 \n    5.0001 5.00008 5.00005 5.00003 5 4.99431 4.99459 4.99591 \n    5.00087 5.01029 5.03935 4.92784 4.51643 3.78356 2.68745 \n    1.43417 0.583128 0.205094 0.0777337 0.0391566 0.02723 0.023883 \n    0.018808 0.010165 0.00254623 -0.00377463 -0.0038097 0.00144145 \n    0.00267231 0.00193045 0.00144538 0.00121758 0.00112893 0.00109424 \n    0.0010226 0.000948072 0.000882573 0.000826996 0.000776391 \n    0.000729719 0.000686499 0.000647333 0.000610108 0.000575631 \n    0.000545069 0.000515485 0.000488514 0.000465316 0.000443215 \n    0.000422454 0.00040292 0.00038488 0.000368472 0.000353628 \n    0.000339643 0.000326197 0.000313483 0.000302884 0.000294038 \n    0.000284003 0.000270941 0.000254925 0.000246511 0.000244089 \n    0.000245538 0.000242099 0.000235728 0.000227482 0.000218001 \n    0.000207257 0.000202127 0.000196997 0.000191868 0.000186738 \n    0.000181608 0.00017758 0.000173899 0.000170219 0.000166538 \n    0.000162857 0.000159576 0.00015679 0.000154005 0.000151219 \n    0.000148433 0.000145647 0.000142861 0.000140076 0.00013729 \n    0.000134504 0.000131718 0.000129603 0.000127635 0.000125668 \n    0.0001237 0.000121732 0.000119765 0.000117797 0.000115829 \n    0.000113862 0.000111894 0.000109993 0.000108372 0.000106751 \n    0.00010513 0.000103509 0.000101887 0.000100266 9.86449e-05 \n    9.70237e-05 \n    EOD\n\n    @v[29].set(<<-'EOD')\n    5 4.99899 4.99654 4.99327 4.9863 4.98954 4.99212 4.99378 \n    4.9951 4.99624 4.99715 4.99786 4.99839 4.99879 4.99909 4.99931 \n    4.99922 4.99933 4.99971 5.00064 5.00084 5.00123 4.99865 \n    4.99853 4.99983 5.00457 5.00242 5.00105 5.00062 5.00042 \n    4.99971 4.9994 4.9992 4.9996 4.99955 4.99932 4.99918 4.99915 \n    4.99919 4.99927 4.99937 4.99948 4.99957 4.99966 4.99974 \n    4.9998 4.99985 4.99989 4.99992 4.99993 4.99994 4.99994 4.99996 \n    4.99998 5 5 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 \n    5.00001 5.00001 5 5 5 5 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99998 4.99998 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 \n    5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5 5 5 5 5 5 4.9997 4.99998 4.99954 4.99963 \n    5.00059 4.99945 4.99732 4.99957 5.00919 5.00558 5.00033 \n    4.99851 4.9983 4.99854 4.99871 4.99928 4.99914 4.99939 4.99952 \n    4.9998 4.99976 4.99744 4.99598 4.99478 4.99806 5.01911 5.04602 \n    5.05469 5.01317 4.89484 4.69655 4.42036 4.06069 3.60793 \n    3.12531 2.72975 2.45187 2.25081 2.09841 1.98509 1.90211 \n    1.84084 1.79411 1.7574 1.72763 1.70283 1.68188 1.66389 1.64823 \n    1.63438 1.62201 1.61088 1.60081 1.59163 1.58323 1.57549 \n    1.56835 1.56173 1.55558 1.54985 1.54451 1.53951 1.53479 \n    1.53035 1.52615 1.5222 1.51845 1.5149 1.51153 1.50834 1.50529 \n    1.5024 1.49964 1.497 1.49449 1.49208 1.48977 1.48755 1.48542 \n    1.48336 1.48138 1.47948 1.47765 1.4759 1.47419 1.47255 1.47096 \n    1.46949 1.46823 1.46696 1.4657 1.46444 1.46317 1.46191 1.46065 \n    1.45956 1.4585 1.45743 1.45636 1.45529 1.45422 1.45315 1.45226 \n    1.45145 1.45064 1.44983 1.44902 1.44821 1.4474 1.44659 1.44579 \n    1.44498 1.44417 1.44336 1.44255 1.44174 1.44094 1.44019 \n    1.43944 1.43868 1.43793 1.43765 1.43679 1.43515 1.43405 \n    1.43478 1.43387 1.43345 1.43184 1.43086 1.43021 1.43003 \n    1.42988 1.42944 1.42883 1.42818 1.42702 1.42642 1.42595 \n    1.42586 1.42616 1.42783 1.41733 1.38106 1.30738 1.3877 2.09819 \n    3.05285 3.58059 3.77601 3.87609 4.02557 4.24887 4.4608 4.60411 \n    4.72109 4.8255 4.90465 4.97379 5.01253 5.01532 5.01239 5.0092 \n    5.00665 5.00474 5.00333 5.00232 5.00163 5.00117 5.00082 \n    5.00057 5.00039 5.00027 5.00019 5.00013 5.00009 5.00006 \n    5.00004 5.00003 5.00002 5.00001 5.00001 5 5 5 4.99998 4.99995 \n    4.99992 4.99996 5.00005 5.00012 5.00008 4.99996 4.9999 4.99985 \n    4.99986 4.99997 5.00021 5.0003 5.00024 5.00009 5.00007 5.00005 \n    5.00003 5.00001 4.99998 4.99998 4.99998 4.99999 4.99999 \n    5 5 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00002 5.00002 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99998 \n    4.99998 4.99998 \n    EOD\n\n    @v[30].set(<<-'EOD')\n    7.10441e-10 5.70385e-05 0.000226143 0.000131916 -0.000887764 \n    -8.01837e-05 -3.49653e-05 9.40039e-05 0.000118663 0.000108025 \n    8.6059e-05 6.33268e-05 4.99295e-05 3.16843e-05 3.60692e-05 \n    2.07572e-05 -8.6375e-05 3.44583e-05 8.07397e-05 0.000196296 \n    0.000115615 -7.12768e-05 -0.000129812 -4.18679e-05 7.94364e-05 \n    0.000182034 -5.41226e-05 -0.000451819 -0.000713937 -0.00129863 \n    -0.00262186 -0.00213417 -0.00133767 0.000775698 0.000969902 \n    0.000549281 0.000280946 0.000140321 8.6919e-05 7.22446e-05 \n    6.5631e-05 6.45263e-05 6.63087e-05 7.17391e-05 7.59042e-05 \n    7.59172e-05 7.03353e-05 6.33558e-05 5.31136e-05 4.64278e-05 \n    4.40594e-05 4.16909e-05 4.05674e-05 3.96957e-05 3.87875e-05 \n    3.74977e-05 3.62079e-05 3.49181e-05 3.36283e-05 3.23385e-05 \n    3.12427e-05 3.02775e-05 2.93124e-05 2.83472e-05 2.7382e-05 \n    2.64613e-05 2.59077e-05 2.5354e-05 2.48004e-05 2.42468e-05 \n    2.36931e-05 2.31395e-05 2.25859e-05 2.20322e-05 2.14786e-05 \n    2.0925e-05 2.03916e-05 1.9995e-05 1.95984e-05 1.92019e-05 \n    1.88053e-05 1.84087e-05 1.80122e-05 1.76156e-05 1.7219e-05 \n    1.68225e-05 1.64259e-05 1.6051e-05 1.57991e-05 1.55471e-05 \n    1.52952e-05 1.50433e-05 1.47913e-05 1.45394e-05 1.42875e-05 \n    1.40356e-05 1.37836e-05 1.35317e-05 1.32978e-05 1.31513e-05 \n    1.30048e-05 1.28583e-05 1.27118e-05 1.25653e-05 1.24188e-05 \n    1.22724e-05 1.21259e-05 1.19794e-05 1.18329e-05 1.16864e-05 \n    1.15399e-05 1.13934e-05 1.12469e-05 1.11005e-05 1.0954e-05 \n    1.08075e-05 1.0661e-05 1.05145e-05 1.0368e-05 1.02215e-05 \n    1.76447e-05 7.21516e-05 -3.59786e-05 -0.000159618 0.000156236 \n    0.000135106 -0.000336402 -0.000302283 0.000699323 0.000473866 \n    -0.000156146 -0.000225625 -0.000123592 -3.78116e-05 8.47472e-06 \n    2.43387e-06 -7.44762e-05 7.80111e-05 9.43608e-05 0.000170159 \n    8.83919e-05 -0.00018802 -0.000373512 -0.000390597 0.000156875 \n    0.0032343 0.00776304 -0.000566905 -0.00760695 -0.0159226 \n    -0.0245989 -0.0331402 -0.0100902 0.067837 0.266702 0.910818 \n    1.82282 2.69714 3.43247 3.98325 4.32893 4.51529 4.67087 \n    4.79288 4.87574 4.92797 4.95902 4.97655 4.98622 4.99195 \n    4.99526 4.99735 4.9991 4.99974 4.99982 4.99974 4.99961 4.9995 \n    4.99943 4.9994 4.9994 4.99942 4.99944 4.99948 4.99952 4.99956 \n    4.99961 4.99965 4.9997 4.99974 4.99977 4.99981 4.99983 4.99986 \n    4.99988 4.9999 4.99991 4.99992 4.99993 4.99994 4.99995 4.99995 \n    4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 4.99999 \n    4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 5 \n    5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 5 5.00019 4.99888 4.99663 4.99457 4.99902 \n    5.00229 5.00323 5.00302 5.0023 5.0015 5.00085 5.00041 5.00013 \n    4.99993 4.99979 4.99948 4.99954 4.99983 5.00055 5.00109 \n    5.00009 4.9987 4.998 4.99755 4.99676 4.99618 5.01091 5.05272 \n    5.04156 4.80112 4.27692 3.42343 2.23953 0.967179 0.429813 \n    0.540757 1.32991 2.32147 3.14903 3.78143 4.22325 4.47978 \n    4.59448 4.69875 4.79798 4.87419 4.92339 4.95249 4.97174 \n    4.98408 4.99124 4.99478 4.99729 4.99868 4.9992 4.99941 4.99947 \n    4.99946 4.99943 4.9994 4.99939 4.9994 4.99942 4.99946 4.99951 \n    4.99956 4.99961 4.99967 4.99973 4.99977 4.9998 4.99981 4.99983 \n    4.99984 4.99987 4.99992 5.00001 5.00005 5.00001 4.99994 \n    4.99995 4.99995 4.99996 4.99996 4.99996 4.99997 4.99997 \n    4.99997 4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 \n    4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 \n    4.99998 4.99998 4.99998 \n    EOD\n\n    @v[31].set(<<-'EOD')\n    1.8179e-09 -5.28841e-06 -1.44913e-05 -3.62932e-05 -9.75719e-05 \n    0.000141781 3.73396e-05 -1.65603e-05 -1.5271e-05 -6.73884e-06 \n    4.40157e-06 -4.85345e-06 -1.02964e-05 2.03126e-05 -1.89457e-05 \n    -8.75564e-06 7.67422e-06 4.71103e-06 1.29798e-05 6.13469e-06 \n    -1.14363e-05 -0.0394563 -0.0477298 -0.0622012 -0.0519225 \n    0.262499 0.943611 1.67052 2.31017 2.84028 3.28467 3.61582 \n    3.85887 4.13011 4.36511 4.54063 4.67013 4.76408 4.83263 \n    4.8825 4.91837 4.94373 4.96117 4.97318 4.98093 4.98562 4.98906 \n    4.99267 4.99539 4.99666 4.99731 4.99797 4.99844 4.99887 \n    4.99927 4.99933 4.99938 4.99944 4.99949 4.99955 4.9996 4.99965 \n    4.9997 4.99975 4.9998 4.99985 4.99986 4.99987 4.99989 4.9999 \n    4.99991 4.99992 4.99993 4.99995 4.99996 4.99997 4.99998 \n    4.99998 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 \n    5.00001 5.00001 5 5 5 5 5 5 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99997 5.00002 5.00004 5.0001 5.0001 4.99987 5.00009 \n    5.00021 5.00002 5.00004 4.99988 5.00013 4.99993 5.00026 \n    4.99973 5 5.00006 5.00009 5.00004 5.00004 5.04854 4.82711 \n    4.04208 2.64155 0.838902 0.19014 0.0982549 0.0723197 0.0576863 \n    0.0427644 0.0301979 0.020146 0.0135728 0.00980358 0.00774482 \n    0.00586604 0.0036687 0.00211511 0.00121906 0.000647581 0.000828436 \n    0.00190938 0.00224254 0.00199956 0.00165488 0.00135612 0.00113715 \n    0.000984181 0.000877175 0.000789973 0.000741139 0.000689338 \n    0.000625676 0.000586082 0.000550152 0.000529573 0.000505606 \n    0.000482117 0.000460574 0.000441649 0.000424674 0.000408398 \n    0.000391914 0.000376272 0.000361487 0.000348181 0.000336045 \n    0.000324466 0.000313545 0.000303046 0.000293056 0.00028356 \n    0.000274586 0.000266155 0.000258279 0.000250938 0.000243789 \n    0.000236912 0.000230244 0.000224186 0.000219291 0.000215346 \n    0.000212468 0.000207291 0.000200862 0.00019368 0.000186767 \n    0.000183515 0.000180263 0.00017701 0.000173758 0.000170506 \n    0.000167253 0.000164001 0.000161164 0.000158357 0.00015555 \n    0.000152743 0.000149936 0.000147129 0.000144322 0.000142066 \n    0.000140096 0.000138127 0.000136157 0.000134187 0.000132218 \n    0.000130248 0.000128278 0.000126308 0.000124339 0.000122369 \n    0.000120399 0.000118429 0.00011646 0.000114527 0.000112892 \n    0.000111258 0.000109623 0.000107988 0.000103598 6.86052e-05 \n    3.337e-05 7.00783e-05 0.000218764 0.000221318 0.000118593 \n    -0.000113962 5.78552e-05 9.42068e-05 0.000237037 0.000171302 \n    0.0001033 6.16066e-05 5.52908e-05 6.30233e-05 7.01897e-05 \n    8.48573e-05 0.000106859 8.37213e-05 -0.0391541 -0.047722 \n    -0.0618454 -0.0169804 0.345725 1.03426 1.74825 2.37152 2.88737 \n    3.32173 3.66761 3.9707 4.17762 3.98832 3.30483 2.09737 0.710892 \n    0.148159 0.0707463 0.0555808 0.045618 0.0319116 0.0199589 \n    0.0133357 0.00898528 0.00586075 0.00375478 0.00245443 0.00156038 \n    0.000962344 0.000590953 0.000375107 0.000250243 0.00015882 \n    0.000100203 6.18122e-05 3.7372e-05 2.23009e-05 1.32569e-05 \n    8.29437e-06 5.72457e-06 3.96832e-06 2.98935e-06 2.59699e-06 \n    2.75024e-06 3.38689e-06 4.0453e-06 3.50095e-06 1.64988e-06 \n    -3.84371e-07 -2.03828e-06 -3.46401e-06 -1.24301e-06 4.63458e-06 \n    1.14104e-05 1.02619e-05 2.15487e-06 -2.98487e-06 -3.67221e-06 \n    -2.94279e-06 -2.58649e-06 -2.23019e-06 -1.87389e-06 -1.5176e-06 \n    -1.1613e-06 -7.92127e-07 -4.18889e-07 -4.56502e-08 3.27588e-07 \n    7.00827e-07 8.79539e-07 8.17025e-07 7.5451e-07 6.91996e-07 \n    6.29481e-07 5.66966e-07 5.04452e-07 4.41937e-07 3.79422e-07 \n    3.16908e-07 2.54393e-07 1.90078e-07 1.25366e-07 6.0654e-08 \n    -4.05776e-09 -6.87696e-08 -1.33481e-07 -1.98193e-07 -2.62905e-07 \n    -3.27617e-07 -3.92329e-07 -4.40392e-07 -4.18802e-07 -3.97213e-07 \n    -3.75624e-07 -3.54035e-07 -3.32446e-07 -3.10856e-07 -2.89267e-07 \n    -2.67678e-07 \n    EOD\n\n    @v[32].set(<<-'EOD')\n    1.10294 1.10297 1.10291 1.10277 1.10259 1.10294 1.10313 \n    1.10306 1.10299 1.10296 1.10295 1.10295 1.10294 1.10294 \n    1.10294 1.10294 1.10294 1.10294 1.10294 1.10296 1.10296 \n    1.00547 0.998599 1.5201 2.49297 3.31258 3.73162 3.84757 \n    3.92505 4.02965 4.16599 4.30294 4.41541 4.52886 4.64414 \n    4.73865 4.81065 4.86391 4.90315 4.93188 4.95258 4.96726 \n    4.97738 4.98436 4.98888 4.99162 4.99363 4.99573 4.99731 \n    4.99804 4.99843 4.99881 4.99909 4.99934 4.99957 4.9996 4.99964 \n    4.99967 4.9997 4.99973 4.99977 4.9998 4.99983 4.99986 4.99988 \n    4.99991 4.99992 4.99992 4.99993 4.99994 4.99994 4.99995 \n    4.99996 4.99996 4.99997 4.99997 4.99998 4.99998 4.99999 \n    4.99999 4.99999 4.99999 5 5 5 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 5.00028 4.99988 4.99968 \n    5.00019 4.99987 5.00021 4.99973 4.99977 4.99996 4.99997 \n    5.0002 4.99957 5.00026 4.99947 5.00074 5.00003 4.99987 4.99979 \n    5.00008 4.99997 5.08794 5.05993 4.76875 3.99197 3.10174 \n    2.5197 2.21771 2.04 1.92235 1.83874 1.77592 1.72665 1.686 \n    1.65276 1.6286 1.61299 1.60039 1.58934 1.57954 1.57083 1.56306 \n    1.55604 1.54963 1.54375 1.53832 1.53331 1.52865 1.52432 \n    1.52026 1.51645 1.51287 1.50949 1.50629 1.50327 1.50039 \n    1.49766 1.49505 1.49257 1.49019 1.48792 1.48574 1.48365 \n    1.48164 1.47971 1.47784 1.47604 1.47431 1.47264 1.47102 \n    1.46945 1.46794 1.46647 1.46505 1.46367 1.46233 1.46103 \n    1.45976 1.45853 1.45733 1.45616 1.45502 1.45392 1.45284 \n    1.45179 1.45076 1.44975 1.4488 1.44795 1.44711 1.44626 1.44541 \n    1.44457 1.44372 1.44287 1.44212 1.44138 1.44063 1.43989 \n    1.43914 1.4384 1.43766 1.43701 1.43641 1.43581 1.43522 1.43462 \n    1.43402 1.43342 1.43282 1.43223 1.43163 1.43103 1.43043 \n    1.42984 1.42924 1.42865 1.42808 1.42752 1.42695 1.42639 \n    1.42584 1.42529 1.42472 1.42412 1.42365 1.42326 1.42304 \n    1.42162 1.42082 1.42032 1.42029 1.42026 1.41995 1.41947 \n    1.41894 1.41841 1.4179 1.41742 1.41699 1.41656 1.32097 1.30963 \n    1.78765 2.64656 3.35764 3.747 3.86589 3.94217 4.04185 4.18453 \n    4.3561 4.53439 4.68621 4.74905 4.77848 4.84629 4.91261 4.97541 \n    5.01284 5.01548 5.01248 5.00924 5.00666 5.00475 5.00334 \n    5.00234 5.00164 5.00118 5.00083 5.00058 5.0004 5.00028 5.00019 \n    5.00013 5.00009 5.00007 5.00004 5.00003 5.00002 5.00001 \n    5.00001 5.00001 5 5 4.99999 4.99995 4.99992 4.99996 5.00006 \n    5.00012 5.00009 4.99997 4.9999 4.99985 4.99986 4.99997 5.00021 \n    5.00031 5.00024 5.0001 5.00007 5.00005 5.00003 5.00001 4.99998 \n    4.99998 4.99999 4.99999 4.99999 5 5 5 5 5 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00002 5.00002 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 \n    5 4.99999 4.99999 4.99999 4.99998 4.99998 4.99998 \n    EOD\n\n    @v[33].set(<<-'EOD')\n    5 5.00012 5.00023 5.0003 4.99972 4.99988 4.99984 4.99991 \n    4.99996 4.99999 5.00008 5.00009 4.99986 5.00003 5.00007 \n    4.99995 4.9999 4.99997 5.00013 5.00014 5.00013 4.99701 4.99763 \n    4.99742 4.99998 5.02836 5.07262 4.96856 4.57267 3.85637 \n    2.79544 1.45942 0.408016 0.084885 0.0271375 0.0119294 0.00707546 \n    0.0051087 0.00373035 0.00264737 0.00186477 0.00130379 0.000915857 \n    0.000653121 0.000483893 0.000380852 0.000302362 0.000219498 \n    0.000154435 0.000121928 0.000104026 8.61242e-05 7.48526e-05 \n    6.49216e-05 5.56238e-05 5.29689e-05 5.03139e-05 4.7659e-05 \n    4.5004e-05 4.23491e-05 4.00356e-05 3.79522e-05 3.58687e-05 \n    3.37852e-05 3.17018e-05 2.97592e-05 2.89804e-05 2.82016e-05 \n    2.74228e-05 2.66441e-05 2.58653e-05 2.50865e-05 2.43077e-05 \n    2.35289e-05 2.27501e-05 2.19714e-05 2.12346e-05 2.07821e-05 \n    2.03295e-05 1.98769e-05 1.94244e-05 1.89718e-05 1.85192e-05 \n    1.80667e-05 1.76141e-05 1.71615e-05 1.6709e-05 1.62828e-05 \n    1.60061e-05 1.57294e-05 1.54527e-05 1.5176e-05 1.48993e-05 \n    1.46226e-05 1.43459e-05 1.40692e-05 1.37925e-05 1.35158e-05 \n    1.3262e-05 1.31191e-05 1.29761e-05 1.28332e-05 1.26903e-05 \n    1.25474e-05 1.24045e-05 1.22615e-05 1.21186e-05 1.19757e-05 \n    1.18328e-05 1.16898e-05 1.15469e-05 1.1404e-05 1.12611e-05 \n    1.11182e-05 1.09752e-05 1.08323e-05 1.06894e-05 1.05465e-05 \n    1.04036e-05 1.02606e-05 1.00185e-05 3.8343e-05 -3.06781e-05 \n    -0.000111758 0.000111673 0.000130815 -0.000210491 -0.000231304 \n    0.000310226 0.000265303 3.0878e-05 -4.48405e-05 -1.2852e-05 \n    -7.84469e-06 3.29986e-05 -1.23286e-05 -6.07871e-05 5.35082e-05 \n    7.69194e-05 0.000126221 6.57178e-05 0.00223349 -0.0148854 \n    -0.0476636 -0.0491447 0.220125 1.11174 2.03988 2.90209 3.61069 \n    4.13554 4.50679 4.71501 4.83916 4.91027 4.95284 4.98086 \n    4.99151 4.98651 4.97113 4.95075 4.93102 4.93683 4.95457 \n    4.97071 4.98212 4.98948 4.99386 4.99636 4.99785 4.9987 4.99927 \n    4.99989 5.00014 5.00007 4.99988 4.99982 4.99976 4.99973 \n    4.99972 4.99972 4.99973 4.99974 4.99975 4.99977 4.99979 \n    4.99981 4.99984 4.99986 4.99988 4.99989 4.99991 4.99992 \n    4.99993 4.99994 4.99995 4.99996 4.99996 4.99997 4.99997 \n    4.99998 4.99998 4.99998 4.99998 4.99999 4.99999 4.99999 \n    4.99999 5 5 5 5.00001 5.00001 5.00001 5.00002 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5 5 5 5 5 5 5 5 4.99999 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 4.99999 \n    4.99999 4.99999 4.99999 5 5.00012 4.99946 4.99839 4.99733 \n    4.99948 5.00114 5.00158 5.00147 5.00113 5.00073 5.00043 \n    5.0002 5.00006 4.99995 4.99986 4.99973 4.99976 4.9999 5.00029 \n    5.00055 4.99704 4.99734 4.9972 5.00278 5.03354 5.07184 4.94057 \n    4.51936 3.75638 2.60982 1.23803 0.315016 0.0796102 0.0252894 \n    0.0165723 0.0827785 0.491298 1.40686 2.33436 3.1251 3.7691 \n    4.22201 4.49976 4.68115 4.80513 4.88509 4.93208 4.95861 \n    4.97579 4.98655 4.99268 4.99571 4.99771 4.99881 4.99929 \n    4.99954 4.99965 4.9997 4.99971 4.99971 4.99971 4.99971 4.99972 \n    4.99974 4.99976 4.99978 4.99981 4.99984 4.99987 4.99989 \n    4.99991 4.99991 4.99992 4.99992 4.99993 4.99997 5.00003 \n    5.00006 5.00004 5.00001 5 4.99999 4.99998 4.99998 4.99997 \n    4.99997 4.99997 4.99998 4.99998 4.99998 4.99999 4.99999 \n    4.99999 4.99999 5 5 5 5 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5 5 5 5 5 5 5 4.99999 \n    4.99999 4.99999 4.99999 4.99998 4.99998 \n    EOD\n\n    @v[34].set(<<-'EOD')\n    5 5.00207 5.00813 5.01486 5.00156 5.0018 4.99861 4.99844 \n    4.99888 4.9993 4.99956 4.99971 4.99979 4.99983 4.99987 4.99989 \n    4.99671 4.9974 4.99864 5.00131 5.00377 5.0021 5.00039 4.99993 \n    5.00004 5.0009 5.00109 4.99636 4.98617 4.96778 4.92047 4.89528 \n    4.91112 4.9559 4.98286 4.99369 4.99812 4.99951 4.99994 5.00014 \n    5.00008 4.99994 4.99984 4.99989 4.99998 5.00004 5.00004 \n    5.00006 5.00005 5.00001 4.99997 4.99992 4.99993 4.99994 \n    4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 \n    4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 4.99996 \n    4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 \n    4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 \n    4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 4.99997 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 \n    4.99998 4.99998 4.99998 4.99998 5.00131 5.00072 4.9977 4.99811 \n    5.00325 4.99647 4.98948 4.99459 5.00262 5.00276 5.00156 \n    5.00072 5.0003 5.00013 4.99995 4.99668 4.99775 4.99917 5.00173 \n    5.00386 5.00188 4.99888 4.99757 4.99951 5.01712 5.0557 5.07088 \n    5.07704 5.07758 5.06958 5.04223 5.03331 5.0279 5.03408 5.07611 \n    5.01911 4.68594 3.99152 2.92195 1.69878 0.809 0.344091 0.154663 \n    0.0788717 0.0467212 0.0336168 0.0280514 0.0254947 0.024173 \n    0.0223567 0.0220555 0.0271514 0.0295872 0.0296052 0.0283971 \n    0.0264726 0.0241813 0.0218244 0.0195349 0.017368 0.0152495 \n    0.013295 0.0115444 0.00996982 0.00857091 0.00733891 0.00627261 \n    0.0053494 0.00456316 0.00388373 0.00331073 0.00282181 0.00240991 \n    0.00206389 0.00177187 0.00152283 0.00131167 0.00112558 0.000954373 \n    0.000805726 0.00069326 0.000600991 0.000525743 0.00047355 \n    0.00044359 0.000434815 0.000436053 0.000402511 0.000368969 \n    0.000335427 0.000301886 0.000268344 0.000234802 0.00020126 \n    0.000184967 0.000169932 0.000154896 0.000139861 0.000124825 \n    0.00010979 9.47546e-05 8.67896e-05 8.24901e-05 7.81906e-05 \n    7.38911e-05 6.95915e-05 6.5292e-05 6.09925e-05 5.66929e-05 \n    5.23934e-05 4.80939e-05 4.37943e-05 3.94948e-05 3.51953e-05 \n    3.08957e-05 2.67968e-05 2.42936e-05 2.17904e-05 1.92872e-05 \n    1.6784e-05 0.00125927 -0.00794344 -0.0305499 -0.0621697 \n    -0.0463796 -0.0224608 -0.00538381 0.00546086 0.0108675 0.012883 \n    0.0131787 0.0127271 0.0119702 0.0110398 0.0100635 0.00649617 \n    0.00489388 0.00545863 0.0098351 0.0167428 0.0126563 0.00697542 \n    0.00427027 0.00330002 0.00390774 0.00408999 -0.00259143 \n    -0.0160578 -0.0451849 -0.0409651 0.1301 0.597429 1.3848 \n    2.63426 3.81272 4.51373 4.8412 4.98731 4.88165 4.37165 3.40034 \n    2.17681 1.12217 0.505129 0.219703 0.104992 0.0622333 0.0448317 \n    0.0355782 0.0311867 0.0293529 0.0274615 0.0288739 0.0307845 \n    0.0304909 0.029245 0.0273602 0.0251006 0.022697 0.0202765 \n    0.0179357 0.0157106 0.0136562 0.0117951 0.0101273 0.00865784 \n    0.00739394 0.00634364 0.00551356 0.00480538 0.00415747 0.00356084 \n    0.00297585 0.00236711 0.00181853 0.00160713 0.00169822 0.00166542 \n    0.00145504 0.00120252 0.00109259 0.000982658 0.00087273 \n    0.000762802 0.000652874 0.000584068 0.000528263 0.000472458 \n    0.000416653 0.000360848 0.000321155 0.000301442 0.000281729 \n    0.000262016 0.000242303 0.00022259 0.000202877 0.000183164 \n    0.000163451 0.000143738 0.000124025 0.000114582 0.000107399 \n    0.000100216 9.30332e-05 8.58502e-05 7.86672e-05 7.14841e-05 \n    6.43011e-05 5.7118e-05 4.9935e-05 4.35378e-05 4.04281e-05 \n    3.73184e-05 3.42088e-05 3.10991e-05 2.79894e-05 2.48798e-05 \n    2.17701e-05 1.86604e-05 \n    EOD\n\n    @v[35].set(<<-'EOD')\n    7.24585e-12 2.21843e-05 3.20014e-05 1.25076e-05 -2.44947e-05 \n    1.8425e-05 5.50546e-06 3.53025e-05 -1.07551e-05 -3.94383e-06 \n    -2.27848e-06 -9.04789e-05 7.44215e-05 -2.7662e-05 0.000200038 \n    -2.11998e-05 -2.09011e-05 2.37098e-05 2.18751e-05 -2.28422e-05 \n    -6.23659e-05 3.58241e-05 1.76386e-05 -4.28311e-05 0.000355626 \n    0.00156903 0.00100999 -0.0085304 -0.02067 -0.0389485 -0.0651568 \n    -0.128475 -0.314362 -0.406837 -0.421558 -0.421277 -0.418176 \n    -0.414481 -0.410845 -0.407348 -0.403971 -0.400716 -0.397582 \n    -0.394563 -0.391658 -0.388866 -0.386178 -0.383585 -0.381094 \n    -0.378789 -0.376569 -0.37435 -0.372256 -0.370188 -0.36815 \n    -0.366422 -0.364694 -0.362967 -0.361239 -0.359511 -0.357888 \n    -0.356334 -0.354781 -0.353227 -0.351674 -0.350152 -0.348888 \n    -0.347625 -0.346361 -0.345098 -0.343834 -0.342571 -0.341307 \n    -0.340044 -0.33878 -0.337517 -0.336279 -0.335215 -0.334152 \n    -0.333088 -0.332024 -0.330961 -0.329897 -0.328833 -0.32777 \n    -0.326706 -0.325642 -0.324601 -0.323683 -0.322766 -0.321849 \n    -0.320932 -0.320014 -0.319097 -0.31818 -0.317263 -0.316345 \n    -0.315428 -0.314545 -0.313825 -0.313106 -0.312387 -0.311667 \n    -0.310948 -0.310228 -0.309509 -0.308789 -0.30807 -0.307351 \n    -0.306631 -0.305912 -0.305192 -0.304473 -0.303754 -0.303034 \n    -0.302315 -0.301595 -0.300876 -0.300157 -0.299437 -0.298716 \n    -0.29798 -0.297329 -0.296691 -0.295837 -0.29516 -0.294725 \n    -0.294044 -0.292917 -0.292351 -0.291965 -0.291365 -0.290687 \n    -0.290027 -0.289376 -0.288772 -0.288193 -0.287505 -0.286892 \n    -0.28626 -0.285714 -0.284545 -0.289246 -0.298717 -0.298492 \n    -0.214163 0.181451 0.0749974 0.0454707 0.0292987 0.0196837 \n    0.0124119 0.00884715 0.00527181 0.00585821 0.0296361 0.169856 \n    0.361207 0.538856 0.67469 0.685933 0.392802 0.17772 0.0813085 \n    0.0424601 0.0246654 0.0175258 0.0144256 0.0129859 0.012205 \n    0.0112846 0.010933 0.0134813 0.0147254 0.0147981 0.0142156 \n    0.0132732 0.0121355 0.0109587 0.00981238 0.00872731 0.00767007 \n    0.00669346 0.00581341 0.00502167 0.00431819 0.00369842 0.00316168 \n    0.00269663 0.00230035 0.00195801 0.00166928 0.00142286 0.00121522 \n    0.00104072 0.000893384 0.000767675 0.000661268 0.000567659 \n    0.000481766 0.000407101 0.000350044 0.000302721 0.000263424 \n    0.000236813 0.00022199 0.000218182 0.000219548 0.0002027 \n    0.000185853 0.000169006 0.000152158 0.000135311 0.000118463 \n    0.000101616 9.33782e-05 8.57685e-05 7.81588e-05 7.0549e-05 \n    6.29393e-05 5.53296e-05 4.77199e-05 4.36954e-05 4.15296e-05 \n    3.93637e-05 3.71978e-05 3.50319e-05 3.28661e-05 3.07002e-05 \n    2.85343e-05 2.63685e-05 2.42026e-05 2.20367e-05 1.98709e-05 \n    1.7705e-05 1.55391e-05 1.34772e-05 1.22416e-05 1.10061e-05 \n    9.77055e-06 8.535e-06 0.000631271 -0.00362586 -0.0146235 \n    -0.0308486 -0.0237466 -0.0117522 -0.00304171 0.00251033 \n    0.00531986 0.0063897 0.00657351 0.00636494 0.00599705 0.00553442 \n    0.00505994 0.00330925 0.00246671 0.0027006 0.00473161 0.00830333 \n    0.00649147 0.00356815 0.00217448 0.00187579 0.00270447 0.00219543 \n    -0.00546118 -0.0179576 -0.0445306 -0.0649309 0.0197935 0.473629 \n    0.87268 0.269542 0.0086094 0.0844602 0.606456 1.04929 0.906014 \n    0.916205 0.919425 0.872867 0.556244 0.262457 0.11838 0.0571226 \n    0.0333451 0.0237133 0.0185096 0.0159617 0.0148663 0.0138683 \n    0.0144081 0.0153797 0.0152551 0.0146487 0.0137192 0.0125973 \n    0.0113996 0.0101903 0.00901851 0.00790495 0.00687502 0.00593994 \n    0.00510092 0.00436111 0.00372439 0.0031945 0.00277537 0.00241888 \n    0.002095 0.00179943 0.00150419 0.00119264 0.00090934 0.000802394 \n    0.000852816 0.000838368 0.000730842 0.000601028 0.000546616 \n    0.000492205 0.000437793 0.000383381 0.000328969 0.00029454 \n    0.000266428 0.000238317 0.000210205 0.000182093 0.000162091 \n    0.000152145 0.000142198 0.000132252 0.000122306 0.000112359 \n    0.000102413 9.24665e-05 8.25201e-05 7.25738e-05 6.26274e-05 \n    5.78553e-05 5.42216e-05 5.05878e-05 4.69541e-05 4.33204e-05 \n    3.96867e-05 3.60529e-05 3.24192e-05 2.87855e-05 2.51518e-05 \n    2.19153e-05 2.03406e-05 1.8766e-05 1.71913e-05 1.56167e-05 \n    1.4042e-05 1.24674e-05 1.08927e-05 9.31806e-06 \n    EOD\n\n    @v[36].set(<<-'EOD')\n    5 5.01426 5.02852 5.01923 4.77685 4.56471 4.52338 4.56813 \n    4.63122 4.693 4.74776 4.79385 4.83258 4.86358 4.88918 4.91021 \n    4.90553 4.89733 4.89554 4.91953 5.00757 5.07101 5.06318 \n    5.05241 5.05535 5.08042 5.07251 4.90973 4.56136 3.98637 \n    3.237 2.67216 2.33678 2.13529 2.00544 1.91429 1.84638 1.79461 \n    1.75338 1.71958 1.69175 1.6686 1.64918 1.63258 1.61836 1.60607 \n    1.59506 1.58483 1.57575 1.56847 1.56193 1.55538 1.54968 \n    1.54416 1.5388 1.53523 1.53165 1.52807 1.52449 1.52091 1.51771 \n    1.51477 1.51182 1.50888 1.50593 1.50309 1.50113 1.49917 \n    1.4972 1.49524 1.49328 1.49132 1.48935 1.48739 1.48543 1.48346 \n    1.48157 1.48012 1.47868 1.47724 1.47579 1.47435 1.47291 \n    1.47146 1.47002 1.46857 1.46713 1.46574 1.46462 1.4635 1.46238 \n    1.46126 1.46014 1.45902 1.4579 1.45678 1.45567 1.45455 1.45349 \n    1.45275 1.45201 1.45127 1.45053 1.44979 1.44905 1.44831 \n    1.44757 1.44683 1.44609 1.44535 1.44461 1.44387 1.44313 \n    1.44239 1.44165 1.44091 1.44017 1.43943 1.43869 1.43795 \n    1.43721 1.43874 1.43976 1.43619 1.43182 1.43726 1.43084 \n    1.42587 1.42383 1.42642 1.42728 1.42736 1.4271 1.42669 1.42621 \n    1.42569 1.41703 1.41244 1.41019 1.41199 1.41833 1.42502 \n    1.41504 1.37535 1.28381 1.44779 2.33713 3.25835 3.67554 \n    3.84975 4.01125 4.2253 4.45433 4.62215 4.74478 4.82998 4.8868 \n    4.92396 4.94768 4.96498 4.98537 5.0128 5.04467 5.06722 5.06535 \n    5.01475 4.91956 4.80647 4.7242 4.7059 4.73552 4.76379 4.81684 \n    4.87376 4.92276 4.96112 4.9884 5.0045 5.00999 5.00933 5.00619 \n    5.00384 5.00342 5.00373 5.00362 5.00309 5.00272 5.00239 \n    5.00204 5.00172 5.00146 5.00124 5.00105 5.00089 5.00076 \n    5.00065 5.00057 5.00048 5.00041 5.00034 5.00028 5.00023 \n    5.00019 5.00015 5.00015 5.00016 5.0002 5.00023 5.00021 5.00019 \n    5.00017 5.00015 5.00012 5.0001 5.00008 5.00007 5.00006 5.00005 \n    5.00004 5.00003 5.00002 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00002 5.00002 5.00002 5.00002 \n    5.00002 5.00002 5.00002 5.00002 5.00002 5.00002 5.00001 \n    5.00001 5.00001 5.00062 4.99506 4.9835 4.96726 4.9728 4.97877 \n    4.98675 4.9966 5.00406 5.00679 5.00629 5.00561 5.00487 5.00429 \n    5.00384 5.002 5.00164 5.00229 5.00484 5.00769 5.00019 5.00242 \n    5.01319 5.0335 5.07265 5.10129 5.11485 5.12551 5.13953 5.16048 \n    5.18862 5.22811 5.25656 5.25627 5.19975 4.9139 4.24745 3.43732 \n    2.8202 2.43224 2.17409 2.01333 1.93951 1.94622 1.98861 2.02217 \n    2.05383 2.08376 2.11184 2.13793 2.16191 2.18267 2.20502 \n    2.22837 2.24958 2.26901 2.28648 2.302 2.31582 2.32802 2.33869 \n    2.34795 2.35596 2.36282 2.3687 2.37371 2.37797 2.38161 2.38476 \n    2.38743 2.3897 2.39168 2.39329 2.39463 2.39575 2.39671 2.39756 \n    2.39835 2.39907 2.39968 2.39999 2.4003 2.40061 2.40091 2.40122 \n    2.40142 2.40159 2.40176 2.40193 2.4021 2.40222 2.40228 2.40234 \n    2.4024 2.40247 2.40253 2.40259 2.40265 2.40271 2.40277 2.40284 \n    2.40287 2.40289 2.40291 2.40294 2.40296 2.40298 2.40301 \n    2.40303 2.40305 2.40308 2.4031 2.40311 2.40312 2.40313 2.40314 \n    2.40315 2.40316 2.40317 2.40318 \n    EOD\n\n    @v[37].set(<<-'EOD')\n    5 5.01732 5.03181 5.05944 5.12686 5.20725 5.28103 5.31254 \n    5.32901 5.33709 5.3408 5.34257 5.34311 5.34347 5.34386 5.34411 \n    5.3406 5.33484 5.32942 5.32904 5.33644 5.34869 5.35001 5.34882 \n    5.34758 5.34672 5.34599 5.34496 5.34364 5.34165 5.33712 \n    5.33502 5.3366 5.34067 5.34306 5.34398 5.34434 5.34442 5.34443 \n    5.34443 5.34441 5.34439 5.34437 5.34437 5.34438 5.34438 \n    5.34438 5.34438 5.34438 5.34437 5.34437 5.34436 5.34436 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 5.34437 \n    5.34437 5.34437 5.34437 5.34437 5.34437 5.35377 5.35451 \n    5.34265 5.34488 5.35861 5.28622 4.90033 4.75027 4.89731 \n    4.97098 4.99293 4.99832 4.99909 4.99956 4.99858 4.99829 \n    4.9998 5.00035 5.0038 5.00989 5.00251 4.99438 4.9953 4.99761 \n    4.99985 5.00152 5.0011 5.00046 4.99996 4.99925 4.99862 4.99919 \n    4.99961 5.00048 5.00234 4.99654 4.98235 4.95936 4.83738 \n    4.53021 4.21004 4.00593 3.91207 3.88059 3.87822 3.89117 \n    3.91278 3.94044 3.97376 4.01152 4.05052 4.10679 4.17908 \n    4.25673 4.33414 4.40875 4.47879 4.54342 4.60258 4.65595 \n    4.70291 4.74414 4.78018 4.81185 4.83915 4.86291 4.88301 \n    4.90048 4.91528 4.92802 4.9387 4.94777 4.95539 4.9618 4.96725 \n    4.97195 4.97588 4.97932 4.98247 4.98512 4.98697 4.98831 \n    4.98919 4.99015 4.99101 4.99169 4.99222 4.99282 4.99341 \n    4.994 4.9946 4.99519 4.99578 4.99638 4.99667 4.99693 4.9972 \n    4.99747 4.99773 4.998 4.99827 4.99841 4.99849 4.99856 4.99864 \n    4.99872 4.9988 4.99888 4.99896 4.99904 4.99911 4.99919 4.99927 \n    4.99935 4.99943 4.9995 4.99955 4.9996 4.99965 4.9997 5.00736 \n    4.98252 4.87516 4.66727 4.49142 4.43103 4.4301 4.4571 4.49729 \n    4.5407 4.5835 4.62363 4.66114 4.69577 4.72738 4.74632 4.75971 \n    4.77576 4.80671 4.87073 4.91665 4.93252 4.94418 4.95331 \n    4.96094 4.96727 4.97148 4.97471 4.97612 4.98276 5.00247 \n    5.04086 5.08628 5.10673 5.08887 5.0564 5.02767 5.01336 4.99685 \n    4.97422 4.90866 4.67035 4.33117 4.07888 3.94432 3.89105 \n    3.88174 3.89292 3.91442 3.94564 3.98708 4.0355 4.09134 4.16315 \n    4.24088 4.31918 4.39527 4.46693 4.53337 4.59405 4.6486 4.69693 \n    4.73938 4.77617 4.80809 4.83551 4.85895 4.87894 4.89596 \n    4.91081 4.92417 4.93651 4.94552 4.95198 4.9565 4.96096 4.96523 \n    4.96972 4.97428 4.97868 4.98064 4.9826 4.98455 4.98651 4.98847 \n    4.98967 4.99064 4.9916 4.99257 4.99353 4.99422 4.99457 4.99493 \n    4.99528 4.99563 4.99598 4.99633 4.99668 4.99703 4.99738 \n    4.99773 4.9979 4.99804 4.99817 4.9983 4.99843 4.99856 4.99869 \n    4.99883 4.99896 4.99909 4.99921 4.99926 4.99931 4.99937 \n    4.99942 4.99948 4.99953 4.99959 4.99964 \n    EOD\n\n    @v[38].set(<<-'EOD')\n    4.49849 4.53282 4.58329 4.66625 4.83345 4.97823 5.0207 5.01816 \n    5.01116 5.00595 5.00296 5.00148 5.00073 5.00062 5.00033 \n    5.0003 4.99864 4.99661 4.99652 4.99928 5.00361 5.12573 5.17251 \n    5.22612 5.33479 5.44503 5.44432 5.44379 5.44334 5.443 5.44276 \n    5.44258 5.44246 5.44238 5.44232 5.44228 5.44225 5.44223 \n    5.44221 5.4422 5.44219 5.44219 5.44218 5.44218 5.44218 5.44218 \n    5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 \n    5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 \n    5.44217 5.44217 5.44217 5.44217 5.44217 5.44217 5.44216 \n    5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 \n    5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 5.44216 \n    5.44216 5.44216 5.44216 5.44216 5.44215 5.44215 5.44215 \n    5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 \n    5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 \n    5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 5.44215 \n    5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 5.44214 \n    5.44214 5.44214 5.44214 5.44214 5.44212 5.45159 5.45236 \n    5.44064 5.44307 5.45616 5.38122 4.77163 3.53297 2.74466 \n    2.34448 2.11802 1.9783 1.88656 1.82001 1.77389 1.72955 1.69632 \n    1.66971 1.6526 1.65236 1.56034 1.53764 1.97139 2.75096 3.39212 \n    3.74042 3.82345 3.85696 3.88547 3.91862 3.9585 4.00467 4.05903 \n    4.1254 4.19533 4.26791 4.34517 4.42112 4.49238 4.55807 4.6179 \n    4.6713 4.71815 4.75889 4.79418 4.82456 4.85062 4.87291 4.89196 \n    4.90823 4.92209 4.93388 4.9439 4.95242 4.95968 4.96585 4.97108 \n    4.9755 4.97923 4.98237 4.98503 4.98732 4.98927 4.99094 4.99233 \n    4.99353 4.99452 4.99538 4.99608 4.99668 4.99718 4.9976 4.99794 \n    4.99822 4.99847 4.99867 4.99884 4.99899 4.99913 4.99924 \n    4.99932 4.99938 4.99943 4.99947 4.99951 4.99953 4.99955 \n    4.99958 4.99961 4.99964 4.99967 4.99969 4.99972 4.99975 \n    4.99977 4.99978 4.99979 4.99981 4.99982 4.99983 4.99985 \n    4.99986 4.99986 4.99987 4.99987 4.99988 4.99988 4.99988 \n    4.99989 4.99989 4.9999 4.9999 4.99991 4.99991 4.99992 4.99992 \n    4.99993 4.99993 4.99993 4.99994 5.00381 5.00064 4.99246 \n    4.99823 5.00349 5.00076 5.00033 5.00015 5.00009 5.00007 \n    5.00005 5.00004 5.00003 5.00002 4.99988 4.99732 4.99728 \n    4.9978 5.00187 5.00927 5.08712 5.07654 4.92855 4.4863 3.76162 \n    3.00049 2.49834 2.20883 2.03492 1.92384 1.84676 1.79021 \n    1.74716 1.7132 1.68576 1.66309 1.64406 1.62785 1.61383 1.60162 \n    1.59081 1.58117 1.57253 1.56473 1.55765 1.55117 1.54527 \n    1.53988 1.53485 1.53012 1.5257 1.5216 1.51773 1.51411 1.51071 \n    1.50746 1.50438 1.50146 1.49868 1.49603 1.4935 1.49109 1.48878 \n    1.48657 1.48445 1.48242 1.48046 1.47858 1.47677 1.47502 \n    1.47333 1.4717 1.47012 1.46859 1.46711 1.46568 1.46428 1.46292 \n    1.4616 1.46034 1.45923 1.45812 1.45701 1.4559 1.45479 1.45378 \n    1.45279 1.45181 1.45082 1.44983 1.44893 1.44813 1.44732 \n    1.44652 1.44571 1.44491 1.4441 1.4433 1.44249 1.44169 1.44089 \n    1.44019 1.43951 1.43883 1.43815 1.43747 1.4368 1.43612 1.43544 \n    1.43476 1.43408 1.43342 1.43283 1.43223 1.43163 1.43104 \n    1.43044 1.42984 1.42924 1.42865 \n    EOD\n\n    @v[39].set(<<-'EOD')\n    5 5.01048 5.01221 4.98887 4.76261 4.54943 4.51564 4.56249 \n    4.62621 4.68843 4.74374 4.79044 4.82972 4.86127 4.88724 \n    4.90862 4.90791 4.89858 4.89589 4.91767 5.00405 5.16956 \n    5.12391 4.7557 3.87953 3.01124 2.48482 2.20424 2.03812 1.92679 \n    1.84956 1.79256 1.74907 1.71487 1.68724 1.6644 1.64513 1.6287 \n    1.61446 1.60197 1.59095 1.58117 1.57245 1.5646 1.55752 1.55109 \n    1.54516 1.53958 1.53444 1.53008 1.52606 1.52205 1.51843 \n    1.5149 1.51146 1.50893 1.50639 1.50387 1.50133 1.4988 1.49651 \n    1.49436 1.49222 1.49007 1.48793 1.48585 1.48433 1.4828 1.48128 \n    1.47975 1.47823 1.4767 1.47518 1.47365 1.47213 1.4706 1.46912 \n    1.46795 1.46678 1.46561 1.46444 1.46327 1.4621 1.46093 1.45976 \n    1.45859 1.45741 1.45628 1.45534 1.45441 1.45347 1.45254 \n    1.4516 1.45067 1.44973 1.4488 1.44786 1.44693 1.44604 1.44539 \n    1.44475 1.4441 1.44345 1.44281 1.44216 1.44151 1.44086 1.44022 \n    1.43957 1.43892 1.43828 1.43763 1.43698 1.43633 1.43569 \n    1.43504 1.43439 1.43375 1.4331 1.43245 1.4318 1.43157 1.43089 \n    1.43001 1.43042 1.42899 1.42439 1.42216 1.43447 1.44048 \n    1.43705 1.43314 1.43039 1.42861 1.42739 1.42651 1.42548 \n    1.42488 1.4243 1.42392 1.4235 1.32443 1.31149 1.78169 2.64844 \n    3.43211 3.95252 4.20231 4.3746 4.49948 4.58929 4.65742 4.71183 \n    4.77057 4.83196 4.88354 4.92894 4.96625 4.99235 5.00651 \n    5.00941 5.00813 5.00689 5.00588 5.00504 5.00431 5.00368 \n    5.00314 5.00268 5.00228 5.00194 5.00165 5.0014 5.00118 5.001 \n    5.00085 5.00072 5.00061 5.00052 5.00044 5.00037 5.00031 \n    5.00027 5.00022 5.00019 5.00016 5.00013 5.00011 5.00009 \n    5.00008 5.00007 5.00006 5.00005 5.00004 5.00003 5.00003 \n    5.00003 5.00002 5.00002 5.00002 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 5.00001 \n    5.00001 5.00001 5 5 5 5 5 4.99999 4.99999 4.99999 4.99998 \n    4.99998 4.99998 4.99998 4.99998 4.99998 4.99998 4.99999 \n    4.99999 4.99999 4.99999 4.99999 4.99999 5 5 5 5 5.00001 \n    5.00002 5.00003 5.00004 5.00022 4.99974 4.99942 4.99997 \n    5.00063 5.00002 5.00003 4.99994 4.99998 4.99999 5 5 5 5 \n    5 4.99981 4.99998 5.00004 5.00036 5.00049 5.12012 5.16315 \n    5.19712 5.21835 4.87874 4.10151 3.31555 2.74207 2.38075 \n    2.15872 2.01614 1.91886 1.84852 1.79401 1.75052 1.71508 \n    1.68672 1.66467 1.64602 1.62985 1.61576 1.60343 1.59256 \n    1.58287 1.57418 1.56632 1.55922 1.55282 1.54687 1.54132 \n    1.53618 1.53143 1.52698 1.52282 1.51895 1.51527 1.5118 1.50851 \n    1.5054 1.50244 1.49963 1.49695 1.4944 1.49196 1.48963 1.4874 \n    1.48527 1.48322 1.48124 1.47934 1.47751 1.47574 1.47403 \n    1.47239 1.4708 1.46926 1.46777 1.46632 1.46491 1.46355 1.46237 \n    1.4612 1.46002 1.45884 1.45766 1.45659 1.45555 1.45451 1.45346 \n    1.45242 1.45147 1.45062 1.44978 1.44894 1.44809 1.44725 \n    1.4464 1.44556 1.44472 1.44387 1.44303 1.4423 1.44159 1.44088 \n    1.44017 1.43947 1.43876 1.43805 1.43734 1.43664 1.43593 \n    1.43524 1.43462 1.434 1.43338 1.43276 1.43213 1.43151 1.43089 \n    1.43027 \n    EOD\n  end\n\n  def highlightTrace(graph)\n    entry = graph.legend_get(:current)\n    active_list = graph.legend_activate\n    if active_list.include?(entry)\n      graph.legend_deactivate(entry)\n      graph.element_deactivate(entry)\n    else\n      graph.legend_activate(entry)\n      graph.element_activate(entry)\n    end\n  end\n\nend\n\nBLT_Graph_Demo.new\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/graph7.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nlength = 250000\ngraph = Tk::BLT::Graph.new(:title=>\"Scatter Plot\\n#{length} points\")\ngraph.xaxis_configure(:loose=>false, :title=>'X Axis Label')\ngraph.yaxis_configure(:title=>'Y Axis Label')\ngraph.legend_configure(:activerelief=>:sunken, :background=>'')\n\nTk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both)\n\nv_x = Tk::BLT::Vector.new(length)\nv_y = Tk::BLT::Vector.new(length)\nv_x.expr(\"random(#{v_x})\")\nv_y.expr(\"random(#{v_y})\")\nv_x.sort(v_y)\n\nplot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, \n                                           :color=>'green4', :fill=>'green2', \n                                           :linewidth=>0, :outlinewidth=>1, \n                                           :pixels=>4, :label=>'plot', \n                                           :xdata=>v_x, :ydata=>v_y)\n\nTk.root.minsize(0, 0)\n\n#graph.zoom_stack\n#graph.crosshairs\n#graph.active_legend\n#graph.closest_point\nTk::BLT.zoom_stack(graph)\nTk::BLT.crosshairs(graph)\nTk::BLT.active_legend(graph)\nTk::BLT.closest_point(graph)\n\nTk::BLT::Busy.hold(graph)\nTk.update\nTk::BLT::Busy.release(graph)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/graph7a.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nfile = File.join(File.dirname(File.expand_path(__FILE__)), \n                 'images', 'buckskin.gif')\nbgTexture = TkPhotoImage.new(:file=>file)\n\nTkOption.add('*Graph.Tile', bgTexture)\nTkOption.add('*Label.Tile', bgTexture)\nTkOption.add('*Frame.Tile', bgTexture)\nTkOption.add('*Htext.Tile', bgTexture)\nTkOption.add('*TileOffset', 0)\nTkOption.add('*HighlightThickness',   0)\nTkOption.add('*Element.ScaleSybols',  false)\nTkOption.add('*Element.Smooth',       :linear)\nTkOption.add('*activeLine.Color',     'yellow4')\nTkOption.add('*activeLine.Fill',      'yellow')\nTkOption.add('*activeLine.LineWidth', 0)\nTkOption.add('*Element.Pixels',       3)\nTkOption.add('*Graph.halo',           '7i')\n\nif Tk.root.winfo_screenvisual != 'staticgray'\n  TkOption.add('*print.background', 'yellow')\n  TkOption.add('*quit.background',  'red')\nend\n\nlength = 250000\ngraph = Tk::BLT::Graph.new(:title=>\"Scatter Plot\\n#{length} points\")\ngraph.xaxis_configure(:loose=>false, :title=>'X Axis Label')\ngraph.yaxis_configure(:title=>'Y Axis Label')\ngraph.legend_configure(:activerelief=>:sunken, :background=>'')\n\nTk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both)\n\nv_x = Tk::BLT::Vector.new(length)\nv_y = Tk::BLT::Vector.new(length)\nv_x.expr(\"random(#{v_x})\")\nv_y.expr(\"random(#{v_y})\")\nv_x.sort(v_y)\n\nplot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, \n                                           :color=>'green4', :fill=>'green2', \n                                           :linewidth=>0, :outlinewidth=>1, \n                                           :pixels=>4, :label=>'plot', \n                                           :xdata=>v_x, :ydata=>v_y)\n\nTk.root.minsize(0, 0)\n\n#graph.zoom_stack\n#graph.crosshairs\n#graph.active_legend\n#graph.closest_point\nTk::BLT.zoom_stack(graph)\nTk::BLT.crosshairs(graph)\nTk::BLT.active_legend(graph)\nTk::BLT.closest_point(graph)\n\nTk::BLT::Busy.hold(graph)\nTk.update\nTk::BLT::Busy.release(graph)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/graph7b.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nlength = 250000\ngraph = Tk::BLT::Graph.new(:title=>\"Scatter Plot\\n#{length} points\")\ngraph.xaxis_configure(:loose=>false, :title=>'X Axis Label')\ngraph.yaxis_configure(:title=>'Y Axis Label')\ngraph.legend_configure(:activerelief=>:sunken, :background=>'')\n\nTk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both)\n\nx = Array.new(length)\ny = Array.new(length)\n(0...length).each{|i|\n  x[i] = rand\n  y[i] = rand\n}\n\nplot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, \n                                           :color=>'green4', :fill=>'green2', \n                                           :linewidth=>0, :outlinewidth=>1, \n                                           :pixels=>4, :label=>'plot', \n                                           :xdata=>x, :ydata=>y)\n\nTk.root.minsize(0, 0)\n\n#graph.zoom_stack\n#graph.crosshairs\n#graph.active_legend\n#graph.closest_point\nTk::BLT.zoom_stack(graph)\nTk::BLT.crosshairs(graph)\nTk::BLT.active_legend(graph)\nTk::BLT.closest_point(graph)\n\nTk::BLT::Busy.hold(graph)\nTk.update\nTk::BLT::Busy.release(graph)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/graph7c.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nlength = 250000\ngraph = Tk::BLT::Graph.new(:title=>\"Scatter Plot\\n#{length} points\")\ngraph.xaxis_configure(:loose=>false, :title=>'X Axis Label')\ngraph.yaxis_configure(:title=>'Y Axis Label')\ngraph.legend_configure(:activerelief=>:sunken, :background=>'')\n\nTk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both)\n\nv_x = Tk::BLT::Vector.new(length)\nv_y = Tk::BLT::Vector.new(length)\nx = Array.new(length)\ny = Array.new(length)\n(0...length).each{|i|\n  x[i] = rand\n  y[i] = rand\n}\nv_x.set(x)\nv_y.set(y)\n\nplot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, \n                                           :color=>'green4', :fill=>'green2', \n                                           :linewidth=>0, :outlinewidth=>1, \n                                           :pixels=>4, :label=>'plot', \n                                           :xdata=>v_x, :ydata=>v_y)\n\nTk.root.minsize(0, 0)\n\n#graph.zoom_stack\n#graph.crosshairs\n#graph.active_legend\n#graph.closest_point\nTk::BLT.zoom_stack(graph)\nTk::BLT.crosshairs(graph)\nTk::BLT.active_legend(graph)\nTk::BLT.closest_point(graph)\n\nTk::BLT::Busy.hold(graph)\nTk.update\nTk::BLT::Busy.release(graph)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/pareto.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/blt'\n\n# Example of a pareto chart.\n#\n# The pareto chart mixes line and bar elements in the same graph.\n# Each processing operating is represented by a bar element.  The\n# total accumulated defects is displayed with a single line element.\nb = Tk::BLT::Barchart.new(:title=>'Defects Found During Inspection', \n                          :font=>'Helvetica 12', :plotpady=>[12, 4], \n                          :width=>'6i', :height=>'5i')\nTk::BLT::Table.add(Tk.root, b, :fill=>:both)\n\ndata = [\n  [\"Spot Weld\",  82,   'yellow'], \n  [\"Lathe\",      49,   'orange'], \n  [\"Gear Cut\",   38,   'green'], \n  [\"Drill\",      24,   'blue'], \n  [\"Grind\",      17,   'red'], \n  [\"Lapping\",    12,   'brown'], \n  [\"Press\",       8,   'purple'], \n  [\"De-burr\",     4,   'pink'], \n  [\"Packaging\",   3,   'cyan'], \n  [\"Other\",      12,   'magenta']\n]\n\n# Create an X-Y graph line element to trace the accumulated defects.\nb.line_create('accum', :label=>'', :symbol=>:none, :color=>'red')\n\n# Define a bitmap to be used to stipple the background of each bar.\npattern1 = Tk::BLT::Bitmap.define([ [4, 4], [1, 2, 4, 8] ])\n\n# For each process, create a bar element to display the magnitude.\ncount = 0\nsum   = 0\nydata = [0]\nxdata = [0]\nlabels = []\n\ndata.each{|label, value, color|\n  count += 1\n  b.element_create(label, :xdata=>count, :ydata=>value, :foreground=>color, \n                   :relief=>:solid, :borderwidth=>1, :stipple=>pattern1, \n                   :background=>'lightblue')\n  labels[count] = label\n  # Get the total number of defects.\n  sum += value\n  ydata << sum\n  xdata << count\n}\n\n# Configure the coordinates of the accumulated defects, \n# now that we know what they are.\nb.element_configure('accum', :xdata=>xdata, :ydata=>ydata)\n\n# Add text markers to label the percentage of total at each point.\nxdata.zip(ydata){|x, y|\n  percent = (y * 100.0) / sum\n  if x == 0\n    text = ' 0%'\n  else\n    text = '%.1f' % percent\n  end\n  b.marker_create(:text, :coords=>[x, y], :text=>text, :font=>'Helvetica 10', \n                  :foreground=>'red4', :anchor=>:center, :yoffset=>-5)\n}\n\n# Display an auxillary y-axis for percentages.\nb.axis_configure('y2', :hide=>false, :min=>0.0, :max=>100.0, \n                 :title=>'Percentage')\n\n# Title the y-axis\nb.axis_configure('y', :title=>'Defects')\n\n# Configure the x-axis to display the process names, instead of numbers.\nb.axis_configure('x', :title=>'Process', :rotate=>90, :subdivisions=>0, \n                 :command=>proc{|w, val|\n                   val = val.round\n                   labels[val]? labels[val]: val\n                  })\n\n# No legend needed.\nb.legend_configure(:hide=>true)\n\n# Configure the grid lines.\nb.gridline_configure(:mapx=>:x, :color=>'lightblue')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/plot1.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\ngraph = Tk::BLT::Graph.new.pack\nplot = Tk::BLT::PlotComponent::Element.new(graph, :linewidth=>0, :label=>'foo')\nplot.data([[1.0, 3.4], [1.1, 2.8], [1.2, 3.1], [1.4, 2.9]].flatten)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/plot1b.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\ngraph = Tk::BLT::Graph.new.pack\nplot = graph.element_create\nplot.configure(:linewidth=>0, :label=>'foo', \n               :data=>[[1.0, 3.4], [1.1, 2.8], [1.2, 3.1], [1.4, 2.9]].flatten)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/readme.txt",
    "content": "The scripts and image files in this directory are based on demo files\nof Tcl/Tk's BLT extention. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/scripts/stipples.rb",
    "content": "$stipples = {} unless $stipples\n\n$stipples['bdiagonal1'] = Tk::BLT::Bitmap.new(<<EOD)\n#define bdiagonal1_width 8\n#define bdiagonal1_height 8\nstatic unsigned char bdiagonal1_bits[] = {\n   0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11};\nEOD\n\n$stipples['bdiagonal2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define bdiagonal2_width 8\n#define bdiagonal2_height 8\nstatic unsigned char bdiagonal2_bits[] = {\n   0x08, 0x04, 0x02, 0x01, 0x80, 0x40, 0x20, 0x10};\nEOD\n\n$stipples['checker2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define checker2_width 8\n#define checker2_height 8\nstatic unsigned char checker2_bits[] = {\n   0x33, 0x33, 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc};\nEOD\n\n\n$stipples['checker3'] = Tk::BLT::Bitmap.new(<<EOD)\n#define checker3_width 8\n#define checker3_height 8\nstatic unsigned char checker3_bits[] = {\n   0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0};\nEOD\n\n$stipples['cross1'] = Tk::BLT::Bitmap.new(<<EOD)\n#define cross1_width 8\n#define cross1_height 8\nstatic unsigned char cross_bits[] = {\n   0xff, 0xaa, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xaa};\nEOD\n\n$stipples['cross2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define cross2_width 8\n#define cross2_height 8\nstatic unsigned char cross2_bits[] = {\n   0xff, 0x88, 0x88, 0x88, 0xff, 0x88, 0x88, 0x88};\nEOD\n\n$stipples['cross3'] = Tk::BLT::Bitmap.new(<<EOD)\n#define cross3_width 8\n#define cross3_height 8\nstatic unsigned char cross3_bits[] = {\n   0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};\nEOD\n\n$stipples['crossdiag'] = Tk::BLT::Bitmap.new(<<EOD)\n#define crossdiag_width 8\n#define crossdiag_height 8\nstatic unsigned char crossdiag2_bits[] = {\n   0x18, 0x24, 0x42, 0x81, 0x81, 0x42, 0x24, 0x18};\nEOD\n\n$stipples['dot1'] = Tk::BLT::Bitmap.new(<<EOD)\n#define dot1_width 8\n#define dot1_height 8\nstatic unsigned char dot1_bits[] = {\n   0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa};\nEOD\n\n$stipples['dot2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define dot2_width 8\n#define dot2_height 8\nstatic unsigned char dot2_bits[] = {\n   0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00};\nEOD\n\n$stipples['dot3'] = Tk::BLT::Bitmap.new(<<EOD)\n#define dot3_width 8\n#define dot3_height 8\nstatic unsigned char dot3_bits[] = {\n   0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00};\nEOD\n\n$stipples['dot4'] = Tk::BLT::Bitmap.new(<<EOD)\n#define dot4_width 8\n#define dot4_height 8\nstatic unsigned char dot4_bits[] = {\n   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\nEOD\n\n$stipples['fdiagonal1'] = Tk::BLT::Bitmap.new(<<EOD)\n#define fdiagonal1_width 8\n#define fdiagonal1_height 8\nstatic unsigned char fdiagonal1_bits[] = {\n   0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88};\nEOD\n\n$stipples['fdiagonal2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define fdiagonal2_width 8\n#define fdiagonal2_height 8\nstatic unsigned char fdiagonal2_bits[] = {\n   0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08};\nEOD\n\n$stipples['hline1'] = Tk::BLT::Bitmap.new(<<EOD)\n#define hline1_width 8\n#define hline1_height 8\nstatic unsigned char hline1_bits[] = {\n   0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00};\nEOD\n\n$stipples['hline2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define hline2_width 8\n#define hline2_height 8\nstatic unsigned char hline2_bits[] = {\n   0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00};\nEOD\n\n$stipples['lbottom'] = Tk::BLT::Bitmap.new(<<EOD)\n#define lbottom_width 8\n#define lbottom_height 8\nstatic unsigned char lbottom_bits[] = {\n   0x00, 0x11, 0x11, 0x77, 0x00, 0x11, 0x11, 0x77};\nEOD\n\n$stipples['ltop'] = Tk::BLT::Bitmap.new(<<EOD)\n#define ltop_width 8\n#define ltop_height 8\nstatic unsigned char ltop_bits[] = {\n   0xee, 0x88, 0x88, 0x00, 0xee, 0x88, 0x88, 0x00};\nEOD\n\n$stipples['rbottom'] = Tk::BLT::Bitmap.new(<<EOD)\n#define rbottom_width 8\n#define rbottom_height 8\nstatic unsigned char rbottom_bits[] = {\n   0x00, 0x88, 0x88, 0xee, 0x00, 0x88, 0x88, 0xee};\nEOD\n\n$stipples['rtop'] = Tk::BLT::Bitmap.new(<<EOD)\n#define rtop_width 8\n#define rtop_height 8\nstatic unsigned char rtop_bits[] = {\n   0x77, 0x11, 0x11, 0x00, 0x77, 0x11, 0x11, 0x00};\nEOD\n\n$stipples['vline1'] = Tk::BLT::Bitmap.new(<<EOD)\n#define vline1_width 8\n#define vline1_height 8\nstatic unsigned char vline1_bits[] = {\n   0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};\nEOD\n\n$stipples['vline2'] = Tk::BLT::Bitmap.new(<<EOD)\n#define vline2_width 8\n#define vline2_height 8\nstatic unsigned char vline2_bits[] = {\n   0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33};\nEOD\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/winop1.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nfile = File.join(File.dirname(File.expand_path(__FILE__)), \n                 'images', 'sample.gif')\nif File.exist?(file)\n  src = TkPhotoImage.new(:file=>file)\nelse\n  fail RuntimeError, 'no image file'\nend\n\nwidth = src.width\nheight = src.height\n\nTkOption.add('*Label.font', '*helvetica*10*')\nTkOption.add('*Label.background', 'white')\n\nl_img0 = TkLabel.new(:image=>src)\nl_hdr0 = TkLabel.new(:text=>\"#{width} x #{height}\")\nl_ftr0 = TkLabel.new(:text=>'100%')\nTk.root.background('white')\n\n(2..10).each{|i|\n  iw = width/i\n  ih = height/i\n  r = '%6g'%(100.0/i)\n  dst = TkPhotoImage.new(:width=>iw, :height=>ih)\n  Tk::BLT::Winop.image_resample(src, dst, :sinc)\n  l_hdr = TkLabel.new(:text=>\"#{iw} x #{ih}\")\n  l_ftr = TkLabel.new(:text=>\"#{r}%\")\n  l_img = TkLabel.new(:image=>dst)\n  Tk::BLT::Table.add(Tk.root, \n                     [0,i], l_hdr, \n                     [1,i], l_img, \n                     [2,i], l_ftr)\n  Tk.update\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/blt/winop2.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/blt'\n\nfile = File.join(File.dirname(File.expand_path(__FILE__)), \n                 'images', 'qv100.t.gif')\nif File.exist?(file)\n  src = TkPhotoImage.new(:file=>file)\nelse\n  fail RuntimeError, 'no image file'\nend\n\nwidth = src.width\nheight = src.height\n\nTkOption.add('*Label.font', '*helvetica*10*')\nTkOption.add('*Label.background', 'white')\n\n[0, 90, 180, 270, 360, 45].each_with_index{|r, i|\n  dest = TkPhotoImage.new\n  Tk::BLT::Winop.image_rotate(src, dest, r)\n  l_txt = TkLabel.new(:text=>\"#{r} degrees\")\n  l_img = TkLabel.new(:image=>dest)\n  Tk::BLT::Table.add(Tk.root, [0,i], l_img, [1,i], l_txt)\n  Tk.update\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/Orig_LICENSE.txt",
    "content": "\n  ######################################################################\n  ###  The following text is the original 'LICENSE.txt' of BWidget   ###\n  ###  extension.                                                    ###\n  ###  Original Tcl source files are not include in this directry,   ###\n  ###  because of all of them are rewrited to Ruby files.            ###\n  ###  However, the bitmap data files ('bwidgtet.xbm' and 'x1.xbm')  ###\n  ###  included in this directory are quoted from BWidget source     ###\n  ###  archive. So, those bitmaps are under the following license.   ###\n  ######################################################################\n\n\nBWidget ToolKit\nCopyright (c) 1998-1999 UNIFIX. \nCopyright (c) 2001-2002 ActiveState Corp. \n\nThe following terms apply to all files associated with the software\nunless explicitly disclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/basic.rb",
    "content": "#\n#  basic demo  ---  called from demo.rb\n#\nunless Object.const_defined?('DemoVar')\n  fail RuntimeError, \"This is NOT a stand alone script. This script is called from 'demo.rb'. \"\nend\n\nmodule DemoBasic\n  @@var   = TkVariable.new_hash\n  @@after = nil\n  @@count = 0\n\n  def self.create(nb)\n    frame = nb.insert('end', 'demoBasic', :text=>'Basic')\n    topf  = TkFrame.new(frame)\n\n    titf1 = Tk::BWidget::TitleFrame.new(topf, :text=>'Label')\n    titf2 = Tk::BWidget::TitleFrame.new(topf, :text=>'Entry')\n\n    titf3 = Tk::BWidget::TitleFrame.new(frame, :text=>'Button and ArrowButton')\n\n    _label(titf1.get_frame)\n    _entry(titf2.get_frame)\n    _button(titf3.get_frame)\n\n    Tk.pack(titf1, titf2, :side=>:left, :fill=>:both, :padx=>4, :expand=>true)\n    topf.pack(:pady=>2, :fill=>:x)\n    titf3.pack(:pady=>2, :padx=>4, :fill=>:x)\n  end\n\n  def self._label(parent)\n    lab = Tk::BWidget::Label.new(parent, :text=>'This is a Label widget', \n                                 :helptext=>'Label widget')\n    chk = TkCheckbutton.new(parent, :text=>'Disabled', \n                            :variable=>@@var.ref(lab, 'state'), \n                            :onvalue=>'disabled', :offvalue=>'normal', \n                            :command=>proc{lab[:state] = @@var[lab, 'state']})\n    lab.pack(:anchor=>:w, :pady=>4)\n    chk.pack(:anchor=>:w)\n  end\n\n  def self._entry(parent)\n    ent = Tk::BWidget::Entry.new(parent, :text=>'Press enter', \n                                 :helptext=>'Entry widtet', \n                                 :command=>proc{\n                                   @@var['entcmd'] = 'command called'\n                                   Tk.after(500, proc{@@var['entcmd'] = ''})\n                                 })\n\n    chk1 = TkCheckbutton.new(parent, :text=>'Disabled', \n                             :variable=>@@var.ref(ent, 'state'), \n                             :onvalue=>'disabled', :offvalue=>'normal', \n                             :command=>proc{ent.state = @@var[ent, 'state']})\n\n    chk2 = TkCheckbutton.new(parent, :text=>'Non editable', \n                             :variable=>@@var.ref(ent, 'editable'), \n                             :onvalue=>false, :offvalue=>true, \n                             :command=>proc{\n                               ent.editable = @@var[ent, 'editable']\n                             })\n\n    lab = TkLabel.new(parent, :textvariable=>@@var.ref('entcmd'), \n                      :foreground=>'red')\n\n    ent.pack(:pady=>4, :anchor=>:w)\n    Tk.pack(chk1, chk2, :anchor=>:w)\n    lab.pack(:pady=>4)\n  end\n\n  def self._button(parent)\n    frame = TkFrame.new(parent)\n    but  = Tk::BWidget::Button.new(frame, :text=>'Press me!', \n                                   :repeatdelay=>300, \n                                   :command=>proc{_butcmd('command')}, \n                                   :helptext=>'This is a Button widget')\n\n    sep1 = Tk::BWidget::Separator.new(frame, :orient=>:vertical)\n    arr1 = Tk::BWidget::ArrowButton.new(frame, :type=>:button, \n                :width=>25, :height=>25, :repeatdelay=>300, \n                :command=>proc{_butcmd('command')}, \n                :helptext=>\"This is an ArrowButton widget\\nof type button\")\n\n    sep2 = Tk::BWidget::Separator.new(frame, :orient=>:vertical)\n    arr2 = Tk::BWidget::ArrowButton.new(frame, :type=>:arrow, \n                :width=>25, :height=>25, :relief=>:sunken, \n                :ipadx=>0, :ipady=>0, :repeatdelay=>300, \n                :command=>proc{_butcmd('command')}, \n                :helptext=>\"This is an ArrowButton widget\\nof type arrow\")\n\n    but.pack(:side=>:left, :padx=>4)\n    sep1.pack(:side=>:left, :padx=>4, :fill=>:y)\n    arr1.pack(:side=>:left, :padx=>4)\n    sep2.pack(:side=>:left, :padx=>4, :fill=>:y)\n    arr2.pack(:side=>:left, :padx=>4)\n    frame.pack\n\n    Tk::BWidget::Separator.new(parent, \n                               :orient=>:horizontal).pack(:fill=>:x, :pady=>10)\n\n    labf1 = Tk::BWidget::LabelFrame.new(parent, :text=>'Command', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>1)\n    subf = labf1.get_frame\n    chk1 = TkCheckbutton.new(subf, :text=>'Disabled', \n                             :variable=>@@var.ref('bstate'), \n                             :onvalue=>'disabled', :offvalue=>'normal', \n                             :command=>proc{_bstate(@@var['bstate'], \n                                                     but, arr1, arr2)})\n    chk2 = TkCheckbutton.new(subf, :text=>\"Use armcommand/\\ndisarmcommand\", \n                             :variable=>@@var.ref('barmcmd'), \n                             :command=>proc{_barmcmd(@@var['barmcmd'], \n                                                     but, arr1, arr2)})\n    Tk.pack(chk1, chk2, :anchor=>:w)\n\n    label = TkLabel.new(parent, :textvariable=>@@var.ref('butcmd'), \n                        :foreground=>'red').pack(:side=>:bottom, :pady=>4)\n\n    labf2 = Tk::BWidget::LabelFrame.new(parent, :text=>'Direction', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>1)\n    subf = labf2.get_frame\n    @@var['bside'] = :top\n    [:top, :left, :bottom, :right].each{|dir|\n      TkRadiobutton.new(subf, :text=>\"#{dir} arrow\", \n                        :variable=>@@var.ref('bside'), :value=>dir, \n                        :command=>proc{_bside(@@var['bside'], arr1, arr2)}\n                        ).pack(:anchor=>:w)\n    }\n\n    labf3 = Tk::BWidget::LabelFrame.new(parent, :text=>'Relief', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>1)\n    subf = labf3.get_frame\n    @@var['brelief'] = :raised\n    [ %w(raised sunken ridge groove), %w(flat solid link)].each{|lrelief|\n      f = TkFrame.new(subf)\n      lrelief.each{|relief|\n        TkRadiobutton.new(f, :text=>relief, \n                          :variable=>@@var.ref('brelief'), :value=>relief, \n                          :command=>proc{\n                            _brelief(@@var['brelief'], but, arr1, arr2)\n                          }).pack(:anchor=>:w)\n      }\n      f.pack(:side=>:left, :padx=>2, :anchor=>:n)\n    }\n    Tk.pack(labf1, labf2, labf3, :side=>:left, :fill=>:y, :padx=>4)\n  end\n\n  def self._bstate(state, but, arr1, arr2)\n    [but, arr1, arr2].each{|b| b[:state] = state}\n  end\n\n  def self._brelief(relief, but, arr1, arr2)\n    but[:relief] = relief\n    if relief.to_s != 'link'\n      [arr1, arr2].each{|arr| arr[:relief] = relief}\n    end\n  end\n\n  def self._bside(side, *args)\n    args.each{|arr| arr[:dir] = side}\n  end\n\n  def self._barmcmd(value, but, arr1, arr2)\n    if TkComm.bool(value)\n      but.configure(:armcommand=>proc{_butcmd('arm')}, \n                    :disarmcommand=>proc{_butcmd('disarm')}, \n                    :command=>'')\n      [arr1, arr2].each{|arr|\n        arr.configure(:armcommand=>proc{_butcmd('arm')}, \n                      :disarmcommand=>proc{_butcmd('disarm')}, \n                      :command=>'')\n      }\n    else\n      but.configure(:armcommand=>'', :disarmcommand=>'', \n                    :command=>proc{_butcmd('command')})\n      [arr1, arr2].each{|arr|\n        arr.configure(:armcommand=>'', :disarmcommand=>'', \n                      :command=>proc{_butcmd('command')})\n      }\n    end\n  end\n\n  def self._butcmd(reason)\n    unless @@after\n      @@after = TkTimer.new(500, 1, proc{@@var['butcmd'] = ''})\n    end\n    @@after.stop\n    if (reason == 'arm')\n      @@count += 1\n      @@var['butcmd'] = \"#{reason} command called (#{@@count})\"\n    else\n      @@count = 0\n      @@var['butcmd'] = \"#{reason} command called\"\n    end\n    @@after.start\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/bwidget.xbm",
    "content": "#define bwidget_width 76\n#define bwidget_height 64\nstatic char bwidget_bits[] = {\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0x00,0xb6,0x6d,0xdb,0x16,0x00,0x00,0x00,0x00,0xf0,\n 0x00,0xdb,0xb6,0x6d,0xab,0x00,0x00,0x00,0x00,0xf0,0x00,0x55,0x55,0x55,0x75,\n 0x01,0x00,0x00,0x00,0xf0,0x00,0x6d,0xdb,0xb6,0xad,0x02,0x00,0x00,0x00,0xf0,\n 0x00,0xb6,0x6d,0xdb,0xb6,0x05,0x00,0x00,0x00,0xf0,0x00,0x55,0x55,0x55,0x55,\n 0x05,0x00,0x00,0x00,0xf0,0x00,0xda,0xb6,0xad,0x6d,0x0b,0x00,0x00,0x00,0xf0,\n 0x00,0x6b,0x03,0xc0,0xb6,0x05,0x00,0x00,0x00,0xf0,0x00,0x56,0x05,0x00,0x55,\n 0x0d,0x00,0x00,0x00,0xf0,0x00,0xbb,0x05,0x80,0xdb,0x06,0x00,0x00,0x00,0xf0,\n 0x00,0xca,0x06,0x00,0x6c,0x0b,0x00,0x00,0x00,0xf0,0x00,0xb6,0x02,0x00,0xaa,\n 0x0a,0x00,0x00,0x00,0xf0,0x00,0xab,0x05,0x00,0x6c,0x0b,0x00,0x00,0x00,0xf0,\n 0x00,0xdd,0x06,0x00,0xb6,0x05,0x00,0x00,0x00,0xf0,0x00,0xaa,0x02,0x00,0x55,\n 0x05,0x00,0x00,0x00,0xf0,0x00,0xb7,0x05,0xc0,0xda,0x02,0x00,0x00,0x00,0xf0,\n 0x00,0xd9,0x06,0x50,0x6b,0x01,0x00,0x00,0x00,0xf0,0x00,0x56,0xb5,0xad,0xad,\n 0x00,0x00,0x00,0x00,0xf0,0x00,0xdb,0xd6,0x76,0x15,0x00,0x00,0x00,0x00,0xf0,\n 0x00,0x6a,0xab,0xaa,0x2d,0x00,0x00,0x00,0x00,0xf0,0x00,0x56,0x75,0xad,0xb6,\n 0x02,0x00,0x00,0x00,0xf0,0x00,0xbb,0xad,0xd6,0xaa,0x05,0x00,0x00,0x00,0xf0,\n 0x00,0xca,0xb6,0x6b,0xdb,0x2a,0x00,0x00,0x00,0xf0,0x00,0x77,0xd5,0x5c,0x6d,\n 0x2d,0x00,0x00,0x00,0xf0,0x00,0x99,0x05,0x00,0xaa,0x56,0x00,0x00,0x00,0xf0,\n 0x00,0xee,0x06,0x00,0x6c,0xbb,0x00,0x00,0x00,0xf0,0x00,0xaa,0x02,0x00,0xb0,\n 0x55,0x00,0x00,0x00,0xf0,0x00,0x55,0x05,0x00,0xa8,0xd6,0x00,0x00,0x00,0xf0,\n 0x00,0xee,0x06,0x00,0xd0,0x6a,0x00,0x00,0x00,0xf0,0x00,0x55,0x03,0x00,0x68,\n 0xb7,0xfc,0x00,0x7e,0xf0,0x00,0x6d,0x05,0x00,0xa8,0xaa,0xfc,0x80,0x7e,0xf0,\n 0x00,0xb6,0x05,0x00,0x50,0xbb,0xfe,0x01,0x7e,0xf0,0x00,0x55,0x05,0x00,0x78,\n 0xad,0xfe,0x81,0x1f,0xf0,0x00,0xb6,0x05,0x00,0xa4,0xb5,0xfe,0x81,0x1f,0xf0,\n 0x00,0x5b,0x05,0x80,0xba,0x56,0xfe,0x83,0x1f,0xf0,0x00,0xaa,0x6b,0x5b,0xd5,\n 0x5a,0xff,0x85,0x1f,0xf0,0x00,0xdb,0x5a,0xad,0x57,0x2b,0xff,0xc7,0x0f,0xf0,\n 0x00,0x6d,0xad,0xd5,0x6a,0x0d,0xff,0xc7,0x0f,0xf0,0x00,0xaa,0xd6,0xb6,0xba,\n 0x05,0xdf,0xc7,0x0f,0xf0,0x00,0xb7,0xb5,0x5a,0xab,0x8a,0xdf,0xcf,0x0f,0xf0,\n 0x00,0xd9,0x5a,0xab,0x6d,0x8f,0xcf,0xef,0x07,0xf0,0x00,0x56,0xad,0x75,0xb5,\n 0xaf,0x8f,0xef,0x07,0xf0,0x00,0xb5,0xeb,0x5a,0x00,0x9f,0xcf,0xef,0x07,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0xff,0x8f,0xff,0x07,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0x87,0xff,0x03,0xf0,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xff,0x03,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0x03,0xff,0x03,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0x03,0xff,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0xfc,0x01,0xff,0x03,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0x01,0xfe,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x01,0xfe,0x01,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0};\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/demo.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/bwidget'\n\nmodule DemoVar\n  @_wfont    = nil\n  @notebook  = nil\n  @mainframe = nil\n  @status    = TkVariable.new\n  @prgtext   = TkVariable.new\n  @prgindic  = TkVariable.new\n  @font      = nil\n  @font_name = nil\n  @toolbar1  = TkVariable.new(true)\n  @toolbar2  = TkVariable.new(true)\nend\nclass << DemoVar\n  attr_accessor :_wfont, :notebook, :mainframe, :font, :font_name\n  attr_reader   :status, :prgtext, :prgindic, :toolbar1, :toolbar2\nend\n\nclass BWidget_Demo\n  DEMODIR = File.dirname(File.expand_path(__FILE__))\n\n  %w(manager basic select dnd tree tmpldlg).each{|f|\n    require File.join(DEMODIR, f << '.rb')\n  }\n\n  def initialize\n    TkOption.add('*TitleFrame.l.font', 'helvetica 11 bold italic')\n\n    root = TkRoot.new(:title=>'BWidget demo')\n    root.withdraw\n\n    _create\n\n    Tk::BWidget.place(root, 0, 0, :center)\n    root.deiconify\n    root.raise\n    root.focus(true)\n\n    root.geometry(root.geometry)\n  end\n\n  def _create\n    DemoVar.prgtext.value = 'Please wait while loading font...'\n    DemoVar.prgindic.value = -1\n\n    intro = _create_intro\n\n    Tk.update\n\n    Tk::BWidget::SelectFont.load_font\n\n    descmenu = [\n      '&File', 'all', 'file', 0, [\n        ['command', 'E&xit', [], 'Exit BWidget demo', [], \n          {:command=>proc{exit}}]\n      ], \n      '&Options', 'all', 'options', 0, [\n        ['checkbutton', 'Toolbar &1', ['all', 'option'], \n          'Show/hide toolbar 1', [], \n          { :variable=>DemoVar.toolbar1, \n            :command=>proc{\n              DemoVar.mainframe.show_toolbar(0, DemoVar.toolbar1.value)\n            }\n          }\n        ], \n        ['checkbutton', 'Toolbar &2', ['all', 'option'], \n          'Show/hide toolbar 2', [], \n          { :variable=>DemoVar.toolbar2, \n            :command=>proc{\n              DemoVar.mainframe.show_toolbar(1, DemoVar.toolbar2.value)\n            }\n          }\n        ]\n      ]\n    ]\n\n    DemoVar.prgtext.value = 'Creating MainFrame...'\n    DemoVar.prgindic.value = 0\n\n    DemoVar.mainframe = Tk::BWidget::MainFrame.new(\n                                :menu=>descmenu, \n                                :textvariable=>DemoVar.status, \n                                :progressvar=>DemoVar.prgindic\n                        )\n\n    # toobar 1 creation\n    DemoVar.prgindic.numeric += 1\n\n    DemoVar.mainframe.add_toolbar{|tb1|\n      Tk::BWidget::ButtonBox.new(tb1, :spacing=>0, :padx=>1, :pady=>1){|bbox|\n        add(:image=>Tk::BWidget::Bitmap.new('new'), \n            :highlightthickness=>0, :takefocus=>0, :relief=>:link, \n            :borderwidth=>1, :padx=>1, :pady=>1, \n            :command=>proc{puts 'select \"Create a new file\" icon'}, \n            :helptext=>\"Create a new file\")\n\n        add(:image=>Tk::BWidget::Bitmap.new('open'), \n            :highlightthickness=>0, :takefocus=>0, :relief=>:link, \n            :borderwidth=>1, :padx=>1, :pady=>1, \n            :command=>proc{puts 'select \"Open an existing file\" icon'}, \n            :helptext=>\"Open an existing file\")\n\n        add(:image=>Tk::BWidget::Bitmap.new('save'), \n            :highlightthickness=>0, :takefocus=>0, :relief=>:link, \n            :borderwidth=>1, :padx=>1, :pady=>1, \n            :command=>proc{puts 'select \"Save file\" icon'}, \n            :helptext=>\"Save file\")\n\n        pack(:side=>:left, :anchor=>:w)\n      }\n\n      Tk::BWidget::Separator.new(tb1, :orient=>:vertical){\n        pack(:side=>:left, :fill=>:y, :padx=>4, :anchor=>:w)\n      }\n\n      DemoVar.prgindic.numeric += 1\n\n      Tk::BWidget::ButtonBox.new(tb1, :spacing=>0, :padx=>1, :pady=>1){|bbox|\n        add(:image=>Tk::BWidget::Bitmap.new('cut'), \n            :highlightthickness=>0, :takefocus=>0, :relief=>:link, \n            :borderwidth=>1, :padx=>1, :pady=>1, \n            :command=>proc{puts 'select \"Cut selection\" icon'}, \n            :helptext=>\"Cut selection\")\n\n        add(:image=>Tk::BWidget::Bitmap.new('copy'), \n            :highlightthickness=>0, :takefocus=>0, :relief=>:link, \n            :borderwidth=>1, :padx=>1, :pady=>1, \n            :command=>proc{puts 'select \"Copy selection\" icon'}, \n            :helptext=>\"Copy selection\")\n\n        add(:image=>Tk::BWidget::Bitmap.new('paste'), \n            :highlightthickness=>0, :takefocus=>0, :relief=>:link, \n            :borderwidth=>1, :padx=>1, :pady=>1, \n            :command=>proc{puts 'select \"Paste selection\" icon'}, \n            :helptext=>\"Paste selection\")\n\n        pack(:side=>:left, :anchor=>:w)\n      }\n    }\n\n    # toolbar 2 creation\n    DemoVar.prgindic.numeric += 1\n\n    tb2 = DemoVar.mainframe.add_toolbar\n    DemoVar._wfont = Tk::BWidget::SelectFont::Toolbar.new(tb2, \n                       :command=>proc{update_font(DemoVar._wfont[:font])}\n                     )\n    DemoVar.font = DemoVar._wfont[:font]\n    DemoVar._wfont.pack(:side=>:left, :anchor=>:w)\n\n    DemoVar.mainframe.add_indicator(\n      :text=>\"BWidget #{Tk::BWidget.package_version}\"\n    )\n    DemoVar.mainframe.add_indicator(:textvariable=>'tk_patchLevel')\n\n    # NoteBook creation\n    DemoVar.notebook = Tk::BWidget::NoteBook.new(DemoVar.mainframe.get_frame)\n\n    DemoVar.prgtext.value = \"Creating Manager...\"\n    DemoVar.prgindic.numeric += 1\n    DemoManager.create(DemoVar.notebook)\n\n    DemoVar.prgtext.value = \"Creating Basic...\"\n    DemoVar.prgindic.numeric += 1\n    DemoBasic.create(DemoVar.notebook)\n\n    DemoVar.prgtext.value = \"Creating Select...\"\n    DemoVar.prgindic.numeric += 1\n    DemoSelect.create(DemoVar.notebook)\n\n    DemoVar.prgtext.value = \"Creating Dialog...\"\n    DemoVar.prgindic.numeric += 1\n    DemoDialog.create(DemoVar.notebook)\n\n    DemoVar.prgtext.value = \"Creating Drag and Drop...\"\n    DemoVar.prgindic.numeric += 1\n    DemoDnD.create(DemoVar.notebook)\n\n    DemoVar.prgtext.value = \"Creating Tree...\"\n    DemoVar.prgindic.numeric += 1\n    DemoTree.create(DemoVar.notebook)\n\n    DemoVar.prgtext.value = \"Done\"\n    DemoVar.prgindic.numeric += 1\n\n    DemoVar.notebook.compute_size\n    DemoVar.notebook.pack(:fill=>:both, :expand=>true, :padx=>4, :pady=>4)\n    DemoVar.notebook.raise(DemoVar.notebook.get_page(0))\n\n    DemoVar.mainframe.pack(:fill=>:both, :expand=>true)\n\n    Tk.update_idletasks\n\n    intro.destroy\n  end\n\n  def update_font(newfont)\n    root = Tk.root\n    root[:cursor] = 'watch'\n    if newfont != '' && DemoVar.font != newfont\n      DemoVar._wfont[:font] = newfont\n      DemoVar.notebook[:font] = newfont\n      DemoVar.font = newfont\n    end\n    root[:cursor] = ''\n  end\n\n  def _create_intro\n    top = TkToplevel.new(:relief=>:raised, :borderwidth=>2)\n    top.withdraw\n    top.overrideredirect(true)\n\n    ximg  = TkLabel.new(top, :bitmap=>\"@#{File.join(DEMODIR,'x1.xbm')}\", \n                        :foreground=>'grey90', :background=>'white')\n    bwimg = TkLabel.new(ximg, :bitmap=>\"@#{File.join(DEMODIR,'bwidget.xbm')}\",\n                        :foreground=>'grey90', :background=>'white')\n    frame = TkFrame.new(ximg, :background=>'white')\n    TkLabel.new(frame, :text=>'Loading demo', \n                :background=>'white', :font=>'times 8').pack\n    TkLabel.new(frame, :textvariable=>DemoVar.prgtext, \n                :background=>'white', :font=>'times 8', :width=>35).pack\n    Tk::BWidget::ProgressBar.new(frame, :width=>50, :height=>10, \n                                 :background=>'white', \n                                 :variable=>DemoVar.prgindic, \n                                 :maximum=>10).pack\n    frame.place(:x=>0, :y=>0, :anchor=>:nw)\n    bwimg.place(:relx=>1, :rely=>1, :anchor=>:se)\n    ximg.pack\n    Tk::BWidget.place(top, 0, 0, :center)\n    top.deiconify\n\n    top\n  end\nend\n\nmodule DemoVar\n  Demo = BWidget_Demo.new\nend\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/dnd.rb",
    "content": "#\n#  dnd demo  ---  called from demo.rb\n#\nunless Object.const_defined?('DemoVar')\n  fail RuntimeError, \"This is NOT a stand alone script. This script is called from 'demo.rb'. \"\nend\n\nmodule DemoDnD\n  def self.create(nb)\n    frame = nb.insert('end', 'demoDnD', :text=>'Drag and Drop')\n\n    titf1 = Tk::BWidget::TitleFrame.new(frame, :text=>'Drag source')\n    subf = titf1.get_frame\n\n    ent1 = Tk::BWidget::LabelEntry.new(subf, :label=>'Entry', \n                                       :labelwidth=>14, :dragenabled=>true, \n                                       :dragevent=>3)\n    labf1 = Tk::BWidget::LabelFrame.new(subf, :text=>'Label (text)', \n                                        :width=>14)\n    f = labf1.get_frame\n    lab = Tk::BWidget::Label.new(f, :text=>'Drag this text', \n                                 :dragenabled=>true, :dragevent=>3).pack\n\n    labf2 = Tk::BWidget::LabelFrame.new(subf, :text=>'Label (bitmap)', \n                                        :width=>14)\n    f = labf2.get_frame\n    lab = Tk::BWidget::Label.new(f, :bitmap=>'info', \n                                 :dragenabled=>true, :dragevent=>3).pack\n\n    Tk.pack(ent1, labf1, labf2, :side=>:top, :fill=>:x, :pady=>4)\n\n    titf2 = Tk::BWidget::TitleFrame.new(frame, :text=>'Drop targets')\n    subf = titf2.get_frame\n\n    ent1 = Tk::BWidget::LabelEntry.new(subf, :label=>'Entry', \n                                       :labelwidth=>14, :dropenabled=>true)\n    labf1 = Tk::BWidget::LabelFrame.new(subf, :text=>'Label', :width=>14)\n    f = labf1.get_frame\n    lab = Tk::BWidget::Label.new(f, :dropenabled=>true, \n                                 :highlightthickness=>1).pack(:fill=>:x)\n    Tk.pack(ent1, labf1, :side=>:top, :fill=>:x, :pady=>4)\n    Tk.pack(titf1, titf2, :pady=>4)\n\n    frame\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/manager.rb",
    "content": "#\n#  manager demo  ---  called from demo.rb\n#\nunless Object.const_defined?('DemoVar')\n  fail RuntimeError, \"This is NOT a stand alone script. This script is called from 'demo.rb'. \"\nend\n\nmodule DemoManager\n  @@progress    = TkVariable.new(false)\n  @@status      = TkVariable.new('Compute in progress...')\n  @@homogeneous = TkVariable.new(false)\n  @@constw      = TkVariable.new\n  @@afterobj    = nil\n\n  def self.create(nb)\n    frame = nb.insert('end', 'demoManager', :text=>'Manager')\n\n    topf = TkFrame.new(frame)\n    titf1 = Tk::BWidget::TitleFrame.new(topf, :text=>\"MainFrame\")\n    titf2 = Tk::BWidget::TitleFrame.new(topf, :text=>\"NoteBook\")\n    titf3 = Tk::BWidget::TitleFrame.new(frame, :text=>\"Paned & ScrolledWindow\")\n\n    _mainframe(titf1.get_frame)\n    _notebook(titf2.get_frame)\n    _paned(titf3.get_frame)\n\n    Tk.pack(titf1, titf2, :padx=>4, :side=>:left, :fill=>:both, :expand=>true)\n    Tk.pack(topf, :fill=>:x, :pady=>2)\n    Tk.pack(titf3, :pady=>2, :padx=>4, :fill=>:both, :expand=>true)\n\n    frame\n  end\n\n  def self._mainframe(parent)\n    labf1 = Tk::BWidget::LabelFrame.new(parent, :text=>'Toolbar', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>2)\n    subf = labf1.get_frame\n    chk1 = TkCheckbutton.new(subf, :text=>'View toolbar 1', \n                             :variable=>DemoVar.toolbar1, \n                             :command=>proc{\n                               DemoVar.mainframe.show_toolbar(\n                                  0, DemoVar.toolbar1.value\n                               )\n                             })\n    chk2 = TkCheckbutton.new(subf, :text=>'View toolbar 2', \n                             :variable=>DemoVar.toolbar2, \n                             :command=>proc{\n                               DemoVar.mainframe.show_toolbar(\n                                  1, DemoVar.toolbar2.value\n                               )\n                             })\n\n    Tk.pack(chk1, chk2, :anchor=>:w, :fill=>:x)\n    labf1.pack(:fill=>:both)\n\n    labf2 = Tk::BWidget::LabelFrame.new(parent, :text=>'Status bar', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>2)\n    subf = labf2.get_frame\n    chk1 = TkCheckbutton.new(subf, :text=>\"Show Progress\\nindicator\", \n                             :justify=>:left, :variable=>@@progress, \n                             :command=>proc{ _show_progress })\n    chk1.pack(:anchor=>:w, :fill=>:x)\n\n    Tk.pack(labf1, labf2, :side=>:left, :padx=>4, :fill=>:both)\n  end\n\n  def self._notebook(parent)\n    TkCheckbutton.new(parent, :text=>'Homogeneous label', \n                      :variable=>@@homogeneous, \n                      :command=>proc{\n                        DemoVar.notebook[:homogeneous] = @@homogeneous.value\n                      }).pack(:side=>:left, :anchor=>:n, :fill=>:x)\n  end\n\n  def self._paned(parent)\n    pw1   = Tk::BWidget::PanedWindow.new(parent, :side=>:top)\n    pane  = pw1.add(:minsize=>100)\n\n    pw2   = Tk::BWidget::PanedWindow.new(pane, :side=>:left)\n    pane1 = pw2.add(:minsize=>100)\n    pane2 = pw2.add(:minsize=>100)\n\n    pane3 = pw1.add(:minsize=>100)\n\n    [pane1, pane2].each{|pane|\n      sw = Tk::BWidget::ScrolledWindow.new(pane)\n      lb = TkListbox.new(sw, :height=>8, :width=>20, :highlightthickness=>0)\n      (1..8).each{|i| lb.insert('end', \"Valur #{i}\") }\n      sw.set_widget(lb)\n      sw.pack(:fill=>:both, :expand=>true)\n    }\n\n    sw = Tk::BWidget::ScrolledWindow.new(pane3, :relief=>:sunken, \n                                         :borderwidth=>2)\n    sf = Tk::BWidget::ScrollableFrame.new(sw)\n    sw.set_widget(sf)\n    subf = sf.get_frame\n    lab = TkLabel.new(subf, :text=>'This is a ScrollableFrame')\n    chk = TkCheckbutton.new(subf, :text=>'Constrained with', \n                            :variable=>@@constw, :command=>proc{\n                              sf['constrainedwidth'] = @@constw.value\n                            })\n    lab.pack\n    chk.pack(:anchor=>:w)\n    chk.bind('FocusIn', proc{sf.see(chk)})\n    (0..20).each{|i|\n      ent = TkEntry.new(subf, :width=>50).pack(:fill=>:x, :pady=>4)\n      ent.bind('FocusIn', proc{sf.see(ent)})\n      ent.insert('end', \"Text field #{i}\")\n    }\n\n    Tk.pack(sw, pw2, pw1, :fill=>:both, :expand=>true)\n  end\n\n  def self._show_progress\n    unless @@afterobj\n      @@afterobj = TkTimer.new(30, -1, proc{_update_progress})\n    end\n    if @@progress.bool\n      DemoVar.status.value = 'Compute in progress...'\n      DemoVar.prgindic.value = 0\n      DemoVar.mainframe.show_statusbar(:progression)\n      @@afterobj.start unless @@afterobj.running?\n    else\n      DemoVar.status.value = ''\n      DemoVar.mainframe.show_statusbar(:status)\n      @@afterobj.stop\n    end\n  end\n\n  def self._update_progress\n    if @@progress.bool\n      if DemoVar.prgindic.numeric < 100\n        DemoVar.prgindic.numeric += 5\n      else\n        @@progress.value = false\n        DemoVar.mainframe.show_statusbar(:status)\n        DemoVar.status.value = 'Done'\n        @@afterobj.stop\n        Tk.after(500, proc{ DemoVar.status.value = '' })\n      end\n    else\n      @@afterobj.stop\n    end\n  end\n\nend\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/select.rb",
    "content": "#\n#  select demo  ---  called from demo.rb\n#\nunless Object.const_defined?('DemoVar')\n  fail RuntimeError, \"This is NOT a stand alone script. This script is called from 'demo.rb'. \"\nend\n\nmodule DemoSelect\n  @@var = TkVariable.new_hash\n\n  def self.create(nb)\n    frame = nb.insert('end', 'demoSelect', :text=>'Spin & Combo')\n\n    titf1 = Tk::BWidget::TitleFrame.new(frame, :text=>'SpinBox')\n    subf = titf1.get_frame\n    spin = Tk::BWidget::SpinBox.new(subf, :range=>[1, 100, 1], \n                                    :textvariable=>@@var.ref('spin', 'var'), \n                                    :helptext=>'This is the SpinBox')\n    ent = Tk::BWidget::LabelEntry.new(subf, :label=>'Linked var', \n                                      :labelwidth=>10, :labelanchor=>:w,  \n                                      :textvariable=>@@var.ref('spin', 'var'), \n                                      :editable=>0, \n                                      :helptext=>\"This is an Entry reflecting\\nthe linked var of SpinBox\")\n    labf = Tk::BWidget::LabelFrame.new(subf, :text=>'Options', \n                                       :side=>:top, :anchor=>:w, \n                                       :relief=>:sunken, :borderwidth=>1, \n                                       :helptext=>'Modify some options of SpinBox')\n    subf = labf.get_frame\n    chk1 = TkCheckbutton.new(subf, :text=>'Non editable', \n                             :variable=>@@var.ref('spin', 'editable'), \n                             :onvalue=>false, :offvalue=>true, \n                             :command=>proc{\n                               spin.editable(@@var['spin', 'editable'])\n                             })\n    chk2 = TkCheckbutton.new(subf, :text=>'Disabled', \n                             :variable=>@@var.ref('spin', 'state'), \n                             :onvalue=>'disabled', :offvalue=>'normal', \n                             :command=>proc{\n                               spin.state(@@var['spin', 'state'])\n                             })\n    Tk.pack(chk1, chk2, :side=>:left, :anchor=>:w)\n    Tk.pack(spin, ent, labf, :pady=>4, :fill=>:x)\n    titf1.pack\n\n    titf2 = Tk::BWidget::TitleFrame.new(frame, :text=>'ComboBox')\n    subf = titf2.get_frame\n    combo = Tk::BWidget::ComboBox.new(subf,\n                                      :textvariable=>@@var.ref('combo', 'var'),\n                                      :values=>[\n                                        'first value', 'second value', \n                                        'third value', 'fourth value', \n                                        'fifth value'\n                                      ], \n                                      :helptext=>'This is the ComboBox')\n    ent = Tk::BWidget::LabelEntry.new(subf, :label=>'Linked var', \n                                      :labelwidth=>10, :labelanchor=>:w, \n                                      :textvariable=>@@var.ref('combo', 'var'),\n                                      :editable=>0, :helptext=>\"This is an Entry reflecting\\nthe linked var of ComboBox\")\n    labf = Tk::BWidget::LabelFrame.new(subf, :text=>'Options', :side=>:top, \n                                       :anchor=>:w, :relief=>:sunken, \n                                       :borderwidth=>1, :helptext=>'Modify some options of ComboBox')\n    subf = labf.get_frame\n    chk1 = TkCheckbutton.new(subf, :text=>'Non editable', \n                             :variable=>@@var.ref('combo', 'editable'), \n                             :onvalue=>false, :offvalue=>true, \n                             :command=>proc{\n                               combo.editable(@@var['combo', 'editable'])\n                             })\n    chk2 = TkCheckbutton.new(subf, :text=>'Disabled', \n                             :variable=>@@var.ref('combo', 'state'), \n                             :onvalue=>'disabled', :offvalue=>'normal', \n                             :command=>proc{\n                               combo.state(@@var['combo', 'state'])\n                             })\n\n    Tk.pack(chk1, chk2, :side=>:left, :anchor=>:w)\n    Tk.pack(combo, ent, labf, :pady=>4, :fill=>:x)\n    Tk.pack(titf1, titf2, :pady=>4)\n\n    frame\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/tmpldlg.rb",
    "content": "#\n#  templdlg demo  ---  called from demo.rb\n#\nunless Object.const_defined?('DemoVar')\n  fail RuntimeError, \"This is NOT a stand alone script. This script is called from 'demo.rb'. \"\nend\n\nmodule DemoDialog\n  @@tmpl      = TkVariable.new_hash\n  @@msg       = TkVariable.new_hash\n  @@msgdlg    = nil\n  @@progmsg   = TkVariable.new\n  @@progval   = TkVariable.new\n  @@progdlg   = nil\n  @@resources = TkVariable.new('en')\n\n  def self.create(nb)\n    frame = nb.insert('end', 'demoDlg', :text=>'Dialog')\n\n    titf1 = Tk::BWidget::TitleFrame.new(frame, :text=>'Resources')\n    titf2 = Tk::BWidget::TitleFrame.new(frame, :text=>'Template Dialog')\n    titf3 = Tk::BWidget::TitleFrame.new(frame, :text=>'Message Dialog')\n    titf4 = Tk::BWidget::TitleFrame.new(frame, :text=>'Other dialog')\n\n    subf = titf1.get_frame\n    cmd = proc{ TkOption.read_file(File.join(Tk::BWidget::LIBRARY, 'lang', \n                                             @@resources.value + '.rc')) }\n    Tk.pack(TkRadiobutton.new(subf, :text=>'English', :value=>'en', \n                              :variable=>@@resources, :command=>cmd), \n            TkRadiobutton.new(subf, :text=>'French', :value=>'fr', \n                              :variable=>@@resources, :command=>cmd), \n            TkRadiobutton.new(subf, :text=>'German', :value=>'de', \n                              :variable=>@@resources, :command=>cmd), \n            :side=>:left)\n\n    _tmpldlg(titf2.get_frame)\n    _msgdlg(titf3.get_frame)\n    _stddlg(titf4.get_frame)\n\n    titf1.pack(:fill=>:x, :pady=>2, :padx=>2)\n    titf4.pack(:side=>:bottom, :fill=>:x, :pady=>2, :padx=>2)\n    Tk.pack(titf2, titf3, :side=>:left, :padx=>2, :fill=>:both, :expand=>true)\n  end\n\n  def self._tmpldlg(parent)\n    @@tmpl['side'] = :bottom\n    @@tmpl['anchor'] = :c\n\n    labf1 = Tk::BWidget::LabelFrame.new(parent, :text=>'Button side', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>1)\n    subf = labf1.get_frame\n    Tk.pack(TkRadiobutton.new(subf, :text=>'Bottom', :value=>:bottom, \n                              :variable=>@@tmpl.ref('side'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Left', :value=>:left, \n                              :variable=>@@tmpl.ref('side'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Right', :value=>:right, \n                              :variable=>@@tmpl.ref('side'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Top', :value=>:top, \n                              :variable=>@@tmpl.ref('side'), :anchor=>:w), \n            :fill=>:x, :anchor=>:w)\n\n    labf2 = Tk::BWidget::LabelFrame.new(parent, :text=>'Button anchor', \n                                        :side=>:top, :anchor=>:w, \n                                        :relief=>:sunken, :borderwidth=>1)\n    subf = labf2.get_frame\n    Tk.pack(TkRadiobutton.new(subf, :text=>'North', :value=>:n, \n                              :variable=>@@tmpl.ref('anchor'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'West', :value=>:w, \n                              :variable=>@@tmpl.ref('anchor'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'East', :value=>:e, \n                              :variable=>@@tmpl.ref('anchor'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'South', :value=>:s, \n                              :variable=>@@tmpl.ref('anchor'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Center', :value=>:c, \n                              :variable=>@@tmpl.ref('anchor'), :anchor=>:w), \n            :fill=>:x, :anchor=>:w)\n\n    sep = Tk::BWidget::Separator.new(parent, :orient=>:horizontal)\n    button = TkButton.new(parent, :text=>'Show', :command=>proc{_show_tmpldlg})\n\n    button.pack(:side=>:bottom)\n    sep.pack(:side=>:bottom, :fill=>:x, :pady=>10)\n    Tk.pack(labf1, labf2, :side=>:left, :padx=>4, :anchor=>:n)\n  end\n\n  def self._msgdlg(parent)\n    @@msg['type'] = 'ok'\n    @@msg['icon'] = 'info'\n\n    labf1 = Tk::BWidget::LabelFrame.new(parent, :text=>'Type', :side=>:top, \n                                        :anchor=>:w, :relief=>:sunken, \n                                        :borderwidth=>1)\n    subf = labf1.get_frame\n    Tk.pack(TkRadiobutton.new(subf, :text=>'Ok', :value=>'ok', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Ok, Cancel', :value=>'okcancel', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Retry, Cancel', \n                              :value=>'retrycancel', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Yes, No', :value=>'yesno', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Yes, No, Cancel', \n                              :value=>'yesnocancel', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Abort, Retry, Ignore', \n                              :value=>'abortretryignore', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            :fill=>:x, :anchor=>:w)\n\n    Tk.pack(TkRadiobutton.new(subf, :text=>'User', :value=>'user', \n                              :variable=>@@msg.ref('type'), :anchor=>:w), \n            Tk::BWidget::Entry.new(subf, :textvariable=>@@msg.ref('buttons')),\n            :side=>:left)\n\n    labf2 = Tk::BWidget::LabelFrame.new(parent, :text=>'Icon', :side=>:top, \n                                        :anchor=>:w, :relief=>:sunken, \n                                        :borderwidth=>1)\n    subf = labf2.get_frame\n    Tk.pack(TkRadiobutton.new(subf, :text=>'Information', :value=>'info', \n                              :variable=>@@msg.ref('icon'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Question',    :value=>'question', \n                              :variable=>@@msg.ref('icon'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Warning',     :value=>'warning', \n                              :variable=>@@msg.ref('icon'), :anchor=>:w), \n            TkRadiobutton.new(subf, :text=>'Error',       :value=>'error', \n                              :variable=>@@msg.ref('icon'), :anchor=>:w), \n            :fill=>:x, :anchor=>:w)\n\n    sep = Tk::BWidget::Separator.new(parent, :orient=>:horizontal)\n    button = TkButton.new(parent, :text=>'Show', :command=>proc{_show_msgdlg})\n\n    button.pack(:side=>:bottom)\n    sep.pack(:side=>:bottom, :fill=>:x, :pady=>10)\n    Tk.pack(labf1, labf2, :side=>:left, :padx=>4, :anchor=>:n)\n  end\n\n  def self._stddlg(parent)\n    Tk.pack(TkButton.new(parent, :text=>'Select a color '){|w|\n              command(proc{DemoDialog._show_color(w)})\n            }, \n            TkButton.new(parent, :text=>'Font selector dialog', \n                         :command=>proc{_show_fontdlg}), \n            TkButton.new(parent, :text=>'Progression dialog', \n                         :command=>proc{_show_progdlg}), \n            TkButton.new(parent, :text=>'Password dialog', \n                         :command=>proc{_show_passdlg}), \n            :side=>:left, :padx=>5, :anchor=>:w)\n  end\n\n  def self._show_color(w)\n    dlg = Tk::BWidget::SelectColor.new(w, :color=>w.background)\n    color = dlg.menu([:below, w])\n    unless color.empty?\n      w.background(color)\n    end\n  end\n\n  def self._show_tmpldlg\n    dlg = Tk::BWidget::Dialog.new(:relative=>Tk.root, :modal=>:local, \n                                  :separator=>true, :title=>'Template dialog', \n                                  :side=>@@tmpl['side'], \n                                  :anchor=>@@tmpl['anchor'], \n                                  :default=>0, :cancel=>1)\n    dlg.add('name'=>'ok')\n    dlg.add('name'=>'cancel')\n    TkMessage.new(dlg.get_frame, :text=>\"Template\\nDialog\", :justify=>:center, \n                  :anchor=>:c, :width=>80).pack(:fill=>:both, :expand=>true, \n                                                :padx=>100, :pady=>100)\n    dlg.draw\n    dlg.destroy\n  end\n\n  def self._show_msgdlg\n    @@msgdlg.destroy if @@msgdlg\n    @@msgdlg = Tk::BWidget::MessageDlg.new(:relative=>Tk.root, \n                                           :message=>'Message for MessageBox', \n                                           :type=>@@msg['type'], \n                                           :icon=>@@msg['icon'], \n                                           :buttons=>@@msg['buttons'])\n    @@msgdlg.create\n  end\n\n  def self._show_fontdlg\n    font = Tk::BWidget::SelectFont.new(:relative=>Tk.root, \n                                       :font=>DemoVar.font).create\n    DemoVar::Demo.update_font(font)\n  end\n\n  def self._show_progdlg\n    @@progmsg.value = \"Compute in progress...\"\n    @@progval.value = 0\n\n    @@progdlg = Tk::BWidget::ProgressDlg.new(:relative=>Tk.root, \n                                             :title=>'Wait...', \n                                             :type=>'infinite', :width=>20, \n                                             :textvariable=>@@progmsg, \n                                             :variable=>@@progval, \n                                             :stop=>'Stop') {\n      command(proc{self.destroy})\n      create\n    }\n    _update_progdlg\n  end\n\n  def self._update_progdlg\n    TkTimer.new(20, -1, proc{\n                  if @@progdlg && @@progdlg.winfo_exist?\n                    @@progval.value = 2\n                  else\n                    stop\n                  end\n                }).start\n  end\n\n  def self._show_passdlg\n    Tk::BWidget::PasswdDlg.new(:relative=>Tk.root).create\n  end\nend\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/tree.rb",
    "content": "#\n#  templdlg demo  ---  called from demo.rb\n#\nunless Object.const_defined?('DemoVar')\n  fail RuntimeError, \"This is NOT a stand alone script. This script is called from 'demo.rb'. \"\nend\n\nmodule DemoTree\n  @@count = 0\n  @@dblclick = false\n  @@top = nil\n\n  def self.create(nb)\n    frame = nb.insert('end', 'demoTree', :text=>'Tree')\n    pw = Tk::BWidget::PanedWindow.new(frame, :side=>:top)\n\n    pane = pw.add(:weight=>1)\n    title = Tk::BWidget::TitleFrame.new(pane, :text=>'Directory tree')\n    sw = Tk::BWidget::ScrolledWindow.new(title.get_frame, \n                                         :relief=>:sunken, :borderwidth=>2)\n    tree = Tk::BWidget::Tree.new(sw, :relief=>:flat, :borderwidth=>0, \n                                 :width=>15, :highlightthickness=>0, \n                                 :redraw=>false, :dropenabled=>true, \n                                 :dragenabled=>true, :dragevent=>3, \n                                 :droptypes=>[\n                                   'TREE_NODE', [\n                                     :copy, [], \n                                     :move, [],\n                                     :link, []\n                                   ], \n                                   'LISTBOX_ITEM', [\n                                     :copy, [], \n                                     :move, [],\n                                     :link, []\n                                   ]\n                                 ], \n                                 :opencmd=>proc{|node| \n                                   moddir(1, tree, node)\n                                 }, \n                                 :closecmd=>proc{|node| \n                                   moddir(0, tree, node)\n                                 })\n    sw.set_widget(tree)\n\n    sw.pack(:side=>:top, :expand=>true, :fill=>:both)\n    title.pack(:fill=>:both, :expand=>true)\n\n    pane = pw.add(:weight=>2)\n    lf = Tk::BWidget::TitleFrame.new(pane, :text=>'Content')\n    sw = Tk::BWidget::ScrolledWindow.new(lf.get_frame, \n                                         :scrollbar=>:horizontal, \n                                         :auto=>:none, :relief=>:sunken, \n                                         :borderwidth=>2)\n\n    list = Tk::BWidget::ListBox.new(sw, :relief=>:flat, :borderwidth=>0, \n                                    :highlightthickness=>0, :width=>20, \n                                    :multicolumn=>true, :redraw=>false, \n                                    :dragevent=>3, :dropenabled=>true, \n                                    :dragenabled=>true, \n                                 :droptypes=>[\n                                      'TREE_NODE', [\n                                        :copy, [], \n                                        :move, [],\n                                        :link, []\n                                      ], \n                                      'LISTBOX_ITEM', [\n                                        :copy, [], \n                                        :move, [],\n                                        :link, []\n                                      ]\n                                    ])\n    sw.set_widget(list)\n\n    Tk.pack(sw, lf, :fill=>:both, :expand=>true)\n\n    pw.pack(:fill=>:both, :expand=>true)\n\n    tree.textbind('ButtonPress-1',\n                  proc{|node, ev| select('tree', 1, tree, list, node)})\n    tree.textbind('Double-ButtonPress-1', \n                  proc{|node, ev| select('tree', 2, tree, list, node)})\n\n    list.textbind('ButtonPress-1',\n                  proc{|node, ev| select('list', 1, tree, list, node)})\n    list.textbind('Double-ButtonPress-1', \n                  proc{|node, ev| select('list', 2, tree, list, node)})\n\n    list.imagebind('Double-ButtonPress-1', \n                   proc{|node, ev| select('list', 2, tree, list, node)})\n\n    nb.itemconfigure('demoTree', \n                     :createcmd=>proc{|*args| init(tree, list, *args)}, \n                     :raisecmd=>proc{\n                       Tk.root.geometry =~ \n                         /\\d+x\\d+([+-]{1,2}\\d+)([+-]{1,2}\\d+)/\n                       global_w = ($1 || 0).to_i\n                       global_h = ($2 || 0).to_i\n                       if @@top\n                         Tk::BWidget.place(@@top, 0, 0, :at, \n                            global_w - Tk.root.winfo_screenwidth, global_h)\n                         @@top.deiconify\n                         Tk.root.bind('Unmap', proc{@@top.withdraw})\n                         Tk.root.bind('Map',   proc{@@top.deiconify})\n                         Tk.root.bind('Configure', proc{|w|\n                                if w == Tk.root\n                                  Tk.root.geometry =~ \n                                    /\\d+x\\d+([+-]{1,2}\\d+)([+-]{1,2}\\d+)/\n                                  global_w = ($1 || 0).to_i\n                                  global_h = ($2 || 0).to_i\n                                  Tk::BWidget.place(@@top, 0, 0, :at, \n                                       global_w - Tk.root.winfo_screenwidth, \n                                       global_h)\n                                end\n                         }, '%W')\n                       end\n                     }, \n                     :leavecmd=>proc{\n                       @@top.withdraw if @@top\n                       Tk.root.bind_remove('Unmap')\n                       Tk.root.bind_remove('Map')\n                       Tk.root.bind_remove('Configure')\n                       true\n                     })\n  end\n\n  def self.init(tree, list, *args)\n    @@count = 0\n    if Tk::PLATFORM['platform'] == 'unix'\n      rootdir = File.expand_path('~')\n    else\n      rootdir = 'c:'\n    end\n\n    tree.insert('end', 'root', 'home', \n                :text=>rootdir, :data=>rootdir, :open=>true, \n                :image=>Tk::BWidget::Bitmap.new('openfold'))\n    getdir(tree, 'home', rootdir)\n    select('tree', 1, tree, list, 'home')\n    tree.redraw(true)\n    list.redraw(true)\n\n    @@top = TkToplevel.new\n    @@top.withdraw\n    @@top.protocol('WM_DELETE_WINDOW'){\n      # don't kill me\n    }\n    @@top.resizable(false, false)\n    @@top.title('Drag rectangle to scroll directory tree')\n    @@top.transient(Tk.root)\n    Tk::BWidget::ScrollView.new(@@top, :window=>tree, :fill=>'white', \n                                :width=>300, :height=>300, :relief=>:sunken, \n                                :bd=>1).pack(:fill=>:both, :expand=>true)\n  end\n\n  def self.getdir(tree, node, path)\n    lentries = Dir.glob(File.join(path, '*')).sort\n    lfiles = []\n    lentries.each{|f|\n      basename = File.basename(f)      \n      if File.directory?(f)\n        Tk::BWidget::Tree::Node.new(tree, node, \n                                    :index=>'end', :text=>basename, \n                                    :image=>Tk::BWidget::Bitmap.new('folder'), \n                                    :drawcross=>:allways, :data=>f)\n        @@count += 1\n      else\n        lfiles << basename\n      end\n    }\n    tree.itemconfigure(node, :drawcross=>:auto, :data=>lfiles)\n  end\n\n  def self.moddir(idx, tree, node)\n    if (idx != 0 && tree.itemcget(node, :drawcross).to_s == 'allways')\n      getdir(tree, node, tree.itemcget(node, :data))\n      if tree.nodes(node).empty?\n        tree.itemconfigure(node, :image=>Tk::BWidget::Bitmap.new('folder'))\n      else\n        tree.itemconfigure(node, :image=>Tk::BWidget::Bitmap.new('openfold'))\n      end\n    else\n      img = %w(folder openfold)[idx] || 'openfold'\n      tree.itemconfigure(node, :image=>Tk::BWidget::Bitmap.new(img))\n    end\n  end\n\n  def self.select(where, num, tree, list, node)\n    @@dblclick = true\n    if num == 1\n      if (where == 'tree' && \n          tree.selection_get.find{|x|\n            TkUtil._get_eval_string(x) == TkUtil._get_eval_string(node)\n          })\n        @@dblclick = false\n        Tk.after(500, proc{edit('tree', tree, list, node)})\n        return\n      end\n      if (where == 'list' && \n          list.selection_get.find{|x|\n            TkUtil._get_eval_string(x) == TkUtil._get_eval_string(node)\n          })\n        @@dblclick = false\n        Tk.after(500, proc{edit('list', tree, list, node)})\n        return\n      end\n      if where == 'tree'\n        select_node(tree, list, node)\n      else\n        list.selection_set(node)\n      end\n    elsif (where == 'list' && tree.exist?(node))\n      parent = tree.parent(node)\n      while TkUtil._get_eval_string(parent) != 'root'\n        tree.itemconfigure(parent, :open=>true)\n        parent = tree.parent(parent)\n      end\n      select_node(tree, list, node)\n    end\n  end\n\n  def self.select_node(tree, list, node)\n    tree.selection_set(node)\n    Tk.update\n    list.delete(*(list.items(0, 'end')))\n\n    dir = tree.itemcget(node, :data)\n    if tree.itemcget(node, :drawcross).to_s == 'allways'\n      getdir(tree, node, dir)\n      dir = tree.itemcget(node, :data)\n    end\n\n    tree.nodes(node).each{|subnode|\n      list.insert('end', subnode, \n                  :text=>tree.itemcget(subnode, :text), \n                  :image=>Tk::BWidget::Bitmap.new('folder'))\n    }\n\n    TkComm.simplelist(dir).each{|f|\n      Tk::BWidget::ListBox::Item.new(list, 'end', :text=>f, \n                                     :image=>Tk::BWidget::Bitmap.new('file'))\n    }\n  end\n\n  def self.edit(where, tree, list, node)\n    return if @@dblclick\n\n    if (where == 'tree' && \n        tree.selection_get.find{|x|\n          TkUtil._get_eval_string(x) == TkUtil._get_eval_string(node)\n        })\n      res = tree.edit(node, tree.itemcget(node, :text))\n      if res != ''\n        tree.itemconfigure(node, :text=>res)\n        if list.exist?(node)\n          list.itemconfigure(node, :text=>res)\n        end\n        tree.selection_set(node)\n      end\n      return\n    end\n\n    if (where == 'list')\n      res = list.edit(node, list.igemcget(node, :text))\n      if res != ''\n        list.itemconfigure(node, :text=>res)\n        if tree.exist?(node)\n          tree.itemconfigure(node, :text=>res)\n        else\n          cursel = tree.selection_get[0]\n          index  = list.index(node) - tree.nodes(cursel).size\n          data   = TkComm.simplelist(tree.itemcget(cursel, :data))\n          data[index] = res\n          tree.itemconfigure(cursel, :date=>data)\n        end\n        list.selection_set(node)\n      end\n    end\n  end\n\n  def self.expand(tree, but)\n    unless (cur = tree.selection_get).empty?\n      if TkComm.bool(but)\n        tree.opentree(cur)\n      else\n        tree.closetree(cur)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/bwidget/x1.xbm",
    "content": "#define x1_width 626\n#define x1_height 428\nstatic char x1_bits[] = {\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0x03,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x80,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x03,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x3f,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xe0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xc0,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x80,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0x03,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x07,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0x01,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x07,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x03,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0xf8,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0x3f,0x00,0x00,0x00,0xc0,0xff,0xff,0x03,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x3f,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0x1f,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0xfc,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xfe,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0x07,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,\n 0xf8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0x00,0xfe,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x80,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xc0,0xff,0x07,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,\n 0x00,0x00,0x00,0x00,0xf8,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0xfc,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0xfe,0xff,0x0f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x80,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xc0,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0x3f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x1f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x07,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x0f,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xf0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x80,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x80,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xf8,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0x03,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0x01,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x01,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x00,0x00,0x00,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0xff,0x7f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0x3f,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0x1f,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0xff,0x1f,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0x0f,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0x07,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0x07,0x00,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0x03,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0x01,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0x01,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x07,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0x7f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0x7f,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0xe0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x0f,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,\n 0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x80,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x07,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x80,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x06,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xfd,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,\n 0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0xfc,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,0x00,0x00,0x00,\n 0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0xfc,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0xfc,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xfc,0x00,0x00,0x00,0x00,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xfc,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0xfc,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0xfc,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xfc,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xfc,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0xfc,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0xfc,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0xfc,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0xfc,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0xfc,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xfc,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xfc,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0xfc,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0xfc,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xfc,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0xfc,0x00,0x00,\n 0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,\n 0x00,0xfc,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0xfc,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xfc,0x00,0x00,0xe0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xfc,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0xfc,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0xfc,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0xfc,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0xfc,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x0f,0x00,0xfc,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0x00,0xfc,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0xfc,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,\n 0xfc,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0xfc,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0xfc,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0xfc,0x00,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0xfc,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0xfc,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0xfc,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0xfc,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,\n 0x00,0x00,0xfc,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0xfc,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xfc,0x00,0xf0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xfc,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0xfc,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xfc,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xfc,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,\n 0xfc,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x03,0x00,0x00,0xfc,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xfc,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xfc,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0xfc,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0xfc,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0xfc,0x00,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xfc,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0xfc,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0xfc,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xfc,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xfc,\n 0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0x00,0xfc,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xfc,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xfc,0xe0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0xfc,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0x00,0x00,0x00,0xfc,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xfc,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xfc,0xf0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,\n 0x00,0xfc,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0xfc,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0xfc,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0xfc,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,\n 0x00,0x00,0x00,0xfc,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x0f,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x07,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0xc0,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xc0,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xe0,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x80,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0xf0,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x80,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xf8,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xfc,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,\n 0xfc,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0x00,0x00,0x00,0xfe,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x80,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x80,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0xc0,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xe0,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xf0,0xff,0xff,\n 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0x00,0xf8,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xfc,0xff,0xff,0x03,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xe0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0x07,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xf0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,\n 0xff,0xff,0x03,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0x01,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x3f,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x3f,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0x1f,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xf0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0x0f,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x07,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0x07,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0x01,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,\n 0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xe0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0x7f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x1f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0x03,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x03,0x00,\n 0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xc0,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0xf0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,\n 0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0x7f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xf8,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,\n 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xf0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xc0,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x01,0x00,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0x1f,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xc0,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0x7f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xf8,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0xfc,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x01,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfe,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x07,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,\n 0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xc0,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0xc0,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf8,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x1f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x80,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x3f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x80,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0xf8,\n 0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x01,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,\n 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x80,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,\n 0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x80,0x0f,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0xc0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x80,\n 0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n 0x00,0xfc};\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/catalog_demo/Orig_LICENSE.txt",
    "content": "\n  #######################################################################\n  ###  The following text is the original 'license.terms' of iwidges  ###\n  ###  extension.                                                     ###\n  ###  Original Tcl source files are not include in this directry,    ###\n  ###  because of all of them are rewrited to Ruby files.             ###\n  ###  However, the image data files in the 'images' directory are    ###\n  ###  quoted from iwidgets source archive.                           ###\n  #######################################################################\n\n\nThis software is copyrighted by DSC Technologies and private individual \ncontributors.  The copyright holder is specifically listed in the header \nof each file.  The following terms apply to all files associated with the\nsoftware unless explicitly disclaimed in individual files by private\ncontributors.\n\nCopyright 1997 DSC Technologies Corporation\n\nPermission to use, copy, modify, distribute and license this software and \nits documentation for any purpose, and without fee or written agreement \nwith DSC, is hereby granted, provided that the above copyright notice \nappears in all copies and that both the copyright notice and warranty \ndisclaimer below appear in supporting documentation, and that the names of\nDSC Technologies Corporation or DSC Communications Corporation not be used \nin advertising or publicity pertaining to the software without specific, \nwritten prior permission.\n\nDSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-INFRINGEMENT.\nTHIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND \nDISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,\nENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL DSC BE LIABLE FOR ANY\nSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER\nRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF\nCONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN\nCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\nRESTRICTED RIGHTS: Use, duplication or disclosure by the government\nis subject to the restrictions as set forth in subparagraph (c) (1) (ii)\nof the Rights in Technical Data and Computer Software Clause as DFARS\n252.227-7013 and FAR 52.227-19.\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/catalog_demo/images/box.xbm",
    "content": "#define Tool_32_box_width 32\n#define Tool_32_box_height 32\nstatic unsigned char Tool_32_box_bits[] = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x0f, 0x20, 0x00, 0x00, 0x08,\n  0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08,\n  0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08,\n  0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08,\n  0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08,\n  0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08,\n  0xe0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/catalog_demo/images/line.xbm",
    "content": "#define lineOp_width 32\n#define lineOp_height 32\nstatic unsigned char lineOp_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,\n   0xf0, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00,\n   0x80, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,\n   0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,\n   0x00, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00,\n   0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3c, 0x00,\n   0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0x01,\n   0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x0f,\n   0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/catalog_demo/images/oval.xbm",
    "content": "#define ovalOp_width 32\n#define ovalOp_height 32\nstatic unsigned char ovalOp_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00,\n   0x00, 0x1c, 0x70, 0x00, 0x00, 0x03, 0x80, 0x01, 0x80, 0x00, 0x00, 0x02,\n   0x40, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x10,\n   0x10, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20,\n   0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x10,\n   0x10, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x04,\n   0x80, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0x00, 0x1c, 0x70, 0x00,\n   0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/catalog_demo/images/points.xbm",
    "content": "#define dotPencilOp_width 32\n#define dotPencilOp_height 32\nstatic unsigned char dotPencilOp_bits[] = {\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x12, 0x00,\n  0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x80, 0x04, 0x00,\n  0x00, 0x80, 0x04, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,\n  0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00,\n  0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00,\n  0x00, 0x24, 0x00, 0x18, 0x00, 0x24, 0x00, 0x18, 0x00, 0x12, 0x00, 0x00,\n  0x00, 0x12, 0x00, 0x30, 0x00, 0x0e, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00,\n  0x00, 0x06, 0x0c, 0x30, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x30, 0xa0, 0x01,\n  0x00, 0x60, 0xb0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/catalog_demo/images/text.xbm",
    "content": "#define font_edit_width 32\n#define font_edit_height 32\nstatic unsigned char font_edit_bits[] = {\n  0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1c,\n  0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x7b,\n  0x00, 0x00, 0x80, 0x7e, 0x00, 0x00, 0xc0, 0xfd, 0x00, 0x00, 0x60, 0xfb,\n  0x00, 0x00, 0xb0, 0xf7, 0x00, 0x00, 0xd0, 0xef, 0x00, 0x00, 0xf8, 0xdf,\n  0x00, 0x00, 0xd4, 0x7f, 0x00, 0x00, 0xaa, 0x1f, 0x00, 0x00, 0x15, 0x0f,\n  0x00, 0x80, 0x82, 0x06, 0x03, 0x40, 0x01, 0x01, 0x07, 0xa0, 0x80, 0x00,\n  0x0f, 0x10, 0x40, 0x00, 0x1f, 0x08, 0x20, 0x00, 0x3b, 0xe4, 0x1f, 0x00,\n  0x73, 0x1a, 0x00, 0x00, 0xe3, 0x07, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x00,\n  0xe3, 0x03, 0x00, 0x00, 0x7b, 0x07, 0x00, 0x00, 0x1f, 0x06, 0x00, 0x00,\n  0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,\n  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/buttonbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n# sample 1\np bb1 = Tk::Iwidgets::Buttonbox.new\np bb1.add('Yes',   :text=>'Yes',   :command=>proc{puts 'Yes'})\np bb1.add('No',    :text=>'No',    :command=>proc{puts 'No'})\np bb1.add('Maybe', :text=>'Maybe', :command=>proc{puts 'Maybe'})\nbb1.default('Yes')\nbb1.pack(:expand=>true, :fill=>:both, :pady=>5)\nprint \"\\n\"\n\n# sample 2\np bb2 = Tk::Iwidgets::Buttonbox.new\np btn1 = bb2.add(:text=>'Yes',   :command=>proc{puts 'Yes'})\np btn2 = bb2.add(:text=>'No',    :command=>proc{puts 'No'})\np btn3 = bb2.add(:text=>'Maybe', :command=>proc{puts 'Maybe'})\nbb2.default(btn1)\nbb2.pack(:expand=>true, :fill=>:both, :pady=>5)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/calendar.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Calendar.new(:command=>proc{|arg| puts(arg.date)}, \n                           :weekendbackground=>'mistyrose', \n                           :weekdaybackground=>'ghostwhite', \n                           :outline=>'black', :startday=>'wednesday', \n                           :days=>%w(We Th Fr Sa Su Mo Tu)).pack\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/canvasprintbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Canvasprintbox.new(:orient=>:landscape, :stretch=>1) \\\n  .pack(:padx=>10, :pady=>10, :fill=>:both, :expand=>true)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/canvasprintdialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Canvasprintdialog.new.activate\n\nTk.mainloop\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/checkbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\ncb = Tk::Iwidgets::Checkbox.new\ncb.add('bold',      :text=>'Bold')\ncb.add('italic',    :text=>'Italic')\ncb.add('underline', :text=>'Underline')\ncb.select('underline')\ncb.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/combobox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n#\n# Non-editable Dropdown Combobox\n#\ncb1 = Tk::Iwidgets::Combobox.new(:labeltext=>'Month:', \n                                 :selectioncommand=>proc{\n                                   puts(cb1.get_curselection)\n                                 }, \n                                 :editable=>false, :listheight=>185, \n                                 :popupcursor=>'hand1')\n\ncb1.insert_list('end', *%w(Jan Feb Mar Apr May June Jul Aug Sept Oct Nov Dec))\n\n\n#\n# Editable Dropdown Combobox\n#\ncb2 = Tk::Iwidgets::Combobox.new(:labeltext=>'Operating System:', \n                                 :selectioncommand=>proc{\n                                   puts(cb2.get_curselection)\n                                 })\n\ncb2.insert_list('end', *%w(Linux HP-UX SunOS Solaris Irix))\ncb2.insert_entry('end', 'L')\n\ncb1.pack(:padx=>10, :pady=>10, :fill=>:x)\ncb2.pack(:padx=>10, :pady=>10, :fill=>:x)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/dateentry.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Dateentry.new.pack\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/datefield.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\ndf = Tk::Iwidgets::Datefield.new(:command=>proc{puts(df.get)})\ndf.pack(:fill=>:x, :expand=>true, :padx=>10,  :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/dialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nThread.new{Tk.mainloop}\n\nd = Tk::Iwidgets::Dialog.new(:modality=>:application)\n\nd.buttonconfigure('OK', :command=>proc{puts 'OK'; d.deactivate true})\nd.buttonconfigure('Apply', :command=>proc{puts 'Apply'})\nd.buttonconfigure('Cancel', :command=>proc{puts 'Cancel'; d.deactivate false})\nd.buttonconfigure('Help', :command=>proc{puts 'Help'})\n\nTkListbox.new(d.child_site, :relief=>:sunken).pack(:expand=>true, :fill=>:both)\n\nif TkComm.bool(d.activate)\n  puts \"Exit via OK button\"\nelse\n  puts \"Exit via Cancel button\"\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/dialogshell.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nds = Tk::Iwidgets::Dialogshell.new(:modality=>:none)\n\nds.add('OK', :text=>'OK', :command=>proc{puts 'OK'; ds.deactivate})\nds.add('Cancel', :text=>'Cancel', :command=>proc{puts 'Cancel'; ds.deactivate})\nds.default('OK')\n\nTkButton.new(:text=>'ACTIVATE', :padx=>7, :pady=>7, \n             :command=>proc{puts ds.activate}).pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/disjointlistbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\ndjl = Tk::Iwidgets::Disjointlistbox.new.pack(:fill=>:both, :expand=>true, \n                                             :padx=>10,  :pady=>10)\ndjl.set_lhs(*[0,2,4,5])\ndjl.set_rhs(3,6)\n\ndjl.insert_lhs(1,7,8)\ndjl.insert_rhs(9)\n\np djl.get_lhs\np djl.get_rhs\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/entryfield-1.rb",
    "content": "#!/usr/bin/env ruby\n#########################################################\n#\n#  use Tk::UTF8_String() for a utf8 charecter\n#\n#########################################################\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTkOption.add('*textBackground', 'white')\n\nef  = Tk::Iwidgets::Entryfield.new(:command=>proc{puts \"Return Pressed\"})\n\nfef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Fixed:', \n                                   :fixed=>10, :width=>12)\n\nnef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Numeric:', \n                                   :validate=>:numeric, :width=>12)\n\naef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Alphabetic:', \n                                   :validate=>:alphabetic, :width=>12, \n                                   :invalid=>proc{\n                                     puts \"Alphabetic contents invalid\"\n                                   })\n\npef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Password:', :width=>12, \n                                   :show=>Tk::UTF8_String(\"\\267\"),  \n                                                         ## <=== utf8 character\n                                   :command=>proc{puts \"Return Pressed\"})\n\nTk::Iwidgets::Labeledwidget.alignlabels(ef, fef, nef, aef, pef)\n\nef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\nfef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\nnef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\naef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\npef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/entryfield-2.rb",
    "content": "#!/usr/bin/env ruby\n#########################################################\n#\n#  set $KCODE to 'utf' for a utf8 charecter\n#\n#########################################################\n$KCODE='utf'\n\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTkOption.add('*textBackground', 'white')\n\nef  = Tk::Iwidgets::Entryfield.new(:command=>proc{puts \"Return Pressed\"})\n\nfef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Fixed:', \n                                   :fixed=>10, :width=>12)\n\nnef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Numeric:', \n                                   :validate=>:numeric, :width=>12)\n\naef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Alphabetic:', \n                                   :validate=>:alphabetic, :width=>12, \n                                   :invalid=>proc{\n                                     puts \"Alphabetic contents invalid\"\n                                   })\n\npef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Password:', :width=>12, \n                                   :show=>\"\\267\",  ## <=== utf8 character\n                                   :command=>proc{puts \"Return Pressed\"})\n\nTk::Iwidgets::Labeledwidget.alignlabels(ef, fef, nef, aef, pef)\n\nef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\nfef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\nnef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\naef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\npef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/entryfield-3.rb",
    "content": "#!/usr/bin/env ruby\n#########################################################\n#\n#  set Tk.encoding = 'utf-8' for a utf8 charecter\n#\n#########################################################\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk.encoding = 'utf-8'\n\nTkOption.add('*textBackground', 'white')\n\nef  = Tk::Iwidgets::Entryfield.new(:command=>proc{puts \"Return Pressed\"})\n\nfef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Fixed:', \n                                   :fixed=>10, :width=>12)\n\nnef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Numeric:', \n                                   :validate=>:numeric, :width=>12)\n\naef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Alphabetic:', \n                                   :validate=>:alphabetic, :width=>12, \n                                   :invalid=>proc{\n                                     puts \"Alphabetic contents invalid\"\n                                   })\n\npef = Tk::Iwidgets::Entryfield.new(:labeltext=>'Password:', :width=>12, \n                                   :show=>\"\\267\",  ## <=== utf8 character\n                                   :command=>proc{puts \"Return Pressed\"})\n\nTk::Iwidgets::Labeledwidget.alignlabels(ef, fef, nef, aef, pef)\n\nef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\nfef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\nnef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\naef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\npef.pack(:fil=>:x,  :expand=>true, :padx=>10, :pady=>5)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/extbutton.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Extbutton.new(:text=>'Bitmap example', :bitmap=>'info', \n                            :background=>'bisque',  :activeforeground=>'red', \n                            :bitmapforeground=>'blue', :defaultring=>true, \n                            :command=>proc{\n                              puts \"Bisque is beautiful\"\n                            }).pack(:expand=>true)\n\n#img = TkPhotoImage.new(:file=>File.join(File.dirname(File.expand_path(__FILE__)), '../../../images/earthris.gif'))\nimg = TkPhotoImage.new(:file=>File.join(File.dirname(File.expand_path(__FILE__)), '../catalog_demo/images/clear.gif'))\n\nTk::Iwidgets::Extbutton.new(:text=>'Image example', :relief=>:ridge, \n                            :image=>img, :imagepos=>:e, :font=>'9x15bold', \n                            :activebackground=>'lightyellow', \n                            :background=>'lightgreen').pack(:expand=>true)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/extfileselectionbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Extfileselectionbox.new.pack(:padx=>10, :pady=>10, \n                                           :fill=>:both, :expand=>true)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/extfileselectiondialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\n#\n# Non-modal example\n#\nnmfsd = Tk::Iwidgets::Extfileselectiondialog.new(:title=>'Non-Modal')\nnmfsd.buttonconfigure('OK', :command=>proc{\n                        puts \"You selected #{nmfsd.get}\"\n                        nmfsd.deactivate\n                      })\nnmfsd.activate\n\n#\n# Modal example\n#\nmfsd = Tk::Iwidgets::Extfileselectiondialog.new(:modality=>:application)\nmfsd.center\nif TkComm.bool(mfsd.activate)\n  puts \"You selected #{mfsd.get}\"\nelse\n  puts \"You cancelled the dialog\"\nend\n\n\nmainloop.join\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/feedback.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Feedback.new(:labeltext=>'Status', :steps=>20){|fb|\n  pack(:padx=>10, :pady=>10, :fill=>:both, :expand=>true)\n  TkTimer.new(500, 20, proc{fb.step}).start(2500)\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/fileselectionbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Fileselectionbox.new.pack(:padx=>10, :pady=>10, \n                                        :fill=>:both, :expand=>true)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/fileselectiondialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\n#\n# Non-modal example\n#\nnmfsd = Tk::Iwidgets::Fileselectiondialog.new(:title=>'Non-Modal')\nnmfsd.buttonconfigure('OK', :command=>proc{\n                        puts \"You selected #{nmfsd.get}\"\n                        nmfsd.deactivate\n                      })\nnmfsd.activate\n\n#\n# Modal example\n#\nmfsd = Tk::Iwidgets::Fileselectiondialog.new(:modality=>:application)\nmfsd.center\nif TkComm.bool(mfsd.activate)\n  puts \"You selected #{mfsd.get}\"\nelse\n  puts \"You cancelled the dialog\"\nend\n\nmainloop.join\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/finddialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\nst = Tk::Iwidgets::Scrolledtext.new.pack\nst.insert('end', \"Now is the time for all good men\\n\")\nst.insert('end', \"to come to the aid of their country\")\n\nfd = Tk::Iwidgets::Finddialog.new(:textwidget=>st)\nfd.center(st)\nfd.activate\n\nmainloop.join\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/hierarchy.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\ndef get_files(file)\n  dir = (file.empty?)? ENV['HOME'] : TkComm._fromUTF8(file)\n  Dir.chdir(dir) rescue return ''\n  Dir['*'].sort.collect{|f|\n    [TkComm._toUTF8(File.join(dir, f)), TkComm._toUTF8(f)]\n  }\nend\n\nTk::Iwidgets::Hierarchy.new(:querycommand=>proc{|arg| get_files(arg.node)}, \n                            :visibleitems=>'30x15', \n                            :labeltext=>ENV['HOME']).pack(:side=>:left, \n                                                          :expand=>true, \n                                                          :fill=>:both)\n\n# Tk::Iwidgets::Hierarchy.new(:querycommand=>[proc{|n| get_files(n)}, '%n'], \n#                           :visibleitems=>'30x15', \n#                           :labeltext=>ENV['HOME']).pack(:side=>:left, \n#                                                         :expand=>true, \n#                                                         :fill=>:both)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/hyperhelp.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\ndir  = '/usr/local/ActiveTcl/demos/IWidgets/html/'\nhref = [ 'hyperhelp.n', 'buttonbox.n', 'calendar.n' ]\n\nhh = Tk::Iwidgets::Hyperhelp.new(:topics=>href, :helpdir=>dir)\nhh.show_topic('hyperhelp.n')\nhh.activate\n\nmainloop.join\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/labeledframe.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nlf = Tk::Iwidgets::Labeledframe.new(:labeltext=>'Entry Frame', :labelpos=>:n)\nlf.pack(:fill=>:both, :expand=>true, :padx=>10, :pady=>10)\n\ncs = lf.child_site\n\nTk::Iwidgets::Entryfield.new(cs, :labeltext=>'Name:').pack(:side=>:top, :fill=>:x)\nTk::Iwidgets::Spinint.new(cs, :labeltext=>'Number:').pack(:side=>:top, :fill=>:x)\nTk::Iwidgets::Pushbutton.new(cs, :text=>'Details:').pack(:side=>:top, :fill=>:x)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/labeledwidget.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nlw = Tk::Iwidgets::Labeledwidget.new(:labeltext=>'Canvas Widget', \n                                     :labelpos=>:s)\nlw.pack(:fill=>:both, :expand=>true, :padx=>10, :pady=>10)\n\ncw = TkCanvas.new(lw.child_site, :relief=>:raised, :width=>200, :height=>200, \n                  :borderwidth=>3, :background=>:white)\ncw.pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/mainwindow.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmw = Tk::Iwidgets::Mainwindow.new\n\nmw.menubar.add(:menubutton, 'file', :text=>'File', :underline=>0, \n               :padx=>8, :pady=>2, :menu=>[\n                 [:options, {:tearoff=>false}], \n\n                 [:command, 'new', {\n                     :label=>'New', :underline=>0, \n                     :helpstr=>'Create a new file'\n                   }\n                 ], \n\n                 [:command, 'open', {\n                     :label=>'Open ...', :underline=>0, \n                     :helpstr=>'Open an existing file'\n                   }\n                 ], \n\n                 [:command, 'save', {\n                     :label=>'Save', :underline=>0, \n                     :helpstr=>'Save the current file'\n                   }\n                 ], \n\n                 [:command, 'saveas', {\n                     :label=>'Save As', :underline=>5, \n                     :helpstr=>'Save the file as a different name'\n                   }\n                 ], \n\n                 [:command, 'print', {\n                     :label=>'Print', :underline=>0, \n                     :helpstr=>'Print the file'\n                   }\n                 ], \n\n                 [:separator, 'sep1'], \n\n                 [:command, 'close', {\n                     :label=>'Close', :underline=>0, \n                     :helpstr=>'Close the file'\n                   }\n                 ], \n\n                 [:separator, 'sep2'], \n\n                 [:command, 'exit', {\n                     :label=>'Exit', :underline=>1, \n                     :helpstr=>'Exit this application'\n                   }\n                 ], \n\n                 nil\n               ])\n\nTk::Iwidgets::Scrolledtext.new(mw.child_site).pack(:fill=>:both, :expand=>true)\n\nmw.activate\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/menubar.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nhelpvar = TkVariable.new\nviewmode = TkVariable.new\n\nmenu_spec = [\n  [:menubutton, 'file', {\n      :text=>'File', :menu=>[\n        [:options, {:tearoff=>false}], \n\n        [:command, 'new', {\n            :label=>'New', :helpstr=>'Open new document', \n            :command=>proc{puts 'NEW'}\n          }\n        ], \n\n        [:command, 'close', {\n            :label=>'Close', :helpstr=>'Close current document', \n            :command=>proc{puts 'CLOSE'}\n          }\n        ], \n\n        [:separator, 'sep1'], \n\n        [:command, 'exit', {\n            :label=>'Exit', :helpstr=>'Exit application', \n            :command=>proc{exit}\n          }\n        ]\n      ]\n    }\n  ], \n\n  [:menubutton, 'edit', {\n      :text=>'Edit', :menu=>[\n        [:options, {:tearoff=>false}], \n\n        [:command, 'undo', {\n            :label=>'Undo', :underline=>0, \n            :helpstr=>'Undo last command', \n            :command=>proc{puts 'UNDO'}\n          }\n        ], \n\n        [:separator, 'sep2'], \n\n        [:command, 'cut', {\n            :label=>'Cut', :underline=>1, \n            :helpstr=>'Cut selection to clipboard', \n            :command=>proc{puts 'CUT'}\n          }\n        ], \n\n        [:command, 'copy', {\n            :label=>'Copy', :underline=>1, \n            :helpstr=>'Copy selection to clipboard', \n            :command=>proc{puts 'COPY'}\n          }\n        ], \n\n        [:command, 'paste', {\n            :label=>'Paste', :underline=>0, \n            :helpstr=>'Paste clipboard contents', \n            :command=>proc{puts 'PASTE'}\n          }\n        ]\n      ]\n    }\n  ], \n\n  [:menubutton, 'options', {\n      :text=>'Options', :menu=>[\n        [:options, {:tearoff=>false, :selectcolor=>'blue'}], \n\n        [:radiobutton, 'byName', {\n            :variable=>viewmode, :value=>'NAME', \n            :label=>'by Name', :helpstr=>'View files by name order', \n            :command=>proc{puts 'NAME'}\n          }\n        ], \n\n        [:radiobutton, 'byDate', {\n            :variable=>viewmode, :value=>'DATE', \n            :label=>'by Date', :helpstr=>'View files by date order', \n            :command=>proc{puts 'DATE'}\n          }\n        ], \n\n        [:cascade, 'prefs', {\n            :label=>'Preferences', :menu=>[\n              [:command, 'colors', {\n                  :label=>'Colors...', :helpstr=>'Change text colors', \n                  :command=>proc{puts 'COLORS'}\n                }\n              ], \n\n              [:command, 'fonts', {\n                  :label=>'Fonts...', :helpstr=>'Change text font', \n                  :command=>proc{puts 'COLORS'}\n                }\n              ]\n            ]\n          }\n        ]\n      ]\n    }\n  ]\n]\n\n#mb = Tk::Iwidgets::Menubar.new(:helpvariable=>helpvar, \n#                              :menubuttons=>menu_spec)\nmb = Tk::Iwidgets::Menubar.new(:helpvariable=>helpvar)\nmb.configure(:menubuttons=>menu_spec)\n\nfr = TkFrame.new(:width=>300, :height=>300)\nef = TkEntry.new(:textvariable=>helpvar)\n\nmb.pack(:anchor=>:nw, :fill=>:x, :expand=>true)\nfr.pack(:fill=>:both, :expand=>true)\nef.pack(:anchor=>:sw, :fill=>:x, :expand=>true)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/menubar2.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nhelpvar = TkVariable.new\nviewmode = TkVariable.new\n\nmb = Tk::Iwidgets::Menubar.new\nmb.menubuttons = [\n  [:menubutton, 'file', {\n      :text=>'File', :menu=>[\n        [:command,   'new',   {:label=>'New'}], \n        [:command,   'close', {:label=>'Close'}], \n        [:separator, 'sep1'], \n        [:command,   'quit',  {:label=>'Quit'}]\n      ]\n    }\n  ], \n  [:menubutton, 'edit', {:text=>'Edit'}]\n]\n\nmb.add(:command, '.edit.undo', :label=>'Undo', :underline=>0)\nmb.add(:separator, '.edit.sep2')\nmb.add(:command, '.edit.cut',   :label=>'Cut',   :underline=>1)\nmb.add(:command, '.edit.copy',  :label=>'Copy',  :underline=>1)\nmb.add(:command, '.edit.paste', :label=>'Paste', :underline=>0)\n\nmb.add(:menubutton, '.options', :text=>'Options', :menu=>[\n         [:radiobutton, 'byName', {\n             :variable=>viewmode, :value=>'NAME', :label=>'by Name'}\n         ], \n         [:radiobutton, 'byDate', {\n             :variable=>viewmode, :value=>'DATE', :label=>'by Date'}\n         ]\n       ])\n\nmb.add(:cascade, '.options.prefs', :label=>'Preferences', :menu=>[\n         [:command, 'colors', {:label=>'Colors...'}], \n         [:command, 'fonts',  {:label=>'Fonts...'}]\n       ])\n\nmb.pack(:side=>:left, :anchor=>:nw, :fill=>:x, :expand=>true)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/messagebox1.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmb = Tk::Iwidgets::Messagebox.new(:hscrollmode=>:dynamic, \n                                  :labeltext=>'Messages', :labelpos=>:n, \n                                  :height=>120, :width=>550, \n                                  :savedir=>'/tmp', :textbackground=>'#d9d9d9')\nmb.pack(:padx=>5, :pady=>5, :fill=>:both, :expand=>true)\n\nmb.type_add('ERROR', :background=>'red', :foreground=>'white', :bell=>true)\nmb.type_add('WARNING', :background=>'yellow', :foreground=>'black')\nmb.type_add('INFO', :background=>'white', :foreground=>'black')\n\nmb.issue('This is an error message in red with a beep', 'ERROR')\nmb.issue('This warning message in yellow', 'WARNING')\nmb.issue('This is an informational message', 'INFO')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/messagebox2.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmb = Tk::Iwidgets::Messagebox.new(:hscrollmode=>:dynamic, \n                                  :labeltext=>'Messages', :labelpos=>:n, \n                                  :height=>120, :width=>550, \n                                  :savedir=>'/tmp', :textbackground=>'#d9d9d9')\nmb.pack(:padx=>5, :pady=>5, :fill=>:both, :expand=>true)\n\nerror   = mb.type_add(:background=>'red', :foreground=>'white', :bell=>true)\nwarning = mb.type_add(:background=>'yellow', :foreground=>'black')\ninfo    = mb.type_add(:background=>'white', :foreground=>'black')\n\nmb.issue('This is an error message in red with a beep', error)\nmb.issue('This warning message in yellow', warning)\nmb.issue('This is an informational message', info)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/messagedialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\n#\n# Standard question message dialog used for confirmation.\n#\nmd = Tk::Iwidgets::Messagedialog.new(:title=>'Message Dialog', \n                                     :text=>'Are you sure ? ', \n                                     :bitmap=>'questhead', :modality=>:global)\n\nmd.buttonconfigure('OK', :text=>'Yes')\nmd.buttonconfigure('Cancel', :text=>'No')\n\nif TkComm.bool(md.activate)\n  md.text('Are you really sure ? ')\n  if TkComm.bool(md.activate)\n    puts 'Yes'\n  else\n    puts 'No'\n  end\nelse\n  puts 'No'\nend\n\nmd.destroy\n\n#\n# Copyright notice with automatic deactivation.\n#\nbmp = '@' + File.join(File.dirname(File.expand_path(__FILE__)), '../catalog_demo/images/text.xbm')\n\ncr = Tk::Iwidgets::Messagedialog.new(:title=>'Copyright', \n                                     :bitmap=>bmp, :imagepos=>:n, \n                                     :text=>\"Copyright 200x XXX Corporation\\nAll rights reserved\")\n\ncr.hide('Cancel')\n\ncr.activate\nTk.after(7000, proc{cr.deactivate; Tk.root.destroy})\n\nmainloop.join\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/notebook.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n# Create the tabnotebook widget and pack it.\nnb = Tk::Iwidgets::Notebook.new(:width=>100, :height=>100)\nnb.pack(:anchor=>:nw, :fill=>:both, :expand=>true, \n        :side=>:left, :padx=>10, :pady=>10)\n\n# Add two pages to the tabnotebook,\n# labelled \"Page One\" and \"Page Two\"\nnb.add(:label=>'Page One')\nnb.add(:label=>'Page Two')\n\n# Get the child site frames of these two pages.\npage1CS = nb.child_site(0)\npage2CS = nb.child_site('Page Two')\n\n# Create buttons on each page of the tabnotebook.\nTkButton.new(page1CS, :text=>'Button One').pack\nTkButton.new(page2CS, :text=>'Button Two').pack\n\n# Select the first page of the tabnotebook.\nnb.select(0)\n\n# Create the scrollbar and associate teh scrollbar\n# and the notebook together, then pack the scrollbar\nnb.scrollbar(TkScrollbar.new).pack(:fill=>:y, :expand=>true, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/notebook2.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n# Create the tabnotebook widget and pack it.\nnb = Tk::Iwidgets::Notebook.new(:width=>100, :height=>100)\nnb.pack(:anchor=>:nw, :fill=>:both, :expand=>true, \n        :side=>:top, :padx=>10, :pady=>0)\n\n# Add two pages to the tabnotebook,\n# labelled \"Page One\" and \"Page Two\"\nnb.add(:label=>'Page One')\nnb.add(:label=>'Page Two')\n\n# Get the child site frames of these two pages.\npage1CS = nb.child_site(0)\npage2CS = nb.child_site('Page Two')\n\n# Create buttons on each page of the tabnotebook.\nTkButton.new(page1CS, :text=>'Button One').pack\nTkButton.new(page2CS, :text=>'Button Two').pack\n\n# Select the first page of the tabnotebook.\nnb.select(0)\n\n# Create the scrollbar and associate teh scrollbar\n# and the notebook together, then pack the scrollbar\nnb.xscrollbar(TkScrollbar.new).pack(:fill=>:x, :expand=>true, :padx=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/optionmenu.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nom = Tk::Iwidgets::Optionmenu.new(:labelmargin=>5, :labelpos=>:w, \n                                  :labeltext=>\"Operating System :\")\n\nom.insert('end', 'Unix', 'VMS', 'Linux', 'OS/2', 'Windows NT', 'DOS')\nom.sort_ascending\nom.select('Linux')\n\nom.pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/panedwindow.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\npw = Tk::Iwidgets::Panedwindow.new(:width=>300, :height=>300)\n\npw.add('top')\npw.add('middle', :margin=>10)\npw.add('bottom', :margin=>10, :minimum=>10)\n\npw.pack(:fill=>:both, :expand=>true)\n\npw.child_site_list.each{|pane|\n  TkButton.new(pane, :text=>pane.path, :relief=>:raised, \n               :borderwidth=>2).pack(:fill=>:both, :expand=>true)\n}\n\npw.fraction(50,30,20)\npw.paneconfigure(0, :minimum=>20)\npw.paneconfigure('bottom', :margin=>15)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/panedwindow2.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\npw = Tk::Iwidgets::Panedwindow.new(:width=>300, :height=>300)\n\ntop = pw.add\nmiddle = pw.add(:margin=>10)\nbottom = pw.add(:margin=>10, :minimum=>10)\n\npw.pack(:fill=>:both, :expand=>true)\n\npw.child_site_list.each{|pane|\n  TkButton.new(pane, :text=>pane.path, :relief=>:raised, \n               :borderwidth=>2).pack(:fill=>:both, :expand=>true)\n}\n\npw.fraction(50,30,20)\npw.paneconfigure(0, :minimum=>20)  # 0 == pw.index(top)\npw.paneconfigure(bottom, :margin=>15)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/promptdialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\nTkOption.add('*textBackground', 'white')\n\npd = Tk::Iwidgets::Promptdialog.new(:modality=>:global, :title=>'Password', \n                                    :labeltext=>'Password:', :show=>'*')\npd.hide('Apply')\n\nif TkComm.bool(pd.activate)\n  puts \"Password entered: #{pd.get}\"\nelse\n  puts \"Password prompt cancelled\"\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/pushbutton.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Pushbutton.new(:text=>'Hello', \n                             :command=>proc{puts 'Hello World'}, \n                             :defaultring=>true).pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/radiobox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nrb = Tk::Iwidgets::Radiobox.new(:labeltext=>'Fonts')\nrb.add('times',     :text=>'Times')\nrb.add('helvetica', :text=>'Helvetica')\nrb.add('courier',   :text=>'Courier')\nrb.add('symbol',    :text=>'Symbol')\nrb.select('courier')\nrb.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/scrolledcanvas.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nsc = Tk::Iwidgets::Scrolledcanvas.new\n\nsc.create(TkcRectangle, 100, 100, 400, 400, :fill=>'red')\nTkcRectangle.new(sc, 300, 300, 600, 600, :fill=>'green')\nTkcRectangle.new(sc, [[200, 200], [500, 500]], :fill=>'blue')\n\nsc.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/scrolledframe.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nsf = Tk::Iwidgets::Scrolledframe.new(:width=>150, :height=>180, \n                                     :labeltext=>'scrolledframe')\ncs = sf.child_site\n\nTkButton.new(cs, :text=>'Hello').pack(:pady=>10)\nTkButton.new(cs, :text=>'World').pack(:pady=>10)\nTkButton.new(cs, :text=>'This is a test').pack(:pady=>10)\nTkButton.new(cs, :text=>'This is a really big button').pack(:pady=>10)\nTkButton.new(cs, :text=>'This is another really big button').pack(:pady=>10)\nTkButton.new(cs, :text=>'This is the last really big button').pack(:pady=>10)\n\nsf.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/scrolledhtml.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTkOption.add('*textBackground', 'white')\n\nsh = Tk::Iwidgets::Scrolledhtml.new(:fontname=>'helvetica', \n                                    :linkcommand=>proc{|href|\n                                      sh.import_link(href)\n                                    })\nsh.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nsh.import(Tk.getOpenFile(:title=>'select HTML document'))\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/scrolledlistbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTkOption.add('*textBackground', 'white')\n\nslb = Tk::Iwidgets::Scrolledlistbox.new(:selectmode=>:single, \n                                        :vscrollmode=>:static,\n                                        :hscrollmode=>:dynamic,\n                                        :labeltext=>'List', \n                                        :selectioncommand=>proc{\n                                          puts(slb.get_curselection)\n                                        }, \n                                        :dblclickcommand=>proc{\n                                          puts('Double Click')\n                                          puts(slb.get_curselection)\n                                        })\nslb.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nslb.insert('end', *['Hello', 'Out There', 'World'])\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/scrolledtext.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nst = Tk::Iwidgets::Scrolledtext.new(:hscrollmode=>:dynamic, :wrap=>:none, \n                                    :labeltext=>'Password File')\nst.pack(:expand=>true, :fill=>:both, :padx=>10, :pady=>10)\n\nst.import('/etc/passwd')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/selectionbox.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTkOption.add('*textBackground', 'white')\n\nsb = Tk::Iwidgets::Selectionbox.new.pack(:padx=>10, :pady=>10, \n                                         :fill=>:both, :expand=>true)\n\nsb.insert_items('end', *['Hello', 'Out There', 'World'])\n\nTkLabel.new(sb.child_site, \n            :text=>'Child Site is Here').pack(:fill=>:x, :padx=>10, :pady=>10)\n\nsb.insert_items(2, 'Cruel Cruel')\n\nsb.selection_set(1)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/selectiondialog.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nmainloop = Thread.new{Tk.mainloop}\n\nTkButton.new(:text=>'QUIT', \n             :command=>proc{Tk.root.destroy}).pack(:padx=>10, :pady=>10)\n\nTk::Iwidgets::Selectiondialog.new.activate\n\nmainloop.join\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/shell.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nsh = Tk::Iwidgets::Shell.new(:modality=>:application, \n                             :padx=>20, :pady=>20, :title=>'Shell')\n\nTkButton.new(:text=>'ACTIVATE', :padx=>7, :pady=>7, \n             :command=>proc{puts sh.activate}).pack(:padx=>10, :pady=>10)\n\nTkLabel.new(sh.child_site, :text=>'SHELL').pack\nTkButton.new(sh.child_site, :text=>'YES', \n             :command=>proc{sh.deactivate 'press YES'}).pack(:fill=>:x)\nTkButton.new(sh.child_site, :text=>'NO', \n             :command=>proc{sh.deactivate 'press NO'}).pack(:fill=>:x)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/spindate.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Spindate.new.pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/spinint.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTkOption.add('*textBackground', 'white')\n\nTk::Iwidgets::Spinint.new(:labeltext=>'Temperature', :labelpos=>:w, :width=>5, \n                          :fixed=>true, :range=>[32, 212]).pack(:pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/spinner.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nclass Spinner_demo < TkWindow\n  Months = %w(January February March April May June July August September October November December)\n\n  def block_input(c)\n    false\n  end\n\n  def spin_month(step)\n    index = Months.index(@spinner.get) + step\n    index = 11 if index < 0\n    index = 0 if index > 11\n\n    @spinner.value = Months[index]\n  end\n\n  def initialize(parent=nil)\n    @spinner = Tk::Iwidgets::Spinner.new(parent, :labeltext=>'Month : ', \n                                         :width=>10, :fixed=>10, \n                                         :validate=>proc{|c| block_input}, \n                                         :decrement=>proc{spin_month -1}, \n                                         :increment=>proc{spin_month 1})\n    @path = @spinner\n    @spinner.insert(0, Months[0])\n  end\nend\n\nSpinner_demo.new.pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/spintime.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Spintime.new.pack(:padx=>10, :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/tabnotebook.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n# Create the tabnotebook widget and pack it.\ntn = Tk::Iwidgets::Tabnotebook.new(:width=>300, :height=>100)\ntn.pack(:anchor=>:nw, :fill=>:both, :expand=>true, \n        :side=>:left, :padx=>10, :pady=>10)\n\n# Add two pages to the tabnotebook,\n# labelled \"Page One\" and \"Page Two\"\ntn.add(:label=>'Page One')\ntn.add(:label=>'Page Two')\n\n# Get the child site frames of these two pages.\npage1CS = tn.child_site(0)\npage2CS = tn.child_site('Page Two')\n\n# Create buttons on each page of the tabnotebook.\nTkButton.new(page1CS, :text=>'Button One').pack\nTkButton.new(page2CS, :text=>'Button Two').pack\n\n# Select the first page of the tabnotebook.\ntn.select(0)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/tabnotebook2.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n# Create the tabnotebook widget and pack it.\ntn = Tk::Iwidgets::Tabnotebook.new(:width=>300, :height=>100)\ntn.pack(:anchor=>:nw, :fill=>:both, :expand=>true, \n        :side=>:top, :padx=>10, :pady=>0)\n\n# Add two pages to the tabnotebook,\n# labelled \"Page One\" and \"Page Two\"\ntn.add(:label=>'Page One')\ntn.add(:label=>'Page Two')\n\n# Get the child site frames of these two pages.\npage1CS = tn.child_site(0)\npage2CS = tn.child_site('Page Two')\n\n# Create buttons on each page of the tabnotebook.\nTkButton.new(page1CS, :text=>'Button One').pack\nTkButton.new(page2CS, :text=>'Button Two').pack\n\n# Select the first page of the tabnotebook.\ntn.select(0)\n\n# Create the scrollbar\n# and the notebook together, then pack the scrollbar\ntn.xscrollbar(TkScrollbar.new).pack(:fill=>:x, :expand=>true, :padx=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/tabset.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n# Create a listbox with two items (one and two)\nl = TkListbox.new(:selectmode=>:single, :exportselection=>false).pack\nl.insert('end', 'one')\nl.insert('end', 'two')\nl.selection_set(0)\n\n# Define a proc that knows how to select an item\n# from a list given an index from the tabset -command callback.\nselectItem = proc{|item|\n  l.selection_clear(l.curselection)\n  l.selection_set(item)\n  l.see(item)\n}\n\n# Create a tabset, set its -command to call selectItem\n# Add two labels to the tabset (one and two).\nts = Tk::Iwidgets::Tabset.new(:command=>selectItem)\nts.add(:label=>1)\nts.add(:label=>2)\nts.select(0)\nts.pack(:fill=>:x, :expand=>true)\n\n# Define a proc that knows how to select a tab\n# given a y pixel coordinate from the list..\nselectTab = proc{|y| ts.select(l.nearest(y)) }\n\n# bind button 1 press to the selectTab procedure.\nl.bind('ButtonPress-1', proc{|y| selectTab.call(y) }, '%y')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/timeentry.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nTk::Iwidgets::Timeentry.new.pack\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/timefield.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\ntf = Tk::Iwidgets::Timefield.new(:command=>proc{puts(tf.get)})\ntf.pack(:fill=>:x, :expand=>true, :padx=>10,  :pady=>10)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/toolbar.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\n##########################################\n# icon images\neditcopy22 = TkPhotoImage.new(:data=><<'EOD')\n   R0lGODlhFgAWAIUAAPwCBBQSFPz+/DQyNISChDw6PMzKzMTGxERGRIyKjFxa\n   XMTCvKSmpHR2dPz6/Pz29PTq3MS2rPz69MTCxFxWVHx6dJyWjNzSzPz27Pzy\n   7Pzu5PTm3NTKvIR+fJyGfHxuZHxqXNTCtPTq5PTi1PTezNS+rExOTFRORMyy\n   lPTaxOzWxOzSvNze3NTOxMy2nMyulMyqjAQCBAAAAAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAbY\n   QIBwSCwahYGkUnk0BgTQ6IAQaBKfUWhBYKhaAU+CgXAQIAyChLeJzSIQhcH6\n   GFaM0QtGY5kstqEODw8QEQELAhJTc08KBBMEFBUWDRcBE1pca20SGBkaEBsc\n   AY5maFRIAgoLHRQRHh8gIQFlZnByqA8ZGSIQIyQjJQEmYgJ5p2ACrK4gJx4g\n   KIZZAgdeAQ4ZI9kjKSor0AwEjeAs1S0cHAslLi4vMDDRWeRIfEsxMeET4ATy\n   VoYLC5fizXEiAR84BeMG+pEm8EsAFhAjSlR4hR6fLxiF0AkCACH+aENyZWF0\n   ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5\n   OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2\n   ZWxjb3IuY29tADs=\nEOD\n\neditcut22 = TkPhotoImage.new(:data=><<'EOD')\n   R0lGODlhFgAWAIMAAPwCBAQCBAwCBPz+/OTi5JyanOzq7DQyNGxqbAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAARbEMhJq704gxBE\n   0Bf3cZo4kRJqBQNRfBucyudgvJS6VaxLzyMa6/bLiWA9HOg4VIIkL5vzuRkc\n   pkvRIIAorphJLzBW84WEuRZWp6uaT7J2Sh1Hit3OY/ZO7WvsEQAh/mhDcmVh\n   dGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAx\n   OTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRl\n   dmVsY29yLmNvbQA7\nEOD\n\neditpaste22 = TkPhotoImage.new(:data=><<'EOD')\n   R0lGODlhFgAWAIYAAPwCBBQWFDw6FHRuFGRaBFxSBAQCBAQKBCQiBIx6HPz6\n   /NTOfKyiXDQuFOTm5Pz+/Ozu7PTq5Pz63PTyxNTOjKSeRExGLMTGxMzKzNTS\n   1NTW1Dw2NKSmpKyqrKSipJyanNzWlLy6ZLSuVIx6FISChIyKhJSSlCQiJLS2\n   tDw6NDQyNCQiFCQmHBQSDGRiZHRydGxubHx6dGxqbFxeXGRmZFxaXCwuLOzq\n   7KyurHx+fDwmFEQuFCweFCQWDBQODBwaHBweHKSinJSWlOTi5JyepHR2dDw6\n   PBQSFNze3ERGRIyKjIyOjISGhPz29Pzy7MS2rMzOzFRWVHx2dHxybDQiFPz2\n   7Pzu5PTq3PTm1NTCtJyGdHxuZHxqXPzq3PTaxNS6pFxWVFRKRNS2nPTi1PTS\n   tNSulNzOxNSynMymhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAA\n   LAAAAAAWABYAAAf/gACCgwABAgMEBYSLggaOjgcICQoLDA2Pj4MGDg8QEZ4F\n   DxITFBUWFxcYGRobjQ8cHR4fCQ8gCyEiFSMWJCUkJieNEB4dKB4pKissK8wr\n   LS4vMDHBAAYQHx8dFx0fJDIzNDU0M+IyHzaNNyg43Ng5Ojs7Ojw9Pj9AMkCN\n   DiZB/h9CSOx4QLCgihItqBkYgqIDESElitAYWJCgkQcXjjRCgi1Ihw4BB5LA\n   QOLCgyQYHihpUU3DBw5ElpAgAYNixSRJjKjQaECDCRPZPDB5IbIGSQwKLnh4\n   wbInLA4kmJB4oaPiAwVNnER40hRK1BIAaVatUZJEFCkmpmjgCeWDCalFe4q4\n   oFKwSRUrEa5gycLzwq8lUnPQ4PEgSpYcUZ5o2cIlS1O/JHLEDdfjQZMIVrpg\n   weLFy5e+M6WSmBGlxYMYYBRzCaOFi5imHWBIfOEiShLTVjaP6eyFTBmN1TA5\n   OvLDjJksWb58OVMGDRqWjAYdmU79SIvpjqJr104nEAAh/mhDcmVhdGVkIGJ5\n   IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5\n   OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29y\n   LmNvbQA7\nEOD\n\neditdelete22 = TkPhotoImage.new(:data=><<'EOD')\n   R0lGODlhFgAWAIYAAASC/FRSVExKTERCRDw6PDQyNCwuLBweHBwaHAwODAwK\n   DAQCBExOTNze3NTW1MTGxLS2tJyanPz+/Ozu7BQSFCwqLDw+POTi5PTu7MzK\n   xIR+fCQmJPz6/Oze1NTGvPz69Pzy7Pz29LyyrPy+vPyupPTm1BQWFIQCBPwC\n   BMS6rPzSzNTOxPTi1NS+rPTezNzOxPTizOzWxMy2pOzaxMy2nPTaxOzOtMyy\n   nOzSvMyqjPx+fOzGpMSihPTq3OzKrOTCpNzKxNTCtAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAA\n   LAAAAAAWABYAAAf8gACCAQIDBAUGBwgJCgsLgpCRAAwNlZYODxALEY+SkAMN\n   EqKjEw0UD5yegqCjrRMVEqidkgWhraMWF7GptLa3EgEWFRSOnhW+vxgZEBqz\n   kBvItxwdHryRCNGjHyAhHSLOgtgSI60c2yQjJd+eJqEnKK0hJCgnJSngAO0S\n   F+8qEvL0VrBogW+BLX4oVKgIyMIFQU8KfDV4R+8FDBcxZBREthAFiRIsOsyg\n   sVEUh4Un3pGoUcPGjZInK65QicPlxg8oX5RwqNJGjo0hdJwQ6EIkjRM6dvDY\n   CKIHSBc1Ztjw4eOH0oIrsgIJEqSFDBo0cuTgsdSTo7No0xYTZCcQACH+aENy\n   ZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29y\n   IDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cu\n   ZGV2ZWxjb3IuY29tADs=\nEOD\n\ntext22 = TkPhotoImage.new(:data=><<'EOD')\n   R0lGODlhFgAWAIQAAPwCBAQCBBwaHAwKDBQSFLy+vLS2tJSWlBQWFKyqrFRS\n   VCwqLDQyNNTS1GxqbFxaXJyanIyOjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n   AAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAWABYAAAVcICCOZGmK\n   QSoMaZsShBsQBdAapHvgaIDUqUPJlRjSbAoT0fRDKgODRbF0PLUYjZO2F2Bs\n   t9evNix+dsvDlGKK5jraudQb7qbX6a2HEJ+ycyF+LRE8ZTI+fX5oGCEAIf5o\n   Q3JlYXRlZCBieSBCTVBUb0dJRiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxD\n   b3IgMTk5NywxOTk4LiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3\n   dy5kZXZlbGNvci5jb20AOw==\nEOD\n\n##########################################\n\nbmp_dir = File.join(File.dirname(File.expand_path(__FILE__)), \n                    '../catalog_demo/images')\n\n##########################################\n\nstatus_var = TkVariable.new\nradio_var  = TkVariable.new\ncheck_var1 = TkVariable.new\ncheck_var2 = TkVariable.new\n\ntb = Tk::Iwidgets::Toolbar.new(:helpvariable=>status_var)\n\n##########################################\n\ntb.add(:button, :helpstr=>'Copy It', :image=>editcopy22, \n       :balloonstr=>'Copy', :command=>proc{puts 'Copy It'})\n\ntb.add(:button, :helpstr=>'Cut It', :image=>editcut22, \n       :balloonstr=>'Cut', :command=>proc{puts 'Cut It'})\n\ntb.add(:button, :helpstr=>'Paste It', :image=>editpaste22, \n       :balloonstr=>'Paste', :command=>proc{puts 'Paste It'})\n\ntb.add(:button, :helpstr=>'Delete It', :image=>editdelete22, \n       :balloonstr=>'Delete', :command=>proc{puts 'Delete It'})\n\n#--------------------------------\n\ntb.add(:frame, :borderwidth=>1, :width=>10, :height=>10)\n\n#--------------------------------\n\ntb.add(:radiobutton, :variable=>radio_var, :value=>'Box', \n       :bitmap=>\"@#{bmp_dir}/box.xbm\", \n       :helpstr=>'Radio Button #1', :balloonstr=>'Radio', \n       :command=>proc{puts 'Radio Button \"Box\"'})\n\ntb.add(:radiobutton, :variable=>radio_var, :value=>'Line', \n       :bitmap=>\"@#{bmp_dir}/line.xbm\", \n       :helpstr=>'Radio Button #2', :balloonstr=>'Radio', \n       :command=>proc{puts 'Radio Button \"Line\"'})\n\ntb.add(:radiobutton, :variable=>radio_var, :value=>'Oval', \n       :bitmap=>\"@#{bmp_dir}/oval.xbm\", \n       :helpstr=>'Radio Button #3', :balloonstr=>'Radio', \n       :command=>proc{puts 'Radio Button \"Oval\"'})\n\n#--------------------------------\n\ntb.add(:frame, :borderwidth=>1, :width=>10, :height=>10)\n\n#--------------------------------\n\ntb.add(:checkbutton, :variable=>check_var1, :onvalue=>'yes', :offvalue=>'no', \n       :image=>text22, :command=>proc{puts 'Checkbutton 1'})\n\ntb.add(:checkbutton, :variable=>check_var2, :onvalue=>'yes', :offvalue=>'no', \n       :bitmap=>\"@#{bmp_dir}/points.xbm\", :command=>proc{puts 'Checkbutton 2'})\n\ntb.pack(:side=>:top, :anchor=>:nw)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/iwidgets/sample/watch.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'tk'\nrequire 'tkextlib/iwidgets'\n\nThread.new{\n  trap('INT') {puts 'catch SIGINT'}\n  sleep 5\n  trap('INT', 'DEFAULT')\n}\n\nTk::Iwidgets::Watch.new(:state=>:disabled, :showampm=>:no, \n                        :width=>155, :height=>155){|w|\n  w.pack(:padx=>10, :pady=>10, :fill=>:both, :expand=>true)\n  # TkTimer.new(1000, -1, proc{w.show; Tk.update}).start\n  TkTimer.new(25, -1, proc{w.show; Tk.update}).start\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tcllib/Orig_LICENSE.txt",
    "content": "\n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n  >>>  The following text is the original 'license.term' of tklib    <<<\n  >>>  extension.                                                    <<<\n  >>>  Original Tcl files are not include in this directry, because  <<<\n  >>>  of all of them are rewrited to Ruby files.                    <<<\n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\nThis software is copyrighted by Ajuba Solutions and other parties.\nThe following terms apply to all files associated with the software unless\nexplicitly disclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tcllib/datefield.rb",
    "content": "#!/usr/bin/ruby\n\nrequire 'tk'\nrequire 'tkextlib/tcllib/datefield'\nrequire 'parsedate'\n\nTk.root.title('Datefield example')\n\n\nmy_date1 = TkVariable.new\nmy_date2 = TkVariable.new\nmy_date1.trace('w'){\n  begin\n    t = Time.local(*(ParseDate.parsedate(my_date1.value)))\n    my_date2.value = t.strftime('%A')\n  rescue\n    # ignore error\n  end\n}\n\ndf = Tk::Tcllib::Datefield.new(:textvariable=>my_date1)\nTk.grid(TkLabel.new(:text=>'Enter a date:', :anchor=>:e), df, :sticky=>:ew)\nTk.grid(TkLabel.new(:text=>'That date ia a:', :anchor=>:e), \n        TkLabel.new(:textvariable=>my_date2, :relief=>:sunken, :width=>12), \n        :sticky=>:ew)\n\ndf.set_focus\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tcllib/plotdemos1.rb",
    "content": "#!/usr/bin/ruby\n\nrequire 'tk'\nrequire 'tkextlib/tcllib/plotchart'\n\n###############################\n\nc1 = TkCanvas.new(:background=>'white', :width=>400, :height=>200)\nc2 = TkCanvas.new(:background=>'white', :width=>400, :height=>200)\nc3 = TkCanvas.new(:background=>'white', :width=>400, :height=>200)\nTk.pack(c1,c2,c3, :fill=>:both, :side=>:top)\n\nh = TkToplevel.new(:title=>'h')\nhc1 = TkCanvas.new(h, :background=>'white', :width=>400, :height=>200)\nhc2 = TkCanvas.new(h, :background=>'white', :width=>400, :height=>200)\nTk.pack(hc1,hc2, :fill=>:both, :side=>:top)\n\nv = TkToplevel.new(:title=>'v')\nvc1 = TkCanvas.new(v, :background=>'white', :width=>400, :height=>200)\nvc2 = TkCanvas.new(v, :background=>'white', :width=>400, :height=>200)\nvc3 = TkCanvas.new(v, :background=>'white', :width=>400, :height=>200)\nTk.pack(vc1,vc2,vc3, :fill=>:both, :side=>:top)\n\n###############################\n\ns = Tk::Tcllib::Plotchart::XYPlot.new(c1, [0.0, 100.0, 10.0], \n                                          [0.0, 100.0, 20.0])\n\n\nxd =    5.0\nyd =   20.0\nxold =  0.0\nyold = 50.0\n\ns.dataconfig('series1', :color=>'red')\n\n(0..19).each{|i|\n  xnew = xold + xd\n  ynew = yold + (rand() - 0.5) * yd\n  ynew2 = yold + (rand() - 0.5) * 2.0 * yd\n  s.plot('series1', xnew, ynew)\n  s.plot('series2', xnew, ynew2)\n  xold = xnew\n  yold = ynew\n}\n\ns.xtext \"X-coordinate\"\ns.ytext \"Y-data\"\ns.title \"Aha!\"\n\nc1.wait_visibility\n\ns.save_plot \"aha.ps\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::Piechart.new(c2)\n\ns.plot([ [\"Long names\", 10], [\"Short names\", 30], \n         [\"Average\", 40],    [\"Ultra-short names\", 5] ])\n\n#\n# Note: title should be shifted up\n#       - distinguish a separate title area\n#\ns.title \"Okay - this works\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::PolarPlot.new(c3, [3.0, 1.0])\n\n0.step(359, 10){|angle|\n  rad = 1.0+Math.cos(angle*Math::PI/180.0)\n  s.plot('cardioid', rad, angle)\n}\n\ns.title \"Cardioid\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::Barchart.new(hc1, %w(A B C D E), \n                                        [0.0, 10.0, 2.0], 2)\n\ns.plot('series1', [1.0, 4.0, 6.0, 1.0, 7.0], 'red')\ns.plot('series2', [0.0, 3.0, 7.0, 9.3, 2.0], 'green')\ns.title \"Arbitrary data\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::Barchart.new(hc2, %w(A B C D E), \n                                        [0.0, 20.0, 5.0], :stacked)\n\ns.plot('series1', [1.0, 4.0, 6.0, 1.0, 7.0], 'red')\ns.plot('series2', [0.0, 3.0, 7.0, 9.3, 2.0], 'green')\ns.title \"Stacked diagram\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::HorizontalBarchart.new(vc1, [0.0, 10.0, 2.0], \n                                                  %w(A B C D E), 2)\n\ns.plot('series1', [1.0, 4.0, 6.0, 1.0, 7.0], 'red')\ns.plot('series2', [0.0, 3.0, 7.0, 9.3, 2.0], 'green')\ns.title \"Arbitrary data\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::HorizontalBarchart.new(vc2, [0.0, 20.0, 5.0], \n                                                  %w(A B C D E), :stacked)\n\ns.plot('series1', [1.0, 4.0, 6.0, 1.0, 7.0], 'red')\ns.plot('series2', [0.0, 3.0, 7.0, 9.3, 2.0], 'green')\ns.title \"Stacked diagram\"\n\n###############################\n\ns = Tk::Tcllib::Plotchart::Timechart.new(vc3, \"1 january 2004\", \n                                              \"31 december 2004\", 4)\n\ns.period(\"Spring\", \"1 march 2004\", \"1 june 2004\", 'green')\ns.period(\"Summer\", \"1 june 2004\", \"1 september 2004\", 'yellow')\ns.vertline(\"1 jan\", \"1 january 2004\")\ns.vertline(\"1 apr\", \"1 april 2004\")\ns.vertline(\"1 jul\", \"1 july 2004\")\ns.vertline(\"1 oct\", \"1 october 2004\")\ns.milestone(\"Longest day\", \"21 july 2004\")\ns.title \"Seasons (northern hemisphere)\"\n\n###############################\n\nz = TkToplevel.new(:title=>'3D')\n\nzc1 = TkCanvas.new(z, :background=>'white', :width=>400, :height=>300)\nzc2 = TkCanvas.new(z, :background=>'white', :width=>400, :height=>250)\nTk.pack(zc1,zc2)\n\ns = Tk::Tcllib::Plotchart::Plot3D.new(zc1, \n                                      [0, 10, 3], [-10, 10, 10], [0, 10, 2.5])\n\ns.title \"3D Plot\"\ns.plot_function{|x, y|\n  # cowboyhat\n  x1 = x.to_f/9.0\n  y1 = y.to_f/9.0\n  3.0 * (1.0-(x1*x1+y1*y1))*(1.0-(x1*x1+y1*y1))\n}\n\ns = Tk::Tcllib::Plotchart::Plot3D.new(zc2, \n                                      [0, 10, 3], [-10, 10, 10], [0, 10, 2.5])\ns.title \"3D Plot - data \"\ns.colour(\"green\", \"black\")\ns.plot_data([ [1.0, 2.0, 1.0, 0.0], \n              [1.1, 3.0, 1.1, -0.5], \n              [3.0, 1.0, 4.0, 5.0] ])\n\n###############################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tcllib/plotdemos2.rb",
    "content": "#!/usr/bin/ruby\n\nrequire 'tk'\nrequire 'tkextlib/tcllib/plotchart'\n\n###############################\n\nc1 = TkCanvas.new(:background=>'white', :width=>400, :height=>200)\nc2 = TkCanvas.new(:background=>'white', :width=>400, :height=>200)\nTk.pack(c1,c2, :fill=>:both, :side=>:top)\n\n###############################\n# Set up a strip chart\n###############################\nslipchart = Tk::Tcllib::Plotchart::Stripchart.new(c1, [0.0, 100.0, 10.0], \n                                                      [0.0, 100.0, 20.0])\n\nTkTimer.new(500, -1, proc{|obj| # obj --> TkTimer object\n              slipchart, xold, xd, yold, yd = obj.return_value\n              xnew = xold + xd\n              ynew = yold + (rand() - 0.5) * yd\n              ynew2 = yold + (rand() - 0.5) * 2.0 * yd\n              slipchart.plot('series1', xnew, ynew)\n              slipchart.plot('series2', xnew, ynew2)\n              obj.stop if xnew >= 200\n              [slipchart, xnew, xd, ynew, yd] # return_value\n            }).start(100, proc{\n                       # init return_value\n                       [slipchart, 0.0, 15.0, 50.0, 30.0]\n                     })\n\nslipchart.title \"Aha!\"\n\n###############################\n# Set up an isometric plot\n###############################\ns = Tk::Tcllib::Plotchart::IsometricPlot.new(c2, [0.0, 100.0], [0.0, 200.0], \n                                             :noaxes)\n\ns.set_zoom_pan\n\ns.plot('rectangle',        [10.0, 10.0, 50.0, 50.0], 'green')\ns.plot('filled-rectangle', [20.0, 20.0, 40.0, 40.0], 'red')\ns.plot('filled-circle',    [70.0, 70.0, 40.0], 'yellow')\ns.plot('circle',           [70.0, 70.0, 42.0])\n\n###############################\n# Check the symbols\n###############################\nh = TkToplevel.new(:title=>'h')\nc = TkCanvas.new(h, :bg=>'white', :width=>400, :height=>200).pack(:fill=>:both)\n\ns = Tk::Tcllib::Plotchart::XYPlot.new(c, [0.0, 100.0, 10.0], \n                                         [0.0, 100.0, 20.0]) \ns.dataconfig('series1', :colour=>'red',   :type=>:symbol)\ns.dataconfig('series2', :colour=>'green', :type=>:both)\n\ns.yconfig(:format=>\"%12.2e\")\n\nx = 5.0\n%w(plus cross circle up down dot upfilled downfilled).each{|sym|\n  s.dataconfig('series1', :symbol=>sym)\n  s.dataconfig('series2', :symbol=>sym)\n  s.plot('series1', x, 50.0)\n  s.plot('series2', x, 20)\n  x += 10\n}\n\n##############################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tcllib/plotdemos3.rb",
    "content": "#!/usr/bin/ruby\n\nrequire 'tk'\nrequire 'tkextlib/tcllib/plotchart'\n\n###############################\n# Set up a strip chart\n###############################\n\nTk::Tcllib::Plotchart::Stripchart.new([0.0, 100.0, 10.0], \n                                      [0.0, 100.0, 20.0], \n                                      :background=>'white', \n                                      :width=>400, :height=>200){|chart|\n  title \"Aha!\"\n  pack(:fill=>:both, :side=>:top)\n\n  series1 = Tk::Tcllib::Plotchart::PlotSeries.new(chart)\n  series2 = Tk::Tcllib::Plotchart::PlotSeries.new(chart)\n\n  xd = 15.0\n  yd = 30.0\n\n  TkTimer.new(500, -1, proc{|obj| # obj --> TkTimer object\n                xold, yold = obj.return_value\n                xnew = xold + xd\n                ynew = yold + (rand() - 0.5) * yd\n                ynew2 = yold + (rand() - 0.5) * 2.0 * yd\n\n                series1.plot(xnew, ynew)\n                series2.plot(xnew, ynew2)\n\n                obj.stop if xnew >= 200\n\n                [xnew, ynew] # return_value\n              }).start(100, proc{ [0.0, 50.0] }) # init return_value\n}\n\n###############################\n# Set up an isometric plot\n###############################\nTk::Tcllib::Plotchart::IsometricPlot.new([0.0, 100.0], [0.0, 200.0], :noaxes, \n                                         :background=>'white', \n                                         :width=>400, :height=>200){|chart|\n  pack(:fill=>:both, :side=>:top)\n  set_zoom_pan\n\n  chart.plot('rectangle',        [10.0, 10.0, 50.0, 50.0], 'green')\n  chart.plot('filled-rectangle', [20.0, 20.0, 40.0, 40.0], 'red')\n  chart.plot('filled-circle',    [70.0, 70.0, 40.0], 'yellow')\n  chart.plot('circle',           [70.0, 70.0, 42.0])\n}\n\n###############################\n# Check the symbols\n###############################\nTkToplevel.new(:title=>'h'){|h|\n  Tk::Tcllib::Plotchart::XYPlot.new(h, [0.0, 100.0, 10.0], \n                                       [0.0, 100.0, 20.0], \n                                    :bg=>'white', \n                                    :width=>400, :height=>200){|chart|\n    pack(:fill=>:both)\n\n    yconfig(:format=>\"%12.2e\")\n\n    series1 = Tk::Tcllib::Plotchart::PlotSeries.new(chart, :colour=>'red', \n                                                    :type=>:symbol)\n    series2 = Tk::Tcllib::Plotchart::PlotSeries.new(chart, :colour=>'green', \n                                                    :type=>:both)\n\n    x = 5.0\n    %w(plus cross circle up down dot upfilled downfilled).each{|sym|\n      series1.dataconfig(:symbol=>sym)\n      series2.dataconfig(:symbol=>sym)\n      series1.plot(x, 50.0)\n      series2.plot(x, 20)\n      x += 10\n    }\n  }\n}\n\n##############################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tcllib/xyplot.rb",
    "content": "#!/usr/bin/ruby\n\nrequire 'tk'\nrequire 'tkextlib/tcllib/plotchart'\n\nTkCanvas.new(:background=>'white', :width=>400, :height=>200){|c|\n  pack(:fill=>:both)\n  Tk::Tcllib::Plotchart::XYPlot.new(c, [0.0, 100.0, 10.0], \n                                       [0.0, 100.0, 20.0]){\n    [ [0.0, 32.0], [10.0, 50.0], [25.0, 60.0], [78.0, 11.0] ].each{|x, y|\n      plot('series1', x, y)\n    }\n    title(\"Data series\")\n  }\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/Orig_LICENSE.txt",
    "content": "\n  ######################################################################\n  ###  The following text is the original 'license.terms' of tile    ###\n  ###  extension.                                                    ###\n  ######################################################################\n\n\nLICENSE (\"MIT-style\")\n\nThis software is Copyright (C) 2003 Joe English and other parties.\n\nThe following terms apply to all files associated with this software\nunless explicitly disclaimed in individual files.  \n\nThe author(s) hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS for a PARTICULAR PURPOSE.  IN NO EVENT\nshall the AUTHORS of THIS SOFTWARE be LIABLE to ANY PARTY for\nDIRECT, INDIRECT, SPECIAL, INCIDENTAL, or CONSEQUENTIAL DAMAGES\narising out of the USE of THIS SOFTWARE and its DOCUMENTATION.\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/demo.rb",
    "content": "#!/usr/bin/env ruby\n#\n# Demo for 'tile' package.\n#\nrequire 'tk'\n\ndemodir = File.dirname($0)\nthemesdir = File.join(demodir, 'themes')\nTk::AUTO_PATH.lappend('.', demodir, themesdir)\n\nDir.foreach(themesdir){|name|\n  next if name == '.' || name == '..'\n  dir = File.join(themesdir, name)\n  Tk::AUTO_PATH.lappend(dir) if File.directory?(dir)\n}\n\nrequire 'tkextlib/tile'\n\ndef version?(ver)\n  TkPackage.vcompare(Tk::Tile.package_version, ver) >= 0\nend\n\n# define Tcl/Tk procedures for compatibility\nTk::Tile.__define_LoadImages_proc_for_compatibility__!\nTk::Tile::Style.__define_wrapper_proc_for_compatibility__!\n\nunless Tk::Tile::Style.theme_names.include?('step')\n  Tk::Tile::Style.theme_create('step')\nend\n\nTk.load_tclscript(File.join(demodir, 'toolbutton.tcl'))\nTk.load_tclscript(File.join(demodir, 'repeater.tcl'))\n\n# This forces an update of the available packages list. It's required\n# for package names to find the themes in demos/themes/*.tcl\n## Tk.tk_call(TkPackage.unknown_proc, 'Tcl', TkPackage.provide('Tcl'))\n##  --> This doesn't work. \n##      Because, unknown_proc may be \"command + some arguments\".\nTk.ip_eval(\"#{TkPackage.unknown_proc}  Tcl #{TkPackage.provide('Tcl')}\")\n\nTkRoot.new{\n  title 'Tile demo'\n  iconname 'Tile demo'\n}\n\n# The descriptive names of the builtin themes.\n$THEMELIST = [\n  ['default', 'Default'], \n  ['classic', 'Classic'], \n  ['alt', 'Revitalized'], \n  ['winnative', 'Windows native'], \n  ['xpnative', 'XP Native'], \n  ['aqua', 'Aqua'], \n]\n\n$V = TkVariable.new_hash(:THEME      => 'default', \n                         :COMPOUND   => 'top', \n                         :CONSOLE    => false, \n                         :MENURADIO1 => 'One', \n                         :MENUCHECK1 => true,\n                         :PBMODE     => 'determinate',\n                         :SELECTED   => true,\n                         :CHOICE     => 2)\n\n# Add in any available loadable themes.\nTkPackage.names.find_all{|n| n =~ /^(tile|ttk)::theme::/}.each{|pkg|\n  name = pkg.split('::')[-1]\n  unless $THEMELIST.assoc(name)\n    $THEMELIST << [name, Tk.tk_call('string', 'totitle', name)]\n  end\n}\n\n# Add theme definition written by ruby\n$RUBY_THEMELIST = []\nbegin\n  load(File.join(demodir, 'themes', 'kroc.rb'), true)\nrescue => e\nraise e\n  $RUBY_THEMELIST << ['kroc-rb', 'Kroc (by Ruby)', false]\nelse\n  $RUBY_THEMELIST << ['kroc-rb', 'Kroc (by Ruby)', true]\nend\n\ndef makeThemeControl(parent)\n  c = Tk::Tile::Labelframe.new(parent, :text=>'Theme')\n  $THEMELIST.each{|theme, name|\n    b = Tk::Tile::Radiobutton.new(c, :text=>name, :value=>theme, \n                                  :variable=>$V.ref(:THEME), \n                                  :command=>proc{setTheme(theme)})\n    b.grid(:sticky=>:ew)\n    unless (TkPackage.names.find{|n| n =~ /(tile|ttk)::theme::#{theme}/})\n      b.ttk_state(:disabled)\n    end\n  }\n  $RUBY_THEMELIST.each{|theme, name, available|\n    b = Tk::Tile::Radiobutton.new(c, :text=>name, :value=>theme, \n                                  :variable=>$V.ref(:THEME), \n                                  :command=>proc{setTheme(theme)})\n    b.grid(:sticky=>:ew)\n    b.ttk_state(:disabled) unless available\n  }\n  c\nend\n\ndef makeThemeMenu(parent)\n  m = TkMenu.new(parent)\n  $THEMELIST.each{|theme, name|\n    m.add(:radiobutton, :label=>name, :variable=>$V.ref(:THEME), \n          :value=>theme, :command=>proc{setTheme(theme)})\n    unless (TkPackage.names.find{|n| n =~ /(tile|ttk)::theme::#{theme}/})\n      m.entryconfigure(:end, :state=>:disabled)\n    end\n  }\n  $RUBY_THEMELIST.each{|theme, name, available|\n    m.add(:radiobutton, :label=>name, :variable=>$V.ref(:THEME), \n          :value=>theme, :command=>proc{setTheme(theme)})\n    m.entryconfigure(:end, :state=>:disabled) unless available\n  }\n  m\nend\n\ndef setTheme(theme)\n  if (pkg = TkPackage.names.find{|n| n =~ /(tile|ttk)::theme::#{theme}/})\n    unless Tk::Tile::Style.theme_names.find{|n| n == theme}\n      TkPackage.require(pkg)\n    end\n  end\n  Tk::Tile::Style.theme_use(theme)\nend\n\n#\n# Load icons...\n#\n$BUTTONS = ['open', 'new', 'save']\n$CHECKBOXES = ['bold', 'italic']\n$ICON = {}\n\ndef loadIcons(file)\n  Tk.load_tclscript(file)\n  img_data = TkVarAccess.new('ImgData')\n  img_data.keys.each{|icon|\n    $ICON[icon] = TkPhotoImage.new(:data=>img_data[icon])\n  }\nend\n\nloadIcons(File.join(demodir, 'iconlib.tcl'))\n\n#\n# Utilities:\n#\ndef foreachWidget(wins, cmd)\n  wins.each{|w|\n    cmd.call(w)\n    foreachWidget(w.winfo_children, cmd)\n  }\nend\n\n# sbstub\n#\tUsed as the :command option for a scrollbar,\n#\tupdates the scrollbar's position.\n#\ndef sbstub(sb, cmd, num, units = 'units')\n  num = TkComm.number(num)\n  case cmd.to_s\n  when 'moveto'\n    sb.set(num, num+0.5)\n\n  when 'scroll'\n    if units.to_s == 'pages'\n      delta = 0.2\n    else\n      delta = 0.05\n    end\n    current = sb.get\n    sb.set(current[0] + delta * num, current[1] + delta * num)\n  end\nend    \n\n# ... for debugging:\nTkBindTag::ALL.bind('ButtonPress-3', proc{|w| $W = w}, '%W')\nTkBindTag::ALL.bind('Control-ButtonPress-3', proc{|w| w.set_focus}, '%W')\n\ndef showHelp()\n  Tk.messageBox(:message=>'No help yet...')\nend\n\n#\n# See toolbutton.tcl.\nTkOption.add('*Toolbar.relief', :groove)\nTkOption.add('*Toolbar.borderWidth', 2)\n\nTkOption.add('*Toolbar.Button.Pad', 2)\n\n$ROOT = Tk.root\n$BASE = $ROOT\nTk.destroy(*($ROOT.winfo_children))\n\n$TOOLBARS = []\n\n#\n# Toolbar button standard vs. tile comparison:\n#\ndef makeToolbars\n  #\n  # Tile toolbar:\n  #\n  tb = Tk::Tile::Frame.new($BASE, :class=>'Toolbar')\n  $TOOLBARS << tb\n  i = 0\n  $BUTTONS.each{|icon|\n    i += 1\n    Tk::Tile::Button.new(tb, :text=>icon, :image=>$ICON[icon], \n                         :compound=>$V[:COMPOUND], \n                         :style=>:Toolbutton).grid(:row=>0, :column=>i, \n                                                   :sticky=>:news)\n  }\n  $CHECKBOXES.each{|icon|\n    i += 1\n    Tk::Tile::Checkbutton.new(tb, :text=>icon, :image=>$ICON[icon], \n                              :variable=>$V.ref(icon), \n                              :compound=>$V[:COMPOUND], \n                              :style=>:Toolbutton).grid(:row=>0, :column=>i, \n                                                        :sticky=>:news)\n  }\n\n  mb = Tk::Tile::Menubutton.new(tb, :text=>'toolbar', :image=>$ICON['file'], \n                                :compound=>$V[:COMPOUND])\n  mb.configure(:menu=>makeCompoundMenu(mb))\n  i += 1\n  mb.grid(:row=>0, :column=>i, :sticky=>:news)\n\n  i += 1\n  tb.grid_columnconfigure(i, :weight=>1)\n\n  #\n  # Standard toolbar:\n  #\n  tb = TkFrame.new($BASE, :class=>'Toolbar')\n  $TOOLBARS << tb\n  i = 0\n  $BUTTONS.each{|icon|\n    i += 1\n    TkButton.new(tb, :text=>icon, :image=>$ICON[icon], \n                 :compound=>$V[:COMPOUND], :relief=>:flat, \n                 :overrelief=>:raised).grid(:row=>0, :column=>i, \n                                            :sticky=>:news)\n  }\n  $CHECKBOXES.each{|icon|\n    i += 1\n    TkCheckbutton.new(tb, :text=>icon, :image=>$ICON[icon], \n                      :variable=>$V.ref(icon), :compound=>$V[:COMPOUND], \n                      :indicatoron=>false, :selectcolor=>'', :relief=>:flat, \n                      :overrelief=>:raised).grid(:row=>0, :column=>i, \n                                                 :sticky=>:news)\n  }\n\n  mb = TkMenubutton.new(tb, :text=>'toolbar', :image=>$ICON['file'], \n                        :compound=>$V[:COMPOUND])\n  mb.configure(:menu=>makeCompoundMenu(mb))\n  i += 1\n  mb.grid(:row=>0, :column=>i, :sticky=>:news)\n\n  i += 1\n  tb.grid_columnconfigure(i, :weight=>1)\nend\n\n#\n# Toolbar :compound control:\n#\ndef makeCompoundMenu(mb)\n  menu = TkMenu.new(mb)\n  %w(text image none top bottom left right center).each{|str|\n    menu.add(:radiobutton, :label=>Tk.tk_call('string', 'totitle', str), \n             :variable=>$V.ref(:COMPOUND), :value=>str, \n             :command=>proc{ changeToolbars() })\n  }\n  menu\nend\n\nmakeToolbars()\n\n## CONTROLS\ncontrol = Tk::Tile::Frame.new($BASE)\n\n#\n# Overall theme control:\n#\nmakeThemeControl(control).grid(:sticky=>:news, :padx=>6, :ipadx=>6)\ncontrol.grid_rowconfigure(99, :weight=>1)\n\ndef changeToolbars\n  foreachWidget($TOOLBARS, \n                proc{|w|\n                  begin\n                    w.compound($V[:COMPOUND])\n                  rescue\n                  end\n                })\nend\n\ndef scrolledWidget(parent, klass, themed, *args)\n  if themed\n    f = Tk::Tile::Frame.new(parent)\n    t = klass.new(f, *args)\n    vs = Tk::Tile::Scrollbar.new(f)\n    hs = Tk::Tile::Scrollbar.new(f)\n  else\n    f = TkFrame.new(parent)\n    t = klass.new(f, *args)\n    vs = TkScrollbar.new(f)\n    hs = TkScrollbar.new(f)\n  end\n  t.yscrollbar(vs)\n  t.xscrollbar(hs)\n\n  TkGrid.configure(t, vs, :sticky=>:news)\n  TkGrid.configure(hs, 'x', :sticky=>:news)\n  TkGrid.rowconfigure(f, 0, :weight=>1)\n  TkGrid.columnconfigure(f, 0, :weight=>1)\n\n  [f, t]\nend\n\n#\n# Notebook demonstration:\n#\ndef makeNotebook\n  nb = Tk::Tile::Notebook.new($BASE, :padding=>6)\n  nb.enable_traversal\n  client = Tk::Tile::Frame.new(nb)\n  nb.add(client, :text=>'Demo', :underline=>0)\n  nb.select(client)\n\n  scales = Tk::Tile::Frame.new(nb)\n  nb.add(scales, :text=>'Scales')\n  combo = Tk::Tile::Frame.new(nb)\n  nb.add(combo, :text=>'Combobox', :underline=>7)\n  tree = Tk::Tile::Frame.new(nb)\n  nb.add(tree, :text=>'Tree')\n  others = Tk::Tile::Frame.new(nb)\n  nb.add(others, :text=>'Others', :underline=>4)\n\n  [nb, client, scales, combo, tree, others]\nend\n\nnb, client, scales, combo, tree, others = makeNotebook()\n\n#\n# Side-by side check, radio, and menu button comparison:\n#\ndef fillMenu(menu)\n  %w(above below left right flush).each{|dir|\n    menu.add(:command, :label=>Tk.tk_call('string', 'totitle', dir), \n             :command=>proc{ menu.winfo_parent.direction(dir) })\n  }\n  menu.add(:cascade, :label=>'Submenu', :menu=>(submenu = TkMenu.new(menu)))\n  submenu.add(:command, :label=>'Subcommand 1')\n  submenu.add(:command, :label=>'Subcommand 2')\n  submenu.add(:command, :label=>'Subcommand 3')\n\n  menu.add(:separator)\n  menu.add(:command, :label=>'Quit', :command=>proc{Tk.root.destroy})\nend\n\nl = Tk::Tile::Labelframe.new(client, :text=>'Themed', :padding=>6)\nr = TkLabelframe.new(client, :text=>'Standard', :padx=>6, :pady=>6)\n\n## Styled frame\ncb = Tk::Tile::Checkbutton.new(l, :text=>'Checkbutton', \n                               :variable=>$V.ref(:SELECTED), :underline=>2)\nrb1 = Tk::Tile::Radiobutton.new(l, :text=>'One', :variable=>$V.ref(:CHOICE), \n                                :value=>1, :underline=>0)\nrb2 = Tk::Tile::Radiobutton.new(l, :text=>'Two', :variable=>$V.ref(:CHOICE), \n                                :value=>2)\nrb3 = Tk::Tile::Radiobutton.new(l, :text=>'Three', \n                                :variable=>$V.ref(:CHOICE), \n                                :value=>3, :underline=>0)\nbtn = Tk::Tile::Button.new(l, :text=>'Button', :underline=>0)\n\nmb = Tk::Tile::Menubutton.new(l, :text=>'Menubutton', :underline=>2)\nm = TkMenu.new(mb)\nmb.menu(m)\nfillMenu(m)\n\n$entryText = TkVariable.new('Entry widget')\ne = Tk::Tile::Entry.new(l, :textvariable=>$entryText)\ne.selection_range(6, :end)\n\nltext_f, ltext = scrolledWidget(l, TkText, true, \n                                :width=>12, :height=>5, :wrap=>:none)\n# NOTE TO MAINTAINERS: \n# The checkbuttons are -sticky ew / -expand x  on purpose:\n# it demonstrates one of the differences between TCheckbuttons\n# and standard checkbuttons.\n#\nTk.grid(cb, :sticky=>:ew)\nTk.grid(rb1, :sticky=>:ew)\nTk.grid(rb2, :sticky=>:ew)\nTk.grid(rb3, :sticky=>:ew)\nTk.grid(btn, :sticky=>:ew, :padx=>2, :pady=>2)\nTk.grid(mb, :sticky=>:ew, :padx=>2, :pady=>2)\nTk.grid(e, :sticky=>:ew, :padx=>2, :pady=>2)\nTk.grid(ltext_f, :sticky=>:news)\n\nTkGrid.columnconfigure(l, 0, :weight=>1)\nTkGrid.rowconfigure(l, 7, :weight=>1) # text widget (grid is a PITA)\n\n## Orig frame\ncb = TkCheckbutton.new(r, :text=>'Checkbutton', :variable=>$V.ref(:SELECTED))\nrb1 = TkRadiobutton.new(r, :text=>'One', \n                        :variable=>$V.ref(:CHOICE), :value=>1)\nrb2 = TkRadiobutton.new(r, :text=>'Two', :variable=>$V.ref(:CHOICE), \n                        :value=>2, :underline=>1)\nrb3 = TkRadiobutton.new(r, :text=>'Three', \n                        :variable=>$V.ref(:CHOICE), :value=>3)\nbtn = TkButton.new(r, :text=>'Button')\n\nmb = TkMenubutton.new(r, :text=>'Menubutton', :underline=>3, :takefocus=>true)\nm = TkMenu.new(mb)\nmb.menu(m)\n$V[:rmbIndicatoron] = mb.indicatoron\nm.add(:checkbutton, :label=>'Indicator?', #'\n      :variable=>$V.ref(:rmbIndicatoron), \n      :command=>proc{mb.indicatoron($V[:rmbIndicatoron])})\nm.add(:separator)\nfillMenu(m)\n\ne = TkEntry.new(r, :textvariable=>$entryText)\n\nrtext_f, rtext = scrolledWidget(r, TkText, false, \n                                :width=>12, :height=>5, :wrap=>:none)\n\nTk.grid(cb, :sticky=>:ew)\nTk.grid(rb1, :sticky=>:ew)\nTk.grid(rb2, :sticky=>:ew)\nTk.grid(rb3, :sticky=>:ew)\nTk.grid(btn, :sticky=>:ew, :padx=>2, :pady=>2)\nTk.grid(mb, :sticky=>:ew, :padx=>2, :pady=>2)\nTk.grid(e, :sticky=>:ew, :padx=>2, :pady=>2)\nTk.grid(rtext_f, :sticky=>:news)\n\nTkGrid.columnconfigure(l, 0, :weight=>1)\nTkGrid.rowconfigure(l, 7, :weight=>1) # text widget (grid is a PITA)\n\nTk.grid(l, r, :sticky=>:news, :padx=>6, :pady=>6)\nTkGrid.rowconfigure(client, 0, :weight=>1)\nTkGrid.columnconfigure(client, [0, 1], :weight=>1)\n\n#\n# Add some text to the text boxes:\n#\nmsgs = [\n\"The cat crept into the crypt, crapped and crept out again\", \n\"Peter Piper picked a peck of pickled peppers\", \n\"How much wood would a woodchuck chuck if a woodchuck could chuck wood\", \n\"He thrusts his fists against the posts and still insists he sees the ghosts\",\n\"Who put the bomb in the bom-b-bom-b-bom,\",\n\"Is this your sister's sixth zither, sir?\",\n\"Who put the ram in the ramalamadingdong?\",\n\"I am not the pheasant plucker, I'm the pheasant plucker's mate.\"\n]\n\nnmsgs = msgs.size\n(0...50).each{|n|\n  msg = msgs[n % nmsgs]\n  ltext.insert(:end, \"#{n}: #{msg}\\n\")\n  rtext.insert(:end, \"#{n}: #{msg}\\n\")\n}\n#\n# Scales and sliders pane:\n#\nl = Tk::Tile::Labelframe.new(scales, :text=>'Themed', :padding=>6)\nr = TkLabelframe.new(scales, :text=>'Standard', :padx=>6, :pady=>6)\n\nif version?('0.6')\n\n  # thremed frame\n  scale = Tk::Tile::Scale.new(l, :orient=>:horizontal, :from=>0, :to=>100,\n          :variable=>$V.ref(:SCALE))\n  vscale = Tk::Tile::Scale.new(l, :orient=>:vertical, :from=>0, :to=>100,\n          :variable=>$V.ref(:VSCALE))\n  progress = Tk::Tile::Progressbar.new(l, :orient=>:horizontal, :maximum=>100)\n  vprogress = Tk::Tile::Progressbar.new(l, :orient=>:vertical, :maximum=>100)\n\n  if true\n    def progress.inverted(w, value)\n      if w.mode == 'indeterminate'\n        w.value(value)\n      else\n        w.value(w.maximum - value)\n      end\n    end\n    scale.command {|value| progress.value(value)}\n    vscale.command {|value| progress.inverted(vprogress, value) }\n  else\n    # This would also work, but the Tk scale widgets \n    # in the right hand pane cause some interference when \n    # in autoincrement/indeterminate mode.\n    #\n    progress.variable $V.ref(:SCALE)\n    vprogress.variable $V.ref(:VSCALE)\n  end\n\n  scale.set(50)\n  vscale.set(50)\n\n  lmode = Tk::Tile::Label.new(l, :text=>'Progress bar mode')\n  pbmode0 = Tk::Tile::Radiobutton.new(l, :variable=>$V.ref(:PBMODE),\n          :text=>'determinate', :value=>'determinate',\n          :command=>proc{pbMode(progress, vprogress)})\n  pbmode1 = Tk::Tile::Radiobutton.new(l, :variable=>$V.ref(:PBMODE),\n          :text=>'indeterminate', :value=>'indeterminate',\n          :command=>proc{pbMode(progress, vprogress)})\n  def pbMode(progress, vprogress)\n    if vprogress.mode != $V[:PBMODE]\n      vprogress.value(vprogress.maximum - vprogress.value)\n    end\n\n    progress.mode $V[:PBMODE]\n    vprogress.mode $V[:PBMODE]\n  end\n\n  start = Tk::Tile::Button.new(l, :text=>\"Start\",\n          :command=>proc{pbStart(progress, vprogress)})\n  def pbStart(progress, vprogress)\n    # $V[:PBMODE] = 'indeterminate'\n    pbMode(progress, vprogress)\n    progress.start 10\n    vprogress.start\n  end\n\n  stop = Tk::Tile::Button.new(l, :text=>'Stop',\n          :command=>proc{pbStop(progress, vprogress)})\n  def pbStop(progress, vprogress)\n    progress.stop\n    vprogress.stop\n  end\n\n  Tk.grid(scale, :columnspan=>2, :sticky=>'ew')\n  Tk.grid(progress, :columnspan=>2, :sticky=>'ew')\n  Tk.grid(vscale, vprogress, :sticky=>'nws')\n\n  Tk.grid(lmode, :sticky=>'we', :columnspan=>2)\n  Tk.grid(pbmode0, :sticky=>'we', :columnspan=>2)\n  Tk.grid(pbmode1, :sticky=>'we', :columnspan=>2)\n  Tk.grid(start, :sticky=>'we', :columnspan=>2)\n  Tk.grid(stop, :sticky=>'we', :columnspan=>2)\n\n  l.grid_columnconfigure(0, :weight=>1)\n  l.grid_columnconfigure(1, :weight=>1)\n  l.grid_rowconfigure(99, :weight=>1)\n\n  # standard frame\n  TkScale.new(r, :orient=>:horizontal, :from=>0, :to=>100,\n          :variable=>$V.ref(:SCALE)).grid(:sticky=>'news')\n  TkScale.new(r, :orient=>:vertical, :from=>0, :to=>100,\n          :variable=>$V.ref(:VSCALE)).grid(:sticky=>'nws')\n\n  r.grid_columnconfigure(0, :weight=>1)\n  r.grid_columnconfigure(1, :weight=>1)\n  r.grid_rowconfigure(99, :weight=>1)\n\nelse # tile 0.5 or earlier\n\n  # themed frame\n  scale = Tk::Tile::Scale.new(l, :variable=>$V.ref(:SCALE),\n          :orient=>:horizontal, :from=>0, :to=>100)\n  vscale = Tk::Tile::Scale.new(l, :variable=>$V.ref(:VSCALE),\n          :orient=>:vertical, :from=>-25, :to=>25)\n\n  progress = Tk::Tile::Progress.new(l,\n          :orient=>:horizontal, :from=>0, :to=>100)\n  vprogress = Tk::Tile::Progress.new(l,\n          :orient=>:vertical, :from=>-25, :to=>25)\n\n  if true\n    scale.command{|value| progress.set(value)}\n    vscale.command{|value| vprogress.set(value)}\n  else # this would also work. (via TkVariable#trace)\n    v1 = scale.variable\n    v2 = vscale.variable\n    v1.trace('w', proc{ progress.set(v1.value) })\n    v2.trace('w', proc{ vprogress.set(v2.value) })\n  end\n\n  Tk.grid(scale, :columnspan=>2, :sticky=>:ew)\n  Tk.grid(progress, :columnspan=>2, :sticky=>:ew)\n  Tk.grid(vscale, vprogress, :sticky=>:nws)\n  TkGrid.columnconfigure(l, 0, :weight=>1)\n  TkGrid.columnconfigure(l, 1, :weight=>1)\n\n  # standard frame\n  TkScale.new(r, :variable=>$V.ref(:SCALE),\n          :orient=>:horizontal, :from=>0, :to=>100).grid(:sticky=>'news')\n  TkScale.new(r, :variable=>$V.ref(:VSCALE),\n          :orient=>:vertical, :from=>-25, :to=>25).grid(:sticky=>'nws')\n\n  TkGrid.columnconfigure(r, 0, :weight=>1)\n  TkGrid.columnconfigure(r, 1, :weight=>1)\nend\n\n# layout frames\nTk.grid(l, r, :sticky=>'nwes', :padx=>6, :pady=>6)\nscales.grid_columnconfigure(0, :weight=>1)\nscales.grid_columnconfigure(1, :weight=>1)\nscales.grid_rowconfigure(0, :weight=>1)\n\n#\n# Command box:\n#\ncmd = Tk::Tile::Frame.new($BASE)\nb_close = Tk::Tile::Button.new(cmd, :text=>'Close', \n                               :underline=>0, :default=>:normal, \n                               :command=>proc{Tk.root.destroy})\nb_help = Tk::Tile::Button.new(cmd, :text=>'Help', :underline=>0, \n                              :default=>:normal, :command=>proc{showHelp()})\nTk.grid('x', b_close, b_help, :pady=>[6, 4], :padx=>4)\nTkGrid.columnconfigure(cmd, 0, :weight=>1)\n\n#\n# Set up accelerators:\n#\n$ROOT.bind('KeyPress-Escape', proc{Tk.event_generate(b_close, '<Invoke>')})\n$ROOT.bind('<Help>', proc{Tk.event_generate(b_help, '<Invoke>')})\nTk::Tile::KeyNav.enableMnemonics($ROOT)\nTk::Tile::KeyNav.defaultButton(b_help)\n\nTk.grid($TOOLBARS[0], '-', :sticky=>:ew)\nTk.grid($TOOLBARS[1], '-', :sticky=>:ew)\nTk.grid(control,      nb,  :sticky=>:news)\nTk.grid(cmd,          '-', :sticky=>:ew)\nTkGrid.columnconfigure($ROOT, 1, :weight=>1)\nTkGrid.rowconfigure($ROOT, 2, :weight=>1)\n\n#\n# Add a menu\n#\nmenu = TkMenu.new($BASE)\n$ROOT.menu(menu)\nm_file = TkMenu.new(menu, :tearoff=>0)\nmenu.add(:cascade, :label=>'File', :underline=>0, :menu=>m_file)\nm_file.add(:command, :label=>'Open', :underline=>0, \n           :compound=>:left, :image=>$ICON['open'])\nm_file.add(:command, :label=>'Save', :underline=>0, \n           :compound=>:left, :image=>$ICON['save'])\nm_file.add(:separator)\nm_f_test = TkMenu.new(menu, :tearoff=>0)\nm_file.add(:cascade, :label=>'Test submenu', :underline=>0, :menu=>m_f_test)\nm_file.add(:checkbutton, :label=>'Text check', :underline=>5, \n           :variable=>$V.ref(:MENUCHECK1))\nm_file.insert(:end, :separator)\n\nif Tk.windowingsystem != 'x11'\n  TkConsole.create\n  m_file.insert(:end, :checkbutton, :label=>'Console', :underline=>5, \n                :variable=>$V.ref(:CONSOLE), :command=>proc{toggle_console()})\n  def toggle_console\n    if TkComm.bool($V[:CONSOLE])\n      TkConsole.show\n    else\n      TkConsole.hide\n    end\n  end\nend\n\nm_file.add(:command, :label=>'Exit', :underline=>1, \n           :command=>proc{Tk.event_generate(b_close, '<Invoke>')})\n\n%w(One Two Three Four).each{|lbl|\n  m_f_test.add(:radiobutton, :label=>lbl, :variable=>$V.ref(:MENURADIO1))\n}\n\n# Add Theme menu.\n#\nmenu.add(:cascade, :label=>'Theme', :underline=>3, \n         :menu=>makeThemeMenu(menu))\n\nsetTheme($V[:THEME])\n\n#\n# Combobox demo pane:\n#\nvalues = %w(list abc def ghi jkl mno pqr stu vwx yz)\n2.times {|i|\n  cb = Tk::Tile::Combobox.new(\n    combo, :values=>values, :textvariable=>$V.ref(:COMBO))\n  cb.pack(:side=>:top, :padx=>2, :pady=>2, :expand=>false, :fill=>:x)\n  if i == 1\n    cb.ttk_state :readonly\n    begin\n      cb.current = 3 # ignore if unsupported (tile0.4)\n    rescue\n    end\n  end\n}\n\n#\n# Treeview widget demo pane:\n#\nif version?('0.5')\n\n  treeview = nil # avoid 'undefined' error\n  scrollbar = Tk::Tile::Scrollbar.new(tree,\n      :command=>proc{|*args| treeview.yview(*args)})\n  treeview = Tk::Tile::Treeview.new(tree, :columns=>%w(Class), :padding=>4,\n      :yscrollcommand=>proc{|*args| scrollbar.set(*args)})\n\n  Tk.grid(treeview, scrollbar, :sticky=>'news')\n  tree.grid_columnconfigure(0, :weight=>1)\n  tree.grid_rowconfigure(0, :weight=>1)\n  tree.grid_propagate(0)\n\n  # Add initial tree node: \n  # Later nodes will be added in <<TreeviewOpen>> binding.\n  treeview.insert('', 0, :id=>'.', :text=>'Main Window', :open=>false,\n      :values=>[TkWinfo.classname('.')])\n  treeview.headingconfigure('#0', :text=>'Widget')\n  treeview.headingconfigure('Class', :text=>'Class')\n  treeview.bind('<TreeviewOpen>', proc{fillTree(treeview)})\n\n  def fillTree(treeview)\n    id = treeview.focus_item\n    unless TkWinfo.exist?(id)\n      treeview.delete(id)\n    end\n    # Replace tree item children with current list of child windows.\n    treeview.delete(treeview.children(id))\n    for child in TkWinfo.children(id)\n      treeview.insert(id, :end, :id=>child, :text=>TkWinfo.appname(child),\n          :open=>false, :values=>[TkWinfo.classname(child)])\n      unless TkWinfo.children(child).empty?\n        # insert dummy child to show [+] indicator\n        treeview.insert(child, :end)\n      end\n    end\n  end\n\nelse\n  Tk::Tile::Label.new(tree,\n      :text=>'Treeview is supported on tile 0.5 or later...').pack\nend\n\n#\n# Other demos:\n#\n$Timers = {:StateMonitor=>nil, :FocusMonitor=>nil}\n\nbegin\n  msg = Tk::Tile::Label.new(others, :justify=>:left, :wraplength=>300)\nrescue\n  msg = TkMessage.new(others, :aspect=>200)\nend\n\n$Desc = {}\n\nshowDescription = TkBindTag.new\nshowDescription.bind('Enter', proc{|w| msg.text($Desc[w.path])}, '%W')\nshowDescription.bind('Leave', proc{|w| msg.text('')}, '%W')\n\n[\n  [ :trackStates, \"Widget states...\",  \n    \"Display/modify widget state bits\" ], \n\n  [ :scrollbarResizeDemo,  \"Scrollbar resize behavior...\", \n    \"Shows how Tile and standard scrollbars differ when they're sized too large\" ], \n\n  [ :trackFocus, \"Track keyboard focus...\" , \n    \"Display the name of the widget that currently has focus\" ],\n\n  [ :repeatDemo, \"Repeating buttons...\",\n    \"Demonstrates custom classes (see demos/repeater.tcl)\" ]\n\n].each{|demo_cmd, label, description|\n  b = Tk::Tile::Button.new(others, :text=>label, \n                           :command=>proc{ self.__send__(demo_cmd) })\n  $Desc[b.path] = description\n  b.bindtags <<= showDescription\n\n  b.pack(:side=>:top, :expand=>false, :fill=>:x, :padx=>6, :pady=>6)\n}\n\nmsg.pack(:side=>:bottom, :expand=>true, :fill=>:both)\n\n\n#\n# Scrollbar resize demo:\n#\n$scrollbars = nil\n\ndef scrollbarResizeDemo\n  if $scrollbars\n    begin\n      $scrollbars.destroy\n    rescue\n    end\n  end\n  $scrollbars = TkToplevel.new(:title=>'Scrollbars', :geometry=>'200x200')\n  f = TkFrame.new($scrollbars, :height=>200)\n  tsb = Tk::Tile::Scrollbar.new(f, :command=>proc{|*args| sbstub(tsb, *args)})\n  sb = TkScrollbar.new(f, :command=>proc{|*args| sbstub(sb, *args)})\n  Tk.grid(tsb, sb, :sticky=>:news)\n\n  sb.set(0, 0.5)  # prevent backwards-compatibility mode for old SB\n\n  f.grid_columnconfigure(0, :weight=>1)\n  f.grid_columnconfigure(1, :weight=>1)\n  f.grid_rowconfigure(0, :weight=>1)\n\n  f.pack(:expand=>true, :fill=>:both)\nend\n\n#\n# Track focus demo:\n#\n$FocusInf = TkVariable.new_hash\n$focus = nil\n\ndef trackFocus\n  if $focus\n    begin\n      $focus.destroy\n    rescue\n    end\n  end\n  $focus = TkToplevel.new(:title=>'Keyboard focus')\n  i = 0\n  [\n    [\"Focus widget:\", :Widget], \n    [\"Class:\", :WidgetClass], \n    [\"Next:\", :WidgetNext], \n    [\"Grab:\", :Grab], \n    [\"Status:\", :GrabStatus]\n  ].each{|label, var_index|\n    Tk.grid(Tk::Tile::Label.new($focus, :text=>label, :anchor=>:e), \n            Tk::Tile::Label.new($focus, \n                                :textvariable=>$FocusInf.ref(var_index), \n                                :width=>40, :anchor=>:w, :relief=>:groove), \n            :sticky=>:ew)\n    i += 1\n  }\n  $focus.grid_columnconfigure(1, :weight=>1)\n  $focus.grid_rowconfigure(i, :weight=>1)\n\n  $focus.bind('Destroy', proc{Tk.after_cancel($Timers[:FocusMonitor])})\n  focusMonitor\nend\n\ndef focusMonitor\n  $FocusInf[:Widget] = focus_win = Tk.focus\n  if focus_win\n    $FocusInf[:WidgetClass] = focus_win.winfo_classname\n    $FocusInf[:WidgetNext] = Tk.focus_next(focus_win)\n  else\n    $FocusInf[:WidgetClass] = $FocusInf[:WidgetNext] = ''\n  end\n\n  $FocusInf[:Grab] = grab_wins = Tk.current_grabs\n  unless grab_wins.empty?\n    $FocusInf[:GrabStatus] = grab_wins[0].grab_status\n  else  \n    $FocusInf[:GrabStatus] = ''\n  end\n\n  $Timers[:FocusMonitor] = Tk.after(200, proc{ focusMonitor() })\nend\n\n#\n# Widget state demo:\n#\n$Widget = TkVariable.new\n\nTkBindTag::ALL.bind('Control-Shift-ButtonPress-1', \n                    proc{|w|\n                      $Widget.value = w\n                      updateStates()\n                      Tk.callback_break\n                    }, '%W')\n$states_list = %w(active disabled focus pressed selected \n                  background indeterminate invalid default)\n$states_btns = {}\n$states = nil\n\n$State = TkVariable.new_hash\n\ndef trackStates\n  if $states\n    begin\n      $state.destroy\n    rescue\n    end\n  end\n  $states = TkToplevel.new(:title=>'Widget states')\n\n  l_inf = Tk::Tile::Label.new($states, :text=>\"Press Control-Shift-Button-1 on any widget\")\n\n  l_lw = Tk::Tile::Label.new($states, :text=>'Widget:', \n                             :anchor=>:e, :relief=>:groove)\n  l_w = Tk::Tile::Label.new($states, :textvariable=>$Widget, \n                             :anchor=>:w, :relief=>:groove)\n\n  Tk.grid(l_inf, '-', :sticky=>:ew, :padx=>6, :pady=>6)\n  Tk.grid(l_lw, l_w, :sticky=>:ew)\n\n  $states_list.each{|st|\n    cb = Tk::Tile::Checkbutton.new($states, :text=>st, \n                                   :variable=>$State.ref(st), \n                                   :command=>proc{ changeState(st) })\n    $states_btns[st] = cb\n    Tk.grid('x', cb, :sticky=>:nsew)\n  }\n\n  $states.grid_columnconfigure(1, :weight=>1)\n\n  f_cmd = Tk::Tile::Frame.new($states)\n  Tk.grid('x', f_cmd, :sticky=>:nse)\n\n  b_close = Tk::Tile::Button.new(f_cmd, :text=>'Close', \n                                 :command=>proc{ $states.destroy })\n  Tk.grid('x', b_close, :padx=>4, :pady=>[6,4])\n  f_cmd.grid_columnconfigure(0, :weight=>1)\n\n  $states.bind('KeyPress-Escape', proc{Tk.event_generate(b_close, '<Invoke>')})\n\n  $states.bind('Destroy', proc{Tk.after_cancel($Timers[:StateMonitor])})\n  stateMonitor()\nend\n\ndef stateMonitor\n  updateStates() if $Widget.value != ''\n  $Timers[:StateMonitor] = Tk.after(200, proc{ stateMonitor() })\nend\n\ndef updateStates\n  $states_list.each{|st|\n    begin\n      $State[st] = $Widget.window.ttk_instate(st)\n    rescue\n      $states_btns[st].ttk_state('disabled')\n    else\n      $states_btns[st].ttk_state('!disabled')\n    end\n  }\nend\n\ndef changeState(st)\n  if $Widget.value != ''\n    if $State.bool_element(st)\n      $Widget.window.ttk_state(st)\n    else\n      $Widget.window.ttk_state(\"!#{st}\")\n    end\n  end\nend\n\n#\n# Repeating buttons demo:\n#\ndef repeatDemo\n  if defined?($repeatDemo) && $repeatDemo.exist?\n    $repeatDemo.deiconify; return\n  end\n  $repeatDemo = TkToplevel.new(:title=>'Repeating button')\n\n  f = Tk::Tile::Frame.new($repeatDemo)\n  b = Tk::Tile::Button.new(f, :class=>'Repeater', :text=>'Press and hold')\n  if version?('0.6')\n    p = Tk::Tile::Progressbar.new(f, :orient=>:horizontal, :maximum=>10)\n  else # progressbar is not supported\n    p = Tk::Tile::Progress.new(f, :orient=>:horizontal, :from=>0, :to=>10)\n    def p.step\n      i = self.get + 1\n      i = self.from if i > self.to\n      self.set(i)\n    end\n  end\n  b.command {p.step}\n\n  b.pack(:side=>:left, :expand=>false, :fill=>:none, :padx=>6, :pady=>6)\n  p.pack(:side=>:right, :expand=>true, :fill=>:x, :padx=>6, :pady=>6)\n  f.pack(:expand=>true, :fill=>:both)\nend\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/iconlib.tcl",
    "content": "array set ImgData {\nbold {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAI6hI+py60U3wj+\nRYQFJYRvEWFBCeFbRFhQQvhG8YPgX0RYUEL4FhEWlBC+RYQFJYQPFN8IPqYut/8hBQA7}\ncopy {R0lGODlhEAAQAJEAANnZ2QAAAP///wAAhCH5BAEAAAAALAAAAAAQABAAAAJUhI8JFJ/gY4iI\nUEL4FyIiFIXgW0iEUDgfACBI9pzMAAGRiIghWSMDECR7JEKGtkFIRFBG+TIQKDQxtgzcDcmX\nIfgwQrFlCD4MyZch+EDzj+Bj6mYBADs=}\ncut {R0lGODlhEAAQAJEAANnZ2QAAAAAAhP///yH5BAEAAAAALAAAAAAQABAAAAJFhI+pcUHwEeIi\nE0gACIKPEAFBIXy0gMg8EhM+YmQiKSL4eAIiJMI/EQEhQGYGYiQIQAg+iAkIATIzECMBIgT/\nRBARERlSADs=}\ndragfile {R0lGODlhGAAYAKIAANnZ2TMzM////wAAAJmZmf///////////yH5BAEAAAAALAAAAAAYABgA\nAAPACBi63IqgC4GiyxwogaAbKLrMgSKBoBoousyBogEACIGiyxwoKgGAECI4uiyCExMTOACB\nosuNpDoAGCI4uiyCIkREOACBosutSDoAgSI4usyCIjQAGCi63Iw0ACEoOLrMgiI0ABgoutyM\nNAAhKDi6zIIiNAAYKLrcjDQAISg4usyCIjQAGCi63Iw0AIGiiqPLIyhCA4CBosvNSAMQKKo4\nujyCIjQAGCi63Iw0AIGiy81IAxCBpMu9GAMAgKPL3QgJADs=}\ndragicon {R0lGODlhGAAYALMAANnZ2TMzM/////8zM8zMzGYAAAAAAJmZmQCZMwAzZgCZzGZmZv//////\n/////////yH5BAEAAAAALAAAAAAYABgAAAT/EMAgJ60SAjlBgEJOSoMIEMgZoJCT0iADBFIG\nKOSkNMwAAABhwiHnIEKIIIQQAQIZhBBwyDmKEMIEE0yABoAghIBDzlGEENDIaQAIQgg45BwF\nCinPOccAECYcUiKEEBFCiHPgMQAEIcQYYyABBUGIQCHlMQCEScZAAhKEEApCECGOARAEIQQp\nBRGIpAyCJCGOASBAISdEcqJAVBLiGABggELOAJGUKyiVhDgGABigkJMEhNAKSqkEhTgGgCCl\nFCQEGIJSSiUhjgEgQCEnJVBJmYQ4BoAAhZyTQCVnEuIYAAIUckoCk5xSiGMACFDISSs9BoBg\nrRXQMQAEKOSklR4DEUAI8MhJ6wwGAACgkZNWCkAEADs=}\nerror {R0lGODlhIAAgAKIAANnZ2YQAAP8AAISEhP///////////////yH5BAEAAAAALAAAAAAgACAA\nAAP/CLoMGLqKoMvtGIqiqxEYCLrcioGiyxwIusyBgaLLLRiBoMsQKLrcjYGgu4Giy+2CAkFX\nA0WX2wXFIOgGii7trkCEohsDCACBoktEKLpKhISiGwAIECiqSKooukiqKKoxgACBooukKiIo\nSKooujGDECi6iqQqsopEV2MQAkV3kXQZRXdjEAJFl5F0FUWXY3ACRZcFSRdFlyVwJlB0WZB0\nUXRZAmcCRZeRdBVFl2NwAkV3kXQZRXdjcAJFV5FURVaR6GoMDgSKLpKqiKAgqaLoxgwOBIoq\nkiqKLpIqimrM4ECg6BIRiq4SIaHoxgyCBoou7a5AhKIbMzgAAIGiy+2CTWJmBhAAAkWX2wXF\nzCDoBooud2PMDIKuRqDocgtGzMwg6O4Eii5z4Kgi6DIMhqLoagQGjiqCLvPgYOgqji6CLrfi\n6DIj6HI7jq4i6DIkADs=}\nfile {R0lGODlhCwANAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAALAA0AAAIyhI9G8Q0AguSH\nAMQdxQgxEyEFQfItICQokYgEBMm3gBCKLRIQJN8CQii2SECQfAug+FgAOw==}\nfolder {R0lGODlhEAANAKIAANnZ2YSEhMbGxv//AP///wAAAP///////yH5BAEAAAAALAAAAAAQAA0A\nAANjCIqhiqDLITgyEgi6GoIjIyMYugCBpMsaWBA0giMjIzgyUYBBMjIoIyODEgVBODIygiMj\nE1gQJIMyMjIoI1GAQSMjODIyghMFQSgjI4MyMhJYEDSCIyMjODJRgKHLXAiApcucADs=}\nhourglass {R0lGODlhIAAgAKIAANnZ2YAAAAAAAP8AAP///8DAwICAgP///yH5BAEAAAAALAAAAAAgACAA\nAAPZCLrc/jDKSau9OGcUuqyCoMvNGENVhaMrCLrcjaLLgqDL7WhFVIVVZoKgy+1oRUSFVWaC\noMvtaEVEhVVmgqDL7WhFRIVVZoKgy+1oVVaCJWaCoMvtgKxISrBMEHS5fZEVSRkKgi63NzIq\nEwRdbndkVCYIutzeyIqqDAVBl9sXWRFJYZkg6HI7ICsiKqwyEwRdbkcrIhKsMhMEXW5HKyIp\nlDITBF1uRysyEiwxEwRdbkcrIyuUEhMEXW5H0WVB0OVujKGqwtEVBF1uRtHlRdDl9odRTlrt\nxRmjBAA7}\ninfo {R0lGODlhIAAgAKIAANnZ2YSEhMbGxv///wAA/wAAAP///////yH5BAEAAAAALAAAAAAgACAA\nAAP/CLoMGLqKoMvtGCo4uhKBgaDLDRghOLqsghEIuryBgqPLPSiBoMsQOLojhEQkOLpTCLob\nOLqKpIujq4WgC4Gju0i6OLpbCKohOLorhEQkOLorhaAQOLrc3qgCIARHl9sbSQUEji4j6RKO\nLk9hQODosiKp4ujyFIbi6LIiqeLo8hSG4uiyIqni6PIUhuLosiKp4ujyFIYKji4PkiqOLkth\nBASOLg+SKo4uV2AEhODoMpIqju5KYShA4Ogqku7i6E4FRgAAYOHocvugiohAUC0cXe7GiohA\n0IUSHF3uQamICATdrULB0WUVrIqIQNBlCCwVHF2pwsJQRdDlDYyoKsHRPMLQDQRdbsDQqBmc\nwlBF0OV2jJqZwggEXW5vVDMVgaDL7Y5qKgJBl9sfVUUg6HL7AxSKoMvtr1AEgi5DAgA7}\nitalic {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAIrhI+py+1A4hN8\nhIjINBITPlpEZBqJCR8tIjKNxISPFhGZQOITfExdbv9FCgA7}\nnew {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAJFhI95FN8IvgXJ\njyD4ECQ/JAh+kPyICIIdJP+CYAfJvyDYQfIvCHaQ/AuCHST/gmAHyb8g2EHyLwh2kPwLgk3x\nMQg+pu4WADs=}\nopen {R0lGODlhEAAQAKIAANnZ2QAAAP//AP///4SEAP///////////yH5BAEAAAAALAAAAAAQABAA\nAANZCLrczigUQZc1EDQgEHSZAwMgIhB0NQIDQkYwdANBNUZwZGQEJxBUQwZlZGRQAkE1RnAE\nQ5dVcCSQdDcAYySQdDcAISSQdDcAASKQdDcAAQBDlwNBl9sfApQAOw==}\nopenfold {R0lGODlhEAANAKIAANnZ2YSEhP///8bGxv//AAAAAP///////yH5BAEAAAAALAAAAAAQAA0A\nAANgCIqhiqDLgaIaCLoagkNDIxi6AIFCQ0M4KKpRgCFDQzg0NIQThaHLSxgVKLochRMVMkhD\nQ4M0VBFYEDKEQ0NDOFFRgCE0NEhDQ4MVBRAoNDSEQ0NRWAAYuqyFBQBYurwJADs=}\noverstrike {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAI3hI+py80Uh+Aj\nRFhQCP8iMILgWwRGEHyLwAiCbxEYQfCB4iPBhwiMIPgXYREEHyEiguBj6nI7FQA7}\npalette {R0lGODlhEAAQAKIAANnZ2QAAAP//AP////8A/4QAhP8AAAD//yH5BAEAAAAALAAAAAAQABAA\nAANtCLrcjqGBoMsRKCMTgaALMSgDAYMSCKoxgAFBITgSAIAQEhUIARCAEgAQOBAwghMQEwga\nMoIjIxAIEgCAEBEyKBAgg4GgGxAIYTGCgaALcRgQIIGgCwEYICODgaALITgyEoGguxiqCLrc\n/lChBAA7}\npasswd {R0lGODlhIAAgAMQAANnZ2QAAAICAgICAAP///7CwsMDAwMjIAPjIAOjo6Pj4AODg4HBwcMj4\nANjY2JiYANDQ0MjIyPj4yKCgoMiYAMjImDAwAMjIMJiYmJCQkP//////////////////////\n/yH5BAEAAAAALAAAAAAgACAAAAX/ICCOIhiIIgiII1maZSCMQnCeJyAIQiAIAiAMwxCcJwkk\nEAQRCIUwGMSBDEEAAuJIlgKRJEEgGAMRBIGiDENQlqNAJAsYCEwgEEEgBAHSIEMAAuJIAgKR\nLEsgGEMgCEJgBMqhHENQlgJILMsSCMRABEFgGAESHMcRgIA4kgKxOIsTBAOhKAITKEGDHMhD\nkqIAEqAjisJAgIooBkpwNMcTgIA4jgLhOBAkEAOhKIoSKEGDIMcTkKQICgQEQQIxEIqiBEpw\nIMdxPAEIiCMJCEQUMUQ0EIqiHIfSIM3xBGUpCiABCUQyEMqhHMiBHMjxBCAgjuQoEAKxRANB\nHMqhHM1x/zxDUJajQIACsUTDQBAEIR3IcQRDAALiSIoCYQiEE03gII7HQR3BEICAOJICYRSC\nQDjRNE1CAAzVQR3WE5AkAAqEUQiFQEARBAUAAAzHQR3BEICAOI4CUQhFIBAREwXjUFUHdQRD\nQJJAABbCFAhEJBgBAADAMAwXdQRDAALiCAhEIRQCYRiCEZDjUFFHMAQkIBAFOAmTQBiFUAQg\nII7AUFXUEQwBCQjEJExBkBRCEZCjMIBD9RxDAALiGEzCFBBYIRTBOI7AQB1DMIoCMQkYGAjL\nJEwBCIgjOVDDEJCAQGACJiTTJEwBSY5BEJAiSCCwTAiCZBKmAATEkSzNQBCCYCDBJgELTNMk\ng0AMEgwTAhAQR7I0zYARgvM8TyAIznMMAQA7}\npaste {R0lGODlhEAAQAKIAANnZ2QAAAP//AISEAISEhP///wAAhP///yH5BAEAAAAALAAAAAAQABAA\nAANwCLrcjqGBoKsYqiKrCDSGBkMiJJCGAgCDKBB0gwYDIKYwdJUIAyBokIaGBmloAhBiaAgH\nTdcCEIKGBsmwVM0AIYaGcAxL1coQgoYGySoisMzMAoeGxrB01QJpaMiwMHTLAEPVsHTVEHTR\ndBlBlxswAQA7}\nprint {R0lGODlhEAAQAKIAANnZ2QAAAP///4SEhP//AP///////////yH5BAEAAAAALAAAAAAQABAA\nAANZCLrcjqG7CLqBoquBoBuCoSqBoBsouhoIuiEYqrKBoIGiqwEYEIChyxAIEYGgywEYgKHL\nDAgRCLozgwABARgIukSEABEBGLq8gAEQCLobgAEAgKHLgaDLzZgAOw==}\nquestion {R0lGODlhIAAgAKIAANnZ2YSEhMbGxv///wAAAAAA/////////yH5BAEAAAAALAAAAAAgACAA\nAAP/CLoMGLqKoMvtGCo4uhKBgaDLDRghOLqsghEIuryBgqPLPSiBoMsQOLrcjYSgu4GjO4Kl\nKzi6Qwi6EDi6I4UyU1VYgqM7hKAagqM7VTg6VYWFoztCCAqBo6tVWDVThVU4ukqBACE4ulqF\nVSNVWIWjq0IYEDi6K4UlU1VYOLpMgRA4uryCpTi6PIShOLq8hVU4uqyEoTi6vIUlOLqshKE4\nuryFhaPLSxgqOLrc3kgoAgJHl0ewSnB0eQhDIQRHl6uwCkeXhTAUIHB0uQqrcHSZAiMAAJBw\ndFcKS3B0lwIjAkGVcHS5GykiAkEXSHB0uQeFIiIQdJcIBUeXVZAoIgJBT5chkFRwdIUICUMV\nQZc3MIKIBEcJQzcQdLkBQ4NmcAhDFUGX2zFoZggjEHS5vRHNUASCLrc7oqEIBF1uf0QUgaDL\n7Q9QKIIut79CEQi6DAkAOw==}\nredo {R0lGODlhEAAQAJEAANnZ2QAAhP///////yH5BAEAAAAALAAAAAAQABAAAAIvhI+py+1vSByC\njxAYQXDMwsyAggQAQBB8iwgMgg8REQgUwqbYBDsIPqYutz+MgBQAOw==}\nsave {R0lGODlhEAAQAJEAANnZ2QAAAISEAP///yH5BAEAAAAALAAAAAAQABAAAAJWhI9pFB8RIIRC\n+BYQFqQQvkWEBSmEbyFhQQrhW0hYkEL4FhIWpBC+hYQFSYxvIgFAoXy0AAiSGP8kAIIkxgcI\nCSBEQvEBQgIIkVB8gJAAAhgfj+BjWgEAOw==}\nunderline {R0lGODlhEAAQAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAQABAAAAI3hI+py60UBy4I\nvkVcBMG/iIsg+BdxEQT/Ii6C4F/ERRD8i7gIgn8RF0HwkWITfExFin8EH1OXCwA7}\nundo {R0lGODlhEAAQAJEAANnZ2QAAhP///////yH5BAEAAAAALAAAAAAQABAAAAIuhI+py+2vSByC\nHxdxQCHsCIg7oAAAEUHwLTAiKIQPgRSbYMfd3VEIH1OX2x8mUgA7}\nwarning {R0lGODlhIAAgAKIAANnZ2YSEAP//AMbGxgAAAISEhP///////yH5BAEAAAAALAAAAAAgACAA\nAAP/CLq8gREIutz+KESGEHS5vVGIiAxSIehy+6JAUaUqBF1uBxQoukOFhaDL7RgoukKFhaDL\n3RgoujqEVQi63IyBortUWAi63IuBostDWIWgy60YIjKERCMiSFUIutyAISKCpCoiOFSFoMsd\nKCpIqiKCQlUIusyBooqkKiIoQ1UIuryBooqkiqJKVQi6rIGii6SKojpUWAi6DIGiG0RIgaJL\nVQi6HCi6MoREg6I7VFgIuhsoukqEhKKrVFgIuhoouhuEgaKrQ1iFoAuBortDOCi6S4WFoBso\nuiyEostDWIWgGii63K6IqgAAIVB0WQaJBkV3h7AKAAJFl4WQiFB0mQoLRyBQdFkJiQhFl4ew\nCgJFl3WQaFB0WQirIFB0ud0RVVWg6HJ7o6GqAgwUXW5fNFRVhQCBpMvti0oVABCwdLndEehi\n6XI7I4AEADs=}\n}\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/readme.txt",
    "content": "All of *.tcl and under themes/ directory (except kroc.rb) are \nquoted from Tcl/Tk's Tile extension. Please read Orig_LICENSE.txt. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/repeater.tcl",
    "content": "#\n# $Id$\n#\n# Demonstration of custom classes.\n#\n# The Tile button doesn't have built-in support for autorepeat.\n# Instead of adding -repeatdelay and -repeatinterval options,\n# and all the extra binding scripts required to deal with them,\n# we create a custom widget class for autorepeating buttons.\n#\n# Usage:\n#\tttk::button .b -class Repeater [... other options ...]\n#\n# TODO:\n#\tUse system settings for repeat interval and initial delay.\n#\n# Notes:\n#\tRepeater buttons work more like scrollbar arrows than\n#\tTk repeating buttons: they fire once immediately when\n#\tfirst pressed, and $State(delay) specifies the initial \n#\tinterval before the button starts autorepeating.\n#\n\nnamespace eval tile::Repeater {\n    variable State\n    set State(timer) \t{}\t;# [after] id of repeat script\n    set State(interval)\t100\t;# interval between repetitions\n    set State(delay)\t300\t;# delay after initial invocation\n}\n\n### Class bindings.\n#\n\nbind Repeater <Enter>\t\t{ %W state active }\nbind Repeater <Leave>\t\t{ %W state !active }\n\nbind Repeater <Key-space> \t{ tile::Repeater::Activate %W }\nbind Repeater <<Invoke>> \t{ tile::Repeater::Activate %W }\n\nbind Repeater <ButtonPress-1> \t{ tile::Repeater::Press %W }\nbind Repeater <ButtonRelease-1> { tile::Repeater::Release %W }\nbind Repeater <B1-Leave> \t{ tile::Repeater::Pause %W }\nbind Repeater <B1-Enter> \t{ tile::Repeater::Resume %W } ;# @@@ see below\n\n# @@@ Workaround for metacity-induced bug:\nbind Repeater <B1-Enter> \\\n    { if {\"%d\" ne \"NotifyUngrab\"} { tile::Repeater::Resume %W } }\n\n### Binding procedures.\n#\n\n## Activate -- Keyboard activation binding. \n#\tSimulate clicking the button, and invoke the command once. \n#\nproc tile::Repeater::Activate {w} {\n    $w instate disabled { return }\n    set oldState [$w state pressed]\n    update idletasks; after 100\n    $w state $oldState\n    after idle [list $w invoke]\n}\n\n## Press -- ButtonPress-1 binding.\n#\tInvoke the command once and start autorepeating after \n#\t$State(delay) milliseconds.\n#\nproc tile::Repeater::Press {w} {\n    variable State\n    $w instate disabled { return }\n    $w state pressed\n    $w invoke\n    after cancel $State(timer)\n    set State(timer) [after $State(delay) [list tile::Repeater::Repeat $w]]\n}\n\n## Release -- ButtonRelease binding.\n#\tStop repeating.\n#\nproc tile::Repeater::Release {w} {\n    variable State\n    $w state !pressed\n    after cancel $State(timer)\n}\n\n## Pause -- B1-Leave binding\n#\tTemporarily suspend autorepeat.\n#\nproc tile::Repeater::Pause {w} {\n    variable State\n    $w state !pressed\n    after cancel $State(timer)\n}\n\n## Resume -- B1-Enter binding\n#\tResume autorepeat.\n#\nproc tile::Repeater::Resume {w} {\n    variable State\n    $w instate disabled { return }\n    $w state pressed\n    $w invoke\n    after cancel $State(timer)\n    set State(timer) [after $State(interval) [list tile::Repeater::Repeat $w]]\n}\n\n## Repeat -- Timer script\n#\tInvoke the command and reschedule another repetition \n#\tafter $State(interval) milliseconds.\n#\nproc tile::Repeater::Repeat {w} {\n    variable State\n    $w instate disabled { return }\n    $w invoke\n    set State(timer) [after $State(interval) [list tile::Repeater::Repeat $w]]\n}\n\n#*EOF*\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/blue/blue.tcl",
    "content": "# blue.tcl - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>\n#\n# blue.tcl,v 1.27 2005/10/08 14:56:57 jenglish Exp\n#\n#\n\nnamespace eval tile::theme::blue {\n\n    package provide tile::theme::blue 0.7\n\n    set imgdir [file join [file dirname [info script]] blue]\n    array set I [tile::LoadImages $imgdir *.gif]\n\n    array set colors {\n\t-frame  \t\"#6699cc\"\n\t-lighter\t\"#bcd2e8\"\n\t-window\t \t\"#e6f3ff\"\n\t-selectbg\t\"#ffff33\"\n\t-selectfg\t\"#000000\"\n\t-disabledfg\t\"#666666\"\n    }\n\n    style theme create blue -settings {\n\n\tstyle default . \\\n\t    -borderwidth \t1 \\\n\t    -background \t$colors(-frame) \\\n\t    -fieldbackground\t$colors(-window) \\\n\t    -troughcolor\t$colors(-lighter) \\\n\t    -selectbackground\t$colors(-selectbg) \\\n\t    -selectforeground\t$colors(-selectfg) \\\n\t    ;\n\tstyle map . -foreground [list disabled $colors(-disabledfg)]\n\n\t## Buttons.\n\t#\n\tstyle default TButton -padding \"10 0\"\n\tstyle layout TButton {\n\t    Button.button -children {\n\t\tButton.focus -children {\n\t\t    Button.padding -children {\n\t\t\tButton.label\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\tstyle element create button image $I(button-n) \\\n\t    -map [list pressed $I(button-p)  active $I(button-h)] \\\n\t    -border 4 -sticky ew\n\n\tstyle element create Checkbutton.indicator image $I(check-nu) \\\n\t    -width 24 -sticky w -map [list \\\n\t\t{!disabled active selected} $I(check-hc) \\\n\t\t{!disabled active} $I(check-hu) \\\n\t\t{!disabled selected} $I(check-nc) ]\n\n\tstyle element create Radiobutton.indicator image $I(radio-nu) \\\n\t    -width 24 -sticky w -map [list \\\n\t\t{!disabled active selected} $I(radio-hc) \\\n\t\t{!disabled active} $I(radio-hu) \\\n\t\tselected $I(radio-nc) ]\n\n\tstyle default TMenubutton -relief raised -padding {10 2}\n\n\t## Toolbar buttons.\n\t#\n\tstyle default Toolbutton \\\n\t    -width 0 -relief flat -borderwidth 2 -padding 4 \\\n\t    -background $colors(-frame) -foreground #000000 ;\n\tstyle map Toolbutton -background [list active $colors(-selectbg)] \n\tstyle map Toolbutton -foreground [list active $colors(-selectfg)] \n\tstyle map Toolbutton -relief {\n\t    disabled \tflat\n\t    selected\tsunken  \n\t    pressed \tsunken  \n\t    active  \traised\n\t}\n\n\t## Entry widgets.\n\t#\n\tstyle default TEntry \\\n\t    -selectborderwidth 1 -padding 2 -insertwidth 2 -font TkTextFont\n\tstyle default TCombobox \\\n\t    -selectborderwidth 1 -padding 2 -insertwidth 2 -font TkTextFont\n\n\t## Notebooks.\n\t#\n\tstyle default TNotebook.Tab -padding {4 2 4 2}\n\tstyle map TNotebook.Tab \\\n\t    -background \\\n\t\t[list selected $colors(-frame) active $colors(-lighter)] \\\n\t    -padding [list selected {4 4 4 2}]\n\n\t## Labelframes.\n\t#\n\tstyle default TLabelframe -borderwidth 2 -relief groove\n\n\t## Scrollbars.\n\t#\n\tstyle layout Vertical.TScrollbar {\n\t    Scrollbar.trough -children {\n\t\tScrollbar.uparrow -side top\n\t\tScrollbar.downarrow -side bottom\n\t\tScrollbar.uparrow -side bottom\n\t\tVertical.Scrollbar.thumb -side top -expand true -sticky ns\n\t    }\n\t}\n\n\tstyle layout Horizontal.TScrollbar {\n\t    Scrollbar.trough -children {\n\t\tScrollbar.leftarrow -side left\n\t\tScrollbar.rightarrow -side right\n\t\tScrollbar.leftarrow -side right\n\t\tHorizontal.Scrollbar.thumb -side left -expand true -sticky we\n\t    }\n\t}\n\n\tstyle element create Horizontal.Scrollbar.thumb image $I(sb-thumb) \\\n\t    -map [list {pressed !disabled} $I(sb-thumb-p)] -border 3\n\n\tstyle element create Vertical.Scrollbar.thumb image $I(sb-vthumb) \\\n\t    -map [list {pressed !disabled} $I(sb-vthumb-p)] -border 3\n\n\tforeach dir {up down left right} {\n\t    style element create ${dir}arrow image $I(arrow${dir}) \\\n\t\t-map [list \\\n\t\t    disabled $I(arrow${dir}) \\\n\t\t    pressed $I(arrow${dir}-p) \\\n\t\t    active $I(arrow${dir}-h)] \\\n\t        -border 1 -sticky {}\n\t}\n\n\t## Scales.\n\t#\n\tstyle element create Scale.slider \\\n\t    image $I(slider) -map [list {pressed !disabled} $I(slider-p)]\n\n\tstyle element create Vertical.Scale.slider \\\n\t    image $I(vslider) -map [list {pressed !disabled} $I(vslider-p)]\n\n\tstyle element create Horizontal.Progress.bar \\\n\t    image $I(sb-thumb) -border 2\n\tstyle element create Vertical.Progress.bar \\\n\t    image $I(sb-vthumb) -border 2\n\n    }\n}\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/blue/pkgIndex.tcl",
    "content": "# Package index for tile demo pixmap themes.\n\nif {[file isdirectory [file join $dir blue]]} {\n    package ifneeded tile::theme::blue 0.7 \\\n        [list source [file join $dir blue.tcl]]\n}\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/keramik/keramik.tcl",
    "content": "# keramik.tcl - \n#\n# A sample pixmap theme for the tile package.\n#\n#  Copyright (c) 2004 Googie\n#  Copyright (c) 2004 Pat Thoyts <patthoyts@users.sourceforge.net>\n#\n# $Id$\n\npackage require Tk 8.4;                 # minimum version for Tile\npackage require tile 0.5;               # depends upon tile 0.5\n\nnamespace eval tile {\n    namespace eval theme {\n        namespace eval keramik {\n            variable version 0.3.2\n        }\n    }\n}\n\nnamespace eval tile::theme::keramik {\n\n    variable imgdir [file join [file dirname [info script]] keramik]\n    variable I\n    array set I [tile::LoadImages $imgdir *.gif]\n\n    variable colors\n    array set colors {\n        -frame      \"#cccccc\"\n        -lighter    \"#cccccc\"\n        -window     \"#ffffff\"\n        -selectbg   \"#eeeeee\"\n        -selectfg   \"#000000\"\n        -disabledfg \"#aaaaaa\"\n    }\n\n    style theme create keramik -parent alt -settings {\n\n\n        # -----------------------------------------------------------------\n        # Theme defaults\n        #\n        style default . \\\n            -borderwidth 1 \\\n            -background $colors(-frame) \\\n            -troughcolor $colors(-lighter) \\\n            -font TkDefaultFont \\\n            ;\n\n        style map . -foreground [list disabled $colors(-disabledfg)]\n                \n        # -----------------------------------------------------------------\n        # Button elements\n        #  - the button has a large rounded border and needs a bit of\n        #    horizontal padding.\n        #  - the checkbutton and radiobutton have the focus drawn around \n        #    the whole widget - hence the new layouts.\n        #\n        style layout TButton {\n            Button.background\n            Button.button -children {\n                Button.focus -children {\n                    Button.label\n                }\n            }\n        }\n        style layout Toolbutton {\n            Toolbutton.background\n            Toolbutton.button -children {\n                Toolbutton.focus -children {\n                    Toolbutton.label\n                }\n            }\n        }\n        style element create button image $I(button-n) \\\n            -border {8 6 8 16} -padding {6 6} -sticky news \\\n            -map [list {pressed !disabled} $I(button-p) \\\n                      {active !selected}  $I(button-h) \\\n                      selected $I(button-s) \\\n                      disabled $I(button-d)]\n        style default TButton -padding {10 6}\n\n        style element create Toolbutton.button image $I(tbar-n) \\\n            -border {2 8 2 16} -padding {2 2} -sticky news \\\n            -map [list {pressed !disabled} $I(tbar-p) \\\n                      {active !selected}   $I(tbar-a) \\\n                      selected             $I(tbar-p)]\n\n        style element create Checkbutton.indicator image $I(check-u) \\\n            -width 20 -sticky w \\\n            -map [list selected $I(check-c)]\n\n        style element create Radiobutton.indicator image $I(radio-u) \\\n            -width 20 -sticky w \\\n            -map [list  selected $I(radio-c)]\n\n        # The layout for the menubutton is modified to have a button element\n        # drawn on top of the background. This means we can have transparent\n        # pixels in the button element. Also, the pixmap has a special\n        # region on the right for the arrow. So we draw the indicator as a\n        # sibling element to the button, and draw it after (ie on top of) the\n        # button image.\n        style layout TMenubutton {\n            Menubutton.background\n            Menubutton.button -children {\n                Menubutton.focus -children {\n                    Menubutton.padding -children {\n                        Menubutton.label -side left -expand true\n                    }\n                }\n            }\n            Menubutton.indicator -side right\n        }\n        style element create Menubutton.button image $I(mbut-n) \\\n            -map [list {active !disabled} $I(mbut-a) \\\n                      {pressed !disabled} $I(mbut-a) \\\n                      {disabled}          $I(mbut-d)] \\\n            -border {7 10 29 15} -padding {7 4 29 4} -sticky news\n        style element create Menubutton.indicator image $I(mbut-arrow-n) \\\n            -width 11 -sticky w -padding {0 0 18 0}\n\n        # -----------------------------------------------------------------\n        # Scrollbars, scale and progress elements\n        #  - the scrollbar has three arrow buttons, two at the bottom and\n        #    one at the top.\n        #\n        style layout Vertical.TScrollbar {\n            Scrollbar.background \n            Scrollbar.trough -children {\n                Scrollbar.uparrow -side top\n                Scrollbar.downarrow -side bottom\n                Scrollbar.uparrow -side bottom\n                Vertical.Scrollbar.thumb -side top -expand true -sticky ns\n            }\n        }\n        \n        style layout Horizontal.TScrollbar {\n            Scrollbar.background \n            Scrollbar.trough -children {\n                Scrollbar.leftarrow -side left\n                Scrollbar.rightarrow -side right\n                Scrollbar.leftarrow -side right\n                Horizontal.Scrollbar.thumb -side left -expand true -sticky we\n            }\n        }\n\n        style default TScrollbar -width 16\n\n        style element create Horizontal.Scrollbar.thumb image $I(hsb-n) \\\n            -border {6 4} -width 15 -height 16 -sticky news \\\n            -map [list {pressed !disabled} $I(hsb-p)]\n        \n        style element create Vertical.Scrollbar.thumb image $I(vsb-n) \\\n            -border {4 6} -width 16 -height 15 -sticky news \\\n            -map [list {pressed !disabled} $I(vsb-p)]\n        \n        style element create Scale.slider image $I(hslider-n) \\\n            -border 3\n        \n        style element create Vertical.Scale.slider image $I(vslider-n) \\\n            -border 3\n        \n        style element create Horizontal.Progress.bar image $I(hsb-n) \\\n            -border {6 4}\n        \n        style element create Vertical.Progress.bar image $I(vsb-n) \\\n            -border {4 6}\n        \n        style element create uparrow image $I(arrowup-n) \\\n            -map [list {pressed !disabled} $I(arrowup-p)]\n                  \n        style element create downarrow image $I(arrowdown-n) \\\n            -map [list {pressed !disabled} $I(arrowdown-p)]\n\n        style element create rightarrow image $I(arrowright-n) \\\n            -map [list {pressed !disabled} $I(arrowright-p)]\n\n        style element create leftarrow image $I(arrowleft-n) \\\n            -map [list {pressed !disabled} $I(arrowleft-p)]\n        \n        # -----------------------------------------------------------------\n        # Notebook elements\n        #\n        style element create tab image $I(tab-n) \\\n            -map [list selected $I(tab-p) active $I(tab-p)] \\\n            -border {6 6 6 2} -height 12\n\n\t## Labelframes.\n\t#\n\tstyle default TLabelframe -borderwidth 2 -relief groove\n    }\n}\n\npackage provide tile::theme::keramik $::tile::theme::keramik::version\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/keramik/pkgIndex.tcl",
    "content": "# pkgIndex.tcl for additional tile pixmap themes.\n#\n# We don't provide the package is the image subdirectory isn't present,\n# or we don't have the right version of Tcl/Tk\n#\n# To use this automatically within tile, the tile-using application should\n# use tile::availableThemes and tile::setTheme \n#\n# $Id$\n\nif {![file isdirectory [file join $dir keramik]]} { return }\nif {![package vsatisfies [package provide Tcl] 8.4]} { return }\n\npackage ifneeded tile::theme::keramik 0.3.2 \\\n    [list source [file join $dir keramik.tcl]]\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/kroc/kroc.tcl",
    "content": "# kroc.tcl - Copyright (C) 2004 David Zolli <kroc@kroc.tk>\n#\n# A sample pixmap theme for the tile package.\n\n#package require tile::pixmap\n\nnamespace eval tile {\n    namespace eval kroc {\n        variable version 0.0.1\n    }\n}\n\nnamespace eval tile::kroc {\n    \n    set imgdir [file join [file dirname [info script]] kroc]\n    array set Images [tile::LoadImages $imgdir *.gif]\n    \n    if {[package vsatisfies [package provide tile] 0.5]} {\n        set TNoteBook_Tab TNotebook.Tab\n    } else {\n        set TNoteBook_Tab Tab.TNotebook\n    }\n    \n    style theme create kroc -parent alt -settings {\n        \n        style default . -background #FCB64F -troughcolor #F8C278 -borderwidth 1\n\tstyle default . -font TkDefaultFont -borderwidth 1\n        style map . -background [list active #694418]\n        style map . -foreground [list disabled #B2B2B2 active #FFE7CB]\n        \n        style default TButton -padding \"10 4\"\n        \n        style default $TNoteBook_Tab -padding {10 3} -font TkDefaultFont\n        style map $TNoteBook_Tab \\\n                -background [list selected #FCB64F {} #FFE6BA] \\\n                -foreground [list {} black] \\\n                -padding [list selected {10 6 10 3}]\n\n        style map TScrollbar \\\n\t\t-background\t{ pressed #694418} \\\n                -arrowcolor\t{ pressed #FFE7CB } \\\n                -relief\t\t{ pressed sunken } \\\n                ;\n        \n        style layout Vertical.TScrollbar {\n            Scrollbar.trough -children {\n                Scrollbar.uparrow -side top\n                Scrollbar.downarrow -side bottom\n                Scrollbar.uparrow -side bottom\n                Scrollbar.thumb -side top -expand true\n            }\n        }\n        \n        style layout Horizontal.TScrollbar {\n            Scrollbar.trough -children {\n                Scrollbar.leftarrow -side left\n                Scrollbar.rightarrow -side right\n                Scrollbar.leftarrow -side right\n                Scrollbar.thumb -side left -expand true\n            }\n        }\n        \n        #\n        # Elements:\n        #\n        if {[package vsatisfies [package provide tile] 0.5]} {\n            \n            style element create Button.button image $Images(button-n) \\\n                -map [list  \\\n                    pressed\t\t$Images(button-p) \\\n                    active\t\t$Images(button-h) \\\n                    ] -border 3 -sticky ew\n            \n            style element create Checkbutton.indicator image $Images(check-nu) \\\n                -map [list \\\n                    {pressed selected}\t$Images(check-nc) \\\n                    pressed\t\t$Images(check-nu) \\\n                    {active selected}\t$Images(check-hc) \\\n                    active\t\t$Images(check-hu) \\\n                    selected\t\t$Images(check-nc) \\\n                    ] -sticky w\n            \n            style element create Radiobutton.indicator image $Images(radio-nu) \\\n                -map [list \\\n                    {pressed selected}\t$Images(radio-nc) \\\n                    pressed\t\t$Images(radio-nu) \\\n                    {active selected}\t$Images(radio-hc) \\\n                    active\t\t$Images(radio-hu) \\\n                    selected\t\t$Images(radio-nc) \\\n                    ] -sticky w\n            \n        } else {\n            \n            style element create Button.button pixmap -images [list  \\\n                    pressed\t\t$Images(button-p) \\\n                    active\t\t$Images(button-h) \\\n                    {}\t\t\t$Images(button-n) \\\n                    ] -border 3 -tiling tile\n            \n            style element create Checkbutton.indicator pixmap -images [list \\\n                    {pressed selected}\t$Images(check-nc) \\\n                    pressed\t\t$Images(check-nu) \\\n                    {active selected}\t$Images(check-hc) \\\n                    active\t\t$Images(check-hu) \\\n                    selected\t\t$Images(check-nc) \\\n                    {}\t\t\t$Images(check-nu) \\\n                    ] -tiling fixed\n            \n            style element create Radiobutton.indicator pixmap -images [list \\\n                    {pressed selected}\t$Images(radio-nc) \\\n                    pressed\t\t$Images(radio-nu) \\\n                    {active selected}\t$Images(radio-hc) \\\n                    active\t\t$Images(radio-hu) \\\n                    selected\t\t$Images(radio-nc) \\\n                    {}\t\t\t$Images(radio-nu) \\\n                    ] -tiling fixed\n            \n        }\n\n        #\n        # Settings: (*button.background is not needed in tile 0.5 or above)\n        #\n        style layout TButton {\n\t    Button.button -children {\n\t\tButton.focus -children {\n\t\t    Button.padding -children {\n\t\t\tButton.label -expand true -sticky {}\n\t\t    }\n\t\t}\n\t    }\n        }\n\n        style layout TCheckbutton {\n\t    Checkbutton.border -children {\n\t\tCheckbutton.background\n\t\tCheckbutton.padding -children {\n\t\t    Checkbutton.indicator -side left\n\t\t    Checkbutton.focus -side left -children {\n\t\t\tCheckbutton.label\n\t\t    }\n\t\t}\n            }\n        }\n        \n        style layout TRadiobutton {\n            Radiobutton.border -children {\n                Radiobutton.background\n                Radiobutton.padding -children  {\n                    Radiobutton.indicator -side left\n                    Radiobutton.focus -expand true -sticky w -children {\n                        Radiobutton.label -side right -expand true\n                    }\n                }\n            }\n        }\n        \n    } }\n\n# -------------------------------------------------------------------------\n\npackage provide tile::theme::kroc $::tile::kroc::version\n\n# -------------------------------------------------------------------------\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/kroc/pkgIndex.tcl",
    "content": "# pkgIndex.tcl for additional tile pixmap themes.\n#\n# We don't provide the package is the image subdirectory isn't present,\n# or we don't have the right version of Tcl/Tk\n#\n# To use this automatically within tile, the tile-using application should\n# use tile::availableThemes and tile::setTheme \n#\n# $Id$\n\nif {![file isdirectory [file join $dir kroc]]} { return }\nif {![package vsatisfies [package provide Tcl] 8.4]} { return }\n\npackage ifneeded tile::theme::kroc 0.0.1 \\\n    [list source [file join $dir kroc.tcl]]\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/kroc.rb",
    "content": "#\n# kroc.rb \n#\n# based on:\n#   >> kroc.tcl - Copyright (C) 2004 David Zolli <kroc@kroc.tk>\n#\n\nimgdir = File.join(File.dirname(__FILE__), 'kroc', 'kroc')\n$images = Tk::Tile.load_images(imgdir, '*.gif')\n\nif TkPackage.vcompare(Tk::Tile.package_version, '0.5') >= 0\n  $TNotebook_Tab = Tk::Tile::TNotebook.style('Tab')\nelse\n  $TNotebook_Tab = 'Tab.TNotebook'\nend\n\ndef kroc_rb_settings\n  # Tk::Tile::Style.default(TkRoot, :background=>'#FCB64F', \n  #                         :troughcolor=>'#F8C278', :borderwidth=>1)\n  #   or\n  # Tk::Tile::Style.default(Tk.root, :background=>'#FCB64F', \n  #                         :troughcolor=>'#F8C278', :borderwidth=>1)\n  #   or\n  # Tk::Tile::Style.default('.', :background=>'#FCB64F', \n  #                         :troughcolor=>'#F8C278', :borderwidth=>1)\n  #   or\n  # Tk::Tile::Style.default(nil, :background=>'#FCB64F', \n  #                         :troughcolor=>'#F8C278', :borderwidth=>1)\n  #   or\n  Tk::Tile::Style.default(:background=>'#FCB64F', :troughcolor=>'#F8C278', \n                          :borderwidth=>1)\n  # Tk::Tile::Style.default(TkRoot, :font=>Tk::Tile::Font::Default, \n  #                         :borderwidth=>1)\n  #   or\n  # Tk::Tile::Style.default(Tk.root, :font=>Tk::Tile::Font::Default, \n  #                         :borderwidth=>1)\n  #   or\n  # Tk::Tile::Style.default('.', :font=>Tk::Tile::Font::Default, \n  #                         :borderwidth=>1)\n  #   or\n  # Tk::Tile::Style.default(nil, :font=>Tk::Tile::Font::Default, \n  #                         :borderwidth=>1)\n  #   or\n  Tk::Tile::Style.default(:font=>Tk::Tile::Font::Default, :borderwidth=>1)\n\n  # Tk::Tile::Style.map(TkRoot, :background=>[:active, '#694418'])\n  #   or\n  # Tk::Tile::Style.map(Tk.root, :background=>[:active, '#694418'])\n  #   or\n  # Tk::Tile::Style.map('.', :background=>[:active, '#694418'])\n  #   or\n  # Tk::Tile::Style.map(nil, :background=>[:active, '#694418'])\n  #   or\n  Tk::Tile::Style.map(:background=>[:active, '#694418'])\n  Tk::Tile::Style.map(:foreground=>[:disabled, '#B2B2B2', :active, '#FFE7CB'])\n\n  # Tk::Tile::Style.default('TButton', :padding=>[10,4])\n  Tk::Tile::Style.default(Tk::Tile::TButton, :padding=>[10,4])\n\n  # Tk::Tile::Style.default('TNotebook.Tab', \n  Tk::Tile::Style.default($TNotebook_Tab, \n                          :padding=>[10, 3], :font=>Tk::Tile::Font::Default)\n  # Tk::Tile::Style.map('TNotebook.Tab', \n  Tk::Tile::Style.map($TNotebook_Tab, \n                      :background=>[:selected, '#FCB64F', '', '#FFE6BA'], \n                      :foreground=>['', 'black'], \n                      :padding=>[:selected, [10, 6, 10, 3]])\n\n  # Tk::Tile::Style.map('TScrollbar', \n  Tk::Tile::Style.map(Tk::Tile::TScrollbar, \n                      :background=>[:pressed, '#694418'], \n                      :arrowcolor=>[:pressed, '#FEF7CB'], \n                      :relief=>[:pressed, :sunken])\n\n  # Tk::Tile::Style.layout('Vertical.TScrollbar', \n  Tk::Tile::Style.layout(Tk::Tile.style('Vertical', Tk::Tile::TScrollbar), \n                         ['Scrollbar.trough', {:children=>[\n                             'Scrollbar.uparrow',   {:side=>:top}, \n                             'Scrollbar.downarrow', {:side=>:bottom}, \n                             'Scrollbar.uparrow',   {:side=>:bottom}, \n                             'Scrollbar.thumb',  {:side=>:top, :expand=>true}\n                           ]}\n                         ])\n\n  # Tk::Tile::Style.layout('Horizontal.TScrollbar', \n  Tk::Tile::Style.layout(Tk::Tile.style('Horizontal', Tk::Tile::TScrollbar), \n                         ['Scrollbar.trough', {:children=>[\n                             'Scrollbar.leftarrow',   {:side=>:left}, \n                             'Scrollbar.rightarrow', {:side=>:right}, \n                             'Scrollbar.leftarrow',   {:side=>:right}, \n                             'Scrollbar.thumb',  {:side=>:left, :expand=>true}\n                           ]}\n                         ])\n\n  #\n  # Elements:\n  #\n  if Tk::Tile::TILE_SPEC_VERSION_ID >= 8\n    Tk::Tile::Style.element_create('Button.button', \n                                   :image, \n                                   [ $images['button-n'],\n                                     :pressed, $images['button-p'], \n                                     :active,  $images['button-h'], \n                                   ], :border=>3, :sticky=>:ew)\n\n    Tk::Tile::Style.element_create('Checkbutton.indicator', \n                                   :image, \n                                   [ $images['check-nu'],\n                                     [:pressed, :selected],$images['check-nc'],\n                                     :pressed,             $images['check-nu'],\n                                     [:active, :selected], $images['check-hc'],\n                                     :active,              $images['check-hu'],\n                                     :selected,            $images['check-nc'],\n                                   ], :sticky=>:w)\n\n    Tk::Tile::Style.element_create('Radiobutton.indicator', \n                                   :image, \n                                   [ $images['radio-nu'],\n                                     [:pressed,:selected],$images['radio-nc'],\n                                     :pressed,            $images['radio-nu'],\n                                     [:active,:selected], $images['radio-hc'],\n                                     :active,             $images['radio-hu'],\n                                     :selected,           $images['radio-nc'],\n                                   ], :sticky=>:w)\n\n  elsif TkPackage.vcompare(Tk::Tile.package_version, '0.5') >= 0\n    Tk::Tile::Style.element_create('Button.button', \n                                   :image, $images['button-n'],\n                                   :map=>[\n                                     :pressed, $images['button-p'], \n                                     :active,  $images['button-h'], \n                                   ], :border=>3, :sticky=>:ew)\n\n    Tk::Tile::Style.element_create('Checkbutton.indicator', \n                                   :image, $images['check-nu'],\n                                   :map=>[\n                                     [:pressed, :selected],$images['check-nc'],\n                                     :pressed,             $images['check-nu'],\n                                     [:active, :selected], $images['check-hc'],\n                                     :active,              $images['check-hu'],\n                                     :selected,            $images['check-nc'],\n                                   ], :sticky=>:w)\n\n    Tk::Tile::Style.element_create('Radiobutton.indicator', \n                                   :image, $images['radio-nu'],\n                                   :map=>[\n                                     [:pressed, :selected],$images['radio-nc'],\n                                     :pressed,             $images['radio-nu'],\n                                     [:active, :selected], $images['radio-hc'],\n                                     :active,              $images['radio-hu'],\n                                     :selected,            $images['radio-nc'],\n                                   ], :sticky=>:w)\n\n  else # tile 0.4 or earlier\n    Tk::Tile::Style.element_create('Button.button', :pixmap, \n                                   :images=>[\n                                     :pressed, $images['button-p'], \n                                     :active,  $images['button-h'], \n                                     '',       $images['button-n']\n                                   ], :border=>3, :tiling=>:tile)\n\n    Tk::Tile::Style.element_create('Checkbutton.indicator', :pixmap, \n                                   :images=>[\n                                     [:pressed, :selected],$images['check-nc'],\n                                     :pressed,             $images['check-nu'],\n                                     [:active, :selected], $images['check-hc'],\n                                     :active,              $images['check-hu'],\n                                     :selected,            $images['check-nc'],\n                                     '',                   $images['check-nu'],\n                                   ], :tiling=>:fixed)\n\n    Tk::Tile::Style.element_create('Radiobutton.indicator', :pixmap, \n                                   :images=>[\n                                     [:pressed, :selected],$images['radio-nc'],\n                                     :pressed,             $images['radio-nu'],\n                                     [:active, :selected], $images['radio-hc'],\n                                     :active,              $images['radio-hu'],\n                                     :selected,            $images['radio-nc'],\n                                     '',                   $images['radio-nu'],\n                                   ], :tiling=>:fixed)\n\n  end\n\n  #\n  # Settings:\n  #\n  # Tk::Tile::Style.layout(Tk::Tile::TButton, \n  Tk::Tile::Style.layout('TButton', [\n      'Button.button', {:children=>[\n           'Button.focus', {:children=>[\n                'Button.padding', {:children=>[\n                    'Button.label', {:expand=>true, :sticky=>''}\n                ]}\n           ]}\n      ]}\n  ])\n\n  # Tk::Tile::Style.layout(Tk::Tile::TCheckbutton, \n  Tk::Tile::Style.layout('TCheckbutton', [\n      'Checkbutton.background', # this is not needed in tile 0.5 or later\n      'Checkbutton.border', {:children=>[\n           'Checkbutton.padding', {:children=>[\n                'Checkbutton.indicator', {:side=>:left}, \n                'Checkbutton.focus', {:side=>:left, :children=>[\n                    'Checkbutton.label'\n                ]}\n           ]}\n      ]}\n  ])\n\n  # Tk::Tile::Style.layout(Tk::Tile::TRadiobutton, \n  Tk::Tile::Style.layout('TRadiobutton', [\n      'Radiobutton.background', # this is not needed in tile 0.5 or later\n      'Radiobutton.border', {:children=>[\n           'Radiobutton.padding', {:children=>[\n                'Radiobutton.indicator', {:side=>:left}, \n                'Radiobutton.focus', {:expand=>true, :sticky=>:w, :children=>[\n                    'Radiobutton.label', {:side=>:right, :expand=>true}\n                ]}\n           ]}\n      ]}\n  ])\nend\n\nTk::Tile::Style.theme_create('kroc-rb', :parent=>'alt', \n                             :settings=>proc{ kroc_rb_settings() })\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/plastik/pkgIndex.tcl",
    "content": "# pkgIndex.tcl for additional tile pixmap themes.\n#\n# We don't provide the package is the image subdirectory isn't present,\n# or we don't have the right version of Tcl/Tk\n#\n# To use this automatically within tile, the tile-using application should\n# use tile::availableThemes and tile::setTheme \n#\n# $Id$\n\nif {![file isdirectory [file join $dir plastik]]} { return }\nif {![package vsatisfies [package provide Tcl] 8.4]} { return }\n\npackage ifneeded tile::theme::plastik 0.3.1 \\\n    [list source [file join $dir plastik.tcl]]\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/themes/plastik/plastik.tcl",
    "content": "# plastik.tcl - Copyright (C) 2004 Googie\n#\n# A sample pixmap theme for the tile package.\n#\n#  Copyright (c) 2004 Googie\n#  Copyright (c) 2005 Pat Thoyts <patthoyts@users.sourceforge.net>\n#\n# $Id$\n\npackage require Tk 8.4\npackage require tile 0.5\n\nnamespace eval tile::theme::plastik {\n\n    variable version 0.3.1\n    package provide tile::theme::plastik $version\n\n    variable imgdir [file join [file dirname [info script]] plastik]\n    variable Images;\n    array set Images [tile::LoadImages $imgdir *.gif]\n\n    variable colors\n    array set colors {\n    \t-frame \t\t\"#cccccc\"\n\t-disabledfg\t\"#aaaaaa\"\n\t-selectbg\t\"#657a9e\"\n\t-selectfg\t\"#ffffff\"\n    }\n\nstyle theme create plastik -parent default -settings {\n    style default . \\\n    \t-background $colors(-frame) \\\n\t-troughcolor $colors(-frame) \\\n\t-selectbackground $colors(-selectbg) \\\n\t-selectforeground $colors(-selectfg) \\\n\t-font TkDefaultFont \\\n\t-borderwidth 1 \\\n\t;\n\n    style map . -foreground [list disabled $colors(-disabledfg)]\n\n    #\n    # Layouts:\n    #\n    style layout Vertical.TScrollbar {\n        Scrollbar.background\n        Scrollbar.trough -children {\n            Scrollbar.uparrow -side top\n            Scrollbar.downarrow -side bottom\n            Scrollbar.uparrow -side bottom\n            Vertical.Scrollbar.thumb -side top -expand true -sticky ns\n        }\n    }\n\n    style layout Horizontal.TScrollbar {\n        Scrollbar.background\n        Scrollbar.trough -children {\n            Scrollbar.leftarrow -side left\n            Scrollbar.rightarrow -side right\n            Scrollbar.leftarrow -side right\n            Horizontal.Scrollbar.thumb -side left -expand true -sticky we\n        }\n    }\n\n    style layout TButton {\n        Button.button -children {\n\t    Button.focus -children {\n\t\tButton.padding -children {\n\t\t    Button.label -side left -expand true\n\t\t}\n\t    }\n\t}\n    }\n\n    #\n    # Elements:\n    #\n    style element create Button.button image $Images(button-n) \\\n    \t-border 4 -sticky ew \\\n    \t-map [list pressed $Images(button-p)  active $Images(button-h)]\n\n    style element create Checkbutton.indicator image $Images(check-nu) \\\n\t-sticky {} -map [list \\\n\t    {active selected}     $Images(check-hc) \\\n\t    {pressed selected}    $Images(check-pc) \\\n\t    active                $Images(check-hu) \\\n\t    selected              $Images(check-nc) \\\n\t]\n\n    style element create Radiobutton.indicator image $Images(radio-nu) \\\n\t-sticky {} -map [list \\\n\t    {active selected}     $Images(radio-hc) \\\n\t    {pressed selected}    $Images(radio-pc) \\\n\t    active                $Images(radio-hu) \\\n\t    selected              $Images(radio-nc) \\\n\t]\n\n    style element create Horizontal.Scrollbar.thumb \\\n    \timage $Images(hsb-n) -border 3 -sticky ew\n    style element create Vertical.Scrollbar.thumb \\\n    \timage $Images(vsb-n) -border 3 -sticky ns\n\n    style element create Scale.slider \\\n    \timage $Images(hslider-n) -sticky {}\n    style element create Vertical.Scale.slider \\\n    \timage $Images(vslider-n) -sticky {}\n\n    style element create Scrollbar.uparrow image $Images(arrowup-n) \\\n    \t-map [list pressed $Images(arrowup-p)] -sticky {}\n    style element create Scrollbar.downarrow image $Images(arrowdown-n) \\\n    \t-map [list pressed $Images(arrowdown-p)] -sticky {}\n    style element create Scrollbar.leftarrow image $Images(arrowleft-n) \\\n    \t-map [list pressed $Images(arrowleft-p)] -sticky {}\n    style element create Scrollbar.rightarrow image $Images(arrowright-n) \\\n    \t-map [list pressed $Images(arrowright-p)] -sticky {}\n\n    #\n    # Settings:\n    #\n    style default TButton -width -10\n    style default TNotebook.Tab -padding {6 2 6 2}\n    style default TLabelframe -borderwidth 2 -relief groove\n\n} }\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tile/toolbutton.tcl",
    "content": "#\n# $Id$\n#\n# Demonstration of custom widget styles.\n#\n\n#\n# ~ BACKGROUND\n#\n# Checkbuttons in toolbars have a very different appearance \n# than regular checkbuttons: there's no indicator, they\n# \"pop up\" when the mouse is over them, and they appear sunken\n# when selected.\n# \n# Tk added partial support for toolbar-style buttons in 8.4 \n# with the \"-overrelief\" option, and TIP #82 added further\n# support with the \"-offrelief\" option.  So to get a toolbar-style \n# checkbutton, you can configure it with:\n#\n# checkbutton .cb \\\n#     -indicatoron false -selectcolor {} -relief flat -overrelief raised\n#\n# Behind the scenes, Tk has a lot of rather complicated logic\n# to implement this checkbutton style; see library/button.tcl,\n# generic/tkButton.c, and the platform-specific files unix/tkUnixButton.c\n# et al. for the full details.\n#\n# The tile widget set has a better way: custom styles.\n# Since the appearance is completely controlled by the theme engine,\n# we can define a new \"Toolbutton\" style and just use:\n#\n# checkbutton .cb -style Toolbutton\n#\n#\n# ~ DEMONSTRATION\n#\n# The tile built-in themes (default, \"alt\", windows, and XP) \n# already include Toolbutton styles.  This script will add\n# them to the \"step\" and \"blue\" themes as a demonstration.\n#\n# (Note: Pushbuttons and radiobuttons can also use the \"Toolbutton\" \n# style; see demo.tcl.)\n#\n\nstyle theme settings \"step\" {\n\n#\n# First, we use [style layout] to define what elements to\n# use and how they're arranged.  Toolbuttons are pretty\n# simple, consisting of a border, some internal padding,\n# and a label.  (See also the TScrollbar layout definition \n# in demos/blue.tcl for a more complicated layout spec.)\n#\n    style layout Toolbutton {\n        Toolbutton.background\n        Toolbutton.border -children {\n            Toolbutton.padding -children {\n                Toolbutton.label\n            }\n        }\n    }\n\n# (Actually the above isn't strictly necessary, since the same layout \n# is defined in the default theme; we could have inherited it \n# instead.)\n#\n# Next, specify default values for element options.\n# For many options (like -background), the defaults\n# inherited from the parent style are sufficient.\n#\n    style default Toolbutton -width 0 -padding 1 -relief flat -borderwidth 2\n\n#\n# Finally, use [style map] to specify state-specific \n# resource values.  We want a flat relief if the widget is\n# disabled, sunken if it's selected (on) or pressed, \n# and raised when it's active (the mouse pointer is\n# over the widget).  Each state-value pair is checked\n# in order, and the first matching state takes precedence.\n#\n    style map Toolbutton -relief {\n\tdisabled \tflat\n    \tselected\tsunken  \n\tpressed \tsunken  \n\tactive\t\traised\n    }\n}\n\n#\n# Now for the \"blue\" theme.  (Since the purpose of this\n# theme is to show what *can* be done, not necessarily what\n# *should* be done, the following makes some questionable\n# design decisions from an aesthetic standpoint.)\n#\nif {![catch {package require tile::theme::blue}]} {\nstyle theme settings \"blue\" {\n\n    #\n    # Default values:\n    #\n    style default Toolbutton \\\n    \t-width 0 -relief flat -borderwidth 2 \\\n\t-background #6699CC -foreground #000000 ;\n\n    #\n    # Configure state-specific values for -relief, as before:\n    #\n    style map Toolbutton -relief {\n\tdisabled \tflat\n    \tselected\tsunken  \n\tpressed \tsunken  \n\tactive\t\traised\n    } \n\n    #\n    # Adjust the -padding at the same time, to enhance\n    # the raised/sunken illusion:\n    #\n    style default Toolbutton -padding 4\n    style map Toolbutton -padding {\n\tdisabled\t{4}\n\tselected\t{6 6 2 2}\n\tpressed\t\t{6 6 2 2}\n\tactive\t\t{2 2 6 6}\n    }\n\n    #\n    # ... and change the foreground and background colors\n    # when the mouse cursor is over the widget:\n    #\n    style map Toolbutton -background {\n\tactive  \t#008800\n    } -foreground {\n\tactive  \t#FFFFFF\n    }\n}\n\n}\n\n#\n# ~ A final note:  \n#\n# TIP #82 also says: \"When -indicatoron is off and the button itself\n# is on, the relief continues to be hard-coded to sunken. For symmetry,\n# we might consider adding another -onrelief option to cover this\n# case. But it is difficult to imagine ever wanting to change the\n# value of -onrelief so it has been omitted from this TIP.\n# If there as strong desire to have -onrelief, it can be added later.\"\n# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n#\n# The Tile project aims to make sure that this never needs to happen.\n#\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/Orig_COPYRIGHT.txt",
    "content": "\nThe following text is the original 'COPYRIGHT' file of tkHTML. \n\n-----------------------------------------------------------------------\nMost of the source code for the Tk Html widget has been place in the\npublic domain.  You can do with it whatever you want.  However, some\nfiles have been copied from other sources and contain copyrights.\nA copyright notice appears separately at the top of each source file.\n-----------------------------------------------------------------------\n\nIn this sample, HTML documents are quoted in the 'tests' directory of\ntkHTML source tree. There were no copyright notice in the directory. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/README",
    "content": "\n   [ TkHtml widget example ]\n\nThe directory page1 -- page4 are referd from \"test\" directory of \noriginal TkHtml extension's source archive. \n( see http://www.hwaci.com/sw/tkhtml/index.html )\n\nYou can see the HTML documents on the 'hv.rb' or 'ss.rb' sample script.\n\n e.g. \n   LD_LIBRARY_PATH=/usr/local/ActiveTcl/lib:$LD_LIBRARY_PATH /usr/local/bin/ruby ./hv.rb page1/index.html\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/hv.rb",
    "content": "#!/usr/bin/env ruby\n#\n# This script implements the \"hv\" application.  Type \"hv FILE\" to\n# view FILE as HTML.\n#\n# This application is used for testing the HTML widget.  It can\n# also server as an example of how to use the HTML widget.\n# \nrequire 'tk'\nrequire 'tkextlib/tkHTML'\n\nroot = TkRoot.new(:title=>'HTML File Viewer', :iconname=>'HV')\n\nfile = ARGV[0]\n\n#\n# These images are used in place of GIFs or of form elements\n#\nbiggray = TkPhotoImage.new(:data=><<'EOD')\n    R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm\n    6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO///\nEOD\n\nsmgray = TkPhotoImage.new(:data=><<'EOD')\n    R0lGODdhOAAYAPAAALi4uAAAACwAAAAAOAAYAAACI4SPqcvtD6OctNqLs968+w+G4kiW5omm\n    6sq27gvH8kzX9m0VADv/\nEOD\n\nnogifbig = TkPhotoImage.new(:data=><<'EOD')\n    R0lGODdhJAAkAPEAAACQkADQ0PgAAAAAACwAAAAAJAAkAAACmISPqcsQD6OcdJqKM71PeK15\n    AsSJH0iZY1CqqKSurfsGsex08XuTuU7L9HywHWZILAaVJssvgoREk5PolFo1XrHZ29IZ8oo0\n    HKEYVDYbyc/jFhz2otvdcyZdF68qeKh2DZd3AtS0QWcDSDgWKJXY+MXS9qY4+JA2+Vho+YPp\n    FzSjiTIEWslDQ1rDhPOY2sXVOgeb2kBbu1AAADv/\nEOD\n\nnogifsm = TkPhotoImage.new(:data=><<'EOD')\n    R0lGODdhEAAQAPEAAACQkADQ0PgAAAAAACwAAAAAEAAQAAACNISPacHtD4IQz80QJ60as25d\n    3idKZdR0IIOm2ta0Lhw/Lz2S1JqvK8ozbTKlEIVYceWSjwIAO///\nEOD\n\n#\n# define variables\n#\nul_hyper = TkVariable.new(0)\nshow_tbl = TkVariable.new(0)\nshow_img = TkVariable.new(1)\n\n#\n# A font chooser routine.\n#\n# html[:fontcommand] = pick_font\npick_font = proc{|size, attrs|\n  puts \"FontCmd: #{size} #{attrs}\"\n  [ ((attrs =~ /fixed/)? 'courier': 'charter'), \n    (12 * (1.2**(size.to_f - 4.0))).to_i, \n    ((attrs =~ /italic/)? 'italic': 'roman'), \n    ((attrs =~ /bold/)? 'bold': 'normal') ].join(' ') \n} \n\n#\n# This routine is called for each form element\n#\nform_cmd = proc{|n, cmd, style, *args|\n  # puts \"FormCmd: $n $cmd $args\"\n  case cmd\n  when 'select', 'textarea', 'input'\n    TkLabel.new(:widgetname=>args[0], :image=>nogifsm)\n  end\n}\n\n#\n# This routine is called for every <IMG> markup\n#\nimages   = {}\nold_imgs = {}\nbig_imgs = {}\n\nhotkey   = {}\n\nmove_big_image = proc{|b|\n  if big_imgs.key?(b)\n    b.copy(big_imgs[b])\n    big_imgs[b].delete\n    big_imgs.delete(b)\n    Tk.update\n  end\n}\n\nimage_cmd = proc{|*args|\n  if show_img.bool\n    smgray\n  else\n    fn = args[0]\n\n    if old_imgs.key?(fn)\n      images[fn] = old_imgs[fn]\n      old_imgs.delete(fn)\n      images[fn]\n\n    else\n      begin\n        img = TkPhotoImage.new(:file=>fn)\n      rescue\n        smgray\n      else\n        if img.width * img.height > 20000\n          b = TkPhotoImage.new(:width=>img.width, :height=>img.height)\n          big_imgs[b] = img\n          img = b\n          Tk.after_idle(proc{ move_big_image.call(b) })\n        end\n\n        images[fn] = img\n        img\n      end\n    end\n  end\n}\n\n#\n# This routine is called for every <SCRIPT> markup\n#\nscript_cmd = proc{|*args|\n  # puts \"ScriptCmd: #{args.inspect}\"\n}\n\n# This routine is called for every <APPLET> markup\n#\napplet_cmd = proc{|w, arglist| \n  # puts \"AppletCmd: w=#{w} arglist=#{arglist}\"\n  TkLabel.new(w, :text=>\"The Applet #{w}\", :bd=>2, :relief=>raised)\n}\n\n#\n# Construct the main HTML viewer\n#\nhtml = Tk::HTML_Widget.new(:padx=>5, :pady=>9, \n                           :formcommand=>form_cmd, \n                           :imagecommand=>image_cmd, \n                           :scriptcommand=>script_cmd, \n                           :appletcommand=>applet_cmd, \n                           :underlinehyperlinks=>0, \n                           :bg=>'white', :tablerelief=>:raised)\nvscr = html.yscrollbar(TkScrollbar.new)\nhscr = html.xscrollbar(TkScrollbar.new)\n\nTk.grid(html, vscr, :sticky=>:news)\nTk.grid(hscr,       :sticky=>:ew)\nTk.root.grid_columnconfigure(0, :weight=>1)\nTk.root.grid_columnconfigure(1, :weight=>0)\nTk.root.grid_rowconfigure(0, :weight=>1)\nTk.root.grid_rowconfigure(1, :weight=>0)\n\n#\n# This procedure is called when the user clicks on a hyperlink.\n#\npriv = {}\nlast_file = ''\n\n# Read a file\n#\nread_file = proc{|name|\n  begin\n    fp = open(name, 'r')\n    ret = fp.read(File.size(name))\n  rescue\n    ret = nil\n    fp = nil\n    Tk.messageBox(:icon=>'error', :message=>\"fail to open '#{name}'\", \n                  :type=>:ok)\n  ensure\n    fp.close if fp\n  end\n  ret\n}\n\n# Clear the screen.\n#\nclear_screen = proc{\n  html.clear\n  old_imgs.clear\n  big_imgs.clear\n  hotkey.clear\n  images.each{|k, v| old_imgs[k] = v }\n  images.clear\n}\n\n# Load a file into the HTML widget\n#\nload_file = proc{|name|\n  if (doc = read_file.call(name))\n    clear_screen.call\n    last_file = name\n    html.configure(:base=>name)\n    html.parse(doc)\n    old_imgs.clear\n  end\n}\n\nhref_binding = proc{|x, y|\n  # koba & dg marking text\n  html.selection_clear\n  priv['mark'] = \"@#{x},#{y}\"\n  lst = html.href(x, y)\n\n  unless lst.size.zero?\n    lnk, target = lst\n\n    if lnk != \"\"\n      if lnk =~ /^#{last_file}#(.*)$/\n        html.yview($1)\n      else\n        load_file.call(lnk)\n      end\n    end\n  end\n}\nhtml.clipping_window.bind('1', href_binding, '%x %y')\n\n# marking text with the mouse and copying to the clipboard just with tkhtml2.0 working\nhtml.clipping_window.bind('B1-Motion', proc{|w, x, y|\n                            w.selection_set(priv['mark'], \"@#{x},#{y}\")\n                            TkClipboard.clear\n                            # avoid tkhtml0.0 errors \n                            # anyone can fix this for tkhtml0.0\n                            begin\n                              TkClipboard.append(TkSelection.get)\n                            rescue\n                            end\n                          }, '%W %x %y')\n\n# This procedure is called when the user selects the File/Open\n# menu option.\n#\nlast_dir = Dir.pwd\nsel_load = proc{\n  filetypes = [\n    ['Html Files', ['.html', '.htm']], \n    ['All Files', '*']\n  ]\n\n  f = Tk.getOpenFile(:initialdir=>last_dir, :filetypes=>filetypes)\n  if f != ''\n    load_file.call(f)\n    last_dir = File.dirname(f)\n  end\n}\n\n# Refresh the current file.\n#\nrefresh = proc{|*args|\n  load_file.call(last_file)\n}\n\n# This binding changes the cursor when the mouse move over\n# top of a hyperlink.\n#\nTk::HTML_Widget::ClippingWindow.bind('Motion', proc{|w, x, y|\n                                       parent = w.winfo_parent\n                                       url = parent.href(x, y)\n                                       unless url.empty?\n                                         parent[:cursor] = 'hand2'\n                                       else\n                                         parent[:cursor] = ''\n                                       end\n                                     }, '%W %x %y')\n#\n# Setup menu\n#\nmenu_spec = [\n  [['File', 0], \n    ['Open',    sel_load, 0], \n    ['Refresh', refresh,   0], \n    '---',\n    ['Exit', proc{exit}, 1]], \n\n  [['View', 0], \n    ['Underline Hyperlinks', ul_hyper], \n    ['Show Table Structure', show_tbl], \n    ['Show Images',          show_img]]\n]\n\nmbar = Tk.root.add_menubar(menu_spec)\n\n#\n# Setup trace\n#\nul_hyper.trace('w', proc{ \n                 html[:underlinehyperlinks] = ul_hyper.value\n                 refresh.call\n               })\n\nshow_tbl.trace('w', proc{\n                 if show_tbl.bool\n                   html[:tablerelief] = :flat\n                 else\n                   html[:tablerelief] = :raised\n                 end\n                 refresh.call\n               })\n\nshow_img.trace('w', refresh)\n\n# If an arguent was specified, read it into the HTML widget.\n#\nTk.update\nif file && file != \"\"\n  load_file.call(file)\nend\n\n#####################################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/page1/index.html",
    "content": "<HTML><HEAD><TITLE>Slashdot:News for Nerds. Stuff that Matters.</TITLE>  </HEAD>\n<BODY bgcolor=\"#000000\" text=\"#000000\" link=\"#006666\" vlink=\"#000000\">\n<center><a href=\"http://209.207.224.220/redir.pl?1463\" target=\"_top\"><img src=\"image1\" alt=\"Click Here to enter the Sweepstakes\" border=\"2\" width=\"468\" height=\"60\"></a></center> <TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\"><TR><TD WIDTH=\"1\"><SCRIPT LANGUAGE=\"JAVASCRIPT\">\n<!-- now=\"now\" =\"\" new=\"new\" Date();=\"Date();\" tail=\"tail\" =\"\" now.getTime();=\"now.getTime();\" document.write(\"<IMG=\"document.write(\"<IMG\" SRC=\"http://209.207.224.245/Slashdot/pc.gif?/slashhead.inc,\"+\" tail=\"tail\" +=\"+\" \"=\"\"\" WIDTH=\"1\" HEIGHT=\"1><BR>\");\" -->\n</SCRIPT>\n<NOSCRIPT>\n<IMG SRC=\"image2\" WIDTH=\"1\" HEIGHT=\"1\">\n</NOSCRIPT></TD></TR></TABLE><P>\n<TABLE bgcolor=\"#FFFFFF\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"99%\" align=\"center\">\n <TR>\n  <TD valign=\"top\" align=\"left\" valign=\"top\"><A href=\"http://slashdot.org/\"><IMG src=\"image3\" width=\"275\" height=\"72\" border=\"0\" alt=\"Welcome to Slashdot\"></A></TD>\n   <TD><A href=\"http://slashdot.org/search.pl?topic=linux\"><IMG SRC=\"image4\" width=\"60\" height=\"70\" border=\"0\" alt=\"Linux\"></A></TD>\n<TD><A href=\"http://slashdot.org/search.pl?topic=news\"><IMG SRC=\"image5\" width=\"34\" height=\"44\" border=\"0\" alt=\"News\"></A></TD>\n<TD><A href=\"http://slashdot.org/search.pl?topic=usa\"><IMG SRC=\"image6\" width=\"80\" height=\"61\" border=\"0\" alt=\"United States\"></A></TD>\n<TD><A href=\"http://slashdot.org/search.pl?topic=ed\"><IMG SRC=\"image7\" width=\"87\" height=\"64\" border=\"0\" alt=\"Education\"></A></TD>\n<TD><A href=\"http://slashdot.org/search.pl?topic=space\"><IMG SRC=\"image8\" width=\"73\" height=\"59\" border=\"0\" alt=\"Space\"></A></TD>\n\n</TR></TABLE>\n<TABLE width=\"99%\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" bgcolor=\"#FFFFFF\"><TR>\n<TD valign=\"top\" rowspan=\"5\"><NOBR><FONT size=\"2\"><B>\n&nbsp;<A href=\"/faq.shtml\">faq</A> <BR>\n&nbsp;<A href=\"/code.shtml\">code</A> <BR>\n&nbsp;<A href=\"/awards.shtml\">awards</A> <BR>\n&nbsp;<A href=\"http://Andover.Net/privacy.html\">privacy</A> <BR>\n&nbsp;<A href=\"http://slashnet.org\">slashNET</A> <BR>\n&nbsp;<A href=\"/search.pl\">older stuff</A> <BR>\n&nbsp;<A href=\"http://cmdrtaco.net\">rob's page</A> <BR>\n&nbsp;<A href=\"/users.pl?op=preferences\">preferences</A> <BR>\n&nbsp;<A href=\"http://Andover.Net\">andover.net</A> <BR>\n&nbsp;<A href=\"/submit.pl\">submit story</A> <BR>\n&nbsp;<A href=\"/advertising.shtml\">advertising</A> <BR>\n&nbsp;<A href=\"/supporters.shtml\">supporters</A> <BR>\n&nbsp;<A href=\"/pollBooth.pl\">past polls</A> <BR>\n&nbsp;<A href=\"/topics.shtml\">topics</A> <BR>\n&nbsp;<A href=\"/about.shtml\">about</A> <BR>\n&nbsp;<A href=\"/jobs.shtml\">jobs</A> <BR>\n&nbsp;<A href=\"/hof.shtml\">hof</A>\n\n</B></FONT></NOBR>\n <P><TABLE border=\"0\" cellpadding=\"1\" cellspacing=\"0\" align=\"center\" bgcolor=\"#CCCCCC\"><TR>\n  <TD><FONT size=\"2\" color=\"#000000\"><B> Sections</B></FONT></TD></TR>\n <TR><TD><TABLE border=\"0\" cellspacing=\"1\" cellpadding=\"1\" bgcolor=\"#FFFFFF\" width=\"100%\"><TR><TD><FONT color=\"#000000\" size=\"2\"><NOBR>\n1/23<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=apache\">apache</A></B><BR>\n1/29 (3)<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=askslashdot\">askslashdot</A></B><BR>\n1/27<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=awards\">awards</A></B><BR>\n1/29 (2)<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=books\">books</A></B><BR>\n1/27<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=bsd\">bsd</A></B><BR>\n1/28 (2)<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=features\">features</A></B><BR>\n1/28 (2)<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=interviews\">interviews</A></B><BR>\n1/19<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=radio\">radio</A></B><BR>\n1/27 (2)<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=science\">science</A></B><BR>\n1/28 (3)<BR>\n<B><A href=\"http://slashdot.org/index.pl?section=yro\">yro</A></B><BR> </NOBR></FONT></TD></TR></TABLE><TR>\n  <TD><A href=\"http://andover.net\"><FONT size=\"2\" color=\"#000000\"><B>Andover.Net</B></FONT></A></TD></TR>\n <TR><TD><TABLE border=\"0\" cellspacing=\"1\" cellpadding=\"1\" bgcolor=\"#FFFFFF\"><TR><TD>\n<FONT color=\"#000000\" size=\"2\"><NOBR><A href=\"http://www.andovernews.com\">AndoverNews</A><BR><A href=\"http://www.askreggie.com\">Ask Reggie</A><BR><A href=\"http://www.davecentral.com\">DaveCentral</A><BR><A href=\"http://www.freecode.com\">FreeCode</A><BR><A href=\"http://www.mediabuilder.com\">MediaBuilder</A><BR> </NOBR></FONT></TD></TR></TABLE></TD></TR></TABLE></P>\n <P></P>\n</TD><TD valign=\"top\" align=\"left\"><FONT color=\"#000000\"> <TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Who Bought Linux.Net?</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=linux\"><IMG src=\"image4\" width=\"60\" height=\"70\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Linux\"></A> <B>Posted by <A href=\"http://CmdrTaco.net\">CmdrTaco</A> on Saturday January 29, @10:52AM</B><BR> <FONT size=\"2\"><B>from the this-game-again dept.</B></FONT><BR> So Fred VanKampen (who has to hold the record for most money made by reselling two domain names) e-mailed us to say that the Domain Name for 'Linux.Net' has been sold. He won't say to whom, but it supposedly will be announced at LinuxWorld next week. Of course we have no idea what he got for the entry, but the rumors were that he made several million when he sold <A href=\"http://www.linux.com\">Linux.com</A> to <A href=\"http://www.valinux.com\">VA Linux</A>. Hopefully he'll take me for a ride in his yacht. ;) <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/29/0837235.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/29/0837235&mode=thread&threshold=0\">58</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/29/0837235&mode=thread&threshold=-1\">62</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Book Reviews: E-Mails from (Over?) The Edge</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=news\"><IMG src=\"image5\" width=\"34\" height=\"44\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"News\"></A> <B>Posted by <A href=\"http://hemos.net\">Hemos</A> on Saturday January 29, @10:43AM</B><BR> <FONT size=\"2\"><B>from the touching-story dept.</B></FONT><BR> I'd like to thank the author of this book for sending it to me. Nick's written a book that's touching and endearing, and one that's well worth reading for everyone who's ever had social struggles to deal with. As well, his involvement with the fine folks of <a href=\"http://www.thevenue.org\">TheVenue</a>. I'll warn you - it's not a tech text. But it's still worth reading. Click below to read more. <P><B>( </B><A href=\"http://slashdot.org/books/00/01/24/1146250.shtml\"><B>Read More...</B></A> | <A href=\"http://slashdot.org/article.pl?sid=00/01/24/1146250&mode=nocomment\">6197 bytes in body</A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/24/1146250&mode=thread&threshold=0\">6</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/24/1146250&mode=thread&threshold=-1\">22</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Linux Kernel 2.3.41</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=linux\"><IMG src=\"image4\" width=\"60\" height=\"70\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Linux\"></A> <B>Posted by <A href=\"http://CmdrTaco.net\">CmdrTaco</A> on Saturday January 29, @10:21AM</B><BR> <FONT size=\"2\"><B>from the download-compile-reboot-repeat dept.</B></FONT><BR> <A href=\"mailto:bwhitehead@nospam.acm.org\">sdriver</A> writes <I>\"For those of us who enjoy *panic*, *oops*, and suddenly seeing their video BIOS... the newest version is out! Be the first on your block to submit a new patch! ;) \"</I> If you don't know where to get it, you probably should stick to your warm and cuddly 2.2.x kernel *grin*. Now outta my way, I wanna crash my laptop! <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/29/0834223.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/29/0834223&mode=thread&threshold=0\">52</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/29/0834223&mode=thread&threshold=-1\">57</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Congress Still Figuring Out E-Mail</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=usa\"><IMG src=\"image6\" width=\"80\" height=\"61\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"United States\"></A> <B>Posted by <A href=\"mailto:roblimo@slashdot.org\">Roblimo</A> on Saturday January 29, @07:28AM</B><BR> <FONT size=\"2\"><B>from the voice-of-the-people-can-get-awfully-loud dept.</B></FONT><BR> Jett writes <I>\" <A href=\"http://www.vote.com/\">Vote.com</A> has <A href=\"http://www.vote.com/magazine/editorials/editorial1843752.phtml\">an interesting article</A> in their Webmag Fifth Estate about how congressmen have responded to the popularity of e-mail in their daily operations. Quote: 'Of the 440 voting and non-voting House of Representatives members, 22 have no e-mail at all. Even House Speaker Dennis Hastert is wired only halfway -- his office receives e-mail, but does not respond to it. And while all U.S. senators have e-mail, they, like their House counterparts, routinely shun non-constituent mail -- even though they chair committees whose decisions affect the entire country.'\"</I> <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/28/2311232.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/28/2311232&mode=thread&threshold=0\">66</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/28/2311232&mode=thread&threshold=-1\">66</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Ask Slashdot: Sci Fi Literature 101?</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=ed\"><IMG src=\"image7\" width=\"87\" height=\"64\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Education\"></A> <B>Posted by <A href=\"http://exit118.com/\">Cliff</A> on Saturday January 29, @06:56AM</B><BR> <FONT size=\"2\"><B>from the recommendations-wanted dept.</B></FONT><BR> ohlaadee asks: <I>\"My niece (she's 13) wants to start reading science fiction. I do too. I gave us both Asimov's </I>_The Foundation_<I>&nbsp; for Christmas. We'll read it together. I suppose we could spend the rest of our lives just reading Asimov, but I'm wondering what books and movies you folks would come up with? What does the /. recommended Science Fiction 101 list include?\"</I> <P><B>( </B><A href=\"http://slashdot.org/askslashdot/00/01/22/1946244.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/22/1946244&mode=thread&threshold=0\">345</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/22/1946244&mode=thread&threshold=-1\">345</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Could Distributed.Net Help the Mars Polar Lander?</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=space\"><IMG src=\"image8\" width=\"73\" height=\"59\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Space\"></A> <B>Posted by <A href=\"mailto:roblimo@slashdot.org\">Roblimo</A> on Saturday January 29, @03:35AM</B><BR> <FONT size=\"2\"><B>from the food-for-thought dept.</B></FONT><BR> Anonymous Coward writes <I>\"This official JPL <A href=\"http://mpfwww.jpl.nasa.gov/msp98/news/mpl000127.html\">press release</A> describes the current attempt to listen for faint signals from the Mars Lander. They get three windows a day, and it takes 18 hours to process data because the signal is so weak (if it's really there). Too bad they don't have a deal with <A href=\"http://www.distributed.net\"> distributed.net</A>.\"</I> Interesting thought. Is anyone at distributed.net or JPL interested in pursuing it? <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/28/2318246.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/28/2318246&mode=thread&threshold=0\">99</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/28/2318246&mode=thread&threshold=-1\">102</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>iCrave TV Loses Battle against U.S. Broadcasters</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=tv\"><IMG src=\"image10\" width=\"50\" height=\"50\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Television\"></A> <B>Posted by <A href=\"mailto:roblimo@slashdot.org\">Roblimo</A> on Saturday January 29, @12:21AM</B><BR> <FONT size=\"2\"><B>from the shut-down-just-before-the-super-bowl dept.</B></FONT><BR> <A href=\"mailto:doran@brandx.net\">Doran</A> writes <I>\"C|Net has <a href=\"http://news.cnet.com/news/0-1004-200-1535528.html\">this story</a> about how the Canadian company <a href=\"http://www.icravetv.com\">iCraveTV.com</a> has lost its latest battle in U.S. courts over whether it can rebroadcast TV signals over the Web. The broadcasters say it's theft, while iCraveTV sez it's just doing what's legal for other cable TV companies in Canada (ie. rebroadcasting TV). Of course, by framing the streaming video iCraveTV is doing more than just rebroadcasting, they're also adding more commercial content, which the broadcasters feel dilutes their TV commercials. \"</I> <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/29/0010203.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/29/0010203&mode=thread&threshold=0\">152</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/29/0010203&mode=thread&threshold=-1\">170</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Win2k Security holes found</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=microsoft\"><IMG src=\"image11\" width=\"75\" height=\"55\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Microsoft\"></A> <B>Posted by <A href=\"mailto:heunique@slashdot.org\">HeUnique</A> on Friday January 28, @04:58PM</B><BR> <FONT size=\"2\"><B>from the and-it's-not-even-out-yet dept.</B></FONT><BR> According to a story posted by <a href=\"http://www.zdnn.com\">ZDNN</a>, <a href=\"http://www.zdnet.com/zdnn/stories/news/0,4586,2429334,00.html?chkpt=zdnntop\">two security holes</a> have been found on Windows 2000, and that's even before the official release of Windows 2000! Administrators who rush to incorporate the patch from MS beware - according to one of the talkback posts on ZDNN, the patch creates a new problem with Windows 2000 news server service. <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/28/1653228.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/28/1653228&mode=thread&threshold=0\">510</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/28/1653228&mode=thread&threshold=-1\">534</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Encryption Debate at Mitnick Trial</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=encryption\"><IMG src=\"image12\" width=\"80\" height=\"70\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Encryption\"></A> <B>Posted by <A href=\"http://hemos.net\">Hemos</A> on Friday January 28, @03:33PM</B><BR> <FONT size=\"2\"><B>from the gimmie-the-data dept.</B></FONT><BR> A number of people have written about <A HREF=\"http://nytimes.com/library/tech/00/01/cyber/cyberlaw/28law.html\">the latest twist</a> in the Mitnick case. Kevin wants to get his data back, but the government is refusing to do so until he gives them the key. Apparently, the government is unable to crack the encryption that he's got on it - you'd think after having the data for five years, they'd be able to brute-force the darn thing. It's a NYT article - free login required. <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/28/1320253.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/28/1320253&mode=thread&threshold=0\">504</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/28/1320253&mode=thread&threshold=-1\">521</A> </B>comments <B>)</B> <P><TABLE width=\"99%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD valign=\"top\" bgcolor=\"#006666\"><IMG src=\"image9\" width=\"13\" height=\"16\" alt=\"\" align=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Forum: Future Ports of Games to Linux</B></FONT></TD> </TR></TABLE><A href=\"http://slashdot.org/search.pl?topic=games\"><IMG src=\"image13\" width=\"80\" height=\"56\" border=\"0\" align=\"right\" hspace=\"20\" vspace=\"10\" alt=\"Games\"></A> <B>Posted by <A href=\"http://CmdrTaco.net\">CmdrTaco</A> on Friday January 28, @02:26PM</B><BR> <FONT size=\"2\"><B>from the it's-been-awhile dept.</B></FONT><BR> It's been a long time since I posted an open forum like this, but I'm curious what people think on this one. What games do you most want to see ported to Linux in the next few months? Of course, for me personally it's StarCraft and Diablo 2, but I'm curious what games have come out or are due soon that people would most like to see a port of (and note that WINE doesn't count. ;) <P><B>( </B><A href=\"http://slashdot.org/articles/00/01/28/1257211.shtml\"><B>Read More...</B></A> | <B><A href=\"http://slashdot.org/article.pl?sid=00/01/28/1257211&mode=thread&threshold=0\">648</A> of <A href=\"http://slashdot.org/article.pl?sid=00/01/28/1257211&mode=thread&threshold=-1\">652</A> </B>comments <B>)</B> <P></TD><TD width=\"210\" align=\"center\" valign=\"top\"><TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B><A HREF=\"/index.pl?section=features\"><FONT COLOR=\"#FFFFFF\">Features</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><A href=\"/vote.pl\">Voting has begun</A> for the $100k <A href=\"/index.pl?section=awards\">Slashdot Beanie Awards</A>. Talk amongst yourselves and choose who deserves the cash. <P>The latest installment of <A href=\"http://www.thesync.com/geeks\">Geeks in Space</A> is up at <A href=\"http://www.thesync.com\">The Sync</A>. Listen to CmdrTaco, Hemos, and Nate talk about the latest events to happen - or not happen in the computer world. <P>Perhaps you are seeking Jon Katz's series of articles related to recent events in Colorado. These articles include <A href=\"/article.pl?sid=99/04/25/1438249\">Voices from the Hellmouth</A>, <A href=\"/article.pl?sid=99/04/27/0310247\">More Stories from the Hellmouth</A> or <A href=\"/article.pl?sid=99/04/29/0124247\">The Price of Being Different</A>, <P>For something different, try reading a little essay <A href=\"/article.pl?sid=99/03/31/0137221\">Thoughts from the Furnace</A> about the internet, and flame. <p> And for a bit of an amusing take on the Open Source world, check out <a href=\"/article.pl?sid=99/08/24/1327256&mode=thread\">Open Source as an Ant Farm</a> <P><B>Update: 01/03 03:10</B> by <B><A href=\"http://cowboyneal.org\">CowboyNeal</a></B>: <P align=\"right\"><B><A href=\"/features/\">Past Features</A></B> <!-- end=\"end\" features=\"features\" block=\"block\" --></FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B><A HREF=\"http://slashdot.org/index.pl?section=askslashdot\"><FONT COLOR=\"#FFFFFF\">Ask Slashdot</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1946244\">Sci Fi Literature 101?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/192226\">Linux and Satellite Internet Services</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1843258\">Open Defensive Patents?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1825252\">Technologies That Shaped the Last Century?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1958212\">Disk Repair Tools for Linux?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1955215\">Why Can't the Command-Line be More Standardized?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1928235\">Packet Radio Networking with PalmOS?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1817211\">Cheap Rackmount Enclosures/Systems?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1950249\">Open Source Software and Tax Breaks?</A> <li><A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1917207\">Building an Upgradable Dual Processor System</A> <P> if you have a question for Ask Slashdot, send it to <A href=\"mailto:askslashdot@slashdot.org\">askslashdot@slashdot.org</A></FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B><A HREF=\"/users.pl\"><FONT COLOR=\"#FFFFFF\">Slashdot Login</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><FORM action=\"/users.pl\" METHOD=\"POST\"> <B>Nickname:</B><BR> <INPUT type=\"text\" name=\"unickname\" size=\"20\" value=\"\"><BR> <B>Password:</B><BR> <INPUT type=\"hidden\" name=\"returnto\" value=\"index.pl\"> <INPUT type=\"password\" name=\"upasswd\" size=\"20\"><BR> <INPUT type=\"submit\" name=\"op\" value=\"userlogin\"> </FORM> Don't have an account yet? <A href=\"/users.pl\">Go Create One</A>. A user account will allow you to customize all these <A href=\"/cheesyportal.shtml\">nutty little boxes</A>, tailor the stories you see, as well as remember your comment viewing preferences.</FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Slashdot Poll</B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><FORM action=\"http://slashdot.org/pollBooth.pl\"> <INPUT type=\"hidden\" name=\"qid\" value=\"techadvance\"> <B>The Tech Advance I Most Want Is:</B><BR><INPUT type=\"radio\" name=\"aid\" value=\"1\">Nanotechnology<BR><INPUT type=\"radio\" name=\"aid\" value=\"2\">Cold Fusion<BR><INPUT type=\"radio\" name=\"aid\" value=\"3\">Powerful Fuel Cells<BR><INPUT type=\"radio\" name=\"aid\" value=\"4\">Hard Wiring my Body<BR><INPUT type=\"radio\" name=\"aid\" value=\"5\">Universal Strong Crypto<BR><INPUT type=\"radio\" name=\"aid\" value=\"6\">Interstellar Travel<BR><INPUT type=\"radio\" name=\"aid\" value=\"7\">Cybernetic Body Armor<BR><INPUT type=\"radio\" name=\"aid\" value=\"8\">ColecoVision<BR><INPUT type=\"submit\" value=\"Vote\"> [ <A href=\"http://slashdot.org/pollBooth.pl?qid=techadvance&aid=-1\"><B>Results</B></A> | <A href=\"http://slashdot.org/pollBooth.pl?\"><B>Polls</B></A> ] <BR>Comments:<B>656</B> | Votes:<B>29121</B></FORM> </FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Older Stuff</B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><P><B><A href=\"http://slashdot.org/index.pl?section=&issue=730512&mode=thread\"><FONT size=\"4\">Friday</FONT></A> January 28</B> <LI><A href=\"http://slashdot.org/articles/00/01/28/1110258.shtml\">Abstract Programming and GPL Enforcement</A> (235) <LI><A href=\"http://slashdot.org/interviews/00/01/28/1225206.shtml\">Interview: FreeDOS Leader Jim Hall Answers</A> (86) <LI><A href=\"http://slashdot.org/articles/00/01/28/116240.shtml\">Open Source's Achilles Heel</A> (466) <LI><A href=\"http://slashdot.org/features/00/01/26/1915230.shtml\">The Virtue of Communal Instincts</A> (237) <LI><A href=\"http://slashdot.org/articles/00/01/28/0723223.shtml\">Gartner Group Debunking Open Source Myths</A> (165) <LI><A href=\"http://slashdot.org/yro/00/01/28/0917229.shtml\">DoubleClick Taken to Court</A> (310) <LI><A href=\"http://slashdot.org/articles/00/01/28/0718209.shtml\">Updated Slash & Server 51</A> (81) <LI><A href=\"http://slashdot.org/articles/00/01/28/089230.shtml\">XMMS 1.0.0 Released</A> (128) <LI><A href=\"http://slashdot.org/askslashdot/00/01/22/192226.shtml\">Linux and Satellite Internet Services</A> (138) <LI><A href=\"http://slashdot.org/articles/00/01/27/1811221.shtml\">UN Wants to Combat Online Racism</A> (531) <P><B><A href=\"http://slashdot.org/index.pl?section=&issue=730511&mode=thread\"><FONT size=\"4\">Thursday</FONT></A> January 27</B> <LI><A href=\"http://slashdot.org/yro/00/01/27/2330205.shtml\">Crackdowns, Fools and the MPAA</A> (351) <LI><A href=\"http://slashdot.org/articles/00/01/27/0832215.shtml\">Heroes of Might and Magic III Demo Released</A> (157) <LI><A href=\"http://slashdot.org/science/00/01/27/1345241.shtml\">Sandia Labs Venture Into Nanotechnology</A> (117) <LI><A href=\"http://slashdot.org/articles/00/01/27/0931237.shtml\">CA Announces Program Ports to Linux</A> (195) <LI><A href=\"http://slashdot.org/interviews/00/01/27/1118251.shtml\">Interview: Larry Augustin Finally Answers</A> (210) <LI><A href=\"http://slashdot.org/awards/00/01/27/0855252.shtml\">Final Call for Voting in Slashdot's Beanie Awards</A> (178) <LI><A href=\"http://slashdot.org/features/00/01/26/197211.shtml\">Transmeta Code Morphing != Just In Time</A> (449) <LI><A href=\"http://slashdot.org/books/00/01/24/1150256.shtml\">Intrusion Detection</A> (65) <LI><A href=\"http://slashdot.org/science/00/01/27/0824239.shtml\">Using Enzymes to Help Fight CO2 Build-Up</A> (165) <LI><A href=\"http://slashdot.org/articles/00/01/27/0712217.shtml\">Jon Johansen on ABC World News Tonight</A> (415) <P align=\"right\"><BR><A href=\"http://slashdot.org/search.pl?section=&min=30\"><B>Older Articles</B></A><BR><A href=\"http://slashdot.org/index.pl?section=&mode=thread&issue=730512\"><B>Yesterday's Edition</B></A> </FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B><A HREF=\"/index.pl?section=books\"><FONT COLOR=\"#FFFFFF\">Book Reviews</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><p>Jon Katz, Resident Gasbag, has a new, very appropriate book coming out soon, <a href=\"http://www.thinkgeek.com\">Geeks</a>. Preorder now and receive the book early. <p>For probably the best fiction read around, check out Neal Stephenson's <cite><a href=\"/article.pl?sid=99/06/23/139229&mode=thread\">Cryptonomicon</a></cite>, an engaging read about WWII, cryptography and buried treasure. And data vaults. <p>If you've been doing a lot of work in Perl, you've probably figured out you really need <cite><a href=\"/article.pl?sid=99/05/10/2238254&mode=thread\">Perl in a Nutshell</a></cite> or <cite><a href=\"/article.pl?sid=99/01/29/1035246&mode=thread\">The Perl Cookbook</a></cite>. If you're still learning, grab <cite><a href=\"/books/older/980526096229.shtml\">Programming Perl</a></cite>. <p>And if you want to learn more about how to become a better coder, grab <cite><a href=\"/article.pl?sid=99/06/28/1417229&mode=thread\">The Unified Software Development Process</a></cite> or <cite><a href=\"/article.pl?sid=99/04/08/1512209&mode=thread\">The Practice of Programming</cite></a> Additionally, check out <cite><a href=\"http://slashdot.org/article.pl?sid=99/09/16/1333202&mode=thread\">Refactoring: Improving the Design of Existing Code</a></cite> . <p>Developing a large application? Grab Eric Greenberg's excellent <cite><a href=\"/article.pl?sid=99/07/13/1943258&mode=thread\">Network Application Frameworks</cite></a>. <P>Visit <A href=\"/index.pl?section=books\">Our Book Reviews Section</A> for more. <br> <B>Update: 11/12 05:19</B> by <B><A href=\"mailto:hemos@slashdot.org\">H</A></B>:</FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B>Quick Links</B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><B>Cool Sites:</B> <LI><A href=\"http://www.linux.com\">Linux.com</A> (What <B>is</B> Linux?) <LI><A href=\"http://everything.blockstackers.com\">Everything</A> (Blow your Mind) <LI><A href=\"http://www.geekculture.com/geekycomics/Aftery2k/aftery2kmain.html\">After Y2k</A> (<I>This</I> is Post-Apocalyptic?) <LI><A href=\"http://www.userfriendly.org\">User Friendly</A> (Laugh) <LI><A href=\"http://themes.org\">Themes.org</A> (Make X Perty) <P><B>Support Slashdot:</B> <LI><A href=\"http://www.thinkgeek.com\">ThinkGeek</A> (Clothe Yourself in Slashdot) <LI><A href=\"http://cdnow.com/from=sr-302791\">CDnow</A> (Support <A href=\"http://www.cdnow.com/gift/malda@slashdot.org\">Rob's Who Habit</A>) <LI><A href=\"http://adfu.slashdot.org\">Slashdot Advertiser Index</A></FONT></TD> </TR> </TABLE><P> <TABLE cellpadding=\"1\" cellspacing=\"0\" border=\"0\" width=\"200\" align=\"center\"> <TR bgcolor=\"#006666\"> <TD valign=\"top\"><FONT size=\"4\" color=\"#FFFFFF\" face=\"arial,helvetica\"><B><A HREF=\"http://freshmeat.net\"><FONT COLOR=\"#FFFFFF\">Freshmeat</FONT></A></B></FONT></TD> </TR><TR><TD bgcolor=\"#CCCCCC\"><FONT color=\"#000000\" size=\"2\"><P><FONT size=\"4\" color=\"#006666\"><B>January</B></FONT><BR> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949208399.html\">We should get this out of the door now</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949159642.html\">Is Linux for Crazies?</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949156343.html\">SQN Linux 1.6</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949156277.html\">Limo 0.3.2</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949156237.html\">Fusion GS 1.3</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949145887.html\">MMR 1.5.4</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949142835.html\">KUPS 0.3.4</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949142815.html\">3DSE patch for XMMS 4</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949139763.html\">Linux 2.3.41</A> <LI><A href=\"http://freshmeat.net/news/2000/01/29/949139751.html\">Free Code for Linux S/390</A> <FORM METHOD=\"post\" ACTION=\"http://core.freshmeat.net/search.php3\"> <FONT size=\"3\" color=\"#006666\"><B>Search Freshmeat:</B></FONT><BR> <INPUT TYPE=\"hidden\" NAME=\"link\" VALUE=\"freshmeat.net\"> <INPUT TYPE=\"text\" NAME=\"query\"> </FORM> <P align=\"right\"><A href=\"http://freshmeat.net\"><B>More Meat...</B></A></FONT></TD> </TR> </TABLE><P> </FONT></TD>\n         </TR>\n        </TABLE><TABLE cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"99%\" align=\"center\" bgcolor=\"ffffff\">\n            <TR>\n             <TD colspan=\"4\" align=\"center\"><IMG src=\"image14\" alt=\"\" width=\"80%\" height=\"1\" hspace=\"10\" vspace=\"30\"></TD>\n            </TR><TR>\n             <TD align=\"center\"><FONT size=\"2\" face=\"arial,helvetica\">\n  <FORM method=\"GET\" action=\"http://slashdot.org/search.pl\">\n         <INPUT type=\"name\" name=\"query\" value=\"\" width=\"20\" size=\"20\" length=\"20\">\n        <INPUT type=\"submit\" value=\"Search\">\n  </FORM>\n  </FONT>\n  </TD>\n  <TD bgcolor=\"#ffffff\" width=\"25\">  &nbsp; </TD>\n  <TD align=\"center\">\n    <FONT size=\"2\" face=\"arial,helvetica\"><I>Wasn't there something about a PASCAL programmer knowing the value of\neverything and the Wirth of nothing?\n<TD>&nbsp;</TD></I></FONT>\n    </FONT>\n  </TD></TR>\n  <TR><TD colspan=\"4\" align=\"center\">\n  <FONT size=\"1\" color=\"#006666\" face=\"arial,helvetica\">\n\n All trademarks and copyrights on this\n  page are owned by their respective owners.  Comments\n  are owned by the Poster.\n  The Rest  1997-2000 <A href=\"http://Andover.Net\">Andover.Net</A>.\n</FONT></CENTER>\n             </TD>\n            </TR>\n           </TABLE>\n        <CENTER>\n          <FONT size=\"2\" color=\"#006666\">\n\n         [ <A href=\"http://slashdot.org/\"><Font color=\"#ffffff\">home</FONT></A> |\n         <A href=\"http://slashdot.org/awards.shtml\"><Font color=\"#ffffff\">awards</FONT></A> |\n         <A href=\"http://slashdot.org/supporters.shtml\"><FONT color=\"#ffffff\">supporters</FONT></A> |\n         <A href=\"http://CmdrTaco.net\"><FONT color=\"#ffffff\">rob's homepage</FONT></A> |\n         <A href=\"http://slashdot.org/submit.pl\"><FONT color=\"#ffffff\">contribute story</FONT></A> |\n         <A href=\"http://slashdot.org/search.pl\"><FONT color=\"#ffffff\">older articles</FONT></A> |\n         <A href=\"http://Andover.Net\"><FONT color=\"#ffffff\">Andover.Net</FONT></A> |\n         <A href=\"http://slashdot.org/advertising.shtml\"><FONT color=\"#ffffff\">advertising</FONT></A> |\n         <A href=\"http://slashdot.org/pollBooth.pl\"><FONT color=\"#ffffff\">past polls</FONT></A> |\n         <A href=\"http://slashdot.org/about.shtml\"><FONT color=\"#ffffff\">about</FONT></A> |\n         <A href=\"http://slashdot.org/faq.shtml\"><FONT color=\"#ffffff\">faq</FONT></A> ]\n           </FONT>\n          </CENTER>\n</BODY>\n</HTML>\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/page2/index.html",
    "content": "<html>\n<head>\n  <title>Tcl Resource Center</title>\n</head>\n\n<body bgcolor=\"white\" text=\"black\">\n\n    <!-- MenuTopLevel Resource Software Extensions -->\n    <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n      <tr>\n        <td width=\"120\" valign=\"TOP\"><a href=\"/\"><img src=\"image1\" width=\"120\" height=\"79\" alt=\"Scriptics\" border=\"0\"></a></td>\n        <td valign=\"top\" width=\"548\">\n        \n          <!-- Table to hold tabs -->\n          <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"548\">\n            <tr>\n              <td valign=\"top\" align=\"right\" colspan=\"15\" width=\"548\"><a name=\"TOP\"><img src=\"image2\" width=\"548\" height=\"9\" alt=\"Tcl/Tk\" border=\"0\"></a></td>\n            </tr>\n            <tr>\n              <td valign=\"top\" align=\"right\" colspan=\"15\" width=\"548\"><img src=\"image3\" width=\"482\" height=\"34\" alt=\"Scripting Solutions for eBusiness Integration\" border=\"0\"></td>\n            </tr>\n            <tr>\n              <td width=\"18\" valign=\"TOP\"><img src=\"image4\" width=\"18\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"58\"><a href=\"/products/\" onMouseOver=\"msover(4, 'http://images.scriptics.com/images/ProductsMouseOff.gif') ; return true ;\" onMouseOut=\"msover(4, 'http://images.scriptics.com/images/ProductsOff.gif') ; return true ;\"><img src=\"image5\" width=\"58\" height=\"36\" alt=\"Products\" border=\"0\"></a></td>\n              <td width=\"14\" valign=\"TOP\"><img src=\"image6\" width=\"14\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"69\"><a href=\"/customers/\" onMouseOver=\"msover(6, 'http://images.scriptics.com/images/CustomersMouseOff.gif') ; return true ;\" onMouseOut=\"msover(6, 'http://images.scriptics.com/images/CustomersOff.gif') ; return true ;\"><img src=\"image7\" width=\"69\" height=\"36\" alt=\"Customers\" border=\"0\"></a></td>\n              <td width=\"14\" valign=\"TOP\"><img src=\"image6\" width=\"14\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"60\"><a href=\"/partners/\" onMouseOver=\"msover(8, 'http://images.scriptics.com/images/PartnersMouseOff.gif') ; return true ;\" onMouseOut=\"msover(8, 'http://images.scriptics.com/images/PartnersOff.gif') ; return true ;\"><img src=\"image8\" width=\"60\" height=\"36\" alt=\"Partners\" border=\"0\"></a></td>\n              <td width=\"14\" valign=\"TOP\"><img src=\"image6\" width=\"14\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"56\"><a href=\"/services/\" onMouseOver=\"msover(10, 'http://images.scriptics.com/images/ServicesMouseOff.gif') ; return true ;\" onMouseOut=\"msover(10, 'http://images.scriptics.com/images/ServicesOff.gif') ; return true ;\"><img src=\"image9\" width=\"56\" height=\"36\" alt=\"Services\" border=\"0\"></a></td>\n              <td width=\"14\" valign=\"TOP\"><img src=\"image10\" width=\"14\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"88\"><a href=\"/resource/\" onMouseOver=\"msover(12, 'http://images.scriptics.com/images/ResourceMouseOn.gif') ; return true ;\" onMouseOut=\"msover(12, 'http://images.scriptics.com/images/ResourceOn.gif') ; return true ;\"><img src=\"image11\" width=\"88\" height=\"36\" alt=\"Tcl Resources\" border=\"0\"></a></td>\n              <td width=\"14\" valign=\"TOP\"><img src=\"image12\" width=\"14\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"57\"><a href=\"/company/\" onMouseOver=\"msover(14, 'http://images.scriptics.com/images/CompanyMouseOff.gif') ; return true ;\" onMouseOut=\"msover(14, 'http://images.scriptics.com/images/CompanyOff.gif') ; return true ;\"><img src=\"image13\" width=\"57\" height=\"36\" alt=\"Company\" border=\"0\"></a></td>\n              <td width=\"8\" valign=\"TOP\"><img src=\"image14\" width=\"8\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"50\" valign=\"TOP\"><img src=\"image15\" width=\"50\" height=\"36\" alt=\"\" border=\"0\"></td>\n              <td width=\"14\" valign=\"TOP\"><img src=\"image16\" width=\"14\" height=\"36\" alt=\"\" border=\"0\"></td>\n            </tr>\n          </table>\n        </td>\n      </tr>\n    </table> <script language=\"Javascript\">\n   <!--\n\tfunction msover(num, file )\n\t{\n\t    old = (((navigator.appName=='Netscape') &&\n\t              (parseInt(navigator.appVersion)<=3.0 )))\n\t  if ( !old ) {\n\t\tdocument.images[num].src=file\n\t  }\n        }\n\t//-->\n   </SCRIPT> \n\t\n<!-- MenuSubLevel Resource Software Extensions Tk -->\n\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n\n<!-- Left Hand Column-->\n\n<tr><td valign=\"top\" width=\"120\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"120\">\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image17\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/\"><img src=\"image18\" width=\"120\" height=\"11\" alt=\"Software\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image19\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/tcltk/\"><img src=\"image20\" width=\"120\" height=\"11\" alt=\"Tcl/Tk Core\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image19\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/applications/\"><img src=\"image21\" width=\"120\" height=\"11\" alt=\"Applications\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image22\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/extensions/\"><img src=\"image23\" width=\"120\" height=\"11\" alt=\"Extensions\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image24\" width=\"120\" height=\"6\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/patches/\"><img src=\"image25\" width=\"120\" height=\"11\" alt=\"Patches\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image19\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/java/\"><img src=\"image26\" width=\"120\" height=\"11\" alt=\"Tcl &amp; Java\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image19\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/ports/\"><img src=\"image27\" width=\"120\" height=\"11\" alt=\"Tcl/Tk Ports\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image19\" width=\"120\" height=\"4\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/software/tools/\"><img src=\"image28\" width=\"120\" height=\"11\" alt=\"Tools\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image29\" width=\"120\" height=\"6\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/doc/\"><img src=\"image30\" width=\"120\" height=\"11\" alt=\"Documentation\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image31\" width=\"120\" height=\"5\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/resource/community/\"><img src=\"image32\" width=\"120\" height=\"11\" alt=\"Community\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image31\" width=\"120\" height=\"5\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/live/bydate\"><img src=\"image33\" width=\"120\" height=\"11\" alt=\"What's New\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image31\" width=\"120\" height=\"5\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/forms/urlnote.html\"><img src=\"image34\" width=\"120\" height=\"11\" alt=\"Add URL\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image31\" width=\"120\" height=\"5\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/live/keyword\"><img src=\"image35\" width=\"120\" height=\"11\" alt=\"Keyword Search\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image31\" width=\"120\" height=\"5\" alt=\"\" border=\"0\"></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><a href=\"/live/sitemap\"><img src=\"image36\" width=\"120\" height=\"11\" alt=\"Index\" border=\"0\"></a></td>\n    </tr>\n    <tr>\n      <td width=\"120\" valign=\"TOP\"><img src=\"image37\" width=\"120\" height=\"6\" alt=\"\" border=\"0\"></td>\n    </tr>\n</table><!-- End Left Column --></td><!-- Right Hand Column --><td valign=\"top\" width=\"548\" align=\"left\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"548\">\n    <tr>\n      <td width=\"295\" valign=\"TOP\"><img src=\"image38\" width=\"295\" height=\"42\" alt=\"Resource\" border=\"0\"></td>\n      <td width=\"187\" valign=\"bottom\" align=\"right\"><FORM action=\"/live/keyword\"><img src=\"image39\" width=\"46\" height=\"24\" alt=\"\" border=\"0\"><INPUT TYPE=\"TEXT\" SIZE=\"10\" MAXLENGTH=\"35\" NAME=\"keywords\"><INPUT type=\"IMAGE\" border=\"0\" img=\"img\" src=\"http://images.scriptics.com/images/Go.gif\" value=\"submit\" width=\"33\" height=\"24\"></FORM>\n    </tr>\n  </table>\n  <!-- 2 Columns for spacer -->\n  <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"548\">\n    <tr>\n      <!-- Spacer Column -->\n      <td valign=\"top\" width=\"10\">\n      &nbsp;\n      </td>\n\n\n      <td valign=\"top\" width=\"548\"><font face=\"Geneva, Helvetica, Arial\" size=\"2\"><h1>Tcl Resource Center</h1>\n<font size=\"+1\"><a href=\"/resource/\">Top</a>&gt;<a href=\"/resource/software/\" =\"\">Software Central</a>&gt;<a href=\"/resource/software/extensions/\" =\"\">Extensions</a>&gt;Tk Widgets</font><font size=\"-1\"><br>Viewed by name (<a href=\"/resource/software/extensions/tk/?sortby=date\">By date</a>)</font><br>\n<p>Tk is a toolkit for building graphical user interfaces with Tcl.\n    Your Tcl/Tk scripts run on UNIX, Windows, and Macintosh.<p>\n<font face=\"Geneva, Helvetica, Arial\"><ul></ul></font><dl>\n<dt><b><a href=\"http://marge.phys.washington.edu/%7Ezager/blt80-unoff-exe.zip\" =\"\">BLT 8.0 Unofficial zip and DLL</a></b>\n<dd>This is a compiled version of BLT 8.0 \"unofficial\" for\nthe Windows platform. <a href=\"/live/annotate?url=http%3a%2f%2fmarge%2ephys%2ewashington%2eedu%2f%257Ezager%2fblt80%2dunoff%2dexe%2ezip\">Edit</a>\n <i><font size=\"-1\">(September 24, 1999 06:31)</font></i><dt><b><a href=\"ftp://ftp.neosoft.com/languages/tcl/sorted/unknown/blt8.0p2-unoff.tgz\" =\"\">BLT 8.0p2 Unofficial tar file</a><a name=\"bltunoff\"></a></b>\n<dd>This is a contributed patch to make BLT compatible with Tcl/Tk 8.0p2.  While still \"unofficial\", it is widely used.\n    Make sure you get the 8.0p2 version because the 8.0 version does\n    not compile under windows.\n    There is also a <a href=\"ftp://ftp.neosoft.com/languages/sorted/devel/blt2.3-8.1.tar.gz\">2.3-8.1 version</a> that has been patched to work with 8.1.\n    <a href=\"ftp://ftp.neosoft.com/languages/tcl/sorted/unknown/blt8.0p2-unoff.README\">README file</a>. <a href=\"/live/annotate?url=ftp%3a%2f%2fftp%2eneosoft%2ecom%2flanguages%2ftcl%2fsorted%2funknown%2fblt8%2e0p2%2dunoff%2etgz\">Edit</a>\n <i><font size=\"-1\">(August 30, 1999 06:38)</font></i><dt><b><a href=\"http://www.tcltk.com/blt/\" =\"\">BLT Home Page</a></b>\n<dd>\n\t\t\tAuthor <b>George Howlett</b>, Version <b>2.3</b>,\n\t\t\tWorks with <b>Tk 4.1 through Tk 8.1</b>\n<br><a href=\"ftp://ftp.tcltk.com/pub/blt/\">Download</a>, <a href=\"ftp://ftp.tcltk.com/pub/blt/BLT2.3.tar.gz\">BLT2.3.tar.gz</a>, <a href=\"ftp://ftp.tcltk.com/pub/blt/BLT2.4h.tar.gz\">BLT2.4h.tar.gz</a>, <a href=\"ftp://ftp.tcltk.com/pub/blt/BLT2.4i.tar.gz\">BLT2.4i.tar.gz</a>, <a href=\"ftp://ftp.tcltk.com/pub/blt/blt2.4i-for-8.0.exe\">blt2.4i-for-8.0.exe</a>, <a href=\"ftp://ftp.tcltk.com/pub/blt/blt2.4i-for-8.1.exe\">blt2.4i-for-8.1.exe</a><br>BLT is a set of widgets for Tk, including a graph widget,\nbar chart, drag&drop, a simple command tracer, and much more.\nThe 2.4 release, which is still under development, works with 8.0\nor higher.\nThere are also an \"<a href=\"#bltunoff\">unofficial</a>\" release for 8.0p2\nand 8.1a2 that were not done by the author. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2etcltk%2ecom%2fblt%2f\">Edit</a>\n <i><font size=\"-1\">(October 26, 1999 09:43)</font></i><dt><b><a href=\"http://www.unifix-online.com/BWidget/index.html\" =\"\">BWidget</a></b>\n<dd>A set of native Tk 8.x Widgets using Tcl8.x namespaces. \nThe ToolKit is available under Unix/X11 and Windows.\nThe BWidget(s) have a professional look&feel as in other \nwell known Toolkits (Tix or Incr Widget) but the concept is \nradically different because everything is native \nso no platform compilation, no compiled extension\nlibrary are needed. The code is 100 Pure Tcl/Tk. \nMore 30 components : Notebook, PageManager, Tree, PanedWindow, ButtonBox,\nScrollView, ComboBox, SpinBox, ListBox, SelectFont, SelectColor,\nProgressBare ... <a href=\"/live/annotate?url=http%3a%2f%2fwww%2eunifix%2donline%2ecom%2fBWidget%2findex%2ehtml\">Edit</a>\n <i><font size=\"-1\">(September 06, 1999 09:58)</font></i><dt><b><a href=\"http://purl.oclc.org/net/nijtmans/dash.html\" =\"\">Dash Patch for Tk</a></b>\n<dd>This patch has many enhancements to the Tk and its canvas\nwidget, including dashed lines, smoothed polygons,\nand performance enhancements. <a href=\"/live/annotate?url=http%3a%2f%2fpurl%2eoclc%2eorg%2fnet%2fnijtmans%2fdash%2ehtml\">Edit</a>\n <i><font size=\"-1\">(November 21, 1999 06:33)</font></i><dt><b><a href=\"http://www.hwaci.com/sw/et\" =\"\">Embedded Tk (et)</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:drh@acm.org\" =\"\">Richard Hipp</a></b>, Version <b>8.0b5</b>,\n\t\t\tWorks with <b>Tk 4.0, 4.1, 4.2, 8.0</b>\n<br>Download: <a href=\"http://www.hwaci.com/sw/et/et80b5.tar.gz\">et80b5.tar.gz</a><br>Embedded Tk or ``ET'' is tool for making stand-alone executables out of a mixture of C or C++ and Tcl/Tk.\nUsing ET you can invoke a short Tcl/Tk script in the middle of a C routine, or you can invoke a C routine in the\nmiddle of a Tcl/Tk script. ET also bundles external Tcl/Tk scripts (including the standard Tcl/Tk startup scripts)\ninto the executable so that the executable can be run on another binary-compatible computer that doesn't have\nTcl/Tk installed.  <a href=\"/live/annotate?url=http%3a%2f%2fwww%2ehwaci%2ecom%2fsw%2fet\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 15:35)</font></i><dt><b><a href=\"http://www.purl.org/net/hobbs/tcl/script/tkcon/\" =\"\">Enhanced Tk Console (TkCon)</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:jeffrey.hobbs@oen.siemens.de\" =\"\">Jeff Hobbs</a></b>, Version <b>1.3</b>,\n\t\t\tWorks with <b>Tk 4.1 through Tk 8.1</b>\n<br>Download: <a href=\"http://www.purl.org/net/hobbs/tcl/script/tkcon/tkcon.tar.gz\">tkcon.tar.gz</a><br>TkCon is a replacement for the standard console that comes with Tk (on Windows/Mac, but also works on\n\nUnix). The console itself provides many more features than the standard console.  <a href=\"/live/annotate?url=http%3a%2f%2fwww%2epurl%2eorg%2fnet%2fhobbs%2ftcl%2fscript%2ftkcon%2f\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:06)</font></i><dt><b><a href=\"http://www.scriptmeridian.org/projects/tk/\" =\"\">Frontier-Tk ScriptMeridian project</a></b>\n<dd>This project seeks to integrate the Tk toolkit\nwith the Frontier scripting language. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2escriptmeridian%2eorg%2fprojects%2ftk%2f\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 15:36)</font></i><dt><b><a href=\"http://purl.oclc.org/net/nijtmans/img.html\" =\"\">Img image format extension</a></b>\n<dd>This package enhances Tk, adding support for many other Image formats: \nBMP, XBM, XPM, GIF (with transparency), PNG,\nJPEG, TIFF and postscript.\nThis is implemented as a shared library that can be dynamically loaded into \nTcl/Tk.\n <a href=\"/live/annotate?url=http%3a%2f%2fpurl%2eoclc%2eorg%2fnet%2fnijtmans%2fimg%2ehtml\">Edit</a>\n <i><font size=\"-1\">(November 21, 1999 06:35)</font></i><dt><b><a href=\"http://purl.oclc.org/net/oakley/tcl/mclistbox/index.html\" =\"\">mclistbox - a multi-column listbox widget</a></b>\n<dd>mclistbox is a multi-column listbox that is\nwritten in pure tcl and runs on all platforms\nthat support tcl/tk 8.0 or higher. This widget\nrequires no other extensions; it is completely\nstandalone. <a href=\"/live/annotate?url=http%3a%2f%2fpurl%2eoclc%2eorg%2fnet%2foakley%2ftcl%2fmclistbox%2findex%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 15:37)</font></i><dt><b><a href=\"http://home.t-online.de/home/dshepherd/tkview.htm\" =\"\">MFC views C++ class for embedding Tk</a></b>\n<dd>The idea of embedding Tk in MFC windows always seemed very enticing but information was sparse and contradictory - on a\n scale between \"very easy\" and \"not yet possible\". The only thing for it was to have a go and lo, it wasn't that hard after all.  \n CTkView is a C++ class which can be used in MFC SDI or MDI applications. An instance of CTkView hosts an embedded Tk\n toplevel widget and performs some management chores for the widget so that it can size, update and react correctly to Windows\n events.   <a href=\"/live/annotate?url=http%3a%2f%2fhome%2et%2donline%2ede%2fhome%2fdshepherd%2ftkview%2ehtm\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 15:38)</font></i><dt><b><a href=\"http://www.cs.umd.edu/hcil/pad++\" =\"\">Pad++</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:pad-info@cs.umd.edu\" =\"\">Ben Bederson et al</a></b>, Version <b>0.9p1</b>,\n\t\t\tWorks with <b>8.0</b>\n<br>Download: <a href=\"http://www.cs.umd.edu/hcil/pad++/download.html\">download.html</a><br>Pad++ is a Tk widget that provides a Zoomable User Interface (ZUI) that supports real-time interactive zoomable graphics in a fashion similar to the Tk Canvas widget.  Pad++ supports tens of thousands of objects which include text, images, graphics, portals, lenses, simple html (and more), including transparency and rotation. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2ecs%2eumd%2eedu%2fhcil%2fpad%2b%2b\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 15:39)</font></i><dt><b><a href=\"http://home.t-online.de/home/sesam.com/freeware.htm\" =\"\">Progressbar</a></b>\n<dd>Progressbar is a megawidget written in pure tcl (ie: no compiling required - runs on all platforms Macintosh, Unix, Windows). \nIts primary purpose is to show the progress of any action in percent. <a href=\"/live/annotate?url=http%3a%2f%2fhome%2et%2donline%2ede%2fhome%2fsesam%2ecom%2ffreeware%2ehtm\">Edit</a>\n <i><font size=\"-1\">(January 24, 2000 09:19)</font></i><dt><b><a href=\"http://jfontain.free.fr/\" =\"\">scwoop (Simple Composite Widget Object Oriented Package)</a></b>\n<dd>Scwoop is a composite widget (also known as mega widget) extension to the great Tk widget library. Scwoop is\nentirely written in Tcl using the stooop (Simple Tcl Only Object Oriented Programming) extension. <a href=\"/live/annotate?url=http%3a%2f%2fjfontain%2efree%2efr%2f\">Edit</a>\n <i><font size=\"-1\">(January 09, 2000 02:10)</font></i><dt><b><a href=\"http://www2.clearlight.com/~oakley/tcl/supertext.html\" =\"\">Supertext - tk text widget with unlimited undo</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:oakley@channelpoint.com\" =\"\">Bryan Oakley</a></b>, Version <b>1.0b1</b>,\n\t\t\tWorks with <b>Tcl 8.0</b>\n<br>Download: <a href=\"http://www2.clearlight.com/~oakley/tcl/supertext.tcl\">supertext.tcl</a><br>Supertext is a package that provides a tk text widget with full undo and the ability to execute procedures both before and after a text\nwidget command has been processed. Supertext may be used as-is, or for the brave it may be used in place of the standard text\nwidget.  <a href=\"/live/annotate?url=http%3a%2f%2fwww2%2eclearlight%2ecom%2f%7eoakley%2ftcl%2fsupertext%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:06)</font></i><dt><b><a href=\"http://www.hwaci.com/sw/tk/nbpi.html\" =\"\">Tabbed Notebook Widget</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:drh@acm.org\" =\"\">Richard Hipp</a></b>, Version <b>1.0</b>,\n\t\t\tWorks with <b>Tk 4.1 or later.</b>\n<br>Download: <a href=\"http://www.hwaci.com/sw/tk/notebook.tcl\">notebook.tcl</a><br>This implements a tabbed notebook using\na canvas widget and embedded frames.\nThis is pure Tcl\ncode - not a C extension. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2ehwaci%2ecom%2fsw%2ftk%2fnbpi%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:08)</font></i><dt><b><a href=\"http://www.tcltk.com/ellson/ftp/Gdtclft2.0.README\" =\"\">Tcl GD - graphics</a></b>\n<dd>\n\t\t\tAuthor <b>John Ellson and Spencer Thomas</b>, Version <b>2.0</b>,\n\t\t\tWorks with <b>8.0 and higher</b>\n<br>Download: <a href=\"http://www.tcltk.com/ellson/ftp/Gdtclft2.0.tar.gz\">Gdtclft2.0.tar.gz</a><br>\n\tThomas Boutell's Gd package provides a convenient way to generate\n\t    PNG images with a C program. If you prefer Tcl for CGI\n\t\tapplications, you'll want the TCL GD extension. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2etcltk%2ecom%2fellson%2fftp%2fGdtclft2%2e0%2eREADME\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 14:52)</font></i><dt><b><a href=\"http://www.stratasys.com/software/metagui\" =\"\">The Meta-GUI Tools</a></b>\n<dd>The Meta-GUI tools provide a framework for quickly building full\nGUI applications. The GUI is rendered by a run-time engine\nbased on a hierarchical set of definitions you provide. At the bottom\nof the hierarchy are abstract data types such as length, angle,\nstring, etc., and these are used to progressively build up frames,\ndialogs, toolbars, menus, and operations. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2estratasys%2ecom%2fsoftware%2fmetagui\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:10)</font></i><dt><b><a href=\"http://jfontain.free.fr/\" =\"\">Tkpiechart Home Page</a></b>\n<dd>Tkpiechart is a Tcl-only extension that allows the programmer to create and dynamically update 2D or 3D pie\ncharts in a Tcl/Tk application.  This uses the stooop package and builds\npie charts on a Tk canvas. <a href=\"/live/annotate?url=http%3a%2f%2fjfontain%2efree%2efr%2f\">Edit</a>\n <i><font size=\"-1\">(January 09, 2000 02:12)</font></i><dt><b><a href=\"http://www.cygnus.com/~irox/tkprint/\" =\"\">TkPrint</a></b>\n<dd>TkPrint is an extension that allows you to print from a\n        Tk widget. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2ecygnus%2ecom%2f%7eirox%2ftkprint%2f\">Edit</a>\n <i><font size=\"-1\">(October 11, 1999 09:58)</font></i><dt><b><a href=\"http://www.purl.org/net/hobbs/tcl/capp/\" =\"\">TkTable Home Page</a></b>\n<dd>The TkTable widget.  The <code>table</code> command creates a \n2-dimensional grid of cells. The table can use a Tcl array variable or Tcl\n\ncommand for data storage and retrieval. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2epurl%2eorg%2fnet%2fhobbs%2ftcl%2fcapp%2f\">Edit</a>\n <i><font size=\"-1\">(November 18, 1999 09:25)</font></i><dt><b><a href=\"http://ftp.austintx.net/users/jatucker/TkTextmatrix/default.htm\" =\"\">TkTextMatrix (spreadsheet)</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:jatucker@austin.dsccc.com\" =\"\">John Arthur Tucker</a></b>, Version <b>4.1</b>,\n\t\t\tWorks with <b>Tk 4.1</b>\n<br>Download: <a href=\"http://ftp.austintx.net/users/jatucker/TkTextmatrix/download.htm\">download.htm</a>, <a href=\"http://ftp.austintx.net/users/jatucker/TkTextmatrix/textmatrix4.1.tar.gz\">textmatrix4.1.tar.gz</a><br>A Tcl/Tk spreadsheet widget, TkTextmatrix, which is implemented in C++ and is\n             basically a Tk Canvas widget plus extra behavior for manipulating rows and columns of cell\n             items many times faster than with a plain Tk Canvas.  It actually inserts text nearly as fast\n             as the Tk Text widget.  If you work with or are interested in creating your own Tcl/Tk widgets\n             in C++,  you might want to take a look at the C++ widget library included with this\n             distribution. <a href=\"/live/annotate?url=http%3a%2f%2fftp%2eaustintx%2enet%2fusers%2fjatucker%2fTkTextmatrix%2fdefault%2ehtm\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:14)</font></i><dt><b><a href=\"http://www.cs.umd.edu/~bederson/Togl.html\" =\"\">ToGL - a Tk Open GL widget</a></b>\n<dd>Togl is a Tk widget for OpenGL rendering. Togl is based on OGLTK, originally written by Benjamin Bederson at the\nUniversity of New Mexico (who has since moved to the University of Maryland). Togl adds the new features: \n<ul>\n<li>     color-index mode support including color allocation functions \n<li>     support for requesting stencil, accumulation, alpha buffers, etc \n<li>     multiple OpenGL drawing widgets \n<li>     OpenGL extension testing from Tcl \n<li>     simple, portable font support \n<li>     overlay plane support \n</ul>\nTogl allows one to create and manage a special Tk/OpenGL widget with Tcl and render into it with a C program. That is,\na typical Togl program will have Tcl code for managing the user interface and a C program for computations and\nOpenGL rendering.  <a href=\"/live/annotate?url=http%3a%2f%2fwww%2ecs%2eumd%2eedu%2f%7ebederson%2fTogl%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:14)</font></i><dt><b><a href=\"http://www.hwaci.com/sw/tk/treepi.html\" =\"\">Tree Widget</a></b>\n<dd>This implements a tree display in a canvas widget.\nIt is similar in layout to that of the\nWindows explorer file viewer.  This is pure Tcl\ncode - not a C extension. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2ehwaci%2ecom%2fsw%2ftk%2ftreepi%2ehtml\">Edit</a>\n <i><font size=\"-1\">(September 29, 1999 14:37)</font></i><dt><b><a href=\"http://www.du.edu/~mschwart/tcl-tk.htm\" =\"\">Windows Extensions for Tcl/Tk (Michael Schwartz)</a></b>\n<dd>This site has pointers to several extensions specific to the\nWindows platform.  The extensions provide printing,\na MAPI interface to send email, and an interface to manipulate\n.INI files, among other things. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2edu%2eedu%2f%7emschwart%2ftcl%2dtk%2ehtm\">Edit</a>\n <i><font size=\"-1\">(October 07, 1999 10:50)</font></i><dt><b><a href=\"http://www.tcltk.com/iwidgets/\" =\"\">[incr Widgets] Home Page</a></b>\n<dd>[incr Widgets] is a set of megawidgets (combo boxes, etc.) that are\nupon the [incr Tcl] object system and the [incr Tk] megawidget\nframework.  This comes bundled with the\n<a href=\"http://www.tcltk.com/itcl/\">[incr Tcl]</a> distributions. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2etcltk%2ecom%2fiwidgets%2f\">Edit</a>\n <i><font size=\"-1\">(September 05, 1999 16:08)</font></i><dt><b><a href=\"http://www1.clearlight.com/~oakley/tcl/combobox/index.html\" =\"\">combobox</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:oakley@channelpoint.com\" =\"\">Bryan Oakley</a></b>, Version <b>1.03</b>,\n\t\t\tWorks with <b>8.x</b>\n<br>Download: <a href=\"http://www1.clearlight.com/~oakley/tcl/combobox/combobox.tcl\">combobox.tcl</a><br>combobox is a pure-tcl implementation of a combobox widget. It is\nentirely self contained and does not require any other OO or megawidget\nextension. It supports both editable and non-editable entries, and\nprovides the ability to call a procedure anytime the value of the combobox\nchanges. <a href=\"/live/annotate?url=http%3a%2f%2fwww1%2eclearlight%2ecom%2f%7eoakley%2ftcl%2fcombobox%2findex%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:15)</font></i><dt><b><a href=\"http://www.multimania.com/droche/rnotebook/index.html\" =\"\">Rnotebook</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:dan@lectra.com\" =\"\">Daniel Roche</a></b>, Version <b>1.0</b>,\n\t\t\tWorks with <b>8.0 or higher</b>\n<br>Download: <a href=\"http://www.multimania.com/droche/rnotebook/index.html\">index.html</a><br>This implements a resizeable notebook\nwidget in pure tcl/tk <a href=\"/live/annotate?url=http%3a%2f%2fwww%2emultimania%2ecom%2fdroche%2frnotebook%2findex%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 19, 1999 15:39)</font></i><dt><b><a href=\"http://www.tregar.com/samdi.html\" =\"\">saMDI v1.0a1 Multi-Document Interface Extension</a></b>\n<dd>A multi-document interface (MDI) extension for TCL/Tk 8.0.\nThis is a common interface format in Microsoft Windows that lets a parent window contain multiple child windows.\nIn effect you get a window manager inside a window!\nUses and includes the STOOOP object-oriented extension by\nJean-Luc Fontaine.\nsaMDI v1.0a1 GPL Copyright 1998 Sam Tregar. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2etregar%2ecom%2fsamdi%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:07)</font></i><dt><b><a href=\"http://tix.mne.com/htdocs/tix/index.html\" =\"\">Tix Support Site</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:tix@mne.com\" =\"\">Ioi Lam, (adopted by Gregg Squires)</a></b>, Version <b>4.1</b>,\n\t\t\tWorks with <b>Tcl 7.4 through Tcl 8.0</b>\n<br><a href=\"ftp://ftp.tix.mne.com/pub/tix/\">Download</a>, <a href=\"ftp://ftp.tix.mne.com/pub/tix/Tix4.1.0.006.tar.gz\">Tix4.1.0.006.tar.gz</a>, <a href=\"ftp://ftp.tix.mne.com/pub/tix/Tix41p6.zip\">Tix41p6.zip</a>, <a href=\"ftp://ftp.tix.mne.com/pub/tix/win41p6bin.zip\">win41p6bin.zip</a><br><b>Tix has found a new home!</b>\n <br>\n Tix provides over 40 new Tk including the\ncombo box, file selection dialogs, paned widget,\nnotebook, hierarchical list, directory tree, and more.\n  <a href=\"/live/annotate?url=http%3a%2f%2ftix%2emne%2ecom%2fhtdocs%2ftix%2findex%2ehtml\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:11)</font></i><dt><b><a href=\"ftp://ftp.archive.eso.org/pub/tree\" =\"\">Tk Tree Widget (C++)</a></b>\n<dd>Tk Tree widget for Tcl8.0.3.\n\nThis version contains (optional) support for \\[incr Tcl\\] and \\[incr Tk\\]\nversion 3.0.\n<br>\nWith the tree widget, you can display a tree in a Tk canvas. The nodes\ncan be made up of any number of canvas items or even other Tk widgets.\nYou create the objects that make up a node and the line that connects\nit to its parent and pass them to the tree widget. After this the tree\nwidget manages the positions of the nodes and end points of the tree\nlines.  Operations are available for inserting, moving and removing\nnodes and subtrees and for querrying the position of a node in the\ntree. The tree can be displayed horizontally or vertically.\n <a href=\"/live/annotate?url=ftp%3a%2f%2fftp%2earchive%2eeso%2eorg%2fpub%2ftree\">Edit</a>\n <i><font size=\"-1\">(August 25, 1999 03:14)</font></i><dt><b><a href=\"http://www.purl.org/net/hobbs/tcl/script/widget/\" =\"\">widget, simple megawidget package</a></b>\n<dd>\n\t\t\tAuthor <b><a href=\"mailto:jeffrey.hobbs@oen.siemens.de\" =\"\">Jeffrey Hobbs</a></b>, Version <b>0.9</b>,\n\t\t\tWorks with <b>Tcl/Tk 8.0 or higher</b>\n<br>Download: <a href=\"http://www.purl.org/net/hobbs/tcl/script/widget/widget-0.9.tar.gz\">widget-0.9.tar.gz</a><br>This is a package of\n megawidgets (i.e., compound widgets) that work almost exactly like Tk widgets.\n You can also build your own new megawidgets. \nIncludes: combobox, hierarchy, console, progressbar,\ntabnotebook, validating entry, pane geometry manager, baloon help. <a href=\"/live/annotate?url=http%3a%2f%2fwww%2epurl%2eorg%2fnet%2fhobbs%2ftcl%2fscript%2fwidget%2f\">Edit</a>\n <i><font size=\"-1\">(August 23, 1999 12:16)</font></i></dl>\n<hr><p><center><font size=\"-1\" face=\"Geneva, Helvetica, Arial\"><br><a href=\"#TOP\"><b>Top</b></a><br><!-- key ResourceSoftwareExtensions --><a href=\"/\">Home</a>\n | <a href=\"/products/\">Products</a>\n | <a href=\"/customers/\">Customers</a>\n | <a href=\"/partners/\">Partners</a>\n | <a href=\"/services/\">Services</a>\n | <a href=\"/resource/\">Tcl Resources</a>\n | <a href=\"/company/\">Company</a>\n<br><a href=\"/live/keyword\">Search</a>\n | <a href=\"/live/map\">Site Map</a>\n | <a href=\"/company/feedback.html?url=%2fresource%2fsoftware%2fextensions%2ftk%2f\">Feedback</a>\n | <a href=\"/company/contact.html\">Contact Us</a>\n | <a href=\"mailto:info@scriptics.com\">info@scriptics.com</a>\n\n <SCRIPT LANGUAGE=\"Javascript\">\n<!--\n         browser = (((navigator.appName == \"Netscape\") &&(parseInt(navigator.appVersion) >= 3 )) || ((navigator.appName ==\"Microsoft Internet Explorer\") && (parseInt(navigator.appVersion) >= 4 )))\n\n  if ( browser )\n   {\n        over = new MakeImageArray(10)\n        over[0].src = \"http://images.scriptics.com/images/ProductsMouseOff.gif\"\n        over[1].src = \"http://images.scriptics.com/images/CustomersMouseOff.gif\"\n        over[2].src = \"http://images.scriptics.com/images/PartnersMouseOff.gif\"\n        over[3].src = \"http://images.scriptics.com/images/ServicesMouseOff.gif\"\n        over[4].src = \"http://images.scriptics.com/images/ResourceMouseOff.gif\"\n        over[5].src = \"http://images.scriptics.com/images/CompanyMouseOff.gif\"\n        over[6].src = \"http://images.scriptics.com/images/homeMainRollover1.gif\"\n        over[7].src = \"http://images.scriptics.com/images/homeMainRollover2.gif\"\n        over[8].src = \"http://images.scriptics.com/images/homeMainRollover3.gif\"\n        over[9].src = \"http://images.scriptics.com/images/homeMainRollover3.gif\"\n\n  }\n  \n  function MakeImageArray(n)  {\n        this.length = n\n        for (var i = 0; i<=n; i++)=\"i++)\" {=\"{\" this[i]=\"this[i]\" =\"\" new=\"new\" Image()=\"Image()\" }=\"}\" return=\"return\" this=\"this\" }=\"}\" //=\"//\" --=\"--\">\n  </SCRIPT><br>\n    <font size=\"2\">\n    &copy; 1998-2000 Scriptics Corporation.  All rights reserved.\n    <a href=\"/legal_notice.html\">Legal Notice</a> | <A href=\"\" /privacy.html=\"/privacy.html\"> \n    Privacy Statement</a>\n    </td></tr></table></td></tr></table>\n</Body>\n</Html>"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/page3/index.html",
    "content": "<html><body bgcolor=\"white\">\n<hr>\n<h1 align=\"center\">Embedding Tcl in C/C++ Applications</h1>\n\n    <table width=\"100%\">\n    <tr><td valign=\"top\" align=\"left\" width=\"46%\">\n    <b>Presented At:</b>\n  <blockquote>\n     The&nbsp;Tcl2K&nbsp;Conference<br>\n     Austin, Texas<br>\n     <nobr>9:00am, February 15, 2000</nobr><br>\n  </blockquote>\n    </td>\n    <td width=\"5%\">&nbsp;</td>\n    <td valign=\"top\" align=\"left\" width=\"46%\">\n    <b>Instructor:</b>\n  <blockquote>\n     D. Richard Hipp<br>\n     drh@hwaci.com<br>\n     http://www.hwaci.com/drh/<br>\n     704.948.4565\n  </blockquote>\n    </td></tr>\n    </table><p>\n  <center><table border=\"2\">\n  <tr><td>\n  <p align=\"center\">\n  Copies of these notes, example source code,<br>and other\n  resources related to this tutorial<br>are available online at\n  <a href=\"http://www.hwaci.com/tcl2k/\">\n  http://www.hwaci.com/tcl2k/</a></p>\n  <p align=\"center\"><small>$Id$</small></p></td></tr>\n  </table>\n  </center>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Tutorial Outline</h2>\n<p><ul><li>Introduction</li>\n<li>Building It Yourself</li>\n<ul><li>\"Hello, World!\" using Tcl</li>\n<li>Tcl scripts as C strings</li>\n<li>Adding new Tcl commands</li>\n<li>A tour of the Tcl API</li>\n<li>Tcl initialization scripts</li>\n<li>Adding Tk</li>\n</ul><li>Tools Survey</li>\n<li>Mktclapp</li>\n<ul><li>\"Hello World\" using mktclapp</li>\n<li>Adding C code</li>\n<li>Other Features</li>\n<li>Invoking Tcl from C</li>\n<li>Running mktclapp directly</li>\n<li>Real-world examples</li>\n</ul><li>Summary</li>\n</ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Embedding Tcl in C/C++ Applications</h2>\n<p><ul><li>You know how to program in Tcl/Tk</li></ul><ul><li>You know how to program in C/C++</li></ul><ul><li>This tutorial is about how to do both at the same time.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Why Mix C With Tcl/Tk?</h2>\n<p><ul><li>Use C for the things C is good at and Tcl for the things\n  Tcl is good at.</li></ul><ul><li>Generate standalone executables.\n  <ul><li>Eliminate the need to install Tcl/Tk.</li>\n  <li>Prevent problems when the wrong version of Tcl/Tk is installed.</li>\n  </ul></li></ul><ul><li>Prevent end users from changing the source code.\n  <ul><li>Keeps users from creating new bugs.</li>\n  <li>Protects proprietary code.</li>\n  </ul></li></ul><ul><li>Office politics</li></ul><ul><li>Use Tcl/Tk as a portability layer for a large C program</li></ul><ul><li>Use Tcl as a testing interface</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Why Mix C With Tcl/Tk?</h2>\n<p><blockquote><big><b>\n  \"Use C for the things C is good at and use Tcl/Tk for the things\n  Tcl/Tk is good at.\"\n  </b></blockquote></p><p>\n\n    <table width=\"100%\">\n    <tr><td valign=\"top\" align=\"left\" width=\"46%\">\n    <b>C is good at:</b>\n  <ul>\n  <li>Speed</li>\n  <li>Complex data structures</li>\n  <li>Computation</li>\n  <li>Interacting with hardware</li>\n  <li>Byte-by-byte data analysis</li>\n  </ul>\n    </td>\n    <td width=\"5%\">&nbsp;</td>\n    <td valign=\"top\" align=\"left\" width=\"46%\">\n    <b>Tcl/Tk is good at:</b>\n  <ul>\n  <li>Building a user interface</li>\n  <li>Manipulation of strings</li>\n  <li>Portability</li>\n  <li>Opening sockets</li>\n  <li>Handling events</li>\n  </ul>\n    </td></tr>\n    </table>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Programming Models</h2>\n<table width=\"100%\">\n<tr><td valign=\"top\" width=\"49%\">\n\n  <p><b>Mainstream Tcl Programming Model:</b></p>\n</td>\n<td width=\"2%\">&nbsp;</td>\n<td valign=\"top\" width=\"49%\">\n\n  <p><b>Embedded Tcl Programming Model:&nbsp;&nbsp;</b></p>\n</td></tr>\n<tr><td valign=\"top\" width=\"49%\">\n\n  <ul><li>Add bits of C code to a large Tcl program</li></ul>\n</td>\n<td width=\"2%\">&nbsp;</td>\n<td valign=\"top\" width=\"49%\">\n\n  <ul><li>Add bits of Tcl code to a large C program</li></ul>\n</td></tr>\n<tr><td valign=\"top\" width=\"49%\">\n\n  <ul><li>Main Tcl script loads extensions written in C</li></ul>\n</td>\n<td width=\"2%\">&nbsp;</td>\n<td valign=\"top\" width=\"49%\">\n\n  <ul><li>Main C procedure invokes the Tcl interpreter</li></ul>\n</td></tr>\n<tr><td valign=\"top\" width=\"49%\">\n\n  <ul><li>Tcl/Tk is a programming language</li></ul>\n</td>\n<td width=\"2%\">&nbsp;</td>\n<td valign=\"top\" width=\"49%\">\n\n  <ul><li>Tcl/Tk is a C library</li></ul>\n</td></tr>\n<tr><td valign=\"top\" width=\"49%\">\n\n  <center><img src=\"image1\"><br>\n  Most of the Tcl2K conference is about</center>\n</td>\n<td width=\"2%\">&nbsp;</td>\n<td valign=\"top\" width=\"49%\">\n\n  <center><img src=\"image1\"><br>\n  This tutorial is about</center>\n</td></tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">\"Hello, World!\" Using The Tcl Library</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h></tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Always include &lt;tcl.h></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Create a new Tcl interpreter</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;\"puts&nbsp;{Hello,&nbsp;World!}\");</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Execute a Tcl command.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Compiling \"Hello, World!\"</h2>\n<p><p><b>Unix:</b></p>\n  <blockquote><tt>\n  $ gcc hello.c -ltcl -lm -ldl<br>\n  $ ./a.out<br>\n  Hello, World!</tt></blockquote>\n\n  <p><b>Windows using Cygwin:</b></p>\n  <blockquote><tt>\n  C:> gcc hello.c -ltcl80 -lm<br>\n  C:> a.exe<br>\n  Hello, World!</tt></blockquote>\n\n  <p><b>Windows using Mingw32:</b></p>\n  <blockquote><tt>\n  C:> gcc -mno-cygwin hello.c -ltcl82 -lm<br>\n  </tt></blockquote>\n<table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>Also works with VC++</b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Where Does <tt>-ltcl</tt> Come From On Unix?</h2>\n<p><p>Build it yourself using these steps:</p></p><p>\n<p><ul><li>Get tcl8.2.2.tar.gz from Scriptics</li></ul><ul><li><tt>zcat tcl8.2.2.tar.gz | tar vx </tt></li></ul><ul><li><tt>cd tcl8.2.2/unix</tt></li></ul><ul><li><tt>./configure --disable-shared</tt></li></ul><ul><li><tt>make</tt></li></ul><ul><li>Move <b>libtcl8.2.a</b> to your lib directory.</li></ul><ul><li>Copy <b>../generic/tcl.h</b> into /usr/include.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">What Other Libraries Are Required For Unix?</h2>\n<p><ul><li>The sequence of <b>-l</b> options after <b>-ltcl</b>\n  varies from system to system</li></ul><ul><li>Observe what libraries the TCL makefile inserts when\n  it is building <b>tclsh</b></li></ul><ul><li>Examples in this talk are for RedHat Linux 6.0 for Intel</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">How To Compile Under Unix Without Installing Tcl</h2>\n<p><p>Specify the *.a file directly:</p>\n  <blockquote><pre>\n  $ gcc -I../tcl8.2.2/generic hello.c \\ \n      ../tcl8.2.2/unix/libtcl8.2.a -lm -ldl\n  $ strip a.out\n  $ ./a.out\n  Hello, World!</pre></blockquote>\n\n  <p>Or, tell the C compiler where to look for *.a files:</p>\n  <blockquote><pre>\n  $ gcc -I../tcl8.2.2/generic hello.c \\ \n      -L../tcl8.2.2/unix -ltcl -lm -ldl\n  $ strip a.out\n  $ ./a.out\n  Hello, World!</pre></blockquote>\n<table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>The <tt>-I../tcl8.2.2</tt> argument\n  tells the compiler where to\n  find <tt>&lt;tcl.h&gt;</tt>.</p></b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">What's \"Cygwin\"?</h2>\n<p><ul><li>An implementation of GCC/G++ and all development tools\n  for Windows95/98/NT/2000</li></ul><ul><li>Available for free download at\n  <blockquote>\n  <tt>http://sourceware.cygnus.com/cygwin/</tt>\n  </blockquote></li></ul><ul><li>Also available shrink-wrapped at your local software retailer or\n  online at\n  <blockquote>\n  <tt>http://www.cygnus.com/cygwin/index.html</tt>\n  </blockquote></li></ul><ul><li>Programs compiled using Cygwin require a special\n  DLL (<b>cygwin1.dll</b>) that provides a POSIX system API</li></ul><ul><li>Cygwin1.dll cannot be shipped with proprietary programs\n  without purchasing a license from Cygnus.</li></ul><ul><li>Mingw32 is the same compiler as Cygwin, but generates\n  binaries that do not use cygwin1.dll</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Where Does <tt>-ltcl82</tt> Come From On Windows?</h2>\n<p><p>Build it like this:</p></p><p>\n<p><ul><li>Get <b>tcl82.lib</b> and <b>tcl82.dll</b> from Scriptics.</li></ul><ul><li><tt>echo EXPORTS >tcl82.def</tt></li></ul><ul><li><tt>nm tcl82.lib | grep 'T _' | sed 's/.* T _//' >>tcl82.def</tt></li></ul><ul><li><tt>dlltool --def tcl82.def --dllname tcl82.dll --output-lib libtcl82.a</tt></li></ul><ul><li>Move <b>libtcl82.a</b> to the lib directory and <b>tcl82.dll</b>\n  to the bin directory.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Where Does Your Code Go?</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;Your&nbsp;application&nbsp;code&nbsp;goes&nbsp;here&nbsp;*/</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Insert C code here to do whatever it is your program is\n  suppose to do</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Building A Simple TCLSH</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;char&nbsp;*z;<br>\n&nbsp;&nbsp;char&nbsp;zLine[2000];<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;while(&nbsp;fgets(zLine,sizeof(zLine),stdin)&nbsp;){</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Get one line of input</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zLine);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Execute the input as Tcl.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;z&nbsp;=&nbsp;Tcl_GetStringResult(interp);<br>\n&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;z[0]&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(\"P\u0004\bX\u0004\b\\n\",&nbsp;z);<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Print result if not empty</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>What if user types more than 2000 characters?</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Building A Simple TCLSH</h2>\n<p>Use TCL to handle input.  Allows input lines of unlimited length.</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\n/*&nbsp;Tcl&nbsp;code&nbsp;to&nbsp;implement&nbsp;the<br>\n**&nbsp;input&nbsp;loop&nbsp;*/<br>\nstatic&nbsp;char&nbsp;zLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;\"while&nbsp;{![eof&nbsp;stdin]}&nbsp;{\\n\"</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;\"&nbsp;&nbsp;set&nbsp;line&nbsp;[gets&nbsp;stdin]\\n\"</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Get one line of input</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;\"&nbsp;&nbsp;set&nbsp;result&nbsp;[eval&nbsp;$line]\\n\"</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Execute input as Tcl</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;\"&nbsp;&nbsp;if&nbsp;{$result!=\\\"\\\"}&nbsp;{puts&nbsp;$result}\\n\"</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Print result</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;\"}\\n\"<br>\n;<br>\n&nbsp;<br>\n<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zLoop);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Run the Tcl input loop</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>But what about commands that span multiple lines of input?</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Better Handling Of Command-Line Input</h2>\n<p>The file \"input.tcl\"</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>set&nbsp;line&nbsp;{}<br>\nwhile&nbsp;{![eof&nbsp;stdin]}&nbsp;{</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if&nbsp;{$line!=\"\"}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\">&nbsp;\"<br>\n&nbsp;&nbsp;}&nbsp;else&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\"%&nbsp;\"<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;flush&nbsp;stdout</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Prompt for user input.  The prompt is normally &quot;%&quot;\n  but changes to &quot;&gt;&quot; if the current line is a continuation.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;append&nbsp;line&nbsp;[gets&nbsp;stdin]<br>\n&nbsp;&nbsp;if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">If the command is complete, execute it.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;stderr&nbsp;\"Error:&nbsp;$result\"<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{$result!=\"\"}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;$result<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;line&nbsp;{}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;}&nbsp;else&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;line&nbsp;\\n<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">If the command is incomplete, append a newline and get\n  another line of text.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Better Handling Of Command-Line Input</h2>\n<p>The file \"input.c\"</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;\"source&nbsp;input.tcl\");</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Read and execute the input loop</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>But now the program is not standalone!</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Converting Scripts Into C Strings</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;\"set&nbsp;line&nbsp;{}\\n\"<br>\n&nbsp;&nbsp;\"while&nbsp;{![eof&nbsp;stdin]}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;if&nbsp;{$line!=\\\"\\\"}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\\\">&nbsp;\\\"\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;}&nbsp;else&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\\\"%&nbsp;\\\"\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;}\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;flush&nbsp;stdout\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;append&nbsp;line&nbsp;[gets&nbsp;stdin]\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;stderr&nbsp;\\\"Error:&nbsp;$result\\\"\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{$result!=\\\"\\\"}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;$result\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;}\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;line&nbsp;{}\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;}&nbsp;else&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;line&nbsp;\\\\n\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;}\\n\"<br>\n&nbsp;&nbsp;\"}\\n\"<br>\n;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Compile Tcl Scripts Into C Programs</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Actual&nbsp;code&nbsp;omitted&nbsp;*/<br>\n;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Copy and paste the converted Tcl script here</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Execute the Tcl code</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Converting Scripts To Strings<br>Using SED Or TCLSH</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>sed&nbsp;-e&nbsp;'s/\\\\/\\\\\\\\/g'&nbsp;\\&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Convert <b>\\</b> into <b>\\\\</b></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'s/\"/\\\\\"/g'&nbsp;\\&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Convert <b>\"</b> into <b>\\\"</b></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'s/^/&nbsp;&nbsp;\"/'&nbsp;\\&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Add <b>\"</b> to start of each line</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'s/$/\\\\n\"/'&nbsp;input.tcl</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Add <b>\\n\"</b> to end of each line</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\n&nbsp;<br>\n<br>\n&nbsp;<br>\n<br>\nwhile&nbsp;{![eof&nbsp;stdin]}&nbsp;{<br>\n&nbsp;&nbsp;set&nbsp;line&nbsp;[gets&nbsp;stdin]</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{\\}&nbsp;$line&nbsp;{&amp;&amp;}&nbsp;line</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Convert <b>\\</b> into <b>\\\\</b></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{\"}&nbsp;$line&nbsp;{\\\"}&nbsp;line</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Convert <b>\"</b> into <b>\\\"</b></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;puts&nbsp;\"\\\"$line\\\\n\\\"\"</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Add <b>\"</b> in front and <b>\\n\"</b> at the end</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Converting Scripts Into C Strings</h2>\n<p>You may want to save space by removing comments and extra whitespace\n  from scripts.</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;\"set&nbsp;line&nbsp;{}\\n\"<br>\n&nbsp;&nbsp;\"while&nbsp;{![eof&nbsp;stdin]}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"if&nbsp;{$line!=\\\"\\\"}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"puts&nbsp;-nonewline&nbsp;\\\">&nbsp;\\\"\\n\"<br>\n&nbsp;&nbsp;\"}&nbsp;else&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"puts&nbsp;-nonewline&nbsp;\\\"%&nbsp;\\\"\\n\"<br>\n&nbsp;&nbsp;\"}\\n\"<br>\n&nbsp;&nbsp;\"flush&nbsp;stdout\\n\"<br>\n&nbsp;&nbsp;\"append&nbsp;line&nbsp;[gets&nbsp;stdin]\\n\"<br>\n&nbsp;&nbsp;\"if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"if&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"puts&nbsp;stderr&nbsp;\\\"Error:&nbsp;$result\\\"\\n\"<br>\n&nbsp;&nbsp;\"}&nbsp;elseif&nbsp;{$result!=\\\"\\\"}&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"puts&nbsp;$result\\n\"<br>\n&nbsp;&nbsp;\"}\\n\"<br>\n&nbsp;&nbsp;\"set&nbsp;line&nbsp;{}\\n\"<br>\n&nbsp;&nbsp;\"}&nbsp;else&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"append&nbsp;line&nbsp;\\\\n\\n\"<br>\n&nbsp;&nbsp;\"}\\n\"<br>\n&nbsp;&nbsp;\"}\\n\"<br>\n;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Converting Scripts To Strings</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>sed&nbsp;-e&nbsp;'s/\\\\/\\\\\\\\/g'&nbsp;\\&nbsp;<br>\n&nbsp;&nbsp;-e&nbsp;'s/\"/\\\\\"/g'&nbsp;\\&nbsp;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'/^&nbsp;*#/d'&nbsp;\\&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Delete lines that begin with #</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'/^&nbsp;*$/d'&nbsp;\\&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Delete blank lines</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'s/^&nbsp;*/&nbsp;&nbsp;\"/'&nbsp;\\&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Delete leading spaces</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;-e&nbsp;'s/$/\\\\n\"/'&nbsp;input.tcl<br>\n&nbsp;<br>\n<br>\n&nbsp;<br>\n<br>\n&nbsp;<br>\nwhile&nbsp;{![eof&nbsp;stdin]}&nbsp;{<br>\n&nbsp;&nbsp;set&nbsp;line&nbsp;[gets&nbsp;stdin]</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;set&nbsp;line&nbsp;[string&nbsp;trimleft&nbsp;$line]</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Remove leading space</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if&nbsp;{$line==\"\"}&nbsp;continue</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Delete blank lines</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if&nbsp;{[string&nbsp;index&nbsp;$line&nbsp;0]==\"#\"}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;continue<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Delete lines starting with #</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{\\}&nbsp;$line&nbsp;{&amp;&amp;}&nbsp;line<br>\n&nbsp;&nbsp;regsub&nbsp;-all&nbsp;{\"}&nbsp;$line&nbsp;{\\\"}&nbsp;line<br>\n&nbsp;&nbsp;puts&nbsp;\"\\\"$line\\\\n\\\"\"<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Removing Comments Or Leading Space<br>Will Break Some Tcl Scripts!</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>image&nbsp;create&nbsp;bitmap&nbsp;smiley&nbsp;-data&nbsp;{</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>#define&nbsp;smile_width&nbsp;15<br>\n#define&nbsp;smile_height&nbsp;15</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">These lines begin with # but are not comment</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;unsigned&nbsp;char&nbsp;smile_bits[]&nbsp;=&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;0xc0,&nbsp;0x01,&nbsp;0x30,&nbsp;0x06,&nbsp;0x0c,&nbsp;0x18,<br>\n&nbsp;&nbsp;&nbsp;0x04,&nbsp;0x10,&nbsp;0x22,&nbsp;0x22,&nbsp;0x52,&nbsp;0x25,<br>\n&nbsp;&nbsp;&nbsp;0x01,&nbsp;0x40,&nbsp;0x01,&nbsp;0x40,&nbsp;0x01,&nbsp;0x40,<br>\n&nbsp;&nbsp;&nbsp;0x12,&nbsp;0x24,&nbsp;0xe2,&nbsp;0x23,&nbsp;0x04,&nbsp;0x10,<br>\n&nbsp;&nbsp;&nbsp;0x0c,&nbsp;0x18,&nbsp;0x30,&nbsp;0x06,&nbsp;0xc0,&nbsp;0x01};<br>\n}<br>\n&nbsp;<br>\n<br>\n&nbsp;<br>\ntext&nbsp;.t<br>\npack&nbsp;.t<br>\n.t&nbsp;insert&nbsp;end&nbsp;[string&nbsp;trim&nbsp;{</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>She&nbsp;walks&nbsp;in&nbsp;beauty,&nbsp;like&nbsp;the&nbsp;night<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Of&nbsp;cloudless&nbsp;climes&nbsp;and&nbsp;starry&nbsp;skies;<br>\nAnd&nbsp;all&nbsp;that's&nbsp;best&nbsp;of&nbsp;dark&nbsp;and&nbsp;bright<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Meet&nbsp;in&nbsp;her&nbsp;aspect&nbsp;and&nbsp;her&nbsp;eyes;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Indentation is deleted on lines 2\n  and 4</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}]&nbsp;<br>\n&nbsp;<br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>Problems like these are rare</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Adding A \"continue\" Command</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>set&nbsp;line&nbsp;{}<br>\nwhile&nbsp;{![eof&nbsp;stdin]}&nbsp;{<br>\n&nbsp;&nbsp;if&nbsp;{$line!=\"\"}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\">&nbsp;\"<br>\n&nbsp;&nbsp;}&nbsp;else&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;-nonewline&nbsp;\"%&nbsp;\"<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;flush&nbsp;stdout<br>\n&nbsp;&nbsp;append&nbsp;line&nbsp;[gets&nbsp;stdin]<br>\n&nbsp;&nbsp;if&nbsp;{[info&nbsp;complete&nbsp;$line]}&nbsp;{</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{[lindex&nbsp;$line&nbsp;0]==\"continue\"}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Break out of the loop if the command\n  is \"continue\"</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{[catch&nbsp;{uplevel&nbsp;#0&nbsp;$line}&nbsp;result]}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;stderr&nbsp;\"Error:&nbsp;$result\"<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;elseif&nbsp;{$result!=\"\"}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;$result<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;line&nbsp;{}<br>\n&nbsp;&nbsp;}&nbsp;else&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;line&nbsp;\\n<br>\n&nbsp;&nbsp;}<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Stop For Tcl Input At Various Points<br>In A C Program</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Tcl&nbsp;Input&nbsp;loop&nbsp;as&nbsp;a&nbsp;C&nbsp;string&nbsp;*/<br>\n;<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;Application&nbsp;C&nbsp;code&nbsp;*/</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Do some computation</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Stop for some Tcl input</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;More&nbsp;application&nbsp;C&nbsp;code&nbsp;*/</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Do more computation</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Stop for more Tcl input</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;Finish&nbsp;up&nbsp;the&nbsp;application&nbsp;*/</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Finish the computation</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Using Tcl For Testing</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Tcl&nbsp;Input&nbsp;loop&nbsp;as&nbsp;a&nbsp;C&nbsp;string&nbsp;*/<br>\n;<br>\n&nbsp;<br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n#ifdef&nbsp;TESTING<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Create interpreter only if TESTING\n is defined</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();<br>\n#endif<br>\n&nbsp;&nbsp;/*&nbsp;Application&nbsp;C&nbsp;code&nbsp;*/</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>#ifdef&nbsp;TESTING<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n#endif</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Accept command-line input only if TESTING\n  is defined</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;More&nbsp;application&nbsp;C&nbsp;code&nbsp;*/<br>\n#ifdef&nbsp;TESTING<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n#endif<br>\n&nbsp;&nbsp;/*&nbsp;Finish&nbsp;up&nbsp;the&nbsp;application&nbsp;*/<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Creating A New Tcl Command In C</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nint&nbsp;NewCmd(</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;void&nbsp;*clientData,<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp,<br>\n&nbsp;&nbsp;int&nbsp;argc,<br>\n&nbsp;&nbsp;char&nbsp;**argv</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">The Tcl command is implemented as\n  a C function with four arguments.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>){<br>\n&nbsp;&nbsp;printf(\"Hello,&nbsp;World!\\n\");</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Returns TCL_OK or TCL_ERROR</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}<br>\n&nbsp;<br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br>\n;<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_CreateCommand(interp,&nbsp;\"helloworld\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewCmd,&nbsp;0,&nbsp;0);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Tell the interpreter which C function to call when the\n  \"helloworld\" Tcl command is executed</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Linkage From Tcl To C</h2>\n<p><p align=\"center\"><img src=\"image4\"></p></p><p><ul><li>3rd parameter of Tcl_CreateCommand() is a pointer to the C subroutine\n that implements the command.</li></ul><ul><li>4th parameter to Tcl_CreateCommand() becomes the 1st parameter to \n the C routine whenever the Tcl command is executed.</li></ul><ul><li>1st parameter to Tcl_CreateCommand() must be a valid Tcl interpreter.\n The same pointer appears as the second parameter to the C routine\n whenever the Tcl command is executed.</li></ul></p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Linkage From Tcl To C</h2>\n<p><p align=\"center\"><img src=\"image5\"></p></p><p><ul><li>5th parameter of Tcl_CreateCommand() is a pointer to the C subroutine\n that is called when the Tcl command is deleted.</li></ul><ul><li>4th parameter to Tcl_CreateCommand() becomes the 1st parameter to \n the C routine.</li></ul></p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">When To Use A Delete Proc</h2>\n<p>Examples of where the delete proc is used in standard Tcl/Tk:</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>button&nbsp;.b&nbsp;-text&nbsp;Hello<br>\npack&nbsp;.b</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>rename&nbsp;.b&nbsp;{}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Deleting the <b>.b</b> command causes the button to be destroyed</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\n&nbsp;<br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>image&nbsp;create&nbsp;photo&nbsp;smiley&nbsp;\\&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;-file&nbsp;smiley.gif</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>rename&nbsp;smiley&nbsp;{}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Deleting the <b>smiley</b> command destroys the image and reclaims the\n  memory used to hold the image</td>\n</tr>\n</table>\n<p><ul><li>Always use a delete proc if the clientData is a pointer to\n  malloced memory or some other resource that needs freeing</li></ul><ul><li>Delete procs are never used in the Tcl core but are used\n  extensively in Tk</li></ul></p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Linkage From Tcl To C</h2>\n<p>The <tt>argc</tt> and <tt>argv</tt> parameters work just like in \n <tt>main()</tt></p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>helloworld&nbsp;one&nbsp;{two&nbsp;three}&nbsp;four</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><tt>argc = 4<br>\n  argv[0] = \"helloworld\"<br>\n  argv[1] = \"one\"<br>\n  argv[2] = \"two three\"<br>\n  argv[3] = \"four\"<br>\n  argv[4] = NULL</tt></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">A Short-Cut</h2>\n<p>In a program with many new Tcl commands implemented in C, it becomes\n  tedious to type the same four parameters over and over again.  So\n  we define a short-cut.</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#define&nbsp;TCLARGS&nbsp;\\&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;*clientData,&nbsp;\\&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;Tcl_Interp&nbsp;*interp,&nbsp;\\&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;argc,&nbsp;\\&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*argv</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Define TCLARGS once in a header file</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;<br>\n&nbsp;<br>\n&nbsp;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;NewCmd(TCLARGS){</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Use the TCLARGS macro to define new C functions\n  that implement Tcl commands.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;/*&nbsp;implementation...&nbsp;*/<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>For brevity, we will use the TCLARGS macro during the\n  rest of this talk.</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Returning A Value From C Back To Tcl</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;NewCmd(TCLARGS){</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Note that the C function returns an \"int\"</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Return value is TCL_OK or TCL_ERROR</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><ul><li>TCL_OK and TCL_ERROR are defined in &lt;tcl.h&gt;</li></ul><ul><li>Other valid return values TCL_RETURN, TCL_BREAK and TCL_CONTINUE\n  are rarely used</li></ul><ul><li>Common mistake: forgetting to return TCL_OK</li></ul></p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Returning A Value From C Back To Tcl</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;NewCmd(TCLARGS){</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_SetResult(interp,\"Hello!\",TCL_STATIC);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Set the result to \"Hello!\"</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><ul><li>Result should be the text of an error message if you \n  return TCL_ERROR.</li></ul><ul><li>3rd argument to Tcl_SetResult() can be TCL_STATIC,\n  TCL_DYNAMIC, TCL_VOLATILE, or a function pointer.</li></ul><ul><li>Also consider using Tcl_AppendResult().</li></ul><ul><li>Direct access to <tt>interp->result</tt> is deprecated.</li></ul><ul><li>See the man pages for details.</li></ul></p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The Tcl_Obj Interface</h2>\n<p><ul><li>A new way to write Tcl commands in C code</li></ul><ul><li>First introduced in Tcl8.0</li></ul><ul><li>Can be much faster, especially for lists or numeric values.</li></ul><ul><li>Able to handle arbitrary binary data.</li></ul><ul><li>More difficult to program.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The Tcl_Obj Interface</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;NewObjCmd(<br>\n&nbsp;&nbsp;void&nbsp;*clientData,<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp,<br>\n&nbsp;&nbsp;int&nbsp;objc,</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Obj&nbsp;*const*&nbsp;objv</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">4th parameter is an array Tcl_Objs, not an array of strings</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>){<br>\n&nbsp;&nbsp;/*&nbsp;Implementation...&nbsp;*/<br>\n&nbsp;&nbsp;return&nbsp;TCL_OK;<br>\n}<br>\n&nbsp;<br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br>\n;<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_CreateObjCommand(interp,&nbsp;\"newcmd\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewObjCmd,&nbsp;0,&nbsp;0);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Use a different function to register the command</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The Tcl_Obj Interface</h2>\n<p><ul><li>There are countless access methods for reading information from and\n  placing information in Tcl_Objs.  Always use the access methods.</li></ul><ul><li>Details provided at Lee Bernhard's talk this afternoon.</li></ul><ul><li>Definitely use Tcl_Objs if you are writing a new Tcl extension.</li></ul><ul><li>Tcl_Objs address some of the weaknesses of Tcl relative to C/C++.\n  <ul>\n  <li> Tcl_Objs are faster </li>\n  <li> Tcl_Objs work with binary data </li>\n  </ul>\n  But C/C++ is faster still and better for working with binary data.</li></ul><ul><li>When mixing C/C++ with Tcl/Tk the benefits of Tcl_Objs are\n  less important.  Using Tcl_Objs in this context may not be\n  worth the extra trouble.</li></ul><ul><li>This talk will focus on the string interface.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Nickel Tour Of The Tcl API</h2>\n<p><p><b>Memory allocation functions</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Alloc<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Free<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Realloc<br>\n</tt></small></td>\n</table></center><p><b>Functions useful in the implementation of new  Tcl commands</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_AppendElement<br>\n  Tcl_AppendResult<br>\n  Tcl_GetBoolean<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_GetDouble<br>\n  Tcl_GetInt<br>\n  Tcl_GetStringResult<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_ResetResult<br>\n  Tcl_SetResult<br>\n</tt></small></td>\n</table></center><p><b>Functions for controlling the Tcl interpreter</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_CreateCommand<br>\n  Tcl_CreateInterp<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_CreateObjCommand<br>\n  Tcl_DeleteCommand<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_DeleteInterp<br>\n  Tcl_Exit<br>\n</tt></small></td>\n</table></center></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Nickel Tour Of The Tcl API</h2>\n<p><p><b>I/O functions</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Close<br>\n  Tcl_Eof<br>\n  Tcl_Flush<br>\n  Tcl_GetChannel<br>\n  Tcl_GetChannelMode<br>\n  Tcl_GetChannelName<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Gets<br>\n  Tcl_OpenCommandChannel<br>\n  Tcl_OpenFileChannel<br>\n  Tcl_OpenTcpClient<br>\n  Tcl_OpenTcpServer<br>\n  Tcl_Read<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Seek<br>\n  Tcl_Tell<br>\n  Tcl_Ungets<br>\n  Tcl_Write<br>\n  Tcl_WriteChars<br>\n</tt></small></td>\n</table></center><p><b>Names and meanings of system error codes</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_ErrnoId<br>\n  Tcl_ErrnoMsg<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_GetErrno<br>\n  Tcl_SetErrno<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_SignalId<br>\n  Tcl_SignalMsg<br>\n</tt></small></td>\n</table></center></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Nickel Tour Of The Tcl API</h2>\n<p><p><b>General Operating System Calls</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Access<br>\n  Tcl_Chdir<br>\n  Tcl_GetCwd<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_GetHostName<br>\n  Tcl_GetNameOfExecutable<br>\n  Tcl_Sleep<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Stat<br>\n</tt></small></td>\n</table></center><p><b>String Manipulation And Comparison</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Concat<br>\n  Tcl_Merge<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_SplitList<br>\n  Tcl_StringCaseMatch<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_StringMatch<br>\n</tt></small></td>\n</table></center><p><b>Dynamically Resizable Strings</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"49%\" valign=\"top\"><small><tt>\n  Tcl_DStringAppend<br>\n  Tcl_DStringAppendElement<br>\n  Tcl_DStringEndSublist<br>\n  Tcl_DStringInit<br>\n  Tcl_DStringLength<br>\n</tt></small></td>\n<td width=\"49%\" valign=\"top\"><small><tt>\n  Tcl_DStringResult<br>\n  Tcl_DStringSetLength<br>\n  Tcl_DStringStartSublist<br>\n  Tcl_DStringValue<br>\n</tt></small></td>\n</table></center></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Nickel Tour Of The Tcl API</h2>\n<p><p><b>Event Handlers</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"49%\" valign=\"top\"><small><tt>\n  Tcl_CancelIdleCall<br>\n  Tcl_CreateChannelHandler<br>\n  Tcl_CreateTimerHandler<br>\n  Tcl_DeleteChannelHandler<br>\n</tt></small></td>\n<td width=\"49%\" valign=\"top\"><small><tt>\n  Tcl_DeleteTimerHandler<br>\n  Tcl_DoOneEvent<br>\n  Tcl_DoWhenIdle<br>\n</tt></small></td>\n</table></center><p><b>Functions For Reading And Writing Tcl Variables</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_GetVar<br>\n  Tcl_GetVar2<br>\n  Tcl_LinkVar<br>\n  Tcl_SetVar<br>\n  Tcl_SetVar2<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_TraceVar<br>\n  Tcl_TraceVar2<br>\n  Tcl_UnlinkVar<br>\n  Tcl_UnsetVar<br>\n  Tcl_UnsetVar2<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_UntraceVar<br>\n  Tcl_UntraceVar2<br>\n  Tcl_UpdateLinkedVar<br>\n</tt></small></td>\n</table></center><p><b>Functions For Executing Tcl Code</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_Eval<br>\n  Tcl_EvalFile<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_EvalObj<br>\n  Tcl_GlobalEval<br>\n</tt></small></td>\n<td width=\"32%\" valign=\"top\"><small><tt>\n  Tcl_GlobalEvalObj<br>\n  Tcl_VarEval<br>\n</tt></small></td>\n</table></center></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Nickel Tour Of The Tcl API</h2>\n<p><p><b>Functions For Dealing With Unicode</b></p>\n<center><table width=\"90%\"><tr>\n<td width=\"49%\" valign=\"top\"><small><tt>\n  Tcl_NumUtfChars<br>\n  Tcl_UniCharAtIndex<br>\n  Tcl_UniCharIsAlnum<br>\n  Tcl_UniCharIsAlpha<br>\n  Tcl_UniCharIsControl<br>\n  Tcl_UniCharIsDigit<br>\n  Tcl_UniCharIsGraph<br>\n  Tcl_UniCharIsLower<br>\n  Tcl_UniCharIsPrint<br>\n  Tcl_UniCharIsPunct<br>\n  Tcl_UniCharIsSpace<br>\n  Tcl_UniCharIsUpper<br>\n  Tcl_UniCharIsWordChar<br>\n  Tcl_UniCharLen<br>\n  Tcl_UniCharNcmp<br>\n  Tcl_UniCharToLower<br>\n  Tcl_UniCharToTitle<br>\n</tt></small></td>\n<td width=\"49%\" valign=\"top\"><small><tt>\n  Tcl_UniCharToUpper<br>\n  Tcl_UniCharToUtf<br>\n  Tcl_UniCharToUtfDString<br>\n  Tcl_UtfAtIndex<br>\n  Tcl_UtfBackslash<br>\n  Tcl_UtfCharComplete<br>\n  Tcl_UtfFindFirst<br>\n  Tcl_UtfFindLast<br>\n  Tcl_UtfNcasecmp<br>\n  Tcl_UtfNcmp<br>\n  Tcl_UtfNext<br>\n  Tcl_UtfPrev<br>\n  Tcl_UtfToLower<br>\n  Tcl_UtfToTitle<br>\n  Tcl_UtfToUniChar<br>\n  Tcl_UtfToUniCharDString<br>\n  Tcl_UtfToUpper<br>\n</tt></small></td>\n</table></center>\n  <p><b>Functions For Dealing With Tcl_Objs</b></p>\n  <blockquote><i>Too numerous to list...</i></blockquote></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Documentation Of The Tcl API</h2>\n<p><ul><li>Tcl comes with excellent man pages</li></ul><ul><li>\"Use the source, Luke\"</li></ul><ul><li>See <tt>tclDecl.h</tt> for a list of API functions</li></ul><ul><li>The header comments on the implementation of API functions usually\n  gives a good description of what the function does and how it should\n  be used.</li></ul><ul><li>Most API functions are used within Tcl and Tk.  Use grep to locate\n  examples.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Initialization Scripts</h2>\n<p><ul><li>Run the mini TCLSH implemented above and execute the <tt>parray</tt> command</li></ul><ul><li>It doesn't work!  What's wrong? </p></li></li></ul><ul><li><tt>parray</tt> is really a Tcl proc that is read in when the\n interpreter is initialized. </p></li></li></ul><ul><li><tt>parray</tt> (and several other commands) are stored in a\n  handful of &quot;Initialization Scripts&quot; </p></li></li></ul><ul><li>All the initialization scripts are stored in the \n &quot;Tcl Library&quot; - a directory on the host\n computer. </p></li></li></ul><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>Invoke the Tcl_Init() function to locate and read the\n Tcl initialization scripts.</b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>Tcl_Init()</tt> Function</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br>\n;<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Init(interp);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Locate and read the initialization scripts</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;Call&nbsp;Tcl_CreateCommand()?&nbsp;*/<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>But Tcl_Init() can fail. We need to check its return value...</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>Tcl_Init()</tt> Function</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nstatic&nbsp;char&nbsp;zInputLoop[]&nbsp;=&nbsp;<br>\n&nbsp;&nbsp;/*&nbsp;Tcl&nbsp;code&nbsp;omitted...&nbsp;*/<br>\n;<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_Init(interp)!=TCL_OK&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,\"Tcl_Init()&nbsp;failed:&nbsp;P\u0004\bX\u0004\b\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tcl_GetStringResult(interp));<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Print error message if Tcl_Init() fails</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;Call&nbsp;Tcl_CreateCommand()?&nbsp;*/<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>But now the program is not standalone.</b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">How <tt>Tcl_Init()</tt> Works</h2>\n<p><ul><li>Computes the value of variable <tt>tcl_libPath</tt>.</li></ul><ul><li>Invokes the procedure named &quot;<tt>tclInit</tt>&quot;</li></ul><ul><li>A default <tt>tclInit</tt> procedure is built into Tcl.\n  You can define an alternative <tt>tclInit</tt> procedure\n  prior to calling <tt>Tcl_Init()</tt>.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The Default <tt>initTcl</tt> Procedure</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>set&nbsp;errors&nbsp;{}<br>\nset&nbsp;dirs&nbsp;{}<br>\nif&nbsp;{[info&nbsp;exists&nbsp;tcl_library]}&nbsp;{<br>\n&nbsp;&nbsp;lappend&nbsp;dirs&nbsp;$tcl_library<br>\n}&nbsp;else&nbsp;{<br>\n&nbsp;&nbsp;if&nbsp;{[info&nbsp;exists&nbsp;env(TCL_LIBRARY)]}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;lappend&nbsp;dirs&nbsp;$env(TCL_LIBRARY)<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;lappend&nbsp;dirs&nbsp;$tclDefaultLibrary<br>\n&nbsp;&nbsp;unset&nbsp;tclDefaultLibrary<br>\n&nbsp;&nbsp;set&nbsp;dirs&nbsp;[concat&nbsp;$dirs&nbsp;$tcl_libPath]<br>\n}<br>\nforeach&nbsp;i&nbsp;$dirs&nbsp;{<br>\n&nbsp;&nbsp;set&nbsp;tcl_library&nbsp;$i<br>\n&nbsp;&nbsp;set&nbsp;tclfile&nbsp;[file&nbsp;join&nbsp;$i&nbsp;init.tcl]<br>\n&nbsp;&nbsp;if&nbsp;{[file&nbsp;exists&nbsp;$tclfile]}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;{![catch&nbsp;{uplevel&nbsp;#0&nbsp;[list&nbsp;source&nbsp;$tclfile]}&nbsp;msg]}&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;append&nbsp;errors&nbsp;\"$tclfile:&nbsp;$msg\\n$errorInfo\\n\"<br>\n&nbsp;&nbsp;&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;}<br>\n}<br>\nerror&nbsp;\"Can't&nbsp;find&nbsp;a&nbsp;usable&nbsp;init.tcl&nbsp;...\"</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The Default Initialization Sequence</h2>\n<p><ul><li>The <tt>tclInit</tt> procedure locates and sources the <tt>init.tcl</tt>\n  script.  The directory that contains <tt>init.tcl</tt> is stored in\n  the <tt>tcl_library</tt> variable.</li></ul><ul><li>The <tt>init.tcl</tt> script creates an <tt>unknown</tt> procedure.\n  The <tt>unknown</tt> procedure will run whenever Tcl encounters an\n  unknown command.</li></ul><ul><li>The <tt>unknown</tt> procedure consults the file <tt>tclIndex</tt> in the\n  <tt>tcl_library</tt> directory to see if the command is defined by one of\n  the initialization scripts.</li></ul><ul><li>The <tt>unknown</tt> procedure sources any needed initialization scripts\n  and retries the command.</li></ul><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>Commands defined in the initialization scripts are loaded\n  on demand.</b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Standalone Initialization Techniques</h2>\n<p><p><b>Manually execute all initialization scripts</b></p>\n<ul><li>Convert all initialization scripts into C strings and\n  put them in the executable.</li></ul><ul><li>Call <tt>Tcl_Eval()</tt> on each initialization script and omit the\n  call to <tt>Tcl_Init()</tt></li></ul><ul><li>Or, redefine <tt>tclInit</tt> so that it does not attempt to source\n  <tt>init.tcl</tt> then call <tt>Tcl_Eval()</tt> on each initialization\n  script after <tt>Tcl_Init()</tt> returns.</li></ul><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>This approach is not recommended</b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Standalone Initialization Techniques</h2>\n<p><p><b>Redefining the builtin <tt>source</tt> command</b></p>\n<ul><li>Convert all initialization scripts into C strings and\n  put them in the executable.</li></ul><ul><li>Create a new <tt>source</tt> command that\n  calls <tt>Tcl_Eval()</tt> on the appropriate built-in string\n  instead of reading from the disk.</li></ul><ul><li>Read from disk if the named file is not one that is built in.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Redefining <tt>source</tt></h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;char&nbsp;zInitTcl[]&nbsp;=&nbsp;\"...\";<br>\nstatic&nbsp;char&nbsp;zParrayTcl[]&nbsp;=&nbsp;\"...\";</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Scripts <tt>init.tcl</tt> and <tt>parray.tcl</tt></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\nint&nbsp;NewSourceCmd(TCLARGS){</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;!strcmp(argv[1],\"/builtin/init.tcl\")&nbsp;)<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Tcl_Eval(interp,&nbsp;zInitTcl);<br>\n&nbsp;&nbsp;if(&nbsp;!strcmp(argv[1],\"/builtin/parray.tcl\")&nbsp;)<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Tcl_Eval(interp,&nbsp;zParrayTcl);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Call <tt>Tcl_Eval()</tt> on builtin strings if the names match</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;Tcl_EvalFile(interp,&nbsp;argv[1]);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Call <tt>Tcl_EvalFile()</tt> if no match</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;setenv(\"TCL_LIBRARY\",\"/builtin\");</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Causes <tt>tclInit</tt> to look for <tt>init.tcl</tt> in <tt>/builtin</tt></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_CreateCommand(interp,&nbsp;\"source\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NewSourceCmd,&nbsp;0,&nbsp;0);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Redefine <tt>source</tt></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Init(interp);<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Redefining <tt>source</tt></h2>\n<p><ul><li>This approach works for all versions of Tcl and Tk.</li></ul><ul><li>Also need to redefine the \"<tt>file exists</tt>\" Tcl command since it\n  too is used by <tt>tclInit</tt>.</li></ul><ul><li>To verify that the program is really standalone, remove the call\n  to <tt>Tcl_EvalFile()</tt>.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Standalone Initialization Techniques</h2>\n<p><p><b>Use the <tt>Tcl</tt>*<tt>InsertProc()</tt> functions</b></p>\n<ul><li>Three routines that overload basic file I/O operations:\n  <ul>\n  <li> <tt>TclStatInsertProc()</tt> </li>\n  <li> <tt>TclAccessInsertProc()</tt> </li>\n  <li> <tt>TclOpenFileChannelInsertProc()</tt> </li>\n  </ul></li></ul><ul><li>Allows us to implement a virtual filesystem that overlays the\n  real filesystem.</li></ul><ul><li>The virtual filesystem contains all the initialization scripts\n  as compiled-in strings.  The initialization scripts look like\n  they are resident on disk even though they are built in.</li></ul><ul><li>These functions first appeared in Tcl8.0.3.  \n  Presumably to support TclPro Wrapper.</li></ul><ul><li>The only documentation is comments on the code. \n  See the Tcl source file <tt>generic/tclIOUtil.c</tt></li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>TclStatInsertProc()</tt> Function</h2>\n<p><ul><li>Sole argument is a pointer to a function whose interface is the\n  same as <tt>stat()</tt></li></ul><ul><li>Functions are stacked. Tcl tries each <tt>stat</tt> function on the\n  list, beginning with the most recently inserted, until one succeeds.</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>TclStatInsertProc()</tt> Function</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tclInt.h></tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Rather than <tt>&lt;tcl.h&gt;</tt>!</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\nstatic&nbsp;int<br>\nBltinFileStat(char&nbsp;*path,struct&nbsp;stat&nbsp;*buf){<br>\n&nbsp;&nbsp;char&nbsp;*zData;<br>\n&nbsp;&nbsp;int&nbsp;nData;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;zData&nbsp;=&nbsp;FindBuiltinFile(path,&nbsp;0,&nbsp;&amp;nData);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Check if <tt>path</tt> is a builtin</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;zData==0&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Fail if <tt>path</tt> is not a builtin</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;memset(buf,&nbsp;0,&nbsp;sizeof(*buf));<br>\n&nbsp;&nbsp;buf->st_mode&nbsp;=&nbsp;0400;<br>\n&nbsp;&nbsp;buf->st_size&nbsp;=&nbsp;nData;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Success if it is builtin</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;TclStatInsertProc(BltinFileStat);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Register new <tt>stat</tt> function</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();<br>\n&nbsp;&nbsp;Tcl_Init(interp);<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>TclAccessInsertProc()</tt> Function</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tclInt.h></tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Rather than <tt>&lt;tcl.h&gt;</tt>!</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\n/*&nbsp;BltinFileStat()&nbsp;not&nbsp;shown...&nbsp;*/<br>\n&nbsp;<br>\nstatic&nbsp;int<br>\nBltinFileAccess(char&nbsp;*path,&nbsp;int&nbsp;mode){<br>\n&nbsp;&nbsp;char&nbsp;*zData;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;mode&nbsp;&amp;&nbsp;3&nbsp;)&nbsp;return&nbsp;-1;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">All builtins are read-only</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;zData&nbsp;=&nbsp;FindBuiltinFile(path,&nbsp;0,&nbsp;&amp;nData);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Check if <tt>path</tt> is a builtin</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;zData==0&nbsp;)&nbsp;return&nbsp;-1;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Fail if <tt>path</tt> is not a builtin</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;0;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Success if it is builtin</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;TclStatInsertProc(BltinFileStat);<br>\n&nbsp;&nbsp;TclAccessInsertProc(BltinFileAccess);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Register new <tt>stat</tt> and <tt>access</tt> functions</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();<br>\n&nbsp;&nbsp;Tcl_Init(interp);<br>\n&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zInputLoop);<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>TclOpenFileChannelInsertProc()</tt> Function</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;Tcl_Channel&nbsp;BuiltinFileOpen(<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp,&nbsp;&nbsp;&nbsp;/*&nbsp;The&nbsp;TCL&nbsp;interpreter&nbsp;doing&nbsp;the&nbsp;open&nbsp;*/<br>\n&nbsp;&nbsp;char&nbsp;*zFilename,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Name&nbsp;of&nbsp;the&nbsp;file&nbsp;to&nbsp;open&nbsp;*/<br>\n&nbsp;&nbsp;char&nbsp;*modeString,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Mode&nbsp;string&nbsp;for&nbsp;the&nbsp;open&nbsp;(ignored)&nbsp;*/<br>\n&nbsp;&nbsp;int&nbsp;permissions&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Permissions&nbsp;for&nbsp;a&nbsp;newly&nbsp;created&nbsp;file&nbsp;(ignored)&nbsp;*/<br>\n){<br>\n&nbsp;&nbsp;char&nbsp;*zData;<br>\n&nbsp;&nbsp;BuiltinFileStruct&nbsp;*p;<br>\n&nbsp;&nbsp;int&nbsp;nData;<br>\n&nbsp;&nbsp;char&nbsp;zName[50];<br>\n&nbsp;&nbsp;Tcl_Channel&nbsp;chan;<br>\n&nbsp;&nbsp;static&nbsp;int&nbsp;count&nbsp;=&nbsp;1;<br>\n&nbsp;<br>\n&nbsp;&nbsp;zData&nbsp;=&nbsp;FindBuiltinFile(zFilename,&nbsp;1,&nbsp;&amp;nData);<br>\n&nbsp;&nbsp;if(&nbsp;zData==0&nbsp;)&nbsp;return&nbsp;NULL;<br>\n&nbsp;&nbsp;p&nbsp;=&nbsp;(BuiltinFileStruct*)Tcl_Alloc(&nbsp;sizeof(BuiltinFileStruct)&nbsp;);<br>\n&nbsp;&nbsp;if(&nbsp;p==0&nbsp;)&nbsp;return&nbsp;NULL;<br>\n&nbsp;&nbsp;p->zData&nbsp;=&nbsp;zData;<br>\n&nbsp;&nbsp;p->nData&nbsp;=&nbsp;nData;<br>\n&nbsp;&nbsp;p->cursor&nbsp;=&nbsp;0;<br>\n&nbsp;&nbsp;sprintf(zName,\"etbi_bffffc7c_8049b04\",((int)BuiltinFileOpen)>>12,count++);<br>\n&nbsp;&nbsp;chan&nbsp;=&nbsp;Tcl_CreateChannel(&amp;builtinChannelType,&nbsp;zName,&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ClientData)p,&nbsp;TCL_READABLE);<br>\n&nbsp;&nbsp;return&nbsp;chan;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">The <tt>TclOpenFileChannelInsertProc()</tt> Function</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;Tcl_ChannelType&nbsp;builtinChannelType&nbsp;=&nbsp;{<br>\n&nbsp;&nbsp;\"builtin\",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Type&nbsp;name.&nbsp;*/<br>\n&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Always&nbsp;non-blocking.*/<br>\n&nbsp;&nbsp;BuiltinFileClose,&nbsp;&nbsp;&nbsp;/*&nbsp;Close&nbsp;proc.&nbsp;*/<br>\n&nbsp;&nbsp;BuiltinFileInput,&nbsp;&nbsp;&nbsp;/*&nbsp;Input&nbsp;proc.&nbsp;*/<br>\n&nbsp;&nbsp;BuiltinFileOutput,&nbsp;&nbsp;/*&nbsp;Output&nbsp;proc.&nbsp;*/<br>\n&nbsp;&nbsp;BuiltinFileSeek,&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Seek&nbsp;proc.&nbsp;*/<br>\n&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Set&nbsp;option&nbsp;proc.&nbsp;*/<br>\n&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Get&nbsp;option&nbsp;proc.&nbsp;*/<br>\n&nbsp;&nbsp;BuiltinFileWatch,&nbsp;&nbsp;&nbsp;/*&nbsp;Watch&nbsp;for&nbsp;events&nbsp;on&nbsp;console.&nbsp;*/<br>\n&nbsp;&nbsp;BuiltinFileHandle,&nbsp;&nbsp;/*&nbsp;Get&nbsp;a&nbsp;handle&nbsp;from&nbsp;the&nbsp;device.&nbsp;*/<br>\n};</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p>\n  <p>For additional information see:</p>\n  <ul>\n  <li>The man page for <tt>Tcl_CreateChannel()</tt></li>\n  <li>Tk source code file <tt>generic/tkConsole.c</tt></li>\n  </ul>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Initializing Tk</h2>\n<p><ul><li>All the same initialization script issues as Tcl</li></ul><ul><li>Tk initialization scripts are in a different directory\n  than the Tcl initialization scripts - the \"Tk Library\"</li></ul><ul><li>Call <tt>Tk_Init()</tt> after <tt>Tcl_Init()</tt></li></ul><ul><li>Must have an event loop or Tk will not work!</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Implementing An Event Loop</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>button&nbsp;.b&nbsp;-text&nbsp;Hello&nbsp;-command&nbsp;exit<br>\npack&nbsp;.b</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Create a Tk interface</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>bind&nbsp;.&nbsp;&lt;Destroy>&nbsp;{<br>\n&nbsp;&nbsp;if&nbsp;{![winfo&nbsp;exists&nbsp;.]}&nbsp;exit<br>\n}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Close the application when the main window\n  is destroyed</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>while&nbsp;1&nbsp;{vwait&nbsp;forever}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">The event loop</td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">\"Hello, World!\" Using Tk</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tk.h><br>\n&nbsp;<br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;char&nbsp;zHello[]&nbsp;=&nbsp;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">The application code</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;\"button&nbsp;.b&nbsp;\"<br>\n&nbsp;&nbsp;&nbsp;&nbsp;\"-text&nbsp;{Hello,&nbsp;World}&nbsp;\"<br>\n&nbsp;&nbsp;&nbsp;&nbsp;\"-command&nbsp;exit\\n\"<br>\n&nbsp;&nbsp;\"pack&nbsp;.b\\n\";<br>\n&nbsp;<br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>static&nbsp;char&nbsp;zEventLoop[]&nbsp;=</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">The event loop</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;\"bind&nbsp;.&nbsp;&lt;Destroy>&nbsp;{\\n\"<br>\n&nbsp;&nbsp;\"&nbsp;&nbsp;if&nbsp;{![winfo&nbsp;exists&nbsp;.]}&nbsp;exit\\n\"<br>\n&nbsp;&nbsp;\"}\\n\"<br>\n&nbsp;&nbsp;\"while&nbsp;1&nbsp;{vwait&nbsp;forever}\\n\";<br>\n&nbsp;<br>\n<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;Tcl_Interp&nbsp;*interp;<br>\n&nbsp;&nbsp;interp&nbsp;=&nbsp;Tcl_CreateInterp();</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Init(interp);<br>\n&nbsp;&nbsp;Tk_Init(interp);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">We really should check the return values of the init functions...</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zHello);</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_Eval(interp,&nbsp;zEventLoop);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">The event loop never returns</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*NOTREACHED*/<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Compiling \"Hello, World!\" For Tk</h2>\n<p><p><b>Unix:</b></p>\n  <blockquote><pre>\n  $ gcc hello.c -ltk -L/usr/X11R6/lib \\ \n        -lX11 -ltcl -lm -ldl\n  $ ./a.out</pre></blockquote>\n\n  <p><b>Windows using Cygwin:</b></p>\n  <blockquote><pre>\n  C:> gcc hello.c -mwindows -ltk80 -ltcl80 -lm\n  C:> a.exe</pre></blockquote>\n\n  <p><b>Windows using Mingw32:</b></p>\n  <blockquote><pre>\n  C:> gcc -mno-cygwin hello.c -mwindows \\ \n           -ltk82 -ltcl82 -lm\n  C:> a.exe</pre></blockquote></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Making The Program Standalone</h2>\n<p><p>To make a Tcl application standalone you have to convert the following\n     initialization scripts to C strings and compile them into the\n     executable:</p>\n  <table><tr>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;auto.tcl<br>\n    &nbsp;&nbsp;history.tcl<br>\n    &nbsp;&nbsp;init.tcl\n  </tt></td>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;ldAout.tcl<br>\n    &nbsp;&nbsp;package.tcl\n  </tt></td>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;parray.tcl<br>\n    &nbsp;&nbsp;safe.tcl\n  </tt></td>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;tclIndex<br>\n    &nbsp;&nbsp;word.tcl\n  </tt></td>\n  </tr></table>\n\n  <p>To make a Tk application standalone requires these additional\n     initialization scripts from the Tk Library:</p>\n  <table><tr>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;bgerror.tcl<br>\n    &nbsp;&nbsp;button.tcl<br>\n    &nbsp;&nbsp;clrpick.tcl<br>\n    &nbsp;&nbsp;comdlg.tcl<br>\n    &nbsp;&nbsp;console.tcl<br>\n    &nbsp;&nbsp;dialog.tcl\n  </tt></td>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;entry.tcl<br>\n    &nbsp;&nbsp;focus.tcl<br>\n    &nbsp;&nbsp;listbox.tcl<br>\n    &nbsp;&nbsp;menu.tcl<br>\n    &nbsp;&nbsp;msgbox.tcl<br>\n    &nbsp;&nbsp;optMenu.tcl\n  </tt></td>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;palette.tcl<br>\n    &nbsp;&nbsp;safetk.tcl<br>\n    &nbsp;&nbsp;scale.tcl<br>\n    &nbsp;&nbsp;scrlbar.tcl<br>\n    &nbsp;&nbsp;tclIndex<br>\n    &nbsp;&nbsp;tearoff.tcl\n  </tt></td>\n  <td valign=\"top\"><tt>\n    &nbsp;&nbsp;text.tcl<br>\n    &nbsp;&nbsp;tk.tcl<br>\n    &nbsp;&nbsp;tkfbox.tcl<br>\n    &nbsp;&nbsp;xmfbox.tcl\n  </tt></td>\n  </tr></table>\n\n  <p>Total of about 13K lines and 400K bytes of text or 9K lines and\n     250K bytes if you strip comments and leading spaces</p></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">A Review Of The Features We Want</h2>\n<p><ol type=\"A\">\n  <li value=\"1\">\n  Combine C/C++ with Tcl/Tk into a single executable.</dd>\n  </li></ol>\n\n  <ol type=\"A\">\n  <li value=\"2\">\n  The executable should be standalone.  It must not depend\n  on files not normally found on the system.\n  </li></ol>\n\n  <ol type=\"A\">\n  <li value=\"3\">\n  It should be difficult for end users to alter the program\n  (and introduce bugs).\n  </li></ol></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Available Programming Aids</h2>\n<p><p>Several tools are available.  The chart below shows which tools\n help achieve which objectives.</p>\n\n <center><table border=\"2\">\n <tr>\n   <td></td>\n   <td colspan=\"3\" align=\"center\">\n      <b>Features The Tool Helps To Achieve</b></td>\n </tr>\n <tr>\n   <td align=\"center\"><b>Tool Name</b></td>\n   <td align=\"center\">Mix C and Tcl</td>\n   <td align=\"center\">Standalone</td>\n   <td align=\"center\">Hide Source</td>\n </tr>\n <tr>\n   <td>SWIG</td>\n   <td align=\"center\"><img src=\"image6\"></td>\n   <td>&nbsp;</td>\n   <td>&nbsp;</td>\n </tr>\n <tr>\n   <td>TclPro Wrapper</td>\n   <td>&nbsp;</td>\n   <td align=\"center\"><img src=\"image6\"></td>\n   <td align=\"center\"><img src=\"image6\"></td>\n </tr>\n <tr>\n   <td>FreeWrap</td>\n   <td>&nbsp;</td>\n   <td align=\"center\"><img src=\"image6\"></td>\n   <td align=\"center\"><img src=\"image6\"></td>\n </tr>\n <tr>\n   <td>Wrap</td>\n   <td>&nbsp;</td>\n   <td align=\"center\"><img src=\"image6\"></td>\n   <td>&nbsp;</td>\n </tr>\n <tr>\n   <td>mktclapp</td>\n   <td align=\"center\"><img src=\"image6\"></td>\n   <td align=\"center\"><img src=\"image6\"></td>\n   <td align=\"center\"><img src=\"image6\"></td>\n </tr>\n </table></center></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">SWIG</h2>\n<table><tr><td valign=\"top\"><img src=\"image7\"></td>\n<td valign=\"top\"><p><ul><li>Creates an interface between an existing C/C++ library and a high-level\n  programming language.  Support for:\n  <ul>\n  <li> Tcl/Tk </li>\n  <li> Perl </li>\n  <li> Python </li>\n  <li> Java </li>\n  <li> Eiffel </li>\n  <li> Guile </li>\n  </ul></li></ul><ul><li>No changes required to C/C++ code.  Can be used with legacy libraries.</li></ul><ul><li>Generates an extension, not a standalone binary</li></ul><ul><li>The tutorial on SWIG was yesterday afternoon.</li></ul><ul><li>http://www.swig.org/</li></ul></p></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Wrapper Programs</h2>\n<table><tr><td valign=\"top\"><img src=\"image8\"></td>\n<td valign=\"top\"><p><ul><li>Convert a pure Tcl/Tk program into a standalone binary</li></ul><ul><li>Several wrapper programs are available:\n  <ul>\n  <li> TclPro Wrapper - http://www.scriptics.com/ </li>\n  <li> FreeWrap - http://www.albany.net/~dlabelle/freewrap/freewrap.html </li>\n  <li> Wrap - http://members1.chello.nl/~j.nijtmans/wrap.html </li>\n  </ul></li></ul><ul><li>No C compiler required!</li></ul><ul><li>TclPro will convert Tcl script into bytecode so that it cannot be\n  easily read by the end user.  FreeWrap encrypts the scripts.</li></ul><ul><li>FreeWrap uses compression on its executable. \n  Wrap uses compression on both the executable and on the bundled script files.</li></ul><ul><li>Usually include extensions like winico and/or BLT</li></ul></p></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">mktclapp</h2>\n<table><tr><td valign=\"top\"><img src=\"image9\"></td>\n<td valign=\"top\"><p><ul><li>Mix C/C++ with Tcl/Tk into a standalone binary</li></ul>\n<ul><li><tt>mktclapp</tt> generates an application initialization file\n  that contains Tcl scripts as strings and makes all necessary calls \n  to <tt>Tcl_Init</tt>, <tt>Tcl_CreateCommand</tt>, \n  <tt>Tcl</tt>*<tt>InsertProc</tt>, etc.</li></ul><ul><li>Features to make it easier to write new Tcl command in C</li></ul><ul><li><tt>xmktclapp.tcl</tt> provides a GUI interface to <tt>mktclapp</tt></li></ul><ul><li>http://www.hwaci.com/sw/mktclapp/</li></ul></p></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">\"Hello, World!\" Using Mktclapp</h2>\n<p><ul><li>Download <tt>mktclapp.c</tt> and <tt>xmktclapp.tcl</tt> from\n  http://www.hwaci.com/sw/mktclapp/</li></ul><ul><li>Compile <tt>mktclapp</tt>:\n  <blockquote><pre>\n  cc -o mktclapp mktclapp.c\n  </pre></blockquote></li></ul><ul><li>Create \"Hello, World!\" as a Tcl script in file <tt>hw.tcl</tt>:\n  <blockquote><pre>\n  button .b -text {Hello, World!} -command exit\n  pack .b\n  </pre></blockquote></li></ul><ul><li>Launch xmktclapp:\n  <blockquote><pre>\n  wish xmktclapp.tcl\n  </pre></blockquote></li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">\"Hello, World!\" Using Mktclapp</h2>\n<table width=\"100%\"><tr><td valign=\"top\"><p><ul><li>Set \"Command Line Input?\" to \"None\"</li></ul><ul><li>Set \"Standalone?\" to \"Yes\"</li></ul><ul><li>Enter \"<tt>hw.mta</tt>\" for the Configuration File</li></ul><ul><li>Enter \"<tt>hw.c</tt>\" for the Output C File</li></ul></p></td>\n<td valign=\"top\" align=\"right\"><img src=\"image10\"></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">\"Hello, World!\" Using Mktclapp</h2>\n<table width=\"100%\"><tr><td valign=\"top\"><p><ul><li>Go to the \"Tcl Scripts\" page</li></ul><ul><li>Press \"Insert\" and add <tt>hw.tcl</tt> to the list of\n  Tcl scripts</li></ul><ul><li>Change the \"Startup Script\" to be <tt>hw.tcl</tt>.</li></ul><ul><li>Select File/Build and File/Exit</li></ul></p></td>\n<td valign=\"top\" align=\"right\"><img src=\"image11\"></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">\"Hello, World!\" Using Mktclapp</h2>\n<p><ul><li>Mktclapp generates <tt>hw.c</tt>.\n  Compile it something like this:\n  <pre>\n  cc hw.c -ltk -L/usr/X11R6/lib -lX11 -ltcl -lm -ldl\n  </pre></li></ul><ul><li>Or, if using Cygwin:\n  <pre>\n  gcc hw.c -mwindows -ltk80 -ltcl80 -lm\n  </pre></li></ul><ul><li>Or, if using Mingw32:\n  <pre>\n  gcc -mno-cygwin hw.c -mwindows -ltk82 -ltcl82 -lm\n  </pre></li></ul><ul><li>And you're done!</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Adding C Code To Your Program</h2>\n<p>Put the new C code in a new source file named \"<tt>add.c</tt>\"</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;\"hw.h\"</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Generated by mktclapp</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt></tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;ET_COMMAND_add(ET_TCLARGS){</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><tt>ET_TCLARGS</tt> is a macro defined in <tt>hw.h</tt></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;int&nbsp;a,&nbsp;b;<br>\n&nbsp;&nbsp;char&nbsp;zResult[30];<br>\n&nbsp;&nbsp;a&nbsp;=&nbsp;atoi(argv[1]);<br>\n&nbsp;&nbsp;b&nbsp;=&nbsp;atoi(argv[2]);<br>\n&nbsp;&nbsp;sprintf(zResult,&nbsp;\"-1073742724\",&nbsp;a+b);<br>\n&nbsp;&nbsp;Tcl_SetResult(interp,&nbsp;zResult,&nbsp;TCL_VOLATILE);<br>\n&nbsp;&nbsp;return&nbsp;TCL_OK;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Adding C Code To Your Program</h2>\n<table width=\"100%\"><tr><td valign=\"top\"><p><ul><li>Go to the \"C/C++ Modules\" page of xmktclapp.tcl</li></ul>\n<ul><li>Press \"Insert\" and add <tt>add.c</tt> to the list of\n  C/C++ modules</p></li></ul></li></ul><ul><li>Select File/Build and File/Exit</li></ul></p></td>\n<td valign=\"top\" align=\"right\"><img src=\"image12\"></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Adding C Code To Your Program</h2>\n<p><ul><li>Compile as follows:\n  <pre>\n  cc add.c hw.c -ltk -L/usr/X11R6/lib -ltcl -lm -ldl\n  </pre></li></ul><ul><li>Or construct a Makefile that compiles <tt>add.c</tt> into <tt>add.o</tt>\n  and <tt>hw.c</tt> into <tt>hw.o</tt> and then links them.</li></ul><ul><li>Compile the same way for Windows except use the usual Windows\n  libraries and options...</li></ul><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>Don't have to worry with <tt>Tcl_CreateCommand()</tt> - Mktclapp takes\n  care of that automatically.</b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Checking Parameters In The <tt>add</tt> Command</h2>\n<p>Modify <tt>add.c</tt> to insure the <tt>add</tt> command\n  is called with exactly two integer arguments</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;\"hw.h\"<br>\n&nbsp;<br>\nint&nbsp;ET_COMMAND_add(ET_TCLARGS){<br>\n&nbsp;&nbsp;int&nbsp;a,&nbsp;b;<br>\n&nbsp;&nbsp;char&nbsp;zResult[30];</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;argc!=3&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;Tcl_AppendResult(interp,<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"wrong&nbsp;#&nbsp;args:&nbsp;should&nbsp;be:&nbsp;\\\"\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv[0],&nbsp;\"&nbsp;VALUE&nbsp;VALUE\\\"\",&nbsp;0);<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Report an error if there are not exactly\n  2 arguments</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[1],&nbsp;&amp;a)!=TCL_OK&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Report an error if the first argument is\n  not an integer</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[2],&nbsp;&amp;b)!=TCL_OK&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Do the same for the second argument</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;sprintf(zResult,&nbsp;\"-1073742724\",&nbsp;a+b);<br>\n&nbsp;&nbsp;Tcl_SetResult(interp,&nbsp;zResult,&nbsp;TCL_VOLATILE);<br>\n&nbsp;&nbsp;return&nbsp;TCL_OK;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Using The Tcl_Obj Interface</h2>\n<p>In the file <tt>objadd.c</tt> put this code:</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;\"hw.h\"</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\nint&nbsp;ET_OBJCOMMAND_add2(ET_OBJARGS){<br>\n&nbsp;&nbsp;int&nbsp;a,&nbsp;b;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Use \"<tt>ET_OBJCOMMAND</tt>\" instead of \"<tt>ET_COMMAND</tt>\" and\n  \"<tt>ET_OBJARGS</tt>\" instead of \"<tt>ET_TCLARGS</tt>\"</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;objc!=3&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;Tcl_WrongNumArgs(interp,&nbsp;1,&nbsp;objv,<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"number&nbsp;number\");<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">A special routine for \"wrong # args\" error</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;Tcl_GetIntFromObj(interp,&nbsp;objv[1],&nbsp;&amp;a)&nbsp;){</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Instead of <tt>Tcl_GetInt</tt></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;if(&nbsp;Tcl_GetIntFromObj(interp,&nbsp;objv[2],&nbsp;&amp;b)&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_SetIntObj(Tcl_GetObjResult(interp),&nbsp;a+b);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Result stored as integer, not a string</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Speed Of Tcl_Obj Versus \"char*\"  Interfaces</h2>\n<p><ul><li>Compile both <tt>add</tt> and <tt>add2</tt> into the same executable.</li></ul><ul><li>Compare their speeds:\n  <pre>\n   time {add 123456 654321} 10000\n  <font color=\"blue\">26 microseconds per iteration</font>\n   time {add2 123456 654321} 10000\n  <font color=\"blue\">4 microseconds per iteration</font>\n  </pre></li></ul><ul><li>The Tcl_Obj version is 650 faster!</li></ul><ul><li>Replace the addition with a \"real\" computation that takes\n  10 milliseconds.</li></ul><ul><li>Now the Tcl_Obj version is only 0.2 faster!</li></ul><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>In many real-world problems, the Tcl_Obj interface has no noticeable\n  speed advantage over the string interface.</b></td></tr></table></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">More About Built-in Tcl Scripts</h2>\n<table><tr><td valign=\"top\"><img src=\"image11\"></td>\n<td valign=\"top\"><p><ul><li>Comments and leading white-space are removed from the\n  script by default.  Use the \"Don't Strip Comments\"\n  button to change this.</li></ul><ul><li>The file name must exactly match the name that is\n  used by the <tt>source</tt> command.</li></ul></p></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Locations Of Libraries</h2>\n<table><tr><td valign=\"top\"><img src=\"image13\"></td>\n<td valign=\"top\"><p><ul><li>Tells mktclapp where to look for script libraries.</li></ul><ul><li>All Tcl scripts in the indicated directories are\n  compiled into the <tt>appinit.c</tt> file.</li></ul><ul><li>Comments and extra white-space are removed. \n  There is no way to turn this off.</li></ul></p></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Built-in Binary Data Files</h2>\n<table><tr><td valign=\"top\"><img src=\"image14\"></td>\n<td valign=\"top\"><p><ul><li>Arbitrary files become part of the virtual filesystem</li></ul><ul><li>No comment or white-space removal is attempted</li></ul><ul><li>Useful for images or other binary data</li></ul></p></td></tr></table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">New Commands In Namespaces</h2>\n<p>Two underscores (__)  are replaced by two colons (::) in\n  command names, thus giving the ability to define new commands\n  in a namespace</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;hw.h></tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt><br>\nint&nbsp;ET_COMMAND_adder__add(ET_TCLARGS){<br>\n&nbsp;&nbsp;int&nbsp;a,&nbsp;b;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Creates the Tcl command called \"<tt>adder::add</tt>\"</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;char&nbsp;*zResult[30];<br>\n&nbsp;&nbsp;if(&nbsp;argc!=3&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;Tcl_AppendResult(interp,<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"wrong&nbsp;#&nbsp;args:&nbsp;should&nbsp;be:&nbsp;\\\"\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv[0],&nbsp;\"&nbsp;VALUE&nbsp;VALUE\\\"\",&nbsp;0);<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[1],&nbsp;&amp;a)!=TCL_OK&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;if(&nbsp;Tcl_GetInt(interp,&nbsp;argv[1],&nbsp;&amp;b)!=TCL_OK&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}<br>\n&nbsp;&nbsp;sprintf(zResult,&nbsp;\"-1073742724\",&nbsp;a+b);<br>\n&nbsp;&nbsp;Tcl_SetResult(interp,&nbsp;zResult,&nbsp;TCL_VOLATILE);<br>\n&nbsp;&nbsp;return&nbsp;TCL_OK;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Adding Your Own <tt>main()</tt></h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;/*&nbsp;Application&nbsp;specific&nbsp;initialization&nbsp;*/</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Never returns!</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*NOTREACHED*/<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><table><tr><td valign=\"top\"><img src=\"image3\"></td>\n<td valign=\"top\"><b>The \"Autofork\" feature is disabled if you supply your own <tt>main()</tt></b></td></tr></table>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Initializing The Tcl Interpreter</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nint&nbsp;counter&nbsp;=&nbsp;0;<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){<br>\n&nbsp;&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);<br>\n&nbsp;&nbsp;&nbsp;/*NOTREACHED*/<br>\n&nbsp;&nbsp;&nbsp;return&nbsp;0;<br>\n}<br>\n&nbsp;<br>\nint&nbsp;Et_AppInit(Tcl_Interp&nbsp;*interp){</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;if(&nbsp;Blt_Init(Interp)&nbsp;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TCL_ERROR;<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Example: Initialize an extension</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Tcl_LinkVar(interp,&nbsp;\"counter\",&nbsp;&amp;counter,<br>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TCL_LINK_INT);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Or link a C variable to a Tcl variable</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return&nbsp;TCL_OK;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Return TCL_OK if successful</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Writing Your Own Event Loop</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>void&nbsp;Et_CustomMainLoop(Tcl_Interp&nbsp;*interp){</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Replaces the default event loop</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;return;</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Ex: Return without handling any events.</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">This now returns after initializing Tcl</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*&nbsp;Application&nbsp;code&nbsp;here&nbsp;*/<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Writing Your Own Event Loop</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;&lt;tcl.h><br>\n&nbsp;<br>\nvoid&nbsp;Et_CustomMainLoop(Tcl_Interp&nbsp;*interp){</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;for(;;){<br>\n&nbsp;&nbsp;&nbsp;&nbsp;Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT);<br>\n&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;Other&nbsp;processing...&nbsp;*/<br>\n&nbsp;&nbsp;}</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Intermix processing and event handling</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>}<br>\n&nbsp;<br>\nint&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;Et_Init(argc,&nbsp;argv);</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Never returns</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>&nbsp;&nbsp;/*NOTREACHED*/<br>\n&nbsp;&nbsp;return&nbsp;0;<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Mktclapp Initialization Sequence</h2>\n<p><ul><li>Initialization starts when the <tt>Et_Init()</tt> \n  function is called either by client code or by\n  the <tt>main()</tt> that mktclapp generates</li></ul><ul><li>Create the main Tcl interpreter</li></ul><ul><li>Construct the virtual filesystem overlay by redefining\n  the <tt>source</tt> command and by using the \n  <tt>Tcl</tt>*<tt>InsertProc()</tt> functions</li></ul><ul><li>Call <tt>Et_PreInit()</tt> if the client defines it</li></ul><ul><li>Call <tt>Tcl_Init()</tt> and <tt>Tk_Init()</tt></li></ul><ul><li>Call <tt>Tcl_CreateCommand()</tt> and <tt>Tcl_CreateObjCommand()</tt>\n  for every <tt>ET_COMMAND_</tt>* and <tt>ET_OBJCOMMAND_</tt>* function\n  in the client code</li></ul><ul><li>Call <tt>Et_AppInit()</tt> if the client defines it</li></ul><ul><li>Run the main Tcl script if there is one</li></ul><ul><li>Call <tt>Et_CustomMainLoop()</tt> if defined by client code or\n  else run the built-in event loop</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Invoking Tcl From C</h2>\n<p><ul><li>Use one of the built-in evaluation functions:\n  <center><table width=\"80%\">\n  <tr><td valign=\"top\" width=\"50%\"><ul>\n     <li> Tcl_Eval() </li>\n     <li> Tcl_VarEval() </li>\n     <li> Tcl_EvalFile() </li>\n     <li> Tcl_GlobalEval() </li>\n     </ul></td>\n  <td valign=\"top\" width=\"50%\"><ul>\n     <li> Tcl_EvalObj() </li>\n     <li> Tcl_GlobalEvalObj() </li>\n   </ul></td></tr>\n  </table></center></li></ul><ul><li>Mktclapp provides evaluation functions with variable argument\n  lists as in <tt>printf()</tt>:\n  <ul>\n  <li> Et_EvalF() </li>\n  <li> Et_GlobalEvalF() </li>\n  </ul></li></ul><ul><li>Mktclapp provides a global variable <tt>Et_Interp</tt> which is\n  a pointer to the main interpreter</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Invoking Tcl From C</h2>\n<p>Example:  A C function that pops up an error message dialog box</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;\"appinit.h\"<br>\n&nbsp;<br>\nvoid&nbsp;ErrMsg(char&nbsp;*zMsg){<br>\n&nbsp;&nbsp;Tcl_SetVar(Et_Interp,&nbsp;\"zMsg\",&nbsp;zMsg,&nbsp;TCL_GLOBAL_ONLY);<br>\n&nbsp;&nbsp;Tcl_GlobalEval(Et_Interp,&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;\"tk_messageBox&nbsp;-icon&nbsp;error&nbsp;-msg&nbsp;$zMsg&nbsp;-type&nbsp;ok\");<br>\n&nbsp;&nbsp;Tcl_UnsetVar(Et_Interp,&nbsp;\"zMsg\",&nbsp;TCL_GLOBAL_ONLY);<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Invoking Tcl From C</h2>\n<p>The same C function implemented using <tt>Et_EvalF()</tt> instead\n  of <tt>Tcl_GlobalEval()</tt></p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;\"appinit.h\"<br>\n&nbsp;<br>\nvoid&nbsp;ErrMsg(char&nbsp;*zMsg){<br>\n&nbsp;&nbsp;Et_EvalF(Et_Interp,&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;\"tk_messageBox&nbsp;-icon&nbsp;error&nbsp;-msg&nbsp;{P\u0004\bX\u0004\b}&nbsp;-type&nbsp;ok\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;zMsg);<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p>\n  <ul><li>\n  Suppose the function is called as follows:\n  <blockquote>\n    <tt>ErrMsg(\"Syntax error near \\\"}\\\"\");</tt>\n  </blockquote>\n  </li></ul>\n\n  <ul><li>\n  The command that gets executed is:\n  <pre>\n    tk_messageBox -icon error -msg \\ \n        {Syntax error near \"}\"} -type ok\n  </pre>\n  </li></ul>\n\n  <ul><li>\n  But this is an ill-formed Tcl command!\n  </li></ul>\n</p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Invoking Tcl From C</h2>\n<p>Use the \"<tt></tt>\" format to generate a quoted string</p><p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#include&nbsp;\"appinit.h\"<br>\n&nbsp;<br>\nvoid&nbsp;ErrMsg(char&nbsp;*zMsg){<br>\n&nbsp;&nbsp;Et_EvalF(Et_Interp,&nbsp;<br>\n&nbsp;&nbsp;&nbsp;&nbsp;\"tk_messageBox&nbsp;-icon&nbsp;error&nbsp;-msg&nbsp;\\\"%\\\"&nbsp;-type&nbsp;ok\",<br>\n&nbsp;&nbsp;&nbsp;&nbsp;zMsg);<br>\n}</tt></small></td>\n<td></td><td></td><td></td><td></td>\n</tr>\n</table>\n<p><ul><li>The <tt></tt> puts a backslash before all characters that\n  are special to Tcl</li></ul><ul><li>The Tcl command becomes:\n  <pre>\n    tk_messageBox -icon error -msg \\ \n        \"Syntax error near \\\"\\}\\\"\" -type ok\n  </pre></li></ul></p>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Other Functions Provided By Mktclapp</h2>\n<p><ul><li><tt>void Et_ResultF(Tcl_Interp*, ...);</tt></li></ul><ul><li><tt>char *Et_DStringAppendF(Tcl_DString*, ...);</tt></li></ul><ul><li><tt>int Et_AppendObjF(Tcl_Obj*, ...);</tt></li></ul><ul><li><tt>char *mprintf(const char *format, ...);<br>\n  char *vmprintf(const char *format, va_list);</tt></li></ul><ul><li><tt>void Et_NewBuiltinFile(char *filename, char *data, int amt);</tt></li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Operating Mktclapp From The Command Line</h2>\n<p><ul><li>Generate the <tt>appinit.h</tt> header file like this:\n  <blockquote>\n  <tt>mktclapp -header &gt;appinit.h</tt>\n  </blockquote></li></ul><ul><li>Generate the <tt>appinit.c</tt> file like this:\n  <blockquote>\n  <tt>mktclapp -f appinit.mta >appinit.c</tt>\n  </blockquote></li></ul><ul><li>The <tt>*.mta</tt> file is just a list of command-line options</li></ul><ul><li>Enter\n  <blockquote>\n  <tt>mktclapp -help</tt>\n  </blockquote>\n  to get a list of available options</li></ul><ul><li>Look at MTA files generated by xmktclapp.tcl for examples</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Format Of An MTA File</h2>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><td valign=\"center\">\n<small><tt>#&nbsp;Configuration&nbsp;file&nbsp;generated&nbsp;by&nbsp;xmktclapp<br>\n#&nbsp;Hand&nbsp;editing&nbsp;is&nbsp;not&nbsp;recommended<br>\n#</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Comments begin with one #</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>##&nbsp;Autofork&nbsp;No<br>\n##&nbsp;CFile:add.c&nbsp;1<br>\n##&nbsp;CFile:objadd.c&nbsp;1<br>\n##&nbsp;CmdLine&nbsp;Console<br>\n##&nbsp;ConfigFile&nbsp;hw.mta<br>\n##&nbsp;Data:check.gif&nbsp;1<br>\n##&nbsp;MainScript&nbsp;hw.tcl<br>\n##&nbsp;Mode&nbsp;Tcl/Tk<br>\n##&nbsp;NoSource&nbsp;No<br>\n##&nbsp;OutputFile&nbsp;hw.c<br>\n##&nbsp;Shroud&nbsp;No<br>\n##&nbsp;Standalone&nbsp;Yes<br>\n##&nbsp;TclFile:hw.tcl&nbsp;1<br>\n##&nbsp;TclLib&nbsp;/usr/lib/tcl8.0<br>\n##&nbsp;TkLib&nbsp;/usr/lib/tk8.0</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">Lines beginning with two #s are used\n  by xmktclapp.tcl and ignored by mktclapp</td>\n</tr>\n<tr><td valign=\"center\">\n<small><tt>-console<br>\n-main-script&nbsp;\"hw.tcl\"<br>\n-tcl-library&nbsp;\"/usr/lib/tcl8.0\"<br>\n-tk-library&nbsp;\"/usr/lib/tk8.0\"<br>\n\"add.c\"<br>\n\"objadd.c\"<br>\n-i&nbsp;\"check.gif\"<br>\n-strip-tcl&nbsp;\"hw.tcl\"</tt></small></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\"><img src=\"image2\"></td>\n<td>&nbsp;&nbsp;</td>\n<td valign=\"center\">All other lines are read by mktclapp and\n  ignored by xmktclapp.tcl</td>\n</tr>\n</table>\n\n<br clear=\"both\"><p><hr></p>\n<h2 align=\"center\">Summary</h2>\n<p><ul><li>Use Tcl for the things Tcl is good at and use C/C++ for the things that\n  C/C++ is good at</li></ul><ul><li>Use wrapper programs to make pure Tcl programs standalone</li></ul><ul><li>Use mktclapp to combine Tcl/Tk with C/C++ into a standalone</li></ul></p>\n<br clear=\"both\"><p><hr></p>\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/page4/index.html",
    "content": "<!DOCTYPE HTML=\"HTML\" PUBLIC=\"PUBLIC\" \"-//W3C//DTD=\"\"-//W3C//DTD\" HTML=\"HTML\" 4.0=\"4.0\" Transitional//EN\"=\"Transitional//EN\"\">\n<HTML>\n<HEAD>\n<TITLE>[fm] welcome to freshmeat.net</TITLE>\n<STYLE TYPE=\"text/css\"><!-- A:link {text-decoration: none}A:visited{text-decoration:none}A:active{text-decoration:none}--></STYLE>\n</HEAD>\n<BODY MARGINWIDTH=\"0\" MARGINHEIGHT=\"0\" LEFTMARGIN=\"0\" RIGHTMARGIN=\"0\" TOPMARGIN=\"0\" BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#336699\" VLINK=\"#336699\" ALINK=\"#336699\">\n<BR><CENTER><TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\"><TR><TD WIDTH=\"1\"><SCRIPT LANGUAGE=\"JAVASCRIPT\">\n<!--\nnow = new Date();\ntail = now.getTime();\ndocument.write(\"<IMG SRC='http://209.207.224.246/FreshMeat/Core/pc.gif?/index.php3,\" + tail + \"' WIDTH=1 HEIGHT=1><BR>\");\n//-->\n</SCRIPT>\n<NOSCRIPT>\n<IMG SRC=\"image1\" WIDTH=\"1\" HEIGHT=\"1\"><BR>\n</NOSCRIPT></TD></TR></TABLE>\n<TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\"><TR><TD WIDTH=\"468\"><SCRIPT LANGUAGE=\"JAVASCRIPT\">\n<!--\nnow = new Date();\ntail = now.getTime();\nAltText = \"\\\"Please click here.\\\"\";\ndocument.write(\"<A HREF='http://ads.freshmeat.net/cgi-bin/ad_click.pl?index,tsof0001en'>\")\ndocument.write(\"<IMG SRC='http://ads.freshmeat.net/tsof0001en.gif?\" + tail + \"' WIDTH=468 HEIGHT=60 ALT=\" + AltText + \"></A><BR>\");\n//-->\n</SCRIPT>\n<NOSCRIPT>\n<A HREF=\"http://ads.freshmeat.net/cgi-bin/ad_click.pl?index,tsof0001en\"><IMG SRC=\"image2\" WIDTH=\"468\" HEIGHT=\"60\" ALT=\"Please click here.\"></A><BR>\n</NOSCRIPT></TD></TR></TABLE>\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" BORDER=\"0\" WIDTH=\"97%\"><TR>\n<TD ALIGN=\"left\" VALIGN=\"bottom\"><A HREF=\"/\"><IMG SRC=\"image3\" BORDER=\"0\" ALT=\"freshmeat.net\" WIDTH=\"300\" HEIGHT=\"65\"></A></TD>\n<TD VALIGN=\"bottom\" ALIGN=\"left\" ROWSPAN=\"2\"><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<FORM METHOD=\"get\" ACTION=\"/search.php3\">\n<SMALL>find: <INPUT TYPE=\"text\" SIZE=\"15\" NAME=\"query\"></SMALL></FORM></FONT></TD>\n<TD ALIGN=\"right\" VALIGN=\"bottom\"><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<A HREF=\"http://www.linux.com\"><FONT COLOR=\"#000000\"><B><SMALL>linux.com partner</SMALL></B></FONT></A><BR>\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"1\" BORDER=\"0\" WIDTH=\"100%\"><TR>\n<TD ALIGN=\"right\"><SMALL><NOBR><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><B><A HREF=\"/\">news</A> |<BR>\n<A HREF=\"/appindex/\">appindex</A> |<BR>\n<A HREF=\"/editorials/\">editorials</A> |</B></FONT></NOBR></SMALL></TD>\n<TD ALIGN=\"right\"><SMALL><NOBR><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><B><A HREF=\"/lounge/\">lounge</A> |<BR>\n<A HREF=\"/contrib.php3\">contribute</A> |<BR>\n<A HREF=\"/feedback.php3\">feedback</A> |</B></FONT></NOBR></SMALL></TD>\n<TD ALIGN=\"right\"><SMALL><NOBR><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><B><A HREF=\"/about.php3\">about</A> |<BR>\n<A HREF=\"/awards.php3\">awards</A> |<BR>\n<A HREF=\"/faq.php3\">FAQ</A> |</B></FONT></NOBR></SMALL></TD>\n</TR></TABLE></TD>\n</TR></TABLE>\n<TABLE WIDTH=\"100%\" CELLPADDING=\"0\" CELLSPACING=\"0\" BORDER=\"0\">\n<TR BGCOLOR=\"#000000\"><TD><IMG SRC=\"image4\" WIDTH=\"1\" HEIGHT=\"2\" ALT=\"\"></TD></TR></TABLE>\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" BORDER=\"0\" WIDTH=\"100%\" BGCOLOR=\"#BBDDFF\">\n<TR><TD ALIGN=\"center\" VALIGN=\"top\">\n<BR>\n<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n\n\n<SMALL><B>sort by: [ <A HREF=\"/news/2000/01/29/\">date</A> | <A HREF=\"/news/list.php3?day=/2000/01/29/&orderby=name\">name</A> | <A HREF=\"/news/list.php3?day=/2000/01/29/&orderby=urgency\">urgency</A> ]</B></SMALL><BR></TD><TD>&nbsp;</TD></TR><TR><TD VALIGN=\"top\" ALIGN=\"center\"><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">We should get this out of the door now</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:scoop@freshmeat.net\">scoop</A> - January 29th 2000, 23:59 EST</B></SMALL>\n<P>Everyone else is talking about it, so we should announce it ourselves\nbefore you start to think it's a government hoax. <A HREF=\"http://server51.freshmeat.net/\">Server 51</A> is our new hosting service for Open Source projects, based on Super Cool Space Alien Technology(TM). We hadn't planned to announce it quite so soon, and it's still in the alpha stage as we work day and night at integrating SCSAT with our terrestrial systems, but feel free to take a look around and see what's going on. When we're out of the testing stage and ready to make room for your project, we'll send word via your implants. Be listening.\n\n\n\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949208399.html\">comments (8)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>Category: freshmeat\n</SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n \t<A HREF=\"http://server51.freshmeat.net\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">Is Linux for Crazies?</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:jeff.covey@pobox.com\">jeff covey</A> - January 29th 2000, 23:59 EST</B></SMALL>\n<P>Ray Woodcock writes: \"In terms relevant to Linux, this freshmeat\neditorial glances at the tendency of mainstream viewpoints to dismiss\nother viewpoints as 'fringe,' the propensity of dissident movements to\nsplinter into factions before they can effectively counter their\nprimary adversaries, and the difficulty of creating stability without\nsquelching curiosity.\"\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949208340.html\">comments (2), 2065 words in body</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>Category: Editorial\n</SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n   &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">RabbIT 2.0.2</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:d94-rol@nada.kth.se\">Ernimril</A> - January 29th 2000, 18:29 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>RabbIt is the mutating, caching webproxy which is used to speed up surfing over slow links like modems. It does this by removing advertising and background images and scaling down images to low quality JPEGs. RabbIT is written in Java and should be able to run on any platform. It does depend upon an image converter if imagescaleing is on. The recommended image converter is \"convert\" from the ImageMagick package.</DIV>\n<P><B>Changes:</B> Fixes have been made for a few bugs concerning keep alive and the HTTP response header, a bug with NT and cache directories, a bug concerning requests without a response body, a bug in GZIPHandler that caused it to not gzip already compressed (gzip or compress) streams, a bug in HTTPHeader regarding response phrases that are multiline, and a few bugs in ImageHandler and NCache. GZIPHandler has been built as an intermediate(*) to FilterHandler (this means that it is possible to gzip text/plain, etc., without filtering those streams) uuencoding has been added to the Coder, RabbIT now uses HTTP/1.1, HTMLParser now compiles cleanly with Jikes, and GeneralHeader has been created to allow for HTTPFooter (which is useful when sending chunked data).\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949188564.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: freely distributable</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/daemons/proxy.html\"><FONT COLOR=\"#FFFFFF\">Daemons/Proxy</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/902659138/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/902659138/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/1998/08/09/902659138.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">nmpg 1.1.3</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:narkos@linuxmail.org\">Joel Lindau</A> - January 29th 2000, 18:18 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>nmpg is a small command-driven frontend and network-jukebox for mpg123.</DIV>\n<P><B>Changes:</B> Bugfixes, better memory managment, a new .nmpgrc parser, and new options.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949187896.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: OpenSource</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/sound.html\"><FONT COLOR=\"#FFFFFF\">Console/Sound</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/935430877/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/935430877/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/935430877/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/08/23/935430877.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">mod_dtcl 0.7.3</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:davidw@prosa.it\">David Welton</A> - January 29th 2000, 18:11 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>Mod_dtcl is a free/open source implementation of server-parsed Tcl under Apache. It allows you to tightly integrate HTML with Tcl, a widely-used scripting language with many years of development invested in it. There are also many external Tcl modules that you can load into mod_dtcl, to create images, access databases, etc.</DIV>\n<P><B>Changes:</B> A major overhaul of header handling and internal buffering, and the addition of the ability to handle binary data.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949187471.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/web/development.html\"><FONT COLOR=\"#FFFFFF\">Web/Development</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/917925309/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/917925309/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/917925309/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/02/01/917925309.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">CoreLinux++ 0.4.6</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:frankc@users.sourceforge.net\">Frank V. Castellucci</A> - January 29th 2000, 18:07 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>CoreLinux++ is an initiative to normalize methods and conventions for OOA/OOD/C++ development for Linux, materialized in a set of Open Source C++ class libraries (libcorelinux++ and libcoreframework++) to support common patterns and exploit the C++ standards.</DIV>\n<P><B>Changes:</B> This release adds AbstractFactory and AssociativeIterator analysis, design, implementations, test code, a CVS daily tarball, a Patch Submission facility and updated FAQ, Web Pages, and defect reporting guidelines.\n<P><B>Urgency:</B> medium\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949187233.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: LGPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/development/libraries.html\"><FONT COLOR=\"#FFFFFF\">Development/Libraries</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/944077775/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/944077775/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/944077775/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/12/01/944077775.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">scribe 0.2</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:kahlage@logoncafe.net\">ChromeBob</A> - January 29th 2000, 12:12 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>scribe writes functions prototypes for your C code, so you don't have to. It also compares unique functions between source code files and will 'extern' when appropriate. C++ methods support is also planned.</DIV>\n<P><B>Changes:</B> A fix for an fflush() bug and better documentation.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949165962.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/development/tools.html\"><FONT COLOR=\"#FFFFFF\">Development/Tools</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/946661656/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/946661656/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/1999/12/31/946661656.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">E theme updater 0.1</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:hallvar@ii.uib.no\">Hallvar Helleseth</A> - January 29th 2000, 12:04 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>E theme Updater is a bash script to automatically update all of your Enlightenment themes from e.themes.org.</DIV>\n<P><B>Changes:</B> Initial release.\n\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949165472.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/misc.html\"><FONT COLOR=\"#FFFFFF\">Console/Misc</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/949164501/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/949164501/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/2000/01/29/949164501.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">Powertweak-Linux 0.1.7</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:dave@denial.force9.co.uk\">Dave Jones</A> - January 29th 2000, 12:03 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>Powertweak-Linux is a port of the Microsoft Windows tool of the same name rewritten from the ground up. Its main function is to tune your system to its optimal performance settings. Currently, it tunes PCI chipsets and can set /proc/sys entries.</DIV>\n<P><B>Changes:</B> A major GUI overhaul, the ability to generate configuration files, extended PCI information tabs, extra information support for the Matrox G200, and numerous other bugfixes & improvements.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949165416.html\">comments (2)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/system.html\"><FONT COLOR=\"#FFFFFF\">Console/System</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/930836224/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/930836224/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/930836224/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/07/01/930836224.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">Pexeso Beta</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:pavolkrigler@pobox.sk\">Pavol Krigler</A> - January 29th 2000, 11:55 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>pexeso is a simple graphic card game for one or two players.</DIV>\n<P><B>Changes:</B> Initial public release.\n\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164956.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: Freeware</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/games.html\"><FONT COLOR=\"#FFFFFF\">Console/Games</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/949141436/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/949141436/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/2000/01/29/949141436.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">XZX 2.9.2</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:Erik.Kunze@fantasy.muc.de\">E. Kunze</A> - January 29th 2000, 11:54 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>XZX is a portable emulator of ZX Spectrum 48K/128K/+3 (8-bit home computers made by Sir Clive Sinclair) and Pentagon/Scorpion (Spectrum clones made in Russia) for machines running UNIX and the X Window system. XZX is completely written in C and emulates Spectrum 48K, 128K, +2 and +3, Pentagon and Scorpion, Interface I with up to 8 microdrives, Multiface 128 and Multiface 3, BetaDisk 128 interface by Technology Research Ltd with 4 disk drives, +D interface by Miles Gordon Technology with 2 disk drives, Kempston mouse, Kempston joystick and built-in machine code monitor.</DIV>\n<P><B>Changes:</B> Lots of feature improvement and bug fixes. Most parts of the audio support has been rewritten for different UNICES.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164896.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: Shareware</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/x11/emulators.html\"><FONT COLOR=\"#FFFFFF\">X11/Emulators</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/936956384/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/936956384/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/936956384/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/09/10/936956384.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">DistroLib 0.4</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:phir@gcu-squad.org\">PhiR</A> - January 29th 2000, 11:54 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>DistroLib is an abstraction library designed to make the development of distributed application easier. Its main target is currently compute-bound tasks based on a one server, many clients model (much like distributed.net), but it is quite generic and could be used for any client/server app. It is lightweight, easy-to-use, and relies heavily on threads.</DIV>\n<P><B>Changes:</B> Important bug fixes and command history support.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164869.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/development/libraries.html\"><FONT COLOR=\"#FFFFFF\">Development/Libraries</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/942588431/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/942588431/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/942588431/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/11/14/942588431.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">ToutDoux 1.1.7</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:yeupou@altern.org\">yeupou</A> - January 29th 2000, 11:54 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>ToutDoux is a project manager which lets you design a plan of action using a tree structure, with translations in French and English.</DIV>\n<P><B>Changes:</B> A new menu and XML standard for save files.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164843.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/gnome/tools.html\"><FONT COLOR=\"#FFFFFF\">GNOME/Tools</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/944433411/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/944433411/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/1999/12/05/944433411.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">goMP 1.0.3</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:dioxine@poulet.org\">Gautier</A> - January 29th 2000, 11:52 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>goMP is a set of CGI scripts that allows you to remotely control, via a Web browser, a computer acting as an MP3 jukebox. This program is very useful for someone who's got a dedicated computer with a lot of MP3 files but that doesn't have any output and input devices except network and sound card. It's main advantages are built-in cataloging, fast access to music, and no special software needed on the client side.</DIV>\n<P><B>Changes:</B> Bugfixes, a password-protected config page, basic search function, easier installation thanks to an install script, and relocation of HTML docs and CGIs to a subdirectory.\n<P><B>Urgency:</B> medium\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164772.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: Artistic</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/web/tools.html\"><FONT COLOR=\"#FFFFFF\">Web/Tools</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/948492962/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/948492962/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/948492962/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/2000/01/21/948492962.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">APSEND 1.40</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:sventek@gmx.net\">M.K.</A> - January 29th 2000, 11:50 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>APSEND is a TCP/IP packet sender to test firewalls and other network applications. It also includes a syn flood option, the land DoS attack, and a DoS attack against tcpdump running on a UNIX-based system. Future updates will include support for a scripting language to construct TCP packets and a few more options and protocols like UDP and ICMP. A port of APSEND from Perl to C is planned as well.</DIV>\n<P><B>Changes:</B> The stream attack, bugfixes, and rewrites for parts of the code.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164633.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/networking.html\"><FONT COLOR=\"#FFFFFF\">Console/Networking</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/941654429/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/941654429/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/941654429/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/11/03/941654429.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">ecasound 1.6.12r10</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:kaiv@wakkanet.fi\">Kai Vehmanen</A> - January 29th 2000, 11:48 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>Ecasound is a software package designed for multitrack audio processing. It can be used for simple tasks like audio playback, recording and format conversions, as well as for multitrack effect processing, mixing, recording and signal recycling. Ecasound supports a wide range of audio inputs, outputs and effect algorithms. Ecasound has a chain-based design that allows effects to be easily combined both in series and in parallel. Oscillators and MIDI-CCs can be used for controlling effect parameters. Includes a versatile console mode interface, a Qt-based X-interface and various command-line utils suitable for batch processing.</DIV>\n<P><B>Changes:</B> Support for 24- and 32-bit audio formats and for ALSA 0.5, multichannel noisegate, a new 2nd order lowpass filter, some ia-mode commands, and various bugfixes and low-level improvements.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164529.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/sound.html\"><FONT COLOR=\"#FFFFFF\">Console/Sound</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/931819147/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/931819147/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/931819147/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/07/12/931819147.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">SCEZ 20000129</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:m032@mbsks.franken.de\">endergone Zwiebeltuete</A> - January 29th 2000, 11:46 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>SCEZ is a library that should make the handling of smart cards (not memory cards) and card readers as simple as possible and be at the same time small and easily portable. Currently supported are Dumb Mouse, CT-API and Towitoko readers and Schlumberger Cryptoflex, Gemplus GPK4000, GSM SIM and Telesec SigG cards. A PKCS#15 implementation is in the design phase. There are ports to PalmOS and MS-Windows available.</DIV>\n<P><B>Changes:</B> More card and reader drivers, and an application to read out GSM SIM card (phone book and SMS) and write it to the card.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164394.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: BSD type</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/development/libraries.html\"><FONT COLOR=\"#FFFFFF\">Development/Libraries</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/939677525/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/939677525/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/1999/10/11/939677525.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">Comicq 0.2.0</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:terminal6@submail.net\">Terminal6</A> - January 29th 2000, 11:45 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>COMICQ is a command line ICQ messaging tool that allows a user to connect to ICQ using your UIN and password, then sends a message to the destination UIN.</DIV>\n<P><B>Changes:</B> Several bugfixes, icq99a compliance, and a new option --ip that allows you to get any user's IP by their UIN.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164350.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/communication.html\"><FONT COLOR=\"#FFFFFF\">Console/Communication</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/948389309/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/948389309/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A>  \t<A HREF=\"/appindex/2000/01/20/948389309.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">senv 0.2</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:kojak@ids.pl\">Zbyszek Sobiecki</A> - January 29th 2000, 11:44 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>Senv allows you to run programs with a specified environment. It can set uid, gid, root directory, working directory, limits, and environment variables. It is useful in init scripts and as a shell for users for setting resource limits and environment variables. You can create sets of configurations and specify the one to use from command line.</DIV>\n<P><B>Changes:</B> Login shell limits and environment setting for users, permanent resource limits for specified groups of users and environment variables, and other minor bugfixes.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949164259.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: GPL</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/console/administration.html\"><FONT COLOR=\"#FFFFFF\">Console/Administration</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/944953892/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A>  <A HREF=\"http://apps.freshmeat.net/changelog/944953892/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/12/11/944953892.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"97%\" BORDER=\"0\" BGCOLOR=\"#000000\"><TR><TD COLSPAN=\"2\">\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"3\" WIDTH=\"100%\" BORDER=\"0\" BGCOLOR=\"#FFFFFF\">\n<TR><TD><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B><FONT SIZE=\"+2\">XZX 2.9.2</FONT></B><BR>\n<SMALL><B><A HREF=\"mailto:Erik.Kunze@fantasy.muc.de\">E. Kunze</A> - January 29th 2000, 10:55 EST</B></SMALL>\n<DIV ALIGN=\"justify\"><P>XZX is a portable emulator of ZX Spectrum 48K/128K/+3 (8-bit home computers made by Sir Clive Sinclair) and Pentagon/Scorpion (Spectrum clones made in Russia) for machines running UNIX and the X Window system. XZX is completely written in C and emulates Spectrum 48K, 128K, +2 and +3, Pentagon and Scorpion, Interface I with up to 8 microdrives, Multiface 128 and Multiface 3, BetaDisk 128 interface by Technology Research Ltd with 4 disk drives, +D interface by Miles Gordon Technology with 2 disk drives, Kempston mouse, Kempston joystick and built-in machine code monitor.</DIV>\n<P><B>Changes:</B> Lots of feature improvement and bug fixes. Most parts of the audio support has been rewritten for different UNICES.\n<P><B>Urgency:</B> low\n<P ALIGN=\"right\"><B>[ <A HREF=\"/news/2000/01/29/949161354.html\">comments (0)</A> ]</B>\n</FONT></TD></TR></TABLE></TD></TR><TR><TD VALIGN=\"middle\">\n&nbsp;<FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#FFFFFF\"><B><SMALL>License: Shareware</SMALL></B><BR>\n<B><SMALL>&nbsp;Category: <A HREF=\"/appindex/x11/emulators.html\"><FONT COLOR=\"#FFFFFF\">X11/Emulators</FONT></A></SMALL></B></FONT></FONT></TD><TD ALIGN=\"right\">\n<A HREF=\"http://apps.freshmeat.net/download/936956384/\"><IMG SRC=\"image6\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"download\"></A> <A HREF=\"http://apps.freshmeat.net/homepage/936956384/\"><IMG SRC=\"image5\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"homepage\"></A> <A HREF=\"http://apps.freshmeat.net/changelog/936956384/\"><IMG SRC=\"image8\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"changelog\"></A> \t<A HREF=\"/appindex/1999/09/10/936956384.html\"><IMG SRC=\"image7\" WIDTH=\"21\" HEIGHT=\"21\" BORDER=\"0\" ALT=\"appindex record\"></A> &nbsp;\n</TD></TR></TABLE>\n<HR WIDTH=\"0\" SIZE=\"0\">\n\n\n<P><SMALL><CENTER><B>[ <A HREF=\"/news/2000/01/29/\">full page for today</A> | <A HREF=\"/news/2000/01/28/\">yesterday's edition</A> ]</SMALL></B></CENTER></FONT></TD><TD WIDTH=\"27%\" VALIGN=\"top\" ALIGN=\"center\"><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\">navigator</FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"/news/2000/01/29/\"><FONT COLOR=\"#000000\">full page for today</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/\"><FONT COLOR=\"#000000\">yesterday's edition</FONT></A><BR>\n- <A HREF=\"news://news.freshmeat.net/\"><FONT COLOR=\"#000000\"><B>new:</B> fm news via NNTP</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\">eye catcher</FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<B>Free Shirts</B><BR>We give away a free freshmeat t-shirt every week for the best comment added to an application announcement or story posted on freshmeat.\n<P><B>#freshmeat</B><BR>If you want to chat about what's new on freshmeat and hang out with other fm lounge lizards and the fm staff, head over to #freshmeat on irc.freshmeat.net, part of <A HREF=\"http://openprojects.nu/\">The Open Projects Network</A>.\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\">site notes</FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"/news/2000/01/29/949208399.html\"><FONT COLOR=\"#000000\">We should get this out of the door now (Jan 29th)</FONT></A><BR>\n- <A HREF=\"/news/2000/01/01/946704535.html\"><FONT COLOR=\"#000000\">freshmeat Y2K report (Jan 01st)</FONT></A><BR>\n- <A HREF=\"/news/1999/08/16/934862340.html\"><FONT COLOR=\"#000000\">Assorted freshmeat notes (Aug 16th)</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\">recent editorials</FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"/news/2000/01/29/949208340.html\"><FONT COLOR=\"#000000\">Is Linux for Crazies? (Jan 29th)</FONT></A><BR>\n- <A HREF=\"/news/2000/01/22/948603540.html\"><FONT COLOR=\"#000000\">A New Business Plan for Free Software (Jan 22nd)</FONT></A><BR>\n- <A HREF=\"/news/2000/01/15/947998740.html\"><FONT COLOR=\"#000000\">Is Linux Going to Reunite the UNIX Market? (Jan 15th)</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\">andover.net</FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n<BR><CENTER><A HREF=\"http://andover.net\"><IMG SRC=\"image9\" BORDER=\"0\" WIDTH=\"150\" HEIGHT=\"43\" ALT=\"Mirror Logo\"></A></CENTER><P>\n- <A HREF=\"http://www.animfactory.com/\"><FONT COLOR=\"#000000\">Animation Factory</FONT></A><BR>\n- <A HREF=\"http://www.davecentral.com/\"><FONT COLOR=\"#000000\">DaveCentral</FONT></A><BR>\n- <A HREF=\"http://www.freecode.com/\"><FONT COLOR=\"#000000\">FreeCode</FONT></A><BR>\n- <A HREF=\"http://www.InternetTrafficReport.com/\"><FONT COLOR=\"#000000\">Internet Traffic Report</FONT></A><BR>\n- <A HREF=\"http://www.ITManagersJournal.com/\"><FONT COLOR=\"#000000\">IT Manager's Journal</FONT></A><BR>\n- <A HREF=\"http://www.mediabuilder.com/\"><FONT COLOR=\"#000000\">MediaBuilder</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/\"><FONT COLOR=\"#000000\">Slashdot</FONT></A><BR>\n- <A HREF=\"http://www.slaughterhouse.com/\"><FONT COLOR=\"#000000\">Slaughterhouse</FONT></A><BR>\n- <A HREF=\"http://www.techmailings.com/\"><FONT COLOR=\"#000000\">TechMailings</FONT></A><BR>\n- <A HREF=\"http://www.techsightings.com/\"><FONT COLOR=\"#000000\">TechSightings</FONT></A><BR>\n<BR><CENTER><B>E-Commerce</B></CENTER><P>\n- <A HREF=\"http://www.thinkgeek.com\"><FONT COLOR=\"#000000\">ThinkGeek (Stuff for smart masses)</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\">supported sites</FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://www.userfriendly.org\"><FONT COLOR=\"#000000\">Userfriendly.org</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com\"><FONT COLOR=\"#000000\">SecurityFocus</FONT></A><BR>\n- <A HREF=\"http://copyleft.net\"><FONT COLOR=\"#000000\">copyleft</FONT></A><BR>\n- <A HREF=\"http://filewatcher.org\"><FONT COLOR=\"#000000\">Filewatcher</FONT></A><BR>\n- <A HREF=\"http://www.linux.com\"><FONT COLOR=\"#000000\">Linux.com</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org\"><FONT COLOR=\"#000000\">LinuxTelephony</FONT></A><BR>\n- <A HREF=\"http://www.linuxtoday.com\"><FONT COLOR=\"#000000\">LinuxToday</FONT></A><BR>\n- <A HREF=\"http://openprojects.nu/services/irc.html\"><FONT COLOR=\"#000000\">Openprojects</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com\"><FONT COLOR=\"#000000\">32bitsonline</FONT></A><BR>\n- <A HREF=\"http://www.gnu.org\"><FONT COLOR=\"#000000\">The GNU Project</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"/news/2000/01/29/\"><font color=\"#000000\">saturday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"/news/2000/01/29/949208399.html\"><FONT COLOR=\"#000000\">We should get this out of the door now</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949208340.html\"><FONT COLOR=\"#000000\">Is Linux for Crazies?</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949188564.html\"><FONT COLOR=\"#000000\">RabbIT 2.0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949187896.html\"><FONT COLOR=\"#000000\">nmpg 1.1.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949187471.html\"><FONT COLOR=\"#000000\">mod_dtcl 0.7.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949187233.html\"><FONT COLOR=\"#000000\">CoreLinux++ 0.4.6</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949165962.html\"><FONT COLOR=\"#000000\">scribe 0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949165472.html\"><FONT COLOR=\"#000000\">E theme updater 0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949165416.html\"><FONT COLOR=\"#000000\">Powertweak-Linux 0.1.7</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164956.html\"><FONT COLOR=\"#000000\">Pexeso Beta</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164896.html\"><FONT COLOR=\"#000000\">XZX 2.9.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164869.html\"><FONT COLOR=\"#000000\">DistroLib 0.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164843.html\"><FONT COLOR=\"#000000\">ToutDoux 1.1.7</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164772.html\"><FONT COLOR=\"#000000\">goMP 1.0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164633.html\"><FONT COLOR=\"#000000\">APSEND 1.40</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164529.html\"><FONT COLOR=\"#000000\">ecasound 1.6.12r10</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164394.html\"><FONT COLOR=\"#000000\">SCEZ 20000129</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164350.html\"><FONT COLOR=\"#000000\">Comicq 0.2.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949164259.html\"><FONT COLOR=\"#000000\">senv 0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949161354.html\"><FONT COLOR=\"#000000\">XZX 2.9.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949161036.html\"><FONT COLOR=\"#000000\">log4j 0.7.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949156343.html\"><FONT COLOR=\"#000000\">SQN Linux 1.6</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949156277.html\"><FONT COLOR=\"#000000\">Limo 0.3.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949156237.html\"><FONT COLOR=\"#000000\">Fusion GS 1.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949145887.html\"><FONT COLOR=\"#000000\">MMR 1.5.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949142835.html\"><FONT COLOR=\"#000000\">KUPS 0.3.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949142815.html\"><FONT COLOR=\"#000000\">3DSE patch for XMMS 4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949139763.html\"><FONT COLOR=\"#000000\">Linux 2.3.41</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949139751.html\"><FONT COLOR=\"#000000\">Free Code for Linux S/390</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135979.html\"><FONT COLOR=\"#000000\">CircleMUD 3.0 beta patchlevel 17</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135938.html\"><FONT COLOR=\"#000000\">NiL Isn't Liero 000128</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135913.html\"><FONT COLOR=\"#000000\">OpenSSH Unix Port 1.2.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135889.html\"><FONT COLOR=\"#000000\">KBoxes! 1.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135867.html\"><FONT COLOR=\"#000000\">phpLanParty 0.23</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135509.html\"><FONT COLOR=\"#000000\">DGen/SDL 1.20</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135482.html\"><FONT COLOR=\"#000000\">EdcomLib 1.0 alpha 5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135309.html\"><FONT COLOR=\"#000000\">Etherboot 4.4.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135205.html\"><FONT COLOR=\"#000000\">BLADE 0.18.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135115.html\"><FONT COLOR=\"#000000\">Sapphire 0.13.7</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949135070.html\"><FONT COLOR=\"#000000\">ippl 1.99.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134977.html\"><FONT COLOR=\"#000000\">Saint 1.5patch1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134943.html\"><FONT COLOR=\"#000000\">Zircon 1.18.232</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134927.html\"><FONT COLOR=\"#000000\">nmap 2.3BETA14</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134901.html\"><FONT COLOR=\"#000000\">xterm patch #124</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134817.html\"><FONT COLOR=\"#000000\">MyThreads-Links v0.5.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134633.html\"><FONT COLOR=\"#000000\">sudo 1.6.2p1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134552.html\"><FONT COLOR=\"#000000\">MIT Photonic-Bands 0.10</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134246.html\"><FONT COLOR=\"#000000\">Launcher 0.86</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134179.html\"><FONT COLOR=\"#000000\">nano 0.8.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134103.html\"><FONT COLOR=\"#000000\">Gtk-- 1.1.8</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949134049.html\"><FONT COLOR=\"#000000\">tkchooser 0.65</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949133420.html\"><FONT COLOR=\"#000000\">XShipWars 1.33a</FONT></A><BR>\n- <A HREF=\"/news/2000/01/29/949133280.html\"><FONT COLOR=\"#000000\">Lamerpad 0.1</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"/news/2000/01/28/\"><font color=\"#000000\">friday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"/news/2000/01/28/949117833.html\"><FONT COLOR=\"#000000\">fsv 0.9</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949117711.html\"><FONT COLOR=\"#000000\">popsneaker 0.1.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949114716.html\"><FONT COLOR=\"#000000\">eyep-updater.sh 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949113240.html\"><FONT COLOR=\"#000000\">W3Mail 0.5.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949113214.html\"><FONT COLOR=\"#000000\">The Urgent Decision 0.9.9</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949112269.html\"><FONT COLOR=\"#000000\">LTSP 1.02</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949112198.html\"><FONT COLOR=\"#000000\">Production BASIC 0.2.12</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949112123.html\"><FONT COLOR=\"#000000\">Postfix 19991231-pl03</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949109732.html\"><FONT COLOR=\"#000000\">Mp3 Commander 0.7</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949109324.html\"><FONT COLOR=\"#000000\">iManager 1.0.1b</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949108399.html\"><FONT COLOR=\"#000000\">Eterm 0.9</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949108308.html\"><FONT COLOR=\"#000000\">dqd_dirindex 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949108087.html\"><FONT COLOR=\"#000000\">Tidings 1.0.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949108026.html\"><FONT COLOR=\"#000000\">localscan 2.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949107922.html\"><FONT COLOR=\"#000000\">WMKeyboard 0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949107834.html\"><FONT COLOR=\"#000000\">fcmp 1.0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949107767.html\"><FONT COLOR=\"#000000\">Akkord 0.3.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949107649.html\"><FONT COLOR=\"#000000\">HiM 0.1.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949106305.html\"><FONT COLOR=\"#000000\">cdrecord 1.8</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949103400.html\"><FONT COLOR=\"#000000\">eMixer 0.05.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949103187.html\"><FONT COLOR=\"#000000\">FreeVSD 1.4.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949103096.html\"><FONT COLOR=\"#000000\">Common C++ Libraries 0.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949095155.html\"><FONT COLOR=\"#000000\">Moonshine 1.0beta2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949095112.html\"><FONT COLOR=\"#000000\">swim 0.3.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949095009.html\"><FONT COLOR=\"#000000\">Xmame/xmess 0.36b15.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949094448.html\"><FONT COLOR=\"#000000\">pcmcia-cs 3.1.9</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949091509.html\"><FONT COLOR=\"#000000\">gPS 0.5.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949091415.html\"><FONT COLOR=\"#000000\">Snort 1.5.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949090436.html\"><FONT COLOR=\"#000000\">Pygmy Linux 0.7 beta</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949090237.html\"><FONT COLOR=\"#000000\">Intro to Bash Programming HOWTO 0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949084379.html\"><FONT COLOR=\"#000000\">GNU Pth 1.3b2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949084356.html\"><FONT COLOR=\"#000000\">Laonux 0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949084304.html\"><FONT COLOR=\"#000000\">x-wvdial 0.12</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949084188.html\"><FONT COLOR=\"#000000\">Intro to Bash Programming HOWTO 0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949084106.html\"><FONT COLOR=\"#000000\">Catalog 1.02</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949084062.html\"><FONT COLOR=\"#000000\">harvest 1.5.20-kj-0.9</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949068306.html\"><FONT COLOR=\"#000000\">wmseti 0.3.0a</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949057272.html\"><FONT COLOR=\"#000000\">RIG 1.02</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949057019.html\"><FONT COLOR=\"#000000\">FreeAddr 0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949056939.html\"><FONT COLOR=\"#000000\">GtkAda 1.2.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949056664.html\"><FONT COLOR=\"#000000\">dot.conf 0.6.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949055099.html\"><FONT COLOR=\"#000000\">dep.pl 1.28.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949054980.html\"><FONT COLOR=\"#000000\">Prae's Scripts 1.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949044301.html\"><FONT COLOR=\"#000000\">Project Clock 0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949044285.html\"><FONT COLOR=\"#000000\">Xtheater 0.2.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949040013.html\"><FONT COLOR=\"#000000\">i-no Chart 0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949039945.html\"><FONT COLOR=\"#000000\">spliff 0.8.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949038953.html\"><FONT COLOR=\"#000000\">Regexx 0.95</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949038316.html\"><FONT COLOR=\"#000000\">RBook 0.5.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949036742.html\"><FONT COLOR=\"#000000\">RIG 1.01</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949036714.html\"><FONT COLOR=\"#000000\">wchat 1.2.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/28/949036428.html\"><FONT COLOR=\"#000000\">PCCS MySQLDatabase Admin Tool 1.2.2</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"/news/2000/01/27/\"><font color=\"#000000\">thursday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"/news/2000/01/27/949033332.html\"><FONT COLOR=\"#000000\">CADUBI 1.1b1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949032987.html\"><FONT COLOR=\"#000000\">Angus' Chess Clock 0.8.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949032555.html\"><FONT COLOR=\"#000000\">MP3 Report Generator 1.0.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949032518.html\"><FONT COLOR=\"#000000\">4DOM 0.9.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949032386.html\"><FONT COLOR=\"#000000\">4XSLT 0.8.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949031346.html\"><FONT COLOR=\"#000000\">OpenNaken 1.10</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949025747.html\"><FONT COLOR=\"#000000\">iManager 1.0b</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949025168.html\"><FONT COLOR=\"#000000\">QuakeForge 0.1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949023271.html\"><FONT COLOR=\"#000000\">pylice 0.7.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949023250.html\"><FONT COLOR=\"#000000\">Solfege 0.6.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949023151.html\"><FONT COLOR=\"#000000\">xinetd 2.1.8.7p1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949022849.html\"><FONT COLOR=\"#000000\">jac 0.13</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949022803.html\"><FONT COLOR=\"#000000\">Xmms 1.0.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949022319.html\"><FONT COLOR=\"#000000\">KSrnd 0.97</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949021877.html\"><FONT COLOR=\"#000000\">getpg / UW-IMAP 0.54</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949021849.html\"><FONT COLOR=\"#000000\">getpg 0.53</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949021824.html\"><FONT COLOR=\"#000000\">setserial 2.17</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949021250.html\"><FONT COLOR=\"#000000\">Pan 0.7.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949021216.html\"><FONT COLOR=\"#000000\">jwhois 2.4.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949021126.html\"><FONT COLOR=\"#000000\">Kmp3 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949020964.html\"><FONT COLOR=\"#000000\">xPine 0.0.12</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949019905.html\"><FONT COLOR=\"#000000\">Avenger's News System 2.1 Alpha</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949019709.html\"><FONT COLOR=\"#000000\">RIG 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949019321.html\"><FONT COLOR=\"#000000\">scroller 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949018347.html\"><FONT COLOR=\"#000000\">Perl EyeP Client 0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949017796.html\"><FONT COLOR=\"#000000\">sfront 0.54</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949017631.html\"><FONT COLOR=\"#000000\">XFrisk 1.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949016202.html\"><FONT COLOR=\"#000000\">Moffy 0.0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949015348.html\"><FONT COLOR=\"#000000\">Solid POP3 0.14</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949014200.html\"><FONT COLOR=\"#000000\">php3guest 1.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949013630.html\"><FONT COLOR=\"#000000\">crUD 01.27.2000</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949013380.html\"><FONT COLOR=\"#000000\">crUD 01.27.2000</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949012979.html\"><FONT COLOR=\"#000000\">Free Pascal Compiler 0.99.14</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949012771.html\"><FONT COLOR=\"#000000\">gtk-font-hack 0.2-gtk-1.2.6</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949009233.html\"><FONT COLOR=\"#000000\">Linux 2.2.15pre5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/949005620.html\"><FONT COLOR=\"#000000\">krunseti 0.2.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948996446.html\"><FONT COLOR=\"#000000\">CompuPic 5.0.1036</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948995905.html\"><FONT COLOR=\"#000000\">gfontview 0.3.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948995819.html\"><FONT COLOR=\"#000000\">authlocal 1.0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948995600.html\"><FONT COLOR=\"#000000\">bigwig 1.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948995501.html\"><FONT COLOR=\"#000000\">CAFire 0.0.11</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948995429.html\"><FONT COLOR=\"#000000\">ANVLOGIN 2.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994944.html\"><FONT COLOR=\"#000000\">sawmill.el 1.9</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994810.html\"><FONT COLOR=\"#000000\">Perlsh 20000127</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994776.html\"><FONT COLOR=\"#000000\">sitescooper 2.1.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994691.html\"><FONT COLOR=\"#000000\">MHDns 1.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994419.html\"><FONT COLOR=\"#000000\">JChemPaint 0.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994364.html\"><FONT COLOR=\"#000000\">Filesystems HOWTO 0.7.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948994343.html\"><FONT COLOR=\"#000000\">KSnes9x 1.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948993513.html\"><FONT COLOR=\"#000000\">Mozilla M13</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948993439.html\"><FONT COLOR=\"#000000\">edna 0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948993409.html\"><FONT COLOR=\"#000000\">GMasqdialer 0.99.8</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948993341.html\"><FONT COLOR=\"#000000\">spliff 0.8</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948992808.html\"><FONT COLOR=\"#000000\">MultiSeti 0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970667.html\"><FONT COLOR=\"#000000\">rude 0.50</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970605.html\"><FONT COLOR=\"#000000\">cgi-util++ 0.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970479.html\"><FONT COLOR=\"#000000\">Cricket 0.72</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970458.html\"><FONT COLOR=\"#000000\">nuni 0.04</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970379.html\"><FONT COLOR=\"#000000\">Ksetiwatch 0.3.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970358.html\"><FONT COLOR=\"#000000\">SiteMgrYAP 0.1.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970322.html\"><FONT COLOR=\"#000000\">phpLanParty 0.21</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970285.html\"><FONT COLOR=\"#000000\">Glitter Newsreader 0.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970263.html\"><FONT COLOR=\"#000000\">Fastresolve 2.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970164.html\"><FONT COLOR=\"#000000\">ColdSync 1.1.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970080.html\"><FONT COLOR=\"#000000\">DDD 3.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948970032.html\"><FONT COLOR=\"#000000\">X Northern Captain 4.2.1</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969919.html\"><FONT COLOR=\"#000000\">abcde 1.0.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969659.html\"><FONT COLOR=\"#000000\">Gnapster 1.3.2</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969551.html\"><FONT COLOR=\"#000000\">xmix 1.0 Alpha</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969488.html\"><FONT COLOR=\"#000000\">gtktetcolor 0.3</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969412.html\"><FONT COLOR=\"#000000\">muttzilla 0.40</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969395.html\"><FONT COLOR=\"#000000\">muttzilla 0.40</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969337.html\"><FONT COLOR=\"#000000\">asp2php 0.73.6</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969217.html\"><FONT COLOR=\"#000000\">mod_ticket 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948969078.html\"><FONT COLOR=\"#000000\">MegaHAL for Eggdrop .01</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948968456.html\"><FONT COLOR=\"#000000\">Jetty 2.3.5</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948968386.html\"><FONT COLOR=\"#000000\">xlpotdb 1.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948968341.html\"><FONT COLOR=\"#000000\">Koala Complete MUD Server 0.1.1a</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948968255.html\"><FONT COLOR=\"#000000\">mcountd 0.4</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948967933.html\"><FONT COLOR=\"#000000\">cdbackup 0.5.0</FONT></A><BR>\n- <A HREF=\"/news/2000/01/27/948967908.html\"><FONT COLOR=\"#000000\">The Java SSH/Telnet Application/Applet 2.0 RC1</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"http://slashdot.org\"><font color=\"#000000\">slashdot</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/29/1534255\"><FONT COLOR=\"#000000\">Petition Apple for Linux QuickTime</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/29/1223249\"><FONT COLOR=\"#000000\">GNUstep 0.6.5 freeze</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/28/2324203\"><FONT COLOR=\"#000000\">YETI@Home</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/29/1024215\"><FONT COLOR=\"#000000\">Documents Unsealed in Microsoft/Caldera Case</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/29/0837235\"><FONT COLOR=\"#000000\">Who Bought Linux.Net?</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/24/1146250\"><FONT COLOR=\"#000000\">E-Mails from (Over?) The Edge</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/29/0834223\"><FONT COLOR=\"#000000\">Linux Kernel 2.3.41</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/28/2311232\"><FONT COLOR=\"#000000\">Congress Still Figuring Out E-Mail</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/22/1946244\"><FONT COLOR=\"#000000\">Sci Fi Literature 101?</FONT></A><BR>\n- <A HREF=\"http://slashdot.org/article.pl?sid=00/01/28/2318246\"><FONT COLOR=\"#000000\">Could Distributed.Net Help the Mars Polar Lander?</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"http://www.securityfocus.com\"><font color=\"#000000\">securityfocus</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://www.securityfocus.com/level2/?go=news&id=http://www.zdnet.com/zdnn/stories/news/0,4586,2429334,00.html?chkpt=zdnntop\"><FONT COLOR=\"#000000\">Win2000 security hole a 'major threat'</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=news&id=http://www.computerworld.com/home/print.nsf/all/000128e45a\"><FONT COLOR=\"#000000\">Visa acknowledges cracker break-ins</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=news&id=http://www.zdnet.com/sr/stories/column/0,4712,2429536,00.html\"><FONT COLOR=\"#000000\">What's Wrong With Microsoft  Security?</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=news&id=http://www.zdnet.com/pcweek/stories/news/0,4153,2429334,00.html\"><FONT COLOR=\"#000000\">Microsoft posts first Win2K security patch</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=tools&id=1018\"><FONT COLOR=\"#000000\">Libnids 1.12</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=news&id=http://www.theregister.co.uk/000127-000005.html\"><FONT COLOR=\"#000000\">New hack attack is greater threat than imagined</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=news&id=http://www.mercurycenter.com/svtech/news/indepth/docs/hacker012700.htm\"><FONT COLOR=\"#000000\">Student charged with hacking</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=library&id=63\"><FONT COLOR=\"#000000\">Building and Managing Virtual Private Networks (book)</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=library&id=111\"><FONT COLOR=\"#000000\">Threats, Vulnerabilities and Real-Worl Responses: The Foundations of the TruSecure Process</FONT></A><BR>\n- <A HREF=\"http://www.securityfocus.com/level2/?go=library&id=1701\"><FONT COLOR=\"#000000\">The Hundredth Window : Protecting Your Privacy and Security in the Age of the Internet (boo</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"http://www.bebits.com\"><font color=\"#000000\">bebits</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://www.bebits.com/app/706/\"><FONT COLOR=\"#000000\">Pe 3.0a3</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/757/\"><FONT COLOR=\"#000000\">Rarscript 1.5</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/736/\"><FONT COLOR=\"#000000\">CD Manager 0.66a beta</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/174/\"><FONT COLOR=\"#000000\">TraX 1.1</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/785/\"><FONT COLOR=\"#000000\">BeMath 1.2.2</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/784/\"><FONT COLOR=\"#000000\">simple blackjack 1</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/758/\"><FONT COLOR=\"#000000\">HtmlTree 0.5.3</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/783/\"><FONT COLOR=\"#000000\">Yacp 0.1</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/222/\"><FONT COLOR=\"#000000\">TicTacToe 1.5</FONT></A><BR>\n- <A HREF=\"http://www.bebits.com/app/706/\"><FONT COLOR=\"#000000\">Pe 3.0a2</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"http://linuxtoday.com\"><font color=\"#000000\">linuxtoday</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://linuxtoday.com/story.php3?sn=15878\"><FONT COLOR=\"#000000\">Linux Journal: KDE--The Next Generation</FONT></A><BR>\n- <A HREF=\"http://linuxtoday.com/story.php3?sn=15876\"><FONT COLOR=\"#000000\">Kernel Cousin gimp-devel #11 Is Out</FONT></A><BR>\n- <A HREF=\"http://linuxtoday.com/story.php3?sn=15875\"><FONT COLOR=\"#000000\">Infoworld: Corel Linux OS ideal for the desktop</FONT></A><BR>\n- <A HREF=\"http://linuxtoday.com/story.php3?sn=15874\"><FONT COLOR=\"#000000\">Technology Evaluation: IBM Jumps on the Linux Bandwagon with Both Feet, Sort Of</FONT></A><BR>\n- <A HREF=\"http://linuxtoday.com/story.php3?sn=15873\"><FONT COLOR=\"#000000\">Tobias Hvekamp: European Union acknowledges</FONT></A><BR>\n- <A HREF=\"\"><FONT COLOR=\"#000000\">&</FONT></A><BR>\n- <A HREF=\"\"><FONT COLOR=\"#000000\">#34;Open Source Software</FONT></A><BR>\n- <A HREF=\"\"><FONT COLOR=\"#000000\">&</FONT></A><BR>\n- <A HREF=\"\"><FONT COLOR=\"#000000\">#34;</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"http://www.linuxtelephony.org\"><font color=\"#000000\">linuxtelephony</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=208&r=0\"><FONT COLOR=\"#000000\">Traverse Technologies releases NETspider-U in US</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=207&r=0\"><FONT COLOR=\"#000000\">Quicknet releases new GPL'd Linux Drivers!</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=206&r=0\"><FONT COLOR=\"#000000\">Natural Microsystems Delivers Carrier-Class Linux</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=205&r=0\"><FONT COLOR=\"#000000\">Quicknet is hiring programmers of all kinds!</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=204&r=0\"><FONT COLOR=\"#000000\">Babylon MLPPP Software Released under GPL</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=202&r=0\"><FONT COLOR=\"#000000\">Linux Telephony Server Project?</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=203&r=0\"><FONT COLOR=\"#000000\">Vovida Networks to Hire Telephony Software Engineers</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=200&r=0\"><FONT COLOR=\"#000000\">SPIRO-Linux Introduces Web-Enabled Phone Administration</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=199&r=0\"><FONT COLOR=\"#000000\">LinuxTelephony sponsors area at LinuxFest 2000</FONT></A><BR>\n- <A HREF=\"http://www.linuxtelephony.org/article.cgi?i=198&r=0\"><FONT COLOR=\"#000000\">GSM-Mobile Switching Center (MSC) with Linux-PC</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<TABLE BORDER=\"0\" CELLPADDING=\"1\" CELLSPACING=\"0\" BGCOLOR=\"#000000\" WIDTH=\"97%\"><TR><TD>\n<TABLE WIDTH=\"100%\" BORDER=\"0\" CELLSPACING=\"1\" CELLPADDING=\"3\">\n<TR><TD ALIGN=\"center\" BGCOLOR=\"#EEEEEE\"><B><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><FONT COLOR=\"#000000\"><a href=\"http://www.32bitsonline.com\"><font color=\"#000000\">32bitsonline</font></a></FONT></FONT></B></TD></TR><TR><TD BGCOLOR=\"#FFFFFF\"><SMALL><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\">\n- <A HREF=\"http://www.32bitsonline.com/article.php3?file=issues/200001/homeworld&page=1\n\"><FONT COLOR=\"#000000\">Game: Homeworld</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/news.php3?news=news/200001/nb200001271a&page=1\n\"><FONT COLOR=\"#000000\">DVD Lawsuit Spreads Its Own 'Trade Secrets'</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/news.php3?news=news/200001/nb200001272&page=1\n\"><FONT COLOR=\"#000000\">Register.com Adds 'One-step' Domain Registration</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/article.php3?file=issues/200001/webevent&page=1\n\"><FONT COLOR=\"#000000\">WebEvent: Keeping you organized</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/news.php3?news=news/200001/nb200001273a&page=1\n\"><FONT COLOR=\"#000000\">Y2K Officers Defend $100 Bil Investment</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/article.php3?file=issues/200001/jan2000_john_berger&page=1\n\"><FONT COLOR=\"#000000\">DON'T BE FOOLED</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/news.php3?news=news/200001/nb200001274&page=1\n\"><FONT COLOR=\"#000000\">Microsoft Scorns Think-Tank's Breakup Idea</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/news.php3?news=news/200001/nb200001275a&page=1\n\"><FONT COLOR=\"#000000\">Yahoo Accused Of Stalking Internet Users</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/news.php3?news=news/200001/nb200001276a&page=1\n\"><FONT COLOR=\"#000000\">eToys.com Settles Spat With Swiss Artist Group</FONT></A><BR>\n- <A HREF=\"http://www.32bitsonline.com/\n\"><FONT COLOR=\"#000000\">[more articles/news]</FONT></A><BR>\n&nbsp;</FONT></SMALL></TD></TR></TABLE></TD></TR></TABLE><P>\n<BR><BR></FONT>\n</TD></TR></TABLE>\n<TABLE WIDTH=\"100%\" CELLPADDING=\"0\" CELLSPACING=\"0\" BORDER=\"0\">\n<TR BGCOLOR=\"#000000\"><TD><IMG SRC=\"image4\" WIDTH=\"1\" HEIGHT=\"2\" ALT=\"\"></TD></TR></TABLE>\n</CENTER>\n<TABLE CELLSPACING=\"0\" CELLPADDING=\"2\" WIDTH=\"100%\" BORDER=\"0\"><TR>\n<TD VALIGN=\"top\" ALIGN=\"center\"><FONT FACE=\"Lucida,Verdana,Helvetica,Arial\"><SMALL>copyright  1997-2000 <A HREF=\"http://andover.net\">Andover.Net</A> -\nicons courtesy of <A HREF=\"mailto:tigert@gimp.org\">tigert@gimp.org</A> -\ncode revision <A HREF=\"http://freshmeat.net/ChangeLog\">20000101</A> -\nour <A HREF=\"http://www.andover.net/privacy.html\">privacy policy</A></SMALL></FONT></TD>\n</TR></TABLE>\n</BODY>\n</HTML>\n\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkHTML/ss.rb",
    "content": "#!/usr/bin/env ruby\n#\n# This script implements the \"ss\" application.  \"ss\" implements\n# a presentation slide-show based on HTML slides.\n# \nrequire 'tk'\nrequire 'tkextlib/tkHTML'\n\nfile = ARGV[0]\n\nclass TkHTML_File_Viewer\n  include TkComm\n\n# These are images to use with the actual image specified in a\n# \"<img>\" markup can't be found.\n#\n@@biggray = TkPhotoImage.new(:data=><<'EOD')\n    R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm\n    6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO///\nEOD\n\n@@smgray = TkPhotoImage.new(:data=><<'EOD')\n    R0lGODdhOAAYAPAAALi4uAAAACwAAAAAOAAYAAACI4SPqcvtD6OctNqLs968+w+G4kiW5omm\n    6sq27gvH8kzX9m0VADv/\nEOD\n\n  def initialize(file = nil)\n    @root  = TkRoot.new(:title=>'HTML File Viewer', :iconname=>'HV')\n    @fswin = nil\n\n    @html = nil\n    @html_fs = nil\n\n    @hotkey = {}\n\n    @applet_arg = TkVarAccess.new_hash('AppletArg')\n\n    @images   = {}\n    @old_imgs = {}\n    @big_imgs = {}\n\n    @last_dir = Dir.pwd\n\n    @last_file = ''\n\n    @key_block = false\n\n    Tk::HTML_Widget::ClippingWindow.bind('1', \n                                         proc{|w, ksym| key_press(w, ksym)}, \n                                         '%W Down')\n    Tk::HTML_Widget::ClippingWindow.bind('3', \n                                         proc{|w, ksym| key_press(w, ksym)}, \n                                         '%W Up')\n    Tk::HTML_Widget::ClippingWindow.bind('2', \n                                         proc{|w, ksym| key_press(w, ksym)}, \n                                         '%W Down')\n\n    Tk::HTML_Widget::ClippingWindow.bind('KeyPress', \n                                         proc{|w, ksym| key_press(w, ksym)}, \n                                         '%W %K')\n\n    ############################################\n    #\n    # Build the half-size view of the page\n    #\n    menu_spec = [\n      [['File', 0], \n        ['Open',        proc{sel_load()},   0], \n        ['Full Screen', proc{fullscreen()}, 0], \n        ['Refresh',     proc{refresh()},    0], \n        '---',\n        ['Exit', proc{exit}, 1]]\n    ]\n\n    mbar = @root.add_menubar(menu_spec)\n\n    @html = Tk::HTML_Widget.new(:width=>512, :height=>384, \n                                :padx=>5, :pady=>9, \n                                :formcommand=>proc{|*args| form_cmd(*args)},\n                                :imagecommand=>proc{|*args|\n                                  image_cmd(1, *args)\n                                }, \n                                :scriptcommand=>proc{|*args|\n                                  script_cmd(*args)\n                                }, \n                                :appletcommand=>proc{|*args|\n                                  applet_cmd(*args)\n                                }, \n                                :hyperlinkcommand=>proc{|*args| \n                                  hyper_cmd(*args)\n                                }, \n                                :fontcommand=>proc{|*args|\n                                  pick_font(*args)\n                                }, \n                                :appletcommand=>proc{|*args|\n                                  run_applet('small', *args)\n                                }, \n                                :bg=>'white', :tablerelief=>:raised)\n\n    @html.token_handler('meta', proc{|*args| meta(@html, *args)})\n\n    vscr = @html.yscrollbar(TkScrollbar.new)\n    hscr = @html.xscrollbar(TkScrollbar.new)\n\n    Tk.grid(@html, vscr, :sticky=>:news)\n    Tk.grid(hscr,       :sticky=>:ew)\n    @root.grid_columnconfigure(0, :weight=>1)\n    @root.grid_columnconfigure(1, :weight=>0)\n    @root.grid_rowconfigure(0, :weight=>1)\n    @root.grid_rowconfigure(1, :weight=>0)\n\n    ############################################\n\n    @html.clipwin.focus\n\n    # If an arguent was specified, read it into the HTML widget.\n    #\n    Tk.update\n    if file && file != \"\"\n      load_file(file)\n    end\n  end\n\n  #\n  # A font chooser routine.\n  #\n  # html[:fontcommand] = pick_font\n  def pick_font(size, attrs)\n    # puts \"FontCmd: #{size} #{attrs}\"\n    [ ((attrs =~ /fixed/)? 'courier': 'charter'), \n      (12 * (1.2**(size.to_f - 4.0))).to_i, \n      ((attrs =~ /italic/)? 'italic': 'roman'), \n      ((attrs =~ /bold/)? 'bold': 'normal') ].join(' ')\n  end\n\n  # This routine is called to pick fonts for the fullscreen view.\n  #\n  def pick_font_fs(size, attrs)\n    baseFontSize = 24\n\n    # puts \"FontCmd: #{size} #{attrs}\"\n    [ ((attrs =~ /fixed/)? 'courier': 'charter'), \n      (baseFontSize * (1.2**(size.to_f - 4.0))).to_i, \n      ((attrs =~ /italic/)? 'italic': 'roman'), \n      ((attrs =~ /bold/)? 'bold': 'normal')  ].join(' ')\n  end\n\n  #\n  #\n  def hyper_cmd(*args)\n    puts \"HyperlinkCommand: #{args.inspect}\"\n  end\n\n  # This routine is called to run an applet\n  #\n  def run_applet(size, w, arglist)\n    applet_arg.value = Hash[*simplelist(arglist)]\n\n    return unless @applet_arg.key?('src')\n\n    src = @html.remove(@applet_arg['src'])\n\n    @applet_arg['window'] = w\n    @applet_arg['fontsize'] = size\n\n    begin\n      Tk.load_tclscript(src)\n    rescue => e\n      puts \"Applet error: #{e.message}\"\n    end\n  end\n\n  #\n  #\n  def form_cmd(n, cmd, *args)\n    # p [n, cmd, *args]\n  end\n\n  #\n  #\n  def move_big_image(b)\n    return unless @big_imgs.key?(b)\n    b.copy(@big_imgs[b])\n    @big_imgs[b].delete\n    @big_imgs.delete(b)\n  end\n\n  def image_cmd(hs, *args)\n    fn = args[0]\n\n    if @old_imgs.key?(fn)\n      return (@images[fn] = @old_imgs.delete(fn))\n    end\n\n    begin\n      img = TkPhotoImage.new(:file=>fn)\n    rescue\n      return ((hs)? @@smallgray: @@biggray)\n    end\n\n    if hs\n      img2 = TkPhotoImage.new\n      img2.copy(img, :subsample=>[2,2])\n      img.delete\n      img = img2\n    end\n\n    if img.width * img.height > 20000\n      b = TkPhotoImage.new(:width=>img.width, :height=>img.height)\n      @big_imgs[b] = img\n      img = b\n      Tk.after_idle(proc{ move_big_image(b) })\n    end\n\n    @images[fn] = img\n\n    img\n  end\n\n  #\n  # This routine is called for every <SCRIPT> markup\n  #\n  def script_cmd(*args)\n    # puts \"ScriptCmd: #{args.inspect}\"\n  end\n\n  # This routine is called for every <APPLET> markup\n  #\n  def applet_cmd(w, arglist)\n    # puts \"AppletCmd: w=#{w} arglist=#{arglist}\"\n    #TkLabel.new(w, :text=>\"The Applet #{w}\", :bd=>2, :relief=>raised)\n  end\n\n  # This binding fires when there is a click on a hyperlink\n  #\n  def href_binding(w, x, y)\n    lst = w.href(x, y)\n    unless lst.empty?\n      process_url(lst)\n    end\n  end\n\n  #\n  #\n  def sel_load\n    filetypes = [\n      ['Html Files', ['.html', '.htm']], \n      ['All Files', '*']\n    ]\n\n    f = Tk.getOpenFile(:initialdir=>@last_dir, :filetypes=>filetypes)\n    if f != ''\n      load_file(f)\n      @last_dir = File.dirname(f)\n    end\n  end\n\n  # Clear the screen.\n  #\n  def clear_screen\n    if @html_fs && @html_fs.exist?\n      w = @html_fs\n    else\n      w = @html\n    end\n    w.clear\n    @old_imgs.clear\n    @big_imgs.clear\n    @hotkey.clear\n    @images.each{|k, v| @old_imgs[k] = v }\n    @images.clear\n  end\n\n  # Read a file\n  #\n  def read_file(name)\n    begin\n      fp = open(name, 'r')\n      ret = fp.read(File.size(name))\n    rescue\n      ret = nil\n      fp = nil\n      Tk.messageBox(:icon=>'error', :message=>\"fail to open '#{name}'\", \n                    :type=>:ok)\n    ensure\n      fp.close if fp\n    end\n    ret\n  end\n\n  # Process the given URL\n  #\n  def process_url(url)\n    case url[0]\n    when /^file:/\n      load_file(url[0][5..-1])\n    when /^exec:/\n      Tk.ip_eval(url[0][5..-1].tr('\\\\', ' '))\n    else\n      load_file(url[0])\n    end\n  end\n\n  # Load a file into the HTML widget\n  #\n  def load_file(name)\n    return unless (doc = read_file(name))\n    clear_screen()\n    @last_file = name\n    if @html_fs && @html_fs.exist?\n      w = @html_fs\n    else\n      w = @html\n    end\n    w.configure(:base=>name)\n    w.parse(doc)\n    w.configure(:cursor=>'top_left_arrow')\n    @old_imgs.clear\n  end\n\n  # Refresh the current file.\n  #\n  def refresh(*args)\n    load_file(@last_file) if @last_file\n  end\n\n  # This routine is called whenever a \"<meta>\" markup is seen.\n  #\n  def meta(w, tag, alist)\n    v = Hash[*simplelist(alist)]\n\n    if v.key?('key') && v.key?('href')\n      @hotkey[v['key']] = w.resolve(v['href'])\n    end\n\n    if v.key?('next')\n      @hotkey['Down'] =v['next']\n    end\n\n    if v.key?('prev')\n      @hotkey['Up'] =v['prev']\n    end\n\n    if v.key?('other')\n      @hotkey['o'] =v['other']\n    end\n  end\n\n  # Go from full-screen mode back to window mode.\n  #\n  def fullscreen_off\n    @fswin.destroy\n    @root.deiconify\n    Tk.update\n    @root.raise\n    @html.clipwin.focus\n    clear_screen()\n    @old_imgs.clear\n    refresh()\n  end\n\n  # Go from window mode to full-screen mode.\n  #\n  def fullscreen\n    if @fswin && @fswin.exist?\n      @fswin.deiconify\n      Tk.update\n      @fswin.raise\n      return\n    end\n\n    width  =  @root.winfo_screenwidth\n    height =  @root.winfo_screenheight\n    @fswin = TkToplevel.new(:overrideredirect=>true, \n                            :geometry=>\"#{width}x#{height}+0+0\")\n\n    @html_fs = Tk::HTML_Widget.new(@fswin, :padx=>5, :pady=>9, \n                                   :formcommand=>proc{|*args|\n                                     form_cmd(*args)\n                                   },\n                                   :imagecommand=>proc{|*args| \n                                     image_cmd(0, *args)\n                                   }, \n                                   :scriptcommand=>proc{|*args|\n                                     script_cmd(*args)\n                                   }, \n                                   :appletcommand=>proc{|*args|\n                                     applet_cmd(*args)\n                                   }, \n                                   :hyperlinkcommand=>proc{|*args| \n                                     hyper_cmd(*args)\n                                   }, \n                                   :appletcommand=>proc{|*args|\n                                     run_applet('big', *args)\n                                   }, \n                                   :fontcommand=>proc{|*args|\n                                     pick_font_fs(*args)\n                                   }, \n                                   :bg=>'white', :tablerelief=>:raised, \n                                   :cursor=>:tcross) {\n      pack(:fill=>:both, :expand=>true)\n      token_handler('meta', proc{|*args| meta(self, *args)})\n    }\n\n    clear_screen()\n    @old_imgs.clear\n    refresh()\n    Tk.update\n    @html_fs.clipwin.focus\n  end\n\n  #\n  #\n  def key_press(w, keysym)\n    return if @key_block\n    @key_block = true\n    Tk.after(250, proc{@key_block = false})\n\n    if @hotkey.key?(keysym)\n      process_url(@hotkey[keysym])\n    end\n    case keysym\n    when 'Escape'\n      if @fswin && @fswin.exist?\n        fullscreen_off()\n      else\n        fullscreen()\n      end\n    end\n  end\nend\n############################################\n\nTkHTML_File_Viewer.new(file)\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkimg/demo.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  Tk::Img demo\n#\n#    --  This script is based on demo.tcl of Tcl/Tk's 'Img' extention. \n#        Image data in this script is those of demo.tcl.\n#        Please read 'license_terms_of_Img_extension' file.\n#\nrequire 'tk'\nrequire 'tkextlib/tkimg'\n\n#\n# Make the Image format available.\n#\nclass TkImg_demo\n  def initialize\n    img_version = Tk::Img.package_version\n\n    @typeFrame = Hash.new\n    @imgPriv = Hash.new\n\n    root = TkRoot.new(:title=>'Tests for available image formats')\n\n    root.winfo_children.each{|w| w.destroy}\n    TkImage.names{|img| img.delete}\n\n    f = TkFrame.new\n    TkButton.new(f, :text=>'Dismiss', :command=>proc{exit}).pack(:side=>:left)\n    f.pack(:side=>:top, :expand=>:y, :fill=>:both)\n\n    TkMessage.new(:aspect=>900, :text=>format('This page shows the available image formats of the Img extension (Img version %s, using Tcl/Tk %s)', img_version, Tk::TK_PATCHLEVEL)).pack(:side=>:top, :expand=>:y, :fill=>:both)\n  end\n\n##############################\n\n  def update_animated_gif(w, method, num)\n    return unless @imgPriv[w]\n\n    if @imgPriv[w][:args]\n      im = TkPhotoImage.new\n      im.copy(@imgPriv[w][num])\n      num += 1\n      begin\n        im.configure(@imgPriv[w][:args].merge(:format=>[:gif, {:index=>num}]))\n        im.configure(:data=>'', :file=>'') #free storage\n        @imgPriv[w][num] = im\n      rescue\n        @imgPriv[w].delete(:args)\n        if num > 1\n          num = 0\n          im = @imgPriv[w][num]\n        else\n          # this is not an animated GIF; just stop\n          @imgPriv[w].delete(0)\n          return\n        end\n      end\n    else\n      num += 1\n      num = 0 unless @imgPriv[w][num]\n      im = @imgPriv[w][num]\n    end\n    begin\n      w.__send__(method, im)\n      Tk.update_idletasks\n      Tk.after(20, proc{update_animated_gif(w, method, num)})\n    rescue\n      @imgPriv[w].delete(:args)\n      @imgPriv[w].each{|im|\n        @im.delete\n        @imgPriv.delete(im)\n      }\n    end\n  end\n\n  def show_animated_gif(keys)\n    w = TkLabel.new\n    begin\n      im = TkPhotoImage.new(keys.merge(:format=>[:gif, {:index=>0}]))\n      im.configure(:data=>'', :file=>'', :format=>'') #free storage\n      w.image(im)\n      @imgPriv[w] ||= Hash.new\n      @imgPriv[w][0] = im\n      @imgPriv[w][:args] = keys\n      Tk.update_idletasks\n      Tk.after(20, proc{update_animated_gif(w, :image, 0)})\n    rescue => e\n      w.configure(:text=>\"error displaying animated gif:\\n#{e.message}\", \n                  :image=>'', :relief=>:ridge)\n    end\n    w.pack\n  end\n\n  def show_image(fmt, type, data)\n    fmt = fmt.to_s.capitalize\n    unless @typeFrame[fmt]\n      @typeFrame[fmt] = TkFrame.new.pack(:side=>:top, :expand=>true, :fill=>:x)\n      TkLabel.new(@typeFrame[fmt], :text=>\"#{fmt} :  \").pack(:side=>:left)\n    end\n    begin\n      f = TkFrame.new(@typeFrame[fmt], \n                      :borderwidth=>2, :relief=>:ridge).pack(:side=>:left)\n      im = TkPhotoImage.new(:data=>data)\n      im['data'] = ''\n      TkLabel.new(f, :image=>im).pack\n      TkLabel.new(f, :text=>type, :borderwidth=>0, :pady=>0, :padx=>2, \n                  :font=>'Helvetica 8').pack\n    rescue => e\n      TkMessage.new(f, :text=>\"error displaying #{type} image: #{e.message}\", \n                    :aspect=>250).pack\n    end\n    Tk.update\n  end\n\nend\n\n##############\n\ndemo = TkImg_demo.new\n\n##############\n\ndemo.show_animated_gif(:data=><<'ENDofIMG')\nR0lGODlhYgIEAIIAAQAAACQAJEkASW0AbZIAkrYAttsA2/8A/yH/C05FVFNDQVBFMi4wAwEA\nAAAh+QQABgD/ACwAAAAAYgIEAAIDuUg63CMwwiCCvQAHwLv/YCiOZGmeaKqubOu+pZXNV03d\nkuAwysLoucjNlpFtYMikcslsOp+ijbRow1EiD12jtyA4INnJZGg8HmfQtHrNbrPP6KqlEgRq\nB17vzi6ukKVmHXBuhIWGh4RTcXJ0QQ8OeVx6XzlWVTRoiJqbnJ0tGmUXdDhgd1uTP2FCo5dT\ng56wsbKaoYBzVlimPJJ7QX9EirPCw8RttTZ1ul29Er81mMXR0tMvxzXJO1wAACH5BAAGAP8A\nLAAAAABiAgQAAgPdCLrc/jDKSau9OOuNAwjgB46kEJjnKazr0A5wTBDDbBc4buz74f/AoHBI\nLBqPSCGPh7M5abQYTOBysVYprAlFCo0+YI9CzCmbz+i0es1uu9/wOFrsqYtE3S73yq9SpTBP\nBDk5PEmHiImKRQYHTISDNjWTMX9UfFuZIFwkY3RhcqGio6SlpqeoqRt2dXmuWyqZV1Z/UjM1\nToQFS46Lvr/AQUu6BYK4gJe0V7Eprl+sXqrS09TV1tfYbKxhziqxmFOAgYKDOrs9wenqSY07\nuznklFKXmCzN3aB22fv81AAAIfkEAAYA/wAspgAAABgBBAACA+YIEQrNS61Jg1hX6C2GHiBI\nDERpFkShFkZrHHAsz3Rt06/Lrqk5jqFQ58PheI5B0s+HWrFch9dtSp26dDyULwnqeIoay+Qi\nrkAcZ4YDrVY/IOaxGGz0IkPLknN3rfr/MToGTilaJSRcR3RgikF5JyuDfYCUVFeDKj0mSkle\nQ4sYcXFvaA1rDxIScKIZYUVfiUA+PU6Tlbc4US07PJs/nYqLQ4kieZkqki24yzJXe5qziEHD\ndHNloqqpbqfcbquiGK2MH0mzkJG2zLfOhObSQsHC1OVKTLVQUurrWL1biZ9grIFLs2YbNwAh\n+QQABgD/ACyHAAAAVwEEAAID/ggQy94uyCloFTgPsYf/AyGOYmGaRnoYR+u+cCzPcZqeJyl6\nxMdhm4zwUgkUJ8iFkqFgKptQCQRJMRqJwqAPtCMVCDhDwcaimc9mslhs0vXeoJ9caL1Q748n\ntMl89PFURURXQx4cH11eYChjKmiPkC5kOGCVIyCYWkN2VoB8fXtOS34RgJybGkCZbosnZJGw\naCw3bF9tXSFxhqhXnb5JSUt6CsKlxneDqHIdqyEjOI0qZbHUMGq1bs6Yh3NDdb93U1Ki41Hi\npoSEqYZcuYphr9XykjbQrLnbHbwYEkd4xQ2GERvoZxQ6LIUOrWLlKtq8h5Ps6ci0SxknQOVE\nDdy4HvGPQVMIC1Hk4QZavIfUZq3J8YUEPl0WL3qaIIwjMQAh+QQABgD/ACxlAAAAmwEEAAID\n/ggRCr1qSSlWDVXorYfwQxgSxECSBVGsheEaB3zMdG3feF7DbsumJ5JJJPpwjhnLZMloPp4M\nh3RKrVqv2KxW2nRGmBQlBnP0dD7EYfDne8l08DjcbfgFhaW0cX8ciy9LD05RUREOhQ2GYEoa\nZGQbIGlDJmsqPy9ymZo0PD11Kyp3anogfX5igamGh1utrq+uhFBQYBm2j5CSIncnLHWYm8Fx\nbj52QZOSSBeNp2BfEIVeU4PUi0mOSJFoaXcpvnTC4TnExiejRdrK2IsSgrKIsPHyr4OJ7GHL\nthxmkSN4vZdauIghriCnF2yAmBOCzoiZPkkAOav3JEs0d+z0ZdPFMgvFJWAGCxL7pPBYHiJ8\nTElcNGuey5cwW97Dp6yDpBK82LgJaXAki47IGqq7xm4WPCoAACH5BAAGAP8ALEYAAADZAQQA\nAgP+GKC7yiHKGYSo1Wo9xPgfMYhEWRZoYaiGcbxwLM90Tbf4ihKFSYqgjnBDjFwuGMoD0Fgy\nn9CodEqtWq/YrHa7hTgaTSXySCZ6PMFQyJdC5Vy2uFz+VqV8pFH6czYfM0pKYF4MYE0OD4ET\nY4BEfHt6eDt2OAdwc5iZLzhtO3iQIBYdGhgWpYoTYUxOXK2ur7CxrV5fqBR/GWZDaT9sPG4s\nl5rDNi4tdpOfQGlno6SmSEkUiISDT4mJtYpkubq7Qb0mbSuVwsTnmzltPJ96oY9+uNGKiLWy\n9/j5+l3YqrZl3UT12YPnxLg36BLCULdOmbt38bjNC3TISSEqSyRQE1M8yo8QXiMk/XJTSaFC\nhg19gIp4auI0Vhf3yZxJUx8EbP/K6EIDLqSvgy1MJlSno0cPlcsg+gEkTZBGVlMAACH5BAAG\nAP8ALCYAAAAXAgQAAgP+CAHaHQtKKGioV+itRx/gQIBESRTnWRRGexhHLM90bd9127Jrao7A\nkMfDKVommMnisYwwHM+odEqtWq/YrHbL7Xq/YIaTCVEoj5YiZ8gmiX6l1UrnguHu+DvdIEeh\n4EJsAkRqGBoXZxJmEU2NYo9mYoyJFRwZG22Bbz99LHR5oKEydDxyPiUimiCDrIeViK9ni4wP\nkGG3uLm6u7y9tmO1iRKuGZeYmUDJJn18OqLPoKQ9fyZuga2Er4fCioqRTVFlZWTcxJVFQx9u\nyioqPM7Q8TbSptRBI0KthRvF3OLitnwJHEiwoMErk5jMOmMIVqFMIdjFmeMJhh15GF/o6HRK\nqhq+VayyWYLlr5GTcVjAlTS0DyIJOBPlfMqI0WKzeoA+htCnph+3SFAOCh1KtGivk/+EnWs5\nKJDEFMzg0ZS3BydMVSL5aStJ6woAIfkEAAYA/wAsBwAAAFUCBAACA/4ICqEd8MUJRQ0i65GH\nF55HEMM4FkShFgZrHHAsz3Rt10aer6s5lqEQqKPRYI6WI+XBYDYYi+diSq1ar9isdsvter/g\nsHhMLkebUEhziUkai8ROMOQ78Vy6m37Pf+1aPXUlJEJCcG9ubGpOaWlPUowSSxYZbW1FHCBz\ng3V3eC98oaIwfi07KCkmQIQfH4eUsBdLa4tnUma4ubq7vL2+v1mPUGiKE7GVh4V0Pz53pjmj\n0X06LD2oqqxBG4dKiRS0TrdTkcURlBWwmJqaIqsmqDw6oNL0NPKeddnaHJlwl0qKGgkTB6yg\nwYMIEyq8Qm5RsXOW4PCbGIREp3jy5tXbWE4KUCBsm4aI5HYuSUBJDoZZgQTu4aVkm5ZdVCFv\no01SB/589AFkzshXAE8KXEi0qNGjSMlEajnpJcxN+exUy3OTIzUeUXvue4WsXC0mWAAAIfkE\nAAYA/wAsAAAAAGICBAACA/4YotIuA8JBKxkk60KKN6BxiEdpnmiqrmhoeF6naVXdRI/DBAq/\n8MAAQDgsEgHIpHLJbDqf0Kh0Sq1ar9isdsvterdEIW8IJAfPv0XOEalZZjJYwcWq2++i0Fwu\nm2HcbWs5PWoMgm01F4obci90d5CRJS5yHBw0GX8UEpw6D4RnY0FGYUVfp6ipqqusra6vXKVk\npqFBhYM5gYkYcJWOIZLBdnovMH2YbjcSOLc+hA2GyoB/cBmWe8DC2ivExpdw05vMn4W1o2Wi\nsOrr7O3u7/BVoujz5mrQhxNuF7zWHTCPtgmcNALEHmPg+NnohOvHs3yILPRjBBAYiYHaXBRD\n6CtnmiBP5mqZGhmvpMmTKFOqbBJGTEgg+D5GlFjt2pyAGIVR4lNNU7JxnhwCACH5BAAGAP8A\nLAAAAABiAgQAAgPtWLZ7/jDKSaU5rOhCuu9DKA5CKJRnGgjB6rJt3AIxDdzBbet87//AoHBI\nLBqPyKRyyWw6n9CodOrL8ay5rFa2YsG8qRNJXAoRRB8CZ6NgYCrweJxhUNjd8rz+QWevPwMg\nImUoYWEtX1wzNFg2jVSQkZKTlJWWl5iZTo+OW4qIMYZhJKQjgWlqbHQXe61wFwt2bQ2utROw\nsX6oZqYoY4YvLp81WY47msjJysvMzc7PxjPEw2DVKWOmvKceaxurtuB8GLl1Dazhtn0bqGdn\nvb/AXsPE0dD29/j5+vvLVtHzJ7qIKpSNXSpVtNCly1AAACH5BAAGAP8ALAAAAABiAgQAAgPV\neLq8diYWUwqxJJOx9/iDEIpCaZpBmQZs6wYAC8QwPd94ru987//AoHBILBqPyKRyyWw6n9Ao\nElaj0l4tlYC1PZVCoHBnnLFUJpF0Y81uOyCTc0Wj4YRBJO9qu8LKqjaAUoOEhYaHiImKi4yN\nTzUxN1STflxZXiZgInccdGZyaQ9uo24PoXFmdHacJCOYKXx8lZRXM5COuLm6u7y9vr+KtJSz\ne1perpwZnRqfaGqk0GunZxd0yh54mq8qxFaRwODh4uPk5eaEVVbdxpibm3fWZXLOotEAADs=\nENDofIMG\n\ndemo.show_image('bmp', '1-bit', <<'ENDofIMG')\nQk3OAQAAAAAAAD4AAAAoAAAAIgAAADIAAAABAAEAAAAAAJABAABtCwAAbQsAAAIAAAACAAAA\nMzPMAMwzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAZmTKAAAAAABIRIwAAAAAAEZAigAAAAAAQECIAAAAAAAAAAgAAAAAAAAEAA\nAAAAAAABQAAAAAAAAAPAAAAAAAAAB+AAAAAAAAAC4AAAAAAAAALgAAAAAAAAAsAAAAAAAAAC\nwAAAAAAAAALgAAAAAAAABuAAAAAAAAAG4AAAAAAAAAbgAAAAAAAABuAAAAAAAAAG4AAAAAAA\nAAfgAAAAAAAAA+AAAAAAAAADcAAAAAAAAAPwAAAAAAAAA/AAAAAAAAAD+AAAAAAAAAP4AAAA\nAAAAA/gAAAAAAAAD4AAAAAAAAAHgAAAAAAAAAfAAAAAAAAAA+AAAAAAAAAB8AAAAAAAAADgA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nENDofIMG\n\ndemo.show_image('bmp', '4-bit', <<'ENDofIMG')\nQk1aBAAAAAAAAHIAAAAoAAAAIgAAADIAAAABAAQAAAAAAOgDAABtCwAAbQsAAA8AAAAPAAAA\n////AAD//wDMzP8AmZn/AGaZ/wAzM8wAmZnMAGaZzAAzZswAzMyZAJmZmQDMZjMAZjNmADMz\nZgBmMzMABWMgAAAAAAAAAAAAAAAAAAAAAAAFVVVVVVVVVVVVVVVVVVVVUAAAAAVVVVVVVVVV\nVVVVVVVVVVVQAAAABVVVVVVVVVVVVVVVVVVVVVAAAAAFVVVVVVVVVVVVVVVVVVVVUAAAAAVV\nVVVVVVVVVVVVVVVVVVWAAAAABVVVVVVVVVVVVVVVVVVVVVAAAAAFVVBVU3VSVVNVB1UFBVVV\nUAAAAAVVUFU1VVNVVVUFVQBVVVVgAAAABVVQVVUFU1VVVQVVBVVVVTAAAAAIVVBVVVVTVXVV\nBVUFVVVVMAAAAAVVVVVVVVFVFVVVVQVVVVUgAAAABVVVVVVVVVUFVVVVVVVVVSAAAAAHVVVV\nVVVVW5tVVVVVVVVVAAAAAAZVVVVVVVW8u2VVVVVVVVUAAAAAA1VVVVVVW7W7tVVVVVVVVQAA\nAAADVVVVVVWCtbuzVVVVVVVVAAAAAANVVVVVVVW1vrJVVVVVVVUAAAAAAlVVVVVVWLW7UFVV\nVVVVVQAAAAACVVVVVVVatbtVVVVVVVVVAAAAAABVVVVVVVq3u8NVVVVVVVUAAAAAAFVVVVVV\nXrS74VVVVVVVVQAAAAAAVVVVVVWLtbuyVVVVVVVVAAAAAABVVVVVVUu1u7BVVVVVVVUAAAAA\nAFVVVVVVO7W7sFVVVVVVVQAAAAAAVVVVVVUbtbu6VVVVVVVVAAAAAABVVVVVVSu9u1VVVVVV\nVVUAAAAAAFVVVVVVJb67tVVVVVVVVQAAAAAAVVVVVVVVu6u7VVVVVVVVAAAAAABVVVVVVVW7\nu7slVVVVVVUAAAAAAFVVVVVVVbu7u1VVVVVVVQAAAAACVVVVVVVVu7u7wlRVVVVVAAAAAAJV\nVVVVVVW7u7uwV1VVVVUAAAAAA1VVVVVVVbu7u7BVhVVVVSAAAAADVVVVVYVVu7vFAFUVVVVV\nMAAAAAZVVVVVhVUbu7VVVRVXVVVgAAAAB1VVVVVVVVu7u1VVFVFVVVAAAAAFVVVVVVhVVLu7\nxVVVVVVVgAAAAAVVVVVVUVVVK7u1VVVVVVVQAAAACFVVVVhRVVVQq7VVVVVVVVAAAAAFVVVV\nVFV1VVUgBVVVVVVVUAAAAAVVVVVUVRVVVVVVVVVVVVVQAAAABVVVVViFUVVVVVVVVVVVVVAA\nAAAFVVVVVRVUFVVVVVVVVVVVUAAAAAVVVVVVVVVVVVVVVVVVVVVQAAAABVVVVVVVVVVVVVVV\nVVVVVVIAAAAFVVVVVVVVVVVVVVVVVVVVUQAAAAVVVVVVVVVVVVVVVTdVVVVWAAAAAAAhNnWF\nVVVVVVcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==}\nENDofIMG\n\nif false\ndemo.show_image('bmp', '4-bit-RLE', <<'ENDofIMG')\nQk1sAwAAAAAAAHYAAAAoAAAAIgAAADIAAAABAAQAAgAAAPYCAAAAAAAAAAAAABAAAAAQAAAA\n////AMzM/wAA//8AmZn/AJmZzABmmcwAMzPMADNmzABmmf8AmZmZAMxmMwBmM2YAZjMzADMz\nZgDMzJkAAAAAAAAGBkMQABwAAAACBh5mAmAAAAIGHmYCYAAAAgYeZgJgAAACBh5mAmAAAAIG\nHmYCcAAAAgYeZgJgAAAAIgZmYGZjVmFmY2YFZgYGZmZgAAAAACIGZmBmNmZjZmZmBmYAZmZm\nQAAAAAAiBmZgZmYGY2ZmZgZmBmZmZjAAAAAAIgdmYGZmZmNmVmYGZgZmZmYwAAAAAgYKZgAW\nYmYmZmZmBmZmZhAAAAACBg5mAgYOZgIQAAACBQxmAARq6g5mAgAAAAIEDGYABquqRgAMZgIA\nAAACAwpmAAhqpqqmDGYCAAAAAgMKZgAIcaaqowxmAgAAAAIDDGYABqasoQAMZgIAAAACAQpm\nAAhnpqpgDGYCAAAAAgEKZgAGaaaqAA5mAgAAAAIACmYACGmlqrMMZgIAAAACAApmAAhsqKrC\nDGYCAAAAAgAKZgAIeqaqoQxmAgAAAAIACmYACIqmqqAMZgIAAAACAApmAAg6pqqgDGYCAAAA\nAgAKZgAIKqaqqQxmAgAAAAIACmYABhqtqgAOZgIAAAACAApmAAgWrKqmDGYCAAAAAgAMZgAG\nqpqqAAxmAgAAAAIADGYACKqqqhYKZgIAAAACAAxmAAaqqqoADGYCAAAAAgEMZgAKqqqqsWgA\nCGYCAAAAAgEMZgAKqqqqoGUACGYCAAAAAgMMZgAUqqqqoGZ2ZmZmEAAAAgMIZgAYdmaqqrYA\nZiZmZmYwAAACBAhmABh2ZiqqpmZmJmVmZkAAAAIFDGYAFGqqqmZmJmJmZmAAAAIGCGYADGdm\naKqqtgpmAnAAAAIGCGYADGJmZhqqpgpmAmAAAAAWB2ZmZmdiZmZgmqYACmYCYAAAABYGZmZm\naGZWZmYQBgAKZgJgAAAADgZmZmZoZiYAEmYCYAAAAA4GZmZmZ3ZiABJmAmAAAAIGCGYABiZo\nJgAQZgJgAAACBh5mAmAAAAIGHmYCYQAAAgYeZgJiAAACBhZmAAo1ZmZmZAAAAAAMAAASNFZ2\nCGYCZQwAAAAiAAAB\nENDofIMG\nend\n\ndemo.show_image('bmp', '8-bit', <<'ENDofIMG')\nQk0CCAAAAAAAAPoAAAAoAAAAIgAAADIAAAABAAgAAAAAAAgHAABtCwAAbQsAADEAAAAxAAAA\n////AMz//wAA//8AzMz/AJnM/wAAzP8AmZn/AGaZ/wAAmf8AZmb/ADNm/wAzM/8A/8zMAMzM\nzACZmcwAZpnMAACZzABmZswAM2bMAABmzAAzM8wAADPMAAAAzAD/zJkAzMyZAMyZmQCZmZkA\nZmaZAGYzmQAzM5kAzJlmAJlmZgBmZmYAZjNmADMzZgDMmTMAmWYzAJkzMwBmMzMAmWYAAJkz\nAAAAAN0A7u7uAN3d3QC7u7sAqqqqAIiIiAB3d3cAVVVVAAARDgYDKgAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAVFRUVFRUVFRUVFBQUFBQUFRUVFRUVFRUVFRUVFRUVFQAAAAAV\nFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFQAAAAAVFRUVFRUVFRUVFRUVFRUVFRUV\nFRUVFRUVFRUVFRUVFAAAAAAVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFAAAAAAV\nFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVEgAAAAAVFRUVFhUVFRYVFRUWFRUVERUV\nFhUVFRYVFhUVFRUVEQAAAAAUFRUWABEVFQYPFhUDERUWBhUVKg8VFAAUABQVFRUVEQAAAAAU\nFRUWABYVBhQWFRUGFBUWERUWABYVFgAAFRUVFRUVDgAAAAAUFRUVABUVFBEAFhUGFBUUFRUV\nABUVFgARFRUVFRUVBgAAAAASFRUWABUVFRUVFRUGFBUPFhUWABYVFgAVFBUVFRUVBgAAAAAR\nFRUVFhUVFRUVFRUEFBUEFhUVFhUVFQAWFRUVFRUVAwAAAAARFRUVFRUVFRUVFRUVFRUrHRUV\nFRUVFRUVFRUVFRUVAwAAAAAPFRUVFRUVFRUVFRUVFCQYKBUVFRUVFRUVFRUVFRUVKgAAAAAO\nFRUVFRUVFRUVFRUUJyEeKA4VFRUVFRUVFRUVFRUVAAAAAAAGFRUVFRUVFRUVFRYeKB0kKCQU\nFRUVFRUVFRUVFRUVAAAAAAAGFRUVFRUVFRUVFRIDKBQnKCgGFRUVFRUVFRUVFRUVAAAAAAAG\nFRUVFRUVFRUVFRUVJxEnJigDFRUVFRUVFRUVFRUVAAAAAAADFRUVFRUVFRUVFRUSKBEnKAkq\nFRUVFRUVFRUVFRUVAAAAAAADFRUVFRUVFRUVFRUuJxEoKBEWFRUVFRUVFRUVFRUVAAAAAAAr\nFRUVFRUVFRUVFRYvKA8oKCEGFRUVFRUVFRUVFRUVAAAAAAAqFRUVFRUVFRUVFRQmKAcoKCYE\nFRUVFRUVFRUVFRUVAAAAAAAAFRUVFRUVFRUVFRIoJwkoKCgDFRUVFRUVFRUVFRUVAAAAAAAA\nFRUVFRUVFRUVFQcoJxEnKCgBFRUVFRUVFRUVFRUUAAAAAAAAFRUVFRUVFRUVFQYoKBQnKCgq\nFhUVFRUVFRUVFRUUAAAAAAAAFRUVFRUVFRUVFQQoKBQkKCgsFhUVFRUVFRUVFRUUAAAAAAAA\nFRUVFRUVFRUVFQMkKCIjKB0RFRUVFRUVFRUVFRUUAAAAAAAAFRUVFRUVFRUVFQMUKCYeKCgV\nFRUVFRUVFRUVFRUVAAAAAAAAFRUVFRUVFRUVFRUVKCgaKCgnFRUVFRUVFRUVFRUVAAAAAAAA\nFRUVFRUVFRUVFRUUKCgkKCgoAxYVFRUVFRUVFRUVAAAAAAArFRUVFRUVFRUVFRURKCgoKCgo\nERQVFRUVFRUVFRUVAAAAAAADFRUVFRUVFRUVFRURKCgoKCgoIQMWCBUVFRUVFRUVAAAAAAAD\nFRUVFRUVFRUVFRURKCgoKCgoKAAWEBYVFRUVFRUVKgAAAAAGFRUVFRUVFRUVFRUUJygoKCgo\nKAAWFRMVFRUVFRUVAwAAAAAGFRUVFRUVFRUTFhUWHigoKCEUKgAWFgIVFRUVFRUVBgAAAAAO\nFRUVFRUVFRUTFRUVBCgoKCgUFRYVFgIWFRAWFRUVDgAAAAAPFRUVFRUVFRUVFRUVFR4oKCgo\nFRUVFQIVFQUVFRUVEQAAAAARFRUVFRUVFRUVExUVFQckKCgoIRUVFRYVFRUVFRUVEgAAAAAR\nFRUVFRUVFRUWAhYVFRYDJygoKB0VFRUVFRUVFRUVFAAAAAASFRUVFRUVFRMVBRUVFRUWKhko\nKBQVFRUVFRUVFRUVFQAAAAAUFRUVFRUVFQgWFRAVFRUVFgMAKxYVFRUVFRUVFRUVFQAAAAAU\nFRUVFRUVFQgWFQIWFRUVFRUWFhUVFRUVFRUVFRUVFQAAAAAUFRUVFRUVFRMTFRUFFhUVFRUV\nFRUVFRUVFRUVFRUVFQAAAAAVFRUVFRUVFRYFFhUIAhYVFRUVFRUVFRUVFRUVFRUVFQAAAAAV\nFRUVFRUVFRUVFRUVFhUVFRUVFRUVFRUVFRUVFRUVFQAAAAAVFRUVFRUVFRUVFRUVFRUVFRUV\nFRUVFRUVFRUVFRUVFQMAAAAVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFQQAAAAV\nFRUVFRUVFRUVFRUVFRUVFRUVFRUVFAYPEREUFBQVFQ4AAAAAACoDBAYODxESFBQVFRUVFRUV\nFQ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\nENDofIMG\n\nif false\ndemo.show_image('bmp', '8-bit-RLE', <<'ENDofIMG')\nQk22CAAAAAAAADYEAAAoAAAAIgAAADIAAAABAAgAAQAAAIAEAAAAAAAAAAAAAAABAAAAAQAA\n////AO7u7gDMzP8Amcz/AJmZ/wCZmcwAZpnMAGZmzAAzZswAMzPMAAAzzAAAAMwAAMz/AACZ\n/wAA//8AAGbMAACZzADd3d0AzJmZAJkzAACZZgAAMzOZAGaZ/wCZZjMAZjNmAMyZZgCZmZkA\nZjMzADMzZgDMmTMAu7u7AMz//wBmZv8Ad3d3AIiIiADMzJkAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG\nAAcFBAIBHAAAAAEACgoGCRAKAQAAAAEAIAoBAAAAAQAfCgEJAQAAAAEAHwoBCQEAAAABAB8K\nAQgBAAAAAQAECgAWCwoKCgsKCgoLCgoKBwoKCwoKCgsKCwUKAQcBAAAAABwACQoKCwAHCgoE\nBgsKAgcKCwQKCgEGCgkACQAJBAoBBwEAAAAAGgAJCgoLAAsKBAkLCgoECQoLBwoLAAsKCwAA\nBgoBBQEAAAAAGgAJCgoKAAoKCQcACwoECQoJCgoKAAoKCwAHBgoBBAEAAAAABgAICgoLAAcK\nAA4ECQoGCwoLAAsKCwAKCQUKAQQBAAAAAAYABwoKCgsHCgANAwkKAwsKCgsKCgoACwAGCgEC\nAQAAAAEAAQcOCgERARUOCgECAQAAAAEAAQYMCgAECRcjEw4KAQEBAAAAAQABBQsKAAYJFBgZ\nEwUNCgEAAQAAAAEAAQQKCgAICxkTFRcTFwkMCgEAAQAAAAEAAQQKCgAICAITCRQTEwQMCgEA\nAQAAAAEAAQQMCgAGFAcUGxMCDAoBAAEAAAABAAECCwoABwgTBxQTIAEADAoBAAEAAAABAAEC\nCwoAByIUBxMTBwsADAoBAAEAAAABAAERCgoACAshEwYTExgEDAoBAAEAAAABAAEBCgoACAkb\nExYTExsDDAoBAAEAAAABAAEACgoACAgTFCATExMCDAoBAAEAAAABAAEACgoACBYTFAcUExMf\nCwoAAwkAAAAAAAEAAQAKCgAJBBMTCRQTEwELAAoKAAMJAAAAAAABAAEACgoACQMTEwkXExMe\nCwAKCgADCQAAAAAAAQABAAoKAAgCFxMcHRMVBwsKAAMJAAAAAAABAAEACgoABwIJExsZExMA\nDQoBAAEAAAABAAEADAoABhMTGhMTFAwKAQABAAAAAQABAAsKAAkJExMXExMTAgsACgoBAAEA\nAAABAAERCwoBBwYTAQcBCQoKAQABAAAAAQABAgsKAQcGEwAEGAILDQgKAQABAAAAAQABAgsK\nAQcHEwAEAAsQCwcKAQEBAAAAAQABBAsKAQkBFAYTAAQACwoPBwoBAgEAAAABAAEECAoADw8L\nCgsZExMTGAkBAAsLDgAHCgEEAQAAAAEAAQUICgAFDwoKCgMABBMADwkKCwoLDgsKEAsKCgoF\nAAAAAAEAAQYNCgEZBBMECgAEDgoKDAQKAQcBAAAAAQABBwkKAA4PCgoKFhcTExMYCgoKCwcK\nAQgBAAAAAQABBwgKAAwLDgsKCgsCFBMTExUKCgEJAQAAAAEAAQgHCgADDwoMAAQKAAYLARIT\nEwkLCgEAAAABAAEJBwoABA0LChAECgAFCwIAEQsACwoBAAAAAQABCQcKAAUNCwoOCwAFCgEL\nAQsMCgEAAAABAAEJBwoABg8PCgoMCxIKAQAAAAEACAoABwsMCwoNDgsAEQoBAAAAAQANCgEL\nEgoBAAAAAQAgCgECAAABACAKAQMAAAEAFgoACwkEBgcHCQkJCgoFAAAAAA0AAAABAgMEBQYH\nCAkJAAgKAQYMAAAAIgAAAQ==\nENDofIMG\nend\n\ndemo.show_image('bmp', '32-bit', <<'ENDofIMG')\nQk2GFAAAAAAAADYAAAAoAAAAIgAAADIAAAABABgAAAAAAFAUAABtCwAAbQsAAAAAAAAAAAAA\n////ZmbMmZnMmZn/zMz/7u7u////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////AAD///8A\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wzM8wzM8wzM8wzM8wzM8wzM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8z///8AAP///wAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzP///wAA////ADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMMzPM////AAD///8AM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wzM8z///8AAP///wAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzDNmzP///wAA////ADPMADPMADPMADPMAADMADPMADPM\nADPMAADMADPMADPMADPMAADMADPMADPMADPMZmbMADPMADPMAADMADPMADPMADPMAADMADPM\nAADMADPMADPMADPMADPMADPMZmbM////AAD///8zM8wAM8wAM8wAAMz///9mZswAM8wAM8yZ\nmf9mmcwAAMwAM8zMzP9mZswAM8wAAMyZmf8AM8wAM8zu7u5mmcwAM8wzM8z///8zM8z///8z\nM8wAM8wAM8wAM8wAM8xmZsz///8AAP///zMzzAAzzAAzzAAAzP///wAAzAAzzJmZ/zMzzAAA\nzAAzzAAzzJmZ/zMzzAAzzAAAzGZmzAAzzAAAzP///wAAzAAzzAAAzP///////wAzzAAzzAAz\nzAAzzAAzzAAzzJmZzP///wAA////MzPMADPMADPMADPM////ADPMADPMMzPMZmbM////AADM\nADPMmZn/MzPMADPMMzPMADPMADPMADPM////ADPMADPMAADM////ZmbMADPMADPMADPMADPM\nADPMADPMmZn/////AAD///8zZswAM8wAM8wAAMz///8AM8wAM8wAM8wAM8wAM8wAM8wAM8yZ\nmf8zM8wAM8xmmcwAAMwAM8wAAMz///8AAMwAM8wAAMz///8AM8wzM8wAM8wAM8wAM8wAM8wA\nM8yZmf////8AAP///2ZmzAAzzAAzzAAzzAAAzAAzzAAzzAAzzAAzzAAzzAAzzAAzzJnM/zMz\nzAAzzJnM/wAAzAAzzAAzzAAAzAAzzAAzzAAzzP///wAAzAAzzAAzzAAzzAAzzAAzzAAzzMzM\n/////wAA////ZmbMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM\n3d3dMzOZADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMzMz/////\nAAD///9mmcwAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wzM8yZZjPMzJmZ\nMwAAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8zu7u7///8AAP//\n/5mZzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzDMzzJlmAGYzZsyZZpkzAJmZ\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzP///////wAA////mZn/\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMAADMzJlmmTMAMzOZmWYzmTMAmWYzMzPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM////////AAD///+Zmf8AM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wzZszMzP+ZMwAzM8yZZgCZMwCZMwCZmf8AM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8z///////8AAP///5mZ/wAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzJlmAGZmzJlmAGYzM5kzAMzM/wAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzP///////wAA////zMz/ADPMADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMM2bMmTMAZmbMmWYAmTMAZmb/7u7uADPMADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPM////////AAD////MzP8AM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8yIiIiZZgBmZsyZMwCZMwBmZswAAMwAM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8z///////8AAP///93d3QAzzAAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAAzHd3d5kzAGaZzJkzAJkzAGYzZpmZ/wAzzAAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzP///////wAA////7u7uADPMADPMADPMADPMADPMADPMADPMADPM\nADPMADPMMzPMZjMzmTMAZpn/mTMAmTMAZjMzmcz/ADPMADPMADPMADPMADPMADPMADPMADPM\nADPMADPMADPMADPM////////AAD///////8AM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wA\nM8wzZsyZMwCZZgBmZv+ZMwCZMwCZMwDMzP8AM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8z///////8AAP///////wAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzGaZ\n/5kzAJlmAGZmzJlmAJkzAJkzAMz//wAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAz\nzDMzzP///////wAA////////ADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMmZn/mTMA\nmTMAMzPMmWYAmTMAmTMA7u7uAADMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMMzPM\n////////AAD///////8AM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8yZzP+ZMwCZMwAz\nM8yZZjOZMwCZMwC7u7sAAMwAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wzM8z/////\n//8AAP///////wAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzMzM/5lmM5kzADMzZsyZ\nM5kzADMzmWZmzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzDMzzP///////wAA\n////////ADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMzMz/MzPMmTMAZjMzzJlmmTMA\nmTMAADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM////////AAD/////\n//8AM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8yZMwCZMwCZmZmZMwCZMwCZ\nZgAAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8z///////8AAP///////wAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzDMzzJkzAJkzAJlmM5kzAJkzAJkzAMzM\n/wAAzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzP///////wAA////3d3dADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMZmbMmTMAmTMAmTMAmTMAmTMAmTMAZmbMMzPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM////////AAD////MzP8AM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8xmZsyZMwCZMwCZMwCZMwCZMwCZMwBmM2bMzP8AAMwA\nmf8AM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8z///////8AAP///8zM/wAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzGZmzJkzAJkzAJkzAJkzAJkzAJkzAJkzAP///wAAzACZzAAA\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzO7u7v///wAA////mZn/ADPMADPMADPMADPMADPMADPM\nADPMADPMADPMADPMADPMMzPMmWYAmTMAmTMAmTMAmTMAmTMAmTMA////AADMADPMAGbMADPM\nADPMADPMADPMADPMADPMADPMzMz/////AAD///+Zmf8AM8wAM8wAM8wAM8wAM8wAM8wAM8wA\nM8wAZswAAMwAM8wAAMzMmWaZMwCZMwCZMwBmM2YzM8zu7u7///8AAMwAAMwA//8AM8wAM8wA\nM8wAM8wAM8wAM8wAM8yZmf////8AAP///5mZzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzABm\nzAAzzAAzzAAzzJnM/5kzAJkzAJkzAJkzADMzzAAzzAAAzAAzzAAAzAD//wAAzAAzzACZzAAA\nzAAzzAAzzAAzzJmZzP///wAA////ZpnMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM\nADPMADPMADPMzJlmmTMAmTMAmTMAmTMAADPMADPMADPMADPMAP//ADPMADPMAMz/ADPMADPM\nADPMADPMZmbM////AAD///9mZswAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAZswAM8wA\nM8wAM8xmmf+ZZjOZMwCZMwCZMwBmM2YAM8wAM8wAM8wAAMwAM8wAM8wAM8wAM8wAM8wAM8wA\nM8wzZsz///8AAP///2ZmzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAAzAD//wAAzAAzzAAz\nzAAAzMzM/5lmAJkzAJkzAJkzADMzmQAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzDMz\nzP///wAA////M2bMADPMADPMADPMADPMADPMADPMADPMAGbMADPMAMz/ADPMADPMADPMADPM\nAADM7u7uzJmZmTMAmTMAMzPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM////\nAAD///8zM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAmf8AAMwAM8wAmcwAM8wAM8wAM8wAM8wA\nAMzMzP/////d3d0AAMwAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8z///8AAP//\n/zMzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzACZ/wAAzAAzzAD//wAAzAAzzAAzzAAzzAAzzAAz\nzAAAzAAAzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzP///wAA////MzPM\nADPMADPMADPMADPMADPMADPMADPMAGbMAGbMADPMADPMAMz/AADMADPMADPMADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM////AAD///8AM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAAMwAzP8AAMwAM8wAmf8A//8AAMwAM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8z///8AAP///wAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAAzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzP///wAA////ADPMADPMADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPMADPM\nADPMADPMADPMADPMADPMADPMADPMADPMADPMzMz/AAD///8AM8wAM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8wA\nM8wAM8wAM8wAM8wAM8wAM8wAM8wAM8yZzP8AAP///wAzzAAzzAAzzAAzzAAzzAAzzAAzzAAz\nzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzAAzzDMzzJmZ/2aZzGZm\nzGZmzDMzzDMzzDMzzAAzzAAzzJmZzAAA////////////7u7uzMz/mcz/mZn/mZnMZpnMZmbM\nM2bMMzPMMzPMADPMADPMADPMADPMADPMADPMADPMADPMZpnM////////////////////////\n////////////////////////AAD/////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////\n//////////////////8AAA==\nENDofIMG\n\ndemo.show_image('gif', 'gif87a', <<'ENDofIMG')\nR0lGODdhQAAoAPcAAAAAADgoOHBgYJiIkIB4iJCAiIB4gGBIUGhggKiYmLCYoLiooHBocMCA\neJBocLCYmMCooKiQkKCAgGBASIiAiGhYeLiQiIhoaJhwcJh4gMCYkMCgoMCoqKiQiEBAWEg4\nQMiwoMioqMComLCIiFhAWIBgaJhweHBgcLiQkIiAgDg4UIhwgHhgYJh4cMiooFBQcGBYeJiA\niIBwgIh4iKCAiKB4eHhYYGhIWKiIiEhAWFBIYEhAaEhIaHBYcHBgeFBQeHBogHBQYHBQWGBA\nUFhQaGBYaFhYeKCIkLCQmHhYaGBIWLCYiFBAYEhAYFhQYFBIaFhYcKCIiKCQkKiIkLCIgHBQ\naIhwcJiAeIBgcJBwcLCQiKiAeKB4gHhwgNCwqMiwqIBoeHBYaJh4eMCYmJBweGhYYNC4qEg4\nUEA4WGBQWEBAYFBQaHBoeFhQcGhgeGhYcMiwsJB4cGBIYNjIwEAwSMCgmHhocFBAWNDAuNDI\nuIBweGBYcHhoeDgwQGhgaKCIgNjQuKiAgNjIuKiIgKCAeKCQiEhIWFBIUGBQaNC4sGBQcGBY\nYMi4sGhYWFhIYFhIaFhQWHhoaLCQkDg4SHBgaJB4gJB4eLiYmLiomGhYaEhIYFhYaIh4gHho\ngGhgcIBoaGBIaHhgcNDAsFBAUGhQYLigoLioqJiIgGhQaFA4SFhIWHhweFBIWJiAgIh4eFhI\nUHBYYIhweEg4WLiYkDg4WGBQYEA4SEA4UMCwqIhocHhgaJB4iJCAgFhASEBAUEhAUIBocFhA\nUKCQmHhgeEgwSNjQwEg4SLCgmDgwUGhQWLCgoEAwUFBASLigmEAwQGhIUFg4SIhoeEgwQKiY\nkFA4UDgwSJiIiIBwcKiQmLCooLCYkDgoQP//////////////////////////////////////\n////////////////////////////////////////////////////////////////////////\n/////////////////////////////////ywAAAAAQAAoAAAI/gABCBxIsKDBggEEDBhAoICB\nAwcjSpxIMSKCBAoWIGDQoIGDBxAURJBAoKLJkwcnUKgQoYEFlxcwdOyYoYGGDRw6eEDJc+IH\nCSBCiHg5YiaJEjM7mjgBAkUKAip6Sh24YqYGmUkbYGDRwoWGlxocvIABI4aMGVN70qiRNSkL\nGzda4BhhIoeOHTx6+PjxwwcCIGlPouiI4WUDFkFYCLlhYwiLBkU73iBShAgRAkaMHCGAIDBF\nJBpmXkiiZMiQCagzLEFRgi0GDUyaONHx5MkLKFFCSOns+eCUBlRKVIErxIYVG1ewsMiixYSW\nLVxQkIDRpDqRJF1gVPDyhQDg3gSB/mQAwyKMmBJjpoAhU6bKCjMgMGxZAuIMmjRq0KhpsmbN\nEjZtuHEEAgQ4Ad5ACLxRQhkZwBHHGHKMAcccdFxhBgpU1FGDHUzc0QESduDhxRx56DEHHnvs\n4R0ffRzYhREwYOHHH4BUEQgZYYlgoSBfjCHIBh0MAoEdAxBSiCGHIJLIHHCYwEEFQHRhx4Ew\nLLCHIm4sIggjc9RhgQhzgEAIIGSEAAIgjShhwhwN4MGEI4/sAIkjSEQiCRJYuAHEJL0RwMge\nejzBBiV6VGKJFpcMskUcFyQygoiEbAABJn9kogkaa+RgwCZEMEEEBlNw4gMbiPQ2QyeefAKK\nGpT0cAIk/jjEgQIKggAiiAMgUAFZIkiEIkokozyigyakLFLBGzb8IcUDPXjSGxArlGJKKKcg\nsQAqdojAlQMaCDLGHIlk8EkqiFhQBxJL5BAGE0yo4gQaTBTAQAYc2NGDZ4UAYcoOhfBxwiql\nnFGGDQ3UwMIFGsyBAgs19MBKDg0IQUoroqCRgweO5OCKJjo4osEYBXjySmAE/JBCDHBMUUkT\nT6AxiktgvXTDDbDEUoEsF8ySQxl8LJEGLTugUUQtllBQyyqW8DFyWggY8UYoHPBxxh1O0PDA\nGA0g1ZEQQphQwhus2GJDEGh4cAstbjSBBhF7aEJEEzwYQUQnaQSWHQ+o4BIG/i5gPFIKHl8k\nZYENGOSiixysqHHGLYbE4IQTt1TQhA6o8KDJGjy8YJkiJPOlCAw7OPKEB7LccYsQoUFWxwSq\n2EFJETo8ogoaThSRwy2y4KEGBaDwUIQfu1DiwyOBNc3DGrzI0cYdnNyRQx+vuCRIAyD0wokS\naehgSw60+GIILbSoYMstpvwywxM88PAEETwQQTIMCOwBBjAdfMFIFBcEQ4IIDdTaAjAJgMQd\nUnGGJJTtdpMI3yRUAAEP4AUIT9DECRxhN2EoIAZ7IAUkAhECDgwDDLYgxgREgQk8FMNWcxAF\nBwjRhztEQRWtoIQdbHGGHOCBFmqAgRr2kIm6pWUC/p3wwRFAMYM/6IIUR0gAE+Rwh2DIwRgo\nwEMe5jAHQQhCFHFoBAAycYxXxMER27MBMtTACtkU4QyeUYACStGEO8QADA/wRAAEIoMsiOEK\nNxACCEAgiDwIAg+l+EQyAnCKDljAFLbghTHKp4Yi9IBznlEGBxLhiGUsgQOM+EQWAPABKkBC\nDBEIRC/iIApbCQICgxhCMERAiBZYwRLMmIAxFgAK7r3gCb1hAwXwYIUogKIMQSBEHprhDCVc\n4BNVnAMgABEm+hTgGYcoAzQWIAIsTOABaSBEFNIAiSfIAjwIYEQIZIGFMIAhDW/IAy6igYNE\nfEEUiWDEJcRgjBsEgRTM/pDDH5jRAUbgwhQJcIUkaAAEWvziQAjgQCnukIBW6KEWVsDDLFhA\nhQuEwAUjAMEsZnGBPwhBAtI4AAMaEYEOfAIAyjjGNOKgByLM8UADUAYnEmCJLwQBB3jAhRYG\ngTAN4CALWajDEWBxAV1MIBIMcIItjCEQSEShEqoYBTUOJBBbFACAqWjGBl5BhS+gQAs4mEYH\nCOHPXmCBEBMYxjQC0IhbVEMglEgDKX5xBgpSVSAEqAAnTtGMB4CBEApAAS6yMIhmlMISlmjG\nIKxxjFnc4AgCsIMqXMEJXujhF7eABFPvKhAEsMENqliAFHpBCRvUAQKm4IAVxBCFBSijFA8Y\n2MQAjDENUrjCClaohB2KAAlWcJYgCLjGABKAjVYsIBsJuEQEmoGJbJjiuNpIQDY4UYAC8EEP\nkegEA9zwBk38tiAIMEB0swGBbGDjGM2QhDIeMItsONe9MrWGMKxhXU8Q4aDfLcgkCpCCCCRA\nG0hQQAKU4d4FGDgbyiBuBAZQAArIAAZ7yEF+IwIER8wAGxherwKOcQllTGMaSJBCBGLAi1Os\ngBJ2nbBEoFCAAUQhCtiIQASEIeMB0IAG1rAsH5ywDRWbJACdmEFDdlGAGMyAxF1gAwzuQNWA\nAAA7\nENDofIMG\n\ndemo.show_image('gif', 'gif89a', <<'ENDofIMG')\nR0lGODlhQAAoAPcAAMnJyTgoOHBgYJiIkIB4iJCAiIB4gGBIUGhggKiYmLCYoLiooHBocMCA\neJBocLCYmMCooKiQkKCAgGBASIiAiGhYeLiQiIhoaJhwcJh4gMCYkMCgoMCoqKiQiEBAWEg4\nQMiwoMioqMComLCIiFhAWIBgaJhweHBgcLiQkIiAgDg4UIhwgHhgYJh4cMiooFBQcGBYeJiA\niIBwgIh4iKCAiKB4eHhYYGhIWKiIiEhAWFBIYEhAaEhIaHBYcHBgeFBQeHBogHBQYHBQWGBA\nUFhQaGBYaFhYeKCIkLCQmHhYaGBIWLCYiFBAYEhAYFhQYFBIaFhYcKCIiKCQkKiIkLCIgHBQ\naIhwcJiAeIBgcJBwcLCQiKiAeKB4gHhwgNCwqMiwqIBoeHBYaJh4eMCYmJBweGhYYNC4qEg4\nUEA4WGBQWEBAYFBQaHBoeFhQcGhgeGhYcMiwsJB4cGBIYNjIwEAwSMCgmHhocFBAWNDAuNDI\nuIBweGBYcHhoeDgwQGhgaKCIgNjQuKiAgNjIuKiIgKCAeKCQiEhIWFBIUGBQaNC4sGBQcGBY\nYMi4sGhYWFhIYFhIaFhQWHhoaLCQkDg4SHBgaJB4gJB4eLiYmLiomGhYaEhIYFhYaIh4gHho\ngGhgcIBoaGBIaHhgcNDAsFBAUGhQYLigoLioqJiIgGhQaFA4SFhIWHhweFBIWJiAgIh4eFhI\nUHBYYIhweEg4WLiYkDg4WGBQYEA4SEA4UMCwqIhocHhgaJB4iJCAgFhASEBAUEhAUIBocFhA\nUKCQmHhgeEgwSNjQwEg4SLCgmDgwUGhQWLCgoEAwUFBASLigmEAwQGhIUFg4SIhoeEgwQKiY\nkFA4UDgwSJiIiIBwcKiQmLCooLCYkDgoQP//////////////////////////////////////\n////////////////////////////////////////////////////////////////////////\n/////////////////////////////////yH5BAEAAAAALAAAAABAACgAAAj+AAEIHEiwoMGC\nAQQMGECggIEDByNKnEgxIoIEChYgYNCggYMHEBREkECgosmTBydQqBChgQWXFzB07JihgYYN\nHDp4QMlz4gcJIEKIeDliJokSMzuaOAECRQoCKnpKHbhipgaZSRtgYNHChYaXGhy8gAEjhowZ\nU3vSqJE1KQsbN1rgGGEih44dPHr4+PHDBwIgaU+i6IjhZQMWQVgIuWFjCIsGRTveIFKECBEC\nRowcIYAgMEUkGmZeSKJkyJAJqDMsQVGCLQYNTJo40fHkyQsoUUJI6ez54JQGVEpUgSvEhhUb\nV7CwyKLFhJYtXFCQgNGkOpEkXWBU8PKFAODeBIH+ZADDIoyYEmOmgCFTpsoKMyAwbFkC4gya\nNGrQqGmyZs0SNm24cQQCBDgB3kAIvFFCGRnAEccYcowBxxx0XGEGClTUUYMdTNzRARJ24OHF\nHHnoMQcee+zhHR99HNiFETBg4ccfgFQRCBlhiWChIF+MIcgGHQwCgR0DEFKIIYcgksgccJjA\nQQVAdGHHgTAssIcibiwiCCNz1GGBCHOAQAggZIQAAiCNKGHCHA3gwYQjj+wAiSNIRCIJEli4\nAcQkvRHAyB56PMEGJXpUYokWlwyyRRwXJDKCiIRsAAEmf2SiCRpr5GDAJkQwQQQGU3DiAxuI\n9DZDJ558AooalPRwAiT+OMSBAgqCACKIAyBQAVkiSIQiSiSjPKKDJqQsUsEbNvwhxQM9eNIb\nECuUYkoopyCxACp2iMCVAxoIMsYciWTwSSqIWFAHEkvkEAYTTKjiBBpMFMBABhzY0YNnhQBh\nyg6F8HHCKqWcUYYNDdTAwgUazIECCzX0wEoODQhBSiuioJGDB47k4IomOjiiwRgFePJKYAT8\nkEIMcExRSRNPoDGKS2C9dMMNsMRSgSwXzJJDGXwskQYtO6BRRC2WUFDLKpbwMXJaCBjxRigc\n8HHGHU7Q8MAYDSDVkRBCmFDCG6zYYkMQaHhwCy1uNIEGEXtoQkQTPBhBRCdpBJYdD6jgEgb+\nLmA8UgoeXyRlgQ0Y5KKLHKyoccYthsTghBO3VNCEDqjwoMkaPLxgmSIk86UIDDs48oQHstxx\nixChQVbHBKrYQUkROjyiChpOFJHDLbLgoQYFoPBQhB+7UOLDI4E1zcMavMjRxh2c3JFDH6+4\nJEgDIPTCiRJp6GBLDrT4YggttKhgyy2m/DLDEzzw8AQRPBBBMgwI7AEGMB18wUgUFwRDgggN\n1NoCMAmAxB1ScYYklO12kwjfJFQAAQ/gBQhP0MQJHGE3YSggBnsgBSQCEQIODAMMtiDGBESB\nCTwUw1ZzEAUHCNGHO0RBFa2ghB1scYYc4IEWaoCBGvaQibqlZQL+nfDBEUAxgz/oghRHSAAT\n5HCHYMjBGCjAQx7mMAdBCEIUcWgEADJxjFfEwRHbswEy1MAK2RThDJ5RgAJK0YQ7xAAMD/BE\nAAQigyyI4Qo3EAIIQCCIPAgCD6X4RDICcIoOWMAUtuCFMcqnhiL0gHOeUQYHEuGIZSyBA4z4\nRBYA8AEqQEIMEQhEL+IgClsJAgKDGEIwRECIFljBEsyYgDEWAAruveAJvWEDBfBghSiAogxB\nIEQemuEMJVzgE1WcAyAAESb6FOAZhygDNBYgAixM4AFpIEQU0gCJJ8gCPAhgRAhkgYUwgCEN\nb8gDLqKBg0R8QRSJYMQlxGCMGwSBFMz+kMMfmNEBRuDCFAlwhSRoAARa/OJACOBAKe6QgFbo\noRZWwMMsWECFC4TABSMAwSxmcYE/CEEC0jgAAxoRgQ58AgDKOMY04qAHIszxQANQBicSYIkv\nBAEHeMCFFgaBMA3gIAtZqMMRYHEBXUwgEgxwgi2MIRBIRKESqhgFNQ4kEFsUAICpaMYGXkGF\nL6BACziYRgcI4c9eYIEQExjGNALQiFtUQyCUSAMpfnEGClJVIASoACdO0YwHgIEQCkABLrIw\niGaUwhKWaMYgrHGMWdzgCAKwgypcwQle6OEXt4AEU+8qEASwwQ2qWIAUekEJG9QBAqbggBXE\nEIUFKKMUDxjYxACMMQ1SuMIKVqiEHYoACVZwliAIuMYAEoCNViwgGwm4RASagYlsmOK42khA\nNjhRgALwQQ+R6AQD3PAGTfy2IAgwQHSzAYFsYOMYzZCEMh4wi2w4170ytYYwrGFdTxDhoN8t\nyCQKkIIIJEAbSFBAApTh3gUYOBvKIG4EBlAACsgABnvIQX4jAgRHzAAbGF6vAo5xCWVMYxpI\nkEIEYsCLU6yAEnadsESgUIABRCEK2IhABIQh4wHQgAbWsCwfnLANFZskAJ2YQUN2UYAYzIDE\nXWADDO5A1YAAADs=\nENDofIMG\n\nteapot = <<'ENDofIMG'\n\",\n\".. c #998074\",\n\"#. c #84aadc\",\n\"a. c #c47e55\",\n\"b. c #4c6ea0\",\n\"c. c #d48a64\",\n\"d. c #ecccbc\",\n\"e. c #8c6252\",\n\"f. c #b1a094\",\n\"g. c #714628\",\n\"h. c #af8a76\",\n\"i. c #2c5284\",\n\"j. c #98745f\",\n\"k. c #8f5124\",\n\"l. c #844614\",\n\"m. c #5074a6\",\n\"n. c #aeb2b9\",\n\"o. c #3e291c\",\n\"p. c #44689b\",\n\"q. c #4c2705\",\n\"r. c #1b2b43\",\n\"s. c #e1c8bb\",\n\"t. c #dd782d\",\n\"u. c #9c5824\",\n\"v. c #547aac\",\n\"w. c #906e5a\",\n\"x. c #545253\",\n\"y. c #e07e33\",\n\"z. c #bcaeac\",\n\"A. c #aeb6bc\",\n\"B. c #6f737b\",\n\"C. c #7e5942\",\n\"D. c #b55e1a\",\n\"E. c #7c5134\",\n\"F. c #8c7a70\",\n\"G. c #62524d\",\n\"H. c #bc8a6c\",\n\"I. c #936754\",\n\"J. c #6e6d75\",\n\"K. c #8cb0e2\",\n\"L. c #d4beb4\",\n\"M. c #2a201a\",\n\"N. c #c48664\",\n\"O. c #412105\",\n\"P. c #a95a19\",\n\"Q. c #747a7c\",\n\"R. c #2a2e33\",\n\"S. c #484c53\",\n\"T. c #8690a1\",\n\"U. c #6c524c\",\n\"V. c #505967\",\n\"W. c #040204\",\n\"X. c #8cb6e4\",\n\"Y. c #8f4912\",\n\"Z. c #846e5c\",\n\"0. c #244a7c\",\n\"1. c #dcc2b6\",\n\"2. c #33261b\",\n\"3. c #81736c\",\n\"4. c #3c3b46\",\n\"5. c #735f53\",\n\"6. c #545e69\",\n\"7. c #bc7c58\",\n\"8. c #4c2f1d\",\n\"9. c #a4806b\",\n\".# c #604c4c\",\n\"## c #d4916b\",\n\"a# c #5c80b2\",\n\"b# c #e3d3cd\",\n\"c# c #c8ad9a\",\n\"d# c #bf6c2e\",\n\"e# c #08121c\",\n\"f# c #9c5e34\",\n\"g# c #9298a1\",\n\"h# c #8b7f7c\",\n\"i# c #835f44\",\n\"j# c #a46e54\",\n\"k# c #474649\",\n\"l# c #a65d26\",\n\"m# c #be6420\",\n\"n# c #7c9ed2\",\n\"o# c #ac622c\",\n\"p# c #726e6c\",\n\"q# c #e1a684\",\n\"r# c #a48676\",\n\"s# c #54464c\",\n\"t# c #a0a4ac\",\n\"u# c #b37b5a\",\n\"v# c #947a70\",\n\"w# c #543d31\",\n\"x# c #743e12\",\n\"y# c #98bcee\",\n\"z# c #d49e7c\",\n\"A# c #64320c\",\n\"B# c #d4cac6\",\n\"C# c #2c3642\",\n\"D# c #6e686b\",\n\"E# c #5c463e\",\n\"F# c #7f7575\",\n\"G# c #bcb2b0\",\n\"H# c #979dac\",\n\"I# c #a47a61\",\n\"J# c #8c9094\",\n\"K# c #1c262c\",\n\"L# c #d3c3bc\",\n\"M# c #9cc2f4\",\n\"N# c #af7455\",\n\"O# c #fcad5f\",\n\"P# c #6486b8\",\n\"Q# c #d4742d\",\n\"R# c #6d4e3d\",\n\"S# c #242224\",\n\"T# c #3b444c\",\n\"U# c #181515\",\n\"V# c #6e4024\",\n\"W# c #749bcc\",\n\"X# c #afabac\",\n\"Y# c #7e6a64\",\n\"Z# c #343634\",\n\"0# c #e8ac8a\",\n\"1# c #343a44\",\n\"2# c #b18f7a\",\n\"3# c #dda07f\",\n\"4# c #6f380d\",\n\"5# c #2f5684\",\n\"6# c #a08d86\",\n\"7# c #5f6068\",\n\"8# c #625751\",\n\"9# c #16253b\",\n\".a c #94b6e9\",\n\"#a c #dfcec8\",\n\"aa c #3c6194\",\n\"ba c #ecdad3\",\n\"ca c #948a89\",\n\"da c #a4c8fa\",\n\"ea c #bcb6b8\",\n\"fa c #604432\",\n\"ga c #cc6d29\",\n\"ha c #949ea4\",\n\"ia c #413024\",\n\"ja c #a48a7a\",\n\"ka c #9a867d\",\n\"la c #1c1a1c\",\n\"ma c #342116\",\n\"na c #bc8364\",\n\"oa c #9c8674\",\n\"pa c #844e25\",\n\"qa c #3c4a5c\",\n\"ra c #582c0d\",\n\"sa c #c7835a\",\n\"ta c #613c24\",\n\"ua c #614b41\",\n\"va c #adaeb5\",\n\"wa c #805c4c\",\n\"xa c #0a0b0f\",\n\"ya c #c4b2ac\",\n\"za c #648abc\",\n\"Aa c #af846a\",\n\"Ba c #c68a69\",\n\"Ca c #483c39\",\n\"Da c #7f400d\",\n\"Ea c #646e74\",\n\"Fa c #a85515\",\n\"Ga c #042244\",\n\"Ha c #816759\",\n\"Ia c #95817c\",\n\"Ja c #9c9aa1\",\n\"Ka c #9c6b54\",\n\"La c #7e4924\",\n\"Ma c #0c1a2c\",\n\"Na c #5f595f\",\n\"Oa c #6f615e\",\n\"Pa c #474149\",\n\"Qa c #8c9aac\",\n\"Ra c #cbbeb8\",\n\"Sa c #806e68\",\n\"Ta c #82624e\",\n\"Ua c #949294\",\n\"Va c #b4652c\",\n\"Wa c #9c9ea4\",\n\"Xa c #72574c\",\n\"Ya c #2a303e\",\n\"Za c #bc9175\",\n\"0a c #9c7a64\",\n\"1a c #261a13\",\n\"2a c #aca6ac\",\n\"3a c #341a04\",\n\"4a c #593520\",\n\"5a c #d49878\",\n\"6a c #26282c\",\n\"7a c #475261\",\n\"8a c #3f3535\",\n\"9a c #63676f\",\n\".b c #a47255\",\n\"#b c #bc967c\",\n\"ab c #52433a\",\n\"bb c #80a4d6\",\n\"cb c #544c4c\",\n\"db c #bc723c\",\n\"eb c #645e54\",\n\"fb c #a4abb4\",\n\"gb c #c89070\",\n\"hb c #8c7469\",\n\"ib c #c7b8b3\",\n\"                                                                                                                                \",\n\"                                                                                                                                \",\n\"                                                                                                                                \",\n\"                                                            wawae.e.wa                                                          \",\n\"                                                          .#j#N#7.a.db.#                                                        \",\n\"                                                            8.g.x#C.o.                                                          \",\n\"                                                  N#DaA#raY.Xa4aV#4aPas#q.W.W.6a                                                \",\n\"                                            i#O.l.4.4.4.4.4.s#wa7.N#wawaXawawawaA#q.C.                                          \",\n\"                                        3a3a4#wawawae.e.e.I.j#m#d#VaN#KaI.e.e.e.e.waDaO..#j#j#N#N#j#fa                          \",\n\"                                        O.A#wae.e.I.e.I.I.Kal#m#m#D.u.KaKaKaKaI.e.I.e.Da3aXaE#C#W.o.C.                          \",\n\"                                      w#e.k.I.I.Kaf#KaKaKaKal#m#m#D.l#j#Kaj#KaKaKaKaKaFai#u.    GaDaI.                          \",\n\"                                      .#waKaI.KaKaj#j#j#j#j#VaD.m#FaVaj#j#j#j#j#j#j#KaKae.U.    9#o.Ka                          \",\n\"                                      .#Xae.Kaj#j#N#N#N#N#N#j#N#j#N#N#N#N#N#dbdbN#N#N#I.waU.  e#M.taPa                          \",\n\"                                    .#U.Xawae.Kaj#N#7.dbj#a.a.a.a.a.a.a.j#7.sa##naj#I.e.waXaU.Yama.#                            \",\n\"                                    .#U.Xawae.I.Ka.bna3#0#3###sasaa.sac.##Ba7.u#N#Kaf#f#waXaU.4.s#Pa                            \",\n\"      j#N#5aW.Y.u#j#R#            8a.#XaXae.e.I.KaN#naz#0#q#gb7.7.N#N#N#u#nau#N#N#Kaf#f#e.waU.LaU.                              \",\n\"        4.Hahb.bI.j#KaY.          s#U.XaXawae.KaKaN#na3#0#3#gbna7.N#u#u#N#7.u#N#.bj#KaI.e.waXa.#                                \",\n\"              G.2#e.KaI.E#        .#U.Xawae.P.Kaj#N#H.z#q#3#gb7.7.7.7.N#N#u#u#N#.bj#KaI.e.TaXaU.0.                              \",\n\"                Ca.#e.j#Va  5#aa0.MaU.Xawak.d#I.j#I#N.5a3#5aBa7.dbN#N#dbN#N#u#I#j#KaKaI.e.waXaU.0.i.p.                          \",\n\"                  abU.I.KapaaaaaxaGaU.C.wau.VaKaj#I#na5a5agbN.u#N#7.N#N#N#N#N#.bj#KaKaI.e.waXa.#R#m.m.m.p.                      \",\n\"            zaW#0.0.s#waKam#0.0.e#GaU.C.k.l#I.KaKa.bnagbgbBa7.u#7.N#N#N#N#N#.bj#j#KaKaI.e.waXa.#.#b.m.m.i.i.0.                  \",\n\"    5#aaW#W#n#aaaa0.U..#e.Kau.ta4aLak.k.u.o#e.KaKa.bu#H.H.nau#N#N#N#N#N#N#j#N#j#KaKaI.I.e.waXa.#fab.m.i.i.i.i.i.0.              \",\n\"p.p.p.aan#W#0.0.0.0.p.uaU.KaKal#o#d#gal#o#o#e.I.Kaj#N#Aau#u#N#N#N#.bN#N#j#.bj#j#KaKaI.I.e.waXa.#E#m.m.v.m.i.i.m.n#bbn#          \",\n\"p.p.n#n#n#p.0.0.0.0.0.xa.#waKaKagaQ#t.y.d#dbi#e.I.Ka.bN#I#N#N#N#N#.bN#N#j#N#j#KaKaI.f#e.waXaU.U.w#5#m.m.i.i.i.m.bbbbbbbbaa      \",\n\"n#n#n#n#n#n#0.aaaap.aaaas#s#waKaj#na##O#dbl#wae.I.I.j.j#j#j#j#j#j#j#.bj#j#j#KaKaKaI.e.e.waXaE.Hai.m.m.i.i.i.i.p.p.bbb.b.p.p.aa  \",\n\"p.bbn#bbp.p.p.p.p.p.aaaaaaua..#be.Kaj#j#u.XawaTae.I.KaKaKaKaj#j#j#j#j#KaKaKaKaKaI.I.i#waXawaR#uav.m.m.v.v.i.b.bbbbbbbbp.p.b.p.p.\",\n\"bbp.p.p.p.p.p.n#p.0.0.0.0.p.8#Oa2#ZaZaZak.XaXawae.e.e.I.KaKaKaj#KaKaKaKaI.w.I.I.I.e.waXa0aXa5.5#i.m.m.v.v.p.p.#.#.#.#.#.#.b.bb#.\",\n\"bbW#p.p.p.n#bbbbp.0.0.0.0.0.0.0.x.D#3.3.w.waU.wawae.e.e.e.f#I.I.I.I.I.I.I.f#e.e.wawaXae.w.ua4.5#5#i.7ai.b.b.b.p.b.#.#.#.p.b.b.#.\",\n\"p.bbp.bbbbp.p.p.p.0.0.6.p.p.p.0.0.0.0.9#R#wae.9.j.wawae.Tae.e.e.e.I.e.Tai#e.wawaw.Aaw.hbOa6aC#5#m.v.v.#.p.p.b.b.p.#.#.b.b.p.p.b.\",\n\"0.0.0.p.p.p.p.aa0.0.p.p.p.p.p.p.0.0.p.qaT#s#Z.0a..h.I#I#ZaZaI#gbI#.bH..b.bH.h.j.r#HaU.PaV.V.Na1#v.m.K.K.K.#.b.#.#.#.#.K.p.b.m.p.\",\n\"0.0.0.0.p.0.0.0.0.0.0.p.p.p.p.0.0.p.p.qaqaqa2.iaR#HaY#ja2#2#I#Za2#0a2#2#h.jaoaF.8#V.6aC#C#C#CaNab.bbbbK.#.b.b.b.#.K.K.#.#.#.X.#.\",\n\"b.b.p.p.p.0.i.0.0.0.0.p.0.0.0.i.0.0.qaqak#6aR.6a3aiawaY#OaOaOaD#Iah#D#OaF#cbPa6a6aW.V.6.1#C#7ap#b.b.b.b.b.b.b.b.b.K.K.#.b.b.b.b.\",\n\"bb#.#.#.#.b.b.i.0.p.p.p.0.b.b.0.0.0.qar.YaYaYaR.K#Z#E.xa1a2.S#.#x.x.S.R.laU#1#W.W.9a6.J#J#T.7av#K.K.K.K.b.b.m.m.b.m.K.b.p.m.b.b.\",\n\"#.#.#.#.#.#.K.#.#.#.#.#.#.b.b.b.#.p.qaqaYaR.YaR.Pa6ak#S#lalaW.W.xaW.W.W.W.U#U#ebT.hag#g#haT.7ac#K.K.K.K.K.K.b.b.#.K.K.K.K.m.b.b.\",\n\"#.#.#.b.b.b.b.#.#.bb#.#.#.b.K.bbK.#.T.T.J#R.YaS.S.x.ebebR.2.S#S#S#T#S#S#S.9a7aEaEafbhag#6.7aV.m.K.K.K.K.X.K.m.X.K.K..a.aX.K.b.m.\",\n\"b.b.p.b.p.b.p.K.K.K.b.b.b.b.#.#.#.#.T.T.J#UaJ#J#g#g#haWaWa7#9a2at#fbA.t#9a6.9aJ.EaEafbV.6.V.Nam.b.m..a.am.b.m.m.m.K.X.K..a.a.am.\",\n\"  p.b.p.p.b.p.K.b.b.p.b.b.b.b.K.#.K.7a7aV.9aWat#X#WahaH#ha6.t#n.n.n.n.fbfb9a9an.t#t#fbfb7aV.7#m.m.m..am.m.m.m.m.m.m..a.a.am.m.m.\",\n\"  b.p.b.#.#.#.#.#.b.b.b.b.b.b.K.Pax.V.7aNa7#7#t#vafbB.B.B.B.B.n.A.A.A.fbfb9aA.t#t#fbfbQaH#7#D#m.X..a.a.aX.v.v.v.v.m.m..am.v.m.m.\",\n\"    #.K.K.K.K.K.#.b.b.b.b.K.K.K.T.S.V.9aB.ebNaV.p#9a9aB.D#9a9aB.A.A.A.9aB.B.Eafbn.t#g#hat#X#m..ay#y#y#y#.ay#v.v.v..aX.y#.av.v.v.\",\n\"    #.K.K.#.K.K.K.K.K.K.K.K.K.QaT.V.7#Ea9af.f.2at#OaD#F#Q.J.9aEaB.Ea9a6.Ea9aEaV.H#H#t#2aD#J.v.m.y#y#y#y#X..ay#y#y#y#y#y#.ay#.av.\",\n\"      K.K.K.K.b.b.b.b.K.K.K.K.g#g#t#D#fbWag#c#X#2a2aeb7#D#Q.vaA.2at#p#9a6.V.7#7#9avaSaSaSav.m.v.v.y#.ay#X.v.v.v.v.y#y#y#y#y#y#y#\",\n\"      K.K.b.m.b.b.b.b.K.K.K.K.Ja7#7#6.2az.#ac#z.G#eaG#p#2a2a2at#t#t#t#7#9aD#J.SaL#RaRaF#v.v.v.v.v.v.y#m.v.v.a#a#v.v.M#M#M#y#y#  \",\n\"        b.b.m.b.m.b.b.b.K.X.7#7#7#7#D#3.1.z.yac#yaibh#caB#L#eaz.z.z.z.z.F#h##ab##aL#ibibv.a#m.m.v.y#M#y#a#v.v.v.a#a#a#a#M#      \",\n\"        p.b.m.b.b.m.b.b.m.b.7#9a9aSahb..m..ayayahbhbF.h#Ias.RaRaibibL.L#kab#bab#1.L.L.y#y#a#v.v.M#y#y#M#y#v.a#a#a#v.a#a#        \",\n\"          b.m.b.b.X.K..aK.b.7#D#F#hbv#m.b.m.m.F.F.F.v#v#F.v#L.L.L.L#..ka6#h.s.1.L#1.y#M#y#daM#M#day#y#M#M#M#a#a#a#a#            \",\n\"          p.b.X.X.X.X.X.X.X.9aD#6#..m..aX.y#m.m.F.v#v#v#....1.Ia....kakar#r#r#1.s.M#M#y#a#a#a#M#M#y#y#daM#dadada                \",\n\"            .a.aX..aX..aX..aD#SaF..ay#y#.aX..am.m.........s.s.9.9.r#r#r#r#kakar#M#M#a#a#a#a#a#a#M#M#M#M#dadada                  \",\n\"            K.X..a.a.a.a.aH#vab#1.y#X.X.y#y#y#y#v.v...s.d.d.d.s.r#r#h.jajajar#a#M#v.a#a#a#a#a#a#P#dadadaM#                      \"};\nENDofIMG\n\ndemo.show_image('xpm', 'color', \"/* XPM */\nstatic char * teapot[] = {\n\\\"64 48 204 2\\\",\n\\\"   c #145ec4#{teapot}\")\n\ndemo.show_image('xpm', 'transparent', \"/* XPM */\nstatic char * teapot[] = {\n\\\"64 48 204 2\\\",\n\\\"   s None c None#{teapot}\")\n\ndemo.show_image('xbm', 'bitmap', <<'ENDofIMG')\n#define flagup_width 48\n#define flagup_height 48\nstatic char flagup_bits[] = {\n   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00,\n   0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xef, 0x6a, 0x00,\n   0x00, 0x00, 0xc0, 0x7b, 0x75, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x6a, 0x00,\n   0x00, 0x00, 0x30, 0x60, 0x75, 0x00, 0x00, 0x00, 0x18, 0xe0, 0x7f, 0x00,\n   0x00, 0x00, 0x0c, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x06, 0xe0, 0x04, 0x00,\n   0x00, 0x00, 0x03, 0xe0, 0x04, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00,\n   0x00, 0xc0, 0x1f, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x7f, 0xe0, 0x07, 0x00,\n   0x00, 0x70, 0xe0, 0xe0, 0x05, 0x00, 0x00, 0x38, 0x80, 0xe1, 0x04, 0x00,\n   0x00, 0x18, 0x80, 0xf1, 0x04, 0x00, 0x00, 0x0c, 0x00, 0xfb, 0x04, 0x00,\n   0x00, 0x0c, 0x00, 0xff, 0x04, 0x00, 0x00, 0x86, 0x1f, 0xee, 0x04, 0x00,\n   0x00, 0x06, 0x06, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0xe6, 0x04, 0x00,\n   0x00, 0x06, 0x00, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x66, 0x04, 0x00,\n   0x7f, 0x56, 0x52, 0x06, 0xe4, 0xff, 0x00, 0x76, 0x55, 0x06, 0x04, 0x00,\n   0x00, 0x56, 0x57, 0x06, 0x04, 0x00, 0x00, 0x56, 0x55, 0x06, 0x06, 0x00,\n   0x00, 0x56, 0xd5, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00,\n   0x54, 0x06, 0x00, 0xc6, 0x54, 0x55, 0xaa, 0x06, 0x00, 0x66, 0xaa, 0x2a,\n   0x54, 0x06, 0x00, 0x36, 0x55, 0x55, 0xaa, 0x06, 0x00, 0xbe, 0xaa, 0x2a,\n   0x54, 0xfe, 0xff, 0x6f, 0x55, 0x55, 0xaa, 0xfc, 0xff, 0xa7, 0xaa, 0x2a,\n   0x54, 0x01, 0x88, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a,\n   0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a,\n   0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a,\n   0x54, 0x55, 0x8d, 0x50, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa8, 0xaa, 0x2a,\n   0x54, 0x55, 0x95, 0x54, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a,\n   0x54, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\nENDofIMG\n\ndemo.show_image('png', 'color', <<'ENDofIMG')\niVBORw0KGgoAAAANSUhEUgAAAC4AAAAjCAIAAAETQp8oAAAIVklEQVR4nNVXPYgbSRb+xm7B\nK5CgC07QtaCDOvBCDeyAFAxIwQYdbKCBDeTgQBMqtOGCcTYOvXDBODjwHBzsBHcwExzMBAtW\n4GN7YQ1ScKAOBNPBLFcLHugGC7pgBf0WeuGC1vz6h7XZ4O5DIJp69dX3qr969Rp4A3erv69H\nYQn8aasDxh0Aw66JTtPU5ZIIhLsAvIZXw9rLJItfvd74vVzNepPx3Rh2DQAPwPFO3zqenaaO\nGcAdAAdRkuf50TQxyv8Q0gqh0ZWYNQDD0GRpHrbVJHFRYvtGE9H9nr7/dAwg8OkugLldmFaz\n1fDLtXKj1eytt76fv9JKKkkmaE5/yFbMD0IzDA2A3UEbQFsHH6bs7rsGvt0dnC9yu1heRTwZ\ndKPkHMDhTj9OXp0tXpelCBp0F8DXo/DLjp5ni+3uxou5fXT/c5Tl/HwxPcvO3dIDkOXFxGYA\n0tz+5/neNJooRSqVqi1DE3iXqyhJp2n+1dODooBjVpKKAm2t7gAIpCACgHUlD6IkXFfj2HaN\nYnBs3Ur2oK0BHO/030zqDgBmVpIAVPv924AI7cDvt3X16L0/usKzUcjAo4MIwKjftjb1SRAR\ng6/UVjje6T8bhXvDlZ/3Rt3Di/QOJ6fa9wEMu6arJJFwXGSOT6b2NsvEppPTNMnSZ6Owa4I0\n5Ulsn+8OAIABIh34WvuCKIotAN/Hg377293BDRZFBCDNmQABxNbN0vwwig93BrHNJnHS1TLL\nnE/U7xqfJBhp6m5rAdDTSkkaz6xWUitSvhCCRk9Pjnf6StHR1BYFGGwUSYLRgZKUZO4Gi1Ey\nshYAEQE4iJJwPSgKMLD1dEwQAI6myf2n469O4rZWSorxzD48iFAdxcsXEZ1aJfyJtbF1/bYO\nTaCV/ACD+PRrI//3MOzeOC+/yrvX4RM96Lcz50ah8Wm1EXfePwdAaIKvR/1RaKrHve0wSTMA\nRYHMrU7A26vTs2HY39Tj2AJAWdYEDqOkBPaGYbJ4XTKWS14syyRdnF33S1v7Twbdb3cHO/02\ngJP4FMVFCpKIiIFh15Agm7rM5Qykeb5a5pJlFJrT1B1ESdjWD/pmkmRK0ZNRtxpNUzfsmszl\nHe0nNo2SbBzbyrWhCa4yapuWcywEqFZblmXLl2se/JpQ0h/HPypJZ855pbeh1d++m5vA37yn\n7in55+3eX17EZXmhRQkBIM/ZprkkAlAwj2d2Z9ADUDBCo9e1ZObK0NUsAno6uMpIXnhX+jSz\nWeZYK+kTJok9ffZA+qKtVV5wASYSBBARAbHNK8YVi80LBjsUbSUlyCcIwDEe7o/jxFa+cK5w\nedEzgZJUERWMauiCJXMdHez2e0+jxLq8ykJJGvXbjw8nWx2tCFGSHU+tUTItWCuSAiDW/jUt\nxxNLwMOjKCDSSkpJWVEUBZjZOpfmeWWvqc2Ysd0zVU49rR4eRVcsjpkgKmICigJ7J7GSlOYM\n4NHR1KZ5Fbm9P54kqSTR0XLromhcnSMGtCQGADqaxv22BiG68FXljgpPx/Etr1+dI1+AiHyi\n/SgGsN0zkogvRg+iBL8Gxzv9qlP4eFye8f8/mOBG87b2rrjfHMc7/cTlKKClJEJi87ZRW1+d\nXAZ8cNV9P9o6eDzojGN73RfPdwdpxvvjWeBLZrbSFQU62mfm63N/GymBTx2tQqOVpP1xEiUr\nu/fbOuxom7loZisjEVFeMDPGcWayj5XSb+vtnk7zQiv55GSyagcBAFW7l2SpL3Wlwye639OD\nrnHMB9GMIHySjlcbQQQi2NT5hIub6EJKtbG54ywviJAzJ9Z1dNA1KrZpynwysePYjmM7Co0v\n5eNBL0rS/atzTbkrtPI7WgEYdo0QSHN2jnPmwgFUZAygmNjs5mu5wg3b+oRHg24BuEoqMwP9\nts6ZT2ZWCwJB+X7qeNDWmXM508ODVYnqmkAAu6P7+4djx4VPomeCtlbMvPVG79PVwVZXE4TR\nFCf545Mpbl3QXKL/WWtdSbtY4sJULSkWeWE+qb9IUikEL1n9rv7P6Q+b91SNsB1+/v08WXLZ\n8LyG8DbX1XfJebEsG1RrNuvlz7UFMzNMS36mpJLStOQ9JQXVXi+WX2xq55YP//GyWv12r/Dl\n5qcN8uz5AkAJnKZ506/XBVyBl/GP1bfd5sYn38/Ts9R58DqfNj/f3PhjGB6+mJIg5zhc18uC\nPc9rCmop0fLrLxNb92oM1D14WP0AqIZYlgBwdqtBvY604CRnm7MAfCGUL2c26xrdM0oH0qVF\n1fjHNus9OuA8VUgPdwZEAFj7xMwMntnMpnnmOPBldR0QkZQkJVXI8sIE/uVX6u1dMcpvNRtl\nWTYEbbb8L3t/yF6X4/mZzYqax3WvweBwo5XY5e/qxMuyLPngu6Srm8uyXFcytouWlH+fzL1f\nvB/yZVPWWlK2pHDlUklyy7LRIM/zxFq5VoNjbjUbZVl7MbdvkcI/8eanzWWJhVvOX7lv/n02\nP89Vs9HAWp0aUlKNUfcECSzc8l7L9+u1+bn7JrZfbLSIoJpkAvnXf83P3dItueF5Rknlk1cT\nS8bPv/BPZck/lbJBql43SjouyxKVlLcU/mejkFEcRtYEghlEJASKAlIgL+CYcy62jE7ZEcgx\nXxZWE/ijsFP1G9cJCXgy7PpCAOACKedaSkEAsL1/Ffm2ElfAKGkCJyWBwcWqDhDRUbQqJI/6\nnTRxDEQzezkvydzjk2hvO7xeuAAw8Oho+paFbuItUqQkgACkqVOSSICIolliL+hHoUkd5znW\nFVl3o2Ax4+FB5BMB7yhkHyQFgGPurfs2ZRCc42tVFcPQnNr8/V2Qe1dBfS9ue2Vv2CUhiGia\n2Oczm7mPIf04/BfyDD1tMD0WfgAAAABJRU5ErkJggg==\nENDofIMG\n\ndemo.show_image('png', 'grayscale', <<'ENDofIMG')\niVBORw0KGgoAAAANSUhEUgAAAC4AAAAjCAAAAAG5S1ejAAAEJElEQVR4nKWTXUwcZRiFH2YG\nZpiBLsx2wW6ZpU1YC+3axWClf7ZKY5NVozHRxIYaL0xq1YuGeOFVRW40TXthk4aLxsT/xJjG\n+tdiGkUl1nQV6rYokuy2IFugy8/irp3dHXYGvFiwBdQ08Vx9+d73Oznfe84LAIjQNv+ELdBy\naVqTRBSh/8p6aGMZWpDomBwwETg7020sL0NjG0XsTTT9GmlSdreji1xZ555bvzmyVvcNAI/s\npRX/8lfi4uHoREIEnrnEKwNjcxUibdt+39PX6gwNTEkkB0l+3VPtdgclQI8fs0zd8gvoMkZX\nMBywY3B0Ox0FKoGcTvtKhQuQa5tBuvXmkHOCx4Y1xS7o6Qg29vFi6DvMe79paRjP5sIgAL/1\njxwKJC4ewS72+kp7WfX4UQRgFUlBjA1/2R7t25DQdpbZiQJPU5V1xVMuqW+9ykc+X37WKJLC\nAmD8gkJX0HIOS3S3f+B3h48jAVNI0Viztbub4wCdC+rUf/3J7eEBOgr6l0Dbr4TUpffBl0Jw\ncARr5qYvL2wPM1d8bv65a3kzPTKKBHU7AuFT53eAS3FaSsdyynQcRGiNxXaVff9wfa+Of/rB\nT66OpgkmRNiYkkssj6CuDusJ6s4YDTUHTjsCuEiNauQu7MNqXJ8LekGoRwAVXNGkV+1/33Wn\nmVdERYx5EWDCttbJqpQ5NqCRSgV0UbE0BBjzP/XpBDn90Te3ll3q8aXXqGIVAvSInau8rrSV\nm5iaY9DaU6TUdyKAKVUhWh/qSU6Owmv9mv9wIQ+OxynqbpZ6IQ6cAgrzURXtc/ZoDnQtGWFH\n6z/OW/t/dhkARbfR2DGer5avbnyZZWleCv/+C13AkYmP3bkxqy73X+y6v9F9NgLNW8Sf7DJs\nyzI+X8ne3DK99r0YoDNSEUHbdb95RiozLWR5TM2ABP79fyRlc8gfiKZ7wuFQ5dOR01CU8vpp\nkZMp05St+UFrga4IQN3npMg7W2/8UCm5k9uT2TcgID7/rqkF/LnDANTvkNYNvlMIZn6L73re\nYfWMEdEynm8bSkIXs3Lppki21G3fsGpr3bU1yvS21InFHO8sjTMfryzNXIxbmyPXhPrm0Bkl\nfXdGKr/DfVl2ZEEQqJhl9O91SF+fFMtWR+8KeKdsogdSxe3ynCdnR0dn3IqmuFyKkqwxFtmN\nalutu2/qx3FRsZuGXFm7a8OsL+r5ikSFx53Vb5RJomBWO30L7WaDNTN8fthTrLrmZHnGVz58\n4Z4ST81nU3/Khl6SnbWy5ZVGxu5btOmQfa7GUmRLzZhmU0oyu8B4SOwEEJ/VsFJVCq/ftCm/\nxnDZOVC+gCd/dnqB+NsH1QzgnLzFxoX2CoGELiu9kxBKpo1JAOv4ygwvhsDcNC6lTgF7h25u\ng7mivaD9QKlyOZxcUVyJvwDv65E2xA9RYAAAAABJRU5ErkJggg==\nENDofIMG\n\ndemo.show_image('png', 'transparent color', <<'ENDofIMG')\niVBORw0KGgoAAAANSUhEUgAAAC4AAAAjCAYAAAGcIAh/AAAIl0lEQVR4nOWYIXDjyNLHf7p6\noMU0TIIDtcxhNhT0Mi9LoD+2y7JsF+6xhG3YBSYsYWt2gg6zWcS+gSM2w9RsPiDbiS/Z/e7u\n3b33ql5Xqcoujbp7unv+/+6B70i2//HLskn3G8f8xLJaO34COJ3WqX30+BgwIiCML7oYiKps\nXcw+362pjDyp+Z6t/19Op3UC+AfA3fk8uahsHj1RFdgZv247QgjcPnRZXRV/3txBmtqmvecZ\nwGlTp94HmknFuou0nWNeW0SEdzPLu8tVBlAWkg4hnE9smtkSFyMAE1tx0z5y1rxh6zzDALcP\n3WE975s6nTbjlj8tJmn8qPwnAvh75NdPi9TUo5Wfnr/4spgeTN+cz5MtJF2u1kDO1JbpH/CU\n4AfnuTht0sfbNrNVxWJW03aOresz2KWwDwNr1wPgg+N/v12kh3ZNVQmVN1QTk5q6HBfvpTLC\now/8fHnNMEBUpTLCMIwh/QmgNDmyq7k3leG67bLmTcVq67JpXaEoWxefdryY2ARjVX0vMj8B\n6M4ccEjz3yoipElZpPnOQ+A4IL9Hvi6bpMDH6zYDWM4nyTlPITkigqKHtUdJvzufp6/LJl2c\nPh3ci+U03TyL0836EVuMB+10WqdpZRDJiTrQR+X+wWWvKl87z/rR0/Wer8smTesyea+st45v\nnxajAR1jYMsiWVuQi9BuHQBFAe/nk/Trbu2R8mqXfx8UAXJg6yIbH7hpt9ycL9LW9ay3HVNr\n6PtIIcJ8WlOIAQXv4+thAZjZisoIq43DVgZbCVWRk+fC8vKeu/M5VSXcPrhsGEBR6kowArUt\nqYzQ9fGl8roytG7coux2MRZwyaiI7O3lKhNyYASNd5er7Of7bTaxFZXJWW0cH3bJPqrRr8sm\ntY+OKi9YO8fWxWw+sampS2xl/nxNF8LfjEz/qXI6fYkdf/iE/lYKkfR+PqGPkWVTp2IPZ7xS\nij+Spi7TL8t5Wu6YBODirKHzI/AOA/Tx6fj/MPtfT5tEzqG0bCGpObHctB0K2cVpk1wMhKCo\nKlFBBFbbEQIOnk9skb4spunXT4t0Ph+57X77CMOzEBjZgRPZ6bROkgvOR/oYUMCHcFB8pHzZ\n1Dz6yHXb0Uws7+d1Wnc9VSV8WT6xmPeR02md+hg4sQWd87Rdn622Luv6mO3DB88S6nce5jm4\nPiIiLKY1nQ8Uec6ymaTrdpuZWpKPgQLBB8VFzeqySLYyByfPrlbHnlf5eKRDUJzfdVXAoMpq\n4zhfzHb/oaktb6xBVWnq8qAYQICZLY+Vm6cKwhTCxvX0UbGVoRBYd47Hr++TKXImtiIMyoAi\nkiOMWCTA1gX2xg7KXRhQlMjApDIYhEJG2I0KH65WbDvHvo5jHIhhYFaPSLg3MCiHNU/K+8iJ\nLfk0n3HZdrgYDmGojLCcT/h8s+btiaUSaLs+u3tw1JXBD4qtBJMDotjiN57frR0CfLhtKUWw\nlcEYoR+GEW5VcTFmPoQDSz64PlOFs1kNjGU6sxUfbtvjOo+qmZAfrArjibu431KZsTIAPt4+\nZM6HQ37OrlbZuvMYyTmxhrfPYPkIWxSwRnaeCbcP22w+sQnhwJPAgWn2crnavnrSj7ClyMek\nFCJcteMHZ7MaszuV+3XXbffHSePufJ72be1fKoXIfycT1WXxYuP/NBH9lXJ3Pk9dDDCANQYR\n6FxgUle8/fn+aO2/zPGJLdPnxQmrrXtRyN8+LZLvlavVhrIYsdaZyDDAiS1Q1Rf6/lbHy0LS\nia1oaktlhKtVR9u5oyGzObG4PtJu3GEIEhHCoKjCattT93+h4/OJTWcziw8DtjJ8uV+zdfEo\nkvuZqes9hbEHpwuR9G5mWUxroirX7QYhpxBD1NHhcQPj43ykEFJUXgLiPpUhKn0YEIGgSudG\n/pjWFVvn8arcrx2rrctWWzc2WMbweTGj7Xy6OgJHIcQBWxWc2AoYp5w8H2eLGJWgyhABGRgD\nOw62qj9up168LIT0cTFlAOK+KdNxOptPLEGV+43D5uNtS1UU+KgsJpY+RoIKH66fqGJalykH\nPi3fcXWzIupAITmzumRiK1T1iFqey9SW6e3UIuTUVth2gc/3D8f8tpeoZAKc7JsQfRopVZUY\nBuZvSjY+oAq+j1SFcLnaIiKYAu4+LVNZjNgdd7yoGoiMTA8j3blecVFpapvmE5sWE5v2v+cT\nm0yRs+l6alsQox6cftVxANl1XTw7zY8+4MKA5BAH6H3k28axcYHC5Pg4cN12PLpAZeDq4xl3\nX86Tj0pQuG87Fic1tjTjEKdgCqjLAhiQ3WaKMZGHB8bgBB3P1Q8d34sflC4oLig5UOQ5VWHY\nuJ5pbZnVFbY0RD8cRv2t65l9vM40eCo8N+eLHVoothBUFUXZuB7nA31UysIc+gERwZjxkd3/\nPgzUZcHza7dXHd+3OnU1Lp7XJeeLE3SAm3WH6weiBoTxbqK2hkrM2BnqOHecXa6yR9fjY+Rs\n9gYfFB+VtfP4fmDrw+GurXlTYQzYaozx3mGT7xr5GMeLpOKph37V8XbjUFVyGSPUdj2fb9fc\nPDwiuWCLEbqMEQyC98pkRxS1LZjWI4L8z3WbqSoi0JyU2FLoo2YPrs9cH7POBQZVqkKoqwoQ\n8nxEsxAUEcEWBVNb4eMxln8XcsZboIGb1lGXOapjJPJ8bEpNDmF3pRZ04G1t8RoRZIfNT+xY\nl0VaNif7zvmFTYH05XRKsTtbOoDXgDWGfFfoZ1fH332fgIbxVqQuI8aMJaDD065FhNv2CbM/\nzk+S7yK6y9hz6fqYfb5v08VZ84JIYLxd+Xj78F1XXpPvOm7M07n2Po6Tzq6pbjcdLurB+LKp\nR/QI8KaSo3cH55Tsw3W7a3FfUvgflR9SflRl9qbAeQUZCenqN2PDaVOnRxd+9wQQ9eWm/oy8\nquTidJokH280HzrHt42jfyWK/075P4AQnUfVTZNLAAAAAElFTkSuQmCC\nENDofIMG\n\ndemo.show_image('png', 'transparent grayscale', <<'ENDofIMG')\niVBORw0KGgoAAAANSUhEUgAAAC4AAAAjCAQAAAE2KcD0AAAFPElEQVR4nMXWXYicZxUH8N+z\nM3HezCy76axJzJrtR8jWVVc29IMtTTG6hUqqqL1QWlrxQmirXpTihRdSY4pUSws1IIEWBesH\nCAZFapNaSISgpUurJra2i7u2IWs+dpNMnbWzndfM9Hixs5tNmrYJCv7vHvi///ec85z/OQ/L\nkODeeMZ1fq+LsTjolIqixAejx3jqj5EFknfEWFBke5zwkga62O01+9LAO38INsW9QeKmmHG1\nvzrgapkttiWqkWA0hsziSr/1CX+T25fAp+Km4PZg8F2CfCseipGga+HwxYBvxur4hWQoigtp\nT7grHk3rbXHAVKJIzQRq9sZ+a/XpixHFBZGqaQ/LNVTlBnVRVcKAPWnEeBrWMrXw7+uD7WfF\n3EVTFdvSxaaiFJfFaGAxlLfinmj7fuIzcUhFpmUZfXvUND2a+Gr0uT+x1+cxFhsc1zDvQOrE\nCC97wWH3xHDM+JMHg5YV+uNSKz2PHrfEQ2eK24OaLgVTDnnKtpj0Rx8wo+IG3VpmLFNnSNW4\nfutUZb7tW9b6Xcq1rFe2QdU/ztAHvIgMe9KIXDvdl4rYl7aln6VBfcbtSEupnkTRpKk0Grkt\n9mHHUsV3nl378kV31f8SH1/qkbe91UVU4hanbI0ylhXybIzE12JrwN0OI/caOqPgDL4SK+xI\nrI5rPK2d7opZdU3zSsYXC7kxNhs2blf6g82gV6adxmKlo5oyp0yf6Zmtpu1xrc/Gi9a6O2DG\nWJyy0SsOpvE0nRiJjvq/UHJUZovDun0ynkyVOKak5kQaiH7c7IFF9V7UHVFB07NuQ26TKzSN\nRH+nJkOL9HIn3kk1/cpe8NPodaWG0zIFmYIp/Yv0WS25y5WUFc172EsqqKsbVlWQyVUW6UcN\nutWvzVow9Kf9wHW6HUz7XWrOOmUFaxbp+xXs1KNfrzm5ptl00puYSLkbJZkhO1OH3khFa1CQ\n+7mqGh5LR8AD6QUVg+5Ly3qmbbW2ZF8ajaLnwXTnpnctu/lOz5RlKp5I3KiinWDP2w+k7XH7\nhVuk8v9008DSz9/VTBeG7XHMaWuVvOJDvv7fiA/GHZ5dKvODMeuX+jQdlduoucS7yMVQjUGb\n9Nndmd6jca2C57R0oyWXG/BEuoDIR2PMKe/3E1MdehWHrXIgUYmP+piGJxV1a8hRUnJUOebP\nNONg3OGfakoaXjVo2KQ5+42ncVvjEl9wIH6VFhKt6zeIsSipqWtoKMmFCfk5dVg6luM2bXWc\n1nad1z3jEkV9aq5X84bvJRiOgi/7sYaKYYOaHcssYCg2K7rchMfTslk6nwqu6EjTVHeVQ3Iz\nqnbJ9PhuVIM65v1bjrbjTtoUo3F9bIrRGI1eL9tgzuPL9ymsxGkwbVbJvBnjpqxSs9srqr7h\nkaiZt9cN+mVaeqwXCtrKCgoKOG7ewlPgnC0w57gTCrq916SPGNbvpBYm3ZnqVtim5E2rNbVM\nOuI1fTIVmV69Mpma9RYedcvEj2DAgKvcqmmvY15X1LJBr4qW1XF/+rtTblRTM2HWIbMY0WMd\nMpmyklnz+s4Vf05TpumgH9ons1q3XiUzNmq6wjAeSU3vcY33qaWJdDS96g1Vl0lKGuoyawyp\nndstcE+0PG29XKYkVzavoeFqdUWNjicH4maFZW+DQnxJBbm6NTJ853wmOm2dAb1aHQtnfpPg\nc/Fn7c4oZjr9KO5eMgrt9Jjz4yzxVbowo6ok87wTCbZGzZyBzgnytOOCBu859m/4sGOK6ktL\n4qZ49byboHEBU2kZ5c5YKfMX42oX/849L/4D4jD0vGNZ6YMAAAAASUVORK5CYII=\nENDofIMG\n\ndemo.show_image('jpeg', 'color', <<'ENDofIMG')\n/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof\nHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwh\nMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAAR\nCAAmADkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA\nAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK\nFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG\nh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl\n5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA\nAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk\nNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE\nhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk\n5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDzLyJSuV5FIsUm4DAzW1Ywpb3sbPhoQ4LA\njPGea6jWdH0W6EdxYLJA78gICUb169KIq8JTutDWnSnUmqcFds4y2e5jkzGrOVGTt7Ct2aae\nZFzGSR6cmni1t4RiFWCseRknJHf+f51MsZG4JHwP4hXmVaqctEfVYDLqsKbTla+43S7NZLkr\ndHamMEgg9R6isDVtDu7KdjFGZoOodOcD3rowWIVRkbDuUHI3DFbWnOs1n9pIIMZwwIzyBxwe\nv/16ujWs9iK+VQqfFN3W3Yo6Pp/n6LbXFx9rWeCNifLbjac9T6YxXN+a/wDzy/SvedC13S5/\nDtnZ3ckZmMQSVVTK8cYJ6HI96tfZvC3/AD42/wD35NdfM5dT5Pdtp3PBtEji1CVTtyR1U9vc\n11WpXOnRW9rYwWxB6O+/n2OOgrm40EZyg2n2rTm8M6xp+lrrk1q76bIu4hcMwB74zkD3/TFV\nKcXRcFHXudWGm6deM+axUmCQytGjrIi8Kyg81NFKrxqogVsMWk5OH78j8/YfnQ1hKlrbXU8F\nxCk43ws67d4/L3H5j1rLurqVLhhno2RXlKErn2f1qEIKV7xL77QN21VxwMdqdLdvBpbpDveS\n5cJGiHBzyMj8/wBB61i3OoySJjhR3C0+71FYYfIjncSgbSUOMj0J/mBW1OlJSuzz8fmsY0nG\nkvQ6qO4ubaLyt8fnR/Idh3AEdfyNQeVrH/QQuf8Avv8A+tWd4fu0j0dePnEjIM+vU/zqz/aq\nf8/J/wC/h/xotNSaifEO6bsVo1yy8DmvetkF3HbaW0INuYFMiYwpXA4wKKK7Y7HWtzSvNPs7\nywezurdJLYrjyyOgx29D6EcivGviF4EtfDlnFqVpeSvFLMsPkSKCVJVjncO3y9MfjRRRUirX\nNKdWcfdi9DhbW3YRS3a7cW+GOepycDA+vWsaS3AcqScjvRRUU9zOcnLVlqx8+Elll43qoH1r\nK2L70UVaerMluf/Z\nENDofIMG\n\ndemo.show_image('jpeg', 'grayscale', <<'ENDofIMG')\n/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof\nHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAmADkBAREA/8QAHwAA\nAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR\nBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF\nRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ip\nqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEB\nAAA/APMvIlK5XkUixSbgMDNX7Z7mOTMas5UZO3sK3Zpp5kXMZJHpyan0uzWS5K3R2pjBIIPU\neorA1bQ7uynYxRmaDqHTnA966/R9P8/Rba4uPtazwRsT5bcbTnqfTGK5vzX/AOeX6VFYwpb3\nsbPhoQ4LAjPGea6jWdH0W6EdxYLJA78gICUb169KzBa28IxCrBWPIyTkjv8Az/OpljI3BI+B\n/EKcCxCqMjYdyg5G4Yra051ms/tJBBjOGBGeQOOD1/8Ar16PoWu6XP4ds7O7kjMxiCSqqZXj\njBPQ5HvVr7N4W/58bf8A78mvBtEji1CVTtyR1U9vc11WpXOnRW9rYwWxB6O+/n2OOgrDmCQy\ntGjrIi8Kyg81NFKrxqogVsMWk5OH78j8/YfnUT7QN21VxwMdqdLdvBpbpDveS5cJGiHBzyMj\n8/0HrWnHcXNtF5W+Pzo/kOw7gCOv5GoPK1j/AKCFz/33/wDWrIjQRnKDafatObwzrGn6WuuT\nWrvpsi7iFwzAHvjOQPf9MVE1hKlrbXU8FxCk43ws67d4/L3H5j1rLurqVLhhno2RVa51GSRM\ncKO4Wn3eorDD5Ec7iUDaShxkehP8wK0vD92kejrx84kZBn16n+dWf7VT/n5P/fw/41WjXLLw\nOa962QXcdtpbQg25gUyJjClcDjArSvNPs7ywezurdJLYrjyyOgx29D6EcivGviF4EtfDlnFq\nVpeSvFLMsPkSKCVJVjncO3y9MfjXC2tuwilu124t8Mc9Tk4GB9etY0luA5Uk5HerVj58JLLL\nxvVQPrWVsX3r/9k=\nENDofIMG\n\ndemo.show_image('jpeg', 'progressive color', <<'ENDofIMG')\n/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof\nHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwh\nMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgAR\nCAAmADkDASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAAAAQDBQYBAv/EABkBAAIDAQAA\nAAAAAAAAAAAAAAECAAMFBP/aAAwDAQACEAMQAAABzA7aRqV/vvl1eIWLrCCt3stuTgrWtaNs\nPsV5dljqXX57XwtLMSLehdazjQjUSQBZVQK//8QAHhAAAgIDAQEBAQAAAAAAAAAAAQIAAwQR\nEiEQBRP/2gAIAQEAAQUC0ZoxegSSZUm2toZDTXuncQcvdTS05UTXyv1KL6jj84spAsNjVhT4\nQfIW1UGZRq6DyHGurq4PLMemsJjWaGO2qf6wTxg9aOn6GCuOir4VibHz/8QAHxEAAgEEAgMA\nAAAAAAAAAAAAAQIAAwQQERIxEyFB/9oACAEDAQE/AVUseIlC3YL3HtQ3ZxTPFwdzygDfyV7o\nBdLlWI9CE7x//8QAGxEAAwEBAAMAAAAAAAAAAAAAAAECESEQEjH/2gAIAQIBAT8BXxsqukWb\no2vTMMZMvTu8EUifH//EACgQAAEDAwIDCQAAAAAAAAAAAAIAAREQITESUQMiMhMjM0FScYGR\nof/aAAgBAQAGPwKllhcys0shItUs3ksJtkxBLKyxTVsgAnaYuugfqggwqMrHvS2SwotLLxCp\n27j3boSdiacVhnuvldX7QeFHLF1oIZHZNxBN4d4h05emmaf/xAAgEAEAAwACAgIDAAAAAAAA\nAAABABEhMUFRcWGBEJHx/9oACAEBAAE/IcshZFgLXiHkBRkjX2ZMMXcupaDQ7fZRlXxwzq2m\nHKvtNw8afMR+4nAyQDPwUhn1PcOblWCA4SAgq7fyjXNBFYupQJoHCzZ/Qg6ZDC0rzWJF3bSr\nhl7gHj1CvvTIIebEpAaSnHFp1UQioh8wNbjHv6jUa7TSpzzsEon/2gAMAwEAAgADAAAAEIb7\nMuvRaP43Yv/EABoRAQADAQEBAAAAAAAAAAAAAAEAETEhUXH/2gAIAQMBAT8QGjax8NL2bzZn\nk1Ubj8VKe1w5H5Gxahs6xyN0w2f/xAAaEQEBAQEBAQEAAAAAAAAAAAABABEhMUFR/9oACAEC\nAQE/EBu05G8Fg+WvqUj1+xtC02FE8QZt6h63/8QAJBABAAICAgIBBAMAAAAAAAAAAQARITFB\nUWGRcaGx0fCB4fH/2gAIAQEAAT8QvtkSkKLl8RFvQllJTrLEKYaUR2dkTm2mejzMlLHRa9vV\nVP3kopAoS8XmEZJwK929QBQEyWtpz9/cQpiOEFAWXobKVLxEVQS8hjDv+46IjecMUumzzP8A\ncRqyTa48sXGOt/w1ogxTIDmGiosjXPJ78HuVGgwVxK9tt03ks9/Q7nZ8b0E36Z+z/EFWbeJY\nAwKAPNXYefpUHWepPryezuBl6sSs4HJFYsll1Z0v3CYYxDfe37zz/b8yzAZldCmppUMURDFp\nY0Vx09JklKrxFSl046V/MBjlFe22ij53AGls5lpwah8z5p//2Q==\nENDofIMG\n\ndemo.show_image('jpeg', 'progressive grayscale', <<'ENDofIMG')\n/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof\nHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wgALCAAmADkBAREA/8QAGgAA\nAgMBAQAAAAAAAAAAAAAAAgQDBQYBAP/aAAgBAQAAAAHMenfNC3rRtFT67pJcFaomPWQTaBWP\nrMsW9ZxtElKr/8QAHhAAAgIDAQEBAQAAAAAAAAAAAQIAAwQREiEQBRP/2gAIAQEAAQUC0Zox\negSSZUm2toZDTXuncQcvdTS05UTXyv1KL6jj84spAsNjVhT4QfIW1UGZRq6DyHGurq4PLMem\nsJjWaGO2qf6wTxg9aOn6GCuOir4VibHz/8QAKBAAAQMDAgMJAAAAAAAAAAAAAgABERAhMRJR\nAyIyEyMzQVJxgZGh/9oACAEBAAY/AqWWFzKzSyEi1SzeSwm2TEEsrLFNWyACdpi66B+qCDCo\nyse9LZLCi0svEKnbuPduhJ2JpxWGe6+V1ftB4UcsXWghkdk3EE3h3iHTl6aZp//EACAQAQAD\nAAICAgMAAAAAAAAAAAEAESExQVFxYYEQkfH/2gAIAQEAAT8hyyFkWAteIeQFGSNfZkwxdy6l\noNDt9lGVfHDOraYcq+03Dxp8xH7icDJAM/BSGfU9w5uVYIDhICCrt/KNc0EVi6lAmgcLNn9C\nDpkMLSvNYkXdtKuGXuAePUK+9Mgh5sSkBpKccWnVRCKiHzA1uMe/qNRrtNKnPOwSif/aAAgB\nAQAAABCrPPK25v/EACQQAQACAgICAQQDAAAAAAAAAAEAESExQVFhkXGhsdHwgeHx/9oACAEB\nAAE/EL7ZEpCi5fERb0JZSU6yxCmGlEdnZE5tpno8zJSx0Wvb1VT95KKQKEvF5hGScCvdvUAU\nBMlrac/f3EKYjhBQFl6GylS8RFUEvIYw7/uOiI3nDFLps8z/AHEask2uPLFxjrf8NaIMUyA5\nhoqLI1zye/B7lRoMFcSvbbdN5LPf0O52fG9BN+mfs/xBVm3iWAMCgDzV2Hn6VB1nqT68ns7g\nZerErOByRWLJZdWdL9wmGMQ33t+88/2/MswGZXQpqaVDFEQxaWNFcdPSZJSq8RUpdOOlfzAY\n5RXttoo+dwBpbOZacGofM+af/9k=\nENDofIMG\n\ndemo.show_image('tiff', 'uncompressed', <<'ENDofIMG')\nTU0AKgAAHggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAADb///bttu2tv+Sttu2ttvb2/8AJEkAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////b//+229u2\n29vb2/+2ttttttu2ttu22//b//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAJAC229skbZLb//+2tv8AJEkkbZJtkrbb///b//9tktvb//8A\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSttu2\n29u2ttvb2/8AAAC229skbZIAACSSttu229uSttsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQAAAAAAAAAAAAAJCQAJCSSttsAAACS\nttvb//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAASUkAAABJbZIAACQkAACStrYASQDb2/8AAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////29v//9v/29v///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAABtJACSbSS2bUnbkm22km3btm22kkn/25L//9ttJAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSSSSSSSTbkm2SSSSSSSSSJACSSSS2\nbUm2bUm2bUn/27b//9v/////////////27b/tm3btm3//9v/27b//////////////9skAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAkAABJAAAAAACSSSRJAABtJABtJACSbSSSSSTbtm22km3btm3btm3btm22km3/\nkm22bUn/25L/27b/25Lbtm3btpLbkm3/27bbtpLbtm22km3/25L/27b//7b/27b//////9v/\n/////9v/////tpL/km1tJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtAABJAABJAABJAACSJCRJ\nAABtJABtAACSSSRtJACSbSSSSSTbkm222222km22bUm2kknbtpLb25K2km22kknbtpLbtm3b\ntpLbtm22km3btpK2km3btpLb25L//9v/25L/25Lb29v//7b/27b//7b/27b/25Lb29v/27bb\ntpL//9v//////7b///////////////+2bUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAABJAABJAABJAABJAABJJACSSSSSJABtSQCSSSSSSSSSSSSSJCSSSSS2\nbUmSSSSSJABtJABtAACSSSS2kkm2bUnbkkm2kkn/25K2kknbtm22km3bkm22km3/tm3btm3b\ntm3btpLbkm22km22kkm2kknbtm3bkpL/25L/27b//7b/27b//7b/////tm3btpL/27b/tm3b\ntpLbtm3//7b/25L//9v/////////////////////2/8AAAAAAAAAAAAAAACSSSQkAABtJABJ\nAABtJABJAABJAABJAACSSSRtSQBtJABtSSS2kkmSJCSSJCSSSSSSSSSSSSSSSSSSSSSSSSRt\nJACSSSSSSSS2bUm2km3//9u2bUm2bUm2bUm2SSS2bUm2bUm2km2SSSSSSSTbtm3btpL/25K2\nkm3btkm2km3btm22km3bkm3btpL/25K2tm3bkm22km3btm22bUm2bUm2bUm2kkm2bUnbtm22\ntm3bkm3b25L//9v///////////8ADgEAAAMAAAABAEAAAAEBAAMAAAABACgAAAECAAMAAAAD\nAAAetgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEV\nAAMAAAABAAMAAAEWAAMAAAABACgAAAEXAAQAAAABAAAeAAEaAAUAAAABAAAevAEbAAUAAAAB\nAAAexAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAAAAAAACAAIAAgSwAAAAAQAABLAAAAABAAA\nENDofIMG\n\ndemo.show_image('tiff', 'packbits compressed', <<'ENDofIMG')\nTU0AKgAABAqBAMEAgQDBAIEAwQCBAMEAgQDBAIEAwQCBAMEAgQDBAIEAwQCBAMEAgQDBAIEA\nwQCBAMEAgQDBAIEAwQCbAAvb///bttu2tv+Sttv/tv7bA/8AJEm8AKEA/v8G2///ttvbtv3b\nDf+2ttttttu2ttu22//b//+/AKMACCQAttvbJG2S2////7YR/wAkSSRtkm2Sttv//9v//22S\n/9v//8IAoQADkrbbtv/b/7b+2wD//gARttvbJG2SAAAkkrbbttvbkrbbwgCcAAAk9wD/JAUA\nJCSSttv+AAGStv/b///CAJcA/0n+AAJJbZL/AP8k/wAIkra2AEkA29v/wgCBAMEAgQDBAIEA\nwQCBAMEAgQDBAIEAwQCBAMEAgQDBAIEAwQCBAMEAgQDBAIEAwQD9///b//8B2///2/7/gQDQ\nAB5tJACSbSS2bUnbkm22km3btm22kkn/25L//9ttJAAkgQDgACOSSSSSSSTbkm2SSSSSSSSS\nJACSSSS2bUm2bUm2bUn/27b//9v3/w3btv+2bdu2bf//2//btvb/AdskigADJAAASfwAU5JJ\nJEkAAG0kAG0kAJJtJJJJJNu2bbaSbdu2bdu2bdu2bbaSbf+SbbZtSf/bkv/btv/bktu2bdu2\nktuSbf/bttu2ktu2bbaSbf/bkv/btv//tv/btvz/ANv8/wDb/f8GtpL/km1tJLUAYm0AAEkA\nAEkAAEkAAJIkJEkAAG0kAG0AAJJJJG0kAJJtJJJJJNuSbbbbbbaSbbZtSbaSSdu2ktvbkraS\nbbaSSdu2ktu2bdu2ktu2bbaSbdu2kraSbdu2ktvbkv//2//bkv/bkv7b//8Mtv/btv//tv/b\ntv/bkv7bCP/bttu2kv//2/z/ALb1/wK2bUnXAH9JAABJAABJAABJAABJJACSSSSSJABtSQCS\nSSSSSSSSSSSSJCSSSSS2bUmSSSSSJABtJABtAACSSSS2kkm2bUnbkkm2kkn/25K2kknbtm22\nkm3bkm22km3/tm3btm3btm3btpLbkm22km22kkm2kknbtm3bkpL/25L/27b//7b/2wO2//+2\n/f8Ztm3btpL/27b/tm3btpLbtm3//7b/25L//9vx/wHb//UAAZJJ/yT/AH9tJABJAABtJABJ\nAABJAABJAACSSSRtSQBtJABtSSS2kkmSJCSSJCSSSSSSSSSSSSSSSSSSSSSSSSRtJACSSSSS\nSSS2bUm2km3//9u2bUm2bUm2bUm2SSS2bUm2bUm2km2SSSSSSSTbtm3btpL/25K2km3btkm2\nkm3btm22km3bkjBt27aS/9uStrZt25JttpJt27Zttm1Jtm1Jtm1JtpJJtm1J27ZttrZt25Jt\n29uS///b+P8ADgEAAAMAAAABAEAAAAEBAAMAAAABACgAAAECAAMAAAADAAAEuAEDAAMAAAAB\ngAUAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEVAAMAAAABAAMAAAEW\nAAMAAAABACgAAAEXAAQAAAABAAAEAgEaAAUAAAABAAAEvgEbAAUAAAABAAAExgEcAAMAAAAB\nAAEAAAEoAAMAAAABAAIAAAAAAAAACAAIAAgSwAAAAAQAABLAAAAABAAA\nENDofIMG\n\nif false\ndemo.show_image('tiff', 'pixarlog compressed', <<'ENDofIMG')\nTU0AKgAAA3Z4nO2aIWzbUBCGz7HjYyVTNDAp0CgKDRorCauiSGFjRmWRxs0rlQ2FlUWKrLKQ\nsIDK1BoyjFRUjZSF7f13eYnjpZOmdeuU3Wc1se+dn17uf/ee5SuRYRiGYRiGYRiGYRiGYRiG\nYRg/YxVt3EG04IpLJkqocJ8VD6S1746ELsOP8UNMxO1J9MbDPQs2EvOKcV66uOsZoo34lwxb\nJraMfEsif+S06Lrj74/5XNi2iG6jdbCKruMRz3gdfKUbF/OFi/c0vHbzfNvqBDl1giENKHdt\n492dI/7sdIElMRV+i0l0G62igcx3ZMBhnUFc0ebV4fZzeBfDfx2ofyGr1DycOt+3/RXnALIB\n63rTqnYo9SVYBxptVS11+WDz//WZh/MQ8Z5E8/AiwjdmPnTg9qfg1sV+Hn7gabiK3gWbSDPl\nrcdsGIZhGIZhGIZhGIZhnCebXc1IKxeJ2LSGkbija+8G/zAXEd4LDqkTbFuo091T312l8iYd\n79JhK7ngGY+dNSfoklKP38eX4VOMt73NN77Gr4B3tP4NOeLbCWY84qfYt18x4ntPUCd133XG\nzv+RSOp5RD57DlRSiSo5Y59RY1HQV2fH1KRyunbDy/D/0VRjr3HVirQqMuJJxO2UvDY+R4hm\nDKUe3RXywudIHbVrdBe8lNzJJfK08y2kQr5k7RfXS0ZeZaJNIfYl+35S8dF7j1fI8dHV8fmC\nP7P23OO7+Dl8/idVvZCYz7hpz6VyNHKz/6ACxj8kqLNk5MWxIrkoktKhP0Re49uX+qtWxUtn\n1cjP2Nvhi8/h7vyg7FDUXLKe+7o6tEKs/bgrGUEiFfdTeqji6qN1evSaiLYH34X4/piVaOnx\nQzx1Gr72f03MX9xdEdlcVh5dhZaMLBkS1XJCuZJxo1XXKOwWsOld6nPQbiC9asT70l+5+93Q\ncMFY//rSk1eBaj7IgaoxW3wGlXu710X7QetwpxnRqTxSEHlEupJZk+x3v2xnIRk1VMvk3oJp\n32tz7a2Du7svVNl0tUFdmtt+NiNWOuf1vE6+m/8aUR/5bSuTqBYu06/2UTjeLU7h8+h+r6nf\nZfAMMKYbUaTH3+Lj+1Tf+n4E/6K2c+kKqS26Py0k7xDTmcz+tPZ04VUmyTLvX4p/wdR4Gsm4\nuV54beCT1Z5edCVNpc/TSn0HoOsh4gAOAQAAAwAAAAEAQAAAAQEAAwAAAAEAKAAAAQIAAwAA\nAAMAAAQkAQMAAwAAAAGAjQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAA\nARUAAwAAAAEAAwAAARYAAwAAAAEAKAAAARcABAAAAAEAAANuARoABQAAAAEAAAQqARsABQAA\nAAEAAAQyARwAAwAAAAEAAQAAASgAAwAAAAEAAgAAAAAAAAAIAAgACBLAAAAABAAAEsAAAAAE\nAAA=\nENDofIMG\nend\n\nif false\ndemo.show_image('tiff', 'logluv compressed', <<'ENDofIMG')\nTU0AKgAAAAgADgEAAAMAAAABAEAAAAEBAAMAAAABACgAAAECAAMAAAADAAAAtgEDAAMAAAAB\nh3QAAAEGAAMAAAABAAIAAAERAAQAAAABAAAAAAESAAMAAAABAAEAAAEVAAMAAAABAAMAAAEW\nAAMAAAABACgAAAEXAAQAAAABAAAAAAEaAAUAAAABAAAAvAEbAAUAAAABAAAAxAEcAAMAAAAB\nAAEAAAEoAAMAAAABAAIAAAAAAAAAEAAQABASwAAAAAQAABLAAAAABAAA\nENDofIMG\nend\n\ndemo.show_image('tiff', 'jpeg compressed', <<'ENDofIMG')\nTU0AKgAABID/2P/AABEIACgAQAMAEQABEQACEQD/2gAMAwAAAQACAAA/APn+vn+vn+iiiiii\niiiiiiiiiiiiiiiiiiiiiiiiiiitK28O63e28VxaaNqE8ExIilitXZXIODtIGDyCOPStO18O\na5e28VxaaNqNxBLny5IrV3V8Eg4IGDyCPqDWtZ+FvEOo2kd3Y6Dql1bS/wCrmgs5HR+SOCBg\n8gj6g1m1mkEEgggjqDWUysjFWUqwOCCMEGikpKKKKKKKKKKKKKKUHBB449RRXdXHxU16+nt5\nLl1j8li5MDOTIxdWJYOzKSMMF3KwG4jHTHo83xl8QXs8U92Y1aJWASAMAxZkO472ZSQA4G5W\nA3YwRjb6mfjj4guZ4pblYYhEr/u7VWHmMzIcszuwyAHC5Vgu7G054x/GPiGDxNqtvqEcLRz/\nAGcR3LFAvmSB3wwwTxsKcEnbjaCQorA8e+J7bxbrdvqcEDRzfZViunaNU82QM3zgAnjaUGCT\njG0HAFcx8QfFlt4z1221aK18i4+yrFdt5ap50iu+HwCTymzgkkY25IUE87XLVydFFFFFFFFF\nFFFFFFFFFFFFFFFFFFe2vceH9WtktdR8KaRGsEu53hjW2Z8ZH3o1jP8AeG32B6/d7l/E9hqU\nENvqHhjSkWKUNKUt47Z2IJHDRiM+oK5xx7Db0t34mjvrWK3u9F0vEcoeUxWkdvI2MjAaJUOO\neV6d/TFlfhp4BvnlmZtYtCHG6G3uUKJk9F3Izce7ZP542IfDXgG5trm4uv7YtJlOfJhnURAs\nTiNMxuxwM43NkgZ61p2lh4Lube5muodVhmDMdlvdII0JJwqgxuxA46tkj8cT23wi+HtwIsat\nraF/veZcQx4PoN0QJ+vA4zV+x8C/Dm6it92rauJJOH33McIVs8gb4cnjvwDjOfS5p+geAZoo\nBcXuqmWRQGYXEcKo2eRhoiTgc54HB554zofgFayMfM8XeSp+ZC2nggr0/wCeo7+38jitB8H9\nOLAXfi9bVXXfG72PyuucZB8z1BH4fXEUHw70/wDdte+IzaxyLvjZrLO5ckZA3jnIx6Z79cNm\n+AEUkFwNO8YQXF3EuRFLYtGh/wB5w7bRjnODS3HwYtJYpF0fxfbXlzHgvHNZvEqg9CWVnwMc\n5x0/HEt18NNPc+VpPimG7uVAaRJ7NokQHHJZWf37c44zms4fs++JyCf7Y8P/AC5zi5lOB68R\n9ODVdfgZr7KP+J54fDEkbBcysw9yBGePft3qOH4S6lLGr/2/oCgnH/HxK2PQnbGeD69B3xkZ\nw7z4N+MrW8lgjs7O5RGwJor+FUf3AdlbGeOQOlYM/wAL/E0V08McdhOik7ZV1CGNZAP4gJGV\nsfUDofSsV/Aeti9kt4jYShSdsxvookcDuPNZTjnuAfbg1n6h8MPGumiMy+HbybzM4+x7brGM\nZ3eUW29e+M846GoL34aeMrHZu8P3dxuyM2O26C4x97yi23qOuM0tz8PPFlvs2aLNeb8/8g90\nvNuMfe8ktt68ZxnnHQ1//9kAAA8BAAADAAAAAQBAAAABAQADAAAAAQAoAAABAgADAAAAAwAA\nBToBAwADAAAAAQAHAAABBgADAAAAAQACAAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQAD\nAAAAAQADAAABFgADAAAAAQAoAAABFwAEAAAAAQAABHcBGgAFAAAAAQAABUABGwAFAAAAAQAA\nBUgBHAADAAAAAQABAAABKAADAAAAAQACAAABWwAHAAABIQAABVAAAAAAAAgACAAIEsAAAAAE\nAAASwAAAAAQAAP/Y/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQu\nJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQF\nBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0Kx\nwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlq\nc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT\n1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9k=\nENDofIMG\n\ndemo.show_image('tiff', 'deflate compressed', <<'ENDofIMG')\nTU0AKgAAAah4nO2Y643EMAiEXQzNUIyboRiaoRh2ADuP+7N70knZkxhZlmNH2fkMRPGO0Wq1\nWq1Wq9Vqtb5L5m5qqi7Rm5kP4qdNfSSHc3dYDtfmMD8TQS3mn3b3TjRgm6YEgsaeYzwRg4TC\n9PcjRMLYzpmxcABW8+ifNviJ6DIktLKN/vv3/xRHwXJuPoV5HTwqKK1Wq9VqtVqtz+VxwMjv\n8ej/39fUpCGTdLLJVJmm6NlNQIQlev+AhyVMaDBfA6GYAU41nFrzqLSFSw3GjJf6ZeEpUvwu\nbxDOcFREAkpXRKph7IjRzOjAvEnOC9jzcC7rnlp13YB29ip4wvxT1Jn+qwlthMQ5QWDbwlsE\nRTis4uQX+cZl+zCPQfWWGZgsEkfHhaML3KyQN901lIjwL/6a4GvL5EEK4QErneKSKqPW0qaD\n+awarnpJlkTIOnI9Aic1o1LsuEHuMdIyHTgrPyVTVKsM/YfuRzY4odxz3v2KBfaf021aDQqi\nE2q3SYs0QxN1cdSOHnW0i8uWyYoR79dFIK95nedr5HhObRRmctXuUC9uNR31AAAOAQAAAwAA\nAAEAQAAAAQEAAwAAAAEAKAAAAQIAAwAAAAMAAAJWAQMAAwAAAAGAsgAAAQYAAwAAAAEAAgAA\nAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEAAwAAARYAAwAAAAEAKAAAARcABAAA\nAAEAAAGfARoABQAAAAEAAAJcARsABQAAAAEAAAJkARwAAwAAAAEAAQAAASgAAwAAAAEAAgAA\nAAAAAAAIAAgACBLAAAAABAAAEsAAAAAEAAA=\nENDofIMG\n\nif Tk::PLATFORM['platform'] != 'windows'\ndemo.show_image('other', 'postscript', <<'ENDofIMG')\n%!PS-Adobe-3\n%%Title: postscript.ps\n%%BoundingBox: 66 648 146 720\n%%Pages: 1\n%%DocumentProcSets: Adobe_distill 0.96\n%%EndComments\n%%BeginProcSet: Adobe_distill 0.96\n/PROLOGUE 30 40 add dict def\n % 30 procedure entries + room for 40 cached font dictionaries\n PROLOGUE begin\n /clip { } def    % causes problems. remove if \"clip\" is needed\n /bdef { bind def } bind def\t/ldef { load def } bdef\n /T { moveto show } bdef\t/A { moveto ashow } bdef\n /W { moveto widthshow } bdef\t/AW { moveto awidthshow } bdef\n /f /fill ldef\t\t\t/R { { rlineto } repeat } bdef\n /r /rlineto ldef\t\t/L { { lineto } repeat } bdef\n /m /moveto ldef\t\t/l { moveto lineto stroke } bdef\n /x { 0 rlineto } bdef\t\t/y { 0 exch rlineto } bdef\n /c /curveto ldef\t\t/cp /closepath ldef\n /s /stroke ldef\t\t/w /setlinewidth ldef\n /g /setgray ldef\t\t/j /setlinejoin ldef\n /d /setdash ldef\t\t/F /setfont ldef\n /C /setcmykcolor where { /setcmykcolor get }{ %ifelse\n   { %def\n     1 sub 3 { 3 index add neg dup 0 lt { pop 0 } if 3 1 roll } repeat\n     setrgbcolor\n   } bind\n } ifelse def\n /selectfont where { pop }{ %ifelse\n     /selectfont { exch findfont exch scalefont setfont } bdef\n } ifelse\n /MF { exch findfont exch makefont setfont } bdef\n /FF /selectfont ldef\n /DF { selectfont currentfont def } bdef\n /BEGINPAGE { pop /pagesave save def } bdef\n /ENDPAGE { pop pagesave restore showpage } def\n /REMAP { %def\n   FontDirectory 2 index known { pop pop pop } { %ifelse\n     findfont dup length dict begin\n       { 1 index /FID ne {def}{pop pop} ifelse } forall\n       exch dup length 0 gt { /Encoding exch def }{ pop } ifelse\n     currentdict end definefont pop\n   } ifelse\n } bdef\n /RECODE { %def\n    3 -1 roll 1 index findfont /Encoding get 256 array copy exch\n    0 exch { %forall\n     dup type/nametype eq\n       { 3 {2 index} repeat put pop 1 add }{ exch pop }ifelse\n    } forall pop 3 1 roll REMAP\n } bdef\n end %PROLOGUE\n%%EndProcSet: Adobe_distill 0.96\n%%EndProlog\n%%BeginSetup\nPROLOGUE begin\n%%EndSetup\n%%Page: 1 1\n1 BEGINPAGE\n1 g\n2 setlinecap\n144 53 m\n390 x\n-19 y\n-390 x\neofill\n0 g\n1.268 w\n0 setlinecap\n4 setmiterlimit\n[] 0 d\n109.698 714.182 m\n111.525 713.672 112.472 713.234 113.624 712.431 c\n-22.3128 -25.8381 r\n97.4019 682.652 103.794 672.84 100.329 664.844 c\n102.034 675.687 90.7436 683.82 84.1099 684.842 c\n25.588 29.3407 r\nf\n1.0361 w\nf\nf\n91.8805 654.468 m\n96.0255 654.285 100.155 654.188 104.481 654.188 c\n113.804 654.188 122.752 654.636 131.141 655.44 c\n134.222 655.737 136.724 658.133 137.108 661.279 c\n137.79 666.855 138.107 672.696 138.107 678.705 c\n138.107 684.714 137.79 690.555 137.108 696.131 c\n136.724 699.277 134.222 701.674 131.141 701.97 c\n127.476 702.321 123.704 702.604 119.84 702.813 c\n119.84 702.813 103.842 668.373 102.231 664.827 c\n99.8549 659.595 96.601 655.765 91.8805 654.468 c\nf\n0.7851 w\n77.8202 655.44 m\n74.7171 655.948 72.2887 657.716 71.8525 661.279 c\n71.1725 666.855 70.8549 672.696 70.8549 678.705 c\n70.8549 684.714 71.1725 690.555 71.8525 696.131 c\n72.2381 699.277 74.7417 701.674 77.8202 701.97 c\n82.1335 702.383 86.5932 702.702 91.1764 702.916 c\n8.16241 9.07727 r\n99.2863 711.98 101.266 712.345 102.996 711.921 c\n-28.4564 -32.9334 r\n80.6983 681.906 98.7446 677.354 98.7446 666.708 c\n98.7446 655.332 86.3243 654.054 77.8202 655.44 c\nf\n0.0843 w\n139.67 644.154 m\n140.194 644.154 140.619 644.576 140.619 645.098 c\n140.619 645.619 140.194 646.042 139.67 646.042 c\n139.146 646.042 138.721 645.619 138.721 645.098 c\n138.721 644.576 139.146 644.154 139.67 644.154 c\n1 ENDPAGE\n%%Trailer\nend %PROLOGUE\n%%Pages: 1\n%%EOF\nENDofIMG\nend\n\nif false\ndemo.show_image('other', 'pdf', <<'ENDofIMG')\nJVBERi0xLjIKJcfsj6IKNCAwIG9iago8PC9MZW5ndGggNSAwIFIvRmlsdGVyIC9GbGF0ZURl\nY29kZT4+CnN0cmVhbQp4nF1TSY7cQAy7+xX1AkFbaXlG3jBAgAAzh/z/Esp2uyeDPhhUayEp\nFZMsnt/9/fg6/h6y/hzCHdS1UlyodH0dIrJJNyIWlLpE1OcLrGQOjLg6MOIm6+NoMULWiopN\nbevz6HRiaUQ0aKMHW1L7itQitGA2UvwdDuhoIaw8zSN3UOVqTnILNLAiXQVy3NNvCvQs+M57\nZv4Gj6LivWK7UxS0dDCknBGl2jNY6MKoKmBkljwYfQUD2d8ZqjkKgINASEyEfCq208nc0Fon\nYSdZIiFy7IldQmbACe4FraKUfVYkzEAgarhgIBJyvIGi+IYrCWqm4I6UJ4mvV4PmfTW4J3TI\ntZCHQzdmDqeLY7Jgpf6IAG7KKVAsLAMBxWIEqrEvuAAc8xXp2Rtgkdhp038B7PfcCyQZ5WDV\noXIuWGdCI387SO/GjezVgcZyuRaAP1b3gXVmopb1ZfXXkSM/z6Imx+4xpHAsseGHgD2abFzu\n2+qEzjwjl9fJN4vb6zd+ef1Ebq+fDrfZz4zH7GFhc0O32cPSJR+zXzIes0vnMPZlNk73ejWT\ngFNDYs/IOM3tkTXmGUbMsaPF9cAwq8KuyNwxFMc4gJY+d47S0Td/68nSNxkiUNpz159H8Twg\ng1LkcKyGBe6TkQYL3jhwTDwreSJ7gw9eZeBY3GZpPBU/FjY7/HX8A9+h3WJlbmRzdHJlYW0K\nZW5kb2JqCjUgMCBvYmoKNTE2CmVuZG9iagozIDAgb2JqCjw8Ci9UeXBlIC9QYWdlCi9NZWRp\nYUJveCBbMCAwIDYxMiA3OTJdCi9QYXJlbnQgMiAwIFIKL1Jlc291cmNlcyA8PCAvUHJvY1Nl\ndCBbL1BERl0KPj4KL0NvbnRlbnRzIDQgMCBSCj4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBl\nIC9QYWdlcyAvS2lkcyBbCjMgMCBSCl0gL0NvdW50IDEKPj4KZW5kb2JqCjEgMCBvYmoKPDwg\nL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSCj4+CmVuZG9iago2IDAgb2JqCjw8IC9DcmVh\ndGlvbkRhdGUgKEQ6MTk5NzEyMDUyMjU2MzcpCi9Qcm9kdWNlciAoQWxhZGRpbiBHaG9zdHNj\ncmlwdCA1LjEwKQo+PgplbmRvYmoKeHJlZgowIDcKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAw\nMDAwNzk5IDAwMDAwIG4gCjAwMDAwMDA3NDAgMDAwMDAgbiAKMDAwMDAwMDYyMCAwMDAwMCBu\nIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDA2MDEgMDAwMDAgbiAKMDAwMDAwMDg0OCAw\nMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDcgL1Jvb3QgMSAwIFIgL0luZm8gNiAwIFIKPj4K\nc3RhcnR4cmVmCjkzOQolJUVPRgo=\nENDofIMG\nend\n\n#######################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkimg/license_terms_of_Img_extension",
    "content": "This software is copyrighted by Jan Nijtmans (the maintainer)\nand a lot of other people who contributed code (most notably\nAndreas Kupries, Thomas G. Lane, Ioi K. Lam, Mario Weilguni\nand Roger E Critchlow Jr).\nThe following terms apply to all files associated with the\nsoftware unless explicitly disclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute,\nand license this software and its documentation for any purpose, provided\nthat existing copyright notices are retained in all copies and that this\nnotice is included verbatim in any distributions. No written agreement,\nlicense, or royalty fee is required for any of the authorized uses.\nModifications to this software may be copyrighted by their authors\nand need not follow the licensing terms described here, provided that\nthe new terms are clearly indicated on the first page of each file where\nthey apply.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES\nARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY\nDERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE\nIS PROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE\nNO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nGOVERNMENT USE: If you are acquiring this software on behalf of the\nU.S. government, the Government shall have only \"Restricted Rights\"\nin the software and related documentation as defined in the Federal \nAcquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you\nare acquiring the software on behalf of the Department of Defense, the\nsoftware shall be classified as \"Commercial Computer Software\" and the\nGovernment shall have only \"Restricted Rights\" as defined in Clause\n252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the\nauthors grant the U.S. Government and others acting in its behalf\npermission to use and distribute the software in accordance with the\nterms specified in this license. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tkimg/readme.txt",
    "content": "The script 'demo.rb' is based on 'demo.tcl' of Tcl/Tk's 'Img' extention. \nImage data in 'demo.rb' is those of 'demo.tcl'.\nPlease read 'license_terms_of_Img_extension' file.\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/Orig_LICENSE.txt",
    "content": "\n  #######################################################################\n  ###  The following text is the original 'license.txt' of tktable    ###\n  ###  extension.                                                     ###\n  ###  Original Tcl source files are not include in this directry,    ###\n  ###  because of all of them are rewrited to Ruby files.             ###\n  ###  However, the image data file is quoted from iwidgets source    ###\n  ###  archive.                                                       ###\n  #######################################################################\n\n\n\t\t   * COPYRIGHT AND LICENSE TERMS *\n\n(This file blatantly stolen from Tcl/Tk license and adapted - thus assume\nit falls under similar license terms).\n\nThis software is copyrighted by Jeffrey Hobbs <jeff.hobbs@acm.org>.  The\nfollowing terms apply to all files associated with the software unless\nexplicitly disclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute, and\nlicense this software and its documentation for any purpose, provided that\nexisting copyright notices are retained in all copies and that this notice\nis included verbatim in any distributions.  No written agreement, license,\nor royalty fee is required for any of the authorized uses.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR\nDIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\nOF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,\nEVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS\nPROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO\nOBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nRESTRICTED RIGHTS: Use, duplication or disclosure by the U.S. government\nis subject to the restrictions as set forth in subparagraph (c) (1) (ii)\nof the Rights in Technical Data and Computer Software Clause as DFARS\n252.227-7013 and FAR 52.227-19.\n\nSPECIAL NOTES:\n\nThis software also falls under the bourbon_ware clause:\n\n    Should you find this software useful in your daily work, you should\n    feel obliged to take the author out for a drink if the opportunity\n    presents itself.  The user may feel exempt from this clause if they\n    are under 21 or think the author has already partaken of too many\n    drinks.\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/basic.rb",
    "content": "#!/usr/bin/env ruby\n##\n## basic.rb\n##\n## This demo shows the basic use of the table widget\n## \n## ( based on 'basic.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\nary  = TkVariable.new_hash\nrows = 8\ncols = 8\n\n# fill table variable\n((-(rows))..rows).each{|x|\n  ((-(cols))..cols).each{|y|\n    ary[x,y] = \"r#{x},c#{y}\"\n  }\n}\n\nlbl = TkLabel.new(:text=>\"TkTable v1 Example\")\n\ntable = Tk::TkTable.new(:rows=>rows, :cols=>cols, :variable=>ary, \n                        :width=>6, :height=>6, \n                        :titlerows=>1, :titlecols=>2, \n                        :roworigin=>-1, :colorigin=>-2, \n                        :rowstretchmode=>:last, :colstretchmode=>:last,\n                        :rowtagcommand=>proc{|row|\n                          row = Integer(row)\n                          (row>0 && row%2 == 1)? 'OddRow': ''\n                        }, \n                        :coltagcommand=>proc{|col|\n                          col = Integer(col)\n                          (col>0 && col%2 == 1)? 'OddCol': ''\n                        }, \n                        :selectmode=>:extended, :sparsearray=>false)\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nbtn = TkButton.new(:text=>'Exit', :command=>proc{exit})\n\nTk.grid(lbl, '-', :sticky=>:ew)\nTk.grid(table, sy, :sticky=>:news)\nTk.grid(sx, :sticky=>:ew)\nTk.grid(btn, :sticky=>:ew, :columnspan=>2)\n\nTk.root.grid_columnconfig(0, :weight=>1)\nTk.root.grid_rowconfig(1, :weight=>1)\n\ntable.tag_configure('OddRow', :bg=>'orange', :fg=>'purple')\ntable.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')\n\ntable.set_width([-2, 7], [-1, 7], [1, 5], [2, 8], [4, 14])\n\nputs \"Table is #{table.path} with array #{(table['variable'])}\"\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/buttons.rb",
    "content": "#!/usr/bin/env ruby\n##\n## buttons.rb\n##\n## demonstrates the simulation of a button array\n##\n## ( based on 'buttons.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\n# create the table\ntab  = TkVariable.new_hash\nrows = 20\ncols = 20\n\ntable = Tk::TkTable.new(:rows=>rows + 1, :cols=>cols + 1, \n                        :variable=>tab, :titlerows=>1, :titlecols=>1, \n                        :roworigin=>-1, :colorigin=>-1, \n                        :colwidth=>4, :width=>8, :height=>8, \n                        :cursor=>'top_left_arrow', :borderwidth=>2, \n                        :flashmode=>false, :state=>:disabled)\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nTk.grid(table, sy, :sticky=>:news)\nTk.grid(sx, :sticky=>:ew)\n\nTk.root.grid_columnconfig(0, :weight=>1)\nTk.root.grid_rowconfig(0, :weight=>1)\n\n# set up tags for the various states of the buttons\ntable.tag_configure('OFF', :bg=>'red',    :relief=>:raised)\ntable.tag_configure('ON',  :bg=>'green',  :relief=>:sunken)\ntable.tag_configure('sel', :bg=>'gray75', :relief=>:flat)\n\n# clean up if mouse leaves the widget\ntable.bind('Leave', proc{|w| w.selection_clear_all}, '%W')\n\n# highlight the cell under the mouse\ntable.bind('Motion', proc{|w, x, y|\n             Tk.callback_break if w.selection_include?(TkComm._at(x,y))\n             w.selection_clear_all\n             w.selection_set(TkComm._at(x,y))\n             Tk.callback_break\n             ## \"break\" prevents the call to tkTableCheckBorder\n           }, '%W %x %y')\n\n# mousebutton 1 toggles the value of the cell\n# use of \"selection includes\" would work here\ntable.bind('1', proc{|w, x, y|\n             #rc = w.curselection[0]\n             rc = w.index(TkComm._at(x,y))\n             if tab[rc] == 'ON'\n               tab[rc] = 'OFF'\n               w.tag_cell('OFF', rc)\n             else\n               tab[rc] = 'ON'\n               w.tag_cell('ON', rc)\n             end}, '%W %x %y')\n\n\n# inititialize the array, titles, and celltags\n0.step(rows){|i|\n  tab[i,-1] = i\n  0.step(cols){|j|\n    if i == 0\n      tab[-1,j] = j\n    end \n    tab[i,j] = \"OFF\"\n    table.tag_cell('OFF', \"#{i},#{j}\")\n  }\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/command.rb",
    "content": "#!/usr/bin/env ruby\n##\n## command.rb\n##\n## This demo shows the use of the table widget's -command options\n##\n## ( based on 'command.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\n# create the table\ndata = TkVariable.new_hash\nrows = 10\ncols = 10\n\n# fill table variable\n((-(rows))..rows).each{|x|\n  ((-(cols))..cols).each{|y|\n    data[x,y] = \"#{x} x #{y}\"\n  }\n}\n\nlbl = TkLabel.new(:text=>\"TkTable :command Example\")\ncur_var = TkVariable.new\ncurrent = TkLabel.new(:textvariable=>cur_var, :width=>5)\nent_var = TkVariable.new\nentry = TkEntry.new(:textvariable=>ent_var)\n\ntable = Tk::TkTable.new(:rows=>rows, :cols=>cols, \n                        :command=>[proc{|mode, cell, val|\n                          if (mode == :w)\n                            data[cell] = val\n                          else\n                            begin\n                              data[cell]  # exist\n                            rescue\n                              ''          # not exist\n                            end\n                          end\n                        }, '%i %C %s'], \n                        :width=>6, :height=>6, \n                        :titlerows=>1, :titlecols=>1, \n                        :roworigin=>-1, :colorigin=>-1, \n                        :rowstretchmode=>:last, :colstretchmode=>:last,\n                        :rowtagcommand=>proc{|row|\n                          row = Integer(row)\n                          (row>0 && row%2 == 1)? 'OddRow': ''\n                        },\n                        :coltagcommand=>proc{|col|\n                          col = Integer(col)\n                          (col>0 && col%2 == 1)? 'OddCol': ''\n                        }, \n                        :selectmode=>:extended, :flashmode=>true, \n                        :rowstretch=>:unset, :colstretch=>:unset,\n                        :browsecommand=>[proc{|w, s|\n                          cur_var.value = s\n                          ent_var.value = w.get(s)\n                        }, '%W %S'], \n                        :validate=>true, \n                        :validatecommand=>proc{|e| \n                          ent_var.value = e.new_value; true\n                        })\n=begin\n                        :validatecommand=>[\n                          proc{|s| \n                            ent_var.value = s; true\n                          }, '%S'])\n=end\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nentry.bind('Return', proc{|w| table.curvalue = w.value}, '%W')\n\nTk.grid(lbl, '-', '-', :sticky=>:ew)\nTk.grid(current, entry, '-', :sticky=>:ew)\nTk.grid(table, '-', sy, :sticky=>:news)\nTk.grid(sx, '-', :sticky=>:ew)\n\nTk.root.grid_columnconfig(1, :weight=>1)\nTk.root.grid_rowconfig(2, :weight=>1)\n\ntable.tag_configure('OddRow', :bg=>'orange', :fg=>'purple')\ntable.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')\n\nputs \"Table is #{table.path}\"\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/debug.rb",
    "content": "#!/usr/bin/env ruby\n##\n## debug.rb\n##\n## This demo uses most features of the table widget\n##\n## ( based on 'debug.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\n# create the table\nary  = TkVariable.new_hash\nrows = 25\ncols = 20\n\n# fill table variable\n((-(rows))..rows).each{|x|\n  ((-(cols))..cols).each{|y|\n    ary[x,y] = \"r#{x},c#{y}\"\n  }\n}\n\nlbl = TkLabel.new(:text=>\"TkTable v2 Example\")\n\ntable = Tk::TkTable.new(:rows=>rows, :cols=>cols, :variable=>ary, \n                        :width=>6, :height=>6, \n                        :titlerows=>1, :titlecols=>2, \n                        :roworigin=>-5, :colorigin=>-2, \n                        :coltagcommand=>proc{|col|\n                          col = Integer(col)\n                          (col>0 && col%2 == 1)? 'OddCol': ''\n                        }, \n                        :selectmode=>:extended, :flashmode=>true, \n                        :rowstretch=>:unset, :colstretch=>:unset,\n                        :selecttitles=>false, :drawmode=>:single)\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nbtn = TkButton.new(:text=>'Exit', :command=>proc{exit})\n\nTk.grid(lbl, '-', :sticky=>:ew)\nTk.grid(table, sy, :sticky=>:news)\nTk.grid(sx, :sticky=>:ew)\nTk.grid(btn, :sticky=>:ew, :columnspan=>2)\n\nTk.root.grid_columnconfig(0, :weight=>1)\nTk.root.grid_rowconfig(1, :weight=>1)\n\ntable.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')\ntable.tag_configure('title',  :bg=>'red',   :fg=>'green', :relief=>:sunken)\ntable.tag_configure('dis',    :state=>:disabled)\n\nfirst = table[:colorigin]\n%w(n s e w nw ne sw se c).each_with_index{|anchor, idx|\n  table.tag_configure(anchor, :anchor=>anchor)\n  table.tag_row(anchor, idx)\n  table.set([idx,first], anchor)\n}\ncourier = TkFont.new(:family=>'Courier', :size=>10)\ntable.tag_configure('s', :font=>courier, :justify=>:center)\n\nlogo = TkPhotoImage.new(:file=>File.join(File.dirname(File.expand_path(__FILE__)), 'tcllogo.gif'))\ntable.tag_configure('logo', :image=>logo, :showtext=>true)\ntable.tag_cell('logo', [1,2], [2,3], [4,1])\ntable.tag_cell('dis', [2,1], [1,-1], [3,0])\ntable.set_width([-2,8], [-1,9], [0, 12], [4, 14])\n\ntable.set([1,1], \"multi-line\\ntext\\nmight be\\ninteresting\", \n          [3,2], \"more\\nmulti-line\\nplaying\\n\", \n          [2,2], \"null\\0byte\")\n\n# This is in the row span\nl = TkLabel.new(table, :text=>'Window s', :bg=>'yellow')\ntable.window_configure([6,0], :sticky=>:s, :window=>l)\n\n# This is in the row titles\nl = TkLabel.new(table, :text=>'Window ne', :bg=>'yellow')\ntable.window_configure([4,-1], :sticky=>:ne, :window=>l)\n\n# This will get swallowed by a span\nl = TkLabel.new(table, :text=>'Window ew', :bg=>'yellow')\ntable.window_configure([5,3], :sticky=>:ew, :window=>l)\n\n# This is in the col titles\nl = TkLabel.new(table, :text=>'Window news', :bg=>'yellow')\ntable.window_configure([-5,1], :sticky=>:news, :window=>l)\n\nl = TkLabel.new(table.winfo_parent, :text=>'Sibling l', :bg=>'orange')\ntable.window_configure([5,1], :sticky=>:news, :window=>l)\n\nif table.span_list.empty?\n  table.set_spans([-1,-2], [0,3], [1,2], [0,5], [3,2], [2,2], [6,0], [4,0])\nend\n\nputs \"Table is #{table.path} with array #{(table['variable'])}\"\n\n# table.postscript(:file=>'out.ps', :first=>:origin, :last=>[2,2])\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/dynarows.rb",
    "content": "#!/usr/bin/env ruby\n##\n## dynarows.rb\n##\n## This demos shows the use of the validation mechanism of the table\n## and uses the table's cache (no -command or -variable) with a cute\n## dynamic row routine.\n## \n## ( based on 'dynarows.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\ndef table_validate(w, idx)\n  return unless idx =~ /^(\\d+),(\\d+)$/\n  row = Integer($1)\n  col = Integer($2)\n  val = w.get(idx)\n\n [w, idx]\n  nrows = w[:rows]\n  return if row == nrows - 1 && val == ''\n\n  begin\n    time = Tk.tk_call('clock', 'scan', val)\n    date = []\n    Tk.tk_call('clock', 'format', time, \n               :format=>'%m %d %Y').split(' ').each{|item|\n      date << item.sub(/^\\s*0*/,'')\n    }\n    w.set(idx, date.join('/'))\n    if row == nrows - 1\n      if w.get([row,1]) != '' && w.get([row,2]) != ''\n        w.tag_row_reset(row)\n        w.set([row,0], row)\n        nrows += 1\n        row += 1\n        w.configure(:rows=>nrows)\n        w.tag_row('unset', row)\n        w.set([row,0], '*')\n        w.see([row,1])\n        w.activate([row,1])\n      end\n    end\n  rescue\n    Tk.bell\n    w.activate(idx)\n    w.selection_clear_all\n    w.selection_set(:active)\n    w.see(:active)\n  end\nend\n\n\nlbl = TkLabel.new(:text=>\"Dynamic Date Validated Rows\")\n\ntable = Tk::TkTable.new(:rows=>2, :cols=>3, :cache=>1, :selecttype=>:row, \n                        :titlerows=>1, :titlecols=>1, :height=>5, \n                        :colstretch=>:unset, :rowstretch=>:unset, \n                        :autoclear=>true, \n                        :browsecommand=>[\n                          proc{|w,s| table_validate(w, s)}, \n                          '%W %s'\n                        ])\ntable.set([0,1], 'Begin', [0,2], 'End', [1,0], '*')\ntable.tag_configure('unset', :fg=>'#008811')\ntable.tag_configure('title', :fg=>'red')\ntable.tag_row('unset', 1)\ntable.set_width(0,3)\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nTk.grid(lbl, '-', :sticky=>:ew)\nTk.grid(table, sy, :sticky=>:news)\nTk.grid(sx, :sticky=>:ew)\n\nTk.root.grid_columnconfig(0, :weight=>1)\nTk.root.grid_rowconfig(1, :weight=>1)\n\nrtn_proc = proc{|w|\n  r = w.row_index(:active)\n  c = w.col_index(:active)\n\n  if c == 2\n    r += 1\n    w.activate([r,1])\n  else\n    c += 1\n    w.activate([r,c])\n  end\n  w.see(:active)\n  Tk.callback_break\n}\n\ntable.bind('Return', rtn_proc, '%W')\ntable.bind('KP_Enter', rtn_proc, '%W')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/maxsize.rb",
    "content": "#!/usr/bin/env ruby\n##\n## maxsize.rb\n##\n## This demo uses a really big table.  The big startup time is in\n## filling the table's Tcl array var.\n## \n## ( based on 'maxsize.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\nary  = TkVariable.new_hash\nrows = 40000\ncols = 10\n\n# fill table variable\n((-(rows))..rows).each{|x|\n  ((-(cols))..cols).each{|y|\n    ary[x,y] = \"#{x},#{y}\"\n  }\n}\n\nlbl = TkLabel.new(:text=>\"TkTable v2 Example\")\n\ntable = Tk::TkTable.new(:rows=>rows, :cols=>cols, :variable=>ary, \n                        :width=>6, :height=>8, \n                        :titlerows=>1, :titlecols=>1, \n                        :coltagcommand=>proc{|col|\n                          col = Integer(col)\n                          (col>0 && col%2 == 1)? 'OddCol': ''\n                        }, \n                        :selectmode=>:extended, \n                        :colstretch=>:unset, :rowstretch=>:unset, \n                        :selecttitles=>false, :drawmode=>:slow)\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nbtn = TkButton.new(:text=>'Exit', :command=>proc{exit})\n\nTk.grid(lbl, '-', :sticky=>:ew)\nTk.grid(table, sy, :sticky=>:news)\nTk.grid(sx, :sticky=>:ew)\nTk.grid(btn, :sticky=>:ew, :columnspan=>2)\n\nTk.root.grid_columnconfig(0, :weight=>1)\nTk.root.grid_rowconfig(1, :weight=>1)\n\ntable.tag_configure('OddCol', :bg=>'brown', :fg=>'pink')\ntable.tag_configure('title',  :bg=>'red',   :fg=>'blue', :relief=>:sunken)\ntable.tag_configure('dis',    :state=>:disabled)\n\nfirst = table[:colorigin]\n%w(n s e w nw ne sw se c).each_with_index{|anchor, idx|\n  table.tag_configure(anchor, :anchor=>anchor)\n  table.tag_row(anchor, idx)\n  table.set([idx,first], anchor)\n}\ncourier = TkFont.new(:family=>'Courier', :size=>10)\ntable.tag_configure('s', :font=>courier, :justify=>:center)\n\ntable.set_width([-2, 8], [-1, 9], [0, 12], [4, 14])\n\nputs \"Table is #{table.path} with array #{(table['variable'])}\"\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/spreadsheet.rb",
    "content": "#!/usr/bin/env ruby\n##\n## spreadsheet.rb\n##\n## This demos shows how you can simulate a 3D table\n## and has other basic features to begin a basic spreadsheet\n## \n## ( based on 'spreadsheet.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\nrows = 10\ncols = 10\ncur_var = TkVariable.new\ntable_list = Hash.new{|hash, key| hash[key] = TkVariable.new_hash}\npage = TkVariable.new('AA')\ncolor = Hash.new('pink')\ncolor['AA'] = 'orange'\ncolor['BB'] = 'blue'\ncolor['CC'] = 'green'\n\ndef colorize(num)\n  num = Integer(num)\n  return 'colored' if (num > 0 && num % 2 == 1)\nend\n\ndef fill_table(tbl_list, page, r=10, c=10)\n  ary = tbl_list[page]\n\n  (0...r).each{|i|\n    (0...c).each{|j|\n      if i!=0 && j!=0\n        ary[i,j] = \"#{page} #{i},#{j}\"\n      elsif i!=0\n        ary[i,j] = i.to_s\n      else\n        ary[i,j] = (64+j).chr\n      end\n    }\n  }\nend\n\ndef changepage(tbl_list, tbl, ent, col, var, elem, op)\n  if elem != ''\n    page = var[elem]\n  else\n    page = var.value\n  end\n  if tbl[:variable] != tbl_list[page].id\n    tbl.selection_clear_all\n    tbl.variable(tbl_list[page])\n    ent.textvariable(tbl_list[page].ref('active'))\n    tbl.activate('origin')\n    tbl.tag_configure('colored', :bg=>col[page])\n    tbl.see('active')\n  end\nend\n\nlbl = TkLabel.new(:text=>\"TkTable v1 Spreadsheet Example\")\n\ncurrent = TkLabel.new(:textvariable=>cur_var, :width=>5)\nentry = TkEntry.new(:textvariable=>table_list[page.value].ref('active'))\nlpage = TkLabel.new(:text=>'PAGE:', :width=>6, :anchor=>:e)\noptmenu = TkOptionMenubutton.new(page, *(%w(AA BB CC DD)))\n\nfill_table(table_list, page.value)\nfill_table(table_list, 'BB', Integer(rows/2), Integer(cols/2))\n\ntable = Tk::TkTable.new(:rows=>rows, :cols=>cols, :width=>5, :height=>5, \n                        :variable=>table_list[page.value], \n                        :titlerows=>1, :titlecols=>1, \n                        :coltagcommand=>proc{|n| colorize(n)},\n                        :flashmode=>true, :selectmode=>:extended, \n                        :colstretch=>:unset, :rowstretch=>:unset, \n                        :browsecommand=>proc{|e| cur_var.value = e.new_index})\n\npage.trace(:w, proc{|var, elem, op| \n             changepage(table_list, table, entry, color, var, elem, op)\n           })\n\ntable.tag_configure('colored', :bg=>color[page.value])\ntable.tag_configure('title',   :fg=>'red', :relief=>:groove)\ntable.tag_configure('blue',    :bg=>'blue')\ntable.tag_configure('green',   :bg=>'green')\n\ntable.tag_cell('green', [6,3], [5,7], [4,9])\ntable.tag_cell('blue', [8,8])\ntable.tag_row('blue', 7)\ntable.tag_col('blue', 6, 8)\ntable.set_width([0, 3], [2, 7])\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nbtn = TkButton.new(:text=>'Exit', :command=>proc{exit})\n\nTk.grid(lbl, '-', '-', '-', '-', :sticky=>:ew)\nTk.grid(current, entry, lpage, optmenu, '-', :sticky=>:ew)\nTk.grid(table, '-', '-', '-', sy, :sticky=>:ns)\nTk.grid(sx, '-', '-', '-', :sticky=>:ew)\nTk.grid(btn, '-', '-', '-', '-', :sticky=>:ew)\n\nTk.root.grid_columnconfig(1, :weight=>1)\nTk.root.grid_rowconfig(2, :weight=>1)\n\ntable.grid_configure(:sticky=>:news)\n\nentry.bind('Return', proc{\n             r = table.row_index(:active)\n             c = table.col_index(:active)\n             rmax = table[:rows]\n             cmax = table[:cols]\n\n             c += 1\n             if c == cmax\n               c = table[:titlecols]\n               r += 1\n               if r == rmax\n                 r = table[:titlerows]\n               end\n             end\n             table.activate([r, c])\n             table.see('active')\n           })\n\nmenu = TkMenu.new\nm_file = TkMenu.new(menu)\nTk.root.menu(menu)\nmenu.add(:cascade, :label=>'File', :underline=>0, :menu=>m_file)\nm_file.add(:command, :label=>'Fill Array', \n           :command=>proc{ fill_table(table_list, page.value) })\nm_file.add(:command, :label=>'Quit', :command=>proc{exit})\n\nputs \"Table is #{table.path} with array #{(table['variable'])}\"\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/tktable/valid.rb",
    "content": "#!/usr/bin/env ruby\n##\n## valid.rb\n##\n## This demos shows the use of the validation mechanism of the table\n## and uses the table's cache (no -command or -variable)\n## \n## ( based on 'valid.tcl' included source archive of tktable extension )\n##\nrequire 'tk'\nrequire 'tkextlib/tktable'\n\nrows = 10\ncols = 10\n\ndef colorize(num)\n  num = Integer(num)\n  return 'colored' if (num > 0 && num % 2 == 1)\nend\n\ndef fill_headers(w, r=10, c=10)\n  (1..(r-1)).each{|i| w.set([i,0], i.to_s)}\n\n  (1..(c-1)).each{|j|\n    if j % 3 == 1\n      w.set([0,j], 'AlphaNum')\n    elsif j % 2 == 1\n      w.set([0,j], 'Alpha')\n    elsif j != 0\n      w.set([0,j], 'Real')\n    end\n  }\nend\n\ndef validate_proc(c, val)\n  if c % 3 == 1\n    # AlphaNum\n    regexp = /^[A-Za-z0-9 ]*$/\n  elsif c % 2 == 1\n    # Alpha\n    regexp = /^[A-Za-z ]*$/\n  elsif c != 0\n    # 'Real'\n    regexp = /^[-+]?[0-9]*\\.?[0-9]*([0-9]\\.?e[-+]?[0-9]*)?$/\n  end\n  if val =~ regexp\n    return true\n  else\n    Tk.bell\n    return false\n  end\nend\n\nlbl = TkLabel.new(:text=>\"TkTable v1 Validated Table Example\")\n\ntable = Tk::TkTable.new(:rows=>rows, :cols=>cols, :cache=>1, \n                        :width=>5, :height=>5, :titlerows=>1, :titlecols=>1, \n                        :coltagcommand=>proc{|n| colorize(n)},\n                        :flashmode=>true, :selectmode=>:extended, \n                        :colstretch=>:unset, :rowstretch=>:unset, \n                        :validate=>true, \n                        :validatecommand=>proc{|e|\n                          unless e.widget.tag_include?('title', e.index)\n                            validate_proc(e.column, e.new_value)\n                          end } )\n\nfill_headers(table)\n\ntable.tag_configure('colored', :bg=>'lightblue')\ntable.tag_configure('title',   :fg=>'red')\ntable.set_width(0,3)\n\nsx = table.xscrollbar(TkScrollbar.new)\nsy = table.yscrollbar(TkScrollbar.new)\n\nbtn = TkButton.new(:text=>'Exit', :command=>proc{exit})\n\nTk.grid(lbl, '-', :sticky=>:ew)\nTk.grid(table, sy, :sticky=>:news)\nTk.grid(sx, :sticky=>:ew)\nTk.grid(btn, '-', :sticky=>:ew)\n\nTk.root.grid_columnconfig(0, :weight=>1)\nTk.root.grid_rowconfig(1, :weight=>1)\n\nputs \"Table is #{table.path}\"\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/bitmaps.rb",
    "content": "#\n# Demo: Bitmaps\n#\ndef demoBitmaps(t)\n  #if $Version_1_1_OrLater\n  if @has_bgimg\n    t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n                :selectmode=>:browse, :orient=>:horizontal, :wrap=>'5 items', \n                :showheader=>false, :backgroundimage=>@images['sky'])\n  else\n    t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n                :selectmode=>:browse, :orient=>:horizontal, :wrap=>'5 items', \n                :showheader=>false)\n  end\n\n  if $HasColumnCreate\n    t.column_create(:itembackground=>['gray90', []])\n  else\n    t.column_configure(0, :itembackground=>['gray90', []])\n  end\n\n  t.element_create('elemTxt', :text, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('elemSelTxt', :rect, :showfocus=>true, \n                   :fill=>[@SystemHighlight, ['selected', 'focus']])\n  t.element_create('elemSelBmp', :rect, :outlinewidth=>4, \n                   :outline=>[@SystemHighlight, ['selected', 'focus']])\n  t.element_create('elemBmp', :bitmap, \n                   :foreground=>[@SystemHighlight, ['selected', 'focus']], \n                   :background=>'linen', \n                   :bitmap=>['question' ['selected']])\n\n  s = t.style_create('STYLE', :orient=>:vertical)\n  t.style_elements(s, ['elemSelBmp', 'elemBmp', 'elemSelTxt', 'elemTxt'])\n  t.style_layout(s, 'elemSelBmp', :union=>'elemBmp', :ipadx=>6, :ipady=>6)\n  t.style_layout(s, 'elemBmp',    :pady=>[0, 6], :expand=>:we)\n  t.style_layout(s, 'elemSelTxt', :union=>'elemTxt', :ipadx=>2)\n  t.style_layout(s, 'elemTxt',    :expand=>:we)\n\n  # Set default item style\n  if $Version_1_1_OrLater\n    t.defaultstyle = [s]\n  end\n\n  bitmap_names = %w(error gray75 gray50 gray25 gray12 \n                    hourglass info questhead question warning)\n\n  bitmap_names.each{|name|\n    i = t.item_create\n    unless $Version_1_1_OrLater\n      t.item_style_set(i, 0, s)\n    end\n    t.item_text(i, 0, name)\n    t.item_element_configure(i, 0, 'elemBmp', :bitmap=>name)\n    t.item_lastchild(:root, i)\n  }\n\n  bitmap_names.each{|name|\n    i = t.item_create\n    t.item_style_set(i, 0, s)\n    t.item_text(i, 0, name)\n    if true\n      t.item_element_configure(i, 0, 'elemBmp', :bitmap=>name, \n                               :foreground=>['brown', ''], \n                               :background=>['', ''])\n    else\n      t.item_element_configure(i, 0, 'elemBmp', :bitmap=>name, \n                               :foreground=>[\n                                 @SystemHighlight, ['selected', 'focus'], \n                                 'brown', []\n                               ], \n                               :background=>['', []])\n    end\n    t.item_lastchild(:root, i)\n  }\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/demo.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/treectrl'\n\n$ScriptDir = File.dirname(File.expand_path(__FILE__))\n\n$HasColumnCreate = Tk::TreeCtrl::HasColumnCreateCommand\n\n$Version_1_1_OrLater = (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0)\n\n#if Hash.instance_methods.include?(:key)\nif TkCore::WITH_RUBY_VM  ### Ruby 1.9 !!!!\n  # ruby 1.9.x --> use Hash#key\n  # Because Hash#index show warning \"Hash#index is deprecated; use Hash#key\".\nelse\n  # ruby 1.8.x --> use Hash#index\n  class Hash\n    alias key index\n  end\nend\n\nclass TkTreeCtrl_demo\n  def initialize(dir)\n    @ScriptDir = dir || '.'\n\n    @thisPlatform = Tk::PLATFORM['platform']\n    if @thisPlatform == 'unix' && Tk.windowingsystem == 'aqua'\n      @thisPlatform = 'macosx'\n    end\n\n    @RandomN = [500]\n\n    @images = Hash.new\n    @sel_images = Hash.new\n\n    @popup = Hash.new\n    @mTree = Hash.new\n    @mHeader = Hash.new\n\n    @non_clear_list = []\n\n    @demoCmd = Hash.new\n    @demoFile = Hash.new\n\n    # Get default colors\n    w = TkListbox.new\n    @SystemButtonFace    = w[:highlightbackground]\n    @SystemHighlight     = w[:selectbackground]\n    @SystemHighlightText = w[:selectforeground]\n    w.destroy\n\n    ####################\n\n    make_source_window()\n    make_menubar()\n    make_main_window()\n\n    if $Version_1_1_OrLater\n      begin\n        @tree2[:backgroundimage]\n        @has_bgimg = true\n      rescue\n        @has_bgimg = false\n      end\n    else\n      @has_bgimg = false\n    end\n\n    ####################\n\n    make_list_popup()\n    make_header_popup()\n\n    init_pics('sky')\n\n    ####################\n\n    @tree2.bind('ButtonPress-3', \n                proc{|w, x, y, rootx, rooty|\n                  show_list_popup(w, x, y, rootx, rooty)\n                }, '%W %x %y %X %Y')\n\n    # Allow \"scan\" bindings\n    if @thisPlatform == 'windows'\n      @tree2.bind_remove('Control-ButtonPress-3')\n    end\n\n    ####################\n\n    init_demo_scripts_module()\n    load_demo_scripts()\n    init_demo_list()\n\n    ####################\n\n    @tree1.notify_bind(@tree1, 'Selection', \n                       proc{|c, t|\n                         if c == 1\n                           item = t.selection_get[0]\n                           demo_set(@demoCmd[item], @demoFile[item])\n                         end\n                       }, '%c %T')\n\n    # When one item is selected in the demo list, display the styles in \n    # that item.\n    # See DemoClear for why the tag \"DontDelete\" is used\n    @tree2.notify_bind('DontDelete', 'Selection', \n                       proc{|c, t|\n                         display_styles_in_item(t.selection_get[0]) if c == 1\n                       }, '%c %T')\n  end\n\n  ##########################\n\n  def init_pics(*args)\n    args.each{|pat|\n      unless TkImage.names.find{|img| (name = @images.key(img)) && File.fnmatch(pat, name)}\n        Dir.glob(File.join(@ScriptDir, 'pics', \"#{pat}.gif\")).each{|file|\n          name = File.basename(file, '.gif')\n          img = TkPhotoImage.new(:file=>file)\n          @images[name] = img\n          @sel_images[name] = TkPhotoImage.new\n          @sel_images[name].copy(img)\n          Tk::TreeCtrl.image_tint(@sel_images[name], @SystemHighlight, 128)\n        }\n      end\n    }\n  end\n\n  ##########################\n\n  private\n\n  def make_menubar\n    menuspec = [\n      [['File']]\n    ]\n    if Tk::PLATFORM['platform'] != 'unix'\n      TkConsole.create\n      TkConsole.eval('.console conf -height 8')\n      menuspec[0] << ['Console', proc{\n          if TkComm.bool(TkConsole.eval('winfo ismapped .'))\n            TkConsole.hide\n          else\n            TkConsole.show\n          end\n        }]\n    end\n    menuspec[0] << ['View Source', proc{toggle_source_window()}]\n    menuspec[0] << ['Quit', proc{exit}]\n    Tk.root.add_menubar(menuspec)\n  end\n\n  def make_source_window\n    @src_top = TkToplevel.new\n    f = TkFrame.new(@src_top, :borderwidth=>0)\n    case @thisPlatform\n    when 'macintosh', 'macos'\n      font = TkFont.new(['Geneva', 9])\n    when 'unix'\n      font = TkFont.new(['Courier', -12])\n    else\n      font = TkFont.new(['Courier', 9])\n    end\n\n    @src_txt = TkText.new(f, :font=>font, :tabs=>font.measure('1234'), \n                          :wrap=>:none)\n    xscr = @src_txt.xscrollbar(TkScrollbar.new(f))\n    yscr = @src_txt.yscrollbar(TkScrollbar.new(f))\n\n    f.pack(:expand=>true, :fill=>:both)\n    f.grid_columnconfigure(0, :weight=>1)\n    f.grid_rowconfigure(0, :weight=>1)\n    @src_txt.grid(:row=>0, :column=>0, :sticky=>:news)\n    xscr.grid(:row=>1, :column=>0, :sticky=>:we)\n    yscr.grid(:row=>0, :column=>1, :sticky=>:ns)\n\n    @src_top.protocol('WM_DELETE_WINDOW', proc{@src_top.withdraw})\n    @src_top.geometry('-0+0')\n    @src_top.withdraw\n  end\n\n  def show_source(file)\n    @src_top.title(\"Demo Source: #{file}\")\n    @src_txt.value = IO.read(File.join(@ScriptDir, file))\n    @src_txt.set_insert('1.0')\n  end\n\n  def toggle_source_window\n    if @src_top.winfo_mapped?\n      @src_top.withdraw\n    else\n      @src_top.deiconify\n    end\n  end\n\n  def tree_plus_scrollbars_in_a_frame(parent, h, v)\n    f = TkFrame.new(parent, :borderwidth=>1, :relief=>:sunken)\n    case @thisPlatform\n    when 'macintosh'\n      font = TkFont.new(['Geneva', 9])\n    when 'macos'\n      font = TkFont.new(['Lucida Grande', 11])\n    when 'unix'\n      font = TkFont.new(['Helvetica', -12])\n    else\n      # There is a bug on my Win98 box with Tk_MeasureChars() and\n      # MS Sans Serif 8.\n      font = TkFont.new(['MS Sans', 8])\n    end\n\n    tree = Tk::TreeCtrl.new(f, :highlightthickness=>0, \n                            :borderwidth=>0, :font=>font)\n    tree[:xscrollincrement] = 20\n    tree.debug_configure(:enable=>false, :display=>false)\n\n    if h\n      h_scr = TkScrollbar.new(f, :orient=>:horizontal, \n                              :command=>proc{|*args| tree.xview(*args)})\n      tree.notify_bind(h_scr, 'Scroll-x', \n                       proc{|w, l, u| w.set(l, u)}, '%W %l %u')\n      h_scr.bind('ButtonPress-1', proc{tree.set_focus})\n    end\n\n    if v\n      v_scr = TkScrollbar.new(f, :orient=>:vertical, \n                              :command=>proc{|*args| tree.yview(*args)})\n      tree.notify_bind(v_scr, 'Scroll-y', \n                       proc{|w, l, u| w.set(l, u)}, '%W %l %u')\n      v_scr.bind('ButtonPress-1', proc{tree.set_focus})\n    end\n\n    f.grid_columnconfigure(0, :weight=>1)\n    f.grid_rowconfigure(0, :weight=>1)\n    tree.grid(:row=>0, :column=>0, :sticky=>:news)\n    h_scr.grid(:row=>1, :column=>0, :sticky=>:we) if h\n    v_scr.grid(:row=>0, :column=>1, :sticky=>:ns) if v\n\n    [f, tree]\n  end\n\n  def make_main_window\n    Tk.root.title('Tk::TreeCtrl Demo')\n\n    case @thisPlatform\n    when 'macintosh', 'macosx'\n      Tk.root.geometry('+40+40')\n    else\n      Tk.root.geometry('+0+30')\n    end\n\n    pane1 = TkPanedWindow.new(:orient=>:vertical, :borderwidth=>0)\n    pane2 = TkPanedWindow.new(:orient=>:horizontal, :borderwidth=>0)\n\n    # Tree + scrollbar: demos\n    f1, @tree1 = tree_plus_scrollbars_in_a_frame(nil, false, true)\n    @tree1.configure(:showbuttons=>false, :showlines=>:false, \n                    :showroot=>false, :height=>100)\n    if $HasColumnCreate\n      @tree1.column_create(:text=>'List of Demos', \n                           :expand=>true, :button=>false)\n    else\n      @tree1.column_configure(0, :text=>'List of Demos', \n                              :expand=>true, :button=>false)\n    end\n\n    # Tree + scrollbar: styles + elements in list\n    f4, @tree4 = tree_plus_scrollbars_in_a_frame(nil, false, true)\n    @tree4.configure(:showroot=>false, :height=>140)\n    if $HasColumnCreate\n      @tree4.column_create(:text=>'Elements and Styles', \n                           :expand=>true, :button=>false)\n    else\n      @tree4.column_configure(0, :text=>'Elements and Styles', \n                              :expand=>true, :button=>false)\n    end\n\n    # Tree + scrollbar: styles + elements in selected item\n    f3, @tree3 = tree_plus_scrollbars_in_a_frame(nil, false, true)\n    @tree3.configure(:showroot=>false)\n    if $HasColumnCreate\n      @tree3.column_create(:text=>'Styles in Item', \n                           :expand=>true, :button=>false)\n    else\n      @tree3.column_configure(0, :text=>'Styles in Item', \n                              :expand=>true, :button=>false)\n    end\n\n    pane1.add(f1, f4, f3, :height=>150)\n    pane1.pack(:expand=>true, :fill=>:both)\n\n    # Frame on right\n    f2_base = TkFrame.new\n\n    # Tree + scrollbars\n    f2, @tree2 = tree_plus_scrollbars_in_a_frame(f2_base, true, true)\n    @tree2.configure(:indent=>19)\n    @tree2.debug_configure(:enable=>false, :display=>true, \n                           :erasecolor=>'pink', :displaydelay=>30)\n\n    # Give it a big border to debug drawing\n    @tree2.configure(:borderwidth=>6, :relief=>:ridge, :highlightthickness=>3)\n\n    f2_base.grid_columnconfigure(0, :weight=>1)\n    f2_base.grid_rowconfigure(0, :weight=>1)\n    f2.grid(:row=>0, :column=>0, :sticky=>:news, :pady=>0)\n\n    pane2.add(pane1, :width=>200)\n    pane2.add(f2_base, :width=>450)\n\n    pane2.pack(:expand=>true, :fill=>:both)\n\n    ###\n    # A treectrl widget can generate the following built-in events:\n    # <ActiveItem> called when the active item changes\n    # <Collapse-before> called before an item is closed\n    # <Collapse-after> called after an item is closed\n    # <Expand-before> called before an item is opened\n    # <Expand-after> called after an item is opened\n    # <Selection> called when items are added to or removed from the selection\n    # <Scroll-x> called when horizontal scroll position changes\n    # <Scroll-y> called when vertical scroll position changes\n    #\n    # The application programmer can define custom events to be\n    # generated by the \"T notify generate\" command. The following events\n    # are generated by the example bindings.\n\n    @tree2.notify_install_event('Header')\n    @tree2.notify_install_detail('Header', 'invoke')\n\n    @tree2.notify_install_event('Drag')\n    @tree2.notify_install_detail('Drag', 'begin')\n    @tree2.notify_install_detail('Drag', 'end')\n    @tree2.notify_install_detail('Drag', 'receive')\n\n    @tree2.notify_install_event('Edit')\n    @tree2.notify_install_detail('Edit', 'accept')\n  end\n\n  def make_list_popup\n    @popup[:bgimg] = TkVariable.new\n    @popup[:bgmode] = TkVariable.new\n    @popup[:debug] = Hash.new{|h, k| h[k] = TkVariable.new}\n    @popup[:doublebuffer] = TkVariable.new\n    @popup[:linestyle] = TkVariable.new\n    @popup[:orient] = TkVariable.new\n    @popup[:selectmode] = TkVariable.new\n    @popup[:show] = Hash.new{|h, k| h[k] = TkVariable.new}\n\n    menuspec = [\n      [ 'Collapse', [], nil, '', {:menu_config=>{:tearoff=>false}} ], \n\n      [ 'Expand',   [], nil, '', {:menu_config=>{:tearoff=>false}} ]\n    ]\n\n    # if $Version_1_1_OrLater\n    if @has_bgimg\n      menuspec << \\\n      [ 'Background Image', \n        [\n          [ 'none', [@popup[:bgimg], 'none'], nil, '', \n            {:command=>proc{@tree2.backgroundimage = ''}} ], \n          [ 'sky',  [@popup[:bgimg], 'sky'],  nil, '', \n            {:command=>proc{\n                @tree2.backgroundimage = @images[@popup[:bgimg].value]}} ]\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ]\n    end\n\n    menuspec.concat([\n      [ 'Background Mode', \n        %w(column index row visindex).collect{|val|\n          [ val, [@popup[:bgmode], val] , nil, '', \n            {:command=>proc{@tree2.backgroundmode = @popup[:bgmode].value}} ]\n        }, \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Debug', \n        [\n          [ 'Data',    @popup[:debug][:data],    nil, '', \n            {:command=>proc{\n                @tree2.debug_configure(:data=>@popup[:debug][:data].value)\n              }\n            } ], \n          [ 'Display', @popup[:debug][:display], nil, '', \n            {:command=>proc{\n                @tree2.debug_configure(:display=>@popup[:debug][:display].value)\n              }\n            } ], \n          [ 'Enable',  @popup[:debug][:enable],  nil, '', \n            {:command=>proc{\n                @tree2.debug_configure(:enable=>@popup[:debug][:enable].value)\n              }\n            } ]\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Buffering', \n        [\n          [ 'none',   [@popup[:doublebuffer], 'none'],   nil, '', \n            {:command=>proc{\n                @tree2.doublebuffer = @popup[:doublebuffer].value\n              }\n            } ], \n          [ 'item',   [@popup[:doublebuffer], 'item'],   nil, '', \n            {:command=>proc{\n                @tree2.doublebuffer = @popup[:doublebuffer].value\n              }\n            } ], \n          [ 'window', [@popup[:doublebuffer], 'window'], nil, '', \n            {:command=>proc{\n                @tree2.doublebuffer = @popup[:doublebuffer].value\n              }\n            } ]\n        ],\n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Line style', \n        [\n          [ 'dot',   [@popup[:linestyle], 'dot'],   nil, '', \n            {:command=>proc{@tree2.linestyle = @popup[:linestyle].value}} ], \n          [ 'solid', [@popup[:linestyle], 'solid'], nil, '', \n            {:command=>proc{@tree2.linestyle = @popup[:linestyle].value}} ]\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Orient', \n        [\n          [ 'Horizontal', [@popup[:orient], 'horizontal'], nil, '', \n            {:command=>proc{@tree2.orient = @popup[:orient].value}} ], \n          [ 'Vertical',   [@popup[:orient], 'vertical'],   nil, '', \n            {:command=>proc{@tree2.orient = @popup[:orient].value}} ]\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Selectmode', \n        %w(list browse extended multiple single).collect{|val|\n          [ val, [@popup[:selectmode], val] , nil, '', \n            {:command=>proc{@tree2.selectmode = @popup[:selectmode].value}} ]\n        }, \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Show', \n        [\n          [ 'Buttons', @popup[:show][:buttons], nil, '', \n            {:command=>proc{\n                @tree2.showbuttons = @popup[:show][:buttons].value\n              }\n            } ], \n          [ 'Header', @popup[:show][:header], nil, '', \n            {:command=>proc{\n                @tree2.showheader = @popup[:show][:header].value\n              }\n            } ], \n          [ 'Lines', @popup[:show][:lines], nil, '', \n            {:command=>proc{\n                @tree2.showlines = @popup[:show][:lines].value\n              }\n            } ], \n          [ 'Root', @popup[:show][:root], nil, '', \n            {:command=>proc{\n                @tree2.showroot = @popup[:show][:root].value\n              }\n            } ], \n          [ 'Root Button', @popup[:show][:rootbutton], nil, '', \n            {:command=>proc{\n                @tree2.showrootbutton = @popup[:show][:rootbutton].value\n              }\n            } ]\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}}\n      ],\n\n      [ 'Visible', [], nil, '', {:menu_config=>{:tearoff=>false}} ]\n    ])\n\n    m = TkMenu.new_menuspec(menuspec, @tree2, false)\n    @non_clear_list << m\n    @mTree[@tree2] = m\n  end\n\n  def show_list_popup(w, x, y, rootx, rooty)\n    id = w.identify(x, y)\n    unless id.empty?\n      if id[0] == 'header'\n        col = id[1]\n        @popup[:column].value = col\n        @popup[:arrow].value = w.column_cget(col, :arrow)\n        @popup[:arrowside].value = w.column_cget(col, :arrowside)\n        @popup[:arrowgravity].value = w.column_cget(col, :arrowgravity)\n        @popup[:expand].value = w.column_cget(col, :expand)\n        @popup[:squeeze].value = w.column_cget(col, :squeeze)\n        @popup[:justify].value = w.column_cget(col, :justify)\n        @mHeader[w].popup(rootx, rooty)\n        return\n      end\n    end\n\n    m = @mTree[w].entrycget('Collapse', :menu)\n    m.delete(0, :end)\n    if $Version_1_1_OrLater\n      m.add_command(:label=>'All', :command=>proc{w.item_collapse(:all)})\n    else\n      m.add_command(:label=>'All', :command=>proc{w.collapse(:all)})\n    end\n    unless id.empty?\n      if id[0] == 'item'\n        item = id[1]\n        if $Version_1_1_OrLater\n          m.add_command(:label=>\"Item #{item}\", \n                        :command=>proc{w.item_collapse(item)})\n          m.add_command(:label=>\"Item #{item} (recurse)\", \n                        :command=>proc{w.item_collapse_recurse(item)})\n        else\n          m.add_command(:label=>\"Item #{item}\", \n                        :command=>proc{w.collapse(item)})\n          m.add_command(:label=>\"Item #{item} (recurse)\", \n                        :command=>proc{w.collapse_recurse(item)})\n        end\n      end\n    end\n\n    m = @mTree[w].entrycget('Expand', :menu)\n    m.delete(0, :end)\n    if $Version_1_1_OrLater\n      m.add_command(:label=>'All', :command=>proc{w.item_expand(:all)})\n    else\n      m.add_command(:label=>'All', :command=>proc{w.expand(:all)})\n    end\n    unless id.empty?\n      if id[0] == 'item'\n        item = id[1]\n        if $Version_1_1_OrLater\n          m.add_command(:label=>\"Item #{item}\", \n                        :command=>proc{w.item_expand(item)})\n          m.add_command(:label=>\"Item #{item} (recurse)\", \n                        :command=>proc{w.item_expand_recurse(item)})\n        else\n          m.add_command(:label=>\"Item #{item}\", \n                        :command=>proc{w.expand(item)})\n          m.add_command(:label=>\"Item #{item} (recurse)\", \n                        :command=>proc{w.expand_recurse(item)})\n        end\n      end\n    end\n\n    [:data, :display, :enable].each{|k|\n      @popup[:debug][k].value = w.debug_cget(k)\n    }\n    # if $Version_1_1_OrLater\n    if @has_bgimg\n      @popup[:bgimg].value = @images.key(w[:backgroundimage])\n    end\n    @popup[:bgmode].value = w[:backgroundmode]\n    @popup[:doublebuffer].value = w[:doublebuffer]\n    @popup[:linestyle].value = w[:linestyle]\n    @popup[:orient].value = w[:orient]\n    @popup[:selectmode].value = w[:selectmode]\n    @popup[:show][:buttons].value = w[:showbuttons]\n    @popup[:show][:header].value = w[:showheader]\n    @popup[:show][:lines].value = w[:showlines]\n    @popup[:show][:root].value = w[:showroot]\n    @popup[:show][:rootbutton].value = w[:showrootbutton]\n\n    m = @mTree[w].entrycget('Visible', :menu)\n    m.delete(0, :end)\n    @popup[:visible] = []\n    (0...(w.numcolumns)).each{|i|\n      @popup[:visible][i] = TkVariable.new(w.column_cget(i, :visible))\n      txt = w.column_cget(i, :text)\n      img_name = w.column_cget(i, :image)\n      img_name = @images.key(img_name) if img_name.kind_of?(TkImage)\n      m.add_checkbutton(:variable=>@popup[:visible][i], \n                        :label=>\"Column #{i} \\\"#{txt}\\\" [#{img_name}]\", \n                        :command=>proc{w.column_configure(i, :visible=>@popup[:visible][i].value)})\n    }\n\n    @mTree[w].popup(rootx, rooty)\n  end\n\n  def make_header_popup\n    @popup[:column] = TkVariable.new unless @popup[:column]\n    @popup[:arrow] = TkVariable.new\n    @popup[:arrowside] = TkVariable.new\n    @popup[:arrowgravity] = TkVariable.new\n    @popup[:expand] = TkVariable.new\n    @popup[:squeeze] = TkVariable.new\n    @popup[:justify] = TkVariable.new\n\n    menuspec = [\n      [ 'Arrow', \n        [\n          [ 'None', [@popup[:arrow], 'none'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, :arrow=>:none)\n              }\n            } ],\n          [ 'Up', [@popup[:arrow], 'up'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, :arrow=>:up)\n              }\n            } ],\n          [ 'Down', [@popup[:arrow], 'down'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, :arrow=>:down)\n              }\n            } ],\n\n          '---', \n\n          [ 'Side Left', [@popup[:arrowside], 'left'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, \n                                        :arrowside=>:left)\n              }\n            } ],\n          [ 'Side Right', [@popup[:arrowside], 'right'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, \n                                        :arrowside=>:right)\n              }\n            } ],\n\n          '---', \n\n          [ 'Gravity Left', [@popup[:arrowgravity], 'left'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, \n                                        :arrowgravity=>:left)\n              }\n            } ],\n          [ 'Gravity Right', [@popup[:arrowgravity], 'right'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, \n                                        :arrowgravity=>:right)\n              }\n            } ],\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}} ], \n\n      [ 'Expand',  @popup[:expand],  nil, '', \n        {:command=>proc{\n            @tree2.column_configure(@popup[:column].value, \n                                    :expand=>@popup[:expand].value)\n          }\n        } ],\n\n      [ 'Squeeze', @popup[:squeeze], nil, '', \n        {:command=>proc{\n            @tree2.column_configure(@popup[:column].value, \n                                    :squeeze=>@popup[:squeeze].value)\n          }\n        } ],\n\n      [ 'Justify', \n        [\n          [ 'Left', [@popup[:justify], 'left'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, :justify=>:left)\n              }\n            } ],\n          [ 'Center', [@popup[:justify], 'center'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, \n                                        :justify=>:center)\n              }\n            } ],\n          [ 'Right', [@popup[:justify], 'right'], nil, '', \n            {:command=>proc{\n                @tree2.column_configure(@popup[:column].value, \n                                        :justify=>:right)\n              }\n            } ]\n        ], \n        nil, '', {:menu_config=>{:tearoff=>false}} ]\n    ]\n\n    m = TkMenu.new_menuspec(menuspec, @tree2, false)\n    @non_clear_list << m\n    @mHeader[@tree2] = m\n  end\n\n  ###########################\n\n  def init_demo_scripts_module\n    @demo_scripts = Module.new\n\n    master = self\n\n    has_bgimg = @has_bgimg\n\n    scriptDir = @ScriptDir\n\n    thisPlatform = @thisPlatform\n\n    randomN = @RandomN\n\n    images = @images\n    sel_images = @sel_images\n\n    systemButtonFace = @SystemButtonFace\n    systemHighlight  = @SystemHighlight\n    systemHighlightText = @SystemHighlightText\n\n    def master._pub_display_styles_in_item(item)\n      display_styles_in_item(item)\n    end\n    proc_disp_styles_in_item = proc{|item| \n      master._pub_display_styles_in_item(item)\n    }\n\n    @demo_scripts.instance_eval{\n      @master = master\n\n      @has_bgimg = has_bgimg\n\n      @display_styles_in_item = proc_disp_styles_in_item\n\n      @Priv = TkVarAccess.new('::TreeCtrl::Priv')\n\n      @ScriptDir = scriptDir\n\n      @thisPlatform = thisPlatform\n\n      @RandomN = randomN\n\n      @images = images\n      @sel_images = sel_images\n\n      @SystemButtonFace = systemButtonFace\n      @SystemHighlight  = systemHighlight\n      @SystemHighlightText = systemHighlightText\n    }\n\n    class << @demo_scripts\n      def _get_binding\n        binding\n      end\n      private :_get_binding\n\n      def load_demo(file)\n        puts \"load \\\"#{file}\\\"\" if $DEBUG\n        begin\n          eval(IO.readlines(file).join, _get_binding())\n        rescue Exception => e\n          bt = e.backtrace\n\n          if bt[0] =~ /^([^:]+):(\\d+):/\n            errline = $2.to_i\n          else\n            raise e\n          end\n\n          if bt[1] =~ /^([^:]+):(\\d+):/\n            bt.unshift(\"#{file}:#{errline - $2.to_i + 1}\")\n            raise e\n          else\n            raise e\n          end\n        end\n      end\n\n      def init_pics(*args)\n        @master.init_pics(*args)\n      end\n    end\n  end\n\n  def load_demo_scripts\n    # demo sources\n    [\n      'bitmaps',  \n      'explorer', \n      'help', \n      'imovie', \n      'layout', \n      'mailwasher', \n      'outlook-folders', \n      'outlook-newgroup', \n      'random', \n      'www-options'\n    ].each{|f|\n      @demo_scripts.load_demo(File.join(@ScriptDir, \"#{f}.rb\"))\n    }\n  end\n\n  ###########################\n\n  def init_demo_list\n    @tree1.element_create('e1', :text, \n                          :fill=>[@SystemHighlightText, ['selected', 'focus']])\n    @tree1.element_create('e2', :rect, :showfocus=>true, \n                          :fill=>[\n                            @SystemHighlight, ['selected', 'focus'], \n                            'gray', ['selected', '!focus'], \n                          ])\n    @tree1.style_create('s1')\n    @tree1.style_elements('s1', ['e2', 'e1'])\n\n    # Tk listbox has linespace + 1 height\n    @tree1.style_layout('s1', 'e2', :union=>['e1'], \n                        :ipadx=>2, :ipady=>[0, 1], :iexpand=>:e)\n\n    if $Version_1_1_OrLater\n      @tree1.defaultstyle = 's1'\n    end\n\n    ###\n    [\n      [\"Random #{@RandomN[0]} Items\", :demoRandom, 'random.rb'], \n      [\"Random #{@RandomN[0]} Items, Button Images\", :demoRandom2, 'random.rb'], \n      [\"Outlook Express (Folders)\", :demoOutlookFolders, 'outlook-folders.rb'],\n      [\"Outlook Express (Newsgroup)\", :demoOutlookNewsgroup, 'outlook-newgroup.rb'], \n      [\"Explorer (Details)\", :demoExplorerDetails, 'explorer.rb'], \n      [\"Explorer (List)\", :demoExplorerList, 'explorer.rb'], \n      [\"Explorer (Large icons)\", :demoExplorerLargeIcons, 'explorer.rb'], \n      [\"Explorer (Small icons)\", :demoExplorerSmallIcons, 'explorer.rb'], \n      [\"Internet Options\", :demoInternetOptions, 'www-options.rb'], \n      [\"Help Contents\", :demoHelpContents, 'help.rb'], \n      [\"Layout\", :demoLayout, 'layout.rb'], \n      [\"MailWasher\", :demoMailWasher, 'mailwasher.rb'], \n      [\"Bitmaps\", :demoBitmaps, 'bitmaps.rb'], \n      [\"iMovie\", :demoIMovie, 'imovie.rb']\n    ].each{|label, cmd, file|\n      item = @tree1.item_create\n      @tree1.item_lastchild(:root, item)\n      unless $Version_1_1_OrLater\n        @tree1.item_style_set(item, 0, 's1')\n      end\n      @tree1.item_text(item, 0, label)\n      @demoCmd[item] = cmd\n      @demoFile[item] = file\n    }\n\n    @tree1.yview_moveto(0.0)\n  end\n\n  def demo_set(cmd, file)\n    demo_clear()\n    clicks = Tk::Clock.clicks\n    @demo_scripts.__send__(cmd, @tree2)\n    clicks = Tk::Clock.clicks - clicks\n    puts \"set list in #{'%.2g'%(clicks/1000000.0)} seconds (#{clicks} clicks)\"\n    @tree2.xview_moveto(0)\n    @tree2.yview_moveto(0)\n    Tk.update\n    display_styles_in_list()\n    show_source(file)\n  end\n\n  def display_styles_in_list\n    # Create elements and styles the first time this is called\n    if @tree4.style_names.empty?\n      @tree4.element_create('e1', :text, \n                            :fill=>[@SystemHighlightText,['selected','focus']])\n      @tree4.element_create('e2', :text, \n                            :fill=>[\n                              @SystemHighlightText, ['selected','focus'], \n                              '', ['selected','!focus'], \n                              'blue', []\n                            ])\n      @tree4.element_create('e3', :rect, :showfocus=>true, \n                            :fill=>[\n                              @SystemHighlight, ['selected','focus'],\n                              'gray', ['selected', '!focus']\n                            ])\n\n      @tree4.style_create('s1')\n      @tree4.style_elements('s1', ['e3', 'e1'])\n      @tree4.style_layout('s1', 'e3', :union=>['e1'], :ipadx=>1, :ipady=>[0,1])\n\n      @tree4.style_create('s2')\n      @tree4.style_elements('s2', ['e3', 'e1', 'e2'])\n      @tree4.style_layout('s2', 'e1', :padx=>[0,4])\n      @tree4.style_layout('s2', 'e3', :union=>['e1', 'e2'], \n                          :ipadx=>1, :ipady=>[0,1])\n    end\n\n    # Clear the list\n    @tree4.item_delete(:all)\n    \n    # One item for each element in the demo list\n    @tree2.element_names.sort.each{|elem|\n      if $Version_1_1_OrLater\n        item = @tree4.item_create(:button=>true)\n        @tree4.item_collapse(item)\n      else\n        item = @tree4.item_create\n        @tree4.item_hasbutton(item, true)\n        @tree4.collapse(item)\n      end\n      @tree4.item_style_set(item, 0, 's1')\n      @tree4.item_text(item, 0, \n                       \"Element #{elem} (#{@tree2.element_type(elem)})\")\n\n      # One item for each configuration option for this element\n      @tree2.element_configinfo(elem).each{|name, x, y, default, current|\n        item2 = @tree4.item_create\n\n        if default == current\n          @tree4.item_style_set(item2, 0, 's1')\n          @tree4.item_complex(item2, [\n                                ['e1', {:text=>\"#{name} #{current.inspect}\"}]\n                              ])\n        else\n          @tree4.item_style_set(item2, 0, 's2')\n          @tree4.item_complex(item2, [\n                                ['e1', {:text=>name}], \n                                ['e2', {:text=>current.inspect}]\n                              ])\n        end\n\n        @tree4.item_lastchild(item, item2)\n      }\n\n      @tree4.item_lastchild(:root, item)\n    }\n\n    # One item for each style in the demo list\n    @tree2.style_names.sort.each{|sty|\n      if $Version_1_1_OrLater\n        item = @tree4.item_create(:button=>true)\n        @tree4.item_collapse(item)\n      else\n        item = @tree4.item_create\n        @tree4.item_hasbutton(item, true)\n        @tree4.collapse(item)\n      end\n      @tree4.item_style_set(item, 0, 's1')\n      @tree4.item_text(item, 0, \"Style #{sty}\")\n\n      # One item for each element in the style\n      @tree2.style_elements(sty).each{|elem|\n        if $Version_1_1_OrLater\n          item2 = @tree4.item_create(:button=>true)\n          @tree4.item_collapse(item2)\n        else\n          item2 = @tree4.item_create\n          @tree4.item_hasbutton(item2, true)\n          @tree4.collapse(item2)\n        end\n        @tree4.item_style_set(item2, 0, 's1')\n        @tree4.item_text(item2, 0, \n                         \"Element #{elem} (#{@tree2.element_type(elem)})\")\n\n        # One item for each layout option for this element in this style\n        @tree2.style_layout(sty, elem).each{|k, v|\n          item3 = @tree4.item_create\n          unless $Version_1_1_OrLater\n            @tree4.item_hasbutton(item3, false)\n          end\n          @tree4.item_style_set(item3, 0, 's1')\n          @tree4.item_text(item3, 0, \"#{k} #{v.inspect}\")\n          @tree4.item_lastchild(item2, item3)\n        }\n\n        @tree4.item_lastchild(item, item2)\n      }\n\n      @tree4.item_lastchild(:root, item)\n    }\n\n    @tree4.xview_moveto(0)\n    @tree4.yview_moveto(0)\n  end\n\n  def display_styles_in_item(item)\n    @tree3.column_configure(0, :text=>\"Styles in item #{@tree2.index(item)}\")\n\n    # Create elements and styles the first time this is called\n    if @tree3.style_names.empty?\n      @tree3.element_create('e1', :text, \n                            :fill=>[@SystemHighlightText,['selected','focus']])\n      @tree3.element_create('e2', :text, \n                            :fill=>[\n                              @SystemHighlightText, ['selected','focus'], \n                              '', ['selected','!focus'], \n                              'blue', []\n                            ])\n      @tree3.element_create('e3', :rect, :showfocus=>true, \n                            :fill=>[\n                              @SystemHighlight, ['selected','focus'],\n                              'gray', ['selected', '!focus']\n                            ])\n\n      @tree3.style_create('s1')\n      @tree3.style_elements('s1', ['e3', 'e1'])\n      @tree3.style_layout('s1', 'e3', :union=>['e1'], :ipadx=>1, :ipady=>[0,1])\n\n      @tree3.style_create('s2')\n      @tree3.style_elements('s2', ['e3', 'e1', 'e2'])\n      @tree3.style_layout('s2', 'e1', :padx=>[0,4])\n      @tree3.style_layout('s2', 'e3', :union=>['e1', 'e2'], \n                          :ipadx=>1, :ipady=>[0,1])\n    end\n    # Clear the list\n    @tree3.item_delete(:all)\n\n    # One item for each item-column\n    column = 0\n    @tree2.item_style_set(item).each{|sty|\n      item2 = @tree3.item_create\n      if $Version_1_1_OrLater\n        @tree3.item_collapse(item2)\n      else\n        @tree3.collapse(item2)\n      end\n      @tree3.item_style_set(item2, 0, 's1')\n      @tree3.item_element_configure(item2, 0, 'e1', \n                                    :text=>\"Column #{column}: Style #{sty}\")\n\n      button = false\n\n      # One item for each element in this style\n      unless sty.to_s.empty?\n        @tree2.item_style_elements(item, column).each{|elem|\n          button = true\n          if $Version_1_1_OrLater\n            item3 = @tree3.item_create(:button=>true)\n          else\n            item3 = @tree3.item_create\n            @tree3.item_hasbutton(item3, true)\n          end\n          if $Version_1_1_OrLater\n            @tree3.item_collapse(item3)\n          else\n            @tree3.collapse(item3)\n          end\n          @tree3.item_style_set(item3, 0, 's1')\n          @tree3.item_element_configure(item3, 0, 'e1', \n                                        :text=>\"Element #{elem} (#{@tree2.element_type(elem)})\")\n\n          # One item for each configuration option in this element\n          @tree2.item_element_configinfo(item, column, elem) \\\n          .each{|name, x, y, default, current|\n            item4 = @tree3.item_create\n            masterDefault = @tree2.element_cget(elem, name)\n            sameAsMaster = (masterDefault == current)\n            if !sameAsMaster && current == ''\n              sameAsMaster = true\n              current = masterDefault\n            end\n\n            if sameAsMaster\n              @tree3.item_style_set(item4, 0, 's1')\n              @tree3.item_complex(item4, [\n                                    ['e1', \n                                      {:text=>\"#{name} #{current.inspect}\"}]\n                                  ])\n            else\n              @tree3.item_style_set(item4, 0, 's2')\n              @tree3.item_complex(item4, [\n                                    ['e1', {:text=>name}], \n                                    ['e2', {:text=>current.inspect}]\n                                  ])\n            end\n            @tree3.item_lastchild(item3, item4)\n          }\n          @tree3.item_lastchild(item2, item3)\n        }\n        if $Version_1_1_OrLater\n          @tree3.item_configure(item2, :button=>true) if button\n        else\n          @tree3.item_hasbutton(item2, true) if button\n        end\n      end\n      @tree3.item_lastchild(:root, item2)\n      column += 1\n    }\n\n    @tree3.xview_moveto(0)\n    @tree3.yview_moveto(0)\n  end\n\n  def demo_clear\n    # Clear the demo list\n    @tree2.item_delete(:all)\n\n    # Clear all bindings on the demo list added by the previous demo.\n    # This is why DontDelete is used for the <Selection> binding.\n    @tree2.notify_bindinfo(@tree2).each{|ev|\n      @tree2.notify_bind_remove(@tree2, ev)\n    }\n\n    # Clear all run-time states\n    @tree2.state_names.each{|st| @tree2.state_undefine(st) }\n\n    # Clear the styles-in-item list\n    @tree3.item_delete(:all)\n\n    # Delete columns in demo list\n    while (@tree2.numcolumns > 0)\n      @tree2.column_delete(0)\n    end\n\n    # Delete all styles in demo list\n    @tree2.style_delete(*(@tree2.style_names))\n\n    # Delete all elements in demo list\n    @tree2.element_delete(*(@tree2.element_names))\n\n    if $Version_1_1_OrLater\n      @tree2.item_configure(:root, :button=>false)\n      @tree2.item_expand(:root)\n    else\n      @tree2.item_hasbutton(:root, false)\n      @tree2.expand(:root)\n    end\n\n    # Restore some happy defaults to the demo list\n    # if $Version_1_1_OrLater\n    if @has_bgimg\n      @tree2.configure(:orient=>:vertical, :wrap=>'', \n                       :xscrollincrement=>0, :yscrollincrement=>0, \n                       :itemheight=>0, :showheader=>true, \n                       :background=>'white', :scrollmargin=>0, \n                       :xscrolldelay=>50, :yscrolldelay=>50, \n                       :openbuttonimage=>'', :closedbuttonimage=>'', \n                       :backgroundmode=>:row, :treecolumn=>0, :indent=>19, \n                       :defaultstyle=>'', :backgroundimage=>'')\n    else\n      @tree2.configure(:orient=>:vertical, :wrap=>'', \n                       :xscrollincrement=>0, :yscrollincrement=>0, \n                       :itemheight=>0, :showheader=>true, \n                       :background=>'white', :scrollmargin=>0, \n                       :xscrolldelay=>50, :yscrolldelay=>50, \n                       :openbuttonimage=>'', :closedbuttonimage=>'', \n                       :backgroundmode=>:row, :treecolumn=>0, :indent=>19)\n    end\n\n    # Restore default bindings to the demo list\n    @tree2.bindtags = [ @tree2, Tk::TreeCtrl, @tree2.winfo_toplevel, :all ]\n\n    @tree2.winfo_children.each{|w| \n      w.destroy unless @non_clear_list.include?(w)\n    }\n  end\nend\n\nTkTreeCtrl_demo.new($ScriptDir)\n\n##############################################\n\ndef cursor_window(top = nil)\n  top.destroy if top.kind_of?(TkWindow) && top.winfo_exist?\n  top = TkToplevel.new(:title=>'Cursor Window')\n\n  c = TkCanvas.new(top, :background=>'white', \n                   :width=>50*10, :highlightthickness=>0, \n                   :borderwidth=>0).pack(:expand=>true, :fill=>:both)\n  cursors = %w(\n\tX_cursor\n\tarrow\n\tbased_arrow_down\n\tbased_arrow_up\n\tboat\n\tbogosity\n\tbottom_left_corner\n\tbottom_right_corner\n\tbottom_side\n\tbottom_tee\n\tbox_spiral\n\tcenter_ptr\n\tcircle\n\tclock\n\tcoffee_mug\n\tcross\n\tcross_reverse\n\tcrosshair\n\tdiamond_cross\n\tdot\n\tdotbox\n\tdouble_arrow\n\tdraft_large\n\tdraft_small\n\tdraped_box\n\texchange\n\tfleur\n\tgobbler\n\tgumby\n\thand1\n\thand2\n\theart\n\ticon\n\tiron_cross\n\tleft_ptr\n\tleft_side\n\tleft_tee\n\tleftbutton\n\tll_angle\n\tlr_angle\n\tman\n\tmiddlebutton\n\tmouse\n\tpencil\n\tpirate\n\tplus\n\tquestion_arrow\n\tright_ptr\n\tright_side\n\tright_tee\n\trightbutton\n\trtl_logo\n\tsailboat\n\tsb_down_arrow\n\tsb_h_double_arrow\n\tsb_left_arrow\n\tsb_right_arrow\n\tsb_up_arrow\n\tsb_v_double_arrow\n\tshuttle\n\tsizing\n\tspider\n\tspraycan\n\tstar\n\ttarget\n\ttcross\n\ttop_left_arrow\n\ttop_left_corner\n\ttop_right_corner\n\ttop_side\n\ttop_tee\n\ttrek\n\tul_angle\n\tumbrella\n\tur_angle\n\twatch\n\txterm\n    )\n\n  orig_cursor = c.cursor\n  col = 0\n  row = 0\n\n  cursors.each{|cur|\n    x = col * 50\n    y = row * 40\n\n    begin\n      c.cursor = cur\n\n      r = TkcRectangle.new(c, x, y, x+50, y+40, \n                           :fill=>'gray90', :outline=>'black', :width=>2)\n      t = TkcText.new(c, x+50/2, y+4, :text=>cur, :anchor=>:n, :width=>42)\n\n      col += 1\n      if col >= 10\n        col = 0\n        row += 1\n      end\n\n      r.bind('Enter', proc{c.cursor = cur; r.fill = 'linen'})\n      r.bind('Leave', proc{c.cursor = ''; r.fill = 'gray90'})\n\n      t.bind('Enter', proc{c.cursor = cur})\n      t.bind('Leave', proc{c.cursor = ''})\n    rescue\n      c.cursor = orig_cursor\n    end\n  }\n\n  c.cursor = orig_cursor\n  c.height = (row + 1) * 40\nend\n\ncursor_window()\n\n##############################################\n\n# A little screen magnifier for X11\nif Tk::PLATFORM['platform'] == 'unix' && Tk.windowingsystem != 'aqua'\n  def show_loupe(setting=nil)\n    loupe = (setting.kind_of?(Hash))? setting: {}\n    loupe[:zoom] = 3 unless loupe[:zoom]\n    loupe[:x] = 0 unless loupe[:x]\n    loupe[:y] = 0 unless loupe[:y]\n    loupe[:auto] = true unless loupe[:auto]\n    loupe[:delay] = 500 unless loupe[:delay]\n    loupe[:image] = \n      TkPhotoImage.new(:width=>150, :height=>150) unless loupe[:image]\n\n    top = TkToplevel.new(:geometry=>'-0+30', \n                         :title=>'A little screen magnifier for X11')\n    TkLabel.new(top, :image=>loupe[:image]).pack\n\n    TkTimer.new(proc{loupe[:delay]}, -1, proc{\n                  x, y = TkWinfo.pointerxy(Tk.root)\n                  if loupe[:auto] || loupe[:x] != x || loupe[:y] != y\n                    w = loupe[:image].width\n                    h = loupe[:image].height\n                    Tk::TreeCtrl.loupe(loupe[:image], x, y, w, h, loupe[:zoom])\n                    loupe[:x] = x\n                    loupe[:y] = y\n                  end\n                }).start\n  end\n\n  show_loupe()\nend\n\n##############################################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/explorer.rb",
    "content": "\ndef demoExplorerAux(t, dir_proc, file_proc)\n  base_dir = File.dirname(File.dirname(@ScriptDir))\n\n  clicks = Tk::Clock.clicks\n  globDirs = Dir.glob(File.join(base_dir, '*')).find_all{|file|\n    FileTest.directory?(file)\n  }\n  clickGlobDirs = Tk::Clock.clicks - clicks\n\n  clicks = Tk::Clock.clicks\n  list = globDirs.sort\n  clickSortDirs = Tk::Clock.clicks - clicks\n\n  clicks = Tk::Clock.clicks\n  list.each{|file| dir_proc.call(file)}\n  clickAddDirs = Tk::Clock.clicks - clicks\n\n  clicks = Tk::Clock.clicks\n  globFiles = Dir.glob(File.join(base_dir, '*')).find_all{|file|\n    FileTest.file?(file)\n  }\n  clickGlobFiles = Tk::Clock.clicks - clicks\n\n  clicks = Tk::Clock.clicks\n  list = globFiles.sort\n  clickSortFiles = Tk::Clock.clicks - clicks\n\n  clicks = Tk::Clock.clicks\n  list.each{|file| file_proc.call(file)}\n  clickAddFiles = Tk::Clock.clicks - clicks\n\n  gd = '%.2g' % (clickGlobDirs / 1000000.0)\n  sd = '%.2g' % (clickSortDirs / 1000000.0)\n  ad = '%.2g' % (clickAddDirs  / 1000000.0)\n  gf = '%.2g' % (clickGlobFiles / 1000000.0)\n  sf = '%.2g' % (clickSortFiles / 1000000.0)\n  af = '%.2g' % (clickAddFiles  / 1000000.0)\n\n  puts \"dirs(#{globDirs.length}) glob/sort/add #{gd}/#{sd}/#{ad}    files(#{globFiles.length}) glob/sort/add #{gf}/#{sf}/#{af}\"\n\n  @Priv[:DirCnt, t] = globDirs.length\nend\n\n#\n# Demo: explorer files\n#\ndef demoExplorerDetails(t)\n  height = t.font.metrics(:linespace)\n  height = 18 if height < 18\n\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :itemheight=>height, :selectmode=>:extended, \n              :xscrollincrement=>20, :scrollmargin=>16, \n              :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50])\n\n  init_pics('small-*')\n\n  if $HasColumnCreate\n    t.column_create(:text=>'Name', :tag=>'name', \n                    :width=>200, :arrow=>:up, :arrowpad=>6)\n    t.column_create(:text=>'Size', :tag=>'size', :justify=>:right, \n                    :width=>60, :arrowside=>:left, :arrowgravity=>:right)\n    t.column_create(:text=>'Type', :tag=>'type', :width=>120)\n    t.column_create(:text=>'Modified', :tag=>'modified', :width=>130)\n  else\n    t.column_configure(0, :text=>'Name', :tag=>'name', \n                       :width=>200, :arrow=>:up, :arrowpad=>6)\n    t.column_configure(1, :text=>'Size', :tag=>'size', :justify=>:right, \n                       :width=>60, :arrowside=>:left, :arrowgravity=>:right)\n    t.column_configure(2, :text=>'Type', :tag=>'type', :width=>120)\n    t.column_configure(3, :text=>'Modified', :tag=>'modified', :width=>130)\n  end\n\n  t.element_create('e1', :image, \n                   :image=>[\n                     @sel_images['small-folder'], ['selected'], \n                     @images['small-folder'], []\n                   ])\n  t.element_create('e2', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('txtType', :text, :lines=>1)\n  t.element_create('txtSize', :text, :lines=>1, \n                   :datatype=>:integer, :format=>'%dKB')\n  t.element_create('txtDate', :text, :lines=>1, \n                   :datatype=>:time, :format=>'%d/%m/%y %I:%M %p')\n  t.element_create('e4', :rect, :showfocus=>true,\n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray', ['selected', '!focus']\n                   ])\n\n  # image + text\n  s = t.style_create('styName', :orient=>:horizontal)\n  t.style_elements(s, ['e4', 'e1', 'e2'])\n  t.style_layout(s, 'e1', :expand=>:ns)\n  t.style_layout(s, 'e2', :padx=>[2,0], :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e2'], :iexpand=>:ns, :ipadx=>2)\n\n  # column 1: text\n  s = t.style_create('stySize')\n  t.style_elements(s, ['txtSize'])\n  t.style_layout(s, 'txtSize', :padx=>6, :squeeze=>:x, :expand=>:ns)\n\n  # column 2: text\n  s = t.style_create('styType')\n  t.style_elements(s, ['txtType'])\n  t.style_layout(s, 'txtType', :padx=>6, :squeeze=>:x, :expand=>:ns)\n\n  # column 3: text\n  s = t.style_create('styDate')\n  t.style_elements(s, ['txtDate'])\n  t.style_layout(s, 'txtDate', :padx=>6, :squeeze=>:x, :expand=>:ns)\n\n  @Priv[:edit, t] = ['e2']\n  @Priv[:sensitive, t] = [ ['name', 'styName', 'e1', 'e2'] ]\n  @Priv[:dragimage, t] = [ ['name', 'styName', 'e1', 'e2'] ]\n\n  t.notify_bind(t, 'Edit-accept', \n                proc{|w, i, tt| w.item_text(i, 0, tt)}, '%T %I %t')\n\n  dir_proc = proc{|file|\n    item = t.item_create\n    t.item_style_set(item, 0, 'styName', 2, 'styType', 3, 'styDate')\n    t.item_complex(item, \n                   [['e2', {:text=>File.basename(file)}]], \n                   [], \n                   [['txtType', {:text=>'Folder'}]], \n                   [['txtDate', {:data=>File.mtime(file).tv_sec}]])\n    t.item_lastchild(:root, item)\n  }\n\n  file_proc = proc{|file|\n    item = t.item_create\n    t.item_style_set(item, 0, 'styName', 1, 'stySize', \n                           2, 'styType', 3, 'styDate')\n\n    ext = File.extname(file)\n    case ext\n    when '.dll'\n      img = 'small-dll'\n    when '.exe'\n      img = 'small-exe'\n    when '.txt'\n      img = 'small-txt'\n    else\n      img = 'small-file'\n    end\n\n    type = ext.upcase\n    type = type[1..-1] << ' ' unless type.empty?\n    type << 'File'\n\n    t.item_complex(item, \n                   [ \n                     ['e1', {:image=>[@sel_images[img], ['selected'], \n                                      @images[img], []]}],\n                     ['e2', {:text=>File.basename(file)}]\n                   ], \n                   [ ['txtSize', {:data=>File.size(file)/1024 + 1}] ], \n                   [ ['txtType', {:text=>type}] ], \n                   [ ['txtDate', {:data=>File.mtime(file).tv_sec}] ]\n                   )\n    t.item_lastchild(:root, item)\n  }\n\n  demoExplorerAux(t, dir_proc, file_proc)\n\n  @SortColumn = 0\n  t.notify_bind(t, 'Header-invoke', \n                proc{|w, c| explorerHeaderInvoke(t, w, c)}, '%T %C')\n\n  t.bindtags = [ t, 'TreeCtrlFileList', Tk::TreeCtrl, t.winfo_toplevel, :all ]\nend\n\ndef explorerHeaderInvoke(t, w, c)\n  if (c == @SortColumn)\n    if t.column_cget(@SortColumn, :arrow) == 'down'\n      order = :increasing\n      arrow = :up\n    else\n      order = :decreasing\n      arrow = :down\n    end\n  else\n    if t.column_cget(@SortColumn, :arrow) == 'down'\n      order = :decreasing\n      arrow = :down\n    else\n      order = :increasing\n      arrow = :up\n    end\n    t.column_configure(@SortColumn, :arrow=>:none)\n    @SortColumn = c\n  end\n\n  t.column_configure(c, :arrow=>arrow)\n  dirCount = TkComm.number(@Priv[:DirCnt, t])\n  lastDir = dirCount - 1\n  case t.column_cget(c, :tag)\n  when 'name'\n    if dirCount > 0\n      t.item_sort(:root, order, {:last=>\"root child #{lastDir}\"}, \n                  {:column=>c, :dictionary=>true})\n    end\n    if dirCount < t.numitems - 1\n      t.item_sort(:root, order, {:first=>\"root child #{dirCount}\"}, \n                  {:column=>c, :dictionary=>true})\n    end\n\n  when 'size'\n    if dirCount < t.numitems - 1\n      t.item_sort(:root, order, {:first=>\"root child #{dirCount}\"}, \n                  {:column=>c, :integer=>true}, \n                  {:column=>'name', :dictionary=>true})\n    end\n\n  when 'type'\n    if dirCount < t.numitems - 1\n      t.item_sort(:root, order, {:first=>\"root child #{dirCount}\"}, \n                  {:column=>c, :dictionary=>true}, \n                  {:column=>'name', :dictionary=>true})\n    end\n\n  when 'modified'\n    if dirCount > 0\n      t.item_sort(:root, order, {:last=>\"root child #{lastDir}\"}, \n                  {:column=>c, :integer=>true}, \n                  {:column=>'name', :dictionary=>true})\n    end\n    if dirCount < t.numitems - 1\n      t.item_sort(:root, order, {:first=>\"root child #{dirCount}\"}, \n                  {:column=>c, :integer=>true}, \n                  {:column=>'name', :dictionary=>true})\n    end\n\n  end\nend\n\ndef demoExplorerLargeIcons(t)\n  # Item height is 32 for icon, 4 padding, 3 lines of text\n  itemHeight = 32 + 4 + t.font.metrics(:linespace) * 3\n\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :selectmode=>:extended, :wrap=>:window, :orient=>:horizontal, \n              :itemheight=>itemHeight, :showheader=>false, :scrollmargin=>16, \n              :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50])\n\n  init_pics('big-*')\n\n  if $HasColumnCreate\n    t.column_create(:width=>75)\n  else\n    t.column_configure(0, :width=>75)\n  end\n\n  t.element_create('elemImg', :image, \n                   :image=>[\n                     @sel_images['big-folder'], ['selected'], \n                     @images['big-folder'], []\n                   ])\n  t.element_create('elemTxt', :text, :justify=>:center, \n                   :lines=>1, :width=>71, :wrap=>:word, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('elemSel', :rect, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray', ['selected']\n                   ])\n\n  # image + text\n  s = t.style_create('STYLE', :orient=>:vertical)\n  t.style_elements(s, ['elemSel', 'elemImg', 'elemTxt'])\n  t.style_layout(s, 'elemImg', :expand=>:we)\n  t.style_layout(s, 'elemTxt', \n                 :pady=>[4,0], :padx=>2, :squeeze=>:x, :expand=>:we)\n  t.style_layout(s, 'elemSel', :union=>['elemTxt'])\n\n  @Priv[:edit, t] = ['elemTxt']\n  @Priv[:sensitive, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ]\n  @Priv[:dragimage, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ]\n\n  t.notify_bind(t, 'Edit-accept', \n                proc{|w, i, tt| w.item_text(i, 0, tt)}, '%T %I %t')\n\n  dir_proc = proc{|file|\n    item = t.item_create\n    t.item_style_set(item, 0, 'STYLE')\n    t.item_text(item, 0, File.basename(file))\n    t.item_lastchild(:root, item)\n  }\n\n  file_proc = proc{|file|\n    item = t.item_create\n    t.item_style_set(item, 0, 'STYLE')\n\n    ext = File.extname(file)\n    case ext\n    when '.dll'\n      img = 'big-dll'\n    when '.exe'\n      img = 'big-exe'\n    when '.txt'\n      img = 'big-txt'\n    else\n      img = 'big-file'\n    end\n\n    type = ext.upcase\n    type = type[1..-1] << ' ' unless type.empty?\n    type << 'File'\n\n    t.item_complex(item, \n                   [ \n                     ['elemImg', {:image=>[@sel_images[img], ['selected'], \n                                           @images[img], []]}],\n                     ['elemTxt', {:text=>File.basename(file)}]\n                   ])\n    t.item_lastchild(:root, item)\n  }\n\n  demoExplorerAux(t, dir_proc, file_proc)\n\n  t.activate(t.index('root firstchild'))\n\n  t.notify_bind(t, 'ActiveItem', \n                proc{|w, a, c|\n                  w.item_element_configure(a, 0, 'elemTxt', :lines=>'')\n                  w.item_element_configure(c, 0, 'elemTxt', :lines=>3)\n                }, '%T %p %c')\n\n  t.bindtags = [ t, 'TreeCtrlFileList', Tk::TreeCtrl, t.winfo_toplevel, :all ]\nend\n\n# Tree is horizontal, wrapping occurs at right edge of window, each item\n# is as wide as the smallest needed multiple of 110 pixels\ndef demoExplorerSmallIcons(t)\n  demoExplorerList(t)\n  t.configure(:orient=>:horizontal, :xscrollincrement=>0)\n  t.column_configure(0, :width=>'', :stepwidth=>110, :widthhack=>false)\nend\n\n# Tree is vertical, wrapping occurs at bottom of window, each range has the\n# same width (as wide as the longest item), xscrollincrement is by range\ndef demoExplorerList(t)\n  height = t.font.metrics(:linespace) + 2\n  height = 18 if height < 18\n\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :itemheight=>height, :selectmode=>:extended, :wrap=>:window, \n              :showheader=>false, :scrollmargin=>16, \n              :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50])\n\n  init_pics('small-*')\n\n  if $HasColumnCreate\n    t.column_create(:widthhack=>true)\n  else\n    t.column_configure(0, :widthhack=>true)\n  end\n\n  t.element_create('elemImg', :image, \n                   :image=>[\n                     @sel_images['small-folder'], ['selected'], \n                     @images['small-folder'], []\n                   ])\n  t.element_create('elemTxt', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('elemSel', :rect, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray', ['selected', '!focus']\n                   ])\n\n  # image + text\n  s = t.style_create('STYLE')\n  t.style_elements(s, ['elemSel', 'elemImg', 'elemTxt'])\n  t.style_layout(s, 'elemImg', :expand=>:ns)\n  t.style_layout(s, 'elemTxt', :squeeze=>:x, :expand=>:ns, :padx=>[2,0])\n  t.style_layout(s, 'elemSel', :union=>['elemTxt'], :iexpand=>:ns, :ipadx=>2)\n\n  @Priv[:edit, t] = ['elemTxt']\n  @Priv[:sensitive, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ]\n  @Priv[:dragimage, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ]\n\n  t.notify_bind(t, 'Edit-accept', \n                proc{|w, i, tt| w.item_text(i, 0, tt)}, '%T %I %t')\n\n  dir_proc = proc{|file|\n    item = t.item_create\n    t.item_style_set(item, 0, 'STYLE')\n    t.item_text(item, 0, File.basename(file))\n    t.item_lastchild(:root, item)\n  }\n\n  file_proc = proc{|file|\n    item = t.item_create\n    t.item_style_set(item, 0, 'STYLE')\n\n    ext = File.extname(file)\n    case ext\n    when '.dll'\n      img = 'small-dll'\n    when '.exe'\n      img = 'small-exe'\n    when '.txt'\n      img = 'small-txt'\n    else\n      img = 'small-file'\n    end\n\n    type = ext.upcase\n    type = type[1..-1] << ' ' unless type.empty?\n    type << 'File'\n\n    t.item_complex(item, \n                   [ \n                     ['elemImg', {:image=>[@sel_images[img], ['selected'], \n                                           @images[img], []]}],\n                     ['elemTxt', {:text=>File.basename(file)}]\n                   ])\n    t.item_lastchild(:root, item)\n  }\n\n  demoExplorerAux(t, dir_proc, file_proc)\n\n  t.activate(t.item_firstchild(:root))\n\n  t.bindtags = [ t, 'TreeCtrlFileList', Tk::TreeCtrl, t.winfo_toplevel, :all ]\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/help.rb",
    "content": "#\n# Demo: Help contents\n#\ndef demoHelpContents(t)\n  height = t.font.metrics(:linespace)\n  height = 18 if height < 18\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :itemheight=>height, :selectmode=>:browse)\n\n  init_pics('help-*')\n\n  if $Version_1_1_OrLater\n    t.column_create(:text=>'Help Contents')\n  else # TreeCtrl 1.0\n    t.column_configure(0, :text=>'Help Contents')\n  end\n\n  # Define a new item state\n  t.state_define('mouseover')\n\n  t.element_create('e1', :image, :image=>@images['help-page'])\n  t.element_create('e2', :image, :image=>[\n                     @images['help-book-open'], ['open'], \n                     @images['help-book-closed'], [], \n                   ])\n  t.element_create('e3', :text, \n                   :font=>[t.font.dup.underline(true), ['mouseover']], \n                   :fill=>[\n                     @SystemHighlightText, ['selected', 'focus'], \n                     'blue', ['mouseover']\n                   ])\n  t.element_create('e4', :rect, :showfocus=>true, \n                   :fill=>[@SystemHighlight, ['selected', 'focus']])\n\n  # book\n  s = t.style_create('s1')\n  t.style_elements(s, ['e4', 'e1', 'e3'])\n  t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e3', :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  # page\n  s = t.style_create('s2')\n  t.style_elements(s, ['e4', 'e2', 'e3'])\n  t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e3', :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  parentList = [:root, '', '', '', '', '', '']\n  parent = :root\n  [\n     [0, 's1', \"Welcome to Help\"], \n     [0, 's2', \"Introducing Windows 98\"], \n        [1, 's2', \"How to Use Help\"], \n           [2, 's1', \"Find a topic\"], \n           [2, 's1', \"Get more out of help\"],\n        [1, 's2', \"Register Your Software\"],\n           [2, 's1', \"Registering Windows 98 online\"], \n        [1, 's2', \"What's New in Windows 98\"], \n           [2, 's1', \"Innovative, easy-to-use features\"], \n           [2, 's1', \"Improved reliability\"], \n           [2, 's1', \"A faster operating system\"], \n           [2, 's1', \"True Web integration\"], \n           [2, 's1', \"More entertaining and fun\"], \n        [1, 's2', \"If You're New to Windows 98\"], \n           [2, 's2', \"Tips for Macintosh Users\"], \n              [3, 's1', \"Why does the mouse have two buttons?\"]\n  ].each{|depth, style, text|\n    item = t.item_create\n    t.item_style_set(item, 0, style)\n    t.item_element_configure(item, 0, 'e3', :text=>text)\n    if $Version_1_1_OrLater\n      t.item_collapse(item)\n    else # TreeCtrl 1.0\n      t.collapse(item)\n    end\n    t.item_lastchild(parentList[depth], item)\n    depth += 1\n    parentList[depth] = item\n  }\n\n  treeCtrlHelp = TkBindTag.new\n\n  treeCtrlHelp.bind('Double-ButtonPress-1', \n                    proc{|w, x, y|\n                      if w.identify(x, y)[0] == 'header'\n                        Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y)\n                      else\n                        helpButton1(w, x, y)\n                      end\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('ButtonPress-1', \n                    proc{|w, x, y|\n                      helpButton1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('Button1-Motion', \n                    proc{|w, x, y|\n                      helpMotion1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('Button1-Leave', \n                    proc{|w, x, y|\n                      helpLeave1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('ButtonRelease-1', \n                    proc{|w, x, y|\n                      helpRelease1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('Motion', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y')\n\n  treeCtrlHelp.bind('Leave', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y')\n\n  treeCtrlHelp.bind('KeyPress-Return', \n                    proc{|w, x, y|\n                      if w.selection_get.length == 1\n                        if $Version_1_1_OrLater\n                          w.item_toggle(w.selection_get[0])\n                        else # TreeCtrl 1.0\n                          w.toggle(w.selection_get[0])\n                        end\n                      end\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  @Priv[:help, :prev] = ''\n\n  t.bindtags = [ t, treeCtrlHelp, Tk::TreeCtrl, t.winfo_toplevel, :all ]\nend\n\n# This is an alternate implementation that does not define a new item state\n# to change the appearance of the item under the cursor.\ndef demoHelpContents2(t)\n  height = t.font.metrics(:linespace)\n  height = 18 if height < 18\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :itemheight=>height, :selectmode=>:browse)\n\n  init_pics('help-*')\n\n  if $Version_1_1_OrLater\n    t.column_create(:text=>'Help Contents')\n  else # TreeCtrl 1.0\n    t.column_configure(0, :text=>'Help Contents')\n  end\n\n  t.element_create('e1', :image, :image=>@images['help-page'])\n  t.element_create('e2', :image, :image=>[\n                     @images['help-book-open'], ['open'], \n                     @images['help-book-closed'], [], \n                   ])\n  t.element_create('e3', :text, \n                   :fill=>[\n                     @SystemHighlightText, ['selected', 'focus'], \n                     'blue', []\n                   ])\n  t.element_create('e4', :rect, :showfocus=>true, \n                   :fill=>[@SystemHighligh, ['selected', 'focus']])\n  t.element_create('e5', :text, :font=>t.font.dup.underline(true), \n                   :fill=>[\n                     @SystemHighlightText, ['selected', 'focus'], \n                     'blue', []\n                   ])\n\n  # book\n  s = t.style_create('s1')\n  t.style_elements(s, ['e4', 'e1', 'e3'])\n  t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e3', :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  # page\n  s = t.style_create('s2')\n  t.style_elements(s, ['e4', 'e2', 'e3'])\n  t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e3', :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  # book (focus)\n  s = t.style_create('s1.f')\n  t.style_elements(s, ['e4', 'e1', 'e5'])\n  t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e5', :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e5'], :iexpand=>:ns, :ipadx=>2)\n\n  # page (focus)\n  s = t.style_create('s2')\n  t.style_elements(s, ['e4', 'e2', 'e5'])\n  t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e5', :expand=>:ns)\n  t.style_layout(s, 'e4', :union=>['e5'], :iexpand=>:ns, :ipadx=>2)\n\n  parentList = [:root, '', '', '', '', '', '']\n  parent = :root\n  [\n     [0, 's1', \"Welcome to Help\"], \n     [0, 's2', \"Introducing Windows 98\"], \n        [1, 's2', \"How to Use Help\"], \n           [2, 's1' \"Find a topic\"], \n           [2, 's1', \"Get more out of help\"],\n        [1, 's2', \"Register Your Software\"],\n           [2, 's1', \"Registering Windows 98 online\"], \n        [1, 's2', \"What's New in Windows 98\"], \n           [2, 's1', \"Innovative, easy-to-use features\"], \n           [2, 's1', \"Improved reliability\"], \n           [2, 's1', \"A faster operating system\"], \n           [2, 's1', \"True Web integration\"], \n           [2, 's1', \"More entertaining and fun\"], \n        [1, 's2', \"If You're New to Windows 98\"], \n           [2, 's2', \"Tips for Macintosh Users\"], \n              [3, 's1', \"Why does the mouse have two buttons?\"]\n  ].each{|depth, style, text|\n    item = t.item_create\n    t.item_style_set(item, 0, style)\n    t.item_element_configure(item, 0, 'e3', :text=>text)\n    if $Version_1_1_OrLater\n      t.item_collapse(item)\n    else # TreeCtrl 1.0\n      t.collapse(item)\n    end\n    t.item_lastchild(parentList[depth], item)\n    depth += 1\n    parentList[depth] = item\n  }\n\n  treeCtrlHelp = TkBindTag.new\n\n  treeCtrlHelp.bind('Double-ButtonPress-1', \n                    proc{|w, x, y|\n                      if w.identify(x, y)[0] == 'header'\n                        Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y)\n                      else\n                        helpButton1(w, x, y)\n                      end\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('ButtonPress-1', \n                    proc{|w, x, y|\n                      helpButton1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('Button1-Motion', \n                    proc{|w, x, y|\n                      helpMotion1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('Button1-Leave', \n                    proc{|w, x, y|\n                      helpLeave1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('ButtonRelease-1', \n                    proc{|w, x, y|\n                      helpRelease1(w, x, y)\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  treeCtrlHelp.bind('Motion', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y')\n\n  treeCtrlHelp.bind('Leave', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y')\n\n  treeCtrlHelp.bind('KeyPress-Return', \n                    proc{|w, x, y|\n                      if w.selection_get.length == 1\n                        w.item_toggle(w.selection_get[0])\n                      end\n                      Tk.callback_break\n                    }, '%W %x %y')\n\n  @Priv[:help, :prev] = ''\n\n  t.bindtags = [ t, treeCtrlHelp, Tk::TreeCtrl, t.winfo_toplevel, :all ]\nend\n\ndef helpButton1(w, x, y)\n  w.set_focus\n  id = w.identify(x, y)\n  @Priv['buttonMode'] = ''\n  if id[0] == 'header'\n    Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y)\n  elsif id[0] == 'item'\n    item = id[1]\n    # didn't click an element\n    return if id.length != 6\n    if w.selection_includes(item)\n      w.toggle(item)\n      return\n    end\n    if w.selection_get.length > 0\n      item2 = w.selection_get[0]\n      if $Version_1_1_OrLater\n        w.item_collapse(item2)\n      else # TreeCtrl 1.0\n        w.collapse(item2)\n      end\n      w.item_ancestors(item2).each{|i|\n        if $Version_1_1_OrLater\n          w.item_collapse(i) if w.compare(item, '!=', i)\n        else # TreeCtrl 1.0\n          w.collapse(i) if w.compare(item, '!=', i)\n        end\n      }\n    end\n    w.activate(item)\n    if $Version_1_1_OrLater\n      w.item_ancestors(item).each{|i|\n        w.item_expand(i)\n      }\n      w.item_toggle(item)\n    else # TreeCtrl 1.0\n      w.expand(*(w.item_ancestors(item)))\n      w.toggle(item)\n    end\n    w.selection_modify(item, :all)\n  end\nend\n\ndef helpMotion1(w, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.motion1(w, x, y)\n  end\nend\n\ndef helpLeave1(w, x, y)\n  # This is called when I do ButtonPress-1 on Unix for some reason,\n  # and buttonMode is undefined.\n  return unless @Priv.exist?('buttonMode')\n  case @Priv['buttonMode']\n  when 'header'\n    w.column_configure(@Priv['column'], :sunken=>false)\n  end\nend\n\ndef helpRelease1(w, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.release1(w, x, y)\n  end\n  @Priv['buttonMode'] = ''\nend\n\ndef helpMotion(w, x, y)\n  id = w.identify(x, y)\n  if id.empty?\n  elsif id[0] == 'header'\n  elsif id[0] == 'item'\n    item = id[1]\n    if id.length == 6\n      if @Priv[:help, :prev] != TkComm._get_eval_string(item)\n        if @Priv[:help, :prev] != ''\n          w.item_state_set(@Priv[:help, :prev], '!mouseover')\n        end\n        w.item_state_set(item, 'mouseover')\n        @Priv[:help, :prev] = item\n      end\n      return\n    end\n  end\n  if @Priv[:help, :prev] != ''\n    w.item_state_set(@Priv[:help, :prev], '!mouseover')\n    @Priv[:help, :prev] = ''\n  end\nend\n\n# Alternate implementation doesn't rely on mouseover state\ndef helpMotion2(w, x, y)\n  id = w.identify(x, y)\n  if id[0] == 'header'\n  elsif !id.empty?\n    item = id[1]\n    if id.kength == 6\n      if @Priv[:help, :prev] != TkComm._get_eval_string(item)\n        if @Priv[:help, :prev] != ''\n          style = w.item_style_set(@Priv[:help, :prev], 0)\n          style.sub!(/\\.f$/, '')\n          w.item_style_map(@Priv[:help, :prev], 0, style, ['e5', 'e3'])\n        end\n        style = w.item_style_set(item, 0)\n        w.item_style_map(item, 0, style + '.f', ['e3', 'e5'])\n        @Priv[:help, :prev] = item\n      end\n      return\n    end\n  end\n  if @Priv[:help, :prev] != ''\n    style = w.item_style_set(@Priv[:help, :prev], 0)\n    style.sub!(/\\.f$/, '')\n    w.item_style_map(@Priv[:help, :prev], 0, style, ['e5', 'e3'])\n    @Priv[:help, :prev] = ''\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/imovie.rb",
    "content": "#\n# Demo: iMovie\n#\ndef demoIMovie(t)\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :selectmode=>:browse, :orient=>:horizontal, :wrap=>:window, \n              :showheader=>false, :background=>'#dcdcdc')\n\n  if $HasColumnCreate\n    t.column_create\n  end\n\n  init_pics('imovie-*')\n\n  case @thisPlatform\n  when 'macintosh', 'macosx'\n    font1 = TkFont.new(['Geneva', 9])\n    font2 = TkFont.new(['Geneva', 10])\n  when 'unix'\n    font1 = TkFont.new(['Helvetica', -12])\n    font2 = TkFont.new(['Helvetica', -14])\n  else\n    font1 = TkFont.new(['Helvetica', 8])\n    font2 = TkFont.new(['Helvetica', 10])\n  end\n\n  t.element_create('elemTime', :text, :font=>font1)\n  t.element_create('elemName', :text, :font=>font2, :lines=>1, :width=>80)\n  t.element_create('elemRect', :rect, :outline=>'#827878', :outlinewidth=>1, \n                   :fill=>['#ffdc5a', ['selected'], 'white', []])\n  t.element_create('elemImg', :image)\n  t.element_create('elemShadow', :rect, :outline=>'gray', :outlinewidth=>1, \n                   :open=>:wn)\n\n  s = t.style_create('STYLE', :orient=>:vertical)\n  t.style_elements(s, [\n                     'elemShadow', 'elemRect', 'elemTime', \n                     'elemImg', 'elemName'\n                   ])\n  t.style_layout(s, 'elemShadow', :detach=>true, \n                 :padx=>[1,2], :pady=>[1,2], :iexpand=>:es)\n  t.style_layout(s, 'elemTime', :padx=>[2,0])\n  t.style_layout(s, 'elemImg', :pady=>[0,1])\n  t.style_layout(s, 'elemName', :expand=>:we, :ipady=>[0,2], :padx=>[0,3], \n                 :squeeze=>:x)\n  t.style_layout(s, 'elemRect', :union=>['elemTime', 'elemImg', 'elemName'], \n                 :ipadx=>6, :padx=>[0,3], :pady=>[0,3])\n\n  # Set default item style\n  if $Version_1_1_OrLater\n    t.defaultstyle([s])\n  end\n\n  (0..4).each{|i|\n    [\n      ['15:20', 'Clip 1', @images['imovie-01']], \n      ['19:18', 'Clip 2', @images['imovie-02']], \n      ['07:20', 'Clip 3', @images['imovie-03']], \n      ['07:20', 'Clip 4', @images['imovie-04']], \n      ['07:20', 'Clip 5', @images['imovie-05']], \n      ['07:20', 'Clip 6', @images['imovie-06']], \n      ['07:20', 'Clip 7', @images['imovie-07']]\n    ].each{|time, name, image|\n      item = t.item_create\n      unless $Version_1_1_OrLater\n        t.item_style_set(item, 0, s)\n      end\n      t.item_element_configure(item, 0, 'elemTime', :text=>time)\n      t.item_element_configure(item, 0, 'elemName', :text=>name)\n      t.item_element_configure(item, 0, 'elemImg', :image=>image)\n      t.item_lastchild(:root, item)\n    }\n  }\n\n  t.notify_bind(t, 'Edit-accept', proc{|w, i, c, e, tt|\n                  w.item_element_configure(i, c, e, :text=>tt)\n                }, '%T %I %C %E %t')\n\n  iMovie = TkBindTag.new\n  iMovie.bind('ButtonPress-1', proc{|w, x, y|\n                iMovieButton1(w, x, y)\n              }, '%W %x %y')\n\n  t.bindtags = [t, iMovie, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL]\nend\n\ndef iMovieButton1(w, x, y)\n  w.set_focus\n  id = w.identify(x,y)\n\n  if id.empty?\n    # Click outside any item\n\n  elsif id[0] == 'header'\n    # Click in header\n    Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y)\n\n  elsif id[0] == 'item'\n    # Click in item\n    Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y)\n    Tk.update\n    where, item, arg1, arg2, arg3, arg4 = id\n    case arg1\n    when 'column'\n      i = id[1]\n      if id.length == 6\n        e = id[-1]\n        if e == 'elemName'\n          exists = TkWinfo.exist?(w.path + '.entry')\n          Tk::TreeCtrl::BindCallback.entryOpen(w, i, 0, e)\n          ent = TkComm.window(w.path + '.entry')\n          unless exists\n            ent.configure(:borderwidth=>0, :justify=>:center, \n                          :background=>'#ffdc5a')\n            x1, y1, x2, y2 = w.item_bbox(i, 0, e)\n            ent.place(:y=>y1 - 1)\n          end\n          ent.selection_clear\n          x1, y1, x2, y2 = w.item_bbox(i)\n          ent.place(:x=>x1 + 1, :width=>x2 - x1 - 5)\n          puts \"@#{x - (x1 + 1)}\"\n          # ent.icursor = ent.index(\"@#{x - (x1 + 1)}\")\n          ent.icursor = ent.index(TkComm._at(x - (x1 + 1)))\n        end\n      end\n    end\n  end\n\n  Tk.callback_break\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/layout.rb",
    "content": "#\n# Demo: Layout\n#\ndef demoLayout(t)\n  t.configure(:showroot=>false, :showrootbutton=>true, :showbuttons=>true, \n              :showlines=>true, :itemheight=>0, :selectmode=>:browse)\n\n  if $HasColumnCreate\n    t.column_create(:text=>'Layout')\n  else\n    t.column_configure(0, :text=>'Layout')\n  end\n\n  t.element_create('e1', :rect, :width=>30, :height=>30, :fill=>'gray20')\n  t.element_create('e2', :rect, :width=>30, :height=>30, :fill=>'gray40', \n                   :outline=>'blue', :outlinewidth=>3)\n  t.element_create('e3', :rect, :fill=>'gray60')\n  t.element_create('e4', :rect, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], 'gray80', []\n                   ])\n  t.element_create('e5', :rect, :fill=>'{sky blue}', :width=>20, :height=>20)\n  t.element_create('e6', :rect, :fill=>'{sea green}', :width=>30, :height=>16)\n  t.element_create('e7', :rect, :fill=>'{sky blue}', :width=>30, :height=>16)\n  t.element_create('e8', :rect, :fill=>'gray70', :height=>1)\n\n  s = t.style_create('s1')\n  t.style_elements(s, ['e4', 'e3', 'e1', 'e2', 'e5', 'e6', 'e7'])\n  t.style_layout(s, 'e1', :padx=>[28, 4], :pady=>4)\n  t.style_layout(s, 'e2', :expand=>:es, :padx=>[0, 38])\n  t.style_layout(s, 'e3', :union=>['e1', 'e2'], :ipadx=>4, :ipady=>4, :pady=>2)\n  t.style_layout(s, 'e4', :detach=>true, :iexpand=>:es)\n  t.style_layout(s, 'e5', :detach=>true, :padx=>[2,0], :pady=>2, :iexpand=>:s)\n  t.style_layout(s, 'e6', :detach=>true, :expand=>:ws, \n                 :padx=>[0,2], :pady=>[2,0])\n  t.style_layout(s, 'e7', :detach=>true, :expand=>:wn, \n                 :padx=>[0,2], :pady=>[0,2])\n\n  if $Version_1_1_OrLater\n    i = t.item_create(:button=>true)\n  else\n    i = t.item_create\n    t.item_hasbutton(i, true)\n  end\n  t.item_style_set(i, 0, s)\n  t.item_lastchild(:root, i)\n  parent = i\n\n  i = t.item_create()\n  unless $Version_1_1_OrLater\n    t.item_hasbutton(i, false)\n  end\n  t.item_style_set(i, 0, s)\n  t.item_lastchild(parent, i)\n\n  ### \n\n  s = t.style_create('s2')\n  t.style_elements(s, ['e4', 'e3', 'e1'])\n  t.style_layout(s, 'e1', :padx=>8, :pady=>8, :iexpand=>:e)\n  t.style_layout(s, 'e3', :union=>['e1'], :ipadx=>[20,4], :ipady=>[4,12])\n  t.style_layout(s, 'e4', :detach=>true, :iexpand=>:es)\n\n  if $Version_1_1_OrLater\n    i = t.item_create(:button=>true)\n  else\n    i = t.item_create\n    t.item_hasbutton(i, true)\n  end\n  t.item_style_set(i, 0, s)\n  t.item_lastchild(:root, i)\n\n  i2 = t.item_create()\n  unless $Version_1_1_OrLater\n    t.item_hasbutton(i2, false)\n  end\n  t.item_style_set(i2, 0, s)\n  t.item_lastchild(i, i2)\n\n  ### \n\n  s = t.style_create('s3')\n  t.style_elements(s, ['e4', 'e3', 'e1', 'e5', 'e6'])\n  t.style_layout(s, 'e4', :union=>['e1', 'e6'], :ipadx=>8, :ipady=>[8,0])\n  t.style_layout(s, 'e3', :union=>['e1', 'e5'], :ipadx=>4, :ipady=>4)\n  t.style_layout(s, 'e5', :ipady=>[0,20])\n\n  if $Version_1_1_OrLater\n    i = t.item_create(:button=>true)\n  else\n    i = t.item_create\n    t.item_hasbutton(i, true)\n  end\n  t.item_style_set(i, 0, s)\n  t.item_lastchild(:root, i)\n\n  i2 = t.item_create()\n  unless $Version_1_1_OrLater\n    t.item_hasbutton(i2, false)\n  end\n  t.item_style_set(i2, 0, s)\n  t.item_lastchild(i, i2)\n\n  ### \n\n  t.element_create('eb', :border, :background=>@SystemButtonFace, \n                   :relief=>[:sunken, ['selected'], :raised, []], \n                   :thickness=>2, :filled=>true)\n  t.element_create('et', :text)\n\n  text = \"Here is a text element surrounded by a border element.\\nResize the column to watch me wrap.\"\n\n  s = t.style_create('e4')\n  t.style_elements(s, ['eb', 'et'])\n  t.style_layout(s, 'eb', :union=>['et'], :ipadx=>2, :ipady=>2)\n  t.style_layout(s, 'et', :squeeze=>:x)\n\n  if $Version_1_1_OrLater\n    i = t.item_create(:button=>true)\n  else\n    i = t.item_create\n    t.item_hasbutton(i, true)\n  end\n  t.item_style_set(i, 0, s)\n  t.item_text(i, 0, text)\n  t.item_lastchild(:root, i)\n  parent = i\n\n  i = t.item_create()\n  unless $Version_1_1_OrLater\n    t.item_hasbutton(i, false)\n  end\n  t.item_style_set(i, 0, s)\n  t.item_text(i, 0, text)\n  t.item_lastchild(parent, i)\n\n  ### \n\n  styleNum = 5\n  [ \n    [:horizontal, [:s, :ns, :n]], \n    [:vertical,   [:e, :we, :w]]\n  ].each{|orient, expandList|\n    expandList.each{|expand|\n      s = t.style_create(\"s#{styleNum}\", :orient=>orient)\n      t.style_elements(s, ['e4', 'e8', 'e2', 'e5', 'e6'])\n      t.style_layout(s, 'e4', :detach=>true, :iexpand=>:es)\n      t.style_layout(s, 'e8', :detach=>true, :expand=>:n, :iexpand=>:e)\n      t.style_layout(s, 'e2', :expand=>expand)\n      t.style_layout(s, 'e5', :expand=>expand)\n      t.style_layout(s, 'e6', :expand=>expand)\n      styleNum += 1\n\n      i = t.item_create()\n      t.item_style_set(i, 0, s)\n      t.item_lastchild(:root, i)\n    }\n  }\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/mailwasher.rb",
    "content": "#\n# Demo: MailWasher\n#\ndef demoMailWasher(t)\n  init_pics('*checked')\n\n  height = t.font.metrics(:linespace) + 2\n  height = 18 if height < 18\n\n  t.configure(:showroot=>false, :showrootbutton=>false, :showbuttons=>false, \n              :showlines=>false, :itemheight=>height, :selectmode=>:browse, \n              :xscrollincrement=>1)\n\n  pad = 4\n\n  if $Version_1_1_OrLater\n    t.column_create(:text=>'Delete', :textpadx=>pad, :tag=>'delete')\n    t.column_create(:text=>'Bounce', :textpadx=>pad, :tag=>'bounce')\n    t.column_create(:text=>'Status', :width=>80, :textpadx=>pad, \n                    :tag=>'status')\n    t.column_create(:text=>'Size', :width=>40, :textpadx=>pad, \n                    :justify=>:right, :tag=>'size')\n    t.column_create(:text=>'From', :width=>140, :textpadx=>pad, :tag=>'from')\n    t.column_create(:text=>'Subject', :width=>240, :textpadx=>pad, \n                    :tag=>'subject')\n    t.column_create(:text=>'Received', :textpadx=>pad, :arrow=>:up, \n                    :arrowpad=>[4,0], :tag=>'received')\n    t.column_create(:text=>'Attachments', :textpadx=>pad, :tag=>'attachments')\n\n    t.state_define('CHECK')\n\n    t.element_create('imgCheck', :image, :image=>[\n                       @images['checked'], ['CHECK'], @images['unchecked'], []\n                     ])\n\n  else # TreeCtrl 1.0\n    t.column_configure(0, :text=>'Delete', :textpadx=>pad, :tag=>'delete')\n    t.column_configure(1, :text=>'Bounce', :textpadx=>pad, :tag=>'bounce')\n    t.column_configure(2, :text=>'Status', :width=>80, :textpadx=>pad, \n                       :tag=>'status')\n    t.column_configure(3, :text=>'Size', :width=>40, :textpadx=>pad, \n                       :justify=>:right, :tag=>'size')\n    t.column_configure(4, :text=>'From', :width=>140, :textpadx=>pad, \n                       :tag=>'from')\n    t.column_configure(5, :text=>'Subject', :width=>240, :textpadx=>pad, \n                       :tag=>'subject')\n    t.column_configure(6, :text=>'Received', :textpadx=>pad, :arrow=>:up, \n                       :arrowpad=>[4,0], :tag=>'received')\n    t.column_configure(7, :text=>'Attachments', :textpadx=>pad, \n                       :tag=>'attachments')\n\n    t.element_create('imgOff', :image, :image=>@images['unchecked'])\n    t.element_create('imgOn', :image, :image=>@images['checked'])\n  end\n\n  t.element_create('border', :rect, :open=>:nw, :outline=>'gray', \n                   :outlinewidth=>1, :fill=>[@SystemHighlight, ['selected']])\n  t.element_create('txtAny', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected']])\n  t.element_create('txtNone', :text, :text=>'none', :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected']])\n  t.element_create('txtYes', :text, :text=>'yes', :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected']])\n  t.element_create('txtNormal', :text, :text=>'Normal', :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected'], '#006800', []])\n  t.element_create('txtPossSpam', :text, :text=>'Possible Spam', :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected'], '#787800', []])\n  t.element_create('txtProbSpam', :text, :text=>'Probably Spam', :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected'], '#FF9000', []])\n  t.element_create('txtBlacklist', :text, :text=>'Blacklisted', :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected'], '#FF5800', []])\n\n  if $Version_1_1_OrLater\n    s = t.style_create('styCheck')\n    t.style_elements(s, ['border', 'imgCheck'])\n    t.style_layout(s, 'border', :detach=>true, :iexpand=>:es)\n    t.style_layout(s, 'imgCheck', :expand=>:news)\n  else\n    ['Off', 'On'].each{|name|\n      s = t.style_create('sty' << name)\n      i = 'img' << name\n      t.style_elements(s, ['border', i])\n      t.style_layout(s, 'border', :detach=>true, :iexpand=>:es)\n      t.style_layout(s, i, :expand=>:news)\n    }\n  end\n\n  pad = 4\n\n  %w(Any None Yes Normal PossSpam ProbSpam Blacklist).each{|name|\n    s = t.style_create('sty' << name)\n    e = 'txt' << name\n    t.style_elements(s, ['border', e])\n    t.style_layout(s, 'border', :detach=>true, :iexpand=>:es)\n    t.style_layout(s, e, :padx=>pad, :squeeze=>:x, :expand=>:ns)\n  }\n\n  [\n    ['baldy@spammer.com',  \"Your hair is thinning\"], \n    ['flat@spammer.com', \"Your breasts are too small\"], \n    ['tiny@spammer.com',  \"Your penis is too small\"], \n    ['dumbass@spammer.com', \"You are not very smart\"], \n    ['bankrobber@spammer.com', \"You need more money\"], \n    ['loser@spammer.com', \"You need better friends\"], \n    ['gossip@spammer.com', \"Find out what your coworkers think about you\"], \n    ['whoami@spammer.com', \"Find out what you think about yourself\"],\n    ['downsized@spammer.com', \"You need a better job\"], \n    ['poorhouse@spammer.com', \"Your mortgage is a joke\"], \n    ['spam4ever@spammer.com', \"You need more spam\"]\n  ].each{|frm, subj|\n    item = t.item_create\n    status = ['styNormal','styPossSpam','styProbSpam','styBlacklist'][rand(4)]\n    attachments = ['styNone','styYes'][rand(2)]\n\n    if $Version_1_1_OrLater\n      delete = [false, true][rand(2)]\n      bounce = [false, true][rand(2)]\n      t.item_style_set(item, \n                       0, 'styCheck', 1, 'styCheck', 2, status, 3, 'styAny', \n                       4, 'styAny', 5, 'styAny', 6, 'styAny', 7, attachments)\n      t.item_state_forcolumn(item, 'delete', 'CHECK') if delete\n      t.item_state_forcolumn(item, 'bounce', 'CHECK') if bounce\n\n    else # TreeCtrl 1.0\n      delete = ['styOn', 'styOff'][rand(2)]\n      bounce = ['styOn', 'styOff'][rand(2)]\n      t.item_style_set(item, \n                       0, delete, 1, bounce, 2, status, 3, 'styAny', \n                       4, 'styAny', 5, 'styAny', 6, 'styAny', 7, attachments)\n    end\n\n    bytes = 512 + rand(1024 * 12)\n    size = \"#{bytes / 1024 + 1}KB\"\n    seconds = Tk::Clock.seconds - rand(100000)\n    received = Tk::Clock.format(seconds, '%d/%m/%y %I:%M %p')\n    t.item_text(item, 3, size, 4, frm, 5, subj, 6, received)\n    t.item_lastchild(:root, item)\n  }\n\n  sortColumn = 6\n  t.notify_bind(t, 'Header-invoke', \n                proc{|c, w|\n                  if c == sortColumn\n                    if w.column_cget(sortColumn, :arrow) == 'down'\n                      order = :increasing\n                      arrow = :up\n                    else\n                      order = :decreasing\n                      arrow = :down\n                    end\n                  else\n                    if w.column_cget(sortColumn, :arrow) == 'down'\n                      order = :decreasing\n                      arrow = :down\n                    else\n                      order = :increasing\n                      arrow = :up\n                    end\n                    w.column_configure(sortColumn, :arrow=>:none)\n                    sortColumn = c\n                  end\n                  w.column_configure(c, :arrow=>arrow)\n                  case w.column_cget(c, :tag)\n                  when 'bounce', 'delete'\n                    w.item_sort(:root, order, \n                                { \n                                  :column=>c, \n                                  :command=>proc{|item1, item2|\n                                    compareOnOff(w, c, item1, item2)\n                                  }\n                                }, \n                                { :column=>'subject', :dictionary=>true })\n                  when 'status'\n                    w.item_sort(:root, order, \n                                { :column=>c, :dictionary=>true })\n                  when 'from'\n                    w.item_sort(:root, order, \n                                { :column=>c, :dictionary=>true }, \n                                { :column=>'subject', :dictionary=>true })\n                  when 'subject'\n                    w.item_sort(:root, order, \n                                { :column=>c, :dictionary=>true })\n                  when 'size'\n                    w.item_sort(:root, order, \n                                { :column=>c, :dictionary=>true }, \n                                { :column=>'subject', :dictionary=>true })\n                  when 'received'\n                    w.item_sort(:root, order, \n                                { :column=>c, :dictionary=>true }, \n                                { :column=>'subject', :dictionary=>true })\n                  when 'attachments'\n                    w.item_sort(:root, order, \n                                { :column=>c, :dictionary=>true }, \n                                { :column=>'subject', :dictionary=>true })\n                  end\n                }, '%C %T')\n\n  mailWasher = TkBindTag.new\n\n  if $Version_1_1_OrLater\n    mailWasher.bind('ButtonPress-1', \n                    proc{|w, x, y|\n                      id = w.identify(x, y)\n                      if id.empty?\n                      elsif id[0] == 'header'\n                      else\n                        what, item, where, arg1, arg2, arg3 = id\n                        if where == 'column'\n                          tag = w.column_cget(arg1, :tag)\n                          if tag == 'delete' || tag == 'bounce'\n                            w.item_state_forcolumn(item, arg1, '~CHECK')\n                          end\n                        end\n                      end\n                    }, '%W %x %y')\n  else # TreeCtrl 1.0\n    mailWasher.bind('ButtonPress-1', \n                    proc{|w, x, y|\n                      id = w.identify(x, y)\n                      if id.empty?\n                      elsif id[0] == 'header'\n                      else\n                        what, item, where, arg1, arg2, arg3 = id\n                        if where == 'column'\n                          tag = w.column_cget(arg1, :tag)\n                          if tag == 'delete' || tag == 'bounce'\n                            style = w.item_style_set(item, arg1)\n                            if style == 'styOn'\n                              style = 'styOff'\n                            else\n                              style = 'styOn'\n                            end\n                            w.item_style_set(item, arg1, style)\n                            @display_styles_in_item.call(item)\n                          end\n                        end\n                      end\n                    }, '%W %x %y')\n  end\n\n  t.bindtags = [t, mailWasher, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL]\nend\n\nif $Version_1_1_OrLater\n  def compareOnOff(w, c, item1, item2)\n    s1 = w.item_state_forcolumn(item1, c)\n    s2 = w.item_state_forcolumn(item2, c)\n    if (s1 == s2)\n      0\n    elsif (s1 == 'CHECK')\n      -1\n    else\n      1\n    end\n  end\n\nelse # TreeCtrl 1.0\n  def compareOnOff(w, c, item1, item2)\n    s1 = w.item_style_set(item1, c)\n    s2 = w.item_style_set(item2, c)\n    if (s1 == s2)\n      0\n    elsif (s1 == 'styOff')\n      -1\n    else\n      1\n    end\n  end\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/outlook-folders.rb",
    "content": "#\n# Demo: Outlook Express folder list\n#\ndef demoOutlookFolders(t)\n  init_pics('outlook-*')\n\n  height = t.font.metrics(:linespace) + 2\n  height = 18 if height < 18\n\n  t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>true, \n              :showroot=>true, :showrootbutton=>false, :showbuttons=>true)\n\n  if $HasColumnCreate\n    t.column_create(:text=>'Folders')\n  else\n    t.column_configure(0, :text=>'Folders')\n  end\n\n  t.element_create('e1', :image)\n  t.element_create('e2', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('e3', :text, :lines=>1, :font=>t.font.dup.weight(:bold), \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('e4', :text, :fill=>'blue')\n  t.element_create('e5', :image, :image=>@images['outlook-folder'])\n  t.element_create('e6', :rect, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray', ['selected', '!focus']\n                   ])\n\n  # image + text\n  s = t.style_create('s1')\n  t.style_elements(s, ['e6', 'e1', 'e2'])\n  t.style_layout(s, 'e1', :expand=>:ns)\n  t.style_layout(s, 'e2', :padx=>[4,0], :expand=>:ns, :squeeze=>:x)\n  t.style_layout(s, 'e6', :union=>['e2'], :iexpand=>:ns, :ipadx=>2)\n\n  # image + text + text\n  s = t.style_create('s2')\n  t.style_elements(s, ['e6', 'e1', 'e3', 'e4'])\n  t.style_layout(s, 'e1', :expand=>:ns)\n  t.style_layout(s, 'e3', :padx=>4, :expand=>:ns, :squeeze=>:x)\n  t.style_layout(s, 'e4', :expand=>:ns)\n  t.style_layout(s, 'e6', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  # folder + text\n  s = t.style_create('s3')\n  t.style_elements(s, ['e6', 'e5', 'e2'])\n  t.style_layout(s, 'e5', :expand=>:ns)\n  t.style_layout(s, 'e2', :padx=>[4,0], :expand=>:ns, :squeeze=>:x)\n  t.style_layout(s, 'e6', :union=>['e2'], :iexpand=>:ns, :ipadx=>2)\n\n  # folder + text + text\n  s = t.style_create('s4')\n  t.style_elements(s, ['e6', 'e5', 'e3', 'e4'])\n  t.style_layout(s, 'e5', :expand=>:ns)\n  t.style_layout(s, 'e3', :padx=>4, :expand=>:ns, :squeeze=>:x)\n  t.style_layout(s, 'e4', :expand=>:ns)\n  t.style_layout(s, 'e6', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  t.item_style_set(:root, 0, 's1')\n  t.item_complex(:root, \n                 [\n                   ['e1', {:image=>@images['outlook-main']}], \n                   ['e2', {:text=>'Outlook Express'}]\n                 ])\n\n  parentList = [:root, '', '', '', '', '', '']\n  parent = :root\n  [\n     [0, :local, \"Local Folders\", true, 0], \n        [1, :inbox, 'Inbox', false, 5], \n        [1, :outbox, 'Outbox', false, 0], \n        [1, :sent, \"Sent Items\", false, 0], \n        [1, :deleted, \"Deleted Items\", false, 50], \n        [1, :draft, 'Drafts', false, 0], \n        [1, :folder, \"Messages to Dad\", false, 0], \n        [1, :folder, \"Messages to Sis\", false, 0], \n        [1, :folder, \"Messages to Me\", false, 0], \n           [2, :folder, \"2001\", false, 0], \n           [2, :folder, \"2000\", false, 0], \n           [2, :folder, \"1999\", false, 0], \n     [0, :server, \"news.gmane.org\", true, 0], \n        [1, :group, \"gmane.comp.lang.lua.general\", false, 498]\n  ].each{|depth, img, text, button, unread|\n    if $Version_1_1_OrLater\n      item = t.item_create(:button=>button)\n    else\n      item = t.item_create\n      t.item_hasbutton(item, button)\n    end\n    if img == :folder\n      if unread != 0\n        t.item_style_set(item, 0, 's4')\n        t.item_complex(item, \n                       [['e3', {:text=>text}], ['e4', {:text=>\"(#{unread})\"}]])\n      else\n        t.item_style_set(item, 0, 's3')\n        t.item_complex(item, [['e2', {:text=>text}]])\n      end\n    else\n      if unread != 0\n        t.item_style_set(item, 0, 's2')\n        t.item_complex(item, \n                       [\n                         ['e1', {:image=>@images[\"outlook-#{img}\"]}], \n                         ['e3', {:text=>text}], \n                         ['e4', {:text=>\"(#{unread})\"}]\n                       ])\n      else\n        t.item_style_set(item, 0, 's1')\n        t.item_complex(item, \n                       [\n                         ['e1', {:image=>@images[\"outlook-#{img}\"]}], \n                         ['e2', {:text=>text}]\n                       ])\n      end\n    end\n    t.item_lastchild(parentList[depth], item)\n    depth += 1\n    parentList[depth] = item\n  }\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb",
    "content": "#\n# Demo: Outlook Express newsgroup messages\n#\ndef demoOutlookNewsgroup(t)\n  init_pics('outlook-*')\n\n  height = t.font.metrics(:linespace)\n  height = 18 if height < 18\n  t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, \n              :showroot=>false, :showrootbutton=>false, :showbuttons=>true)\n\n  if $Version_1_1_OrLater\n    t.column_create(:image=>@images['outlook-clip'], :tag=>'clip')\n    t.column_create(:image=>@images['outlook-arrow'], :tag=>'arrow')\n    t.column_create(:image=>@images['outlook-watch'], :tag=>'watch')\n    t.column_create(:text=>'Subject', :width=>250, :tag=>'subject')\n    t.column_create(:text=>'From', :width=>150, :tag=>'from')\n    t.column_create(:text=>'Sent', :width=>150, :tag=>'sent')\n    t.column_create(:text=>'Size', :width=>60, :justify=>:right, :tag=>'size')\n  else # TreeCtrl 1.0\n    t.column_configure(0, :image=>@images['outlook-clip'], :tag=>'clip')\n    t.column_configure(1, :image=>@images['outlook-arrow'], :tag=>'arrow')\n    t.column_configure(2, :image=>@images['outlook-watch'], :tag=>'watch')\n    t.column_configure(3, :text=>'Subject', :width=>250, :tag=>'subject')\n    t.column_configure(4, :text=>'From', :width=>150, :tag=>'from')\n    t.column_configure(5, :text=>'Sent', :width=>150, :tag=>'sent')\n    t.column_configure(6, :text=>'Size', :width=>60, :justify=>:right, \n                       :tag=>'size')\n  end\n\n  # Would be nice if I could specify a column -tag too\n  t.treecolumn = 3\n\n  # State for a read message\n  t.state_define('read')\n\n  # State for a message with unread descendants\n  t.state_define('unread')\n\n  t.element_create('elemImg', :image, \n                   :image=>[\n                     @sel_images['outlook-read-2'], \n                          ['selected', 'read', 'unread', '!open'], \n                     @images['outlook-read-2'], ['read', 'unread', '!open'],\n                     @sel_images['outlook-read'], ['selected', 'read'], \n                     @images['outlook-read'], ['read'], \n                     @sel_images['outlook-unread'], ['selected'], \n                     @images['outlook-unread'], []\n                   ])\n  t.element_create('elemTxt', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']], \n                   :font=>[\n                     t.font.dup.weight(:bold), ['read', 'unread', '!open'], \n                     t.font.dup.weight(:bold), ['!read']\n                   ])\n  t.element_create('sel.e', :rect, :open=>:e, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray',  ['selected', '!focus']\n                   ])\n  t.element_create('sel.w', :rect, :open=>:w, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray',  ['selected', '!focus']\n                   ])\n  t.element_create('sel.we', :rect, :open=>:we, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray',  ['selected', '!focus']\n                   ])\n\n  # Image + text\n  s = t.style_create('s1')\n  t.style_elements(s, ['sel.e', 'elemImg', 'elemTxt'])\n  t.style_layout(s, 'elemImg', :expand=>:ns)\n  t.style_layout(s, 'elemTxt', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.e', :union=>['elemTxt'], \n                 :iexpand=>:nes, :ipadx=>[2,0])\n\n  # Text\n  s = t.style_create('s2.we')\n  t.style_elements(s, ['sel.we', 'elemTxt'])\n  t.style_layout(s, 'elemTxt', :padx=>6, :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es)\n\n  # Text\n  s = t.style_create('s2.w')\n  t.style_elements(s, ['sel.w', 'elemTxt'])\n  t.style_layout(s, 'elemTxt', :padx=>6, :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es)\n\n  # Set default item style\n  if $Version_1_1_OrLater\n    t.defaultstyle = ['', '', '', 's1', 's2.we', 's2.we', 's2.w']\n  end\n\n  msgCnt = 100\n  thread = 0\n\n  @Message = Hash.new{|k, v| k[v] = Hash.new}\n  @Message[:count][0] = 0\n\n  items = [t.index(:root)]\n\n  (1...(msgCnt)).each{|i|\n    item_i = t.item_create\n    item_j = nil\n    j = nil\n    loop {\n      j = rand(i)\n      item_j = items[j]\n      break if j == 0\n      next if t.depth(item_j) == 5\n      next if @Message[:count][@Message[:thread][item_j]] == 15\n      break\n    }\n    t.item_lastchild(item_j, item_i)\n\n    @Message[:read][item_i] = (rand(2) == 0)\n    if j == 0\n      thread += 1\n      @Message[:thread][item_i] = thread\n      @Message[:seconds][item_i] = (Tk::Clock.seconds - rand(500000))\n      @Message[:seconds2][item_i] = @Message[:seconds][item_i]\n      @Message[:count][thread] = 1\n    else\n      @Message[:thread][item_i] = @Message[:thread][item_j]\n      @Message[:seconds][item_i] = (@Message[:seconds2][item_j] + rand(10000))\n      @Message[:seconds2][item_i] = @Message[:seconds][item_i]\n      @Message[:seconds2][item_j] = @Message[:seconds][item_i]\n      @Message[:count][@Message[:thread][item_j]] += 1\n    end\n    items << item_i\n  }\n\n  (1...(msgCnt)).each{|i|\n    item_i = items[i]\n    subject = \"This is thread number #{@Message[:thread][item_i]}\"\n    from = 'somebody@somewhere.net'\n    sent = Tk::Clock.format(@Message[:seconds][item_i], \"%d/%m/%y %I:%M %p\")\n    size = \"#{1 + rand(10)}KB\"\n\n    # This message has been read\n    t.item_state_set(item_i, 'read') if @Message[:read][item_i]\n\n    # This message has unread descendants\n    t.item_state_set(item_i, 'unread')  if anyUnreadDescendants(t, item_i)\n\n    if t.item_numchildren(item_i) > 0\n      if $Version_1_1_OrLater\n        t.item_configure(item_i, :button=>true)\n      else # TreeCtrl 1.0\n        t.item_hasbutton(item_i, true)\n      end\n\n      # Collapse some messages\n      if $Version_1_1_OrLater\n        t.item_collapse(item_i) if rand(2) == 0\n      else # TreeCtrl 1.0\n        t.collapse(item_i) if rand(2) == 0\n      end\n    end\n\n    unless $Version_1_1_OrLater\n      t.item_style_set(item_i, 3, 's1', 4, 's2.we', 5, 's2.we', 6, 's2.w')\n    end\n    t.item_text(item_i, 3, subject, 4, from, 5, sent, 6, size)\n  }\n\n  # Do something when the selection changes\n  t.notify_bind(t, 'Selection', \n                proc{|w|\n                  if w.selection_count == 1\n                    # One item is selected\n                    if @Message[:afterId][:id]\n                      Tk.after_cancel(@Message[:afterId][:id]) \n                    end\n                    @Message[:afterId][:item] = w.selection_get[0]\n                    @Message[:afterId][:id] = Tk.after(500, proc{\n                                                         messageReadDelayed(w)\n                                                       })\n                  end\n                }, '%T')\nend\n\ndef messageReadDelayed(t)\n  @Message[:afterId].delete(:id)\n  i = @Message[:afterId][:item]\n  return unless t.selection_includes(i)\n\n  # This message is not read\n  unless @Message[:read][i]\n    # Read the message\n    t.item_state_set(i, 'read')\n    @Message[:read][i] = true\n\n    # Check ancestors (except root)\n    t.item_ancestors(i)[0..-2].each{|i2|\n      # This ancestor has no more unread descendants\n      t.item_state_set(i2, '!unread') unless anyUnreadDescendants(t, i2)\n    }\n  end\nend\n\n# Alternate implementation which does not rely on run-time states\ndef demoOutlookNewsgroup2(t)\n  init_pics('outlook-*')\n\n  height = t.font.metrics(:linespace)\n  height = 18 if height < 18\n  t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, \n              :showroot=>false, :showrootbutton=>false, :showbuttons=>true)\n\n  if $Version_1_1_OrLater\n    t.column_create(:image=>@images['outlook-clip'], :tag=>'clip')\n    t.column_create(:image=>@images['outlook-arrow'], :tag=>'arrow')\n    t.column_create(:image=>@images['outlook-watch'], :tag=>'watch')\n    t.column_create(:text=>'Subject', :width=>250, :tag=>'subject')\n    t.column_create(:text=>'From', :width=>150, :tag=>'from')\n    t.column_create(:text=>'Sent', :width=>150, :tag=>'sent')\n    t.column_create(:text=>'Size', :width=>60, :justify=>:right, :tag=>'size')\n  else # TreeCtrl 1.0\n    t.column_configure(0, :image=>@images['outlook-clip'], :tag=>'clip')\n    t.column_configure(1, :image=>@images['outlook-arrow'], :tag=>'arrow')\n    t.column_configure(2, :image=>@images['outlook-watch'], :tag=>'watch')\n    t.column_configure(3, :text=>'Subject', :width=>250, :tag=>'subject')\n    t.column_configure(4, :text=>'From', :width=>150, :tag=>'from')\n    t.column_configure(5, :text=>'Sent', :width=>150, :tag=>'sent')\n    t.column_configure(6, :text=>'Size', :width=>60, :justify=>:right, \n                       :tag=>'size')\n  end\n\n  t.treecolumn = 3\n\n  t.element_create('image.unread', :image, :image=>@images['outlook-unread'])\n  t.element_create('image.read', :image, :image=>@images['outlook-read'])\n  t.element_create('image.read2', :image, :image=>@images['outlook-read-2'])\n  t.element_create('text.read', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('text.unread', :text, :lines=>1, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']], \n                   :font=>t.font.dup.weight(:bold))\n  t.element_create('sel.e', :rect, :open=>:e, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray',  ['selected', '!focus']\n                   ])\n  t.element_create('sel.w', :rect, :open=>:w, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray',  ['selected', '!focus']\n                   ])\n  t.element_create('sel.we', :rect, :open=>:we, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray',  ['selected', '!focus']\n                   ])\n\n  # Image + text\n  s = t.style_create('unread')\n  t.style_elements(s, ['sel.e', 'image.unread', 'text.unread'])\n  t.style_layout(s, 'image.unread', :expand=>:ns)\n  t.style_layout(s, 'text.unread', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.e', :union=>['text.unread'], \n                 :iexpand=>:nes, :ipadx=>[2,0])\n\n  # Image + text\n  s = t.style_create('read')\n  t.style_elements(s, ['sel.e', 'image.read', 'text.read'])\n  t.style_layout(s, 'image.read', :expand=>:ns)\n  t.style_layout(s, 'text.read', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.e', :union=>['text.read'], \n                 :iexpand=>:nes, :ipadx=>[2,0])\n\n  # Image + text\n  s = t.style_create('read2')\n  t.style_elements(s, ['sel.e', 'image.read2', 'text.unread'])\n  t.style_layout(s, 'image.read2', :expand=>:ns)\n  t.style_layout(s, 'text.unread', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.e', :union=>['text.unread'], \n                 :iexpand=>:nes, :ipadx=>[2,0])\n\n  # Text\n  s = t.style_create('unread.we')\n  t.style_elements(s, ['sel.we', 'text.unread'])\n  t.style_layout(s, 'text.unread', :padx=>6, :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es)\n\n  # Text\n  s = t.style_create('read.we')\n  t.style_elements(s, ['sel.we', 'text.read'])\n  t.style_layout(s, 'text.read', :padx=>6, :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es)\n\n  # Text\n  s = t.style_create('unread.w')\n  t.style_elements(s, ['sel.w', 'text.unread'])\n  t.style_layout(s, 'text.unread', :padx=>6, :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es)\n\n  # Text\n  s = t.style_create('read.w')\n  t.style_elements(s, ['sel.w', 'text.read'])\n  t.style_layout(s, 'text.read', :padx=>6, :squeeze=>:x, :expand=>:ns)\n  t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es)\n\n  msgCnt = 100\n  thread = 0\n\n  @Message = Hash.new{|k, v| k[v] = Hash.new}\n  @Message[:count][0] = 0\n\n  (1...(msgCnt)).each{|i|\n    t.item_create\n    j = nil\n    loop {\n      j = rand(i)\n      break if j == 0\n      next if t.depth(j) == 5\n      next if @Message[:count][@Message[:thread][j]] == 15\n      break\n    }\n    t.item_lastchild(j, i)\n\n    @Message[:read][i] = (rand(2) == 0)\n    if j == 0\n      thread += 1\n      @Message[:thread][i] = thread\n      @Message[:seconds][i] = (Tk::Clock.seconds - rand(500000))\n      @Message[:seconds2][i] = @Message[:seconds][i]\n      @Message[:count][thread] = 1\n    else\n      @Message[:thread][i] = @Message[:thread][j]\n      @Message[:seconds][i] = (@Message[:seconds2][j] + rand(10000))\n      @Message[:seconds2][i] = @Message[:seconds][i]\n      @Message[:seconds2][j] = @Message[:seconds][i]\n      @Message[:count][@Message[:thread][j]] += 1\n    end\n  }\n\n  (1...(msgCnt)).each{|i|\n    subject = \"This is thread number #{@Message[:thread][i]}\"\n    from = 'somebody@somewhere.net'\n    sent = Tk::Clock.format(@Message[:seconds][i], \"%d/%m/%y %I:%M %p\")\n    size = \"#{1 + rand(10)}KB\"\n    if @Message[:read][i]\n      style = 'read'\n      style2 = 'read2'\n    else\n      style = 'unread'\n      style2 = 'unread2'\n    end\n    t.item_style_set(i, 3, style, 4, \"#{style2}.we\", 5, \"#{style2}.we\", \n                     6, \"#{style2}.w\")\n    t.item_text(i, 3, subject, 4, from, 5, sent, 6, size)\n    if t.item_numchildren(i) > 0\n      t.item_configure(item_i, :button=>true)\n    end\n  }\n\n  # Do something when the selection changes\n  t.notify_bind(t, 'Selection', \n                proc{|w|\n                  if w.selection_count == 1\n                    i = t.selection_get[0]\n                    unless @Message[:read][i]\n                      if t.item_isopen(i) || !anyUnreadDescendants(t, i)\n                        # unread -> read\n                        t.item_style_map(i, 'subject', 'read', \n                                         ['text.unread', 'text.read'])\n                        t.item_style_map(i, 'from', 'read.we', \n                                         ['text.unread', 'text.read'])\n                        t.item_style_map(i, 'sent', 'read.we', \n                                         ['text.unread', 'text.read'])\n                        t.item_style_map(i, 'size', 'read.w', \n                                         ['text.unread', 'text.read'])\n                      else\n                        # unread -> read2\n                        t.item_style_map(i, 'subject', 'read2', \n                                         ['text.unread', 'text.unread'])\n                      end\n\n                      @Message[:read][i] = true\n                      @display_styles_in_item.call(i)\n                    end\n                  end\n                }, '%T')\n\n  t.notify_bind(t, 'Expand-after', \n                proc{|w, i|\n                  if @Messge[:read][i] && anyUnreadDescendants(t, i)\n                    # read2 -> read\n                    t.item_style_map(i, 'subject', 'read', \n                                     ['text.unread', 'text.read'])\n                    # unread -> read\n                    t.item_style_map(i, 'from', 'read.we', \n                                     ['text.unread', 'text.read'])\n                    t.item_style_map(i, 'sent', 'read.we', \n                                     ['text.unread', 'text.read'])\n                    t.item_style_map(i, 'size', 'read.w', \n                                     ['text.unread', 'text.read'])\n                  end\n                }, '%T %I')\n\n  t.notify_bind(t, 'Collapse-after', \n                proc{|w, i|\n                  if @Messge[:read][i] && anyUnreadDescendants(t, i)\n                    # read -> read2\n                    t.item_style_map(i, 'subject', 'read2', \n                                     ['text.read', 'text.unread'])\n                    # read -> unread\n                    t.item_style_map(i, 'from', 'unread.we', \n                                     ['text.read', 'text.unread'])\n                    t.item_style_map(i, 'sent', 'unread.we', \n                                     ['text.read', 'text.unread'])\n                    t.item_style_map(i, 'size', 'unread.w', \n                                     ['text.read', 'text.unread'])\n                  end\n                }, '%T %I')\n\n  (1...(msgCnt)).each{|i|\n    if rand(2) == 0\n      if t.item_numchildren(i) > 0\n        if $Version_1_1_OrLater\n          t.item_collapse(i)\n        else # TreeCtrl 1.0\n          t.collapse(i)\n        end\n      end\n    end\n  }\nend\n\ndef anyUnreadDescendants(t, i)\n  itemList = []\n  item = t.item_firstchild(i)\n  itemList.push(item) if item != ''\n\n  while item = itemList.pop\n    return true unless @Message[:read][item]\n\n    item2 = t.item_nextsibling(item)\n    itemList.push(item2) if item2 != ''\n    item2 = t.item_firstchild(item)\n    itemList.push(item2) if item2 != ''\n  end\n  false\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/random.rb",
    "content": "# \ndef random_N\n  @RandomN[0] || 500\nend\n\n#\n# Demo: random N items\n#\ndef demoRandom(t)\n  init_pics('folder-*', 'small-*')\n\n  height = t.font.metrics(:linespace)\n  height = 18 if height < 18\n  t.configure(:itemheight=>height, :selectmode=>:extended, \n              :showroot=>true, :showrootbutton=>true, :showbuttons=>true, \n              :showlines=>true, :scrollmargin=>16, \n              :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50])\n\n  if $Version_1_1_OrLater\n    t.column_create(:expand=>true, :text=>'Item', \n                    :itembackground=>['#e0e8f0', []], :tag=>'item')\n    t.column_create(:text=>'Parent', :justify=>:center, \n                    :itembackground=>['gray90', []], :tag=>'parent')\n    t.column_create(:text=>'Depth', :justify=>:center, \n                    :itembackground=>['linen', []], :tag=>'depth')\n  else # TreeCtrl 1.0\n    t.column_configure(0, :expand=>true, :text=>'Item', \n                       :itembackground=>['#e0e8f0', []], :tag=>'item')\n    t.column_configure(1, :text=>'Parent', :justify=>:center, \n                       :itembackground=>['gray90', []], :tag=>'parent')\n    t.column_configure(2, :text=>'Depth', :justify=>:center, \n                       :itembackground=>['linen', []], :tag=>'depth')\n  end\n\n  t.element_create('e1', :image, :image=>[\n                     @images['folder-open'], ['open'], \n                     @images['folder-closed'], []\n                   ])\n  t.element_create('e2', :image, :image=>@images['small-file'])\n  t.element_create('e3', :text, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('e4', :text, :fill=>'blue')\n  t.element_create('e6', :text)\n  t.element_create('e5', :rect, :showfocus=>true, \n                   :fill=>[\n                     @SystemHighlight, ['selected', 'focus'], \n                     'gray', ['selected', '!focus']\n                   ])\n\n  s = t.style_create('s1')\n  t.style_elements(s, ['e5', 'e1', 'e3', 'e4'])\n  t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e3', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e4', :padx=>[0,6], :expand=>:ns)\n  t.style_layout(s, 'e5', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  s = t.style_create('s2')\n  t.style_elements(s, ['e5', 'e2', 'e3'])\n  t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e3', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e5', :union=>['e3'], :iexpand=>:ns, :ipadx=>2)\n\n  s = t.style_create('s3')\n  t.style_elements(s, ['e6'])\n  t.style_layout(s, 'e6', :padx=>6, :expand=>:ns)\n\n  @Priv[:sensitive, t] = [\n    [:item, 's1',  'e5', 'e1', 'e3'], \n    [:item, 's2',  'e5', 'e2', 'e3']\n  ]\n  @Priv[:dragimage, t] = [\n    [:item, 's1',  'e1', 'e3'], \n    [:item, 's2',  'e2', 'e3']\n  ]\n\n  clicks = Tk::Clock.clicks\n  items = [ t.index(:root) ]\n  (1...(random_N())).each{|i|\n    item_i = t.item_create\n    item_j = nil\n    loop {\n      j = rand(i)\n      item_j = items[j]\n      break if t.depth(item_j) < 5\n    }\n    if $Version_1_1_OrLater\n      t.item_collapse(item_i) if rand(2) == 0\n    else # TreeCtrl 1.0\n      t.collapse(item_i) if rand(2) == 0\n    end\n    if rand(2) == 0\n      t.item_lastchild(item_j, item_i)\n    else\n      t.item_firstchild(item_j, item_i)\n    end\n    items << item_i\n  }\n  puts \"created #{random_N() - 1} items in #{Tk::Clock.clicks - clicks} clicks\"\n\n  clicks = Tk::Clock.clicks\n  (0...(random_N())).each{|i|\n    item_i = items[i]\n    numChildren = t.item_numchildren(item_i)\n    if numChildren > 0\n      if $Version_1_1_OrLater\n        t.item_configure(item_i, :button=>true)\n      else # TreeCtrl 1.0\n        t.item_hasbutton(item_i, true)\n      end\n      t.item_style_set(item_i, 0, 's1', 1, 's3', 2, 's3')\n      t.item_complex(item_i, \n                     [ ['e3', {:text=>\"Item #{i}\"}], \n                       ['e4', {:text=>\"(#{numChildren})\"}] ], \n                     [ ['e6', {:text=>\"#{t.item_parent(item_i)}\"}] ], \n                     [ ['e6', {:text=>\"#{t.depth(item_i)}\"}] ])\n    else\n      t.item_style_set(item_i, 1, 's3', 2, 's3', 0, 's2')\n      t.item_complex(item_i, \n                     [ ['e3', {:text=>\"Item #{i}\"}] ], \n                     [ ['e6', {:text=>\"#{t.item_parent(item_i)}\"}] ], \n                     [ ['e6', {:text=>\"#{t.depth(item_i)}\"}] ])\n    end\n  }\n  puts \"configured #{random_N()} items in #{Tk::Clock.clicks - clicks} clicks\"\n\n  treeCtrlRandom = TkBindTag.new\n\n  treeCtrlRandom.bind('Double-ButtonPress-1', \n                      proc{|w, x, y|\n                        Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  treeCtrlRandom.bind('Control-ButtonPress-1', \n                      proc{|w, x, y|\n                        @Priv['selectMode'] = :toggle\n                        randomButton1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  treeCtrlRandom.bind('Shift-ButtonPress-1', \n                      proc{|w, x, y|\n                        @Priv['selectMode'] = :add\n                        randomButton1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  treeCtrlRandom.bind('ButtonPress-1', \n                      proc{|w, x, y|\n                        @Priv['selectMode'] = :set\n                        randomButton1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  treeCtrlRandom.bind('Button1-Motion', \n                      proc{|w, x, y|\n                        randomMotion1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  treeCtrlRandom.bind('Button1-Leave', \n                      proc{|w, x, y|\n                        randomLeave1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  treeCtrlRandom.bind('ButtonRelease-1', \n                      proc{|w, x, y|\n                        randomRelease1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  t.bindtags = [ t, treeCtrlRandom, Tk::TreeCtrl, t.winfo_toplevel, :all ]\nend\n\ndef randomButton1(t, x, y)\n  t.set_focus\n  id = t.identify(x, y)\n  puts id.inspect\n  @Priv['buttonMode'] = ''\n\n  # Click outside any item\n  if id.empty?\n    t.selection_clear\n\n  # Click in header\n  elsif id[0] == 'header'\n    Tk::TreeCtrl::BindCallback.buttonPress1(t, x, y)\n\n  # Click in item\n  else\n    where, item, arg1, arg2, arg3, arg4 = id\n    case arg1\n    when 'button'\n      if $Version_1_1_OrLater\n        t.item_toggle(item)\n      else # TreeCtrl 1.0\n        t.toggle(item)\n      end\n\n    when 'line'\n      if $Version_1_1_OrLater\n        t.item_toggle(arg2)\n      else # TreeCtrl 1.0\n        t.toggle(arg2)\n      end\n\n    when 'column'\n      ok = false\n      # Clicked an element\n      if id.length == 6\n        column = id[3]\n        e = id[5]\n        @Priv.list_element(:sensitive, t).each{|lst|\n          c, s, *eList = TkComm.simplelist(lst)\n          next if column != t.column_index(c)\n          next if t.item_style_set(item, c) != s\n          next if eList.find{|le| le == e} == nil\n          ok = true\n          break\n        }\n      end\n      unless ok\n        t.selection_clear\n        return\n      end\n\n      @Priv[:drag, :motion] = 0\n      @Priv[:drag, :x] = t.canvasx(x)\n      @Priv[:drag, :y] = t.canvasy(y)\n      @Priv[:drop] = ''\n\n      if @Priv['selectMode'] == 'add'\n          Tk::TreeCtrl::BindCallback.beginExtend(t, item)\n      elsif @Priv['selectMode'] == 'toggle'\n          Tk::TreeCtrl::BindCallback.beginToggle(t, item)\n      elsif ! t.selection_includes(item)\n          Tk::TreeCtrl::BindCallback.beginSelect(t, item)\n      end\n      t.activate(item)\n\n      if t.selection_includes(item)\n        @Priv['buttonMode'] = 'drag'\n      end\n    end\n  end\nend\n\ndef randomMotion1(t, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.motion1(t, x, y)\n  when 'drag'\n    randomAutoScanCheck(t, x, y)\n    randomMotion(t, x, y)\n  end\nend\n\ndef randomMotion(t, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.motion1(t, x, y)\n\n  when 'drag'\n    # Detect initial mouse movement\n    unless @Priv.bool_element(:drag, :motion)\n      @Priv[:selection] = t.selection_get\n      @Priv[:drop] = ''\n      t.dragimage_clear\n      # For each selected item, add 2nd and 3rd elements of\n      # column \"item\" to the dragimage\n      @Priv.list_element(:selection).each{|i|\n        @Priv.list_element(:dragimage,t).each{|lst|\n          c, s, *eList = TkComm.simplelist(lst)\n          if t.item_style_set(i, c) == s\n            t.dragimage_add(i, c, *eList)\n          end\n        }\n      }\n      @Priv[:drag,:motion] = true\n    end\n\n    # Find the item under the cursor\n    cursor = 'X_cursor'\n    drop = ''\n    id = t.identify(x, y)\n    ok = false\n    if !id.empty? && id[0] == 'item' && id.length == 6\n      item = id[1]\n      column = id[3]\n      e = id[5]\n      @Priv.list_element(:sensitive,t).each{|lst|\n        c, s, *eList = TkComm.simplelist(lst)\n        next if column != t.column_index(c)\n        next if t.item_style_set(item, c) != s\n        next unless eList.find{|val| val.to_s == e.to_s}\n        ok = true\n        break\n      }\n      ok = true if @Priv.list_element(:sensitive,t).find{|val| TkComm.simplelist(val).index(e)}\n    end\n\n    if ok\n      # If the item is not in the pre-drag selection\n      # (i.e. not being dragged) see if we can drop on it\n      unless @Priv.list_element(:selection).find{|val| val.to_s == item.to_s}\n        drop = item\n        # We can drop if dragged item isn't an ancestor\n        @Priv.list_element(:selection).each{|item2|\n          if t.item_isancestor(item2, item)\n            drop = ''\n            break\n          end\n        }\n        if drop != ''\n          x1, y1, x2, y2 = t.item_bbox(drop)\n          if y < y1 + 3\n            cursor = 'top_side'\n            @Priv[:drop,:pos] = 'prevsibling'\n          elsif y >= y2 - 3\n            cursor = 'bottom_side'\n            @Priv[:drop,:pos] = 'nextsibling'\n          else\n            cursor = ''\n            @Priv[:drop,:pos] = 'lastchild'\n          end\n        end\n      end\n    end\n\n    t[:cursor] = cursor if t[:cursor] != cursor\n\n    # Select the item under the cursor (if any) and deselect\n    # the previous drop-item (if any)\n    t.selection_modify(drop, @Priv[:drop])\n    @Priv[:drop] = drop\n\n    # Show the dragimage in its new position\n    x = t.canvasx(x) - @Priv.numeric_element(:drag,:x)\n    y = t.canvasx(y) - @Priv.numeric_element(:drag,:y)\n    t.dragimage_offset(x, y)\n    t.dragimage_configure(:visible=>true)\n  end\nend\n\ndef randomLeave1(t, x, y)\n  # This is called when I do ButtonPress-1 on Unix for some reason,\n  # and buttonMode is undefined.\n  return unless @Priv.exist?('buttonMode')\n  case @Priv['buttonMode']\n  when 'header'\n    Tk::TreeCtrl::BindCallback.leave1(t, x, y)\n  end\nend\n\ndef randomRelease1(t, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.release1(t, x, y)\n  when 'drag'\n    Tk::TreeCtrl::BindCallback.autoScanCancel(t)\n    t.dragimage_configure(:visible=>false)\n    t.selection_modify('', @Priv[:drop])\n    t[:cursor] = ''\n    if @Priv[:drop] != ''\n      randomDrop(t, @Priv[:drop], @Priv.list_element(:selection), \n                 @Priv[:drop, :pos])\n    end\n  end\n  @Priv['buttonMode'] = ''\nend\n\ndef randomDrop(t, target, src, pos)\n  parentList = []\n  case pos\n  when 'lastchild'\n    parent = target\n  when 'prevsibling'\n    parent = t.item_parent(target)\n  when 'nextsibling'\n    parent = t.item_parent(target)\n  end\n  src.each{|item|\n    # Ignore any item whose ancestor is also selected\n    ignore = false\n    t.item_ancestors(item).each{|ancestor|\n      if src.find{|val| val.to_s == ancestor.to_s}\n        ignore = true\n        break\n      end\n    }\n    next if ignore\n\n    # Update the old parent of this moved item later\n    unless parentList.find{|val| val.to_s == item.to_s}\n      parentList << t.item_parent(item)\n    end\n\n    # Add to target\n    t.__send__(\"item_#{pos}\", target, item)\n\n    # Update text: parent\n    t.item_element_configure(item, 'parent', 'e6', :text=>parent)\n\n    # Update text: depth\n    t.item_element_configure(item, 'depth', 'e6', :text=>t.depth(item))\n\n    # Recursively update text: depth\n    itemList = []\n    item = t.item_firstchild(item)\n    itemList << item if item != ''\n\n    while item = itemList.pop\n      t.item_element_configure(item, 'depth', 'e6', :text=>t.depth(item))\n\n      item2 = t.item_nextsibling(item)\n      itemList << item2 if item2 != ''\n\n      item2 = t.item_firstchild(item)\n      itemList << item2 if item2 != ''\n    end\n  }\n\n  # Update items that lost some children\n  parentList.each{|item|\n    numChildren = t.item_numchildren(item)\n    if numChildren == 0\n      if $Version_1_1_OrLater\n        t.item_configure(item, :button=>false)\n      else # TreeCtrl 1.0\n        t.item_hasbutton(item, false)\n      end\n      t.item_style_map(item, 'item', 's2', ['e3', 'e3'])\n    else\n      t.item_element_configure(item, 'item', 'e4', :text=>\"(#{numChildren})\")\n    end\n  }\n\n  # Update the target that gained some children\n  if t.item_style_set(parent, 0) != 's1'\n    if $Version_1_1_OrLater\n      t.item_configure(parent, :button=>true)\n    else # TreeCtrl 1.0\n      t.item_hasbutton(parent, true)\n    end\n    t.item_style_map(parent, 'item', 's1', ['e3', 'e3'])\n  end\n  numChildren = t.item_numchildren(parent)\n  t.item_element_configure(parent, 'item', 'e4', :text=>\"(#{numChildren})\")\nend\n\n# Same as TreeCtrl::AutoScanCheck, but calls RandomMotion and\n# RandomAutoScanCheckAux\ndef randomAutoScanCheck(t, x, y)\n  x1, y1, x2, y2 = t.contentbox\n  margin = t.winfo_pixels(t.scrollmargin)\n  if x < x1 + margin || x >= x2 - margin || y < y1 + margin || y >= y2 - margin\n    if ! @Priv.exist?(:autoscan, :afterId, t)\n      if y >= y2 - margin\n        t.yview(:scroll, 1, :units)\n        delay = t.yscrolldelay\n      elsif y < y1 + margin\n        t.yview(:scroll, -1, :units)\n        delay = t.yscrolldelay\n      elsif x >= x2 - margin\n        t.xview(:scroll, 1, :units)\n        delay = t.xscrolldelay\n      elsif x < x1 + margin\n        t.xview(:scroll, -1, :units)\n        delay = t.xscrolldelay\n      end\n      if @Priv.exist?(:autoscan, :scanning, t)\n        delay = delay[1] if delay.kind_of?(Array)\n      else\n        delay = delay[0] if delay.kind_of?(Array)\n        @Priv[:autoscan, :scanning, t] = true\n      end\n      case @Priv['buttonMode']\n      when 'drag', 'marquee'\n        randomMotion(t, x, y)\n      end\n      @Priv[:autoscan, :afterId, t] = \n        Tk.after(delay, proc{ randomAutoScanCheckAux(t) })\n    end\n    return\n  end\n  Tk::TreeCtrl::BindCallback.autoScanCancel(t)\nend\n\ndef randomAutoScanCheckAux(t)\n  @Priv.unset(:autoscan, :afterId, t)\n  x = t.winfo_pointerx - t.winfo_rootx\n  y = t.winfo_pointery - t.winfo_rooty\n  randomAutoScanCheck(t, x, y)\nend\n\n#\n# Demo: random N items, button images\n#\ndef demoRandom2(t)\n  demoRandom(t)\n\n  init_pics('mac-*')\n\n  t.configure(:openbuttonimage=>@images['mac-collapse'], \n              :closedbuttonimage=>@images['mac-expand'], \n              :showlines=>false)\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/readme.txt",
    "content": "The scripts and image files in this directory are based on demo files\nof Tcl/Tk's TreeCtrl extention. \n"
  },
  {
    "path": "ext/tk/sample/tkextlib/treectrl/www-options.rb",
    "content": "def demoInternetOptions (t)\n  @Option = TkVarAccess.new_hash('::Option')\n\n  height = t.font.metrics(:linespace) + 2\n  height = 18 if height < 18\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :itemheight=>height, :selectmode=>:browse)\n\n  init_pics('internet-*')\n\n  if $HasColumnCreate\n    t.column_create(:text=>'Internet Options')\n  else\n    t.column_configure(0, :text=>'Internet Options')\n  end\n\n  t.state_define('check')\n  t.state_define('radio')\n  t.state_define('on')\n\n  t.element_create('e1', :image, :image=>[\n                     @images['internet-check-on'],  ['check', 'on'], \n                     @images['internet-check-off'], ['check'], \n                     @images['internet-radio-on'],  ['radio', 'on'], \n                     @images['internet-radio-off'], ['radio']\n                   ])\n  t.element_create('e2', :text, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('e3', :rect, :showfocus=>true, \n                   :fill=>[@SystemHighlight, ['selected', 'focus']])\n\n  s = t.style_create('s1')\n  t.style_elements(s, ['e3', 'e1', 'e2'])\n  t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e2', :expand=>:ns)\n  t.style_layout(s, 'e3', :union=>['e2'], :iexpand=>:ns, :ipadx=>2)\n\n  parentList = [:root, '', '', '', '', '', '']\n  parent = :root\n  [\n    [0, :print, \"Printing\", \"\", \"\"], \n        [1, :off, \"Print background colors and images\", \"o1\", \"\"], \n    [0, :search, \"Search from Address bar\", \"\", \"\"], \n        [1, :search, \"When searching\", \"\", \"\"], \n            [2, :off, \"Display results, and go to the most likely sites\", \n                                                                 \"o2\", \"r1\"], \n            [2, :off, \"Do not search from the Address bar\", \"o3\", \"r1\"], \n            [2, :off, \"Just display the results in the main window\", \n                                                                 \"o4\", \"r1\"],\n            [2, :on, \"Just go to the most likely site\", \"o5\", \"r1\"], \n    [0, :security, \"Security\", \"\", \"\"], \n        [1, :on, \"Check for publisher's certificate revocation\", \"o5\", \"\"], \n        [1, :off, \"Check for server certificate revocation (requires restart)\",\n                                                                 \"o6\", \"\"]\n  ].each{|depth, setting, text, option, group|\n    item = t.item_create()\n    t.item_style_set(item, 0, 's1')\n    t.item_element_configure(item, 0, 'e2', :text=>text)\n    @Option[:option, item] = option\n    @Option[:group, item] = group\n    if setting == :on || setting == :off\n      @Option[:setting, item] = setting\n      if group == ''\n        t.item_state_set(item, 'check')\n        if setting == :on\n          t.item_state_set(item, 'on')\n        end\n      else\n        if setting == :on\n          @Option[:current, group] = item\n          t.item_state_set(item, 'on')\n        end\n        t.item_state_set(item, 'radio')\n      end\n    else\n      t.item_element_configure(item, 0, 'e1', \n                               :image=>@images[\"internet-#{setting}\"])\n    end\n    t.item_lastchild(parentList[depth], item)\n    depth += 1\n    parentList[depth] = item\n  }\n\n  treeCtrlOption = TkBindTag.new\n  treeCtrlOption.bind('Double-ButtonPress-1', proc{|w, x, y|\n                        Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y)\n                      }, '%W %x %y')\n  treeCtrlOption.bind('ButtonPress-1', proc{|w, x, y|\n                        optionButton1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n  treeCtrlOption.bind('Button1-Motion', proc{|w, x, y|\n                        optionMotion1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n  treeCtrlOption.bind('Button1-Leave', proc{|w, x, y|\n                        optionLeave1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n  treeCtrlOption.bind('ButtonRelease-1', proc{|w, x, y|\n                        optionRelease1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  t.bindtags = [\n    t, treeCtrlOption, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL\n  ]\nend\n\ndef optionButton1(w, x, y)\n  w.set_focus\n  id = w.identify(x, y)\n  if id[0] == 'header'\n    Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y)\n  elsif id.empty?\n    @Priv['buttonMode'] = ''\n  else\n    @Priv['buttonMode'] = ''\n    item = id[1]\n    w.selection_modify(item, :all)\n    w.activate(item)\n    return if @Option[:option, item] == ''\n    group = @Option[:group, item]\n    if group == ''\n      # a checkbutton\n      w.item_state_set(item, '~on')\n      if @Option[:setting, item] == 'on'\n        setting = :off\n      else\n        setting = :on\n      end\n      @Option[:setting, item] = setting\n    else\n      # a radiobutton\n      current = @Option[:current, group]\n      return if current == item.to_s\n      w.item_state_set(current, '!on')\n      w.item_state_set(item, 'on')\n      @Option[:setting, item] = :on\n      @Option[:current, group] = item\n    end\n  end\nend\n\n# Alternate implementation that doesn't rely on run-time styles\ndef demoInternetOptions_2(t)\n  height = t.font.metrics(:linespace) + 2\n  height = 18 if height < 18\n  t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, \n              :itemheight=>height, :selectmode=>:browse)\n\n  init_pics('internet-*')\n\n  t.column_configure(0, :text=>'Internet Options')\n\n  t.element_create('e1', :image)\n  t.element_create('e2', :text, \n                   :fill=>[@SystemHighlightText, ['selected', 'focus']])\n  t.element_create('e3', :rect, :showfocus=>true, \n                   :fill=>[@SystemHighlight, ['selected', 'focus']])\n\n  s = t.style_create('s1')\n  t.style_elements('s1', ['e3', 'e1', 'e2'])\n  t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns)\n  t.style_layout(s, 'e2', :expand=>:ns)\n  t.style_layout(s, 'e3', :union=>['e2'], :iexpand=>:ns, :ipadx=>2)\n\n  parentList = [:root, '', '', '', '', '', '']\n  parent = :root\n  [\n    [0, :print, \"Printing\", \"\", \"\"], \n        [1, :off, \"Print background colors and images\", \"o1\", \"\"], \n    [0, :search, \"Search from Address bar\", \"\", \"\"], \n        [1, :search, \"When searching\", \"\", \"\"], \n            [2, :off, \"Display results, and go to the most likely sites\", \n                                                                 \"o2\", \"r1\"], \n            [2, :off, \"Do not search from the Address bar\", \"o3\", \"r1\"], \n            [2, :off, \"Just display the results in the main window\", \n                                                                 \"o4\", \"r1\"],\n            [2, :on, \"Just go to the most likely site\", \"o5\", \"r1\"], \n    [0, :security, \"Security\", \"\", \"\"], \n        [1, :on, \"Check for publisher's certificate revocation\", \"o5\", \"\"], \n        [1, :off, \"Check for server certificate revocation (requires restart)\",\n                                                                 \"o6\", \"\"]\n  ].each{|depth, setting, text, option, group|\n    item = t.item_create()\n    t.item_style_set(item, 0, 's1')\n    t.item_element_configure(item, 0, 'e2', :text=>text)\n    @Option[:option, item] = option\n    @Option[:group, item] = group\n    if setting == :on || setting == :off\n      @Option[:setting, item] = setting\n      if group == ''\n        img = @images[\"internet-check-#{setting}\"]\n        t.item_element_configure(item, 0, 'e1', :image=>img)\n      else\n        if setting == :on\n          @Option[:current, group] = item\n        end\n        img = @images[\"internet-radio-#{setting}\"]\n        t.item_element_configure(item, 0, 'e1', :image=>img)\n      end\n    else\n      t.item_element_configure(item, 0, 'e1', \n                               :image=>@images[\"internet-#{setting}\"])\n    end\n    t.item_lastchild(parentList[depth], item)\n    depth += 1\n    parentList[depth] = item\n  }\n\n  treeCtrlOption = TkBindTag.new\n  treeCtrlOption.bind('Double-ButtonPress-1', proc{|w, x, y|\n                        Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y)\n                      }, '%W %x %y')\n  treeCtrlOption.bind('ButtonPress-1', proc{|w, x, y|\n                        optionButton1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n  treeCtrlOption.bind('Button1-Motion', proc{|w, x, y|\n                        optionMotion1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n  treeCtrlOption.bind('Button1-Leave', proc{|w, x, y|\n                        optionLeave1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n  treeCtrlOption.bind('ButtonRelease-1', proc{|w, x, y|\n                        optionRelease1(w, x, y)\n                        Tk.callback_break\n                      }, '%W %x %y')\n\n  t.bindtags = [\n    t, treeCtrlOption, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL\n  ]\nend\n\ndef optionButton1_2(w, x, y)\n  w.set_focus\n  id = w.identify(x, y)\n  if id[0] == 'header'\n    Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y)\n  elsif id.empty?\n    @Priv['buttonMode'] = ''\n  else\n    @Priv['buttonMode'] = ''\n    item = id[1]\n    w.selection_modify(item, :all)\n    w.activate(item)\n    return if @Option[:option, item] == ''\n    group = @Option[:group, item]\n    if group == ''\n      # a checkbutton\n      if @Option[:setting, item] == 'on'\n        setting = :off\n      else\n        setting = :on\n      end\n      w.item_element_configure(item, 0, 'e1', \n                               :image=>@images[\"internet-check-#{setting}\"])\n      @Option[:setting, item] = setting\n    else\n      # a radiobutton\n      current = @Option[:current, group]\n      return if current == item.to_s\n      w.item_element_configure(current, 0, 'e1', \n                               :image=>@images[\"internet-radio-off\"])\n      w.item_element_configure(item, 0, 'e1', \n                               :image=>@images[\"internet-radio-on\"])\n      @Option[:setting, item] = :on\n      @Option[:current, group] = item\n    end\n  end\nend\n\ndef optionMotion1(w, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.motion1(w, x, y)\n  end\nend\n\ndef optionLeave1(w, x, y)\n  # This is called when I do ButtonPress-1 on Unix for some reason,\n  # and buttonMode is undefined.\n  begin\n    mode = @Priv['buttonMode']\n  rescue\n  else\n    case mode\n    when 'header'\n      t.column_configure(@Priv['column'], :sunken=>false)\n    end\n  end\nend\n\ndef optionRelease1(w, x, y)\n  case @Priv['buttonMode']\n  when 'resize', 'header'\n    Tk::TreeCtrl::BindCallback.release1(w, x, y)\n  end\n  @Priv['buttonMode'] = ''\nend\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/Orig_LICENSE.txt",
    "content": "\n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n  >>>  The following text is the original 'license.txt' of vu extension.  <<<\n  >>>  Original Tcl source files are not include in this directry,        <<<\n  >>>  because of all of them are rewrited to Ruby files.                 <<<\n  >>>  However, the bitmap data file included in this directory is the    <<<\n  >>>  same file of vu extension. So, the bitmap data file is under the   <<<\n  >>>  following license.                                                 <<<\n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n\t\t   * COPYRIGHT AND LICENSE TERMS *\n\n(This file blatantly stolen from Tcl/Tk license and adapted - thus assume\nit falls under similar license terms).\n\nThis software is copyrighted by Jeffrey Hobbs <jeff.hobbs@acm.org> and\nothers.  The following terms apply to all files associated with the\nsoftware unless explicitly disclaimed in individual files.\n\nThe authors hereby grant permission to use, copy, modify, distribute, and\nlicense this software and its documentation for any purpose, provided that\nexisting copyright notices are retained in all copies and that this notice\nis included verbatim in any distributions.  No written agreement, license,\nor royalty fee is required for any of the authorized uses.\n\nIN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR\nDIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT\nOF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,\nEVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nTHE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS\nPROVIDED ON AN \"AS IS\" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO\nOBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR\nMODIFICATIONS.\n\nRESTRICTED RIGHTS: Use, duplication or disclosure by the U.S. government\nis subject to the restrictions as set forth in subparagraph (c) (1) (ii)\nof the Rights in Technical Data and Computer Software Clause as DFARS\n252.227-7013 and FAR 52.227-19.\n\nSPECIAL NOTES:\n\nThis software also falls under the bourbon_ware clause:\n\n    Should you find this software useful in your daily work, you should\n    feel obliged to take the author out for a drink if the opportunity\n    presents itself.  The user may feel exempt from this clause if they\n    are under 21 or think the author has already partaken of too many\n    drinks.\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/README.txt",
    "content": "\n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n  >>>  The following text is the original 'README.txt' of  <<<\n  >>>  vu extension demos.                                 <<<\n  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n##\n## DESCRIPTION OF DEMOS\n##\n\ncanvItems.tcl\n\told demo of all canvas chart items, useful to find memory leaks.\n\t<1> prints out the additional memory usage (charts.so + script)\n\ncanvSticker.tcl\n\tHeribert Dahms original \"demo.tcl\"\n\t<p> creates DEMO.ps\n\ncanvSticker2.tcl\n\tcompares \"sticker\" and \"text\"; press <1>, <2> or <1> ...\n\t<p> creates DEMO.ps\n\ndial.tcl\n\tdemo of variations of the dial widget.\n\nload.tcl\n\tJust a utility file, not a real demo.\n\nm128_000.xbm\n\tXBM pic used by sticker and canvItems demos\n\noscilloscope.tcl\n\tthe heart of a Realtime Oscilloscope,where the PCs joystick\n\tport gives 4 digtal inputs and 4 analog 8 bit values with an\n\tresolution of ~1 millisecond (!!!)  running Realtime Linux.\n\t<p> creates DEMO.ps\n\npie.tcl\n\tThe magic 3D spinning pie chart!\n\nvu.tcl\n\tdemo fo Vu widgets\n\ncanvLabel.tcl\n\t'label' is a canvas item just like 'text', but with -angle\n\trotation of the string.  This is not built in by default, as\n\tit requires the internal Tk headers.\n\tpress <1>, <2> or <1> ...\n\t<p> creates DEMO.ps\n\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/canvItems.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu/charts'\n\n#######################################\n\nxbm = File.join(File.dirname(File.expand_path(__FILE__)), 'm128_000.xbm')\n\nsval = [ 11, 22, 33, 44, 55, 66, 77, 88, 99 ]\n\nl0 = TkLabel.new(:width=>128, :height=>128, \n                 :bitmap=>\"@#{xbm}\", :relief=>:groove).pack(:side=>:left)\n\nc0 = TkCanvas.new(:width=>80, :height=>80, \n                  :insertwidth=>0, :highlightthickness=>0, \n                  :selectborderwidth=>0, :borderwidth=>2, \n                  :relief=>:ridge).place(:in=>l0, :relx=>0.5, :rely=>0.5, \n                                         :anchor=>:c)\n\nst = Tk::Vu::TkcStripchart.new(c0, 3, 3, 80, 80, \n                               :background=>\"#b7c0d7\", :fill=>'slategray3', \n                               :jumpscroll=>1, :outline=>'black', \n                               :scaleline=>'blue', :stripline=>'red', \n                               :selected=>1, :values=>sval)\n\nTkcText.create(c0, 40, 40, \n               :text=>Tk::TCL_PATCHLEVEL, :fill=>'cyan', :tags=>'text')\n\n\nl1 = TkLabel.new(:width=>128, :height=>128, \n                 :bitmap=>\"@#{xbm}\", :relief=>:groove).pack(:side=>:left)\n\nc1 = TkCanvas.new(:width=>80, :height=>80, \n                  :insertwidth=>0, :highlightthickness=>0, \n                  :selectborderwidth=>0, :borderwidth=>2, \n                  :relief=>:ridge).place(:in=>l1, :relx=>0.5, :rely=>0.5, \n                                         :anchor=>:c)\n\nbar1 = Tk::Vu::TkcBarchart.new(c1, 3, 3, 80, 80, \n                               :background=>\"#b7c0d7\", :scalevalue=>10.0, \n                               :autocolor=>true, :selected=>1, \n                               :outline=>'black', :barline=>'yellow', \n                               :scalelinestyle=>0)\n\nbar2 = Tk::Vu::TkcBarchart.new(c1, 53, 3, 80, 80, \n                               :background=>\"#b7c0d7\", :scalevalue=>10.0, \n                               :autocolor=>true, :selected=>1, \n                               :outline=>'black', :fill=>\"#b7c0d7\", \n                               :barline=>'red', :scalelinestyle=>22)\n\n\nl2 = TkLabel.new(:width=>128, :height=>128, \n                 :bitmap=>\"@#{xbm}\", :relief=>:groove).pack(:side=>:left)\n\nc2 = TkCanvas.new(:width=>80, :height=>80, \n                  :insertwidth=>0, :highlightthickness=>0, \n                  :selectborderwidth=>0, :borderwidth=>2, \n                  :relief=>:ridge).place(:in=>l2, :relx=>0.5, :rely=>0.5, \n                                         :anchor=>:c)\n\nbegin\n  stick = Tk::Vu::TkcSticker.new(c2, 3, 3, 80, 80, \n                                 :text=>\"Tcl/Tk\", :space=>0, :color=>'red', \n                                 :outline=>'red', :font=>'Helvetica 14 bold', \n                                 :fill=>'', :stipple=>'', :bar=>'blue', \n                                 :orient=>:vertical, :anchor=>:s, \n                                 :relheight=>1.0, :relwidth=>0.15, \n                                 :relx=>0.1, :rely=>0.0)\nrescue\n  stick = nil\n  TkcText.new(c2, 40, 10, :text=>\"No Sticker Item\")\nend\n\nc_do = proc{\n  st[:values]   = rand() * 100\n\n  bar1[:values] = rand() * 10\n  bar2[:values] = rand() * 10\n\n  stick[:rely]  = rand() * 100 * 0.01 if stick\n}\n\nc0.bind('1', c_do)\n\nTkTimer.new(100, -1, c_do).start\n\nTk.root.bind('q', proc{exit})\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/canvSticker.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu/charts'\n\n#######################################\n\nTk.root.geometry('+30+30')\n\ndelay = 2000\n\nc = TkCanvas.new.pack\n\nbegin\n  st = Tk::Vu::TkcSticker.new(c, 0, 0, 10, 10)\nrescue\n  Tk.messageBox(:type=>'ok', :title=>\"No sticker Item\", \n                :message=>\"This build of vu does not include the sticker item\")\n  exit\nend\n#st.delete\n\nsteps = []\n\nsteps << proc{\n  # I used a 75dpi screen for testing, but others should make no difference!\n  puts 'You\\'ll see a small upright rectangle with \"He\" inside.'\n  st = Tk::Vu::TkcSticker.new(c, '6m', '10m', '13m', '27m', :text=>'Hello')\n}\n\nsteps << proc{\n  puts 'You\\'ll see the whole \"Hello\" drawn rotated 90 degrees.'\n  st[:orient] = :vertical\n}\n\nsteps << proc{\n  puts 'The rectangle shrinks and the text is clipped to \"Hell\"'\n  #st.coords('6m', '10m', '13m', '20m')\n  st.coords('6m', '10m', '13m', '17m')\n}\n\nsteps << proc{\n  puts 'Now you\\'ll read \"ello\"'\n  st[:lefttrunc] = true\n}\n\nsteps << proc{\n  puts 'Enlarging the rectangle shows the complete \"Hello\" again'\n  st.scale(0, 0, 3, 3)\n}\n\nsteps << proc{\n  puts 'This time the text is repeated: \"Hello\", approx. 5mm space, \"Hello\"'\n  st[:space] = '5m'\n}\n\nsteps << proc{\n  puts 'A vertical bar appears in the lower right region and text jumps to the left.'\n  st.configure(:anchor=>:n, :relw=>0.3, :relh=>0.7, \n               :relx=>0.6, :rely=>0.3, :bar=>'red')\n}\n\nsteps << proc{\n  puts 'Paint the backgound.'\n  st[:fill] = 'yellow'\n}\n\nsteps << proc{\n  puts \"Let's test stippling.\"\n  st[:stipple] = 'gray25'\n}\n\nsteps << proc{\n  puts 'Finally a large outline forces a single \"Hello\" and shrinks the bar.'\n  st[:width] = '6m'\n}\n\nTk.root.bind('q', proc{exit})\n\nTkTimer.new(delay, 1, *steps).start\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/canvSticker2.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu/charts'\n\n#######################################\n\nc = TkCanvas.new.pack\n\nbegin\n  st = Tk::Vu::TkcSticker.new(c, 0, 0, 10, 10)\nrescue\n  Tk.messageBox(:type=>'ok', :title=>\"No sticker Item\", \n                :message=>\"This build of vu does not include the sticker item\")\n  exit\nend\n\nc.destroy\n\n#---\n#--- set STRING {{x0 y0 x1 y1} {...text...} {resize point: center}\n\n#sti_conf = [ [10, 10, 180, 180], \"Sticker äöüß@²³¼½¾\",  :center ]\n#txt_conf = [ [210, 210],        \"Text    äöüß@²³¼½¾\",  :center ]\nsti_conf = [ [10, 10, 350, 350], \n             Tk::UTF8_String('Sticker \\u00E4\\u00F6\\u00FC\\u00DF\\u0040\\u00B2\\u00B3\\u00BC\\u00BD\\u00BE'),\n             :center ]\ntxt_conf = [ [250, 250],\n             Tk::UTF8_String('Text    \\u00E4\\u00F6\\u00FC\\u00DF\\u0040\\u00B2\\u00B3\\u00BC\\u00BD\\u00BE'),\n             :center ]\n\n#p sti_conf\n\nfnt = TkFont.new('Helvetica 24 bold')\n\n#---GUI\nc = TkCanvas.new(:width=>500, :height=>500, :bg=>'aquamarine3').pack\n\n#---CRRW Use the technique of eval the coord ...\nsti = Tk::Vu::TkcSticker.new(c, sti_conf[0]){\n  anchor    sti_conf[2]\n  bar       'black'\n  color     'red'\n  fill      ''\n  font      fnt\n  lefttrunc 0\n  outline   ''\n  relheight 0.0\n  relwidth  0.0\n  relx      0.0\n  rely      0.0\n  space     0\n  stipple   ''\n  tags      'sti'\n  text      sti_conf[1]\n  width     0\n  orient    :vertical\n  minwidth  0\n  minheight 0\n  maxwidth  32767\n  maxheight 32767\n}\n\ntxt = TkcText.new(c, txt_conf[0]){\n  activefill      ''\n  activestipple   ''\n  anchor          txt_conf[2]\n  disabledfill    ''\n  disabledstipple ''\n  fill            'blue'\n  font            fnt\n  justify         :left\n  offset          '0,0'\n  state           ''\n  stipple         ''\n  tags            ['tex']\n  text            txt_conf[1]\n  width           0\n}\n\n#---BINDINGS\nc.bind('2', proc{\n         sti[:orient] = :horizontal\n         txt[:width] = 0  # horizontal\n       })\n\nc.bind('3', proc{\n         sti[:orient] = :vertical\n         txt[:width] = 1  # top down\n       })\n\nTk.root.bind('p', proc{\n               c.postscript(:file=>'DEMO.ps')\n               puts \"DEMO.ps printed\"\n             })\n\nTk.root.bind('q', proc{exit})\n\n#####################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/dial_demo.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu/dial'\n\n#######################################\n\nv_volume = TkVariable.new\nv_speed  = TkVariable.new\nv_dir    = TkVariable.new\nv_rot    = TkVariable.new\nv_linked = TkVariable.new\nv_needle = TkVariable.new\n\nvolume = Tk::Vu::Dial.new(:label=>\"Volume\", :from=>-0.1, :to=>0.1, \n                          :resolution=>0.001, :minortickinterval=>0.01, \n                          :tickinterval=>0.1, :beginangle=>-20, \n                          :endangle=>260, :variable=>v_volume)\n\nspeed = Tk::Vu::Dial.new(:label=>\"Speed\", :from=>2000, :to=>100, \n                         :resolution=>10, :tickinterval=>100, \n                         :minortickinterval=>0, :variable=>v_speed, \n                         :showtags=>:label, :showvalue=>false)\n\nspeed.set_tag_constrain(100, 'Fast', 2000, 'Slow')\n\nfwd  = Tk::Vu::Dial.new(:from=>-10.0, :to=>-20.0, :resolution=>0.1, \n                        :tickinterval=>5.0, :minortickinterval=>1.0, \n                        :variable=>v_dir)\n\nrev  = Tk::Vu::Dial.new(:from=>-20.0, :to=>-10.0, :resolution=>0.1, \n                        :tickinterval=>5.0, :minortickinterval=>1.0, \n                        :variable=>v_dir)\n\nsmall = Tk::Vu::Dial.new(:font=>\"Helvetica -10\", :from=>0, :to=>10, \n                         :resolution=>0.05, :tickinterval=>2,\n                         :minortickinterval=>0.5, :radius=>20, \n                         :dialcolor=>'red2', :activebackground=>'red', \n                         :variable=>v_rot)\n\nlarge = Tk::Vu::Dial.new(:font=>\"Helvetica -8\", :from=>0, :to=>10, \n                         :resolution=>0.05, :tickinterval=>1,\n                         :minortickinterval=>0.25, :radius=>40, \n                         :dialcolor=>'red2', :activebackground=>'red', \n                         :variable=>v_rot)\n\nturn = Tk::Vu::Dial.new(:needlecolor=>'red', :label=>\"Linked\", \n                        :variable=>v_linked)\n\nscale = TkScale.new(:label=>\"Linked\", :variable=>v_linked)\n\nd1 = Tk::Vu::Dial.new(:resolution=>0.0001, :from=>-0.1, :to=>0.1, \n                      :showvalue=>true, :minortickinterval=>0.01, \n                      :tickinterval=>0.1, :radius=>30, :label=>\"Dial\", \n                      :beginangle=>-20, :endangle=>260, :variable=>v_needle, \n                      :relief=>:raised)\n\nd2 = Tk::Vu::Dial.new(:resolution=>0.01, :from=>-0.1, :to=>0.1, \n                      :showvalue=>true, :minortickinterval=>0.01, \n                      :tickinterval=>0.1, :radius=>30, :label=>\"Dial 2\", \n                      :beginangle=>-20, :endangle=>260, :variable=>v_needle, \n                      :dialrelief=>:flat, :needlecolor=>'red', \n                      :needletype=>:triangle, :relief=>:sunken)\n\nd3 = Tk::Vu::Dial.new(:resolution=>0.001, :from=>-0.1, :to=>0.1, \n                      :showvalue=>true, :minortickinterval=>0.01, \n                      :tickinterval=>0.1, :radius=>30, :label=>\"Dial 3\", \n                      :beginangle=>-20, :endangle=>260, :variable=>v_needle, \n                      :dialrelief=>:flat, :needlecolor=>'blue', \n                      :needletype=>:arc, :relief=>:ridge)\n\nf_btns = TkFrame.new\nf_sep  = TkFrame.new(:height=>2, :relief=>:sunken, :bd=>1)\n\n\nv_volume.value = -0.1\nv_speed.value = 500\n\nupdate = TkTimer.new(proc{v_speed.numeric}, -1, proc{\n                       if v_volume == volume[:to]\n                         v_volume.numeric = volume[:from]\n                       else\n                         v_volume.numeric += volume[:resolution]\n                       end\n                     })\n\nb_start = TkButton.new(:text=>\"Start\", :command=>proc{update.start})\nb_stop  = TkButton.new(:text=>\"Stop\",  :command=>proc{update.stop})\nb_exit  = TkButton.new(:text=>\"Exit\",  :command=>proc{exit})\n\nTk.grid(b_start, :in=>f_btns, :sticky=>:ew, :padx=>4, :pady=>4)\nTk.grid(b_stop,  :in=>f_btns, :sticky=>:ew, :padx=>4, :pady=>4)\nf_btns.grid_columnconfigure(0, :weight=>1)\n\nTk.grid(f_btns, speed, volume, :sticky=>:news)\nTk.grid(f_sep,  '-',   '-',    :sticky=>:news)\nTk.grid(fwd,    rev,   d1,     :sticky=>:news)\nTk.grid(small,  large, d2,     :sticky=>:news)\nTk.grid(turn,   scale, d3,     :sticky=>:news)\n\nTk.grid(b_exit, '-',   '-',    :sticky=>:ew, :padx=>4, :pady=>4)\n\nTk.root.grid_columnconfigure(0, :weight=>1)\nTk.root.grid_columnconfigure(1, :weight=>1)\nTk.root.grid_columnconfigure(2, :weight=>1)\n\nTk.root.grid_rowconfigure(0, :weight=>1)\nTk.root.grid_rowconfigure(2, :weight=>1)\nTk.root.grid_rowconfigure(3, :weight=>1)\nTk.root.grid_rowconfigure(4, :weight=>1)\n\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/m128_000.xbm",
    "content": "#define m128_000_width 128\n#define m128_000_height 128\nstatic unsigned char m128_000_bits[] = {\n  0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,\n  0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0x03, 0xfc, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xea, 0x0f, 0xfc, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x0f,\n  0xbf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3f, 0x7f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3f, 0xaf, 0xfa, 0xab, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xab, 0x3e,\n  0x5f, 0xf5, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0xf5, 0x57, 0x3d, 0xaf, 0x0e, 0xac, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0e, 0xac, 0x3e, 0x5f, 0x0d, 0x5c, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x0d, 0x5c, 0x3d,\n  0xaf, 0x03, 0xb0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0x03, 0xb0, 0x3e, 0x5f, 0x03, 0x70, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x03, 0x70, 0x3d, 0xaf, 0x03, 0xb0, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x03, 0xb0, 0x3e,\n  0x5f, 0x03, 0x70, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x03, 0x70, 0x3d, 0xaf, 0x03, 0xb0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x03, 0xb0, 0x3e, 0x5f, 0x03, 0x70, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x03, 0x70, 0x3d,\n  0xaf, 0x0e, 0xac, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0x0e, 0xac, 0x3e, 0x5f, 0x0d, 0x5c, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x0d, 0x5c, 0x3d, 0xaf, 0xfa, 0xab, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xab, 0x3e,\n  0x5f, 0xf5, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0xf5, 0x57, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e,\n  0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x3d, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d,\n  0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0x3e, 0x5f, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3d, 0xaf, 0xfa, 0xab, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xab, 0x3e,\n  0x5f, 0xf5, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0xf5, 0x57, 0x3d, 0xaf, 0x0e, 0xac, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0e, 0xac, 0x3e, 0x5f, 0x0d, 0x5c, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x0d, 0x5c, 0x3d,\n  0xaf, 0x03, 0xb0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0x03, 0xb0, 0x3e, 0x5f, 0x03, 0x70, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x03, 0x70, 0x3d, 0xaf, 0x03, 0xb0, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x03, 0xb0, 0x3e,\n  0x5f, 0x03, 0x70, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x03, 0x70, 0x3d, 0xaf, 0x03, 0xb0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x03, 0xb0, 0x3e, 0x5f, 0x03, 0x70, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x03, 0x70, 0x3d,\n  0xaf, 0x0e, 0xac, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0x0e, 0xac, 0x3e, 0x5f, 0x0d, 0x5c, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x0d, 0x5c, 0x3d, 0xaf, 0xfa, 0xab, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xab, 0x3e,\n  0x5f, 0xf5, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0xf5, 0x57, 0x3d, 0xbf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3f, 0x7f, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3f,\n  0xfc, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,\n  0xaa, 0xaa, 0xea, 0x0f, 0xfc, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,\n  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x0f, 0xf0, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,\n  0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0xff,\n  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/oscilloscope.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu/charts'\n\n#---USAGE\ninfo = \"...the heart of a Realtime Oscilloscope, where the PCIs\njoystick port gives 4 digtal inputs and 4 analog 8 bit\nvalues with an resolution of ~1 millisecond (!!!)\nrunning Realtime Linux.\n<p> creates DEMO.ps\n<B1-Motion> see what happens\"\nputs info\n\n#---GEOMETRY\ngeo_fr  = [10, 10, 210, 180]\ngeo_ch0 = [10, 10, 210,  90]\ngeo_ch1 = [10, 90, 210, 180]\ngeo_t1  = [15, 88]\n\n#---GUI\nc = TkCanvas.new(:width=>220, :height=>190).pack(:fill=>:both, :expand=>true)\n\n#---background\nTkcRectangle.new(c, geo_fr, :width=>4, :fill=>'aquamarine3', \n                 :tags=>['osc', 'frbg'])\n\n#---channel 0\nch0 = Tk::Vu::TkcStripchart.new(c, geo_ch0, \n                                :fill=>'', :jumpscroll=>false, \n                                :outline=>'', :scaleline=>'', \n                                :stripline=>'cyan', :tags=>['osc', 'ch0'])\n\n#---channel 1\nch1 = Tk::Vu::TkcStripchart.new(c, geo_ch1, \n                                :fill=>'', :jumpscroll=>0, \n                                :outline=>'', :scaleline=>'', \n                                :stripline=>'red', :tags=>['osc', 'ch1'])\n\n#---frame\nTkcRectangle.new(c, geo_fr, :width=>4, :tags=>['osc', 'frfg'])\n\n#---position\ntxt1 = TkcText.new(c, geo_t1, :text=>\"B1-Motion: X:%X\\tY:%Y\", \n                   :anchor=>:nw, :tags=>['osc', 'txt1'])\n\n#---BINDINGS\nc.bind('B1-Motion', proc{|x, y, xx, yy|\n         ch0[:values] = x\n         ch1[:values] = y\n         txt1[:text] = \"B1-Motion: X:#{xx}\\tY:#{yy}\"\n       }, '%x %y %X %Y')\n\nTk.root.bind('v', proc{\n               puts ch0[:values].join(' ')\n               puts ch0[:values].size\n             })\n\nTk.root.bind('p', proc{\n               c.postscript(:file=>'DEMO.ps')\n               puts \"DEMO.ps printed\"\n             })\n\nTk.root.bind('q', proc{exit})\n\n#####################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/pie.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu/pie'\n\npie = Tk::Vu::Pie.new(:label=>\"My Revolving Budget\"){\n  itemconfigure('Welfare',   :value=>3.004)\n  itemconfigure('Military',  :value=>7.006)\n  itemconfigure('Transport', :value=>1.6, :explode=>15)\n  itemconfigure('Parks',     :value=>0.9)\n  itemconfigure('Schools',   :value=>2)\n  itemconfigure('Debt',      :value=>4,   :explode=>10)\n\n  configure(:angle=>10, :origin=>90, :shadow=>10)\n}\n\nspin = TkTimer.new(60, -1, proc{|obj|\n  pie.configure(:origin=>pie[:origin] + 1)\n})\n\nf = TkFrame.new\nfast_btn = TkButton.new(f, :text=>\"Spin Faster\", :command=>proc{spin.start})\nslow_btn = TkButton.new(f, :text=>\"Spin Slower\", :command=>proc{spin.stop})\nquit_btn = TkButton.new(f, :text=>\"Exit\", :command=>proc{exit})\n\nTk.grid(pie, :sticky=>:news)\nTk.grid(f, :sticky=>:ew)\n\nTk.pack(fast_btn, slow_btn, quit_btn, \n        :in=>f, :side=>:left, :fill=>:both, :expand=>true, :padx=>6, :pady=>4)\n\nTk.root.grid_columnconfigure(0, :weight=>1)\nTk.root.grid_rowconfigure(0, :weight=>1)\n\npriv = { \n  :x=>0, :y=>0, :pie_in=>false, :angle=>pie[:angle], :origin=>pie[:origin]\n}\n\npie.bind('ButtonPress-1', proc{|w, x, y|\n             priv[:x] = x\n             priv[:y] = y\n             priv[:pie_in] = (w.winfo_width/1.8 > x)\n             priv[:angle]  = w[:angle]\n             priv[:origin] = w[:origin]\n         }, '%W %x %y')\n\npie.bind('B1-Motion', proc{|w, x, y|\n           if priv[:pie_in]\n             w.configure(:angle=>priv[:angle] + (priv[:y] - y)/3, \n                         :origin=>(priv[:origin] + \n                                   ((w.winfo_height/2.2 > y)? -1: 1) * \n                                   (priv[:x] - x)/3) % 360)\n           end\n         }, '%W %x %y')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkextlib/vu/vu_demo.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\nrequire 'tkextlib/vu'\n\n#######################################\n\nputs \"Show off barchart and dial widgets\"\n\nspeed = TkVariable.new(0)\n\ndial = Tk::Vu::Dial.new(:resolution=>0.001, :from=>-0.1, :to=>0.1, \n                        :showvalue=>true, :minortickinterval=>0.01, \n                        :tickinterval=>0.1, :radius=>50, :label=>\"Dial\", \n                        :beginangle=>-20, :endangle=>260, :dialcolor=>'red3', \n                        :active=>'red2', :variable=>speed)\n\nbar = Tk::Vu::Bargraph.new(:from=>0, :to=>100, :relief=>:groove, \n                           :border=>2, :label=>\"Bar Chart\")\n\n#######################################\n\ngreen   = 25\nblue    = 50\npurple  = 75\ncurrent = 50\n\ndef rand_bool\n  \nend\n\nupdate = TkTimer.new(200, -1, proc{\n                       if (rand() - 0.5 + speed.numeric * 3) > 0\n                         current += 1\n                       else\n                         current -= 1\n                       end\n                       bar.set(current)\n                       if current < green\n                         current = 100 if current <= 0\n                         bar[:barcolor] = 'green'\n                       elsif current < blue\n                         bar[:barcolor] = 'blue'\n                       elsif current < purple\n                         bar[:barcolor] = 'purple'\n                       else\n                         bar[:barcolor] = 'red'\n                         current = 0 if current >= 100\n                       end\n                     })\n\n#######################################\n\ngobar = TkButton.new(:text=>\"Start\", :command=>proc{update.start})\nnobar = TkButton.new(:text=>\"Stop\",  :command=>proc{update.stop})\nquit  = TkButton.new(:text=>\"Exit\",  :command=>proc{exit})\n\nTk.grid('x', gobar, :sticky=>:ew, :padx=>4, :pady=>4)\nTk.grid(dial, bar, :sticky=>:news)\nTk.grid('x', nobar, :sticky=>:ew, :padx=>4, :pady=>4)\nTk.grid(quit, '-', '-', :sticky=>:ew, :padx=>4, :pady=>4)\nTk.root.grid_columnconfigure(2, :weight=>1)\nTk.root.grid_rowconfigure(1, :weight=>1)\n                       \n#######################################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkfrom.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"parsedate\"\nrequire \"base64\"\n\ninclude ParseDate\n\nclass Mail\n  def Mail.new(f)\n    if !f.kind_of?(IO)\n      f = open(f, \"r\")\n      me = super(f)\n      f.close\n    else\n      me = super\n    end\n    return me\n  end\n\n  def initialize(f)\n    @header = {}\n    @body = []\n    while line = f.gets()\n      $_.chop!\n      next if /^From / =~ line  # skip From-line  \n      break if /^$/ =~ line     # end of header\n      if /^(\\S+):\\s*(.*)/ =~ line\n        @header[attr = $1.capitalize] = $2\n      elsif attr\n        sub(/^\\s*/, '')\n        @header[attr] += \"\\n\" + $_\n      end\n    end\n\n    return unless $_\n\n    while line = f.gets()\n      break if /^From / =~ line\n      @body.push($_)\n    end\n  end\n\n  def header\n    return @header\n  end\n\n  def body\n    return @body\n  end\n\nend\n\nif ARGV.length == 0\n  if ENV['MAIL']\n    ARGV[0] = ENV['MAIL']\n  elsif ENV['USER']\n    ARGV[0] = '/var/spool/mail/' + ENV['USER']\n  elsif ENV['LOGNAME']\n    ARGV[0] = '/var/spool/mail/' + ENV['LOGNAME']\n  end\nend\n\nrequire \"tk\"\nlist = scroll = nil\nTkFrame.new{|f|\n  list = TkListbox.new(f) {\n    yscroll proc{|*idx|\n        scroll.set *idx\n    }\n    relief 'raised'\n#    geometry \"80x5\"\n    width 80\n    height 5\n    setgrid 'yes'\n    pack('side'=>'left','fill'=>'both','expand'=>'yes')\n  }\n  scroll = TkScrollbar.new(f) {\n    command proc{|idx|\n      list.yview *idx\n    }\n    pack('side'=>'right','fill'=>'y')\n  }\n  pack\n}\nroot = Tk.root\nTkButton.new(root) {\n  text 'Dismiss'\n  command proc {exit}\n  pack('fill'=>'both','expand'=>'yes')\n}\nroot.bind \"Control-c\", proc{exit}\nroot.bind \"Control-q\", proc{exit}\nroot.bind \"space\", proc{exit}\n\n$outcount = 0;\nfor file in ARGV\n  next unless File.exist?(file)\n  atime = File.atime(file)\n  mtime = File.mtime(file)\n  f = open(file, \"r\")\n  begin\n    until f.eof\n      mail = Mail.new(f)\n      date = mail.header['Date']\n      next unless date\n      from = mail.header['From']\n      subj = mail.header['Subject']\n      y = m = d = 0\n      y, m, d = parsedate(date) if date\n      from = \"sombody@somewhere\" unless from\n      subj = \"(nil)\" unless subj\n      from = decode_b(from)\n      subj = decode_b(subj)\n      list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj)\n      $outcount += 1\n    end\n  ensure\n    f.close\n    File.utime(atime, mtime, file)\n    list.see 'end'\n  end\nend\n\nlimit = 10000\nif $outcount == 0\n  list.insert 'end', \"You have no mail.\"\n  limit = 2000\nend\nTk.after limit, proc{\n  exit\n}\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkhello.rb",
    "content": "require \"tk\"\n\nTkButton.new(nil, \n             :text => 'hello',\n             :command => proc{print \"hello\\n\"}).pack(:fill=>'x')\nTkButton.new(nil,\n             :text => 'quit',\n             :command => proc{exit}).pack(:fill=>'x')\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkline.rb",
    "content": "\nrequire \"tkclass\"\n\n$tkline_init = FALSE\ndef start_random\n  return if $tkline_init\n  $tkline_init = TRUE\n  if defined? Thread\n    Thread.start do\n      loop do\n        sleep 2\n        Line.new($c, rand(400), rand(200), rand(400), rand(200))\n      end\n    end\n  end\nend\n\nLabel.new('text'=>'Please press or drag button-1').pack\n\n$c = Canvas.new\n$c.pack\n$start_x = start_y = 0\n\ndef do_press(x, y)\n  $start_x = x\n  $start_y = y\n  $current_line = Line.new($c, x, y, x, y)\n  start_random\nend\ndef do_motion(x, y)\n  if $current_line\n    $current_line.coords $start_x, $start_y, x, y\n  end\nend\n\ndef do_release(x, y)\n  if $current_line\n    $current_line.coords $start_x, $start_y, x, y\n    $current_line.fill 'black'\n    $current_line = nil\n  end\nend\n\n$c.bind(\"1\", proc{|e| do_press e.x, e.y})\n$c.bind(\"B1-Motion\", proc{|x, y| do_motion x, y}, \"%x %y\")\n$c.bind(\"ButtonRelease-1\", proc{|x, y| do_release x, y}, \"%x %y\")\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkmenubutton.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  menubutton sample : based on sample menubuttons on the Tcl/Tk demo script\n#\nrequire 'tk'\n\nTkLabel.new(:text=>'Sample of TkMenubutton').pack(:side=>:top)\n\nTkFrame.new{|f|\n  pack(:side=>:top) \n\n\n  TkMenubutton.new(:parent=>f, :text=>'Right', :underline=>0, \n                   :direction=>:right, :relief=>:raised){|mb|\n    menu TkMenu.new(:parent=>mb, :tearoff=>0){\n      add(:command, :label=>'Right menu: first item', \n                    :command=>proc{print 'You have selected the first item' + \n                                         \" from the Right menu.\\n\"})\n      add(:command, :label=>'Right menu: second item', \n                    :command=>proc{print 'You have selected the second item' + \n                                         \" from the Right menu.\\n\"})\n    }\n    pack(:side=>:left, :padx=>25, :pady=>25)\n  }\n\n  TkMenubutton.new(:parent=>f, :text=>'Below', :underline=>0, \n                   :direction=>:below, :relief=>:raised){|mb|\n    menu(TkMenu.new(:parent=>mb, :tearoff=>0){\n      add(:command, :label=>'Below menu: first item', \n                    :command=>proc{print 'You have selected the first item' + \n                                         \" from the Below menu.\\n\"})\n      add(:command, :label=>'Below menu: second item', \n                    :command=>proc{print 'You have selected the second item' + \n                                         \" from the Below menu.\\n\"})\n    })\n    pack(:side=>:left, :padx=>25, :pady=>25)\n  }\n\n  TkMenubutton.new(:parent=>f, :text=>'Above', :underline=>0, \n                   :direction=>:above, :relief=>:raised){|mb|\n    menu TkMenu.new(:parent=>mb, :tearoff=>0){\n      add(:command, :label=>'Above menu: first item', \n                    :command=>proc{print 'You have selected the first item' + \n                                         \" from the Above menu.\\n\"})\n      add(:command, :label=>'Above menu: second item', \n                    :command=>proc{print 'You have selected the second item' + \n                                         \" from the Above menu.\\n\"})\n    }\n    pack(:side=>:left, :padx=>25, :pady=>25)\n  }\n\n  TkMenubutton.new(:parent=>f, :text=>'Left', :underline=>0, \n                   :direction=>:left, :relief=>:raised){|mb|\n    menu(TkMenu.new(:parent=>mb, :tearoff=>0){\n      add(:command, :label=>'Left menu: first item', \n                    :command=>proc{print 'You have selected the first item' + \n                                         \" from the Left menu.\\n\"})\n      add(:command, :label=>'Left menu: second item', \n                    :command=>proc{print 'You have selected the second item' + \n                                         \" from the Left menu.\\n\"})\n    })\n    pack(:side=>:left, :padx=>25, :pady=>25)\n  }\n}\n\n############################\nTkFrame.new(:borderwidth=>2, :relief=>:sunken, \n            :height=>5).pack(:side=>:top, :fill=>:x, :padx=>20)\n############################\n\nTkLabel.new(:text=>'Sample of TkOptionMenu').pack(:side=>:top)\n\ncolors = %w(Black red4 DarkGreen NavyBlue gray75 Red Green Blue gray50 \n            Yellow Cyan Magenta White Brown DarkSeaGreen DarkViolet)\n\nTkFrame.new{|f|\n  pack(:side=>:top) \n\n  b1 = TkOptionMenubutton . \n    new(:parent=>f, :values=>%w(one two three)) . \n    pack(:side=>:left, :padx=>25, :pady=>25)\n\n  b2 = TkOptionMenubutton.new(:parent=>f, :values=>colors) {|optMB|\n    colors.each{|color|\n      no_sel = TkPhotoImage.new(:height=>16, :width=>16){\n        put 'gray50', *[ 0,  0, 16,  1]\n        put 'gray50', *[ 0,  1,  1, 16]\n        put 'gray75', *[ 0, 15, 16, 16]\n        put 'gray75', *[15,  1, 16, 16]\n        put color,    *[ 1,  1, 15, 15]\n      }\n      sel = TkPhotoImage.new(:height=>16, :width=>16){\n        put 'Black',  *[ 0,  0, 16,  2]\n        put 'Black',  *[ 0,  2,  2, 16]\n        put 'Black',  *[ 2, 14, 16, 16]\n        put 'Black',  *[14,  2, 16, 14]\n        put color,    *[ 2,  2, 14, 14]\n      }\n      optMB.entryconfigure(color, :hidemargin=>1, \n                           :image=>no_sel, :selectimage=>sel)\n    }\n    optMB.menuconfigure(:tearoff, 1)\n    %w(Black gray75 gray50 White).each{|color|\n      optMB.entryconfigure(color, :columnbreak=>true)\n    }\n    pack(:side=>:left, :padx=>25, :pady=>25)\n  }\n\n  TkButton.new(:parent=>f){\n    text 'show values'\n    command proc{p [b1.value, b2.value]}\n    pack(:side=>:left, :padx=>25, :pady=>5, :anchor=>:s)\n  }\n}\n\n############################\nTkFrame.new(:borderwidth=>2, :relief=>:sunken, \n            :height=>5).pack(:side=>:top, :fill=>:x, :padx=>20)\n############################\n\nroot = TkRoot.new(:title=>'menubutton samples')\n\nTkButton.new(root, :text=>'exit', :command=>proc{exit}){\n  pack(:side=>:top, :padx=>25, :pady=>5, :anchor=>:e)\n}\n\n# VirtualEvent <<MenuSelect>> on Tcl/Tk ==> '<MenuSelect>' on Ruby/Tk\n# ( remove the most external <, > for Ruby/Tk notation )\nTkMenu.bind('<MenuSelect>', proc{|widget|\n              p widget.entrycget('active', :label)\n            }, '%W')\n\n############################\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkmsgcat-load_rb.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\n\ndemo_dir = File.dirname($0)\nmsgcat_dir = [demo_dir, 'msgs_rb'].join(File::Separator)\ntop_win = nil\n#msgcat = TkMsgCatalog.new('::tk')\nmsgcat = TkMsgCatalog.new('::tkmsgcat_demo')\ndefault_locale = msgcat.locale\n#msgcat.load_rb(msgcat_dir)\nmsgcat.load(msgcat_dir)\n\ncol_proc = TkComm.install_bind(proc{|w, color, frame, label|\n                                 TkComm.window(frame).background(color)\n                                 Tk.update\n                                 TkComm.window(label).text(\n                                          msgcat[\"%1$s:: %2$s\", 'Color', \n                                                 color.capitalize])\n                                 w.flash; w.flash\n                                 Tk.callback_break;\n                              }, \"%W\")\n\ndel_proc = TkComm.install_cmd(proc{top_win.destroy; top_win = nil})\n\nerr_proc = TkComm.install_cmd(proc{fail(RuntimeError, \n                                        msgcat['Application Error'])})\n\nshow_sample = proc{|loc|\n  top_win = TkToplevel.new(:title=>loc)\n\n  msgcat.locale = loc\n  #msgcat.load_rb(msgcat_dir)\n  msgcat.load(msgcat_dir)\n\n  TkLabel.new(top_win){\n    text \"preferences:: #{msgcat.preferences.join(' ')}\"\n    pack(:pady=>10, :padx=>10)\n  }\n\n  lbl = TkLabel.new(top_win, :text=>msgcat[\"%1$s:: %2$s\", \n                                           'Color', '']).pack(:anchor=>'w')\n\n  bg = TkFrame.new(top_win).pack(:ipadx=>20, :ipady=>10, \n                                 :expand=>true, :fill=>:both)\n\n  TkFrame.new(bg){|f|\n    ['blue', 'green', 'red'].each{|col|\n      TkButton.new(f, :text=>msgcat[col]){\n        bind('ButtonRelease-1', col_proc, \"#{col} #{bg.path} #{lbl.path}\")\n      }.pack(:fill=>:x)\n    }\n  }.pack(:anchor=>'center', :pady=>15)\n\n  TkFrame.new(top_win){|f|\n    TkButton.new(f, :text=>msgcat['Delete'], \n                 :command=>del_proc).pack(:side=>:right, :padx=>5)\n    TkButton.new(f, :text=>msgcat['Error'], \n                 :command=>err_proc).pack(:side=>:left, :padx=>5)\n  }.pack(:side=>:bottom, :fill=>:x)\n\n  top_win\n}\n\n\n#  listbox for locale list\nTkLabel.new(:text=>\"Please click a locale.\").pack(:padx=>5, :pady=>3)\n\nTkFrame.new{|f|\n  TkButton.new(f, :text=>msgcat['Exit'], \n               :command=>proc{exit}).pack(:side=>:right, :padx=>5)\n}.pack(:side=>:bottom, :fill=>:x)\n\nf = TkFrame.new.pack(:side=>:top, :fill=>:both, :expand=>true)\nlbox = TkListbox.new(f).pack(:side=>:left, :fill=>:both, :expand=>true)\nlbox.yscrollbar(TkScrollbar.new(f, :width=>12).pack(:side=>:right, :fill=>:y))\n\nlbox.bind('ButtonRelease-1'){|ev|\n  idx = lbox.index(\"@#{ev.x},#{ev.y}\")\n  if idx == 0\n    loc = default_locale\n  else\n    loc = lbox.get(idx)\n  end\n  if top_win != nil && top_win.exist?\n    top_win.destroy\n  end\n  top_win = show_sample.call(loc)\n}\n\nlbox.insert('end', 'default')\n\nDir.entries(msgcat_dir).sort.each{|f| \n  if f =~ /^(.*).msg$/\n    lbox.insert('end', $1)\n  end\n}\n\ntop_win = show_sample.call(default_locale)\n\n#  start eventloop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkmsgcat-load_rb2.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\n\ndemo_dir = File.dirname($0)\nmsgcat_dir = [demo_dir, 'msgs_rb2'].join(File::Separator)\ntop_win = nil\n#msgcat = TkMsgCatalog.new('::tk')\nmsgcat = TkMsgCatalog.new('::tkmsgcat_demo')\ndefault_locale = msgcat.locale\n#msgcat.load_rb(msgcat_dir)\nmsgcat.load(msgcat_dir)\n\ncol_proc = TkComm.install_bind(proc{|w, color, frame, label|\n                                 TkComm.window(frame).background(color)\n                                 Tk.update\n                                 TkComm.window(label).text(\n                                          msgcat[\"%1$s:: %2$s\", 'Color', \n                                                 color.capitalize])\n                                 w.flash; w.flash\n                                 Tk.callback_break;\n                              }, \"%W\")\n\ndel_proc = TkComm.install_cmd(proc{top_win.destroy; top_win = nil})\n\nerr_proc = TkComm.install_cmd(proc{fail(RuntimeError, \n                                        msgcat['Application Error'])})\n\nshow_sample = proc{|loc|\n  top_win = TkToplevel.new(:title=>loc)\n\n  msgcat.locale = loc\n  #msgcat.load_rb(msgcat_dir)\n  msgcat.load(msgcat_dir)\n\n  TkLabel.new(top_win){\n    text \"preferences:: #{msgcat.preferences.join(' ')}\"\n    pack(:pady=>10, :padx=>10)\n  }\n\n  lbl = TkLabel.new(top_win, :text=>msgcat[\"%1$s:: %2$s\", \n                                           'Color', '']).pack(:anchor=>'w')\n\n  bg = TkFrame.new(top_win).pack(:ipadx=>20, :ipady=>10, \n                                 :expand=>true, :fill=>:both)\n\n  TkFrame.new(bg){|f|\n    ['blue', 'green', 'red'].each{|col|\n      TkButton.new(f, :text=>msgcat[col]){\n        bind('ButtonRelease-1', col_proc, \"#{col} #{bg.path} #{lbl.path}\")\n      }.pack(:fill=>:x)\n    }\n  }.pack(:anchor=>'center', :pady=>15)\n\n  TkFrame.new(top_win){|f|\n    TkButton.new(f, :text=>msgcat['Delete'], \n                 :command=>del_proc).pack(:side=>:right, :padx=>5)\n    TkButton.new(f, :text=>msgcat['Error'], \n                 :command=>err_proc).pack(:side=>:left, :padx=>5)\n  }.pack(:side=>:bottom, :fill=>:x)\n\n  top_win\n}\n\n\n#  listbox for locale list\nTkLabel.new(:text=>\"Please click a locale.\").pack(:padx=>5, :pady=>3)\n\nTkFrame.new{|f|\n  TkButton.new(f, :text=>msgcat['Exit'], \n               :command=>proc{exit}).pack(:side=>:right, :padx=>5)\n}.pack(:side=>:bottom, :fill=>:x)\n\nf = TkFrame.new.pack(:side=>:top, :fill=>:both, :expand=>true)\nlbox = TkListbox.new(f).pack(:side=>:left, :fill=>:both, :expand=>true)\nlbox.yscrollbar(TkScrollbar.new(f, :width=>12).pack(:side=>:right, :fill=>:y))\n\nlbox.bind('ButtonRelease-1'){|ev|\n  idx = lbox.index(\"@#{ev.x},#{ev.y}\")\n  if idx == 0\n    loc = default_locale\n  else\n    loc = lbox.get(idx)\n  end\n  if top_win != nil && top_win.exist?\n    top_win.destroy\n  end\n  top_win = show_sample.call(loc)\n}\n\nlbox.insert('end', 'default')\n\nDir.entries(msgcat_dir).sort.each{|f| \n  if f =~ /^(.*).msg$/\n    lbox.insert('end', $1)\n  end\n}\n\ntop_win = show_sample.call(default_locale)\n\n#  start eventloop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkmsgcat-load_tk.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'tk'\n\ndemo_dir = File.dirname($0)\nmsgcat_dir = [demo_dir, 'msgs_tk'].join(File::Separator)\ntop_win = nil\n#msgcat = TkMsgCatalog.new('::tk')\nmsgcat = TkMsgCatalog.new('::tkmsgcat_demo')\ndefault_locale = msgcat.locale\nmsgcat.load_tk(msgcat_dir)\n\ncol_proc = TkComm.install_bind(proc{|w, color, frame, label|\n                                 TkComm.window(frame).background(color)\n                                 Tk.update\n                                 TkComm.window(label).text(\n                                          msgcat.mc(\"%1$s:: %2$s\", 'Color', \n                                                    color.capitalize))\n                                 w.flash; w.flash\n                                 Tk.callback_break;\n                              }, \"%W\")\n\ndel_proc = TkComm.install_cmd(proc{top_win.destroy; top_win = nil})\n\nerr_proc = TkComm.install_cmd(proc{fail(RuntimeError, \n                                        msgcat.mc('Application Error'))})\n\nshow_sample = proc{|loc|\n  top_win = TkToplevel.new(:title=>loc)\n\n  msgcat.locale = loc\n  msgcat.load_tk(msgcat_dir)\n\n  TkLabel.new(top_win){\n    text \"preferences:: #{msgcat.preferences.join(' ')}\"\n    pack(:pady=>10, :padx=>10)\n  }\n\n  lbl = TkLabel.new(top_win, :text=>msgcat.mc(\"%1$s:: %2$s\", \n                                              'Color', '')).pack(:anchor=>'w')\n\n  bg = TkFrame.new(top_win).pack(:ipadx=>20, :ipady=>10, \n                                 :expand=>true, :fill=>:both)\n\n  TkFrame.new(bg){|f|\n    ['blue', 'green', 'red'].each{|col|\n      TkButton.new(f, :text=>msgcat.mc(col)){\n        bind('ButtonRelease-1', col_proc, \"#{col} #{bg.path} #{lbl.path}\")\n      }.pack(:fill=>:x)\n=begin\n      TkButton.new(f, :text=>msgcat.mc(col), \n                   :command=>proc{\n                     bg.background col\n                     lbl.text msgcat.mc(\"%1$s:: %2$s\", 'Color', col.capitalize)\n                   }).pack(:fill=>:x)\n=end\n    }\n  }.pack(:anchor=>'center', :pady=>15)\n\n  TkFrame.new(top_win){|f|\n    TkButton.new(f, :text=>msgcat.mc('Delete'), \n                 :command=>del_proc).pack(:side=>:right, :padx=>5)\n    TkButton.new(f, :text=>msgcat.mc('Error'), \n                 :command=>err_proc).pack(:side=>:left, :padx=>5)\n=begin\n    TkButton.new(f, :text=>msgcat.mc('Delete'), \n                 :command=>proc{\n                   top_win.destroy\n                   top_win = nil\n                 }).pack(:side=>:right, :padx=>5)\n    TkButton.new(f, :text=>msgcat.mc('Error'), \n                 :command=>proc{\n                   fail RuntimeError, msgcat.mc('Application Error')\n                 }).pack(:side=>:left, :padx=>5)\n=end\n  }.pack(:side=>:bottom, :fill=>:x)\n\n  top_win\n}\n\n\n#  listbox for locale list\nTkLabel.new(:text=>\"Please click a locale.\").pack(:padx=>5, :pady=>3)\n\nTkFrame.new{|f|\n  TkButton.new(f, :text=>msgcat.mc('Exit'), \n               :command=>proc{exit}).pack(:side=>:right, :padx=>5)\n}.pack(:side=>:bottom, :fill=>:x)\n\nf = TkFrame.new.pack(:side=>:top, :fill=>:both, :expand=>true)\nlbox = TkListbox.new(f).pack(:side=>:left, :fill=>:both, :expand=>true)\nlbox.yscrollbar(TkScrollbar.new(f, :width=>12).pack(:side=>:right, :fill=>:y))\n\nlbox.bind('ButtonRelease-1'){|ev|\n  idx = lbox.index(\"@#{ev.x},#{ev.y}\")\n  if idx == 0\n    loc = default_locale\n  else\n    loc = lbox.get(idx)\n  end\n  if top_win != nil && top_win.exist?\n    top_win.destroy\n  end\n  top_win = show_sample.call(loc)\n}\n\nlbox.insert('end', 'default')\n\nDir.entries(msgcat_dir).sort.each{|f| \n  if f =~ /^(.*).msg$/\n    lbox.insert('end', $1)\n  end\n}\n\ntop_win = show_sample.call(default_locale)\n\n#  start eventloop\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkmulticolumnlist.rb",
    "content": "#\n# tkmulticolumnlist.rb : multiple column list widget on scrollable frame\n#                        by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass TkMultiColumnList < TkText\n  include TkComposite\n\n  #   lbox_height : height of listboxes (pixel)\n  #   title_info  : array [ [<title_string>,<init_width>], ... ]\n  #   keys        : hash {<option>=><value>, ... }\n  def initialize_composite(lbox_height, title_info, keys={})\n    # argument check\n    if (! title_info.kind_of? Array) or (title_info.size < 2)\n      raise\n    end\n\n    # mode\n    @keep_minsize = true\n    @show_each_hscr = true\n    @show_win_hscr = true\n\n    # init arrays\n    @base_list  = []\n    @rel_list   = []\n    @title_list = []\n    @title_cmd  = []\n    @lbox_list  = []\n    @hscr_list  = []\n\n    # decide total width\n    @lbox_total = title_info.size\n    @width_total = 0\n    title_info.each{|title, width, cmd| \n      @width_total += width.to_f\n      @title_cmd << cmd\n    }\n\n    # rel-table of label=>index\n    @name_index = {}\n\n    # size definition\n    @window_width = @width_total\n    @sash = 5\n    @scrbar_width = 15\n    @scrbar_border = 3\n    @lbox_border = 1\n    @title_border = 3\n    @h_l_thick = 0\n\n    # init status\n    @mode = :title\n    @command = nil\n\n    # virtical scrollbar\n    @v_scroll = TkYScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, \n                                 'borderwidth'=>@scrbar_border, \n                                 'width'=>@scrbar_width)\n\n    # horizontal scrollbar\n    @h_scroll = TkXScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, \n                                 'borderwidth'=>@scrbar_border, \n                                 'width'=>@scrbar_width)\n\n    # create base flames\n    @c_title = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, \n                            'width'=>@window_width)\n    @f_title = TkFrame.new(@c_title, 'width'=>@width_total)\n    @w_title = TkcWindow.new(@c_title, 0, 0, \n                             'window'=>@f_title, 'anchor'=>'nw')\n\n    @c_lbox  = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, \n                            'width'=>@window_width)\n    @f_lbox  = TkFrame.new(@c_lbox, 'width'=>@width_total)\n    @w_lbox  = TkcWindow.new(@c_lbox, 0, 0, 'window'=>@f_lbox, 'anchor'=>'nw')\n\n    @c_hscr  = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, \n                            'width'=>@window_width)\n    @f_hscr  = TkFrame.new(@c_hscr, 'width'=>@width_total)\n    @w_hscr  = TkcWindow.new(@c_hscr, 0, 0, 'window'=>@f_hscr, 'anchor'=>'nw')\n\n    # create each listbox\n    sum = 0.0\n    @rel_list << sum/@width_total\n    title_info.each_with_index{|(label, width), idx|\n      # set relation between label and index\n      if @name_index.include?(label)\n        @name_index[label] << idx\n      else\n        @name_index[label] = [idx]\n      end\n\n      # calculate relative positioning\n      sum += width\n      @rel_list << sum/@width_total\n\n      # title field\n      f = TkFrame.new(@f_title, 'width'=>width)\n      base = [f]\n\n      title = TkLabel.new(f, 'text'=>label, 'borderwidth'=>@title_border, \n                          'relief'=>'raised', 'highlightthickness'=>@h_l_thick)\n      title_binding(title, idx)\n      title.pack('fill'=>'x')\n\n      @title_list << title\n\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, \n              'relheight'=>1.0, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n      # listbox field\n      f = TkFrame.new(@f_lbox, 'width'=>width)\n      base << f\n      @lbox_list << TkText.new(f, 'highlightthickness'=>@h_l_thick, \n                               'borderwidth'=>@lbox_border, \n                               'takefocus'=>false, \n                               'wrap'=>'none') {\n\n        bindtags(bindtags - [TkText])\n\n        @seltag = TkTextTag.new(self, 'background'=>'#b3b3b3', \n                                'borderwidth'=>1, 'relief'=>'raised')\n        def self.nearest(y)\n          self.index(\"@1,#{y}\").split('.')[0].to_i\n        end\n\n        def self.select_clear(first, last=nil)\n          first = \"#{first}.0\" if first.kind_of?(Integer)\n          first = self.index(first.to_s + ' linestart')\n          last = first unless last\n          last = \"#{last}.0\" if first.kind_of?(Integer)\n          last = self.index(last.to_s + ' + 1 lines linestart')\n          @seltag.remove(first, last)\n        end\n\n        def self.select_set(first, last=nil)\n          first = \"#{first}.0\" if first.kind_of?(Integer)\n          first = self.index(first.to_s + ' linestart')\n          last = first unless last\n          last = \"#{last}.0\" if first.kind_of?(Integer)\n          last = self.index(last.to_s + ' + 1 lines linestart')\n          @seltag.add(first, last)\n        end\n\n        def self.select_index\n          self.index(@seltag.first).split('.')[0].to_i\n        end\n\n        pack('fill'=>'both', 'expand'=>true)\n      }\n\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx], 'relheight'=>1.0)\n\n      # scrollbar field\n      f = TkFrame.new(@f_hscr, 'width'=>width)\n      base << f\n      @hscr_list << TkXScrollbar.new(f, 'width'=>@scrbar_width, \n                                     'borderwidth'=>@scrbar_border, \n                                     'highlightthickness'=>@h_l_thick\n                                    ).pack('fill'=>'x', 'anchor'=>'w')\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n      @lbox_list[idx].xscrollbar(@hscr_list[idx])\n\n      # add new base\n      @base_list << base\n    }\n\n    # pad\n    @f_title_pad = TkFrame.new(@frame, 'relief'=>'raised', \n                               'borderwidth'=>@title_border, \n                               'highlightthickness'=>@h_l_thick)\n\n    @f_scr_pad = TkFrame.new(@frame, 'relief'=>'sunken', \n                             'borderwidth'=>1, \n                             'highlightthickness'=>@h_l_thick)\n\n    # height check\n    title_height = 0\n    @title_list.each{|w| \n      h = w.winfo_reqheight\n      title_height = h if title_height < h\n    }\n\n    hscr_height = 0\n    @hscr_list.each{|w| \n      h = w.winfo_reqheight\n      hscr_height = h if hscr_height < h\n    }\n\n    @f_title.height title_height\n    @f_lbox.height lbox_height\n    @f_hscr.height hscr_height\n\n    # set control procedure for virtical scroll\n    @v_scroll.assign(*@lbox_list)\n\n    # set control procedure for horizoncal scroll\n    @h_scroll.assign(@c_title, @c_lbox, @c_hscr)\n\n    # binding for listboxes\n    @lbox_list.each_with_index{|l, idx| \n      l.bind('Button-1', proc{|w, y| \n               @frame.focus\n               select_line(w, w.nearest(y))\n             }, '%W %y')\n      l.bind('B1-Motion', proc{|w, y| \n               select_line(w, w.nearest(y))\n             }, '%W %y')\n      l.bind('Double-Button-1', proc{\n               @command.call(get_select) if @command\n             })\n\n      l.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W')\n      l.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W')\n\n      l.bind('Button-2', proc{|x, y| \n               @lbox_mark_x = x\n               @lbox_list.each{|lbox| lbox.scan_mark(x, y)}\n             }, '%x %y')\n      l.bind('B2-Motion', proc{|x, y| \n               @lbox_list.each{|lbox| lbox.scan_dragto(@lbox_mark_x, y)}\n               l.scan_dragto(x, y)\n             }, '%x %y')\n    }\n\n    bbox = @w_title.bbox\n    @c_title.height(bbox[3])\n    @c_title.scrollregion(bbox)\n\n    bbox = @w_lbox.bbox\n    @c_lbox.height(bbox[3])\n    @c_lbox.scrollregion(bbox)\n\n    if @show_each_hscr\n      bbox = @w_hscr.bbox\n      @c_hscr.height(bbox[3])\n      @c_hscr.scrollregion(bbox)\n    end\n\n    # binding\n    @frame.takefocus(true)\n    @frame.bind('Key-Up', proc{select_shift(@lbox_list[0], -1)})\n    @frame.bind('Key-Down', proc{select_shift(@lbox_list[0], 1)})\n    @frame.bind('Return', proc{@command.call(get_select) if @command})\n\n    # alignment\n    TkGrid.rowconfigure(@frame, 0, 'weight'=>0)\n    TkGrid.rowconfigure(@frame, 1, 'weight'=>1)\n    TkGrid.rowconfigure(@frame, 2, 'weight'=>0)\n    TkGrid.rowconfigure(@frame, 3, 'weight'=>0)\n    TkGrid.columnconfigure(@frame, 0, 'weight'=>1)\n    TkGrid.columnconfigure(@frame, 1, 'weight'=>0)\n    TkGrid.columnconfigure(@frame, 2, 'weight'=>0)\n    @v_scroll.grid('row'=>1, 'column'=>2, 'sticky'=>'ns')\n    @c_title.grid('row'=>0, 'column'=>0, 'sticky'=>'news')\n    @f_title_pad.grid('row'=>0, 'column'=>2, 'sticky'=>'news')\n    @c_lbox.grid('row'=>1, 'column'=>0, 'sticky'=>'news')\n    @c_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew') if @show_each_hscr\n    @h_scroll.grid('row'=>3, 'column'=>0, 'sticky'=>'ew') if @show_win_hscr\n    @f_scr_pad.grid('row'=>2, 'rowspan'=>2, 'column'=>2, 'sticky'=>'news')\n\n    # binding for 'Configure' event\n    @c_lbox.bind('Configure', \n                 proc{|height, width| reconstruct(height, width)}, \n                 '%h %w')\n\n    # set default receiver of method calls\n    @path = @frame.path\n\n    # configure options\n    keys = {} unless keys\n    keys = _symbolkey2str(keys)\n\n    # command\n    cmd = keys.delete('command')\n    command(cmd) if cmd\n\n    # 'scrollbarwidth' option == 'width' option of scrollbars\n    width = keys.delete('scrollbarwidth')\n    scrollbarwidth(width) if width\n\n    # options for listbox titles\n    title_font = keys.delete('titlefont')\n    titlefont(title_font) if title_font\n\n    title_fg = keys.delete('titleforeground')\n    titleforeground(title_fg) if title_fg\n\n    title_bg = keys.delete('titlebackground')\n    titlebackground(title_bg) if title_bg\n\n    # set receivers for configure methods\n    delegate('DEFAULT', *@lbox_list)\n    delegate('activebackground', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('troughcolor', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('repeatdelay', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('repeatinterval', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('borderwidth', @frame)\n    delegate('width', @c_lbox, @c_title, @c_hscr)\n    delegate('relief', @frame)\n\n    # configure\n    configure(keys) if keys.size > 0\n  end\n  private :initialize_composite\n\n  # keep_minsize?\n  def keep_minsize?\n    @keep_minsize\n  end\n  def keep_minsize(bool)\n    @keep_minsize = bool\n  end\n\n  # each hscr\n  def show_each_hscr\n    @show_each_hscr = true\n    @c_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew')\n  end\n  def hide_each_hscr\n    @show_each_hscr = false\n    @c_hscr.ungrid\n  end\n\n  # window hscroll\n  def show_win_hscr\n    @show_win_hscr = true\n    @h_scroll.grid('row'=>3, 'column'=>0, 'sticky'=>'ew')\n  end\n  def hide_win_hscr\n    @show_each_hscr = false\n    @h_scroll.ungrid\n  end\n\n  # set command\n  def command(cmd)\n    @command = cmd\n    self\n  end\n\n  # set scrollbar width\n  def scrollbarwidth(width)\n    @scrbar_width = width\n    @v_scroll['width'] = @scrbar_width\n    @h_scroll['width'] = @scrbar_width\n    @hscr_list.each{|hscr| hscr['width'] = @scrbar_width}\n    self\n  end\n\n  # set scrollbar border\n  def scrollbarborder(width)\n    @scrbar_border = width\n    @v_scroll['border'] = @scrbar_border\n    @h_scroll['border'] = @scrbar_border\n    @hscr_list.each{|hscr| hscr['border'] = @scrbar_border}\n    self\n  end\n\n  # set listbox borders\n  def listboxborder(width)\n    @lbox_border = width\n    @lbox_list.each{|w| w['border'] = @lbox_border}\n    self\n  end\n\n  # set listbox relief\n  def listboxrelief(relief)\n    @lbox_list.each{|w| w['relief'] = relief}\n    self\n  end\n\n  # set title borders\n  def titleborder(width)\n    @title_border = width\n    @f_title_pad['border'] = @title_border\n    @title_list.each{|label| label['border'] = @title_border}\n    self\n  end\n\n  # set title font\n  def titlefont(font)\n    @title_list.each{|label| label['font'] = font}\n    title_height = 0\n    @title_list.each{|w| \n      h = w.winfo_reqheight\n      title_height = h if title_height < h\n    }\n    @f_title.height title_height\n    bbox = @w_title.bbox\n    @c_title.height(bbox[3])\n    @c_title.scrollregion(bbox)\n    self\n  end\n\n  # set title foreground color\n  def titleforeground(fg)\n    @title_list.each{|label| label['foreground'] = fg}\n    self\n  end\n\n  # set title background color\n  def titlebackground(bg)\n    @f_title_pad['background'] = bg\n    @title_list.each{|label| label['background'] = bg}\n    self\n  end\n\n  # set title cmds\n  def titlecommand(idx, cmd=Proc.new)\n    @title_cmd[idx] = cmd\n  end\n\n  # call title cmds\n  def titleinvoke(idx)\n    @title_cmd[idx].call if @title_cmd[idx]\n  end\n\n  # get label widgets of listbox titles\n  def titlelabels(*indices)\n    @title_list[*indices]\n  end\n\n  # get listbox widgets\n  def columns(*indices)\n    @lbox_list[*indices]\n  end\n\n  def delete(*idx)\n    idx = idx.collect{|i|\n      if i.kind_of?(Integer)\n        \"#{i}.0\"\n      else\n        i.to_s\n      end\n    }\n    @lbox_list.collect{|lbox| lbox.delete(*idx)}\n  end\n\n  def get(idx_s, idx_e=nil)\n    unless idx_e\n      if idx_s.kind_of?(Integer)\n        idx_s = \"#{idx_s}.0\"\n        idx_e = \"#{idx_s} lineend\"\n      else\n        idx_s = idx_s.to_s\n        idx_e = \"#{idx_s} lineend\"\n      end\n      @lbox_list.collect{|lbox|\n        lbox.get(idx_s, idx_e)\n      }\n    else\n      if idx_s.kind_of?(Integer)\n        idx_s = \"#{idx_s}.0\"\n      else\n        idx_s = idx_s.to_s\n      end\n      if idx_e.kind_of?(Integer)\n        idx_e = \"#{idx_e}.end\"\n      else\n        idx_e = \"#{idx_e} lineend\"\n      end\n      list = @lbox_list.collect{|lbox| lbox.get(idx_s, idx_e).split(/\\n/)}\n      result = []\n      list[0].each_with_index{|line, index|\n        result << list.collect{|lines| lines[index]}\n      }\n      result\n    end\n  end\n\n  def get_select\n    get(@lbox_list[0].select_index)\n  end\n\n  def _line_array_to_hash(line)\n    result = {}\n    @name_index.each_pair{|label, indices|\n      if indices.size == 1\n        result[label] = line[indices[0]]\n      else\n        result[label] = indices.collect{|index| line[index]}\n      end\n    }\n    result\n  end\n  private :_line_array_to_hash\n\n  def get_by_hash(*idx)\n    get_result = get(*idx)\n    if idx.size == 1\n      _line_array_to_hash(get_result)\n    else\n      get_result.collect{|line| _line_array_to_hash(line)}\n    end\n  end\n\n  def insert(idx, *lines)\n    lbox_ins = []\n    (0..@lbox_list.size).each{lbox_ins << []}\n\n    if idx.kind_of?(Integer)\n      idx = \"#{idx}.0\"\n    else\n      idx = idx.to_s\n    end\n\n    if @lbox_list[0].index('1.0 + 1 char') == @lbox_list[0].index('end')\n      cr = \"\"\n    else\n      cr = \"\\n\"\n    end\n\n    lines.each{|line|\n      if line.kind_of? Hash\n        array = []\n        @name_index.each_pair{|label, indices|\n          if indices.size == 1\n            array[indices[0]] = line[label]\n          else\n            if line[label].kind_of? Array\n              indices.each_with_index{|index, num| \n                array[index] = line[label][num]\n              }\n            else\n              array[indices[0]] = line[label]\n            end\n          end\n        }\n        line = array\n      end\n\n      @name_index.each_pair{|label, indices|\n        if indices.size == 1\n          lbox_ins[indices[0]] << line[indices[0]]\n        else\n          indices.each{|index| lbox_ins[index] << line[index]}\n        end\n      }\n    }   \n\n    @lbox_list.each_with_index{|lbox, index| \n      lbox.insert(idx, cr + lbox_ins[index].join(\"\\n\")) if lbox_ins[index]\n    }\n  end\n\n  def select_clear(first, last=None)\n    @lbox_list.each{|lbox| lbox.sel_clear(first, last=None)}\n  end\n\n  def select_set(first, last=None)\n    @lbox_list.each{|lbox| lbox.sel_set(first, last=None)}\n  end\n\n  ###########################################\n  private\n\n  def reconstruct(height, width)\n    if @keep_minsize && width <= @width_total\n      @f_title.width(@width_total)\n      @f_lbox.width(@width_total)\n      @f_hscr.width(@width_total) if @show_each_hscr\n      @window_width = @width_total\n    else\n      @f_title.width(width)\n      @f_lbox.width(width)\n      @f_hscr.width(width) if @show_each_hscr\n      @window_width = width\n    end\n\n    @f_lbox.height(height)\n\n    @c_title.scrollregion(@w_title.bbox)\n    @c_lbox.scrollregion(@w_lbox.bbox)\n    @c_hscr.scrollregion(@w_hscr.bbox) if @show_each_hscr\n\n    (0..(@rel_list.size - 2)).each{|idx|\n      title, lbox, hscr = @base_list[idx]\n      title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n      lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n                 'relheight'=>1.0)\n      hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n    }\n  end\n\n  def resize(x)\n    idx = @sel_sash\n    return if idx == 0\n\n    # adjustment of relative positioning\n    delta = (x - @x) / @frame_width\n    if delta < @rel_list[idx-1] - @rel_list[idx] + (2*@sash/@frame_width)\n      delta = @rel_list[idx-1] - @rel_list[idx] + (2*@sash/@frame_width)\n    elsif delta > @rel_list[idx+1] - @rel_list[idx] - (2*@sash/@frame_width)\n      delta = @rel_list[idx+1] - @rel_list[idx] - (2*@sash/@frame_width)\n    end\n    @rel_list[idx] += delta\n\n    # adjustment of leftside widget of the sash\n    title, lbox, hscr = @base_list[idx - 1]\n    title.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1])\n    lbox.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1], 'relheight'=>1.0)\n    hscr.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1])\n\n    # adjustment of rightside widget of the sash\n    title, lbox, hscr = @base_list[idx]\n    title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n                'relx'=>@rel_list[idx])\n    lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n               'relx'=>@rel_list[idx], 'relheight'=>1.0)\n    hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n               'relx'=>@rel_list[idx])\n\n    # update reference position\n    @x = x\n  end\n\n  def motion_cb(w, x, idx)\n    if x <= @sash && idx > 0\n      w.cursor 'sb_h_double_arrow'\n      @mode = :sash\n      @sel_sash = idx\n    elsif x >= w.winfo_width - @sash && idx < @lbox_total - 1\n      w.cursor 'sb_h_double_arrow'\n      @mode = :sash\n      @sel_sash = idx + 1\n    else\n      w.cursor \"\"\n      @mode = :title\n      @sel_sash = 0\n    end\n  end\n\n  def title_binding(title, index)\n    title.bind('Motion', proc{|w, x, idx| motion_cb(w, x, idx.to_i)}, \n               \"%W %x #{index}\")\n\n    title.bind('Enter', proc{|w, x, idx| motion_cb(w, x, idx.to_i)}, \n               \"%W %x #{index}\")\n\n    title.bind('Leave', proc{|w| w.cursor \"\"}, \"%W\")\n\n    title.bind('Button-1', \n               proc{|w, x| \n                 if @mode == :sash\n                   @x = x\n                   @frame_width = TkWinfo.width(@f_title).to_f\n                 else\n                   title.relief 'sunken'\n                 end\n               }, \n               '%W %X')\n\n    title.bind('ButtonRelease-1', \n               proc{|w, x, idx| \n                 i = idx.to_i\n                 if @mode == :title && @title_cmd[i].kind_of?(Proc)\n                   @title_cmd[i].call\n                 end\n                 title.relief 'raised'\n                 motion_cb(w,x,i)\n               }, \n               \"%W %x #{index}\")\n\n    title.bind('B1-Motion', proc{|x| resize(x) if @mode == :sash}, \"%X\")\n  end\n\n  ########################\n  def select_line(w, idx)\n    @lbox_list.each{|l|\n      l.select_clear(1, 'end')\n      l.select_set(idx)\n    }\n    w.select_set(idx)\n  end\n\n  def select_shift(w, dir)\n    head = w.index('@1,1').split('.')[0].to_i\n    tail = w.index(\"@1,#{w.winfo_height - 1}\").split('.')[0].to_i - 1\n    idx = w.select_index + dir\n    last = w.index('end - 1 char').split('.')[0].to_i\n    if idx < 1\n      idx = 1\n    elsif idx > last\n      idx = last\n    end\n    @lbox_list.each{|l|\n      l.select_clear(1, 'end')\n      l.select_set(idx)\n    }\n    if head > idx\n      @lbox_list.each{|l| l.yview('scroll', -1, 'units')}\n    elsif tail < idx\n      @lbox_list.each{|l| l.yview('scroll', 1, 'units')}\n    end\n  end\n  ########################\nend\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  l = TkMultiColumnList.new(nil, 200, \n                            [ ['L1', 200, proc{p 'click L1'}], \n                              ['L2', 100], \n                              ['L3', 200] ], \n                            'width'=>350, \n                            #'titleforeground'=>'yellow', \n                            'titleforeground'=>'white', \n                            #'titlebackground'=>'navy',\n                            'titlebackground'=>'blue',\n                            'titlefont'=>'courier'\n                            ).pack('fill'=>'both', 'expand'=>true)\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', \n                   'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',\n                   'cccccccccccccccccccccccccccccccccccccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  p l.columns(1)\n  p l.columns(1..3)\n  p l.columns(1,2)\n\n  l.command proc{|line_info| p line_info}\n\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tkmultilistbox.rb",
    "content": "#\n# tkmultilistbox.rb : multiple listbox widget\n#                       by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass TkMultiListbox < TkListbox\n  include TkComposite\n\n  #   lbox_height : height of listboxes (pixel)\n  #   title_info  : array [ [<title_string>,<init_width>], ... ]\n  #   keys        : hash {<option>=><value>, ... }\n  def initialize_composite(lbox_height, title_info, keys={})\n    # argument check\n    if (! title_info.kind_of? Array) or (title_info.size < 2)\n      raise\n    end\n\n    # decide total width\n    @width_total = 0\n    title_info.each{|title, width| @width_total += width.to_f}\n\n    # virtical scrollbar\n    @v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')\n\n    # init arrays\n    @base_list = []\n    @rel_list   = []\n    @title_list = []\n    @lbox_list  = []\n    @hscr_list  = []\n\n    # rel-table of label=>index\n    @name_index = {}\n\n    # create base flames\n    @f_title = TkFrame.new(@frame, 'width'=>@width_total)\n    @f_lbox  = TkFrame.new(@frame, \n                           'width'=>@width_total, 'height'=>lbox_height)\n    @f_hscr  = TkFrame.new(@frame, 'width'=>@width_total, \n                           'height'=>@v_scroll.cget('width') + \n                                     2 * @v_scroll.cget('borderwidth'))\n\n    # dummy label to keep the hight of title space\n    TkLabel.new(@f_title, 'text'=>' ').pack\n\n    # create each listbox\n    sum = 0.0\n    @rel_list << sum/@width_total\n    title_info.each_with_index{|(label, width), idx|\n      # set relation between label and index\n      if @name_index.include?(label)\n        @name_index[label] << idx\n      else\n        @name_index[label] = [idx]\n      end\n\n      # calculate relative positioning\n      sum += width\n      @rel_list << sum/@width_total\n\n      # title field\n      f = TkFrame.new(@f_title, 'width'=>width)\n      base = [f]\n      @title_list << TkLabel.new(f, 'text'=>label).pack('fill'=>'x')\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>-6, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n      # listbox field\n      f = TkFrame.new(@f_lbox, 'width'=>width)\n      base << f\n      @lbox_list << TkListbox.new(f).pack('fill'=>'both', 'expand'=>true)\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>-4, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx], 'relheight'=>1.0)\n\n      # scrollbar field\n      f = TkFrame.new(@f_hscr, 'width'=>width)\n      base << f\n      @hscr_list << TkScrollbar.new(f, 'orient'=>'horizontal') . \n                                              pack('fill'=>'x', 'anchor'=>'w')\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>-4, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n      @lbox_list[idx].xscrollcommand proc{|first, last| \n        @hscr_list[idx].set first, last\n      }\n      @hscr_list[idx].command proc{|*args| @lbox_list[idx].xview *args}\n\n      # add new base\n      @base_list << base\n    }\n\n    # create tab\n    @tab_list = [nil]\n    (1..(@rel_list.size - 2)).each{|idx|\n      tab = TkFrame.new(@f_title, 'cursor'=>'sb_h_double_arrow', \n                        'width'=>6, 'borderwidth'=>2, 'relief'=>'raised')\n      @tab_list << tab\n      tab.place('relx'=>@rel_list[idx], 'anchor'=>'ne', 'relheight'=>0.95)\n      tab.bind('Button-1', \n               proc{|x| @x = x; @frame_width = TkWinfo.width(@f_title).to_f}, \n               '%X')\n      tab.bind('B1-Motion', proc{|x, idx| resize(x, idx.to_i)}, \"%X #{idx}\")\n    }\n\n    # set control procedure for virtical scroll\n    @lbox_list.each{|lbox|\n      lbox.yscrollcommand proc{|first, last| \n        @v_scroll.set first, last\n      }\n    }\n    @v_scroll.command proc{|*args| @lbox_list.each{|lbox| lbox.yview *args} }\n\n    # binding for listboxes\n    @mode = {}\n    @mode['browse']   = browse_mode_bindtag\n    @mode['single']   = single_mode_bindtag\n    @mode['extended'] = extended_mode_bindtag\n    @mode['multiple'] = multiple_mode_bindtag\n    @current_mode = 'browse'\n    @lbox_list.each{|l| \n      l.bind('Shift-Key-Left', \n             proc{|w| focus_shift(w, -1); Tk.callback_break}, '%W')\n      l.bind('Shift-Key-Right', \n             proc{|w| focus_shift(w, 1); Tk.callback_break}, '%W')\n\n      l.bind('Button-2', proc{|x, y| \n               @lbox_mark_x = x\n               @lbox_list.each{|lbox| lbox.scan_mark(x, y)}\n             }, '%x %y')\n      l.bind('B2-Motion', proc{|x, y| \n               @lbox_list.each{|lbox| lbox.scan_dragto(@lbox_mark_x, y)}\n               l.scan_dragto(x, y)\n             }, '%x %y')\n\n      l.bindtags(l.bindtags.unshift(@mode[@current_mode]))\n    }\n\n    # alignment\n    TkGrid.rowconfigure(@frame, 0, 'weight'=>0)\n    TkGrid.rowconfigure(@frame, 1, 'weight'=>1)\n    TkGrid.rowconfigure(@frame, 2, 'weight'=>0)\n    TkGrid.columnconfigure(@frame, 0, 'weight'=>1)\n    TkGrid.columnconfigure(@frame, 1, 'weight'=>0)\n    @v_scroll.grid('row'=>1, 'column'=>1, 'sticky'=>'ns')\n    @f_title.grid('row'=>0, 'column'=>0, 'sticky'=>'news')\n    @f_lbox.grid('row'=>1, 'column'=>0, 'sticky'=>'news')\n    @f_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew')\n\n    # binding for 'Configure' event\n    @frame.bind('Configure', proc{reconstruct})\n\n    # set default receiver of method calls\n    @path = @lbox_list[0].path\n\n    # configure options\n    keys = {} unless keys\n    keys = _symbolkey2str(keys)\n\n    # 'mode' option of listboxes\n    sel_mode = keys.delete('mode')\n    mode(sel_mode) if sel_mode\n\n    # 'scrollbarwidth' option == 'width' option of scrollbars\n    width = keys.delete('scrollbarwidth')\n    scrollbarwidth(width) if width\n\n    # options for listbox titles\n    title_font = keys.delete('titlefont')\n    title_fg = keys.delete('titleforeground')\n    title_bg = keys.delete('titlebackground')\n    if title_font or title_fg or title_bg\n      titleconfig(title_font, title_fg, title_bg)\n    end\n\n    # set receivers for configure methods\n    delegate('DEFAULT', *@lbox_list)\n    delegate('activebackground', @v_scroll, *@hscr_list)\n    delegate('troughcolor', @v_scroll, *@hscr_list)\n    delegate('repeatdelay', @v_scroll, *@hscr_list)\n    delegate('repeatinterval', @v_scroll, *@hscr_list)\n    delegate('borderwidth', @frame)\n    delegate('relief', @frame)\n\n    # configure\n    configure(keys) if keys.size > 0\n  end\n  private :initialize_composite\n\n  # set 'mode' option of listboxes\n  def mode(sel_mode)\n    @lbox_list.each{|l| \n      tags = l.bindtags\n      tags = tags - [ @mode[@current_mode] ]\n      l.bindtags(tags.unshift(@mode[sel_mode]))\n      @current_mode = sel_mode\n    }\n  end\n\n  # set scrollbar width\n  def scrollbarwidth(width)\n    @v_scroll['width'] = width\n    @hscr_list.each{|hscr| hscr['width'] = width}\n    @f_hscr['height'] = width + 2 * @v_scroll.cget('borderwidth')\n  end\n\n  # set options of titles\n  def titleconfig(font, fg, bg)\n    keys = {}\n    keys['font'] = font if font\n    keys['foreground'] = fg if fg\n    keys['background'] = bg if bg\n    @title_list.each{|label| label.configure(keys)}\n  end\n\n  # get label widgets of listbox titles\n  def titlelabels(*indices)\n    @title_list[*indices]\n  end\n\n  # get listbox widgets\n  def columns(*indices)\n    @lbox_list[*indices]\n  end\n\n  def activate(idx)\n    @lbox_list.each{|lbox| lbox.activate(idx)}\n  end\n\n  def bbox(idx)\n    @lbox_list.collect{|lbox| lbox.bbox(idx)}\n  end\n\n  def delete(*idx)\n    @lbox_list.collect{|lbox| lbox.delete(*idx)}\n  end\n\n  def get(*idx)\n    if idx.size == 1\n      @lbox_list.collect{|lbox| lbox.get(*idx)}\n    else\n      list = @lbox_list.collect{|lbox| lbox.get(*idx)}\n      result = []\n      list[0].each_with_index{|line, index|\n        result << list.collect{|lines| lines[index]}\n      }\n      result\n    end\n  end\n\n  def _line_array_to_hash(line)\n    result = {}\n    @name_index.each_pair{|label, indices|\n      if indices.size == 1\n        result[label] = line[indices[0]]\n      else\n        result[label] = indices.collect{|index| line[index]}\n      end\n    }\n    result\n  end\n  private :_line_array_to_hash\n\n  def get_by_hash(*idx)\n    get_result = get(*idx)\n    if idx.size == 1\n      _line_array_to_hash(get_result)\n    else\n      get_result.collect{|line| _line_array_to_hash(line)}\n    end\n  end\n\n  def insert(idx, *lines)\n    lbox_ins = []\n    (0..@lbox_list.size).each{lbox_ins << []}\n\n    lines.each{|line|\n      if line.kind_of? Hash\n        array = []\n        @name_index.each_pair{|label, indices|\n          if indices.size == 1\n            array[indices[0]] = line[label]\n          else\n            if line[label].kind_of? Array\n              indices.each_with_index{|index, num| \n                array[index] = line[label][num]\n              }\n            else\n              array[indices[0]] = line[label]\n            end\n          end\n        }\n        line = array\n      end\n\n      @name_index.each_pair{|label, indices|\n        if indices.size == 1\n          lbox_ins[indices[0]] << line[indices[0]]\n        else\n          indices.each{|index| lbox_ins[index] << line[index]}\n        end\n      }\n    }   \n\n    @lbox_list.each_with_index{|lbox, index| \n      lbox.insert(idx, *lbox_ins[index]) if lbox_ins[index]\n    }\n  end\n\n  def selection_anchor(index)\n    @lbox_list.each{|lbox| lbox.selection_anchor(index)}\n  end\n\n  def selection_clear(first, last=None)\n    @lbox_list.each{|lbox| lbox.selection_clear(first, last=None)}\n  end\n\n  def selection_set(first, last=None)\n    @lbox_list.each{|lbox| lbox.selection_set(first, last=None)}\n  end\n\n  ###########################################\n  private\n\n  def reconstruct\n    (0..(@rel_list.size - 2)).each{|idx|\n      title, lbox, hscr = @base_list[idx]\n      title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n      lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n                 'relheight'=>1.0)\n      hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n      tab = @tab_list[idx]\n      tab.place('relx'=>@rel_list[idx]) if tab\n    }\n  end\n\n  def resize(x, idx)\n    # adjustment of relative positioning\n    delta = (x - @x) / @frame_width\n    if delta < @rel_list[idx-1] - @rel_list[idx] + 0.02\n      delta = @rel_list[idx-1] - @rel_list[idx] + 0.02\n    elsif delta > @rel_list[idx+1] - @rel_list[idx] - 0.02\n      delta = @rel_list[idx+1] - @rel_list[idx] - 0.02\n    end\n    @rel_list[idx] += delta\n\n    # adjustment of leftside widget of the tab\n    title, lbox, hscr = @base_list[idx - 1]\n    title.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1])\n    lbox.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1], 'relheight'=>1.0)\n    hscr.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1])\n\n    # adjustment of the tab position\n    @tab_list[idx].place('relx'=>@rel_list[idx])\n\n    # adjustment of rightside widget of the tab\n    title, lbox, hscr = @base_list[idx]\n    title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n                'relx'=>@rel_list[idx])\n    lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n               'relx'=>@rel_list[idx], 'relheight'=>1.0)\n    hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n               'relx'=>@rel_list[idx])\n\n    # update reference position\n    @x = x\n  end\n\n  #################################\n  def browse_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_line(w, w.nearest(y))}, '%W %y')\n    t.bind('B1-Motion', proc{|w, y| select_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Shift-Button-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| select_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| select_shift(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Select', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Control-slash', \n           proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n\n    t\n  end\n\n  ########################\n  def single_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_only(w, w.nearest(y))}, '%W %y')\n    t.bind('ButtonRelease-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Shift-Button-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| select_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| select_shift(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Select', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Control-slash', \n           proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Control-backslash', \n           proc{@lbox_list.each{|l| l.selection_clear(0, 'end')}})\n\n    t\n  end\n\n  ########################\n  def extended_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_only(w, w.nearest(y))}, '%W %y')\n    t.bind('B1-Motion', proc{|w, y| select_range(w, w.nearest(y))}, '%W %y')\n\n    t.bind('ButtonRelease-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Shift-Button-1', \n           proc{|w, y| select_range(w, w.nearest(y))}, '%W %y')\n    t.bind('Shift-B1-Motion', \n           proc{|w, y| select_range(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Control-Button-1', \n           proc{|w, y| select_toggle(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Control-B1-Motion', \n           proc{|w, y| select_drag(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| active_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| active_shift(w, 1)}, '%W')\n\n    t.bind('Shift-Up', proc{|w| select_expand(w, -1)}, '%W')\n    t.bind('Shift-Down', proc{|w| select_expand(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line2(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line2(w, 'end')}, '%W')\n\n    t.bind('Control-Shift-Home', proc{|w| select_range(w, 0)}, '%W')\n    t.bind('Control-Shift-End', proc{|w| select_range(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_active(w)}, '%W')\n    t.bind('Select', proc{|w| select_active(w)}, '%W')\n    t.bind('Control-slash', proc{|w| select_all}, '%W')\n    t.bind('Control-backslash', proc{|w| clear_all}, '%W')\n\n    t\n  end\n\n  ########################\n  def multiple_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_line3(w, w.nearest(y))}, '%W %y')\n    t.bind('ButtonRelease-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| active_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| active_shift(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line2(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line2(w, 'end')}, '%W')\n\n    t.bind('Control-Shift-Home', proc{|w| active_line(w, 0)}, '%W')\n    t.bind('Control-Shift-End', proc{|w| active_line(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_active(w)}, '%W')\n    t.bind('Select', proc{|w| select_active(w)}, '%W')\n    t.bind('Control-slash', proc{|w| select_all}, '%W')\n    t.bind('Control-backslash', proc{|w| clear_all}, '%W')\n\n    t\n  end\n\n  ########################\n  def active_line(w, idx)\n    @lbox_list.each{|l| l.activate(idx)}\n  end\n\n  def select_only(w, idx)\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n  end\n\n  def select_range(w, idx)\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.selection_set('anchor', idx)\n    }\n  end\n\n  def select_toggle(w, idx)\n    st = w.selection_includes(idx)\n    @lbox_list.each{|l|\n      l.selection_anchor(idx)\n      if st == 1\n        l.selection_clear(idx)\n      else\n        l.selection_set(idx)\n      end\n    }\n  end\n\n  def select_drag(w, idx)\n    st = w.selection_includes('anchor')\n    @lbox_list.each{|l|\n      if st == 1\n        l.selection_set('anchor', idx)\n      else\n        l.selection_clear('anchor', idx)\n      end\n    }\n  end\n\n  def select_line(w, idx)\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.activate(idx)\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n    w.selection_set('anchor')\n  end\n\n  def select_line2(w, idx)\n    @lbox_list.each{|l|\n      l.activate(idx)\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n  end\n\n  def select_line3(w, idx)\n    @lbox_list.each{|l|\n      l.selection_set(idx)\n    }\n  end\n\n  def select_active(w)\n    idx = l.activate(idx)\n    @lbox_list.each{|l|\n      l.selection_set(idx)\n    }\n  end\n\n  def select_expand(w, dir)\n    idx = w.index('active').to_i + dir\n    if idx < 0\n      idx = 0\n    elsif idx >= w.size\n      idx = w.size - 1\n    end\n    @lbox_list.each{|l|\n      l.activate(idx)\n      l.selection_set(idx)\n    }\n  end\n\n  def active_shift(w, dir)\n    idx = w.index('active').to_i + dir\n    if idx < 0\n      idx = 0\n    elsif idx >= w.size\n      idx = w.size - 1\n    end\n    @lbox_list.each{|l|\n      l.activate(idx)\n      l.selection_anchor(idx)\n    }\n  end\n\n  def select_shift(w, dir)\n    idx = w.index('anchor').to_i + dir\n    if idx < 0\n      idx = 0\n    elsif idx >= w.size\n      idx = w.size - 1\n    end\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.activate(idx)\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n  end\n\n  def select_all\n    @lbox_list.each{|l|\n      l.selection_set(0, 'end')\n    }\n  end\n\n  def clear_all\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n    }\n  end\n\n  def focus_shift(w, dir)\n    idx = @lbox_list.index(w) + dir\n    return if idx < 0\n    return if idx >= @lbox_list.size\n    @lbox_list[idx].focus\n  end\n  ########################\nend\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  f = TkFrame.new(nil, 'width'=>300, \n                  'height'=>200).pack('fill'=>'both', 'expand'=>'true')\n  #f = TkFrame.new.pack('fill'=>'both', 'expand'=>'true')\n  l = TkMultiListbox.new(f, 150, \n                         [ ['L1', 100], \n                           ['L2', 200], \n                           ['L3', 50] ], \n                         'titlefont'=>'courier', \n                         'titleforeground'=>'yellow', \n                         'titlebackground'=>'navy'\n                         ).pack('fill'=>'both', 'expand'=>true)\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  p l.columns(1)\n  p l.columns(1..3)\n  p l.columns(1,2)\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tkmultilistframe.rb",
    "content": "#\n# tkmultilistframe.rb : multiple listbox widget on scrollable frame\n#                       by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass TkMultiListFrame < TkListbox\n  include TkComposite\n\n  #   lbox_height : height of listboxes (pixel)\n  #   title_info  : array [ [<title_string>,<init_width>], ... ]\n  #   keys        : hash {<option>=><value>, ... }\n  def initialize_composite(lbox_height, title_info, keys={})\n    # argument check\n    if (! title_info.kind_of? Array) or (title_info.size < 2)\n      raise\n    end\n\n    # mode\n    @keep_minsize = true\n    @show_each_hscr = true\n    @show_win_hscr = true\n\n    # init arrays\n    @base_list  = []\n    @rel_list   = []\n    @title_list = []\n    @title_cmd  = []\n    @lbox_list  = []\n    @hscr_list  = []\n\n    # decide total width\n    @lbox_total = title_info.size\n    @width_total = 0\n    title_info.each{|title, width, cmd| \n      @width_total += width.to_f\n      @title_cmd << cmd\n    }\n\n    # rel-table of label=>index\n    @name_index = {}\n\n    # size definition\n    @window_width = @width_total\n    @sash = 5\n    @scrbar_width = 15\n    @scrbar_border = 3\n    @lbox_border = 1\n    @title_border = 3\n    @h_l_thick = 0\n\n    # init status\n    @mode = :title\n\n    # virtical scrollbar\n=begin\n    @v_scroll = TkScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, \n                                'borderwidth'=>@scrbar_border, \n                                'orient'=>'vertical', 'width'=>@scrbar_width)\n=end\n    @v_scroll = TkYScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, \n                                 'borderwidth'=>@scrbar_border, \n                                 'width'=>@scrbar_width)\n\n    # horizontal scrollbar\n=begin\n    @h_scroll = TkScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, \n                                'borderwidth'=>@scrbar_border, \n                                'orient'=>'horizontal', 'width'=>@scrbar_width)\n=end\n    @h_scroll = TkXScrollbar.new(@frame, 'highlightthickness'=>@h_l_thick, \n                                 'borderwidth'=>@scrbar_border, \n                                 'width'=>@scrbar_width)\n\n    # create base flames\n    @c_title = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, \n                            'width'=>@window_width)\n    @f_title = TkFrame.new(@c_title, 'width'=>@width_total)\n    @w_title = TkcWindow.new(@c_title, 0, 0, \n                             'window'=>@f_title, 'anchor'=>'nw')\n\n    @c_lbox  = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, \n                            'width'=>@window_width)\n    @f_lbox  = TkFrame.new(@c_lbox, 'width'=>@width_total)\n    @w_lbox  = TkcWindow.new(@c_lbox, 0, 0, 'window'=>@f_lbox, 'anchor'=>'nw')\n\n    @c_hscr  = TkCanvas.new(@frame, 'highlightthickness'=>@h_l_thick, \n                            'width'=>@window_width)\n    @f_hscr  = TkFrame.new(@c_hscr, 'width'=>@width_total)\n    @w_hscr  = TkcWindow.new(@c_hscr, 0, 0, 'window'=>@f_hscr, 'anchor'=>'nw')\n\n    # create each listbox\n    sum = 0.0\n    @rel_list << sum/@width_total\n    title_info.each_with_index{|(label, width), idx|\n      # set relation between label and index\n      if @name_index.include?(label)\n        @name_index[label] << idx\n      else\n        @name_index[label] = [idx]\n      end\n\n      # calculate relative positioning\n      sum += width\n      @rel_list << sum/@width_total\n\n      # title field\n      f = TkFrame.new(@f_title, 'width'=>width)\n      base = [f]\n\n      title = TkLabel.new(f, 'text'=>label, 'borderwidth'=>@title_border, \n                          'relief'=>'raised', 'highlightthickness'=>@h_l_thick)\n      title_binding(title, idx)\n      title.pack('fill'=>'x')\n\n      @title_list << title\n\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, \n              'relheight'=>1.0, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n      # listbox field\n      f = TkFrame.new(@f_lbox, 'width'=>width)\n      base << f\n      @lbox_list << TkListbox.new(f, 'highlightthickness'=>@h_l_thick, \n                                  'borderwidth'=>@lbox_border\n                                  ).pack('fill'=>'both', 'expand'=>true)\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx], 'relheight'=>1.0)\n\n      # scrollbar field\n      f = TkFrame.new(@f_hscr, 'width'=>width)\n      base << f\n=begin\n      @hscr_list << TkScrollbar.new(f, 'orient'=>'horizontal', \n                                    'width'=>@scrbar_width, \n                                    'borderwidth'=>@scrbar_border, \n                                    'highlightthickness'=>@h_l_thick\n                                    ).pack('fill'=>'x', 'anchor'=>'w')\n=end\n      @hscr_list << TkXScrollbar.new(f, 'width'=>@scrbar_width, \n                                     'borderwidth'=>@scrbar_border, \n                                     'highlightthickness'=>@h_l_thick\n                                    ).pack('fill'=>'x', 'anchor'=>'w')\n      f.place('relx'=>@rel_list[idx], 'y'=>0, 'anchor'=>'nw', 'width'=>1, \n              'relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n\n=begin\n      @lbox_list[idx].xscrollcommand proc{|first, last| \n        @hscr_list[idx].set first, last\n      }\n      @hscr_list[idx].command proc{|*args| @lbox_list[idx].xview *args}\n=end\n      @lbox_list[idx].xscrollbar(@hscr_list[idx])\n\n      # add new base\n      @base_list << base\n    }\n\n    # pad\n    # @f_title_pad = TkFrame.new(@frame)\n    @f_title_pad = TkFrame.new(@frame, 'relief'=>'raised', \n                               'borderwidth'=>@title_border, \n                               'highlightthickness'=>@h_l_thick)\n\n    @f_scr_pad = TkFrame.new(@frame, 'relief'=>'sunken', \n                             'borderwidth'=>1, \n                             'highlightthickness'=>@h_l_thick)\n\n    # height check\n    title_height = 0\n    @title_list.each{|w| \n      h = w.winfo_reqheight\n      title_height = h if title_height < h\n    }\n\n    hscr_height = 0\n    @hscr_list.each{|w| \n      h = w.winfo_reqheight\n      hscr_height = h if hscr_height < h\n    }\n\n    @f_title.height title_height\n    @f_lbox.height lbox_height\n    @f_hscr.height hscr_height\n\n    # set control procedure for virtical scroll\n=begin\n    @lbox_list.each{|lbox|\n      lbox.yscrollcommand proc{|first, last| \n        @v_scroll.set first, last\n      }\n    }\n    @v_scroll.command proc{|*args| @lbox_list.each{|lbox| lbox.yview *args} }\n=end\n    @v_scroll.assign(*@lbox_list)\n\n    # set control procedure for horizoncal scroll\n=begin\n    @c_title.xscrollcommand proc{|first, last| \n      @h_scroll.set first, last\n    }\n    @c_lbox.xscrollcommand proc{|first, last| \n      @h_scroll.set first, last\n    }\n    @c_hscr.xscrollcommand proc{|first, last| \n      @h_scroll.set first, last\n    }\n    @h_scroll.command proc{|*args| \n      @c_title.xview *args\n      @c_lbox.xview *args\n      @c_hscr.xview *args if @show_each_hscr\n    }\n=end\n    @h_scroll.assign(@c_title, @c_lbox, @c_hscr)\n\n    # binding for listboxes\n    @lbox_mode = {}\n    @lbox_mode['browse']   = browse_mode_bindtag\n    @lbox_mode['single']   = single_mode_bindtag\n    @lbox_mode['extended'] = extended_mode_bindtag\n    @lbox_mode['multiple'] = multiple_mode_bindtag\n    @current_mode = 'browse'\n    @lbox_list.each_with_index{|l, idx| \n      l.bind('Shift-Key-Left', \n             proc{|w| focus_shift(w, -1); Tk.callback_break}, '%W')\n      l.bind('Shift-Key-Right', \n             proc{|w| focus_shift(w, 1); Tk.callback_break}, '%W')\n\n      l.bind('Button-2', proc{|x, y| \n               @lbox_mark_x = x\n               @lbox_list.each{|lbox| lbox.scan_mark(x, y)}\n             }, '%x %y')\n      l.bind('B2-Motion', proc{|x, y| \n               @lbox_list.each{|lbox| lbox.scan_dragto(@lbox_mark_x, y)}\n               l.scan_dragto(x, y)\n             }, '%x %y')\n\n      l.bindtags(l.bindtags.unshift(@lbox_mode[@current_mode]))\n    }\n\n    bbox = @w_title.bbox\n    @c_title.height(bbox[3])\n    @c_title.scrollregion(bbox)\n\n    bbox = @w_lbox.bbox\n    @c_lbox.height(bbox[3])\n    @c_lbox.scrollregion(bbox)\n\n    if @show_each_hscr\n      bbox = @w_hscr.bbox\n      @c_hscr.height(bbox[3])\n      @c_hscr.scrollregion(bbox)\n    end\n\n    # alignment\n    TkGrid.rowconfigure(@frame, 0, 'weight'=>0)\n    TkGrid.rowconfigure(@frame, 1, 'weight'=>1)\n    TkGrid.rowconfigure(@frame, 2, 'weight'=>0)\n    TkGrid.rowconfigure(@frame, 3, 'weight'=>0)\n    TkGrid.columnconfigure(@frame, 0, 'weight'=>1)\n    TkGrid.columnconfigure(@frame, 1, 'weight'=>0)\n    TkGrid.columnconfigure(@frame, 2, 'weight'=>0)\n    @v_scroll.grid('row'=>1, 'column'=>2, 'sticky'=>'ns')\n    @c_title.grid('row'=>0, 'column'=>0, 'sticky'=>'news')\n    @f_title_pad.grid('row'=>0, 'column'=>2, 'sticky'=>'news')\n    @c_lbox.grid('row'=>1, 'column'=>0, 'sticky'=>'news')\n    @c_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew') if @show_each_hscr\n    @h_scroll.grid('row'=>3, 'column'=>0, 'sticky'=>'ew') if @show_win_hscr\n    @f_scr_pad.grid('row'=>2, 'rowspan'=>2, 'column'=>2, 'sticky'=>'news')\n\n    # binding for 'Configure' event\n    @c_lbox.bind('Configure', \n                 proc{|height, width| reconstruct(height, width)}, \n                 '%h %w')\n\n    # set default receiver of method calls\n    @path = @lbox_list[0].path\n\n    # configure options\n    keys = {} unless keys\n    keys = _symbolkey2str(keys)\n\n    # 'mode' option of listboxes\n    sel_mode = keys.delete('mode')\n    mode(sel_mode) if sel_mode\n\n    # 'scrollbarwidth' option == 'width' option of scrollbars\n    width = keys.delete('scrollbarwidth')\n    scrollbarwidth(width) if width\n\n    # options for listbox titles\n    title_font = keys.delete('titlefont')\n    titlefont(title_font) if title_font\n\n    title_fg = keys.delete('titleforeground')\n    titleforeground(title_fg) if title_fg\n\n    title_bg = keys.delete('titlebackground')\n    titlebackground(title_bg) if title_bg\n\n    # set receivers for configure methods\n    delegate('DEFAULT', *@lbox_list)\n    delegate('activebackground', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('troughcolor', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('repeatdelay', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('repeatinterval', @v_scroll, @h_scroll, *@hscr_list)\n    delegate('borderwidth', @frame)\n    delegate('width', @c_lbox, @c_title, @c_hscr)\n    delegate('relief', @frame)\n\n    # configure\n    configure(keys) if keys.size > 0\n  end\n  private :initialize_composite\n\n  # set 'mode' option of listboxes\n  def mode(sel_mode)\n    @lbox_list.each{|l| \n      tags = l.bindtags\n      tags = tags - [ @lbox_mode[@current_mode] ]\n      l.bindtags(tags.unshift(@lbox_mode[sel_mode]))\n      @current_mode = sel_mode\n    }\n  end\n\n  # keep_minsize?\n  def keep_minsize?\n    @keep_minsize\n  end\n  def keep_minsize(bool)\n    @keep_minsize = bool\n  end\n\n  # each hscr\n  def show_each_hscr\n    @show_each_hscr = true\n    @c_hscr.grid('row'=>2, 'column'=>0, 'sticky'=>'ew')\n  end\n  def hide_each_hscr\n    @show_each_hscr = false\n    @c_hscr.ungrid\n  end\n\n  # window hscroll\n  def show_win_hscr\n    @show_win_hscr = true\n    @h_scroll.grid('row'=>3, 'column'=>0, 'sticky'=>'ew')\n  end\n  def hide_win_hscr\n    @show_each_hscr = false\n    @h_scroll.ungrid\n  end\n\n  # set scrollbar width\n  def scrollbarwidth(width)\n    @scrbar_width = width\n    @v_scroll['width'] = @scrbar_width\n    @h_scroll['width'] = @scrbar_width\n    @hscr_list.each{|hscr| hscr['width'] = @scrbar_width}\n    self\n  end\n\n  # set scrollbar border\n  def scrollbarborder(width)\n    @scrbar_border = width\n    @v_scroll['border'] = @scrbar_border\n    @h_scroll['border'] = @scrbar_border\n    @hscr_list.each{|hscr| hscr['border'] = @scrbar_border}\n    self\n  end\n\n  # set listbox borders\n  def listboxborder(width)\n    @lbox_border = width\n    @lbox_list.each{|w| w['border'] = @lbox_border}\n    self\n  end\n\n  # set listbox relief\n  def listboxrelief(relief)\n    @lbox_list.each{|w| w['relief'] = relief}\n    self\n  end\n\n  # set title borders\n  def titleborder(width)\n    @title_border = width\n    @f_title_pad['border'] = @title_border\n    @title_list.each{|label| label['border'] = @title_border}\n    self\n  end\n\n  # set title font\n  def titlefont(font)\n    @title_list.each{|label| label['font'] = font}\n    title_height = 0\n    @title_list.each{|w| \n      h = w.winfo_reqheight\n      title_height = h if title_height < h\n    }\n    @f_title.height title_height\n    bbox = @w_title.bbox\n    @c_title.height(bbox[3])\n    @c_title.scrollregion(bbox)\n    self\n  end\n\n  # set title foreground color\n  def titleforeground(fg)\n    @title_list.each{|label| label['foreground'] = fg}\n    self\n  end\n\n  # set title background color\n  def titlebackground(bg)\n    @f_title_pad['background'] = bg\n    @title_list.each{|label| label['background'] = bg}\n    self\n  end\n\n  # set title cmds\n  def titlecommand(idx, cmd=Proc.new)\n    @title_cmd[idx] = cmd\n  end\n\n  # call title cmds\n  def titleinvoke(idx)\n    @title_cmd[idx].call if @title_cmd[idx]\n  end\n\n  # get label widgets of listbox titles\n  def titlelabels(*indices)\n    @title_list[*indices]\n  end\n\n  # get listbox widgets\n  def columns(*indices)\n    @lbox_list[*indices]\n  end\n\n  def activate(idx)\n    @lbox_list.each{|lbox| lbox.activate(idx)}\n  end\n\n  def bbox(idx)\n    @lbox_list.collect{|lbox| lbox.bbox(idx)}\n  end\n\n  def delete(*idx)\n    @lbox_list.collect{|lbox| lbox.delete(*idx)}\n  end\n\n  def get(*idx)\n    if idx.size == 1\n      @lbox_list.collect{|lbox| lbox.get(*idx)}\n    else\n      list = @lbox_list.collect{|lbox| lbox.get(*idx)}\n      result = []\n      list[0].each_with_index{|line, index|\n        result << list.collect{|lines| lines[index]}\n      }\n      result\n    end\n  end\n\n  def _line_array_to_hash(line)\n    result = {}\n    @name_index.each_pair{|label, indices|\n      if indices.size == 1\n        result[label] = line[indices[0]]\n      else\n        result[label] = indices.collect{|index| line[index]}\n      end\n    }\n    result\n  end\n  private :_line_array_to_hash\n\n  def get_by_hash(*idx)\n    get_result = get(*idx)\n    if idx.size == 1\n      _line_array_to_hash(get_result)\n    else\n      get_result.collect{|line| _line_array_to_hash(line)}\n    end\n  end\n\n  def insert(idx, *lines)\n    lbox_ins = []\n    (0..@lbox_list.size).each{lbox_ins << []}\n\n    lines.each{|line|\n      if line.kind_of? Hash\n        array = []\n        @name_index.each_pair{|label, indices|\n          if indices.size == 1\n            array[indices[0]] = line[label]\n          else\n            if line[label].kind_of? Array\n              indices.each_with_index{|index, num| \n                array[index] = line[label][num]\n              }\n            else\n              array[indices[0]] = line[label]\n            end\n          end\n        }\n        line = array\n      end\n\n      @name_index.each_pair{|label, indices|\n        if indices.size == 1\n          lbox_ins[indices[0]] << line[indices[0]]\n        else\n          indices.each{|index| lbox_ins[index] << line[index]}\n        end\n      }\n    }   \n\n    @lbox_list.each_with_index{|lbox, index| \n      lbox.insert(idx, *lbox_ins[index]) if lbox_ins[index]\n    }\n  end\n\n  def selection_anchor(index)\n    @lbox_list.each{|lbox| lbox.selection_anchor(index)}\n  end\n\n  def selection_clear(first, last=None)\n    @lbox_list.each{|lbox| lbox.selection_clear(first, last=None)}\n  end\n\n  def selection_set(first, last=None)\n    @lbox_list.each{|lbox| lbox.selection_set(first, last=None)}\n  end\n\n  ###########################################\n  private\n\n  def reconstruct(height, width)\n    if @keep_minsize && width <= @width_total\n      @f_title.width(@width_total)\n      @f_lbox.width(@width_total)\n      @f_hscr.width(@width_total) if @show_each_hscr\n      @window_width = @width_total\n    else\n      @f_title.width(width)\n      @f_lbox.width(width)\n      @f_hscr.width(width) if @show_each_hscr\n      @window_width = width\n    end\n\n    @f_lbox.height(height)\n\n    @c_title.scrollregion(@w_title.bbox)\n    @c_lbox.scrollregion(@w_lbox.bbox)\n    @c_hscr.scrollregion(@w_hscr.bbox) if @show_each_hscr\n\n    (0..(@rel_list.size - 2)).each{|idx|\n      title, lbox, hscr = @base_list[idx]\n      title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n      lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n                 'relheight'=>1.0)\n      hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx])\n    }\n  end\n\n  def resize(x)\n    idx = @sel_sash\n    return if idx == 0\n\n    # adjustment of relative positioning\n    delta = (x - @x) / @frame_width\n    if delta < @rel_list[idx-1] - @rel_list[idx] + (2*@sash/@frame_width)\n      delta = @rel_list[idx-1] - @rel_list[idx] + (2*@sash/@frame_width)\n    elsif delta > @rel_list[idx+1] - @rel_list[idx] - (2*@sash/@frame_width)\n      delta = @rel_list[idx+1] - @rel_list[idx] - (2*@sash/@frame_width)\n    end\n    @rel_list[idx] += delta\n\n    # adjustment of leftside widget of the sash\n    title, lbox, hscr = @base_list[idx - 1]\n    title.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1])\n    lbox.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1], 'relheight'=>1.0)\n    hscr.place('relwidth'=>@rel_list[idx] - @rel_list[idx-1])\n\n    # adjustment of rightside widget of the sash\n    title, lbox, hscr = @base_list[idx]\n    title.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n                'relx'=>@rel_list[idx])\n    lbox.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n               'relx'=>@rel_list[idx], 'relheight'=>1.0)\n    hscr.place('relwidth'=>@rel_list[idx+1] - @rel_list[idx], \n               'relx'=>@rel_list[idx])\n\n    # update reference position\n    @x = x\n  end\n\n  def motion_cb(w, x, idx)\n    if x <= @sash && idx > 0\n      w.cursor 'sb_h_double_arrow'\n      @mode = :sash\n      @sel_sash = idx\n    elsif x >= w.winfo_width - @sash && idx < @lbox_total - 1\n      w.cursor 'sb_h_double_arrow'\n      @mode = :sash\n      @sel_sash = idx + 1\n    else\n      w.cursor \"\"\n      @mode = :title\n      @sel_sash = 0\n    end\n  end\n\n  def title_binding(title, index)\n    title.bind('Motion', proc{|w, x, idx| motion_cb(w, x, idx.to_i)}, \n               \"%W %x #{index}\")\n\n    title.bind('Enter', proc{|w, x, idx| motion_cb(w, x, idx.to_i)}, \n               \"%W %x #{index}\")\n\n    title.bind('Leave', proc{|w| w.cursor \"\"}, \"%W\")\n\n    title.bind('Button-1', \n               proc{|w, x| \n                 if @mode == :sash\n                   @x = x\n                   @frame_width = TkWinfo.width(@f_title).to_f\n                 else\n                   title.relief 'sunken'\n                 end\n               }, \n               '%W %X')\n\n    title.bind('ButtonRelease-1', \n               proc{|w, x, idx| \n                 i = idx.to_i\n                 if @mode == :title && @title_cmd[i].kind_of?(Proc)\n                   @title_cmd[i].call\n                 end\n                 title.relief 'raised'\n                 motion_cb(w,x,i)\n               }, \n               \"%W %x #{index}\")\n\n    title.bind('B1-Motion', proc{|x| resize(x) if @mode == :sash}, \"%X\")\n  end\n\n  #################################\n  def browse_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_line(w, w.nearest(y))}, '%W %y')\n    t.bind('B1-Motion', proc{|w, y| select_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Shift-Button-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| select_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| select_shift(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Select', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Control-slash', \n           proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n\n    t\n  end\n\n  ########################\n  def single_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_only(w, w.nearest(y))}, '%W %y')\n    t.bind('ButtonRelease-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Shift-Button-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| select_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| select_shift(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Select', proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Control-slash', \n           proc{|w| select_line(w, w.index('active').to_i)}, '%W')\n    t.bind('Control-backslash', \n           proc{@lbox_list.each{|l| l.selection_clear(0, 'end')}})\n\n    t\n  end\n\n  ########################\n  def extended_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_only(w, w.nearest(y))}, '%W %y')\n    t.bind('B1-Motion', proc{|w, y| select_range(w, w.nearest(y))}, '%W %y')\n\n    t.bind('ButtonRelease-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Shift-Button-1', \n           proc{|w, y| select_range(w, w.nearest(y))}, '%W %y')\n    t.bind('Shift-B1-Motion', \n           proc{|w, y| select_range(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Control-Button-1', \n           proc{|w, y| select_toggle(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Control-B1-Motion', \n           proc{|w, y| select_drag(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| active_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| active_shift(w, 1)}, '%W')\n\n    t.bind('Shift-Up', proc{|w| select_expand(w, -1)}, '%W')\n    t.bind('Shift-Down', proc{|w| select_expand(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line2(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line2(w, 'end')}, '%W')\n\n    t.bind('Control-Shift-Home', proc{|w| select_range(w, 0)}, '%W')\n    t.bind('Control-Shift-End', proc{|w| select_range(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_active(w)}, '%W')\n    t.bind('Select', proc{|w| select_active(w)}, '%W')\n    t.bind('Control-slash', proc{|w| select_all}, '%W')\n    t.bind('Control-backslash', proc{|w| clear_all}, '%W')\n\n    t\n  end\n\n  ########################\n  def multiple_mode_bindtag\n    t = TkBindTag.new\n    t.bind('Button-1', \n           proc{|w, y| w.focus; select_line3(w, w.nearest(y))}, '%W %y')\n    t.bind('ButtonRelease-1', \n           proc{|w, y| active_line(w, w.nearest(y))}, '%W %y')\n\n    t.bind('Key-Up', proc{|w| active_shift(w, -1)}, '%W')\n    t.bind('Key-Down', proc{|w| active_shift(w, 1)}, '%W')\n\n    t.bind('Control-Home', proc{|w| select_line2(w, 0)}, '%W')\n    t.bind('Control-End', proc{|w| select_line2(w, 'end')}, '%W')\n\n    t.bind('Control-Shift-Home', proc{|w| active_line(w, 0)}, '%W')\n    t.bind('Control-Shift-End', proc{|w| active_line(w, 'end')}, '%W')\n\n    t.bind('space', proc{|w| select_active(w)}, '%W')\n    t.bind('Select', proc{|w| select_active(w)}, '%W')\n    t.bind('Control-slash', proc{|w| select_all}, '%W')\n    t.bind('Control-backslash', proc{|w| clear_all}, '%W')\n\n    t\n  end\n\n  ########################\n  def active_line(w, idx)\n    @lbox_list.each{|l| l.activate(idx)}\n  end\n\n  def select_only(w, idx)\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n  end\n\n  def select_range(w, idx)\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.selection_set('anchor', idx)\n    }\n  end\n\n  def select_toggle(w, idx)\n    st = w.selection_includes(idx)\n    @lbox_list.each{|l|\n      l.selection_anchor(idx)\n      if st == 1\n        l.selection_clear(idx)\n      else\n        l.selection_set(idx)\n      end\n    }\n  end\n\n  def select_drag(w, idx)\n    st = w.selection_includes('anchor')\n    @lbox_list.each{|l|\n      if st == 1\n        l.selection_set('anchor', idx)\n      else\n        l.selection_clear('anchor', idx)\n      end\n    }\n  end\n\n  def select_line(w, idx)\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.activate(idx)\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n    w.selection_set('anchor')\n  end\n\n  def select_line2(w, idx)\n    @lbox_list.each{|l|\n      l.activate(idx)\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n  end\n\n  def select_line3(w, idx)\n    @lbox_list.each{|l|\n      l.selection_set(idx)\n    }\n  end\n\n  def select_active(w)\n    idx = l.activate(idx)\n    @lbox_list.each{|l|\n      l.selection_set(idx)\n    }\n  end\n\n  def select_expand(w, dir)\n    idx = w.index('active').to_i + dir\n    if idx < 0\n      idx = 0\n    elsif idx >= w.size\n      idx = w.size - 1\n    end\n    @lbox_list.each{|l|\n      l.activate(idx)\n      l.selection_set(idx)\n    }\n  end\n\n  def active_shift(w, dir)\n    idx = w.index('active').to_i + dir\n    if idx < 0\n      idx = 0\n    elsif idx >= w.size\n      idx = w.size - 1\n    end\n    @lbox_list.each{|l|\n      l.activate(idx)\n      l.selection_anchor(idx)\n    }\n  end\n\n  def select_shift(w, dir)\n    idx = w.index('anchor').to_i + dir\n    if idx < 0\n      idx = 0\n    elsif idx >= w.size\n      idx = w.size - 1\n    end\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n      l.activate(idx)\n      l.selection_anchor(idx)\n      l.selection_set('anchor')\n    }\n  end\n\n  def select_all\n    @lbox_list.each{|l|\n      l.selection_set(0, 'end')\n    }\n  end\n\n  def clear_all\n    @lbox_list.each{|l|\n      l.selection_clear(0, 'end')\n    }\n  end\n\n  def focus_shift(w, dir)\n    idx = @lbox_list.index(w) + dir\n    return if idx < 0\n    return if idx >= @lbox_list.size\n    @lbox_list[idx].focus\n  end\n  ########################\nend\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  l = TkMultiListFrame.new(nil, 200, \n                           [ ['L1', 200, proc{p 'click L1'}], \n                             ['L2', 100], \n                             ['L3', 200] ], \n                           'width'=>350, \n                           #'titleforeground'=>'yellow', \n                           'titleforeground'=>'white', \n                           #'titlebackground'=>'navy',\n                           'titlebackground'=>'blue',\n                           'titlefont'=>'courier'\n                           ).pack('fill'=>'both', 'expand'=>true)\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', \n                   'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',\n                   'cccccccccccccccccccccccccccccccccccccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  l.insert('end', ['aaaaaaaaaaaaaaa','bbbbbbbbbbbbbb','ccccccccccccccccc'])\n  l.insert('end', [1,2,3])\n  l.insert('end', [4,5,6], [4,5,6])\n  p l.columns(1)\n  p l.columns(1..3)\n  p l.columns(1,2)\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tkoptdb-safeTk.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'multi-tk'\n\nTkMessage.new(:text => <<EOM).pack\nThis is a sample of the safe-Tk slave interpreter. \\\nOn the slave interpreter, 'tkoptdb.rb' demo is running.\n( NOTE:: a safe-Tk interpreter can't read options \\\nfrom a file. Options are given by the master interpreter \\\nin this script. )\nThe window shown this message is a root widget of \\\nthe default master interpreter. The other window \\\nis a toplevel widget of the master interpreter, and it \\\nhas a container frame of the safe-Tk slave interpreter.\n'exit' on the slave interpreter exits the slave only. \\\nYou can also delete the slave by the button on the toplevel widget.\nEOM\n\nif ENV['LANG'] =~ /^ja/\n  # read Japanese resource\n  ent = TkOptionDB.read_entries(File.expand_path('resource.ja', \n                                                 File.dirname(__FILE__)),\n                                'euc-jp')\nelse\n  # read English resource\n  ent = TkOptionDB.read_entries(File.expand_path('resource.en', \n                                                File.dirname(__FILE__)))\nend\n\nfile = File.expand_path('tkoptdb.rb', File.dirname(__FILE__))\n\nip = MultiTkIp.new_safeTk{\n  # When a block is given to 'new_safeTk' method, \n  # the block is evaluated on $SAFE==4.\n  ent.each{|pat, val| Tk.tk_call('option', 'add', pat, val)}\n}\n\nprint \"ip.eval_proc{$SAFE} ==> \", ip.eval_proc{$SAFE}, \"\\n\"\n\nprint \"\\ncall 'ip.wait_on_mainloop = false'\\n\"\nprint \"If 'ip.wait_on_mainloop? == true', \", \n  \"when 'mainloop' is called on 'ip.eval_proc', \", \n  \"'ip.eval_proc' does't return while the root window exists.\\n\", \n  \"If you want to avoid that, set wait_on_mainloop to false. \", \n  \"Then the mainloop in the eval_proc returns soon \", \n  \"and the following steps are evaluated. \\n\", \n  \"If you hate the both of them, use 'ip.bg_eval_proc' or \", \n  \"wrap 'ip.eval_proc' by a thread.\\n\"\n\nip.wait_on_mainloop = false\n\nret = ip.eval_proc{\n  # When a block is given to 'eval_proc' method, \n  # the block is evaluated on the IP's current safe level.\n  # So, the followings raises an exception. \n  # An Exception object of the exception is returned as a \n  # return value of this method.\n\n  load file\n}\nprint \"\\nip.eval_proc{}, which includes insecure operiation in the given block, returns an exception object: \", ret.inspect, \"\\n\"\n\nprint \"If a proc object is given, the proc is evaluated on the safe-level which is kept on the proc :: ip.eval_proc( proc{$SAFE} ) ==> \", ip.eval_proc(proc{$SAFE}), \"\\n\"\n\nsafe0_cmd = Proc.new{\n  print 'safe0_cmd safe-level == ', $SAFE, \"\\n\"\n  # This proc object keeps current safe-level ($SAFE==0). \n  load file\n}\nip.eval_proc{safe0_cmd.call}\n\n# Tk.mainloop is ignored on the slave-IP\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkoptdb.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  sample script of TkOptionDB\n#\n#  If 'LANG' environment variable's value is started by 'ja',  \n#  then read Japanese resource data and display Japanese button text. \n#  In other case, read English resource data and display English text. \n#\nrequire \"tk\"\n\nif __FILE__ == $0 || !TkCore::INTERP.safe?\n  if ENV['LANG'] =~ /^ja/\n    # read Japanese resource\n    TkOptionDB.read_with_encoding(File.expand_path('resource.ja', \n                                                   File.dirname(__FILE__)), \n                                  'euc-jp')\n  else\n    # read English resource\n    TkOptionDB.readfile(File.expand_path('resource.en', \n                                         File.dirname(__FILE__)))\n  end\nend\n\n# 'show_msg' and 'bye_msg' procedures can be defined on BTN_CMD resource.\n# Those procedures are called under $SAFE==2\ncmd = TkOptionDB.new_proc_class(:BTN_CMD, [:show_msg, :bye_msg], 3) {\n  # If you want to check resource string (str), \n  # please define __check_proc_string__(str) like this.\n  class << self\n    def __check_proc_string__(str)\n      print \"($SAFE=#{$SAFE} >>>) check!! str.tainted?::#{str.tainted?}\"\n      str.untaint\n      print \"==>#{str.tainted?} (<<< $SAFE=#{$SAFE}): \"\n      str\n    end\n    private :__check_proc_string__\n  end\n}\n\n# following two frame widgets use same database entry\nTkFrame.new(:class=>'BtnFrame'){|f|\n  pack(:padx=>5, :pady=>5)\n  TkButton.new(:parent=>f, :widgetname=>'hello'){ \n    command proc{\n      print \"($SAFE=#{$SAFE} >>>) : \"\n      cmd.show_msg(TkOptionDB.inspect)\n      print \"(<<< $SAFE=#{$SAFE})\"\n    } \n    pack(:fill=>:x, :padx=>10, :pady=>10)\n  }\n  TkButton.new(:command=>proc{\n                 print \"($SAFE=#{$SAFE} >>>) : \"\n                 cmd.bye_msg\n                 print \"(<<< $SAFE=#{$SAFE} ) : \"\n                 exit\n               }, \n               :parent=>f, :widgetname=>'quit'){\n    pack(:fill=>:x, :padx=>10, :pady=>10)\n  }\n}\n\nclass BtnFrame < TkFrame; end\nBtnFrame.new{|f|\n  pack(:padx=>5, :pady=>5)\n  TkButton.new(:parent=>f, :widgetname=>'hello'){ \n    command proc{\n      print \"($SAFE=#{$SAFE} >>>) : \"\n      cmd.show_msg(TkOptionDB.inspect)\n      print \"(<<< $SAFE=#{$SAFE})\"\n    } \n    pack(:fill=>:x, :padx=>10, :pady=>10)\n  }\n  TkButton.new(:command=>proc{\n                 print \"($SAFE=#{$SAFE} >>>) : \"\n                 cmd.bye_msg\n                 print \"(<<< $SAFE=#{$SAFE})\"\n                 exit\n               }, \n               :parent=>f, :widgetname=>'quit'){\n    pack(:fill=>:x, :padx=>10, :pady=>10)\n  }\n}\n\n# if unknown class, use default option values\nTkFrame.new(:class=>'BtnFrame2'){|f|\n  pack(:padx=>5, :pady=>5)\n  TkButton.new(:parent=>f, :widgetname=>'hello'){ \n    command proc{\n      print \"($SAFE=#{$SAFE} >>>) : \"\n      cmd.show_msg(TkOptionDB.inspect)\n      print \"(<<< $SAFE=#{$SAFE})\"\n    } \n    pack(:fill=>:x, :padx=>10, :pady=>10)\n  }\n  TkButton.new(:command=>proc{\n                 print \"($SAFE=#{$SAFE} >>>) : \"\n                 cmd.bye_msg\n                 print \"(<<< $SAFE=#{$SAFE})\"\n                 exit\n               }, \n               :parent=>f, :widgetname=>'quit'){\n    pack(:fill=>:x, :padx=>10, :pady=>10)\n  }\n}\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tkrttimer.rb",
    "content": "#!/usr/bin/env ruby\n# This script is a re-implementation of tktimer.rb with TkTimer(TkAfter) class.\n\nrequire \"tk\"\n\nroot = TkRoot.new(:title=>'realtime timer sample')\n\nf1 = TkFrame.new(:borderwidth=>2, :relief=>:ridge)\nf1.pack(:side=>:bottom, :fill=>:both)\nTkLabel.new(f1, :text=>'use TkTimer (TkAfter) class').pack(:anchor=>:center)\nlabel1 = TkLabel.new(:parent=>f1, :relief=>:raised, \n                     :width=>10).pack(:fill=>:both)\n\nf2 = TkFrame.new(:borderwidth=>2, :relief=>:ridge)\nf2.pack(:side=>:bottom, :fill=>:both)\nTkLabel.new(f2, :text=>'use TkRTTimer class').pack\nlabel2 = TkLabel.new(:parent=>f2, :relief=>:raised, \n                     :width=>10).pack(:fill=>:both)\n\nTkLabel.new(:padx=>10, :pady=>5, :justify=>'left', :text=><<EOT).pack\nInterval setting of each timer object is 10 ms.\nEach timer object counts up the value on each callback\n(the value is not the clock data).\nThe count of the TkTimer object is delayed by execution \ntime of callbacks and inaccuracy of interval.\nOn the other hand, the count of the TkRTTimer object is \nnot delayed. Its callback interval is not accurate too. \nBut it can compute error correction about the time when \na callback should start.\nEOT\n\n# define the procedure repeated by the TkTimer object\ntick = proc{|aobj| #<== TkTimer object\n  cnt = aobj.return_value + 1  # return_value keeps a result of the last proc\n  label = aobj.current_args[0]\n  label.text format(\"%d.%02d\", *(cnt.divmod(100)))\n  cnt #==> return value is kept by TkTimer object\n      #    (so, can be send to the next repeat-proc)\n}\n\ntimer1 = TkTimer.new(10, -1, [tick, label1])    # 10 ms interval\ntimer2 = TkRTTimer.new(10, -1, [tick, label2])  # 10 ms interval\n\ntimer1.start(0, proc{ label1.text('0.00'); 0 })\ntimer2.start(0, proc{ label2.text('0.00'); 0 })\n\nb_start = TkButton.new(:text=>'Start', :state=>:disabled) {\n  pack(:side=>:left, :fill=>:both, :expand=>true)\n}\n\nb_stop  = TkButton.new(:text=>'Stop', :state=>:normal) {\n  pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n}\n\nb_start.command {\n  timer1.continue\n  timer2.continue\n  b_stop.state(:normal)\n  b_start.state(:disabled)\n}\n\nb_stop.command {\n  timer1.stop\n  timer2.stop\n  b_start.state(:normal)\n  b_stop.state(:disabled)\n}\n\nTkButton.new(:text=>'Reset', :state=>:normal) {\n  command { timer1.reset; timer2.reset }\n  pack(:side=>:right, :fill=>:both, :expand=>:yes)\n}\n\nev_quit = TkVirtualEvent.new('Control-c', 'Control-q')\nTk.root.bind(ev_quit, proc{Tk.exit}).focus\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tksleep_sample.rb",
    "content": "require 'tk'\n\nv = TkVariable.new(0)\nl = TkLabel.new(:textvariable=>v).pack(:pady=>[1, 10])\n\na = TkButton.new(:text=>\"button A :: proc{p ['AAA', v.value]}\").pack(:fill=>:x, :pady=>[1, 15], :padx=>15)\na.command{p ['AAA', v.value]}\n\nTkLabel.new(:text=>'Callback of the button B returns LIFO order').pack\nb = TkButton.new(:text=>\"button B :: proc{n = v.value; p ['B:start', n]; Tk.sleep(10000); p ['B:end', n]}\").pack(:fill=>:x, :pady=>[1, 15], :padx=>15)\nb.command{n = v.value; p ['B:start', n]; Tk.sleep(10000); p ['B:end', n]}\n\nTkLabel.new(:text=>'Callback of the button C returns FIFO order').pack\nc = TkButton.new(:text=>\"button C :: proc{n = v.value; Thread.new{p ['C:start', n]; Tk.sleep(10000); p ['C:end', n]}}\").pack(:fill=>:x, :pady=>[1, 15], :padx=>15)\nc.command{n = v.value; Thread.new{p ['C:start', n]; Tk.sleep(10000); p ['C:end', n]}}\n\nTkLabel.new(:text=>'Callback of the button D blocks eventloop (no respond to event)').pack\nd = TkButton.new(:text=>\"button D :: proc{n = v.value; p ['D:start', n]; sleep(10); p ['D:end', n]}\").pack(:fill=>:x, :pady=>[1,15], :padx=>15)\nd.command{n = v.value; p ['D:start', n]; sleep(10); p ['D:end', n]}\n\nTkLabel.new(:text=>'Callback of the button E is another way to avoid eventloop blocking').pack\ne = TkButton.new(:text=>\"button E :: proc{n = v.value; Thread.new{p ['D:start', n]; sleep(10); p ['D:end', n]}}\").pack(:fill=>:x, :pady=>[1,15], :padx=>15)\ne.command{n = v.value; Thread.new{p ['D:start', n]; sleep(10); p ['D:end', n]}}\n\nTkButton.new(:text=>'QUIT', :command=>proc{exit}).pack\n\nTkTimer.new(500, -1){v.numeric += 1}.start\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tktextframe.rb",
    "content": "#\n#  tktextframe.rb : a sample of TkComposite\n#\n#                         by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nrequire 'tk'\n\nclass TkTextFrame < TkText\n  include TkComposite\n\n  def initialize_composite(keys={})\n    keys = _symbolkey2str(keys)\n\n    # create scrollbars\n    @v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')\n    @h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal')\n\n    # create a text widget\n    @text = TkText.new(@frame, 'wrap'=>'none')\n\n    # set default receiver of method calls\n    @path = @text.path\n\n    # assign scrollbars\n    @text.xscrollbar(@h_scroll)\n    @text.yscrollbar(@v_scroll)\n\n    # allignment\n    TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)\n    TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)\n    @text.grid('row'=>0, 'column'=>0, 'sticky'=>'news')\n\n    # scrollbars ON\n    vscroll(keys.delete('vscroll'){true})\n    hscroll(keys.delete('hscroll'){true})\n\n    # set background of the text widget\n=begin\n    color = keys.delete('textbackground')\n    textbackground(color) if color\n=end\n    # please check the differences of the following definitions\n    option_methods(\n       [:scrollbarwidth, :get_scrollbarwidth], \n       [:textbackground, nil, :textbg_info], \n       :textborderwidth, \n       :textrelief\n    )\n\n    # set receiver widgets for configure methods (with alias)\n    delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll)\n\n    # set receiver widgets for configure methods\n    delegate('DEFAULT', @text)\n    delegate('background', @frame, @h_scroll, @v_scroll)\n    delegate('activebackground', @h_scroll, @v_scroll)\n    delegate('troughcolor', @h_scroll, @v_scroll)\n    delegate('repeatdelay', @h_scroll, @v_scroll)\n    delegate('repeatinterval', @h_scroll, @v_scroll)\n    delegate('borderwidth', @frame)\n    delegate('relief', @frame)\n\n    # do configure\n    configure keys unless keys.empty?\n  end\n  private :initialize_composite\n\n  # set background color of text widget\n  def textbackground(color = nil)\n    if color\n      @text.background(color)\n    else\n      @text.background\n    end\n  end\n\n  def textbg_info\n    info = @text.configinfo(:background)\n    if TkComm::GET_CONFIGINFO_AS_ARRAY\n      info[0] = 'textbackground'\n      info\n    else # ! TkComm::GET_CONFIGINFO_AS_ARRAY\n      {'textbackground' => info['background']}\n    end\n  end\n\n  # get/set borderwidth of text widget\n  def set_textborderwidth(width)\n    @text.borderwidth(width)\n  end\n  def get_textborderwidth\n    @text.borderwidth\n  end\n  def textborderwidth(width = nil)\n    if width\n      set_textborderwidth(width)\n    else\n      get_textborderwidth\n    end\n  end\n\n  # set relief of text widget\n  def textrelief(type)\n    @text.relief(type)\n  end\n\n  # get/set width of scrollbar\n  def get_scrollbarwidth\n    @v_scroll.width\n  end\n  def set_scrollbarwidth(width)\n    @v_scroll.width(width)\n    @h_scroll.width(width)\n  end\n  alias :scrollbarwidth :set_scrollbarwidth\n\n  # vertical scrollbar : ON/OFF\n  def vscroll(mode)\n    st = TkGrid.info(@v_scroll)\n    if mode && st.size == 0 then\n      @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')\n    elsif !mode && st.size != 0 then\n      @v_scroll.ungrid\n    end\n    self\n  end\n\n  # horizontal scrollbar : ON/OFF\n  def hscroll(mode, wrap_mode=\"char\")\n    st = TkGrid.info(@h_scroll)\n    if mode && st.size == 0 then\n      @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')\n      wrap 'none'  # => self.wrap('none')\n    elsif !mode && st.size != 0 then\n      @h_scroll.ungrid\n      wrap wrap_mode  # => self.wrap(wrap_mode)\n    end\n    self\n  end\nend\n\n\n################################################\n# test\n################################################\nif __FILE__ == $0\n  f = TkFrame.new.pack('fill'=>'x')\n  #t = TkTextFrame.new.pack\n  t = TkTextFrame.new(:textborderwidth=>3, \n                      :textrelief=>:ridge, \n                      :scrollbarrelief=>:ridge).pack\n  p t.configinfo\n  TkButton.new(f, 'text'=>'vscr OFF', \n               'command'=>proc{t.vscroll(false)}).pack('side'=>'right')\n  TkButton.new(f, 'text'=>'vscr ON', \n               'command'=>proc{t.vscroll(true)}).pack('side'=>'right')\n  TkButton.new(f, 'text'=>'hscr ON', \n               'command'=>proc{t.hscroll(true)}).pack('side'=>'left')\n  TkButton.new(f, 'text'=>'hscr OFF', \n               'command'=>proc{t.hscroll(false)}).pack('side'=>'left')\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tktextio.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  TkTextIO class :: handling I/O stream on a TkText widget\n#                             by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\n#  NOTE: TkTextIO supports 'character' (not 'byte') access only. \n#        So, for example, TkTextIO#getc returns a character, TkTextIO#pos \n#        means the character position, TkTextIO#read(size) counts by \n#        characters, and so on.\n#        Of course, it is available to make TkTextIO class to suuport \n#        'byte' access. However, it may break multi-byte characters. \n#        and then, displayed string on the text widget may be garbled.\n#        I think that it is not good on the supposed situation of using \n#        TkTextIO. \n#\nrequire 'tk'\nrequire 'tk/text'\nrequire 'tk/textmark'\nrequire 'thread'\n\nclass TkTextIO < TkText\n  # keep safe level\n  @@create_queues = proc{ [Queue.new, Mutex.new, Queue.new, Mutex.new] }\n\n  OPT_DEFAULTS = {\n    'mode'       => nil,\n    'overwrite'  => false, \n    'text'       => nil, \n    'show'       => :pos, \n    'wrap'       => 'char', \n    'sync'       => true, \n    'prompt'     => nil, \n    'prompt_cmd' => nil, \n    'hist_size'  => 1000, \n  }\n\n  def create_self(keys)\n    opts = _get_io_params((keys.kind_of?(Hash))? keys: {})\n\n    super(keys)\n\n    @count_var = TkVariable.new\n\n    @write_buffer = ''\n    @read_buffer  = ''\n    @buf_size = 0\n    @buf_max = 1024\n\n    @write_buf_queue, @write_buf_mutex, \n    @read_buf_queue,  @read_buf_mutex  = @@create_queues.call\n\n    @idle_flush  = TkTimer.new(:idle, 1, proc{ @flusher.run rescue nil })\n    @timer_flush = TkTimer.new(250, -1, proc{ @flusher.run rescue nil })\n\n    @flusher = Thread.new{ loop { Thread.stop; flush() } }\n\n    @receiver = Thread.new{\n      begin\n        loop {\n          str = @write_buf_queue.deq\n          @write_buf_mutex.synchronize { @write_buffer << str }\n          @idle_flush.start\n        }\n      ensure\n        @flusher.kill\n      end\n    }\n\n    @timer_flush.start\n\n    _setup_io(opts)\n  end\n  private :create_self\n\n  def destroy\n    @flusher.kill rescue nil\n\n    @idle_flush.stop rescue nil\n    @timer_flush.stop rescue nil\n\n    @receiver.kill rescue nil\n\n    super()\n  end\n\n  ####################################\n\n  def _get_io_params(keys)\n    opts = {}\n    self.class.const_get(:OPT_DEFAULTS).each{|k, v| \n      if keys.has_key?(k)\n        opts[k] = keys.delete(k)\n      else\n        opts[k] = v\n      end\n    }\n    opts\n  end\n\n  def _setup_io(opts)\n    unless defined? @txtpos\n      @txtpos = TkTextMark.new(self, '1.0')\n    else\n      @txtpos.set('1.0')\n    end\n    @txtpos.gravity = :left\n\n    @lineno = 0\n    @line_offset = 0\n\n    @hist_max = opts['hist_size'].to_i\n    @hist_index = 0\n    @history = Array.new(@hist_max)\n    @history[0] = ''\n\n    self['wrap'] = wrap\n\n    self.show_mode = opts['show']\n\n    self.value = opts['text'] if opts['text']\n\n    @overwrite = (opts['overwrite'])? true: false\n\n    @sync = opts['sync']\n\n    @prompt = opts['prompt']\n    @prompt_cmd = opts['prompt_cmd']\n\n    @open  = {:r => true,  :w => true}  # default is 'r+'\n\n    @console_mode = false\n    @end_of_stream = false\n    @console_buffer = nil\n\n    case opts['mode']\n    when nil\n      # do nothing\n\n    when :console, 'console'\n      @console_mode = true\n      # @console_buffer = TkTextIO.new(:mode=>'r')\n      @console_buffer = self.class.new(:mode=>'r')\n      self.show_mode = :insert\n\n    when 'r', 'rb'\n      @open[:r] = true; @open[:w] = nil\n\n    when 'r+', 'rb+', 'r+b'\n      @open[:r] = true; @open[:w] = true\n\n    when 'w', 'wb'\n      @open[:r] = nil;  @open[:w] = true\n      self.value=''\n\n    when 'w+', 'wb+', 'w+b'\n      @open[:r] = true; @open[:w] = true\n      self.value=''\n\n    when 'a', 'ab'\n      @open[:r] = nil;  @open[:w] = true\n      @txtpos.set('end - 1 char')\n      @txtpos.gravity = :right\n\n    when 'a+', 'ab+', 'a+b'\n      @open[:r] = true;  @open[:w] = true\n      @txtpos.set('end - 1 char')\n      @txtpos.gravity = :right\n\n    else\n      fail ArgumentError, \"unknown mode `#{opts['mode']}'\"\n    end\n\n    unless defined? @ins_head\n      @ins_head = TkTextMark.new(self, 'insert')\n      @ins_head.gravity = :left\n    end\n\n    unless defined? @ins_tail\n      @ins_tail = TkTextMark.new(self, 'insert')\n      @ins_tail.gravity = :right\n    end\n\n    unless defined? @tmp_mark\n      @tmp_mark = TkTextMark.new(self, 'insert')\n      @tmp_mark.gravity = :left\n    end\n\n    if @console_mode\n      _set_console_line\n      _setup_console_bindings\n    end\n  end\n  private :_get_io_params, :_setup_io\n\n  def _set_console_line\n    @tmp_mark.set(@ins_tail)\n\n    mark_set('insert', 'end')\n\n    prompt = ''\n    prompt << @prompt_cmd.call if @prompt_cmd\n    prompt << @prompt if @prompt\n    insert(@tmp_mark, prompt)\n\n    @ins_head.set(@ins_tail)\n    @ins_tail.set('insert')\n\n    @txtpos.set(@tmp_mark)\n\n    _see_pos\n  end\n\n  def _replace_console_line(str)\n    self.delete(@ins_head, @ins_tail)\n    self.insert(@ins_head, str)\n  end\n\n  def _get_console_line\n    @tmp_mark.set(@ins_tail)\n    s = self.get(@ins_head, @tmp_mark)\n    _set_console_line\n    s\n  end\n  private :_set_console_line, :_replace_console_line, :_get_console_line\n\n  def _cb_up\n    @history[@hist_index].replace(self.get(@ins_head, @ins_tail))\n    @hist_index += 1\n    @hist_index -= 1 if @hist_index >= @hist_max || !@history[@hist_index]\n    _replace_console_line(@history[@hist_index]) if @history[@hist_index]\n    Tk.callback_break\n  end\n  def _cb_down\n    @history[@hist_index].replace(self.get(@ins_head, @ins_tail))\n    @hist_index -= 1\n    @hist_index = 0 if @hist_index < 0\n    _replace_console_line(@history[@hist_index]) if @history[@hist_index]\n    Tk.callback_break\n  end\n  def _cb_left\n    if @console_mode && compare('insert', '<=', @ins_head)\n      mark_set('insert', @ins_head)\n      Tk.callback_break\n    end\n  end\n  def _cb_backspace\n    if @console_mode && compare('insert', '<=', @ins_head)\n      Tk.callback_break\n    end\n  end\n  def _cb_ctrl_a\n    if @console_mode\n      mark_set('insert', @ins_head)\n      Tk.callback_break\n    end\n  end\n  def _cb_ctrl_u\n    if @console_mode\n      mark_set('insert', @ins_head)\n      delete('insert', 'insert lineend')\n      Tk.callback_break\n    end\n  end\n  private :_cb_up, :_cb_down, :_cb_left, :_cb_backspace, \n          :_cb_ctrl_a, :_cb_ctrl_u\n\n  def _setup_console_bindings\n    @bindtag = TkBindTag.new\n\n    tags = self.bindtags\n    tags[tags.index(self)+1, 0] = @bindtag\n    self.bindtags = tags\n\n    @bindtag.bind('Return'){\n      insert('end - 1 char', \"\\n\")\n      if (str = _get_console_line)\n        @read_buf_queue.push(str)\n\n        @history[0].replace(str.chomp)\n        @history.pop\n        @history.unshift('')\n        @hist_index = 0\n      end\n\n      Tk.update\n      Tk.callback_break\n    }\n    @bindtag.bind('Alt-Return'){\n      Tk.callback_continue\n    }\n\n    @bindtag.bind('FocusIn'){\n      if @console_mode\n        mark_set('insert', @ins_tail)\n        Tk.callback_break\n      end\n    }\n\n    ins_mark = TkTextMark.new(self, 'insert')\n\n    @bindtag.bind('ButtonPress'){\n      if @console_mode\n        ins_mark.set('insert')\n      end\n    }\n\n    @bindtag.bind('ButtonRelease-1'){\n      if @console_mode && compare('insert', '<=', @ins_head)\n        mark_set('insert', ins_mark)\n        Tk.callback_break\n      end\n    }\n\n    @bindtag.bind('ButtonRelease-2', '%x %y'){|x, y|\n      if @console_mode\n        # paste a text at 'insert' only\n        x1, y1, x2, y2 =  bbox(ins_mark)\n        unless x == x1 && y == y1\n          Tk.event_generate(self, 'ButtonRelease-2', :x=>x1, :y=>y1)\n          Tk.callback_break\n        end\n      end\n    }\n\n    @bindtag.bind('Up'){ _cb_up }\n    @bindtag.bind('Control-p'){ _cb_up }\n\n    @bindtag.bind('Down'){ _cb_down }\n    @bindtag.bind('Control-n'){ _cb_down }\n\n    @bindtag.bind('Left'){ _cb_left }\n    @bindtag.bind('Control-b'){ _cb_left }\n\n    @bindtag.bind('BackSpace'){ _cb_backspace }\n    @bindtag.bind('Control-h'){ _cb_backspace }\n\n    @bindtag.bind('Home'){ _cb_ctrl_a }\n    @bindtag.bind('Control-a'){ _cb_ctrl_a }\n\n    @bindtag.bind('Control-u'){ _cb_ctrl_u }\n  end\n  private :_setup_console_bindings\n\n  def _block_read(size = nil, ret = '', block_mode = true)\n    return '' if size == 0\n    return nil if ! @read_buf_queue && @read_buffer.empty?\n    ret = '' unless ret.kind_of?(String)\n    ret.replace('') unless ret.empty?\n\n    if block_mode == nil # partial\n      if @read_buffer.empty?\n        ret << @read_buffer.slice!(0..-1)\n        return ret\n      end\n    end\n\n    if size.kind_of?(Numeric)\n      loop{\n        @read_buf_mutex.synchronize {\n          buf_len = @read_buffer.length\n          if buf_len >= size\n            ret << @read_buffer.slice!(0, size)\n            return ret\n          else\n            ret << @read_buffer.slice!(0..-1)\n            size -= buf_len\n            return ret unless @read_buf_queue\n          end\n        }\n        @read_buffer << @read_buf_queue.pop\n      }\n    else # readline\n      rs = (size)? size: $/\n      rs = rs.to_s if rs.kind_of?(Regexp)\n      loop{\n        @read_buf_mutex.synchronize {\n          if (str = @read_buffer.slice!(/\\A(.*)(#{rs})/m))\n            ret << str\n            return ret\n          else\n            ret << @read_buffer.slice!(0..-1)\n            return ret unless @read_buf_queue\n          end\n        }\n        @read_buffer << @read_buf_queue.pop\n      }\n    end\n  end\n\n  def _block_write\n    ###### currently, not support\n  end\n  private :_block_read, :_block_write\n\n  ####################################\n\n  def <<(obj)\n    _write(obj)\n    self\n  end\n\n  def binmode\n    self\n  end\n\n  def clone\n    fail NotImplementedError, 'cannot clone TkTextIO'\n  end\n  def dup\n    fail NotImplementedError, 'cannot duplicate TkTextIO'\n  end\n\n  def close\n    close_read\n    close_write\n    nil\n  end\n  def close_read\n    @open[:r] = false if @open[:r]\n    nil\n  end\n  def close_write\n    @open[:w] = false if @opne[:w]\n    nil\n  end\n\n  def closed?(dir=nil)\n    case dir\n    when :r, 'r'\n      !@open[:r]\n    when :w, 'w'\n      !@open[:w]\n    else\n      !@open[:r] && !@open[:w]\n    end\n  end\n\n  def _check_readable\n    fail IOError, \"not opened for reading\" if @open[:r].nil?\n    fail IOError, \"closed stream\" if !@open[:r]\n  end\n  def _check_writable\n    fail IOError, \"not opened for writing\" if @open[:w].nil?\n    fail IOError, \"closed stream\" if !@open[:w]\n  end\n  private :_check_readable, :_check_writable\n\n  def each_line(rs = $/)\n    _check_readable\n    while(s = self.gets(rs))\n      yield(s)\n    end\n    self\n  end\n  alias each each_line\n\n  def each_char\n    _check_readable\n    while(c = self.getc)\n      yield(c)\n    end\n    self\n  end\n  alias each_byte each_char\n\n  def eof?\n    compare(@txtpos, '==', 'end - 1 char')\n  end\n  alias eof eof?\n\n  def fcntl(*args)\n    fail NotImplementedError, \"fcntl is not implemented on #{self.class}\"\n  end\n\n  def fsync\n    0\n  end\n\n  def fileno\n    nil\n  end\n\n  def flush\n    Thread.pass\n    if @open[:w] || ! @write_buffer.empty?\n      @write_buf_mutex.synchronize {\n        _sync_write_buf(@write_buffer) \n        @write_buffer[0..-1] = ''\n      }\n    end\n    self\n  end\n\n  def getc\n    return _block_read(1) if @console_mode\n\n    _check_readable\n    return nil if eof?\n    c = get(@txtpos)\n    @txtpos.set(@txtpos + '1 char')\n    _see_pos\n    c\n  end\n\n  def gets(rs = $/)\n    return _block_read(rs) if @console_mode\n\n    _check_readable\n    return nil if eof?\n    _readline(rs)\n  end\n\n  def ioctrl(*args)\n    fail NotImplementedError, 'iocntl is not implemented on TkTextIO'\n  end\n\n  def isatty\n    false\n  end\n  def tty?\n    false\n  end\n\n  def lineno\n    @lineno + @line_offset\n  end\n\n  def lineno=(num)\n    @line_offset = num - @lineno\n    num\n  end\n\n  def overwrite?\n    @overwrite\n  end\n\n  def overwrite=(ovwt)\n    @overwrite = (ovwt)? true: false\n  end\n\n  def pid\n    nil\n  end\n\n  def index_pos\n    index(@txtpos)\n  end\n  alias tell_index index_pos\n\n  def index_pos=(idx)\n    @txtpos.set(idx)\n    @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n    _see_pos\n    idx\n  end\n\n  def pos\n    s = get('1.0', @txtpos)\n    number(tk_call('string', 'length', s))\n  end\n  alias tell pos\n\n  def pos=(idx)\n    seek(idx, IO::SEEK_SET)\n    idx\n  end\n\n  def pos_gravity\n    @txtpos.gravity\n  end\n\n  def pos_gravity=(side)\n    @txtpos.gravity = side\n    side\n  end\n\n  def print(arg=$_, *args)\n    _check_writable\n    args.unshift(arg)\n    args.map!{|val| (val == nil)? 'nil': val.to_s }\n    str = args.join($,)\n    str << $\\ if $\\\n    _write(str)\n    nil\n  end\n  def printf(*args)\n    _check_writable\n    _write(sprintf(*args))\n    nil\n  end\n\n  def putc(c)\n    _check_writable\n    c = c.chr if c.kind_of?(Fixnum)\n    _write(c)\n    c\n  end\n\n  def puts(*args)\n    _check_writable\n    if args.empty?\n      _write(\"\\n\")\n      return nil\n    end\n    args.each{|arg|\n      if arg == nil\n        _write(\"nil\\n\")\n      elsif arg.kind_of?(Array)\n        puts(*arg)\n      elsif arg.kind_of?(String)\n        _write(arg.chomp)\n        _write(\"\\n\")\n      else\n        begin\n          arg = arg.to_ary\n          puts(*arg)\n        rescue\n          puts(arg.to_s)\n        end\n      end\n    }\n    nil\n  end\n\n  def _read(len)\n    epos = @txtpos + \"#{len} char\"\n    s = get(@txtpos, epos)\n    @txtpos.set(epos)\n    @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n    _see_pos\n    s\n  end\n  private :_read\n\n  def read(len=nil, buf=nil)\n    return _block_read(len, buf) if @console_mode\n\n    _check_readable\n    if len\n      return \"\" if len == 0\n      return nil if eof?\n      s = _read(len)\n    else\n      s = get(@txtpos, 'end - 1 char')\n      @txtpos.set('end - 1 char')\n      _see_pos\n    end\n    buf.replace(s) if buf.kind_of?(String)\n    s\n  end\n\n  def readchar\n    return _block_read(1) if @console_mode\n\n    _check_readable\n    fail EOFError if eof?\n    c = get(@txtpos)\n    @txtpos.set(@txtpos + '1 char')\n    _see_pos\n    c\n  end\n\n  def _readline(rs = $/)\n    if rs == nil\n      s = get(@txtpos, 'end - 1 char')\n      @txtpos.set('end - 1 char')\n    elsif rs == ''\n      @count_var.value  # make it global\n      idx = tksearch_with_count([:regexp], @count_var, \n                                   \"\\n(\\n)+\", @txtpos, 'end - 1 char')\n      if idx\n        s = get(@txtpos, idx) << \"\\n\"\n        @txtpos.set(\"#{idx} + #{@count_var.value} char\")\n        @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n      else\n        s = get(@txtpos, 'end - 1 char')\n        @txtpos.set('end - 1 char')\n      end\n    else\n      @count_var.value  # make it global\n      idx = tksearch_with_count(@count_var, rs, @txtpos, 'end - 1 char')\n      if idx\n        s = get(@txtpos, \"#{idx} + #{@count_var.value} char\")\n        @txtpos.set(\"#{idx} + #{@count_var.value} char\")\n        @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n      else\n        s = get(@txtpos, 'end - 1 char')\n        @txtpos.set('end - 1 char')\n      end\n    end\n\n    _see_pos\n    @lineno += 1\n    $_ = s\n  end\n  private :_readline\n\n  def readline(rs = $/)\n    return _block_readline(rs) if @console_mode\n\n    _check_readable\n    fail EOFError if eof?\n    _readline(rs)\n  end\n\n  def readlines(rs = $/)\n    if @console_mode\n      lines = []\n      while (line = _block_readline(rs))\n        lines << line\n      end\n      return lines\n    end\n\n    _check_readable\n    lines = []\n    until(eof?)\n      lines << _readline(rs)\n    end\n    $_ = nil\n    lines\n  end\n\n  def readpartial(maxlen, buf=nil)\n    #return @console_buffer.readpartial(maxlen, buf) if @console_mode\n    return _block_read(maxlen, buf, nil) if @console_mode\n\n    _check_readable\n    fail EOFError if eof?\n    s = _read(maxlen)\n    buf.replace(s) if buf.kind_of?(String)\n    s\n  end\n\n  def reopen(*args)\n    fail NotImplementedError, 'reopen is not implemented on TkTextIO'\n  end\n\n  def rewind\n    @txtpos.set('1.0')\n    _see_pos\n    @lineno = 0\n    @line_offset = 0\n    self\n  end\n\n  def seek(offset, whence=IO::SEEK_SET)\n    case whence\n    when IO::SEEK_SET\n      offset = \"1.0 + #{offset} char\" if offset.kind_of?(Numeric)\n      @txtpos.set(offset)\n\n    when IO::SEEK_CUR\n      offset = \"#{offset} char\" if offset.kind_of?(Numeric)\n      @txtpos.set(@txtpos + offset)\n\n    when IO::SEEK_END\n      offset = \"#{offset} char\" if offset.kind_of?(Numeric)\n      @txtpos.set(\"end - 1 char + #{offset}\")\n\n    else\n      fail Errno::EINVAL, 'invalid whence argument'\n    end\n\n    @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n    _see_pos\n\n    0\n  end\n  alias sysseek seek\n\n  def _see_pos\n    see(@show) if @show\n  end\n  private :_see_pos\n\n  def show_mode\n    (@show == @txtpos)? :pos : @show\n  end\n\n  def show_mode=(mode)\n    # define show mode  when file position is changed. \n    #  mode == :pos or \"pos\" or true :: see current file position. \n    #  mode == :insert or \"insert\"   :: see insert cursor position. \n    #  mode == nil or false          :: do nothing\n    #  else see 'mode' position ('mode' should be text index or mark)\n    case mode\n    when :pos, 'pos', true\n      @show = @txtpos\n    when :insert, 'insert'\n      @show = :insert\n    when nil, false\n      @show = false\n    else\n      begin\n        index(mode)\n      rescue\n        fail ArgumentError, 'invalid show-position'\n      end\n      @show = mode\n    end\n\n    _see_pos\n\n    mode\n  end\n\n  def stat\n    fail NotImplementedError, 'stat is not implemented on TkTextIO'\n  end\n\n  def sync\n    @sync\n  end\n\n  def sync=(mode)\n    @sync = mode\n  end\n\n  def sysread(len, buf=nil)\n    return _block_read(len, buf) if @console_mode\n\n    _check_readable\n    fail EOFError if eof?\n    s = _read(len)\n    buf.replace(s) if buf.kind_of?(String)\n    s\n  end\n\n  def syswrite(obj)\n    _write(obj)\n  end\n\n  def to_io\n    self\n  end\n\n  def trancate(len)\n    delete(\"1.0 + #{len} char\", :end)\n    0\n  end\n\n  def ungetc(c)\n    if @console_mode\n      @read_buf_mutex.synchronize {\n        @read_buffer[0,0] = c.chr\n      }\n      return nil\n    end\n\n    _check_readable\n    c = c.chr if c.kind_of?(Fixnum)\n    if compare(@txtpos, '>', '1.0')\n      @txtpos.set(@txtpos - '1 char')\n      delete(@txtpos)\n      insert(@txtpos, tk_call('string', 'range', c, 0, 1))\n      @txtpos.set(@txtpos - '1 char') if @txtpos.gravity == 'right'\n      _see_pos\n    else\n      fail IOError, 'cannot ungetc at head of stream'\n    end\n    nil\n  end\n\n=begin\n  def _write(obj)\n    #s = _get_eval_string(obj)\n    s = (obj.kind_of?(String))? obj: obj.to_s\n    n = number(tk_call('string', 'length', s))\n    delete(@txtpos, @txtpos + \"#{n} char\") if @overwrite\n    self.insert(@txtpos, s)\n    @txtpos.set(@txtpos + \"#{n} char\")\n    @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n    _see_pos\n    Tk.update if @sync\n    n\n  end\n  private :_write\n=end\n#=begin\n  def _sync_write_buf(s)\n    if (n = number(tk_call('string', 'length', s))) > 0\n      delete(@txtpos, @txtpos + \"#{n} char\") if @overwrite\n      self.insert(@txtpos, s)\n      #Tk.update\n\n      @txtpos.set(@txtpos + \"#{n} char\")\n      @txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)\n\n      @ins_head.set(@txtpos) if compare(@txtpos, '>', @ins_head)\n\n      _see_pos\n    end\n    self\n  end\n  private :_sync_write_buf\n\n  def _write(obj)\n    s = (obj.kind_of?(String))? obj: obj.to_s\n    n = number(tk_call('string', 'length', s))\n    @write_buf_queue.enq(s)\n    if @sync\n      Thread.pass\n      Tk.update\n    end\n    n\n  end\n  private :_write\n#=end\n\n  def write(obj)\n    _check_writable\n    _write(obj)\n  end\nend\n\n####################\n#  TEST\n####################\nif __FILE__ == $0\n  ev_loop = Thread.new{Tk.mainloop}\n\n  f = TkFrame.new.pack\n  #tio = TkTextIO.new(f, :show=>:nil, \n  #tio = TkTextIO.new(f, :show=>:pos, \n  tio = TkTextIO.new(f, :show=>:insert, \n                     :text=>\">>> This is an initial text line. <<<\\n\\n\"){\n#    yscrollbar(TkScrollbar.new(f).pack(:side=>:right, :fill=>:y))\n    pack(:side=>:left, :fill=>:both, :expand=>true)\n  }\n\n  Tk.update\n\n  $stdin  = tio\n  $stdout = tio\n  $stderr = tio\n\n  STDOUT.print(\"\\n========= TkTextIO#gets for inital text ========\\n\\n\")\n\n  while(s = gets)\n    STDOUT.print(s)\n  end\n\n  STDOUT.print(\"\\n============ put strings to TkTextIO ===========\\n\\n\")\n\n  puts \"On this sample, a text widget works as if it is a I/O stream.\"\n  puts \"Please see the code.\"\n  puts\n  printf(\"printf message: %d %X\\n\", 123456, 255)\n  puts\n  printf(\"(output by 'p' method) This TkTextIO object is ...\\n\")\n  p tio\n  print(\" [ Current wrap mode of this object is 'char'. ]\\n\")\n  puts\n  warn(\"This is a warning message generated by 'warn' method.\")\n  puts\n  puts \"current show_mode is #{tio.show_mode}.\"\n  if tio.show_mode == :pos\n    puts \"So, you can see the current file position on this text widget.\"\n  else\n    puts \"So, you can see the position '#{tio.show_mode}' on this text widget.\"\n  end\n  print(\"Please scroll up this text widget to see the head of lines.\\n\")\n  print(\"---------------------------------------------------------\\n\")\n\n  STDOUT.print(\"\\n=============== TkTextIO#readlines =============\\n\\n\")\n\n  tio.seek(0)\n  lines = readlines\n  STDOUT.puts(lines.inspect)\n\n  STDOUT.print(\"\\n================== TkTextIO#each ===============\\n\\n\")\n\n  tio.rewind\n  tio.each{|line| STDOUT.printf(\"%2d: %s\\n\", tio.lineno, line.chomp)}\n\n  STDOUT.print(\"\\n================================================\\n\\n\")\n\n  STDOUT.print(\"\\n========= reverse order (seek by lines) ========\\n\\n\")\n\n  tio.seek(-1, IO::SEEK_END)\n  begin\n    begin\n      tio.seek(:linestart, IO::SEEK_CUR)\n    rescue\n      # maybe use old version of tk/textmark.rb\n      tio.seek('0 char linestart', IO::SEEK_CUR)\n    end\n    STDOUT.print(gets)\n    tio.seek('-1 char linestart -1 char', IO::SEEK_CUR)\n  end while(tio.pos > 0)\n\n  STDOUT.print(\"\\n================================================\\n\\n\")\n\n  tio.seek(0, IO::SEEK_END)\n\n  STDOUT.print(\"tio.sync ==  #{tio.sync}\\n\")\n#  tio.sync = false\n#  STDOUT.print(\"tio.sync ==  #{tio.sync}\\n\")\n\n  (0..10).each{|i|\n    STDOUT.print(\"#{i}\\n\")\n    s = ''\n    (0..1000).each{ s << '*' }\n    print(s)\n  }\n  print(\"\\n\")\n  print(\"\\n=========================================================\\n\\n\")\n\n  s = ''\n  timer = TkTimer.new(:idle, -1, proc{\n                        #STDOUT.print(\"idle call\\n\")\n                        unless s.empty?\n                          print(s)\n                          s = ''\n                        end\n                      }).start\n  (0..10).each{|i|\n    STDOUT.print(\"#{i}\\n\")\n    (0..1000).each{ s << '*' }\n  }\n#  timer.stop\n  until s.empty?\n    sleep 0.1\n  end\n  timer.stop\n\n=begin\n  tio.sync = false\n  print(\"\\n\")\n  #(0..10000).each{ putc('*') }\n  (0..10).each{|i|\n    STDOUT.print(\"#{i}\\n\")\n    (0..1000).each{ putc('*') }\n  }\n\n  (0..10).each{|i|\n    STDOUT.print(\"#{i}\\n\")\n    s = ''\n    (0..1000).each{ s << '*' }\n    print(s)\n  }\n=end\n\n  num = 0\n#  io = TkTextIO.new(:mode=>:console, :prompt=>'').pack\n#=begin\n  io = TkTextIO.new(:mode=>:console, \n                    :prompt_cmd=>proc{\n                      s = \"[#{num}]\"\n                      num += 1\n                      s\n                    }, \n                    :prompt=>'-> ').pack\n#=end\n  Thread.new{loop{sleep 2; io.puts 'hoge'}}\n  Thread.new{loop{p io.gets}}\n\n  ev_loop.join\nend\n"
  },
  {
    "path": "ext/tk/sample/tktimer.rb",
    "content": "#!/usr/bin/env ruby\n# This script generates a counter with start and stop buttons.\n\nrequire \"tk\"\n$label = TkLabel.new {\n  text '0.00'\n  relief 'raised'\n  width 10\n  pack('side'=>'bottom', 'fill'=>'both')\n}\n\nTkButton.new {\n  text 'Start'\n  command proc {\n    if $stopped\n      $stopped = FALSE\n      tick\n    end\n  }\n  pack('side'=>'left','fill'=>'both','expand'=>'yes')\n}\nTkButton.new {\n  text 'Stop'\n  command proc{\n    exit if $stopped\n    $stopped = TRUE\n  }\n  pack('side'=>'right','fill'=>'both','expand'=>'yes')\n}\n\n$seconds=0\n$hundredths=0\n$stopped=TRUE\n\ndef tick\n  if $stopped then return end\n  Tk.after 50, proc{tick}\n  $hundredths+=5\n  if $hundredths >= 100\n    $hundredths=0\n    $seconds+=1\n  end\n  $label.text format(\"%d.%02d\", $seconds, $hundredths)\nend\n\nroot = Tk.root\nroot.bind \"Control-c\", proc{root.destroy}\nroot.bind \"Control-q\", proc{root.destroy}\nTk.root.focus\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tktimer2.rb",
    "content": "#!/usr/bin/env ruby\n# This script is a re-implementation of tktimer.rb with TkTimer(TkAfter) class.\n\nrequire \"tk\"\n\n# new notation :\n#   * symbols are acceptable as keys or values of the option hash\n#   * the parent widget can be given by :parent key on the option hash \nroot = TkRoot.new(:title=>'timer sample')\nlabel = TkLabel.new(:parent=>root, :relief=>:raised, :width=>10) \\\n               .pack(:side=>:bottom, :fill=>:both)\n\n# define the procedure repeated by the TkTimer object\ntick = proc{|aobj| #<== TkTimer object\n  cnt = aobj.return_value + 5 # return_value keeps a result of the last proc\n  label.text format(\"%d.%02d\", *(cnt.divmod(100)))\n  cnt #==> return value is kept by TkTimer object\n      #    (so, can be send to the next repeat-proc)\n}\n\ntimer = TkTimer.new(50, -1, tick).start(0, proc{ label.text('0.00'); 0 })\n        # ==> repeat-interval : (about) 50 ms,  \n        #     repeat : infinite (-1) times, \n        #     repeat-procedure : tick (only one, in this case)\n        #\n        # ==> wait-before-call-init-proc : 0 ms, \n        #     init_proc : proc{ label.text('0.00'); 0 }\n        #\n        # (0ms)-> init_proc ->(50ms)-> tick ->(50ms)-> tick ->....\n\nTkButton.new(:text=>'Start') {\n  command proc{ timer.continue unless timer.running? }\n  pack(:side=>:left, :fill=>:both, :expand=>true)\n}\nTkButton.new(:text=>'Restart') {\n  command proc{ timer.restart(0, proc{ label.text('0.00'); 0 }) }\n  pack(:side=>:left, :fill=>:both, :expand=>true)\n}\nTkButton.new(:text=>'Stop') {\n  command proc{ timer.stop if timer.running? }\n  pack('side'=>'right','fill'=>'both','expand'=>'yes')\n}\n\nev_quit = TkVirtualEvent.new('Control-c', 'Control-q')\nTk.root.bind(ev_quit, proc{Tk.exit}).focus\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tktimer3.rb",
    "content": "#!/usr/bin/env ruby\n# This script is a re-implementation of tktimer.rb with TkTimer(TkAfter) class.\n\nrequire \"tk\"\n\n# new notation :\n#   * symbols are acceptable as keys or values of the option hash\n#   * the parent widget can be given by :parent key on the option hash \nroot = TkRoot.new(:title=>'timer sample')\nlabel = TkLabel.new(:parent=>root, :relief=>:raised, :width=>10) \\\n               .pack(:side=>:bottom, :fill=>:both)\n\n# define the procedure repeated by the TkTimer object\ntick = proc{|aobj| #<== TkTimer object\n  cnt = aobj.return_value + 5 # return_value keeps a result of the last proc\n  label.text format(\"%d.%02d\", *(cnt.divmod(100)))\n  cnt #==> return value is kept by TkTimer object\n      #    (so, can be send to the next repeat-proc)\n}\n\ntimer = TkTimer.new(50, -1, tick).start(0, proc{ label.text('0.00'); 0 })\n        # ==> repeat-interval : (about) 50 ms,  \n        #     repeat : infinite (-1) times, \n        #     repeat-procedure : tick (only one, in this case)\n        #\n        # ==> wait-before-call-init-proc : 0 ms, \n        #     init_proc : proc{ label.text('0.00'); 0 }\n        #\n        # (0ms)-> init_proc ->(50ms)-> tick ->(50ms)-> tick ->....\n\nb_start = TkButton.new(:text=>'Start', :state=>:disabled) {\n  pack(:side=>:left, :fill=>:both, :expand=>true)\n}\n\nb_stop  = TkButton.new(:text=>'Stop', :state=>:normal) {\n  pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')\n}\n\nb_start.command {\n  timer.continue\n  b_stop.state(:normal)\n  b_start.state(:disabled)\n}\n\nb_stop.command {\n  timer.stop\n  b_start.state(:normal)\n  b_stop.state(:disabled)\n}\n\nTkButton.new(:text=>'Reset', :state=>:normal) {\n  command { timer.reset }\n  pack(:side=>:right, :fill=>:both, :expand=>:yes)\n}\n\nev_quit = TkVirtualEvent.new('Control-c', 'Control-q')\nTk.root.bind(ev_quit, proc{Tk.exit}).focus\n\nTk.mainloop\n"
  },
  {
    "path": "ext/tk/sample/tktree.rb",
    "content": "##########################################################################\n# TkTree widget class\n#\n#    see <http://wiki.tcl.tk/10615>\n#\n#  Note:  optional argument '-font' of the Tcl library is changed to \n#         'itemfont' on this Ruby library, because of avoiding font \n#         operation trouble in 'initialize' method  ( see the following \n#         test script ). \n#\n##########################################################################\nrequire 'tk'\n\nclass TkTree < TkCanvas\n  TCL_SCRIPT_PATH = File.join(File.dirname(__FILE__), 'tktree.tcl')\n\n  def create_self(keys)\n    args = [@path]\n    if keys.kind_of?(Hash)\n      font = keys.delete('itemfont')\n#      font = hash_kv(font) if font.kind_of?(Hash)\n      keys['font'] = font if font\n#      args.concat(hash_kv(keys))\n      args << keys\n    end\n    begin\n      tk_call('::tktree::treecreate', *args)\n    rescue NameError, RuntimeError\n      Tk.load_tclscript(TkTree::TCL_SCRIPT_PATH)\n      tk_call('::tktree::treecreate', *args)\n    end\n  end\n\n  def newitem(itempath, keys = nil)\n    if keys.kind_of?(Hash)\n      keys = _symbolkey2str(keys)\n      font = keys.delete('itemfont')\n#      font = hash_kv(font) if font.kind_of?(Hash)\n      keys['font'] = font if font\n#      tk_call('::tktree::newitem', @path, itempath, *hash_kv(keys))\n      tk_call('::tktree::newitem', @path, itempath, keys)\n    else\n      tk_call('::tktree::newitem', @path, itempath)\n    end\n  end\n\n  def delitem(itempath)\n    tk_call('::tktree::delitem', @path, itempath)\n  end\n\n  def labelat(xpos, ypos)\n    tk_call('::tktree::delitem', @path, xpos, ypos)\n  end\n\n  def getselection\n    tk_call('::tktree::getselection', @path)\n  end\n\n  def setselection(itempath)\n    tk_call('::tktree::getselection', @path, itempath)\n  end\nend\n\n\n##########################################################################\n# test script\n##########################################################################\nif __FILE__ == $0\n  TkLabel.new(:text=><<EOL, :relief=>:ridge, :justify=>:left).pack\n\n This is a sample to use a Tcl library script on Ruby/Tk. \n This sample loads tktree.tcl (see <http://wiki.tcl.tk/10615>) \n and calls functions of the Tcl script. \nEOL\n\n  items = %w(/group1/item1 /group1/item2 /group1/subgroup/item1 /group2/item1 /item1)\n\n  tr1 = TkTree.new.pack(:expand=>true, :fill=>:both)\n  tr1.focus\n\n  items.each{|item|\n    tr1.newitem(item, \n                :command=>proc{Tk.messageBox(:message=>\"#{item} executed\")})\n  }\n\n  f = TkFrame.new.pack(:expand=>true, :fill=>:both)\n  tr2 = TkTree.new(f, :bg=>'black', #:itemfont=>{:family=>'Times', :size=>14}, \n                   :textcolor=>'red', :bd=>4, :relief=>:ridge, \n                   :selectbackground=>'darkBlue', :selectforeground=>'yellow', \n                   :selectborderwidth=>3, :linecolor=>'yellow') {\n    yscrollbar(TkScrollbar.new(f, :width=>10).pack(:side=>:right, :fill=>:y))\n    xscrollbar(TkScrollbar.new(f, :width=>10).pack(:side=>:bottom, :fill=>:x))\n    pack(:expand=>true, :fill=>:both)\n  }\n\n  items.each{|item|\n    tr2.newitem(item, :textcolor=>'green', :image=>'', \n                :itemfont=>{:family=>'Times', :size=>10}, \n                :command=>proc{Tk.messageBox(:message=>\"#{item} executed\")})\n  }\n\n  Tk.mainloop\nend\n"
  },
  {
    "path": "ext/tk/sample/tktree.tcl",
    "content": "#\n#  This Tcl/Tk script is quoted from <http://wiki.tcl.tk/10615>.\n#\n package require Tk\n  namespace eval ::tktree {\n\n    # Images used for open and close state of subgroups\n    set ::tktree::imgcollapse [image create photo .tktreeopenbm -data {\n      R0lGODdhCQAJAIAAAAEBAf///ywAAAAACQAJAAACEISPoRvG614D80x5ZXyogwIAOw==}]\n    set ::tktree::imgexpand [image create photo .tktreeclosebm -data {\n      R0lGODdhCQAJAIAAAAEBAf///ywAAAAACQAJAAACEYSPoRu28KCSDSJLc44s3lMAADs=}]\n    ###Default images for groups and children\n    set ::tktree::imgsubgroups [image create photo .tktreeimgfolder -data {\n                R0lGODlhEAANAKIAANnZ2Xh4eLi4uPj4APj4+AAAAP///////yH5BAEAAAAA\n                LAAAAAAQAA0AAANkCIChiqDLITgyEgi6GoIjIyMYugCBpMsaWBA0giMjIzgy\n                UYBBMjIoIyODEgVBODIygiMjE1gQJIMyMjIoI1GAQSMjODIyghMFQSgjI4My\n                MhJYEDSCIyMjODJRgKHLXAiApcsMmAA7}]\n    set ::tktree::imgchildren [image create photo .tktreeimgfile -data {\n                R0lGODlhDQAQAKIAANnZ2Xh4ePj4+Li4uAAAAP///////////yH5BAEAAAAA\n                LAAAAAANABAAAANSGLoLgACBoqsRCBAoujqCASGDojtESCEihCREIjgUKLo8\n                hCGCpCsySIGiy0MYIki6IoMUKLo8hCGCpCsySIGiy0MYKLo8hIGiy0MYOLo8\n                SLrMCQA7}]\n\n    #### Swtich all subgroups of a layer to open or close\n    proc ::tktree::switchlayer {win opn {layer /}} {\n      variable cfg\n      foreach child $cfg($win,$layer:subgroups) {\n        set cfg($win,$child:open) $opn\n        switchlayer $win $opn $child\n      }\n      buildwhenidle $win\n    }\n\n    ####  will open or close the item given\n    proc ::tktree::switchstate {win item} {\n      set ::tktree::cfg($win,$item:open) [expr ! $::tktree::cfg($win,$item:open)]\n      buildwhenidle $win\n    }\n\n    #### Select the next item up or down\n    proc ::tktree::updown {win down} {\n      variable cfg\n      set index [lsearch -exact $cfg($win,sortlist) $cfg($win,selection)]\n      if {$down} {incr index} {incr index -1}\n      if {$index < 0} {set index end} elseif {$index >= [llength $cfg($win,sortlist)]} {set index 0}\n      setselection $win [lindex $cfg($win,sortlist) $index]\n    }\n\n    #### left-right button binding commands\n    proc ::tktree::leftright {win right} {\n      variable cfg\n      set item $cfg($win,selection)\n      set index [lsearch -exact $cfg($win,sortlist) $item]\n      set parentindex [lsearch -exact $cfg($win,sortlist) [file dirname $item]]\n      if {$parentindex == -1} {set parentindex [expr $index - 1]}\n      if {$cfg($win,$item:group)} {\n        if {$right} {\n          if {$cfg($win,$item:open)} {incr index} {set cfg($win,$item:open) 1}\n        } else {\n          if {$cfg($win,$item:open)} {set cfg($win,$item:open) 0} {set index $parentindex}\n        }\n      } else {\n        if {$right} {incr index} {set index $parentindex}\n      }\n      if {$index < 0} {set index end} elseif {$index >= [llength $cfg($win,sortlist)]} {set index 0}\n      setselection $win [lindex $cfg($win,sortlist) $index]\n      buildwhenidle $win\n    }\n\n    #### will return the pathname of the item at x and y cooridinates\n    proc ::tktree::labelat {win x y} {\n      set x [$win canvasx $x]; set y [$win canvasy $y]\n      foreach m [$win find overlapping $x $y $x $y] {\n        if {[info exists ::tktree::cfg($win,tag:$m)]} {return $::tktree::cfg($win,tag:$m)}\n      }\n      return \"\"\n    }\n\n    #### will return the path of the current selection in the given tree widget\n    proc ::tktree::getselection {win} {\n      return $::tktree::cfg($win,selection)\n    }\n\n    #### adjust the scrollview to show the selected item as needed\n    proc ::tktree::scrolladjust {win tag} {\n      update\n      set item [$win bbox $tag]\n      set region [$win cget -scrollregion]\n      foreach {axis idx1 idx2} {yview 1 3 xview 0 2} {\n        set range [expr abs([lindex $region $idx2]) - abs([lindex $region $idx1])]\n        set itemtop [lindex $item $idx1];  set itembot [lindex $item $idx2]\n        set viewtop [expr $range * [lindex [$win $axis] 0]]\n        set viewbot [expr $range * [lindex [$win $axis] 1]]\n        if {$itembot > $viewbot} {$win $axis moveto [expr ($itembot. - $viewbot + $viewtop) / $range]}\n        if {$itemtop < $viewtop} {$win $axis moveto [expr $itemtop. / $range]}\n      }\n    }\n\n    #### will set the current selection to the given item on the given tree\n    proc ::tktree::setselection {win item} {\n      variable cfg\n      if {![llength $cfg($win,sortlist)]} {return}\n      if {$item eq \"\"} {set item [lindex $cfg($win,sortlist) 0]}\n      if {![info exists cfg($win,$item:tag)]} {set item [lindex $cfg($win,sortlist) 0]}\n      if {[$win gettags $cfg($win,$item:tag)] ne \"\"} {\n        $win select from $cfg($win,$item:tag) 0\n        $win select to $cfg($win,$item:tag) end\n        set cfg($win,selection) $item\n        scrolladjust $win $cfg($win,$item:tag)\n      } {\n        setselection $win \"/[lindex $cfg($win,/:sortlist) 0]\"\n      }\n    }\n\n    #### will delete the item given from the tree given\n    proc ::tktree::delitem {win item} {\n      variable cfg\n      if {$item eq \"/\"} {\n        array unset cfg $win,* ; catch {destroy $win}\n      } {\n        set group [file dirname $item]\n        if {$cfg($win,$item:group)} {set type subgroups} {set type children}\n        set index [lsearch -exact $cfg($win,$group:$type) $item]\n        set cfg($win,$group:$type) [lreplace $cfg($win,$group:$type) $index $index]\n        array unset cfg $win,$item*\n        buildwhenidle $win\n      }\n    }\n\n    #### create a new item in the tree and rebuild the widget\n    proc ::tktree::newitem {win item args} {\n      variable cfg\n      if {[string index $item 0] ne \"/\"} {set item /$item}\n      if {[string index $item end] eq \"/\"} {\n        set subgroup 1\n        set type subgroups\n        set item [string range $item 0 end-1]\n        set cfg($win,$item:command) [list ::tktree::switchstate $win $item]\n      } {\n        set subgroup 0\n        set type children\n        set cfg($win,$item:command) {}\n      }\n      #Build parent group if needed\n      set group [file dirname $item]\n      if {![info exists cfg($win,$group:open)]} {newitem $win \"$group\\/\"}\n      lappend cfg($win,$group:$type) $item\n      #Configure the new item\n      set cfg($win,$item:group) $subgroup\n      set cfg($win,$item:subgroups) {}\n      set cfg($win,$item:children) {}\n      set cfg($win,$item:sortlist) {}\n      set cfg($win,$item:tags) {}\n      set cfg($win,$item:open) 0\n      set cfg($win,$item:image) {}\n      set cfg($win,$item:textcolor) $cfg($win,textcolor)\n      set cfg($win,$item:font) $cfg($win,font)\n      if {$cfg($win,images)} {set cfg($win,$item:image) [eval list \\$::tktree::img$type]}\n      foreach {confitem confval} $args {\n        switch -exact -- $confitem {\n          -textcolor  {set cfg($win,$item:textcolor) $confval}\n          -command    {set cfg($win,$item:command)   $confval}\n          -image      {set cfg($win,$item:image)     $confval}\n          -font       {set cfg($win,$item:font)      $confval}\n        }\n      }\n      buildwhenidle $win\n    }\n\n    #### Draw the given layer of the tree on the canvas starting at xposition\n    proc ::tktree::buildlayer {win layer xpos} {\n      variable cfg\n      #Record y positions for vertical line later on\n      set ystart $cfg($win,y); set yend $cfg($win,y)\n      if {$layer eq \"/\"} {set cfg($win,sortlist) \"\"}\n      foreach child $cfg($win,$layer:sortlist) {\n        lappend cfg($win,sortlist) $child\n        #Check spacing required for images\n        set imgwidth 0; set imgheight 0\n        if {[string length $cfg($win,$child:image)]} {\n          set imgwidth [expr  ([image width $cfg($win,$child:image)] + 2) / 2]\n          set imgheight [expr ([image height $cfg($win,$child:image)] + 2) / 2]\n        }\n        #find X-axis points for image, horiz line, and text\n        if {$imgwidth} {\n          set centerX [expr $imgwidth + $xpos + 7]\n          set rightX  [expr $xpos + 7]\n          set textX   [expr ($imgwidth * 2) + $xpos + 10]\n        } {\n          set centerX [expr $xpos + 10]\n          set rightX  [expr $centerX + 4]\n          set textX   [expr $rightX + 1]\n        }\n        #Find the proper amount to increment the y axis\n        set fontheight [lindex [font metrics $cfg($win,$child:font)] 5]\n        set yincr [expr ($fontheight + 1) / 2]\n        if {$imgheight > $yincr} {set yincr $imgheight}\n        incr cfg($win,y) $yincr\n        #Draw the horizonal line\n        $win create line $xpos $cfg($win,y) $rightX $cfg($win,y) -fill $cfg($win,linecolor)\n        set yend $cfg($win,y)\n        #Draw the image, if it exists\n        if {$imgwidth} {\n          set it [$win create image $centerX $cfg($win,y) -image $cfg($win,$child:image)]\n          $win bind $it <1> [list ::tktree::setselection $win $child]\n        }\n        #Draw text and store tags for reference\n        set cfg($win,$child:tag) [$win create text $textX $cfg($win,y) \\\n            -text [file tail $child] -font $cfg($win,$child:font) -anchor w -tags x -fill $cfg($win,$child:textcolor)]\n        set cfg($win,tag:$cfg($win,$child:tag)) $child\n        #Command binding\n        $win bind $cfg($win,$child:tag) <1> [list ::tktree::setselection $win $child]\n        $win bind $cfg($win,$child:tag) <Double-1> $cfg($win,$child:command)\n        #next step up on the y axis\n        incr cfg($win,y) $yincr\n        #If its a group, add open-close functionality\n        if {$cfg($win,$child:group)} {\n          if {$cfg($win,$child:open)} {set img collapse} {set img expand}\n          set ocimg [$win create image $xpos [expr $cfg($win,y) - $yincr] -image [eval list \\$::tktree::img$img]]\n          $win bind $ocimg <1> [list ::tktree::switchstate $win $child]\n          if {$cfg($win,$child:open)} {buildlayer $win $child $centerX}\n        }\n      }\n      #Vertical line\n      $win lower [$win create line $xpos [expr $ystart - 7] $xpos $yend -fill $cfg($win,linecolor)]\n    }\n\n    #### sort the layer by subgroups then children\n    proc ::tktree::sortlayer {win {layer /}} {\n      variable cfg\n      set cfg($win,$layer:subgroups) [lsort -dictionary $cfg($win,$layer:subgroups)]\n      set cfg($win,$layer:children) [lsort -dictionary $cfg($win,$layer:children)]\n      set cfg($win,$layer:sortlist) [join [list $cfg($win,$layer:subgroups) $cfg($win,$layer:children)]]\n      foreach group $cfg($win,$layer:subgroups) {sortlayer $win $group}\n    }\n\n    #### build the tree at the given path\n    proc ::tktree::buildtree {win} {\n      variable cfg\n      $win delete all\n      sortlayer $win\n      set xpos 5\n      set cfg($win,y) 5\n      #Draw global expand/contract button, if needed\n      if {[string length $cfg($win,/:subgroups)] && $cfg($win,expandall)} {\n        set exp 0\n        foreach subgroup $cfg($win,/:subgroups) {incr exp $cfg($win,$subgroup:open)}\n        if {$exp} {set type collapse} {set type expand}\n        set ocimg [$win create image 1 1 -image [eval list \\$::tktree::img$type] -anchor w]\n        $win bind $ocimg <1> [list ::tktree::switchlayer $win [expr ! $exp]]\n      }\n      #Build the layers and set initial selection\n      buildlayer $win / $xpos\n      $win config -scrollregion [$win bbox all]\n      setselection $win $cfg($win,selection)\n    }\n\n    #### internal use - set up a handle to build the tree when everything is idle\n    proc ::tktree::buildwhenidle {win} {\n      catch {after cancel $::tktree::cfg($win,buildHandle)}\n      set ::tktree::cfg($win,buildHandle) [after idle [list ::tktree::buildtree $win]]\n    }\n\n    #### will create a new tree widget at the given path\n    proc ::tktree::treecreate {win args} {\n      variable cfg\n      #Default configuration for new tree\n      set cfg($win,selection) {}\n      set cfg($win,selidx) {}\n      set cfg($win,/:subgroups) {}\n      set cfg($win,/:children) {}\n      set cfg($win,/:open) 1\n      set cfg($win,images) 1\n      set cfg($win,expandall) 1\n      set cfg($win,linecolor)  black\n      set cfg($win,textcolor)  black\n      set cfg($win,font) {-family Helvetica -size 10}\n      #Parse and setup custom configuration options\n      set canvascfg \"\"\n      foreach {item val} $args {\n        switch -- $item {\n          -linecolor            {set cfg($win,linecolor) $val}\n          -textcolor            {set cfg($win,textcolor) $val}\n          -font                 {set cfg($win,font) $val}\n          -images               {set cfg($win,images) $val}\n          -expandall            {set cfg($win,expandall) $val}\n          default               {lappend canvascfg $item $val}\n        }\n      }\n      #Build the canvas\n      eval {canvas $win -takefocus 1} $canvascfg\n      bind $win <Destroy> [list ::tktree::delitem $win /]\n      bind $win <1>  [list focus $win]\n      bind $win <Return> {eval $::tktree::cfg(%W,[::tktree::getselection %W]:command)}\n      bind $win <space> {eval $::tktree::cfg(%W,[::tktree::getselection %W]:command)}\n      bind $win <Up>    [list ::tktree::updown $win 0]\n      bind $win <Down>    [list ::tktree::updown $win 1]\n      bind $win <Left>    [list ::tktree::leftright $win 0]\n      bind $win <Right>    [list ::tktree::leftright $win 1]\n\n      #Build the tree when idle\n      buildwhenidle $win\n    }\n }\n\n"
  },
  {
    "path": "ext/tk/sample/ttk_wrapper.rb",
    "content": "#!/usr/bin/env ruby\n#\n#  ttk_wrapper.rb  --  use Ttk widgets as default on old Ruby/Tk scripts\n#\n#                       by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)\n#\nversion = '0.1.3'\n#\n##########################################################################\n#  parse commandline arguments\n##########################################################################\nrequire 'optparse'\nopt = OptionParser.new(\"Usage: #{$0} [options] rubytk_script\" << \"\\n    \" << \n                         \"Ruby/Tk script wrapper. Use Ttk widgets as default.\")\nopt.version = version\n\nOPTS = {}\nOPTS[:themedir] = []\nOPTS[:rb_theme] = []\nOPTS[:theme] = 'default'\n\nopt.on('-l', '--list', 'list available theme names'){|v| OPTS[:list] = true}\nopt.on('-t', '--theme theme', 'theme name'){|v| OPTS[:theme] = v}\nopt.on('-d', '--themedir themes_dir', 'directory of theme definitions'){|v| \n  OPTS[:themedir] << v\n}\nopt.on('-r', '--rubytheme rb_theme', 'theme definition file (ruby script)'){|v|\n  OPTS[:rb_theme] << v\n}\nopt.on('-v', '--verbose', 'print verbose messages'){|v| OPTS[:verbose] = true}\n\nopt.parse!(ARGV)\n\n\n##########################################################################\n#  load Ttk (Tile) extension\n##########################################################################\nrequire 'tk'\n\nbegin\n  require 'tkextlib/tile'\n  Tk.default_widget_set = :Ttk\nrescue LoadError\n  if OPTS[:verbose]\n    print \"warning: fail to load 'Ttk' extension. use standard widgets.\\n\" \n  end\nend\n\nif OPTS[:verbose]\n  print \"current default widget set is '#{Tk.default_widget_set}'\\n\"\nend\n\n\n##########################################################################\n# define Tcl/Tk procedures for compatibility.\n# those are required when want to use themes included \n# in \"sample/tkextlib/tile/demo.rb\".\n##########################################################################\nTk::Tile.__define_LoadImages_proc_for_compatibility__!\nTk::Tile::Style.__define_wrapper_proc_for_compatibility__!\n\n\n##########################################################################\n#  use themes defined on the demo of Ttk (Tile) extension\n##########################################################################\ndemodir = File.dirname(__FILE__)\ndemo_themesdir = File.expand_path(File.join(demodir, 'tkextlib', 'tile', 'themes'))\n\nTk::AUTO_PATH.lappend(*OPTS[:themedir]) unless OPTS[:themedir].empty?\nTk::AUTO_PATH.lappend('.', demodir, demo_themesdir)\n\nOPTS[:themedir] << demo_themesdir\nprint \"theme-dirs: #{OPTS[:themedir].inspect}\\n\" if OPTS[:verbose]\n\nOPTS[:themedir].each{|themesdir|\n  if File.directory?(themesdir)\n    Dir.foreach(themesdir){|name|\n      next if name == '.' || name == '..'\n      path = File.join(themesdir, name)\n      Tk::AUTO_PATH.lappend(path) if File.directory?(path)\n    }\n  end\n}\n\n# This forces an update of the available packages list. It's required\n# for package names to find the themes in demos/themes/*.tcl\nTk.ip_eval(\"#{TkPackage.unknown_proc}  Tcl #{TkPackage.provide('Tcl')}\")\n\n# load themes written in Ruby.\nthemes_by_ruby = [File.join(demo_themesdir, 'kroc.rb')]\nthemes_by_ruby.concat OPTS[:rb_theme]\nprint \"ruby-themes: #{themes_by_ruby.inspect}\\n\" if OPTS[:verbose]\n\nthemes_by_ruby.each{|f|\n  begin\n    load(f, true)\n  rescue LoadError\n    print \"fail to load \\\"#{f}\\\"\\n\" if OPTS[:verbose]\n  end\n}\n\n\n##########################################################################\n# ignore unsupported options of Ttk widgets\n##########################################################################\nTkConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true\nTkItemConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true\n\n\n##########################################################################\n#  set theme of widget style\n##########################################################################\nif OPTS[:list] || OPTS[:verbose]\n  print \"supported theme names: #{Tk::Tile.themes.inspect}\\n\" \n  exit if OPTS[:list] && ARGV.empty?\nend\nprint \"use theme: \\\"#{OPTS[:theme]}\\\"\\n\" if OPTS[:theme] && OPTS[:verbose]\n#setTheme(OPTS[:theme]) if OPTS[:theme]\nTk::Tile.set_theme(OPTS[:theme]) if OPTS[:theme]\n\n\n##########################################################################\n#  replace $0 and $RPAGRAM_NAME\n##########################################################################\n#  When the expand_path of the target script is long, ruby sometimes \n#  fails to set the path to $0 (the path string is trimmed).\n#  The following replaces $0 and $PROGNAME to avoid such trouble.\nprogname_obj = $0.dup\n$program_name = progname_obj\n\nalias $REAL_PROGRAM_NAME $0\nalias $PROGRAM_NAME $program_name\nalias $0 $program_name\n\ntrace_var(:$program_name){|val|\n  unless progname_obj.object_id == val.object_id\n    progname_obj.replace(val.to_s)\n    $program_name = progname_obj\n  end\n}\n\n\n##########################################################################\n#  load script\n##########################################################################\nif (path = ARGV.shift) && (script = File.expand_path(path))\n  print \"load script \\\"#{script}\\\"\\n\" if OPTS[:verbose]\n  $0 = script\n  load(script)\nelse\n  print \"Error: no script is given.\\n\"\n  print opt.help\n  exit(1)\nend\n"
  },
  {
    "path": "ext/tk/stubs.c",
    "content": "/************************************************\n\n  stubs.c - Tcl/Tk stubs support\n\n************************************************/\n\n#include \"ruby.h\"\n#include \"stubs.h\"\n#include <tcl.h>\n#include <tk.h>\n\n/*------------------------------*/\n\n#ifdef __MACOS__\n# include <tkMac.h>\n# include <Quickdraw.h>\n\nstatic int call_macinit = 0;\n\nstatic void\n_macinit()\n{\n    if (!call_macinit) {\n        tcl_macQdPtr = &qd; /* setup QuickDraw globals */\n        Tcl_MacSetEventProc(TkMacConvertEvent); /* setup event handler */\n        call_macinit = 1;\n    }\n}\n#endif\n\n/*------------------------------*/\n\nstatic int nativethread_checked = 0;\n\nstatic void\n_nativethread_consistency_check(ip)\n    Tcl_Interp *ip;\n{\n    if (nativethread_checked || ip == (Tcl_Interp *)NULL) {\n        return;\n    }\n\n    /* If the variable \"tcl_platform(threaded)\" exists,  \n       then the Tcl interpreter was compiled with threads enabled. */\n    if (Tcl_GetVar2(ip, \"tcl_platform\", \"threaded\", TCL_GLOBAL_ONLY) != (char*)NULL) {\n#ifdef HAVE_NATIVETHREAD\n        /* consistent */\n#else\n        rb_warn(\"Inconsistency. Loaded Tcl/Tk libraries are enabled nativethread-support. But `tcltklib' is not. The inconsistency causes SEGV or other troubles frequently.\");\n#endif\n    } else {\n#ifdef HAVE_NATIVETHREAD\n        rb_warning(\"Inconsistency.`tcltklib' is enabled nativethread-support. But loaded Tcl/Tk libraries are not. (Probably, the inconsistency doesn't cause any troubles.)\");\n#else\n        /* consistent */\n#endif\n    }\n\n    Tcl_ResetResult(ip);\n\n    nativethread_checked = 1;\n}\n\n/*------------------------------*/\n\n#if defined USE_TCL_STUBS && defined USE_TK_STUBS\n\n#if defined _WIN32 || defined __CYGWIN__\n# include \"util.h\"\n# include <windows.h>\n  typedef HINSTANCE DL_HANDLE;\n# define DL_OPEN LoadLibrary\n# define DL_SYM GetProcAddress\n# define TCL_INDEX 4\n# define TK_INDEX 3\n# define TCL_NAME \"tcl89%s\"\n# define TK_NAME \"tk89%s\"\n# undef DLEXT\n# define DLEXT \".dll\"\n#elif defined HAVE_DLOPEN\n# include <dlfcn.h>\n  typedef void *DL_HANDLE;\n# define DL_OPEN(file) dlopen(file, RTLD_LAZY|RTLD_GLOBAL)\n# define DL_SYM dlsym\n# define TCL_INDEX 8\n# define TK_INDEX 7\n# define TCL_NAME \"libtcl8.9%s\"\n# define TK_NAME \"libtk8.9%s\"\n#endif\n\nstatic DL_HANDLE tcl_dll = (DL_HANDLE)0;\nstatic DL_HANDLE tk_dll  = (DL_HANDLE)0;\n\nint\n#ifdef RUBY_VM\nruby_open_tcl_dll(char *appname)\n#else\nruby_open_tcl_dll(appname)\n    char *appname;\n#endif\n{\n    void (*p_Tcl_FindExecutable)(const char *);\n    int n;\n    char *ruby_tcl_dll = 0;\n    char tcl_name[20];\n\n    if (tcl_dll) return TCLTK_STUBS_OK;\n\n    ruby_tcl_dll = getenv(\"RUBY_TCL_DLL\");\n#if defined _WIN32\n    if (ruby_tcl_dll) ruby_tcl_dll = ruby_strdup(ruby_tcl_dll);\n#endif\n    if (ruby_tcl_dll) {\n        tcl_dll = (DL_HANDLE)DL_OPEN(ruby_tcl_dll);\n    } else {\n        snprintf(tcl_name, sizeof tcl_name, TCL_NAME, DLEXT);\n        /* examine from 8.9 to 8.1 */\n        for (n = '9'; n > '0'; n--) {\n            tcl_name[TCL_INDEX] = n;\n            tcl_dll = (DL_HANDLE)DL_OPEN(tcl_name);\n            if (tcl_dll)\n                break;\n        }\n    }\n\n#if defined _WIN32\n    if (ruby_tcl_dll) ruby_xfree(ruby_tcl_dll);\n#endif\n\n    if (!tcl_dll)\n        return NO_TCL_DLL;\n\n    p_Tcl_FindExecutable = (void (*)(const char *))DL_SYM(tcl_dll, \"Tcl_FindExecutable\");\n    if (!p_Tcl_FindExecutable)\n        return NO_FindExecutable;\n\n    if (appname) {\n        p_Tcl_FindExecutable(appname);\n    } else {\n        p_Tcl_FindExecutable(\"ruby\");\n    }\n\n    return TCLTK_STUBS_OK;\n}\n\nint\nruby_open_tk_dll()\n{\n    int n;\n    char *ruby_tk_dll = 0;\n    char tk_name[20];\n\n    if (!tcl_dll) {\n        /* int ret = ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */\n        int ret = ruby_open_tcl_dll(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n        if (ret != TCLTK_STUBS_OK) return ret;\n    }\n\n    if (tk_dll) return TCLTK_STUBS_OK;\n\n    ruby_tk_dll = getenv(\"RUBY_TK_DLL\");\n    if (ruby_tk_dll) {\n        tk_dll = (DL_HANDLE)DL_OPEN(ruby_tk_dll);\n    } else {\n        snprintf(tk_name, sizeof tk_name, TK_NAME, DLEXT);\n        /* examine from 8.9 to 8.1 */\n        for (n = '9'; n > '0'; n--) {\n            tk_name[TK_INDEX] = n;\n            tk_dll = (DL_HANDLE)DL_OPEN(tk_name);\n            if (tk_dll)\n                break;\n        }\n    }\n\n    if (!tk_dll)\n        return NO_TK_DLL;\n\n    return TCLTK_STUBS_OK;\n}\n\nint\n#ifdef RUBY_VM\nruby_open_tcltk_dll(char *appname)\n#else\nruby_open_tcltk_dll(appname)\n    char *appname;\n#endif\n{\n    return( ruby_open_tcl_dll(appname) || ruby_open_tk_dll() );\n}\n\nint \ntcl_stubs_init_p()\n{\n    return(tclStubsPtr != (TclStubs*)NULL);\n}\n\nint \ntk_stubs_init_p()\n{\n    return(tkStubsPtr != (TkStubs*)NULL);\n}\n\n\nTcl_Interp *\n#ifdef RUBY_VM\nruby_tcl_create_ip_and_stubs_init(int *st)\n#else\nruby_tcl_create_ip_and_stubs_init(st)\n    int *st;\n#endif\n{\n    Tcl_Interp *tcl_ip;\n\n    if (st) *st = 0;\n\n    if (tcl_stubs_init_p()) {\n        tcl_ip = Tcl_CreateInterp();\n\n        if (!tcl_ip) {\n            if (st) *st = FAIL_CreateInterp;\n            return (Tcl_Interp*)NULL;\n        }\n\n        _nativethread_consistency_check(tcl_ip);\n\n        return tcl_ip;\n\n    } else {\n        Tcl_Interp *(*p_Tcl_CreateInterp)();\n        Tcl_Interp *(*p_Tcl_DeleteInterp)();\n\n        if (!tcl_dll) {\n            /* int ret = ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */\n            int ret = ruby_open_tcl_dll(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n\n            if (ret != TCLTK_STUBS_OK) {\n                if (st) *st = ret;\n                return (Tcl_Interp*)NULL;\n            }\n        }\n\n        p_Tcl_CreateInterp \n            = (Tcl_Interp *(*)())DL_SYM(tcl_dll, \"Tcl_CreateInterp\");\n        if (!p_Tcl_CreateInterp) {\n            if (st) *st = NO_CreateInterp;\n            return (Tcl_Interp*)NULL;\n        }\n\n        p_Tcl_DeleteInterp \n            = (Tcl_Interp *(*)())DL_SYM(tcl_dll, \"Tcl_DeleteInterp\");\n        if (!p_Tcl_DeleteInterp) {\n            if (st) *st = NO_DeleteInterp;\n            return (Tcl_Interp*)NULL;\n        }\n\n        tcl_ip = (*p_Tcl_CreateInterp)();\n        if (!tcl_ip) {\n            if (st) *st = FAIL_CreateInterp;\n            return (Tcl_Interp*)NULL;\n        }\n\n        if (!Tcl_InitStubs(tcl_ip, \"8.1\", 0)) {\n            if (st) *st = FAIL_Tcl_InitStubs;\n            (*p_Tcl_DeleteInterp)(tcl_ip);\n            return (Tcl_Interp*)NULL;\n        }\n\n        _nativethread_consistency_check(tcl_ip);\n\n        return tcl_ip;\n    }\n}\n\nint\nruby_tcl_stubs_init()\n{\n    int st;\n    Tcl_Interp *tcl_ip;\n\n    if (!tcl_stubs_init_p()) {\n        tcl_ip = ruby_tcl_create_ip_and_stubs_init(&st);\n\n        if (!tcl_ip) return st;\n\n        Tcl_DeleteInterp(tcl_ip);\n    }\n\n    return TCLTK_STUBS_OK;\n}\n\nint\n#ifdef RUBY_VM\nruby_tk_stubs_init(Tcl_Interp *tcl_ip)\n#else\nruby_tk_stubs_init(tcl_ip)\n    Tcl_Interp *tcl_ip;\n#endif\n{\n    Tcl_ResetResult(tcl_ip);\n\n    if (tk_stubs_init_p()) {\n        if (Tk_Init(tcl_ip) == TCL_ERROR) {\n            return FAIL_Tk_Init;\n        }\n    } else {\n        int (*p_Tk_Init)(Tcl_Interp *);\n\n        if (!tk_dll) {\n            int ret = ruby_open_tk_dll();\n            if (ret != TCLTK_STUBS_OK) return ret;\n        }\n\n        p_Tk_Init = (int (*)(Tcl_Interp *))DL_SYM(tk_dll, \"Tk_Init\");\n        if (!p_Tk_Init)\n            return NO_Tk_Init;\n\n        if ((*p_Tk_Init)(tcl_ip) == TCL_ERROR)\n            return FAIL_Tk_Init;\n\n        if (!Tk_InitStubs(tcl_ip, \"8.1\", 0))\n            return FAIL_Tk_InitStubs;\n\n#ifdef __MACOS__\n        _macinit();\n#endif\n    }\n\n    return TCLTK_STUBS_OK;\n}\n\nint\n#ifdef RUBY_VM\nruby_tk_stubs_safeinit(Tcl_Interp *tcl_ip)\n#else\nruby_tk_stubs_safeinit(tcl_ip)\n    Tcl_Interp *tcl_ip;\n#endif\n{\n    Tcl_ResetResult(tcl_ip);\n\n    if (tk_stubs_init_p()) {\n        if (Tk_SafeInit(tcl_ip) == TCL_ERROR)\n            return FAIL_Tk_Init;\n    } else {\n        int (*p_Tk_SafeInit)(Tcl_Interp *);\n\n        if (!tk_dll) {\n            int ret = ruby_open_tk_dll();\n            if (ret != TCLTK_STUBS_OK) return ret;\n        }\n\n        p_Tk_SafeInit = (int (*)(Tcl_Interp *))DL_SYM(tk_dll, \"Tk_SafeInit\");\n        if (!p_Tk_SafeInit)\n            return NO_Tk_Init;\n\n        if ((*p_Tk_SafeInit)(tcl_ip) == TCL_ERROR)\n            return FAIL_Tk_Init;\n\n        if (!Tk_InitStubs(tcl_ip, \"8.1\", 0))\n            return FAIL_Tk_InitStubs;\n\n#ifdef __MACOS__\n        _macinit();\n#endif\n    }\n\n    return TCLTK_STUBS_OK;\n}\n\nint\nruby_tcltk_stubs()\n{\n    int st;\n    Tcl_Interp *tcl_ip;\n\n    /* st = ruby_open_tcltk_dll(RSTRING_PTR(rb_argv0)); */\n    st = ruby_open_tcltk_dll(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n    switch(st) {\n    case NO_FindExecutable:\n        return -7;\n    case NO_TCL_DLL:\n    case NO_TK_DLL:\n        return -1;\n    }\n\n    tcl_ip = ruby_tcl_create_ip_and_stubs_init(&st);\n    if (!tcl_ip) {\n        switch(st) {\n        case NO_CreateInterp:\n        case NO_DeleteInterp:\n            return -2;\n        case FAIL_CreateInterp:\n            return -3;\n        case FAIL_Tcl_InitStubs:\n            return -5;\n        }\n    }\n\n    st = ruby_tk_stubs_init(tcl_ip);\n    switch(st) {\n    case NO_Tk_Init:\n        Tcl_DeleteInterp(tcl_ip);\n        return -4;\n    case FAIL_Tk_Init:\n    case FAIL_Tk_InitStubs:\n        Tcl_DeleteInterp(tcl_ip);\n        return -6;\n    }\n\n    Tcl_DeleteInterp(tcl_ip);\n\n    return 0;\n}\n\n/*###################################################*/\n#else /* ! USE_TCL_STUBS || ! USE_TK_STUBS) */\n/*###################################################*/\n\nstatic int open_tcl_dll = 0;\nstatic int call_tk_stubs_init = 0;\n\nint\n#ifdef RUBY_VM\nruby_open_tcl_dll(char *appname)\n#else\nruby_open_tcl_dll(appname)\n    char *appname;\n#endif\n{\n    if (appname) {\n        Tcl_FindExecutable(appname);\n    } else {\n        Tcl_FindExecutable(\"ruby\");\n    }\n    open_tcl_dll = 1;\n\n    return TCLTK_STUBS_OK;\n}\n\nint \nruby_open_tk_dll()\n{\n    if (!open_tcl_dll) {\n        /* ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */\n        ruby_open_tcl_dll(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n    }\n\n    return TCLTK_STUBS_OK;\n}\n\nint \n#ifdef RUBY_VM\nruby_open_tcltk_dll(char *appname)\n#else\nruby_open_tcltk_dll(appname)\n    char *appname;\n#endif\n{\n    return( ruby_open_tcl_dll(appname) || ruby_open_tk_dll() );\n}\n\nint \ntcl_stubs_init_p()\n{\n    return 1;\n}\n\nint \ntk_stubs_init_p()\n{\n    return call_tk_stubs_init;\n}\n\nTcl_Interp *\n#ifdef RUBY_VM\nruby_tcl_create_ip_and_stubs_init(int *st)\n#else\nruby_tcl_create_ip_and_stubs_init(st)\n    int *st;\n#endif\n{\n    Tcl_Interp *tcl_ip;\n\n    if (!open_tcl_dll) {\n        /* ruby_open_tcl_dll(RSTRING_PTR(rb_argv0)); */\n        ruby_open_tcl_dll(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n    }\n\n    if (st) *st = 0;\n    tcl_ip = Tcl_CreateInterp();\n    if (!tcl_ip) {\n        if (st) *st = FAIL_CreateInterp;\n        return (Tcl_Interp*)NULL;\n    }\n\n    _nativethread_consistency_check(tcl_ip);\n\n    return tcl_ip;\n}\n\nint \nruby_tcl_stubs_init()\n{\n    return TCLTK_STUBS_OK;\n}\n\nint \n#ifdef RUBY_VM\nruby_tk_stubs_init(Tcl_Interp *tcl_ip)\n#else\nruby_tk_stubs_init(tcl_ip)\n    Tcl_Interp *tcl_ip;\n#endif\n{\n    if (Tk_Init(tcl_ip) == TCL_ERROR)\n        return FAIL_Tk_Init;\n\n    if (!call_tk_stubs_init) {\n#ifdef __MACOS__\n        _macinit();\n#endif\n        call_tk_stubs_init = 1;\n    }\n\n    return TCLTK_STUBS_OK;\n}\n\nint\n#ifdef RUBY_VM\nruby_tk_stubs_safeinit(Tcl_Interp *tcl_ip)\n#else\nruby_tk_stubs_safeinit(tcl_ip)\n    Tcl_Interp *tcl_ip;\n#endif\n{\n#if TCL_MAJOR_VERSION >= 8\n    if (Tk_SafeInit(tcl_ip) == TCL_ERROR)\n        return FAIL_Tk_Init;\n\n    if (!call_tk_stubs_init) {\n#ifdef __MACOS__\n        _macinit();\n#endif\n        call_tk_stubs_init = 1;\n    }\n\n    return TCLTK_STUBS_OK;\n\n#else /* TCL_MAJOR_VERSION < 8 */\n\n    return FAIL_Tk_Init;\n#endif\n}\n\nint \nruby_tcltk_stubs()\n{\n    /* Tcl_FindExecutable(RSTRING_PTR(rb_argv0)); */\n    Tcl_FindExecutable(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n    return 0;\n}\n\n#endif\n"
  },
  {
    "path": "ext/tk/stubs.h",
    "content": "#include <tcl.h>\n\nextern int ruby_open_tcl_dll(char *);\nextern int ruby_open_tk_dll();\nextern int ruby_open_tcltk_dll(char *);\nextern int tcl_stubs_init_p();\nextern int tk_stubs_init_p();\nextern Tcl_Interp *ruby_tcl_create_ip_and_stubs_init(int*);\nextern int ruby_tcl_stubs_init();\nextern int ruby_tk_stubs_init(Tcl_Interp*);\nextern int ruby_tk_stubs_safeinit(Tcl_Interp*);\nextern int ruby_tcltk_stubs();\n\n/* no error */\n#define TCLTK_STUBS_OK     (0)\n\n/* return value of ruby_open_tcl_dll() */\n#define NO_TCL_DLL         (1)\n#define NO_FindExecutable  (2)\n\n/* return value of ruby_open_tk_dll() */\n#define NO_TK_DLL         (-1)\n\n/* status value of ruby_tcl_create_ip_and_stubs_init(st) */\n#define NO_CreateInterp    (3)\n#define NO_DeleteInterp    (4)\n#define FAIL_CreateInterp  (5)\n#define FAIL_Tcl_InitStubs (6)\n\n/* return value of ruby_tk_stubs_init() */\n#define NO_Tk_Init         (7)\n#define FAIL_Tk_Init       (8)\n#define FAIL_Tk_InitStubs  (9)\n"
  },
  {
    "path": "ext/tk/tcltklib.c",
    "content": "/*\n *      tcltklib.c\n *              Aug. 27, 1997   Y. Shigehiro\n *              Oct. 24, 1997   Y. Matsumoto\n */\n\n#define TCLTKLIB_RELEASE_DATE \"2008-05-23\"\n\n#include \"ruby.h\"\n\n#ifdef RUBY_VM\n/* #include \"ruby/ruby.h\" */\n#include \"ruby/signal.h\"\n#include \"ruby/encoding.h\"\n#else\n/* #include \"ruby.h\" */\n#include \"rubysig.h\"\n#include \"version.h\"\n#endif\n\n#undef EXTERN   /* avoid conflict with tcl.h of tcl8.2 or before */\n#include <stdio.h>\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n#include <string.h>\n#include <tcl.h>\n#include <tk.h>\n\n#include \"stubs.h\"\n\n#ifndef TCL_ALPHA_RELEASE\n#define TCL_ALPHA_RELEASE       0\n#define TCL_BETA_RELEASE        1\n#define TCL_FINAL_RELEASE       2\n#endif\n\nstatic struct {\n  int major;\n  int minor;\n  int patchlevel;\n  int type;\n} tcltk_version = {0, 0, 0, 0};\n\nstatic void\nset_tcltk_version()\n{\n    if (tcltk_version.major) return;\n\n    Tcl_GetVersion(&(tcltk_version.major), \n\t\t   &(tcltk_version.minor), \n\t\t   &(tcltk_version.patchlevel), \n\t\t   &(tcltk_version.type));\n}\n\n#if TCL_MAJOR_VERSION >= 8\n# ifndef CONST84\n#  if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION <= 4 /* Tcl8.0.x -- 8.4b1 */\n#   define CONST84\n#  else /* unknown (maybe TCL_VERSION >= 8.5) */\n#   ifdef CONST\n#    define CONST84 CONST\n#   else\n#    define CONST84\n#   endif\n#  endif\n# endif\n#else  /* TCL_MAJOR_VERSION < 8 */\n# ifdef CONST\n#  define CONST84 CONST\n# else\n#  define CONST\n#  define CONST84\n# endif\n#endif\n\n/* copied from eval.c */\n#define TAG_RETURN      0x1\n#define TAG_BREAK       0x2\n#define TAG_NEXT        0x3\n#define TAG_RETRY       0x4\n#define TAG_REDO        0x5\n#define TAG_RAISE       0x6\n#define TAG_THROW       0x7\n#define TAG_FATAL       0x8\n\n/* for ruby_debug */\n#define DUMP1(ARG1) if (ruby_debug) { fprintf(stderr, \"tcltklib: %s\\n\", ARG1); fflush(stderr); }\n#define DUMP2(ARG1, ARG2) if (ruby_debug) { fprintf(stderr, \"tcltklib: \");\\\nfprintf(stderr, ARG1, ARG2); fprintf(stderr, \"\\n\"); fflush(stderr); }\n#define DUMP3(ARG1, ARG2, ARG3) if (ruby_debug) { fprintf(stderr, \"tcltklib: \");\\\nfprintf(stderr, ARG1, ARG2, ARG3); fprintf(stderr, \"\\n\"); fflush(stderr); }\n/*\n#define DUMP1(ARG1)\n#define DUMP2(ARG1, ARG2)\n#define DUMP3(ARG1, ARG2, ARG3)\n*/\n\n/* release date */\nconst char tcltklib_release_date[] = TCLTKLIB_RELEASE_DATE;\n\n/* finalize_proc_name */\nstatic char *finalize_hook_name = \"INTERP_FINALIZE_HOOK\";\n\nstatic void ip_finalize _((Tcl_Interp*));\n\nstatic int at_exit = 0;\n\n#ifdef RUBY_VM\nstatic VALUE cRubyEncoding;\n\n/* encoding */\nstatic int ENCODING_INDEX_UTF8;\nstatic int ENCODING_INDEX_BINARY;\n#endif\nstatic VALUE ENCODING_NAME_UTF8;\nstatic VALUE ENCODING_NAME_BINARY;\n\nstatic VALUE create_dummy_encoding_for_tk_core _((VALUE, VALUE, VALUE));\nstatic VALUE create_dummy_encoding_for_tk _((VALUE, VALUE));\nstatic int update_encoding_table _((VALUE, VALUE, VALUE));\nstatic VALUE encoding_table_get_name_core _((VALUE, VALUE, VALUE));\nstatic VALUE encoding_table_get_obj_core _((VALUE, VALUE, VALUE));\nstatic VALUE encoding_table_get_name _((VALUE, VALUE));\nstatic VALUE encoding_table_get_obj _((VALUE, VALUE));\nstatic VALUE create_encoding_table _((VALUE));\nstatic VALUE ip_get_encoding_table _((VALUE));\n\n\n/* for callback break & continue */\nstatic VALUE eTkCallbackReturn;\nstatic VALUE eTkCallbackBreak;\nstatic VALUE eTkCallbackContinue;\n\nstatic VALUE eLocalJumpError;\n\nstatic VALUE eTkLocalJumpError;\nstatic VALUE eTkCallbackRetry;\nstatic VALUE eTkCallbackRedo;\nstatic VALUE eTkCallbackThrow;\n\nstatic VALUE tcltkip_class;\n\nstatic ID ID_at_enc;\nstatic ID ID_at_interp;\n\nstatic ID ID_encoding_name;\nstatic ID ID_encoding_table;\n\nstatic ID ID_stop_p;\nstatic ID ID_alive_p;\nstatic ID ID_kill;\nstatic ID ID_join;\nstatic ID ID_value;\n\nstatic ID ID_call;\nstatic ID ID_backtrace;\nstatic ID ID_message;\n\nstatic ID ID_at_reason;\nstatic ID ID_return;\nstatic ID ID_break;\nstatic ID ID_next;\n\nstatic ID ID_to_s;\nstatic ID ID_inspect;\n\nstatic VALUE ip_invoke_real _((int, VALUE*, VALUE));\nstatic VALUE ip_invoke _((int, VALUE*, VALUE));\nstatic VALUE ip_invoke_with_position _((int, VALUE*, VALUE, Tcl_QueuePosition));\nstatic VALUE tk_funcall _((VALUE(), int, VALUE*, VALUE));\n\n/* Tcl's object type */\n#if TCL_MAJOR_VERSION >= 8\nstatic char *Tcl_ObjTypeName_ByteArray = \"bytearray\";\nstatic Tcl_ObjType *Tcl_ObjType_ByteArray;\n\nstatic char *Tcl_ObjTypeName_String    = \"string\";\nstatic Tcl_ObjType *Tcl_ObjType_String;\n\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)\n#define IS_TCL_BYTEARRAY(obj)    ((obj)->typePtr == Tcl_ObjType_ByteArray)\n#define IS_TCL_STRING(obj)       ((obj)->typePtr == Tcl_ObjType_String)\n#define IS_TCL_VALID_STRING(obj) ((obj)->bytes != (char*)NULL)\n#endif\n#endif\n\n#ifndef HAVE_RB_HASH_LOOKUP\n#define rb_hash_lookup rb_hash_aref\n#endif\n\n/* safe Tcl_Eval and Tcl_GlobalEval */\nstatic int\n#ifdef RUBY_VM\ntcl_eval(Tcl_Interp *interp, const char *cmd)\n#else\ntcl_eval(interp, cmd)\n    Tcl_Interp *interp;\n    const char *cmd; /* don't have to be writable */\n#endif\n{\n    char *buf = strdup(cmd);\n    int ret;\n\n    Tcl_AllowExceptions(interp);\n    ret = Tcl_Eval(interp, buf);\n    free(buf);\n    return ret;\n}\n\n#undef Tcl_Eval\n#define Tcl_Eval tcl_eval\n\nstatic int\n#ifdef RUBY_VM\ntcl_global_eval(Tcl_Interp *interp, const char *cmd)\n#else\ntcl_global_eval(interp, cmd)\n    Tcl_Interp *interp;\n    const char *cmd; /* don't have to be writable */\n#endif\n{\n    char *buf = strdup(cmd);\n    int ret;\n\n    Tcl_AllowExceptions(interp);\n    ret = Tcl_GlobalEval(interp, buf);\n    free(buf);\n    return ret;\n}\n\n#undef Tcl_GlobalEval\n#define Tcl_GlobalEval tcl_global_eval\n\n/* Tcl_{Incr|Decr}RefCount for tcl7.x or earlier */\n#if TCL_MAJOR_VERSION < 8\n#define Tcl_IncrRefCount(obj) (1)\n#define Tcl_DecrRefCount(obj) (1)\n#endif\n\n/* Tcl_GetStringResult for tcl7.x or earlier */\n#if TCL_MAJOR_VERSION < 8\n#define Tcl_GetStringResult(interp) ((interp)->result)\n#endif\n\n/* Tcl_[GS]etVar2Ex for tcl8.0 */\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0\nstatic Tcl_Obj *\nTcl_GetVar2Ex(interp, name1, name2, flags)\n    Tcl_Interp *interp;\n    CONST char *name1;\n    CONST char *name2;\n    int flags;\n{\n    Tcl_Obj *nameObj1, *nameObj2 = NULL, *retObj;\n\n    nameObj1 = Tcl_NewStringObj((char*)name1, -1);\n    Tcl_IncrRefCount(nameObj1);\n\n    if (name2) {\n        nameObj2 = Tcl_NewStringObj((char*)name2, -1);\n        Tcl_IncrRefCount(nameObj2);\n    }\n\n    retObj = Tcl_ObjGetVar2(interp, nameObj1, nameObj2, flags);\n\n    if (name2) {\n        Tcl_DecrRefCount(nameObj2);\n    }\n\n    Tcl_DecrRefCount(nameObj1);\n\n    return retObj;\n}\n\nstatic Tcl_Obj *\nTcl_SetVar2Ex(interp, name1, name2, newValObj, flags)\n    Tcl_Interp *interp;\n    CONST char *name1;\n    CONST char *name2;\n    Tcl_Obj *newValObj;\n    int flags;\n{\n    Tcl_Obj *nameObj1, *nameObj2 = NULL, *retObj;\n\n    nameObj1 = Tcl_NewStringObj((char*)name1, -1);\n    Tcl_IncrRefCount(nameObj1);\n\n    if (name2) {\n        nameObj2 = Tcl_NewStringObj((char*)name2, -1);\n        Tcl_IncrRefCount(nameObj2);\n    }\n\n    retObj = Tcl_ObjSetVar2(interp, nameObj1, nameObj2, newValObj, flags);\n\n    if (name2) {\n        Tcl_DecrRefCount(nameObj2);\n    }\n\n    Tcl_DecrRefCount(nameObj1);\n\n    return retObj;\n}\n#endif\n\n/* from tkAppInit.c */\n\n#if TCL_MAJOR_VERSION < 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 4)\n#  if !defined __MINGW32__ && !defined __BORLANDC__\n/*\n * The following variable is a special hack that is needed in order for\n * Sun shared libraries to be used for Tcl.\n */\n\nextern int matherr();\nint *tclDummyMathPtr = (int *) matherr;\n#  endif\n#endif\n\n/*---- module TclTkLib ----*/\n\nstruct invoke_queue {\n    Tcl_Event ev;\n    int argc;\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj **argv;\n#else /* TCL_MAJOR_VERSION < 8 */\n    char **argv;\n#endif\n    VALUE interp;\n    int *done;\n    int safe_level;\n    VALUE result;\n    VALUE thread;\n};\n\nstruct eval_queue {\n    Tcl_Event ev;\n    char *str;\n    int len;\n    VALUE interp;\n    int *done;\n    int safe_level;\n    VALUE result;\n    VALUE thread;\n};\n\nstruct call_queue {\n    Tcl_Event ev;\n    VALUE (*func)();\n    int argc;\n    VALUE *argv;\n    VALUE interp;\n    int *done;\n    int safe_level;\n    VALUE result;\n    VALUE thread;\n};\n\nvoid \ninvoke_queue_mark(struct invoke_queue *q)\n{\n    rb_gc_mark(q->interp);\n    rb_gc_mark(q->result);\n    rb_gc_mark(q->thread);\n}\n\nvoid \neval_queue_mark(struct eval_queue *q)\n{\n    rb_gc_mark(q->interp);\n    rb_gc_mark(q->result);\n    rb_gc_mark(q->thread);\n}\n\nvoid \ncall_queue_mark(struct call_queue *q)\n{\n    int i;\n\n    for(i = 0; i < q->argc; i++) {\n        rb_gc_mark(q->argv[i]);\n    }\n\n    rb_gc_mark(q->interp);\n    rb_gc_mark(q->result);\n    rb_gc_mark(q->thread);\n}\n\n\nstatic VALUE eventloop_thread;\n#ifdef RUBY_VM\nTcl_ThreadId tk_eventloop_thread_id;  /* native thread ID of Tcl interpreter */\n#endif\nstatic VALUE eventloop_stack;\nstatic int   window_event_mode = ( ~ TCL_IDLE_EVENTS | TCL_WINDOW_EVENTS );\n\nstatic VALUE watchdog_thread;\n\nTcl_Interp  *current_interp;\n\n/* thread control strategy */ \n/* multi-tk works with the following settings only ???\n    : CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE 1\n    : USE_TOGGLE_WINDOW_MODE_FOR_IDLE 0\n    : DO_THREAD_SCHEDULE_AT_CALLBACK_DONE 0\n*/\n#define CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE 1\n#define USE_TOGGLE_WINDOW_MODE_FOR_IDLE 0\n#define DO_THREAD_SCHEDULE_AT_CALLBACK_DONE 0\n\n#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE\nstatic int have_rb_thread_waiting_for_value = 0;\n#endif\n\n/* \n *  'event_loop_max' is a maximum events which the eventloop processes in one \n *  term of thread scheduling. 'no_event_tick' is the count-up value when \n *  there are no event for processing. \n *  'timer_tick' is a limit of one term of thread scheduling. \n *  If 'timer_tick' == 0, then not use the timer for thread scheduling.\n */\n#ifdef RUBY_VM\n#define DEFAULT_EVENT_LOOP_MAX        800/*counts*/\n#define DEFAULT_NO_EVENT_TICK          10/*counts*/\n#define DEFAULT_NO_EVENT_WAIT          10/*milliseconds ( 1 -- 999 ) */\n#define WATCHDOG_INTERVAL              10/*milliseconds ( 1 -- 999 ) */\n#define DEFAULT_TIMER_TICK              0/*milliseconds ( 0 -- 999 ) */\n#define NO_THREAD_INTERRUPT_TIME      100/*milliseconds ( 1 -- 999 ) */\n#else /* ! RUBY_VM */\n#define DEFAULT_EVENT_LOOP_MAX        800/*counts*/\n#define DEFAULT_NO_EVENT_TICK          10/*counts*/\n#define DEFAULT_NO_EVENT_WAIT          20/*milliseconds ( 1 -- 999 ) */\n#define WATCHDOG_INTERVAL              10/*milliseconds ( 1 -- 999 ) */\n#define DEFAULT_TIMER_TICK              0/*milliseconds ( 0 -- 999 ) */\n#define NO_THREAD_INTERRUPT_TIME      100/*milliseconds ( 1 -- 999 ) */\n#endif\n\nstatic int event_loop_max = DEFAULT_EVENT_LOOP_MAX;\nstatic int no_event_tick  = DEFAULT_NO_EVENT_TICK;\nstatic int no_event_wait  = DEFAULT_NO_EVENT_WAIT;\nstatic int timer_tick     = DEFAULT_TIMER_TICK;\nstatic int req_timer_tick = DEFAULT_TIMER_TICK;\nstatic int run_timer_flag = 0;\n\nstatic int event_loop_wait_event   = 0;\nstatic int event_loop_abort_on_exc = 1;\nstatic int loop_counter = 0;\n\nstatic int check_rootwidget_flag = 0;\n\n\n/* call ruby interpreter */\n#if TCL_MAJOR_VERSION >= 8\nstatic int ip_ruby_eval _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*));\nstatic int ip_ruby_cmd _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*));\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int ip_ruby_eval _((ClientData, Tcl_Interp *, int, char **));\nstatic int ip_ruby_cmd _((ClientData, Tcl_Interp *, int, char **));\n#endif\n\nstruct cmd_body_arg {\n    VALUE receiver;\n    ID    method;\n    VALUE args;\n};\n\n\n/*----------------------------*/\n/* use Tcl internal functions */\n/*----------------------------*/\n#ifndef TCL_NAMESPACE_DEBUG\n#define TCL_NAMESPACE_DEBUG 0\n#endif\n\n#if TCL_NAMESPACE_DEBUG\n\n#if TCL_MAJOR_VERSION >= 8\nEXTERN struct TclIntStubs *tclIntStubsPtr;\n#endif\n\n/*-- Tcl_GetCurrentNamespace --*/\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 5\n/* Tcl7.x doesn't have namespace support.                            */\n/* Tcl8.5+ has definition of Tcl_GetCurrentNamespace() in tclDecls.h */\n#  ifndef Tcl_GetCurrentNamespace\nEXTERN Tcl_Namespace *  Tcl_GetCurrentNamespace _((Tcl_Interp *));\n#  endif\n#  if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)\n#    ifndef Tcl_GetCurrentNamespace\n#      ifndef FunctionNum_of_GetCurrentNamespace\n#define FunctionNum_of_GetCurrentNamespace 124\n#      endif\nstruct DummyTclIntStubs_for_GetCurrentNamespace {\n    int magic;\n    struct TclIntStubHooks *hooks;\n    void (*func[FunctionNum_of_GetCurrentNamespace])();\n    Tcl_Namespace * (*tcl_GetCurrentNamespace) _((Tcl_Interp *));\n};\n\n#define Tcl_GetCurrentNamespace \\\n   (((struct DummyTclIntStubs_for_GetCurrentNamespace *)tclIntStubsPtr)->tcl_GetCurrentNamespace)\n#    endif\n#  endif\n#endif\n\n/* namespace check */\n/* ip_null_namespace(Tcl_Interp *interp) */\n#if TCL_MAJOR_VERSION < 8\n#define ip_null_namespace(interp) (0)\n#else /* support namespace */\n#define ip_null_namespace(interp) \\\n    (Tcl_GetCurrentNamespace(interp) == (Tcl_Namespace *)NULL)\n#endif\n\n/* rbtk_invalid_namespace(tcltkip *ptr) */\n#if TCL_MAJOR_VERSION < 8\n#define rbtk_invalid_namespace(ptr) (0)\n#else /* support namespace */\n#define rbtk_invalid_namespace(ptr) \\\n    ((ptr)->default_ns == (Tcl_Namespace*)NULL || Tcl_GetCurrentNamespace((ptr)->ip) != (ptr)->default_ns)\n#endif\n\n/*-- Tcl_PopCallFrame & Tcl_PushCallFrame --*/\n#if TCL_MAJOR_VERSION >= 8\n#  ifndef CallFrame\ntypedef struct CallFrame {\n    Tcl_Namespace *nsPtr;\n    int dummy1;\n    int dummy2;\n    char *dummy3;\n    struct CallFrame *callerPtr;\n    struct CallFrame *callerVarPtr;\n    int level;\n    char *dummy7;\n    char *dummy8;\n    int dummy9;\n    char* dummy10;\n} CallFrame;\n#  endif\n\n#  if !defined(TclGetFrame) && !defined(TclGetFrame_TCL_DECLARED)\nEXTERN int  TclGetFrame _((Tcl_Interp *, CONST char *, CallFrame **));\n#  endif\n#  if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)\n#    ifndef TclGetFrame\n#      ifndef FunctionNum_of_GetFrame\n#define FunctionNum_of_GetFrame 32\n#      endif\nstruct DummyTclIntStubs_for_GetFrame {\n    int magic;\n    struct TclIntStubHooks *hooks;\n    void (*func[FunctionNum_of_GetFrame])();\n    int (*tclGetFrame) _((Tcl_Interp *, CONST char *, CallFrame **));\n};\n#define TclGetFrame \\\n   (((struct DummyTclIntStubs_for_GetFrame *)tclIntStubsPtr)->tclGetFrame)\n#    endif\n#  endif\n\n#  if !defined(Tcl_PopCallFrame) && !defined(Tcl_PopCallFrame_TCL_DECLARED)\nEXTERN void Tcl_PopCallFrame _((Tcl_Interp *));\nEXTERN int  Tcl_PushCallFrame _((Tcl_Interp *, Tcl_CallFrame *, Tcl_Namespace *, int));\n#  endif\n#  if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)\n#    ifndef Tcl_PopCallFrame\n#      ifndef FunctionNum_of_PopCallFrame\n#define FunctionNum_of_PopCallFrame 128\n#      endif\nstruct DummyTclIntStubs_for_PopCallFrame {\n    int magic;\n    struct TclIntStubHooks *hooks;\n    void (*func[FunctionNum_of_PopCallFrame])();\n    void (*tcl_PopCallFrame) _((Tcl_Interp *));\n    int  (*tcl_PushCallFrame) _((Tcl_Interp *, Tcl_CallFrame *, Tcl_Namespace *, int));\n};\n\n#define Tcl_PopCallFrame \\\n   (((struct DummyTclIntStubs_for_PopCallFrame *)tclIntStubsPtr)->tcl_PopCallFrame)\n#define Tcl_PushCallFrame \\\n   (((struct DummyTclIntStubs_for_PopCallFrame *)tclIntStubsPtr)->tcl_PushCallFrame)\n#    endif\n#  endif\n\n#else /* Tcl7.x */\n#  ifndef CallFrame\ntypedef struct CallFrame {\n    Tcl_HashTable varTable;\n    int level;\n    int argc;\n    char **argv;\n    struct CallFrame *callerPtr;\n    struct CallFrame *callerVarPtr;\n} CallFrame;\n#  endif\n#  ifndef Tcl_CallFrame\n#define Tcl_CallFrame CallFrame\n#  endif\n\n#  if !defined(TclGetFrame) && !defined(TclGetFrame_TCL_DECLARED)\nEXTERN int  TclGetFrame _((Tcl_Interp *, CONST char *, CallFrame **));\n#  endif\n\n#  if !defined(Tcl_PopCallFrame) && !defined(Tcl_PopCallFrame_TCL_DECLARED)\ntypedef struct DummyInterp {\n    char *dummy1;\n    char *dummy2;\n    int  dummy3;\n    Tcl_HashTable dummy4;\n    Tcl_HashTable dummy5;\n    Tcl_HashTable dummy6;\n    int numLevels;\n    int maxNestingDepth;\n    CallFrame *framePtr;\n    CallFrame *varFramePtr;\n} DummyInterp;\n\nstatic void\nTcl_PopCallFrame(interp)\n    Tcl_Interp *interp;\n{\n    DummyInterp *iPtr = (DummyInterp*)interp;\n    CallFrame *frame = iPtr->varFramePtr;\n\n    /* **** DUMMY **** */\n    iPtr->framePtr = frame.callerPtr;\n    iPtr->varFramePtr = frame.callerVarPtr;\n\n    return TCL_OK;\n}\n\n/* dummy */\n#define Tcl_Namespace char\n\nstatic int\nTcl_PushCallFrame(interp, framePtr, nsPtr, isProcCallFrame)\n    Tcl_Interp *interp;\n    Tcl_CallFrame *framePtr;\n    Tcl_Namespace *nsPtr;\n    int isProcCallFrame;\n{\n    DummyInterp *iPtr = (DummyInterp*)interp;\n    CallFrame *frame = (CallFrame *)framePtr;\n\n    /* **** DUMMY **** */\n    Tcl_InitHashTable(&frame.varTable, TCL_STRING_KEYS);\n    if (iPtr->varFramePtr != NULL) {\n        frame.level = iPtr->varFramePtr->level + 1;\n    } else {\n        frame.level = 1;\n    }\n    frame.callerPtr = iPtr->framePtr;\n    frame.callerVarPtr = iPtr->varFramePtr;\n    iPtr->framePtr = &frame;\n    iPtr->varFramePtr = &frame;\n\n    return TCL_OK;\n}\n#  endif\n\n#endif\n\n#endif /* TCL_NAMESPACE_DEBUG */\n\n\n/*---- class TclTkIp ----*/\nstruct tcltkip {\n    Tcl_Interp *ip;              /* the interpreter */\n#if TCL_NAMESPACE_DEBUG\n    Tcl_Namespace *default_ns;   /* default namespace */\n#endif\n#ifdef RUBY_VM\n    Tcl_ThreadId tk_thread_id;   /* native thread ID of Tcl interpreter */\n#endif\n    int has_orig_exit;           /* has original 'exit' command ? */\n    Tcl_CmdInfo orig_exit_info;  /* command info of original 'exit' command */\n    int ref_count;               /* reference count of rbtk_preserve_ip call */\n    int allow_ruby_exit;         /* allow exiting ruby by 'exit' function */\n    int return_value;            /* return value */\n};\n\nstatic struct tcltkip *\nget_ip(self)\n    VALUE self;\n{\n    struct tcltkip *ptr;\n\n    Data_Get_Struct(self, struct tcltkip, ptr);\n    if (ptr == 0) {\n        /* rb_raise(rb_eTypeError, \"uninitialized TclTkIp\"); */\n        return((struct tcltkip *)NULL);\n    }\n    if (ptr->ip == (Tcl_Interp*)NULL) {\n        /* rb_raise(rb_eRuntimeError, \"deleted IP\"); */\n        return((struct tcltkip *)NULL);\n    }\n    return ptr;\n}\n\nstatic int\ndeleted_ip(ptr)\n    struct tcltkip *ptr;\n{\n    if (!ptr || !ptr->ip || Tcl_InterpDeleted(ptr->ip)\n#if TCL_NAMESPACE_DEBUG\n          || rbtk_invalid_namespace(ptr)\n#endif\n    ) {\n        DUMP1(\"ip is deleted\");\n        return 1;\n    }\n    return 0;\n}\n\n/* increment/decrement reference count of tcltkip */\nstatic int\nrbtk_preserve_ip(ptr)\n    struct tcltkip *ptr;\n{\n    ptr->ref_count++;\n    if (ptr->ip == (Tcl_Interp*)NULL) {\n        /* deleted IP */\n        ptr->ref_count = 0;\n    } else {\n        Tcl_Preserve((ClientData)ptr->ip);\n    }\n    return(ptr->ref_count);\n}\n\nstatic int\nrbtk_release_ip(ptr)\n    struct tcltkip *ptr;\n{\n    ptr->ref_count--;\n    if (ptr->ref_count < 0) {\n        ptr->ref_count = 0;\n    } else if (ptr->ip == (Tcl_Interp*)NULL) {\n        /* deleted IP */\n        ptr->ref_count = 0;\n    } else {\n        Tcl_Release((ClientData)ptr->ip);\n    }\n    return(ptr->ref_count);\n}\n\n\nstatic VALUE\n#ifdef HAVE_STDARG_PROTOTYPES\ncreate_ip_exc(VALUE interp, VALUE exc, const char *fmt, ...)\n#else\ncreate_ip_exc(interp, exc, fmt, va_alist)\n    VALUE interp:\n    VALUE exc;\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n    char buf[BUFSIZ];\n    VALUE einfo;\n    struct tcltkip *ptr = get_ip(interp);\n\n    va_init_list(args,fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    buf[BUFSIZ - 1] = '\\0';\n    va_end(args);\n    einfo = rb_exc_new2(exc, buf);\n    rb_ivar_set(einfo, ID_at_interp, interp);\n    if (ptr) {\n        Tcl_ResetResult(ptr->ip);\n    }\n\n    return einfo;\n}\n\n\n/* stub status */\nstatic void\ntcl_stubs_check()\n{\n    if (!tcl_stubs_init_p()) {\n        int st = ruby_tcl_stubs_init();\n        switch(st) {\n        case TCLTK_STUBS_OK:\n            break;\n        case NO_TCL_DLL:\n            rb_raise(rb_eLoadError, \"tcltklib: fail to open tcl_dll\");\n        case NO_FindExecutable:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_FindExecutable\");\n        case NO_CreateInterp:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_CreateInterp()\");\n        case NO_DeleteInterp:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_DeleteInterp()\");\n        case FAIL_CreateInterp:\n            rb_raise(rb_eRuntimeError, \"tcltklib: fail to create a new IP to call Tcl_InitStubs()\");\n        case FAIL_Tcl_InitStubs:\n            rb_raise(rb_eRuntimeError, \"tcltklib: fail to Tcl_InitStubs()\");\n        default:\n            rb_raise(rb_eRuntimeError, \"tcltklib: unknown error(%d) on ruby_tcl_stubs_init()\", st);\n        }\n    }\n}\n\n\nstatic VALUE\ntcltkip_init_tk(interp)\n    VALUE interp;\n{\n    struct tcltkip *ptr = get_ip(interp);\n\n#if TCL_MAJOR_VERSION >= 8\n    int  st;\n\n    if (Tcl_IsSafe(ptr->ip)) {\n        DUMP1(\"Tk_SafeInit\");\n        st = ruby_tk_stubs_safeinit(ptr->ip);\n        switch(st) {\n        case TCLTK_STUBS_OK:\n            break;\n        case NO_Tk_Init:\n            return rb_exc_new2(rb_eLoadError, \n                               \"tcltklib: can't find Tk_SafeInit()\");\n        case FAIL_Tk_Init:\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"tcltklib: fail to Tk_SafeInit(). %s\", \n                                 Tcl_GetStringResult(ptr->ip));\n        case FAIL_Tk_InitStubs:\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"tcltklib: fail to Tk_InitStubs(). %s\", \n                                 Tcl_GetStringResult(ptr->ip));\n        default:\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"tcltklib: unknown error(%d) on ruby_tk_stubs_safeinit\", st);\n        }\n    } else {\n        DUMP1(\"Tk_Init\");\n        st = ruby_tk_stubs_init(ptr->ip);\n        switch(st) {\n        case TCLTK_STUBS_OK:\n            break;\n        case NO_Tk_Init:\n            return rb_exc_new2(rb_eLoadError, \n                               \"tcltklib: can't find Tk_Init()\");\n        case FAIL_Tk_Init:\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"tcltklib: fail to Tk_Init(). %s\", \n                                 Tcl_GetStringResult(ptr->ip));\n        case FAIL_Tk_InitStubs:\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"tcltklib: fail to Tk_InitStubs(). %s\", \n                                 Tcl_GetStringResult(ptr->ip));\n        default:\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"tcltklib: unknown error(%d) on ruby_tk_stubs_init\", st);\n        }\n    }\n\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tk_Init\");\n    if (ruby_tk_stubs_init(ptr->ip) != TCLTK_STUBS_OK) {\n        return rb_exc_new2(rb_eRuntimeError, ptr->ip->result);\n    }\n#endif\n\n#ifdef RUBY_VM\n    ptr->tk_thread_id = Tcl_GetCurrentThread();\n#endif\n\n    return Qnil;\n}\n\n\n/* treat excetiopn on Tcl side */\nstatic VALUE rbtk_pending_exception;\nstatic int rbtk_eventloop_depth = 0;\nstatic int rbtk_internal_eventloop_handler = 0;\n\n\nstatic int\npending_exception_check0()\n{\n    volatile VALUE exc = rbtk_pending_exception;\n\n    if (!NIL_P(exc) && rb_obj_is_kind_of(exc, rb_eException)) {\n        DUMP1(\"find a pending exception\");\n        if (rbtk_eventloop_depth > 0 \n\t    || rbtk_internal_eventloop_handler > 0\n\t    ) {\n            return 1; /* pending */\n        } else {\n            rbtk_pending_exception = Qnil;\n\n            if (rb_obj_is_kind_of(exc, eTkCallbackRetry)) {\n                DUMP1(\"pending_exception_check0: call rb_jump_tag(retry)\");\n                rb_jump_tag(TAG_RETRY);\n            } else if (rb_obj_is_kind_of(exc, eTkCallbackRedo)) {\n                DUMP1(\"pending_exception_check0: call rb_jump_tag(redo)\");\n                rb_jump_tag(TAG_REDO);\n            } else if (rb_obj_is_kind_of(exc, eTkCallbackThrow)) {\n                DUMP1(\"pending_exception_check0: call rb_jump_tag(throw)\");\n                rb_jump_tag(TAG_THROW);\n            }\n\n            rb_exc_raise(exc);\n        }\n    } else {\n        return 0;\n    }\n}\n\nstatic int\npending_exception_check1(thr_crit_bup, ptr)\n    int thr_crit_bup;\n    struct tcltkip *ptr;\n{\n    volatile VALUE exc = rbtk_pending_exception;\n\n    if (!NIL_P(exc) && rb_obj_is_kind_of(exc, rb_eException)) {\n        DUMP1(\"find a pending exception\");\n\n        if (rbtk_eventloop_depth > 0\n\t    || rbtk_internal_eventloop_handler > 0\n\t    ) {\n            return 1; /* pending */\n        } else {\n            rbtk_pending_exception = Qnil;\n\n            if (ptr != (struct tcltkip *)NULL) {\n                /* Tcl_Release(ptr->ip); */\n                rbtk_release_ip(ptr);\n            }\n\n            rb_thread_critical = thr_crit_bup;\n\n            if (rb_obj_is_kind_of(exc, eTkCallbackRetry)) {\n                DUMP1(\"pending_exception_check1: call rb_jump_tag(retry)\");\n                rb_jump_tag(TAG_RETRY);\n            } else if (rb_obj_is_kind_of(exc, eTkCallbackRedo)) {\n                DUMP1(\"pending_exception_check1: call rb_jump_tag(redo)\");\n                rb_jump_tag(TAG_REDO);\n            } else if (rb_obj_is_kind_of(exc, eTkCallbackThrow)) {\n                DUMP1(\"pending_exception_check1: call rb_jump_tag(throw)\");\n                rb_jump_tag(TAG_THROW);\n            }\n            rb_exc_raise(exc);\n        }\n    } else {\n        return 0;\n    }\n}\n\n\n/* call original 'exit' command */\nstatic void \ncall_original_exit(ptr, state)\n    struct tcltkip *ptr;\n    int state;\n{\n    int  thr_crit_bup;\n    Tcl_CmdInfo *info;\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj *cmd_obj;\n    Tcl_Obj *state_obj;\n#endif\n    DUMP1(\"original_exit is called\");\n\n    if (!(ptr->has_orig_exit)) return;\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    Tcl_ResetResult(ptr->ip);\n\n    info = &(ptr->orig_exit_info);\n\n    /* memory allocation for arguments of this command */\n#if TCL_MAJOR_VERSION >= 8\n    state_obj = Tcl_NewIntObj(state);\n    Tcl_IncrRefCount(state_obj);\n\n    if (info->isNativeObjectProc) {\n        Tcl_Obj **argv;\n#define USE_RUBY_ALLOC 0\n#if USE_RUBY_ALLOC\n        argv = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, 3);\n#else /* not USE_RUBY_ALLOC */\n        argv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * 3);\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)argv); /* XXXXXXXX */\n#endif\n#endif\n\tcmd_obj = Tcl_NewStringObj(\"exit\", 4);\n\tTcl_IncrRefCount(cmd_obj);\n\n        argv[0] = cmd_obj;\n        argv[1] = state_obj;\n        argv[2] = (Tcl_Obj *)NULL;\n\n        ptr->return_value \n            = (*(info->objProc))(info->objClientData, ptr->ip, 2, argv);\n\n\tTcl_DecrRefCount(cmd_obj);\n\n#if USE_RUBY_ALLOC\n        free(argv);\n#else /* not USE_RUBY_ALLOC */\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* free(argv); */\n        ckfree((char*)argv);\n#endif\n#endif\n#endif\n#undef USE_RUBY_ALLOC\n\n    } else {\n        /* string interface */\n        char **argv;\n#define USE_RUBY_ALLOC 0\n#if USE_RUBY_ALLOC\n        argv = (char **)ALLOC_N(char *, 3); /* XXXXXXXXXX */\n#else /* not USE_RUBY_ALLOC */\n        argv = (char **)ckalloc(sizeof(char *) * 3);\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)argv); /* XXXXXXXX */\n#endif\n#endif\n        argv[0] = \"exit\";\n        /* argv[1] = Tcl_GetString(state_obj); */\n        argv[1] = Tcl_GetStringFromObj(state_obj, (int*)NULL);\n        argv[2] = (char *)NULL;\n\n        ptr->return_value = (*(info->proc))(info->clientData, ptr->ip, \n                                            2, (CONST84 char **)argv);\n\n#if USE_RUBY_ALLOC\n        free(argv);\n#else /* not USE_RUBY_ALLOC */\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* free(argv); */\n        ckfree((char*)argv);\n#endif\n#endif\n#endif\n#undef USE_RUBY_ALLOC\n    }\n\n    Tcl_DecrRefCount(state_obj);\n\n#else /* TCL_MAJOR_VERSION < 8 */\n    {\n        /* string interface */\n        char **argv;\n#define USE_RUBY_ALLOC 0\n#if USE_RUBY_ALLOC\n        argv = (char **)ALLOC_N(char *, 3);\n#else /* not USE_RUBY_ALLOC */\n        argv = (char **)ckalloc(sizeof(char *) * 3);\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)argv); /* XXXXXXXX */\n#endif\n#endif\n        argv[0] = \"exit\";\n        argv[1] = RSTRING_PTR(rb_fix2str(INT2NUM(state), 10));\n        argv[2] = (char *)NULL;\n\n        ptr->return_value = (*(info->proc))(info->clientData, ptr->ip, \n                                            2, argv);\n\n#if USE_RUBY_ALLOC\n        free(argv);\n#else /* not USE_RUBY_ALLOC */\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* free(argv); */\n        ckfree(argv);\n#endif\n#endif\n#endif\n#undef USE_RUBY_ALLOC\n    }\n#endif\n    DUMP1(\"complete original_exit\");\n\n    rb_thread_critical = thr_crit_bup;\n}\n\n/* Tk_ThreadTimer */\nstatic Tcl_TimerToken timer_token = (Tcl_TimerToken)NULL;\n\n/* timer callback */\nstatic void _timer_for_tcl _((ClientData));\nstatic void\n_timer_for_tcl(clientData)\n    ClientData clientData;\n{\n    int thr_crit_bup;\n\n    /* struct invoke_queue *q, *tmp; */\n    /* VALUE thread; */\n\n    DUMP1(\"call _timer_for_tcl\");\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    Tcl_DeleteTimerHandler(timer_token);\n\n    run_timer_flag = 1;\n\n    if (timer_tick > 0) {\n        timer_token = Tcl_CreateTimerHandler(timer_tick, _timer_for_tcl, \n                                             (ClientData)0);\n    } else {\n        timer_token = (Tcl_TimerToken)NULL;\n    }\n\n    rb_thread_critical = thr_crit_bup;\n\n    /* rb_thread_schedule(); */\n    /* tick_counter += event_loop_max; */\n}\n\n#ifdef RUBY_VM\n#if USE_TOGGLE_WINDOW_MODE_FOR_IDLE\nstatic int\ntoggle_eventloop_window_mode_for_idle()\n{\n  if (window_event_mode & TCL_IDLE_EVENTS) {\n    /* idle -> event */\n    window_event_mode |= TCL_WINDOW_EVENTS;\n    window_event_mode &= ~TCL_IDLE_EVENTS;\n    return 1;\n  } else {\n    /* event -> idle */\n    window_event_mode |= TCL_IDLE_EVENTS;\n    window_event_mode &= ~TCL_WINDOW_EVENTS;\n    return 0;\n  }\n}\n#endif\n#endif\n\nstatic VALUE\nset_eventloop_window_mode(self, mode)\n    VALUE self;\n    VALUE mode;\n{\n    rb_secure(4);\n\n    if (RTEST(mode)) {\n      window_event_mode = ~0;\n    } else {\n      window_event_mode = ~(TCL_WINDOW_EVENTS | TCL_IDLE_EVENTS);\n    }\n\n    return mode;\n}\n\nstatic VALUE\nget_eventloop_window_mode(self)\n    VALUE self;\n{\n    if ( ~window_event_mode ) {\n      return Qfalse;\n    } else {\n      return Qtrue;\n    }\n}\n\nstatic VALUE\nset_eventloop_tick(self, tick)\n    VALUE self;\n    VALUE tick;\n{\n    int ttick = NUM2INT(tick);\n    int thr_crit_bup;\n\n    rb_secure(4);\n\n    if (ttick < 0) {\n        rb_raise(rb_eArgError, \n                 \"timer-tick parameter must be 0 or positive number\");\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* delete old timer callback */\n    Tcl_DeleteTimerHandler(timer_token);\n\n    timer_tick = req_timer_tick = ttick;\n    if (timer_tick > 0) {\n        /* start timer callback */\n        timer_token = Tcl_CreateTimerHandler(timer_tick, _timer_for_tcl, \n                                             (ClientData)0);\n    } else {\n        timer_token = (Tcl_TimerToken)NULL;\n    }\n\n    rb_thread_critical = thr_crit_bup;\n\n    return tick;\n}\n\nstatic VALUE\nget_eventloop_tick(self)\n    VALUE self;\n{\n    return INT2NUM(timer_tick);\n}\n\nstatic VALUE\nip_set_eventloop_tick(self, tick)\n    VALUE self;\n    VALUE tick;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return get_eventloop_tick(self);\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return get_eventloop_tick(self);\n    }\n    return set_eventloop_tick(self, tick);\n}\n\nstatic VALUE\nip_get_eventloop_tick(self)\n    VALUE self;\n{\n    return get_eventloop_tick(self);\n}\n\nstatic VALUE\nset_no_event_wait(self, wait)\n    VALUE self;\n    VALUE wait;\n{\n    int t_wait = NUM2INT(wait);\n\n    rb_secure(4);\n\n    if (t_wait <= 0) {\n        rb_raise(rb_eArgError, \n                 \"no_event_wait parameter must be positive number\");\n    }\n\n    no_event_wait = t_wait;\n\n    return wait;\n}\n\nstatic VALUE\nget_no_event_wait(self)\n    VALUE self;\n{\n    return INT2NUM(no_event_wait);\n}\n\nstatic VALUE\nip_set_no_event_wait(self, wait)\n    VALUE self;\n    VALUE wait;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return get_no_event_wait(self);\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return get_no_event_wait(self);\n    }\n    return set_no_event_wait(self, wait);\n}\n\nstatic VALUE\nip_get_no_event_wait(self)\n    VALUE self;\n{\n    return get_no_event_wait(self);\n}\n\nstatic VALUE\nset_eventloop_weight(self, loop_max, no_event)\n    VALUE self;\n    VALUE loop_max;\n    VALUE no_event;\n{\n    int lpmax = NUM2INT(loop_max);\n    int no_ev = NUM2INT(no_event);\n\n    rb_secure(4);\n\n    if (lpmax <= 0 || no_ev <= 0) {\n        rb_raise(rb_eArgError, \"weight parameters must be positive numbers\");\n    }\n\n    event_loop_max = lpmax;\n    no_event_tick  = no_ev;\n\n    return rb_ary_new3(2, loop_max, no_event);\n}\n\nstatic VALUE\nget_eventloop_weight(self)\n    VALUE self;\n{\n    return rb_ary_new3(2, INT2NUM(event_loop_max), INT2NUM(no_event_tick));\n}\n\nstatic VALUE\nip_set_eventloop_weight(self, loop_max, no_event)\n    VALUE self;\n    VALUE loop_max;\n    VALUE no_event;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return get_eventloop_weight(self);\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return get_eventloop_weight(self);\n    }\n    return set_eventloop_weight(self, loop_max, no_event);\n}\n\nstatic VALUE\nip_get_eventloop_weight(self)\n    VALUE self;\n{\n    return get_eventloop_weight(self);\n}\n\nstatic VALUE\nset_max_block_time(self, time)\n    VALUE self;\n    VALUE time;\n{\n    struct Tcl_Time tcl_time;\n    VALUE divmod;\n\n    switch(TYPE(time)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n        /* time is micro-second value */\n        divmod = rb_funcall(time, rb_intern(\"divmod\"), 1, LONG2NUM(1000000));\n        tcl_time.sec  = NUM2LONG(RARRAY_PTR(divmod)[0]);\n        tcl_time.usec = NUM2LONG(RARRAY_PTR(divmod)[1]);\n        break;\n\n    case T_FLOAT:\n        /* time is second value */\n        divmod = rb_funcall(time, rb_intern(\"divmod\"), 1, INT2FIX(1));\n        tcl_time.sec  = NUM2LONG(RARRAY_PTR(divmod)[0]);\n        tcl_time.usec = (long)(NUM2DBL(RARRAY_PTR(divmod)[1]) * 1000000);\n\n    default:\n        {\n\t    VALUE tmp = rb_funcall(time, ID_inspect, 0, 0);\n\t    rb_raise(rb_eArgError, \"invalid value for time: '%s'\", \n\t\t     StringValuePtr(tmp));\n\t}\n    }\n\n    Tcl_SetMaxBlockTime(&tcl_time);\n\n    return Qnil;\n}\n\nstatic VALUE\nlib_evloop_thread_p(self)\n    VALUE self;\n{\n    if (NIL_P(eventloop_thread)) {\n        return Qnil;    /* no eventloop */\n    } else if (rb_thread_current() == eventloop_thread) {\n        return Qtrue;   /* is eventloop */\n    } else {\n        return Qfalse;  /* not eventloop */\n    }\n}\n\nstatic VALUE\nlib_evloop_abort_on_exc(self)\n    VALUE self;\n{\n    if (event_loop_abort_on_exc > 0) {\n        return Qtrue;\n    } else if (event_loop_abort_on_exc == 0) {\n        return Qfalse;\n    } else {\n        return Qnil;\n    }\n}\n\nstatic VALUE\nip_evloop_abort_on_exc(self)\n    VALUE self;\n{\n    return lib_evloop_abort_on_exc(self);\n}\n\nstatic VALUE\nlib_evloop_abort_on_exc_set(self, val)\n    VALUE self, val;\n{\n    rb_secure(4);\n    if (RTEST(val)) {\n        event_loop_abort_on_exc =  1;\n    } else if (NIL_P(val)) {\n        event_loop_abort_on_exc = -1;\n    } else {\n        event_loop_abort_on_exc =  0;\n    }\n    return lib_evloop_abort_on_exc(self);\n}\n\nstatic VALUE\nip_evloop_abort_on_exc_set(self, val)\n    VALUE self, val;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    rb_secure(4);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return lib_evloop_abort_on_exc(self);\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return lib_evloop_abort_on_exc(self);\n    }\n    return lib_evloop_abort_on_exc_set(self, val);\n}\n\nstatic VALUE\nlib_num_of_mainwindows_core(self, argc, argv)\n    VALUE self;\n    int   argc;   /* dummy */\n    VALUE *argv;  /* dummy */\n{\n    if (tk_stubs_init_p()) {\n        return INT2FIX(Tk_GetNumMainWindows());\n    } else {\n        return INT2FIX(0);\n    }\n}\n\nstatic VALUE\nlib_num_of_mainwindows(self)\n    VALUE self;\n{\n#ifdef RUBY_VM  /* Ruby 1.9+ !!! */\n    return tk_funcall(lib_num_of_mainwindows_core, 0, (VALUE*)NULL, self);\n#else\n    return lib_num_of_mainwindows_core(self, 0, (VALUE*)NULL);\n#endif\n}\n\n\n#ifdef RUBY_VM  /* Ruby 1.9+ !!! */\nstatic VALUE\ncall_DoOneEvent_core(flag_val)\n    VALUE flag_val;\n{\n    int flag;\n\n    flag = FIX2INT(flag_val);\n    if (Tcl_DoOneEvent(flag)) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n\nstatic VALUE\ncall_DoOneEvent(flag_val)\n    VALUE flag_val;\n{\n  return tk_funcall(call_DoOneEvent_core, 0, (VALUE*)NULL, flag_val);\n}\n\n#else  /* Ruby 1.8- */\nstatic VALUE\ncall_DoOneEvent(flag_val)\n    VALUE flag_val;\n{\n    int flag;\n\n    flag = FIX2INT(flag_val);\n    if (Tcl_DoOneEvent(flag)) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n#endif\n\n\nstatic VALUE\neventloop_sleep(dummy)\n    VALUE dummy;\n{\n    struct timeval t;\n\n    t.tv_sec = (time_t)0;\n    t.tv_usec = (time_t)(no_event_wait*1000.0);\n\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n        rb_bug(\"cross-thread violation on eventloop_sleep()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on eventloop_sleep()\");\n    }\n#endif\n#endif\n\n    DUMP2(\"eventloop_sleep: rb_thread_wait_for() at thread : %lx\", rb_thread_current());\n    rb_thread_wait_for(t);\n    DUMP2(\"eventloop_sleep: finish at thread : %lx\", rb_thread_current());\n\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n        rb_bug(\"cross-thread violation on eventloop_sleep()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on eventloop_sleep()\");\n    }\n#endif\n#endif\n\n    return Qnil;\n}\n\n#define USE_EVLOOP_THREAD_ALONE_CHECK_FLAG 0\n\n#if USE_EVLOOP_THREAD_ALONE_CHECK_FLAG\nstatic int\nget_thread_alone_check_flag()\n{\n#ifdef RUBY_VM\n  return 0;\n#else\n  set_tcltk_version();\n\n  if (tcltk_version.major < 8) {\n    /* Tcl/Tk 7.x */\n    return 1;\n  } else if (tcltk_version.major == 8) {\n    if (tcltk_version.minor < 5) {\n      /* Tcl/Tk 8.0 - 8.4 */\n      return 1;\n    } else if (tcltk_version.minor == 5) {\n      if (tcltk_version.type < TCL_FINAL_RELEASE) {\n\t/* Tcl/Tk 8.5a? - 8.5b? */\n\treturn 1;\n      } else {\n\t/* Tcl/Tk 8.5.x */\n\treturn 0;\n      }\n    } else {\n      /* Tcl/Tk 8.6 - 8.9 ?? */\n      return 0;\n    }\n  } else {\n    /* Tcl/Tk 9+ ?? */\n    return 0;\n  }\n#endif\n}\n#endif\n\nstatic int\nlib_eventloop_core(check_root, update_flag, check_var, interp)\n    int check_root;\n    int update_flag;\n    int *check_var;\n    Tcl_Interp *interp;\n{\n    volatile VALUE current = eventloop_thread;\n    int found_event = 1;\n    int event_flag;\n    struct timeval t;\n    int thr_crit_bup;\n    int status;\n    int depth = rbtk_eventloop_depth;\n#if USE_EVLOOP_THREAD_ALONE_CHECK_FLAG\n    int thread_alone_check_flag = 1;\n#endif\n\n    if (update_flag) DUMP1(\"update loop start!!\");\n\n    t.tv_sec = (time_t)0;\n    t.tv_usec = (time_t)(no_event_wait*1000.0);\n\n    Tcl_DeleteTimerHandler(timer_token);\n    run_timer_flag = 0;\n    if (timer_tick > 0) {\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n        timer_token = Tcl_CreateTimerHandler(timer_tick, _timer_for_tcl, \n                                             (ClientData)0);\n        rb_thread_critical = thr_crit_bup;\n    } else {\n        timer_token = (Tcl_TimerToken)NULL;\n    }\n\n#if USE_EVLOOP_THREAD_ALONE_CHECK_FLAG\n    /* version check */\n    thread_alone_check_flag = get_thread_alone_check_flag();\n#endif\n\n    for(;;) {\n#if USE_EVLOOP_THREAD_ALONE_CHECK_FLAG\n        if (thread_alone_check_flag && rb_thread_alone()) {\n#else\n        if (rb_thread_alone()) {\n#endif\n            DUMP1(\"no other thread\");\n            event_loop_wait_event = 0;\n\n            if (update_flag) {\n                event_flag = update_flag | TCL_DONT_WAIT; /* for safety */\n            } else {\n\t        event_flag = TCL_ALL_EVENTS;\n\t        /* event_flag = TCL_ALL_EVENTS | TCL_DONT_WAIT; */\n            }\n\n            if (timer_tick == 0 && update_flag == 0) {\n                timer_tick = NO_THREAD_INTERRUPT_TIME;\n                timer_token = Tcl_CreateTimerHandler(timer_tick, \n                                                     _timer_for_tcl, \n                                                     (ClientData)0);\n            }\n\n            if (check_var != (int *)NULL) {\n                if (*check_var || !found_event) {\n                    return found_event;\n                }\n                if (interp != (Tcl_Interp*)NULL \n                    && Tcl_InterpDeleted(interp)) {\n                    /* IP for check_var is deleted */\n                    return 0;\n                }\n            }\n\n            /* found_event = Tcl_DoOneEvent(event_flag); */\n            found_event = RTEST(rb_protect(call_DoOneEvent, \n                                           INT2FIX(event_flag), &status)); \n            if (status) {\n                switch (status) {\n                case TAG_RAISE:\n#ifdef RUBY_VM\n                    if (NIL_P(rb_errinfo())) {\n#else\n                    if (NIL_P(ruby_errinfo)) {\n#endif\n                        rbtk_pending_exception \n                            = rb_exc_new2(rb_eException, \"unknown exception\");\n                    } else {\n#ifdef RUBY_VM\n                        rbtk_pending_exception = rb_errinfo();\n#else\n                        rbtk_pending_exception = ruby_errinfo;\n#endif\n\n                        if (!NIL_P(rbtk_pending_exception)) {\n                            if (rbtk_eventloop_depth == 0) {\n                                VALUE exc = rbtk_pending_exception;\n                                rbtk_pending_exception = Qnil;\n                                rb_exc_raise(exc);\n                            } else {\n                                return 0;\n                            }\n                        }\n                    }\n                    break;\n\n                case TAG_FATAL:\n#ifdef RUBY_VM\n                    if (NIL_P(rb_errinfo())) {\n#else\n                    if (NIL_P(ruby_errinfo)) {\n#endif\n                        rb_exc_raise(rb_exc_new2(rb_eFatal, \"FATAL\"));\n                    } else {\n#ifdef RUBY_VM\n                        rb_exc_raise(rb_errinfo());\n#else\n                        rb_exc_raise(ruby_errinfo);\n#endif\n                    }\n                }\n            }\n\n            if (depth != rbtk_eventloop_depth) {\n                DUMP2(\"DoOneEvent(1) abnormal exit!! %d\", \n                      rbtk_eventloop_depth);\n            }\n\n            if (check_var != (int*)NULL && !NIL_P(rbtk_pending_exception)) {\n                DUMP1(\"exception on wait\");\n                return 0;\n            }\n\n            if (pending_exception_check0()) {\n                /* pending -> upper level */\n                return 0;\n            }\n\n            if (update_flag != 0) {\n              if (found_event) {\n                DUMP1(\"next update loop\");\n                continue;\n              } else {\n                DUMP1(\"update complete\");\n                return 0;\n              }\n            }\n\n            DUMP1(\"trap check\");\n            if (rb_trap_pending) {\n                run_timer_flag = 0;\n                if (rb_prohibit_interrupt || check_var != (int*)NULL) {\n                    /* pending or on wait command */\n                    return 0;\n                } else {\n                    rb_trap_exec();\n                }\n            }\n\n            DUMP1(\"check Root Widget\");\n            if (check_root && tk_stubs_init_p() && Tk_GetNumMainWindows() == 0) {\n                run_timer_flag = 0;\n                if (rb_trap_pending) {\n                    if (rb_prohibit_interrupt || check_var != (int*)NULL) {\n                        /* pending or on wait command */\n                        return 0;\n                    } else {\n                        rb_trap_exec();\n                    }\n                }\n                return 1;\n            }\n\n            if (loop_counter++ > 30000) {\n                /* fprintf(stderr, \"loop_counter > 30000\\n\"); */\n                loop_counter = 0;\n            }\n\n        } else {\n            int tick_counter;\n\n            DUMP1(\"there are other threads\");\n            event_loop_wait_event = 1;\n\n            found_event = 1;\n\n            if (update_flag) {\n                event_flag = update_flag | TCL_DONT_WAIT; /* for safety */\n            } else {\n                event_flag = TCL_ALL_EVENTS | TCL_DONT_WAIT;\n            }\n\n            timer_tick = req_timer_tick;\n            tick_counter = 0;\n            while(tick_counter < event_loop_max) {\n                if (check_var != (int *)NULL) {\n                    if (*check_var || !found_event) {\n                        return found_event;\n                    }\n                    if (interp != (Tcl_Interp*)NULL \n                        && Tcl_InterpDeleted(interp)) {\n                        /* IP for check_var is deleted */\n                        return 0;\n                    }\n                }\n\n                if (NIL_P(eventloop_thread) || current == eventloop_thread) {\n                    int st;\n                    int status;\n#ifdef RUBY_VM\n\t\t    if (update_flag) {\n\t\t      st = RTEST(rb_protect(call_DoOneEvent, \n\t\t\t\t\t    INT2FIX(event_flag), &status)); \n\t\t    } else {\n\t\t      st = RTEST(rb_protect(call_DoOneEvent, \n\t\t\t\t\t    INT2FIX(event_flag & window_event_mode), \n\t\t\t\t\t    &status)); \n#if USE_TOGGLE_WINDOW_MODE_FOR_IDLE\n\t\t      if (!st) {\n\t\t\tif (toggle_eventloop_window_mode_for_idle()) {\n\t\t\t  /* idle-mode -> event-mode*/\n\t\t\t  tick_counter = event_loop_max;\n\t\t\t} else {\n\t\t\t  /* event-mode -> idle-mode */\n\t\t\t  tick_counter = 0;\n\t\t\t}\n\t\t      }\n#endif\n\t\t    }\n#else\n                    /* st = Tcl_DoOneEvent(event_flag); */\n                    st = RTEST(rb_protect(call_DoOneEvent, \n                                          INT2FIX(event_flag), &status)); \n#endif\n\n#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE\n\t\t    if (have_rb_thread_waiting_for_value) {\n\t\t      have_rb_thread_waiting_for_value = 0;\n\t\t      rb_thread_schedule();\n\t\t    }\n#endif\n\n                    if (status) {\n                        switch (status) {\n                        case TAG_RAISE:\n#ifdef RUBY_VM\n                            if (NIL_P(rb_errinfo())) {\n#else\n                            if (NIL_P(ruby_errinfo)) {\n#endif\n                                rbtk_pending_exception \n                                    = rb_exc_new2(rb_eException, \n                                                  \"unknown exception\");\n                            } else {\n#ifdef RUBY_VM\n                                rbtk_pending_exception = rb_errinfo();\n#else\n                                rbtk_pending_exception = ruby_errinfo;\n#endif\n\n                                if (!NIL_P(rbtk_pending_exception)) {\n                                    if (rbtk_eventloop_depth == 0) {\n                                        VALUE exc = rbtk_pending_exception;\n                                        rbtk_pending_exception = Qnil;\n                                        rb_exc_raise(exc);\n                                    } else {\n                                        return 0;\n                                    }\n                                }\n                            }\n                            break;\n\n                        case TAG_FATAL:\n#ifdef RUBY_VM\n                            if (NIL_P(rb_errinfo())) {\n#else\n                            if (NIL_P(ruby_errinfo)) {\n#endif\n                                rb_exc_raise(rb_exc_new2(rb_eFatal, \"FATAL\"));\n                            } else {\n#ifdef RUBY_VM\n                                rb_exc_raise(rb_errinfo());\n#else\n                                rb_exc_raise(ruby_errinfo);\n#endif\n                            }\n                        }\n                    }\n\n                    if (depth != rbtk_eventloop_depth) {\n                        DUMP2(\"DoOneEvent(2) abnormal exit!! %d\", \n                              rbtk_eventloop_depth);\n                        return 0;\n                    }\n\n                    DUMP1(\"trap check\");\n                    if (rb_trap_pending) {\n                        run_timer_flag = 0;\n                        if (rb_prohibit_interrupt || check_var != (int*)NULL) {\n                            /* pending or on wait command */\n                            return 0;\n                        } else {\n                            rb_trap_exec();\n                        }\n                    }\n\n                    if (check_var != (int*)NULL \n                        && !NIL_P(rbtk_pending_exception)) {\n                        DUMP1(\"exception on wait\");\n                        return 0;\n                    }\n\n                    if (pending_exception_check0()) {\n                        /* pending -> upper level */\n                        return 0;\n                    }\n\n                    if (st) {\n                        tick_counter++;\n                    } else {\n                        if (update_flag != 0) {\n                            DUMP1(\"update complete\");\n                            return 0;\n                        }\n\n                        tick_counter += no_event_tick;\n\n                        /* rb_thread_wait_for(t); */\n\n                        rb_protect(eventloop_sleep, Qnil, &status);\n\n                        if (status) {\n                            switch (status) {\n                            case TAG_RAISE:\n#ifdef RUBY_VM\n                                if (NIL_P(rb_errinfo())) {\n#else\n                                if (NIL_P(ruby_errinfo)) {\n#endif\n                                    rbtk_pending_exception \n                                        = rb_exc_new2(rb_eException, \n                                                      \"unknown exception\");\n                                } else {\n#ifdef RUBY_VM\n                                    rbtk_pending_exception = rb_errinfo();\n#else\n                                    rbtk_pending_exception = ruby_errinfo;\n#endif\n\n                                    if (!NIL_P(rbtk_pending_exception)) {\n                                        if (rbtk_eventloop_depth == 0) {\n                                            VALUE exc = rbtk_pending_exception;\n                                            rbtk_pending_exception = Qnil;\n                                            rb_exc_raise(exc);\n                                        } else {\n                                            return 0;\n                                        }\n                                    }\n                                }\n                                break;\n\n                            case TAG_FATAL:\n#ifdef RUBY_VM\n                                if (NIL_P(rb_errinfo())) {\n#else\n                                if (NIL_P(ruby_errinfo)) {\n#endif\n                                    rb_exc_raise(rb_exc_new2(rb_eFatal, \n                                                             \"FATAL\"));\n                                } else {\n#ifdef RUBY_VM\n                                    rb_exc_raise(rb_errinfo());\n#else\n                                    rb_exc_raise(ruby_errinfo);\n#endif\n                                }\n                            }\n                        }\n                    }\n\n                } else {\n                    DUMP2(\"sleep eventloop %lx\", current);\n                    DUMP2(\"eventloop thread is %lx\", eventloop_thread);\n                    /* rb_thread_stop(); */\n                    rb_thread_sleep_forever();\n                }\n\n                if (!NIL_P(watchdog_thread) && eventloop_thread != current) {\n                    return 1;\n                }\n\n                DUMP1(\"trap check\");\n                if (rb_trap_pending) {\n                    run_timer_flag = 0;\n                    if (rb_prohibit_interrupt || check_var != (int*)NULL) {\n                        /* pending or on wait command */\n                        return 0;\n                    } else {\n                        rb_trap_exec();\n                    }\n                }\n\n                DUMP1(\"check Root Widget\");\n                if (check_root && tk_stubs_init_p() && Tk_GetNumMainWindows() == 0) {\n                    run_timer_flag = 0;\n                    if (rb_trap_pending) {\n                        if (rb_prohibit_interrupt || check_var != (int*)NULL) {\n                            /* pending or on wait command */\n                            return 0;\n                        } else {\n                            rb_trap_exec();\n                        }\n                    }\n                    return 1;\n                }\n\n                if (loop_counter++ > 30000) {\n                    /* fprintf(stderr, \"loop_counter > 30000\\n\"); */\n                    loop_counter = 0;\n                }\n\n                if (run_timer_flag) {\n                    /*\n                    DUMP1(\"timer interrupt\");\n                    run_timer_flag = 0;\n                    */\n                    break; /* switch to other thread */\n                }\n            }\n\n            DUMP1(\"thread scheduling\");\n            rb_thread_schedule();\n        }\n\n        DUMP1(\"trap check & thread scheduling\");\n#ifdef RUBY_VM\n        /* if (update_flag == 0) CHECK_INTS; */ /*XXXXXXXXXXXXX  TODO !!!! */\n#else\n        if (update_flag == 0) CHECK_INTS;\n#endif\n\n    }\n    return 1;\n}\n\n\nstruct evloop_params {\n    int check_root;\n    int update_flag;\n    int *check_var;\n    Tcl_Interp *interp;\n    int thr_crit_bup;\n};\n\nVALUE\nlib_eventloop_main_core(args)\n    VALUE args;\n{\n    struct evloop_params *params = (struct evloop_params *)args;\n\n    check_rootwidget_flag = params->check_root;\n\n    if (lib_eventloop_core(params->check_root, \n                           params->update_flag, \n                           params->check_var, \n                           params->interp)) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n\nVALUE\nlib_eventloop_main(args)\n    VALUE args;\n{\n    return lib_eventloop_main_core(args);\n\n#if 0\n    volatile VALUE ret;\n    int status = 0;\n\n    ret = rb_protect(lib_eventloop_main_core, args, &status);\n\n    switch (status) {\n    case TAG_RAISE:\n#ifdef RUBY_VM\n        if (NIL_P(rb_errinfo())) {\n#else\n        if (NIL_P(ruby_errinfo)) {\n#endif\n            rbtk_pending_exception \n                = rb_exc_new2(rb_eException, \"unknown exception\");\n        } else {\n#ifdef RUBY_VM\n            rbtk_pending_exception = rb_errinfo();\n#else\n            rbtk_pending_exception = ruby_errinfo;\n#endif\n        }\n        return Qnil;\n\n    case TAG_FATAL:\n#ifdef RUBY_VM\n        if (NIL_P(rb_errinfo())) {\n#else\n        if (NIL_P(ruby_errinfo)) {\n#endif\n            rbtk_pending_exception = rb_exc_new2(rb_eFatal, \"FATAL\");\n        } else {\n#ifdef RUBY_VM\n            rbtk_pending_exception = rb_errinfo();\n#else\n            rbtk_pending_exception = ruby_errinfo;\n#endif\n        }\n        return Qnil;\n    }\n\n    return ret;\n#endif\n}\n\nVALUE\nlib_eventloop_ensure(args)\n    VALUE args;\n{\n    struct evloop_params *ptr = (struct evloop_params *)args;\n    volatile VALUE current_evloop = rb_thread_current();\n\n    DUMP2(\"eventloop_ensure: current-thread : %lx\", current_evloop);\n    DUMP2(\"eventloop_ensure: eventloop-thread : %lx\", eventloop_thread);\n    if (eventloop_thread != current_evloop) {\n        DUMP2(\"finish eventloop %lx (NOT current eventloop)\", current_evloop);\n\n\trb_thread_critical = ptr->thr_crit_bup;\n\n        free(ptr);\n        /* ckfree((char*)ptr); */\n\n        return Qnil;\n    }\n\n    while((eventloop_thread = rb_ary_pop(eventloop_stack))) {\n        DUMP2(\"eventloop-ensure: new eventloop-thread -> %lx\", \n              eventloop_thread);\n\n        if (eventloop_thread == current_evloop) {\n            rbtk_eventloop_depth--;\n            DUMP2(\"eventloop %lx : back from recursive call\", current_evloop);\n            break;\n        }\n\n        if (NIL_P(eventloop_thread)) {\n          Tcl_DeleteTimerHandler(timer_token);\n          timer_token = (Tcl_TimerToken)NULL;\n\n          break; \n        }\n\n        /* if (RTEST(rb_funcall(eventloop_thread, ID_alive_p, 0, 0))) { */\n\tif (RTEST(rb_thread_alive_p(eventloop_thread))) {\n            DUMP2(\"eventloop-enshure: wake up parent %lx\", eventloop_thread);\n            rb_thread_wakeup(eventloop_thread);\n\n            break;\n        }\n    }\n\n#ifdef RUBY_VM\n    if (NIL_P(eventloop_thread)) {\n        tk_eventloop_thread_id = (Tcl_ThreadId) 0;\n    }\n#endif\n\n    rb_thread_critical = ptr->thr_crit_bup;\n\n    free(ptr);\n    /* ckfree((char*)ptr);*/\n\n    DUMP2(\"finish current eventloop %lx\", current_evloop);\n    return Qnil;\n}\n\nstatic VALUE\nlib_eventloop_launcher(check_root, update_flag, check_var, interp)\n    int check_root;\n    int update_flag;\n    int *check_var;\n    Tcl_Interp *interp;\n{\n    volatile VALUE parent_evloop = eventloop_thread;\n    struct evloop_params *args = ALLOC(struct evloop_params);\n    /* struct evloop_params *args = (struct evloop_params *)ckalloc(sizeof(struct evloop_params)); */\n\n    tcl_stubs_check();\n\n    eventloop_thread = rb_thread_current();\n#ifdef RUBY_VM\n    tk_eventloop_thread_id = Tcl_GetCurrentThread();\n#endif\n\n    if (parent_evloop == eventloop_thread) {\n        DUMP2(\"eventloop: recursive call on %lx\", parent_evloop);\n        rbtk_eventloop_depth++;\n    }\n\n    if (!NIL_P(parent_evloop) && parent_evloop != eventloop_thread) {\n        DUMP2(\"wait for stop of parent_evloop %lx\", parent_evloop);\n        while(!RTEST(rb_funcall(parent_evloop, ID_stop_p, 0))) {\n            DUMP2(\"parent_evloop %lx doesn't stop\", parent_evloop);\n            rb_thread_run(parent_evloop);\n        }\n        DUMP1(\"succeed to stop parent\");\n    }\n\n    rb_ary_push(eventloop_stack, parent_evloop);\n\n    DUMP3(\"tcltklib: eventloop-thread : %lx -> %lx\\n\", \n                parent_evloop, eventloop_thread);\n\n    args->check_root   = check_root;\n    args->update_flag  = update_flag;\n    args->check_var    = check_var;\n    args->interp       = interp;\n    args->thr_crit_bup = rb_thread_critical;\n\n    rb_thread_critical = Qfalse;\n\n#if 0\n    return rb_ensure(lib_eventloop_main, (VALUE)args, \n                     lib_eventloop_ensure, (VALUE)args);\n#endif\n    return rb_ensure(lib_eventloop_main_core, (VALUE)args, \n                     lib_eventloop_ensure, (VALUE)args);\n}\n\n/* execute Tk_MainLoop */\nstatic VALUE\nlib_mainloop(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE check_rootwidget;\n\n    if (rb_scan_args(argc, argv, \"01\", &check_rootwidget) == 0) {\n        check_rootwidget = Qtrue;\n    } else if (RTEST(check_rootwidget)) {\n        check_rootwidget = Qtrue;\n    } else {\n        check_rootwidget = Qfalse;\n    }\n\n    return lib_eventloop_launcher(RTEST(check_rootwidget), 0, \n                                  (int*)NULL, (Tcl_Interp*)NULL);\n}\n\nstatic VALUE\nip_mainloop(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return Qnil;\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return Qnil;\n    }\n    return lib_mainloop(argc, argv, self);\n}\n\n\nstatic VALUE\nwatchdog_evloop_launcher(check_rootwidget)\n    VALUE check_rootwidget;\n{\n    return lib_eventloop_launcher(RTEST(check_rootwidget), 0, \n                                  (int*)NULL, (Tcl_Interp*)NULL);\n}\n\n#define EVLOOP_WAKEUP_CHANCE 3\n\nstatic VALUE\nlib_watchdog_core(check_rootwidget)\n    VALUE check_rootwidget;\n{\n    VALUE evloop;\n    int   prev_val = -1;\n    int   chance = 0;\n    int   check = RTEST(check_rootwidget);\n    struct timeval t0, t1;\n\n    t0.tv_sec  = (time_t)0;\n    t0.tv_usec = (time_t)((NO_THREAD_INTERRUPT_TIME)*1000.0);\n    t1.tv_sec  = (time_t)0;\n    t1.tv_usec = (time_t)((WATCHDOG_INTERVAL)*1000.0);\n\n    /* check other watchdog thread */\n    if (!NIL_P(watchdog_thread)) {\n        if (RTEST(rb_funcall(watchdog_thread, ID_stop_p, 0))) {\n            rb_funcall(watchdog_thread, ID_kill, 0);\n        } else {\n            return Qnil;\n        }\n    }\n    watchdog_thread = rb_thread_current();\n\n    /* watchdog start */\n    do {\n        if (NIL_P(eventloop_thread)\n            || (loop_counter == prev_val && chance >= EVLOOP_WAKEUP_CHANCE)) {\n            /* start new eventloop thread */\n            DUMP2(\"eventloop thread %lx is sleeping or dead\", \n                  eventloop_thread);\n            evloop = rb_thread_create(watchdog_evloop_launcher, \n                                      (void*)&check_rootwidget);\n            DUMP2(\"create new eventloop thread %lx\", evloop);\n            loop_counter = -1;\n            chance = 0;\n            rb_thread_run(evloop);\n        } else {\n            prev_val = loop_counter;\n            if (RTEST(rb_funcall(eventloop_thread, ID_stop_p, 0))) {\n                ++chance;\n            } else {\n                chance = 0;\n            }\n            if (event_loop_wait_event) {\n                rb_thread_wait_for(t0);\n            } else {\n                rb_thread_wait_for(t1);\n            }\n            /* rb_thread_schedule(); */\n        }\n    } while(!check || !tk_stubs_init_p() || Tk_GetNumMainWindows() != 0);\n\n    return Qnil;\n}\n\nVALUE\nlib_watchdog_ensure(arg)\n    VALUE arg;\n{\n    eventloop_thread = Qnil; /* stop eventloops */\n#ifdef RUBY_VM\n    tk_eventloop_thread_id = (Tcl_ThreadId) 0;\n#endif\n    return Qnil;\n}\n\nstatic VALUE\nlib_mainloop_watchdog(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE check_rootwidget;\n\n#ifdef RUBY_VM\n    rb_raise(rb_eNotImpError, \n\t     \"eventloop_watchdog is not implemented on Ruby VM.\");\n#endif\n\n    if (rb_scan_args(argc, argv, \"01\", &check_rootwidget) == 0) {\n        check_rootwidget = Qtrue;\n    } else if (RTEST(check_rootwidget)) {\n        check_rootwidget = Qtrue;\n    } else {\n        check_rootwidget = Qfalse;\n    }\n\n    return rb_ensure(lib_watchdog_core, check_rootwidget, \n                     lib_watchdog_ensure, Qnil);\n}\n\nstatic VALUE\nip_mainloop_watchdog(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return Qnil;\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return Qnil;\n    }\n    return lib_mainloop_watchdog(argc, argv, self);\n}\n\n\n/* thread-safe(?) interaction between Ruby and Tk */\nstruct thread_call_proc_arg {\n    VALUE proc;\n    int *done;\n};\n\nvoid \n_thread_call_proc_arg_mark(struct thread_call_proc_arg *q)\n{\n    rb_gc_mark(q->proc);\n}\n\nstatic VALUE\n_thread_call_proc_core(arg)\n    VALUE arg;\n{\n    struct thread_call_proc_arg *q = (struct thread_call_proc_arg*)arg;\n    return rb_funcall(q->proc, ID_call, 0);\n}\n\nstatic VALUE\n_thread_call_proc_ensure(arg)\n    VALUE arg;\n{\n    struct thread_call_proc_arg *q = (struct thread_call_proc_arg*)arg;\n    *(q->done) = 1;\n    return Qnil;\n}\n\nstatic VALUE\n_thread_call_proc(arg)\n    VALUE arg;\n{\n    struct thread_call_proc_arg *q = (struct thread_call_proc_arg*)arg;\n\n    return rb_ensure(_thread_call_proc_core, (VALUE)q, \n                     _thread_call_proc_ensure, (VALUE)q);\n}\n\nstatic VALUE\n_thread_call_proc_value(th)\n    VALUE th;\n{\n    return rb_funcall(th, ID_value, 0);\n}\n\nstatic VALUE\nlib_thread_callback(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct thread_call_proc_arg *q;\n    VALUE proc, th, ret;\n    int status, foundEvent;\n\n    if (rb_scan_args(argc, argv, \"01\", &proc) == 0) {\n        proc = rb_block_proc();\n    }\n\n    q = (struct thread_call_proc_arg *)ALLOC(struct thread_call_proc_arg);\n    /* q = (struct thread_call_proc_arg *)ckalloc(sizeof(struct thread_call_proc_arg)); */\n    q->proc = proc;\n    q->done = (int*)ALLOC(int);\n    /* q->done = (int*)ckalloc(sizeof(int)); */\n    *(q->done) = 0;\n\n    /* create call-proc thread */\n    th = rb_thread_create(_thread_call_proc, (void*)q);\n\n    rb_thread_schedule();\n\n    /* start sub-eventloop */\n    foundEvent = RTEST(lib_eventloop_launcher(/* not check root-widget */0, 0, \n                                              q->done, (Tcl_Interp*)NULL));\n\n    /* if (RTEST(rb_funcall(th, ID_alive_p, 0))) { */\n    if (RTEST(rb_thread_alive_p(th))) {\n        rb_funcall(th, ID_kill, 0);\n        ret = Qnil;\n    } else {\n        ret = rb_protect(_thread_call_proc_value, th, &status);\n    }\n\n    free(q->done);\n    free(q);\n    /* ckfree((char*)q->done); */\n    /* ckfree((char*)q); */\n\n    if (NIL_P(rbtk_pending_exception)) {\n#ifdef RUBY_VM\n        /* return rb_errinfo(); */\n        if (status) {\n            rb_exc_raise(rb_errinfo());\n        }\n#else\n        /* return ruby_errinfo; */\n        if (status) {\n            rb_exc_raise(ruby_errinfo);\n        }\n#endif\n    } else {\n        VALUE exc = rbtk_pending_exception;\n        rbtk_pending_exception = Qnil;\n        /* return exc; */\n        rb_exc_raise(exc);\n    }\n\n    return ret;\n}\n\n\n/* do_one_event */\nstatic VALUE\nlib_do_one_event_core(argc, argv, self, is_ip)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n    int   is_ip;\n{\n    volatile VALUE vflags;\n    int flags;\n    int found_event;\n\n    if (!NIL_P(eventloop_thread)) {\n        rb_raise(rb_eRuntimeError, \"eventloop is already running\");\n    }\n\n    tcl_stubs_check();\n\n    if (rb_scan_args(argc, argv, \"01\", &vflags) == 0) {\n        flags = TCL_ALL_EVENTS | TCL_DONT_WAIT;\n    } else {\n        Check_Type(vflags, T_FIXNUM);\n        flags = FIX2INT(vflags);\n    }\n\n    if (rb_safe_level() >= 4 || (rb_safe_level() >=1 && OBJ_TAINTED(vflags))) {\n      flags |= TCL_DONT_WAIT;\n    }\n\n    if (is_ip) {\n        /* check IP */\n        struct tcltkip *ptr = get_ip(self);\n\n        /* ip is deleted? */\n        if (deleted_ip(ptr)) {\n            return Qfalse;\n        }\n\n        if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n            /* slave IP */\n            flags |= TCL_DONT_WAIT;\n        }\n    }\n\n    /* found_event = Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT); */\n    found_event = Tcl_DoOneEvent(flags);\n\n    if (pending_exception_check0()) {\n        return Qfalse;\n    }\n\n    if (found_event) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n\nstatic VALUE\nlib_do_one_event(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return lib_do_one_event_core(argc, argv, self, 0);\n}\n\nstatic VALUE\nip_do_one_event(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return lib_do_one_event_core(argc, argv, self, 0);\n}\n\n\nstatic void\nip_set_exc_message(interp, exc)\n    Tcl_Interp *interp;\n    VALUE exc;\n{\n    char *buf;\n    Tcl_DString dstr;\n    volatile VALUE msg;\n    int thr_crit_bup;\n\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)\n    volatile VALUE enc;\n    Tcl_Encoding encoding;\n#endif\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    msg = rb_funcall(exc, ID_message, 0, 0);\n    StringValue(msg);\n\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)\n    enc = rb_attr_get(exc, ID_at_enc);\n    if (NIL_P(enc)) {\n        enc = rb_attr_get(msg, ID_at_enc);\n    }\n    if (NIL_P(enc)) {\n        encoding = (Tcl_Encoding)NULL;\n    } else if (TYPE(enc) == T_STRING) {\n        /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */\n        encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, RSTRING_PTR(enc));\n    } else {\n        enc = rb_funcall(enc, ID_to_s, 0, 0);\n        /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */\n        encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, RSTRING_PTR(enc));\n    }\n\n    /* to avoid a garbled error message dialog */\n    /* buf = ALLOC_N(char, (RSTRING(msg)->len)+1);*/\n    /* memcpy(buf, RSTRING(msg)->ptr, RSTRING(msg)->len);*/\n    /* buf[RSTRING(msg)->len] = 0; */\n    buf = ALLOC_N(char, RSTRING_LEN(msg)+1);\n    /* buf = ckalloc(sizeof(char)*((RSTRING_LEN(msg))+1)); */\n    memcpy(buf, RSTRING_PTR(msg), RSTRING_LEN(msg));\n    buf[RSTRING_LEN(msg)] = 0;\n\n    Tcl_DStringInit(&dstr);\n    Tcl_DStringFree(&dstr);\n    Tcl_ExternalToUtfDString(encoding, buf, RSTRING_LEN(msg), &dstr);\n\n    Tcl_AppendResult(interp, Tcl_DStringValue(&dstr), (char*)NULL);\n    DUMP2(\"error message:%s\", Tcl_DStringValue(&dstr));\n    Tcl_DStringFree(&dstr);\n    free(buf);\n    /* ckfree(buf); */\n\n#else /* TCL_VERSION <= 8.0 */\n    Tcl_AppendResult(interp, RSTRING_PTR(msg), (char*)NULL);\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n}\n\nstatic VALUE\nTkStringValue(obj)\n    VALUE obj;\n{\n    switch(TYPE(obj)) {\n    case T_STRING:\n        return obj;\n\n    case T_NIL:\n        return rb_str_new2(\"\");\n\n    case T_TRUE:\n        return rb_str_new2(\"1\");\n\n    case T_FALSE:\n        return rb_str_new2(\"0\");\n\n    case T_ARRAY:\n        return rb_funcall(obj, ID_join, 1, rb_str_new2(\" \"));\n\n    default:\n        if (rb_respond_to(obj, ID_to_s)) {\n            return rb_funcall(obj, ID_to_s, 0, 0);\n        }\n    }\n\n    return rb_funcall(obj, ID_inspect, 0, 0);\n}\n\nstatic int\ntcl_protect_core(interp, proc, data) /* should not raise exception */\n    Tcl_Interp *interp;\n    VALUE (*proc)();\n    VALUE data;\n{\n    volatile VALUE ret, exc = Qnil;\n    int status = 0;\n    int thr_crit_bup = rb_thread_critical;\n\n    Tcl_ResetResult(interp);\n\n    rb_thread_critical = Qfalse;\n    ret = rb_protect(proc, data, &status);\n    rb_thread_critical = Qtrue;\n    if (status) {\n        char *buf;\n        VALUE old_gc;\n        volatile VALUE type, str;\n\n        old_gc = rb_gc_disable();\n\n        switch(status) {\n        case TAG_RETURN:\n            type = eTkCallbackReturn;\n            goto error;\n        case TAG_BREAK:\n            type = eTkCallbackBreak;\n            goto error;\n        case TAG_NEXT:\n            type = eTkCallbackContinue;\n            goto error;\n        error:\n            str = rb_str_new2(\"LocalJumpError: \");\n#ifdef RUBY_VM\n            rb_str_append(str, rb_obj_as_string(rb_errinfo()));\n#else\n            rb_str_append(str, rb_obj_as_string(ruby_errinfo));\n#endif\n            exc = rb_exc_new3(type, str);\n            break;\n\n        case TAG_RETRY:\n#ifdef RUBY_VM\n            if (NIL_P(rb_errinfo())) {\n#else\n            if (NIL_P(ruby_errinfo)) {\n#endif\n                DUMP1(\"rb_protect: retry\");\n                exc = rb_exc_new2(eTkCallbackRetry, \"retry jump error\");\n            } else {\n#ifdef RUBY_VM\n                exc = rb_errinfo();\n#else\n                exc = ruby_errinfo;\n#endif\n            }\n            break;\n\n        case TAG_REDO:\n#ifdef RUBY_VM\n            if (NIL_P(rb_errinfo())) {\n#else\n            if (NIL_P(ruby_errinfo)) {\n#endif\n                DUMP1(\"rb_protect: redo\");\n                exc = rb_exc_new2(eTkCallbackRedo,  \"redo jump error\");\n            } else {\n#ifdef RUBY_VM\n                exc = rb_errinfo();\n#else\n                exc = ruby_errinfo;\n#endif\n            }\n            break;\n\n        case TAG_RAISE:\n#ifdef RUBY_VM\n            if (NIL_P(rb_errinfo())) {\n#else\n            if (NIL_P(ruby_errinfo)) {\n#endif\n                exc = rb_exc_new2(rb_eException, \"unknown exception\");\n            } else {\n#ifdef RUBY_VM\n                exc = rb_errinfo();\n#else\n                exc = ruby_errinfo;\n#endif\n            }\n            break;\n\n        case TAG_FATAL:\n#ifdef RUBY_VM\n            if (NIL_P(rb_errinfo())) {\n#else\n            if (NIL_P(ruby_errinfo)) {\n#endif\n                exc = rb_exc_new2(rb_eFatal, \"FATAL\");\n            } else {\n#ifdef RUBY_VM\n                exc = rb_errinfo();\n#else\n                exc = ruby_errinfo;\n#endif\n            }\n            break;\n\n        case TAG_THROW:\n#ifdef RUBY_VM\n            if (NIL_P(rb_errinfo())) {\n#else\n            if (NIL_P(ruby_errinfo)) {\n#endif\n                DUMP1(\"rb_protect: throw\");\n                exc = rb_exc_new2(eTkCallbackThrow,  \"throw jump error\");\n            } else {\n#ifdef RUBY_VM\n                exc = rb_errinfo();\n#else\n                exc = ruby_errinfo;\n#endif\n            }\n            break;\n\n        default:\n            buf = ALLOC_N(char, 256);\n            /* buf = ckalloc(sizeof(char) * 256); */\n            sprintf(buf, \"unknown loncaljmp status %d\", status);\n            exc = rb_exc_new2(rb_eException, buf);\n            free(buf);\n            /* ckfree(buf); */\n            break;\n        }\n\n        if (old_gc == Qfalse) rb_gc_enable();\n\n        ret = Qnil;\n    }\n\n    rb_thread_critical = thr_crit_bup;\n\n    Tcl_ResetResult(interp);\n\n    /* status check */\n    if (!NIL_P(exc)) {\n        volatile VALUE eclass = rb_obj_class(exc);\n        volatile VALUE backtrace;\n\n        DUMP1(\"(failed)\");\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        DUMP1(\"set backtrace\");\n        if (!NIL_P(backtrace = rb_funcall(exc, ID_backtrace, 0, 0))) {\n            backtrace = rb_ary_join(backtrace, rb_str_new2(\"\\n\"));\n            Tcl_AddErrorInfo(interp, StringValuePtr(backtrace));\n        }\n\n        rb_thread_critical = thr_crit_bup;\n\n        ip_set_exc_message(interp, exc);\n\n        if (eclass == eTkCallbackReturn)\n            return TCL_RETURN;\n\n        if (eclass == eTkCallbackBreak)\n            return TCL_BREAK;\n\n        if (eclass == eTkCallbackContinue)\n            return TCL_CONTINUE;\n\n        if (eclass == rb_eSystemExit || eclass == rb_eInterrupt) {\n            rbtk_pending_exception = exc;\n            return TCL_RETURN;\n        }\n\n        if (rb_obj_is_kind_of(exc, eTkLocalJumpError)) {\n            rbtk_pending_exception = exc;\n            return TCL_ERROR;\n        }\n\n        if (rb_obj_is_kind_of(exc, eLocalJumpError)) {\n            VALUE reason = rb_ivar_get(exc, ID_at_reason);\n\n            if (TYPE(reason) == T_SYMBOL) {\n                if (SYM2ID(reason) == ID_return)\n                    return TCL_RETURN;\n\n                if (SYM2ID(reason) == ID_break)\n                    return TCL_BREAK;\n\n                if (SYM2ID(reason) == ID_next)\n                    return TCL_CONTINUE;\n            }\n        }\n\n        return TCL_ERROR;\n    }\n\n    /* result must be string or nil */\n    if (!NIL_P(ret)) {\n        /* copy result to the tcl interpreter */\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        ret = TkStringValue(ret);\n        DUMP1(\"Tcl_AppendResult\");\n        Tcl_AppendResult(interp, RSTRING_PTR(ret), (char *)NULL);\n\n        rb_thread_critical = thr_crit_bup;\n    }\n\n    DUMP2(\"(result) %s\", NIL_P(ret) ? \"nil\" : RSTRING_PTR(ret));\n\n    return TCL_OK;\n}\n\nstatic int\ntcl_protect(interp, proc, data)\n    Tcl_Interp *interp;\n    VALUE (*proc)();\n    VALUE data;\n{\n    int old_trapflag = rb_trap_immediate;\n    int code;\n\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n        rb_bug(\"cross-thread violation on tcl_protect()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on tcl_protect()\");\n    }\n#endif\n#endif\n\n    rb_trap_immediate = 0;\n    code = tcl_protect_core(interp, proc, data);\n    rb_trap_immediate = old_trapflag;\n\n    return code;\n}\n\nstatic int\n#if TCL_MAJOR_VERSION >= 8\nip_ruby_eval(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int argc;\n    Tcl_Obj *CONST argv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nip_ruby_eval(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int argc;\n    char *argv[];\n#endif\n{\n    char *arg;\n    int thr_crit_bup;\n    int code;\n\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n\n    /* ruby command has 1 arg. */\n    if (argc != 2) {\n#if 0\n        rb_raise(rb_eArgError, \n                 \"wrong number of arguments (%d for 1)\", argc - 1);\n#else\n        char buf[sizeof(int)*8 + 1];\n        Tcl_ResetResult(interp);\n        sprintf(buf, \"%d\", argc-1);\n        Tcl_AppendResult(interp, \"wrong number of arguments (\", \n                         buf, \" for 1)\", (char *)NULL);\n        rbtk_pending_exception = rb_exc_new2(rb_eArgError, \n                                             Tcl_GetStringResult(interp));\n        return TCL_ERROR;\n#endif\n    }\n\n    /* get C string from Tcl object */\n#if TCL_MAJOR_VERSION >= 8\n    {\n      char *str;\n      int  len;\n\n      thr_crit_bup = rb_thread_critical;\n      rb_thread_critical = Qtrue;\n\n      str = Tcl_GetStringFromObj(argv[1], &len);\n      arg = ALLOC_N(char, len + 1);\n      /* arg = ckalloc(sizeof(char) * (len + 1)); */\n      memcpy(arg, str, len);\n      arg[len] = 0;\n\n      rb_thread_critical = thr_crit_bup;\n\n    }\n#else /* TCL_MAJOR_VERSION < 8 */\n    arg = argv[1];\n#endif\n\n    /* evaluate the argument string by ruby */\n    DUMP2(\"rb_eval_string(%s)\", arg);\n\n    code = tcl_protect(interp, rb_eval_string, (VALUE)arg);\n\n#if TCL_MAJOR_VERSION >= 8\n    free(arg);\n    /* ckfree(arg); */\n#endif\n\n    return code;\n}\n\n\n/* Tcl command `ruby_cmd' */\nstatic VALUE\nip_ruby_cmd_core(arg)\n    struct cmd_body_arg *arg;\n{\n    volatile VALUE ret;\n    int thr_crit_bup;\n\n    DUMP1(\"call ip_ruby_cmd_core\");\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qfalse;\n    ret = rb_apply(arg->receiver, arg->method, arg->args);\n    rb_thread_critical = thr_crit_bup;\n    DUMP1(\"finish ip_ruby_cmd_core\");\n\n    return ret;\n}\n\n#define SUPPORT_NESTED_CONST_AS_IP_RUBY_CMD_RECEIVER 1\n\nstatic VALUE\nip_ruby_cmd_receiver_const_get(name)\n     char *name;\n{\n  volatile VALUE klass = rb_cObject;\n  char *head, *tail;\n  int state;\n\n#if SUPPORT_NESTED_CONST_AS_IP_RUBY_CMD_RECEIVER\n  klass = rb_eval_string_protect(name, &state);\n  if (state) {\n    return Qnil;\n  } else {\n    return klass;\n  }\n#else\n  return rb_const_get(klass, rb_intern(name));\n#endif\n\n  /* TODO!!!!!! */\n  /* support nest of classes/modules */\n\n  /* return rb_eval_string(name); */\n  /* return rb_eval_string_protect(name, &state); */\n\n#if 0 /* doesn't work!! (fail to autoload?) */\n  /* duplicate */\n  head = name = strdup(name);\n\n  /* has '::' at head ? */\n  if (*head == ':')  head += 2;\n  tail = head; \n\n  /* search */\n  while(*tail) {\n    if (*tail == ':') {\n      *tail = '\\0';\n      klass = rb_const_get(klass, rb_intern(head));\n      tail += 2;\n      head = tail;\n    } else {\n      tail++;\n    }\n  }\n\n  free(name);\n  return rb_const_get(klass, rb_intern(head));\n#endif\n}\n\nstatic VALUE\nip_ruby_cmd_receiver_get(str)\n     char *str;\n{\n  volatile VALUE receiver;\n  volatile VALUE klass = rb_cObject;\n  int state;\n\n  if (str[0] == ':' || ('A' <= str[0] && str[0] <= 'Z')) {\n    /* class | module | constant */\n#if SUPPORT_NESTED_CONST_AS_IP_RUBY_CMD_RECEIVER\n    receiver = ip_ruby_cmd_receiver_const_get(str);\n#else\n    receiver = rb_protect(ip_ruby_cmd_receiver_const_get, (VALUE)str, &state);\n    if (state) return Qnil;\n#endif\n  } else if (str[0] == '$') {\n    /* global variable */\n    receiver = rb_gv_get(str);\n  } else {\n    /* global variable omitted '$' */\n    char *buf;\n    int len;\n\n    len = strlen(str);\n    buf = ALLOC_N(char, len + 2);\n    /* buf = ckalloc(sizeof(char) * (len + 2)); */\n    buf[0] = '$';\n    memcpy(buf + 1, str, len);\n    buf[len + 1] = 0;\n    receiver = rb_gv_get(buf);\n    free(buf);\n    /* ckfree(buf); */\n  }\n\n  return receiver;\n}\n\n/* ruby_cmd receiver method arg ... */\nstatic int\n#if TCL_MAJOR_VERSION >= 8\nip_ruby_cmd(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int argc;\n    Tcl_Obj *CONST argv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nip_ruby_cmd(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int argc;\n    char *argv[];\n#endif\n{\n    volatile VALUE receiver;\n    volatile ID method;\n    volatile VALUE args;\n    char *str;\n    int i;\n    int  len;\n    struct cmd_body_arg *arg;\n    int thr_crit_bup;\n    VALUE old_gc;\n    int code;\n\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n\n    if (argc < 3) {\n#if 0\n        rb_raise(rb_eArgError, \"too few arguments\");\n#else\n        Tcl_ResetResult(interp);\n        Tcl_AppendResult(interp, \"too few arguments\", (char *)NULL);\n        rbtk_pending_exception = rb_exc_new2(rb_eArgError, \n                                             Tcl_GetStringResult(interp));\n        return TCL_ERROR;\n#endif\n    }\n\n    /* get arguments from Tcl objects */\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n    old_gc = rb_gc_disable();\n\n    /* get receiver */\n#if TCL_MAJOR_VERSION >= 8\n    str = Tcl_GetStringFromObj(argv[1], &len);\n#else /* TCL_MAJOR_VERSION < 8 */\n    str = argv[1];\n#endif\n    DUMP2(\"receiver:%s\",str);\n    /* receiver = rb_protect(ip_ruby_cmd_receiver_get, (VALUE)str, &code); */\n    receiver = ip_ruby_cmd_receiver_get(str);\n    if (NIL_P(receiver)) {\n#if 0\n        rb_raise(rb_eArgError, \n                 \"unknown class/module/global-variable '%s'\", str);\n#else\n        Tcl_ResetResult(interp);\n        Tcl_AppendResult(interp, \"unknown class/module/global-variable '\", \n                         str, \"'\", (char *)NULL);\n        rbtk_pending_exception = rb_exc_new2(rb_eArgError, \n                                             Tcl_GetStringResult(interp));\n        if (old_gc == Qfalse) rb_gc_enable();\n        return TCL_ERROR;\n#endif\n    }\n\n    /* get metrhod */\n#if TCL_MAJOR_VERSION >= 8\n    str = Tcl_GetStringFromObj(argv[2], &len);\n#else /* TCL_MAJOR_VERSION < 8 */\n    str = argv[2];\n#endif\n    method = rb_intern(str);\n\n    /* get args */\n    args = rb_ary_new2(argc - 2);\n#ifdef RUBY_VM\n#else\n    RARRAY(args)->len = 0;\n#endif\n    for(i = 3; i < argc; i++) {\n#if TCL_MAJOR_VERSION >= 8\n        str = Tcl_GetStringFromObj(argv[i], &len);\n        DUMP2(\"arg:%s\",str);\n#ifdef RUBY_VM\n\trb_ary_push(args, rb_tainted_str_new(str, len));\n#else\n        RARRAY(args)->ptr[RARRAY(args)->len++] = rb_tainted_str_new(str, len);\n#endif\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP2(\"arg:%s\",argv[i]);\n#ifdef RUBY_VM\n\trb_ary_push(args, rb_tainted_str_new2(argv[i]));\n#else\n        RARRAY(args)->ptr[RARRAY(args)->len++] = rb_tainted_str_new2(argv[i]);\n#endif\n#endif\n    }\n\n    if (old_gc == Qfalse) rb_gc_enable();\n    rb_thread_critical = thr_crit_bup;\n\n    /* allocate */\n    arg = ALLOC(struct cmd_body_arg);\n    /* arg = (struct cmd_body_arg *)ckalloc(sizeof(struct cmd_body_arg)); */\n\n    arg->receiver = receiver;\n    arg->method = method;\n    arg->args = args;\n\n    /* evaluate the argument string by ruby */\n    code = tcl_protect(interp, ip_ruby_cmd_core, (VALUE)arg);\n\n    free(arg);\n    /* ckfree((char*)arg); */\n\n    return code;\n}\n\n\n/*****************************/\n/* relpace of 'exit' command */\n/*****************************/\nstatic int\n#if TCL_MAJOR_VERSION >= 8\nip_InterpExitObjCmd(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int argc;\n    Tcl_Obj *CONST argv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nip_InterpExitCommand(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int argc;\n    char *argv[];\n#endif\n{\n    DUMP1(\"start ip_InterpExitCommand\");\n    if (interp != (Tcl_Interp*)NULL \n        && !Tcl_InterpDeleted(interp)\n#if TCL_NAMESPACE_DEBUG\n        && !ip_null_namespace(interp)\n#endif\n        ) {\n        Tcl_ResetResult(interp);\n        /* Tcl_Preserve(interp); */\n        /* Tcl_Eval(interp, \"interp eval {} {destroy .}; interp delete {}\"); */\n        ip_finalize(interp);\n        Tcl_DeleteInterp(interp);\n        Tcl_Release(interp);\n    }\n    return TCL_OK;\n}\n\nstatic int\n#if TCL_MAJOR_VERSION >= 8\nip_RubyExitObjCmd(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int argc;\n    Tcl_Obj *CONST argv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nip_RubyExitCommand(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int argc;\n    char *argv[];\n#endif\n{\n    int state;\n    char *cmd, *param;\n#if TCL_MAJOR_VERSION < 8\n    char *endptr;\n    cmd = argv[0];\n#endif\n\n    DUMP1(\"start ip_RubyExitCommand\");\n\n#if TCL_MAJOR_VERSION >= 8\n    /* cmd = Tcl_GetString(argv[0]); */\n    cmd = Tcl_GetStringFromObj(argv[0], (int*)NULL);\n#endif\n\n    if (argc < 1 || argc > 2) {\n        /* arguemnt error */\n        Tcl_AppendResult(interp, \n                         \"wrong number of arguments: should be \\\"\", \n                         cmd, \" ?returnCode?\\\"\", (char *)NULL);\n        return TCL_ERROR;\n    }\n\n    if (interp == (Tcl_Interp*)NULL) return TCL_OK;\n\n    Tcl_ResetResult(interp);\n\n    if (rb_safe_level() >= 4 || Tcl_IsSafe(interp)) {\n        ip_finalize(interp);\n        Tcl_DeleteInterp(interp);\n        Tcl_Release(interp);\n        return TCL_OK;\n    }\n\n    switch(argc) {\n    case 1:\n        /* rb_exit(0); */ /* not return if succeed */\n        Tcl_AppendResult(interp, \n                         \"fail to call \\\"\", cmd, \"\\\"\", (char *)NULL);\n\n        rbtk_pending_exception = rb_exc_new2(rb_eSystemExit, \n                                             Tcl_GetStringResult(interp));\n        rb_iv_set(rbtk_pending_exception, \"status\", INT2FIX(0));\n\n        return TCL_RETURN;\n\n    case 2:\n#if TCL_MAJOR_VERSION >= 8\n        if (Tcl_GetIntFromObj(interp, argv[1], &state) == TCL_ERROR) {\n            return TCL_ERROR;\n        }\n        /* param = Tcl_GetString(argv[1]); */\n        param = Tcl_GetStringFromObj(argv[1], (int*)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n        state = (int)strtol(argv[1], &endptr, 0);\n        if (*endptr) {\n            Tcl_AppendResult(interp, \n                             \"expected integer but got \\\"\", \n                             argv[1], \"\\\"\", (char *)NULL);\n            return TCL_ERROR;\n        }\n        param = argv[1];\n#endif\n        /* rb_exit(state); */ /* not return if succeed */\n\n        Tcl_AppendResult(interp, \"fail to call \\\"\", cmd, \" \", \n                         param, \"\\\"\", (char *)NULL);\n\n        rbtk_pending_exception = rb_exc_new2(rb_eSystemExit, \n                                             Tcl_GetStringResult(interp));\n        rb_iv_set(rbtk_pending_exception, \"status\", INT2FIX(state));\n\n        return TCL_RETURN;\n\n    default:\n        /* arguemnt error */\n        Tcl_AppendResult(interp, \n                         \"wrong number of arguments: should be \\\"\", \n                         cmd, \" ?returnCode?\\\"\", (char *)NULL);\n        return TCL_ERROR;\n    }\n}\n\n\n/**************************/\n/*  based on tclEvent.c   */\n/**************************/\n\n/*********************/\n/* replace of update */\n/*********************/\n#if TCL_MAJOR_VERSION >= 8\nstatic int ip_rbUpdateObjCmd _((ClientData, Tcl_Interp *, int,\n                               Tcl_Obj *CONST []));\nstatic int\nip_rbUpdateObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int ip_rbUpdateCommand _((ClientData, Tcl_Interp *, int, char *[]));\nstatic int\nip_rbUpdateCommand(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int objc;\n    char *objv[];\n#endif\n{\n    int  optionIndex;\n    int  ret;\n    int  flags = 0;\n    static CONST char *updateOptions[] = {\"idletasks\", (char *) NULL};\n    enum updateOptions {REGEXP_IDLETASKS};\n\n    DUMP1(\"Ruby's 'update' is called\");\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n        rb_bug(\"cross-thread violation on ip_ruby_eval()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on ip_ruby_eval()\");\n    }\n#endif\n#endif\n\n    Tcl_ResetResult(interp);\n\n    if (objc == 1) {\n        flags = TCL_DONT_WAIT;\n\n    } else if (objc == 2) {\n#if TCL_MAJOR_VERSION >= 8\n        if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)updateOptions,\n                \"option\", 0, &optionIndex) != TCL_OK) {\n            return TCL_ERROR;\n        }\n        switch ((enum updateOptions) optionIndex) {\n            case REGEXP_IDLETASKS: {\n                flags = TCL_IDLE_EVENTS;\n                break;\n            }\n            default: {\n                rb_bug(\"ip_rbUpdateObjCmd: bad option index to UpdateOptions\");\n            }\n        }\n#else\n        if (strncmp(objv[1], \"idletasks\", strlen(objv[1])) != 0) {\n            Tcl_AppendResult(interp, \"bad option \\\"\", objv[1],\n                    \"\\\": must be idletasks\", (char *) NULL);\n            return TCL_ERROR;\n        }\n        flags = TCL_IDLE_EVENTS;\n#endif\n    } else {\n#ifdef Tcl_WrongNumArgs\n        Tcl_WrongNumArgs(interp, 1, objv, \"[ idletasks ]\");\n#else\n# if TCL_MAJOR_VERSION >= 8\n        int  dummy;\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         Tcl_GetStringFromObj(objv[0], &dummy), \n                         \" [ idletasks ]\\\"\", \n                         (char *) NULL);\n# else /* TCL_MAJOR_VERSION < 8 */\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         objv[0], \" [ idletasks ]\\\"\", (char *) NULL);\n# endif\n#endif\n        return TCL_ERROR;\n    }\n\n    Tcl_Preserve(interp);\n\n    /* call eventloop */\n    /* ret = lib_eventloop_core(0, flags, (int *)NULL);*/ /* ignore result */\n    ret = RTEST(lib_eventloop_launcher(0, flags, (int *)NULL, interp)); /* ignore result */\n\n    /* exception check */\n    if (!NIL_P(rbtk_pending_exception)) {\n        Tcl_Release(interp);\n\n        /*\n        if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)) {\n        */\n        if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)\n            || rb_obj_is_kind_of(rbtk_pending_exception, rb_eInterrupt)) {\n            return TCL_RETURN;\n        } else{\n            return TCL_ERROR;\n        }\n    }\n\n    /* trap check */\n    if (rb_trap_pending) {\n        Tcl_Release(interp);\n\n        return TCL_RETURN;\n    }\n\n    /*\n     * Must clear the interpreter's result because event handlers could\n     * have executed commands.\n     */\n\n    DUMP2(\"last result '%s'\", Tcl_GetStringResult(interp));\n    Tcl_ResetResult(interp);\n    Tcl_Release(interp);\n\n    DUMP1(\"finish Ruby's 'update'\");\n    return TCL_OK;\n}\n\n\n/**********************/\n/* update with thread */\n/**********************/\nstruct th_update_param {\n    VALUE thread;\n    int   done;\n};\n\nstatic void rb_threadUpdateProc _((ClientData));\nstatic void \nrb_threadUpdateProc(clientData)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n{\n    struct th_update_param *param = (struct th_update_param *) clientData;\n\n    DUMP1(\"threadUpdateProc is called\");\n    param->done = 1;\n    rb_thread_wakeup(param->thread);\n\n    return;\n}\n\n#if TCL_MAJOR_VERSION >= 8\nstatic int ip_rb_threadUpdateObjCmd _((ClientData, Tcl_Interp *, int,\n                                       Tcl_Obj *CONST []));\nstatic int\nip_rb_threadUpdateObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int ip_rb_threadUpdateCommand _((ClientData, Tcl_Interp *, int,\n                                       char *[]));\nstatic int\nip_rb_threadUpdateCommand(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int objc;\n    char *objv[];\n#endif\n{\n    int  optionIndex;\n    int  flags = 0;\n    struct th_update_param *param;\n    static CONST char *updateOptions[] = {\"idletasks\", (char *) NULL};\n    enum updateOptions {REGEXP_IDLETASKS};\n    volatile VALUE current_thread = rb_thread_current();\n\n    DUMP1(\"Ruby's 'thread_update' is called\");\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n        rb_bug(\"cross-thread violation on ip_rb_threadUpdateCommand()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on ip_rb_threadUpdateCommand()\");\n    }\n#endif\n#endif\n\n    if (rb_thread_alone() \n        || NIL_P(eventloop_thread) || eventloop_thread == current_thread) {\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"call ip_rbUpdateObjCmd\");\n        return ip_rbUpdateObjCmd(clientData, interp, objc, objv);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"call ip_rbUpdateCommand\");\n        return ip_rbUpdateCommand(clientData, interp, objc, objv);\n#endif\n    }\n\n    DUMP1(\"start Ruby's 'thread_update' body\");\n\n    Tcl_ResetResult(interp);\n\n    if (objc == 1) {\n        flags = TCL_DONT_WAIT;\n\n    } else if (objc == 2) {\n#if TCL_MAJOR_VERSION >= 8\n        if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)updateOptions,\n                \"option\", 0, &optionIndex) != TCL_OK) {\n            return TCL_ERROR;\n        }\n        switch ((enum updateOptions) optionIndex) {\n            case REGEXP_IDLETASKS: {\n                flags = TCL_IDLE_EVENTS;\n                break;\n            }\n            default: {\n                rb_bug(\"ip_rb_threadUpdateObjCmd: bad option index to UpdateOptions\");\n            }\n        }\n#else\n        if (strncmp(objv[1], \"idletasks\", strlen(objv[1])) != 0) {\n            Tcl_AppendResult(interp, \"bad option \\\"\", objv[1],\n                    \"\\\": must be idletasks\", (char *) NULL);\n            return TCL_ERROR;\n        }\n        flags = TCL_IDLE_EVENTS;\n#endif\n    } else {\n#ifdef Tcl_WrongNumArgs\n        Tcl_WrongNumArgs(interp, 1, objv, \"[ idletasks ]\");\n#else\n# if TCL_MAJOR_VERSION >= 8\n        int  dummy;\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         Tcl_GetStringFromObj(objv[0], &dummy), \n                         \" [ idletasks ]\\\"\", \n                         (char *) NULL);\n# else /* TCL_MAJOR_VERSION < 8 */\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         objv[0], \" [ idletasks ]\\\"\", (char *) NULL);\n# endif\n#endif\n        return TCL_ERROR;\n    }\n\n    DUMP1(\"pass argument check\");\n\n    /* param = (struct th_update_param *)Tcl_Alloc(sizeof(struct th_update_param)); */\n    param = (struct th_update_param *)ckalloc(sizeof(struct th_update_param));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)param);\n#endif\n    param->thread = current_thread;\n    param->done = 0;\n\n    DUMP1(\"set idle proc\");\n    Tcl_DoWhenIdle(rb_threadUpdateProc, (ClientData) param);\n\n    while(!param->done) {\n        DUMP1(\"wait for complete idle proc\");\n        /* rb_thread_stop(); */\n        rb_thread_sleep_forever();\n    }\n\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)param);\n#else\n    /* Tcl_Free((char *)param); */\n    ckfree((char *)param);\n#endif\n#endif\n\n    DUMP1(\"finish Ruby's 'thread_update'\");\n    return TCL_OK;\n}\n\n\n/***************************/\n/* replace of vwait/tkwait */\n/***************************/\n#if TCL_MAJOR_VERSION >= 8\nstatic int ip_rbVwaitObjCmd _((ClientData, Tcl_Interp *, int,\n                               Tcl_Obj *CONST []));\nstatic int ip_rb_threadVwaitObjCmd _((ClientData, Tcl_Interp *, int,\n                                      Tcl_Obj *CONST []));\nstatic int ip_rbTkWaitObjCmd _((ClientData, Tcl_Interp *, int,\n                                Tcl_Obj *CONST []));\nstatic int ip_rb_threadTkWaitObjCmd _((ClientData, Tcl_Interp *, int,\n                                       Tcl_Obj *CONST []));\n#else\nstatic int ip_rbVwaitCommand _((ClientData, Tcl_Interp *, int, char *[]));\nstatic int ip_rb_threadVwaitCommand _((ClientData, Tcl_Interp *, int,\n                                       char *[]));\nstatic int ip_rbTkWaitCommand _((ClientData, Tcl_Interp *, int, char *[]));\nstatic int ip_rb_threadTkWaitCommand _((ClientData, Tcl_Interp *, int,\n                                        char *[]));\n#endif\n\n#if TCL_MAJOR_VERSION >= 8\nstatic char *VwaitVarProc _((ClientData, Tcl_Interp *, \n                             CONST84 char *,CONST84 char *, int));\nstatic char *\nVwaitVarProc(clientData, interp, name1, name2, flags)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    Tcl_Interp *interp;         /* Interpreter containing variable. */\n    CONST84 char *name1;        /* Name of variable. */\n    CONST84 char *name2;        /* Second part of variable name. */\n    int flags;                  /* Information about what happened. */\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic char *VwaitVarProc _((ClientData, Tcl_Interp *, char *, char *, int));\nstatic char *\nVwaitVarProc(clientData, interp, name1, name2, flags)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    Tcl_Interp *interp;         /* Interpreter containing variable. */\n    char *name1;                /* Name of variable. */\n    char *name2;                /* Second part of variable name. */\n    int flags;                  /* Information about what happened. */\n#endif\n{\n    int *donePtr = (int *) clientData;\n\n    *donePtr = 1;\n    return (char *) NULL;\n}\n\n#if TCL_MAJOR_VERSION >= 8\nstatic int\nip_rbVwaitObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int\nip_rbVwaitCommand(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int objc;\n    char *objv[];\n#endif\n{\n    int  ret, done, foundEvent;\n    char *nameString;\n    int  dummy;\n    int thr_crit_bup;\n\n    DUMP1(\"Ruby's 'vwait' is called\");\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n\n#if 0\n    if (!rb_thread_alone() \n\t&& eventloop_thread != Qnil\n\t&& eventloop_thread != rb_thread_current()) {\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"call ip_rb_threadVwaitObjCmd\");\n        return ip_rb_threadVwaitObjCmd(clientData, interp, objc, objv);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"call ip_rb_threadVwaitCommand\");\n        return ip_rb_threadVwaitCommand(clientData, interp, objc, objv);\n#endif\n    }\n#endif\n\n    Tcl_Preserve(interp);\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n        rb_bug(\"cross-thread violation on ip_rbVwaitCommand()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on ip_rbVwaitCommand()\");\n    }\n#endif\n#endif\n\n    Tcl_ResetResult(interp);\n\n    if (objc != 2) {\n#ifdef Tcl_WrongNumArgs\n        Tcl_WrongNumArgs(interp, 1, objv, \"name\");\n#else\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n        /* nameString = Tcl_GetString(objv[0]); */\n        nameString = Tcl_GetStringFromObj(objv[0], &dummy);\n#else /* TCL_MAJOR_VERSION < 8 */\n        nameString = objv[0];\n#endif\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         nameString, \" name\\\"\", (char *) NULL);\n\n        rb_thread_critical = thr_crit_bup;\n#endif\n\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_IncrRefCount(objv[1]);\n    /* nameString = Tcl_GetString(objv[1]); */\n    nameString = Tcl_GetStringFromObj(objv[1], &dummy);\n#else /* TCL_MAJOR_VERSION < 8 */\n    nameString = objv[1];\n#endif\n\n    /* \n    if (Tcl_TraceVar(interp, nameString,\n                     TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                     VwaitVarProc, (ClientData) &done) != TCL_OK) {\n        return TCL_ERROR;\n    }\n    */\n    ret = Tcl_TraceVar(interp, nameString,\n                       TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                       VwaitVarProc, (ClientData) &done);\n\n    rb_thread_critical = thr_crit_bup;\n\n    if (ret != TCL_OK) {\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[1]);\n#endif\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n    done = 0;\n\n    foundEvent = RTEST(lib_eventloop_launcher(/* not check root-widget */0, \n                                              0, &done, interp));\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    Tcl_UntraceVar(interp, nameString,\n                   TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                   VwaitVarProc, (ClientData) &done);\n\n    rb_thread_critical = thr_crit_bup;\n\n    /* exception check */\n    if (!NIL_P(rbtk_pending_exception)) {\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[1]);\n#endif\n        Tcl_Release(interp);\n\n/*\n        if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)) {\n*/\n        if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)\n            || rb_obj_is_kind_of(rbtk_pending_exception, rb_eInterrupt)) {\n            return TCL_RETURN;\n        } else{\n            return TCL_ERROR;\n        }\n    }\n\n    /* trap check */\n    if (rb_trap_pending) {\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[1]);\n#endif\n        Tcl_Release(interp);\n\n        return TCL_RETURN;\n    }\n\n    /*\n     * Clear out the interpreter's result, since it may have been set\n     * by event handlers.\n     */\n\n    Tcl_ResetResult(interp);\n    if (!foundEvent) {\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        Tcl_AppendResult(interp, \"can't wait for variable \\\"\", nameString,\n                         \"\\\":  would wait forever\", (char *) NULL);\n\n        rb_thread_critical = thr_crit_bup;\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[1]);\n#endif\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_DecrRefCount(objv[1]);\n#endif\n    Tcl_Release(interp);\n    return TCL_OK;\n}\n\n\n/**************************/\n/*  based on tkCmd.c      */\n/**************************/\n#if TCL_MAJOR_VERSION >= 8\nstatic char *WaitVariableProc _((ClientData, Tcl_Interp *, \n                                 CONST84 char *,CONST84 char *, int));\nstatic char *\nWaitVariableProc(clientData, interp, name1, name2, flags)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    Tcl_Interp *interp;         /* Interpreter containing variable. */\n    CONST84 char *name1;        /* Name of variable. */\n    CONST84 char *name2;        /* Second part of variable name. */\n    int flags;                  /* Information about what happened. */\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic char *WaitVariableProc _((ClientData, Tcl_Interp *, \n                                 char *, char *, int));\nstatic char *\nWaitVariableProc(clientData, interp, name1, name2, flags)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    Tcl_Interp *interp;         /* Interpreter containing variable. */\n    char *name1;                /* Name of variable. */\n    char *name2;                /* Second part of variable name. */\n    int flags;                  /* Information about what happened. */\n#endif\n{\n    int *donePtr = (int *) clientData;\n\n    *donePtr = 1;\n    return (char *) NULL;\n}\n\nstatic void WaitVisibilityProc _((ClientData, XEvent *));\nstatic void\nWaitVisibilityProc(clientData, eventPtr)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    XEvent *eventPtr;           /* Information about event (not used). */\n{\n    int *donePtr = (int *) clientData;\n\n    if (eventPtr->type == VisibilityNotify) {\n        *donePtr = 1;\n    }\n    if (eventPtr->type == DestroyNotify) {\n        *donePtr = 2;\n    }\n}\n\nstatic void WaitWindowProc _((ClientData, XEvent *));\nstatic void\nWaitWindowProc(clientData, eventPtr)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    XEvent *eventPtr;           /* Information about event. */\n{\n    int *donePtr = (int *) clientData;\n\n    if (eventPtr->type == DestroyNotify) {\n        *donePtr = 1;\n    }\n}\n\n#if TCL_MAJOR_VERSION >= 8\nstatic int\nip_rbTkWaitObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int\nip_rbTkWaitCommand(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int objc;\n    char *objv[];\n#endif\n{\n    Tk_Window tkwin = (Tk_Window) clientData;\n    Tk_Window window;\n    int done, index;\n    static CONST char *optionStrings[] = { \"variable\", \"visibility\", \"window\",\n                                           (char *) NULL };\n    enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW };\n    char *nameString;\n    int ret, dummy;\n    int thr_crit_bup;\n\n    DUMP1(\"Ruby's 'tkwait' is called\");\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n\n#if 0\n    if (!rb_thread_alone() \n\t&& eventloop_thread != Qnil\n\t&& eventloop_thread != rb_thread_current()) {\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"call ip_rb_threadTkWaitObjCmd\");\n        return ip_rb_threadTkWaitObjCmd(clientData, interp, objc, objv);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"call ip_rb_threadTkWaitCommand\");\n        return ip_rb_threadTkWwaitCommand(clientData, interp, objc, objv);\n#endif\n    }\n#endif\n\n    Tcl_Preserve(interp);\n    Tcl_ResetResult(interp);\n\n    if (objc != 3) {\n#ifdef Tcl_WrongNumArgs\n        Tcl_WrongNumArgs(interp, 1, objv, \"variable|visibility|window name\");\n#else\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         Tcl_GetStringFromObj(objv[0], &dummy), \n                         \" variable|visibility|window name\\\"\", \n                         (char *) NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         objv[0], \" variable|visibility|window name\\\"\", \n                         (char *) NULL);\n#endif\n\n        rb_thread_critical = thr_crit_bup;\n#endif\n\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n#if TCL_MAJOR_VERSION >= 8\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /*\n    if (Tcl_GetIndexFromObj(interp, objv[1], \n                            (CONST84 char **)optionStrings, \n                            \"option\", 0, &index) != TCL_OK) {\n        return TCL_ERROR;\n    }\n    */\n    ret = Tcl_GetIndexFromObj(interp, objv[1], \n                              (CONST84 char **)optionStrings, \n                              \"option\", 0, &index);\n\n    rb_thread_critical = thr_crit_bup;\n\n    if (ret != TCL_OK) {\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n#else /* TCL_MAJOR_VERSION < 8 */\n    {\n        int c = objv[1][0];\n        size_t length = strlen(objv[1]);\n\n        if ((c == 'v') && (strncmp(objv[1], \"variable\", length) == 0)\n            && (length >= 2)) {\n            index = TKWAIT_VARIABLE;\n        } else if ((c == 'v') && (strncmp(objv[1], \"visibility\", length) == 0)\n                   && (length >= 2)) {\n            index = TKWAIT_VISIBILITY;\n        } else if ((c == 'w') && (strncmp(objv[1], \"window\", length) == 0)) {\n            index = TKWAIT_WINDOW;\n        } else {\n            Tcl_AppendResult(interp, \"bad option \\\"\", objv[1],\n                             \"\\\": must be variable, visibility, or window\", \n                             (char *) NULL);\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n    }\n#endif\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_IncrRefCount(objv[2]);\n    /* nameString = Tcl_GetString(objv[2]); */\n    nameString = Tcl_GetStringFromObj(objv[2], &dummy);\n#else /* TCL_MAJOR_VERSION < 8 */\n    nameString = objv[2];\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n\n    switch ((enum options) index) {\n    case TKWAIT_VARIABLE:\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n        /*\n        if (Tcl_TraceVar(interp, nameString,\n                         TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                         WaitVariableProc, (ClientData) &done) != TCL_OK) {\n            return TCL_ERROR;\n        }\n        */\n        ret = Tcl_TraceVar(interp, nameString,\n                           TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                           WaitVariableProc, (ClientData) &done);\n\n        rb_thread_critical = thr_crit_bup;\n\n        if (ret != TCL_OK) {\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        done = 0;\n        /* lib_eventloop_core(check_rootwidget_flag, 0, &done); */\n        lib_eventloop_launcher(check_rootwidget_flag, 0, &done, interp);\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        Tcl_UntraceVar(interp, nameString,\n                       TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                       WaitVariableProc, (ClientData) &done);\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[2]);\n#endif\n\n        rb_thread_critical = thr_crit_bup;\n\n        /* exception check */\n        if (!NIL_P(rbtk_pending_exception)) {\n            Tcl_Release(interp);\n\n            /*\n            if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)) {\n            */\n            if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)\n                || rb_obj_is_kind_of(rbtk_pending_exception, rb_eInterrupt)) {\n                return TCL_RETURN;\n            } else{\n                return TCL_ERROR;\n            }\n        }\n\n        /* trap check */\n        if (rb_trap_pending) {\n            Tcl_Release(interp);\n\n            return TCL_RETURN;\n        }\n\n        break;\n\n    case TKWAIT_VISIBILITY:\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n\t/* This function works on the Tk eventloop thread only. */\n        if (!tk_stubs_init_p() || Tk_MainWindow(interp) == (Tk_Window)NULL) {\n            window = NULL;\n        } else {\n            window = Tk_NameToWindow(interp, nameString, tkwin);\n        }\n\n        if (window == NULL) {\n            Tcl_AppendResult(interp, \": tkwait: \", \n                             \"no main-window (not Tk application?)\", \n                             (char*)NULL);\n            rb_thread_critical = thr_crit_bup;\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        Tk_CreateEventHandler(window,\n                              VisibilityChangeMask|StructureNotifyMask,\n                              WaitVisibilityProc, (ClientData) &done);\n\n        rb_thread_critical = thr_crit_bup;\n\n        done = 0;\n        /* lib_eventloop_core(check_rootwidget_flag, 0, &done); */\n        lib_eventloop_launcher(check_rootwidget_flag, 0, &done, interp);\n\n        /* exception check */\n        if (!NIL_P(rbtk_pending_exception)) {\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n            Tcl_Release(interp);\n\n            /*\n            if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)) {\n            */\n            if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)\n                || rb_obj_is_kind_of(rbtk_pending_exception, rb_eInterrupt)) {\n                return TCL_RETURN;\n            } else{\n                return TCL_ERROR;\n            }\n        }\n\n        /* trap check */\n        if (rb_trap_pending) {\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n            Tcl_Release(interp);\n\n            return TCL_RETURN;\n        }\n\n        if (done != 1) {\n            /*\n             * Note that we do not delete the event handler because it\n             * was deleted automatically when the window was destroyed.\n             */\n            thr_crit_bup = rb_thread_critical;\n            rb_thread_critical = Qtrue;\n\n            Tcl_ResetResult(interp);\n            Tcl_AppendResult(interp, \"window \\\"\", nameString,\n                             \"\\\" was deleted before its visibility changed\",\n                             (char *) NULL);\n\n            rb_thread_critical = thr_crit_bup;\n\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[2]);\n#endif\n\n        Tk_DeleteEventHandler(window,\n                              VisibilityChangeMask|StructureNotifyMask,\n                              WaitVisibilityProc, (ClientData) &done);\n\n        rb_thread_critical = thr_crit_bup;\n\n        break;\n\n    case TKWAIT_WINDOW:\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n\t/* This function works on the Tk eventloop thread only. */\n        if (!tk_stubs_init_p() || Tk_MainWindow(interp) == (Tk_Window)NULL) {\n            window = NULL;\n        } else {\n            window = Tk_NameToWindow(interp, nameString, tkwin);\n        }\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[2]);\n#endif\n\n        if (window == NULL) {\n            Tcl_AppendResult(interp, \": tkwait: \", \n                             \"no main-window (not Tk application?)\", \n                             (char*)NULL);\n            rb_thread_critical = thr_crit_bup;\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        Tk_CreateEventHandler(window, StructureNotifyMask,\n                              WaitWindowProc, (ClientData) &done);\n\n        rb_thread_critical = thr_crit_bup;\n\n        done = 0;\n        /* lib_eventloop_core(check_rootwidget_flag, 0, &done); */\n        lib_eventloop_launcher(check_rootwidget_flag, 0, &done, interp);\n\n        /* exception check */\n        if (!NIL_P(rbtk_pending_exception)) {\n            Tcl_Release(interp);\n\n            /*\n            if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)) {\n            */\n            if (rb_obj_is_kind_of(rbtk_pending_exception, rb_eSystemExit)\n                || rb_obj_is_kind_of(rbtk_pending_exception, rb_eInterrupt)) {\n                return TCL_RETURN;\n            } else{\n                return TCL_ERROR;\n            }\n        }\n\n        /* trap check */\n        if (rb_trap_pending) {\n            Tcl_Release(interp);\n\n            return TCL_RETURN;\n        }\n\n        /*\n         * Note:  there's no need to delete the event handler.  It was\n         * deleted automatically when the window was destroyed.\n         */\n        break;\n    }\n\n    /*\n     * Clear out the interpreter's result, since it may have been set\n     * by event handlers.\n     */\n\n    Tcl_ResetResult(interp);\n    Tcl_Release(interp);\n    return TCL_OK;\n}\n\n/****************************/\n/* vwait/tkwait with thread */\n/****************************/\nstruct th_vwait_param {\n    VALUE thread;\n    int   done;\n};\n\n#if TCL_MAJOR_VERSION >= 8\nstatic char *rb_threadVwaitProc _((ClientData, Tcl_Interp *, \n                                   CONST84 char *,CONST84 char *, int));\nstatic char *\nrb_threadVwaitProc(clientData, interp, name1, name2, flags)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    Tcl_Interp *interp;         /* Interpreter containing variable. */\n    CONST84 char *name1;        /* Name of variable. */\n    CONST84 char *name2;        /* Second part of variable name. */\n    int flags;                  /* Information about what happened. */\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic char *rb_threadVwaitProc _((ClientData, Tcl_Interp *, \n                                   char *, char *, int));\nstatic char *\nrb_threadVwaitProc(clientData, interp, name1, name2, flags)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    Tcl_Interp *interp;         /* Interpreter containing variable. */\n    char *name1;                /* Name of variable. */\n    char *name2;                /* Second part of variable name. */\n    int flags;                  /* Information about what happened. */\n#endif\n{\n    struct th_vwait_param *param = (struct th_vwait_param *) clientData;\n\n    if (flags & (TCL_INTERP_DESTROYED | TCL_TRACE_DESTROYED)) {\n        param->done = -1;\n    } else {\n        param->done = 1;\n    }\n    if (param->done != 0) rb_thread_wakeup(param->thread);\n\n    return (char *)NULL;\n}\n\n#define TKWAIT_MODE_VISIBILITY 1\n#define TKWAIT_MODE_DESTROY    2\n\nstatic void rb_threadWaitVisibilityProc _((ClientData, XEvent *));\nstatic void\nrb_threadWaitVisibilityProc(clientData, eventPtr)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    XEvent *eventPtr;           /* Information about event (not used). */\n{\n    struct th_vwait_param *param = (struct th_vwait_param *) clientData;\n\n    if (eventPtr->type == VisibilityNotify) {\n        param->done = TKWAIT_MODE_VISIBILITY;\n    }\n    if (eventPtr->type == DestroyNotify) {\n        param->done = TKWAIT_MODE_DESTROY;\n    }\n    if (param->done != 0) rb_thread_wakeup(param->thread);\n}\n\nstatic void rb_threadWaitWindowProc _((ClientData, XEvent *));\nstatic void\nrb_threadWaitWindowProc(clientData, eventPtr)\n    ClientData clientData;      /* Pointer to integer to set to 1. */\n    XEvent *eventPtr;           /* Information about event. */\n{\n    struct th_vwait_param *param = (struct th_vwait_param *) clientData;\n\n    if (eventPtr->type == DestroyNotify) {\n        param->done = TKWAIT_MODE_DESTROY;\n    }\n    if (param->done != 0) rb_thread_wakeup(param->thread);\n}\n\n#if TCL_MAJOR_VERSION >= 8\nstatic int\nip_rb_threadVwaitObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int\nip_rb_threadVwaitCommand(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int objc;\n    char *objv[];\n#endif\n{\n    struct th_vwait_param *param;\n    char *nameString;\n    int ret, dummy;\n    int thr_crit_bup;\n    volatile VALUE current_thread = rb_thread_current();\n\n    DUMP1(\"Ruby's 'thread_vwait' is called\");\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n\n    if (rb_thread_alone() || eventloop_thread == current_thread) {\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"call ip_rbVwaitObjCmd\");\n        return ip_rbVwaitObjCmd(clientData, interp, objc, objv);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"call ip_rbVwaitCommand\");\n        return ip_rbVwaitCommand(clientData, interp, objc, objv);\n#endif\n    }\n\n    Tcl_Preserve(interp);\n    Tcl_ResetResult(interp);\n\n    if (objc != 2) {\n#ifdef Tcl_WrongNumArgs\n        Tcl_WrongNumArgs(interp, 1, objv, \"name\");\n#else\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n        /* nameString = Tcl_GetString(objv[0]); */\n        nameString = Tcl_GetStringFromObj(objv[0], &dummy);\n#else /* TCL_MAJOR_VERSION < 8 */\n        nameString = objv[0];\n#endif\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         nameString, \" name\\\"\", (char *) NULL);\n\n        rb_thread_critical = thr_crit_bup;\n#endif\n\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_IncrRefCount(objv[1]);\n    /* nameString = Tcl_GetString(objv[1]); */\n    nameString = Tcl_GetStringFromObj(objv[1], &dummy);\n#else /* TCL_MAJOR_VERSION < 8 */\n    nameString = objv[1];\n#endif\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); */\n    param = (struct th_vwait_param *)ckalloc(sizeof(struct th_vwait_param));\n#if 1 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)param);\n#endif\n    param->thread = current_thread;\n    param->done = 0;\n\n    /*\n    if (Tcl_TraceVar(interp, nameString,\n                     TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                     rb_threadVwaitProc, (ClientData) param) != TCL_OK) {\n        return TCL_ERROR;\n    }\n    */\n    ret = Tcl_TraceVar(interp, nameString,\n                       TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                       rb_threadVwaitProc, (ClientData) param);\n\n    rb_thread_critical = thr_crit_bup;\n\n    if (ret != TCL_OK) {\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n        Tcl_Release((ClientData)param);\n#else\n        /* Tcl_Free((char *)param); */\n        ckfree((char *)param);\n#endif\n#endif\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[1]);\n#endif\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n    while(!param->done) {\n        /* rb_thread_stop(); */\n        rb_thread_sleep_forever();\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    if (param->done > 0) {\n        Tcl_UntraceVar(interp, nameString,\n                       TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                       rb_threadVwaitProc, (ClientData) param);\n    }\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)param);\n#else\n    /* Tcl_Free((char *)param); */\n    ckfree((char *)param);\n#endif\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_DecrRefCount(objv[1]);\n#endif\n    Tcl_Release(interp);\n    return TCL_OK;\n}\n\n#if TCL_MAJOR_VERSION >= 8\nstatic int\nip_rb_threadTkWaitObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic int\nip_rb_threadTkWaitCommand(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int objc;\n    char *objv[];\n#endif\n{\n    struct th_vwait_param *param;\n    Tk_Window tkwin = (Tk_Window) clientData;\n    Tk_Window window;\n    int index;\n    static CONST char *optionStrings[] = { \"variable\", \"visibility\", \"window\",\n                                           (char *) NULL };\n    enum options { TKWAIT_VARIABLE, TKWAIT_VISIBILITY, TKWAIT_WINDOW };\n    char *nameString;\n    int ret, dummy;\n    int thr_crit_bup;\n    volatile VALUE current_thread = rb_thread_current();\n\n    DUMP1(\"Ruby's 'thread_tkwait' is called\");\n    if (interp == (Tcl_Interp*)NULL) {\n        rbtk_pending_exception = rb_exc_new2(rb_eRuntimeError, \n                                             \"IP is deleted\");\n        return TCL_ERROR;\n    }\n\n    if (rb_thread_alone() || eventloop_thread == current_thread) {\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"call ip_rbTkWaitObjCmd\");\n        return ip_rbTkWaitObjCmd(clientData, interp, objc, objv);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"call rb_VwaitCommand\");\n        return ip_rbTkWaitCommand(clientData, interp, objc, objv);\n#endif\n    }\n\n    Tcl_Preserve(interp);\n    Tcl_Preserve(tkwin);\n\n    Tcl_ResetResult(interp);\n\n    if (objc != 3) {\n#ifdef Tcl_WrongNumArgs\n        Tcl_WrongNumArgs(interp, 1, objv, \"variable|visibility|window name\");\n#else\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         Tcl_GetStringFromObj(objv[0], &dummy), \n                         \" variable|visibility|window name\\\"\", \n                         (char *) NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n        Tcl_AppendResult(interp, \"wrong number of arguments: should be \\\"\",\n                         objv[0], \" variable|visibility|window name\\\"\", \n                         (char *) NULL);\n#endif\n\n        rb_thread_critical = thr_crit_bup;\n#endif\n\n        Tcl_Release(tkwin);\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n\n#if TCL_MAJOR_VERSION >= 8\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n    /*\n    if (Tcl_GetIndexFromObj(interp, objv[1], \n                            (CONST84 char **)optionStrings, \n                            \"option\", 0, &index) != TCL_OK) {\n        return TCL_ERROR;\n    }\n    */\n    ret = Tcl_GetIndexFromObj(interp, objv[1], \n                              (CONST84 char **)optionStrings, \n                              \"option\", 0, &index);\n\n    rb_thread_critical = thr_crit_bup;\n\n    if (ret != TCL_OK) {\n        Tcl_Release(tkwin);\n        Tcl_Release(interp);\n        return TCL_ERROR;\n    }\n#else /* TCL_MAJOR_VERSION < 8 */\n    {\n        int c = objv[1][0];\n        size_t length = strlen(objv[1]);\n\n        if ((c == 'v') && (strncmp(objv[1], \"variable\", length) == 0)\n            && (length >= 2)) {\n            index = TKWAIT_VARIABLE;\n        } else if ((c == 'v') && (strncmp(objv[1], \"visibility\", length) == 0)\n                   && (length >= 2)) {\n            index = TKWAIT_VISIBILITY;\n        } else if ((c == 'w') && (strncmp(objv[1], \"window\", length) == 0)) {\n            index = TKWAIT_WINDOW;\n        } else {\n            Tcl_AppendResult(interp, \"bad option \\\"\", objv[1],\n                             \"\\\": must be variable, visibility, or window\", \n                             (char *) NULL);\n            Tcl_Release(tkwin);\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n    }\n#endif\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_IncrRefCount(objv[2]);\n    /* nameString = Tcl_GetString(objv[2]); */\n    nameString = Tcl_GetStringFromObj(objv[2], &dummy);\n#else /* TCL_MAJOR_VERSION < 8 */\n    nameString = objv[2];\n#endif\n\n    /* param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); */\n    param = (struct th_vwait_param *)ckalloc(sizeof(struct th_vwait_param));\n#if 1 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)param);\n#endif\n    param->thread = current_thread;\n    param->done = 0;\n\n    rb_thread_critical = thr_crit_bup;\n\n    switch ((enum options) index) {\n    case TKWAIT_VARIABLE:\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n        /* \n        if (Tcl_TraceVar(interp, nameString,\n                         TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                         rb_threadVwaitProc, (ClientData) param) != TCL_OK) {\n            return TCL_ERROR;\n        }\n        */\n        ret = Tcl_TraceVar(interp, nameString,\n                         TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                         rb_threadVwaitProc, (ClientData) param);\n\n        rb_thread_critical = thr_crit_bup;\n\n        if (ret != TCL_OK) {\n#if 0 /* use Tcl_EventuallyFree */\n            Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n            Tcl_Release(param);\n#else\n            /* Tcl_Free((char *)param); */\n            ckfree((char *)param);\n#endif\n#endif\n\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n\n            Tcl_Release(tkwin);\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        while(!param->done) {\n            /* rb_thread_stop(); */\n            rb_thread_sleep_forever();\n        }\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        if (param->done > 0) {\n            Tcl_UntraceVar(interp, nameString,\n                           TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,\n                           rb_threadVwaitProc, (ClientData) param);\n        }\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[2]);\n#endif\n\n        rb_thread_critical = thr_crit_bup;\n\n        break;\n\n    case TKWAIT_VISIBILITY:\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if 0 /* variable 'tkwin' must keep the token of MainWindow */\n        if (!tk_stubs_init_p() || Tk_MainWindow(interp) == (Tk_Window)NULL) {\n            window = NULL;\n        } else {\n            window = Tk_NameToWindow(interp, nameString, tkwin);\n        }\n#else\n        if (!tk_stubs_init_p() || tkwin == (Tk_Window)NULL) {\n            window = NULL;\n\t} else {\n            /* Tk_NameToWindow() returns right token on non-eventloop thread */\n            Tcl_CmdInfo info;\n            if (Tcl_GetCommandInfo(interp, \".\", &info)) { /* check root */\n                window = Tk_NameToWindow(interp, nameString, tkwin);\n            } else {\n                window = NULL;\n            }\n\t}\n#endif\n\n        if (window == NULL) {\n            Tcl_AppendResult(interp, \": thread_tkwait: \", \n                             \"no main-window (not Tk application?)\", \n                             (char*)NULL);\n\n            rb_thread_critical = thr_crit_bup;\n\n#if 0 /* use Tcl_EventuallyFree */\n\t    Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n            Tcl_Release(param);\n#else\n            /* Tcl_Free((char *)param); */\n            ckfree((char *)param);\n#endif\n#endif\n\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n            Tcl_Release(tkwin);\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n        Tcl_Preserve(window);\n\n        Tk_CreateEventHandler(window,\n                              VisibilityChangeMask|StructureNotifyMask,\n                              rb_threadWaitVisibilityProc, (ClientData) param);\n\n        rb_thread_critical = thr_crit_bup;\n\n        while(param->done != TKWAIT_MODE_VISIBILITY) {\n            if (param->done == TKWAIT_MODE_DESTROY) break;\n            /* rb_thread_stop(); */\n            rb_thread_sleep_forever();\n        }\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        /* when a window is destroyed, no need to call Tk_DeleteEventHandler */\n        if (param->done != TKWAIT_MODE_DESTROY) {\n            Tk_DeleteEventHandler(window,\n                                  VisibilityChangeMask|StructureNotifyMask,\n                                  rb_threadWaitVisibilityProc, \n                                  (ClientData) param);\n        }\n\n        if (param->done != 1) {\n            Tcl_ResetResult(interp);\n            Tcl_AppendResult(interp, \"window \\\"\", nameString,\n                             \"\\\" was deleted before its visibility changed\",\n                             (char *) NULL);\n\n            rb_thread_critical = thr_crit_bup;\n\n            Tcl_Release(window);\n\n#if 0 /* use Tcl_EventuallyFree */\n\t    Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n            Tcl_Release(param);\n#else\n            /* Tcl_Free((char *)param); */\n            ckfree((char *)param);\n#endif\n#endif\n\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_DecrRefCount(objv[2]);\n#endif\n\n            Tcl_Release(tkwin);\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        Tcl_Release(window);\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[2]);\n#endif\n\n        rb_thread_critical = thr_crit_bup;\n\n        break;\n\n    case TKWAIT_WINDOW:\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n#if 0 /* variable 'tkwin' must keep the token of MainWindow */\n        if (!tk_stubs_init_p() || Tk_MainWindow(interp) == (Tk_Window)NULL) {\n            window = NULL;\n        } else {\n            window = Tk_NameToWindow(interp, nameString, tkwin);\n        }\n#else\n        if (!tk_stubs_init_p() || tkwin == (Tk_Window)NULL) {\n            window = NULL;\n\t} else {\n            /* Tk_NameToWindow() returns right token on non-eventloop thread */\n            Tcl_CmdInfo info;\n            if (Tcl_GetCommandInfo(interp, \".\", &info)) { /* check root */\n                window = Tk_NameToWindow(interp, nameString, tkwin);\n            } else {\n                window = NULL;\n            }\n\t}\n#endif\n\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[2]);\n#endif\n\n        if (window == NULL) {\n            Tcl_AppendResult(interp, \": thread_tkwait: \", \n                             \"no main-window (not Tk application?)\", \n                             (char*)NULL);\n\n            rb_thread_critical = thr_crit_bup;\n\n#if 0 /* use Tcl_EventuallyFree */\n\t    Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n            Tcl_Release(param);\n#else\n            /* Tcl_Free((char *)param); */\n            ckfree((char *)param);\n#endif\n#endif\n\n            Tcl_Release(tkwin);\n            Tcl_Release(interp);\n            return TCL_ERROR;\n        }\n\n        Tcl_Preserve(window);\n\n        Tk_CreateEventHandler(window, StructureNotifyMask,\n                              rb_threadWaitWindowProc, (ClientData) param);\n\n        rb_thread_critical = thr_crit_bup;\n\n        while(param->done != TKWAIT_MODE_DESTROY) {\n            /* rb_thread_stop(); */\n            rb_thread_sleep_forever();\n        }\n\n        Tcl_Release(window);\n\n        /* when a window is destroyed, no need to call Tk_DeleteEventHandler\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        Tk_DeleteEventHandler(window, StructureNotifyMask,\n                              rb_threadWaitWindowProc, (ClientData) param);\n\n        rb_thread_critical = thr_crit_bup;\n        */\n\n        break;\n    } /* end of 'switch' statement */\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 1 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)param);\n#else\n    /* Tcl_Free((char *)param); */\n    ckfree((char *)param);\n#endif\n#endif\n\n    /*\n     * Clear out the interpreter's result, since it may have been set\n     * by event handlers.\n     */\n\n    Tcl_ResetResult(interp);\n\n    Tcl_Release(tkwin);\n    Tcl_Release(interp);\n    return TCL_OK;\n}\n\nstatic VALUE\nip_thread_vwait(self, var)\n    VALUE self;\n    VALUE var;\n{\n    VALUE argv[2];\n    volatile VALUE cmd_str = rb_str_new2(\"thread_vwait\");\n\n    argv[0] = cmd_str;\n    argv[1] = var;\n\n    return ip_invoke_with_position(2, argv, self, TCL_QUEUE_TAIL);\n}\n\nstatic VALUE\nip_thread_tkwait(self, mode, target)\n    VALUE self;\n    VALUE mode;\n    VALUE target;\n{\n    VALUE argv[3];\n    volatile VALUE cmd_str = rb_str_new2(\"thread_tkwait\");\n\n    argv[0] = cmd_str;\n    argv[1] = mode;\n    argv[2] = target;\n\n    return ip_invoke_with_position(3, argv, self, TCL_QUEUE_TAIL);\n}\n\n\n/* delete slave interpreters */\n#if TCL_MAJOR_VERSION >= 8\nstatic void\ndelete_slaves(ip)\n    Tcl_Interp *ip;\n{\n    int  thr_crit_bup;\n    Tcl_Interp *slave;\n    Tcl_Obj *slave_list, *elem;\n    char *slave_name;\n    int i, len;\n\n    DUMP1(\"delete slaves\");\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    if (!Tcl_InterpDeleted(ip) && Tcl_Eval(ip, \"interp slaves\") == TCL_OK) {\n        slave_list = Tcl_GetObjResult(ip);\n        Tcl_IncrRefCount(slave_list);\n\n        if (Tcl_ListObjLength((Tcl_Interp*)NULL, slave_list, &len) == TCL_OK) {\n            for(i = 0; i < len; i++) {\n                Tcl_ListObjIndex((Tcl_Interp*)NULL, slave_list, i, &elem);\n\n                if (elem == (Tcl_Obj*)NULL) continue;\n\n                Tcl_IncrRefCount(elem);\n\n                /* get slave */\n                /* slave_name = Tcl_GetString(elem); */\n                slave_name = Tcl_GetStringFromObj(elem, (int*)NULL);\n                DUMP2(\"delete slave:'%s'\", slave_name);\n\n                Tcl_DecrRefCount(elem);\n\n                slave = Tcl_GetSlave(ip, slave_name);\n                if (slave == (Tcl_Interp*)NULL) continue;\n\n                /* call ip_finalize */\n                ip_finalize(slave);\n\n                Tcl_DeleteInterp(slave);\n                /* Tcl_Release(slave); */\n            }\n        }\n\n        Tcl_DecrRefCount(slave_list);\n    }\n\n    rb_thread_critical = thr_crit_bup;\n}\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic void\ndelete_slaves(ip)\n    Tcl_Interp *ip;\n{\n    int  thr_crit_bup;\n    Tcl_Interp *slave;\n    int argc;\n    char **argv;\n    char *slave_list;\n    char *slave_name;\n    int i, len;\n\n    DUMP1(\"delete slaves\");\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    if (!Tcl_InterpDeleted(ip) && Tcl_Eval(ip, \"interp slaves\") == TCL_OK) {\n        slave_list = ip->result;\n        if (Tcl_SplitList((Tcl_Interp*)NULL, \n                          slave_list, &argc, &argv) == TCL_OK) {\n            for(i = 0; i < argc; i++) {\n                slave_name = argv[i];\n\n                DUMP2(\"delete slave:'%s'\", slave_name);\n\n                slave = Tcl_GetSlave(ip, slave_name);\n                if (slave == (Tcl_Interp*)NULL) continue;\n\n                /* call ip_finalize */\n                ip_finalize(slave);\n\n                Tcl_DeleteInterp(slave);\n            }\n        }\n    }\n\n    rb_thread_critical = thr_crit_bup;\n}\n#endif\n\n\n/* finalize operation */\nstatic void\nlib_mark_at_exit(self)\n    VALUE self;\n{\n    at_exit = 1;\n}\n\nstatic int\n#if TCL_MAJOR_VERSION >= 8\nip_null_proc(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int argc;\n    Tcl_Obj *CONST argv[];\n#else /* TCL_MAJOR_VERSION < 8 */\nip_null_proc(clientData, interp, argc, argv)\n    ClientData clientData;\n    Tcl_Interp *interp;\n    int argc;\n    char *argv[];\n#endif\n{\n    Tcl_ResetResult(interp);\n    return TCL_OK;\n}\n\nstatic void\nip_finalize(ip)\n    Tcl_Interp *ip;\n{\n    Tcl_CmdInfo info;\n    int  thr_crit_bup;\n\n    VALUE rb_debug_bup, rb_verbose_bup;\n          /* When ruby is exiting, printing debug messages in some callback \n             operations from Tcl-IP sometimes cause SEGV. I don't know the \n             reason. But I got SEGV when calling \"rb_io_write(rb_stdout, ...)\".\n             So, in some part of this function, debug mode and verbose mode \n             are disabled. If you know the reason, please fix it.\n                           --  Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)  */\n\n    DUMP1(\"start ip_finalize\");\n\n    if (ip == (Tcl_Interp*)NULL) {\n        DUMP1(\"ip is NULL\");\n        return;\n    }\n\n    if (Tcl_InterpDeleted(ip)) {\n        DUMP2(\"ip(%p) is already deleted\", ip);\n        return;\n    }\n\n#if TCL_NAMESPACE_DEBUG\n    if (ip_null_namespace(ip)) {\n        DUMP2(\"ip(%p) has null namespace\", ip);\n        return;\n    }\n#endif\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    rb_debug_bup   = ruby_debug;\n    rb_verbose_bup = ruby_verbose;\n\n    Tcl_Preserve(ip);\n\n    /* delete slaves */\n    delete_slaves(ip);\n\n    /* shut off some connections from Tcl-proc to Ruby */\n    if (at_exit) {\n\t/* NOTE: Only when at exit. \n\t   Because, ruby removes objects, which depends on the deleted \n\t   interpreter, on some callback operations. \n\t   It is important for GC. */\n#if TCL_MAJOR_VERSION >= 8\n\tTcl_CreateObjCommand(ip, \"ruby\", ip_null_proc, \n\t\t\t     (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);\n\tTcl_CreateObjCommand(ip, \"ruby_eval\", ip_null_proc, \n\t\t\t     (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);\n\tTcl_CreateObjCommand(ip, \"ruby_cmd\", ip_null_proc, \n\t\t\t     (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n\tTcl_CreateCommand(ip, \"ruby\", ip_null_proc, \n\t\t\t  (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);\n\tTcl_CreateCommand(ip, \"ruby_eval\", ip_null_proc, \n\t\t\t  (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);\n\tTcl_CreateCommand(ip, \"ruby_cmd\", ip_null_proc, \n\t\t\t  (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\t/* \n\t  rb_thread_critical = thr_crit_bup;\n\t  return;\n\t*/\n    }\n\n    /* delete root widget */\n#if 1\n    DUMP1(\"check `destroy'\");\n    if (Tcl_GetCommandInfo(ip, \"destroy\", &info)) {\n        DUMP1(\"call `destroy .'\");\n        Tcl_GlobalEval(ip, \"catch {destroy .}\");\n    }\n#endif\n#if 1\n    DUMP1(\"destroy root widget\");\n    if (tk_stubs_init_p() && Tk_MainWindow(ip) != (Tk_Window)NULL) {\n        /*\n\t *  On Ruby VM, this code piece may be not called, because \n\t *  Tk_MainWindow() returns NULL on a native thread except \n         *  the thread which initialize Tk environment.\n         *  Of course, that is a problem. But maybe not so serious.\n         *  All widgets are destroyed when the Tcl interp is deleted.\n         *  At then, Ruby may raise exceptions on the delete hook \n         *  callbacks which registered for the deleted widgets, and \n\t *  may fail to clear objects which depends on the widgets.\n         *  Although it is the problem, it is possibly avoidable by\n         *  rescuing exceptions and the finalize hook of the interp.\n         */\n        Tk_Window win = Tk_MainWindow(ip);\n\n        DUMP1(\"call Tk_DestroyWindow\");\n        ruby_debug   = Qfalse;\n        ruby_verbose = Qnil;\n\tif (! (((Tk_FakeWin*)win)->flags & TK_ALREADY_DEAD)) {\n\t  Tk_DestroyWindow(win);\n\t}\n        ruby_debug   = rb_debug_bup;\n        ruby_verbose = rb_verbose_bup;\n    }\n#endif\n\n    /* call finalize-hook-proc */\n    DUMP1(\"check `finalize-hook-proc'\");\n    if ( Tcl_GetCommandInfo(ip, finalize_hook_name, &info)) {\n        DUMP2(\"call finalize hook proc '%s'\", finalize_hook_name);\n        ruby_debug   = Qfalse;\n        ruby_verbose = Qnil;\n        Tcl_GlobalEval(ip, finalize_hook_name);\n        ruby_debug   = rb_debug_bup;\n        ruby_verbose = rb_verbose_bup;\n    }\n\n    DUMP1(\"check `foreach' & `after'\");\n    if ( Tcl_GetCommandInfo(ip, \"foreach\", &info)\n         && Tcl_GetCommandInfo(ip, \"after\", &info) ) {\n        DUMP1(\"cancel after callbacks\");\n        ruby_debug   = Qfalse;\n        ruby_verbose = Qnil;\n        Tcl_GlobalEval(ip, \"catch {foreach id [after info] {after cancel $id}}\");\n        ruby_debug   = rb_debug_bup;\n        ruby_verbose = rb_verbose_bup;\n    }\n\n    Tcl_Release(ip);\n\n    DUMP1(\"finish ip_finalize\");\n    ruby_debug   = rb_debug_bup;\n    ruby_verbose = rb_verbose_bup;\n    rb_thread_critical = thr_crit_bup;\n}\n\n\n/* destroy interpreter */\nstatic void\nip_free(ptr)\n    struct tcltkip *ptr;\n{\n    int  thr_crit_bup;\n\n    DUMP2(\"free Tcl Interp %lx\", (unsigned long)ptr->ip);\n    if (ptr) {\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        if ( ptr->ip != (Tcl_Interp*)NULL \n             && !Tcl_InterpDeleted(ptr->ip)\n             && Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL \n             && !Tcl_InterpDeleted(Tcl_GetMaster(ptr->ip)) ) {\n            DUMP2(\"parent IP(%lx) is not deleted\", \n                  (unsigned long)Tcl_GetMaster(ptr->ip));\n            DUMP2(\"slave IP(%lx) should not be deleted\", \n                  (unsigned long)ptr->ip);\n            free(ptr);\n            /* ckfree((char*)ptr); */\n            rb_thread_critical = thr_crit_bup;\n            return;\n        }\n\n        if (ptr->ip == (Tcl_Interp*)NULL) {\n            DUMP1(\"ip_free is called for deleted IP\");\n            free(ptr);\n            /* ckfree((char*)ptr); */\n            rb_thread_critical = thr_crit_bup;\n            return;\n        }\n\n        ip_finalize(ptr->ip);\n        Tcl_DeleteInterp(ptr->ip); \n        Tcl_Release(ptr->ip); \n\n        ptr->ip = (Tcl_Interp*)NULL;\n        free(ptr);\n        /* ckfree((char*)ptr); */\n\n        rb_thread_critical = thr_crit_bup;\n    }\n\n    DUMP1(\"complete freeing Tcl Interp\");\n}\n\n\n/* create and initialize interpreter */\nstatic VALUE ip_alloc _((VALUE));\nstatic VALUE\nip_alloc(self)\n    VALUE self;\n{\n    return Data_Wrap_Struct(self, 0, ip_free, 0);\n}\n\nstatic void\nip_replace_wait_commands(interp, mainWin)\n    Tcl_Interp *interp;\n    Tk_Window mainWin;\n{\n    /* replace 'vwait' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"vwait\\\")\");\n    Tcl_CreateObjCommand(interp, \"vwait\", ip_rbVwaitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"vwait\\\")\");\n    Tcl_CreateCommand(interp, \"vwait\", ip_rbVwaitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* replace 'tkwait' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"tkwait\\\")\");\n    Tcl_CreateObjCommand(interp, \"tkwait\", ip_rbTkWaitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"tkwait\\\")\");\n    Tcl_CreateCommand(interp, \"tkwait\", ip_rbTkWaitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* add 'thread_vwait' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"thread_vwait\\\")\");\n    Tcl_CreateObjCommand(interp, \"thread_vwait\", ip_rb_threadVwaitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"thread_vwait\\\")\");\n    Tcl_CreateCommand(interp, \"thread_vwait\", ip_rb_threadVwaitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* add 'thread_tkwait' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"thread_tkwait\\\")\");\n    Tcl_CreateObjCommand(interp, \"thread_tkwait\", ip_rb_threadTkWaitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"thread_tkwait\\\")\");\n    Tcl_CreateCommand(interp, \"thread_tkwait\", ip_rb_threadTkWaitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* replace 'update' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"update\\\")\");\n    Tcl_CreateObjCommand(interp, \"update\", ip_rbUpdateObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"update\\\")\");\n    Tcl_CreateCommand(interp, \"update\", ip_rbUpdateCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* add 'thread_update' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"thread_update\\\")\");\n    Tcl_CreateObjCommand(interp, \"thread_update\", ip_rb_threadUpdateObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"thread_update\\\")\");\n    Tcl_CreateCommand(interp, \"thread_update\", ip_rb_threadUpdateCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n}\n\n\n\n#if TCL_MAJOR_VERSION >= 8\nstatic int ip_rbNamespaceObjCmd _((ClientData, Tcl_Interp *, int,\n                                   Tcl_Obj *CONST []));\nstatic int\nip_rbNamespaceObjCmd(clientData, interp, objc, objv)\n    ClientData clientData;\n    Tcl_Interp *interp; \n    int objc;\n    Tcl_Obj *CONST objv[];\n{\n    Tcl_CmdInfo info;\n    int ret;\n\n    if (!Tcl_GetCommandInfo(interp, \"__orig_namespace_command__\", &(info))) {\n        Tcl_ResetResult(interp);\n        Tcl_AppendResult(interp, \n                         \"invalid command name \\\"namespace\\\"\", (char*)NULL);\n        return TCL_ERROR;\n    }\n\n    rbtk_eventloop_depth++;\n    DUMP2(\"namespace wrapper enter depth == %d\", rbtk_eventloop_depth);\n\n    if (info.isNativeObjectProc) {\n        ret = (*(info.objProc))(info.objClientData, interp, objc, objv);\n    } else {\n        /* string interface */\n        int i;\n        char **argv;\n\n        /* argv = (char **)Tcl_Alloc(sizeof(char *) * (objc + 1)); */\n        argv = (char **)ckalloc(sizeof(char *) * (objc + 1));\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)argv); /* XXXXXXXX */\n#endif\n\n        for(i = 0; i < objc; i++) {\n            /* argv[i] = Tcl_GetString(objv[i]); */\n            argv[i] = Tcl_GetStringFromObj(objv[i], (int*)NULL);\n        }\n        argv[objc] = (char *)NULL;\n\n        ret = (*(info.proc))(info.clientData, interp, \n                              objc, (CONST84 char **)argv);\n\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* Tcl_Free((char*)argv); */\n        ckfree((char*)argv);\n#endif\n#endif\n    }\n\n    DUMP2(\"namespace wrapper exit depth == %d\", rbtk_eventloop_depth);\n    rbtk_eventloop_depth--;\n\n    return ret;\n}\n#endif\n\nstatic void\nip_wrap_namespace_command(interp)\n    Tcl_Interp *interp; \n{\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_CmdInfo orig_info;\n\n    if (!Tcl_GetCommandInfo(interp, \"namespace\", &(orig_info))) {\n        return;\n    }\n\n    if (orig_info.isNativeObjectProc) {\n        Tcl_CreateObjCommand(interp, \"__orig_namespace_command__\", \n                             orig_info.objProc, orig_info.objClientData, \n                             orig_info.deleteProc);\n    } else {\n        Tcl_CreateCommand(interp, \"__orig_namespace_command__\", \n                          orig_info.proc, orig_info.clientData, \n                          orig_info.deleteProc);\n    }\n\n    Tcl_CreateObjCommand(interp, \"namespace\", ip_rbNamespaceObjCmd, \n                         (ClientData) 0, (Tcl_CmdDeleteProc *)NULL);\n#endif\n}\n\n\n/* call when interpreter is deleted */\nstatic void\nip_CallWhenDeleted(clientData, ip)\n    ClientData clientData;\n    Tcl_Interp *ip;\n{\n    int  thr_crit_bup;\n    /* Tk_Window main_win = (Tk_Window) clientData; */\n\n    DUMP1(\"start ip_CallWhenDeleted\");\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    ip_finalize(ip);\n\n    DUMP1(\"finish ip_CallWhenDeleted\");\n    rb_thread_critical = thr_crit_bup;\n}\n\n/* initialize interpreter */\nstatic VALUE\nip_init(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct tcltkip *ptr;        /* tcltkip data struct */\n    VALUE argv0, opts;\n    int cnt;\n    int st;\n    int with_tk = 1;\n    Tk_Window mainWin = (Tk_Window)NULL;\n\n    /* security check */\n#ifdef RUBY_VM\n    if (rb_safe_level() >= 4) {\n#else\n    if (ruby_safe_level >= 4) {\n#endif\n        rb_raise(rb_eSecurityError, \n                 \"Cannot create a TclTkIp object at level %d\", \n#ifdef RUBY_VM\n                 rb_safe_level()\n#else\n                 ruby_safe_level\n#endif\n                 );\n    }\n\n    /* create object */\n    Data_Get_Struct(self, struct tcltkip, ptr);\n    ptr = ALLOC(struct tcltkip);\n    /* ptr = (struct tcltkip *)ckalloc(sizeof(struct tcltkip)); */\n    DATA_PTR(self) = ptr;\n#ifdef RUBY_VM\n    ptr->tk_thread_id = 0;\n#endif\n    ptr->ref_count = 0;\n    ptr->allow_ruby_exit = 1;\n    ptr->return_value = 0;\n\n    /* from Tk_Main() */\n    DUMP1(\"Tcl_CreateInterp\");\n    ptr->ip = ruby_tcl_create_ip_and_stubs_init(&st);\n    if (ptr->ip == NULL) {\n        switch(st) {\n        case TCLTK_STUBS_OK:\n            break;\n        case NO_TCL_DLL:\n            rb_raise(rb_eLoadError, \"tcltklib: fail to open tcl_dll\");\n        case NO_FindExecutable:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_FindExecutable\");\n        case NO_CreateInterp:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_CreateInterp()\");\n        case NO_DeleteInterp:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_DeleteInterp()\");\n        case FAIL_CreateInterp:\n            rb_raise(rb_eRuntimeError, \"tcltklib: fail to create a new IP\");\n        case FAIL_Tcl_InitStubs:\n            rb_raise(rb_eRuntimeError, \"tcltklib: fail to Tcl_InitStubs()\");\n        default:\n            rb_raise(rb_eRuntimeError, \"tcltklib: unknown error(%d) on ruby_tcl_create_ip_and_stubs_init\", st);\n        }\n    }\n\n#if TCL_MAJOR_VERSION >= 8\n#if TCL_NAMESPACE_DEBUG\n    DUMP1(\"get current namespace\");\n    if ((ptr->default_ns = Tcl_GetCurrentNamespace(ptr->ip)) \n        == (Tcl_Namespace*)NULL) {\n      rb_raise(rb_eRuntimeError, \"a new Tk interpreter has a NULL namespace\");\n    }\n#endif\n#endif\n\n    rbtk_preserve_ip(ptr);\n    DUMP2(\"IP ref_count = %d\", ptr->ref_count);\n    current_interp = ptr->ip;\n\n    ptr->has_orig_exit \n        = Tcl_GetCommandInfo(ptr->ip, \"exit\", &(ptr->orig_exit_info));\n\n    /* from Tcl_AppInit() */\n    DUMP1(\"Tcl_Init\");\n    if (Tcl_Init(ptr->ip) == TCL_ERROR) {\n        rb_raise(rb_eRuntimeError, \"%s\", Tcl_GetStringResult(ptr->ip));\n    }\n\n    /* set variables */\n    cnt = rb_scan_args(argc, argv, \"02\", &argv0, &opts);\n    switch(cnt) {\n    case 2:\n        /* options */\n        if (NIL_P(opts) || opts == Qfalse) {\n            /* without Tk */\n            with_tk = 0;\n        } else {\n            /* Tcl_SetVar(ptr->ip, \"argv\", StringValuePtr(opts), 0); */\n            Tcl_SetVar(ptr->ip, \"argv\", StringValuePtr(opts), TCL_GLOBAL_ONLY);\n        }\n    case 1:\n        /* argv0 */\n        if (!NIL_P(argv0)) {\n            if (strncmp(StringValuePtr(argv0), \"-e\", 3) == 0\n                || strncmp(StringValuePtr(argv0), \"-\", 2) == 0) {\n                Tcl_SetVar(ptr->ip, \"argv0\", \"ruby\", TCL_GLOBAL_ONLY);\n            } else {\n                /* Tcl_SetVar(ptr->ip, \"argv0\", StringValuePtr(argv0), 0); */\n                Tcl_SetVar(ptr->ip, \"argv0\", StringValuePtr(argv0), \n                           TCL_GLOBAL_ONLY);\n            }\n        }\n    case 0:\n        /* no args */\n        ;\n    }\n\n    /* from Tcl_AppInit() */\n    if (with_tk) {\n        DUMP1(\"Tk_Init\");\n        st = ruby_tk_stubs_init(ptr->ip);\n        switch(st) {\n        case TCLTK_STUBS_OK:\n            break;\n        case NO_Tk_Init:\n            rb_raise(rb_eLoadError, \"tcltklib: can't find Tk_Init()\");\n        case FAIL_Tk_Init:\n            rb_raise(rb_eRuntimeError, \"tcltklib: fail to Tk_Init(). %s\", \n                     Tcl_GetStringResult(ptr->ip));\n        case FAIL_Tk_InitStubs:\n            rb_raise(rb_eRuntimeError, \"tcltklib: fail to Tk_InitStubs(). %s\", \n                     Tcl_GetStringResult(ptr->ip));\n        default:\n            rb_raise(rb_eRuntimeError, \"tcltklib: unknown error(%d) on ruby_tk_stubs_init\", st);\n        }\n\n        DUMP1(\"Tcl_StaticPackage(\\\"Tk\\\")\");\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_StaticPackage(ptr->ip, \"Tk\", Tk_Init, Tk_SafeInit);\n#else /* TCL_MAJOR_VERSION < 8 */\n        Tcl_StaticPackage(ptr->ip, \"Tk\", Tk_Init,\n                          (Tcl_PackageInitProc *) NULL);\n#endif\n\n#ifdef RUBY_VM\n        /* set Tk thread ID */\n        ptr->tk_thread_id = Tcl_GetCurrentThread();\n#endif\n        /* get main window */\n        mainWin = Tk_MainWindow(ptr->ip);\n        Tk_Preserve((ClientData)mainWin);\n    }\n\n    /* add ruby command to the interpreter */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"ruby\\\")\");\n    Tcl_CreateObjCommand(ptr->ip, \"ruby\", ip_ruby_eval, (ClientData)NULL,\n                         (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateObjCommand(\\\"ruby_eval\\\")\");\n    Tcl_CreateObjCommand(ptr->ip, \"ruby_eval\", ip_ruby_eval, (ClientData)NULL,\n                         (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateObjCommand(\\\"ruby_cmd\\\")\");\n    Tcl_CreateObjCommand(ptr->ip, \"ruby_cmd\", ip_ruby_cmd, (ClientData)NULL,\n                         (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"ruby\\\")\");\n    Tcl_CreateCommand(ptr->ip, \"ruby\", ip_ruby_eval, (ClientData)NULL,\n                      (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateCommand(\\\"ruby_eval\\\")\");\n    Tcl_CreateCommand(ptr->ip, \"ruby_eval\", ip_ruby_eval, (ClientData)NULL,\n                      (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateCommand(\\\"ruby_cmd\\\")\");\n    Tcl_CreateCommand(ptr->ip, \"ruby_cmd\", ip_ruby_cmd, (ClientData)NULL,\n                      (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* add 'interp_exit', 'ruby_exit' and replace 'exit' command */\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"interp_exit\\\")\");\n    Tcl_CreateObjCommand(ptr->ip, \"interp_exit\", ip_InterpExitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateObjCommand(\\\"ruby_exit\\\")\");\n    Tcl_CreateObjCommand(ptr->ip, \"ruby_exit\", ip_RubyExitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateObjCommand(\\\"exit\\\") --> \\\"ruby_exit\\\"\");\n    Tcl_CreateObjCommand(ptr->ip, \"exit\", ip_RubyExitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"interp_exit\\\")\");\n    Tcl_CreateCommand(ptr->ip, \"interp_exit\", ip_InterpExitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateCommand(\\\"ruby_exit\\\")\");\n    Tcl_CreateCommand(ptr->ip, \"ruby_exit\", ip_RubyExitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n    DUMP1(\"Tcl_CreateCommand(\\\"exit\\\") --> \\\"ruby_exit\\\"\");\n    Tcl_CreateCommand(ptr->ip, \"exit\", ip_RubyExitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* replace vwait and tkwait */\n    ip_replace_wait_commands(ptr->ip, mainWin);\n\n    /* wrap namespace command */\n    ip_wrap_namespace_command(ptr->ip);\n\n    /* set finalizer */\n    Tcl_CallWhenDeleted(ptr->ip, ip_CallWhenDeleted, (ClientData)mainWin);\n\n    if (mainWin != (Tk_Window)NULL) {\n        Tk_Release((ClientData)mainWin);\n    }\n\n    return self;\n}\n\nstatic VALUE\nip_create_slave_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;\n    VALUE *argv;\n{\n    struct tcltkip *master = get_ip(interp);\n    struct tcltkip *slave = ALLOC(struct tcltkip);\n    /* struct tcltkip *slave = (struct tcltkip *)ckalloc(sizeof(struct tcltkip)); */\n    VALUE safemode;\n    VALUE name;\n    int safe;\n    int thr_crit_bup;\n    Tk_Window mainWin;\n\n    /* ip is deleted? */\n    if (deleted_ip(master)) {\n        return rb_exc_new2(rb_eRuntimeError, \n                           \"deleted master cannot create a new slave\");\n    }\n\n    name     = argv[0];\n    safemode = argv[1];\n\n    if (Tcl_IsSafe(master->ip) == 1) {\n        safe = 1;\n    } else if (safemode == Qfalse || NIL_P(safemode)) {\n        safe = 0;\n        /* rb_secure(4); */ /* already checked */\n    } else {\n        safe = 1;\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n#if 0\n    /* init Tk */\n    if (RTEST(with_tk)) {\n        volatile VALUE exc;\n        if (!tk_stubs_init_p()) {\n            exc = tcltkip_init_tk(interp);\n            if (!NIL_P(exc)) {\n                rb_thread_critical = thr_crit_bup;\n                return exc;\n            }\n        }\n    }\n#endif\n\n    /* create slave-ip */\n#ifdef RUBY_VM\n    /* slave->tk_thread_id = 0; */\n    slave->tk_thread_id = master->tk_thread_id; /* == current thread */\n#endif\n    slave->ref_count = 0;\n    slave->allow_ruby_exit = 0;\n    slave->return_value = 0;\n\n    slave->ip = Tcl_CreateSlave(master->ip, StringValuePtr(name), safe);\n    if (slave->ip == NULL) {\n        rb_thread_critical = thr_crit_bup;\n        return rb_exc_new2(rb_eRuntimeError, \n                           \"fail to create the new slave interpreter\");\n    }\n#if TCL_MAJOR_VERSION >= 8\n#if TCL_NAMESPACE_DEBUG\n    slave->default_ns = Tcl_GetCurrentNamespace(slave->ip);\n#endif\n#endif\n    rbtk_preserve_ip(slave);\n\n    slave->has_orig_exit \n        = Tcl_GetCommandInfo(slave->ip, \"exit\", &(slave->orig_exit_info));\n\n    /* replace 'exit' command --> 'interp_exit' command */\n    mainWin = (tk_stubs_init_p())? Tk_MainWindow(slave->ip): (Tk_Window)NULL;\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"exit\\\") --> \\\"interp_exit\\\"\");\n    Tcl_CreateObjCommand(slave->ip, \"exit\", ip_InterpExitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"exit\\\") --> \\\"interp_exit\\\"\");\n    Tcl_CreateCommand(slave->ip, \"exit\", ip_InterpExitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    /* replace vwait and tkwait */\n    ip_replace_wait_commands(slave->ip, mainWin);\n\n    /* wrap namespace command */\n    ip_wrap_namespace_command(slave->ip);\n\n    /* set finalizer */\n    Tcl_CallWhenDeleted(slave->ip, ip_CallWhenDeleted, (ClientData)mainWin);\n\n    rb_thread_critical = thr_crit_bup;\n\n    return Data_Wrap_Struct(CLASS_OF(interp), 0, ip_free, slave);\n}\n\nstatic VALUE\nip_create_slave(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct tcltkip *master = get_ip(self);\n    VALUE safemode;\n    VALUE name;\n    VALUE callargv[2];\n\n    /* ip is deleted? */\n    if (deleted_ip(master)) {\n        rb_raise(rb_eRuntimeError, \n                 \"deleted master cannot create a new slave interpreter\");\n    }\n\n    /* argument check */\n    if (rb_scan_args(argc, argv, \"11\", &name, &safemode) == 1) {\n        safemode = Qfalse;\n    }\n    if (Tcl_IsSafe(master->ip) != 1\n        && (safemode == Qfalse || NIL_P(safemode))) {\n        rb_secure(4);\n    }\n\n    StringValue(name);\n    callargv[0] = name;\n    callargv[1] = safemode;\n\n    return tk_funcall(ip_create_slave_core, 2, callargv, self);\n}\n\n\n/* self is slave of master? */\nstatic VALUE\nip_is_slave_of_p(self, master)\n    VALUE self, master;\n{\n    if (!rb_obj_is_kind_of(master, tcltkip_class)) {\n        rb_raise(rb_eArgError, \"expected TclTkIp object\");\n    }\n\n    if (Tcl_GetMaster(get_ip(self)->ip) == get_ip(master)->ip) {\n      return Qtrue;\n    } else {\n      return Qfalse;\n    }\n}\n\n\n/* create console (if supported) */\n#if defined(MAC_TCL) || defined(__WIN32__)\n#if TCL_MAJOR_VERSION < 8 \\\n    || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0) \\\n    || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 1 \\\n        && (TCL_RELEASE_LEVEL == TCL_ALPHA_RELEASE \\\n           || (TCL_RELEASE_LEVEL == TCL_BETA_RELEASE \\\n               && TCL_RELEASE_SERIAL < 2) ) )\nEXTERN void TkConsoleCreate _((void));\n#endif\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 1 \\\n    && ( (TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE \\\n          && TCL_RELEASE_SERIAL == 0) \\\n       || (TCL_RELEASE_LEVEL == TCL_BETA_RELEASE \\\n           && TCL_RELEASE_SERIAL >= 2) )\nEXTERN void TkConsoleCreate_ _((void));\n#endif\n#endif\nstatic VALUE\nip_create_console_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;   /* dummy */\n    VALUE *argv;  /* dummy */\n{\n    struct tcltkip *ptr = get_ip(interp);\n\n    if (!tk_stubs_init_p()) {\n        tcltkip_init_tk(interp);\n    }\n\n    if (Tcl_GetVar(ptr->ip,\"tcl_interactive\",TCL_GLOBAL_ONLY) == (char*)NULL) {\n        Tcl_SetVar(ptr->ip, \"tcl_interactive\", \"0\", TCL_GLOBAL_ONLY);\n    }\n\n#if TCL_MAJOR_VERSION > 8 \\\n    || (TCL_MAJOR_VERSION == 8 \\\n        && (TCL_MINOR_VERSION > 1 \\\n            || (TCL_MINOR_VERSION == 1 \\\n                 && TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE \\\n                 && TCL_RELEASE_SERIAL >= 1) ) )\n    Tk_InitConsoleChannels(ptr->ip);\n\n    if (Tk_CreateConsoleWindow(ptr->ip) != TCL_OK) {\n        rb_raise(rb_eRuntimeError, \"fail to create console-window\");\n    }\n#else\n#if defined(MAC_TCL) || defined(__WIN32__)\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 1 \\\n    && ( (TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE && TCL_RELEASE_SERIAL == 0) \\\n        || (TCL_RELEASE_LEVEL == TCL_BETA_RELEASE && TCL_RELEASE_SERIAL >= 2) )\n    TkConsoleCreate_();\n#else\n    TkConsoleCreate();\n#endif\n\n    if (TkConsoleInit(ptr->ip) != TCL_OK) {\n        rb_raise(rb_eRuntimeError, \"fail to create console-window\");\n    }\n#else\n    rb_notimplement();\n#endif\n#endif\n\n    return interp;\n}\n\nstatic VALUE\nip_create_console(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n    \n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    return tk_funcall(ip_create_console_core, 0, (VALUE*)NULL, self);\n}\n\n/* make ip \"safe\" */\nstatic VALUE\nip_make_safe_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;   /* dummy */\n    VALUE *argv;  /* dummy */\n{\n    struct tcltkip *ptr = get_ip(interp);\n    Tk_Window mainWin;\n    \n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return rb_exc_new2(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    if (Tcl_MakeSafe(ptr->ip) == TCL_ERROR) {\n        /* return rb_exc_new2(rb_eRuntimeError, \n                              Tcl_GetStringResult(ptr->ip)); */\n        return create_ip_exc(interp, rb_eRuntimeError, \n                             Tcl_GetStringResult(ptr->ip));\n    }\n\n    ptr->allow_ruby_exit = 0;\n\n    /* replace 'exit' command --> 'interp_exit' command */\n    mainWin = (tk_stubs_init_p())? Tk_MainWindow(ptr->ip): (Tk_Window)NULL;\n#if TCL_MAJOR_VERSION >= 8\n    DUMP1(\"Tcl_CreateObjCommand(\\\"exit\\\") --> \\\"interp_exit\\\"\");\n    Tcl_CreateObjCommand(ptr->ip, \"exit\", ip_InterpExitObjCmd, \n                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP1(\"Tcl_CreateCommand(\\\"exit\\\") --> \\\"interp_exit\\\"\");\n    Tcl_CreateCommand(ptr->ip, \"exit\", ip_InterpExitCommand, \n                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n\n    return interp;\n}\n\nstatic VALUE\nip_make_safe(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n    \n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    return tk_funcall(ip_make_safe_core, 0, (VALUE*)NULL, self);\n}\n\n/* is safe? */\nstatic VALUE\nip_is_safe_p(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n    \n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    if (Tcl_IsSafe(ptr->ip)) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n\n/* allow_ruby_exit? */\nstatic VALUE\nip_allow_ruby_exit_p(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n    \n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    if (ptr->allow_ruby_exit) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n\n/* allow_ruby_exit = mode */\nstatic VALUE\nip_allow_ruby_exit_set(self, val)\n    VALUE self, val;\n{\n    struct tcltkip *ptr = get_ip(self);\n    Tk_Window mainWin;\n\n    rb_secure(4);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    if (Tcl_IsSafe(ptr->ip)) {\n        rb_raise(rb_eSecurityError, \n                 \"insecure operation on a safe interpreter\");\n    }\n\n    /*\n     *  Because of cross-threading, the following line may fail to find \n     *  the MainWindow, even if the Tcl/Tk interpreter has one or more.\n     *  But it has no problem. Current implementation of both type of \n     *  the \"exit\" command don't need maiinWin token.\n     */\n    mainWin = (tk_stubs_init_p())? Tk_MainWindow(ptr->ip): (Tk_Window)NULL;\n\n    if (RTEST(val)) {\n        ptr->allow_ruby_exit = 1;\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"Tcl_CreateObjCommand(\\\"exit\\\") --> \\\"ruby_exit\\\"\");\n        Tcl_CreateObjCommand(ptr->ip, \"exit\", ip_RubyExitObjCmd, \n                             (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"Tcl_CreateCommand(\\\"exit\\\") --> \\\"ruby_exit\\\"\");\n        Tcl_CreateCommand(ptr->ip, \"exit\", ip_RubyExitCommand, \n                          (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n        return Qtrue;\n\n    } else {\n        ptr->allow_ruby_exit = 0;\n#if TCL_MAJOR_VERSION >= 8\n        DUMP1(\"Tcl_CreateObjCommand(\\\"exit\\\") --> \\\"interp_exit\\\"\");\n        Tcl_CreateObjCommand(ptr->ip, \"exit\", ip_InterpExitObjCmd, \n                             (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#else /* TCL_MAJOR_VERSION < 8 */\n        DUMP1(\"Tcl_CreateCommand(\\\"exit\\\") --> \\\"interp_exit\\\"\");\n        Tcl_CreateCommand(ptr->ip, \"exit\", ip_InterpExitCommand, \n                          (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);\n#endif\n        return Qfalse;\n    }\n}\n\n/* delete interpreter */\nstatic VALUE\nip_delete(self)\n    VALUE self;\n{\n    int  thr_crit_bup;\n    struct tcltkip *ptr = get_ip(self);\n\n    if (ptr == (struct tcltkip *)NULL || ptr->ip == (Tcl_Interp*)NULL) {\n        DUMP1(\"delete deleted IP\");\n        return Qnil;\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    DUMP1(\"call ip_finalize\");\n    ip_finalize(ptr->ip);\n\n    DUMP1(\"delete interp\");\n    Tcl_DeleteInterp(ptr->ip);\n    Tcl_Release(ptr->ip);\n\n    rb_thread_critical = thr_crit_bup;\n\n    return Qnil;\n}\n\n\n/* is deleted? */\nstatic VALUE\nip_has_invalid_namespace_p(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    if (ptr == (struct tcltkip *)NULL || ptr->ip == (Tcl_Interp *)NULL) {\n        /* deleted IP */\n        return Qtrue;\n    }\n\n#if TCL_NAMESPACE_DEBUG\n    if (rbtk_invalid_namespace(ptr)) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n#else\n    return Qfalse;\n#endif\n}\n\nstatic VALUE\nip_is_deleted_p(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    if (deleted_ip(ptr)) {\n        return Qtrue;\n    } else {\n        return Qfalse;\n    }\n}\n\nstatic VALUE\nip_has_mainwindow_p_core(self, argc, argv)\n    VALUE self;\n    int   argc;   /* dummy */\n    VALUE *argv;  /* dummy */\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    if (deleted_ip(ptr) || !tk_stubs_init_p()) {\n        return Qnil;\n    } else if (Tk_MainWindow(ptr->ip) == (Tk_Window)NULL) {\n        return Qfalse;\n    } else {\n        return Qtrue;\n    }\n}\n\nstatic VALUE\nip_has_mainwindow_p(self)\n    VALUE self;\n{\n    return tk_funcall(ip_has_mainwindow_p_core, 0, (VALUE*)NULL, self);\n}\n\n\n/*** ruby string <=> tcl object ***/\n#if TCL_MAJOR_VERSION >= 8\nstatic VALUE\nget_str_from_obj(obj)\n    Tcl_Obj *obj;\n{\n    int len, binary = 0;\n    const char *s;\n    volatile VALUE str;\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 4)\n    int len2;\n    const char *s2;\n#endif\n\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0\n    s = Tcl_GetStringFromObj(obj, &len);\n#else\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION <= 3\n     /* TCL_VERSION 8.1 -- 8.3 */\n    if (Tcl_GetCharLength(obj) != Tcl_UniCharLen(Tcl_GetUnicode(obj))) {\n        /* possibly binary string */\n        s = Tcl_GetByteArrayFromObj(obj, &len);\n        binary = 1;\n    } else {\n        /* possibly text string */\n        s = Tcl_GetStringFromObj(obj, &len);\n    }\n#else /* TCL_VERSION >= 8.4 */\n    if (IS_TCL_BYTEARRAY(obj)) {\n      s = Tcl_GetByteArrayFromObj(obj, &len);\n      binary = 1;\n    } else {\n      s = Tcl_GetStringFromObj(obj, &len);\n    }\n\n#endif\n#endif\n    str = s ? rb_str_new(s, len) : rb_str_new2(\"\");\n    if (binary) {\n#ifdef RUBY_VM\n      rb_enc_associate_index(str, ENCODING_INDEX_BINARY);\n#endif\n      rb_ivar_set(str, ID_at_enc, ENCODING_NAME_BINARY);\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)\n    } else {\n#ifdef RUBY_VM\n      rb_enc_associate_index(str, ENCODING_INDEX_UTF8);\n#endif\n      rb_ivar_set(str, ID_at_enc, ENCODING_NAME_UTF8);\n#endif\n    }\n    return str;\n}\n\nstatic Tcl_Obj *\nget_obj_from_str(str)\n    VALUE str;\n{\n    const char *s = StringValuePtr(str);\n\n#if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0\n    return Tcl_NewStringObj((char*)s, RSTRING_LEN(str));\n#else /* TCL_VERSION >= 8.1 */\n    VALUE enc = rb_attr_get(str, ID_at_enc);\n\n    if (!NIL_P(enc)) {\n        StringValue(enc);\n        if (strcmp(RSTRING_PTR(enc), \"binary\") == 0) {\n            /* binary string */\n            return Tcl_NewByteArrayObj(s, RSTRING_LEN(str));\n        } else {\n            /* text string */\n            return Tcl_NewStringObj(s, RSTRING_LEN(str));\n        }\n#ifdef RUBY_VM\n    } else if (rb_enc_get_index(str) == ENCODING_INDEX_BINARY) {\n        /* binary string */\n        return Tcl_NewByteArrayObj(s, RSTRING_LEN(str));\n#endif\n    } else if (strlen(s) != RSTRING_LEN(str)) {\n        /* probably binary string */\n        return Tcl_NewByteArrayObj(s, RSTRING_LEN(str));\n    } else {\n        /* probably text string */\n        return Tcl_NewStringObj(s, RSTRING_LEN(str));\n    }\n#endif\n}\n#endif /* ruby string <=> tcl object */\n\nstatic VALUE\nip_get_result_string_obj(interp)\n    Tcl_Interp *interp;\n{\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj *retObj;\n    volatile VALUE strval;\n\n    retObj = Tcl_GetObjResult(interp);\n    Tcl_IncrRefCount(retObj);\n    strval = get_str_from_obj(retObj);\n    OBJ_TAINT(strval);\n    Tcl_ResetResult(interp);\n    Tcl_DecrRefCount(retObj);\n    return strval;\n#else\n    return rb_tainted_str_new2(interp->result);\n#endif\n}\n\n/* call Tcl/Tk functions on the eventloop thread */\nstatic VALUE\ncallq_safelevel_handler(arg, callq)\n    VALUE arg;\n    VALUE callq;\n{\n    struct call_queue *q;\n\n    Data_Get_Struct(callq, struct call_queue, q);\n    DUMP2(\"(safe-level handler) $SAFE = %d\", q->safe_level);\n    rb_set_safe_level(q->safe_level);\n    return((q->func)(q->interp, q->argc, q->argv));\n}\n\nstatic int call_queue_handler _((Tcl_Event *, int));\nstatic int\ncall_queue_handler(evPtr, flags)\n    Tcl_Event *evPtr;\n    int flags;\n{\n    struct call_queue *q = (struct call_queue *)evPtr;\n    volatile VALUE ret;\n    volatile VALUE q_dat;\n    volatile VALUE thread = q->thread;\n    struct tcltkip *ptr;\n\n    DUMP2(\"do_call_queue_handler : evPtr = %p\", evPtr);\n    DUMP2(\"call_queue_handler thread : %lx\", rb_thread_current());\n    DUMP2(\"added by thread : %lx\", thread);\n\n    if (*(q->done)) {\n        DUMP1(\"processed by another event-loop\");\n        return 0;\n    } else {\n        DUMP1(\"process it on current event-loop\");\n    }\n\n    if (RTEST(rb_thread_alive_p(thread)) \n\t&& ! RTEST(rb_funcall(thread, ID_stop_p, 0))) {\n      DUMP1(\"caller is not yet ready to receive the result -> pending\");\n      return 0;\n    }\n\n    /* process it */\n    *(q->done) = 1;\n\n    /* deleted ipterp ? */\n    ptr = get_ip(q->interp);\n    if (deleted_ip(ptr)) {\n        /* deleted IP --> ignore */\n        return 1;\n    }\n\n    /* incr internal handler mark */\n    rbtk_internal_eventloop_handler++;\n\n    /* check safe-level */\n    if (rb_safe_level() != q->safe_level) {\n        /* q_dat = Data_Wrap_Struct(rb_cData,0,-1,q); */\n        q_dat = Data_Wrap_Struct(rb_cData,call_queue_mark,-1,q);\n        ret = rb_funcall(rb_proc_new(callq_safelevel_handler, q_dat), \n                         ID_call, 0);\n        rb_gc_force_recycle(q_dat);\n\tq_dat = (VALUE)NULL;\n    } else {\n        DUMP2(\"call function (for caller thread:%lx)\", thread);\n        DUMP2(\"call function (current thread:%lx)\", rb_thread_current());\n        ret = (q->func)(q->interp, q->argc, q->argv);\n    }\n\n    /* set result */\n    RARRAY_PTR(q->result)[0] = ret;\n    ret = (VALUE)NULL;\n\n    /* decr internal handler mark */\n    rbtk_internal_eventloop_handler--;\n\n    /* complete */\n    *(q->done) = -1;\n\n    /* unlink ruby objects */\n    q->argv = (VALUE*)NULL;\n    q->interp = (VALUE)NULL;\n    q->result = (VALUE)NULL;\n    q->thread = (VALUE)NULL;\n\n    /* back to caller */\n    /* if (RTEST(rb_funcall(thread, ID_alive_p, 0, 0))) { */\n    if (RTEST(rb_thread_alive_p(thread))) {\n      DUMP2(\"back to caller (caller thread:%lx)\", thread);\n      DUMP2(\"               (current thread:%lx)\", rb_thread_current());\n#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE\n      have_rb_thread_waiting_for_value = 1;\n      rb_thread_wakeup(thread);\n#else\n      rb_thread_run(thread);\n#endif\n      DUMP1(\"finish back to caller\");\n#if DO_THREAD_SCHEDULE_AT_CALLBACK_DONE\n      rb_thread_schedule();\n#endif\n    } else {\n      DUMP2(\"caller is dead (caller thread:%lx)\", thread);\n      DUMP2(\"               (current thread:%lx)\", rb_thread_current());\n    }\n\n    /* end of handler : remove it */\n    return 1;\n}\n\nstatic VALUE\ntk_funcall(func, argc, argv, obj)\n    VALUE (*func)();\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct call_queue *callq;\n    struct tcltkip *ptr;\n    int  *alloc_done;\n    int  thr_crit_bup;\n    int  is_tk_evloop_thread;\n    volatile VALUE current = rb_thread_current();\n    volatile VALUE ip_obj = obj;\n    volatile VALUE result;\n    volatile VALUE ret;\n\n    if (!NIL_P(ip_obj) && rb_obj_is_kind_of(ip_obj, tcltkip_class)) {\n        ptr = get_ip(ip_obj);\n        if (deleted_ip(ptr)) return Qnil;\n    } else {\n        ptr = (struct tcltkip *)NULL;\n    }\n\n#ifdef RUBY_VM\n    if (ptr) {\n      /* on Tcl interpreter */\n      is_tk_evloop_thread = (ptr->tk_thread_id == (Tcl_ThreadId) 0 \n\t\t\t     || ptr->tk_thread_id == Tcl_GetCurrentThread());\n    } else {\n      /* on Tcl/Tk library */\n      is_tk_evloop_thread = (tk_eventloop_thread_id == (Tcl_ThreadId) 0 \n\t\t\t     || tk_eventloop_thread_id == Tcl_GetCurrentThread());\n    }\n#else\n    is_tk_evloop_thread = 1;\n#endif\n\n    if (is_tk_evloop_thread\n\t&& (NIL_P(eventloop_thread) || current == eventloop_thread)\n        ) {\n        if (NIL_P(eventloop_thread)) {\n            DUMP2(\"tk_funcall from thread:%lx but no eventloop\", current);\n        } else {\n            DUMP2(\"tk_funcall from current eventloop %lx\", current);\n        }\n        result = (func)(ip_obj, argc, argv);\n        if (rb_obj_is_kind_of(result, rb_eException)) {\n            rb_exc_raise(result);\n        }\n        return result;\n    }\n\n    DUMP2(\"tk_funcall from thread %lx (NOT current eventloop)\", current);\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* allocate memory (argv cross over thread : must be in heap) */\n    if (argv) {\n        /* VALUE *temp = ALLOC_N(VALUE, argc); */\n        VALUE *temp = (VALUE*)ckalloc(sizeof(VALUE) * argc);\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)temp); /* XXXXXXXX */\n#endif\n        MEMCPY(temp, argv, VALUE, argc);\n        argv = temp;\n    }\n\n    /* allocate memory (keep result) */\n    /* alloc_done = (int*)ALLOC(int); */\n    alloc_done = (int*)ckalloc(sizeof(int));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */\n#endif\n    *alloc_done = 0;\n\n    /* allocate memory (freed by Tcl_ServiceEvent) */\n    /* callq = (struct call_queue *)Tcl_Alloc(sizeof(struct call_queue)); */\n    callq = (struct call_queue *)ckalloc(sizeof(struct call_queue));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve(callq);\n#endif\n\n    /* allocate result obj */\n    result = rb_ary_new3(1, Qnil);\n\n    /* construct event data */\n    callq->done = alloc_done;\n    callq->func = func;\n    callq->argc = argc;\n    callq->argv = argv;\n    callq->interp = ip_obj;\n    callq->result = result;\n    callq->thread = current;\n    callq->safe_level = rb_safe_level();\n    callq->ev.proc = call_queue_handler;\n\n    /* add the handler to Tcl event queue */\n    DUMP1(\"add handler\");\n#ifdef RUBY_VM\n    if (ptr && ptr->tk_thread_id) {\n      /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, \n\t\t\t   &(callq->ev), TCL_QUEUE_HEAD); */\n      Tcl_ThreadQueueEvent(ptr->tk_thread_id, \n\t\t\t   (Tcl_Event*)callq, TCL_QUEUE_HEAD);\n      Tcl_ThreadAlert(ptr->tk_thread_id);\n    } else if (tk_eventloop_thread_id) {\n      /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, \n\t\t\t   &(callq->ev), TCL_QUEUE_HEAD); */\n      Tcl_ThreadQueueEvent(tk_eventloop_thread_id, \n\t\t\t   (Tcl_Event*)callq, TCL_QUEUE_HEAD);\n      Tcl_ThreadAlert(tk_eventloop_thread_id);\n    } else {\n      /* Tcl_QueueEvent(&(callq->ev), TCL_QUEUE_HEAD); */\n      Tcl_QueueEvent((Tcl_Event*)callq, TCL_QUEUE_HEAD);\n    }\n#else\n    /* Tcl_QueueEvent(&(callq->ev), TCL_QUEUE_HEAD); */\n    Tcl_QueueEvent((Tcl_Event*)callq, TCL_QUEUE_HEAD);\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n\n    /* wait for the handler to be processed */\n    DUMP2(\"wait for handler (current thread:%lx)\", current);\n    while(*alloc_done >= 0) {\n      DUMP2(\"*** wait for handler (current thread:%lx)\", current);\n      /* rb_thread_stop(); */\n      rb_thread_sleep_forever();\n      DUMP2(\"*** wakeup (current thread:%lx)\", current);\n    }\n    DUMP2(\"back from handler (current thread:%lx)\", current);\n\n    /* get result & free allocated memory */\n    ret = RARRAY_PTR(result)[0];\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)alloc_done, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */\n#else\n    /* free(alloc_done); */\n    ckfree((char*)alloc_done);\n#endif\n#endif\n    /* if (argv) free(argv); */\n    if (argv) {\n      /* if argv != NULL, alloc as 'temp' */\n      int i;\n      for(i = 0; i < argc; i++) { argv[i] = (VALUE)NULL; }\n\n#if 0 /* use Tcl_EventuallyFree */\n      Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n      Tcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n      ckfree((char*)argv);\n#endif\n#endif\n    }\n\n#if 0 /* callq is freed by Tcl_ServiceEvent */\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release(callq);\n#else\n    ckfree((char*)callq);\n#endif\n#endif\n\n    /* exception? */\n    if (rb_obj_is_kind_of(ret, rb_eException)) {\n        DUMP1(\"raise exception\");\n        /* rb_exc_raise(ret); */\n\trb_exc_raise(rb_exc_new3(rb_obj_class(ret), \n\t\t\t\t rb_funcall(ret, ID_to_s, 0, 0)));\n    }\n\n    DUMP1(\"exit tk_funcall\");\n    return ret;\n}\n\n\n/* eval string in tcl by Tcl_Eval() */\n#if TCL_MAJOR_VERSION >= 8\nstruct call_eval_info {\n    struct tcltkip *ptr;\n    Tcl_Obj *cmd;\n};\n\nstatic VALUE\ncall_tcl_eval(arg)\n    VALUE arg;\n{\n    struct call_eval_info *inf = (struct call_eval_info *)arg;\n\n    Tcl_AllowExceptions(inf->ptr->ip);\n    inf->ptr->return_value = Tcl_EvalObj(inf->ptr->ip, inf->cmd);\n\n    return Qnil;\n}\n#endif\n\nstatic VALUE\nip_eval_real(self, cmd_str, cmd_len)\n    VALUE self;\n    char *cmd_str;\n    int  cmd_len;\n{\n    volatile VALUE ret;\n    struct tcltkip *ptr = get_ip(self);\n    int thr_crit_bup;\n\n#if TCL_MAJOR_VERSION >= 8\n    /* call Tcl_EvalObj() */\n    {\n      Tcl_Obj *cmd;\n\n      thr_crit_bup = rb_thread_critical;\n      rb_thread_critical = Qtrue;\n\n      cmd = Tcl_NewStringObj(cmd_str, cmd_len);\n      Tcl_IncrRefCount(cmd);\n\n      /* ip is deleted? */\n      if (deleted_ip(ptr)) {\n          Tcl_DecrRefCount(cmd);\n          rb_thread_critical = thr_crit_bup;\n          ptr->return_value = TCL_OK;\n          return rb_tainted_str_new2(\"\");\n      } else {\n          int status;\n          struct call_eval_info inf;\n\n          /* Tcl_Preserve(ptr->ip); */\n          rbtk_preserve_ip(ptr);\n\n#if 0\n          ptr->return_value = Tcl_EvalObj(ptr->ip, cmd);\n          /* ptr->return_value = Tcl_GlobalEvalObj(ptr->ip, cmd); */\n#else\n          inf.ptr = ptr;\n          inf.cmd = cmd;\n          ret = rb_protect(call_tcl_eval, (VALUE)&inf, &status);\n          switch(status) {\n          case TAG_RAISE:\n#ifdef RUBY_VM\n              if (NIL_P(rb_errinfo())) {\n#else\n              if (NIL_P(ruby_errinfo)) {\n#endif\n                  rbtk_pending_exception = rb_exc_new2(rb_eException, \n                                                       \"unknown exception\");\n              } else {\n#ifdef RUBY_VM\n                  rbtk_pending_exception = rb_errinfo();\n#else\n                  rbtk_pending_exception = ruby_errinfo;\n#endif\n              }\n              break;\n\n          case TAG_FATAL:\n#ifdef RUBY_VM\n              if (NIL_P(rb_errinfo())) {\n#else\n              if (NIL_P(ruby_errinfo)) {\n#endif\n                  rbtk_pending_exception = rb_exc_new2(rb_eFatal, \"FATAL\");\n              } else {\n#ifdef RUBY_VM\n                  rbtk_pending_exception = rb_errinfo();\n#else\n                  rbtk_pending_exception = ruby_errinfo;\n#endif\n              }\n          }\n#endif\n      }\n\n      Tcl_DecrRefCount(cmd);\n\n    }\n\n    if (pending_exception_check1(thr_crit_bup, ptr)) {\n        rbtk_release_ip(ptr);\n        return rbtk_pending_exception;\n    }\n\n    if (ptr->return_value == TCL_ERROR) {\n        if (event_loop_abort_on_exc > 0 && !Tcl_InterpDeleted(ptr->ip)) {\n            volatile VALUE exc;\n            exc = create_ip_exc(self, rb_eRuntimeError, \n                                \"%s\", Tcl_GetStringResult(ptr->ip));\n            rbtk_release_ip(ptr);\n            rb_thread_critical = thr_crit_bup;\n            return exc;\n        } else {\n            if (event_loop_abort_on_exc < 0) {\n                rb_warning(\"%s (ignore)\", Tcl_GetStringResult(ptr->ip));\n            } else {\n                rb_warn(\"%s (ignore)\", Tcl_GetStringResult(ptr->ip));\n            }\n            Tcl_ResetResult(ptr->ip);\n            rbtk_release_ip(ptr);\n            rb_thread_critical = thr_crit_bup;\n            return rb_tainted_str_new2(\"\");\n        }\n    }\n\n    /* pass back the result (as string) */\n    ret =  ip_get_result_string_obj(ptr->ip);\n    rbtk_release_ip(ptr);\n    rb_thread_critical = thr_crit_bup;\n    return ret;\n\n#else /* TCL_MAJOR_VERSION < 8 */\n    DUMP2(\"Tcl_Eval(%s)\", cmd_str);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        ptr->return_value = TCL_OK;\n        return rb_tainted_str_new2(\"\");\n    } else {\n        /* Tcl_Preserve(ptr->ip); */\n        rbtk_preserve_ip(ptr);\n        ptr->return_value = Tcl_Eval(ptr->ip, cmd_str);\n        /* ptr->return_value = Tcl_GlobalEval(ptr->ip, cmd_str); */\n    }\n\n    if (pending_exception_check1(thr_crit_bup, ptr)) {\n        rbtk_release_ip(ptr);\n        return rbtk_pending_exception;\n    }\n\n    if (ptr->return_value == TCL_ERROR) {\n        volatile VALUE exc;\n\n        exc = create_ip_exc(self, rb_eRuntimeError, \"%s\", ptr->ip->result);\n\n        rbtk_release_ip(ptr);\n        return exc;\n    }\n    DUMP2(\"(TCL_Eval result) %d\", ptr->return_value);\n\n    /* pass back the result (as string) */\n    ret =  ip_get_result_string_obj(ptr->ip);\n    rbtk_release_ip(ptr);\n    return ret;\n#endif\n}\n\nstatic VALUE\nevq_safelevel_handler(arg, evq)\n    VALUE arg;\n    VALUE evq;\n{\n    struct eval_queue *q;\n\n    Data_Get_Struct(evq, struct eval_queue, q);\n    DUMP2(\"(safe-level handler) $SAFE = %d\", q->safe_level);\n    rb_set_safe_level(q->safe_level);\n    return ip_eval_real(q->interp, q->str, q->len);\n}\n\nint eval_queue_handler _((Tcl_Event *, int));\nint\neval_queue_handler(evPtr, flags)\n    Tcl_Event *evPtr;\n    int flags;\n{\n    struct eval_queue *q = (struct eval_queue *)evPtr;\n    volatile VALUE ret;\n    volatile VALUE q_dat;\n    volatile VALUE thread = q->thread;\n    struct tcltkip *ptr;\n\n    DUMP2(\"do_eval_queue_handler : evPtr = %p\", evPtr);\n    DUMP2(\"eval_queue_thread : %lx\", rb_thread_current());\n    DUMP2(\"added by thread : %lx\", thread);\n\n    if (*(q->done)) {\n        DUMP1(\"processed by another event-loop\");\n        return 0;\n    } else {\n        DUMP1(\"process it on current event-loop\");\n    }\n\n    if (RTEST(rb_thread_alive_p(thread)) \n\t&& ! RTEST(rb_funcall(thread, ID_stop_p, 0))) {\n      DUMP1(\"caller is not yet ready to receive the result -> pending\");\n      return 0;\n    }\n\n    /* process it */\n    *(q->done) = 1;\n\n    /* deleted ipterp ? */\n    ptr = get_ip(q->interp);\n    if (deleted_ip(ptr)) {\n        /* deleted IP --> ignore */\n        return 1;\n    }\n\n    /* incr internal handler mark */\n    rbtk_internal_eventloop_handler++;\n\n    /* check safe-level */\n    if (rb_safe_level() != q->safe_level) {\n#ifdef HAVE_NATIVETHREAD\n#ifdef RUBY_VM\n#if 0\n    if (!ruby_native_thread_p()) {\n      rb_bug(\"cross-thread violation on eval_queue_handler()\");\n    }\n#endif\n#else\n    if (!is_ruby_native_thread()) {\n      rb_bug(\"cross-thread violation on eval_queue_handler()\");\n    }\n#endif\n#endif\n        /* q_dat = Data_Wrap_Struct(rb_cData,0,-1,q); */\n        q_dat = Data_Wrap_Struct(rb_cData,eval_queue_mark,-1,q);\n        ret = rb_funcall(rb_proc_new(evq_safelevel_handler, q_dat), \n                         ID_call, 0);\n        rb_gc_force_recycle(q_dat);\n\tq_dat = (VALUE)NULL;\n    } else {\n        ret = ip_eval_real(q->interp, q->str, q->len);\n    }\n\n    /* set result */\n    RARRAY_PTR(q->result)[0] = ret;\n    ret = (VALUE)NULL;\n\n    /* decr internal handler mark */\n    rbtk_internal_eventloop_handler--;\n\n    /* complete */\n    *(q->done) = -1;\n\n    /* unlink ruby objects */\n    q->interp = (VALUE)NULL;\n    q->result = (VALUE)NULL;\n    q->thread = (VALUE)NULL;\n\n    /* back to caller */\n    /* if (RTEST(rb_funcall(thread, ID_alive_p, 0, 0))) { */\n    if (RTEST(rb_thread_alive_p(thread))) {\n      DUMP2(\"back to caller (caller thread:%lx)\", thread);\n      DUMP2(\"               (current thread:%lx)\", rb_thread_current());\n#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE\n      have_rb_thread_waiting_for_value = 1;\n      rb_thread_wakeup(thread);\n#else\n      rb_thread_run(thread);\n#endif\n      DUMP1(\"finish back to caller\");\n#if DO_THREAD_SCHEDULE_AT_CALLBACK_DONE\n      rb_thread_schedule();\n#endif\n    } else {\n      DUMP2(\"caller is dead (caller thread:%lx)\", thread);\n      DUMP2(\"               (current thread:%lx)\", rb_thread_current());\n    }\n\n    /* end of handler : remove it */\n    return 1;\n}\n\nstatic VALUE\nip_eval(self, str)\n    VALUE self;\n    VALUE str;\n{\n    struct eval_queue *evq;\n#ifdef RUBY_VM\n    struct tcltkip *ptr;\n#endif\n    char *eval_str;\n    int  *alloc_done;\n    int  thr_crit_bup;\n    volatile VALUE current = rb_thread_current();\n    volatile VALUE ip_obj = self;\n    volatile VALUE result;\n    volatile VALUE ret;\n    Tcl_QueuePosition position;\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n    StringValue(str);\n    rb_thread_critical = thr_crit_bup;\n\n#ifdef RUBY_VM\n    ptr = get_ip(ip_obj);\n#endif\n\n    if (\n#ifdef RUBY_VM\n\t(ptr->tk_thread_id == 0 || ptr->tk_thread_id == Tcl_GetCurrentThread())\n\t&& \n#endif\n\t(NIL_P(eventloop_thread) || current == eventloop_thread)\n\t) {\n        if (NIL_P(eventloop_thread)) {\n            DUMP2(\"eval from thread:%lx but no eventloop\", current);\n        } else {\n            DUMP2(\"eval from current eventloop %lx\", current);\n        }\n        result = ip_eval_real(self, RSTRING_PTR(str), RSTRING_LEN(str));\n        if (rb_obj_is_kind_of(result, rb_eException)) {\n            rb_exc_raise(result);\n        }\n        return result;\n    }\n\n    DUMP2(\"eval from thread %lx (NOT current eventloop)\", current);\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* allocate memory (keep result) */\n    /* alloc_done = (int*)ALLOC(int); */\n    alloc_done = (int*)ckalloc(sizeof(int));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */\n#endif\n    *alloc_done = 0;\n\n    /* eval_str = ALLOC_N(char, RSTRING_LEN(str) + 1); */\n    eval_str = ckalloc(sizeof(char) * (RSTRING_LEN(str) + 1));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)eval_str); /* XXXXXXXX */\n#endif\n    memcpy(eval_str, RSTRING_PTR(str), RSTRING_LEN(str));\n    eval_str[RSTRING_LEN(str)] = 0;\n\n    /* allocate memory (freed by Tcl_ServiceEvent) */\n    /* evq = (struct eval_queue *)Tcl_Alloc(sizeof(struct eval_queue)); */\n    evq = (struct eval_queue *)ckalloc(sizeof(struct eval_queue));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve(evq);\n#endif\n\n    /* allocate result obj */\n    result = rb_ary_new3(1, Qnil);\n\n    /* construct event data */\n    evq->done = alloc_done;\n    evq->str = eval_str;\n    evq->len = RSTRING_LEN(str);\n    evq->interp = ip_obj;\n    evq->result = result;\n    evq->thread = current;\n    evq->safe_level = rb_safe_level();\n    evq->ev.proc = eval_queue_handler;\n\n    position = TCL_QUEUE_TAIL;\n\n    /* add the handler to Tcl event queue */\n    DUMP1(\"add handler\");\n#ifdef RUBY_VM\n    if (ptr->tk_thread_id) {\n      /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(evq->ev), position); */\n      Tcl_ThreadQueueEvent(ptr->tk_thread_id, (Tcl_Event*)evq, position);\n      Tcl_ThreadAlert(ptr->tk_thread_id);\n    } else if (tk_eventloop_thread_id) {\n      Tcl_ThreadQueueEvent(tk_eventloop_thread_id, (Tcl_Event*)evq, position);\n      /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, \n\t\t\t   &(evq->ev), position); */\n      Tcl_ThreadAlert(tk_eventloop_thread_id);\n    } else {\n      /* Tcl_QueueEvent(&(evq->ev), position); */\n      Tcl_QueueEvent((Tcl_Event*)evq, position);\n    }\n#else\n    /* Tcl_QueueEvent(&(evq->ev), position); */\n    Tcl_QueueEvent((Tcl_Event*)evq, position);\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n\n    /* wait for the handler to be processed */\n    DUMP2(\"wait for handler (current thread:%lx)\", current);\n    while(*alloc_done >= 0) {\n      DUMP2(\"*** wait for handler (current thread:%lx)\", current);\n      /* rb_thread_stop(); */\n      rb_thread_sleep_forever();\n      DUMP2(\"*** wakeup (current thread:%lx)\", current);\n    }\n    DUMP2(\"back from handler (current thread:%lx)\", current);\n\n    /* get result & free allocated memory */\n    ret = RARRAY_PTR(result)[0];\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)alloc_done, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */\n#else\n    /* free(alloc_done); */\n    ckfree((char*)alloc_done);\n#endif\n#endif\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)eval_str, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)eval_str); /* XXXXXXXX */\n#else\n    /* free(eval_str); */\n    ckfree(eval_str);\n#endif\n#endif\n#if 0 /* evq is freed by Tcl_ServiceEvent */\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release(evq);\n#else\n    ckfree((char*)evq);\n#endif\n#endif\n\n    if (rb_obj_is_kind_of(ret, rb_eException)) {\n        DUMP1(\"raise exception\");\n        /* rb_exc_raise(ret); */\n\trb_exc_raise(rb_exc_new3(rb_obj_class(ret), \n\t\t\t\t rb_funcall(ret, ID_to_s, 0, 0)));\n    }\n\n    return ret;\n}\n\n\n/* restart Tk */\nstatic VALUE\nlib_restart_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;   /* dummy */\n    VALUE *argv;  /* dummy */\n{\n    volatile VALUE exc;\n    struct tcltkip *ptr = get_ip(interp);\n    int  thr_crit_bup;\n\n    /* rb_secure(4); */ /* already checked */\n\n    /* tcl_stubs_check(); */ /* already checked */\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return rb_exc_new2(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* Tcl_Preserve(ptr->ip); */\n    rbtk_preserve_ip(ptr);\n\n    /* destroy the root wdiget */\n    ptr->return_value = Tcl_Eval(ptr->ip, \"destroy .\");\n    /* ignore ERROR */\n    DUMP2(\"(TCL_Eval result) %d\", ptr->return_value);\n    Tcl_ResetResult(ptr->ip);\n\n#if TCL_MAJOR_VERSION >= 8\n    /* delete namespace ( tested on tk8.4.5 ) */\n    ptr->return_value = Tcl_Eval(ptr->ip, \"namespace delete ::tk::msgcat\");\n    /* ignore ERROR */\n    DUMP2(\"(TCL_Eval result) %d\", ptr->return_value);\n    Tcl_ResetResult(ptr->ip);\n#endif\n\n    /* delete trace proc ( tested on tk8.4.5 ) */\n    ptr->return_value = Tcl_Eval(ptr->ip, \"trace vdelete ::tk_strictMotif w ::tk::EventMotifBindings\");\n    /* ignore ERROR */\n    DUMP2(\"(TCL_Eval result) %d\", ptr->return_value);\n    Tcl_ResetResult(ptr->ip);\n\n    /* execute Tk_Init or Tk_SafeInit */\n    exc = tcltkip_init_tk(interp);\n    if (!NIL_P(exc)) {\n        rb_thread_critical = thr_crit_bup;\n        rbtk_release_ip(ptr);\n        return exc;\n    }\n\n    /* Tcl_Release(ptr->ip); */\n    rbtk_release_ip(ptr);\n\n    rb_thread_critical = thr_crit_bup;\n\n    /* return Qnil; */\n    return interp;\n}\n\nstatic VALUE\nlib_restart(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    rb_secure(4);\n\n    tcl_stubs_check();\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    return tk_funcall(lib_restart_core, 0, (VALUE*)NULL, self);\n}\n\n\nstatic VALUE\nip_restart(self)\n    VALUE self;\n{\n    struct tcltkip *ptr = get_ip(self);\n\n    rb_secure(4);\n\n    tcl_stubs_check();\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        rb_raise(rb_eRuntimeError, \"interpreter is deleted\");\n    }\n\n    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {\n        /* slave IP */\n        return Qnil;\n    }\n    return lib_restart(self);\n}\n\nstatic VALUE\nlib_toUTF8_core(ip_obj, src, encodename)\n    VALUE ip_obj;\n    VALUE src;\n    VALUE encodename;\n{\n    volatile VALUE str = src;\n\n#ifdef TCL_UTF_MAX\n    Tcl_Interp *interp;\n    Tcl_Encoding encoding;\n    Tcl_DString dstr;\n    int taint_flag = OBJ_TAINTED(str);\n    struct tcltkip *ptr;\n    char *buf;\n    int thr_crit_bup;\n#endif\n\n    tcl_stubs_check();\n\n    if (NIL_P(src)) {\n      return rb_str_new2(\"\");\n    }\n\n#ifdef TCL_UTF_MAX\n    if (NIL_P(ip_obj)) {\n        interp = (Tcl_Interp *)NULL;\n    } else {\n        ptr = get_ip(ip_obj);\n\n        /* ip is deleted? */\n        if (deleted_ip(ptr)) {\n            interp = (Tcl_Interp *)NULL;\n        } else {\n            interp = ptr->ip;\n        }\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    if (NIL_P(encodename)) {\n        if (TYPE(str) == T_STRING) {\n            volatile VALUE enc;\n\n#ifdef RUBY_VM\n            enc = rb_funcall(rb_obj_encoding(str), ID_to_s, 0, 0);\n#else\n            enc = rb_attr_get(str, ID_at_enc);\n#endif\n            if (NIL_P(enc)) {\n                if (NIL_P(ip_obj)) {\n                    encoding = (Tcl_Encoding)NULL;\n                } else {\n                    enc = rb_attr_get(ip_obj, ID_at_enc);\n                    if (NIL_P(enc)) {\n                        encoding = (Tcl_Encoding)NULL;\n                    } else {\n                        /* StringValue(enc); */\n                        enc = rb_funcall(enc, ID_to_s, 0, 0);\n                        /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */\n\t\t\tif (!RSTRING_LEN(enc)) {\n\t\t\t  encoding = (Tcl_Encoding)NULL;\n\t\t\t} else {\n\t\t\t  encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, \n\t\t\t\t\t\t     RSTRING_PTR(enc));\n\t\t\t  if (encoding == (Tcl_Encoding)NULL) {\n                            rb_warning(\"Tk-interp has unknown encoding information (@encoding:'%s')\", RSTRING_PTR(enc));\n\t\t\t  }\n\t\t\t}\n                    }\n                }\n            } else {\n                StringValue(enc);\n                if (strcmp(RSTRING_PTR(enc), \"binary\") == 0) {\n#ifdef RUBY_VM\n\t\t    rb_enc_associate_index(str, ENCODING_INDEX_BINARY);\n#endif\n\t\t    rb_ivar_set(str, ID_at_enc, ENCODING_NAME_BINARY);\n                    rb_thread_critical = thr_crit_bup;\n                    return str;\n                }\n                /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */\n                encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, \n\t\t\t\t\t   RSTRING_PTR(enc));\n                if (encoding == (Tcl_Encoding)NULL) {\n                    rb_warning(\"string has unknown encoding information (@encoding:'%s')\", RSTRING_PTR(enc));\n                }\n            }\n        } else {\n            encoding = (Tcl_Encoding)NULL;\n        }\n    } else {\n        StringValue(encodename);\n\tif (strcmp(RSTRING_PTR(encodename), \"binary\") == 0) {\n#ifdef RUBY_VM\n\t  rb_enc_associate_index(str, ENCODING_INDEX_BINARY);\n#endif\n\t  rb_ivar_set(str, ID_at_enc, ENCODING_NAME_BINARY);\n\t  rb_thread_critical = thr_crit_bup;\n\t  return str;\n\t}\n        /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(encodename)); */\n        encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, RSTRING_PTR(encodename));\n        if (encoding == (Tcl_Encoding)NULL) {\n            /*\n            rb_warning(\"unknown encoding name '%s'\", \n                       RSTRING_PTR(encodename));\n            */\n            rb_raise(rb_eArgError, \"unknown encoding name '%s'\", \n                     RSTRING_PTR(encodename));\n        }\n    }\n\n    StringValue(str);\n    if (!RSTRING_LEN(str)) {\n        rb_thread_critical = thr_crit_bup;\n        return str;\n    }\n    buf = ALLOC_N(char, RSTRING_LEN(str)+1);\n    /* buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1)); */\n    memcpy(buf, RSTRING_PTR(str), RSTRING_LEN(str));\n    buf[RSTRING_LEN(str)] = 0;\n\n    Tcl_DStringInit(&dstr);\n    Tcl_DStringFree(&dstr);\n    /* Tcl_ExternalToUtfDString(encoding,buf,strlen(buf),&dstr); */\n    Tcl_ExternalToUtfDString(encoding, buf, RSTRING_LEN(str), &dstr);\n\n    /* str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); */\n    /* str = rb_str_new2(Tcl_DStringValue(&dstr)); */\n    str = rb_str_new(Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr));\n#ifdef RUBY_VM\n    rb_enc_associate_index(str, ENCODING_INDEX_UTF8);\n#endif\n    rb_ivar_set(str, ID_at_enc, ENCODING_NAME_UTF8);\n    if (taint_flag) OBJ_TAINT(str);\n\n    /*\n    if (encoding != (Tcl_Encoding)NULL) {\n        Tcl_FreeEncoding(encoding);\n    }\n    */\n    Tcl_DStringFree(&dstr);\n\n    free(buf);\n    /* ckfree(buf); */\n\n    rb_thread_critical = thr_crit_bup;\n#endif\n\n    return str;\n}\n\nstatic VALUE\nlib_toUTF8(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE str, encodename;\n\n    if (rb_scan_args(argc, argv, \"11\", &str, &encodename) == 1) {\n        encodename = Qnil;\n    }\n    return lib_toUTF8_core(Qnil, str, encodename);\n}\n\nstatic VALUE\nip_toUTF8(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE str, encodename;\n\n    if (rb_scan_args(argc, argv, \"11\", &str, &encodename) == 1) {\n        encodename = Qnil;\n    }\n    return lib_toUTF8_core(self, str, encodename);\n}\n\nstatic VALUE\nlib_fromUTF8_core(ip_obj, src, encodename)\n    VALUE ip_obj;\n    VALUE src;\n    VALUE encodename;\n{\n    volatile VALUE str = src;\n\n#ifdef TCL_UTF_MAX\n    Tcl_Interp *interp;\n    Tcl_Encoding encoding;\n    Tcl_DString dstr;\n    int taint_flag = OBJ_TAINTED(str);\n    char *buf;\n    int thr_crit_bup;\n#endif\n\n    tcl_stubs_check();\n\n    if (NIL_P(src)) {\n      return rb_str_new2(\"\");\n    }\n\n#ifdef TCL_UTF_MAX\n    if (NIL_P(ip_obj)) {\n        interp = (Tcl_Interp *)NULL;\n    } else if (get_ip(ip_obj) == (struct tcltkip *)NULL) {\n        interp = (Tcl_Interp *)NULL;\n    } else {\n        interp = get_ip(ip_obj)->ip;\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    if (NIL_P(encodename)) {\n        volatile VALUE enc;\n\n        if (TYPE(str) == T_STRING) {\n            enc = rb_attr_get(str, ID_at_enc);\n            if (!NIL_P(enc)) {\n                StringValue(enc);\n                if (strcmp(RSTRING_PTR(enc), \"binary\") == 0) {\n#ifdef RUBY_VM\n\t\t    rb_enc_associate_index(str, ENCODING_INDEX_BINARY);\n#endif\n\t\t    rb_ivar_set(str, ID_at_enc, ENCODING_NAME_BINARY);\n                    rb_thread_critical = thr_crit_bup;\n                    return str;\n                }\n#ifdef RUBY_VM\n\t    } else if (rb_enc_get_index(str) == ENCODING_INDEX_BINARY) {\n\t        rb_enc_associate_index(str, ENCODING_INDEX_BINARY);\n\t\trb_ivar_set(str, ID_at_enc, ENCODING_NAME_BINARY);\n\t\trb_thread_critical = thr_crit_bup;\n\t\treturn str;\n#endif\n            }\n        }\n\n        if (NIL_P(ip_obj)) {\n            encoding = (Tcl_Encoding)NULL;\n        } else {\n            enc = rb_attr_get(ip_obj, ID_at_enc);\n            if (NIL_P(enc)) {\n                encoding = (Tcl_Encoding)NULL;\n            } else {\n                /* StringValue(enc); */\n                enc = rb_funcall(enc, ID_to_s, 0, 0);\n                /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */\n\t\tif (!RSTRING_LEN(enc)) {\n\t\t  encoding = (Tcl_Encoding)NULL;\n\t\t} else {\n\t\t  encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, \n\t\t\t\t\t     RSTRING_PTR(enc));\n\t\t  if (encoding == (Tcl_Encoding)NULL) {\n                    rb_warning(\"Tk-interp has unknown encoding information (@encoding:'%s')\", RSTRING_PTR(enc));\n\t\t  } else {\n\t\t    encodename = rb_obj_dup(enc);\n\t\t  }\n\t\t}\n            }\n        }\n\n    } else {\n        StringValue(encodename);\n\n        if (strcmp(RSTRING_PTR(encodename), \"binary\") == 0) {\n\t    Tcl_Obj *tclstr;\n            char *s;\n            int  len;\n\n            StringValue(str);\n            tclstr = Tcl_NewStringObj(RSTRING_PTR(str), RSTRING_LEN(str));\n\t    Tcl_IncrRefCount(tclstr);\n            s = Tcl_GetByteArrayFromObj(tclstr, &len);\n            str = rb_tainted_str_new(s, len);\n\t    s = (char*)NULL;\n\t    Tcl_DecrRefCount(tclstr);\n#ifdef RUBY_VM\n\t    rb_enc_associate_index(str, ENCODING_INDEX_BINARY);\n#endif\n            rb_ivar_set(str, ID_at_enc, ENCODING_NAME_BINARY);\n\n            rb_thread_critical = thr_crit_bup;\n            return str;\n        }\n\n        /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(encodename)); */\n        encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, RSTRING_PTR(encodename));\n        if (encoding == (Tcl_Encoding)NULL) {\n            /* \n            rb_warning(\"unknown encoding name '%s'\", \n                       RSTRING_PTR(encodename));\n            encodename = Qnil;\n            */\n            rb_raise(rb_eArgError, \"unknown encoding name '%s'\", \n                     RSTRING_PTR(encodename));\n        }\n    }\n\n    StringValue(str);\n\n    if (RSTRING_LEN(str) == 0) {\n        rb_thread_critical = thr_crit_bup;\n        return rb_tainted_str_new2(\"\");\n    }\n\n    buf = ALLOC_N(char, RSTRING_LEN(str)+1);\n    /* buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1)); */\n    memcpy(buf, RSTRING_PTR(str), RSTRING_LEN(str));\n    buf[RSTRING_LEN(str)] = 0;\n\n    Tcl_DStringInit(&dstr);\n    Tcl_DStringFree(&dstr);\n    /* Tcl_UtfToExternalDString(encoding,buf,strlen(buf),&dstr); */\n    Tcl_UtfToExternalDString(encoding,buf,RSTRING_LEN(str),&dstr);\n\n    /* str = rb_tainted_str_new2(Tcl_DStringValue(&dstr)); */\n    /* str = rb_str_new2(Tcl_DStringValue(&dstr)); */\n    str = rb_str_new(Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr));\n#ifdef RUBY_VM\n    if (interp) {\n      /* can access encoding_table of TclTkIp */\n      /*   ->  try to use encoding_table      */\n      VALUE tbl = ip_get_encoding_table(ip_obj);\n      VALUE encobj = encoding_table_get_obj(tbl, encodename);\n      rb_enc_associate_index(str, rb_to_encoding_index(encobj));\n    } else {\n      /* cannot access encoding_table of TclTkIp */\n      /*   ->  try to find on Ruby Encoding      */\n      rb_enc_associate_index(str, rb_enc_find_index(RSTRING_PTR(encodename)));\n    }\n#endif\n    rb_ivar_set(str, ID_at_enc, encodename);\n\n    if (taint_flag) OBJ_TAINT(str);\n\n    /*\n    if (encoding != (Tcl_Encoding)NULL) {\n        Tcl_FreeEncoding(encoding);\n    }\n    */\n    Tcl_DStringFree(&dstr);\n\n    free(buf);\n    /* ckfree(buf); */\n\n    rb_thread_critical = thr_crit_bup;\n#endif\n\n    return str;\n}\n\nstatic VALUE\nlib_fromUTF8(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE str, encodename;\n\n    if (rb_scan_args(argc, argv, \"11\", &str, &encodename) == 1) {\n        encodename = Qnil;\n    }\n    return lib_fromUTF8_core(Qnil, str, encodename);\n}\n\nstatic VALUE\nip_fromUTF8(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE str, encodename;\n\n    if (rb_scan_args(argc, argv, \"11\", &str, &encodename) == 1) {\n        encodename = Qnil;\n    }\n    return lib_fromUTF8_core(self, str, encodename);\n}\n\nstatic VALUE\nlib_UTF_backslash_core(self, str, all_bs)\n    VALUE self;\n    VALUE str;\n    int all_bs;\n{\n#ifdef TCL_UTF_MAX\n    char *src_buf, *dst_buf, *ptr;\n    int read_len = 0, dst_len = 0;\n    int taint_flag = OBJ_TAINTED(str);\n    int thr_crit_bup;\n\n    tcl_stubs_check();\n\n    StringValue(str);\n    if (!RSTRING_LEN(str)) {\n        return str;\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* src_buf = ALLOC_N(char, RSTRING_LEN(str)+1); */\n    src_buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)src_buf); /* XXXXXXXX */\n#endif\n    memcpy(src_buf, RSTRING_PTR(str), RSTRING_LEN(str));\n    src_buf[RSTRING_LEN(str)] = 0;\n\n    /* dst_buf = ALLOC_N(char, RSTRING_LEN(str)+1); */\n    dst_buf = ckalloc(sizeof(char) * (RSTRING_LEN(str)+1));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)dst_buf); /* XXXXXXXX */\n#endif\n\n    ptr = src_buf;\n    while(RSTRING_LEN(str) > ptr - src_buf) {\n        if (*ptr == '\\\\' && (all_bs || *(ptr + 1) == 'u')) {\n            dst_len += Tcl_UtfBackslash(ptr, &read_len, (dst_buf + dst_len));\n            ptr += read_len;\n        } else {\n            *(dst_buf + (dst_len++)) = *(ptr++);\n        }\n    }\n\n    str = rb_str_new(dst_buf, dst_len);\n    if (taint_flag) OBJ_TAINT(str);\n#ifdef RUBY_VM\n    rb_enc_associate_index(str, ENCODING_INDEX_UTF8);\n#endif\n    rb_ivar_set(str, ID_at_enc, ENCODING_NAME_UTF8);\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)src_buf, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)src_buf); /* XXXXXXXX */\n#else\n    /* free(src_buf); */\n    ckfree(src_buf);\n#endif\n#endif\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)dst_buf, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)dst_buf); /* XXXXXXXX */\n#else\n    /* free(dst_buf); */\n    ckfree(dst_buf);\n#endif\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n#endif\n\n    return str;\n}\n\nstatic VALUE\nlib_UTF_backslash(self, str)\n    VALUE self;\n    VALUE str;\n{\n    return lib_UTF_backslash_core(self, str, 0);\n}\n\nstatic VALUE\nlib_Tcl_backslash(self, str)\n    VALUE self;\n    VALUE str;\n{\n    return lib_UTF_backslash_core(self, str, 1);\n}\n\nstatic VALUE\nlib_get_system_encoding(self)\n    VALUE self;\n{\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)\n    tcl_stubs_check();\n    return rb_str_new2(Tcl_GetEncodingName((Tcl_Encoding)NULL));\n#else\n    return Qnil;\n#endif\n}\n\nstatic VALUE\nlib_set_system_encoding(self, enc_name)\n    VALUE self;\n    VALUE enc_name;\n{\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 0)\n    tcl_stubs_check();\n\n    if (NIL_P(enc_name)) {\n        Tcl_SetSystemEncoding((Tcl_Interp *)NULL, (CONST char *)NULL);\n        return lib_get_system_encoding(self);\n    }\n\n    enc_name = rb_funcall(enc_name, ID_to_s, 0, 0);\n    if (Tcl_SetSystemEncoding((Tcl_Interp *)NULL, \n                              StringValuePtr(enc_name)) != TCL_OK) {\n        rb_raise(rb_eArgError, \"unknown encoding name '%s'\", \n                 RSTRING_PTR(enc_name));\n    }\n\n    return enc_name;\n#else\n    return Qnil;\n#endif\n}\n\n\n/* invoke Tcl proc */\nstruct invoke_info {\n    struct tcltkip *ptr;\n    Tcl_CmdInfo cmdinfo;\n#if TCL_MAJOR_VERSION >= 8\n    int objc;\n    Tcl_Obj **objv;\n#else\n    int argc;\n    char **argv;\n#endif\n};\n\nstatic VALUE\ninvoke_tcl_proc(arg)\n    VALUE arg;\n{\n    struct invoke_info *inf = (struct invoke_info *)arg;\n    int i, len;\n#if TCL_MAJOR_VERSION >= 8\n    int argc = inf->objc;\n    char **argv = (char **)NULL;\n#endif\n\n    /* memory allocation for arguments of this command */\n#if TCL_MAJOR_VERSION >= 8\n    if (!inf->cmdinfo.isNativeObjectProc) {\n        /* string interface */\n        /* argv = (char **)ALLOC_N(char *, argc+1);*/ /* XXXXXXXXXX */\n        argv = (char **)ckalloc(sizeof(char *)*(argc+1));\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)argv); /* XXXXXXXX */\n#endif\n        for (i = 0; i < argc; ++i) {\n            argv[i] = Tcl_GetStringFromObj(inf->objv[i], &len);\n        }\n        argv[argc] = (char *)NULL;\n    }\n#endif\n\n    Tcl_ResetResult(inf->ptr->ip);\n\n    /* Invoke the C procedure */\n#if TCL_MAJOR_VERSION >= 8\n    if (inf->cmdinfo.isNativeObjectProc) {\n        inf->ptr->return_value \n            = (*(inf->cmdinfo.objProc))(inf->cmdinfo.objClientData, \n                                        inf->ptr->ip, inf->objc, inf->objv);\n    }\n    else\n#endif\n    {\n#if TCL_MAJOR_VERSION >= 8\n        inf->ptr->return_value \n            = (*(inf->cmdinfo.proc))(inf->cmdinfo.clientData, inf->ptr->ip, \n                                     argc, (CONST84 char **)argv);\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* free(argv); */\n        ckfree((char*)argv);\n#endif\n#endif\n\n#else /* TCL_MAJOR_VERSION < 8 */\n        inf->ptr->return_value \n            = (*(inf->cmdinfo.proc))(inf->cmdinfo.clientData, inf->ptr->ip, \n                                     inf->argc, inf->argv);\n#endif\n    }\n\n    return Qnil;\n}\n\n\n#if TCL_MAJOR_VERSION >= 8\nstatic VALUE\nip_invoke_core(interp, objc, objv)\n    VALUE interp;\n    int objc;\n    Tcl_Obj **objv;\n#else\nstatic VALUE\nip_invoke_core(interp, argc, argv)\n    VALUE interp;\n    int argc;\n    char **argv;\n#endif\n{\n    struct tcltkip *ptr;\n    Tcl_CmdInfo info;\n    char *cmd;\n    int  len;\n    int  thr_crit_bup;\n    int unknown_flag = 0;\n\n#if 1 /* wrap tcl-proc call */\n    struct invoke_info inf;\n    int status;\n    VALUE ret;\n#else\n#if TCL_MAJOR_VERSION >= 8\n    int argc = objc;\n    char **argv = (char **)NULL;\n    /* Tcl_Obj *resultPtr; */\n#endif\n#endif\n\n    /* get the data struct */\n    ptr = get_ip(interp);\n\n    /* get the command name string */\n#if TCL_MAJOR_VERSION >= 8\n    cmd = Tcl_GetStringFromObj(objv[0], &len);\n#else /* TCL_MAJOR_VERSION < 8 */\n    cmd = argv[0];\n#endif\n\n    /* get the data struct */\n    ptr = get_ip(interp);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return rb_tainted_str_new2(\"\");\n    }\n\n    /* Tcl_Preserve(ptr->ip); */\n    rbtk_preserve_ip(ptr);\n\n    /* map from the command name to a C procedure */\n    DUMP2(\"call Tcl_GetCommandInfo, %s\", cmd);\n    if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {\n        DUMP1(\"error Tcl_GetCommandInfo\");\n        DUMP1(\"try auto_load (call 'unknown' command)\");\n        if (!Tcl_GetCommandInfo(ptr->ip, \n#if TCL_MAJOR_VERSION >= 8\n                                \"::unknown\", \n#else\n                                \"unknown\", \n#endif\n                                &info)) {\n            DUMP1(\"fail to get 'unknown' command\");\n            /* if (event_loop_abort_on_exc || cmd[0] != '.') { */\n            if (event_loop_abort_on_exc > 0) {\n                /* Tcl_Release(ptr->ip); */\n                rbtk_release_ip(ptr);\n                /*rb_ip_raise(obj,rb_eNameError,\"invalid command name `%s'\",cmd);*/\n                return create_ip_exc(interp, rb_eNameError, \n                                     \"invalid command name `%s'\", cmd);\n            } else {\n                if (event_loop_abort_on_exc < 0) {\n                    rb_warning(\"invalid command name `%s' (ignore)\", cmd);\n                } else {\n                    rb_warn(\"invalid command name `%s' (ignore)\", cmd);\n                }\n                Tcl_ResetResult(ptr->ip);\n                /* Tcl_Release(ptr->ip); */\n                rbtk_release_ip(ptr);\n                return rb_tainted_str_new2(\"\");\n            }\n        } else {\n#if TCL_MAJOR_VERSION >= 8\n            Tcl_Obj **unknown_objv;\n#else\n            char **unknown_argv;\n#endif\n            DUMP1(\"find 'unknown' command -> set arguemnts\");\n            unknown_flag = 1;\n\n#if TCL_MAJOR_VERSION >= 8\n            /* unknown_objv = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, objc+2); */\n            unknown_objv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * (objc+2));\n#if 0 /* use Tcl_Preserve/Release */\n\t    Tcl_Preserve((ClientData)unknown_objv); /* XXXXXXXX */\n#endif\n            unknown_objv[0] = Tcl_NewStringObj(\"::unknown\", 9);\n            Tcl_IncrRefCount(unknown_objv[0]);\n            memcpy(unknown_objv + 1, objv, sizeof(Tcl_Obj *)*objc);\n            unknown_objv[++objc] = (Tcl_Obj*)NULL;\n            objv = unknown_objv;\n#else\n            /* unknown_argv = (char **)ALLOC_N(char *, argc+2); */\n            unknown_argv = (char **)ckalloc(sizeof(char *) * (argc+2));\n#if 0 /* use Tcl_Preserve/Release */\n\t    Tcl_Preserve((ClientData)unknown_argv); /* XXXXXXXX */\n#endif\n            unknown_argv[0] = strdup(\"unknown\");\n            memcpy(unknown_argv + 1, argv, sizeof(char *)*argc);\n            unknown_argv[++argc] = (char *)NULL;\n            argv = unknown_argv;\n#endif\n        }\n    }\n    DUMP1(\"end Tcl_GetCommandInfo\");\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n#if 1 /* wrap tcl-proc call */\n    /* setup params */\n    inf.ptr = ptr;\n    inf.cmdinfo = info;\n#if TCL_MAJOR_VERSION >= 8\n    inf.objc = objc;\n    inf.objv = objv;\n#else\n    inf.argc = argc;\n    inf.argv = argv;\n#endif\n\n    /* invoke tcl-proc */\n    ret = rb_protect(invoke_tcl_proc, (VALUE)&inf, &status);\n    switch(status) {\n    case TAG_RAISE:\n#ifdef RUBY_VM\n        if (NIL_P(rb_errinfo())) {\n#else\n        if (NIL_P(ruby_errinfo)) {\n#endif\n            rbtk_pending_exception = rb_exc_new2(rb_eException, \n                                                 \"unknown exception\");\n        } else {\n#ifdef RUBY_VM\n            rbtk_pending_exception = rb_errinfo();\n#else\n            rbtk_pending_exception = ruby_errinfo;\n#endif\n        }\n        break;\n        \n    case TAG_FATAL:\n#ifdef RUBY_VM\n        if (NIL_P(rb_errinfo())) {\n#else\n        if (NIL_P(ruby_errinfo)) {\n#endif\n            rbtk_pending_exception = rb_exc_new2(rb_eFatal, \"FATAL\");\n        } else {\n#ifdef RUBY_VM\n            rbtk_pending_exception = rb_errinfo();\n#else\n            rbtk_pending_exception = ruby_errinfo;\n#endif\n        }\n    }\n\n#else /* !wrap tcl-proc call */\n\n    /* memory allocation for arguments of this command */\n#if TCL_MAJOR_VERSION >= 8\n    if (!info.isNativeObjectProc) {\n        int i;\n\n        /* string interface */\n        /* argv = (char **)ALLOC_N(char *, argc+1); */\n        argv = (char **)ckalloc(sizeof(char *) * (argc+1));\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Preserve((ClientData)argv); /* XXXXXXXX */\n#endif\n        for (i = 0; i < argc; ++i) {\n            argv[i] = Tcl_GetStringFromObj(objv[i], &len);\n        }\n        argv[argc] = (char *)NULL;\n    }\n#endif\n\n    Tcl_ResetResult(ptr->ip);\n\n    /* Invoke the C procedure */\n#if TCL_MAJOR_VERSION >= 8\n    if (info.isNativeObjectProc) {\n        ptr->return_value = (*info.objProc)(info.objClientData, ptr->ip, \n                                            objc, objv);\n#if 0\n        /* get the string value from the result object */\n        resultPtr = Tcl_GetObjResult(ptr->ip);\n        Tcl_SetResult(ptr->ip, Tcl_GetStringFromObj(resultPtr, &len),\n                      TCL_VOLATILE);\n#endif\n    }\n    else\n#endif\n    {\n#if TCL_MAJOR_VERSION >= 8\n        ptr->return_value = (*info.proc)(info.clientData, ptr->ip, \n                                         argc, (CONST84 char **)argv);\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* free(argv); */\n        ckfree((char*)argv);\n#endif\n#endif\n\n#else /* TCL_MAJOR_VERSION < 8 */\n        ptr->return_value = (*info.proc)(info.clientData, ptr->ip, \n                                         argc, argv);\n#endif\n    }\n#endif /* ! wrap tcl-proc call */\n\n    /* free allocated memory for calling 'unknown' command */\n    if (unknown_flag) {\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(objv[0]);\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)objv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)objv); /* XXXXXXXX */\n#else\n        /* free(objv); */\n        ckfree((char*)objv);\n#endif\n#endif\n#else /* TCL_MAJOR_VERSION < 8 */\n        free(argv[0]);\n        /* ckfree(argv[0]); */\n#if 0 /* use Tcl_EventuallyFree */\n\tTcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n\tTcl_Release((ClientData)argv); /* XXXXXXXX */\n#else\n        /* free(argv); */\n        ckfree((char*)argv);\n#endif\n#endif\n#endif\n    }\n\n    /* exception on mainloop */\n    if (pending_exception_check1(thr_crit_bup, ptr)) {\n        return rbtk_pending_exception;\n    }\n\n    rb_thread_critical = thr_crit_bup;\n\n    if (ptr->return_value == TCL_ERROR) {\n        if (event_loop_abort_on_exc > 0 && !Tcl_InterpDeleted(ptr->ip)) {\n\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 \"%s\", Tcl_GetStringResult(ptr->ip));\n        } else {\n            if (event_loop_abort_on_exc < 0) {\n                rb_warning(\"%s (ignore)\", Tcl_GetStringResult(ptr->ip));\n            } else {\n                rb_warn(\"%s (ignore)\", Tcl_GetStringResult(ptr->ip));\n            }\n            Tcl_ResetResult(ptr->ip);\n            return rb_tainted_str_new2(\"\");\n        }\n    }\n\n    /* pass back the result (as string) */\n    return ip_get_result_string_obj(ptr->ip);\n}\n\n\n#if TCL_MAJOR_VERSION >= 8\nstatic Tcl_Obj **\n#else /* TCL_MAJOR_VERSION < 8 */\nstatic char **\n#endif\nalloc_invoke_arguments(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int i;\n    int thr_crit_bup;\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj **av;\n#else /* TCL_MAJOR_VERSION < 8 */\n    char **av;\n#endif\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* memory allocation */\n#if TCL_MAJOR_VERSION >= 8\n    /* av = ALLOC_N(Tcl_Obj *, argc+1);*/ /* XXXXXXXXXX */\n    av = (Tcl_Obj**)ckalloc(sizeof(Tcl_Obj *)*(argc+1));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)av); /* XXXXXXXX */\n#endif\n    for (i = 0; i < argc; ++i) {\n        av[i] = get_obj_from_str(argv[i]);\n        Tcl_IncrRefCount(av[i]);\n    }\n    av[argc] = NULL;\n\n#else /* TCL_MAJOR_VERSION < 8 */\n    /* string interface */\n    /* av = ALLOC_N(char *, argc+1); */\n    av = (char**)ckalloc(sizeof(char *) * (argc+1));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)av); /* XXXXXXXX */\n#endif\n    for (i = 0; i < argc; ++i) {\n        av[i] = strdup(StringValuePtr(argv[i]));\n    }\n    av[argc] = NULL;\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n\n    return av;\n}\n\nstatic void\nfree_invoke_arguments(argc, av)\n    int argc;\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj **av;\n#else /* TCL_MAJOR_VERSION < 8 */\n    char **av;\n#endif\n{\n    int i;\n\n    for (i = 0; i < argc; ++i) {\n#if TCL_MAJOR_VERSION >= 8\n        Tcl_DecrRefCount(av[i]);\n\tav[i] = (Tcl_Obj*)NULL;\n#else /* TCL_MAJOR_VERSION < 8 */\n        free(av[i]);\n\tav[i] = (char*)NULL;\n#endif\n    }\n#if TCL_MAJOR_VERSION >= 8\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)av, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)av); /* XXXXXXXX */\n#else\n    ckfree((char*)av);\n#endif\n#endif\n#else /* TCL_MAJOR_VERSION < 8 */\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)av, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)av); /* XXXXXXXX */\n#else\n    /* free(av); */\n    ckfree((char*)av);\n#endif\n#endif\n#endif\n}\n\nstatic VALUE\nip_invoke_real(argc, argv, interp)\n    int argc;\n    VALUE *argv;\n    VALUE interp;\n{\n    VALUE v;\n    struct tcltkip *ptr;        /* tcltkip data struct */\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj **av = (Tcl_Obj **)NULL;\n#else /* TCL_MAJOR_VERSION < 8 */\n    char **av = (char **)NULL;\n#endif\n\n    DUMP2(\"invoke_real called by thread:%lx\", rb_thread_current());\n\n    /* get the data struct */\n    ptr = get_ip(interp);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return rb_tainted_str_new2(\"\");\n    }\n\n    /* allocate memory for arguments */\n    av = alloc_invoke_arguments(argc, argv);\n\n    /* Invoke the C procedure */\n    Tcl_ResetResult(ptr->ip);\n    v = ip_invoke_core(interp, argc, av);\n\n    /* free allocated memory */\n    free_invoke_arguments(argc, av);\n\n    return v;\n}\n\nVALUE\nivq_safelevel_handler(arg, ivq)\n    VALUE arg;\n    VALUE ivq;\n{\n    struct invoke_queue *q;\n\n    Data_Get_Struct(ivq, struct invoke_queue, q);\n    DUMP2(\"(safe-level handler) $SAFE = %d\", q->safe_level);\n    rb_set_safe_level(q->safe_level);\n    return ip_invoke_core(q->interp, q->argc, q->argv);\n}\n\nint invoke_queue_handler _((Tcl_Event *, int));\nint\ninvoke_queue_handler(evPtr, flags)\n    Tcl_Event *evPtr;\n    int flags;\n{\n    struct invoke_queue *q = (struct invoke_queue *)evPtr;\n    volatile VALUE ret;\n    volatile VALUE q_dat;\n    volatile VALUE thread = q->thread;\n    struct tcltkip *ptr;\n\n    DUMP2(\"do_invoke_queue_handler : evPtr = %p\", evPtr);\n    DUMP2(\"invoke queue_thread : %lx\", rb_thread_current());\n    DUMP2(\"added by thread : %lx\", thread);\n\n    if (*(q->done)) {\n        DUMP1(\"processed by another event-loop\");\n        return 0;\n    } else {\n        DUMP1(\"process it on current event-loop\");\n    }\n\n    if (RTEST(rb_thread_alive_p(thread)) \n\t&& ! RTEST(rb_funcall(thread, ID_stop_p, 0))) {\n      DUMP1(\"caller is not yet ready to receive the result -> pending\");\n      return 0;\n    }\n\n    /* process it */\n    *(q->done) = 1;\n\n    /* deleted ipterp ? */\n    ptr = get_ip(q->interp);\n    if (deleted_ip(ptr)) {\n        /* deleted IP --> ignore */\n        return 1;\n    }\n\n    /* incr internal handler mark */\n    rbtk_internal_eventloop_handler++;\n\n    /* check safe-level */\n    if (rb_safe_level() != q->safe_level) {\n        /* q_dat = Data_Wrap_Struct(rb_cData,0,0,q); */\n        q_dat = Data_Wrap_Struct(rb_cData,invoke_queue_mark,-1,q);\n        ret = rb_funcall(rb_proc_new(ivq_safelevel_handler, q_dat), \n                         ID_call, 0);\n        rb_gc_force_recycle(q_dat);\n\tq_dat = (VALUE)NULL;\n    } else {\n        DUMP2(\"call invoke_real (for caller thread:%lx)\", thread);\n        DUMP2(\"call invoke_real (current thread:%lx)\", rb_thread_current());\n        ret = ip_invoke_core(q->interp, q->argc, q->argv);\n    }\n\n    /* set result */\n    RARRAY_PTR(q->result)[0] = ret;\n    ret = (VALUE)NULL;\n\n    /* decr internal handler mark */\n    rbtk_internal_eventloop_handler--;\n\n    /* complete */\n    *(q->done) = -1;\n\n    /* unlink ruby objects */\n    q->interp = (VALUE)NULL;\n    q->result = (VALUE)NULL;\n    q->thread = (VALUE)NULL;\n\n    /* back to caller */\n    /* if (RTEST(rb_funcall(thread, ID_alive_p, 0, 0))) { */\n    if (RTEST(rb_thread_alive_p(thread))) {\n      DUMP2(\"back to caller (caller thread:%lx)\", thread);\n      DUMP2(\"               (current thread:%lx)\", rb_thread_current());\n#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE\n      have_rb_thread_waiting_for_value = 1;\n      rb_thread_wakeup(thread);\n#else\n      rb_thread_run(thread);\n#endif\n      DUMP1(\"finish back to caller\");\n#if DO_THREAD_SCHEDULE_AT_CALLBACK_DONE\n      rb_thread_schedule();\n#endif\n    } else {\n      DUMP2(\"caller is dead (caller thread:%lx)\", thread);\n      DUMP2(\"               (current thread:%lx)\", rb_thread_current());\n    }\n\n    /* end of handler : remove it */\n    return 1;\n}\n\nstatic VALUE\nip_invoke_with_position(argc, argv, obj, position)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n    Tcl_QueuePosition position;\n{\n    struct invoke_queue *ivq;\n#ifdef RUBY_VM\n    struct tcltkip *ptr;\n#endif\n    int  *alloc_done;\n    int  thr_crit_bup;\n    volatile VALUE current = rb_thread_current();\n    volatile VALUE ip_obj = obj;\n    volatile VALUE result;\n    volatile VALUE ret;\n\n#if TCL_MAJOR_VERSION >= 8\n    Tcl_Obj **av = (Tcl_Obj **)NULL;\n#else /* TCL_MAJOR_VERSION < 8 */\n    char **av = (char **)NULL;\n#endif\n\n    if (argc < 1) {\n        rb_raise(rb_eArgError, \"command name missing\");\n    }\n\n#ifdef RUBY_VM\n    ptr = get_ip(ip_obj);\n    DUMP2(\"status: ptr->tk_thread_id %d\", ptr->tk_thread_id);\n#endif\n    DUMP2(\"status: Tcl_GetCurrentThread %d\", Tcl_GetCurrentThread());\n    DUMP2(\"status: eventloopt_thread %lx\", eventloop_thread);\n\n    if (\n#ifdef RUBY_VM\n\t(ptr->tk_thread_id == 0 || ptr->tk_thread_id == Tcl_GetCurrentThread())\n\t&& \n#endif\n\t(NIL_P(eventloop_thread) || current == eventloop_thread)\n\t) {\n        if (NIL_P(eventloop_thread)) {\n            DUMP2(\"invoke from thread:%lx but no eventloop\", current);\n        } else {\n            DUMP2(\"invoke from current eventloop %lx\", current);\n        }\n        result = ip_invoke_real(argc, argv, ip_obj);\n        if (rb_obj_is_kind_of(result, rb_eException)) {\n            rb_exc_raise(result);\n        }\n        return result;\n    }\n\n    DUMP2(\"invoke from thread %lx (NOT current eventloop)\", current);\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    /* allocate memory (for arguments) */\n    av = alloc_invoke_arguments(argc, argv);\n\n    /* allocate memory (keep result) */\n    /* alloc_done = (int*)ALLOC(int); */\n    alloc_done = (int*)ckalloc(sizeof(int));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */\n#endif\n    *alloc_done = 0;\n\n    /* allocate memory (freed by Tcl_ServiceEvent) */\n    /* ivq = (struct invoke_queue *)Tcl_Alloc(sizeof(struct invoke_queue)); */\n    ivq = (struct invoke_queue *)ckalloc(sizeof(struct invoke_queue));\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)ivq); /* XXXXXXXX */\n#endif\n\n    /* allocate result obj */\n    result = rb_ary_new3(1, Qnil);\n\n    /* construct event data */\n    ivq->done = alloc_done;\n    ivq->argc = argc;\n    ivq->argv = av;\n    ivq->interp = ip_obj;\n    ivq->result = result;\n    ivq->thread = current;\n    ivq->safe_level = rb_safe_level();\n    ivq->ev.proc = invoke_queue_handler;\n\n    /* add the handler to Tcl event queue */\n    DUMP1(\"add handler\");\n#ifdef RUBY_VM\n    if (ptr->tk_thread_id) {\n      /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(ivq->ev), position); */\n      Tcl_ThreadQueueEvent(ptr->tk_thread_id, (Tcl_Event*)ivq, position);\n      Tcl_ThreadAlert(ptr->tk_thread_id);\n    } else if (tk_eventloop_thread_id) {\n      /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, \n\t\t\t   &(ivq->ev), position); */\n      Tcl_ThreadQueueEvent(tk_eventloop_thread_id, \n\t\t\t   (Tcl_Event*)ivq, position);\n      Tcl_ThreadAlert(tk_eventloop_thread_id);\n    } else {\n      /* Tcl_QueueEvent(&(ivq->ev), position); */\n      Tcl_QueueEvent((Tcl_Event*)ivq, position);\n    }\n#else\n    /* Tcl_QueueEvent(&(ivq->ev), position); */\n    Tcl_QueueEvent((Tcl_Event*)ivq, position);\n#endif\n\n    rb_thread_critical = thr_crit_bup;\n\n    /* wait for the handler to be processed */\n    DUMP2(\"wait for handler (current thread:%lx)\", current);\n    while(*alloc_done >= 0) {\n\t/* rb_thread_stop(); */\n\trb_thread_sleep_forever();\n    }\n    DUMP2(\"back from handler (current thread:%lx)\", current);\n\n    /* get result & free allocated memory */\n    ret = RARRAY(result)->ptr[0];\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)alloc_done, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */\n#else\n    /* free(alloc_done); */\n    ckfree((char*)alloc_done);\n#endif\n#endif\n\n#if 0 /* ivq is freed by Tcl_ServiceEvent */\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)ivq, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release(ivq);\n#else\n    ckfree((char*)ivq);\n#endif\n#endif\n#endif\n\n    /* free allocated memory */\n    free_invoke_arguments(argc, av);\n\n    /* exception? */\n    if (rb_obj_is_kind_of(ret, rb_eException)) {\n        DUMP1(\"raise exception\");\n        /* rb_exc_raise(ret); */\n\trb_exc_raise(rb_exc_new3(rb_obj_class(ret), \n\t\t\t\t rb_funcall(ret, ID_to_s, 0, 0)));\n    }\n\n    DUMP1(\"exit ip_invoke\");\n    return ret;\n}\n\n\n/* get return code from Tcl_Eval() */\nstatic VALUE\nip_retval(self)\n    VALUE self;\n{\n    struct tcltkip *ptr;        /* tcltkip data struct */\n\n    /* get the data strcut */\n    ptr = get_ip(self);\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return rb_tainted_str_new2(\"\");\n    }\n\n    return (INT2FIX(ptr->return_value));\n}\n\nstatic VALUE\nip_invoke(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    return ip_invoke_with_position(argc, argv, obj, TCL_QUEUE_TAIL);\n}\n\nstatic VALUE\nip_invoke_immediate(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    /* POTENTIALY INSECURE : can create infinite loop */\n    rb_secure(4);\n    return ip_invoke_with_position(argc, argv, obj, TCL_QUEUE_HEAD);\n}\n\n\n/* access Tcl variables */\nstatic VALUE\nip_get_variable2_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;\n    VALUE *argv;\n{\n    struct tcltkip *ptr = get_ip(interp);\n    int thr_crit_bup;\n    volatile VALUE varname, index, flag;\n\n    varname = argv[0];\n    index   = argv[1];\n    flag    = argv[2];\n\n    /* \n    StringValue(varname);\n    if (!NIL_P(index)) StringValue(index);\n    */\n\n#if TCL_MAJOR_VERSION >= 8\n    {\n        Tcl_Obj *ret;\n        volatile VALUE strval;\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        /* ip is deleted? */\n        if (deleted_ip(ptr)) {\n            rb_thread_critical = thr_crit_bup;\n            return rb_tainted_str_new2(\"\");\n        } else {\n            /* Tcl_Preserve(ptr->ip); */\n            rbtk_preserve_ip(ptr);\n            ret = Tcl_GetVar2Ex(ptr->ip, RSTRING_PTR(varname),\n                                NIL_P(index) ? NULL : RSTRING_PTR(index),\n                                FIX2INT(flag));\n        }\n\n        if (ret == (Tcl_Obj*)NULL) {\n            volatile VALUE exc;\n            /* exc = rb_exc_new2(rb_eRuntimeError, \n                                 Tcl_GetStringResult(ptr->ip)); */\n            exc = create_ip_exc(interp, rb_eRuntimeError, \n                                Tcl_GetStringResult(ptr->ip));\n            /* Tcl_Release(ptr->ip); */\n            rbtk_release_ip(ptr);\n            rb_thread_critical = thr_crit_bup;\n            return exc;\n        }\n\n        Tcl_IncrRefCount(ret);\n        strval = get_str_from_obj(ret);\n        OBJ_TAINT(strval);\n        Tcl_DecrRefCount(ret);\n\n        /* Tcl_Release(ptr->ip); */\n        rbtk_release_ip(ptr);\n        rb_thread_critical = thr_crit_bup;\n        return(strval);\n    }\n#else /* TCL_MAJOR_VERSION < 8 */\n    {\n        char *ret;\n        volatile VALUE strval;\n\n        /* ip is deleted? */\n        if (deleted_ip(ptr)) {\n            return rb_tainted_str_new2(\"\");\n        } else {\n            /* Tcl_Preserve(ptr->ip); */\n            rbtk_preserve_ip(ptr);\n            ret = Tcl_GetVar2(ptr->ip, RSTRING_PTR(varname), \n                              NIL_P(index) ? NULL : RSTRING_PTR(index),\n                              FIX2INT(flag));\n        }\n\n        if (ret == (char*)NULL) {\n            volatile VALUE exc;\n            exc = rb_exc_new2(rb_eRuntimeError, Tcl_GetStringResult(ptr->ip));\n            /* Tcl_Release(ptr->ip); */\n            rbtk_release_ip(ptr);\n            rb_thread_critical = thr_crit_bup;\n            return exc;\n        }\n\n        strval = rb_tainted_str_new2(ret);\n        /* Tcl_Release(ptr->ip); */\n        rbtk_release_ip(ptr);\n        rb_thread_critical = thr_crit_bup;\n\n        return(strval);\n    }\n#endif\n}\n\nstatic VALUE\nip_get_variable2(self, varname, index, flag)\n    VALUE self;\n    VALUE varname;\n    VALUE index;\n    VALUE flag;\n{\n    VALUE argv[3];\n    VALUE retval;\n\n    StringValue(varname);\n    if (!NIL_P(index)) StringValue(index);\n\n    argv[0] = varname;\n    argv[1] = index;\n    argv[2] = flag;\n\n    retval = tk_funcall(ip_get_variable2_core, 3, argv, self);\n\n    if (NIL_P(retval)) {\n        return rb_tainted_str_new2(\"\");\n    } else {\n        return retval;\n    }\n}\n\nstatic VALUE\nip_get_variable(self, varname, flag)\n    VALUE self;\n    VALUE varname;\n    VALUE flag;\n{\n    return ip_get_variable2(self, varname, Qnil, flag);\n}\n\nstatic VALUE\nip_set_variable2_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;\n    VALUE *argv;\n{\n    struct tcltkip *ptr = get_ip(interp);\n    int thr_crit_bup;\n    volatile VALUE varname, index, value, flag;\n\n    varname = argv[0];\n    index   = argv[1];\n    value   = argv[2];\n    flag    = argv[3];\n\n    /*\n    StringValue(varname);\n    if (!NIL_P(index)) StringValue(index);\n    StringValue(value);\n    */\n\n#if TCL_MAJOR_VERSION >= 8\n    {\n        Tcl_Obj *valobj, *ret;\n        volatile VALUE strval;\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        valobj = get_obj_from_str(value);\n        Tcl_IncrRefCount(valobj);\n\n        /* ip is deleted? */\n        if (deleted_ip(ptr)) {\n            Tcl_DecrRefCount(valobj);\n            rb_thread_critical = thr_crit_bup;\n            return rb_tainted_str_new2(\"\");\n        } else {\n            /* Tcl_Preserve(ptr->ip); */\n            rbtk_preserve_ip(ptr);\n            ret = Tcl_SetVar2Ex(ptr->ip, RSTRING_PTR(varname),\n                                NIL_P(index) ? NULL : RSTRING_PTR(index),\n                                valobj, FIX2INT(flag));\n        }\n\n        Tcl_DecrRefCount(valobj);\n\n        if (ret == (Tcl_Obj*)NULL) {\n            volatile VALUE exc;\n            /* exc = rb_exc_new2(rb_eRuntimeError, \n                                 Tcl_GetStringResult(ptr->ip)); */\n            exc = create_ip_exc(interp, rb_eRuntimeError, \n                                Tcl_GetStringResult(ptr->ip));\n            /* Tcl_Release(ptr->ip); */\n            rbtk_release_ip(ptr);\n            rb_thread_critical = thr_crit_bup;\n            return exc;\n        }\n\n        Tcl_IncrRefCount(ret);\n        strval = get_str_from_obj(ret);\n        OBJ_TAINT(strval);\n        Tcl_DecrRefCount(ret);\n\n        /* Tcl_Release(ptr->ip); */\n        rbtk_release_ip(ptr);\n        rb_thread_critical = thr_crit_bup;\n\n        return(strval);\n    }\n#else /* TCL_MAJOR_VERSION < 8 */\n    {\n        CONST char *ret;\n        volatile VALUE strval;\n\n        /* ip is deleted? */\n        if (deleted_ip(ptr)) {\n            return rb_tainted_str_new2(\"\");\n        } else {\n            /* Tcl_Preserve(ptr->ip); */\n            rbtk_preserve_ip(ptr);\n            ret = Tcl_SetVar2(ptr->ip, RSTRING_PTR(varname), \n                              NIL_P(index) ? NULL : RSTRING_PTR(index), \n                              RSTRING_PTR(value), FIX2INT(flag));\n        }\n\n        if (ret == (char*)NULL) {\n            return rb_exc_new2(rb_eRuntimeError, ptr->ip->result);\n        }\n\n        strval = rb_tainted_str_new2(ret);\n\n        /* Tcl_Release(ptr->ip); */\n        rbtk_release_ip(ptr);\n        rb_thread_critical = thr_crit_bup;\n\n        return(strval);\n    }\n#endif\n}\n\nstatic VALUE\nip_set_variable2(self, varname, index, value, flag)\n    VALUE self;\n    VALUE varname;\n    VALUE index;\n    VALUE value;\n    VALUE flag;\n{\n    VALUE argv[4];\n    VALUE retval;\n\n    StringValue(varname);\n    if (!NIL_P(index)) StringValue(index);\n    StringValue(value);\n\n    argv[0] = varname;\n    argv[1] = index;\n    argv[2] = value;\n    argv[3] = flag;\n\n    retval = tk_funcall(ip_set_variable2_core, 4, argv, self);\n\n    if (NIL_P(retval)) {\n        return rb_tainted_str_new2(\"\");\n    } else {\n        return retval;\n    }\n}\n\nstatic VALUE\nip_set_variable(self, varname, value, flag)\n    VALUE self;\n    VALUE varname;\n    VALUE value;\n    VALUE flag;\n{\n    return ip_set_variable2(self, varname, Qnil, value, flag);\n}\n\nstatic VALUE\nip_unset_variable2_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;\n    VALUE *argv;\n{\n    struct tcltkip *ptr = get_ip(interp);\n    volatile VALUE varname, index, flag;\n\n    varname = argv[0];\n    index   = argv[1];\n    flag    = argv[2];\n\n    /* \n    StringValue(varname);\n    if (!NIL_P(index)) StringValue(index);\n    */\n\n    /* ip is deleted? */\n    if (deleted_ip(ptr)) {\n        return Qtrue;\n    }\n\n    ptr->return_value = Tcl_UnsetVar2(ptr->ip, RSTRING_PTR(varname), \n                                      NIL_P(index) ? NULL : RSTRING_PTR(index),\n                                      FIX2INT(flag));\n\n    if (ptr->return_value == TCL_ERROR) {\n        if (FIX2INT(flag) & TCL_LEAVE_ERR_MSG) {\n            /* return rb_exc_new2(rb_eRuntimeError, \n                                  Tcl_GetStringResult(ptr->ip)); */\n            return create_ip_exc(interp, rb_eRuntimeError, \n                                 Tcl_GetStringResult(ptr->ip));\n        }\n        return Qfalse;\n    }\n    return Qtrue;\n}\n\nstatic VALUE\nip_unset_variable2(self, varname, index, flag)\n    VALUE self;\n    VALUE varname;\n    VALUE index;\n    VALUE flag;\n{\n    VALUE argv[3];\n    VALUE retval;\n\n    StringValue(varname);\n    if (!NIL_P(index)) StringValue(index);\n\n    argv[0] = varname;\n    argv[1] = index;\n    argv[2] = flag;\n\n    retval = tk_funcall(ip_unset_variable2_core, 3, argv, self);\n\n    if (NIL_P(retval)) {\n        return rb_tainted_str_new2(\"\");\n    } else {\n        return retval;\n    }\n}\n\nstatic VALUE\nip_unset_variable(self, varname, flag)\n    VALUE self;\n    VALUE varname;\n    VALUE flag;\n{\n    return ip_unset_variable2(self, varname, Qnil, flag);\n}\n\nstatic VALUE\nip_get_global_var(self, varname)\n    VALUE self;\n    VALUE varname;\n{\n    return ip_get_variable(self, varname, \n                           INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));\n}\n\nstatic VALUE\nip_get_global_var2(self, varname, index)\n    VALUE self;\n    VALUE varname;\n    VALUE index;\n{\n    return ip_get_variable2(self, varname, index, \n                            INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));\n}\n\nstatic VALUE\nip_set_global_var(self, varname, value)\n    VALUE self;\n    VALUE varname;\n    VALUE value;\n{\n    return ip_set_variable(self, varname, value, \n                           INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));\n}\n\nstatic VALUE\nip_set_global_var2(self, varname, index, value)\n    VALUE self;\n    VALUE varname;\n    VALUE index;\n    VALUE value;\n{\n    return ip_set_variable2(self, varname, index, value, \n                            INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));\n}\n\nstatic VALUE\nip_unset_global_var(self, varname)\n    VALUE self;\n    VALUE varname;\n{\n    return ip_unset_variable(self, varname, \n                             INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));\n}\n\nstatic VALUE\nip_unset_global_var2(self, varname, index)\n    VALUE self;\n    VALUE varname;\n    VALUE index;\n{\n    return ip_unset_variable2(self, varname, index, \n                              INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));\n}\n\n\n/* treat Tcl_List */\nstatic VALUE\nlib_split_tklist_core(ip_obj, list_str)\n    VALUE ip_obj;\n    VALUE list_str;\n{\n    Tcl_Interp *interp;\n    volatile VALUE ary, elem;\n    int idx;\n    int taint_flag = OBJ_TAINTED(list_str);\n#ifdef RUBY_VM\n    int list_enc_idx;\n    volatile VALUE list_ivar_enc;\n#endif\n    int result;\n    VALUE old_gc;\n\n    tcl_stubs_check();\n\n    if (NIL_P(ip_obj)) {\n        interp = (Tcl_Interp *)NULL;\n    } else if (get_ip(ip_obj) == (struct tcltkip *)NULL) {\n        interp = (Tcl_Interp *)NULL;\n    } else {\n        interp = get_ip(ip_obj)->ip;\n    }\n\n    StringValue(list_str);\n#ifdef RUBY_VM\n    list_enc_idx = rb_enc_get_index(list_str);\n    list_ivar_enc = rb_ivar_get(list_str, ID_at_enc);\n#endif\n\n    {\n#if TCL_MAJOR_VERSION >= 8\n        /* object style interface */\n        Tcl_Obj *listobj;\n        int     objc;\n        Tcl_Obj **objv;\n        int thr_crit_bup;\n\n        listobj = get_obj_from_str(list_str);\n\n        Tcl_IncrRefCount(listobj);\n\n        result = Tcl_ListObjGetElements(interp, listobj, &objc, &objv);\n\n        if (result == TCL_ERROR) {\n            Tcl_DecrRefCount(listobj);\n            if (interp == (Tcl_Interp*)NULL) {\n                rb_raise(rb_eRuntimeError, \"can't get elements from list\");\n            } else {\n                rb_raise(rb_eRuntimeError, \"%s\", Tcl_GetStringResult(interp));\n            }\n        }\n\n        for(idx = 0; idx < objc; idx++) {\n            Tcl_IncrRefCount(objv[idx]);\n        }\n\n        thr_crit_bup = rb_thread_critical;\n        rb_thread_critical = Qtrue;\n\n        ary = rb_ary_new2(objc);\n        if (taint_flag) OBJ_TAINT(ary);\n\n        old_gc = rb_gc_disable();\n\n        for(idx = 0; idx < objc; idx++) {\n            elem = get_str_from_obj(objv[idx]);\n#ifdef RUBY_VM\n\t    if (rb_enc_get_index(elem) == ENCODING_INDEX_BINARY) {\n\t        rb_enc_associate_index(elem, ENCODING_INDEX_BINARY);\n\t\trb_ivar_set(elem, ID_at_enc, ENCODING_NAME_BINARY);\n\t    } else {\n\t        rb_enc_associate_index(elem, list_enc_idx);\n\t\trb_ivar_set(elem, ID_at_enc, list_ivar_enc);\n\t    }\n#endif\n            if (taint_flag) OBJ_TAINT(elem);\n            /* RARRAY(ary)->ptr[idx] = elem; */\n\t    rb_ary_push(ary, elem);\n        }\n\n        /* RARRAY(ary)->len = objc; */\n\n        if (old_gc == Qfalse) rb_gc_enable();\n\n        rb_thread_critical = thr_crit_bup;\n\n        for(idx = 0; idx < objc; idx++) {\n            Tcl_DecrRefCount(objv[idx]);\n        }\n\n        Tcl_DecrRefCount(listobj);\n\n#else /* TCL_MAJOR_VERSION < 8 */\n        /* string style interface */\n        int  argc;\n        char **argv;\n\n        if (Tcl_SplitList(interp, RSTRING_PTR(list_str), \n                          &argc, &argv) == TCL_ERROR) {\n            if (interp == (Tcl_Interp*)NULL) {\n                rb_raise(rb_eRuntimeError, \"can't get elements from list\");\n            } else {\n                rb_raise(rb_eRuntimeError, \"%s\", interp->result);\n            }\n        }\n\n        ary = rb_ary_new2(argc);\n        if (taint_flag) OBJ_TAINT(ary);\n\n        old_gc = rb_gc_disable();\n\n        for(idx = 0; idx < argc; idx++) {\n            if (taint_flag) {\n                elem = rb_tainted_str_new2(argv[idx]);\n            } else {\n                elem = rb_str_new2(argv[idx]);\n            }\n            /* rb_ivar_set(elem, ID_at_enc, rb_str_new2(\"binary\")); */\n            /* RARRAY(ary)->ptr[idx] = elem; */\n\t    rb_ary_push(ary, elem)\n        }\n        /* RARRAY(ary)->len = argc; */\n\n        if (old_gc == Qfalse) rb_gc_enable();\n#endif\n    }\n\n    return ary;\n}\n\nstatic VALUE\nlib_split_tklist(self, list_str)\n    VALUE self;\n    VALUE list_str;\n{\n    return lib_split_tklist_core(Qnil, list_str);\n}\n\n\nstatic VALUE\nip_split_tklist(self, list_str)\n    VALUE self;\n    VALUE list_str;\n{\n    return lib_split_tklist_core(self, list_str);\n}\n\nstatic VALUE\nlib_merge_tklist(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    int  num, len;\n    int  *flagPtr;\n    char *dst, *result;\n    volatile VALUE str;\n    int taint_flag = 0;\n    int thr_crit_bup;\n    VALUE old_gc;\n\n    if (argc == 0) return rb_str_new2(\"\");\n\n    tcl_stubs_check();\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n    old_gc = rb_gc_disable();\n\n    /* based on Tcl/Tk's Tcl_Merge() */\n    /* flagPtr = ALLOC_N(int, argc); */\n    flagPtr = (int *)ckalloc(sizeof(int) * argc);\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)flagPtr); /* XXXXXXXXXX */\n#endif\n\n    /* pass 1 */\n    len = 1;\n    for(num = 0; num < argc; num++) {\n        if (OBJ_TAINTED(argv[num])) taint_flag = 1;\n        dst = StringValuePtr(argv[num]);\n#if TCL_MAJOR_VERSION >= 8\n        len += Tcl_ScanCountedElement(dst, RSTRING_LEN(argv[num]),  \n                                      &flagPtr[num]) + 1;\n#else /* TCL_MAJOR_VERSION < 8 */\n        len += Tcl_ScanElement(dst, &flagPtr[num]) + 1;\n#endif\n    }\n\n    /* pass 2 */\n    /* result = (char *)Tcl_Alloc(len); */\n    result = (char *)ckalloc(len);\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Preserve((ClientData)result);\n#endif\n    dst = result;\n    for(num = 0; num < argc; num++) {\n#if TCL_MAJOR_VERSION >= 8\n        len = Tcl_ConvertCountedElement(RSTRING_PTR(argv[num]), \n                                        RSTRING_LEN(argv[num]), \n                                        dst, flagPtr[num]);\n#else /* TCL_MAJOR_VERSION < 8 */\n        len = Tcl_ConvertElement(RSTRING_PTR(argv[num]), dst, flagPtr[num]);\n#endif\n        dst += len;\n        *dst = ' ';\n        dst++;\n    }\n    if (dst == result) {\n        *dst = 0;\n    } else {\n        dst[-1] = 0;\n    }\n\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)flagPtr, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)flagPtr);\n#else\n    /* free(flagPtr); */\n    ckfree((char*)flagPtr);\n#endif\n#endif\n\n    /* create object */\n    str = rb_str_new(result, dst - result - 1);\n    if (taint_flag) OBJ_TAINT(str);\n#if 0 /* use Tcl_EventuallyFree */\n    Tcl_EventuallyFree((ClientData)result, TCL_DYNAMIC); /* XXXXXXXX */\n#else\n#if 0 /* use Tcl_Preserve/Release */\n    Tcl_Release((ClientData)result); /* XXXXXXXXXXX */\n#else\n    /* Tcl_Free(result); */\n    ckfree(result);\n#endif\n#endif\n\n    if (old_gc == Qfalse) rb_gc_enable();\n    rb_thread_critical = thr_crit_bup;\n\n    return str;\n}\n\nstatic VALUE\nlib_conv_listelement(self, src)\n    VALUE self;\n    VALUE src;\n{\n    int   len, scan_flag;\n    volatile VALUE dst;\n    int   taint_flag = OBJ_TAINTED(src);\n    int thr_crit_bup;\n\n    tcl_stubs_check();\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    StringValue(src);\n\n#if TCL_MAJOR_VERSION >= 8\n    len = Tcl_ScanCountedElement(RSTRING_PTR(src), RSTRING_LEN(src), \n                                 &scan_flag);\n    dst = rb_str_new(0, len + 1);\n    len = Tcl_ConvertCountedElement(RSTRING_PTR(src), RSTRING_LEN(src), \n                                    RSTRING_PTR(dst), scan_flag);\n#else /* TCL_MAJOR_VERSION < 8 */\n    len = Tcl_ScanElement(RSTRING_PTR(src), &scan_flag);\n    dst = rb_str_new(0, len + 1);\n    len = Tcl_ConvertElement(RSTRING_PTR(src), RSTRING_PTR(dst), scan_flag);\n#endif\n\n    rb_str_resize(dst, len);\n    if (taint_flag) OBJ_TAINT(dst);\n\n    rb_thread_critical = thr_crit_bup;\n\n    return dst;\n}\n\nstatic VALUE\nlib_getversion(self)\n    VALUE self;\n{\n    volatile VALUE type_name;\n\n    set_tcltk_version();\n\n    switch(tcltk_version.type) {\n    case TCL_ALPHA_RELEASE:\n      type_name = rb_str_new2(\"alpha\");\n      break;\n    case TCL_BETA_RELEASE:\n      type_name = rb_str_new2(\"beta\");\n      break;\n    case TCL_FINAL_RELEASE:\n      type_name = rb_str_new2(\"final\");\n      break;\n    default:\n      type_name = rb_str_new2(\"unknown\");\n    }\n\n    return rb_ary_new3(5, INT2NUM(tcltk_version.major), \n\t\t          INT2NUM(tcltk_version.minor), \n\t\t          INT2NUM(tcltk_version.type), type_name, \n\t\t          INT2NUM(tcltk_version.patchlevel));\n}\n\n\nstatic VALUE\ntcltklib_compile_info()\n{\n    volatile VALUE ret;\n    int size;\n    char form[] \n      = \"tcltklib %s :: Ruby%s (%s) %s pthread :: Tcl%s(%s)/Tk%s(%s) %s\";\n    char *info;\n\n    size = strlen(form)\n        + strlen(TCLTKLIB_RELEASE_DATE)\n        + strlen(RUBY_VERSION)\n        + strlen(RUBY_RELEASE_DATE)\n        + strlen(\"without\") \n        + strlen(TCL_PATCH_LEVEL)\n        + strlen(\"without stub\")\n        + strlen(TK_PATCH_LEVEL)\n        + strlen(\"without stub\") \n        + strlen(\"unknown tcl_threads\");\n\n    info = ALLOC_N(char, size);\n    /* info = ckalloc(sizeof(char) * size); */ /* SEGV */\n\n    sprintf(info, form,\n            TCLTKLIB_RELEASE_DATE, \n            RUBY_VERSION, RUBY_RELEASE_DATE, \n#ifdef HAVE_NATIVETHREAD\n            \"with\",\n#else\n            \"without\",\n#endif\n            TCL_PATCH_LEVEL, \n#ifdef USE_TCL_STUBS\n            \"with stub\",\n#else\n            \"without stub\",\n#endif\n            TK_PATCH_LEVEL, \n#ifdef USE_TK_STUBS\n            \"with stub\",\n#else\n            \"without stub\",\n#endif\n#ifdef WITH_TCL_ENABLE_THREAD\n# if WITH_TCL_ENABLE_THREAD\n            \"with tcl_threads\"\n# else\n            \"without tcl_threads\"\n# endif\n#else\n            \"unknown tcl_threads\"\n#endif\n        );\n\n    ret = rb_obj_freeze(rb_str_new2(info));\n\n    free(info);\n    /* ckfree(info); */\n\n    return ret;\n}\n\n\n/*###############################################*/\n\nstatic VALUE\ncreate_dummy_encoding_for_tk_core(interp, name, error_mode)\n     VALUE interp;\n     VALUE name;\n     VALUE error_mode;\n{\n  struct tcltkip *ptr = get_ip(interp);\n\n  rb_secure(4);\n\n  StringValue(name);\n\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)\n  if (Tcl_GetEncoding((Tcl_Interp*)NULL, RSTRING_PTR(name)) == (Tcl_Encoding)NULL) {\n    if (RTEST(error_mode)) {\n      rb_raise(rb_eArgError, \"invalid Tk encoding name '%s'\", \n\t       RSTRING_PTR(name));\n    } else {\n      return Qnil;\n    }\n  }\n#endif\n\n#ifdef RUBY_VM\n  if (RTEST(rb_define_dummy_encoding(RSTRING_PTR(name)))) {\n    int idx = rb_enc_find_index(StringValueCStr(name));\n    return rb_enc_from_encoding(rb_enc_from_index(idx));\n  } else {\n    if (RTEST(error_mode)) {\n      rb_raise(rb_eRuntimeError, \"fail to create dummy encoding for '%s'\",\n\t       RSTRING_PTR(name));\n    } else {\n      return Qnil;\n    }\n  }\n#else\n    return name;\n#endif\n}\nstatic VALUE\ncreate_dummy_encoding_for_tk(interp, name)\n     VALUE interp;\n     VALUE name;\n{\n  return create_dummy_encoding_for_tk_core(interp, name, Qtrue);\n}\n\n\n#ifdef RUBY_VM\nstatic int\nupdate_encoding_table(table, interp, error_mode)\n     VALUE table;\n     VALUE interp;\n     VALUE error_mode;\n{\n  struct tcltkip *ptr;\n  int retry = 0;\n  int i, idx, objc;\n  Tcl_Obj **objv;\n  Tcl_Obj *enc_list;\n  volatile VALUE encname = Qnil;\n  volatile VALUE encobj = Qnil;\n\n  /* interpreter check */\n  if (NIL_P(interp)) return 0;\n  ptr = get_ip(interp);\n  if (ptr == (struct tcltkip *) NULL)  return 0;\n  if (deleted_ip(ptr)) return 0;\n\n  /* get Tcl's encoding list */\n  Tcl_GetEncodingNames(ptr->ip);\n  enc_list = Tcl_GetObjResult(ptr->ip);\n  Tcl_IncrRefCount(enc_list);\n\n  if (Tcl_ListObjGetElements(ptr->ip, enc_list, \n\t\t\t     &objc, &objv) != TCL_OK) {\n    Tcl_DecrRefCount(enc_list);\n    /* rb_raise(rb_eRuntimeError, \"failt to get Tcl's encoding names\");*/\n    return 0;\n  }\n\n  /* check each encoding name */\n  for(i = 0; i < objc; i++) {\n    encname = rb_str_new2(Tcl_GetString(objv[i]));\n    if (NIL_P(rb_hash_lookup(table, encname))) {\n      /* new Tk encoding -> add to table */\n      idx = rb_enc_find_index(StringValueCStr(encname));\n      if (idx < 0) {\n\tencobj = create_dummy_encoding_for_tk_core(interp,encname,error_mode);\n      } else {\n\tencobj = rb_enc_from_encoding(rb_enc_from_index(idx));\n      }\n      encname = rb_obj_freeze(encname);\n      rb_hash_aset(table, encname, encobj);\n      if (!NIL_P(encobj) && NIL_P(rb_hash_lookup(table, encobj))) {\n\trb_hash_aset(table, encobj, encname);\n      }\n      retry = 1;\n    }\n  }\n\n  Tcl_DecrRefCount(enc_list);\n\n  return retry;\n}\n\nstatic VALUE\nencoding_table_get_name_core(table, enc_arg, error_mode)\n     VALUE table;\n     VALUE enc_arg;\n     VALUE error_mode;\n{\n  volatile VALUE enc = enc_arg;\n  volatile VALUE name = Qnil;\n  volatile VALUE tmp = Qnil;\n  volatile VALUE interp = rb_ivar_get(table, ID_at_interp);\n  struct tcltkip *ptr = (struct tcltkip *) NULL;\n  int idx;\n\n  /* deleted interp ? */\n  if (!NIL_P(interp)) {\n    ptr = get_ip(interp);\n    if (deleted_ip(ptr)) {\n      ptr = (struct tcltkip *) NULL;\n    }\n  }\n\n  /* encoding argument check */\n  /* 1st: default encoding setting of interp */\n  if (ptr && NIL_P(enc)) {\n    if (rb_respond_to(interp, ID_encoding_name)) {\n      enc = rb_funcall(interp, ID_encoding_name, 0, 0);\n    }\n  }\n  /* 2nd: encoding system of Tcl/Tk */\n  if (NIL_P(enc)) {\n    enc = rb_str_new2(Tcl_GetEncodingName((Tcl_Encoding)NULL));\n  }\n  /* 3rd: Encoding.default_external */\n  if (NIL_P(enc)) {\n    enc = rb_enc_default_external();\n  }\n\n  if (RTEST(rb_obj_is_kind_of(enc, cRubyEncoding))) {\n    /* Ruby's Encoding object */\n    name = rb_hash_lookup(table, enc);\n    if (!NIL_P(name)) {\n      /* find */\n      return name;\n    }\n\n    /* is it new ? */\n    /* update check of Tk encoding names */\n    if (update_encoding_table(table, interp, error_mode)) {\n      /* add new relations to the table   */\n      /* RETRY: registered Ruby encoding? */\n      name = rb_hash_lookup(table, enc);\n      if (!NIL_P(name)) {\n\t/* find */\n\treturn name;\n      }\n    }\n    /* fail to find */\n\n  } else {\n    /* String or Symbol? */\n    name = rb_funcall(enc, ID_to_s, 0, 0);\n\n    if (!NIL_P(rb_hash_lookup(table, name))) {\n      /* find */\n      return name;\n    }\n\n    /* is it new ? */\n    idx = rb_enc_find_index(StringValueCStr(name));\n    if (idx >= 0) {\n      enc = rb_enc_from_encoding(rb_enc_from_index(idx));\n\n      /* registered Ruby encoding? */\n      tmp = rb_hash_lookup(table, enc);\n      if (!NIL_P(tmp)) {\n\t/* find */\n\treturn tmp;\n      }\n\n      /* update check of Tk encoding names */\n      if (update_encoding_table(table, interp, error_mode)) {\n\t/* add new relations to the table   */\n\t/* RETRY: registered Ruby encoding? */\n\ttmp = rb_hash_lookup(table, enc);\n\tif (!NIL_P(tmp)) {\n\t  /* find */\n\t  return tmp;\n\t}\n      }\n    }\n    /* fail to find */\n  }\n\n  if (RTEST(error_mode)) {\n    enc = rb_funcall(enc_arg, ID_to_s, 0, 0);\n    rb_raise(rb_eArgError, \"unsupported Tk encoding '%s'\", RSTRING_PTR(enc));\n  }\n  return Qnil;\n}\nstatic VALUE\nencoding_table_get_obj_core(table, enc, error_mode)\n     VALUE table;\n     VALUE enc;\n     VALUE error_mode;\n{\n  volatile VALUE obj = Qnil;\n\n  obj = rb_hash_lookup(table, \n\t\t       encoding_table_get_name_core(table, enc, error_mode));\n  if (RTEST(rb_obj_is_kind_of(obj, cRubyEncoding))) {\n    return obj;\n  } else {\n    return Qnil;\n  }\n}\n\n#else /* ! RUBY_VM */\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)\nstatic int\nupdate_encoding_table(table, interp, error_mode)\n     VALUE table;\n     VALUE interp;\n     VALUE error_mode;\n{\n  struct tcltkip *ptr;\n  int retry = 0;\n  int i, idx, objc;\n  Tcl_Obj **objv;\n  Tcl_Obj *enc_list;\n  volatile VALUE encname = Qnil;\n  volatile VALUE encobj = Qnil;\n\n  /* interpreter check */\n  if (NIL_P(interp)) return 0;\n  ptr = get_ip(interp);\n  if (ptr == (struct tcltkip *) NULL)  return 0;\n  if (deleted_ip(ptr)) return 0;\n\n  /* get Tcl's encoding list */\n  Tcl_GetEncodingNames(ptr->ip);\n  enc_list = Tcl_GetObjResult(ptr->ip);\n  Tcl_IncrRefCount(enc_list);\n\n  if (Tcl_ListObjGetElements(ptr->ip, enc_list, &objc, &objv) != TCL_OK) {\n    Tcl_DecrRefCount(enc_list);\n    /* rb_raise(rb_eRuntimeError, \"failt to get Tcl's encoding names\"); */\n    return 0;\n  }\n\n  /* get encoding name and set it to table */\n  for(i = 0; i < objc; i++) {\n    encname = rb_str_new2(Tcl_GetString(objv[i]));\n    if (NIL_P(rb_hash_lookup(table, encname))) {\n      /* new Tk encoding -> add to table */\n      encname = rb_obj_freeze(encname);\n      rb_hash_aset(table, encname, encname);\n      retry = 1;\n    }\n  }\n\n  Tcl_DecrRefCount(enc_list);\n\n  return retry;\n}\n\nstatic VALUE\nencoding_table_get_name_core(table, enc, error_mode)\n     VALUE table;\n     VALUE enc;\n     VALUE error_mode;\n{\n  volatile VALUE name = Qnil;\n  int retry = 0;\n\n  enc = rb_funcall(enc, ID_to_s, 0, 0);\n  name = rb_hash_lookup(table, enc);\n\n  if (!NIL_P(name)) {\n    /* find */\n    return name;\n  }\n\n  /* update check */\n  if (update_encoding_table(table, rb_ivar_get(table, ID_at_interp), \n\t\t\t\t\t       error_mode)) {\n    /* add new relations to the table   */\n    /* RETRY: registered Ruby encoding? */\n    name = rb_hash_lookup(table, enc);\n    if (!NIL_P(name)) {\n      /* find */\n      return name;\n    }\n  }\n\n  if (RTEST(error_mode)) {\n    rb_raise(rb_eArgError, \"unsupported Tk encoding '%s'\", RSTRING_PTR(enc));\n  }\n  return Qnil;\n}\nstatic VALUE\nencoding_table_get_obj_core(table, enc, error_mode)\n     VALUE table;\n     VALUE enc;\n     VALUE error_mode;\n{\n  return encoding_table_get_name_core(table, enc, error_mode);\n}\n\n#else /* Tcl/Tk 7.x or 8.0 */\nstatic VALUE\nencoding_table_get_name_core(table, enc, error_mode)\n     VALUE table;\n     VALUE enc;\n     VALUE error_mode;\n{\n  return Qnil;\n}\nstatic VALUE\nencoding_table_get_obj_core(table, enc, error_mode)\n     VALUE table;\n     VALUE enc;\n     VALUE error_mode;\n{\n  return Qnil;\n}\n#endif /* end of dependency for the version of Tcl/Tk */\n#endif\n\nstatic VALUE\nencoding_table_get_name(table, enc)\n     VALUE table;\n     VALUE enc;\n{\n  return encoding_table_get_name_core(table, enc, Qtrue);\n}\nstatic VALUE\nencoding_table_get_obj(table, enc)\n     VALUE table;\n     VALUE enc;\n{\n  return encoding_table_get_obj_core(table, enc, Qtrue);\n}\n\n#ifdef RUBY_VM\nstatic VALUE\ncreate_encoding_table(interp)\n     VALUE interp;\n{\n  struct tcltkip *ptr = get_ip(interp);\n  volatile VALUE table = rb_hash_new();\n  volatile VALUE encname = Qnil;\n  volatile VALUE encobj = Qnil;\n  int i, idx, objc;\n  Tcl_Obj **objv;\n  Tcl_Obj *enc_list;\n\n  rb_secure(4);\n\n  /* set 'binary' encoding */\n  encobj = rb_enc_from_encoding(rb_enc_from_index(ENCODING_INDEX_BINARY));\n  rb_hash_aset(table, ENCODING_NAME_BINARY, encobj);\n  rb_hash_aset(table, encobj, ENCODING_NAME_BINARY);\n\t       \n\n  /* Tcl stub check */\n  tcl_stubs_check();\n\n  /* get Tcl's encoding list */\n  Tcl_GetEncodingNames(ptr->ip);\n  enc_list = Tcl_GetObjResult(ptr->ip);\n  Tcl_IncrRefCount(enc_list);\n\n  if (Tcl_ListObjGetElements(ptr->ip, enc_list, &objc, &objv) != TCL_OK) {\n    Tcl_DecrRefCount(enc_list);\n    rb_raise(rb_eRuntimeError, \"failt to get Tcl's encoding names\");\n  }\n\n  /* get encoding name and set it to table */\n  for(i = 0; i < objc; i++) {\n    int name2obj, obj2name;\n\n    name2obj = 1; obj2name = 1;\n    encname = rb_obj_freeze(rb_str_new2(Tcl_GetString(objv[i])));\n    idx = rb_enc_find_index(StringValueCStr(encname));\n    if (idx < 0) {\n      /* fail to find ruby encoding -> check known encoding */\n      if (strcmp(RSTRING_PTR(encname), \"identity\") == 0) {\n\tname2obj = 1; obj2name = 0;\n\tidx = ENCODING_INDEX_BINARY;\n\n      } else if (strcmp(RSTRING_PTR(encname), \"shiftjis\") == 0) {\n\tname2obj = 1; obj2name = 0;\n\tidx = rb_enc_find_index(\"Shift_JIS\");\n\n      } else if (strcmp(RSTRING_PTR(encname), \"unicode\") == 0) {\n\tname2obj = 1; obj2name = 0;\n\tidx = ENCODING_INDEX_UTF8;\n\n      } else if (strcmp(RSTRING_PTR(encname), \"symbol\") == 0) {\n\tname2obj = 1; obj2name = 0;\n\tidx = rb_enc_find_index(\"ASCII-8BIT\");\n\n      } else {\n\t/* regist dummy encoding */\n\tname2obj = 1; obj2name = 1;\n      }\n    }\n\n    if (idx < 0) {\n      /* unknown encoding -> create dummy */\n      encobj = create_dummy_encoding_for_tk(interp, encname);\n    } else {\n      encobj = rb_enc_from_encoding(rb_enc_from_index(idx));\n    }\n\n    if (name2obj) {\n      DUMP2(\"create_encoding_table: name2obj: %s\", RSTRING_PTR(encname));\n      rb_hash_aset(table, encname, encobj);\n    }\n    if (obj2name) {\n      DUMP2(\"create_encoding_table: obj2name: %s\", RSTRING_PTR(encname));\n      rb_hash_aset(table, encobj, encname);\n    }\n  }\n\n  Tcl_DecrRefCount(enc_list);\n\n  rb_ivar_set(table, ID_at_interp, interp);\n  rb_ivar_set(interp, ID_encoding_table, table);\n\n  return table;\n}\n\n#else /* ! RUBY_VM */\n#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)\nstatic VALUE\ncreate_encoding_table(interp)\n     VALUE interp;\n{\n  struct tcltkip *ptr = get_ip(interp);\n  volatile VALUE table = rb_hash_new();\n  volatile VALUE encname = Qnil;\n  int i, objc;\n  Tcl_Obj **objv;\n  Tcl_Obj *enc_list;\n\n  rb_secure(4);\n\n  /* set 'binary' encoding */\n  rb_hash_aset(table, ENCODING_NAME_BINARY, ENCODING_NAME_BINARY);\n\n  /* get Tcl's encoding list */\n  Tcl_GetEncodingNames(ptr->ip);\n  enc_list = Tcl_GetObjResult(ptr->ip);\n  Tcl_IncrRefCount(enc_list);\n\n  if (Tcl_ListObjGetElements(ptr->ip, enc_list, &objc, &objv) != TCL_OK) {\n    Tcl_DecrRefCount(enc_list);\n    rb_raise(rb_eRuntimeError, \"failt to get Tcl's encoding names\");\n  }\n\n  /* get encoding name and set it to table */\n  for(i = 0; i < objc; i++) {\n    encname = rb_obj_freeze(rb_str_new2(Tcl_GetString(objv[i])));\n    rb_hash_aset(table, encname, encname);\n  }\n\n  Tcl_DecrRefCount(enc_list);\n\n  rb_ivar_set(table, ID_at_interp, interp);\n  rb_ivar_set(interp, ID_encoding_table, table);\n\n  return table;\n}\n\n#else /* Tcl/Tk 7.x or 8.0 */\nstatic VALUE\ncreate_encoding_table(interp)\n     VALUE interp;\n{\n  volatile VALUE table = rb_hash_new();\n  rb_secure(4);\n  rb_ivar_set(interp, ID_encoding_table, table);\n  return table;\n}\n#endif\n#endif\n\nstatic VALUE\nip_get_encoding_table(interp)\n     VALUE interp;\n{\n  volatile VALUE table = Qnil;\n\n  table = rb_ivar_get(interp, ID_encoding_table);\n\n  if (NIL_P(table)) {\n    /* initialize encoding_table */\n    table = create_encoding_table(interp);\n    rb_define_singleton_method(table, \"get_name\", encoding_table_get_name, 1);\n    rb_define_singleton_method(table, \"get_obj\",  encoding_table_get_obj,  1);\n  }\n\n  return table;\n}\n\n\n/*###############################################*/\n\n/*\n *   The following is based on tkMenu.[ch] \n *   of Tcl/Tk (Tk8.0 -- Tk8.5b1) source code.\n */\n#if TCL_MAJOR_VERSION >= 8\n\n#define MASTER_MENU             0\n#define TEAROFF_MENU            1\n#define MENUBAR                 2\n\nstruct dummy_TkMenuEntry {\n    int type;\n    struct dummy_TkMenu *menuPtr;\n    /* , and etc.   */\n};\n\nstruct dummy_TkMenu {\n    Tk_Window tkwin;\n    Display *display;\n    Tcl_Interp *interp;\n    Tcl_Command widgetCmd;\n    struct dummy_TkMenuEntry **entries;\n    int numEntries;\n    int active;\n    int menuType;     /* MASTER_MENU, TEAROFF_MENU, or MENUBAR */\n    Tcl_Obj *menuTypePtr;\n    /* , and etc.   */\n};\n\nstruct dummy_TkMenuRef {\n    struct dummy_TkMenu *menuPtr;\n    char *dummy1;\n    char *dummy2;\n    char *dummy3;\n};\n\n#if 0 /* was available on Tk8.0 -- Tk8.4 */\nEXTERN struct dummy_TkMenuRef *TkFindMenuReferences(Tcl_Interp*, char*);\n#else /* based on Tk8.0 -- Tk8.5.0 */\n#define MENU_HASH_KEY \"tkMenus\"\n#endif\n\n#endif\n\nstatic VALUE\nip_make_menu_embeddable_core(interp, argc, argv)\n    VALUE interp;\n    int   argc;\n    VALUE *argv;\n{\n#if TCL_MAJOR_VERSION >= 8\n    volatile VALUE menu_path;\n    struct tcltkip *ptr = get_ip(interp);\n    struct dummy_TkMenuRef *menuRefPtr = NULL;\n    XEvent event;\n    Tcl_HashTable *menuTablePtr;\n    Tcl_HashEntry *hashEntryPtr;\n\n    menu_path = argv[0];\n    StringValue(menu_path);\n\n#if 0 /* was available on Tk8.0 -- Tk8.4 */\n    menuRefPtr = TkFindMenuReferences(ptr->ip, RSTRING_PTR(menu_path));\n#else /* based on Tk8.0 -- Tk8.5b1 */\n    if ((menuTablePtr \n\t = (Tcl_HashTable *) Tcl_GetAssocData(ptr->ip, MENU_HASH_KEY, NULL))\n\t!= NULL) {\n      if ((hashEntryPtr \n\t   = Tcl_FindHashEntry(menuTablePtr, RSTRING_PTR(menu_path)))\n\t  != NULL) {\n        menuRefPtr = (struct dummy_TkMenuRef *) Tcl_GetHashValue(hashEntryPtr);\n      }\n    }\n#endif\n\n    if (menuRefPtr == (struct dummy_TkMenuRef *) NULL) {\n        rb_raise(rb_eArgError, \"not a menu widget, or invalid widget path\");\n    }\n\n    if (menuRefPtr->menuPtr == (struct dummy_TkMenu *) NULL) {\n        rb_raise(rb_eRuntimeError, \n\t\t \"invalid menu widget (maybe already destroyed)\");\n    }\n\n    if ((menuRefPtr->menuPtr)->menuType != MENUBAR) {\n        rb_raise(rb_eRuntimeError, \n\t\t \"target menu widget must be a MENUBAR type\");\n    }\n\n    (menuRefPtr->menuPtr)->menuType = TEAROFF_MENU;\n#if 0  /* cause SEGV */\n    {\n       /* char *s = \"tearoff\"; */\n       char *s = \"normal\";\n       /* Tcl_SetStringObj((menuRefPtr->menuPtr)->menuTypePtr, s, strlen(s));*/\n       (menuRefPtr->menuPtr)->menuTypePtr = Tcl_NewStringObj(s, strlen(s));\n       /* Tcl_IncrRefCount((menuRefPtr->menuPtr)->menuTypePtr); */\n       /* (menuRefPtr->menuPtr)->menuType = TEAROFF_MENU; */\n       (menuRefPtr->menuPtr)->menuType = MASTER_MENU;\n    }\n#endif\n\n#if 0 /* was available on Tk8.0 -- Tk8.4 */\n    TkEventuallyRecomputeMenu(menuRefPtr->menuPtr);\n    TkEventuallyRedrawMenu(menuRefPtr->menuPtr, \n\t\t\t   (struct dummy_TkMenuEntry *)NULL);\n#else /* based on Tk8.0 -- Tk8.5b1 */\n    memset((void *) &event, 0, sizeof(event));\n    event.xany.type = ConfigureNotify;\n    event.xany.serial = NextRequest(Tk_Display((menuRefPtr->menuPtr)->tkwin));\n    event.xany.send_event = 0; /* FALSE */\n    event.xany.window = Tk_WindowId((menuRefPtr->menuPtr)->tkwin);\n    event.xany.display = Tk_Display((menuRefPtr->menuPtr)->tkwin);\n    event.xconfigure.window = event.xany.window;\n    Tk_HandleEvent(&event);\n#endif\n\n#else /* TCL_MAJOR_VERSION <= 7 */\n    rb_notimplement();\n#endif\n\n    return interp;\n}\n\nstatic VALUE\nip_make_menu_embeddable(interp, menu_path)\n    VALUE interp;\n    VALUE menu_path;\n{\n    VALUE argv[1];\n\n    argv[0] = menu_path;\n    return tk_funcall(ip_make_menu_embeddable_core, 1, argv, interp);\n}\n\n\n/*###############################################*/\n\n/*---- initialization ----*/\nvoid\nInit_tcltklib()\n{\n    int  ret;\n\n    VALUE lib = rb_define_module(\"TclTkLib\");\n    VALUE ip = rb_define_class(\"TclTkIp\", rb_cObject);\n\n    VALUE ev_flag = rb_define_module_under(lib, \"EventFlag\");\n    VALUE var_flag = rb_define_module_under(lib, \"VarAccessFlag\");\n    VALUE release_type = rb_define_module_under(lib, \"RELEASE_TYPE\");\n\n    /* --------------------------------------------------------------- */\n\n    tcltkip_class = ip;\n\n    /* --------------------------------------------------------------- */\n\n#ifdef RUBY_VM\n    rb_global_variable(&cRubyEncoding);\n    cRubyEncoding = rb_const_get(rb_cObject, rb_intern(\"Encoding\"));\n\n    ENCODING_INDEX_UTF8   = rb_enc_to_index(rb_utf8_encoding());\n    ENCODING_INDEX_BINARY = rb_enc_find_index(\"binary\");\n#endif\n\n    rb_global_variable(&ENCODING_NAME_UTF8);\n    rb_global_variable(&ENCODING_NAME_BINARY);\n\n    ENCODING_NAME_UTF8   = rb_obj_freeze(rb_str_new2(\"utf-8\"));\n    ENCODING_NAME_BINARY = rb_obj_freeze(rb_str_new2(\"binary\"));\n\n    /* --------------------------------------------------------------- */\n\n    rb_global_variable(&eTkCallbackReturn);\n    rb_global_variable(&eTkCallbackBreak);\n    rb_global_variable(&eTkCallbackContinue);\n\n    rb_global_variable(&eventloop_thread);\n    rb_global_variable(&eventloop_stack);\n    rb_global_variable(&watchdog_thread);\n\n    rb_global_variable(&rbtk_pending_exception);\n\n   /* --------------------------------------------------------------- */\n\n    rb_define_const(lib, \"COMPILE_INFO\", tcltklib_compile_info());\n\n    rb_define_const(lib, \"RELEASE_DATE\", \n                    rb_obj_freeze(rb_str_new2(tcltklib_release_date)));\n\n    rb_define_const(lib, \"FINALIZE_PROC_NAME\", \n                    rb_str_new2(finalize_hook_name));\n\n   /* --------------------------------------------------------------- */\n\n    rb_define_const(ev_flag, \"NONE\",      INT2FIX(0));\n    rb_define_const(ev_flag, \"WINDOW\",    INT2FIX(TCL_WINDOW_EVENTS));\n    rb_define_const(ev_flag, \"FILE\",      INT2FIX(TCL_FILE_EVENTS));\n    rb_define_const(ev_flag, \"TIMER\",     INT2FIX(TCL_TIMER_EVENTS));\n    rb_define_const(ev_flag, \"IDLE\",      INT2FIX(TCL_IDLE_EVENTS));\n    rb_define_const(ev_flag, \"ALL\",       INT2FIX(TCL_ALL_EVENTS));\n    rb_define_const(ev_flag, \"DONT_WAIT\", INT2FIX(TCL_DONT_WAIT));\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_const(var_flag, \"NONE\",           INT2FIX(0));\n    rb_define_const(var_flag, \"GLOBAL_ONLY\",    INT2FIX(TCL_GLOBAL_ONLY));\n#ifdef TCL_NAMESPACE_ONLY\n    rb_define_const(var_flag, \"NAMESPACE_ONLY\", INT2FIX(TCL_NAMESPACE_ONLY));\n#else /* probably Tcl7.6 */\n    rb_define_const(var_flag, \"NAMESPACE_ONLY\", INT2FIX(0));\n#endif\n    rb_define_const(var_flag, \"LEAVE_ERR_MSG\",  INT2FIX(TCL_LEAVE_ERR_MSG));\n    rb_define_const(var_flag, \"APPEND_VALUE\",   INT2FIX(TCL_APPEND_VALUE));\n    rb_define_const(var_flag, \"LIST_ELEMENT\",   INT2FIX(TCL_LIST_ELEMENT));\n#ifdef TCL_PARSE_PART1\n    rb_define_const(var_flag, \"PARSE_VARNAME\",  INT2FIX(TCL_PARSE_PART1));\n#else /* probably Tcl7.6 */\n    rb_define_const(var_flag, \"PARSE_VARNAME\",  INT2FIX(0));\n#endif\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_module_function(lib, \"get_version\", lib_getversion, -1);\n\n    rb_define_const(release_type, \"ALPHA\", INT2FIX(TCL_ALPHA_RELEASE));\n    rb_define_const(release_type, \"BETA\",  INT2FIX(TCL_BETA_RELEASE));\n    rb_define_const(release_type, \"FINAL\", INT2FIX(TCL_FINAL_RELEASE));\n\n    /* --------------------------------------------------------------- */\n\n    eTkCallbackReturn = rb_define_class(\"TkCallbackReturn\", rb_eStandardError);\n    eTkCallbackBreak = rb_define_class(\"TkCallbackBreak\", rb_eStandardError);\n    eTkCallbackContinue = rb_define_class(\"TkCallbackContinue\",\n                                          rb_eStandardError);\n\n    /* --------------------------------------------------------------- */\n\n    eLocalJumpError = rb_const_get(rb_cObject, rb_intern(\"LocalJumpError\"));\n\n    eTkLocalJumpError = rb_define_class(\"TkLocalJumpError\", eLocalJumpError);\n\n    eTkCallbackRetry  = rb_define_class(\"TkCallbackRetry\", eTkLocalJumpError);\n    eTkCallbackRedo   = rb_define_class(\"TkCallbackRedo\",  eTkLocalJumpError);\n    eTkCallbackThrow  = rb_define_class(\"TkCallbackThrow\", eTkLocalJumpError);\n\n    /* --------------------------------------------------------------- */\n\n    ID_at_enc = rb_intern(\"@encoding\");\n    ID_at_interp = rb_intern(\"@interp\");\n    ID_encoding_name = rb_intern(\"encoding_name\");\n    ID_encoding_table = rb_intern(\"encoding_table\");\n\n    ID_stop_p = rb_intern(\"stop?\");\n    ID_alive_p = rb_intern(\"alive?\");\n    ID_kill = rb_intern(\"kill\");\n    ID_join = rb_intern(\"join\");\n    ID_value = rb_intern(\"value\");\n\n    ID_call = rb_intern(\"call\");\n    ID_backtrace = rb_intern(\"backtrace\");\n    ID_message = rb_intern(\"message\");\n\n    ID_at_reason = rb_intern(\"@reason\");\n    ID_return = rb_intern(\"return\");\n    ID_break = rb_intern(\"break\");\n    ID_next = rb_intern(\"next\");\n\n    ID_to_s = rb_intern(\"to_s\");\n    ID_inspect = rb_intern(\"inspect\");\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_module_function(lib, \"mainloop\", lib_mainloop, -1);\n    rb_define_module_function(lib, \"mainloop_thread?\", \n                              lib_evloop_thread_p, 0);\n    rb_define_module_function(lib, \"mainloop_watchdog\", \n                              lib_mainloop_watchdog, -1);\n    rb_define_module_function(lib, \"do_thread_callback\", \n                              lib_thread_callback, -1);\n    rb_define_module_function(lib, \"do_one_event\", lib_do_one_event, -1);\n    rb_define_module_function(lib, \"mainloop_abort_on_exception\", \n                             lib_evloop_abort_on_exc, 0);\n    rb_define_module_function(lib, \"mainloop_abort_on_exception=\",  \n                             lib_evloop_abort_on_exc_set, 1);\n    rb_define_module_function(lib, \"set_eventloop_window_mode\", \n\t\t\t      set_eventloop_window_mode, 1);\n    rb_define_module_function(lib, \"get_eventloop_window_mode\", \n\t\t\t      get_eventloop_window_mode, 0);\n    rb_define_module_function(lib, \"set_eventloop_tick\",set_eventloop_tick,1);\n    rb_define_module_function(lib, \"get_eventloop_tick\",get_eventloop_tick,0);\n    rb_define_module_function(lib, \"set_no_event_wait\", set_no_event_wait, 1);\n    rb_define_module_function(lib, \"get_no_event_wait\", get_no_event_wait, 0);\n    rb_define_module_function(lib, \"set_eventloop_weight\", \n                              set_eventloop_weight, 2);\n    rb_define_module_function(lib, \"set_max_block_time\", set_max_block_time,1);\n    rb_define_module_function(lib, \"get_eventloop_weight\", \n                              get_eventloop_weight, 0);\n    rb_define_module_function(lib, \"num_of_mainwindows\", \n                              lib_num_of_mainwindows, 0);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_module_function(lib, \"_split_tklist\", lib_split_tklist, 1);\n    rb_define_module_function(lib, \"_merge_tklist\", lib_merge_tklist, -1);\n    rb_define_module_function(lib, \"_conv_listelement\", \n                              lib_conv_listelement, 1);\n    rb_define_module_function(lib, \"_toUTF8\", lib_toUTF8, -1);\n    rb_define_module_function(lib, \"_fromUTF8\", lib_fromUTF8, -1);\n    rb_define_module_function(lib, \"_subst_UTF_backslash\", \n                              lib_UTF_backslash, 1);\n    rb_define_module_function(lib, \"_subst_Tcl_backslash\", \n                              lib_Tcl_backslash, 1);\n\n    rb_define_module_function(lib, \"encoding_system\", \n                              lib_get_system_encoding, 0);\n    rb_define_module_function(lib, \"encoding_system=\", \n                              lib_set_system_encoding, 1);\n    rb_define_module_function(lib, \"encoding\", \n                              lib_get_system_encoding, 0);\n    rb_define_module_function(lib, \"encoding=\", \n                              lib_set_system_encoding, 1);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_alloc_func(ip, ip_alloc);\n    rb_define_method(ip, \"initialize\", ip_init, -1);\n    rb_define_method(ip, \"create_slave\", ip_create_slave, -1);\n    rb_define_method(ip, \"slave_of?\", ip_is_slave_of_p, 1);\n    rb_define_method(ip, \"make_safe\", ip_make_safe, 0);\n    rb_define_method(ip, \"safe?\", ip_is_safe_p, 0);\n    rb_define_method(ip, \"allow_ruby_exit?\", ip_allow_ruby_exit_p, 0);\n    rb_define_method(ip, \"allow_ruby_exit=\", ip_allow_ruby_exit_set, 1);\n    rb_define_method(ip, \"delete\", ip_delete, 0);\n    rb_define_method(ip, \"deleted?\", ip_is_deleted_p, 0);\n    rb_define_method(ip, \"has_mainwindow?\", ip_has_mainwindow_p, 0);\n    rb_define_method(ip, \"invalid_namespace?\", ip_has_invalid_namespace_p, 0);\n    rb_define_method(ip, \"_eval\", ip_eval, 1);\n    rb_define_method(ip, \"_toUTF8\", ip_toUTF8, -1);\n    rb_define_method(ip, \"_fromUTF8\", ip_fromUTF8, -1);\n    rb_define_method(ip, \"_thread_vwait\", ip_thread_vwait, 1);\n    rb_define_method(ip, \"_thread_tkwait\", ip_thread_tkwait, 2);\n    rb_define_method(ip, \"_invoke\", ip_invoke, -1);\n    rb_define_method(ip, \"_immediate_invoke\", ip_invoke_immediate, -1);\n    rb_define_method(ip, \"_return_value\", ip_retval, 0);\n\n    rb_define_method(ip, \"_create_console\", ip_create_console, 0);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_method(ip, \"create_dummy_encoding_for_tk\", \n\t\t     create_dummy_encoding_for_tk, 1);\n    rb_define_method(ip, \"encoding_table\", ip_get_encoding_table, 0);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_method(ip, \"_get_variable\", ip_get_variable, 2);\n    rb_define_method(ip, \"_get_variable2\", ip_get_variable2, 3);\n    rb_define_method(ip, \"_set_variable\", ip_set_variable, 3);\n    rb_define_method(ip, \"_set_variable2\", ip_set_variable2, 4);\n    rb_define_method(ip, \"_unset_variable\", ip_unset_variable, 2);\n    rb_define_method(ip, \"_unset_variable2\", ip_unset_variable2, 3);\n    rb_define_method(ip, \"_get_global_var\", ip_get_global_var, 1);\n    rb_define_method(ip, \"_get_global_var2\", ip_get_global_var2, 2);\n    rb_define_method(ip, \"_set_global_var\", ip_set_global_var, 2);\n    rb_define_method(ip, \"_set_global_var2\", ip_set_global_var2, 3);\n    rb_define_method(ip, \"_unset_global_var\", ip_unset_global_var, 1);\n    rb_define_method(ip, \"_unset_global_var2\", ip_unset_global_var2, 2);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_method(ip, \"_make_menu_embeddable\", ip_make_menu_embeddable, 1);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_method(ip, \"_split_tklist\", ip_split_tklist, 1);\n    rb_define_method(ip, \"_merge_tklist\", lib_merge_tklist, -1);\n    rb_define_method(ip, \"_conv_listelement\", lib_conv_listelement, 1);\n\n    /* --------------------------------------------------------------- */\n\n    rb_define_method(ip, \"mainloop\", ip_mainloop, -1);\n    rb_define_method(ip, \"mainloop_watchdog\", ip_mainloop_watchdog, -1);\n    rb_define_method(ip, \"do_one_event\", ip_do_one_event, -1);\n    rb_define_method(ip, \"mainloop_abort_on_exception\", \n                    ip_evloop_abort_on_exc, 0);\n    rb_define_method(ip, \"mainloop_abort_on_exception=\", \n                    ip_evloop_abort_on_exc_set, 1);\n    rb_define_method(ip, \"set_eventloop_tick\", ip_set_eventloop_tick, 1);\n    rb_define_method(ip, \"get_eventloop_tick\", ip_get_eventloop_tick, 0);\n    rb_define_method(ip, \"set_no_event_wait\", ip_set_no_event_wait, 1);\n    rb_define_method(ip, \"get_no_event_wait\", ip_get_no_event_wait, 0);\n    rb_define_method(ip, \"set_eventloop_weight\", ip_set_eventloop_weight, 2);\n    rb_define_method(ip, \"get_eventloop_weight\", ip_get_eventloop_weight, 0);\n    rb_define_method(ip, \"set_max_block_time\", set_max_block_time, 1);\n    rb_define_method(ip, \"restart\", ip_restart, 0);\n\n    /* --------------------------------------------------------------- */\n\n    eventloop_thread = Qnil;\n\n#ifndef DEFAULT_EVENTLOOP_DEPTH\n#define DEFAULT_EVENTLOOP_DEPTH 7\n#endif \n    eventloop_stack = rb_ary_new2(DEFAULT_EVENTLOOP_DEPTH);\n    OBJ_TAINT(eventloop_stack);\n\n    watchdog_thread  = Qnil;\n\n    rbtk_pending_exception = Qnil;\n\n    /* --------------------------------------------------------------- */\n\n    /* if ruby->nativethread-supprt and tcltklib->doen't, \n       the following will cause link-error. */\n#ifdef RUBY_VM\n    ruby_native_thread_p();\n#else\n    is_ruby_native_thread();\n#endif\n\n    /* --------------------------------------------------------------- */\n\n    rb_set_end_proc(lib_mark_at_exit, 0);\n\n    /* --------------------------------------------------------------- */\n\n    ret = ruby_open_tcl_dll(rb_argv0 ? RSTRING_PTR(rb_argv0) : 0);\n    switch(ret) {\n    case TCLTK_STUBS_OK:\n        break;\n    case NO_TCL_DLL:\n        rb_raise(rb_eLoadError, \"tcltklib: fail to open tcl_dll\");\n    case NO_FindExecutable:\n        rb_raise(rb_eLoadError, \"tcltklib: can't find Tcl_FindExecutable\");\n    default:\n        rb_raise(rb_eLoadError, \"tcltklib: unknown error(%d) on ruby_open_tcl_dll\", ret);\n    }\n\n    /* --------------------------------------------------------------- */\n\n    /* Tcl stub check */\n    tcl_stubs_check();\n\n    Tcl_ObjType_ByteArray = Tcl_GetObjType(Tcl_ObjTypeName_ByteArray);\n    Tcl_ObjType_String    = Tcl_GetObjType(Tcl_ObjTypeName_String);\n\n    /* --------------------------------------------------------------- */\n}\n\n/* eof */\n"
  },
  {
    "path": "ext/tk/tkutil/.cvsignore",
    "content": "Makefile\n*.log\n*.def\n"
  },
  {
    "path": "ext/tk/tkutil/depend",
    "content": "tkutil.o: tkutil.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h\n"
  },
  {
    "path": "ext/tk/tkutil/extconf.rb",
    "content": "begin\n  has_tk = compiled?('tk')\nrescue NoMethodError\n  # Probably, called manually (NOT from 'extmk.rb'). Force to make Makefile.\n  has_tk = true\nend\n\nif has_tk\n  require 'mkmf'\n  have_func(\"rb_obj_instance_exec\", \"ruby.h\")\n  have_func(\"strndup\", \"string.h\")\n  create_makefile('tkutil')\nend\n"
  },
  {
    "path": "ext/tk/tkutil/tkutil.c",
    "content": "/************************************************\n\n  tkutil.c -\n\n  $Author$\n  created at: Fri Nov  3 00:47:54 JST 1995\n\n************************************************/\n\n#define TKUTIL_RELEASE_DATE \"2008-05-23\"\n\n#include \"ruby.h\"\n\n#ifdef RUBY_VM  /* Ruby 1.9 */\n/* #include \"ruby/ruby.h\" */\n#include \"ruby/signal.h\"\n#include \"ruby/st.h\"\n#else\n/* #include \"ruby.h\" */\n#include \"rubysig.h\"\n#include \"version.h\"\n#include \"st.h\"\n#endif\n\nstatic VALUE cMethod;\n\nstatic VALUE cTclTkLib;\n\nstatic VALUE cTkObject;\nstatic VALUE cTkCallbackEntry;\n\nstatic VALUE TK_None;\n\nstatic VALUE cCB_SUBST;\nstatic VALUE cSUBST_INFO;\n\nstatic VALUE ENCODING_NAME_UTF8; /* for saving GC cost */\n\nstatic ID ID_split_tklist;\nstatic ID ID_toUTF8;\nstatic ID ID_fromUTF8;\nstatic ID ID_path;\nstatic ID ID_at_path;\nstatic ID ID_at_enc;\nstatic ID ID_to_eval;\nstatic ID ID_to_s;\nstatic ID ID_source;\nstatic ID ID_downcase;\nstatic ID ID_install_cmd;\nstatic ID ID_merge_tklist;\nstatic ID ID_encoding;\nstatic ID ID_encoding_system;\nstatic ID ID_call;\n\nstatic ID ID_SUBST_INFO;\n\nstatic VALUE CALLBACK_TABLE;\nstatic unsigned long CALLBACK_ID_NUM = 0;\n\n/*************************************/\n\nstatic VALUE\ntk_s_new(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj = rb_class_new_instance(argc, argv, klass);\n\n    if (rb_block_given_p()) {\n#ifndef HAVE_RB_OBJ_INSTANCE_EXEC\n      rb_obj_instance_eval(0, 0, obj);\n#else\n      rb_obj_instance_exec(1, &obj, obj);\n#endif\n    }\n    return obj;\n}\n\n/*************************************/\n\nstatic VALUE\ntkNone_to_s(self)\n    VALUE self;\n{\n    return rb_str_new2(\"None\");\n}\n\n/*************************************/\n\nstatic VALUE\ntk_eval_cmd(argc, argv, self)\n    int argc;\n    VALUE argv[];\n    VALUE self;\n{\n    volatile VALUE cmd, rest;\n\n    rb_scan_args(argc, argv, \"1*\", &cmd, &rest);\n    return rb_eval_cmd(cmd, rest, 0);\n}\n\nstatic VALUE\ntk_do_callback(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n#if 0\n    volatile VALUE id;\n    volatile VALUE rest;\n\n    rb_scan_args(argc, argv, \"1*\", &id, &rest);\n    return rb_apply(rb_hash_aref(CALLBACK_TABLE, id), ID_call, rest);\n#endif\n    return rb_funcall2(rb_hash_aref(CALLBACK_TABLE, argv[0]), \n                       ID_call, argc - 1, argv + 1);\n}\n\nstatic char *cmd_id_head = \"ruby_cmd TkUtil callback \";\nstatic char *cmd_id_prefix = \"cmd\";\n\nstatic VALUE\ntk_install_cmd_core(cmd)\n    VALUE cmd;\n{\n    volatile VALUE id_num;\n\n    id_num = ULONG2NUM(CALLBACK_ID_NUM++);\n    id_num = rb_funcall(id_num, ID_to_s, 0, 0);\n    id_num = rb_str_append(rb_str_new2(cmd_id_prefix), id_num);\n    rb_hash_aset(CALLBACK_TABLE, id_num, cmd);\n    return rb_str_append(rb_str_new2(cmd_id_head), id_num);\n}\n\nstatic VALUE\ntk_install_cmd(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    volatile VALUE cmd;\n\n#if 0\n    if (rb_scan_args(argc, argv, \"01\", &cmd) == 0) {\n        cmd = rb_block_proc();\n    }\n    return tk_install_cmd_core(cmd);\n#endif\n    if (argc == 0) {\n        cmd = rb_block_proc();\n    } else {\n        cmd = argv[0];\n    }\n    return tk_install_cmd_core(cmd);\n}\n\nstatic VALUE\ntk_uninstall_cmd(self, cmd_id)\n    VALUE self;\n    VALUE cmd_id;\n{\n    int head_len = strlen(cmd_id_head);\n    int prefix_len = strlen(cmd_id_prefix);\n\n    StringValue(cmd_id);\n    if (strncmp(cmd_id_head, RSTRING_PTR(cmd_id), head_len) != 0) {\n        return Qnil;\n    }\n    if (strncmp(cmd_id_prefix, \n                RSTRING_PTR(cmd_id) + head_len, prefix_len) != 0) {\n        return Qnil;\n    }\n\n    return rb_hash_delete(CALLBACK_TABLE, \n                          rb_str_new2(RSTRING_PTR(cmd_id) + head_len));\n}\n\nstatic VALUE\ntk_toUTF8(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return rb_funcall2(cTclTkLib, ID_toUTF8, argc, argv);\n}\n\nstatic VALUE\ntk_fromUTF8(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return rb_funcall2(cTclTkLib, ID_fromUTF8, argc, argv);\n}\n\nstatic VALUE\nfromDefaultEnc_toUTF8(str, self)\n    VALUE str;\n    VALUE self;\n{\n    VALUE argv[1];\n\n    argv[0] = str;\n    return tk_toUTF8(1, argv, self);\n}\n\nstatic VALUE\nfromUTF8_toDefaultEnc(str, self)\n    VALUE str;\n    VALUE self;\n{\n    VALUE argv[1];\n\n    argv[0] = str;\n    return tk_fromUTF8(1, argv, self);\n}\n\nstatic int\nto_strkey(key, value, hash)\n    VALUE key;\n    VALUE value;\n    VALUE hash;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_hash_aset(hash, rb_funcall(key, ID_to_s, 0, 0), value);\n    return ST_CHECK;\n}\n\nstatic VALUE\ntk_symbolkey2str(self, keys)\n    VALUE self;\n    VALUE keys;\n{\n    volatile VALUE new_keys = rb_hash_new();\n\n    if NIL_P(keys) return new_keys;\n    keys = rb_convert_type(keys, T_HASH, \"Hash\", \"to_hash\");\n    st_foreach(RHASH_TBL(keys), to_strkey, new_keys);\n    return new_keys;\n}\n\nstatic VALUE get_eval_string_core _((VALUE, VALUE, VALUE));\nstatic VALUE ary2list _((VALUE, VALUE, VALUE));\nstatic VALUE ary2list2 _((VALUE, VALUE, VALUE));\nstatic VALUE hash2list _((VALUE, VALUE));\nstatic VALUE hash2list_enc _((VALUE, VALUE));\nstatic VALUE hash2kv _((VALUE, VALUE, VALUE));\nstatic VALUE hash2kv_enc _((VALUE, VALUE, VALUE));\n\nstatic VALUE\nary2list(ary, enc_flag, self)\n    VALUE ary;\n    VALUE enc_flag;\n    VALUE self;\n{\n    int idx, idx2, size, size2, req_chk_flag;\n    volatile VALUE val, val2, str_val;\n    volatile VALUE dst;\n    volatile VALUE sys_enc, dst_enc, str_enc;\n\n    sys_enc = rb_funcall(cTclTkLib, ID_encoding, 0, 0);\n    if (NIL_P(sys_enc)) {\n      sys_enc = rb_funcall(cTclTkLib, ID_encoding_system, 0, 0);\n      sys_enc = rb_funcall(sys_enc, ID_to_s, 0, 0);\n    }\n\n    if NIL_P(enc_flag) {\n        dst_enc = sys_enc;\n        req_chk_flag = 1;\n    } else if (TYPE(enc_flag) == T_TRUE || TYPE(enc_flag) == T_FALSE) {\n        dst_enc = enc_flag;\n        req_chk_flag = 0;\n    } else {\n        dst_enc = rb_funcall(enc_flag, ID_to_s, 0, 0);\n        req_chk_flag = 0;\n    }\n\n    /* size = RARRAY_LEN(ary); */\n    size = 0;\n    for(idx = 0; idx < RARRAY_LEN(ary); idx++) {\n        if (TYPE(RARRAY_PTR(ary)[idx]) == T_HASH) {\n            size += 2 * RHASH_SIZE(RARRAY_PTR(ary)[idx]);\n        } else {\n            size++;\n        }\n    }\n\n    dst = rb_ary_new2(size);\n    for(idx = 0; idx < RARRAY_LEN(ary); idx++) {\n        val = RARRAY_PTR(ary)[idx];\n        str_val = Qnil;\n        switch(TYPE(val)) {\n        case T_ARRAY:\n            str_val = ary2list(val, enc_flag, self);\n            rb_ary_push(dst, str_val);\n\n            if (req_chk_flag) {\n                str_enc = rb_ivar_get(str_val, ID_at_enc);\n                if (!NIL_P(str_enc)) {\n                    str_enc = rb_funcall(str_enc, ID_to_s, 0, 0);\n                } else {\n                    str_enc = sys_enc;\n                }\n                if (!rb_str_cmp(str_enc, dst_enc)) {\n                    dst_enc = Qtrue;\n                    req_chk_flag = 0;\n                }\n            }\n\n            break;\n\n        case T_HASH:\n\t    /* rb_ary_push(dst, hash2list(val, self)); */\n            if (RTEST(enc_flag)) {\n                val = hash2kv_enc(val, Qnil, self);\n            } else {\n                val = hash2kv(val, Qnil, self);\n            }\n            size2 = RARRAY_LEN(val);\n            for(idx2 = 0; idx2 < size2; idx2++) {\n                val2 = RARRAY_PTR(val)[idx2];\n                switch(TYPE(val2)) {\n                case T_ARRAY:\n                    str_val = ary2list(val2, enc_flag, self);\n                    rb_ary_push(dst, str_val);\n                    break;\n\n                case T_HASH:\n                    if (RTEST(enc_flag)) {\n                        str_val = hash2list_enc(val2, self);\n                    } else {\n                        str_val = hash2list(val2, self);\n                    }\n                    rb_ary_push(dst, str_val);\n                    break;\n\n                default:\n                    if (val2 != TK_None) {\n                        str_val = get_eval_string_core(val2, enc_flag, self);\n                        rb_ary_push(dst, str_val);\n                    }\n                }\n\n                if (req_chk_flag) {\n                    str_enc = rb_ivar_get(str_val, ID_at_enc);\n                    if (!NIL_P(str_enc)) {\n                        str_enc = rb_funcall(str_enc, ID_to_s, 0, 0);\n                    } else {\n                        str_enc = sys_enc;\n                    }\n                    if (!rb_str_cmp(str_enc, dst_enc)) {\n                        dst_enc = Qtrue;\n                        req_chk_flag = 0;\n                    }\n                }\n            }\n            break;\n\n        default:\n            if (val != TK_None) {\n                str_val = get_eval_string_core(val, enc_flag, self);\n                rb_ary_push(dst, str_val);\n\n                if (req_chk_flag) {\n                    str_enc = rb_ivar_get(str_val, ID_at_enc);\n                    if (!NIL_P(str_enc)) {\n                        str_enc = rb_funcall(str_enc, ID_to_s, 0, 0);\n                    } else {\n                        str_enc = sys_enc;\n                    }\n                    if (!rb_str_cmp(str_enc, dst_enc)) {\n                        dst_enc = Qtrue;\n                        req_chk_flag = 0;\n                    }\n                }\n            }\n        }\n    }\n\n    if (RTEST(dst_enc) && !NIL_P(sys_enc)) {\n        for(idx = 0; idx < RARRAY_LEN(dst); idx++) {\n            str_val = RARRAY_PTR(dst)[idx];\n            if (rb_obj_respond_to(self, ID_toUTF8, Qtrue)) {\n                str_val = rb_funcall(self, ID_toUTF8, 1, str_val);\n            } else {\n                str_val = rb_funcall(cTclTkLib, ID_toUTF8, 1, str_val);\n            }\n            RARRAY_PTR(dst)[idx] = str_val;\n        }\n        val = rb_apply(cTclTkLib, ID_merge_tklist, dst);\n        if (TYPE(dst_enc) == T_STRING) {\n            val = rb_funcall(cTclTkLib, ID_fromUTF8, 2, val, dst_enc);\n            rb_ivar_set(val, ID_at_enc, dst_enc);\n        } else {\n            rb_ivar_set(val, ID_at_enc, ENCODING_NAME_UTF8);\n        }\n        return val;\n    } else {\n        return rb_apply(cTclTkLib, ID_merge_tklist, dst);\n    }\n}\n\nstatic VALUE\nary2list2(ary, enc_flag, self)\n    VALUE ary;\n    VALUE enc_flag;\n    VALUE self;\n{\n    int idx, size, req_chk_flag;\n    volatile VALUE val, str_val;\n    volatile VALUE dst;\n    volatile VALUE sys_enc, dst_enc, str_enc;\n\n    sys_enc = rb_funcall(cTclTkLib, ID_encoding, 0, 0);\n    if NIL_P(sys_enc) {\n      sys_enc = rb_funcall(cTclTkLib, ID_encoding_system, 0, 0);\n      sys_enc = rb_funcall(sys_enc, ID_to_s, 0, 0);\n    }\n\n    if NIL_P(enc_flag) {\n        dst_enc = sys_enc;\n        req_chk_flag = 1;\n    } else if (TYPE(enc_flag) == T_TRUE || TYPE(enc_flag) == T_FALSE) {\n        dst_enc = enc_flag;\n        req_chk_flag = 0;\n    } else {\n        dst_enc = rb_funcall(enc_flag, ID_to_s, 0, 0);\n        req_chk_flag = 0;\n    }\n\n    size = RARRAY_LEN(ary);\n    dst = rb_ary_new2(size);\n    for(idx = 0; idx < RARRAY_LEN(ary); idx++) {\n        val = RARRAY_PTR(ary)[idx];\n        str_val = Qnil;\n        switch(TYPE(val)) {\n        case T_ARRAY:\n            str_val = ary2list(val, enc_flag, self);\n            break;\n\n        case T_HASH:\n            if (RTEST(enc_flag)) {\n                str_val = hash2list(val, self);\n            } else {\n                str_val = hash2list_enc(val, self);\n            }\n            break;\n\n        default:\n            if (val != TK_None) {\n                str_val = get_eval_string_core(val, enc_flag, self);\n            }\n        }\n\n        if (!NIL_P(str_val)) {\n            rb_ary_push(dst, str_val);\n\n            if (req_chk_flag) {\n                str_enc = rb_ivar_get(str_val, ID_at_enc);\n                if (!NIL_P(str_enc)) {\n                    str_enc = rb_funcall(str_enc, ID_to_s, 0, 0);\n                } else {\n                    str_enc = sys_enc;\n                }\n                if (!rb_str_cmp(str_enc, dst_enc)) {\n                    dst_enc = Qtrue;\n                    req_chk_flag = 0;\n                }\n            }\n        }\n    }\n\n    if (RTEST(dst_enc) && !NIL_P(sys_enc)) {\n        for(idx = 0; idx < RARRAY_LEN(dst); idx++) {\n            str_val = RARRAY_PTR(dst)[idx];\n            if (rb_obj_respond_to(self, ID_toUTF8, Qtrue)) {\n                str_val = rb_funcall(self, ID_toUTF8, 1, str_val);\n            } else {\n                str_val = rb_funcall(cTclTkLib, ID_toUTF8, 1, str_val);\n            }\n            RARRAY_PTR(dst)[idx] = str_val;\n        }\n        val = rb_apply(cTclTkLib, ID_merge_tklist, dst);\n        if (TYPE(dst_enc) == T_STRING) {\n            val = rb_funcall(cTclTkLib, ID_fromUTF8, 2, val, dst_enc);\n            rb_ivar_set(val, ID_at_enc, dst_enc);\n        } else {\n            rb_ivar_set(val, ID_at_enc, ENCODING_NAME_UTF8);\n        }\n        return val;\n    } else {\n        return rb_apply(cTclTkLib, ID_merge_tklist, dst);\n    }\n}\n\nstatic VALUE\nkey2keyname(key)\n    VALUE key;\n{\n    return rb_str_append(rb_str_new2(\"-\"), rb_funcall(key, ID_to_s, 0, 0));\n}\n\nstatic VALUE\nassoc2kv(assoc, ary, self)\n    VALUE assoc;\n    VALUE ary;\n    VALUE self;\n{\n    int i, j, len;\n    volatile VALUE pair;\n    volatile VALUE val;\n    volatile VALUE dst = rb_ary_new2(2 * RARRAY_LEN(assoc));\n\n    len = RARRAY_LEN(assoc);\n\n    for(i = 0; i < len; i++) {\n        pair = RARRAY_PTR(assoc)[i];\n        if (TYPE(pair) != T_ARRAY) {\n            rb_ary_push(dst, key2keyname(pair));\n            continue;\n        }\n        switch(RARRAY_LEN(assoc)) {\n        case 2:\n            rb_ary_push(dst, RARRAY_PTR(pair)[2]);\n\n        case 1:\n            rb_ary_push(dst, key2keyname(RARRAY_PTR(pair)[0]));\n\n        case 0:\n            continue;\n\n        default:\n            rb_ary_push(dst, key2keyname(RARRAY_PTR(pair)[0]));\n\n            val = rb_ary_new2(RARRAY_LEN(pair) - 1);\n            for(j = 1; j < RARRAY_LEN(pair); j++) {\n                rb_ary_push(val, RARRAY_PTR(pair)[j]);\n            }\n\n            rb_ary_push(dst, val);\n        }\n    }\n\n    if (NIL_P(ary)) {\n        return dst;\n    } else {\n        return rb_ary_plus(ary, dst);\n    }\n}\n\nstatic VALUE\nassoc2kv_enc(assoc, ary, self)\n    VALUE assoc;\n    VALUE ary;\n    VALUE self;\n{\n    int i, j, len;\n    volatile VALUE pair;\n    volatile VALUE val;\n    volatile VALUE dst = rb_ary_new2(2 * RARRAY_LEN(assoc));\n\n    len = RARRAY_LEN(assoc);\n\n    for(i = 0; i < len; i++) {\n        pair = RARRAY_PTR(assoc)[i];\n        if (TYPE(pair) != T_ARRAY) {\n            rb_ary_push(dst, key2keyname(pair));\n            continue;\n        }\n        switch(RARRAY_LEN(assoc)) {\n        case 2:\n            rb_ary_push(dst, get_eval_string_core(RARRAY_PTR(pair)[2], Qtrue, self));\n\n        case 1:\n            rb_ary_push(dst, key2keyname(RARRAY_PTR(pair)[0]));\n\n        case 0:\n            continue;\n\n        default:\n            rb_ary_push(dst, key2keyname(RARRAY_PTR(pair)[0]));\n\n            val = rb_ary_new2(RARRAY_LEN(pair) - 1);\n            for(j = 1; j < RARRAY_LEN(pair); j++) {\n                rb_ary_push(val, RARRAY_PTR(pair)[j]);\n            }\n\n            rb_ary_push(dst, get_eval_string_core(val, Qtrue, self));\n        }\n    }\n\n    if (NIL_P(ary)) {\n        return dst;\n    } else {\n        return rb_ary_plus(ary, dst);\n    }\n}\n\nstatic int\npush_kv(key, val, args)\n    VALUE key;\n    VALUE val;\n    VALUE args;\n{\n    volatile VALUE ary;\n\n    ary = RARRAY_PTR(args)[0];\n\n    if (key == Qundef) return ST_CONTINUE;\n#if 0\n    rb_ary_push(ary, key2keyname(key));\n    if (val != TK_None) rb_ary_push(ary, val);\n#endif\n    rb_ary_push(ary, key2keyname(key));\n\n    if (val == TK_None) return ST_CHECK;\n\n    rb_ary_push(ary, get_eval_string_core(val, Qnil, RARRAY_PTR(args)[1]));\n\n    return ST_CHECK;\n}\n\nstatic VALUE\nhash2kv(hash, ary, self)\n    VALUE hash;\n    VALUE ary;\n    VALUE self;\n{\n    volatile VALUE dst = rb_ary_new2(2 * RHASH_SIZE(hash));\n    volatile VALUE args = rb_ary_new3(2, dst, self);\n\n    st_foreach(RHASH_TBL(hash), push_kv, args);\n\n    if (NIL_P(ary)) {\n        return dst;\n    } else {\n        return rb_ary_concat(ary, dst);\n    }\n}\n\nstatic int\npush_kv_enc(key, val, args)\n    VALUE key;\n    VALUE val;\n    VALUE args;\n{\n    volatile VALUE ary;\n\n    ary = RARRAY_PTR(args)[0];\n\n    if (key == Qundef) return ST_CONTINUE;\n#if 0\n    rb_ary_push(ary, key2keyname(key));\n    if (val != TK_None) {\n        rb_ary_push(ary, get_eval_string_core(val, Qtrue, \n                                              RARRAY_PTR(args)[1]));\n    }\n#endif\n    rb_ary_push(ary, key2keyname(key));\n\n    if (val == TK_None) return ST_CHECK;\n\n    rb_ary_push(ary, get_eval_string_core(val, Qtrue, RARRAY_PTR(args)[1]));\n\n    return ST_CHECK;\n}\n\nstatic VALUE\nhash2kv_enc(hash, ary, self)\n    VALUE hash;\n    VALUE ary;\n    VALUE self;\n{\n    volatile VALUE dst = rb_ary_new2(2 * RHASH_SIZE(hash));\n    volatile VALUE args = rb_ary_new3(2, dst, self);\n\n    st_foreach(RHASH_TBL(hash), push_kv_enc, args);\n\n    if (NIL_P(ary)) {\n        return dst;\n    } else {\n        return rb_ary_concat(ary, dst);\n    }\n}\n\nstatic VALUE\nhash2list(hash, self)\n    VALUE hash;\n    VALUE self;\n{\n    return ary2list2(hash2kv(hash, Qnil, self), Qfalse, self);\n}\n\n\nstatic VALUE\nhash2list_enc(hash, self)\n    VALUE hash;\n    VALUE self;\n{\n    return ary2list2(hash2kv_enc(hash, Qnil, self), Qfalse, self);\n}\n\nstatic VALUE\ntk_hash_kv(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    volatile VALUE hash, enc_flag, ary;\n\n    ary = Qnil;\n    enc_flag = Qnil;\n    switch(argc) {\n    case 3:\n        ary = argv[2];\n    case 2:\n        enc_flag = argv[1];\n    case 1:\n        hash = argv[0];\n        break;\n    case 0:\n        rb_raise(rb_eArgError, \"too few arguments\");\n    default: /* >= 3 */\n        rb_raise(rb_eArgError, \"too many arguments\");\n    }\n\n    switch(TYPE(hash)) {\n    case T_ARRAY:\n        if (RTEST(enc_flag)) {\n            return assoc2kv_enc(hash, ary, self);\n        } else {\n            return assoc2kv(hash, ary, self);\n        }\n\n    case T_HASH:\n        if (RTEST(enc_flag)) {\n            return hash2kv_enc(hash, ary, self);\n        } else {\n            return hash2kv(hash, ary, self);\n        }\n\n    case T_NIL:\n        if (NIL_P(ary)) {\n            return rb_ary_new();\n        } else {\n            return ary;\n        }\n\n    default:\n        if (hash == TK_None) {\n            if (NIL_P(ary)) {\n                return rb_ary_new();\n            } else {\n                return ary;\n            }\n        }\n        rb_raise(rb_eArgError, \"Hash is expected for 1st argument\");\n    }\n}\n\nstatic VALUE\nget_eval_string_core(obj, enc_flag, self)\n    VALUE obj;\n    VALUE enc_flag;\n    VALUE self;\n{\n    switch(TYPE(obj)) {\n    case T_FLOAT:\n    case T_FIXNUM:\n    case T_BIGNUM:\n        return rb_funcall(obj, ID_to_s, 0, 0);\n\n    case T_STRING:\n        if (RTEST(enc_flag)) {\n            if (rb_obj_respond_to(self, ID_toUTF8, Qtrue)) {\n                return rb_funcall(self, ID_toUTF8, 1, obj);\n            } else {\n                return fromDefaultEnc_toUTF8(obj, self);\n            }\n        } else {\n            return obj;\n        }\n\n    case T_SYMBOL:\n        if (RTEST(enc_flag)) {\n            if (rb_obj_respond_to(self, ID_toUTF8, Qtrue)) {\n                return rb_funcall(self, ID_toUTF8, 1, \n                                  rb_str_new2(rb_id2name(SYM2ID(obj))));\n            } else {\n                return fromDefaultEnc_toUTF8(rb_str_new2(rb_id2name(SYM2ID(obj))), self);\n            }\n        } else {\n#ifdef RUBY_VM\n            return rb_sym_to_s(obj);\n#else\n            return rb_str_new2(rb_id2name(SYM2ID(obj)));\n#endif\n        }\n\n    case T_HASH:\n        if (RTEST(enc_flag)) {\n            return hash2list_enc(obj, self);\n        } else {\n            return hash2list(obj, self);\n        }\n\n    case T_ARRAY:\n        return ary2list(obj, enc_flag, self);\n\n    case T_FALSE:\n        return rb_str_new2(\"0\");\n\n    case T_TRUE:\n        return rb_str_new2(\"1\");\n\n    case T_NIL:\n        return rb_str_new2(\"\");\n\n    case T_REGEXP:\n        return rb_funcall(obj, ID_source, 0, 0);\n\n    default:\n        if (rb_obj_is_kind_of(obj, cTkObject)) {\n            /* return rb_str_new3(rb_funcall(obj, ID_path, 0, 0)); */\n            return get_eval_string_core(rb_funcall(obj, ID_path, 0, 0), \n                                        enc_flag, self);\n        }\n\n        if (rb_obj_is_kind_of(obj, rb_cProc)\n            || rb_obj_is_kind_of(obj, cMethod)\n            || rb_obj_is_kind_of(obj, cTkCallbackEntry)) {\n            if (rb_obj_respond_to(self, ID_install_cmd, Qtrue)) {\n                return rb_funcall(self, ID_install_cmd, 1, obj);\n            } else {\n                return tk_install_cmd_core(obj);\n            }\n        }\n\n        if (obj == TK_None)  return Qnil;\n\n        if (rb_obj_respond_to(obj, ID_to_eval, Qtrue)) {\n            /* return rb_funcall(obj, ID_to_eval, 0, 0); */\n            return get_eval_string_core(rb_funcall(obj, ID_to_eval, 0, 0), \n                                        enc_flag, self);\n        } else if (rb_obj_respond_to(obj, ID_path, Qtrue)) {\n            /* return rb_funcall(obj, ID_path, 0, 0); */\n            return get_eval_string_core(rb_funcall(obj, ID_path, 0, 0), \n                                        enc_flag, self);\n        } else if (rb_obj_respond_to(obj, ID_to_s, Qtrue)) {\n            return rb_funcall(obj, ID_to_s, 0, 0);\n        }\n    }\n\n    rb_warning(\"fail to convert '%s' to string for Tk\", \n               RSTRING_PTR(rb_funcall(obj, rb_intern(\"inspect\"), 0, 0)));\n\n    return obj;\n}\n\nstatic VALUE\ntk_get_eval_string(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    volatile VALUE obj, enc_flag;\n\n    if (rb_scan_args(argc, argv, \"11\", &obj, &enc_flag) == 1) {\n        enc_flag = Qnil;\n    }\n\n    return get_eval_string_core(obj, enc_flag, self);\n}\n\nstatic VALUE\ntk_get_eval_enc_str(self, obj)\n    VALUE self;\n    VALUE obj;\n{\n    if (obj == TK_None) {\n        return obj;\n    } else {\n        return get_eval_string_core(obj, Qtrue, self);\n    }\n}\n\nstatic VALUE\ntk_conv_args(argc, argv, self)\n    int   argc;\n    VALUE *argv; /* [0]:base_array, [1]:enc_mode, [2]..[n]:args */\n    VALUE self;\n{\n    int idx, size;\n    volatile VALUE dst;\n    int thr_crit_bup;\n    VALUE old_gc;\n\n    if (argc < 2) {\n      rb_raise(rb_eArgError, \"too few arguments\");\n    }\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n    old_gc = rb_gc_disable();\n\n    for(size = 0, idx = 2; idx < argc; idx++) {\n        if (TYPE(argv[idx]) == T_HASH) {\n            size += 2 * RHASH_SIZE(argv[idx]);\n        } else {\n            size++;\n        }\n    }\n    /* dst = rb_ary_new2(argc - 2); */\n    dst = rb_ary_new2(size);\n    for(idx = 2; idx < argc; idx++) {\n        if (TYPE(argv[idx]) == T_HASH) {\n            if (RTEST(argv[1])) {\n                hash2kv_enc(argv[idx], dst, self);\n            } else {\n                hash2kv(argv[idx], dst, self);\n            }\n        } else if (argv[idx] != TK_None) {\n            rb_ary_push(dst, get_eval_string_core(argv[idx], argv[1], self));\n        }\n    }\n\n    if (old_gc == Qfalse) rb_gc_enable();\n    rb_thread_critical = thr_crit_bup;\n\n    return rb_ary_plus(argv[0], dst);\n}\n\n\n/*************************************/\n\nstatic VALUE\ntcl2rb_bool(self, value)\n    VALUE self;\n    VALUE value;\n{\n    if (TYPE(value) == T_FIXNUM) {\n        if (NUM2INT(value) == 0) {\n            return Qfalse;\n        } else {\n            return Qtrue;\n        }\n    }\n\n    if (TYPE(value) == T_TRUE || TYPE(value) == T_FALSE) {\n        return value;\n    }\n\n    rb_check_type(value, T_STRING);\n\n    value = rb_funcall(value, ID_downcase, 0);\n\n    if (RSTRING_PTR(value) == (char*)NULL) return Qnil;\n\n    if (RSTRING_PTR(value)[0] == '\\0'\n        || strcmp(RSTRING_PTR(value), \"0\") == 0\n        || strcmp(RSTRING_PTR(value), \"no\") == 0\n        || strcmp(RSTRING_PTR(value), \"off\") == 0\n        || strcmp(RSTRING_PTR(value), \"false\") == 0) {\n        return Qfalse;\n    } else {\n        return Qtrue;\n    }\n}\n\nstatic VALUE\ntkstr_to_dec(value)\n    VALUE value;\n{\n    return rb_cstr_to_inum(RSTRING_PTR(value), 10, 1);\n}\n\nstatic VALUE\ntkstr_to_int(value)\n    VALUE value;\n{\n    return rb_cstr_to_inum(RSTRING_PTR(value), 0, 1);\n}\n\nstatic VALUE\ntkstr_to_float(value)\n    VALUE value;\n{\n    return rb_float_new(rb_cstr_to_dbl(RSTRING_PTR(value), 1));\n}\n\nstatic VALUE\ntkstr_invalid_numstr(value)\n    VALUE value;\n{\n    rb_raise(rb_eArgError, \n             \"invalid value for Number: '%s'\", RSTRING_PTR(value));\n    return Qnil; /*dummy*/\n}\n\nstatic VALUE\ntkstr_rescue_float(value)\n    VALUE value;\n{\n    return rb_rescue2(tkstr_to_float, value, \n                      tkstr_invalid_numstr, value, \n                      rb_eArgError, 0);\n}\n\nstatic VALUE\ntkstr_to_number(value)\n    VALUE value;\n{\n    rb_check_type(value, T_STRING);\n\n    if (RSTRING_PTR(value) == (char*)NULL) return INT2FIX(0);\n\n    return rb_rescue2(tkstr_to_int, value, \n                      tkstr_rescue_float, value, \n                      rb_eArgError, 0);\n}\n\nstatic VALUE\ntcl2rb_number(self, value)\n    VALUE self;\n    VALUE value;\n{\n    return tkstr_to_number(value);\n}\n\nstatic VALUE\ntkstr_to_str(value)\n    VALUE value;\n{\n    char * ptr;\n    int len;\n\n    ptr = RSTRING_PTR(value);\n    len = RSTRING_LEN(value);\n\n    if (len > 1 && *ptr == '{' && *(ptr + len - 1) == '}') {\n        return rb_str_new(ptr + 1, len - 2);\n    }\n    return value;\n}\n\nstatic VALUE\ntcl2rb_string(self, value)\n    VALUE self;\n    VALUE value;\n{\n    rb_check_type(value, T_STRING);\n\n    if (RSTRING_PTR(value) == (char*)NULL) return rb_tainted_str_new2(\"\");\n\n    return tkstr_to_str(value);\n}\n\nstatic VALUE\ntcl2rb_num_or_str(self, value)\n    VALUE self;\n    VALUE value;\n{\n    rb_check_type(value, T_STRING);\n\n    if (RSTRING_PTR(value) == (char*)NULL) return rb_tainted_str_new2(\"\");\n\n    return rb_rescue2(tkstr_to_number, value, \n                      tkstr_to_str, value, \n                      rb_eArgError, 0);\n}\n\n\n/*************************************/\n\n#define CBSUBST_TBL_MAX (256)\nstruct cbsubst_info {\n    int   full_subst_length;\n    int   keylen[CBSUBST_TBL_MAX];\n    unsigned char  *key[CBSUBST_TBL_MAX];\n    unsigned char  type[CBSUBST_TBL_MAX];\n    ID    ivar[CBSUBST_TBL_MAX];\n    VALUE proc;\n    VALUE aliases;\n};\n\nstatic void\nsubst_mark(ptr)\n    struct cbsubst_info *ptr;\n{\n    rb_gc_mark(ptr->proc);\n    rb_gc_mark(ptr->aliases);\n}\n\nstatic void\nsubst_free(ptr)\n    struct cbsubst_info *ptr;\n{\n    int i;\n\n    if (ptr) {\n      for(i = 0; i < CBSUBST_TBL_MAX; i++) {\n\tif (ptr->key[i] != (unsigned char *)NULL) {\n\t  free(ptr->key[i]);\n\t  ptr->key[i] = (unsigned char *)NULL;\n\t}\n      }\n      free(ptr);\n    }\n}\n\nstatic struct cbsubst_info *\nallocate_cbsubst_info()\n{\n  struct cbsubst_info *inf;\n  volatile VALUE proc, aliases;\n  int idx;\n\n  inf = ALLOC(struct cbsubst_info);\n\n  inf->full_subst_length = 0;\n\n  for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {\n    inf->keylen[idx] = 0;\n    inf->key[idx]    = (unsigned char *) NULL;\n    inf->type[idx]   = '\\0';\n    inf->ivar[idx]   = (ID) 0;\n  }\n\n  proc = rb_hash_new();\n  inf->proc = proc;\n\n  aliases = rb_hash_new();\n  inf->aliases = aliases;\n\n  return inf;\n}\n\nstatic void\ncbsubst_init()\n{\n    rb_const_set(cCB_SUBST, ID_SUBST_INFO, \n\t\t Data_Wrap_Struct(cSUBST_INFO, subst_mark, subst_free, \n\t\t\t\t  allocate_cbsubst_info()));\n}\n\nstatic VALUE\ncbsubst_initialize(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct cbsubst_info *inf;\n    int idx, iv_idx;\n\n    Data_Get_Struct(rb_const_get(rb_obj_class(self), ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n   idx = 0;\n    for(iv_idx = 0; iv_idx < CBSUBST_TBL_MAX; iv_idx++) {\n      if ( inf->ivar[iv_idx] == (ID) 0 ) continue;\n      rb_ivar_set(self, inf->ivar[iv_idx], argv[idx++]);\n      if (idx >= argc) break;\n    }\n\n    return self;\n}\n\nstatic VALUE\ncbsubst_ret_val(self, val)\n    VALUE self;\n    VALUE val;\n{\n    /* This method may be overwritten on some sub-classes.                  */\n    /* This method is used for converting from ruby's callback-return-value */\n    /* to tcl's value (e.g. validation procedure of entry widget).          */\n    return val;\n}\n\nstatic int\neach_attr_def(key, value, klass)\n    VALUE key, value, klass;\n{\n    ID key_id, value_id;\n\n    if (key == Qundef) return ST_CONTINUE;\n\n    switch(TYPE(key)) {\n    case T_STRING:\n        key_id = rb_intern(RSTRING_PTR(key));\n        break;\n    case T_SYMBOL:\n        key_id = SYM2ID(key);\n        break;\n    default:\n        rb_raise(rb_eArgError, \n                 \"includes invalid key(s). expected a String or a Symbol\");\n    }\n\n    switch(TYPE(value)) {\n    case T_STRING:\n        value_id = rb_intern(RSTRING_PTR(value));\n        break;\n    case T_SYMBOL:\n        value_id = SYM2ID(value);\n        break;\n    default:\n        rb_raise(rb_eArgError, \n                 \"includes invalid value(s). expected a String or a Symbol\");\n    }\n\n    rb_alias(klass, key_id, value_id);\n\n    return ST_CONTINUE;\n}\n\nstatic VALUE\ncbsubst_def_attr_aliases(self, tbl)\n    VALUE self;\n    VALUE tbl;\n{\n    struct cbsubst_info *inf;\n\n    if (TYPE(tbl) != T_HASH) {\n        rb_raise(rb_eArgError, \"expected a Hash\");\n    }\n\n    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n    rb_hash_foreach(tbl, each_attr_def, self);\n\n    return rb_funcall(inf->aliases, rb_intern(\"update\"), 1, tbl);\n}\n\nstatic VALUE\ncbsubst_sym_to_subst(self, sym)\n    VALUE self;\n    VALUE sym;\n{\n    struct cbsubst_info *inf;\n    const char *str;\n    unsigned char *buf, *ptr;\n    int idx, len;\n    ID id;\n    volatile VALUE ret;\n\n    if (TYPE(sym) != T_SYMBOL) return sym;\n\n    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n    if (!NIL_P(ret = rb_hash_aref(inf->aliases, sym))) {\n      str = rb_id2name(SYM2ID(ret));\n    } else {\n      str = rb_id2name(SYM2ID(sym));\n    }\n\n    id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2(\"@\"), str)));\n\n    for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {\n      if (inf->ivar[idx] == id) break;\n    }\n    if (idx >= CBSUBST_TBL_MAX)  return sym;\n\n    ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);\n\n    *(ptr++) = '%';\n\n    if (len = inf->keylen[idx]) {\n      /* longname */\n      strncpy(ptr, inf->key[idx], len);\n      ptr += len;\n    } else {\n      /* single char */\n      *(ptr++) = idx;\n    }\n\n    *(ptr++) = ' ';\n    *(ptr++) = '\\0';\n\n    ret = rb_str_new2(buf);\n\n    free(buf);\n\n    return ret;\n}\n\nstatic VALUE\ncbsubst_get_subst_arg(argc, argv, self)\n    int   argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct cbsubst_info *inf;\n    const char *str;\n    unsigned char *buf, *ptr;\n    int i, idx, len;\n    ID id;\n    volatile VALUE arg_sym, ret;\n\n    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n    ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);\n\n    for(i = 0; i < argc; i++) {\n        switch(TYPE(argv[i])) {\n        case T_STRING:\n            str = RSTRING_PTR(argv[i]);\n            arg_sym = ID2SYM(rb_intern(str));\n            break;\n        case T_SYMBOL:\n            arg_sym = argv[i];\n            str = rb_id2name(SYM2ID(arg_sym));\n            break;\n        default:\n            rb_raise(rb_eArgError, \"arg #%d is not a String or a Symbol\", i);\n        }\n\n        if (!NIL_P(ret = rb_hash_aref(inf->aliases, arg_sym))) {\n            str = rb_id2name(SYM2ID(ret));\n        }\n\n        id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2(\"@\"), str)));\n\n\tfor(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {\n\t  if (inf->ivar[idx] == id) break;\n\t}\n        if (idx >= CBSUBST_TBL_MAX) {\n            rb_raise(rb_eArgError, \"cannot find attribute :%s\", str);\n        }\n\n\t*(ptr++) = '%';\n\n\tif (len = inf->keylen[idx]) {\n\t  /* longname */\n\t  strncpy(ptr, inf->key[idx], len);\n\t  ptr += len;\n\t} else {\n\t  /* single char */\n\t  *(ptr++) = idx;\n\t}\n\n\t*(ptr++) = ' ';\n    }\n\n    *ptr = '\\0';\n\n    ret = rb_str_new2(buf);\n\n    free(buf);\n\n    return ret;\n}\n\nstatic VALUE\ncbsubst_get_subst_key(self, str)\n    VALUE self;\n    VALUE str;\n{\n    struct cbsubst_info *inf;\n    volatile VALUE list;\n    volatile VALUE ret;\n    VALUE keyval;\n    int i, len, keylen, idx;\n    unsigned char *buf, *ptr, *key;\n\n    list = rb_funcall(cTclTkLib, ID_split_tklist, 1, str);\n    len = RARRAY_LEN(list);\n\n    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n    ptr = buf = ALLOC_N(unsigned char, inf->full_subst_length + len + 1);\n\n    for(i = 0; i < len; i++) {\n      keyval = RARRAY_PTR(list)[i];\n      key = (unsigned char*)RSTRING_PTR(keyval);\n      if (*key == '%') {\n\tif (*(key + 2) == '\\0') {\n\t  /* single char */\n\t  *(ptr++) = *(key + 1);\n\t} else {\n\t  /* search longname-key */\n\t  keylen = RSTRING_LEN(keyval) - 1;\n\t  for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {\n\t    if (inf->keylen[idx] != keylen) continue;\n\t    if (inf->key[idx][0] != *(key + 1)) continue;\n\t    if (strncmp(inf->key[idx], key + 1, keylen)) continue;\n\t    break;\n\t  }\n\t  if (idx < CBSUBST_TBL_MAX) {\n\t    *(ptr++) = (unsigned char)idx;\n\t  } else {\n\t    *(ptr++) = ' ';\n\t  }\n\t}\n      } else {\n\t*(ptr++) = ' ';\n      }\n    }\n    *ptr = '\\0';\n\n    ret = rb_str_new2((const char*)buf);\n    free(buf);\n    return ret;\n}\n\nstatic VALUE\ncbsubst_get_all_subst_keys(self)\n    VALUE self;\n{\n    struct cbsubst_info *inf;\n    unsigned char *buf, *ptr;\n    unsigned char *keys_buf, *keys_ptr;\n    int idx, len;\n    volatile VALUE ret;\n\n    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n    ptr = buf = ALLOC_N(unsigned char, inf->full_subst_length + 1);\n    keys_ptr = keys_buf = ALLOC_N(unsigned char, CBSUBST_TBL_MAX + 1);\n\n    for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {\n      if (inf->ivar[idx] == (ID) 0) continue;\n\n      *(keys_ptr++) = (unsigned char)idx;\n\n      *(ptr++) = '%';\n\n      if (len = inf->keylen[idx]) {\n\t/* longname */\n\tstrncpy(ptr, inf->key[idx], len);\n\tptr += len;\n      } else {\n\t/* single char */\n\t*(ptr++) = (unsigned char)idx;\n      }\n\n      *(ptr++) = ' ';\n    }\n\n    *ptr = '\\0';\n    *keys_ptr = '\\0';\n\n    ret = rb_ary_new3(2, rb_str_new2(keys_buf), rb_str_new2((const char*)buf));\n\n    free(buf);\n    free(keys_buf);\n\n    return ret;\n}\n\nstatic VALUE\ncbsubst_table_setup(argc, argv, self)\n     int   argc;\n     VALUE *argv;\n     VALUE self;\n{\n  volatile VALUE key_inf;\n  volatile VALUE longkey_inf;\n  volatile VALUE proc_inf;\n  VALUE inf;\n  ID id;\n  struct cbsubst_info *subst_inf;\n  int idx, len;\n  unsigned char chr;\n\n  /* accept (key_inf, proc_inf) or (key_inf, longkey_inf, procinf) */\n  if (rb_scan_args(argc, argv, \"21\", &key_inf, &longkey_inf, &proc_inf) == 2) {\n    proc_inf = longkey_inf;\n    longkey_inf = rb_ary_new();\n  }\n\n  /* check the number of longkeys */\n  if (RARRAY_LEN(longkey_inf) > 125 /* from 0x80 to 0xFD */) {\n    rb_raise(rb_eArgError, \"too many longname-key definitions\");\n  }\n\n  /* init */\n  subst_inf = allocate_cbsubst_info();\n\n  /*\n   * keys : array of [subst, type, ivar]\n   *         subst ==> char code or string\n   *         type  ==> char code or string\n   *         ivar  ==> symbol\n   */\n  len = RARRAY_LEN(key_inf);\n  for(idx = 0; idx < len; idx++) {\n    inf = RARRAY_PTR(key_inf)[idx];\n    if (TYPE(inf) != T_ARRAY) continue;\n\n    if (TYPE(RARRAY_PTR(inf)[0]) == T_STRING) {\n      chr = *(RSTRING_PTR(RARRAY_PTR(inf)[0]));\n    } else {\n      chr = NUM2CHR(RARRAY_PTR(inf)[0]);\n    }\n    if (TYPE(RARRAY_PTR(inf)[1]) == T_STRING) {\n      subst_inf->type[chr] = *(RSTRING_PTR(RARRAY_PTR(inf)[1]));\n    } else {\n      subst_inf->type[chr] = NUM2CHR(RARRAY_PTR(inf)[1]);\n    }\n\n    subst_inf->full_subst_length += 3;\n\n    id = SYM2ID(RARRAY_PTR(inf)[2]);\n    subst_inf->ivar[chr] = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2(\"@\"), rb_id2name(id))));\n\n    rb_attr(self, id, 1, 0, Qtrue);\n  }\n\n\n  /*\n   * longkeys : array of [name, type, ivar]\n   *         name ==> longname key string\n   *         type ==> char code or string\n   *         ivar ==> symbol\n   */\n  len = RARRAY_LEN(longkey_inf);\n  for(idx = 0; idx < len; idx++) {\n    inf = RARRAY_PTR(longkey_inf)[idx];\n    if (TYPE(inf) != T_ARRAY) continue;\n\n    chr = (unsigned char)(0x80 + idx);\n    subst_inf->keylen[chr] = RSTRING_LEN(RARRAY_PTR(inf)[0]);\n#if HAVE_STRNDUP\n    subst_inf->key[chr] = strndup(RSTRING_PTR(RARRAY_PTR(inf)[0]), \n\t\t\t\t  RSTRING_LEN(RARRAY_PTR(inf)[0]));\n#else\n    subst_inf->key[chr] = malloc(RSTRING_LEN(RARRAY_PTR(inf)[0]) + 1);\n    if (subst_inf->key[chr]) {\n      strncpy(subst_inf->key[chr], RSTRING_PTR(RARRAY_PTR(inf)[0]),\n\t      RSTRING_LEN(RARRAY_PTR(inf)[0]) + 1);\n      subst_inf->key[chr][RSTRING_LEN(RARRAY_PTR(inf)[0])] = '\\0';\n    }\n#endif\n    if (TYPE(RARRAY_PTR(inf)[1]) == T_STRING) {\n      subst_inf->type[chr] = *(RSTRING_PTR(RARRAY_PTR(inf)[1]));\n    } else {\n      subst_inf->type[chr] = NUM2CHR(RARRAY_PTR(inf)[1]);\n    }\n\n    subst_inf->full_subst_length += (subst_inf->keylen[chr] + 2);\n\n    id = SYM2ID(RARRAY_PTR(inf)[2]);\n    subst_inf->ivar[chr] = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2(\"@\"), rb_id2name(id))));\n\n    rb_attr(self, id, 1, 0, Qtrue);\n  }\n\n  /*\n   * procs : array of [type, proc]\n   *         type  ==> char code or string\n   *         proc  ==> proc/method/obj (must respond to 'call')\n   */\n  len = RARRAY_LEN(proc_inf);\n  for(idx = 0; idx < len; idx++) {\n    inf = RARRAY_PTR(proc_inf)[idx];\n    if (TYPE(inf) != T_ARRAY) continue;\n    rb_hash_aset(subst_inf->proc, \n\t\t ((TYPE(RARRAY_PTR(inf)[0]) == T_STRING)? \n\t\t  INT2FIX(*(RSTRING_PTR(RARRAY_PTR(inf)[0]))) : \n\t\t  RARRAY_PTR(inf)[0]), \n\t\t RARRAY_PTR(inf)[1]);\n  }\n\n  rb_const_set(self, ID_SUBST_INFO, \n\t       Data_Wrap_Struct(cSUBST_INFO, subst_mark, \n\t\t\t\tsubst_free, subst_inf));\n\n  return self;\n}\n\nstatic VALUE\ncbsubst_get_extra_args_tbl(self)\n    VALUE self;\n{\n  return rb_ary_new();\n}\n\nstatic VALUE\ncbsubst_scan_args(self, arg_key, val_ary)\n    VALUE self;\n    VALUE arg_key;\n    VALUE val_ary;\n{\n    struct cbsubst_info *inf;\n    int idx;\n    unsigned char *keyptr = (unsigned char*)RSTRING_PTR(arg_key);\n    int keylen = RSTRING_LEN(arg_key);\n    int vallen = RARRAY_LEN(val_ary);\n    unsigned char type_chr;\n    volatile VALUE dst = rb_ary_new2(vallen);\n    volatile VALUE proc;\n    int thr_crit_bup;\n    VALUE old_gc;\n\n    thr_crit_bup = rb_thread_critical;\n    rb_thread_critical = Qtrue;\n\n    old_gc = rb_gc_disable();\n\n    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO), \n                    struct cbsubst_info, inf);\n\n    for(idx = 0; idx < vallen; idx++) {\n      if (idx >= keylen) {\n\tproc = Qnil;\n      } else if (*(keyptr + idx) == ' ') {\n\tproc = Qnil;\n      } else {\n\tif (type_chr = inf->type[*(keyptr + idx)]) {\n\t  proc = rb_hash_aref(inf->proc, INT2FIX((int)type_chr));\n\t} else {\n\t  proc = Qnil;\n\t}\n      }\n\n      if (NIL_P(proc)) {\n\trb_ary_push(dst, RARRAY_PTR(val_ary)[idx]);\n      } else {\n\trb_ary_push(dst, rb_funcall(proc, ID_call, 1, \n\t\t\t\t    RARRAY_PTR(val_ary)[idx]));\n      }\n    }\n\n    if (old_gc == Qfalse) rb_gc_enable();\n    rb_thread_critical = thr_crit_bup;\n\n    return dst;\n}\n\nstatic VALUE\ncbsubst_inspect(self)\n    VALUE self;\n{\n    return rb_str_new2(\"CallbackSubst\");\n}\n\nstatic VALUE\nsubstinfo_inspect(self)\n    VALUE self;\n{\n    return rb_str_new2(\"SubstInfo\");\n}\n\n/*************************************/\n\nstatic VALUE\ntk_cbe_inspect(self)\n    VALUE self;\n{\n    return rb_str_new2(\"TkCallbackEntry\");\n}\n\n/*************************************/\n\nstatic VALUE\ntkobj_path(self)\n    VALUE self;\n{\n    return rb_ivar_get(self, ID_at_path);\n}\n\n\n/*************************************/\n/* release date */\nconst char tkutil_release_date[] = TKUTIL_RELEASE_DATE;\n\nvoid\nInit_tkutil()\n{\n    VALUE cTK = rb_define_class(\"TkKernel\", rb_cObject);\n    VALUE mTK = rb_define_module(\"TkUtil\");\n\n    /* --------------------- */\n\n    rb_define_const(mTK, \"RELEASE_DATE\", \n                    rb_obj_freeze(rb_str_new2(tkutil_release_date)));\n\n    /* --------------------- */\n    rb_global_variable(&cMethod);\n    cMethod = rb_const_get(rb_cObject, rb_intern(\"Method\"));\n\n    ID_path = rb_intern(\"path\");\n    ID_at_path = rb_intern(\"@path\");\n    ID_at_enc = rb_intern(\"@encoding\");\n    ID_to_eval = rb_intern(\"to_eval\");\n    ID_to_s = rb_intern(\"to_s\");\n    ID_source = rb_intern(\"source\");\n    ID_downcase = rb_intern(\"downcase\");\n    ID_install_cmd = rb_intern(\"install_cmd\");\n    ID_merge_tklist = rb_intern(\"_merge_tklist\");\n    ID_encoding = rb_intern(\"encoding\");\n    ID_encoding_system = rb_intern(\"encoding_system\");\n    ID_call = rb_intern(\"call\");\n\n    /* --------------------- */\n    cCB_SUBST = rb_define_class_under(mTK, \"CallbackSubst\", rb_cObject);\n    rb_define_singleton_method(cCB_SUBST, \"inspect\", cbsubst_inspect, 0);\n\n    cSUBST_INFO = rb_define_class_under(cCB_SUBST, \"Info\", rb_cObject);\n    rb_define_singleton_method(cSUBST_INFO, \"inspect\", substinfo_inspect, 0);\n\n    ID_SUBST_INFO = rb_intern(\"SUBST_INFO\");\n    rb_define_singleton_method(cCB_SUBST, \"ret_val\", cbsubst_ret_val, 1);\n    rb_define_singleton_method(cCB_SUBST, \"scan_args\", cbsubst_scan_args, 2);\n    rb_define_singleton_method(cCB_SUBST, \"_sym2subst\", \n\t\t\t       cbsubst_sym_to_subst, 1);\n    rb_define_singleton_method(cCB_SUBST, \"subst_arg\", \n                               cbsubst_get_subst_arg, -1);\n    rb_define_singleton_method(cCB_SUBST, \"_get_subst_key\", \n                               cbsubst_get_subst_key,  1);\n    rb_define_singleton_method(cCB_SUBST, \"_get_all_subst_keys\", \n                               cbsubst_get_all_subst_keys,  0);\n    rb_define_singleton_method(cCB_SUBST, \"_setup_subst_table\", \n                               cbsubst_table_setup, -1);\n    rb_define_singleton_method(cCB_SUBST, \"_get_extra_args_tbl\", \n                               cbsubst_get_extra_args_tbl,  0);\n    rb_define_singleton_method(cCB_SUBST, \"_define_attribute_aliases\", \n                               cbsubst_def_attr_aliases,  1);\n\n    rb_define_method(cCB_SUBST, \"initialize\", cbsubst_initialize, -1);\n\n    cbsubst_init();\n\n    /* --------------------- */\n    rb_global_variable(&cTkCallbackEntry);\n    cTkCallbackEntry = rb_define_class(\"TkCallbackEntry\", cTK);\n    rb_define_singleton_method(cTkCallbackEntry, \"inspect\", tk_cbe_inspect, 0);\n\n    /* --------------------- */\n    rb_global_variable(&cTkObject);\n    cTkObject = rb_define_class(\"TkObject\", cTK);\n    rb_define_method(cTkObject, \"path\", tkobj_path, 0);\n\n    /* --------------------- */\n    rb_require(\"tcltklib\");\n    rb_global_variable(&cTclTkLib);\n    cTclTkLib = rb_const_get(rb_cObject, rb_intern(\"TclTkLib\"));\n    ID_split_tklist = rb_intern(\"_split_tklist\");\n    ID_toUTF8 = rb_intern(\"_toUTF8\");\n    ID_fromUTF8 = rb_intern(\"_fromUTF8\");\n\n    /* --------------------- */\n    rb_define_singleton_method(cTK, \"new\", tk_s_new, -1);\n\n    /* --------------------- */\n    rb_global_variable(&TK_None);\n    TK_None = rb_obj_alloc(rb_cObject);\n    rb_define_const(mTK, \"None\", TK_None);\n    rb_define_singleton_method(TK_None, \"to_s\", tkNone_to_s, 0);\n    rb_define_singleton_method(TK_None, \"inspect\", tkNone_to_s, 0);\n    OBJ_FREEZE(TK_None);\n\n    /* --------------------- */\n    rb_global_variable(&CALLBACK_TABLE);\n    CALLBACK_TABLE = rb_hash_new();\n\n    /* --------------------- */\n    rb_define_singleton_method(mTK, \"eval_cmd\", tk_eval_cmd, -1);\n    rb_define_singleton_method(mTK, \"callback\", tk_do_callback, -1);\n    rb_define_singleton_method(mTK, \"install_cmd\", tk_install_cmd, -1);\n    rb_define_singleton_method(mTK, \"uninstall_cmd\", tk_uninstall_cmd, 1);\n    rb_define_singleton_method(mTK, \"_symbolkey2str\", tk_symbolkey2str, 1);\n    rb_define_singleton_method(mTK, \"hash_kv\", tk_hash_kv, -1);\n    rb_define_singleton_method(mTK, \"_get_eval_string\", \n                               tk_get_eval_string, -1);\n    rb_define_singleton_method(mTK, \"_get_eval_enc_str\", \n                               tk_get_eval_enc_str, 1);\n    rb_define_singleton_method(mTK, \"_conv_args\", tk_conv_args, -1);\n\n    rb_define_singleton_method(mTK, \"bool\", tcl2rb_bool, 1);\n    rb_define_singleton_method(mTK, \"number\", tcl2rb_number, 1);\n    rb_define_singleton_method(mTK, \"string\", tcl2rb_string, 1);\n    rb_define_singleton_method(mTK, \"num_or_str\", tcl2rb_num_or_str, 1);\n\n    rb_define_method(mTK, \"_toUTF8\", tk_toUTF8, -1);\n    rb_define_method(mTK, \"_fromUTF8\", tk_fromUTF8, -1);\n    rb_define_method(mTK, \"_symbolkey2str\", tk_symbolkey2str, 1);\n    rb_define_method(mTK, \"hash_kv\", tk_hash_kv, -1);\n    rb_define_method(mTK, \"_get_eval_string\", tk_get_eval_string, -1);\n    rb_define_method(mTK, \"_get_eval_enc_str\", tk_get_eval_enc_str, 1);\n    rb_define_method(mTK, \"_conv_args\", tk_conv_args, -1);\n\n    rb_define_method(mTK, \"bool\", tcl2rb_bool, 1);\n    rb_define_method(mTK, \"number\", tcl2rb_number, 1);\n    rb_define_method(mTK, \"string\", tcl2rb_string, 1);\n    rb_define_method(mTK, \"num_or_str\", tcl2rb_num_or_str, 1);\n\n    /* --------------------- */\n    rb_global_variable(&ENCODING_NAME_UTF8);\n    ENCODING_NAME_UTF8 = rb_obj_freeze(rb_str_new2(\"utf-8\"));\n\n    /* --------------------- */\n}\n"
  },
  {
    "path": "ext/win32ole/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.log\n.document\n"
  },
  {
    "path": "ext/win32ole/depend",
    "content": "win32ole.o : win32ole.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h \n"
  },
  {
    "path": "ext/win32ole/doc/win32ole.rd",
    "content": "=begin\n= Win32OLE extension module\n\n== WIN32OLE \n=== Constants\n: VERSION\n    The version number of WIN32OLE.\n\n: ARGV\n    The argument of the method invoked recently.\n    This constant is used to get value of argument \n    when the argument is passed by reference.\n\n=== Class Method\n: connect(oleserver)\n   returns running OLE automation object or WIN32OLE object from moniker.\n\n: const_load(ole [,obj])\n   defines the constants of OLE automation\n   server as 'obj' class constants. If 'obj' omitted, the default\n   is WIN32OLE.\n\n: new(oleserver)\n   returns OLE Automation object.\n\n: ole_free(obj)\n   invokes Release method of Dispatch interface of WIN32OLE object.\n   This method should not be used because this method exists for debugging WIN32OLE.\n\n: ole_reference_count(obj)\n   returns reference counter of Dispatch interface.\n   This method should not be used because this method exists for debugging WIN32OLE.\n\n: ole_show_help(info [,helpcontext])\n   displays helpfile.\n   The first argument specifies WIN32OLE_TYPE object or WIN32OLE_METHOD object \n   or helpfile.\n\n=== Method\n: self[property]\n   gets property of OLE object.\n\n: self[property]=\n   sets property of OLE object.\n\n: _invoke(dispid, args, types)\n   runs the early binding method.\n   The dispid specifies Dispatch ID, args specifies the array of arguments,\n   types specifies array of the type of arguments.\n\n: each {...}\n   Iterates over each item of OLE collection which has IEnumVARIANT\n   interface.\n\n: invoke(method, args,...)\n   runs OLE method.\n\n: ole_func_methods\n   returns array of WIN32OLE_METHOD object which corresponds with function.\n\n: ole_get_methods\n   returns array of WIN32OLE_METHOD object which corresponds with get properties.\n\n: ole_method(method)\n   returns WIN32OLE_METHOD object which coreesponds with method \n   which specified by argument.\n\n: ole_method_help(method)\n   alias of ole_method.\n\n: ole_methods\n   returns WIN32OLE_METHOD object which coreesponds with method.\n\n: ole_obj_help\n   returns WIN32OLE_TYPE object.\n\n: ole_put_methods\n   returns array of WIN32OLE_METHOD object which corresponds with put properties.\n\n: setproperty(property, key, val)\n   set property of OLE object. \n   This method is used when the property has argument.\n\n   For example, in VB\n     obj.item(\"key\") = val\n   in Win32OLE\n     obj.setproperty(\"item\", \"key\", val)\n\n\n== WIN32OLE_EVENT class\n\n=== Class Method\n\n: new(ole, interface)\n   The new class method creates OLE event sink object to connect ole.\n   The ole must be WIN32OLE object, and interface is the interface\n   name of event.\n\n: message_loop\n    The message_loop class method translates and dispatches Windows \n    message.\n\n=== Method\n: on_event([event]){...}\n    defines the callback of event.\n    If event omitted, defines the callback of all events.\n\n: on_event_with_outargs([event]) {...}\n    defines the callback of event.\n    If you want modify argument in callback, \n\n== WIN32OLE_METHOD\n\n=== Class Methods\n: new(win32ole_type, method)    \n   creates WIN32OLE_METHOD object.\n\n=== Methods\n: dispid\n   returns Dispatch ID.\n\n: event?\n   returns true if the method is event.\n\n: event_interface\n   returns interface name of event if the method is event.\n\n: helpcontext\n   returns help context.\n\n: helpfile\n   returns help file.\n\n: invkind\n   returns invkind.\n\n: invoke_kind\n   returns invoke kind string.\n\n: name\n   returns name of method.\n\n: offset_vtbl\n   returns the offset of Vtbl.\n\n: params\n   returns array of WIN32OLE_PARAM object.\n\n: return_type\n   returns string of return value type of method.\n\n: return_vtype\n   returns number of return value type of method.\n\n: return_type_detail\n   returns detail information of return value type of method.\n\n: size_params\n   returns the size of arguments.\n\n: size_opt_params\n   returns the size of optional arguments.\n\n: visible?\n   returns true if the method is public.\n\n== WIN32OLE_PARAM\n: default\n   returns default value.\n\n: input?\n   returns true if argument is input.\n\n: optional?\n   returns true if argument is optional.\n\n: output?\n   returns true if argument is output.\n\n: name\n   returns name.\n\n: ole_type\n   returns type of argument.\n\n: ole_type_detail\n   returns detail information of type of argument.\n\n: retval?\n   returns true if argument is return value.\n\n== WIN32OLE_TYPE\n=== Class Methods\n: new(typelibrary, class)\n    returns WIN32OLE_TYPE object.\n\n: ole_classes(typelibrary)\n    returns array of WIN32OLE_TYPE objects defined by Type Library.\n\n: progids\n    returns array of ProgID.\n\n: typelibs\n    returns array of type libraries.\n\n=== Methods\n: guid\n   returns GUID.\n\n: helpfile\n   returns helpfile.\n\n: helpcontext\n   returns helpcontext.\n\n: helpstring\n   returns help string.\n\n: major_version\n   returns major version.\n\n: minor_version\n   returns minor version.\n\n: name\n   returns name.\n\n: ole_methods\n   returns array of WIN32OLE_METHOD objects.\n\n: ole_type\n   returns type of class.\n\n: progid\n   returns ProgID if it exists. If not found, then returns nil.\n\n: src_type\n   returns source class when the OLE class is 'Alias'.\n\n: typekind\n   returns number which represents type.\n\n: variables\n   returns array of variables defined in OLE class.\n\n: visible?\n   returns true if the OLE class is public.\n\n== WIN32OLE_VARIABLE\n=== Methods\n: name\n   returns the name.\n\n: ole_type\n   returns type\n\n: ole_type_detail\n   returns detail information of type.\n\n: value\n   returns value.\n\n: variable_kind\n   returns variable kind string.\n\n: varkind\n   returns the number which represents variable kind.\n\n== WIN32OLE::VARIANT\n=== Constants\n  *VT_I4\n  *VT_R4\n  *VT_R8\n  *VT_CY\n  *VT_DATE\n  *VT_BSTR\n  *VT_USERDEFINED\n  *VT_PTR\n  *VT_DISPATCH\n  *VT_ERROR\n  *VT_BOOL\n  *VT_VARIANT\n  *VT_UNKNOWN\n  *VT_I1\n  *VT_UI1\n  *VT_UI2\n  *VT_UI4\n  *VT_INT\n  *VT_UINT\n  *VT_ARRAY\n  *VT_BYREF\n\n=end\n\n"
  },
  {
    "path": "ext/win32ole/extconf.rb",
    "content": "#----------------------------------\n# extconf.rb\n# $Revision$\n# $Date$\n#----------------------------------\nrequire 'mkmf'\n\ndir_config(\"win32\")\n\nSRCFILES=<<SRC\nwin32ole.c\nSRC\n\ndef create_docfile(src)\n  open(File.expand_path($srcdir) + \"/.document\", \"w\") {|ofs|\n    ofs.print src\n  }\nend\n\ndef create_win32ole_makefile\n  if have_library(\"ole32\") and\n     have_library(\"oleaut32\") and\n     have_library(\"uuid\") and \n     have_library(\"user32\") and\n     have_library(\"kernel32\") and\n     have_library(\"advapi32\") and\n     have_header(\"windows.h\")\n    create_makefile(\"win32ole\")\n    create_docfile(SRCFILES)\n  else\n    create_docfile(\"\")\n  end\nend\n\ncase RUBY_PLATFORM\nwhen /mswin32/\n  $CFLAGS += ' /W3'\nwhen /cygwin/, /mingw/\n  $defs << '-DNONAMELESSUNION'\nend\ncreate_win32ole_makefile\n"
  },
  {
    "path": "ext/win32ole/lib/win32ole/property.rb",
    "content": "# OLEProperty\n# helper class of Property with arguments.\nclass OLEProperty\n  def initialize(obj, dispid, gettypes, settypes)\n    @obj = obj\n    @dispid = dispid\n    @gettypes = gettypes\n    @settypes = settypes\n  end\n  def [](*args)\n    @obj._getproperty(@dispid, args, @gettypes)\n  end\n  def []=(*args)\n    @obj._setproperty(@dispid, args, @settypes)\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/sample/excel1.rb",
    "content": "require 'win32ole'\n\n#application = WIN32OLE.new('Excel.Application.5')\napplication = WIN32OLE.new('Excel.Application')\n\napplication.visible = TRUE\nworkbook = application.Workbooks.Add();\nworksheet = workbook.Worksheets(1);\nworksheet.Range(\"A1:D1\").value = [\"North\",\"South\",\"East\",\"West\"];\nworksheet.Range(\"A2:B2\").value = [5.2, 10];\nworksheet.Range(\"C2\").value = 8;\nworksheet.Range(\"D2\").value = 20;\n\nrange = worksheet.Range(\"A1:D2\");\nrange.Select\nchart = workbook.Charts.Add;\n\nworkbook.saved = TRUE;\n\napplication.ActiveWorkbook.Close(0);\napplication.Quit();\n\n"
  },
  {
    "path": "ext/win32ole/sample/excel2.rb",
    "content": "require 'win32ole'\n\n#   -4100 is the value for the Excel constant xl3DColumn.\nChartTypeVal = -4100;\n\n#   Creates OLE object to Excel\n#excel = WIN32OLE.new(\"excel.application.5\")\nexcel = WIN32OLE.new(\"excel.application\")\n\n# Create and rotate the chart\n\nexcel['Visible'] = TRUE;\nexcel.Workbooks.Add();\nexcel.Range(\"a1\")['Value'] = 3;\nexcel.Range(\"a2\")['Value'] = 2;\nexcel.Range(\"a3\")['Value'] = 1;\nexcel.Range(\"a1:a3\").Select();\nexcelchart = excel.Charts.Add();\nexcelchart['Type'] = ChartTypeVal;\n\ni = 30\ni.step(180, 10) do |rot|\n#    excelchart['Rotation'] = rot;\n    excelchart.rotation=rot;\nend\n# Done, bye\n\nexcel.ActiveWorkbook.Close(0);\nexcel.Quit();\n\n"
  },
  {
    "path": "ext/win32ole/sample/excel3.rb",
    "content": "require 'win32ole'\n\n#application = WIN32OLE.new('Excel.Application.5')\napplication = WIN32OLE.new('Excel.Application')\n\napplication.visible = TRUE\nworkbook = application.Workbooks.Add();\nsheet = workbook.Worksheets(1);\nsheetS = workbook.Worksheets\nputs \"The number of sheets is #{sheetS.count}\"\nputs \"Now add 2 sheets after of `#{sheet.name}`\"\nsheetS.add({'count'=>2, 'after'=>sheet})\nputs \"The number of sheets is #{sheetS.count}\"\n"
  },
  {
    "path": "ext/win32ole/sample/ie.rb",
    "content": "require 'win32ole'\nurl = 'http://www.ruby-lang.org/'\nie = WIN32OLE.new('InternetExplorer.Application')\nie.visible = TRUE\nie.gohome\nprint \"Now navigate Ruby home page... Please enter.\"\ngets\nie.navigate(url)\nprint \"Now quit Internet Explorer... Please enter.\"\ngets\nie.Quit()\n"
  },
  {
    "path": "ext/win32ole/sample/ieconst.rb",
    "content": "require 'win32ole'\n\nie = WIN32OLE.new('InternetExplorer.Application')\n=begin\nWIN32OLE.const_load(ie)\nWIN32OLE.constants.sort.each do |c|\n  puts \"#{c} = #{WIN32OLE.const_get(c)}\"\nend\n=end\n\nmodule IE_CONST\nend\n\nWIN32OLE.const_load(ie, IE_CONST)\nIE_CONST.constants.sort.each do |c|\n  puts \"#{c} = #{IE_CONST.const_get(c)}\"\nend\n\n#------------------------------------------------------------\n# Remark!!! CONSTANTS has not tested enoughly!!!\n# CONSTANTS is alpha release.\n# If there are constants which first letter is not [a-zA-Z],\n# like a '_Foo', then maybe you can access the value by \n# using CONSTANTS['_Foo']\n#------------------------------------------------------------\nIE_CONST::CONSTANTS.each do |k, v|\n  puts \"#{k} = #{v}\"\nend\n\nputs WIN32OLE::VERSION\nie.quit\n\n"
  },
  {
    "path": "ext/win32ole/sample/ienavi.rb",
    "content": "require 'win32ole'\n\n$urls = []\n\ndef navigate(url)\n  $urls << url\nend\n\ndef stop_msg_loop\n  puts \"Now Stop IE...\"\n  $LOOP = FALSE;\nend\n\ndef default_handler(event, *args)\n  case event\n  when \"BeforeNavigate\"\n    puts \"Now Navigate #{args[0]}...\"\n  end\nend\n\nie = WIN32OLE.new('InternetExplorer.Application')\nie.visible = TRUE\nie.gohome\n\nev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')\n\nev.on_event {|*args| default_handler(*args)}\nev.on_event(\"NavigateComplete\") {|url| navigate(url)}\nev.on_event(\"Quit\") {|*args| stop_msg_loop} \n\n$LOOP = TRUE\nwhile ($LOOP)\n  WIN32OLE_EVENT.message_loop\nend\n\nputs \"You Navigated the URLs ...\"\n$urls.each_with_index do |url, i|\n  puts \"(#{i+1}) #{url}\"\nend\n\n"
  },
  {
    "path": "ext/win32ole/sample/oledirs.rb",
    "content": "#\n# You need WSH(Windows Scripting Host) to run this script.\n#\n\nrequire \"win32ole\"\n\ndef listup(items)\n#  items.each do |i|\n  for i in items\n    puts i.name \n  end\nend\n\nfs = WIN32OLE.new(\"Scripting.FileSystemObject\")\n\nfolder = fs.GetFolder(\".\")\n\nputs \"--- folder of #{folder.path} ---\"\nlistup(folder.SubFolders)\n\nputs \"--- files of #{folder.path} ---\"\nlistup(folder.Files)\n\n"
  },
  {
    "path": "ext/win32ole/sample/olegen.rb",
    "content": "#-----------------------------\n# olegen.rb\n# $Date$\n# $Revision$\n#-----------------------------\n\nrequire 'win32ole'\n\nclass WIN32COMGen\n  def initialize(typelib)\n    @typelib = typelib\n    @reciever = \"\"\n  end\n  attr_reader :typelib\n\n  def ole_classes(typelib)\n    begin\n      @ole = WIN32OLE.new(typelib)\n      [@ole.ole_obj_help]\n    rescue\n      WIN32OLE_TYPE.ole_classes(typelib)\n    end\n  end\n\n  def generate_args(method)\n    args = []\n    if method.size_opt_params >= 0\n      size_required_params = method.size_params - method.size_opt_params\n    else\n      size_required_params = method.size_params - 1\n    end\n    size_required_params.times do |i|\n      if method.params[i] && method.params[i].optional?\n        args.push \"arg#{i}=nil\"\n      else\n        args.push \"arg#{i}\"\n      end\n    end\n    if method.size_opt_params >= 0\n      method.size_opt_params.times do |i|\n        args.push \"arg#{i + size_required_params}=nil\"\n      end\n    else\n      args.push \"*arg\"\n    end\n    args.join(\", \")\n  end\n\n  def generate_argtype(typedetails)\n    ts = ''\n    typedetails.each do |t|\n      case t\n      when 'CARRAY', 'VOID', 'UINT', 'RESULT', 'DECIMAL', 'I8', 'UI8' \n#\t  raise \"Sorry type\\\"\" + t + \"\\\" not supported\"\n      ts << \"\\\"??? NOT SUPPORTED TYPE:`#{t}'\\\"\"\n      when 'USERDEFINED', 'Unknown Type 9'\n        ts << 'VT_DISPATCH'\n        break;\n      when 'SAFEARRAY'\n        ts << 'VT_ARRAY|'\n      when 'PTR'\n        ts << 'VT_BYREF|'\n      when 'INT'\n        ts << 'VT_I4'\n      else\n        if String === t\n          ts << 'VT_' + t\n        end\n      end\n    end\n    if ts.empty?\n      ts = 'VT_VARIANT'\n    elsif ts[-1] == ?|\n\tts += 'VT_VARIANT'\n    end\n    ts\n  end\n\n  def generate_argtypes(method, proptypes)\n    types = method.params.collect{|param|\n      generate_argtype(param.ole_type_detail)\n    }.join(\", \")\n    if proptypes\n      types += \", \" if types.size > 0 \n      types += generate_argtype(proptypes)\n    end\n    types\n  end\n\n  def generate_method_body(method, disptype, types=nil)\n    \"    ret = #{@reciever}#{disptype}(#{method.dispid}, [\" +\n    generate_args(method).gsub(\"=nil\", \"\") +\n    \"], [\" +\n    generate_argtypes(method, types) +\n    \"])\\n\" +\n    \"    @lastargs = WIN32OLE::ARGV\\n\" +\n    \"    ret\"\n  end\n\n  def generate_method_help(method, type = nil)\n    str = \"  # \"  \n    if type \n      str += type\n    else\n      str += method.return_type\n    end\n    str += \" #{method.name}\"\n    if method.event?\n      str += \" EVENT\"\n      str += \" in #{method.event_interface}\"\n    end\n    if method.helpstring && method.helpstring != \"\"\n      str += \"\\n  # \"\n      str += method.helpstring\n    end\n    args_help = generate_method_args_help(method)\n    if args_help\n      str += \"\\n\"\n      str += args_help\n    end\n    str\n  end\n\n  def generate_method_args_help(method)\n    args = []\n    method.params.each_with_index {|param, i|\n      h = \"  #   #{param.ole_type} arg#{i} --- #{param.name}\" \n      inout = []\n      inout.push \"IN\" if param.input?\n      inout.push \"OUT\" if param.output?\n      h += \" [#{inout.join('/')}]\"\n      h += \" ( = #{param.default})\" if param.default\n      args.push h\n    }\n    if args.size > 0\n      args.join(\"\\n\")\n    else\n      nil\n    end\n  end\n\n  def generate_method(method, disptype, io = STDOUT, types = nil)\n    io.puts \"\\n\"\n    io.puts  generate_method_help(method)\n    if method.invoke_kind == 'PROPERTYPUT'\n      io.print \"  def #{method.name}=(\"\n    else\n      io.print \"  def #{method.name}(\"\n    end\n    io.print generate_args(method)\n    io.puts \")\"\n    io.puts generate_method_body(method, disptype, types)\n    io.puts \"  end\"\n  end\n\n  def generate_propputref_methods(klass, io = STDOUT)\n    klass.ole_methods.select {|method|\n      method.invoke_kind == 'PROPERTYPUTREF' && method.visible?\n    }.each do |method|\n      generate_method(method, io)\n    end\n  end\n\n  def generate_properties_with_args(klass, io = STDOUT)\n    klass.ole_methods.select {|method|\n      method.invoke_kind == 'PROPERTYGET' &&\n      method.visible? &&\n      method.size_params > 0\n    }.each do |method|\n      types = method.return_type_detail \n      io.puts \"\\n\"\n      io.puts  generate_method_help(method, types[0])\n      io.puts  \"  def #{method.name}\"\n      if klass.ole_type == \"Class\"\n        io.print \"    OLEProperty.new(@dispatch, #{method.dispid}, [\" \n      else\n        io.print \"    OLEProperty.new(self, #{method.dispid}, [\" \n      end\n      io.print generate_argtypes(method, nil)\n      io.print \"], [\"\n      io.print generate_argtypes(method, types)\n      io.puts \"])\"\n      io.puts  \"  end\"\n    end\n  end\n\n  def generate_propput_methods(klass, io = STDOUT)\n    klass.ole_methods.select {|method|\n      method.invoke_kind == 'PROPERTYPUT' && method.visible? &&\n      method.size_params == 1\n    }.each do |method|\n      ms = klass.ole_methods.select {|m|\n        m.invoke_kind == 'PROPERTYGET' &&\n        m.dispid == method.dispid\n      }\n      types = []\n      if ms.size == 1\n        types = ms[0].return_type_detail\n      end\n      generate_method(method, '_setproperty', io, types)\n    end\n  end\n\n  def generate_propget_methods(klass, io = STDOUT)\n    klass.ole_methods.select {|method|\n      method.invoke_kind == 'PROPERTYGET' && method.visible? &&\n      method.size_params == 0\n    }.each do |method|\n      generate_method(method, '_getproperty', io)\n    end\n  end\n\n  def generate_func_methods(klass, io = STDOUT)\n    klass.ole_methods.select {|method|\n      method.invoke_kind == \"FUNC\" && method.visible?\n    }.each do |method|\n      generate_method(method, '_invoke', io)\n    end\n  end\n\n  def generate_methods(klass, io = STDOUT)\n    generate_propget_methods(klass, io)\n    generate_propput_methods(klass, io)\n    generate_properties_with_args(klass, io)\n    generate_func_methods(klass, io)\n#   generate_propputref_methods(klass, io)\n  end\n\n  def generate_constants(klass, io = STDOUT)\n    klass.variables.select {|v|\n      v.visible? && v.variable_kind == 'CONSTANT'\n    }.each do |v|\n      io.print \"  \"\n      io.print v.name.sub(/^./){|c| c.upcase}\n      io.print \" = \"\n      io.puts  v.value\n    end\n  end\n\n  def class_name(klass)\n    klass_name = klass.name\n    if klass.ole_type == \"Class\" &&\n       klass.guid &&\n       klass.progid\n       klass_name = klass.progid.gsub(/\\./, '_')\n    end\n    if /^[A-Z]/ !~ klass_name || Module.constants.include?(klass_name)\n      klass_name = 'OLE' + klass_name\n    end\n    klass_name\n  end\n\n  def define_initialize(klass)\n    <<STR\n\n  def initialize(obj = nil)\n    @clsid = \"#{klass.guid}\"\n    @progid = \"#{klass.progid}\"\n    if obj.nil?\n      @dispatch = WIN32OLE.new @progid\n    else\n      @dispatch = obj\n    end\n  end\nSTR\n  end\n\n  def define_include\n    \"  include WIN32OLE::VARIANT\"\n  end\n\n  def define_instance_variables\n    \"  attr_reader :lastargs\"\n  end\n\n  def define_method_missing\n    <<STR\n\n  def method_missing(cmd, *arg)\n    @dispatch.method_missing(cmd, *arg)\n  end\nSTR\n  end\n\n  def define_class(klass, io = STDOUT)\n    io.puts \"class #{class_name(klass)} # #{klass.name}\"\n    io.puts define_include\n    io.puts define_instance_variables\n    io.puts \"  attr_reader :dispatch\"\n    io.puts \"  attr_reader :clsid\"\n    io.puts \"  attr_reader :progid\"\n    io.puts define_initialize(klass)\n    io.puts define_method_missing\n  end\n\n  def define_module(klass, io = STDOUT)\n    io.puts \"module #{class_name(klass)}\"\n    io.puts define_include\n    io.puts define_instance_variables\n  end\n\n  def generate_class(klass, io = STDOUT)\n    io.puts \"\\n# #{klass.helpstring}\"\n    if klass.ole_type == \"Class\" &&\n       klass.guid &&\n       klass.progid\n      @reciever = \"@dispatch.\"\n      define_class(klass, io)\n    else\n      @reciever = \"\"\n      define_module(klass, io)\n    end\n    generate_constants(klass, io)\n    generate_methods(klass, io)\n    io.puts \"end\"\n  end\n\n  def generate(io = STDOUT)\n    io.puts \"require 'win32ole'\"\n    io.puts \"require 'win32ole/property'\"\n\n    ole_classes(typelib).select{|klass|\n      klass.visible? &&\n      (klass.ole_type == \"Class\" || \n       klass.ole_type == \"Interface\" || \n       klass.ole_type == \"Dispatch\" ||\n       klass.ole_type == \"Enum\")\n    }.each do |klass|\n      generate_class(klass, io)\n    end\n    begin\n      @ole.quit if @ole\n    rescue \n    end\n  end\nend\n\nrequire 'win32ole'\nif __FILE__ == $0\n  if ARGV.size == 0\n    $stderr.puts \"usage: #{$0} Type Library [...]\"\n    exit 1\n  end\n  ARGV.each do |typelib|\n    comgen = WIN32COMGen.new(typelib)\n    comgen.generate\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/sample/xml.rb",
    "content": "# \n# This file created by olegen.rb as following.\n#    ruby olegen.rb 'Microsoft XML, version 2.0' > xml.rb\n# \nrequire 'win32ole'\nrequire 'win32ole/property'\n\n# \nmodule IXMLDOMImplementation\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BOOL hasFeature\n  #   BSTR arg0 --- feature [IN]\n  #   BSTR arg1 --- version [IN]\n  def hasFeature(arg0, arg1)\n    ret = _invoke(145, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# Core DOM node interface\nmodule IXMLDOMNode\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# Constants that define a node's type\nmodule OLEtagDOMNodeType\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  NODE_INVALID = 0\n  NODE_ELEMENT = 1\n  NODE_ATTRIBUTE = 2\n  NODE_TEXT = 3\n  NODE_CDATA_SECTION = 4\n  NODE_ENTITY_REFERENCE = 5\n  NODE_ENTITY = 6\n  NODE_PROCESSING_INSTRUCTION = 7\n  NODE_COMMENT = 8\n  NODE_DOCUMENT = 9\n  NODE_DOCUMENT_TYPE = 10\n  NODE_DOCUMENT_FRAGMENT = 11\n  NODE_NOTATION = 12\nend\n\n# \nmodule IXMLDOMNodeList\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # I4 length\n  # number of nodes in the collection\n  def length()\n    ret = _getproperty(74, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # PTR item\n  # collection of nodes\n  #   I4 arg0 --- index [IN]\n  def item\n    OLEProperty.new(self, 0, [VT_I4], [VT_I4, VT_BYREF|VT_DISPATCH])\n  end\n\n  # IXMLDOMNode nextNode\n  # get next node from iterator\n  def nextNode()\n    ret = _invoke(76, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID reset\n  # reset the position of iterator\n  def reset()\n    ret = _invoke(77, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMNamedNodeMap\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # I4 length\n  # number of nodes in the collection\n  def length()\n    ret = _getproperty(74, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # PTR item\n  # collection of nodes\n  #   I4 arg0 --- index [IN]\n  def item\n    OLEProperty.new(self, 0, [VT_I4], [VT_I4, VT_BYREF|VT_DISPATCH])\n  end\n\n  # IXMLDOMNode getNamedItem\n  # lookup item by name\n  #   BSTR arg0 --- name [IN]\n  def getNamedItem(arg0)\n    ret = _invoke(83, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode setNamedItem\n  # set item by name\n  #   IXMLDOMNode arg0 --- newItem [IN]\n  def setNamedItem(arg0)\n    ret = _invoke(84, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeNamedItem\n  # remove item by name\n  #   BSTR arg0 --- name [IN]\n  def removeNamedItem(arg0)\n    ret = _invoke(85, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode getQualifiedItem\n  # lookup the item by name and namespace\n  #   BSTR arg0 --- baseName [IN]\n  #   BSTR arg1 --- namespaceURI [IN]\n  def getQualifiedItem(arg0, arg1)\n    ret = _invoke(87, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeQualifiedItem\n  # remove the item by name and namespace\n  #   BSTR arg0 --- baseName [IN]\n  #   BSTR arg1 --- namespaceURI [IN]\n  def removeQualifiedItem(arg0, arg1)\n    ret = _invoke(88, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextNode\n  # get next node from iterator\n  def nextNode()\n    ret = _invoke(89, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID reset\n  # reset the position of iterator\n  def reset()\n    ret = _invoke(90, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMDocument\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocumentType doctype\n  # node corresponding to the DOCTYPE\n  def doctype()\n    ret = _getproperty(38, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMImplementation implementation\n  # info on this DOM implementation\n  def implementation()\n    ret = _getproperty(39, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMElement documentElement\n  # the root of the tree\n  def documentElement()\n    ret = _getproperty(40, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 readyState\n  # get the state of the XML document\n  def readyState()\n    ret = _getproperty(-525, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMParseError parseError\n  # get the last parser error\n  def parseError()\n    ret = _getproperty(59, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR url\n  # get the URL for the loaded XML document\n  def url()\n    ret = _getproperty(60, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL async\n  # flag for asynchronous download\n  def async()\n    ret = _getproperty(61, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL validateOnParse\n  # indicates whether the parser performs validation\n  def validateOnParse()\n    ret = _getproperty(65, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL resolveExternals\n  # indicates whether the parser resolves references to external DTD/Entities/Schema\n  def resolveExternals()\n    ret = _getproperty(66, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL preserveWhiteSpace\n  # indicates whether the parser preserves whitespace\n  def preserveWhiteSpace()\n    ret = _getproperty(67, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID async\n  # flag for asynchronous download\n  def async=(arg0)\n    ret = _setproperty(61, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID validateOnParse\n  # indicates whether the parser performs validation\n  def validateOnParse=(arg0)\n    ret = _setproperty(65, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID resolveExternals\n  # indicates whether the parser resolves references to external DTD/Entities/Schema\n  def resolveExternals=(arg0)\n    ret = _setproperty(66, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID preserveWhiteSpace\n  # indicates whether the parser preserves whitespace\n  def preserveWhiteSpace=(arg0)\n    ret = _setproperty(67, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID onreadystatechange\n  # register a readystatechange event handler\n  def onreadystatechange=(arg0)\n    ret = _setproperty(68, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID ondataavailable\n  # register an ondataavailable event handler\n  def ondataavailable=(arg0)\n    ret = _setproperty(69, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID ontransformnode\n  # register an ontransformnode event handler\n  def ontransformnode=(arg0)\n    ret = _setproperty(70, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMElement createElement\n  # create an Element node\n  #   BSTR arg0 --- tagName [IN]\n  def createElement(arg0)\n    ret = _invoke(41, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocumentFragment createDocumentFragment\n  # create a DocumentFragment node\n  def createDocumentFragment()\n    ret = _invoke(42, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMText createTextNode\n  # create a text node\n  #   BSTR arg0 --- data [IN]\n  def createTextNode(arg0)\n    ret = _invoke(43, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMComment createComment\n  # create a comment node\n  #   BSTR arg0 --- data [IN]\n  def createComment(arg0)\n    ret = _invoke(44, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMCDATASection createCDATASection\n  # create a CDATA section node\n  #   BSTR arg0 --- data [IN]\n  def createCDATASection(arg0)\n    ret = _invoke(45, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMProcessingInstruction createProcessingInstruction\n  # create a processing instruction node\n  #   BSTR arg0 --- target [IN]\n  #   BSTR arg1 --- data [IN]\n  def createProcessingInstruction(arg0, arg1)\n    ret = _invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMAttribute createAttribute\n  # create an attribute node\n  #   BSTR arg0 --- name [IN]\n  def createAttribute(arg0)\n    ret = _invoke(47, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMEntityReference createEntityReference\n  # create an entity reference node\n  #   BSTR arg0 --- name [IN]\n  def createEntityReference(arg0)\n    ret = _invoke(49, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList getElementsByTagName\n  # build a list of elements by name\n  #   BSTR arg0 --- tagName [IN]\n  def getElementsByTagName(arg0)\n    ret = _invoke(50, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode createNode\n  # create a node of the specified node type and name\n  #   VARIANT arg0 --- type [IN]\n  #   BSTR arg1 --- name [IN]\n  #   BSTR arg2 --- namespaceURI [IN]\n  def createNode(arg0, arg1, arg2)\n    ret = _invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nodeFromID\n  # retrieve node from it's ID\n  #   BSTR arg0 --- idString [IN]\n  def nodeFromID(arg0)\n    ret = _invoke(56, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL load\n  # load document from the specified XML source\n  #   VARIANT arg0 --- xmlSource [IN]\n  def load(arg0)\n    ret = _invoke(58, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID abort\n  # abort an asynchronous download\n  def abort()\n    ret = _invoke(62, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL loadXML\n  # load the document from a string\n  #   BSTR arg0 --- bstrXML [IN]\n  def loadXML(arg0)\n    ret = _invoke(63, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID save\n  # save the document to a specified desination\n  #   VARIANT arg0 --- desination [IN]\n  def save(arg0)\n    ret = _invoke(64, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMDocumentType\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR name\n  # name of the document type (root of the tree)\n  def name()\n    ret = _getproperty(131, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap entities\n  # a list of entities in the document\n  def entities()\n    ret = _getproperty(132, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap notations\n  # a list of notations in the document\n  def notations()\n    ret = _getproperty(133, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMElement\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR tagName\n  # get the tagName of the element\n  def tagName()\n    ret = _getproperty(97, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT getAttribute\n  # look up the string value of an attribute by name\n  #   BSTR arg0 --- name [IN]\n  def getAttribute(arg0)\n    ret = _invoke(99, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID setAttribute\n  # set the string value of an attribute by name\n  #   BSTR arg0 --- name [IN]\n  #   VARIANT arg1 --- value [IN]\n  def setAttribute(arg0, arg1)\n    ret = _invoke(100, [arg0, arg1], [VT_BSTR, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID removeAttribute\n  # remove an attribute by name\n  #   BSTR arg0 --- name [IN]\n  def removeAttribute(arg0)\n    ret = _invoke(101, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMAttribute getAttributeNode\n  # look up the attribute node by name\n  #   BSTR arg0 --- name [IN]\n  def getAttributeNode(arg0)\n    ret = _invoke(102, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMAttribute setAttributeNode\n  # set the specified attribute on the element\n  #   IXMLDOMAttribute arg0 --- DOMAttribute [IN]\n  def setAttributeNode(arg0)\n    ret = _invoke(103, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMAttribute removeAttributeNode\n  # remove the specified attribute\n  #   IXMLDOMAttribute arg0 --- DOMAttribute [IN]\n  def removeAttributeNode(arg0)\n    ret = _invoke(104, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList getElementsByTagName\n  # build a list of elements by name\n  #   BSTR arg0 --- tagName [IN]\n  def getElementsByTagName(arg0)\n    ret = _invoke(105, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID normalize\n  # collapse all adjacent text nodes in sub-tree\n  def normalize()\n    ret = _invoke(106, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMAttribute\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR name\n  # get name of the attribute\n  def name()\n    ret = _getproperty(118, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT value\n  # string value of the attribute\n  def value()\n    ret = _getproperty(120, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID value\n  # string value of the attribute\n  def value=(arg0)\n    ret = _setproperty(120, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMDocumentFragment\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMText\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR data\n  # value of the node\n  def data()\n    ret = _getproperty(109, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 length\n  # number of characters in value\n  def length()\n    ret = _getproperty(110, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID data\n  # value of the node\n  def data=(arg0)\n    ret = _setproperty(109, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR substringData\n  # retrieve substring of value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def substringData(arg0, arg1)\n    ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID appendData\n  # append string to value\n  #   BSTR arg0 --- data [IN]\n  def appendData(arg0)\n    ret = _invoke(112, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID insertData\n  # insert string into value\n  #   I4 arg0 --- offset [IN]\n  #   BSTR arg1 --- data [IN]\n  def insertData(arg0, arg1)\n    ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID deleteData\n  # delete string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def deleteData(arg0, arg1)\n    ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID replaceData\n  # replace string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  #   BSTR arg2 --- data [IN]\n  def replaceData(arg0, arg1, arg2)\n    ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMText splitText\n  # split the text node into two text nodes at the position specified\n  #   I4 arg0 --- offset [IN]\n  def splitText(arg0)\n    ret = _invoke(123, [arg0], [VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMCharacterData\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR data\n  # value of the node\n  def data()\n    ret = _getproperty(109, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 length\n  # number of characters in value\n  def length()\n    ret = _getproperty(110, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID data\n  # value of the node\n  def data=(arg0)\n    ret = _setproperty(109, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR substringData\n  # retrieve substring of value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def substringData(arg0, arg1)\n    ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID appendData\n  # append string to value\n  #   BSTR arg0 --- data [IN]\n  def appendData(arg0)\n    ret = _invoke(112, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID insertData\n  # insert string into value\n  #   I4 arg0 --- offset [IN]\n  #   BSTR arg1 --- data [IN]\n  def insertData(arg0, arg1)\n    ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID deleteData\n  # delete string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def deleteData(arg0, arg1)\n    ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID replaceData\n  # replace string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  #   BSTR arg2 --- data [IN]\n  def replaceData(arg0, arg1, arg2)\n    ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMComment\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR data\n  # value of the node\n  def data()\n    ret = _getproperty(109, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 length\n  # number of characters in value\n  def length()\n    ret = _getproperty(110, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID data\n  # value of the node\n  def data=(arg0)\n    ret = _setproperty(109, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR substringData\n  # retrieve substring of value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def substringData(arg0, arg1)\n    ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID appendData\n  # append string to value\n  #   BSTR arg0 --- data [IN]\n  def appendData(arg0)\n    ret = _invoke(112, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID insertData\n  # insert string into value\n  #   I4 arg0 --- offset [IN]\n  #   BSTR arg1 --- data [IN]\n  def insertData(arg0, arg1)\n    ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID deleteData\n  # delete string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def deleteData(arg0, arg1)\n    ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID replaceData\n  # replace string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  #   BSTR arg2 --- data [IN]\n  def replaceData(arg0, arg1, arg2)\n    ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMCDATASection\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR data\n  # value of the node\n  def data()\n    ret = _getproperty(109, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 length\n  # number of characters in value\n  def length()\n    ret = _getproperty(110, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID data\n  # value of the node\n  def data=(arg0)\n    ret = _setproperty(109, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR substringData\n  # retrieve substring of value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def substringData(arg0, arg1)\n    ret = _invoke(111, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID appendData\n  # append string to value\n  #   BSTR arg0 --- data [IN]\n  def appendData(arg0)\n    ret = _invoke(112, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID insertData\n  # insert string into value\n  #   I4 arg0 --- offset [IN]\n  #   BSTR arg1 --- data [IN]\n  def insertData(arg0, arg1)\n    ret = _invoke(113, [arg0, arg1], [VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID deleteData\n  # delete string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  def deleteData(arg0, arg1)\n    ret = _invoke(114, [arg0, arg1], [VT_I4, VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID replaceData\n  # replace string within the value\n  #   I4 arg0 --- offset [IN]\n  #   I4 arg1 --- count [IN]\n  #   BSTR arg2 --- data [IN]\n  def replaceData(arg0, arg1, arg2)\n    ret = _invoke(115, [arg0, arg1, arg2], [VT_I4, VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMText splitText\n  # split the text node into two text nodes at the position specified\n  #   I4 arg0 --- offset [IN]\n  def splitText(arg0)\n    ret = _invoke(123, [arg0], [VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMProcessingInstruction\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR target\n  # the target\n  def target()\n    ret = _getproperty(127, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR data\n  # the data\n  def data()\n    ret = _getproperty(128, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID data\n  # the data\n  def data=(arg0)\n    ret = _setproperty(128, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMEntityReference\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# structure for reporting parser errors\nmodule IXMLDOMParseError\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # I4 errorCode\n  # the error code\n  def errorCode()\n    ret = _getproperty(0, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR url\n  # the URL of the XML document containing the error\n  def url()\n    ret = _getproperty(179, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR reason\n  # the cause of the error\n  def reason()\n    ret = _getproperty(180, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR srcText\n  # the data where the error occurred\n  def srcText()\n    ret = _getproperty(181, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 line\n  # the line number in the XML document where the error occurred\n  def line()\n    ret = _getproperty(182, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 linepos\n  # the character position in the line containing the error\n  def linepos()\n    ret = _getproperty(183, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 filepos\n  # the absolute file position in the XML document containing the error\n  def filepos()\n    ret = _getproperty(184, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMNotation\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT publicId\n  # the public ID\n  def publicId()\n    ret = _getproperty(136, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT systemId\n  # the system ID\n  def systemId()\n    ret = _getproperty(137, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# \nmodule IXMLDOMEntity\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT publicId\n  # the public ID\n  def publicId()\n    ret = _getproperty(140, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT systemId\n  # the system ID\n  def systemId()\n    ret = _getproperty(141, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR notationName\n  # the name of the notation\n  def notationName()\n    ret = _getproperty(142, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# XTL runtime object\nmodule IXTLRuntime\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = _getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = _getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = _getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = _getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = _getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = _getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = _getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = _getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = _getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = _getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = _getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = _getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = _getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = _getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = _getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = _getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = _setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = _setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = _setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = _setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = _invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = _invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = _invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = _invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = _invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = _invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = _invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = _invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = _invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = _invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 uniqueID\n  #   IXMLDOMNode arg0 --- pNode [IN]\n  def uniqueID(arg0)\n    ret = _invoke(187, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 depth\n  #   IXMLDOMNode arg0 --- pNode [IN]\n  def depth(arg0)\n    ret = _invoke(188, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 childNumber\n  #   IXMLDOMNode arg0 --- pNode [IN]\n  def childNumber(arg0)\n    ret = _invoke(189, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 ancestorChildNumber\n  #   BSTR arg0 --- bstrNodeName [IN]\n  #   IXMLDOMNode arg1 --- pNode [IN]\n  def ancestorChildNumber(arg0, arg1)\n    ret = _invoke(190, [arg0, arg1], [VT_BSTR, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 absoluteChildNumber\n  #   IXMLDOMNode arg0 --- pNode [IN]\n  def absoluteChildNumber(arg0)\n    ret = _invoke(191, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR formatIndex\n  #   I4 arg0 --- lIndex [IN]\n  #   BSTR arg1 --- bstrFormat [IN]\n  def formatIndex(arg0, arg1)\n    ret = _invoke(192, [arg0, arg1], [VT_I4, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR formatNumber\n  #   R8 arg0 --- dblNumber [IN]\n  #   BSTR arg1 --- bstrFormat [IN]\n  def formatNumber(arg0, arg1)\n    ret = _invoke(193, [arg0, arg1], [VT_R8, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR formatDate\n  #   VARIANT arg0 --- varDate [IN]\n  #   BSTR arg1 --- bstrFormat [IN]\n  #   VARIANT arg2 --- varDestLocale [IN]\n  def formatDate(arg0, arg1, arg2=nil)\n    ret = _invoke(194, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR formatTime\n  #   VARIANT arg0 --- varTime [IN]\n  #   BSTR arg1 --- bstrFormat [IN]\n  #   VARIANT arg2 --- varDestLocale [IN]\n  def formatTime(arg0, arg1, arg2=nil)\n    ret = _invoke(195, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# W3C-DOM XML Document\nclass Microsoft_XMLDOM_1_0 # DOMDocument\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  attr_reader :dispatch\n  attr_reader :clsid\n  attr_reader :progid\n\n  def initialize(obj = nil)\n    @clsid = \"{2933BF90-7B36-11D2-B20E-00C04F983E60}\"\n    @progid = \"Microsoft.XMLDOM.1.0\"\n    if obj.nil?\n      @dispatch = WIN32OLE.new(@progid)\n    else\n      @dispatch = obj\n    end\n  end\n\n  def method_missing(cmd, *arg)\n    @dispatch.method_missing(cmd, *arg)\n  end\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = @dispatch._getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = @dispatch._getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = @dispatch._getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = @dispatch._getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = @dispatch._getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = @dispatch._getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = @dispatch._getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = @dispatch._getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = @dispatch._getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = @dispatch._getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = @dispatch._getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = @dispatch._getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = @dispatch._getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = @dispatch._getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = @dispatch._getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = @dispatch._getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = @dispatch._getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = @dispatch._getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = @dispatch._getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = @dispatch._getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = @dispatch._getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = @dispatch._getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocumentType doctype\n  # node corresponding to the DOCTYPE\n  def doctype()\n    ret = @dispatch._getproperty(38, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMImplementation implementation\n  # info on this DOM implementation\n  def implementation()\n    ret = @dispatch._getproperty(39, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMElement documentElement\n  # the root of the tree\n  def documentElement()\n    ret = @dispatch._getproperty(40, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 readyState\n  # get the state of the XML document\n  def readyState()\n    ret = @dispatch._getproperty(-525, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMParseError parseError\n  # get the last parser error\n  def parseError()\n    ret = @dispatch._getproperty(59, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR url\n  # get the URL for the loaded XML document\n  def url()\n    ret = @dispatch._getproperty(60, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL async\n  # flag for asynchronous download\n  def async()\n    ret = @dispatch._getproperty(61, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL validateOnParse\n  # indicates whether the parser performs validation\n  def validateOnParse()\n    ret = @dispatch._getproperty(65, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL resolveExternals\n  # indicates whether the parser resolves references to external DTD/Entities/Schema\n  def resolveExternals()\n    ret = @dispatch._getproperty(66, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL preserveWhiteSpace\n  # indicates whether the parser preserves whitespace\n  def preserveWhiteSpace()\n    ret = @dispatch._getproperty(67, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = @dispatch._setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = @dispatch._setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = @dispatch._setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = @dispatch._setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID async\n  # flag for asynchronous download\n  def async=(arg0)\n    ret = @dispatch._setproperty(61, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID validateOnParse\n  # indicates whether the parser performs validation\n  def validateOnParse=(arg0)\n    ret = @dispatch._setproperty(65, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID resolveExternals\n  # indicates whether the parser resolves references to external DTD/Entities/Schema\n  def resolveExternals=(arg0)\n    ret = @dispatch._setproperty(66, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID preserveWhiteSpace\n  # indicates whether the parser preserves whitespace\n  def preserveWhiteSpace=(arg0)\n    ret = @dispatch._setproperty(67, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID onreadystatechange\n  # register a readystatechange event handler\n  def onreadystatechange=(arg0)\n    ret = @dispatch._setproperty(68, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID ondataavailable\n  # register an ondataavailable event handler\n  def ondataavailable=(arg0)\n    ret = @dispatch._setproperty(69, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID ontransformnode\n  # register an ontransformnode event handler\n  def ontransformnode=(arg0)\n    ret = @dispatch._setproperty(70, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = @dispatch._invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = @dispatch._invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = @dispatch._invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = @dispatch._invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = @dispatch._invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = @dispatch._invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = @dispatch._invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = @dispatch._invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = @dispatch._invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = @dispatch._invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMElement createElement\n  # create an Element node\n  #   BSTR arg0 --- tagName [IN]\n  def createElement(arg0)\n    ret = @dispatch._invoke(41, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocumentFragment createDocumentFragment\n  # create a DocumentFragment node\n  def createDocumentFragment()\n    ret = @dispatch._invoke(42, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMText createTextNode\n  # create a text node\n  #   BSTR arg0 --- data [IN]\n  def createTextNode(arg0)\n    ret = @dispatch._invoke(43, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMComment createComment\n  # create a comment node\n  #   BSTR arg0 --- data [IN]\n  def createComment(arg0)\n    ret = @dispatch._invoke(44, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMCDATASection createCDATASection\n  # create a CDATA section node\n  #   BSTR arg0 --- data [IN]\n  def createCDATASection(arg0)\n    ret = @dispatch._invoke(45, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMProcessingInstruction createProcessingInstruction\n  # create a processing instruction node\n  #   BSTR arg0 --- target [IN]\n  #   BSTR arg1 --- data [IN]\n  def createProcessingInstruction(arg0, arg1)\n    ret = @dispatch._invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMAttribute createAttribute\n  # create an attribute node\n  #   BSTR arg0 --- name [IN]\n  def createAttribute(arg0)\n    ret = @dispatch._invoke(47, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMEntityReference createEntityReference\n  # create an entity reference node\n  #   BSTR arg0 --- name [IN]\n  def createEntityReference(arg0)\n    ret = @dispatch._invoke(49, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList getElementsByTagName\n  # build a list of elements by name\n  #   BSTR arg0 --- tagName [IN]\n  def getElementsByTagName(arg0)\n    ret = @dispatch._invoke(50, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode createNode\n  # create a node of the specified node type and name\n  #   VARIANT arg0 --- type [IN]\n  #   BSTR arg1 --- name [IN]\n  #   BSTR arg2 --- namespaceURI [IN]\n  def createNode(arg0, arg1, arg2)\n    ret = @dispatch._invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nodeFromID\n  # retrieve node from it's ID\n  #   BSTR arg0 --- idString [IN]\n  def nodeFromID(arg0)\n    ret = @dispatch._invoke(56, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL load\n  # load document from the specified XML source\n  #   VARIANT arg0 --- xmlSource [IN]\n  def load(arg0)\n    ret = @dispatch._invoke(58, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID abort\n  # abort an asynchronous download\n  def abort()\n    ret = @dispatch._invoke(62, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL loadXML\n  # load the document from a string\n  #   BSTR arg0 --- bstrXML [IN]\n  def loadXML(arg0)\n    ret = @dispatch._invoke(63, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID save\n  # save the document to a specified desination\n  #   VARIANT arg0 --- desination [IN]\n  def save(arg0)\n    ret = @dispatch._invoke(64, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT ondataavailable EVENT in XMLDOMDocumentEvents\n  def ondataavailable()\n    ret = @dispatch._invoke(198, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT onreadystatechange EVENT in XMLDOMDocumentEvents\n  def onreadystatechange()\n    ret = @dispatch._invoke(-609, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# W3C-DOM XML Document (Apartment)\nclass Microsoft_FreeThreadedXMLDOM_1_0 # DOMFreeThreadedDocument\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  attr_reader :dispatch\n  attr_reader :clsid\n  attr_reader :progid\n\n  def initialize(obj = nil)\n    @clsid = \"{2933BF91-7B36-11D2-B20E-00C04F983E60}\"\n    @progid = \"Microsoft.FreeThreadedXMLDOM.1.0\"\n    if obj.nil?\n      @dispatch = WIN32OLE.new(@progid)\n    else\n      @dispatch = obj\n    end\n  end\n\n  def method_missing(cmd, *arg)\n    @dispatch.method_missing(cmd, *arg)\n  end\n\n  # BSTR nodeName\n  # name of the node\n  def nodeName()\n    ret = @dispatch._getproperty(2, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeValue\n  # value stored in the node\n  def nodeValue()\n    ret = @dispatch._getproperty(3, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DOMNodeType nodeType\n  # the node's type\n  def nodeType()\n    ret = @dispatch._getproperty(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode parentNode\n  # parent of the node\n  def parentNode()\n    ret = @dispatch._getproperty(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList childNodes\n  # the collection of the node's children\n  def childNodes()\n    ret = @dispatch._getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode firstChild\n  # first child of the node\n  def firstChild()\n    ret = @dispatch._getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode lastChild\n  # first child of the node\n  def lastChild()\n    ret = @dispatch._getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode previousSibling\n  # left sibling of the node\n  def previousSibling()\n    ret = @dispatch._getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nextSibling\n  # right sibling of the node\n  def nextSibling()\n    ret = @dispatch._getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNamedNodeMap attributes\n  # the collection of the node's attributes\n  def attributes()\n    ret = @dispatch._getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocument ownerDocument\n  # document that contains the node\n  def ownerDocument()\n    ret = @dispatch._getproperty(18, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR nodeTypeString\n  # the type of node in string form\n  def nodeTypeString()\n    ret = @dispatch._getproperty(21, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR text\n  # text content of the node and subtree\n  def text()\n    ret = @dispatch._getproperty(24, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL specified\n  # indicates whether node is a default value\n  def specified()\n    ret = @dispatch._getproperty(22, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode definition\n  # pointer to the definition of the node in the DTD or schema\n  def definition()\n    ret = @dispatch._getproperty(23, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue()\n    ret = @dispatch._getproperty(25, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT dataType\n  # the data type of the node\n  def dataType()\n    ret = @dispatch._getproperty(26, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR xml\n  # return the XML source for the node and each of its descendants\n  def xml()\n    ret = @dispatch._getproperty(27, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL parsed\n  # has sub-tree been completely parsed\n  def parsed()\n    ret = @dispatch._getproperty(31, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR namespaceURI\n  # the URI for the namespace applying to the node\n  def namespaceURI()\n    ret = @dispatch._getproperty(32, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR prefix\n  # the prefix for the namespace applying to the node\n  def prefix()\n    ret = @dispatch._getproperty(33, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR baseName\n  # the base name of the node (nodename with the prefix stripped off)\n  def baseName()\n    ret = @dispatch._getproperty(34, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocumentType doctype\n  # node corresponding to the DOCTYPE\n  def doctype()\n    ret = @dispatch._getproperty(38, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMImplementation implementation\n  # info on this DOM implementation\n  def implementation()\n    ret = @dispatch._getproperty(39, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMElement documentElement\n  # the root of the tree\n  def documentElement()\n    ret = @dispatch._getproperty(40, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 readyState\n  # get the state of the XML document\n  def readyState()\n    ret = @dispatch._getproperty(-525, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMParseError parseError\n  # get the last parser error\n  def parseError()\n    ret = @dispatch._getproperty(59, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR url\n  # get the URL for the loaded XML document\n  def url()\n    ret = @dispatch._getproperty(60, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL async\n  # flag for asynchronous download\n  def async()\n    ret = @dispatch._getproperty(61, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL validateOnParse\n  # indicates whether the parser performs validation\n  def validateOnParse()\n    ret = @dispatch._getproperty(65, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL resolveExternals\n  # indicates whether the parser resolves references to external DTD/Entities/Schema\n  def resolveExternals()\n    ret = @dispatch._getproperty(66, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL preserveWhiteSpace\n  # indicates whether the parser preserves whitespace\n  def preserveWhiteSpace()\n    ret = @dispatch._getproperty(67, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeValue\n  # value stored in the node\n  def nodeValue=(arg0)\n    ret = @dispatch._setproperty(3, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID text\n  # text content of the node and subtree\n  def text=(arg0)\n    ret = @dispatch._setproperty(24, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID nodeTypedValue\n  # get the strongly typed value of the node\n  def nodeTypedValue=(arg0)\n    ret = @dispatch._setproperty(25, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID dataType\n  # the data type of the node\n  def dataType=(arg0)\n    ret = @dispatch._setproperty(26, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID async\n  # flag for asynchronous download\n  def async=(arg0)\n    ret = @dispatch._setproperty(61, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID validateOnParse\n  # indicates whether the parser performs validation\n  def validateOnParse=(arg0)\n    ret = @dispatch._setproperty(65, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID resolveExternals\n  # indicates whether the parser resolves references to external DTD/Entities/Schema\n  def resolveExternals=(arg0)\n    ret = @dispatch._setproperty(66, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID preserveWhiteSpace\n  # indicates whether the parser preserves whitespace\n  def preserveWhiteSpace=(arg0)\n    ret = @dispatch._setproperty(67, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID onreadystatechange\n  # register a readystatechange event handler\n  def onreadystatechange=(arg0)\n    ret = @dispatch._setproperty(68, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID ondataavailable\n  # register an ondataavailable event handler\n  def ondataavailable=(arg0)\n    ret = @dispatch._setproperty(69, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID ontransformnode\n  # register an ontransformnode event handler\n  def ontransformnode=(arg0)\n    ret = @dispatch._setproperty(70, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode insertBefore\n  # insert a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   VARIANT arg1 --- refChild [IN]\n  def insertBefore(arg0, arg1)\n    ret = @dispatch._invoke(13, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode replaceChild\n  # replace a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  #   IXMLDOMNode arg1 --- oldChild [IN]\n  def replaceChild(arg0, arg1)\n    ret = @dispatch._invoke(14, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode removeChild\n  # remove a child node\n  #   IXMLDOMNode arg0 --- childNode [IN]\n  def removeChild(arg0)\n    ret = @dispatch._invoke(15, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode appendChild\n  # append a child node\n  #   IXMLDOMNode arg0 --- newChild [IN]\n  def appendChild(arg0)\n    ret = @dispatch._invoke(16, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL hasChildNodes\n  def hasChildNodes()\n    ret = @dispatch._invoke(17, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode cloneNode\n  #   BOOL arg0 --- deep [IN]\n  def cloneNode(arg0)\n    ret = @dispatch._invoke(19, [arg0], [VT_BOOL])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR transformNode\n  # apply the stylesheet to the subtree\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  def transformNode(arg0)\n    ret = @dispatch._invoke(28, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList selectNodes\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectNodes(arg0)\n    ret = @dispatch._invoke(29, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode selectSingleNode\n  # execute query on the subtree\n  #   BSTR arg0 --- queryString [IN]\n  def selectSingleNode(arg0)\n    ret = @dispatch._invoke(30, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID transformNodeToObject\n  # apply the stylesheet to the subtree, returning the result through a document or a stream\n  #   IXMLDOMNode arg0 --- stylesheet [IN]\n  #   VARIANT arg1 --- outputObject [IN]\n  def transformNodeToObject(arg0, arg1)\n    ret = @dispatch._invoke(35, [arg0, arg1], [VT_BYREF|VT_DISPATCH, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMElement createElement\n  # create an Element node\n  #   BSTR arg0 --- tagName [IN]\n  def createElement(arg0)\n    ret = @dispatch._invoke(41, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMDocumentFragment createDocumentFragment\n  # create a DocumentFragment node\n  def createDocumentFragment()\n    ret = @dispatch._invoke(42, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMText createTextNode\n  # create a text node\n  #   BSTR arg0 --- data [IN]\n  def createTextNode(arg0)\n    ret = @dispatch._invoke(43, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMComment createComment\n  # create a comment node\n  #   BSTR arg0 --- data [IN]\n  def createComment(arg0)\n    ret = @dispatch._invoke(44, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMCDATASection createCDATASection\n  # create a CDATA section node\n  #   BSTR arg0 --- data [IN]\n  def createCDATASection(arg0)\n    ret = @dispatch._invoke(45, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMProcessingInstruction createProcessingInstruction\n  # create a processing instruction node\n  #   BSTR arg0 --- target [IN]\n  #   BSTR arg1 --- data [IN]\n  def createProcessingInstruction(arg0, arg1)\n    ret = @dispatch._invoke(46, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMAttribute createAttribute\n  # create an attribute node\n  #   BSTR arg0 --- name [IN]\n  def createAttribute(arg0)\n    ret = @dispatch._invoke(47, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMEntityReference createEntityReference\n  # create an entity reference node\n  #   BSTR arg0 --- name [IN]\n  def createEntityReference(arg0)\n    ret = @dispatch._invoke(49, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNodeList getElementsByTagName\n  # build a list of elements by name\n  #   BSTR arg0 --- tagName [IN]\n  def getElementsByTagName(arg0)\n    ret = @dispatch._invoke(50, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode createNode\n  # create a node of the specified node type and name\n  #   VARIANT arg0 --- type [IN]\n  #   BSTR arg1 --- name [IN]\n  #   BSTR arg2 --- namespaceURI [IN]\n  def createNode(arg0, arg1, arg2)\n    ret = @dispatch._invoke(54, [arg0, arg1, arg2], [VT_VARIANT, VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # IXMLDOMNode nodeFromID\n  # retrieve node from it's ID\n  #   BSTR arg0 --- idString [IN]\n  def nodeFromID(arg0)\n    ret = @dispatch._invoke(56, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL load\n  # load document from the specified XML source\n  #   VARIANT arg0 --- xmlSource [IN]\n  def load(arg0)\n    ret = @dispatch._invoke(58, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID abort\n  # abort an asynchronous download\n  def abort()\n    ret = @dispatch._invoke(62, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BOOL loadXML\n  # load the document from a string\n  #   BSTR arg0 --- bstrXML [IN]\n  def loadXML(arg0)\n    ret = @dispatch._invoke(63, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID save\n  # save the document to a specified desination\n  #   VARIANT arg0 --- desination [IN]\n  def save(arg0)\n    ret = @dispatch._invoke(64, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT ondataavailable EVENT in XMLDOMDocumentEvents\n  def ondataavailable()\n    ret = @dispatch._invoke(198, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT onreadystatechange EVENT in XMLDOMDocumentEvents\n  def onreadystatechange()\n    ret = @dispatch._invoke(-609, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# IXMLHttpRequest Interface\nmodule IXMLHttpRequest\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n\n  # I4 status\n  # Get HTTP status code\n  def status()\n    ret = _getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR statusText\n  # Get HTTP status text\n  def statusText()\n    ret = _getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DISPATCH responseXML\n  # Get response body\n  def responseXML()\n    ret = _getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR responseText\n  # Get response body\n  def responseText()\n    ret = _getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT responseBody\n  # Get response body\n  def responseBody()\n    ret = _getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT responseStream\n  # Get response body\n  def responseStream()\n    ret = _getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 readyState\n  # Get ready state\n  def readyState()\n    ret = _getproperty(13, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID onreadystatechange\n  # Register a complete event handler\n  def onreadystatechange=(arg0)\n    ret = _setproperty(14, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID open\n  # Open HTTP connection\n  #   BSTR arg0 --- bstrMethod [IN]\n  #   BSTR arg1 --- bstrUrl [IN]\n  #   VARIANT arg2 --- varAsync [IN]\n  #   VARIANT arg3 --- bstrUser [IN]\n  #   VARIANT arg4 --- bstrPassword [IN]\n  def open(arg0, arg1, arg2=nil, arg3=nil, arg4=nil)\n    ret = _invoke(1, [arg0, arg1, arg2, arg3, arg4], [VT_BSTR, VT_BSTR, VT_VARIANT, VT_VARIANT, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID setRequestHeader\n  # Add HTTP request header\n  #   BSTR arg0 --- bstrHeader [IN]\n  #   BSTR arg1 --- bstrValue [IN]\n  def setRequestHeader(arg0, arg1)\n    ret = _invoke(2, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR getResponseHeader\n  # Get HTTP response header\n  #   BSTR arg0 --- bstrHeader [IN]\n  def getResponseHeader(arg0)\n    ret = _invoke(3, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR getAllResponseHeaders\n  # Get all HTTP response headers\n  def getAllResponseHeaders()\n    ret = _invoke(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID send\n  # Send HTTP request\n  #   VARIANT arg0 --- varBody [IN]\n  def send(arg0=nil)\n    ret = _invoke(5, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID abort\n  # Abort HTTP request\n  def abort()\n    ret = _invoke(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# XML HTTP Request class.\nclass Microsoft_XMLHTTP_1 # XMLHTTPRequest\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  attr_reader :dispatch\n  attr_reader :clsid\n  attr_reader :progid\n\n  def initialize(obj = nil)\n    @clsid = \"{ED8C108E-4349-11D2-91A4-00C04F7969E8}\"\n    @progid = \"Microsoft.XMLHTTP.1\"\n    if obj.nil?\n      @dispatch = WIN32OLE.new(@progid)\n    else\n      @dispatch = obj\n    end\n  end\n\n  def method_missing(cmd, *arg)\n    @dispatch.method_missing(cmd, *arg)\n  end\n\n  # I4 status\n  # Get HTTP status code\n  def status()\n    ret = @dispatch._getproperty(7, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR statusText\n  # Get HTTP status text\n  def statusText()\n    ret = @dispatch._getproperty(8, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # DISPATCH responseXML\n  # Get response body\n  def responseXML()\n    ret = @dispatch._getproperty(9, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR responseText\n  # Get response body\n  def responseText()\n    ret = @dispatch._getproperty(10, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT responseBody\n  # Get response body\n  def responseBody()\n    ret = @dispatch._getproperty(11, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VARIANT responseStream\n  # Get response body\n  def responseStream()\n    ret = @dispatch._getproperty(12, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 readyState\n  # Get ready state\n  def readyState()\n    ret = @dispatch._getproperty(13, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID onreadystatechange\n  # Register a complete event handler\n  def onreadystatechange=(arg0)\n    ret = @dispatch._setproperty(14, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID open\n  # Open HTTP connection\n  #   BSTR arg0 --- bstrMethod [IN]\n  #   BSTR arg1 --- bstrUrl [IN]\n  #   VARIANT arg2 --- varAsync [IN]\n  #   VARIANT arg3 --- bstrUser [IN]\n  #   VARIANT arg4 --- bstrPassword [IN]\n  def open(arg0, arg1, arg2=nil, arg3=nil, arg4=nil)\n    ret = @dispatch._invoke(1, [arg0, arg1, arg2, arg3, arg4], [VT_BSTR, VT_BSTR, VT_VARIANT, VT_VARIANT, VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID setRequestHeader\n  # Add HTTP request header\n  #   BSTR arg0 --- bstrHeader [IN]\n  #   BSTR arg1 --- bstrValue [IN]\n  def setRequestHeader(arg0, arg1)\n    ret = @dispatch._invoke(2, [arg0, arg1], [VT_BSTR, VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR getResponseHeader\n  # Get HTTP response header\n  #   BSTR arg0 --- bstrHeader [IN]\n  def getResponseHeader(arg0)\n    ret = @dispatch._invoke(3, [arg0], [VT_BSTR])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # BSTR getAllResponseHeaders\n  # Get all HTTP response headers\n  def getAllResponseHeaders()\n    ret = @dispatch._invoke(4, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID send\n  # Send HTTP request\n  #   VARIANT arg0 --- varBody [IN]\n  def send(arg0=nil)\n    ret = @dispatch._invoke(5, [arg0], [VT_VARIANT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID abort\n  # Abort HTTP request\n  def abort()\n    ret = @dispatch._invoke(6, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# XML Data Source Object\nclass Microsoft_XMLDSO_1_0 # XMLDSOControl\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  attr_reader :dispatch\n  attr_reader :clsid\n  attr_reader :progid\n\n  def initialize(obj = nil)\n    @clsid = \"{550DDA30-0541-11D2-9CA9-0060B0EC3D39}\"\n    @progid = \"Microsoft.XMLDSO.1.0\"\n    if obj.nil?\n      @dispatch = WIN32OLE.new(@progid)\n    else\n      @dispatch = obj\n    end\n  end\n\n  def method_missing(cmd, *arg)\n    @dispatch.method_missing(cmd, *arg)\n  end\n\n  # IXMLDOMDocument XMLDocument\n  def XMLDocument()\n    ret = @dispatch._getproperty(65537, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 JavaDSOCompatible\n  def JavaDSOCompatible()\n    ret = @dispatch._getproperty(65538, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # I4 readyState\n  def readyState()\n    ret = @dispatch._getproperty(-525, [], [])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID XMLDocument\n  def XMLDocument=(arg0)\n    ret = @dispatch._setproperty(65537, [arg0], [VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # VOID JavaDSOCompatible\n  def JavaDSOCompatible=(arg0)\n    ret = @dispatch._setproperty(65538, [arg0], [VT_I4])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n\n# Constants that define types for IXMLElement.\nmodule OLEtagXMLEMEM_TYPE\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  XMLELEMTYPE_ELEMENT = 0\n  XMLELEMTYPE_TEXT = 1\n  XMLELEMTYPE_COMMENT = 2\n  XMLELEMTYPE_DOCUMENT = 3\n  XMLELEMTYPE_DTD = 4\n  XMLELEMTYPE_PI = 5\n  XMLELEMTYPE_OTHER = 6\nend\n\n# XMLDocument extends IXML Document.  It is obsolete.  You should use DOMDocument.  This object should not be confused with the XMLDocument property on the XML data island.\nclass Msxml # XMLDocument\n  include WIN32OLE::VARIANT\n  attr_reader :lastargs\n  attr_reader :dispatch\n  attr_reader :clsid\n  attr_reader :progid\n\n  def initialize(obj = nil)\n    @clsid = \"{CFC399AF-D876-11D0-9C10-00C04FC99C8E}\"\n    @progid = \"Msxml\"\n    if obj.nil?\n      @dispatch = WIN32OLE.new(@progid)\n    else\n      @dispatch = obj\n    end\n  end\n\n  def method_missing(cmd, *arg)\n    @dispatch.method_missing(cmd, *arg)\n  end\n\n  # HRESULT url\n  # set URL to load an XML document from the URL.\n  #   BSTR arg0 --- p [IN]\n  def url=(arg0)\n    ret = @dispatch._setproperty(65641, [arg0], [VT_BSTR, VT_HRESULT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT charset\n  # get encoding.\n  #   BSTR arg0 --- p [IN]\n  def charset=(arg0)\n    ret = @dispatch._setproperty(65645, [arg0], [VT_BSTR, VT_HRESULT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT async\n  # get asynchronous loading flag.\n  #   BOOL arg0 --- pf [IN]\n  def async=(arg0)\n    ret = @dispatch._setproperty(65649, [arg0], [VT_BOOL, VT_HRESULT])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\n\n  # HRESULT root\n  # get root IXMLElement of the XML document.\n  #   IXMLElement2,IXMLElement2 arg0 --- p [OUT]\n  def root\n    OLEProperty.new(@dispatch, 65637, [VT_BYREF|VT_BYREF|VT_DISPATCH], [VT_BYREF|VT_BYREF|VT_DISPATCH, VT_HRESULT])\n  end\n\n  # HRESULT url\n  # set URL to load an XML document from the URL.\n  #   BSTR arg0 --- p [OUT]\n  def url\n    OLEProperty.new(@dispatch, 65641, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])\n  end\n\n  # HRESULT readyState\n  # get ready state.\n  #   I4 arg0 --- pl [OUT]\n  def readyState\n    OLEProperty.new(@dispatch, 65643, [VT_BYREF|VT_I4], [VT_BYREF|VT_I4, VT_HRESULT])\n  end\n\n  # HRESULT charset\n  # get encoding.\n  #   BSTR arg0 --- p [OUT]\n  def charset\n    OLEProperty.new(@dispatch, 65645, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])\n  end\n\n  # HRESULT version\n  # get XML version number.\n  #   BSTR arg0 --- p [OUT]\n  def version\n    OLEProperty.new(@dispatch, 65646, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])\n  end\n\n  # HRESULT doctype\n  # get document type.\n  #   BSTR arg0 --- p [OUT]\n  def doctype\n    OLEProperty.new(@dispatch, 65647, [VT_BYREF|VT_BSTR], [VT_BYREF|VT_BSTR, VT_HRESULT])\n  end\n\n  # HRESULT async\n  # get asynchronous loading flag.\n  #   BOOL arg0 --- pf [OUT]\n  def async\n    OLEProperty.new(@dispatch, 65649, [VT_BYREF|VT_BOOL], [VT_BYREF|VT_BOOL, VT_HRESULT])\n  end\n\n  # HRESULT createElement\n  # create different types of IXMLElements.\n  #   VARIANT arg0 --- vType [IN]\n  #   VARIANT arg1 --- var1 [IN]\n  #   IXMLElement2,IXMLElement2 arg2 --- ppElem [OUT]\n  def createElement(arg0, arg1=nil, arg2=nil)\n    ret = @dispatch._invoke(65644, [arg0, arg1, arg2], [VT_VARIANT, VT_VARIANT, VT_BYREF|VT_BYREF|VT_DISPATCH])\n    @lastargs = WIN32OLE::ARGV\n    ret\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/oleserver.rb",
    "content": "require 'win32ole'\ndef oletypelib_name(pat)\n  WIN32OLE_TYPE.typelibs.each do |lib|\n    return lib if pat =~ lib\n  end\nend\nmodule OLESERVER\n  MS_EXCEL_TYPELIB = oletypelib_name(/^Microsoft Excel .* Object Library$/)\n  MS_XML_TYPELIB = oletypelib_name(/^Microsoft XML/)\nend\n"
  },
  {
    "path": "ext/win32ole/tests/testNIL2VTEMPTY.rb",
    "content": "# This is test script to check that WIN32OLE should convert nil to VT_EMPTY in second try.\n# [ruby-talk:137054]\n\nrequire 'win32ole'\nrequire 'test/unit'\n\nclass TestNIL2VT_EMPTY < Test::Unit::TestCase\n  def setup\n    fs = WIN32OLE.new('Scripting.FileSystemObject')\n    @path = fs.GetFolder(\".\").path\n  end\n  def test_openSchema\n    con = nil\n    begin\n      con = WIN32OLE.new('ADODB.Connection')\n      con.connectionString = \"Provider=MSDASQL;Extended Properties=\"\n      con.connectionString +=\"\\\"DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=#{@path}\\\"\"\n      con.open\n    rescue\n      con = nil\n    end\n    if con\n      rs = con.openSchema(4, [nil,nil,\"DUMMY\", \"TABLE\"])\n      assert(rs)\n    end\n  end\nend\n\n"
  },
  {
    "path": "ext/win32ole/tests/testOLEMETHOD.rb",
    "content": "# You need RubyUnit and MS Excel and MSI to run this test script \n\nrequire 'rubyunit'\n\nrequire 'win32ole'\nrequire 'oleserver'\n\nclass TestOLEMETHOD < RUNIT::TestCase\n  include OLESERVER\n  def setup\n    @excel_app = WIN32OLE_TYPE.new(MS_EXCEL_TYPELIB, 'Application')\n  end\n  def test_s_new\n    m = WIN32OLE_METHOD.new(@excel_app, 'Quit')\n    assert_instance_of(WIN32OLE_METHOD, m)\n    m =  WIN32OLE_METHOD.new(@excel_app, 'WorkbookOpen')\n    assert_instance_of(WIN32OLE_METHOD, m)\n    m =  WIN32OLE_METHOD.new(@excel_app, 'workbookopen')\n    assert_instance_of(WIN32OLE_METHOD, m)\n  end\n  def test_name\n    m = WIN32OLE_METHOD.new(@excel_app, 'Quit')\n    assert_equal('Quit', m.name)\n  end\n  def test_to_s\n    m = WIN32OLE_METHOD.new(@excel_app, 'Quit')\n    assert_equal('Quit', \"#{m}\")\n  end\n  def test_return_type\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert_equal('Range', m.return_type)\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActivePrinter')\n    assert_equal('BSTR', m.return_type)\n  end\n  def test_return_vtype\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert_equal(WIN32OLE::VARIANT::VT_PTR, m.return_vtype)\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActivePrinter')\n    assert_equal(WIN32OLE::VARIANT::VT_BSTR, m.return_vtype)\n  end\n  def test_return_type_detail\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert_equal(['PTR', 'USERDEFINED', 'Range'], m.return_type_detail)\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActivePrinter')\n    assert_equal(['BSTR'], m.return_type_detail)\n  end\n\n  def test_invoke_kind\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert_equal('PROPERTYGET', m.invoke_kind)\n  end\n  def test_visible\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert(m.visible?)\n    m = WIN32OLE_METHOD.new(@excel_app, 'AddRef')\n    assert(!m.visible?)\n  end\n  def test_event\n    m =  WIN32OLE_METHOD.new(@excel_app, 'WorkbookOpen')\n    assert(m.event?)\n    m =  WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert(!m.event?)\n  end\n  def test_event_interface\n    m = WIN32OLE_METHOD.new(@excel_app, 'WorkbookOpen')\n    assert_equal('AppEvents', m.event_interface)\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert_nil(m.event_interface)\n  end\n  def test_helpstring\n    domdoc = WIN32OLE_TYPE.new(MS_XML_TYPELIB, 'DOMDocument')\n    m =  WIN32OLE_METHOD.new(domdoc, 'abort')\n    assert_equal('abort an asynchronous download', m.helpstring)\n  end\n  def test_helpfile\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert_match(/VBAXL.*\\.(HLP|CHM)$/i, m.helpfile)\n  end\n  def test_helpcontext\n    m = WIN32OLE_METHOD.new(@excel_app, 'ActiveCell')\n    assert(m.helpcontext > 0)\n  end\n  def test_offset_vtbl\n    m = WIN32OLE_METHOD.new(@excel_app, 'QueryInterface')\n    assert_equal(0, m.offset_vtbl)\n  end\n  def test_dispid\n    tobj = WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation', 'FolderItem2')\n    method = WIN32OLE_METHOD.new(tobj, 'InvokeVerb')\n    assert_equal(1610743824, method.dispid)\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/testOLEPARAM.rb",
    "content": "# You need RubyUnit and MS Excel and MSI to run this test script \n\nrequire 'rubyunit'\n\nrequire 'win32ole'\nrequire 'oleserver'\n\nclass TestOLEPARAM < RUNIT::TestCase\n  include OLESERVER\n  def test_name\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    sh = classes.find {|c| c.name == 'Worksheet'}\n    saveas = sh.ole_methods.find {|m| m.name == 'SaveAs'}\n    param_names = saveas.params.collect{|p| p.name}\n    assert(param_names.size > 0)\n    assert(param_names.include?('Filename'))\n  end\n  def test_to_s\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    sh = classes.find {|c| c.name == 'Worksheet'}\n    saveas = sh.ole_methods.find {|m| m.name == 'SaveAs'}\n    param_names = saveas.params.collect{|p| \"#{p}\"}\n    assert(param_names.include?('Filename'))\n  end\n  def test_ole_type\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    methods = classes.find {|c| c.name == 'Worksheet'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert_equal('BSTR', f.params[0].ole_type)\n    methods = classes.find {|c| c.name == 'Workbook'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert_equal('XlSaveAsAccessMode', f.params[6].ole_type)\n  end\n  def test_ole_type_detail\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    methods = classes.find {|c| c.name == 'Worksheet'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert_equal(['BSTR'], f.params[0].ole_type_detail)\n    methods = classes.find {|c| c.name == 'Workbook'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert_equal(['USERDEFINED', 'XlSaveAsAccessMode'], f.params[6].ole_type_detail)\n  end\n  def test_input\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    methods = classes.find {|c| c.name == 'Worksheet'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert(f.params[0].input?)\n  end\n  \n  def test_output\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    methods = classes.find {|c| c.name == 'Worksheet'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert(!f.params[0].output?)\n  end\n  def test_optional\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    methods = classes.find {|c| c.name == 'Worksheet'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert(!f.params[0].optional?)\n    methods = classes.find {|c| c.name == 'Workbook'}.ole_methods\n    f = methods.find {|m| m.name == 'SaveAs'}\n    assert(f.params[0].optional?)\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/testOLETYPE.rb",
    "content": "# You need RubyUnit and MS Excel and MSI to run this test script \n\nrequire 'rubyunit'\n\nrequire 'win32ole'\nrequire 'oleserver'\n\nclass TestOLETYPE < RUNIT::TestCase\n  include OLESERVER\n  def test_s_new\n    type = WIN32OLE_TYPE.new(MS_EXCEL_TYPELIB, 'Application')\n    assert_instance_of(WIN32OLE_TYPE, type)\n  end\n  def test_s_ole_classes\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    assert(classes.size > 0)\n  end\n  def test_s_typelibs\n    libs = WIN32OLE_TYPE.typelibs\n    assert(libs.include?(MS_EXCEL_TYPELIB))\n    assert(libs.include?(MS_XML_TYPELIB))\n  end\n  def test_s_progids\n    progids = WIN32OLE_TYPE.progids\n    assert(progids.include?('Excel.Application'))\n  end\n  def test_name\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    class_names = classes.collect{|c|\n      c.name\n    }\n    assert(class_names.include?('Application'))\n  end\n\n  def test_class_to_s\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    class_names = classes.collect{|c|\n      \"#{c}\"\n    }\n    assert(class_names.include?('Application'))\n  end\n\n  def test_ole_type\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    app = classes.find {|c| c.name == 'Application'}\n    assert_equal('Class', app.ole_type)\n    app = classes.find {|c| c.name == '_Application'}\n    assert_equal('Dispatch', app.ole_type)\n  end\n  def test_typekind\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    app = classes.find {|c| c.name == 'Application'}\n    assert_equal(5, app.typekind)\n  end\n  def test_visible\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    app = classes.find {|c| c.name == 'Application'}\n    assert(app.visible?)\n    app = classes.find {|c| c.name == 'IAppEvents'}\n    assert(!app.visible?)\n  end\n  def test_src_type\n    classes = WIN32OLE_TYPE.ole_classes(MS_XML_TYPELIB)\n    domnode = classes.find {|c| c.name == 'DOMNodeType'}\n    assert_equal('tagDOMNodeType', domnode.src_type)\n  end\n  def test_helpstring\n    classes = WIN32OLE_TYPE.ole_classes(MS_XML_TYPELIB)\n    domdoc = classes.find {|c| c.name == 'DOMDocument'}\n    assert_equal('W3C-DOM XML Document', domdoc.helpstring)\n  end\n  def test_variables\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    xlchart = classes.find {|c| c.name == 'XlChartType'}\n    assert(xlchart.variables.size > 0)\n  end\n  def test_ole_methods\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    worksheet = classes.find {|c| c.name == 'Worksheet'}\n    assert(worksheet.ole_methods.size > 0)\n  end\n  def test_helpfile\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    worksheet = classes.find {|c| c.name == 'Worksheet'}\n    assert_match(/VBAXL.*\\.(CHM|HLP)$/, worksheet.helpfile)\n  end\n  def test_helpcontext\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    worksheet = classes.find {|c| c.name == 'Worksheet'}\n    assert_equal(131088, worksheet.helpcontext)\n  end\n  def test_to_s\n    type = WIN32OLE_TYPE.new(MS_EXCEL_TYPELIB, 'Application')\n    assert_equal(\"Application\", \"#{type}\");\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/testOLEVARIABLE.rb",
    "content": "# You need RubyUnit and MS Excel and MSI to run this test script \n\nrequire 'rubyunit'\n\nrequire 'win32ole'\nrequire 'oleserver'\n\nclass TestOLEVARIABLE < RUNIT::TestCase\n  include OLESERVER\n  def test_name\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    chart = classes.find {|c| c.name == 'XlChartType'}\n    var_names = chart.variables.collect {|m| m.name}\n    assert(var_names.size > 0)\n    assert(var_names.include?('xl3DColumn'))\n  end\n  def test_to_s\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    chart = classes.find {|c| c.name == 'XlChartType'}\n    var_names = chart.variables.collect {|m| \"#{m}\"}\n    assert(var_names.size > 0)\n    assert(var_names.include?('xl3DColumn'))\n  end\n  def test_ole_type\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    chart = classes.find {|c| c.name == 'XlChartType'}\n    var = chart.variables.find {|m| m.name == 'xl3DColumn'}\n    assert_equal('INT', var.ole_type)\n  end\n  def test_ole_type_detail\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    chart = classes.find {|c| c.name == 'XlChartType'}\n    var = chart.variables.find {|m| m.name == 'xl3DColumn'}\n    assert_equal(['INT'], var.ole_type_detail)\n  end\n\n  def test_value\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    chart = classes.find {|c| c.name == 'XlChartType'}\n    var = chart.variables.find {|m| m.name == 'xl3DColumn'}\n    assert_equal(-4100, var.value)\n  end\n  def test_visible\n    classes = WIN32OLE_TYPE.ole_classes(MS_EXCEL_TYPELIB)\n    chart = classes.find {|c| c.name == 'XlChartType'}\n    var = chart.variables.find {|m| m.name == 'xl3DColumn'}\n    assert(var.visible?)\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/testVARIANT.rb",
    "content": "# You need RubyUnit and MS Excel and MSI to run this test script \n\nrequire 'rubyunit'\n\nrequire 'win32ole'\n\nclass TestWin32OLE_VARIANT < RUNIT::TestCase\n  include WIN32OLE::VARIANT\n  def test_variant\n    assert_equal(2, VT_I2)\n    assert_equal(3, VT_I4)\n    assert_equal(4, VT_R4)\n    assert_equal(5, VT_R8)\n    assert_equal(6, VT_CY)\n    assert_equal(7, VT_DATE)\n    assert_equal(8, VT_BSTR)\n    assert_equal(9, VT_DISPATCH)\n    assert_equal(10, VT_ERROR)\n    assert_equal(11, VT_BOOL)\n    assert_equal(12, VT_VARIANT)\n    assert_equal(13, VT_UNKNOWN)\n    assert_equal(16, VT_I1)\n    assert_equal(17, VT_UI1)\n    assert_equal(18, VT_UI2)\n    assert_equal(19, VT_UI4)\n    assert_equal(22, VT_INT)\n    assert_equal(23, VT_UINT)\n    assert_equal(0x2000, VT_ARRAY)\n    assert_equal(0x4000, VT_BYREF)\n  end\nend\n\n"
  },
  {
    "path": "ext/win32ole/tests/testWIN32OLE.rb",
    "content": "# You need RubyUnit and MS Excel and MSI to run this test script \n\nrequire 'runit/testcase'\nrequire 'runit/cui/testrunner'\n\nrequire 'win32ole'\nrequire 'oleserver'\n\nmodule EXCEL_CONST\nend\n\nmodule CONST1\nend\n\nmodule CONST2\nend\n\nmodule CONST3\nend\n\nclass TestWin32OLE < RUNIT::TestCase\n  include OLESERVER\n  def setup\n    @excel = WIN32OLE.new(\"Excel.Application\")\n    @excel.visible = true\n  end\n  def test_s_new\n    assert_instance_of(WIN32OLE, @excel)\n  end\n  def test_s_new_DCOM\n    rexcel = WIN32OLE.new(\"Excel.Application\", \"localhost\")\n    assert_instance_of(WIN32OLE, rexcel)\n    rexcel.visible = true\n    rexcel.quit\n  end\n  def test_s_new_from_clsid\n    excel = WIN32OLE.new(\"{00024500-0000-0000-C000-000000000046}\")\n    assert_instance_of(WIN32OLE, excel)\n    excel.quit\n    exc = assert_exception(WIN32OLERuntimeError) {\n      WIN32OLE.new(\"{000}\")\n    }\n    assert_match(/unknown OLE server: `\\{000\\}'/, exc.message)\n  end\n  def test_s_connect\n    excel2 = WIN32OLE.connect('Excel.Application')\n    assert_instance_of(WIN32OLE, excel2)\n  end\n\n  def test_s_const_load\n    assert(!defined?(EXCEL_CONST::XlTop))\n    WIN32OLE.const_load(@excel, EXCEL_CONST)\n    assert_equal(-4160, EXCEL_CONST::XlTop)\n\n    assert(!defined?(CONST1::XlTop))\n    WIN32OLE.const_load(MS_EXCEL_TYPELIB, CONST1)\n    assert_equal(-4160, CONST1::XlTop)\n  end\n\n  def test_s_codepage\n    assert_equal(WIN32OLE::CP_ACP, WIN32OLE.codepage)\n  end\n\n  def test_s_codepage_set\n    WIN32OLE.codepage = WIN32OLE::CP_UTF8\n    assert_equal(WIN32OLE::CP_UTF8, WIN32OLE.codepage)\n    WIN32OLE.codepage = WIN32OLE::CP_ACP\n  end\n\n  def test_const_CP_ACP\n    assert_equal(0, WIN32OLE::CP_ACP)\n  end\n\n  def test_const_CP_OEMCP\n    assert_equal(1, WIN32OLE::CP_OEMCP)\n  end\n\n  def test_const_CP_MACCP\n    assert_equal(2, WIN32OLE::CP_MACCP)\n  end\n\n  def test_const_CP_THREAD_ACP\n    assert_equal(3, WIN32OLE::CP_THREAD_ACP)\n  end\n\n  def test_const_CP_SYMBOL\n    assert_equal(42, WIN32OLE::CP_SYMBOL)\n  end\n\n  def test_const_CP_UTF7\n    assert_equal(65000, WIN32OLE::CP_UTF7)\n  end\n\n  def test_const_CP_UTF8\n    assert_equal(65001, WIN32OLE::CP_UTF8)\n  end\n\n  def test_s_codepage_changed\n    book = @excel.workbooks.add\n    sheet = book.worksheets(1)\n    begin\n      WIN32OLE.codepage = WIN32OLE::CP_UTF8\n      sheet.range(\"A1\").value = [0x3042].pack(\"U*\")\n      val = sheet.range(\"A1\").value\n      assert_equal(\"\\343\\201\\202\", val)\n      WIN32OLE.codepage = WIN32OLE::CP_ACP\n      val = sheet.range(\"A1\").value\n      assert_equal(\"\\202\\240\", val)\n    ensure\n      book.saved = true\n    end\n  end\n\n  def test_get_win32ole_object\n    workbooks = @excel.Workbooks;\n    assert_instance_of(WIN32OLE, workbooks)\n  end\n  def test_each\n    workbooks = @excel.Workbooks\n    assert_no_exception {\n      i = 0;\n      workbooks.each do |workbook|\n        print i += 1\n      end\n    }\n    workbooks.add\n    workbooks.add\n    i = 0\n    workbooks.each do |workbook|\n      i+=1\n    end\n    assert_equal(2, i)\n    workbooks.each do |workbook|\n      workbook.saved = true\n    end\n  end\n  def test_setproperty_bracket\n    book = @excel.workbooks.add\n    sheet = book.worksheets(1)\n    begin\n      sheet.range(\"A1\")['Value'] = 10\n      assert_equal(10, sheet.range(\"A1\").value)\n      sheet['Cells', 1, 2] = 10\n      assert_equal(10, sheet.range(\"B1\").value)\n      assert_equal(10, sheet['Cells', 1, 2].value)\n    ensure\n      book.saved = true\n    end\n  end\n  def test_convert_bignum\n    book = @excel.workbooks.add\n    sheet = book.worksheets(1)\n    begin\n      sheet.range(\"A1\").value = 999999999\n      sheet.range(\"A2\").value = 9999999999\n      sheet.range(\"A3\").value = \"=A1*10 + 9\"\n      assert_equal(9999999999, sheet.range(\"A2\").value)\n      assert_equal(9999999999, sheet.range(\"A3\").value)\n      sheet.range(\"A4\").value = \"2008/03/04\"\n      assert_equal(\"2008/03/04 00:00:00\", sheet.range(\"A4\").value)\n    ensure\n      book.saved = true\n    end\n  end\n\n  def test_ole_invoke_with_named_arg\n    book = @excel.workbooks.add\n    sheets = book.worksheets\n    sheet = book.worksheets(1)\n    num = sheets.count\n    begin\n      sheets.add({'count' => 2, 'after'=>sheet})\n      assert_equal(2, sheets.count - num);\n    ensure\n      book.saved = true\n    end\n  end\n\n  def test_ole_invoke_with_named_arg_last\n    book = @excel.workbooks.add\n    sheets = book.worksheets\n    sheet = book.worksheets(1)\n    num = sheets.count\n    begin\n      sheets.add(sheet, {'count' => 2})\n      assert_equal(2, sheets.count - num);\n    ensure\n      book.saved = true\n    end\n  end\n\n  def test_setproperty\n    @excel.setproperty('Visible', false)\n    assert_equal(false, @excel.Visible)\n    @excel.setproperty('Visible', true)\n    assert_equal(true, @excel.Visible)\n    book = @excel.workbooks.add\n    sheet = book.worksheets(1)\n    begin\n      sheet.setproperty('Cells', 1, 2, 10)\n      assert_equal(10, sheet.range(\"B1\").value)\n    ensure\n      book.saved = true\n    end\n  end\n  def test_no_exist_property\n    isok = false\n    begin\n      @excel.unknown_prop = 1\n    rescue WIN32OLERuntimeError\n      isok = true\n    end\n    assert(isok)\n\n    isok = false\n    begin\n      @excel['unknown_prop'] = 2\n    rescue WIN32OLERuntimeError\n      isok = true\n    end\n    assert(isok)\n  end\n\n  def test_setproperty_with_equal\n    book = @excel.workbooks.add\n    sheet = book.worksheets(1)\n    begin\n      sheet.range(\"B1\").value = 10\n      assert_equal(10, sheet.range(\"B1\").value)\n      sheet.range(\"C1:D1\").value = [11, 12]\n      assert_equal(11, sheet.range(\"C1\").value)\n      assert_equal(12, sheet.range(\"D1\").value)\n    ensure\n      book.saved = true\n    end\n  end\n  def test_invoke\n    workbooks = @excel.invoke( 'workbooks' )\n    assert_instance_of(WIN32OLE, workbooks)\n    book = workbooks.invoke( 'add' )\n    assert_instance_of(WIN32OLE, book)\n  end\n  def test_ole_methods\n    methods = @excel.ole_methods\n    method_names = methods.collect{|m| m.name}\n    assert(method_names.include?(\"Quit\"))\n  end\n  def test_ole_func_methods\n    methods = @excel.ole_func_methods\n    assert(methods.size > 0)\n    method_names = methods.collect{|m| m.name}\n    assert(method_names.include?(\"Quit\"))\n  end\n  def test_ole_put_methods\n    methods = @excel.ole_put_methods\n    assert(methods.size > 0)\n    method_names = methods.collect{|m| m.name}\n    assert(method_names.include?(\"Visible\"))\n  end\n  def test_ole_get_methods\n    methods = @excel.ole_get_methods\n    assert(methods.size > 0)\n    method_names = methods.collect{|m| m.name}\n    assert(method_names.include?(\"Visible\"))\n  end\n  def test_ole_method_help\n    quit_info = @excel.ole_method_help(\"Quit\")\n    assert_equal(0, quit_info.size_params)\n    assert_equal(0, quit_info.size_opt_params)\n\n    workbooks = @excel.Workbooks\n    add_info = workbooks.ole_method_help(\"Add\")\n    assert_equal(1, add_info.size_params)\n    assert_equal(1, add_info.size_opt_params)\n    assert(add_info.params[0].input?)\n    assert(add_info.params[0].optional?)\n    assert_equal('VARIANT', add_info.params[0].ole_type)\n  end\n  def teardown\n    @excel.quit\n    @excel = nil\n    GC.start\n  end\nend\n\nclass TestWin32OLE_WITH_MSI < RUNIT::TestCase\n  def setup\n    installer = WIN32OLE.new(\"WindowsInstaller.Installer\")\n    @record = installer.CreateRecord(2)\n  end\n\n  # Sorry, this test fails. \n  # Win32OLE does not support this style to set property.\n  # Use Win32OLE#setproperty or Win32OLE#[]= .\n  # def test_invoke\n  #   @record.invoke(\"StringData\", 1, 'cccc')\n  #   assert_equal('cccc', @record.StringData(1))\n  # end\n\n  def test_setproperty\n    @record.setproperty( \"StringData\", 1, 'dddd')\n    assert_equal('dddd', @record.StringData(1))\n  end\n  def test_bracket_equal_with_arg\n    @record[ \"StringData\", 1 ] =  'ffff'\n    assert_equal('ffff', @record.StringData(1))\n  end\n\n  def test__invoke\n    shell=WIN32OLE.new('Shell.Application')\n    assert_equal(shell.NameSpace(0).title, shell._invoke(0x60020002, [0], [WIN32OLE::VARIANT::VT_VARIANT]).title)\n  end\nend\n\n# ---------------------\n#\n# a subclass of Win32OLE\n# override new() and connect()\nclass MyExcel<WIN32OLE\n    def MyExcel.new \n        super \"Excel.Application\"\n    end\n    def MyExcel.connect\n        super \"Excel.Application\"\n    end\nend\n\nclass TestMyExcel < TestWin32OLE\n#\n# because we overrided new() and connect()\n# we need to change the test.\n# also, because the class will be different\n# \n  def setup\n    @excel = MyExcel.new\n    @excel.visible = true\n  end\n  def test_s_new\n    assert_instance_of(MyExcel, @excel)\n  end\n  def test_s_connect\n    excel2 = MyExcel.connect\n    assert_instance_of(MyExcel, excel2)\n  end\n#\n# const_load didn't like to be called twice,\n# and I don't know how to undefine something in Ruby yet \n# so, hide the test.\n#\n  private :test_s_const_load\nend\n\nif $0 == __FILE__\n  puts \"Now Test Win32OLE version #{WIN32OLE::VERSION}\"\n  if ARGV.size == 0\n\tsuite = RUNIT::TestSuite.new\n\tsuite.add_test(TestWin32OLE.suite)\n\tsuite.add_test(TestMyExcel.suite)\n    begin\n      installer = WIN32OLE.new(\"WindowsInstaller.Installer\")\n      suite.add_test(TestWin32OLE_WITH_MSI.suite)\n    rescue\n      puts \"Skip some test with MSI\"\n    end\n  else\n    suite = RUNIT::TestSuite.new\n    ARGV.each do |testmethod|\n      suite.add_test(TestWin32OLE.new(testmethod))\n    end\n  end\n  RUNIT::CUI::TestRunner.quiet_mode = true\n  RUNIT::CUI::TestRunner.run(suite)\nend\n"
  },
  {
    "path": "ext/win32ole/tests/test_ole_methods.rb",
    "content": "#\n# This is test for [ruby-talk:196897]\n#\nbegin\n  require 'win32ole'\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(WIN32OLE)\n  class TestWIN32OLE_FOR_PROPERTYPUTREF < Test::Unit::TestCase\n    \n    def setup\n      @obj = WIN32OLE.new('Scripting.Dictionary')\n    end\n\n    def test_ole_methods\n      x = @obj.ole_methods.select {|m|\n        m.invoke_kind == 'PROPERTYPUTREF'\n      }\n      assert(x.size > 0)\n      assert_equal(1, x.size)\n      assert_equal('Item', x[0].name)\n    end\n\n    def test_ole_put_methods\n      x = @obj.ole_put_methods.select {|m|\n        m.invoke_kind == 'PROPERTYPUTREF'\n      }\n      assert(x.size > 0)\n      assert_equal(1, x.size)\n      assert_equal('Item', x[0].name)\n    end\n\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/test_propertyputref.rb",
    "content": "require 'test/unit'\nrequire 'win32ole'\n\nclass TestWIN32OLE_PROPERTYPUTREF < Test::Unit::TestCase\n  def setup\n    begin\n      @sapi = WIN32OLE.new('SAPI.SpVoice')\n    rescue WIN32OLERuntimeError\n      @sapi = nil\n    end\n  end\n  def test_sapi\n    if @sapi\n      new_id = @sapi.getvoices.item(2).Id\n      @sapi.voice = @sapi.getvoices.item(2)\n      assert_equal(new_id, @sapi.voice.Id)\n    end\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/test_win32ole_event.rb",
    "content": "begin\n  require 'win32ole'\nrescue LoadError\nend\nrequire 'test/unit'\n\nif defined?(WIN32OLE_EVENT)\n  class TestWIN32OLE_EVENT < Test::Unit::TestCase\n    def create_temp_html\n      fso = WIN32OLE.new('Scripting.FileSystemObject')\n      dummy_file = fso.GetTempName + \".html\"\n      cfolder = fso.getFolder(\".\")\n      f = cfolder.CreateTextFile(dummy_file)\n      f.writeLine(\"<html><body>This is test HTML file for Win32OLE.</body></html>\")\n      f.close\n      dummy_path = cfolder.path + \"\\\\\" + dummy_file\n      dummy_path\n    end\n\n    def setup\n      @ie = WIN32OLE.new(\"InternetExplorer.Application\")\n      @ie.visible = true\n      @event = \"\"\n      @event2 = \"\"\n      @event3 = \"\"\n      @f = create_temp_html\n    end\n\n    def default_handler(event, *args)\n      @event += event\n    end\n\n    def test_on_event\n      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')\n      ev.on_event {|*args| default_handler(*args)}\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents') \n        GC.start  \n        sleep 0.1\n      end\n      assert_match(/BeforeNavigate/, @event)\n      assert_match(/NavigateComplete/, @event)\n    end\n\n    def test_on_event2\n      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')\n      ev.on_event('BeforeNavigate') {|*args| handler1}\n      ev.on_event('BeforeNavigate') {|*args| handler2}\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        sleep 0.1\n      end\n      assert_equal(\"handler2\", @event2)\n    end\n\n    def test_on_event3\n      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')\n      ev.on_event {|*args| handler1}\n      ev.on_event {|*args| handler2}\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        sleep 0.1\n      end\n      assert_equal(\"handler2\", @event2)\n    end\n\n    def test_on_event4\n      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')\n      ev.on_event{|*args| handler1}\n      ev.on_event{|*args| handler2}\n      ev.on_event('NavigateComplete'){|*args| handler3(*args)}\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        sleep 0.1\n      end\n      assert(@event3!=\"\")\n      assert(\"handler2\", @event2)\n    end\n\n    def test_on_event5\n      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')\n      ev.on_event {|*args| default_handler(*args)}\n      ev.on_event('NavigateComplete'){|*args| handler3(*args)}\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        sleep 0.1\n      end\n      assert_match(/BeforeNavigate/, @event)\n      assert(/NavigateComplete/ !~ @event)\n      assert(@event!=\"\")\n    end\n\n    def test_unadvise\n      ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')\n      ev.on_event {|*args| default_handler(*args)}\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        sleep 0.1\n      end\n      assert_match(/BeforeNavigate/, @event)\n      ev.unadvise\n      @event = \"\"\n      @ie.navigate(\"file:///#{@f}\")\n      while @ie.busy\n        sleep 0.1\n      end\n      assert_equal(\"\", @event);\n      assert_raise(WIN32OLERuntimeError) {\n        ev.on_event {|*args| default_handler(*args)}\n      }\n    end\n\n    def handler1\n      @event2 = \"handler1\"\n    end\n\n    def handler2\n      @event2 = \"handler2\"\n    end\n\n    def handler3(url)\n      @event3 += url\n    end\n\n    def teardown\n      @ie.quit\n      @ie = nil\n      File.unlink(@f)\n      GC.start\n    end\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/test_word.rb",
    "content": "#\n# This is test for [ruby-Bugs#3237]\n#\nbegin\n  require 'win32ole'\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(WIN32OLE)\n  class TestWIN32OLE_WITH_WORD < Test::Unit::TestCase\n    \n    def setup\n      begin\n        @obj = WIN32OLE.new('Word.Application')\n      rescue WIN32OLERuntimeError\n        @obj = nil\n      end\n    end\n\n    def test_ole_methods\n      if @obj\n        @obj.visible = true\n        @obj.wordbasic.disableAutoMacros(true)\n        assert(true)\n      end\n    end\n\n    def teardown\n      if @obj\n        @obj.quit\n        @obj = nil\n      end\n    end\n\n  end\nend\n"
  },
  {
    "path": "ext/win32ole/tests/testall.rb",
    "content": "require 'rubyunit'\nrequire 'win32ole'\nputs \"Now Test Win32OLE version #{WIN32OLE::VERSION}\"\n# RUNIT::CUI::TestRunner.quiet_mode = true\nrequire \"testWIN32OLE\"\nrequire \"testOLETYPE\"\nrequire \"testOLEPARAM\"\nrequire \"testOLEMETHOD\"\nrequire \"testOLEVARIABLE\"\nrequire \"testVARIANT\"\nrequire \"testNIL2VTEMPTY\"\nrequire \"test_ole_methods.rb\"\nrequire \"test_propertyputref.rb\"\nrequire \"test_word.rb\"\nrequire \"test_win32ole_event.rb\"\n# require \"testOLEEVENT\"\n"
  },
  {
    "path": "ext/win32ole/win32ole.c",
    "content": "/*\n *  (c) 1995 Microsoft Corporation. All rights reserved.\n *  Developed by ActiveWare Internet Corp., http://www.ActiveWare.com\n *\n *  Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy\n *  <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>\n *\n *  You may distribute under the terms of either the GNU General Public\n *  License or the Artistic License, as specified in the README file\n *  of the Perl distribution.\n *\n */\n\n/*\n  $Date$\n  modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp>\n */\n\n#include \"ruby.h\"\n#include \"st.h\"\n#include <windows.h>\n#include <ocidl.h>\n#include <olectl.h>\n#include <ole2.h>\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n#include <objidl.h>\n\n#define DOUT fprintf(stderr,\"[%d]\\n\",__LINE__)\n#define DOUTS(x) fprintf(stderr,\"[%d]:\" #x \"=%s\\n\",__LINE__,x)\n#define DOUTMSG(x) fprintf(stderr, \"[%d]:\" #x \"\\n\",__LINE__)\n#define DOUTI(x) fprintf(stderr, \"[%ld]:\" #x \"=%d\\n\",__LINE__,x)\n#define DOUTD(x) fprintf(stderr, \"[%d]:\" #x \"=%f\\n\",__LINE__,x)\n\n#if defined NONAMELESSUNION && __GNUC__\n#define V_UNION1(X, Y) ((X)->u.Y)\n#else\n#define V_UNION1(X, Y) ((X)->Y)\n#endif\n\n#if defined NONAMELESSUNION && __GNUC__\n#undef V_UNION\n#define V_UNION(X,Y) ((X)->n1.n2.n3.Y)\n\n#undef V_VT\n#define V_VT(X) ((X)->n1.n2.vt)\n\n#undef V_BOOL\n#define V_BOOL(X) V_UNION(X,boolVal)\n#endif\n\n#define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0\n\n#define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0\n\n#define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y)))\n#define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y)))\n\n#define OLE_FREE(x) {\\\n    if(gOLEInitialized == Qtrue) {\\\n        if(x) {\\\n            OLE_RELEASE(x);\\\n            (x) = 0;\\\n        }\\\n    }\\\n}\n\n#define OLEData_Get_Struct(obj, pole) {\\\n    Data_Get_Struct(obj, struct oledata, pole);\\\n    if(!pole->pDispatch) {\\\n        rb_raise(rb_eRuntimeError, \"failed to get Dispatch Interface\");\\\n    }\\\n}\n\n#define WC2VSTR(x) ole_wc2vstr((x), TRUE)\n\n#define WIN32OLE_VERSION \"0.7.6\"\n\ntypedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)\n    (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);\n\ntypedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile,\n                                 UINT uCommand, DWORD dwData);\ntypedef struct {\n    struct IEventSinkVtbl * lpVtbl;\n} IEventSink, *PEVENTSINK;\n\ntypedef struct IEventSinkVtbl IEventSinkVtbl;\n\nstruct IEventSinkVtbl {\n    STDMETHOD(QueryInterface)(\n        PEVENTSINK,\n        REFIID,\n        LPVOID *);\n    STDMETHOD_(ULONG, AddRef)(PEVENTSINK);\n    STDMETHOD_(ULONG, Release)(PEVENTSINK);\n\n    STDMETHOD(GetTypeInfoCount)(\n        PEVENTSINK,\n        UINT *);\n    STDMETHOD(GetTypeInfo)(\n        PEVENTSINK,\n        UINT,\n        LCID,\n        ITypeInfo **);\n    STDMETHOD(GetIDsOfNames)(\n        PEVENTSINK,\n        REFIID,\n        OLECHAR **,\n        UINT,\n        LCID,\n        DISPID *);\n    STDMETHOD(Invoke)(\n        PEVENTSINK,\n        DISPID,\n        REFIID,\n        LCID,\n        WORD,\n        DISPPARAMS *,\n        VARIANT *,\n        EXCEPINFO *,\n        UINT *);\n};\n\ntypedef struct tagIEVENTSINKOBJ {\n    IEventSinkVtbl *lpVtbl;\n    DWORD m_cRef;\n    IID m_iid;\n    int m_event_id;\n    DWORD m_dwCookie;\n    IConnectionPoint *pConnectionPoint;\n    ITypeInfo *pTypeInfo;\n    int *ptr_freed;\n}IEVENTSINKOBJ, *PIEVENTSINKOBJ;\n\nVALUE cWIN32OLE;\nVALUE cWIN32OLE_TYPE;\nVALUE cWIN32OLE_VARIABLE;\nVALUE cWIN32OLE_METHOD;\nVALUE cWIN32OLE_PARAM;\nVALUE cWIN32OLE_EVENT;\nVALUE eWIN32OLE_RUNTIME_ERROR;\nVALUE mWIN32OLE_VARIANT;\n\nstatic VALUE ary_ole_event;\nstatic ID id_events;\nstatic BOOL gOLEInitialized = Qfalse;\nstatic HINSTANCE ghhctrl = NULL;\nstatic HINSTANCE gole32 = NULL;\nstatic FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;\nstatic VALUE com_hash;\nstatic IDispatchVtbl com_vtbl;\nstatic UINT  cWIN32OLE_cp = CP_ACP;\nstatic VARTYPE g_nil_to = VT_ERROR;\nstatic IMessageFilterVtbl message_filter;\nstatic IMessageFilter imessage_filter = { &message_filter };\nstatic IMessageFilter* previous_filter;\n\nstruct oledata {\n    IDispatch *pDispatch;\n};\n\nstruct oletypedata {\n    ITypeInfo *pTypeInfo;\n};\n\nstruct olemethoddata {\n    ITypeInfo *pOwnerTypeInfo;\n    ITypeInfo *pTypeInfo;\n    UINT index;\n};\n\nstruct olevariabledata {\n    ITypeInfo *pTypeInfo;\n    UINT index;\n};\n\nstruct oleparamdata {\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n    UINT index;\n};\n\nstruct oleeventdata {\n    IEVENTSINKOBJ *pEvent;\n    int freed;\n};\n\nstruct oleparam {\n    DISPPARAMS dp;\n    OLECHAR** pNamedArgs;\n};\n\nstatic VALUE folemethod_s_allocate _((VALUE));\nstatic VALUE olemethod_set_member _((VALUE, ITypeInfo *, ITypeInfo *, int, VALUE));\nstatic VALUE foletype_s_allocate _((VALUE));\nstatic VALUE oletype_set_member  _((VALUE, ITypeInfo *, VALUE));\nstatic VALUE olemethod_from_typeinfo _((VALUE, ITypeInfo *, VALUE));\nstatic HRESULT ole_docinfo_from_type _((ITypeInfo *, BSTR *, BSTR *, DWORD *, BSTR *));\nstatic char *ole_wc2mb(LPWSTR);\nstatic VALUE ole_variant2val(VARIANT*);\nstatic void ole_val2variant(VALUE, VARIANT*);\n  \nstatic HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(\n    IMessageFilter __RPC_FAR * This,\n    /* [in] */ REFIID riid,\n    /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)\n{\n    if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0\n        || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)\n    {\n        *ppvObject = &message_filter;\n        return S_OK;\n    }\n    return E_NOINTERFACE;\n}\n\nstatic ULONG (STDMETHODCALLTYPE mf_AddRef)( \n    IMessageFilter __RPC_FAR * This)\n{\n    return 1;\n}\n        \nstatic ULONG (STDMETHODCALLTYPE mf_Release)( \n    IMessageFilter __RPC_FAR * This)\n{\n    return 1;\n}\n\nstatic DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(\n    IMessageFilter __RPC_FAR * pThis,\n    DWORD dwCallType,      //Type of incoming call\n    HTASK threadIDCaller,  //Task handle calling this task\n    DWORD dwTickCount,     //Elapsed tick count\n    LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure\n    )\n{\n#ifdef DEBUG_MESSAGEFILTER\n    printf(\"incoming %08X, %08X, %d\\n\", dwCallType, threadIDCaller, dwTickCount);\n    fflush(stdout);\n#endif\n    switch (dwCallType)\n    {\n    case CALLTYPE_ASYNC:\n    case CALLTYPE_TOPLEVEL_CALLPENDING:\n    case CALLTYPE_ASYNC_CALLPENDING:\n        if (rb_during_gc()) {\n            return SERVERCALL_RETRYLATER;\n        }\n        break;\n    default:\n        break;\n    }\n    if (previous_filter) {\n        return previous_filter->lpVtbl->HandleInComingCall(previous_filter,\n                                                   dwCallType,\n                                                   threadIDCaller,\n                                                   dwTickCount,\n                                                   lpInterfaceInfo);\n    }\n    return SERVERCALL_ISHANDLED;\n}\n\nstatic DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(\n    IMessageFilter* pThis,\n    HTASK threadIDCallee,  //Server task handle\n    DWORD dwTickCount,     //Elapsed tick count\n    DWORD dwRejectType     //Returned rejection message\n    )\n{\n    if (previous_filter) {\n        return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,\n                                                  threadIDCallee,\n                                                  dwTickCount,\n                                                  dwRejectType);\n    }\n    return 1000;\n}\n\nstatic DWORD (STDMETHODCALLTYPE mf_MessagePending)(\n    IMessageFilter* pThis,\n    HTASK threadIDCallee,  //Called applications task handle\n    DWORD dwTickCount,     //Elapsed tick count\n    DWORD dwPendingType    //Call type\n    )\n{\n    if (rb_during_gc()) {\n        return PENDINGMSG_WAITNOPROCESS;\n    }\n    if (previous_filter) {\n        return previous_filter->lpVtbl->MessagePending(previous_filter,\n                                               threadIDCallee,\n                                               dwTickCount,\n                                               dwPendingType);\n    }\n    return PENDINGMSG_WAITNOPROCESS;\n}\n    \ntypedef struct _Win32OLEIDispatch\n{\n    IDispatch dispatch;\n    ULONG refcount;\n    VALUE obj;\n} Win32OLEIDispatch;\n\nstatic HRESULT ( STDMETHODCALLTYPE QueryInterface )( \n    IDispatch __RPC_FAR * This,\n    /* [in] */ REFIID riid,\n    /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)\n{\n    if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0\n        || MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0)\n    {\n        Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;\n        p->refcount++;\n        *ppvObject = This;\n        return S_OK;\n    }\n    return E_NOINTERFACE;\n}\n        \nstatic ULONG ( STDMETHODCALLTYPE AddRef )( \n    IDispatch __RPC_FAR * This)\n{\n    Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;\n    return ++(p->refcount);\n}\n        \nstatic ULONG ( STDMETHODCALLTYPE Release )( \n    IDispatch __RPC_FAR * This)\n{\n    Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;\n    ULONG u = --(p->refcount);\n    if (u == 0) {\n        st_data_t key = p->obj;\n        st_delete(DATA_PTR(com_hash), &key, 0);\n        free(p);\n    }\n    return u;\n}\n        \nstatic HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )( \n    IDispatch __RPC_FAR * This,\n    /* [out] */ UINT __RPC_FAR *pctinfo)\n{\n    return E_NOTIMPL;\n}\n        \nstatic HRESULT ( STDMETHODCALLTYPE GetTypeInfo )( \n    IDispatch __RPC_FAR * This,\n    /* [in] */ UINT iTInfo,\n    /* [in] */ LCID lcid,\n    /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)\n{\n    return E_NOTIMPL;\n}\n\n        \nstatic HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )( \n    IDispatch __RPC_FAR * This,\n    /* [in] */ REFIID riid,\n    /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,\n    /* [in] */ UINT cNames,\n    /* [in] */ LCID lcid,\n    /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)\n{\n    Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;\n    char* psz = ole_wc2mb(*rgszNames); // support only one method\n    *rgDispId = rb_intern(psz);\n    free(psz);\n    return S_OK;\n}\n        \nstatic /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )( \n    IDispatch __RPC_FAR * This,\n    /* [in] */ DISPID dispIdMember,\n    /* [in] */ REFIID riid,\n    /* [in] */ LCID lcid,\n    /* [in] */ WORD wFlags,\n    /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,\n    /* [out] */ VARIANT __RPC_FAR *pVarResult,\n    /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,\n    /* [out] */ UINT __RPC_FAR *puArgErr)\n{\n    VALUE v;\n    int i;\n    int args = pDispParams->cArgs;\n    Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;\n    VALUE* parg = ALLOCA_N(VALUE, args);\n    for (i = 0; i < args; i++) {\n        *(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]);\n    }\n    if (dispIdMember == DISPID_VALUE) {\n        if (wFlags == DISPATCH_METHOD) {\n            dispIdMember = rb_intern(\"call\");\n        } else if (wFlags & DISPATCH_PROPERTYGET) {\n            dispIdMember = rb_intern(\"value\");\n        }\n    }\n    v = rb_funcall2(p->obj, dispIdMember, args, parg);\n    ole_val2variant(v, pVarResult);\n    return S_OK;\n}\n\nstatic IDispatch*\nval2dispatch(val)\n    VALUE val;\n{\n    struct st_table *tbl = DATA_PTR(com_hash);\n    Win32OLEIDispatch* pdisp;\n    st_data_t data;\n\n    if (st_lookup(tbl, val, &data)) {\n        pdisp = (Win32OLEIDispatch *)(data & ~FIXNUM_FLAG);\n        pdisp->refcount++;\n    }\n    else {\n        pdisp = ALLOC(Win32OLEIDispatch);\n        pdisp->dispatch.lpVtbl = &com_vtbl;\n        pdisp->refcount = 1;\n        pdisp->obj = val;\n        st_insert(tbl, val, (VALUE)pdisp | FIXNUM_FLAG);\n    }\n    return &pdisp->dispatch;\n}\n\nstatic void\ntime2d(hh, mm, ss, pv)\n    int hh, mm, ss;\n    double *pv;\n{\n    *pv =  (hh * 60.0 * 60.0 + mm * 60.0 + ss) / 86400.0;\n}\n\nstatic void\nd2time(v, hh, mm, ss)\n    double v;\n    int *hh, *mm, *ss;\n{\n    double d_hh, d_mm, d_ss;\n    int    i_hh, i_mm, i_ss;\n\n    double d = v * 86400.0;\n\n    d_hh = d / 3600.0;\n    i_hh = (int)d_hh;\n\n    d = d - i_hh * 3600.0;\n\n    d_mm = d / 60.0;\n    i_mm = (int)d_mm;\n\n    d = d - i_mm * 60.0;\n\n    d_ss = d * 10.0 + 5;\n    \n    i_ss = (int)d_ss / 10;\n\n    if(i_ss == 60) {\n        i_mm += 1;\n        i_ss = 0;\n    }\n\n    if (i_mm == 60) {\n        i_hh += 1;\n        i_mm = 0;\n    }\n    if (i_hh == 24) {\n        i_hh = 0;\n    }\n    \n    *hh = i_hh;\n    *mm = i_mm;\n    *ss = i_ss;\n}\n\nstatic void\ncivil2jd(y, m, d, jd)\n    int y, m, d;\n    long *jd;\n{\n    long a, b;\n    if (m <= 2) {\n        y -= 1;\n        m += 12;\n    }\n    a = (long)(y / 100.0);\n    b = 2 - a + (long)(a / 4.0);\n    *jd = (long)(365.25 * (double)(y + 4716))\n         + (long)(30.6001 * (m + 1))\n         + d + b - 1524;\n}\n\nstatic void\njd2civil(day, yy, mm, dd)\n    long day;\n    int *yy, *mm, *dd;\n{\n    long x, a, b, c, d, e;\n    x = (long)(((double)day - 1867216.25) / 36524.25);\n    a = day + 1 + x - (long)(x / 4.0);\n    b = a + 1524;\n    c = (long)(((double)b -122.1) /365.25);\n    d = (long)(365.25 * c);\n    e = (long)((double)(b - d) / 30.6001);\n    *dd = b - d - (long)(30.6001 * e);\n    if (e <= 13) {\n        *mm = e - 1;\n        *yy = c - 4716;\n    }\n    else {\n        *mm = e - 13;\n        *yy = c - 4715;\n    }\n}\n\nstatic void\ndouble2time(v, y, m, d, hh, mm, ss)\n    double v;\n    int *y, *m, *d, *hh, *mm, *ss;\n{\n    long day;\n    double t;\n\n    day = (long)v;\n    t = v - day;\n    jd2civil(2415019 + day, y, m, d);\n\n    d2time(t, hh, mm, ss);\n}\n\nstatic double\ntime_object2date(tmobj)\n    VALUE tmobj;\n{\n    long y, m, d, hh, mm, ss;\n    long day;\n    double t;\n    y = FIX2INT(rb_funcall(tmobj, rb_intern(\"year\"), 0));\n    m = FIX2INT(rb_funcall(tmobj, rb_intern(\"month\"), 0));\n    d = FIX2INT(rb_funcall(tmobj, rb_intern(\"mday\"), 0));\n    hh = FIX2INT(rb_funcall(tmobj, rb_intern(\"hour\"), 0));\n    mm = FIX2INT(rb_funcall(tmobj, rb_intern(\"min\"), 0));\n    ss = FIX2INT(rb_funcall(tmobj, rb_intern(\"sec\"), 0));\n    civil2jd(y, m, d, &day);\n    time2d(hh, mm, ss, &t);\n    return t + day - 2415019;\n}\n\nstatic VALUE\ndate2time_str(date)\n    double date;\n{\n    int y, m, d, hh, mm, ss;\n    char szTime[40];\n    double2time(date, &y, &m, &d, &hh, &mm, &ss);\n    sprintf(szTime,\n            \"%4.4d/%02.2d/%02.2d %02.2d:%02.2d:%02.2d\",\n            y, m, d, hh, mm, ss);\n    return rb_str_new2(szTime);\n}\n\nstatic void ole_val2variant();\n\nstatic char *\nole_wc2mb(pw)\n    LPWSTR pw;\n{\n    int size;\n    LPSTR pm;\n    size = WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, NULL, 0, NULL, NULL);\n    if (size) {\n        pm = ALLOC_N(char, size + 1);    \n        WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, pm, size, NULL, NULL);\n        pm[size] = '\\0';\n    }\n    else {\n        pm = ALLOC_N(char, 1);\n        *pm = '\\0';\n    }\n    return pm;\n} \n\nstatic VALUE\nole_hresult2msg(hr)\n    HRESULT hr;\n{\n    VALUE msg = Qnil;\n    char *p_msg = NULL;\n    char *term = NULL;\n    DWORD dwCount;\n\n    char strhr[100];\n    sprintf(strhr, \"    HRESULT error code:0x%08lx\\n      \", hr);\n    msg = rb_str_new2(strhr);\n\n    dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |\n                            FORMAT_MESSAGE_FROM_SYSTEM |\n                            FORMAT_MESSAGE_IGNORE_INSERTS,\n                            NULL, hr, LOCALE_SYSTEM_DEFAULT,\n                            (LPTSTR)&p_msg, 0, NULL);\n    if (dwCount > 0) {\n\tterm = p_msg + strlen(p_msg);\n\twhile (p_msg < term) {\n\t    term--;\n\t    if (*term == '\\r' || *term == '\\n')\n\t        *term = '\\0';\n\t    else break;\n\t}\n        if (p_msg[0] != '\\0') {\n            rb_str_cat2(msg, p_msg);\n        }\n    }\n    LocalFree(p_msg);\n    return msg;\n}\n\nstatic void\nole_freeexceptinfo(pExInfo)\n    EXCEPINFO *pExInfo;\n{\n    SysFreeString(pExInfo->bstrDescription);\n    SysFreeString(pExInfo->bstrSource);\n    SysFreeString(pExInfo->bstrHelpFile);\n}\n\nstatic VALUE\nole_excepinfo2msg(pExInfo)\n    EXCEPINFO *pExInfo;\n{\n    char error_code[40];\n    char *pSource = NULL;\n    char *pDescription = NULL;\n    VALUE error_msg;\n    if(pExInfo->pfnDeferredFillIn != NULL) {\n        (*pExInfo->pfnDeferredFillIn)(pExInfo);\n    }\n    if (pExInfo->bstrSource != NULL) {\n        pSource = ole_wc2mb(pExInfo->bstrSource);\n    }\n    if (pExInfo->bstrDescription != NULL) {\n        pDescription = ole_wc2mb(pExInfo->bstrDescription);\n    }\n    if(pExInfo->wCode == 0) {\n        sprintf(error_code, \"\\n    OLE error code:%lX in \", pExInfo->scode);\n    }\n    else{\n        sprintf(error_code, \"\\n    OLE error code:%u in \", pExInfo->wCode);\n    }\n    error_msg = rb_str_new2(error_code);\n    if(pSource != NULL) {\n        rb_str_cat(error_msg, pSource, strlen(pSource));\n    }\n    else {\n        rb_str_cat(error_msg, \"<Unknown>\", 9);\n    }\n    rb_str_cat2(error_msg, \"\\n      \");\n    if(pDescription != NULL) {\n        rb_str_cat2(error_msg, pDescription);\n    }\n    else {\n        rb_str_cat2(error_msg, \"<No Description>\");\n    }\n    if(pSource) free(pSource);\n    if(pDescription) free(pDescription);\n    ole_freeexceptinfo(pExInfo);\n    return error_msg;\n}\n\nstatic void\n#ifdef HAVE_STDARG_PROTOTYPES\nole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...)\n#else\nole_raise(hr, exc, fmt, va_alist)\n    HRESULT hr;\n    VALUE exc;\n    const char *fmt;\n    va_dcl\n#endif\n{\n    va_list args;\n    char buf[BUFSIZ];\n    VALUE err_msg;\n    va_init_list(args, fmt);\n    vsnprintf(buf, BUFSIZ, fmt, args);\n    va_end(args);\n\n    err_msg = ole_hresult2msg(hr);\n    if(err_msg != Qnil) {\n        rb_raise(ecs, \"%s\\n%s\", buf, StringValuePtr(err_msg));\n    }\n    else {\n        rb_raise(ecs, \"%s\", buf);\n    }\n}\n\nvoid\nole_uninitialize()\n{\n    OleUninitialize();\n    gOLEInitialized = Qfalse;\n}\n\nstatic void\nole_initialize() \n{\n    HRESULT hr;\n    \n    if(gOLEInitialized == Qfalse) {\n        hr = OleInitialize(NULL);\n        if(FAILED(hr)) {\n            ole_raise(hr, rb_eRuntimeError, \"fail: OLE initialize\");\n        }\n        gOLEInitialized = Qtrue;\n        /*\n         * In some situation, OleUninitialize does not work fine. ;-<\n         */\n        /*\n        atexit((void (*)(void))ole_uninitialize);\n        */\n        hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);\n        if(FAILED(hr)) {\n            previous_filter = NULL;\n            ole_raise(hr, rb_eRuntimeError, \"fail: install OLE MessageFilter\");\n        }\n    }\n}\n\nstatic void\nole_msg_loop() {\n    MSG msg;\n    while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n}\n\nstatic void\nole_free(pole)\n    struct oledata *pole;\n{\n    OLE_FREE(pole->pDispatch);\n    free(pole);\n}\n\nstatic void\noletype_free(poletype)\n    struct oletypedata *poletype;\n{\n    OLE_FREE(poletype->pTypeInfo);\n    free(poletype);\n}\n\nstatic void\nolemethod_free(polemethod)\n    struct olemethoddata *polemethod;\n{\n    OLE_FREE(polemethod->pTypeInfo);\n    OLE_FREE(polemethod->pOwnerTypeInfo);\n    free(polemethod);\n}\n\nstatic void\nolevariable_free(polevar)\n    struct olevariabledata *polevar;\n{\n    OLE_FREE(polevar->pTypeInfo);\n    free(polevar);\n}\n\nstatic void\noleparam_free(pole)\n    struct oleparamdata *pole;\n{\n    OLE_FREE(pole->pTypeInfo);\n    free(pole);\n}\n\nstatic LPWSTR\nole_mb2wc(pm, len)\n    char *pm;\n    int  len;\n{\n    int size;\n    LPWSTR pw;\n    size = MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, NULL, 0);\n    pw = SysAllocStringLen(NULL, size - 1);\n    MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, pw, size);\n    return pw;\n}\n\nstatic VALUE\nole_wc2vstr(pw, isfree)\n    LPWSTR pw;\n    BOOL isfree;\n{\n    char *p = ole_wc2mb(pw);\n    VALUE vstr = rb_str_new2(p);\n    if(isfree)\n        SysFreeString(pw);\n    free(p);\n    return vstr;\n}\n\nstatic VALUE\nole_ary_m_entry(val, pid)\n    VALUE val;\n    long *pid;\n{\n    VALUE obj = Qnil;\n    int i = 0;\n    obj = val;\n    while(TYPE(obj) == T_ARRAY) {\n        obj = rb_ary_entry(obj, pid[i]);\n        i++;\n    }\n    return obj;\n}\n\nstatic void\nole_set_safe_array(n, psa, pid, pub, val, dim)\n    long n;\n    SAFEARRAY *psa;\n    long *pid;\n    long *pub;\n    VALUE val;\n    long dim;\n{\n    VALUE val1;\n    VARIANT var;\n    VariantInit(&var);\n    if(n < 0) return;\n    if(n == dim) {\n        val1 = ole_ary_m_entry(val, pid);\n        ole_val2variant(val1, &var);\n        SafeArrayPutElement(psa, pid, &var);\n    }\n    pid[n] += 1;\n    if (pid[n] < pub[n]) {\n        ole_set_safe_array(dim, psa, pid, pub, val, dim);\n    }\n    else {\n        pid[n] = 0;\n        ole_set_safe_array(n-1, psa, pid, pub, val, dim);\n    }\n}\n\nstatic void\nole_val2variant(val, var)\n    VALUE val;\n    VARIANT *var;\n{\n    struct oledata *pole;\n    if(rb_obj_is_kind_of(val, cWIN32OLE)) {\n        Data_Get_Struct(val, struct oledata, pole);\n        OLE_ADDREF(pole->pDispatch);\n        V_VT(var) = VT_DISPATCH;\n        V_DISPATCH(var) = pole->pDispatch;\n        return;\n    }\n    if (rb_obj_is_kind_of(val, rb_cTime)) {\n        V_VT(var) = VT_DATE;\n        V_DATE(var) = time_object2date(val);\n        return;\n    }\n    switch (TYPE(val)) {\n    case T_ARRAY:\n    {\n        VALUE val1;\n        long dim = 0;\n        int  i = 0;\n\n        HRESULT hr;\n        SAFEARRAYBOUND *psab;\n        SAFEARRAY *psa;\n        long      *pub, *pid;\n\n        val1 = val;\n        while(TYPE(val1) == T_ARRAY) {\n            val1 = rb_ary_entry(val1, 0);\n            dim += 1;\n        }\n        psab = ALLOC_N(SAFEARRAYBOUND, dim);\n        pub  = ALLOC_N(long, dim);\n        pid  = ALLOC_N(long, dim);\n\n        if(!psab || !pub || !pid) {\n            if(pub) free(pub);\n            if(psab) free(psab);\n            if(pid) free(pid);\n            rb_raise(rb_eRuntimeError, \"memory allocation error\");\n        }\n        val1 = val;\n        i = 0;\n        while(TYPE(val1) == T_ARRAY) {\n            psab[i].cElements = RARRAY(val1)->len;\n            psab[i].lLbound = 0;\n            pub[i] = psab[i].cElements;\n            pid[i] = 0;\n            i ++;\n            val1 = rb_ary_entry(val1, 0);\n        }\n        /* Create and fill VARIANT array */\n        psa = SafeArrayCreate(VT_VARIANT, dim, psab);\n        if (psa == NULL)\n            hr = E_OUTOFMEMORY;\n        else\n            hr = SafeArrayLock(psa);\n        if (SUCCEEDED(hr)) {\n            ole_set_safe_array(dim-1, psa, pid, pub, val, dim-1);\n            hr = SafeArrayUnlock(psa);\n        }\n        if(pub) free(pub);\n        if(psab) free(psab);\n        if(pid) free(pid);\n\n        if (SUCCEEDED(hr)) {\n            V_VT(var) = VT_VARIANT | VT_ARRAY;\n            V_ARRAY(var) = psa;\n        }\n        else if (psa != NULL)\n            SafeArrayDestroy(psa);\n        break;\n    }\n    case T_STRING:\n        V_VT(var) = VT_BSTR;\n        V_BSTR(var) = ole_mb2wc(StringValuePtr(val), -1);\n        break;\n    case T_FIXNUM:\n        V_VT(var) = VT_I4;\n        V_I4(var) = NUM2INT(val);\n        break;\n    case T_BIGNUM:\n        V_VT(var) = VT_R8;\n        V_R8(var) = rb_big2dbl(val);\n        break;\n    case T_FLOAT:\n        V_VT(var) = VT_R8;\n        V_R8(var) = NUM2DBL(val);\n        break;\n    case T_TRUE:\n        V_VT(var) = VT_BOOL;\n        V_BOOL(var) = VARIANT_TRUE;\n        break;\n    case T_FALSE:\n        V_VT(var) = VT_BOOL;\n        V_BOOL(var) = VARIANT_FALSE;\n        break;\n    case T_NIL:\n        if (g_nil_to == VT_ERROR) {\n            V_VT(var) = VT_ERROR;\n            V_ERROR(var) = DISP_E_PARAMNOTFOUND;\n        }else {\n            V_VT(var) = VT_EMPTY;\n        }\n        break;\n    default:\n        V_VT(var) = VT_DISPATCH;\n        V_DISPATCH(var) = val2dispatch(val);\n        break;\n    }\n}\n\nstatic void\nole_val2variant2(val, var)\n    VALUE val;\n    VARIANT *var;\n{\n    g_nil_to = VT_EMPTY;\n    ole_val2variant(val, var);\n    g_nil_to = VT_ERROR;\n}\n\nstatic VALUE\nole_set_member(self, dispatch)\n    VALUE self;\n    IDispatch * dispatch;\n{\n    struct oledata *pole;\n    Data_Get_Struct(self, struct oledata, pole);\n    if (pole->pDispatch) {\n        OLE_RELEASE(pole->pDispatch);\n        pole->pDispatch = NULL;\n    }\n    pole->pDispatch = dispatch;\n    return self;\n}\n\nstatic VALUE fole_s_allocate _((VALUE));\nstatic VALUE\nfole_s_allocate(klass)\n    VALUE klass;\n{\n    struct oledata *pole;\n    VALUE obj;\n    ole_initialize();\n    obj = Data_Make_Struct(klass,struct oledata,0,ole_free,pole);\n    pole->pDispatch = NULL;\n    return obj;\n}\n\nstatic VALUE\ncreate_win32ole_object(klass, pDispatch, argc, argv)\n    VALUE klass;\n    IDispatch *pDispatch;\n    int argc;\n    VALUE *argv;\n{\n    VALUE obj = fole_s_allocate(klass);\n    ole_set_member(obj, pDispatch);\n    return obj;\n}\n\nstatic VALUE\nole_variant2val(pvar)\n    VARIANT *pvar;\n{\n    VALUE obj = Qnil;\n    HRESULT hr;\n    while ( V_VT(pvar) == (VT_BYREF | VT_VARIANT) )\n        pvar = V_VARIANTREF(pvar);\n\n    if(V_ISARRAY(pvar)) {\n        SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);\n        long i;\n        long *pID, *pLB, *pUB;\n        VARIANT variant;\n        VALUE val;\n        VALUE val2;\n        int dim = 0;\n\n        if (!psa) {\n            return obj;\n        }\n        dim = SafeArrayGetDim(psa);\n\n        VariantInit(&variant);\n        V_VT(&variant) = (V_VT(pvar) & ~VT_ARRAY) | VT_BYREF;\n\n        pID = ALLOC_N(long, dim);\n        pLB = ALLOC_N(long, dim);\n        pUB = ALLOC_N(long, dim);\n\n        if(!pID || !pLB || !pUB) {\n            if(pID) free(pID);\n            if(pLB) free(pLB);\n            if(pUB) free(pUB);\n            rb_raise(rb_eRuntimeError, \"memory allocation error\");\n        }\n\n        obj = Qnil;\n\n        for(i = 0; i < dim; ++i) {\n            SafeArrayGetLBound(psa, i+1, &pLB[i]);\n            SafeArrayGetLBound(psa, i+1, &pID[i]);\n            SafeArrayGetUBound(psa, i+1, &pUB[i]);\n        }\n\n        hr = SafeArrayLock(psa);\n        if (SUCCEEDED(hr)) {\n            val2 = rb_ary_new();\n            while (i >= 0) {\n                hr = SafeArrayPtrOfIndex(psa, pID, &V_BYREF(&variant));\n                if (FAILED(hr))\n                    break;\n\n                val = ole_variant2val(&variant);\n                rb_ary_push(val2, val);\n                for (i = dim-1 ; i >= 0 ; --i) {\n                    if (++pID[i] <= pUB[i])\n                        break;\n\n                    pID[i] = pLB[i];\n                    if (i > 0) {\n                        if (obj == Qnil)\n                            obj = rb_ary_new();\n                        rb_ary_push(obj, val2);\n                        val2 = rb_ary_new();\n                    }\n                }\n            }\n            SafeArrayUnlock(psa);\n        }\n        if(pID) free(pID);\n        if(pLB) free(pLB);\n        if(pUB) free(pUB);\n        return (obj == Qnil) ? val2 : obj;\n    }\n    switch(V_VT(pvar) & ~VT_BYREF){\n    case VT_EMPTY:\n        break;\n    case VT_NULL:\n        break;\n    case VT_UI1:\n        if(V_ISBYREF(pvar)) \n            obj = INT2NUM((long)*V_UI1REF(pvar));\n        else \n            obj = INT2NUM((long)V_UI1(pvar));\n        break;\n\n    case VT_I2:\n        if(V_ISBYREF(pvar))\n            obj = INT2NUM((long)*V_I2REF(pvar));\n        else \n            obj = INT2NUM((long)V_I2(pvar));\n        break;\n\n    case VT_I4:\n        if(V_ISBYREF(pvar))\n            obj = INT2NUM((long)*V_I4REF(pvar));\n        else \n            obj = INT2NUM((long)V_I4(pvar));\n        break;\n\n    case VT_R4:\n        if(V_ISBYREF(pvar))\n            obj = rb_float_new(*V_R4REF(pvar));\n        else\n            obj = rb_float_new(V_R4(pvar));\n        break;\n\n    case VT_R8:\n        if(V_ISBYREF(pvar))\n            obj = rb_float_new(*V_R8REF(pvar));\n        else\n            obj = rb_float_new(V_R8(pvar));\n        break;\n\n    case VT_BSTR:\n    {\n        char *p;\n        if(V_ISBYREF(pvar))\n            p = ole_wc2mb(*V_BSTRREF(pvar));\n        else\n            p = ole_wc2mb(V_BSTR(pvar));\n        obj = rb_str_new2(p);\n        if(p) free(p);\n        break;\n    }\n\n    case VT_ERROR:\n        if(V_ISBYREF(pvar))\n            obj = INT2NUM(*V_ERRORREF(pvar));\n        else\n            obj = INT2NUM(V_ERROR(pvar));\n        break;\n\n    case VT_BOOL:\n        if (V_ISBYREF(pvar))\n            obj = (*V_BOOLREF(pvar) ? Qtrue : Qfalse);\n        else\n            obj = (V_BOOL(pvar) ? Qtrue : Qfalse);\n        break;\n\n    case VT_DISPATCH:\n    {\n        IDispatch *pDispatch;\n\n        if (V_ISBYREF(pvar))\n            pDispatch = *V_DISPATCHREF(pvar);\n        else\n            pDispatch = V_DISPATCH(pvar);\n\n        if (pDispatch != NULL ) {\n            OLE_ADDREF(pDispatch);\n            obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);\n        }\n        break;\n    }\n\n    case VT_UNKNOWN:\n    {\n\n        /* get IDispatch interface from IUnknown interface */\n        IUnknown *punk;\n        IDispatch *pDispatch;\n        HRESULT hr;\n\n        if (V_ISBYREF(pvar))\n            punk = *V_UNKNOWNREF(pvar);\n        else\n            punk = V_UNKNOWN(pvar);\n\n        if(punk != NULL) {\n           hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch,\n                                             (void **)&pDispatch);\n           if(SUCCEEDED(hr)) {\n               obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);\n           }\n        }\n        break;\n    }\n\n    case VT_DATE:\n    {\n        DATE date;\n        if(V_ISBYREF(pvar))\n            date = *V_DATEREF(pvar);\n        else\n            date = V_DATE(pvar);\n\n        obj =  date2time_str(date);\n        break;\n    }\n    case VT_CY:\n    default:\n        {\n        HRESULT hr;\n        VARIANT variant;\n        VariantInit(&variant);\n        hr = VariantChangeTypeEx(&variant, pvar, \n                                  LOCALE_SYSTEM_DEFAULT, 0, VT_BSTR);\n        if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {\n            char *p = ole_wc2mb(V_BSTR(&variant));\n            obj = rb_str_new2(p);\n            if(p) free(p);\n        }\n        VariantClear(&variant);\n        break;\n        }\n    }\n    return obj;\n}\n\n\nstatic LONG reg_open_key(hkey, name, phkey)\n    HKEY hkey;\n    const char *name;\n    HKEY *phkey;\n{\n    return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey);\n}\n\nstatic LONG reg_open_vkey(hkey, key, phkey)\n    HKEY hkey;\n    VALUE key;\n    HKEY *phkey;\n{\n    return reg_open_key(hkey, StringValuePtr(key), phkey);\n}\n\nstatic VALUE\nreg_enum_key(hkey, i)\n    HKEY hkey;\n    DWORD i;\n{\n    char buf[BUFSIZ + 1];\n    DWORD size_buf = sizeof(buf) - 1;\n    FILETIME ft;\n    LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,\n                            NULL, NULL, NULL, &ft);\n    if(err == ERROR_SUCCESS) {\n        buf[BUFSIZ] = '\\0';\n        return rb_str_new2(buf);\n    }\n    return Qnil;\n}\n\nstatic VALUE\nreg_get_val(hkey, subkey)\n    HKEY hkey;\n    const char *subkey;\n{\n    char buf[BUFSIZ + 1];\n    LONG size_buf = sizeof(buf) - 1;\n    LONG err = RegQueryValue(hkey, subkey, buf, &size_buf);\n    if (err == ERROR_SUCCESS) {\n        buf[BUFSIZ] = '\\0';\n        return rb_str_new2(buf);\n    }\n    return Qnil;\n}\n\nstatic VALUE\ntypelib_file_from_clsid(ole)\n    VALUE ole;\n{\n    OLECHAR *pbuf;\n    CLSID clsid;\n    HRESULT hr;\n    HKEY hroot, hclsid;\n    LONG err;\n    VALUE typelib;\n    VALUE vclsid;\n    char *pclsid = NULL;\n\n    pbuf  = ole_mb2wc(StringValuePtr(ole), -1);\n    hr = CLSIDFromProgID(pbuf, &clsid);\n    SysFreeString(pbuf);\n    if (FAILED(hr)) {\n        return Qnil;\n    }\n    StringFromCLSID(&clsid, &pbuf);\n    vclsid = WC2VSTR(pbuf);\n    err = reg_open_key(HKEY_CLASSES_ROOT, \"CLSID\", &hroot);\n    if (err != ERROR_SUCCESS) {\n        return Qnil;\n    }\n    err = reg_open_key(hroot, StringValuePtr(vclsid), &hclsid);\n    if (err != ERROR_SUCCESS) {\n        RegCloseKey(hroot);\n        return Qnil;\n    }\n    typelib = reg_get_val(hclsid, \"InprocServer32\");\n    RegCloseKey(hroot);\n    RegCloseKey(hclsid);\n    return typelib;\n}\n\nstatic VALUE\ntypelib_file_from_typelib(ole)\n    VALUE ole;\n{\n    HKEY htypelib, hclsid, hversion, hlang;\n    double fver;\n    DWORD i, j, k;\n    LONG err;\n    BOOL found = FALSE;\n    VALUE typelib;\n    VALUE file = Qnil;\n    VALUE clsid;\n    VALUE ver;\n    VALUE lang;\n\n    err = reg_open_key(HKEY_CLASSES_ROOT, \"TypeLib\", &htypelib);\n    if(err != ERROR_SUCCESS) {\n        return Qnil;\n    }\n    for(i = 0; !found; i++) {\n        clsid = reg_enum_key(htypelib, i);\n        if (clsid == Qnil)\n            break;\n        err = reg_open_vkey(htypelib, clsid, &hclsid);\n        if (err != ERROR_SUCCESS)\n            continue;\n        fver = 0;\n        for(j = 0; !found; j++) {\n            ver = reg_enum_key(hclsid, j);\n            if (ver == Qnil)\n                break;\n            err = reg_open_vkey(hclsid, ver, &hversion);\n            if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))\n                continue;\n            fver = atof(StringValuePtr(ver));\n            typelib = reg_get_val(hversion, NULL);\n            if (typelib == Qnil)\n                continue;\n            if (rb_str_cmp(typelib, ole) == 0) {\n                for(k = 0; !found; k++) {\n                    lang = reg_enum_key(hversion, k);\n                    if (lang == Qnil)\n                        break;\n                    err = reg_open_vkey(hversion, lang, &hlang);\n                    if (err == ERROR_SUCCESS) {\n                        if ((file = reg_get_val(hlang, \"win32\")) != Qnil) \n                            found = TRUE;\n                        RegCloseKey(hlang);\n                    }\n                }\n            }\n            RegCloseKey(hversion);\n        }\n        RegCloseKey(hclsid);\n    }\n    RegCloseKey(htypelib);\n    return  file;\n}\n\nstatic VALUE\ntypelib_file(ole)\n    VALUE ole;\n{\n    VALUE file = typelib_file_from_clsid(ole);\n    if (file != Qnil) {\n        return file;\n    }\n    return typelib_file_from_typelib(ole);\n}\n\nstatic void\nole_const_load(pTypeLib, klass, self)\n    ITypeLib *pTypeLib;\n    VALUE klass;\n    VALUE self;\n{\n    unsigned int count;\n    unsigned int index;\n    int iVar;\n    ITypeInfo *pTypeInfo;\n    TYPEATTR  *pTypeAttr;\n    VARDESC   *pVarDesc;\n    HRESULT hr;\n    unsigned int len;\n    BSTR bstr;\n    char *pName = NULL;\n    VALUE val;\n    VALUE constant;\n    ID id;\n    constant = rb_hash_new();\n    count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);\n    for (index = 0; index < count; index++) {\n        hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);\n        if (FAILED(hr))\n            continue;\n        hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n        if(FAILED(hr)) {\n            OLE_RELEASE(pTypeInfo);\n            continue;\n        }\n        for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {\n            hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);\n            if(FAILED(hr))\n                continue;\n            if(pVarDesc->varkind == VAR_CONST &&\n               !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |\n                                        VARFLAG_FRESTRICTED |\n                                        VARFLAG_FNONBROWSABLE))) {\n                hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,\n                                                 1, &len);\n                if(FAILED(hr) || len == 0 || !bstr)\n                    continue;\n                pName = ole_wc2mb(bstr);\n                val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));\n                *pName = toupper(*pName);\n                id = rb_intern(pName);\n                if (rb_is_const_id(id)) {\n                    rb_define_const(klass, pName, val);\n                }\n                else {\n                    rb_hash_aset(constant, rb_str_new2(pName), val);\n                }\n                SysFreeString(bstr);\n                if(pName) {\n                    free(pName);\n                    pName = NULL;\n                }\n            }\n            pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n        }\n        pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);\n        OLE_RELEASE(pTypeInfo);\n    }\n    rb_define_const(klass, \"CONSTANTS\", constant);\n}\n\nstatic HRESULT\nclsid_from_remote(host, com, pclsid)\n    VALUE host;\n    VALUE com;\n    CLSID *pclsid;\n{\n    HKEY hlm;\n    HKEY hpid;\n    VALUE subkey;\n    LONG err;\n    char clsid[100];\n    OLECHAR *pbuf;\n    DWORD len;\n    DWORD dwtype;\n    HRESULT hr = S_OK;\n    err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);\n    if (err != ERROR_SUCCESS)\n        return HRESULT_FROM_WIN32(err);\n    subkey = rb_str_new2(\"SOFTWARE\\\\Classes\\\\\");\n    rb_str_concat(subkey, com);\n    rb_str_cat2(subkey, \"\\\\CLSID\");\n    err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid);\n    if (err != ERROR_SUCCESS)\n        hr = HRESULT_FROM_WIN32(err);\n    else {\n        len = sizeof(clsid);\n        err = RegQueryValueEx(hpid, \"\", NULL, &dwtype, clsid, &len);\n        if (err == ERROR_SUCCESS && dwtype == REG_SZ) {\n            pbuf  = ole_mb2wc(clsid, -1);\n            hr = CLSIDFromString(pbuf, pclsid);\n            SysFreeString(pbuf);\n        }\n        else {\n            hr = HRESULT_FROM_WIN32(err);\n        }\n        RegCloseKey(hpid);\n    }\n    RegCloseKey(hlm);\n    return hr;\n}\n\nstatic VALUE\nole_create_dcom(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE ole, host, others;\n    HRESULT hr;\n    CLSID   clsid;\n    OLECHAR *pbuf;\n\n    COSERVERINFO serverinfo;\n    MULTI_QI multi_qi;\n    DWORD clsctx = CLSCTX_REMOTE_SERVER;\n\n    if (!gole32)\n        gole32 = LoadLibrary(\"OLE32\");\n    if (!gole32)\n        rb_raise(rb_eRuntimeError, \"failed to load OLE32\");\n    if (!gCoCreateInstanceEx)\n        gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)\n            GetProcAddress(gole32, \"CoCreateInstanceEx\");\n    if (!gCoCreateInstanceEx)\n        rb_raise(rb_eRuntimeError, \"CoCreateInstanceEx is not supported in this environment\");\n    rb_scan_args(argc, argv, \"2*\", &ole, &host, &others);\n\n    pbuf  = ole_mb2wc(StringValuePtr(ole), -1);\n    hr = CLSIDFromProgID(pbuf, &clsid);\n    if (FAILED(hr))\n        hr = clsid_from_remote(host, ole, &clsid);\n    if (FAILED(hr))\n        hr = CLSIDFromString(pbuf, &clsid);\n    SysFreeString(pbuf);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"unknown OLE server: `%s'\",\n                  StringValuePtr(ole));\n    memset(&serverinfo, 0, sizeof(COSERVERINFO));    \n    serverinfo.pwszName = ole_mb2wc(StringValuePtr(host), -1);\n    memset(&multi_qi, 0, sizeof(MULTI_QI));\n    multi_qi.pIID = &IID_IDispatch;\n    hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi);\n    SysFreeString(serverinfo.pwszName);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"failed to create DCOM server `%s' in `%s'\",\n                  StringValuePtr(ole),\n                  StringValuePtr(host));\n\n    ole_set_member(self, (IDispatch*)multi_qi.pItf);\n    return self;\n}\n\nstatic VALUE\nole_bind_obj(moniker, argc, argv, self)\n    VALUE moniker;\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    IBindCtx *pBindCtx;\n    IMoniker *pMoniker;\n    IDispatch *pDispatch;\n    HRESULT hr;\n    OLECHAR *pbuf;\n    ULONG eaten = 0;\n    \n    ole_initialize();\n\n    hr = CreateBindCtx(0, &pBindCtx);\n    if(FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"failed to create bind context\");\n    }\n\n    pbuf  = ole_mb2wc(StringValuePtr(moniker), -1);\n    hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);\n    SysFreeString(pbuf);\n    if(FAILED(hr)) {\n        OLE_RELEASE(pBindCtx);\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,\n                  \"failed to parse display name of moniker `%s'\",\n                  StringValuePtr(moniker));\n    }\n    hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL, \n                                        &IID_IDispatch,\n                                        (void**)&pDispatch);\n    OLE_RELEASE(pMoniker);\n    OLE_RELEASE(pBindCtx);\n\n    if(FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,\n                  \"failed to bind moniker `%s'\",\n                  StringValuePtr(moniker));\n    }\n    return create_win32ole_object(self, pDispatch, argc, argv);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE.connect( ole ) --> aWIN32OLE\n * \n *  Returns running OLE Automation object or WIN32OLE object from moniker.\n *  1st argument should be OLE program id or class id or moniker.\n *     \n *     WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.\n */\nstatic VALUE\nfole_s_connect(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE svr_name;\n    VALUE others;\n    HRESULT hr;\n    CLSID   clsid;\n    OLECHAR *pBuf;\n    IDispatch *pDispatch;\n    IUnknown *pUnknown;\n\n    rb_secure(4);\n    /* initialize to use OLE */\n    ole_initialize();\n\n    rb_scan_args(argc, argv, \"1*\", &svr_name, &others);\n    if (ruby_safe_level > 0 && OBJ_TAINTED(svr_name)) {\n        rb_raise(rb_eSecurityError, \"Insecure Object Connection - %s\",\n                 StringValuePtr(svr_name));\n    }\n\n    /* get CLSID from OLE server name */\n    pBuf  = ole_mb2wc(StringValuePtr(svr_name), -1);\n    hr = CLSIDFromProgID(pBuf, &clsid);\n    if(FAILED(hr)) {\n        hr = CLSIDFromString(pBuf, &clsid);\n    }\n    SysFreeString(pBuf);\n    if(FAILED(hr)) {\n        return ole_bind_obj(svr_name, argc, argv, self);\n    }\n\n    hr = GetActiveObject(&clsid, 0, &pUnknown);\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"OLE server `%s' not running\", StringValuePtr(svr_name));\n    }\n    hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch,\n                                             (void **)&pDispatch);\n    if(FAILED(hr)) {\n        OLE_RELEASE(pUnknown);\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"failed to create WIN32OLE server `%s'\", \n                  StringValuePtr(svr_name));\n    }\n\n    OLE_RELEASE(pUnknown);\n\n    return create_win32ole_object(self, pDispatch, argc, argv);\n}\n\n/* \n *  call-seq:\n *     WIN32OLE.const_load( ole, mod = WIN32OLE)\n * \n *  Defines the constants of OLE Automation server as mod's constants.\n *  The first argument is WIN32OLE object or type library name.\n *  If 2nd argument is omitted, the default is WIN32OLE.\n *  The first letter of Ruby's constant variable name is upper case,\n *  so constant variable name of WIN32OLE object is capitalized.\n *  For example, the 'xlTop' constant of Excel is changed to 'XlTop' \n *  in WIN32OLE.\n *  If the first letter of constant variabl is not [A-Z], then\n *  the constant is defined as CONSTANTS hash element.\n *\n *     module EXCEL_CONST\n *     end\n *     excel = WIN32OLE.new('Excel.Application')\n *     WIN32OLE.const_load(excel, EXCEL_CONST)\n *     puts EXCEL_CONST::XlTop # => -4160\n *     puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541\n *     \n *     WIN32OLE.const_load(excel)\n *     puts WIN32OLE::XlTop # => -4160\n *\n *     module MSO\n *     end\n *     WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)\n *     puts MSO::MsoLineSingle # => 1\n */\nstatic VALUE\nfole_s_const_load(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE ole;\n    VALUE klass;\n    struct oledata *pole;\n    ITypeInfo *pTypeInfo;\n    ITypeLib *pTypeLib;\n    unsigned int index;\n    HRESULT hr;\n    OLECHAR *pBuf;\n    VALUE file;\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n    \n    rb_secure(4);\n    rb_scan_args(argc, argv, \"11\", &ole, &klass);\n    if (TYPE(klass) != T_CLASS &&\n        TYPE(klass) != T_MODULE &&\n        TYPE(klass) != T_NIL) {\n        rb_raise(rb_eTypeError, \"2nd parameter must be Class or Module\");\n    }\n    if (rb_obj_is_kind_of(ole, cWIN32OLE)) {\n        OLEData_Get_Struct(ole, pole);\n        hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,\n                                                  0, lcid, &pTypeInfo);\n        if(FAILED(hr)) {\n            ole_raise(hr, rb_eRuntimeError, \"failed to GetTypeInfo\");\n        }\n        hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);\n        if(FAILED(hr)) {\n            OLE_RELEASE(pTypeInfo);\n            ole_raise(hr, rb_eRuntimeError, \"failed to GetContainingTypeLib\");\n        }\n        OLE_RELEASE(pTypeInfo);\n        if(TYPE(klass) != T_NIL) {\n            ole_const_load(pTypeLib, klass, self);\n        }\n        else {\n            ole_const_load(pTypeLib, cWIN32OLE, self);\n        }\n        OLE_RELEASE(pTypeLib);\n    }\n    else if(TYPE(ole) == T_STRING) {\n        file = typelib_file(ole);\n        if (file == Qnil) {\n            file = ole;\n        }\n        pBuf = ole_mb2wc(StringValuePtr(file), -1);\n        hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);\n        SysFreeString(pBuf);\n        if (FAILED(hr))\n            ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to LoadTypeLibEx\");\n        if(TYPE(klass) != T_NIL) {\n            ole_const_load(pTypeLib, klass, self);\n        }\n        else {\n            ole_const_load(pTypeLib, cWIN32OLE, self);\n        }\n        OLE_RELEASE(pTypeLib);\n    }\n    else {\n        rb_raise(rb_eTypeError, \"1st parameter must be WIN32OLE instance\");\n    }\n    return Qnil;\n}\n\nstatic VALUE\nole_classes_from_typelib(pTypeLib, classes)\n    ITypeLib *pTypeLib;\n    VALUE classes;\n{\n    \n    long count;\n    int i;\n    HRESULT hr;\n    BSTR bstr;\n    ITypeInfo *pTypeInfo;\n    VALUE type;\n  \n    rb_secure(4);\n    count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);\n    for (i = 0; i < count; i++) {\n        hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,\n                                                &bstr, NULL, NULL, NULL);\n        if (FAILED(hr)) \n            continue;\n\n        hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);\n        if (FAILED(hr))\n            continue;\n\n        type = foletype_s_allocate(cWIN32OLE_TYPE);\n        oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));\n\n        rb_ary_push(classes, type);\n        OLE_RELEASE(pTypeInfo);\n    }\n    return classes;\n}\n\nstatic ULONG\nreference_count(pole)\n    struct oledata * pole;\n{\n    ULONG n = 0;\n    if(pole->pDispatch) {\n        OLE_ADDREF(pole->pDispatch);\n        n = OLE_RELEASE(pole->pDispatch);\n    }\n    return n;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE.ole_reference_count(aWIN32OLE) --> number\n * \n *  Returns reference counter of Dispatch interface of WIN32OLE object. \n *  You should not use this method because this method\n *  exists only for debugging WIN32OLE.\n */\nstatic VALUE\nfole_s_reference_count(self, obj)\n    VALUE self;\n    VALUE obj;\n{\n    struct oledata * pole;\n    OLEData_Get_Struct(obj, pole);\n    return INT2NUM(reference_count(pole));\n}\n\n/*\n *  call-seq:\n *     WIN32OLE.ole_free(aWIN32OLE) --> number\n * \n *  Invokes Release method of Dispatch interface of WIN32OLE object. \n *  You should not use this method because this method\n *  exists only for debugging WIN32OLE.\n *  The return value is reference counter of OLE object.\n */\nstatic VALUE\nfole_s_free(self, obj)\n    VALUE self;\n    VALUE obj;\n{\n    ULONG n = 0;\n    struct oledata * pole;\n    OLEData_Get_Struct(obj, pole);\n    if(pole->pDispatch) {\n        if (reference_count(pole) > 0) {\n            n = OLE_RELEASE(pole->pDispatch);\n        }\n    }\n    return INT2NUM(n);\n}\n\nstatic HWND\nole_show_help(helpfile, helpcontext)\n    VALUE helpfile;\n    VALUE helpcontext;\n{\n    FNHTMLHELP *pfnHtmlHelp;\n    HWND hwnd = 0;\n\n    if(!ghhctrl)\n        ghhctrl = LoadLibrary(\"HHCTRL.OCX\");\n    if (!ghhctrl)\n        return hwnd;\n    pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, \"HtmlHelpA\");\n    if (!pfnHtmlHelp)\n        return hwnd;\n    hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile), \n                    0x0f, NUM2INT(helpcontext));\n    if (hwnd == 0)\n        hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile), \n                 0,  NUM2INT(helpcontext));\n    return hwnd;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE.ole_show_help(obj [,helpcontext])\n * \n *  Displays helpfile. The 1st argument specifies WIN32OLE_TYPE\n *  object or WIN32OLE_METHOD object or helpfile.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     typeobj = excel.ole_type\n *     WIN32OLE.ole_show_help(typeobj)\n */\nstatic VALUE\nfole_s_show_help(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE target;\n    VALUE helpcontext;\n    VALUE helpfile;\n    VALUE name;\n    HWND  hwnd;\n    rb_scan_args(argc, argv, \"11\", &target, &helpcontext);\n    if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||\n        rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {\n        helpfile = rb_funcall(target, rb_intern(\"helpfile\"), 0);\n        if(strlen(StringValuePtr(helpfile)) == 0) {\n            name = rb_ivar_get(target, rb_intern(\"name\"));\n            rb_raise(rb_eRuntimeError, \"no helpfile of `%s'\",\n                     StringValuePtr(name));\n        }\n        helpcontext = rb_funcall(target, rb_intern(\"helpcontext\"), 0);\n    } else {\n        helpfile = target;\n    }\n    if (TYPE(helpfile) != T_STRING) {\n        rb_raise(rb_eTypeError, \"1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)\");\n    }\n    hwnd = ole_show_help(helpfile, helpcontext);\n    if(hwnd == 0) {\n        rb_raise(rb_eRuntimeError, \"failed to open help file `%s'\",\n                 StringValuePtr(helpfile));\n    }\n    return Qnil;\n}\n\n/* \n *  call-seq:\n *     WIN32OLE.codepage\n * \n *  Returns current codepage.\n *     WIN32OLE.codepage # => WIN32OLE::CP_ACP\n */\nstatic VALUE\nfole_s_get_code_page(self)\n    VALUE self;\n{\n    return INT2FIX(cWIN32OLE_cp);\n}\n\n/* \n *  call-seq:\n *     WIN32OLE.codepage = CP\n * \n *  Sets current codepage.\n *     WIN32OLE.codepage = WIN32OLE::CP_UTF8\n */\nstatic VALUE\nfole_s_set_code_page(self, vcp)\n    VALUE self;\n    VALUE vcp;\n{\n    UINT cp = FIX2INT(vcp);\n\n    switch(cp) {\n    case CP_ACP:\n    case CP_OEMCP:\n    case CP_MACCP:\n    case CP_THREAD_ACP:\n    case CP_SYMBOL:\n    case CP_UTF7:\n    case CP_UTF8:\n        cWIN32OLE_cp = cp;\n        break;\n    default:\n        rb_raise(eWIN32OLE_RUNTIME_ERROR, \"codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8\");\n        break;\n    }\n\n    /*\n     * Should this method return old codepage?\n     */\n    return Qnil;\n}\n\n/*\n * Document-class: WIN32OLE\n *\n *   <code>WIN32OLE</code> objects represent OLE Automation object in Ruby.\n */\n\n/*\n *  call-seq:\n *     WIN32OLE.new(server, [host]) -> WIN32OLE object\n * \n *  Returns a new WIN32OLE object(OLE Automation object).\n *  The first argument server specifies OLE Automation server.\n *  The first argument should be CLSID or PROGID.\n *  If second argument host specified, then returns OLE Automation \n *  object on host. \n *\n *      WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.\n *      WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.\n */\nstatic VALUE\nfole_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE svr_name;\n    VALUE host;\n    VALUE others;\n    HRESULT hr;\n    CLSID   clsid;\n    OLECHAR *pBuf;\n    IDispatch *pDispatch;\n\n    rb_secure(4);\n    rb_call_super(0, 0);\n    rb_scan_args(argc, argv, \"11*\", &svr_name, &host, &others);\n\n    if (ruby_safe_level > 0 && OBJ_TAINTED(svr_name)) {\n        rb_raise(rb_eSecurityError, \"Insecure Object Creation - %s\",\n                 StringValuePtr(svr_name));\n    }\n    if (!NIL_P(host)) {\n        if (ruby_safe_level > 0 && OBJ_TAINTED(host)) {\n            rb_raise(rb_eSecurityError, \"Insecure Object Creation - %s\",\n                     StringValuePtr(svr_name));\n        }\n        return ole_create_dcom(argc, argv, self);\n    }\n\n    /* get CLSID from OLE server name */\n    pBuf  = ole_mb2wc(StringValuePtr(svr_name), -1);\n    hr = CLSIDFromProgID(pBuf, &clsid);\n    if(FAILED(hr)) {\n        hr = CLSIDFromString(pBuf, &clsid);\n    }\n    SysFreeString(pBuf);\n    if(FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"unknown OLE server: `%s'\",\n                  StringValuePtr(svr_name));\n    }\n\n    /* get IDispatch interface */\n    hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,\n                          &IID_IDispatch, (void**)&pDispatch);\n    if(FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,\n                  \"failed to create WIN32OLE object from `%s'\",\n                  StringValuePtr(svr_name));\n    }\n    \n    ole_set_member(self, pDispatch);\n    return self;\n}\n\nstatic VALUE\nhash2named_arg(pair, pOp)\n    VALUE pair;\n    struct oleparam* pOp;\n{\n    unsigned int index, i;\n    VALUE key, value;\n    index = pOp->dp.cNamedArgs;\n\n    /*-------------------------------------\n      the data-type of key must be String\n    ---------------------------------------*/\n    key = rb_ary_entry(pair, 0);\n    if(TYPE(key) != T_STRING) {\n        /* clear name of dispatch parameters */\n        for(i = 1; i < index + 1; i++) {\n            SysFreeString(pOp->pNamedArgs[i]);\n        }\n        /* clear dispatch parameters */\n        for(i = 0; i < index; i++ ) {\n            VariantClear(&(pOp->dp.rgvarg[i]));\n        }\n        /* raise an exception */\n        Check_Type(key, T_STRING);\n    }\n\n    /* pNamedArgs[0] is <method name>, so \"index + 1\" */\n    pOp->pNamedArgs[index + 1] = ole_mb2wc(StringValuePtr(key), -1);\n\n    value = rb_ary_entry(pair, 1);\n    VariantInit(&(pOp->dp.rgvarg[index]));\n    ole_val2variant(value, &(pOp->dp.rgvarg[index]));\n\n    pOp->dp.cNamedArgs += 1;\n    return Qnil;\n}\n\nstatic VALUE\nset_argv(realargs, beg, end)\n    VARIANTARG* realargs;\n    unsigned int beg, end;\n{\n    VALUE argv = rb_const_get(cWIN32OLE, rb_intern(\"ARGV\"));\n\n    Check_Type(argv, T_ARRAY);\n    rb_ary_clear(argv);\n    while (end-- > beg) {\n        rb_ary_push(argv, ole_variant2val(&realargs[end]));\n        VariantClear(&realargs[end]);\n    }\n    return argv;\n}\n\nstatic VALUE\nole_invoke(argc, argv, self, wFlags)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n    USHORT wFlags;\n{\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n    struct oledata *pole;\n    HRESULT hr;\n    VALUE cmd;\n    VALUE paramS;\n    VALUE param;\n    VALUE obj;\n    VALUE v;\n\n    BSTR wcmdname;\n\n    DISPID DispID;\n    DISPID* pDispID;\n    EXCEPINFO excepinfo;\n    VARIANT result;\n    VARIANTARG* realargs = NULL;\n    unsigned int argErr = 0;\n    unsigned int i;\n    unsigned int cNamedArgs;\n    int n;\n    struct oleparam op;\n    memset(&excepinfo, 0, sizeof(EXCEPINFO));\n\n    VariantInit(&result);\n\n    op.dp.rgvarg = NULL;\n    op.dp.rgdispidNamedArgs = NULL;\n    op.dp.cNamedArgs = 0;\n    op.dp.cArgs = 0;\n\n    rb_scan_args(argc, argv, \"1*\", &cmd, &paramS);\n    OLEData_Get_Struct(self, pole);\n    if(!pole->pDispatch) {\n        rb_raise(rb_eRuntimeError, \"failed to get dispatch interface\");\n    }\n    wcmdname = ole_mb2wc(StringValuePtr(cmd), -1);\n    hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,\n                                                 &wcmdname, 1, lcid, &DispID);\n    SysFreeString(wcmdname);\n    if(FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"unknown property or method `%s'\",\n                  StringValuePtr(cmd));\n    }\n\n    /* pick up last argument of method */\n    param = rb_ary_entry(paramS, argc-2);\n\n    op.dp.cNamedArgs = 0;\n\n    /* if last arg is hash object */\n    if(TYPE(param) == T_HASH) {\n        /*------------------------------------------ \n          hash object ==> named dispatch parameters \n        --------------------------------------------*/\n        cNamedArgs = NUM2INT(rb_funcall(param, rb_intern(\"length\"), 0));\n        op.dp.cArgs = cNamedArgs + argc - 2;\n        op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);\n        op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);\n        rb_iterate(rb_each, param, hash2named_arg, (VALUE)&op);\n\n        pDispID = ALLOCA_N(DISPID, cNamedArgs + 1);\n        op.pNamedArgs[0] = ole_mb2wc(StringValuePtr(cmd), -1);\n        hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch,\n                                                    &IID_NULL,\n                                                    op.pNamedArgs,\n                                                    op.dp.cNamedArgs + 1,\n                                                    lcid, pDispID);\n        for(i = 0; i < op.dp.cNamedArgs + 1; i++) {\n            SysFreeString(op.pNamedArgs[i]);\n            op.pNamedArgs[i] = NULL;\n        }\n        if(FAILED(hr)) {\n            /* clear dispatch parameters */\n            for(i = 0; i < op.dp.cArgs; i++ ) {\n                VariantClear(&op.dp.rgvarg[i]);\n            }\n            ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                      \"failed to get named argument info: `%s'\",\n                      StringValuePtr(cmd));\n        }\n        op.dp.rgdispidNamedArgs = &(pDispID[1]);\n    }\n    else {\n        cNamedArgs = 0;\n        op.dp.cArgs = argc - 1;\n        op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);\n        if (op.dp.cArgs > 0) {\n            op.dp.rgvarg  = ALLOCA_N(VARIANTARG, op.dp.cArgs);\n        }\n    }\n    /*--------------------------------------\n      non hash args ==> dispatch parameters \n     ----------------------------------------*/\n    if(op.dp.cArgs > cNamedArgs) {\n        realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);\n        for(i = cNamedArgs; i < op.dp.cArgs; i++) {\n            n = op.dp.cArgs - i + cNamedArgs - 1;\n            VariantInit(&realargs[n]);\n            VariantInit(&op.dp.rgvarg[n]);\n            param = rb_ary_entry(paramS, i-cNamedArgs);\n            \n             ole_val2variant(param, &realargs[n]);\n            V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;\n             V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];\n\n        }\n    }\n    /* apparent you need to call propput, you need this */\n    if (wFlags & DISPATCH_PROPERTYPUT) {\n        if (op.dp.cArgs == 0)\n            return ResultFromScode(E_INVALIDARG);\n\n        op.dp.cNamedArgs = 1;\n        op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );\n        op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;\n    }\n    \n    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, \n                                         &IID_NULL, lcid, wFlags, &op.dp, \n                                         &result, &excepinfo, &argErr);\n    if (FAILED(hr)) {\n        /* retry to call args by value */\n        if(op.dp.cArgs >= cNamedArgs) {\n            for(i = cNamedArgs; i < op.dp.cArgs; i++) {\n                n = op.dp.cArgs - i + cNamedArgs - 1;\n                param = rb_ary_entry(paramS, i-cNamedArgs);\n                ole_val2variant(param, &op.dp.rgvarg[n]);\n            }\n            if (hr == DISP_E_EXCEPTION) {\n                ole_freeexceptinfo(&excepinfo);\n            }\n            memset(&excepinfo, 0, sizeof(EXCEPINFO));\n            VariantInit(&result);\n            hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, \n                                                 &IID_NULL, lcid, wFlags,\n                                                 &op.dp, &result,\n                                                 &excepinfo, &argErr);\n\n            /* mega kludge. if a method in WORD is called and we ask\n             * for a result when one is not returned then\n             * hResult == DISP_E_EXCEPTION. this only happens on\n             * functions whose DISPID > 0x8000 */\n            if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {\n                if (hr == DISP_E_EXCEPTION) {\n                    ole_freeexceptinfo(&excepinfo);\n                }\n                memset(&excepinfo, 0, sizeof(EXCEPINFO));\n                hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, \n                        &IID_NULL, lcid, wFlags,\n                        &op.dp, NULL,\n                        &excepinfo, &argErr);\n            }\n            for(i = cNamedArgs; i < op.dp.cArgs; i++) {\n                n = op.dp.cArgs - i + cNamedArgs - 1;\n                VariantClear(&op.dp.rgvarg[n]);\n            }\n        }\n        if (FAILED(hr)) {\n            /* retry after converting nil to VT_EMPTY */\n            if (op.dp.cArgs > cNamedArgs) {\n                for(i = cNamedArgs; i < op.dp.cArgs; i++) {\n                    n = op.dp.cArgs - i + cNamedArgs - 1;\n                    param = rb_ary_entry(paramS, i-cNamedArgs);\n                    ole_val2variant2(param, &op.dp.rgvarg[n]);\n                }\n                if (hr == DISP_E_EXCEPTION) {\n                    ole_freeexceptinfo(&excepinfo);\n                }\n                memset(&excepinfo, 0, sizeof(EXCEPINFO));\n                VariantInit(&result);\n                hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID, \n                        &IID_NULL, lcid, wFlags,\n                        &op.dp, &result,\n                        &excepinfo, &argErr);\n                for(i = cNamedArgs; i < op.dp.cArgs; i++) {\n                    n = op.dp.cArgs - i + cNamedArgs - 1;\n                    VariantClear(&op.dp.rgvarg[n]);\n                }\n            }\n        }\n\n    }\n    /* clear dispatch parameter */\n    if(op.dp.cArgs > cNamedArgs) {\n        set_argv(realargs, cNamedArgs, op.dp.cArgs);\n    }\n    else {\n        for(i = 0; i < op.dp.cArgs; i++) {\n            VariantClear(&op.dp.rgvarg[i]);\n        }\n    }\n\n    if (FAILED(hr)) {\n        v = ole_excepinfo2msg(&excepinfo);\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"%s%s\",\n                  StringValuePtr(cmd), StringValuePtr(v));\n    }\n    obj = ole_variant2val(&result);\n    VariantClear(&result);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#invoke(method, [arg1,...])  => return value of method.\n *\n *  Runs OLE method. \n *  The first argument specifies the method name of OLE Automation object.\n *  The others specify argument of the <i>method</i>.\n *  If you can not execute <i>method</i> directly, then use this method instead.\n *\n *    excel = WIN32OLE.new('Excel.Application')\n *    excel.invoke('Quit')  # => same as excel.Quit\n *\n */\nstatic VALUE\nfole_invoke(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET);\n}\n\nstatic VALUE\nole_invoke2(self, dispid, args, types, dispkind)\n    VALUE self;\n    VALUE dispid;\n    VALUE args;\n    VALUE types;\n    USHORT dispkind;\n{\n    HRESULT hr;\n    struct oledata *pole;\n    unsigned int argErr = 0;\n    EXCEPINFO excepinfo;\n    VARIANT result;\n    DISPPARAMS dispParams;\n    VARIANTARG* realargs = NULL;\n    int i, j;\n    VALUE obj = Qnil;\n    VALUE tp, param;\n    VALUE v;\n    VARTYPE vt;\n\n    Check_Type(args, T_ARRAY);\n    Check_Type(types, T_ARRAY);\n    \n    memset(&excepinfo, 0, sizeof(EXCEPINFO));\n    memset(&dispParams, 0, sizeof(DISPPARAMS));\n    VariantInit(&result);\n    OLEData_Get_Struct(self, pole);\n\n    dispParams.cArgs = RARRAY(args)->len;\n    dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs);\n    realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs);\n    for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--)\n    {\n        VariantInit(&realargs[i]);\n        VariantInit(&dispParams.rgvarg[i]);\n        tp = rb_ary_entry(types, j);\n        vt = (VARTYPE)FIX2INT(tp);\n        V_VT(&dispParams.rgvarg[i]) = vt;\n        param = rb_ary_entry(args, j);\n        if (param == Qnil)\n        {\n\n            V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;\n            V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;\n        }\n        else\n        {\n            if (vt & VT_ARRAY)\n            {\n                int ent;\n                LPBYTE pb;\n                short* ps;\n                LPLONG pl;\n                VARIANT* pv;\n                CY *py;\n                VARTYPE v;\n                SAFEARRAYBOUND rgsabound[1];\n                Check_Type(param, T_ARRAY);\n                rgsabound[0].lLbound = 0;\n                rgsabound[0].cElements = RARRAY(param)->len;\n                v = vt & ~(VT_ARRAY | VT_BYREF);\n                V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);\n                V_VT(&realargs[i]) = VT_ARRAY | v;\n                SafeArrayLock(V_ARRAY(&realargs[i]));\n                pb = V_ARRAY(&realargs[i])->pvData;\n                ps = V_ARRAY(&realargs[i])->pvData;\n                pl = V_ARRAY(&realargs[i])->pvData;\n                py = V_ARRAY(&realargs[i])->pvData;\n                pv = V_ARRAY(&realargs[i])->pvData;\n                for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)\n                {\n                    VARIANT velem;\n                    VALUE elem = rb_ary_entry(param, ent);\n                    ole_val2variant(elem, &velem);\n                    if (v != VT_VARIANT)\n                    {\n                        VariantChangeTypeEx(&velem, &velem,\n                            LOCALE_SYSTEM_DEFAULT, 0, v);\n                    }\n                    switch (v)\n                    {\n                    /* 128 bits */\n                    case VT_VARIANT:\n                        *pv++ = velem;\n                        break;\n                    /* 64 bits */\n                    case VT_R8:\n                    case VT_CY:\n                    case VT_DATE:\n                        *py++ = V_CY(&velem);\n                        break;\n                    /* 16 bits */\n                    case VT_BOOL:\n                    case VT_I2:\n                    case VT_UI2:\n                        *ps++ = V_I2(&velem);\n                        break;\n                    /* 8 bites */\n                    case VT_UI1:\n                    case VT_I1:\n                        *pb++ = V_UI1(&velem);\n                        break;\n                    /* 32 bits */\n                    default:\n                        *pl++ = V_I4(&velem);\n                        break;\n                    }\n                }\n                SafeArrayUnlock(V_ARRAY(&realargs[i]));\n            }\n            else\n            {\n                ole_val2variant(param, &realargs[i]);\n                if ((vt & (~VT_BYREF)) != VT_VARIANT)\n                {\n                    hr = VariantChangeTypeEx(&realargs[i], &realargs[i],\n                                             LOCALE_SYSTEM_DEFAULT, 0,\n                                             (VARTYPE)(vt & (~VT_BYREF)));\n                    if (hr != S_OK)\n                    {\n                        rb_raise(rb_eTypeError, \"not valid value\");\n                    }\n                }\n            }\n            if ((vt & VT_BYREF) || vt == VT_VARIANT)\n            {\n                if (vt == VT_VARIANT)\n                    V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;\n                switch (vt & (~VT_BYREF))\n                {\n                /* 128 bits */\n                case VT_VARIANT:\n                    V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];\n                    break;\n                /* 64 bits */\n                case VT_R8:\n                case VT_CY:\n                case VT_DATE:\n                    V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);\n                    break;\n                /* 16 bits */\n                case VT_BOOL:\n                case VT_I2:\n                case VT_UI2:\n                    V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);\n                    break;\n                /* 8 bites */\n                case VT_UI1:\n                case VT_I1:\n                    V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);\n                    break;\n                /* 32 bits */\n                default:\n                    V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);\n                    break;\n                }\n            }\n            else\n            {\n                /* copy 64 bits of data */\n                V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);\n            }\n        }\n    }\n\n    if (dispkind & DISPATCH_PROPERTYPUT) {\n        dispParams.cNamedArgs = 1;\n        dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );\n        dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;\n    }\n\n    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, NUM2INT(dispid),\n                                         &IID_NULL, LOCALE_SYSTEM_DEFAULT,\n                                         dispkind,\n                                         &dispParams, &result,\n                                         &excepinfo, &argErr);\n\n    if (FAILED(hr)) {\n        v = ole_excepinfo2msg(&excepinfo);\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"_invoke %s\",\n                  StringValuePtr(v));\n    }\n\n    /* clear dispatch parameter */\n    if(dispParams.cArgs > 0) {\n        set_argv(realargs, 0, dispParams.cArgs);\n    }\n\n    obj = ole_variant2val(&result);\n    VariantClear(&result);\n    return obj;\n}\n\n/*\n *   call-seq:\n *      WIN32OLE#_invoke(dispid, args, types)\n * \n *   Runs the early binding method.\n *   The 1st argument specifies dispatch ID, \n *   the 2nd argument specifies the array of arguments,\n *   the 3rd argument specifies the array of the type of arguments.\n *\n *      excel = WIN32OLE.new('Excel.Application')\n *      excel._invoke(302, [], []) #  same effect as excel.Quit\n */\nstatic VALUE\nfole_invoke2(self, dispid, args, types)\n    VALUE self;\n    VALUE dispid;\n    VALUE args;\n    VALUE types;\n{\n    return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#_getproperty(dispid, args, types)\n * \n *  Runs the early binding method to get property.\n *  The 1st argument specifies dispatch ID, \n *  the 2nd argument specifies the array of arguments,\n *  the 3rd argument specifies the array of the type of arguments.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     puts excel._getproperty(558, [], []) # same effect as puts excel.visible\n */\nstatic VALUE\nfole_getproperty2(self, dispid, args, types)\n    VALUE self;\n    VALUE dispid;\n    VALUE args;\n    VALUE types;\n{\n    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);\n}\n\n/*\n *   call-seq:\n *      WIN32OLE#_setproperty(dispid, args, types)\n * \n *   Runs the early binding method to set property.\n *   The 1st argument specifies dispatch ID, \n *   the 2nd argument specifies the array of arguments,\n *   the 3rd argument specifies the array of the type of arguments.\n *\n *      excel = WIN32OLE.new('Excel.Application')\n *      excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true\n */\nstatic VALUE\nfole_setproperty2(self, dispid, args, types)\n    VALUE self;\n    VALUE dispid;\n    VALUE args;\n    VALUE types;\n{\n    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE['property']=val \n *     WIN32OLE.setproperty('property', [arg1, arg2,...] val)\n * \n *  Sets property of OLE object.\n *  When you want to set property with argument, you can use this method.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     excel['Visible'] = true\n *     book = excel.workbooks.add\n *     sheet = book.worksheets(1)\n *     sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.\n */\nstatic VALUE\nfole_setproperty(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE['property'] \n * \n *  Returns property of OLE object.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     puts excel['Visible'] # => false\n */\nstatic VALUE\nfole_getproperty(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET);\n}\n\nstatic VALUE\nole_propertyput(self, property, value)\n    VALUE self, property, value;\n{\n    struct oledata *pole;\n    unsigned argErr;\n    unsigned int index;\n    HRESULT hr;\n    EXCEPINFO excepinfo;\n    DISPID dispID = DISPID_VALUE;\n    DISPID dispIDParam = DISPID_PROPERTYPUT;\n    USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;\n    DISPPARAMS dispParams;\n    VARIANTARG propertyValue[2];\n    OLECHAR* pBuf[1];\n    VALUE v;\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n    dispParams.rgdispidNamedArgs = &dispIDParam;\n    dispParams.rgvarg = propertyValue;\n    dispParams.cNamedArgs = 1;\n    dispParams.cArgs = 1;\n\n    VariantInit(&propertyValue[0]);\n    VariantInit(&propertyValue[1]);\n    memset(&excepinfo, 0, sizeof(excepinfo));\n\n    OLEData_Get_Struct(self, pole);\n\n    /* get ID from property name */\n    pBuf[0]  = ole_mb2wc(StringValuePtr(property), -1);\n    hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL,\n                                                pBuf, 1, lcid, &dispID);\n    SysFreeString(pBuf[0]);\n    pBuf[0] = NULL;\n\n    if(FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \n                  \"unknown property or method: `%s'\",\n                  StringValuePtr(property));\n    }\n    /* set property value */\n    ole_val2variant(value, &propertyValue[0]);\n    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL, \n                                         lcid, wFlags, &dispParams,\n                                         NULL, &excepinfo, &argErr);\n\n    for(index = 0; index < dispParams.cArgs; ++index) {\n        VariantClear(&propertyValue[index]);\n    }\n    if (FAILED(hr)) {\n        v = ole_excepinfo2msg(&excepinfo);\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, StringValuePtr(v));\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#ole_free\n *\n *  invokes Release method of Dispatch interface of WIN32OLE object.\n *  Usually, you do not need to call this method because Release method\n *  called automatically when WIN32OLE object garbaged.\n *\n */\nstatic VALUE\nfole_free(self)\n    VALUE self;\n{\n    struct oledata *pole;\n    rb_secure(4);\n    OLEData_Get_Struct(self, pole);\n    OLE_FREE(pole->pDispatch);\n    pole->pDispatch = NULL;\n    return Qnil;\n}\n\nstatic VALUE\nole_each_sub(pEnumV)\n    VALUE pEnumV;\n{\n    VARIANT variant;\n    VALUE obj = Qnil;\n    IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;\n    VariantInit(&variant);\n    while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) {\n        obj = ole_variant2val(&variant);\n        VariantClear(&variant);\n        VariantInit(&variant);\n        rb_yield(obj);\n    }\n    return Qnil;\n}\n\nstatic VALUE\nole_ienum_free(pEnumV)\n    VALUE pEnumV;\n{\n    IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;\n    OLE_RELEASE(pEnum);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#each {|i|...}\n * \n *  Iterates over each item of OLE collection which has IEnumVARIANT interface.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     book = excel.workbooks.add\n *     sheets = book.worksheets(1)\n *     cells = sheets.cells(\"A1:A5\")\n *     cells.each do |cell|\n *       cell.value = 10\n *     end\n */\nstatic VALUE\nfole_each(self)\n    VALUE self;\n{\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n\n    struct oledata *pole;\n\n    unsigned int argErr;\n    EXCEPINFO excepinfo;\n    DISPPARAMS dispParams;\n    VARIANT result;\n    HRESULT hr;\n    IEnumVARIANT *pEnum = NULL;\n\n    VariantInit(&result);\n    dispParams.rgvarg = NULL;\n    dispParams.rgdispidNamedArgs = NULL;\n    dispParams.cNamedArgs = 0;\n    dispParams.cArgs = 0;\n    memset(&excepinfo, 0, sizeof(excepinfo));\n    \n    OLEData_Get_Struct(self, pole);\n    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,\n                                         &IID_NULL, lcid,\n                                         DISPATCH_METHOD | DISPATCH_PROPERTYGET,\n                                         &dispParams, &result,\n                                         &excepinfo, &argErr);\n\n    if (FAILED(hr)) {\n        VariantClear(&result);\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to get IEnum Interface\");\n    }\n\n    if (V_VT(&result) == VT_UNKNOWN)\n        hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),\n                                                        &IID_IEnumVARIANT,\n                                                        (void**)&pEnum);\n    else if (V_VT(&result) == VT_DISPATCH)\n        hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),\n                                                         &IID_IEnumVARIANT,\n                                                         (void**)&pEnum);\n    if (FAILED(hr) || !pEnum) {\n        VariantClear(&result);\n        ole_raise(hr, rb_eRuntimeError, \"failed to get IEnum Interface\");\n    }\n\n    VariantClear(&result);\n    rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#method_missing(id [,arg1, arg2, ...])\n * \n *  Calls WIN32OLE#invoke method.\n */\nstatic VALUE\nfole_missing(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    ID id;\n    char* mname;\n    int n;\n    id = rb_to_id(argv[0]);\n    mname = rb_id2name(id);\n    if(!mname) {\n        rb_raise(rb_eRuntimeError, \"fail: unknown method or property\");\n    }\n    n = strlen(mname);\n    if(mname[n-1] == '=') {\n        argv[0] = rb_str_new(mname, n-1);\n\n        return ole_propertyput(self, argv[0], argv[1]);\n    }\n    else {\n        argv[0] = rb_str_new2(mname);\n        return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET);\n    }\n}\n\nstatic VALUE\nole_method_sub(self, pOwnerTypeInfo, pTypeInfo, name)\n    VALUE self;\n    ITypeInfo *pOwnerTypeInfo;\n    ITypeInfo *pTypeInfo;\n    VALUE name;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    BSTR bstr;\n    FUNCDESC *pFuncDesc;\n    WORD i;\n    VALUE fname;\n    VALUE method = Qnil;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    }\n    for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {\n        hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);\n        if (FAILED(hr))\n             continue;\n\n        hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,\n                                                 &bstr, NULL, NULL, NULL);\n        if (FAILED(hr)) {\n            pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n            continue;\n        }\n        fname = WC2VSTR(bstr);\n        if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {\n            olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);\n            method = self;\n        }\n        pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n        pFuncDesc=NULL;\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return method;\n}\n\nstatic VALUE\nolemethod_from_typeinfo(self, pTypeInfo, name)\n    VALUE self;\n    ITypeInfo *pTypeInfo;\n    VALUE name;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    WORD i;\n    HREFTYPE href;\n    ITypeInfo *pRefTypeInfo;\n    VALUE method = Qnil;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    }\n    method = ole_method_sub(self, 0, pTypeInfo, name);\n    if (method != Qnil) {\n       return method;\n    }\n    for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){\n       hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);\n       if(FAILED(hr))\n           continue;\n       hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);\n       if (FAILED(hr))\n           continue;\n       method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);\n       OLE_RELEASE(pRefTypeInfo);\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return method;\n}\n\nstatic VALUE\nole_methods_sub(pOwnerTypeInfo, pTypeInfo, methods, mask)\n    ITypeInfo *pOwnerTypeInfo;\n    ITypeInfo *pTypeInfo;\n    VALUE     methods;\n    int       mask;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    BSTR bstr;\n    char *pstr;\n    FUNCDESC *pFuncDesc;\n    VALUE method;\n    WORD i;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    }\n    for(i = 0; i < pTypeAttr->cFuncs; i++) {\n        pstr = NULL;\n        hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);\n        if (FAILED(hr))\n             continue;\n                 \n        hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,\n                                                 &bstr, NULL, NULL, NULL);\n        if (FAILED(hr)) {\n            pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n            continue;\n        }\n        if(pFuncDesc->invkind & mask) {\n            method = folemethod_s_allocate(cWIN32OLE_METHOD);\n            olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo, \n                                 i, WC2VSTR(bstr));\n            rb_ary_push(methods, method);\n        }\n        pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n        pFuncDesc=NULL;\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n\n    return methods;\n}\n\nstatic VALUE\nole_methods_from_typeinfo(pTypeInfo, mask)\n    ITypeInfo *pTypeInfo;\n    int mask;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    WORD i;\n    HREFTYPE href;\n    ITypeInfo *pRefTypeInfo;\n    VALUE methods = rb_ary_new();\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    }\n\n    ole_methods_sub(0, pTypeInfo, methods, mask);\n    for(i=0; i < pTypeAttr->cImplTypes; i++){\n       hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);\n       if(FAILED(hr))\n           continue;\n       hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);\n       if (FAILED(hr))\n           continue;\n       ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);\n       OLE_RELEASE(pRefTypeInfo);\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return methods;\n}\n\nstatic HRESULT\ntypeinfo_from_ole(pole, ppti)\n    struct oledata *pole;\n    ITypeInfo **ppti;\n{\n    ITypeInfo *pTypeInfo;\n    ITypeLib *pTypeLib;\n    BSTR bstr;\n    VALUE type;\n    UINT i;\n    UINT count;\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n    HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,\n                                                      0, lcid, &pTypeInfo);\n    if(FAILED(hr)) {\n        ole_raise(hr, rb_eRuntimeError, \"failed to GetTypeInfo\");\n    }\n    hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,\n                                             -1,\n                                             &bstr,\n                                             NULL, NULL, NULL);\n    type = WC2VSTR(bstr);\n    hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);\n    OLE_RELEASE(pTypeInfo);\n    if (FAILED(hr)) {\n        ole_raise(hr, rb_eRuntimeError, \"failed to GetContainingTypeLib\");\n    }\n    count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);\n    for (i = 0; i < count; i++) {\n        hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,\n                                                &bstr, NULL, NULL, NULL);\n        if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) {\n            hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);\n            if (SUCCEEDED(hr)) {\n                *ppti = pTypeInfo;\n                break;\n            }\n        }\n    }\n    OLE_RELEASE(pTypeLib);\n    return hr;\n}\n\nstatic VALUE\nole_methods(self,mask)\n    VALUE self;\n    int mask;\n{\n    ITypeInfo *pTypeInfo;\n    HRESULT hr;\n    VALUE methods;\n    struct oledata *pole;\n\n    OLEData_Get_Struct(self, pole);\n    methods = rb_ary_new();\n\n    hr = typeinfo_from_ole(pole, &pTypeInfo);\n    if(FAILED(hr))\n        return methods;\n    rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask));\n    OLE_RELEASE(pTypeInfo);\n    return methods;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#ole_methods\n * \n *  Returns the array of WIN32OLE_METHOD object. \n *  The element is OLE method of WIN32OLE object.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     methods = excel.ole_methods\n *     \n */\nstatic VALUE\nfole_methods( self )\n    VALUE self;\n{\n    return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#ole_get_methods\n * \n *  Returns the array of WIN32OLE_METHOD object .\n *  The element of the array is property (gettable) of WIN32OLE object.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     properties = excel.ole_get_methods\n */\nstatic VALUE\nfole_get_methods( self )\n    VALUE self;\n{\n    return ole_methods( self, INVOKE_PROPERTYGET);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#ole_put_methods\n * \n *  Returns the array of WIN32OLE_METHOD object .\n *  The element of the array is property (settable) of WIN32OLE object.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     properties = excel.ole_put_methods\n */\nstatic VALUE\nfole_put_methods( self )\n    VALUE self;\n{\n    return ole_methods( self, INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#ole_func_methods\n * \n *  Returns the array of WIN32OLE_METHOD object .\n *  The element of the array is functional method of WIN32OLE object.\n *\n *     excel = WIN32OLE.new('Excel.Application')\n *     properties = excel.ole_func_methods\n *\n */\nstatic VALUE\nfole_func_methods( self )\n    VALUE self;\n{\n    return ole_methods( self, INVOKE_FUNC);\n}\n\n/*\n *   call-seq:\n *      WIN32OLE#ole_obj_help\n * \n *   Returns WIN32OLE_TYPE object.\n *\n *      excel = WIN32OLE.new('Excel.Application')\n *      tobj = excel.ole_obj_help\n */\nstatic VALUE\nfole_obj_help( self )\n    VALUE self;\n{\n    unsigned int index;\n    ITypeInfo *pTypeInfo;\n    ITypeLib *pTypeLib;\n    HRESULT hr;\n    struct oledata *pole;\n    BSTR bstr;\n    LCID  lcid = LOCALE_SYSTEM_DEFAULT;\n    VALUE type = Qnil;\n\n    OLEData_Get_Struct(self, pole);\n\n    hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );\n    if(FAILED(hr)) {\n        ole_raise(hr, rb_eRuntimeError, \"failed to GetTypeInfo\");\n    }\n    hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );\n    if(FAILED(hr)) {\n        OLE_RELEASE(pTypeInfo);\n        ole_raise(hr, rb_eRuntimeError, \"failed to GetContainingTypeLib\");\n    }\n    hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,\n                                             &bstr, NULL, NULL, NULL);\n    if (SUCCEEDED(hr)) {\n        type = foletype_s_allocate(cWIN32OLE_TYPE);\n        oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));\n    }\n    OLE_RELEASE(pTypeLib);\n    OLE_RELEASE(pTypeInfo);\n\n    return type;\n}\n\nstatic HRESULT\nole_docinfo_from_type(pTypeInfo, name, helpstr, helpcontext, helpfile)\n    ITypeInfo *pTypeInfo;\n    BSTR *name;\n    BSTR *helpstr; \n    DWORD *helpcontext;\n    BSTR *helpfile;\n{\n    HRESULT hr;\n    ITypeLib *pTypeLib;\n    UINT i;\n\n    hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);\n    if (FAILED(hr)) {\n        return hr;\n    }\n    \n    hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,\n                                            name, helpstr, \n                                            helpcontext, helpfile);\n    if (FAILED(hr)) {\n        OLE_RELEASE(pTypeLib);\n        return hr;\n    }\n    OLE_RELEASE(pTypeLib);\n    return hr;\n}\n\nstatic VALUE\nole_usertype2val(pTypeInfo, pTypeDesc, typedetails)\n    ITypeInfo *pTypeInfo;\n    TYPEDESC *pTypeDesc;\n    VALUE typedetails;\n{\n    HRESULT hr;\n    BSTR bstr;\n    ITypeInfo *pRefTypeInfo;\n    VALUE type = Qnil;\n\n    hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, \n                                           V_UNION1(pTypeDesc, hreftype),\n                                           &pRefTypeInfo);\n    if(FAILED(hr))\n        return Qnil;\n    hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL);\n    if(FAILED(hr)) {\n        OLE_RELEASE(pRefTypeInfo);\n        return Qnil;\n    }\n    OLE_RELEASE(pRefTypeInfo);\n    type = WC2VSTR(bstr);\n    if(typedetails != Qnil)\n        rb_ary_push(typedetails, type);\n    return type;\n}\n\nstatic VALUE ole_typedesc2val();\nstatic VALUE\nole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails) \n    ITypeInfo *pTypeInfo;\n    TYPEDESC *pTypeDesc;\n    VALUE typedetails;\n{    \n    TYPEDESC *p = pTypeDesc;\n    VALUE type = rb_str_new2(\"\");\n    while(p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {\n        p = V_UNION1(p, lptdesc);\n        if(strlen(StringValuePtr(type)) == 0) {\n           type = ole_typedesc2val(pTypeInfo, p, typedetails);\n        } else {\n           rb_str_cat(type, \",\", 1);\n           rb_str_concat(type, ole_typedesc2val(pTypeInfo, p, typedetails));\n        }\n    }\n    return type;\n}\n\nstatic VALUE\nole_typedesc2val(pTypeInfo, pTypeDesc, typedetails)\n    ITypeInfo *pTypeInfo;\n    TYPEDESC *pTypeDesc;\n    VALUE typedetails;\n{\n    VALUE str;\n    switch(pTypeDesc->vt) {\n    case VT_I2:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"I2\"));\n        return rb_str_new2(\"I2\");\n    case VT_I4:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"I4\"));\n        return rb_str_new2(\"I4\");\n    case VT_R4:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"R4\"));\n        return rb_str_new2(\"R4\");\n    case VT_R8:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"R8\"));\n        return rb_str_new2(\"R8\");\n    case VT_CY:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"CY\"));\n        return rb_str_new2(\"CY\");\n    case VT_DATE:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"DATE\"));\n        return rb_str_new2(\"DATE\");\n    case VT_BSTR:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"BSTR\"));\n        return rb_str_new2(\"BSTR\");\n    case VT_BOOL:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"BOOL\"));\n        return rb_str_new2(\"BOOL\");\n    case VT_VARIANT:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"VARIANT\"));\n        return rb_str_new2(\"VARIANT\");\n    case VT_DECIMAL:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"DECIMAL\"));\n        return rb_str_new2(\"DECIMAL\");\n    case VT_I1:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"I1\"));\n        return rb_str_new2(\"I1\");\n    case VT_UI1:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"UI1\"));\n        return rb_str_new2(\"UI1\");\n    case VT_UI2:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"UI2\"));\n        return rb_str_new2(\"UI2\");\n    case VT_UI4:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"UI4\"));\n        return rb_str_new2(\"UI4\");\n    case VT_I8:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"I8\"));\n        return rb_str_new2(\"I8\");\n    case VT_UI8:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"UI8\"));\n        return rb_str_new2(\"UI8\");\n    case VT_INT:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"INT\"));\n        return rb_str_new2(\"INT\");\n    case VT_UINT:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"UINT\"));\n        return rb_str_new2(\"UINT\");\n    case VT_VOID:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"VOID\"));\n        return rb_str_new2(\"VOID\");\n    case VT_HRESULT:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"HRESULT\"));\n        return rb_str_new2(\"HRESULT\");\n    case VT_PTR:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"PTR\"));\n        return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);\n    case VT_SAFEARRAY:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"SAFEARRAY\"));\n        return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);\n    case VT_CARRAY:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"CARRAY\"));\n        return rb_str_new2(\"CARRAY\");\n    case VT_USERDEFINED:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"USERDEFINED\"));\n        str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);\n        if (str != Qnil) {\n            return str;\n        }\n        return rb_str_new2(\"USERDEFINED\");\n    case VT_UNKNOWN:\n        return rb_str_new2(\"UNKNOWN\");\n    case VT_DISPATCH:\n        if(typedetails != Qnil)\n            rb_ary_push(typedetails, rb_str_new2(\"DISPATCH\"));\n        return rb_str_new2(\"DISPATCH\");\n    default:\n        str = rb_str_new2(\"Unknown Type \");\n        rb_str_concat(str, rb_fix2str(INT2FIX(pTypeDesc->vt), 10));\n        return str;\n    }\n}\n\n/*\n *   call-seq:\n *      WIN32OLE#ole_method_help(method)\n * \n *   Returns WIN32OLE_METHOD object corresponding with method \n *   specified by 1st argument.\n *\n *      excel = WIN32OLE.new('Excel.Application')\n *      method = excel.ole_method_help('Quit')\n *\n */\nstatic VALUE\nfole_method_help( self, cmdname )\n    VALUE self;\n    VALUE cmdname;\n{\n    ITypeInfo *pTypeInfo;\n    HRESULT hr;\n    struct oledata *pole;\n    VALUE method, obj;\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n\n    Check_SafeStr(cmdname);\n    OLEData_Get_Struct(self, pole);\n    hr = typeinfo_from_ole(pole, &pTypeInfo);\n    if(FAILED(hr))\n        ole_raise(hr, rb_eRuntimeError, \"failed to get ITypeInfo\");\n    method = folemethod_s_allocate(cWIN32OLE_METHOD);\n    obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);\n    OLE_RELEASE(pTypeInfo);\n    if (obj == Qnil)\n        rb_raise(eWIN32OLE_RUNTIME_ERROR, \"not found %s\",\n                 StringValuePtr(cmdname));\n    return obj;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#ole_activex_initialize() -> Qnil\n *\n *  Initialize WIN32OLE object(ActiveX Control) by calling \n *  IPersistMemory::InitNew.\n *\n *  Before calling OLE method, some kind of the ActiveX controls \n *  created with MFC should be initialized by calling \n *  IPersistXXX::InitNew.\n *\n *  If and only if you recieved the exception \"HRESULT error code:\n *  0x8000ffff catastrophic failure\", try this method before\n *  invoking any ole_method.\n *\n *     obj = WIN32OLE.new(\"ProgID_or_GUID_of_ActiveX_Control\")\n *     obj.ole_activex_initialize\n *     obj.method(...)\n *  \n */ \nstatic VALUE\nfole_activex_initialize(self)\n    VALUE self; \n{\n    struct oledata *pole;\n    IPersistMemory *pPersistMemory;\n\n    HRESULT hr = S_OK;\n\n    OLEData_Get_Struct(self, pole);\n\n    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory,\n                                                 (void **)&pPersistMemory);\n    if (SUCCEEDED(hr)) {\n        hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);\n        OLE_RELEASE(pPersistMemory);\n        if (SUCCEEDED(hr)) {\n            return Qnil;\n        }\n    }\n\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"fail to initialize ActiveX control\");\n    }\n\n    return Qnil;\n}\n\n/*\n *   call-seq:\n *      WIN32OLE_TYPE.ole_classes(typelib)\n * \n *   Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library.\n */\nstatic VALUE\nfoletype_s_ole_classes(self, typelib)\n    VALUE self;\n    VALUE typelib;\n{\n    VALUE file, classes;\n    OLECHAR * pbuf;\n    ITypeLib *pTypeLib;\n    HRESULT hr;\n\n    rb_secure(4);\n    classes = rb_ary_new();\n    if(TYPE(typelib) == T_STRING) {\n        file = typelib_file(typelib);\n        if (file == Qnil) {\n            file = typelib;\n        }\n        pbuf = ole_mb2wc(StringValuePtr(file), -1);\n        hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);\n        if (FAILED(hr))\n          ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to LoadTypeLibEx\");\n        SysFreeString(pbuf);\n        ole_classes_from_typelib(pTypeLib, classes);\n        OLE_RELEASE(pTypeLib);\n    } else {\n        rb_raise(rb_eTypeError, \"1st argument should be TypeLib string\");\n    }\n    return classes;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE.typelibs\n * \n *  Returns array of type libraries.\n *\n */\nstatic VALUE\nfoletype_s_typelibs(self)\n    VALUE self;\n{\n    HKEY htypelib, hclsid;\n    double fversion;\n    DWORD i, j;\n    LONG err;\n    VALUE clsid;\n    VALUE ver;\n    VALUE v = Qnil;\n    VALUE typelibs = rb_ary_new();\n\n    err = reg_open_key(HKEY_CLASSES_ROOT, \"TypeLib\", &htypelib);\n    if(err != ERROR_SUCCESS) {\n        return typelibs;\n    }\n    for(i = 0; ; i++) {\n        clsid = reg_enum_key(htypelib, i);\n        if (clsid == Qnil)\n            break;\n        err = reg_open_vkey(htypelib, clsid, &hclsid);\n        if (err != ERROR_SUCCESS)\n            continue;\n        fversion = 0;\n        for(j = 0; ; j++) {\n            ver = reg_enum_key(hclsid, j);\n            if (ver == Qnil)\n                break;\n            if (fversion > atof(StringValuePtr(ver)))\n                continue;\n            fversion = atof(StringValuePtr(ver));\n            if ( (v = reg_get_val(hclsid, StringValuePtr(ver))) != Qnil ) {\n                rb_ary_push(typelibs, v);\n            }\n        }\n        RegCloseKey(hclsid);\n    }\n    RegCloseKey(htypelib);\n    return typelibs;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE.progids\n * \n *  Returns array of ProgID.\n */\nstatic VALUE\nfoletype_s_progids(self)\n    VALUE self;\n{\n    HKEY hclsids, hclsid;\n    DWORD i;\n    LONG err;\n    VALUE clsid;\n    VALUE v = rb_str_new2(\"\");\n    VALUE progids = rb_ary_new();\n\n    err = reg_open_key(HKEY_CLASSES_ROOT, \"CLSID\", &hclsids);\n    if(err != ERROR_SUCCESS) {\n        return progids;\n    }\n    for(i = 0; ; i++) {\n        clsid = reg_enum_key(hclsids, i);\n        if (clsid == Qnil)\n            break;\n        err = reg_open_vkey(hclsids, clsid, &hclsid);\n        if (err != ERROR_SUCCESS)\n            continue;\n        if ((v = reg_get_val(hclsid, \"ProgID\")) != Qnil) \n            rb_ary_push(progids, v);\n        if ((v = reg_get_val(hclsid, \"VersionIndependentProgID\")) != Qnil)\n            rb_ary_push(progids, v);\n        RegCloseKey(hclsid);\n    }\n    RegCloseKey(hclsids);\n    return progids;\n}\n\nstatic VALUE\nfoletype_s_allocate(klass)\n    VALUE klass;\n{\n    struct oletypedata *poletype;\n    VALUE obj;\n    ole_initialize();\n    obj = Data_Make_Struct(klass,struct oletypedata,0,oletype_free,poletype);\n    poletype->pTypeInfo = NULL;\n    return obj;\n}\n\nstatic VALUE\noletype_set_member(self, pTypeInfo, name)\n    VALUE self;\n    ITypeInfo *pTypeInfo;\n    VALUE name;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    rb_ivar_set(self, rb_intern(\"name\"), name);\n    ptype->pTypeInfo = pTypeInfo;\n    if(pTypeInfo) OLE_ADDREF(pTypeInfo);\n    return self;\n}\n\nstatic VALUE\noleclass_from_typelib(self, pTypeLib, oleclass)\n    VALUE self;\n    ITypeLib *pTypeLib;\n    VALUE oleclass;\n{\n    \n    long count;\n    int i;\n    HRESULT hr;\n    BSTR bstr;\n    VALUE typelib;\n    ITypeInfo *pTypeInfo;\n\n    VALUE found = Qfalse;\n  \n    count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);\n    for (i = 0; i < count && found == Qfalse; i++) {\n        hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);\n        if (FAILED(hr))\n            continue;\n        hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,\n                                                &bstr, NULL, NULL, NULL);\n        if (FAILED(hr)) \n            continue;\n        typelib = WC2VSTR(bstr);\n        if (rb_str_cmp(oleclass, typelib) == 0) {\n            oletype_set_member(self, pTypeInfo, typelib);\n            found = Qtrue;\n        }\n        OLE_RELEASE(pTypeInfo);\n    }\n    return found;\n}\n\n/*\n * Document-class: WIN32OLE_TYPE\n *\n *   <code>WIN32OLE_TYPE</code> objects represent OLE type libarary information.\n */\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE.new(typelib, ole_class) -> WIN32OLE_TYPE object\n *\n *  Returns a new WIN32OLE_TYPE object.\n *  The first argument <i>typelib</i> specifies OLE type library name.\n *  The second argument specifies OLE class name.\n *\n *      WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') \n *          # => WIN32OLE_TYPE object of Application class of Excel. \n */\nstatic VALUE\nfoletype_initialize(self, typelib, oleclass)\n    VALUE self;\n    VALUE typelib;\n    VALUE oleclass;\n{\n    VALUE file;\n    OLECHAR * pbuf;\n    ITypeLib *pTypeLib;\n    HRESULT hr;\n\n    Check_SafeStr(oleclass);\n    Check_SafeStr(typelib);\n    file = typelib_file(typelib);\n    if (file == Qnil) {\n        file = typelib;\n    }\n    pbuf = ole_mb2wc(StringValuePtr(file), -1);\n    hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to LoadTypeLibEx\");\n    SysFreeString(pbuf);\n    if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {\n        OLE_RELEASE(pTypeLib);\n        rb_raise(eWIN32OLE_RUNTIME_ERROR, \"not found `%s` in `%s`\",\n                 StringValuePtr(oleclass), StringValuePtr(typelib));\n    }\n    OLE_RELEASE(pTypeLib);\n    return self;\n}\n\n/*\n * call-seq:\n *    WIN32OLE_TYPE#name #=> OLE type name\n *\n * Returns OLE type name.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') \n *    puts tobj.name  # => Application\n */\nstatic VALUE\nfoletype_name(self)\n    VALUE self;\n{\n    return rb_ivar_get(self, rb_intern(\"name\"));\n}\n\nstatic VALUE\nole_ole_type(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    VALUE type = Qnil;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if(FAILED(hr)){\n        return type;\n    }\n    switch(pTypeAttr->typekind) {\n    case TKIND_ENUM:\n        type = rb_str_new2(\"Enum\");\n        break;\n    case TKIND_RECORD:\n        type = rb_str_new2(\"Record\");\n        break;\n    case TKIND_MODULE:\n        type = rb_str_new2(\"Module\");\n        break;\n    case TKIND_INTERFACE:\n        type = rb_str_new2(\"Interface\");\n        break;\n    case TKIND_DISPATCH:\n        type = rb_str_new2(\"Dispatch\");\n        break;\n    case TKIND_COCLASS:\n        type = rb_str_new2(\"Class\");\n        break;\n    case TKIND_ALIAS:\n        type = rb_str_new2(\"Alias\");\n        break;\n    case TKIND_UNION:\n        type = rb_str_new2(\"Union\");\n        break;\n    case TKIND_MAX:\n        type = rb_str_new2(\"Max\");\n        break;\n    default:\n        type = Qnil;\n        break;\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return type;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#ole_type #=> OLE type string.\n * \n *  returns type of OLE class.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') \n *    puts tobj.ole_type  # => Class\n */\nstatic VALUE\nfoletype_ole_type(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_ole_type(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_guid(pTypeInfo) \n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    int len;\n    OLECHAR bstr[80];\n    VALUE guid = Qnil;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) \n        return guid;\n    len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));\n    if (len > 3) {\n        guid = ole_wc2vstr(bstr, FALSE);\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return guid;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#guid  #=> GUID\n * \n *  Returns GUID.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application') \n *    puts tobj.guid  # => {00024500-0000-0000-C000-000000000046}\n */\nstatic VALUE\nfoletype_guid(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_guid(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_progid(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    OLECHAR *pbuf;\n    VALUE progid = Qnil;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) \n        return progid;\n    hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);\n    if (SUCCEEDED(hr)) { \n        progid = ole_wc2vstr(pbuf, FALSE);\n        CoTaskMemFree(pbuf);\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return progid;\n}\n\n/*\n * call-seq:\n *    WIN32OLE_TYPE#progid  #=> ProgID\n * \n * Returns ProgID if it exists. If not found, then returns nil.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')\n *    puts tobj.progid  # =>   Excel.Application.9\n */\nstatic VALUE\nfoletype_progid(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_progid(ptype->pTypeInfo);\n}\n\n\nstatic VALUE\nole_type_visible(pTypeInfo) \n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    VALUE visible;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) \n        return Qtrue;\n    if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {\n        visible = Qfalse;\n    } else {\n        visible = Qtrue;\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return visible;\n}\n\n/*\n *  call-seq:\n *    WIN32OLE_TYPE#visible  #=> true or false\n * \n *  Returns true if the OLE class is public.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')\n *    puts tobj.visible  # => true\n */\nstatic VALUE\nfoletype_visible(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_visible(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_major_version(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    VALUE ver;\n    TYPEATTR *pTypeAttr;\n    HRESULT hr;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    ver = INT2FIX(pTypeAttr->wMajorVerNum);\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return ver;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#major_version\n * \n *  Returns major version.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')\n *     puts tobj.major_version # => 8\n */\nstatic VALUE\nfoletype_major_version(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_major_version(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_minor_version(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    VALUE ver;\n    TYPEATTR *pTypeAttr;\n    HRESULT hr;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    ver = INT2FIX(pTypeAttr->wMinorVerNum);\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return ver;\n}\n\n/*\n *  call-seq:\n *    WIN32OLE_TYPE#minor_version #=> OLE minor version\n * \n *  Returns minor version.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')\n *     puts tobj.minor_version # => 2\n */\nstatic VALUE\nfoletype_minor_version(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_minor_version(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_typekind(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    VALUE typekind;\n    TYPEATTR *pTypeAttr;\n    HRESULT hr;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    typekind = INT2FIX(pTypeAttr->typekind);\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return typekind;\n}\n\n/*\n *  call-seq:\n *    WIN32OLE_TYPE#typekind #=> number of type.\n * \n *  Returns number which represents type.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')\n *    puts tobj.typekind # => 4\n *\n */\nstatic VALUE \nfoletype_typekind(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_typekind(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_helpstring(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    BSTR bhelpstr;\n    hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);\n    if(FAILED(hr)) {\n        return Qnil;\n    }\n    return WC2VSTR(bhelpstr);\n}\n\n/*\n *  call-seq:\n *    WIN32OLE_TYPE#helpstring #=> help string.\n * \n *  Returns help string.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')\n *    puts tobj.helpstring # => Web Browser interface\n */\nstatic VALUE \nfoletype_helpstring(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_helpstring(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_src_type(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    VALUE alias = Qnil;\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr))\n        return alias;\n    if(pTypeAttr->typekind != TKIND_ALIAS) {\n        OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n        return alias;\n    }\n    alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return alias;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#src_type #=> OLE source class\n * \n *  Returns source class when the OLE class is 'Alias'.\n *     tobj =  WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType')\n *     puts tobj.src_type # => I4\n *\n */\nstatic VALUE\nfoletype_src_type(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_src_type(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_helpfile(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    BSTR bhelpfile;\n    hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);\n    if(FAILED(hr)) {\n        return Qnil;\n    }\n    return WC2VSTR(bhelpfile);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#helpfile\n * \n *  Returns helpfile path. If helpfile is not found, then returns nil.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')\n *     puts tobj.helpfile # => C:\\...\\VBAXL9.CHM\n *\n */\nstatic VALUE\nfoletype_helpfile(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_helpfile(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_type_helpcontext(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    DWORD helpcontext;\n    hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, \n                               &helpcontext, NULL);\n    if(FAILED(hr))\n        return Qnil;\n    return INT2FIX(helpcontext);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#helpcontext\n * \n *  Returns helpcontext. If helpcontext is not found, then returns nil.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')\n *     puts tobj.helpfile # => 131185\n */\nstatic VALUE\nfoletype_helpcontext(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_type_helpcontext(ptype->pTypeInfo);\n}\n\nstatic VALUE\nole_variables(pTypeInfo)\n    ITypeInfo *pTypeInfo;\n{\n    HRESULT hr;\n    TYPEATTR *pTypeAttr;\n    WORD i;\n    UINT len;\n    BSTR bstr;\n    char *pstr;\n    VARDESC *pVarDesc;\n    struct olevariabledata *pvar;\n    VALUE var;\n    VALUE variables = rb_ary_new();\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) {\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetTypeAttr\");\n    }\n    \n    for(i = 0; i < pTypeAttr->cVars; i++) {\n        hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);\n        if(FAILED(hr))\n            continue;\n        len = 0;\n        pstr = NULL;\n        hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,\n                                         1, &len);\n        if(FAILED(hr) || len == 0 || !bstr)\n            continue;\n\n        var = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,\n                               0,olevariable_free,pvar);\n        pvar->pTypeInfo = pTypeInfo;\n        OLE_ADDREF(pTypeInfo);\n        pvar->index = i;\n        rb_ivar_set(var, rb_intern(\"name\"), WC2VSTR(bstr));\n        rb_ary_push(variables, var);\n\n        pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n        pVarDesc = NULL;\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return variables;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#variables\n * \n *  Returns array of WIN32OLE_VARIABLE objects which represent variables \n *  defined in OLE class.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *     vars = tobj.variables\n *     vars.each do |v|\n *       puts \"#{v.name} = #{v.value}\"\n *     end\n *     \n *     The result of above sample script is follows:\n *       xlChart = -4109\n *       xlDialogSheet = -4116\n *       xlExcel4IntlMacroSheet = 4\n *       xlExcel4MacroSheet = 3\n *       xlWorksheet = -4167\n *\n */\nstatic VALUE\nfoletype_variables(self)\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_variables(ptype->pTypeInfo);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects.\n * \n *  Returns array of WIN32OLE_METHOD objects which represent OLE method defined in \n *  OLE type library.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')\n *    methods = tobj.ole_methods.collect{|m|\n *      m.name\n *    }                                       \n *    # => ['Activate', 'Copy', 'Delete',....]\n */\nstatic VALUE\nfoletype_methods(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    struct oletypedata *ptype;\n    Data_Get_Struct(self, struct oletypedata, ptype);\n    return ole_methods_from_typeinfo(ptype->pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);\n}\n\n/*\n * Document-class: WIN32OLE_VARIABLE\n *\n *   <code>WIN32OLE_VARIABLE</code> objects represent OLE variable information.\n */\n\n/*\n *  call-seq:\n *     WIN32OLE_VARIABLE#name\n * \n *  Returns the name of variable.\n *\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *     variables = tobj.variables\n *     variables.each do |variable|\n *       puts \"#{variable.name}\"\n *     end\n *\n *     The result of above script is following:\n *       xlChart\n *       xlDialogSheet\n *       xlExcel4IntlMacroSheet\n *       xlExcel4MacroSheet\n *       xlWorksheet\n *\n */\nstatic VALUE\nfolevariable_name(self)\n    VALUE self;\n{\n    return rb_ivar_get(self, rb_intern(\"name\"));\n}\n\nstatic VALUE\nole_variable_ole_type(pTypeInfo, var_index)\n    ITypeInfo *pTypeInfo;\n    UINT var_index;\n{\n    VARDESC *pVarDesc;\n    HRESULT hr;\n    VALUE type;\n    hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetVarDesc\");\n    type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);\n    pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n    return type;\n}\n\n/*\n *   call-seq:\n *      WIN32OLE_VARIABLE#ole_type\n * \n *   Returns OLE type string.\n *\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *     variables = tobj.variables\n *     variables.each do |variable|\n *       puts \"#{variable.ole_type} #{variable.name}\"\n *     end\n *\n *     The result of above script is following:\n *       INT xlChart\n *       INT xlDialogSheet\n *       INT xlExcel4IntlMacroSheet\n *       INT xlExcel4MacroSheet\n *       INT xlWorksheet\n *\n */\nstatic VALUE\nfolevariable_ole_type(self)\n    VALUE self;\n{\n    struct olevariabledata *pvar;\n    Data_Get_Struct(self, struct olevariabledata, pvar);\n    return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);\n}\n\nstatic VALUE\nole_variable_ole_type_detail(pTypeInfo, var_index)\n    ITypeInfo *pTypeInfo;\n    UINT var_index;\n{\n    VARDESC *pVarDesc;\n    HRESULT hr;\n    VALUE type = rb_ary_new();\n    hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);\n    if (FAILED(hr))\n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetVarDesc\");\n    ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);\n    pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n    return type;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_VARIABLE#ole_type_detail\n * \n *  Returns detail information of type. The information is array of type.\n *\n *     tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS')\n *     variable = tobj.variables.find {|variable| variable.name == 'lFlags'}\n *     tdetail  = variable.ole_type_detail\n *     p tdetail # => [\"USERDEFINED\", \"CONST_D3DCLIPSTATUSFLAGS\"]\n *\n */\nstatic VALUE\nfolevariable_ole_type_detail(self)\n    VALUE self;\n{\n    struct olevariabledata *pvar;\n    Data_Get_Struct(self, struct olevariabledata, pvar);\n    return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);\n}\n\nstatic VALUE\nole_variable_value(pTypeInfo, var_index)\n    ITypeInfo *pTypeInfo;\n    UINT var_index;\n{\n    VARDESC *pVarDesc;\n    HRESULT hr;\n    VALUE val = Qnil;\n    hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);\n    if (FAILED(hr))\n        return Qnil;\n    if(pVarDesc->varkind == VAR_CONST)\n        val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));\n    pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n    return val;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_VARIABLE#value\n * \n *  Returns value if value is exists. If the value does not exist, \n *  this method returns nil.\n *\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *     variables = tobj.variables\n *     variables.each do |variable|\n *       puts \"#{variable.name} = #{variable.value}\"\n *     end\n *\n *     The result of above script is following:\n *       xlChart = -4109\n *       xlDialogSheet = -4116\n *       xlExcel4IntlMacroSheet = 4\n *       xlExcel4MacroSheet = 3\n *       xlWorksheet = -4167\n *\n */    \nstatic VALUE\nfolevariable_value(self)\n    VALUE self;\n{\n    struct olevariabledata *pvar;\n    Data_Get_Struct(self, struct olevariabledata, pvar);\n    return ole_variable_value(pvar->pTypeInfo, pvar->index);\n}\n\nstatic VALUE\nole_variable_visible(pTypeInfo, var_index)\n    ITypeInfo *pTypeInfo;\n    UINT var_index;\n{\n    VARDESC *pVarDesc;\n    HRESULT hr;\n    VALUE visible = Qfalse;\n    hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);\n    if (FAILED(hr))\n        return visible;\n    if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |\n                                 VARFLAG_FRESTRICTED |\n                                 VARFLAG_FNONBROWSABLE))) {\n        visible = Qtrue;\n    }\n    pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n    return visible;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_VARIABLE#visible?\n * \n *  Returns true if the variable is public.\n *\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *     variables = tobj.variables\n *     variables.each do |variable|\n *       puts \"#{variable.name} #{variable.visible?}\"\n *     end\n *\n *     The result of above script is following:\n *       xlChart true\n *       xlDialogSheet true\n *       xlExcel4IntlMacroSheet true\n *       xlExcel4MacroSheet true\n *       xlWorksheet true\n *       \n */\nstatic VALUE\nfolevariable_visible(self)\n    VALUE self;\n{\n    struct olevariabledata *pvar;\n    Data_Get_Struct(self, struct olevariabledata, pvar);\n    return ole_variable_visible(pvar->pTypeInfo, pvar->index);\n}\n\nstatic VALUE\nole_variable_kind(pTypeInfo, var_index)\n    ITypeInfo *pTypeInfo;\n    UINT var_index;\n{\n    VARDESC *pVarDesc;\n    HRESULT hr;\n    VALUE kind = rb_str_new2(\"UNKNOWN\");\n    hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);\n    if (FAILED(hr))\n        return kind;\n    switch(pVarDesc->varkind) {\n    case VAR_PERINSTANCE:\n        kind = rb_str_new2(\"PERINSTANCE\");\n        break;\n    case VAR_STATIC:\n        kind = rb_str_new2(\"STATIC\");\n        break;\n    case VAR_CONST:\n        kind = rb_str_new2(\"CONSTANT\");\n        break;\n    case VAR_DISPATCH:\n        kind = rb_str_new2(\"DISPATCH\");\n        break;\n    default:\n        break;\n    }\n    pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n    return kind;\n}\n\n/*\n * call-seq:\n *   WIN32OLE_VARIABLE#variable_kind\n * \n * Returns variable kind string.\n *\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *    variables = tobj.variables\n *    variables.each do |variable|\n *      puts \"#{variable.name} #{variable.variable_kind}\"\n *    end\n *\n *    The result of above script is following:\n *      xlChart CONSTANT\n *      xlDialogSheet CONSTANT\n *      xlExcel4IntlMacroSheet CONSTANT\n *      xlExcel4MacroSheet CONSTANT\n *      xlWorksheet CONSTANT\n */\nstatic VALUE\nfolevariable_variable_kind(self)\n    VALUE self;\n{\n    struct olevariabledata *pvar;\n    Data_Get_Struct(self, struct olevariabledata, pvar);\n    return ole_variable_kind(pvar->pTypeInfo, pvar->index);\n}\n\nstatic VALUE\nole_variable_varkind(pTypeInfo, var_index)\n    ITypeInfo *pTypeInfo;\n    UINT var_index;\n{\n    VARDESC *pVarDesc;\n    HRESULT hr;\n    VALUE kind = Qnil;\n    hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);\n    if (FAILED(hr))\n        return kind;\n    pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);\n    kind = INT2FIX(pVarDesc->varkind);    \n    return kind;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_VARIABLE#varkind\n * \n *  Returns the number which represents variable kind.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')\n *    variables = tobj.variables\n *    variables.each do |variable|\n *      puts \"#{variable.name} #{variable.varkind}\"\n *    end\n *\n *    The result of above script is following:\n *       xlChart 2\n *       xlDialogSheet 2\n *       xlExcel4IntlMacroSheet 2\n *       xlExcel4MacroSheet 2\n *       xlWorksheet 2\n */\nstatic VALUE\nfolevariable_varkind(self)\n    VALUE self;\n{\n    struct olevariabledata *pvar;\n    Data_Get_Struct(self, struct olevariabledata, pvar);\n    return ole_variable_varkind(pvar->pTypeInfo, pvar->index);\n}\n\n/*\n * Document-class: WIN32OLE_METHOD\n *\n *   <code>WIN32OLE_METHOD</code> objects represent OLE method information.\n */\n\nstatic VALUE\nolemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, index, name)\n    VALUE self;\n    ITypeInfo *pTypeInfo;\n    ITypeInfo *pOwnerTypeInfo;\n    int index;\n    VALUE name;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    pmethod->pTypeInfo = pTypeInfo;\n    OLE_ADDREF(pTypeInfo);\n    pmethod->pOwnerTypeInfo = pOwnerTypeInfo;\n    if(pOwnerTypeInfo) OLE_ADDREF(pOwnerTypeInfo);\n    pmethod->index = index;\n    rb_ivar_set(self, rb_intern(\"name\"), name);\n    return self;\n}\n\nstatic VALUE\nfolemethod_s_allocate(klass)\n    VALUE klass;\n{\n    struct olemethoddata *pmethod;\n    VALUE obj;\n    obj = Data_Make_Struct(klass, \n                           struct olemethoddata,\n                           0, olemethod_free, pmethod);\n    pmethod->pTypeInfo = NULL;\n    pmethod->pOwnerTypeInfo = NULL;\n    pmethod->index = 0;\n    return obj;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD.new(ole_type,  method) -> WIN32OLE_METHOD object\n * \n *  Returns a new WIN32OLE_METHOD object which represents the information\n *  about OLE method.\n *  The first argument <i>ole_type</i> specifies WIN32OLE_TYPE object.\n *  The second argument <i>method</i> specifies OLE method name defined OLE class\n *  which represents WIN32OLE_TYPE object.\n *\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n */\nstatic VALUE\nfolemethod_initialize(self, oletype, method)\n    VALUE self;\n    VALUE oletype;\n    VALUE method;\n{\n    struct oletypedata *ptype;\n    VALUE obj = Qnil;\n    if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {\n        Check_SafeStr(method);\n        Data_Get_Struct(oletype, struct oletypedata, ptype);\n        obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method);\n        if (obj == Qnil) {\n            rb_raise(eWIN32OLE_RUNTIME_ERROR, \"not found %s\",\n                     StringValuePtr(method));\n        }\n    }\n    else {\n        rb_raise(rb_eTypeError, \"1st argument should be WIN32OLE_TYPE object\");\n    }\n    return obj;\n}\n\n/*\n *  call-seq\n *     WIN32OLE_METHOD#name\n *\n *  Returns the name of the method.\n *\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     puts method.name # => SaveAs\n *     \n */\nstatic VALUE\nfolemethod_name(self)\n    VALUE self;\n{\n    return rb_ivar_get(self, rb_intern(\"name\"));\n}\n\nstatic VALUE\nole_method_return_type(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE type;\n\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr)) \n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetFuncDesc\");\n    \n    type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return type;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#return_type\n * \n *  Returns string of return value type of method.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.return_type # => Workbook\n *\n */\nstatic VALUE\nfolemethod_return_type(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_return_vtype(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE vt;\n\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr)) \n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetFuncDesc\");\n    \n    vt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return vt;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#return_vtype\n * \n *  Returns number of return value type of method.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.return_vtype # => 26\n *\n */\nstatic VALUE\nfolemethod_return_vtype(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_return_type_detail(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE type = rb_ary_new();\n\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr)) \n        return type;\n    \n    ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return type;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#return_type_detail\n * \n *  Returns detail information of return value type of method.\n *  The information is array.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     p method.return_type_detail # => [\"PTR\", \"USERDEFINED\", \"Workbook\"]\n */\nstatic VALUE\nfolemethod_return_type_detail(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_invkind(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE invkind;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if(FAILED(hr)) \n        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, \"failed to GetFuncDesc\");\n    invkind = INT2FIX(pFuncDesc->invkind);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return invkind;\n}\n\nstatic VALUE\nole_method_invoke_kind(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    WORD method_index;\n{\n    VALUE type = rb_str_new2(\"UNKNOWN\");\n    VALUE invkind = ole_method_invkind(pTypeInfo, method_index);\n    if((FIX2INT(invkind) & INVOKE_PROPERTYGET) &&\n       (FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {\n        type = rb_str_new2(\"PROPERTY\");\n    } else if(FIX2INT(invkind) & INVOKE_PROPERTYGET) {\n        type =  rb_str_new2(\"PROPERTYGET\");\n    } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUT) {\n        type = rb_str_new2(\"PROPERTYPUT\");\n    } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {\n        type = rb_str_new2(\"PROPERTYPUTREF\");\n    } else if(FIX2INT(invkind) & INVOKE_FUNC) {\n        type = rb_str_new2(\"FUNC\");\n    }\n    return type;\n}\n\n/*\n *   call-seq:\n *      WIN32OLE_MTHOD#invkind\n * \n *   Returns the method invoke kind. \n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.invkind # => 1\n *\n */\nstatic VALUE\nfolemethod_invkind(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#invoke_kind\n * \n *  Returns the method kind string. The string is \"UNKNOWN\" or \"PROPERTY\" \n *  or \"PROPERTY\" or \"PROPERTYGET\" or \"PROPERTYPUT\" or \"PROPERTYPPUTREF\" \n *  or \"FUNC\".\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.invoke_kind # => \"FUNC\"\n */\nstatic VALUE\nfolemethod_invoke_kind(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_visible(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE visible;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if(FAILED(hr))\n        return Qfalse;\n    if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |\n                                 FUNCFLAG_FHIDDEN |\n                                 FUNCFLAG_FNONBROWSABLE)) {\n        visible = Qfalse;\n    } else {\n        visible = Qtrue;\n    }\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return visible;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#visible?\n * \n *  Returns true if the method is public.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.visible? # => true\n */\nstatic VALUE\nfolemethod_visible(self) \n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_visible(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_event(pTypeInfo, method_index, method_name)\n    ITypeInfo *pTypeInfo;\n    WORD method_index;\n    VALUE method_name;\n{\n    TYPEATTR *pTypeAttr;\n    HRESULT hr;\n    WORD i;\n    int flags;\n    HREFTYPE href;\n    ITypeInfo *pRefTypeInfo;\n    FUNCDESC *pFuncDesc;\n    BSTR bstr;\n    VALUE name;\n    VALUE event = Qfalse;\n    \n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) \n        return event;\n    if(pTypeAttr->typekind != TKIND_COCLASS) {\n        pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);\n        return event;\n    }\n    for (i = 0; i < pTypeAttr->cImplTypes; i++) {\n        hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);\n        if (FAILED(hr))\n            continue;\n\n        if (flags & IMPLTYPEFLAG_FSOURCE) {\n            hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,\n                                                         i, &href);\n            if (FAILED(hr))\n                continue;\n            hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,\n                                                   href, &pRefTypeInfo);\n            if (FAILED(hr))\n                continue;\n            hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index, \n                                                   &pFuncDesc);\n            if (FAILED(hr)) {\n                OLE_RELEASE(pRefTypeInfo);\n                continue;\n            }\n\n            hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo, \n                                                        pFuncDesc->memid,\n                                                        &bstr, NULL, NULL, NULL);\n            if (FAILED(hr)) {\n                pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);\n                OLE_RELEASE(pRefTypeInfo);\n                continue;\n            }\n\n            name = WC2VSTR(bstr);\n            pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);\n            OLE_RELEASE(pRefTypeInfo);\n            if (rb_str_cmp(method_name, name) == 0) {\n                event = Qtrue;\n                break;\n            }\n        }\n    }\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    return event;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#event?\n * \n *  Returns true if the method is event.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')\n *     puts method.event? # => true\n *\n */\nstatic VALUE\nfolemethod_event(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    if (!pmethod->pOwnerTypeInfo)\n        return Qfalse;\n    return ole_method_event(pmethod->pOwnerTypeInfo, \n                            pmethod->index,\n                            rb_ivar_get(self, rb_intern(\"name\")));\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#event_interface\n *\n *  Returns event interface name if the method is event.\n *    tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *    method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')\n *    puts method.event_interface # =>  WorkbookEvents\n */\nstatic VALUE\nfolemethod_event_interface(self)\n    VALUE self;\n{\n    BSTR name;\n    struct olemethoddata *pmethod;\n    HRESULT hr;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    if(folemethod_event(self) == Qtrue) {\n        hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);\n        if(SUCCEEDED(hr))\n            return WC2VSTR(name);\n    }\n    return Qnil;\n}\n\nstatic VALUE\nole_method_docinfo_from_type(pTypeInfo, method_index, name, helpstr,\n                             helpcontext, helpfile)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n    BSTR *name;\n    BSTR *helpstr;\n    DWORD *helpcontext;\n    BSTR *helpfile;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return hr;\n    hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,\n                                             name, helpstr,\n                                             helpcontext, helpfile);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return hr;\n}\n\nstatic VALUE\nole_method_helpstring(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    HRESULT hr;\n    BSTR bhelpstring;\n    hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,\n                                      NULL, NULL); \n    if (FAILED(hr))\n        return Qnil;\n    return WC2VSTR(bhelpstring);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#helpstring\n *\n *  Returns help string of OLE method. If the help string is not found, \n *  then the method returns nil.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')\n *     method = WIN32OLE_METHOD.new(tobj, 'Navigate')\n *     puts method.helpstring # => Navigates to a URL or file.\n *\n */\nstatic VALUE\nfolemethod_helpstring(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_helpfile(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    HRESULT hr;\n    BSTR bhelpfile;\n    hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,\n                                      NULL, &bhelpfile); \n    if (FAILED(hr))\n        return Qnil;\n    return WC2VSTR(bhelpfile);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#helpfile\n * \n *  Returns help file. If help file is not found, then \n *  the method returns nil.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.helpfile # => C:\\...\\VBAXL9.CHM\n */\nstatic VALUE\nfolemethod_helpfile(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n\n    return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_helpcontext(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    HRESULT hr;\n    DWORD helpcontext = 0;\n    hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,\n                                      &helpcontext, NULL); \n    if (FAILED(hr))\n        return Qnil;\n    return INT2FIX(helpcontext);\n}\n\n/* \n *  call-seq:\n *     WIN32OLE_METHOD#helpcontext\n * \n *  Returns help context.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.helpcontext # => 65717\n */\nstatic VALUE\nfolemethod_helpcontext(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_dispid(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE dispid = Qnil;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return dispid;\n    dispid = INT2NUM(pFuncDesc->memid); \n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return dispid;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#dispid\n * \n *  Returns dispatch ID.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.dispid # => 181\n */\nstatic VALUE\nfolemethod_dispid(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_offset_vtbl(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE offset_vtbl = Qnil;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return offset_vtbl;\n    offset_vtbl = INT2FIX(pFuncDesc->oVft); \n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return offset_vtbl;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#offset_vtbl\n * \n *  Returns the offset ov VTBL.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')\n *     method = WIN32OLE_METHOD.new(tobj, 'Add')\n *     puts method.offset_vtbl # => 40\n */\nstatic VALUE\nfolemethod_offset_vtbl(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_size_params(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE size_params = Qnil;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return size_params;\n    size_params = INT2FIX(pFuncDesc->cParams);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return size_params;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#size_params\n * \n *  Returns the size of arguments of the method.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     puts method.size_params # => 11\n *  \n */\nstatic VALUE\nfolemethod_size_params(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_size_opt_params(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE size_opt_params = Qnil;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return size_opt_params;\n    size_opt_params = INT2FIX(pFuncDesc->cParamsOpt);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return size_opt_params;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#size_opt_params\n * \n *  Returns the size of optional parameters.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     puts method.size_opt_params # => 4\n */\nstatic VALUE\nfolemethod_size_opt_params(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);\n}\n\nstatic VALUE\nole_method_params(pTypeInfo, method_index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    BSTR *bstrs;\n    UINT len, i;\n    struct oleparamdata *pparam;\n    VALUE param;\n    VALUE params = rb_ary_new();\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr)) \n        return params;\n\n    len = 0;\n    bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);\n    hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid, \n                                     bstrs, pFuncDesc->cParams + 1,\n                                     &len);\n    if (FAILED(hr)) {\n        pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n        return params;\n    }\n    SysFreeString(bstrs[0]);\n    if (pFuncDesc->cParams > 0) {\n        for(i = 1; i < len; i++) {\n            param = Data_Make_Struct(cWIN32OLE_PARAM, struct oleparamdata, 0,\n                                     oleparam_free, pparam);\n            pparam->pTypeInfo = pTypeInfo;\n            OLE_ADDREF(pTypeInfo);\n            pparam->method_index = method_index;\n            pparam->index = i - 1;\n            rb_ivar_set(param, rb_intern(\"name\"), WC2VSTR(bstrs[i]));\n            rb_ary_push(params, param);\n         }\n     }\n     pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n     return params;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_METHOD#params\n * \n *  returns array of WIN32OLE_PARAM object corresponding with method parameters.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     p method.params # => [Filename, FileFormat, Password, WriteResPassword, \n *                           ReadOnlyRecommended, CreateBackup, AccessMode, \n *                           ConflictResolution, AddToMru, TextCodepage, \n *                           TextVisualLayout]\n */\nstatic VALUE\nfolemethod_params(self)\n    VALUE self;\n{\n    struct olemethoddata *pmethod;\n    Data_Get_Struct(self, struct olemethoddata, pmethod);\n    return ole_method_params(pmethod->pTypeInfo, pmethod->index);\n}\n\n/*\n * Document-class: WIN32OLE_PARAM\n *\n *   <code>WIN32OLE_PARAM</code> objects represent param information of \n *   the OLE method.\n */\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#name\n * \n *  Returns name.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     param1 = method.params[0]\n *     puts param1.name # => Filename\n */\nstatic VALUE\nfoleparam_name(self)\n    VALUE self;\n{\n    return rb_ivar_get(self, rb_intern(\"name\"));\n}\n\nstatic VALUE\nole_param_ole_type(pTypeInfo, method_index, index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n    UINT index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE type = rb_str_new2(\"UNKNOWN\");\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return type;\n    type = ole_typedesc2val(pTypeInfo, \n                            &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return type;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#ole_type\n *\n *  Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method).\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     param1 = method.params[0]\n *     puts param1.ole_type # => VARIANT\n */\nstatic VALUE \nfoleparam_ole_type(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index, \n                              pparam->index);\n}\n\nstatic VALUE\nole_param_ole_type_detail(pTypeInfo, method_index, index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n    UINT index;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE typedetail = rb_ary_new();\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return typedetail;\n    ole_typedesc2val(pTypeInfo, \n                     &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail);\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return typedetail;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#ole_type_detail\n *\n *  Returns detail information of type of argument.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction')\n *     method = WIN32OLE_METHOD.new(tobj, 'SumIf')\n *     param1 = method.params[0]\n *     p param1.ole_type_detail # => [\"PTR\", \"USERDEFINED\", \"Range\"]\n */\nstatic VALUE \nfoleparam_ole_type_detail(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index, \n                                     pparam->index);\n}\n\nstatic VALUE\nole_param_flag_mask(pTypeInfo, method_index, index, mask)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n    UINT index;\n    USHORT mask;\n{\n    FUNCDESC *pFuncDesc;\n    HRESULT hr;\n    VALUE ret = Qfalse;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if(FAILED(hr)) \n        return ret;\n    if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask) \n        ret = Qtrue;\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return ret;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#input?\n * \n *  Returns true if the parameter is input.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     param1 = method.params[0]\n *     puts param1.input? # => true\n */\nstatic VALUE foleparam_input(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, \n                               pparam->index, PARAMFLAG_FIN);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE#output?\n * \n *  Returns true if argument is output.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents')\n *     method = WIN32OLE_METHOD.new(tobj, 'NewWindow')\n *     method.params.each do |param|\n *       puts \"#{param.name} #{param.output?}\"\n *     end\n *\n *     The result of above script is following:\n *       URL false\n *       Flags false\n *       TargetFrameName false\n *       PostData false\n *       Headers false\n *       Processed true\n */\nstatic VALUE foleparam_output(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, \n                               pparam->index, PARAMFLAG_FOUT);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#optional?\n * \n *  Returns true if argument is optional.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     param1 = method.params[0]\n *     puts \"#{param1.name} #{param1.optional?}\" # => Filename true\n */\nstatic VALUE foleparam_optional(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, \n                               pparam->index, PARAMFLAG_FOPT);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#retval?\n *\n *  Returns true if argument is return value.\n *     tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', \n *                              'DirectPlayLobbyConnection')\n *     method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName')\n *     param = method.params[0]\n *     puts \"#{param.name} #{param.retval?}\"  # => name true\n */\nstatic VALUE foleparam_retval(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index, \n                               pparam->index, PARAMFLAG_FRETVAL);\n}\n\nstatic VALUE\nole_param_default(pTypeInfo, method_index, index)\n    ITypeInfo *pTypeInfo;\n    UINT method_index;\n    UINT index;\n{\n    FUNCDESC *pFuncDesc;\n    ELEMDESC *pElemDesc;\n    PARAMDESCEX * pParamDescEx;\n    HRESULT hr;\n    USHORT wParamFlags;\n    USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT;\n    VALUE defval = Qnil;\n    hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);\n    if (FAILED(hr))\n        return defval;\n    pElemDesc = &pFuncDesc->lprgelemdescParam[index]; \n    wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags;\n    if ((wParamFlags & mask) == mask) {\n         pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex;\n         defval = ole_variant2val(&pParamDescEx->varDefaultValue);\n    }\n    pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);\n    return defval;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_PARAM#default\n * \n *  Returns default value. If the default value does not exist, \n *  this method returns nil.\n *     tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')\n *     method = WIN32OLE_METHOD.new(tobj, 'SaveAs')\n *     method.params.each do |param|\n *       if param.default\n *         puts \"#{param.name} (= #{param.default})\"\n *       else\n *         puts \"#{param}\"\n *       end\n *     end\n *\n *     The above script result is following:\n *         Filename\n *         FileFormat\n *         Password\n *         WriteResPassword\n *         ReadOnlyRecommended\n *         CreateBackup\n *         AccessMode (= 1)\n *         ConflictResolution\n *         AddToMru\n *         TextCodepage\n *         TextVisualLayout\n */\nstatic VALUE foleparam_default(self)\n    VALUE self;\n{\n    struct oleparamdata *pparam;\n    Data_Get_Struct(self, struct oleparamdata, pparam);\n    return ole_param_default(pparam->pTypeInfo, pparam->method_index,\n                             pparam->index);\n}\n\n\n/*\n * Document-class: WIN32OLE_EVENT\n *\n *   <code>WIN32OLE_EVENT</code> objects controls OLE event.\n */\n\nstatic IEventSinkVtbl vtEventSink;\nstatic BOOL g_IsEventSinkVtblInitialized = FALSE;\n\nvoid EVENTSINK_Destructor(PIEVENTSINKOBJ);\n\nSTDMETHODIMP\nEVENTSINK_QueryInterface(\n    PEVENTSINK pEV,\n    REFIID     iid,\n    LPVOID*    ppv\n    ) {\n    if (IsEqualIID(iid, &IID_IUnknown) ||\n        IsEqualIID(iid, &IID_IDispatch) ||\n        IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) {\n        *ppv = pEV;\n    }\n    else {\n        *ppv = NULL;\n        return E_NOINTERFACE;\n    }\n    ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);\n    return NOERROR;\n}\n\nSTDMETHODIMP_(ULONG)\nEVENTSINK_AddRef(\n    PEVENTSINK pEV\n    ){\n    PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;\n    return ++pEVObj->m_cRef;\n}\n\nSTDMETHODIMP_(ULONG) EVENTSINK_Release(\n    PEVENTSINK pEV\n    ) {\n    PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;\n    --pEVObj->m_cRef;\n    if(pEVObj->m_cRef != 0)\n        return pEVObj->m_cRef;\n    EVENTSINK_Destructor(pEVObj);\n    return 0;\n}\n\nSTDMETHODIMP EVENTSINK_GetTypeInfoCount(\n    PEVENTSINK pEV,\n    UINT *pct\n    ) {\n    *pct = 0;\n    return NOERROR;\n}\n\nSTDMETHODIMP EVENTSINK_GetTypeInfo(\n    PEVENTSINK pEV,\n    UINT info,\n    LCID lcid,\n    ITypeInfo **pInfo\n    ) {\n    *pInfo = NULL;\n    return DISP_E_BADINDEX;\n}\n\nSTDMETHODIMP EVENTSINK_GetIDsOfNames(\n    PEVENTSINK pEV,\n    REFIID riid,\n    OLECHAR **szNames,\n    UINT cNames,\n    LCID lcid,\n    DISPID *pDispID\n    ) {\n    return DISP_E_UNKNOWNNAME;\n}\n\nstatic long\nole_search_event_at(ary, ev)\n    VALUE ary;\n    VALUE ev;\n{\n    VALUE event;\n    VALUE def_event;\n    VALUE event_name;\n    long i, len; \n    long ret = -1;\n    def_event = Qnil;\n    len = RARRAY(ary)->len;\n    for(i = 0; i < len; i++) {\n        event = rb_ary_entry(ary, i);\n        event_name = rb_ary_entry(event, 1);\n        if(NIL_P(event_name) && NIL_P(ev)) {\n            ret = i;\n            break;\n        }\n        else if (TYPE(ev) == T_STRING &&\n                 TYPE(event_name) == T_STRING &&\n                 rb_str_cmp(ev, event_name) == 0) {\n            ret = i;\n            break;\n        }\n    }\n    return ret;\n}\n\nstatic VALUE\nole_search_event(ary, ev, is_default)\n    VALUE ary;\n    VALUE ev;\n    BOOL  *is_default;\n{\n    VALUE event;\n    VALUE def_event;\n    VALUE event_name;\n    long i, len;\n    *is_default = FALSE;\n    def_event = Qnil;\n    len = RARRAY(ary)->len;\n    for(i = 0; i < len; i++) {\n        event = rb_ary_entry(ary, i);\n        event_name = rb_ary_entry(event, 1);\n        if(NIL_P(event_name)) {\n            *is_default = TRUE;\n            def_event = event;\n        }\n        else if (rb_str_cmp(ev, event_name) == 0) {\n            *is_default = FALSE;\n            return event;\n        }\n    }\n    return def_event;\n}\n\nstatic void\nval2ptr_variant(val, var)\n    VALUE val;\n    VARIANT *var;\n{\n    switch (TYPE(val)) {\n    case T_STRING:\n        if (V_VT(var) == (VT_BSTR | VT_BYREF)) {\n            *V_BSTRREF(var) = ole_mb2wc(StringValuePtr(val), -1);\n        }\n        break;\n    case T_FIXNUM:\n        switch(V_VT(var)) {\n        case (VT_UI1 | VT_BYREF) :\n            *V_UI1REF(var) = NUM2CHR(val);\n            break;\n        case (VT_I2 | VT_BYREF) :\n            *V_I2REF(var) = (short)NUM2INT(val);\n            break;\n        case (VT_I4 | VT_BYREF) :\n            *V_I4REF(var) = NUM2INT(val);\n            break;\n        case (VT_R4 | VT_BYREF) :\n            *V_R4REF(var) = (float)NUM2INT(val);\n            break;\n        case (VT_R8 | VT_BYREF) :\n            *V_R8REF(var) = NUM2INT(val);\n            break;\n        default:\n            break;\n        }\n        break;\n    case T_FLOAT:\n        switch(V_VT(var)) {\n        case (VT_I2 | VT_BYREF) :\n            *V_I2REF(var) = (short)NUM2INT(val);\n            break;\n        case (VT_I4 | VT_BYREF) :\n            *V_I4REF(var) = NUM2INT(val);\n            break;\n        case (VT_R4 | VT_BYREF) :\n            *V_R4REF(var) = (float)NUM2DBL(val);\n            break;\n        case (VT_R8 | VT_BYREF) :\n            *V_R8REF(var) = NUM2DBL(val);\n            break;\n        default:\n            break;\n        }\n        break;\n    case T_BIGNUM:\n        if (V_VT(var) == (VT_R8 | VT_BYREF)) {\n            *V_R8REF(var) = rb_big2dbl(val);\n        }\n        break;\n    case T_TRUE:\n        if (V_VT(var) == (VT_BOOL | VT_BYREF)) {\n            *V_BOOLREF(var) = VARIANT_TRUE;\n        }\n        break;\n    case T_FALSE:\n        if (V_VT(var) == (VT_BOOL | VT_BYREF)) {\n            *V_BOOLREF(var) = VARIANT_FALSE;\n        }\n        break;\n    default:\n        break;\n    }\n}\n\nstatic void\nary2ptr_dispparams(ary, pdispparams)\n    VALUE ary;\n    DISPPARAMS *pdispparams;\n{\n    int i;\n    VALUE v;\n    VARIANT *pvar;\n    for(i = 0; i < RARRAY(ary)->len && (unsigned int) i < pdispparams->cArgs; i++) {\n        v = rb_ary_entry(ary, i);\n        pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];\n        val2ptr_variant(v, pvar);\n    }\n}\n\nSTDMETHODIMP EVENTSINK_Invoke(\n    PEVENTSINK pEventSink,\n    DISPID dispid,\n    REFIID riid,\n    LCID lcid,\n    WORD wFlags,\n    DISPPARAMS *pdispparams,\n    VARIANT *pvarResult,\n    EXCEPINFO *pexcepinfo,\n    UINT *puArgErr\n    ) {\n\n    HRESULT hr;\n    BSTR bstr;\n    unsigned int count;\n    unsigned int i;\n    ITypeInfo *pTypeInfo;\n    VARIANT *pvar;\n    VALUE ary, obj, event, handler, args, argv, ev, result;\n    BOOL is_default_handler = FALSE;\n\n    PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;\n    pTypeInfo = pEV->pTypeInfo;\n\n    obj = rb_ary_entry(ary_ole_event, pEV->m_event_id);\n    if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {\n        return NOERROR;\n    }\n\n    ary = rb_ivar_get(obj, id_events);\n    if (NIL_P(ary) || TYPE(ary) != T_ARRAY) {\n        return NOERROR;\n    }\n    hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,\n                                     &bstr, 1, &count);\n    if (FAILED(hr)) {\n        return NOERROR;\n    }\n    ev = WC2VSTR(bstr);\n    event = ole_search_event(ary, ev, &is_default_handler);\n    if (NIL_P(event)) {\n        return NOERROR;\n    }\n    args = rb_ary_new();\n    if (is_default_handler) {\n        rb_ary_push(args, ev);\n    }\n\n    /* make argument of event handler */\n    for (i = 0; i < pdispparams->cArgs; ++i) {\n        pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];\n        rb_ary_push(args, ole_variant2val(pvar));\n    }\n    handler = rb_ary_entry(event, 0);\n\n    if (rb_ary_entry(event, 3) == Qtrue) {\n        argv = rb_ary_new();\n        rb_ary_push(args, argv);\n        result = rb_apply(handler, rb_intern(\"call\"), args);\n        ary2ptr_dispparams(argv, pdispparams);\n    }\n    else {\n        result = rb_apply(handler, rb_intern(\"call\"), args);\n    }\n\n    if (pvarResult) {\n        ole_val2variant(result, pvarResult);\n    }\n    \n    return NOERROR;\n}\n\nPIEVENTSINKOBJ\nEVENTSINK_Constructor() {\n    PIEVENTSINKOBJ pEv;\n    if (!g_IsEventSinkVtblInitialized) {\n        vtEventSink.QueryInterface=EVENTSINK_QueryInterface;\n        vtEventSink.AddRef = EVENTSINK_AddRef;\n        vtEventSink.Release = EVENTSINK_Release;\n        vtEventSink.Invoke = EVENTSINK_Invoke;\n        vtEventSink.GetIDsOfNames = EVENTSINK_GetIDsOfNames;\n        vtEventSink.GetTypeInfoCount = EVENTSINK_GetTypeInfoCount;\n        vtEventSink.GetTypeInfo = EVENTSINK_GetTypeInfo;\n\n        g_IsEventSinkVtblInitialized = TRUE;\n    }\n    pEv = ALLOC_N(IEVENTSINKOBJ, 1);\n    if(pEv == NULL) return NULL;\n    pEv->lpVtbl = &vtEventSink;\n    pEv->m_cRef = 0;\n    pEv->m_event_id = 0;\n    pEv->m_dwCookie = 0;\n    pEv->pConnectionPoint = NULL;\n    pEv->pTypeInfo = NULL;\n    pEv->ptr_freed = NULL;\n    return pEv;\n}\n\nvoid EVENTSINK_Destructor(\n    PIEVENTSINKOBJ pEVObj\n    ) {\n    if(pEVObj != NULL) {\n        *(pEVObj->ptr_freed) = 1;\n        free(pEVObj);\n    }\n}\n\nstatic HRESULT\nfind_iid(ole, pitf, piid, ppTypeInfo)\n    VALUE ole;\n    char *pitf;\n    IID *piid;\n    ITypeInfo **ppTypeInfo;\n{\n    HRESULT hr;\n    IDispatch *pDispatch;\n    ITypeInfo *pTypeInfo;\n    ITypeLib *pTypeLib;\n    TYPEATTR *pTypeAttr;\n    HREFTYPE RefType;\n    ITypeInfo *pImplTypeInfo;\n    TYPEATTR *pImplTypeAttr;\n\n    struct oledata *pole;\n    unsigned int index;\n    unsigned int count;\n    int type;\n    BSTR bstr;\n    char *pstr;\n\n    BOOL is_found = FALSE;\n    LCID    lcid = LOCALE_SYSTEM_DEFAULT;\n\n    OLEData_Get_Struct(ole, pole);\n\n    pDispatch = pole->pDispatch;\n\n    hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo);\n    if (FAILED(hr))\n        return hr;\n\n    hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo,\n                                                 &pTypeLib,\n                                                 &index);\n    OLE_RELEASE(pTypeInfo);\n    if (FAILED(hr))\n        return hr;\n\n    if (!pitf) {\n        hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib,\n                                                 piid,\n                                                 ppTypeInfo);\n        OLE_RELEASE(pTypeLib);\n        return hr;\n    }\n    count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);\n    for (index = 0; index < count; index++) {\n        hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib,\n                                           index,\n                                           &pTypeInfo);\n        if (FAILED(hr))\n            break;\n        hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n\n        if(FAILED(hr)) {\n            OLE_RELEASE(pTypeInfo);\n            break;\n        }\n        if(pTypeAttr->typekind == TKIND_COCLASS) {\n            for (type = 0; type < pTypeAttr->cImplTypes; type++) {\n                hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,\n                                                             type,\n                                                             &RefType);\n                if (FAILED(hr))\n                    break;\n                hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,\n                                                       RefType,\n                                                       &pImplTypeInfo);\n                if (FAILED(hr))\n                    break;\n\n                hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo,\n                                                             -1,\n                                                             &bstr,\n                                                             NULL, NULL, NULL);\n                if (FAILED(hr)) {\n                    OLE_RELEASE(pImplTypeInfo);\n                    break;\n                }\n                pstr = ole_wc2mb(bstr);\n                if (strcmp(pitf, pstr) == 0) {\n                    hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo,\n                                                            &pImplTypeAttr);\n                    if (SUCCEEDED(hr)) {\n                        is_found = TRUE;\n                        *piid = pImplTypeAttr->guid;\n                        if (ppTypeInfo) {\n                            *ppTypeInfo = pImplTypeInfo;\n                            (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo));\n                        }\n                        pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo,\n                                                               pImplTypeAttr);\n                    }\n                }\n                free(pstr);\n                OLE_RELEASE(pImplTypeInfo);\n                if (is_found || FAILED(hr))\n                    break;\n            }\n        }\n\n        OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n        OLE_RELEASE(pTypeInfo);\n        if (is_found || FAILED(hr))\n            break;\n    }\n    OLE_RELEASE(pTypeLib);\n    if(!is_found)\n        return E_NOINTERFACE;\n    return hr;\n}\n\nstatic HRESULT\nfind_default_source(ole, piid, ppTypeInfo)\n    VALUE ole;\n    IID *piid;\n    ITypeInfo **ppTypeInfo;\n{\n    HRESULT hr;\n    IProvideClassInfo2 *pProvideClassInfo2;\n    IProvideClassInfo *pProvideClassInfo;\n\n    IDispatch *pDispatch;\n    ITypeInfo *pTypeInfo;\n    TYPEATTR *pTypeAttr;\n    int i;\n    int iFlags;\n    HREFTYPE hRefType;\n\n    struct oledata *pole;\n\n    OLEData_Get_Struct(ole, pole);\n    pDispatch = pole->pDispatch;\n    hr = pDispatch->lpVtbl->QueryInterface(pDispatch,\n                                           &IID_IProvideClassInfo2,\n                                           (void**)&pProvideClassInfo2);\n    if (SUCCEEDED(hr)) {\n        hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2,\n                                                 GUIDKIND_DEFAULT_SOURCE_DISP_IID,\n                                                 piid);\n        OLE_RELEASE(pProvideClassInfo2);\n        return find_iid(ole, NULL, piid, ppTypeInfo);\n    }\n    hr = pDispatch->lpVtbl->QueryInterface(pDispatch,\n                                           &IID_IProvideClassInfo,\n                                           (void**)&pProvideClassInfo);\n    if (FAILED(hr))\n        return hr;\n\n    hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo,\n                                                 &pTypeInfo);\n    OLE_RELEASE(pProvideClassInfo);\n    if (FAILED(hr))\n        return hr;\n\n    hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);\n    if (FAILED(hr)) {\n        OLE_RELEASE(pTypeInfo);\n        return hr;\n    }\n    /* Enumerate all implemented types of the COCLASS */\n    for (i = 0; i < pTypeAttr->cImplTypes; i++) {\n        hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &iFlags);\n        if (FAILED(hr))\n            continue;\n\n        /*\n           looking for the [default] [source]\n           we just hope that it is a dispinterface :-)\n        */\n        if ((iFlags & IMPLTYPEFLAG_FDEFAULT) &&\n            (iFlags & IMPLTYPEFLAG_FSOURCE)) {\n\n            hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,\n                                                         i, &hRefType);\n            if (FAILED(hr))\n                continue;\n            hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,\n                                                   hRefType, ppTypeInfo);\n            if (SUCCEEDED(hr))\n                break;\n        }\n    }\n\n    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);\n    OLE_RELEASE(pTypeInfo);\n\n    /* Now that would be a bad surprise, if we didn't find it, wouldn't it? */\n    if (!*ppTypeInfo) {\n        if (SUCCEEDED(hr))\n            hr = E_UNEXPECTED;\n        return hr;\n    }\n\n    /* Determine IID of default source interface */\n    hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr);\n    if (SUCCEEDED(hr)) {\n        *piid = pTypeAttr->guid;\n        (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr);\n    }\n    else\n        OLE_RELEASE(*ppTypeInfo);\n\n    return hr;\n\n}\n\nstatic void\nole_event_free(poleev)\n    struct oleeventdata *poleev;\n{\n    ITypeInfo *pti = NULL;\n    IConnectionPoint *pcp = NULL;\n\n    if (poleev->freed == 1) {\n        /* \n         * this return create memory leak.\n         * but poleev->pEvent->pConnectionPoint shoul'd not be freed\n         * until poleev-> freed == 0.\n         */\n        return;\n    }\n    if(poleev->pEvent) {\n        pti = poleev->pEvent->pTypeInfo;\n        if(pti) OLE_RELEASE(pti);\n        pcp = poleev->pEvent->pConnectionPoint;\n        if(pcp) {\n            pcp->lpVtbl->Unadvise(pcp, poleev->pEvent->m_dwCookie);\n            OLE_RELEASE(pcp);\n        }\n        free(poleev);\n    }\n}\n\nstatic VALUE fev_s_allocate _((VALUE));\nstatic VALUE\nfev_s_allocate(klass)\n    VALUE klass;\n{\n    VALUE obj;\n    struct oleeventdata *poleev;\n    obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);\n    poleev->pEvent = NULL;\n    return obj;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_EVENT.new(ole, event) #=> WIN32OLE_EVENT object.\n *\n *  Returns OLE event object.\n *  The first argument specifies WIN32OLE object.\n *  The second argument specifies OLE event name.\n *     ie = WIN32OLE.new('InternetExplorer.Application')\n *     ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')\n */     \nstatic VALUE\nfev_initialize(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE ole, itf;\n    struct oledata *pole;\n    char *pitf;\n    HRESULT hr;\n    IID iid;\n    ITypeInfo *pTypeInfo;\n    IDispatch *pDispatch;\n    IConnectionPointContainer *pContainer;\n    IConnectionPoint *pConnectionPoint;\n    IEVENTSINKOBJ *pIEV;\n    DWORD dwCookie = 0;\n    struct oleeventdata *poleev;\n\n    rb_secure(4);\n    rb_scan_args(argc, argv, \"11\", &ole, &itf);\n\n    if (!rb_obj_is_kind_of(ole, cWIN32OLE)) {\n        rb_raise(rb_eTypeError, \"1st parameter must be WIN32OLE object\");\n    }\n\n    if(TYPE(itf) != T_NIL) {\n        if (ruby_safe_level > 0 && OBJ_TAINTED(itf)) {\n            rb_raise(rb_eSecurityError, \"Insecure Event Creation - %s\",\n                     StringValuePtr(itf));\n        }\n        Check_SafeStr(itf);\n        pitf = StringValuePtr(itf);\n        hr = find_iid(ole, pitf, &iid, &pTypeInfo);\n    }\n    else {\n        hr = find_default_source(ole, &iid, &pTypeInfo);\n    }\n    if (FAILED(hr)) {\n        ole_raise(hr, rb_eRuntimeError, \"interface not found\");\n    }\n\n    OLEData_Get_Struct(ole, pole);\n    pDispatch = pole->pDispatch;\n    hr = pDispatch->lpVtbl->QueryInterface(pDispatch,\n                                           &IID_IConnectionPointContainer,\n                                           (void**)&pContainer);\n    if (FAILED(hr)) {\n        OLE_RELEASE(pTypeInfo);\n        ole_raise(hr, rb_eRuntimeError,\n                  \"failed to query IConnectionPointContainer\");\n    }\n\n    hr = pContainer->lpVtbl->FindConnectionPoint(pContainer,\n                                                 &iid,\n                                                 &pConnectionPoint);\n    OLE_RELEASE(pContainer);\n    if (FAILED(hr)) {\n        OLE_RELEASE(pTypeInfo);\n        ole_raise(hr, rb_eRuntimeError, \"failed to query IConnectionPoint\");\n    }\n    pIEV = EVENTSINK_Constructor();\n    pIEV->m_iid = iid;\n    hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint,\n                                          (IUnknown*)pIEV,\n                                          &dwCookie);\n    if (FAILED(hr)) {\n        ole_raise(hr, rb_eRuntimeError, \"Advise Error\");\n    }\n\n    Data_Get_Struct(self, struct oleeventdata, poleev);\n    poleev->pEvent = pIEV;\n    poleev->pEvent->m_event_id\n        = NUM2INT(rb_funcall(ary_ole_event, rb_intern(\"length\"), 0));\n    poleev->pEvent->pConnectionPoint = pConnectionPoint;\n    poleev->pEvent->pTypeInfo = pTypeInfo;\n    poleev->pEvent->m_dwCookie = dwCookie;\n    poleev->freed = 0;\n    poleev->pEvent->ptr_freed = &(poleev->freed);\n    rb_ary_push(ary_ole_event, self);\n    return self;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_EVENT.message_loop\n * \n *  Translates and dispatches Windows message.\n */\nstatic VALUE\nfev_s_msg_loop(klass)\n    VALUE klass;\n{\n    ole_msg_loop();\n    return Qnil;\n}\n\n\nstatic void\nadd_event_call_back(obj, event, data)\n    VALUE obj;\n    VALUE event;\n    VALUE data;\n{\n    long at;\n    VALUE events = rb_ivar_get(obj, id_events);\n    if (NIL_P(events) || TYPE(events) != T_ARRAY) {\n        events = rb_ary_new();\n        rb_ivar_set(obj, id_events, events);\n    }\n    at = ole_search_event_at(events, event);\n    if (at > -1) {\n        rb_ary_delete_at(events, at);\n    }\n    rb_ary_push(events, data);\n}\n\nstatic VALUE\nev_on_event(argc, argv, self, is_ary_arg)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n    VALUE is_ary_arg;\n{\n    VALUE event, args, data;\n    rb_scan_args(argc, argv, \"01*\", &event, &args);\n    if(!NIL_P(event)) {\n        Check_SafeStr(event);\n    }\n    data = rb_ary_new3(4, rb_block_proc(), event, args, is_ary_arg);\n    add_event_call_back(self, event, data);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_EVENT#on_event([event]){...}\n * \n *  Defines the callback event.\n *  If argument is omitted, this method defines the callback of all events.\n *    ie = WIN32OLE.new('InternetExplorer.Application')\n *    ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')\n *    ev.on_event(\"NavigateComplete\") {|url| puts url}\n */\nstatic VALUE\nfev_on_event(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return ev_on_event(argc, argv, self, Qfalse);\n}\n\n/*\n *  call-seq:\n *     WIN32OLE_EVENT#on_event_with_outargs([event]){...}\n * \n *  Defines the callback of event.\n *  If you want modify argument in callback, \n *  you should use this method instead of WIN32OLE_EVENT#on_event.\n */\nstatic VALUE\nfev_on_event_with_outargs(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    return ev_on_event(argc, argv, self, Qtrue);\n}\n\n\nvoid\nInit_win32ole()\n{\n    rb_global_variable(&ary_ole_event);\n    ary_ole_event = rb_ary_new();\n    id_events = rb_intern(\"events\");\n\n    rb_global_variable(&com_hash);\n    com_vtbl.QueryInterface = QueryInterface;\n    com_vtbl.AddRef = AddRef;\n    com_vtbl.Release = Release;\n    com_vtbl.GetTypeInfoCount = GetTypeInfoCount;\n    com_vtbl.GetTypeInfo = GetTypeInfo;\n    com_vtbl.GetIDsOfNames = GetIDsOfNames;\n    com_vtbl.Invoke = Invoke;\n\n    message_filter.QueryInterface = mf_QueryInterface;\n    message_filter.AddRef = mf_AddRef;\n    message_filter.Release = mf_Release;\n    message_filter.HandleInComingCall = mf_HandleInComingCall;\n    message_filter.RetryRejectedCall = mf_RetryRejectedCall;\n    message_filter.MessagePending = mf_MessagePending;\n\n    com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());\n\n    cWIN32OLE = rb_define_class(\"WIN32OLE\", rb_cObject);\n\n    rb_define_alloc_func(cWIN32OLE, fole_s_allocate);\n\n    rb_define_method(cWIN32OLE, \"initialize\", fole_initialize, -1);\n\n    rb_define_singleton_method(cWIN32OLE, \"connect\", fole_s_connect, -1);\n    rb_define_singleton_method(cWIN32OLE, \"const_load\", fole_s_const_load, -1);\n\n    rb_define_singleton_method(cWIN32OLE, \"ole_free\", fole_s_free, 1);\n    rb_define_singleton_method(cWIN32OLE, \"ole_reference_count\", fole_s_reference_count, 1);\n    rb_define_singleton_method(cWIN32OLE, \"ole_show_help\", fole_s_show_help, -1);\n    rb_define_singleton_method(cWIN32OLE, \"codepage\", fole_s_get_code_page, 0);\n    rb_define_singleton_method(cWIN32OLE, \"codepage=\", fole_s_set_code_page, 1);\n\n\n    rb_define_method(cWIN32OLE, \"invoke\", fole_invoke, -1);\n    rb_define_method(cWIN32OLE, \"[]\", fole_getproperty, -1);\n    rb_define_method(cWIN32OLE, \"_invoke\", fole_invoke2, 3);\n    rb_define_method(cWIN32OLE, \"_getproperty\", fole_getproperty2, 3);\n    rb_define_method(cWIN32OLE, \"_setproperty\", fole_setproperty2, 3);\n\n    /* support propput method that takes an argument */\n    rb_define_method(cWIN32OLE, \"[]=\", fole_setproperty, -1); \n\n    rb_define_method(cWIN32OLE, \"ole_free\", fole_free, 0);\n\n    rb_define_method(cWIN32OLE, \"each\", fole_each, 0);\n    rb_define_method(cWIN32OLE, \"method_missing\", fole_missing, -1);\n\n    /* support setproperty method much like Perl ;-) */\n    rb_define_method(cWIN32OLE, \"setproperty\", fole_setproperty, -1);\n\n    rb_define_method(cWIN32OLE, \"ole_methods\", fole_methods, 0);\n    rb_define_method(cWIN32OLE, \"ole_get_methods\", fole_get_methods, 0);\n    rb_define_method(cWIN32OLE, \"ole_put_methods\", fole_put_methods, 0);\n    rb_define_method(cWIN32OLE, \"ole_func_methods\", fole_func_methods, 0);\n\n    rb_define_method(cWIN32OLE, \"ole_method\", fole_method_help, 1);\n    rb_define_alias(cWIN32OLE, \"ole_method_help\", \"ole_method\");\n    rb_define_method(cWIN32OLE, \"ole_obj_help\", fole_obj_help, 0);\n    rb_define_method(cWIN32OLE, \"ole_activex_initialize\", fole_activex_initialize, 0);\n\n    rb_define_const(cWIN32OLE, \"VERSION\", rb_str_new2(WIN32OLE_VERSION));\n    rb_define_const(cWIN32OLE, \"ARGV\", rb_ary_new());\n    rb_define_const(cWIN32OLE, \"CP_ACP\"       ,INT2FIX(CP_ACP));\n    rb_define_const(cWIN32OLE, \"CP_OEMCP\"     ,INT2FIX(CP_OEMCP));\n    rb_define_const(cWIN32OLE, \"CP_MACCP\"     ,INT2FIX(CP_MACCP));\n    rb_define_const(cWIN32OLE, \"CP_THREAD_ACP\",INT2FIX(CP_THREAD_ACP));\n    rb_define_const(cWIN32OLE, \"CP_SYMBOL\"    ,INT2FIX(CP_SYMBOL));\n    rb_define_const(cWIN32OLE, \"CP_UTF7\"      ,INT2FIX(CP_UTF7));\n    rb_define_const(cWIN32OLE, \"CP_UTF8\"      ,INT2FIX(CP_UTF8));\n\n    mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, \"VARIANT\");\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_I2\", INT2FIX(VT_I2));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_I4\", INT2FIX(VT_I4));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_R4\", INT2FIX(VT_R4));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_R8\", INT2FIX(VT_R8));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_CY\", INT2FIX(VT_CY));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_DATE\", INT2FIX(VT_DATE));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_BSTR\", INT2FIX(VT_BSTR));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_USERDEFINED\", INT2FIX(VT_USERDEFINED));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_PTR\", INT2FIX(VT_PTR));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_DISPATCH\", INT2FIX(VT_DISPATCH));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_ERROR\", INT2FIX(VT_ERROR));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_BOOL\", INT2FIX(VT_BOOL));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_VARIANT\", INT2FIX(VT_VARIANT));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_UNKNOWN\", INT2FIX(VT_UNKNOWN));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_I1\", INT2FIX(VT_I1));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_UI1\", INT2FIX(VT_UI1));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_UI2\", INT2FIX(VT_UI2));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_UI4\", INT2FIX(VT_UI4));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_INT\", INT2FIX(VT_INT));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_UINT\", INT2FIX(VT_UINT));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_ARRAY\", INT2FIX(VT_ARRAY));\n    rb_define_const(mWIN32OLE_VARIANT, \"VT_BYREF\", INT2FIX(VT_BYREF));\n    \n    cWIN32OLE_TYPE = rb_define_class(\"WIN32OLE_TYPE\", rb_cObject);\n    rb_define_singleton_method(cWIN32OLE_TYPE, \"ole_classes\", foletype_s_ole_classes, 1);\n    rb_define_singleton_method(cWIN32OLE_TYPE, \"typelibs\", foletype_s_typelibs, 0);\n    rb_define_singleton_method(cWIN32OLE_TYPE, \"progids\", foletype_s_progids, 0);\n    rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate);\n    rb_define_method(cWIN32OLE_TYPE, \"initialize\", foletype_initialize, 2);\n    rb_define_method(cWIN32OLE_TYPE, \"name\", foletype_name, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"ole_type\", foletype_ole_type, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"guid\", foletype_guid, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"progid\", foletype_progid, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"visible?\", foletype_visible, 0);\n    rb_define_alias(cWIN32OLE_TYPE, \"to_s\", \"name\");\n\n    rb_define_method(cWIN32OLE_TYPE, \"major_version\", foletype_major_version, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"minor_version\", foletype_minor_version, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"typekind\", foletype_typekind, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"helpstring\", foletype_helpstring, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"src_type\", foletype_src_type, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"helpfile\", foletype_helpfile, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"helpcontext\", foletype_helpcontext, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"variables\", foletype_variables, 0);\n    rb_define_method(cWIN32OLE_TYPE, \"ole_methods\", foletype_methods, -1);\n\n    cWIN32OLE_VARIABLE = rb_define_class(\"WIN32OLE_VARIABLE\", rb_cObject);\n    rb_define_method(cWIN32OLE_VARIABLE, \"name\", folevariable_name, 0);\n    rb_define_method(cWIN32OLE_VARIABLE, \"ole_type\", folevariable_ole_type, 0);\n    rb_define_method(cWIN32OLE_VARIABLE, \"ole_type_detail\", folevariable_ole_type_detail, 0);\n    rb_define_method(cWIN32OLE_VARIABLE, \"value\", folevariable_value, 0);\n    rb_define_method(cWIN32OLE_VARIABLE, \"visible?\", folevariable_visible, 0);\n    rb_define_method(cWIN32OLE_VARIABLE, \"variable_kind\", folevariable_variable_kind, 0);\n    rb_define_method(cWIN32OLE_VARIABLE, \"varkind\", folevariable_varkind, 0);\n    rb_define_alias(cWIN32OLE_VARIABLE, \"to_s\", \"name\");\n\n    cWIN32OLE_METHOD = rb_define_class(\"WIN32OLE_METHOD\", rb_cObject);\n    rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);\n    rb_define_method(cWIN32OLE_METHOD, \"initialize\", folemethod_initialize, 2);\n\n    rb_define_method(cWIN32OLE_METHOD, \"name\", folemethod_name, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"return_type\", folemethod_return_type, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"return_vtype\", folemethod_return_vtype, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"return_type_detail\", folemethod_return_type_detail, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"invoke_kind\", folemethod_invoke_kind, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"invkind\", folemethod_invkind, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"visible?\", folemethod_visible, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"event?\", folemethod_event, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"event_interface\", folemethod_event_interface, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"helpstring\", folemethod_helpstring, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"helpfile\", folemethod_helpfile, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"helpcontext\", folemethod_helpcontext, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"dispid\", folemethod_dispid, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"offset_vtbl\", folemethod_offset_vtbl, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"size_params\", folemethod_size_params, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"size_opt_params\", folemethod_size_opt_params, 0);\n    rb_define_method(cWIN32OLE_METHOD, \"params\", folemethod_params, 0);\n    rb_define_alias(cWIN32OLE_METHOD, \"to_s\", \"name\");\n\n    cWIN32OLE_PARAM = rb_define_class(\"WIN32OLE_PARAM\", rb_cObject);\n    rb_define_method(cWIN32OLE_PARAM, \"name\", foleparam_name, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"ole_type\", foleparam_ole_type, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"ole_type_detail\", foleparam_ole_type_detail, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"input?\", foleparam_input, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"output?\", foleparam_output, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"optional?\", foleparam_optional, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"retval?\", foleparam_retval, 0);\n    rb_define_method(cWIN32OLE_PARAM, \"default\", foleparam_default, 0);\n    rb_define_alias(cWIN32OLE_PARAM, \"to_s\", \"name\");\n \n    cWIN32OLE_EVENT = rb_define_class(\"WIN32OLE_EVENT\", rb_cObject);\n\n    rb_define_alloc_func(cWIN32OLE_EVENT, fev_s_allocate);\n    rb_define_method(cWIN32OLE_EVENT, \"initialize\", fev_initialize, -1);\n    rb_define_singleton_method(cWIN32OLE_EVENT, \"message_loop\", fev_s_msg_loop, 0);\n\n    rb_define_method(cWIN32OLE_EVENT, \"on_event\", fev_on_event, -1);\n    rb_define_method(cWIN32OLE_EVENT, \"on_event_with_outargs\", fev_on_event_with_outargs, -1);\n    eWIN32OLE_RUNTIME_ERROR = rb_define_class(\"WIN32OLERuntimeError\", rb_eRuntimeError);\n}\n"
  },
  {
    "path": "ext/zlib/.cvsignore",
    "content": "Makefile\nmkmf.log\n*.def\n"
  },
  {
    "path": "ext/zlib/doc/zlib.rd",
    "content": "=begin\n#\n# zlib.rd.src\n#\n#   Copyright (C) UENO Katsuhiro 2000-2003\n#\n# $Id$\n#\n\n= Ruby/zlib version 0.6.0\n\nRuby/zlib is an extension library to use zlib from Ruby.\nRuby/zlib also provides the features for accessing gzipped files.\n\nYou can modify or redistribute Ruby/zlib in the same manner of\nRuby interpreter. The latest version of Ruby/zlib would be found\nat ((<URL:http://www.blue.sky.or.jp/>)).\n\nAny comments and suggestions are always welcome. Please send\nthem to ruby-list ML, ruby-ext ML, ruby-talk ML, or the author's\nmail address ((<URL:mailto:katsu@blue.sky.or.jp>)).\n\nThis document is experimental and broken English version.\nIf you find some mistakes or strange expressions (including\nkidding or unnatural ones) in this document, please let me know\nfor my study.\n\n* ((<Zlib>))\n\n  * ((<Zlib::Error>))\n  * ((<Zlib::ZStream>))\n  * ((<Zlib::Deflate>))\n  * ((<Zlib::Inflate>))\n  * ((<Zlib::GzipFile>))\n  * ((<Zlib::GzipFile::Error>))\n  * ((<Zlib::GzipWriter>))\n  * ((<Zlib::GzipReader>))\n\n* ((<Changes from 0.5 to 0.6>))\n* ((<Changes from 0.4 to 0.5>))\n\n== Zlib\n\nZlib is the module which provides the other features in zlib C\nlibrary. See zlib.h for detail of each module function.\n\n=== Module Functions:\n\n--- Zlib.zlib_version\n\n    Returns the string which represents the version of zlib\n    library.\n\n--- Zlib.adler32([string[, adler]])\n\n    Calculates Alder-32 checksum for ((|string|)),\n    and returns updated value of ((|alder|)).\n    If ((|string|)) is omitted, it returns the Adler-32 initial\n    value. If ((|alder|)) is omitted, it assumes that the initial\n    value is given to ((|alder|)).\n\n--- Zlib.crc32([string[, crc]])\n\n    Calculates CRC checksum for ((|string|)), and returns\n    updated value of ((|crc|)). If ((|string|)) is omitted,\n    it returns the CRC initial value. ((|crc|)) is omitted,\n    it assumes that the initial value is given to ((|crc|)).\n\n--- Zlib.crc_table\n\n    Returns the table for calculating CRC checksum as an array.\n\n=== Constants:\n\n--- Zlib::VERSION\n\n    The Ruby/zlib version string.\n\n--- Zlib::ZLIB_VERSION\n\n    The string which represents the version of zlib.h.\n\n--- Zlib::BINARY\n--- Zlib::ASCII\n--- Zlib::UNKNOWN\n\n    The integers representing data types which\n    ((<Zlib::ZStream#data_type>)) method returns.\n\n--- Zlib::NO_COMPRESSION\n--- Zlib::BEST_SPEED\n--- Zlib::BEST_COMPRESSION\n--- Zlib::DEFAULT_COMPRESSION\n\n    The integers representing compression levels which are\n    an argument for ((<Zlib::Deflate.new>)),\n    ((<Zlib::Deflate#deflate>)), and so on.\n\n--- Zlib::FILTERED\n--- Zlib::HUFFMAN_ONLY\n--- Zlib::DEFAULT_STRATEGY\n\n    The integers representing compression methods which are\n    an argument for ((<Zlib::Deflate.new>)) and\n    ((<Zlib::Deflate#params>)).\n\n--- Zlib::DEF_MEM_LEVEL\n--- Zlib::MAX_MEM_LEVEL\n\n    The integers representing memory levels which are an\n    argument for ((<Zlib::Deflate.new>)),\n    ((<Zlib::Deflate#params>)), and so on.\n\n--- Zlib::MAX_WBITS\n\n    The default value of ((|windowBits|)) which is an argument for\n    ((<Zlib::Deflate.new>)) and ((<Zlib::Inflate.new>)).\n\n--- Zlib::NO_FLUSH\n--- Zlib::SYNC_FLUSH\n--- Zlib::FULL_FLUSH\n--- Zlib::FINISH\n\n    The integers to control the output of the deflate stream,\n    which are an argument for ((<Zlib::Deflate#deflate>)) and so on.\n\n--- Zlib::OS_CODE\n--- Zlib::OS_MSDOS\n--- Zlib::OS_AMIGA\n--- Zlib::OS_VMS\n--- Zlib::OS_UNIX\n--- Zlib::OS_VMCMS\n--- Zlib::OS_ATARI\n--- Zlib::OS_OS2\n--- Zlib::OS_MACOS\n--- Zlib::OS_ZSYSTEM\n--- Zlib::OS_CPM\n--- Zlib::OS_TOPS20\n--- Zlib::OS_WIN32\n--- Zlib::OS_QDOS\n--- Zlib::OS_RISCOS\n--- Zlib::OS_UNKNOWN\n\n    The return values of ((<Zlib::GzipFile#os_code>)) method.\n\n\n== Zlib::Error\n\nThe superclass for all exceptions raised by Ruby/zlib.\n\nThe following exceptions are defined as subclasses of Zlib::Error.\nThese exceptions are raised when zlib library functions return\nwith an error status.\n\n  * Zlib::StreamEnd\n  * Zlib::NeedDict\n  * Zlib::DataError\n  * Zlib::StreamError\n  * Zlib::MemError\n  * Zlib::BufError\n  * Zlib::VersionError\n\n=== SuperClass:\n\n* StandardError\n\n\n== Zlib::ZStream\n\nThe abstract class for the stream which handles the compressed\ndata. The operations are defined in the subclasses,\n((<Zlib::Deflate>)) for compression, and ((<Zlib::Inflate>))\nfor decompression.\n\nAn instance of Zlib::ZStream has one stream (struct zstream) and\ntwo variable-length buffers which associated to the input\n(next_in) of the stream and the output (next_out) of the stream.\nIn this document, \"input buffer\" means the buffer for input, and\n\"output buffer\" means the buffer for output.\n\nData inputed into an instance of Zlib::ZStream are temporally\nstored into the end of input buffer, and then data in input buffer\nare processed from the beginning of the buffer until no more\noutput from the stream is produced (i.e. until avail_out > 0\nafter processing). During processing, output buffer is allocated\nand expanded automatically to hold all output data.\n\nSome particular instance methods consume the data in output buffer\nand return them as a String.\n\nHere is an ascii art for describing above:\n\n     +================ an instance of Zlib::ZStream ================+\n     ||                                                            ||\n     ||     +--------+          +-------+          +--------+      ||\n     ||  +--| output |<---------|zstream|<---------| input  |<--+  ||\n     ||  |  | buffer |  next_out+-------+next_in   | buffer |   |  ||\n     ||  |  +--------+                             +--------+   |  ||\n     ||  |                                                      |  ||\n     +===|======================================================|===+\n         |                                                      |\n         v                                                      |\n     \"output data\"                                         \"input data\"\n\nIf an error is occurred during processing input buffer,\nan exception which is a subclass of ((<Zlib::Error>)) is raised.\nAt that time, both input and output buffer keeps their conditions\nat the time when the error is occurred.\n\n=== SuperClass:\n\n* Object\n\n=== Class Methods:\n\n--- Zlib::ZStream.new\n\n    See ((<Zlib::Deflate.new>)) and ((<Zlib::Inflate.new>)).\n\n=== Methods:\n\n--- Zlib::ZStream#avail_in\n\n    Returns bytes of data in input buffer.\n    Normally, returns 0.\n\n--- Zlib::ZStream#avail_out\n\n    Returns bytes of free spaces in output buffer.\n    Because the free spaces are allocated automatically,\n    this method returns 0 normally.\n\n--- Zlib::ZStream#avail_out = size\n\n    Allocates free spaces of ((|size|)) bytes in output buffer.\n    If there are more than ((|size|)) bytes spaces in the buffer,\n    the buffer is truncated.\n    Because the free spaces are allocated automatically,\n    you usually need not to use this method.\n\n--- Zlib::ZStream#flush_next_in\n\n    Flushes input buffer and returns all data in that buffer.\n\n--- Zlib::ZStream#flush_next_out\n\n    Flushes output buffer and returns all data in that buffer.\n\n--- Zlib::ZStream#total_in\n\n    Returns the total bytes of the input data to the stream.\n\n--- Zlib::ZStream#total_out\n\n    Returns the total bytes of the output data from the stream.\n\n--- Zlib::ZStream#data_type\n\n    Guesses the type of the data which have been inputed into\n    the stream. The returned value is either ((<Zlib::BINARY>)),\n    ((<Zlib::ASCII>)), or ((<Zlib::UNKNOWN>)).\n\n--- Zlib::ZStream#adler\n\n    Returns the alder-32 checksum.\n\n--- Zlib::ZStream#reset\n\n    Resets and initializes the stream. All data in both\n    input and output buffer are discarded.\n\n--- Zlib::ZStream#finish\n\n    Finishes the stream and flushes output buffer.\n    See ((<Zlib::Deflate#finish>)) and ((<Zlib::Inflate#finish>))\n    for detail of the behavior.\n\n--- Zlib::ZStream#finished?\n--- Zlib::ZStream#stream_end?\n\n    Returns true if the stream is finished.\n\n--- Zlib::ZStream#close\n--- Zlib::ZStream#end\n\n    Closes the stream. All operations on the closed stream\n    will raise an exception.\n\n--- Zlib::ZStream#closed?\n--- Zlib::ZStream#ended?\n\n    Returns true if the stream closed.\n\n\n== Zlib::Deflate\n\nThe class for compressing string data.\n\n=== SuperClass:\n\n* ((<Zlib::ZStream>))\n\n=== Class Methods:\n\n--- Zlib::Deflate.deflate(string[, level])\n\n    Compresses ((|string|)). The avail values of ((|level|)) are\n    ((<Zlib::NO_COMPRESSION>)), ((<Zlib::BEST_SPEED>)),\n    ((<Zlib::BEST_COMPRESSION>)), ((<Zlib::DEFAULT_COMPRESSION>)),\n    and the integer from 0 to 9.\n\n    This method is almost equivalent to the following code:\n\n      def deflate(string, level)\n        z = Zlib::Deflate.new(level)\n        dst = z.deflate(string, Zlib::FINISH)\n        z.close\n        dst\n      end\n\n--- Zlib::Deflate.new([level[, windowBits[, memlevel[, strategy]]]])\n\n    Creates a new deflate stream for compression.\n    See zlib.h for details of each argument.\n    If an argument is nil, the default value of that\n    argument is used.\n\n=== Methods:\n\n--- Zlib::Deflate#clone\n\n    Duplicates the deflate stream.\n\n--- Zlib::Deflate#deflate(string[, flush])\n\n    Inputs ((|string|)) into the deflate stream and returns\n    the output from the stream. Calling this method,\n    both input and output buffer of the stream are flushed.\n    If ((|string|)) is nil, this method finishes the stream,\n    just like ((<Zlib::ZStream#finish>)).\n    The value of ((|flush|)) should be either ((<Zlib::NO_FLUSH>)),\n    ((<Zlib::SYNC_FLUSH>)), ((<Zlib::FULL_FLUSH>)), or\n    ((<Zlib::FINISH>)).\n    See zlib.h for details.\n\n--- Zlib::Deflate#<< string\n\n    Inputs ((|string|)) into the deflate stream just like\n    ((<Zlib::Deflate#deflate>)), but returns Zlib::Deflate object\n    itself. The output from the stream is preserved in output\n    buffer.\n\n--- Zlib::Deflate#flush([flush])\n\n    This method is equivalent to (({deflate('', ((|flush|)))})).\n    If ((|flush|)) is omitted, ((<Zlib::SYNC_FLUSH>)) is used\n    as ((|flush|)). This method is just provided for\n    readability of your Ruby script.\n\n--- Zlib::Deflate#finish\n\n    Finishes the stream. This method is equivalent to\n    (({deflate('', Zlib::FINISH)})).\n\n--- Zlib::Deflate#params(level, strategy)\n\n    Changes the parameters of the deflate stream.\n    See zlib.h for details. The output from the stream\n    by changing the params is preserved in output buffer.\n\n--- Zlib::Deflate#set_dictionary(string)\n\n    Sets the preset dictionary and returns ((|string|)).\n    This method is available just only after\n    ((<Zlib::Deflate.new>)) or ((<Zlib::ZStream#reset>)) method\n    was called. See zlib.h for details.\n\n\n== Zlib::Inflate\n\nThe class for decompressing compressed data.\nUnlike ((<Zlib::Deflate>)), an instance of this class is not able\nto duplicate (clone, dup) itself.\n\n=== SuperClass:\n\n* ((<Zlib::ZStream>))\n\n=== Class Methods:\n\n--- Zlib::Inflate.inflate(string)\n\n    Decompresses ((|string|)). Raises a ((<Zlib::NeedDict>))\n    exception if a preset dictionary is needed for decompression.\n\n    This method is almost equivalent to the following code:\n\n      def inflate(string)\n        zstream = Zlib::Inflate.new\n        buf = zstream.inflate(string)\n        zstream.finish\n        zstream.close\n        buf\n      end\n\n--- Zlib::Inflate.new([windowBits])\n\n    Creates a new inflate stream for decompression.\n    See zlib.h for details of the argument.\n    If ((|windowBits|)) is nil, the default value is used.\n\n=== Methods:\n\n--- Zlib::Inflate#inflate(string)\n\n    Inputs ((|string|)) into the inflate stream and returns\n    the output from the stream. Calling this method,\n    both input and output buffer of the stream are flushed.\n    If ((|string|)) is nil, this method finishes the stream,\n    just like ((<Zlib::ZStream#finish>)).\n\n    Raises a ((<Zlib::NeedDict>)) exception if a preset\n    dictionary is needed to decompress. Set the dictionary\n    by ((<Zlib::Inflate#set_dictionary>)) and then call\n    this method again with an empty string.\n\n--- Zlib::Inflate#<< string\n\n    Inputs ((|string|)) into the inflate stream just like\n    ((<Zlib::Inflate#inflate>)), but returns Zlib::Inflate object\n    itself. The output from the stream is preserved in output\n    buffer.\n\n--- Zlib::Inflate#finish\n\n    Finishes the inflate stream and returns the garbage\n    following the compressed data. Raises an exception\n    if the stream is not finished\n    (i.e. ((<Zlib::ZStream#finished?>)) doesn't returns true).\n\n    The inflate stream finishes itself as soon as it meets\n    the end code of the compressed data, you need not to call\n    this method explicitly. However, this method is useful\n    for checking whether the data is correctly ended or not.\n\n--- Zlib::Inflate#set_dictionary(string)\n\n    Sets the preset dictionary and returns ((|string|))\n    This method is available just only after a ((<Zlib::NeedDict>))\n    exception was raised. See zlib.h for details.\n\n--- Zlib::Inflate#sync(string)\n\n    Inputs ((|string|)) into the end of input buffer and\n    skips data until a full flush point can be found.\n    If the point is found in the buffer, this method flushes\n    the buffer and returns false. Otherwise it returns true\n    and the following data of full flush point is preserved\n    in the buffer.\n\n--- Zlib::Inflate#sync_point?\n\n    What is this?\n\n\n== Zlib::GzipFile\n\nThe abstract class for handling a gzip formatted compressed file.\nThe operations are defined in the subclasses,\n((<Zlib::GzipReader>)) for reading, and ((<Zlib::GzipWriter>))\nfor writing.\n\nGzipReader should be used with associating an instance of IO class\n(or an object which has the same methods as IO has).\n\n=== SuperClass:\n\n* Object\n\n=== Class Methods:\n\n--- Zlib::GzipFile.new(args...)\n\n    See ((<Zlib::GzipReader.new>)) and ((<Zlib::GzipWriter.new>)).\n\n--- Zlib::GzipFile.wrap(args...) {|gz| ... }\n\n    See ((<Zlib::GzipReader.wrap>)) and ((<Zlib::GzipWriter.wrap>)).\n\n--- Zlib::GzipFile.open(args...) {|gz| ... }\n\n    See ((<Zlib::GzipReader.open>)) and ((<Zlib::GzipWriter.open>)).\n\n=== Methods:\n\n--- Zlib::GzipFile#closed?\n--- Zlib::GzipFile#to_io\n\n    Same as IO.\n\n--- Zlib::GzipFile#close\n\n    Closes the GzipFile object. This method calls close method\n    of the associated IO object. Returns the associated IO object.\n\n--- Zlib::GzipFile#finish\n\n    Closes the GzipFile object. Unlike ((<Zlib::GzipFile#close>)),\n    this method ((*never*)) calls close method of the associated IO\n    object. Returns the associated IO object.\n\n--- Zlib::GzipFile#crc\n\n    Returns CRC value of the uncompressed data.\n\n--- Zlib::GzipFile#level\n\n    Returns compression level.\n\n--- Zlib::GzipFile#mtime\n\n    Returns last modification time recorded in the gzip\n    file header.\n\n--- Zlib::GzipFile#os_code\n\n    Returns OS code number recorded in the gzip file header.\n\n--- Zlib::GzipFile#orig_name\n\n    Returns original filename recorded in the gzip file header,\n    or nil if original filename is not present.\n\n--- Zlib::GzipFile#comment\n\n    Returns comments recorded in the gzip file header, or\n    nil if the comments is not present.\n\n--- Zlib::GzipFile#sync\n--- Zlib::GzipFile#sync= flag\n\n    Same as IO. If ((|flag|)) is true, the associated IO object\n    must respond to flush method. While `sync' mode is true,\n    the compression ratio decreases sharply.\n\n\n== Zlib::GzipFile::Error\n\nThe superclass for all exceptions raised during processing a gzip\nfile.\n\nThe following exceptions are defined as subclasses of\nZlib::GzipFile::Error.\n\n: Zlib::GzipFile::NoFooter\n\n    Raised when gzip file footer has not found.\n\n: Zlib::GzipFile::CRCError\n\n    Raised when the CRC checksum recorded in gzip file footer\n    is not equivalent to CRC checksum of the actually\n    uncompressed data.\n\n: Zlib::GzipFile::LengthError\n\n    Raised when the data length recorded in gzip file footer\n    is not equivalent to length of the actually uncompressed data.\n\n=== SuperClass:\n\n* ((<Zlib::Error>))\n\n\n== Zlib::GzipReader\n\nThe class for reading a gzipped file. GzipReader should be used\nwith associating an instance of IO class (or an object which has\nthe same methods as IO has).\n\n    Zlib::GzipReader.open('hoge.gz') {|gz|\n      print gz.read\n    }\n\n    f = File.open('hoge.gz')\n    gz = Zlib::GzipReader.new(f)\n    print gz.read\n    gz.close\n\n=== SuperClass:\n\n* ((<Zlib::GzipFile>))\n\n=== Included Modules:\n\n* Enumerable\n\n=== Class Methods:\n\n--- Zlib::GzipReader.new(io)\n\n    Creates a GzipReader object associated with ((|io|)).\n    The GzipReader object reads gzipped data from ((|io|)),\n    and parses/decompresses them. At least, ((|io|)) must have\n    read method that behaves same as read method in IO class.\n\n    If the gzip file header is incorrect, raises an\n    ((<Zlib::GzipFile::Error>)) exception.\n\n--- Zlib::GzipReader.wrap(io) {|gz| ... }\n\n    Creates a GzipReader object associated with ((|io|)), and\n    executes the block with the newly created GzipReader object,\n    just like File::open. The GzipReader object will be closed\n    automatically after executing the block. If you want to keep\n    the associated IO object opening, you may call\n    ((<Zlib::GzipFile#finish>)) method in the block.\n\n--- Zlib::GzipReader.open(filename)\n--- Zlib::GzipReader.open(filename) {|gz| ... }\n\n    Opens a file specified by ((|filename|)) as a gzipped file,\n    and returns a GzipReader object associated with that file.\n    Further details of this method are same as\n    ((<Zlib::GzipReader.new>)) and ((<ZLib::GzipReader.wrap>)).\n\n=== ᥽å:\n\n--- Zlib::GzipReader#eof\n--- Zlib::GzipReader#eof?\n\n    Returns true if the object reaches the end of compressed data.\n    Note that eof? does ((*not*)) return true when reaches the\n    end of ((*file*)).\n\n--- Zlib::GzipReader#pos\n--- Zlib::GzipReader#tell\n\n    Returns the total bytes of data decompressed until now.\n    Not that it does ((*not*)) the position of file pointer.\n\n--- Zlib::GzipReader#each([rs])\n--- Zlib::GzipReader#each_line([rs])\n--- Zlib::GzipReader#each_byte([rs])\n--- Zlib::GzipReader#gets([rs])\n--- Zlib::GzipReader#getc\n--- Zlib::GzipReader#lineno\n--- Zlib::GzipReader#lineno=\n--- Zlib::GzipReader#read([length])\n--- Zlib::GzipReader#readchar\n--- Zlib::GzipReader#readline([rs])\n--- Zlib::GzipReader#readlines([rs])\n--- Zlib::GzipReader#ungetc(char)\n\n    Same as IO, but raises ((<Zlib::Error>)) or\n    ((<Zlib::GzipFile::Error>)) exception if an error was found\n    in the gzip file.\n\n    Be careful of the footer of gzip file. A gzip file has\n    the checksum of pre-compressed data in its footer.\n    GzipReader checks all uncompressed data against that checksum\n    at the following cases, and if failed, raises\n    ((<Zlib::GzipFile::NoFooter>)), ((<Zlib::GzipFile::CRCError>)),\n    or ((<Zlib::GzipFile::LengthError>)) exception.\n\n    * When an reading request is received beyond the end of file\n      (the end of compressed data).\n      That is, when ((<Zlib::GzipReader#read>)),\n      ((<Zlib::GzipReader#gets>)), or some other methods for reading\n      returns nil.\n\n    * When ((<Zlib::GzipFile#close>)) method is called after\n      the object reaches the end of file.\n\n    * When ((<Zlib::GzipReader#unused>)) method is called after\n      the object reaches the end of file.\n\n--- Zlib::GzipReader#rewind\n\n    Resets the position of the file pointer to the point\n    created the GzipReader object.\n    The associated IO object need to respond to seek method.\n\n--- Zlib::GzipReader#unused\n\n    Returns the rest of the data which had read for parsing gzip\n    format, or nil if the whole gzip file is not parsed yet.\n\n\n== Zlib::GzipWriter\n\nThe class for writing a gzipped file. GzipWriter should be used\nwith associate with an instance of IO class (or an object which\nhas the same methods as IO has).\n\n    Zlib::GzipWriter.open('hoge.gz') {|gz|\n      gz.write 'jugemu jugemu gokou no surikire...'\n    }\n\n    f = File.open('hoge.gz', 'w')\n    gz = Zlib::GzipWriter.new(f)\n    gz.write 'jugemu jugemu gokou no surikire...'\n    gz.close\n\nNOTE: Due to the limitation in finalizer of Ruby, you must close\nexplicitly GzipWriter object by ((<Zlib::GzipWriter#close>)) etc.\nOtherwise, GzipWriter should be not able to write gzip footer and\ngenerate broken gzip file.\n\n=== SuperClass:\n\n* ((<Zlib::GzipFile>))\n\n=== Class Methods:\n\n--- Zlib::GzipWriter.new(io[, level[, strategy]])\n\n    Creates a GzipWriter object associated with ((|io|)).\n    ((|level|)) and ((|strategy|)) should be same as the\n    arguments of ((<Zlib::Deflate.new>)). The GzipWriter object\n    writes gzipped data to ((|io|)). At least, ((|io|)) must\n    respond to write method that behaves same as write method\n    in IO class.\n\n--- Zlib::GzipWriter.wrap(io[, level[, strategy]]) {|gz| ... }\n\n    Creates a GzipWriter object associated with ((|io|)), and\n    executes the block with the newly created GzipWriter object,\n    just like File::open. The GzipWriter object will be closed\n    automatically after executing the block. If you want to keep\n    the associated IO object opening, you may call\n    ((<Zlib::GzipFile#finish>)) method in the block.\n\n--- Zlib::GzipWriter.open(filename[, level[, strategy]])\n--- Zlib::GzipWriter.open(filename[, level[, strategy]]) {|gz| ... }\n\n    Opens a file specified by ((|filename|)) for writing\n    gzip compressed data, and returns a GzipWriter object\n    associated with that file. Further details of this method\n    are same as ((<Zlib::GzipWriter.new>)) and\n    ((<Zlib::GzipWriter#wrap>)).\n\n\n=== Methods:\n\n--- Zlib::GzipWriter#close\n--- Zlib::GzipWriter#finish\n\n    Closes the GzipFile object. This method calls close method\n    of the associated IO object. Returns the associated IO object.\n    See ((<Zlib::GzipFile#close>)) and ((<Zlib::GzipFile#finish>))\n    for the difference between close and finish.\n\n    ((*NOTE: Due to the limitation in finalizer of Ruby, you must\n    close GzipWriter object explicitly. Otherwise, GzipWriter\n    should be not able to write gzip footer and generate broken\n    gzip file.*))\n\n--- Zlib::GzipWriter#pos\n--- Zlib::GzipWriter#tell\n\n    Returns the total bytes of data compressed until now.\n    Note that it does ((*not*)) the position of file pointer.\n\n--- Zlib::GzipWriter#<< str\n--- Zlib::GzipWriter#putc(ch)\n--- Zlib::GzipWriter#puts(obj...)\n--- Zlib::GzipWriter#print(arg...)\n--- Zlib::GzipWriter#printf(format, arg...)\n--- Zlib::GzipWriter#write(str)\n\n    Same as IO.\n\n--- Zlib::GzipWriter#flush([flush])\n\n    Flushes all the internal buffers of the GzipWriter object.\n    The meaning of ((|flush|)) is same as one of the argument of\n    ((<Zlib::Deflate#deflate>)).\n    ((<Zlib::SYNC_FLUSH>)) is used if ((|flush|)) is omitted.\n    It is no use giving ((|flush|)) ((<Zlib::NO_FLUSH>)).\n\n--- Zlib::GzipWriter#mtime= time\n\n    Sets last modification time to be stored in the gzip file\n    header. ((<Zlib::GzipFile::Error>)) exception will be raised\n    if this method is called after writing method (like\n    ((<Zlib::GzipWriter#write>))) was called.\n\n--- Zlib::GzipWriter#orig_name= filename\n\n    Sets original filename to be stored in the gzip file header.\n    ((<Zlib::GzipFile::Error>)) exception will be raised\n    if this method is called after writing method (like\n    ((<Zlib::GzipWriter#write>))) was called.\n\n--- Zlib::GzipWriter#comment= string\n\n    Sets comments to be stored in the gzip file header.\n    ((<Zlib::GzipFile::Error>)) exception will be raised\n    if this method is called after writing method (like\n    ((<Zlib::GzipWriter#write>))) was called.\n\n\n== Changes from 0.5 to 0.6\n\n* New methods:\n\n  * ((<Zlib::GzipFile.wrap>))\n  * ((<Zlib::GzipFile#finish>))\n\n* New constants:\n\n  * ((<Zlib::ZLIB_VERSION>))\n  * ((<Zlib::OS_VMCMS>))\n  * ((<Zlib::OS_ZSYSTEM>))\n  * ((<Zlib::OS_CPM>))\n  * ((<Zlib::OS_QDOS>))\n  * ((<Zlib::OS_RISCOS>))\n  * ((<Zlib::OS_UNKNOWN>))\n\n* Changed methods:\n\n  * ((<Zlib::GzipFile.new>)) now takes no block. Use\n    ((<Zlib::GzipFile.wrap>)) instead.\n\n  * ((<Zlib::GzipFile#close>)) now takes no argument. Use\n    ((<Zlib::GzipFile#finish>)) instead.\n\n* Renamed methods:\n\n  * Zlib.version is renamed to ((<Zlib.zlib_version>)).\n\n* Changed constants:\n\n  * ((<Zlib::VERSION>)) indicates the version of Ruby/zlib.\n    The zlib.h version is now in ((<Zlib::ZLIB_VERSION>)).\n\n* Backward compatibility:\n\n  * For backward compatibility for 0.5, the obsoleted methods and\n    arguments are still available.\n\n  * Obsoleted classes, methods, and constants for backward\n    compatibility for 0.4 or earlier are removed.\n\n== Changes from 0.4 to 0.5\n\nAlmost all the code are rewritten.\nI hope all changes are enumerated below :-)\n\n* The names of almost classes and some methods are changed.\n  All classes and constants are now defined under module\n  ((<Zlib>)). The obsoleted names are also available for backward\n  compatibility.\n\n  * Classes\n\n    * Deflate -> ((<Zlib::Deflate>))\n    * Inflate -> ((<Zlib::Inflate>))\n    * Zlib::Gzip -> ((<Zlib::GzipFile>))\n    * GzipReader -> ((<Zlib::GzipReader>))\n    * GzipWriter -> ((<Zlib::GzipWriter>))\n    * Zlib::Gzip::Error -> ((<Zlib::GzipFile::Error>))\n    * Zlib::GzipReader::NoFooter -> ((<Zlib::GzipFile::NoFooter>))\n    * Zlib::GzipReader::CRCError -> ((<Zlib::GzipFile::CRCError>))\n    * Zlib::GzipReader::LengthError -> ((<Zlib::GzipFile::LengthError>))\n\n  * Constants\n\n    * Zlib::ZStream::BINARY -> ((<Zlib::BINARY>))\n    * Zlib::ZStream::ASCII -> ((<Zlib::ASCII>))\n    * Zlib::ZStream::UNKNOWN -> ((<Zlib::UNKNOWN>))\n    * Zlib::Deflate::NO_COMPRESSION -> ((<Zlib::NO_COMPRESSION>))\n    * Zlib::Deflate::BEST_SPEED -> ((<Zlib::BEST_SPEED>))\n    * Zlib::Deflate::BEST_COMPRESSION -> ((<Zlib::BEST_COMPRESSION>))\n    * Zlib::Deflate::DEFAULT_COMPRESSION -> ((<Zlib::DEFAULT_COMPRESSION>))\n    * Zlib::Deflate::FILTERED -> ((<Zlib::FILTERED>))\n    * Zlib::Deflate::HUFFMAN_ONLY -> ((<Zlib::HUFFMAN_ONLY>))\n    * Zlib::Deflate::DEFAULT_STRATEGY -> ((<Zlib::DEFAULT_STRATEGY>))\n    * Zlib::Deflate::MAX_WBITS -> ((<Zlib::MAX_WBITS>))\n    * Zlib::Deflate::DEF_MEM_LEVEL -> ((<Zlib::DEF_MEM_LEVEL>))\n    * Zlib::Deflate::MAX_MEM_LEVEL -> ((<Zlib::MAX_MEM_LEVEL>))\n    * Zlib::Deflate::NO_FLUSH -> ((<Zlib::NO_FLUSH>))\n    * Zlib::Deflate::SYNC_FLUSH -> ((<Zlib::SYNC_FLUSH>))\n    * Zlib::Deflate::FULL_FLUSH -> ((<Zlib::FULL_FLUSH>))\n    * Zlib::Inflate::MAX_WBITS -> ((<Zlib::MAX_WBITS>))\n    * Zlib::GzipReader::OS_* -> ((<Zlib::OS_*|Zlib::OS_CODE>))\n\n  * Methods\n\n    * Zlib::ZStream#flush_out -> ((<Zlib::ZStream#flush_next_out>))\n\n* Made buffer for input (next_in).\n\n* ((<Zlib::GzipReader#unused>)) returns nil after closing.\n\n* Now you are up to call ((<Zlib::GzipWriter#close>)) explicitly\nto avoid segv in finalizer.\n((<[ruby-dev:11915]|URL:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/11915>))\n\n* divided initialize from new.\n\n* remove sanity checks for arguments for deflateInit2 and\n  inflateInit2.\n\n* adapted the behavior of ((<Zlib::GzipWriter#puts>)) to Ruby-1.7.\n\n* Made all functions static.\n\n\n=end\n"
  },
  {
    "path": "ext/zlib/extconf.rb",
    "content": "#\n# extconf.rb\n#\n# $Id$\n#\n\nrequire 'mkmf'\nrequire 'rbconfig'\n\ndir_config 'zlib'\n\n\nif %w'z libz zlib1 zlib zdll'.find {|z| have_library(z, 'deflateReset')} and\n    have_header('zlib.h') then\n\n  defines = []\n\n  message 'checking for kind of operating system... '\n  os_code = with_config('os-code') ||\n    case RUBY_PLATFORM.split('-',2)[1]\n    when 'amigaos' then\n      os_code = 'AMIGA'\n    when /\\Aos2[\\-_]emx\\z/ then\n      os_code = 'OS2'\n    when /mswin|mingw|bccwin/ then\n      # NOTE: cygwin should be regarded as Unix.\n      os_code = 'WIN32'\n    else\n      os_code = 'UNIX'\n    end\n  os_code = 'OS_' + os_code.upcase\n\n  OS_NAMES = {\n    'OS_MSDOS'   => 'MS-DOS',\n    'OS_AMIGA'   => 'Amiga',\n    'OS_VMS'     => 'VMS',\n    'OS_UNIX'    => 'Unix',\n    'OS_ATARI'   => 'Atari',\n    'OS_OS2'     => 'OS/2',\n    'OS_MACOS'   => 'MacOS',\n    'OS_TOPS20'  => 'TOPS20',\n    'OS_WIN32'   => 'Win32',\n    'OS_VMCMS'   => 'VM/CMS',\n    'OS_ZSYSTEM' => 'Z-System',\n    'OS_CPM'     => 'CP/M',\n    'OS_QDOS'    => 'QDOS',\n    'OS_RISCOS'  => 'RISCOS',\n    'OS_UNKNOWN' => 'Unknown',\n  }\n  unless OS_NAMES.key? os_code then\n    puts \"invalid OS_CODE `#{os_code}'\"\n    exit\n  end\n  message \"#{OS_NAMES[os_code]}\\n\"\n  defines << \"OS_CODE=#{os_code}\"\n\n  $defs.concat(defines.collect{|d|' -D'+d})\n\n  create_makefile('zlib')\n\nend\n"
  },
  {
    "path": "ext/zlib/zlib.c",
    "content": "/*\n * zlib.c - An interface for zlib.\n *\n *   Copyright (C) UENO Katsuhiro 2000-2003\n *\n * $Id$\n */\n\n#include <ruby.h>\n#include <zlib.h>\n#include <time.h>\n\n#define RUBY_ZLIB_VERSION  \"0.6.0\"\n\n\n#define OBJ_IS_FREED(val)  (RBASIC(val)->flags == 0)\n\n#ifndef GZIP_SUPPORT\n#define GZIP_SUPPORT  1\n#endif\n\n/* from zutil.h */\n#ifndef DEF_MEM_LEVEL\n#if MAX_MEM_LEVEL >= 8\n#define DEF_MEM_LEVEL  8\n#else\n#define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#endif\n#endif\n\n\n/*--------- Prototypes --------*/\n\nstatic NORETURN(void raise_zlib_error _((int, const char *)));\nstatic VALUE rb_zlib_version _((VALUE));\nstatic VALUE do_checksum _((int, VALUE*, uLong (*) _((uLong, const Bytef*, uInt))));\nstatic VALUE rb_zlib_adler32 _((int, VALUE*, VALUE));\nstatic VALUE rb_zlib_crc32 _((int, VALUE*, VALUE));\nstatic VALUE rb_zlib_crc_table _((VALUE));\nstatic voidpf zlib_mem_alloc _((voidpf, uInt, uInt));\nstatic void zlib_mem_free _((voidpf, voidpf));\nstatic void finalizer_warn _((const char*));\n\nstruct zstream;\nstruct zstream_funcs;\nstatic void zstream_init _((struct zstream*, const struct zstream_funcs *));\nstatic void zstream_expand_buffer _((struct zstream*));\nstatic void zstream_expand_buffer_into _((struct zstream*, int));\nstatic void zstream_append_buffer _((struct zstream*, const char*, int));\nstatic VALUE zstream_detach_buffer _((struct zstream*));\nstatic VALUE zstream_shift_buffer _((struct zstream*, int));\nstatic void zstream_buffer_ungetc _((struct zstream*, int));\nstatic void zstream_append_input _((struct zstream*, const char*, unsigned int));\nstatic void zstream_discard_input _((struct zstream*, unsigned int));\nstatic void zstream_reset_input _((struct zstream*));\nstatic void zstream_passthrough_input _((struct zstream*));\nstatic VALUE zstream_detach_input _((struct zstream*));\nstatic void zstream_reset _((struct zstream*));\nstatic VALUE zstream_end _((struct zstream*));\nstatic void zstream_run _((struct zstream*, Bytef*, uInt, int));\nstatic VALUE zstream_sync _((struct zstream*, Bytef*, uInt));\nstatic void zstream_mark _((struct zstream*));\nstatic void zstream_free _((struct zstream*));\nstatic VALUE zstream_new _((VALUE, const struct zstream_funcs*));\nstatic struct zstream *get_zstream _((VALUE));\nstatic void zstream_finalize _((struct zstream*));\n\nstatic VALUE rb_zstream_end _((VALUE));\nstatic VALUE rb_zstream_reset _((VALUE));\nstatic VALUE rb_zstream_finish _((VALUE));\nstatic VALUE rb_zstream_flush_next_in _((VALUE));\nstatic VALUE rb_zstream_flush_next_out _((VALUE));\nstatic VALUE rb_zstream_avail_out _((VALUE));\nstatic VALUE rb_zstream_set_avail_out _((VALUE, VALUE));\nstatic VALUE rb_zstream_avail_in _((VALUE));\nstatic VALUE rb_zstream_total_in _((VALUE));\nstatic VALUE rb_zstream_total_out _((VALUE));\nstatic VALUE rb_zstream_data_type _((VALUE));\nstatic VALUE rb_zstream_adler _((VALUE));\nstatic VALUE rb_zstream_finished_p _((VALUE));\nstatic VALUE rb_zstream_closed_p _((VALUE));\n\nstatic VALUE rb_deflate_s_allocate _((VALUE));\nstatic VALUE rb_deflate_initialize _((int, VALUE*, VALUE));\nstatic VALUE rb_deflate_init_copy _((VALUE, VALUE));\nstatic VALUE deflate_run _((VALUE));\nstatic VALUE rb_deflate_s_deflate _((int, VALUE*, VALUE));\nstatic void do_deflate _((struct zstream*, VALUE, int));\nstatic VALUE rb_deflate_deflate _((int, VALUE*, VALUE));\nstatic VALUE rb_deflate_addstr _((VALUE, VALUE));\nstatic VALUE rb_deflate_flush _((int, VALUE*, VALUE));\nstatic VALUE rb_deflate_params _((VALUE, VALUE, VALUE));\nstatic VALUE rb_deflate_set_dictionary _((VALUE, VALUE));\n\nstatic VALUE inflate_run _((VALUE));\nstatic VALUE rb_inflate_s_allocate _((VALUE));\nstatic VALUE rb_inflate_initialize _((int, VALUE*, VALUE));\nstatic VALUE rb_inflate_s_inflate _((VALUE, VALUE));\nstatic void do_inflate _((struct zstream*, VALUE));\nstatic VALUE rb_inflate_inflate _((VALUE, VALUE));\nstatic VALUE rb_inflate_addstr _((VALUE, VALUE));\nstatic VALUE rb_inflate_sync _((VALUE, VALUE));\nstatic VALUE rb_inflate_sync_point_p _((VALUE));\nstatic VALUE rb_inflate_set_dictionary _((VALUE, VALUE));\n\n#if GZIP_SUPPORT\nstruct gzfile;\nstatic void gzfile_mark _((struct gzfile*));\nstatic void gzfile_free _((struct gzfile*));\nstatic VALUE gzfile_new _((VALUE, const struct zstream_funcs*, void (*) _((struct gzfile*))));\nstatic void gzfile_reset _((struct gzfile*));\nstatic void gzfile_close _((struct gzfile*, int));\nstatic void gzfile_write_raw _((struct gzfile*));\nstatic VALUE gzfile_read_raw _((struct gzfile*));\nstatic int gzfile_read_raw_ensure _((struct gzfile*, int));\nstatic char *gzfile_read_raw_until_zero _((struct gzfile*, long));\nstatic unsigned int gzfile_get16 _((const unsigned char*));\nstatic unsigned long gzfile_get32 _((const unsigned char*));\nstatic void gzfile_set32 _((unsigned long n, unsigned char*));\nstatic void gzfile_make_header _((struct gzfile*));\nstatic void gzfile_make_footer _((struct gzfile*));\nstatic void gzfile_read_header _((struct gzfile*));\nstatic void gzfile_check_footer _((struct gzfile*));\nstatic void gzfile_write _((struct gzfile*, Bytef*, uInt));\nstatic long gzfile_read_more _((struct gzfile*));\nstatic void gzfile_calc_crc _((struct gzfile*, VALUE));\nstatic VALUE gzfile_read _((struct gzfile*, int));\nstatic VALUE gzfile_read_all _((struct gzfile*));\nstatic void gzfile_ungetc _((struct gzfile*, int));\nstatic VALUE gzfile_writer_end_run _((VALUE));\nstatic void gzfile_writer_end _((struct gzfile*));\nstatic VALUE gzfile_reader_end_run _((VALUE));\nstatic void gzfile_reader_end _((struct gzfile*));\nstatic void gzfile_reader_rewind _((struct gzfile*));\nstatic VALUE gzfile_reader_get_unused _((struct gzfile*));\nstatic struct gzfile *get_gzfile _((VALUE));\nstatic VALUE gzfile_ensure_close _((VALUE));\nstatic VALUE rb_gzfile_s_wrap _((int, VALUE*, VALUE));\nstatic VALUE gzfile_s_open _((int, VALUE*, VALUE, const char*));\n\nstatic VALUE rb_gzfile_to_io _((VALUE));\nstatic VALUE rb_gzfile_crc _((VALUE));\nstatic VALUE rb_gzfile_mtime _((VALUE));\nstatic VALUE rb_gzfile_level _((VALUE));\nstatic VALUE rb_gzfile_os_code _((VALUE));\nstatic VALUE rb_gzfile_orig_name _((VALUE));\nstatic VALUE rb_gzfile_comment _((VALUE));\nstatic VALUE rb_gzfile_lineno _((VALUE));\nstatic VALUE rb_gzfile_set_lineno _((VALUE, VALUE));\nstatic VALUE rb_gzfile_set_mtime _((VALUE, VALUE));\nstatic VALUE rb_gzfile_set_orig_name _((VALUE, VALUE));\nstatic VALUE rb_gzfile_set_comment _((VALUE, VALUE));\nstatic VALUE rb_gzfile_close _((VALUE));\nstatic VALUE rb_gzfile_finish _((VALUE));\nstatic VALUE rb_gzfile_closed_p _((VALUE));\nstatic VALUE rb_gzfile_eof_p _((VALUE));\nstatic VALUE rb_gzfile_sync _((VALUE));\nstatic VALUE rb_gzfile_set_sync _((VALUE, VALUE));\nstatic VALUE rb_gzfile_total_in _((VALUE));\nstatic VALUE rb_gzfile_total_out _((VALUE));\n\nstatic VALUE rb_gzwriter_s_allocate _((VALUE));\nstatic VALUE rb_gzwriter_s_open _((int, VALUE*, VALUE));\nstatic VALUE rb_gzwriter_initialize _((int, VALUE*, VALUE));\nstatic VALUE rb_gzwriter_flush _((int, VALUE*, VALUE));\nstatic VALUE rb_gzwriter_write _((VALUE, VALUE));\nstatic VALUE rb_gzwriter_putc _((VALUE, VALUE));\n\nstatic VALUE rb_gzreader_s_allocate _((VALUE));\nstatic VALUE rb_gzreader_s_open _((int, VALUE*, VALUE));\nstatic VALUE rb_gzreader_initialize _((VALUE, VALUE));\nstatic VALUE rb_gzreader_rewind _((VALUE));\nstatic VALUE rb_gzreader_unused _((VALUE));\nstatic VALUE rb_gzreader_read _((int, VALUE*, VALUE));\nstatic VALUE rb_gzreader_getc _((VALUE));\nstatic VALUE rb_gzreader_readchar _((VALUE));\nstatic VALUE rb_gzreader_each_byte _((VALUE));\nstatic VALUE rb_gzreader_ungetc _((VALUE, VALUE));\nstatic void gzreader_skip_linebreaks _((struct gzfile*));\nstatic VALUE gzreader_gets _((int, VALUE*, VALUE));\nstatic VALUE rb_gzreader_gets _((int, VALUE*, VALUE));\nstatic VALUE rb_gzreader_readline _((int, VALUE*, VALUE));\nstatic VALUE rb_gzreader_each _((int, VALUE*, VALUE));\nstatic VALUE rb_gzreader_readlines _((int, VALUE*, VALUE));\n#endif /* GZIP_SUPPORT */\n\n\nvoid Init_zlib _((void));\n\n\n\n/*--------- Exceptions --------*/\n\nstatic VALUE cZError, cStreamEnd, cNeedDict;\nstatic VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;\n\nstatic void\nraise_zlib_error(err, msg)\n    int err;\n    const char *msg;\n{\n    VALUE exc;\n\n    if (!msg) {\n\tmsg = zError(err);\n    }\n\n    switch(err) {\n      case Z_STREAM_END:\n\texc = rb_exc_new2(cStreamEnd, msg);\n\tbreak;\n      case Z_NEED_DICT:\n\texc = rb_exc_new2(cNeedDict, msg);\n\tbreak;\n      case Z_STREAM_ERROR:\n\texc = rb_exc_new2(cStreamError, msg);\n\tbreak;\n      case Z_DATA_ERROR:\n\texc = rb_exc_new2(cDataError, msg);\n\tbreak;\n      case Z_BUF_ERROR:\n\texc = rb_exc_new2(cBufError, msg);\n\tbreak;\n      case Z_VERSION_ERROR:\n\texc = rb_exc_new2(cVersionError, msg);\n\tbreak;\n      case Z_MEM_ERROR:\n\texc = rb_exc_new2(cMemError, msg);\n\tbreak;\n      case Z_ERRNO:\n\trb_sys_fail(msg);\n\t/* no return */\n      default:\n      {\n\t  char buf[BUFSIZ];\n\t  snprintf(buf, BUFSIZ, \"unknown zlib error %d: %s\", err, msg);\n\t  exc = rb_exc_new2(cZError, buf);\n      }\n    }\n\n    rb_exc_raise(exc);\n}\n\n\n/*--- Warning (in finalizer) ---*/\n\nstatic void\nfinalizer_warn(msg)\n    const char *msg;\n{\n    fprintf(stderr, \"zlib(finalizer): %s\\n\", msg);\n}\n\n\n/*-------- module Zlib --------*/\n\n/*\n * Returns the string which represents the version of zlib library.\n */\nstatic VALUE\nrb_zlib_version(klass)\n    VALUE klass;\n{\n    VALUE str;\n\n    str = rb_str_new2(zlibVersion());\n    OBJ_TAINT(str);  /* for safe */\n    return str;\n}\n\nstatic VALUE\ndo_checksum(argc, argv, func)\n    int argc;\n    VALUE *argv;\n    uLong (*func) _((uLong, const Bytef *, uInt));\n{\n    VALUE str, vsum;\n    unsigned long sum;\n\n    rb_scan_args(argc, argv, \"02\", &str, &vsum);\n\n    if (!NIL_P(vsum)) {\n\tsum = NUM2ULONG(vsum);\n    }\n    else if (NIL_P(str)) {\n\tsum = 0;\n    }\n    else {\n\tsum = func(0, Z_NULL, 0);\n    }\n\n    if (NIL_P(str)) {\n\tsum = func(sum, Z_NULL, 0);\n    }\n    else {\n\tStringValue(str);\n\tsum = func(sum, RSTRING(str)->ptr, RSTRING(str)->len);\n    }\n    return rb_uint2inum(sum);\n}\n\n/*\n * call-seq: Zlib.adler32(string, adler)\n *\n * Calculates Alder-32 checksum for +string+, and returns updated value of\n * +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If\n * +adler+ is omitted, it assumes that the initial value is given to +adler+.\n *\n * FIXME: expression.\n */\nstatic VALUE\nrb_zlib_adler32(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    return do_checksum(argc, argv, adler32);\n}\n\n/*\n * call-seq: Zlib.crc32(string, adler)\n *\n * Calculates CRC checksum for +string+, and returns updated value of +crc+. If\n * +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it\n * assumes that the initial value is given to +crc+.\n *\n * FIXME: expression.\n */\nstatic VALUE\nrb_zlib_crc32(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    return do_checksum(argc, argv, crc32);\n}\n\n/*\n * Returns the table for calculating CRC checksum as an array.\n */\nstatic VALUE\nrb_zlib_crc_table(obj)\n    VALUE obj;\n{\n    const unsigned long *crctbl;\n    VALUE dst;\n    int i;\n\n    crctbl = get_crc_table();\n    dst = rb_ary_new2(256);\n\n    for (i = 0; i < 256; i++) {\n\trb_ary_push(dst, rb_uint2inum(crctbl[i]));\n    }\n    return dst;\n}\n\n\n\n/*-------- zstream - internal APIs --------*/\n\nstruct zstream {\n    unsigned long flags;\n    VALUE buf;\n    long buf_filled;\n    VALUE input;\n    z_stream stream;\n    const struct zstream_funcs {\n\tint (*reset) _((z_streamp));\n\tint (*end) _((z_streamp));\n\tint (*run) _((z_streamp, int));\n    } *func;\n};\n\n#define ZSTREAM_FLAG_READY      0x1\n#define ZSTREAM_FLAG_IN_STREAM  0x2\n#define ZSTREAM_FLAG_FINISHED   0x4\n#define ZSTREAM_FLAG_CLOSING    0x8\n#define ZSTREAM_FLAG_UNUSED     0x10\n\n#define ZSTREAM_READY(z)       ((z)->flags |= ZSTREAM_FLAG_READY)\n#define ZSTREAM_IS_READY(z)    ((z)->flags & ZSTREAM_FLAG_READY)\n#define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)\n#define ZSTREAM_IS_CLOSING(z)  ((z)->flags & ZSTREAM_FLAG_CLOSING)\n\n/* I think that more better value should be found,\n   but I gave up finding it. B) */\n#define ZSTREAM_INITIAL_BUFSIZE       1024\n#define ZSTREAM_AVAIL_OUT_STEP_MAX   16384\n#define ZSTREAM_AVAIL_OUT_STEP_MIN    2048\n\nstatic const struct zstream_funcs deflate_funcs = {\n    deflateReset, deflateEnd, deflate,\n};\n\nstatic const struct zstream_funcs inflate_funcs = {\n    inflateReset, inflateEnd, inflate,\n};\n\n\nstatic voidpf\nzlib_mem_alloc(opaque, items, size)\n    voidpf opaque;\n    uInt items, size;\n{\n    return xmalloc(items * size);\n}\n\nstatic void\nzlib_mem_free(opaque, address)\n    voidpf opaque, address;\n{\n    free(address);\n}\n\nstatic void\nzstream_init(z, func)\n    struct zstream *z;\n    const struct zstream_funcs *func;\n{\n    z->flags = 0;\n    z->buf = Qnil;\n    z->buf_filled = 0;\n    z->input = Qnil;\n    z->stream.zalloc = zlib_mem_alloc;\n    z->stream.zfree = zlib_mem_free;\n    z->stream.opaque = Z_NULL;\n    z->stream.msg = Z_NULL;\n    z->stream.next_in = Z_NULL;\n    z->stream.avail_in = 0;\n    z->stream.next_out = Z_NULL;\n    z->stream.avail_out = 0;\n    z->func = func;\n}\n\n#define zstream_init_deflate(z)   zstream_init((z), &deflate_funcs)\n#define zstream_init_inflate(z)   zstream_init((z), &inflate_funcs)\n\nstatic void\nzstream_expand_buffer(z)\n    struct zstream *z;\n{\n    long inc;\n\n    if (NIL_P(z->buf)) {\n\t    /* I uses rb_str_new here not rb_str_buf_new because\n\t       rb_str_buf_new makes a zero-length string. */\n\tz->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);\n\tz->buf_filled = 0;\n\tz->stream.next_out = RSTRING(z->buf)->ptr;\n\tz->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;\n\tRBASIC(z->buf)->klass = 0;\n\treturn;\n    }\n\n    if (RSTRING(z->buf)->len - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {\n\t/* to keep other threads from freezing */\n\tz->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;\n    }\n    else {\n\tinc = z->buf_filled / 2;\n\tif (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {\n\t    inc = ZSTREAM_AVAIL_OUT_STEP_MIN;\n\t}\n\trb_str_resize(z->buf, z->buf_filled + inc);\n\tz->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?\n\t    inc : ZSTREAM_AVAIL_OUT_STEP_MAX;\n    }\n    z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;\n}\n\nstatic void\nzstream_expand_buffer_into(z, size)\n    struct zstream *z;\n    int size;\n{\n    if (NIL_P(z->buf)) {\n\t/* I uses rb_str_new here not rb_str_buf_new because\n\t   rb_str_buf_new makes a zero-length string. */\n\tz->buf = rb_str_new(0, size);\n\tz->buf_filled = 0;\n\tz->stream.next_out = RSTRING(z->buf)->ptr;\n\tz->stream.avail_out = size;\n\tRBASIC(z->buf)->klass = 0;\n    }\n    else if (z->stream.avail_out != size) {\n\trb_str_resize(z->buf, z->buf_filled + size);\n\tz->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;\n\tz->stream.avail_out = size;\n    }\n}\n\nstatic void\nzstream_append_buffer(z, src, len)\n    struct zstream *z;\n    const char *src;\n    int len;\n{\n    if (NIL_P(z->buf)) {\n\tz->buf = rb_str_buf_new(len);\n\trb_str_buf_cat(z->buf, src, len);\n\tz->buf_filled = len;\n\tz->stream.next_out = RSTRING(z->buf)->ptr;\n\tz->stream.avail_out = 0;\n\tRBASIC(z->buf)->klass = 0;\n\treturn;\n    }\n\n    if (RSTRING(z->buf)->len < z->buf_filled + len) {\n\trb_str_resize(z->buf, z->buf_filled + len);\n\tz->stream.avail_out = 0;\n    }\n    else {\n\tif (z->stream.avail_out >= len) {\n\t    z->stream.avail_out -= len;\n\t}\n\telse {\n\t    z->stream.avail_out = 0;\n\t}\n    }\n    memcpy(RSTRING(z->buf)->ptr + z->buf_filled, src, len);\n    z->buf_filled += len;\n    z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;\n}\n\n#define zstream_append_buffer2(z,v) \\\n    zstream_append_buffer((z),RSTRING(v)->ptr,RSTRING(v)->len)\n\nstatic VALUE\nzstream_detach_buffer(z)\n    struct zstream *z;\n{\n    VALUE dst;\n\n    if (NIL_P(z->buf)) {\n\tdst = rb_str_new(0, 0);\n    }\n    else {\n\tdst = z->buf;\n\trb_str_resize(dst, z->buf_filled);\n\tRBASIC(dst)->klass = rb_cString;\n    }\n\n    z->buf = Qnil;\n    z->buf_filled = 0;\n    z->stream.next_out = 0;\n    z->stream.avail_out = 0;\n    return dst;\n}\n\nstatic VALUE\nzstream_shift_buffer(z, len)\n    struct zstream *z;\n    int len;\n{\n    VALUE dst;\n\n    if (z->buf_filled <= len) {\n\treturn zstream_detach_buffer(z);\n    }\n\n    dst = rb_str_substr(z->buf, 0, len);\n    RBASIC(dst)->klass = rb_cString;\n    z->buf_filled -= len;\n    memmove(RSTRING(z->buf)->ptr, RSTRING(z->buf)->ptr + len,\n\t    z->buf_filled);\n    z->stream.next_out = RSTRING(z->buf)->ptr + z->buf_filled;\n    z->stream.avail_out = RSTRING(z->buf)->len - z->buf_filled;\n    if (z->stream.avail_out > ZSTREAM_AVAIL_OUT_STEP_MAX) {\n\tz->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;\n    }\n\n    return dst;\n}\n\nstatic void\nzstream_buffer_ungetc(z, c)\n    struct zstream *z;\n    int c;\n{\n    if (NIL_P(z->buf) || RSTRING(z->buf)->len - z->buf_filled == 0) {\n\tzstream_expand_buffer(z);\n    }\n\n    memmove(RSTRING(z->buf)->ptr + 1, RSTRING(z->buf)->ptr, z->buf_filled);\n    RSTRING(z->buf)->ptr[0] = (char)c;\n    z->buf_filled++;\n    if (z->stream.avail_out > 0) {\n\tz->stream.next_out++;\n\tz->stream.avail_out--;\n    }\n}\n\nstatic void\nzstream_append_input(z, src, len)\n    struct zstream *z;\n    const char *src;\n    unsigned int len;\n{\n    if (len <= 0) return;\n\n    if (NIL_P(z->input)) {\n\tz->input = rb_str_buf_new(len);\n\trb_str_buf_cat(z->input, src, len);\n\tRBASIC(z->input)->klass = 0;\n    }\n    else {\n\trb_str_buf_cat(z->input, src, len);\n    }\n}\n\n#define zstream_append_input2(z,v)\\\n    RB_GC_GUARD(v),\\\n    zstream_append_input((z), RSTRING(v)->ptr, RSTRING(v)->len)\n\nstatic void\nzstream_discard_input(z, len)\n    struct zstream *z;\n    unsigned int len;\n{\n    if (NIL_P(z->input) || RSTRING(z->input)->len <= len) {\n\tz->input = Qnil;\n    }\n    else {\n\tmemmove(RSTRING(z->input)->ptr, RSTRING(z->input)->ptr + len,\n\t\tRSTRING(z->input)->len - len);\n\trb_str_resize(z->input, RSTRING(z->input)->len - len);\n    }\n}\n\nstatic void\nzstream_reset_input(z)\n    struct zstream *z;\n{\n    z->input = Qnil;\n}\n\nstatic void\nzstream_passthrough_input(z)\n    struct zstream *z;\n{\n    if (!NIL_P(z->input)) {\n\tzstream_append_buffer2(z, z->input);\n\tz->input = Qnil;\n    }\n}\n\nstatic VALUE\nzstream_detach_input(z)\n    struct zstream *z;\n{\n    VALUE dst;\n\n    if (NIL_P(z->input)) {\n\tdst = rb_str_new(0, 0);\n    }\n    else {\n\tdst = z->input;\n\tRBASIC(dst)->klass = rb_cString;\n    }\n    z->input = Qnil;\n    return dst;\n}\n\nstatic void\nzstream_reset(z)\n    struct zstream *z;\n{\n    int err;\n\n    err = z->func->reset(&z->stream);\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n    z->flags = ZSTREAM_FLAG_READY;\n    z->buf = Qnil;\n    z->buf_filled = 0;\n    z->stream.next_out = 0;\n    z->stream.avail_out = 0;\n    zstream_reset_input(z);\n}\n\nstatic VALUE\nzstream_end(z)\n    struct zstream *z;\n{\n    int err;\n\n    if (!ZSTREAM_IS_READY(z)) {\n\trb_warning(\"attempt to close uninitialized zstream; ignored.\");\n\treturn Qnil;\n    }\n    if (z->flags & ZSTREAM_FLAG_IN_STREAM) {\n\trb_warning(\"attempt to close unfinished zstream; reset forced.\");\n\tzstream_reset(z);\n    }\n\n    zstream_reset_input(z);\n    err = z->func->end(&z->stream);\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n    z->flags = 0;\n    return Qnil;\n}\n\nstatic void\nzstream_run(z, src, len, flush)\n    struct zstream *z;\n    Bytef *src;\n    uInt len;\n    int flush;\n{\n    uInt n;\n    int err;\n    volatile VALUE guard;\n\n    if (NIL_P(z->input) && len == 0) {\n\tz->stream.next_in = \"\";\n\tz->stream.avail_in = 0;\n    }\n    else {\n\tzstream_append_input(z, src, len);\n\tz->stream.next_in = RSTRING(z->input)->ptr;\n\tz->stream.avail_in = RSTRING(z->input)->len;\n\t/* keep reference to `z->input' so as not to be garbage collected\n\t   after zstream_reset_input() and prevent `z->stream.next_in'\n\t   from dangling. */\n\tguard = z->input;\n    }\n\n    if (z->stream.avail_out == 0) {\n\tzstream_expand_buffer(z);\n    }\n\n    for (;;) {\n\tn = z->stream.avail_out;\n\terr = z->func->run(&z->stream, flush);\n\tz->buf_filled += n - z->stream.avail_out;\n\trb_thread_schedule();\n\n\tif (err == Z_STREAM_END) {\n\t    z->flags &= ~ZSTREAM_FLAG_IN_STREAM;\n\t    z->flags |= ZSTREAM_FLAG_FINISHED;\n\t    break;\n\t}\n\tif (err != Z_OK) {\n\t    if (flush != Z_FINISH && err == Z_BUF_ERROR\n\t\t&& z->stream.avail_out > 0) {\n\t\tz->flags |= ZSTREAM_FLAG_IN_STREAM;\n\t\tbreak;\n\t    }\n\t    zstream_reset_input(z);\n\t    if (z->stream.avail_in > 0) {\n\t\tzstream_append_input(z, z->stream.next_in, z->stream.avail_in);\n\t    }\n\t    raise_zlib_error(err, z->stream.msg);\n\t}\n\tif (z->stream.avail_out > 0) {\n\t    z->flags |= ZSTREAM_FLAG_IN_STREAM;\n\t    break;\n\t}\n\tzstream_expand_buffer(z);\n    }\n\n    zstream_reset_input(z);\n    if (z->stream.avail_in > 0) {\n\tzstream_append_input(z, z->stream.next_in, z->stream.avail_in);\n        guard = Qnil; /* prevent tail call to make guard effective */\n    }\n}\n\nstatic VALUE\nzstream_sync(z, src, len)\n    struct zstream *z;\n    Bytef *src;\n    uInt len;\n{\n    VALUE rest;\n    int err;\n\n    if (!NIL_P(z->input)) {\n\tz->stream.next_in = RSTRING(z->input)->ptr;\n\tz->stream.avail_in = RSTRING(z->input)->len;\n\terr = inflateSync(&z->stream);\n\tif (err == Z_OK) {\n\t    zstream_discard_input(z,\n\t\t\t\t  RSTRING(z->input)->len - z->stream.avail_in);\n\t    zstream_append_input(z, src, len);\n\t    return Qtrue;\n\t}\n\tzstream_reset_input(z);\n\tif (err != Z_DATA_ERROR) {\n\t    rest = rb_str_new(z->stream.next_in, z->stream.avail_in);\n\t    raise_zlib_error(err, z->stream.msg);\n\t}\n    }\n\n    if (len <= 0) return Qfalse;\n\n    z->stream.next_in = src;\n    z->stream.avail_in = len;\n    err = inflateSync(&z->stream);\n    if (err == Z_OK) {\n\tzstream_append_input(z, z->stream.next_in, z->stream.avail_in);\n\treturn Qtrue;\n    }\n    if (err != Z_DATA_ERROR) {\n\trest = rb_str_new(z->stream.next_in, z->stream.avail_in);\n\traise_zlib_error(err, z->stream.msg);\n    }\n    return Qfalse;\n}\n\nstatic void\nzstream_mark(z)\n    struct zstream *z;\n{\n    rb_gc_mark(z->buf);\n    rb_gc_mark(z->input);\n}\n\nstatic void\nzstream_finalize(z)\n    struct zstream *z;\n{\n    int err = z->func->end(&z->stream);\n    if (err == Z_STREAM_ERROR)\n\tfinalizer_warn(\"the stream state was inconsistent.\");\n    if (err == Z_DATA_ERROR)\n\tfinalizer_warn(\"the stream was freed prematurely.\");\n}\n\nstatic void\nzstream_free(z)\n    struct zstream *z;\n{\n    if (ZSTREAM_IS_READY(z)) {\n\tzstream_finalize(z);\n    }\n    free(z);\n}\n\nstatic VALUE\nzstream_new(klass, funcs)\n    VALUE klass;\n    const struct zstream_funcs *funcs;\n{\n    VALUE obj;\n    struct zstream *z;\n\n    obj = Data_Make_Struct(klass, struct zstream,\n\t\t\t   zstream_mark, zstream_free, z);\n    zstream_init(z, funcs);\n    return obj;\n}\n\n#define zstream_deflate_new(klass)  zstream_new((klass), &deflate_funcs)\n#define zstream_inflate_new(klass)  zstream_new((klass), &inflate_funcs)\n\nstatic struct zstream *\nget_zstream(obj)\n    VALUE obj;\n{\n    struct zstream *z;\n\n    Data_Get_Struct(obj, struct zstream, z);\n    if (!ZSTREAM_IS_READY(z)) {\n\trb_raise(cZError, \"stream is not ready\");\n    }\n    return z;\n}\n\n\n/* ------------------------------------------------------------------------- */\n\n/*\n * Document-class: Zlib::ZStream\n *\n * Zlib::ZStream is the abstract class for the stream which handles the\n * compressed data. The operations are defined in the subclasses:\n * Zlib::Deflate for compression, and Zlib::Inflate for decompression.\n *\n * An instance of Zlib::ZStream has one stream (struct zstream in the source)\n * and two variable-length buffers which associated to the input (next_in) of\n * the stream and the output (next_out) of the stream. In this document,\n * \"input buffer\" means the buffer for input, and \"output buffer\" means the\n * buffer for output.\n *\n * Data input into an instance of Zlib::ZStream are temporally stored into\n * the end of input buffer, and then data in input buffer are processed from\n * the beginning of the buffer until no more output from the stream is\n * produced (i.e. until avail_out > 0 after processing).  During processing,\n * output buffer is allocated and expanded automatically to hold all output\n * data.\n *\n * Some particular instance methods consume the data in output buffer and\n * return them as a String.\n *\n * Here is an ascii art for describing above:\n *\n *    +================ an instance of Zlib::ZStream ================+\n *    ||                                                            ||\n *    ||     +--------+          +-------+          +--------+      ||\n *    ||  +--| output |<---------|zstream|<---------| input  |<--+  ||\n *    ||  |  | buffer |  next_out+-------+next_in   | buffer |   |  ||\n *    ||  |  +--------+                             +--------+   |  ||\n *    ||  |                                                      |  ||\n *    +===|======================================================|===+\n *        |                                                      |\n *        v                                                      |\n *    \"output data\"                                         \"input data\"\n *\n * If an error occurs during processing input buffer, an exception which is a\n * subclass of Zlib::Error is raised.  At that time, both input and output\n * buffer keep their conditions at the time when the error occurs.\n *\n * == Method Catalogue\n *\n * Many of the methods in this class are fairly low-level and unlikely to be\n * of interest to users.  In fact, users are unlikely to use this class\n * directly; rather they will be interested in Zlib::Inflate and\n * Zlib::Deflate.\n *\n * The higher level methods are listed below.\n *\n * - #total_in\n * - #total_out\n * - #data_type\n * - #adler\n * - #reset\n * - #finish\n * - #finished?\n * - #close\n * - #closed?\n */\n\n/*\n * Closes the stream. All operations on the closed stream will raise an\n * exception.\n */\nstatic VALUE\nrb_zstream_end(obj)\n    VALUE obj;\n{\n    zstream_end(get_zstream(obj));\n    return Qnil;\n}\n\n/*\n * Resets and initializes the stream. All data in both input and output buffer\n * are discarded.\n */\nstatic VALUE\nrb_zstream_reset(obj)\n    VALUE obj;\n{\n    zstream_reset(get_zstream(obj));\n    return Qnil;\n}\n\n/*\n * Finishes the stream and flushes output buffer. See Zlib::Deflate#finish and\n * Zlib::Inflate#finish for details of this behavior.\n */\nstatic VALUE\nrb_zstream_finish(obj)\n    VALUE obj;\n{\n    struct zstream *z = get_zstream(obj);\n    VALUE dst;\n\n    zstream_run(z, \"\", 0, Z_FINISH);\n    dst = zstream_detach_buffer(z);\n\n    OBJ_INFECT(dst, obj);\n    return dst;\n}\n\n/*\n * Flushes input buffer and returns all data in that buffer.\n */\nstatic VALUE\nrb_zstream_flush_next_in(obj)\n    VALUE obj;\n{\n    struct zstream *z;\n    VALUE dst;\n\n    Data_Get_Struct(obj, struct zstream, z);\n    dst = zstream_detach_input(z);\n    OBJ_INFECT(dst, obj);\n    return dst;\n}\n\n/*\n * Flushes output buffer and returns all data in that buffer.\n */\nstatic VALUE\nrb_zstream_flush_next_out(obj)\n    VALUE obj;\n{\n    struct zstream *z;\n    VALUE dst;\n\n    Data_Get_Struct(obj, struct zstream, z);\n    dst = zstream_detach_buffer(z);\n    OBJ_INFECT(dst, obj);\n    return dst;\n}\n\n/*\n * Returns number of bytes of free spaces in output buffer.  Because the free\n * space is allocated automatically, this method returns 0 normally.\n */\nstatic VALUE\nrb_zstream_avail_out(obj)\n    VALUE obj;\n{\n    struct zstream *z;\n    Data_Get_Struct(obj, struct zstream, z);\n    return rb_uint2inum(z->stream.avail_out);\n}\n\n/*\n * Allocates +size+ bytes of free space in the output buffer. If there are more\n * than +size+ bytes already in the buffer, the buffer is truncated. Because \n * free space is allocated automatically, you usually don't need to use this\n * method.\n */\nstatic VALUE\nrb_zstream_set_avail_out(obj, size)\n    VALUE obj, size;\n{\n    struct zstream *z = get_zstream(obj);\n\n    Check_Type(size, T_FIXNUM);\n    zstream_expand_buffer_into(z, FIX2INT(size));\n    return size;\n}\n\n/*\n * Returns bytes of data in the input buffer. Normally, returns 0.\n */\nstatic VALUE\nrb_zstream_avail_in(obj)\n    VALUE obj;\n{\n    struct zstream *z;\n    Data_Get_Struct(obj, struct zstream, z);\n    return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING(z->input)->len));\n}\n\n/*\n * Returns the total bytes of the input data to the stream.  FIXME\n */\nstatic VALUE\nrb_zstream_total_in(obj)\n    VALUE obj;\n{\n    return rb_uint2inum(get_zstream(obj)->stream.total_in);\n}\n\n/*\n * Returns the total bytes of the output data from the stream.  FIXME\n */\nstatic VALUE\nrb_zstream_total_out(obj)\n    VALUE obj;\n{\n    return rb_uint2inum(get_zstream(obj)->stream.total_out);\n}\n\n/*\n * Guesses the type of the data which have been inputed into the stream. The\n * returned value is either <tt>Zlib::BINARY</tt>, <tt>Zlib::ASCII</tt>, or\n * <tt>Zlib::UNKNOWN</tt>.\n */\nstatic VALUE\nrb_zstream_data_type(obj)\n    VALUE obj;\n{\n    return INT2FIX(get_zstream(obj)->stream.data_type);\n}\n\n/*\n * Returns the adler-32 checksum.\n */\nstatic VALUE\nrb_zstream_adler(obj)\n    VALUE obj;\n{\n\treturn rb_uint2inum(get_zstream(obj)->stream.adler);\n}\n\n/*\n * Returns true if the stream is finished.\n */\nstatic VALUE\nrb_zstream_finished_p(obj)\n    VALUE obj;\n{\n    return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;\n}\n\n/*\n * Returns true if the stream is closed.\n */\nstatic VALUE\nrb_zstream_closed_p(obj)\n    VALUE obj;\n{\n    struct zstream *z;\n    Data_Get_Struct(obj, struct zstream, z);\n    return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;\n}\n\n\n/* ------------------------------------------------------------------------- */\n\n/*\n * Document-class: Zlib::Deflate\n *\n * Zlib::Deflate is the class for compressing data.  See Zlib::Stream for more\n * information.\n */\n\n#define FIXNUMARG(val, ifnil) \\\n    (NIL_P((val)) ? (ifnil) \\\n    : ((void)Check_Type((val), T_FIXNUM), FIX2INT((val))))\n\n#define ARG_LEVEL(val)     FIXNUMARG((val), Z_DEFAULT_COMPRESSION)\n#define ARG_WBITS(val)     FIXNUMARG((val), MAX_WBITS)\n#define ARG_MEMLEVEL(val)  FIXNUMARG((val), DEF_MEM_LEVEL)\n#define ARG_STRATEGY(val)  FIXNUMARG((val), Z_DEFAULT_STRATEGY)\n#define ARG_FLUSH(val)     FIXNUMARG((val), Z_NO_FLUSH)\n\n\nstatic VALUE\nrb_deflate_s_allocate(klass)\n    VALUE klass;\n{\n    return zstream_deflate_new(klass);\n}\n\n/*\n * call-seq: Zlib::Deflate.new(level=nil, windowBits=nil, memlevel=nil, strategy=nil)\n *\n * Creates a new deflate stream for compression. See zlib.h for details of\n * each argument. If an argument is nil, the default value of that argument is\n * used.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_deflate_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct zstream *z;\n    VALUE level, wbits, memlevel, strategy;\n    int err;\n\n    rb_scan_args(argc, argv, \"04\", &level, &wbits, &memlevel, &strategy);\n    Data_Get_Struct(obj, struct zstream, z);\n\n    err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,\n\t\t       ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),\n\t\t       ARG_STRATEGY(strategy));\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n    ZSTREAM_READY(z);\n\n    return obj;\n}\n\n/*\n * Duplicates the deflate stream.\n */\nstatic VALUE\nrb_deflate_init_copy(self, orig)\n    VALUE self, orig;\n{\n    struct zstream *z1, *z2;\n    int err;\n\n    Data_Get_Struct(self, struct zstream, z1);\n    z2 = get_zstream(orig);\n\n    err = deflateCopy(&z1->stream, &z2->stream);\n    if (err != Z_OK) {\n\traise_zlib_error(err, 0);\n    }\n    z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);\n    z1->buf   = NIL_P(z2->buf)   ? Qnil : rb_str_dup(z2->buf);\n    z1->buf_filled = z2->buf_filled;\n    z1->flags = z2->flags;\n\n    return self;\n}\n\nstatic VALUE\ndeflate_run(args)\n    VALUE args;\n{\n    struct zstream *z = (struct zstream *)((VALUE *)args)[0];\n    VALUE src = ((VALUE *)args)[1];\n\n    zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_FINISH);\n    return zstream_detach_buffer(z);\n}\n\n/*\n * call-seq: Zlib::Deflate.deflate(string[, level])\n *\n * Compresses the given +string+. Valid values of level are\n * <tt>Zlib::NO_COMPRESSION</tt>, <tt>Zlib::BEST_SPEED</tt>,\n * <tt>Zlib::BEST_COMPRESSION</tt>, <tt>Zlib::DEFAULT_COMPRESSION</tt>, and an\n * integer from 0 to 9.\n *\n * This method is almost equivalent to the following code:\n *\n *   def deflate(string, level)\n *     z = Zlib::Deflate.new(level)\n *     dst = z.deflate(string, Zlib::FINISH)\n *     z.close\n *     dst\n *   end\n *\n * TODO: what's default value of +level+?\n *\n */\nstatic VALUE\nrb_deflate_s_deflate(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    struct zstream z;\n    VALUE src, level, dst, args[2];\n    int err, lev;\n\n    rb_scan_args(argc, argv, \"11\", &src, &level);\n\n    lev = ARG_LEVEL(level);\n    StringValue(src);\n    zstream_init_deflate(&z);\n    err = deflateInit(&z.stream, lev);\n    if (err != Z_OK) {\n\traise_zlib_error(err, z.stream.msg);\n    }\n    ZSTREAM_READY(&z);\n\n    args[0] = (VALUE)&z;\n    args[1] = src;\n    dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);\n\n    OBJ_INFECT(dst, src);\n    return dst;\n}\n\nstatic void\ndo_deflate(z, src, flush)\n    struct zstream *z;\n    VALUE src;\n    int flush;\n{\n    if (NIL_P(src)) {\n\tzstream_run(z, \"\", 0, Z_FINISH);\n\treturn;\n    }\n    StringValue(src);\n    if (flush != Z_NO_FLUSH || RSTRING(src)->len > 0) { /* prevent BUF_ERROR */\n\tzstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, flush);\n    }\n}\n\n/*\n * call-seq: deflate(string[, flush])\n *\n * Inputs +string+ into the deflate stream and returns the output from the\n * stream.  On calling this method, both the input and the output buffers of\n * the stream are flushed. If +string+ is nil, this method finishes the\n * stream, just like Zlib::ZStream#finish.\n *\n * The value of +flush+ should be either <tt>Zlib::NO_FLUSH</tt>,\n * <tt>Zlib::SYNC_FLUSH</tt>, <tt>Zlib::FULL_FLUSH</tt>, or\n * <tt>Zlib::FINISH</tt>. See zlib.h for details.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_deflate_deflate(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct zstream *z = get_zstream(obj);\n    VALUE src, flush, dst;\n\n    rb_scan_args(argc, argv, \"11\", &src, &flush);\n    OBJ_INFECT(obj, src);\n    do_deflate(z, src, ARG_FLUSH(flush));\n    dst = zstream_detach_buffer(z);\n\n    OBJ_INFECT(dst, obj);\n    return dst;\n}\n\n/*\n * call-seq: << string\n *\n * Inputs +string+ into the deflate stream just like Zlib::Deflate#deflate, but\n * returns the Zlib::Deflate object itself.  The output from the stream is\n * preserved in output buffer.\n */\nstatic VALUE\nrb_deflate_addstr(obj, src)\n    VALUE obj, src;\n{\n    OBJ_INFECT(obj, src);\n    do_deflate(get_zstream(obj), src, Z_NO_FLUSH);\n    return obj;\n}\n\n/*\n * call-seq: flush(flush)\n *\n * This method is equivalent to <tt>deflate('', flush)</tt>.  If flush is omitted,\n * <tt>Zlib::SYNC_FLUSH</tt> is used as flush.  This method is just provided\n * to improve the readability of your Ruby program.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_deflate_flush(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct zstream *z = get_zstream(obj);\n    VALUE v_flush, dst;\n    int flush;\n\n    rb_scan_args(argc, argv, \"01\", &v_flush);\n    flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);\n    if (flush != Z_NO_FLUSH) {  /* prevent Z_BUF_ERROR */\n\tzstream_run(z, \"\", 0, flush);\n    }\n    dst = zstream_detach_buffer(z);\n\n    OBJ_INFECT(dst, obj);\n    return dst;\n}\n\n/*\n * call-seq: params(level, strategy)\n * \n * Changes the parameters of the deflate stream. See zlib.h for details. The\n * output from the stream by changing the params is preserved in output\n * buffer.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_deflate_params(obj, v_level, v_strategy)\n    VALUE obj, v_level, v_strategy;\n{\n    struct zstream *z = get_zstream(obj);\n    int level, strategy;\n    int err;\n\n    level = ARG_LEVEL(v_level);\n    strategy = ARG_STRATEGY(v_strategy);\n\n    err = deflateParams(&z->stream, level, strategy);\n    while (err == Z_BUF_ERROR) {\n\trb_warning(\"deflateParams() returned Z_BUF_ERROR\");\n\tzstream_expand_buffer(z);\n\terr = deflateParams(&z->stream, level, strategy);\n    }\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n\n    return Qnil;\n}\n\n/*\n * call-seq: set_dictionary(string)\n *\n * Sets the preset dictionary and returns +string+. This method is available\n * just only after Zlib::Deflate.new or Zlib::ZStream#reset method was called.\n * See zlib.h for details.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_deflate_set_dictionary(obj, dic)\n    VALUE obj, dic;\n{\n    struct zstream *z = get_zstream(obj);\n    VALUE src = dic;\n    int err;\n\n    OBJ_INFECT(obj, dic);\n    StringValue(src);\n    err = deflateSetDictionary(&z->stream,\n\t\t\t       RSTRING(src)->ptr, RSTRING(src)->len);\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n\n    return dic;\n}\n\n\n/* ------------------------------------------------------------------------- */\n\n/*\n * Document-class: Zlib::Inflate\n *\n * Zlib:Inflate is the class for decompressing compressed data.  Unlike\n * Zlib::Deflate, an instance of this class is not able to duplicate (clone,\n * dup) itself.\n */\n\n\n\nstatic VALUE\nrb_inflate_s_allocate(klass)\n    VALUE klass;\n{\n    return zstream_inflate_new(klass);\n}\n\n/*\n * call-seq: Zlib::Inflate.new(window_bits)\n *\n * Creates a new inflate stream for decompression. See zlib.h for details\n * of the argument.  If +window_bits+ is +nil+, the default value is used.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_inflate_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct zstream *z;\n    VALUE wbits;\n    int err;\n\n    rb_scan_args(argc, argv, \"01\", &wbits);\n    Data_Get_Struct(obj, struct zstream, z);\n\n    err = inflateInit2(&z->stream, ARG_WBITS(wbits));\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n    ZSTREAM_READY(z);\n\n    return obj;\n}\n\nstatic VALUE\ninflate_run(args)\n    VALUE args;\n{\n    struct zstream *z = (struct zstream *)((VALUE *)args)[0];\n    VALUE src = ((VALUE *)args)[1];\n\n    zstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);\n    zstream_run(z, \"\", 0, Z_FINISH);  /* for checking errors */\n    return zstream_detach_buffer(z);\n}\n\n/*\n * call-seq: Zlib::Inflate.inflate(string)\n *\n * Decompresses +string+. Raises a Zlib::NeedDict exception if a preset\n * dictionary is needed for decompression.\n *\n * This method is almost equivalent to the following code:\n *\n *   def inflate(string)\n *     zstream = Zlib::Inflate.new\n *     buf = zstream.inflate(string)\n *     zstream.finish\n *     zstream.close\n *     buf\n *   end\n *\n */\nstatic VALUE\nrb_inflate_s_inflate(obj, src)\n    VALUE obj, src;\n{\n    struct zstream z;\n    VALUE dst, args[2];\n    int err;\n\n    StringValue(src);\n    zstream_init_inflate(&z);\n    err = inflateInit(&z.stream);\n    if (err != Z_OK) {\n\traise_zlib_error(err, z.stream.msg);\n    }\n    ZSTREAM_READY(&z);\n\n    args[0] = (VALUE)&z;\n    args[1] = src;\n    dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);\n\n    OBJ_INFECT(dst, src);\n    return dst;\n}\n\nstatic void\ndo_inflate(z, src)\n    struct zstream *z;\n    VALUE src;\n{\n    if (NIL_P(src)) {\n\tzstream_run(z, \"\", 0, Z_FINISH);\n\treturn;\n    }\n    StringValue(src);\n    if (RSTRING(src)->len > 0) { /* prevent Z_BUF_ERROR */\n\tzstream_run(z, RSTRING(src)->ptr, RSTRING(src)->len, Z_SYNC_FLUSH);\n    }\n}\n\n/*\n * call-seq: inflate(string)\n *\n * Inputs +string+ into the inflate stream and returns the output from the\n * stream.  Calling this method, both the input and the output buffer of the\n * stream are flushed.  If string is +nil+, this method finishes the stream,\n * just like Zlib::ZStream#finish.\n *\n * Raises a Zlib::NeedDict exception if a preset dictionary is needed to\n * decompress.  Set the dictionary by Zlib::Inflate#set_dictionary and then\n * call this method again with an empty string.  (<i>???</i>)\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_inflate_inflate(obj, src)\n    VALUE obj, src;\n{\n    struct zstream *z = get_zstream(obj);\n    VALUE dst;\n\n    OBJ_INFECT(obj, src);\n\n    if (ZSTREAM_IS_FINISHED(z)) {\n\tif (NIL_P(src)) {\n\t    dst = zstream_detach_buffer(z);\n\t}\n\telse {\n\t    StringValue(src);\n\t    zstream_append_buffer2(z, src);\n\t    dst = rb_str_new(0, 0);\n\t}\n    }\n    else {\n\tdo_inflate(z, src);\n\tdst = zstream_detach_buffer(z);\n\tif (ZSTREAM_IS_FINISHED(z)) {\n\t    zstream_passthrough_input(z);\n\t}\n    }\n\n    OBJ_INFECT(dst, obj);\n    return dst;\n}\n\n/*\n * call-seq: << string\n *\n * Inputs +string+ into the inflate stream just like Zlib::Inflate#inflate, but\n * returns the Zlib::Inflate object itself.  The output from the stream is\n * preserved in output buffer.\n */\nstatic VALUE\nrb_inflate_addstr(obj, src)\n    VALUE obj, src;\n{\n    struct zstream *z = get_zstream(obj);\n\n    OBJ_INFECT(obj, src);\n\n    if (ZSTREAM_IS_FINISHED(z)) {\n\tif (!NIL_P(src)) {\n\t    StringValue(src);\n\t    zstream_append_buffer2(z, src);\n\t}\n    }\n    else {\n\tdo_inflate(z, src);\n\tif (ZSTREAM_IS_FINISHED(z)) {\n\t    zstream_passthrough_input(z);\n\t}\n    }\n\n    return obj;\n}\n\n/*\n * call-seq: sync(string)\n *\n * Inputs +string+ into the end of input buffer and skips data until a full\n * flush point can be found.  If the point is found in the buffer, this method\n * flushes the buffer and returns false.  Otherwise it returns +true+ and the\n * following data of full flush point is preserved in the buffer.\n */\nstatic VALUE\nrb_inflate_sync(obj, src)\n    VALUE obj, src;\n{\n    struct zstream *z = get_zstream(obj);\n\n    OBJ_INFECT(obj, src);\n    StringValue(src);\n    return zstream_sync(z, RSTRING(src)->ptr, RSTRING(src)->len);\n}\n\n/*\n * Quoted verbatim from original documentation:\n *\n *   What is this?\n *\n * <tt>:)</tt>\n */\nstatic VALUE\nrb_inflate_sync_point_p(obj)\n    VALUE obj;\n{\n    struct zstream *z = get_zstream(obj);\n    int err;\n\n    err = inflateSyncPoint(&z->stream);\n    if (err == 1) {\n\treturn Qtrue;\n    }\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n    return Qfalse;\n}\n\n/*\n * Sets the preset dictionary and returns +string+.  This method is available just\n * only after a Zlib::NeedDict exception was raised.  See zlib.h for details.\n *\n * TODO: document better!\n */\nstatic VALUE\nrb_inflate_set_dictionary(obj, dic)\n    VALUE obj, dic;\n{\n    struct zstream *z = get_zstream(obj);\n    VALUE src = dic;\n    int err;\n\n    OBJ_INFECT(obj, dic);\n    StringValue(src);\n    err = inflateSetDictionary(&z->stream,\n\t\t\t       RSTRING(src)->ptr, RSTRING(src)->len);\n    if (err != Z_OK) {\n\traise_zlib_error(err, z->stream.msg);\n    }\n\n    return dic;\n}\n\n\n\n#if GZIP_SUPPORT\n\n/* NOTE: Features for gzip files of Ruby/zlib are written from scratch\n *       and using undocumented feature of zlib, negative wbits.\n *       I don't think gzFile APIs of zlib are good for Ruby.\n */\n\n/*------- .gz file header --------*/\n\n#define GZ_MAGIC1             0x1f\n#define GZ_MAGIC2             0x8b\n#define GZ_METHOD_DEFLATE     8\n#define GZ_FLAG_MULTIPART     0x2\n#define GZ_FLAG_EXTRA         0x4\n#define GZ_FLAG_ORIG_NAME     0x8\n#define GZ_FLAG_COMMENT       0x10\n#define GZ_FLAG_ENCRYPT       0x20\n#define GZ_FLAG_UNKNOWN_MASK  0xc0\n\n#define GZ_EXTRAFLAG_FAST     0x4\n#define GZ_EXTRAFLAG_SLOW     0x2\n\n/* from zutil.h */\n#define OS_MSDOS    0x00\n#define OS_AMIGA    0x01\n#define OS_VMS      0x02\n#define OS_UNIX     0x03\n#define OS_ATARI    0x05\n#define OS_OS2      0x06\n#define OS_MACOS    0x07\n#define OS_TOPS20   0x0a\n#define OS_WIN32    0x0b\n\n#define OS_VMCMS    0x04\n#define OS_ZSYSTEM  0x08\n#define OS_CPM      0x09\n#define OS_QDOS     0x0c\n#define OS_RISCOS   0x0d\n#define OS_UNKNOWN  0xff\n\n#ifndef OS_CODE\n#define OS_CODE  OS_UNIX\n#endif\n\nstatic ID id_write, id_read, id_flush, id_seek, id_close;\nstatic VALUE cGzError, cNoFooter, cCRCError, cLengthError;\n\n\n\n/*-------- gzfile internal APIs --------*/\n\nstruct gzfile {\n    struct zstream z;\n    VALUE io;\n    int level;\n    time_t mtime;       /* for header */\n    int os_code;        /* for header */\n    VALUE orig_name;    /* for header; must be a String */\n    VALUE comment;      /* for header; must be a String */\n    unsigned long crc;\n    int lineno;\n    int ungetc;\n    void (*end)(struct gzfile *);\n};\n\n#define GZFILE_FLAG_SYNC             ZSTREAM_FLAG_UNUSED\n#define GZFILE_FLAG_HEADER_FINISHED  (ZSTREAM_FLAG_UNUSED << 1)\n#define GZFILE_FLAG_FOOTER_FINISHED  (ZSTREAM_FLAG_UNUSED << 2)\n\n#define GZFILE_IS_FINISHED(gz) \\\n    (ZSTREAM_IS_FINISHED(&gz->z) && (gz)->z.buf_filled == 0)\n\n#define GZFILE_READ_SIZE  2048\n\n\nstatic void\ngzfile_mark(gz)\n    struct gzfile *gz;\n{\n    rb_gc_mark(gz->io);\n    rb_gc_mark(gz->orig_name);\n    rb_gc_mark(gz->comment);\n    zstream_mark(&gz->z);\n}\n\nstatic void\ngzfile_free(gz)\n    struct gzfile *gz;\n{\n    struct zstream *z = &gz->z;\n\n    if (ZSTREAM_IS_READY(z)) {\n\tif (z->func == &deflate_funcs) {\n\t    finalizer_warn(\"Zlib::GzipWriter object must be closed explicitly.\");\n\t}\n\tzstream_finalize(z);\n    }\n    free(gz);\n}\n\nstatic VALUE\ngzfile_new(klass, funcs, endfunc)\n    VALUE klass;\n    const struct zstream_funcs *funcs;\n    void (*endfunc) _((struct gzfile *));\n{\n    VALUE obj;\n    struct gzfile *gz;\n\n    obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);\n    zstream_init(&gz->z, funcs);\n    gz->io = Qnil;\n    gz->level = 0;\n    gz->mtime = 0;\n    gz->os_code = OS_CODE;\n    gz->orig_name = Qnil;\n    gz->comment = Qnil;\n    gz->crc = crc32(0, Z_NULL, 0);\n    gz->lineno = 0;\n    gz->ungetc = 0;\n    gz->end = endfunc;\n\n    return obj;\n}\n\n#define gzfile_writer_new(gz) gzfile_new((gz),&deflate_funcs,gzfile_writer_end)\n#define gzfile_reader_new(gz) gzfile_new((gz),&inflate_funcs,gzfile_reader_end)\n\nstatic void\ngzfile_reset(gz)\n    struct gzfile *gz;\n{\n    zstream_reset(&gz->z);\n    gz->crc = crc32(0, Z_NULL, 0);\n    gz->lineno = 0;\n    gz->ungetc = 0;\n}\n\nstatic void\ngzfile_close(gz, closeflag)\n    struct gzfile *gz;\n    int closeflag;\n{\n    VALUE io = gz->io;\n\n    gz->end(gz);\n    gz->io = Qnil;\n    gz->orig_name = Qnil;\n    gz->comment = Qnil;\n    if (closeflag && rb_respond_to(io, id_close)) {\n\trb_funcall(io, id_close, 0);\n    }\n}\n\nstatic void\ngzfile_write_raw(gz)\n    struct gzfile *gz;\n{\n    VALUE str;\n\n    if (gz->z.buf_filled > 0) {\n\tstr = zstream_detach_buffer(&gz->z);\n\tOBJ_TAINT(str);  /* for safe */\n\trb_funcall(gz->io, id_write, 1, str);\n\tif ((gz->z.flags & GZFILE_FLAG_SYNC)\n\t    && rb_respond_to(gz->io, id_flush))\n\t    rb_funcall(gz->io, id_flush, 0);\n    }\n}\n\nstatic VALUE\ngzfile_read_raw(gz)\n    struct gzfile *gz;\n{\n    VALUE str;\n\n    str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));\n    if (!NIL_P(str)) {\n\tCheck_Type(str, T_STRING);\n    }\n    return str;\n}\n\nstatic int\ngzfile_read_raw_ensure(gz, size)\n    struct gzfile *gz;\n    int size;\n{\n    VALUE str;\n\n    while (NIL_P(gz->z.input) || RSTRING(gz->z.input)->len < size) {\n\tstr = gzfile_read_raw(gz);\n\tif (NIL_P(str)) return Qfalse;\n\tzstream_append_input2(&gz->z, str);\n    }\n    return Qtrue;\n}\n\nstatic char *\ngzfile_read_raw_until_zero(gz, offset)\n    struct gzfile *gz;\n    long offset;\n{\n    VALUE str;\n    char *p;\n\n    for (;;) {\n\tp = memchr(RSTRING(gz->z.input)->ptr + offset, '\\0',\n\t\t   RSTRING(gz->z.input)->len - offset);\n\tif (p) break;\n\tstr = gzfile_read_raw(gz);\n\tif (NIL_P(str)) {\n\t    rb_raise(cGzError, \"unexpected end of file\");\n\t}\n\toffset = RSTRING(gz->z.input)->len;\n\tzstream_append_input2(&gz->z, str);\n    }\n    return p;\n}\n\nstatic unsigned int\ngzfile_get16(src)\n    const unsigned char *src;\n{\n    unsigned int n;\n    n  = *(src++) & 0xff;\n    n |= (*(src++) & 0xff) << 8;\n    return n;\n}\n\nstatic unsigned long\ngzfile_get32(src)\n    const unsigned char *src;\n{\n    unsigned long n;\n    n  = *(src++) & 0xff;\n    n |= (*(src++) & 0xff) << 8;\n    n |= (*(src++) & 0xff) << 16;\n    n |= (*(src++) & 0xffU) << 24;\n    return n;\n}\n\nstatic void\ngzfile_set32(n, dst)\n    unsigned long n;\n    unsigned char *dst;\n{\n    *(dst++) = n & 0xff;\n    *(dst++) = (n >> 8) & 0xff;\n    *(dst++) = (n >> 16) & 0xff;\n    *dst     = (n >> 24) & 0xff;\n}\n\nstatic void\ngzfile_make_header(gz)\n    struct gzfile *gz;\n{\n    unsigned char buf[10];  /* the size of gzip header */\n    unsigned char flags = 0, extraflags = 0;\n\n    if (!NIL_P(gz->orig_name)) {\n\tflags |= GZ_FLAG_ORIG_NAME;\n    }\n    if (!NIL_P(gz->comment)) {\n\tflags |= GZ_FLAG_COMMENT;\n    }\n    if (gz->mtime == 0) {\n\tgz->mtime = time(0);\n    }\n\n    if (gz->level == Z_BEST_SPEED) {\n\textraflags |= GZ_EXTRAFLAG_FAST;\n    }\n    else if (gz->level == Z_BEST_COMPRESSION) {\n\textraflags |= GZ_EXTRAFLAG_SLOW;\n    }\n\n    buf[0] = GZ_MAGIC1;\n    buf[1] = GZ_MAGIC2;\n    buf[2] = GZ_METHOD_DEFLATE;\n    buf[3] = flags;\n    gzfile_set32(gz->mtime, &buf[4]);\n    buf[8] = extraflags;\n    buf[9] = gz->os_code;\n    zstream_append_buffer(&gz->z, buf, sizeof(buf));\n\n    if (!NIL_P(gz->orig_name)) {\n\tzstream_append_buffer2(&gz->z, gz->orig_name);\n\tzstream_append_buffer(&gz->z, \"\\0\", 1);\n    }\n    if (!NIL_P(gz->comment)) {\n\tzstream_append_buffer2(&gz->z, gz->comment);\n\tzstream_append_buffer(&gz->z, \"\\0\", 1);\n    }\n\n    gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;\n}\n\nstatic void\ngzfile_make_footer(gz)\n    struct gzfile *gz;\n{\n    unsigned char buf[8];  /* 8 is the size of gzip footer */\n\n    gzfile_set32(gz->crc, buf);\n    gzfile_set32(gz->z.stream.total_in, &buf[4]);\n    zstream_append_buffer(&gz->z, buf, sizeof(buf));\n    gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;\n}\n\nstatic void\ngzfile_read_header(gz)\n    struct gzfile *gz;\n{\n    const unsigned char *head;\n    long len;\n    char flags, *p;\n\n    if (!gzfile_read_raw_ensure(gz, 10)) {  /* 10 is the size of gzip header */\n\trb_raise(cGzError, \"not in gzip format\");\n    }\n\n    head = RSTRING(gz->z.input)->ptr;\n\n    if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {\n\trb_raise(cGzError, \"not in gzip format\");\n    }\n    if (head[2] != GZ_METHOD_DEFLATE) {\n\trb_raise(cGzError, \"unsupported compression method %d\", head[2]);\n    }\n\n    flags = head[3];\n    if (flags & GZ_FLAG_MULTIPART) {\n\trb_raise(cGzError, \"multi-part gzip file is not supported\");\n    }\n    else if (flags & GZ_FLAG_ENCRYPT) {\n\trb_raise(cGzError, \"encrypted gzip file is not supported\");\n    }\n    else if (flags & GZ_FLAG_UNKNOWN_MASK) {\n\trb_raise(cGzError, \"unknown flags 0x%02x\", flags);\n    }\n\n    if (head[8] & GZ_EXTRAFLAG_FAST) {\n\tgz->level = Z_BEST_SPEED;\n    }\n    else if (head[8] & GZ_EXTRAFLAG_SLOW) {\n\tgz->level = Z_BEST_COMPRESSION;\n    }\n    else {\n\tgz->level = Z_DEFAULT_COMPRESSION;\n    }\n\n    gz->mtime = gzfile_get32(&head[4]);\n    gz->os_code = head[9];\n    zstream_discard_input(&gz->z, 10);\n\n    if (flags & GZ_FLAG_EXTRA) {\n\tif (!gzfile_read_raw_ensure(gz, 2)) {\n\t    rb_raise(cGzError, \"unexpected end of file\");\n\t}\n\tlen = gzfile_get16(RSTRING(gz->z.input)->ptr);\n\tif (!gzfile_read_raw_ensure(gz, 2 + len)) {\n\t    rb_raise(cGzError, \"unexpected end of file\");\n\t}\n\tzstream_discard_input(&gz->z, 2 + len);\n    }\n    if (flags & GZ_FLAG_ORIG_NAME) {\n\tp = gzfile_read_raw_until_zero(gz, 0);\n\tlen = p - RSTRING(gz->z.input)->ptr;\n\tgz->orig_name = rb_str_new(RSTRING(gz->z.input)->ptr, len);\n\tOBJ_TAINT(gz->orig_name);  /* for safe */\n\tzstream_discard_input(&gz->z, len + 1);\n    }\n    if (flags & GZ_FLAG_COMMENT) {\n\tp = gzfile_read_raw_until_zero(gz, 0);\n\tlen = p - RSTRING(gz->z.input)->ptr;\n\tgz->comment = rb_str_new(RSTRING(gz->z.input)->ptr, len);\n\tOBJ_TAINT(gz->comment);  /* for safe */\n\tzstream_discard_input(&gz->z, len + 1);\n    }\n\n    if (gz->z.input != Qnil && RSTRING(gz->z.input)->len > 0) {\n\tzstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);\n    }\n}\n\nstatic void\ngzfile_check_footer(gz)\n    struct gzfile *gz;\n{\n    unsigned long crc, length;\n\n    gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;\n\n    if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */\n\trb_raise(cNoFooter, \"footer is not found\");\n    }\n\n    crc = gzfile_get32(RSTRING(gz->z.input)->ptr);\n    length = gzfile_get32(RSTRING(gz->z.input)->ptr + 4);\n\n    gz->z.stream.total_in += 8;  /* to rewind correctly */\n    zstream_discard_input(&gz->z, 8);\n\n    if (gz->crc != crc) {\n\trb_raise(cCRCError, \"invalid compressed data -- crc error\");\n    }\n    if (gz->z.stream.total_out != length) {\n\trb_raise(cLengthError, \"invalid compressed data -- length error\");\n    }\n}\n\nstatic void\ngzfile_write(gz, str, len)\n    struct gzfile *gz;\n    Bytef *str;\n    uInt len;\n{\n    if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {\n\tgzfile_make_header(gz);\n    }\n\n    if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {\n\tgz->crc = crc32(gz->crc, str, len);\n\tzstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)\n\t\t    ? Z_SYNC_FLUSH : Z_NO_FLUSH);\n    }\n    gzfile_write_raw(gz);\n}\n\nstatic long\ngzfile_read_more(gz)\n    struct gzfile *gz;\n{\n    volatile VALUE str;\n\n    while (!ZSTREAM_IS_FINISHED(&gz->z)) {\n\tstr = gzfile_read_raw(gz);\n\tif (NIL_P(str)) {\n\t    if (!ZSTREAM_IS_FINISHED(&gz->z)) {\n\t\trb_raise(cGzError, \"unexpected end of file\");\n\t    }\n\t    break;\n\t}\n\tif (RSTRING(str)->len > 0) { /* prevent Z_BUF_ERROR */\n\t    zstream_run(&gz->z, RSTRING(str)->ptr, RSTRING(str)->len,\n\t\t\tZ_SYNC_FLUSH);\n\t}\n\tif (gz->z.buf_filled > 0) break;\n    }\n    return gz->z.buf_filled;\n}\n\nstatic void\ngzfile_calc_crc(gz, str)\n    struct gzfile *gz;\n    VALUE str;\n{\n    if (RSTRING(str)->len <= gz->ungetc) {\n\tgz->ungetc -= RSTRING(str)->len;\n    }\n    else {\n\tgz->crc = crc32(gz->crc, RSTRING(str)->ptr + gz->ungetc,\n\t\t\tRSTRING(str)->len - gz->ungetc);\n\tgz->ungetc = 0;\n    }\n}\n\nstatic VALUE\ngzfile_read(gz, len)\n    struct gzfile *gz;\n    int len;\n{\n    VALUE dst;\n\n    if (len < 0)\n        rb_raise(rb_eArgError, \"negative length %d given\", len);\n    if (len == 0)\n\treturn rb_str_new(0, 0);\n    while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {\n\tgzfile_read_more(gz);\n    }\n    if (GZFILE_IS_FINISHED(gz)) {\n\tif (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {\n\t    gzfile_check_footer(gz);\n\t}\n\treturn Qnil;\n    }\n\n    dst = zstream_shift_buffer(&gz->z, len);\n    gzfile_calc_crc(gz, dst);\n\n    OBJ_TAINT(dst);  /* for safe */\n    return dst;\n}\n\nstatic VALUE\ngzfile_read_all(gz)\n    struct gzfile *gz;\n{\n    VALUE dst;\n\n    while (!ZSTREAM_IS_FINISHED(&gz->z)) {\n\tgzfile_read_more(gz);\n    }\n    if (GZFILE_IS_FINISHED(gz)) {\n\tif (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {\n\t    gzfile_check_footer(gz);\n\t}\n\treturn rb_str_new(0, 0);\n    }\n\n    dst = zstream_detach_buffer(&gz->z);\n    gzfile_calc_crc(gz, dst);\n\n    OBJ_TAINT(dst);  /* for safe */\n    return dst;\n}\n\nstatic void\ngzfile_ungetc(gz, c)\n    struct gzfile *gz;\n    int c;\n{\n    zstream_buffer_ungetc(&gz->z, c);\n    gz->ungetc++;\n}\n\nstatic VALUE\ngzfile_writer_end_run(arg)\n    VALUE arg;\n{\n    struct gzfile *gz = (struct gzfile *)arg;\n\n    if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {\n\tgzfile_make_header(gz);\n    }\n\n    zstream_run(&gz->z, \"\", 0, Z_FINISH);\n    gzfile_make_footer(gz);\n    gzfile_write_raw(gz);\n\n    return Qnil;\n}\n\nstatic void\ngzfile_writer_end(gz)\n    struct gzfile *gz;\n{\n    if (ZSTREAM_IS_CLOSING(&gz->z)) return;\n    gz->z.flags |= ZSTREAM_FLAG_CLOSING;\n\n    rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);\n}\n\nstatic VALUE\ngzfile_reader_end_run(arg)\n    VALUE arg;\n{\n    struct gzfile *gz = (struct gzfile *)arg;\n\n    if (GZFILE_IS_FINISHED(gz)\n\t&& !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {\n\tgzfile_check_footer(gz);\n    }\n\n    return Qnil;\n}\n\nstatic void\ngzfile_reader_end(gz)\n    struct gzfile *gz;\n{\n    if (ZSTREAM_IS_CLOSING(&gz->z)) return;\n    gz->z.flags |= ZSTREAM_FLAG_CLOSING;\n\n    rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);\n}\n\nstatic void\ngzfile_reader_rewind(gz)\n    struct gzfile *gz;\n{\n    long n;\n\n    n = gz->z.stream.total_in;\n    if (!NIL_P(gz->z.input)) {\n\tn += RSTRING(gz->z.input)->len;\n    }\n\n    rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));\n    gzfile_reset(gz);\n}\n\nstatic VALUE\ngzfile_reader_get_unused(gz)\n    struct gzfile *gz;\n{\n    VALUE str;\n\n    if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;\n    if (!GZFILE_IS_FINISHED(gz)) return Qnil;\n    if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {\n\tgzfile_check_footer(gz);\n    }\n    if (NIL_P(gz->z.input)) return Qnil;\n\n    str = rb_str_dup(gz->z.input);\n    OBJ_TAINT(str);  /* for safe */\n    return str;\n}\n\nstatic struct gzfile *\nget_gzfile(obj)\n    VALUE obj;\n{\n    struct gzfile *gz;\n\n    Data_Get_Struct(obj, struct gzfile, gz);\n    if (!ZSTREAM_IS_READY(&gz->z)) {\n\trb_raise(cGzError, \"closed gzip stream\");\n    }\n    return gz;\n}\n\n\n/* ------------------------------------------------------------------------- */\n\n/*\n * Document-class: Zlib::GzipFile\n *\n * Zlib::GzipFile is an abstract class for handling a gzip formatted\n * compressed file. The operations are defined in the subclasses,\n * Zlib::GzipReader for reading, and Zlib::GzipWriter for writing.\n *\n * GzipReader should be used by associating an IO, or IO-like, object.\n */\n\n\nstatic VALUE\ngzfile_ensure_close(obj)\n    VALUE obj;\n{\n    struct gzfile *gz;\n\n    Data_Get_Struct(obj, struct gzfile, gz);\n    if (ZSTREAM_IS_READY(&gz->z)) {\n\tgzfile_close(gz, 1);\n    }\n    return Qnil;\n}\n\n/*\n * See Zlib::GzipReader#wrap and Zlib::GzipWriter#wrap.\n */\nstatic VALUE\nrb_gzfile_s_wrap(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj = rb_class_new_instance(argc, argv, klass);\n\n    if (rb_block_given_p()) {\n\treturn rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);\n    }\n    else {\n\treturn obj;\n    }\n}\n\n/*\n * See Zlib::GzipReader#open and Zlib::GzipWriter#open.\n */\nstatic VALUE\ngzfile_s_open(argc, argv, klass, mode)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n    const char *mode;\n{\n    VALUE io, filename;\n\n    if (argc < 1) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (0 for 1)\");\n    }\n    filename = argv[0];\n    SafeStringValue(filename);\n    io = rb_file_open(RSTRING(filename)->ptr, mode);\n\n    argv[0] = io;\n    return rb_gzfile_s_wrap(argc, argv, klass);\n}\n\n/*\n * Same as IO.\n */\nstatic VALUE\nrb_gzfile_to_io(obj)\n    VALUE obj;\n{\n    return get_gzfile(obj)->io;\n}\n\n/*\n * Returns CRC value of the uncompressed data.\n */\nstatic VALUE\nrb_gzfile_crc(obj)\n    VALUE obj;\n{\n    return rb_uint2inum(get_gzfile(obj)->crc);\n}\n\n/*\n * Returns last modification time recorded in the gzip file header.\n */\nstatic VALUE\nrb_gzfile_mtime(obj)\n    VALUE obj;\n{\n    return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);\n}\n\n/*\n * Returns compression level.\n */\nstatic VALUE\nrb_gzfile_level(obj)\n    VALUE obj;\n{\n    return INT2FIX(get_gzfile(obj)->level);\n}\n\n/*\n * Returns OS code number recorded in the gzip file header.\n */\nstatic VALUE\nrb_gzfile_os_code(obj)\n    VALUE obj;\n{\n    return INT2FIX(get_gzfile(obj)->os_code);\n}\n\n/*\n * Returns original filename recorded in the gzip file header, or +nil+ if\n * original filename is not present.\n */\nstatic VALUE\nrb_gzfile_orig_name(obj)\n    VALUE obj;\n{\n    VALUE str = get_gzfile(obj)->orig_name;\n    if (!NIL_P(str)) {\n\tstr = rb_str_dup(str);\n    }\n    OBJ_TAINT(str);  /* for safe */\n    return str;\n}\n\n/*\n * Returns comments recorded in the gzip file header, or nil if the comments\n * is not present.\n */\nstatic VALUE\nrb_gzfile_comment(obj)\n    VALUE obj;\n{\n    VALUE str = get_gzfile(obj)->comment;\n    if (!NIL_P(str)) {\n\tstr = rb_str_dup(str);\n    }\n    OBJ_TAINT(str);  /* for safe */\n    return str;\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_lineno(obj)\n    VALUE obj;\n{\n    return INT2NUM(get_gzfile(obj)->lineno);\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_set_lineno(obj, lineno)\n    VALUE obj, lineno;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    gz->lineno = NUM2INT(lineno);\n    return lineno;\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_set_mtime(obj, mtime)\n    VALUE obj, mtime;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE val;\n\n    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {\n\trb_raise(cGzError, \"header is already written\");\n    }\n\n    if (FIXNUM_P(mtime)) {\n\tgz->mtime = FIX2INT(mtime);\n    }\n    else {\n\tval = rb_Integer(mtime);\n\tgz->mtime = FIXNUM_P(val) ? FIX2INT(val) : rb_big2ulong(val);\n    }\n    return mtime;\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_set_orig_name(obj, str)\n    VALUE obj, str;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE s;\n    char *p;\n\n    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {\n\trb_raise(cGzError, \"header is already written\");\n    }\n    s = rb_str_dup(rb_str_to_str(str));\n    p = memchr(RSTRING(s)->ptr, '\\0', RSTRING(s)->len);\n    if (p) {\n\trb_str_resize(s, p - RSTRING(s)->ptr);\n    }\n    gz->orig_name = s;\n    return str;\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_set_comment(obj, str)\n    VALUE obj, str;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE s;\n    char *p;\n\n    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {\n\trb_raise(cGzError, \"header is already written\");\n    }\n    s = rb_str_dup(rb_str_to_str(str));\n    p = memchr(RSTRING(s)->ptr, '\\0', RSTRING(s)->len);\n    if (p) {\n\trb_str_resize(s, p - RSTRING(s)->ptr);\n    }\n    gz->comment = s;\n    return str;\n}\n\n/*\n * Closes the GzipFile object. This method calls close method of the\n * associated IO object. Returns the associated IO object.\n */\nstatic VALUE\nrb_gzfile_close(obj)\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE io;\n\n    io = gz->io;\n    gzfile_close(gz, 1);\n    return io;\n}\n\n/*\n * Closes the GzipFile object. Unlike Zlib::GzipFile#close, this method never\n * calls the close method of the associated IO object. Returns the associated IO\n * object.\n */\nstatic VALUE\nrb_gzfile_finish(obj)\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE io;\n\n    io = gz->io;\n    gzfile_close(gz, 0);\n    return io;\n}\n\n/*\n * Same as IO.\n */\nstatic VALUE\nrb_gzfile_closed_p(obj)\n    VALUE obj;\n{\n    struct gzfile *gz;\n    Data_Get_Struct(obj, struct gzfile, gz);\n    return NIL_P(gz->io) ? Qtrue : Qfalse;\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_eof_p(obj)\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;\n}\n\n/*\n * Same as IO.\n */\nstatic VALUE\nrb_gzfile_sync(obj)\n    VALUE obj;\n{\n    return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;\n}\n\n/*\n * call-seq: sync = flag\n *\n * Same as IO.  If flag is +true+, the associated IO object must respond to the\n * +flush+ method.  While +sync+ mode is +true+, the compression ratio\n * decreases sharply.\n */\nstatic VALUE\nrb_gzfile_set_sync(obj, mode)\n    VALUE obj, mode;\n{\n    struct gzfile *gz = get_gzfile(obj);\n\n    if (RTEST(mode)) {\n\tgz->z.flags |= GZFILE_FLAG_SYNC;\n    }\n    else {\n\tgz->z.flags &= ~GZFILE_FLAG_SYNC;\n    }\n    return mode;\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_total_in(obj)\n    VALUE obj;\n{\n    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);\n}\n\n/*\n * ???\n */\nstatic VALUE\nrb_gzfile_total_out(obj)\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);\n}\n\n\n/* ------------------------------------------------------------------------- */\n\n/*\n * Document-class: Zlib::GzipWriter\n *\n * Zlib::GzipWriter is a class for writing gzipped files.  GzipWriter should\n * be used with an instance of IO, or IO-like, object. \n *\n * For example:\n *\n *   Zlib::GzipWriter.open('hoge.gz') do |gz|\n *     gz.write 'jugemu jugemu gokou no surikire...'\n *   end\n *\n *   File.open('hoge.gz', 'w') do |f|\n *     gz = Zlib::GzipWriter.new(f)\n *     gz.write 'jugemu jugemu gokou no surikire...'\n *     gz.close\n *   end\n *\n *   # TODO: test these.  Are they equivalent?  Can GzipWriter.new take a\n *   # block?\n *\n * NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close\n * GzipWriter objects by Zlib::GzipWriter#close etc.  Otherwise, GzipWriter\n * will be not able to write the gzip footer and will generate a broken gzip\n * file.\n */\n\nstatic VALUE\nrb_gzwriter_s_allocate(klass)\n    VALUE klass;\n{\n    return gzfile_writer_new(klass);\n}\n\n/*\n * call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }\n *\n * Opens a file specified by +filename+ for writing gzip compressed data, and\n * returns a GzipWriter object associated with that file.  Further details of\n * this method are found in Zlib::GzipWriter.new and Zlib::GzipWriter#wrap.\n */\nstatic VALUE\nrb_gzwriter_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    return gzfile_s_open(argc, argv, klass, \"wb\");\n}\n\n/*\n * call-seq: Zlib::GzipWriter.new(io, level, strategy)\n *\n * Creates a GzipWriter object associated with +io+. +level+ and +strategy+\n * should be the same as the arguments of Zlib::Deflate.new.  The GzipWriter\n * object writes gzipped data to +io+.  At least, +io+ must respond to the\n * +write+ method that behaves same as write method in IO class.\n */\nstatic VALUE\nrb_gzwriter_initialize(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct gzfile *gz;\n    VALUE io, level, strategy;\n    int err;\n\n    rb_scan_args(argc, argv, \"12\", &io, &level, &strategy);\n    Data_Get_Struct(obj, struct gzfile, gz);\n\n    /* this is undocumented feature of zlib */\n    gz->level = ARG_LEVEL(level);\n    err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,\n\t\t       -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));\n    if (err != Z_OK) {\n\traise_zlib_error(err, gz->z.stream.msg);\n    }\n    gz->io = io;\n    ZSTREAM_READY(&gz->z);\n\n    return obj;\n}\n\n/*\n * call-seq: flush(flush=nil)\n *\n * Flushes all the internal buffers of the GzipWriter object.  The meaning of\n * +flush+ is same as in Zlib::Deflate#deflate.  <tt>Zlib::SYNC_FLUSH</tt> is used if\n * +flush+ is omitted.  It is no use giving flush <tt>Zlib::NO_FLUSH</tt>.\n */\nstatic VALUE\nrb_gzwriter_flush(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE v_flush;\n    int flush;\n\n    rb_scan_args(argc, argv, \"01\", &v_flush);\n\n    flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);\n    if (flush != Z_NO_FLUSH) {  /* prevent Z_BUF_ERROR */\n\tzstream_run(&gz->z, \"\", 0, flush);\n    }\n\n    gzfile_write_raw(gz);\n    if (rb_respond_to(gz->io, id_flush)) {\n\trb_funcall(gz->io, id_flush, 0);\n    }\n    return obj;\n}\n\n/*\n * Same as IO.\n */\nstatic VALUE\nrb_gzwriter_write(obj, str)\n    VALUE obj, str;\n{\n    struct gzfile *gz = get_gzfile(obj);\n\n    if (TYPE(str) != T_STRING) {\n\tstr = rb_obj_as_string(str);\n    }\n    gzfile_write(gz, RSTRING(str)->ptr, RSTRING(str)->len);\n    return INT2FIX(RSTRING(str)->len);\n}\n\n/*\n * Same as IO.\n */\nstatic VALUE\nrb_gzwriter_putc(obj, ch)\n    VALUE obj, ch;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    char c = NUM2CHR(ch);\n\n    gzfile_write(gz, &c, 1);\n    return ch;\n}\n\n\n\n/*\n * Document-method: <<\n * Same as IO.\n */\n#define rb_gzwriter_addstr  rb_io_addstr\n/*\n * Document-method: printf\n * Same as IO.\n */\n#define rb_gzwriter_printf  rb_io_printf\n/*\n * Document-method: print\n * Same as IO.\n */\n#define rb_gzwriter_print  rb_io_print\n/*\n * Document-method: puts\n * Same as IO.\n */\n#define rb_gzwriter_puts  rb_io_puts\n\n\n/* ------------------------------------------------------------------------- */\n\n/*\n * Document-class: Zlib::GzipReader\n *\n * Zlib::GzipReader is the class for reading a gzipped file.  GzipReader should\n * be used an IO, or -IO-lie, object.\n *\n *   Zlib::GzipReader.open('hoge.gz') {|gz|\n *     print gz.read\n *   }\n *\n *   File.open('hoge.gz') do |f|\n *     gz = Zlib::GzipReader.new(f)\n *     print gz.read\n *     gz.close\n *   end\n *\n *   # TODO: test these.  Are they equivalent?  Can GzipReader.new take a\n *   # block?\n *\n * == Method Catalogue\n *\n * The following methods in Zlib::GzipReader are just like their counterparts\n * in IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an\n * error was found in the gzip file.\n * - #each\n * - #each_line\n * - #each_byte\n * - #gets\n * - #getc\n * - #lineno\n * - #lineno=\n * - #read\n * - #readchar\n * - #readline\n * - #readlines\n * - #ungetc\n *\n * Be careful of the footer of the gzip file. A gzip file has the checksum of\n * pre-compressed data in its footer. GzipReader checks all uncompressed data\n * against that checksum at the following cases, and if it fails, raises\n * <tt>Zlib::GzipFile::NoFooter</tt>, <tt>Zlib::GzipFile::CRCError</tt>, or\n * <tt>Zlib::GzipFile::LengthError</tt> exception.\n *\n * - When an reading request is received beyond the end of file (the end of\n *   compressed data). That is, when Zlib::GzipReader#read,\n *   Zlib::GzipReader#gets, or some other methods for reading returns nil.\n * - When Zlib::GzipFile#close method is called after the object reaches the\n *   end of file.\n * - When Zlib::GzipReader#unused method is called after the object reaches\n *   the end of file.\n *\n * The rest of the methods are adequately described in their own\n * documentation.\n */\n\nstatic VALUE\nrb_gzreader_s_allocate(klass)\n    VALUE klass;\n{\n    return gzfile_reader_new(klass);\n}\n\n/*\n * call-seq: Zlib::GzipReader.open(filename) {|gz| ... }\n *\n * Opens a file specified by +filename+ as a gzipped file, and returns a\n * GzipReader object associated with that file.  Further details of this method\n * are in Zlib::GzipReader.new and ZLib::GzipReader.wrap.\n */\nstatic VALUE\nrb_gzreader_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    return gzfile_s_open(argc, argv, klass, \"rb\");\n}\n\n/*\n * call-seq: Zlib::GzipReader.new(io)\n *\n * Creates a GzipReader object associated with +io+. The GzipReader object reads\n * gzipped data from +io+, and parses/decompresses them.  At least, +io+ must have\n * a +read+ method that behaves same as the +read+ method in IO class.\n *\n * If the gzip file header is incorrect, raises an Zlib::GzipFile::Error\n * exception.\n */\nstatic VALUE\nrb_gzreader_initialize(obj, io)\n    VALUE obj, io;\n{\n    struct gzfile *gz;\n    int err;\n\n    Data_Get_Struct(obj, struct gzfile, gz);\n\n    /* this is undocumented feature of zlib */\n    err = inflateInit2(&gz->z.stream, -MAX_WBITS);\n    if (err != Z_OK) {\n\traise_zlib_error(err, gz->z.stream.msg);\n    }\n    gz->io = io;\n    ZSTREAM_READY(&gz->z);\n    gzfile_read_header(gz);\n\n    return obj;\n}\n\n/*\n * Resets the position of the file pointer to the point created the GzipReader\n * object.  The associated IO object needs to respond to the +seek+ method.\n */\nstatic VALUE\nrb_gzreader_rewind(obj)\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    gzfile_reader_rewind(gz);\n    return INT2FIX(0);\n}\n\n/*\n * Returns the rest of the data which had read for parsing gzip format, or\n * +nil+ if the whole gzip file is not parsed yet.\n */\nstatic VALUE\nrb_gzreader_unused(obj)\n    VALUE obj;\n{\n    struct gzfile *gz;\n    Data_Get_Struct(obj, struct gzfile, gz);\n    return gzfile_reader_get_unused(gz);\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_read(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE vlen;\n    int len;\n\n    rb_scan_args(argc, argv, \"01\", &vlen);\n    if (NIL_P(vlen)) {\n\treturn gzfile_read_all(gz);\n    }\n\n    len = NUM2INT(vlen);\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"negative length %d given\", len);\n    }\n    return gzfile_read(gz, len);\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_getc(obj)\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    VALUE dst;\n\n    dst = gzfile_read(gz, 1);\n    if (!NIL_P(dst)) {\n\tdst = INT2FIX((unsigned int)(RSTRING(dst)->ptr[0]) & 0xff);\n    }\n    return dst;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_readchar(obj)\n    VALUE obj;\n{\n    VALUE dst;\n    dst = rb_gzreader_getc(obj);\n    if (NIL_P(dst)) {\n\trb_raise(rb_eEOFError, \"end of file reached\");\n    }\n    return dst;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_each_byte(obj)\n    VALUE obj;\n{\n    VALUE c;\n    while (!NIL_P(c = rb_gzreader_getc(obj))) {\n\trb_yield(c);\n    }\n    return Qnil;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_ungetc(obj, ch)\n    VALUE obj, ch;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    gzfile_ungetc(gz, NUM2CHR(ch));\n    return Qnil;\n}\n\nstatic void\ngzreader_skip_linebreaks(gz)\n    struct gzfile *gz;\n{\n    VALUE str;\n    char *p;\n    int n;\n\n    while (gz->z.buf_filled == 0) {\n\tif (GZFILE_IS_FINISHED(gz)) return;\n\tgzfile_read_more(gz);\n    }\n    n = 0;\n    p = RSTRING(gz->z.buf)->ptr;\n\n    while (n++, *(p++) == '\\n') {\n\tif (n >= gz->z.buf_filled) {\n\t    str = zstream_detach_buffer(&gz->z);\n\t    gzfile_calc_crc(gz, str);\n\t    while (gz->z.buf_filled == 0) {\n\t\tif (GZFILE_IS_FINISHED(gz)) return;\n\t\tgzfile_read_more(gz);\n\t    }\n\t    n = 0;\n\t    p = RSTRING(gz->z.buf)->ptr;\n\t}\n    }\n\n    str = zstream_shift_buffer(&gz->z, n - 1);\n    gzfile_calc_crc(gz, str);\n}\n\nstatic void\nrscheck(rsptr, rslen, rs)\n    char *rsptr;\n    long rslen;\n    VALUE rs;\n{\n    if (RSTRING(rs)->ptr != rsptr && RSTRING(rs)->len != rslen)\n\trb_raise(rb_eRuntimeError, \"rs modified\");\n}\n\nstatic VALUE\ngzreader_gets(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    struct gzfile *gz = get_gzfile(obj);\n    volatile VALUE rs;\n    VALUE dst;\n    char *rsptr, *p, *res;\n    long rslen, n;\n    int rspara;\n\n    if (argc == 0) {\n\trs = rb_rs;\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &rs);\n\tif (!NIL_P(rs)) {\n\t    Check_Type(rs, T_STRING);\n\t}\n    }\n\n    if (NIL_P(rs)) {\n\tdst = gzfile_read_all(gz);\n\tif (RSTRING(dst)->len != 0) gz->lineno++;\n\telse\n\t\treturn Qnil;\n\treturn dst;\n    }\n\n    if (RSTRING(rs)->len == 0) {\n\trsptr = \"\\n\\n\";\n\trslen = 2;\n\trspara = 1;\n    } else {\n\trsptr = RSTRING(rs)->ptr;\n\trslen = RSTRING(rs)->len;\n\trspara = 0;\n    }\n\n    if (rspara) {\n\tgzreader_skip_linebreaks(gz);\n    }\n\n    while (gz->z.buf_filled < rslen) {\n\tif (ZSTREAM_IS_FINISHED(&gz->z)) {\n\t    if (gz->z.buf_filled > 0) gz->lineno++;\n\t    return gzfile_read(gz, rslen);\n\t}\n\tgzfile_read_more(gz);\n    }\n\n    p = RSTRING(gz->z.buf)->ptr;\n    n = rslen;\n    for (;;) {\n\tif (n > gz->z.buf_filled) {\n\t    if (ZSTREAM_IS_FINISHED(&gz->z)) break;\n\t    gzfile_read_more(gz);\n\t    p = RSTRING(gz->z.buf)->ptr + n - rslen;\n\t}\n\tif (!rspara) rscheck(rsptr, rslen, rs);\n\tres = memchr(p, rsptr[0], (gz->z.buf_filled - n + 1));\n\tif (!res) {\n\t    n = gz->z.buf_filled + 1;\n\t} else {\n\t    n += (long)(res - p);\n\t    p = res;\n\t    if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;\n\t    p++, n++;\n\t}\n    }\n\n    gz->lineno++;\n    dst = gzfile_read(gz, n);\n    if (rspara) {\n\tgzreader_skip_linebreaks(gz);\n    }\n\n    return dst;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_gets(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE dst;\n    dst = gzreader_gets(argc, argv, obj);\n    if (!NIL_P(dst)) {\n\trb_lastline_set(dst);\n    }\n    return dst;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_readline(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE dst;\n    dst = rb_gzreader_gets(argc, argv, obj);\n    if (NIL_P(dst)) {\n\trb_raise(rb_eEOFError, \"end of file reached\");\n    }\n    return dst;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_each(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE str;\n    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {\n\trb_yield(str);\n    }\n    return obj;\n}\n\n/*\n * See Zlib::GzipReader documentation for a description.\n */\nstatic VALUE\nrb_gzreader_readlines(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE str, dst;\n    dst = rb_ary_new();\n    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {\n\trb_ary_push(dst, str);\n    }\n    return dst;\n}\n\n#endif /* GZIP_SUPPORT */\n\n\n\n/*\n * The Zlib module contains several classes for compressing and decompressing\n * streams, and for working with \"gzip\" files.\n *\n * == Classes\n *\n * Following are the classes that are most likely to be of interest to the\n * user:\n * Zlib::Inflate\n * Zlib::Deflate\n * Zlib::GzipReader\n * Zlib::GzipWriter\n *\n * There are two important base classes for the classes above: Zlib::ZStream\n * and Zlib::GzipFile.  Everything else is an error class.\n *\n * == Constants\n *\n * Here's a list.\n *\n *   Zlib::VERSION\n *       The Ruby/zlib version string.\n *\n *   Zlib::ZLIB_VERSION\n *       The string which represents the version of zlib.h.\n *\n *   Zlib::BINARY\n *   Zlib::ASCII\n *   Zlib::UNKNOWN\n *       The integers representing data types which Zlib::ZStream#data_type\n *       method returns.\n *\n *   Zlib::NO_COMPRESSION\n *   Zlib::BEST_SPEED\n *   Zlib::BEST_COMPRESSION\n *   Zlib::DEFAULT_COMPRESSION\n *       The integers representing compression levels which are an argument\n *       for Zlib::Deflate.new, Zlib::Deflate#deflate, and so on.\n *\n *   Zlib::FILTERED\n *   Zlib::HUFFMAN_ONLY\n *   Zlib::DEFAULT_STRATEGY\n *       The integers representing compression methods which are an argument\n *       for Zlib::Deflate.new and Zlib::Deflate#params.\n *\n *   Zlib::DEF_MEM_LEVEL\n *   Zlib::MAX_MEM_LEVEL\n *       The integers representing memory levels which are an argument for\n *       Zlib::Deflate.new, Zlib::Deflate#params, and so on.\n *\n *   Zlib::MAX_WBITS\n *       The default value of windowBits which is an argument for\n *       Zlib::Deflate.new and Zlib::Inflate.new.\n *\n *   Zlib::NO_FLUSH\n *   Zlib::SYNC_FLUSH\n *   Zlib::FULL_FLUSH\n *   Zlib::FINISH\n *       The integers to control the output of the deflate stream, which are\n *       an argument for Zlib::Deflate#deflate and so on.\n *\n *   Zlib::OS_CODE\n *   Zlib::OS_MSDOS\n *   Zlib::OS_AMIGA\n *   Zlib::OS_VMS\n *   Zlib::OS_UNIX\n *   Zlib::OS_VMCMS\n *   Zlib::OS_ATARI\n *   Zlib::OS_OS2\n *   Zlib::OS_MACOS\n *   Zlib::OS_ZSYSTEM\n *   Zlib::OS_CPM\n *   Zlib::OS_TOPS20\n *   Zlib::OS_WIN32\n *   Zlib::OS_QDOS\n *   Zlib::OS_RISCOS\n *   Zlib::OS_UNKNOWN\n *       The return values of Zlib::GzipFile#os_code method.\n */\nvoid Init_zlib()\n{\n    VALUE mZlib, cZStream, cDeflate, cInflate;\n#if GZIP_SUPPORT\n    VALUE cGzipFile, cGzipWriter, cGzipReader;\n#endif\n\n    mZlib = rb_define_module(\"Zlib\");\n\n    cZError = rb_define_class_under(mZlib, \"Error\", rb_eStandardError);\n    cStreamEnd    = rb_define_class_under(mZlib, \"StreamEnd\", cZError);\n    cNeedDict     = rb_define_class_under(mZlib, \"NeedDict\", cZError);\n    cDataError    = rb_define_class_under(mZlib, \"DataError\", cZError);\n    cStreamError  = rb_define_class_under(mZlib, \"StreamError\", cZError);\n    cMemError     = rb_define_class_under(mZlib, \"MemError\", cZError);\n    cBufError     = rb_define_class_under(mZlib, \"BufError\", cZError);\n    cVersionError = rb_define_class_under(mZlib, \"VersionError\", cZError);\n\n    rb_define_module_function(mZlib, \"zlib_version\", rb_zlib_version, 0);\n    rb_define_module_function(mZlib, \"adler32\", rb_zlib_adler32, -1);\n    rb_define_module_function(mZlib, \"crc32\", rb_zlib_crc32, -1);\n    rb_define_module_function(mZlib, \"crc_table\", rb_zlib_crc_table, 0);\n\n    rb_define_const(mZlib, \"VERSION\", rb_str_new2(RUBY_ZLIB_VERSION));\n    rb_define_const(mZlib, \"ZLIB_VERSION\", rb_str_new2(ZLIB_VERSION));\n\n    cZStream = rb_define_class_under(mZlib, \"ZStream\", rb_cObject);\n    rb_undef_alloc_func(cZStream);\n    rb_define_method(cZStream, \"avail_out\", rb_zstream_avail_out, 0);\n    rb_define_method(cZStream, \"avail_out=\", rb_zstream_set_avail_out, 1);\n    rb_define_method(cZStream, \"avail_in\", rb_zstream_avail_in, 0);\n    rb_define_method(cZStream, \"total_in\", rb_zstream_total_in, 0);\n    rb_define_method(cZStream, \"total_out\", rb_zstream_total_out, 0);\n    rb_define_method(cZStream, \"data_type\", rb_zstream_data_type, 0);\n    rb_define_method(cZStream, \"adler\", rb_zstream_adler, 0);\n    rb_define_method(cZStream, \"finished?\", rb_zstream_finished_p, 0);\n    rb_define_method(cZStream, \"stream_end?\", rb_zstream_finished_p, 0);\n    rb_define_method(cZStream, \"closed?\", rb_zstream_closed_p, 0);\n    rb_define_method(cZStream, \"ended?\", rb_zstream_closed_p, 0);\n    rb_define_method(cZStream, \"close\", rb_zstream_end, 0);\n    rb_define_method(cZStream, \"end\", rb_zstream_end, 0);\n    rb_define_method(cZStream, \"reset\", rb_zstream_reset, 0);\n    rb_define_method(cZStream, \"finish\", rb_zstream_finish, 0);\n    rb_define_method(cZStream, \"flush_next_in\", rb_zstream_flush_next_in, 0);\n    rb_define_method(cZStream, \"flush_next_out\", rb_zstream_flush_next_out, 0);\n\n    rb_define_const(mZlib, \"BINARY\", INT2FIX(Z_BINARY));\n    rb_define_const(mZlib, \"ASCII\", INT2FIX(Z_ASCII));\n    rb_define_const(mZlib, \"UNKNOWN\", INT2FIX(Z_UNKNOWN));\n\n    cDeflate = rb_define_class_under(mZlib, \"Deflate\", cZStream);\n    rb_define_singleton_method(cDeflate, \"deflate\", rb_deflate_s_deflate, -1);\n    rb_define_alloc_func(cDeflate, rb_deflate_s_allocate);\n    rb_define_method(cDeflate, \"initialize\", rb_deflate_initialize, -1);\n    rb_define_method(cDeflate, \"initialize_copy\", rb_deflate_init_copy, 1);\n    rb_define_method(cDeflate, \"deflate\", rb_deflate_deflate, -1);\n    rb_define_method(cDeflate, \"<<\", rb_deflate_addstr, 1);\n    rb_define_method(cDeflate, \"flush\", rb_deflate_flush, -1);\n    rb_define_method(cDeflate, \"params\", rb_deflate_params, 2);\n    rb_define_method(cDeflate, \"set_dictionary\", rb_deflate_set_dictionary, 1);\n\n    cInflate = rb_define_class_under(mZlib, \"Inflate\", cZStream);\n    rb_define_singleton_method(cInflate, \"inflate\", rb_inflate_s_inflate, 1);\n    rb_define_alloc_func(cInflate, rb_inflate_s_allocate);\n    rb_define_method(cInflate, \"initialize\", rb_inflate_initialize, -1);\n    rb_define_method(cInflate, \"inflate\", rb_inflate_inflate, 1);\n    rb_define_method(cInflate, \"<<\", rb_inflate_addstr, 1);\n    rb_define_method(cInflate, \"sync\", rb_inflate_sync, 1);\n    rb_define_method(cInflate, \"sync_point?\", rb_inflate_sync_point_p, 0);\n    rb_define_method(cInflate, \"set_dictionary\", rb_inflate_set_dictionary, 1);\n\n    rb_define_const(mZlib, \"NO_COMPRESSION\", INT2FIX(Z_NO_COMPRESSION));\n    rb_define_const(mZlib, \"BEST_SPEED\", INT2FIX(Z_BEST_SPEED));\n    rb_define_const(mZlib, \"BEST_COMPRESSION\", INT2FIX(Z_BEST_COMPRESSION));\n    rb_define_const(mZlib, \"DEFAULT_COMPRESSION\",\n\t\t    INT2FIX(Z_DEFAULT_COMPRESSION));\n\n    rb_define_const(mZlib, \"FILTERED\", INT2FIX(Z_FILTERED));\n    rb_define_const(mZlib, \"HUFFMAN_ONLY\", INT2FIX(Z_HUFFMAN_ONLY));\n    rb_define_const(mZlib, \"DEFAULT_STRATEGY\", INT2FIX(Z_DEFAULT_STRATEGY));\n\n    rb_define_const(mZlib, \"MAX_WBITS\", INT2FIX(MAX_WBITS));\n    rb_define_const(mZlib, \"DEF_MEM_LEVEL\", INT2FIX(DEF_MEM_LEVEL));\n    rb_define_const(mZlib, \"MAX_MEM_LEVEL\", INT2FIX(MAX_MEM_LEVEL));\n\n    rb_define_const(mZlib, \"NO_FLUSH\", INT2FIX(Z_NO_FLUSH));\n    rb_define_const(mZlib, \"SYNC_FLUSH\", INT2FIX(Z_SYNC_FLUSH));\n    rb_define_const(mZlib, \"FULL_FLUSH\", INT2FIX(Z_FULL_FLUSH));\n    rb_define_const(mZlib, \"FINISH\", INT2FIX(Z_FINISH));\n\n#if GZIP_SUPPORT\n    id_write = rb_intern(\"write\");\n    id_read = rb_intern(\"read\");\n    id_flush = rb_intern(\"flush\");\n    id_seek = rb_intern(\"seek\");\n    id_close = rb_intern(\"close\");\n\n    cGzipFile = rb_define_class_under(mZlib, \"GzipFile\", rb_cObject);\n    cGzError = rb_define_class_under(cGzipFile, \"Error\", cZError);\n\n    cNoFooter = rb_define_class_under(cGzipFile, \"NoFooter\", cGzError);\n    cCRCError = rb_define_class_under(cGzipFile, \"CRCError\", cGzError);\n    cLengthError = rb_define_class_under(cGzipFile,\"LengthError\",cGzError);\n\n    cGzipWriter = rb_define_class_under(mZlib, \"GzipWriter\", cGzipFile);\n    cGzipReader = rb_define_class_under(mZlib, \"GzipReader\", cGzipFile);\n    rb_include_module(cGzipReader, rb_mEnumerable);\n\n    rb_define_singleton_method(cGzipFile, \"wrap\", rb_gzfile_s_wrap, -1);\n    rb_undef_alloc_func(cGzipFile);\n    rb_define_method(cGzipFile, \"to_io\", rb_gzfile_to_io, 0);\n    rb_define_method(cGzipFile, \"crc\", rb_gzfile_crc, 0);\n    rb_define_method(cGzipFile, \"mtime\", rb_gzfile_mtime, 0);\n    rb_define_method(cGzipFile, \"level\", rb_gzfile_level, 0);\n    rb_define_method(cGzipFile, \"os_code\", rb_gzfile_os_code, 0);\n    rb_define_method(cGzipFile, \"orig_name\", rb_gzfile_orig_name, 0);\n    rb_define_method(cGzipFile, \"comment\", rb_gzfile_comment, 0);\n    rb_define_method(cGzipReader, \"lineno\", rb_gzfile_lineno, 0);\n    rb_define_method(cGzipReader, \"lineno=\", rb_gzfile_set_lineno, 1);\n    rb_define_method(cGzipWriter, \"mtime=\", rb_gzfile_set_mtime, 1);\n    rb_define_method(cGzipWriter, \"orig_name=\", rb_gzfile_set_orig_name,1);\n    rb_define_method(cGzipWriter, \"comment=\", rb_gzfile_set_comment, 1);\n    rb_define_method(cGzipFile, \"close\", rb_gzfile_close, 0);\n    rb_define_method(cGzipFile, \"finish\", rb_gzfile_finish, 0);\n    rb_define_method(cGzipFile, \"closed?\", rb_gzfile_closed_p, 0);\n    rb_define_method(cGzipReader, \"eof\", rb_gzfile_eof_p, 0);\n    rb_define_method(cGzipReader, \"eof?\", rb_gzfile_eof_p, 0);\n    rb_define_method(cGzipFile, \"sync\", rb_gzfile_sync, 0);\n    rb_define_method(cGzipFile, \"sync=\", rb_gzfile_set_sync, 1);\n    rb_define_method(cGzipReader, \"pos\", rb_gzfile_total_out, 0);\n    rb_define_method(cGzipWriter, \"pos\", rb_gzfile_total_in, 0);\n    rb_define_method(cGzipReader, \"tell\", rb_gzfile_total_out, 0);\n    rb_define_method(cGzipWriter, \"tell\", rb_gzfile_total_in, 0);\n\n    rb_define_singleton_method(cGzipWriter, \"open\", rb_gzwriter_s_open,-1);\n    rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);\n    rb_define_method(cGzipWriter, \"initialize\", rb_gzwriter_initialize,-1);\n    rb_define_method(cGzipWriter, \"flush\", rb_gzwriter_flush, -1);\n    rb_define_method(cGzipWriter, \"write\", rb_gzwriter_write, 1);\n    rb_define_method(cGzipWriter, \"putc\", rb_gzwriter_putc, 1);\n    rb_define_method(cGzipWriter, \"<<\", rb_gzwriter_addstr, 1);\n    rb_define_method(cGzipWriter, \"printf\", rb_gzwriter_printf, -1);\n    rb_define_method(cGzipWriter, \"print\", rb_gzwriter_print, -1);\n    rb_define_method(cGzipWriter, \"puts\", rb_gzwriter_puts, -1);\n\n    rb_define_singleton_method(cGzipReader, \"open\", rb_gzreader_s_open,-1);\n    rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);\n    rb_define_method(cGzipReader, \"initialize\", rb_gzreader_initialize, 1);\n    rb_define_method(cGzipReader, \"rewind\", rb_gzreader_rewind, 0);\n    rb_define_method(cGzipReader, \"unused\", rb_gzreader_unused, 0);\n    rb_define_method(cGzipReader, \"read\", rb_gzreader_read, -1);\n    rb_define_method(cGzipReader, \"getc\", rb_gzreader_getc, 0);\n    rb_define_method(cGzipReader, \"readchar\", rb_gzreader_readchar, 0);\n    rb_define_method(cGzipReader, \"each_byte\", rb_gzreader_each_byte, 0);\n    rb_define_method(cGzipReader, \"ungetc\", rb_gzreader_ungetc, 1);\n    rb_define_method(cGzipReader, \"gets\", rb_gzreader_gets, -1);\n    rb_define_method(cGzipReader, \"readline\", rb_gzreader_readline, -1);\n    rb_define_method(cGzipReader, \"each\", rb_gzreader_each, -1);\n    rb_define_method(cGzipReader, \"each_line\", rb_gzreader_each, -1);\n    rb_define_method(cGzipReader, \"readlines\", rb_gzreader_readlines, -1);\n\n    rb_define_const(mZlib, \"OS_CODE\", INT2FIX(OS_CODE));\n    rb_define_const(mZlib, \"OS_MSDOS\", INT2FIX(OS_MSDOS));\n    rb_define_const(mZlib, \"OS_AMIGA\", INT2FIX(OS_AMIGA));\n    rb_define_const(mZlib, \"OS_VMS\", INT2FIX(OS_VMS));\n    rb_define_const(mZlib, \"OS_UNIX\", INT2FIX(OS_UNIX));\n    rb_define_const(mZlib, \"OS_ATARI\", INT2FIX(OS_ATARI));\n    rb_define_const(mZlib, \"OS_OS2\", INT2FIX(OS_OS2));\n    rb_define_const(mZlib, \"OS_MACOS\", INT2FIX(OS_MACOS));\n    rb_define_const(mZlib, \"OS_TOPS20\", INT2FIX(OS_TOPS20));\n    rb_define_const(mZlib, \"OS_WIN32\", INT2FIX(OS_WIN32));\n\n    rb_define_const(mZlib, \"OS_VMCMS\", INT2FIX(OS_VMCMS));\n    rb_define_const(mZlib, \"OS_ZSYSTEM\", INT2FIX(OS_ZSYSTEM));\n    rb_define_const(mZlib, \"OS_CPM\", INT2FIX(OS_CPM));\n    rb_define_const(mZlib, \"OS_QDOS\", INT2FIX(OS_QDOS));\n    rb_define_const(mZlib, \"OS_RISCOS\", INT2FIX(OS_RISCOS));\n    rb_define_const(mZlib, \"OS_UNKNOWN\", INT2FIX(OS_UNKNOWN));\n\n#endif /* GZIP_SUPPORT */\n}\n\n/* Document error classes. */\n\n/*\n * Document-class: Zlib::Error\n *\n * The superclass for all exceptions raised by Ruby/zlib.\n *\n * The following exceptions are defined as subclasses of Zlib::Error. These\n * exceptions are raised when zlib library functions return with an error\n * status.\n *\n * - Zlib::StreamEnd\n * - Zlib::NeedDict\n * - Zlib::DataError\n * - Zlib::StreamError\n * - Zlib::MemError\n * - Zlib::BufError\n * - Zlib::VersionError\n *\n */\n\n/*\n * Document-class: Zlib::GzipFile::Error\n *\n * Base class of errors that occur when processing GZIP files.\n */\n\n/*\n * Document-class: Zlib::GzipFile::NoFooter\n *\n * Raised when gzip file footer is not found. \n */\n\n/*\n * Document-class: Zlib::GzipFile::CRCError\n *\n * Raised when the CRC checksum recorded in gzip file footer is not equivalent\n * to the CRC checksum of the actual uncompressed data. \n */\n\n/*\n * Document-class: Zlib::GzipFile::LengthError\n *\n * Raised when the data length recorded in the gzip file footer is not equivalent\n * to the length of the actual uncompressed data. \n */\n\n\n"
  },
  {
    "path": "file.c",
    "content": "/**********************************************************************\n\n  file.c -\n\n  $Author$\n  $Date$\n  created at: Mon Nov 15 12:24:34 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#ifdef _WIN32\n#include \"missing/file.h\"\n#endif\n#ifdef __CYGWIN__\n#include <windows.h>\n#include <sys/cygwin.h>\n#endif\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"rubysig.h\"\n#include \"util.h\"\n#include \"dln.h\"\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#ifdef HAVE_SYS_FILE_H\n# include <sys/file.h>\n#else\nint flock _((int, int));\n#endif\n\n#ifdef HAVE_SYS_PARAM_H\n# include <sys/param.h>\n#endif\n#ifndef MAXPATHLEN\n# define MAXPATHLEN 1024\n#endif\n\n#include <time.h>\n\nVALUE rb_time_new _((time_t, time_t));\n\n#ifdef HAVE_UTIME_H\n#include <utime.h>\n#elif defined HAVE_SYS_UTIME_H\n#include <sys/utime.h>\n#endif\n\n#ifdef HAVE_PWD_H\n#include <pwd.h>\n#endif\n\n#ifndef HAVE_STRING_H\nchar *strrchr _((const char*,const char));\n#endif\n\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#ifdef HAVE_SYS_MKDEV_H\n#include <sys/mkdev.h>\n#endif\n\n#if defined(HAVE_FCNTL_H)\n#include <fcntl.h>\n#endif\n\n#if !defined HAVE_LSTAT && !defined lstat\n#define lstat stat\n#endif\n#if !HAVE_FSEEKO && !defined(fseeko)\n# define fseeko  fseek\n#endif\n\n#ifdef __BEOS__ /* should not change ID if -1 */\nstatic int\nbe_chown(const char *path, uid_t owner, gid_t group)\n{\n    if (owner == -1 || group == -1) {\n\tstruct stat st;\n\tif (stat(path, &st) < 0) return -1;\n\tif (owner == -1) owner = st.st_uid;\n\tif (group == -1) group = st.st_gid;\n    }\n    return chown(path, owner, group);\n}\n#define chown be_chown\nstatic int\nbe_fchown(int fd, uid_t owner, gid_t group)\n{\n    if (owner == -1 || group == -1) {\n\tstruct stat st;\n\tif (fstat(fd, &st) < 0) return -1;\n\tif (owner == -1) owner = st.st_uid;\n\tif (group == -1) group = st.st_gid;\n    }\n    return fchown(fd, owner, group);\n}\n#define fchown be_fchown\n#endif /* __BEOS__ */\n\nVALUE rb_cFile;\nVALUE rb_mFileTest;\nVALUE rb_cStat;\n\nstatic long apply2files _((void (*)(const char *, void *), VALUE, void *));\nstatic long\napply2files(func, vargs, arg)\n    void (*func)_((const char *, void *));\n    VALUE vargs;\n    void *arg;\n{\n    long i;\n    VALUE path;\n    struct RArray *args = RARRAY(vargs);\n\n    for (i=0; i<args->len; i++) {\n\tpath = args->ptr[i];\n\tSafeStringValue(path);\n\t(*func)(StringValueCStr(path), arg);\n    }\n\n    return args->len;\n}\n\n/*\n *  call-seq:\n *     file.path -> filename\n *  \n *  Returns the pathname used to create <i>file</i> as a string. Does\n *  not normalize the name.\n *     \n *     File.new(\"testfile\").path               #=> \"testfile\"\n *     File.new(\"/tmp/../tmp/xxx\", \"w\").path   #=> \"/tmp/../tmp/xxx\"\n *     \n */\n\nstatic VALUE\nrb_file_path(obj)\n    VALUE obj;\n{\n    rb_io_t *fptr;\n\n    fptr = RFILE(rb_io_taint_check(obj))->fptr;\n    rb_io_check_initialized(fptr);\n    if (!fptr->path) return Qnil;\n    return rb_tainted_str_new2(fptr->path);\n}\n\nstatic VALUE\nstat_new_0(klass, st)\n    VALUE klass;\n    struct stat *st;\n{\n    struct stat *nst = 0;\n\n    if (st) {\n\tnst = ALLOC(struct stat);\n\t*nst = *st;\n    }\n    return Data_Wrap_Struct(klass, NULL, free, nst);\n}\n\nstatic VALUE\nstat_new(st)\n    struct stat *st;\n{\n    return stat_new_0(rb_cStat, st);\n}\n\nstatic struct stat*\nget_stat(self)\n    VALUE self;\n{\n    struct stat* st;\n    Data_Get_Struct(self, struct stat, st);\n    if (!st) rb_raise(rb_eTypeError, \"uninitialized File::Stat\");\n    return st;\n}\n\n/*\n *  call-seq:\n *     stat <=> other_stat    => -1, 0, 1\n *  \n *  Compares <code>File::Stat</code> objects by comparing their\n *  respective modification times.\n *     \n *     f1 = File.new(\"f1\", \"w\")\n *     sleep 1\n *     f2 = File.new(\"f2\", \"w\")\n *     f1.stat <=> f2.stat   #=> -1\n */\n\nstatic VALUE\nrb_stat_cmp(self, other)\n    VALUE self, other;\n{\n    if (rb_obj_is_kind_of(other, rb_obj_class(self))) {\n\ttime_t t1 = get_stat(self)->st_mtime;\n\ttime_t t2 = get_stat(other)->st_mtime;\n\tif (t1 == t2)\n\t    return INT2FIX(0);\n\telse if (t1 < t2)\n\t    return INT2FIX(-1);\n\telse\n\t    return INT2FIX(1);\n    }\n    return Qnil;\n}\n\nstatic VALUE rb_stat_dev _((VALUE));\nstatic VALUE rb_stat_ino _((VALUE));\nstatic VALUE rb_stat_mode _((VALUE));\nstatic VALUE rb_stat_nlink _((VALUE));\nstatic VALUE rb_stat_uid _((VALUE));\nstatic VALUE rb_stat_gid _((VALUE));\nstatic VALUE rb_stat_rdev _((VALUE));\nstatic VALUE rb_stat_size _((VALUE));\nstatic VALUE rb_stat_blksize _((VALUE));\nstatic VALUE rb_stat_blocks _((VALUE));\nstatic VALUE rb_stat_atime _((VALUE));\nstatic VALUE rb_stat_mtime _((VALUE));\nstatic VALUE rb_stat_ctime _((VALUE));\n\n/*\n *  call-seq:\n *     stat.dev    => fixnum\n *  \n *  Returns an integer representing the device on which <i>stat</i>\n *  resides.\n *     \n *     File.stat(\"testfile\").dev   #=> 774\n */\n\nstatic VALUE\nrb_stat_dev(self)\n    VALUE self;\n{\n    return INT2NUM(get_stat(self)->st_dev);\n}\n\n/*\n *  call-seq:\n *     stat.dev_major   => fixnum\n *  \n *  Returns the major part of <code>File_Stat#dev</code> or\n *  <code>nil</code>.\n *     \n *     File.stat(\"/dev/fd1\").dev_major   #=> 2\n *     File.stat(\"/dev/tty\").dev_major   #=> 5\n */\n\nstatic VALUE\nrb_stat_dev_major(self)\n    VALUE self;\n{\n#if defined(major)\n    long dev = get_stat(self)->st_dev;\n    return ULONG2NUM(major(dev));\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.dev_minor   => fixnum\n *  \n *  Returns the minor part of <code>File_Stat#dev</code> or\n *  <code>nil</code>.\n *     \n *     File.stat(\"/dev/fd1\").dev_minor   #=> 1\n *     File.stat(\"/dev/tty\").dev_minor   #=> 0\n */\n\nstatic VALUE\nrb_stat_dev_minor(self)\n    VALUE self;\n{\n#if defined(minor)\n    long dev = get_stat(self)->st_dev;\n    return ULONG2NUM(minor(dev));\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.ino   => fixnum\n *  \n *  Returns the inode number for <i>stat</i>.\n *     \n *     File.stat(\"testfile\").ino   #=> 1083669\n *     \n */\n\nstatic VALUE\nrb_stat_ino(self)\n    VALUE self;\n{\n#ifdef HUGE_ST_INO\n    return ULL2NUM(get_stat(self)->st_ino);\n#else\n    return ULONG2NUM(get_stat(self)->st_ino);\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.mode   => fixnum\n *  \n *  Returns an integer representing the permission bits of\n *  <i>stat</i>. The meaning of the bits is platform dependent; on\n *  Unix systems, see <code>stat(2)</code>.\n *     \n *     File.chmod(0644, \"testfile\")   #=> 1\n *     s = File.stat(\"testfile\")\n *     sprintf(\"%o\", s.mode)          #=> \"100644\"\n */\n\nstatic VALUE\nrb_stat_mode(self)\n    VALUE self;\n{\n#ifdef __BORLANDC__\n    return UINT2NUM((unsigned short)(get_stat(self)->st_mode));\n#else\n    return UINT2NUM(get_stat(self)->st_mode);\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.nlink   => fixnum\n *  \n *  Returns the number of hard links to <i>stat</i>.\n *     \n *     File.stat(\"testfile\").nlink             #=> 1\n *     File.link(\"testfile\", \"testfile.bak\")   #=> 0\n *     File.stat(\"testfile\").nlink             #=> 2\n *     \n */\n\nstatic VALUE\nrb_stat_nlink(self)\n    VALUE self;\n{\n    return UINT2NUM(get_stat(self)->st_nlink);\n}\n\n/*\n *  call-seq:\n *     stat.uid    => fixnum\n *  \n *  Returns the numeric user id of the owner of <i>stat</i>.\n *     \n *     File.stat(\"testfile\").uid   #=> 501\n *     \n */\n\nstatic VALUE\nrb_stat_uid(self)\n    VALUE self;\n{\n    return UINT2NUM(get_stat(self)->st_uid);\n}\n\n/*\n *  call-seq:\n *     stat.gid   => fixnum\n *  \n *  Returns the numeric group id of the owner of <i>stat</i>.\n *     \n *     File.stat(\"testfile\").gid   #=> 500\n *     \n */\n\nstatic VALUE\nrb_stat_gid(self)\n    VALUE self;\n{\n    return UINT2NUM(get_stat(self)->st_gid);\n}\n\n/*\n *  call-seq:\n *     stat.rdev   =>  fixnum or nil\n *  \n *  Returns an integer representing the device type on which\n *  <i>stat</i> resides. Returns <code>nil</code> if the operating\n *  system doesn't support this feature.\n *     \n *     File.stat(\"/dev/fd1\").rdev   #=> 513\n *     File.stat(\"/dev/tty\").rdev   #=> 1280\n */\n\nstatic VALUE\nrb_stat_rdev(self)\n    VALUE self;\n{\n#ifdef HAVE_ST_RDEV\n    return ULONG2NUM(get_stat(self)->st_rdev);\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.rdev_major   => fixnum\n *  \n *  Returns the major part of <code>File_Stat#rdev</code> or\n *  <code>nil</code>.\n *     \n *     File.stat(\"/dev/fd1\").rdev_major   #=> 2\n *     File.stat(\"/dev/tty\").rdev_major   #=> 5\n */\n\nstatic VALUE\nrb_stat_rdev_major(self)\n    VALUE self;\n{\n#if defined(HAVE_ST_RDEV) && defined(major)\n    long rdev = get_stat(self)->st_rdev;\n    return ULONG2NUM(major(rdev));\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.rdev_minor   => fixnum\n *  \n *  Returns the minor part of <code>File_Stat#rdev</code> or\n *  <code>nil</code>.\n *     \n *     File.stat(\"/dev/fd1\").rdev_minor   #=> 1\n *     File.stat(\"/dev/tty\").rdev_minor   #=> 0\n */\n\nstatic VALUE\nrb_stat_rdev_minor(self)\n    VALUE self;\n{\n#if defined(HAVE_ST_RDEV) && defined(minor)\n    long rdev = get_stat(self)->st_rdev;\n    return ULONG2NUM(minor(rdev));\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.size    => fixnum\n *  \n *  Returns the size of <i>stat</i> in bytes.\n *     \n *     File.stat(\"testfile\").size   #=> 66\n */\n\nstatic VALUE\nrb_stat_size(self)\n    VALUE self;\n{\n    return OFFT2NUM(get_stat(self)->st_size);\n}\n\n/*\n *  call-seq:\n *     stat.blksize   => integer or nil\n *  \n *  Returns the native file system's block size. Will return <code>nil</code>\n *  on platforms that don't support this information.\n *     \n *     File.stat(\"testfile\").blksize   #=> 4096\n *     \n */\n\nstatic VALUE\nrb_stat_blksize(self)\n    VALUE self;\n{\n#ifdef HAVE_ST_BLKSIZE\n    return ULONG2NUM(get_stat(self)->st_blksize);\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.blocks    => integer or nil\n *  \n *  Returns the number of native file system blocks allocated for this\n *  file, or <code>nil</code> if the operating system doesn't \n *  support this feature.\n *     \n *     File.stat(\"testfile\").blocks   #=> 2\n */\n\nstatic VALUE\nrb_stat_blocks(self)\n    VALUE self;\n{\n#ifdef HAVE_ST_BLOCKS\n    return ULONG2NUM(get_stat(self)->st_blocks);\n#else\n    return Qnil;\n#endif\n}\n\n/*\n *  call-seq:\n *     stat.atime   => time\n *  \n *  Returns the last access time for this file as an object of class\n *  <code>Time</code>.\n *     \n *     File.stat(\"testfile\").atime   #=> Wed Dec 31 18:00:00 CST 1969\n *     \n */\n\nstatic VALUE\nrb_stat_atime(self)\n    VALUE self;\n{\n    return rb_time_new(get_stat(self)->st_atime, 0);\n}\n\n/*\n *  call-seq:\n *     stat.mtime -> aTime\n *  \n *  Returns the modification time of <i>stat</i>.\n *     \n *     File.stat(\"testfile\").mtime   #=> Wed Apr 09 08:53:14 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_stat_mtime(self)\n    VALUE self;\n{\n    return rb_time_new(get_stat(self)->st_mtime, 0);\n}\n\n/*\n *  call-seq:\n *     stat.ctime -> aTime\n *  \n *  Returns the change time for <i>stat</i> (that is, the time\n *  directory information about the file was changed, not the file\n *  itself).\n *     \n *     File.stat(\"testfile\").ctime   #=> Wed Apr 09 08:53:14 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_stat_ctime(self)\n    VALUE self;\n{\n    return rb_time_new(get_stat(self)->st_ctime, 0);\n}\n\n/*\n * call-seq:\n *   stat.inspect  =>  string\n *\n * Produce a nicely formatted description of <i>stat</i>.\n *\n *   File.stat(\"/etc/passwd\").inspect\n *      #=> \"#<File::Stat dev=0xe000005, ino=1078078, mode=0100644, \n *           nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096, \n *           blocks=8, atime=Wed Dec 10 10:16:12 CST 2003, \n *           mtime=Fri Sep 12 15:41:41 CDT 2003, \n *           ctime=Mon Oct 27 11:20:27 CST 2003>\"\n */\n\nstatic VALUE\nrb_stat_inspect(self)\n    VALUE self;\n{\n    VALUE str;\n    int i;\n    static const struct {\n\tconst char *name;\n\tVALUE (*func)_((VALUE));\n    } member[] = {\n\t{\"dev\",\t    rb_stat_dev},\n\t{\"ino\",\t    rb_stat_ino},\n\t{\"mode\",    rb_stat_mode},\n\t{\"nlink\",   rb_stat_nlink},\n\t{\"uid\",\t    rb_stat_uid},\n\t{\"gid\",\t    rb_stat_gid},\n\t{\"rdev\",    rb_stat_rdev},\n\t{\"size\",    rb_stat_size},\n\t{\"blksize\", rb_stat_blksize},\n\t{\"blocks\",  rb_stat_blocks},\n\t{\"atime\",   rb_stat_atime},\n\t{\"mtime\",   rb_stat_mtime},\n\t{\"ctime\",   rb_stat_ctime},\n    };\n\n    str = rb_str_buf_new2(\"#<\");\n    rb_str_buf_cat2(str, rb_obj_classname(self));\n    rb_str_buf_cat2(str, \" \");\n\n    for (i = 0; i < sizeof(member)/sizeof(member[0]); i++) {\n\tVALUE v;\n\n\tif (i > 0) {\n\t    rb_str_buf_cat2(str, \", \");\n\t}\n\trb_str_buf_cat2(str, member[i].name);\n\trb_str_buf_cat2(str, \"=\");\n\tv = (*member[i].func)(self);\n\tif (i == 2) {\t\t/* mode */\n\t    char buf[32];\n\n\t    sprintf(buf, \"0%lo\", NUM2ULONG(v));\n\t    rb_str_buf_cat2(str, buf);\n\t}\n\telse if (i == 0 || i == 6) { /* dev/rdev */\n\t    char buf[32];\n\n\t    sprintf(buf, \"0x%lx\", NUM2ULONG(v));\n\t    rb_str_buf_cat2(str, buf);\n\t}\n\telse {\n\t    rb_str_append(str, rb_inspect(v));\n\t}\n    }\n    rb_str_buf_cat2(str, \">\");\n    OBJ_INFECT(str, self);\n\n    return str;\n}\n\nstatic int\nrb_stat(file, st)\n    VALUE file;\n    struct stat *st;\n{\n    VALUE tmp;\n\n    tmp = rb_check_convert_type(file, T_FILE, \"IO\", \"to_io\");\n    if (!NIL_P(tmp)) {\n\trb_io_t *fptr;\n\n\trb_secure(2);\n\tGetOpenFile(tmp, fptr);\n\treturn fstat(fileno(fptr->f), st);\n    }\n    SafeStringValue(file);\n    return stat(StringValueCStr(file), st);\n}\n\n#ifdef _WIN32\nstatic HANDLE\nw32_io_info(file, st)\n    VALUE *file;\n    BY_HANDLE_FILE_INFORMATION *st;\n{\n    VALUE tmp;\n    HANDLE f, ret = 0;\n\n    tmp = rb_check_convert_type(*file, T_FILE, \"IO\", \"to_io\");\n    if (!NIL_P(tmp)) {\n\trb_io_t *fptr;\n\n\tGetOpenFile(tmp, fptr);\n\tf = (HANDLE)rb_w32_get_osfhandle(fileno(fptr->f));\n\tif (f == (HANDLE)-1) return INVALID_HANDLE_VALUE;\n    }\n    else {\n\tSafeStringValue(*file);\n\tf = CreateFile(StringValueCStr(*file), 0,\n\t               FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,\n\t               rb_w32_iswin95() ? 0 : FILE_FLAG_BACKUP_SEMANTICS, NULL);\n\tif (f == INVALID_HANDLE_VALUE) return f;\n\tret = f;\n    }\n    if (GetFileType(f) == FILE_TYPE_DISK) {\n\tZeroMemory(st, sizeof(*st));\n\tif (GetFileInformationByHandle(f, st)) return ret;\n    }\n    if (ret) CloseHandle(ret);\n    return INVALID_HANDLE_VALUE;\n}\n#endif\n\n/*\n *  call-seq:\n *     File.stat(file_name)   =>  stat\n *  \n *  Returns a <code>File::Stat</code> object for the named file (see\n *  <code>File::Stat</code>).\n *     \n *     File.stat(\"testfile\").mtime   #=> Tue Apr 08 12:58:04 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_file_s_stat(klass, fname)\n    VALUE klass, fname;\n{\n    struct stat st;\n\n    SafeStringValue(fname);\n    if (rb_stat(fname, &st) < 0) {\n\trb_sys_fail(StringValueCStr(fname));\n    }\n    return stat_new(&st);\n}\n\n/*\n *  call-seq:\n *     ios.stat    => stat\n *  \n *  Returns status information for <em>ios</em> as an object of type\n *  <code>File::Stat</code>.\n *     \n *     f = File.new(\"testfile\")\n *     s = f.stat\n *     \"%o\" % s.mode   #=> \"100644\"\n *     s.blksize       #=> 4096\n *     s.atime         #=> Wed Apr 09 08:53:54 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_io_stat(obj)\n    VALUE obj;\n{\n    rb_io_t *fptr;\n    struct stat st;\n\n    GetOpenFile(obj, fptr);\n    if (fstat(fileno(fptr->f), &st) == -1) {\n\trb_sys_fail(fptr->path);\n    }\n    return stat_new(&st);\n}\n\n/*\n *  call-seq:\n *     File.lstat(file_name)   => stat\n *  \n *  Same as <code>File::stat</code>, but does not follow the last symbolic\n *  link. Instead, reports on the link itself.\n *     \n *     File.symlink(\"testfile\", \"link2test\")   #=> 0\n *     File.stat(\"testfile\").size              #=> 66\n *     File.lstat(\"link2test\").size            #=> 8\n *     File.stat(\"link2test\").size             #=> 66\n *     \n */\n\nstatic VALUE\nrb_file_s_lstat(klass, fname)\n    VALUE klass, fname;\n{\n#ifdef HAVE_LSTAT\n    struct stat st;\n\n    SafeStringValue(fname);\n    if (lstat(StringValueCStr(fname), &st) == -1) {\n\trb_sys_fail(RSTRING(fname)->ptr);\n    }\n    return stat_new(&st);\n#else\n    return rb_file_s_stat(klass, fname);\n#endif\n}\n\n/*\n *  call-seq:\n *     file.lstat   =>  stat\n *  \n *  Same as <code>IO#stat</code>, but does not follow the last symbolic\n *  link. Instead, reports on the link itself.\n *     \n *     File.symlink(\"testfile\", \"link2test\")   #=> 0\n *     File.stat(\"testfile\").size              #=> 66\n *     f = File.new(\"link2test\")\n *     f.lstat.size                            #=> 8\n *     f.stat.size                             #=> 66\n */\n\nstatic VALUE\nrb_file_lstat(obj)\n    VALUE obj;\n{\n#ifdef HAVE_LSTAT\n    rb_io_t *fptr;\n    struct stat st;\n\n    rb_secure(2);\n    GetOpenFile(obj, fptr);\n    if (!fptr->path) return Qnil;\n    if (lstat(fptr->path, &st) == -1) {\n\trb_sys_fail(fptr->path);\n    }\n    return stat_new(&st);\n#else\n    return rb_io_stat(obj);\n#endif\n}\n\n#ifndef HAVE_GROUP_MEMBER\nstatic int\ngroup_member(gid)\n    GETGROUPS_T gid;\n{\n#ifndef _WIN32\n    if (getgid() == gid || getegid() == gid)\n\treturn Qtrue;\n\n# ifdef HAVE_GETGROUPS\n#  ifndef NGROUPS\n#   ifdef NGROUPS_MAX\n#    define NGROUPS NGROUPS_MAX\n#   else\n#    define NGROUPS 32\n#   endif\n#  endif\n    {\n\tGETGROUPS_T gary[NGROUPS];\n\tint anum;\n\n\tanum = getgroups(NGROUPS, gary);\n\twhile (--anum >= 0)\n\t    if (gary[anum] == gid)\n\t\treturn Qtrue;\n    }\n# endif\n#endif\n    return Qfalse;\n}\n#endif\n\n#ifndef S_IXUGO\n#  define S_IXUGO\t\t(S_IXUSR | S_IXGRP | S_IXOTH)\n#endif\n\n#if defined(S_IXGRP) && !defined(_WIN32) && !defined(__CYGWIN__)\n#define USE_GETEUID 1\n#endif\n\n#ifndef HAVE_EACCESS\nint\neaccess(path, mode)\n     const char *path;\n     int mode;\n{\n#ifdef USE_GETEUID\n    struct stat st;\n    int euid;\n\n    if (stat(path, &st) < 0) return -1;\n\n    euid = geteuid();\n\n    if (euid == 0) {\n\t/* Root can read or write any file. */\n\tif (!(mode & X_OK))\n\t    return 0;\n\n\t/* Root can execute any file that has any one of the execute\n\t   bits set. */\n\tif (st.st_mode & S_IXUGO)\n\t    return 0;\n\n\treturn -1;\n    }\n\n    if (st.st_uid == euid)        /* owner */\n\tmode <<= 6;\n    else if (group_member(st.st_gid))\n\tmode <<= 3;\n\n    if ((st.st_mode & mode) == mode) return 0;\n\n    return -1;\n#else\n# if defined(_MSC_VER) || defined(__MINGW32__)\n    mode &= ~1;\n# endif\n    return access(path, mode);\n#endif\n}\n#endif\n\n\n/*\n * Document-class: FileTest\n *\n *  <code>FileTest</code> implements file test operations similar to\n *  those used in <code>File::Stat</code>. It exists as a standalone\n *  module, and its methods are also insinuated into the <code>File</code>\n *  class. (Note that this is not done by inclusion: the interpreter cheats).\n *     \n */\n\n/*\n * call-seq:\n *   File.directory?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file is a directory,\n * <code>false</code> otherwise.\n *\n *    File.directory?(\".\")\n */\n\nstatic VALUE\ntest_d(obj, fname)\n    VALUE obj, fname;\n{\n#ifndef S_ISDIR\n#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)\n#endif\n\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (S_ISDIR(st.st_mode)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   File.pipe?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file is a pipe.\n */\n\nstatic VALUE\ntest_p(obj, fname)\n    VALUE obj, fname;\n{\n#ifdef S_IFIFO\n#  ifndef S_ISFIFO\n#    define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO)\n#  endif\n\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (S_ISFIFO(st.st_mode)) return Qtrue;\n\n#endif\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   File.symlink?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file is a symbolic link.\n */\n\nstatic VALUE\ntest_l(obj, fname)\n    VALUE obj, fname;\n{\n#ifndef S_ISLNK\n#  ifdef _S_ISLNK\n#    define S_ISLNK(m) _S_ISLNK(m)\n#  elif defined __BORLANDC__\n#    ifdef _S_IFLNK\n#      define S_ISLNK(m) (((unsigned short)(m) & S_IFMT) == _S_IFLNK)\n#    else\n#      ifdef S_IFLNK\n#        define S_ISLNK(m) (((unsigned short)(m) & S_IFMT) == S_IFLNK)\n#      endif\n#    endif\n#  else\n#    ifdef _S_IFLNK\n#      define S_ISLNK(m) ((m & S_IFMT) == _S_IFLNK)\n#    else\n#      ifdef S_IFLNK\n#\t define S_ISLNK(m) ((m & S_IFMT) == S_IFLNK)\n#      endif\n#    endif\n#  endif\n#endif\n\n#ifdef S_ISLNK\n    struct stat st;\n\n    SafeStringValue(fname);\n    if (lstat(StringValueCStr(fname), &st) < 0) return Qfalse;\n    if (S_ISLNK(st.st_mode)) return Qtrue;\n#endif\n\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   File.socket?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file is a socket.\n */\n\nstatic VALUE\ntest_S(obj, fname)\n    VALUE obj, fname;\n{\n#ifndef S_ISSOCK\n#  ifdef _S_ISSOCK\n#    define S_ISSOCK(m) _S_ISSOCK(m)\n#  elif defined __BORLANDC__\n#    ifdef _S_IFSOCK\n#      define S_ISSOCK(m) (((unsigned short)(m) & S_IFMT) == _S_IFSOCK)\n#    else\n#      ifdef S_IFSOCK\n#        define S_ISSOCK(m) (((unsigned short)(m) & S_IFMT) == S_IFSOCK)\n#      endif\n#    endif\n#  else\n#    ifdef _S_IFSOCK\n#      define S_ISSOCK(m) ((m & S_IFMT) == _S_IFSOCK)\n#    else\n#      ifdef S_IFSOCK\n#\t define S_ISSOCK(m) ((m & S_IFMT) == S_IFSOCK)\n#      endif\n#    endif\n#  endif\n#endif\n\n#ifdef S_ISSOCK\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (S_ISSOCK(st.st_mode)) return Qtrue;\n\n#endif\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   File.blockdev?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file is a block device.\n */\n\nstatic VALUE\ntest_b(obj, fname)\n    VALUE obj, fname;\n{\n#ifndef S_ISBLK\n#   ifdef S_IFBLK\n#\tdefine S_ISBLK(m) ((m & S_IFMT) == S_IFBLK)\n#   else\n#\tdefine S_ISBLK(m) (0)  /* anytime false */\n#   endif\n#endif\n\n#ifdef S_ISBLK\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (S_ISBLK(st.st_mode)) return Qtrue;\n\n#endif\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   File.chardev?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file is a character device.\n */\nstatic VALUE\ntest_c(obj, fname)\n    VALUE obj, fname;\n{\n#ifndef S_ISCHR\n#   define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR)\n#endif\n\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (S_ISCHR(st.st_mode)) return Qtrue;\n\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *    File.exist?(file_name)    =>  true or false\n *    File.exists?(file_name)   =>  true or false    (obsolete)\n *\n * Return <code>true</code> if the named file exists.\n */\n\nstatic VALUE\ntest_e(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.readable?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file is readable by the effective\n * user id of this process.\n */\n\nstatic VALUE\ntest_r(obj, fname)\n    VALUE obj, fname;\n{\n    SafeStringValue(fname);\n    if (eaccess(StringValueCStr(fname), R_OK) < 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.readable_real?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file is readable by the real\n * user id of this process.\n */\n\nstatic VALUE\ntest_R(obj, fname)\n    VALUE obj, fname;\n{\n    SafeStringValue(fname);\n    if (access(StringValueCStr(fname), R_OK) < 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.writable?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file is writable by the effective\n * user id of this process.\n */\n\nstatic VALUE\ntest_w(obj, fname)\n    VALUE obj, fname;\n{\n    SafeStringValue(fname);\n    if (eaccess(StringValueCStr(fname), W_OK) < 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.writable_real?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file is writable by the real\n * user id of this process.\n */\n\nstatic VALUE\ntest_W(obj, fname)\n    VALUE obj, fname;\n{\n    SafeStringValue(fname);\n    if (access(StringValueCStr(fname), W_OK) < 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.executable?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file is executable by the effective\n * user id of this process.\n */\n\nstatic VALUE\ntest_x(obj, fname)\n    VALUE obj, fname;\n{\n    SafeStringValue(fname);\n    if (eaccess(StringValueCStr(fname), X_OK) < 0) return Qfalse;\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.executable_real?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file is executable by the real\n * user id of this process.\n */\n\nstatic VALUE\ntest_X(obj, fname)\n    VALUE obj, fname;\n{\n    SafeStringValue(fname);\n    if (access(StringValueCStr(fname), X_OK) < 0) return Qfalse;\n    return Qtrue;\n}\n\n#ifndef S_ISREG\n#   define S_ISREG(m) ((m & S_IFMT) == S_IFREG)\n#endif\n\n/*\n * call-seq:\n *    File.file?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file exists and is a\n * regular file.\n */\n\nstatic VALUE\ntest_f(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (S_ISREG(st.st_mode)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *    File.zero?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file exists and has\n * a zero size.\n */\n\nstatic VALUE\ntest_z(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (st.st_size == 0) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *    File.size?(file_name)   => Integer or nil\n *\n * Returns +nil+ if +file_name+ doesn't exist or has zero size, the size of the\n * file otherwise.\n */\n\nstatic VALUE\ntest_s(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qnil;\n    if (st.st_size == 0) return Qnil;\n    return OFFT2NUM(st.st_size);\n}\n\n/*\n * call-seq:\n *    File.owned?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file exists and the\n * effective used id of the calling process is the owner of\n * the file.\n */\n\nstatic VALUE\ntest_owned(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (st.st_uid == geteuid()) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\ntest_rowned(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (st.st_uid == getuid()) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *    File.grpowned?(file_name)   => true or false\n *\n * Returns <code>true</code> if the named file exists and the\n * effective group id of the calling process is the owner of\n * the file. Returns <code>false</code> on Windows.\n */\n\nstatic VALUE\ntest_grpowned(obj, fname)\n    VALUE obj, fname;\n{\n#ifndef _WIN32\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0) return Qfalse;\n    if (group_member(st.st_gid)) return Qtrue;\n#endif\n    return Qfalse;\n}\n\n#if defined(S_ISUID) || defined(S_ISGID) || defined(S_ISVTX)\nstatic VALUE\ncheck3rdbyte(fname, mode)\n    VALUE fname;\n    int mode;\n{\n    struct stat st;\n\n    SafeStringValue(fname);\n    if (stat(StringValueCStr(fname), &st) < 0) return Qfalse;\n    if (st.st_mode & mode) return Qtrue;\n    return Qfalse;\n}\n#endif\n\n/*\n * call-seq:\n *   File.setuid?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file has the setuid bit set.\n */\n\nstatic VALUE\ntest_suid(obj, fname)\n    VALUE obj, fname;\n{\n#ifdef S_ISUID\n    return check3rdbyte(fname, S_ISUID);\n#else\n    return Qfalse;\n#endif\n}\n\n/*\n * call-seq:\n *   File.setgid?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file has the setgid bit set.\n */\n\nstatic VALUE\ntest_sgid(obj, fname)\n    VALUE obj, fname;\n{\n#ifdef S_ISGID\n    return check3rdbyte(fname, S_ISGID);\n#else\n    return Qfalse;\n#endif\n}\n\n/*\n * call-seq:\n *   File.sticky?(file_name)   =>  true or false\n *\n * Returns <code>true</code> if the named file has the sticky bit set.\n */\n\nstatic VALUE\ntest_sticky(obj, fname)\n    VALUE obj, fname;\n{\n#ifdef S_ISVTX\n    return check3rdbyte(fname, S_ISVTX);\n#else\n    return Qnil;\n#endif\n}\n\n/*\n * call-seq:\n *   File.identical?(file_1, file_2)   =>  true or false\n *\n * Returns <code>true</code> if the named files are identical.\n *\n *     open(\"a\", \"w\") {}\n *     p File.identical?(\"a\", \"a\")      #=> true\n *     p File.identical?(\"a\", \"./a\")    #=> true\n *     File.link(\"a\", \"b\")\n *     p File.identical?(\"a\", \"b\")      #=> true\n *     File.symlink(\"a\", \"c\")\n *     p File.identical?(\"a\", \"c\")      #=> true\n *     open(\"d\", \"w\") {}\n *     p File.identical?(\"a\", \"d\")      #=> false\n */\n\nstatic VALUE\ntest_identical(obj, fname1, fname2)\n    VALUE obj, fname1, fname2;\n{\n#ifndef DOSISH\n    struct stat st1, st2;\n\n    if (rb_stat(fname1, &st1) < 0) return Qfalse;\n    if (rb_stat(fname2, &st2) < 0) return Qfalse;\n    if (st1.st_dev != st2.st_dev) return Qfalse;\n    if (st1.st_ino != st2.st_ino) return Qfalse;\n#else\n#ifdef _WIN32\n    BY_HANDLE_FILE_INFORMATION st1, st2;\n    HANDLE f1 = 0, f2 = 0;\n#endif\n\n    rb_secure(2);\n#ifdef _WIN32\n    f1 = w32_io_info(&fname1, &st1);\n    if (f1 == INVALID_HANDLE_VALUE) return Qfalse;\n    f2 = w32_io_info(&fname2, &st2);\n    if (f1) CloseHandle(f1);\n    if (f2 == INVALID_HANDLE_VALUE) return Qfalse;\n    if (f2) CloseHandle(f2);\n\n    if (st1.dwVolumeSerialNumber == st2.dwVolumeSerialNumber &&\n\tst1.nFileIndexHigh == st2.nFileIndexHigh &&\n\tst1.nFileIndexLow == st2.nFileIndexLow)\n\treturn Qtrue;\n    if (!f1 || !f2) return Qfalse;\n    if (rb_w32_iswin95()) return Qfalse;\n#else\n    SafeStringValue(fname1);\n    fname1 = rb_str_new4(fname1);\n    SafeStringValue(fname2);\n    if (access(RSTRING(fname1)->ptr, 0)) return Qfalse;\n    if (access(RSTRING(fname2)->ptr, 0)) return Qfalse;\n#endif\n    fname1 = rb_file_expand_path(fname1, Qnil);\n    fname2 = rb_file_expand_path(fname2, Qnil);\n    if (RSTRING(fname1)->len != RSTRING(fname2)->len) return Qfalse;\n    if (rb_memcicmp(RSTRING(fname1)->ptr, RSTRING(fname2)->ptr, RSTRING(fname1)->len))\n\treturn Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *    File.size(file_name)   => integer\n *\n * Returns the size of <code>file_name</code>.\n */\n\nstatic VALUE\nrb_file_s_size(klass, fname)\n    VALUE klass, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0)\n\trb_sys_fail(StringValueCStr(fname));\n    return OFFT2NUM(st.st_size);\n}\n\nstatic VALUE\nrb_file_ftype(st)\n    struct stat *st;\n{\n    const char *t;\n\n    if (S_ISREG(st->st_mode)) {\n\tt = \"file\";\n    }\n    else if (S_ISDIR(st->st_mode)) {\n\tt = \"directory\";\n    }\n    else if (S_ISCHR(st->st_mode)) {\n\tt = \"characterSpecial\";\n    }\n#ifdef S_ISBLK\n    else if (S_ISBLK(st->st_mode)) {\n\tt = \"blockSpecial\";\n    }\n#endif\n#ifdef S_ISFIFO\n    else if (S_ISFIFO(st->st_mode)) {\n\tt = \"fifo\";\n    }\n#endif\n#ifdef S_ISLNK\n    else if (S_ISLNK(st->st_mode)) {\n\tt = \"link\";\n    }\n#endif\n#ifdef S_ISSOCK\n    else if (S_ISSOCK(st->st_mode)) {\n\tt = \"socket\";\n    }\n#endif\n    else {\n\tt = \"unknown\";\n    }\n\n    return rb_str_new2(t);\n}\n\n/*\n *  call-seq:\n *     File.ftype(file_name)   => string\n *  \n *  Identifies the type of the named file; the return string is one of\n *  ``<code>file</code>'', ``<code>directory</code>'',\n *  ``<code>characterSpecial</code>'', ``<code>blockSpecial</code>'',\n *  ``<code>fifo</code>'', ``<code>link</code>'',\n *  ``<code>socket</code>'', or ``<code>unknown</code>''.\n *     \n *     File.ftype(\"testfile\")            #=> \"file\"\n *     File.ftype(\"/dev/tty\")            #=> \"characterSpecial\"\n *     File.ftype(\"/tmp/.X11-unix/X0\")   #=> \"socket\"\n */\n\nstatic VALUE\nrb_file_s_ftype(klass, fname)\n    VALUE klass, fname;\n{\n    struct stat st;\n\n    SafeStringValue(fname);\n    if (lstat(StringValueCStr(fname), &st) == -1) {\n\trb_sys_fail(RSTRING(fname)->ptr);\n    }\n\n    return rb_file_ftype(&st);\n}\n\n/*\n *  call-seq:\n *     File.atime(file_name)  =>  time\n *  \n *  Returns the last access time for the named file as a Time object).\n *     \n *     File.atime(\"testfile\")   #=> Wed Apr 09 08:51:48 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_file_s_atime(klass, fname)\n    VALUE klass, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0)\n\trb_sys_fail(StringValueCStr(fname));\n    return rb_time_new(st.st_atime, 0);\n}\n\n/*\n *  call-seq:\n *     file.atime    => time\n *  \n *  Returns the last access time (a <code>Time</code> object)\n *   for <i>file</i>, or epoch if <i>file</i> has not been accessed.\n *     \n *     File.new(\"testfile\").atime   #=> Wed Dec 31 18:00:00 CST 1969\n *     \n */\n\nstatic VALUE\nrb_file_atime(obj)\n    VALUE obj;\n{\n    rb_io_t *fptr;\n    struct stat st;\n\n    GetOpenFile(obj, fptr);\n    if (fstat(fileno(fptr->f), &st) == -1) {\n\trb_sys_fail(fptr->path);\n    }\n    return rb_time_new(st.st_atime, 0);\n}\n\n/*\n *  call-seq:\n *     File.mtime(file_name)  =>  time\n *  \n *  Returns the modification time for the named file as a Time object.\n *     \n *     File.mtime(\"testfile\")   #=> Tue Apr 08 12:58:04 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_file_s_mtime(klass, fname)\n    VALUE klass, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0)\n\trb_sys_fail(RSTRING(fname)->ptr);\n    return rb_time_new(st.st_mtime, 0);\n}\n\n/*\n *  call-seq:\n *     file.mtime -> time\n *  \n *  Returns the modification time for <i>file</i>.\n *     \n *     File.new(\"testfile\").mtime   #=> Wed Apr 09 08:53:14 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_file_mtime(obj)\n    VALUE obj;\n{\n    rb_io_t *fptr;\n    struct stat st;\n\n    GetOpenFile(obj, fptr);\n    if (fstat(fileno(fptr->f), &st) == -1) {\n\trb_sys_fail(fptr->path);\n    }\n    return rb_time_new(st.st_mtime, 0);\n}\n\n/*\n *  call-seq:\n *     File.ctime(file_name)  => time\n *  \n *  Returns the change time for the named file (the time at which\n *  directory information about the file was changed, not the file\n *  itself).\n *     \n *     File.ctime(\"testfile\")   #=> Wed Apr 09 08:53:13 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_file_s_ctime(klass, fname)\n    VALUE klass, fname;\n{\n    struct stat st;\n\n    if (rb_stat(fname, &st) < 0)\n\trb_sys_fail(RSTRING(fname)->ptr);\n    return rb_time_new(st.st_ctime, 0);\n}\n\n/*\n *  call-seq:\n *     file.ctime -> time\n *  \n *  Returns the change time for <i>file</i> (that is, the time directory\n *  information about the file was changed, not the file itself).\n *     \n *     File.new(\"testfile\").ctime   #=> Wed Apr 09 08:53:14 CDT 2003\n *     \n */\n\nstatic VALUE\nrb_file_ctime(obj)\n    VALUE obj;\n{\n    rb_io_t *fptr;\n    struct stat st;\n\n    GetOpenFile(obj, fptr);\n    if (fstat(fileno(fptr->f), &st) == -1) {\n\trb_sys_fail(fptr->path);\n    }\n    return rb_time_new(st.st_ctime, 0);\n}\n\nstatic void chmod_internal _((const char *, void *));\nstatic void\nchmod_internal(path, mode)\n    const char *path;\n    void *mode;\n{\n    if (chmod(path, *(int *)mode) < 0)\n\trb_sys_fail(path);\n}\n\n/*\n *  call-seq:\n *     File.chmod(mode_int, file_name, ... ) -> integer\n *  \n *  Changes permission bits on the named file(s) to the bit pattern\n *  represented by <i>mode_int</i>. Actual effects are operating system\n *  dependent (see the beginning of this section). On Unix systems, see\n *  <code>chmod(2)</code> for details. Returns the number of files\n *  processed.\n *     \n *     File.chmod(0644, \"testfile\", \"out\")   #=> 2\n */\n\nstatic VALUE\nrb_file_s_chmod(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE vmode;\n    VALUE rest;\n    int mode;\n    long n;\n\n    rb_secure(2);\n    rb_scan_args(argc, argv, \"1*\", &vmode, &rest);\n    mode = NUM2INT(vmode);\n\n    n = apply2files(chmod_internal, rest, &mode);\n    return LONG2FIX(n);\n}\n\n/*\n *  call-seq:\n *     file.chmod(mode_int)   => 0\n *  \n *  Changes permission bits on <i>file</i> to the bit pattern\n *  represented by <i>mode_int</i>. Actual effects are platform\n *  dependent; on Unix systems, see <code>chmod(2)</code> for details.\n *  Follows symbolic links. Also see <code>File#lchmod</code>.\n *     \n *     f = File.new(\"out\", \"w\");\n *     f.chmod(0644)   #=> 0\n */\n\nstatic VALUE\nrb_file_chmod(obj, vmode)\n    VALUE obj, vmode;\n{\n    rb_io_t *fptr;\n    int mode;\n\n    rb_secure(2);\n    mode = NUM2INT(vmode);\n\n    GetOpenFile(obj, fptr);\n#ifdef HAVE_FCHMOD\n    if (fchmod(fileno(fptr->f), mode) == -1)\n\trb_sys_fail(fptr->path);\n#else\n    if (!fptr->path) return Qnil;\n    if (chmod(fptr->path, mode) == -1)\n\trb_sys_fail(fptr->path);\n#endif\n\n    return INT2FIX(0);\n}\n\n#if defined(HAVE_LCHMOD)\nstatic void lchmod_internal _((const char *, void *));\nstatic void\nlchmod_internal(path, mode)\n    const char *path;\n    void *mode;\n{\n    if (lchmod(path, (int)(VALUE)mode) < 0)\n\trb_sys_fail(path);\n}\n\n/*\n *  call-seq:\n *     File.lchmod(mode_int, file_name, ...)  => integer\n *  \n *  Equivalent to <code>File::chmod</code>, but does not follow symbolic\n *  links (so it will change the permissions associated with the link,\n *  not the file referenced by the link). Often not available.\n *     \n */\n\nstatic VALUE\nrb_file_s_lchmod(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE vmode;\n    VALUE rest;\n    long mode, n;\n\n    rb_secure(2);\n    rb_scan_args(argc, argv, \"1*\", &vmode, &rest);\n    mode = NUM2INT(vmode);\n\n    n = apply2files(lchmod_internal, rest, (void *)(long)mode);\n    return LONG2FIX(n);\n}\n#else\nstatic VALUE\nrb_file_s_lchmod(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n}\n#endif\n\nstruct chown_args {\n    int owner, group;\n};\n\nstatic void chown_internal _((const char *, void *));\nstatic void\nchown_internal(path, argp)\n    const char *path;\n    void *argp;\n{\n    struct chown_args *args = (struct chown_args *)argp;\n    if (chown(path, args->owner, args->group) < 0)\n\trb_sys_fail(path);\n}\n\n/*\n *  call-seq:\n *     File.chown(owner_int, group_int, file_name,... ) -> integer\n *  \n *  Changes the owner and group of the named file(s) to the given\n *  numeric owner and group id's. Only a process with superuser\n *  privileges may change the owner of a file. The current owner of a\n *  file may change the file's group to any group to which the owner\n *  belongs. A <code>nil</code> or -1 owner or group id is ignored.\n *  Returns the number of files processed.\n *     \n *     File.chown(nil, 100, \"testfile\")\n *     \n */\n\nstatic VALUE\nrb_file_s_chown(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE o, g, rest;\n    struct chown_args arg;\n    long n;\n\n    rb_secure(2);\n    rb_scan_args(argc, argv, \"2*\", &o, &g, &rest);\n    if (NIL_P(o)) {\n\targ.owner = -1;\n    }\n    else {\n\targ.owner = NUM2INT(o);\n    }\n    if (NIL_P(g)) {\n\targ.group = -1;\n    }\n    else {\n\targ.group = NUM2INT(g);\n    }\n\n    n = apply2files(chown_internal, rest, &arg);\n    return LONG2FIX(n);\n}\n\n/*\n *  call-seq:\n *     file.chown(owner_int, group_int )   => 0\n *  \n *  Changes the owner and group of <i>file</i> to the given numeric\n *  owner and group id's. Only a process with superuser privileges may\n *  change the owner of a file. The current owner of a file may change\n *  the file's group to any group to which the owner belongs. A\n *  <code>nil</code> or -1 owner or group id is ignored. Follows\n *  symbolic links. See also <code>File#lchown</code>.\n *     \n *     File.new(\"testfile\").chown(502, 1000)\n *     \n */\n\nstatic VALUE\nrb_file_chown(obj, owner, group)\n    VALUE obj, owner, group;\n{\n    rb_io_t *fptr;\n    int o, g;\n\n    rb_secure(2);\n    o = NIL_P(owner) ? -1 : NUM2INT(owner);\n    g = NIL_P(group) ? -1 : NUM2INT(group);\n    GetOpenFile(obj, fptr);\n#if defined(DJGPP) || defined(__CYGWIN32__) || defined(_WIN32) || defined(__EMX__)\n    if (!fptr->path) return Qnil;\n    if (chown(fptr->path, o, g) == -1)\n\trb_sys_fail(fptr->path);\n#else\n    if (fchown(fileno(fptr->f), o, g) == -1)\n\trb_sys_fail(fptr->path);\n#endif\n\n    return INT2FIX(0);\n}\n\n#if defined(HAVE_LCHOWN) && !defined(__CHECKER__)\nstatic void lchown_internal _((const char *, void *));\nstatic void\nlchown_internal(path, argp)\n    const char *path;\n    void *argp;\n{\n    struct chown_args *args = (struct chown_args *)argp;\n    if (lchown(path, args->owner, args->group) < 0)\n\trb_sys_fail(path);\n}\n\n/*\n *  call-seq:\n *     file.lchown(owner_int, group_int, file_name,..) => integer\n *  \n *  Equivalent to <code>File::chown</code>, but does not follow symbolic\n *  links (so it will change the owner associated with the link, not the\n *  file referenced by the link). Often not available. Returns number\n *  of files in the argument list.\n *     \n */\n\nstatic VALUE\nrb_file_s_lchown(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE o, g, rest;\n    struct chown_args arg;\n    long n;\n\n    rb_secure(2);\n    rb_scan_args(argc, argv, \"2*\", &o, &g, &rest);\n    if (NIL_P(o)) {\n\targ.owner = -1;\n    }\n    else {\n\targ.owner = NUM2INT(o);\n    }\n    if (NIL_P(g)) {\n\targ.group = -1;\n    }\n    else {\n\targ.group = NUM2INT(g);\n    }\n\n    n = apply2files(lchown_internal, rest, &arg);\n    return LONG2FIX(n);\n}\n#else\nstatic VALUE\nrb_file_s_lchown(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    rb_notimplement();\n}\n#endif\n\nstruct timeval rb_time_timeval();\n\nstatic void utime_internal _((const char *, void *));\n\n#if defined(HAVE_UTIMES) && !defined(__CHECKER__)\n\nstatic void\nutime_internal(path, arg)\n    const char *path;\n    void *arg;\n{\n    struct timeval *tvp = arg;\n    if (utimes(path, tvp) < 0)\n\trb_sys_fail(path);\n}\n\n/*\n * call-seq:\n *  File.utime(atime, mtime, file_name,...)   =>  integer\n *\n * Sets the access and modification times of each\n * named file to the first two arguments. Returns\n * the number of file names in the argument list.\n */\n\nstatic VALUE\nrb_file_s_utime(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE atime, mtime, rest;\n    struct timeval tvs[2], *tvp = NULL;\n    long n;\n\n    rb_secure(2);\n    rb_scan_args(argc, argv, \"2*\", &atime, &mtime, &rest);\n\n    if (!NIL_P(atime) || !NIL_P(mtime)) {\n\ttvp = tvs;\n\ttvp[0] = rb_time_timeval(atime);\n\ttvp[1] = rb_time_timeval(mtime);\n    }\n\n    n = apply2files(utime_internal, rest, tvp);\n    return LONG2FIX(n);\n}\n\n#else\n\n#if !defined HAVE_UTIME_H && !defined HAVE_SYS_UTIME_H\nstruct utimbuf {\n    long actime;\n    long modtime;\n};\n#endif\n\nstatic void\nutime_internal(path, arg)\n    const char *path;\n    void *arg;\n{\n    struct utimbuf *utp = arg;\n    if (utime(path, utp) < 0)\n\trb_sys_fail(path);\n}\n\nstatic VALUE\nrb_file_s_utime(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE atime, mtime, rest;\n    long n;\n    struct timeval tv;\n    struct utimbuf utbuf, *utp = NULL;\n\n    rb_scan_args(argc, argv, \"2*\", &atime, &mtime, &rest);\n\n    if (!NIL_P(atime) || !NIL_P(mtime)) {\n\tutp = &utbuf;\n\ttv = rb_time_timeval(atime);\n\tutp->actime = tv.tv_sec;\n\ttv = rb_time_timeval(mtime);\n\tutp->modtime = tv.tv_sec;\n    }\n\n    n = apply2files(utime_internal, rest, utp);\n    return LONG2FIX(n);\n}\n\n#endif\n\nNORETURN(static void sys_fail2 _((VALUE,VALUE)));\nstatic void\nsys_fail2(s1, s2)\n    VALUE s1, s2;\n{\n    char *buf;\n    int len;\n\n    len = RSTRING(s1)->len + RSTRING(s2)->len + 5;\n    buf = ALLOCA_N(char, len);\n    snprintf(buf, len, \"%s or %s\", RSTRING(s1)->ptr, RSTRING(s2)->ptr);\n    rb_sys_fail(buf);\n}\n\n/*\n *  call-seq:\n *     File.link(old_name, new_name)    => 0\n *  \n *  Creates a new name for an existing file using a hard link. Will not\n *  overwrite <i>new_name</i> if it already exists (raising a subclass\n *  of <code>SystemCallError</code>). Not available on all platforms.\n *     \n *     File.link(\"testfile\", \".testfile\")   #=> 0\n *     IO.readlines(\".testfile\")[0]         #=> \"This is line one\\n\"\n */\n\nstatic VALUE\nrb_file_s_link(klass, from, to)\n    VALUE klass, from, to;\n{\n#ifdef HAVE_LINK\n    SafeStringValue(from);\n    SafeStringValue(to);\n\n    if (link(StringValueCStr(from), StringValueCStr(to)) < 0) {\n\tsys_fail2(from, to);\n    }\n    return INT2FIX(0);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n/*\n *  call-seq:\n *     File.symlink(old_name, new_name)   => 0\n *  \n *  Creates a symbolic link called <i>new_name</i> for the existing file\n *  <i>old_name</i>. Raises a <code>NotImplemented</code> exception on\n *  platforms that do not support symbolic links.\n *     \n *     File.symlink(\"testfile\", \"link2test\")   #=> 0\n *     \n */\n\nstatic VALUE\nrb_file_s_symlink(klass, from, to)\n    VALUE klass, from, to;\n{\n#ifdef HAVE_SYMLINK\n    SafeStringValue(from);\n    SafeStringValue(to);\n\n    if (symlink(StringValueCStr(from), StringValueCStr(to)) < 0) {\n\tsys_fail2(from, to);\n    }\n    return INT2FIX(0);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n/*\n *  call-seq:\n *     File.readlink(link_name) -> file_name\n *  \n *  Returns the name of the file referenced by the given link.\n *  Not available on all platforms.\n *     \n *     File.symlink(\"testfile\", \"link2test\")   #=> 0\n *     File.readlink(\"link2test\")              #=> \"testfile\"\n */\n\nstatic VALUE\nrb_file_s_readlink(klass, path)\n    VALUE klass, path;\n{\n#ifdef HAVE_READLINK\n    char *buf;\n    int size = 100;\n    int rv;\n    VALUE v;\n\n    SafeStringValue(path);\n    buf = xmalloc(size);\n    while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size\n#ifdef _AIX\n\t    || (rv < 0 && errno == ERANGE) /* quirky behavior of GPFS */\n#endif\n\t) {\n\tsize *= 2;\n\tbuf = xrealloc(buf, size);\n    }\n    if (rv < 0) {\n\tfree(buf);\n\trb_sys_fail(RSTRING(path)->ptr);\n    }\n    v = rb_tainted_str_new(buf, rv);\n    free(buf);\n\n    return v;\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\nstatic void unlink_internal _((const char *, void *));\nstatic void\nunlink_internal(path, arg)\n    const char *path;\n    void *arg;\n{\n    if (unlink(path) < 0)\n\trb_sys_fail(path);\n}\n\n/*\n *  call-seq:\n *     File.delete(file_name, ...)  => integer\n *     File.unlink(file_name, ...)  => integer\n *  \n *  Deletes the named files, returning the number of names\n *  passed as arguments. Raises an exception on any error.\n *  See also <code>Dir::rmdir</code>.\n */\n\nstatic VALUE\nrb_file_s_unlink(klass, args)\n    VALUE klass, args;\n{\n    long n;\n\n    rb_secure(2);\n    n = apply2files(unlink_internal, args, 0);\n    return LONG2FIX(n);\n}\n\n/*\n *  call-seq:\n *     File.rename(old_name, new_name)   => 0\n *  \n *  Renames the given file to the new name. Raises a\n *  <code>SystemCallError</code> if the file cannot be renamed.\n *     \n *     File.rename(\"afile\", \"afile.bak\")   #=> 0\n */\n\nstatic VALUE\nrb_file_s_rename(klass, from, to)\n    VALUE klass, from, to;\n{\n    const char *src, *dst;\n    SafeStringValue(from);\n    SafeStringValue(to);\n\n    src = StringValueCStr(from);\n    dst = StringValueCStr(to);\n#if defined __CYGWIN__\n    errno = 0;\n#endif\n    if (rename(src, dst) < 0) {\n#if defined DOSISH && !defined _WIN32\n\tswitch (errno) {\n\t  case EEXIST:\n#if defined (__EMX__)\n\t  case EACCES:\n#endif\n\t    if (chmod(dst, 0666) == 0 &&\n\t\tunlink(dst) == 0 &&\n\t\trename(src, dst) == 0)\n\t\treturn INT2FIX(0);\n\t}\n#endif\n\tsys_fail2(from, to);\n    }\n\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     File.umask()          => integer\n *     File.umask(integer)   => integer\n *  \n *  Returns the current umask value for this process. If the optional\n *  argument is given, set the umask to that value and return the\n *  previous value. Umask values are <em>subtracted</em> from the\n *  default permissions, so a umask of <code>0222</code> would make a\n *  file read-only for everyone.\n *     \n *     File.umask(0006)   #=> 18\n *     File.umask         #=> 6\n */\n\nstatic VALUE\nrb_file_s_umask(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int omask = 0;\n\n    rb_secure(2);\n    if (argc == 0) {\n\tomask = umask(0);\n\tumask(omask);\n    }\n    else if (argc == 1) {\n\tomask = umask(NUM2INT(argv[0]));\n    }\n    else {\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n    return INT2FIX(omask);\n}\n\n#ifdef __CYGWIN__\n#undef DOSISH\n#endif\n#if defined __CYGWIN__ || defined DOSISH\n#define DOSISH_UNC\n#define DOSISH_DRIVE_LETTER\n#define isdirsep(x) ((x) == '/' || (x) == '\\\\')\n#else\n#define isdirsep(x) ((x) == '/')\n#endif\n\n#if defined _WIN32 || defined __CYGWIN__\n#define USE_NTFS 1\n#else\n#define USE_NTFS 0\n#endif\n\n#ifdef DOSISH_DRIVE_LETTER\n#include <ctype.h>\n#endif\n\n#if USE_NTFS\n#define istrailinggabage(x) ((x) == '.' || (x) == ' ')\n#else\n#define istrailinggabage(x) 0\n#endif\n\n#ifndef CharNext\t\t/* defined as CharNext[AW] on Windows. */\n# if defined(DJGPP)\n#   define CharNext(p) ((p) + mblen(p, MB_CUR_MAX))\n# else\n#   define CharNext(p) ((p) + 1)\n# endif\n#endif\n\n#ifdef DOSISH_DRIVE_LETTER\nstatic inline int\nhas_drive_letter(buf)\n    const char *buf;\n{\n    if (ISALPHA(buf[0]) && buf[1] == ':') {\n\treturn 1;\n    }\n    else {\n\treturn 0;\n    }\n}\n\nstatic char*\ngetcwdofdrv(drv)\n    int drv;\n{\n    char drive[4];\n    char *drvcwd, *oldcwd;\n\n    drive[0] = drv;\n    drive[1] = ':';\n    drive[2] = '\\0';\n\n    /* the only way that I know to get the current directory\n       of a particular drive is to change chdir() to that drive,\n       so save the old cwd before chdir()\n    */\n    oldcwd = my_getcwd();\n    if (chdir(drive) == 0) {\n\tdrvcwd = my_getcwd();\n\tchdir(oldcwd);\n\tfree(oldcwd);\n    }\n    else {\n\t/* perhaps the drive is not exist. we return only drive letter */\n\tdrvcwd = strdup(drive);\n    }\n    return drvcwd;\n}\n#endif\n\nstatic inline char *\nskiproot(path)\n    const char *path;\n{\n#ifdef DOSISH_DRIVE_LETTER\n    if (has_drive_letter(path)) path += 2;\n#endif\n    while (isdirsep(*path)) path++;\n    return (char *)path;\n}\n\n#define nextdirsep rb_path_next\nchar *\nrb_path_next(s)\n    const char *s;\n{\n    while (*s && !isdirsep(*s)) {\n\ts = CharNext(s);\n    }\n    return (char *)s;\n}\n\n#if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) \n#define skipprefix rb_path_skip_prefix\n#else\n#define skipprefix(path) (path)\n#endif\nchar *\nrb_path_skip_prefix(path)\n    const char *path;\n{\n#if defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) \n#ifdef DOSISH_UNC\n    if (isdirsep(path[0]) && isdirsep(path[1])) {\n\tpath += 2;\n\twhile (isdirsep(*path)) path++;\n\tif (*(path = nextdirsep(path)) && path[1] && !isdirsep(path[1]))\n\t    path = nextdirsep(path + 1);\n\treturn (char *)path;\n    }\n#endif\n#ifdef DOSISH_DRIVE_LETTER\n    if (has_drive_letter(path))\n\treturn (char *)(path + 2);\n#endif\n#endif\n    return (char *)path;\n}\n\n#define strrdirsep rb_path_last_separator\nchar *\nrb_path_last_separator(path)\n    const char *path;\n{\n    char *last = NULL;\n    while (*path) {\n\tif (isdirsep(*path)) {\n\t    const char *tmp = path++;\n\t    while (isdirsep(*path)) path++;\n\t    if (!*path) break;\n\t    last = (char *)tmp;\n\t}\n\telse {\n\t    path = CharNext(path);\n\t}\n    }\n    return last;\n}\n\nstatic char *\nchompdirsep(path)\n    const char *path;\n{\n    while (*path) {\n\tif (isdirsep(*path)) {\n\t    const char *last = path++;\n\t    while (isdirsep(*path)) path++;\n\t    if (!*path) return (char *)last;\n\t}\n\telse {\n\t    path = CharNext(path);\n\t}\n    }\n    return (char *)path;\n}\n\nchar *\nrb_path_end(path)\n    const char *path;\n{\n    if (isdirsep(*path)) path++;\n    return chompdirsep(path);\n}\n\n#if USE_NTFS\nstatic char *\nntfs_tail(const char *path)\n{\n    while (*path == '.') path++;\n    while (*path && *path != ':') {\n\tif (istrailinggabage(*path)) {\n\t    const char *last = path++;\n\t    while (istrailinggabage(*path)) path++;\n\t    if (!*path || *path == ':') return (char *)last;\n\t}\n\telse if (isdirsep(*path)) {\n\t    const char *last = path++;\n\t    while (isdirsep(*path)) path++;\n\t    if (!*path) return (char *)last;\n\t    if (*path == ':') path++;\n\t}\n\telse {\n\t    path = CharNext(path);\n\t}\n    }\n    return (char *)path;\n}\n#endif\n\n#define BUFCHECK(cond) do {\\\n    long bdiff = p - buf;\\\n    if (cond) {\\\n\tdo {buflen *= 2;} while (cond);\\\n\trb_str_resize(result, buflen);\\\n\tbuf = RSTRING_PTR(result);\\\n\tp = buf + bdiff;\\\n\tpend = buf + buflen;\\\n    }\\\n} while (0)\n\n#define BUFINIT() (\\\n    p = buf = RSTRING(result)->ptr,\\\n    buflen = RSTRING(result)->len,\\\n    pend = p + buflen)\n\n#if !defined(TOLOWER)\n#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c))\n#endif\n\nstatic int is_absolute_path _((const char*));\n\nstatic VALUE\nfile_expand_path(fname, dname, result)\n    VALUE fname, dname, result;\n{\n    const char *s, *b;\n    char *buf, *p, *pend, *root;\n    long buflen, dirlen;\n    int tainted;\n\n    s = StringValuePtr(fname);\n    BUFINIT();\n    tainted = OBJ_TAINTED(fname);\n\n    if (s[0] == '~') {\n\tif (isdirsep(s[1]) || s[1] == '\\0') {\n\t    const char *dir = getenv(\"HOME\");\n\n\t    if (!dir) {\n\t\trb_raise(rb_eArgError, \"couldn't find HOME environment -- expanding `%s'\", s);\n\t    }\n\t    dirlen = strlen(dir);\n\t    BUFCHECK(dirlen > buflen);\n\t    strcpy(buf, dir);\n#if defined DOSISH || defined __CYGWIN__\n\t    for (p = buf; *p; p = CharNext(p)) {\n\t\tif (*p == '\\\\') {\n\t\t    *p = '/';\n\t\t}\n\t    }\n#else\n\t    p = buf + strlen(dir);\n#endif\n\t    s++;\n\t    tainted = 1;\n\t}\n\telse {\n#ifdef HAVE_PWD_H\n\t    struct passwd *pwPtr;\n\t    s++;\n#endif\n\t    s = nextdirsep(b = s);\n\t    BUFCHECK(bdiff + (s-b) >= buflen);\n\t    memcpy(p, b, s-b);\n\t    p += s-b;\n\t    *p = '\\0';\n#ifdef HAVE_PWD_H\n\t    pwPtr = getpwnam(buf);\n\t    if (!pwPtr) {\n\t\tendpwent();\n\t\trb_raise(rb_eArgError, \"user %s doesn't exist\", buf);\n\t    }\n\t    dirlen = strlen(pwPtr->pw_dir);\n\t    BUFCHECK(dirlen > buflen);\n\t    strcpy(buf, pwPtr->pw_dir);\n\t    p = buf + strlen(pwPtr->pw_dir);\n\t    endpwent();\n#endif\n\t}\n    }\n#ifdef DOSISH_DRIVE_LETTER\n    /* skip drive letter */\n    else if (has_drive_letter(s)) {\n\tif (isdirsep(s[2])) {\n\t    /* specified drive letter, and full path */\n\t    /* skip drive letter */\n\t    BUFCHECK(bdiff + 2 >= buflen);\n\t    memcpy(p, s, 2);\n\t    p += 2;\n\t    s += 2;\n\t}\n\telse {\n\t    /* specified drive, but not full path */\n\t    int same = 0;\n\t    if (!NIL_P(dname)) {\n\t\tfile_expand_path(dname, Qnil, result);\n\t\tBUFINIT();\n\t\tif (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) {\n\t\t    /* ok, same drive */\n\t\t    same = 1;\n\t\t}\n\t    }\n\t    if (!same) {\n\t\tchar *dir = getcwdofdrv(*s);\n\n\t\ttainted = 1;\n\t\tdirlen = strlen(dir);\n\t\tBUFCHECK(dirlen > buflen);\n\t\tstrcpy(buf, dir);\n\t\tfree(dir);\n\t    }\n\t    p = chompdirsep(skiproot(buf));\n\t    s += 2;\n\t}\n    }\n#endif\n    else if (!is_absolute_path(s)) {\n\tif (!NIL_P(dname)) {\n\t    file_expand_path(dname, Qnil, result);\n\t    BUFINIT();\n\t}\n\telse {\n\t    char *dir = my_getcwd();\n\n\t    tainted = 1;\n\t    dirlen = strlen(dir);\n\t    BUFCHECK(dirlen > buflen);\n\t    strcpy(buf, dir);\n\t    free(dir);\n\t}\n#if defined DOSISH || defined __CYGWIN__\n\tif (isdirsep(*s)) {\n\t    /* specified full path, but not drive letter nor UNC */\n\t    /* we need to get the drive letter or UNC share name */\n\t    p = skipprefix(buf);\n\t}\n\telse\n#endif\n\t    p = chompdirsep(skiproot(buf));\n    }\n    else {\n\tb = s;\n\tdo s++; while (isdirsep(*s));\n\tp = buf + (s - b);\n\tBUFCHECK(bdiff >= buflen);\n\tmemset(buf, '/', p - buf);\n    }\n    if (p > buf && p[-1] == '/')\n\t--p;\n    else\n\t*p = '/';\n\n    p[1] = 0;\n    root = skipprefix(buf);\n\n    b = s;\n    while (*s) {\n\tswitch (*s) {\n\t  case '.':\n\t    if (b == s++) {\t/* beginning of path element */\n\t\tswitch (*s) {\n\t\t  case '\\0':\n\t\t    b = s;\n\t\t    break;\n\t\t  case '.':\n\t\t    if (*(s+1) == '\\0' || isdirsep(*(s+1))) {\n\t\t\t/* We must go back to the parent */\n\t\t\tchar *n;\n\t\t\t*p = '\\0';\n\t\t\tif (!(n = strrdirsep(root))) {\n\t\t\t    *p = '/';\n\t\t\t}\n\t\t\telse {\n\t\t\t    p = n;\n\t\t\t}\n\t\t\tb = ++s;\n\t\t    }\n#if USE_NTFS\n\t\t    else {\n\t\t\tdo *++s; while (istrailinggabage(*s));\n\t\t    }\n#endif\n\t\t    break;\n\t\t  case '/':\n#if defined DOSISH || defined __CYGWIN__\n\t\t  case '\\\\':\n#endif\n\t\t    b = ++s;\n\t\t    break;\n\t\t  default:\n\t\t    /* ordinary path element, beginning don't move */\n\t\t    break;\n\t\t}\n\t    }\n#if USE_NTFS\n\t    else {\n\t\t--s;\n\t      case ' ': {\n\t\tconst char *e = s;\n\t\twhile (istrailinggabage(*s)) s++;\n\t\tif (!*s) {\n\t\t    s = e;\n\t\t    goto endpath;\n\t\t}\n\t      }\n\t    }\n#endif\n\t    break;\n\t  case '/':\n#if defined DOSISH || defined __CYGWIN__\n\t  case '\\\\':\n#endif\n\t    if (s > b) {\n\t\tlong rootdiff = root - buf;\n\t\tBUFCHECK(bdiff + (s-b+1) >= buflen);\n\t\troot = buf + rootdiff;\n\t\tmemcpy(++p, b, s-b);\n\t\tp += s-b;\n\t\t*p = '/';\n\t    }\n\t    b = ++s;\n\t    break;\n\t  default:\n\t    s = CharNext(s);\n\t    break;\n\t}\n    }\n\n    if (s > b) {\n#if USE_NTFS\n      endpath:\n\tif (s > b + 6 && strncasecmp(s - 6, \":$DATA\", 6) == 0) {\n\t    /* alias of stream */\n\t    /* get rid of a bug of x64 VC++ */\n\t    if (*(s-7) == ':') s -= 7;\t\t\t/* prime */\n\t    else if (memchr(b, ':', s - 6 - b)) s -= 6; /* alternative */\n\t}\n#endif\n\tBUFCHECK(bdiff + (s-b) >= buflen);\n\tmemcpy(++p, b, s-b);\n\tp += s-b;\n    }\n    if (p == skiproot(buf) - 1) p++;\n\n#if USE_NTFS\n    *p = '\\0';\n    if ((s = strrdirsep(b = buf)) != 0 && !strpbrk(s, \"*?\")) {\n\tsize_t len;\n\tWIN32_FIND_DATA wfd;\n#ifdef __CYGWIN__\n\tint lnk_added = 0, is_symlink = 0;\n\tstruct stat st;\n\tchar w32buf[MAXPATHLEN];\n\tp = (char *)s;\n\tif (lstat(buf, &st) == 0 && S_ISLNK(st.st_mode)) {\n\t    is_symlink = 1;\n\t    *p = '\\0';\n\t}\n\tif (cygwin_conv_to_win32_path((*buf ? buf : \"/\"), w32buf) == 0) {\n\t    b = w32buf;\n\t}\n\tif (is_symlink && b == w32buf) {\n\t    *p = '\\\\';\n\t    strlcat(w32buf, p, sizeof(w32buf));\n\t    len = strlen(p);\n\t    if (len > 4 && strcasecmp(p + len - 4, \".lnk\") != 0) {\n\t\tlnk_added = 1;\n\t\tstrlcat(w32buf, \".lnk\", sizeof(w32buf));\n\t    }\n\t}\n\t*p = '/';\n#endif\n\tHANDLE h = FindFirstFile(b, &wfd);\n\tif (h != INVALID_HANDLE_VALUE) {\n\t    FindClose(h);\n\t    len = strlen(wfd.cFileName);\n#ifdef __CYGWIN__\n\t    if (lnk_added && len > 4 &&\n\t\tstrcasecmp(wfd.cFileName + len - 4, \".lnk\") == 0) {\n\t\twfd.cFileName[len -= 4] = '\\0';\n\t    }\n#else\n\t    p = (char *)s;\n#endif\n\t    ++p;\n\t    BUFCHECK(bdiff + len >= buflen);\n\t    memcpy(p, wfd.cFileName, len + 1);\n\t    p += len;\n\t}\n#ifdef __CYGWIN__\n\telse {\n\t    p += strlen(p);\n\t}\n#endif\n    }\n#endif\n\n    if (tainted) OBJ_TAINT(result);\n    rb_str_set_len(result, p - buf);\n    return result;\n}\n\nVALUE\nrb_file_expand_path(fname, dname)\n    VALUE fname, dname;\n{\n    return file_expand_path(fname, dname, rb_str_new(0, MAXPATHLEN + 2));\n}\n\n/*\n *  call-seq:\n *     File.expand_path(file_name [, dir_string] ) -> abs_file_name\n *  \n *  Converts a pathname to an absolute pathname. Relative paths are\n *  referenced from the current working directory of the process unless\n *  <i>dir_string</i> is given, in which case it will be used as the\n *  starting point. The given pathname may start with a\n *  ``<code>~</code>'', which expands to the process owner's home\n *  directory (the environment variable <code>HOME</code> must be set\n *  correctly). ``<code>~</code><i>user</i>'' expands to the named\n *  user's home directory.\n *     \n *     File.expand_path(\"~oracle/bin\")           #=> \"/home/oracle/bin\"\n *     File.expand_path(\"../../bin\", \"/tmp/x\")   #=> \"/bin\"\n */\n\nVALUE\nrb_file_s_expand_path(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE fname, dname;\n\n    if (argc == 1) {\n\treturn rb_file_expand_path(argv[0], Qnil);\n    }\n    rb_scan_args(argc, argv, \"11\", &fname, &dname);\n\n    return rb_file_expand_path(fname, dname);\n}\n\nstatic int\nrmext(p, l1, e)\n    const char *p, *e;\n    int l1;\n{\n    int l2;\n\n    if (!e) return 0;\n\n    l2 = strlen(e);\n    if (l2 == 2 && e[1] == '*') {\n\tunsigned char c = *e;\n\te = p + l1;\n\tdo {\n\t    if (e <= p) return 0;\n\t} while (*--e != c);\n\treturn e - p;\n    }\n    if (l1 < l2) return l1;\n\n#if CASEFOLD_FILESYSTEM\n#define fncomp strncasecmp\n#else\n#define fncomp strncmp\n#endif\n    if (fncomp(p+l1-l2, e, l2) == 0) {\n\treturn l1-l2;\n    }\n    return 0;\n}\n\n/*\n *  call-seq:\n *     File.basename(file_name [, suffix] ) -> base_name\n *  \n *  Returns the last component of the filename given in <i>file_name</i>,\n *  which must be formed using forward slashes (``<code>/</code>'')\n *  regardless of the separator used on the local file system. If\n *  <i>suffix</i> is given and present at the end of <i>file_name</i>,\n *  it is removed.\n *     \n *     File.basename(\"/home/gumby/work/ruby.rb\")          #=> \"ruby.rb\"\n *     File.basename(\"/home/gumby/work/ruby.rb\", \".rb\")   #=> \"ruby\"\n */\n\nstatic VALUE\nrb_file_s_basename(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE fname, fext, basename;\n    const char *name, *p;\n#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC\n    const char *root;\n#endif\n    int f, n;\n\n    if (rb_scan_args(argc, argv, \"11\", &fname, &fext) == 2) {\n\tStringValue(fext);\n    }\n    StringValue(fname);\n    if (RSTRING(fname)->len == 0 || !*(name = RSTRING(fname)->ptr))\n\treturn fname;\n    name = skipprefix(name);\n#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC\n    root = name;\n#endif\n    while (isdirsep(*name))\n\tname++;\n    if (!*name) {\n\tp = name - 1;\n\tf = 1;\n#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC\n\tif (name != root) {\n\t    /* has slashes */\n\t}\n#ifdef DOSISH_DRIVE_LETTER\n\telse if (*p == ':') {\n\t    p++;\n\t    f = 0;\n\t}\n#endif\n#ifdef DOSISH_UNC\n\telse {\n\t    p = \"/\";\n\t}\n#endif\n#endif\n    }\n    else {\n\tif (!(p = strrdirsep(name))) {\n\t    p = name;\n\t}\n\telse {\n\t    while (isdirsep(*p)) p++; /* skip last / */\n\t}\n#if USE_NTFS\n\tn = ntfs_tail(p) - p;\n#else\n\tn = chompdirsep(p) - p;\n#endif\n\tif (NIL_P(fext) || !(f = rmext(p, n, StringValueCStr(fext)))) {\n\t    f = n;\n\t}\n\tif (f == RSTRING_LEN(fname)) return fname;\n    }\n    basename = rb_str_new(p, f);\n    OBJ_INFECT(basename, fname);\n    return basename;\n}\n\n/*\n *  call-seq:\n *     File.dirname(file_name ) -> dir_name\n *  \n *  Returns all components of the filename given in <i>file_name</i>\n *  except the last one. The filename must be formed using forward\n *  slashes (``<code>/</code>'') regardless of the separator used on the\n *  local file system.\n *     \n *     File.dirname(\"/home/gumby/work/ruby.rb\")   #=> \"/home/gumby/work\"\n */\n\nstatic VALUE\nrb_file_s_dirname(klass, fname)\n    VALUE klass, fname;\n{\n    const char *name, *root, *p;\n    VALUE dirname;\n\n    name = StringValueCStr(fname);\n    root = skiproot(name);\n#ifdef DOSISH_UNC\n    if (root > name + 1 && isdirsep(*name))\n\troot = skipprefix(name = root - 2);\n#else\n    if (root > name + 1)\n\tname = root - 1;\n#endif\n    p = strrdirsep(root);\n    if (!p) {\n\tp = root;\n    }\n    if (p == name)\n\treturn rb_str_new2(\".\");\n#ifdef DOSISH_DRIVE_LETTER\n    if (has_drive_letter(name) && isdirsep(*(name + 2))) {\n\tconst char *top = skiproot(name + 2);\n\tdirname = rb_str_new(name, 3);\n\trb_str_cat(dirname, top, p - top);\n    }\n    else\n#endif\n    dirname = rb_str_new(name, p - name);\n#ifdef DOSISH_DRIVE_LETTER\n    if (has_drive_letter(name) && root == name + 2 && p - name == 2)\n\trb_str_cat(dirname, \".\", 1);\n#endif\n    OBJ_INFECT(dirname, fname);\n    return dirname;\n}\n\n/*\n *  call-seq:\n *     File.extname(path) -> string\n *  \n *  Returns the extension (the portion of file name in <i>path</i>\n *  after the period).\n *     \n *     File.extname(\"test.rb\")         #=> \".rb\"\n *     File.extname(\"a/b/d/test.rb\")   #=> \".rb\"\n *     File.extname(\"test\")            #=> \"\"\n *     File.extname(\".profile\")        #=> \"\"\n *     \n */\n\nstatic VALUE\nrb_file_s_extname(klass, fname)\n    VALUE klass, fname;\n{\n    const char *name, *p, *e;\n    VALUE extname;\n\n    name = StringValueCStr(fname);\n    p = strrdirsep(name);\t/* get the last path component */\n    if (!p)\n\tp = name;\n    else\n\tname = ++p;\n\n    e = 0;\n    while (*p) {\n\tif (*p == '.' || istrailinggabage(*p)) {\n#if USE_NTFS\n\t    const char *last = p++, *dot = last;\n\t    while (istrailinggabage(*p)) {\n\t\tif (*p == '.') dot = p;\n\t\tp++;\n\t    }\n\t    if (!*p || *p == ':') {\n\t\tp = last;\n\t\tbreak;\n\t    }\n\t    if (*last == '.' || dot > last) e = dot;\n\t    continue;\n#else\n\t    e = p;\t  /* get the last dot of the last component */\n#endif\n\t}\n#if USE_NTFS\n\telse if (*p == ':') {\n\t    break;\n\t}\n#endif\n\telse if (isdirsep(*p))\n\t    break;\n\tp = CharNext(p);\n    }\n    if (!e || e == name || e+1 == p)\t/* no dot, or the only dot is first or end? */\n\treturn rb_str_new(0, 0);\n    extname = rb_str_new(e, p - e);\t/* keep the dot, too! */\n    OBJ_INFECT(extname, fname);\n    return extname;\n}\n\n/*\n *  call-seq:\n *     File.split(file_name)   => array\n *  \n *  Splits the given string into a directory and a file component and\n *  returns them in a two-element array. See also\n *  <code>File::dirname</code> and <code>File::basename</code>.\n *     \n *     File.split(\"/home/gumby/.profile\")   #=> [\"/home/gumby\", \".profile\"]\n */\n\nstatic VALUE\nrb_file_s_split(klass, path)\n    VALUE klass, path;\n{\n    StringValue(path);\t\t/* get rid of converting twice */\n    return rb_assoc_new(rb_file_s_dirname(Qnil, path), rb_file_s_basename(1,&path));\n}\n\nstatic VALUE separator;\n\nstatic VALUE rb_file_join _((VALUE ary, VALUE sep));\n\nstatic VALUE\nfile_inspect_join(ary, arg)\n    VALUE ary;\n    VALUE *arg;\n{\n    return rb_file_join(arg[0], arg[1]);\n}\n\nstatic VALUE\nrb_file_join(ary, sep)\n    VALUE ary, sep;\n{\n    long len, i;\n    int taint = 0;\n    VALUE result, tmp;\n    const char *name, *tail;\n\n    if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);\n    if (OBJ_TAINTED(ary)) taint = 1;\n    if (OBJ_TAINTED(sep)) taint = 1;\n\n    len = 1;\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\tif (TYPE(RARRAY(ary)->ptr[i]) == T_STRING) {\n\t    len += RSTRING(RARRAY(ary)->ptr[i])->len;\n\t}\n\telse {\n\t    len += 10;\n\t}\n    }\n    if (!NIL_P(sep) && TYPE(sep) == T_STRING) {\n\tlen += RSTRING(sep)->len * RARRAY(ary)->len - 1;\n    }\n    result = rb_str_buf_new(len);\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\ttmp = RARRAY(ary)->ptr[i];\n\tswitch (TYPE(tmp)) {\n\t  case T_STRING:\n\t    break;\n\t  case T_ARRAY:\n\t    if (tmp == ary || rb_inspecting_p(tmp)) {\n\t\trb_raise(rb_eArgError, \"recursive array\");\n\t    }\n\t    else {\n\t\tVALUE args[2];\n\n\t\targs[0] = tmp;\n\t\targs[1] = sep;\n\t\ttmp = rb_protect_inspect(file_inspect_join, ary, (VALUE)args);\n\t    }\n\t    break;\n\t  default:\n\t    StringValueCStr(tmp);\n\t}\n\tname = StringValueCStr(result);\n\tif (i > 0 && !NIL_P(sep)) {\n\t    tail = chompdirsep(name);\n\t    if (RSTRING(tmp)->ptr && isdirsep(RSTRING(tmp)->ptr[0])) {\n\t\tRSTRING(result)->len = tail - name;\n\t    }\n\t    else if (!*tail) {\n\t\trb_str_buf_append(result, sep);\n\t    }\n\t}\n\trb_str_buf_append(result, tmp);\n\tif (OBJ_TAINTED(tmp)) taint = 1;\n    }\n\n    if (taint) OBJ_TAINT(result);\n    return result;\n}\n\n/*\n *  call-seq:\n *     File.join(string, ...) -> path\n *  \n *  Returns a new string formed by joining the strings using\n *  <code>File::SEPARATOR</code>.\n *     \n *     File.join(\"usr\", \"mail\", \"gumby\")   #=> \"usr/mail/gumby\"\n *     \n */\n\nstatic VALUE\nrb_file_s_join(klass, args)\n    VALUE klass, args;\n{\n    return rb_file_join(args, separator);\n}\n\n/*\n *  call-seq:\n *     File.truncate(file_name, integer)  => 0\n *  \n *  Truncates the file <i>file_name</i> to be at most <i>integer</i>\n *  bytes long. Not available on all platforms.\n *     \n *     f = File.new(\"out\", \"w\")\n *     f.write(\"1234567890\")     #=> 10\n *     f.close                   #=> nil\n *     File.truncate(\"out\", 5)   #=> 0\n *     File.size(\"out\")          #=> 5\n *     \n */\n\nstatic VALUE\nrb_file_s_truncate(klass, path, len)\n    VALUE klass, path, len;\n{\n    off_t pos;\n\n    rb_secure(2);\n    pos = NUM2OFFT(len);\n    SafeStringValue(path);\n\n#ifdef HAVE_TRUNCATE\n    if (truncate(StringValueCStr(path), pos) < 0)\n\trb_sys_fail(RSTRING(path)->ptr);\n#else\n# ifdef HAVE_CHSIZE\n    {\n\tint tmpfd;\n\n#  ifdef _WIN32\n\tif ((tmpfd = open(StringValueCStr(path), O_RDWR)) < 0) {\n\t    rb_sys_fail(RSTRING(path)->ptr);\n\t}\n#  else\n\tif ((tmpfd = open(StringValueCStr(path), 0)) < 0) {\n\t    rb_sys_fail(RSTRING(path)->ptr);\n\t}\n#  endif\n\tif (chsize(tmpfd, pos) < 0) {\n\t    close(tmpfd);\n\t    rb_sys_fail(RSTRING(path)->ptr);\n\t}\n\tclose(tmpfd);\n    }\n# else\n    rb_notimplement();\n# endif\n#endif\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     file.truncate(integer)    => 0\n *  \n *  Truncates <i>file</i> to at most <i>integer</i> bytes. The file\n *  must be opened for writing. Not available on all platforms.\n *     \n *     f = File.new(\"out\", \"w\")\n *     f.syswrite(\"1234567890\")   #=> 10\n *     f.truncate(5)              #=> 0\n *     f.close()                  #=> nil\n *     File.size(\"out\")           #=> 5\n */\n\nstatic VALUE\nrb_file_truncate(obj, len)\n    VALUE obj, len;\n{\n    rb_io_t *fptr;\n    FILE *f;\n    off_t pos;\n\n    rb_secure(2);\n    pos = NUM2OFFT(len);\n    GetOpenFile(obj, fptr);\n    if (!(fptr->mode & FMODE_WRITABLE)) {\n\trb_raise(rb_eIOError, \"not opened for writing\");\n    }\n    f = GetWriteFile(fptr);\n    fflush(f);\n    fseeko(f, (off_t)0, SEEK_CUR);\n#ifdef HAVE_FTRUNCATE\n    if (ftruncate(fileno(f), pos) < 0)\n\trb_sys_fail(fptr->path);\n#else\n# ifdef HAVE_CHSIZE\n    if (chsize(fileno(f), pos) < 0)\n\trb_sys_fail(fptr->path);\n# else\n    rb_notimplement();\n# endif\n#endif\n    return INT2FIX(0);\n}\n\n# ifndef LOCK_SH\n#  define LOCK_SH 1\n# endif\n# ifndef LOCK_EX\n#  define LOCK_EX 2\n# endif\n# ifndef LOCK_NB\n#  define LOCK_NB 4\n# endif\n# ifndef LOCK_UN\n#  define LOCK_UN 8\n# endif\n\n#ifdef __CYGWIN__\n#include <winerror.h>\nextern unsigned long __attribute__((stdcall)) GetLastError(void);\n\nstatic int\ncygwin_flock(int fd, int op)\n{\n    int old_errno = errno;\n    int ret = flock(fd, op);\n    if (GetLastError() == ERROR_NOT_LOCKED) {\n\tret = 0;\n\terrno = old_errno;\n    }\n    return ret;\n}\n# define flock(fd, op) cygwin_flock(fd, op)\n#endif\n\nstatic int\nrb_thread_flock(fd, op, fptr)\n    int fd, op;\n    rb_io_t *fptr;\n{\n    if (rb_thread_alone() || (op & LOCK_NB)) {\n\tint ret;\n\tTRAP_BEG;\n\tret = flock(fd, op);\n\tTRAP_END;\n\treturn ret;\n    }\n    op |= LOCK_NB;\n    while (flock(fd, op) < 0) {\n\tswitch (errno) {\n\t  case EAGAIN:\n\t  case EACCES:\n#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN\n\t  case EWOULDBLOCK:\n#endif\n\t    rb_thread_polling();\t/* busy wait */\n\t    rb_io_check_closed(fptr);\n\t    continue;\n\t  default:\n\t    return -1;\n\t}\n    }\n    return 0;\n}\n#ifdef __CYGWIN__\n# undef flock\n#endif\n#define flock(fd, op) rb_thread_flock(fd, op, fptr)\n\n/*\n *  call-seq:\n *     file.flock (locking_constant ) =>  0 or false\n *  \n *  Locks or unlocks a file according to <i>locking_constant</i> (a\n *  logical <em>or</em> of the values in the table below).\n *  Returns <code>false</code> if <code>File::LOCK_NB</code> is\n *  specified and the operation would otherwise have blocked. Not\n *  available on all platforms.\n *     \n *  Locking constants (in class File):\n *\n *     LOCK_EX   | Exclusive lock. Only one process may hold an\n *               | exclusive lock for a given file at a time.\n *     ----------+------------------------------------------------\n *     LOCK_NB   | Don't block when locking. May be combined\n *               | with other lock options using logical or.\n *     ----------+------------------------------------------------\n *     LOCK_SH   | Shared lock. Multiple processes may each hold a\n *               | shared lock for a given file at the same time.\n *     ----------+------------------------------------------------\n *     LOCK_UN   | Unlock.\n *\n *  Example:\n *\n *     File.new(\"testfile\").flock(File::LOCK_UN)   #=> 0\n *     \n */\n\nstatic VALUE\nrb_file_flock(obj, operation)\n    VALUE obj;\n    VALUE operation;\n{\n#ifndef __CHECKER__\n    rb_io_t *fptr;\n    int op;\n\n    rb_secure(2);\n    op = NUM2INT(operation);\n    GetOpenFile(obj, fptr);\n\n    if (fptr->mode & FMODE_WRITABLE) {\n\tfflush(GetWriteFile(fptr));\n    }\n  retry:\n    if (flock(fileno(fptr->f), op) < 0) {\n\tswitch (errno) {\n\t  case EAGAIN:\n\t  case EACCES:\n#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN\n\t  case EWOULDBLOCK:\n#endif\n\t      return Qfalse;\n\t  case EINTR:\n#if defined(ERESTART)\n\t  case ERESTART:\n#endif\n\t    goto retry;\n\t}\n\trb_sys_fail(fptr->path);\n    }\n#endif\n    return INT2FIX(0);\n}\n#undef flock\n\nstatic void\ntest_check(n, argc, argv)\n    int n, argc;\n    VALUE *argv;\n{\n    int i;\n\n    n+=1;\n    if (n != argc) rb_raise(rb_eArgError, \"wrong number of arguments (%d for %d)\", argc, n);\n    for (i=1; i<n; i++) {\n\tswitch (TYPE(argv[i])) {\n\t  case T_STRING:\n\t  default:\n\t    SafeStringValue(argv[i]);\n\t    break;\n\t  case T_FILE:\n\t    break;\n\t}\n    }\n}\n\n#define CHECK(n) test_check((n), argc, argv)\n\n/*\n *  call-seq:\n *     test(int_cmd, file1 [, file2] ) => obj\n *  \n *  Uses the integer <i>aCmd</i> to perform various tests on\n *  <i>file1</i> (first table below) or on <i>file1</i> and\n *  <i>file2</i> (second table).\n *     \n *  File tests on a single file:\n *\n *    Test   Returns   Meaning\n *     ?A  | Time    | Last access time for file1\n *     ?b  | boolean | True if file1 is a block device\n *     ?c  | boolean | True if file1 is a character device\n *     ?C  | Time    | Last change time for file1\n *     ?d  | boolean | True if file1 exists and is a directory\n *     ?e  | boolean | True if file1 exists\n *     ?f  | boolean | True if file1 exists and is a regular file\n *     ?g  | boolean | True if file1 has the \\CF{setgid} bit\n *         |         | set (false under NT)\n *     ?G  | boolean | True if file1 exists and has a group\n *         |         | ownership equal to the caller's group\n *     ?k  | boolean | True if file1 exists and has the sticky bit set\n *     ?l  | boolean | True if file1 exists and is a symbolic link\n *     ?M  | Time    | Last modification time for file1\n *     ?o  | boolean | True if file1 exists and is owned by \n *         |         | the caller's effective uid\n *     ?O  | boolean | True if file1 exists and is owned by\n *         |         | the caller's real uid\n *     ?p  | boolean | True if file1 exists and is a fifo\n *     ?r  | boolean | True if file1 is readable by the effective\n *         |         | uid/gid of the caller\n *     ?R  | boolean | True if file is readable by the real\n *         |         | uid/gid of the caller\n *     ?s  | int/nil | If file1 has nonzero size, return the size,\n *         |         | otherwise return nil\n *     ?S  | boolean | True if file1 exists and is a socket\n *     ?u  | boolean | True if file1 has the setuid bit set\n *     ?w  | boolean | True if file1 exists and is writable by\n *         |         | the effective uid/gid\n *     ?W  | boolean | True if file1 exists and is writable by\n *         |         | the real uid/gid\n *     ?x  | boolean | True if file1 exists and is executable by\n *         |         | the effective uid/gid\n *     ?X  | boolean | True if file1 exists and is executable by\n *         |         | the real uid/gid\n *     ?z  | boolean | True if file1 exists and has a zero length\n *\n * Tests that take two files:\n *\n *     ?-  | boolean | True if file1 and file2 are identical\n *     ?=  | boolean | True if the modification times of file1\n *         |         | and file2 are equal\n *     ?<  | boolean | True if the modification time of file1\n *         |         | is prior to that of file2\n *     ?>  | boolean | True if the modification time of file1\n *         |         | is after that of file2\n */\n\nstatic VALUE\nrb_f_test(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int cmd;\n\n    if (argc == 0) rb_raise(rb_eArgError, \"wrong number of arguments\");\n#if 0 /* 1.7 behavior? */\n    if (argc == 1) {\n\treturn RTEST(argv[0]) ? Qtrue : Qfalse;\n    }\n#endif\n    cmd = NUM2CHR(argv[0]);\n    if (cmd == 0) return Qfalse;\n    if (strchr(\"bcdefgGkloOprRsSuwWxXz\", cmd)) {\n\tCHECK(1);\n\tswitch (cmd) {\n\t  case 'b':\n\t    return test_b(0, argv[1]);\n\n\t  case 'c':\n\t    return test_c(0, argv[1]);\n\n\t  case 'd':\n\t    return test_d(0, argv[1]);\n\n\t  case 'a':\n\t  case 'e':\n\t    return test_e(0, argv[1]);\n\n\t  case 'f':\n\t    return test_f(0, argv[1]);\n\n\t  case 'g':\n\t    return test_sgid(0, argv[1]);\n\n\t  case 'G':\n\t    return test_grpowned(0, argv[1]);\n\n\t  case 'k':\n\t    return test_sticky(0, argv[1]);\n\n\t  case 'l':\n\t    return test_l(0, argv[1]);\n\n\t  case 'o':\n\t    return test_owned(0, argv[1]);\n\n\t  case 'O':\n\t    return test_rowned(0, argv[1]);\n\n\t  case 'p':\n\t    return test_p(0, argv[1]);\n\n\t  case 'r':\n\t    return test_r(0, argv[1]);\n\n\t  case 'R':\n\t    return test_R(0, argv[1]);\n\n\t  case 's':\n\t    return test_s(0, argv[1]);\n\n\t  case 'S':\n\t    return test_S(0, argv[1]);\n\n\t  case 'u':\n\t    return test_suid(0, argv[1]);\n\n\t  case 'w':\n\t    return test_w(0, argv[1]);\n\n\t  case 'W':\n\t    return test_W(0, argv[1]);\n\n\t  case 'x':\n\t    return test_x(0, argv[1]);\n\n\t  case 'X':\n\t    return test_X(0, argv[1]);\n\n\t  case 'z':\n\t    return test_z(0, argv[1]);\n\t}\n    }\n\n    if (strchr(\"MAC\", cmd)) {\n\tstruct stat st;\n\n\tCHECK(1);\n\tif (rb_stat(argv[1], &st) == -1) {\n\t    rb_sys_fail(RSTRING(argv[1])->ptr);\n\t}\n\n\tswitch (cmd) {\n\t  case 'A':\n\t    return rb_time_new(st.st_atime, 0);\n\t  case 'M':\n\t    return rb_time_new(st.st_mtime, 0);\n\t  case 'C':\n\t    return rb_time_new(st.st_ctime, 0);\n\t}\n    }\n\n    if (cmd == '-') {\n\tCHECK(2);\n\treturn test_identical(0, argv[1], argv[2]);\n    }\n\n    if (strchr(\"=<>\", cmd)) {\n\tstruct stat st1, st2;\n\n\tCHECK(2);\n\tif (rb_stat(argv[1], &st1) < 0) return Qfalse;\n\tif (rb_stat(argv[2], &st2) < 0) return Qfalse;\n\n\tswitch (cmd) {\n\t  case '=':\n\t    if (st1.st_mtime == st2.st_mtime) return Qtrue;\n\t    return Qfalse;\n\n\t  case '>':\n\t    if (st1.st_mtime > st2.st_mtime) return Qtrue;\n\t    return Qfalse;\n\n\t  case '<':\n\t    if (st1.st_mtime < st2.st_mtime) return Qtrue;\n\t    return Qfalse;\n\t}\n    }\n    /* unknown command */\n    rb_raise(rb_eArgError, \"unknown command ?%c\", cmd);\n    return Qnil;\t\t/* not reached */\n}\n\n\n/*\n *  Document-class: File::Stat\n *\n *  Objects of class <code>File::Stat</code> encapsulate common status\n *  information for <code>File</code> objects. The information is\n *  recorded at the moment the <code>File::Stat</code> object is\n *  created; changes made to the file after that point will not be\n *  reflected. <code>File::Stat</code> objects are returned by\n *  <code>IO#stat</code>, <code>File::stat</code>,\n *  <code>File#lstat</code>, and <code>File::lstat</code>. Many of these\n *  methods return platform-specific values, and not all values are\n *  meaningful on all systems. See also <code>Kernel#test</code>.\n */\n\nstatic VALUE rb_stat_s_alloc _((VALUE));\nstatic VALUE\nrb_stat_s_alloc(klass)\n    VALUE klass;\n{\n    return stat_new_0(klass, 0);\n}\n\n/*\n * call-seq:\n *\n *   File::Stat.new(file_name)  => stat\n *\n * Create a File::Stat object for the given file name (raising an\n * exception if the file doesn't exist).\n */\n\nstatic VALUE\nrb_stat_init(obj, fname)\n    VALUE obj, fname;\n{\n    struct stat st, *nst;\n\n    SafeStringValue(fname);\n\n    if (stat(StringValueCStr(fname), &st) == -1) {\n\trb_sys_fail(RSTRING(fname)->ptr);\n    }\n    if (DATA_PTR(obj)) {\n\tfree(DATA_PTR(obj));\n\tDATA_PTR(obj) = NULL;\n    }\n    nst = ALLOC(struct stat);\n    *nst = st;\n    DATA_PTR(obj) = nst;\n\n    return Qnil;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_stat_init_copy(copy, orig)\n    VALUE copy, orig;\n{\n    struct stat *nst;\n\n    if (copy == orig) return orig;\n    rb_check_frozen(copy);\n    /* need better argument type check */\n    if (!rb_obj_is_instance_of(orig, rb_obj_class(copy))) {\n\trb_raise(rb_eTypeError, \"wrong argument class\");\n    }\n    if (DATA_PTR(copy)) {\n\tfree(DATA_PTR(copy));\n\tDATA_PTR(copy) = 0;\n    }\n    if (DATA_PTR(orig)) {\n\tnst = ALLOC(struct stat);\n\t*nst = *(struct stat*)DATA_PTR(orig);\n\tDATA_PTR(copy) = nst;\n    }\n\n    return copy;\n}\n\n/*\n *  call-seq:\n *     stat.ftype   => string\n *  \n *  Identifies the type of <i>stat</i>. The return string is one of:\n *  ``<code>file</code>'', ``<code>directory</code>'',\n *  ``<code>characterSpecial</code>'', ``<code>blockSpecial</code>'',\n *  ``<code>fifo</code>'', ``<code>link</code>'',\n *  ``<code>socket</code>'', or ``<code>unknown</code>''.\n *     \n *     File.stat(\"/dev/tty\").ftype   #=> \"characterSpecial\"\n *     \n */\n\nstatic VALUE\nrb_stat_ftype(obj)\n    VALUE obj;\n{\n    return rb_file_ftype(get_stat(obj));\n}\n\n/*\n *  call-seq:\n *     stat.directory?   => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is a directory,\n *  <code>false</code> otherwise.\n *     \n *     File.stat(\"testfile\").directory?   #=> false\n *     File.stat(\".\").directory?          #=> true\n */\n\nstatic VALUE\nrb_stat_d(obj)\n    VALUE obj;\n{\n    if (S_ISDIR(get_stat(obj)->st_mode)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.pipe?    => true or false\n *  \n *  Returns <code>true</code> if the operating system supports pipes and\n *  <i>stat</i> is a pipe; <code>false</code> otherwise.\n */\n\nstatic VALUE\nrb_stat_p(obj)\n    VALUE obj;\n{\n#ifdef S_IFIFO\n    if (S_ISFIFO(get_stat(obj)->st_mode)) return Qtrue;\n\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.symlink?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is a symbolic link,\n *  <code>false</code> if it isn't or if the operating system doesn't\n *  support this feature. As <code>File::stat</code> automatically\n *  follows symbolic links, <code>symlink?</code> will always be\n *  <code>false</code> for an object returned by\n *  <code>File::stat</code>.\n *     \n *     File.symlink(\"testfile\", \"alink\")   #=> 0\n *     File.stat(\"alink\").symlink?         #=> false\n *     File.lstat(\"alink\").symlink?        #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_l(obj)\n    VALUE obj;\n{\n#ifdef S_ISLNK\n    if (S_ISLNK(get_stat(obj)->st_mode)) return Qtrue;\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.socket?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is a socket,\n *  <code>false</code> if it isn't or if the operating system doesn't\n *  support this feature.\n *     \n *     File.stat(\"testfile\").socket?   #=> false\n *     \n */\n\nstatic VALUE\nrb_stat_S(obj)\n    VALUE obj;\n{\n#ifdef S_ISSOCK\n    if (S_ISSOCK(get_stat(obj)->st_mode)) return Qtrue;\n\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.blockdev?   => true or false\n *  \n *  Returns <code>true</code> if the file is a block device,\n *  <code>false</code> if it isn't or if the operating system doesn't\n *  support this feature.\n *     \n *     File.stat(\"testfile\").blockdev?    #=> false\n *     File.stat(\"/dev/hda1\").blockdev?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_b(obj)\n    VALUE obj;\n{\n#ifdef S_ISBLK\n    if (S_ISBLK(get_stat(obj)->st_mode)) return Qtrue;\n\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.chardev?    => true or false\n *  \n *  Returns <code>true</code> if the file is a character device,\n *  <code>false</code> if it isn't or if the operating system doesn't\n *  support this feature.\n *     \n *     File.stat(\"/dev/tty\").chardev?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_c(obj)\n    VALUE obj;\n{\n    if (S_ISCHR(get_stat(obj)->st_mode)) return Qtrue;\n\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.owned?    => true or false\n *  \n *  Returns <code>true</code> if the effective user id of the process is\n *  the same as the owner of <i>stat</i>.\n *     \n *     File.stat(\"testfile\").owned?      #=> true\n *     File.stat(\"/etc/passwd\").owned?   #=> false\n *     \n */\n\nstatic VALUE\nrb_stat_owned(obj)\n    VALUE obj;\n{\n    if (get_stat(obj)->st_uid == geteuid()) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\nrb_stat_rowned(obj)\n    VALUE obj;\n{\n    if (get_stat(obj)->st_uid == getuid()) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.grpowned?   => true or false\n *  \n *  Returns true if the effective group id of the process is the same as\n *  the group id of <i>stat</i>. On Windows NT, returns <code>false</code>.\n *     \n *     File.stat(\"testfile\").grpowned?      #=> true\n *     File.stat(\"/etc/passwd\").grpowned?   #=> false\n *     \n */\n\nstatic VALUE\nrb_stat_grpowned(obj)\n    VALUE obj;\n{\n#ifndef _WIN32\n    if (group_member(get_stat(obj)->st_gid)) return Qtrue;\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.readable?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is readable by the\n *  effective user id of this process.\n *     \n *     File.stat(\"testfile\").readable?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_r(obj)\n    VALUE obj;\n{\n    struct stat *st = get_stat(obj);\n\n#ifdef USE_GETEUID\n    if (geteuid() == 0) return Qtrue;\n#endif\n#ifdef S_IRUSR\n    if (rb_stat_owned(obj))\n\treturn st->st_mode & S_IRUSR ? Qtrue : Qfalse;\n#endif\n#ifdef S_IRGRP\n    if (rb_stat_grpowned(obj))\n\treturn st->st_mode & S_IRGRP ? Qtrue : Qfalse;\n#endif\n#ifdef S_IROTH\n    if (!(st->st_mode & S_IROTH)) return Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     stat.readable_real? -> true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is readable by the real\n *  user id of this process.\n *     \n *     File.stat(\"testfile\").readable_real?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_R(obj)\n    VALUE obj;\n{\n    struct stat *st = get_stat(obj);\n\n#ifdef USE_GETEUID\n    if (getuid() == 0) return Qtrue;\n#endif\n#ifdef S_IRUSR\n    if (rb_stat_rowned(obj))\n\treturn st->st_mode & S_IRUSR ? Qtrue : Qfalse;\n#endif\n#ifdef S_IRGRP\n    if (group_member(get_stat(obj)->st_gid))\n\treturn st->st_mode & S_IRGRP ? Qtrue : Qfalse;\n#endif\n#ifdef S_IROTH\n    if (!(st->st_mode & S_IROTH)) return Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     stat.writable? -> true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is writable by the\n *  effective user id of this process.\n *     \n *     File.stat(\"testfile\").writable?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_w(obj)\n    VALUE obj;\n{\n    struct stat *st = get_stat(obj);\n\n#ifdef USE_GETEUID\n    if (geteuid() == 0) return Qtrue;\n#endif\n#ifdef S_IWUSR\n    if (rb_stat_owned(obj))\n\treturn st->st_mode & S_IWUSR ? Qtrue : Qfalse;\n#endif\n#ifdef S_IWGRP\n    if (rb_stat_grpowned(obj))\n\treturn st->st_mode & S_IWGRP ? Qtrue : Qfalse;\n#endif\n#ifdef S_IWOTH\n    if (!(st->st_mode & S_IWOTH)) return Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     stat.writable_real? -> true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is writable by the real\n *  user id of this process.\n *     \n *     File.stat(\"testfile\").writable_real?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_W(obj)\n    VALUE obj;\n{\n    struct stat *st = get_stat(obj);\n\n#ifdef USE_GETEUID\n    if (getuid() == 0) return Qtrue;\n#endif\n#ifdef S_IWUSR\n    if (rb_stat_rowned(obj))\n\treturn st->st_mode & S_IWUSR ? Qtrue : Qfalse;\n#endif\n#ifdef S_IWGRP\n    if (group_member(get_stat(obj)->st_gid))\n\treturn st->st_mode & S_IWGRP ? Qtrue : Qfalse;\n#endif\n#ifdef S_IWOTH\n    if (!(st->st_mode & S_IWOTH)) return Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     stat.executable?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is executable or if the\n *  operating system doesn't distinguish executable files from\n *  nonexecutable files. The tests are made using the effective owner of\n *  the process.\n *     \n *     File.stat(\"testfile\").executable?   #=> false\n *     \n */\n\nstatic VALUE\nrb_stat_x(obj)\n    VALUE obj;\n{\n    struct stat *st = get_stat(obj);\n\n#ifdef USE_GETEUID\n    if (geteuid() == 0) {\n\treturn st->st_mode & S_IXUGO ? Qtrue : Qfalse;\n    }\n#endif\n#ifdef S_IXUSR\n    if (rb_stat_owned(obj))\n\treturn st->st_mode & S_IXUSR ? Qtrue : Qfalse;\n#endif\n#ifdef S_IXGRP\n    if (rb_stat_grpowned(obj))\n\treturn st->st_mode & S_IXGRP ? Qtrue : Qfalse;\n#endif\n#ifdef S_IXOTH\n    if (!(st->st_mode & S_IXOTH)) return Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     stat.executable_real?    => true or false\n *  \n *  Same as <code>executable?</code>, but tests using the real owner of\n *  the process.\n */\n\nstatic VALUE\nrb_stat_X(obj)\n    VALUE obj;\n{\n    struct stat *st = get_stat(obj);\n\n#ifdef USE_GETEUID\n    if (getuid() == 0) {\n\treturn st->st_mode & S_IXUGO ? Qtrue : Qfalse;\n    }\n#endif\n#ifdef S_IXUSR\n    if (rb_stat_rowned(obj))\n\treturn st->st_mode & S_IXUSR ? Qtrue : Qfalse;\n#endif\n#ifdef S_IXGRP\n    if (group_member(get_stat(obj)->st_gid))\n\treturn st->st_mode & S_IXGRP ? Qtrue : Qfalse;\n#endif\n#ifdef S_IXOTH\n    if (!(st->st_mode & S_IXOTH)) return Qfalse;\n#endif\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     stat.file?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is a regular file (not\n *  a device file, pipe, socket, etc.).\n *     \n *     File.stat(\"testfile\").file?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_f(obj)\n    VALUE obj;\n{\n    if (S_ISREG(get_stat(obj)->st_mode)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.zero?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> is a zero-length file;\n *  <code>false</code> otherwise.\n *     \n *     File.stat(\"testfile\").zero?   #=> false\n *     \n */\n\nstatic VALUE\nrb_stat_z(obj)\n    VALUE obj;\n{\n    if (get_stat(obj)->st_size == 0) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     state.size    => integer\n *  \n *  Returns the size of <i>stat</i> in bytes.\n *     \n *     File.stat(\"testfile\").size   #=> 66\n *     \n */\n\nstatic VALUE\nrb_stat_s(obj)\n    VALUE obj;\n{\n    off_t size = get_stat(obj)->st_size;\n\n    if (size == 0) return Qnil;\n    return OFFT2NUM(size);\n}\n\n/*\n *  call-seq:\n *     stat.setuid?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> has the set-user-id\n *  permission bit set, <code>false</code> if it doesn't or if the\n *  operating system doesn't support this feature.\n *     \n *     File.stat(\"/bin/su\").setuid?   #=> true\n */\n\nstatic VALUE\nrb_stat_suid(obj)\n    VALUE obj;\n{\n#ifdef S_ISUID\n    if (get_stat(obj)->st_mode & S_ISUID) return Qtrue;\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.setgid?   => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> has the set-group-id\n *  permission bit set, <code>false</code> if it doesn't or if the\n *  operating system doesn't support this feature.\n *     \n *     File.stat(\"/usr/sbin/lpc\").setgid?   #=> true\n *     \n */\n\nstatic VALUE\nrb_stat_sgid(obj)\n    VALUE obj;\n{\n#ifdef S_ISGID\n    if (get_stat(obj)->st_mode & S_ISGID) return Qtrue;\n#endif\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     stat.sticky?    => true or false\n *  \n *  Returns <code>true</code> if <i>stat</i> has its sticky bit set,\n *  <code>false</code> if it doesn't or if the operating system doesn't\n *  support this feature.\n *     \n *     File.stat(\"testfile\").sticky?   #=> false\n *     \n */\n\nstatic VALUE\nrb_stat_sticky(obj)\n    VALUE obj;\n{\n#ifdef S_ISVTX\n    if (get_stat(obj)->st_mode & S_ISVTX) return Qtrue;\n#endif\n    return Qfalse;\n}\n\nVALUE rb_mFConst;\n\nvoid\nrb_file_const(name, value)\n    const char *name;\n    VALUE value;\n{\n    rb_define_const(rb_mFConst, name, value);\n}\n\nstatic int\nis_absolute_path(path)\n    const char *path;\n{\n#ifdef DOSISH_DRIVE_LETTER\n    if (has_drive_letter(path) && isdirsep(path[2])) return 1;\n#endif\n#ifdef DOSISH_UNC\n    if (isdirsep(path[0]) && isdirsep(path[1])) return 1;\n#endif\n#ifndef DOSISH\n    if (path[0] == '/') return 1;\n#endif\n    return 0;\n}\n\n#ifndef ENABLE_PATH_CHECK\n# if defined DOSISH || defined __CYGWIN__\n#   define ENABLE_PATH_CHECK 0\n# else\n#   define ENABLE_PATH_CHECK 1\n# endif\n#endif\n\n#if ENABLE_PATH_CHECK\nstatic int\npath_check_0(fpath, execpath)\n     VALUE fpath;\n     int execpath;\n{\n    struct stat st;\n    const char *p0 = StringValueCStr(fpath);\n    char *p = 0, *s;\n\n    if (!is_absolute_path(p0)) {\n\tchar *buf = my_getcwd();\n\tVALUE newpath;\n\n\tnewpath = rb_str_new2(buf);\n\tfree(buf);\n\n\trb_str_cat2(newpath, \"/\");\n\trb_str_cat2(newpath, p0);\n\tp0 = RSTRING(fpath = newpath)->ptr;\n    }\n    for (;;) {\n#ifndef S_IWOTH\n# define S_IWOTH 002\n#endif\n\tif (stat(p0, &st) == 0 && S_ISDIR(st.st_mode) && (st.st_mode & S_IWOTH)\n#ifdef S_ISVTX\n\t    && !(p && execpath && (st.st_mode & S_ISVTX))\n#endif\n\t    ) {\n\t    rb_warn(\"Insecure world writable dir %s in %sPATH, mode 0%o\",\n\t\t    p0, (execpath ? \"\" : \"LOAD_\"), st.st_mode);\n\t    if (p) *p = '/';\n\t    return 0;\n\t}\n\ts = strrdirsep(p0);\n\tif (p) *p = '/';\n\tif (!s || s == p0) return 1;\n\tp = s;\n\t*p = '\\0';\n    }\n}\n#endif\n\nstatic int\nfpath_check(path)\n    const char *path;\n{\n#if ENABLE_PATH_CHECK\n    return path_check_0(rb_str_new2(path), Qfalse);\n#else\n    return 1;\n#endif\n}\n\nint\nrb_path_check(path)\n    const char *path;\n{\n#if ENABLE_PATH_CHECK\n    const char *p0, *p, *pend;\n    const char sep = PATH_SEP_CHAR;\n\n    if (!path) return 1;\n\n    pend = path + strlen(path);\n    p0 = path;\n    p = strchr(path, sep);\n    if (!p) p = pend;\n\n    for (;;) {\n\tif (!path_check_0(rb_str_new(p0, p - p0), Qtrue)) {\n\t    return 0;\t\t/* not safe */\n\t}\n\tp0 = p + 1;\n\tif (p0 > pend) break;\n\tp = strchr(p0, sep);\n\tif (!p) p = pend;\n    }\n#endif\n    return 1;\n}\n\n#if defined(__MACOS__) || defined(riscos)\nstatic int\nis_macos_native_path(path)\n    const char *path;\n{\n    if (strchr(path, ':')) return 1;\n    return 0;\n}\n#endif\n\nstatic int\nfile_load_ok(file)\n    const char *file;\n{\n    int ret = 1;\n    int fd = open(file, O_RDONLY);\n    if (fd == -1) return 0;\n#if !defined DOSISH\n    {\n\tstruct stat st;\n\tif (fstat(fd, &st) || !S_ISREG(st.st_mode)) {\n\t    ret = 0;\n\t}\n    }\n#endif\n    (void)close(fd);\n    return ret;\n}\n\nextern VALUE rb_load_path;\n\nint\nrb_find_file_ext(filep, ext)\n    VALUE *filep;\n    const char * const *ext;\n{\n    const char *path, *found;\n    const char *f = RSTRING(*filep)->ptr;\n    VALUE fname;\n    long i, j;\n\n    if (f[0] == '~') {\n\tfname = rb_file_expand_path(*filep, Qnil);\n\tif (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) {\n\t    rb_raise(rb_eSecurityError, \"loading from unsafe file %s\", f);\n\t}\n\tOBJ_FREEZE(fname);\n\tf = StringValueCStr(fname);\n\t*filep = fname;\n    }\n\n    if (is_absolute_path(f)) {\n\tfor (i=0; ext[i]; i++) {\n\t    fname = rb_str_dup(*filep);\n\t    rb_str_cat2(fname, ext[i]);\n\t    OBJ_FREEZE(fname);\n\t    if (file_load_ok(StringValueCStr(fname))) {\n\t\t*filep = fname;\n\t\treturn i+1;\n\t    }\n\t}\n\treturn 0;\n    }\n\n    if (!rb_load_path) return 0;\n\n    Check_Type(rb_load_path, T_ARRAY);\n    for (i=0;i<RARRAY(rb_load_path)->len;i++) {\n\tVALUE str = RARRAY(rb_load_path)->ptr[i];\n\n\tSafeStringValue(str);\n\tif (RSTRING(str)->len == 0) continue;\n\tpath = RSTRING(str)->ptr;\n\tfor (j=0; ext[j]; j++) {\n\t    fname = rb_str_dup(*filep);\n\t    rb_str_cat2(fname, ext[j]);\n\t    OBJ_FREEZE(fname);\n\t    found = dln_find_file(StringValueCStr(fname), path);\n\t    if (found && file_load_ok(found)) {\n\t\t*filep = fname;\n\t\treturn j+1;\n\t    }\n\t}\n    }\n    return 0;\n}\n\nVALUE\nrb_find_file(path)\n    VALUE path;\n{\n    VALUE tmp;\n    const char *f = StringValueCStr(path);\n    const char *lpath;\n\n    if (f[0] == '~') {\n\tpath = rb_file_expand_path(path, Qnil);\n\tif (rb_safe_level() >= 1 && OBJ_TAINTED(path)) {\n\t    rb_raise(rb_eSecurityError, \"loading from unsafe path %s\", f);\n\t}\n\tOBJ_FREEZE(path);\n\tf = StringValueCStr(path);\n    }\n\n#if defined(__MACOS__) || defined(riscos)\n    if (is_macos_native_path(f)) {\n\tif (rb_safe_level() >= 1 && !fpath_check(f)) {\n\t    rb_raise(rb_eSecurityError, \"loading from unsafe file %s\", f);\n\t}\n\tif (file_load_ok(f)) return path;\n    }\n#endif\n\n    if (is_absolute_path(f)) {\n\tif (rb_safe_level() >= 1 && !fpath_check(f)) {\n\t    rb_raise(rb_eSecurityError, \"loading from unsafe file %s\", f);\n\t}\n\tif (file_load_ok(f)) return path;\n    }\n\n    if (rb_safe_level() >= 4) {\n\trb_raise(rb_eSecurityError, \"loading from non-absolute path %s\", f);\n    }\n\n    if (rb_load_path) {\n\tlong i;\n\n\tCheck_Type(rb_load_path, T_ARRAY);\n\ttmp = rb_ary_new();\n\tfor (i=0;i<RARRAY(rb_load_path)->len;i++) {\n\t    VALUE str = RARRAY(rb_load_path)->ptr[i];\n\t    SafeStringValue(str);\n\t    if (RSTRING(str)->len > 0) {\n\t\trb_ary_push(tmp, str);\n\t    }\n\t}\n\ttmp = rb_ary_join(tmp, rb_str_new2(PATH_SEP));\n\tif (RSTRING(tmp)->len == 0) {\n\t    lpath = 0;\n\t}\n\telse {\n\t    lpath = RSTRING(tmp)->ptr;\n\t}\n    }\n    else {\n\tlpath = 0;\n    }\n\n    if (!lpath) {\n\treturn 0;\t\t/* no path, no load */\n    }\n    if (!(f = dln_find_file(f, lpath))) {\n\treturn 0;\n    }\n    if (rb_safe_level() >= 1 && !fpath_check(f)) {\n\trb_raise(rb_eSecurityError, \"loading from unsafe file %s\", f);\n    }\n    if (file_load_ok(f)) {\n\ttmp = rb_str_new2(f);\n\tOBJ_FREEZE(tmp);\n\treturn tmp;\n    }\n    return 0;\n}\n\nstatic void\ndefine_filetest_function(name, func, argc)\n    const char *name;\n    VALUE (*func)();\n    int argc;\n{\n    rb_define_module_function(rb_mFileTest, name, func, argc);\n    rb_define_singleton_method(rb_cFile, name, func, argc);\n}\n\n\n/*\n *  A <code>File</code> is an abstraction of any file object accessible\n *  by the program and is closely associated with class <code>IO</code>\n *  <code>File</code> includes the methods of module\n *  <code>FileTest</code> as class methods, allowing you to write (for\n *  example) <code>File.exist?(\"foo\")</code>.\n *     \n *  In the description of File methods,\n *  <em>permission bits</em> are a platform-specific\n *  set of bits that indicate permissions of a file. On Unix-based\n *  systems, permissions are viewed as a set of three octets, for the\n *  owner, the group, and the rest of the world. For each of these\n *  entities, permissions may be set to read, write, or execute the\n *  file:\n *     \n *  The permission bits <code>0644</code> (in octal) would thus be\n *  interpreted as read/write for owner, and read-only for group and\n *  other. Higher-order bits may also be used to indicate the type of\n *  file (plain, directory, pipe, socket, and so on) and various other\n *  special features. If the permissions are for a directory, the\n *  meaning of the execute bit changes; when set the directory can be\n *  searched.\n *     \n *  On non-Posix operating systems, there may be only the ability to\n *  make a file read-only or read-write. In this case, the remaining\n *  permission bits will be synthesized to resemble typical values. For\n *  instance, on Windows NT the default permission bits are\n *  <code>0644</code>, which means read/write for owner, read-only for\n *  all others. The only change that can be made is to make the file\n *  read-only, which is reported as <code>0444</code>.\n */\n\nvoid\nInit_File()\n{\n    rb_mFileTest = rb_define_module(\"FileTest\");\n    rb_cFile = rb_define_class(\"File\", rb_cIO);\n\n    define_filetest_function(\"directory?\", test_d, 1);\n    define_filetest_function(\"exist?\", test_e, 1);\n    define_filetest_function(\"exists?\", test_e, 1); /* temporary */\n    define_filetest_function(\"readable?\", test_r, 1);\n    define_filetest_function(\"readable_real?\", test_R, 1);\n    define_filetest_function(\"writable?\", test_w, 1);\n    define_filetest_function(\"writable_real?\", test_W, 1);\n    define_filetest_function(\"executable?\", test_x, 1);\n    define_filetest_function(\"executable_real?\", test_X, 1);\n    define_filetest_function(\"file?\", test_f, 1);\n    define_filetest_function(\"zero?\", test_z, 1);\n    define_filetest_function(\"size?\", test_s, 1);\n    define_filetest_function(\"size\", rb_file_s_size, 1);\n    define_filetest_function(\"owned?\", test_owned, 1);\n    define_filetest_function(\"grpowned?\", test_grpowned, 1);\n\n    define_filetest_function(\"pipe?\", test_p, 1);\n    define_filetest_function(\"symlink?\", test_l, 1);\n    define_filetest_function(\"socket?\", test_S, 1);\n\n    define_filetest_function(\"blockdev?\", test_b, 1);\n    define_filetest_function(\"chardev?\", test_c, 1);\n\n    define_filetest_function(\"setuid?\", test_suid, 1);\n    define_filetest_function(\"setgid?\", test_sgid, 1);\n    define_filetest_function(\"sticky?\", test_sticky, 1);\n\n    define_filetest_function(\"identical?\", test_identical, 2);\n\n    rb_define_singleton_method(rb_cFile, \"stat\",  rb_file_s_stat, 1);\n    rb_define_singleton_method(rb_cFile, \"lstat\", rb_file_s_lstat, 1);\n    rb_define_singleton_method(rb_cFile, \"ftype\", rb_file_s_ftype, 1);\n\n    rb_define_singleton_method(rb_cFile, \"atime\", rb_file_s_atime, 1);\n    rb_define_singleton_method(rb_cFile, \"mtime\", rb_file_s_mtime, 1);\n    rb_define_singleton_method(rb_cFile, \"ctime\", rb_file_s_ctime, 1);\n\n    rb_define_singleton_method(rb_cFile, \"utime\", rb_file_s_utime, -1);\n    rb_define_singleton_method(rb_cFile, \"chmod\", rb_file_s_chmod, -1);\n    rb_define_singleton_method(rb_cFile, \"chown\", rb_file_s_chown, -1);\n    rb_define_singleton_method(rb_cFile, \"lchmod\", rb_file_s_lchmod, -1);\n    rb_define_singleton_method(rb_cFile, \"lchown\", rb_file_s_lchown, -1);\n\n    rb_define_singleton_method(rb_cFile, \"link\", rb_file_s_link, 2);\n    rb_define_singleton_method(rb_cFile, \"symlink\", rb_file_s_symlink, 2);\n    rb_define_singleton_method(rb_cFile, \"readlink\", rb_file_s_readlink, 1);\n\n    rb_define_singleton_method(rb_cFile, \"unlink\", rb_file_s_unlink, -2);\n    rb_define_singleton_method(rb_cFile, \"delete\", rb_file_s_unlink, -2);\n    rb_define_singleton_method(rb_cFile, \"rename\", rb_file_s_rename, 2);\n    rb_define_singleton_method(rb_cFile, \"umask\", rb_file_s_umask, -1);\n    rb_define_singleton_method(rb_cFile, \"truncate\", rb_file_s_truncate, 2);\n    rb_define_singleton_method(rb_cFile, \"expand_path\", rb_file_s_expand_path, -1);\n    rb_define_singleton_method(rb_cFile, \"basename\", rb_file_s_basename, -1);\n    rb_define_singleton_method(rb_cFile, \"dirname\", rb_file_s_dirname, 1);\n    rb_define_singleton_method(rb_cFile, \"extname\", rb_file_s_extname, 1);\n\n    separator = rb_obj_freeze(rb_str_new2(\"/\"));\n    rb_define_const(rb_cFile, \"Separator\", separator);\n    rb_define_const(rb_cFile, \"SEPARATOR\", separator);\n    rb_define_singleton_method(rb_cFile, \"split\",  rb_file_s_split, 1);\n    rb_define_singleton_method(rb_cFile, \"join\",   rb_file_s_join, -2);\n\n#ifdef DOSISH\n    rb_define_const(rb_cFile, \"ALT_SEPARATOR\", rb_obj_freeze(rb_str_new2(\"\\\\\")));\n#else\n    rb_define_const(rb_cFile, \"ALT_SEPARATOR\", Qnil);\n#endif\n    rb_define_const(rb_cFile, \"PATH_SEPARATOR\", rb_obj_freeze(rb_str_new2(PATH_SEP)));\n\n    rb_define_method(rb_cIO, \"stat\",  rb_io_stat, 0); /* this is IO's method */\n    rb_define_method(rb_cFile, \"lstat\",  rb_file_lstat, 0);\n\n    rb_define_method(rb_cFile, \"atime\", rb_file_atime, 0);\n    rb_define_method(rb_cFile, \"mtime\", rb_file_mtime, 0);\n    rb_define_method(rb_cFile, \"ctime\", rb_file_ctime, 0);\n\n    rb_define_method(rb_cFile, \"chmod\", rb_file_chmod, 1);\n    rb_define_method(rb_cFile, \"chown\", rb_file_chown, 2);\n    rb_define_method(rb_cFile, \"truncate\", rb_file_truncate, 1);\n\n    rb_define_method(rb_cFile, \"flock\", rb_file_flock, 1);\n\n    rb_mFConst = rb_define_module_under(rb_cFile, \"Constants\");\n    rb_include_module(rb_cIO, rb_mFConst);\n    rb_file_const(\"LOCK_SH\", INT2FIX(LOCK_SH));\n    rb_file_const(\"LOCK_EX\", INT2FIX(LOCK_EX));\n    rb_file_const(\"LOCK_UN\", INT2FIX(LOCK_UN));\n    rb_file_const(\"LOCK_NB\", INT2FIX(LOCK_NB));\n\n    rb_define_method(rb_cFile, \"path\",  rb_file_path, 0);\n    rb_define_global_function(\"test\", rb_f_test, -1);\n\n    rb_cStat = rb_define_class_under(rb_cFile, \"Stat\", rb_cObject);\n    rb_define_alloc_func(rb_cStat,  rb_stat_s_alloc);\n    rb_define_method(rb_cStat, \"initialize\", rb_stat_init, 1);\n    rb_define_method(rb_cStat, \"initialize_copy\", rb_stat_init_copy, 1);\n\n    rb_include_module(rb_cStat, rb_mComparable);\n\n    rb_define_method(rb_cStat, \"<=>\", rb_stat_cmp, 1);\n\n    rb_define_method(rb_cStat, \"dev\", rb_stat_dev, 0);\n    rb_define_method(rb_cStat, \"dev_major\", rb_stat_dev_major, 0);\n    rb_define_method(rb_cStat, \"dev_minor\", rb_stat_dev_minor, 0);\n    rb_define_method(rb_cStat, \"ino\", rb_stat_ino, 0);\n    rb_define_method(rb_cStat, \"mode\", rb_stat_mode, 0);\n    rb_define_method(rb_cStat, \"nlink\", rb_stat_nlink, 0);\n    rb_define_method(rb_cStat, \"uid\", rb_stat_uid, 0);\n    rb_define_method(rb_cStat, \"gid\", rb_stat_gid, 0);\n    rb_define_method(rb_cStat, \"rdev\", rb_stat_rdev, 0);\n    rb_define_method(rb_cStat, \"rdev_major\", rb_stat_rdev_major, 0);\n    rb_define_method(rb_cStat, \"rdev_minor\", rb_stat_rdev_minor, 0);\n    rb_define_method(rb_cStat, \"size\", rb_stat_size, 0);\n    rb_define_method(rb_cStat, \"blksize\", rb_stat_blksize, 0);\n    rb_define_method(rb_cStat, \"blocks\", rb_stat_blocks, 0);\n    rb_define_method(rb_cStat, \"atime\", rb_stat_atime, 0);\n    rb_define_method(rb_cStat, \"mtime\", rb_stat_mtime, 0);\n    rb_define_method(rb_cStat, \"ctime\", rb_stat_ctime, 0);\n\n    rb_define_method(rb_cStat, \"inspect\", rb_stat_inspect, 0);\n\n    rb_define_method(rb_cStat, \"ftype\", rb_stat_ftype, 0);\n\n    rb_define_method(rb_cStat, \"directory?\",  rb_stat_d, 0);\n    rb_define_method(rb_cStat, \"readable?\",  rb_stat_r, 0);\n    rb_define_method(rb_cStat, \"readable_real?\",  rb_stat_R, 0);\n    rb_define_method(rb_cStat, \"writable?\",  rb_stat_w, 0);\n    rb_define_method(rb_cStat, \"writable_real?\",  rb_stat_W, 0);\n    rb_define_method(rb_cStat, \"executable?\",  rb_stat_x, 0);\n    rb_define_method(rb_cStat, \"executable_real?\",  rb_stat_X, 0);\n    rb_define_method(rb_cStat, \"file?\",  rb_stat_f, 0);\n    rb_define_method(rb_cStat, \"zero?\",  rb_stat_z, 0);\n    rb_define_method(rb_cStat, \"size?\",  rb_stat_s, 0);\n    rb_define_method(rb_cStat, \"owned?\",  rb_stat_owned, 0);\n    rb_define_method(rb_cStat, \"grpowned?\",  rb_stat_grpowned, 0);\n\n    rb_define_method(rb_cStat, \"pipe?\",  rb_stat_p, 0);\n    rb_define_method(rb_cStat, \"symlink?\",  rb_stat_l, 0);\n    rb_define_method(rb_cStat, \"socket?\",  rb_stat_S, 0);\n\n    rb_define_method(rb_cStat, \"blockdev?\",  rb_stat_b, 0);\n    rb_define_method(rb_cStat, \"chardev?\",  rb_stat_c, 0);\n\n    rb_define_method(rb_cStat, \"setuid?\",  rb_stat_suid, 0);\n    rb_define_method(rb_cStat, \"setgid?\",  rb_stat_sgid, 0);\n    rb_define_method(rb_cStat, \"sticky?\",  rb_stat_sticky, 0);\n}\n"
  },
  {
    "path": "gc.c",
    "content": "/**********************************************************************\n\n  gc.c -\n\n  $Author$\n  $Date$\n  created at: Tue Oct  5 09:44:46 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n#include \"st.h\"\n#include \"node.h\"\n#include \"env.h\"\n#include \"re.h\"\n#include <stdio.h>\n#include <setjmp.h>\n#include <math.h>\n#include <sys/types.h>\n#include <ctype.h>\n\n#include <sys/mman.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <stdarg.h>\n\n#ifdef HAVE_SYS_TIME_H\n#include <sys/time.h>\n#endif\n\n#ifdef HAVE_SYS_RESOURCE_H\n#include <sys/resource.h>\n#endif\n\n#if defined _WIN32 || defined __CYGWIN__\n#include <windows.h>\n#endif\n\nvoid re_free_registers _((struct re_registers*));\nvoid rb_io_fptr_finalize _((struct rb_io_t*));\n\n#define rb_setjmp(env) RUBY_SETJMP(env)\n#define rb_jmp_buf rb_jmpbuf_t\n#ifdef __CYGWIN__\nint _setjmp(), _longjmp();\n#endif\n\n#define T_DEFERRED 0x3a\n\n#ifndef GC_LEVEL_MAX  /*maximum # of VALUEs on 'C' stack during GC*/\n#define GC_LEVEL_MAX  8000\n#endif\n#ifndef GC_STACK_PAD\n#define GC_STACK_PAD  200  /* extra padding VALUEs for GC stack */\n#endif\n#define GC_STACK_MAX  (GC_LEVEL_MAX+GC_STACK_PAD)\n\n/* The address of the end of the main thread's application stack. When the\n * main thread is active, application code may not cause the stack to grow\n * past this point. Past this point there's still a small area reserved for\n * garbage collector operations.\n */\nstatic VALUE *stack_limit;\n/*\n * The address of the end of the current thread's GC stack. When running\n * the GC, the stack may not grow past this point.\n * The value of this variable is reset every time garbage_collect() is\n * called.\n */\nstatic VALUE *gc_stack_limit;\n\nstatic void run_final();\nstatic VALUE nomem_error;\nstatic void garbage_collect(const char* reason);\nstatic void add_to_longlife_recent_allocations(VALUE ptr);\n\n#define DEFAULT_LONGLIFE_LAZINESS 0.05\nstatic float longlife_laziness = DEFAULT_LONGLIFE_LAZINESS;\nstatic int longlife_collection = Qfalse;\nstatic int longlife_recent_allocations = 0;\nint ruby_in_longlife_context = Qfalse;\n\ntypedef enum lifetime {\n    lifetime_longlife,\n    lifetime_eden\n} lifetime_t;\n\n#define OBJ_TYPE_COUNT (T_MASK + 1 + NODE_LAST)\n\n#if HAVE_LONG_LONG\n    #define GC_TIME_TYPE LONG_LONG\n#else\n    #define GC_TIME_TYPE long\n#endif\n\nstatic const char lifetime_name[][9] = { \"Longlife\", \"Eden\" };\n\n#ifdef GC_DEBUG\nstatic char *gc_data_file_name;\nstatic char *gc_dump_file_pattern;\nstatic char *backtrace_str_buffer = 0;\nstatic int backtrace_str_buffer_len = 0;\n\nint gc_debug_on = Qfalse;\nstatic int gc_eden_cycles_since_last_longlife = 0;\n\nstatic int gc_debug_summary = 0;\nint gc_debug_dump = 0;\nstatic int gc_debug_longlife_disabled = Qfalse;\nstatic int gc_debug_stress = Qfalse;\nstatic int gc_debug_always_mark = Qfalse;\n\n#define SOURCE_POS_INIT_SIZE 100000\n#define SOURCE_POS_INIT_TMP_SIZE 10000\nstatic st_table *source_positions;\n\nNODE* search_method(VALUE klass, ID id, VALUE *origin);\nstatic const char lifetime_name_lower[][9] = { \"longlife\", \"eden\" };\n#else\n#define gc_debug_stress (0)\n#define gc_debug_always_mark (0)\n#endif\n\n#ifdef GC_DEBUG\n/*\n *  call-seq:\n *    GC.stress                 => true or false\n *\n *  returns current status of GC stress mode.\n */\n\nstatic VALUE\ngc_debug_stress_get(self)\n    VALUE self;\n{\n    return gc_debug_stress;\n}\n\n/*\n *  call-seq:\n *    GC.stress = bool          => bool\n *\n *  updates GC stress mode.\n *\n *  When GC.stress = true, GC is invoked for all GC opportunity:\n *  all memory and object allocation.\n *\n *  Since it makes Ruby very slow, it is only for debugging.\n */\n\nstatic VALUE\ngc_debug_stress_set(self, bool)\n    VALUE self, bool;\n{\n    rb_secure(2);\n    gc_debug_stress = RTEST(bool) ? Qtrue : Qfalse;\n    return gc_debug_stress;\n}\n\n/*\n *  call-seq:\n *     GC.exorcise\n *\n *  Purge ghost references from recently freed stack space\n *\n */\nstatic VALUE gc_exorcise(VALUE mod)\n{\n  rb_gc_wipe_stack();\n  return Qnil;\n}\n#endif\n\nNORETURN(void rb_exc_jump _((VALUE)));\n\n#if defined(HAVE_LONG_LONG)\nstatic unsigned long long allocated_objects = 0;\n#else\nstatic unsigned long allocated_objects = 0;\n#endif\n\nstatic int during_gc = 0;\n\nvoid\nrb_memerror()\n{\n    // If we throw a NoMemoryError, we're no longer doing GC. This will allow\n    // further allocations to occur in the handler for this error. Normally,\n    // it goes unhandled and terminates the VM, but even in that case,\n    // rb_write_error2() will create one new string as part of printing the\n    // error message to stderr. Allowing allocations in NoMemoryError handler\n    // is okay -- by that time some or all of the stack frames were unwound,\n    // so some memory can be realistically allocated again; even a GC can\n    // succeed.\n    during_gc = 0;\n    rb_thread_t th = rb_curr_thread;\n    during_gc = 0;\n    if (!nomem_error ||\n        (rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) {\n        fprintf(stderr, \"[FATAL] failed to allocate memory\\n\");\n        exit(EXIT_FAILURE);\n    }\n    if (rb_thread_raised_p(th, RAISED_NOMEMORY)) {\n        rb_exc_jump(nomem_error);\n    }\n    rb_thread_raised_set(th, RAISED_NOMEMORY);\n    rb_exc_raise(nomem_error);\n}\n\nvoid *\nruby_xmalloc(size)\n    long size;\n{\n    void *mem;\n\n    if (size < 0) {\n        rb_raise(rb_eNoMemError, \"negative allocation size (or too big)\");\n    }\n    if (size == 0) {\n        size = 1;\n    }\n\n    RUBY_CRITICAL(mem = malloc(size));\n    if (!mem) {\n        longlife_collection = Qtrue;\n        garbage_collect(\"OOM in malloc\");\n        RUBY_CRITICAL(mem = malloc(size));\n        if (!mem) {\n            rb_memerror();\n        }\n    }\n\n#if STACK_WIPE_SITES & 0x100\n    rb_gc_update_stack_extent();\n#endif\n    return mem;\n}\n\nvoid *\nruby_xcalloc(n, size)\n    long n, size;\n{\n    void *mem;\n\n    mem = xmalloc(n * size);\n    memset(mem, 0, n * size);\n\n    return mem;\n}\n\nvoid *\nruby_xrealloc(ptr, size)\n    void *ptr;\n    long size;\n{\n    void *mem;\n\n    if (size < 0) {\n        rb_raise(rb_eArgError, \"negative re-allocation size\");\n    }\n    if (!ptr) {\n      return xmalloc(size);\n    }\n    if (size == 0) {\n      size = 1;\n    }\n\n    RUBY_CRITICAL(mem = realloc(ptr, size));\n    if (!mem) {\n        longlife_collection = Qtrue;\n        garbage_collect(\"OOM in realloc()\");\n        RUBY_CRITICAL(mem = realloc(ptr, size));\n        if (!mem) {\n            rb_memerror();\n        }\n    }\n#if STACK_WIPE_SITES & 0x200\n    rb_gc_update_stack_extent();\n#endif\n    return mem;\n}\n\nvoid\nruby_xfree(x)\n    void *x;\n{\n    if (x) {\n        RUBY_CRITICAL(free(x));\n    }\n}\n\nstatic int dont_gc;\nstatic int need_call_final = 0;\nstatic st_table *finalizer_table = 0;\n\n/*******************************************************************/\n\n/*\n *  call-seq:\n *     GC.enable    => true or false\n *\n *  Enables garbage collection, returning <code>true</code> if garbage\n *  collection was previously disabled.\n *\n *     GC.disable   #=> false\n *     GC.enable    #=> true\n *     GC.enable    #=> false\n *\n */\n\nVALUE\nrb_gc_enable()\n{\n    int old = dont_gc;\n\n    dont_gc = Qfalse;\n    return old;\n}\n\n/*\n *  call-seq:\n *     GC.disable    => true or false\n *\n *  Disables garbage collection, returning <code>true</code> if garbage\n *  collection was already disabled.\n *\n *     GC.disable   #=> false\n *     GC.disable   #=> true\n *\n */\n\nVALUE\nrb_gc_disable()\n{\n    int old = dont_gc;\n\n    dont_gc = Qtrue;\n    return old;\n}\n\nVALUE rb_mGC;\n\nstatic struct gc_list {\n    VALUE *varptr;\n    struct gc_list *next;\n} *global_List = 0;\n\nvoid\nrb_gc_register_address(addr)\n    VALUE *addr;\n{\n    struct gc_list *tmp;\n\n    tmp = ALLOC(struct gc_list);\n    tmp->next = global_List;\n    tmp->varptr = addr;\n    global_List = tmp;\n}\n\nvoid\nrb_gc_unregister_address(addr)\n    VALUE *addr;\n{\n    struct gc_list *tmp = global_List;\n\n    if (tmp->varptr == addr) {\n        global_List = tmp->next;\n        RUBY_CRITICAL(free(tmp));\n        return;\n    }\n    while (tmp->next) {\n        if (tmp->next->varptr == addr) {\n            struct gc_list *t = tmp->next;\n\n            tmp->next = tmp->next->next;\n            RUBY_CRITICAL(free(t));\n            break;\n        }\n        tmp = tmp->next;\n    }\n}\n\nvoid\nrb_global_variable(var)\n    VALUE *var;\n{\n    rb_gc_register_address(var);\n}\n\n#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)\n#pragma pack(push, 1) /* magic for reducing sizeof(RVALUE): 24 -> 20 */\n#endif\n\nstatic FILE* gc_data_file = NULL;\n\ntypedef struct RVALUE {\n    union {\n        struct {\n            unsigned long flags;        /* always 0 for freed obj */\n            struct RVALUE *next;\n        } free;\n        struct RBasic  basic;\n        struct RObject object;\n        struct RClass  klass;\n        struct RFloat  flonum;\n        struct RString string;\n        struct RArray  array;\n        struct RRegexp regexp;\n        struct RHash   hash;\n        struct RData   data;\n        struct RStruct rstruct;\n        struct RBignum bignum;\n        struct RFile   file;\n        struct RNode   node;\n        struct RMatch  match;\n        struct RVarmap varmap;\n        struct SCOPE   scope;\n    } as;\n#ifdef GC_DEBUG\n    source_position_t *source_pos;\n#endif\n} RVALUE;\n\n#ifdef GC_DEBUG\nint\ngc_debug_check_printable(char *str)\n{\n    int j, str_len;\n    if (!str) {\n        return 0;\n    }\n    str_len = strlen(str);\n    for (j = 0; j < str_len; j++) {\n        if (!isprint(str[j])) {\n            return 0;\n        }\n    }\n    return 1;\n}\n\nstatic int\nsource_position_compare(source_position_t *x, source_position_t *y)\n{\n    return x->frames_hash != y->frames_hash;\n}\n\nstatic int\nsource_position_hash(source_position_t *x)\n{\n    return x->frames_hash;\n}\n\nstatic struct st_hash_type source_positions_type = {\n    compare: source_position_compare,\n    hash: source_position_hash\n};\n\nchar *\ngc_debug_get_backtrace(source_position_t *source_pos)\n{\n    size_t len;\n    size_t backtrace_len = 0;\n    char line_str[11];\n    char cfunc_str[63];\n    char *func_str;\n\n    /* FIXME Some source_pos aren't correctly marked; thus the guards. */\n    while (source_pos && gc_debug_check_printable(source_pos->file) && source_pos->line > -2 && source_pos->line < 1000000) {\n        if (snprintf(line_str, sizeof(line_str), \"%d\", source_pos->line) > sizeof(line_str)) {\n            rb_bug(\"Overflow on line_str\");\n        }\n\n        func_str = rb_id2name(source_pos->func);\n        if (!func_str) {\n            /* Unknown internal address; can be converted to a function name via atos (OS X) or addr2name (Linux) */\n            if (snprintf(cfunc_str, sizeof(cfunc_str), \"<0x%x>\", (unsigned int) source_pos->func) > sizeof(cfunc_str)) {\n                rb_bug(\"Overflow on cfunc_str\");\n            }\n            func_str = cfunc_str;\n        }\n\n        len = 3 + strlen(source_pos->file) + strlen(line_str) + (func_str ? strlen(func_str) + 1 : 0);\n\n        if (backtrace_str_buffer_len < backtrace_len + len) {\n            backtrace_str_buffer_len = backtrace_len + len;\n            backtrace_str_buffer = realloc(backtrace_str_buffer, backtrace_str_buffer_len);\n            if (!backtrace_str_buffer) {\n                rb_bug(\"OOM on backtrace_str_buffer realloc\");\n            }\n        }\n        snprintf(backtrace_str_buffer + backtrace_len, len,\n            \" %s:%d%s%s\",\n            source_pos->file,\n            source_pos->line,\n            func_str ? \"#\" : \"\",\n            func_str ? func_str : \"\");\n\n        /* gc_debug_check_printable(backtrace_str_buffer); */\n        backtrace_len += len - 1; /* overwrite \\0 on next pass */\n        source_pos = source_pos->parent;\n    }\n    return backtrace_str_buffer;\n}\n\nstatic int\ngc_debug_print_source_locations(source_position_t *source_pos, int *counts, FILE *output_file)\n{\n    int i;\n    char *backtrace_str = 0;\n\n    for(i = 0; i < OBJ_TYPE_COUNT; i++) {\n        if (counts[i] > 0) {\n            if (!backtrace_str) {\n                backtrace_str = gc_debug_get_backtrace(source_pos);\n            }\n            fprintf(output_file, \"%8d %-15s%s\\n\",\n                counts[i],\n                i < T_NODE ? gc_debug_obj_type(i) : gc_debug_node_type(i - T_NODE),\n                backtrace_str);\n        }\n    }\n    free(counts);\n    return ST_CONTINUE;\n}\n\nstatic source_position_t *\ngc_debug_new_source_pos(char *file, int line, struct FRAME *frame)\n{\n    source_position_t *new_source_pos;\n    source_position_t *source_pos;\n    source_position_t *parent;\n    NODE *func_node;\n    ID func = 0;\n\n    new_source_pos = malloc(sizeof(source_position_t));\n    if (!new_source_pos) {\n        rb_bug(\"OOM during source_position_list allocation\");\n    }\n\n    if(frame) {\n        parent = frame->source_pos;\n        if (frame->last_func) {\n            func = frame->last_func;\n        } else if (frame->node) {\n            if (nd_type(frame->node) == NODE_IFUNC) {\n                func = (ID)frame->node->nd_cfnc;\n            } else {\n                func = frame->node->nd_mid;\n            }\n        }\n    }\n    else {\n        parent = 0;\n    }\n    if (!func) {\n        func = ruby_sourcefunc;\n    }\n\n    if(!file && frame) {\n        func_node = search_method(frame->last_class, func, 0);\n        if (func_node && func_node->nd_file) {\n            file = func_node->nd_file;\n        }\n    }\n    if (!file) {\n        file = rb_source_filename(\"(ruby)\");\n    }\n\n    new_source_pos->func = func;\n    new_source_pos->file = file;\n    new_source_pos->line = line;\n    new_source_pos->parent = parent;\n    new_source_pos->frames_hash =\n        (parent ? parent->frames_hash * 31 * 31 * 31 : 0) +\n        (VALUE) file * 31 * 31 +\n        (VALUE) func * 31 +\n        line;\n\n    if (!st_lookup(source_positions, (st_data_t)new_source_pos, (st_data_t *)&source_pos)) {\n        source_pos = new_source_pos;\n        st_insert(source_positions, (st_data_t)(source_pos), (long int) source_pos);\n    } else {\n        free(new_source_pos);\n    }\n    return source_pos;\n}\n\n/**\n  * Creates a source position for a stack frame. It will describe the location\n  * of the call site for the call this frame belongs to.\n  */\nvoid\ngc_debug_get_frame_source_pos(struct FRAME *frame) {\n    char *file = 0;\n    int line = 0;\n\n    if (!(GC_DEBUG_ON && gc_debug_dump)) {\n        return;\n    }\n\n    if (frame->node) {\n        // Location of the call site in the caller\n        file = frame->node->nd_file;\n        line = nd_line(frame->node);\n    }\n\n    frame->source_pos = gc_debug_new_source_pos(file, line, frame->prev);\n}\n\nstatic source_position_t *\ngc_debug_get_obj_source_pos()\n{\n    struct FRAME *frame = ruby_frame;\n    char *file = 0;\n    int line = 0;\n\n    if (frame->last_func == ID_ALLOCATOR) {\n        frame = frame->prev;\n    }\n\n    if (ruby_current_node) {\n        file = ruby_current_node->nd_file;\n        line = nd_line(ruby_current_node);\n    }\n\n    return gc_debug_new_source_pos(file, line, frame);\n}\n\nstatic void\ngc_debug_add_to_source_pos_table(st_table *table, RVALUE *p, int type)\n{\n    int *counts;\n    if (!st_lookup(table, (st_data_t)p->source_pos, (st_data_t *)&counts)) {\n        counts = malloc(sizeof(int) * OBJ_TYPE_COUNT);\n        MEMZERO(counts, int, OBJ_TYPE_COUNT);\n        st_insert(table, (st_data_t)p->source_pos, (long int) counts);\n    }\n\n    if (type == T_NODE) type += nd_type(p);\n    counts[type] +=1;\n}\n\nstatic void\ngc_debug_dump_source_pos_table(st_table *table, lifetime_t lt, char *suffix)\n{\n    char fname[255];\n\n    /* You can parse the output file with simple Unix tools. For example, to\n        see objects that remain on the eden heap after collection, coalesce\n        them by the first 5 backtrace lines, and pretty-print the output, run:\n\n        cat /tmp/rb_gc_debug_objects.eden.live.txt |\n        awk '\n        BEGIN {} { sums[$2,\" \", $3, \" \", $4, \" \", $5, \" \", $6, \" \", $7, \" \", $8] += $1 }\n        END { for (i in sums) { print sums[i], i } }' |\n        sort -rni |\n        head -n 30 |\n        ruby -e \"STDIN.readlines.each {|l| puts l.split}\"\n\n    */\n\n    snprintf(fname, 255, gc_dump_file_pattern, lifetime_name_lower[lt], suffix);\n    FILE* output_file = fopen(fname, \"w\");\n    if (!output_file) {\n        GC_DEBUG_PRINTF(\"ERROR: Can't open %s for writing\\n\", fname);\n        return;\n    }\n    st_foreach(table, gc_debug_print_source_locations, (long int)output_file);\n}\n\n#endif /* GC_DEBUG */\n\n#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)\n#pragma pack(pop)\n#endif\n\nstatic RVALUE *deferred_final_list = 0;\n\nstatic int heaps_increment = 10;\nstatic struct heaps_slot {\n    void *membase;\n    RVALUE *slot;\n    int limit;\n    RVALUE *slotlimit;\n    int *marks;\n    int marks_size;\n    enum lifetime lifetime;\n} *heaps;\nstatic int heaps_length = 0;\nstatic int heaps_used   = 0;\n\n/* Too large a heap size and you can never free a page, due to fragmentation. Too\n    small, and you have too many heaps and get stack errors. */\nstatic int heap_size = 32768;\nstatic int heap_increase_rate = 4;\n\nstatic int eden_heaps = 24;\nstatic int eden_preemptive_heaps = 4;\nstatic int eden_preemptive_total_free_slots;\n\ntypedef struct heaps_space {\n    int num_heaps;\n    unsigned int total_slots;\n    unsigned int total_free_slots;\n    enum lifetime lifetime;\n    RVALUE *freelist;\n} heaps_space_t;\n\nstatic heaps_space_t eden_heaps_space;\nstatic heaps_space_t longlife_heaps_space;\n\ntypedef struct remembered_set {\n    RVALUE *obj;\n    struct remembered_set *next;\n} remembered_set_t;\n\nstatic remembered_set_t *remembered_set_ptr;\nstatic remembered_set_t *remembered_set_freed;\n\ntypedef struct longlife_recent_allocations_set {\n    RVALUE *obj;\n    struct longlife_recent_allocations_set *next;\n} longlife_recent_allocations_set_t;\n\nstatic longlife_recent_allocations_set_t *longlife_recent_allocations_set_ptr;\nstatic longlife_recent_allocations_set_t *longlife_recent_allocations_set_freed;\n\nstatic RVALUE *himem, *lomem;\n\n#include \"marktable.h\"\n#include \"marktable.c\"\n\nstatic int gc_cycles = 0;\nstatic int gc_longlife_cycles = 0;\n\nstatic void set_gc_parameters()\n{\n\n#define WITH_ENV_VAR(varname, variable, type, conv, cond, fmt) \\\n    do { \\\n        char* ptr = getenv(varname); \\\n        type val = variable; \\\n        char* __varname__ = varname; \\\n        char* __fmt__ = fmt; \\\n        if(ptr != NULL) { \\\n            val = conv(ptr); \\\n            if(cond) {\n#define END_WITH_ENV_VAR } } if (gc_data_file) { GC_DEBUG_PRINTF(__fmt__, __varname__, val) } } while(0);\n\n#define WITH_INT_ENV_VAR(varname, variable) WITH_ENV_VAR(varname, variable, int, atoi, val > 0, \"%s=%d\\n\")\n#define WITH_FLOAT_ENV_VAR(varname, variable) WITH_ENV_VAR(varname, variable, double, atof, val > 0, \"%s=%f\\n\")\n\n#define SET_INT_ENV_VAR(varname, variable) WITH_INT_ENV_VAR(varname, variable) variable = val; END_WITH_ENV_VAR\n#define SET_FLOAT_ENV_VAR(varname, variable) WITH_FLOAT_ENV_VAR(varname, variable) variable = val; END_WITH_ENV_VAR\n#define SET_BOOLEAN_ENV_VAR(varname, variable) WITH_INT_ENV_VAR(varname, variable) variable = Qtrue; END_WITH_ENV_VAR\n\n#ifdef GC_DEBUG\n    SET_BOOLEAN_ENV_VAR(\"RUBY_GC_DEBUG\", gc_debug_on)\n    if (gc_debug_on) {\n      gc_data_file_name = getenv(\"RUBY_GC_DATA_FILE\");\n      if (gc_data_file_name == NULL) {\n        gc_data_file_name = \"/dev/stderr\";\n      }\n      FILE* data_file = fopen(gc_data_file_name, \"w\");\n      if (data_file != NULL) {\n          gc_data_file = data_file;\n          // stderr is always unbuffered. user-specified files should be likewise\n          setbuf(gc_data_file, NULL);\n      } else {\n          fprintf(stderr, \"Can't open RUBY_GC_DATA_FILE for writing\\n\");\n          gc_data_file_name = \"/dev/stderr\";\n          gc_data_file = fopen(gc_data_file_name, \"w\");\n      }\n    }\n\n    gc_dump_file_pattern = getenv(\"RUBY_GC_DUMP_FILE_PATTERN\");\n    if(gc_dump_file_pattern == NULL) {\n        gc_dump_file_pattern = \"/tmp/rb_gc_debug_objects.%s.%s.txt\";\n    }\n#endif\n\n    SET_INT_ENV_VAR(\"RUBY_GC_HEAP_SIZE\", heap_size)\n    SET_INT_ENV_VAR(\"RUBY_GC_HEAP_INCREASE_RATE\", heap_increase_rate)\n    SET_INT_ENV_VAR(\"RUBY_GC_EDEN_HEAPS\", eden_heaps)\n    SET_INT_ENV_VAR(\"RUBY_GC_EDEN_PREEMPTIVE_HEAPS\", eden_preemptive_heaps)\n\n    eden_preemptive_total_free_slots = eden_preemptive_heaps * heap_size;\n\n    WITH_FLOAT_ENV_VAR(\"RUBY_GC_LONGLIFE_LAZINESS\", longlife_laziness)\n        if (val >= 1) {\n          val = DEFAULT_LONGLIFE_LAZINESS;\n        }\n        longlife_laziness = val;\n    END_WITH_ENV_VAR\n\n#ifdef GC_DEBUG\n    GC_DEBUG_PRINT(\"GC_DEBUG is available\\n\")\n    SET_BOOLEAN_ENV_VAR(\"RUBY_GC_DEBUG_LONGLIFE_DISABLE\", gc_debug_longlife_disabled)\n    SET_BOOLEAN_ENV_VAR(\"RUBY_GC_DEBUG_STRESS\", gc_debug_stress)\n    SET_BOOLEAN_ENV_VAR(\"RUBY_GC_DEBUG_ALWAYS_MARK\", gc_debug_always_mark)\n    if (GC_DEBUG_ON) {\n        SET_BOOLEAN_ENV_VAR(\"RUBY_GC_DEBUG_SUMMARY\", gc_debug_summary)\n        SET_BOOLEAN_ENV_VAR(\"RUBY_GC_DEBUG_DUMP\", gc_debug_dump)\n    }\n#else\n    GC_DEBUG_PRINT(\"GC_DEBUG not available (configure with --enable-gc-debug)\\n\")\n#endif\n}\n\n/*\n *  call-seq:\n *     GC.log String  => String\n *\n *  Logs string to the GC data file and returns it.\n *\n *     GC.log \"manual GC call\"    #=> \"manual GC call\"\n *\n */\n\nVALUE\nrb_gc_log(self, original_str)\n     VALUE self, original_str;\n{\n    if (original_str == Qnil) {\n        fprintf(gc_data_file, \"\\n\");\n    }\n    else {\n        VALUE str = StringValue(original_str);\n        char *p = RSTRING(str)->ptr;\n        fprintf(gc_data_file, \"%s\\n\", p);\n    }\n    return original_str;\n}\n\n\nstatic inline void push_freelist(heaps_space_t *heaps_space, RVALUE *p)\n{\n    MEMZERO((void*)p, RVALUE, 1);\n    p->as.free.next = heaps_space->freelist;\n    heaps_space->freelist = p;\n}\n\nstatic int\nadd_heap(heaps_space_t *heaps_space)\n{\n    RVALUE *p, *pend;\n    int new_heap_size = heap_size;\n\n    if (heaps_used == heaps_length) {\n        /* Realloc heaps */\n        struct heaps_slot *p;\n        int length;\n\n        heaps_length += heaps_increment;\n        length = heaps_length*sizeof(struct heaps_slot);\n        RUBY_CRITICAL(\n            if (heaps_used > 0) {\n                p = (struct heaps_slot *)realloc(heaps, length);\n                if (p) {\n                  heaps = p;\n                  /* Clear the last_heap cache to remove potentially erroneous references. */\n                  rb_mark_table_prepare();\n                }\n            }\n            else {\n                p = heaps = (struct heaps_slot *)malloc(length);\n            });\n        if (p == 0) {\n          rb_memerror();\n        }\n    }\n\n    for (;;) {\n        RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(new_heap_size)));\n        if (p == 0) {\n          rb_memerror();\n        }\n        heaps[heaps_used].membase = p;\n\n        // Align heap pointer to RVALUE size, if necessary\n        if ((VALUE)p % sizeof(RVALUE) != 0) {\n            p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE)));\n            new_heap_size--;\n        }\n\n        heaps[heaps_used].slot = p;\n        heaps[heaps_used].limit = new_heap_size;\n        heaps[heaps_used].slotlimit = p + new_heap_size;\n        heaps[heaps_used].marks_size = (int) (ceil(new_heap_size / (sizeof(int) * 8.0)));\n        heaps[heaps_used].marks = (int *) calloc(heaps[heaps_used].marks_size, sizeof(int));\n        heaps[heaps_used].lifetime = heaps_space->lifetime;\n        break;\n    }\n    pend = p + new_heap_size;\n    if (lomem == 0 || lomem > p) {\n      lomem = p;\n    }\n    if (himem < pend) {\n      himem = pend;\n    }\n    heaps_space->total_slots += new_heap_size;\n    heaps_space->total_free_slots += new_heap_size;\n    heaps_space->num_heaps++;\n    heaps_used++;\n\n    /* Add to freelist in reverse order. */\n    while (pend > p) {\n        pend--;\n        push_freelist(heaps_space, pend);\n    }\n\n    return new_heap_size;\n}\n\n#define RANY(o) ((RVALUE*)(o))\n\nint\nrb_during_gc()\n{\n    return during_gc;\n}\n\nstatic inline VALUE\npop_freelist(heaps_space_t* heaps_space)\n{\n    VALUE obj = (VALUE)heaps_space->freelist;\n    heaps_space->freelist = heaps_space->freelist->as.free.next;\n    heaps_space->total_free_slots--;\n    RANY(obj)->as.free.next = 0;\n#ifdef GC_DEBUG\n    MEMZERO((void*)obj, RVALUE, 1);\n    if (GC_DEBUG_ON && gc_debug_dump) {\n        RANY(obj)->source_pos = gc_debug_get_obj_source_pos();\n    }\n#endif\n    return obj;\n}\n\nstatic inline void\nadd_heap_if_needed(heaps_space_t* heaps_space)\n{\n    int new_heap_size;\n    if (!heaps_space->freelist) {\n        new_heap_size = add_heap(heaps_space);\n        GC_DEBUG_PRINTF(\"*** %s heap added (out of space) (size %d) ***\\n\",\n          lifetime_name[heaps_space->lifetime], new_heap_size)\n    }\n}\n\n/* Legacy gem compatibility only. Do not use. */\nVALUE\nrb_newobj() {\n    return rb_newobj_eden();\n}\n\nVALUE\nrb_newobj_eden()\n{\n    VALUE obj;\n\n#ifdef GC_DEBUG\n    if (during_gc) {\n        rb_bug(\"object allocation during garbage collection phase\");\n    }\n    if (gc_debug_stress) {\n        longlife_collection = Qtrue;\n        garbage_collect(\"GC stress is enabled\");\n    }\n#endif\n    if (!eden_heaps_space.freelist) {\n      garbage_collect(\"no free space in the eden\");\n    }\n\n    add_heap_if_needed(&eden_heaps_space);\n    obj = pop_freelist(&eden_heaps_space);\n\n    allocated_objects++;\n    return obj;\n}\n\nVALUE\nrb_newobj_longlife()\n{\n    VALUE obj;\n\n#ifdef GC_DEBUG\n    if (gc_debug_longlife_disabled) {\n        return rb_newobj_eden();\n    }\n    if (during_gc) {\n        rb_bug(\"object allocation during garbage collection phase\");\n    }\n    if (gc_debug_stress) {\n        longlife_collection = Qtrue;\n        garbage_collect(\"GC stress is enabled\");\n    }\n#endif\n    if (!longlife_heaps_space.freelist) {\n        longlife_collection = Qtrue;\n        garbage_collect(\"no free space in the longlife\");\n    }\n\n    add_heap_if_needed(&longlife_heaps_space);\n    obj = pop_freelist(&longlife_heaps_space);\n    RBASIC(obj)->flags |= (FL_LONGLIFE|FL_MOVE);\n\n    add_to_longlife_recent_allocations(obj);\n\n    allocated_objects++;\n    return obj;\n}\n\nVALUE\nrb_data_object_alloc(klass, datap, dmark, dfree)\n    VALUE klass;\n    void *datap;\n    RUBY_DATA_FUNC dmark;\n    RUBY_DATA_FUNC dfree;\n{\n    NEWOBJ(data, struct RData);\n    if (klass) {\n      Check_Type(klass, T_CLASS);\n    }\n    OBJSETUP(data, klass, T_DATA);\n    data->data = datap;\n    data->dfree = dfree;\n    data->dmark = dmark;\n\n    return (VALUE)data;\n}\n\nextern st_table *rb_class_tbl;\nVALUE *rb_gc_stack_start = 0;\n#ifdef __ia64\nVALUE *rb_gc_register_stack_start = 0;\n#endif\n\n\n#ifdef DJGPP\n/* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */\nunsigned int _stklen = 0x180000; /* 1.5 kB */\n#endif\n\n#if defined(DJGPP) || defined(_WIN32_WCE)\nstatic unsigned int STACK_LEVEL_MAX = 65535;\n#elif defined(__human68k__)\nunsigned int _stacksize = 262144;\n# define STACK_LEVEL_MAX (_stacksize - 4096)\n# undef HAVE_GETRLIMIT\n#elif defined(HAVE_GETRLIMIT) || defined(_WIN32)\nstatic size_t STACK_LEVEL_MAX = 655300;\n#else\n# define STACK_LEVEL_MAX 655300\n#endif\n\n#ifndef nativeAllocA\n  /* portable way to return an approximate stack pointer */\nNOINLINE(VALUE *__sp(void));\nVALUE *__sp(void) {\n  VALUE tos;\n  return &tos;\n}\n# define SET_STACK_END VALUE stack_end\n# define STACK_END (&stack_end)\n#else\n# define SET_STACK_END ((void)0)\n# define STACK_END __sp()\n#endif\n\n#if STACK_GROW_DIRECTION < 0\n# define STACK_LENGTH(start)  ((start) - STACK_END)\n#elif STACK_GROW_DIRECTION > 0\n# define STACK_LENGTH(start)  (STACK_END - (start) + 1)\n#else\n# define STACK_LENGTH(start)  ((STACK_END < (start)) ? (start) - STACK_END\\\n                                           : STACK_END - (start) + 1)\n#endif\n#if STACK_GROW_DIRECTION > 0\n# define STACK_UPPER(a, b) a\n#elif STACK_GROW_DIRECTION < 0\n# define STACK_UPPER(a, b) b\n#else\nint rb_gc_stack_grow_direction;\nstatic int\nstack_grow_direction(addr)\n    VALUE *addr;\n{\n    SET_STACK_END;\n    return rb_gc_stack_grow_direction = STACK_END > addr ? 1 : -1;\n}\n# define STACK_UPPER(a, b) (rb_gc_stack_grow_direction > 0 ? a : b)\n#endif\n\nsize_t\nruby_stack_length(base)\n    VALUE **base;\n{\n    SET_STACK_END;\n    VALUE *start;\n    if (rb_curr_thread == rb_main_thread) {\n        start = rb_gc_stack_start;\n    } else {\n        start = rb_curr_thread->stk_base;\n    }\n    if (base) {\n      *base = STACK_UPPER(start, STACK_END);\n    }\n    return STACK_LENGTH(start);\n}\n\nint\nruby_stack_check()\n{\n    SET_STACK_END;\n    if (!rb_main_thread || rb_curr_thread == rb_main_thread) {\n        return __stack_past(stack_limit, STACK_END);\n    } else {\n        /* ruby_stack_check() is only called periodically, but we want to\n         * detect a stack overflow before the thread's guard area is accessed.\n         * So we append a '+ getpagesize()' to the address check.\n         *\n         * TODO: support architectures on which the stack grows upwards.\n         */\n        return __stack_past(rb_curr_thread->guard + getpagesize(), STACK_END);\n    }\n}\n\n/*\n  Zero memory that was (recently) part of the stack, but is no longer.\n  Invoke when stack is deep to mark its extent and when it's shallow to wipe it.\n*/\n#if STACK_WIPE_METHOD != 4\n#if STACK_WIPE_METHOD\nvoid rb_gc_wipe_stack(void)\n{\n  if (rb_curr_thread) {\n    VALUE *stack_end = rb_curr_thread->gc_stack_end;\n    VALUE *sp = __sp();\n    rb_curr_thread->gc_stack_end = sp;\n#if STACK_WIPE_METHOD == 1\n#warning clearing of \"ghost references\" from the call stack has been disabled\n#elif STACK_WIPE_METHOD == 2  /* alloca ghost stack before clearing it */\n    if (__stack_past(sp, stack_end)) {\n      size_t bytes = __stack_depth((char *)stack_end, (char *)sp);\n      STACK_UPPER(sp = nativeAllocA(bytes), stack_end = nativeAllocA(bytes));\n      __stack_zero(stack_end, sp);\n    }\n#elif STACK_WIPE_METHOD == 3    /* clear unallocated area past stack pointer */\n    __stack_zero(stack_end, sp);  /* will crash if compiler pushes a temp. here */\n#else\n#error unsupported method of clearing ghost references from the stack\n#endif\n  }\n}\n#else\n#warning clearing of \"ghost references\" from the call stack completely disabled\n#endif\n#endif\n\n#define MARK_STACK_MAX 1024\nstatic VALUE mark_stack[MARK_STACK_MAX];\nstatic VALUE *mark_stack_ptr;\nstatic int mark_stack_overflow;\n\nstatic void\ninit_mark_stack()\n{\n    mark_stack_overflow = 0;\n    mark_stack_ptr = mark_stack;\n}\n\n#define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack)\n\nstatic inline void\npush_mark_stack(VALUE ptr)\n{\n    if (!mark_stack_overflow) {\n        if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {\n            *mark_stack_ptr++ = ptr;\n        } else {\n            mark_stack_overflow = 1;\n        }\n    }\n}\n\nstatic st_table *source_filenames;\n\nvoid\nInit_source_filenames()\n{\n    source_filenames = st_init_strtable();\n}\n\nchar *\nrb_source_filename(f)\n    const char *f;\n{\n    st_data_t name;\n\n    if (!st_lookup(source_filenames, (st_data_t)f, &name)) {\n        long len = strlen(f) + 1;\n        char *ptr = ALLOC_N(char, len + 1);\n        name = (st_data_t)ptr;\n        *ptr++ = 0;\n        MEMCPY(ptr, f, char, len);\n        st_add_direct(source_filenames, (st_data_t)ptr, name);\n        return ptr;\n    }\n    return (char *)name + 1;\n}\n\nstatic void\nmark_source_filename(f)\n    char *f;\n{\n    if (f) {\n        rb_mark_table_add_filename(f);\n    }\n}\n\nstatic int\nsweep_source_filename(key, value)\n    char *key, *value;\n{\n    if (rb_mark_table_contains_filename(value + 1)) {\n        rb_mark_table_remove_filename(value + 1);\n        return ST_CONTINUE;\n    }\n    else {\n        rb_mark_table_remove_filename(value + 1);\n        free(value);\n        return ST_DELETE;\n    }\n}\n\n#ifdef GC_DEBUG\nvoid\nInit_source_positions()\n{\n    source_positions = st_init_table_with_size(&source_positions_type, SOURCE_POS_INIT_SIZE);\n}\n\nstatic void\nmark_source_pos(source_position_t *source_pos)\n{\n    if (GC_DEBUG_ON && gc_debug_dump && longlife_collection && source_pos) {\n        if (!rb_mark_table_contains_source_pos(source_pos)) {\n            rb_mark_table_add_source_pos(source_pos);\n            mark_source_filename(source_pos->file);\n            mark_source_pos(source_pos->parent);\n        }\n    }\n}\n\nstatic int\nsweep_source_pos(char *key, source_position_t *source_pos)\n{\n    if (rb_mark_table_contains_source_pos(source_pos)) {\n        rb_mark_table_remove_source_pos(source_pos);\n        return ST_CONTINUE;\n    }\n    else {\n        rb_mark_table_remove_source_pos(source_pos);\n        st_delete(source_positions, (st_data_t *)source_pos, 0);\n        free(source_pos);\n        return ST_DELETE;\n    }\n}\n#endif\n\nstatic void gc_mark_children _((VALUE ptr));\n\nstatic void\ngc_mark_all()\n{\n    RVALUE *p, *pend;\n    struct heaps_slot *heap = heaps+heaps_used;\n\n    init_mark_stack();\n    while (--heap >= heaps) {\n        p = heap->slot; pend = p + heap->limit;\n        while (p < pend) {\n            if (rb_mark_table_heap_contains(heap, p) &&\n                BUILTIN_TYPE(p) != T_DEFERRED) {\n                gc_mark_children((VALUE)p);\n            }\n            p++;\n        }\n    }\n}\n\nstatic void\ngc_mark_rest()\n{\n    size_t stackLen = mark_stack_ptr - mark_stack;\n#ifdef nativeAllocA\n    VALUE *tmp_arry = nativeAllocA(stackLen*sizeof(VALUE));\n#else\n    VALUE tmp_arry[MARK_STACK_MAX];\n#endif\n    VALUE *p = tmp_arry + stackLen;\n\n    MEMCPY(tmp_arry, mark_stack, VALUE, stackLen);\n\n    init_mark_stack();\n    while(--p >= tmp_arry) gc_mark_children(*p);\n}\n\nstatic inline int\nis_pointer_to_heap(ptr)\n    void *ptr;\n{\n    RVALUE *p = RANY(ptr);\n    struct heaps_slot *heap;\n\n    if (p < lomem || p > himem || (VALUE)p % sizeof(RVALUE)) {\n      return Qfalse;\n    }\n\n    /* check if p looks like a pointer */\n    heap = heaps+heaps_used;\n    while (--heap >= heaps) {\n        if (p >= heap->slot && p < heap->slot + heap->limit) {\n            return Qtrue;\n        }\n    }\n    return Qfalse;\n}\n\nstatic inline int\nis_pointer_to_longlife_heap(ptr)\n    void *ptr;\n{\n    RVALUE *p = RANY(ptr);\n    struct heaps_slot *heap;\n\n    if (p < lomem || p > himem || (VALUE)p % sizeof(RVALUE)) {\n        return Qfalse;\n    }\n\n    /* check if p looks like a pointer */\n    heap = heaps+heaps_used;\n    while (--heap >= heaps) {\n        if (p >= heap->slot && p < heap->slot + heap->limit && heap->lifetime == lifetime_longlife) {\n            return Qtrue;\n        }\n    }\n    return Qfalse;\n}\n\nstatic void\nadd_to_longlife_recent_allocations(VALUE ptr)\n{\n    longlife_recent_allocations_set_t *tmp;\n    if (longlife_recent_allocations_set_freed) {\n        tmp = longlife_recent_allocations_set_freed;\n        longlife_recent_allocations_set_freed = longlife_recent_allocations_set_freed->next;\n    }\n    else {\n        tmp = ALLOC(longlife_recent_allocations_set_t);\n    }\n    tmp->next = longlife_recent_allocations_set_ptr;\n    tmp->obj = (RVALUE *)ptr;\n    longlife_recent_allocations_set_ptr = tmp;\n}\n\n/* Call this if you mutate an object that might be on the longlife heap. */\nvoid\nmaybe_add_to_longlife_recent_allocations(VALUE ptr)\n{\n    if (ptr && OBJ_LONGLIVED(ptr)) {\n        add_to_longlife_recent_allocations(ptr);\n    }\n}\n\nstatic VALUE\nrb_gc_write_barrier(VALUE ptr)\n{\n    RVALUE *obj = RANY(ptr);\n\n    if (ptr && !SPECIAL_CONST_P(ptr) && obj->as.basic.flags && !(RBASIC(ptr)->flags & (FL_REMEMBERED_SET|FL_LONGLIFE))) {\n        remembered_set_t *tmp;\n        if (remembered_set_freed) {\n            tmp = remembered_set_freed;\n            remembered_set_freed = remembered_set_freed->next;\n        }\n        else {\n            tmp = ALLOC(remembered_set_t);\n        }\n        tmp->next = remembered_set_ptr;\n        tmp->obj = obj;\n        obj->as.basic.flags |= FL_REMEMBERED_SET;\n        remembered_set_ptr = tmp;\n    }\n    return ptr;\n}\n\nstatic void\nmark_locations_array(x, n)\n    VALUE *x;\n    size_t n;\n{\n    VALUE v;\n    while (n--) {\n        v = *x;\n        if (is_pointer_to_heap((void *)v)) {\n            rb_gc_mark(v);\n        }\n        x++;\n    }\n}\n\ninline void\nrb_gc_mark_locations(start, end)\n    VALUE *start, *end;\n{\n    mark_locations_array(start,end - start);\n}\n\nstatic int\nmark_entry(key, value)\n    ID key;\n    VALUE value;\n{\n    rb_gc_mark(value);\n    return ST_CONTINUE;\n}\n\nvoid\nrb_mark_tbl(tbl)\n    st_table *tbl;\n{\n    if (!tbl) return;\n    st_foreach(tbl, mark_entry, 0);\n}\n#define mark_tbl(tbl)  rb_mark_tbl(tbl)\n\nstatic int\nmark_keyvalue(key, value)\n    VALUE key;\n    VALUE value;\n{\n    rb_gc_mark(key);\n    rb_gc_mark(value);\n    return ST_CONTINUE;\n}\n\nstatic int\nmark_key(key, value)\n    VALUE key, value;\n{\n    rb_gc_mark(key);\n    return ST_CONTINUE;\n}\n\nvoid\nrb_mark_set(tbl)\n    st_table *tbl;\n{\n    if (!tbl) return;\n    st_foreach(tbl, mark_key, 0);\n}\n#define mark_set(tbl)  rb_mark_set(tbl)\n\nvoid\nrb_mark_hash(tbl)\n    st_table *tbl;\n{\n    if (!tbl) return;\n    st_foreach(tbl, mark_keyvalue, 0);\n}\n#define mark_hash(tbl)  rb_mark_hash(tbl)\n\nvoid\nrb_gc_mark_maybe(obj)\n    VALUE obj;\n{\n    if (is_pointer_to_heap((void *)obj)) {\n        rb_gc_mark(obj);\n    }\n}\n\nvoid\nrb_gc_mark(ptr)\n    VALUE ptr;\n{\n    RVALUE *obj = RANY(ptr);\n    SET_STACK_END;\n\n    if (rb_special_const_p(ptr)) return; /* special const not marked */\n    if (obj->as.basic.flags == 0) return;       /* free cell */\n    if (rb_mark_table_contains(obj)) return;  /* already marked */\n\n    rb_mark_table_add(obj);\n#ifdef GC_DEBUG\n    mark_source_pos(obj->source_pos);\n#endif\n\n    if (__stack_past(gc_stack_limit, STACK_END))\n      push_mark_stack(ptr);\n    else{\n      gc_mark_children(ptr);\n    }\n}\n\nstatic void\ngc_mark_children(ptr)\n    VALUE ptr;\n{\n    RVALUE *obj = RANY(ptr);\n\n    goto marking;               /* skip */\n\n  again:\n    obj = RANY(ptr);\n    if (rb_special_const_p(ptr)) return; /* special const not marked */\n    if (obj->as.basic.flags == 0) return;       /* free cell */\n    if (!(longlife_collection || gc_debug_always_mark) && OBJ_LONGLIVED(obj)) return; /* ref from normal to longlife */\n    if (rb_mark_table_contains(obj)) return;  /* already marked */\n\n    rb_mark_table_add(obj);\n#ifdef GC_DEBUG\n    mark_source_pos(obj->source_pos);\n#endif\n\n  marking:\n    if (FL_TEST(obj, FL_EXIVAR)) {\n        rb_mark_generic_ivar(ptr);\n    }\n\n    switch (obj->as.basic.flags & T_MASK) {\n      case T_NIL:\n      case T_FIXNUM:\n        rb_bug(\"rb_gc_mark() called for broken object\");\n        break;\n\n      case T_NODE:\n        if (longlife_collection) {\n            mark_source_filename(obj->as.node.nd_file);\n        }\n        switch (nd_type(obj)) {\n          case NODE_IF:         /* 1,2,3 */\n          case NODE_FOR:\n          case NODE_ITER:\n          case NODE_CREF:\n          case NODE_WHEN:\n          case NODE_MASGN:\n          case NODE_RESCUE:\n          case NODE_RESBODY:\n          case NODE_CLASS:\n            rb_gc_mark((VALUE)obj->as.node.u2.node);\n            /* fall through */\n          case NODE_BLOCK:      /* 1,3 */\n          case NODE_ARRAY:\n          case NODE_DSTR:\n          case NODE_DXSTR:\n          case NODE_DREGX:\n          case NODE_DREGX_ONCE:\n          case NODE_FBODY:\n          case NODE_ENSURE:\n          case NODE_CALL:\n          case NODE_DEFS:\n          case NODE_OP_ASGN1:\n            rb_gc_mark((VALUE)obj->as.node.u1.node);\n            /* fall through */\n          case NODE_SUPER:      /* 3 */\n          case NODE_FCALL:\n          case NODE_DEFN:\n          case NODE_NEWLINE:\n            ptr = (VALUE)obj->as.node.u3.node;\n            goto again;\n\n          case NODE_WHILE:      /* 1,2 */\n          case NODE_UNTIL:\n          case NODE_AND:\n          case NODE_OR:\n          case NODE_CASE:\n          case NODE_SCLASS:\n          case NODE_DOT2:\n          case NODE_DOT3:\n          case NODE_FLIP2:\n          case NODE_FLIP3:\n          case NODE_MATCH2:\n          case NODE_MATCH3:\n          case NODE_OP_ASGN_OR:\n          case NODE_OP_ASGN_AND:\n          case NODE_MODULE:\n          case NODE_ALIAS:\n          case NODE_VALIAS:\n          case NODE_ARGS:\n            rb_gc_mark((VALUE)obj->as.node.u1.node);\n            /* fall through */\n          case NODE_METHOD:     /* 2 */\n          case NODE_NOT:\n          case NODE_GASGN:\n          case NODE_LASGN:\n          case NODE_DASGN:\n          case NODE_DASGN_CURR:\n          case NODE_IASGN:\n          case NODE_CVDECL:\n          case NODE_CVASGN:\n          case NODE_COLON3:\n          case NODE_OPT_N:\n          case NODE_EVSTR:\n          case NODE_UNDEF:\n            ptr = (VALUE)obj->as.node.u2.node;\n            goto again;\n\n          case NODE_HASH:       /* 1 */\n          case NODE_LIT:\n          case NODE_STR:\n          case NODE_XSTR:\n          case NODE_DEFINED:\n          case NODE_MATCH:\n          case NODE_RETURN:\n          case NODE_BREAK:\n          case NODE_NEXT:\n          case NODE_YIELD:\n          case NODE_COLON2:\n          case NODE_SPLAT:\n          case NODE_TO_ARY:\n          case NODE_SVALUE:\n            ptr = (VALUE)obj->as.node.u1.node;\n            goto again;\n\n          case NODE_SCOPE:      /* 2,3 */\n          case NODE_BLOCK_PASS:\n          case NODE_CDECL:\n            rb_gc_mark((VALUE)obj->as.node.u3.node);\n            ptr = (VALUE)obj->as.node.u2.node;\n            goto again;\n\n          case NODE_ZARRAY:     /* - */\n          case NODE_ZSUPER:\n          case NODE_CFUNC:\n          case NODE_VCALL:\n          case NODE_GVAR:\n          case NODE_LVAR:\n          case NODE_DVAR:\n          case NODE_IVAR:\n          case NODE_CVAR:\n          case NODE_NTH_REF:\n          case NODE_BACK_REF:\n          case NODE_REDO:\n          case NODE_RETRY:\n          case NODE_SELF:\n          case NODE_NIL:\n          case NODE_TRUE:\n          case NODE_FALSE:\n          case NODE_ATTRSET:\n          case NODE_BLOCK_ARG:\n          case NODE_POSTEXE:\n            break;\n          case NODE_ALLOCA:\n            mark_locations_array((VALUE*)obj->as.node.u1.value,\n                                 obj->as.node.u3.cnt);\n            ptr = (VALUE)obj->as.node.u2.node;\n            goto again;\n\n          default:              /* unlisted NODE */\n            if (is_pointer_to_heap(obj->as.node.u1.node)) {\n                rb_gc_mark((VALUE)obj->as.node.u1.node);\n            }\n            if (is_pointer_to_heap(obj->as.node.u2.node)) {\n                rb_gc_mark((VALUE)obj->as.node.u2.node);\n            }\n            if (is_pointer_to_heap(obj->as.node.u3.node)) {\n                ptr = (VALUE)obj->as.node.u3.node;\n                goto again;\n            }\n        }\n        return; /* no need to mark class. */\n    }\n\n    rb_gc_mark(obj->as.basic.klass);\n    switch (obj->as.basic.flags & T_MASK) {\n      case T_ICLASS:\n      case T_CLASS:\n      case T_MODULE:\n        mark_tbl(obj->as.klass.m_tbl);\n        mark_tbl(obj->as.klass.iv_tbl);\n        ptr = obj->as.klass.super;\n        goto again;\n\n      case T_ARRAY:\n        if (FL_TEST(obj, ELTS_SHARED)) {\n            ptr = obj->as.array.aux.shared;\n            goto again;\n        }\n        else {\n            VALUE *ptr = obj->as.array.ptr;\n            VALUE *pend = ptr + obj->as.array.len;\n            while (ptr < pend) {\n                rb_gc_mark(*ptr++);\n            }\n        }\n        break;\n\n      case T_HASH:\n        mark_hash(obj->as.hash.tbl);\n        ptr = obj->as.hash.ifnone;\n        goto again;\n\n      case T_STRING:\n#define STR_ASSOC FL_USER3   /* copied from string.c */\n        if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) {\n            ptr = obj->as.string.aux.shared;\n            goto again;\n        }\n        break;\n\n      case T_DATA:\n        if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj));\n        break;\n\n      case T_OBJECT:\n        mark_tbl(obj->as.object.iv_tbl);\n        break;\n\n      case T_FILE:\n      case T_REGEXP:\n      case T_FLOAT:\n      case T_BIGNUM:\n      case T_BLKTAG:\n        break;\n\n      case T_MATCH:\n        if (obj->as.match.str) {\n            ptr = obj->as.match.str;\n            goto again;\n        }\n        break;\n\n      case T_VARMAP:\n        rb_gc_mark(obj->as.varmap.val);\n        ptr = (VALUE)obj->as.varmap.next;\n        goto again;\n\n      case T_SCOPE:\n        if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) {\n            int n = obj->as.scope.local_tbl[0]+1;\n            VALUE *vars = &obj->as.scope.local_vars[-1];\n\n            while (n--) {\n                rb_gc_mark(*vars++);\n            }\n        }\n        break;\n\n      case T_STRUCT:\n        {\n            VALUE *ptr = obj->as.rstruct.ptr;\n            VALUE *pend = ptr + obj->as.rstruct.len;\n            while (ptr < pend)\n               rb_gc_mark(*ptr++);\n        }\n        break;\n\n      default:\n        rb_bug(\"rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s\",\n               obj->as.basic.flags & T_MASK, obj,\n               is_pointer_to_heap(obj) ? \"corrupted object\" : \"non object\");\n    }\n}\n\nstatic int obj_free _((VALUE));\n\nstatic void add_to_correct_freelist(RVALUE *p)\n{\n    heaps_space_t *heaps_space;\n\n    // Has explicit longlife flag\n    if(OBJ_LONGLIVED(p)) {\n        heaps_space = &longlife_heaps_space;\n    }\n    // Has some flags (so they weren't cleared), but not longlife\n    else if(p->as.free.flags != 0) {\n        heaps_space = &eden_heaps_space;\n    }\n    // If all else fails, use slower is_pointer_to_longlife_heap()\n    else if (is_pointer_to_longlife_heap(p)) {\n        heaps_space = &longlife_heaps_space;\n    } else {\n        heaps_space = &eden_heaps_space;\n    }\n\n    push_freelist(heaps_space, p);\n    heaps_space->total_free_slots++;\n}\n\nstatic void\nfinalize_list(p)\n    RVALUE *p;\n{\n    while (p) {\n        RVALUE *tmp = p->as.free.next;\n        run_final((VALUE)p);\n        /* Don't free objects that are singletons, or objects that are already freed.\n         * The latter is to prevent the unnecessary marking of memory pages as dirty,\n         * which can destroy copy-on-write semantics.\n         */\n        if (!FL_TEST(p, FL_SINGLETON)) {\n            rb_mark_table_remove(p);\n            add_to_correct_freelist(p);\n        }\n        p = tmp;\n    }\n}\n\n#define CONST_TO_NAME(x) case x: return #x;\n\nchar* gc_debug_obj_type(int tp)\n{\n    switch (tp) {\n        CONST_TO_NAME(T_NIL)\n        CONST_TO_NAME(T_OBJECT)\n        CONST_TO_NAME(T_CLASS)\n        CONST_TO_NAME(T_ICLASS)\n        CONST_TO_NAME(T_MODULE)\n        CONST_TO_NAME(T_FLOAT)\n        CONST_TO_NAME(T_STRING)\n        CONST_TO_NAME(T_REGEXP)\n        CONST_TO_NAME(T_ARRAY)\n        CONST_TO_NAME(T_FIXNUM)\n        CONST_TO_NAME(T_HASH)\n        CONST_TO_NAME(T_STRUCT)\n        CONST_TO_NAME(T_BIGNUM)\n        CONST_TO_NAME(T_FILE)\n\n        CONST_TO_NAME(T_TRUE)\n        CONST_TO_NAME(T_FALSE)\n        CONST_TO_NAME(T_DATA)\n        CONST_TO_NAME(T_MATCH)\n        CONST_TO_NAME(T_SYMBOL)\n\n        CONST_TO_NAME(T_BLKTAG)\n        CONST_TO_NAME(T_UNDEF)\n        CONST_TO_NAME(T_VARMAP)\n        CONST_TO_NAME(T_SCOPE)\n        CONST_TO_NAME(T_NODE)\n        default: return \"____\";\n    }\n}\n\nchar* gc_debug_node_type(int tp)\n{\n    switch (tp) {\n        CONST_TO_NAME(NODE_METHOD)\n        CONST_TO_NAME(NODE_FBODY)\n        CONST_TO_NAME(NODE_CFUNC)\n        CONST_TO_NAME(NODE_SCOPE)\n        CONST_TO_NAME(NODE_BLOCK)\n        CONST_TO_NAME(NODE_IF)\n        CONST_TO_NAME(NODE_CASE)\n        CONST_TO_NAME(NODE_WHEN)\n        CONST_TO_NAME(NODE_OPT_N)\n        CONST_TO_NAME(NODE_WHILE)\n        CONST_TO_NAME(NODE_UNTIL)\n        CONST_TO_NAME(NODE_ITER)\n        CONST_TO_NAME(NODE_FOR)\n        CONST_TO_NAME(NODE_BREAK)\n        CONST_TO_NAME(NODE_NEXT)\n        CONST_TO_NAME(NODE_REDO)\n        CONST_TO_NAME(NODE_RETRY)\n        CONST_TO_NAME(NODE_BEGIN)\n        CONST_TO_NAME(NODE_RESCUE)\n        CONST_TO_NAME(NODE_RESBODY)\n        CONST_TO_NAME(NODE_ENSURE)\n        CONST_TO_NAME(NODE_AND)\n        CONST_TO_NAME(NODE_OR)\n        CONST_TO_NAME(NODE_NOT)\n        CONST_TO_NAME(NODE_MASGN)\n        CONST_TO_NAME(NODE_LASGN)\n        CONST_TO_NAME(NODE_DASGN)\n        CONST_TO_NAME(NODE_DASGN_CURR)\n        CONST_TO_NAME(NODE_GASGN)\n        CONST_TO_NAME(NODE_IASGN)\n        CONST_TO_NAME(NODE_CDECL)\n        CONST_TO_NAME(NODE_CVASGN)\n        CONST_TO_NAME(NODE_CVDECL)\n        CONST_TO_NAME(NODE_OP_ASGN1)\n        CONST_TO_NAME(NODE_OP_ASGN2)\n        CONST_TO_NAME(NODE_OP_ASGN_AND)\n        CONST_TO_NAME(NODE_OP_ASGN_OR)\n        CONST_TO_NAME(NODE_CALL)\n        CONST_TO_NAME(NODE_FCALL)\n        CONST_TO_NAME(NODE_VCALL)\n        CONST_TO_NAME(NODE_SUPER)\n        CONST_TO_NAME(NODE_ZSUPER)\n        CONST_TO_NAME(NODE_ARRAY)\n        CONST_TO_NAME(NODE_ZARRAY)\n        CONST_TO_NAME(NODE_HASH)\n        CONST_TO_NAME(NODE_RETURN)\n        CONST_TO_NAME(NODE_YIELD)\n        CONST_TO_NAME(NODE_LVAR)\n        CONST_TO_NAME(NODE_DVAR)\n        CONST_TO_NAME(NODE_GVAR)\n        CONST_TO_NAME(NODE_IVAR)\n        CONST_TO_NAME(NODE_CONST)\n        CONST_TO_NAME(NODE_CVAR)\n        CONST_TO_NAME(NODE_NTH_REF)\n        CONST_TO_NAME(NODE_BACK_REF)\n        CONST_TO_NAME(NODE_MATCH)\n        CONST_TO_NAME(NODE_MATCH2)\n        CONST_TO_NAME(NODE_MATCH3)\n        CONST_TO_NAME(NODE_LIT)\n        CONST_TO_NAME(NODE_STR)\n        CONST_TO_NAME(NODE_DSTR)\n        CONST_TO_NAME(NODE_XSTR)\n        CONST_TO_NAME(NODE_DXSTR)\n        CONST_TO_NAME(NODE_EVSTR)\n        CONST_TO_NAME(NODE_DREGX)\n        CONST_TO_NAME(NODE_DREGX_ONCE)\n        CONST_TO_NAME(NODE_ARGS)\n        CONST_TO_NAME(NODE_ARGSCAT)\n        CONST_TO_NAME(NODE_ARGSPUSH)\n        CONST_TO_NAME(NODE_SPLAT)\n        CONST_TO_NAME(NODE_TO_ARY)\n        CONST_TO_NAME(NODE_SVALUE)\n        CONST_TO_NAME(NODE_BLOCK_ARG)\n        CONST_TO_NAME(NODE_BLOCK_PASS)\n        CONST_TO_NAME(NODE_DEFN)\n        CONST_TO_NAME(NODE_DEFS)\n        CONST_TO_NAME(NODE_ALIAS)\n        CONST_TO_NAME(NODE_VALIAS)\n        CONST_TO_NAME(NODE_UNDEF)\n        CONST_TO_NAME(NODE_CLASS)\n        CONST_TO_NAME(NODE_MODULE)\n        CONST_TO_NAME(NODE_SCLASS)\n        CONST_TO_NAME(NODE_COLON2)\n        CONST_TO_NAME(NODE_COLON3)\n        CONST_TO_NAME(NODE_CREF)\n        CONST_TO_NAME(NODE_DOT2)\n        CONST_TO_NAME(NODE_DOT3)\n        CONST_TO_NAME(NODE_FLIP2)\n        CONST_TO_NAME(NODE_FLIP3)\n        CONST_TO_NAME(NODE_ATTRSET)\n        CONST_TO_NAME(NODE_SELF)\n        CONST_TO_NAME(NODE_NIL)\n        CONST_TO_NAME(NODE_TRUE)\n        CONST_TO_NAME(NODE_FALSE)\n        CONST_TO_NAME(NODE_DEFINED)\n        CONST_TO_NAME(NODE_NEWLINE)\n        CONST_TO_NAME(NODE_POSTEXE)\n        CONST_TO_NAME(NODE_ALLOCA)\n        CONST_TO_NAME(NODE_DMETHOD)\n        CONST_TO_NAME(NODE_BMETHOD)\n        CONST_TO_NAME(NODE_MEMO)\n        CONST_TO_NAME(NODE_IFUNC)\n        CONST_TO_NAME(NODE_DSYM)\n        CONST_TO_NAME(NODE_ATTRASGN)\n        CONST_TO_NAME(NODE_LAST)\n        default: return \"____\";\n    }\n}\n\nstatic void\nfree_unused_heaps()\n{\n    int i, j;\n\n    for (i = j = 1; j < heaps_used; i++) {\n        if (heaps[i].limit == 0) {\n            free(heaps[i].membase);\n            free(heaps[i].marks);\n            heaps_used--;\n        }\n        else {\n            if (i != j) {\n                heaps[j] = heaps[i];\n            }\n            j++;\n        }\n    }\n}\n\nvoid rb_gc_abort_threads(void);\n\nstatic void\nremembered_set_recycle()\n{\n    remembered_set_t *top = 0, *rem, *next;\n\n    int recycled = 0;\n    int kept = 0;\n    rem = remembered_set_ptr;\n    while (rem) {\n        next = rem->next;\n        if (rb_mark_table_contains((RVALUE *)rem->obj)) {\n            top = rem;\n            ++kept;\n        }\n        else {\n            if (top) {\n                top->next = next;\n            }\n            else {\n                remembered_set_ptr = next;\n            }\n            rem->obj = 0;\n            rem->next = remembered_set_freed;\n            remembered_set_freed = rem;\n            ++recycled;\n        }\n        rem = next;\n    }\n    GC_DEBUG_PRINTF(\"  Remembered set kept:           %8d\\n\", kept)\n    GC_DEBUG_PRINTF(\"  Remembered set recycled:       %8d\\n\", recycled)\n}\n\nstatic void\ngc_sweep(heaps_space_t *heaps_space)\n{\n    RVALUE *p, *pstart, *final_list;\n    struct heaps_slot *heap;\n    int i, deferred, type, new_heap_size, prev_sourcefiles_count;\n    int lt = heaps_space->lifetime;\n\n    /* individual heap counters */\n    unsigned long free_slots, newly_freed_slots, finalized_slots, already_freed_slots, live_slots;\n\n    /* heapspace total counters */\n    unsigned long total_free_slots = 0;\n#ifdef GC_DEBUG\n    unsigned long total_newly_freed_slots = 0;\n    unsigned long total_finalized_slots = 0;\n    unsigned long total_already_freed_slots = 0;\n    unsigned long total_live_slots = 0;\n    int empty_heaps = 0;\n\n    int prev_source_positions_count;\n    int free_counts[OBJ_TYPE_COUNT];\n    int live_counts[OBJ_TYPE_COUNT];\n    const char *heaps_space_name;\n\n    if (GC_DEBUG_ON) {\n        heaps_space_name = lifetime_name[lt];\n        if (lt == lifetime_longlife) {\n            fprintf(gc_data_file, \"  %s collection (after %d edens)\\n\", heaps_space_name, gc_eden_cycles_since_last_longlife);\n            fprintf(gc_data_file, \"  Objects moved to longlife: %8d\\n\", longlife_moved_objs_count);\n            gc_eden_cycles_since_last_longlife = 0;\n            longlife_moved_objs_count = 0;\n        } else {\n            fprintf(gc_data_file, \"  %s collection\\n\", heaps_space_name);\n        }\n        MEMZERO(&free_counts, int, OBJ_TYPE_COUNT);\n        MEMZERO(&live_counts, int, OBJ_TYPE_COUNT);\n    }\n#endif\n\n    heaps_space->freelist = 0;\n    final_list = deferred_final_list;\n    deferred_final_list = 0;\n\n#ifdef GC_DEBUG\n    st_table *freed_objects_table, *live_objects_table;\n    if (GC_DEBUG_ON && gc_debug_dump) {\n        freed_objects_table = st_init_table_with_size(&source_positions_type, SOURCE_POS_INIT_TMP_SIZE);\n        live_objects_table = st_init_table_with_size(&source_positions_type, SOURCE_POS_INIT_TMP_SIZE);\n    }\n#endif\n\n    for (i = heaps_used - 1; i >= 0; i--) {\n        heap = &heaps[i];\n        if (heap->lifetime != lt) continue;\n\n        RVALUE *free = heaps_space->freelist;\n        RVALUE *final = final_list;\n\n        finalized_slots = 0;\n        newly_freed_slots = 0;\n        already_freed_slots = 0;\n        live_slots = 0;\n\n        /* Add freed slots in reverse order, so that the first physical free slot is\n            the head of the freelist. This is a feeble attempt to reduce fragmentation. */\n        pstart = heap->slot;\n        p = pstart + heap->limit;\n        while (p-- > pstart) {\n            type = BUILTIN_TYPE(p);\n            if (!rb_mark_table_heap_contains(heap, p)) {\n                if (p->as.basic.flags) {\n#ifdef GC_DEBUG\n                    if (GC_DEBUG_ON && gc_debug_dump) {\n                        gc_debug_add_to_source_pos_table(freed_objects_table, p, type);\n                    }\n#endif\n                    deferred = obj_free((VALUE)p);\n                    if (deferred || ((FL_TEST(p, FL_FINALIZE)) && need_call_final)) {\n                        /* This object has a finalizer, so don't free it right now, but do it later. */\n                        finalized_slots++;\n                        if (!deferred) {\n                            p->as.free.flags = T_DEFERRED;\n                            RDATA(p)->dfree = 0;\n                        }\n                        rb_mark_table_heap_add(heap, p); /* remain marked */\n                        p->as.free.next = final_list;\n                        final_list = p;\n                    } else {\n                        newly_freed_slots++;\n#ifdef GC_DEBUG\n                        if (GC_DEBUG_ON && type) free_counts[type]++;\n#endif\n                        push_freelist(heaps_space, p);\n                    }\n                } else {\n                    already_freed_slots++;\n                    push_freelist(heaps_space, p);\n                }\n#ifdef GC_DEBUG\n            } else if (type == T_DEFERRED) {\n                live_slots++;\n                /* objects to be finalized */\n                /* do nothing remain marked */\n            } else {\n                live_slots++;\n                if (GC_DEBUG_ON) {\n                    live_counts[type]++;\n                    if (gc_debug_dump) {\n                        gc_debug_add_to_source_pos_table(live_objects_table, p, type);\n                    }\n                }\n#endif\n            }\n        }\n\n        free_slots = already_freed_slots + newly_freed_slots + finalized_slots;\n        total_free_slots += free_slots;\n#ifdef GC_DEBUG\n        total_already_freed_slots += already_freed_slots;\n        total_newly_freed_slots += newly_freed_slots;\n        total_finalized_slots += finalized_slots;\n        total_live_slots += live_slots;\n#endif\n\n        if (free_slots == heap->limit) {\n            /* Any unfragmented empty heaps? */\n#ifdef GC_DEBUG\n            empty_heaps++;\n#endif\n            if (gc_debug_stress ||\n                /* Shrink longlife if it's too lazy */\n                (lt == lifetime_longlife && (total_free_slots > (heaps_space->total_slots - heap->limit) * longlife_laziness)) ||\n                /* Shrink eden if there is a freeable heap and we are over our target size */\n                (lt == lifetime_eden && (heaps_space->num_heaps > eden_heaps))) {\n                GC_DEBUG_PRINTF(\"  %s heap freed (size %d)\\n\", heaps_space_name, heap->limit)\n                RVALUE *pp;\n                heaps_space->total_slots -= heap->limit;\n                heaps_space->num_heaps--;\n                total_free_slots -= heap->limit;\n                heap->limit = 0;\n                heap->slotlimit = heap->slot;\n                for (pp = final_list; pp != final; pp = pp->as.free.next) {\n                    pp->as.free.flags |= FL_SINGLETON; /* freeing page mark */\n                }\n                heaps_space->freelist = free;   /* cancel this page from freelist */\n            }\n        }\n    }\n\n    for (i = 0;\n        i < heap_increase_rate &&\n        ((lt == lifetime_longlife &&\n            /* Expand longlife if it's not lazy enough */\n            (total_free_slots < heaps_space->total_slots * longlife_laziness)) ||\n        (lt == lifetime_eden &&\n            /* Add four eden heaps at a time (to reduce initial fragmentation) until we reach\n                the target size */\n            (heaps_space->num_heaps < eden_heaps)));\n        i++) {\n          new_heap_size = add_heap(heaps_space);\n          GC_DEBUG_PRINTF(\"  %s heap added (size %d)\\n\", heaps_space_name, new_heap_size)\n          total_free_slots += new_heap_size;\n    }\n\n    if (lt == lifetime_longlife) {\n        if (final_list) {\n            deferred_final_list = final_list;\n        }\n        mark_source_filename(ruby_sourcefile);\n        longlife_recent_allocations = 0;\n        remembered_set_recycle();\n    } else { /* lt == lifetime_eden */\n        during_gc = 0;\n        /* clear finalization list */\n        if (final_list) {\n            deferred_final_list = final_list;\n            if (!rb_thread_critical) {\n                rb_gc_finalize_deferred();\n            } else {\n                rb_thread_pending = 1;\n            }\n        }\n        free_unused_heaps();\n    }\n\n    /* reset free slot count; we do it in bulk to avoid a cache penalty on every decrement */\n    heaps_space->total_free_slots = total_free_slots;\n\n#ifdef GC_DEBUG\n    if (GC_DEBUG_ON) {\n        fprintf(gc_data_file, \"  %s heaps in heapspace:   %8d\\n\", heaps_space_name, heaps_space->num_heaps);\n        fprintf(gc_data_file, \"  %s empty heaps:          %8d\\n\", heaps_space_name, empty_heaps);\n        fprintf(gc_data_file, \"  %s total slots:          %8u\\n\", heaps_space_name, heaps_space->total_slots);\n        fprintf(gc_data_file, \"  %s already free slots:   %8lu\\n\", heaps_space_name, total_already_freed_slots);\n        fprintf(gc_data_file, \"  %s finalized free slots: %8lu\\n\", heaps_space_name, total_finalized_slots);\n        fprintf(gc_data_file, \"  %s live objects:         %8lu\\n\", heaps_space_name, total_live_slots);\n        fprintf(gc_data_file, \"  %s freed objects:        %8lu\\n\", heaps_space_name, total_newly_freed_slots);\n\n        if (gc_debug_summary) {\n            fprintf(gc_data_file, \"  %s objects summary:\\n    Type         Live    Freed\\n\",  heaps_space_name);\n\n            for(i = 0; i < OBJ_TYPE_COUNT; i++) {\n                if (free_counts[i] > 0 || live_counts[i] > 0) {\n                    fprintf(gc_data_file, \"    %-8s %8d %8d\\n\", gc_debug_obj_type(i), live_counts[i], free_counts[i]);\n                }\n            }\n        }\n\n        if (gc_debug_dump) {\n            gc_debug_dump_source_pos_table(live_objects_table, lt, \"live\");\n            gc_debug_dump_source_pos_table(freed_objects_table, lt, \"freed\");\n            st_free_table(live_objects_table);\n            st_free_table(freed_objects_table);\n        }\n    }\n#endif\n\n    if (lt == lifetime_eden) {\n        prev_sourcefiles_count = source_filenames->num_entries;\n#ifdef GC_DEBUG\n        if (source_positions) {\n            prev_source_positions_count = source_positions->num_entries;\n            if (longlife_collection) {\n                st_foreach(source_positions, sweep_source_pos, 0);\n                GC_DEBUG_PRINTF(\"  Source position freed structs: %8d\\n\", prev_source_positions_count - source_positions->num_entries)\n            }\n            GC_DEBUG_PRINTF(\"  Source position live structs:  %8d\\n\", source_positions->num_entries)\n        }\n#endif\n        if (longlife_collection) {\n            st_foreach(source_filenames, sweep_source_filename, 0);\n            GC_DEBUG_PRINTF(\"  Source filename freed strings: %8d\\n\", prev_sourcefiles_count - source_filenames->num_entries)\n        }\n       GC_DEBUG_PRINTF(\"  Source filename live strings:  %8d\\n\", source_filenames->num_entries)\n    }\n}\n\nvoid\nrb_gc_force_recycle(p)\n    VALUE p;\n{\n    rb_mark_table_remove((RVALUE *) p);\n    add_to_correct_freelist(RANY(p));\n}\n\nstatic inline void\nmake_deferred(p)\n    RVALUE *p;\n{\n    p->as.basic.flags = (p->as.basic.flags & ~T_MASK) | T_DEFERRED;\n}\n\nstatic int\nobj_free(obj)\n    VALUE obj;\n{\n    switch (BUILTIN_TYPE(obj)) {\n      case T_NIL:\n      case T_FIXNUM:\n      case T_TRUE:\n      case T_FALSE:\n        rb_bug(\"obj_free() called for broken object\");\n        break;\n    }\n\n    if (FL_TEST(obj, FL_EXIVAR)) {\n        rb_free_generic_ivar((VALUE)obj);\n    }\n\n    switch (BUILTIN_TYPE(obj)) {\n      case T_OBJECT:\n        if (RANY(obj)->as.object.iv_tbl) {\n            st_free_table(RANY(obj)->as.object.iv_tbl);\n        }\n        break;\n      case T_MODULE:\n      case T_CLASS:\n        rb_clear_cache_by_class((VALUE)obj);\n        st_free_table(RANY(obj)->as.klass.m_tbl);\n        if (RANY(obj)->as.object.iv_tbl) {\n            st_free_table(RANY(obj)->as.object.iv_tbl);\n        }\n        break;\n      case T_STRING:\n        if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) {\n            RUBY_CRITICAL(free(RANY(obj)->as.string.ptr));\n        }\n        break;\n      case T_ARRAY:\n        if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) {\n            RUBY_CRITICAL(free(RANY(obj)->as.array.ptr));\n        }\n        break;\n      case T_HASH:\n        if (RANY(obj)->as.hash.tbl) {\n            st_free_table(RANY(obj)->as.hash.tbl);\n        }\n        break;\n      case T_REGEXP:\n        if (RANY(obj)->as.regexp.ptr) {\n            re_free_pattern(RANY(obj)->as.regexp.ptr);\n        }\n        if (RANY(obj)->as.regexp.str) {\n            RUBY_CRITICAL(free(RANY(obj)->as.regexp.str));\n        }\n        break;\n      case T_DATA:\n        if (DATA_PTR(obj)) {\n            if ((long)RANY(obj)->as.data.dfree == -1) {\n                RUBY_CRITICAL(free(DATA_PTR(obj)));\n            }\n            else if (RANY(obj)->as.data.dfree) {\n                make_deferred(RANY(obj));\n                return 1;\n            }\n        }\n        break;\n      case T_MATCH:\n        if (RANY(obj)->as.match.regs) {\n            re_free_registers(RANY(obj)->as.match.regs);\n            RUBY_CRITICAL(free(RANY(obj)->as.match.regs));\n        }\n        break;\n      case T_FILE:\n        if (RANY(obj)->as.file.fptr) {\n            struct rb_io_t *fptr = RANY(obj)->as.file.fptr;\n            make_deferred(RANY(obj));\n            RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize;\n            RDATA(obj)->data = fptr;\n            return 1;\n        }\n        break;\n      case T_ICLASS:\n        /* iClass shares table with the module */\n        break;\n\n      case T_FLOAT:\n      case T_VARMAP:\n      case T_BLKTAG:\n        break;\n\n      case T_BIGNUM:\n        if (RANY(obj)->as.bignum.digits) {\n            RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits));\n        }\n        break;\n      case T_NODE:\n        switch (nd_type(obj)) {\n          case NODE_SCOPE:\n            if (RANY(obj)->as.node.u1.tbl) {\n                RUBY_CRITICAL(free(RANY(obj)->as.node.u1.tbl));\n            }\n            break;\n          case NODE_ALLOCA:\n            RUBY_CRITICAL(free(RANY(obj)->as.node.u1.node));\n            break;\n        }\n        break;                  /* no need to free iv_tbl */\n\n      case T_SCOPE:\n        if (RANY(obj)->as.scope.local_vars &&\n            RANY(obj)->as.scope.flags != SCOPE_ALLOCA) {\n            VALUE *vars = RANY(obj)->as.scope.local_vars-1;\n            if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0)\n                RUBY_CRITICAL(free(RANY(obj)->as.scope.local_tbl));\n            if ((RANY(obj)->as.scope.flags & (SCOPE_MALLOC|SCOPE_CLONE)) == SCOPE_MALLOC)\n                RUBY_CRITICAL(free(vars));\n        }\n        break;\n\n      case T_STRUCT:\n        if (RANY(obj)->as.rstruct.ptr) {\n            RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr));\n        }\n        break;\n\n      default:\n        rb_bug(\"gc_sweep(): unknown data type 0x%lx(0x%lx)\",\n               RANY(obj)->as.basic.flags & T_MASK, obj);\n    }\n\n    return 0;\n}\n\nvoid\nrb_gc_mark_frame(frame)\n    struct FRAME *frame;\n{\n    rb_gc_mark((VALUE)frame->node);\n#ifdef GC_DEBUG\n    mark_source_pos(frame->source_pos);\n#endif\n}\n\n#ifdef __GNUC__\n#if defined(__human68k__) || defined(DJGPP)\n#undef rb_setjmp\n#undef rb_jmp_buf\n#if defined(__human68k__)\ntypedef unsigned long rb_jmp_buf[8];\n__asm__ (\".even\\n\\\n_rb_setjmp:\\n\\\n        move.l  4(sp),a0\\n\\\n        movem.l d3-d7/a3-a5,(a0)\\n\\\n        moveq.l #0,d0\\n\\\n        rts\");\n#else\n#if defined(DJGPP)\ntypedef unsigned long rb_jmp_buf[6];\n__asm__ (\".align 4\\n\\\n_rb_setjmp:\\n\\\n        pushl   %ebp\\n\\\n        movl    %esp,%ebp\\n\\\n        movl    8(%ebp),%ebp\\n\\\n        movl    %eax,(%ebp)\\n\\\n        movl    %ebx,4(%ebp)\\n\\\n        movl    %ecx,8(%ebp)\\n\\\n        movl    %edx,12(%ebp)\\n\\\n        movl    %esi,16(%ebp)\\n\\\n        movl    %edi,20(%ebp)\\n\\\n        popl    %ebp\\n\\\n        xorl    %eax,%eax\\n\\\n        ret\");\n#endif\n#endif\nint rb_setjmp (rb_jmp_buf);\n#endif /* __human68k__ or DJGPP */\n#endif /* __GNUC__ */\n\nstatic int\nadd_entry_to_remembered_set(key, value)\n    ID key;\n    VALUE value;\n{\n    rb_gc_write_barrier(value);\n    return ST_CONTINUE;\n}\n\nvoid\nadd_table_to_remembered_set(tbl)\n    st_table *tbl;\n{\n    if (!tbl) return;\n    st_foreach(tbl, add_entry_to_remembered_set, 0);\n}\n\nstatic int\nadd_keyvalue_to_remembered_set(key, value)\n    VALUE key;\n    VALUE value;\n{\n    rb_gc_write_barrier(key);\n    rb_gc_write_barrier(value);\n    return ST_CONTINUE;\n}\n\nstatic void\nadd_hash_to_remembered_set(tbl)\n    st_table *tbl;\n{\n    if (!tbl) return;\n    st_foreach(tbl, add_keyvalue_to_remembered_set, 0);\n}\n\nstatic void\nadd_array_elements_to_remembered_set(x, n)\n    VALUE *x;\n    size_t n;\n{\n    VALUE v;\n    while (n--) {\n        v = *x;\n        if (is_pointer_to_heap((void *)v)) {\n            rb_gc_write_barrier(v);\n        }\n        x++;\n    }\n}\n\nstatic void\nadd_children_to_remembered_set(ptr)\n    VALUE ptr;\n{\n    RVALUE *obj = RANY(ptr);\n\n    if (FL_TEST(obj, FL_EXIVAR)) {\n        add_generic_ivar_to_remembered_set(ptr);\n    }\n\n    switch (obj->as.basic.flags & T_MASK) {\n      case T_NIL:\n      case T_FIXNUM:\n        rb_bug(\"add_children_to_remembered_set() called for broken object\");\n        break;\n\n      case T_NODE:\n        switch (nd_type(obj)) {\n          case NODE_IF:         /* 1,2,3 */\n          case NODE_FOR:\n          case NODE_ITER:\n          case NODE_CREF:\n          case NODE_WHEN:\n          case NODE_MASGN:\n          case NODE_RESCUE:\n          case NODE_RESBODY:\n          case NODE_CLASS:\n            rb_gc_write_barrier((VALUE)obj->as.node.u2.node);\n            /* fall through */\n          case NODE_BLOCK:      /* 1,3 */\n          case NODE_ARRAY:\n          case NODE_DSTR:\n          case NODE_DXSTR:\n          case NODE_DREGX:\n          case NODE_DREGX_ONCE:\n          case NODE_FBODY:\n          case NODE_ENSURE:\n          case NODE_CALL:\n          case NODE_DEFS:\n          case NODE_OP_ASGN1:\n            rb_gc_write_barrier((VALUE)obj->as.node.u1.node);\n            /* fall through */\n          case NODE_SUPER:      /* 3 */\n          case NODE_FCALL:\n          case NODE_DEFN:\n          case NODE_NEWLINE:\n            rb_gc_write_barrier((VALUE)obj->as.node.u3.node);\n            break;\n\n          case NODE_WHILE:      /* 1,2 */\n          case NODE_UNTIL:\n          case NODE_AND:\n          case NODE_OR:\n          case NODE_CASE:\n          case NODE_SCLASS:\n          case NODE_DOT2:\n          case NODE_DOT3:\n          case NODE_FLIP2:\n          case NODE_FLIP3:\n          case NODE_MATCH2:\n          case NODE_MATCH3:\n          case NODE_OP_ASGN_OR:\n          case NODE_OP_ASGN_AND:\n          case NODE_MODULE:\n          case NODE_ALIAS:\n          case NODE_VALIAS:\n          case NODE_ARGS:\n            rb_gc_write_barrier((VALUE)obj->as.node.u1.node);\n            /* fall through */\n          case NODE_METHOD:     /* 2 */\n          case NODE_NOT:\n          case NODE_GASGN:\n          case NODE_LASGN:\n          case NODE_DASGN:\n          case NODE_DASGN_CURR:\n          case NODE_IASGN:\n          case NODE_CVDECL:\n          case NODE_CVASGN:\n          case NODE_COLON3:\n          case NODE_OPT_N:\n          case NODE_EVSTR:\n          case NODE_UNDEF:\n            rb_gc_write_barrier((VALUE)obj->as.node.u2.node);\n            break;\n\n          case NODE_HASH:       /* 1 */\n          case NODE_LIT:\n          case NODE_STR:\n          case NODE_XSTR:\n          case NODE_DEFINED:\n          case NODE_MATCH:\n          case NODE_RETURN:\n          case NODE_BREAK:\n          case NODE_NEXT:\n          case NODE_YIELD:\n          case NODE_COLON2:\n          case NODE_SPLAT:\n          case NODE_TO_ARY:\n          case NODE_SVALUE:\n            rb_gc_write_barrier((VALUE)obj->as.node.u1.node);\n            break;\n\n          case NODE_SCOPE:      /* 2,3 */\n          case NODE_BLOCK_PASS:\n          case NODE_CDECL:\n            rb_gc_write_barrier((VALUE)obj->as.node.u3.node);\n            rb_gc_write_barrier((VALUE)obj->as.node.u2.node);\n            break;\n\n          case NODE_ZARRAY:     /* - */\n          case NODE_ZSUPER:\n          case NODE_CFUNC:\n          case NODE_VCALL:\n          case NODE_GVAR:\n          case NODE_LVAR:\n          case NODE_DVAR:\n          case NODE_IVAR:\n          case NODE_CVAR:\n          case NODE_NTH_REF:\n          case NODE_BACK_REF:\n          case NODE_REDO:\n          case NODE_RETRY:\n          case NODE_SELF:\n          case NODE_NIL:\n          case NODE_TRUE:\n          case NODE_FALSE:\n          case NODE_ATTRSET:\n          case NODE_BLOCK_ARG:\n          case NODE_POSTEXE:\n            break;\n          case NODE_ALLOCA:\n            add_array_elements_to_remembered_set((VALUE*)obj->as.node.u1.value,\n                                 obj->as.node.u3.cnt);\n            rb_gc_write_barrier((VALUE)obj->as.node.u2.node);\n            break;\n\n          default:              /* unlisted NODE */\n            if (is_pointer_to_heap(obj->as.node.u1.node)) {\n                rb_gc_write_barrier((VALUE)obj->as.node.u1.node);\n            }\n            if (is_pointer_to_heap(obj->as.node.u2.node)) {\n                rb_gc_write_barrier((VALUE)obj->as.node.u2.node);\n            }\n            if (is_pointer_to_heap(obj->as.node.u3.node)) {\n                rb_gc_write_barrier((VALUE)obj->as.node.u3.node);\n            }\n        }\n        return; /* no need to mark class. */\n    }\n\n    rb_gc_write_barrier(obj->as.basic.klass);\n    switch (obj->as.basic.flags & T_MASK) {\n      case T_ICLASS:\n      case T_CLASS:\n      case T_MODULE:\n        add_table_to_remembered_set(obj->as.klass.m_tbl);\n        add_table_to_remembered_set(obj->as.klass.iv_tbl);\n        rb_gc_write_barrier(obj->as.klass.super);\n        break;\n\n      case T_ARRAY:\n        if (FL_TEST(obj, ELTS_SHARED)) {\n            rb_gc_write_barrier(obj->as.array.aux.shared);\n        }\n        else {\n            VALUE *ptr = obj->as.array.ptr;\n            VALUE *pend = ptr + obj->as.array.len;\n            while (ptr < pend) {\n                rb_gc_write_barrier(*ptr++);\n            }\n        }\n        break;\n\n      case T_HASH:\n        add_hash_to_remembered_set(obj->as.hash.tbl);\n        rb_gc_write_barrier(obj->as.hash.ifnone);\n        break;\n\n      case T_STRING:\n#define STR_ASSOC FL_USER3   /* copied from string.c */\n        if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) {\n            rb_gc_write_barrier(obj->as.string.aux.shared);\n        }\n        break;\n\n      case T_DATA:\n        rb_bug(\"add_children_to_remembered_set() encountered T_DATA 0x%lx\", obj);\n        break;\n\n      case T_OBJECT:\n        add_table_to_remembered_set(obj->as.object.iv_tbl);\n        break;\n\n      case T_FILE:\n      case T_REGEXP:\n      case T_FLOAT:\n      case T_BIGNUM:\n      case T_BLKTAG:\n        break;\n\n      case T_MATCH:\n        if (obj->as.match.str) {\n            rb_gc_write_barrier(obj->as.match.str);\n        }\n        break;\n\n      case T_VARMAP:\n        rb_gc_write_barrier(obj->as.varmap.val);\n        rb_gc_write_barrier((VALUE)obj->as.varmap.next);\n        break;\n\n      case T_SCOPE:\n        if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) {\n            int n = obj->as.scope.local_tbl[0]+1;\n            VALUE *vars = &obj->as.scope.local_vars[-1];\n\n            while (n--) {\n                rb_gc_write_barrier(*vars++);\n            }\n        }\n        break;\n\n      case T_STRUCT:\n        {\n            VALUE *ptr = obj->as.rstruct.ptr;\n            VALUE *pend = ptr + obj->as.rstruct.len;\n            while (ptr < pend)\n               rb_gc_write_barrier(*ptr++);\n        }\n        break;\n\n      default:\n        rb_bug(\"add_children_to_remembered_set(): unknown data type 0x%lx(0x%lx) %s\",\n               obj->as.basic.flags & T_MASK, obj,\n               is_pointer_to_heap(obj) ? \"corrupted object\" : \"non object\");\n    }\n}\n\nstatic void\nrb_gc_recycle_longlife_recent_allocations_set()\n{\n    longlife_recent_allocations_set_t *drem, *next;\n    int seen = 0;\n\n    if (longlife_recent_allocations_set_ptr) {\n        drem = longlife_recent_allocations_set_ptr;\n        while (drem) {\n            next = drem->next;\n            seen += 1;\n            if (drem->obj->as.basic.flags) {\n                add_children_to_remembered_set((VALUE)(drem->obj));\n            }\n            drem->obj = 0;\n            if (next == 0) {\n                drem->next = longlife_recent_allocations_set_freed;\n            }\n            drem = next;\n        }\n\n        longlife_recent_allocations += seen;\n        longlife_recent_allocations_set_freed = longlife_recent_allocations_set_ptr;\n        longlife_recent_allocations_set_ptr = 0;\n    }\n\n    GC_DEBUG_PRINTF(\"  Added %d new longlife allocations to remembered set\\n\", seen)\n}\n\nstatic void\nrb_gc_mark_remembered_set()\n{\n    remembered_set_t *rem = remembered_set_ptr;\n    while (rem) {\n        rb_gc_mark((VALUE)rem->obj);\n        rem = rem->next;\n    }\n}\n\n#ifdef GC_DEBUG\nstatic GC_TIME_TYPE microseconds(struct timeval t) {\n    return t.tv_sec * 1000000 + t.tv_usec;\n}\n\nstatic GC_TIME_TYPE timediff_microseconds(struct timeval later, struct timeval earlier) {\n    GC_TIME_TYPE diff = microseconds(later) - microseconds(earlier);\n    return diff > 0 ? diff : 0;\n}\n#endif\n\nstatic void\ngarbage_collect_0(VALUE *top_frame)\n{\n    struct gc_list *list;\n    struct FRAME * frame;\n    SET_STACK_END;\n\n#ifdef HAVE_NATIVETHREAD\n    if (!is_ruby_native_thread()) {\n        rb_bug(\"cross-thread violation on rb_gc()\");\n    }\n#endif\n    if (dont_gc || during_gc || ruby_in_compile) {\n        add_heap_if_needed(&eden_heaps_space);\n        GC_DEBUG_PRINTF(\"  Skipped due to reason: %s=1\\n\",\n            dont_gc ? \"dont_gc\" : (during_gc ? \"during_gc\" : \"ruby_in_compile\"))\n        return;\n    }\n\n    during_gc++;\n\n#ifdef GC_DEBUG\n    struct rusage ru1, ru2;\n\n    if (GC_DEBUG_ON) {\n        gc_eden_cycles_since_last_longlife++;\n        getrusage(RUSAGE_SELF, &ru1);\n    }\n#endif\n\n    /*** Schedule optional longlife GC based on allocation rate ***/\n\n    if (longlife_recent_allocations > longlife_heaps_space.total_slots * longlife_laziness) {\n        longlife_collection = Qtrue;\n    }\n\n    /* Add any new longlife allocations to the remembered set */\n    rb_gc_recycle_longlife_recent_allocations_set();\n\n    /*** Mark phase ***/\n\n    gc_stack_limit = __stack_grow(STACK_END, GC_LEVEL_MAX);\n    rb_mark_table_prepare();\n    init_mark_stack();\n\n    rb_mark_table_reset(lifetime_eden);\n    if (longlife_collection) {\n        rb_mark_table_reset(lifetime_longlife);\n    } else {\n        // Mark remembered references from longlife to eden\n        rb_gc_mark_remembered_set();\n    }\n\n    /* mark frame stack */\n    if (rb_curr_thread == rb_main_thread) {\n        frame = ruby_frame;\n    } else {\n        frame = rb_main_thread->frame;\n    } for (; frame; frame = frame->prev) {\n        rb_gc_mark_frame(frame);\n        if (frame->tmp) {\n            struct FRAME *tmp = frame->tmp;\n            while (tmp) {\n                rb_gc_mark_frame(tmp);\n                tmp = tmp->prev;\n            }\n        }\n    }\n\n    if (rb_curr_thread == rb_main_thread) {\n        rb_gc_mark((VALUE)ruby_current_node);\n        rb_gc_mark((VALUE)ruby_scope);\n        rb_gc_mark((VALUE)ruby_dyna_vars);\n    } else {\n        rb_gc_mark((VALUE)rb_main_thread->node);\n        rb_gc_mark((VALUE)rb_main_thread->scope);\n        rb_gc_mark((VALUE)rb_main_thread->dyna_vars);\n\n        /* scan the current thread's stack */\n        rb_gc_mark_locations(top_frame, rb_curr_thread->stk_base);\n    }\n\n    if (finalizer_table) {\n        mark_tbl(finalizer_table);\n    }\n\n    /* If this is not the main thread, we need to scan the C stack, so\n     * set top_frame to the end of the C stack.\n     */\n    if (rb_curr_thread != rb_main_thread) {\n        top_frame = rb_main_thread->stk_pos;\n    }\n\n#if STACK_GROW_DIRECTION < 0\n    rb_gc_mark_locations(top_frame, rb_gc_stack_start);\n#elif STACK_GROW_DIRECTION > 0\n    rb_gc_mark_locations(rb_gc_stack_start, top_frame + 1);\n#else\n    if (rb_gc_stack_grow_direction < 0) {\n        rb_gc_mark_locations(top_frame, rb_gc_stack_start);\n    } else {\n        rb_gc_mark_locations(rb_gc_stack_start, top_frame + 1);\n    }\n#endif\n#ifdef __ia64\n    /* mark backing store (flushed register window on the stack) */\n    /* the basic idea from guile GC code                         */\n    rb_gc_mark_locations(rb_gc_register_stack_start, (VALUE*)rb_ia64_bsp());\n#endif\n#if defined(__human68k__) || defined(__mc68000__)\n    rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),\n                         (VALUE*)((char*)rb_gc_stack_start + 2));\n#endif\n\n    rb_gc_mark_threads();\n\n    /* mark protected global variables */\n    for (list = global_List; list; list = list->next) {\n        rb_gc_mark_maybe(*list->varptr);\n    }\n    rb_mark_end_proc();\n    rb_gc_mark_global_tbl();\n\n    rb_mark_tbl(rb_class_tbl);\n    rb_gc_mark_trap_list();\n\n    /* mark generic instance variables for special constants */\n    rb_mark_generic_ivar_tbl();\n\n    rb_gc_mark_parser();\n\n    /* gc_mark objects whose marking are not completed*/\n    do {\n        while (!MARK_STACK_EMPTY) {\n            if (mark_stack_overflow){\n                gc_mark_all();\n            }\n            else {\n                gc_mark_rest();\n            }\n        }\n        rb_gc_abort_threads();\n    } while (!MARK_STACK_EMPTY);\n\n    /*** Sweep phase ***/\n\n    if (longlife_collection) {\n        gc_sweep(&longlife_heaps_space);\n    }\n    gc_sweep(&eden_heaps_space);\n\n    if (longlife_collection) {\n      gc_longlife_cycles++;\n      longlife_collection = Qfalse;\n    } else {\n      gc_cycles++;\n    }\n\n#ifdef GC_DEBUG\n    if (GC_DEBUG_ON) {\n        GC_TIME_TYPE musecs_used_user;\n        GC_TIME_TYPE musecs_used_system;\n        GC_TIME_TYPE musecs_used;\n        getrusage(RUSAGE_SELF, &ru2);\n        musecs_used_user = timediff_microseconds(ru2.ru_utime, ru1.ru_utime);\n        musecs_used_system = timediff_microseconds(ru2.ru_stime, ru1.ru_stime);\n        musecs_used = musecs_used_user + musecs_used_system;\n\n        fprintf(gc_data_file, \"  Garbage collection finished: %llu usec (user: %llu, system: %llu)\\n\",\n            musecs_used, musecs_used_user, musecs_used_system);\n    }\n#endif\n}\n\nstatic void\ngarbage_collect(const char* reason)\n{\n    jmp_buf save_regs_gc_mark;\n    VALUE *top;\n    FLUSH_REGISTER_WINDOWS;\n    /* This assumes that all registers are saved into the jmp_buf (and stack) */\n    rb_setjmp(save_regs_gc_mark);\n    top = __sp();\n\n    GC_DEBUG_PRINTF(\"*** Garbage collection (%s) ***\\n\", reason)\n\n#if STACK_WIPE_SITES & 0x400\n# ifdef nativeAllocA\n    if ((!rb_main_thread || rb_curr_thread == rb_main_thread) && __stack_past (top, stack_limit)) {\n        /* allocate a large frame to ensure app stack cannot grow into GC stack */\n        (volatile void*) nativeAllocA(__stack_depth((void*)stack_limit,(void*)top));\n    }\n    garbage_collect_0(top);\n# else /* no native alloca() available */\n    garbage_collect_0(top);\n    if (rb_curr_thread) {\n        VALUE *paddedLimit = __stack_grow(gc_stack_limit, GC_STACK_PAD);\n        if (__stack_past(rb_curr_thread->gc_stack_end, paddedLimit))\n            rb_curr_thread->gc_stack_end = paddedLimit;\n    }\n    rb_gc_wipe_stack();  /* wipe the whole stack area reserved for this gc */\n# endif\n#else\n    garbage_collect_0(top);\n#endif\n}\n\nvoid\nrb_gc()\n{\n    garbage_collect(\"explicitly called\");\n    rb_gc_finalize_deferred();\n}\n\nVALUE\nrb_gc_preemptive_start()\n{\n    if (GC_DEBUG_ON) {\n        fprintf(gc_data_file, \"*** Preemptive check ***\\n\");\n        fprintf(gc_data_file, \"  Eden slots:            %8u\\n\", eden_heaps_space.total_slots);\n        fprintf(gc_data_file, \"  Free eden slots:       %8u\\n\", eden_heaps_space.total_free_slots);\n        fprintf(gc_data_file, \"  Required free slots:   %8u\\n\", eden_preemptive_total_free_slots);\n    }\n    if (eden_heaps_space.total_free_slots < eden_preemptive_total_free_slots) {\n        garbage_collect(\"preemptive collection request\");\n        return Qtrue;\n    } else {\n        GC_DEBUG_PRINT(\"  Collection skipped\\n\");\n        return Qfalse;\n    }\n}\n\n/*\n *  call-seq:\n *     GC.start                     => nil\n *     gc.garbage_collect           => nil\n *     ObjectSpace.garbage_collect  => nil\n *\n *  Initiates garbage collection, unless manually disabled.\n *\n */\n\nVALUE\nrb_gc_start()\n{\n    longlife_collection = Qtrue;\n    rb_gc();\n    return Qnil;\n}\n\n\nint\nrb_gc_is_thread_marked(the_thread)\n    VALUE the_thread;\n{\n    if (FL_ABLE(the_thread)) {\n        return rb_mark_table_contains((RVALUE *) the_thread);\n    } else {\n        return 0;\n    }\n}\n\nvoid\nruby_set_stack_size(size)\n    size_t size;\n{\n#ifndef STACK_LEVEL_MAX\n    STACK_LEVEL_MAX = size / sizeof(VALUE);\n#endif\n    stack_limit = __stack_grow(rb_gc_stack_start, STACK_LEVEL_MAX-GC_STACK_MAX);\n}\n\nstatic void\nset_stack_size(void)\n{\n#ifdef HAVE_GETRLIMIT\n  struct rlimit rlim;\n  if (getrlimit(RLIMIT_STACK, &rlim) == 0) {\n    if (rlim.rlim_cur > 0 && rlim.rlim_cur != RLIM_INFINITY) {\n      size_t maxStackBytes = rlim.rlim_cur;\n      if (rlim.rlim_cur != maxStackBytes)\n        maxStackBytes = -1;\n      {\n        size_t space = maxStackBytes/5;\n        if (space > 1024*1024) space = 1024*1024;\n#ifdef __FreeBSD__\n        /* For some reason we can't use more than 4 MB of stack on\n        * FreeBSD even if getrlimit() reports a much higher amount.\n        */\n        if (maxStackBytes > 4 * 1024 * 1024)\n            maxStackBytes = 4 * 1024 * 1024;\n#endif\n        ruby_set_stack_size(maxStackBytes - space);\n        return;\n      }\n    }\n  }\n#endif\n  ruby_set_stack_size(STACK_LEVEL_MAX*sizeof(VALUE));\n}\n\nvoid\nInit_stack(addr)\n    VALUE *addr;\n{\n#ifdef __ia64\n    if (rb_gc_register_stack_start == 0) {\n# if defined(__FreeBSD__)\n        /*\n         * FreeBSD/ia64 currently does not have a way for a process to get the\n         * base address for the RSE backing store, so hardcode it.\n         */\n        rb_gc_register_stack_start = (4ULL<<61);\n# elif defined(HAVE___LIBC_IA64_REGISTER_BACKING_STORE_BASE)\n#  pragma weak __libc_ia64_register_backing_store_base\n        extern unsigned long __libc_ia64_register_backing_store_base;\n        rb_gc_register_stack_start = (VALUE*)__libc_ia64_register_backing_store_base;\n# endif\n    }\n    {\n        VALUE *bsp = (VALUE*)rb_ia64_bsp();\n        if (rb_gc_register_stack_start == 0 ||\n            bsp < rb_gc_register_stack_start) {\n            rb_gc_register_stack_start = bsp;\n        }\n    }\n#endif\n#if defined(_WIN32) || defined(__CYGWIN__)\n    MEMORY_BASIC_INFORMATION m;\n    memset(&m, 0, sizeof(m));\n    VirtualQuery(&m, &m, sizeof(m));\n    rb_gc_stack_start =\n        STACK_UPPER((VALUE *)m.BaseAddress,\n                    (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1);\n#elif defined(STACK_END_ADDRESS)\n    {\n        extern void *STACK_END_ADDRESS;\n        rb_gc_stack_start = STACK_END_ADDRESS;\n    }\n#else\n    if (!addr) addr = (void *)&addr;\n    STACK_UPPER(addr, ++addr);\n    if (rb_gc_stack_start) {\n        if (STACK_UPPER(rb_gc_stack_start > addr,\n                        rb_gc_stack_start < addr))\n            rb_gc_stack_start = addr;\n        return;\n    }\n    rb_gc_stack_start = addr;\n#endif\n    set_stack_size();\n}\n\nvoid ruby_init_stack(VALUE *addr\n#ifdef __ia64\n    , void *bsp\n#endif\n    )\n{\n    if (!rb_gc_stack_start ||\n        STACK_UPPER(rb_gc_stack_start > addr,\n                    rb_gc_stack_start < addr)) {\n        rb_gc_stack_start = addr;\n    }\n#ifdef __ia64\n    if (!rb_gc_register_stack_start ||\n        (VALUE*)bsp < rb_gc_register_stack_start) {\n        rb_gc_register_stack_start = (VALUE*)bsp;\n    }\n#endif\n#ifdef HAVE_GETRLIMIT\n    set_stack_size();\n#elif defined _WIN32\n    {\n        MEMORY_BASIC_INFORMATION mi;\n        DWORD size;\n        DWORD space;\n\n        if (VirtualQuery(&mi, &mi, sizeof(mi))) {\n            size = (char *)mi.BaseAddress - (char *)mi.AllocationBase;\n            space = size / 5;\n            if (space > 1024*1024) space = 1024*1024;\n            ruby_set_stack_size(size - space);\n        }\n    }\n#endif\n}\n\nstatic void init_heaps_space(heaps_space_t* heaps_space, enum lifetime lifetime)\n{\n    heaps_space->total_slots = 0;\n    heaps_space->total_free_slots = 0;\n    heaps_space->lifetime = lifetime;\n}\n/*\n * Document-class: ObjectSpace\n *\n *  The <code>ObjectSpace</code> module contains a number of routines\n *  that interact with the garbage collection facility and allow you to\n *  traverse all living objects with an iterator.\n *\n *  <code>ObjectSpace</code> also provides support for object\n *  finalizers, procs that will be called when a specific object is\n *  about to be destroyed by garbage collection.\n *\n *     include ObjectSpace\n *\n *\n *     a = \"A\"\n *     b = \"B\"\n *     c = \"C\"\n *\n *\n *     define_finalizer(a, proc {|id| puts \"Finalizer one on #{id}\" })\n *     define_finalizer(a, proc {|id| puts \"Finalizer two on #{id}\" })\n *     define_finalizer(b, proc {|id| puts \"Finalizer three on #{id}\" })\n *\n *  <em>produces:</em>\n *\n *     Finalizer three on 537763470\n *     Finalizer one on 537763480\n *     Finalizer two on 537763480\n *\n */\n\nvoid\nInit_heap()\n{\n    int new_heap_size;\n    rb_mark_table_init();\n    if (!rb_gc_stack_start) {\n        Init_stack(0);\n    }\n\n    /* Need to set_gc_parameters() before heap initialization. */\n    set_gc_parameters();\n\n    init_heaps_space(&eden_heaps_space, lifetime_eden);\n    new_heap_size = add_heap(&eden_heaps_space);\n    GC_DEBUG_PRINTF(\"*** Eden heap added (initialization) (size %d) ***\\n\", new_heap_size)\n\n    init_heaps_space(&longlife_heaps_space, lifetime_longlife);\n    new_heap_size = add_heap(&longlife_heaps_space);\n    GC_DEBUG_PRINTF(\"*** Longlife heap added (initialization) (size %d) ***\\n\", new_heap_size)\n}\n\nstatic VALUE\nos_obj_of(of)\n    VALUE of;\n{\n    int i;\n    int n = 0;\n    volatile VALUE v;\n\n    for (i = 0; i < heaps_used; i++) {\n        RVALUE *p, *pend;\n\n        p = heaps[i].slot; pend = p + heaps[i].limit;\n        for (;p < pend; p++) {\n            if (p->as.basic.flags) {\n                switch (BUILTIN_TYPE(p)) {\n                  case T_NONE:\n                  case T_ICLASS:\n                  case T_VARMAP:\n                  case T_SCOPE:\n                  case T_NODE:\n                  case T_DEFERRED:\n                    continue;\n                  case T_CLASS:\n                    if (FL_TEST(p, FL_SINGLETON)) continue;\n                  default:\n                    if (!p->as.basic.klass) continue;\n                    v = (VALUE)p;\n                    if (!of || rb_obj_is_kind_of(v, of)) {\n                        rb_yield(v);\n                        n++;\n                    }\n                }\n            }\n        }\n    }\n\n    return INT2FIX(n);\n}\n\n/*\n *  call-seq:\n *     ObjectSpace.each_object([module]) {|obj| ... } => fixnum\n *\n *  Calls the block once for each living, nonimmediate object in this\n *  Ruby process. If <i>module</i> is specified, calls the block\n *  for only those classes or modules that match (or are a subclass of)\n *  <i>module</i>. Returns the number of objects found. Immediate\n *  objects (<code>Fixnum</code>s, <code>Symbol</code>s\n *  <code>true</code>, <code>false</code>, and <code>nil</code>) are\n *  never returned. In the example below, <code>each_object</code>\n *  returns both the numbers we defined and several constants defined in\n *  the <code>Math</code> module.\n *\n *     a = 102.7\n *     b = 95       # Won't be returned\n *     c = 12345678987654321\n *     count = ObjectSpace.each_object(Numeric) {|x| p x }\n *     puts \"Total count: #{count}\"\n *\n *  <em>produces:</em>\n *\n *     12345678987654321\n *     102.7\n *     2.71828182845905\n *     3.14159265358979\n *     2.22044604925031e-16\n *     1.7976931348623157e+308\n *     2.2250738585072e-308\n *     Total count: 7\n *\n */\n\nstatic VALUE\nos_each_obj(argc, argv, os)\n    int argc;\n    VALUE *argv;\n    VALUE os;\n{\n    VALUE of;\n\n    rb_secure(4);\n    if (argc == 0) {\n        of = 0;\n    }\n    else {\n        rb_scan_args(argc, argv, \"01\", &of);\n    }\n    RETURN_ENUMERATOR(os, 1, &of);\n    return os_obj_of(of);\n}\n\nstatic VALUE finalizers;\n\n/* deprecated\n */\n\nstatic VALUE\nadd_final(os, block)\n    VALUE os, block;\n{\n    rb_warn(\"ObjectSpace::add_finalizer is deprecated; use define_finalizer\");\n    if (!rb_respond_to(block, rb_intern(\"call\"))) {\n        rb_raise(rb_eArgError, \"wrong type argument %s (should be callable)\",\n                 rb_obj_classname(block));\n    }\n    rb_ary_push(finalizers, block);\n    return block;\n}\n\n/*\n * deprecated\n */\nstatic VALUE\nrm_final(os, block)\n    VALUE os, block;\n{\n    rb_warn(\"ObjectSpace::remove_finalizer is deprecated; use undefine_finalizer\");\n    rb_ary_delete(finalizers, block);\n    return block;\n}\n\n/*\n * deprecated\n */\nstatic VALUE\nfinals()\n{\n    rb_warn(\"ObjectSpace::finalizers is deprecated\");\n    return finalizers;\n}\n\n/*\n * deprecated\n */\n\nstatic VALUE\ncall_final(os, obj)\n    VALUE os, obj;\n{\n    rb_warn(\"ObjectSpace::call_finalizer is deprecated; use define_finalizer\");\n    need_call_final = 1;\n    FL_SET(obj, FL_FINALIZE);\n    return obj;\n}\n\n/*\n *  call-seq:\n *     ObjectSpace.undefine_finalizer(obj)\n *\n *  Removes all finalizers for <i>obj</i>.\n *\n */\n\nstatic VALUE\nundefine_final(os, obj)\n    VALUE os, obj;\n{\n    if (finalizer_table) {\n        st_delete(finalizer_table, (st_data_t*)&obj, 0);\n    }\n    return obj;\n}\n\n/*\n *  call-seq:\n *     ObjectSpace.define_finalizer(obj, aProc=proc())\n *\n *  Adds <i>aProc</i> as a finalizer, to be called after <i>obj</i>\n *  was destroyed.\n *\n */\n\nstatic VALUE\ndefine_final(argc, argv, os)\n    int argc;\n    VALUE *argv;\n    VALUE os;\n{\n    VALUE obj, block, table;\n\n    rb_scan_args(argc, argv, \"11\", &obj, &block);\n    if (argc == 1) {\n        block = rb_block_proc();\n    }\n    else if (!rb_respond_to(block, rb_intern(\"call\"))) {\n        rb_raise(rb_eArgError, \"wrong type argument %s (should be callable)\",\n                 rb_obj_classname(block));\n    }\n    need_call_final = 1;\n    if (!FL_ABLE(obj)) {\n        rb_raise(rb_eArgError, \"cannot define finalizer for %s\",\n                 rb_obj_classname(obj));\n    }\n    RBASIC(obj)->flags |= FL_FINALIZE;\n\n    block = rb_ary_new3(2, INT2FIX(ruby_safe_level), block);\n    OBJ_FREEZE(block);\n\n    if (!finalizer_table) {\n        finalizer_table = st_init_numtable();\n    }\n    if (st_lookup(finalizer_table, obj, &table)) {\n        rb_ary_push(table, block);\n    }\n    else {\n        table = rb_ary_new3(1, block);\n        RBASIC(table)->klass = 0;\n        st_add_direct(finalizer_table, obj, table);\n    }\n    return block;\n}\n\nvoid\nrb_gc_copy_finalizer(dest, obj)\n    VALUE dest, obj;\n{\n    VALUE table;\n\n    if (!finalizer_table) return;\n    if (!FL_TEST(obj, FL_FINALIZE)) return;\n    if (st_lookup(finalizer_table, obj, &table)) {\n        st_insert(finalizer_table, dest, table);\n    }\n    RBASIC(dest)->flags |= FL_FINALIZE;\n}\n\nstatic VALUE\nrun_single_final(args)\n    VALUE *args;\n{\n    rb_eval_cmd(args[0], args[1], (int)args[2]);\n    return Qnil;\n}\n\nstatic void\nrun_final(obj)\n    VALUE obj;\n{\n    long i;\n    int status, critical_save = rb_thread_critical;\n    VALUE args[3], table, objid;\n\n    objid = rb_obj_id(obj);     /* make obj into id */\n    RBASIC(obj)->klass = 0;\n    rb_thread_critical = Qtrue;\n    if (BUILTIN_TYPE(obj) == T_DEFERRED && RDATA(obj)->dfree) {\n        (*RDATA(obj)->dfree)(DATA_PTR(obj));\n    }\n    args[1] = 0;\n    args[2] = (VALUE)ruby_safe_level;\n    for (i=0; i<RARRAY(finalizers)->len; i++) {\n        args[0] = RARRAY(finalizers)->ptr[i];\n        if (!args[1]) args[1] = rb_ary_new3(1, objid);\n        rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status);\n    }\n    if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) {\n        for (i=0; i<RARRAY(table)->len; i++) {\n            VALUE final = RARRAY(table)->ptr[i];\n            args[0] = RARRAY(final)->ptr[1];\n            if (!args[1]) args[1] = rb_ary_new3(1, objid);\n            args[2] = FIX2INT(RARRAY(final)->ptr[0]);\n            rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status);\n        }\n    }\n    rb_thread_critical = critical_save;\n}\n\nvoid\nrb_gc_finalize_deferred()\n{\n    RVALUE *p = deferred_final_list;\n\n    deferred_final_list = 0;\n    if (p) {\n        finalize_list(p);\n        free_unused_heaps();\n    }\n}\n\nvoid\nrb_gc_call_finalizer_at_exit()\n{\n    RVALUE *p, *pend;\n    struct heaps_slot *heap;\n    int i, finalized_slots = 0;\n\n    /* run finalizers */\n    if (need_call_final && finalizer_table) {\n        GC_DEBUG_PRINT(\"*** Calling finalizers ***\\n\")\n        p = deferred_final_list;\n        deferred_final_list = 0;\n        finalize_list(p);\n        for (i = 0; i < heaps_used; i++) {\n            heap = &heaps[i];\n            p = heaps->slot; pend = p + heaps->limit;\n            while (p < pend) {\n                if (FL_TEST(p, FL_FINALIZE)) {\n                    if (GC_DEBUG_ON) finalized_slots++;\n                    FL_UNSET(p, FL_FINALIZE);\n                    run_final((VALUE)p);\n                }\n                p++;\n            }\n        }\n        if (finalizer_table) {\n            st_free_table(finalizer_table);\n            finalizer_table = 0;\n        }\n    }\n    /* run data object's finalizers */\n    for (i = 0; i < heaps_used; i++) {\n        heap = &heaps[i];\n        p = heap->slot; pend = p + heap->limit;\n        while (p < pend) {\n            if (BUILTIN_TYPE(p) == T_DATA &&\n                DATA_PTR(p) && RANY(p)->as.data.dfree &&\n                RANY(p)->as.basic.klass != rb_cThread) {\n                p->as.free.flags = 0;\n                if ((long)RANY(p)->as.data.dfree == -1) {\n                    RUBY_CRITICAL(free(DATA_PTR(p)));\n                } else if (RANY(p)->as.data.dfree) {\n                    if (GC_DEBUG_ON) finalized_slots++;\n                    (*RANY(p)->as.data.dfree)(DATA_PTR(p));\n                }\n            } else if (BUILTIN_TYPE(p) == T_FILE) {\n                p->as.free.flags = 0;\n                if (GC_DEBUG_ON) finalized_slots++;\n                rb_io_fptr_finalize(RANY(p)->as.file.fptr);\n            }\n            p++;\n        }\n    }\n    GC_DEBUG_PRINTF(\"  Finalized %d objects\\n\", finalized_slots)\n}\n\n/*\n *  call-seq:\n *     ObjectSpace._id2ref(object_id) -> an_object\n *\n *  Converts an object id to a reference to the object. May not be\n *  called on an object id passed as a parameter to a finalizer.\n *\n *     s = \"I am a string\"                    #=> \"I am a string\"\n *     r = ObjectSpace._id2ref(s.object_id)   #=> \"I am a string\"\n *     r == s                                 #=> true\n *\n */\n\nstatic VALUE\nid2ref(obj, objid)\n    VALUE obj, objid;\n{\n    unsigned long ptr, p0;\n    int type;\n\n    rb_secure(4);\n    p0 = ptr = NUM2ULONG(objid);\n    if (ptr == Qtrue) return Qtrue;\n    if (ptr == Qfalse) return Qfalse;\n    if (ptr == Qnil) return Qnil;\n    if (FIXNUM_P(ptr)) return (VALUE)ptr;\n    ptr = objid ^ FIXNUM_FLAG;  /* unset FIXNUM_FLAG */\n\n    if ((ptr % sizeof(RVALUE)) == (4 << 2)) {\n        ID symid = ptr / sizeof(RVALUE);\n        if (rb_id2name(symid) == 0)\n            rb_raise(rb_eRangeError, \"%p is not symbol id value\", p0);\n        return ID2SYM(symid);\n    }\n\n    if (!is_pointer_to_heap((void *)ptr)||\n        (type = BUILTIN_TYPE(ptr)) > T_SYMBOL || type == T_ICLASS) {\n        rb_raise(rb_eRangeError, \"0x%lx is not id value\", p0);\n    }\n    if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) {\n        rb_raise(rb_eRangeError, \"0x%lx is recycled object\", p0);\n    }\n    return (VALUE)ptr;\n}\n\n/*\n *  Document-method: __id__\n *  Document-method: object_id\n *\n *  call-seq:\n *     obj.__id__       => fixnum\n *     obj.object_id    => fixnum\n *\n *  Returns an integer identifier for <i>obj</i>. The same number will\n *  be returned on all calls to <code>id</code> for a given object, and\n *  no two active objects will share an id.\n *  <code>Object#object_id</code> is a different concept from the\n *  <code>:name</code> notation, which returns the symbol id of\n *  <code>name</code>. Replaces the deprecated <code>Object#id</code>.\n */\n\n/*\n *  call-seq:\n *     obj.hash    => fixnum\n *\n *  Generates a <code>Fixnum</code> hash value for this object. This\n *  function must have the property that <code>a.eql?(b)</code> implies\n *  <code>a.hash == b.hash</code>. The hash value is used by class\n *  <code>Hash</code>. Any hash value that exceeds the capacity of a\n *  <code>Fixnum</code> will be truncated before being used.\n */\n\nVALUE\nrb_obj_id(VALUE obj)\n{\n    /*\n     *                32-bit VALUE space\n     *          MSB ------------------------ LSB\n     *  false   00000000000000000000000000000000\n     *  true    00000000000000000000000000000010\n     *  nil     00000000000000000000000000000100\n     *  undef   00000000000000000000000000000110\n     *  symbol  ssssssssssssssssssssssss00001110\n     *  object  oooooooooooooooooooooooooooooo00        = 0 (mod sizeof(RVALUE))\n     *  fixnum  fffffffffffffffffffffffffffffff1\n     *\n     *                    object_id space\n     *                                       LSB\n     *  false   00000000000000000000000000000000\n     *  true    00000000000000000000000000000010\n     *  nil     00000000000000000000000000000100\n     *  undef   00000000000000000000000000000110\n     *  symbol   000SSSSSSSSSSSSSSSSSSSSSSSSSSS0        S...S % A = 4 (S...S = s...s * A + 4)\n     *  object   oooooooooooooooooooooooooooooo0        o...o % A = 0\n     *  fixnum  fffffffffffffffffffffffffffffff1        bignum if required\n     *\n     *  where A = sizeof(RVALUE)/4\n     *\n     *  sizeof(RVALUE) is\n     *  20 if 32-bit, double is 4-byte aligned\n     *  24 if 32-bit, double is 8-byte aligned\n     *  40 if 64-bit\n     */\n    if (TYPE(obj) == T_SYMBOL) {\n        return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;\n    }\n    if (SPECIAL_CONST_P(obj)) {\n        return LONG2NUM((long)obj);\n    }\n    return (VALUE)((long)obj|FIXNUM_FLAG);\n}\n\n/* call-seq:\n *  ObjectSpace.allocated_objects => number\n *\n * Returns the count of objects allocated since the Ruby interpreter has\n * started.  This number can only increase. To know how many objects are\n * currently allocated, use ObjectSpace::live_objects\n */\nstatic\nVALUE rb_allocated_objects(VALUE self)\n{\n#if defined(HAVE_LONG_LONG)\n    return ULL2NUM(allocated_objects);\n#else\n    return ULONG2NUM(allocated_objects);\n#endif\n}\n\n/*\n *  The <code>GC</code> module provides an interface to Ruby's mark and\n *  sweep garbage collection mechanism. Some of the underlying methods\n *  are also available via the <code>ObjectSpace</code> module.\n */\n\nvoid\nInit_GC()\n{\n    VALUE rb_mObSpace;\n\n    rb_mGC = rb_define_module(\"GC\");\n    rb_define_singleton_method(rb_mGC, \"start\", rb_gc_start, 0);\n    rb_define_singleton_method(rb_mGC, \"preemptive_start\", rb_gc_preemptive_start, 0);\n    rb_define_singleton_method(rb_mGC, \"enable\", rb_gc_enable, 0);\n    rb_define_singleton_method(rb_mGC, \"disable\", rb_gc_disable, 0);\n    rb_define_method(rb_mGC, \"garbage_collect\", rb_gc_start, 0);\n\n    rb_mObSpace = rb_define_module(\"ObjectSpace\");\n    rb_define_module_function(rb_mObSpace, \"each_object\", os_each_obj, -1);\n    rb_define_module_function(rb_mObSpace, \"garbage_collect\", rb_gc_start, 0);\n    rb_define_module_function(rb_mObSpace, \"add_finalizer\", add_final, 1);\n    rb_define_module_function(rb_mObSpace, \"remove_finalizer\", rm_final, 1);\n    rb_define_module_function(rb_mObSpace, \"finalizers\", finals, 0);\n    rb_define_module_function(rb_mObSpace, \"call_finalizer\", call_final, 1);\n    rb_define_module_function(rb_mObSpace, \"allocated_objects\", rb_allocated_objects, 0);\n\n    rb_define_module_function(rb_mObSpace, \"define_finalizer\", define_final, -1);\n    rb_define_module_function(rb_mObSpace, \"undefine_finalizer\", undefine_final, 1);\n\n    rb_define_module_function(rb_mObSpace, \"_id2ref\", id2ref, 1);\n\n#ifdef GC_DEBUG\n    rb_define_singleton_method(rb_mGC, \"exorcise\", gc_exorcise, 0);\n    rb_define_singleton_method(rb_mGC, \"stress\", gc_debug_stress_get, 0);\n    rb_define_singleton_method(rb_mGC, \"stress=\", gc_debug_stress_set, 1);\n    rb_define_singleton_method(rb_mGC, \"log\", rb_gc_log, 1);\n#endif\n\n    rb_gc_register_address(&rb_mObSpace);\n    rb_global_variable(&finalizers);\n    rb_gc_unregister_address(&rb_mObSpace);\n    finalizers = rb_ary_new();\n\n    rb_global_variable(&nomem_error);\n    nomem_error = rb_exc_new3(rb_eNoMemError,\n                              rb_obj_freeze(rb_str_new2(\"failed to allocate memory\")));\n    OBJ_TAINT(nomem_error);\n    OBJ_FREEZE(nomem_error);\n\n    rb_define_method(rb_mKernel, \"hash\", rb_obj_id, 0);\n    rb_define_method(rb_mKernel, \"__id__\", rb_obj_id, 0);\n    rb_define_method(rb_mKernel, \"object_id\", rb_obj_id, 0);\n}\n"
  },
  {
    "path": "hash.c",
    "content": "/**********************************************************************\n\n  hash.c -\n\n  $Author$\n  $Date$\n  created at: Mon Nov 22 18:51:18 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"st.h\"\n#include \"util.h\"\n#include \"rubysig.h\"\n\n#ifdef __APPLE__\n#include <crt_externs.h>\n#endif\n\n#define HASH_DELETED  FL_USER1\n#define HASH_PROC_DEFAULT FL_USER2\n\nstatic void\nrb_hash_modify(hash)\n    VALUE hash;\n{\n    if (!RHASH(hash)->tbl) rb_raise(rb_eTypeError, \"uninitialized Hash\");\n    if (OBJ_FROZEN(hash)) rb_error_frozen(\"hash\");\n    if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify hash\");\n}\n\nVALUE\nrb_hash_freeze(hash)\n    VALUE hash;\n{\n    return rb_obj_freeze(hash);\n}\n\nVALUE rb_cHash;\n\nstatic VALUE envtbl;\nstatic ID id_hash, id_call, id_default;\n\nstatic VALUE\neql(args)\n    VALUE *args;\n{\n    return (VALUE)rb_eql(args[0], args[1]);\n}\n\nstatic int\nrb_any_cmp(a, b)\n    VALUE a, b;\n{\n    VALUE args[2];\n\n    if (a == b) return 0;\n    if (FIXNUM_P(a) && FIXNUM_P(b)) {\n\treturn a != b;\n    }\n    if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&\n\tTYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {\n\treturn rb_str_cmp(a, b);\n    }\n    if (a == Qundef || b == Qundef) return -1;\n    if (SYMBOL_P(a) && SYMBOL_P(b)) {\n\treturn a != b;\n    }\n\n    args[0] = a;\n    args[1] = b;\n    return !rb_with_disable_interrupt(eql, (VALUE)args);\n}\n\nVALUE\nrb_hash(obj)\n    VALUE obj;\n{\n    VALUE hval = rb_funcall(obj, id_hash, 0);\n  retry:\n    switch (TYPE(hval)) {\n      case T_FIXNUM:\n\treturn hval;\n\n      case T_BIGNUM:\n\treturn LONG2FIX(((long*)(RBIGNUM_DIGITS(hval)))[0]);\n\n      default:\n\thval = rb_to_int(hval);\n\tgoto retry;\n    }\n}\n\nstatic int\nrb_any_hash(a)\n    VALUE a;\n{\n    VALUE hval;\n    int hnum;\n\n    switch (TYPE(a)) {\n      case T_FIXNUM:\n      case T_SYMBOL:\n\thnum = (int)a;\n\tbreak;\n\n      case T_STRING:\n\thnum = rb_str_hash(a);\n\tbreak;\n\n      default:\n        hval = rb_hash(a);\n\thnum = (int)FIX2LONG(hval);\n    }\n    hnum <<= 1;\n    return RSHIFT(hnum, 1);\n}\n\nstatic struct st_hash_type objhash = {\n    rb_any_cmp,\n    rb_any_hash,\n};\n\ntypedef int st_foreach_func(st_data_t, st_data_t, st_data_t);\n\nstruct foreach_safe_arg {\n    st_table *tbl;\n    st_foreach_func *func;\n    st_data_t arg;\n};\n\nstatic int\nforeach_safe_i(key, value, arg)\n    st_data_t key, value;\n    struct foreach_safe_arg *arg;\n{\n    int status;\n\n    if (key == Qundef) return ST_CONTINUE;\n    status = (*arg->func)(key, value, arg->arg);\n    if (status == ST_CONTINUE) {\n\treturn ST_CHECK;\n    }\n    return status;\n}\n\nvoid\nst_foreach_safe(table, func, a)\n    st_table *table;\n    int (*func)();\n    st_data_t a;\n{\n    struct foreach_safe_arg arg;\n\n    arg.tbl = table;\n    arg.func = (st_foreach_func *)func;\n    arg.arg = a;\n    if (st_foreach(table, foreach_safe_i, (st_data_t)&arg)) {\n\trb_raise(rb_eRuntimeError, \"hash modified during iteration\");\n    }\n}\n\ntypedef int rb_foreach_func(VALUE, VALUE, VALUE);\n\nstruct hash_foreach_arg {\n    VALUE hash;\n    rb_foreach_func *func;\n    VALUE arg;\n};\n\nstatic int\nhash_foreach_iter(key, value, arg)\n    VALUE key, value;\n    struct hash_foreach_arg *arg;\n{\n    int status;\n    st_table *tbl;\n\n    tbl = RHASH(arg->hash)->tbl;\n    if (key == Qundef) return ST_CONTINUE;\n    status = (*arg->func)(key, value, arg->arg);\n    if (RHASH(arg->hash)->tbl != tbl) {\n\trb_raise(rb_eRuntimeError, \"rehash occurred during iteration\");\n    }\n    switch (status) {\n      case ST_DELETE:\n \tst_delete_safe(tbl, (st_data_t*)&key, 0, Qundef);\n\tFL_SET(arg->hash, HASH_DELETED);\n      case ST_CONTINUE:\n \tbreak;\n      case ST_STOP:\n \treturn ST_STOP;\n    }\n    return ST_CHECK;\n}\n\nstatic VALUE\nhash_foreach_ensure(hash)\n    VALUE hash;\n{\n    RHASH(hash)->iter_lev--;\n\n    if (RHASH(hash)->iter_lev == 0) {\n\tif (FL_TEST(hash, HASH_DELETED)) {\n\t    st_cleanup_safe(RHASH(hash)->tbl, Qundef);\n\t    FL_UNSET(hash, HASH_DELETED);\n\t}\n    }\n    return 0;\n}\n\nstatic VALUE\nhash_foreach_call(arg)\n    struct hash_foreach_arg *arg;\n{\n    if (st_foreach(RHASH(arg->hash)->tbl, hash_foreach_iter, (st_data_t)arg)) {\n \trb_raise(rb_eRuntimeError, \"hash modified during iteration\");\n    }\n    return Qnil;\n}\n\nvoid\nrb_hash_foreach(hash, func, farg)\n    VALUE hash;\n    int (*func)();\n    VALUE farg;\n{\n    struct hash_foreach_arg arg;\n\n    RHASH(hash)->iter_lev++;\n    arg.hash = hash;\n    arg.func = (rb_foreach_func *)func;\n    arg.arg  = farg;\n    rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);\n}\n\nstatic VALUE hash_alloc0 _((VALUE));\nstatic VALUE hash_alloc _((VALUE));\nstatic VALUE\nhash_alloc0(klass)\n    VALUE klass;\n{\n    NEWOBJ(hash, struct RHash);\n    OBJSETUP(hash, klass, T_HASH);\n\n    hash->ifnone = Qnil;\n\n    return (VALUE)hash;\n}\n\nstatic VALUE\nhash_alloc(klass)\n    VALUE klass;\n{\n    VALUE hash = hash_alloc0(klass);\n\n    RHASH(hash)->tbl = st_init_table(&objhash);\n\n    return hash;\n}\n\nVALUE\nrb_hash_new()\n{\n    return hash_alloc(rb_cHash);\n}\n\n/*\n *  call-seq:\n *     Hash.new                          => hash\n *     Hash.new(obj)                     => aHash\n *     Hash.new {|hash, key| block }     => aHash\n *\n *  Returns a new, empty hash. If this hash is subsequently accessed by\n *  a key that doesn't correspond to a hash entry, the value returned\n *  depends on the style of <code>new</code> used to create the hash. In\n *  the first form, the access returns <code>nil</code>. If\n *  <i>obj</i> is specified, this single object will be used for\n *  all <em>default values</em>. If a block is specified, it will be\n *  called with the hash object and the key, and should return the\n *  default value. It is the block's responsibility to store the value\n *  in the hash if required.\n *\n *     h = Hash.new(\"Go Fish\")\n *     h[\"a\"] = 100\n *     h[\"b\"] = 200\n *     h[\"a\"]           #=> 100\n *     h[\"c\"]           #=> \"Go Fish\"\n *     # The following alters the single default object\n *     h[\"c\"].upcase!   #=> \"GO FISH\"\n *     h[\"d\"]           #=> \"GO FISH\"\n *     h.keys           #=> [\"a\", \"b\"]\n *\n *     # While this creates a new default object each time\n *     h = Hash.new { |hash, key| hash[key] = \"Go Fish: #{key}\" }\n *     h[\"c\"]           #=> \"Go Fish: c\"\n *     h[\"c\"].upcase!   #=> \"GO FISH: C\"\n *     h[\"d\"]           #=> \"Go Fish: d\"\n *     h.keys           #=> [\"c\", \"d\"]\n *\n */\n\nstatic VALUE\nrb_hash_initialize(argc, argv, hash)\n    int argc;\n    VALUE *argv;\n    VALUE hash;\n{\n    VALUE ifnone;\n\n    rb_hash_modify(hash);\n    if (rb_block_given_p()) {\n\tif (argc > 0) {\n\t    rb_raise(rb_eArgError, \"wrong number of arguments\");\n\t}\n\tRHASH(hash)->ifnone = rb_block_proc();\n\tFL_SET(hash, HASH_PROC_DEFAULT);\n    }\n    else {\n\trb_scan_args(argc, argv, \"01\", &ifnone);\n\tRHASH(hash)->ifnone = ifnone;\n    }\n\n    return hash;\n}\n\n/*\n *  call-seq:\n *     Hash[ [key =>|, value]* ]   => hash\n *\n *  Creates a new hash populated with the given objects. Equivalent to\n *  the literal <code>{ <i>key</i>, <i>value</i>, ... }</code>. Keys and\n *  values occur in pairs, so there must be an even number of arguments.\n *\n *     Hash[\"a\", 100, \"b\", 200]       #=> {\"a\"=>100, \"b\"=>200}\n *     Hash[\"a\" => 100, \"b\" => 200]   #=> {\"a\"=>100, \"b\"=>200}\n *     { \"a\" => 100, \"b\" => 200 }     #=> {\"a\"=>100, \"b\"=>200}\n */\n\nstatic VALUE\nrb_hash_s_create(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE hash, tmp;\n    int i;\n\n    if (argc == 1) {\n\ttmp = rb_check_convert_type(argv[0], T_HASH, \"Hash\", \"to_hash\");\n\tif (!NIL_P(tmp)) {\n\t    hash = hash_alloc0(klass);\n\t    RHASH(hash)->tbl = st_copy(RHASH(tmp)->tbl);\n\t    return hash;\n\t}\n\n\ttmp = rb_check_array_type(argv[0]);\n\tif (!NIL_P(tmp)) {\n\t    long i;\n\n\t    hash = hash_alloc(klass);\n\t    for (i = 0; i < RARRAY_LEN(tmp); ++i) {\n\t\tVALUE v = rb_check_array_type(RARRAY_PTR(tmp)[i]);\n\t\tVALUE key, val = Qnil;\n\n\t\tif (NIL_P(v)) continue;\n\t\tswitch (RARRAY_LEN(v)) {\n\t\t  case 2:\n\t\t    val = RARRAY_PTR(v)[1];\n\t\t  case 1:\n\t\t    key = RARRAY_PTR(v)[0];\n\t\t    rb_hash_aset(hash, key, val);\n\t\t}\n\t    }\n\t    return hash;\n\t}\n    }\n    if (argc % 2 != 0) {\n\trb_raise(rb_eArgError, \"odd number of arguments for Hash\");\n    }\n\n    hash = hash_alloc(klass);\n    for (i=0; i<argc; i+=2) {\n        rb_hash_aset(hash, argv[i], argv[i + 1]);\n    }\n\n    return hash;\n}\n\nstatic VALUE\nto_hash(hash)\n    VALUE hash;\n{\n    return rb_convert_type(hash, T_HASH, \"Hash\", \"to_hash\");\n}\n\nstatic int\nrb_hash_rehash_i(key, value, tbl)\n    VALUE key, value;\n    st_table *tbl;\n{\n    if (key != Qundef) st_insert(tbl, key, value);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.rehash -> hsh\n *\n *  Rebuilds the hash based on the current hash values for each key. If\n *  values of key objects have changed since they were inserted, this\n *  method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is\n *  called while an iterator is traversing the hash, an\n *  <code>IndexError</code> will be raised in the iterator.\n *\n *     a = [ \"a\", \"b\" ]\n *     c = [ \"c\", \"d\" ]\n *     h = { a => 100, c => 300 }\n *     h[a]       #=> 100\n *     a[0] = \"z\"\n *     h[a]       #=> nil\n *     h.rehash   #=> {[\"z\", \"b\"]=>100, [\"c\", \"d\"]=>300}\n *     h[a]       #=> 100\n */\n\nstatic VALUE\nrb_hash_rehash(hash)\n    VALUE hash;\n{\n    st_table *tbl;\n\n    rb_hash_modify(hash);\n    tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);\n    rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);\n    st_free_table(RHASH(hash)->tbl);\n    RHASH(hash)->tbl = tbl;\n\n    return hash;\n}\n\n/*\n *  call-seq:\n *     hsh[key]    =>  value\n *\n *  Element Reference---Retrieves the <i>value</i> object corresponding\n *  to the <i>key</i> object. If not found, returns the a default value (see\n *  <code>Hash::new</code> for details).\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h[\"a\"]   #=> 100\n *     h[\"c\"]   #=> nil\n *\n */\n\nVALUE\nrb_hash_aref(hash, key)\n    VALUE hash, key;\n{\n    VALUE val;\n\n    if (!st_lookup(RHASH(hash)->tbl, key, &val)) {\n\treturn rb_funcall(hash, id_default, 1, key);\n    }\n    return val;\n}\n\nVALUE\nrb_hash_lookup(hash, key)\n    VALUE hash, key;\n{\n    VALUE val;\n\n    if (!st_lookup(RHASH(hash)->tbl, key, &val)) {\n\treturn Qnil; /* without Hash#default */\n    }\n    return val;\n}\n\n/*\n *  call-seq:\n *     hsh.fetch(key [, default] )       => obj\n *     hsh.fetch(key) {| key | block }   => obj\n *\n *  Returns a value from the hash for the given key. If the key can't be\n *  found, there are several options: With no other arguments, it will\n *  raise an <code>IndexError</code> exception; if <i>default</i> is\n *  given, then that will be returned; if the optional code block is\n *  specified, then that will be run and its result returned.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.fetch(\"a\")                            #=> 100\n *     h.fetch(\"z\", \"go fish\")                 #=> \"go fish\"\n *     h.fetch(\"z\") { |el| \"go fish, #{el}\"}   #=> \"go fish, z\"\n *\n *  The following example shows that an exception is raised if the key\n *  is not found and a default value is not supplied.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.fetch(\"z\")\n *\n *  <em>produces:</em>\n *\n *     prog.rb:2:in `fetch': key not found (IndexError)\n *      from prog.rb:2\n *\n */\n\nstatic VALUE\nrb_hash_fetch(argc, argv, hash)\n    int argc;\n    VALUE *argv;\n    VALUE hash;\n{\n    VALUE key, if_none;\n    VALUE val;\n    long block_given;\n\n    rb_scan_args(argc, argv, \"11\", &key, &if_none);\n\n    block_given = rb_block_given_p();\n    if (block_given && argc == 2) {\n\trb_warn(\"block supersedes default value argument\");\n    }\n    if (!st_lookup(RHASH(hash)->tbl, key, &val)) {\n\tif (block_given) return rb_yield(key);\n\tif (argc == 1) {\n\t    rb_raise(rb_eIndexError, \"key not found\");\n\t}\n\treturn if_none;\n    }\n    return val;\n}\n\n/*\n *  call-seq:\n *     hsh.default(key=nil)   => obj\n *\n *  Returns the default value, the value that would be returned by\n *  <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.\n *  See also <code>Hash::new</code> and <code>Hash#default=</code>.\n *\n *     h = Hash.new                            #=> {}\n *     h.default                               #=> nil\n *     h.default(2)                            #=> nil\n *\n *     h = Hash.new(\"cat\")                     #=> {}\n *     h.default                               #=> \"cat\"\n *     h.default(2)                            #=> \"cat\"\n *\n *     h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}\n *     h.default                               #=> nil\n *     h.default(2)                            #=> 20\n */\n\nstatic VALUE\nrb_hash_default(argc, argv, hash)\n    int argc;\n    VALUE *argv;\n    VALUE hash;\n{\n    VALUE key;\n\n    rb_scan_args(argc, argv, \"01\", &key);\n    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {\n\tif (argc == 0) return Qnil;\n\treturn rb_funcall(RHASH(hash)->ifnone, id_call, 2, hash, key);\n    }\n    return RHASH(hash)->ifnone;\n}\n\n/*\n *  call-seq:\n *     hsh.default = obj     => hsh\n *\n *  Sets the default value, the value returned for a key that does not\n *  exist in the hash. It is not possible to set the a default to a\n *  <code>Proc</code> that will be executed on each key lookup.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.default = \"Go fish\"\n *     h[\"a\"]     #=> 100\n *     h[\"z\"]     #=> \"Go fish\"\n *     # This doesn't do what you might hope...\n *     h.default = proc do |hash, key|\n *       hash[key] = key + key\n *     end\n *     h[2]       #=> #<Proc:0x401b3948@-:6>\n *     h[\"cat\"]   #=> #<Proc:0x401b3948@-:6>\n */\n\nstatic VALUE\nrb_hash_set_default(hash, ifnone)\n    VALUE hash, ifnone;\n{\n    rb_hash_modify(hash);\n    RHASH(hash)->ifnone = ifnone;\n    FL_UNSET(hash, HASH_PROC_DEFAULT);\n    return ifnone;\n}\n\n/*\n *  call-seq:\n *     hsh.default_proc -> anObject\n *\n *  If <code>Hash::new</code> was invoked with a block, return that\n *  block, otherwise return <code>nil</code>.\n *\n *     h = Hash.new {|h,k| h[k] = k*k }   #=> {}\n *     p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>\n *     a = []                             #=> []\n *     p.call(a, 2)\n *     a                                  #=> [nil, nil, 4]\n */\n\n\nstatic VALUE\nrb_hash_default_proc(hash)\n    VALUE hash;\n{\n    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {\n\treturn RHASH(hash)->ifnone;\n    }\n    return Qnil;\n}\n\nstatic int\nindex_i(key, value, args)\n    VALUE key, value;\n    VALUE *args;\n{\n    if (rb_equal(value, args[0])) {\n\targs[1] = key;\n\treturn ST_STOP;\n    }\n    return ST_CONTINUE;\n}\n\nstatic VALUE\nrb_hash_delete_key(hash, key)\n    VALUE hash, key;\n{\n    st_data_t ktmp = (st_data_t)key, val;\n\n    if (RHASH(hash)->iter_lev > 0) {\n\tif (st_delete_safe(RHASH(hash)->tbl, &ktmp, &val, Qundef)) {\n\t    FL_SET(hash, HASH_DELETED);\n\t    return (VALUE)val;\n\t}\n    }\n    else if (st_delete(RHASH(hash)->tbl, &ktmp, &val))\n\treturn (VALUE)val;\n    return Qundef;\n}\n\n/*\n *  call-seq:\n *     hsh.index(value)    => key\n *\n *  Returns the key for a given value. If not found, returns <code>nil</code>.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.index(200)   #=> \"b\"\n *     h.index(999)   #=> nil\n *\n */\n\nstatic VALUE\nrb_hash_index(hash, value)\n    VALUE hash, value;\n{\n    VALUE args[2];\n\n    args[0] = value;\n    args[1] = Qnil;\n\n    rb_hash_foreach(hash, index_i, (st_data_t)args);\n\n    return args[1];\n}\n\n/*\n *  call-seq:\n *     hsh.indexes(key, ...)    => array\n *     hsh.indices(key, ...)    => array\n *\n *  Deprecated in favor of <code>Hash#select</code>.\n *\n */\n\nstatic VALUE\nrb_hash_indexes(argc, argv, hash)\n    int argc;\n    VALUE *argv;\n    VALUE hash;\n{\n    VALUE indexes;\n    int i;\n\n    rb_warn(\"Hash#%s is deprecated; use Hash#values_at\",\n\t    rb_id2name(rb_frame_last_func()));\n    indexes = rb_ary_new2(argc);\n    for (i=0; i<argc; i++) {\n\tRARRAY(indexes)->ptr[i] = rb_hash_aref(hash, argv[i]);\n\tRARRAY(indexes)->len++;\n    }\n    return indexes;\n}\n\n/*\n *  call-seq:\n *     hsh.delete(key)                   => value\n *     hsh.delete(key) {| key | block }  => value\n *\n *  Deletes and returns a key-value pair from <i>hsh</i> whose key is\n *  equal to <i>key</i>. If the key is not found, returns <code>nil</code>.\n *  If the optional code block is given and the key is not found,\n *  pass in the key and return the result of <i>block</i>.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.delete(\"a\")                              #=> 100\n *     h.delete(\"z\")                              #=> nil\n *     h.delete(\"z\") { |el| \"#{el} not found\" }   #=> \"z not found\"\n *\n */\n\nVALUE\nrb_hash_delete(hash, key)\n    VALUE hash, key;\n{\n    VALUE val;\n\n    rb_hash_modify(hash);\n    val = rb_hash_delete_key(hash, key);\n    if (val != Qundef) return val;\n    if (rb_block_given_p()) {\n\treturn rb_yield(key);\n    }\n    return Qnil;\n}\n\nstruct shift_var {\n    VALUE key;\n    VALUE val;\n};\n\nstatic int\nshift_i(key, value, var)\n    VALUE key, value;\n    struct shift_var *var;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    if (var->key != Qundef) return ST_STOP;\n    var->key = key;\n    var->val = value;\n    return ST_DELETE;\n}\n\nstatic int\nshift_i_safe(key, value, var)\n    VALUE key, value;\n    struct shift_var *var;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    var->key = key;\n    var->val = value;\n    return ST_STOP;\n}\n\n/*\n *  call-seq:\n *     hsh.shift -> anArray or obj\n *\n *  Removes a key-value pair from <i>hsh</i> and returns it as the\n *  two-item array <code>[</code> <i>key, value</i> <code>]</code>, or\n *  the hash's default value if the hash is empty.\n *\n *     h = { 1 => \"a\", 2 => \"b\", 3 => \"c\" }\n *     h.shift   #=> [1, \"a\"]\n *     h         #=> {2=>\"b\", 3=>\"c\"}\n */\n\nstatic VALUE\nrb_hash_shift(hash)\n    VALUE hash;\n{\n    struct shift_var var;\n\n    rb_hash_modify(hash);\n    var.key = Qundef;\n    if (RHASH(hash)->iter_lev > 0) {\n\trb_hash_foreach(hash, shift_i_safe, (st_data_t)&var);\n\tif (var.key != Qundef) {\n\t    st_data_t key = var.key;\n\t    if (st_delete_safe(RHASH(hash)->tbl, &key, 0, Qundef)) {\n\t\tFL_SET(hash, HASH_DELETED);\n\t    }\n\t}\n    }\n    else {\n\trb_hash_foreach(hash, shift_i, (st_data_t)&var);\n    }\n\n    if (var.key != Qundef) {\n\treturn rb_assoc_new(var.key, var.val);\n    }\n    else if (FL_TEST(hash, HASH_PROC_DEFAULT)) {\n\treturn rb_funcall(RHASH(hash)->ifnone, id_call, 2, hash, Qnil);\n    }\n    else {\n\treturn RHASH(hash)->ifnone;\n    }\n}\n\nstatic int\ndelete_if_i(key, value, hash)\n    VALUE key, value, hash;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    if (RTEST(rb_yield_values(2, key, value))) {\n\trb_hash_delete_key(hash, key);\n    }\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.delete_if {| key, value | block }  -> hsh\n *\n *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>\n *  evaluates to <code>true</code>.\n *\n *     h = { \"a\" => 100, \"b\" => 200, \"c\" => 300 }\n *     h.delete_if {|key, value| key >= \"b\" }   #=> {\"a\"=>100}\n *\n */\n\nVALUE\nrb_hash_delete_if(hash)\n    VALUE hash;\n{\n    RETURN_ENUMERATOR(hash, 0, 0);\n    rb_hash_modify(hash);\n    rb_hash_foreach(hash, delete_if_i, hash);\n    return hash;\n}\n\n/*\n *  call-seq:\n *     hsh.reject! {| key, value | block }  -> hsh or nil\n *\n *  Equivalent to <code>Hash#delete_if</code>, but returns\n *  <code>nil</code> if no changes were made.\n */\n\nVALUE\nrb_hash_reject_bang(hash)\n    VALUE hash;\n{\n    int n;\n\n    RETURN_ENUMERATOR(hash, 0, 0);\n    n = RHASH(hash)->tbl->num_entries;\n    rb_hash_delete_if(hash);\n    if (n == RHASH(hash)->tbl->num_entries) return Qnil;\n    return hash;\n}\n\n/*\n *  call-seq:\n *     hsh.reject {| key, value | block }  -> a_hash\n *\n *  Same as <code>Hash#delete_if</code>, but works on (and returns) a\n *  copy of the <i>hsh</i>. Equivalent to\n *  <code><i>hsh</i>.dup.delete_if</code>.\n *\n */\n\nstatic VALUE\nrb_hash_reject(hash)\n    VALUE hash;\n{\n    return rb_hash_delete_if(rb_obj_dup(hash));\n}\n\nstatic int\nselect_i(key, value, result)\n    VALUE key, value, result;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    if (RTEST(rb_yield_values(2, key, value)))\n\trb_ary_push(result, rb_assoc_new(key, value));\n    return ST_CONTINUE;\n}\n\n/*\n * call-seq:\n *   hsh.values_at(key, ...)   => array\n *\n * Return an array containing the values associated with the given keys.\n * Also see <code>Hash.select</code>.\n *\n *   h = { \"cat\" => \"feline\", \"dog\" => \"canine\", \"cow\" => \"bovine\" }\n *   h.values_at(\"cow\", \"cat\")  #=> [\"bovine\", \"feline\"]\n */\n\nVALUE\nrb_hash_values_at(argc, argv, hash)\n    int argc;\n    VALUE *argv;\n    VALUE hash;\n{\n    VALUE result = rb_ary_new();\n    long i;\n\n    for (i=0; i<argc; i++) {\n\trb_ary_push(result, rb_hash_aref(hash, argv[i]));\n    }\n    return result;\n}\n\n/*\n *  call-seq:\n *     hsh.select {|key, value| block}   => array\n *\n *  Returns a new array consisting of <code>[key,value]</code>\n *  pairs for which the block returns true.\n *  Also see <code>Hash.values_at</code>.\n *\n *     h = { \"a\" => 100, \"b\" => 200, \"c\" => 300 }\n *     h.select {|k,v| k > \"a\"}  #=> [[\"b\", 200], [\"c\", 300]]\n *     h.select {|k,v| v < 200}  #=> [[\"a\", 100]]\n */\n\nVALUE\nrb_hash_select(hash)\n    VALUE hash;\n{\n    VALUE result;\n\n    RETURN_ENUMERATOR(hash, 0, 0);\n    result = rb_ary_new();\n    rb_hash_foreach(hash, select_i, result);\n    return result;\n}\n\nstatic int\nclear_i(key, value, dummy)\n    VALUE key, value, dummy;\n{\n    return ST_DELETE;\n}\n\n/*\n *  call-seq:\n *     hsh.clear -> hsh\n *\n *  Removes all key-value pairs from <i>hsh</i>.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }   #=> {\"a\"=>100, \"b\"=>200}\n *     h.clear                          #=> {}\n *\n */\n\nstatic VALUE\nrb_hash_clear(hash)\n    VALUE hash;\n{\n    rb_hash_modify(hash);\n    if (RHASH(hash)->tbl->num_entries > 0) {\n\trb_hash_foreach(hash, clear_i, 0);\n    }\n\n    return hash;\n}\n\n/*\n *  call-seq:\n *     hsh[key] = value        => value\n *     hsh.store(key, value)   => value\n *\n *  Element Assignment---Associates the value given by\n *  <i>value</i> with the key given by <i>key</i>.\n *  <i>key</i> should not have its value changed while it is in\n *  use as a key (a <code>String</code> passed as a key will be\n *  duplicated and frozen).\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h[\"a\"] = 9\n *     h[\"c\"] = 4\n *     h   #=> {\"a\"=>9, \"b\"=>200, \"c\"=>4}\n *\n */\n\nVALUE\nrb_hash_aset(hash, key, val)\n    VALUE hash, key, val;\n{\n    rb_hash_modify(hash);\n    if (TYPE(key) != T_STRING || st_lookup(RHASH(hash)->tbl, key, 0)) {\n\tst_insert(RHASH(hash)->tbl, key, val);\n    }\n    else {\n\tst_add_direct(RHASH(hash)->tbl, rb_str_new4(key), val);\n    }\n    return val;\n}\n\nstatic int\nreplace_i(key, val, hash)\n    VALUE key, val, hash;\n{\n    if (key != Qundef) {\n\trb_hash_aset(hash, key, val);\n    }\n\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.replace(other_hash) -> hsh\n *\n *  Replaces the contents of <i>hsh</i> with the contents of\n *  <i>other_hash</i>.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.replace({ \"c\" => 300, \"d\" => 400 })   #=> {\"c\"=>300, \"d\"=>400}\n *\n */\n\nstatic VALUE\nrb_hash_replace(hash, hash2)\n    VALUE hash, hash2;\n{\n    hash2 = to_hash(hash2);\n    if (hash == hash2) return hash;\n    rb_hash_clear(hash);\n    rb_hash_foreach(hash2, replace_i, hash);\n    RHASH(hash)->ifnone = RHASH(hash2)->ifnone;\n    if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {\n\tFL_SET(hash, HASH_PROC_DEFAULT);\n    }\n    else {\n\tFL_UNSET(hash, HASH_PROC_DEFAULT);\n    }\n\n    return hash;\n}\n\n/*\n *  call-seq:\n *     hsh.length    =>  fixnum\n *     hsh.size      =>  fixnum\n *\n *  Returns the number of key-value pairs in the hash.\n *\n *     h = { \"d\" => 100, \"a\" => 200, \"v\" => 300, \"e\" => 400 }\n *     h.length        #=> 4\n *     h.delete(\"a\")   #=> 200\n *     h.length        #=> 3\n */\n\nstatic VALUE\nrb_hash_size(hash)\n    VALUE hash;\n{\n    return INT2FIX(RHASH(hash)->tbl->num_entries);\n}\n\n\n/*\n *  call-seq:\n *     hsh.empty?    => true or false\n *\n *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.\n *\n *     {}.empty?   #=> true\n *\n */\n\nstatic VALUE\nrb_hash_empty_p(hash)\n    VALUE hash;\n{\n    if (RHASH(hash)->tbl->num_entries == 0)\n\treturn Qtrue;\n    return Qfalse;\n}\n\nstatic int\neach_value_i(key, value)\n    VALUE key, value;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_yield(value);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.each_value {| value | block } -> hsh\n *\n *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the\n *  value as a parameter.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.each_value {|value| puts value }\n *\n *  <em>produces:</em>\n *\n *     100\n *     200\n */\n\nstatic VALUE\nrb_hash_each_value(hash)\n    VALUE hash;\n{\n    RETURN_ENUMERATOR(hash, 0, 0);\n    rb_hash_foreach(hash, each_value_i, 0);\n    return hash;\n}\n\nstatic int\neach_key_i(key, value)\n    VALUE key, value;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_yield(key);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.each_key {| key | block } -> hsh\n *\n *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key\n *  as a parameter.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.each_key {|key| puts key }\n *\n *  <em>produces:</em>\n *\n *     a\n *     b\n */\nstatic VALUE\nrb_hash_each_key(hash)\n    VALUE hash;\n{\n    RETURN_ENUMERATOR(hash, 0, 0);\n    rb_hash_foreach(hash, each_key_i, 0);\n    return hash;\n}\n\nstatic int\neach_pair_i(key, value)\n    VALUE key, value;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_yield_values(2, key, value);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.each_pair {| key_value_array | block } -> hsh\n *\n *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key\n *  and value as parameters.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.each_pair {|key, value| puts \"#{key} is #{value}\" }\n *\n *  <em>produces:</em>\n *\n *     a is 100\n *     b is 200\n *\n */\n\nstatic VALUE\nrb_hash_each_pair(hash)\n    VALUE hash;\n{\n    RETURN_ENUMERATOR(hash, 0, 0);\n    rb_hash_foreach(hash, each_pair_i, 0);\n    return hash;\n}\n\nstatic int\neach_i(key, value)\n    VALUE key, value;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_yield(rb_assoc_new(key, value));\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.each {| key, value | block } -> hsh\n *\n *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key\n *  and value to the block as a two-element array. Because of the assignment\n *  semantics of block parameters, these elements will be split out if the\n *  block has two formal parameters. Also see <code>Hash.each_pair</code>, which\n *  will be marginally more efficient for blocks with two parameters.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.each {|key, value| puts \"#{key} is #{value}\" }\n *\n *  <em>produces:</em>\n *\n *     a is 100\n *     b is 200\n *\n */\n\nstatic VALUE\nrb_hash_each(hash)\n    VALUE hash;\n{\n    RETURN_ENUMERATOR(hash, 0, 0);\n    rb_hash_foreach(hash, each_i, 0);\n    return hash;\n}\n\nstatic int\nto_a_i(key, value, ary)\n    VALUE key, value, ary;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_ary_push(ary, rb_assoc_new(key, value));\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.to_a -> array\n *\n *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,\n *  value</i> <code>]</code> arrays.\n *\n *     h = { \"c\" => 300, \"a\" => 100, \"d\" => 400, \"c\" => 300  }\n *     h.to_a   #=> [[\"a\", 100], [\"c\", 300], [\"d\", 400]]\n */\n\nstatic VALUE\nrb_hash_to_a(hash)\n    VALUE hash;\n{\n    VALUE ary;\n\n    ary = rb_ary_new();\n    rb_hash_foreach(hash, to_a_i, ary);\n    if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     hsh.sort                    => array\n *     hsh.sort {| a, b | block }  => array\n *\n *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,\n *  value</i> <code>]</code> arrays and sorts it, using\n *  <code>Array#sort</code>.\n *\n *     h = { \"a\" => 20, \"b\" => 30, \"c\" => 10  }\n *     h.sort                       #=> [[\"a\", 20], [\"b\", 30], [\"c\", 10]]\n *     h.sort {|a,b| a[1]<=>b[1]}   #=> [[\"c\", 10], [\"a\", 20], [\"b\", 30]]\n *\n */\n\nstatic VALUE\nrb_hash_sort(hash)\n    VALUE hash;\n{\n    VALUE entries = rb_hash_to_a(hash);\n    rb_ary_sort_bang(entries);\n    return entries;\n}\n\nstatic int\ninspect_i(key, value, str)\n    VALUE key, value, str;\n{\n    VALUE str2;\n\n    if (key == Qundef) return ST_CONTINUE;\n    if (RSTRING(str)->len > 1) {\n\trb_str_cat2(str, \", \");\n    }\n    str2 = rb_inspect(key);\n    rb_str_buf_append(str, str2);\n    OBJ_INFECT(str, str2);\n    rb_str_buf_cat2(str, \"=>\");\n    str2 = rb_inspect(value);\n    rb_str_buf_append(str, str2);\n    OBJ_INFECT(str, str2);\n\n    return ST_CONTINUE;\n}\n\nstatic VALUE\ninspect_hash(hash)\n    VALUE hash;\n{\n    VALUE str;\n\n    str = rb_str_buf_new2(\"{\");\n    rb_hash_foreach(hash, inspect_i, str);\n    rb_str_buf_cat2(str, \"}\");\n    OBJ_INFECT(str, hash);\n\n    return str;\n}\n\n/*\n * call-seq:\n *   hsh.inspect  => string\n *\n * Return the contents of this hash as a string.\n */\n\nstatic VALUE\nrb_hash_inspect(hash)\n    VALUE hash;\n{\n    if (RHASH(hash)->tbl == 0 || RHASH(hash)->tbl->num_entries == 0)\n\treturn rb_str_new2(\"{}\");\n    if (rb_inspecting_p(hash)) return rb_str_new2(\"{...}\");\n    return rb_protect_inspect(inspect_hash, hash, 0);\n}\n\nstatic VALUE\nto_s_hash(hash)\n    VALUE hash;\n{\n    return rb_ary_to_s(rb_hash_to_a(hash));\n}\n\n/*\n *  call-seq:\n *     hsh.to_s   => string\n *\n *  Converts <i>hsh</i> to a string by converting the hash to an array\n *  of <code>[</code> <i>key, value</i> <code>]</code> pairs and then\n *  converting that array to a string using <code>Array#join</code> with\n *  the default separator.\n *\n *     h = { \"c\" => 300, \"a\" => 100, \"d\" => 400, \"c\" => 300  }\n *     h.to_s   #=> \"a100c300d400\"\n */\n\nstatic VALUE\nrb_hash_to_s(hash)\n    VALUE hash;\n{\n    if (rb_inspecting_p(hash)) return rb_str_new2(\"{...}\");\n    return rb_protect_inspect(to_s_hash, hash, 0);\n}\n\n/*\n * call-seq:\n *    hsh.to_hash   => hsh\n *\n * Returns <i>self</i>.\n */\n\nstatic VALUE\nrb_hash_to_hash(hash)\n    VALUE hash;\n{\n    return hash;\n}\n\nstatic int\nkeys_i(key, value, ary)\n    VALUE key, value, ary;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_ary_push(ary, key);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.keys    => array\n *\n *  Returns a new array populated with the keys from this hash. See also\n *  <code>Hash#values</code>.\n *\n *     h = { \"a\" => 100, \"b\" => 200, \"c\" => 300, \"d\" => 400 }\n *     h.keys   #=> [\"a\", \"b\", \"c\", \"d\"]\n *\n */\n\nstatic VALUE\nrb_hash_keys(hash)\n    VALUE hash;\n{\n    VALUE ary;\n\n    ary = rb_ary_new();\n    rb_hash_foreach(hash, keys_i, ary);\n\n    return ary;\n}\n\nstatic int\nvalues_i(key, value, ary)\n    VALUE key, value, ary;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_ary_push(ary, value);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.values    => array\n *\n *  Returns a new array populated with the values from <i>hsh</i>. See\n *  also <code>Hash#keys</code>.\n *\n *     h = { \"a\" => 100, \"b\" => 200, \"c\" => 300 }\n *     h.values   #=> [100, 200, 300]\n *\n */\n\nstatic VALUE\nrb_hash_values(hash)\n    VALUE hash;\n{\n    VALUE ary;\n\n    ary = rb_ary_new();\n    rb_hash_foreach(hash, values_i, ary);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     hsh.has_key?(key)    => true or false\n *     hsh.include?(key)    => true or false\n *     hsh.key?(key)        => true or false\n *     hsh.member?(key)     => true or false\n *\n *  Returns <code>true</code> if the given key is present in <i>hsh</i>.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.has_key?(\"a\")   #=> true\n *     h.has_key?(\"z\")   #=> false\n *\n */\n\nstatic VALUE\nrb_hash_has_key(hash, key)\n    VALUE hash;\n    VALUE key;\n{\n    if (st_lookup(RHASH(hash)->tbl, key, 0)) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\nstatic int\nrb_hash_search_value(key, value, data)\n    VALUE key, value, *data;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    if (rb_equal(value, data[1])) {\n\tdata[0] = Qtrue;\n\treturn ST_STOP;\n    }\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.has_value?(value)    => true or false\n *     hsh.value?(value)        => true or false\n *\n *  Returns <code>true</code> if the given value is present for some key\n *  in <i>hsh</i>.\n *\n *     h = { \"a\" => 100, \"b\" => 200 }\n *     h.has_value?(100)   #=> true\n *     h.has_value?(999)   #=> false\n */\n\nstatic VALUE\nrb_hash_has_value(hash, val)\n    VALUE hash;\n    VALUE val;\n{\n    VALUE data[2];\n\n    data[0] = Qfalse;\n    data[1] = val;\n    rb_hash_foreach(hash, rb_hash_search_value, (st_data_t)data);\n    return data[0];\n}\n\nstruct equal_data {\n    int result;\n    st_table *tbl;\n    int eql;\n};\n\nstatic int\neql_i(key, val1, data)\n    VALUE key;\n    VALUE val1;\n    struct equal_data *data;\n{\n    VALUE val2;\n\n    if (key == Qundef) return ST_CONTINUE;\n    if (!st_lookup(data->tbl, key, &val2)) {\n\tdata->result = Qfalse;\n\treturn ST_STOP;\n    }\n    if (!(data->eql ? rb_eql(val1, val2) : rb_equal(val1, val2))) {\n\tdata->result = Qfalse;\n\treturn ST_STOP;\n    }\n    return ST_CONTINUE;\n}\n\nstatic VALUE recursive_eql _((VALUE, VALUE, int));\nstatic VALUE\nrecursive_eql(hash, dt, recur)\n    VALUE hash;\n    VALUE dt;\n    int recur;\n{\n    struct equal_data *data;\n\n    if (recur) return Qfalse;\n    data = (struct equal_data*)dt;\n    data->result = Qtrue;\n    rb_hash_foreach(hash, eql_i, (st_data_t)data);\n\n    return data->result;\n}\n\nstatic VALUE\nhash_equal(hash1, hash2, eql)\n    VALUE hash1, hash2;\n    int eql;\t\t\t/* compare default value if true */\n{\n    struct equal_data data;\n\n    if (hash1 == hash2) return Qtrue;\n    if (TYPE(hash2) != T_HASH) {\n\tif (!rb_respond_to(hash2, rb_intern(\"to_hash\"))) {\n\t    return Qfalse;\n\t}\n\treturn rb_equal(hash2, hash1);\n    }\n    if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)\n\treturn Qfalse;\n    if (eql) {\n\tif (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) &&\n\t      FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))\n\t    return Qfalse;\n    }\n\n    data.tbl = RHASH(hash2)->tbl;\n    data.eql = eql;\n    return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data);\n}\n\n/*\n *  call-seq:\n *     hsh == other_hash    => true or false\n *\n *  Equality---Two hashes are equal if they each contain the same number\n *  of keys and if each key-value pair is equal to (according to\n *  <code>Object#==</code>) the corresponding elements in the other\n *  hash.\n *\n *     h1 = { \"a\" => 1, \"c\" => 2 }\n *     h2 = { 7 => 35, \"c\" => 2, \"a\" => 1 }\n *     h3 = { \"a\" => 1, \"c\" => 2, 7 => 35 }\n *     h4 = { \"a\" => 1, \"d\" => 2, \"f\" => 35 }\n *     h1 == h2   #=> false\n *     h2 == h3   #=> true\n *     h3 == h4   #=> false\n *\n */\n\nstatic VALUE\nrb_hash_equal(hash1, hash2)\n    VALUE hash1, hash2;\n{\n    return hash_equal(hash1, hash2, Qfalse);\n}\n\nstatic int\nhash_i(key, val, hval)\n    VALUE key;\n    VALUE val;\n    int *hval;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    *hval ^= rb_hash(key);\n    *hval ^= rb_hash(val);\n    return ST_CONTINUE;\n}\n\nstatic VALUE recursive_hash _((VALUE, VALUE, int));\nstatic VALUE\nrecursive_hash(hash, dummy, recur)\n    VALUE hash;\n    VALUE dummy;\n    int recur;\n{\n    int hval;\n\n    if (recur) {\n\treturn LONG2FIX(0);\n    }\n    hval = RHASH(hash)->tbl->num_entries;\n    rb_hash_foreach(hash, hash_i, (st_data_t)&hval);\n    return INT2FIX(hval);\n}\n\n/*\n *  call-seq:\n *     array.hash   -> fixnum\n *\n *  Compute a hash-code for this array. Two arrays with the same content\n *  will have the same hash code (and will compare using <code>eql?</code>).\n */\n\nstatic VALUE\nrb_hash_hash(hash)\n    VALUE hash;\n{\n    return rb_exec_recursive(recursive_hash, hash, 0);\n}\n\n\n/*\n *  call-seq:\n *     hash.eql?(other)  -> true or false\n *\n *  Returns <code>true</code> if <i>hash</i> and <i>other</i> are\n *  both hashes with the same content.\n */\n\nstatic VALUE\nrb_hash_eql(hash1, hash2)\n    VALUE hash1, hash2;\n{\n    return hash_equal(hash1, hash2, Qtrue);\n}\n\nstatic int\nrb_hash_invert_i(key, value, hash)\n    VALUE key, value;\n    VALUE hash;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_hash_aset(hash, value, key);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.invert -> aHash\n *\n *  Returns a new hash created by using <i>hsh</i>'s values as keys, and\n *  the keys as values.\n *\n *     h = { \"n\" => 100, \"m\" => 100, \"y\" => 300, \"d\" => 200, \"a\" => 0 }\n *     h.invert   #=> {0=>\"a\", 100=>\"n\", 200=>\"d\", 300=>\"y\"}\n *\n */\n\nstatic VALUE\nrb_hash_invert(hash)\n    VALUE hash;\n{\n    VALUE h = rb_hash_new();\n\n    rb_hash_foreach(hash, rb_hash_invert_i, h);\n    return h;\n}\n\nstatic int\nrb_hash_update_i(key, value, hash)\n    VALUE key, value;\n    VALUE hash;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    rb_hash_aset(hash, key, value);\n    return ST_CONTINUE;\n}\n\nstatic int\nrb_hash_update_block_i(key, value, hash)\n    VALUE key, value;\n    VALUE hash;\n{\n    if (key == Qundef) return ST_CONTINUE;\n    if (rb_hash_has_key(hash, key)) {\n\tvalue = rb_yield_values(3, key, rb_hash_aref(hash, key), value);\n    }\n    rb_hash_aset(hash, key, value);\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     hsh.merge!(other_hash)                                 => hsh\n *     hsh.update(other_hash)                                 => hsh\n *     hsh.merge!(other_hash){|key, oldval, newval| block}    => hsh\n *     hsh.update(other_hash){|key, oldval, newval| block}    => hsh\n *\n *  Adds the contents of <i>other_hash</i> to <i>hsh</i>.  If no\n *  block is specified entries with duplicate keys are overwritten\n *  with the values from <i>other_hash</i>, otherwise the value\n *  of each duplicate key is determined by calling the block with\n *  the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.\n *\n *     h1 = { \"a\" => 100, \"b\" => 200 }\n *     h2 = { \"b\" => 254, \"c\" => 300 }\n *     h1.merge!(h2)   #=> {\"a\"=>100, \"b\"=>254, \"c\"=>300}\n *\n *     h1 = { \"a\" => 100, \"b\" => 200 }\n *     h2 = { \"b\" => 254, \"c\" => 300 }\n *     h1.merge!(h2) { |key, v1, v2| v1 }\n *                     #=> {\"a\"=>100, \"b\"=>200, \"c\"=>300}\n */\n\nstatic VALUE\nrb_hash_update(hash1, hash2)\n    VALUE hash1, hash2;\n{\n    hash2 = to_hash(hash2);\n    if (rb_block_given_p()) {\n\trb_hash_foreach(hash2, rb_hash_update_block_i, hash1);\n    }\n    else {\n\trb_hash_foreach(hash2, rb_hash_update_i, hash1);\n    }\n    return hash1;\n}\n\n/*\n *  call-seq:\n *     hsh.merge(other_hash)                              -> a_hash\n *     hsh.merge(other_hash){|key, oldval, newval| block} -> a_hash\n *\n *  Returns a new hash containing the contents of <i>other_hash</i> and\n *  the contents of <i>hsh</i>, overwriting entries in <i>hsh</i> with\n *  duplicate keys with those from <i>other_hash</i>.\n *\n *     h1 = { \"a\" => 100, \"b\" => 200 }\n *     h2 = { \"b\" => 254, \"c\" => 300 }\n *     h1.merge(h2)   #=> {\"a\"=>100, \"b\"=>254, \"c\"=>300}\n *     h1             #=> {\"a\"=>100, \"b\"=>200}\n *\n */\n\nstatic VALUE\nrb_hash_merge(hash1, hash2)\n    VALUE hash1, hash2;\n{\n    return rb_hash_update(rb_obj_dup(hash1), hash2);\n}\n\nstatic int path_tainted = -1;\n\nstatic char **origenviron;\n#ifdef _WIN32\n#define GET_ENVIRON(e) (e = rb_w32_get_environ())\n#define FREE_ENVIRON(e) rb_w32_free_environ(e)\nstatic char **my_environ;\n#undef environ\n#define environ my_environ\n#elif defined(__APPLE__)\n#undef environ\n#define environ (*_NSGetEnviron())\n#define GET_ENVIRON(e) (e)\n#define FREE_ENVIRON(e)\n#else\nextern char **environ;\n#define GET_ENVIRON(e) (e)\n#define FREE_ENVIRON(e)\n#endif\n\nstatic VALUE\nenv_str_new(ptr, len)\n    const char *ptr;\n    long len;\n{\n    VALUE str = rb_tainted_str_new(ptr, len);\n\n    rb_obj_freeze(str);\n    return str;\n}\n\nstatic VALUE\nenv_str_new2(ptr)\n    const char *ptr;\n{\n    if (!ptr) return Qnil;\n    return env_str_new(ptr, strlen(ptr));\n}\n\nstatic VALUE\nenv_delete(obj, name)\n    VALUE obj, name;\n{\n    char *nam, *val;\n\n    rb_secure(4);\n    SafeStringValue(name);\n    nam = RSTRING(name)->ptr;\n    if (strlen(nam) != RSTRING(name)->len) {\n\trb_raise(rb_eArgError, \"bad environment variable name\");\n    }\n    val = getenv(nam);\n    if (val) {\n\tVALUE value = env_str_new2(val);\n\n\truby_setenv(nam, 0);\n#ifdef ENV_IGNORECASE\n\tif (strcasecmp(nam, PATH_ENV) == 0)\n#else\n\tif (strcmp(nam, PATH_ENV) == 0)\n#endif\n\t{\n\t    path_tainted = 0;\n\t}\n\treturn value;\n    }\n    return Qnil;\n}\n\nstatic VALUE\nenv_delete_m(obj, name)\n    VALUE obj, name;\n{\n    VALUE val;\n\n    val = env_delete(obj, name);\n    if (NIL_P(val) && rb_block_given_p()) rb_yield(name);\n    return val;\n}\n\nstatic VALUE\nrb_f_getenv(obj, name)\n    VALUE obj, name;\n{\n    char *nam, *env;\n\n    rb_secure(4);\n    SafeStringValue(name);\n    nam = RSTRING(name)->ptr;\n    if (strlen(nam) != RSTRING(name)->len) {\n\trb_raise(rb_eArgError, \"bad environment variable name\");\n    }\n    env = getenv(nam);\n    if (env) {\n#ifdef ENV_IGNORECASE\n\tif (strcasecmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted())\n#else\n\tif (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted())\n#endif\n\t{\n\t    VALUE str = rb_str_new2(env);\n\n\t    rb_obj_freeze(str);\n\t    return str;\n\t}\n\treturn env_str_new2(env);\n    }\n    return Qnil;\n}\n\nstatic VALUE\nenv_fetch(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE key, if_none;\n    long block_given;\n    char *nam, *env;\n\n    rb_secure(4);\n    rb_scan_args(argc, argv, \"11\", &key, &if_none);\n    block_given = rb_block_given_p();\n    if (block_given && argc == 2) {\n\trb_warn(\"block supersedes default value argument\");\n    }\n    SafeStringValue(key);\n    nam = RSTRING(key)->ptr;\n    if (strlen(nam) != RSTRING(key)->len) {\n\trb_raise(rb_eArgError, \"bad environment variable name\");\n    }\n    env = getenv(nam);\n    if (!env) {\n\tif (block_given) return rb_yield(key);\n\tif (argc == 1) {\n\t    rb_raise(rb_eIndexError, \"key not found\");\n\t}\n\treturn if_none;\n    }\n#ifdef ENV_IGNORECASE\n    if (strcasecmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted())\n#else\n    if (strcmp(nam, PATH_ENV) == 0 && !rb_env_path_tainted())\n#endif\n\treturn rb_str_new2(env);\n    return env_str_new2(env);\n}\n\nstatic void\npath_tainted_p(path)\n    char *path;\n{\n    path_tainted = rb_path_check(path)?0:1;\n}\n\nint\nrb_env_path_tainted()\n{\n    if (path_tainted < 0) {\n\tpath_tainted_p(getenv(PATH_ENV));\n    }\n    return path_tainted;\n}\n\n#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))\n#elif defined __sun__\nstatic int\nin_origenv(str)\n    const char *str;\n{\n    char **env;\n    for (env = origenviron; *env; ++env) {\n\tif (*env == str) return 1;\n    }\n    return 0;\n}\n#else\nstatic int\nenvix(nam)\n    const char *nam;\n{\n    register int i, len = strlen(nam);\n    char **env;\n\n    env = GET_ENVIRON(environ);\n    for (i = 0; env[i]; i++) {\n\tif (\n#ifdef ENV_IGNORECASE\n\t    strncasecmp(env[i],nam,len) == 0\n#else\n\t    memcmp(env[i],nam,len) == 0\n#endif\n\t    && env[i][len] == '=')\n\t    break;\t\t\t/* memcmp must come first to avoid */\n    }\t\t\t\t\t/* potential SEGV's */\n    FREE_ENVIRON(environ);\n    return i;\n}\n#endif\n\nvoid\nruby_setenv(name, value)\n    const char *name;\n    const char *value;\n{\n#if defined(_WIN32)\n    /* The sane way to deal with the environment.\n     * Has these advantages over putenv() & co.:\n     *  * enables us to store a truly empty value in the\n     *    environment (like in UNIX).\n     *  * we don't have to deal with RTL globals, bugs and leaks.\n     *  * Much faster.\n     * Why you may want to enable USE_WIN32_RTL_ENV:\n     *  * environ[] and RTL functions will not reflect changes,\n     *    which might be an issue if extensions want to access\n     *    the env. via RTL.  This cuts both ways, since RTL will\n     *    not see changes made by extensions that call the Win32\n     *    functions directly, either.\n     * GSAR 97-06-07\n     *\n     * REMARK: USE_WIN32_RTL_ENV is already obsoleted since we don't use\n     *         RTL's environ global variable directly yet.\n     */\n    SetEnvironmentVariable(name,value);\n#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)\n#undef setenv\n#undef unsetenv\n    if (value)\n\tsetenv(name,value,1);\n    else\n\tunsetenv(name);\n#elif defined __sun__\n    size_t len = strlen(name);\n    char **env_ptr, *str;\n    for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {\n\tif (!strncmp(str, name, len) && str[len] == '=') {\n\t    if (!in_origenv(str)) free(str);\n\t    while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;\n\t    break;\n\t}\n    }\n    if (value) {\n\tstr = malloc(len += strlen(value) + 2);\n\tsnprintf(str, len, \"%s=%s\", name, value);\n\tputenv(str);\n    }\n#else  /* WIN32 */\n    size_t len;\n    int i=envix(name);\t\t        /* where does it go? */\n\n    if (environ == origenviron) {\t/* need we copy environment? */\n\tint j;\n\tint max;\n\tchar **tmpenv;\n\n\tfor (max = i; environ[max]; max++) ;\n\ttmpenv = ALLOC_N(char*, max+2);\n\tfor (j=0; j<max; j++)\t\t/* copy environment */\n\t    tmpenv[j] = strdup(environ[j]);\n\ttmpenv[max] = 0;\n\tenviron = tmpenv;\t\t/* tell exec where it is now */\n    }\n    if (environ[i]) {\n\tchar **envp = origenviron;\n\twhile (*envp && *envp != environ[i]) envp++;\n\tif (!*envp)\n\t    free(environ[i]);\n\tif (!value) {\n\t    while (environ[i]) {\n\t\tenviron[i] = environ[i+1];\n\t\ti++;\n\t    }\n\t    return;\n\t}\n    }\n    else {\t\t\t/* does not exist yet */\n\tif (!value) return;\n\tREALLOC_N(environ, char*, i+2);\t/* just expand it a bit */\n\tenviron[i+1] = 0;\t/* make sure it's null terminated */\n    }\n    len = strlen(name) + strlen(value) + 2;\n    environ[i] = ALLOC_N(char, len);\n#ifndef MSDOS\n    snprintf(environ[i],len,\"%s=%s\",name,value); /* all that work just for this */\n#else\n    /* MS-DOS requires environment variable names to be in uppercase */\n    /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but\n     * some utilities and applications may break because they only look\n     * for upper case strings. (Fixed strupr() bug here.)]\n     */\n    strcpy(environ[i],name); strupr(environ[i]);\n    sprintf(environ[i] + strlen(name),\"=%s\", value);\n#endif /* MSDOS */\n\n#endif /* WIN32 */\n}\n\nvoid\nruby_unsetenv(name)\n    const char *name;\n{\n    ruby_setenv(name, 0);\n}\n\nstatic VALUE\nenv_aset(obj, nm, val)\n    VALUE obj, nm, val;\n{\n    char *name, *value;\n\n    if (rb_safe_level() >= 4) {\n\trb_raise(rb_eSecurityError, \"can't change environment variable\");\n    }\n\n    if (NIL_P(val)) {\n\tenv_delete(obj, nm);\n\treturn Qnil;\n    }\n\n    StringValue(nm);\n    StringValue(val);\n    name = RSTRING(nm)->ptr;\n    value = RSTRING(val)->ptr;\n    if (strlen(name) != RSTRING(nm)->len)\n\trb_raise(rb_eArgError, \"bad environment variable name\");\n    if (strlen(value) != RSTRING(val)->len)\n\trb_raise(rb_eArgError, \"bad environment variable value\");\n\n    ruby_setenv(name, value);\n#ifdef ENV_IGNORECASE\n    if (strcasecmp(name, PATH_ENV) == 0) {\n#else\n    if (strcmp(name, PATH_ENV) == 0) {\n#endif\n\tif (OBJ_TAINTED(val)) {\n\t    /* already tainted, no check */\n\t    path_tainted = 1;\n\t    return val;\n\t}\n\telse {\n\t    path_tainted_p(value);\n\t}\n    }\n    return val;\n}\n\nstatic VALUE\nenv_keys()\n{\n    char **env;\n    VALUE ary;\n\n    rb_secure(4);\n    ary = rb_ary_new();\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    rb_ary_push(ary, env_str_new(*env, s-*env));\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    return ary;\n}\n\nstatic VALUE\nenv_each_key(ehash)\n    VALUE ehash;\n{\n    VALUE keys;\n    long i;\n\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    keys = env_keys();\t/* rb_secure(4); */\n    for (i=0; i<RARRAY(keys)->len; i++) {\n\trb_yield(RARRAY(keys)->ptr[i]);\n    }\n    return ehash;\n}\n\nstatic VALUE\nenv_values()\n{\n    VALUE ary;\n    char **env;\n\n    rb_secure(4);\n    ary = rb_ary_new();\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    rb_ary_push(ary, env_str_new2(s+1));\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    return ary;\n}\n\nstatic VALUE\nenv_each_value(ehash)\n    VALUE ehash;\n{\n    VALUE values;\n    long i;\n\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    values = env_values();\t/* rb_secure(4); */\n    for (i=0; i<RARRAY(values)->len; i++) {\n\trb_yield(RARRAY(values)->ptr[i]);\n    }\n    return ehash;\n}\n\nstatic VALUE\nenv_each_i(ehash, values)\n    VALUE ehash;\n    int values;\n{\n    char **env;\n    VALUE ary;\n    long i;\n\n    rb_secure(4);\n    ary = rb_ary_new();\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    rb_ary_push(ary, env_str_new(*env, s-*env));\n\t    rb_ary_push(ary, env_str_new2(s+1));\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n\n    for (i=0; i<RARRAY(ary)->len; i+=2) {\n\tif (values) {\n\t    rb_yield_values(2, RARRAY(ary)->ptr[i], RARRAY(ary)->ptr[i+1]);\n\t}\n\telse {\n\t    rb_yield(rb_assoc_new(RARRAY(ary)->ptr[i], RARRAY(ary)->ptr[i+1]));\n\t}\n    }\n    return ehash;\n}\n\nstatic VALUE\nenv_each(ehash)\n    VALUE ehash;\n{\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    return env_each_i(ehash, Qfalse);\n}\n\nstatic VALUE\nenv_each_pair(ehash)\n    VALUE ehash;\n{\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    return env_each_i(ehash, Qtrue);\n}\n\nstatic VALUE\nenv_reject_bang(ehash)\n    VALUE ehash;\n{\n    volatile VALUE keys;\n    long i;\n    int del = 0;\n\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    keys = env_keys();\t/* rb_secure(4); */\n    for (i=0; i<RARRAY(keys)->len; i++) {\n\tVALUE val = rb_f_getenv(Qnil, RARRAY(keys)->ptr[i]);\n\tif (!NIL_P(val)) {\n\t    if (RTEST(rb_yield_values(2, RARRAY(keys)->ptr[i], val))) {\n\t\tFL_UNSET(RARRAY(keys)->ptr[i], FL_TAINT);\n\t\tenv_delete(Qnil, RARRAY(keys)->ptr[i]);\n\t\tdel++;\n\t    }\n\t}\n    }\n    if (del == 0) return Qnil;\n    return envtbl;\n}\n\nstatic VALUE\nenv_delete_if(ehash)\n    VALUE ehash;\n{\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    env_reject_bang(ehash);\n    return envtbl;\n}\n\nstatic VALUE\nenv_values_at(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE result;\n    long i;\n\n    rb_secure(4);\n    result = rb_ary_new();\n    for (i=0; i<argc; i++) {\n\trb_ary_push(result, rb_f_getenv(Qnil, argv[i]));\n    }\n    return result;\n}\n\nstatic VALUE\nenv_select(ehash)\n    VALUE ehash;\n{\n    VALUE result;\n    char **env;\n\n    RETURN_ENUMERATOR(ehash, 0, 0);\n    rb_secure(4);\n    result = rb_ary_new();\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    VALUE k = env_str_new(*env, s-*env);\n\t    VALUE v = env_str_new2(s+1);\n\t    if (RTEST(rb_yield_values(2, k, v))) {\n\t\trb_ary_push(result, rb_assoc_new(k, v));\n\t    }\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n\n    return result;\n}\n\nstatic VALUE\nenv_clear()\n{\n    volatile VALUE keys;\n    long i;\n\n    keys = env_keys();\t/* rb_secure(4); */\n    for (i=0; i<RARRAY(keys)->len; i++) {\n\tVALUE val = rb_f_getenv(Qnil, RARRAY(keys)->ptr[i]);\n\tif (!NIL_P(val)) {\n\t    env_delete(Qnil, RARRAY(keys)->ptr[i]);\n\t}\n    }\n    return envtbl;\n}\n\nstatic VALUE\nenv_to_s()\n{\n    return rb_str_new2(\"ENV\");\n}\n\nstatic VALUE\nenv_inspect()\n{\n    char **env;\n    VALUE str, i;\n\n    rb_secure(4);\n    str = rb_str_buf_new2(\"{\");\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\n\tif (env != environ) {\n\t    rb_str_buf_cat2(str, \", \");\n\t}\n\tif (s) {\n\t    rb_str_buf_cat2(str, \"\\\"\");\n\t    rb_str_buf_cat(str, *env, s-*env);\n\t    rb_str_buf_cat2(str, \"\\\"=>\");\n\t    i = rb_inspect(rb_str_new2(s+1));\n\t    rb_str_buf_append(str, i);\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    rb_str_buf_cat2(str, \"}\");\n    OBJ_TAINT(str);\n\n    return str;\n}\n\nstatic VALUE\nenv_to_a()\n{\n    char **env;\n    VALUE ary;\n\n    rb_secure(4);\n    ary = rb_ary_new();\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),\n\t\t\t\t\t  env_str_new2(s+1)));\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    return ary;\n}\n\nstatic VALUE\nenv_none()\n{\n    return Qnil;\n}\n\nstatic VALUE\nenv_size()\n{\n    int i;\n    char **env;\n\n    rb_secure(4);\n    env = GET_ENVIRON(environ);\n    for(i=0; env[i]; i++)\n\t;\n    FREE_ENVIRON(environ);\n    return INT2FIX(i);\n}\n\nstatic VALUE\nenv_empty_p()\n{\n    char **env;\n\n    rb_secure(4);\n    env = GET_ENVIRON(environ);\n    if (env[0] == 0) {\n\tFREE_ENVIRON(environ);\n\treturn Qtrue;\n    }\n    FREE_ENVIRON(environ);\n    return Qfalse;\n}\n\nstatic VALUE\nenv_has_key(env, key)\n    VALUE env, key;\n{\n    char *s;\n\n    rb_secure(4);\n    s = StringValuePtr(key);\n    if (strlen(s) != RSTRING(key)->len)\n\trb_raise(rb_eArgError, \"bad environment variable name\");\n    if (getenv(s)) return Qtrue;\n    return Qfalse;\n}\n\nstatic VALUE\nenv_has_value(dmy, value)\n    VALUE dmy, value;\n{\n    char **env;\n\n    rb_secure(4);\n    value = rb_check_string_type(value);\n    if (NIL_P(value)) return Qfalse;\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s++) {\n\t    long len = strlen(s);\n\t    if (RSTRING(value)->len == len && strncmp(s, RSTRING(value)->ptr, len) == 0) {\n\t\tFREE_ENVIRON(environ);\n\t\treturn Qtrue;\n\t    }\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    return Qfalse;\n}\n\nstatic VALUE\nenv_index(dmy, value)\n    VALUE dmy, value;\n{\n    char **env;\n    VALUE str;\n\n    rb_secure(4);\n    StringValue(value);\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s++) {\n\t    long len = strlen(s);\n\t    if (RSTRING(value)->len == len && strncmp(s, RSTRING(value)->ptr, len) == 0) {\n\t\tstr = env_str_new(*env, s-*env-1);\n\t\tFREE_ENVIRON(environ);\n\t\treturn str;\n\t    }\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    return Qnil;\n}\n\nstatic VALUE\nenv_indexes(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int i;\n    VALUE indexes = rb_ary_new2(argc);\n\n    rb_warn(\"ENV.%s is deprecated; use ENV.values_at\",\n\t    rb_id2name(rb_frame_last_func()));\n    rb_secure(4);\n    for (i=0;i<argc;i++) {\n\tVALUE tmp = rb_check_string_type(argv[i]);\n\tif (NIL_P(tmp)) {\n\t    RARRAY(indexes)->ptr[i] = Qnil;\n\t}\n\telse {\n\t    RARRAY(indexes)->ptr[i] = env_str_new2(getenv(RSTRING(tmp)->ptr));\n\t}\n\tRARRAY(indexes)->len = i+1;\n    }\n\n    return indexes;\n}\n\nstatic VALUE\nenv_to_hash()\n{\n    char **env;\n    VALUE hash;\n\n    rb_secure(4);\n    hash = rb_hash_new();\n    env = GET_ENVIRON(environ);\n    while (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    rb_hash_aset(hash, env_str_new(*env, s-*env),\n\t\t\t       env_str_new2(s+1));\n\t}\n\tenv++;\n    }\n    FREE_ENVIRON(environ);\n    return hash;\n}\n\nstatic VALUE\nenv_reject()\n{\n    return rb_hash_delete_if(env_to_hash());\n}\n\nstatic VALUE\nenv_shift()\n{\n    char **env;\n\n    rb_secure(4);\n    env = GET_ENVIRON(environ);\n    if (*env) {\n\tchar *s = strchr(*env, '=');\n\tif (s) {\n\t    VALUE key = env_str_new(*env, s-*env);\n\t    VALUE val = env_str_new2(getenv(RSTRING(key)->ptr));\n\t    env_delete(Qnil, key);\n\t    return rb_assoc_new(key, val);\n\t}\n    }\n    FREE_ENVIRON(environ);\n    return Qnil;\n}\n\nstatic VALUE\nenv_invert()\n{\n    return rb_hash_invert(env_to_hash());\n}\n\nstatic int\nenv_replace_i(key, val, keys)\n    VALUE key, val, keys;\n{\n    if (key != Qundef) {\n\tenv_aset(Qnil, key, val);\n\tif (rb_ary_includes(keys, key)) {\n\t    rb_ary_delete(keys, key);\n\t}\n    }\n    return ST_CONTINUE;\n}\n\nstatic VALUE\nenv_replace(env, hash)\n    VALUE env, hash;\n{\n    volatile VALUE keys;\n    long i;\n\n    keys = env_keys();\t/* rb_secure(4); */\n    if (env == hash) return env;\n    hash = to_hash(hash);\n    rb_hash_foreach(hash, env_replace_i, keys);\n\n    for (i=0; i<RARRAY(keys)->len; i++) {\n\tenv_delete(env, RARRAY(keys)->ptr[i]);\n    }\n    return env;\n}\n\nstatic int\nenv_update_i(key, val)\n    VALUE key, val;\n{\n    if (key != Qundef) {\n\tif (rb_block_given_p()) {\n\t    val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);\n\t}\n\tenv_aset(Qnil, key, val);\n    }\n    return ST_CONTINUE;\n}\n\nstatic VALUE\nenv_update(env, hash)\n    VALUE env, hash;\n{\n    rb_secure(4);\n    if (env == hash) return env;\n    hash = to_hash(hash);\n    rb_hash_foreach(hash, env_update_i, 0);\n    return env;\n}\n\n/*\n *  A <code>Hash</code> is a collection of key-value pairs. It is\n *  similar to an <code>Array</code>, except that indexing is done via\n *  arbitrary keys of any object type, not an integer index. The order\n *  in which you traverse a hash by either key or value may seem\n *  arbitrary, and will generally not be in the insertion order.\n *\n *  Hashes have a <em>default value</em> that is returned when accessing\n *  keys that do not exist in the hash. By default, that value is\n *  <code>nil</code>.\n *\n *  <code>Hash</code> uses <code>key.eql?</code> to test keys for equality.\n *  If you need to use instances of your own classes as keys in a <code>Hash</code>,\n *  it is recommended that you define both the <code>eql?</code> and <code>hash</code>\n *  methods. The <code>hash</code> method must have the property that\n *  <code>a.eql?(b)</code> implies <code>a.hash == b.hash</code>.\n *\n *    class MyClass\n *      attr_reader :str\n *      def initialize(str)\n *        @str = str\n *      end\n *      def eql?(o)\n *        o.is_a?(MyClass) && str == o.str\n *      end\n *      def hash\n *        @str.hash\n *      end\n *    end\n *\n *    a = MyClass.new(\"some string\")\n *    b = MyClass.new(\"some string\")\n *    a.eql? b  #=> true\n *\n *    h = {}\n *\n *    h[a] = 1\n *    h[a]      #=> 1\n *    h[b]      #=> 1\n *\n *    h[b] = 2\n *    h[a]      #=> 2\n *    h[b]      #=> 2\n */\n\nvoid\nInit_Hash()\n{\n    id_hash = rb_intern(\"hash\");\n    id_call = rb_intern(\"call\");\n    id_default = rb_intern(\"default\");\n\n    rb_cHash = rb_define_class(\"Hash\", rb_cObject);\n\n    rb_include_module(rb_cHash, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cHash, hash_alloc);\n    rb_define_singleton_method(rb_cHash, \"[]\", rb_hash_s_create, -1);\n    rb_define_method(rb_cHash,\"initialize\", rb_hash_initialize, -1);\n    rb_define_method(rb_cHash,\"initialize_copy\", rb_hash_replace, 1);\n    rb_define_method(rb_cHash,\"rehash\", rb_hash_rehash, 0);\n\n    rb_define_method(rb_cHash,\"to_hash\", rb_hash_to_hash, 0);\n    rb_define_method(rb_cHash,\"to_a\", rb_hash_to_a, 0);\n    rb_define_method(rb_cHash,\"to_s\", rb_hash_to_s, 0);\n    rb_define_method(rb_cHash,\"inspect\", rb_hash_inspect, 0);\n\n    rb_define_method(rb_cHash,\"==\", rb_hash_equal, 1);\n    rb_define_method(rb_cHash,\"[]\", rb_hash_aref, 1);\n    rb_define_method(rb_cHash,\"hash\", rb_hash_hash, 0);\n    rb_define_method(rb_cHash,\"eql?\", rb_hash_eql, 1);\n    rb_define_method(rb_cHash,\"fetch\", rb_hash_fetch, -1);\n    rb_define_method(rb_cHash,\"[]=\", rb_hash_aset, 2);\n    rb_define_method(rb_cHash,\"store\", rb_hash_aset, 2);\n    rb_define_method(rb_cHash,\"default\", rb_hash_default, -1);\n    rb_define_method(rb_cHash,\"default=\", rb_hash_set_default, 1);\n    rb_define_method(rb_cHash,\"default_proc\", rb_hash_default_proc, 0);\n    rb_define_method(rb_cHash,\"index\", rb_hash_index, 1);\n    rb_define_method(rb_cHash,\"indexes\", rb_hash_indexes, -1);\n    rb_define_method(rb_cHash,\"indices\", rb_hash_indexes, -1);\n    rb_define_method(rb_cHash,\"size\", rb_hash_size, 0);\n    rb_define_method(rb_cHash,\"length\", rb_hash_size, 0);\n    rb_define_method(rb_cHash,\"empty?\", rb_hash_empty_p, 0);\n\n    rb_define_method(rb_cHash,\"each\", rb_hash_each, 0);\n    rb_define_method(rb_cHash,\"each_value\", rb_hash_each_value, 0);\n    rb_define_method(rb_cHash,\"each_key\", rb_hash_each_key, 0);\n    rb_define_method(rb_cHash,\"each_pair\", rb_hash_each_pair, 0);\n    rb_define_method(rb_cHash,\"sort\", rb_hash_sort, 0);\n\n    rb_define_method(rb_cHash,\"keys\", rb_hash_keys, 0);\n    rb_define_method(rb_cHash,\"values\", rb_hash_values, 0);\n    rb_define_method(rb_cHash,\"values_at\", rb_hash_values_at, -1);\n\n    rb_define_method(rb_cHash,\"shift\", rb_hash_shift, 0);\n    rb_define_method(rb_cHash,\"delete\", rb_hash_delete, 1);\n    rb_define_method(rb_cHash,\"delete_if\", rb_hash_delete_if, 0);\n    rb_define_method(rb_cHash,\"select\", rb_hash_select, 0);\n    rb_define_method(rb_cHash,\"reject\", rb_hash_reject, 0);\n    rb_define_method(rb_cHash,\"reject!\", rb_hash_reject_bang, 0);\n    rb_define_method(rb_cHash,\"clear\", rb_hash_clear, 0);\n    rb_define_method(rb_cHash,\"invert\", rb_hash_invert, 0);\n    rb_define_method(rb_cHash,\"update\", rb_hash_update, 1);\n    rb_define_method(rb_cHash,\"replace\", rb_hash_replace, 1);\n    rb_define_method(rb_cHash,\"merge!\", rb_hash_update, 1);\n    rb_define_method(rb_cHash,\"merge\", rb_hash_merge, 1);\n\n    rb_define_method(rb_cHash,\"include?\", rb_hash_has_key, 1);\n    rb_define_method(rb_cHash,\"member?\", rb_hash_has_key, 1);\n    rb_define_method(rb_cHash,\"has_key?\", rb_hash_has_key, 1);\n    rb_define_method(rb_cHash,\"has_value?\", rb_hash_has_value, 1);\n    rb_define_method(rb_cHash,\"key?\", rb_hash_has_key, 1);\n    rb_define_method(rb_cHash,\"value?\", rb_hash_has_value, 1);\n\n#ifndef __MACOS__ /* environment variables nothing on MacOS. */\n    origenviron = environ;\n    envtbl = rb_obj_alloc(rb_cObject);\n    rb_extend_object(envtbl, rb_mEnumerable);\n\n    rb_define_singleton_method(envtbl,\"[]\", rb_f_getenv, 1);\n    rb_define_singleton_method(envtbl,\"fetch\", env_fetch, -1);\n    rb_define_singleton_method(envtbl,\"[]=\", env_aset, 2);\n    rb_define_singleton_method(envtbl,\"store\", env_aset, 2);\n    rb_define_singleton_method(envtbl,\"each\", env_each, 0);\n    rb_define_singleton_method(envtbl,\"each_pair\", env_each_pair, 0);\n    rb_define_singleton_method(envtbl,\"each_key\", env_each_key, 0);\n    rb_define_singleton_method(envtbl,\"each_value\", env_each_value, 0);\n    rb_define_singleton_method(envtbl,\"delete\", env_delete_m, 1);\n    rb_define_singleton_method(envtbl,\"delete_if\", env_delete_if, 0);\n    rb_define_singleton_method(envtbl,\"clear\", env_clear, 0);\n    rb_define_singleton_method(envtbl,\"reject\", env_reject, 0);\n    rb_define_singleton_method(envtbl,\"reject!\", env_reject_bang, 0);\n    rb_define_singleton_method(envtbl,\"select\", env_select, 0);\n    rb_define_singleton_method(envtbl,\"shift\", env_shift, 0);\n    rb_define_singleton_method(envtbl,\"invert\", env_invert, 0);\n    rb_define_singleton_method(envtbl,\"replace\", env_replace, 1);\n    rb_define_singleton_method(envtbl,\"update\", env_update, 1);\n    rb_define_singleton_method(envtbl,\"inspect\", env_inspect, 0);\n    rb_define_singleton_method(envtbl,\"rehash\", env_none, 0);\n    rb_define_singleton_method(envtbl,\"to_a\", env_to_a, 0);\n    rb_define_singleton_method(envtbl,\"to_s\", env_to_s, 0);\n    rb_define_singleton_method(envtbl,\"index\", env_index, 1);\n    rb_define_singleton_method(envtbl,\"indexes\", env_indexes, -1);\n    rb_define_singleton_method(envtbl,\"indices\", env_indexes, -1);\n    rb_define_singleton_method(envtbl,\"size\", env_size, 0);\n    rb_define_singleton_method(envtbl,\"length\", env_size, 0);\n    rb_define_singleton_method(envtbl,\"empty?\", env_empty_p, 0);\n    rb_define_singleton_method(envtbl,\"keys\", env_keys, 0);\n    rb_define_singleton_method(envtbl,\"values\", env_values, 0);\n    rb_define_singleton_method(envtbl,\"values_at\", env_values_at, -1);\n    rb_define_singleton_method(envtbl,\"include?\", env_has_key, 1);\n    rb_define_singleton_method(envtbl,\"member?\", env_has_key, 1);\n    rb_define_singleton_method(envtbl,\"has_key?\", env_has_key, 1);\n    rb_define_singleton_method(envtbl,\"has_value?\", env_has_value, 1);\n    rb_define_singleton_method(envtbl,\"key?\", env_has_key, 1);\n    rb_define_singleton_method(envtbl,\"value?\", env_has_value, 1);\n    rb_define_singleton_method(envtbl,\"to_hash\", env_to_hash, 0);\n\n    rb_define_global_const(\"ENV\", envtbl);\n#else /* __MACOS__ */\n\tenvtbl = rb_hash_s_new(0, NULL, rb_cHash);\n    rb_define_global_const(\"ENV\", envtbl);\n#endif  /* ifndef __MACOS__  environment variables nothing on MacOS. */\n}\n"
  },
  {
    "path": "ia64.s",
    "content": "// rb_ia64_flushrs and rb_ia64_bsp is written in IA64 assembly language\n// because Intel Compiler for IA64 doesn't support inline assembly.\n//\n// This file is based on following C program compiled by gcc.\n//\n//   void rb_ia64_flushrs(void) { __builtin_ia64_flushrs(); }\n//   void *rb_ia64_bsp(void) { return __builtin_ia64_bsp(); }\n// \n\t.file\t\"ia64.c\"\n\t.text\n\t.align 16\n\t.global rb_ia64_flushrs#\n\t.proc rb_ia64_flushrs#\nrb_ia64_flushrs:\n\t.prologue\n\t.body\n\tflushrs\n\t;;\n\tnop.i 0\n\tbr.ret.sptk.many b0\n\t.endp rb_ia64_flushrs#\n\t.align 16\n\t.global rb_ia64_bsp#\n\t.proc rb_ia64_bsp#\nrb_ia64_bsp:\n\t.prologue\n\t.body\n\tnop.m 0\n\t;;\n\tmov r8 = ar.bsp\n\tbr.ret.sptk.many b0\n\t.endp rb_ia64_bsp#\n\t.ident\t\"GCC: (GNU) 3.3.5 (Debian 1:3.3.5-13)\"\n"
  },
  {
    "path": "inits.c",
    "content": "/**********************************************************************\n\n  inits.c -\n\n  $Author$\n  $Date$\n  created at: Tue Dec 28 16:01:58 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\nvoid Init_Array _((void));\nvoid Init_Bignum _((void));\nvoid Init_Binding _((void));\nvoid Init_Comparable _((void));\nvoid Init_Dir _((void));\nvoid Init_Enumerable _((void));\nvoid Init_Enumerator _((void));\nvoid Init_Exception _((void));\nvoid Init_syserr _((void));\nvoid Init_eval _((void));\nvoid Init_load _((void));\nvoid Init_Proc _((void));\nvoid Init_Thread _((void));\nvoid Init_File _((void));\nvoid Init_GC _((void));\nvoid Init_Hash _((void));\nvoid Init_IO _((void));\nvoid Init_Math _((void));\nvoid Init_marshal _((void));\nvoid Init_Numeric _((void));\nvoid Init_Object _((void));\nvoid Init_pack _((void));\nvoid Init_Precision _((void));\nvoid Init_process _((void));\nvoid Init_Random _((void));\nvoid Init_Range _((void));\nvoid Init_Regexp _((void));\nvoid Init_signal _((void));\nvoid Init_String _((void));\nvoid Init_Struct _((void));\nvoid Init_Time _((void));\nvoid Init_var_tables _((void));\nvoid Init_version _((void));\n\nvoid\nrb_call_inits()\n{\n    Init_var_tables();\n    Init_Object();\n    Init_Comparable();\n    Init_Enumerable();\n    Init_Precision();\n    Init_eval();\n    Init_String();\n    Init_Exception();\n    Init_Thread();\n    Init_Numeric();\n    Init_Bignum();\n    Init_syserr();\n    Init_Array();\n    Init_Hash();\n    Init_Struct();\n    Init_Regexp();\n    Init_pack();\n    Init_Range();\n    Init_IO();\n    Init_Dir();\n    Init_Time();\n    Init_Random();\n    Init_signal();\n    Init_process();\n    Init_load();\n    Init_Proc();\n    Init_Binding();\n    Init_Math();\n    Init_GC();\n    Init_Enumerator();\n    Init_marshal();\n    Init_version();\n}\n"
  },
  {
    "path": "install-sh",
    "content": ""
  },
  {
    "path": "instruby.rb",
    "content": "#!./miniruby\n\nload \"./rbconfig.rb\"\ninclude RbConfig\n\nsrcdir = File.dirname(__FILE__)\n$:.unshift File.expand_path(\"lib\", srcdir)\nrequire 'fileutils'\nrequire 'shellwords'\nrequire 'optparse'\nrequire 'optparse/shellwords'\nrequire 'tempfile'\n\nSTDOUT.sync = true\nFile.umask(0)\n\ndef parse_args(argv = ARGV)\n  $mantype = 'doc'\n  $destdir = nil\n  $extout = nil\n  $make = 'make'\n  $mflags = []\n  $install = []\n  $installed_list = nil\n  $dryrun = false\n  $rdocdir = nil\n  $data_mode = 0644\n  $prog_mode = 0755\n  $dir_mode = nil\n  $script_mode = nil\n  $cmdtype = ('bat' if File::ALT_SEPARATOR == '\\\\')\n  mflags = []\n  opt = OptionParser.new\n  opt.on('-n') {$dryrun = true}\n  opt.on('--dest-dir=DIR') {|dir| $destdir = dir}\n  opt.on('--extout=DIR') {|dir| $extout = (dir unless dir.empty?)}\n  opt.on('--make=COMMAND') {|make| $make = make}\n  opt.on('--mantype=MAN') {|man| $mantype = man}\n  opt.on('--make-flags=FLAGS', '--mflags', Shellwords) do |v|\n    if arg = v.first\n      arg.insert(0, '-') if /\\A[^-][^=]*\\Z/ =~ arg\n    end\n    $mflags.concat(v)\n  end\n  opt.on('-i', '--install=TYPE',\n         [:local, :bin, :\"bin-arch\", :\"bin-comm\", :lib, :man, :ext, :\"ext-arch\", :\"ext-comm\", :rdoc]) do |ins|\n    $install << ins\n  end\n  opt.on('--data-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|\n    $data_mode = mode\n  end\n  opt.on('--prog-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|\n    $prog_mode = mode\n  end\n  opt.on('--dir-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|\n    $dir_mode = mode\n  end\n  opt.on('--script-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|\n    $script_mode = mode\n  end\n  opt.on('--installed-list [FILENAME]') {|name| $installed_list = name}\n  opt.on('--rdoc-output [DIR]') {|dir| $rdocdir = dir}\n  opt.on('--cmd-type=TYPE', %w[bat cmd plain]) {|cmd| $cmdtype = (cmd unless cmd == 'plain')}\n\n  opt.order!(argv) do |v|\n    case v\n    when /\\AINSTALL[-_]([-\\w]+)=(.*)/\n      argv.unshift(\"--#{$1.tr('_', '-')}=#{$2}\")\n    when /\\A\\w[-\\w+]*=\\z/\n      mflags << v\n    when /\\A\\w[-\\w+]*\\z/\n      $install << v.intern\n    else\n      raise OptionParser::InvalidArgument, v\n    end\n  end rescue abort [$!.message, opt].join(\"\\n\")\n\n  $make, *rest = Shellwords.shellwords($make)\n  $mflags.unshift(*rest) unless rest.empty?\n  $mflags.unshift(*mflags)\n\n  def $mflags.set?(flag)\n    grep(/\\A-(?!-).*#{flag.chr}/i) { return true }\n    false\n  end\n  def $mflags.defined?(var)\n    grep(/\\A#{var}=(.*)/) {return block_given? ? yield($1) : $1}\n    false\n  end\n\n  if $mflags.set?(?n)\n    $dryrun = true\n  else\n    $mflags << '-n' if $dryrun\n  end\n\n  $destdir ||= $mflags.defined?(\"DESTDIR\")\n  if $extout ||= $mflags.defined?(\"EXTOUT\")\n    Config.expand($extout)\n  end\n\n  $continue = $mflags.set?(?k)\n\n  if $installed_list ||= $mflags.defined?('INSTALLED_LIST')\n    Config.expand($installed_list, Config::CONFIG)\n    $installed_list = open($installed_list, \"ab\")\n    $installed_list.sync = true\n  end\n\n  $rdocdir ||= $mflags.defined?('RDOCOUT')\n\n  $dir_mode ||= $prog_mode | 0700\n  $script_mode ||= $prog_mode\nend\n\nparse_args()\n\ninclude FileUtils\ninclude FileUtils::NoWrite if $dryrun\n@fileutils_output = STDOUT\n@fileutils_label = ''\n\n$install_procs = Hash.new {[]}\ndef install?(*types, &block)\n  $install_procs[:all] <<= block\n  types.each do |type|\n    $install_procs[type] <<= block\n  end\nend\n\ndef install(src, dest, options = {})\n  options[:preserve] = true\n  super(src, with_destdir(dest), options)\n  if $installed_list\n    dest = File.join(dest, File.basename(src)) if $made_dirs[dest]\n    $installed_list.puts dest\n  end\nend\n\ndef ln_sf(src, dest)\n  super(src, with_destdir(dest))\n  $installed_list.puts dest if $installed_list\nend\n\n$made_dirs = {}\ndef makedirs(dirs)\n  dirs = fu_list(dirs)\n  dirs.collect! do |dir|\n    realdir = with_destdir(dir)\n    realdir unless $made_dirs.fetch(dir) do\n      $made_dirs[dir] = true\n      $installed_list.puts(File.join(dir, \"\")) if $installed_list\n      File.directory?(realdir)\n    end\n  end.compact!\n  super(dirs, :mode => $dir_mode) unless dirs.empty?\nend\n\ndef install_recursive(srcdir, dest, options = {})\n  opts = options.clone\n  noinst = opts.delete(:no_install)\n  glob = opts.delete(:glob) || \"*\"\n  subpath = srcdir.size..-1\n  Dir.glob(\"#{srcdir}/**/#{glob}\") do |src|\n    case base = File.basename(src)\n    when /\\A\\#.*\\#\\z/, /~\\z/\n      next\n    end\n    if noinst\n      if Array === noinst\n        next if noinst.any? {|n| File.fnmatch?(n, base)}\n      else\n        next if File.fnmatch?(noinst, base)\n      end\n    end\n    d = dest + src[subpath]\n    if File.directory?(src)\n      makedirs(d)\n    else\n      makedirs(File.dirname(d))\n      install src, d, opts\n    end\n  end\nend\n\ndef open_for_install(path, mode)\n  data = open(realpath = with_destdir(path), \"rb\") {|f| f.read} rescue nil\n  newdata = yield\n  unless $dryrun\n    unless newdata == data\n      open(realpath, \"wb\", mode) {|f| f.write newdata}\n    end\n    File.chmod(mode, realpath)\n  end\n  $installed_list.puts path if $installed_list\nend\n\ndef with_destdir(dir)\n  return dir if !$destdir or $destdir.empty?\n  dir = dir.sub(/\\A\\w:/, '') if File::PATH_SEPARATOR == ';'\n  $destdir + dir\nend\n\nexeext = CONFIG[\"EXEEXT\"]\n\nruby_install_name = CONFIG[\"ruby_install_name\"]\nrubyw_install_name = CONFIG[\"rubyw_install_name\"]\n\nversion = CONFIG[\"ruby_version\"]\nbindir = CONFIG[\"bindir\"]\nlibdir = CONFIG[\"libdir\"]\nrubylibdir = CONFIG[\"rubylibdir\"]\narchlibdir = CONFIG[\"archdir\"]\nsitelibdir = CONFIG[\"sitelibdir\"]\nsitearchlibdir = CONFIG[\"sitearchdir\"]\nvendorlibdir = CONFIG[\"vendorlibdir\"]\nvendorarchlibdir = CONFIG[\"vendorarchdir\"]\nmandir = File.join(CONFIG[\"mandir\"], \"man\")\nconfigure_args = Shellwords.shellwords(CONFIG[\"configure_args\"])\nenable_shared = CONFIG[\"ENABLE_SHARED\"] == 'yes'\ndll = CONFIG[\"LIBRUBY_SO\"]\nlib = CONFIG[\"LIBRUBY\"]\narc = CONFIG[\"LIBRUBY_A\"]\n\ninstall?(:local, :arch, :bin, :'bin-arch') do\n  puts \"installing binary commands\"\n\n  makedirs [bindir, libdir, archlibdir]\n\n  install ruby_install_name+exeext, bindir, :mode => $prog_mode\n  if rubyw_install_name and !rubyw_install_name.empty?\n    install rubyw_install_name+exeext, bindir, :mode => $prog_mode\n  end\n  if enable_shared and dll != lib\n    install dll, bindir, :mode => $prog_mode\n  end\n  install lib, libdir, :mode => $prog_mode unless lib == arc\n  install arc, libdir, :mode => $data_mode\n  install \"config.h\", archlibdir, :mode => $data_mode\n  install \"rbconfig.rb\", archlibdir, :mode => $data_mode\n  if CONFIG[\"ARCHFILE\"]\n    for file in CONFIG[\"ARCHFILE\"].split\n      install file, archlibdir, :mode => $data_mode\n    end\n  end\n\n  if dll == lib and dll != arc\n    for link in CONFIG[\"LIBRUBY_ALIASES\"].split\n      ln_sf(dll, File.join(libdir, link))\n    end\n  end\nend\n\nif $extout\n  extout = \"#$extout\"\n  install?(:ext, :arch, :'ext-arch') do\n    puts \"installing extension objects\"\n    makedirs [archlibdir, sitearchlibdir, vendorarchlibdir]\n    if noinst = CONFIG[\"no_install_files\"] and noinst.empty?\n      noinst = nil\n    end\n    install_recursive(\"#{extout}/#{CONFIG['arch']}\", archlibdir, :no_install => noinst, :mode => $prog_mode)\n  end\n  install?(:ext, :comm, :'ext-comm') do\n    puts \"installing extension scripts\"\n    makedirs [rubylibdir, sitelibdir, vendorlibdir]\n    install_recursive(\"#{extout}/common\", rubylibdir, :mode => $data_mode)\n  end\nend\n\ninstall?(:rdoc) do\n  if $rdocdir\n    puts \"installing rdoc\"\n\n    ridatadir = File.join(CONFIG['datadir'], 'ri/$(MAJOR).$(MINOR)/system')\n    Config.expand(ridatadir)\n    makedirs [ridatadir]\n    install_recursive($rdocdir, ridatadir, :mode => $data_mode)\n  end\nend\n\ninstall?(:local, :comm, :bin, :'bin-comm') do\n  puts \"installing command scripts\"\n\n  Dir.chdir srcdir\n  makedirs [bindir, rubylibdir]\n\n  ruby_shebang = File.join(bindir, ruby_install_name)\n  if File::ALT_SEPARATOR\n    ruby_bin = ruby_shebang.tr(File::SEPARATOR, File::ALT_SEPARATOR)\n  end\n  for src in Dir[\"bin/*\"]\n    next unless File.file?(src)\n    next if /\\/[.#]|(\\.(old|bak|orig|rej|diff|patch|core)|~|\\/core)$/i =~ src\n\n    name = ruby_install_name.sub(/ruby/, File.basename(src))\n\n    shebang = ''\n    body = ''\n    open(src, \"rb\") do |f|\n      shebang = f.gets\n      body = f.read\n    end\n    shebang.sub!(/^\\#!.*?ruby\\b/) {\"#!\" + ruby_shebang}\n    shebang.sub!(/\\r$/, '')\n    body.gsub!(/\\r$/, '')\n\n    cmd = File.join(bindir, name)\n    cmd << \".#{$cmdtype}\" if $cmdtype\n    open_for_install(cmd, $script_mode) do\n      case $cmdtype\n      when \"bat\"\n        \"#{<<EOH}#{shebang}#{body}#{<<EOF}\".gsub(/$/, \"\\r\")\n@echo off\n@if not \"%~d0\" == \"~d0\" goto WinNT\n#{ruby_bin} -x \"#{cmd}\" %1 %2 %3 %4 %5 %6 %7 %8 %9\n@goto endofruby\n:WinNT\n\"%~dp0#{ruby_install_name}\" -x \"%~f0\" %*\n@goto endofruby\nEOH\n__END__\n:endofruby\nEOF\n      when \"cmd\"\n        \"#{<<EOH}#{shebang}#{body}\"\n@\"%~dp0#{ruby_install_name}\" -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\nEOH\n      else\n        shebang + body\n      end\n    end\n  end\nend\n\ninstall?(:local, :comm, :lib) do\n  puts \"installing library scripts\"\n\n  Dir.chdir srcdir\n  makedirs [rubylibdir]\n\n  for f in Dir[\"lib/**/*{.rb,help-message}\"]\n    dir = File.dirname(f).sub!(/\\Alib/, rubylibdir) || rubylibdir\n    makedirs dir\n    install f, dir, :mode => $data_mode\n  end\nend\n\ninstall?(:local, :arch, :lib) do\n  puts \"installing headers\"\n\n  Dir.chdir(srcdir)\n  makedirs [archlibdir]\n  for f in Dir[\"*.h\"]\n    install f, archlibdir, :mode => $data_mode\n  end\n\n  if RUBY_PLATFORM =~ /mswin32|mingw|bccwin32/\n    win32libdir = File.join(archlibdir, \"win32\")\n    makedirs win32libdir\n    install \"win32/win32.h\", win32libdir, :mode => $data_mode\n  end\nend\n\ninstall?(:local, :comm, :man) do\n  puts \"installing manpages\"\n\n  Dir.chdir(srcdir)\n  for mdoc in Dir[\"*.[1-9]\"]\n    next unless File.file?(mdoc) and open(mdoc){|fh| fh.read(1) == '.'}\n\n    destdir = mandir + mdoc[/(\\d+)$/]\n    destfile = File.join(destdir, mdoc.sub(/ruby/, ruby_install_name))\n\n    makedirs destdir\n\n    if $mantype == \"doc\"\n      install mdoc, destfile, :mode => $data_mode\n    else\n      require 'mdoc2man.rb'\n\n      w = Tempfile.open(mdoc)\n\n      open(mdoc) { |r|\n        Mdoc2Man.mdoc2man(r, w)\n      }\n\n      w.close\n\n      install w.path, destfile, :mode => $data_mode\n    end\n  end\nend\n\n$install << :local << :ext if $install.empty?\n$install.each do |inst|\n  if !(procs = $install_procs[inst]) || procs.empty?\n    next warn(\"unknown install target - #{inst}\")\n  end\n  procs.each do |block|\n    dir = Dir.pwd\n    begin\n      block.call\n    ensure\n      Dir.chdir(dir)\n    end\n  end\nend\n\n# vi:set sw=2:\n"
  },
  {
    "path": "intern.h",
    "content": "/**********************************************************************\n\n  intern.h -\n\n  $Author$\n  $Date$\n  created at: Thu Jun 10 14:22:17 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n/*\n * Functions and variables that are used by more than one source file of\n * the kernel.\n */\n\n#define ID_ALLOCATOR 1\n\n/* array.c */\nvoid rb_mem_clear _((register VALUE*, register long));\nVALUE rb_assoc_new _((VALUE, VALUE));\nVALUE rb_check_array_type _((VALUE));\nVALUE rb_ary_new _((void));\nVALUE rb_ary_new2 _((long));\nVALUE rb_ary_new3 __((long,...));\nVALUE rb_ary_new4 _((long, const VALUE *));\nVALUE rb_ary_freeze _((VALUE));\nVALUE rb_ary_aref _((int, VALUE*, VALUE));\nvoid rb_ary_store _((VALUE, long, VALUE));\nVALUE rb_ary_dup _((VALUE));\nVALUE rb_ary_to_ary _((VALUE));\nVALUE rb_ary_to_s _((VALUE));\nVALUE rb_ary_push _((VALUE, VALUE));\nVALUE rb_ary_pop _((VALUE));\nVALUE rb_ary_shift _((VALUE));\nVALUE rb_ary_unshift _((VALUE, VALUE));\nVALUE rb_ary_entry _((VALUE, long));\nVALUE rb_ary_each _((VALUE));\nVALUE rb_ary_join _((VALUE, VALUE));\nVALUE rb_ary_print_on _((VALUE, VALUE));\nVALUE rb_ary_reverse _((VALUE));\nVALUE rb_ary_sort _((VALUE));\nVALUE rb_ary_sort_bang _((VALUE));\nVALUE rb_ary_delete _((VALUE, VALUE));\nVALUE rb_ary_delete_at _((VALUE, long));\nVALUE rb_ary_clear _((VALUE));\nVALUE rb_ary_plus _((VALUE, VALUE));\nVALUE rb_ary_concat _((VALUE, VALUE));\nVALUE rb_ary_assoc _((VALUE, VALUE));\nVALUE rb_ary_rassoc _((VALUE, VALUE));\nVALUE rb_ary_includes _((VALUE, VALUE));\nVALUE rb_ary_cmp _((VALUE, VALUE));\nVALUE rb_protect_inspect _((VALUE(*)(ANYARGS),VALUE,VALUE));\nVALUE rb_inspecting_p _((VALUE));\nVALUE rb_check_array_value _((VALUE));\nVALUE rb_values_at _((VALUE, long, int, VALUE*, VALUE(*) _((VALUE,long))));\n/* bignum.c */\nVALUE rb_big_clone _((VALUE));\nvoid rb_big_2comp _((VALUE));\nVALUE rb_big_norm _((VALUE));\nVALUE rb_uint2big _((unsigned long));\nVALUE rb_int2big _((long));\nVALUE rb_uint2inum _((unsigned long));\nVALUE rb_int2inum _((long));\nVALUE rb_cstr_to_inum _((const char*, int, int));\nVALUE rb_str_to_inum _((VALUE, int, int));\nVALUE rb_cstr2inum _((const char*, int));\nVALUE rb_str2inum _((VALUE, int));\nVALUE rb_big2str _((VALUE, int));\nVALUE rb_big2str0 _((VALUE, int, int));\nlong rb_big2long _((VALUE));\n#define rb_big2int(x) rb_big2long(x)\nunsigned long rb_big2ulong _((VALUE));\n#define rb_big2uint(x) rb_big2ulong(x)\n#if HAVE_LONG_LONG\nVALUE rb_ll2inum _((LONG_LONG));\nVALUE rb_ull2inum _((unsigned LONG_LONG));\nLONG_LONG rb_big2ll _((VALUE));\nunsigned LONG_LONG rb_big2ull _((VALUE));\n#endif  /* HAVE_LONG_LONG */\nvoid rb_quad_pack _((char*,VALUE));\nVALUE rb_quad_unpack _((const char*,int));\nVALUE rb_dbl2big _((double));\ndouble rb_big2dbl _((VALUE));\nVALUE rb_big_plus _((VALUE, VALUE));\nVALUE rb_big_minus _((VALUE, VALUE));\nVALUE rb_big_mul _((VALUE, VALUE));\nVALUE rb_big_divmod _((VALUE, VALUE));\nVALUE rb_big_pow _((VALUE, VALUE));\nVALUE rb_big_and _((VALUE, VALUE));\nVALUE rb_big_or _((VALUE, VALUE));\nVALUE rb_big_xor _((VALUE, VALUE));\nVALUE rb_big_lshift _((VALUE, VALUE));\nVALUE rb_big_rand _((VALUE, double*));\n/* class.c */\nVALUE rb_class_boot _((VALUE));\nVALUE rb_class_new _((VALUE));\nVALUE rb_mod_init_copy _((VALUE, VALUE));\nVALUE rb_class_init_copy _((VALUE, VALUE));\nVALUE rb_singleton_class_clone _((VALUE));\nvoid rb_singleton_class_attached _((VALUE,VALUE));\nVALUE rb_make_metaclass _((VALUE, VALUE));\nvoid rb_check_inheritable _((VALUE));\nVALUE rb_class_inherited _((VALUE, VALUE));\nVALUE rb_define_class_id _((ID, VALUE));\nVALUE rb_module_new _((void));\nVALUE rb_define_module_id _((ID));\nVALUE rb_mod_included_modules _((VALUE));\nVALUE rb_mod_include_p _((VALUE, VALUE));\nVALUE rb_mod_ancestors _((VALUE));\nVALUE rb_class_instance_methods _((int, VALUE*, VALUE));\nVALUE rb_class_public_instance_methods _((int, VALUE*, VALUE));\nVALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));\nVALUE rb_big_rshift(VALUE, VALUE);\nVALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));\nVALUE rb_obj_singleton_methods _((int, VALUE*, VALUE));\nvoid rb_define_method_id _((VALUE, ID, VALUE (*)(ANYARGS), int));\nvoid rb_frozen_class_p _((VALUE));\nvoid rb_undef _((VALUE, ID));\nvoid rb_define_protected_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));\nvoid rb_define_private_method _((VALUE, const char*, VALUE (*)(ANYARGS), int));\nvoid rb_define_singleton_method _((VALUE, const char*, VALUE(*)(ANYARGS), int));\nVALUE rb_singleton_class _((VALUE));\n/* compar.c */\nint rb_cmpint _((VALUE, VALUE, VALUE));\nNORETURN(void rb_cmperr _((VALUE, VALUE)));\n/* enum.c */\nVALUE rb_block_call _((VALUE, ID, int, VALUE*, VALUE (*)(ANYARGS), VALUE));\n/* enumerator.c */\nVALUE rb_enumeratorize _((VALUE, VALUE, int, VALUE *));\n#define RETURN_ENUMERATOR(obj, argc, argv) do {\t\t\t\t\\\n\tif (!rb_block_given_p())\t\t\t\t\t\\\n\t    return rb_enumeratorize(obj, ID2SYM(rb_frame_this_func()),\t\\\n\t\t\t\t    argc, argv);\t\t\t\\\n    } while (0)\n/* error.c */\nRUBY_EXTERN int ruby_nerrs;\nVALUE rb_exc_new _((VALUE, const char*, long));\nVALUE rb_exc_new2 _((VALUE, const char*));\nVALUE rb_exc_new3 _((VALUE, VALUE));\nNORETURN(void rb_loaderror __((const char*, ...)));\nNORETURN(void rb_name_error __((ID, const char*, ...)));\nNORETURN(void rb_invalid_str _((const char*, const char*)));\nvoid rb_compile_error __((const char*, ...));\nvoid rb_compile_error_append __((const char*, ...));\nNORETURN(void rb_load_fail _((const char*)));\nNORETURN(void rb_error_frozen _((const char*)));\nvoid rb_check_frozen _((VALUE));\n/* eval.c */\nRUBY_EXTERN struct RNode *ruby_current_node;\nvoid ruby_set_current_source _((void));\nNORETURN(void rb_exc_raise _((VALUE)));\nNORETURN(void rb_exc_fatal _((VALUE)));\nVALUE rb_f_exit _((int,VALUE*));\nVALUE rb_f_abort _((int,VALUE*));\nvoid rb_remove_method _((VALUE, const char*));\n#define rb_disable_super(klass, name) ((void)0)\n#define rb_enable_super(klass, name) ((void)0)\n#define HAVE_RB_DEFINE_ALLOC_FUNC 1\nvoid rb_define_alloc_func _((VALUE, VALUE (*)(VALUE)));\nvoid rb_undef_alloc_func _((VALUE));\nvoid rb_clear_cache _((void));\nvoid rb_clear_cache_by_class _((VALUE));\nvoid rb_alias _((VALUE, ID, ID));\nvoid rb_attr _((VALUE,ID,int,int,int));\nint rb_method_boundp _((VALUE, ID, int));\nVALUE rb_dvar_defined _((ID));\nVALUE rb_dvar_curr _((ID));\nVALUE rb_dvar_ref _((ID));\nvoid rb_dvar_asgn _((ID, VALUE));\nvoid rb_dvar_push _((ID, VALUE));\nVALUE *rb_svar _((int));\nVALUE rb_eval_cmd _((VALUE, VALUE, int));\nint rb_obj_respond_to _((VALUE, ID, int));\nint rb_respond_to _((VALUE, ID));\nvoid rb_interrupt _((void));\nVALUE rb_apply _((VALUE, ID, VALUE));\nvoid rb_backtrace _((void));\nID rb_frame_last_func _((void));\nID rb_frame_this_func _((void));\nVALUE rb_obj_instance_eval _((int, VALUE*, VALUE));\nVALUE rb_mod_module_eval _((int, VALUE*, VALUE));\nvoid rb_load _((VALUE, int));\nvoid rb_load_protect _((VALUE, int, int*));\nNORETURN(void rb_jump_tag _((int)));\nint rb_provided _((const char*));\nvoid rb_provide _((const char*));\nVALUE rb_f_require _((VALUE, VALUE));\nVALUE rb_require_safe _((VALUE, int));\nvoid rb_obj_call_init _((VALUE, int, VALUE*));\nVALUE rb_class_new_instance _((int, VALUE*, VALUE));\nVALUE rb_block_proc _((void));\nVALUE rb_block_dup _((VALUE, VALUE, VALUE));\nVALUE rb_method_dup _((VALUE, VALUE, VALUE));\nVALUE rb_f_lambda _((void));\nVALUE rb_proc_call _((VALUE, VALUE));\nVALUE rb_obj_method _((VALUE, VALUE));\nVALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));\nvoid rb_set_end_proc _((void (*)(VALUE), VALUE));\nvoid rb_mark_end_proc _((void));\nvoid rb_exec_end_proc _((void));\nvoid ruby_finalize _((void));\nNORETURN(void ruby_stop _((int)));\nint ruby_cleanup _((int));\nint ruby_exec _((void));\nvoid rb_gc_mark_threads _((void));\nvoid rb_thread_start_timer _((void));\nvoid rb_thread_stop_timer _((void));\nvoid rb_thread_schedule _((void));\nvoid rb_thread_wait_fd _((int));\nint rb_thread_fd_writable _((int));\nvoid rb_thread_fd_close _((int));\nint rb_thread_alone _((void));\nvoid rb_thread_polling _((void));\nvoid rb_thread_sleep _((int));\nvoid rb_thread_sleep_forever _((void));\nVALUE rb_thread_stop _((void));\nVALUE rb_thread_wakeup _((VALUE));\nVALUE rb_thread_wakeup_alive _((VALUE));\nVALUE rb_thread_run _((VALUE));\nVALUE rb_thread_kill _((VALUE));\nVALUE rb_thread_alive_p _((VALUE));\nVALUE rb_thread_create _((VALUE (*)(ANYARGS), void*));\nvoid rb_thread_interrupt _((void));\nvoid rb_thread_trap_eval _((VALUE, int, int));\nvoid rb_thread_signal_raise _((int));\nvoid rb_thread_signal_exit _((void));\nint rb_thread_select _((int, fd_set *, fd_set *, fd_set *, struct timeval *));\nvoid rb_thread_wait_for _((struct timeval));\nVALUE rb_thread_current _((void));\nVALUE rb_thread_main _((void));\nVALUE rb_thread_local_aref _((VALUE, ID));\nVALUE rb_thread_local_aset _((VALUE, ID, VALUE));\nvoid rb_thread_atfork _((void));\nVALUE rb_exec_recursive _((VALUE(*)(VALUE, VALUE, int),VALUE,VALUE));\nVALUE rb_funcall_rescue __((VALUE, ID, int, ...));\n/* file.c */\nVALUE rb_file_s_expand_path _((int, VALUE *));\nVALUE rb_file_expand_path _((VALUE, VALUE));\nvoid rb_file_const _((const char*, VALUE));\nint rb_find_file_ext _((VALUE*, const char* const*));\nVALUE rb_find_file _((VALUE));\nchar *rb_path_next _((const char *));\nchar *rb_path_skip_prefix _((const char *));\nchar *rb_path_last_separator _((const char *));\nchar *rb_path_end _((const char *));\nVALUE rb_file_directory_p _((VALUE,VALUE));\n/* gc.c */\nNORETURN(void rb_memerror __((void)));\nint ruby_stack_check _((void));\nsize_t ruby_stack_length _((VALUE**));\nint rb_during_gc _((void));\nchar *rb_source_filename _((const char*));\nvoid rb_gc_mark_locations _((VALUE*, VALUE*));\nvoid rb_mark_tbl _((struct st_table*));\nvoid add_table_to_remembered_set _((struct st_table*));\nvoid maybe_add_to_longlife_recent_allocations _((VALUE));\nvoid rb_mark_set _((struct st_table*));\nvoid rb_mark_hash _((struct st_table*));\nvoid rb_gc_mark_maybe _((VALUE));\nvoid rb_gc_mark _((VALUE));\nvoid rb_gc_force_recycle _((VALUE));\nvoid rb_gc _((void));\nvoid rb_gc_copy_finalizer _((VALUE,VALUE));\nvoid rb_gc_finalize_deferred _((void));\nvoid rb_gc_call_finalizer_at_exit _((void));\nVALUE rb_gc_enable _((void));\nVALUE rb_gc_disable _((void));\nVALUE rb_gc_start _((void));\nvoid rb_gc_unstress _((void));\nVALUE rb_gc_enable_stats _((void));\nVALUE rb_gc_disable_stats _((void));\nVALUE rb_gc_allocated_size _((void));\nchar* gc_debug_obj_type(int tp);\nchar* gc_debug_node_type(int tp);\n/* hash.c */\nvoid st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long));\nvoid rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE));\nVALUE rb_hash _((VALUE));\nVALUE rb_hash_new _((void));\nVALUE rb_hash_freeze _((VALUE));\nVALUE rb_hash_aref _((VALUE, VALUE));\nVALUE rb_hash_lookup _((VALUE, VALUE));\nVALUE rb_hash_aset _((VALUE, VALUE, VALUE));\nVALUE rb_hash_delete_if _((VALUE));\nVALUE rb_hash_delete _((VALUE,VALUE));\nint rb_path_check _((const char*));\nint rb_env_path_tainted _((void));\n/* io.c */\n#define rb_defout rb_stdout\nRUBY_EXTERN VALUE rb_fs;\nRUBY_EXTERN VALUE rb_output_fs;\nRUBY_EXTERN VALUE rb_rs;\nRUBY_EXTERN VALUE rb_default_rs;\nRUBY_EXTERN VALUE rb_output_rs;\nVALUE rb_io_write _((VALUE, VALUE));\nVALUE rb_io_gets _((VALUE));\nVALUE rb_io_getc _((VALUE));\nVALUE rb_io_ungetc _((VALUE, VALUE));\nVALUE rb_io_close _((VALUE));\nVALUE rb_io_eof _((VALUE));\nVALUE rb_io_binmode _((VALUE));\nVALUE rb_io_addstr _((VALUE, VALUE));\nVALUE rb_io_printf _((int, VALUE*, VALUE));\nVALUE rb_io_print _((int, VALUE*, VALUE));\nVALUE rb_io_puts _((int, VALUE*, VALUE));\nVALUE rb_file_open _((const char*, const char*));\nVALUE rb_gets _((void));\nvoid rb_write_error _((const char*));\nvoid rb_write_error2 _((const char*, long));\n/* marshal.c */\nVALUE rb_marshal_dump _((VALUE, VALUE));\nVALUE rb_marshal_load _((VALUE));\n/* numeric.c */\nvoid rb_num_zerodiv _((void));\nVALUE rb_num_coerce_bin _((VALUE, VALUE));\nVALUE rb_num_coerce_cmp _((VALUE, VALUE));\nVALUE rb_num_coerce_relop _((VALUE, VALUE));\nVALUE rb_float_new _((double));\nVALUE rb_num2fix _((VALUE));\nVALUE rb_fix2str _((VALUE, int));\nVALUE rb_dbl_cmp _((double, double));\n/* object.c */\n#ifdef GC_DEBUG\nRUBY_EXTERN int longlife_moved_objs_count;\n#endif\nint rb_eql _((VALUE, VALUE));\nVALUE rb_any_to_s _((VALUE));\nVALUE rb_inspect _((VALUE));\nVALUE rb_obj_is_instance_of _((VALUE, VALUE));\nVALUE rb_obj_is_kind_of _((VALUE, VALUE));\nVALUE rb_obj_alloc _((VALUE));\nVALUE rb_obj_clone _((VALUE));\nVALUE rb_obj_move _((VALUE));\nVALUE rb_obj_dup _((VALUE));\nVALUE rb_obj_init_copy _((VALUE,VALUE));\nVALUE rb_obj_taint _((VALUE));\nVALUE rb_obj_tainted _((VALUE));\nVALUE rb_obj_untaint _((VALUE));\nVALUE rb_obj_freeze _((VALUE));\nVALUE rb_obj_shallow_freeze _((VALUE));\nVALUE rb_obj_id _((VALUE));\nVALUE rb_obj_class _((VALUE));\nVALUE rb_class_real _((VALUE));\nVALUE rb_class_inherited_p _((VALUE, VALUE));\nVALUE rb_convert_type _((VALUE,int,const char*,const char*));\nVALUE rb_check_convert_type _((VALUE,int,const char*,const char*));\nVALUE rb_check_to_integer _((VALUE, const char *));\nVALUE rb_to_int _((VALUE));\nVALUE rb_Integer _((VALUE));\nVALUE rb_Float _((VALUE));\nVALUE rb_String _((VALUE));\nVALUE rb_Array _((VALUE));\ndouble rb_cstr_to_dbl _((const char*, int));\ndouble rb_str_to_dbl _((VALUE, int));\n/* parse.y */\nRUBY_EXTERN int   ruby_sourceline;\nRUBY_EXTERN char *ruby_sourcefile;\n#ifdef GC_DEBUG\nRUBY_EXTERN ID ruby_sourcefunc;\nRUBY_EXTERN VALUE ruby_sourcefunc_line;\nRUBY_EXTERN char* ruby_sourcefunc_file;\n#endif\nRUBY_EXTERN int ruby_in_compile;\nRUBY_EXTERN int ruby_in_constant_assignment;\nint ruby_yyparse _((void));\nID rb_id_attrset _((ID));\nvoid rb_parser_append_print _((void));\nvoid rb_parser_while_loop _((int, int));\nint ruby_parser_stack_on_heap _((void));\nvoid rb_gc_mark_parser _((void));\nint rb_is_const_id _((ID));\nint rb_is_instance_id _((ID));\nint rb_is_class_id _((ID));\nint rb_is_local_id _((ID));\nint rb_is_junk_id _((ID));\nint rb_symname_p _((const char*));\nint rb_sym_interned_p _((VALUE));\nVALUE rb_backref_get _((void));\nvoid rb_backref_set _((VALUE));\nVALUE rb_lastline_get _((void));\nvoid rb_lastline_set _((VALUE));\nVALUE rb_sym_all_symbols _((void));\n/* process.c */\nint rb_proc_exec _((const char*));\nVALUE rb_f_exec _((int,VALUE*));\nint rb_waitpid _((int,int*,int));\nvoid rb_syswait _((int));\nVALUE rb_proc_times _((VALUE));\nVALUE rb_detach_process _((int));\n/* range.c */\nVALUE rb_range_new _((VALUE, VALUE, int));\nVALUE rb_range_beg_len _((VALUE, long*, long*, long, int));\nVALUE rb_length_by_each _((VALUE));\n/* random.c */\nunsigned long rb_genrand_int32(void);\ndouble rb_genrand_real(void);\n/* re.c */\nint rb_memcmp _((const void*,const void*,long));\nint rb_memcicmp _((const void*,const void*,long));\nlong rb_memsearch _((const void*,long,const void*,long));\nVALUE rb_reg_nth_defined _((int, VALUE));\nVALUE rb_reg_nth_match _((int, VALUE));\nVALUE rb_reg_last_match _((VALUE));\nVALUE rb_reg_match_pre _((VALUE));\nVALUE rb_reg_match_post _((VALUE));\nVALUE rb_reg_match_last _((VALUE));\nVALUE rb_reg_new _((const char*, long, int));\nVALUE rb_reg_match _((VALUE, VALUE));\nVALUE rb_reg_match2 _((VALUE));\nint rb_reg_options _((VALUE));\nvoid rb_set_kcode _((const char*));\nconst char* rb_get_kcode _((void));\nvoid rb_kcode_set_option _((VALUE));\nvoid rb_kcode_reset_option _((void));\n/* ruby.c */\nRUBY_EXTERN VALUE rb_argv;\nRUBY_EXTERN VALUE rb_argv0;\nvoid rb_load_file _((const char*));\nvoid ruby_script _((const char*));\nvoid ruby_prog_init _((void));\nvoid ruby_set_argv _((int, char**));\nvoid ruby_process_options _((int, char**));\nvoid ruby_load_script _((void));\nvoid ruby_init_loadpath _((void));\nvoid ruby_incpush _((const char*));\n/* signal.c */\nVALUE rb_f_kill _((int, VALUE*));\nvoid rb_gc_mark_trap_list _((void));\n#ifdef POSIX_SIGNAL\n#define posix_signal ruby_posix_signal\nvoid posix_signal _((int, RETSIGTYPE (*)(int)));\n#endif\nvoid rb_trap_exit _((void));\nvoid rb_trap_exec _((void));\nconst char *ruby_signal_name _((int));\nvoid ruby_default_signal _((int));\n/* sprintf.c */\nVALUE rb_f_sprintf _((int, VALUE*));\nVALUE rb_str_format _((int, VALUE*, VALUE));\n/* string.c */\nVALUE rb_str_new _((const char*, long));\nVALUE rb_str_new2 _((const char*));\nVALUE rb_str_new3 _((VALUE));\nVALUE rb_str_new4 _((VALUE));\nVALUE rb_str_new5 _((VALUE, const char*, long));\nVALUE rb_tainted_str_new _((const char*, long));\nVALUE rb_tainted_str_new2 _((const char*));\nVALUE rb_str_buf_new _((long));\nVALUE rb_str_buf_new2 _((const char*));\nVALUE rb_str_tmp_new _((long));\nVALUE rb_str_buf_append _((VALUE, VALUE));\nVALUE rb_str_buf_cat _((VALUE, const char*, long));\nVALUE rb_str_buf_cat2 _((VALUE, const char*));\nVALUE rb_obj_as_string _((VALUE));\nVALUE rb_check_string_type _((VALUE));\nVALUE rb_str_dup _((VALUE));\nVALUE rb_str_locktmp _((VALUE));\nVALUE rb_str_unlocktmp _((VALUE));\nVALUE rb_str_dup_frozen _((VALUE));\nVALUE rb_str_plus _((VALUE, VALUE));\nVALUE rb_str_times _((VALUE, VALUE));\nVALUE rb_str_substr _((VALUE, long, long));\nvoid rb_str_modify _((VALUE));\nVALUE rb_str_move _((VALUE));\nvoid rb_str_set_len _((VALUE, long));\nVALUE rb_str_resize _((VALUE, long));\nVALUE rb_str_cat _((VALUE, const char*, long));\nVALUE rb_str_cat2 _((VALUE, const char*));\nVALUE rb_str_append _((VALUE, VALUE));\nVALUE rb_str_concat _((VALUE, VALUE));\nint rb_str_hash _((VALUE));\nint rb_str_cmp _((VALUE, VALUE));\nVALUE rb_str_upto _((VALUE, VALUE, int));\nvoid rb_str_update _((VALUE, long, long, VALUE));\nVALUE rb_str_inspect _((VALUE));\nVALUE rb_str_dump _((VALUE));\nVALUE rb_str_split _((VALUE, const char*));\nvoid rb_str_associate _((VALUE, VALUE));\nVALUE rb_str_associated _((VALUE));\nvoid rb_str_setter _((VALUE, ID, VALUE*));\nVALUE rb_str_intern _((VALUE));\n/* struct.c */\nVALUE rb_struct_new __((VALUE, ...));\nVALUE rb_struct_define __((const char*, ...));\nVALUE rb_struct_alloc _((VALUE, VALUE));\nVALUE rb_struct_aref _((VALUE, VALUE));\nVALUE rb_struct_aset _((VALUE, VALUE, VALUE));\nVALUE rb_struct_getmember _((VALUE, ID));\nVALUE rb_struct_iv_get _((VALUE, const char*));\nVALUE rb_struct_s_members _((VALUE));\nVALUE rb_struct_members _((VALUE));\n/* time.c */\nVALUE rb_time_new _((time_t, time_t));\n/* variable.c */\nVALUE rb_mod_name _((VALUE));\nVALUE rb_class_path _((VALUE));\nvoid rb_set_class_path _((VALUE, VALUE, const char*));\nVALUE rb_path2class _((const char*));\nvoid rb_name_class _((VALUE, ID));\nVALUE rb_class_name _((VALUE));\nvoid rb_autoload _((VALUE, ID, const char*));\nVALUE rb_autoload_load _((VALUE, ID));\nVALUE rb_autoload_p _((VALUE, ID));\nvoid rb_gc_mark_global_tbl _((void));\nVALUE rb_f_trace_var _((int, VALUE*));\nVALUE rb_f_untrace_var _((int, VALUE*));\nVALUE rb_f_global_variables _((void));\nvoid rb_alias_variable _((ID, ID));\nstruct st_table* rb_generic_ivar_table _((VALUE));\nvoid rb_copy_generic_ivar _((VALUE,VALUE));\nvoid rb_mark_generic_ivar _((VALUE));\nvoid rb_mark_generic_ivar_tbl _((void));\nvoid add_generic_ivar_to_remembered_set _((VALUE));\nvoid rb_free_generic_ivar _((VALUE));\nVALUE rb_ivar_get _((VALUE, ID));\nVALUE rb_ivar_set _((VALUE, ID, VALUE));\nVALUE rb_ivar_defined _((VALUE, ID));\nVALUE rb_iv_set _((VALUE, const char*, VALUE));\nVALUE rb_iv_get _((VALUE, const char*));\nVALUE rb_attr_get _((VALUE, ID));\nVALUE rb_obj_instance_variables _((VALUE));\nVALUE rb_obj_remove_instance_variable _((VALUE, VALUE));\nvoid *rb_mod_const_at _((VALUE, void*));\nvoid *rb_mod_const_of _((VALUE, void*));\nVALUE rb_const_list _((void*));\nVALUE rb_mod_constants _((VALUE));\nVALUE rb_mod_remove_const _((VALUE, VALUE));\nint rb_const_defined _((VALUE, ID));\nint rb_const_defined_at _((VALUE, ID));\nint rb_const_defined_from _((VALUE, ID));\nVALUE rb_const_get _((VALUE, ID));\nVALUE rb_const_get_at _((VALUE, ID));\nVALUE rb_const_get_from _((VALUE, ID));\nvoid rb_const_set _((VALUE, ID, VALUE));\nVALUE rb_mod_constants _((VALUE));\nVALUE rb_mod_const_missing _((VALUE,VALUE));\nVALUE rb_cvar_defined _((VALUE, ID));\n#define RB_CVAR_SET_4ARGS 1\nvoid rb_cvar_set _((VALUE, ID, VALUE, int));\nVALUE rb_cvar_get _((VALUE, ID));\nvoid rb_cv_set _((VALUE, const char*, VALUE));\nVALUE rb_cv_get _((VALUE, const char*));\nvoid rb_define_class_variable _((VALUE, const char*, VALUE));\nVALUE rb_mod_class_variables _((VALUE));\nVALUE rb_mod_remove_cvar _((VALUE, VALUE));\n/* version.c */\nvoid ruby_show_version _((void));\nvoid ruby_show_copyright _((void));\n"
  },
  {
    "path": "io.c",
    "content": "/**********************************************************************\n\n  io.c -\n\n  $Author$\n  $Date$\n  created at: Fri Oct 15 18:08:59 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#if defined(__VMS)\n#define _XOPEN_SOURCE\n#define _POSIX_C_SOURCE 2\n#endif\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"rubysig.h\"\n#include \"env.h\"\n#include \"re.h\"\n#include <ctype.h>\n#include <errno.h>\n\n#if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__)\n# define NO_SAFE_RENAME\n#endif\n\n#if defined(MSDOS) || defined(__CYGWIN__) || defined(_WIN32)\n# define NO_LONG_FNAME\n#endif\n\n#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(sun) || defined(_nec_ews)\n# define USE_SETVBUF\n#endif\n\n#ifndef BSD_STDIO\n# if defined(__MACH__) || defined(__DARWIN__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)\n#   define BSD_STDIO 1\n# else\n#   define BSD_STDIO 0\n# endif\n#endif\n\n#ifdef __QNXNTO__\n#include \"unix.h\"\n#endif\n\n#include <sys/types.h>\n#if defined(HAVE_SYS_IOCTL_H) && !defined(DJGPP) && !defined(_WIN32) && !defined(__human68k__)\n#include <sys/ioctl.h>\n#endif\n#if defined(HAVE_FCNTL_H) || defined(_WIN32)\n#include <fcntl.h>\n#elif defined(HAVE_SYS_FCNTL_H)\n#include <sys/fcntl.h>\n#endif\n#ifdef __CYGWIN__\n#include <io.h>\n#endif\n\n#if !HAVE_OFF_T && !defined(off_t)\n# define off_t  long\n#endif\n#if !HAVE_FSEEKO && !defined(fseeko)\n# define fseeko  fseek\n#endif\n#if !HAVE_FTELLO && !defined(ftello)\n# define ftello  ftell\n#endif\n\n#include <sys/stat.h>\n\n/* EMX has sys/param.h, but.. */\n#if defined(HAVE_SYS_PARAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__))\n# include <sys/param.h>\n#endif\n\n#if !defined NOFILE\n# define NOFILE 64\n#endif\n\n#ifdef HAVE_UNISTD_H\n#ifdef HAVE_SYSCALL_H\n#include <syscall.h>\n#elif defined HAVE_SYS_SYSCALL_H\n#include <sys/syscall.h>\n#endif\n\n#include <unistd.h>\n#endif\n\nextern void Init_File _((void));\n\n#ifdef __BEOS__\n# ifndef NOFILE\n#  define NOFILE (OPEN_MAX)\n# endif\n#include <net/socket.h>\n#endif\n\n#include \"util.h\"\n\n#ifndef O_ACCMODE\n#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)\n#endif\n\n#if SIZEOF_OFF_T > SIZEOF_LONG && !defined(HAVE_LONG_LONG)\n# error off_t is bigger than long, but you have no long long...\n#endif\n\n#ifndef PIPE_BUF\n# ifdef _POSIX_PIPE_BUF\n#  define PIPE_BUF _POSIX_PIPE_BUF\n# else\n#  define PIPE_BUF 512 /* is this ok? */\n# endif\n#endif\n\n#define preserving_errno(stmts) \\\n\tdo {int saved_errno = errno; stmts; errno = saved_errno;} while (0)\n\nVALUE rb_cIO;\nVALUE rb_eEOFError;\nVALUE rb_eIOError;\n\nVALUE rb_stdin, rb_stdout, rb_stderr;\nVALUE rb_deferr;\t\t/* rescue VIM plugin */\nstatic VALUE orig_stdout, orig_stderr;\n\nVALUE rb_output_fs;\nVALUE rb_rs;\nVALUE rb_output_rs;\nVALUE rb_default_rs;\n\nstatic VALUE argf;\n\nstatic ID id_write, id_read, id_getc;\n\nextern char *ruby_inplace_mode;\n\nstruct timeval rb_time_interval _((VALUE));\n\nstatic VALUE filename, current_file;\nstatic int gets_lineno;\nstatic int init_p = 0, next_p = 0;\nstatic VALUE lineno = INT2FIX(0);\n\n#ifdef _STDIO_USES_IOSTREAM  /* GNU libc */\n#  ifdef _IO_fpos_t\n#    define READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)\n#    define READ_DATA_PENDING_COUNT(fp) ((fp)->_IO_read_end - (fp)->_IO_read_ptr)\n#    define READ_DATA_PENDING_PTR(fp) ((fp)->_IO_read_ptr)\n#  else\n#    define READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)\n#    define READ_DATA_PENDING_COUNT(fp) ((fp)->_egptr - (fp)->_gptr)\n#    define READ_DATA_PENDING_PTR(fp) ((fp)->_gptr)\n#  endif\n#elif defined(_LP64) && (defined(__sun__) || defined(__sun))\ntypedef struct _FILE64 {\n  unsigned char        *_ptr;  /* next character from/to here in buffer */\n  unsigned char        *_base; /* the buffer */\n  unsigned char        *_end;  /* the end of the buffer */\n  ssize_t      _cnt;   /* number of available characters in buffer */\n  int          _file;  /* UNIX System file descriptor */\n  unsigned int _flag;  /* the state of the stream */\n  char         __fill[80];     /* filler to bring size to 128 bytes */\n} FILE64;\n#  define READ_DATA_PENDING(fp) (((FILE64*)(fp))->_cnt > 0)\n#  define READ_DATA_PENDING_COUNT(fp) (((FILE64*)(fp))->_cnt)\n#  define READ_DATA_PENDING_PTR(fp) ((char *)((FILE64*)(fp))->_ptr)\n#elif defined(FILE_COUNT)\n#  define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)\n#  define READ_DATA_PENDING_COUNT(fp) ((fp)->FILE_COUNT)\n#elif defined(FILE_READEND)\n#  define READ_DATA_PENDING(fp) ((fp)->FILE_READPTR < (fp)->FILE_READEND)\n#  define READ_DATA_PENDING_COUNT(fp) ((fp)->FILE_READEND - (fp)->FILE_READPTR)\n#elif defined(__BEOS__)\n#  define READ_DATA_PENDING(fp) (fp->_state._eof == 0)\n#elif defined(__VMS)\n#  define READ_DATA_PENDING_COUNT(fp) ((unsigned int)(*(fp))->_cnt)\n#  define READ_DATA_PENDING(fp)       (((unsigned int)(*(fp))->_cnt) > 0)\n#  define READ_DATA_BUFFERED(fp) 0\n#elif defined(__DragonFly__)\n/* FILE is an incomplete struct type since DragonFly BSD 1.4.0 */\n#  define READ_DATA_PENDING(fp) (((struct __FILE_public *)(fp))->_r > 0)\n#  define READ_DATA_PENDING_COUNT(fp) (((struct __FILE_public *)(fp))->_r)\n#else\n/* requires systems own version of the ReadDataPending() */\nextern int ReadDataPending();\n#  define READ_DATA_PENDING(fp) (!feof(fp))\n#  define READ_DATA_BUFFERED(fp) 0\n#endif\n#ifndef READ_DATA_BUFFERED\n#  define READ_DATA_BUFFERED(fp) READ_DATA_PENDING(fp)\n#endif\n\n#ifndef READ_DATA_PENDING_PTR\n# ifdef FILE_READPTR\n#  define READ_DATA_PENDING_PTR(fp) ((char *)(fp)->FILE_READPTR)\n# endif\n#endif\n\n#if defined __DJGPP__\n# undef READ_DATA_PENDING_COUNT\n# undef READ_DATA_PENDING_PTR\n#endif\n\n#define READ_CHECK(fp) do {\\\n    if (!READ_DATA_PENDING(fp)) {\\\n\trb_thread_wait_fd(fileno(fp));\\\n        rb_io_check_closed(fptr);\\\n     }\\\n} while(0)\n\nvoid\nrb_eof_error()\n{\n    rb_raise(rb_eEOFError, \"end of file reached\");\n}\n\nVALUE\nrb_io_taint_check(io)\n    VALUE io;\n{\n    if (!OBJ_TAINTED(io) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: operation on untainted IO\");\n    rb_check_frozen(io);\n    return io;\n}\n\nvoid\nrb_io_check_initialized(fptr)\n    rb_io_t *fptr;\n{\n    if (!fptr) {\n\trb_raise(rb_eIOError, \"uninitialized stream\");\n    }\n}\n\nvoid\nrb_io_check_closed(fptr)\n    rb_io_t *fptr;\n{\n    rb_io_check_initialized(fptr);\n    if (!fptr->f && !fptr->f2) {\n\trb_raise(rb_eIOError, \"closed stream\");\n    }\n}\n\nstatic void io_fflush _((FILE *, rb_io_t *));\n\nstatic rb_io_t *\nflush_before_seek(fptr)\n    rb_io_t *fptr;\n{\n    if (fptr->mode & FMODE_WBUF) {\n\tio_fflush(GetWriteFile(fptr), fptr);\n    }\n    errno = 0;\n    return fptr;\n}\n\n#define io_seek(fptr, ofs, whence) fseeko(flush_before_seek(fptr)->f, ofs, whence)\n#define io_tell(fptr) ftello(flush_before_seek(fptr)->f)\n\n#ifndef SEEK_CUR\n# define SEEK_SET 0\n# define SEEK_CUR 1\n# define SEEK_END 2\n#endif\n\n#define FMODE_SYNCWRITE (FMODE_SYNC|FMODE_WRITABLE)\n\nvoid\nrb_io_check_readable(fptr)\n    rb_io_t *fptr;\n{\n    rb_io_check_closed(fptr);\n    if (!(fptr->mode & FMODE_READABLE)) {\n\trb_raise(rb_eIOError, \"not opened for reading\");\n    }\n#ifdef NEED_IO_SEEK_BETWEEN_RW\n    if (((fptr->mode & FMODE_WBUF) ||\n\t (fptr->mode & (FMODE_SYNCWRITE|FMODE_RBUF)) == FMODE_SYNCWRITE) &&\n\t!feof(fptr->f) &&\n\t!fptr->f2) {\n\tio_seek(fptr, 0, SEEK_CUR);\n    }\n#endif\n    fptr->mode |= FMODE_RBUF;\n}\n\nvoid\nrb_io_check_writable(fptr)\n    rb_io_t *fptr;\n{\n    rb_io_check_closed(fptr);\n    if (!(fptr->mode & FMODE_WRITABLE)) {\n\trb_raise(rb_eIOError, \"not opened for writing\");\n    }\n    if ((fptr->mode & FMODE_RBUF) && !feof(fptr->f) && !fptr->f2) {\n\tio_seek(fptr, 0, SEEK_CUR);\n    }\n    if (!fptr->f2) {\n\tfptr->mode &= ~FMODE_RBUF;\n    }\n}\n\nint\nrb_read_pending(fp)\n    FILE *fp;\n{\n    return READ_DATA_PENDING(fp);\n}\n\nvoid\nrb_read_check(fp)\n    FILE *fp;\n{\n    if (!READ_DATA_PENDING(fp)) {\n\trb_thread_wait_fd(fileno(fp));\n    }\n}\n\nstatic int\nruby_dup(orig)\n    int orig;\n{\n    int fd;\n\n    fd = dup(orig);\n    if (fd < 0) {\n\tif (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {\n\t    rb_gc();\n\t    fd = dup(orig);\n\t}\n\tif (fd < 0) {\n\t    rb_sys_fail(0);\n\t}\n    }\n    return fd;\n}\n\nstatic VALUE io_alloc _((VALUE));\nstatic VALUE\nio_alloc(klass)\n    VALUE klass;\n{\n    NEWOBJ(io, struct RFile);\n    OBJSETUP(io, klass, T_FILE);\n\n    io->fptr = 0;\n\n    return (VALUE)io;\n}\n\nstatic void\nio_fflush(f, fptr)\n    FILE *f;\n    rb_io_t *fptr;\n{\n    int n;\n\n    if (!rb_thread_fd_writable(fileno(f))) {\n        rb_io_check_closed(fptr);\n    }\n    for (;;) {\n\tTRAP_BEG;\n\tn = fflush(f);\n\tTRAP_END;\n\tif (n != EOF) break;\n\tif (!rb_io_wait_writable(fileno(f)))\n\t    rb_sys_fail(fptr->path);\n    }\n    fptr->mode &= ~FMODE_WBUF;\n}\n\nint\nrb_io_wait_readable(f)\n    int f;\n{\n    fd_set rfds;\n\n    switch (errno) {\n      case EINTR:\n#if defined(ERESTART)\n      case ERESTART:\n#endif\n\trb_thread_wait_fd(f);\n\treturn Qtrue;\n\n      case EAGAIN:\n#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN\n      case EWOULDBLOCK:\n#endif\n\tFD_ZERO(&rfds);\n\tFD_SET(f, &rfds);\n\trb_thread_select(f + 1, &rfds, NULL, NULL, NULL);\n\treturn Qtrue;\n\n      default:\n\treturn Qfalse;\n    }\n}\n\nint\nrb_io_wait_writable(f)\n    int f;\n{\n    fd_set wfds;\n\n    switch (errno) {\n      case EINTR:\n#if defined(ERESTART)\n      case ERESTART:\n#endif\n\trb_thread_fd_writable(f);\n\treturn Qtrue;\n\n      case EAGAIN:\n#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN\n      case EWOULDBLOCK:\n#endif\n\tFD_ZERO(&wfds);\n\tFD_SET(f, &wfds);\n\trb_thread_select(f + 1, NULL, &wfds, NULL, NULL);\n\treturn Qtrue;\n\n      default:\n\treturn Qfalse;\n    }\n}\n\n#ifndef S_ISREG\n#   define S_ISREG(m) ((m & S_IFMT) == S_IFREG)\n#endif\n\nstatic int\nwsplit_p(rb_io_t *fptr)\n{\n    FILE *f = GetWriteFile(fptr);\n#if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)\n    int r;\n#endif\n\n    if (!(fptr->mode & FMODE_WSPLIT_INITIALIZED)) {\n        struct stat buf;\n        if (fstat(fileno(f), &buf) == 0 &&\n            !S_ISREG(buf.st_mode)\n#if defined(HAVE_FCNTL) && defined(F_GETFL) && defined(O_NONBLOCK)\n            && (r = fcntl(fileno(f), F_GETFL)) != -1 &&\n            !(r & O_NONBLOCK)\n#endif\n            ) {\n            fptr->mode |= FMODE_WSPLIT;\n        }\n        fptr->mode |= FMODE_WSPLIT_INITIALIZED;\n    }\n    return fptr->mode & FMODE_WSPLIT;\n}\n\n/* writing functions */\nstatic long\nio_fwrite(str, fptr)\n    VALUE str;\n    rb_io_t *fptr;\n{\n    long len, n, r, l, offset = 0;\n    FILE *f = GetWriteFile(fptr);\n\n    len = RSTRING(str)->len;\n    if ((n = len) <= 0) return n;\n    if (fptr->mode & FMODE_SYNC) {\n\tio_fflush(f, fptr);\n\tif (!rb_thread_fd_writable(fileno(f))) {\n\t    rb_io_check_closed(fptr);\n\t}\n      retry:\n        l = n;\n        if (PIPE_BUF < l &&\n            !rb_thread_critical &&\n            !rb_thread_alone() &&\n            wsplit_p(fptr)) {\n            l = PIPE_BUF;\n        }\n        TRAP_BEG;\n\tr = write(fileno(f), RSTRING(str)->ptr+offset, l);\n        TRAP_END;\n#if BSD_STDIO\n\tpreserving_errno(fseeko(f, lseek(fileno(f), (off_t)0, SEEK_CUR), SEEK_SET));\n#endif\n        if (r == n) return len;\n        if (0 <= r) {\n            offset += r;\n            n -= r;\n            errno = EAGAIN;\n        }\n        if (rb_io_wait_writable(fileno(f))) {\n            rb_io_check_closed(fptr);\n\t    if (offset < RSTRING(str)->len)\n\t\tgoto retry;\n        }\n        return -1L;\n    }\n#if defined(__human68k__) || defined(__vms)\n    do {\n\tif (fputc(RSTRING(str)->ptr[offset++], f) == EOF) {\n\t    if (ferror(f)) return -1L;\n\t    break;\n\t}\n    } while (--n > 0);\n#else\n    while (errno = 0, offset += (r = fwrite(RSTRING(str)->ptr+offset, 1, n, f)), (n -= r) > 0) {\n\tif (ferror(f)\n#if defined __BORLANDC__\n\t    || errno\n#endif\n\t) {\n#ifdef __hpux\n\t    if (!errno) errno = EAGAIN;\n#elif defined(_WIN32) && !defined(__BORLANDC__)\n\t    /* workaround for MSVCRT's bug */\n\t    if (!errno) {\n\t\tif (GetLastError() == ERROR_NO_DATA)\n\t\t    errno = EPIPE;\n\t\telse\n\t\t    errno = EBADF;\n\t    }\n#endif\n\t    if (rb_io_wait_writable(fileno(f))) {\n\t\trb_io_check_closed(fptr);\n\t\tclearerr(f);\n\t\tif (offset < RSTRING(str)->len)\n\t\t    continue;\n\t    }\n\t    return -1L;\n\t}\n    }\n#endif\n    return len - n;\n}\n\nlong\nrb_io_fwrite(ptr, len, f)\n    const char *ptr;\n    long len;\n    FILE *f;\n{\n    rb_io_t of;\n\n    of.f = f;\n    of.f2 = NULL;\n    of.mode = FMODE_WRITABLE;\n    of.path = NULL;\n    return io_fwrite(rb_str_new(ptr, len), &of);\n}\n\n/*\n *  call-seq:\n *     ios.write(string)    => integer\n *  \n *  Writes the given string to <em>ios</em>. The stream must be opened\n *  for writing. If the argument is not a string, it will be converted\n *  to a string using <code>to_s</code>. Returns the number of bytes\n *  written.\n *     \n *     count = $stdout.write( \"This is a test\\n\" )\n *     puts \"That was #{count} bytes of data\"\n *     \n *  <em>produces:</em>\n *     \n *     This is a test\n *     That was 15 bytes of data\n */\n\nstatic VALUE\nio_write(io, str)\n    VALUE io, str;\n{\n    rb_io_t *fptr;\n    long n;\n\n    rb_secure(4);\n    if (TYPE(str) != T_STRING)\n\tstr = rb_obj_as_string(str);\n\n    if (TYPE(io) != T_FILE) {\n\t/* port is not IO, call write method for it. */\n\treturn rb_funcall(io, id_write, 1, str);\n    }\n    if (RSTRING(str)->len == 0) return INT2FIX(0);\n\n    GetOpenFile(io, fptr);\n    rb_io_check_writable(fptr);\n\n    n = io_fwrite(str, fptr);\n    if (n == -1L) rb_sys_fail(fptr->path);\n    if (!(fptr->mode & FMODE_SYNC)) {\n\tfptr->mode |= FMODE_WBUF;\n    }\n\n    return LONG2FIX(n);\n}\n\nVALUE\nrb_io_write(io, str)\n    VALUE io, str;\n{\n    return rb_funcall(io, id_write, 1, str);\n}\n\n/*\n *  call-seq:\n *     ios << obj     => ios\n *  \n *  String Output---Writes <i>obj</i> to <em>ios</em>.\n *  <i>obj</i> will be converted to a string using\n *  <code>to_s</code>.\n *     \n *     $stdout << \"Hello \" << \"world!\\n\"\n *     \n *  <em>produces:</em>\n *     \n *     Hello world!\n */\n\nVALUE\nrb_io_addstr(io, str)\n    VALUE io, str;\n{\n    rb_io_write(io, str);\n    return io;\n}\n\n/*\n *  call-seq:\n *     ios.flush    => ios\n *  \n *  Flushes any buffered data within <em>ios</em> to the underlying\n *  operating system (note that this is Ruby internal buffering only;\n *  the OS may buffer the data as well).\n *     \n *     $stdout.print \"no newline\"\n *     $stdout.flush\n *     \n *  <em>produces:</em>\n *     \n *     no newline\n */\n\nstatic VALUE\nrb_io_flush(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    FILE *f;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_writable(fptr);\n    f = GetWriteFile(fptr);\n\n    io_fflush(f, fptr);\n#ifdef _WIN32\n    fsync(fileno(f));\n#endif\n\n    return io;\n}\n\n/*\n *  call-seq:\n *     ios.pos     => integer\n *     ios.tell    => integer\n *  \n *  Returns the current offset (in bytes) of <em>ios</em>.\n *     \n *     f = File.new(\"testfile\")\n *     f.pos    #=> 0\n *     f.gets   #=> \"This is line one\\n\"\n *     f.pos    #=> 17\n */\n\nstatic VALUE\nrb_io_tell(io)\n     VALUE io;\n{\n    rb_io_t *fptr;\n    off_t pos;\n\n    GetOpenFile(io, fptr);\n    pos = io_tell(fptr);\n    if (pos < 0 && errno) rb_sys_fail(fptr->path);\n    return OFFT2NUM(pos);\n}\n\nstatic VALUE\nrb_io_seek(io, offset, whence)\n    VALUE io, offset;\n    int whence;\n{\n    rb_io_t *fptr;\n    off_t pos;\n\n    pos = NUM2OFFT(offset);\n    GetOpenFile(io, fptr);\n    pos = io_seek(fptr, pos, whence);\n    if (pos < 0 && errno) rb_sys_fail(fptr->path);\n    clearerr(fptr->f);\n\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     ios.seek(amount, whence=SEEK_SET) -> 0\n *  \n *  Seeks to a given offset <i>anInteger</i> in the stream according to\n *  the value of <i>whence</i>:\n *\n *    IO::SEEK_CUR  | Seeks to _amount_ plus current position\n *    --------------+----------------------------------------------------\n *    IO::SEEK_END  | Seeks to _amount_ plus end of stream (you probably \n *                  | want a negative value for _amount_)\n *    --------------+----------------------------------------------------\n *    IO::SEEK_SET  | Seeks to the absolute location given by _amount_\n *\n *  Example:\n *     \n *     f = File.new(\"testfile\")\n *     f.seek(-13, IO::SEEK_END)   #=> 0\n *     f.readline                  #=> \"And so on...\\n\"\n */\n\nstatic VALUE\nrb_io_seek_m(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE offset, ptrname;\n    int whence = SEEK_SET;\n\n    if (rb_scan_args(argc, argv, \"11\", &offset, &ptrname) == 2) {\n\twhence = NUM2INT(ptrname);\n    }\n\n    return rb_io_seek(io, offset, whence);\n}\n\n/*\n *  call-seq:\n *     ios.pos = integer    => integer\n *  \n *  Seeks to the given position (in bytes) in <em>ios</em>.\n *     \n *     f = File.new(\"testfile\")\n *     f.pos = 17\n *     f.gets   #=> \"This is line two\\n\"\n */\n\nstatic VALUE\nrb_io_set_pos(io, offset)\n     VALUE io, offset;\n{\n    rb_io_t *fptr;\n    off_t pos;\n\n    pos = NUM2OFFT(offset);\n    GetOpenFile(io, fptr);\n    pos = io_seek(fptr, pos, SEEK_SET);\n    if (pos != 0) rb_sys_fail(fptr->path);\n    clearerr(fptr->f);\n\n    return OFFT2NUM(pos);\n}\n\n/*\n *  call-seq:\n *     ios.rewind    => 0\n *  \n *  Positions <em>ios</em> to the beginning of input, resetting\n *  <code>lineno</code> to zero.\n *     \n *     f = File.new(\"testfile\")\n *     f.readline   #=> \"This is line one\\n\"\n *     f.rewind     #=> 0\n *     f.lineno     #=> 0\n *     f.readline   #=> \"This is line one\\n\"\n */\n\nstatic VALUE\nrb_io_rewind(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    if (io_seek(fptr, 0L, 0) != 0) rb_sys_fail(fptr->path);\n    clearerr(fptr->f);\n    if (io == current_file) {\n\tgets_lineno -= fptr->lineno;\n    }\n    fptr->lineno = 0;\n\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     ios.eof     => true or false\n *     ios.eof?    => true or false\n *\n *  Returns true if <em>ios</em> is at end of file that means\n *  there are no more data to read.\n *  The stream must be opened for reading or an <code>IOError</code> will be\n *  raised.\n *\n *     f = File.new(\"testfile\")\n *     dummy = f.readlines\n *     f.eof   #=> true\n *\n *  If <em>ios</em> is a stream such as pipe or socket, <code>IO#eof?</code>\n *  blocks until the other end sends some data or closes it.\n *\n *     r, w = IO.pipe\n *     Thread.new { sleep 1; w.close }\n *     r.eof?  #=> true after 1 second blocking\n *\n *     r, w = IO.pipe\n *     Thread.new { sleep 1; w.puts \"a\" }\n *     r.eof?  #=> false after 1 second blocking\n *\n *     r, w = IO.pipe\n *     r.eof?  # blocks forever\n *\n *  Note that <code>IO#eof?</code> reads data to a input buffer.\n *  So <code>IO#sysread</code> doesn't work with <code>IO#eof?</code>.\n */\n\nVALUE\nrb_io_eof(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    int ch;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n\n    if (feof(fptr->f)) return Qtrue;\n    if (READ_DATA_PENDING(fptr->f)) return Qfalse;\n    READ_CHECK(fptr->f);\n    clearerr(fptr->f);\n    TRAP_BEG;\n    ch = getc(fptr->f);\n    TRAP_END;\n\n    if (ch != EOF) {\n\tungetc(ch, fptr->f);\n\treturn Qfalse;\n    }\n    rb_io_check_closed(fptr);\n    clearerr(fptr->f);\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     ios.sync    => true or false\n *  \n *  Returns the current ``sync mode'' of <em>ios</em>. When sync mode is\n *  true, all output is immediately flushed to the underlying operating\n *  system and is not buffered by Ruby internally. See also\n *  <code>IO#fsync</code>.\n *     \n *     f = File.new(\"testfile\")\n *     f.sync   #=> false\n */\n\nstatic VALUE\nrb_io_sync(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    return (fptr->mode & FMODE_SYNC) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     ios.sync = boolean   => boolean\n *  \n *  Sets the ``sync mode'' to <code>true</code> or <code>false</code>.\n *  When sync mode is true, all output is immediately flushed to the\n *  underlying operating system and is not buffered internally. Returns\n *  the new state. See also <code>IO#fsync</code>.\n *     \n *     f = File.new(\"testfile\")\n *     f.sync = true\n *     \n *  <em>(produces no output)</em>\n */\n\nstatic VALUE\nrb_io_set_sync(io, mode)\n    VALUE io, mode;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    if (RTEST(mode)) {\n\tfptr->mode |= FMODE_SYNC;\n    }\n    else {\n\tfptr->mode &= ~FMODE_SYNC;\n    }\n    return mode;\n}\n\n/*\n *  call-seq:\n *     ios.fsync   => 0 or nil\n *  \n *  Immediately writes all buffered data in <em>ios</em> to disk.\n *  Returns <code>nil</code> if the underlying operating system does not\n *  support <em>fsync(2)</em>. Note that <code>fsync</code> differs from\n *  using <code>IO#sync=</code>. The latter ensures that data is flushed\n *  from Ruby's buffers, but doesn't not guarantee that the underlying\n *  operating system actually writes it to disk.\n */\n\nstatic VALUE\nrb_io_fsync(io)\n    VALUE io;\n{\n#ifdef HAVE_FSYNC\n    rb_io_t *fptr;\n    FILE *f;\n\n    GetOpenFile(io, fptr);\n    f = GetWriteFile(fptr);\n\n    io_fflush(f, fptr);\n    if (fsync(fileno(f)) < 0)\n\trb_sys_fail(fptr->path);\n    return INT2FIX(0);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n/*\n *  call-seq:\n *     ios.fileno    => fixnum\n *     ios.to_i      => fixnum\n *  \n *  Returns an integer representing the numeric file descriptor for\n *  <em>ios</em>.\n *     \n *     $stdin.fileno    #=> 0\n *     $stdout.fileno   #=> 1\n */\n\nstatic VALUE\nrb_io_fileno(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    int fd;\n\n    GetOpenFile(io, fptr);\n    fd = fileno(fptr->f);\n    return INT2FIX(fd);\n}\n\n/*\n *  call-seq:\n *     ios.pid    => fixnum\n *  \n *  Returns the process ID of a child process associated with\n *  <em>ios</em>. This will be set by <code>IO::popen</code>.\n *     \n *     pipe = IO.popen(\"-\")\n *     if pipe\n *       $stderr.puts \"In parent, child pid is #{pipe.pid}\"\n *     else\n *       $stderr.puts \"In child, pid is #{$$}\"\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     In child, pid is 26209\n *     In parent, child pid is 26209\n */\n\nstatic VALUE\nrb_io_pid(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    if (!fptr->pid)\n\treturn Qnil;\n    return INT2FIX(fptr->pid);\n}\n\n/*\n * call-seq:\n *   ios.inspect   => string\n *\n * Return a string describing this IO object.\n */\n\nstatic VALUE\nrb_io_inspect(obj)\n    VALUE obj;\n{\n    rb_io_t *fptr;\n    char *buf;\n    const char *cname, *st = \"\";\n    long len;\n\n    fptr = RFILE(rb_io_taint_check(obj))->fptr;\n    if (!fptr || !fptr->path) return rb_any_to_s(obj);\n    cname = rb_obj_classname(obj);\n    len = strlen(cname) + strlen(fptr->path) + 5;\n    if (!(fptr->f || fptr->f2)) {\n\tst = \" (closed)\";\n\tlen += 9;\n    }\n    buf = ALLOCA_N(char, len);\n    snprintf(buf, len, \"#<%s:%s%s>\", cname, fptr->path, st);\n    return rb_str_new2(buf);\n}\n\n/*\n *  call-seq:\n *     ios.to_io -> ios\n *  \n *  Returns <em>ios</em>.\n */\n\nstatic VALUE\nrb_io_to_io(io)\n    VALUE io;\n{\n    return io;\n}\n\n/* reading functions */\nstatic long\nread_buffered_data(ptr, len, f)\n    char *ptr;\n    long len;\n    FILE *f;\n{\n    long n;\n\n#ifdef READ_DATA_PENDING_COUNT\n    n = READ_DATA_PENDING_COUNT(f);\n    if (n <= 0) return 0;\n    if (n > len) n = len;\n    return fread(ptr, 1, n, f);\n#else\n    int c;\n\n    for (n = 0; n < len && READ_DATA_PENDING(f) && (c = getc(f)) != EOF; ++n) {\n\t*ptr++ = c;\n    }\n    return n;\n#endif\n}\n\nstatic long\nio_fread(ptr, len, fptr)\n    char *ptr;\n    long len;\n    rb_io_t *fptr;\n{\n    long n = len;\n    int c;\n    int saved_errno;\n\n    while (n > 0) {\n        c = read_buffered_data(ptr, n, fptr->f);\n        if (c < 0) goto eof;\n        if (c > 0) {\n            ptr += c;\n            if ((n -= c) <= 0) break;\n        }\n        rb_thread_wait_fd(fileno(fptr->f));\n        rb_io_check_closed(fptr);\n\tclearerr(fptr->f);\n\tTRAP_BEG;\n\tc = getc(fptr->f);\n\tTRAP_END;\n\tif (c == EOF) {\n\t  eof:\n\t    if (ferror(fptr->f)) {\n\t\tswitch (errno) {\n\t\t  case EINTR:\n#if defined(ERESTART)\n\t\t  case ERESTART:\n#endif\n\t\t    clearerr(fptr->f);\n\t\t    continue;\n\t\t  case EAGAIN:\n#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN\n\t\t  case EWOULDBLOCK:\n#endif\n\t\t    if (len > n) {\n\t\t\tclearerr(fptr->f);\n\t\t    }\n                    saved_errno = errno;\n                    rb_warning(\"nonblocking IO#read is obsolete; use IO#readpartial or IO#sysread\");\n                    errno = saved_errno;\n\t\t}\n\t\tif (len == n) return 0;\n\t    }\n\t    break;\n\t}\n\t*ptr++ = c;\n\tn--;\n    }\n    return len - n;\n}\n\nlong\nrb_io_fread(ptr, len, f)\n    char *ptr;\n    long len;\n    FILE *f;\n{\n    rb_io_t of;\n\n    of.f = f;\n    of.f2 = NULL;\n    return io_fread(ptr, len, &of);\n}\n\n#define SMALLBUF 100\n\nstatic long\nremain_size(fptr)\n    rb_io_t *fptr;\n{\n    struct stat st;\n    off_t siz = BUFSIZ;\n    off_t pos;\n\n    if (feof(fptr->f)) return 0;\n    if (fstat(fileno(fptr->f), &st) == 0  && S_ISREG(st.st_mode)\n#ifdef __BEOS__\n\t&& (st.st_dev > 3)\n#endif\n\t)\n    {\n\tpos = io_tell(fptr);\n\tif (st.st_size >= pos && pos >= 0) {\n\t    siz = st.st_size - pos + 1;\n\t    if (siz > LONG_MAX) {\n\t\trb_raise(rb_eIOError, \"file too big for single read\");\n\t    }\n\t}\n    }\n    return (long)siz;\n}\n\nstatic VALUE\nread_all(fptr, siz, str)\n    rb_io_t *fptr;\n    long siz;\n    VALUE str;\n{\n    long bytes = 0;\n    long n;\n\n    if (siz == 0) siz = BUFSIZ;\n    if (NIL_P(str)) {\n\tstr = rb_str_new(0, siz);\n    }\n    else {\n\trb_str_resize(str, siz);\n    }\n    for (;;) {\n\trb_str_locktmp(str);\n\tREAD_CHECK(fptr->f);\n\tn = io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr);\n\trb_str_unlocktmp(str);\n\tif (n == 0 && bytes == 0) {\n\t    if (!fptr->f) break;\n\t    if (feof(fptr->f)) break;\n\t    if (!ferror(fptr->f)) break;\n\t    rb_sys_fail(fptr->path);\n\t}\n\tbytes += n;\n\tif (bytes < siz) break;\n\tsiz += BUFSIZ;\n\trb_str_resize(str, siz);\n    }\n    if (bytes != siz) rb_str_resize(str, bytes);\n    OBJ_TAINT(str);\n\n    return str;\n}\n\nvoid rb_io_set_nonblock(rb_io_t *fptr)\n{\n    int flags;\n#ifdef F_GETFL\n    flags = fcntl(fileno(fptr->f), F_GETFL);\n    if (flags == -1) {\n        rb_sys_fail(fptr->path);\n    }\n#else\n    flags = 0;\n#endif\n    if ((flags & O_NONBLOCK) == 0) {\n        flags |= O_NONBLOCK;\n        if (fcntl(fileno(fptr->f), F_SETFL, flags) == -1) {\n            rb_sys_fail(fptr->path);\n        }\n    }\n    if (fptr->f2) {\n#ifdef F_GETFL\n        flags = fcntl(fileno(fptr->f2), F_GETFL);\n        if (flags == -1) {\n            rb_sys_fail(fptr->path);\n        }\n#else\n        flags = 0;\n#endif\n        if ((flags & O_NONBLOCK) == 0) {\n            flags |= O_NONBLOCK;\n            if (fcntl(fileno(fptr->f2), F_SETFL, flags) == -1) {\n                rb_sys_fail(fptr->path);\n            }\n        }\n    }\n}\n\nstatic VALUE\nio_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)\n{\n    rb_io_t *fptr;\n    VALUE length, str;\n    long n, len;\n\n    rb_scan_args(argc, argv, \"11\", &length, &str);\n\n    if ((len = NUM2LONG(length)) < 0) {\n        rb_raise(rb_eArgError, \"negative length %ld given\", len);\n    }\n\n    if (NIL_P(str)) {\n        str = rb_str_new(0, len);\n    }\n    else {\n        StringValue(str);\n        rb_str_modify(str);\n        rb_str_resize(str, len);\n    }\n    OBJ_TAINT(str);\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n\n    if (len == 0)\n        return str;\n\n    if (!nonblock) {\n        READ_CHECK(fptr->f);\n    }\n    if (RSTRING(str)->len != len) {\n      modified:\n        rb_raise(rb_eRuntimeError, \"buffer string modified\");\n    }\n    n = read_buffered_data(RSTRING(str)->ptr, len, fptr->f);\n    if (n <= 0) {\n      again:\n        if (RSTRING(str)->len != len) goto modified;\n        if (nonblock) {\n            rb_io_set_nonblock(fptr);\n            n = read(fileno(fptr->f), RSTRING(str)->ptr, len);\n        }\n        else {\n            TRAP_BEG;\n            n = read(fileno(fptr->f), RSTRING(str)->ptr, len);\n            TRAP_END;\n        }\n        if (n < 0) {\n            if (!nonblock && rb_io_wait_readable(fileno(fptr->f)))\n                goto again;\n            rb_sys_fail(fptr->path);\n        }\n        if (fptr->f) /* update pos in FILE structure [ruby-core:21561] */\n            fflush(fptr->f);\n    }\n    rb_str_resize(str, n);\n\n    if (n == 0)\n        return Qnil;\n    else\n        return str;\n}\n\n/*\n *  call-seq:\n *     ios.readpartial(maxlen)              => string\n *     ios.readpartial(maxlen, outbuf)      => outbuf\n *\n *  Reads at most <i>maxlen</i> bytes from the I/O stream.\n *  It blocks only if <em>ios</em> has no data immediately available.\n *  It doesn't block if some data available.\n *  If the optional <i>outbuf</i> argument is present,\n *  it must reference a String, which will receive the data.\n *  It raises <code>EOFError</code> on end of file.\n *\n *  readpartial is designed for streams such as pipe, socket, tty, etc.\n *  It blocks only when no data immediately available.\n *  This means that it blocks only when following all conditions hold.\n *  * the buffer in the IO object is empty.\n *  * the content of the stream is empty.\n *  * the stream is not reached to EOF.\n *\n *  When readpartial blocks, it waits data or EOF on the stream.\n *  If some data is reached, readpartial returns with the data.\n *  If EOF is reached, readpartial raises EOFError.\n *\n *  When readpartial doesn't blocks, it returns or raises immediately.\n *  If the buffer is not empty, it returns the data in the buffer.\n *  Otherwise if the stream has some content,\n *  it returns the data in the stream. \n *  Otherwise if the stream is reached to EOF, it raises EOFError.\n *\n *     r, w = IO.pipe           #               buffer          pipe content\n *     w << \"abc\"               #               \"\"              \"abc\".\n *     r.readpartial(4096)      #=> \"abc\"       \"\"              \"\"\n *     r.readpartial(4096)      # blocks because buffer and pipe is empty.\n *\n *     r, w = IO.pipe           #               buffer          pipe content\n *     w << \"abc\"               #               \"\"              \"abc\"\n *     w.close                  #               \"\"              \"abc\" EOF\n *     r.readpartial(4096)      #=> \"abc\"       \"\"              EOF\n *     r.readpartial(4096)      # raises EOFError\n *\n *     r, w = IO.pipe           #               buffer          pipe content\n *     w << \"abc\\ndef\\n\"        #               \"\"              \"abc\\ndef\\n\"\n *     r.gets                   #=> \"abc\\n\"     \"def\\n\"         \"\"\n *     w << \"ghi\\n\"             #               \"def\\n\"         \"ghi\\n\"\n *     r.readpartial(4096)      #=> \"def\\n\"     \"\"              \"ghi\\n\"\n *     r.readpartial(4096)      #=> \"ghi\\n\"     \"\"              \"\"\n *\n *  Note that readpartial behaves similar to sysread.\n *  The differences are:\n *  * If the buffer is not empty, read from the buffer instead of \"sysread for buffered IO (IOError)\".\n *  * It doesn't cause Errno::EAGAIN and Errno::EINTR.  When readpartial meets EAGAIN and EINTR by read system call, readpartial retry the system call.\n *\n *  The later means that readpartial is nonblocking-flag insensitive.\n *  It blocks on the situation IO#sysread causes Errno::EAGAIN as if the fd is blocking mode.\n *\n */\n\nstatic VALUE\nio_readpartial(int argc, VALUE *argv, VALUE io)\n{\n    VALUE ret;\n\n    ret = io_getpartial(argc, argv, io, 0);\n    if (NIL_P(ret))\n        rb_eof_error();\n    else\n        return ret;\n}\n\n/*\n *  call-seq:\n *     ios.read_nonblock(maxlen)              => string\n *     ios.read_nonblock(maxlen, outbuf)      => outbuf\n *\n *  Reads at most <i>maxlen</i> bytes from <em>ios</em> using\n *  read(2) system call after O_NONBLOCK is set for\n *  the underlying file descriptor.\n *\n *  If the optional <i>outbuf</i> argument is present,\n *  it must reference a String, which will receive the data.\n *\n *  read_nonblock just calls read(2).\n *  It causes all errors read(2) causes: EAGAIN, EINTR, etc.\n *  The caller should care such errors.\n *\n *  read_nonblock causes EOFError on EOF.\n *\n *  If the read buffer is not empty,\n *  read_nonblock reads from the buffer like readpartial.\n *  In this case, read(2) is not called.\n *\n */\n\nstatic VALUE\nio_read_nonblock(int argc, VALUE *argv, VALUE io)\n{\n    VALUE ret;\n\n    ret = io_getpartial(argc, argv, io, 1);\n    if (NIL_P(ret))\n        rb_eof_error();\n    else\n        return ret;\n}\n\n/*\n *  call-seq:\n *     ios.write_nonblock(string)   => integer\n *\n *  Writes the given string to <em>ios</em> using\n *  write(2) system call after O_NONBLOCK is set for\n *  the underlying file descriptor.\n *\n *  write_nonblock just calls write(2).\n *  It causes all errors write(2) causes: EAGAIN, EINTR, etc.\n *  The result may also be smaller than string.length (partial write).\n *  The caller should care such errors and partial write.\n *\n */\n\nstatic VALUE\nrb_io_write_nonblock(VALUE io, VALUE str)\n{\n    rb_io_t *fptr;\n    FILE *f;\n    long n;\n\n    rb_secure(4);\n    if (TYPE(str) != T_STRING)\n\tstr = rb_obj_as_string(str);\n\n    GetOpenFile(io, fptr);\n    rb_io_check_writable(fptr);\n\n    f = GetWriteFile(fptr);\n\n    rb_io_set_nonblock(fptr);\n    n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len);\n\n    if (n == -1) rb_sys_fail(fptr->path);\n\n    return LONG2FIX(n);\n}\n\n/*\n *  call-seq:\n *     ios.read([length [, buffer]])    => string, buffer, or nil\n *\n *  Reads at most <i>length</i> bytes from the I/O stream, or to the\n *  end of file if <i>length</i> is omitted or is <code>nil</code>.\n *  <i>length</i> must be a non-negative integer or nil.\n *  If the optional <i>buffer</i> argument is present, it must reference\n *  a String, which will receive the data.\n *\n *  At end of file, it returns <code>nil</code> or <code>\"\"</code>\n *  depend on <i>length</i>.\n *  <code><i>ios</i>.read()</code> and\n *  <code><i>ios</i>.read(nil)</code> returns <code>\"\"</code>.\n *  <code><i>ios</i>.read(<i>positive-integer</i>)</code> returns nil.\n *\n *     f = File.new(\"testfile\")\n *     f.read(16)   #=> \"This is line one\"\n */\n\nstatic VALUE\nio_read(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    rb_io_t *fptr;\n    long n, len;\n    VALUE length, str;\n\n    rb_scan_args(argc, argv, \"02\", &length, &str);\n\n    if (NIL_P(length)) {\n\tif (!NIL_P(str)) StringValue(str);\n\tGetOpenFile(io, fptr);\n\trb_io_check_readable(fptr);\t\n\treturn read_all(fptr, remain_size(fptr), str);\n    }\n    len = NUM2LONG(length);\n    if (len < 0) {\n\trb_raise(rb_eArgError, \"negative length %ld given\", len);\n    }\n\n    if (NIL_P(str)) {\n\tstr = rb_tainted_str_new(0, len);\n    }\n    else {\n\tStringValue(str);\n\trb_str_modify(str);\n\trb_str_resize(str,len);\n    }\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    if (feof(fptr->f)) return Qnil;\n    if (len == 0) return str;\n\n    rb_str_locktmp(str);\n    READ_CHECK(fptr->f);\n    if (RSTRING(str)->len != len) {\n\trb_raise(rb_eRuntimeError, \"buffer string modified\");\n    }\n    n = io_fread(RSTRING(str)->ptr, len, fptr);\n    rb_str_unlocktmp(str);\n    if (n == 0) {\n\tif (!fptr->f) return Qnil;\n\tif (feof(fptr->f)) {\n\t    rb_str_resize(str, 0);\n\t    return Qnil;\n\t}\n\tif (len > 0) rb_sys_fail(fptr->path);\n    }\n    rb_str_resize(str, n);\n    RSTRING(str)->len = n;\n    RSTRING(str)->ptr[n] = '\\0';\n    OBJ_TAINT(str);\n\n    return str;\n}\n\nstatic int\nappendline(fptr, delim, strp)\n    rb_io_t *fptr;\n    int delim;\n    VALUE *strp;\n{\n    FILE *f = fptr->f;\n    VALUE str = *strp;\n    int c = EOF;\n#ifndef READ_DATA_PENDING_PTR\n    char buf[8192];\n    char *bp = buf, *bpe = buf + sizeof buf - 3;\n    int update = Qfalse;\n#endif\n\n    do {\n#ifdef READ_DATA_PENDING_PTR\n\tlong pending = READ_DATA_PENDING_COUNT(f);\n\tif (pending > 0) {\n\t    const char *p = READ_DATA_PENDING_PTR(f);\n\t    const char *e = memchr(p, delim, pending);\n\t    long last = 0, len = (c != EOF);\n\t    if (e) pending = e - p + 1;\n\t    len += pending;\n\t    if (!NIL_P(str)) {\n\t\tlast = RSTRING(str)->len;\n\t\trb_str_resize(str, last + len);\n\t    }\n\t    else {\n\t\t*strp = str = rb_str_buf_new(len);\n\t\tRSTRING(str)->len = len;\n\t\tRSTRING(str)->ptr[len] = '\\0';\n\t    }\n\t    if (c != EOF) {\n\t\tRSTRING(str)->ptr[last++] = c;\n\t    }\n\t    fread(RSTRING(str)->ptr + last, 1, pending, f); /* must not fail */\n\t    if (e) return delim;\n\t}\n\telse if (c != EOF) {\n\t    if (!NIL_P(str)) {\n\t\tchar ch = c;\n\t\trb_str_buf_cat(str, &ch, 1);\n\t    }\n\t    else {\n\t\t*strp = str = rb_str_buf_new(1);\n\t\tRSTRING(str)->ptr[RSTRING(str)->len++] = c;\n\t    }\n\t}\n\trb_thread_wait_fd(fileno(f));\n\trb_io_check_closed(fptr);\n#else\n\tREAD_CHECK(f);\n#endif\n\tclearerr(f);\n\tTRAP_BEG;\n\tc = getc(f);\n\tTRAP_END;\n\tif (c == EOF) {\n\t    if (ferror(f)) {\n\t\tclearerr(f);\n\t\tif (!rb_io_wait_readable(fileno(f)))\n\t\t    rb_sys_fail(fptr->path);\n\t\tcontinue;\n\t    }\n#ifdef READ_DATA_PENDING_PTR\n\t    return c;\n#endif\n\t}\n#ifndef READ_DATA_PENDING_PTR\n\tif (c == EOF || (*bp++ = c) == delim || bp == bpe) {\n\t    int cnt = bp - buf;\n\n\t    if (cnt > 0) {\n\t\tif (!NIL_P(str))\n\t\t    rb_str_cat(str, buf, cnt);\n\t\telse\n\t\t    *strp = str = rb_str_new(buf, cnt);\n\t    }\n\t    if (c == EOF) {\n\t\tif (update)\n\t\t    return (int)RSTRING(str)->ptr[RSTRING(str)->len-1];\n\t\treturn c;\n\t    }\n\t    bp = buf;\n\t}\n\tupdate = Qtrue;\n#endif\n    } while (c != delim);\n\n#ifdef READ_DATA_PENDING_PTR\n    {\n\tchar ch = c;\n\tif (!NIL_P(str)) {\n\t    rb_str_cat(str, &ch, 1);\n\t}\n\telse {\n\t    *strp = str = rb_str_new(&ch, 1);\n\t}\n    }\n#endif\n\n    return c;\n}\n\nstatic inline int\nswallow(fptr, term)\n    rb_io_t *fptr;\n    int term;\n{\n    FILE *f = fptr->f;\n    int c;\n\n    do {\n#ifdef READ_DATA_PENDING_PTR\n\tlong cnt;\n\twhile ((cnt = READ_DATA_PENDING_COUNT(f)) > 0) {\n\t    char buf[1024];\n\t    const char *p = READ_DATA_PENDING_PTR(f);\n\t    int i;\n\t    if (cnt > sizeof buf) cnt = sizeof buf;\n\t    if (*p != term) return Qtrue;\n\t    i = cnt;\n\t    while (--i && *++p == term);\n\t    if (!fread(buf, 1, cnt - i, f)) /* must not fail */\n\t\trb_sys_fail(fptr->path);\n\t}\n\trb_thread_wait_fd(fileno(f));\n\trb_io_check_closed(fptr);\n#else\n\tREAD_CHECK(f);\n#endif\n\tclearerr(f);\n\tTRAP_BEG;\n\tc = getc(f);\n\tTRAP_END;\n\tif (c != term) {\n\t    ungetc(c, f);\n\t    return Qtrue;\n\t}\n    } while (c != EOF);\n    return Qfalse;\n}\n\nstatic VALUE\nrb_io_getline_fast(fptr, delim)\n    rb_io_t *fptr;\n    unsigned char delim;\n{\n    VALUE str = Qnil;\n    int c;\n\n    while ((c = appendline(fptr, delim, &str)) != EOF && c != delim);\n\n    if (!NIL_P(str)) {\n\tfptr->lineno++;\n\tlineno = INT2FIX(fptr->lineno);\n\tOBJ_TAINT(str);\n    }\n\n    return str;\n}\n\nstatic int\nrscheck(rsptr, rslen, rs)\n    const char *rsptr;\n    long rslen;\n    VALUE rs;\n{\n    if (RSTRING(rs)->ptr != rsptr && RSTRING(rs)->len != rslen)\n\trb_raise(rb_eRuntimeError, \"rs modified\");\n    return 1;\n}\n\nstatic VALUE rb_io_getline(VALUE rs, VALUE io);\n\nstatic VALUE\nrb_io_getline(rs, io)\n    VALUE rs, io;\n{\n    VALUE str = Qnil;\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    if (NIL_P(rs)) {\n\tstr = read_all(fptr, 0, Qnil);\n\tif (RSTRING(str)->len == 0) return Qnil;\n    }\n    else if (rs == rb_default_rs) {\n\treturn rb_io_getline_fast(fptr, '\\n');\n    }\n    else {\n\tint c, newline;\n\tconst char *rsptr;\n\tlong rslen;\n\tint rspara = 0;\n\n\trslen = RSTRING(rs)->len;\n\tif (rslen == 0) {\n\t    rsptr = \"\\n\\n\";\n\t    rslen = 2;\n\t    rspara = 1;\n\t    swallow(fptr, '\\n');\n\t}\n\telse if (rslen == 1) {\n\t    return rb_io_getline_fast(fptr, (unsigned char)RSTRING(rs)->ptr[0]);\n\t}\n\telse {\n\t    rsptr = RSTRING(rs)->ptr;\n\t}\n\tnewline = rsptr[rslen - 1];\n\n\twhile ((c = appendline(fptr, newline, &str)) != EOF &&\n\t       (c != newline || RSTRING(str)->len < rslen ||\n\t\t((rspara || rscheck(rsptr,rslen,rs)) && 0) ||\n\t\tmemcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen,rsptr,rslen)));\n\n\tif (rspara) {\n\t    if (c != EOF) {\n\t\tswallow(fptr, '\\n');\n\t    }\n\t}\n    }\n\n    if (!NIL_P(str)) {\n\tfptr->lineno++;\n\tlineno = INT2FIX(fptr->lineno);\n\tOBJ_TAINT(str);\n    }\n\n    return str;\n}\n\nVALUE\nrb_io_gets(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    return rb_io_getline_fast(fptr, '\\n');\n}\n\n/*\n *  call-seq:\n *     ios.gets(sep_string=$/)   => string or nil\n *  \n *  Reads the next ``line'' from the I/O stream; lines are separated by\n *  <i>sep_string</i>. A separator of <code>nil</code> reads the entire\n *  contents, and a zero-length separator reads the input a paragraph at\n *  a time (two successive newlines in the input separate paragraphs).\n *  The stream must be opened for reading or an <code>IOError</code>\n *  will be raised. The line read in will be returned and also assigned\n *  to <code>$_</code>. Returns <code>nil</code> if called at end of\n *  file.\n *     \n *     File.new(\"testfile\").gets   #=> \"This is line one\\n\"\n *     $_                          #=> \"This is line one\\n\"\n */\n\nstatic VALUE\nrb_io_gets_m(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE rs, str;\n\n    if (argc == 0) {\n\trs = rb_rs;\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &rs);\n\tif (!NIL_P(rs)) StringValue(rs);\n    }\n    str = rb_io_getline(rs, io);\n    rb_lastline_set(str);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     ios.lineno    => integer\n *  \n *  Returns the current line number in <em>ios</em>. The stream must be\n *  opened for reading. <code>lineno</code> counts the number of times\n *  <code>gets</code> is called, rather than the number of newlines\n *  encountered. The two values will differ if <code>gets</code> is\n *  called with a separator other than newline. See also the\n *  <code>$.</code> variable.\n *     \n *     f = File.new(\"testfile\")\n *     f.lineno   #=> 0\n *     f.gets     #=> \"This is line one\\n\"\n *     f.lineno   #=> 1\n *     f.gets     #=> \"This is line two\\n\"\n *     f.lineno   #=> 2\n */\n\nstatic VALUE\nrb_io_lineno(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    return INT2NUM(fptr->lineno);\n}\n\n/*\n *  call-seq:\n *     ios.lineno = integer    => integer\n *  \n *  Manually sets the current line number to the given value.\n *  <code>$.</code> is updated only on the next read.\n *     \n *     f = File.new(\"testfile\")\n *     f.gets                     #=> \"This is line one\\n\"\n *     $.                         #=> 1\n *     f.lineno = 1000\n *     f.lineno                   #=> 1000\n *     $. # lineno of last read   #=> 1\n *     f.gets                     #=> \"This is line two\\n\"\n *     $. # lineno of last read   #=> 1001\n */\n\nstatic VALUE\nrb_io_set_lineno(io, lineno)\n    VALUE io, lineno;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    fptr->lineno = NUM2INT(lineno);\n    return lineno;\n}\n\nstatic void\nlineno_setter(val, id, var)\n    VALUE val;\n    ID id;\n    VALUE *var;\n{\n    gets_lineno = NUM2INT(val);\n    *var = INT2FIX(gets_lineno);\n}\n\nstatic VALUE\nargf_set_lineno(argf, val)\n    VALUE argf, val;\n{\n    gets_lineno = NUM2INT(val);\n    lineno = INT2FIX(gets_lineno);\n    return Qnil;\n}\n\nstatic VALUE\nargf_lineno()\n{\n    return lineno;\n}\n\n/*\n *  call-seq:\n *     ios.readline(sep_string=$/)   => string\n *  \n *  Reads a line as with <code>IO#gets</code>, but raises an\n *  <code>EOFError</code> on end of file.\n */\n\nstatic VALUE\nrb_io_readline(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE line = rb_io_gets_m(argc, argv, io);\n\n    if (NIL_P(line)) {\n\trb_eof_error();\n    }\n    return line;\n}\n\n/*\n *  call-seq:\n *     ios.readlines(sep_string=$/)  =>   array\n *  \n *  Reads all of the lines in <em>ios</em>, and returns them in\n *  <i>anArray</i>. Lines are separated by the optional\n *  <i>sep_string</i>. If <i>sep_string</i> is <code>nil</code>, the\n *  rest of the stream is returned as a single record.\n *  The stream must be opened for reading or an\n *  <code>IOError</code> will be raised.\n *     \n *     f = File.new(\"testfile\")\n *     f.readlines[0]   #=> \"This is line one\\n\"\n */\n\nstatic VALUE\nrb_io_readlines(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE line, ary;\n    VALUE rs;\n\n    if (argc == 0) {\n\trs = rb_rs;\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &rs);\n\tif (!NIL_P(rs)) StringValue(rs);\n    }\n    ary = rb_ary_new();\n    while (!NIL_P(line = rb_io_getline(rs, io))) {\n\trb_ary_push(ary, line);\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     ios.each(sep_string=$/)      {|line| block }  => ios\n *     ios.each_line(sep_string=$/) {|line| block }  => ios\n *  \n *  Executes the block for every line in <em>ios</em>, where lines are\n *  separated by <i>sep_string</i>. <em>ios</em> must be opened for\n *  reading or an <code>IOError</code> will be raised.\n *     \n *     f = File.new(\"testfile\")\n *     f.each {|line| puts \"#{f.lineno}: #{line}\" }\n *     \n *  <em>produces:</em>\n *     \n *     1: This is line one\n *     2: This is line two\n *     3: This is line three\n *     4: And so on...\n */\n\nstatic VALUE\nrb_io_each_line(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE str;\n    VALUE rs;\n\n    RETURN_ENUMERATOR(io, argc, argv);\n    if (argc == 0) {\n\trs = rb_rs;\n    }\n    else {\n\trb_scan_args(argc, argv, \"1\", &rs);\n\tif (!NIL_P(rs)) StringValue(rs);\n    }\n    while (!NIL_P(str = rb_io_getline(rs, io))) {\n\trb_yield(str);\n    }\n    return io;\n}\n\n/*\n *  call-seq:\n *     ios.each_byte {|byte| block }  => ios\n *  \n *  Calls the given block once for each byte (0..255) in <em>ios</em>,\n *  passing the byte as an argument. The stream must be opened for\n *  reading or an <code>IOError</code> will be raised.\n *     \n *     f = File.new(\"testfile\")\n *     checksum = 0\n *     f.each_byte {|x| checksum ^= x }   #=> #<File:testfile>\n *     checksum                           #=> 12\n */\n\nstatic VALUE\nrb_io_each_byte(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    FILE *f;\n    int c;\n\n    RETURN_ENUMERATOR(io, 0, 0);\n    GetOpenFile(io, fptr);\n\n    for (;;) {\n\trb_io_check_readable(fptr);\n\tf = fptr->f;\n\tREAD_CHECK(f);\n\tclearerr(f);\n\tTRAP_BEG;\n\tc = getc(f);\n\tTRAP_END;\n\tif (c == EOF) {\n\t    if (ferror(f)) {\n\t\tclearerr(f);\n\t\tif (!rb_io_wait_readable(fileno(f)))\n\t\t    rb_sys_fail(fptr->path);\n\t\tcontinue;\n\t    }\n\t    break;\n\t}\n\trb_yield(INT2FIX(c & 0xff));\n    }\n    if (ferror(f)) rb_sys_fail(fptr->path);\n    return io;\n}\n\nVALUE rb_io_getc _((VALUE));\n\n/*\n *  call-seq:\n *     ios.each_char {|c| block }  => ios\n *\n *  Calls the given block once for each character in <em>ios</em>,\n *  passing the character as an argument. The stream must be opened for\n *  reading or an <code>IOError</code> will be raised.  Multibyte\n *  characters are dealt with according to $KCODE.\n *\n *     f = File.new(\"testfile\")\n *     f.each_char {|c| print c, ' ' }   #=> #<File:testfile>\n */\n\nstatic VALUE\nrb_io_each_char(io)\n    VALUE io;\n{\n    VALUE ch;\n\n    RETURN_ENUMERATOR(io, 0, 0);\n\n    while (!NIL_P(ch = rb_io_getc(io))) {\n\tunsigned char c;\n\tint n;\n\tVALUE str;\n\n\tc= FIX2INT(ch);\n\tn = mbclen(c);\n\tstr = rb_tainted_str_new((const char *)&c, 1);\n\n\twhile (--n > 0) {\n\t    if (NIL_P(ch = rb_io_getc(io))) {\n\t\trb_yield(str);\n\t\treturn io;\n\t    }\n\t    c = FIX2INT(ch);\n\t    rb_str_cat(str, (const char *)&c, 1);\n\t}\n\trb_yield(str);\n    }\n    return io;\n}\n\n/*\n *  call-seq:\n *     ios.lines(sep=$/)     => anEnumerator\n *     ios.lines(limit)      => anEnumerator\n *     ios.lines(sep, limit) => anEnumerator\n *\n *  Returns an enumerator that gives each line in <em>ios</em>.\n *  The stream must be opened for reading or an <code>IOError</code>\n *  will be raised.\n *\n *     f = File.new(\"testfile\")\n *     f.lines.to_a  #=> [\"foo\\n\", \"bar\\n\"]\n *     f.rewind\n *     f.lines.sort  #=> [\"bar\\n\", \"foo\\n\"]\n */\n\nstatic VALUE\nrb_io_lines(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    return rb_enumeratorize(io, ID2SYM(rb_intern(\"each_line\")), argc, argv);\n}\n\n/*\n *  call-seq:\n *     ios.bytes   => anEnumerator\n *\n *  Returns an enumerator that gives each byte (0..255) in <em>ios</em>.\n *  The stream must be opened for reading or an <code>IOError</code>\n *  will be raised.\n *     \n *     f = File.new(\"testfile\")\n *     f.bytes.to_a  #=> [104, 101, 108, 108, 111]\n *     f.rewind\n *     f.bytes.sort  #=> [101, 104, 108, 108, 111]\n */\n\nstatic VALUE\nrb_io_bytes(io)\n    VALUE io;\n{\n    return rb_enumeratorize(io, ID2SYM(rb_intern(\"each_byte\")), 0, 0);\n}\n\n/*\n *  call-seq:\n *     ios.getc   => fixnum or nil\n *  \n *  Gets the next 8-bit byte (0..255) from <em>ios</em>. Returns\n *  <code>nil</code> if called at end of file.\n *     \n *     f = File.new(\"testfile\")\n *     f.getc   #=> 84\n *     f.getc   #=> 104\n */\n\nVALUE\nrb_io_getc(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    FILE *f;\n    int c;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n    f = fptr->f;\n\n  retry:\n    READ_CHECK(f);\n    clearerr(f);\n    TRAP_BEG;\n    c = getc(f);\n    TRAP_END;\n\n    if (c == EOF) {\n\tif (ferror(f)) {\n\t    clearerr(f);\n\t    if (!rb_io_wait_readable(fileno(f)))\n\t\trb_sys_fail(fptr->path);\n\t    goto retry;\n\t}\n\treturn Qnil;\n    }\n    return INT2FIX(c & 0xff);\n}\n\nint\nrb_getc(f)\n    FILE *f;\n{\n    int c;\n\n    if (!READ_DATA_PENDING(f)) {\n\trb_thread_wait_fd(fileno(f));\n    }\n    clearerr(f);\n    TRAP_BEG;\n    c = getc(f);\n    TRAP_END;\n\n    return c;\n}\n\n/*\n *  call-seq:\n *     ios.readchar   => fixnum\n *  \n *  Reads a character as with <code>IO#getc</code>, but raises an\n *  <code>EOFError</code> on end of file.\n */\n\nstatic VALUE\nrb_io_readchar(io)\n    VALUE io;\n{\n    VALUE c = rb_io_getc(io);\n\n    if (NIL_P(c)) {\n\trb_eof_error();\n    }\n    return c;\n}\n\n/*\n *  call-seq:\n *     ios.ungetc(integer)   => nil\n *  \n *  Pushes back one character (passed as a parameter) onto <em>ios</em>,\n *  such that a subsequent buffered read will return it. Only one character\n *  may be pushed back before a subsequent read operation (that is,\n *  you will be able to read only the last of several characters that have been pushed\n *  back). Has no effect with unbuffered reads (such as <code>IO#sysread</code>).\n *     \n *     f = File.new(\"testfile\")   #=> #<File:testfile>\n *     c = f.getc                 #=> 84\n *     f.ungetc(c)                #=> nil\n *     f.getc                     #=> 84\n */\n\nVALUE\nrb_io_ungetc(io, c)\n    VALUE io, c;\n{\n    rb_io_t *fptr;\n    int cc = NUM2INT(c);\n\n    GetOpenFile(io, fptr);\n    if (!(fptr->mode & FMODE_RBUF))\n\trb_raise(rb_eIOError, \"unread stream\");\n    rb_io_check_readable(fptr);\n\n    if (ungetc(cc, fptr->f) == EOF && cc != EOF) {\n\trb_raise(rb_eIOError, \"ungetc failed\");\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.isatty   => true or false\n *     ios.tty?     => true or false\n *  \n *  Returns <code>true</code> if <em>ios</em> is associated with a\n *  terminal device (tty), <code>false</code> otherwise.\n *     \n *     File.new(\"testfile\").isatty   #=> false\n *     File.new(\"/dev/tty\").isatty   #=> true\n */\n\nstatic VALUE\nrb_io_isatty(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    if (isatty(fileno(fptr->f)) == 0)\n\treturn Qfalse;\n    return Qtrue;\n}\n\nstatic void\nfptr_finalize(fptr, noraise)\n    rb_io_t *fptr;\n    int noraise;\n{\n    int n1 = 0, n2 = 0, f1, f2 = -1;\n\n    errno = 0;\n    if (fptr->f2) {\n\tf2 = fileno(fptr->f2);\n\twhile (n2 = 0, fflush(fptr->f2) < 0) {\n\t    n2 = errno;\n\t    if (!rb_io_wait_writable(f2)) {\n\t\tbreak;\n\t    }\n\t    if (!fptr->f2) break;\n\t}\n\tif (fclose(fptr->f2) < 0 && n2 == 0) {\n\t    n2 = errno;\n\t}\n\tfptr->f2 = 0;\n    }\n    if (fptr->f) {\n\tf1 = fileno(fptr->f);\n\tif ((f2 == -1) && (fptr->mode & FMODE_WBUF)) {\n\t    while (n1 = 0, fflush(fptr->f) < 0) {\n\t\tn1 = errno;\n\t\tif (!rb_io_wait_writable(f1)) break;\n\t\tif (!fptr->f) break;\n\t    }\n\t}\n\tif (fclose(fptr->f) < 0 && n1 == 0) {\n\t    n1 = errno;\n\t}\n\tfptr->f = 0;\n\tif (n1 == EBADF && f1 == f2) {\n\t    n1 = 0;\n\t}\n    }\n    if (!noraise && (n1 || n2)) {\n\terrno = (n1 ? n1 : n2);\n\trb_sys_fail(fptr->path);\n    }\n}\n\nstatic void\nrb_io_fptr_cleanup(fptr, noraise)\n    rb_io_t *fptr;\n    int noraise;\n{\n    if (fptr->finalize) {\n\t(*fptr->finalize)(fptr, noraise);\n    }\n    else {\n\tfptr_finalize(fptr, noraise);\n    }\n}\n\nvoid\nrb_io_fptr_finalize(fptr)\n    rb_io_t *fptr;\n{\n    if (!fptr) return;\n    if (fptr->path) {\n\tfree(fptr->path);\n    }\n    if ((fptr->f && fileno(fptr->f) > 2) || fptr->f2) {\n\trb_io_fptr_cleanup(fptr, Qtrue);\n    }\n    xfree(fptr);\n}\n\nVALUE\nrb_io_close(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    int fd, fd2;\n\n    fptr = RFILE(io)->fptr;\n    if (!fptr) return Qnil;\n    if (fptr->f2) {\n\tfd2 = fileno(fptr->f2);\n    }\n    else {\n\tif (!fptr->f) return Qnil;\n\tfd2 = -1;\n    }\n\n    fd = fileno(fptr->f);\n    rb_io_fptr_cleanup(fptr, Qfalse);\n    rb_thread_fd_close(fd);\n    if (fd2 >= 0) rb_thread_fd_close(fd2);\n\n    if (fptr->pid) {\n\trb_syswait(fptr->pid);\n\tfptr->pid = 0;\n    }\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.close   => nil\n *  \n *  Closes <em>ios</em> and flushes any pending writes to the operating\n *  system. The stream is unavailable for any further data operations;\n *  an <code>IOError</code> is raised if such an attempt is made. I/O\n *  streams are automatically closed when they are claimed by the\n *  garbage collector.\n *\n *  If <em>ios</em> is opened by <code>IO.popen</code>,\n *  <code>close</code> sets <code>$?</code>.\n */\n\nstatic VALUE\nrb_io_close_m(io)\n    VALUE io;\n{\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close\");\n    }\n    rb_io_check_closed(RFILE(io)->fptr);\n    rb_io_close(io);\n    return Qnil;\n}\n\nstatic VALUE\nio_call_close(io)\n    VALUE io;\n{\n    return rb_funcall(io, rb_intern(\"close\"), 0, 0);\n}\n\nstatic VALUE\nio_close(io)\n    VALUE io;\n{\n    return rb_rescue(io_call_close, io, 0, 0);\n}\n\n/*\n *  call-seq:\n *     ios.closed?    => true or false\n *  \n *  Returns <code>true</code> if <em>ios</em> is completely closed (for\n *  duplex streams, both reader and writer), <code>false</code>\n *  otherwise.\n *     \n *     f = File.new(\"testfile\")\n *     f.close         #=> nil\n *     f.closed?       #=> true\n *     f = IO.popen(\"/bin/sh\",\"r+\")\n *     f.close_write   #=> nil\n *     f.closed?       #=> false\n *     f.close_read    #=> nil\n *     f.closed?       #=> true\n */\n\nstatic VALUE\nrb_io_closed(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    fptr = RFILE(io)->fptr;\n    rb_io_check_initialized(fptr);\n    return (fptr->f || fptr->f2)?Qfalse:Qtrue;\n}\n\n/*\n *  call-seq:\n *     ios.close_read    => nil\n *  \n *  Closes the read end of a duplex I/O stream (i.e., one that contains\n *  both a read and a write stream, such as a pipe). Will raise an\n *  <code>IOError</code> if the stream is not duplexed.\n *     \n *     f = IO.popen(\"/bin/sh\",\"r+\")\n *     f.close_read\n *     f.readlines\n *     \n *  <em>produces:</em>\n *     \n *     prog.rb:3:in `readlines': not opened for reading (IOError)\n *     \tfrom prog.rb:3\n */\n\nstatic VALUE\nrb_io_close_read(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    int n;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close\");\n    }\n    GetOpenFile(io, fptr);\n    if (fptr->f2 == 0 && (fptr->mode & FMODE_WRITABLE)) {\n\trb_raise(rb_eIOError, \"closing non-duplex IO for reading\");\n    }\n    if (fptr->f2 == 0) {\n\treturn rb_io_close(io);\n    }\n    n = fclose(fptr->f);\n    fptr->mode &= ~FMODE_READABLE;\n    fptr->f = fptr->f2;\n    fptr->f2 = 0;\n    if (n != 0) rb_sys_fail(fptr->path);\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.close_write   => nil\n *  \n *  Closes the write end of a duplex I/O stream (i.e., one that contains\n *  both a read and a write stream, such as a pipe). Will raise an\n *  <code>IOError</code> if the stream is not duplexed.\n *     \n *     f = IO.popen(\"/bin/sh\",\"r+\")\n *     f.close_write\n *     f.print \"nowhere\"\n *     \n *  <em>produces:</em>\n *     \n *     prog.rb:3:in `write': not opened for writing (IOError)\n *     \tfrom prog.rb:3:in `print'\n *     \tfrom prog.rb:3\n */\n\nstatic VALUE\nrb_io_close_write(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n    int n;\n\n    if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't close\");\n    }\n    GetOpenFile(io, fptr);\n    if (fptr->f2 == 0 && (fptr->mode & FMODE_READABLE)) {\n\trb_raise(rb_eIOError, \"closing non-duplex IO for writing\");\n    }\n    if (fptr->f2 == 0) {\n\treturn rb_io_close(io);\n    }\n    n = fclose(fptr->f2);\n    fptr->f2 = 0;\n    fptr->mode &= ~FMODE_WRITABLE;\n    if (n != 0) rb_sys_fail(fptr->path);\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.sysseek(offset, whence=SEEK_SET)   => integer\n *  \n *  Seeks to a given <i>offset</i> in the stream according to the value\n *  of <i>whence</i> (see <code>IO#seek</code> for values of\n *  <i>whence</i>). Returns the new offset into the file.\n *     \n *     f = File.new(\"testfile\")\n *     f.sysseek(-13, IO::SEEK_END)   #=> 53\n *     f.sysread(10)                  #=> \"And so on.\"\n */\n\nstatic VALUE\nrb_io_sysseek(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE offset, ptrname;\n    int whence = SEEK_SET;\n    rb_io_t *fptr;\n    off_t pos;\n\n    if (rb_scan_args(argc, argv, \"11\", &offset, &ptrname) == 2) {\n\twhence = NUM2INT(ptrname);\n    }\n    pos = NUM2OFFT(offset);\n    GetOpenFile(io, fptr);\n    if ((fptr->mode & FMODE_READABLE) && READ_DATA_BUFFERED(fptr->f)) {\n\trb_raise(rb_eIOError, \"sysseek for buffered IO\");\n    }\n    if ((fptr->mode & FMODE_WRITABLE) && (fptr->mode & FMODE_WBUF)) {\n\trb_warn(\"sysseek for buffered IO\");\n    }\n    pos = lseek(fileno(fptr->f), pos, whence);\n    if (pos == -1) rb_sys_fail(fptr->path);\n    clearerr(fptr->f);\n\n    return OFFT2NUM(pos);\n}\n\n/*\n *  call-seq:\n *     ios.syswrite(string)   => integer\n *  \n *  Writes the given string to <em>ios</em> using a low-level write.\n *  Returns the number of bytes written. Do not mix with other methods\n *  that write to <em>ios</em> or you may get unpredictable results.\n *  Raises <code>SystemCallError</code> on error.\n *     \n *     f = File.new(\"out\", \"w\")\n *     f.syswrite(\"ABCDEF\")   #=> 6\n */\n\nstatic VALUE\nrb_io_syswrite(io, str)\n    VALUE io, str;\n{\n    rb_io_t *fptr;\n    FILE *f;\n    long n;\n\n    rb_secure(4);\n    if (TYPE(str) != T_STRING)\n\tstr = rb_obj_as_string(str);\n\n    GetOpenFile(io, fptr);\n    rb_io_check_writable(fptr);\n    f = GetWriteFile(fptr);\n\n    if (fptr->mode & FMODE_WBUF) {\n\trb_warn(\"syswrite for buffered IO\");\n    }\n    if (!rb_thread_fd_writable(fileno(f))) {\n        rb_io_check_closed(fptr);\n    }\n    TRAP_BEG;\n    n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len);\n    TRAP_END;\n\n    if (n == -1) rb_sys_fail(fptr->path);\n\n    return LONG2FIX(n);\n}\n\n/*\n *  call-seq:\n *     ios.sysread(integer )    => string\n *  \n *  Reads <i>integer</i> bytes from <em>ios</em> using a low-level\n *  read and returns them as a string. Do not mix with other methods\n *  that read from <em>ios</em> or you may get unpredictable results.\n *  Raises <code>SystemCallError</code> on error and\n *  <code>EOFError</code> at end of file.\n *     \n *     f = File.new(\"testfile\")\n *     f.sysread(16)   #=> \"This is line one\"\n */\n\nstatic VALUE\nrb_io_sysread(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE len, str;\n    rb_io_t *fptr;\n    long n, ilen;\n\n    rb_scan_args(argc, argv, \"11\", &len, &str);\n    ilen = NUM2LONG(len);\n\n    if (NIL_P(str)) {\n\tstr = rb_str_new(0, ilen);\n    }\n    else {\n\tStringValue(str);\n\trb_str_modify(str);\n\trb_str_resize(str, ilen);\n    }\n    if (ilen == 0) return str;\n\n    GetOpenFile(io, fptr);\n    rb_io_check_readable(fptr);\n\n    if (READ_DATA_BUFFERED(fptr->f)) {\n\trb_raise(rb_eIOError, \"sysread for buffered IO\");\n    }\n    rb_str_locktmp(str);\n\n    n = fileno(fptr->f);\n    rb_thread_wait_fd(fileno(fptr->f));\n    rb_io_check_closed(fptr);\n    if (RSTRING(str)->len != ilen) {\n\trb_raise(rb_eRuntimeError, \"buffer string modified\");\n    }\n    TRAP_BEG;\n    n = read(fileno(fptr->f), RSTRING(str)->ptr, ilen);\n    TRAP_END;\n\n    rb_str_unlocktmp(str);\n    if (n == -1) {\n\trb_sys_fail(fptr->path);\n    }\n    rb_str_resize(str, n);\n    if (n == 0 && ilen > 0) {\n\trb_eof_error();\n    }\n    RSTRING(str)->len = n;\n    RSTRING(str)->ptr[n] = '\\0';\n    OBJ_TAINT(str);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     ios.binmode    => ios\n *  \n *  Puts <em>ios</em> into binary mode. This is useful only in\n *  MS-DOS/Windows environments. Once a stream is in binary mode, it\n *  cannot be reset to nonbinary mode.\n */\n\nVALUE\nrb_io_binmode(io)\n    VALUE io;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n#if (defined(O_BINARY) && O_BINARY) || (defined(_IOBIN) && _IOBIN)\n#if (defined(_IOBIN) && _IOBIN)\t/* __human68k__ */\n    if (fptr->f)\n\tfmode(fptr->f, _IOBIN);\n    if (fptr->f2)\n\tfmode(fptr->f2, _IOBIN);\n#else\n    if (fptr->f && setmode(fileno(fptr->f), O_BINARY) == -1)\n\trb_sys_fail(fptr->path);\n    if (fptr->f2 && setmode(fileno(fptr->f2), O_BINARY) == -1)\n\trb_sys_fail(fptr->path);\n#endif\n\n    fptr->mode |= FMODE_BINMODE;\n#endif\n    return io;\n}\n\nconst char*\nrb_io_flags_mode(flags)\n    int flags;\n{\n#ifdef O_BINARY\n# define MODE_BINMODE(a,b) ((flags & FMODE_BINMODE) ? (b) : (a))\n#else\n# define MODE_BINMODE(a,b) (a)\n#endif\n    if (flags & FMODE_APPEND) {\n\tif ((flags & FMODE_READWRITE) == FMODE_READWRITE) {\n\t    return MODE_BINMODE(\"a+\", \"ab+\");\n\t}\n\treturn MODE_BINMODE(\"a\", \"ab\");\n    }\n    switch (flags & FMODE_READWRITE) {\n      case FMODE_READABLE:\n\treturn MODE_BINMODE(\"r\", \"rb\");\n      case FMODE_WRITABLE:\n\treturn MODE_BINMODE(\"w\", \"wb\");\n      case FMODE_READWRITE:\n\tif (flags & FMODE_CREATE) {\n\t    return MODE_BINMODE(\"w+\", \"wb+\");\n\t}\n\treturn MODE_BINMODE(\"r+\", \"rb+\");\n    }\n    rb_raise(rb_eArgError, \"illegal access modenum %o\", flags);\n    return NULL;\t\t/* not reached */\n}\n\nint\nrb_io_mode_flags(mode)\n    const char *mode;\n{\n    int flags = 0;\n    const char *m = mode;\n\n    switch (*m++) {\n      case 'r':\n\tflags |= FMODE_READABLE;\n\tbreak;\n      case 'w':\n\tflags |= FMODE_WRITABLE | FMODE_CREATE;\n\tbreak;\n      case 'a':\n\tflags |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE;\n\tbreak;\n      default:\n      error:\n\trb_raise(rb_eArgError, \"illegal access mode %s\", mode);\n    }\n\n    while (*m) {\n        switch (*m++) {\n        case 'b':\n            flags |= FMODE_BINMODE;\n            break;\n        case '+':\n            flags |= FMODE_READWRITE;\n            break;\n        case ':':\n            /* forward compatibility */\n            rb_warning(\"encoding options not supported in 1.8: %s\", mode);\n            goto end;\n        default:\n            goto error;\n        }\n    }\n\n end:\n    return flags;\n}\n\nint\nrb_io_modenum_flags(mode)\n    int mode;\n{\n    int flags = 0;\n\n    switch (mode & (O_RDONLY|O_WRONLY|O_RDWR)) {\n      case O_RDONLY:\n\tflags = FMODE_READABLE;\n\tbreak;\n      case O_WRONLY:\n\tflags = FMODE_WRITABLE;\n\tbreak;\n      case O_RDWR:\n\tflags = FMODE_READWRITE;\n\tbreak;\n    }\n\n    if (mode & O_APPEND) {\n\tflags |= FMODE_APPEND;\n    }\n    if (mode & O_CREAT) {\n\tflags |= FMODE_CREATE;\n    }\n#ifdef O_BINARY\n    if (mode & O_BINARY) {\n\tflags |= FMODE_BINMODE;\n    }\n#endif\n\n    return flags;\n}\n\nstatic int\nrb_io_mode_modenum(mode)\n    const char *mode;\n{\n    int flags = 0;\n    const char *m = mode;\n\n    switch (*m++) {\n      case 'r':\n\tflags |= O_RDONLY;\n\tbreak;\n      case 'w':\n\tflags |= O_WRONLY | O_CREAT | O_TRUNC;\n\tbreak;\n      case 'a':\n\tflags |= O_WRONLY | O_CREAT | O_APPEND;\n\tbreak;\n      default:\n      error:\n\trb_raise(rb_eArgError, \"illegal access mode %s\", mode);\n    }\n\n    while (*m) {\n        switch (*m++) {\n        case 'b':\n#ifdef O_BINARY\n            flags |= O_BINARY;\n#endif\n            break;\n        case '+':\n            flags = (flags & ~O_ACCMODE) | O_RDWR;\n            break;\n        case ':':\n            /* forward compatibility */\n            rb_warning(\"encoding options not supported in 1.8: %s\", mode);\n            goto end;\n        default:\n            goto error;\n        }\n    }\n\n end:\n    return flags;\n}\n\n#define MODENUM_MAX 4\n\nstatic const char*\nrb_io_modenum_mode(flags)\n    int flags;\n{\n#ifdef O_BINARY\n# define MODE_BINARY(a,b) ((flags & O_BINARY) ? (b) : (a))\n#else\n# define MODE_BINARY(a,b) (a)\n#endif\n    if (flags & O_APPEND) {\n\tif ((flags & O_RDWR) == O_RDWR) {\n\t    return MODE_BINARY(\"a+\", \"ab+\");\n\t}\n\treturn MODE_BINARY(\"a\", \"ab\");\n    }\n    switch (flags & (O_RDONLY|O_WRONLY|O_RDWR)) {\n      case O_RDONLY:\n\treturn MODE_BINARY(\"r\", \"rb\");\n      case O_WRONLY:\n\treturn MODE_BINARY(\"w\", \"wb\");\n      case O_RDWR:\n\treturn MODE_BINARY(\"r+\", \"rb+\");\n    }\n    rb_raise(rb_eArgError, \"illegal access modenum %o\", flags);\n    return NULL;\t\t/* not reached */\n}\n\nstatic int\nrb_sysopen(fname, flags, mode)\n    char *fname;\n    int flags;\n    unsigned int mode;\n{\n    int fd;\n\n#ifdef _WIN32\n    errno = EINVAL;\n#endif\n    fd = open(fname, flags, mode);\n    if (fd < 0) {\n\tif (errno == EMFILE || errno == ENFILE) {\n\t    rb_gc();\n#ifdef _WIN32\n\t    errno = EINVAL;\n#endif\n\t    fd = open(fname, flags, mode);\n\t}\n\tif (fd < 0) {\n\t    rb_sys_fail(fname);\n\t}\n    }\n    return fd;\n}\n\nFILE *\nrb_fopen(fname, mode)\n    const char *fname;\n    const char *mode;\n{\n    FILE *file;\n\n    file = fopen(fname, mode);\n    if (!file) {\n\tif (errno == EMFILE || errno == ENFILE) {\n\t    rb_gc();\n\t    file = fopen(fname, mode);\n\t}\n\tif (!file) {\n\t    rb_sys_fail(fname);\n\t}\n    }\n#ifdef USE_SETVBUF\n    if (setvbuf(file, NULL, _IOFBF, 0) != 0)\n\trb_warn(\"setvbuf() can't be honoured for %s\", fname);\n#endif\n#ifdef __human68k__\n    fmode(file, _IOTEXT);\n#endif\n    return file;\n}\n\nFILE *\nrb_fdopen(fd, mode)\n    int fd;\n    const char *mode;\n{\n    FILE *file;\n\n#if defined(sun)\n    errno = 0;\n#endif\n    file = fdopen(fd, mode);\n    if (!file) {\n#if defined(sun)\n\tif (errno == 0 || errno == EMFILE || errno == ENFILE) {\n#else\n\tif (errno == EMFILE || errno == ENFILE) {\n#endif\n\t    rb_gc();\n#if defined(sun)\n\t    errno = 0;\n#endif\n\t    file = fdopen(fd, mode);\n\t}\n\tif (!file) {\n#ifdef _WIN32\n\t    if (errno == 0) errno = EINVAL;\n#endif\n#if defined(sun)\n\t    if (errno == 0) errno = EMFILE;\n#endif\n\t    rb_sys_fail(0);\n\t}\n    }\n\n#ifdef USE_SETVBUF\n    if (setvbuf(file, NULL, _IOFBF, 0) != 0)\n\trb_warn(\"setvbuf() can't be honoured (fd=%d)\", fd);\n#endif\n    return file;\n}\n\nstatic VALUE\nrb_file_open_internal(io, fname, mode)\n    VALUE io;\n    const char *fname, *mode;\n{\n    rb_io_t *fptr;\n\n    MakeOpenFile(io, fptr);\n\n    fptr->mode = rb_io_mode_flags(mode);\n    fptr->path = strdup(fname);\n    fptr->f = rb_fopen(fptr->path, rb_io_flags_mode(fptr->mode));\n\n    return io;\n}\n\nVALUE\nrb_file_open(fname, mode)\n    const char *fname, *mode;\n{\n    return rb_file_open_internal(io_alloc(rb_cFile), fname, mode);\n}\n\nstatic VALUE\nrb_file_sysopen_internal(io, fname, flags, mode)\n    VALUE io;\n    char *fname;\n    int flags, mode;\n{\n    rb_io_t *fptr;\n    int fd;\n    const char *m;\n\n    MakeOpenFile(io, fptr);\n\n    fptr->path = strdup(fname);\n    m = rb_io_modenum_mode(flags);\n    fptr->mode = rb_io_modenum_flags(flags);\n    fd = rb_sysopen(fptr->path, flags, mode);\n    fptr->f = rb_fdopen(fd, m);\n\n    return io;\n}\n\nVALUE\nrb_file_sysopen(fname, flags, mode)\n    const char *fname;\n    int flags, mode;\n{\n    return rb_file_sysopen_internal(io_alloc(rb_cFile), fname, flags, mode);\n}\n\n#if defined (_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__VMS)\nstatic struct pipe_list {\n    rb_io_t *fptr;\n    struct pipe_list *next;\n} *pipe_list;\n\nstatic void\npipe_add_fptr(fptr)\n    rb_io_t *fptr;\n{\n    struct pipe_list *list;\n\n    list = ALLOC(struct pipe_list);\n    list->fptr = fptr;\n    list->next = pipe_list;\n    pipe_list = list;\n}\n\nstatic void\npipe_del_fptr(fptr)\n    rb_io_t *fptr;\n{\n    struct pipe_list *list = pipe_list;\n    struct pipe_list *tmp;\n\n    if (list->fptr == fptr) {\n\tpipe_list = list->next;\n\tfree(list);\n\treturn;\n    }\n\n    while (list->next) {\n\tif (list->next->fptr == fptr) {\n\t    tmp = list->next;\n\t    list->next = list->next->next;\n\t    free(tmp);\n\t    return;\n\t}\n\tlist = list->next;\n    }\n}\n\nstatic void\npipe_atexit _((void))\n{\n    struct pipe_list *list = pipe_list;\n    struct pipe_list *tmp;\n\n    while (list) {\n\ttmp = list->next;\n\trb_io_fptr_finalize(list->fptr);\n\tlist = tmp;\n    }\n}\n\nstatic void pipe_finalize _((rb_io_t *fptr,int));\n\nstatic void\npipe_finalize(fptr, noraise)\n    rb_io_t *fptr;\n    int noraise;\n{\n#if !defined (__CYGWIN__) && !defined(_WIN32)\n    extern VALUE rb_last_status;\n    int status;\n    if (fptr->f) {\n\tstatus = pclose(fptr->f);\n    }\n    if (fptr->f2) {\n\tstatus = pclose(fptr->f2);\n    }\n    fptr->f = fptr->f2 = 0;\n#if defined DJGPP\n    status <<= 8;\n#endif\n    rb_last_status = INT2FIX(status);\n#else\n    fptr_finalize(fptr, noraise);\n#endif\n    pipe_del_fptr(fptr);\n}\n#endif\n\nvoid\nrb_io_synchronized(fptr)\n    rb_io_t *fptr;\n{\n    fptr->mode |= FMODE_SYNC;\n}\n\nvoid\nrb_io_unbuffered(fptr)\n    rb_io_t *fptr;\n{\n    rb_io_synchronized(fptr);\n}\n\nstatic VALUE pipe_open(VALUE pstr, const char *pname, const char *mode);\n\nstatic VALUE\npipe_open(pstr, pname, mode)\n    VALUE pstr;\n    const char *pname, *mode;\n{\n    int modef = rb_io_mode_flags(mode);\n    rb_io_t *fptr;\n#if defined(DJGPP) || defined(__human68k__) || defined(__VMS)\n    FILE *f;\n#else\n    int pid;\n#ifdef _WIN32\n    FILE *fpr, *fpw;\n#else\n    int pr[2], pw[2];\n#endif\n#endif\n    volatile int doexec;\n\n    if (!pname) pname = StringValueCStr(pstr);\n    doexec = (strcmp(\"-\", pname) != 0);\n\n#if defined(DJGPP) || defined(__human68k__) || defined(__VMS) || defined(_WIN32)\n    if (!doexec) {\n\trb_raise(rb_eNotImpError,\n\t\t \"fork() function is unimplemented on this machine\");\n    }\n#endif\n\n#if defined(DJGPP) || defined(__human68k__) || defined(__VMS)\n    f = popen(pname, mode);\n    \n    if (!f) rb_sys_fail(pname);\n    else {\n\tVALUE port = io_alloc(rb_cIO);\n\n\tMakeOpenFile(port, fptr);\n\tfptr->finalize = pipe_finalize;\n\tfptr->mode = modef;\n\n\tpipe_add_fptr(fptr);\n\tif (modef & FMODE_READABLE) fptr->f  = f;\n\tif (modef & FMODE_WRITABLE) {\n\t    if (fptr->f) fptr->f2 = f;\n\t    else fptr->f = f;\n\t    rb_io_synchronized(fptr);\n\t}\n\treturn (VALUE)port;\n    }\n#else\n#ifdef _WIN32\nretry:\n    pid = pipe_exec(pname, rb_io_mode_modenum(mode), &fpr, &fpw);\n    if (pid == -1) {\t\t/* exec failed */\n\tif (errno == EAGAIN) {\n\t    rb_thread_sleep(1);\n\t    goto retry;\n\t}\n\trb_sys_fail(pname);\n    }\n    else {\n        VALUE port = io_alloc(rb_cIO);\n\n\tMakeOpenFile(port, fptr);\n\tfptr->mode = modef;\n\tfptr->mode |= FMODE_SYNC;\n\tfptr->pid = pid;\n\n\tif (modef & FMODE_READABLE) {\n\t    fptr->f = fpr;\n\t}\n\tif (modef & FMODE_WRITABLE) {\n\t    if (fptr->f) fptr->f2 = fpw;\n\t    else fptr->f = fpw;\n\t}\n\tfptr->finalize = pipe_finalize;\n\tpipe_add_fptr(fptr);\n\treturn (VALUE)port;\n    }\n#else\n    if (((modef & FMODE_READABLE) && pipe(pr) == -1) ||\n\t((modef & FMODE_WRITABLE) && pipe(pw) == -1))\n\trb_sys_fail(pname);\n\n    if (!doexec) {\n\tfflush(stdin);\t\t/* is it really needed? */\n\tfflush(stdout);\n\tfflush(stderr);\n    }\n\n  retry:\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n    rb_thread_stop_timer();\n#endif\n    switch ((pid = fork())) {\n      case 0:\t\t\t/* child */\n\tif (modef & FMODE_READABLE) {\n\t    close(pr[0]);\n\t    if (pr[1] != 1) {\n\t\tdup2(pr[1], 1);\n\t\tclose(pr[1]);\n\t    }\n\t}\n\tif (modef & FMODE_WRITABLE) {\n\t    close(pw[1]);\n\t    if (pw[0] != 0) {\n\t\tdup2(pw[0], 0);\n\t\tclose(pw[0]);\n\t    }\n\t}\n\n\tif (doexec) {\n\t    int fd;\n\n\t    for (fd = 3; fd < NOFILE; fd++)\n\t\tclose(fd);\n\t    rb_proc_exec(pname);\n\t    fprintf(stderr, \"%s:%d: command not found: %s\\n\",\n\t\t    ruby_sourcefile, ruby_sourceline, pname);\n\t    _exit(127);\n\t}\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n\trb_thread_start_timer();\n#endif\n\trb_io_synchronized(RFILE(orig_stdout)->fptr);\n\trb_io_synchronized(RFILE(orig_stderr)->fptr);\n\treturn Qnil;\n\n      case -1:\t\t\t/* fork failed */\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n        rb_thread_start_timer();\n#endif\n\tif (errno == EAGAIN) {\n\t    rb_thread_sleep(1);\n\t    goto retry;\n\t}\n\telse {\n\t    int e = errno;\n\t    if ((modef & FMODE_READABLE)) {\n\t\tclose(pr[0]);\n\t\tclose(pr[1]);\n\t    }\n\t    if ((modef & FMODE_WRITABLE)) {\n\t\tclose(pw[0]);\n\t\tclose(pw[1]);\n\t    }\n\t    errno = e;\n\t    rb_sys_fail(pname);\n\t}\n\tbreak;\n\n      default:\t\t\t/* parent */\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n        rb_thread_start_timer();\n#endif\n\tif (pid < 0) rb_sys_fail(pname);\n\telse {\n\t    VALUE port = io_alloc(rb_cIO);\n\n\t    MakeOpenFile(port, fptr);\n\t    fptr->mode = modef;\n\t    fptr->mode |= FMODE_SYNC;\n\t    fptr->pid = pid;\n\n\t    if (modef & FMODE_READABLE) {\n\t\tclose(pr[1]);\n\t\tfptr->f  = rb_fdopen(pr[0], \"r\");\n\t    }\n\t    if (modef & FMODE_WRITABLE) {\n\t\tFILE *f = rb_fdopen(pw[1], \"w\");\n\n\t\tclose(pw[0]);\n\t\tif (fptr->f) fptr->f2 = f;\n\t\telse fptr->f = f;\n\t    }\n#if defined (__CYGWIN__)\n\t    fptr->finalize = pipe_finalize;\n\t    pipe_add_fptr(fptr);\n#endif\n\t    return port;\n\t}\n    }\n#endif\n#endif\n}\n\n/*\n *  call-seq:\n *     IO.popen(cmd_string, mode=\"r\" )               => io\n *     IO.popen(cmd_string, mode=\"r\" ) {|io| block } => obj\n *  \n *  Runs the specified command string as a subprocess; the subprocess's\n *  standard input and output will be connected to the returned\n *  <code>IO</code> object. If <i>cmd_string</i> starts with a\n *  ``<code>-</code>'', then a new instance of Ruby is started as the\n *  subprocess. The default mode for the new file object is ``r'', but\n *  <i>mode</i> may be set to any of the modes listed in the description\n *  for class IO.\n *     \n *  If a block is given, Ruby will run the command as a child connected\n *  to Ruby with a pipe. Ruby's end of the pipe will be passed as a\n *  parameter to the block.\n *  At the end of block, Ruby close the pipe and sets <code>$?</code>.\n *  In this case <code>IO::popen</code> returns\n *  the value of the block.\n *     \n *  If a block is given with a <i>cmd_string</i> of ``<code>-</code>'',\n *  the block will be run in two separate processes: once in the parent,\n *  and once in a child. The parent process will be passed the pipe\n *  object as a parameter to the block, the child version of the block\n *  will be passed <code>nil</code>, and the child's standard in and\n *  standard out will be connected to the parent through the pipe. Not\n *  available on all platforms.\n *     \n *     f = IO.popen(\"uname\")\n *     p f.readlines\n *     puts \"Parent is #{Process.pid}\"\n *     IO.popen (\"date\") { |f| puts f.gets }\n *     IO.popen(\"-\") {|f| $stderr.puts \"#{Process.pid} is here, f is #{f}\"}\n *     p $?\n *     \n *  <em>produces:</em>\n *     \n *     [\"Linux\\n\"]\n *     Parent is 26166\n *     Wed Apr  9 08:53:52 CDT 2003\n *     26169 is here, f is\n *     26166 is here, f is #<IO:0x401b3d44>\n *     #<Process::Status: pid=26166,exited(0)>\n */\n\nstatic VALUE\nrb_io_s_popen(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    const char *mode;\n    VALUE pname, pmode, port;\n\n    if (rb_scan_args(argc, argv, \"11\", &pname, &pmode) == 1) {\n\tmode = \"r\";\n    }\n    else if (FIXNUM_P(pmode)) {\n\tmode = rb_io_modenum_mode(FIX2INT(pmode));\n    }\n    else {\n\tmode = rb_io_flags_mode(rb_io_mode_flags(StringValueCStr(pmode)));\n    }\n    SafeStringValue(pname);\n    port = pipe_open(pname, 0, mode);\n    if (NIL_P(port)) {\n\t/* child */\n\tif (rb_block_given_p()) {\n\t    rb_yield(Qnil);\n\t    fflush(stdout);\n\t    fflush(stderr);\n\t    _exit(0);\n\t}\n\treturn Qnil;\n    }\n    RBASIC(port)->klass = klass;\n    if (rb_block_given_p()) {\n\treturn rb_ensure(rb_yield, port, io_close, port);\n    }\n    return port;\n}\n\nstatic VALUE\nrb_open_file(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE fname, vmode, perm;\n    const char *path, *mode;\n    int flags;\n    unsigned int fmode;\n\n    rb_scan_args(argc, argv, \"12\", &fname, &vmode, &perm);\n    SafeStringValue(fname);\n\n    path = StringValueCStr(fname);\n    if (FIXNUM_P(vmode) || !NIL_P(perm)) {\n\tif (FIXNUM_P(vmode)) {\n\t    flags = FIX2INT(vmode);\n\t}\n\telse {\n\t    SafeStringValue(vmode);\n\t    flags = rb_io_mode_modenum(RSTRING(vmode)->ptr);\n\t}\n\tfmode = NIL_P(perm) ? 0666 :  NUM2UINT(perm);\n\n\trb_file_sysopen_internal(io, path, flags, fmode);\n    }\n    else {\n\tmode = NIL_P(vmode) ? \"r\" : StringValueCStr(vmode);\n\trb_file_open_internal(io, path, mode);\n    }\n    return io;\n}\n\n/*\n *  call-seq:\n *     IO.open(fd, mode_string=\"r\" )               => io\n *     IO.open(fd, mode_string=\"r\" ) {|io| block } => obj\n *  \n *  With no associated block, <code>open</code> is a synonym for\n *  <code>IO::new</code>. If the optional code block is given, it will\n *  be passed <i>io</i> as an argument, and the IO object will\n *  automatically be closed when the block terminates. In this instance,\n *  <code>IO::open</code> returns the value of the block.\n *     \n */\n\nstatic VALUE\nrb_io_s_open(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE io = rb_class_new_instance(argc, argv, klass);\n\n    if (rb_block_given_p()) {\n\treturn rb_ensure(rb_yield, io, io_close, io);\n    }\n\n    return io;\n}\n\n/*\n *  call-seq:\n *     IO.sysopen(path, [mode, [perm]])  => fixnum\n *  \n *  Opens the given path, returning the underlying file descriptor as a\n *  <code>Fixnum</code>.\n *     \n *     IO.sysopen(\"testfile\")   #=> 3\n *     \n */\n\nstatic VALUE\nrb_io_s_sysopen(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE fname, vmode, perm;\n    int flags, fd;\n    unsigned int fmode;\n    char *path;\n\n    rb_scan_args(argc, argv, \"12\", &fname, &vmode, &perm);\n    SafeStringValue(fname);\n\n    if (NIL_P(vmode)) flags = O_RDONLY;\n    else if (FIXNUM_P(vmode)) flags = FIX2INT(vmode);\n    else {\n\tSafeStringValue(vmode);\n\tflags = rb_io_mode_modenum(RSTRING(vmode)->ptr);\n    }\n    if (NIL_P(perm)) fmode = 0666;\n    else             fmode = NUM2UINT(perm);\n\n    path = ALLOCA_N(char, strlen(RSTRING(fname)->ptr)+1);\n    strcpy(path, RSTRING(fname)->ptr);\n    fd = rb_sysopen(path, flags, fmode);\n    return INT2NUM(fd);\n}\n\n/*\n *  call-seq:\n *     open(path [, mode [, perm]] )                => io or nil\n *     open(path [, mode [, perm]] ) {|io| block }  => obj\n *  \n *  Creates an <code>IO</code> object connected to the given stream,\n *  file, or subprocess.\n *     \n *  If <i>path</i> does not start with a pipe character\n *  (``<code>|</code>''), treat it as the name of a file to open using\n *  the specified mode (defaulting to ``<code>r</code>''). (See the table\n *  of valid modes on page 331.) If a file is being created, its initial\n *  permissions may be set using the integer third parameter.\n *     \n *  If a block is specified, it will be invoked with the\n *  <code>File</code> object as a parameter, and the file will be\n *  automatically closed when the block terminates. The call\n *  returns the value of the block.\n *     \n *  If <i>path</i> starts with a pipe character, a subprocess is\n *  created, connected to the caller by a pair of pipes. The returned\n *  <code>IO</code> object may be used to write to the standard input\n *  and read from the standard output of this subprocess. If the command\n *  following the ``<code>|</code>'' is a single minus sign, Ruby forks,\n *  and this subprocess is connected to the parent. In the subprocess,\n *  the <code>open</code> call returns <code>nil</code>. If the command\n *  is not ``<code>-</code>'', the subprocess runs the command. If a\n *  block is associated with an <code>open(\"|-\")</code> call, that block\n *  will be run twice---once in the parent and once in the child. The\n *  block parameter will be an <code>IO</code> object in the parent and\n *  <code>nil</code> in the child. The parent's <code>IO</code> object\n *  will be connected to the child's <code>$stdin</code> and\n *  <code>$stdout</code>. The subprocess will be terminated at the end\n *  of the block.\n *     \n *     open(\"testfile\") do |f|\n *       print f.gets\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     This is line one\n *     \n *  Open a subprocess and read its output:\n *     \n *     cmd = open(\"|date\")\n *     print cmd.gets\n *     cmd.close\n *     \n *  <em>produces:</em>\n *     \n *     Wed Apr  9 08:56:31 CDT 2003\n *     \n *  Open a subprocess running the same Ruby program:\n *     \n *     f = open(\"|-\", \"w+\")\n *     if f == nil\n *       puts \"in Child\"\n *       exit\n *     else\n *       puts \"Got: #{f.gets}\"\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     Got: in Child\n *     \n *  Open a subprocess using a block to receive the I/O object:\n *     \n *     open(\"|-\") do |f|\n *       if f == nil\n *         puts \"in Child\"\n *       else\n *         puts \"Got: #{f.gets}\"\n *       end\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     Got: in Child\n */\n\nstatic VALUE\nrb_f_open(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    if (argc >= 1) {\n\tchar *str = StringValuePtr(argv[0]);\n\n\tif (str[0] == '|') {\n\t    VALUE tmp = rb_str_new(str+1, RSTRING(argv[0])->len-1);\n\t    OBJ_INFECT(tmp, argv[0]);\n\t    argv[0] = tmp;\n\t    return rb_io_s_popen(argc, argv, rb_cIO);\n\t}\n    }\n    return rb_io_s_open(argc, argv, rb_cFile);\n}\n\nstatic VALUE\nrb_io_open(fname, mode)\n    char *fname, *mode;\n{\n    if (fname[0] == '|') {\n\treturn pipe_open(0, fname+1, mode);\n    }\n    else {\n\treturn rb_file_open(fname, mode);\n    }\n}\n\nstatic VALUE\nrb_io_get_io(io)\n    VALUE io;\n{\n    return rb_convert_type(io, T_FILE, \"IO\", \"to_io\");\n}\n\nstatic VALUE\nrb_io_check_io(io)\n    VALUE io;\n{\n    return rb_check_convert_type(io, T_FILE, \"IO\", \"to_io\");\n}\n\nstatic const char*\nrb_io_mode_string(fptr)\n    rb_io_t *fptr;\n{\n    switch (fptr->mode & FMODE_READWRITE) {\n      case FMODE_READABLE:\n      default:\n\treturn \"r\";\n      case FMODE_WRITABLE:\n\treturn \"w\";\n      case FMODE_READWRITE:\n\treturn \"r+\";\n    }\n}\n\nstatic VALUE\nio_reopen(io, nfile)\n    VALUE io, nfile;\n{\n    rb_io_t *fptr, *orig;\n    const char *mode;\n    int fd, fd2;\n    off_t pos = 0;\n\n    nfile = rb_io_get_io(nfile);\n    if (rb_safe_level() >= 4 && (!OBJ_TAINTED(io) || !OBJ_TAINTED(nfile))) {\n\trb_raise(rb_eSecurityError, \"Insecure: can't reopen\");\n    }\n    GetOpenFile(io, fptr);\n    GetOpenFile(nfile, orig);\n\n    if (fptr == orig) return io;\n    if (orig->mode & FMODE_READABLE) {\n\tpos = io_tell(orig);\n    }\n    if (orig->f2) {\n\tio_fflush(orig->f2, orig);\n    }\n    else if (orig->mode & FMODE_WRITABLE) {\n\tio_fflush(orig->f, orig);\n    }\n    if (fptr->mode & FMODE_WRITABLE) {\n\tio_fflush(GetWriteFile(fptr), fptr);\n    }\n\n    /* copy rb_io_t structure */\n    fptr->mode = orig->mode;\n    fptr->pid = orig->pid;\n    fptr->lineno = orig->lineno;\n    if (fptr->path) free(fptr->path);\n    if (orig->path) fptr->path = strdup(orig->path);\n    else fptr->path = 0;\n    fptr->finalize = orig->finalize;\n\n    mode = rb_io_mode_string(fptr);\n    fd = fileno(fptr->f);\n    fd2 = fileno(orig->f);\n    if (fd != fd2) {\n\tif (fptr->f == stdin || fptr->f == stdout || fptr->f == stderr) {\n\t    clearerr(fptr->f);\n\t    /* need to keep stdio objects */\n\t    if (dup2(fd2, fd) < 0)\n\t\trb_sys_fail(orig->path);\n\t}\n\telse {\n\t    FILE *f2 = fptr->f2;\n\t    int m = fptr->mode;\n\t    fclose(fptr->f);\n\t    fptr->f = f2;\n\t    fptr->f2 = NULL;\n\t    fptr->mode &= (m & FMODE_READABLE) ? ~FMODE_READABLE : ~FMODE_WRITABLE;\n\t    if (dup2(fd2, fd) < 0)\n\t\trb_sys_fail(orig->path);\n\t    if (f2) {\n\t\tfptr->f = rb_fdopen(fd, \"r\");\n\t\tfptr->f2 = f2;\n\t    }\n\t    else {\n\t\tfptr->f = rb_fdopen(fd, mode);\n\t    }\n\t    fptr->mode = m;\n\t}\n\trb_thread_fd_close(fd);\n\tif ((orig->mode & FMODE_READABLE) && pos >= 0) {\n\t    io_seek(fptr, pos, SEEK_SET);\n\t    io_seek(orig, pos, SEEK_SET);\n\t}\n    }\n\n    if (fptr->f2 && fd != fileno(fptr->f2)) {\n\tfd = fileno(fptr->f2);\n\tif (!orig->f2) {\n\t    fclose(fptr->f2);\n\t    rb_thread_fd_close(fd);\n\t    fptr->f2 = 0;\n\t}\n\telse if (fd != (fd2 = fileno(orig->f2))) {\n\t    fclose(fptr->f2);\n\t    rb_thread_fd_close(fd);\n\t    if (dup2(fd2, fd) < 0)\n\t\trb_sys_fail(orig->path);\n\t    fptr->f2 = rb_fdopen(fd, \"w\");\n\t}\n    }\n\n    if (fptr->mode & FMODE_BINMODE) {\n\trb_io_binmode(io);\n    }\n\n    RBASIC(io)->klass = RBASIC(nfile)->klass;\n    return io;\n}\n\n/*\n *  call-seq:\n *     ios.reopen(other_IO)         => ios \n *     ios.reopen(path, mode_str)   => ios\n *  \n *  Reassociates <em>ios</em> with the I/O stream given in\n *  <i>other_IO</i> or to a new stream opened on <i>path</i>. This may\n *  dynamically change the actual class of this stream.\n *     \n *     f1 = File.new(\"testfile\")\n *     f2 = File.new(\"testfile\")\n *     f2.readlines[0]   #=> \"This is line one\\n\"\n *     f2.reopen(f1)     #=> #<File:testfile>\n *     f2.readlines[0]   #=> \"This is line one\\n\"\n */\n\nstatic VALUE\nrb_io_reopen(argc, argv, file)\n    int argc;\n    VALUE *argv;\n    VALUE file;\n{\n    VALUE fname, nmode;\n    const char *mode;\n    rb_io_t *fptr;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"11\", &fname, &nmode) == 1) {\n\tVALUE tmp = rb_io_check_io(fname);\n\tif (!NIL_P(tmp)) {\n\t    return io_reopen(file, tmp);\n\t}\n    }\n\n    SafeStringValue(fname);\n    rb_io_taint_check(file);\n    fptr = RFILE(file)->fptr;\n    if (!fptr) {\n\tfptr = RFILE(file)->fptr = ALLOC(rb_io_t);\n\tMEMZERO(fptr, rb_io_t, 1);\n    }\n\n    if (!NIL_P(nmode)) {\n\tfptr->mode = rb_io_mode_flags(StringValueCStr(nmode));\n    }\n\n    if (fptr->path) {\n\tfree(fptr->path);\n\tfptr->path = 0;\n    }\n\n    fptr->path = strdup(StringValueCStr(fname));\n    mode = rb_io_flags_mode(fptr->mode);\n    if (!fptr->f) {\n\tfptr->f = rb_fopen(fptr->path, mode);\n\tif (fptr->f2) {\n\t    fclose(fptr->f2);\n\t    fptr->f2 = 0;\n\t}\n\treturn file;\n    }\n\n    if (freopen(fptr->path, mode, fptr->f) == 0) {\n\trb_sys_fail(fptr->path);\n    }\n#ifdef USE_SETVBUF\n    if (setvbuf(fptr->f, NULL, _IOFBF, 0) != 0)\n\trb_warn(\"setvbuf() can't be honoured for %s\", fptr->path);\n#endif\n\n    if (fptr->f2) {\n\tif (freopen(fptr->path, \"w\", fptr->f2) == 0) {\n\t    rb_sys_fail(fptr->path);\n\t}\n    }\n\n    return file;\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_io_init_copy(dest, io)\n    VALUE dest, io;\n{\n    rb_io_t *fptr, *orig;\n    int fd;\n    const char *mode;\n\n    io = rb_io_get_io(io);\n    if (dest == io) return dest;\n    GetOpenFile(io, orig);\n    MakeOpenFile(dest, fptr);\n\n    if (orig->f2) {\n\tio_fflush(orig->f2, orig);\n\tfseeko(orig->f, 0L, SEEK_CUR);\n    }\n    else if (orig->mode & FMODE_WRITABLE) {\n\tio_fflush(orig->f, orig);\n    }\n    else {\n\tfseeko(orig->f, 0L, SEEK_CUR);\n    }\n\n    /* copy rb_io_t structure */\n    fptr->mode = orig->mode;\n    fptr->pid = orig->pid;\n    fptr->lineno = orig->lineno;\n    if (orig->path) fptr->path = strdup(orig->path);\n    fptr->finalize = orig->finalize;\n\n    switch (fptr->mode & FMODE_READWRITE) {\n      case FMODE_READABLE:\n      default:\n\tmode = \"r\"; break;\n      case FMODE_WRITABLE:\n\tmode = \"w\"; break;\n      case FMODE_READWRITE:\n\tif (orig->f2) mode = \"r\";\n\telse          mode = \"r+\";\n\tbreak;\n    }\n    fd = ruby_dup(fileno(orig->f));\n    fptr->f = rb_fdopen(fd, mode);\n    fseeko(fptr->f, ftello(orig->f), SEEK_SET);\n    if (orig->f2) {\n\tif (fileno(orig->f) != fileno(orig->f2)) {\n\t    fd = ruby_dup(fileno(orig->f2));\n\t}\n\tfptr->f2 = rb_fdopen(fd, \"w\");\n\tfseeko(fptr->f2, ftello(orig->f2), SEEK_SET);\n    }\n    if (fptr->mode & FMODE_BINMODE) {\n\trb_io_binmode(dest);\n    }\n\n    return dest;\n}\n\n/*\n *  call-seq:\n *     ios.printf(format_string [, obj, ...] )   => nil\n *  \n *  Formats and writes to <em>ios</em>, converting parameters under\n *  control of the format string. See <code>Kernel#sprintf</code>\n *  for details.\n */\n\nVALUE\nrb_io_printf(argc, argv, out)\n    int argc;\n    VALUE argv[];\n    VALUE out;\n{\n    rb_io_write(out, rb_f_sprintf(argc, argv));\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     printf(io, string [, obj ... ] )    => nil\n *     printf(string [, obj ... ] )        => nil\n *  \n *  Equivalent to:\n *     io.write(sprintf(string, obj, ...)\n *  or\n *     $stdout.write(sprintf(string, obj, ...)\n */\n\nstatic VALUE\nrb_f_printf(argc, argv)\n    int argc;\n    VALUE argv[];\n{\n    VALUE out;\n\n    if (argc == 0) return Qnil;\n    if (TYPE(argv[0]) == T_STRING) {\n\tout = rb_stdout;\n    }\n    else {\n\tout = argv[0];\n\targv++;\n\targc--;\n    }\n    rb_io_write(out, rb_f_sprintf(argc, argv));\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.print()             => nil\n *     ios.print(obj, ...)     => nil\n *  \n *  Writes the given object(s) to <em>ios</em>. The stream must be\n *  opened for writing. If the output record separator (<code>$\\\\</code>)\n *  is not <code>nil</code>, it will be appended to the output. If no\n *  arguments are given, prints <code>$_</code>. Objects that aren't\n *  strings will be converted by calling their <code>to_s</code> method.\n *  With no argument, prints the contents of the variable <code>$_</code>.\n *  Returns <code>nil</code>.\n *     \n *     $stdout.print(\"This is \", 100, \" percent.\\n\")\n *     \n *  <em>produces:</em>\n *     \n *     This is 100 percent.\n */\n\nVALUE\nrb_io_print(argc, argv, out)\n    int argc;\n    VALUE *argv;\n    VALUE out;\n{\n    int i;\n    VALUE line;\n\n    /* if no argument given, print `$_' */\n    if (argc == 0) {\n\targc = 1;\n\tline = rb_lastline_get();\n\targv = &line;\n    }\n    for (i=0; i<argc; i++) {\n\tif (!NIL_P(rb_output_fs) && i>0) {\n\t    rb_io_write(out, rb_output_fs);\n\t}\n\tswitch (TYPE(argv[i])) {\n\t  case T_NIL:\n\t    rb_io_write(out, rb_str_new2(\"nil\"));\n\t    break;\n\t  default:\n\t    rb_io_write(out, argv[i]);\n\t    break;\n\t}\n    }\n    if (!NIL_P(rb_output_rs)) {\n\trb_io_write(out, rb_output_rs);\n    }\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     print(obj, ...)    => nil\n *  \n *  Prints each object in turn to <code>$stdout</code>. If the output\n *  field separator (<code>$,</code>) is not +nil+, its\n *  contents will appear between each field. If the output record\n *  separator (<code>$\\\\</code>) is not +nil+, it will be\n *  appended to the output. If no arguments are given, prints\n *  <code>$_</code>. Objects that aren't strings will be converted by\n *  calling their <code>to_s</code> method.\n *     \n *     print \"cat\", [1,2,3], 99, \"\\n\"\n *     $, = \", \"\n *     $\\ = \"\\n\"\n *     print \"cat\", [1,2,3], 99\n *     \n *  <em>produces:</em>\n *     \n *     cat12399\n *     cat, 1, 2, 3, 99\n */\n\nstatic VALUE\nrb_f_print(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    rb_io_print(argc, argv, rb_stdout);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.putc(obj)    => obj\n *  \n *  If <i>obj</i> is <code>Numeric</code>, write the character whose\n *  code is <i>obj</i>, otherwise write the first character of the\n *  string representation of  <i>obj</i> to <em>ios</em>.\n *     \n *     $stdout.putc \"A\"\n *     $stdout.putc 65\n *     \n *  <em>produces:</em>\n *     \n *     AA\n */\n\nstatic VALUE\nrb_io_putc(io, ch)\n    VALUE io, ch;\n{\n    char c = NUM2CHR(ch);\n\n    rb_io_write(io, rb_str_new(&c, 1));\n    return ch;\n}\n\n/*\n *  call-seq:\n *     putc(int)   => int\n *  \n *  Equivalent to:\n *\n *    $stdout.putc(int)\n */\n\nstatic VALUE\nrb_f_putc(recv, ch)\n    VALUE recv, ch;\n{\n    return rb_io_putc(rb_stdout, ch);\n}\n\nstatic VALUE\nio_puts_ary(ary, out)\n    VALUE ary, out;\n{\n    VALUE tmp;\n    long i;\n\n    for (i=0; i<RARRAY(ary)->len; i++) {\n\ttmp = RARRAY(ary)->ptr[i];\n\tif (rb_inspecting_p(tmp)) {\n\t    tmp = rb_str_new2(\"[...]\");\n\t}\n\trb_io_puts(1, &tmp, out);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     ios.puts(obj, ...)    => nil\n *  \n *  Writes the given objects to <em>ios</em> as with\n *  <code>IO#print</code>. Writes a record separator (typically a\n *  newline) after any that do not already end with a newline sequence.\n *  If called with an array argument, writes each element on a new line.\n *  If called without arguments, outputs a single record separator.\n *     \n *     $stdout.puts(\"this\", \"is\", \"a\", \"test\")\n *     \n *  <em>produces:</em>\n *     \n *     this\n *     is\n *     a\n *     test\n */\n\nVALUE\nrb_io_puts(argc, argv, out)\n    int argc;\n    VALUE *argv;\n    VALUE out;\n{\n    int i;\n    VALUE line;\n\n    /* if no argument given, print newline. */\n    if (argc == 0) {\n\trb_io_write(out, rb_default_rs);\n\treturn Qnil;\n    }\n    for (i=0; i<argc; i++) {\n\tif (NIL_P(argv[i])) {\n\t    line = rb_str_new2(\"nil\");\n\t}\n\telse {\n\t    line = rb_check_array_type(argv[i]);\n\t    if (!NIL_P(line)) {\n\t\trb_protect_inspect(io_puts_ary, line, out);\n\t\tcontinue;\n\t    }\n\t    line = rb_obj_as_string(argv[i]);\n\t}\n\trb_io_write(out, line);\n\tif (RSTRING(line)->len == 0 ||\n            RSTRING(line)->ptr[RSTRING(line)->len-1] != '\\n') {\n\t    rb_io_write(out, rb_default_rs);\n\t}\n    }\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     puts(obj, ...)    => nil\n *  \n *  Equivalent to \n *\n *      $stdout.puts(obj, ...)\n */\n\nstatic VALUE\nrb_f_puts(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    rb_io_puts(argc, argv, rb_stdout);\n    return Qnil;\n}\n\nvoid\nrb_p(obj)\t\t\t/* for debug print within C code */\n    VALUE obj;\n{\n    rb_io_write(rb_stdout, rb_obj_as_string(rb_inspect(obj)));\n    rb_io_write(rb_stdout, rb_default_rs);\n}\n\n/*\n *  call-seq:\n *     p(obj, ...)    => nil\n *  \n *  For each object, directly writes\n *  _obj_.+inspect+ followed by the current output\n *  record separator to the program's standard output.\n *     \n *     S = Struct.new(:name, :state)\n *     s = S['dave', 'TX']\n *     p s\n *     \n *  <em>produces:</em>\n *     \n *     #<S name=\"dave\", state=\"TX\">\n */\n\nstatic VALUE\nrb_f_p(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n\trb_p(argv[i]);\n    }\n    if (TYPE(rb_stdout) == T_FILE) {\n\trb_io_flush(rb_stdout);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     obj.display(port=$>)    => nil\n *  \n *  Prints <i>obj</i> on the given port (default <code>$></code>).\n *  Equivalent to:\n *     \n *     def display(port=$>)\n *       port.write self\n *     end\n *     \n *  For example:\n *     \n *     1.display\n *     \"cat\".display\n *     [ 4, 5, 6 ].display\n *     puts\n *     \n *  <em>produces:</em>\n *     \n *     1cat456\n */\n\nstatic VALUE\nrb_obj_display(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE out;\n\n    if (rb_scan_args(argc, argv, \"01\", &out) == 0) {\n\tout = rb_stdout;\n    }\n\n    rb_io_write(out, self);\n\n    return Qnil;\n}\n\nvoid\nrb_write_error2(mesg, len)\n    const char *mesg;\n    long len;\n{\n    rb_io_write(rb_stderr, rb_str_new(mesg, len));\n}\n\nvoid\nrb_write_error(mesg)\n    const char *mesg;\n{\n    rb_write_error2(mesg, strlen(mesg));\n}\n\nstatic void\nmust_respond_to(mid, val, id)\n    ID mid;\n    VALUE val;\n    ID id;\n{\n    if (!rb_respond_to(val, mid)) {\n\trb_raise(rb_eTypeError, \"%s must have %s method, %s given\",\n\t\t rb_id2name(id), rb_id2name(mid),\n\t\t rb_obj_classname(val));\n    }\n}\n\nstatic void\nstdout_setter(val, id, variable)\n    VALUE val;\n    ID id;\n    VALUE *variable;\n{\n    must_respond_to(id_write, val, id);\n    *variable = val;\n}\n\nstatic void\ndefout_setter(val, id, variable)\n    VALUE val;\n    ID id;\n    VALUE *variable;\n{\n    stdout_setter(val, id, variable);\n    rb_warn(\"$defout is obsolete; use $stdout instead\");\n}\n\nstatic void\ndeferr_setter(val, id, variable)\n    VALUE val;\n    ID id;\n    VALUE *variable;\n{\n    stdout_setter(val, id, variable);\n    rb_warn(\"$deferr is obsolete; use $stderr instead\");\n}\n\nstatic VALUE\nprep_stdio(f, mode, klass)\n    FILE *f;\n    int mode;\n    VALUE klass;\n{\n    rb_io_t *fp;\n    VALUE io = io_alloc(klass);\n\n    MakeOpenFile(io, fp);\n#ifdef __CYGWIN__\n    if (!isatty(fileno(f))) {\n\tmode |= O_BINARY;\n\tsetmode(fileno(f), O_BINARY);\n    }\n#endif\n    fp->f = f;\n    fp->mode = mode;\n\n    return io;\n}\n\nstatic void\nprep_path(io, path)\n    VALUE io;\n    char *path;\n{\n    rb_io_t *fptr;\n\n    GetOpenFile(io, fptr);\n    if (fptr->path) rb_bug(\"illegal prep_path() call\");\n    fptr->path = strdup(path);\n}\n\n/*\n *  call-seq:\n *     IO.new(fd, mode)   => io\n *  \n *  Returns a new <code>IO</code> object (a stream) for the given\n *  integer file descriptor and mode string. See also\n *  <code>IO#fileno</code> and <code>IO::for_fd</code>.\n *     \n *     a = IO.new(2,\"w\")      # '2' is standard error\n *     $stderr.puts \"Hello\"\n *     a.puts \"World\"\n *     \n *  <em>produces:</em>\n *     \n *     Hello\n *     World\n */\n\nstatic VALUE\nrb_io_initialize(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE fnum, mode;\n    rb_io_t *fp;\n    int fd, flags;\n\n    rb_secure(4);\n    rb_scan_args(argc, argv, \"11\", &fnum, &mode);\n    fd = NUM2INT(fnum);\n    if (argc == 2) {\n\tif (FIXNUM_P(mode)) {\n\t    flags = FIX2LONG(mode);\n\t}\n\telse {\n\t    SafeStringValue(mode);\n\t    flags = rb_io_mode_modenum(StringValueCStr(mode));\n\t}\n    }\n    else {\n#if defined(HAVE_FCNTL) && defined(F_GETFL)\n\tflags = fcntl(fd, F_GETFL);\n\tif (flags == -1) rb_sys_fail(0);\n#else\n\tflags = O_RDONLY;\n#endif\n    }\n    MakeOpenFile(io, fp);\n    fp->mode = rb_io_modenum_flags(flags);\n    fp->f = rb_fdopen(fd, rb_io_modenum_mode(flags));\n\n    return io;\n}\n\n/*\n *  call-seq:\n *     File.new(filename, mode=\"r\")            => file\n *     File.new(filename [, mode [, perm]])    => file\n *  \n\n *  Opens the file named by _filename_ according to\n *  _mode_ (default is ``r'') and returns a new\n *  <code>File</code> object. See the description of class +IO+ for\n *  a description of _mode_. The file mode may optionally be\n *  specified as a +Fixnum+ by _or_-ing together the\n *  flags (O_RDONLY etc, again described under +IO+). Optional\n *  permission bits may be given in _perm_. These mode and permission\n *  bits are platform dependent; on Unix systems, see\n *  <code>open(2)</code> for details.\n *\n *     f = File.new(\"testfile\", \"r\")\n *     f = File.new(\"newfile\",  \"w+\")\n *     f = File.new(\"newfile\", File::CREAT|File::TRUNC|File::RDWR, 0644)\n */\n\nstatic VALUE\nrb_file_initialize(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    if (RFILE(io)->fptr) {\n\trb_raise(rb_eRuntimeError, \"reinitializing File\");\n    }\n    if (0 < argc && argc < 3) {\n\tVALUE fd = rb_check_convert_type(argv[0], T_FIXNUM, \"Fixnum\", \"to_int\");\n\n\tif (!NIL_P(fd)) {\n\t    argv[0] = fd;\n\t    return rb_io_initialize(argc, argv, io);\n\t}\n    }\n    rb_open_file(argc, argv, io);\n\n    return io;\n}\n\n/*\n *  call-seq:\n *     IO.new(fd, mode_string)   => io\n *  \n *  Returns a new <code>IO</code> object (a stream) for the given\n *  integer file descriptor and mode string. See also\n *  <code>IO#fileno</code> and <code>IO::for_fd</code>.\n *     \n *     a = IO.new(2,\"w\")      # '2' is standard error\n *     $stderr.puts \"Hello\"\n *     a.puts \"World\"\n *     \n *  <em>produces:</em>\n *     \n *     Hello\n *     World\n */\n\nstatic VALUE\nrb_io_s_new(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    if (rb_block_given_p()) {\n\tconst char *cname = rb_class2name(klass);\n\n\trb_warn(\"%s::new() does not take block; use %s::open() instead\",\n\t\tcname, cname);\n    }\n    return rb_class_new_instance(argc, argv, klass);\n}\n\n/*\n *  call-seq:\n *     IO.for_fd(fd, mode)    => io\n *  \n *  Synonym for <code>IO::new</code>.\n *     \n */\n\nstatic VALUE\nrb_io_s_for_fd(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE io = rb_obj_alloc(klass);\n    rb_io_initialize(argc, argv, io);\n    return io;\n}\n\nstatic int binmode = 0;\n\nstatic VALUE\nargf_forward(int argc, VALUE *argv)\n{\n    return rb_funcall3(current_file, ruby_frame->last_func, argc, argv);\n}\n\n#define ARGF_FORWARD(argc, argv) do {\\\n  if (TYPE(current_file) != T_FILE)\\\n     return argf_forward(argc, argv);\\\n} while (0)\n#define NEXT_ARGF_FORWARD(argc, argv) do {\\\n     if (!next_argv()) return Qnil;\\\n     ARGF_FORWARD(argc, argv);\\\n} while (0)\n\nstatic void\nargf_close(file)\n    VALUE file;\n{\n    rb_funcall3(file, rb_intern(\"close\"), 0, 0);\n}\n\nstatic int\nnext_argv()\n{\n    extern VALUE rb_argv;\n    char *fn;\n    rb_io_t *fptr;\n    int stdout_binmode = 0;\n\n    if (TYPE(rb_stdout) == T_FILE) {\n        GetOpenFile(rb_stdout, fptr);\n        if (fptr->mode & FMODE_BINMODE)\n            stdout_binmode = 1;\n    }\n\n    if (init_p == 0) {\n\tif (RARRAY(rb_argv)->len > 0) {\n\t    next_p = 1;\n\t}\n\telse {\n\t    next_p = -1;\n\t}\n\tinit_p = 1;\n\tgets_lineno = 0;\n    }\n\n    if (next_p == 1) {\n\tnext_p = 0;\n      retry:\n\tif (RARRAY(rb_argv)->len > 0) {\n\t    filename = rb_ary_shift(rb_argv);\n\t    fn = StringValueCStr(filename);\n\t    if (strlen(fn) == 1 && fn[0] == '-') {\n\t\tcurrent_file = rb_stdin;\n\t\tif (ruby_inplace_mode) {\n\t\t    rb_warn(\"Can't do inplace edit for stdio; skipping\");\n\t\t    goto retry;\n\t\t}\n\t    }\n\t    else {\n\t\tFILE *fr = rb_fopen(fn, \"r\");\n\n\t\tif (ruby_inplace_mode) {\n\t\t    struct stat st;\n#ifndef NO_SAFE_RENAME\n\t\t    struct stat st2;\n#endif\n\t\t    VALUE str;\n\t\t    FILE *fw;\n\n\t\t    if (TYPE(rb_stdout) == T_FILE && rb_stdout != orig_stdout) {\n\t\t\trb_io_close(rb_stdout);\n\t\t    }\n\t\t    fstat(fileno(fr), &st);\n\t\t    if (*ruby_inplace_mode) {\n\t\t\tstr = rb_str_new2(fn);\n#ifdef NO_LONG_FNAME\n                        ruby_add_suffix(str, ruby_inplace_mode);\n#else\n\t\t\trb_str_cat2(str, ruby_inplace_mode);\n#endif\n#ifdef NO_SAFE_RENAME\n\t\t\t(void)fclose(fr);\n\t\t\t(void)unlink(RSTRING(str)->ptr);\n\t\t\t(void)rename(fn, RSTRING(str)->ptr);\n\t\t\tfr = rb_fopen(RSTRING(str)->ptr, \"r\");\n#else\n\t\t\tif (rename(fn, RSTRING(str)->ptr) < 0) {\n\t\t\t    rb_warn(\"Can't rename %s to %s: %s, skipping file\",\n\t\t\t\t    fn, RSTRING(str)->ptr, strerror(errno));\n\t\t\t    fclose(fr);\n\t\t\t    goto retry;\n\t\t\t}\n#endif\n\t\t    }\n\t\t    else {\n#ifdef NO_SAFE_RENAME\n\t\t\trb_fatal(\"Can't do inplace edit without backup\");\n#else\n\t\t\tif (unlink(fn) < 0) {\n\t\t\t    rb_warn(\"Can't remove %s: %s, skipping file\",\n\t\t\t\t    fn, strerror(errno));\n\t\t\t    fclose(fr);\n\t\t\t    goto retry;\n\t\t\t}\n#endif\n\t\t    }\n\t\t    fw = rb_fopen(fn, \"w\");\n#ifndef NO_SAFE_RENAME\n\t\t    fstat(fileno(fw), &st2);\n#ifdef HAVE_FCHMOD\n\t\t    fchmod(fileno(fw), st.st_mode);\n#else\n\t\t    chmod(fn, st.st_mode);\n#endif\n\t\t    if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {\n\t\t\tfchown(fileno(fw), st.st_uid, st.st_gid);\n\t\t    }\n#endif\n\t\t    rb_stdout = prep_stdio(fw, FMODE_WRITABLE, rb_cFile);\n\t\t    prep_path(rb_stdout, fn);\n\t\t    if (stdout_binmode) rb_io_binmode(rb_stdout);\n\t\t}\n\t\tcurrent_file = prep_stdio(fr, FMODE_READABLE, rb_cFile);\n\t\tprep_path(current_file, fn);\n\t    }\n\t    if (binmode) rb_io_binmode(current_file);\n\t}\n\telse {\n\t    next_p = 1;\n\t    return Qfalse;\n\t}\n    }\n    else if (next_p == -1) {\n\tcurrent_file = rb_stdin;\n\tfilename = rb_str_new2(\"-\");\n\tif (ruby_inplace_mode) {\n\t    rb_warn(\"Can't do inplace edit for stdio\");\n\t    rb_stdout = orig_stdout;\n\t}\n    }\n    return Qtrue;\n}\n\nstatic VALUE\nargf_getline(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE line;\n\n  retry:\n    if (!next_argv()) return Qnil;\n    if (argc == 0 && rb_rs == rb_default_rs) {\n\tline = rb_io_gets(current_file);\n    }\n    else {\n\tVALUE rs;\n\n\tif (argc == 0) {\n\t    rs = rb_rs;\n\t}\n\telse {\n\t    rb_scan_args(argc, argv, \"1\", &rs);\n\t    if (!NIL_P(rs)) StringValue(rs);\n\t}\n\tline = rb_io_getline(rs, current_file);\n    }\n    if (NIL_P(line) && next_p != -1) {\n\targf_close(current_file);\n\tnext_p = 1;\n\tgoto retry;\n    }\n    if (!NIL_P(line)) {\n\tgets_lineno++;\n\tlineno = INT2FIX(gets_lineno);\n    }\n    return line;\n}\n\n/*\n *  call-seq:\n *     gets(separator=$/)    => string or nil\n *  \n *  Returns (and assigns to <code>$_</code>) the next line from the list\n *  of files in +ARGV+ (or <code>$*</code>), or from standard\n *  input if no files are present on the command line. Returns\n *  +nil+ at end of file. The optional argument specifies the\n *  record separator. The separator is included with the contents of\n *  each record. A separator of +nil+ reads the entire\n *  contents, and a zero-length separator reads the input one paragraph\n *  at a time, where paragraphs are divided by two consecutive newlines.\n *  If multiple filenames are present in +ARGV+,\n *  +gets(nil)+ will read the contents one file at a time.\n *     \n *     ARGV << \"testfile\"\n *     print while gets\n *     \n *  <em>produces:</em>\n *     \n *     This is line one\n *     This is line two\n *     This is line three\n *     And so on...\n *     \n *  The style of programming using <code>$_</code> as an implicit\n *  parameter is gradually losing favor in the Ruby community.\n */\n\nstatic VALUE\nrb_f_gets(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE line;\n\n    if (!next_argv()) return Qnil;\n    if (TYPE(current_file) != T_FILE) {\n\tline = rb_funcall3(current_file, rb_intern(\"gets\"), argc, argv);\n    }\n    else {\n\tline = argf_getline(argc, argv);\n    }\n    rb_lastline_set(line);\n    return line;\n}\n\nVALUE\nrb_gets()\n{\n    VALUE line;\n\n    if (rb_rs != rb_default_rs) {\n\treturn rb_f_gets(0, 0);\n    }\n\n  retry:\n    if (!next_argv()) return Qnil;\n    line = rb_io_gets(current_file);\n    if (NIL_P(line) && next_p != -1) {\n\targf_close(current_file);\n\tnext_p = 1;\n\tgoto retry;\n    }\n    rb_lastline_set(line);\n    if (!NIL_P(line)) {\n\tgets_lineno++;\n\tlineno = INT2FIX(gets_lineno);\n    }\n\n    return line;\n}\n\n/*\n *  call-seq:\n *     readline(separator=$/)   => string\n *  \n *  Equivalent to <code>Kernel::gets</code>, except\n *  +readline+ raises +EOFError+ at end of file.\n */\n\nstatic VALUE\nrb_f_readline(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE line;\n\n    if (!next_argv()) rb_eof_error();\n    ARGF_FORWARD(argc, argv);\n    line = rb_f_gets(argc, argv);\n    if (NIL_P(line)) {\n\trb_eof_error();\n    }\n\n    return line;\n}\n\n/*\n * obsolete\n */\n\nstatic VALUE\nrb_f_getc()\n{\n    rb_warn(\"getc is obsolete; use STDIN.getc instead\");\n    if (TYPE(rb_stdin) != T_FILE) {\n\treturn rb_funcall3(rb_stdin, rb_intern(\"getc\"), 0, 0);\n    }\n    return rb_io_getc(rb_stdin);\n}\n\n/*\n *  call-seq:\n *     readlines(separator=$/)    => array\n *  \n *  Returns an array containing the lines returned by calling\n *  <code>Kernel.gets(<i>separator</i>)</code> until the end of file.\n */\n\nstatic VALUE\nrb_f_readlines(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE line, ary;\n\n    NEXT_ARGF_FORWARD(argc, argv);\n    ary = rb_ary_new();\n    while (!NIL_P(line = argf_getline(argc, argv))) {\n\trb_ary_push(ary, line);\n    }\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     `cmd`    => string\n *  \n *  Returns the standard output of running _cmd_ in a subshell.\n *  The built-in syntax <code>%x{...}</code> uses\n *  this method. Sets <code>$?</code> to the process status.\n *     \n *     `date`                   #=> \"Wed Apr  9 08:56:30 CDT 2003\\n\"\n *     `ls testdir`.split[1]    #=> \"main.rb\"\n *     `echo oops && exit 99`   #=> \"oops\\n\"\n *     $?.exitstatus            #=> 99\n */\n\nstatic VALUE\nrb_f_backquote(obj, str)\n    VALUE obj, str;\n{\n    volatile VALUE port;\n    VALUE result;\n    rb_io_t *fptr;\n\n    SafeStringValue(str);\n    port = pipe_open(str, 0, \"r\");\n    if (NIL_P(port)) return rb_str_new(0,0);\n\n    GetOpenFile(port, fptr);\n    result = read_all(fptr, remain_size(fptr), Qnil);\n    rb_io_close(port);\n\n    return result;\n}\n\n#ifdef HAVE_SYS_SELECT_H\n#include <sys/select.h>\n#endif\n\n/*\n *  call-seq:\n *     IO.select(read_array \n *               [, write_array \n *               [, error_array \n *               [, timeout]]] ) =>  array  or  nil\n *  \n *  See <code>Kernel#select</code>.\n */\n\nstatic VALUE\nrb_f_select(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE read, write, except, timeout, res, list;\n    fd_set rset, wset, eset, pset;\n    fd_set *rp, *wp, *ep;\n    struct timeval *tp, timerec;\n    rb_io_t *fptr;\n    long i;\n    int max = 0, n;\n    int interrupt_flag = 0;\n    int pending = 0;\n\n    rb_scan_args(argc, argv, \"13\", &read, &write, &except, &timeout);\n    if (NIL_P(timeout)) {\n\ttp = 0;\n    }\n    else {\n\ttimerec = rb_time_interval(timeout);\n\ttp = &timerec;\n    }\n\n    FD_ZERO(&pset);\n    if (!NIL_P(read)) {\n\tCheck_Type(read, T_ARRAY);\n\trp = &rset;\n\tFD_ZERO(rp);\n\tfor (i=0; i<RARRAY(read)->len; i++) {\n\t    GetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);\n\t    FD_SET(fileno(fptr->f), rp);\n\t    if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */\n\t\tpending++;\n\t\tFD_SET(fileno(fptr->f), &pset);\n\t    }\n\t    if (max < fileno(fptr->f)) max = fileno(fptr->f);\n\t}\n\tif (pending) {\t\t/* no blocking if there's buffered data */\n\t    timerec.tv_sec = timerec.tv_usec = 0;\n\t    tp = &timerec;\n\t}\n    }\n    else\n\trp = 0;\n\n    if (!NIL_P(write)) {\n\tCheck_Type(write, T_ARRAY);\n\twp = &wset;\n\tFD_ZERO(wp);\n\tfor (i=0; i<RARRAY(write)->len; i++) {\n\t    GetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);\n\t    FD_SET(fileno(fptr->f), wp);\n\t    if (max < fileno(fptr->f)) max = fileno(fptr->f);\n\t    if (fptr->f2) {\n\t\tFD_SET(fileno(fptr->f2), wp);\n\t\tif (max < fileno(fptr->f2)) max = fileno(fptr->f2);\n\t    }\n\t}\n    }\n    else\n\twp = 0;\n\n    if (!NIL_P(except)) {\n\tCheck_Type(except, T_ARRAY);\n\tep = &eset;\n\tFD_ZERO(ep);\n\tfor (i=0; i<RARRAY(except)->len; i++) {\n\t    GetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);\n\t    FD_SET(fileno(fptr->f), ep);\n\t    if (max < fileno(fptr->f)) max = fileno(fptr->f);\n\t    if (fptr->f2) {\n\t\tFD_SET(fileno(fptr->f2), ep);\n\t\tif (max < fileno(fptr->f2)) max = fileno(fptr->f2);\n\t    }\n\t}\n    }\n    else {\n\tep = 0;\n    }\n\n    max++;\n\n    n = rb_thread_select(max, rp, wp, ep, tp);\n    if (n < 0) {\n\trb_sys_fail(0);\n    }\n    if (!pending && n == 0) return Qnil; /* returns nil on timeout */\n\n    res = rb_ary_new2(3);\n    rb_ary_push(res, rp?rb_ary_new():rb_ary_new2(0));\n    rb_ary_push(res, wp?rb_ary_new():rb_ary_new2(0));\n    rb_ary_push(res, ep?rb_ary_new():rb_ary_new2(0));\n\n    if (interrupt_flag == 0) {\n\tif (rp) {\n\t    list = RARRAY(res)->ptr[0];\n\t    for (i=0; i< RARRAY(read)->len; i++) {\n\t\tGetOpenFile(rb_io_get_io(RARRAY(read)->ptr[i]), fptr);\n\t\tif (FD_ISSET(fileno(fptr->f), rp)\n\t\t    || FD_ISSET(fileno(fptr->f), &pset)) {\n\t\t    rb_ary_push(list, rb_ary_entry(read, i));\n\t\t}\n\t    }\n\t}\n\n\tif (wp) {\n\t    list = RARRAY(res)->ptr[1];\n\t    for (i=0; i< RARRAY(write)->len; i++) {\n\t\tGetOpenFile(rb_io_get_io(RARRAY(write)->ptr[i]), fptr);\n\t\tif (FD_ISSET(fileno(fptr->f), wp)) {\n\t\t    rb_ary_push(list, rb_ary_entry(write, i));\n\t\t}\n\t\telse if (fptr->f2 && FD_ISSET(fileno(fptr->f2), wp)) {\n\t\t    rb_ary_push(list, rb_ary_entry(write, i));\n\t\t}\n\t    }\n\t}\n\n\tif (ep) {\n\t    list = RARRAY(res)->ptr[2];\n\t    for (i=0; i< RARRAY(except)->len; i++) {\n\t\tGetOpenFile(rb_io_get_io(RARRAY(except)->ptr[i]), fptr);\n\t\tif (FD_ISSET(fileno(fptr->f), ep)) {\n\t\t    rb_ary_push(list, rb_ary_entry(except, i));\n\t\t}\n\t\telse if (fptr->f2 && FD_ISSET(fileno(fptr->f2), ep)) {\n\t\t    rb_ary_push(list, rb_ary_entry(except, i));\n\t\t}\n\t    }\n\t}\n    }\n\n    return res;\t\t\t/* returns an empty array on interrupt */\n}\n\n#if !defined(MSDOS) && !defined(__human68k__)\nstatic int\nio_cntl(fd, cmd, narg, io_p)\n    int fd, cmd, io_p;\n    long narg;\n{\n    int retval;\n\n#ifdef HAVE_FCNTL\n    TRAP_BEG;\n# if defined(__CYGWIN__)\n    retval = io_p?ioctl(fd, cmd, (void*)narg):fcntl(fd, cmd, narg);\n# else\n    retval = io_p?ioctl(fd, cmd, narg):fcntl(fd, cmd, narg);\n# endif\n    TRAP_END;\n#else\n    if (!io_p) {\n\trb_notimplement();\n    }\n    TRAP_BEG;\n    retval = ioctl(fd, cmd, narg);\n    TRAP_END;\n#endif\n    return retval;\n}\n#endif\n\nstatic VALUE\nrb_io_ctl(io, req, arg, io_p)\n    VALUE io, req, arg;\n    int io_p;\n{\n#if !defined(MSDOS) && !defined(__human68k__)\n    int cmd = NUM2ULONG(req);\n    rb_io_t *fptr;\n    long len = 0;\n    long narg = 0;\n    int retval;\n\n    rb_secure(2);\n\n    if (NIL_P(arg) || arg == Qfalse) {\n\tnarg = 0;\n    }\n    else if (FIXNUM_P(arg)) {\n\tnarg = FIX2LONG(arg);\n    }\n    else if (arg == Qtrue) {\n\tnarg = 1;\n    }\n    else {\n\tVALUE tmp = rb_check_string_type(arg);\n\n\tif (NIL_P(tmp)) {\n\t    narg = NUM2LONG(arg);\n\t}\n\telse {\n\t    arg = tmp;\n#ifdef IOCPARM_MASK\n#ifndef IOCPARM_LEN\n#define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)\n#endif\n#endif\n#ifdef IOCPARM_LEN\n\t    len = IOCPARM_LEN(cmd);\t/* on BSDish systems we're safe */\n#else\n\t    len = 256;\t\t/* otherwise guess at what's safe */\n#endif\n\t    rb_str_modify(arg);\n\n\t    if (len <= RSTRING(arg)->len) {\n\t\tlen = RSTRING(arg)->len;\n\t    }\n\t    if (RSTRING(arg)->len < len) {\n\t\trb_str_resize(arg, len+1);\n\t    }\n\t    RSTRING(arg)->ptr[len] = 17;\t/* a little sanity check here */\n\t    narg = (long)RSTRING(arg)->ptr;\n\t}\n    }\n    GetOpenFile(io, fptr);\n    retval = io_cntl(fileno(fptr->f), cmd, narg, io_p);\n    if (retval < 0) rb_sys_fail(fptr->path);\n    if (TYPE(arg) == T_STRING && RSTRING(arg)->ptr[len] != 17) {\n\trb_raise(rb_eArgError, \"return value overflowed string\");\n    }\n\n    if (fptr->f2 && fileno(fptr->f) != fileno(fptr->f2)) {\n\t/* call on f2 too; ignore result */\n\tio_cntl(fileno(fptr->f2), cmd, narg, io_p);\n    }\n\n    if (!io_p && cmd == F_SETFL) {\n      if (narg & O_NONBLOCK) {\n        fptr->mode |= FMODE_WSPLIT_INITIALIZED;\n        fptr->mode &= ~FMODE_WSPLIT;\n      }\n      else {\n        fptr->mode &= ~(FMODE_WSPLIT_INITIALIZED|FMODE_WSPLIT);\n      }\n    }\n\n    return INT2NUM(retval);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n/*\n *  call-seq:\n *     ios.ioctl(integer_cmd, arg)    => integer\n *  \n *  Provides a mechanism for issuing low-level commands to control or\n *  query I/O devices. Arguments and results are platform dependent. If\n *  <i>arg</i> is a number, its value is passed directly. If it is a\n *  string, it is interpreted as a binary sequence of bytes. On Unix\n *  platforms, see <code>ioctl(2)</code> for details. Not implemented on\n *  all platforms.\n */\n\nstatic VALUE\nrb_io_ioctl(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE req, arg;\n\n    rb_scan_args(argc, argv, \"11\", &req, &arg);\n    return rb_io_ctl(io, req, arg, 1);\n}\n\n/*\n *  call-seq:\n *     ios.fcntl(integer_cmd, arg)    => integer\n *  \n *  Provides a mechanism for issuing low-level commands to control or\n *  query file-oriented I/O streams. Arguments and results are platform\n *  dependent. If <i>arg</i> is a number, its value is passed\n *  directly. If it is a string, it is interpreted as a binary sequence\n *  of bytes (<code>Array#pack</code> might be a useful way to build this\n *  string). On Unix platforms, see <code>fcntl(2)</code> for details.\n *  Not implemented on all platforms.\n */\n\nstatic VALUE\nrb_io_fcntl(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n#ifdef HAVE_FCNTL\n    VALUE req, arg;\n\n    rb_scan_args(argc, argv, \"11\", &req, &arg);\n    return rb_io_ctl(io, req, arg, 0);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n/*\n *  call-seq:\n *     syscall(fixnum [, args...])   => integer\n *  \n *  Calls the operating system function identified by _fixnum_,\n *  passing in the arguments, which must be either +String+\n *  objects, or +Integer+ objects that ultimately fit within\n *  a native +long+. Up to nine parameters may be passed (14\n *  on the Atari-ST). The function identified by _fixnum_ is system\n *  dependent. On some Unix systems, the numbers may be obtained from a\n *  header file called <code>syscall.h</code>.\n *     \n *     syscall 4, 1, \"hello\\n\", 6   # '4' is write(2) on our box\n *     \n *  <em>produces:</em>\n *     \n *     hello\n */\n\nstatic VALUE\nrb_f_syscall(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n#if defined(HAVE_SYSCALL) && !defined(__CHECKER__)\n#ifdef atarist\n    unsigned long arg[14]; /* yes, we really need that many ! */\n#else\n    unsigned long arg[8];\n#endif\n    int retval = -1;\n    int i = 1;\n    int items = argc - 1;\n\n    /* This probably won't work on machines where sizeof(long) != sizeof(int)\n     * or where sizeof(long) != sizeof(char*).  But such machines will\n     * not likely have syscall implemented either, so who cares?\n     */\n\n    rb_secure(2);\n    if (argc == 0)\n\trb_raise(rb_eArgError, \"too few arguments for syscall\");\n    if (argc > sizeof(arg) / sizeof(arg[0]))\n\trb_raise(rb_eArgError, \"too many arguments for syscall\");\n    arg[0] = NUM2LONG(argv[0]); argv++;\n    while (items--) {\n\tVALUE v = rb_check_string_type(*argv);\n\n\tif (!NIL_P(v)) {\n\t    StringValue(v);\n\t    rb_str_modify(v);\n\t    arg[i] = (unsigned long)StringValueCStr(v);\n\t}\n\telse {\n\t    arg[i] = (unsigned long)NUM2LONG(*argv);\n\t}\n\targv++;\n\ti++;\n    }\n    TRAP_BEG;\n    switch (argc) {\n      case 1:\n\tretval = syscall(arg[0]);\n\tbreak;\n      case 2:\n\tretval = syscall(arg[0],arg[1]);\n\tbreak;\n      case 3:\n\tretval = syscall(arg[0],arg[1],arg[2]);\n\tbreak;\n      case 4:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3]);\n\tbreak;\n      case 5:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]);\n\tbreak;\n      case 6:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);\n\tbreak;\n      case 7:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);\n\tbreak;\n      case 8:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7]);\n\tbreak;\n#ifdef atarist\n      case 9:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7], arg[8]);\n\tbreak;\n      case 10:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7], arg[8], arg[9]);\n\tbreak;\n      case 11:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7], arg[8], arg[9], arg[10]);\n\tbreak;\n      case 12:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7], arg[8], arg[9], arg[10], arg[11]);\n\tbreak;\n      case 13:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]);\n\tbreak;\n      case 14:\n\tretval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],\n\t  arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13]);\n\tbreak;\n#endif /* atarist */\n    }\n    TRAP_END;\n    if (retval < 0) rb_sys_fail(0);\n    return INT2NUM(retval);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\nstatic VALUE io_new_instance _((VALUE));\nstatic VALUE\nio_new_instance(args)\n    VALUE args;\n{\n    return rb_class_new_instance(2, (VALUE*)args+1, *(VALUE*)args);\n}\n\n/*\n *  call-seq:\n *     IO.pipe -> array\n *  \n *  Creates a pair of pipe endpoints (connected to each other) and\n *  returns them as a two-element array of <code>IO</code> objects:\n *  <code>[</code> <i>read_file</i>, <i>write_file</i> <code>]</code>. Not\n *  available on all platforms.\n *     \n *  In the example below, the two processes close the ends of the pipe\n *  that they are not using. This is not just a cosmetic nicety. The\n *  read end of a pipe will not generate an end of file condition if\n *  there are any writers with the pipe still open. In the case of the\n *  parent process, the <code>rd.read</code> will never return if it\n *  does not first issue a <code>wr.close</code>.\n *     \n *     rd, wr = IO.pipe\n *     \n *     if fork\n *       wr.close\n *       puts \"Parent got: <#{rd.read}>\"\n *       rd.close\n *       Process.wait\n *     else\n *       rd.close\n *       puts \"Sending message to parent\"\n *       wr.write \"Hi Dad\"\n *       wr.close\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     Sending message to parent\n *     Parent got: <Hi Dad>\n */\n\nstatic VALUE\nrb_io_s_pipe(klass)\n    VALUE klass;\n{\n#ifndef __human68k__\n    int pipes[2], state;\n    VALUE r, w, args[3];\n\n#ifdef _WIN32\n    if (_pipe(pipes, 1024, O_BINARY) == -1)\n#else\n    if (pipe(pipes) == -1)\n#endif\n\trb_sys_fail(0);\n\n    args[0] = klass;\n    args[1] = INT2NUM(pipes[0]);\n    args[2] = INT2FIX(O_RDONLY);\n    r = rb_protect(io_new_instance, (VALUE)args, &state);\n    if (state) {\n\tclose(pipes[0]);\n\tclose(pipes[1]);\n\trb_jump_tag(state);\n    }\n    args[1] = INT2NUM(pipes[1]);\n    args[2] = INT2FIX(O_WRONLY);\n    w = rb_protect(io_new_instance, (VALUE)args, &state);\n    if (state) {\n\tclose(pipes[1]);\n\tif (!NIL_P(r)) rb_io_close(r);\n\trb_jump_tag(state);\n    }\n    rb_io_synchronized(RFILE(w)->fptr);\n\n    return rb_assoc_new(r, w);\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\nstruct foreach_arg {\n    int argc;\n    VALUE sep;\n    VALUE io;\n};\n\nstatic VALUE\nio_s_foreach(arg)\n    struct foreach_arg *arg;\n{\n    VALUE str;\n\n    while (!NIL_P(str = rb_io_getline(arg->sep, arg->io))) {\n\trb_yield(str);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     IO.foreach(name, sep_string=$/) {|line| block }   => nil\n *  \n *  Executes the block for every line in the named I/O port, where lines\n *  are separated by <em>sep_string</em>.\n *     \n *     IO.foreach(\"testfile\") {|x| print \"GOT \", x }\n *     \n *  <em>produces:</em>\n *     \n *     GOT This is line one\n *     GOT This is line two\n *     GOT This is line three\n *     GOT And so on...\n */     \n\nstatic VALUE\nrb_io_s_foreach(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE fname;\n    struct foreach_arg arg;\n\n    rb_scan_args(argc, argv, \"11\", &fname, &arg.sep);\n    RETURN_ENUMERATOR(self, argc, argv);\n    SafeStringValue(fname);\n\n    if (argc == 1) {\n\targ.sep = rb_default_rs;\n    }\n    else if (!NIL_P(arg.sep)) {\n\tStringValue(arg.sep);\n    }\n    arg.io = rb_io_open(StringValueCStr(fname), \"r\");\n    if (NIL_P(arg.io)) return Qnil;\n\n    return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);\n}\n\nstatic VALUE\nio_s_readlines(arg)\n    struct foreach_arg *arg;\n{\n    return rb_io_readlines(arg->argc, &arg->sep, arg->io);\n}\n\n/*\n *  call-seq:\n *     IO.readlines(name, sep_string=$/)   => array\n *  \n *  Reads the entire file specified by <i>name</i> as individual\n *  lines, and returns those lines in an array. Lines are separated by\n *  <i>sep_string</i>.\n *     \n *     a = IO.readlines(\"testfile\")\n *     a[0]   #=> \"This is line one\\n\"\n *     \n */\n\nstatic VALUE\nrb_io_s_readlines(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE fname;\n    struct foreach_arg arg;\n\n    rb_scan_args(argc, argv, \"11\", &fname, &arg.sep);\n    SafeStringValue(fname);\n\n    arg.argc = argc - 1;\n    arg.io = rb_io_open(StringValueCStr(fname), \"r\");\n    if (NIL_P(arg.io)) return Qnil;\n    return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io);\n}\n\nstatic VALUE\nio_s_read(arg)\n    struct foreach_arg *arg;\n{\n    return io_read(arg->argc, &arg->sep, arg->io);\n}\n\n/*\n *  call-seq:\n *     IO.read(name, [length [, offset]] )   => string\n *  \n *  Opens the file, optionally seeks to the given offset, then returns\n *  <i>length</i> bytes (defaulting to the rest of the file).\n *  <code>read</code> ensures the file is closed before returning.\n *     \n *     IO.read(\"testfile\")           #=> \"This is line one\\nThis is line two\\nThis is line three\\nAnd so on...\\n\"\n *     IO.read(\"testfile\", 20)       #=> \"This is line one\\nThi\"\n *     IO.read(\"testfile\", 20, 10)   #=> \"ne one\\nThis is line \"\n */\n\nstatic VALUE\nrb_io_s_read(argc, argv, io)\n    int argc;\n    VALUE *argv;\n    VALUE io;\n{\n    VALUE fname, offset;\n    struct foreach_arg arg;\n\n    rb_scan_args(argc, argv, \"12\", &fname, &arg.sep, &offset);\n    SafeStringValue(fname);\n\n    arg.argc = argc ? 1 : 0;\n    arg.io = rb_io_open(StringValueCStr(fname), \"r\");\n    if (NIL_P(arg.io)) return Qnil;\n    if (!NIL_P(offset)) {\n\trb_io_seek(arg.io, offset, SEEK_SET);\n    }\n    return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);\n}\n\nstatic VALUE\nargf_tell()\n{\n    if (!next_argv()) {\n\trb_raise(rb_eArgError, \"no stream to tell\");\n    }\n    ARGF_FORWARD(0, 0);\n    return rb_io_tell(current_file);\n}\n\nstatic VALUE\nargf_seek_m(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    if (!next_argv()) {\n\trb_raise(rb_eArgError, \"no stream to seek\");\n    }\n    ARGF_FORWARD(argc, argv);\n    return rb_io_seek_m(argc, argv, current_file);\n}\n\nstatic VALUE\nargf_set_pos(self, offset)\n     VALUE self, offset;\n{\n    if (!next_argv()) {\n\trb_raise(rb_eArgError, \"no stream to set position\");\n    }\n    ARGF_FORWARD(1, &offset);\n    return rb_io_set_pos(current_file, offset);\n}\n\nstatic VALUE\nargf_rewind()\n{\n    if (!next_argv()) {\n\trb_raise(rb_eArgError, \"no stream to rewind\");\n    }\n    ARGF_FORWARD(0, 0);\n    return rb_io_rewind(current_file);\n}\n\nstatic VALUE\nargf_fileno()\n{\n    if (!next_argv()) {\n\trb_raise(rb_eArgError, \"no stream\");\n    }\n    ARGF_FORWARD(0, 0);\n    return rb_io_fileno(current_file);\n}\n\nstatic VALUE\nargf_to_io()\n{\n    next_argv();\n    ARGF_FORWARD(0, 0);\n    return current_file;\n}\n\nstatic VALUE\nargf_eof()\n{\n    if (current_file) {\n\tif (init_p == 0) return Qtrue;\n\tnext_argv();\n\tARGF_FORWARD(0, 0);\n\tif (rb_io_eof(current_file)) {\n\t    return Qtrue;\n\t}\n    }\n    return Qfalse;\n}\n\nstatic VALUE\nargf_read(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE tmp, str, length;\n    long len = 0;\n\n    rb_scan_args(argc, argv, \"02\", &length, &str);\n    if (!NIL_P(length)) {\n\tlen = NUM2LONG(argv[0]);\n    }\n    if (!NIL_P(str)) {\n\tStringValue(str);\n\trb_str_resize(str,0);\n\targv[1] = Qnil;\n    }\n\n  retry:\n    if (!next_argv()) {\n\treturn str;\n    }\n    if (TYPE(current_file) != T_FILE) {\n\ttmp = argf_forward(argc, argv);\n    }\n    else {\n\ttmp = io_read(argc, argv, current_file);\n    }\n    if (NIL_P(str)) str = tmp;\n    else if (!NIL_P(tmp)) rb_str_append(str, tmp);\n    if (NIL_P(tmp) || NIL_P(length)) {\n\tif (next_p != -1) {\n\t    argf_close(current_file);\n\t    next_p = 1;\n\t    goto retry;\n\t}\n    }\n    else if (argc >= 1) {\n\tif (RSTRING(str)->len < len) {\n\t    len -= RSTRING(str)->len;\n\t    argv[0] = INT2NUM(len);\n\t    goto retry;\n\t}\n    }\n    return str;\n}\n\nstatic VALUE\nargf_getc()\n{\n    VALUE byte;\n\n  retry:\n    if (!next_argv()) return Qnil;\n    if (TYPE(current_file) != T_FILE) {\n\tbyte = rb_funcall3(current_file, rb_intern(\"getc\"), 0, 0);\n    }\n    else {\n\tbyte = rb_io_getc(current_file);\n    }\n    if (NIL_P(byte) && next_p != -1) {\n\targf_close(current_file);\n\tnext_p = 1;\n\tgoto retry;\n    }\n\n    return byte;\n}\n\nstatic VALUE\nargf_readchar()\n{\n    VALUE c;\n\n    NEXT_ARGF_FORWARD(0, 0);\n    c = argf_getc();\n    if (NIL_P(c)) {\n\trb_eof_error();\n    }\n    return c;\n}\n\nstatic VALUE\nargf_each_line(argc, argv, argf)\n    int argc;\n    VALUE *argv;\n    VALUE argf;\n{\n    VALUE str;\n\n    RETURN_ENUMERATOR(argf, argc, argv);\n    if (!next_argv()) return Qnil;\n    if (TYPE(current_file) != T_FILE) {\n\tfor (;;) {\n\t    if (!next_argv()) return argf;\n\t    rb_iterate(rb_each, current_file, rb_yield, 0);\n\t    next_p = 1;\n\t}\n    }\n    while (!NIL_P(str = argf_getline(argc, argv))) {\n\trb_yield(str);\n    }\n    return argf;\n}\n\nstatic VALUE\nargf_each_byte(argf)\n    VALUE argf;\n{\n    VALUE byte;\n\n    RETURN_ENUMERATOR(argf, 0, 0);\n    while (!NIL_P(byte = argf_getc())) {\n\trb_yield(byte);\n    }\n    return argf;\n}\n\nstatic VALUE\nargf_each_char(argf)\n    VALUE argf;\n{\n    VALUE ch;\n\n    RETURN_ENUMERATOR(argf, 0, 0);\n\n    while (!NIL_P(ch = argf_getc())) {\n\tunsigned char c;\n\tint n;\n\tVALUE str, file;\n\n      first_char:\n\tc = FIX2INT(ch);\n\tn = mbclen(c);\n\tstr = rb_tainted_str_new((const char *)&c, 1);\n\tfile = current_file;\n\n\twhile (--n > 0) {\n\t    if (NIL_P(ch = argf_getc())) {\n\t\trb_yield(str);\n\t\treturn argf;\n\t    }\n\t    if (current_file != file) {\n\t\trb_yield(str);\n\t\tgoto first_char;\n\t    }\n\t    c = FIX2INT(ch);\n\t    rb_str_cat(str, (const char *)&c, 1);\n\t}\n\trb_yield(str);\n    }\n    return argf;\n}\n\nstatic VALUE\nargf_filename()\n{\n    next_argv();\n    return filename;\n}\n\nstatic VALUE\nargf_file()\n{\n    next_argv();\n    return current_file;\n}\n\nstatic VALUE\nargf_binmode()\n{\n    binmode = 1;\n    next_argv();\n    ARGF_FORWARD(0, 0);\n    rb_io_binmode(current_file);\n    return argf;\n}\n\nstatic VALUE\nargf_skip()\n{\n    if (init_p && next_p == 0) {\n\targf_close(current_file);\n\tnext_p = 1;\n    }\n    return argf;\n}\n\nstatic VALUE\nargf_close_m()\n{\n    next_argv();\n    argf_close(current_file);\n    if (next_p != -1) {\n\tnext_p = 1;\n    }\n    gets_lineno = 0;\n    return argf;\n}\n\nstatic VALUE\nargf_closed()\n{\n    next_argv();\n    ARGF_FORWARD(0, 0);\n    return rb_io_closed(current_file);\n}\n\nstatic VALUE\nargf_to_s()\n{\n    return rb_str_new2(\"ARGF\");\n}\n\nstatic VALUE\nopt_i_get()\n{\n    if (!ruby_inplace_mode) return Qnil;\n    return rb_str_new2(ruby_inplace_mode);\n}\n\nstatic void\nopt_i_set(val)\n    VALUE val;\n{\n    if (!RTEST(val)) {\n\tif (ruby_inplace_mode) free(ruby_inplace_mode);\n\truby_inplace_mode = 0;\n\treturn;\n    }\n    StringValue(val);\n    if (ruby_inplace_mode) free(ruby_inplace_mode);\n    ruby_inplace_mode = 0;\n    ruby_inplace_mode = strdup(StringValueCStr(val));\n}\n\n/*\n *  Class <code>IO</code> is the basis for all input and output in Ruby.\n *  An I/O stream may be <em>duplexed</em> (that is, bidirectional), and\n *  so may use more than one native operating system stream.\n *     \n *  Many of the examples in this section use class <code>File</code>,\n *  the only standard subclass of <code>IO</code>. The two classes are\n *  closely associated.\n *     \n *  As used in this section, <em>portname</em> may take any of the\n *  following forms.\n *     \n *  * A plain string represents a filename suitable for the underlying\n *    operating system.\n *     \n *  * A string starting with ``<code>|</code>'' indicates a subprocess.\n *    The remainder of the string following the ``<code>|</code>'' is\n *    invoked as a process with appropriate input/output channels\n *    connected to it.\n *     \n *  * A string equal to ``<code>|-</code>'' will create another Ruby\n *    instance as a subprocess.\n *     \n *  Ruby will convert pathnames between different operating system\n *  conventions if possible. For instance, on a Windows system the\n *  filename ``<code>/gumby/ruby/test.rb</code>'' will be opened as\n *  ``<code>\\gumby\\ruby\\test.rb</code>''. When specifying a\n *  Windows-style filename in a Ruby string, remember to escape the\n *  backslashes:\n *     \n *     \"c:\\\\gumby\\\\ruby\\\\test.rb\"\n *     \n *  Our examples here will use the Unix-style forward slashes;\n *  <code>File::SEPARATOR</code> can be used to get the\n *  platform-specific separator character.\n *     \n *  I/O ports may be opened in any one of several different modes, which\n *  are shown in this section as <em>mode</em>. The mode may\n *  either be a Fixnum or a String. If numeric, it should be\n *  one of the operating system specific constants (O_RDONLY,\n *  O_WRONLY, O_RDWR, O_APPEND and so on). See man open(2) for\n *  more information.\n *\n *  If the mode is given as a String, it must be one of the\n *  values listed in the following table.\n *\n *    Mode |  Meaning\n *    -----+--------------------------------------------------------\n *    \"r\"  |  Read-only, starts at beginning of file  (default mode).\n *    -----+--------------------------------------------------------\n *    \"r+\" |  Read-write, starts at beginning of file.\n *    -----+--------------------------------------------------------\n *    \"w\"  |  Write-only, truncates existing file \n *         |  to zero length or creates a new file for writing.\n *    -----+--------------------------------------------------------\n *    \"w+\" |  Read-write, truncates existing file to zero length\n *         |  or creates a new file for reading and writing.\n *    -----+--------------------------------------------------------\n *    \"a\"  |  Write-only, starts at end of file if file exists,\n *         |  otherwise creates a new file for writing.\n *    -----+--------------------------------------------------------\n *    \"a+\" |  Read-write, starts at end of file if file exists,\n *         |  otherwise creates a new file for reading and \n *         |  writing.\n *    -----+--------------------------------------------------------\n *     \"b\" |  (DOS/Windows only) Binary file mode (may appear with \n *         |  any of the key letters listed above).\n *\n *\n *  The global constant ARGF (also accessible as $<) provides an\n *  IO-like stream which allows access to all files mentioned on the\n *  command line (or STDIN if no files are mentioned). ARGF provides\n *  the methods <code>#path</code> and <code>#filename</code> to access\n *  the name of the file currently being read.\n */\n\nvoid\nInit_IO()\n{\n#ifdef __CYGWIN__ \n#include <sys/cygwin.h>\n    static struct __cygwin_perfile pf[] =\n    {\n\t{\"\", O_RDONLY | O_BINARY},\n\t{\"\", O_WRONLY | O_BINARY},\n\t{\"\", O_RDWR | O_BINARY},\n\t{\"\", O_APPEND | O_BINARY},\n\t{NULL, 0}\n    };\n    cygwin_internal(CW_PERFILE, pf);\n#endif\n\n    rb_eIOError = rb_define_class(\"IOError\", rb_eStandardError);\n    rb_eEOFError = rb_define_class(\"EOFError\", rb_eIOError);\n\n    id_write = rb_intern(\"write\");\n    id_read = rb_intern(\"read\");\n    id_getc = rb_intern(\"getc\");\n\n    rb_define_global_function(\"syscall\", rb_f_syscall, -1);\n\n    rb_define_global_function(\"open\", rb_f_open, -1);\n    rb_define_global_function(\"printf\", rb_f_printf, -1);\n    rb_define_global_function(\"print\", rb_f_print, -1);\n    rb_define_global_function(\"putc\", rb_f_putc, 1);\n    rb_define_global_function(\"puts\", rb_f_puts, -1);\n    rb_define_global_function(\"gets\", rb_f_gets, -1);\n    rb_define_global_function(\"readline\", rb_f_readline, -1);\n    rb_define_global_function(\"getc\", rb_f_getc, 0);\n    rb_define_global_function(\"select\", rb_f_select, -1);\n\n    rb_define_global_function(\"readlines\", rb_f_readlines, -1);\n\n    rb_define_global_function(\"`\", rb_f_backquote, 1);\n\n    rb_define_global_function(\"p\", rb_f_p, -1);\n    rb_define_method(rb_mKernel, \"display\", rb_obj_display, -1);\n\n    rb_cIO = rb_define_class(\"IO\", rb_cObject);\n    rb_include_module(rb_cIO, rb_mEnumerable);\n\n    rb_define_alloc_func(rb_cIO, io_alloc);\n    rb_define_singleton_method(rb_cIO, \"new\", rb_io_s_new, -1);\n    rb_define_singleton_method(rb_cIO, \"open\",  rb_io_s_open, -1);\n    rb_define_singleton_method(rb_cIO, \"sysopen\",  rb_io_s_sysopen, -1);\n    rb_define_singleton_method(rb_cIO, \"for_fd\", rb_io_s_for_fd, -1);\n    rb_define_singleton_method(rb_cIO, \"popen\", rb_io_s_popen, -1);\n    rb_define_singleton_method(rb_cIO, \"foreach\", rb_io_s_foreach, -1);\n    rb_define_singleton_method(rb_cIO, \"readlines\", rb_io_s_readlines, -1);\n    rb_define_singleton_method(rb_cIO, \"read\", rb_io_s_read, -1);\n    rb_define_singleton_method(rb_cIO, \"select\", rb_f_select, -1);\n    rb_define_singleton_method(rb_cIO, \"pipe\", rb_io_s_pipe, 0);\n\n    rb_define_method(rb_cIO, \"initialize\", rb_io_initialize, -1);\n\n    rb_output_fs = Qnil;\n    rb_define_hooked_variable(\"$,\", &rb_output_fs, 0, rb_str_setter);\n\n    rb_global_variable(&rb_default_rs);\n    rb_rs = rb_default_rs = rb_str_new2(\"\\n\");\n    rb_output_rs = Qnil;\n    OBJ_FREEZE(rb_default_rs);\t/* avoid modifying RS_default */\n    rb_define_hooked_variable(\"$/\", &rb_rs, 0, rb_str_setter);\n    rb_define_hooked_variable(\"$-0\", &rb_rs, 0, rb_str_setter);\n    rb_define_hooked_variable(\"$\\\\\", &rb_output_rs, 0, rb_str_setter);\n\n    rb_define_hooked_variable(\"$.\", &lineno, 0, lineno_setter);\n    rb_define_virtual_variable(\"$_\", rb_lastline_get, rb_lastline_set);\n\n    rb_define_method(rb_cIO, \"initialize_copy\", rb_io_init_copy, 1);\n    rb_define_method(rb_cIO, \"reopen\", rb_io_reopen, -1);\n\n    rb_define_method(rb_cIO, \"print\", rb_io_print, -1);\n    rb_define_method(rb_cIO, \"putc\", rb_io_putc, 1);\n    rb_define_method(rb_cIO, \"puts\", rb_io_puts, -1);\n    rb_define_method(rb_cIO, \"printf\", rb_io_printf, -1);\n\n    rb_define_method(rb_cIO, \"each\",  rb_io_each_line, -1);\n    rb_define_method(rb_cIO, \"each_line\",  rb_io_each_line, -1);\n    rb_define_method(rb_cIO, \"each_byte\",  rb_io_each_byte, 0);\n    rb_define_method(rb_cIO, \"each_char\",  rb_io_each_char, 0);\n    rb_define_method(rb_cIO, \"lines\",  rb_io_lines, -1);\n    rb_define_method(rb_cIO, \"bytes\",  rb_io_bytes, 0);\n    rb_define_method(rb_cIO, \"chars\",  rb_io_each_char, 0);\n\n    rb_define_method(rb_cIO, \"syswrite\", rb_io_syswrite, 1);\n    rb_define_method(rb_cIO, \"sysread\",  rb_io_sysread, -1);\n\n    rb_define_method(rb_cIO, \"fileno\", rb_io_fileno, 0);\n    rb_define_alias(rb_cIO, \"to_i\", \"fileno\");\n    rb_define_method(rb_cIO, \"to_io\", rb_io_to_io, 0);\n\n    rb_define_method(rb_cIO, \"fsync\",   rb_io_fsync, 0);\n    rb_define_method(rb_cIO, \"sync\",   rb_io_sync, 0);\n    rb_define_method(rb_cIO, \"sync=\",  rb_io_set_sync, 1);\n\n    rb_define_method(rb_cIO, \"lineno\",   rb_io_lineno, 0);\n    rb_define_method(rb_cIO, \"lineno=\",  rb_io_set_lineno, 1);\n\n    rb_define_method(rb_cIO, \"readlines\",  rb_io_readlines, -1);\n\n    rb_define_method(rb_cIO, \"read_nonblock\",  io_read_nonblock, -1);\n    rb_define_method(rb_cIO, \"write_nonblock\", rb_io_write_nonblock, 1);\n    rb_define_method(rb_cIO, \"readpartial\",  io_readpartial, -1);\n    rb_define_method(rb_cIO, \"read\",  io_read, -1);\n    rb_define_method(rb_cIO, \"write\", io_write, 1);\n    rb_define_method(rb_cIO, \"gets\",  rb_io_gets_m, -1);\n    rb_define_method(rb_cIO, \"readline\",  rb_io_readline, -1);\n    rb_define_method(rb_cIO, \"getc\",  rb_io_getc, 0);\n    rb_define_method(rb_cIO, \"getbyte\",  rb_io_getc, 0);\n    rb_define_method(rb_cIO, \"readchar\",  rb_io_readchar, 0);\n    rb_define_method(rb_cIO, \"readbyte\",  rb_io_readchar, 0);\n    rb_define_method(rb_cIO, \"ungetc\",rb_io_ungetc, 1);\n    rb_define_method(rb_cIO, \"<<\",    rb_io_addstr, 1);\n    rb_define_method(rb_cIO, \"flush\", rb_io_flush, 0);\n    rb_define_method(rb_cIO, \"tell\", rb_io_tell, 0);\n    rb_define_method(rb_cIO, \"seek\", rb_io_seek_m, -1);\n    rb_define_const(rb_cIO, \"SEEK_SET\", INT2FIX(SEEK_SET));\n    rb_define_const(rb_cIO, \"SEEK_CUR\", INT2FIX(SEEK_CUR));\n    rb_define_const(rb_cIO, \"SEEK_END\", INT2FIX(SEEK_END));\n    rb_define_method(rb_cIO, \"rewind\", rb_io_rewind, 0);\n    rb_define_method(rb_cIO, \"pos\", rb_io_tell, 0);\n    rb_define_method(rb_cIO, \"pos=\", rb_io_set_pos, 1);\n    rb_define_method(rb_cIO, \"eof\", rb_io_eof, 0);\n    rb_define_method(rb_cIO, \"eof?\", rb_io_eof, 0);\n\n    rb_define_method(rb_cIO, \"close\", rb_io_close_m, 0);\n    rb_define_method(rb_cIO, \"closed?\", rb_io_closed, 0);\n    rb_define_method(rb_cIO, \"close_read\", rb_io_close_read, 0);\n    rb_define_method(rb_cIO, \"close_write\", rb_io_close_write, 0);\n\n    rb_define_method(rb_cIO, \"isatty\", rb_io_isatty, 0);\n    rb_define_method(rb_cIO, \"tty?\", rb_io_isatty, 0);\n    rb_define_method(rb_cIO, \"binmode\",  rb_io_binmode, 0);\n    rb_define_method(rb_cIO, \"sysseek\", rb_io_sysseek, -1);\n\n    rb_define_method(rb_cIO, \"ioctl\", rb_io_ioctl, -1);\n    rb_define_method(rb_cIO, \"fcntl\", rb_io_fcntl, -1);\n    rb_define_method(rb_cIO, \"pid\", rb_io_pid, 0);\n    rb_define_method(rb_cIO, \"inspect\",  rb_io_inspect, 0);\n\n    rb_define_variable(\"$stdin\", &rb_stdin);\n    rb_stdin = prep_stdio(stdin, FMODE_READABLE, rb_cIO);\n    rb_define_hooked_variable(\"$stdout\", &rb_stdout, 0, stdout_setter);\n    rb_stdout = prep_stdio(stdout, FMODE_WRITABLE, rb_cIO);\n    rb_define_hooked_variable(\"$stderr\", &rb_stderr, 0, stdout_setter);\n    rb_stderr = prep_stdio(stderr, FMODE_WRITABLE, rb_cIO);\n    rb_define_hooked_variable(\"$>\", &rb_stdout, 0, stdout_setter);\n    orig_stdout = rb_stdout;\n    rb_deferr = orig_stderr = rb_stderr;\n\n    /* variables to be removed in 1.8.1 */\n    rb_define_hooked_variable(\"$defout\", &rb_stdout, 0, defout_setter);\n    rb_define_hooked_variable(\"$deferr\", &rb_stderr, 0, deferr_setter);\n\n    /* constants to hold original stdin/stdout/stderr */\n    rb_define_global_const(\"STDIN\", rb_stdin);\n    rb_define_global_const(\"STDOUT\", rb_stdout);\n    rb_define_global_const(\"STDERR\", rb_stderr);\n\n    rb_define_readonly_variable(\"$<\", &argf);\n    argf = rb_obj_alloc(rb_cObject);\n    rb_extend_object(argf, rb_mEnumerable);\n    rb_define_global_const(\"ARGF\", argf);\n\n    rb_define_singleton_method(argf, \"to_s\", argf_to_s, 0);\n\n    rb_define_singleton_method(argf, \"fileno\", argf_fileno, 0);\n    rb_define_singleton_method(argf, \"to_i\", argf_fileno, 0);\n    rb_define_singleton_method(argf, \"to_io\", argf_to_io, 0);\n    rb_define_singleton_method(argf, \"each\",  argf_each_line, -1);\n    rb_define_singleton_method(argf, \"each_line\",  argf_each_line, -1);\n    rb_define_singleton_method(argf, \"each_byte\",  argf_each_byte, 0);\n    rb_define_singleton_method(argf, \"each_char\",  argf_each_char, 0);\n    rb_define_singleton_method(argf, \"lines\",  argf_each_line, -1);\n    rb_define_singleton_method(argf, \"bytes\",  argf_each_byte, 0);\n    rb_define_singleton_method(argf, \"chars\",  argf_each_char, 0);\n\n    rb_define_singleton_method(argf, \"read\",  argf_read, -1);\n    rb_define_singleton_method(argf, \"readlines\", rb_f_readlines, -1);\n    rb_define_singleton_method(argf, \"to_a\", rb_f_readlines, -1);\n    rb_define_singleton_method(argf, \"gets\", rb_f_gets, -1);\n    rb_define_singleton_method(argf, \"readline\", rb_f_readline, -1);\n    rb_define_singleton_method(argf, \"getc\", argf_getc, 0);\n    rb_define_singleton_method(argf, \"getbyte\", argf_getc, 0);\n    rb_define_singleton_method(argf, \"readchar\", argf_readchar, 0);\n    rb_define_singleton_method(argf, \"readbyte\", argf_readchar, 0);\n    rb_define_singleton_method(argf, \"tell\", argf_tell, 0);\n    rb_define_singleton_method(argf, \"seek\", argf_seek_m, -1);\n    rb_define_singleton_method(argf, \"rewind\", argf_rewind, 0);\n    rb_define_singleton_method(argf, \"pos\", argf_tell, 0);\n    rb_define_singleton_method(argf, \"pos=\", argf_set_pos, 1);\n    rb_define_singleton_method(argf, \"eof\", argf_eof, 0);\n    rb_define_singleton_method(argf, \"eof?\", argf_eof, 0);\n    rb_define_singleton_method(argf, \"binmode\", argf_binmode, 0);\n\n    rb_define_singleton_method(argf, \"filename\", argf_filename, 0);\n    rb_define_singleton_method(argf, \"path\", argf_filename, 0);\n    rb_define_singleton_method(argf, \"file\", argf_file, 0);\n    rb_define_singleton_method(argf, \"skip\", argf_skip, 0);\n    rb_define_singleton_method(argf, \"close\", argf_close_m, 0);\n    rb_define_singleton_method(argf, \"closed?\", argf_closed, 0);\n\n    rb_define_singleton_method(argf, \"lineno\",   argf_lineno, 0);\n    rb_define_singleton_method(argf, \"lineno=\",  argf_set_lineno, 1);\n\n    rb_global_variable(&current_file);\n    rb_define_readonly_variable(\"$FILENAME\", &filename);\n    filename = rb_str_new2(\"-\");\n\n    rb_define_virtual_variable(\"$-i\", opt_i_get, opt_i_set);\n\n#if defined (_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__)\n    atexit(pipe_atexit);\n#endif\n\n    Init_File();\n\n    rb_define_method(rb_cFile, \"initialize\",  rb_file_initialize, -1);\n\n    rb_file_const(\"RDONLY\", INT2FIX(O_RDONLY));\n    rb_file_const(\"WRONLY\", INT2FIX(O_WRONLY));\n    rb_file_const(\"RDWR\", INT2FIX(O_RDWR));\n    rb_file_const(\"APPEND\", INT2FIX(O_APPEND));\n    rb_file_const(\"CREAT\", INT2FIX(O_CREAT));\n    rb_file_const(\"EXCL\", INT2FIX(O_EXCL));\n#if defined(O_NDELAY) || defined(O_NONBLOCK)\n#   ifdef O_NONBLOCK\n    rb_file_const(\"NONBLOCK\", INT2FIX(O_NONBLOCK));\n#   else\n    rb_file_const(\"NONBLOCK\", INT2FIX(O_NDELAY));\n#   endif\n#endif\n    rb_file_const(\"TRUNC\", INT2FIX(O_TRUNC));\n#ifdef O_NOCTTY\n    rb_file_const(\"NOCTTY\", INT2FIX(O_NOCTTY));\n#endif\n#ifdef O_BINARY\n    rb_file_const(\"BINARY\", INT2FIX(O_BINARY));\n#endif\n#ifdef O_SYNC\n    rb_file_const(\"SYNC\", INT2FIX(O_SYNC));\n#endif\n}\n"
  },
  {
    "path": "keywords",
    "content": "struct kwtable {const char *name; int id[2]; enum lex_state state;};\n%%\n__LINE__, {k__LINE__, k__LINE__}, EXPR_END\n__FILE__, {k__FILE__, k__FILE__}, EXPR_END\nBEGIN, {klBEGIN, klBEGIN}, EXPR_END\nEND, {klEND, klEND}, EXPR_END\nalias, {kALIAS, kALIAS}, EXPR_FNAME\nand, {kAND, kAND}, EXPR_BEG\nbegin, {kBEGIN, kBEGIN}, EXPR_BEG\nbreak, {kBREAK, kBREAK}, EXPR_MID\ncase, {kCASE, kCASE}, EXPR_BEG\nclass, {kCLASS, kCLASS}, EXPR_CLASS\ndef, {kDEF, kDEF}, EXPR_FNAME\ndefined?, {kDEFINED, kDEFINED}, EXPR_ARG\ndo, {kDO, kDO}, EXPR_BEG\nelse, {kELSE, kELSE}, EXPR_BEG\nelsif, {kELSIF, kELSIF}, EXPR_BEG\nend, {kEND, kEND}, EXPR_END\nensure, {kENSURE, kENSURE}, EXPR_BEG\nfalse, {kFALSE, kFALSE}, EXPR_END\nfor, {kFOR, kFOR}, EXPR_BEG\nif, {kIF, kIF_MOD}, EXPR_BEG\nin, {kIN, kIN}, EXPR_BEG\nmodule, {kMODULE, kMODULE}, EXPR_BEG\nnext, {kNEXT, kNEXT}, EXPR_MID\nnil, {kNIL, kNIL}, EXPR_END\nnot, {kNOT, kNOT}, EXPR_BEG\nor, {kOR, kOR}, EXPR_BEG\nredo, {kREDO, kREDO}, EXPR_END\nrescue, {kRESCUE, kRESCUE_MOD}, EXPR_MID\nretry, {kRETRY, kRETRY}, EXPR_END\nreturn, {kRETURN, kRETURN}, EXPR_MID\nself, {kSELF, kSELF}, EXPR_END\nsuper, {kSUPER, kSUPER}, EXPR_ARG\nthen, {kTHEN, kTHEN}, EXPR_BEG\ntrue, {kTRUE, kTRUE}, EXPR_END\nundef, {kUNDEF, kUNDEF}, EXPR_FNAME\nunless, {kUNLESS, kUNLESS_MOD}, EXPR_BEG\nuntil, {kUNTIL, kUNTIL_MOD}, EXPR_BEG\nwhen, {kWHEN, kWHEN}, EXPR_BEG\nwhile, {kWHILE, kWHILE_MOD}, EXPR_BEG\nyield, {kYIELD, kYIELD}, EXPR_ARG\n"
  },
  {
    "path": "kiji-todo",
    "content": "TODO:\n- fix build chain to properly include system_allocator\n- see if removing taint improves performance\n- investigate other types to go on the longlife\n\nDONE:\n- change marktable incremental clear to just dump the table\n- fix mutating strings remembered set corruption\n- correct allocation points for objects during parse\n- put any frozen string on the longlife\n- use st_foreach_map for copy-compacter\n- correct source file for C func\n- indicate the C files as (native)\n- refactor the two source position functions into one\n- macro for rb_newobj\n- attempt to remove NODE_NEWLINE (doesn't work)\n"
  },
  {
    "path": "lib/.document",
    "content": "# We only run RDoc on the top-level files in here: we skip\n# all the helper stuff in sub-directories\n\n# Eventually, we hope to see...\n# *.rb\n\n# But for now\n\nEnglish.rb\nEnv.rb\nREADME\nabbrev.rb\nbase64.rb\nbenchmark.rb\ncgi\ncgi.rb\ncgi-lib.rb\ncomplex.rb\ncsv.rb\ndate\ndate.rb\ndate2.rb\ndebug.rb\ndelegate.rb\ndrb\ndrb.rb\ne2mmap.rb\nerb.rb\neregex.rb\nfileutils.rb\nfinalize.rb\nfind.rb\nforwardable.rb\nftools.rb\ngenerator.rb\ngetoptlong.rb\ngetopts.rb\ngserver.rb\nimportenv.rb\nipaddr.rb\nirb\nirb.rb\njcode.rb\nlogger.rb\nmailread.rb\nmathn.rb\nmatrix.rb\nmkmf.rb\nmonitor.rb\nmutex_m.rb\nnet\nobserver.rb\nopen-uri.rb\nopen3.rb\noptparse\noptparse.rb\nostruct.rb\nparsearg.rb\nparsedate.rb\npathname.rb\nping.rb\npp.rb\nprettyprint.rb\nprofile.rb\nprofiler.rb\npstore.rb\nracc\nrational.rb\nrdoc\nreadbytes.rb\nresolv-replace.rb\nresolv.rb\nrexml\nrinda\nrss\nrss.rb\nrubyunit.rb\nrunit\nscanf.rb\nset.rb\nshell\nshell.rb\nshellwords.rb\nsingleton.rb\nsoap\nsync.rb\ntempfile.rb\ntest\nthread.rb\nthwait.rb\ntime.rb\ntimeout.rb\ntmpdir.rb\ntracer.rb\ntsort.rb\nun.rb\nuri\nuri.rb\nweakref.rb\nwebrick\nwebrick.rb\nwsdl\nxmlrpc\nxsd\nyaml\nyaml.rb\n"
  },
  {
    "path": "lib/English.rb",
    "content": "#  Include the English library file in a Ruby script, and you can\n#  reference the global variables such as \\VAR{\\$\\_} using less\n#  cryptic names, listed in the following table.% \\vref{tab:english}.\n#\n#  Without 'English':\n#\n#      $\\ = ' -- '\n#      \"waterbuffalo\" =~ /buff/\n#      print $\", $', $$, \"\\n\"\n#\n#  With English:\n#\n#      require \"English\"\n#      \n#      $OUTPUT_FIELD_SEPARATOR = ' -- '\n#      \"waterbuffalo\" =~ /buff/\n#      print $LOADED_FEATURES, $POSTMATCH, $PID, \"\\n\"\n\n\n# The exception object passed to +raise+.\nalias $ERROR_INFO              $!\n\n# The stack backtrace generated by the last\n# exception. <tt>See Kernel.caller</tt> for details. Thread local.\nalias $ERROR_POSITION          $@\n\n# The default separator pattern used by <tt>String.split</tt>.  May be\n# set from the command line using the <tt>-F</tt> flag.\nalias $FS                      $;\n\n# The default separator pattern used by <tt>String.split</tt>.  May be\n# set from the command line using the <tt>-F</tt> flag.\nalias $FIELD_SEPARATOR         $;\n\n# The separator string output between the parameters to methods such\n# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,\n# which adds no text.\nalias $OFS                     $,\n\n# The separator string output between the parameters to methods such\n# as <tt>Kernel.print</tt> and <tt>Array.join</tt>. Defaults to +nil+,\n# which adds no text.\nalias $OUTPUT_FIELD_SEPARATOR  $,\n\n# The input record separator (newline by default). This is the value\n# that routines such as <tt>Kernel.gets</tt> use to determine record\n# boundaries. If set to +nil+, +gets+ will read the entire file.\nalias $RS                      $/\n\n# The input record separator (newline by default). This is the value\n# that routines such as <tt>Kernel.gets</tt> use to determine record\n# boundaries. If set to +nil+, +gets+ will read the entire file.\nalias $INPUT_RECORD_SEPARATOR  $/\n\n# The string appended to the output of every call to methods such as\n# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is\n# +nil+.\nalias $ORS                     $\\\n\n# The string appended to the output of every call to methods such as\n# <tt>Kernel.print</tt> and <tt>IO.write</tt>. The default value is\n# +nil+.\nalias $OUTPUT_RECORD_SEPARATOR $\\\n\n# The number of the last line read from the current input file.\nalias $INPUT_LINE_NUMBER       $.\n\n# The number of the last line read from the current input file.\nalias $NR                      $.\n\n# The last line read by <tt>Kernel.gets</tt> or\n# <tt>Kernel.readline</tt>. Many string-related functions in the\n# +Kernel+ module operate on <tt>$_</tt> by default. The variable is\n# local to the current scope. Thread local.\nalias $LAST_READ_LINE          $_\n\n# The destination of output for <tt>Kernel.print</tt>\n# and <tt>Kernel.printf</tt>. The default value is\n# <tt>$stdout</tt>.\nalias $DEFAULT_OUTPUT          $>\n\n# An object that provides access to the concatenation\n# of the contents of all the files\n# given as command-line arguments, or <tt>$stdin</tt>\n# (in the case where there are no\n# arguments). <tt>$<</tt> supports methods similar to a \n# +File+ object:\n# +inmode+, +close+,\n# <tt>closed?</tt>, +each+,\n# <tt>each_byte</tt>, <tt>each_line</tt>,\n# +eof+, <tt>eof?</tt>, +file+,\n# +filename+, +fileno+,\n# +getc+, +gets+, +lineno+,\n# <tt>lineno=</tt>, +path+, \n# +pos+, <tt>pos=</tt>,\n# +read+, +readchar+,\n# +readline+, +readlines+,\n# +rewind+, +seek+, +skip+,\n# +tell+, <tt>to_a</tt>, <tt>to_i</tt>,\n# <tt>to_io</tt>, <tt>to_s</tt>, along with the\n# methods in +Enumerable+. The method +file+\n# returns a +File+ object for the file currently\n# being read. This may change as <tt>$<</tt> reads\n# through the files on the command line. Read only.\nalias $DEFAULT_INPUT           $<\n\n# The process number of the program being executed. Read only.\nalias $PID                     $$\n\n# The process number of the program being executed. Read only.\nalias $PROCESS_ID              $$\n\n# The exit status of the last child process to terminate. Read\n# only. Thread local.\nalias $CHILD_STATUS            $?\n\n# A +MatchData+ object that encapsulates the results of a successful\n# pattern match. The variables <tt>$&</tt>, <tt>$`</tt>, <tt>$'</tt>,\n# and <tt>$1</tt> to <tt>$9</tt> are all derived from\n# <tt>$~</tt>. Assigning to <tt>$~</tt> changes the values of these\n# derived variables.  This variable is local to the current\n# scope. Thread local.\nalias $LAST_MATCH_INFO         $~\n\n# If set to any value apart from +nil+ or +false+, all pattern matches\n# will be case insensitive, string comparisons will ignore case, and\n# string hash values will be case insensitive. Deprecated\nalias $IGNORECASE              $=\n\n# An array of strings containing the command-line\n# options from the invocation of the program. Options\n# used by the Ruby interpreter will have been\n# removed. Read only. Also known simply as +ARGV+.\nalias $ARGV                    $*\n\n# The string matched by the last successful pattern\n# match. This variable is local to the current\n# scope. Read only. Thread local.\nalias $MATCH                   $&\n\n# The string preceding the match in the last\n# successful pattern match. This variable is local to \n# the current scope. Read only. Thread local.\nalias $PREMATCH                $`\n\n# The string following the match in the last\n# successful pattern match. This variable is local to \n# the current scope. Read only. Thread local.\nalias $POSTMATCH               $'\n\n# The contents of the highest-numbered group matched in the last\n# successful pattern match. Thus, in <tt>\"cat\" =~ /(c|a)(t|z)/</tt>,\n# <tt>$+</tt> will be set to \"t\".  This variable is local to the\n# current scope. Read only. Thread local.\nalias $LAST_PAREN_MATCH        $+\n"
  },
  {
    "path": "lib/Env.rb",
    "content": "# Env.rb -- imports environment variables as global variables, Perlish ;(\n# Usage:\n#\n#  require 'Env'\n#  p $USER\n#  $USER = \"matz\"\n#  p ENV[\"USER\"]\n\nrequire 'importenv'\n\nif __FILE__ == $0\n  p $TERM\n  $TERM = nil\n  p $TERM\n  p ENV[\"TERM\"]\n  $TERM = \"foo\"\n  p ENV[\"TERM\"]\nend\n"
  },
  {
    "path": "lib/README",
    "content": "English.rb\tlets Perl'ish global variables have English names\nEnv.rb\t\tloads importenv.rb\nREADME\t\tthis file\nbase64.rb\tencodes/decodes base64 (obsolete)\nbenchmark.rb\ta benchmark utility\ncgi-lib.rb\tsimple CGI support library (old style)\ncgi.rb\t\tCGI support library\ncgi/session.rb\tCGI session class\ncomplex.rb\tcomplex number support\ncsv.rb\t\tCSV parser/generator\ndate.rb\t\tdate object\ndate/format.rb\tdate parsing and formatting\ndate2.rb\tdate object (obsolete; use date)\ndebug.rb\truby debugger\ndelegate.rb\tdelegates messages to other object\ndrb.rb\t\tdistributed Ruby\ne2mmap.rb\texception utilities\nerb.rb\t\ttiny eRuby library\neregex.rb\textended regular expression (just a proof of concept)\nfileutils.rb\tfile utilities\nfinalize.rb\tadds finalizer to the object\nfind.rb\t\ttraverses directory tree\nforwardable.rb\texplicit delegation library\nftools.rb\tfile tools\ngetoptlong.rb\tGNU getoptlong compatible\ngetopts.rb\tparses command line options (use getoptlong)\ngserver.rb\tgeneral TCP server\nimportenv.rb\timports environment variables as global variables\nipaddr.rb\tdefines the IPAddr class\nirb.rb\t\tinteractive ruby\njcode.rb\tJapanese text handling (replace String methods)\nlogger.rb\tsimple logging utility\nmailread.rb\treads mail headers\nmathn.rb\textended math operation\nmatrix.rb\tmatrix calculation library\nmkmf.rb\t\tMakefile maker\nmonitor.rb\texclusive region monitor for thread\nmutex_m.rb\tmutex mixin\nnet/ftp.rb\tftp access\nnet/http.rb\tHTTP access\nnet/imap.rb\tIMAP4 access\nnet/pop.rb\tPOP3 access\nnet/protocol.rb\tabstract class for net library (DO NOT USE)\nnet/smtp.rb\tSMTP access\nnet/telnet.rb\ttelnet library\nobserver.rb\tobserver desing pattern library (provides Observable)\nopen-uri.rb\teasy-to-use network interface using URI and Net\nopen3.rb\topens subprocess connection stdin/stdout/stderr\noptparse.rb\tcommand line option analysis\nostruct.rb\tpython style object\nparsearg.rb\targument parser using getopts\nparsedate.rb\tparses date string (obsolete)\npathname.rb\tObject-Oriented Pathname Class\nping.rb\t\tchecks whether host is up, using TCP echo.\npp.rb\t\tpretty print objects\nprettyprint.rb\tpretty printing algorithm\nprofile.rb\truns ruby profiler\nprofiler.rb\truby profiler module\npstore.rb\tpersistent object strage using marshal\nracc/parser.rb\tracc (Ruby yACC) runtime\nrational.rb\trational number support\nrdoc\tsource-code documentation tool\nreadbytes.rb\tdefine IO#readbytes\nresolv-replace.rb\treplace Socket DNS by resolve.rb\nresolv.rb\tDNS resolver in Ruby\nrexml\t\tan XML parser for Ruby, in Ruby\nrubyunit.rb\toriginal Ruby Unit testing framework\nscanf.rb\tscanf for Ruby\nset.rb\t\tdefines the Set class\nshell.rb\truns commands and does pipeline operations like shell\nshellwords.rb\tsplit into words like shell\nsingleton.rb\tsingleton design pattern library\nsoap\t\tSOAP 1.1 implementation\nsync.rb\t\t2 phase lock\ntempfile.rb\ttemporary file with automatic removal\ntest/unit\tRuby Unit Testing Framework\nthread.rb\tthread support\nthwait.rb\tthread syncronization class\ntime.rb\t\tRFC2822, RFC2616, ISO8601 style time formatting/parsing\ntimeout.rb\tprovides timeout\ntmpdir.rb\tretrieve temporary directory path\ntracer.rb\texecution tracer\ntsort.rb\ttopological sorting\nun.rb\t\tUtilities to replace common UNIX commands in Makefiles etc\nuri.rb\t\tURI support\nuri/ftp.rb\tftp scheme support\nuri/http.rb\thttp scheme support\nuri/https.rb\thttps scheme support\nuri/ldap.rb\tldap scheme support\nuri/mailto.rb\tmailto scheme support\nweakref.rb\tweak reference class\nwebrick.rb\tWEB server toolkit\nwsdl\t\tWSDL 1.1 implementation\nxmlrpc\t\tXML-RPC implementation\nxsd\t\tXML Schema Datatypes implementation\nyaml.rb\t\tYAML implementation\n"
  },
  {
    "path": "lib/abbrev.rb",
    "content": "#!/usr/bin/env ruby\n=begin\n#\n# Copyright (c) 2001,2003 Akinori MUSHA <knu@iDaemons.org>\n#\n# All rights reserved.  You can redistribute and/or modify it under\n# the same terms as Ruby.\n#\n# $Idaemons: /home/cvs/rb/abbrev.rb,v 1.2 2001/05/30 09:37:45 knu Exp $\n# $RoughId: abbrev.rb,v 1.4 2003/10/14 19:45:42 knu Exp $\n# $Id$\n=end\n\n# Calculate the set of unique abbreviations for a given set of strings.\n#\n#   require 'abbrev'\n#   require 'pp'\n#\n#   pp Abbrev::abbrev(['ruby', 'rules']).sort\n#\n# <i>Generates:</i>\n#\n#   [[\"rub\", \"ruby\"],\n#    [\"ruby\", \"ruby\"],\n#    [\"rul\", \"rules\"],\n#    [\"rule\", \"rules\"],\n#    [\"rules\", \"rules\"]]\n#\n# Also adds an +abbrev+ method to class +Array+.\n\nmodule Abbrev\n\n  # Given a set of strings, calculate the set of unambiguous\n  # abbreviations for those strings, and return a hash where the keys\n  # are all the possible abbreviations and the values are the full\n  # strings. Thus, given input of \"car\" and \"cone\", the keys pointing\n  # to \"car\" would be \"ca\" and \"car\", while those pointing to \"cone\"\n  # would be \"co\", \"con\", and \"cone\".\n  #\n  # The optional +pattern+ parameter is a pattern or a string. Only\n  # those input strings matching the pattern, or begging the string,\n  # are considered for inclusion in the output hash\n\n  def abbrev(words, pattern = nil)\n    table = {}\n    seen = Hash.new(0)\n\n    if pattern.is_a?(String)\n      pattern = /^#{Regexp.quote(pattern)}/\t# regard as a prefix\n    end\n\n    words.each do |word|\n      next if (abbrev = word).empty?\n      while (len = abbrev.rindex(/[\\w\\W]\\z/)) > 0\n\tabbrev = word[0,len]\n\n\tnext if pattern && pattern !~ abbrev\n\n\tcase seen[abbrev] += 1\n\twhen 1\n\t  table[abbrev] = word\n\twhen 2\n\t  table.delete(abbrev)\n\telse\n\t  break\n\tend\n      end\n    end\n\n    words.each do |word|\n      next if pattern && pattern !~ word\n\n      table[word] = word\n    end\n\n    table\n  end\n\n  module_function :abbrev\nend\n\nclass Array\n  # Calculates the set of unambiguous abbreviations for the strings in\n  # +self+. If passed a pattern or a string, only the strings matching\n  # the pattern or starting with the string are considered.\n  #\n  #   %w{ car cone }.abbrev   #=> { \"ca\" => \"car\", \"car\" => \"car\",\n  #                                 \"co\" => \"cone\", \"con\" => cone\",\n  #                                 \"cone\" => \"cone\" }\n  def abbrev(pattern = nil)\n    Abbrev::abbrev(self, pattern)\n  end\nend\n\nif $0 == __FILE__\n  while line = gets\n    hash = line.split.abbrev\n\n    hash.sort.each do |k, v|\n      puts \"#{k} => #{v}\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/base64.rb",
    "content": "#\n# = base64.rb: methods for base64-encoding and -decoding stings\n#\n# Author:: Yukihiro Matsumoto \n# Documentation:: Dave Thomas and Gavin Sinclair\n#\n# Until Ruby 1.8.1, these methods were defined at the top-level.  Now\n# they are in the Base64 module but included in the top-level, where\n# their usage is deprecated.\n#\n# See Base64 for documentation.\n#\n\nrequire \"kconv\"\n\n\n# The Base64 module provides for the encoding (#encode64) and decoding\n# (#decode64) of binary data using a Base64 representation.\n# \n# The following particular features are also provided:\n# - encode into lines of a given length (#b64encode)\n# - decode the special format specified in RFC2047 for the\n#   representation of email headers (decode_b)\n#\n# == Example\n#\n# A simple encoding and decoding. \n# \n#     require \"base64\"\n#\n#     enc   = Base64.encode64('Send reinforcements')\n#                         # -> \"U2VuZCByZWluZm9yY2VtZW50cw==\\n\" \n#     plain = Base64.decode64(enc)\n#                         # -> \"Send reinforcements\"\n#\n# The purpose of using base64 to encode data is that it translates any\n# binary data into purely printable characters.  It is specified in\n# RFC 2045 (http://www.faqs.org/rfcs/rfc2045.html).\n\nmodule Base64\n  module_function\n\n  # Returns the Base64-decoded version of +str+.\n  #\n  #   require 'base64'\n  #   str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +\n  #         'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +\n  #         'ZSB0aHJlZQpBbmQgc28gb24uLi4K'\n  #   puts Base64.decode64(str)\n  #\n  # <i>Generates:</i>\n  #\n  #    This is line one\n  #    This is line two\n  #    This is line three\n  #    And so on...\n\n  def decode64(str)\n    str.unpack(\"m\")[0]\n  end\n\n\n  # Decodes text formatted using a subset of RFC2047 (the one used for\n  # mime-encoding mail headers).\n  #\n  # Only supports an encoding type of 'b' (base 64), and only supports\n  # the character sets ISO-2022-JP and SHIFT_JIS (so the only two\n  # encoded word sequences recognized are <tt>=?ISO-2022-JP?B?...=</tt> and\n  # <tt>=?SHIFT_JIS?B?...=</tt>).  Recognition of these sequences is case\n  # insensitive.\n\n  def decode_b(str)\n    str.gsub!(/=\\?ISO-2022-JP\\?B\\?([!->@-~]+)\\?=/i) {\n      decode64($1)\n    }\n    str = Kconv::toeuc(str)\n    str.gsub!(/=\\?SHIFT_JIS\\?B\\?([!->@-~]+)\\?=/i) {\n      decode64($1)\n    }\n    str = Kconv::toeuc(str)\n    str.gsub!(/\\n/, ' ') \n    str.gsub!(/\\0/, '')\n    str\n  end\n\n  # Returns the Base64-encoded version of +str+.\n  #\n  #    require 'base64'\n  #    Base64.b64encode(\"Now is the time for all good coders\\nto learn Ruby\")\n  #\n  # <i>Generates:</i>\n  #\n  #    Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g\n  #    UnVieQ==\n\n  def encode64(bin)\n    [bin].pack(\"m\")\n  end\n\n  # _Prints_ the Base64 encoded version of +bin+ (a +String+) in lines of\n  # +len+ (default 60) characters.\n  #\n  #    require 'base64'\n  #    data = \"Now is the time for all good coders\\nto learn Ruby\" \n  #    Base64.b64encode(data)\n  #\n  # <i>Generates:</i>\n  #\n  #    Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g\n  #    UnVieQ==\n\n  def b64encode(bin, len = 60)\n    encode64(bin).scan(/.{1,#{len}}/) do\n      print $&, \"\\n\"\n    end\n  end \n\n\n  module Deprecated # :nodoc:\n    include Base64\n\n    for m in Base64.private_instance_methods(false)\n      module_eval %{\n        def #{m}(*args)\n          warn(\"\\#{caller(1)[0]}: #{m} is deprecated; use Base64.#{m} instead\")\n          super\n        end\n      }\n    end\n  end\nend\n\ninclude Base64::Deprecated\n"
  },
  {
    "path": "lib/benchmark.rb",
    "content": "=begin\n#\n# benchmark.rb - a performance benchmarking library \n# \n# $Id$\n# \n# Created by Gotoken (gotoken@notwork.org). \n#\n# Documentation by Gotoken (original RD), Lyle Johnson (RDoc conversion), and\n# Gavin Sinclair (editing). \n#\n=end\n\n# == Overview\n#\n# The Benchmark module provides methods for benchmarking Ruby code, giving\n# detailed reports on the time taken for each task.\n#\n\n# The Benchmark module provides methods to measure and report the time\n# used to execute Ruby code.\n#\n# * Measure the time to construct the string given by the expression\n#   <tt>\"a\"*1_000_000</tt>:\n#\n#       require 'benchmark'\n#\n#       puts Benchmark.measure { \"a\"*1_000_000 }\n# \n#   On my machine (FreeBSD 3.2 on P5, 100MHz) this generates:\n# \n#       1.166667   0.050000   1.216667 (  0.571355)\n# \n#   This report shows the user CPU time, system CPU time, the sum of\n#   the user and system CPU times, and the elapsed real time. The unit\n#   of time is seconds.\n# \n# * Do some experiments sequentially using the #bm method:\n#\n#       require 'benchmark'\n#\n#       n = 50000\n#       Benchmark.bm do |x|\n#         x.report { for i in 1..n; a = \"1\"; end }\n#         x.report { n.times do   ; a = \"1\"; end }\n#         x.report { 1.upto(n) do ; a = \"1\"; end }\n#       end\n# \n#   The result:\n#\n#              user     system      total        real\n#          1.033333   0.016667   1.016667 (  0.492106)\n#          1.483333   0.000000   1.483333 (  0.694605)\n#          1.516667   0.000000   1.516667 (  0.711077)\n#\n# * Continuing the previous example, put a label in each report:\n#\n#       require 'benchmark'\n#\n#       n = 50000\n#       Benchmark.bm(7) do |x|\n#         x.report(\"for:\")   { for i in 1..n; a = \"1\"; end }\n#         x.report(\"times:\") { n.times do   ; a = \"1\"; end }\n#         x.report(\"upto:\")  { 1.upto(n) do ; a = \"1\"; end }\n#       end\n# \n# The result:\n# \n#                     user     system      total        real\n#        for:     1.050000   0.000000   1.050000 (  0.503462)\n#        times:   1.533333   0.016667   1.550000 (  0.735473)\n#        upto:    1.500000   0.016667   1.516667 (  0.711239)\n# \n#\n# * The times for some benchmarks depend on the order in which items\n#   are run.  These differences are due to the cost of memory\n#   allocation and garbage collection. To avoid these discrepancies,\n#   the #bmbm method is provided.  For example, to compare ways to\n#   sort an array of floats:\n#\n#       require 'benchmark'\n#       \n#       array = (1..1000000).map { rand }\n#       \n#       Benchmark.bmbm do |x|\n#         x.report(\"sort!\") { array.dup.sort! }\n#         x.report(\"sort\")  { array.dup.sort  }\n#       end\n# \n#   The result:\n# \n#        Rehearsal -----------------------------------------\n#        sort!  11.928000   0.010000  11.938000 ( 12.756000)\n#        sort   13.048000   0.020000  13.068000 ( 13.857000)\n#        ------------------------------- total: 25.006000sec\n#        \n#                    user     system      total        real\n#        sort!  12.959000   0.010000  12.969000 ( 13.793000)\n#        sort   12.007000   0.000000  12.007000 ( 12.791000)\n#\n#\n# * Report statistics of sequential experiments with unique labels,\n#   using the #benchmark method:\n#\n#       require 'benchmark'\n#\n#       n = 50000\n#       Benchmark.benchmark(\" \"*7 + CAPTION, 7, FMTSTR, \">total:\", \">avg:\") do |x|\n#         tf = x.report(\"for:\")   { for i in 1..n; a = \"1\"; end }\n#         tt = x.report(\"times:\") { n.times do   ; a = \"1\"; end }\n#         tu = x.report(\"upto:\")  { 1.upto(n) do ; a = \"1\"; end }\n#         [tf+tt+tu, (tf+tt+tu)/3]\n#       end\n# \n#   The result:\n# \n#                     user     system      total        real\n#        for:     1.016667   0.016667   1.033333 (  0.485749)\n#        times:   1.450000   0.016667   1.466667 (  0.681367)\n#        upto:    1.533333   0.000000   1.533333 (  0.722166)\n#        >total:  4.000000   0.033333   4.033333 (  1.889282)\n#        >avg:    1.333333   0.011111   1.344444 (  0.629761)\n\nmodule Benchmark\n\n  BENCHMARK_VERSION = \"2002-04-25\" #:nodoc\"\n\n  def Benchmark::times() # :nodoc:\n      Process::times()\n  end\n\n\n  # Invokes the block with a <tt>Benchmark::Report</tt> object, which\n  # may be used to collect and report on the results of individual\n  # benchmark tests. Reserves <i>label_width</i> leading spaces for\n  # labels on each line. Prints _caption_ at the top of the\n  # report, and uses _fmt_ to format each line.\n  # If the block returns an array of\n  # <tt>Benchmark::Tms</tt> objects, these will be used to format\n  # additional lines of output. If _label_ parameters are\n  # given, these are used to label these extra lines.\n  #\n  # _Note_: Other methods provide a simpler interface to this one, and are\n  # suitable for nearly all benchmarking requirements.  See the examples in\n  # Benchmark, and the #bm and #bmbm methods.\n  #\n  # Example: \n  #\n  #     require 'benchmark'\n  #     include Benchmark          # we need the CAPTION and FMTSTR constants \n  #\n  #     n = 50000\n  #     Benchmark.benchmark(\" \"*7 + CAPTION, 7, FMTSTR, \">total:\", \">avg:\") do |x|\n  #       tf = x.report(\"for:\")   { for i in 1..n; a = \"1\"; end }\n  #       tt = x.report(\"times:\") { n.times do   ; a = \"1\"; end }\n  #       tu = x.report(\"upto:\")  { 1.upto(n) do ; a = \"1\"; end }\n  #       [tf+tt+tu, (tf+tt+tu)/3]\n  #     end\n  # \n  # <i>Generates:</i>\n  # \n  #                     user     system      total        real\n  #        for:     1.016667   0.016667   1.033333 (  0.485749)\n  #        times:   1.450000   0.016667   1.466667 (  0.681367)\n  #        upto:    1.533333   0.000000   1.533333 (  0.722166)\n  #        >total:  4.000000   0.033333   4.033333 (  1.889282)\n  #        >avg:    1.333333   0.011111   1.344444 (  0.629761)\n  # \n\n  def benchmark(caption = \"\", label_width = nil, fmtstr = nil, *labels) # :yield: report\n    sync = STDOUT.sync\n    STDOUT.sync = true\n    label_width ||= 0\n    fmtstr ||= FMTSTR\n    raise ArgumentError, \"no block\" unless iterator?\n    print caption\n    results = yield(Report.new(label_width, fmtstr))\n    Array === results and results.grep(Tms).each {|t|\n      print((labels.shift || t.label || \"\").ljust(label_width), \n            t.format(fmtstr))\n    }\n    STDOUT.sync = sync\n  end\n\n\n  # A simple interface to the #benchmark method, #bm is generates sequential reports\n  # with labels.  The parameters have the same meaning as for #benchmark.\n  # \n  #     require 'benchmark'\n  #\n  #     n = 50000\n  #     Benchmark.bm(7) do |x|\n  #       x.report(\"for:\")   { for i in 1..n; a = \"1\"; end }\n  #       x.report(\"times:\") { n.times do   ; a = \"1\"; end }\n  #       x.report(\"upto:\")  { 1.upto(n) do ; a = \"1\"; end }\n  #     end\n  # \n  # <i>Generates:</i>\n  # \n  #                     user     system      total        real\n  #        for:     1.050000   0.000000   1.050000 (  0.503462)\n  #        times:   1.533333   0.016667   1.550000 (  0.735473)\n  #        upto:    1.500000   0.016667   1.516667 (  0.711239)\n  #\n\n  def bm(label_width = 0, *labels, &blk) # :yield: report\n    benchmark(\" \"*label_width + CAPTION, label_width, FMTSTR, *labels, &blk)\n  end\n\n\n  # Sometimes benchmark results are skewed because code executed\n  # earlier encounters different garbage collection overheads than\n  # that run later. #bmbm attempts to minimize this effect by running\n  # the tests twice, the first time as a rehearsal in order to get the\n  # runtime environment stable, the second time for\n  # real. <tt>GC.start</tt> is executed before the start of each of\n  # the real timings; the cost of this is not included in the\n  # timings. In reality, though, there's only so much that #bmbm can\n  # do, and the results are not guaranteed to be isolated from garbage\n  # collection and other effects.\n  #\n  # Because #bmbm takes two passes through the tests, it can\n  # calculate the required label width.\n  #\n  #       require 'benchmark'\n  #       \n  #       array = (1..1000000).map { rand }\n  #       \n  #       Benchmark.bmbm do |x|\n  #         x.report(\"sort!\") { array.dup.sort! }\n  #         x.report(\"sort\")  { array.dup.sort  }\n  #       end\n  # \n  # <i>Generates:</i>\n  # \n  #        Rehearsal -----------------------------------------\n  #        sort!  11.928000   0.010000  11.938000 ( 12.756000)\n  #        sort   13.048000   0.020000  13.068000 ( 13.857000)\n  #        ------------------------------- total: 25.006000sec\n  #        \n  #                    user     system      total        real\n  #        sort!  12.959000   0.010000  12.969000 ( 13.793000)\n  #        sort   12.007000   0.000000  12.007000 ( 12.791000)\n  #\n  # #bmbm yields a Benchmark::Job object and returns an array of\n  # Benchmark::Tms objects.\n  #\n  def bmbm(width = 0, &blk) # :yield: job\n    job = Job.new(width)\n    yield(job)\n    width = job.width\n    sync = STDOUT.sync\n    STDOUT.sync = true\n\n    # rehearsal\n    print \"Rehearsal \"\n    puts '-'*(width+CAPTION.length - \"Rehearsal \".length)\n    list = []\n    job.list.each{|label,item|\n      print(label.ljust(width))\n      res = Benchmark::measure(&item)\n      print res.format()\n      list.push res\n    }\n    sum = Tms.new; list.each{|i| sum += i}\n    ets = sum.format(\"total: %tsec\")\n    printf(\"%s %s\\n\\n\",\n           \"-\"*(width+CAPTION.length-ets.length-1), ets)\n    \n    # take\n    print ' '*width, CAPTION\n    list = []\n    ary = []\n    job.list.each{|label,item|\n      GC::start\n      print label.ljust(width)\n      res = Benchmark::measure(&item)\n      print res.format()\n      ary.push res\n      list.push [label, res]\n    }\n\n    STDOUT.sync = sync\n    ary\n  end\n\n  # \n  # Returns the time used to execute the given block as a\n  # Benchmark::Tms object.\n  #\n  def measure(label = \"\") # :yield:\n    t0, r0 = Benchmark.times, Time.now\n    yield\n    t1, r1 = Benchmark.times, Time.now\n    Benchmark::Tms.new(t1.utime  - t0.utime, \n                       t1.stime  - t0.stime, \n                       t1.cutime - t0.cutime, \n                       t1.cstime - t0.cstime, \n                       r1.to_f - r0.to_f,\n                       label)\n  end\n\n  #\n  # Returns the elapsed real time used to execute the given block.\n  #\n  def realtime(&blk) # :yield:\n    r0 = Time.now\n    yield\n    r1 = Time.now\n    r1.to_f - r0.to_f\n  end\n\n\n\n  #\n  # A Job is a sequence of labelled blocks to be processed by the\n  # Benchmark.bmbm method.  It is of little direct interest to the user.\n  #\n  class Job # :nodoc:\n    #\n    # Returns an initialized Job instance.\n    # Usually, one doesn't call this method directly, as new\n    # Job objects are created by the #bmbm method.\n    # _width_ is a initial value for the label offset used in formatting;\n    # the #bmbm method passes its _width_ argument to this constructor. \n    # \n    def initialize(width)\n      @width = width\n      @list = []\n    end\n\n    #\n    # Registers the given label and block pair in the job list.\n    #\n    def item(label = \"\", &blk) # :yield:\n      raise ArgumentError, \"no block\" unless block_given?\n      label += ' '\n      w = label.length\n      @width = w if @width < w\n      @list.push [label, blk]\n      self\n    end\n\n    alias report item\n    \n    # An array of 2-element arrays, consisting of label and block pairs.\n    attr_reader :list\n    \n    # Length of the widest label in the #list, plus one.  \n    attr_reader :width\n  end\n\n  module_function :benchmark, :measure, :realtime, :bm, :bmbm\n\n\n\n  #\n  # This class is used by the Benchmark.benchmark and Benchmark.bm methods.\n  # It is of little direct interest to the user.\n  #\n  class Report # :nodoc:\n    #\n    # Returns an initialized Report instance.\n    # Usually, one doesn't call this method directly, as new\n    # Report objects are created by the #benchmark and #bm methods. \n    # _width_ and _fmtstr_ are the label offset and \n    # format string used by Tms#format. \n    # \n    def initialize(width = 0, fmtstr = nil)\n      @width, @fmtstr = width, fmtstr\n    end\n\n    #\n    # Prints the _label_ and measured time for the block,\n    # formatted by _fmt_. See Tms#format for the\n    # formatting rules.\n    #\n    def item(label = \"\", *fmt, &blk) # :yield:\n      print label.ljust(@width)\n      res = Benchmark::measure(&blk)\n      print res.format(@fmtstr, *fmt)\n      res\n    end\n\n    alias report item\n  end\n\n\n\n  #\n  # A data object, representing the times associated with a benchmark\n  # measurement.\n  #\n  class Tms\n    CAPTION = \"      user     system      total        real\\n\"\n    FMTSTR = \"%10.6u %10.6y %10.6t %10.6r\\n\"\n\n    # User CPU time\n    attr_reader :utime\n    \n    # System CPU time\n    attr_reader :stime\n   \n    # User CPU time of children\n    attr_reader :cutime\n    \n    # System CPU time of children\n    attr_reader :cstime\n    \n    # Elapsed real time\n    attr_reader :real\n    \n    # Total time, that is _utime_ + _stime_ + _cutime_ + _cstime_ \n    attr_reader :total\n    \n    # Label\n    attr_reader :label\n\n    #\n    # Returns an initialized Tms object which has\n    # _u_ as the user CPU time, _s_ as the system CPU time, \n    # _cu_ as the children's user CPU time, _cs_ as the children's\n    # system CPU time, _real_ as the elapsed real time and _l_\n    # as the label. \n    # \n    def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0, l = nil)\n      @utime, @stime, @cutime, @cstime, @real, @label = u, s, cu, cs, real, l\n      @total = @utime + @stime + @cutime + @cstime\n    end\n\n    # \n    # Returns a new Tms object whose times are the sum of the times for this\n    # Tms object, plus the time required to execute the code block (_blk_).\n    # \n    def add(&blk) # :yield:\n      self + Benchmark::measure(&blk) \n    end\n\n    # \n    # An in-place version of #add.\n    # \n    def add!\n      t = Benchmark::measure(&blk) \n      @utime  = utime + t.utime\n      @stime  = stime + t.stime\n      @cutime = cutime + t.cutime\n      @cstime = cstime + t.cstime\n      @real   = real + t.real\n      self\n    end\n\n    # \n    # Returns a new Tms object obtained by memberwise summation\n    # of the individual times for this Tms object with those of the other\n    # Tms object.\n    # This method and #/() are useful for taking statistics. \n    # \n    def +(other); memberwise(:+, other) end\n    \n    #\n    # Returns a new Tms object obtained by memberwise subtraction\n    # of the individual times for the other Tms object from those of this\n    # Tms object.\n    #\n    def -(other); memberwise(:-, other) end\n    \n    #\n    # Returns a new Tms object obtained by memberwise multiplication\n    # of the individual times for this Tms object by _x_.\n    #\n    def *(x); memberwise(:*, x) end\n\n    # \n    # Returns a new Tms object obtained by memberwise division\n    # of the individual times for this Tms object by _x_.\n    # This method and #+() are useful for taking statistics. \n    # \n    def /(x); memberwise(:/, x) end\n\n    #\n    # Returns the contents of this Tms object as\n    # a formatted string, according to a format string\n    # like that passed to Kernel.format. In addition, #format\n    # accepts the following extensions:\n    #\n    # <tt>%u</tt>::     Replaced by the user CPU time, as reported by Tms#utime.\n    # <tt>%y</tt>::     Replaced by the system CPU time, as reported by #stime (Mnemonic: y of \"s*y*stem\")\n    # <tt>%U</tt>::     Replaced by the children's user CPU time, as reported by Tms#cutime \n    # <tt>%Y</tt>::     Replaced by the children's system CPU time, as reported by Tms#cstime\n    # <tt>%t</tt>::     Replaced by the total CPU time, as reported by Tms#total\n    # <tt>%r</tt>::     Replaced by the elapsed real time, as reported by Tms#real\n    # <tt>%n</tt>::     Replaced by the label string, as reported by Tms#label (Mnemonic: n of \"*n*ame\")\n    # \n    # If _fmtstr_ is not given, FMTSTR is used as default value, detailing the\n    # user, system and real elapsed time.\n    # \n    def format(arg0 = nil, *args)\n      fmtstr = (arg0 || FMTSTR).dup\n      fmtstr.gsub!(/(%[-+\\.\\d]*)n/){\"#{$1}s\" % label}\n      fmtstr.gsub!(/(%[-+\\.\\d]*)u/){\"#{$1}f\" % utime}\n      fmtstr.gsub!(/(%[-+\\.\\d]*)y/){\"#{$1}f\" % stime}\n      fmtstr.gsub!(/(%[-+\\.\\d]*)U/){\"#{$1}f\" % cutime}\n      fmtstr.gsub!(/(%[-+\\.\\d]*)Y/){\"#{$1}f\" % cstime}\n      fmtstr.gsub!(/(%[-+\\.\\d]*)t/){\"#{$1}f\" % total}\n      fmtstr.gsub!(/(%[-+\\.\\d]*)r/){\"(#{$1}f)\" % real}\n      arg0 ? Kernel::format(fmtstr, *args) : fmtstr\n    end\n\n    # \n    # Same as #format.\n    # \n    def to_s\n      format\n    end\n\n    # \n    # Returns a new 6-element array, consisting of the\n    # label, user CPU time, system CPU time, children's\n    # user CPU time, children's system CPU time and elapsed\n    # real time.\n    # \n    def to_a\n      [@label, @utime, @stime, @cutime, @cstime, @real]\n    end\n\n    protected\n    def memberwise(op, x)\n      case x\n      when Benchmark::Tms\n        Benchmark::Tms.new(utime.__send__(op, x.utime),\n                           stime.__send__(op, x.stime),\n                           cutime.__send__(op, x.cutime),\n                           cstime.__send__(op, x.cstime),\n                           real.__send__(op, x.real)\n                           )\n      else\n        Benchmark::Tms.new(utime.__send__(op, x),\n                           stime.__send__(op, x),\n                           cutime.__send__(op, x),\n                           cstime.__send__(op, x),\n                           real.__send__(op, x)\n                           )\n      end\n    end\n  end\n\n  # The default caption string (heading above the output times).\n  CAPTION = Benchmark::Tms::CAPTION\n\n  # The default format string used to display times.  See also Benchmark::Tms#format. \n  FMTSTR = Benchmark::Tms::FMTSTR\nend\n\nif __FILE__ == $0\n  include Benchmark\n\n  n = ARGV[0].to_i.nonzero? || 50000\n  puts %Q([#{n} times iterations of `a = \"1\"'])\n  benchmark(\"       \" + CAPTION, 7, FMTSTR) do |x|\n    x.report(\"for:\")   {for i in 1..n; a = \"1\"; end} # Benchmark::measure\n    x.report(\"times:\") {n.times do   ; a = \"1\"; end}\n    x.report(\"upto:\")  {1.upto(n) do ; a = \"1\"; end}\n  end\n\n  benchmark do\n    [\n      measure{for i in 1..n; a = \"1\"; end},  # Benchmark::measure\n      measure{n.times do   ; a = \"1\"; end},\n      measure{1.upto(n) do ; a = \"1\"; end}\n    ]\n  end\nend\n"
  },
  {
    "path": "lib/cgi/.document",
    "content": "session.rb\n\n"
  },
  {
    "path": "lib/cgi/session/pstore.rb",
    "content": "#\n# cgi/session/pstore.rb - persistent storage of marshalled session data\n#\n# Documentation: William Webber (william@williamwebber.com)\n# \n# == Overview\n#\n# This file provides the CGI::Session::PStore class, which builds\n# persistent of session data on top of the pstore library.  See\n# cgi/session.rb for more details on session storage managers.\n\nrequire 'cgi/session'\nrequire 'pstore'\n\nclass CGI\n  class Session\n    # PStore-based session storage class.\n    #\n    # This builds upon the top-level PStore class provided by the\n    # library file pstore.rb.  Session data is marshalled and stored\n    # in a file.  File locking and transaction services are provided.\n    class PStore\n      # Create a new CGI::Session::PStore instance\n      #\n      # This constructor is used internally by CGI::Session.  The\n      # user does not generally need to call it directly.\n      #\n      # +session+ is the session for which this instance is being\n      # created.  The session id must only contain alphanumeric\n      # characters; automatically generated session ids observe\n      # this requirement.\n      # \n      # +option+ is a hash of options for the initializer.  The\n      # following options are recognised:\n      #\n      # tmpdir:: the directory to use for storing the PStore\n      #          file.  Defaults to Dir::tmpdir (generally \"/tmp\"\n      #          on Unix systems).\n      # prefix:: the prefix to add to the session id when generating\n      #          the filename for this session's PStore file.\n      #          Defaults to the empty string.\n      #\n      # This session's PStore file will be created if it does\n      # not exist, or opened if it does.\n      def initialize(session, option={})\n\tdir = option['tmpdir'] || Dir::tmpdir\n\tprefix = option['prefix'] || ''\n\tid = session.session_id\n        require 'digest/md5'\n        md5 = Digest::MD5.hexdigest(id)[0,16]\n\tpath = dir+\"/\"+prefix+md5\n\tpath.untaint\n\tif File::exist?(path)\n\t  @hash = nil\n\telse\n          unless session.new_session\n            raise CGI::Session::NoSession, \"uninitialized session\"\n          end\n\t  @hash = {}\n\tend\n\t@p = ::PStore.new(path)\n\t@p.transaction do |p|\n\t  File.chmod(0600, p.path)\n\tend\n      end\n\n      # Restore session state from the session's PStore file.\n      #\n      # Returns the session state as a hash.\n      def restore\n\tunless @hash\n\t  @p.transaction do\n           @hash = @p['hash'] || {}\n\t  end\n\tend\n\t@hash\n      end\n\n      # Save session state to the session's PStore file.\n      def update \n\t@p.transaction do\n\t    @p['hash'] = @hash\n\tend\n      end\n\n      # Update and close the session's PStore file.\n      def close\n\tupdate\n      end\n\n      # Close and delete the session's PStore file.\n      def delete\n\tpath = @p.path\n\tFile::unlink path\n      end\n\n    end\n  end\nend\n\nif $0 == __FILE__\n  # :enddoc:\n  STDIN.reopen(\"/dev/null\")\n  cgi = CGI.new\n  session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::PStore)\n  session['key'] = {'k' => 'v'}\n  puts session['key'].class\n  fail unless Hash === session['key']\n  puts session['key'].inspect\n  fail unless session['key'].inspect == '{\"k\"=>\"v\"}'\nend\n"
  },
  {
    "path": "lib/cgi/session.rb",
    "content": "#\n# cgi/session.rb - session support for cgi scripts\n#\n# Copyright (C) 2001  Yukihiro \"Matz\" Matsumoto\n# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n# Copyright (C) 2000  Information-technology Promotion Agency, Japan\n#\n# Author: Yukihiro \"Matz\" Matsumoto\n#\n# Documentation: William Webber (william@williamwebber.com)\n#\n# == Overview\n#\n# This file provides the +CGI::Session+ class, which provides session\n# support for CGI scripts.  A session is a sequence of HTTP requests\n# and responses linked together and associated with a single client.  \n# Information associated with the session is stored\n# on the server between requests.  A session id is passed between client\n# and server with every request and response, transparently\n# to the user.  This adds state information to the otherwise stateless\n# HTTP request/response protocol.\n#\n# See the documentation to the +CGI::Session+ class for more details\n# and examples of usage.  See cgi.rb for the +CGI+ class itself.\n\nrequire 'cgi'\nrequire 'tmpdir'\n\nclass CGI\n\n  # Class representing an HTTP session.  See documentation for the file \n  # cgi/session.rb for an introduction to HTTP sessions.\n  #\n  # == Lifecycle\n  #\n  # A CGI::Session instance is created from a CGI object.  By default,\n  # this CGI::Session instance will start a new session if none currently\n  # exists, or continue the current session for this client if one does\n  # exist.  The +new_session+ option can be used to either always or\n  # never create a new session.  See #new() for more details.\n  #\n  # #delete() deletes a session from session storage.  It\n  # does not however remove the session id from the client.  If the client\n  # makes another request with the same id, the effect will be to start\n  # a new session with the old session's id.\n  #\n  # == Setting and retrieving session data.\n  #\n  # The Session class associates data with a session as key-value pairs.\n  # This data can be set and retrieved by indexing the Session instance \n  # using '[]', much the same as hashes (although other hash methods\n  # are not supported).\n  #\n  # When session processing has been completed for a request, the\n  # session should be closed using the close() method.  This will\n  # store the session's state to persistent storage.  If you want\n  # to store the session's state to persistent storage without\n  # finishing session processing for this request, call the update()\n  # method.\n  #\n  # == Storing session state\n  #\n  # The caller can specify what form of storage to use for the session's \n  # data with the +database_manager+ option to CGI::Session::new.  The\n  # following storage classes are provided as part of the standard library:\n  #\n  # CGI::Session::FileStore:: stores data as plain text in a flat file.  Only \n  #                           works with String data.  This is the default \n  #                           storage type.\n  # CGI::Session::MemoryStore:: stores data in an in-memory hash.  The data \n  #                             only persists for as long as the current ruby \n  #                             interpreter instance does.\n  # CGI::Session::PStore:: stores data in Marshalled format.  Provided by\n  #                        cgi/session/pstore.rb.  Supports data of any type, \n  #                        and provides file-locking and transaction support.\n  #\n  # Custom storage types can also be created by defining a class with \n  # the following methods:\n  #\n  #    new(session, options)\n  #    restore  # returns hash of session data.\n  #    update\n  #    close\n  #    delete\n  #\n  # Changing storage type mid-session does not work.  Note in particular\n  # that by default the FileStore and PStore session data files have the\n  # same name.  If your application switches from one to the other without\n  # making sure that filenames will be different\n  # and clients still have old sessions lying around in cookies, then\n  # things will break nastily!\n  #\n  # == Maintaining the session id.\n  #\n  # Most session state is maintained on the server.  However, a session\n  # id must be passed backwards and forwards between client and server\n  # to maintain a reference to this session state.\n  #\n  # The simplest way to do this is via cookies.  The CGI::Session class\n  # provides transparent support for session id communication via cookies\n  # if the client has cookies enabled.\n  # \n  # If the client has cookies disabled, the session id must be included\n  # as a parameter of all requests sent by the client to the server.  The\n  # CGI::Session class in conjunction with the CGI class will transparently\n  # add the session id as a hidden input field to all forms generated\n  # using the CGI#form() HTML generation method.  No built-in support is\n  # provided for other mechanisms, such as URL re-writing.  The caller is\n  # responsible for extracting the session id from the session_id \n  # attribute and manually encoding it in URLs and adding it as a hidden\n  # input to HTML forms created by other mechanisms.  Also, session expiry\n  # is not automatically handled.\n  #\n  # == Examples of use\n  #\n  # === Setting the user's name\n  #\n  #   require 'cgi'\n  #   require 'cgi/session'\n  #   require 'cgi/session/pstore'     # provides CGI::Session::PStore\n  #\n  #   cgi = CGI.new(\"html4\")\n  #\n  #   session = CGI::Session.new(cgi,\n  #       'database_manager' => CGI::Session::PStore,  # use PStore\n  #       'session_key' => '_rb_sess_id',              # custom session key\n  #       'session_expires' => Time.now + 30 * 60,     # 30 minute timeout \n  #       'prefix' => 'pstore_sid_')                   # PStore option\n  #   if cgi.has_key?('user_name') and cgi['user_name'] != ''\n  #       # coerce to String: cgi[] returns the \n  #       # string-like CGI::QueryExtension::Value\n  #       session['user_name'] = cgi['user_name'].to_s\n  #   elsif !session['user_name']\n  #       session['user_name'] = \"guest\"\n  #   end\n  #   session.close\n  #\n  # === Creating a new session safely\n  #\n  #   require 'cgi'\n  #   require 'cgi/session'\n  #\n  #   cgi = CGI.new(\"html4\")\n  #\n  #   # We make sure to delete an old session if one exists,\n  #   # not just to free resources, but to prevent the session \n  #   # from being maliciously hijacked later on.\n  #   begin\n  #       session = CGI::Session.new(cgi, 'new_session' => false)      \n  #       session.delete                 \n  #   rescue ArgumentError  # if no old session\n  #   end\n  #   session = CGI::Session.new(cgi, 'new_session' => true)\n  #   session.close\n  #\n  class Session\n\n    class NoSession < RuntimeError #:nodoc:\n    end\n\n    # The id of this session.\n    attr_reader :session_id, :new_session\n\n    def Session::callback(dbman)  #:nodoc:\n      Proc.new{\n\tdbman[0].close unless dbman.empty?\n      }\n    end\n\n    # Create a new session id.\n    #\n    # The session id is an MD5 hash based upon the time,\n    # a random number, and a constant string.  This routine\n    # is used internally for automatically generated\n    # session ids. \n    def create_new_id\n      require 'securerandom'\n      begin\n        session_id = SecureRandom.hex(16)\n      rescue NotImplementedError\n        require 'digest/md5'\n        md5 = Digest::MD5::new\n        now = Time::now\n        md5.update(now.to_s)\n        md5.update(String(now.usec))\n        md5.update(String(rand(0)))\n        md5.update(String($$))\n        md5.update('foobar')\n        session_id = md5.hexdigest\n      end\n      session_id\n    end\n    private :create_new_id\n\n    # Create a new CGI::Session object for +request+.\n    #\n    # +request+ is an instance of the +CGI+ class (see cgi.rb).\n    # +option+ is a hash of options for initialising this\n    # CGI::Session instance.  The following options are\n    # recognised:\n    #\n    # session_key:: the parameter name used for the session id.\n    #               Defaults to '_session_id'.\n    # session_id:: the session id to use.  If not provided, then\n    #              it is retrieved from the +session_key+ parameter\n    #              of the request, or automatically generated for\n    #              a new session.\n    # new_session:: if true, force creation of a new session.  If not set, \n    #               a new session is only created if none currently\n    #               exists.  If false, a new session is never created,\n    #               and if none currently exists and the +session_id+\n    #               option is not set, an ArgumentError is raised.\n    # database_manager:: the name of the class providing storage facilities\n    #                    for session state persistence.  Built-in support\n    #                    is provided for +FileStore+ (the default),\n    #                    +MemoryStore+, and +PStore+ (from\n    #                    cgi/session/pstore.rb).  See the documentation for\n    #                    these classes for more details.\n    #\n    # The following options are also recognised, but only apply if the\n    # session id is stored in a cookie.\n    #\n    # session_expires:: the time the current session expires, as a \n    #                   +Time+ object.  If not set, the session will terminate\n    #                   when the user's browser is closed.\n    # session_domain:: the hostname domain for which this session is valid.\n    #                  If not set, defaults to the hostname of the server.\n    # session_secure:: if +true+, this session will only work over HTTPS.\n    # session_path:: the path for which this session applies.  Defaults\n    #                to the directory of the CGI script.\n    #\n    # +option+ is also passed on to the session storage class initializer; see\n    # the documentation for each session storage class for the options\n    # they support.\n    #                  \n    # The retrieved or created session is automatically added to +request+\n    # as a cookie, and also to its +output_hidden+ table, which is used\n    # to add hidden input elements to forms.  \n    #\n    # *WARNING* the +output_hidden+\n    # fields are surrounded by a <fieldset> tag in HTML 4 generation, which\n    # is _not_ invisible on many browsers; you may wish to disable the\n    # use of fieldsets with code similar to the following\n    # (see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/37805)\n    #\n    #   cgi = CGI.new(\"html4\")\n    #   class << cgi\n    #       undef_method :fieldset\n    #   end\n    #\n    def initialize(request, option={})\n      @new_session = false\n      session_key = option['session_key'] || '_session_id'\n      session_id = option['session_id']\n      unless session_id\n\tif option['new_session']\n\t  session_id = create_new_id\n      @new_session = true\n\tend\n      end\n      unless session_id\n\tif request.key?(session_key)\n\t  session_id = request[session_key]\n\t  session_id = session_id.read if session_id.respond_to?(:read)\n\tend\n\tunless session_id\n\t  session_id, = request.cookies[session_key]\n\tend\n\tunless session_id\n\t  unless option.fetch('new_session', true)\n\t    raise ArgumentError, \"session_key `%s' should be supplied\"%session_key\n\t  end\n\t  session_id = create_new_id\n      @new_session = true\n\tend\n      end\n      @session_id = session_id\n      dbman = option['database_manager'] || FileStore\n      begin\n        @dbman = dbman::new(self, option)\n      rescue NoSession\n        unless option.fetch('new_session', true)\n          raise ArgumentError, \"invalid session_id `%s'\"%session_id\n        end\n        session_id = @session_id = create_new_id unless session_id\n      @new_session = true\n        retry\n      end\n      request.instance_eval do\n\t@output_hidden = {session_key => session_id} unless option['no_hidden']\n\t@output_cookies =  [\n          Cookie::new(\"name\" => session_key,\n\t\t      \"value\" => session_id,\n\t\t      \"expires\" => option['session_expires'],\n\t\t      \"domain\" => option['session_domain'],\n\t\t      \"secure\" => option['session_secure'],\n\t\t      \"path\" => if option['session_path'] then\n\t\t\t\t  option['session_path']\n\t\t                elsif ENV[\"SCRIPT_NAME\"] then\n\t\t\t\t  File::dirname(ENV[\"SCRIPT_NAME\"])\n\t\t\t\telse\n\t\t\t\t  \"\"\n\t\t\t\tend)\n        ] unless option['no_cookies']\n      end\n      @dbprot = [@dbman]\n      ObjectSpace::define_finalizer(self, Session::callback(@dbprot))\n    end\n\n    # Retrieve the session data for key +key+.\n    def [](key)\n      @data ||= @dbman.restore\n      @data[key]\n    end\n\n    # Set the session date for key +key+.\n    def []=(key, val)\n      @write_lock ||= true\n      @data ||= @dbman.restore\n      @data[key] = val\n    end\n\n    # Store session data on the server.  For some session storage types,\n    # this is a no-op.\n    def update  \n      @dbman.update\n    end\n\n    # Store session data on the server and close the session storage.  \n    # For some session storage types, this is a no-op.\n    def close\n      @dbman.close\n      @dbprot.clear\n    end\n\n    # Delete the session from storage.  Also closes the storage.\n    #\n    # Note that the session's data is _not_ automatically deleted\n    # upon the session expiring.\n    def delete\n      @dbman.delete\n      @dbprot.clear\n    end\n\n    # File-based session storage class.\n    #\n    # Implements session storage as a flat file of 'key=value' values.\n    # This storage type only works directly with String values; the\n    # user is responsible for converting other types to Strings when\n    # storing and from Strings when retrieving.\n    class FileStore\n      # Create a new FileStore instance.\n      #\n      # This constructor is used internally by CGI::Session.  The\n      # user does not generally need to call it directly.\n      #\n      # +session+ is the session for which this instance is being\n      # created.  The session id must only contain alphanumeric\n      # characters; automatically generated session ids observe\n      # this requirement.\n      # \n      # +option+ is a hash of options for the initializer.  The\n      # following options are recognised:\n      #\n      # tmpdir:: the directory to use for storing the FileStore\n      #          file.  Defaults to Dir::tmpdir (generally \"/tmp\"\n      #          on Unix systems).\n      # prefix:: the prefix to add to the session id when generating\n      #          the filename for this session's FileStore file.\n      #          Defaults to the empty string.\n      # suffix:: the prefix to add to the session id when generating\n      #          the filename for this session's FileStore file.\n      #          Defaults to the empty string.\n      #\n      # This session's FileStore file will be created if it does\n      # not exist, or opened if it does.\n      def initialize(session, option={})\n\tdir = option['tmpdir'] || Dir::tmpdir\n\tprefix = option['prefix'] || ''\n\tsuffix = option['suffix'] || ''\n\tid = session.session_id\n        require 'digest/md5'\n        md5 = Digest::MD5.hexdigest(id)[0,16]\n\t@path = dir+\"/\"+prefix+md5+suffix\n\tif File::exist? @path\n\t  @hash = nil\n\telse\n          unless session.new_session\n            raise CGI::Session::NoSession, \"uninitialized session\"\n          end\n\t  @hash = {}\n\tend\n      end\n\n      # Restore session state from the session's FileStore file.\n      #\n      # Returns the session state as a hash.\n      def restore\n\tunless @hash\n\t  @hash = {}\n          begin\n            lockf = File.open(@path+\".lock\", \"r\")\n            lockf.flock File::LOCK_SH\n\t    f = File.open(@path, 'r')\n\t    for line in f\n\t      line.chomp!\n\t      k, v = line.split('=',2)\n\t      @hash[CGI::unescape(k)] = CGI::unescape(v)\n\t    end\n          ensure\n\t    f.close unless f.nil?\n            lockf.close if lockf\n          end\n\tend\n\t@hash\n      end\n\n      # Save session state to the session's FileStore file.\n      def update\n\treturn unless @hash\n        begin\n          lockf = File.open(@path+\".lock\", File::CREAT|File::RDWR, 0600)\n\t  lockf.flock File::LOCK_EX\n          f = File.open(@path+\".new\", File::CREAT|File::TRUNC|File::WRONLY, 0600)\n   \t  for k,v in @hash\n\t    f.printf \"%s=%s\\n\", CGI::escape(k), CGI::escape(String(v))\n\t  end\n          f.close\n          File.rename @path+\".new\", @path\n        ensure\n          f.close if f and !f.closed?\n          lockf.close if lockf\n        end\n      end\n\n      # Update and close the session's FileStore file.\n      def close\n\tupdate\n      end\n\n      # Close and delete the session's FileStore file.\n      def delete\n        File::unlink @path+\".lock\" rescue nil\n        File::unlink @path+\".new\" rescue nil\n        File::unlink @path\n      rescue Errno::ENOENT\n      end\n    end\n\n    # In-memory session storage class.\n    #\n    # Implements session storage as a global in-memory hash.  Session\n    # data will only persist for as long as the ruby interpreter \n    # instance does.\n    class MemoryStore\n      GLOBAL_HASH_TABLE = {} #:nodoc:\n\n      # Create a new MemoryStore instance.\n      #\n      # +session+ is the session this instance is associated with.\n      # +option+ is a list of initialisation options.  None are\n      # currently recognised.\n      def initialize(session, option=nil)\n\t@session_id = session.session_id\n        unless GLOBAL_HASH_TABLE.key?(@session_id)\n          unless session.new_session\n            raise CGI::Session::NoSession, \"uninitialized session\"\n          end\n          GLOBAL_HASH_TABLE[@session_id] = {}\n        end\n      end\n\n      # Restore session state.\n      #\n      # Returns session data as a hash.\n      def restore\n\tGLOBAL_HASH_TABLE[@session_id]\n      end\n\n      # Update session state.\n      #\n      # A no-op.\n      def update\n\t# don't need to update; hash is shared\n      end\n\n      # Close session storage.\n      #\n      # A no-op.\n      def close\n\t# don't need to close\n      end\n\n      # Delete the session state.\n      def delete\n\tGLOBAL_HASH_TABLE.delete(@session_id)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/cgi-lib.rb",
    "content": "warn \"Warning:#{caller[0].sub(/:in `.*'\\z/, '')}: cgi-lib is deprecated after Ruby 1.8.1; use cgi instead\"\n\n=begin\n\n= simple CGI support library\n\n= example\n\n== get form values\n\n\trequire \"cgi-lib.rb\"\n\tquery = CGI.new\n\tquery['field']   # <== value of 'field'\n\tquery.keys       # <== array of fields\n\nand query has Hash class methods\n\n\n== get cookie values\n\n\trequire \"cgi-lib.rb\"\n\tquery = CGI.new\n\tquery.cookie['name']  # <== cookie value of 'name'\n\tquery.cookie.keys     # <== all cookie names\n\nand query.cookie has Hash class methods\n\n\n== print HTTP header and HTML string to $>\n\n\trequire \"cgi-lib.rb\"\n\tCGI::print{\n\t  CGI::tag(\"HTML\"){\n\t    CGI::tag(\"HEAD\"){ CGI::tag(\"TITLE\"){\"TITLE\"} } +\n\t    CGI::tag(\"BODY\"){\n\t      CGI::tag(\"FORM\", {\"ACTION\"=>\"test.rb\", \"METHOD\"=>\"POST\"}){\n\t        CGI::tag(\"INPUT\", {\"TYPE\"=>\"submit\", \"VALUE\"=>\"submit\"})\n\t      } +\n\t      CGI::tag(\"HR\")\n\t    }\n\t  }\n\t}\n\n\n== make raw cookie string\n\n\trequire \"cgi-lib.rb\"\n\tcookie1 = CGI::cookie({'name'    => 'name',\n\t                       'value'   => 'value',\n\t                       'path'    => 'path',   # optional\n\t                       'domain'  => 'domain', # optional\n\t                       'expires' => Time.now, # optional\n\t                       'secure'  => true      # optional\n\t                      })\n\n\tCGI::print(\"Content-Type: text/html\", cookie1, cookie2){ \"string\" }\n\n\n== print HTTP header and string to $>\n\n\trequire \"cgi-lib.rb\"\n\tCGI::print{ \"string\" }\n\t  # == CGI::print(\"Content-Type: text/html\"){ \"string\" }\n\tCGI::print(\"Content-Type: text/html\", cookie1, cookie2){ \"string\" }\n\n\n=== NPH (no-parse-header) mode\n\n\trequire \"cgi-lib.rb\"\n\tCGI::print(\"nph\"){ \"string\" }\n\t  # == CGI::print(\"nph\", \"Content-Type: text/html\"){ \"string\" }\n\tCGI::print(\"nph\", \"Content-Type: text/html\", cookie1, cookie2){ \"string\" }\n\n\n== make HTML tag string\n\n\trequire \"cgi-lib.rb\"\n\tCGI::tag(\"element\", {\"attribute_name\"=>\"attribute_value\"}){\"content\"}\n\n\n== make HTTP header string\n\n\trequire \"cgi-lib.rb\"\n\tCGI::header # == CGI::header(\"Content-Type: text/html\")\n\tCGI::header(\"Content-Type: text/html\", cookie1, cookie2)\n\n\n=== NPH (no-parse-header) mode\n\n\tCGI::header(\"nph\") # == CGI::header(\"nph\", \"Content-Type: text/html\")\n\tCGI::header(\"nph\", \"Content-Type: text/html\", cookie1, cookie2)\n\n\n== escape url encode\n\n\trequire \"cgi-lib.rb\"\n\turl_encoded_string = CGI::escape(\"string\")\n\n\n== unescape url encoded\n\n\trequire \"cgi-lib.rb\"\n\tstring = CGI::unescape(\"url encoded string\")\n\n\n== escape HTML &\"<>\n\n\trequire \"cgi-lib.rb\"\n\tCGI::escapeHTML(\"string\")\n\n\n=end\n\nrequire \"delegate\"\n\nclass CGI < SimpleDelegator\n\n  CR  = \"\\015\"\n  LF  = \"\\012\"\n  EOL = CR + LF\n\n  RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]\n  RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]\n\n  # make rfc1123 date string\n  def CGI::rfc1123_date(time)\n    t = time.clone.gmtime\n    return format(\"%s, %.2d %s %d %.2d:%.2d:%.2d GMT\",\n                RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,\n                t.hour, t.min, t.sec)\n  end\n\n  # escape url encode\n  def CGI::escape(str)\n    str.gsub(/[^a-zA-Z0-9_\\-.]/n){ sprintf(\"%%%02X\", $&.unpack(\"C\")[0]) }\n  end\n\n  # unescape url encoded\n  def CGI::unescape(str)\n    str.gsub(/\\+/, ' ').gsub(/%([0-9a-fA-F]{2})/){ [$1.hex].pack(\"c\") }\n  end\n\n  # escape HTML\n  def CGI::escapeHTML(str)\n    str.gsub(/&/, \"&amp;\").gsub(/\\\"/, \"&quot;\").gsub(/>/, \"&gt;\").gsub(/</, \"&lt;\")\n  end\n\n  # offline mode. read name=value pairs on standard input.\n  def read_from_cmdline\n    require \"shellwords.rb\"\n    words = Shellwords.shellwords(\n              if not ARGV.empty?\n                ARGV.join(' ')\n              else\n                STDERR.print \"(offline mode: enter name=value pairs on standard input)\\n\" if STDIN.tty?\n                readlines.join(' ').gsub(/\\n/, '')\n              end.gsub(/\\\\=/, '%3D').gsub(/\\\\&/, '%26'))\n\n    if words.find{|x| x =~ /=/} then words.join('&') else words.join('+') end\n  end\n\n  def initialize(input = $stdin)\n\n    @inputs = {}\n    @cookie = {}\n\n    case ENV['REQUEST_METHOD']\n    when \"GET\"\n      ENV['QUERY_STRING'] or \"\"\n    when \"POST\"\n      input.read(Integer(ENV['CONTENT_LENGTH'])) or \"\"\n    else\n      read_from_cmdline\n    end.split(/[&;]/).each do |x|\n      key, val = x.split(/=/,2).collect{|x|CGI::unescape(x)}\n      if @inputs.include?(key)\n        @inputs[key] += \"\\0\" + (val or \"\")\n      else\n        @inputs[key] = (val or \"\")\n      end\n    end\n\n    super(@inputs)\n\n    if ENV.has_key?('HTTP_COOKIE') or ENV.has_key?('COOKIE')\n      (ENV['HTTP_COOKIE'] or ENV['COOKIE']).split(/; /).each do |x|\n        key, val = x.split(/=/,2)\n        key = CGI::unescape(key)\n        val = val.split(/&/).collect{|x|CGI::unescape(x)}.join(\"\\0\")\n        if @cookie.include?(key)\n          @cookie[key] += \"\\0\" + val\n        else\n          @cookie[key] = val\n        end\n      end\n    end\n  end\n\n  attr(\"inputs\")\n  attr(\"cookie\")\n\n  # make HTML tag string\n  def CGI::tag(element, attributes = {})\n    \"<\" + escapeHTML(element) + attributes.collect{|name, value|\n      \" \" + escapeHTML(name) + '=\"' + escapeHTML(value) + '\"'\n    }.to_s + \">\" +\n    (iterator? ? yield.to_s + \"</\" + escapeHTML(element) + \">\" : \"\")\n  end\n\n  # make raw cookie string\n  def CGI::cookie(options)\n    \"Set-Cookie: \" + options['name'] + '=' + escape(options['value']) +\n    (options['domain']  ? '; domain='  + options['domain'] : '') +\n    (options['path']    ? '; path='    + options['path']   : '') +\n    (options['expires'] ? '; expires=' + rfc1123_date(options['expires']) : '') +\n    (options['secure']  ? '; secure' : '')\n  end\n\n  # make HTTP header string\n  def CGI::header(*options)\n    if defined?(MOD_RUBY)\n      options.each{|option|\n        option.sub(/(.*?): (.*)/){\n          Apache::request.headers_out[$1] = $2\n        }\n      }\n      Apache::request.send_http_header\n      ''\n    else\n      if options.delete(\"nph\") or (ENV['SERVER_SOFTWARE'] =~ /IIS/)\n        [(ENV['SERVER_PROTOCOL'] or \"HTTP/1.0\") + \" 200 OK\",\n         \"Date: \" + rfc1123_date(Time.now),\n         \"Server: \" + (ENV['SERVER_SOFTWARE'] or \"\"),\n         \"Connection: close\"] +\n        (options.empty? ? [\"Content-Type: text/html\"] : options)\n      else\n        options.empty? ? [\"Content-Type: text/html\"] : options\n      end.join(EOL) + EOL + EOL\n    end\n  end\n\n  # print HTTP header and string to $>\n  def CGI::print(*options)\n    $>.print CGI::header(*options) + yield.to_s\n  end\n\n  # print message to $>\n  def CGI::message(message, title = \"\", header = [\"Content-Type: text/html\"])\n    if message.kind_of?(Hash)\n      title   = message['title']\n      header  = message['header']\n      message = message['body']\n    end\n    CGI::print(*header){\n      CGI::tag(\"HTML\"){\n        CGI::tag(\"HEAD\"){ CGI.tag(\"TITLE\"){ title } } +\n        CGI::tag(\"BODY\"){ message }\n      }\n    }\n    true\n  end\n\n  # print error message to $> and exit\n  def CGI::error\n    CGI::message({'title'=>'ERROR', 'body'=>\n      CGI::tag(\"PRE\"){\n        \"ERROR: \" + CGI::tag(\"STRONG\"){ escapeHTML($!.to_s) } + \"\\n\" + escapeHTML($@.join(\"\\n\"))\n      }\n    })\n    exit\n  end\nend\n"
  },
  {
    "path": "lib/cgi.rb",
    "content": "# \n# cgi.rb - cgi support library\n# \n# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n# \n# Copyright (C) 2000  Information-technology Promotion Agency, Japan\n#\n# Author: Wakou Aoyama <wakou@ruby-lang.org>\n#\n# Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber) \n# \n# == Overview\n#\n# The Common Gateway Interface (CGI) is a simple protocol\n# for passing an HTTP request from a web server to a\n# standalone program, and returning the output to the web\n# browser.  Basically, a CGI program is called with the\n# parameters of the request passed in either in the\n# environment (GET) or via $stdin (POST), and everything\n# it prints to $stdout is returned to the client.\n# \n# This file holds the +CGI+ class.  This class provides\n# functionality for retrieving HTTP request parameters,\n# managing cookies, and generating HTML output.  See the\n# class documentation for more details and examples of use.\n#\n# The file cgi/session.rb provides session management\n# functionality; see that file for more details.\n#\n# See http://www.w3.org/CGI/ for more information on the CGI\n# protocol.\n\nraise \"Please, use ruby 1.5.4 or later.\" if RUBY_VERSION < \"1.5.4\"\n\nrequire 'English'\n\n# CGI class.  See documentation for the file cgi.rb for an overview\n# of the CGI protocol.\n#\n# == Introduction\n#\n# CGI is a large class, providing several categories of methods, many of which\n# are mixed in from other modules.  Some of the documentation is in this class,\n# some in the modules CGI::QueryExtension and CGI::HtmlExtension.  See\n# CGI::Cookie for specific information on handling cookies, and cgi/session.rb\n# (CGI::Session) for information on sessions.\n#\n# For queries, CGI provides methods to get at environmental variables,\n# parameters, cookies, and multipart request data.  For responses, CGI provides\n# methods for writing output and generating HTML.\n#\n# Read on for more details.  Examples are provided at the bottom.\n#\n# == Queries\n#\n# The CGI class dynamically mixes in parameter and cookie-parsing\n# functionality,  environmental variable access, and support for\n# parsing multipart requests (including uploaded files) from the\n# CGI::QueryExtension module.\n#\n# === Environmental Variables\n#\n# The standard CGI environmental variables are available as read-only\n# attributes of a CGI object.  The following is a list of these variables:\n#\n#\n#   AUTH_TYPE               HTTP_HOST          REMOTE_IDENT\n#   CONTENT_LENGTH          HTTP_NEGOTIATE     REMOTE_USER\n#   CONTENT_TYPE            HTTP_PRAGMA        REQUEST_METHOD\n#   GATEWAY_INTERFACE       HTTP_REFERER       SCRIPT_NAME\n#   HTTP_ACCEPT             HTTP_USER_AGENT    SERVER_NAME\n#   HTTP_ACCEPT_CHARSET     PATH_INFO          SERVER_PORT\n#   HTTP_ACCEPT_ENCODING    PATH_TRANSLATED    SERVER_PROTOCOL\n#   HTTP_ACCEPT_LANGUAGE    QUERY_STRING       SERVER_SOFTWARE\n#   HTTP_CACHE_CONTROL      REMOTE_ADDR\n#   HTTP_FROM               REMOTE_HOST\n#\n#\n# For each of these variables, there is a corresponding attribute with the\n# same name, except all lower case and without a preceding HTTP_.  \n# +content_length+ and +server_port+ are integers; the rest are strings.\n#\n# === Parameters\n#\n# The method #params() returns a hash of all parameters in the request as\n# name/value-list pairs, where the value-list is an Array of one or more\n# values.  The CGI object itself also behaves as a hash of parameter names \n# to values, but only returns a single value (as a String) for each \n# parameter name.\n#\n# For instance, suppose the request contains the parameter \n# \"favourite_colours\" with the multiple values \"blue\" and \"green\".  The\n# following behaviour would occur:\n#\n#   cgi.params[\"favourite_colours\"]  # => [\"blue\", \"green\"]\n#   cgi[\"favourite_colours\"]         # => \"blue\"\n#\n# If a parameter does not exist, the former method will return an empty\n# array, the latter an empty string.  The simplest way to test for existence\n# of a parameter is by the #has_key? method.\n#\n# === Cookies\n#\n# HTTP Cookies are automatically parsed from the request.  They are available\n# from the #cookies() accessor, which returns a hash from cookie name to\n# CGI::Cookie object.\n#\n# === Multipart requests\n#\n# If a request's method is POST and its content type is multipart/form-data, \n# then it may contain uploaded files.  These are stored by the QueryExtension\n# module in the parameters of the request.  The parameter name is the name\n# attribute of the file input field, as usual.  However, the value is not\n# a string, but an IO object, either an IOString for small files, or a\n# Tempfile for larger ones.  This object also has the additional singleton\n# methods:\n#\n# #local_path():: the path of the uploaded file on the local filesystem\n# #original_filename():: the name of the file on the client computer\n# #content_type():: the content type of the file\n#\n# == Responses\n#\n# The CGI class provides methods for sending header and content output to\n# the HTTP client, and mixes in methods for programmatic HTML generation\n# from CGI::HtmlExtension and CGI::TagMaker modules.  The precise version of HTML\n# to use for HTML generation is specified at object creation time.\n#\n# === Writing output\n#\n# The simplest way to send output to the HTTP client is using the #out() method.\n# This takes the HTTP headers as a hash parameter, and the body content\n# via a block.  The headers can be generated as a string using the #header()\n# method.  The output stream can be written directly to using the #print()\n# method.\n#\n# === Generating HTML\n#\n# Each HTML element has a corresponding method for generating that\n# element as a String.  The name of this method is the same as that\n# of the element, all lowercase.  The attributes of the element are \n# passed in as a hash, and the body as a no-argument block that evaluates\n# to a String.  The HTML generation module knows which elements are\n# always empty, and silently drops any passed-in body.  It also knows\n# which elements require matching closing tags and which don't.  However,\n# it does not know what attributes are legal for which elements.\n#\n# There are also some additional HTML generation methods mixed in from\n# the CGI::HtmlExtension module.  These include individual methods for the\n# different types of form inputs, and methods for elements that commonly\n# take particular attributes where the attributes can be directly specified\n# as arguments, rather than via a hash.\n#\n# == Examples of use\n# \n# === Get form values\n# \n#   require \"cgi\"\n#   cgi = CGI.new\n#   value = cgi['field_name']   # <== value string for 'field_name'\n#     # if not 'field_name' included, then return \"\".\n#   fields = cgi.keys            # <== array of field names\n# \n#   # returns true if form has 'field_name'\n#   cgi.has_key?('field_name')\n#   cgi.has_key?('field_name')\n#   cgi.include?('field_name')\n# \n# CAUTION! cgi['field_name'] returned an Array with the old \n# cgi.rb(included in ruby 1.6)\n# \n# === Get form values as hash\n# \n#   require \"cgi\"\n#   cgi = CGI.new\n#   params = cgi.params\n# \n# cgi.params is a hash.\n# \n#   cgi.params['new_field_name'] = [\"value\"]  # add new param\n#   cgi.params['field_name'] = [\"new_value\"]  # change value\n#   cgi.params.delete('field_name')           # delete param\n#   cgi.params.clear                          # delete all params\n# \n# \n# === Save form values to file\n# \n#   require \"pstore\"\n#   db = PStore.new(\"query.db\")\n#   db.transaction do\n#     db[\"params\"] = cgi.params\n#   end\n# \n# \n# === Restore form values from file\n# \n#   require \"pstore\"\n#   db = PStore.new(\"query.db\")\n#   db.transaction do\n#     cgi.params = db[\"params\"]\n#   end\n# \n# \n# === Get multipart form values\n# \n#   require \"cgi\"\n#   cgi = CGI.new\n#   value = cgi['field_name']   # <== value string for 'field_name'\n#   value.read                  # <== body of value\n#   value.local_path            # <== path to local file of value\n#   value.original_filename     # <== original filename of value\n#   value.content_type          # <== content_type of value\n# \n# and value has StringIO or Tempfile class methods.\n# \n# === Get cookie values\n# \n#   require \"cgi\"\n#   cgi = CGI.new\n#   values = cgi.cookies['name']  # <== array of 'name'\n#     # if not 'name' included, then return [].\n#   names = cgi.cookies.keys      # <== array of cookie names\n# \n# and cgi.cookies is a hash.\n# \n# === Get cookie objects\n# \n#   require \"cgi\"\n#   cgi = CGI.new\n#   for name, cookie in cgi.cookies\n#     cookie.expires = Time.now + 30\n#   end\n#   cgi.out(\"cookie\" => cgi.cookies) {\"string\"}\n# \n#   cgi.cookies # { \"name1\" => cookie1, \"name2\" => cookie2, ... }\n# \n#   require \"cgi\"\n#   cgi = CGI.new\n#   cgi.cookies['name'].expires = Time.now + 30\n#   cgi.out(\"cookie\" => cgi.cookies['name']) {\"string\"}\n# \n# === Print http header and html string to $DEFAULT_OUTPUT ($>)\n# \n#   require \"cgi\"\n#   cgi = CGI.new(\"html3\")  # add HTML generation methods\n#   cgi.out() do\n#     cgi.html() do\n#       cgi.head{ cgi.title{\"TITLE\"} } +\n#       cgi.body() do\n#         cgi.form() do\n#           cgi.textarea(\"get_text\") +\n#           cgi.br +\n#           cgi.submit\n#         end +\n#         cgi.pre() do\n#           CGI::escapeHTML(\n#             \"params: \" + cgi.params.inspect + \"\\n\" +\n#             \"cookies: \" + cgi.cookies.inspect + \"\\n\" +\n#             ENV.collect() do |key, value|\n#               key + \" --> \" + value + \"\\n\"\n#             end.join(\"\")\n#           )\n#         end\n#       end\n#     end\n#   end\n# \n#   # add HTML generation methods\n#   CGI.new(\"html3\")    # html3.2\n#   CGI.new(\"html4\")    # html4.01 (Strict)\n#   CGI.new(\"html4Tr\")  # html4.01 Transitional\n#   CGI.new(\"html4Fr\")  # html4.01 Frameset\n#\nclass CGI\n\n  # :stopdoc:\n\n  # String for carriage return\n  CR  = \"\\015\"\n\n  # String for linefeed\n  LF  = \"\\012\"\n\n  # Standard internet newline sequence\n  EOL = CR + LF\n\n  REVISION = '$Id$' #:nodoc:\n\n  NEEDS_BINMODE = true if /WIN/ni.match(RUBY_PLATFORM) \n\n  # Path separators in different environments.\n  PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\\\', 'MACINTOSH'=>':'}\n\n  # HTTP status codes.\n  HTTP_STATUS = {\n    \"OK\"                  => \"200 OK\",\n    \"PARTIAL_CONTENT\"     => \"206 Partial Content\",\n    \"MULTIPLE_CHOICES\"    => \"300 Multiple Choices\",\n    \"MOVED\"               => \"301 Moved Permanently\",\n    \"REDIRECT\"            => \"302 Found\",\n    \"NOT_MODIFIED\"        => \"304 Not Modified\",\n    \"BAD_REQUEST\"         => \"400 Bad Request\",\n    \"AUTH_REQUIRED\"       => \"401 Authorization Required\",\n    \"FORBIDDEN\"           => \"403 Forbidden\",\n    \"NOT_FOUND\"           => \"404 Not Found\",\n    \"METHOD_NOT_ALLOWED\"  => \"405 Method Not Allowed\",\n    \"NOT_ACCEPTABLE\"      => \"406 Not Acceptable\",\n    \"LENGTH_REQUIRED\"     => \"411 Length Required\",\n    \"PRECONDITION_FAILED\" => \"412 Precondition Failed\",\n    \"SERVER_ERROR\"        => \"500 Internal Server Error\",\n    \"NOT_IMPLEMENTED\"     => \"501 Method Not Implemented\",\n    \"BAD_GATEWAY\"         => \"502 Bad Gateway\",\n    \"VARIANT_ALSO_VARIES\" => \"506 Variant Also Negotiates\"\n  }\n\n  # Abbreviated day-of-week names specified by RFC 822\n  RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ]\n\n  # Abbreviated month names specified by RFC 822\n  RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ]\n\n  # :startdoc:\n\n  def env_table \n    ENV\n  end\n\n  def stdinput\n    $stdin\n  end\n\n  def stdoutput\n    $DEFAULT_OUTPUT\n  end\n\n  private :env_table, :stdinput, :stdoutput\n\n  # URL-encode a string.\n  #   url_encoded_string = CGI::escape(\"'Stop!' said Fred\")\n  #      # => \"%27Stop%21%27+said+Fred\"\n  def CGI::escape(string)\n    string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do\n      '%' + $1.unpack('H2' * $1.size).join('%').upcase\n    end.tr(' ', '+')\n  end\n\n\n  # URL-decode a string.\n  #   string = CGI::unescape(\"%27Stop%21%27+said+Fred\")\n  #      # => \"'Stop!' said Fred\"\n  def CGI::unescape(string)\n    string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do\n      [$1.delete('%')].pack('H*')\n    end\n  end\n\n\n  # Escape special characters in HTML, namely &\\\"<>\n  #   CGI::escapeHTML('Usage: foo \"bar\" <baz>')\n  #      # => \"Usage: foo &quot;bar&quot; &lt;baz&gt;\"\n  def CGI::escapeHTML(string)\n    string.gsub(/&/n, '&amp;').gsub(/\\\"/n, '&quot;').gsub(/>/n, '&gt;').gsub(/</n, '&lt;')\n  end\n\n\n  # Unescape a string that has been HTML-escaped\n  #   CGI::unescapeHTML(\"Usage: foo &quot;bar&quot; &lt;baz&gt;\")\n  #      # => \"Usage: foo \\\"bar\\\" <baz>\"\n  def CGI::unescapeHTML(string)\n    string.gsub(/&(amp|quot|gt|lt|\\#[0-9]+|\\#x[0-9A-Fa-f]+);/n) do\n      match = $1.dup\n      case match\n      when 'amp'                 then '&'\n      when 'quot'                then '\"'\n      when 'gt'                  then '>'\n      when 'lt'                  then '<'\n      when /\\A#0*(\\d+)\\z/n       then\n        if Integer($1) < 256\n          Integer($1).chr\n        else\n          if Integer($1) < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)\n            [Integer($1)].pack(\"U\")\n          else\n            \"&##{$1};\"\n          end\n        end\n      when /\\A#x([0-9a-f]+)\\z/ni then\n        if $1.hex < 128\n          $1.hex.chr\n        else\n          if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U)\n            [$1.hex].pack(\"U\")\n          else\n            \"&#x#{$1};\"\n          end\n        end\n      else\n        \"&#{match};\"\n      end\n    end\n  end\n\n\n  # Escape only the tags of certain HTML elements in +string+.\n  #\n  # Takes an element or elements or array of elements.  Each element\n  # is specified by the name of the element, without angle brackets.\n  # This matches both the start and the end tag of that element.\n  # The attribute list of the open tag will also be escaped (for\n  # instance, the double-quotes surrounding attribute values).\n  #\n  #   print CGI::escapeElement('<BR><A HREF=\"url\"></A>', \"A\", \"IMG\")\n  #     # \"<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt\"\n  #\n  #   print CGI::escapeElement('<BR><A HREF=\"url\"></A>', [\"A\", \"IMG\"])\n  #     # \"<BR>&lt;A HREF=&quot;url&quot;&gt;&lt;/A&gt\"\n  def CGI::escapeElement(string, *elements)\n    elements = elements[0] if elements[0].kind_of?(Array)\n    unless elements.empty?\n      string.gsub(/<\\/?(?:#{elements.join(\"|\")})(?!\\w)(?:.|\\n)*?>/ni) do\n        CGI::escapeHTML($&)\n      end\n    else\n      string\n    end\n  end\n\n\n  # Undo escaping such as that done by CGI::escapeElement()\n  #\n  #   print CGI::unescapeElement(\n  #           CGI::escapeHTML('<BR><A HREF=\"url\"></A>'), \"A\", \"IMG\")\n  #     # \"&lt;BR&gt;<A HREF=\"url\"></A>\"\n  # \n  #   print CGI::unescapeElement(\n  #           CGI::escapeHTML('<BR><A HREF=\"url\"></A>'), [\"A\", \"IMG\"])\n  #     # \"&lt;BR&gt;<A HREF=\"url\"></A>\"\n  def CGI::unescapeElement(string, *elements)\n    elements = elements[0] if elements[0].kind_of?(Array)\n    unless elements.empty?\n      string.gsub(/&lt;\\/?(?:#{elements.join(\"|\")})(?!\\w)(?:.|\\n)*?&gt;/ni) do\n        CGI::unescapeHTML($&)\n      end\n    else\n      string\n    end\n  end\n\n\n  # Format a +Time+ object as a String using the format specified by RFC 1123.\n  #\n  #   CGI::rfc1123_date(Time.now)\n  #     # Sat, 01 Jan 2000 00:00:00 GMT\n  def CGI::rfc1123_date(time)\n    t = time.clone.gmtime\n    return format(\"%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT\",\n                RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,\n                t.hour, t.min, t.sec)\n  end\n\n\n  # Create an HTTP header block as a string.\n  #\n  # Includes the empty line that ends the header block.\n  #\n  # +options+ can be a string specifying the Content-Type (defaults\n  # to text/html), or a hash of header key/value pairs.  The following\n  # header keys are recognized:\n  #\n  # type:: the Content-Type header.  Defaults to \"text/html\"\n  # charset:: the charset of the body, appended to the Content-Type header.\n  # nph:: a boolean value.  If true, prepend protocol string and status code, and\n  #       date; and sets default values for \"server\" and \"connection\" if not\n  #       explicitly set.\n  # status:: the HTTP status code, returned as the Status header.  See the\n  #          list of available status codes below.\n  # server:: the server software, returned as the Server header.\n  # connection:: the connection type, returned as the Connection header (for \n  #              instance, \"close\".\n  # length:: the length of the content that will be sent, returned as the\n  #          Content-Length header.\n  # language:: the language of the content, returned as the Content-Language\n  #            header.\n  # expires:: the time on which the current content expires, as a +Time+\n  #           object, returned as the Expires header.\n  # cookie:: a cookie or cookies, returned as one or more Set-Cookie headers.\n  #          The value can be the literal string of the cookie; a CGI::Cookie\n  #          object; an Array of literal cookie strings or Cookie objects; or a \n  #          hash all of whose values are literal cookie strings or Cookie objects.\n  #          These cookies are in addition to the cookies held in the\n  #          @output_cookies field.\n  #\n  # Other header lines can also be set; they are appended as key: value.\n  # \n  #   header\n  #     # Content-Type: text/html\n  # \n  #   header(\"text/plain\")\n  #     # Content-Type: text/plain\n  # \n  #   header(\"nph\"        => true,\n  #          \"status\"     => \"OK\",  # == \"200 OK\"\n  #            # \"status\"     => \"200 GOOD\",\n  #          \"server\"     => ENV['SERVER_SOFTWARE'],\n  #          \"connection\" => \"close\",\n  #          \"type\"       => \"text/html\",\n  #          \"charset\"    => \"iso-2022-jp\",\n  #            # Content-Type: text/html; charset=iso-2022-jp\n  #          \"length\"     => 103,\n  #          \"language\"   => \"ja\",\n  #          \"expires\"    => Time.now + 30,\n  #          \"cookie\"     => [cookie1, cookie2],\n  #          \"my_header1\" => \"my_value\"\n  #          \"my_header2\" => \"my_value\")\n  # \n  # The status codes are:\n  # \n  #   \"OK\"                  --> \"200 OK\"\n  #   \"PARTIAL_CONTENT\"     --> \"206 Partial Content\"\n  #   \"MULTIPLE_CHOICES\"    --> \"300 Multiple Choices\"\n  #   \"MOVED\"               --> \"301 Moved Permanently\"\n  #   \"REDIRECT\"            --> \"302 Found\"\n  #   \"NOT_MODIFIED\"        --> \"304 Not Modified\"\n  #   \"BAD_REQUEST\"         --> \"400 Bad Request\"\n  #   \"AUTH_REQUIRED\"       --> \"401 Authorization Required\"\n  #   \"FORBIDDEN\"           --> \"403 Forbidden\"\n  #   \"NOT_FOUND\"           --> \"404 Not Found\"\n  #   \"METHOD_NOT_ALLOWED\"  --> \"405 Method Not Allowed\"\n  #   \"NOT_ACCEPTABLE\"      --> \"406 Not Acceptable\"\n  #   \"LENGTH_REQUIRED\"     --> \"411 Length Required\"\n  #   \"PRECONDITION_FAILED\" --> \"412 Precondition Failed\"\n  #   \"SERVER_ERROR\"        --> \"500 Internal Server Error\"\n  #   \"NOT_IMPLEMENTED\"     --> \"501 Method Not Implemented\"\n  #   \"BAD_GATEWAY\"         --> \"502 Bad Gateway\"\n  #   \"VARIANT_ALSO_VARIES\" --> \"506 Variant Also Negotiates\"\n  # \n  # This method does not perform charset conversion. \n  #\n  def header(options = \"text/html\")\n\n    buf = \"\"\n\n    case options\n    when String\n      options = { \"type\" => options }\n    when Hash\n      options = options.dup\n    end\n\n    unless options.has_key?(\"type\")\n      options[\"type\"] = \"text/html\"\n    end\n\n    if options.has_key?(\"charset\")\n      options[\"type\"] += \"; charset=\" + options.delete(\"charset\")\n    end\n\n    options.delete(\"nph\") if defined?(MOD_RUBY)\n    if options.delete(\"nph\") or\n        (/IIS\\/(\\d+)/n.match(env_table['SERVER_SOFTWARE']) and $1.to_i < 5)\n      buf += (env_table[\"SERVER_PROTOCOL\"] or \"HTTP/1.0\")  + \" \" +\n             (HTTP_STATUS[options[\"status\"]] or options[\"status\"] or \"200 OK\") +\n             EOL +\n             \"Date: \" + CGI::rfc1123_date(Time.now) + EOL\n\n      unless options.has_key?(\"server\")\n        options[\"server\"] = (env_table['SERVER_SOFTWARE'] or \"\")\n      end\n\n      unless options.has_key?(\"connection\")\n        options[\"connection\"] = \"close\"\n      end\n\n      options.delete(\"status\")\n    end\n\n    if options.has_key?(\"status\")\n      buf += \"Status: \" +\n             (HTTP_STATUS[options[\"status\"]] or options[\"status\"]) + EOL\n      options.delete(\"status\")\n    end\n\n    if options.has_key?(\"server\")\n      buf += \"Server: \" + options.delete(\"server\") + EOL\n    end\n\n    if options.has_key?(\"connection\")\n      buf += \"Connection: \" + options.delete(\"connection\") + EOL\n    end\n\n    buf += \"Content-Type: \" + options.delete(\"type\") + EOL\n\n    if options.has_key?(\"length\")\n      buf += \"Content-Length: \" + options.delete(\"length\").to_s + EOL\n    end\n\n    if options.has_key?(\"language\")\n      buf += \"Content-Language: \" + options.delete(\"language\") + EOL\n    end\n\n    if options.has_key?(\"expires\")\n      buf += \"Expires: \" + CGI::rfc1123_date( options.delete(\"expires\") ) + EOL\n    end\n\n    if options.has_key?(\"cookie\")\n      if options[\"cookie\"].kind_of?(String) or\n           options[\"cookie\"].kind_of?(Cookie)\n        buf += \"Set-Cookie: \" + options.delete(\"cookie\").to_s + EOL\n      elsif options[\"cookie\"].kind_of?(Array)\n        options.delete(\"cookie\").each{|cookie|\n          buf += \"Set-Cookie: \" + cookie.to_s + EOL\n        }\n      elsif options[\"cookie\"].kind_of?(Hash)\n        options.delete(\"cookie\").each_value{|cookie|\n          buf += \"Set-Cookie: \" + cookie.to_s + EOL\n        }\n      end\n    end\n    if @output_cookies\n      for cookie in @output_cookies\n        buf += \"Set-Cookie: \" + cookie.to_s + EOL\n      end\n    end\n\n    options.each{|key, value|\n      buf += key + \": \" + value.to_s + EOL\n    }\n\n    if defined?(MOD_RUBY)\n      table = Apache::request.headers_out\n      buf.scan(/([^:]+): (.+)#{EOL}/n){ |name, value|\n        warn sprintf(\"name:%s value:%s\\n\", name, value) if $DEBUG\n        case name\n        when 'Set-Cookie'\n          table.add(name, value)\n        when /^status$/ni\n          Apache::request.status_line = value\n          Apache::request.status = value.to_i\n        when /^content-type$/ni\n          Apache::request.content_type = value\n        when /^content-encoding$/ni\n          Apache::request.content_encoding = value\n        when /^location$/ni\n\t  if Apache::request.status == 200\n\t    Apache::request.status = 302\n\t  end\n          Apache::request.headers_out[name] = value\n        else\n          Apache::request.headers_out[name] = value\n        end\n      }\n      Apache::request.send_http_header\n      ''\n    else\n      buf + EOL\n    end\n\n  end # header()\n\n\n  # Print an HTTP header and body to $DEFAULT_OUTPUT ($>)\n  #\n  # The header is provided by +options+, as for #header().\n  # The body of the document is that returned by the passed-\n  # in block.  This block takes no arguments.  It is required.\n  #\n  #   cgi = CGI.new\n  #   cgi.out{ \"string\" }\n  #     # Content-Type: text/html\n  #     # Content-Length: 6\n  #     #\n  #     # string\n  # \n  #   cgi.out(\"text/plain\") { \"string\" }\n  #     # Content-Type: text/plain\n  #     # Content-Length: 6\n  #     #\n  #     # string\n  # \n  #   cgi.out(\"nph\"        => true,\n  #           \"status\"     => \"OK\",  # == \"200 OK\"\n  #           \"server\"     => ENV['SERVER_SOFTWARE'],\n  #           \"connection\" => \"close\",\n  #           \"type\"       => \"text/html\",\n  #           \"charset\"    => \"iso-2022-jp\",\n  #             # Content-Type: text/html; charset=iso-2022-jp\n  #           \"language\"   => \"ja\",\n  #           \"expires\"    => Time.now + (3600 * 24 * 30),\n  #           \"cookie\"     => [cookie1, cookie2],\n  #           \"my_header1\" => \"my_value\",\n  #           \"my_header2\" => \"my_value\") { \"string\" }\n  # \n  # Content-Length is automatically calculated from the size of\n  # the String returned by the content block.\n  #\n  # If ENV['REQUEST_METHOD'] == \"HEAD\", then only the header\n  # is outputted (the content block is still required, but it\n  # is ignored).\n  # \n  # If the charset is \"iso-2022-jp\" or \"euc-jp\" or \"shift_jis\" then\n  # the content is converted to this charset, and the language is set \n  # to \"ja\".\n  def out(options = \"text/html\") # :yield:\n\n    options = { \"type\" => options } if options.kind_of?(String)\n    content = yield\n\n    if options.has_key?(\"charset\")\n      require \"nkf\"\n      case options[\"charset\"]\n      when /iso-2022-jp/ni\n        content = NKF::nkf('-m0 -x -j', content)\n        options[\"language\"] = \"ja\" unless options.has_key?(\"language\")\n      when /euc-jp/ni\n        content = NKF::nkf('-m0 -x -e', content)\n        options[\"language\"] = \"ja\" unless options.has_key?(\"language\")\n      when /shift_jis/ni\n        content = NKF::nkf('-m0 -x -s', content)\n        options[\"language\"] = \"ja\" unless options.has_key?(\"language\")\n      end\n    end\n\n    options[\"length\"] = content.length.to_s\n    output = stdoutput\n    output.binmode if defined? output.binmode\n    output.print header(options)\n    output.print content unless \"HEAD\" == env_table['REQUEST_METHOD']\n  end\n\n\n  # Print an argument or list of arguments to the default output stream\n  #\n  #   cgi = CGI.new\n  #   cgi.print    # default:  cgi.print == $DEFAULT_OUTPUT.print\n  def print(*options)\n    stdoutput.print(*options)\n  end\n\n  require \"delegate\"\n\n  # Class representing an HTTP cookie.\n  #\n  # In addition to its specific fields and methods, a Cookie instance\n  # is a delegator to the array of its values.\n  #\n  # See RFC 2965.\n  #\n  # == Examples of use\n  #   cookie1 = CGI::Cookie::new(\"name\", \"value1\", \"value2\", ...)\n  #   cookie1 = CGI::Cookie::new(\"name\" => \"name\", \"value\" => \"value\")\n  #   cookie1 = CGI::Cookie::new('name'    => 'name',\n  #                              'value'   => ['value1', 'value2', ...],\n  #                              'path'    => 'path',   # optional\n  #                              'domain'  => 'domain', # optional\n  #                              'expires' => Time.now, # optional\n  #                              'secure'  => true      # optional\n  #                             )\n  # \n  #   cgi.out(\"cookie\" => [cookie1, cookie2]) { \"string\" }\n  # \n  #   name    = cookie1.name\n  #   values  = cookie1.value\n  #   path    = cookie1.path\n  #   domain  = cookie1.domain\n  #   expires = cookie1.expires\n  #   secure  = cookie1.secure\n  # \n  #   cookie1.name    = 'name'\n  #   cookie1.value   = ['value1', 'value2', ...]\n  #   cookie1.path    = 'path'\n  #   cookie1.domain  = 'domain'\n  #   cookie1.expires = Time.now + 30\n  #   cookie1.secure  = true\n  class Cookie < DelegateClass(Array)\n\n    # Create a new CGI::Cookie object.\n    #\n    # The contents of the cookie can be specified as a +name+ and one\n    # or more +value+ arguments.  Alternatively, the contents can\n    # be specified as a single hash argument.  The possible keywords of\n    # this hash are as follows:\n    #\n    # name:: the name of the cookie.  Required.\n    # value:: the cookie's value or list of values.\n    # path:: the path for which this cookie applies.  Defaults to the\n    #        base directory of the CGI script.\n    # domain:: the domain for which this cookie applies.\n    # expires:: the time at which this cookie expires, as a +Time+ object.\n    # secure:: whether this cookie is a secure cookie or not (default to\n    #          false).  Secure cookies are only transmitted to HTTPS \n    #          servers.\n    #\n    # These keywords correspond to attributes of the cookie object.\n    def initialize(name = \"\", *value)\n      if name.kind_of?(String)\n        @name = name\n        @value = value\n        %r|^(.*/)|.match(ENV[\"SCRIPT_NAME\"])\n        @path = ($1 or \"\")\n        @secure = false\n        return super(@value)\n      end\n\n      options = name\n      unless options.has_key?(\"name\")\n        raise ArgumentError, \"`name' required\"\n      end\n\n      @name = options[\"name\"]\n      @value = Array(options[\"value\"])\n      # simple support for IE\n      if options[\"path\"]\n        @path = options[\"path\"]\n      else\n        %r|^(.*/)|.match(ENV[\"SCRIPT_NAME\"])\n        @path = ($1 or \"\")\n      end\n      @domain = options[\"domain\"]\n      @expires = options[\"expires\"]\n      @secure = options[\"secure\"] == true ? true : false\n\n      super(@value)\n    end\n\n    attr_accessor(\"name\", \"path\", \"domain\", \"expires\")\n    attr_reader(\"secure\", \"value\")\n\n    # Set whether the Cookie is a secure cookie or not.\n    #\n    # +val+ must be a boolean.\n    def secure=(val)\n      @secure = val if val == true or val == false\n      @secure\n    end\n\n    def value=(val)\n      @value.replace(Array(val))\n    end\n\n    # Convert the Cookie to its string representation.\n    def to_s\n      buf = \"\"\n      buf += @name + '='\n\n      buf += @value.map { |v| CGI::escape(v) }.join(\"&\")\n\n      if @domain\n        buf += '; domain=' + @domain\n      end\n\n      if @path\n        buf += '; path=' + @path\n      end\n\n      if @expires\n        buf += '; expires=' + CGI::rfc1123_date(@expires)\n      end\n\n      if @secure == true\n        buf += '; secure'\n      end\n\n      buf\n    end\n\n  end # class Cookie\n\n\n  # Parse a raw cookie string into a hash of cookie-name=>Cookie\n  # pairs.\n  #\n  #   cookies = CGI::Cookie::parse(\"raw_cookie_string\")\n  #     # { \"name1\" => cookie1, \"name2\" => cookie2, ... }\n  #\n  def Cookie::parse(raw_cookie)\n    cookies = Hash.new([])\n    return cookies unless raw_cookie\n\n    raw_cookie.split(/[;,]\\s?/).each do |pairs|\n      name, values = pairs.split('=',2)\n      next unless name and values\n      name = CGI::unescape(name)\n      values ||= \"\"\n      values = values.split('&').collect{|v| CGI::unescape(v) }\n      if cookies.has_key?(name)\n        values = cookies[name].value + values\n      end\n      cookies[name] = Cookie::new(name, *values)\n    end\n\n    cookies\n  end\n\n  # Parse an HTTP query string into a hash of key=>value pairs.\n  #\n  #   params = CGI::parse(\"query_string\")\n  #     # {\"name1\" => [\"value1\", \"value2\", ...],\n  #     #  \"name2\" => [\"value1\", \"value2\", ...], ... }\n  #\n  def CGI::parse(query)\n    params = Hash.new([].freeze)\n\n    query.split(/[&;]/n).each do |pairs|\n      key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) }\n      if params.has_key?(key)\n        params[key].push(value)\n      else\n        params[key] = [value]\n      end\n    end\n\n    params\n  end\n\n  # Mixin module. It provides the follow functionality groups:\n  #\n  # 1. Access to CGI environment variables as methods.  See \n  #    documentation to the CGI class for a list of these variables.\n  #\n  # 2. Access to cookies, including the cookies attribute.\n  #\n  # 3. Access to parameters, including the params attribute, and overloading\n  #    [] to perform parameter value lookup by key.\n  #\n  # 4. The initialize_query method, for initialising the above\n  #    mechanisms, handling multipart forms, and allowing the\n  #    class to be used in \"offline\" mode.\n  #\n  module QueryExtension\n\n    %w[ CONTENT_LENGTH SERVER_PORT ].each do |env|\n      define_method(env.sub(/^HTTP_/n, '').downcase) do\n        (val = env_table[env]) && Integer(val)\n      end\n    end\n\n    %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO\n        PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST\n        REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME\n        SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE\n\n        HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING\n        HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST\n        HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env|\n      define_method(env.sub(/^HTTP_/n, '').downcase) do\n        env_table[env]\n      end\n    end\n\n    # Get the raw cookies as a string.\n    def raw_cookie\n      env_table[\"HTTP_COOKIE\"]\n    end\n\n    # Get the raw RFC2965 cookies as a string.\n    def raw_cookie2\n      env_table[\"HTTP_COOKIE2\"]\n    end\n\n    # Get the cookies as a hash of cookie-name=>Cookie pairs.\n    attr_accessor(\"cookies\")\n\n    # Get the parameters as a hash of name=>values pairs, where\n    # values is an Array.\n    attr(\"params\")\n\n    # Set all the parameters.\n    def params=(hash)\n      @params.clear\n      @params.update(hash)\n    end\n\n    def read_multipart(boundary, content_length)\n      params = Hash.new([])\n      boundary = \"--\" + boundary\n      quoted_boundary = Regexp.quote(boundary, \"n\")\n      buf = \"\"\n      bufsize = 10 * 1024\n      boundary_end=\"\"\n\n      # start multipart/form-data\n      stdinput.binmode if defined? stdinput.binmode\n      boundary_size = boundary.size + EOL.size\n      content_length -= boundary_size\n      status = stdinput.read(boundary_size)\n      if nil == status\n        raise EOFError, \"no content body\"\n      elsif boundary + EOL != status\n        raise EOFError, \"bad content body\"\n      end\n\n      loop do\n        head = nil\n        if 10240 < content_length\n          require \"tempfile\"\n          body = Tempfile.new(\"CGI\")\n        else\n          begin\n            require \"stringio\"\n            body = StringIO.new\n          rescue LoadError\n            require \"tempfile\"\n            body = Tempfile.new(\"CGI\")\n          end\n        end\n        body.binmode if defined? body.binmode\n\n        until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)\n\n          if (not head) and /#{EOL}#{EOL}/n.match(buf)\n            buf = buf.sub(/\\A((?:.|\\n)*?#{EOL})#{EOL}/n) do\n              head = $1.dup\n              \"\"\n            end\n            next\n          end\n\n          if head and ( (EOL + boundary + EOL).size < buf.size )\n            body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]\n            buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = \"\"\n          end\n\n          c = if bufsize < content_length\n                stdinput.read(bufsize)\n              else\n                stdinput.read(content_length)\n              end\n          if c.nil? || c.empty?\n            raise EOFError, \"bad content body\"\n          end\n          buf.concat(c)\n          content_length -= c.size\n        end\n\n        buf = buf.sub(/\\A((?:.|\\n)*?)(?:[\\r\\n]{1,2})?#{quoted_boundary}([\\r\\n]{1,2}|--)/n) do\n          body.print $1\n          if \"--\" == $2\n            content_length = -1\n          end\n          boundary_end = $2.dup\n          \"\"\n        end\n\n        body.rewind\n\n        /Content-Disposition:.* filename=(?:\"((?:\\\\.|[^\\\"])*)\"|([^;\\s]*))/ni.match(head)\n\tfilename = ($1 or $2 or \"\")\n\tif /Mac/ni.match(env_table['HTTP_USER_AGENT']) and\n\t    /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and\n\t    (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))\n\t  filename = CGI::unescape(filename)\n\tend\n        \n        /Content-Type: ([^\\s]*)/ni.match(head)\n        content_type = ($1 or \"\")\n\n        (class << body; self; end).class_eval do\n          alias local_path path\n          define_method(:original_filename) {filename.dup.taint}\n          define_method(:content_type) {content_type.dup.taint}\n        end\n\n        /Content-Disposition:.* name=\"?([^\\\";\\s]*)\"?/ni.match(head)\n        name = $1.dup\n\n        if params.has_key?(name)\n          params[name].push(body)\n        else\n          params[name] = [body]\n        end\n        break if buf.size == 0\n        break if content_length == -1\n      end\n      raise EOFError, \"bad boundary end of body part\" unless boundary_end=~/--/\n\n      params\n    end # read_multipart\n    private :read_multipart\n\n    # offline mode. read name=value pairs on standard input.\n    def read_from_cmdline\n      require \"shellwords\"\n\n      string = unless ARGV.empty?\n        ARGV.join(' ')\n      else\n        if STDIN.tty?\n          STDERR.print(\n            %|(offline mode: enter name=value pairs on standard input)\\n|\n          )\n        end\n        array = readlines rescue nil\n        if not array.nil?\n          array.join(' ').gsub(/\\n/n, '')\n        else\n          \"\"\n        end\n      end.gsub(/\\\\=/n, '%3D').gsub(/\\\\&/n, '%26')\n\n      words = Shellwords.shellwords(string)\n\n      if words.find{|x| /=/n.match(x) }\n        words.join('&')\n      else\n        words.join('+')\n      end\n    end\n    private :read_from_cmdline\n\n    # Initialize the data from the query.\n    #\n    # Handles multipart forms (in particular, forms that involve file uploads).\n    # Reads query parameters in the @params field, and cookies into @cookies.\n    def initialize_query()\n      if (\"POST\" == env_table['REQUEST_METHOD']) and\n         %r|\\Amultipart/form-data.*boundary=\\\"?([^\\\";,]+)\\\"?|n.match(env_table['CONTENT_TYPE'])\n        boundary = $1.dup\n        @multipart = true\n        @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))\n      else\n        @multipart = false\n        @params = CGI::parse(\n                    case env_table['REQUEST_METHOD']\n                    when \"GET\", \"HEAD\"\n                      if defined?(MOD_RUBY)\n                        Apache::request.args or \"\"\n                      else\n                        env_table['QUERY_STRING'] or \"\"\n                      end\n                    when \"POST\"\n                      stdinput.binmode if defined? stdinput.binmode\n                      stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''\n                    else\n                      read_from_cmdline\n                    end\n                  )\n      end\n\n      @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))\n    end\n    private :initialize_query\n\n    def multipart?\n      @multipart\n    end\n\n    module Value    # :nodoc:\n      def set_params(params)\n        @params = params\n      end\n      def [](idx, *args)\n        if args.size == 0\n          warn \"#{caller(1)[0]}:CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']\"\n          @params[idx]\n        else\n          super[idx,*args]\n        end\n      end\n      def first\n        warn \"#{caller(1)[0]}:CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']\"\n        self\n      end\n      alias last first\n      def to_a\n        @params || [self]\n      end\n      alias to_ary to_a   \t# to be rhs of multiple assignment\n    end\n\n    # Get the value for the parameter with a given key.\n    #\n    # If the parameter has multiple values, only the first will be \n    # retrieved; use #params() to get the array of values.\n    def [](key)\n      params = @params[key]\n      return '' unless params\n      value = params[0]\n      if @multipart\n        if value\n          return value\n        elsif defined? StringIO\n          StringIO.new(\"\")\n        else\n          Tempfile.new(\"CGI\")\n        end\n      else\n        str = if value then value.dup else \"\" end\n        str.extend(Value)\n        str.set_params(params)\n        str\n      end\n    end\n\n    # Return all parameter keys as an array.\n    def keys(*args)\n      @params.keys(*args)\n    end\n\n    # Returns true if a given parameter key exists in the query.\n    def has_key?(*args)\n      @params.has_key?(*args)\n    end\n    alias key? has_key?\n    alias include? has_key?\n\n  end # QueryExtension\n\n\n  # Prettify (indent) an HTML string.\n  #\n  # +string+ is the HTML string to indent.  +shift+ is the indentation\n  # unit to use; it defaults to two spaces.\n  #\n  #   print CGI::pretty(\"<HTML><BODY></BODY></HTML>\")\n  #     # <HTML>\n  #     #   <BODY>\n  #     #   </BODY>\n  #     # </HTML>\n  # \n  #   print CGI::pretty(\"<HTML><BODY></BODY></HTML>\", \"\\t\")\n  #     # <HTML>\n  #     #         <BODY>\n  #     #         </BODY>\n  #     # </HTML>\n  #\n  def CGI::pretty(string, shift = \"  \")\n    lines = string.gsub(/(?!\\A)<(?:.|\\n)*?>/n, \"\\n\\\\0\").gsub(/<(?:.|\\n)*?>(?!\\n)/n, \"\\\\0\\n\")\n    end_pos = 0\n    while end_pos = lines.index(/^<\\/(\\w+)/n, end_pos)\n      element = $1.dup\n      start_pos = lines.rindex(/^\\s*<#{element}/ni, end_pos)\n      lines[start_pos ... end_pos] = \"__\" + lines[start_pos ... end_pos].gsub(/\\n(?!\\z)/n, \"\\n\" + shift) + \"__\"\n    end\n    lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\\/?\\w)/n, '\\1')\n  end\n\n\n  # Base module for HTML-generation mixins.\n  #\n  # Provides methods for code generation for tags following\n  # the various DTD element types.\n  module TagMaker # :nodoc:\n\n    # Generate code for an element with required start and end tags.\n    #\n    #   - -\n    def nn_element_def(element)\n      nOE_element_def(element, <<-END)\n          if block_given?\n            yield.to_s\n          else\n            \"\"\n          end +\n          \"</#{element.upcase}>\"\n      END\n    end\n\n    # Generate code for an empty element.\n    #\n    #   - O EMPTY\n    def nOE_element_def(element, append = nil)\n      s = <<-END\n          \"<#{element.upcase}\" + attributes.collect{|name, value|\n            next unless value\n            \" \" + CGI::escapeHTML(name) +\n            if true == value\n              \"\"\n            else\n              '=\"' + CGI::escapeHTML(value) + '\"'\n            end\n          }.to_s + \">\"\n      END\n      s.sub!(/\\Z/, \" +\") << append if append\n      s\n    end\n\n    # Generate code for an element for which the end (and possibly the\n    # start) tag is optional.\n    #\n    #   O O or - O\n    def nO_element_def(element)\n      nOE_element_def(element, <<-END)\n          if block_given?\n            yield.to_s + \"</#{element.upcase}>\"\n          else\n            \"\"\n          end\n      END\n    end\n\n  end # TagMaker\n\n\n  #\n  # Mixin module providing HTML generation methods.\n  #\n  # For example,\n  #   cgi.a(\"http://www.example.com\") { \"Example\" }\n  #     # => \"<A HREF=\\\"http://www.example.com\\\">Example</A>\"\n  #\n  # Modules Http3, Http4, etc., contain more basic HTML-generation methods\n  # (:title, :center, etc.).\n  #\n  # See class CGI for a detailed example. \n  #\n  module HtmlExtension\n\n\n    # Generate an Anchor element as a string.\n    #\n    # +href+ can either be a string, giving the URL\n    # for the HREF attribute, or it can be a hash of\n    # the element's attributes.\n    #\n    # The body of the element is the string returned by the no-argument\n    # block passed in.\n    #\n    #   a(\"http://www.example.com\") { \"Example\" }\n    #     # => \"<A HREF=\\\"http://www.example.com\\\">Example</A>\"\n    #\n    #   a(\"HREF\" => \"http://www.example.com\", \"TARGET\" => \"_top\") { \"Example\" }\n    #     # => \"<A HREF=\\\"http://www.example.com\\\" TARGET=\\\"_top\\\">Example</A>\"\n    #\n    def a(href = \"\") # :yield:\n      attributes = if href.kind_of?(String)\n                     { \"HREF\" => href }\n                   else\n                     href\n                   end\n      if block_given?\n        super(attributes){ yield }\n      else\n        super(attributes)\n      end\n    end\n\n    # Generate a Document Base URI element as a String. \n    #\n    # +href+ can either by a string, giving the base URL for the HREF\n    # attribute, or it can be a has of the element's attributes.\n    #\n    # The passed-in no-argument block is ignored.\n    #\n    #   base(\"http://www.example.com/cgi\")\n    #     # => \"<BASE HREF=\\\"http://www.example.com/cgi\\\">\"\n    def base(href = \"\") # :yield:\n      attributes = if href.kind_of?(String)\n                     { \"HREF\" => href }\n                   else\n                     href\n                   end\n      if block_given?\n        super(attributes){ yield }\n      else\n        super(attributes)\n      end\n    end\n\n    # Generate a BlockQuote element as a string.\n    #\n    # +cite+ can either be a string, give the URI for the source of\n    # the quoted text, or a hash, giving all attributes of the element,\n    # or it can be omitted, in which case the element has no attributes.\n    #\n    # The body is provided by the passed-in no-argument block\n    #\n    #   blockquote(\"http://www.example.com/quotes/foo.html\") { \"Foo!\" }\n    #     #=> \"<BLOCKQUOTE CITE=\\\"http://www.example.com/quotes/foo.html\\\">Foo!</BLOCKQUOTE>\n    def blockquote(cite = nil)  # :yield:\n      attributes = if cite.kind_of?(String)\n                     { \"CITE\" => cite }\n                   else\n                     cite or \"\"\n                   end\n      if block_given?\n        super(attributes){ yield }\n      else\n        super(attributes)\n      end\n    end\n\n\n    # Generate a Table Caption element as a string.\n    #\n    # +align+ can be a string, giving the alignment of the caption\n    # (one of top, bottom, left, or right).  It can be a hash of\n    # all the attributes of the element.  Or it can be omitted.\n    #\n    # The body of the element is provided by the passed-in no-argument block.\n    #\n    #   caption(\"left\") { \"Capital Cities\" }\n    #     # => <CAPTION ALIGN=\\\"left\\\">Capital Cities</CAPTION>\n    def caption(align = nil) # :yield:\n      attributes = if align.kind_of?(String)\n                     { \"ALIGN\" => align }\n                   else\n                     align or \"\"\n                   end\n      if block_given?\n        super(attributes){ yield }\n      else\n        super(attributes)\n      end\n    end\n\n\n    # Generate a Checkbox Input element as a string.\n    #\n    # The attributes of the element can be specified as three arguments,\n    # +name+, +value+, and +checked+.  +checked+ is a boolean value;\n    # if true, the CHECKED attribute will be included in the element.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   checkbox(\"name\")\n    #     # = checkbox(\"NAME\" => \"name\")\n    # \n    #   checkbox(\"name\", \"value\")\n    #     # = checkbox(\"NAME\" => \"name\", \"VALUE\" => \"value\")\n    # \n    #   checkbox(\"name\", \"value\", true)\n    #     # = checkbox(\"NAME\" => \"name\", \"VALUE\" => \"value\", \"CHECKED\" => true)\n    def checkbox(name = \"\", value = nil, checked = nil)\n      attributes = if name.kind_of?(String)\n                     { \"TYPE\" => \"checkbox\", \"NAME\" => name,\n                       \"VALUE\" => value, \"CHECKED\" => checked }\n                   else\n                     name[\"TYPE\"] = \"checkbox\"\n                     name\n                   end\n      input(attributes)\n    end\n\n    # Generate a sequence of checkbox elements, as a String.\n    #\n    # The checkboxes will all have the same +name+ attribute.\n    # Each checkbox is followed by a label.\n    # There will be one checkbox for each value.  Each value\n    # can be specified as a String, which will be used both\n    # as the value of the VALUE attribute and as the label\n    # for that checkbox.  A single-element array has the\n    # same effect.\n    #\n    # Each value can also be specified as a three-element array.\n    # The first element is the VALUE attribute; the second is the\n    # label; and the third is a boolean specifying whether this\n    # checkbox is CHECKED.\n    #\n    # Each value can also be specified as a two-element\n    # array, by omitting either the value element (defaults\n    # to the same as the label), or the boolean checked element\n    # (defaults to false).\n    #\n    #   checkbox_group(\"name\", \"foo\", \"bar\", \"baz\")\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"foo\">foo\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"bar\">bar\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"baz\">baz\n    # \n    #   checkbox_group(\"name\", [\"foo\"], [\"bar\", true], \"baz\")\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"foo\">foo\n    #     # <INPUT TYPE=\"checkbox\" CHECKED NAME=\"name\" VALUE=\"bar\">bar\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"baz\">baz\n    # \n    #   checkbox_group(\"name\", [\"1\", \"Foo\"], [\"2\", \"Bar\", true], \"Baz\")\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"1\">Foo\n    #     # <INPUT TYPE=\"checkbox\" CHECKED NAME=\"name\" VALUE=\"2\">Bar\n    #     # <INPUT TYPE=\"checkbox\" NAME=\"name\" VALUE=\"Baz\">Baz\n    # \n    #   checkbox_group(\"NAME\" => \"name\",\n    #                    \"VALUES\" => [\"foo\", \"bar\", \"baz\"])\n    # \n    #   checkbox_group(\"NAME\" => \"name\",\n    #                    \"VALUES\" => [[\"foo\"], [\"bar\", true], \"baz\"])\n    # \n    #   checkbox_group(\"NAME\" => \"name\",\n    #                    \"VALUES\" => [[\"1\", \"Foo\"], [\"2\", \"Bar\", true], \"Baz\"])\n    def checkbox_group(name = \"\", *values)\n      if name.kind_of?(Hash)\n        values = name[\"VALUES\"]\n        name = name[\"NAME\"]\n      end\n      values.collect{|value|\n        if value.kind_of?(String)\n          checkbox(name, value) + value\n        else\n          if value[value.size - 1] == true\n            checkbox(name, value[0], true) +\n            value[value.size - 2]\n          else\n            checkbox(name, value[0]) +\n            value[value.size - 1]\n          end\n        end\n      }.to_s\n    end\n\n\n    # Generate an File Upload Input element as a string.\n    #\n    # The attributes of the element can be specified as three arguments,\n    # +name+, +size+, and +maxlength+.  +maxlength+ is the maximum length\n    # of the file's _name_, not of the file's _contents_.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    # See #multipart_form() for forms that include file uploads.\n    #\n    #   file_field(\"name\")\n    #     # <INPUT TYPE=\"file\" NAME=\"name\" SIZE=\"20\">\n    # \n    #   file_field(\"name\", 40)\n    #     # <INPUT TYPE=\"file\" NAME=\"name\" SIZE=\"40\">\n    # \n    #   file_field(\"name\", 40, 100)\n    #     # <INPUT TYPE=\"file\" NAME=\"name\" SIZE=\"40\" MAXLENGTH=\"100\">\n    # \n    #   file_field(\"NAME\" => \"name\", \"SIZE\" => 40)\n    #     # <INPUT TYPE=\"file\" NAME=\"name\" SIZE=\"40\">\n    def file_field(name = \"\", size = 20, maxlength = nil)\n      attributes = if name.kind_of?(String)\n                     { \"TYPE\" => \"file\", \"NAME\" => name,\n                       \"SIZE\" => size.to_s }\n                   else\n                     name[\"TYPE\"] = \"file\"\n                     name\n                   end\n      attributes[\"MAXLENGTH\"] = maxlength.to_s if maxlength\n      input(attributes)\n    end\n\n\n    # Generate a Form element as a string.\n    #\n    # +method+ should be either \"get\" or \"post\", and defaults to the latter.\n    # +action+ defaults to the current CGI script name.  +enctype+\n    # defaults to \"application/x-www-form-urlencoded\".  \n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    # See also #multipart_form() for forms that include file uploads.\n    #\n    #   form{ \"string\" }\n    #     # <FORM METHOD=\"post\" ENCTYPE=\"application/x-www-form-urlencoded\">string</FORM>\n    # \n    #   form(\"get\") { \"string\" }\n    #     # <FORM METHOD=\"get\" ENCTYPE=\"application/x-www-form-urlencoded\">string</FORM>\n    # \n    #   form(\"get\", \"url\") { \"string\" }\n    #     # <FORM METHOD=\"get\" ACTION=\"url\" ENCTYPE=\"application/x-www-form-urlencoded\">string</FORM>\n    # \n    #   form(\"METHOD\" => \"post\", \"ENCTYPE\" => \"enctype\") { \"string\" }\n    #     # <FORM METHOD=\"post\" ENCTYPE=\"enctype\">string</FORM>\n    def form(method = \"post\", action = script_name, enctype = \"application/x-www-form-urlencoded\")\n      attributes = if method.kind_of?(String)\n                     { \"METHOD\" => method, \"ACTION\" => action,\n                       \"ENCTYPE\" => enctype } \n                   else\n                     unless method.has_key?(\"METHOD\")\n                       method[\"METHOD\"] = \"post\"\n                     end\n                     unless method.has_key?(\"ENCTYPE\")\n                       method[\"ENCTYPE\"] = enctype\n                     end\n                     method\n                   end\n      if block_given?\n        body = yield\n      else\n        body = \"\"\n      end\n      if @output_hidden\n        body += @output_hidden.collect{|k,v|\n          \"<INPUT TYPE=\\\"HIDDEN\\\" NAME=\\\"#{k}\\\" VALUE=\\\"#{v}\\\">\"\n        }.to_s\n      end\n      super(attributes){body}\n    end\n\n    # Generate a Hidden Input element as a string.\n    #\n    # The attributes of the element can be specified as two arguments,\n    # +name+ and +value+.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   hidden(\"name\")\n    #     # <INPUT TYPE=\"hidden\" NAME=\"name\">\n    # \n    #   hidden(\"name\", \"value\")\n    #     # <INPUT TYPE=\"hidden\" NAME=\"name\" VALUE=\"value\">\n    # \n    #   hidden(\"NAME\" => \"name\", \"VALUE\" => \"reset\", \"ID\" => \"foo\")\n    #     # <INPUT TYPE=\"hidden\" NAME=\"name\" VALUE=\"value\" ID=\"foo\">\n    def hidden(name = \"\", value = nil)\n      attributes = if name.kind_of?(String)\n                     { \"TYPE\" => \"hidden\", \"NAME\" => name, \"VALUE\" => value }\n                   else\n                     name[\"TYPE\"] = \"hidden\"\n                     name\n                   end\n      input(attributes)\n    end\n\n    # Generate a top-level HTML element as a string.\n    #\n    # The attributes of the element are specified as a hash.  The\n    # pseudo-attribute \"PRETTY\" can be used to specify that the generated\n    # HTML string should be indented.  \"PRETTY\" can also be specified as\n    # a string as the sole argument to this method.  The pseudo-attribute\n    # \"DOCTYPE\", if given, is used as the leading DOCTYPE SGML tag; it\n    # should include the entire text of this tag, including angle brackets.\n    #\n    # The body of the html element is supplied as a block.\n    # \n    #   html{ \"string\" }\n    #     # <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\"><HTML>string</HTML>\n    # \n    #   html(\"LANG\" => \"ja\") { \"string\" }\n    #     # <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\"><HTML LANG=\"ja\">string</HTML>\n    # \n    #   html(\"DOCTYPE\" => false) { \"string\" }\n    #     # <HTML>string</HTML>\n    # \n    #   html(\"DOCTYPE\" => '<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">') { \"string\" }\n    #     # <!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\"><HTML>string</HTML>\n    # \n    #   html(\"PRETTY\" => \"  \") { \"<BODY></BODY>\" }\n    #     # <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n    #     # <HTML>\n    #     #   <BODY>\n    #     #   </BODY>\n    #     # </HTML>\n    # \n    #   html(\"PRETTY\" => \"\\t\") { \"<BODY></BODY>\" }\n    #     # <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n    #     # <HTML>\n    #     #         <BODY>\n    #     #         </BODY>\n    #     # </HTML>\n    # \n    #   html(\"PRETTY\") { \"<BODY></BODY>\" }\n    #     # = html(\"PRETTY\" => \"  \") { \"<BODY></BODY>\" }\n    # \n    #   html(if $VERBOSE then \"PRETTY\" end) { \"HTML string\" }\n    #\n    def html(attributes = {}) # :yield:\n      if nil == attributes\n        attributes = {}\n      elsif \"PRETTY\" == attributes\n        attributes = { \"PRETTY\" => true }\n      end\n      pretty = attributes.delete(\"PRETTY\")\n      pretty = \"  \" if true == pretty\n      buf = \"\"\n\n      if attributes.has_key?(\"DOCTYPE\")\n        if attributes[\"DOCTYPE\"]\n          buf += attributes.delete(\"DOCTYPE\")\n        else\n          attributes.delete(\"DOCTYPE\")\n        end\n      else\n        buf += doctype\n      end\n\n      if block_given?\n        buf += super(attributes){ yield }\n      else\n        buf += super(attributes)\n      end\n\n      if pretty\n        CGI::pretty(buf, pretty)\n      else\n        buf\n      end\n\n    end\n\n    # Generate an Image Button Input element as a string.\n    #\n    # +src+ is the URL of the image to use for the button.  +name+ \n    # is the input name.  +alt+ is the alternative text for the image.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    # \n    #   image_button(\"url\")\n    #     # <INPUT TYPE=\"image\" SRC=\"url\">\n    # \n    #   image_button(\"url\", \"name\", \"string\")\n    #     # <INPUT TYPE=\"image\" SRC=\"url\" NAME=\"name\" ALT=\"string\">\n    # \n    #   image_button(\"SRC\" => \"url\", \"ATL\" => \"strng\")\n    #     # <INPUT TYPE=\"image\" SRC=\"url\" ALT=\"string\">\n    def image_button(src = \"\", name = nil, alt = nil)\n      attributes = if src.kind_of?(String)\n                     { \"TYPE\" => \"image\", \"SRC\" => src, \"NAME\" => name,\n                       \"ALT\" => alt }\n                   else\n                     src[\"TYPE\"] = \"image\"\n                     src[\"SRC\"] ||= \"\"\n                     src\n                   end\n      input(attributes)\n    end\n\n\n    # Generate an Image element as a string.\n    #\n    # +src+ is the URL of the image.  +alt+ is the alternative text for\n    # the image.  +width+ is the width of the image, and +height+ is\n    # its height.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   img(\"src\", \"alt\", 100, 50)\n    #     # <IMG SRC=\"src\" ALT=\"alt\" WIDTH=\"100\" HEIGHT=\"50\">\n    # \n    #   img(\"SRC\" => \"src\", \"ALT\" => \"alt\", \"WIDTH\" => 100, \"HEIGHT\" => 50)\n    #     # <IMG SRC=\"src\" ALT=\"alt\" WIDTH=\"100\" HEIGHT=\"50\">\n    def img(src = \"\", alt = \"\", width = nil, height = nil)\n      attributes = if src.kind_of?(String)\n                     { \"SRC\" => src, \"ALT\" => alt }\n                   else\n                     src\n                   end\n      attributes[\"WIDTH\"] = width.to_s if width\n      attributes[\"HEIGHT\"] = height.to_s if height\n      super(attributes)\n    end\n\n\n    # Generate a Form element with multipart encoding as a String.\n    #\n    # Multipart encoding is used for forms that include file uploads.\n    #\n    # +action+ is the action to perform.  +enctype+ is the encoding\n    # type, which defaults to \"multipart/form-data\".\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   multipart_form{ \"string\" }\n    #     # <FORM METHOD=\"post\" ENCTYPE=\"multipart/form-data\">string</FORM>\n    # \n    #   multipart_form(\"url\") { \"string\" }\n    #     # <FORM METHOD=\"post\" ACTION=\"url\" ENCTYPE=\"multipart/form-data\">string</FORM>\n    def multipart_form(action = nil, enctype = \"multipart/form-data\")\n      attributes = if action == nil\n                     { \"METHOD\" => \"post\", \"ENCTYPE\" => enctype } \n                   elsif action.kind_of?(String)\n                     { \"METHOD\" => \"post\", \"ACTION\" => action,\n                       \"ENCTYPE\" => enctype } \n                   else\n                     unless action.has_key?(\"METHOD\")\n                       action[\"METHOD\"] = \"post\"\n                     end\n                     unless action.has_key?(\"ENCTYPE\")\n                       action[\"ENCTYPE\"] = enctype\n                     end\n                     action\n                   end\n      if block_given?\n        form(attributes){ yield }\n      else\n        form(attributes)\n      end\n    end\n\n\n    # Generate a Password Input element as a string.\n    #\n    # +name+ is the name of the input field.  +value+ is its default\n    # value.  +size+ is the size of the input field display.  +maxlength+\n    # is the maximum length of the inputted password.\n    #\n    # Alternatively, attributes can be specified as a hash.\n    #\n    #   password_field(\"name\")\n    #     # <INPUT TYPE=\"password\" NAME=\"name\" SIZE=\"40\">\n    # \n    #   password_field(\"name\", \"value\")\n    #     # <INPUT TYPE=\"password\" NAME=\"name\" VALUE=\"value\" SIZE=\"40\">\n    # \n    #   password_field(\"password\", \"value\", 80, 200)\n    #     # <INPUT TYPE=\"password\" NAME=\"name\" VALUE=\"value\" SIZE=\"80\" MAXLENGTH=\"200\">\n    # \n    #   password_field(\"NAME\" => \"name\", \"VALUE\" => \"value\")\n    #     # <INPUT TYPE=\"password\" NAME=\"name\" VALUE=\"value\">\n    def password_field(name = \"\", value = nil, size = 40, maxlength = nil)\n      attributes = if name.kind_of?(String)\n                     { \"TYPE\" => \"password\", \"NAME\" => name,\n                       \"VALUE\" => value, \"SIZE\" => size.to_s }\n                   else\n                     name[\"TYPE\"] = \"password\"\n                     name\n                   end\n      attributes[\"MAXLENGTH\"] = maxlength.to_s if maxlength\n      input(attributes)\n    end\n\n    # Generate a Select element as a string.\n    #\n    # +name+ is the name of the element.  The +values+ are the options that\n    # can be selected from the Select menu.  Each value can be a String or\n    # a one, two, or three-element Array.  If a String or a one-element\n    # Array, this is both the value of that option and the text displayed for\n    # it.  If a three-element Array, the elements are the option value, displayed\n    # text, and a boolean value specifying whether this option starts as selected.\n    # The two-element version omits either the option value (defaults to the same\n    # as the display text) or the boolean selected specifier (defaults to false).\n    #\n    # The attributes and options can also be specified as a hash.  In this\n    # case, options are specified as an array of values as described above,\n    # with the hash key of \"VALUES\".\n    #\n    #   popup_menu(\"name\", \"foo\", \"bar\", \"baz\")\n    #     # <SELECT NAME=\"name\">\n    #     #   <OPTION VALUE=\"foo\">foo</OPTION>\n    #     #   <OPTION VALUE=\"bar\">bar</OPTION>\n    #     #   <OPTION VALUE=\"baz\">baz</OPTION>\n    #     # </SELECT>\n    # \n    #   popup_menu(\"name\", [\"foo\"], [\"bar\", true], \"baz\")\n    #     # <SELECT NAME=\"name\">\n    #     #   <OPTION VALUE=\"foo\">foo</OPTION>\n    #     #   <OPTION VALUE=\"bar\" SELECTED>bar</OPTION>\n    #     #   <OPTION VALUE=\"baz\">baz</OPTION>\n    #     # </SELECT>\n    # \n    #   popup_menu(\"name\", [\"1\", \"Foo\"], [\"2\", \"Bar\", true], \"Baz\")\n    #     # <SELECT NAME=\"name\">\n    #     #   <OPTION VALUE=\"1\">Foo</OPTION>\n    #     #   <OPTION SELECTED VALUE=\"2\">Bar</OPTION>\n    #     #   <OPTION VALUE=\"Baz\">Baz</OPTION>\n    #     # </SELECT>\n    # \n    #   popup_menu(\"NAME\" => \"name\", \"SIZE\" => 2, \"MULTIPLE\" => true,\n    #               \"VALUES\" => [[\"1\", \"Foo\"], [\"2\", \"Bar\", true], \"Baz\"])\n    #     # <SELECT NAME=\"name\" MULTIPLE SIZE=\"2\">\n    #     #   <OPTION VALUE=\"1\">Foo</OPTION>\n    #     #   <OPTION SELECTED VALUE=\"2\">Bar</OPTION>\n    #     #   <OPTION VALUE=\"Baz\">Baz</OPTION>\n    #     # </SELECT>\n    def popup_menu(name = \"\", *values)\n\n      if name.kind_of?(Hash)\n        values   = name[\"VALUES\"]\n        size     = name[\"SIZE\"].to_s if name[\"SIZE\"]\n        multiple = name[\"MULTIPLE\"]\n        name     = name[\"NAME\"]\n      else\n        size = nil\n        multiple = nil\n      end\n\n      select({ \"NAME\" => name, \"SIZE\" => size,\n               \"MULTIPLE\" => multiple }){\n        values.collect{|value|\n          if value.kind_of?(String)\n            option({ \"VALUE\" => value }){ value }\n          else\n            if value[value.size - 1] == true\n              option({ \"VALUE\" => value[0], \"SELECTED\" => true }){\n                value[value.size - 2]\n              }\n            else\n              option({ \"VALUE\" => value[0] }){\n                value[value.size - 1]\n              }\n            end\n          end\n        }.to_s\n      }\n\n    end\n\n    # Generates a radio-button Input element.\n    #\n    # +name+ is the name of the input field.  +value+ is the value of\n    # the field if checked.  +checked+ specifies whether the field\n    # starts off checked.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   radio_button(\"name\", \"value\")\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"value\">\n    # \n    #   radio_button(\"name\", \"value\", true)\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"value\" CHECKED>\n    # \n    #   radio_button(\"NAME\" => \"name\", \"VALUE\" => \"value\", \"ID\" => \"foo\")\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"value\" ID=\"foo\">\n    def radio_button(name = \"\", value = nil, checked = nil)\n      attributes = if name.kind_of?(String)\n                     { \"TYPE\" => \"radio\", \"NAME\" => name,\n                       \"VALUE\" => value, \"CHECKED\" => checked }\n                   else\n                     name[\"TYPE\"] = \"radio\"\n                     name\n                   end\n      input(attributes)\n    end\n\n    # Generate a sequence of radio button Input elements, as a String.\n    #\n    # This works the same as #checkbox_group().  However, it is not valid\n    # to have more than one radiobutton in a group checked.\n    # \n    #   radio_group(\"name\", \"foo\", \"bar\", \"baz\")\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"foo\">foo\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"bar\">bar\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"baz\">baz\n    # \n    #   radio_group(\"name\", [\"foo\"], [\"bar\", true], \"baz\")\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"foo\">foo\n    #     # <INPUT TYPE=\"radio\" CHECKED NAME=\"name\" VALUE=\"bar\">bar\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"baz\">baz\n    # \n    #   radio_group(\"name\", [\"1\", \"Foo\"], [\"2\", \"Bar\", true], \"Baz\")\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"1\">Foo\n    #     # <INPUT TYPE=\"radio\" CHECKED NAME=\"name\" VALUE=\"2\">Bar\n    #     # <INPUT TYPE=\"radio\" NAME=\"name\" VALUE=\"Baz\">Baz\n    # \n    #   radio_group(\"NAME\" => \"name\",\n    #                 \"VALUES\" => [\"foo\", \"bar\", \"baz\"])\n    # \n    #   radio_group(\"NAME\" => \"name\",\n    #                 \"VALUES\" => [[\"foo\"], [\"bar\", true], \"baz\"])\n    # \n    #   radio_group(\"NAME\" => \"name\",\n    #                 \"VALUES\" => [[\"1\", \"Foo\"], [\"2\", \"Bar\", true], \"Baz\"])\n    def radio_group(name = \"\", *values)\n      if name.kind_of?(Hash)\n        values = name[\"VALUES\"]\n        name = name[\"NAME\"]\n      end\n      values.collect{|value|\n        if value.kind_of?(String)\n          radio_button(name, value) + value\n        else\n          if value[value.size - 1] == true\n            radio_button(name, value[0], true) +\n            value[value.size - 2]\n          else\n            radio_button(name, value[0]) +\n            value[value.size - 1]\n          end\n        end\n      }.to_s\n    end\n\n    # Generate a reset button Input element, as a String.\n    #\n    # This resets the values on a form to their initial values.  +value+\n    # is the text displayed on the button. +name+ is the name of this button.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   reset\n    #     # <INPUT TYPE=\"reset\">\n    # \n    #   reset(\"reset\")\n    #     # <INPUT TYPE=\"reset\" VALUE=\"reset\">\n    # \n    #   reset(\"VALUE\" => \"reset\", \"ID\" => \"foo\")\n    #     # <INPUT TYPE=\"reset\" VALUE=\"reset\" ID=\"foo\">\n    def reset(value = nil, name = nil)\n      attributes = if (not value) or value.kind_of?(String)\n                     { \"TYPE\" => \"reset\", \"VALUE\" => value, \"NAME\" => name }\n                   else\n                     value[\"TYPE\"] = \"reset\"\n                     value\n                   end\n      input(attributes)\n    end\n\n    alias scrolling_list popup_menu\n\n    # Generate a submit button Input element, as a String.\n    #\n    # +value+ is the text to display on the button.  +name+ is the name\n    # of the input.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   submit\n    #     # <INPUT TYPE=\"submit\">\n    # \n    #   submit(\"ok\")\n    #     # <INPUT TYPE=\"submit\" VALUE=\"ok\">\n    # \n    #   submit(\"ok\", \"button1\")\n    #     # <INPUT TYPE=\"submit\" VALUE=\"ok\" NAME=\"button1\">\n    # \n    #   submit(\"VALUE\" => \"ok\", \"NAME\" => \"button1\", \"ID\" => \"foo\")\n    #     # <INPUT TYPE=\"submit\" VALUE=\"ok\" NAME=\"button1\" ID=\"foo\">\n    def submit(value = nil, name = nil)\n      attributes = if (not value) or value.kind_of?(String)\n                     { \"TYPE\" => \"submit\", \"VALUE\" => value, \"NAME\" => name }\n                   else\n                     value[\"TYPE\"] = \"submit\"\n                     value\n                   end\n      input(attributes)\n    end\n\n    # Generate a text field Input element, as a String.\n    #\n    # +name+ is the name of the input field.  +value+ is its initial\n    # value.  +size+ is the size of the input area.  +maxlength+\n    # is the maximum length of input accepted.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    #   text_field(\"name\")\n    #     # <INPUT TYPE=\"text\" NAME=\"name\" SIZE=\"40\">\n    # \n    #   text_field(\"name\", \"value\")\n    #     # <INPUT TYPE=\"text\" NAME=\"name\" VALUE=\"value\" SIZE=\"40\">\n    # \n    #   text_field(\"name\", \"value\", 80)\n    #     # <INPUT TYPE=\"text\" NAME=\"name\" VALUE=\"value\" SIZE=\"80\">\n    # \n    #   text_field(\"name\", \"value\", 80, 200)\n    #     # <INPUT TYPE=\"text\" NAME=\"name\" VALUE=\"value\" SIZE=\"80\" MAXLENGTH=\"200\">\n    # \n    #   text_field(\"NAME\" => \"name\", \"VALUE\" => \"value\")\n    #     # <INPUT TYPE=\"text\" NAME=\"name\" VALUE=\"value\">\n    def text_field(name = \"\", value = nil, size = 40, maxlength = nil)\n      attributes = if name.kind_of?(String)\n                     { \"TYPE\" => \"text\", \"NAME\" => name, \"VALUE\" => value,\n                       \"SIZE\" => size.to_s }\n                   else\n                     name[\"TYPE\"] = \"text\"\n                     name\n                   end\n      attributes[\"MAXLENGTH\"] = maxlength.to_s if maxlength\n      input(attributes)\n    end\n\n    # Generate a TextArea element, as a String.\n    #\n    # +name+ is the name of the textarea.  +cols+ is the number of\n    # columns and +rows+ is the number of rows in the display.\n    #\n    # Alternatively, the attributes can be specified as a hash.\n    #\n    # The body is provided by the passed-in no-argument block\n    #\n    #   textarea(\"name\")\n    #      # = textarea(\"NAME\" => \"name\", \"COLS\" => 70, \"ROWS\" => 10)\n    #\n    #   textarea(\"name\", 40, 5)\n    #      # = textarea(\"NAME\" => \"name\", \"COLS\" => 40, \"ROWS\" => 5)\n    def textarea(name = \"\", cols = 70, rows = 10)  # :yield:\n      attributes = if name.kind_of?(String)\n                     { \"NAME\" => name, \"COLS\" => cols.to_s,\n                       \"ROWS\" => rows.to_s }\n                   else\n                     name\n                   end\n      if block_given?\n        super(attributes){ yield }\n      else\n        super(attributes)\n      end\n    end\n\n  end # HtmlExtension\n\n\n  # Mixin module for HTML version 3 generation methods.\n  module Html3 # :nodoc:\n\n    # The DOCTYPE declaration for this version of HTML\n    def doctype\n      %|<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">|\n    end\n\n    # Initialise the HTML generation methods for this version.\n    def element_init\n      extend TagMaker\n      methods = \"\"\n      # - -\n      for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG\n          DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP\n          APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE\n          STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE\n          CAPTION ]\n        methods += <<-BEGIN + nn_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # - O EMPTY\n      for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT\n          ISINDEX META ]\n        methods += <<-BEGIN + nOE_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # O O or - O\n      for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr\n          th td ]\n        methods += <<-BEGIN + nO_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n      eval(methods)\n    end\n\n  end # Html3\n\n\n  # Mixin module for HTML version 4 generation methods.\n  module Html4 # :nodoc:\n\n    # The DOCTYPE declaration for this version of HTML\n    def doctype\n      %|<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">|\n    end\n\n    # Initialise the HTML generation methods for this version.\n    def element_init\n      extend TagMaker\n      methods = \"\"\n      # - -\n      for element in %w[ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD\n        VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT\n        H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP\n        FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT\n        TEXTAREA FORM A BLOCKQUOTE CAPTION ]\n        methods += <<-BEGIN + nn_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # - O EMPTY\n      for element in %w[ IMG BASE BR AREA LINK PARAM HR INPUT COL META ]\n        methods += <<-BEGIN + nOE_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # O O or - O\n      for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY\n          COLGROUP TR TH TD HEAD]\n        methods += <<-BEGIN + nO_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n      eval(methods)\n    end\n\n  end # Html4\n\n\n  # Mixin module for HTML version 4 transitional generation methods.\n  module Html4Tr # :nodoc:\n\n    # The DOCTYPE declaration for this version of HTML\n    def doctype\n      %|<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">|\n    end\n\n    # Initialise the HTML generation methods for this version.\n    def element_init\n      extend TagMaker\n      methods = \"\"\n      # - -\n      for element in %w[ TT I B U S STRIKE BIG SMALL EM STRONG DFN\n          CODE SAMP KBD VAR CITE ABBR ACRONYM FONT SUB SUP SPAN BDO\n          ADDRESS DIV CENTER MAP OBJECT APPLET H1 H2 H3 H4 H5 H6 PRE Q\n          INS DEL DL OL UL DIR MENU LABEL SELECT OPTGROUP FIELDSET\n          LEGEND BUTTON TABLE IFRAME NOFRAMES TITLE STYLE SCRIPT\n          NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION ]\n        methods += <<-BEGIN + nn_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # - O EMPTY\n      for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT\n          COL ISINDEX META ]\n        methods += <<-BEGIN + nOE_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # O O or - O\n      for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY\n          COLGROUP TR TH TD HEAD ]\n        methods += <<-BEGIN + nO_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n      eval(methods)\n    end\n\n  end # Html4Tr\n\n\n  # Mixin module for generating HTML version 4 with framesets.\n  module Html4Fr # :nodoc:\n\n    # The DOCTYPE declaration for this version of HTML\n    def doctype\n      %|<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">|\n    end\n\n    # Initialise the HTML generation methods for this version.\n    def element_init\n      methods = \"\"\n      # - -\n      for element in %w[ FRAMESET ]\n        methods += <<-BEGIN + nn_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n\n      # - O EMPTY\n      for element in %w[ FRAME ]\n        methods += <<-BEGIN + nOE_element_def(element) + <<-END\n          def #{element.downcase}(attributes = {})\n        BEGIN\n          end\n        END\n      end\n      eval(methods)\n    end\n\n  end # Html4Fr\n\n\n  # Creates a new CGI instance.\n  #\n  # +type+ specifies which version of HTML to load the HTML generation\n  # methods for.  The following versions of HTML are supported:\n  #\n  # html3:: HTML 3.x\n  # html4:: HTML 4.0\n  # html4Tr:: HTML 4.0 Transitional\n  # html4Fr:: HTML 4.0 with Framesets\n  #\n  # If not specified, no HTML generation methods will be loaded.\n  #\n  # If the CGI object is not created in a standard CGI call environment\n  # (that is, it can't locate REQUEST_METHOD in its environment), then\n  # it will run in \"offline\" mode.  In this mode, it reads its parameters\n  # from the command line or (failing that) from standard input.  Otherwise,\n  # cookies and other parameters are parsed automatically from the standard\n  # CGI locations, which varies according to the REQUEST_METHOD.\n  def initialize(type = \"query\")\n    if defined?(MOD_RUBY) && !ENV.key?(\"GATEWAY_INTERFACE\")\n      Apache.request.setup_cgi_env\n    end\n\n    extend QueryExtension\n    @multipart = false\n    if defined?(CGI_PARAMS)\n      warn \"do not use CGI_PARAMS and CGI_COOKIES\"\n      @params = CGI_PARAMS.dup\n      @cookies = CGI_COOKIES.dup\n    else\n      initialize_query()  # set @params, @cookies\n    end\n    @output_cookies = nil\n    @output_hidden = nil\n\n    case type\n    when \"html3\"\n      extend Html3\n      element_init()\n      extend HtmlExtension\n    when \"html4\"\n      extend Html4\n      element_init()\n      extend HtmlExtension\n    when \"html4Tr\"\n      extend Html4Tr\n      element_init()\n      extend HtmlExtension\n    when \"html4Fr\"\n      extend Html4Tr\n      element_init()\n      extend Html4Fr\n      element_init()\n      extend HtmlExtension\n    end\n  end\n\nend   # class CGI\n"
  },
  {
    "path": "lib/complex.rb",
    "content": "#\n#   complex.rb - \n#   \t$Release Version: 0.5 $\n#   \t$Revision: 1.3 $\n#   \t$Date: 1998/07/08 10:05:28 $\n#   \tby Keiju ISHITSUKA(SHL Japan Inc.)\n#\n# ----\n#\n# complex.rb implements the Complex class for complex numbers.  Additionally,\n# some methods in other Numeric classes are redefined or added to allow greater\n# interoperability with Complex numbers.\n#\n# Complex numbers can be created in the following manner:\n# - <tt>Complex(a, b)</tt>\n# - <tt>Complex.polar(radius, theta)</tt>\n#   \n# Additionally, note the following:\n# - <tt>Complex::I</tt> (the mathematical constant <i>i</i>)\n# - <tt>Numeric#im</tt> (e.g. <tt>5.im -> 0+5i</tt>)\n#\n# The following +Math+ module methods are redefined to handle Complex arguments.\n# They will work as normal with non-Complex arguments.\n#    sqrt exp cos sin tan log log10\n#    cosh sinh tanh acos asin atan atan2 acosh asinh atanh\n#\n\n\n#\n# Numeric is a built-in class on which Fixnum, Bignum, etc., are based.  Here\n# some methods are added so that all number types can be treated to some extent\n# as Complex numbers.\n#\nclass Numeric\n  #\n  # Returns a Complex number <tt>(0,<i>self</i>)</tt>.\n  #\n  def im\n    Complex(0, self)\n  end\n  \n  #\n  # The real part of a complex number, i.e. <i>self</i>.\n  #\n  def real\n    self\n  end\n  \n  #\n  # The imaginary part of a complex number, i.e. 0.\n  #\n  def image\n    0\n  end\n  alias imag image\n  \n  #\n  # See Complex#arg.\n  #\n  def arg\n    Math.atan2!(0, self)\n  end\n  alias angle arg\n  \n  #\n  # See Complex#polar.\n  #\n  def polar\n    return abs, arg\n  end\n  \n  #\n  # See Complex#conjugate (short answer: returns <i>self</i>).\n  #\n  def conjugate\n    self\n  end\n  alias conj conjugate\nend\n\n\n#\n# Creates a Complex number.  +a+ and +b+ should be Numeric.  The result will be\n# <tt>a+bi</tt>.\n#\ndef Complex(a, b = 0)\n  if b == 0 and (a.kind_of?(Complex) or defined? Complex::Unify)\n    a\n  else\n    Complex.new( a.real-b.imag, a.imag+b.real )\n  end\nend\n\n#\n# The complex number class.  See complex.rb for an overview.\n#\nclass Complex < Numeric\n  @RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'\n\n  undef step\n  undef div, divmod\n  undef floor, truncate, ceil, round\n\n  def Complex.generic?(other) # :nodoc:\n    other.kind_of?(Integer) or\n    other.kind_of?(Float) or\n    (defined?(Rational) and other.kind_of?(Rational))\n  end\n\n  #\n  # Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle).\n  #\n  def Complex.polar(r, theta)\n    Complex(r*Math.cos(theta), r*Math.sin(theta))\n  end\n\n  #\n  # Creates a +Complex+ number <tt>a</tt>+<tt>b</tt><i>i</i>.\n  #\n  def Complex.new!(a, b=0)\n    new(a,b)\n  end\n\n  def initialize(a, b)\n    raise TypeError, \"non numeric 1st arg `#{a.inspect}'\" if !a.kind_of? Numeric\n    raise TypeError, \"`#{a.inspect}' for 1st arg\" if a.kind_of? Complex\n    raise TypeError, \"non numeric 2nd arg `#{b.inspect}'\" if !b.kind_of? Numeric\n    raise TypeError, \"`#{b.inspect}' for 2nd arg\" if b.kind_of? Complex\n    @real = a\n    @image = b\n  end\n\n  #\n  # Addition with real or complex number.\n  #\n  def + (other)\n    if other.kind_of?(Complex)\n      re = @real + other.real\n      im = @image + other.image\n      Complex(re, im)\n    elsif Complex.generic?(other)\n      Complex(@real + other, @image)\n    else\n      x , y = other.coerce(self)\n      x + y\n    end\n  end\n  \n  #\n  # Subtraction with real or complex number.\n  #\n  def - (other)\n    if other.kind_of?(Complex)\n      re = @real - other.real\n      im = @image - other.image\n      Complex(re, im)\n    elsif Complex.generic?(other)\n      Complex(@real - other, @image)\n    else\n      x , y = other.coerce(self)\n      x - y\n    end\n  end\n  \n  #\n  # Multiplication with real or complex number.\n  #\n  def * (other)\n    if other.kind_of?(Complex)\n      re = @real*other.real - @image*other.image\n      im = @real*other.image + @image*other.real\n      Complex(re, im)\n    elsif Complex.generic?(other)\n      Complex(@real * other, @image * other)\n    else\n      x , y = other.coerce(self)\n      x * y\n    end\n  end\n  \n  #\n  # Division by real or complex number.\n  #\n  def / (other)\n    if other.kind_of?(Complex)\n      self*other.conjugate/other.abs2\n    elsif Complex.generic?(other)\n      Complex(@real/other, @image/other)\n    else\n      x, y = other.coerce(self)\n      x/y\n    end\n  end\n  \n  def quo(other)\n    Complex(@real.quo(1), @image.quo(1)) / other\n  end\n\n  #\n  # Raise this complex number to the given (real or complex) power.\n  #\n  def ** (other)\n    if other == 0\n      return Complex(1)\n    end\n    if other.kind_of?(Complex)\n      r, theta = polar\n      ore = other.real\n      oim = other.image\n      nr = Math.exp!(ore*Math.log!(r) - oim * theta)\n      ntheta = theta*ore + oim*Math.log!(r)\n      Complex.polar(nr, ntheta)\n    elsif other.kind_of?(Integer)\n      if other > 0\n\tx = self\n\tz = x\n\tn = other - 1\n\twhile n != 0\n\t  while (div, mod = n.divmod(2)\n\t\t mod == 0)\n\t    x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image)\n\t    n = div\n\t  end\n\t  z *= x\n\t  n -= 1\n\tend\n\tz\n      else\n\tif defined? Rational\n\t  (Rational(1) / self) ** -other\n\telse\n\t  self ** Float(other)\n\tend\n      end\n    elsif Complex.generic?(other)\n      r, theta = polar\n      Complex.polar(r**other, theta*other)\n    else\n      x, y = other.coerce(self)\n      x**y\n    end\n  end\n  \n  #\n  # Remainder after division by a real or complex number.\n  #\n  def % (other)\n    if other.kind_of?(Complex)\n      Complex(@real % other.real, @image % other.image)\n    elsif Complex.generic?(other)\n      Complex(@real % other, @image % other)\n    else\n      x , y = other.coerce(self)\n      x % y\n    end\n  end\n  \n#--\n#    def divmod(other)\n#      if other.kind_of?(Complex)\n#        rdiv, rmod = @real.divmod(other.real)\n#        idiv, imod = @image.divmod(other.image)\n#        return Complex(rdiv, idiv), Complex(rmod, rmod)\n#      elsif Complex.generic?(other)\n#        Complex(@real.divmod(other), @image.divmod(other))\n#      else\n#        x , y = other.coerce(self)\n#        x.divmod(y)\n#      end\n#    end\n#++\n  \n  #\n  # Absolute value (aka modulus): distance from the zero point on the complex\n  # plane.\n  #\n  def abs\n    Math.hypot(@real, @image)\n  end\n  \n  #\n  # Square of the absolute value.\n  #\n  def abs2\n    @real*@real + @image*@image\n  end\n  \n  #\n  # Argument (angle from (1,0) on the complex plane).\n  #\n  def arg\n    Math.atan2!(@image, @real)\n  end\n  alias angle arg\n  \n  #\n  # Returns the absolute value _and_ the argument.\n  #\n  def polar\n    return abs, arg\n  end\n  \n  #\n  # Complex conjugate (<tt>z + z.conjugate = 2 * z.real</tt>).\n  #\n  def conjugate\n    Complex(@real, -@image)\n  end\n  alias conj conjugate\n  \n  #\n  # Compares the absolute values of the two numbers.\n  #\n  def <=> (other)\n    self.abs <=> other.abs\n  end\n  \n  #\n  # Test for numerical equality (<tt>a == a + 0<i>i</i></tt>).\n  #\n  def == (other)\n    if other.kind_of?(Complex)\n      @real == other.real and @image == other.image\n    elsif Complex.generic?(other)\n      @real == other and @image == 0\n    else\n      other == self\n    end\n  end\n\n  #\n  # Attempts to coerce +other+ to a Complex number.\n  #\n  def coerce(other)\n    if Complex.generic?(other)\n      return Complex.new!(other), self\n    else\n      super\n    end\n  end\n\n  #\n  # FIXME\n  #\n  def denominator\n    @real.denominator.lcm(@image.denominator)\n  end\n  \n  #\n  # FIXME\n  #\n  def numerator\n    cd = denominator\n    Complex(@real.numerator*(cd/@real.denominator),\n\t    @image.numerator*(cd/@image.denominator))\n  end\n  \n  #\n  # Standard string representation of the complex number.\n  #\n  def to_s\n    if @real != 0\n      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1\n\tif @image >= 0\n\t  @real.to_s+\"+(\"+@image.to_s+\")i\"\n\telse\n\t  @real.to_s+\"-(\"+(-@image).to_s+\")i\"\n\tend\n      else\n\tif @image >= 0\n\t  @real.to_s+\"+\"+@image.to_s+\"i\"\n\telse\n\t  @real.to_s+\"-\"+(-@image).to_s+\"i\"\n\tend\n      end\n    else\n      if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1\n\t\"(\"+@image.to_s+\")i\"\n      else\n\t@image.to_s+\"i\"\n      end\n    end\n  end\n  \n  #\n  # Returns a hash code for the complex number.\n  #\n  def hash\n    @real.hash ^ @image.hash\n  end\n  \n  #\n  # Returns \"<tt>Complex(<i>real</i>, <i>image</i>)</tt>\".\n  #\n  def inspect\n    sprintf(\"Complex(%s, %s)\", @real.inspect, @image.inspect)\n  end\n\n  \n  #\n  # +I+ is the imaginary number.  It exists at point (0,1) on the complex plane.\n  #\n  I = Complex(0,1)\n  \n  # The real part of a complex number.\n  attr :real\n\n  # The imaginary part of a complex number.\n  attr :image\n  alias imag image\n  \nend\n\nclass Integer\n\n  unless defined?(1.numerator)\n    def numerator() self end\n    def denominator() 1 end\n\n    def gcd(other)\n      min = self.abs\n      max = other.abs\n      while min > 0\n        tmp = min\n        min = max % min\n        max = tmp\n      end\n      max\n    end\n\n    def lcm(other)\n      if self.zero? or other.zero?\n        0\n      else\n        (self.div(self.gcd(other)) * other).abs\n      end\n    end\n\n  end\n\nend\n\nmodule Math\n  alias sqrt! sqrt\n  alias exp! exp\n  alias log! log\n  alias log10! log10\n  alias cos! cos\n  alias sin! sin\n  alias tan! tan\n  alias cosh! cosh\n  alias sinh! sinh\n  alias tanh! tanh\n  alias acos! acos\n  alias asin! asin\n  alias atan! atan\n  alias atan2! atan2\n  alias acosh! acosh\n  alias asinh! asinh\n  alias atanh! atanh  \n\n  # Redefined to handle a Complex argument.\n  def sqrt(z)\n    if Complex.generic?(z)\n      if z >= 0\n\tsqrt!(z)\n      else\n\tComplex(0,sqrt!(-z))\n      end\n    else\n      if z.image < 0\n\tsqrt(z.conjugate).conjugate\n      else\n\tr = z.abs\n\tx = z.real\n\tComplex( sqrt!((r+x)/2), sqrt!((r-x)/2) )\n      end\n    end\n  end\n  \n  # Redefined to handle a Complex argument.\n  def exp(z)\n    if Complex.generic?(z)\n      exp!(z)\n    else\n      Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))\n    end\n  end\n  \n  # Redefined to handle a Complex argument.\n  def cos(z)\n    if Complex.generic?(z)\n      cos!(z)\n    else\n      Complex(cos!(z.real)*cosh!(z.image),\n\t      -sin!(z.real)*sinh!(z.image))\n    end\n  end\n    \n  # Redefined to handle a Complex argument.\n  def sin(z)\n    if Complex.generic?(z)\n      sin!(z)\n    else\n      Complex(sin!(z.real)*cosh!(z.image),\n\t      cos!(z.real)*sinh!(z.image))\n    end\n  end\n  \n  # Redefined to handle a Complex argument.\n  def tan(z)\n    if Complex.generic?(z)\n      tan!(z)\n    else\n      sin(z)/cos(z)\n    end\n  end\n\n  def sinh(z)\n    if Complex.generic?(z)\n      sinh!(z)\n    else\n      Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )\n    end\n  end\n\n  def cosh(z)\n    if Complex.generic?(z)\n      cosh!(z)\n    else\n      Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )\n    end\n  end\n\n  def tanh(z)\n    if Complex.generic?(z)\n      tanh!(z)\n    else\n      sinh(z)/cosh(z)\n    end\n  end\n  \n  # Redefined to handle a Complex argument.\n  def log(z)\n    if Complex.generic?(z) and z >= 0\n      log!(z)\n    else\n      r, theta = z.polar\n      Complex(log!(r.abs), theta)\n    end\n  end\n  \n  # Redefined to handle a Complex argument.\n  def log10(z)\n    if Complex.generic?(z)\n      log10!(z)\n    else\n      log(z)/log!(10)\n    end\n  end\n\n  def acos(z)\n    if Complex.generic?(z) and z >= -1 and z <= 1\n      acos!(z)\n    else\n      -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )\n    end\n  end\n\n  def asin(z)\n    if Complex.generic?(z) and z >= -1 and z <= 1\n      asin!(z)\n    else\n      -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) )\n    end\n  end\n\n  def atan(z)\n    if Complex.generic?(z)\n      atan!(z)\n    else\n      1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0\n    end\n  end\n\n  def atan2(y,x)\n    if Complex.generic?(y) and Complex.generic?(x)\n      atan2!(y,x)\n    else\n      -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) )\n    end\n  end\n\n  def acosh(z)\n    if Complex.generic?(z) and z >= 1\n      acosh!(z)\n    else\n      log( z + sqrt(z*z-1.0) )\n    end\n  end\n\n  def asinh(z)\n    if Complex.generic?(z)\n      asinh!(z)\n    else\n      log( z + sqrt(1.0+z*z) )\n    end\n  end\n\n  def atanh(z)\n    if Complex.generic?(z) and z >= -1 and z <= 1\n      atanh!(z)\n    else\n      log( (1.0+z) / (1.0-z) ) / 2.0\n    end\n  end\n\n  module_function :sqrt!\n  module_function :sqrt\n  module_function :exp!\n  module_function :exp\n  module_function :log!\n  module_function :log\n  module_function :log10!\n  module_function :log10\n  module_function :cosh!\n  module_function :cosh\n  module_function :cos!\n  module_function :cos\n  module_function :sinh!\n  module_function :sinh\n  module_function :sin!\n  module_function :sin\n  module_function :tan!\n  module_function :tan\n  module_function :tanh!\n  module_function :tanh\n  module_function :acos!\n  module_function :acos\n  module_function :asin!\n  module_function :asin\n  module_function :atan!\n  module_function :atan\n  module_function :atan2!\n  module_function :atan2\n  module_function :acosh!\n  module_function :acosh\n  module_function :asinh!\n  module_function :asinh\n  module_function :atanh!\n  module_function :atanh\n  \nend\n\n# Documentation comments:\n#  - source: original (researched from pickaxe)\n#  - a couple of fixme's\n#  - RDoc output for Bignum etc. is a bit short, with nothing but an\n#    (undocumented) alias.  No big deal.\n"
  },
  {
    "path": "lib/csv.rb",
    "content": "# CSV -- module for generating/parsing CSV data.\n# Copyright (C) 2000-2004  NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.\n  \n# $Id$\n  \n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n  \n  \nclass CSV\n  class IllegalFormatError < RuntimeError; end\n\n  # deprecated\n  class Cell < String\n    def initialize(data = \"\", is_null = false)\n      super(is_null ? \"\" : data)\n    end\n\n    def data\n      to_s\n    end\n  end\n\n  # deprecated\n  class Row < Array\n  end\n\n  # Open a CSV formatted file for reading or writing.\n  #\n  # For reading.\n  #\n  # EXAMPLE 1\n  #   CSV.open('csvfile.csv', 'r') do |row|\n  #     p row\n  #   end\n  #\n  # EXAMPLE 2\n  #   reader = CSV.open('csvfile.csv', 'r')\n  #   row1 = reader.shift\n  #   row2 = reader.shift\n  #   if row2.empty?\n  #     p 'row2 not find.'\n  #   end\n  #   reader.close\n  #\n  # ARGS\n  #   filename: filename to parse.\n  #   col_sep: Column separator.  ?, by default.  If you want to separate\n  #     fields with semicolon, give ?; here.\n  #   row_sep: Row separator.  nil by default.  nil means \"\\r\\n or \\n\".  If you\n  #     want to separate records with \\r, give ?\\r here.\n  #\n  # RETURNS\n  #   reader instance.  To get parse result, see CSV::Reader#each.\n  #\n  #\n  # For writing.\n  #\n  # EXAMPLE 1\n  #   CSV.open('csvfile.csv', 'w') do |writer|\n  #     writer << ['r1c1', 'r1c2']\n  #     writer << ['r2c1', 'r2c2']\n  #     writer << [nil, nil]\n  #   end\n  #\n  # EXAMPLE 2\n  #   writer = CSV.open('csvfile.csv', 'w')\n  #   writer << ['r1c1', 'r1c2'] << ['r2c1', 'r2c2'] << [nil, nil]\n  #   writer.close\n  #\n  # ARGS\n  #   filename: filename to generate.\n  #   col_sep: Column separator.  ?, by default.  If you want to separate\n  #     fields with semicolon, give ?; here.\n  #   row_sep: Row separator.  nil by default.  nil means \"\\r\\n or \\n\".  If you\n  #     want to separate records with \\r, give ?\\r here.\n  #\n  # RETURNS\n  #   writer instance.  See CSV::Writer#<< and CSV::Writer#add_row to know how\n  #   to generate CSV string.\n  #\n  def CSV.open(path, mode, fs = nil, rs = nil, &block)\n    if mode == 'r' or mode == 'rb'\n      open_reader(path, mode, fs, rs, &block)\n    elsif mode == 'w' or mode == 'wb'\n      open_writer(path, mode, fs, rs, &block)\n    else\n      raise ArgumentError.new(\"'mode' must be 'r', 'rb', 'w', or 'wb'\")\n    end\n  end\n\n  def CSV.foreach(path, rs = nil, &block)\n    open_reader(path, 'r', ',', rs, &block)\n  end\n\n  def CSV.read(path, length = nil, offset = nil)\n    CSV.parse(IO.read(path, length, offset))\n  end\n  \n  def CSV.readlines(path, rs = nil)\n    reader = open_reader(path, 'r', ',', rs)\n    begin\n      reader.collect { |row| row }\n    ensure\n      reader.close\n    end\n  end\n\n  def CSV.generate(path, fs = nil, rs = nil, &block)\n    open_writer(path, 'w', fs, rs, &block)\n  end\n\n  # Parse lines from given string or stream.  Return rows as an Array of Arrays.\n  def CSV.parse(str_or_readable, fs = nil, rs = nil, &block)\n    if File.exist?(str_or_readable)\n      STDERR.puts(\"CSV.parse(filename) is deprecated.\" +\n        \"  Use CSV.open(filename, 'r') instead.\")\n      return open_reader(str_or_readable, 'r', fs, rs, &block)\n    end\n    if block\n      CSV::Reader.parse(str_or_readable, fs, rs) do |row|\n        yield(row)\n      end\n      nil\n    else\n      CSV::Reader.create(str_or_readable, fs, rs).collect { |row| row }\n    end\n  end\n\n  # Parse a line from given string.  Bear in mind it parses ONE LINE.  Rest of\n  # the string is ignored for example \"a,b\\r\\nc,d\" => ['a', 'b'] and the\n  # second line 'c,d' is ignored.\n  #\n  # If you don't know whether a target string to parse is exactly 1 line or\n  # not, use CSV.parse_row instead of this method.\n  def CSV.parse_line(src, fs = nil, rs = nil)\n    fs ||= ','\n    if fs.is_a?(Fixnum)\n      fs = fs.chr\n    end\n    if !rs.nil? and rs.is_a?(Fixnum)\n      rs = rs.chr\n    end\n    idx = 0\n    res_type = :DT_COLSEP\n    row = []\n    begin\n      while res_type == :DT_COLSEP\n        res_type, idx, cell = parse_body(src, idx, fs, rs)\n        row << cell\n      end\n    rescue IllegalFormatError\n      return []\n    end\n    row\n  end\n\n  # Create a line from cells.  each cell is stringified by to_s.\n  def CSV.generate_line(row, fs = nil, rs = nil)\n    if row.size == 0\n      return ''\n    end\n    fs ||= ','\n    if fs.is_a?(Fixnum)\n      fs = fs.chr\n    end\n    if !rs.nil? and rs.is_a?(Fixnum)\n      rs = rs.chr\n    end\n    res_type = :DT_COLSEP\n    result_str = ''\n    idx = 0\n    while true\n      generate_body(row[idx], result_str, fs, rs)\n      idx += 1\n      if (idx == row.size)\n        break\n      end\n      generate_separator(:DT_COLSEP, result_str, fs, rs)\n    end\n    result_str\n  end\n  \n  # Parse a line from string.  Consider using CSV.parse_line instead.\n  # To parse lines in CSV string, see EXAMPLE below.\n  #\n  # EXAMPLE\n  #   src = \"a,b\\r\\nc,d\\r\\ne,f\"\n  #   idx = 0\n  #   begin\n  #     parsed = []\n  #     parsed_cells, idx = CSV.parse_row(src, idx, parsed)\n  #     puts \"Parsed #{ parsed_cells } cells.\"\n  #     p parsed\n  #   end while parsed_cells > 0\n  #\n  # ARGS\n  #   src: a CSV data to be parsed.  Must respond '[](idx)'.\n  #     src[](idx) must return a char. (Not a string such as 'a', but 97).\n  #     src[](idx_out_of_bounds) must return nil.  A String satisfies this\n  #     requirement.\n  #   idx: index of parsing location of 'src'.  0 origin.\n  #   out_dev: buffer for parsed cells.  Must respond '<<(aString)'.\n  #   col_sep: Column separator.  ?, by default.  If you want to separate\n  #     fields with semicolon, give ?; here.\n  #   row_sep: Row separator.  nil by default.  nil means \"\\r\\n or \\n\".  If you\n  #     want to separate records with \\r, give ?\\r here.\n  #\n  # RETURNS\n  #   parsed_cells: num of parsed cells.\n  #   idx: index of next parsing location of 'src'.\n  #\n  def CSV.parse_row(src, idx, out_dev, fs = nil, rs = nil)\n    fs ||= ','\n    if fs.is_a?(Fixnum)\n      fs = fs.chr\n    end\n    if !rs.nil? and rs.is_a?(Fixnum)\n      rs = rs.chr\n    end\n    idx_backup = idx\n    parsed_cells = 0\n    res_type = :DT_COLSEP\n    begin\n      while res_type != :DT_ROWSEP\n        res_type, idx, cell = parse_body(src, idx, fs, rs)\n        if res_type == :DT_EOS\n          if idx == idx_backup #((parsed_cells == 0) and cell.nil?)\n            return 0, 0\n          end\n          res_type = :DT_ROWSEP\n        end\n        parsed_cells += 1\n        out_dev << cell\n      end\n    rescue IllegalFormatError\n      return 0, 0\n    end\n    return parsed_cells, idx\n  end\n  \n  # Convert a line from cells data to string.  Consider using CSV.generate_line\n  # instead.  To generate multi-row CSV string, see EXAMPLE below.\n  #\n  # EXAMPLE\n  #   row1 = ['a', 'b']\n  #   row2 = ['c', 'd']\n  #   row3 = ['e', 'f']\n  #   src = [row1, row2, row3]\n  #   buf = ''\n  #   src.each do |row|\n  #     parsed_cells = CSV.generate_row(row, 2, buf)\n  #     puts \"Created #{ parsed_cells } cells.\"\n  #   end\n  #   p buf\n  #\n  # ARGS\n  #   src: an Array of String to be converted to CSV string.  Must respond to\n  #     'size' and '[](idx)'.  src[idx] must return String.\n  #   cells: num of cells in a line.\n  #   out_dev: buffer for generated CSV string.  Must respond to '<<(string)'.\n  #   col_sep: Column separator.  ?, by default.  If you want to separate\n  #     fields with semicolon, give ?; here.\n  #   row_sep: Row separator.  nil by default.  nil means \"\\r\\n or \\n\".  If you\n  #     want to separate records with \\r, give ?\\r here.\n  #\n  # RETURNS\n  #   parsed_cells: num of converted cells.\n  #\n  def CSV.generate_row(src, cells, out_dev, fs = nil, rs = nil)\n    fs ||= ','\n    if fs.is_a?(Fixnum)\n      fs = fs.chr\n    end\n    if !rs.nil? and rs.is_a?(Fixnum)\n      rs = rs.chr\n    end\n    src_size = src.size\n    if (src_size == 0)\n      if cells == 0\n        generate_separator(:DT_ROWSEP, out_dev, fs, rs)\n      end\n      return 0\n    end\n    res_type = :DT_COLSEP\n    parsed_cells = 0\n    generate_body(src[parsed_cells], out_dev, fs, rs)\n    parsed_cells += 1\n    while ((parsed_cells < cells) and (parsed_cells != src_size))\n      generate_separator(:DT_COLSEP, out_dev, fs, rs)\n      generate_body(src[parsed_cells], out_dev, fs, rs)\n      parsed_cells += 1\n    end\n    if (parsed_cells == cells)\n      generate_separator(:DT_ROWSEP, out_dev, fs, rs)\n    else\n      generate_separator(:DT_COLSEP, out_dev, fs, rs)\n    end\n    parsed_cells\n  end\n  \n  # Private class methods.\n  class << self\n  private\n\n    def open_reader(path, mode, fs, rs, &block)\n      file = File.open(path, mode)\n      if block\n        begin\n          CSV::Reader.parse(file, fs, rs) do |row|\n            yield(row)\n          end\n        ensure\n          file.close\n        end\n        nil\n      else\n        reader = CSV::Reader.create(file, fs, rs)\n        reader.close_on_terminate\n        reader\n      end\n    end\n\n    def open_writer(path, mode, fs, rs, &block)\n      file = File.open(path, mode)\n      if block\n        begin\n          CSV::Writer.generate(file, fs, rs) do |writer|\n            yield(writer)\n          end\n        ensure\n          file.close\n        end\n        nil\n      else\n        writer = CSV::Writer.create(file, fs, rs) \n        writer.close_on_terminate\n        writer\n      end\n    end\n\n    def parse_body(src, idx, fs, rs)\n      fs_str = fs\n      fs_size = fs_str.size\n      rs_str = rs || \"\\n\"\n      rs_size = rs_str.size\n      fs_idx = rs_idx = 0\n      cell = Cell.new\n      state = :ST_START\n      quoted = cr = false\n      c = nil\n      last_idx = idx\n      while c = src[idx]\n        unless quoted\n          fschar = (c == fs_str[fs_idx])\n          rschar = (c == rs_str[rs_idx])\n          # simple 1 char backtrack\n          if !fschar and c == fs_str[0]\n            fs_idx = 0\n            fschar = true\n            if state == :ST_START\n              state = :ST_DATA\n            elsif state == :ST_QUOTE\n              raise IllegalFormatError\n            end\n          end\n          if !rschar and c == rs_str[0]\n            rs_idx = 0\n            rschar = true\n            if state == :ST_START\n              state = :ST_DATA\n            elsif state == :ST_QUOTE\n              raise IllegalFormatError\n            end\n          end\n        end\n        if c == ?\"\n          fs_idx = rs_idx = 0\n          if cr\n            raise IllegalFormatError\n          end\n          cell << src[last_idx, (idx - last_idx)]\n          last_idx = idx\n          if state == :ST_DATA\n            if quoted\n              last_idx += 1\n              quoted = false\n              state = :ST_QUOTE\n            else\n              raise IllegalFormatError\n            end\n          elsif state == :ST_QUOTE\n            cell << c.chr\n            last_idx += 1\n            quoted = true\n            state = :ST_DATA\n          else  # :ST_START\n            quoted = true\n            last_idx += 1\n            state = :ST_DATA\n          end\n        elsif fschar or rschar\n          if fschar\n            fs_idx += 1\n          end\n          if rschar\n            rs_idx += 1\n          end\n          sep = nil\n          if fs_idx == fs_size\n            if state == :ST_START and rs_idx > 0 and fs_idx < rs_idx\n              state = :ST_DATA\n            end\n            cell << src[last_idx, (idx - last_idx - (fs_size - 1))]\n            last_idx = idx\n            fs_idx = rs_idx = 0\n            if cr\n              raise IllegalFormatError\n            end\n            sep = :DT_COLSEP\n          elsif rs_idx == rs_size\n            if state == :ST_START and fs_idx > 0 and rs_idx < fs_idx\n              state = :ST_DATA\n            end\n            if !(rs.nil? and cr)\n              cell << src[last_idx, (idx - last_idx - (rs_size - 1))]\n              last_idx = idx\n            end\n            fs_idx = rs_idx = 0\n            sep = :DT_ROWSEP\n          end\n          if sep\n            if state == :ST_DATA\n              return sep, idx + 1, cell;\n            elsif state == :ST_QUOTE\n              return sep, idx + 1, cell;\n            else  # :ST_START\n              return sep, idx + 1, nil\n            end\n          end\n        elsif rs.nil? and c == ?\\r\n          # special \\r treatment for backward compatibility\n          fs_idx = rs_idx = 0\n          if cr\n            raise IllegalFormatError\n          end\n          cell << src[last_idx, (idx - last_idx)]\n          last_idx = idx\n          if quoted\n            state = :ST_DATA\n          else\n            cr = true\n          end\n        else\n          fs_idx = rs_idx = 0\n          if state == :ST_DATA or state == :ST_START\n            if cr\n              raise IllegalFormatError\n            end\n            state = :ST_DATA\n          else  # :ST_QUOTE\n            raise IllegalFormatError\n          end\n        end\n        idx += 1\n      end\n      if state == :ST_START\n        if fs_idx > 0 or rs_idx > 0\n          state = :ST_DATA\n        else\n          return :DT_EOS, idx, nil\n        end\n      elsif quoted\n        raise IllegalFormatError\n      elsif cr\n        raise IllegalFormatError\n      end\n      cell << src[last_idx, (idx - last_idx)]\n      last_idx = idx\n      return :DT_EOS, idx, cell\n    end\n  \n    def generate_body(cell, out_dev, fs, rs)\n      if cell.nil?\n        # empty\n      else\n        cell = cell.to_s\n        row_data = cell.dup\n        if (row_data.gsub!('\"', '\"\"') or\n            row_data.index(fs) or\n            (rs and row_data.index(rs)) or\n            (/[\\r\\n]/ =~ row_data) or\n            (cell.empty?))\n          out_dev << '\"' << row_data << '\"'\n        else\n          out_dev << row_data\n        end\n      end\n    end\n    \n    def generate_separator(type, out_dev, fs, rs)\n      case type\n      when :DT_COLSEP\n        out_dev << fs\n      when :DT_ROWSEP\n        out_dev << (rs || \"\\n\")\n      end\n    end\n  end\n\n\n  # CSV formatted string/stream reader.\n  #\n  # EXAMPLE\n  #   read CSV lines untill the first column is 'stop'.\n  #\n  #   CSV::Reader.parse(File.open('bigdata', 'rb')) do |row|\n  #     p row\n  #     break if !row[0].is_null && row[0].data == 'stop'\n  #   end\n  #\n  class Reader\n    include Enumerable\n\n    # Parse CSV data and get lines.  Given block is called for each parsed row.\n    # Block value is always nil.  Rows are not cached for performance reason.\n    def Reader.parse(str_or_readable, fs = ',', rs = nil, &block)\n      reader = Reader.create(str_or_readable, fs, rs)\n      if block\n        reader.each do |row|\n          yield(row)\n        end\n        reader.close\n        nil\n      else\n        reader\n      end\n    end\n\n    # Returns reader instance.\n    def Reader.create(str_or_readable, fs = ',', rs = nil)\n      case str_or_readable\n      when IO\n        IOReader.new(str_or_readable, fs, rs)\n      when String\n        StringReader.new(str_or_readable, fs, rs)\n      else\n        IOReader.new(str_or_readable, fs, rs)\n      end\n    end\n\n    def each\n      while true\n        row = []\n        parsed_cells = get_row(row)\n        if parsed_cells == 0\n          break\n        end\n        yield(row)\n      end\n      nil\n    end\n\n    def shift\n      row = []\n      parsed_cells = get_row(row)\n      row\n    end\n\n    def close\n      terminate\n    end\n\n  private\n\n    def initialize(dev)\n      raise RuntimeError.new('Do not instanciate this class directly.')\n    end\n\n    def get_row(row)\n      raise NotImplementedError.new('Method get_row must be defined in a derived class.')\n    end\n\n    def terminate\n      # Define if needed.\n    end\n  end\n  \n\n  class StringReader < Reader\n    def initialize(string, fs = ',', rs = nil)\n      @fs = fs\n      @rs = rs\n      @dev = string\n      @idx = 0\n      if @dev[0, 3] == \"\\xef\\xbb\\xbf\"\n        @idx += 3\n      end\n    end\n\n  private\n\n    def get_row(row)\n      parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs)\n      if parsed_cells == 0 and next_idx == 0 and @idx != @dev.size\n        raise IllegalFormatError.new\n      end\n      @idx = next_idx\n      parsed_cells\n    end\n  end\n\n\n  class IOReader < Reader\n    def initialize(io, fs = ',', rs = nil)\n      @io = io\n      @fs = fs\n      @rs = rs\n      @dev = CSV::IOBuf.new(@io)\n      @idx = 0\n      if @dev[0] == 0xef and @dev[1] == 0xbb and @dev[2] == 0xbf\n        @idx += 3\n      end\n      @close_on_terminate = false\n    end\n\n    # Tell this reader to close the IO when terminated (Triggered by invoking\n    # CSV::IOReader#close).\n    def close_on_terminate\n      @close_on_terminate = true\n    end\n\n  private\n\n    def get_row(row)\n      parsed_cells, next_idx = CSV.parse_row(@dev, @idx, row, @fs, @rs)\n      if parsed_cells == 0 and next_idx == 0 and !@dev.is_eos?\n        raise IllegalFormatError.new\n      end\n      dropped = @dev.drop(next_idx)\n      @idx = next_idx - dropped\n      parsed_cells\n    end\n\n    def terminate\n      if @close_on_terminate\n        @io.close\n      end\n\n      if @dev\n        @dev.close\n      end\n    end\n  end\n\n\n  # CSV formatted string/stream writer.\n  #\n  # EXAMPLE\n  #   Write rows to 'csvout' file.\n  #\n  #   outfile = File.open('csvout', 'wb')\n  #   CSV::Writer.generate(outfile) do |csv|\n  #     csv << ['c1', nil, '', '\"', \"\\r\\n\", 'c2']\n  #     ...\n  #   end\n  #\n  #   outfile.close\n  #\n  class Writer\n    # Given block is called with the writer instance.  str_or_writable must\n    # handle '<<(string)'.\n    def Writer.generate(str_or_writable, fs = ',', rs = nil, &block)\n      writer = Writer.create(str_or_writable, fs, rs)\n      if block\n        yield(writer)\n        writer.close\n        nil\n      else\n        writer\n      end\n    end\n\n    # str_or_writable must handle '<<(string)'.\n    def Writer.create(str_or_writable, fs = ',', rs = nil)\n      BasicWriter.new(str_or_writable, fs, rs)\n    end\n\n    # dump CSV stream to the device.  argument must be an Array of String.\n    def <<(row)\n      CSV.generate_row(row, row.size, @dev, @fs, @rs)\n      self\n    end\n    alias add_row <<\n\n    def close\n      terminate\n    end\n\n  private\n\n    def initialize(dev)\n      raise RuntimeError.new('Do not instanciate this class directly.')\n    end\n\n    def terminate\n      # Define if needed.\n    end\n  end\n\n\n  class BasicWriter < Writer\n    def initialize(str_or_writable, fs = ',', rs = nil)\n      @fs = fs\n      @rs = rs\n      @dev = str_or_writable\n      @close_on_terminate = false\n    end\n\n    # Tell this writer to close the IO when terminated (Triggered by invoking\n    # CSV::BasicWriter#close).\n    def close_on_terminate\n      @close_on_terminate = true\n    end\n\n  private\n\n    def terminate\n      if @close_on_terminate\n        @dev.close\n      end\n    end\n  end\n\nprivate\n\n  # Buffered stream.\n  #\n  # EXAMPLE 1 -- an IO.\n  #   class MyBuf < StreamBuf\n  #     # Do initialize myself before a super class.  Super class might call my\n  #     # method 'read'. (Could be awful for C++ user. :-)\n  #     def initialize(s)\n  #       @s = s\n  #       super()\n  #     end\n  #\n  #     # define my own 'read' method.\n  #     # CAUTION: Returning nil means EnfOfStream.\n  #     def read(size)\n  #       @s.read(size)\n  #     end\n  #\n  #     # release buffers. in Ruby which has GC, you do not have to call this...\n  #     def terminate\n  #       @s = nil\n  #       super()\n  #     end\n  #   end\n  #\n  #   buf = MyBuf.new(STDIN)\n  #   my_str = ''\n  #   p buf[0, 0]               # => '' (null string)\n  #   p buf[0]                  # => 97 (char code of 'a')\n  #   p buf[0, 1]               # => 'a'\n  #   my_str = buf[0, 5]\n  #   p my_str                  # => 'abcde' (5 chars)\n  #   p buf[0, 6]               # => \"abcde\\n\" (6 chars)\n  #   p buf[0, 7]               # => \"abcde\\n\" (6 chars)\n  #   p buf.drop(3)             # => 3 (dropped chars)\n  #   p buf.get(0, 2)           # => 'de' (2 chars)\n  #   p buf.is_eos?             # => false (is not EOS here)\n  #   p buf.drop(5)             # => 3 (dropped chars)\n  #   p buf.is_eos?             # => true (is EOS here)\n  #   p buf[0]                  # => nil (is EOS here)\n  #\n  # EXAMPLE 2 -- String.\n  #   This is a conceptual example.  No pros with this.\n  #\n  #   class StrBuf < StreamBuf\n  #     def initialize(s)\n  #       @str = s\n  #       @idx = 0\n  #       super()\n  #     end\n  #\n  #     def read(size)\n  #       str = @str[@idx, size]\n  #       @idx += str.size\n  #       str\n  #     end\n  #   end\n  #\n  class StreamBuf\n    # get a char or a partial string from the stream.\n    # idx: index of a string to specify a start point of a string to get.\n    # unlike String instance, idx < 0 returns nil.\n    # n: size of a string to get.\n    # returns char at idx if n == nil.\n    # returns a partial string, from idx to (idx + n) if n != nil.  at EOF,\n    # the string size could not equal to arg n.\n    def [](idx, n = nil) \n      if idx < 0\n        return nil\n      end\n      if (idx_is_eos?(idx))\n        if n and (@offset + idx == buf_size(@cur_buf))\n          # Like a String, 'abc'[4, 1] returns nil and\n          # 'abc'[3, 1] returns '' not nil.\n          return ''\n        else\n          return nil\n        end\n      end\n      my_buf = @cur_buf\n      my_offset = @offset\n      next_idx = idx\n      while (my_offset + next_idx >= buf_size(my_buf))\n        if (my_buf == @buf_tail_idx)\n          unless add_buf\n            break\n          end\n        end\n        next_idx = my_offset + next_idx - buf_size(my_buf)\n        my_buf += 1\n        my_offset = 0\n      end\n      loc = my_offset + next_idx\n      if !n\n        return @buf_list[my_buf][loc]           # Fixnum of char code.\n      elsif (loc + n - 1 < buf_size(my_buf))\n        return @buf_list[my_buf][loc, n]        # String.\n      else # should do loop insted of (tail) recursive call...\n        res = @buf_list[my_buf][loc, BufSize]\n        size_added = buf_size(my_buf) - loc\n        if size_added > 0\n          idx += size_added\n          n -= size_added\n          ret = self[idx, n]\n          if ret\n            res << ret\n          end\n        end\n        return res\n      end\n    end\n    alias get []\n  \n    # drop a string from the stream.\n    # returns dropped size.  at EOF, dropped size might not equals to arg n.\n    # Once you drop the head of the stream, access to the dropped part via []\n    # or get returns nil.\n    def drop(n)\n      if is_eos?\n        return 0\n      end\n      size_dropped = 0\n      while (n > 0)\n        if !@is_eos or (@cur_buf != @buf_tail_idx)\n          if (@offset + n < buf_size(@cur_buf))\n            size_dropped += n\n            @offset += n\n            n = 0\n          else\n            size = buf_size(@cur_buf) - @offset\n            size_dropped += size\n            n -= size\n            @offset = 0\n            unless rel_buf\n              unless add_buf\n                break\n              end\n              @cur_buf = @buf_tail_idx\n            end\n          end\n        end\n      end\n      size_dropped\n    end\n  \n    def is_eos?\n      return idx_is_eos?(0)\n    end\n  \n    # WARN: Do not instantiate this class directly.  Define your own class\n    # which derives this class and define 'read' instance method.\n    def initialize\n      @buf_list = []\n      @cur_buf = @buf_tail_idx = -1\n      @offset = 0\n      @is_eos = false\n      add_buf\n      @cur_buf = @buf_tail_idx\n    end\n  \n  protected\n\n    def terminate\n      while (rel_buf); end\n    end\n  \n    # protected method 'read' must be defined in derived classes.\n    # CAUTION: Returning a string which size is not equal to 'size' means\n    # EnfOfStream.  When it is not at EOS, you must block the callee, try to\n    # read and return the sized string.\n    def read(size) # raise EOFError\n      raise NotImplementedError.new('Method read must be defined in a derived class.')\n    end\n  \n  private\n  \n    def buf_size(idx)\n      @buf_list[idx].size\n    end\n\n    def add_buf\n      if @is_eos\n        return false\n      end\n      begin\n        str_read = read(BufSize)\n      rescue EOFError\n        str_read = nil\n      rescue\n        terminate\n        raise\n      end\n      if str_read.nil?\n        @is_eos = true\n        @buf_list.push('')\n        @buf_tail_idx += 1\n        false\n      else\n        @buf_list.push(str_read)\n        @buf_tail_idx += 1\n        true\n      end\n    end\n  \n    def rel_buf\n      if (@cur_buf < 0)\n        return false\n      end\n      @buf_list[@cur_buf] = nil\n      if (@cur_buf == @buf_tail_idx)\n        @cur_buf = -1\n        return false\n      else\n        @cur_buf += 1\n        return true\n      end\n    end\n  \n    def idx_is_eos?(idx)\n      (@is_eos and ((@cur_buf < 0) or (@cur_buf == @buf_tail_idx)))\n    end\n  \n    BufSize = 1024 * 8\n  end\n\n  # Buffered IO.\n  #\n  # EXAMPLE\n  #   # File 'bigdata' could be a giga-byte size one!\n  #   buf = CSV::IOBuf.new(File.open('bigdata', 'rb'))\n  #   CSV::Reader.new(buf).each do |row|\n  #     p row\n  #     break if row[0].data == 'admin'\n  #   end\n  #\n  class IOBuf < StreamBuf\n    def initialize(s)\n      @s = s\n      super()\n    end\n  \n    def close\n      terminate\n    end\n\n  private\n\n    def read(size)\n      @s.read(size)\n    end\n \n    def terminate\n      super()\n    end\n  end\nend\n"
  },
  {
    "path": "lib/date/format.rb",
    "content": "# format.rb: Written by Tadayoshi Funaba 1999-2008\n# $Id: format.rb,v 2.43 2008-01-17 20:16:31+09 tadf Exp $\n\nrequire 'rational'\n\nclass Date\n\n  module Format # :nodoc:\n\n    MONTHS = {\n      'january'  => 1, 'february' => 2, 'march'    => 3, 'april'    => 4,\n      'may'      => 5, 'june'     => 6, 'july'     => 7, 'august'   => 8,\n      'september'=> 9, 'october'  =>10, 'november' =>11, 'december' =>12\n    }\n\n    DAYS = {\n      'sunday'   => 0, 'monday'   => 1, 'tuesday'  => 2, 'wednesday'=> 3,\n      'thursday' => 4, 'friday'   => 5, 'saturday' => 6\n    }\n\n    ABBR_MONTHS = {\n      'jan'      => 1, 'feb'      => 2, 'mar'      => 3, 'apr'      => 4,\n      'may'      => 5, 'jun'      => 6, 'jul'      => 7, 'aug'      => 8,\n      'sep'      => 9, 'oct'      =>10, 'nov'      =>11, 'dec'      =>12\n    }\n\n    ABBR_DAYS = {\n      'sun'      => 0, 'mon'      => 1, 'tue'      => 2, 'wed'      => 3,\n      'thu'      => 4, 'fri'      => 5, 'sat'      => 6\n    }\n\n    ZONES = {\n      'ut'  =>  0*3600, 'gmt' =>  0*3600, 'est' => -5*3600, 'edt' => -4*3600,\n      'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,\n      'pst' => -8*3600, 'pdt' => -7*3600,\n      'a'   =>  1*3600, 'b'   =>  2*3600, 'c'   =>  3*3600, 'd'   =>  4*3600,\n      'e'   =>  5*3600, 'f'   =>  6*3600, 'g'   =>  7*3600, 'h'   =>  8*3600,\n      'i'   =>  9*3600, 'k'   => 10*3600, 'l'   => 11*3600, 'm'   => 12*3600,\n      'n'   => -1*3600, 'o'   => -2*3600, 'p'   => -3*3600, 'q'   => -4*3600,\n      'r'   => -5*3600, 's'   => -6*3600, 't'   => -7*3600, 'u'   => -8*3600,\n      'v'   => -9*3600, 'w'   =>-10*3600, 'x'   =>-11*3600, 'y'   =>-12*3600,\n      'z'   =>  0*3600,\n\n      'utc' =>  0*3600, 'wet' =>  0*3600,\n      'at'  => -2*3600, 'brst'=> -2*3600, 'ndt' => -(2*3600+1800),\n      'art' => -3*3600, 'adt' => -3*3600, 'brt' => -3*3600, 'clst'=> -3*3600,\n      'nst' => -(3*3600+1800),\n      'ast' => -4*3600, 'clt' => -4*3600,\n      'akdt'=> -8*3600, 'ydt' => -8*3600,\n      'akst'=> -9*3600, 'hadt'=> -9*3600, 'hdt' => -9*3600, 'yst' => -9*3600,\n      'ahst'=>-10*3600, 'cat' =>-10*3600, 'hast'=>-10*3600, 'hst' =>-10*3600,\n      'nt'  =>-11*3600,\n      'idlw'=>-12*3600,\n      'bst' =>  1*3600, 'cet' =>  1*3600, 'fwt' =>  1*3600, 'met' =>  1*3600,\n      'mewt'=>  1*3600, 'mez' =>  1*3600, 'swt' =>  1*3600, 'wat' =>  1*3600,\n      'west'=>  1*3600,\n      'cest'=>  2*3600, 'eet' =>  2*3600, 'fst' =>  2*3600, 'mest'=>  2*3600,\n      'mesz'=>  2*3600, 'sast'=>  2*3600, 'sst' =>  2*3600,\n      'bt'  =>  3*3600, 'eat' =>  3*3600, 'eest'=>  3*3600, 'msk' =>  3*3600,\n      'msd' =>  4*3600, 'zp4' =>  4*3600,\n      'zp5' =>  5*3600, 'ist' =>  (5*3600+1800),\n      'zp6' =>  6*3600,\n      'wast'=>  7*3600,\n      'cct' =>  8*3600, 'sgt' =>  8*3600, 'wadt'=>  8*3600,\n      'jst' =>  9*3600, 'kst' =>  9*3600,\n      'east'=> 10*3600, 'gst' => 10*3600,\n      'eadt'=> 11*3600,\n      'idle'=> 12*3600, 'nzst'=> 12*3600, 'nzt' => 12*3600,\n      'nzdt'=> 13*3600,\n\n      'afghanistan'           =>   16200, 'alaskan'               =>  -32400,\n      'arab'                  =>   10800, 'arabian'               =>   14400,\n      'arabic'                =>   10800, 'atlantic'              =>  -14400,\n      'aus central'           =>   34200, 'aus eastern'           =>   36000,\n      'azores'                =>   -3600, 'canada central'        =>  -21600,\n      'cape verde'            =>   -3600, 'caucasus'              =>   14400,\n      'cen. australia'        =>   34200, 'central america'       =>  -21600,\n      'central asia'          =>   21600, 'central europe'        =>    3600,\n      'central european'      =>    3600, 'central pacific'       =>   39600,\n      'central'               =>  -21600, 'china'                 =>   28800,\n      'dateline'              =>  -43200, 'e. africa'             =>   10800,\n      'e. australia'          =>   36000, 'e. europe'             =>    7200,\n      'e. south america'      =>  -10800, 'eastern'               =>  -18000,\n      'egypt'                 =>    7200, 'ekaterinburg'          =>   18000,\n      'fiji'                  =>   43200, 'fle'                   =>    7200,\n      'greenland'             =>  -10800, 'greenwich'             =>       0,\n      'gtb'                   =>    7200, 'hawaiian'              =>  -36000,\n      'india'                 =>   19800, 'iran'                  =>   12600,\n      'jerusalem'             =>    7200, 'korea'                 =>   32400,\n      'mexico'                =>  -21600, 'mid-atlantic'          =>   -7200,\n      'mountain'              =>  -25200, 'myanmar'               =>   23400,\n      'n. central asia'       =>   21600, 'nepal'                 =>   20700,\n      'new zealand'           =>   43200, 'newfoundland'          =>  -12600,\n      'north asia east'       =>   28800, 'north asia'            =>   25200,\n      'pacific sa'            =>  -14400, 'pacific'               =>  -28800,\n      'romance'               =>    3600, 'russian'               =>   10800,\n      'sa eastern'            =>  -10800, 'sa pacific'            =>  -18000,\n      'sa western'            =>  -14400, 'samoa'                 =>  -39600,\n      'se asia'               =>   25200, 'malay peninsula'       =>   28800,\n      'south africa'          =>    7200, 'sri lanka'             =>   21600,\n      'taipei'                =>   28800, 'tasmania'              =>   36000,\n      'tokyo'                 =>   32400, 'tonga'                 =>   46800,\n      'us eastern'            =>  -18000, 'us mountain'           =>  -25200,\n      'vladivostok'           =>   36000, 'w. australia'          =>   28800,\n      'w. central africa'     =>    3600, 'w. europe'             =>    3600,\n      'west asia'             =>   18000, 'west pacific'          =>   36000,\n      'yakutsk'               =>   32400\n    }\n\n    [MONTHS, DAYS, ABBR_MONTHS, ABBR_DAYS, ZONES].each do |x|\n      x.freeze\n    end\n\n    class Bag # :nodoc:\n\n      def initialize\n\t@elem = {}\n      end\n\n      def method_missing(t, *args, &block)\n\tt = t.to_s\n\tset = t.chomp!('=')\n\tt = t.intern\n\tif set\n\t  @elem[t] = args[0]\n\telse\n\t  @elem[t]\n\tend\n      end\n\n      def to_hash\n\t@elem.reject{|k, v| /\\A_/ =~ k.to_s || v.nil?}\n      end\n\n    end\n\n  end\n\n  def emit(e, f) # :nodoc:\n    case e\n    when Numeric\n      sign = %w(+ + -)[e <=> 0]\n      e = e.abs\n    end\n\n    s = e.to_s\n\n    if f[:s] && f[:p] == '0'\n      f[:w] -= 1\n    end\n\n    if f[:s] && f[:p] == \"\\s\"\n      s[0,0] = sign\n    end\n\n    if f[:p] != '-'\n      s = s.rjust(f[:w], f[:p])\n    end\n\n    if f[:s] && f[:p] != \"\\s\"\n      s[0,0] = sign\n    end\n\n    s = s.upcase if f[:u]\n    s = s.downcase if f[:d]\n    s\n  end\n\n  def emit_w(e, w, f) # :nodoc:\n    f[:w] = [f[:w], w].compact.max\n    emit(e, f)\n  end\n\n  def emit_n(e, w, f) # :nodoc:\n    f[:p] ||= '0'\n    emit_w(e, w, f)\n  end\n\n  def emit_sn(e, w, f) # :nodoc:\n    if e < 0\n      w += 1\n      f[:s] = true\n    end\n    emit_n(e, w, f)\n  end\n\n  def emit_z(e, w, f) # :nodoc:\n    w += 1\n    f[:s] = true\n    emit_n(e, w, f)\n  end\n\n  def emit_a(e, w, f) # :nodoc:\n    f[:p] ||= \"\\s\"\n    emit_w(e, w, f)\n  end\n\n  def emit_ad(e, w, f) # :nodoc:\n    if f[:x]\n      f[:u] = true\n      f[:d] = false\n    end\n    emit_a(e, w, f)\n  end\n\n  def emit_au(e, w, f) # :nodoc:\n    if f[:x]\n      f[:u] = false\n      f[:d] = true\n    end\n    emit_a(e, w, f)\n  end\n\n  private :emit, :emit_w, :emit_n, :emit_sn, :emit_z,\n\t  :emit_a, :emit_ad, :emit_au\n\n  def strftime(fmt='%F')\n    fmt.gsub(/%([-_0^#]+)?(\\d+)?([EO]?(?::{1,3}z|.))/m) do |m|\n      f = {}\n      a = $&\n      s, w, c = $1, $2, $3\n      if s\n\ts.scan(/./) do |k|\n\t  case k\n\t  when '-'; f[:p] = '-'\n\t  when '_'; f[:p] = \"\\s\"\n\t  when '0'; f[:p] = '0'\n\t  when '^'; f[:u] = true\n\t  when '#'; f[:x] = true\n\t  end\n\tend\n      end\n      if w\n\tf[:w] = w.to_i\n      end\n      case c\n      when 'A'; emit_ad(DAYNAMES[wday], 0, f)\n      when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)\n      when 'B'; emit_ad(MONTHNAMES[mon], 0, f)\n      when 'b'; emit_ad(ABBR_MONTHNAMES[mon], 0, f)\n      when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)\n      when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)\n      when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)\n      when 'd', 'Od'; emit_n(mday, 2, f)\n      when 'e', 'Oe'; emit_a(mday, 2, f)\n      when 'F'\n\tif m == '%F'\n\t  format('%.4d-%02d-%02d', year, mon, mday) # 4p\n\telse\n\t  emit_a(strftime('%Y-%m-%d'), 0, f)\n\tend\n      when 'G'; emit_sn(cwyear, 4, f)\n      when 'g'; emit_n(cwyear % 100, 2, f)\n      when 'H', 'OH'; emit_n(hour, 2, f)\n      when 'h'; emit_ad(strftime('%b'), 0, f)\n      when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)\n      when 'j'; emit_n(yday, 3, f)\n      when 'k'; emit_a(hour, 2, f)\n      when 'L'\n\temit_n((sec_fraction / MILLISECONDS_IN_DAY).floor, 3, f)\n      when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)\n      when 'M', 'OM'; emit_n(min, 2, f)\n      when 'm', 'Om'; emit_n(mon, 2, f)\n      when 'N'\n\temit_n((sec_fraction / NANOSECONDS_IN_DAY).floor, 9, f)\n      when 'n'; \"\\n\"\n      when 'P'; emit_ad(strftime('%p').downcase, 0, f)\n      when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)\n      when 'Q'\n\ts = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round\n\temit_sn(s, 1, f)\n      when 'R'; emit_a(strftime('%H:%M'), 0, f)\n      when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)\n      when 'S', 'OS'; emit_n(sec, 2, f)\n      when 's'\n\ts = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round\n\temit_sn(s, 1, f)\n      when 'T'\n\tif m == '%T'\n\t  format('%02d:%02d:%02d', hour, min, sec) # 4p\n\telse\n\t  emit_a(strftime('%H:%M:%S'), 0, f)\n\tend\n      when 't'; \"\\t\"\n      when 'U', 'W', 'OU', 'OW'\n\temit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)\n      when 'u', 'Ou'; emit_n(cwday, 1, f)\n      when 'V', 'OV'; emit_n(cweek, 2, f)\n      when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)\n      when 'w', 'Ow'; emit_n(wday, 1, f)\n      when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)\n      when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)\n      when 'Y', 'EY'; emit_sn(year, 4, f)\n      when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)\n      when 'Z'; emit_au(strftime('%:z'), 0, f)\n      when /\\A(:{0,3})z/\n\tt = $1.size\n\tsign = if offset < 0 then -1 else +1 end\n\tfr = offset.abs\n\tss = fr.div(SECONDS_IN_DAY) # 4p\n\thh, ss = ss.divmod(3600)\n\tmm, ss = ss.divmod(60)\n\tif t == 3\n\t  if    ss.nonzero? then t =  2\n\t  elsif mm.nonzero? then t =  1\n\t  else                   t = -1\n\t  end\n\tend\n\tcase t\n\twhen -1\n\t  tail = []\n\t  sep = ''\n\twhen 0\n\t  f[:w] -= 2 if f[:w]\n\t  tail = ['%02d' % mm]\n\t  sep = ''\n\twhen 1\n\t  f[:w] -= 3 if f[:w]\n\t  tail = ['%02d' % mm]\n\t  sep = ':'\n\twhen 2\n\t  f[:w] -= 6 if f[:w]\n\t  tail = ['%02d' % mm, '%02d' % ss]\n\t  sep = ':'\n\tend\n\t([emit_z(sign * hh, 2, f)] + tail).join(sep)\n      when '%'; emit_a('%', 0, f)\n      when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)\n      when '1'\n\tif $VERBOSE\n\t  warn(\"warning: strftime: %1 is deprecated; forget this\")\n\tend\n\temit_n(jd, 1, f)\n      when '2'\n\tif $VERBOSE\n\t  warn(\"warning: strftime: %2 is deprecated; use '%Y-%j'\")\n\tend\n\temit_a(strftime('%Y-%j'), 0, f)\n      when '3'\n\tif $VERBOSE\n\t  warn(\"warning: strftime: %3 is deprecated; use '%F'\")\n\tend\n\temit_a(strftime('%F'), 0, f)\n      else\n\ta\n      end\n    end\n  end\n\n# alias_method :format, :strftime\n\n  def asctime() strftime('%c') end\n\n  alias_method :ctime, :asctime\n\n=begin\n  def iso8601() strftime('%F') end\n\n  def rfc3339() iso8601 end\n\n  def rfc2822() strftime('%a, %-d %b %Y %T %z') end\n\n  alias_method :rfc822, :rfc2822\n\n  def jisx0301\n    if jd < 2405160\n      iso8601\n    else\n      case jd\n      when 2405160...2419614\n\tg = 'M%02d' % (year - 1867)\n      when 2419614...2424875\n\tg = 'T%02d' % (year - 1911)\n      when 2424875...2447535\n\tg = 'S%02d' % (year - 1925)\n      else\n\tg = 'H%02d' % (year - 1988)\n      end\n      g + strftime('.%m.%d')\n    end\n  end\n\n  def beat(n=0)\n    i, f = (new_offset(HOURS_IN_DAY).day_fraction * 1000).divmod(1)\n    ('@%03d' % i) +\n      if n < 1\n\t''\n      else\n\t'.%0*d' % [n, (f / Rational(1, 10**n)).round]\n      end\n  end\n=end\n\n  def self.num_pattern? (s) # :nodoc:\n    /\\A%[EO]?[CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy\\d]/ =~ s || /\\A\\d/ =~ s\n  end\n\n  private_class_method :num_pattern?\n\n  def self._strptime_i(str, fmt, e) # :nodoc:\n    fmt.scan(/%([EO]?(?::{1,3}z|.))|(.)/m) do |s, c|\n      a = $&\n      if s\n\tcase s\n\twhen 'A', 'a'\n\t  return unless str.sub!(/\\A(#{Format::DAYS.keys.join('|')})/io, '') ||\n\t\t\tstr.sub!(/\\A(#{Format::ABBR_DAYS.keys.join('|')})/io, '')\n\t  val = Format::DAYS[$1.downcase] || Format::ABBR_DAYS[$1.downcase]\n\t  return unless val\n\t  e.wday = val\n\twhen 'B', 'b', 'h'\n\t  return unless str.sub!(/\\A(#{Format::MONTHS.keys.join('|')})/io, '') ||\n\t\t\tstr.sub!(/\\A(#{Format::ABBR_MONTHS.keys.join('|')})/io, '')\n\t  val = Format::MONTHS[$1.downcase] || Format::ABBR_MONTHS[$1.downcase]\n\t  return unless val\n\t  e.mon = val\n\twhen 'C', 'EC'\n\t  return unless str.sub!(if num_pattern?($')\n\t\t\t\t then /\\A([-+]?\\d{1,2})/\n\t\t\t\t else /\\A([-+]?\\d{1,})/\n\t\t\t\t end, '')\n\t  val = $1.to_i\n\t  e._cent = val\n\twhen 'c', 'Ec'\n\t  return unless _strptime_i(str, '%a %b %e %H:%M:%S %Y', e)\n\twhen 'D'\n\t  return unless _strptime_i(str, '%m/%d/%y', e)\n\twhen 'd', 'e', 'Od', 'Oe'\n\t  return unless str.sub!(/\\A( \\d|\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (1..31) === val\n\t  e.mday = val\n\twhen 'F'\n\t  return unless _strptime_i(str, '%Y-%m-%d', e)\n\twhen 'G'\n\t  return unless str.sub!(if num_pattern?($')\n\t\t\t\t then /\\A([-+]?\\d{1,4})/\n\t\t\t\t else /\\A([-+]?\\d{1,})/\n\t\t\t\t end, '')\n\t  val = $1.to_i\n\t  e.cwyear = val\n\twhen 'g'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (0..99) === val\n\t  e.cwyear = val\n\t  e._cent ||= if val >= 69 then 19 else 20 end\n\twhen 'H', 'k', 'OH'\n\t  return unless str.sub!(/\\A( \\d|\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (0..24) === val\n\t  e.hour = val\n\twhen 'I', 'l', 'OI'\n\t  return unless str.sub!(/\\A( \\d|\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (1..12) === val\n\t  e.hour = val\n\twhen 'j'\n\t  return unless str.sub!(/\\A(\\d{1,3})/, '')\n\t  val = $1.to_i\n\t  return unless (1..366) === val\n\t  e.yday = val\n\twhen 'L'\n\t  return unless str.sub!(if num_pattern?($')\n\t\t\t\t then /\\A([-+]?\\d{1,3})/\n\t\t\t\t else /\\A([-+]?\\d{1,})/\n\t\t\t\t end, '')\n#\t  val = Rational($1.to_i, 10**3)\n\t  val = Rational($1.to_i, 10**$1.size)\n\t  e.sec_fraction = val\n\twhen 'M', 'OM'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (0..59) === val\n\t  e.min = val\n\twhen 'm', 'Om'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (1..12) === val\n\t  e.mon = val\n\twhen 'N'\n\t  return unless str.sub!(if num_pattern?($')\n\t\t\t\t then /\\A([-+]?\\d{1,9})/\n\t\t\t\t else /\\A([-+]?\\d{1,})/\n\t\t\t\t end, '')\n#\t  val = Rational($1.to_i, 10**9)\n\t  val = Rational($1.to_i, 10**$1.size)\n\t  e.sec_fraction = val\n\twhen 'n', 't'\n\t  return unless _strptime_i(str, \"\\s\", e)\n\twhen 'P', 'p'\n\t  return unless str.sub!(/\\A([ap])(?:m\\b|\\.m\\.)/i, '')\n\t  e._merid = if $1.downcase == 'a' then 0 else 12 end\n\twhen 'Q'\n\t  return unless str.sub!(/\\A(-?\\d{1,})/, '')\n\t  val = Rational($1.to_i, 10**3)\n\t  e.seconds = val\n\twhen 'R'\n\t  return unless _strptime_i(str, '%H:%M', e)\n\twhen 'r'\n\t  return unless _strptime_i(str, '%I:%M:%S %p', e)\n\twhen 'S', 'OS'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (0..60) === val\n\t  e.sec = val\n\twhen 's'\n\t  return unless str.sub!(/\\A(-?\\d{1,})/, '')\n\t  val = $1.to_i\n\t  e.seconds = val\n\twhen 'T'\n\t  return unless _strptime_i(str, '%H:%M:%S', e)\n\twhen 'U', 'W', 'OU', 'OW'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (0..53) === val\n\t  e.__send__(if s[-1,1] == 'U' then :wnum0= else :wnum1= end, val)\n\twhen 'u', 'Ou'\n\t  return unless str.sub!(/\\A(\\d{1})/, '')\n\t  val = $1.to_i\n\t  return unless (1..7) === val\n\t  e.cwday = val\n\twhen 'V', 'OV'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (1..53) === val\n\t  e.cweek = val\n\twhen 'v'\n\t  return unless _strptime_i(str, '%e-%b-%Y', e)\n\twhen 'w'\n\t  return unless str.sub!(/\\A(\\d{1})/, '')\n\t  val = $1.to_i\n\t  return unless (0..6) === val\n\t  e.wday = val\n\twhen 'X', 'EX'\n\t  return unless _strptime_i(str, '%H:%M:%S', e)\n\twhen 'x', 'Ex'\n\t  return unless _strptime_i(str, '%m/%d/%y', e)\n\twhen 'Y', 'EY'\n\t  return unless str.sub!(if num_pattern?($')\n\t\t\t\t then /\\A([-+]?\\d{1,4})/\n\t\t\t\t else /\\A([-+]?\\d{1,})/\n\t\t\t\t end, '')\n\t  val = $1.to_i\n\t  e.year = val\n\twhen 'y', 'Ey', 'Oy'\n\t  return unless str.sub!(/\\A(\\d{1,2})/, '')\n\t  val = $1.to_i\n\t  return unless (0..99) === val\n\t  e.year = val\n\t  e._cent ||= if val >= 69 then 19 else 20 end\n\twhen 'Z', /\\A:{0,3}z/\n\t  return unless str.sub!(/\\A((?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?\n\t\t\t\t    |[[:alpha:].\\s]+(?:standard|daylight)\\s+time\\b\n\t\t\t\t    |[[:alpha:]]+(?:\\s+dst)?\\b\n\t\t\t\t    )/ix, '')\n\t  val = $1\n\t  e.zone = val\n\t  offset = zone_to_diff(val)\n\t  e.offset = offset\n\twhen '%'\n\t  return unless str.sub!(/\\A%/, '')\n\twhen '+'\n\t  return unless _strptime_i(str, '%a %b %e %H:%M:%S %Z %Y', e)\n\twhen '1'\n\t  if $VERBOSE\n\t    warn(\"warning: strptime: %1 is deprecated; forget this\")\n\t  end\n\t  return unless str.sub!(/\\A(\\d+)/, '')\n\t  val = $1.to_i\n\t  e.jd = val\n\twhen '2'\n\t  if $VERBOSE\n\t    warn(\"warning: strptime: %2 is deprecated; use '%Y-%j'\")\n\t  end\n\t  return unless _strptime_i(str, '%Y-%j', e)\n\twhen '3'\n\t  if $VERBOSE\n\t    warn(\"warning: strptime: %3 is deprecated; use '%F'\")\n\t  end\n\t  return unless _strptime_i(str, '%F', e)\n\telse\n\t  return unless str.sub!(Regexp.new('\\\\A' + Regexp.quote(a)), '')\n\tend\n      else\n\tcase c\n\twhen /\\A[\\s\\v]/\n\t  str.sub!(/\\A[\\s\\v]+/, '')\n\telse\n\t  return unless str.sub!(Regexp.new('\\\\A' + Regexp.quote(a)), '')\n\tend\n      end\n    end\n  end\n\n  private_class_method :_strptime_i\n\n  def self._strptime(str, fmt='%F')\n    str = str.dup\n    e = Format::Bag.new\n    return unless _strptime_i(str, fmt, e)\n\n    if e._cent\n      if e.cwyear\n\te.cwyear += e._cent * 100\n      end\n      if e.year\n\te.  year += e._cent * 100\n      end\n    end\n\n    if e._merid\n      if e.hour\n\te.hour %= 12\n\te.hour += e._merid\n      end\n    end\n\n    unless str.empty?\n      e.leftover = str\n    end\n\n    e.to_hash\n  end\n\n  def self.s3e(e, y, m, d, bc=false)\n    unless String === m\n      m = m.to_s\n    end\n\n    if y && m && !d\n      y, m, d = d, y, m\n    end\n\n    if y == nil\n      if d && d.size > 2\n\ty = d\n\td = nil\n      end\n      if d && d[0,1] == \"'\"\n\ty = d\n\td = nil\n      end\n    end\n\n    if y\n      y.scan(/(\\d+)(.+)?/)\n      if $2\n\ty, d = d, $1\n      end\n    end\n\n    if m\n      if m[0,1] == \"'\" || m.size > 2\n\ty, m, d = m, d, y # us -> be\n      end\n    end\n\n    if d\n      if d[0,1] == \"'\" || d.size > 2\n\ty, d = d, y\n      end\n    end\n\n    if y\n      y =~ /([-+])?(\\d+)/\n      if $1 || $2.size > 2\n\tc = false\n      end\n      iy = $&.to_i\n      if bc\n\tiy = -iy + 1\n      end\n      e.year = iy\n    end\n\n    if m\n      m =~ /\\d+/\n      e.mon = $&.to_i\n    end\n\n    if d\n      d =~ /\\d+/\n      e.mday = $&.to_i\n    end\n\n    if c != nil\n      e._comp = c\n    end\n\n  end\n\n  private_class_method :s3e\n\n  def self._parse_day(str, e) # :nodoc:\n    if str.sub!(/\\b(#{Format::ABBR_DAYS.keys.join('|')})[^-\\d\\s]*/ino, ' ')\n      e.wday = Format::ABBR_DAYS[$1.downcase]\n      true\n=begin\n    elsif str.sub!(/\\b(?!\\dth)(su|mo|tu|we|th|fr|sa)\\b/in, ' ')\n      e.wday = %w(su mo tu we th fr sa).index($1.downcase)\n      true\n=end\n    end\n  end\n\n  def self._parse_time(str, e) # :nodoc:\n    if str.sub!(\n\t\t/(\n\t\t   (?:\n\t\t     \\d+\\s*:\\s*\\d+\n\t\t     (?:\n\t\t       \\s*:\\s*\\d+(?:[,.]\\d*)?\n\t\t     )?\n\t\t   |\n\t\t     \\d+\\s*h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?\n\t\t   )\n\t\t   (?:\n\t\t     \\s*\n\t\t     [ap](?:m\\b|\\.m\\.)\n\t\t   )?\n\t\t |\n\t\t   \\d+\\s*[ap](?:m\\b|\\.m\\.)\n\t\t )\n\t\t (?:\n\t\t   \\s*\n\t\t   (\n\t\t     (?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?\n\t\t   |\n\t\t     [[:alpha:].\\s]+(?:standard|daylight)\\stime\\b\n\t\t   |\n\t\t     [[:alpha:]]+(?:\\sdst)?\\b\n\t\t   )\n\t\t )?\n\t\t/inx,\n\t\t' ')\n\n      t = $1\n      e.zone = $2 if $2\n\n      t =~ /\\A(\\d+)h?\n\t      (?:\\s*:?\\s*(\\d+)m?\n\t\t(?:\n\t\t  \\s*:?\\s*(\\d+)(?:[,.](\\d+))?s?\n\t\t)?\n\t      )?\n\t    (?:\\s*([ap])(?:m\\b|\\.m\\.))?/inx\n\n      e.hour = $1.to_i\n      e.min = $2.to_i if $2\n      e.sec = $3.to_i if $3\n      e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4\n\n      if $5\n\te.hour %= 12\n\tif $5.downcase == 'p'\n\t  e.hour += 12\n\tend\n      end\n      true\n    end\n  end\n\n=begin\n  def self._parse_beat(str, e) # :nodoc:\n    if str.sub!(/@\\s*(\\d+)(?:[,.](\\d*))?/, ' ')\n      beat = Rational($1.to_i)\n      beat += Rational($2.to_i, 10**$2.size) if $2\n      secs = Rational(beat, 1000)\n      h, min, s, fr = self.day_fraction_to_time(secs)\n      e.hour = h\n      e.min = min\n      e.sec = s\n      e.sec_fraction = fr * 86400\n      e.zone = '+01:00'\n      true\n    end\n  end\n=end\n\n  def self._parse_eu(str, e) # :nodoc:\n    if str.sub!(\n\t\t/'?(\\d+)[^-\\d\\s]*\n\t\t \\s*\n\t\t (#{Format::ABBR_MONTHS.keys.join('|')})[^-\\d\\s']*\n\t\t (?:\n\t\t   \\s*\n\t\t   (c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?\n\t\t   \\s*\n\t\t   ('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)\n\t\t )?\n\t\t/inox,\n\t\t' ') # '\n      s3e(e, $4, Format::ABBR_MONTHS[$2.downcase], $1,\n\t  $3 && $3[0,1].downcase == 'b')\n      true\n    end\n  end\n\n  def self._parse_us(str, e) # :nodoc:\n    if str.sub!(\n\t\t/\\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-\\d\\s']*\n\t\t \\s*\n\t\t ('?\\d+)[^-\\d\\s']*\n\t\t (?:\n\t\t   \\s*\n\t\t   (c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?\n\t\t   \\s*\n\t\t   ('?-?\\d+)\n\t\t )?\n\t\t/inox,\n\t\t' ') # '\n      s3e(e, $4, Format::ABBR_MONTHS[$1.downcase], $2,\n\t  $3 && $3[0,1].downcase == 'b')\n      true\n    end\n  end\n\n  def self._parse_iso(str, e) # :nodoc:\n    if str.sub!(/('?[-+]?\\d+)-(\\d+)-('?-?\\d+)/n, ' ')\n      s3e(e, $1, $2, $3)\n      true\n    end\n  end\n\n  def self._parse_iso2(str, e) # :nodoc:\n    if str.sub!(/\\b(\\d{2}|\\d{4})?-?w(\\d{2})(?:-?(\\d))?\\b/in, ' ')\n      e.cwyear = $1.to_i if $1\n      e.cweek = $2.to_i\n      e.cwday = $3.to_i if $3\n      true\n    elsif str.sub!(/-w-(\\d)\\b/in, ' ')\n      e.cwday = $1.to_i\n      true\n    elsif str.sub!(/--(\\d{2})?-(\\d{2})\\b/n, ' ')\n      e.mon = $1.to_i if $1\n      e.mday = $2.to_i\n      true\n    elsif str.sub!(/--(\\d{2})(\\d{2})?\\b/n, ' ')\n      e.mon = $1.to_i\n      e.mday = $2.to_i if $2\n      true\n    elsif /[,.](\\d{2}|\\d{4})-\\d{3}\\b/n !~ str &&\n\tstr.sub!(/\\b(\\d{2}|\\d{4})-(\\d{3})\\b/n, ' ')\n      e.year = $1.to_i\n      e.yday = $2.to_i\n      true\n    elsif /\\d-\\d{3}\\b/n !~ str &&\n\tstr.sub!(/\\b-(\\d{3})\\b/n, ' ')\n      e.yday = $1.to_i\n      true\n    end\n  end\n\n  def self._parse_jis(str, e) # :nodoc:\n    if str.sub!(/\\b([mtsh])(\\d+)\\.(\\d+)\\.(\\d+)/in, ' ')\n      era = { 'm'=>1867,\n\t      't'=>1911,\n\t      's'=>1925,\n\t      'h'=>1988\n\t  }[$1.downcase]\n      e.year = $2.to_i + era\n      e.mon = $3.to_i\n      e.mday = $4.to_i\n      true\n    end\n  end\n\n  def self._parse_vms(str, e) # :nodoc:\n    if str.sub!(/('?-?\\d+)-(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*\n\t\t-('?-?\\d+)/inox, ' ')\n      s3e(e, $3, Format::ABBR_MONTHS[$2.downcase], $1)\n      true\n    elsif str.sub!(/\\b(#{Format::ABBR_MONTHS.keys.join('|')})[^-]*\n\t\t-('?-?\\d+)(?:-('?-?\\d+))?/inox, ' ')\n      s3e(e, $3, Format::ABBR_MONTHS[$1.downcase], $2)\n      true\n    end\n  end\n\n  def self._parse_sla(str, e) # :nodoc:\n    if str.sub!(%r|('?-?\\d+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?|n, ' ') # '\n      s3e(e, $3, $1, $2)\n      true\n    end\n  end\n\n  def self._parse_dot(str, e) # :nodoc:\n    if str.sub!(%r|('?-?\\d+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)|n, ' ') # '\n      s3e(e, $1, $2, $3)\n      true\n    end\n  end\n\n  def self._parse_year(str, e) # :nodoc:\n    if str.sub!(/'(\\d+)\\b/n, ' ')\n      e.year = $1.to_i\n      true\n    end\n  end\n\n  def self._parse_mon(str, e) # :nodoc:\n    if str.sub!(/\\b(#{Format::ABBR_MONTHS.keys.join('|')})\\S*/ino, ' ')\n      e.mon = Format::ABBR_MONTHS[$1.downcase]\n      true\n    end\n  end\n\n  def self._parse_mday(str, e) # :nodoc:\n    if str.sub!(/(\\d+)(st|nd|rd|th)\\b/in, ' ')\n      e.mday = $1.to_i\n      true\n    end\n  end\n\n  def self._parse_ddd(str, e) # :nodoc:\n    if str.sub!(\n\t\t/([-+]?)(\\d{2,14})\n\t\t  (?:\n\t\t    \\s*\n\t\t    t?\n\t\t    \\s*\n\t\t    (\\d{2,6})?(?:[,.](\\d*))?\n\t\t  )?\n\t\t  (?:\n\t\t    \\s*\n\t\t    (\n\t\t      z\\b\n\t\t    |\n\t\t      [-+]\\d{1,4}\\b\n\t\t    |\n\t\t      \\[[-+]?\\d[^\\]]*\\]\n\t\t    )\n\t\t  )?\n\t\t/inx,\n\t\t' ')\n      case $2.size\n      when 2\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\telse\n\t  e.mday = $2[ 0, 2].to_i\n\tend\n      when 4\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\t  e.min  = $2[-4, 2].to_i\n\telse\n\t  e.mon  = $2[ 0, 2].to_i\n\t  e.mday = $2[ 2, 2].to_i\n\tend\n      when 6\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\t  e.min  = $2[-4, 2].to_i\n\t  e.hour = $2[-6, 2].to_i\n\telse\n\t  e.year = ($1 + $2[ 0, 2]).to_i\n\t  e.mon  = $2[ 2, 2].to_i\n\t  e.mday = $2[ 4, 2].to_i\n\tend\n      when 8, 10, 12, 14\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\t  e.min  = $2[-4, 2].to_i\n\t  e.hour = $2[-6, 2].to_i\n\t  e.mday = $2[-8, 2].to_i\n\t  if $2.size >= 10\n\t    e.mon  = $2[-10, 2].to_i\n\t  end\n\t  if $2.size == 12\n\t    e.year = ($1 + $2[-12, 2]).to_i\n\t  end\n\t  if $2.size == 14\n\t    e.year = ($1 + $2[-14, 4]).to_i\n\t    e._comp = false\n\t  end\n\telse\n\t  e.year = ($1 + $2[ 0, 4]).to_i\n\t  e.mon  = $2[ 4, 2].to_i\n\t  e.mday = $2[ 6, 2].to_i\n\t  e.hour = $2[ 8, 2].to_i if $2.size >= 10\n\t  e.min  = $2[10, 2].to_i if $2.size >= 12\n\t  e.sec  = $2[12, 2].to_i if $2.size >= 14\n\t  e._comp = false\n\tend\n      when 3\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\t  e.min  = $2[-3, 1].to_i\n\telse\n\t  e.yday = $2[ 0, 3].to_i\n\tend\n      when 5\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\t  e.min  = $2[-4, 2].to_i\n\t  e.hour = $2[-5, 1].to_i\n\telse\n\t  e.year = ($1 + $2[ 0, 2]).to_i\n\t  e.yday = $2[ 2, 3].to_i\n\tend\n      when 7\n\tif $3.nil? && $4\n\t  e.sec  = $2[-2, 2].to_i\n\t  e.min  = $2[-4, 2].to_i\n\t  e.hour = $2[-6, 2].to_i\n\t  e.mday = $2[-7, 1].to_i\n\telse\n\t  e.year = ($1 + $2[ 0, 4]).to_i\n\t  e.yday = $2[ 4, 3].to_i\n\tend\n      end\n      if $3\n\tif $4\n\t  case $3.size\n\t  when 2, 4, 6\n\t    e.sec  = $3[-2, 2].to_i\n\t    e.min  = $3[-4, 2].to_i if $3.size >= 4\n\t    e.hour = $3[-6, 2].to_i if $3.size >= 6\n\t  end\n\telse\n\t  case $3.size\n\t  when 2, 4, 6\n\t    e.hour = $3[ 0, 2].to_i\n\t    e.min  = $3[ 2, 2].to_i if $3.size >= 4\n\t    e.sec  = $3[ 4, 2].to_i if $3.size >= 6\n\t  end\n\tend\n      end\n      if $4\n\te.sec_fraction = Rational($4.to_i, 10**$4.size)\n      end\n      if $5\n\te.zone = $5\n\tif e.zone[0,1] == '['\n\t  o, n, = e.zone[1..-2].split(':')\n\t  e.zone = n || o\n\t  if /\\A\\d/ =~ o\n\t    o = format('+%s', o)\n\t  end\n\t  e.offset = zone_to_diff(o)\n\tend\n      end\n      true\n    end\n  end\n\n  private_class_method :_parse_day, :_parse_time, # :_parse_beat,\n\t:_parse_eu, :_parse_us, :_parse_iso, :_parse_iso2,\n\t:_parse_jis, :_parse_vms, :_parse_sla, :_parse_dot,\n\t:_parse_year, :_parse_mon, :_parse_mday, :_parse_ddd\n\n  def self._parse(str, comp=false)\n    str = str.dup\n\n    e = Format::Bag.new\n\n    e._comp = comp\n\n    str.gsub!(/[^-+',.\\/:@[:alnum:]\\[\\]\\x80-\\xff]+/n, ' ')\n\n    _parse_time(str, e) # || _parse_beat(str, e)\n    _parse_day(str, e)\n\n    _parse_eu(str, e)     ||\n    _parse_us(str, e)     ||\n    _parse_iso(str, e)    ||\n    _parse_jis(str, e)    ||\n    _parse_vms(str, e)    ||\n    _parse_sla(str, e)    ||\n    _parse_dot(str, e)    ||\n    _parse_iso2(str, e)   ||\n    _parse_year(str, e)   ||\n    _parse_mon(str, e)    ||\n    _parse_mday(str, e)   ||\n    _parse_ddd(str, e)\n\n    if str.sub!(/\\b(bc\\b|bce\\b|b\\.c\\.|b\\.c\\.e\\.)/in, ' ')\n      if e.year\n\te.year = -e.year + 1\n      end\n    end\n\n    if str.sub!(/\\A\\s*(\\d{1,2})\\s*\\z/n, ' ')\n      if e.hour && !e.mday\n\tv = $1.to_i\n\tif (1..31) === v\n\t  e.mday = v\n\tend\n      end\n      if e.mday && !e.hour\n\tv = $1.to_i\n\tif (0..24) === v\n\t  e.hour = v\n\tend\n      end\n    end\n\n    if e._comp\n      if e.cwyear\n\tif e.cwyear >= 0 && e.cwyear <= 99\n\t  e.cwyear += if e.cwyear >= 69\n\t\t      then 1900 else 2000 end\n\tend\n      end\n      if e.year\n\tif e.year >= 0 && e.year <= 99\n\t  e.year += if e.year >= 69\n\t\t    then 1900 else 2000 end\n\tend\n      end\n    end\n\n    e.offset ||= zone_to_diff(e.zone) if e.zone\n\n    e.to_hash\n  end\n\n  def self.zone_to_diff(zone) # :nodoc:\n    zone = zone.downcase\n    if zone.sub!(/\\s+(standard|daylight)\\s+time\\z/, '')\n      dst = $1 == 'daylight'\n    else\n      dst = zone.sub!(/\\s+dst\\z/, '')\n    end\n    if Format::ZONES.include?(zone)\n      offset = Format::ZONES[zone]\n      offset += 3600 if dst\n    elsif zone.sub!(/\\A(?:gmt|utc?)?([-+])/, '')\n      sign = $1\n      if zone.include?(':')\n\thour, min, sec, = zone.split(':')\n      elsif zone.include?(',') || zone.include?('.')\n\thour, fr, = zone.split(/[,.]/)\n\tmin = Rational(fr.to_i, 10**fr.size) * 60\n      else\n\tcase zone.size\n\twhen 3\n\t  hour = zone[0,1]\n\t  min = zone[1,2]\n\telse\n\t  hour = zone[0,2]\n\t  min = zone[2,2]\n\t  sec = zone[4,2]\n\tend\n      end\n      offset = hour.to_i * 3600 + min.to_i * 60 + sec.to_i\n      offset *= -1 if sign == '-'\n    end\n    offset\n  end\n\nend\n\nclass DateTime < Date\n\n  def strftime(fmt='%FT%T%:z')\n    super(fmt)\n  end\n\n  def self._strptime(str, fmt='%FT%T%z')\n    super(str, fmt)\n  end\n\n=begin\n  def iso8601_timediv(n) # :nodoc:\n    strftime('T%T' +\n\t     if n < 1\n\t       ''\n\t     else\n\t       '.%0*d' % [n, (sec_fraction / SECONDS_IN_DAY / (10**n)).round]\n\t     end +\n\t     '%:z')\n  end\n\n  private :iso8601_timediv\n\n  def iso8601(n=0)\n    super() + iso8601_timediv(n)\n  end\n\n  def rfc3339(n=0) iso8601(n) end\n\n  def jisx0301(n=0)\n    super() + iso8601_timediv(n)\n  end\n=end\n\nend\n"
  },
  {
    "path": "lib/date.rb",
    "content": "#\n# date.rb - date and time library\n#\n# Author: Tadayoshi Funaba 1998-2008\n#\n# Documentation: William Webber <william@williamwebber.com>\n#\n#--\n# $Id: date.rb,v 2.37 2008-01-17 20:16:31+09 tadf Exp $\n#++\n#\n# == Overview\n#\n# This file provides two classes for working with\n# dates and times.\n#\n# The first class, Date, represents dates.\n# It works with years, months, weeks, and days.\n# See the Date class documentation for more details.\n#\n# The second, DateTime, extends Date to include hours,\n# minutes, seconds, and fractions of a second.  It\n# provides basic support for time zones.  See the\n# DateTime class documentation for more details.\n#\n# === Ways of calculating the date.\n#\n# In common usage, the date is reckoned in years since or\n# before the Common Era (CE/BCE, also known as AD/BC), then\n# as a month and day-of-the-month within the current year.\n# This is known as the *Civil* *Date*, and abbreviated\n# as +civil+ in the Date class.\n#\n# Instead of year, month-of-the-year,  and day-of-the-month,\n# the date can also be reckoned in terms of year and\n# day-of-the-year.  This is known as the *Ordinal* *Date*,\n# and is abbreviated as +ordinal+ in the Date class.  (Note\n# that referring to this as the Julian date is incorrect.)\n#\n# The date can also be reckoned in terms of year, week-of-the-year,\n# and day-of-the-week.  This is known as the *Commercial*\n# *Date*, and is abbreviated as +commercial+ in the\n# Date class.  The commercial week runs Monday (day-of-the-week\n# 1) to Sunday (day-of-the-week 7), in contrast to the civil\n# week which runs Sunday (day-of-the-week 0) to Saturday\n# (day-of-the-week 6).  The first week of the commercial year\n# starts on the Monday on or before January 1, and the commercial\n# year itself starts on this Monday, not January 1.\n#\n# For scientific purposes, it is convenient to refer to a date\n# simply as a day count, counting from an arbitrary initial\n# day.  The date first chosen for this was January 1, 4713 BCE.\n# A count of days from this date is the *Julian* *Day* *Number*\n# or *Julian* *Date*, which is abbreviated as +jd+ in the\n# Date class.  This is in local time, and counts from midnight\n# on the initial day.  The stricter usage is in UTC, and counts\n# from midday on the initial day.  This is referred to in the\n# Date class as the *Astronomical* *Julian* *Day* *Number*, and\n# abbreviated as +ajd+.  In the Date class, the Astronomical\n# Julian Day Number includes fractional days.\n#\n# Another absolute day count is the *Modified* *Julian* *Day*\n# *Number*, which takes November 17, 1858 as its initial day.\n# This is abbreviated as +mjd+ in the Date class.  There\n# is also an *Astronomical* *Modified* *Julian* *Day* *Number*,\n# which is in UTC and includes fractional days.  This is\n# abbreviated as +amjd+ in the Date class.  Like the Modified\n# Julian Day Number (and unlike the Astronomical Julian\n# Day Number), it counts from midnight.\n#\n# Alternative calendars such as the Chinese Lunar Calendar,\n# the Islamic Calendar, or the French Revolutionary Calendar\n# are not supported by the Date class; nor are calendars that\n# are based on an Era different from the Common Era, such as\n# the Japanese Imperial Calendar or the Republic of China\n# Calendar.\n#\n# === Calendar Reform\n#\n# The standard civil year is 365 days long.  However, the\n# solar year is fractionally longer than this.  To account\n# for this, a *leap* *year* is occasionally inserted.  This\n# is a year with 366 days, the extra day falling on February 29.\n# In the early days of the civil calendar, every fourth\n# year without exception was a leap year.  This way of\n# reckoning leap years is the *Julian* *Calendar*.\n#\n# However, the solar year is marginally shorter than 365 1/4\n# days, and so the *Julian* *Calendar* gradually ran slow\n# over the centuries.  To correct this, every 100th year\n# (but not every 400th year) was excluded as a leap year.\n# This way of reckoning leap years, which we use today, is\n# the *Gregorian* *Calendar*.\n#\n# The Gregorian Calendar was introduced at different times\n# in different regions.  The day on which it was introduced\n# for a particular region is the *Day* *of* *Calendar*\n# *Reform* for that region.  This is abbreviated as +sg+\n# (for Start of Gregorian calendar) in the Date class.\n#\n# Two such days are of particular\n# significance.  The first is October 15, 1582, which was\n# the Day of Calendar Reform for Italy and most Catholic\n# countries.  The second is September 14, 1752, which was\n# the Day of Calendar Reform for England and its colonies\n# (including what is now the United States).  These two\n# dates are available as the constants Date::ITALY and\n# Date::ENGLAND, respectively.  (By comparison, Germany and\n# Holland, less Catholic than Italy but less stubborn than\n# England, changed over in 1698; Sweden in 1753; Russia not\n# till 1918, after the Revolution; and Greece in 1923.  Many\n# Orthodox churches still use the Julian Calendar.  A complete\n# list of Days of Calendar Reform can be found at\n# http://www.polysyllabic.com/GregConv.html.)\n#\n# Switching from the Julian to the Gregorian calendar\n# involved skipping a number of days to make up for the\n# accumulated lag, and the later the switch was (or is)\n# done, the more days need to be skipped.  So in 1582 in Italy,\n# 4th October was followed by 15th October, skipping 10 days; in 1752\n# in England, 2nd September was followed by 14th September, skipping\n# 11 days; and if I decided to switch from Julian to Gregorian\n# Calendar this midnight, I would go from 27th July 2003 (Julian)\n# today to 10th August 2003 (Gregorian) tomorrow, skipping\n# 13 days.  The Date class is aware of this gap, and a supposed\n# date that would fall in the middle of it is regarded as invalid.\n#\n# The Day of Calendar Reform is relevant to all date representations\n# involving years.  It is not relevant to the Julian Day Numbers,\n# except for converting between them and year-based representations.\n#\n# In the Date and DateTime classes, the Day of Calendar Reform or\n# +sg+ can be specified a number of ways.  First, it can be as\n# the Julian Day Number of the Day of Calendar Reform.  Second,\n# it can be using the constants Date::ITALY or Date::ENGLAND; these\n# are in fact the Julian Day Numbers of the Day of Calendar Reform\n# of the respective regions.  Third, it can be as the constant\n# Date::JULIAN, which means to always use the Julian Calendar.\n# Finally, it can be as the constant Date::GREGORIAN, which means\n# to always use the Gregorian Calendar.\n#\n# Note: in the Julian Calendar, New Years Day was March 25.  The\n# Date class does not follow this convention.\n#\n# === Time Zones\n#\n# DateTime objects support a simple representation\n# of time zones.  Time zones are represented as an offset\n# from UTC, as a fraction of a day.  This offset is the\n# how much local time is later (or earlier) than UTC.\n# UTC offset 0 is centred on England (also known as GMT).\n# As you travel east, the offset increases until you\n# reach the dateline in the middle of the Pacific Ocean;\n# as you travel west, the offset decreases.  This offset\n# is abbreviated as +of+ in the Date class.\n#\n# This simple representation of time zones does not take\n# into account the common practice of Daylight Savings\n# Time or Summer Time.\n#\n# Most DateTime methods return the date and the\n# time in local time.  The two exceptions are\n# #ajd() and #amjd(), which return the date and time\n# in UTC time, including fractional days.\n#\n# The Date class does not support time zone offsets, in that\n# there is no way to create a Date object with a time zone.\n# However, methods of the Date class when used by a\n# DateTime instance will use the time zone offset of this\n# instance.\n#\n# == Examples of use\n#\n# === Print out the date of every Sunday between two dates.\n#\n#     def print_sundays(d1, d2)\n#         d1 +=1 while (d1.wday != 0)\n#         d1.step(d2, 7) do |date|\n#             puts \"#{Date::MONTHNAMES[date.mon]} #{date.day}\"\n#         end\n#     end\n#\n#     print_sundays(Date::civil(2003, 4, 8), Date::civil(2003, 5, 23))\n#\n# === Calculate how many seconds to go till midnight on New Year's Day.\n#\n#     def secs_to_new_year(now = DateTime::now())\n#         new_year = DateTime.new(now.year + 1, 1, 1)\n#         dif = new_year - now\n#         hours, mins, secs, ignore_fractions = Date::day_fraction_to_time(dif)\n#         return hours * 60 * 60 + mins * 60 + secs\n#     end\n#\n#     puts secs_to_new_year()\n\nrequire 'rational'\nrequire 'date/format'\n\n# Class representing a date.\n#\n# See the documentation to the file date.rb for an overview.\n#\n# Internally, the date is represented as an Astronomical\n# Julian Day Number, +ajd+.  The Day of Calendar Reform, +sg+, is\n# also stored, for conversions to other date formats.  (There\n# is also an +of+ field for a time zone offset, but this\n# is only for the use of the DateTime subclass.)\n#\n# A new Date object is created using one of the object creation\n# class methods named after the corresponding date format, and the\n# arguments appropriate to that date format; for instance,\n# Date::civil() (aliased to Date::new()) with year, month,\n# and day-of-month, or Date::ordinal() with year and day-of-year.\n# All of these object creation class methods also take the\n# Day of Calendar Reform as an optional argument.\n#\n# Date objects are immutable once created.\n#\n# Once a Date has been created, date values\n# can be retrieved for the different date formats supported\n# using instance methods.  For instance, #mon() gives the\n# Civil month, #cwday() gives the Commercial day of the week,\n# and #yday() gives the Ordinal day of the year.  Date values\n# can be retrieved in any format, regardless of what format\n# was used to create the Date instance.\n#\n# The Date class includes the Comparable module, allowing\n# date objects to be compared and sorted, ranges of dates\n# to be created, and so forth.\nclass Date\n\n  include Comparable\n\n  # Full month names, in English.  Months count from 1 to 12; a\n  # month's numerical representation indexed into this array\n  # gives the name of that month (hence the first element is nil).\n  MONTHNAMES = [nil] + %w(January February March April May June July\n\t\t\t  August September October November December)\n\n  # Full names of days of the week, in English.  Days of the week\n  # count from 0 to 6 (except in the commercial week); a day's numerical\n  # representation indexed into this array gives the name of that day.\n  DAYNAMES = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)\n\n  # Abbreviated month names, in English.\n  ABBR_MONTHNAMES = [nil] + %w(Jan Feb Mar Apr May Jun\n\t\t\t       Jul Aug Sep Oct Nov Dec)\n\n  # Abbreviated day names, in English.\n  ABBR_DAYNAMES = %w(Sun Mon Tue Wed Thu Fri Sat)\n\n  [MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYNAMES].each do |xs|\n    xs.each{|x| x.freeze unless x.nil?}.freeze\n  end\n\n  class Infinity < Numeric # :nodoc:\n\n    include Comparable\n\n    def initialize(d=1) @d = d <=> 0 end\n\n    def d() @d end\n\n    protected :d\n\n    def zero? () false end\n    def finite? () false end\n    def infinite? () d.nonzero? end\n    def nan? () d.zero? end\n\n    def abs() self.class.new end\n\n    def -@ () self.class.new(-d) end\n    def +@ () self.class.new(+d) end\n\n    def <=> (other)\n      case other\n      when Infinity; return d <=> other.d\n      when Numeric; return d\n      else\n\tbegin\n\t  l, r = other.coerce(self)\n\t  return l <=> r\n\trescue NoMethodError\n\tend\n      end\n      nil\n    end\n\n    def coerce(other)\n      case other\n      when Numeric; return -d, d\n      else\n\tsuper\n      end\n    end\n\n  end\n\n  # The Julian Day Number of the Day of Calendar Reform for Italy\n  # and the Catholic countries.\n  ITALY     = 2299161 # 1582-10-15\n\n  # The Julian Day Number of the Day of Calendar Reform for England\n  # and her Colonies.\n  ENGLAND   = 2361222 # 1752-09-14\n\n  # A constant used to indicate that a Date should always use the\n  # Julian calendar.\n  JULIAN    =  Infinity.new\n\n  # A constant used to indicate that a Date should always use the\n  # Gregorian calendar.\n  GREGORIAN = -Infinity.new\n\n  HALF_DAYS_IN_DAY       = Rational(1, 2) # :nodoc:\n  HOURS_IN_DAY           = Rational(1, 24) # :nodoc:\n  MINUTES_IN_DAY         = Rational(1, 1440) # :nodoc:\n  SECONDS_IN_DAY         = Rational(1, 86400) # :nodoc:\n  MILLISECONDS_IN_DAY    = Rational(1, 86400*10**3) # :nodoc:\n  NANOSECONDS_IN_DAY     = Rational(1, 86400*10**9) # :nodoc:\n  MILLISECONDS_IN_SECOND = Rational(1, 10**3) # :nodoc:\n  NANOSECONDS_IN_SECOND  = Rational(1, 10**9) # :nodoc:\n\n  MJD_EPOCH_IN_AJD       = Rational(4800001, 2) # 1858-11-17 # :nodoc:\n  UNIX_EPOCH_IN_AJD      = Rational(4881175, 2) # 1970-01-01 # :nodoc:\n  MJD_EPOCH_IN_CJD       = 2400001 # :nodoc:\n  UNIX_EPOCH_IN_CJD      = 2440588 # :nodoc:\n  LD_EPOCH_IN_CJD        = 2299160 # :nodoc:\n\n  # Does a given Julian Day Number fall inside the old-style (Julian)\n  # calendar?\n  #\n  # +jd+ is the Julian Day Number in question. +sg+ may be Date::GREGORIAN,\n  # in which case the answer is false; it may be Date::JULIAN, in which case\n  # the answer is true; or it may a number representing the Day of\n  # Calendar Reform. Date::ENGLAND and Date::ITALY are two possible such\n  # days.\n\n  def self.julian? (jd, sg)\n    case sg\n    when Numeric\n      jd < sg\n    else\n      if $VERBOSE\n\twarn(\"#{caller.shift.sub(/:in .*/, '')}: \" \\\n\"warning: do not use non-numerical object as julian day number anymore\")\n      end\n      not sg\n    end\n  end\n\n  # Does a given Julian Day Number fall inside the new-style (Gregorian)\n  # calendar?\n  #\n  # The reverse of self.os?  See the documentation for that method for\n  # more details.\n  def self.gregorian? (jd, sg) !julian?(jd, sg) end\n\n  def self.fix_style(jd, sg) # :nodoc:\n    if julian?(jd, sg)\n    then JULIAN\n    else GREGORIAN end\n  end\n\n  private_class_method :fix_style\n\n  # Convert an Ordinal Date to a Julian Day Number.\n  #\n  # +y+ and +d+ are the year and day-of-year to convert.\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # Returns the corresponding Julian Day Number.\n  def self.ordinal_to_jd(y, d, sg=GREGORIAN)\n    civil_to_jd(y, 1, d, sg)\n  end\n\n  # Convert a Julian Day Number to an Ordinal Date.\n  #\n  # +jd+ is the Julian Day Number to convert.\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # Returns the corresponding Ordinal Date as\n  # [year, day_of_year]\n  def self.jd_to_ordinal(jd, sg=GREGORIAN)\n    y = jd_to_civil(jd, sg)[0]\n    doy = jd - civil_to_jd(y - 1, 12, 31, fix_style(jd, sg))\n    return y, doy\n  end\n\n  # Convert a Civil Date to a Julian Day Number.\n  # +y+, +m+, and +d+ are the year, month, and day of the\n  # month.  +sg+ specifies the Day of Calendar Reform.\n  #\n  # Returns the corresponding Julian Day Number.\n  def self.civil_to_jd(y, m, d, sg=GREGORIAN)\n    if m <= 2\n      y -= 1\n      m += 12\n    end\n    a = (y / 100.0).floor\n    b = 2 - a + (a / 4.0).floor\n    jd = (365.25 * (y + 4716)).floor +\n      (30.6001 * (m + 1)).floor +\n      d + b - 1524\n    if julian?(jd, sg)\n      jd -= b\n    end\n    jd\n  end\n\n  # Convert a Julian Day Number to a Civil Date.  +jd+ is\n  # the Julian Day Number. +sg+ specifies the Day of\n  # Calendar Reform.\n  #\n  # Returns the corresponding [year, month, day_of_month]\n  # as a three-element array.\n  def self.jd_to_civil(jd, sg=GREGORIAN)\n    if julian?(jd, sg)\n      a = jd\n    else\n      x = ((jd - 1867216.25) / 36524.25).floor\n      a = jd + 1 + x - (x / 4.0).floor\n    end\n    b = a + 1524\n    c = ((b - 122.1) / 365.25).floor\n    d = (365.25 * c).floor\n    e = ((b - d) / 30.6001).floor\n    dom = b - d - (30.6001 * e).floor\n    if e <= 13\n      m = e - 1\n      y = c - 4716\n    else\n      m = e - 13\n      y = c - 4715\n    end\n    return y, m, dom\n  end\n\n  # Convert a Commercial Date to a Julian Day Number.\n  #\n  # +y+, +w+, and +d+ are the (commercial) year, week of the year,\n  # and day of the week of the Commercial Date to convert.\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.commercial_to_jd(y, w, d, ns=GREGORIAN)\n    jd = civil_to_jd(y, 1, 4, ns)\n    (jd - (((jd - 1) + 1) % 7)) +\n      7 * (w - 1) +\n      (d - 1)\n  end\n\n  # Convert a Julian Day Number to a Commercial Date\n  #\n  # +jd+ is the Julian Day Number to convert.\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # Returns the corresponding Commercial Date as\n  # [commercial_year, week_of_year, day_of_week]\n  def self.jd_to_commercial(jd, sg=GREGORIAN)\n    ns = fix_style(jd, sg)\n    a = jd_to_civil(jd - 3, ns)[0]\n    y = if jd >= commercial_to_jd(a + 1, 1, 1, ns) then a + 1 else a end\n    w = 1 + ((jd - commercial_to_jd(y, 1, 1, ns)) / 7).floor\n    d = (jd + 1) % 7\n    d = 7 if d == 0\n    return y, w, d\n  end\n\n  def self.weeknum_to_jd(y, w, d, f=0, ns=GREGORIAN) # :nodoc:\n    a = civil_to_jd(y, 1, 1, ns) + 6\n    (a - ((a - f) + 1) % 7 - 7) + 7 * w + d\n  end\n\n  def self.jd_to_weeknum(jd, f=0, sg=GREGORIAN) # :nodoc:\n    ns = fix_style(jd, sg)\n    y, m, d = jd_to_civil(jd, ns)\n    a = civil_to_jd(y, 1, 1, ns) + 6\n    w, d = (jd - (a - ((a - f) + 1) % 7) + 7).divmod(7)\n    return y, w, d\n  end\n\n  private_class_method :weeknum_to_jd, :jd_to_weeknum\n\n  # Convert an Astronomical Julian Day Number to a (civil) Julian\n  # Day Number.\n  #\n  # +ajd+ is the Astronomical Julian Day Number to convert.\n  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).\n  #\n  # Returns the (civil) Julian Day Number as [day_number,\n  # fraction] where +fraction+ is always 1/2.\n  def self.ajd_to_jd(ajd, of=0) (ajd + of + HALF_DAYS_IN_DAY).divmod(1) end\n\n  # Convert a (civil) Julian Day Number to an Astronomical Julian\n  # Day Number.\n  #\n  # +jd+ is the Julian Day Number to convert, and +fr+ is a\n  # fractional day.\n  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).\n  #\n  # Returns the Astronomical Julian Day Number as a single\n  # numeric value.\n  def self.jd_to_ajd(jd, fr, of=0) jd + fr - of - HALF_DAYS_IN_DAY end\n\n  # Convert a fractional day +fr+ to [hours, minutes, seconds,\n  # fraction_of_a_second]\n  def self.day_fraction_to_time(fr)\n    ss,  fr = fr.divmod(SECONDS_IN_DAY) # 4p\n    h,   ss = ss.divmod(3600)\n    min, s  = ss.divmod(60)\n    return h, min, s, fr\n  end\n\n  # Convert an +h+ hour, +min+ minutes, +s+ seconds period\n  # to a fractional day.\n  begin\n    Rational(Rational(1, 2), 2) # a challenge\n\n    def self.time_to_day_fraction(h, min, s)\n      Rational(h * 3600 + min * 60 + s, 86400) # 4p\n    end\n  rescue\n    def self.time_to_day_fraction(h, min, s)\n\tif Integer === h && Integer === min && Integer === s\n\t  Rational(h * 3600 + min * 60 + s, 86400) # 4p\n\telse\n\t  (h * 3600 + min * 60 + s).to_r/86400 # 4p\n\tend\n    end\n  end\n\n  # Convert an Astronomical Modified Julian Day Number to an\n  # Astronomical Julian Day Number.\n  def self.amjd_to_ajd(amjd) amjd + MJD_EPOCH_IN_AJD end\n\n  # Convert an Astronomical Julian Day Number to an\n  # Astronomical Modified Julian Day Number.\n  def self.ajd_to_amjd(ajd) ajd - MJD_EPOCH_IN_AJD end\n\n  # Convert a Modified Julian Day Number to a Julian\n  # Day Number.\n  def self.mjd_to_jd(mjd) mjd + MJD_EPOCH_IN_CJD end\n\n  # Convert a Julian Day Number to a Modified Julian Day\n  # Number.\n  def self.jd_to_mjd(jd) jd - MJD_EPOCH_IN_CJD end\n\n  # Convert a count of the number of days since the adoption\n  # of the Gregorian Calendar (in Italy) to a Julian Day Number.\n  def self.ld_to_jd(ld) ld + LD_EPOCH_IN_CJD end\n\n  # Convert a Julian Day Number to the number of days since\n  # the adoption of the Gregorian Calendar (in Italy).\n  def self.jd_to_ld(jd) jd - LD_EPOCH_IN_CJD end\n\n  # Convert a Julian Day Number to the day of the week.\n  #\n  # Sunday is day-of-week 0; Saturday is day-of-week 6.\n  def self.jd_to_wday(jd) (jd + 1) % 7 end\n\n  # Is a year a leap year in the Julian calendar?\n  #\n  # All years divisible by 4 are leap years in the Julian calendar.\n  def self.julian_leap? (y) y % 4 == 0 end\n\n  # Is a year a leap year in the Gregorian calendar?\n  #\n  # All years divisible by 4 are leap years in the Gregorian calendar,\n  # except for years divisible by 100 and not by 400.\n  def self.gregorian_leap? (y) y % 4 == 0 && y % 100 != 0 || y % 400 == 0 end\n\n  class << self; alias_method :leap?, :gregorian_leap? end\n  class << self; alias_method :new!, :new end\n\n  # Is +jd+ a valid Julian Day Number?\n  #\n  # If it is, returns it.  In fact, any value is treated as a valid\n  # Julian Day Number.\n  def self.valid_jd? (jd, sg=ITALY) jd end\n\n  # Do the year +y+ and day-of-year +d+ make a valid Ordinal Date?\n  # Returns the corresponding Julian Day Number if they do, or\n  # nil if they don't.\n  #\n  # +d+ can be a negative number, in which case it counts backwards\n  # from the end of the year (-1 being the last day of the year).\n  # No year wraparound is performed, however, so valid values of\n  # +d+ are -365 .. -1, 1 .. 365 on a non-leap-year,\n  # -366 .. -1, 1 .. 366 on a leap year.\n  # A date falling in the period skipped in the Day of Calendar Reform\n  # adjustment is not valid.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.valid_ordinal? (y, d, sg=ITALY)\n    if d < 0\n      ny, = (y + 1).divmod(1)\n      jd = ordinal_to_jd(ny, d + 1, sg)\n      ns = fix_style(jd, sg)\n      return unless [y] == jd_to_ordinal(jd, sg)[0..0]\n      return unless [ny, 1] == jd_to_ordinal(jd - d, ns)\n    else\n      jd = ordinal_to_jd(y, d, sg)\n      return unless [y, d] == jd_to_ordinal(jd, sg)\n    end\n    jd\n  end\n\n  # Do year +y+, month +m+, and day-of-month +d+ make a\n  # valid Civil Date?  Returns the corresponding Julian\n  # Day Number if they do, nil if they don't.\n  #\n  # +m+ and +d+ can be negative, in which case they count\n  # backwards from the end of the year and the end of the\n  # month respectively.  No wraparound is performed, however,\n  # and invalid values cause an ArgumentError to be raised.\n  # A date falling in the period skipped in the Day of Calendar\n  # Reform adjustment is not valid.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.valid_civil? (y, m, d, sg=ITALY)\n    if m < 0\n      m += 13\n    end\n    if d < 0\n      ny, nm = (y * 12 + m).divmod(12)\n      nm,    = (nm + 1).divmod(1)\n      jd = civil_to_jd(ny, nm, d + 1, sg)\n      ns = fix_style(jd, sg)\n      return unless [y, m] == jd_to_civil(jd, sg)[0..1]\n      return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)\n    else\n      jd = civil_to_jd(y, m, d, sg)\n      return unless [y, m, d] == jd_to_civil(jd, sg)\n    end\n    jd\n  end\n\n  class << self; alias_method :valid_date?, :valid_civil? end\n\n  # Do year +y+, week-of-year +w+, and day-of-week +d+ make a\n  # valid Commercial Date?  Returns the corresponding Julian\n  # Day Number if they do, nil if they don't.\n  #\n  # Monday is day-of-week 1; Sunday is day-of-week 7.\n  #\n  # +w+ and +d+ can be negative, in which case they count\n  # backwards from the end of the year and the end of the\n  # week respectively.  No wraparound is performed, however,\n  # and invalid values cause an ArgumentError to be raised.\n  # A date falling in the period skipped in the Day of Calendar\n  # Reform adjustment is not valid.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.valid_commercial? (y, w, d, sg=ITALY)\n    if d < 0\n      d += 8\n    end\n    if w < 0\n      ny, nw, nd =\n\tjd_to_commercial(commercial_to_jd(y + 1, 1, 1) + w * 7)\n      return unless ny == y\n      w = nw\n    end\n    jd = commercial_to_jd(y, w, d)\n    return unless gregorian?(jd, sg)\n    return unless [y, w, d] == jd_to_commercial(jd)\n    jd\n  end\n\n  def self.valid_weeknum? (y, w, d, f, sg=ITALY) # :nodoc:\n    if d < 0\n      d += 7\n    end\n    if w < 0\n      ny, nw, nd, nf =\n\tjd_to_weeknum(weeknum_to_jd(y + 1, 1, f, f) + w * 7, f)\n      return unless ny == y\n      w = nw\n    end\n    jd = weeknum_to_jd(y, w, d, f)\n    return unless gregorian?(jd, sg)\n    return unless [y, w, d] == jd_to_weeknum(jd, f)\n    jd\n  end\n\n  private_class_method :valid_weeknum?\n\n  # Do hour +h+, minute +min+, and second +s+ constitute a valid time?\n  #\n  # If they do, returns their value as a fraction of a day.  If not,\n  # returns nil.\n  #\n  # The 24-hour clock is used.  Negative values of +h+, +min+, and\n  # +sec+ are treating as counting backwards from the end of the\n  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No\n  # wraparound is performed.\n  def self.valid_time? (h, min, s)\n    h   += 24 if h   < 0\n    min += 60 if min < 0\n    s   += 60 if s   < 0\n    return unless ((0...24) === h &&\n\t\t   (0...60) === min &&\n\t\t   (0...60) === s) ||\n\t\t  (24 == h &&\n\t\t    0 == min &&\n\t\t    0 == s)\n    time_to_day_fraction(h, min, s)\n  end\n\n  # Create a new Date object from a Julian Day Number.\n  #\n  # +jd+ is the Julian Day Number; if not specified, it defaults to\n  # 0.\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.jd(jd=0, sg=ITALY)\n    jd = valid_jd?(jd, sg)\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  # Create a new Date object from an Ordinal Date, specified\n  # by year +y+ and day-of-year +d+. +d+ can be negative,\n  # in which it counts backwards from the end of the year.\n  # No year wraparound is performed, however.  An invalid\n  # value for +d+ results in an ArgumentError being raised.\n  #\n  # +y+ defaults to -4712, and +d+ to 1; this is Julian Day\n  # Number day 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.ordinal(y=-4712, d=1, sg=ITALY)\n    unless jd = valid_ordinal?(y, d, sg)\n      raise ArgumentError, 'invalid date'\n    end\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  # Create a new Date object for the Civil Date specified by\n  # year +y+, month +m+, and day-of-month +d+.\n  #\n  # +m+ and +d+ can be negative, in which case they count\n  # backwards from the end of the year and the end of the\n  # month respectively.  No wraparound is performed, however,\n  # and invalid values cause an ArgumentError to be raised.\n  # can be negative\n  #\n  # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is\n  # Julian Day Number day 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.civil(y=-4712, m=1, d=1, sg=ITALY)\n    unless jd = valid_civil?(y, m, d, sg)\n      raise ArgumentError, 'invalid date'\n    end\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  class << self; alias_method :new, :civil end\n\n  # Create a new Date object for the Commercial Date specified by\n  # year +y+, week-of-year +w+, and day-of-week +d+.\n  #\n  # Monday is day-of-week 1; Sunday is day-of-week 7.\n  #\n  # +w+ and +d+ can be negative, in which case they count\n  # backwards from the end of the year and the end of the\n  # week respectively.  No wraparound is performed, however,\n  # and invalid values cause an ArgumentError to be raised.\n  #\n  # +y+ defaults to 1582, +w+ to 41, and +d+ to 5, the Day of\n  # Calendar Reform for Italy and the Catholic countries.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.commercial(y=1582, w=41, d=5, sg=ITALY)\n    unless jd = valid_commercial?(y, w, d, sg)\n      raise ArgumentError, 'invalid date'\n    end\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  def self.weeknum(y=1582, w=41, d=5, f=0, sg=ITALY) # :nodoc:\n    unless jd = valid_weeknum?(y, w, d, f, sg)\n      raise ArgumentError, 'invalid date'\n    end\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  private_class_method :weeknum\n\n  def self.rewrite_frags(elem) # :nodoc:\n    elem ||= {}\n    if seconds = elem[:seconds]\n      d,   fr = seconds.divmod(86400)\n      h,   fr = fr.divmod(3600)\n      min, fr = fr.divmod(60)\n      s,   fr = fr.divmod(1)\n      elem[:jd] = UNIX_EPOCH_IN_CJD + d\n      elem[:hour] = h\n      elem[:min] = min\n      elem[:sec] = s\n      elem[:sec_fraction] = fr\n      elem.delete(:seconds)\n      elem.delete(:offset)\n    end\n    elem\n  end\n\n  private_class_method :rewrite_frags\n\n  def self.complete_frags(elem) # :nodoc:\n    i = 0\n    g = [[:time, [:hour, :min, :sec]],\n\t [nil, [:jd]],\n\t [:ordinal, [:year, :yday, :hour, :min, :sec]],\n\t [:civil, [:year, :mon, :mday, :hour, :min, :sec]],\n\t [:commercial, [:cwyear, :cweek, :cwday, :hour, :min, :sec]],\n\t [:wday, [:wday, :hour, :min, :sec]],\n\t [:wnum0, [:year, :wnum0, :wday, :hour, :min, :sec]],\n\t [:wnum1, [:year, :wnum1, :wday, :hour, :min, :sec]],\n\t [nil, [:cwyear, :cweek, :wday, :hour, :min, :sec]],\n\t [nil, [:year, :wnum0, :cwday, :hour, :min, :sec]],\n\t [nil, [:year, :wnum1, :cwday, :hour, :min, :sec]]].\n      collect{|k, a| e = elem.values_at(*a).compact; [k, a, e]}.\n      select{|k, a, e| e.size > 0}.\n      sort_by{|k, a, e| [e.size, i -= 1]}.last\n\n    d = nil\n\n    if g && g[0] && (g[1].size - g[2].size) != 0\n      d ||= Date.today\n\n      case g[0]\n      when :ordinal\n\telem[:year] ||= d.year\n\telem[:yday] ||= 1\n      when :civil\n\tg[1].each do |e|\n\t  break if elem[e]\n\t  elem[e] = d.__send__(e)\n\tend\n\telem[:mon]  ||= 1\n\telem[:mday] ||= 1\n      when :commercial\n\tg[1].each do |e|\n\t  break if elem[e]\n\t  elem[e] = d.__send__(e)\n\tend\n\telem[:cweek] ||= 1\n\telem[:cwday] ||= 1\n      when :wday\n\telem[:jd] ||= (d - d.wday + elem[:wday]).jd\n      when :wnum0\n\tg[1].each do |e|\n\t  break if elem[e]\n\t  elem[e] = d.__send__(e)\n\tend\n\telem[:wnum0] ||= 0\n\telem[:wday]  ||= 0\n      when :wnum1\n\tg[1].each do |e|\n\t  break if elem[e]\n\t  elem[e] = d.__send__(e)\n\tend\n\telem[:wnum1] ||= 0\n\telem[:wday]  ||= 0\n      end\n    end\n\n    if g && g[0] == :time\n      if self <= DateTime\n\td ||= Date.today\n\telem[:jd] ||= d.jd\n      end\n    end\n\n    elem[:hour] ||= 0\n    elem[:min]  ||= 0\n    elem[:sec]  ||= 0\n    elem[:sec] = [elem[:sec], 59].min\n\n    elem\n  end\n\n  private_class_method :complete_frags\n\n  def self.valid_date_frags?(elem, sg) # :nodoc:\n    catch :jd do\n      a = elem.values_at(:jd)\n      if a.all?\n\tif jd = valid_jd?(*(a << sg))\n\t  throw :jd, jd\n\tend\n      end\n\n      a = elem.values_at(:year, :yday)\n      if a.all?\n\tif jd = valid_ordinal?(*(a << sg))\n\t  throw :jd, jd\n\tend\n      end\n\n      a = elem.values_at(:year, :mon, :mday)\n      if a.all?\n\tif jd = valid_civil?(*(a << sg))\n\t  throw :jd, jd\n\tend\n      end\n\n      a = elem.values_at(:cwyear, :cweek, :cwday)\n      if a[2].nil? && elem[:wday]\n\ta[2] = elem[:wday].nonzero? || 7\n      end\n      if a.all?\n\tif jd = valid_commercial?(*(a << sg))\n\t  throw :jd, jd\n\tend\n      end\n\n      a = elem.values_at(:year, :wnum0, :wday)\n      if a[2].nil? && elem[:cwday]\n\ta[2] = elem[:cwday] % 7\n      end\n      if a.all?\n\tif jd = valid_weeknum?(*(a << 0 << sg))\n\t  throw :jd, jd\n\tend\n      end\n\n      a = elem.values_at(:year, :wnum1, :wday)\n      if a[2]\n\ta[2] = (a[2] - 1) % 7\n      end\n      if a[2].nil? && elem[:cwday]\n\ta[2] = (elem[:cwday] - 1) % 7\n      end\n      if a.all?\n\tif jd = valid_weeknum?(*(a << 1 << sg))\n\t  throw :jd, jd\n\tend\n      end\n    end\n  end\n\n  private_class_method :valid_date_frags?\n\n  def self.valid_time_frags? (elem) # :nodoc:\n    h, min, s = elem.values_at(:hour, :min, :sec)\n    valid_time?(h, min, s)\n  end\n\n  private_class_method :valid_time_frags?\n\n  def self.new_by_frags(elem, sg) # :nodoc:\n    elem = rewrite_frags(elem)\n    elem = complete_frags(elem)\n    unless jd = valid_date_frags?(elem, sg)\n      raise ArgumentError, 'invalid date'\n    end\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  private_class_method :new_by_frags\n\n  # Create a new Date object by parsing from a String\n  # according to a specified format.\n  #\n  # +str+ is a String holding a date representation.\n  # +fmt+ is the format that the date is in.  See\n  # date/format.rb for details on supported formats.\n  #\n  # The default +str+ is '-4712-01-01', and the default\n  # +fmt+ is '%F', which means Year-Month-Day_of_Month.\n  # This gives Julian Day Number day 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # An ArgumentError will be raised if +str+ cannot be\n  # parsed.\n  def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)\n    elem = _strptime(str, fmt)\n    new_by_frags(elem, sg)\n  end\n\n  # Create a new Date object by parsing from a String,\n  # without specifying the format.\n  #\n  # +str+ is a String holding a date representation.\n  # +comp+ specifies whether to interpret 2-digit years\n  # as 19XX (>= 69) or 20XX (< 69); the default is not to.\n  # The method will attempt to parse a date from the String\n  # using various heuristics; see #_parse in date/format.rb\n  # for more details.  If parsing fails, an ArgumentError\n  # will be raised.\n  #\n  # The default +str+ is '-4712-01-01'; this is Julian\n  # Day Number day 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.parse(str='-4712-01-01', comp=false, sg=ITALY)\n    elem = _parse(str, comp)\n    new_by_frags(elem, sg)\n  end\n\n  class << self\n\n    def once(*ids) # :nodoc:\n      for id in ids\n\tmodule_eval <<-\"end;\"\n\t  alias_method :__#{id.to_i}__, :#{id.to_s}\n\t  private :__#{id.to_i}__\n\t  def #{id.to_s}(*args, &block)\n\t    (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]\n\t  end\n\tend;\n      end\n    end\n\n    private :once\n\n  end\n\n  # *NOTE* this is the documentation for the method new!().  If\n  # you are reading this as the documentation for new(), that is\n  # because rdoc doesn't fully support the aliasing of the\n  # initialize() method.\n  # new() is in\n  # fact an alias for #civil(): read the documentation for that\n  # method instead.\n  #\n  # Create a new Date object.\n  #\n  # +ajd+ is the Astronomical Julian Day Number.\n  # +of+ is the offset from UTC as a fraction of a day.\n  # Both default to 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform to use for this\n  # Date object.\n  #\n  # Using one of the factory methods such as Date::civil is\n  # generally easier and safer.\n  def initialize(ajd=0, of=0, sg=ITALY) @ajd, @of, @sg = ajd, of, sg end\n\n  # Get the date as an Astronomical Julian Day Number.\n  def ajd() @ajd end\n\n  # Get the date as an Astronomical Modified Julian Day Number.\n  def amjd() self.class.ajd_to_amjd(@ajd) end\n\n  once :amjd\n\n  # Get the date as a Julian Day Number.\n  def jd() self.class.ajd_to_jd(@ajd, @of)[0] end\n\n  # Get any fractional day part of the date.\n  def day_fraction() self.class.ajd_to_jd(@ajd, @of)[1] end\n\n  # Get the date as a Modified Julian Day Number.\n  def mjd() self.class.jd_to_mjd(jd) end\n\n  # Get the date as the number of days since the Day of Calendar\n  # Reform (in Italy and the Catholic countries).\n  def ld() self.class.jd_to_ld(jd) end\n\n  once :jd, :day_fraction, :mjd, :ld\n\n  # Get the date as a Civil Date, [year, month, day_of_month]\n  def civil() self.class.jd_to_civil(jd, @sg) end # :nodoc:\n\n  # Get the date as an Ordinal Date, [year, day_of_year]\n  def ordinal() self.class.jd_to_ordinal(jd, @sg) end # :nodoc:\n\n  # Get the date as a Commercial Date, [year, week_of_year, day_of_week]\n  def commercial() self.class.jd_to_commercial(jd, @sg) end # :nodoc:\n\n  def weeknum0() self.class.__send__(:jd_to_weeknum, jd, 0, @sg) end # :nodoc:\n  def weeknum1() self.class.__send__(:jd_to_weeknum, jd, 1, @sg) end # :nodoc:\n\n  once :civil, :ordinal, :commercial, :weeknum0, :weeknum1\n  private :civil, :ordinal, :commercial, :weeknum0, :weeknum1\n\n  # Get the year of this date.\n  def year() civil[0] end\n\n  # Get the day-of-the-year of this date.\n  #\n  # January 1 is day-of-the-year 1\n  def yday() ordinal[1] end\n\n  # Get the month of this date.\n  #\n  # January is month 1.\n  def mon() civil[1] end\n\n  # Get the day-of-the-month of this date.\n  def mday() civil[2] end\n\n  alias_method :month, :mon\n  alias_method :day, :mday\n\n  def wnum0() weeknum0[1] end # :nodoc:\n  def wnum1() weeknum1[1] end # :nodoc:\n\n  private :wnum0, :wnum1\n\n  # Get the time of this date as [hours, minutes, seconds,\n  # fraction_of_a_second]\n  def time() self.class.day_fraction_to_time(day_fraction) end # :nodoc:\n\n  once :time\n  private :time\n\n  # Get the hour of this date.\n  def hour() time[0] end\n\n  # Get the minute of this date.\n  def min() time[1] end\n\n  # Get the second of this date.\n  def sec() time[2] end\n\n  # Get the fraction-of-a-second of this date.  The unit is in days.\n  # I do NOT recommend you to use this method.\n  def sec_fraction() time[3] end\n\n=begin\n  alias_method :minute, :min\n  alias_method :second, :sec\n  alias_method :second_fraction, :sec_fraction\n=end\n\n  private :hour, :min, :sec, :sec_fraction\n#\t  :minute, :second, :second_fraction\n\n  def zone() strftime('%:z') end\n\n  private :zone\n\n  # Get the commercial year of this date.  See *Commercial* *Date*\n  # in the introduction for how this differs from the normal year.\n  def cwyear() commercial[0] end\n\n  # Get the commercial week of the year of this date.\n  def cweek() commercial[1] end\n\n  # Get the commercial day of the week of this date.  Monday is\n  # commercial day-of-week 1; Sunday is commercial day-of-week 7.\n  def cwday() commercial[2] end\n\n  # Get the week day of this date.  Sunday is day-of-week 0;\n  # Saturday is day-of-week 6.\n  def wday() self.class.jd_to_wday(jd) end\n\n  once :wday\n\n=begin\n  MONTHNAMES.each_with_index do |n, i|\n    if n\n      define_method(n.downcase + '?'){mon == i}\n    end\n  end\n\n  DAYNAMES.each_with_index do |n, i|\n    define_method(n.downcase + '?'){wday == i}\n  end\n=end\n\n  # Is the current date old-style (Julian Calendar)?\n  def julian? () self.class.julian?(jd, @sg) end\n\n  # Is the current date new-style (Gregorian Calendar)?\n  def gregorian? () self.class.gregorian?(jd, @sg) end\n\n  once :julian?, :gregorian?\n\n  def fix_style # :nodoc:\n    if julian?\n    then self.class::JULIAN\n    else self.class::GREGORIAN end\n  end\n\n  private :fix_style\n\n  # Is this a leap year?\n  def leap?\n    self.class.jd_to_civil(self.class.civil_to_jd(year, 3, 1, fix_style) - 1,\n\t\t     fix_style)[-1] == 29\n  end\n\n  once :leap?\n\n  # When is the Day of Calendar Reform for this Date object?\n  def start() @sg end\n\n  # Create a copy of this Date object using a new Day of Calendar Reform.\n  def new_start(sg=self.class::ITALY) self.class.new!(@ajd, @of, sg) end\n\n  # Create a copy of this Date object that uses the Italian/Catholic\n  # Day of Calendar Reform.\n  def italy() new_start(self.class::ITALY) end\n\n  # Create a copy of this Date object that uses the English/Colonial\n  # Day of Calendar Reform.\n  def england() new_start(self.class::ENGLAND) end\n\n  # Create a copy of this Date object that always uses the Julian\n  # Calendar.\n  def julian() new_start(self.class::JULIAN) end\n\n  # Create a copy of this Date object that always uses the Gregorian\n  # Calendar.\n  def gregorian() new_start(self.class::GREGORIAN) end\n\n  def offset() @of end\n\n  def new_offset(of=0)\n    if String === of\n      of = Rational(zone_to_diff(of) || 0, 86400)\n    end\n    self.class.new!(@ajd, of, @sg)\n  end\n\n  private :offset, :new_offset\n\n  # Return a new Date object that is +n+ days later than the\n  # current one.\n  #\n  # +n+ may be a negative value, in which case the new Date\n  # is earlier than the current one; however, #-() might be\n  # more intuitive.\n  #\n  # If +n+ is not a Numeric, a TypeError will be thrown.  In\n  # particular, two Dates cannot be added to each other.\n  def + (n)\n    case n\n    when Numeric; return self.class.new!(@ajd + n, @of, @sg)\n    end\n    raise TypeError, 'expected numeric'\n  end\n\n  # If +x+ is a Numeric value, create a new Date object that is\n  # +x+ days earlier than the current one.\n  #\n  # If +x+ is a Date, return the number of days between the\n  # two dates; or, more precisely, how many days later the current\n  # date is than +x+.\n  #\n  # If +x+ is neither Numeric nor a Date, a TypeError is raised.\n  def - (x)\n    case x\n    when Numeric; return self.class.new!(@ajd - x, @of, @sg)\n    when Date;    return @ajd - x.ajd\n    end\n    raise TypeError, 'expected numeric or date'\n  end\n\n  # Compare this date with another date.\n  #\n  # +other+ can also be a Numeric value, in which case it is\n  # interpreted as an Astronomical Julian Day Number.\n  #\n  # Comparison is by Astronomical Julian Day Number, including\n  # fractional days.  This means that both the time and the\n  # timezone offset are taken into account when comparing\n  # two DateTime instances.  When comparing a DateTime instance\n  # with a Date instance, the time of the latter will be\n  # considered as falling on midnight UTC.\n  def <=> (other)\n    case other\n    when Numeric; return @ajd <=> other\n    when Date;    return @ajd <=> other.ajd\n    end\n    nil\n  end\n\n  # The relationship operator for Date.\n  #\n  # Compares dates by Julian Day Number.  When comparing\n  # two DateTime instances, or a DateTime with a Date,\n  # the instances will be regarded as equivalent if they\n  # fall on the same date in local time.\n  def === (other)\n    case other\n    when Numeric; return jd == other\n    when Date;    return jd == other.jd\n    end\n    false\n  end\n\n  def next_day(n=1) self + n end\n# def prev_day(n=1) self - n end\n\n  private :next_day\n\n  # Return a new Date one day after this one.\n  def next() next_day end\n\n  alias_method :succ, :next\n\n  # Return a new Date object that is +n+ months later than\n  # the current one.\n  #\n  # If the day-of-the-month of the current Date is greater\n  # than the last day of the target month, the day-of-the-month\n  # of the returned Date will be the last day of the target month.\n  def >> (n)\n    y, m = (year * 12 + (mon - 1) + n).divmod(12)\n    m,   = (m + 1)                    .divmod(1)\n    d = mday\n    d -= 1 until jd2 = self.class.valid_civil?(y, m, d, fix_style)\n    self + (jd2 - jd)\n  end\n\n  # Return a new Date object that is +n+ months earlier than\n  # the current one.\n  #\n  # If the day-of-the-month of the current Date is greater\n  # than the last day of the target month, the day-of-the-month\n  # of the returned Date will be the last day of the target month.\n  def << (n) self >> -n end\n\n=begin\n  def next_month(n=1) self >> n end\n  def prev_month(n=1) self << n end\n\n  def next_year(n=1) self >> n * 12 end\n  def prev_year(n=1) self << n * 12 end\n=end\n\n#  require 'enumerator'\n\n  # Step the current date forward +step+ days at a\n  # time (or backward, if +step+ is negative) until\n  # we reach +limit+ (inclusive), yielding the resultant\n  # date at each step.\n  def step(limit, step=1) # :yield: date\n=begin\n    if step.zero?\n      raise ArgumentError, \"step can't be 0\"\n    end\n=end\n=begin\n    unless block_given?\n      return to_enum(:step, limit, step)\n    end\n=end\n    da = self\n    op = %w(- <= >=)[step <=> 0]\n    while da.__send__(op, limit)\n      yield da\n      da += step\n    end\n    self\n  end\n\n  # Step forward one day at a time until we reach +max+\n  # (inclusive), yielding each date as we go.\n  def upto(max, &block) # :yield: date\n    step(max, +1, &block)\n  end\n\n  # Step backward one day at a time until we reach +min+\n  # (inclusive), yielding each date as we go.\n  def downto(min, &block) # :yield: date\n    step(min, -1, &block)\n  end\n\n  # Is this Date equal to +other+?\n  #\n  # +other+ must both be a Date object, and represent the same date.\n  def eql? (other) Date === other && self == other end\n\n  # Calculate a hash value for this date.\n  def hash() @ajd.hash end\n\n  # Return internal object state as a programmer-readable string.\n  def inspect() format('#<%s: %s,%s,%s>', self.class, @ajd, @of, @sg) end\n\n  # Return the date as a human-readable string.\n  #\n  # The format used is YYYY-MM-DD.\n  def to_s() format('%.4d-%02d-%02d', year, mon, mday) end # 4p\n\n  # Dump to Marshal format.\n  def _dump(limit) Marshal.dump([@ajd, @of, @sg], -1) end\n\n# def self._load(str) new!(*Marshal.load(str)) end\n\n  # Load from Marshal format.\n  def self._load(str)\n    a = Marshal.load(str)\n    if a.size == 2\n      ajd,     sg = a\n           of = 0\n      ajd -= 1.to_r/2\n    else\n      ajd, of, sg = a\n    end\n    new!(ajd, of, sg)\n  end\n\nend\n\n# Class representing a date and time.\n#\n# See the documentation to the file date.rb for an overview.\n#\n# DateTime objects are immutable once created.\n#\n# == Other methods.\n#\n# The following methods are defined in Date, but declared private\n# there.  They are made public in DateTime.  They are documented\n# here.\n#\n# === hour()\n#\n# Get the hour-of-the-day of the time.  This is given\n# using the 24-hour clock, counting from midnight.  The first\n# hour after midnight is hour 0; the last hour of the day is\n# hour 23.\n#\n# === min()\n#\n# Get the minute-of-the-hour of the time.\n#\n# === sec()\n#\n# Get the second-of-the-minute of the time.\n#\n# === sec_fraction()\n#\n# Get the fraction of a second of the time.  This is returned as\n# a +Rational+.  The unit is in days.\n# I do NOT recommend you to use this method.\n#\n# === zone()\n#\n# Get the time zone as a String.  This is representation of the\n# time offset such as \"+1000\", not the true time-zone name.\n#\n# === offset()\n#\n# Get the time zone offset as a fraction of a day.  This is returned\n# as a +Rational+.\n#\n# === new_offset(of=0)\n#\n# Create a new DateTime object, identical to the current one, except\n# with a new time zone offset of +of+.  +of+ is the new offset from\n# UTC as a fraction of a day.\n#\nclass DateTime < Date\n\n  # Create a new DateTime object corresponding to the specified\n  # Julian Day Number +jd+ and hour +h+, minute +min+, second +s+.\n  #\n  # The 24-hour clock is used.  Negative values of +h+, +min+, and\n  # +sec+ are treating as counting backwards from the end of the\n  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No\n  # wraparound is performed.  If an invalid time portion is specified,\n  # an ArgumentError is raised.\n  #\n  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # All day/time values default to 0.\n  def self.jd(jd=0, h=0, min=0, s=0, of=0, sg=ITALY)\n    unless (jd = valid_jd?(jd, sg)) &&\n\t   (fr = valid_time?(h, min, s))\n      raise ArgumentError, 'invalid date'\n    end\n    if String === of\n      of = Rational(zone_to_diff(of) || 0, 86400)\n    end\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  # Create a new DateTime object corresponding to the specified\n  # Ordinal Date and hour +h+, minute +min+, second +s+.\n  #\n  # The 24-hour clock is used.  Negative values of +h+, +min+, and\n  # +sec+ are treating as counting backwards from the end of the\n  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No\n  # wraparound is performed.  If an invalid time portion is specified,\n  # an ArgumentError is raised.\n  #\n  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # +y+ defaults to -4712, and +d+ to 1; this is Julian Day Number\n  # day 0.  The time values default to 0.\n  def self.ordinal(y=-4712, d=1, h=0, min=0, s=0, of=0, sg=ITALY)\n    unless (jd = valid_ordinal?(y, d, sg)) &&\n\t   (fr = valid_time?(h, min, s))\n      raise ArgumentError, 'invalid date'\n    end\n    if String === of\n      of = Rational(zone_to_diff(of) || 0, 86400)\n    end\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  # Create a new DateTime object corresponding to the specified\n  # Civil Date and hour +h+, minute +min+, second +s+.\n  #\n  # The 24-hour clock is used.  Negative values of +h+, +min+, and\n  # +sec+ are treating as counting backwards from the end of the\n  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No\n  # wraparound is performed.  If an invalid time portion is specified,\n  # an ArgumentError is raised.\n  #\n  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # +y+ defaults to -4712, +m+ to 1, and +d+ to 1; this is Julian Day\n  # Number day 0.  The time values default to 0.\n  def self.civil(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=ITALY)\n    unless (jd = valid_civil?(y, m, d, sg)) &&\n\t   (fr = valid_time?(h, min, s))\n      raise ArgumentError, 'invalid date'\n    end\n    if String === of\n      of = Rational(zone_to_diff(of) || 0, 86400)\n    end\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  class << self; alias_method :new, :civil end\n\n  # Create a new DateTime object corresponding to the specified\n  # Commercial Date and hour +h+, minute +min+, second +s+.\n  #\n  # The 24-hour clock is used.  Negative values of +h+, +min+, and\n  # +sec+ are treating as counting backwards from the end of the\n  # next larger unit (e.g. a +min+ of -2 is treated as 58).  No\n  # wraparound is performed.  If an invalid time portion is specified,\n  # an ArgumentError is raised.\n  #\n  # +of+ is the offset from UTC as a fraction of a day (defaults to 0).\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # +y+ defaults to 1582, +w+ to 41, and +d+ to 5; this is the Day of\n  # Calendar Reform for Italy and the Catholic countries.\n  # The time values default to 0.\n  def self.commercial(y=1582, w=41, d=5, h=0, min=0, s=0, of=0, sg=ITALY)\n    unless (jd = valid_commercial?(y, w, d, sg)) &&\n\t   (fr = valid_time?(h, min, s))\n      raise ArgumentError, 'invalid date'\n    end\n    if String === of\n      of = Rational(zone_to_diff(of) || 0, 86400)\n    end\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  def self.weeknum(y=1582, w=41, d=5, f=0, h=0, min=0, s=0, of=0, sg=ITALY) # :nodoc:\n    unless (jd = valid_weeknum?(y, w, d, f, sg)) &&\n\t   (fr = valid_time?(h, min, s))\n      raise ArgumentError, 'invalid date'\n    end\n    if String === of\n      of = Rational(zone_to_diff(of) || 0, 86400)\n    end\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  private_class_method :weeknum\n\n  def self.new_by_frags(elem, sg) # :nodoc:\n    elem = rewrite_frags(elem)\n    elem = complete_frags(elem)\n    unless (jd = valid_date_frags?(elem, sg)) &&\n\t   (fr = valid_time_frags?(elem))\n      raise ArgumentError, 'invalid date'\n    end\n    fr += (elem[:sec_fraction] || 0) / 86400\n    of = Rational(elem[:offset] || 0, 86400)\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  private_class_method :new_by_frags\n\n  # Create a new DateTime object by parsing from a String\n  # according to a specified format.\n  #\n  # +str+ is a String holding a date-time representation.\n  # +fmt+ is the format that the date-time is in.  See\n  # date/format.rb for details on supported formats.\n  #\n  # The default +str+ is '-4712-01-01T00:00:00+00:00', and the default\n  # +fmt+ is '%FT%T%z'.  This gives midnight on Julian Day Number day 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  #\n  # An ArgumentError will be raised if +str+ cannot be\n  # parsed.\n  def self.strptime(str='-4712-01-01T00:00:00+00:00', fmt='%FT%T%z', sg=ITALY)\n    elem = _strptime(str, fmt)\n    new_by_frags(elem, sg)\n  end\n\n  # Create a new DateTime object by parsing from a String,\n  # without specifying the format.\n  #\n  # +str+ is a String holding a date-time representation.\n  # +comp+ specifies whether to interpret 2-digit years\n  # as 19XX (>= 69) or 20XX (< 69); the default is not to.\n  # The method will attempt to parse a date-time from the String\n  # using various heuristics; see #_parse in date/format.rb\n  # for more details.  If parsing fails, an ArgumentError\n  # will be raised.\n  #\n  # The default +str+ is '-4712-01-01T00:00:00+00:00'; this is Julian\n  # Day Number day 0.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)\n    elem = _parse(str, comp)\n    new_by_frags(elem, sg)\n  end\n\n  public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset\n#\t :minute, :second, :second_fraction\n\n  def to_s # 4p\n    format('%.4d-%02d-%02dT%02d:%02d:%02d%s',\n\t   year, mon, mday, hour, min, sec, zone)\n  end\n\nend\n\nclass Time\n\n#  def to_time() getlocal end\n\n  def to_date\n    jd = Date.civil_to_jd(year, mon, mday, Date::ITALY)\n    Date.new!(Date.jd_to_ajd(jd, 0, 0), 0, Date::ITALY)\n  end\n\n  def to_datetime\n    jd = DateTime.civil_to_jd(year, mon, mday, DateTime::ITALY)\n    fr = DateTime.time_to_day_fraction(hour, min, [sec, 59].min) +\n      Rational(usec, 86400_000_000)\n    of = Rational(utc_offset, 86400)\n    DateTime.new!(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY)\n  end\n\n  private :to_date, :to_datetime\n\nend\n\nclass Date\n\n=begin\n  def to_time() Time.local(year, mon, mday) end\n  def to_date() self end\n  def to_datetime() DateTime.new!(self.class.jd_to_ajd(jd, 0, 0), @of, @sg) end\n=end\n\n  # Create a new Date object representing today.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.today(sg=ITALY)\n    t = Time.now\n    jd = civil_to_jd(t.year, t.mon, t.mday, sg)\n    new!(jd_to_ajd(jd, 0, 0), 0, sg)\n  end\n\n  # Create a new DateTime object representing the current time.\n  #\n  # +sg+ specifies the Day of Calendar Reform.\n  def self.now(sg=ITALY)\n    t = Time.now\n    jd = civil_to_jd(t.year, t.mon, t.mday, sg)\n    fr = time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +\n      Rational(t.usec, 86400_000_000)\n    of = Rational(t.utc_offset, 86400)\n    new!(jd_to_ajd(jd, fr, of), of, sg)\n  end\n\n  private_class_method :now\n\nend\n\nclass DateTime < Date\n\n=begin\n  def to_time\n    d = new_offset(0)\n    d.instance_eval do\n      Time.utc(year, mon, mday, hour, min, sec,\n\t       (sec_fraction * 86400000000).to_i)\n    end.\n\tgetlocal\n  end\n\n  def to_date() Date.new!(self.class.jd_to_ajd(jd, 0, 0), 0, @sg) end\n  def to_datetime() self end\n=end\n\n  private_class_method :today\n  public_class_method  :now\n\nend\n\nclass Date\n\n  class << self\n\n    def deprecated_class_method_alias(old, new) # :nodoc:\n      module_eval <<-\"end;\"\n\tclass << self\n\t  def #{old}(*args, &block)\n\t    if $VERBOSE\n\t      warn(\"\\#{caller.shift.sub(/:in .*/, '')}: \" \\\n\t\t   \"warning: \\#{self}::#{old} is deprecated; \" \\\n\t\t   \"use \\#{self}::#{new}\")\n\t    end\n\t    #{new}(*args, &block)\n\t  end\n\tend\n      end;\n    end\n\n    private :deprecated_class_method_alias\n\n    def deprecated_alias(old, new) # :nodoc:\n      module_eval <<-\"end;\"\n\tdef #{old}(*args, &block)\n\t  if $VERBOSE\n\t    warn(\"\\#{caller.shift.sub(/:in .*/, '')}: \" \\\n\t\t \"warning: \\#{self.class}\\##{old} is deprecated; \" \\\n\t\t \"use \\#{self.class}\\##{new}\")\n\t  end\n\t  #{new}(*args, &block)\n\tend\n      end;\n    end\n\n    private :deprecated_alias\n\n  end\n\n  [ %w(os?\tjulian?),\n    %w(ns?\tgregorian?),\n    %w(exist1?\tvalid_jd?),\n    %w(exist2?\tvalid_ordinal?),\n    %w(exist3?\tvalid_date?),\n    %w(exist?\tvalid_date?),\n    %w(existw?\tvalid_commercial?),\n    %w(new0\tnew!),\n    %w(new1\tjd),\n    %w(new2\tordinal),\n    %w(new3\tnew),\n    %w(neww\tcommercial)\n  ].each do |old, new|\n    deprecated_class_method_alias(old, new)\n  end\n\n  [ %w(os?\tjulian?),\n    %w(ns?\tgregorian?),\n    %w(sg\tstart),\n    %w(newsg\tnew_start),\n    %w(of\toffset),\n    %w(newof\tnew_offset)\n  ].each do |old, new|\n    deprecated_alias(old, new)\n  end\n\n  private :of, :newof\n\nend\n\nclass DateTime < Date\n\n  public :of, :newof\n\nend\n"
  },
  {
    "path": "lib/date2.rb",
    "content": "# date2 was overridden by date.\n# To be precise, date was overridden by date2,\n# and date2 was renamed to date.\n\nrequire 'date'\n"
  },
  {
    "path": "lib/debug.rb",
    "content": "# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n# Copyright (C) 2000  Information-technology Promotion Agency, Japan\n# Copyright (C) 2000-2003  NAKAMURA, Hiroshi  <nahi@ruby-lang.org>\n\nif $SAFE > 0\n  STDERR.print \"-r debug.rb is not available in safe mode\\n\"\n  exit 1\nend\n\nrequire 'tracer'\nrequire 'pp'\n\nclass Tracer\n  def Tracer.trace_func(*vars)\n    Single.trace_func(*vars)\n  end\nend\n\nSCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__\n\nclass DEBUGGER__\nclass Mutex\n  def initialize\n    @locker = nil\n    @waiting = []\n    @locked = false;\n  end\n\n  def locked?\n    @locked\n  end\n\n  def lock\n    return if Thread.critical\n    return if @locker == Thread.current\n    while (Thread.critical = true; @locked)\n      @waiting.push Thread.current\n      Thread.stop\n    end\n    @locked = true\n    @locker = Thread.current\n    Thread.critical = false\n    self\n  end\n\n  def unlock\n    return if Thread.critical\n    return unless @locked\n    unless @locker == Thread.current\n      raise RuntimeError, \"unlocked by other\"\n    end\n    Thread.critical = true\n    t = @waiting.shift\n    @locked = false\n    @locker = nil\n    Thread.critical = false\n    t.run if t\n    self\n  end\nend\nMUTEX = Mutex.new\n\nclass Context\n  DEBUG_LAST_CMD = []\n\n  begin\n    require 'readline'\n    def readline(prompt, hist)\n      Readline::readline(prompt, hist)\n    end\n  rescue LoadError\n    def readline(prompt, hist)\n      STDOUT.print prompt\n      STDOUT.flush\n      line = STDIN.gets\n      exit unless line\n      line.chomp!\n      line\n    end\n    USE_READLINE = false\n  end\n\n  def initialize\n    if Thread.current == Thread.main\n      @stop_next = 1\n    else\n      @stop_next = 0\n    end\n    @last_file = nil\n    @file = nil\n    @line = nil\n    @no_step = nil\n    @frames = []\n    @finish_pos = 0\n    @trace = false\n    @catch = \"StandardError\"\n    @suspend_next = false\n  end\n\n  def stop_next(n=1)\n    @stop_next = n\n  end\n\n  def set_suspend\n    @suspend_next = true\n  end\n\n  def clear_suspend\n    @suspend_next = false\n  end\n\n  def suspend_all\n    DEBUGGER__.suspend\n  end\n\n  def resume_all\n    DEBUGGER__.resume\n  end\n\n  def check_suspend\n    return if Thread.critical\n    while (Thread.critical = true; @suspend_next)\n      DEBUGGER__.waiting.push Thread.current\n      @suspend_next = false\n      Thread.stop\n    end\n    Thread.critical = false\n  end\n\n  def trace?\n    @trace\n  end\n\n  def set_trace(arg)\n    @trace = arg\n  end\n\n  def stdout\n    DEBUGGER__.stdout\n  end\n\n  def break_points\n    DEBUGGER__.break_points\n  end\n\n  def display\n    DEBUGGER__.display\n  end\n\n  def context(th)\n    DEBUGGER__.context(th)\n  end\n\n  def set_trace_all(arg)\n    DEBUGGER__.set_trace(arg)\n  end\n\n  def set_last_thread(th)\n    DEBUGGER__.set_last_thread(th)\n  end\n\n  def debug_eval(str, binding)\n    begin\n      val = eval(str, binding)\n    rescue StandardError, ScriptError => e\n      at = eval(\"caller(1)\", binding)\n      stdout.printf \"%s:%s\\n\", at.shift, e.to_s.sub(/\\(eval\\):1:(in `.*?':)?/, '')\n      for i in at\n\tstdout.printf \"\\tfrom %s\\n\", i\n      end\n      throw :debug_error\n    end\n  end\n\n  def debug_silent_eval(str, binding)\n    begin\n      eval(str, binding)\n    rescue StandardError, ScriptError\n      nil\n    end\n  end\n\n  def var_list(ary, binding)\n    ary.sort!\n    for v in ary\n      stdout.printf \"  %s => %s\\n\", v, eval(v, binding).inspect\n    end\n  end\n\n  def debug_variable_info(input, binding)\n    case input\n    when /^\\s*g(?:lobal)?\\s*$/\n      var_list(global_variables, binding)\n\n    when /^\\s*l(?:ocal)?\\s*$/\n      var_list(eval(\"local_variables\", binding), binding)\n\n    when /^\\s*i(?:nstance)?\\s+/\n      obj = debug_eval($', binding)\n      var_list(obj.instance_variables, obj.instance_eval{binding()})\n\n    when /^\\s*c(?:onst(?:ant)?)?\\s+/\n      obj = debug_eval($', binding)\n      unless obj.kind_of? Module\n\tstdout.print \"Should be Class/Module: \", $', \"\\n\"\n      else\n\tvar_list(obj.constants, obj.module_eval{binding()})\n      end\n    end\n  end\n\n  def debug_method_info(input, binding)\n    case input\n    when /^i(:?nstance)?\\s+/\n      obj = debug_eval($', binding)\n\n      len = 0\n      for v in obj.methods.sort\n\tlen += v.size + 1\n\tif len > 70\n\t  len = v.size + 1\n\t  stdout.print \"\\n\"\n\tend\n\tstdout.print v, \" \"\n      end\n      stdout.print \"\\n\"\n\n    else\n      obj = debug_eval(input, binding)\n      unless obj.kind_of? Module\n\tstdout.print \"Should be Class/Module: \", input, \"\\n\"\n      else\n\tlen = 0\n\tfor v in obj.instance_methods(false).sort\n\t  len += v.size + 1\n\t  if len > 70\n\t    len = v.size + 1\n\t    stdout.print \"\\n\"\n\t  end\n\t  stdout.print v, \" \"\n\tend\n\tstdout.print \"\\n\"\n      end\n    end\n  end\n\n  def thnum\n    num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}\n    unless num\n      DEBUGGER__.make_thread_list\n      num = DEBUGGER__.instance_eval{@thread_list[Thread.current]}\n    end\n    num\n  end\n\n  def debug_command(file, line, id, binding)\n    MUTEX.lock\n    unless defined?($debugger_restart) and $debugger_restart\n      callcc{|c| $debugger_restart = c} \n    end\n    set_last_thread(Thread.current)\n    frame_pos = 0\n    binding_file = file\n    binding_line = line\n    previous_line = nil\n    if ENV['EMACS']\n      stdout.printf \"\\032\\032%s:%d:\\n\", binding_file, binding_line\n    else\n      stdout.printf \"%s:%d:%s\", binding_file, binding_line,\n\tline_at(binding_file, binding_line)\n    end\n    @frames[0] = [binding, file, line, id]\n    display_expressions(binding)\n    prompt = true\n    while prompt and input = readline(\"(rdb:%d) \"%thnum(), true)\n      catch(:debug_error) do\n\tif input == \"\"\n          next unless DEBUG_LAST_CMD[0]\n\t  input = DEBUG_LAST_CMD[0]\n\t  stdout.print input, \"\\n\"\n\telse\n\t  DEBUG_LAST_CMD[0] = input\n\tend\n\n\tcase input\n\twhen /^\\s*tr(?:ace)?(?:\\s+(on|off))?(?:\\s+(all))?$/\n          if defined?( $2 )\n            if $1 == 'on'\n              set_trace_all true\n            else\n              set_trace_all false\n            end\n          elsif defined?( $1 )\n            if $1 == 'on'\n              set_trace true\n            else\n              set_trace false\n            end\n          end\n          if trace?\n            stdout.print \"Trace on.\\n\"\n          else\n            stdout.print \"Trace off.\\n\"\n          end\n\n\twhen /^\\s*b(?:reak)?\\s+(?:(.+):)?([^.:]+)$/\n\t  pos = $2\n          if $1\n            klass = debug_silent_eval($1, binding)\n            file = $1\n          end\n\t  if pos =~ /^\\d+$/\n\t    pname = pos\n\t    pos = pos.to_i\n\t  else\n\t    pname = pos = pos.intern.id2name\n\t  end\n\t  break_points.push [true, 0, klass || file, pos]\n\t  stdout.printf \"Set breakpoint %d at %s:%s\\n\", break_points.size, klass || file, pname\n\n\twhen /^\\s*b(?:reak)?\\s+(.+)[#.]([^.:]+)$/\n\t  pos = $2.intern.id2name\n\t  klass = debug_eval($1, binding)\n\t  break_points.push [true, 0, klass, pos]\n\t  stdout.printf \"Set breakpoint %d at %s.%s\\n\", break_points.size, klass, pos\n\n\twhen /^\\s*wat(?:ch)?\\s+(.+)$/\n\t  exp = $1\n\t  break_points.push [true, 1, exp]\n\t  stdout.printf \"Set watchpoint %d:%s\\n\", break_points.size, exp\n\n\twhen /^\\s*b(?:reak)?$/\n\t  if break_points.find{|b| b[1] == 0}\n\t    n = 1\n\t    stdout.print \"Breakpoints:\\n\"\n\t    for b in break_points\n\t      if b[0] and b[1] == 0\n\t\tstdout.printf \"  %d %s:%s\\n\", n, b[2], b[3] \n\t      end\n\t      n += 1\n\t    end\n\t  end\n\t  if break_points.find{|b| b[1] == 1}\n\t    n = 1\n\t    stdout.print \"\\n\"\n\t    stdout.print \"Watchpoints:\\n\"\n\t    for b in break_points\n\t      if b[0] and b[1] == 1\n\t\tstdout.printf \"  %d %s\\n\", n, b[2]\n\t      end\n\t      n += 1\n\t    end\n\t  end\n\t  if break_points.size == 0\n\t    stdout.print \"No breakpoints\\n\"\n\t  else\n\t    stdout.print \"\\n\"\n\t  end\n\n\twhen /^\\s*del(?:ete)?(?:\\s+(\\d+))?$/\n\t  pos = $1\n\t  unless pos\n\t    input = readline(\"Clear all breakpoints? (y/n) \", false)\n\t    if input == \"y\"\n\t      for b in break_points\n\t\tb[0] = false\n\t      end\n\t    end\n\t  else\n\t    pos = pos.to_i\n\t    if break_points[pos-1]\n\t      break_points[pos-1][0] = false\n\t    else\n\t      stdout.printf \"Breakpoint %d is not defined\\n\", pos\n\t    end\n\t  end\n\n\twhen /^\\s*disp(?:lay)?\\s+(.+)$/\n\t  exp = $1\n\t  display.push [true, exp]\n\t  stdout.printf \"%d: \", display.size\n\t  display_expression(exp, binding)\n\n\twhen /^\\s*disp(?:lay)?$/\n\t  display_expressions(binding)\n\n\twhen /^\\s*undisp(?:lay)?(?:\\s+(\\d+))?$/\n\t  pos = $1\n\t  unless pos\n\t    input = readline(\"Clear all expressions? (y/n) \", false)\n\t    if input == \"y\"\n\t      for d in display\n\t\td[0] = false\n\t      end\n\t    end\n\t  else\n\t    pos = pos.to_i\n\t    if display[pos-1]\n\t      display[pos-1][0] = false\n\t    else\n\t      stdout.printf \"Display expression %d is not defined\\n\", pos\n\t    end\n\t  end\n\n\twhen /^\\s*c(?:ont)?$/\n\t  prompt = false\n\n\twhen /^\\s*s(?:tep)?(?:\\s+(\\d+))?$/\n\t  if $1\n\t    lev = $1.to_i\n\t  else\n\t    lev = 1\n\t  end\n\t  @stop_next = lev\n\t  prompt = false\n\n\twhen /^\\s*n(?:ext)?(?:\\s+(\\d+))?$/\n\t  if $1\n\t    lev = $1.to_i\n\t  else\n\t    lev = 1\n\t  end\n\t  @stop_next = lev\n\t  @no_step = @frames.size - frame_pos\n\t  prompt = false\n\n\twhen /^\\s*w(?:here)?$/, /^\\s*f(?:rame)?$/\n\t  display_frames(frame_pos)\n\n\twhen /^\\s*l(?:ist)?(?:\\s+(.+))?$/\n\t  if not $1\n\t    b = previous_line ? previous_line + 10 : binding_line - 5\n\t    e = b + 9\n\t  elsif $1 == '-'\n\t    b = previous_line ? previous_line - 10 : binding_line - 5\n\t    e = b + 9\n\t  else\n\t    b, e = $1.split(/[-,]/)\n\t    if e\n\t      b = b.to_i\n\t      e = e.to_i\n\t    else\n\t      b = b.to_i - 5\n\t      e = b + 9\n\t    end\n\t  end\n\t  previous_line = b\n\t  display_list(b, e, binding_file, binding_line)\n\n\twhen /^\\s*up(?:\\s+(\\d+))?$/\n\t  previous_line = nil\n\t  if $1\n\t    lev = $1.to_i\n\t  else\n\t    lev = 1\n\t  end\n\t  frame_pos += lev\n\t  if frame_pos >= @frames.size\n\t    frame_pos = @frames.size - 1\n\t    stdout.print \"At toplevel\\n\"\n\t  end\n\t  binding, binding_file, binding_line = @frames[frame_pos]\n\t  stdout.print format_frame(frame_pos)\n\n\twhen /^\\s*down(?:\\s+(\\d+))?$/\n\t  previous_line = nil\n\t  if $1\n\t    lev = $1.to_i\n\t  else\n\t    lev = 1\n\t  end\n\t  frame_pos -= lev\n\t  if frame_pos < 0\n\t    frame_pos = 0\n\t    stdout.print \"At stack bottom\\n\"\n\t  end\n\t  binding, binding_file, binding_line = @frames[frame_pos]\n\t  stdout.print format_frame(frame_pos)\n\n\twhen /^\\s*fin(?:ish)?$/\n\t  if frame_pos == @frames.size\n\t    stdout.print \"\\\"finish\\\" not meaningful in the outermost frame.\\n\"\n\t  else\n\t    @finish_pos = @frames.size - frame_pos\n\t    frame_pos = 0\n\t    prompt = false\n\t  end\n\n\twhen /^\\s*cat(?:ch)?(?:\\s+(.+))?$/\n\t  if $1\n\t    excn = $1\n\t    if excn == 'off'\n\t      @catch = nil\n\t      stdout.print \"Clear catchpoint.\\n\"\n\t    else\n\t      @catch = excn\n\t      stdout.printf \"Set catchpoint %s.\\n\", @catch\n\t    end\n\t  else\n\t    if @catch\n\t      stdout.printf \"Catchpoint %s.\\n\", @catch\n\t    else\n\t      stdout.print \"No catchpoint.\\n\"\n\t    end\n\t  end\n\n\twhen /^\\s*q(?:uit)?$/\n\t  input = readline(\"Really quit? (y/n) \", false)\n\t  if input == \"y\"\n\t    exit!\t# exit -> exit!: No graceful way to stop threads...\n\t  end\n\n\twhen /^\\s*v(?:ar)?\\s+/\n\t  debug_variable_info($', binding)\n\n\twhen /^\\s*m(?:ethod)?\\s+/\n\t  debug_method_info($', binding)\n\n\twhen /^\\s*th(?:read)?\\s+/\n\t  if DEBUGGER__.debug_thread_info($', binding) == :cont\n\t    prompt = false\n\t  end\n\n\twhen /^\\s*pp\\s+/\n\t  PP.pp(debug_eval($', binding), stdout)\n\n\twhen /^\\s*p\\s+/\n\t  stdout.printf \"%s\\n\", debug_eval($', binding).inspect\n\n\twhen /^\\s*r(?:estart)?$/\n          $debugger_restart.call\n\n\twhen /^\\s*h(?:elp)?$/\n\t  debug_print_help()\n\n\telse\n\t  v = debug_eval(input, binding)\n\t  stdout.printf \"%s\\n\", v.inspect\n\tend\n      end\n    end\n    MUTEX.unlock\n    resume_all\n  end\n\n  def debug_print_help\n    stdout.print <<EOHELP\nDebugger help v.-0.002b\nCommands\n  b[reak] [file:|class:]<line|method>\n  b[reak] [class.]<line|method>\n                             set breakpoint to some position\n  wat[ch] <expression>       set watchpoint to some expression\n  cat[ch] (<exception>|off)  set catchpoint to an exception\n  b[reak]                    list breakpoints\n  cat[ch]                    show catchpoint\n  del[ete][ nnn]             delete some or all breakpoints\n  disp[lay] <expression>     add expression into display expression list\n  undisp[lay][ nnn]          delete one particular or all display expressions\n  c[ont]                     run until program ends or hit breakpoint\n  s[tep][ nnn]               step (into methods) one line or till line nnn\n  n[ext][ nnn]               go over one line or till line nnn\n  w[here]                    display frames\n  f[rame]                    alias for where\n  l[ist][ (-|nn-mm)]         list program, - lists backwards\n                             nn-mm lists given lines\n  up[ nn]                    move to higher frame\n  down[ nn]                  move to lower frame\n  fin[ish]                   return to outer frame\n  tr[ace] (on|off)           set trace mode of current thread\n  tr[ace] (on|off) all       set trace mode of all threads\n  q[uit]                     exit from debugger\n  v[ar] g[lobal]             show global variables\n  v[ar] l[ocal]              show local variables\n  v[ar] i[nstance] <object>  show instance variables of object\n  v[ar] c[onst] <object>     show constants of object\n  m[ethod] i[nstance] <obj>  show methods of object\n  m[ethod] <class|module>    show instance methods of class or module\n  th[read] l[ist]            list all threads\n  th[read] c[ur[rent]]       show current thread\n  th[read] [sw[itch]] <nnn>  switch thread context to nnn\n  th[read] stop <nnn>        stop thread nnn\n  th[read] resume <nnn>      resume thread nnn\n  p expression               evaluate expression and print its value\n  h[elp]                     print this help\n  <everything else>          evaluate\nEOHELP\n  end\n\n  def display_expressions(binding)\n    n = 1\n    for d in display\n      if d[0]\n\tstdout.printf \"%d: \", n\n\tdisplay_expression(d[1], binding)\n      end\n      n += 1\n    end\n  end\n\n  def display_expression(exp, binding)\n    stdout.printf \"%s = %s\\n\", exp, debug_silent_eval(exp, binding).to_s\n  end\n\n  def frame_set_pos(file, line)\n    if @frames[0]\n      @frames[0][1] = file\n      @frames[0][2] = line\n    end\n  end\n\n  def display_frames(pos)\n    0.upto(@frames.size - 1) do |n|\n      if n == pos\n\tstdout.print \"--> \"\n      else\n\tstdout.print \"    \"\n      end\n      stdout.print format_frame(n)\n    end\n  end\n\n  def format_frame(pos)\n    bind, file, line, id = @frames[pos]\n    sprintf \"#%d %s:%s%s\\n\", pos + 1, file, line,\n      (id ? \":in `#{id.id2name}'\" : \"\")\n  end\n\n  def display_list(b, e, file, line)\n    stdout.printf \"[%d, %d] in %s\\n\", b, e, file\n    if lines = SCRIPT_LINES__[file] and lines != true\n      n = 0\n      b.upto(e) do |n|\n\tif n > 0 && lines[n-1]\n\t  if n == line\n\t    stdout.printf \"=> %d  %s\\n\", n, lines[n-1].chomp\n\t  else\n\t    stdout.printf \"   %d  %s\\n\", n, lines[n-1].chomp\n\t  end\n\tend\n      end\n    else\n      stdout.printf \"No sourcefile available for %s\\n\", file\n    end\n  end\n\n  def line_at(file, line)\n    lines = SCRIPT_LINES__[file]\n    if lines\n      return \"\\n\" if lines == true\n      line = lines[line-1]\n      return \"\\n\" unless line\n      return line\n    end\n    return \"\\n\"\n  end\n\n  def debug_funcname(id)\n    if id.nil?\n      \"toplevel\"\n    else\n      id.id2name\n    end\n  end\n\n  def check_break_points(file, klass, pos, binding, id)\n    return false if break_points.empty?\n    n = 1\n    for b in break_points\n      if b[0]\t\t# valid\n\tif b[1] == 0\t# breakpoint\n\t  if (b[2] == file and b[3] == pos) or\n\t      (klass and b[2] == klass and b[3] == pos)\n\t    stdout.printf \"Breakpoint %d, %s at %s:%s\\n\", n, debug_funcname(id), file, pos\n\t    return true\n\t  end\n\telsif b[1] == 1\t# watchpoint\n\t  if debug_silent_eval(b[2], binding)\n\t    stdout.printf \"Watchpoint %d, %s at %s:%s\\n\", n, debug_funcname(id), file, pos\n\t    return true\n\t  end\n\tend\n      end\n      n += 1\n    end\n    return false\n  end\n\n  def excn_handle(file, line, id, binding)\n    if $!.class <= SystemExit\n      set_trace_func nil\n      exit\n    end\n\n    if @catch and ($!.class.ancestors.find { |e| e.to_s == @catch })\n      stdout.printf \"%s:%d: `%s' (%s)\\n\", file, line, $!, $!.class\n      fs = @frames.size\n      tb = caller(0)[-fs..-1]\n      if tb\n\tfor i in tb\n\t  stdout.printf \"\\tfrom %s\\n\", i\n\tend\n      end\n      suspend_all\n      debug_command(file, line, id, binding)\n    end\n  end\n\n  def trace_func(event, file, line, id, binding, klass)\n    Tracer.trace_func(event, file, line, id, binding, klass) if trace?\n    context(Thread.current).check_suspend\n    @file = file\n    @line = line\n    case event\n    when 'line'\n      frame_set_pos(file, line)\n      if !@no_step or @frames.size == @no_step\n\t@stop_next -= 1\n\t@stop_next = -1 if @stop_next < 0\n      elsif @frames.size < @no_step\n\t@stop_next = 0\t\t# break here before leaving...\n      else\n\t# nothing to do. skipped.\n      end\n      if @stop_next == 0 or check_break_points(file, nil, line, binding, id)\n\t@no_step = nil\n\tsuspend_all\n\tdebug_command(file, line, id, binding)\n      end\n\n    when 'call'\n      @frames.unshift [binding, file, line, id]\n      if check_break_points(file, klass, id.id2name, binding, id)\n\tsuspend_all\n\tdebug_command(file, line, id, binding)\n      end\n\n    when 'c-call'\n      frame_set_pos(file, line)\n\n    when 'class'\n      @frames.unshift [binding, file, line, id]\n\n    when 'return', 'end'\n      if @frames.size == @finish_pos\n\t@stop_next = 1\n\t@finish_pos = 0\n      end\n      @frames.shift\n\n    when 'end'\n      @frames.shift\n\n    when 'raise' \n      excn_handle(file, line, id, binding)\n\n    end\n    @last_file = file\n  end\nend\n\ntrap(\"INT\") { DEBUGGER__.interrupt }\n@last_thread = Thread::main\n@max_thread = 1\n@thread_list = {Thread::main => 1}\n@break_points = []\n@display = []\n@waiting = []\n@stdout = STDOUT\n\nclass << DEBUGGER__\n  def stdout\n    @stdout\n  end\n\n  def stdout=(s)\n    @stdout = s\n  end\n\n  def display\n    @display\n  end\n\n  def break_points\n    @break_points\n  end\n\n  def waiting\n    @waiting\n  end\n\n  def set_trace( arg )\n    saved_crit = Thread.critical\n    Thread.critical = true\n    make_thread_list\n    for th, in @thread_list\n      context(th).set_trace arg\n    end\n    Thread.critical = saved_crit\n    arg\n  end\n\n  def set_last_thread(th)\n    @last_thread = th\n  end\n\n  def suspend\n    saved_crit = Thread.critical\n    Thread.critical = true\n    make_thread_list\n    for th, in @thread_list\n      next if th == Thread.current\n      context(th).set_suspend\n    end\n    Thread.critical = saved_crit\n    # Schedule other threads to suspend as soon as possible.\n    Thread.pass unless Thread.critical\n  end\n\n  def resume\n    saved_crit = Thread.critical\n    Thread.critical = true\n    make_thread_list\n    for th, in @thread_list\n      next if th == Thread.current\n      context(th).clear_suspend\n    end\n    waiting.each do |th|\n      th.run\n    end\n    waiting.clear\n    Thread.critical = saved_crit\n    # Schedule other threads to restart as soon as possible.\n    Thread.pass\n  end\n\n  def context(thread=Thread.current)\n    c = thread[:__debugger_data__]\n    unless c\n      thread[:__debugger_data__] = c = Context.new\n    end\n    c\n  end\n\n  def interrupt\n    context(@last_thread).stop_next\n  end\n\n  def get_thread(num)\n    th = @thread_list.index(num)\n    unless th\n      @stdout.print \"No thread ##{num}\\n\"\n      throw :debug_error\n    end\n    th\n  end\n\n  def thread_list(num)\n    th = get_thread(num)\n    if th == Thread.current\n      @stdout.print \"+\"\n    else\n      @stdout.print \" \"\n    end\n    @stdout.printf \"%d \", num\n    @stdout.print th.inspect, \"\\t\"\n    file = context(th).instance_eval{@file}\n    if file\n      @stdout.print file,\":\",context(th).instance_eval{@line}\n    end\n    @stdout.print \"\\n\"\n  end\n\n  def thread_list_all\n    for th in @thread_list.values.sort\n      thread_list(th)\n    end\n  end\n\n  def make_thread_list\n    hash = {}\n    for th in Thread::list\n      if @thread_list.key? th\n\thash[th] = @thread_list[th]\n      else\n\t@max_thread += 1\n\thash[th] = @max_thread\n      end\n    end\n    @thread_list = hash\n  end\n\n  def debug_thread_info(input, binding)\n    case input\n    when /^l(?:ist)?/\n      make_thread_list\n      thread_list_all\n\n    when /^c(?:ur(?:rent)?)?$/\n      make_thread_list\n      thread_list(@thread_list[Thread.current])\n\n    when /^(?:sw(?:itch)?\\s+)?(\\d+)/\n      make_thread_list\n      th = get_thread($1.to_i)\n      if th == Thread.current\n\t@stdout.print \"It's the current thread.\\n\"\n      else\n\tthread_list(@thread_list[th])\n\tcontext(th).stop_next\n\tth.run\n\treturn :cont\n      end\n\n    when /^stop\\s+(\\d+)/\n      make_thread_list\n      th = get_thread($1.to_i)\n      if th == Thread.current\n\t@stdout.print \"It's the current thread.\\n\"\n      elsif th.stop?\n\t@stdout.print \"Already stopped.\\n\"\n      else\n\tthread_list(@thread_list[th])\n\tcontext(th).suspend \n      end\n\n    when /^resume\\s+(\\d+)/\n      make_thread_list\n      th = get_thread($1.to_i)\n      if th == Thread.current\n\t@stdout.print \"It's the current thread.\\n\"\n      elsif !th.stop?\n\t@stdout.print \"Already running.\"\n      else\n\tthread_list(@thread_list[th])\n\tth.run\n      end\n    end\n  end\nend\n\nstdout.printf \"Debug.rb\\n\"\nstdout.printf \"Emacs support available.\\n\\n\"\nset_trace_func proc { |event, file, line, id, binding, klass, *rest|\n  DEBUGGER__.context.trace_func event, file, line, id, binding, klass\n}\nend\n"
  },
  {
    "path": "lib/delegate.rb",
    "content": "# = delegate -- Support for the Delegation Pattern\n#\n# Documentation by James Edward Gray II and Gavin Sinclair\n#\n# == Introduction\n#\n# This library provides three different ways to delegate method calls to an\n# object.  The easiest to use is SimpleDelegator.  Pass an object to the\n# constructor and all methods supported by the object will be delegated.  This\n# object can be changed later.\n#\n# Going a step further, the top level DelegateClass method allows you to easily\n# setup delegation through class inheritance.  This is considerably more\n# flexible and thus probably the most common use for this library.\n#\n# Finally, if you need full control over the delegation scheme, you can inherit\n# from the abstract class Delegator and customize as needed.  (If you find\n# yourself needing this control, have a look at _forwardable_, also in the\n# standard library.  It may suit your needs better.)\n#\n# == Notes\n#\n# Be advised, RDoc will not detect delegated methods.\n#\n# <b>delegate.rb provides full-class delegation via the\n# DelegateClass() method.  For single-method delegation via\n# def_delegator(), see forwardable.rb.</b>\n#\n# == Examples\n#\n# === SimpleDelegator\n#\n# Here's a simple example that takes advantage of the fact that\n# SimpleDelegator's delegation object can be changed at any time.\n#\n#   class Stats\n#     def initialize\n#       @source = SimpleDelegator.new([])\n#     end\n#     \n#     def stats( records )\n#       @source.__setobj__(records)\n#       \t\n#       \"Elements:  #{@source.size}\\n\" +\n#       \" Non-Nil:  #{@source.compact.size}\\n\" +\n#       \"  Unique:  #{@source.uniq.size}\\n\"\n#     end\n#   end\n#   \n#   s = Stats.new\n#   puts s.stats(%w{James Edward Gray II})\n#   puts\n#   puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])\n#\n# <i>Prints:</i>\n#\n#   Elements:  4\n#    Non-Nil:  4\n#     Unique:  4\n# \n#   Elements:  8\n#    Non-Nil:  7\n#     Unique:  6\n#\n# === DelegateClass()\n#\n# Here's a sample of use from <i>tempfile.rb</i>.\n#\n# A _Tempfile_ object is really just a _File_ object with a few special rules\n# about storage location and/or when the File should be deleted.  That makes for\n# an almost textbook perfect example of how to use delegation.\n#\n#   class Tempfile < DelegateClass(File)\n#     # constant and class member data initialization...\n#   \n#     def initialize(basename, tmpdir=Dir::tmpdir)\n#       # build up file path/name in var tmpname...\n#     \n#       @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)\n#     \n#       # ...\n#     \n#       super(@tmpfile)\n#     \n#       # below this point, all methods of File are supported...\n#     end\n#   \n#     # ...\n#   end\n#\n# === Delegator\n#\n# SimpleDelegator's implementation serves as a nice example here.\n#\n#    class SimpleDelegator < Delegator\n#      def initialize(obj)\n#        super             # pass obj to Delegator constructor, required\n#        @_sd_obj = obj    # store obj for future use\n#      end\n# \n#      def __getobj__\n#        @_sd_obj          # return object we are delegating to, required\n#      end\n# \n#      def __setobj__(obj)\n#        @_sd_obj = obj    # change delegation object, a feature we're providing\n#      end\n# \n#      # ...\n#    end\n\n#\n# Delegator is an abstract class used to build delegator pattern objects from\n# subclasses.  Subclasses should redefine \\_\\_getobj\\_\\_.  For a concrete\n# implementation, see SimpleDelegator.\n#\nclass Delegator\n  IgnoreBacktracePat = %r\"\\A#{Regexp.quote(__FILE__)}:\\d+:in `\"\n\n  #\n  # Pass in the _obj_ to delegate method calls to.  All methods supported by\n  # _obj_ will be delegated to.\n  #\n  def initialize(obj)\n    preserved = ::Kernel.public_instance_methods(false)\n    preserved -= [\"to_s\",\"to_a\",\"inspect\",\"==\",\"=~\",\"===\"]\n    for t in self.class.ancestors\n      preserved |= t.public_instance_methods(false)\n      preserved |= t.private_instance_methods(false)\n      preserved |= t.protected_instance_methods(false)\n      break if t == Delegator\n    end\n    preserved << \"singleton_method_added\"\n    for method in obj.methods\n      next if preserved.include? method\n      begin\n\teval <<-EOS, nil, __FILE__, __LINE__+1\n\t  def self.#{method}(*args, &block)\n\t    begin\n\t      __getobj__.__send__(:#{method}, *args, &block)\n\t    ensure\n\t      $@.delete_if{|s|IgnoreBacktracePat=~s} if $@\n\t    end\n\t  end\n\tEOS\n      rescue SyntaxError\n        raise NameError, \"invalid identifier %s\" % method, caller(4)\n      end\n    end\n  end\n  alias initialize_methods initialize\n\n  # Handles the magic of delegation through \\_\\_getobj\\_\\_.\n  def method_missing(m, *args, &block)\n    target = self.__getobj__\n    unless target.respond_to?(m)\n      super(m, *args, &block)\n    end\n    target.__send__(m, *args, &block)\n  end\n\n  # \n  # Checks for a method provided by this the delegate object by fowarding the \n  # call through \\_\\_getobj\\_\\_.\n  # \n  def respond_to?(m, include_private = false)\n    return true if super\n    return self.__getobj__.respond_to?(m, include_private)\n  end\n\n  #\n  # This method must be overridden by subclasses and should return the object\n  # method calls are being delegated to.\n  #\n  def __getobj__\n    raise NotImplementedError, \"need to define `__getobj__'\"\n  end\n\n  # Serialization support for the object returned by \\_\\_getobj\\_\\_.\n  def marshal_dump\n    __getobj__\n  end\n  # Reinitializes delegation from a serialized object.\n  def marshal_load(obj)\n    initialize_methods(obj)\n    __setobj__(obj)\n  end\nend\n\n#\n# A concrete implementation of Delegator, this class provides the means to\n# delegate all supported method calls to the object passed into the constructor\n# and even to change the object being delegated to at a later time with\n# \\_\\_setobj\\_\\_ .\n#\nclass SimpleDelegator<Delegator\n\n  # Pass in the _obj_ you would like to delegate method calls to.\n  def initialize(obj)\n    super\n    @_sd_obj = obj\n  end\n\n  # Returns the current object method calls are being delegated to.\n  def __getobj__\n    @_sd_obj\n  end\n\n  #\n  # Changes the delegate object to _obj_.\n  #\n  # It's important to note that this does *not* cause SimpleDelegator's methods\n  # to change.  Because of this, you probably only want to change delegation\n  # to objects of the same type as the original delegate.\n  #\n  # Here's an example of changing the delegation object.\n  #\n  #   names = SimpleDelegator.new(%w{James Edward Gray II})\n  #   puts names[1]    # => Edward\n  #   names.__setobj__(%w{Gavin Sinclair})\n  #   puts names[1]    # => Sinclair\n  #\n  def __setobj__(obj)\n    raise ArgumentError, \"cannot delegate to self\" if self.equal?(obj)\n    @_sd_obj = obj\n  end\n\n  # Clone support for the object returned by \\_\\_getobj\\_\\_.\n  def clone\n    new = super\n    new.__setobj__(__getobj__.clone)\n    new\n  end\n  # Duplication support for the object returned by \\_\\_getobj\\_\\_.\n  def dup\n    new = super\n    new.__setobj__(__getobj__.clone)\n    new\n  end\nend\n\n# :stopdoc:\n# backward compatibility ^_^;;;\nDelegater = Delegator\nSimpleDelegater = SimpleDelegator\n# :startdoc:\n\n#\n# The primary interface to this library.  Use to setup delegation when defining\n# your class.\n#\n#   class MyClass < DelegateClass( ClassToDelegateTo )    # Step 1\n#     def initialize\n#       super(obj_of_ClassToDelegateTo)                   # Step 2\n#     end\n#   end\n#\ndef DelegateClass(superclass)\n  klass = Class.new\n  methods = superclass.public_instance_methods(true)\n  methods -= ::Kernel.public_instance_methods(false)\n  methods |= [\"to_s\",\"to_a\",\"inspect\",\"==\",\"=~\",\"===\"]\n  klass.module_eval {\n    def initialize(obj)  # :nodoc:\n      @_dc_obj = obj\n    end\n    def method_missing(m, *args, &block)  # :nodoc:\n      unless @_dc_obj.respond_to?(m)\n        super(m, *args, &block)\n      end\n      @_dc_obj.__send__(m, *args, &block)\n    end\n    def respond_to?(m, include_private = false)  # :nodoc:\n      return true if super\n      return @_dc_obj.respond_to?(m, include_private)\n    end\n    def __getobj__  # :nodoc:\n      @_dc_obj\n    end\n    def __setobj__(obj)  # :nodoc:\n      raise ArgumentError, \"cannot delegate to self\" if self.equal?(obj)\n      @_dc_obj = obj\n    end\n    def clone  # :nodoc:\n      new = super\n      new.__setobj__(__getobj__.clone)\n      new\n    end\n    def dup  # :nodoc:\n      new = super\n      new.__setobj__(__getobj__.clone)\n      new\n    end\n  }\n  for method in methods\n    begin\n      klass.module_eval <<-EOS, __FILE__, __LINE__+1\n        def #{method}(*args, &block)\n\t  begin\n\t    @_dc_obj.__send__(:#{method}, *args, &block)\n\t  ensure\n\t    $@.delete_if{|s| ::Delegator::IgnoreBacktracePat =~ s} if $@\n\t  end\n\tend\n      EOS\n    rescue SyntaxError\n      raise NameError, \"invalid identifier %s\" % method, caller(3)\n    end\n  end\n  return klass\nend\n\n# :enddoc:\n\nif __FILE__ == $0\n  class ExtArray<DelegateClass(Array)\n    def initialize()\n      super([])\n    end\n  end\n\n  ary = ExtArray.new\n  p ary.class\n  ary.push 25\n  p ary\n\n  foo = Object.new\n  def foo.test\n    25\n  end\n  def foo.error\n    raise 'this is OK'\n  end\n  foo2 = SimpleDelegator.new(foo)\n  p foo.test == foo2.test\t# => true\n  foo2.error\t\t\t# raise error!\nend\n"
  },
  {
    "path": "lib/drb/acl.rb",
    "content": "# acl-2.0 - simple Access Control List\n#\n# Copyright (c) 2000,2002,2003 Masatoshi SEKI\n#\n# acl.rb is copyrighted free software by Masatoshi SEKI.\n# You can redistribute it and/or modify it under the same terms as Ruby.\n\nrequire 'ipaddr'\n\nclass ACL\n  VERSION=[\"2.0.0\"]\n  class ACLEntry\n    def initialize(str)\n      if str == '*' or str == 'all'\n\t@pat = [:all]\n      elsif str.include?('*')\n        @pat = [:name, dot_pat(str)]\n      else\n\tbegin\n\t  @pat = [:ip, IPAddr.new(str)]\n\trescue ArgumentError\n\t  @pat = [:name, dot_pat(str)]\n\tend\n      end\n    end\n\n    private\n    def dot_pat_str(str)\n      list = str.split('.').collect { |s|\n\t(s == '*') ? '.+' : s\n      }\n      list.join(\"\\\\.\")\n    end\n\n    private\n    def dot_pat(str)\n      exp = \"^\" + dot_pat_str(str) + \"$\"\n      Regexp.new(exp)\n    end\n\n    public\n    def match(addr)\n      case @pat[0]\n      when :all\n\ttrue\n      when :ip\n\tbegin\n\t  ipaddr = IPAddr.new(addr[3])\n\t  ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?\n\trescue ArgumentError\n\t  return false\n\tend\n\t(@pat[1].include?(ipaddr)) ? true : false\n      when :name\n\t(@pat[1] =~ addr[2]) ? true : false\n      else\n\tfalse\n      end\n    end\n  end\n\n  class ACLList\n    def initialize\n      @list = []\n    end\n\n    public\n    def match(addr)\n      @list.each do |e|\n\treturn true if e.match(addr)\n      end\n      false\n    end\n\n    public\n    def add(str)\n      @list.push(ACLEntry.new(str))\n    end\n  end\n\n  DENY_ALLOW = 0\n  ALLOW_DENY = 1\n\n  def initialize(list=nil, order = DENY_ALLOW)\n    @order = order\n    @deny = ACLList.new\n    @allow = ACLList.new\n    install_list(list) if list\n  end\n\n  public\n  def allow_socket?(soc)\n    allow_addr?(soc.peeraddr)\n  end\n\n  public\n  def allow_addr?(addr)\n    case @order\n    when DENY_ALLOW\n      return true if @allow.match(addr)\n      return false if @deny.match(addr)\n      return true\n    when ALLOW_DENY\n      return false if @deny.match(addr)\n      return true if @allow.match(addr)\n      return false\n    else\n      false\n    end\n  end\n\n  public\n  def install_list(list)\n    i = 0\n    while i < list.size\n      permission, domain = list.slice(i,2)\n      case permission.downcase\n      when 'allow'\n\t@allow.add(domain)\n      when 'deny'\n\t@deny.add(domain)\n      else\n\traise \"Invalid ACL entry #{list.to_s}\"\n      end\n      i += 2\n    end\n  end\nend\n\nif __FILE__ == $0\n  # example\n  list = %w(deny all\n\t    allow 192.168.1.1\n            allow ::ffff:192.168.1.2\n            allow 192.168.1.3\n            )\n\n  addr = [\"AF_INET\", 10, \"lc630\", \"192.168.1.3\"]\n\n  acl = ACL.new\n  p acl.allow_addr?(addr)\n\n  acl = ACL.new(list, ACL::DENY_ALLOW)\n  p acl.allow_addr?(addr)\nend\n\n"
  },
  {
    "path": "lib/drb/drb.rb",
    "content": "#\n# = drb/drb.rb\n#\n# Distributed Ruby: _dRuby_ version 2.0.4\n#\n# Copyright (c) 1999-2003 Masatoshi SEKI.  You can redistribute it and/or\n# modify it under the same terms as Ruby.\n#\n# Author:: Masatoshi SEKI\n#\n# Documentation:: William Webber (william@williamwebber.com)\n#\n# == Overview\n#\n# dRuby is a distributed object system for Ruby.  It allows an object in one\n# Ruby process to invoke methods on an object in another Ruby process on the\n# same or a different machine.\n#\n# The Ruby standard library contains the core classes of the dRuby package.\n# However, the full package also includes access control lists and the\n# Rinda tuple-space distributed task management system, as well as a \n# large number of samples.  The full dRuby package can be downloaded from\n# the dRuby home page (see *References*).\n#\n# For an introduction and examples of usage see the documentation to the\n# DRb module.\n#\n# == References\n#\n# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.html]\n#    The dRuby home page, in Japanese.  Contains the full dRuby package\n#    and links to other Japanese-language sources.\n#\n# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.en.html]\n#    The English version of the dRuby home page.\n#\n# [http://www.chadfowler.com/ruby/drb.html]\n#    A quick tutorial introduction to using dRuby by Chad Fowler.\n#\n# [http://www.linux-mag.com/2002-09/ruby_05.html]\n#   A tutorial introduction to dRuby in Linux Magazine by Dave Thomas.\n#   Includes a discussion of Rinda.\n#\n# [http://www.eng.cse.dmu.ac.uk/~hgs/ruby/dRuby/]\n#   Links to English-language Ruby material collected by Hugh Sasse.\n#\n# [http://www.rubycentral.com/book/ospace.html]\n#   The chapter from *Programming* *Ruby* by Dave Thomas and Andy Hunt\n#   which discusses dRuby.\n#\n# [http://www.clio.ne.jp/home/web-i31s/Flotuard/Ruby/PRC2K_seki/dRuby.en.html]\n#   Translation of presentation on Ruby by Masatoshi Seki.\n\nrequire 'socket'\nrequire 'thread'\nrequire 'fcntl'\nrequire 'drb/eq'\n\n#\n# == Overview\n#\n# dRuby is a distributed object system for Ruby.  It is written in\n# pure Ruby and uses its own protocol.  No add-in services are needed\n# beyond those provided by the Ruby runtime, such as TCP sockets.  It\n# does not rely on or interoperate with other distributed object\n# systems such as CORBA, RMI, or .NET.\n#\n# dRuby allows methods to be called in one Ruby process upon a Ruby\n# object located in another Ruby process, even on another machine.\n# References to objects can be passed between processes.  Method\n# arguments and return values are dumped and loaded in marshalled\n# format.  All of this is done transparently to both the caller of the\n# remote method and the object that it is called upon.\n#\n# An object in a remote process is locally represented by a\n# DRb::DRbObject instance.  This acts as a sort of proxy for the\n# remote object.  Methods called upon this DRbObject instance are\n# forwarded to its remote object.  This is arranged dynamically at run\n# time.  There are no statically declared interfaces for remote\n# objects, such as CORBA's IDL.\n#\n# dRuby calls made into a process are handled by a DRb::DRbServer\n# instance within that process.  This reconstitutes the method call,\n# invokes it upon the specified local object, and returns the value to\n# the remote caller.  Any object can receive calls over dRuby.  There\n# is no need to implement a special interface, or mixin special\n# functionality.  Nor, in the general case, does an object need to\n# explicitly register itself with a DRbServer in order to receive\n# dRuby calls.\n#\n# One process wishing to make dRuby calls upon another process must\n# somehow obtain an initial reference to an object in the remote\n# process by some means other than as the return value of a remote\n# method call, as there is initially no remote object reference it can\n# invoke a method upon.  This is done by attaching to the server by\n# URI.  Each DRbServer binds itself to a URI such as\n# 'druby://example.com:8787'.  A DRbServer can have an object attached\n# to it that acts as the server's *front* *object*.  A DRbObject can\n# be explicitly created from the server's URI.  This DRbObject's\n# remote object will be the server's front object.  This front object\n# can then return references to other Ruby objects in the DRbServer's\n# process.\n#\n# Method calls made over dRuby behave largely the same as normal Ruby\n# method calls made within a process.  Method calls with blocks are\n# supported, as are raising exceptions.  In addition to a method's\n# standard errors, a dRuby call may also raise one of the\n# dRuby-specific errors, all of which are subclasses of DRb::DRbError.\n#\n# Any type of object can be passed as an argument to a dRuby call or\n# returned as its return value.  By default, such objects are dumped\n# or marshalled at the local end, then loaded or unmarshalled at the\n# remote end.  The remote end therefore receives a copy of the local\n# object, not a distributed reference to it; methods invoked upon this\n# copy are executed entirely in the remote process, not passed on to\n# the local original.  This has semantics similar to pass-by-value.\n#\n# However, if an object cannot be marshalled, a dRuby reference to it\n# is passed or returned instead.  This will turn up at the remote end\n# as a DRbObject instance.  All methods invoked upon this remote proxy\n# are forwarded to the local object, as described in the discussion of\n# DRbObjects.  This has semantics similar to the normal Ruby\n# pass-by-reference.\n# \n# The easiest way to signal that we want an otherwise marshallable\n# object to be passed or returned as a DRbObject reference, rather\n# than marshalled and sent as a copy, is to include the\n# DRb::DRbUndumped mixin module.\n#\n# dRuby supports calling remote methods with blocks.  As blocks (or\n# rather the Proc objects that represent them) are not marshallable,\n# the block executes in the local, not the remote, context.  Each\n# value yielded to the block is passed from the remote object to the\n# local block, then the value returned by each block invocation is\n# passed back to the remote execution context to be collected, before\n# the collected values are finally returned to the local context as\n# the return value of the method invocation.\n# \n# == Examples of usage\n#\n# For more dRuby samples, see the +samples+ directory in the full\n# dRuby distribution.\n#\n# === dRuby in client/server mode\n#\n# This illustrates setting up a simple client-server drb\n# system.  Run the server and client code in different terminals,\n# starting the server code first.\n#\n# ==== Server code\n#    \n#   require 'drb/drb'\n#     \n#   # The URI for the server to connect to\n#   URI=\"druby://localhost:8787\" \n#     \n#   class TimeServer\n#     \n#     def get_current_time\n#       return Time.now\n#     end\n#     \n#   end\n#     \n#   # The object that handles requests on the server\n#   FRONT_OBJECT=TimeServer.new\n#\n#   $SAFE = 1   # disable eval() and friends\n#   \n#   DRb.start_service(URI, FRONT_OBJECT)\n#   # Wait for the drb server thread to finish before exiting.\n#   DRb.thread.join\n#\n# ==== Client code\n#     \n#   require 'drb/drb'\n#   \n#   # The URI to connect to\n#   SERVER_URI=\"druby://localhost:8787\"\n#\n#   # Start a local DRbServer to handle callbacks.\n#   #\n#   # Not necessary for this small example, but will be required\n#   # as soon as we pass a non-marshallable object as an argument\n#   # to a dRuby call.\n#   DRb.start_service\n#   \n#   timeserver = DRbObject.new_with_uri(SERVER_URI)\n#   puts timeserver.get_current_time \n#\n# === Remote objects under dRuby\n#\n# This example illustrates returning a reference to an object\n# from a dRuby call.  The Logger instances live in the server\n# process.  References to them are returned to the client process,\n# where methods can be invoked upon them.  These methods are \n# executed in the server process.\n#\n# ==== Server code\n#   \n#   require 'drb/drb'\n#   \n#   URI=\"druby://localhost:8787\"\n#   \n#   class Logger\n#\n#       # Make dRuby send Logger instances as dRuby references,\n#       # not copies.\n#       include DRb::DRbUndumped\n#   \n#       def initialize(n, fname)\n#           @name = n\n#           @filename = fname\n#       end\n#   \n#       def log(message)\n#           File.open(@filename, \"a\") do |f|\n#               f.puts(\"#{Time.now}: #{@name}: #{message}\")\n#           end\n#       end\n#   \n#   end\n#   \n#   # We have a central object for creating and retrieving loggers.\n#   # This retains a local reference to all loggers created.  This\n#   # is so an existing logger can be looked up by name, but also\n#   # to prevent loggers from being garbage collected.  A dRuby\n#   # reference to an object is not sufficient to prevent it being\n#   # garbage collected!\n#   class LoggerFactory\n#   \n#       def initialize(bdir)\n#           @basedir = bdir\n#           @loggers = {}\n#       end\n#   \n#       def get_logger(name)\n#           if !@loggers.has_key? name\n#               # make the filename safe, then declare it to be so\n#               fname = name.gsub(/[.\\/]/, \"_\").untaint\n#               @loggers[name] = Logger.new(name, @basedir + \"/\" + fname)\n#           end\n#           return @loggers[name]\n#       end\n#   \n#   end\n#   \n#   FRONT_OBJECT=LoggerFactory.new(\"/tmp/dlog\")\n#\n#   $SAFE = 1   # disable eval() and friends\n#   \n#   DRb.start_service(URI, FRONT_OBJECT)\n#   DRb.thread.join\n#\n# ==== Client code\n#\n#   require 'drb/drb'\n#   \n#   SERVER_URI=\"druby://localhost:8787\"\n#\n#   DRb.start_service\n#   \n#   log_service=DRbObject.new_with_uri(SERVER_URI)\n#   \n#   [\"loga\", \"logb\", \"logc\"].each do |logname|\n#   \n#       logger=log_service.get_logger(logname)\n#   \n#       logger.log(\"Hello, world!\")\n#       logger.log(\"Goodbye, world!\")\n#       logger.log(\"=== EOT ===\")\n#   \n#   end\n#\n# == Security\n#\n# As with all network services, security needs to be considered when\n# using dRuby.  By allowing external access to a Ruby object, you are\n# not only allowing outside clients to call the methods you have\n# defined for that object, but by default to execute arbitrary Ruby\n# code on your server.  Consider the following:\n#\n#    # !!! UNSAFE CODE !!!\n#    ro = DRbObject::new_with_uri(\"druby://your.server.com:8989\")\n#    class << ro\n#      undef :instance_eval  # force call to be passed to remote object\n#    end\n#    ro.instance_eval(\"`rm -rf *`\")\n#\n# The dangers posed by instance_eval and friends are such that a\n# DRbServer should generally be run with $SAFE set to at least \n# level 1.  This will disable eval() and related calls on strings \n# passed across the wire.  The sample usage code given above follows \n# this practice.\n#\n# A DRbServer can be configured with an access control list to\n# selectively allow or deny access from specified IP addresses.  The\n# main druby distribution provides the ACL class for this purpose.  In\n# general, this mechanism should only be used alongside, rather than\n# as a replacement for, a good firewall.\n#\n# == dRuby internals\n#\n# dRuby is implemented using three main components: a remote method\n# call marshaller/unmarshaller; a transport protocol; and an\n# ID-to-object mapper.  The latter two can be directly, and the first\n# indirectly, replaced, in order to provide different behaviour and\n# capabilities.\n#\n# Marshalling and unmarshalling of remote method calls is performed by\n# a DRb::DRbMessage instance.  This uses the Marshal module to dump\n# the method call before sending it over the transport layer, then\n# reconstitute it at the other end.  There is normally no need to\n# replace this component, and no direct way is provided to do so.\n# However, it is possible to implement an alternative marshalling\n# scheme as part of an implementation of the transport layer.\n#\n# The transport layer is responsible for opening client and server\n# network connections and forwarding dRuby request across them.\n# Normally, it uses DRb::DRbMessage internally to manage marshalling\n# and unmarshalling.  The transport layer is managed by\n# DRb::DRbProtocol.  Multiple protocols can be installed in\n# DRbProtocol at the one time; selection between them is determined by\n# the scheme of a dRuby URI.  The default transport protocol is\n# selected by the scheme 'druby:', and implemented by\n# DRb::DRbTCPSocket.  This uses plain TCP/IP sockets for\n# communication.  An alternative protocol, using UNIX domain sockets,\n# is implemented by DRb::DRbUNIXSocket in the file drb/unix.rb, and\n# selected by the scheme 'drbunix:'.  A sample implementation over\n# HTTP can be found in the samples accompanying the main dRuby\n# distribution.\n#\n# The ID-to-object mapping component maps dRuby object ids to the\n# objects they refer to, and vice versa.  The implementation to use\n# can be specified as part of a DRb::DRbServer's configuration.  The\n# default implementation is provided by DRb::DRbIdConv.  It uses an\n# object's ObjectSpace id as its dRuby id.  This means that the dRuby\n# reference to that object only remains meaningful for the lifetime of\n# the object's process and the lifetime of the object within that\n# process.  A modified implementation is provided by DRb::TimerIdConv\n# in the file drb/timeridconv.rb.  This implementation retains a local\n# reference to all objects exported over dRuby for a configurable\n# period of time (defaulting to ten minutes), to prevent them being\n# garbage-collected within this time.  Another sample implementation\n# is provided in sample/name.rb in the main dRuby distribution.  This\n# allows objects to specify their own id or \"name\".  A dRuby reference\n# can be made persistent across processes by having each process\n# register an object using the same dRuby name.\n#\nmodule DRb\n\n  # Superclass of all errors raised in the DRb module.\n  class DRbError < RuntimeError; end\n\n  # Error raised when an error occurs on the underlying communication\n  # protocol.\n  class DRbConnError < DRbError; end\n\n  # Class responsible for converting between an object and its id.\n  #\n  # This, the default implementation, uses an object's local ObjectSpace\n  # __id__ as its id.  This means that an object's identification over\n  # drb remains valid only while that object instance remains alive \n  # within the server runtime.\n  #\n  # For alternative mechanisms, see DRb::TimerIdConv in rdb/timeridconv.rb\n  # and DRbNameIdConv in sample/name.rb in the full drb distribution.\n  class DRbIdConv\n\n    # Convert an object reference id to an object.\n    #\n    # This implementation looks up the reference id in the local object\n    # space and returns the object it refers to.\n    def to_obj(ref)\n      ObjectSpace._id2ref(ref)\n    end\n    \n    # Convert an object into a reference id.\n    #\n    # This implementation returns the object's __id__ in the local\n    # object space.\n    def to_id(obj)\n      obj.nil? ? nil : obj.__id__\n    end\n  end\n\n  # Mixin module making an object undumpable or unmarshallable.\n  #\n  # If an object which includes this module is returned by method\n  # called over drb, then the object remains in the server space\n  # and a reference to the object is returned, rather than the\n  # object being marshalled and moved into the client space.\n  module DRbUndumped \n    def _dump(dummy)  # :nodoc:\n      raise TypeError, 'can\\'t dump'\n    end\n  end\n\n  # Error raised by the DRb module when an attempt is made to refer to\n  # the context's current drb server but the context does not have one.\n  # See #current_server.\n  class DRbServerNotFound < DRbError; end\n\n  # Error raised by the DRbProtocol module when it cannot find any\n  # protocol implementation support the scheme specified in a URI.\n  class DRbBadURI < DRbError; end\n\n  # Error raised by a dRuby protocol when it doesn't support the\n  # scheme specified in a URI.  See DRb::DRbProtocol.\n  class DRbBadScheme < DRbError; end\n\n  # An exception wrapping a DRb::DRbUnknown object\n  class DRbUnknownError < DRbError\n\n    # Create a new DRbUnknownError for the DRb::DRbUnknown object +unknown+\n    def initialize(unknown)\n      @unknown = unknown\n      super(unknown.name)\n    end\n\n    # Get the wrapped DRb::DRbUnknown object.\n    attr_reader :unknown\n\n    def self._load(s)  # :nodoc:\n      Marshal::load(s)\n    end\n    \n    def _dump(lv) # :nodoc:\n      Marshal::dump(@unknown)\n    end\n  end\n\n  # An exception wrapping an error object\n  class DRbRemoteError < DRbError\n    def initialize(error)\n      @reason = error.class.to_s\n      super(\"#{error.message} (#{error.class})\")\n      set_backtrace(error.backtrace)\n    end\n\n    # the class of the error, as a string.\n    attr_reader :reason\n  end\n\n  # Class wrapping a marshalled object whose type is unknown locally.\n  #\n  # If an object is returned by a method invoked over drb, but the\n  # class of the object is unknown in the client namespace, or\n  # the object is a constant unknown in the client namespace, then\n  # the still-marshalled object is returned wrapped in a DRbUnknown instance.\n  #\n  # If this object is passed as an argument to a method invoked over\n  # drb, then the wrapped object is passed instead.\n  #\n  # The class or constant name of the object can be read from the\n  # +name+ attribute.  The marshalled object is held in the +buf+\n  # attribute.\n  class DRbUnknown\n    \n    # Create a new DRbUnknown object.\n    #\n    # +buf+ is a string containing a marshalled object that could not\n    # be unmarshalled.  +err+ is the error message that was raised \n    # when the unmarshalling failed.  It is used to determine the\n    # name of the unmarshalled object.\n    def initialize(err, buf)\n      case err.to_s\n      when /uninitialized constant (\\S+)/\n\t@name = $1\n      when /undefined class\\/module (\\S+)/\n\t@name = $1\n      else\n\t@name = nil\n      end\n      @buf = buf\n    end\n\n    # The name of the unknown thing.\n    #\n    # Class name for unknown objects; variable name for unknown\n    # constants.\n    attr_reader :name\n\n    # Buffer contained the marshalled, unknown object.\n    attr_reader :buf\n\n    def self._load(s) # :nodoc:\n      begin\n\tMarshal::load(s)\n      rescue NameError, ArgumentError\n\tDRbUnknown.new($!, s)\n      end\n    end\n\n    def _dump(lv) # :nodoc:\n      @buf\n    end\n\n    # Attempt to load the wrapped marshalled object again.\n    #\n    # If the class of the object is now known locally, the object\n    # will be unmarshalled and returned.  Otherwise, a new \n    # but identical DRbUnknown object will be returned.\n    def reload\n      self.class._load(@buf)\n    end\n\n    # Create a DRbUnknownError exception containing this object.\n    def exception\n      DRbUnknownError.new(self)\n    end\n  end\n\n  class DRbArray\n    def initialize(ary)\n      @ary = ary.collect { |obj| \n\tif obj.kind_of? DRbUndumped\n\t  DRbObject.new(obj)\n\telse\n\t  begin\n\t    Marshal.dump(obj)\n\t    obj\n\t  rescue\n\t    DRbObject.new(obj)\n\t  end\n\tend\n      }\n    end\n\n    def self._load(s)\n      Marshal::load(s)\n    end\n\n    def _dump(lv)\n      Marshal.dump(@ary)\n    end\n  end\n\n  # Handler for sending and receiving drb messages.\n  #\n  # This takes care of the low-level marshalling and unmarshalling\n  # of drb requests and responses sent over the wire between server\n  # and client.  This relieves the implementor of a new drb\n  # protocol layer with having to deal with these details.\n  #\n  # The user does not have to directly deal with this object in\n  # normal use.\n  class DRbMessage\n    def initialize(config) # :nodoc:\n      @load_limit = config[:load_limit]\n      @argc_limit = config[:argc_limit]\n    end\n\n    def dump(obj, error=false)  # :nodoc:\n      obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped\n      begin\n\tstr = Marshal::dump(obj)\n      rescue\n\tstr = Marshal::dump(make_proxy(obj, error))\n      end\n      [str.size].pack('N') + str\n    end\n\n    def load(soc)  # :nodoc:\n      begin\n        sz = soc.read(4)\t# sizeof (N)\n      rescue\n        raise(DRbConnError, $!.message, $!.backtrace)\n      end\n      raise(DRbConnError, 'connection closed') if sz.nil?\n      raise(DRbConnError, 'premature header') if sz.size < 4\n      sz = sz.unpack('N')[0]\n      raise(DRbConnError, \"too large packet #{sz}\") if @load_limit < sz\n      begin\n        str = soc.read(sz)\n      rescue\n        raise(DRbConnError, $!.message, $!.backtrace)\n      end\n      raise(DRbConnError, 'connection closed') if str.nil?\n      raise(DRbConnError, 'premature marshal format(can\\'t read)') if str.size < sz\n      DRb.mutex.synchronize do\n        begin\n          save = Thread.current[:drb_untaint]\n          Thread.current[:drb_untaint] = []\n          Marshal::load(str)\n        rescue NameError, ArgumentError\n          DRbUnknown.new($!, str)\n        ensure\n          Thread.current[:drb_untaint].each do |x|\n            x.untaint\n          end\n          Thread.current[:drb_untaint] = save\n        end\n      end\n    end\n\n    def send_request(stream, ref, msg_id, arg, b) # :nodoc:\n      ary = []\n      ary.push(dump(ref.__drbref))\n      ary.push(dump(msg_id.id2name))\n      ary.push(dump(arg.length))\n      arg.each do |e|\n\tary.push(dump(e))\n      end\n      ary.push(dump(b))\n      stream.write(ary.join(''))\n    rescue\n      raise(DRbConnError, $!.message, $!.backtrace)\n    end\n    \n    def recv_request(stream) # :nodoc:\n      ref = load(stream)\n      ro = DRb.to_obj(ref)\n      msg = load(stream)\n      argc = load(stream)\n      raise ArgumentError, 'too many arguments' if @argc_limit < argc\n      argv = Array.new(argc, nil)\n      argc.times do |n|\n\targv[n] = load(stream)\n      end\n      block = load(stream)\n      return ro, msg, argv, block\n    end\n\n    def send_reply(stream, succ, result)  # :nodoc:\n      stream.write(dump(succ) + dump(result, !succ))\n    rescue\n      raise(DRbConnError, $!.message, $!.backtrace)\n    end\n\n    def recv_reply(stream)  # :nodoc:\n      succ = load(stream)\n      result = load(stream)\n      [succ, result]\n    end\n\n    private\n    def make_proxy(obj, error=false)\n      if error\n        DRbRemoteError.new(obj)\n      else\n        DRbObject.new(obj)\n      end\n    end\n  end\n\n  # Module managing the underlying network protocol(s) used by drb.\n  #\n  # By default, drb uses the DRbTCPSocket protocol.  Other protocols\n  # can be defined.  A protocol must define the following class methods:\n  #\n  #   [open(uri, config)] Open a client connection to the server at +uri+,\n  #                       using configuration +config+.  Return a protocol\n  #                       instance for this connection.\n  #   [open_server(uri, config)] Open a server listening at +uri+,\n  #                              using configuration +config+.  Return a\n  #                              protocol instance for this listener.\n  #   [uri_option(uri, config)] Take a URI, possibly containing an option\n  #                             component (e.g. a trailing '?param=val'), \n  #                             and return a [uri, option] tuple.\n  #\n  # All of these methods should raise a DRbBadScheme error if the URI \n  # does not identify the protocol they support (e.g. \"druby:\" for\n  # the standard Ruby protocol).  This is how the DRbProtocol module,\n  # given a URI, determines which protocol implementation serves that\n  # protocol.\n  #\n  # The protocol instance returned by #open_server must have the\n  # following methods:\n  #\n  # [accept] Accept a new connection to the server.  Returns a protocol\n  #          instance capable of communicating with the client.\n  # [close] Close the server connection.\n  # [uri] Get the URI for this server.\n  #\n  # The protocol instance returned by #open must have the following methods:\n  #\n  # [send_request (ref, msg_id, arg, b)] \n  #      Send a request to +ref+ with the given message id and arguments.\n  #      This is most easily implemented by calling DRbMessage.send_request,\n  #      providing a stream that sits on top of the current protocol.\n  # [recv_reply]\n  #      Receive a reply from the server and return it as a [success-boolean,\n  #      reply-value] pair.  This is most easily implemented by calling\n  #      DRb.recv_reply, providing a stream that sits on top of the \n  #      current protocol.\n  # [alive?]\n  #      Is this connection still alive?\n  # [close]\n  #      Close this connection.\n  #\n  # The protocol instance returned by #open_server().accept() must have\n  # the following methods:\n  #\n  # [recv_request]\n  #     Receive a request from the client and return a [object, message,\n  #     args, block] tuple.  This is most easily implemented by calling\n  #     DRbMessage.recv_request, providing a stream that sits on top of\n  #     the current protocol.\n  # [send_reply(succ, result)]\n  #     Send a reply to the client.  This is most easily implemented\n  #     by calling DRbMessage.send_reply, providing a stream that sits\n  #     on top of the current protocol.\n  # [close]\n  #     Close this connection.\n  #\n  # A new protocol is registered with the DRbProtocol module using\n  # the add_protocol method.\n  #\n  # For examples of other protocols, see DRbUNIXSocket in drb/unix.rb,\n  # and HTTP0 in sample/http0.rb and sample/http0serv.rb in the full\n  # drb distribution.\n  module DRbProtocol\n\n    # Add a new protocol to the DRbProtocol module.\n    def add_protocol(prot)\n      @protocol.push(prot)\n    end\n    module_function :add_protocol\n\n    # Open a client connection to +uri+ with the configuration +config+.\n    #\n    # The DRbProtocol module asks each registered protocol in turn to\n    # try to open the URI.  Each protocol signals that it does not handle that\n    # URI by raising a DRbBadScheme error.  If no protocol recognises the\n    # URI, then a DRbBadURI error is raised.  If a protocol accepts the\n    # URI, but an error occurs in opening it, a DRbConnError is raised.\n    def open(uri, config, first=true) \n      @protocol.each do |prot|\n\tbegin\n\t  return prot.open(uri, config)\n\trescue DRbBadScheme\n\trescue DRbConnError\n\t  raise($!)\n\trescue\n\t  raise(DRbConnError, \"#{uri} - #{$!.inspect}\")\n\tend\n      end\n      if first && (config[:auto_load] != false)\n\tauto_load(uri, config)\n\treturn open(uri, config, false)\n      end\n      raise DRbBadURI, 'can\\'t parse uri:' + uri\n    end\n    module_function :open\n\n    # Open a server listening for connections at +uri+ with \n    # configuration +config+.\n    #\n    # The DRbProtocol module asks each registered protocol in turn to\n    # try to open a server at the URI.  Each protocol signals that it does \n    # not handle that URI by raising a DRbBadScheme error.  If no protocol \n    # recognises the URI, then a DRbBadURI error is raised.  If a protocol \n    # accepts the URI, but an error occurs in opening it, the underlying \n    # error is passed on to the caller.\n    def open_server(uri, config, first=true)\n      @protocol.each do |prot|\n\tbegin\n\t  return prot.open_server(uri, config)\n\trescue DRbBadScheme\n\tend\n      end\n      if first && (config[:auto_load] != false)\n\tauto_load(uri, config)\n\treturn open_server(uri, config, false)\n      end\n      raise DRbBadURI, 'can\\'t parse uri:' + uri\n    end\n    module_function :open_server\n\n    # Parse +uri+ into a [uri, option] pair.\n    #\n    # The DRbProtocol module asks each registered protocol in turn to\n    # try to parse the URI.  Each protocol signals that it does not handle that\n    # URI by raising a DRbBadScheme error.  If no protocol recognises the\n    # URI, then a DRbBadURI error is raised.  \n    def uri_option(uri, config, first=true)\n      @protocol.each do |prot|\n\tbegin\n\t  uri, opt = prot.uri_option(uri, config)\n\t  # opt = nil if opt == ''\n\t  return uri, opt\n\trescue DRbBadScheme\n\tend\n      end\n      if first && (config[:auto_load] != false)\n\tauto_load(uri, config)\n        return uri_option(uri, config, false)\n      end\n      raise DRbBadURI, 'can\\'t parse uri:' + uri\n    end\n    module_function :uri_option\n\n    def auto_load(uri, config)  # :nodoc:\n      if uri =~ /^drb([a-z0-9]+):/\n\trequire(\"drb/#{$1}\") rescue nil\n      end\n    end\n    module_function :auto_load\n  end\n\n  # The default drb protocol.\n  #\n  # Communicates over a TCP socket.\n  class DRbTCPSocket\n    private\n    def self.parse_uri(uri)\n      if uri =~ /^druby:\\/\\/(.*?):(\\d+)(\\?(.*))?$/\n\thost = $1\n\tport = $2.to_i\n\toption = $4\n\t[host, port, option]\n      else\n\traise(DRbBadScheme, uri) unless uri =~ /^druby:/\n\traise(DRbBadURI, 'can\\'t parse uri:' + uri)\n      end\n    end\n\n    public\n\n    # Open a client connection to +uri+ using configuration +config+.\n    def self.open(uri, config)\n      host, port, option = parse_uri(uri)\n      host.untaint\n      port.untaint\n      soc = TCPSocket.open(host, port)\n      self.new(uri, soc, config)\n    end\n\n    def self.getservername\n      host = Socket::gethostname\n      begin\n        Socket::gethostbyname(host)[0]\n      rescue\n        'localhost'\n      end\n    end\n\n    def self.open_server_inaddr_any(host, port)\n      infos = Socket::getaddrinfo(host, nil, \n                                  Socket::AF_UNSPEC,\n                                  Socket::SOCK_STREAM, \n                                  0,\n                                  Socket::AI_PASSIVE)\n      families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]\n      return TCPServer.open('0.0.0.0', port) if families.has_key?('AF_INET')\n      return TCPServer.open('::', port) if families.has_key?('AF_INET6')\n      return TCPServer.open(port)\n    end\n\n    # Open a server listening for connections at +uri+ using \n    # configuration +config+.\n    def self.open_server(uri, config)\n      uri = 'druby://:0' unless uri\n      host, port, opt = parse_uri(uri)\n      config = {:tcp_original_host => host}.update(config)\n      if host.size == 0\n        host = getservername\n        soc = open_server_inaddr_any(host, port)\n      else\n\tsoc = TCPServer.open(host, port)\n      end\n      port = soc.addr[1] if port == 0\n      config[:tcp_port] = port\n      uri = \"druby://#{host}:#{port}\"\n      self.new(uri, soc, config)\n    end\n\n    # Parse +uri+ into a [uri, option] pair.\n    def self.uri_option(uri, config)\n      host, port, option = parse_uri(uri)\n      return \"druby://#{host}:#{port}\", option\n    end\n\n    # Create a new DRbTCPSocket instance.\n    #\n    # +uri+ is the URI we are connected to.\n    # +soc+ is the tcp socket we are bound to.  +config+ is our\n    # configuration.\n    def initialize(uri, soc, config={})\n      @uri = uri\n      @socket = soc\n      @config = config\n      @acl = config[:tcp_acl]\n      @msg = DRbMessage.new(config)\n      set_sockopt(@socket)\n    end\n\n    # Get the URI that we are connected to.\n    attr_reader :uri\n\n    # Get the address of our TCP peer (the other end of the socket\n    # we are bound to.\n    def peeraddr\n      @socket.peeraddr\n    end\n    \n    # Get the socket.\n    def stream; @socket; end\n\n    # On the client side, send a request to the server.\n    def send_request(ref, msg_id, arg, b)\n      @msg.send_request(stream, ref, msg_id, arg, b)\n    end\n    \n    # On the server side, receive a request from the client.\n    def recv_request\n      @msg.recv_request(stream)\n    end\n\n    # On the server side, send a reply to the client.\n    def send_reply(succ, result)\n      @msg.send_reply(stream, succ, result)\n    end\n\n    # On the client side, receive a reply from the server.\n    def recv_reply\n      @msg.recv_reply(stream)\n    end\n\n    public\n\n    # Close the connection.\n    #\n    # If this is an instance returned by #open_server, then this stops\n    # listening for new connections altogether.  If this is an instance\n    # returned by #open or by #accept, then it closes this particular\n    # client-server session.\n    def close\n      if @socket\n\t@socket.close\n\t@socket = nil\n      end\n    end\n    \n    # On the server side, for an instance returned by #open_server, \n    # accept a client connection and return a new instance to handle\n    # the server's side of this client-server session.\n    def accept\n      while true\n\ts = @socket.accept\n\tbreak if (@acl ? @acl.allow_socket?(s) : true) \n\ts.close\n      end\n      if @config[:tcp_original_host].to_s.size == 0\n        uri = \"druby://#{s.addr[3]}:#{@config[:tcp_port]}\"\n      else\n        uri = @uri\n      end\n      self.class.new(uri, s, @config)\n    end\n\n    # Check to see if this connection is alive.\n    def alive?\n      return false unless @socket\n      if IO.select([@socket], nil, nil, 0)\n\tclose\n\treturn false\n      end\n      true\n    end\n\n    def set_sockopt(soc) # :nodoc:\n      soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)\n      soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC\n    end\n  end\n\n  module DRbProtocol\n    @protocol = [DRbTCPSocket] # default\n  end\n\n  class DRbURIOption  # :nodoc:  I don't understand the purpose of this class...\n    def initialize(option)\n      @option = option.to_s\n    end\n    attr :option\n    def to_s; @option; end\n    \n    def ==(other)\n      return false unless DRbURIOption === other\n      @option == other.option\n    end\n    \n    def hash\n      @option.hash\n    end\n    \n    alias eql? ==\n  end\n\n  # Object wrapping a reference to a remote drb object.\n  #\n  # Method calls on this object are relayed to the remote\n  # object that this object is a stub for.\n  class DRbObject\n\n    # Unmarshall a marshalled DRbObject.\n    #\n    # If the referenced object is located within the local server, then\n    # the object itself is returned.  Otherwise, a new DRbObject is\n    # created to act as a stub for the remote referenced object.\n    def self._load(s)\n      uri, ref = Marshal.load(s)\n      \n      if DRb.here?(uri)\n\tobj = DRb.to_obj(ref)\n        if ((! obj.tainted?) && Thread.current[:drb_untaint])\n          Thread.current[:drb_untaint].push(obj)\n        end\n        return obj\n      end\n\n      self.new_with(uri, ref)\n    end\n\n    def self.new_with(uri, ref)\n      it = self.allocate\n      it.instance_variable_set('@uri', uri)\n      it.instance_variable_set('@ref', ref)\n      it\n    end\n\n    # Create a new DRbObject from a URI alone.\n    def self.new_with_uri(uri)\n      self.new(nil, uri)\n    end\n\n    # Marshall this object.\n    #\n    # The URI and ref of the object are marshalled.\n    def _dump(lv)\n      Marshal.dump([@uri, @ref])\n    end\n\n    # Create a new remote object stub.\n    #\n    # +obj+ is the (local) object we want to create a stub for.  Normally\n    # this is +nil+.  +uri+ is the URI of the remote object that this\n    # will be a stub for.\n    def initialize(obj, uri=nil)\n      @uri = nil\n      @ref = nil\n      if obj.nil?\n\treturn if uri.nil?\n\t@uri, option = DRbProtocol.uri_option(uri, DRb.config)\n\t@ref = DRbURIOption.new(option) unless option.nil?\n      else\n\t@uri = uri ? uri : (DRb.uri rescue nil)\n\t@ref = obj ? DRb.to_id(obj) : nil\n      end\n    end\n\n    # Get the URI of the remote object.\n    def __drburi \n      @uri\n    end\n\n    # Get the reference of the object, if local.\n    def __drbref\n      @ref\n    end\n\n    undef :to_s\n    undef :to_a if respond_to?(:to_a)\n\n    def respond_to?(msg_id, priv=false)\n      case msg_id\n      when :_dump\n        true\n      when :marshal_dump\n        false\n      else\n        method_missing(:respond_to?, msg_id, priv)\n      end\n    end\n\n    # Routes method calls to the referenced object.\n    def method_missing(msg_id, *a, &b)\n      if DRb.here?(@uri)\n\tobj = DRb.to_obj(@ref)\n\tDRb.current_server.check_insecure_method(obj, msg_id)\n\treturn obj.__send__(msg_id, *a, &b) \n      end\n\n      succ, result = self.class.with_friend(@uri) do\n        DRbConn.open(@uri) do |conn|\n          conn.send_message(self, msg_id, a, b)\n        end\n      end\n\n      if succ\n        return result\n      elsif DRbUnknown === result\n        raise result\n      else\n        bt = self.class.prepare_backtrace(@uri, result)\n\tresult.set_backtrace(bt + caller)\n        raise result\n      end\n    end\n\n    def self.with_friend(uri)\n      friend = DRb.fetch_server(uri)\n      return yield() unless friend\n      \n      save = Thread.current['DRb']\n      Thread.current['DRb'] = { 'server' => friend }\n      return yield\n    ensure\n      Thread.current['DRb'] = save if friend\n    end\n\n    def self.prepare_backtrace(uri, result)\n      prefix = \"(#{uri}) \"\n      bt = []\n      result.backtrace.each do |x|\n        break if /`__send__'$/ =~ x \n        if /^\\(druby:\\/\\// =~ x\n          bt.push(x)\n        else\n          bt.push(prefix + x)\n        end\n      end\n      bt\n    end\n\n    def pretty_print(q)   # :nodoc:\n      q.pp_object(self)\n    end\n\n    def pretty_print_cycle(q)   # :nodoc:\n      q.object_address_group(self) {\n        q.breakable\n        q.text '...'\n      }\n    end\n  end\n\n  # Class handling the connection between a DRbObject and the\n  # server the real object lives on.\n  #\n  # This class maintains a pool of connections, to reduce the\n  # overhead of starting and closing down connections for each\n  # method call.\n  #\n  # This class is used internally by DRbObject.  The user does\n  # not normally need to deal with it directly.\n  class DRbConn\n    POOL_SIZE = 16  # :nodoc:\n    @mutex = Mutex.new\n    @pool = []\n\n    def self.open(remote_uri)  # :nodoc:\n      begin\n\tconn = nil\n\n\t@mutex.synchronize do\n\t  #FIXME\n\t  new_pool = []\n\t  @pool.each do |c|\n\t    if conn.nil? and c.uri == remote_uri\n\t      conn = c if c.alive?\n\t    else\n\t      new_pool.push c\n\t    end\n\t  end\n\t  @pool = new_pool\n\tend\n\n\tconn = self.new(remote_uri) unless conn\n\tsucc, result = yield(conn)\n\treturn succ, result\n\n      ensure\n\tif conn\n\t  if succ\n\t    @mutex.synchronize do\n\t      @pool.unshift(conn)\n\t      @pool.pop.close while @pool.size > POOL_SIZE\n\t    end\n\t  else\n\t    conn.close\n\t  end\n\tend\n      end\n    end\n\n    def initialize(remote_uri)  # :nodoc:\n      @uri = remote_uri\n      @protocol = DRbProtocol.open(remote_uri, DRb.config)\n    end\n    attr_reader :uri  # :nodoc:\n\n    def send_message(ref, msg_id, arg, block)  # :nodoc:\n      @protocol.send_request(ref, msg_id, arg, block)\n      @protocol.recv_reply\n    end\n\n    def close  # :nodoc:\n      @protocol.close\n      @protocol = nil\n    end\n\n    def alive?  # :nodoc:\n      return false unless @protocol\n      @protocol.alive?\n    end\n  end\n\n  # Class representing a drb server instance.\n  #\n  # A DRbServer must be running in the local process before any incoming\n  # dRuby calls can be accepted, or any local objects can be passed as\n  # dRuby references to remote processes, even if those local objects are\n  # never actually called remotely. You do not need to start a DRbServer\n  # in the local process if you are only making outgoing dRuby calls\n  # passing marshalled parameters.\n  #\n  # Unless multiple servers are being used, the local DRbServer is normally\n  # started by calling DRb.start_service.\n  class DRbServer\n    @@acl = nil\n    @@idconv = DRbIdConv.new\n    @@secondary_server = nil\n    @@argc_limit = 256\n    @@load_limit = 256 * 102400\n    @@verbose = false\n    @@safe_level = 0\n\n    # Set the default value for the :argc_limit option.\n    #\n    # See #new().  The initial default value is 256.\n    def self.default_argc_limit(argc)\n      @@argc_limit = argc\n    end\n\n    # Set the default value for the :load_limit option.\n    #\n    # See #new().  The initial default value is 25 MB.\n    def self.default_load_limit(sz)\n      @@load_limit = sz\n    end\n\n    # Set the default value for the :acl option.\n    #\n    # See #new().  The initial default value is nil.\n    def self.default_acl(acl)\n      @@acl = acl\n    end\n\n    # Set the default value for the :id_conv option.\n    #\n    # See #new().  The initial default value is a DRbIdConv instance.\n    def self.default_id_conv(idconv)\n      @@idconv = idconv\n    end\n\n    def self.default_safe_level(level)\n      @@safe_level = level\n    end\n\n    # Set the default value of the :verbose option.\n    #\n    # See #new().  The initial default value is false.\n    def self.verbose=(on)\n      @@verbose = on\n    end\n    \n    # Get the default value of the :verbose option.\n    def self.verbose\n      @@verbose\n    end\n\n    def self.make_config(hash={})  # :nodoc:\n      default_config = { \n\t:idconv => @@idconv,\n\t:verbose => @@verbose,\n\t:tcp_acl => @@acl,\n\t:load_limit => @@load_limit,\n\t:argc_limit => @@argc_limit,\n        :safe_level => @@safe_level\n      }\n      default_config.update(hash)\n    end\n\n    # Create a new DRbServer instance.\n    #\n    # +uri+ is the URI to bind to.  This is normally of the form\n    # 'druby://<hostname>:<port>' where <hostname> is a hostname of\n    # the local machine.  If nil, then the system's default hostname\n    # will be bound to, on a port selected by the system; these value\n    # can be retrieved from the +uri+ attribute.  'druby:' specifies\n    # the default dRuby transport protocol: another protocol, such\n    # as 'drbunix:', can be specified instead.\n    #\n    # +front+ is the front object for the server, that is, the object\n    # to which remote method calls on the server will be passed.  If\n    # nil, then the server will not accept remote method calls.\n    #\n    # If +config_or_acl+ is a hash, it is the configuration to\n    # use for this server.  The following options are recognised:\n    #\n    # :idconv :: an id-to-object conversion object.  This defaults\n    #            to an instance of the class DRb::DRbIdConv.\n    # :verbose :: if true, all unsuccessful remote calls on objects\n    #             in the server will be logged to $stdout. false\n    #             by default.\n    # :tcp_acl :: the access control list for this server.  See\n    #             the ACL class from the main dRuby distribution.\n    # :load_limit :: the maximum message size in bytes accepted by\n    #                the server.  Defaults to 25 MB (26214400).\n    # :argc_limit :: the maximum number of arguments to a remote\n    #                method accepted by the server.  Defaults to\n    #                256.\n    #\n    # The default values of these options can be modified on\n    # a class-wide basis by the class methods #default_argc_limit,\n    # #default_load_limit, #default_acl, #default_id_conv,\n    # and #verbose=\n    #\n    # If +config_or_acl+ is not a hash, but is not nil, it is\n    # assumed to be the access control list for this server.\n    # See the :tcp_acl option for more details.\n    #\n    # If no other server is currently set as the primary server,\n    # this will become the primary server.\n    #\n    # The server will immediately start running in its own thread.\n    def initialize(uri=nil, front=nil, config_or_acl=nil)\n      if Hash === config_or_acl\n\tconfig = config_or_acl.dup\n      else\n\tacl = config_or_acl || @@acl\n\tconfig = {\n\t  :tcp_acl => acl\n\t}\n      end\n\n      @config = self.class.make_config(config)\n\n      @protocol = DRbProtocol.open_server(uri, @config)\n      @uri = @protocol.uri\n\n      @front = front\n      @idconv = @config[:idconv]\n      @safe_level = @config[:safe_level]\n\n      @grp = ThreadGroup.new\n      @thread = run\n\n      DRb.regist_server(self)\n    end\n\n    # The URI of this DRbServer.\n    attr_reader :uri\n\n    # The main thread of this DRbServer.\n    #\n    # This is the thread that listens for and accepts connections\n    # from clients, not that handles each client's request-response\n    # session.\n    attr_reader :thread\n\n    # The front object of the DRbServer.\n    # \n    # This object receives remote method calls made on the server's\n    # URI alone, with an object id.\n    attr_reader :front\n\n    # The configuration of this DRbServer\n    attr_reader :config\n\n    attr_reader :safe_level\n\n    # Set whether to operate in verbose mode.\n    #\n    # In verbose mode, failed calls are logged to stdout.\n    def verbose=(v); @config[:verbose]=v; end\n\n    # Get whether the server is in verbose mode.\n    #\n    # In verbose mode, failed calls are logged to stdout.\n    def verbose; @config[:verbose]; end\n\n    # Is this server alive?\n    def alive?\n      @thread.alive?\n    end\n\n    # Stop this server.\n    def stop_service\n      DRb.remove_server(self)\n      if  Thread.current['DRb'] && Thread.current['DRb']['server'] == self\n        Thread.current['DRb']['stop_service'] = true\n      else\n        @thread.kill\n      end\n    end\n\n    # Convert a dRuby reference to the local object it refers to.\n    def to_obj(ref)\n      return front if ref.nil?\n      return front[ref.to_s] if DRbURIOption === ref\n      @idconv.to_obj(ref)\n    end\n\n    # Convert a local object to a dRuby reference.\n    def to_id(obj)\n      return nil if obj.__id__ == front.__id__\n      @idconv.to_id(obj)\n    end\n\n    private\n    def kill_sub_thread\n      Thread.new do\n\tgrp = ThreadGroup.new\n\tgrp.add(Thread.current)\n\tlist = @grp.list\n\twhile list.size > 0\n\t  list.each do |th|\n\t    th.kill if th.alive?\n\t  end\n\t  list = @grp.list\n\tend\n      end\n    end\n\n    def run\n      Thread.start do\n\tbegin\n\t  while true\n\t    main_loop\n\t  end\n\tensure\n\t  @protocol.close if @protocol\n\t  kill_sub_thread\n\tend\n      end\n    end\n\n    # List of insecure methods.\n    #\n    # These methods are not callable via dRuby.\n    INSECURE_METHOD = [\n      :__send__\n    ]\n\n    # Has a method been included in the list of insecure methods?\n    def insecure_method?(msg_id)\n      INSECURE_METHOD.include?(msg_id)\n    end\n\n    # Coerce an object to a string, providing our own representation if\n    # to_s is not defined for the object.\n    def any_to_s(obj)\n      obj.to_s + \":#{obj.class}\"\n    rescue\n      sprintf(\"#<%s:0x%lx>\", obj.class, obj.__id__)      \n    end\n\n    # Check that a method is callable via dRuby.\n    #\n    # +obj+ is the object we want to invoke the method on. +msg_id+ is the\n    # method name, as a Symbol.\n    #\n    # If the method is an insecure method (see #insecure_method?) a \n    # SecurityError is thrown.  If the method is private or undefined,\n    # a NameError is thrown.\n    def check_insecure_method(obj, msg_id)\n      return true if Proc === obj && msg_id == :__drb_yield\n      raise(ArgumentError, \"#{any_to_s(msg_id)} is not a symbol\") unless Symbol == msg_id.class\n      raise(SecurityError, \"insecure method `#{msg_id}'\") if insecure_method?(msg_id)\n      \n      if obj.private_methods.include?(msg_id.to_s)\n\tdesc = any_to_s(obj)\n        raise NoMethodError, \"private method `#{msg_id}' called for #{desc}\"\n      elsif obj.protected_methods.include?(msg_id.to_s)\n\tdesc = any_to_s(obj)\n        raise NoMethodError, \"protected method `#{msg_id}' called for #{desc}\"\n      else\n        true\n      end\n    end\n    public :check_insecure_method\n    \n    class InvokeMethod  # :nodoc:\n      def initialize(drb_server, client)\n\t@drb_server = drb_server\n        @safe_level = drb_server.safe_level\n\t@client = client\n      end\n\n      def perform\n\t@result = nil\n\t@succ = false\n\tsetup_message\n\n        if $SAFE < @safe_level\n          info = Thread.current['DRb']\n          if @block\n            @result = Thread.new {\n              Thread.current['DRb'] = info\n              $SAFE = @safe_level\n              perform_with_block\n            }.value\n          else\n            @result = Thread.new { \n              Thread.current['DRb'] = info\n              $SAFE = @safe_level\n              perform_without_block\n            }.value\n          end\n        else\n          if @block\n            @result = perform_with_block\n          else\n            @result = perform_without_block\n          end\n        end\n\t@succ = true\n\tif @msg_id == :to_ary && @result.class == Array\n\t  @result = DRbArray.new(@result) \n\tend\n\treturn @succ, @result\n      rescue StandardError, ScriptError, Interrupt\n\t@result = $!\n\treturn @succ, @result\n      end\n\n      private\n      def init_with_client\n\tobj, msg, argv, block = @client.recv_request\n        @obj = obj\n        @msg_id = msg.intern\n        @argv = argv\n        @block = block\n      end\n      \n      def check_insecure_method\n        @drb_server.check_insecure_method(@obj, @msg_id)\n      end\n\n      def setup_message\n\tinit_with_client\n\tcheck_insecure_method\n      end\n      \n      def perform_without_block\n\tif Proc === @obj && @msg_id == :__drb_yield\n          if @argv.size == 1\n\t    ary = @argv\n\t  else\n\t    ary = [@argv]\n\t  end\n\t  ary.collect(&@obj)[0]\n\telse\n\t  @obj.__send__(@msg_id, *@argv)\n\tend\n      end\n\n    end\n\n    if RUBY_VERSION >= '1.8'\n      require 'drb/invokemethod'\n      class InvokeMethod\n        include InvokeMethod18Mixin\n      end\n    else\n      require 'drb/invokemethod16'\n      class InvokeMethod\n        include InvokeMethod16Mixin\n      end\n    end\n\n    # The main loop performed by a DRbServer's internal thread.\n    #\n    # Accepts a connection from a client, and starts up its own\n    # thread to handle it.  This thread loops, receiving requests\n    # from the client, invoking them on a local object, and\n    # returning responses, until the client closes the connection\n    # or a local method call fails.\n    def main_loop\n      Thread.start(@protocol.accept) do |client|\n\t@grp.add Thread.current\n\tThread.current['DRb'] = { 'client' => client ,\n\t                          'server' => self }\n\tloop do\n\t  begin\n\t    succ = false\n\t    invoke_method = InvokeMethod.new(self, client)\n\t    succ, result = invoke_method.perform\n\t    if !succ && verbose\n\t      p result\n\t      result.backtrace.each do |x|\n\t\tputs x\n\t      end\n\t    end\n\t    client.send_reply(succ, result) rescue nil\n\t  ensure\n            client.close unless succ\n            if Thread.current['DRb']['stop_service']\n              Thread.new { stop_service }\n            end\n            break unless succ\n\t  end\n\tend\n      end\n    end\n  end\n\n  @primary_server = nil\n\n  # Start a dRuby server locally.\n  #\n  # The new dRuby server will become the primary server, even\n  # if another server is currently the primary server.\n  #\n  # +uri+ is the URI for the server to bind to.  If nil,\n  # the server will bind to random port on the default local host\n  # name and use the default dRuby protocol.\n  #\n  # +front+ is the server's front object.  This may be nil.\n  #\n  # +config+ is the configuration for the new server.  This may\n  # be nil.\n  #\n  # See DRbServer::new.\n  def start_service(uri=nil, front=nil, config=nil)\n    @primary_server = DRbServer.new(uri, front, config)\n  end\n  module_function :start_service\n\n  # The primary local dRuby server.\n  #\n  # This is the server created by the #start_service call.  \n  attr_accessor :primary_server\n  module_function :primary_server=, :primary_server\n\n  # Get the 'current' server.\n  #\n  # In the context of execution taking place within the main\n  # thread of a dRuby server (typically, as a result of a remote\n  # call on the server or one of its objects), the current\n  # server is that server.  Otherwise, the current server is\n  # the primary server.\n  #\n  # If the above rule fails to find a server, a DRbServerNotFound\n  # error is raised.\n  def current_server\n    drb = Thread.current['DRb'] \n    server = (drb && drb['server']) ? drb['server'] : @primary_server \n    raise DRbServerNotFound unless server\n    return server\n  end\n  module_function :current_server\n\n  # Stop the local dRuby server.\n  #\n  # This operates on the primary server.  If there is no primary\n  # server currently running, it is a noop.\n  def stop_service\n    @primary_server.stop_service if @primary_server\n    @primary_server = nil\n  end\n  module_function :stop_service\n\n  # Get the URI defining the local dRuby space.\n  #\n  # This is the URI of the current server.  See #current_server.\n  def uri\n    drb = Thread.current['DRb']\n    client = (drb && drb['client'])\n    if client\n      uri = client.uri\n      return uri if uri\n    end\n    current_server.uri\n  end\n  module_function :uri\n\n  # Is +uri+ the URI for the current local server?\n  def here?(uri)\n    (current_server.uri rescue nil) == uri\n  end\n  module_function :here?\n\n  # Get the configuration of the current server.\n  #\n  # If there is no current server, this returns the default configuration.\n  # See #current_server and DRbServer::make_config.\n  def config\n    current_server.config\n  rescue\n    DRbServer.make_config\n  end\n  module_function :config\n  \n  # Get the front object of the current server.\n  #\n  # This raises a DRbServerNotFound error if there is no current server.\n  # See #current_server.\n  def front\n    current_server.front\n  end\n  module_function :front\n\n  # Convert a reference into an object using the current server.\n  #\n  # This raises a DRbServerNotFound error if there is no current server.\n  # See #current_server.\n  def to_obj(ref)\n    current_server.to_obj(ref)\n  end\n\n  # Get a reference id for an object using the current server.\n  #\n  # This raises a DRbServerNotFound error if there is no current server.\n  # See #current_server.\n  def to_id(obj)\n    current_server.to_id(obj)\n  end\n  module_function :to_id\n  module_function :to_obj\n\n  # Get the thread of the primary server.\n  #\n  # This returns nil if there is no primary server.  See #primary_server.\n  def thread\n    @primary_server ? @primary_server.thread : nil\n  end\n  module_function :thread\n\n  # Set the default id conv object.\n  #\n  # See DRbServer#default_id_conv.\n  def install_id_conv(idconv)\n    DRbServer.default_id_conv(idconv)\n  end\n  module_function :install_id_conv\n\n  # Set the default acl.\n  #\n  # See DRb::DRbServer.default_acl.\n  def install_acl(acl)\n    DRbServer.default_acl(acl)\n  end\n  module_function :install_acl\n\n  @mutex = Mutex.new\n  def mutex\n    @mutex\n  end\n  module_function :mutex\n\n  @server = {}\n  def regist_server(server)\n    @server[server.uri] = server\n    mutex.synchronize do\n      @primary_server = server unless @primary_server\n    end\n  end\n  module_function :regist_server\n\n  def remove_server(server)\n    @server.delete(server.uri)\n  end\n  module_function :remove_server\n  \n  def fetch_server(uri)\n    @server[uri]\n  end\n  module_function :fetch_server\nend\n\nDRbObject = DRb::DRbObject\nDRbUndumped = DRb::DRbUndumped\nDRbIdConv = DRb::DRbIdConv\n"
  },
  {
    "path": "lib/drb/eq.rb",
    "content": "require 'drb/drb'\n\nmodule DRb\n  class DRbObject\n    def ==(other)\n      return false unless DRbObject === other\n     (@ref == other.__drbref) && (@uri == other.__drburi)\n    end\n\n    def hash\n      [@uri, @ref].hash\n    end\n\n    alias eql? ==\n  end\nend\n"
  },
  {
    "path": "lib/drb/extserv.rb",
    "content": "=begin\n external service\n \tCopyright (c) 2000,2002 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nmodule DRb\n  class ExtServ\n    include DRbUndumped\n\n    def initialize(there, name, server=nil)\n      @server = server || DRb::primary_server\n      @name = name\n      ro = DRbObject.new(nil, there)\n      @invoker = ro.regist(name, DRbObject.new(self, @server.uri))\n    end\n    attr_reader :server\n\n    def front\n      DRbObject.new(nil, @server.uri)\n    end\n\n    def stop_service\n      @invoker.unregist(@name)\n      server = @server\n      @server = nil\n      server.stop_service\n      true\n    end\n\n    def alive?\n      @server ? @server.alive? : false\n    end\n  end\nend\n\nif __FILE__ == $0\n  class Foo\n    include DRbUndumped\n\n    def initialize(str)\n      @str = str\n    end\n\n    def hello(it)\n      \"#{it}: #{self}\"\n    end\n\n    def to_s\n      @str\n    end\n  end\n\n  cmd = ARGV.shift\n  case cmd\n  when 'itest1', 'itest2'\n    front = Foo.new(cmd)\n    manager = DRb::DRbServer.new(nil, front)\n    es = DRb::ExtServ.new(ARGV.shift, ARGV.shift, manager)\n    es.server.thread.join\n  end\nend\n\n"
  },
  {
    "path": "lib/drb/extservm.rb",
    "content": "=begin\n external service manager\n \tCopyright (c) 2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\nrequire 'thread'\nrequire 'monitor'\n\nmodule DRb\n  class ExtServManager\n    include DRbUndumped\n    include MonitorMixin\n\n    @@command = {}\n\n    def self.command\n      @@command\n    end\n\n    def self.command=(cmd)\n      @@command = cmd\n    end\n      \n    def initialize\n      super()\n      @cond = new_cond\n      @servers = {}\n      @waiting = []\n      @queue = Queue.new\n      @thread = invoke_thread\n      @uri = nil\n    end\n    attr_accessor :uri\n\n    def service(name)\n      synchronize do\n        while true\n          server = @servers[name]\n          return server if server && server.alive?\n          invoke_service(name)\n          @cond.wait\n        end\n      end\n    end\n\n    def regist(name, ro)\n      synchronize do\n        @servers[name] = ro\n        @cond.signal\n      end\n      self\n    end\n    \n    def unregist(name)\n      synchronize do\n\t@servers.delete(name)\n      end\n    end\n\n    private\n    def invoke_thread\n      Thread.new do\n\twhile true\n\t  name = @queue.pop\n\t  invoke_service_command(name, @@command[name])\n\tend\n      end\n    end\n\n    def invoke_service(name)\n      @queue.push(name)\n    end\n\n    def invoke_service_command(name, command)\n      raise \"invalid command. name: #{name}\" unless command\n      synchronize do\n\treturn if @servers.include?(name)\n\t@servers[name] = false\n      end\n      uri = @uri || DRb.uri\n      if RUBY_PLATFORM =~ /mswin32/ && /NT/ =~ ENV[\"OS\"]\n        system(%Q'cmd /c start \"ruby\" /b #{command} #{uri} #{name}')\n      else\n\tsystem(\"#{command} #{uri} #{name} &\")\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/drb/gw.rb",
    "content": "require 'drb/drb'\nrequire 'monitor'\n\nmodule DRb\n  class GWIdConv < DRbIdConv\n    def to_obj(ref)\n      if Array === ref && ref[0] == :DRbObject\n        return DRbObject.new_with(ref[1], ref[2])\n      end\n      super(ref)\n    end\n  end\n\n  class GW\n    include MonitorMixin\n    def initialize\n      super()\n      @hash = {}\n    end\n\n    def [](key)\n      synchronize do\n        @hash[key]\n      end\n    end\n\n    def []=(key, v)\n      synchronize do\n        @hash[key] = v\n      end\n    end\n  end\n\n  class DRbObject\n    def self._load(s)\n      uri, ref = Marshal.load(s)\n      if DRb.uri == uri\n        return ref ? DRb.to_obj(ref) : DRb.front\n      end\n\n      self.new_with(DRb.uri, [:DRbObject, uri, ref])\n    end\n\n    def _dump(lv)\n      if DRb.uri == @uri\n        if Array === @ref && @ref[0] == :DRbObject\n          Marshal.dump([@ref[1], @ref[2]])\n        else\n          Marshal.dump([@uri, @ref]) # ??\n        end\n      else\n        Marshal.dump([DRb.uri, [:DRbObject, @uri, @ref]])\n      end\n    end\n  end\nend\n\n=begin\nDRb.install_id_conv(DRb::GWIdConv.new)\n\nfront = DRb::GW.new\n\ns1 = DRb::DRbServer.new('drbunix:/tmp/gw_b_a', front)\ns2 = DRb::DRbServer.new('drbunix:/tmp/gw_b_c', front)\n\ns1.thread.join\ns2.thread.join\n=end\n\n=begin\n# foo.rb\n\nrequire 'drb/drb'\n\nclass Foo\n  include DRbUndumped\n  def initialize(name, peer=nil)\n    @name = name\n    @peer = peer\n  end\n\n  def ping(obj)\n    puts \"#{@name}: ping: #{obj.inspect}\"\n    @peer.ping(self) if @peer\n  end\nend\n=end\n\n=begin\n# gw_a.rb\nrequire 'drb/unix'\nrequire 'foo'\n\nobj = Foo.new('a')\nDRb.start_service(\"drbunix:/tmp/gw_a\", obj)\n\nrobj = DRbObject.new_with_uri('drbunix:/tmp/gw_b_a')\nrobj[:a] = obj\n\nDRb.thread.join\n=end\n\n=begin\n# gw_c.rb\nrequire 'drb/unix'\nrequire 'foo'\n\nfoo = Foo.new('c', nil)\n\nDRb.start_service(\"drbunix:/tmp/gw_c\", nil)\n\nrobj = DRbObject.new_with_uri(\"drbunix:/tmp/gw_b_c\")\n\nputs \"c->b\"\na = robj[:a]\nsleep 2\n\na.ping(foo)\n\nDRb.thread.join\n=end\n\n"
  },
  {
    "path": "lib/drb/invokemethod.rb",
    "content": "# for ruby-1.8.0\n\nmodule DRb\n  class DRbServer\n    module InvokeMethod18Mixin\n      def block_yield(x)\n\tif x.size == 1 && x[0].class == Array\n\t  x[0] = DRbArray.new(x[0])\n\tend\n        block_value = @block.call(*x)\n      end\n      \n      def perform_with_block\n        @obj.__send__(@msg_id, *@argv) do |*x|\n          jump_error = nil\n          begin\n            block_value = block_yield(x)\n          rescue LocalJumpError\n            jump_error = $!\n          end\n          if jump_error\n            case jump_error.reason\n            when :retry\n              retry\n            when :break\n              break(jump_error.exit_value)\n            else\n              raise jump_error\n            end\n          end\n          block_value\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/drb/observer.rb",
    "content": "require 'observer'\n\nmodule DRb\n  module DRbObservable\n    include Observable\n\n    def notify_observers(*arg)\n      if defined? @observer_state and @observer_state\n\tif defined? @observer_peers\n\t  for i in @observer_peers.dup\n\t    begin\n\t      i.update(*arg)\n\t    rescue\n\t      delete_observer(i)\n\t    end\n\t  end\n\tend\n\t@observer_state = false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/drb/ssl.rb",
    "content": "require 'socket'\nrequire 'openssl'\nrequire 'drb/drb'\nrequire 'singleton'\n\nmodule DRb\n\n  class DRbSSLSocket < DRbTCPSocket\n\n    class SSLConfig\n\n      DEFAULT = {\n\t:SSLCertificate       => nil,\n\t:SSLPrivateKey        => nil,\n\t:SSLClientCA          => nil,\n\t:SSLCACertificatePath => nil,\n\t:SSLCACertificateFile => nil,\n\t:SSLVerifyMode        => ::OpenSSL::SSL::VERIFY_NONE, \n\t:SSLVerifyDepth       => nil,\n\t:SSLVerifyCallback    => nil,   # custom verification\n        :SSLCertificateStore  => nil,\n\t# Must specify if you use auto generated certificate.\n\t:SSLCertName          => nil,   # e.g. [[\"CN\",\"fqdn.example.com\"]]\n\t:SSLCertComment       => \"Generated by Ruby/OpenSSL\"\n      }\n\n      def initialize(config)\n\t@config  = config\n        @cert    = config[:SSLCertificate]\n        @pkey    = config[:SSLPrivateKey]\n        @ssl_ctx = nil\n      end\n\n      def [](key); \n\t@config[key] || DEFAULT[key]\n      end\n\n      def connect(tcp)\n\tssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)\n\tssl.sync = true\n\tssl.connect\n\tssl\n      end\n      \n      def accept(tcp)\n\tssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)\n\tssl.sync = true\n\tssl.accept\n\tssl\n      end\n      \n      def setup_certificate\n        if @cert && @pkey\n          return\n        end\n\n\trsa = OpenSSL::PKey::RSA.new(512){|p, n|\n\t  next unless self[:verbose]\n\t  case p\n\t  when 0; $stderr.putc \".\"  # BN_generate_prime\n\t  when 1; $stderr.putc \"+\"  # BN_generate_prime\n\t  when 2; $stderr.putc \"*\"  # searching good prime,\n\t                            # n = #of try,\n                          \t    # but also data from BN_generate_prime\n\t  when 3; $stderr.putc \"\\n\" # found good prime, n==0 - p, n==1 - q,\n                         \t    # but also data from BN_generate_prime\n\t  else;   $stderr.putc \"*\"  # BN_generate_prime\n\t  end\n\t}\n\n\tcert = OpenSSL::X509::Certificate.new\n\tcert.version = 3\n\tcert.serial = 0\n\tname = OpenSSL::X509::Name.new(self[:SSLCertName])\n\tcert.subject = name\n\tcert.issuer = name\n\tcert.not_before = Time.now\n\tcert.not_after = Time.now + (365*24*60*60)\n\tcert.public_key = rsa.public_key\n\t\n\tef = OpenSSL::X509::ExtensionFactory.new(nil,cert)\n\tcert.extensions = [\n\t  ef.create_extension(\"basicConstraints\",\"CA:FALSE\"),\n\t  ef.create_extension(\"subjectKeyIdentifier\", \"hash\") ]\n\tef.issuer_certificate = cert\n\tcert.add_extension(ef.create_extension(\"authorityKeyIdentifier\",\n\t\t\t\t\t       \"keyid:always,issuer:always\"))\n\tif comment = self[:SSLCertComment]\n\t  cert.add_extension(ef.create_extension(\"nsComment\", comment))\n\tend\n\tcert.sign(rsa, OpenSSL::Digest::SHA1.new)\n\t\n\t@cert = cert\n        @pkey = rsa\n      end\n\n      def setup_ssl_context\n        ctx = ::OpenSSL::SSL::SSLContext.new\n        ctx.cert            = @cert\n        ctx.key             = @pkey\n\tctx.client_ca       = self[:SSLClientCA]\n\tctx.ca_path         = self[:SSLCACertificatePath]\n\tctx.ca_file         = self[:SSLCACertificateFile]\n\tctx.verify_mode     = self[:SSLVerifyMode]\n\tctx.verify_depth    = self[:SSLVerifyDepth]\n\tctx.verify_callback = self[:SSLVerifyCallback]\n        ctx.cert_store      = self[:SSLCertificateStore]\n        @ssl_ctx = ctx\n      end\n    end\n\n    def self.parse_uri(uri)\n      if uri =~ /^drbssl:\\/\\/(.*?):(\\d+)(\\?(.*))?$/\n\thost = $1\n\tport = $2.to_i\n\toption = $4\n\t[host, port, option]\n      else\n\traise(DRbBadScheme, uri) unless uri =~ /^drbssl:/\n\traise(DRbBadURI, 'can\\'t parse uri:' + uri)\n      end\n    end\n\n    def self.open(uri, config)\n      host, port, option = parse_uri(uri)\n      host.untaint\n      port.untaint\n      soc = TCPSocket.open(host, port)\n      ssl_conf = SSLConfig::new(config)\n      ssl_conf.setup_ssl_context\n      ssl = ssl_conf.connect(soc)\n      self.new(uri, ssl, ssl_conf, true)\n    end\n\n    def self.open_server(uri, config)\n      uri = 'drbssl://:0' unless uri\n      host, port, opt = parse_uri(uri)\n      if host.size == 0\n        host = getservername\n        soc = open_server_inaddr_any(host, port)\n      else\n\tsoc = TCPServer.open(host, port)\n      end\n      port = soc.addr[1] if port == 0\n      @uri = \"drbssl://#{host}:#{port}\"\n      \n      ssl_conf = SSLConfig.new(config)\n      ssl_conf.setup_certificate\n      ssl_conf.setup_ssl_context\n      self.new(@uri, soc, ssl_conf, false)\n    end\n\n    def self.uri_option(uri, config)\n      host, port, option = parse_uri(uri)\n      return \"drbssl://#{host}:#{port}\", option\n    end\n\n    def initialize(uri, soc, config, is_established)\n      @ssl = is_established ? soc : nil\n      super(uri, soc.to_io, config)\n    end\n    \n    def stream; @ssl; end\n\n    def close\n      if @ssl\n\t@ssl.close\n\t@ssl = nil\n      end\n      super\n    end\n      \n    def accept\n      begin\n      while true\n\tsoc = @socket.accept\n\tbreak if (@acl ? @acl.allow_socket?(soc) : true) \n\tsoc.close\n      end\n      ssl = @config.accept(soc)\n      self.class.new(uri, ssl, @config, true)\n      rescue OpenSSL::SSL::SSLError\n\twarn(\"#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})\") if @config[:verbose]\n\tretry\n      end\n    end\n  end\n  \n  DRbProtocol.add_protocol(DRbSSLSocket)\nend\n"
  },
  {
    "path": "lib/drb/timeridconv.rb",
    "content": "require 'drb/drb'\nrequire 'monitor'\n\nmodule DRb\n  class TimerIdConv < DRbIdConv\n    class TimerHolder2\n      include MonitorMixin\n\n      class InvalidIndexError < RuntimeError; end\n\n      def initialize(timeout=600)\n\tsuper()\n\t@sentinel = Object.new\n\t@gc = {}\n\t@curr = {}\n\t@renew = {}\n\t@timeout = timeout\n\t@keeper = keeper\n      end\n\n      def add(obj)\n\tsynchronize do \n\t  key = obj.__id__\n\t  @curr[key] = obj\n\t  return key\n\tend\n      end\n\n      def fetch(key, dv=@sentinel)\n\tsynchronize do \n\t  obj = peek(key)\n\t  if obj == @sentinel\n\t    return dv unless dv == @sentinel\n\t    raise InvalidIndexError\n\t  end\n\t  @renew[key] = obj # KeepIt\n\t  return obj\n\tend\n      end\n\n      def include?(key)\n\tsynchronize do \n\t  obj = peek(key)\n\t  return false if obj == @sentinel\n\t  true\n\tend\n      end\n\n      def peek(key)\n\tsynchronize do \n\t  return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel)))\n\tend\n      end\n\n      private\n      def alternate\n\tsynchronize do\n\t  @gc = @curr       # GCed\n\t  @curr = @renew\n\t  @renew = {}\n\tend\n      end\n\n      def keeper\n\tThread.new do\n\t  loop do\n\t    size = alternate\n\t    sleep(@timeout)\n\t  end\n\tend\n      end\n    end\n\n    def initialize(timeout=600)\n      @holder = TimerHolder2.new(timeout)\n    end\n\n    def to_obj(ref)\n      return super if ref.nil?\n      @holder.fetch(ref)\n    rescue TimerHolder2::InvalidIndexError\n      raise \"invalid reference\"\n    end\n\n    def to_id(obj)\n      return @holder.add(obj)\n    end\n  end\nend\n\n# DRb.install_id_conv(TimerIdConv.new)\n"
  },
  {
    "path": "lib/drb/unix.rb",
    "content": "require 'socket'\nrequire 'drb/drb'\nrequire 'tmpdir'\n\nraise(LoadError, \"UNIXServer is required\") unless defined?(UNIXServer)\n\nmodule DRb\n\n  class DRbUNIXSocket < DRbTCPSocket\n    def self.parse_uri(uri)\n      if /^drbunix:(.*?)(\\?(.*))?$/ =~ uri \n\tfilename = $1\n\toption = $3\n\t[filename, option]\n      else\n\traise(DRbBadScheme, uri) unless uri =~ /^drbunix:/\n\traise(DRbBadURI, 'can\\'t parse uri:' + uri)\n      end\n    end\n\n    def self.open(uri, config)\n      filename, option = parse_uri(uri)\n      filename.untaint\n      soc = UNIXSocket.open(filename)\n      self.new(uri, soc, config)\n    end\n\n    def self.open_server(uri, config)\n      filename, option = parse_uri(uri)\n      if filename.size == 0\n\tsoc = temp_server\n        filename = soc.path\n\turi = 'drbunix:' + soc.path\n      else\n\tsoc = UNIXServer.open(filename)\n      end\n      owner = config[:UNIXFileOwner]\n      group = config[:UNIXFileGroup]\n      if owner || group\n        require 'etc'\n        owner = Etc.getpwnam( owner ).uid  if owner\n        group = Etc.getgrnam( group ).gid  if group\n        File.chown owner, group, filename\n      end\n      mode = config[:UNIXFileMode]\n      File.chmod(mode, filename) if mode\n\n      self.new(uri, soc, config, true)\n    end\n\n    def self.uri_option(uri, config)\n      filename, option = parse_uri(uri)\n      return \"drbunix:#{filename}\", option\n    end\n\n    def initialize(uri, soc, config={}, server_mode = false)\n      super(uri, soc, config)\n      set_sockopt(@socket)\n      @server_mode = server_mode\n      @acl = nil\n    end\n    \n    # import from tempfile.rb\n    Max_try = 10\n    private\n    def self.temp_server\n      tmpdir = Dir::tmpdir\n      n = 0\n      while true\n\tbegin\n\t  tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)\n\t  lock = tmpname + '.lock'\n\t  unless File.exist?(tmpname) or File.exist?(lock)\n\t    Dir.mkdir(lock)\n\t    break\n\t  end\n\trescue\n\t  raise \"cannot generate tempfile `%s'\" % tmpname if n >= Max_try\n\t  #sleep(1)\n\tend\n\tn += 1\n      end\n      soc = UNIXServer.new(tmpname)\n      Dir.rmdir(lock)\n      soc\n    end\n\n    public\n    def close\n      return unless @socket\n      path = @socket.path if @server_mode\n      @socket.close\n      File.unlink(path) if @server_mode\n      @socket = nil\n    end\n\n    def accept\n      s = @socket.accept\n      self.class.new(nil, s, @config)\n    end\n\n    def set_sockopt(soc)\n      soc.fcntl(Fcntl::F_SETFL, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC\n    end\n  end\n\n  DRbProtocol.add_protocol(DRbUNIXSocket)\nend\n"
  },
  {
    "path": "lib/drb.rb",
    "content": "require 'drb/drb'\n\n"
  },
  {
    "path": "lib/e2mmap.rb",
    "content": "#\n#   e2mmap.rb - for ruby 1.1\n#   \t$Release Version: 2.0$\n#   \t$Revision: 1.10 $\n#   \t$Date: 1999/02/17 12:33:17 $\n#   \tby Keiju ISHITSUKA\n#\n# --\n#   Usage:\n#\n# U1)\n#   class Foo\n#     extend Exception2MessageMapper\n#     def_e2message ExistingExceptionClass, \"message...\"\n#     def_exception :NewExceptionClass, \"message...\"[, superclass]\n#     ...\n#   end\n#\n# U2)\n#   module Error\n#     extend Exception2MessageMapper\n#     def_e2meggage ExistingExceptionClass, \"message...\"\n#     def_exception :NewExceptionClass, \"message...\"[, superclass]\n#     ...\n#   end\n#   class Foo\n#     include Error\n#     ...\n#   end\n#\n#   foo = Foo.new\n#   foo.Fail ....\n#\n# U3)\n#   module Error\n#     extend Exception2MessageMapper\n#     def_e2message ExistingExceptionClass, \"message...\"\n#     def_exception :NewExceptionClass, \"message...\"[, superclass]\n#     ...\n#   end\n#   class Foo\n#     extend Exception2MessageMapper\n#     include Error\n#     ...\n#   end\n#\n#   Foo.Fail NewExceptionClass, arg...\n#   Foo.Fail ExistingExceptionClass, arg...\n#\n#\nfail \"Use Ruby 1.1\" if VERSION < \"1.1\"\n\nmodule Exception2MessageMapper\n  @RCS_ID='-$Id: e2mmap.rb,v 1.10 1999/02/17 12:33:17 keiju Exp keiju $-'\n\n  E2MM = Exception2MessageMapper\n\n  def E2MM.extend_object(cl)\n    super\n    cl.bind(self) unless cl == E2MM\n  end\n  \n  # backward compatibility\n  def E2MM.extend_to(b)\n    c = eval(\"self\", b)\n    c.extend(self)\n  end\n\n  def bind(cl)\n    self.module_eval %[\n      def Raise(err = nil, *rest)\n\tException2MessageMapper.Raise(self.class, err, *rest)\n      end\n      alias Fail Raise\n\n      def self.included(mod)\n\tmod.extend Exception2MessageMapper\n      end\n    ]\n  end\n\n  # Fail(err, *rest)\n  #\terr:\texception\n  #\trest:\tmessage arguments\n  #\n  def Raise(err = nil, *rest)\n    E2MM.Raise(self, err, *rest)\n  end\n  alias Fail Raise\n\n  # backward compatibility\n  alias fail! fail\n  def fail(err = nil, *rest)\n    begin \n      E2MM.Fail(self, err, *rest)\n    rescue E2MM::ErrNotRegisteredException\n      super\n    end\n  end\n  class << self\n    public :fail\n  end\n\n  \n  # def_e2message(c, m)\n  #\t    c:  exception\n  #\t    m:  message_form\n  #\tdefine exception c with message m.\n  #\n  def def_e2message(c, m)\n    E2MM.def_e2message(self, c, m)\n  end\n  \n  # def_exception(n, m, s)\n  #\t    n:  exception_name\n  #\t    m:  message_form\n  #\t    s:\tsuperclass(default: StandardError)\n  #\tdefine exception named ``c'' with message m.\n  #\n  def def_exception(n, m, s = StandardError)\n    E2MM.def_exception(self, n, m, s)\n  end\n\n  #\n  # Private definitions.\n  #\n  # {[class, exp] => message, ...}\n  @MessageMap = {}\n\n  # E2MM.def_exception(k, e, m)\n  #\t    k:  class to define exception under.\n  #\t    e:  exception\n  #\t    m:  message_form\n  #\tdefine exception c with message m.\n  #\n  def E2MM.def_e2message(k, c, m)\n    E2MM.instance_eval{@MessageMap[[k, c]] = m}\n    c\n  end\n  \n  # E2MM.def_exception(k, n, m, s)\n  #\t    k:  class to define exception under.\n  #\t    n:  exception_name\n  #\t    m:  message_form\n  #\t    s:\tsuperclass(default: StandardError)\n  #\tdefine exception named ``c'' with message m.\n  #\n  def E2MM.def_exception(k, n, m, s = StandardError)\n    n = n.id2name if n.kind_of?(Fixnum)\n    e = Class.new(s)\n    E2MM.instance_eval{@MessageMap[[k, e]] = m}\n    k.const_set(n, e)\n  end\n\n  # Fail(klass, err, *rest)\n  #\tklass:  class to define exception under.\n  #\terr:\texception\n  #\trest:\tmessage arguments\n  #\n  def E2MM.Raise(klass = E2MM, err = nil, *rest)\n    if form = e2mm_message(klass, err)\n      $! = err.new(sprintf(form, *rest))\n      $@ = caller(1) if $@.nil?\n      #p $@\n      #p __FILE__\n      $@.shift if $@[0] =~ /^#{Regexp.quote(__FILE__)}:/\n      raise\n    else\n      E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect\n    end\n  end\n  class <<E2MM\n    alias Fail Raise\n  end\n\n  def E2MM.e2mm_message(klass, exp)\n    for c in klass.ancestors\n      if mes = @MessageMap[[c,exp]]\n\t#p mes\n\tm = klass.instance_eval('\"' + mes + '\"')\n\treturn m\n      end\n    end\n    nil\n  end\n  class <<self\n    alias message e2mm_message\n  end\n\n  E2MM.def_exception(E2MM, \n\t\t     :ErrNotRegisteredException, \n\t\t     \"not registerd exception(%s)\")\nend\n\n\n"
  },
  {
    "path": "lib/erb.rb",
    "content": "# = ERB -- Ruby Templating\n#\n# Author:: Masatoshi SEKI\n# Documentation:: James Edward Gray II and Gavin Sinclair\n#\n# See ERB for primary documentation and ERB::Util for a couple of utility\n# routines.\n#\n# Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI\n#\n# You can redistribute it and/or modify it under the same terms as Ruby.\n\n#\n# = ERB -- Ruby Templating\n#\n# == Introduction\n#\n# ERB provides an easy to use but powerful templating system for Ruby.  Using\n# ERB, actual Ruby code can be added to any plain text document for the\n# purposes of generating document information details and/or flow control.\n#\n# A very simple example is this:\n# \n#   require 'erb'\n#\n#   x = 42\n#   template = ERB.new <<-EOF\n#     The value of x is: <%= x %>\n#   EOF\n#   puts template.result(binding)\n#\n# <em>Prints:</em> The value of x is: 42\n#\n# More complex examples are given below.\n#\n#\n# == Recognized Tags\n#\n# ERB recognizes certain tags in the provided template and converts them based\n# on the rules below:\n#\n#   <% Ruby code -- inline with output %>\n#   <%= Ruby expression -- replace with result %>\n#   <%# comment -- ignored -- useful in testing %>\n#   % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)\n#   %% replaced with % if first thing on a line and % processing is used\n#   <%% or %%> -- replace with <% or %> respectively\n#\n# All other text is passed through ERB filtering unchanged.\n#\n#\n# == Options\n#\n# There are several settings you can change when you use ERB:\n# * the nature of the tags that are recognized;\n# * the value of <tt>$SAFE</tt> under which the template is run;\n# * the binding used to resolve local variables in the template.\n#\n# See the ERB.new and ERB#result methods for more detail.\n#\n#\n# == Examples\n#\n# === Plain Text\n#\n# ERB is useful for any generic templating situation.  Note that in this example, we use the\n# convenient \"% at start of line\" tag, and we quote the template literally with\n# <tt>%q{...}</tt> to avoid trouble with the backslash.\n#\n#   require \"erb\"\n#   \n#   # Create template.\n#   template = %q{\n#     From:  James Edward Gray II <james@grayproductions.net>\n#     To:  <%= to %>\n#     Subject:  Addressing Needs\n#   \n#     <%= to[/\\w+/] %>:\n#   \n#     Just wanted to send a quick note assuring that your needs are being\n#     addressed.\n#   \n#     I want you to know that my team will keep working on the issues,\n#     especially:\n#   \n#     <%# ignore numerous minor requests -- focus on priorities %>\n#     % priorities.each do |priority|\n#       * <%= priority %>\n#     % end\n#   \n#     Thanks for your patience.\n#   \n#     James Edward Gray II\n#   }.gsub(/^  /, '')\n#   \n#   message = ERB.new(template, 0, \"%<>\")\n#   \n#   # Set up template data.\n#   to = \"Community Spokesman <spokesman@ruby_community.org>\"\n#   priorities = [ \"Run Ruby Quiz\",\n#                  \"Document Modules\",\n#                  \"Answer Questions on Ruby Talk\" ]\n#   \n#   # Produce result.\n#   email = message.result\n#   puts email\n#\n# <i>Generates:</i>\n#\n#   From:  James Edward Gray II <james@grayproductions.net>\n#   To:  Community Spokesman <spokesman@ruby_community.org>\n#   Subject:  Addressing Needs\n#   \n#   Community:\n#   \n#   Just wanted to send a quick note assuring that your needs are being addressed.\n#   \n#   I want you to know that my team will keep working on the issues, especially:\n#   \n#       * Run Ruby Quiz\n#       * Document Modules\n#       * Answer Questions on Ruby Talk\n#   \n#   Thanks for your patience.\n#   \n#   James Edward Gray II\n#\n# === Ruby in HTML\n#\n# ERB is often used in <tt>.rhtml</tt> files (HTML with embedded Ruby).  Notice the need in\n# this example to provide a special binding when the template is run, so that the instance\n# variables in the Product object can be resolved.\n#\n#   require \"erb\"\n#   \n#   # Build template data class.\n#   class Product\n#     def initialize( code, name, desc, cost )\n#       @code = code\n#       @name = name\n#       @desc = desc\n#       @cost = cost\n#        \t\n#       @features = [ ]\n#     end\n#   \n#     def add_feature( feature )\n#       @features << feature\n#     end\n#   \n#     # Support templating of member data.\n#     def get_binding\n#       binding\n#     end\n#   \n#     # ...\n#   end\n#   \n#   # Create template.\n#   template = %{\n#     <html>\n#       <head><title>Ruby Toys -- <%= @name %></title></head>\n#       <body>\n#   \n#         <h1><%= @name %> (<%= @code %>)</h1>\n#         <p><%= @desc %></p>\n#   \n#         <ul>\n#           <% @features.each do |f| %>\n#             <li><b><%= f %></b></li>\n#           <% end %>\n#         </ul>\n#   \n#         <p>\n#           <% if @cost < 10 %>\n#             <b>Only <%= @cost %>!!!</b>\n#           <% else %>\n#              Call for a price, today!\n#           <% end %>\n#         </p>\n#    \n#       </body>\n#     </html>\n#   }.gsub(/^  /, '')\n#   \n#   rhtml = ERB.new(template)\n#   \n#   # Set up template data.\n#   toy = Product.new( \"TZ-1002\",\n#                      \"Rubysapien\",\n#                      \"Geek's Best Friend!  Responds to Ruby commands...\",\n#                      999.95 )\n#   toy.add_feature(\"Listens for verbal commands in the Ruby language!\")\n#   toy.add_feature(\"Ignores Perl, Java, and all C variants.\")\n#   toy.add_feature(\"Karate-Chop Action!!!\")\n#   toy.add_feature(\"Matz signature on left leg.\")\n#   toy.add_feature(\"Gem studded eyes... Rubies, of course!\")\n#   \n#   # Produce result.\n#   rhtml.run(toy.get_binding)\n#\n# <i>Generates (some blank lines removed):</i>\n#\n#    <html>\n#      <head><title>Ruby Toys -- Rubysapien</title></head>\n#      <body>\n#    \n#        <h1>Rubysapien (TZ-1002)</h1>\n#        <p>Geek's Best Friend!  Responds to Ruby commands...</p>\n#    \n#        <ul>\n#            <li><b>Listens for verbal commands in the Ruby language!</b></li>\n#            <li><b>Ignores Perl, Java, and all C variants.</b></li>\n#            <li><b>Karate-Chop Action!!!</b></li>\n#            <li><b>Matz signature on left leg.</b></li>\n#            <li><b>Gem studded eyes... Rubies, of course!</b></li>\n#        </ul>\n#    \n#        <p>\n#             Call for a price, today!\n#        </p>\n#    \n#      </body>\n#    </html>\n#\n# \n# == Notes\n#\n# There are a variety of templating solutions available in various Ruby projects:\n# * ERB's big brother, eRuby, works the same but is written in C for speed;\n# * Amrita (smart at producing HTML/XML);\n# * cs/Template (written in C for speed);\n# * RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere;\n# * and others; search the RAA.\n#\n# Rails, the web application framework, uses ERB to create views.\n#\nclass ERB\n  Revision = '$Date$' \t#'\n\n  # Returns revision information for the erb.rb module.\n  def self.version\n    \"erb.rb [2.1.0 #{ERB::Revision.split[1]}]\"\n  end\nend\n\n#--\n# ERB::Compiler\nclass ERB\n  class Compiler # :nodoc:\n    class PercentLine # :nodoc:\n      def initialize(str)\n        @value = str\n      end\n      attr_reader :value\n      alias :to_s :value\n\n      def empty?\n        @value.empty?\n      end\n    end\n\n    class Scanner # :nodoc:\n      @scanner_map = {}\n      def self.regist_scanner(klass, trim_mode, percent)\n\t@scanner_map[[trim_mode, percent]] = klass\n      end\n\n      def self.default_scanner=(klass)\n\t@default_scanner = klass\n      end\n\n      def self.make_scanner(src, trim_mode, percent)\n\tklass = @scanner_map.fetch([trim_mode, percent], @default_scanner)\n\tklass.new(src, trim_mode, percent)\n      end\n\n      def initialize(src, trim_mode, percent)\n\t@src = src\n\t@stag = nil\n      end\n      attr_accessor :stag\n\n      def scan; end\n    end\n\n    class TrimScanner < Scanner # :nodoc:\n      def initialize(src, trim_mode, percent)\n\tsuper\n\t@trim_mode = trim_mode\n\t@percent = percent\n\tif @trim_mode == '>'\n\t  @scan_line = self.method(:trim_line1)\n\telsif @trim_mode == '<>'\n\t  @scan_line = self.method(:trim_line2)\n\telsif @trim_mode == '-'\n\t  @scan_line = self.method(:explicit_trim_line)\n\telse\n\t  @scan_line = self.method(:scan_line)\n\tend\n      end\n      attr_accessor :stag\n      \n      def scan(&block)\n\t@stag = nil\n\tif @percent\n\t  @src.each do |line|\n\t    percent_line(line, &block)\n\t  end\n\telse\n          @scan_line.call(@src, &block)\n\tend\n\tnil\n      end\n\n      def percent_line(line, &block)\n\tif @stag || line[0] != ?%\n\t  return @scan_line.call(line, &block)\n\tend\n\n\tline[0] = ''\n\tif line[0] == ?%\n\t  @scan_line.call(line, &block)\n\telse\n          yield(PercentLine.new(line.chomp))\n\tend\n      end\n\n      def scan_line(line)\n        line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\\n|\\z)/m) do |tokens|\n          tokens.each do |token|\n            next if token.empty?\n            yield(token)\n          end\n\tend\n      end\n\n      def trim_line1(line)\n        line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\\n|%>|\\n|\\z)/m) do |tokens|\n          tokens.each do |token|\n            next if token.empty?\n            if token == \"%>\\n\"\n              yield('%>')\n              yield(:cr)\n            else\n              yield(token)\n            end\n          end\n\tend\n      end\n\n      def trim_line2(line)\n\thead = nil\n        line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\\n|%>|\\n|\\z)/m) do |tokens|\n          tokens.each do |token|\n            next if token.empty?\n            head = token unless head\n            if token == \"%>\\n\"\n              yield('%>')\n              if is_erb_stag?(head)\n                yield(:cr)\n              else\n                yield(\"\\n\")\n              end\n              head = nil\n            else\n              yield(token)\n              head = nil if token == \"\\n\"\n            end\n          end\n\tend\n      end\n\n      def explicit_trim_line(line)\n        line.scan(/(.*?)(^[ \\t]*<%\\-|<%\\-|<%%|%%>|<%=|<%#|<%|-%>\\n|-%>|%>|\\z)/m) do |tokens|\n          tokens.each do |token|\n            next if token.empty?\n            if @stag.nil? && /[ \\t]*<%-/ =~ token\n              yield('<%')\n            elsif @stag && token == \"-%>\\n\"\n              yield('%>')\n              yield(:cr)\n            elsif @stag && token == '-%>'\n              yield('%>')\n            else\n              yield(token)\n            end\n          end\n        end\n      end\n\n      ERB_STAG = %w(<%= <%# <%)\n      def is_erb_stag?(s)\n\tERB_STAG.member?(s)\n      end\n    end\n\n    Scanner.default_scanner = TrimScanner\n\n    class SimpleScanner < Scanner # :nodoc:\n      def scan\n        @src.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\\n|\\z)/m) do |tokens|\n          tokens.each do |token|\n            next if token.empty?\n            yield(token)\n          end\n\tend\n      end\n    end\n    \n    Scanner.regist_scanner(SimpleScanner, nil, false)\n\n    begin\n      require 'strscan'\n      class SimpleScanner2 < Scanner # :nodoc:\n        def scan\n          stag_reg = /(.*?)(<%%|<%=|<%#|<%|\\z)/m\n          etag_reg = /(.*?)(%%>|%>|\\z)/m\n          scanner = StringScanner.new(@src)\n          while ! scanner.eos?\n            scanner.scan(@stag ? etag_reg : stag_reg)\n            yield(scanner[1])\n            yield(scanner[2])\n          end\n        end\n      end\n      Scanner.regist_scanner(SimpleScanner2, nil, false)\n\n      class ExplicitScanner < Scanner # :nodoc:\n\tdef scan\n          stag_reg = /(.*?)(^[ \\t]*<%-|<%%|<%=|<%#|<%-|<%|\\z)/m\n          etag_reg = /(.*?)(%%>|-%>|%>|\\z)/m\n          scanner = StringScanner.new(@src)\n          while ! scanner.eos?\n\t    scanner.scan(@stag ? etag_reg : stag_reg)\n            yield(scanner[1])\n\n            elem = scanner[2]\n            if /[ \\t]*<%-/ =~ elem\n              yield('<%')\n            elsif elem == '-%>'\n\t      yield('%>')\n\t      yield(:cr) if scanner.scan(/(\\n|\\z)/)\n\t    else\n\t      yield(elem)\n\t    end\n          end\n        end\n      end\n      Scanner.regist_scanner(ExplicitScanner, '-', false)\n\n    rescue LoadError\n    end\n\n    class Buffer # :nodoc:\n      def initialize(compiler)\n\t@compiler = compiler\n\t@line = []\n\t@script = \"\"\n\t@compiler.pre_cmd.each do |x|\n\t  push(x)\n\tend\n      end\n      attr_reader :script\n\n      def push(cmd)\n\t@line << cmd\n      end\n      \n      def cr\n\t@script << (@line.join('; '))\n\t@line = []\n\t@script << \"\\n\"\n      end\n      \n      def close\n\treturn unless @line\n\t@compiler.post_cmd.each do |x|\n\t  push(x)\n\tend\n\t@script << (@line.join('; '))\n\t@line = nil\n      end\n    end\n\n    def content_dump(s)\n      n = s.count(\"\\n\")\n      if n > 0\n        s.dump + \"\\n\" * n\n      else\n        s.dump\n      end\n    end\n\n    def compile(s)\n      out = Buffer.new(self)\n\n      content = ''\n      scanner = make_scanner(s)\n      scanner.scan do |token|\n        next if token.nil? \n        next if token == ''\n\tif scanner.stag.nil?\n\t  case token\n          when PercentLine\n\t    out.push(\"#{@put_cmd} #{content_dump(content)}\") if content.size > 0\n\t    content = ''\n            out.push(token.to_s)\n            out.cr\n\t  when :cr\n\t    out.cr\n\t  when '<%', '<%=', '<%#'\n\t    scanner.stag = token\n\t    out.push(\"#{@put_cmd} #{content_dump(content)}\") if content.size > 0\n\t    content = ''\n\t  when \"\\n\"\n\t    content << \"\\n\"\n\t    out.push(\"#{@put_cmd} #{content_dump(content)}\")\n\t    content = ''\n\t  when '<%%'\n\t    content << '<%'\n\t  else\n\t    content << token\n\t  end\n\telse\n\t  case token\n\t  when '%>'\n\t    case scanner.stag\n\t    when '<%'\n\t      if content[-1] == ?\\n\n\t\tcontent.chop!\n\t\tout.push(content)\n\t\tout.cr\n\t      else\n\t\tout.push(content)\n\t      end\n\t    when '<%='\n\t      out.push(\"#{@insert_cmd}((#{content}).to_s)\")\n\t    when '<%#'\n\t      # out.push(\"# #{content_dump(content)}\")\n\t    end\n\t    scanner.stag = nil\n\t    content = ''\n\t  when '%%>'\n\t    content << '%>'\n\t  else\n\t    content << token\n\t  end\n\tend\n      end\n      out.push(\"#{@put_cmd} #{content_dump(content)}\") if content.size > 0\n      out.close\n      out.script\n    end\n\n    def prepare_trim_mode(mode)\n      case mode\n      when 1\n\treturn [false, '>']\n      when 2\n\treturn [false, '<>']\n      when 0\n\treturn [false, nil]\n      when String\n\tperc = mode.include?('%')\n\tif mode.include?('-')\n\t  return [perc, '-']\n\telsif mode.include?('<>')\n\t  return [perc, '<>']\n\telsif mode.include?('>')\n\t  return [perc, '>']\n\telse\n\t  [perc, nil]\n\tend\n      else\n\treturn [false, nil]\n      end\n    end\n\n    def make_scanner(src)\n      Scanner.make_scanner(src, @trim_mode, @percent)\n    end\n\n    def initialize(trim_mode)\n      @percent, @trim_mode = prepare_trim_mode(trim_mode)\n      @put_cmd = 'print'\n      @insert_cmd = @put_cmd\n      @pre_cmd = []\n      @post_cmd = []\n    end\n    attr_reader :percent, :trim_mode\n    attr_accessor :put_cmd, :insert_cmd, :pre_cmd, :post_cmd\n  end\nend\n\n#--\n# ERB\nclass ERB\n  #\n  # Constructs a new ERB object with the template specified in _str_.\n  # \n  # An ERB object works by building a chunk of Ruby code that will output\n  # the completed template when run. If _safe_level_ is set to a non-nil value,\n  # ERB code will be run in a separate thread with <b>$SAFE</b> set to the\n  # provided level.\n  # \n  # If _trim_mode_ is passed a String containing one or more of the following\n  # modifiers, ERB will adjust its code generation as listed:\n  # \n  # \t%  enables Ruby code processing for lines beginning with %\n  # \t<> omit newline for lines starting with <% and ending in %>\n  # \t>  omit newline for lines ending in %>\n  # \n  # _eoutvar_ can be used to set the name of the variable ERB will build up\n  # its output in.  This is useful when you need to run multiple ERB\n  # templates through the same binding and/or when you want to control where\n  # output ends up.  Pass the name of the variable to be used inside a String.\n  #\n  # === Example\n  #\n  #  require \"erb\"\n  #  \n  #  # build data class\n  #  class Listings\n  #    PRODUCT = { :name => \"Chicken Fried Steak\",\n  #                :desc => \"A well messages pattie, breaded and fried.\",\n  #                :cost => 9.95 }\n  #  \n  #    attr_reader :product, :price\n  #    \n  #    def initialize( product = \"\", price = \"\" )\n  #      @product = product\n  #      @price = price\n  #    end\n  #    \n  #    def build\n  #      b = binding\n  #      # create and run templates, filling member data variables\n  #      ERB.new(<<-'END_PRODUCT'.gsub(/^\\s+/, \"\"), 0, \"\", \"@product\").result b\n  #        <%= PRODUCT[:name] %>\n  #        <%= PRODUCT[:desc] %>\n  #      END_PRODUCT\n  #      ERB.new(<<-'END_PRICE'.gsub(/^\\s+/, \"\"), 0, \"\", \"@price\").result b\n  #        <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>\n  #        <%= PRODUCT[:desc] %>\n  #      END_PRICE\n  #    end\n  #  end\n  #  \n  #  # setup template data\n  #  listings = Listings.new\n  #  listings.build\n  #  \n  #  puts listings.product + \"\\n\" + listings.price\n  #\n  # _Generates_\n  #\n  #  Chicken Fried Steak\n  #  A well messages pattie, breaded and fried.\n  #  \n  #  Chicken Fried Steak -- 9.95\n  #  A well messages pattie, breaded and fried.\n  #  \n  def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')\n    @safe_level = safe_level\n    compiler = ERB::Compiler.new(trim_mode)\n    set_eoutvar(compiler, eoutvar)\n    @src = compiler.compile(str)\n    @filename = nil\n  end\n\n  # The Ruby code generated by ERB\n  attr_reader :src\n\n  # The optional _filename_ argument passed to Kernel#eval when the ERB code\n  # is run\n  attr_accessor :filename\n\n  #\n  # Can be used to set _eoutvar_ as described in ERB#new.  It's probably easier\n  # to just use the constructor though, since calling this method requires the\n  # setup of an ERB _compiler_ object.\n  #\n  def set_eoutvar(compiler, eoutvar = '_erbout')\n    compiler.put_cmd = \"#{eoutvar}.concat\"\n    compiler.insert_cmd = \"#{eoutvar}.concat\"\n\n    cmd = []\n    cmd.push \"#{eoutvar} = ''\"\n    \n    compiler.pre_cmd = cmd\n\n    cmd = []\n    cmd.push(eoutvar)\n\n    compiler.post_cmd = cmd\n  end\n\n  # Generate results and print them. (see ERB#result)\n  def run(b=TOPLEVEL_BINDING)\n    print self.result(b)\n  end\n\n  #\n  # Executes the generated ERB code to produce a completed template, returning\n  # the results of that code.  (See ERB#new for details on how this process can\n  # be affected by _safe_level_.)\n  # \n  # _b_ accepts a Binding or Proc object which is used to set the context of\n  # code evaluation.\n  #\n  def result(b=TOPLEVEL_BINDING)\n    if @safe_level\n      proc { \n\t$SAFE = @safe_level\n\teval(@src, b, (@filename || '(erb)'), 1)\n      }.call\n    else\n      eval(@src, b, (@filename || '(erb)'), 1)\n    end\n  end\n\n  # Define _methodname_ as instance method of _mod_ from compiled ruby source.\n  #\n  # example:\n  #   filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml\n  #   erb = ERB.new(File.read(filename))\n  #   erb.def_method(MyClass, 'render(arg1, arg2)', filename)\n  #   print MyClass.new.render('foo', 123)\n  def def_method(mod, methodname, fname='(ERB)')\n    mod.module_eval(\"def #{methodname}\\n\" + self.src + \"\\nend\\n\", fname, 0)\n  end\n\n  # Create unnamed module, define _methodname_ as instance method of it, and return it.\n  #\n  # example:\n  #   filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml\n  #   erb = ERB.new(File.read(filename))\n  #   erb.filename = filename\n  #   MyModule = erb.def_module('render(arg1, arg2)')\n  #   class MyClass\n  #     include MyModule\n  #   end\n  def def_module(methodname='erb')\n    mod = Module.new\n    def_method(mod, methodname, @filename || '(ERB)')\n    mod\n  end\n\n  # Define unnamed class which has _methodname_ as instance method, and return it.\n  #\n  # example:\n  #   class MyClass_\n  #     def initialize(arg1, arg2)\n  #       @arg1 = arg1;  @arg2 = arg2\n  #     end\n  #   end\n  #   filename = 'example.rhtml'  # @arg1 and @arg2 are used in example.rhtml\n  #   erb = ERB.new(File.read(filename))\n  #   erb.filename = filename\n  #   MyClass = erb.def_class(MyClass_, 'render()')\n  #   print MyClass.new('foo', 123).render()\n  def def_class(superklass=Object, methodname='result')\n    cls = Class.new(superklass)\n    def_method(cls, methodname, @filename || '(ERB)')\n    cls\n  end\nend\n\n#--\n# ERB::Util\nclass ERB\n  # A utility module for conversion routines, often handy in HTML generation.\n  module Util\n    public\n    #\n    # A utility method for escaping HTML tag characters in _s_.\n    # \n    # \trequire \"erb\"\n    # \tinclude ERB::Util\n    # \t\n    # \tputs html_escape(\"is a > 0 & a < 10?\")\n    # \n    # _Generates_\n    # \n    # \tis a &gt; 0 &amp; a &lt; 10?\n    #\n    def html_escape(s)\n      s.to_s.gsub(/&/, \"&amp;\").gsub(/\\\"/, \"&quot;\").gsub(/>/, \"&gt;\").gsub(/</, \"&lt;\")\n    end\n    alias h html_escape\n    module_function :h\n    module_function :html_escape\n    \n    #\n    # A utility method for encoding the String _s_ as a URL.\n    # \n    # \trequire \"erb\"\n    # \tinclude ERB::Util\n    # \t\n    # \tputs url_encode(\"Programming Ruby:  The Pragmatic Programmer's Guide\")\n    # \n    # _Generates_\n    # \n    # \tProgramming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide\n    #\n    def url_encode(s)\n      s.to_s.gsub(/[^a-zA-Z0-9_\\-.]/n){ sprintf(\"%%%02X\", $&.unpack(\"C\")[0]) }\n    end\n    alias u url_encode\n    module_function :u\n    module_function :url_encode\n  end\nend\n\n#--\n# ERB::DefMethod\nclass ERB\n  # Utility module to define eRuby script as instance method.\n  #\n  # === Example\n  #\n  # example.rhtml:\n  #   <% for item in @items %>\n  #   <b><%= item %></b>\n  #   <% end %>\n  #\n  # example.rb:\n  #   require 'erb'\n  #   class MyClass\n  #     extend ERB::DefMethod\n  #     def_erb_method('render()', 'example.rhtml')\n  #     def initialize(items)\n  #       @items = items\n  #     end\n  #   end\n  #   print MyClass.new([10,20,30]).render()\n  #\n  # result:\n  #\n  #   <b>10</b>\n  #\n  #   <b>20</b>\n  #\n  #   <b>30</b>\n  #\n  module DefMethod\n    public\n  # define _methodname_ as instance method of current module, using ERB object or eRuby file\n    def def_erb_method(methodname, erb_or_fname)\n      if erb_or_fname.kind_of? String\n        fname = erb_or_fname\n        erb = ERB.new(File.read(fname))\n        erb.def_method(self, methodname, fname)\n      else\n        erb = erb_or_fname\n        erb.def_method(self, methodname, erb.filename || '(ERB)')\n      end\n    end\n    module_function :def_erb_method\n  end\nend\n"
  },
  {
    "path": "lib/eregex.rb",
    "content": "# this is just a proof of concept toy.\n\nclass RegOr\n  def initialize(re1, re2)\n    @re1 = re1\n    @re2 = re2\n  end\n\n  def =~ (str)\n    @re1 =~ str or @re2 =~ str\n  end\nend\n\nclass RegAnd\n  def initialize(re1, re2)\n    @re1 = re1\n    @re2 = re2\n  end\n\n  def =~ (str)\n    @re1 =~ str and @re2 =~ str\n  end\nend\n\nclass Regexp\n  def |(other)\n    RegOr.new(self, other)\n  end\n  def &(other)\n    RegAnd.new(self, other)\n  end\nend\n\nif __FILE__ == $0\n  p \"abc\" =~ /b/|/c/\n  p \"abc\" =~ /b/&/c/\nend\n"
  },
  {
    "path": "lib/fileutils.rb",
    "content": "# \n# = fileutils.rb\n# \n# Copyright (c) 2000-2006 Minero Aoki\n# \n# This program is free software.\n# You can distribute/modify this program under the same terms of ruby.\n# \n# == module FileUtils\n# \n# Namespace for several file utility methods for copying, moving, removing, etc.\n# \n# === Module Functions\n# \n#   cd(dir, options)\n#   cd(dir, options) {|dir| .... }\n#   pwd()\n#   mkdir(dir, options)\n#   mkdir(list, options)\n#   mkdir_p(dir, options)\n#   mkdir_p(list, options)\n#   rmdir(dir, options)\n#   rmdir(list, options)\n#   ln(old, new, options)\n#   ln(list, destdir, options)\n#   ln_s(old, new, options)\n#   ln_s(list, destdir, options)\n#   ln_sf(src, dest, options)\n#   cp(src, dest, options)\n#   cp(list, dir, options)\n#   cp_r(src, dest, options)\n#   cp_r(list, dir, options)\n#   mv(src, dest, options)\n#   mv(list, dir, options)\n#   rm(list, options)\n#   rm_r(list, options)\n#   rm_rf(list, options)\n#   install(src, dest, mode = <src's>, options)\n#   chmod(mode, list, options)\n#   chmod_R(mode, list, options)\n#   chown(user, group, list, options)\n#   chown_R(user, group, list, options)\n#   touch(list, options)\n#\n# The <tt>options</tt> parameter is a hash of options, taken from the list\n# <tt>:force</tt>, <tt>:noop</tt>, <tt>:preserve</tt>, and <tt>:verbose</tt>.\n# <tt>:noop</tt> means that no changes are made.  The other two are obvious.\n# Each method documents the options that it honours.\n#\n# All methods that have the concept of a \"source\" file or directory can take\n# either one file or a list of files in that argument.  See the method\n# documentation for examples.\n#\n# There are some `low level' methods, which do not accept any option:\n#\n#   copy_entry(src, dest, preserve = false, dereference = false)\n#   copy_file(src, dest, preserve = false, dereference = true)\n#   copy_stream(srcstream, deststream)\n#   remove_entry(path, force = false)\n#   remove_entry_secure(path, force = false)\n#   remove_file(path, force = false)\n#   compare_file(path_a, path_b)\n#   compare_stream(stream_a, stream_b)\n#   uptodate?(file, cmp_list)\n#\n# == module FileUtils::Verbose\n# \n# This module has all methods of FileUtils module, but it outputs messages\n# before acting.  This equates to passing the <tt>:verbose</tt> flag to methods\n# in FileUtils.\n# \n# == module FileUtils::NoWrite\n# \n# This module has all methods of FileUtils module, but never changes\n# files/directories.  This equates to passing the <tt>:noop</tt> flag to methods\n# in FileUtils.\n# \n# == module FileUtils::DryRun\n# \n# This module has all methods of FileUtils module, but never changes\n# files/directories.  This equates to passing the <tt>:noop</tt> and\n# <tt>:verbose</tt> flags to methods in FileUtils.\n# \n\nmodule FileUtils\n\n  def self.private_module_function(name)   #:nodoc:\n    module_function name\n    private_class_method name\n  end\n\n  # This hash table holds command options.\n  OPT_TABLE = {}   #:nodoc: internal use only\n\n  #\n  # Options: (none)\n  #\n  # Returns the name of the current directory.\n  #\n  def pwd\n    Dir.pwd\n  end\n  module_function :pwd\n\n  alias getwd pwd\n  module_function :getwd\n\n  #\n  # Options: verbose\n  # \n  # Changes the current directory to the directory +dir+.\n  # \n  # If this method is called with block, resumes to the old\n  # working directory after the block execution finished.\n  # \n  #   FileUtils.cd('/', :verbose => true)   # chdir and report it\n  # \n  def cd(dir, options = {}, &block) # :yield: dir\n    fu_check_options options, OPT_TABLE['cd']\n    fu_output_message \"cd #{dir}\" if options[:verbose]\n    Dir.chdir(dir, &block)\n    fu_output_message 'cd -' if options[:verbose] and block\n  end\n  module_function :cd\n\n  alias chdir cd\n  module_function :chdir\n\n  OPT_TABLE['cd']    =\n  OPT_TABLE['chdir'] = [:verbose]\n\n  #\n  # Options: (none)\n  # \n  # Returns true if +newer+ is newer than all +old_list+.\n  # Non-existent files are older than any file.\n  # \n  #   FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \\\n  #       system 'make hello.o'\n  # \n  def uptodate?(new, old_list, options = nil)\n    raise ArgumentError, 'uptodate? does not accept any option' if options\n\n    return false unless File.exist?(new)\n    new_time = File.mtime(new)\n    old_list.each do |old|\n      if File.exist?(old)\n        return false unless new_time > File.mtime(old)\n      end\n    end\n    true\n  end\n  module_function :uptodate?\n\n  #\n  # Options: mode noop verbose\n  # \n  # Creates one or more directories.\n  # \n  #   FileUtils.mkdir 'test'\n  #   FileUtils.mkdir %w( tmp data )\n  #   FileUtils.mkdir 'notexist', :noop => true  # Does not really create.\n  #   FileUtils.mkdir 'tmp', :mode => 0700\n  # \n  def mkdir(list, options = {})\n    fu_check_options options, OPT_TABLE['mkdir']\n    list = fu_list(list)\n    fu_output_message \"mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}\" if options[:verbose]\n    return if options[:noop]\n\n    list.each do |dir|\n      fu_mkdir dir, options[:mode]\n    end\n  end\n  module_function :mkdir\n\n  OPT_TABLE['mkdir'] = [:mode, :noop, :verbose]\n\n  #\n  # Options: mode noop verbose\n  # \n  # Creates a directory and all its parent directories.\n  # For example,\n  # \n  #   FileUtils.mkdir_p '/usr/local/lib/ruby'\n  # \n  # causes to make following directories, if it does not exist.\n  #     * /usr\n  #     * /usr/local\n  #     * /usr/local/lib\n  #     * /usr/local/lib/ruby\n  #\n  # You can pass several directories at a time in a list.\n  # \n  def mkdir_p(list, options = {})\n    fu_check_options options, OPT_TABLE['mkdir_p']\n    list = fu_list(list)\n    fu_output_message \"mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}\" if options[:verbose]\n    return *list if options[:noop]\n\n    list.map {|path| path.sub(%r</\\z>, '') }.each do |path|\n      # optimize for the most common case\n      begin\n        fu_mkdir path, options[:mode]\n        next\n      rescue SystemCallError\n        next if File.directory?(path)\n      end\n\n      stack = []\n      until path == stack.last   # dirname(\"/\")==\"/\", dirname(\"C:/\")==\"C:/\"\n        stack.push path\n        path = File.dirname(path)\n      end\n      stack.reverse_each do |path|\n        begin\n          fu_mkdir path, options[:mode]\n        rescue SystemCallError => err\n          raise unless File.directory?(path)\n        end\n      end\n    end\n\n    return *list\n  end\n  module_function :mkdir_p\n\n  alias mkpath    mkdir_p\n  alias makedirs  mkdir_p\n  module_function :mkpath\n  module_function :makedirs\n\n  OPT_TABLE['mkdir_p']  =\n  OPT_TABLE['mkpath']   =\n  OPT_TABLE['makedirs'] = [:mode, :noop, :verbose]\n\n  def fu_mkdir(path, mode)   #:nodoc:\n    path = path.sub(%r</\\z>, '')\n    if mode\n      Dir.mkdir path, mode\n      File.chmod mode, path\n    else\n      Dir.mkdir path\n    end\n  end\n  private_module_function :fu_mkdir\n\n  #\n  # Options: noop, verbose\n  # \n  # Removes one or more directories.\n  # \n  #   FileUtils.rmdir 'somedir'\n  #   FileUtils.rmdir %w(somedir anydir otherdir)\n  #   # Does not really remove directory; outputs message.\n  #   FileUtils.rmdir 'somedir', :verbose => true, :noop => true\n  # \n  def rmdir(list, options = {})\n    fu_check_options options, OPT_TABLE['rmdir']\n    list = fu_list(list)\n    fu_output_message \"rmdir #{list.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    list.each do |dir|\n      Dir.rmdir dir.sub(%r</\\z>, '')\n    end\n  end\n  module_function :rmdir\n\n  OPT_TABLE['rmdir'] = [:noop, :verbose]\n\n  #\n  # Options: force noop verbose\n  #\n  # <b><tt>ln(old, new, options = {})</tt></b>\n  #\n  # Creates a hard link +new+ which points to +old+.\n  # If +new+ already exists and it is a directory, creates a link +new/old+.\n  # If +new+ already exists and it is not a directory, raises Errno::EEXIST.\n  # But if :force option is set, overwrite +new+.\n  # \n  #   FileUtils.ln 'gcc', 'cc', :verbose => true\n  #   FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'\n  # \n  # <b><tt>ln(list, destdir, options = {})</tt></b>\n  # \n  # Creates several hard links in a directory, with each one pointing to the\n  # item in +list+.  If +destdir+ is not a directory, raises Errno::ENOTDIR.\n  # \n  #   include FileUtils\n  #   cd '/sbin'\n  #   FileUtils.ln %w(cp mv mkdir), '/bin'   # Now /sbin/cp and /bin/cp are linked.\n  # \n  def ln(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['ln']\n    fu_output_message \"ln#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    fu_each_src_dest0(src, dest) do |s,d|\n      remove_file d, true if options[:force]\n      File.link s, d\n    end\n  end\n  module_function :ln\n\n  alias link ln\n  module_function :link\n\n  OPT_TABLE['ln']   =\n  OPT_TABLE['link'] = [:force, :noop, :verbose]\n\n  #\n  # Options: force noop verbose\n  #\n  # <b><tt>ln_s(old, new, options = {})</tt></b>\n  # \n  # Creates a symbolic link +new+ which points to +old+.  If +new+ already\n  # exists and it is a directory, creates a symbolic link +new/old+.  If +new+\n  # already exists and it is not a directory, raises Errno::EEXIST.  But if\n  # :force option is set, overwrite +new+.\n  # \n  #   FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'\n  #   FileUtils.ln_s 'verylongsourcefilename.c', 'c', :force => true\n  # \n  # <b><tt>ln_s(list, destdir, options = {})</tt></b>\n  # \n  # Creates several symbolic links in a directory, with each one pointing to the\n  # item in +list+.  If +destdir+ is not a directory, raises Errno::ENOTDIR.\n  #\n  # If +destdir+ is not a directory, raises Errno::ENOTDIR.\n  # \n  #   FileUtils.ln_s Dir.glob('bin/*.rb'), '/home/aamine/bin'\n  # \n  def ln_s(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['ln_s']\n    fu_output_message \"ln -s#{options[:force] ? 'f' : ''} #{[src,dest].flatten.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    fu_each_src_dest0(src, dest) do |s,d|\n      remove_file d, true if options[:force]\n      File.symlink s, d\n    end\n  end\n  module_function :ln_s\n\n  alias symlink ln_s\n  module_function :symlink\n\n  OPT_TABLE['ln_s']    =\n  OPT_TABLE['symlink'] = [:force, :noop, :verbose]\n\n  #\n  # Options: noop verbose\n  # \n  # Same as\n  #   #ln_s(src, dest, :force)\n  # \n  def ln_sf(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['ln_sf']\n    options = options.dup\n    options[:force] = true\n    ln_s src, dest, options\n  end\n  module_function :ln_sf\n\n  OPT_TABLE['ln_sf'] = [:noop, :verbose]\n\n  #\n  # Options: preserve noop verbose\n  #\n  # Copies a file content +src+ to +dest+.  If +dest+ is a directory,\n  # copies +src+ to +dest/src+.\n  #\n  # If +src+ is a list of files, then +dest+ must be a directory.\n  #\n  #   FileUtils.cp 'eval.c', 'eval.c.org'\n  #   FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'\n  #   FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true\n  #   FileUtils.cp 'symlink', 'dest'   # copy content, \"dest\" is not a symlink\n  # \n  def cp(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['cp']\n    fu_output_message \"cp#{options[:preserve] ? ' -p' : ''} #{[src,dest].flatten.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    fu_each_src_dest(src, dest) do |s, d|\n      copy_file s, d, options[:preserve]\n    end\n  end\n  module_function :cp\n\n  alias copy cp\n  module_function :copy\n\n  OPT_TABLE['cp']   =\n  OPT_TABLE['copy'] = [:preserve, :noop, :verbose]\n\n  #\n  # Options: preserve noop verbose dereference_root remove_destination\n  # \n  # Copies +src+ to +dest+. If +src+ is a directory, this method copies\n  # all its contents recursively. If +dest+ is a directory, copies\n  # +src+ to +dest/src+.\n  #\n  # +src+ can be a list of files.\n  # \n  #   # Installing ruby library \"mylib\" under the site_ruby\n  #   FileUtils.rm_r site_ruby + '/mylib', :force\n  #   FileUtils.cp_r 'lib/', site_ruby + '/mylib'\n  # \n  #   # Examples of copying several files to target directory.\n  #   FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'\n  #   FileUtils.cp_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true\n  #\n  #   # If you want to copy all contents of a directory instead of the\n  #   # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,\n  #   # use following code.\n  #   FileUtils.cp_r 'src/.', 'dest'     # cp_r('src', 'dest') makes src/dest,\n  #                                      # but this doesn't.\n  # \n  def cp_r(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['cp_r']\n    fu_output_message \"cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    options[:dereference_root] = true unless options.key?(:dereference_root)\n    fu_each_src_dest(src, dest) do |s, d|\n      copy_entry s, d, options[:preserve], options[:dereference_root], options[:remove_destination]\n    end\n  end\n  module_function :cp_r\n\n  OPT_TABLE['cp_r'] = [:preserve, :noop, :verbose,\n                       :dereference_root, :remove_destination]\n\n  #\n  # Copies a file system entry +src+ to +dest+.\n  # If +src+ is a directory, this method copies its contents recursively.\n  # This method preserves file types, c.f. symlink, directory...\n  # (FIFO, device files and etc. are not supported yet)\n  #\n  # Both of +src+ and +dest+ must be a path name.\n  # +src+ must exist, +dest+ must not exist.\n  #\n  # If +preserve+ is true, this method preserves owner, group, permissions\n  # and modified time.\n  #\n  # If +dereference_root+ is true, this method dereference tree root.\n  #\n  # If +remove_destination+ is true, this method removes each destination file before copy.\n  #\n  def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)\n    Entry_.new(src, nil, dereference_root).traverse do |ent|\n      destent = Entry_.new(dest, ent.rel, false)\n      File.unlink destent.path if remove_destination && File.file?(destent.path)\n      ent.copy destent.path\n      ent.copy_metadata destent.path if preserve\n    end\n  end\n  module_function :copy_entry\n\n  #\n  # Copies file contents of +src+ to +dest+.\n  # Both of +src+ and +dest+ must be a path name.\n  #\n  def copy_file(src, dest, preserve = false, dereference = true)\n    ent = Entry_.new(src, nil, dereference)\n    ent.copy_file dest\n    ent.copy_metadata dest if preserve\n  end\n  module_function :copy_file\n\n  #\n  # Copies stream +src+ to +dest+.\n  # +src+ must respond to #read(n) and\n  # +dest+ must respond to #write(str).\n  #\n  def copy_stream(src, dest)\n    fu_copy_stream0 src, dest, fu_stream_blksize(src, dest)\n  end\n  module_function :copy_stream\n\n  #\n  # Options: force noop verbose\n  # \n  # Moves file(s) +src+ to +dest+.  If +file+ and +dest+ exist on the different\n  # disk partition, the file is copied instead.\n  # \n  #   FileUtils.mv 'badname.rb', 'goodname.rb'\n  #   FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true  # no error\n  # \n  #   FileUtils.mv %w(junk.txt dust.txt), '/home/aamine/.trash/'\n  #   FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true\n  # \n  def mv(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['mv']\n    fu_output_message \"mv#{options[:force] ? ' -f' : ''} #{[src,dest].flatten.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    fu_each_src_dest(src, dest) do |s, d|\n      destent = Entry_.new(d, nil, true)\n      begin\n        if destent.exist?\n          if destent.directory?\n            raise Errno::EEXIST, dest\n          else\n            destent.remove_file if rename_cannot_overwrite_file?\n          end\n        end\n        begin\n          File.rename s, d\n        rescue Errno::EXDEV\n          copy_entry s, d, true\n          if options[:secure]\n            remove_entry_secure s, options[:force]\n          else\n            remove_entry s, options[:force]\n          end\n        end\n      rescue SystemCallError\n        raise unless options[:force]\n      end\n    end\n  end\n  module_function :mv\n\n  alias move mv\n  module_function :move\n\n  OPT_TABLE['mv']   =\n  OPT_TABLE['move'] = [:force, :noop, :verbose, :secure]\n\n  def rename_cannot_overwrite_file?   #:nodoc:\n    /djgpp|cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM\n  end\n  private_module_function :rename_cannot_overwrite_file?\n\n  #\n  # Options: force noop verbose\n  # \n  # Remove file(s) specified in +list+.  This method cannot remove directories.\n  # All StandardErrors are ignored when the :force option is set.\n  # \n  #   FileUtils.rm %w( junk.txt dust.txt )\n  #   FileUtils.rm Dir.glob('*.so')\n  #   FileUtils.rm 'NotExistFile', :force => true   # never raises exception\n  # \n  def rm(list, options = {})\n    fu_check_options options, OPT_TABLE['rm']\n    list = fu_list(list)\n    fu_output_message \"rm#{options[:force] ? ' -f' : ''} #{list.join ' '}\" if options[:verbose]\n    return if options[:noop]\n\n    list.each do |path|\n      remove_file path, options[:force]\n    end\n  end\n  module_function :rm\n\n  alias remove rm\n  module_function :remove\n\n  OPT_TABLE['rm']     =\n  OPT_TABLE['remove'] = [:force, :noop, :verbose]\n\n  #\n  # Options: noop verbose\n  # \n  # Equivalent to\n  #\n  #   #rm(list, :force => true)\n  #\n  def rm_f(list, options = {})\n    fu_check_options options, OPT_TABLE['rm_f']\n    options = options.dup\n    options[:force] = true\n    rm list, options\n  end\n  module_function :rm_f\n\n  alias safe_unlink rm_f\n  module_function :safe_unlink\n\n  OPT_TABLE['rm_f']        =\n  OPT_TABLE['safe_unlink'] = [:noop, :verbose]\n\n  #\n  # Options: force noop verbose secure\n  # \n  # remove files +list+[0] +list+[1]... If +list+[n] is a directory,\n  # removes its all contents recursively. This method ignores\n  # StandardError when :force option is set.\n  # \n  #   FileUtils.rm_r Dir.glob('/tmp/*')\n  #   FileUtils.rm_r '/', :force => true          #  :-)\n  #\n  # WARNING: This method causes local vulnerability\n  # if one of parent directories or removing directory tree are world\n  # writable (including /tmp, whose permission is 1777), and the current\n  # process has strong privilege such as Unix super user (root), and the\n  # system has symbolic link.  For secure removing, read the documentation\n  # of #remove_entry_secure carefully, and set :secure option to true.\n  # Default is :secure=>false.\n  #\n  # NOTE: This method calls #remove_entry_secure if :secure option is set.\n  # See also #remove_entry_secure.\n  # \n  def rm_r(list, options = {})\n    fu_check_options options, OPT_TABLE['rm_r']\n    # options[:secure] = true unless options.key?(:secure)\n    list = fu_list(list)\n    fu_output_message \"rm -r#{options[:force] ? 'f' : ''} #{list.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    list.each do |path|\n      if options[:secure]\n        remove_entry_secure path, options[:force]\n      else\n        remove_entry path, options[:force]\n      end\n    end\n  end\n  module_function :rm_r\n\n  OPT_TABLE['rm_r'] = [:force, :noop, :verbose, :secure]\n\n  #\n  # Options: noop verbose secure\n  # \n  # Equivalent to\n  #\n  #   #rm_r(list, :force => true)\n  #\n  # WARNING: This method causes local vulnerability.\n  # Read the documentation of #rm_r first.\n  # \n  def rm_rf(list, options = {})\n    fu_check_options options, OPT_TABLE['rm_rf']\n    options = options.dup\n    options[:force] = true\n    rm_r list, options\n  end\n  module_function :rm_rf\n\n  alias rmtree rm_rf\n  module_function :rmtree\n\n  OPT_TABLE['rm_rf']  =\n  OPT_TABLE['rmtree'] = [:noop, :verbose, :secure]\n\n  #\n  # This method removes a file system entry +path+.  +path+ shall be a\n  # regular file, a directory, or something.  If +path+ is a directory,\n  # remove it recursively.  This method is required to avoid TOCTTOU\n  # (time-of-check-to-time-of-use) local security vulnerability of #rm_r.\n  # #rm_r causes security hole when:\n  #\n  #   * Parent directory is world writable (including /tmp).\n  #   * Removing directory tree includes world writable directory.\n  #   * The system has symbolic link.\n  #\n  # To avoid this security hole, this method applies special preprocess.\n  # If +path+ is a directory, this method chown(2) and chmod(2) all\n  # removing directories.  This requires the current process is the\n  # owner of the removing whole directory tree, or is the super user (root).\n  #\n  # WARNING: You must ensure that *ALL* parent directories are not\n  # world writable.  Otherwise this method does not work.\n  # Only exception is temporary directory like /tmp and /var/tmp,\n  # whose permission is 1777.\n  #\n  # WARNING: Only the owner of the removing directory tree, or Unix super\n  # user (root) should invoke this method.  Otherwise this method does not\n  # work.\n  #\n  # For details of this security vulnerability, see Perl's case:\n  #\n  #   http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448\n  #   http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452\n  #\n  # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].\n  #\n  def remove_entry_secure(path, force = false)\n    unless fu_have_symlink?\n      remove_entry path, force\n      return\n    end\n    fullpath = File.expand_path(path)\n    st = File.lstat(fullpath)\n    unless st.directory?\n      File.unlink fullpath\n      return\n    end\n    # is a directory.\n    parent_st = File.stat(File.dirname(fullpath))\n    unless fu_world_writable?(parent_st)\n      remove_entry path, force\n      return\n    end\n    unless parent_st.sticky?\n      raise ArgumentError, \"parent directory is world writable, FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})\"\n    end\n    # freeze tree root\n    euid = Process.euid\n    File.open(fullpath + '/.') {|f|\n      unless fu_stat_identical_entry?(st, f.stat)\n        # symlink (TOC-to-TOU attack?)\n        File.unlink fullpath\n        return\n      end\n      f.chown euid, -1\n      f.chmod 0700\n    }\n    # ---- tree root is frozen ----\n    root = Entry_.new(path)\n    root.preorder_traverse do |ent|\n      if ent.directory?\n        ent.chown euid, -1\n        ent.chmod 0700\n      end\n    end\n    root.postorder_traverse do |ent|\n      begin\n        ent.remove\n      rescue\n        raise unless force\n      end\n    end\n  rescue\n    raise unless force\n  end\n  module_function :remove_entry_secure\n\n  def fu_world_writable?(st)\n    (st.mode & 0002) != 0\n  end\n  private_module_function :fu_world_writable?\n\n  def fu_have_symlink?   #:nodoc\n    File.symlink nil, nil\n  rescue NotImplementedError\n    return false\n  rescue\n    return true\n  end\n  private_module_function :fu_have_symlink?\n\n  def fu_stat_identical_entry?(a, b)   #:nodoc:\n    a.dev == b.dev and a.ino == b.ino\n  end\n  private_module_function :fu_stat_identical_entry?\n\n  #\n  # This method removes a file system entry +path+.\n  # +path+ might be a regular file, a directory, or something.\n  # If +path+ is a directory, remove it recursively.\n  #\n  # See also #remove_entry_secure.\n  #\n  def remove_entry(path, force = false)\n    Entry_.new(path).postorder_traverse do |ent|\n      begin\n        ent.remove\n      rescue\n        raise unless force\n      end\n    end\n  rescue\n    raise unless force\n  end\n  module_function :remove_entry\n\n  #\n  # Removes a file +path+.\n  # This method ignores StandardError if +force+ is true.\n  #\n  def remove_file(path, force = false)\n    Entry_.new(path).remove_file\n  rescue\n    raise unless force\n  end\n  module_function :remove_file\n\n  #\n  # Removes a directory +dir+ and its contents recursively.\n  # This method ignores StandardError if +force+ is true.\n  #\n  def remove_dir(path, force = false)\n    remove_entry path, force   # FIXME?? check if it is a directory\n  end\n  module_function :remove_dir\n\n  #\n  # Returns true if the contents of a file A and a file B are identical.\n  # \n  #   FileUtils.compare_file('somefile', 'somefile')  #=> true\n  #   FileUtils.compare_file('/bin/cp', '/bin/mv')    #=> maybe false\n  #\n  def compare_file(a, b)\n    return false unless File.size(a) == File.size(b)\n    File.open(a, 'rb') {|fa|\n      File.open(b, 'rb') {|fb|\n        return compare_stream(fa, fb)\n      }\n    }\n  end\n  module_function :compare_file\n\n  alias identical? compare_file\n  alias cmp compare_file\n  module_function :identical?\n  module_function :cmp\n\n  #\n  # Returns true if the contents of a stream +a+ and +b+ are identical.\n  #\n  def compare_stream(a, b)\n    bsize = fu_stream_blksize(a, b)\n    sa = sb = nil\n    while sa == sb\n      sa = a.read(bsize)\n      sb = b.read(bsize)\n      unless sa and sb\n        if sa.nil? and sb.nil?\n          return true\n        end\n      end\n    end\n    false\n  end\n  module_function :compare_stream\n\n  #\n  # Options: mode preserve noop verbose\n  # \n  # If +src+ is not same as +dest+, copies it and changes the permission\n  # mode to +mode+.  If +dest+ is a directory, destination is +dest+/+src+.\n  # This method removes destination before copy.\n  # \n  #   FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true\n  #   FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true\n  # \n  def install(src, dest, options = {})\n    fu_check_options options, OPT_TABLE['install']\n    fu_output_message \"install -c#{options[:preserve] && ' -p'}#{options[:mode] ? (' -m 0%o' % options[:mode]) : ''} #{[src,dest].flatten.join ' '}\" if options[:verbose]\n    return if options[:noop]\n    fu_each_src_dest(src, dest) do |s, d|\n      unless File.exist?(d) and compare_file(s, d)\n        remove_file d, true\n        st = File.stat(s) if options[:preserve]\n        copy_file s, d\n        File.utime st.atime, st.mtime, d if options[:preserve]\n        File.chmod options[:mode], d if options[:mode]\n      end\n    end\n  end\n  module_function :install\n\n  OPT_TABLE['install'] = [:mode, :preserve, :noop, :verbose]\n\n  #\n  # Options: noop verbose\n  # \n  # Changes permission bits on the named files (in +list+) to the bit pattern\n  # represented by +mode+.\n  # \n  #   FileUtils.chmod 0755, 'somecommand'\n  #   FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)\n  #   FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true\n  # \n  def chmod(mode, list, options = {})\n    fu_check_options options, OPT_TABLE['chmod']\n    list = fu_list(list)\n    fu_output_message sprintf('chmod %o %s', mode, list.join(' ')) if options[:verbose]\n    return if options[:noop]\n    list.each do |path|\n      Entry_.new(path).chmod mode\n    end\n  end\n  module_function :chmod\n\n  OPT_TABLE['chmod'] = [:noop, :verbose]\n\n  #\n  # Options: noop verbose force\n  # \n  # Changes permission bits on the named files (in +list+)\n  # to the bit pattern represented by +mode+.\n  # \n  #   FileUtils.chmod_R 0700, \"/tmp/app.#{$$}\"\n  # \n  def chmod_R(mode, list, options = {})\n    fu_check_options options, OPT_TABLE['chmod_R']\n    list = fu_list(list)\n    fu_output_message sprintf('chmod -R%s %o %s',\n                              (options[:force] ? 'f' : ''),\n                              mode, list.join(' ')) if options[:verbose]\n    return if options[:noop]\n    list.each do |root|\n      Entry_.new(root).traverse do |ent|\n        begin\n          ent.chmod mode\n        rescue\n          raise unless options[:force]\n        end\n      end\n    end\n  end\n  module_function :chmod_R\n\n  OPT_TABLE['chmod_R'] = [:noop, :verbose, :force]\n\n  #\n  # Options: noop verbose\n  # \n  # Changes owner and group on the named files (in +list+)\n  # to the user +user+ and the group +group+.  +user+ and +group+\n  # may be an ID (Integer/String) or a name (String).\n  # If +user+ or +group+ is nil, this method does not change\n  # the attribute.\n  # \n  #   FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'\n  #   FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true\n  # \n  def chown(user, group, list, options = {})\n    fu_check_options options, OPT_TABLE['chown']\n    list = fu_list(list)\n    fu_output_message sprintf('chown %s%s',\n                              [user,group].compact.join(':') + ' ',\n                              list.join(' ')) if options[:verbose]\n    return if options[:noop]\n    uid = fu_get_uid(user)\n    gid = fu_get_gid(group)\n    list.each do |path|\n      Entry_.new(path).chown uid, gid\n    end\n  end\n  module_function :chown\n\n  OPT_TABLE['chown'] = [:noop, :verbose]\n\n  #\n  # Options: noop verbose force\n  # \n  # Changes owner and group on the named files (in +list+)\n  # to the user +user+ and the group +group+ recursively.\n  # +user+ and +group+ may be an ID (Integer/String) or\n  # a name (String).  If +user+ or +group+ is nil, this\n  # method does not change the attribute.\n  # \n  #   FileUtils.chown_R 'www', 'www', '/var/www/htdocs'\n  #   FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true\n  # \n  def chown_R(user, group, list, options = {})\n    fu_check_options options, OPT_TABLE['chown_R']\n    list = fu_list(list)\n    fu_output_message sprintf('chown -R%s %s%s',\n                              (options[:force] ? 'f' : ''),\n                              [user,group].compact.join(':') + ' ',\n                              list.join(' ')) if options[:verbose]\n    return if options[:noop]\n    uid = fu_get_uid(user)\n    gid = fu_get_gid(group)\n    return unless uid or gid\n    list.each do |root|\n      Entry_.new(root).traverse do |ent|\n        begin\n          ent.chown uid, gid\n        rescue\n          raise unless options[:force]\n        end\n      end\n    end\n  end\n  module_function :chown_R\n\n  OPT_TABLE['chown_R'] = [:noop, :verbose, :force]\n\n  begin\n    require 'etc'\n\n    def fu_get_uid(user)   #:nodoc:\n      return nil unless user\n      user = user.to_s\n      if /\\A\\d+\\z/ =~ user\n      then user.to_i\n      else Etc.getpwnam(user).uid\n      end\n    end\n    private_module_function :fu_get_uid\n\n    def fu_get_gid(group)   #:nodoc:\n      return nil unless group\n      group = group.to_s\n      if /\\A\\d+\\z/ =~ group\n      then group.to_i\n      else Etc.getgrnam(group).gid\n      end\n    end\n    private_module_function :fu_get_gid\n\n  rescue LoadError\n    # need Win32 support???\n\n    def fu_get_uid(user)   #:nodoc:\n      user    # FIXME\n    end\n    private_module_function :fu_get_uid\n\n    def fu_get_gid(group)   #:nodoc:\n      group   # FIXME\n    end\n    private_module_function :fu_get_gid\n  end\n\n  #\n  # Options: noop verbose\n  # \n  # Updates modification time (mtime) and access time (atime) of file(s) in\n  # +list+.  Files are created if they don't exist.\n  # \n  #   FileUtils.touch 'timestamp'\n  #   FileUtils.touch Dir.glob('*.c');  system 'make'\n  # \n  def touch(list, options = {})\n    fu_check_options options, OPT_TABLE['touch']\n    list = fu_list(list)\n    created = nocreate = options[:nocreate]\n    t = options[:mtime]\n    if options[:verbose]\n      fu_output_message \"touch #{nocreate ? ' -c' : ''}#{t ? t.strftime(' -t %Y%m%d%H%M.%S') : ''}#{list.join ' '}\"\n    end\n    return if options[:noop]\n    list.each do |path|\n      created = nocreate\n      begin\n        File.utime(t, t, path)\n      rescue Errno::ENOENT\n        raise if created\n        File.open(path, 'a') {\n          ;\n        }\n        created = true\n        retry if t\n      end\n    end\n  end\n  module_function :touch\n\n  OPT_TABLE['touch'] = [:noop, :verbose, :mtime, :nocreate]\n\n  private\n\n  module StreamUtils_\n    private\n\n    def fu_windows?\n      /mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM\n    end\n\n    def fu_copy_stream0(src, dest, blksize)   #:nodoc:\n      # FIXME: readpartial?\n      while s = src.read(blksize)\n        dest.write s\n      end\n    end\n\n    def fu_stream_blksize(*streams)\n      streams.each do |s|\n        next unless s.respond_to?(:stat)\n        size = fu_blksize(s.stat)\n        return size if size\n      end\n      fu_default_blksize()\n    end\n\n    def fu_blksize(st)\n      s = st.blksize\n      return nil unless s\n      return nil if s == 0\n      s\n    end\n\n    def fu_default_blksize\n      1024\n    end\n  end\n\n  include StreamUtils_\n  extend StreamUtils_\n\n  class Entry_   #:nodoc: internal use only\n    include StreamUtils_\n\n    def initialize(a, b = nil, deref = false)\n      @prefix = @rel = @path = nil\n      if b\n        @prefix = a\n        @rel = b\n      else\n        @path = a\n      end\n      @deref = deref\n      @stat = nil\n      @lstat = nil\n    end\n\n    def inspect\n      \"\\#<#{self.class} #{path()}>\"\n    end\n\n    def path\n      if @path\n        @path.to_str\n      else\n        join(@prefix, @rel)\n      end\n    end\n\n    def prefix\n      @prefix || @path\n    end\n\n    def rel\n      @rel\n    end\n\n    def dereference?\n      @deref\n    end\n\n    def exist?\n      lstat! ? true : false\n    end\n\n    def file?\n      s = lstat!\n      s and s.file?\n    end\n\n    def directory?\n      s = lstat!\n      s and s.directory?\n    end\n\n    def symlink?\n      s = lstat!\n      s and s.symlink?\n    end\n\n    def chardev?\n      s = lstat!\n      s and s.chardev?\n    end\n\n    def blockdev?\n      s = lstat!\n      s and s.blockdev?\n    end\n\n    def socket?\n      s = lstat!\n      s and s.socket?\n    end\n\n    def pipe?\n      s = lstat!\n      s and s.pipe?\n    end\n\n    S_IF_DOOR = 0xD000\n\n    def door?\n      s = lstat!\n      s and (s.mode & 0xF000 == S_IF_DOOR)\n    end\n\n    def entries\n      Dir.entries(path())\\\n          .reject {|n| n == '.' or n == '..' }\\\n          .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }\n    end\n\n    def stat\n      return @stat if @stat\n      if lstat() and lstat().symlink?\n        @stat = File.stat(path())\n      else\n        @stat = lstat()\n      end\n      @stat\n    end\n\n    def stat!\n      return @stat if @stat\n      if lstat! and lstat!.symlink?\n        @stat = File.stat(path())\n      else\n        @stat = lstat!\n      end\n      @stat\n    rescue SystemCallError\n      nil\n    end\n\n    def lstat\n      if dereference?\n        @lstat ||= File.stat(path())\n      else\n        @lstat ||= File.lstat(path())\n      end\n    end\n\n    def lstat!\n      lstat()\n    rescue SystemCallError\n      nil\n    end\n\n    def chmod(mode)\n      if symlink?\n        File.lchmod mode, path() if have_lchmod?\n      else\n        File.chmod mode, path()\n      end\n    end\n\n    def chown(uid, gid)\n      if symlink?\n        File.lchown uid, gid, path() if have_lchown?\n      else\n        File.chown uid, gid, path()\n      end\n    end\n\n    def copy(dest)\n      case\n      when file?\n        copy_file dest\n      when directory?\n        begin\n          Dir.mkdir dest\n        rescue\n          raise unless File.directory?(dest)\n        end\n      when symlink?\n        File.symlink File.readlink(path()), dest\n      when chardev?\n        raise \"cannot handle device file\" unless File.respond_to?(:mknod)\n        mknod dest, ?c, 0666, lstat().rdev\n      when blockdev?\n        raise \"cannot handle device file\" unless File.respond_to?(:mknod)\n        mknod dest, ?b, 0666, lstat().rdev\n      when socket?\n        raise \"cannot handle socket\" unless File.respond_to?(:mknod)\n        mknod dest, nil, lstat().mode, 0\n      when pipe?\n        raise \"cannot handle FIFO\" unless File.respond_to?(:mkfifo)\n        mkfifo dest, 0666\n      when door?\n        raise \"cannot handle door: #{path()}\"\n      else\n        raise \"unknown file type: #{path()}\"\n      end\n    end\n\n    def copy_file(dest)\n      st = stat()\n      File.open(path(),  'rb') {|r|\n        File.open(dest, 'wb', st.mode) {|w|\n          fu_copy_stream0 r, w, (fu_blksize(st) || fu_default_blksize())\n        }\n      }\n    end\n\n    def copy_metadata(path)\n      st = lstat()\n      File.utime st.atime, st.mtime, path\n      begin\n        File.chown st.uid, st.gid, path\n      rescue Errno::EPERM\n        # clear setuid/setgid\n        File.chmod st.mode & 01777, path\n      else\n        File.chmod st.mode, path\n      end\n    end\n\n    def remove\n      if directory?\n        remove_dir1\n      else\n        remove_file\n      end\n    end\n\n    def remove_dir1\n      platform_support {\n        Dir.rmdir path().sub(%r</\\z>, '')\n      }\n    end\n\n    def remove_file\n      platform_support {\n        File.unlink path\n      }\n    end\n\n    def platform_support\n      return yield unless fu_windows?\n      first_time_p = true\n      begin\n        yield\n      rescue Errno::ENOENT\n        raise\n      rescue => err\n        if first_time_p\n          first_time_p = false\n          begin\n            File.chmod 0700, path()   # Windows does not have symlink\n            retry\n          rescue SystemCallError\n          end\n        end\n        raise err\n      end\n    end\n\n    def preorder_traverse\n      stack = [self]\n      while ent = stack.pop\n        yield ent\n        stack.concat ent.entries.reverse if ent.directory?\n      end\n    end\n\n    alias traverse preorder_traverse\n\n    def postorder_traverse\n      if directory?\n        entries().each do |ent|\n          ent.postorder_traverse do |e|\n            yield e\n          end\n        end\n      end\n      yield self\n    end\n\n    private\n\n    $fileutils_rb_have_lchmod = nil\n\n    def have_lchmod?\n      # This is not MT-safe, but it does not matter.\n      if $fileutils_rb_have_lchmod == nil\n        $fileutils_rb_have_lchmod = check_have_lchmod?\n      end\n      $fileutils_rb_have_lchmod\n    end\n\n    def check_have_lchmod?\n      return false unless File.respond_to?(:lchmod)\n      File.lchmod 0\n      return true\n    rescue NotImplementedError\n      return false\n    end\n\n    $fileutils_rb_have_lchown = nil\n\n    def have_lchown?\n      # This is not MT-safe, but it does not matter.\n      if $fileutils_rb_have_lchown == nil\n        $fileutils_rb_have_lchown = check_have_lchown?\n      end\n      $fileutils_rb_have_lchown\n    end\n\n    def check_have_lchown?\n      return false unless File.respond_to?(:lchown)\n      File.lchown nil, nil\n      return true\n    rescue NotImplementedError\n      return false\n    end\n\n    def join(dir, base)\n      return dir.to_str if not base or base == '.'\n      return base.to_str if not dir or dir == '.'\n      File.join(dir, base)\n    end\n  end   # class Entry_\n\n  def fu_list(arg)   #:nodoc:\n    [arg].flatten.map {|path| path.to_str }\n  end\n  private_module_function :fu_list\n\n  def fu_each_src_dest(src, dest)   #:nodoc:\n    fu_each_src_dest0(src, dest) do |s, d|\n      raise ArgumentError, \"same file: #{s} and #{d}\" if fu_same?(s, d)\n      yield s, d\n    end\n  end\n  private_module_function :fu_each_src_dest\n\n  def fu_each_src_dest0(src, dest)   #:nodoc:\n    if src.is_a?(Array)\n      src.each do |s|\n        s = s.to_str\n        yield s, File.join(dest, File.basename(s))\n      end\n    else\n      src = src.to_str\n      if File.directory?(dest)\n        yield src, File.join(dest, File.basename(src))\n      else\n        yield src, dest.to_str\n      end\n    end\n  end\n  private_module_function :fu_each_src_dest0\n\n  def fu_same?(a, b)   #:nodoc:\n    if fu_have_st_ino?\n      st1 = File.stat(a)\n      st2 = File.stat(b)\n      st1.dev == st2.dev and st1.ino == st2.ino\n    else\n      File.expand_path(a) == File.expand_path(b)\n    end\n  rescue Errno::ENOENT\n    return false\n  end\n  private_module_function :fu_same?\n\n  def fu_have_st_ino?   #:nodoc:\n    not fu_windows?\n  end\n  private_module_function :fu_have_st_ino?\n\n  def fu_check_options(options, optdecl)   #:nodoc:\n    h = options.dup\n    optdecl.each do |opt|\n      h.delete opt\n    end\n    raise ArgumentError, \"no such option: #{h.keys.join(' ')}\" unless h.empty?\n  end\n  private_module_function :fu_check_options\n\n  def fu_update_option(args, new)   #:nodoc:\n    if args.last.is_a?(Hash)\n      args[-1] = args.last.dup.update(new)\n    else\n      args.push new\n    end\n    args\n  end\n  private_module_function :fu_update_option\n\n  @fileutils_output = $stderr\n  @fileutils_label  = ''\n\n  def fu_output_message(msg)   #:nodoc:\n    @fileutils_output ||= $stderr\n    @fileutils_label  ||= ''\n    @fileutils_output.puts @fileutils_label + msg\n  end\n  private_module_function :fu_output_message\n\n  #\n  # Returns an Array of method names which have any options.\n  #\n  #   p FileUtils.commands  #=> [\"chmod\", \"cp\", \"cp_r\", \"install\", ...]\n  #\n  def FileUtils.commands\n    OPT_TABLE.keys\n  end\n\n  #\n  # Returns an Array of option names.\n  #\n  #   p FileUtils.options  #=> [\"noop\", \"force\", \"verbose\", \"preserve\", \"mode\"]\n  #\n  def FileUtils.options\n    OPT_TABLE.values.flatten.uniq.map {|sym| sym.to_s }\n  end\n\n  #\n  # Returns true if the method +mid+ have an option +opt+.\n  #\n  #   p FileUtils.have_option?(:cp, :noop)     #=> true\n  #   p FileUtils.have_option?(:rm, :force)    #=> true\n  #   p FileUtils.have_option?(:rm, :perserve) #=> false\n  #\n  def FileUtils.have_option?(mid, opt)\n    li = OPT_TABLE[mid.to_s] or raise ArgumentError, \"no such method: #{mid}\"\n    li.include?(opt)\n  end\n\n  #\n  # Returns an Array of option names of the method +mid+.\n  #\n  #   p FileUtils.options(:rm)  #=> [\"noop\", \"verbose\", \"force\"]\n  #\n  def FileUtils.options_of(mid)\n    OPT_TABLE[mid.to_s].map {|sym| sym.to_s }\n  end\n\n  #\n  # Returns an Array of method names which have the option +opt+.\n  #\n  #   p FileUtils.collect_method(:preserve) #=> [\"cp\", \"cp_r\", \"copy\", \"install\"]\n  #\n  def FileUtils.collect_method(opt)\n    OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }\n  end\n\n  METHODS = singleton_methods() - %w( private_module_function\n      commands options have_option? options_of collect_method )\n\n  # \n  # This module has all methods of FileUtils module, but it outputs messages\n  # before acting.  This equates to passing the <tt>:verbose</tt> flag to\n  # methods in FileUtils.\n  # \n  module Verbose\n    include FileUtils\n    @fileutils_output  = $stderr\n    @fileutils_label   = ''\n    ::FileUtils.collect_method(:verbose).each do |name|\n      module_eval(<<-EOS, __FILE__, __LINE__ + 1)\n        def #{name}(*args)\n          super(*fu_update_option(args, :verbose => true))\n        end\n        private :#{name}\n      EOS\n    end\n    extend self\n    class << self\n      ::FileUtils::METHODS.each do |m|\n        public m\n      end\n    end\n  end\n\n  # \n  # This module has all methods of FileUtils module, but never changes\n  # files/directories.  This equates to passing the <tt>:noop</tt> flag\n  # to methods in FileUtils.\n  # \n  module NoWrite\n    include FileUtils\n    @fileutils_output  = $stderr\n    @fileutils_label   = ''\n    ::FileUtils.collect_method(:noop).each do |name|\n      module_eval(<<-EOS, __FILE__, __LINE__ + 1)\n        def #{name}(*args)\n          super(*fu_update_option(args, :noop => true))\n        end\n        private :#{name}\n      EOS\n    end\n    extend self\n    class << self\n      ::FileUtils::METHODS.each do |m|\n        public m\n      end\n    end\n  end\n\n  # \n  # This module has all methods of FileUtils module, but never changes\n  # files/directories, with printing message before acting.\n  # This equates to passing the <tt>:noop</tt> and <tt>:verbose</tt> flag\n  # to methods in FileUtils.\n  # \n  module DryRun\n    include FileUtils\n    @fileutils_output  = $stderr\n    @fileutils_label   = ''\n    ::FileUtils.collect_method(:noop).each do |name|\n      module_eval(<<-EOS, __FILE__, __LINE__ + 1)\n        def #{name}(*args)\n          super(*fu_update_option(args, :noop => true, :verbose => true))\n        end\n        private :#{name}\n      EOS\n    end\n    extend self\n    class << self\n      ::FileUtils::METHODS.each do |m|\n        public m\n      end\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/finalize.rb",
    "content": "#--\n#   finalizer.rb - \n#   \t$Release Version: 0.3$\n#   \t$Revision: 1.4 $\n#   \t$Date: 1998/02/27 05:34:33 $\n#   \tby Keiju ISHITSUKA\n#++\n#\n# Usage:\n#\n# add dependency R_method(obj, dependant)\n#   add(obj, dependant, method = :finalize, *opt)\n#   add_dependency(obj, dependant, method = :finalize, *opt)\n#\n# delete dependency R_method(obj, dependant)\n#   delete(obj_or_id, dependant, method = :finalize)\n#   delete_dependency(obj_or_id, dependant, method = :finalize)\n#\n# delete dependency R_*(obj, dependant)\n#   delete_all_dependency(obj_or_id, dependant)\n#\n# delete dependency R_method(*, dependant)\n#   delete_by_dependant(dependant, method = :finalize)\n#\n# delete dependency R_*(*, dependant)\n#   delete_all_by_dependant(dependant)\n#\n# delete all dependency R_*(*, *)\n#   delete_all\n#\n# finalize the dependant connected by dependency R_method(obj, dependtant).\n#   finalize(obj_or_id, dependant, method = :finalize)\n#   finalize_dependency(obj_or_id, dependant, method = :finalize)\n#\n# finalize all dependants connected by dependency R_*(obj, dependtant).\n#   finalize_all_dependency(obj_or_id, dependant)\n#\n# finalize the dependant connected by dependency R_method(*, dependtant).\n#   finalize_by_dependant(dependant, method = :finalize)\n#\n# finalize all dependants connected by dependency R_*(*, dependant).\n#   finalize_all_by_dependant(dependant)\n#\n# finalize all dependency registered to the Finalizer.\n#   finalize_all\n#\n# stop invoking Finalizer on GC.\n#   safe{..}\n#\n\nmodule Finalizer\n  RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-'\n\n  class <<self\n    # @dependency: {id => [[dependant, method, *opt], ...], ...}\n\n    # add dependency R_method(obj, dependant)\n    def add_dependency(obj, dependant, method = :finalize, *opt)\n      ObjectSpace.call_finalizer(obj)\n      method = method.intern unless method.kind_of?(Integer)\n      assoc = [dependant, method].concat(opt)\n      if dep = @dependency[obj.object_id]\n\tdep.push assoc\n      else\n\t@dependency[obj.object_id] = [assoc]\n      end\n    end\n    alias add add_dependency\n\n    # delete dependency R_method(obj, dependant)\n    def delete_dependency(id, dependant, method = :finalize)\n      id = id.object_id unless id.kind_of?(Integer)\n      method = method.intern unless method.kind_of?(Integer)\n      for assoc in @dependency[id]\n\tassoc.delete_if do\n\t  |d, m, *o|\n\t  d == dependant && m == method\n\tend\n\t@dependency.delete(id) if assoc.empty?\n      end\n    end\n    alias delete delete_dependency\n\n    # delete dependency R_*(obj, dependant)\n    def delete_all_dependency(id, dependant)\n      id = id.object_id unless id.kind_of?(Integer)\n      method = method.intern unless method.kind_of?(Integer)\n      for assoc in @dependency[id]\n\tassoc.delete_if do\n\t  |d, m, *o|\n\t  d == dependant\n\tend\n\t@dependency.delete(id) if assoc.empty?\n      end\n    end\n\n    # delete dependency R_method(*, dependant)\n    def delete_by_dependant(dependant, method = :finalize)\n      method = method.intern unless method.kind_of?(Integer)\n      for id in @dependency.keys\n\tdelete(id, dependant, method)\n      end\n    end\n\n    # delete dependency R_*(*, dependant)\n    def delete_all_by_dependant(dependant)\n      for id in @dependency.keys\n\tdelete_all_dependency(id, dependant)\n      end\n    end\n\n    # finalize the depandant connected by dependency R_method(obj, dependtant)\n    def finalize_dependency(id, dependant, method = :finalize)\n      id = id.object_id unless id.kind_of?(Integer)\n      method = method.intern unless method.kind_of?(Integer)\n      for assocs in @dependency[id]\n\tassocs.delete_if do\n\t  |d, m, *o|\n\t  d.send(m, id, *o) if ret = d == dependant && m == method\n\t  ret\n\tend\n\t@dependency.delete(id) if assoc.empty?\n      end\n    end\n    alias finalize finalize_dependency\n\n    # finalize all dependants connected by dependency R_*(obj, dependtant)\n    def finalize_all_dependency(id, dependant)\n      id = id.object_id unless id.kind_of?(Integer)\n      method = method.intern unless method.kind_of?(Integer)\n      for assoc in @dependency[id]\n\tassoc.delete_if do\n\t  |d, m, *o|\n\t  d.send(m, id, *o) if ret = d == dependant\n\tend\n\t@dependency.delete(id) if assoc.empty?\n      end\n    end\n\n    # finalize the dependant connected by dependency R_method(*, dependtant)\n    def finalize_by_dependant(dependant, method = :finalize)\n      method = method.intern unless method.kind_of?(Integer)\n      for id in @dependency.keys\n\tfinalize(id, dependant, method)\n      end\n    end\n\n    # finalize all dependants connected by dependency R_*(*, dependtant)\n    def finalize_all_by_dependant(dependant)\n      for id in @dependency.keys\n\tfinalize_all_dependency(id, dependant)\n      end\n    end\n\n    # finalize all dependants registered to the Finalizer.\n    def finalize_all\n      for id, assocs in @dependency\n\tfor dependant, method, *opt in assocs\n\t  dependant.send(method, id, *opt)\n\tend\n\tassocs.clear\n      end\n    end\n\n    # method to call finalize_* safely.\n    def safe\n      old_status = Thread.critical\n      Thread.critical = true\n      ObjectSpace.remove_finalizer(@proc)\n      begin\n\tyield\n      ensure\n\tObjectSpace.add_finalizer(@proc)\n\tThread.critical = old_status\n      end\n    end\n\n    private\n\n    # registering function to ObjectSpace#add_finalizer\n    def final_of(id)\n      if assocs = @dependency.delete(id)\n\tfor dependant, method, *opt in assocs\n\t  dependant.send(method, id, *opt)\n\tend\n      end\n    end\n\n  end\n  @dependency = Hash.new\n  @proc = proc{|id| final_of(id)}\n  ObjectSpace.add_finalizer(@proc)\nend\n"
  },
  {
    "path": "lib/find.rb",
    "content": "#\n# find.rb: the Find module for processing all files under a given directory.\n#\n\n#\n# The +Find+ module supports the top-down traversal of a set of file paths.\n#\n# For example, to total the size of all files under your home directory,\n# ignoring anything in a \"dot\" directory (e.g. $HOME/.ssh):\n#\n#   require 'find'\n#\n#   total_size = 0\n#\n#   Find.find(ENV[\"HOME\"]) do |path|\n#     if FileTest.directory?(path)\n#       if File.basename(path)[0] == ?.\n#         Find.prune       # Don't look any further into this directory.\n#       else\n#         next\n#       end\n#     else\n#       total_size += FileTest.size(path)\n#     end\n#   end\n#\nmodule Find\n\n  #\n  # Calls the associated block with the name of every file and directory listed\n  # as arguments, then recursively on their subdirectories, and so on.\n  #\n  # See the +Find+ module documentation for an example.\n  #\n  def find(*paths) # :yield: path\n    paths.collect!{|d| d.dup}\n    while file = paths.shift\n      catch(:prune) do\n\tyield file.dup.taint\n        next unless File.exist? file\n\tbegin\n\t  if File.lstat(file).directory? then\n\t    d = Dir.open(file)\n\t    begin\n\t      for f in d\n\t\tnext if f == \".\" or f == \"..\"\n\t\tif File::ALT_SEPARATOR and file =~ /^(?:[\\/\\\\]|[A-Za-z]:[\\/\\\\]?)$/ then\n\t\t  f = file + f\n\t\telsif file == \"/\" then\n\t\t  f = \"/\" + f\n\t\telse\n\t\t  f = File.join(file, f)\n\t\tend\n\t\tpaths.unshift f.untaint\n\t      end\n\t    ensure\n\t      d.close\n\t    end\n\t  end\n        rescue Errno::ENOENT, Errno::EACCES\n\tend\n      end\n    end\n  end\n\n  #\n  # Skips the current file or directory, restarting the loop with the next\n  # entry. If the current file is a directory, that directory will not be\n  # recursively entered. Meaningful only within the block associated with\n  # Find::find.\n  #\n  # See the +Find+ module documentation for an example.\n  #\n  def prune\n    throw :prune\n  end\n\n  module_function :find, :prune\nend\n"
  },
  {
    "path": "lib/forwardable.rb",
    "content": "# = forwardable - Support for the Delegation Pattern\n#\n#    $Release Version: 1.1$\n#    $Revision$\n#    $Date$\n#    by Keiju ISHITSUKA(keiju@ishitsuka.com)\n#\n#    Documentation by James Edward Gray II and Gavin Sinclair\n#\n# == Introduction\n#\n# This library allows you delegate method calls to an object, on a method by\n# method basis.  You can use Forwardable to setup this delegation at the class\n# level, or SingleForwardable to handle it at the object level.\n#\n# == Notes\n#\n# Be advised, RDoc will not detect delegated methods.\n#\n# <b>forwardable.rb provides single-method delegation via the\n# def_delegator() and def_delegators() methods.  For full-class\n# delegation via DelegateClass(), see delegate.rb.</b>\n#\n# == Examples\n#\n# === Forwardable\n#\n# Forwardable makes building a new class based on existing work, with a proper\n# interface, almost trivial.  We want to rely on what has come before obviously,\n# but with delegation we can take just the methods we need and even rename them\n# as appropriate.  In many cases this is preferable to inheritance, which gives\n# us the entire old interface, even if much of it isn't needed.\n#\n#   class Queue\n#     extend Forwardable\n#     \n#     def initialize\n#       @q = [ ]    # prepare delegate object\n#     end\n#     \n#     # setup preferred interface, enq() and deq()...\n#     def_delegator :@q, :push, :enq\n#     def_delegator :@q, :shift, :deq\n#     \n#     # support some general Array methods that fit Queues well\n#     def_delegators :@q, :clear, :first, :push, :shift, :size\n#   end\n# \n#   q = Queue.new\n#   q.enq 1, 2, 3, 4, 5\n#   q.push 6\n# \n#   q.shift    # => 1\n#   while q.size > 0\n#     puts q.deq\n#   end\n# \n#   q.enq \"Ruby\", \"Perl\", \"Python\"\n#   puts q.first\n#   q.clear\n#   puts q.first\n#\n# <i>Prints:</i>\n#\n#   2\n#   3\n#   4\n#   5\n#   6\n#   Ruby\n#   nil\n#\n# === SingleForwardable\n#\n#    printer = String.new\n#    printer.extend SingleForwardable        # prepare object for delegation\n#    printer.def_delegator \"STDOUT\", \"puts\"  # add delegation for STDOUT.puts()\n#    printer.puts \"Howdy!\"\n#\n# <i>Prints:</i>\n#\n#    Howdy!\n\n#\n# The Forwardable module provides delegation of specified\n# methods to a designated object, using the methods #def_delegator\n# and #def_delegators.\n#\n# For example, say you have a class RecordCollection which\n# contains an array <tt>@records</tt>.  You could provide the lookup method\n# #record_number(), which simply calls #[] on the <tt>@records</tt>\n# array, like this:\n#\n#   class RecordCollection\n#     extend Forwardable\n#     def_delegator :@records, :[], :record_number\n#   end\n#\n# Further, if you wish to provide the methods #size, #<<, and #map,\n# all of which delegate to @records, this is how you can do it:\n#\n#   class RecordCollection\n#     # extend Forwardable, but we did that above\n#     def_delegators :@records, :size, :<<, :map\n#   end\n#\n# Also see the example at forwardable.rb.\n#\nmodule Forwardable\n\n  @debug = nil\n  class<<self\n    # force Forwardable to show up in stack backtraces of delegated methods\n    attr_accessor :debug\n  end\n\n  #\n  # Shortcut for defining multiple delegator methods, but with no\n  # provision for using a different name.  The following two code\n  # samples have the same effect:\n  #\n  #   def_delegators :@records, :size, :<<, :map\n  #\n  #   def_delegator :@records, :size\n  #   def_delegator :@records, :<<\n  #   def_delegator :@records, :map\n  #\n  # See the examples at Forwardable and forwardable.rb.\n  #\n  def def_instance_delegators(accessor, *methods)\n    for method in methods\n      def_instance_delegator(accessor, method)\n    end\n  end\n\n  #\n  # Defines a method _method_ which delegates to _obj_ (i.e. it calls\n  # the method of the same name in _obj_).  If _new_name_ is\n  # provided, it is used as the name for the delegate method.\n  #\n  # See the examples at Forwardable and forwardable.rb.\n  #\n  def def_instance_delegator(accessor, method, ali = method)\n    accessor = accessor.id2name if accessor.kind_of?(Integer)\n    method = method.id2name if method.kind_of?(Integer)\n    ali = ali.id2name if ali.kind_of?(Integer)\n\n    module_eval(<<-EOS, \"(__FORWARDABLE__)\", 1)\n      def #{ali}(*args, &block)\n\tbegin\n\t  #{accessor}.__send__(:#{method}, *args, &block)\n\trescue Exception\n\t  $@.delete_if{|s| /^\\\\(__FORWARDABLE__\\\\):/ =~ s} unless Forwardable::debug\n\t  Kernel::raise\n\tend\n      end\n    EOS\n  end\n\n  alias def_delegators def_instance_delegators\n  alias def_delegator def_instance_delegator\nend\n\n#\n# The SingleForwardable module provides delegation of specified\n# methods to a designated object, using the methods #def_delegator\n# and #def_delegators.  This module is similar to Forwardable, but it works on\n# objects themselves, instead of their defining classes.\n#\n# Also see the example at forwardable.rb.\n#\nmodule SingleForwardable\n  #\n  # Shortcut for defining multiple delegator methods, but with no\n  # provision for using a different name.  The following two code\n  # samples have the same effect:\n  #\n  #   single_forwardable.def_delegators :@records, :size, :<<, :map\n  #\n  #   single_forwardable.def_delegator :@records, :size\n  #   single_forwardable.def_delegator :@records, :<<\n  #   single_forwardable.def_delegator :@records, :map\n  #\n  # See the example at forwardable.rb.\n  #\n  def def_singleton_delegators(accessor, *methods)\n    for method in methods\n      def_singleton_delegator(accessor, method)\n    end\n  end\n\n  #\n  # Defines a method _method_ which delegates to _obj_ (i.e. it calls\n  # the method of the same name in _obj_).  If _new_name_ is\n  # provided, it is used as the name for the delegate method.\n  #\n  # See the example at forwardable.rb.\n  #\n  def def_singleton_delegator(accessor, method, ali = method)\n    accessor = accessor.id2name if accessor.kind_of?(Integer)\n    method = method.id2name if method.kind_of?(Integer)\n    ali = ali.id2name if ali.kind_of?(Integer)\n\n    instance_eval(<<-EOS, \"(__FORWARDABLE__)\", 1)\n       def #{ali}(*args, &block)\n\t begin\n\t   #{accessor}.__send__(:#{method}, *args,&block)\n\t rescue Exception\n\t   $@.delete_if{|s| /^\\\\(__FORWARDABLE__\\\\):/ =~ s} unless Forwardable::debug\n\t   Kernel::raise\n\t end\n       end\n    EOS\n  end\n\n  alias def_delegators def_singleton_delegators\n  alias def_delegator def_singleton_delegator\nend\n"
  },
  {
    "path": "lib/ftools.rb",
    "content": "# \n# = ftools.rb: Extra tools for the File class\n#\n# Author:: WATANABE, Hirofumi\n# Documentation:: Zachary Landau\n#\n# This library can be distributed under the terms of the Ruby license.\n# You can freely distribute/modify this library.\n#\n# It is included in the Ruby standard library.\n#\n# == Description\n#\n# ftools adds several (class, not instance) methods to the File class, for\n# copying, moving, deleting, installing, and comparing files, as well as\n# creating a directory path.  See the File class for details.\n#\n# FileUtils contains all or nearly all the same functionality and more, and\n# is a recommended option over ftools \n#\n# When you\n#\n#   require 'ftools'\n#\n# then the File class aquires some utility methods for copying, moving, and\n# deleting files, and more.\n#\n# See the method descriptions below, and consider using FileUtils as it is\n# more comprehensive.\n#\nclass File\nend\n\nclass << File\n\n  BUFSIZE = 8 * 1024\n\n  #\n  # If +to+ is a valid directory, +from+ will be appended to +to+, adding\n  # and escaping backslashes as necessary. Otherwise, +to+ will be returned.\n  # Useful for appending +from+ to +to+ only if the filename was not specified\n  # in +to+. \n  #\n  def catname(from, to)\n    if directory? to\n      join to.sub(%r([/\\\\]$), ''), basename(from)\n    else\n      to\n    end\n  end\n\n  #\n  # Copies a file +from+ to +to+. If +to+ is a directory, copies +from+\n  # to <tt>to/from</tt>.\n  #\n  def syscopy(from, to)\n    to = catname(from, to)\n\n    fmode = stat(from).mode\n    tpath = to\n    not_exist = !exist?(tpath)\n\n    from = open(from, \"rb\")\n    to = open(to, \"wb\")\n\n    begin\n      while true\n\tto.syswrite from.sysread(BUFSIZE)\n      end\n    rescue EOFError\n      ret = true\n    rescue\n      ret = false\n    ensure\n      to.close\n      from.close\n    end\n    chmod(fmode, tpath) if not_exist\n    ret\n  end\n\n  #\n  # Copies a file +from+ to +to+ using #syscopy. If +to+ is a directory,\n  # copies +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from -> to</tt>\n  # is printed.\n  #\n  def copy(from, to, verbose = false)\n    $stderr.print from, \" -> \", catname(from, to), \"\\n\" if verbose\n    syscopy from, to\n  end\n\n  alias cp copy\n\n  #\n  # Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory,\n  # copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from ->\n  # to</tt> is printed.\n  #\n  def move(from, to, verbose = false)\n    to = catname(from, to)\n    $stderr.print from, \" -> \", to, \"\\n\" if verbose\n\n    if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and file? to\n      unlink to\n    end\n    fstat = stat(from)\n    begin\n      rename from, to\n    rescue\n      begin\n        symlink readlink(from), to and unlink from\n      rescue\n\tfrom_stat = stat(from)\n\tsyscopy from, to and unlink from\n\tutime(from_stat.atime, from_stat.mtime, to)\n\tbegin\n\t  chown(fstat.uid, fstat.gid, to)\n\trescue\n\tend\n      end\n    end\n  end\n\n  alias mv move\n\n  #\n  # Returns +true+ if and only if the contents of files +from+ and +to+ are\n  # identical. If +verbose+ is +true+, <tt>from <=> to</tt> is printed.\n  #\n  def compare(from, to, verbose = false)\n    $stderr.print from, \" <=> \", to, \"\\n\" if verbose\n\n    return false if stat(from).size != stat(to).size\n\n    from = open(from, \"rb\")\n    to = open(to, \"rb\")\n\n    ret = false\n    fr = tr = ''\n\n    begin\n      while fr == tr\n\tfr = from.read(BUFSIZE)\n\tif fr\n\t  tr = to.read(fr.size)\n\telse\n\t  ret = to.read(BUFSIZE)\n\t  ret = !ret || ret.length == 0\n\t  break\n\tend\n      end\n    rescue\n      ret = false\n    ensure\n      to.close\n      from.close\n    end\n    ret\n  end\n\n  alias cmp compare\n\n  #\n  # Removes a list of files. Each parameter should be the name of the file to\n  # delete. If the last parameter isn't a String, verbose mode will be enabled.\n  # Returns the number of files deleted.\n  #\n  def safe_unlink(*files)\n    verbose = if files[-1].is_a? String then false else files.pop end\n    files.each do |file|\n      begin\n        unlink file\n        $stderr.print \"removing \", file, \"\\n\" if verbose\n      rescue Errno::EACCES # for Windows\n        continue if symlink? file\n        begin\n          mode = stat(file).mode\n          o_chmod mode | 0200, file\n          unlink file\n          $stderr.print \"removing \", file, \"\\n\" if verbose\n        rescue\n          o_chmod mode, file rescue nil\n        end\n      rescue\n      end\n    end\n  end\n\n  alias rm_f safe_unlink\n\n  #\n  # Creates a directory and all its parent directories.\n  # For example,\n  #\n  #\tFile.makedirs '/usr/lib/ruby'\n  #\n  # causes the following directories to be made, if they do not exist.\n  #\t* /usr\n  #\t* /usr/lib\n  #\t* /usr/lib/ruby\n  #\n  # You can pass several directories, each as a parameter. If the last\n  # parameter isn't a String, verbose mode will be enabled.\n  #\n  def makedirs(*dirs)\n    verbose = if dirs[-1].is_a? String then false else dirs.pop end\n    mode = 0755\n    for dir in dirs\n      parent = dirname(dir)\n      next if parent == dir or directory? dir\n      makedirs parent unless directory? parent\n      $stderr.print \"mkdir \", dir, \"\\n\" if verbose\n      if basename(dir) != \"\"\n        begin\n          Dir.mkdir dir, mode\n        rescue SystemCallError\n          raise unless directory? dir\n        end\n      end\n    end\n  end\n\n  alias mkpath makedirs\n\n  alias o_chmod chmod\n\n  vsave, $VERBOSE = $VERBOSE, false\n\n  #\n  # Changes permission bits on +files+ to the bit pattern represented\n  # by +mode+. If the last parameter isn't a String, verbose mode will\n  # be enabled.\n  #\n  #   File.chmod 0755, 'somecommand'\n  #   File.chmod 0644, 'my.rb', 'your.rb', true\n  #\n  def chmod(mode, *files)\n    verbose = if files[-1].is_a? String then false else files.pop end\n    $stderr.printf \"chmod %04o %s\\n\", mode, files.join(\" \") if verbose\n    o_chmod mode, *files\n  end\n  $VERBOSE = vsave\n\n  #\n  # If +src+ is not the same as +dest+, copies it and changes the permission\n  # mode to +mode+. If +dest+ is a directory, destination is <tt>dest/src</tt>.\n  # If +mode+ is not set, default is used. If +verbose+ is set to true, the\n  # name of each file copied will be printed.\n  #\n  def install(from, to, mode = nil, verbose = false)\n    to = catname(from, to)\n    unless exist? to and cmp from, to\n      safe_unlink to if exist? to\n      cp from, to, verbose\n      chmod mode, to, verbose if mode\n    end\n  end\n\nend\n\n# vi:set sw=2:\n"
  },
  {
    "path": "lib/generator.rb",
    "content": "#!/usr/bin/env ruby\n#--\n# $Idaemons: /home/cvs/rb/generator.rb,v 1.8 2001/10/03 08:54:32 knu Exp $\n# $RoughId: generator.rb,v 1.10 2003/10/14 19:36:58 knu Exp $\n# $Id$\n#++\n#\n# = generator.rb: convert an internal iterator to an external one\n#\n# Copyright (c) 2001,2003 Akinori MUSHA <knu@iDaemons.org>\n#\n# All rights reserved.  You can redistribute and/or modify it under\n# the same terms as Ruby.\n#\n# == Overview\n#\n# This library provides the Generator class, which converts an\n# internal iterator (i.e. an Enumerable object) to an external\n# iterator.  In that form, you can roll many iterators independently.\n#\n# The SyncEnumerator class, which is implemented using Generator,\n# makes it easy to roll many Enumerable objects synchronously.\n#\n# See the respective classes for examples of usage.\n\n\n#\n# Generator converts an internal iterator (i.e. an Enumerable object)\n# to an external iterator.\n#\n# Note that it is not very fast since it is implemented using\n# continuations, which are currently slow.\n#\n# == Example\n#\n#   require 'generator'\n#\n#   # Generator from an Enumerable object\n#   g = Generator.new(['A', 'B', 'C', 'Z'])\n#\n#   while g.next?\n#     puts g.next\n#   end\n#\n#   # Generator from a block\n#   g = Generator.new { |g|\n#     for i in 'A'..'C'\n#       g.yield i\n#     end\n#\n#     g.yield 'Z'\n#   }\n#\n#   # The same result as above\n#   while g.next?\n#     puts g.next\n#   end\n#   \nclass Generator\n  include Enumerable\n\n  # Creates a new generator either from an Enumerable object or from a\n  # block.\n  #\n  # In the former, block is ignored even if given.\n  #\n  # In the latter, the given block is called with the generator\n  # itself, and expected to call the +yield+ method for each element.\n  def initialize(enum = nil, &block)\n    if enum\n      @block = proc { |g|\n\tenum.each { |x| g.yield x }\n      }\n    else\n      @block = block\n    end\n\n    @index = 0\n    @queue = []\n    @cont_next = @cont_yield = @cont_endp = nil\n\n    if @cont_next = callcc { |c| c }\n      @block.call(self)\n\n      @cont_endp.call(nil) if @cont_endp\n    end\n\n    self\n  end\n\n  # Yields an element to the generator.\n  def yield(value)\n    if @cont_yield = callcc { |c| c }\n      @queue << value\n      @cont_next.call(nil)\n    end\n\n    self\n  end\n\n  # Returns true if the generator has reached the end.\n  def end?()\n    if @cont_endp = callcc { |c| c }\n      @cont_yield.nil? && @queue.empty?\n    else\n      @queue.empty?\n    end\n  end\n\n  # Returns true if the generator has not reached the end yet.\n  def next?()\n    !end?\n  end\n\n  # Returns the current index (position) counting from zero.\n  def index()\n    @index\n  end\n\n  # Returns the current index (position) counting from zero.\n  def pos()\n    @index\n  end\n\n  # Returns the element at the current position and moves forward.\n  def next()\n    if end?\n      raise EOFError, \"no more elements available\"\n    end\n\n    if @cont_next = callcc { |c| c }\n      @cont_yield.call(nil) if @cont_yield\n    end\n\n    @index += 1\n\n    @queue.shift\n  end\n\n  # Returns the element at the current position.\n  def current()\n    if @queue.empty?\n      raise EOFError, \"no more elements available\"\n    end\n\n    @queue.first\n  end\n\n  # Rewinds the generator.\n  def rewind()\n    initialize(nil, &@block) if @index.nonzero?\n\n    self\n  end\n\n  # Rewinds the generator and enumerates the elements.\n  def each\n    rewind\n\n    until end?\n      yield self.next\n    end\n\n    self\n  end\nend\n\nclass Enumerable::Enumerator\n  def __generator\n    @generator ||= Generator.new(self)\n  end\n  private :__generator\n\n  # call-seq:\n  #   e.next   => object\n  #\n  # Returns the next object in the enumerator, and move the internal\n  # position forward.  When the position reached at the end, internal\n  # position is rewinded then StopIteration is raised.\n  #\n  # Note that enumeration sequence by next method does not affect other\n  # non-external enumeration methods, unless underlying iteration\n  # methods itself has side-effect, e.g. IO#each_line.\n  #\n  # Caution: This feature internally uses Generator, which uses callcc\n  # to stop and resume enumeration to fetch each value.  Use with care\n  # and be aware of the performance loss.\n  def next\n    g = __generator\n    return g.next unless g.end?\n\n    g.rewind\n    raise StopIteration, 'iteration reached at end' \n  end\n\n  # call-seq:\n  #   e.rewind   => e\n  #\n  # Rewinds the enumeration sequence by the next method.\n  def rewind\n    __generator.rewind\n    self\n  end\nend\n\n#\n# SyncEnumerator creates an Enumerable object from multiple Enumerable\n# objects and enumerates them synchronously.\n#\n# == Example\n#\n#   require 'generator'\n#\n#   s = SyncEnumerator.new([1,2,3], ['a', 'b', 'c'])\n#\n#   # Yields [1, 'a'], [2, 'b'], and [3,'c']\n#   s.each { |row| puts row.join(', ') }\n#\nclass SyncEnumerator\n  include Enumerable\n\n  # Creates a new SyncEnumerator which enumerates rows of given\n  # Enumerable objects.\n  def initialize(*enums)\n    @gens = enums.map { |e| Generator.new(e) }\n  end\n\n  # Returns the number of enumerated Enumerable objects, i.e. the size\n  # of each row.\n  def size\n    @gens.size\n  end\n\n  # Returns the number of enumerated Enumerable objects, i.e. the size\n  # of each row.\n  def length\n    @gens.length\n  end\n\n  # Returns true if the given nth Enumerable object has reached the\n  # end.  If no argument is given, returns true if any of the\n  # Enumerable objects has reached the end.\n  def end?(i = nil)\n    if i.nil?\n      @gens.detect { |g| g.end? } ? true : false\n    else\n      @gens[i].end?\n    end\n  end\n\n  # Enumerates rows of the Enumerable objects.\n  def each\n    @gens.each { |g| g.rewind }\n\n    loop do\n      count = 0\n\n      ret = @gens.map { |g|\n\tif g.end?\n\t  count += 1\n\t  nil\n\telse\n\t  g.next\n\tend\n      }\n\n      if count == @gens.size\n\tbreak\n      end\n\n      yield ret\n    end\n\n    self\n  end\nend\n\nif $0 == __FILE__\n  eval DATA.read, nil, $0, __LINE__+4\nend\n\n__END__\n\nrequire 'test/unit'\n\nclass TC_Generator < Test::Unit::TestCase\n  def test_block1\n    g = Generator.new { |g|\n      # no yield's\n    }\n\n    assert_equal(0, g.pos)\n    assert_raises(EOFError) { g.current }\n  end\n\n  def test_block2\n    g = Generator.new { |g|\n      for i in 'A'..'C'\n        g.yield i\n      end\n\n      g.yield 'Z'\n    }\n\n    assert_equal(0, g.pos)\n    assert_equal('A', g.current)\n\n    assert_equal(true, g.next?)\n    assert_equal(0, g.pos)\n    assert_equal('A', g.current)\n    assert_equal(0, g.pos)\n    assert_equal('A', g.next)\n\n    assert_equal(1, g.pos)\n    assert_equal(true, g.next?)\n    assert_equal(1, g.pos)\n    assert_equal('B', g.current)\n    assert_equal(1, g.pos)\n    assert_equal('B', g.next)\n\n    assert_equal(g, g.rewind)\n\n    assert_equal(0, g.pos)\n    assert_equal('A', g.current)\n\n    assert_equal(true, g.next?)\n    assert_equal(0, g.pos)\n    assert_equal('A', g.current)\n    assert_equal(0, g.pos)\n    assert_equal('A', g.next)\n\n    assert_equal(1, g.pos)\n    assert_equal(true, g.next?)\n    assert_equal(1, g.pos)\n    assert_equal('B', g.current)\n    assert_equal(1, g.pos)\n    assert_equal('B', g.next)\n\n    assert_equal(2, g.pos)\n    assert_equal(true, g.next?)\n    assert_equal(2, g.pos)\n    assert_equal('C', g.current)\n    assert_equal(2, g.pos)\n    assert_equal('C', g.next)\n\n    assert_equal(3, g.pos)\n    assert_equal(true, g.next?)\n    assert_equal(3, g.pos)\n    assert_equal('Z', g.current)\n    assert_equal(3, g.pos)\n    assert_equal('Z', g.next)\n\n    assert_equal(4, g.pos)\n    assert_equal(false, g.next?)\n    assert_raises(EOFError) { g.next }\n  end\n\n  def test_each\n    a = [5, 6, 7, 8, 9]\n\n    g = Generator.new(a)\n\n    i = 0\n\n    g.each { |x|\n      assert_equal(a[i], x)\n\n      i += 1\n\n      break if i == 3\n    }\n\n    assert_equal(3, i)\n\n    i = 0\n\n    g.each { |x|\n      assert_equal(a[i], x)\n\n      i += 1\n    }\n\n    assert_equal(5, i)\n  end\nend\n\nclass TC_SyncEnumerator < Test::Unit::TestCase\n  def test_each\n    r = ['a'..'f', 1..10, 10..20]\n    ra = r.map { |x| x.to_a }\n\n    a = (0...(ra.map {|x| x.size}.max)).map { |i| ra.map { |x| x[i] } }\n\n    s = SyncEnumerator.new(*r)\n\n    i = 0\n\n    s.each { |x|\n      assert_equal(a[i], x)\n\n      i += 1\n\n      break if i == 3\n    }\n\n    assert_equal(3, i)\n\n    i = 0\n\n    s.each { |x|\n      assert_equal(a[i], x)\n\n      i += 1\n    }\n\n    assert_equal(a.size, i)\n  end\nend\n"
  },
  {
    "path": "lib/getoptlong.rb",
    "content": "#\n# GetoptLong for Ruby\n#\n# Copyright (C) 1998, 1999, 2000  Motoyuki Kasahara.\n#\n# You may redistribute and/or modify this library under the same license\n# terms as Ruby.\n#\n# See GetoptLong for documentation.\n#\n# Additional documents and the latest version of `getoptlong.rb' can be\n# found at http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/\n\n# The GetoptLong class allows you to parse command line options similarly to\n# the GNU getopt_long() C library call. Note, however, that GetoptLong is a \n# pure Ruby implementation.\n#\n# GetoptLong allows for POSIX-style options like <tt>--file</tt> as well \n# as single letter options like <tt>-f</tt>\n#\n# The empty option <tt>--</tt> (two minus symbols) is used to end option\n# processing. This can be particularly important if options have optional\n# arguments.\n#\n# Here is a simple example of usage:\n#\n#     # == Synopsis\n#     #\n#     # hello: greets user, demonstrates command line parsing\n#     #\n#     # == Usage\n#     #\n#     # hello [OPTION] ... DIR\n#     #\n#     # -h, --help:\n#     #    show help\n#     #\n#     # --repeat x, -n x:\n#     #    repeat x times\n#     #\n#     # --name [name]:\n#     #    greet user by name, if name not supplied default is John\n#     #\n#     # DIR: The directory in which to issue the greeting.\n#     \n#     require 'getoptlong'\n#     require 'rdoc/usage'\n#     \n#     opts = GetoptLong.new(\n#       [ '--help', '-h', GetoptLong::NO_ARGUMENT ],\n#       [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ],\n#       [ '--name', GetoptLong::OPTIONAL_ARGUMENT ]\n#     )\n#     \n#     dir = nil\n#     name = nil\n#     repetitions = 1\n#     opts.each do |opt, arg|\n#       case opt\n#         when '--help'\n#           RDoc::usage\n#         when '--repeat'\n#           repetitions = arg.to_i\n#         when '--name'\n#           if arg == ''\n#             name = 'John'\n#           else\n#             name = arg\n#           end\n#       end\n#     end\n#     \n#     if ARGV.length != 1\n#       puts \"Missing dir argument (try --help)\"\n#       exit 0\n#     end\n#     \n#     dir = ARGV.shift\n#     \n#     Dir.chdir(dir)\n#     for i in (1..repetitions)\n#       print \"Hello\"\n#       if name\n#         print \", #{name}\"\n#       end\n#       puts\n#     end\n#\n# Example command line:\n#\n#     hello -n 6 --name -- /tmp\n#\nclass GetoptLong\n  #\n  # Orderings.\n  #\n  ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2]\n\n  #\n  # Argument flags.\n  #\n  ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1,\n    OPTIONAL_ARGUMENT = 2]\n\n  #\n  # Status codes.\n  #\n  STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2\n\n  #\n  # Error types.\n  #\n  class Error  < StandardError; end\n  class AmbigousOption   < Error; end\n  class NeedlessArgument < Error; end\n  class MissingArgument  < Error; end\n  class InvalidOption    < Error; end\n\n  #\n  # Set up option processing.\n  #\n  # The options to support are passed to new() as an array of arrays.\n  # Each sub-array contains any number of String option names which carry \n  # the same meaning, and one of the following flags:\n  #\n  # GetoptLong::NO_ARGUMENT :: Option does not take an argument.\n  #\n  # GetoptLong::REQUIRED_ARGUMENT :: Option always takes an argument.\n  #\n  # GetoptLong::OPTIONAL_ARGUMENT :: Option may or may not take an argument.\n  #\n  # The first option name is considered to be the preferred (canonical) name.\n  # Other than that, the elements of each sub-array can be in any order.\n  #\n  def initialize(*arguments)\n    #\n    # Current ordering.\n    #\n    if ENV.include?('POSIXLY_CORRECT')\n      @ordering = REQUIRE_ORDER\n    else\n      @ordering = PERMUTE\n    end\n\n    #\n    # Hash table of option names.\n    # Keys of the table are option names, and their values are canonical\n    # names of the options.\n    #\n    @canonical_names = Hash.new\n\n    #\n    # Hash table of argument flags.\n    # Keys of the table are option names, and their values are argument\n    # flags of the options.\n    #\n    @argument_flags = Hash.new\n\n    #\n    # Whether error messages are output to $deferr.\n    #\n    @quiet = FALSE\n\n    #\n    # Status code.\n    #\n    @status = STATUS_YET\n\n    #\n    # Error code.\n    #\n    @error = nil\n\n    #\n    # Error message.\n    #\n    @error_message = nil\n\n    #\n    # Rest of catenated short options.\n    #\n    @rest_singles = ''\n\n    #\n    # List of non-option-arguments.\n    # Append them to ARGV when option processing is terminated.\n    #\n    @non_option_arguments = Array.new\n\n    if 0 < arguments.length\n      set_options(*arguments)\n    end\n  end\n\n  #\n  # Set the handling of the ordering of options and arguments.\n  # A RuntimeError is raised if option processing has already started.\n  #\n  # The supplied value must be a member of GetoptLong::ORDERINGS. It alters\n  # the processing of options as follows:\n  #\n  # <b>REQUIRE_ORDER</b> :\n  # \n  # Options are required to occur before non-options.\n  #\n  # Processing of options ends as soon as a word is encountered that has not\n  # been preceded by an appropriate option flag.\n  #\n  # For example, if -a and -b are options which do not take arguments,\n  # parsing command line arguments of '-a one -b two' would result in \n  # 'one', '-b', 'two' being left in ARGV, and only ('-a', '') being \n  # processed as an option/arg pair.\n  #\n  # This is the default ordering, if the environment variable\n  # POSIXLY_CORRECT is set. (This is for compatibility with GNU getopt_long.)\n  #\n  # <b>PERMUTE</b> :\n  #  \n  # Options can occur anywhere in the command line parsed. This is the \n  # default behavior.\n  #\n  # Every sequence of words which can be interpreted as an option (with or\n  # without argument) is treated as an option; non-option words are skipped.\n  #\n  # For example, if -a does not require an argument and -b optionally takes\n  # an argument, parsing '-a one -b two three' would result in ('-a','') and\n  # ('-b', 'two') being processed as option/arg pairs, and 'one','three'\n  # being left in ARGV.\n  #\n  # If the ordering is set to PERMUTE but the environment variable\n  # POSIXLY_CORRECT is set, REQUIRE_ORDER is used instead. This is for\n  # compatibility with GNU getopt_long.\n  #\n  # <b>RETURN_IN_ORDER</b> :\n  #\n  # All words on the command line are processed as options. Words not \n  # preceded by a short or long option flag are passed as arguments\n  # with an option of '' (empty string).\n  #\n  # For example, if -a requires an argument but -b does not, a command line\n  # of '-a one -b two three' would result in option/arg pairs of ('-a', 'one')\n  # ('-b', ''), ('', 'two'), ('', 'three') being processed.\n  #\n  def ordering=(ordering)\n    #\n    # The method is failed if option processing has already started.\n    #\n    if @status != STATUS_YET\n      set_error(ArgumentError, \"argument error\")\n      raise RuntimeError,\n\t\"invoke ordering=, but option processing has already started\"\n    end\n\n    #\n    # Check ordering.\n    #\n    if !ORDERINGS.include?(ordering)\n      raise ArgumentError, \"invalid ordering `#{ordering}'\"\n    end\n    if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')\n      @ordering = REQUIRE_ORDER\n    else\n      @ordering = ordering\n    end\n  end\n\n  #\n  # Return ordering.\n  #\n  attr_reader :ordering\n\n  #\n  # Set options. Takes the same argument as GetoptLong.new.\n  #\n  # Raises a RuntimeError if option processing has already started.\n  #\n  def set_options(*arguments)\n    #\n    # The method is failed if option processing has already started.\n    #\n    if @status != STATUS_YET\n      raise RuntimeError, \n\t\"invoke set_options, but option processing has already started\"\n    end\n\n    #\n    # Clear tables of option names and argument flags.\n    #\n    @canonical_names.clear\n    @argument_flags.clear\n\n    arguments.each do |arg|\n      #\n      # Each argument must be an Array.\n      #\n      if !arg.is_a?(Array)\n\traise ArgumentError, \"the option list contains non-Array argument\"\n      end\n\n      #\n      # Find an argument flag and it set to `argument_flag'.\n      #\n      argument_flag = nil\n      arg.each do |i|\n\tif ARGUMENT_FLAGS.include?(i)\n\t  if argument_flag != nil\n\t    raise ArgumentError, \"too many argument-flags\"\n\t  end\n\t  argument_flag = i\n\tend\n      end\n      raise ArgumentError, \"no argument-flag\" if argument_flag == nil\n\n      canonical_name = nil\n      arg.each do |i|\n\t#\n\t# Check an option name.\n\t#\n\tnext if i == argument_flag\n\tbegin\n\t  if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/\n\t    raise ArgumentError, \"an invalid option `#{i}'\"\n\t  end\n\t  if (@canonical_names.include?(i))\n\t    raise ArgumentError, \"option redefined `#{i}'\"\n\t  end\n\trescue\n\t  @canonical_names.clear\n\t  @argument_flags.clear\n\t  raise\n\tend\n\n\t#\n\t# Register the option (`i') to the `@canonical_names' and \n\t# `@canonical_names' Hashes.\n\t#\n\tif canonical_name == nil\n\t  canonical_name = i\n\tend\n\t@canonical_names[i] = canonical_name\n\t@argument_flags[i] = argument_flag\n      end\n      raise ArgumentError, \"no option name\" if canonical_name == nil\n    end\n    return self\n  end\n\n  #\n  # Set/Unset `quiet' mode.\n  #\n  attr_writer :quiet\n\n  #\n  # Return the flag of `quiet' mode.\n  #\n  attr_reader :quiet\n\n  #\n  # `quiet?' is an alias of `quiet'.\n  #\n  alias quiet? quiet\n\n  #\n  # Explicitly terminate option processing.\n  #\n  def terminate\n    return nil if @status == STATUS_TERMINATED\n    raise RuntimeError, \"an error has occured\" if @error != nil\n\n    @status = STATUS_TERMINATED\n    @non_option_arguments.reverse_each do |argument|\n      ARGV.unshift(argument)\n    end\n\n    @canonical_names = nil\n    @argument_flags = nil\n    @rest_singles = nil\n    @non_option_arguments = nil\n\n    return self\n  end\n\n  #\n  # Returns true if option processing has terminated, false otherwise.\n  #\n  def terminated?\n    return @status == STATUS_TERMINATED\n  end\n\n  #\n  # Set an error (protected).\n  #\n  def set_error(type, message)\n    $deferr.print(\"#{$0}: #{message}\\n\") if !@quiet\n\n    @error = type\n    @error_message = message\n    @canonical_names = nil\n    @argument_flags = nil\n    @rest_singles = nil\n    @non_option_arguments = nil\n\n    raise type, message\n  end\n  protected :set_error\n\n  #\n  # Examine whether an option processing is failed.\n  #\n  attr_reader :error\n\n  #\n  # `error?' is an alias of `error'.\n  #\n  alias error? error\n\n  # Return the appropriate error message in POSIX-defined format.\n  # If no error has occurred, returns nil.\n  #\n  def error_message\n    return @error_message\n  end\n\n  #\n  # Get next option name and its argument, as an Array of two elements.\n  #\n  # The option name is always converted to the first (preferred)\n  # name given in the original options to GetoptLong.new.\n  #\n  # Example: ['--option', 'value']\n  #\n  # Returns nil if the processing is complete (as determined by\n  # STATUS_TERMINATED).\n  #\n  def get\n    option_name, option_argument = nil, ''\n\n    #\n    # Check status.\n    #\n    return nil if @error != nil\n    case @status\n    when STATUS_YET\n      @status = STATUS_STARTED\n    when STATUS_TERMINATED\n      return nil\n    end\n\n    #\n    # Get next option argument.\n    #\n    if 0 < @rest_singles.length\n      argument = '-' + @rest_singles\n    elsif (ARGV.length == 0)\n      terminate\n      return nil\n    elsif @ordering == PERMUTE\n      while 0 < ARGV.length && ARGV[0] !~ /^-./\n\t@non_option_arguments.push(ARGV.shift)\n      end\n      if ARGV.length == 0\n\tterminate\n\treturn nil\n      end\n      argument = ARGV.shift\n    elsif @ordering == REQUIRE_ORDER \n      if (ARGV[0] !~ /^-./)\n\tterminate\n\treturn nil\n      end\n      argument = ARGV.shift\n    else\n      argument = ARGV.shift\n    end\n\n    #\n    # Check the special argument `--'.\n    # `--' indicates the end of the option list.\n    #\n    if argument == '--' && @rest_singles.length == 0\n      terminate\n      return nil\n    end\n\n    #\n    # Check for long and short options.\n    #\n    if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0\n      #\n      # This is a long style option, which start with `--'.\n      #\n      pattern = $1\n      if @canonical_names.include?(pattern)\n\toption_name = pattern\n      else\n\t#\n\t# The option `option_name' is not registered in `@canonical_names'.\n\t# It may be an abbreviated.\n\t#\n\tmatch_count = 0\n\t@canonical_names.each_key do |key|\n\t  if key.index(pattern) == 0\n\t    option_name = key\n\t    match_count += 1\n\t  end\n\tend\n\tif 2 <= match_count\n\t  set_error(AmbigousOption, \"option `#{argument}' is ambiguous\")\n\telsif match_count == 0\n\t  set_error(InvalidOption, \"unrecognized option `#{argument}'\")\n\tend\n      end\n\n      #\n      # Check an argument to the option.\n      #\n      if @argument_flags[option_name] == REQUIRED_ARGUMENT\n\tif argument =~ /=(.*)$/\n\t  option_argument = $1\n\telsif 0 < ARGV.length\n\t  option_argument = ARGV.shift\n\telse\n\t  set_error(MissingArgument,\n\t            \"option `#{argument}' requires an argument\")\n\tend\n      elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT\n\tif argument =~ /=(.*)$/\n\t  option_argument = $1\n\telsif 0 < ARGV.length && ARGV[0] !~ /^-./\n\t  option_argument = ARGV.shift\n\telse\n\t  option_argument = ''\n\tend\n      elsif argument =~ /=(.*)$/\n\tset_error(NeedlessArgument,\n\t\t  \"option `#{option_name}' doesn't allow an argument\")\n      end\n\n    elsif argument =~ /^(-(.))(.*)/\n      #\n      # This is a short style option, which start with `-' (not `--').\n      # Short options may be catenated (e.g. `-l -g' is equivalent to\n      # `-lg').\n      #\n      option_name, ch, @rest_singles = $1, $2, $3\n\n      if @canonical_names.include?(option_name)\n\t#\n\t# The option `option_name' is found in `@canonical_names'.\n\t# Check its argument.\n\t#\n\tif @argument_flags[option_name] == REQUIRED_ARGUMENT\n\t  if 0 < @rest_singles.length\n\t    option_argument = @rest_singles\n\t    @rest_singles = ''\n\t  elsif 0 < ARGV.length\n\t    option_argument = ARGV.shift\n\t  else\n\t    # 1003.2 specifies the format of this message.\n\t    set_error(MissingArgument, \"option requires an argument -- #{ch}\")\n\t  end\n\telsif @argument_flags[option_name] == OPTIONAL_ARGUMENT\n\t  if 0 < @rest_singles.length\n\t    option_argument = @rest_singles\n\t    @rest_singles = ''\n\t  elsif 0 < ARGV.length && ARGV[0] !~ /^-./\n\t    option_argument = ARGV.shift\n\t  else\n\t    option_argument = ''\n\t  end\n\tend\n      else\n\t#\n\t# This is an invalid option.\n\t# 1003.2 specifies the format of this message.\n\t#\n\tif ENV.include?('POSIXLY_CORRECT')\n\t  set_error(InvalidOption, \"illegal option -- #{ch}\")\n\telse\n\t  set_error(InvalidOption, \"invalid option -- #{ch}\")\n\tend\n      end\n    else\n      #\n      # This is a non-option argument.\n      # Only RETURN_IN_ORDER falled into here.\n      #\n      return '', argument\n    end\n\n    return @canonical_names[option_name], option_argument\n  end\n\n  #\n  # `get_option' is an alias of `get'.\n  #\n  alias get_option get\n\n  # Iterator version of `get'.\n  #\n  # The block is called repeatedly with two arguments:\n  # The first is the option name.\n  # The second is the argument which followed it (if any). \n  # Example: ('--opt', 'value')\n  #\n  # The option name is always converted to the first (preferred)\n  # name given in the original options to GetoptLong.new.\n  #\n  def each\n    loop do\n      option_name, option_argument = get_option\n      break if option_name == nil\n      yield option_name, option_argument\n    end\n  end\n\n  #\n  # `each_option' is an alias of `each'.\n  #\n  alias each_option each\nend\n"
  },
  {
    "path": "lib/getopts.rb",
    "content": "#\n#               getopts.rb - \n#                       $Release Version: $\n#                       $Revision$\n#                       $Date$\n#                       by Yasuo OHBA(SHL Japan Inc. Technology Dept.)\n#\n# --\n# this is obsolete; use getoptlong\n#\n# 2000-03-21\n# modified by Minero Aoki <aamine@dp.u-netsurf.ne.jp>\n#\n# 2002-03-05\n# rewritten by Akinori MUSHA <knu@ruby-lang.org>\n#\n\nwarn \"Warning:#{caller[0].sub(/:in `.*'\\z/, '')}: getopts is deprecated after Ruby 1.8.1; use optparse instead\" if caller[0] and $VERBOSE\n\n$RCS_ID=%q$Header$\n\n# getopts is obsolete. Use GetoptLong.\n\ndef getopts(single_options, *options)\n  boolopts = {}\n  valopts = {}\n\n  #\n  # set defaults\n  #\n  single_options.scan(/.:?/) do |opt|\n    if opt.size == 1\n      boolopts[opt] = false\n    else\n      valopts[opt[0, 1]] = nil\n    end\n  end if single_options\n\n  options.each do |arg|\n    opt, val = arg.split(':', 2)\n\n    if val\n      valopts[opt] = val.empty? ? nil : val\n    else\n      boolopts[opt] = false\n    end\n  end\n\n  #\n  # scan\n  #\n  c = 0\n  argv = ARGV\n\n  while arg = argv.shift\n    case arg\n    when /\\A--(.*)/\n      if $1.empty?\t\t\t# xinit -- -bpp 24\n\tbreak\n      end\n\n      opt, val = $1.split('=', 2)\n\n      if opt.size == 1\n\targv.unshift arg\n\treturn nil\n      elsif valopts.key? opt\t\t# imclean --src +trash\n\tvalopts[opt] = val || argv.shift or return nil\n      elsif boolopts.key? opt\t\t# ruby --verbose\n\tboolopts[opt] = true\n      else\n\targv.unshift arg\n\treturn nil\n      end\n\n      c += 1\n    when /\\A-(.+)/\n      opts = $1\n\n      until opts.empty?\n\topt = opts.slice!(0, 1)\n\n\tif valopts.key? opt\n\t  val = opts\n\n\t  if val.empty?\t\t\t# ruby -e 'p $:'\n\t    valopts[opt] = argv.shift or return nil\n\t  else\t\t\t\t# cc -ohello ...\n\t    valopts[opt] = val\n\t  end\n\n\t  c += 1\n\t  break\n\telsif boolopts.key? opt\n\t  boolopts[opt] = true\t\t# ruby -h\n\t  c += 1\n\telse\n\t  argv.unshift arg\n\t  return nil\n\tend\n      end\n    else\n      argv.unshift arg\n      break\n    end\n  end\n\n  #\n  # set\n  #\n  $OPT = {}\n\n  boolopts.each do |opt, val|\n    $OPT[opt] = val\n\n    sopt = opt.gsub(/[^A-Za-z0-9_]/, '_')\n    eval \"$OPT_#{sopt} = val\"\n  end\n  valopts.each do |opt, val|\n    $OPT[opt] = val\n\n    sopt = opt.gsub(/[^A-Za-z0-9_]/, '_')\n    eval \"$OPT_#{sopt} = val\"\n  end\n\n  c\nend\n"
  },
  {
    "path": "lib/gserver.rb",
    "content": "#\n# Copyright (C) 2001 John W. Small All Rights Reserved\n#\n# Author::        John W. Small\n# Documentation:: Gavin Sinclair\n# Licence::       Freeware.\n#\n# See the class GServer for documentation.\n#\n\nrequire \"socket\"\nrequire \"thread\"\n\n#\n# GServer implements a generic server, featuring thread pool management,\n# simple logging, and multi-server management.  See HttpServer in \n# <tt>xmlrpc/httpserver.rb</tt> in the Ruby standard library for an example of\n# GServer in action.\n#\n# Any kind of application-level server can be implemented using this class.\n# It accepts multiple simultaneous connections from clients, up to an optional\n# maximum number.  Several _services_ (i.e. one service per TCP port) can be\n# run simultaneously, and stopped at any time through the class method\n# <tt>GServer.stop(port)</tt>.  All the threading issues are handled, saving\n# you the effort.  All events are optionally logged, but you can provide your\n# own event handlers if you wish.\n#\n# === Example\n#\n# Using GServer is simple.  Below we implement a simple time server, run it,\n# query it, and shut it down.  Try this code in +irb+:\n#\n#   require 'gserver'\n#\n#   #\n#   # A server that returns the time in seconds since 1970.\n#   # \n#   class TimeServer < GServer\n#     def initialize(port=10001, *args)\n#       super(port, *args)\n#     end\n#     def serve(io)\n#       io.puts(Time.now.to_i)\n#     end\n#   end\n#\n#   # Run the server with logging enabled (it's a separate thread).\n#   server = TimeServer.new\n#   server.audit = true                  # Turn logging on.\n#   server.start \n#\n#   # *** Now point your browser to http://localhost:10001 to see it working ***\n#\n#   # See if it's still running. \n#   GServer.in_service?(10001)           # -> true\n#   server.stopped?                      # -> false\n#\n#   # Shut the server down gracefully.\n#   server.shutdown\n#   \n#   # Alternatively, stop it immediately.\n#   GServer.stop(10001)\n#   # or, of course, \"server.stop\".\n#\n# All the business of accepting connections and exception handling is taken\n# care of.  All we have to do is implement the method that actually serves the\n# client.\n#\n# === Advanced\n#\n# As the example above shows, the way to use GServer is to subclass it to\n# create a specific server, overriding the +serve+ method.  You can override\n# other methods as well if you wish, perhaps to collect statistics, or emit\n# more detailed logging.\n#\n#   connecting\n#   disconnecting\n#   starting\n#   stopping\n#\n# The above methods are only called if auditing is enabled.\n#\n# You can also override +log+ and +error+ if, for example, you wish to use a\n# more sophisticated logging system.\n#\nclass GServer\n\n  DEFAULT_HOST = \"127.0.0.1\"\n\n  def serve(io)\n  end\n\n  @@services = {}   # Hash of opened ports, i.e. services\n  @@servicesMutex = Mutex.new\n\n  def GServer.stop(port, host = DEFAULT_HOST)\n    @@servicesMutex.synchronize {\n      @@services[host][port].stop\n    }\n  end\n\n  def GServer.in_service?(port, host = DEFAULT_HOST)\n    @@services.has_key?(host) and\n      @@services[host].has_key?(port)\n  end\n\n  def stop\n    @connectionsMutex.synchronize  {\n      if @tcpServerThread\n        @tcpServerThread.raise \"stop\"\n      end\n    }\n  end\n\n  def stopped?\n    @tcpServerThread == nil\n  end\n\n  def shutdown\n    @shutdown = true\n  end\n\n  def connections\n    @connections.size\n  end\n\n  def join\n    @tcpServerThread.join if @tcpServerThread\n  end\n\n  attr_reader :port, :host, :maxConnections\n  attr_accessor :stdlog, :audit, :debug\n\n  def connecting(client)\n    addr = client.peeraddr\n    log(\"#{self.class.to_s} #{@host}:#{@port} client:#{addr[1]} \" +\n        \"#{addr[2]}<#{addr[3]}> connect\")\n    true\n  end\n\n  def disconnecting(clientPort)\n    log(\"#{self.class.to_s} #{@host}:#{@port} \" +\n      \"client:#{clientPort} disconnect\")\n  end\n\n  protected :connecting, :disconnecting\n\n  def starting()\n    log(\"#{self.class.to_s} #{@host}:#{@port} start\")\n  end\n\n  def stopping()\n    log(\"#{self.class.to_s} #{@host}:#{@port} stop\")\n  end\n\n  protected :starting, :stopping\n\n  def error(detail)\n    log(detail.backtrace.join(\"\\n\"))\n  end\n\n  def log(msg)\n    if @stdlog\n      @stdlog.puts(\"[#{Time.new.ctime}] %s\" % msg)\n      @stdlog.flush\n    end\n  end\n\n  protected :error, :log\n\n  def initialize(port, host = DEFAULT_HOST, maxConnections = 4,\n    stdlog = $stderr, audit = false, debug = false)\n    @tcpServerThread = nil\n    @port = port\n    @host = host\n    @maxConnections = maxConnections\n    @connections = []\n    @connectionsMutex = Mutex.new\n    @connectionsCV = ConditionVariable.new\n    @stdlog = stdlog\n    @audit = audit\n    @debug = debug\n  end\n\n  def start(maxConnections = -1)\n    raise \"running\" if !stopped?\n    @shutdown = false\n    @maxConnections = maxConnections if maxConnections > 0\n    @@servicesMutex.synchronize  {\n      if GServer.in_service?(@port,@host)\n        raise \"Port already in use: #{host}:#{@port}!\"\n      end\n      @tcpServer = TCPServer.new(@host,@port)\n      @port = @tcpServer.addr[1]\n      @@services[@host] = {} unless @@services.has_key?(@host)\n      @@services[@host][@port] = self;\n    }\n    @tcpServerThread = Thread.new {\n      begin\n        starting if @audit\n        while !@shutdown\n          @connectionsMutex.synchronize  {\n             while @connections.size >= @maxConnections\n               @connectionsCV.wait(@connectionsMutex)\n             end\n          }\n          client = @tcpServer.accept\n          @connections << Thread.new(client)  { |myClient|\n            begin\n              myPort = myClient.peeraddr[1]\n              serve(myClient) if !@audit or connecting(myClient)\n            rescue => detail\n              error(detail) if @debug\n            ensure\n              begin\n                myClient.close\n              rescue\n              end\n              @connectionsMutex.synchronize {\n                @connections.delete(Thread.current)\n                @connectionsCV.signal\n              }\n              disconnecting(myPort) if @audit\n            end\n          }\n        end\n      rescue => detail\n        error(detail) if @debug\n      ensure\n        begin\n          @tcpServer.close\n        rescue\n        end\n        if @shutdown\n          @connectionsMutex.synchronize  {\n             while @connections.size > 0\n               @connectionsCV.wait(@connectionsMutex)\n             end\n          }\n        else\n          @connections.each { |c| c.raise \"stop\" }\n        end\n        @tcpServerThread = nil\n        @@servicesMutex.synchronize  {\n          @@services[@host].delete(@port)\n        }\n        stopping if @audit\n      end\n    }\n    self\n  end\n\nend\n"
  },
  {
    "path": "lib/importenv.rb",
    "content": "# importenv.rb -- imports environment variables as global variables, Perlish ;(\n#\n# Usage:\n#\n#  require 'importenv'\n#  p $USER\n#  $USER = \"matz\"\n#  p ENV[\"USER\"]\n\nwarn \"Warning:#{caller[0].sub(/:in `.*'\\z/, '')}: importenv is deprecated after Ruby 1.8.1 (no replacement)\"\n\nfor k,v in ENV\n  next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k\n  eval <<EOS\n  $#{k} = v\n  trace_var \"$#{k}\", proc{|v|\n    ENV[%q!#{k}!] = v\n    $#{k} = v\n    if v == nil\n      untrace_var \"$#{k}\"\n    end\n  }\nEOS\nend\n\nif __FILE__ == $0\n  p $TERM\n  $TERM = nil\n  p $TERM\n  p ENV[\"TERM\"]\n  $TERM = \"foo\"\n  p ENV[\"TERM\"]\nend\n"
  },
  {
    "path": "lib/ipaddr.rb",
    "content": "#\n# ipaddr.rb - A class to manipulate an IP address\n#\n# Copyright (c) 2002 Hajimu UMEMOTO <ume@mahoroba.org>.\n# Copyright (c) 2007 Akinori MUSHA <knu@iDaemons.org>.\n# All rights reserved.\n#\n# You can redistribute and/or modify it under the same terms as Ruby.\n#\n# $Id$\n#\n# Contact:\n#   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)\n#\n# TODO:\n#   - scope_id support\n#\nrequire 'socket'\n\nunless Socket.const_defined? \"AF_INET6\"\n  class Socket\n    AF_INET6 = Object.new\n  end\n\n  class << IPSocket\n    def valid_v4?(addr)\n      if /\\A(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\Z/ =~ addr\n        return $~.captures.all? {|i| i.to_i < 256}\n      end\n      return false\n    end\n\n    def valid_v6?(addr)\n      # IPv6 (normal)\n      return true if /\\A[\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*\\Z/ =~ addr\n      return true if /\\A[\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*::([\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*)?\\Z/ =~ addr\n      return true if /\\A::([\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*)?\\Z/ =~ addr\n      # IPv6 (IPv4 compat)\n      return true if /\\A[\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*:/ =~ addr && valid_v4?($')\n      return true if /\\A[\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*::([\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')\n      return true if /\\A::([\\dA-Fa-f]{1,4}(:[\\dA-Fa-f]{1,4})*:)?/ =~ addr && valid_v4?($')\n\n      false\n    end\n\n    def valid?(addr)\n      valid_v4?(addr) || valid_v6?(addr)\n    end\n\n    alias getaddress_orig getaddress\n    def getaddress(s)\n      if valid?(s)\n        s\n      elsif /\\A[-A-Za-z\\d.]+\\Z/ =~ s\n        getaddress_orig(s)\n      else\n        raise ArgumentError, \"invalid address\"\n      end\n    end\n  end\nend\n\n# IPAddr provides a set of methods to manipulate an IP address.  Both IPv4 and\n# IPv6 are supported.\n#\n# == Example\n#\n#   require 'ipaddr'\n#   \n#   ipaddr1 = IPAddr.new \"3ffe:505:2::1\"\n#   \n#   p ipaddr1\t\t\t#=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>\n#   \n#   p ipaddr1.to_s\t\t#=> \"3ffe:505:2::1\"\n#   \n#   ipaddr2 = ipaddr1.mask(48)\t#=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>\n#   \n#   p ipaddr2.to_s\t\t#=> \"3ffe:505:2::\"\n#   \n#   ipaddr3 = IPAddr.new \"192.168.2.0/24\"\n#   \n#   p ipaddr3\t\t\t#=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>\n\nclass IPAddr\n\n  IN4MASK = 0xffffffff\n  IN6MASK = 0xffffffffffffffffffffffffffffffff\n  IN6FORMAT = ([\"%.4x\"] * 8).join(':')\n\n  # Returns the address family of this IP address.\n  attr :family\n\n  # Creates a new ipaddr containing the given network byte ordered\n  # string form of an IP address.\n  def IPAddr::new_ntoh(addr)\n    return IPAddr.new(IPAddr::ntop(addr))\n  end\n\n  # Convert a network byte ordered string form of an IP address into\n  # human readable form.\n  def IPAddr::ntop(addr)\n    case addr.size\n    when 4\n      s = addr.unpack('C4').join('.')\n    when 16\n      s = IN6FORMAT % addr.unpack('n8')\n    else\n      raise ArgumentError, \"unsupported address family\"\n    end\n    return s\n  end\n\n  # Returns a new ipaddr built by bitwise AND.\n  def &(other)\n    return self.clone.set(@addr & coerce_other(other).to_i)\n  end\n\n  # Returns a new ipaddr built by bitwise OR.\n  def |(other)\n    return self.clone.set(@addr | coerce_other(other).to_i)\n  end\n\n  # Returns a new ipaddr built by bitwise right-shift.\n  def >>(num)\n    return self.clone.set(@addr >> num)\n  end\n\n  # Returns a new ipaddr built by bitwise left shift.\n  def <<(num)\n    return self.clone.set(addr_mask(@addr << num))\n  end\n\n  # Returns a new ipaddr built by bitwise negation.\n  def ~\n    return self.clone.set(addr_mask(~@addr))\n  end\n\n  # Returns true if two ipaddrs are equal.\n  def ==(other)\n    other = coerce_other(other)\n    return @family == other.family && @addr == other.to_i\n  end\n\n  # Returns a new ipaddr built by masking IP address with the given\n  # prefixlen/netmask. (e.g. 8, 64, \"255.255.255.0\", etc.)\n  def mask(prefixlen)\n    return self.clone.mask!(prefixlen)\n  end\n\n  # Returns true if the given ipaddr is in the range.\n  #\n  # e.g.:\n  #   require 'ipaddr'\n  #   net1 = IPAddr.new(\"192.168.2.0/24\")\n  #   net2 = IPAddr.new(\"192.168.2.100\")\n  #   net3 = IPAddr.new(\"192.168.3.0\")\n  #   p net1.include?(net2)\t#=> true\n  #   p net1.include?(net3)\t#=> false\n  def include?(other)\n    other = coerce_other(other)\n    if ipv4_mapped?\n      if (@mask_addr >> 32) != 0xffffffffffffffffffffffff\n\treturn false\n      end\n      mask_addr = (@mask_addr & IN4MASK)\n      addr = (@addr & IN4MASK)\n      family = Socket::AF_INET\n    else\n      mask_addr = @mask_addr\n      addr = @addr\n      family = @family\n    end\n    if other.ipv4_mapped?\n      other_addr = (other.to_i & IN4MASK)\n      other_family = Socket::AF_INET\n    else\n      other_addr = other.to_i\n      other_family = other.family\n    end\n\n    if family != other_family\n      return false\n    end\n    return ((addr & mask_addr) == (other_addr & mask_addr))\n  end\n  alias === include?\n\n  # Returns the integer representation of the ipaddr.\n  def to_i\n    return @addr\n  end\n\n  # Returns a string containing the IP address representation.\n  def to_s\n    str = to_string\n    return str if ipv4?\n\n    str.gsub!(/\\b0{1,3}([\\da-f]+)\\b/i, '\\1')\n    loop do\n      break if str.sub!(/\\A0:0:0:0:0:0:0:0\\Z/, '::')\n      break if str.sub!(/\\b0:0:0:0:0:0:0\\b/, ':')\n      break if str.sub!(/\\b0:0:0:0:0:0\\b/, ':')\n      break if str.sub!(/\\b0:0:0:0:0\\b/, ':')\n      break if str.sub!(/\\b0:0:0:0\\b/, ':')\n      break if str.sub!(/\\b0:0:0\\b/, ':')\n      break if str.sub!(/\\b0:0\\b/, ':')\n      break\n    end\n    str.sub!(/:{3,}/, '::')\n\n    if /\\A::(ffff:)?([\\da-f]{1,4}):([\\da-f]{1,4})\\Z/i =~ str\n      str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)\n    end\n\n    str\n  end\n\n  # Returns a string containing the IP address representation in\n  # canonical form.\n  def to_string\n    return _to_string(@addr)\n  end\n\n  # Returns a network byte ordered string form of the IP address.\n  def hton\n    case @family\n    when Socket::AF_INET\n      return [@addr].pack('N')\n    when Socket::AF_INET6\n      return (0..7).map { |i|\n\t(@addr >> (112 - 16 * i)) & 0xffff\n      }.pack('n8')\n    else\n      raise \"unsupported address family\"\n    end\n  end\n\n  # Returns true if the ipaddr is an IPv4 address.\n  def ipv4?\n    return @family == Socket::AF_INET\n  end\n\n  # Returns true if the ipaddr is an IPv6 address.\n  def ipv6?\n    return @family == Socket::AF_INET6\n  end\n\n  # Returns true if the ipaddr is an IPv4-mapped IPv6 address.\n  def ipv4_mapped?\n    return ipv6? && (@addr >> 32) == 0xffff\n  end\n\n  # Returns true if the ipaddr is an IPv4-compatible IPv6 address.\n  def ipv4_compat?\n    if !ipv6? || (@addr >> 32) != 0\n      return false\n    end\n    a = (@addr & IN4MASK)\n    return a != 0 && a != 1\n  end\n\n  # Returns a new ipaddr built by converting the native IPv4 address\n  # into an IPv4-mapped IPv6 address.\n  def ipv4_mapped\n    if !ipv4?\n      raise ArgumentError, \"not an IPv4 address\"\n    end\n    return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)\n  end\n\n  # Returns a new ipaddr built by converting the native IPv4 address\n  # into an IPv4-compatible IPv6 address.\n  def ipv4_compat\n    if !ipv4?\n      raise ArgumentError, \"not an IPv4 address\"\n    end\n    return self.clone.set(@addr, Socket::AF_INET6)\n  end\n\n  # Returns a new ipaddr built by converting the IPv6 address into a\n  # native IPv4 address.  If the IP address is not an IPv4-mapped or\n  # IPv4-compatible IPv6 address, returns self.\n  def native\n    if !ipv4_mapped? && !ipv4_compat?\n      return self\n    end\n    return self.clone.set(@addr & IN4MASK, Socket::AF_INET)\n  end\n\n  # Returns a string for DNS reverse lookup.  It returns a string in\n  # RFC3172 form for an IPv6 address.\n  def reverse\n    case @family\n    when Socket::AF_INET\n      return _reverse + \".in-addr.arpa\"\n    when Socket::AF_INET6\n      return ip6_arpa\n    else\n      raise \"unsupported address family\"\n    end\n  end\n\n  # Returns a string for DNS reverse lookup compatible with RFC3172.\n  def ip6_arpa\n    if !ipv6?\n      raise ArgumentError, \"not an IPv6 address\"\n    end\n    return _reverse + \".ip6.arpa\"\n  end\n\n  # Returns a string for DNS reverse lookup compatible with RFC1886.\n  def ip6_int\n    if !ipv6?\n      raise ArgumentError, \"not an IPv6 address\"\n    end\n    return _reverse + \".ip6.int\"\n  end\n\n  # Returns the successor to the ipaddr.\n  def succ\n    return self.clone.set(@addr + 1, @family)\n  end\n\n  # Compares the ipaddr with another.\n  def <=>(other)\n    other = coerce_other(other)\n\n    return nil if other.family != @family\n\n    return @addr <=> other.to_i\n  end\n  include Comparable\n\n  # Creates a Range object for the network address.\n  def to_range\n    begin_addr = (@addr & @mask_addr)\n\n    case @family\n    when Socket::AF_INET\n      end_addr = (@addr | (IN4MASK ^ @mask_addr))\n    when Socket::AF_INET6\n      end_addr = (@addr | (IN6MASK ^ @mask_addr))\n    else\n      raise \"unsupported address family\"\n    end\n\n    return clone.set(begin_addr, @family)..clone.set(end_addr, @family)\n  end\n\n  # Returns a string containing a human-readable representation of the\n  # ipaddr. (\"#<IPAddr: family:address/mask>\")\n  def inspect\n    case @family\n    when Socket::AF_INET\n      af = \"IPv4\"\n    when Socket::AF_INET6\n      af = \"IPv6\"\n    else\n      raise \"unsupported address family\"\n    end\n    return sprintf(\"#<%s: %s:%s/%s>\", self.class.name,\n\t\t   af, _to_string(@addr), _to_string(@mask_addr))\n  end\n\n  protected\n\n  def set(addr, *family)\n    case family[0] ? family[0] : @family\n    when Socket::AF_INET\n      if addr < 0 || addr > IN4MASK\n\traise ArgumentError, \"invalid address\"\n      end\n    when Socket::AF_INET6\n      if addr < 0 || addr > IN6MASK\n\traise ArgumentError, \"invalid address\"\n      end\n    else\n      raise ArgumentError, \"unsupported address family\"\n    end\n    @addr = addr\n    if family[0]\n      @family = family[0]\n    end\n    return self\n  end\n\n  def mask!(mask)\n    if mask.kind_of?(String)\n      if mask =~ /^\\d+$/\n\tprefixlen = mask.to_i\n      else\n\tm = IPAddr.new(mask)\n\tif m.family != @family\n\t  raise ArgumentError, \"address family is not same\"\n\tend\n\t@mask_addr = m.to_i\n\t@addr &= @mask_addr\n\treturn self\n      end\n    else\n      prefixlen = mask\n    end\n    case @family\n    when Socket::AF_INET\n      if prefixlen < 0 || prefixlen > 32\n\traise ArgumentError, \"invalid length\"\n      end\n      masklen = 32 - prefixlen\n      @mask_addr = ((IN4MASK >> masklen) << masklen)\n    when Socket::AF_INET6\n      if prefixlen < 0 || prefixlen > 128\n\traise ArgumentError, \"invalid length\"\n      end\n      masklen = 128 - prefixlen\n      @mask_addr = ((IN6MASK >> masklen) << masklen)\n    else\n      raise \"unsupported address family\"\n    end\n    @addr = ((@addr >> masklen) << masklen)\n    return self\n  end\n\n  private\n\n  # Creates a new ipaddr object either from a human readable IP\n  # address representation in string, or from a packed in_addr value\n  # followed by an address family.\n  # \n  # In the former case, the following are the valid formats that will\n  # be recognized: \"address\", \"address/prefixlen\" and \"address/mask\",\n  # where IPv6 address may be enclosed in square brackets (`[' and\n  # `]').  If a prefixlen or a mask is specified, it returns a masked\n  # IP address.  Although the address family is determined\n  # automatically from a specified string, you can specify one\n  # explicitly by the optional second argument.\n  # \n  # Otherwise an IP addess is generated from a packed in_addr value\n  # and an address family.\n  #\n  # The IPAddr class defines many methods and operators, and some of\n  # those, such as &, |, include? and ==, accept a string, or a packed\n  # in_addr value instead of an IPAddr object.\n  def initialize(addr = '::', family = Socket::AF_UNSPEC)\n    if !addr.kind_of?(String)\n      case family\n      when Socket::AF_INET, Socket::AF_INET6\n        set(addr.to_i, family)\n        @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK\n        return\n      when Socket::AF_UNSPEC\n\traise ArgumentError, \"address family must be specified\"\n      else\n\traise ArgumentError, \"unsupported address family: #{family}\"\n      end\n    end\n    prefix, prefixlen = addr.split('/')\n    if prefix =~ /^\\[(.*)\\]$/i\n      prefix = $1\n      family = Socket::AF_INET6\n    end\n    # It seems AI_NUMERICHOST doesn't do the job.\n    #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,\n    #\t\t       Socket::AI_NUMERICHOST)\n    begin\n      IPSocket.getaddress(prefix)\t\t# test if address is vaild\n    rescue\n      raise ArgumentError, \"invalid address\"\n    end\n    @addr = @family = nil\n    if family == Socket::AF_UNSPEC || family == Socket::AF_INET\n      @addr = in_addr(prefix)\n      if @addr\n\t@family = Socket::AF_INET\n      end\n    end\n    if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)\n      @addr = in6_addr(prefix)\n      @family = Socket::AF_INET6\n    end\n    if family != Socket::AF_UNSPEC && @family != family\n      raise ArgumentError, \"address family mismatch\"\n    end\n    if prefixlen\n      mask!(prefixlen)\n    else\n      @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK\n    end\n  end\n\n  def coerce_other(other)\n    case other\n    when IPAddr\n      other\n    when String\n      self.class.new(other)\n    else\n      self.class.new(other, @family)\n    end\n  end\n\n  def in_addr(addr)\n    if addr =~ /^\\d+\\.\\d+\\.\\d+\\.\\d+$/\n      return addr.split('.').inject(0) { |i, s|\n        i << 8 | s.to_i\n      }\n    end\n    return nil\n  end\n\n  def in6_addr(left)\n    case left\n    when /^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i\n      return in_addr($1) + 0xffff00000000\n    when /^::(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i\n      return in_addr($1)\n    when /[^0-9a-f:]/i\n      raise ArgumentError, \"invalid address\"\n    when /^(.*)::(.*)$/\n      left, right = $1, $2\n    else\n      right = ''\n    end\n    l = left.split(':')\n    r = right.split(':')\n    rest = 8 - l.size - r.size\n    if rest < 0\n      return nil\n    end\n    return (l + Array.new(rest, '0') + r).inject(0) { |i, s|\n      i << 16 | s.hex\n    }\n  end\n\n  def addr_mask(addr)\n    case @family\n    when Socket::AF_INET\n      return addr & IN4MASK\n    when Socket::AF_INET6\n      return addr & IN6MASK\n    else\n      raise \"unsupported address family\"\n    end\n  end\n\n  def _reverse\n    case @family\n    when Socket::AF_INET\n      return (0..3).map { |i|\n\t(@addr >> (8 * i)) & 0xff\n      }.join('.')\n    when Socket::AF_INET6\n      return (\"%.32x\" % @addr).reverse!.gsub!(/.(?!$)/, '\\&.')\n    else\n      raise \"unsupported address family\"\n    end\n  end\n\n  def _to_string(addr)\n    case @family\n    when Socket::AF_INET\n      return (0..3).map { |i|\n\t(addr >> (24 - 8 * i)) & 0xff\n      }.join('.')\n    when Socket::AF_INET6\n      return ((\"%.32x\" % addr).gsub!(/.{4}(?!$)/, '\\&:'))\n    else\n      raise \"unsupported address family\"\n    end\n  end\n\nend\n\nif $0 == __FILE__\n  eval DATA.read, nil, $0, __LINE__+4\nend\n\n__END__\n\nrequire 'test/unit'\nrequire 'test/unit/ui/console/testrunner'\n\nclass TC_IPAddr < Test::Unit::TestCase\n  def test_s_new\n    assert_nothing_raised {\n      IPAddr.new(\"3FFE:505:ffff::/48\")\n      IPAddr.new(\"0:0:0:1::\")\n      IPAddr.new(\"2001:200:300::/48\")\n    }\n\n    a = IPAddr.new\n    assert_equal(\"::\", a.to_s)\n    assert_equal(\"0000:0000:0000:0000:0000:0000:0000:0000\", a.to_string)\n    assert_equal(Socket::AF_INET6, a.family)\n\n    a = IPAddr.new(\"0123:4567:89ab:cdef:0ABC:DEF0:1234:5678\")\n    assert_equal(\"123:4567:89ab:cdef:abc:def0:1234:5678\", a.to_s)\n    assert_equal(\"0123:4567:89ab:cdef:0abc:def0:1234:5678\", a.to_string)\n    assert_equal(Socket::AF_INET6, a.family)\n\n    a = IPAddr.new(\"3ffe:505:2::/48\")\n    assert_equal(\"3ffe:505:2::\", a.to_s)\n    assert_equal(\"3ffe:0505:0002:0000:0000:0000:0000:0000\", a.to_string)\n    assert_equal(Socket::AF_INET6, a.family)\n    assert_equal(false, a.ipv4?)\n    assert_equal(true, a.ipv6?)\n    assert_equal(\"#<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>\", a.inspect)\n\n    a = IPAddr.new(\"3ffe:505:2::/ffff:ffff:ffff::\")\n    assert_equal(\"3ffe:505:2::\", a.to_s)\n    assert_equal(\"3ffe:0505:0002:0000:0000:0000:0000:0000\", a.to_string)\n    assert_equal(Socket::AF_INET6, a.family)\n\n    a = IPAddr.new(\"0.0.0.0\")\n    assert_equal(\"0.0.0.0\", a.to_s)\n    assert_equal(\"0.0.0.0\", a.to_string)\n    assert_equal(Socket::AF_INET, a.family)\n\n    a = IPAddr.new(\"192.168.1.2\")\n    assert_equal(\"192.168.1.2\", a.to_s)\n    assert_equal(\"192.168.1.2\", a.to_string)\n    assert_equal(Socket::AF_INET, a.family)\n    assert_equal(true, a.ipv4?)\n    assert_equal(false, a.ipv6?)\n\n    a = IPAddr.new(\"192.168.1.2/24\")\n    assert_equal(\"192.168.1.0\", a.to_s)\n    assert_equal(\"192.168.1.0\", a.to_string)\n    assert_equal(Socket::AF_INET, a.family)\n    assert_equal(\"#<IPAddr: IPv4:192.168.1.0/255.255.255.0>\", a.inspect)\n\n    a = IPAddr.new(\"192.168.1.2/255.255.255.0\")\n    assert_equal(\"192.168.1.0\", a.to_s)\n    assert_equal(\"192.168.1.0\", a.to_string)\n    assert_equal(Socket::AF_INET, a.family)\n\n    assert_equal(\"0:0:0:1::\", IPAddr.new(\"0:0:0:1::\").to_s)\n    assert_equal(\"2001:200:300::\", IPAddr.new(\"2001:200:300::/48\").to_s)\n\n    assert_equal(\"2001:200:300::\", IPAddr.new(\"[2001:200:300::]/48\").to_s)\n\n    [\n      [\"fe80::1%fxp0\"],\n      [\"::1/255.255.255.0\"],\n      [\"::1:192.168.1.2/120\"],\n      [IPAddr.new(\"::1\").to_i],\n      [\"::ffff:192.168.1.2/120\", Socket::AF_INET],\n      [\"[192.168.1.2]/120\"],\n    ].each { |args|\n      assert_raises(ArgumentError) {\n\tIPAddr.new(*args)\n      }\n    }\n  end\n\n  def test_s_new_ntoh\n    addr = ''\n    IPAddr.new(\"1234:5678:9abc:def0:1234:5678:9abc:def0\").hton.each_byte { |c|\n      addr += sprintf(\"%02x\", c)\n    }\n    assert_equal(\"123456789abcdef0123456789abcdef0\", addr)\n    addr = ''\n    IPAddr.new(\"123.45.67.89\").hton.each_byte { |c|\n      addr += sprintf(\"%02x\", c)\n    }\n    assert_equal(sprintf(\"%02x%02x%02x%02x\", 123, 45, 67, 89), addr)\n    a = IPAddr.new(\"3ffe:505:2::\")\n    assert_equal(\"3ffe:505:2::\", IPAddr.new_ntoh(a.hton).to_s)\n    a = IPAddr.new(\"192.168.2.1\")\n    assert_equal(\"192.168.2.1\", IPAddr.new_ntoh(a.hton).to_s)\n  end\n\n  def test_ipv4_compat\n    a = IPAddr.new(\"::192.168.1.2\")\n    assert_equal(\"::192.168.1.2\", a.to_s)\n    assert_equal(\"0000:0000:0000:0000:0000:0000:c0a8:0102\", a.to_string)\n    assert_equal(Socket::AF_INET6, a.family)\n    assert_equal(true, a.ipv4_compat?)\n    b = a.native\n    assert_equal(\"192.168.1.2\", b.to_s)\n    assert_equal(Socket::AF_INET, b.family)\n    assert_equal(false, b.ipv4_compat?)\n\n    a = IPAddr.new(\"192.168.1.2\")\n    b = a.ipv4_compat\n    assert_equal(\"::192.168.1.2\", b.to_s)\n    assert_equal(Socket::AF_INET6, b.family)\n  end\n\n  def test_ipv4_mapped\n    a = IPAddr.new(\"::ffff:192.168.1.2\")\n    assert_equal(\"::ffff:192.168.1.2\", a.to_s)\n    assert_equal(\"0000:0000:0000:0000:0000:ffff:c0a8:0102\", a.to_string)\n    assert_equal(Socket::AF_INET6, a.family)\n    assert_equal(true, a.ipv4_mapped?)\n    b = a.native\n    assert_equal(\"192.168.1.2\", b.to_s)\n    assert_equal(Socket::AF_INET, b.family)\n    assert_equal(false, b.ipv4_mapped?)\n\n    a = IPAddr.new(\"192.168.1.2\")\n    b = a.ipv4_mapped\n    assert_equal(\"::ffff:192.168.1.2\", b.to_s)\n    assert_equal(Socket::AF_INET6, b.family)\n  end\n\n  def test_reverse\n    assert_equal(\"f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa\", IPAddr.new(\"3ffe:505:2::f\").reverse)\n    assert_equal(\"1.2.168.192.in-addr.arpa\", IPAddr.new(\"192.168.2.1\").reverse)\n  end\n\n  def test_ip6_arpa\n    assert_equal(\"f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa\", IPAddr.new(\"3ffe:505:2::f\").ip6_arpa)\n    assert_raises(ArgumentError) {\n      IPAddr.new(\"192.168.2.1\").ip6_arpa\n    }\n  end\n\n  def test_ip6_int\n    assert_equal(\"f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int\", IPAddr.new(\"3ffe:505:2::f\").ip6_int)\n    assert_raises(ArgumentError) {\n      IPAddr.new(\"192.168.2.1\").ip6_int\n    }\n  end\n\n  def test_to_s\n    assert_equal(\"3ffe:0505:0002:0000:0000:0000:0000:0001\", IPAddr.new(\"3ffe:505:2::1\").to_string)\n    assert_equal(\"3ffe:505:2::1\", IPAddr.new(\"3ffe:505:2::1\").to_s)\n  end\nend\n\nclass TC_Operator < Test::Unit::TestCase\n\n  IN6MASK32  = \"ffff:ffff::\"\n  IN6MASK128 = \"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\"\n\n  def setup\n    @in6_addr_any = IPAddr.new()\n    @a = IPAddr.new(\"3ffe:505:2::/48\")\n    @b = IPAddr.new(\"0:0:0:1::\")\n    @c = IPAddr.new(IN6MASK32)\n  end\n  alias set_up setup\n\n  def test_or\n    assert_equal(\"3ffe:505:2:1::\", (@a | @b).to_s)\n    a = @a\n    a |= @b\n    assert_equal(\"3ffe:505:2:1::\", a.to_s)\n    assert_equal(\"3ffe:505:2::\", @a.to_s)\n    assert_equal(\"3ffe:505:2:1::\",\n\t\t (@a | 0x00000000000000010000000000000000).to_s)\n  end\n\n  def test_and\n    assert_equal(\"3ffe:505::\", (@a & @c).to_s)\n    a = @a\n    a &= @c\n    assert_equal(\"3ffe:505::\", a.to_s)\n    assert_equal(\"3ffe:505:2::\", @a.to_s)\n    assert_equal(\"3ffe:505::\", (@a & 0xffffffff000000000000000000000000).to_s)\n  end\n\n  def test_shift_right\n    assert_equal(\"0:3ffe:505:2::\", (@a >> 16).to_s)\n    a = @a\n    a >>= 16\n    assert_equal(\"0:3ffe:505:2::\", a.to_s)\n    assert_equal(\"3ffe:505:2::\", @a.to_s)\n  end\n\n  def test_shift_left\n    assert_equal(\"505:2::\", (@a << 16).to_s)\n    a = @a\n    a <<= 16\n    assert_equal(\"505:2::\", a.to_s)\n    assert_equal(\"3ffe:505:2::\", @a.to_s)\n  end\n\n  def test_carrot\n    a = ~@in6_addr_any\n    assert_equal(IN6MASK128, a.to_s)\n    assert_equal(\"::\", @in6_addr_any.to_s)\n  end\n\n  def test_equal\n    assert_equal(true, @a == IPAddr.new(\"3ffe:505:2::\"))\n    assert_equal(false, @a == IPAddr.new(\"3ffe:505:3::\"))\n    assert_equal(true, @a != IPAddr.new(\"3ffe:505:3::\"))\n    assert_equal(false, @a != IPAddr.new(\"3ffe:505:2::\"))\n  end\n\n  def test_mask\n    a = @a.mask(32)\n    assert_equal(\"3ffe:505::\", a.to_s)\n    assert_equal(\"3ffe:505:2::\", @a.to_s)\n  end\n\n  def test_include?\n    assert_equal(true, @a.include?(IPAddr.new(\"3ffe:505:2::\")))\n    assert_equal(true, @a.include?(IPAddr.new(\"3ffe:505:2::1\")))\n    assert_equal(false, @a.include?(IPAddr.new(\"3ffe:505:3::\")))\n    net1 = IPAddr.new(\"192.168.2.0/24\")\n    assert_equal(true, net1.include?(IPAddr.new(\"192.168.2.0\")))\n    assert_equal(true, net1.include?(IPAddr.new(\"192.168.2.255\")))\n    assert_equal(false, net1.include?(IPAddr.new(\"192.168.3.0\")))\n    # test with integer parameter\n    int = (192 << 24) + (168 << 16) + (2 << 8) + 13\n\n    assert_equal(true, net1.include?(int))\n    assert_equal(false, net1.include?(int+255))\n\n  end\n\nend\n"
  },
  {
    "path": "lib/irb/cmd/chws.rb",
    "content": "#\n#   change-ws.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"irb/cmd/nop.rb\"\nrequire \"irb/ext/change-ws.rb\"\n\nmodule IRB\n  module ExtendCommand\n\n    class CurrentWorkingWorkspace<Nop\n      def execute(*obj)\n\tirb_context.main\n      end\n    end\n\n    class ChangeWorkspace<Nop\n      def execute(*obj)\n\tirb_context.change_workspace(*obj)\n\tirb_context.main\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/cmd/fork.rb",
    "content": "#\n#   fork.rb - \n#   \t$Release Version: 0.9.5 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\n@RCS_ID='-$Id$-'\n\n\nmodule IRB\n  module ExtendCommand\n    class Fork<Nop\n      def execute(&block)\n\tpid = send ExtendCommand.irb_original_method_name(\"fork\")\n\tunless pid \n\t  class<<self\n\t    alias_method :exit, ExtendCommand.irb_original_method_name('exit')\n\t  end\n\t  if iterator?\n\t    begin\n\t      yield\n\t    ensure\n\t      exit\n\t    end\n\t  end\n\tend\n\tpid\n      end\n    end\n  end\nend\n\n\n"
  },
  {
    "path": "lib/irb/cmd/help.rb",
    "content": "#\n#   help.rb - helper using ri\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#\n# --\n#\n#   \n#\n\nrequire 'rdoc/ri/ri_driver'\n\nmodule IRB\n  module ExtendCommand\n    module Help\n      begin\n        @ri = RiDriver.new\n      rescue SystemExit\n      else\n        def self.execute(context, *names)\n          names.each do |name|\n            begin\n              @ri.get_info_for(name.to_s)\n            rescue RiError\n              puts $!.message\n            end\n          end\n          nil\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/irb/cmd/load.rb",
    "content": "#\n#   load.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"irb/cmd/nop.rb\"\nrequire \"irb/ext/loader\"\n\nmodule IRB\n  module ExtendCommand\n    class Load<Nop\n      include IrbLoader\n\n      def execute(file_name, priv = nil)\n#\treturn ruby_load(file_name) unless IRB.conf[:USE_LOADER]\n\treturn irb_load(file_name, priv)\n      end\n    end\n\n    class Require<Nop\n      include IrbLoader\n      \n      def execute(file_name)\n#\treturn ruby_require(file_name) unless IRB.conf[:USE_LOADER]\n\n\trex = Regexp.new(\"#{Regexp.quote(file_name)}(\\.o|\\.rb)?\")\n\treturn false if $\".find{|f| f =~ rex}\n\n\tcase file_name\n\twhen /\\.rb$/\n\t  begin\n\t    if irb_load(file_name)\n\t      $\".push file_name\n\t      return true\n\t    end\n\t  rescue LoadError\n\t  end\n\twhen /\\.(so|o|sl)$/\n\t  return ruby_require(file_name)\n\tend\n\t\n\tbegin\n\t  irb_load(f = file_name + \".rb\")\n\t  $\".push f\n\t  return true\n\trescue LoadError\n\t  return ruby_require(file_name)\n\tend\n      end\n    end\n\n    class Source<Nop\n      include IrbLoader\n      def execute(file_name)\n\tsource_file(file_name)\n      end\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/irb/cmd/nop.rb",
    "content": "#\n#   nop.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nmodule IRB\n  module ExtendCommand\n    class Nop\n      \n      @RCS_ID='-$Id$-'\n\n      def self.execute(conf, *opts)\n\tcommand = new(conf)\n\tcommand.execute(*opts)\n      end\n\n      def initialize(conf)\n\t@irb_context = conf\n      end\n\n      attr_reader :irb_context\n\n      def irb\n\t@irb_context.irb\n      end\n\n      def execute(*opts)\n\t#nop\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/cmd/pushws.rb",
    "content": "#\n#   change-ws.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"irb/cmd/nop.rb\"\nrequire \"irb/ext/workspaces.rb\"\n\nmodule IRB\n  module ExtendCommand\n    class Workspaces<Nop\n      def execute(*obj)\n\tirb_context.workspaces.collect{|ws| ws.main}\n      end\n    end\n\n    class PushWorkspace<Workspaces\n      def execute(*obj)\n\tirb_context.push_workspace(*obj)\n\tsuper\n      end\n    end\n\n    class PopWorkspace<Workspaces\n      def execute(*obj)\n\tirb_context.pop_workspace(*obj)\n\tsuper\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/cmd/subirb.rb",
    "content": "#!/usr/local/bin/ruby\n#\n#   multi.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"irb/cmd/nop.rb\"\nrequire \"irb/ext/multi-irb\"\n\nmodule IRB\n  module ExtendCommand\n    class IrbCommand<Nop\n      def execute(*obj)\n\tIRB.irb(nil, *obj)\n      end\n    end\n\n    class Jobs<Nop\n      def execute\n\tIRB.JobManager\n      end\n    end\n\n    class Foreground<Nop\n      def execute(key)\n\tIRB.JobManager.switch(key)\n      end\n    end\n\n    class Kill<Nop\n      def execute(*keys)\n\tIRB.JobManager.kill(*keys)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/irb/completion.rb",
    "content": "#\n#   irb/completor.rb - \n#   \t$Release Version: 0.9$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n#       From Original Idea of shugo@ruby-lang.org\n#\n\nrequire \"readline\"\n\nmodule IRB\n  module InputCompletor\n\n    @RCS_ID='-$Id$-'\n\n    ReservedWords = [\n      \"BEGIN\", \"END\",\n      \"alias\", \"and\", \n      \"begin\", \"break\", \n      \"case\", \"class\",\n      \"def\", \"defined\", \"do\",\n      \"else\", \"elsif\", \"end\", \"ensure\",\n      \"false\", \"for\", \n      \"if\", \"in\", \n      \"module\", \n      \"next\", \"nil\", \"not\",\n      \"or\", \n      \"redo\", \"rescue\", \"retry\", \"return\",\n      \"self\", \"super\",\n      \"then\", \"true\",\n      \"undef\", \"unless\", \"until\",\n      \"when\", \"while\",\n      \"yield\",\n    ]\n      \n    CompletionProc = proc { |input|\n      bind = IRB.conf[:MAIN_CONTEXT].workspace.binding\n      \n#      puts \"input: #{input}\"\n\n      case input\n      when /^(\\/[^\\/]*\\/)\\.([^.]*)$/\n\t# Regexp\n\treceiver = $1\n\tmessage = Regexp.quote($2)\n\n\tcandidates = Regexp.instance_methods(true)\n\tselect_message(receiver, message, candidates)\n\n      when /^([^\\]]*\\])\\.([^.]*)$/\n\t# Array\n\treceiver = $1\n\tmessage = Regexp.quote($2)\n\n\tcandidates = Array.instance_methods(true)\n\tselect_message(receiver, message, candidates)\n\n      when /^([^\\}]*\\})\\.([^.]*)$/\n\t# Proc or Hash\n\treceiver = $1\n\tmessage = Regexp.quote($2)\n\n\tcandidates = Proc.instance_methods(true) | Hash.instance_methods(true)\n\tselect_message(receiver, message, candidates)\n\t\n      when /^(:[^:.]*)$/\n \t# Symbol\n\tif Symbol.respond_to?(:all_symbols)\n\t  sym = $1\n\t  candidates = Symbol.all_symbols.collect{|s| \":\" + s.id2name}\n\t  candidates.grep(/^#{sym}/)\n\telse\n\t  []\n\tend\n\n      when /^::([A-Z][^:\\.\\(]*)$/\n\t# Absolute Constant or class methods\n\treceiver = $1\n\tcandidates = Object.constants\n\tcandidates.grep(/^#{receiver}/).collect{|e| \"::\" + e}\n\n      when /^(((::)?[A-Z][^:.\\(]*)+)::?([^:.]*)$/\n\t# Constant or class methods\n\treceiver = $1\n\tmessage = Regexp.quote($4)\n\tbegin\n\t  candidates = eval(\"#{receiver}.constants | #{receiver}.methods\", bind)\n\trescue Exception\n\t  candidates = []\n\tend\n\tcandidates.grep(/^#{message}/).collect{|e| receiver + \"::\" + e}\n\n      when /^(:[^:.]+)\\.([^.]*)$/\n\t# Symbol\n\treceiver = $1\n\tmessage = Regexp.quote($2)\n\n\tcandidates = Symbol.instance_methods(true)\n\tselect_message(receiver, message, candidates)\n\n      when /^(-?(0[dbo])?[0-9_]+(\\.[0-9_]+)?([eE]-?[0-9]+)?)\\.([^.]*)$/\n\t# Numeric\n\treceiver = $1\n\tmessage = Regexp.quote($5)\n\n\tbegin\n\t  candidates = eval(receiver, bind).methods\n\trescue Exception\n\t  candidates = []\n\tend\n\tselect_message(receiver, message, candidates)\n\n      when /^(-?0x[0-9a-fA-F_]+)\\.([^.]*)$/\n\t# Numeric(0xFFFF)\n\treceiver = $1\n\tmessage = Regexp.quote($2)\n\n\tbegin\n\t  candidates = eval(receiver, bind).methods\n\trescue Exception\n\t  candidates = []\n\tend\n\tselect_message(receiver, message, candidates)\n\n      when /^(\\$[^.]*)$/\n\tcandidates = global_variables.grep(Regexp.new(Regexp.quote($1)))\n\n#      when /^(\\$?(\\.?[^.]+)+)\\.([^.]*)$/\n      when /^((\\.?[^.]+)+)\\.([^.]*)$/\n\t# variable\n\treceiver = $1\n\tmessage = Regexp.quote($3)\n\n\tgv = eval(\"global_variables\", bind)\n\tlv = eval(\"local_variables\", bind)\n\tcv = eval(\"self.class.constants\", bind)\n\t\n\tif (gv | lv | cv).include?(receiver)\n\t  # foo.func and foo is local var.\n\t  candidates = eval(\"#{receiver}.methods\", bind)\n\telsif /^[A-Z]/ =~ receiver and /\\./ !~ receiver\n\t  # Foo::Bar.func\n\t  begin\n\t    candidates = eval(\"#{receiver}.methods\", bind)\n\t  rescue Exception\n\t    candidates = []\n\t  end\n\telse\n\t  # func1.func2\n\t  candidates = []\n\t  ObjectSpace.each_object(Module){|m|\n\t    begin\n\t      name = m.name\n\t    rescue Exception\n\t      name = \"\"\n\t    end\n\t    next if name != \"IRB::Context\" and \n\t      /^(IRB|SLex|RubyLex|RubyToken)/ =~ name\n\t    candidates.concat m.instance_methods(false)\n\t  }\n\t  candidates.sort!\n\t  candidates.uniq!\n\tend\n\tselect_message(receiver, message, candidates)\n\n      when /^\\.([^.]*)$/\n\t# unknown(maybe String)\n\n\treceiver = \"\"\n\tmessage = Regexp.quote($1)\n\n\tcandidates = String.instance_methods(true)\n\tselect_message(receiver, message, candidates)\n\n      else\n\tcandidates = eval(\"methods | private_methods | local_variables | self.class.constants\", bind)\n\t\t\t  \n\t(candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)\n      end\n    }\n\n    Operators = [\"%\", \"&\", \"*\", \"**\", \"+\",  \"-\",  \"/\",\n      \"<\", \"<<\", \"<=\", \"<=>\", \"==\", \"===\", \"=~\", \">\", \">=\", \">>\",\n      \"[]\", \"[]=\", \"^\",]\n\n    def self.select_message(receiver, message, candidates)\n      candidates.grep(/^#{message}/).collect do |e|\n\tcase e\n\twhen /^[a-zA-Z_]/\n\t  receiver + \".\" + e\n\twhen /^[0-9]/\n\twhen *Operators\n\t  #receiver + \" \" + e\n\tend\n      end\n    end\n  end\nend\n\nif Readline.respond_to?(\"basic_word_break_characters=\")\n  Readline.basic_word_break_characters= \" \\t\\n\\\"\\\\'`><=;|&{(\"\nend\nReadline.completion_append_character = nil\nReadline.completion_proc = IRB::InputCompletor::CompletionProc\n"
  },
  {
    "path": "lib/irb/context.rb",
    "content": "#\n#   irb/context.rb - irb context\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nrequire \"irb/workspace\"\n\nmodule IRB\n  class Context\n    #\n    # Arguments:\n    #   input_method: nil -- stdin or readline\n    #\t\t      String -- File\n    #\t\t      other -- using this as InputMethod\n    #\n    def initialize(irb, workspace = nil, input_method = nil, output_method = nil)\n      @irb = irb\n      if workspace\n\t@workspace = workspace\n      else\n\t@workspace = WorkSpace.new\n      end\n      @thread = Thread.current if defined? Thread\n#      @irb_level = 0\n\n      # copy of default configuration\n      @ap_name = IRB.conf[:AP_NAME]\n      @rc = IRB.conf[:RC]\n      @load_modules = IRB.conf[:LOAD_MODULES]\n\n      @use_readline = IRB.conf[:USE_READLINE]\n      @inspect_mode = IRB.conf[:INSPECT_MODE]\n\n      self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE]\n      self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]\n      self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]\n      self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]\n\n      @ignore_sigint = IRB.conf[:IGNORE_SIGINT]\n      @ignore_eof = IRB.conf[:IGNORE_EOF]\n\n      @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT]\n      \n      self.prompt_mode = IRB.conf[:PROMPT_MODE]\n\n      if IRB.conf[:SINGLE_IRB] or !defined?(JobManager)\n\t@irb_name = IRB.conf[:IRB_NAME]\n      else\n\t@irb_name = \"irb#\"+IRB.JobManager.n_jobs.to_s\n      end\n      @irb_path = \"(\" + @irb_name + \")\"\n\n      case input_method\n      when nil\n\tcase use_readline?\n\twhen nil\n\t  if (defined?(ReadlineInputMethod) && STDIN.tty? &&\n\t      IRB.conf[:PROMPT_MODE] != :INF_RUBY)\n\t    @io = ReadlineInputMethod.new\n\t  else\n\t    @io = StdioInputMethod.new\n\t  end\n\twhen false\n\t  @io = StdioInputMethod.new\n\twhen true\n\t  if defined?(ReadlineInputMethod)\n\t    @io = ReadlineInputMethod.new\n\t  else\n\t    @io = StdioInputMethod.new\n\t  end\n\tend\n\n      when String\n\t@io = FileInputMethod.new(input_method)\n\t@irb_name = File.basename(input_method)\n\t@irb_path = input_method\n      else\n\t@io = input_method\n      end\n      self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]\n\n      if output_method\n\t@output_method = output_method\n      else\n\t@output_method = StdioOutputMethod.new\n      end\n\n      @verbose = IRB.conf[:VERBOSE] \n      @echo = IRB.conf[:ECHO]\n      if @echo.nil?\n\t@echo = true\n      end\n      @debug_level = IRB.conf[:DEBUG_LEVEL]\n    end\n\n    def main\n      @workspace.main\n    end\n\n    attr_reader :workspace_home\n    attr_accessor :workspace\n    attr_reader :thread\n    attr_accessor :io\n    \n    attr_accessor :irb\n    attr_accessor :ap_name\n    attr_accessor :rc\n    attr_accessor :load_modules\n    attr_accessor :irb_name\n    attr_accessor :irb_path\n\n    attr_reader :use_readline\n    attr_reader :inspect_mode\n\n    attr_reader :prompt_mode\n    attr_accessor :prompt_i\n    attr_accessor :prompt_s\n    attr_accessor :prompt_c\n    attr_accessor :prompt_n\n    attr_accessor :auto_indent_mode\n    attr_accessor :return_format\n\n    attr_accessor :ignore_sigint\n    attr_accessor :ignore_eof\n    attr_accessor :echo\n    attr_accessor :verbose\n    attr_reader :debug_level\n\n    attr_accessor :back_trace_limit\n\n    alias use_readline? use_readline\n    alias rc? rc\n    alias ignore_sigint? ignore_sigint\n    alias ignore_eof? ignore_eof\n    alias echo? echo\n\n    def verbose?\n      if @verbose.nil?\n\tif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) \n\t  false\n\telsif !STDIN.tty? or @io.kind_of?(FileInputMethod)\n\t  true\n\telse\n\t  false\n\tend\n      end\n    end\n\n    def prompting?\n      verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||\n\t\t(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))\n    end\n\n    attr_reader :last_value\n\n    def set_last_value(value)\n      @last_value = value\n      @workspace.evaluate self, \"_ = IRB.CurrentContext.last_value\"\n    end\n\n    attr_reader :irb_name\n\n    def prompt_mode=(mode)\n      @prompt_mode = mode\n      pconf = IRB.conf[:PROMPT][mode]\n      @prompt_i = pconf[:PROMPT_I]\n      @prompt_s = pconf[:PROMPT_S]\n      @prompt_c = pconf[:PROMPT_C]\n      @prompt_n = pconf[:PROMPT_N]\n      @return_format = pconf[:RETURN]\n      if ai = pconf.include?(:AUTO_INDENT)\n\t@auto_indent_mode = ai\n      else\n\t@auto_indent_mode = IRB.conf[:AUTO_INDENT]\n      end\n    end\n    \n    def inspect?\n      @inspect_mode.nil? or @inspect_mode\n    end\n\n    def file_input?\n      @io.class == FileInputMethod\n    end\n\n    def inspect_mode=(opt)\n      if opt\n\t@inspect_mode = opt\n      else\n\t@inspect_mode = !@inspect_mode\n      end\n      print \"Switch to#{unless @inspect_mode; ' non';end} inspect mode.\\n\" if verbose?\n      @inspect_mode\n    end\n\n    def use_readline=(opt)\n      @use_readline = opt\n      print \"use readline module\\n\" if @use_readline\n    end\n\n    def debug_level=(value)\n      @debug_level = value\n      RubyLex.debug_level = value\n      SLex.debug_level = value\n    end\n\n    def debug?\n      @debug_level > 0\n    end\n\n    def evaluate(line, line_no)\n      @line_no = line_no\n      set_last_value(@workspace.evaluate(self, line, irb_path, line_no))\n#      @workspace.evaluate(\"_ = IRB.conf[:MAIN_CONTEXT]._\")\n#      @_ = @workspace.evaluate(line, irb_path, line_no)\n    end\n\n    alias __exit__ exit\n    def exit(ret = 0)\n      IRB.irb_exit(@irb, ret)\n    end\n\n    NOPRINTING_IVARS = [\"@last_value\"]\n    NO_INSPECTING_IVARS = [\"@irb\", \"@io\"]\n    IDNAME_IVARS = [\"@prompt_mode\"]\n\n    alias __inspect__ inspect\n    def inspect\n      array = []\n      for ivar in instance_variables.sort{|e1, e2| e1 <=> e2}\n\tname = ivar.sub(/^@(.*)$/){$1}\n\tval = instance_eval(ivar)\n\tcase ivar\n\twhen *NOPRINTING_IVARS\n\t  array.push format(\"conf.%s=%s\", name, \"...\")\n\twhen *NO_INSPECTING_IVARS\n\t  array.push format(\"conf.%s=%s\", name, val.to_s)\n\twhen *IDNAME_IVARS\n\t  array.push format(\"conf.%s=:%s\", name, val.id2name)\n\telse\n\t  array.push format(\"conf.%s=%s\", name, val.inspect)\n\tend\n      end\n      array.join(\"\\n\")\n    end\n    alias __to_s__ to_s\n    alias to_s inspect\n  end\nend\n"
  },
  {
    "path": "lib/irb/ext/change-ws.rb",
    "content": "#\n#   irb/ext/cb.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nmodule IRB\n  class Context\n\n    def home_workspace\n      if defined? @home_workspace\n\t@home_workspace\n      else\n\t@home_workspace = @workspace\n      end\n    end\n\n    def change_workspace(*_main)\n      if _main.empty?\n\t@workspace = home_workspace \n\treturn main\n      end\n      \n      @workspace = WorkSpace.new(_main[0])\n      \n      if !(class<<main;ancestors;end).include?(ExtendCommandBundle)\n\tmain.extend ExtendCommandBundle\n      end\n    end\n\n#     def change_binding(*_main)\n#       back = @workspace\n#       @workspace = WorkSpace.new(*_main)\n#       unless _main.empty?\n# \tbegin\n# \t  main.extend ExtendCommandBundle\n# \trescue\n# \t  print \"can't change binding to: \", main.inspect, \"\\n\"\n# \t  @workspace = back\n# \t  return nil\n# \tend\n#       end\n#       @irb_level += 1\n#       begin\n# \tcatch(:SU_EXIT) do\n# \t  @irb.eval_input\n# \tend\n#       ensure\n# \t@irb_level -= 1\n#  \t@workspace = back\n#       end\n#     end\n#     alias change_workspace change_binding\n   end\nend\n\n"
  },
  {
    "path": "lib/irb/ext/history.rb",
    "content": "#\n#   history.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nmodule IRB\n\n  class Context\n\n    NOPRINTING_IVARS.push \"@eval_history_values\"\n\n    alias _set_last_value set_last_value\n\n    def set_last_value(value)\n      _set_last_value(value)\n\n#      @workspace.evaluate self, \"_ = IRB.CurrentContext.last_value\"\n      if @eval_history #and !@eval_history_values.equal?(llv)\n \t@eval_history_values.push @line_no, @last_value\n \t@workspace.evaluate self, \"__ = IRB.CurrentContext.instance_eval{@eval_history_values}\"\n      end\n\n      @last_value\n    end\n\n    attr_reader :eval_history\n    def eval_history=(no)\n      if no\n\tif defined?(@eval_history) && @eval_history\n\t  @eval_history_values.size(no)\n\telse\n\t  @eval_history_values = History.new(no)\n\t  IRB.conf[:__TMP__EHV__] = @eval_history_values\n\t  @workspace.evaluate(self, \"__ = IRB.conf[:__TMP__EHV__]\")\n\t  IRB.conf.delete(:__TMP_EHV__)\n\tend\n      else\n\t@eval_history_values = nil\n      end\n      @eval_history = no\n    end\n  end\n\n  class History\n    @RCS_ID='-$Id$-'\n\n    def initialize(size = 16)\n      @size = size\n      @contents = []\n    end\n\n    def size(size)\n      if size != 0 && size < @size \n\t@contents = @contents[@size - size .. @size]\n      end\n      @size = size\n    end\n\n    def [](idx)\n      begin\n\tif idx >= 0\n\t  @contents.find{|no, val| no == idx}[1]\n\telse\n\t  @contents[idx][1]\n\tend\n      rescue NameError\n\tnil\n      end\n    end\n\n    def push(no, val)\n      @contents.push [no, val]\n      @contents.shift if @size != 0 && @contents.size > @size\n    end\n    \n    alias real_inspect inspect\n\n    def inspect\n      if @contents.empty?\n\treturn real_inspect\n      end\n\n      unless (last = @contents.pop)[1].equal?(self)\n\t@contents.push last\n\tlast = nil\n      end\n      str = @contents.collect{|no, val|\n\tif val.equal?(self)\n\t  \"#{no} ...self-history...\"\n\telse\n\t  \"#{no} #{val.inspect}\"\n\tend\n      }.join(\"\\n\")\n      if str == \"\"\n\tstr = \"Empty.\"\n      end\n      @contents.push last if last\n      str\n    end\n  end\nend\n\n\n"
  },
  {
    "path": "lib/irb/ext/loader.rb",
    "content": "#\n#   loader.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\n\nmodule IRB\n  class LoadAbort < Exception;end\n\n  module IrbLoader\n    @RCS_ID='-$Id$-'\n\n    alias ruby_load load\n    alias ruby_require require\n\n    def irb_load(fn, priv = nil)\n      path = search_file_from_ruby_path(fn)\n      raise LoadError, \"No such file to load -- #{fn}\" unless path\n\n      load_file(path, priv)\n    end\n\n    def search_file_from_ruby_path(fn)\n      if /^#{Regexp.quote(File::Separator)}/ =~ fn\n\treturn fn if File.exist?(fn)\n\treturn nil\n      end\n\n      for path in $:\n\tif File.exist?(f = File.join(path, fn))\n\t  return f\n\tend\n      end\n      return nil\n    end\n\n    def source_file(path)\n      irb.suspend_name(path, File.basename(path)) do\n\tirb.suspend_input_method(FileInputMethod.new(path)) do\n\t  |back_io|\n\t  irb.signal_status(:IN_LOAD) do \n\t    if back_io.kind_of?(FileInputMethod)\n\t      irb.eval_input\n\t    else\n\t      begin\n\t\tirb.eval_input\n\t      rescue LoadAbort\n\t\tprint \"load abort!!\\n\"\n\t      end\n\t    end\n\t  end\n\tend\n      end\n    end\n\n    def load_file(path, priv = nil)\n      irb.suspend_name(path, File.basename(path)) do\n\t\n\tif priv\n\t  ws = WorkSpace.new(Module.new)\n\telse\n\t  ws = WorkSpace.new\n\tend\n\tirb.suspend_workspace(ws) do\n\t  irb.suspend_input_method(FileInputMethod.new(path)) do\n\t    |back_io|\n\t    irb.signal_status(:IN_LOAD) do \n#\t      p irb.conf\n\t      if back_io.kind_of?(FileInputMethod)\n\t\tirb.eval_input\n\t      else\n\t\tbegin\n\t\t  irb.eval_input\n\t\trescue LoadAbort\n\t\t  print \"load abort!!\\n\"\n\t\tend\n\t      end\n\t    end\n\t  end\n\tend\n      end\n    end\n\n    def old\n      back_io = @io\n      back_path = @irb_path\n      back_name = @irb_name\n      back_scanner = @irb.scanner\n      begin\n \t@io = FileInputMethod.new(path)\n \t@irb_name = File.basename(path)\n\t@irb_path = path\n\t@irb.signal_status(:IN_LOAD) do\n\t  if back_io.kind_of?(FileInputMethod)\n\t    @irb.eval_input\n\t  else\n\t    begin\n\t      @irb.eval_input\n\t    rescue LoadAbort\n\t      print \"load abort!!\\n\"\n\t    end\n\t  end\n\tend\n      ensure\n \t@io = back_io\n \t@irb_name = back_name\n \t@irb_path = back_path\n\t@irb.scanner = back_scanner\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/ext/math-mode.rb",
    "content": "#\n#   math-mode.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nrequire \"mathn\"\n\nmodule IRB\n  class Context\n    attr_reader :math_mode\n    alias math? math_mode\n\n    def math_mode=(opt)\n      if @math_mode == true && opt == false\n\tIRB.fail CantReturnToNormalMode\n\treturn\n      end\n\n      @math_mode = opt\n      if math_mode\n\tmain.extend Math\n\tprint \"start math mode\\n\" if verbose?\n      end\n    end\n\n    def inspect?\n      @inspect_mode.nil? && !@math_mode or @inspect_mode\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/ext/multi-irb.rb",
    "content": "#\n#   irb/multi-irb.rb - multiple irb module\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nIRB.fail CantShiftToMultiIrbMode unless defined?(Thread)\nrequire \"thread\"\n\nmodule IRB\n  # job management class\n  class JobManager\n    @RCS_ID='-$Id$-'\n\n    def initialize\n      # @jobs = [[thread, irb],...]\n      @jobs = []\n      @current_job = nil\n    end\n\n    attr_accessor :current_job\n\n    def n_jobs\n      @jobs.size\n    end\n\n    def thread(key)\n      th, irb = search(key)\n      th\n    end\n\n    def irb(key)\n      th, irb = search(key)\n      irb\n    end\n\n    def main_thread\n      @jobs[0][0]\n    end\n\n    def main_irb\n      @jobs[0][1]\n    end\n\n    def insert(irb)\n      @jobs.push [Thread.current, irb]\n    end\n\n    def switch(key)\n      th, irb = search(key)\n      IRB.fail IrbAlreadyDead unless th.alive?\n      IRB.fail IrbSwitchedToCurrentThread if th == Thread.current\n      @current_job = irb\n      th.run\n      Thread.stop\n      @current_job = irb(Thread.current)\n    end\n\n    def kill(*keys)\n      for key in keys\n\tth, irb = search(key)\n\tIRB.fail IrbAlreadyDead unless th.alive?\n\tth.exit\n      end\n    end    \n\n    def search(key)\n      job = case key\n      when Integer\n\t@jobs[key]\n      when Irb\n\t@jobs.find{|k, v| v.equal?(key)}\n      when Thread\n\t@jobs.assoc(key)\n      else\n\t@jobs.find{|k, v| v.context.main.equal?(key)}\n      end\n      IRB.fail NoSuchJob, key if job.nil?\n      job\n    end\n\n    def delete(key)\n      case key\n      when Integer\n\tIRB.fail NoSuchJob, key unless @jobs[key]\n\t@jobs[key] = nil\n      else\n\tcatch(:EXISTS) do\n\t  @jobs.each_index do\n\t    |i|\n\t    if @jobs[i] and (@jobs[i][0] == key ||\n\t\t\t     @jobs[i][1] == key ||\n\t\t\t     @jobs[i][1].context.main.equal?(key))\n\t      @jobs[i] = nil\n\t      throw :EXISTS\n\t    end\n\t  end\n\t  IRB.fail NoSuchJob, key\n\tend\n      end\n      until assoc = @jobs.pop; end unless @jobs.empty?\n      @jobs.push assoc\n    end\n\n    def inspect\n      ary = []\n      @jobs.each_index do\n\t|i|\n\tth, irb = @jobs[i]\n\tnext if th.nil?\n\n\tif th.alive?\n\t  if th.stop?\n\t    t_status = \"stop\"\n\t  else\n\t    t_status = \"running\"\n\t  end\n\telse\n\t  t_status = \"exited\"\n\tend\n\tary.push format(\"#%d->%s on %s (%s: %s)\",\n\t\t\ti, \n\t\t\tirb.context.irb_name, \n\t\t\tirb.context.main,\n\t\t\tth,\n\t\t\tt_status)\n      end\n      ary.join(\"\\n\")\n    end\n  end\n\n  @JobManager = JobManager.new\n\n  def IRB.JobManager\n    @JobManager\n  end\n\n  def IRB.CurrentContext\n    IRB.JobManager.irb(Thread.current).context\n  end\n\n  # invoke multi-irb \n  def IRB.irb(file = nil, *main)\n    workspace = WorkSpace.new(*main)\n    parent_thread = Thread.current\n    Thread.start do\n      begin\n\tirb = Irb.new(workspace, file)\n      rescue \n\tprint \"Subirb can't start with context(self): \", workspace.main.inspect, \"\\n\"\n\tprint \"return to main irb\\n\"\n\tThread.pass\n\tThread.main.wakeup\n\tThread.exit\n      end\n      @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]\n      @JobManager.insert(irb)\n      @JobManager.current_job = irb\n      begin\n\tsystem_exit = false\n\tcatch(:IRB_EXIT) do\n\t  irb.eval_input\n\tend\n      rescue SystemExit\n\tsystem_exit = true\n\traise\n\t#fail\n      ensure\n\tunless system_exit\n\t  @JobManager.delete(irb)\n\t  if parent_thread.alive?\n\t    @JobManager.current_job = @JobManager.irb(parent_thread)\n\t    parent_thread.run\n\t  else\n\t    @JobManager.current_job = @JobManager.main_irb\n\t    @JobManager.main_thread.run\n\t  end\n\tend\n      end\n    end\n    Thread.stop\n    @JobManager.current_job = @JobManager.irb(Thread.current)\n  end\n\n#   class Context\n#     def set_last_value(value)\n#       @last_value = value\n#       @workspace.evaluate \"_ = IRB.JobManager.irb(Thread.current).context.last_value\"\n#       if @eval_history #and !@__.equal?(@last_value)\n# \t@eval_history_values.push @line_no, @last_value\n# \t@workspace.evaluate \"__ = IRB.JobManager.irb(Thread.current).context.instance_eval{@eval_history_values}\"\n#       end\n#       @last_value\n#     end\n#   end\n\n#  module ExtendCommand\n#     def irb_context\n#       IRB.JobManager.irb(Thread.current).context\n#     end\n# #    alias conf irb_context\n#   end\n\n  @CONF[:SINGLE_IRB_MODE] = false\n  @JobManager.insert(@CONF[:MAIN_CONTEXT].irb)\n  @JobManager.current_job = @CONF[:MAIN_CONTEXT].irb\n\n  class Irb\n    def signal_handle\n      unless @context.ignore_sigint?\n\tprint \"\\nabort!!\\n\" if @context.verbose?\n\texit\n      end\n\n      case @signal_status\n      when :IN_INPUT\n\tprint \"^C\\n\"\n\tIRB.JobManager.thread(self).raise RubyLex::TerminateLineInput\n      when :IN_EVAL\n\tIRB.irb_abort(self)\n      when :IN_LOAD\n\tIRB.irb_abort(self, LoadAbort)\n      when :IN_IRB\n\t# ignore\n      else\n\t# ignore other cases as well\n      end\n    end\n  end\n\n  trap(\"SIGINT\") do\n    @JobManager.current_job.signal_handle\n    Thread.stop\n  end\n\nend\n"
  },
  {
    "path": "lib/irb/ext/save-history.rb",
    "content": "#!/usr/local/bin/ruby\n#\n#   save-history.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKAkeiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"readline\"\n\nmodule IRB\n  module HistorySavingAbility\n    @RCS_ID='-$Id$-'\n  end\n\n  class Context\n    def init_save_history\n      unless (class<<@io;self;end).include?(HistorySavingAbility)\n\t@io.extend(HistorySavingAbility)\n      end\n    end\n\n    def save_history\n      IRB.conf[:SAVE_HISTORY]\n    end\n\n    def save_history=(val)\n      IRB.conf[:SAVE_HISTORY] = val\n      if val\n\tmain_context = IRB.conf[:MAIN_CONTEXT]\n\tmain_context = self unless main_context\n\tmain_context.init_save_history\n      end\n    end\n\n    def history_file\n      IRB.conf[:HISTORY_FILE]\n    end\n\n    def history_file=(hist)\n      IRB.conf[:HISTORY_FILE] = hist\n    end\n  end\n\n  module HistorySavingAbility\n    include Readline\n\n#     def HistorySavingAbility.create_finalizer\n#       proc do\n# \tif num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0\n# \t  if hf = IRB.conf[:HISTORY_FILE]\n# \t    file = File.expand_path(hf)\n# \t  end\n# \t  file = IRB.rc_file(\"_history\") unless file\n# \t  open(file, 'w' ) do |f|\n# \t    hist = HISTORY.to_a\n# \t    f.puts(hist[-num..-1] || hist)\n# \t  end\n# \tend\n#       end\n#     end\n\n    def HistorySavingAbility.extended(obj)\n#      ObjectSpace.define_finalizer(obj, HistorySavingAbility.create_finalizer)\n      IRB.conf[:AT_EXIT].push proc{obj.save_history}\n      obj.load_history\n      obj\n    end\n\n    def load_history\n      hist = IRB.conf[:HISTORY_FILE]\n      hist = IRB.rc_file(\"_history\") unless hist\n      if File.exist?(hist)\n\topen(hist) do |f|\n\t  f.each {|l| HISTORY << l.chomp}\n\tend\n      end\n    end\n\n    def save_history\n      if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0\n\tif history_file = IRB.conf[:HISTORY_FILE]\n\t  history_file = File.expand_path(history_file)\n\tend\n\thistory_file = IRB.rc_file(\"_history\") unless history_file\n\topen(history_file, 'w' ) do |f|\n\t  hist = HISTORY.to_a\n\t  f.puts(hist[-num..-1] || hist)\n\tend\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/ext/tracer.rb",
    "content": "#\n#   irb/lib/tracer.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nrequire \"tracer\"\n\nmodule IRB\n\n  # initialize tracing function\n  def IRB.initialize_tracer\n    Tracer.verbose = false\n    Tracer.add_filter {\n      |event, file, line, id, binding, *rests|\n      /^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and\n\tFile::basename(file) != \"irb.rb\"\n    }\n  end\n\n  class Context\n    attr_reader :use_tracer\n    alias use_tracer? use_tracer\n\n    def use_tracer=(opt)\n      if opt\n\tTracer.set_get_line_procs(@irb_path) {\n\t  |line_no, *rests|\n\t  @io.line(line_no)\n\t}\n      elsif !opt && @use_tracer\n\tTracer.off\n      end\n      @use_tracer=opt\n    end\n  end\n\n  class WorkSpace\n    alias __evaluate__ evaluate\n    def evaluate(context, statements, file = nil, line = nil)\n      if context.use_tracer? && file != nil && line != nil\n\tTracer.on \n\tbegin\n\t  __evaluate__(context, statements, file, line)\n\tensure\n\t  Tracer.off\n\tend\n      else\n\t__evaluate__(context, statements, file || __FILE__, line || __LINE__)\n      end\n    end\n  end\n\n  IRB.initialize_tracer\nend\n\t\n"
  },
  {
    "path": "lib/irb/ext/use-loader.rb",
    "content": "#\n#   use-loader.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"irb/cmd/load\"\nrequire \"irb/ext/loader\"\n\nclass Object\n  alias __original__load__IRB_use_loader__ load\n  alias __original__require__IRB_use_loader__ require\nend\n\nmodule IRB\n  module ExtendCommandBundle\n    def irb_load(*opts, &b)\n      ExtendCommand::Load.execute(irb_context, *opts, &b)\n    end\n    def irb_require(*opts, &b)\n      ExtendCommand::Require.execute(irb_context, *opts, &b)\n    end\n  end\n\n  class Context\n\n    IRB.conf[:USE_LOADER] = false\n    \n    def use_loader\n      IRB.conf[:USE_LOADER]\n    end\n\n    alias use_loader? use_loader\n\n    def use_loader=(opt)\n\n      if IRB.conf[:USE_LOADER] != opt\n\tIRB.conf[:USE_LOADER] = opt\n\tif opt\n\t  if !$\".include?(\"irb/cmd/load\")\n\t  end\n\t  (class<<@workspace.main;self;end).instance_eval {\n\t    alias_method :load, :irb_load\n\t    alias_method :require, :irb_require\n\t  }\n\telse\n\t  (class<<@workspace.main;self;end).instance_eval {\n\t    alias_method :load, :__original__load__IRB_use_loader__\n\t    alias_method :require, :__original__require__IRB_use_loader__\n\t  }\n\tend\n      end\n      print \"Switch to load/require#{unless use_loader; ' non';end} trace mode.\\n\" if verbose?\n      opt\n    end\n  end\nend\n\n\n"
  },
  {
    "path": "lib/irb/ext/workspaces.rb",
    "content": "#\n#   push-ws.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nmodule IRB\n  class Context\n\n    def irb_level\n      workspace_stack.size\n    end\n\n    def workspaces\n      if defined? @workspaces\n\t@workspaces\n      else\n\t@workspaces = []\n      end\n    end\n\n    def push_workspace(*_main)\n      if _main.empty?\n\tif workspaces.empty?\n\t  print \"No other workspace\\n\"\n\t  return nil\n\tend\n\tws = workspaces.pop\n\tworkspaces.push @workspace\n\t@workspace = ws\n\treturn workspaces\n      end\n\n      workspaces.push @workspace\n      @workspace = WorkSpace.new(@workspace.binding, _main[0])\n      if !(class<<main;ancestors;end).include?(ExtendCommandBundle)\n\tmain.extend ExtendCommandBundle\n      end\n    end\n\n    def pop_workspace\n      if workspaces.empty?\n\tprint \"workspace stack empty\\n\"\n\treturn\n      end\n      @workspace = workspaces.pop\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/extend-command.rb",
    "content": "#\n#   irb/extend-command.rb - irb extend command \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nmodule IRB\n  #\n  # IRB extended command\n  #\n  module ExtendCommandBundle\n    EXCB = ExtendCommandBundle\n\n    NO_OVERRIDE = 0\n    OVERRIDE_PRIVATE_ONLY = 0x01\n    OVERRIDE_ALL = 0x02\n\n    def irb_exit(ret = 0)\n      irb_context.exit(ret)\n    end\n\n    def irb_context\n      IRB.CurrentContext\n    end\n\n    @ALIASES = [\n      [:context, :irb_context, NO_OVERRIDE],\n      [:conf, :irb_context, NO_OVERRIDE],\n      [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],\n      [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY],\n      [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY],\n    ]\n\n    @EXTEND_COMMANDS = [\n      [:irb_current_working_workspace, :CurrentWorkingWorkspace, \"irb/cmd/chws\",\n\t[:irb_print_working_workspace, OVERRIDE_ALL],\n\t[:irb_cwws, OVERRIDE_ALL],\n\t[:irb_pwws, OVERRIDE_ALL],\n#\t[:irb_cww, OVERRIDE_ALL],\n#\t[:irb_pww, OVERRIDE_ALL],\n\t[:cwws, NO_OVERRIDE],\n\t[:pwws, NO_OVERRIDE],\n#\t[:cww, NO_OVERRIDE],\n#\t[:pww, NO_OVERRIDE],\n\t[:irb_current_working_binding, OVERRIDE_ALL],\n\t[:irb_print_working_binding, OVERRIDE_ALL],\n\t[:irb_cwb, OVERRIDE_ALL],\n\t[:irb_pwb, OVERRIDE_ALL],\n#\t[:cwb, NO_OVERRIDE],\n#\t[:pwb, NO_OVERRIDE]\n      ],\n      [:irb_change_workspace, :ChangeWorkspace, \"irb/cmd/chws\",\n\t[:irb_chws, OVERRIDE_ALL],\n#\t[:irb_chw, OVERRIDE_ALL],\n\t[:irb_cws, OVERRIDE_ALL],\n#\t[:irb_cw, OVERRIDE_ALL],\n\t[:chws, NO_OVERRIDE],\n#\t[:chw, NO_OVERRIDE],\n\t[:cws, NO_OVERRIDE],\n#\t[:cw, NO_OVERRIDE],\n\t[:irb_change_binding, OVERRIDE_ALL],\n\t[:irb_cb, OVERRIDE_ALL],\n\t[:cb, NO_OVERRIDE]],\n\n      [:irb_workspaces, :Workspaces, \"irb/cmd/pushws\",\n\t[:workspaces, NO_OVERRIDE],\n\t[:irb_bindings, OVERRIDE_ALL],\n\t[:bindings, NO_OVERRIDE]],\n      [:irb_push_workspace, :PushWorkspace, \"irb/cmd/pushws\",\n\t[:irb_pushws, OVERRIDE_ALL],\n#\t[:irb_pushw, OVERRIDE_ALL],\n\t[:pushws, NO_OVERRIDE],\n#\t[:pushw, NO_OVERRIDE],\n\t[:irb_push_binding, OVERRIDE_ALL],\n\t[:irb_pushb, OVERRIDE_ALL],\n\t[:pushb, NO_OVERRIDE]],\n      [:irb_pop_workspace, :PopWorkspace, \"irb/cmd/pushws\",\n\t[:irb_popws, OVERRIDE_ALL],\n#\t[:irb_popw, OVERRIDE_ALL],\n\t[:popws, NO_OVERRIDE],\n#\t[:popw, NO_OVERRIDE],\n\t[:irb_pop_binding, OVERRIDE_ALL],\n\t[:irb_popb, OVERRIDE_ALL],\n\t[:popb, NO_OVERRIDE]],\n\n      [:irb_load, :Load, \"irb/cmd/load\"],\n      [:irb_require, :Require, \"irb/cmd/load\"],\n      [:irb_source, :Source, \"irb/cmd/load\", \n\t[:source, NO_OVERRIDE]],\n\n      [:irb, :IrbCommand, \"irb/cmd/subirb\"],\n      [:irb_jobs, :Jobs, \"irb/cmd/subirb\", \n\t[:jobs, NO_OVERRIDE]],\n      [:irb_fg, :Foreground, \"irb/cmd/subirb\", \n\t[:fg, NO_OVERRIDE]],\n      [:irb_kill, :Kill, \"irb/cmd/subirb\", \n\t[:kill, OVERRIDE_PRIVATE_ONLY]],\n\n      [:irb_help, :Help, \"irb/cmd/help\",\n        [:help, NO_OVERRIDE]],\n\n    ]\n\n    def self.install_extend_commands\n      for args in @EXTEND_COMMANDS\n\tdef_extend_command(*args)\n      end\n    end\n\n    # aliases = [commands_alias, flag], ...\n    def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)\n      case cmd_class\n      when Symbol\n\tcmd_class = cmd_class.id2name\n      when String\n      when Class\n\tcmd_class = cmd_class.name\n      end\n\n      if load_file\n\teval %[\n\t  def #{cmd_name}(*opts, &b)\n\t    require \"#{load_file}\"\n\t    arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity\n\t    args = (1..arity.abs).map {|i| \"arg\" + i.to_s }\n\t    args << \"*opts\" if arity < 0\n\t    args << \"&block\"\n\t    args = args.join(\", \")\n\t    eval %[\n\t      def #{cmd_name}(\\#{args})\n\t\tExtendCommand::#{cmd_class}.execute(irb_context, \\#{args})\n\t      end\n\t    ]\n\t    send :#{cmd_name}, *opts, &b\n\t  end\n\t]\n      else\n\teval %[\n\t  def #{cmd_name}(*opts, &b)\n\t    ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)\n\t  end\n\t]\n      end\n\n      for ali, flag in aliases\n\t@ALIASES.push [ali, cmd_name, flag]\n      end\n    end\n\n    # override = {NO_OVERRIDE, OVERRIDE_PRIVATE_ONLY, OVERRIDE_ALL}\n    def install_alias_method(to, from, override = NO_OVERRIDE)\n      to = to.id2name unless to.kind_of?(String)\n      from = from.id2name unless from.kind_of?(String)\n\n      if override == OVERRIDE_ALL or\n\t  (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or\n\t  (override == NO_OVERRIDE) &&  !respond_to?(to, true)\n\ttarget = self\n\t(class<<self;self;end).instance_eval{\n\t  if target.respond_to?(to, true) && \n\t      !target.respond_to?(EXCB.irb_original_method_name(to), true)\n\t    alias_method(EXCB.irb_original_method_name(to), to) \n\t  end\n\t  alias_method to, from\n\t}\n      else\n\tprint \"irb: warn: can't alias #{to} from #{from}.\\n\"\n      end\n    end\n\n    def self.irb_original_method_name(method_name)\n      \"irb_\" + method_name + \"_org\"\n    end\n\n    def self.extend_object(obj)\n      unless (class<<obj;ancestors;end).include?(EXCB)\n\tsuper\n\tfor ali, com, flg in @ALIASES\n\t  obj.install_alias_method(ali, com, flg)\n\tend\n      end\n    end\n\n    install_extend_commands\n  end\n\n  # extension support for Context\n  module ContextExtender\n    CE = ContextExtender\n\n    @EXTEND_COMMANDS = [\n      [:eval_history=, \"irb/ext/history.rb\"],\n      [:use_tracer=, \"irb/ext/tracer.rb\"],\n      [:math_mode=, \"irb/ext/math-mode.rb\"],\n      [:use_loader=, \"irb/ext/use-loader.rb\"],\n      [:save_history=, \"irb/ext/save-history.rb\"],\n    ]\n\n    def self.install_extend_commands\n      for args in @EXTEND_COMMANDS\n\tdef_extend_command(*args)\n      end\n    end\n\n    def self.def_extend_command(cmd_name, load_file, *aliases)\n      Context.module_eval %[\n        def #{cmd_name}(*opts, &b)\n\t  Context.module_eval {remove_method(:#{cmd_name})}\n\t  require \"#{load_file}\"\n\t  send :#{cmd_name}, *opts, &b\n\tend\n\tfor ali in aliases\n\t  alias_method ali, cmd_name\n\tend\n      ]\n    end\n\n    CE.install_extend_commands\n  end\n\n  module MethodExtender\n    def def_pre_proc(base_method, extend_method)\n      base_method = base_method.to_s\n      extend_method = extend_method.to_s\n\n      alias_name = new_alias_name(base_method)\n      module_eval %[\n        alias_method alias_name, base_method\n        def #{base_method}(*opts)\n\t  send :#{extend_method}, *opts\n\t  send :#{alias_name}, *opts\n\tend\n      ]\n    end\n\n    def def_post_proc(base_method, extend_method)\n      base_method = base_method.to_s\n      extend_method = extend_method.to_s\n\n      alias_name = new_alias_name(base_method)\n      module_eval %[\n        alias_method alias_name, base_method\n        def #{base_method}(*opts)\n\t  send :#{alias_name}, *opts\n\t  send :#{extend_method}, *opts\n\tend\n      ]\n    end\n\n    # return #{prefix}#{name}#{postfix}<num>\n    def new_alias_name(name, prefix = \"__alias_of__\", postfix = \"__\")\n      base_name = \"#{prefix}#{name}#{postfix}\"\n      all_methods = instance_methods(true) + private_instance_methods(true)\n      same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/)\n      return base_name if same_methods.empty?\n      no = same_methods.size\n      while !same_methods.include?(alias_name = base_name + no)\n\tno += 1\n      end\n      alias_name\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/frame.rb",
    "content": "#\n#   frame.rb - \n#   \t$Release Version: 0.9$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\n\nmodule IRB\n  class Frame\n    extend Exception2MessageMapper\n    def_exception :FrameOverflow, \"frame overflow\"\n    def_exception :FrameUnderflow, \"frame underflow\"\n\n    INIT_STACK_TIMES = 3\n    CALL_STACK_OFFSET = 3\n\n    def initialize\n      @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES\n    end\n\n    def trace_func(event, file, line, id, binding)\n      case event\n      when 'call', 'class'\n\t@frames.push binding\n      when 'return', 'end'\n\t@frames.pop\n      end\n    end\n\n    def top(n = 0)\n      bind = @frames[-(n + CALL_STACK_OFFSET)]\n      Fail FrameUnderflow unless bind\n      bind\n    end\n\n    def bottom(n = 0)\n      bind = @frames[n]\n      Fail FrameOverflow unless bind\n      bind\n    end\n\n    # singleton functions\n    def Frame.bottom(n = 0)\n      @backtrace.bottom(n)\n    end\n\n    def Frame.top(n = 0)\n      @backtrace.top(n)\n    end\n\n    def Frame.sender\n      eval \"self\", @backtrace.top\n    end\n\n    @backtrace = Frame.new\n    set_trace_func proc{|event, file, line, id, binding, klass|\n      @backtrace.trace_func(event, file, line, id, binding)\n    }\n  end\nend\n"
  },
  {
    "path": "lib/irb/help.rb",
    "content": "#\n#   irb/help.rb - print usage module\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n#\n# --\n#\n#   \n#\n\nmodule IRB\n  def IRB.print_usage\n    lc = IRB.conf[:LC_MESSAGES]\n    path = lc.find(\"irb/help-message\")\n    space_line = false\n    File.foreach(path) do\n      |l|\n      if /^\\s*$/ =~ l\n\tlc.puts l unless space_line\n\tspace_line = true\n\tnext\n      end\n      space_line = false\n      \n      l.sub!(/#.*$/, \"\")\n      next if /^\\s*$/ =~ l\n      lc.puts l\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/irb/init.rb",
    "content": "#\n#   irb/init.rb - irb initialize module\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nmodule IRB\n\n  # initialize config\n  def IRB.setup(ap_path)\n    IRB.init_config(ap_path)\n    IRB.init_error\n    IRB.parse_opts\n    IRB.run_config\n    IRB.load_modules\n\n    unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]\n      IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE]) \n    end\n  end\n\n  # @CONF default setting\n  def IRB.init_config(ap_path)\n    # class instance variables\n    @TRACER_INITIALIZED = false\n\n    # default configurations\n    unless ap_path and @CONF[:AP_NAME]\n      ap_path = File.join(File.dirname(File.dirname(__FILE__)), \"irb.rb\")\n    end\n    @CONF[:AP_NAME] = File::basename(ap_path, \".rb\")\n\n    @CONF[:IRB_NAME] = \"irb\"\n    @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__)\n\n    @CONF[:RC] = true\n    @CONF[:LOAD_MODULES] = []\n    @CONF[:IRB_RC] = nil\n\n    @CONF[:MATH_MODE] = false\n    @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)\n    @CONF[:INSPECT_MODE] = nil\n    @CONF[:USE_TRACER] = false\n    @CONF[:USE_LOADER] = false\n    @CONF[:IGNORE_SIGINT] = true\n    @CONF[:IGNORE_EOF] = false\n    @CONF[:ECHO] = nil\n    @CONF[:VERBOSE] = nil\n\n    @CONF[:EVAL_HISTORY] = nil\n    @CONF[:SAVE_HISTORY] = nil\n\n    @CONF[:BACK_TRACE_LIMIT] = 16\n\n    @CONF[:PROMPT] = {\n      :NULL => {\n\t:PROMPT_I => nil,\n\t:PROMPT_N => nil,\n\t:PROMPT_S => nil,\n\t:PROMPT_C => nil,\n\t:RETURN => \"%s\\n\"\n      },\n      :DEFAULT => {\n\t:PROMPT_I => \"%N(%m):%03n:%i> \",\n\t:PROMPT_N => \"%N(%m):%03n:%i> \",\n\t:PROMPT_S => \"%N(%m):%03n:%i%l \",\n\t:PROMPT_C => \"%N(%m):%03n:%i* \",\n\t:RETURN => \"=> %s\\n\"\n      },\n      :CLASSIC => {\n\t:PROMPT_I => \"%N(%m):%03n:%i> \",\n\t:PROMPT_N => \"%N(%m):%03n:%i> \",\n\t:PROMPT_S => \"%N(%m):%03n:%i%l \",\n\t:PROMPT_C => \"%N(%m):%03n:%i* \",\n\t:RETURN => \"%s\\n\"\n      },\n      :SIMPLE => {\n\t:PROMPT_I => \">> \",\n\t:PROMPT_N => \">> \",\n\t:PROMPT_S => nil,\n\t:PROMPT_C => \"?> \",\n\t:RETURN => \"=> %s\\n\"\n      },\n      :INF_RUBY => {\n\t:PROMPT_I => \"%N(%m):%03n:%i> \",\n#\t:PROMPT_N => \"%N(%m):%03n:%i> \",\n\t:PROMPT_N => nil,\n\t:PROMPT_S => nil,\n\t:PROMPT_C => nil,\n\t:RETURN => \"%s\\n\",\n\t:AUTO_INDENT => true\n      },\n      :XMP => {\n\t:PROMPT_I => nil,\n\t:PROMPT_N => nil,\n\t:PROMPT_S => nil,\n\t:PROMPT_C => nil,\n\t:RETURN => \"    ==>%s\\n\"\n      }\n    }\n\n    @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)\n    @CONF[:AUTO_INDENT] = false\n\n    @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING\n    @CONF[:SINGLE_IRB] = false\n\n#    @CONF[:LC_MESSAGES] = \"en\"\n    @CONF[:LC_MESSAGES] = Locale.new\n    \n    @CONF[:AT_EXIT] = []\n    \n    @CONF[:DEBUG_LEVEL] = 1\n  end\n\n  def IRB.init_error\n    @CONF[:LC_MESSAGES].load(\"irb/error.rb\")\n  end\n\n  FEATURE_IOPT_CHANGE_VERSION = \"1.9.0\"\n\n  # option analyzing\n  def IRB.parse_opts\n    load_path = []\n    while opt = ARGV.shift\n      case opt\n      when \"-f\"\n\t@CONF[:RC] = false\n      when \"-m\"\n\t@CONF[:MATH_MODE] = true\n      when \"-d\"\n\t$DEBUG = true\n      when /^-r(.+)?/\n\topt = $1 || ARGV.shift\n\t@CONF[:LOAD_MODULES].push opt if opt\n      when /^-I(.+)?/\n        opt = $1 || ARGV.shift\n\tload_path.concat(opt.split(File::PATH_SEPARATOR)) if opt\n      when /^-K(.)/\n\t$KCODE = $1\n      when \"--inspect\"\n\t@CONF[:INSPECT_MODE] = true\n      when \"--noinspect\"\n\t@CONF[:INSPECT_MODE] = false\n      when \"--readline\"\n\t@CONF[:USE_READLINE] = true\n      when \"--noreadline\"\n\t@CONF[:USE_READLINE] = false\n      when \"--echo\"\n\t@CONF[:ECHO] = true\n      when \"--noecho\"\n\t@CONF[:ECHO] = false\n      when \"--verbose\"\n\t@CONF[:VERBOSE] = true\n      when \"--noverbose\"\n\t@CONF[:VERBOSE] = false\n      when \"--prompt-mode\", \"--prompt\"\n\tprompt_mode = ARGV.shift.upcase.tr(\"-\", \"_\").intern\n\t@CONF[:PROMPT_MODE] = prompt_mode\n      when \"--noprompt\"\n\t@CONF[:PROMPT_MODE] = :NULL\n      when \"--inf-ruby-mode\"\n\t@CONF[:PROMPT_MODE] = :INF_RUBY\n      when \"--sample-book-mode\", \"--simple-prompt\"\n\t@CONF[:PROMPT_MODE] = :SIMPLE\n      when \"--tracer\"\n\t@CONF[:USE_TRACER] = true\n      when \"--back-trace-limit\"\n\t@CONF[:BACK_TRACE_LIMIT] = ARGV.shift.to_i\n      when \"--context-mode\"\n\t@CONF[:CONTEXT_MODE] = ARGV.shift.to_i\n      when \"--single-irb\"\n\t@CONF[:SINGLE_IRB] = true\n      when \"--irb_debug\"\n\t@CONF[:DEBUG_LEVEL] = ARGV.shift.to_i\n      when \"-v\", \"--version\"\n\tprint IRB.version, \"\\n\"\n\texit 0\n      when \"-h\", \"--help\"\n\trequire \"irb/help\"\n\tIRB.print_usage\n\texit 0\n      when /^-/\n\tIRB.fail UnrecognizedSwitch, opt\n      else\n\t@CONF[:SCRIPT] = opt\n\t$0 = opt\n\tbreak\n      end\n    end\n    if RUBY_VERSION >= FEATURE_IOPT_CHANGE_VERSION\n      load_path.collect! do |path|\n\t/\\A\\.\\// =~ path ? path : File.expand_path(path)\n      end\n    end\n    $LOAD_PATH.unshift(*load_path)\n  end\n\n  # running config\n  def IRB.run_config\n    if @CONF[:RC]\n      begin\n\tload rc_file\n      rescue LoadError, Errno::ENOENT\n      rescue\n\tprint \"load error: #{rc_file}\\n\"\n\tprint $!.class, \": \", $!, \"\\n\"\n\tfor err in $@[0, $@.size - 2]\n\t  print \"\\t\", err, \"\\n\"\n\tend\n      end\n    end\n  end\n\n  IRBRC_EXT = \"rc\"\n  def IRB.rc_file(ext = IRBRC_EXT)\n    if !@CONF[:RC_NAME_GENERATOR]\n      rc_file_generators do |rcgen|\n\t@CONF[:RC_NAME_GENERATOR] ||= rcgen\n\tif File.exist?(rcgen.call(IRBRC_EXT))\n\t  @CONF[:RC_NAME_GENERATOR] = rcgen\n\t  break\n\tend\n      end\n    end\n    @CONF[:RC_NAME_GENERATOR].call ext\n  end\n\n  # enumerate possible rc-file base name generators\n  def IRB.rc_file_generators\n    if irbrc = ENV[\"IRBRC\"]\n      yield proc{|rc|  rc == \"rc\" ? irbrc : irbrc+rc}\n    end\n    if home = ENV[\"HOME\"]\n      yield proc{|rc| home+\"/.irb#{rc}\"} \n    end\n    home = Dir.pwd\n    yield proc{|rc| home+\"/.irb#{rc}\"}\n    yield proc{|rc| home+\"/irb#{rc.sub(/\\A_?/, '.')}\"}\n    yield proc{|rc| home+\"/_irb#{rc}\"}\n    yield proc{|rc| home+\"/$irb#{rc}\"}\n  end\n\n  # loading modules\n  def IRB.load_modules\n    for m in @CONF[:LOAD_MODULES]\n      begin\n\trequire m\n      rescue\n\tprint $@[0], \":\", $!.class, \": \", $!, \"\\n\"\n      end\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/irb/input-method.rb",
    "content": "#\n#   irb/input-method.rb - input methods used irb\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nmodule IRB\n  # \n  # InputMethod\n  #\tStdioInputMethod\n  #\tFileInputMethod\n  #\t(ReadlineInputMethod)\n  #\n  STDIN_FILE_NAME = \"(line)\"\n  class InputMethod\n    @RCS_ID='-$Id$-'\n\n    def initialize(file = STDIN_FILE_NAME)\n      @file_name = file\n    end\n    attr_reader :file_name\n\n    attr_accessor :prompt\n    \n    def gets\n      IRB.fail NotImplementedError, \"gets\"\n    end\n    public :gets\n\n    def readable_atfer_eof?\n      false\n    end\n  end\n  \n  class StdioInputMethod < InputMethod\n    def initialize\n      super\n      @line_no = 0\n      @line = []\n    end\n\n    def gets\n      print @prompt\n      @line[@line_no += 1] = $stdin.gets\n    end\n\n    def eof?\n      $stdin.eof?\n    end\n\n    def readable_atfer_eof?\n      true\n    end\n\n    def line(line_no)\n      @line[line_no]\n    end\n  end\n  \n  class FileInputMethod < InputMethod\n    def initialize(file)\n      super\n      @io = open(file)\n    end\n    attr_reader :file_name\n\n    def eof?\n      @io.eof?\n    end\n\n    def gets\n      print @prompt\n      l = @io.gets\n#      print @prompt, l\n      l\n    end\n  end\n\n  begin\n    require \"readline\"\n    class ReadlineInputMethod < InputMethod\n      include Readline \n      def initialize\n\tsuper\n\n\t@line_no = 0\n\t@line = []\n\t@eof = false\n      end\n\n      def gets\n\tif l = readline(@prompt, false)\n          HISTORY.push(l) if !l.empty?\n\t  @line[@line_no += 1] = l + \"\\n\"\n\telse\n\t  @eof = true\n\t  l\n\tend\n      end\n\n      def eof?\n\t@eof\n      end\n\n      def readable_atfer_eof?\n\ttrue\n      end\n\n      def line(line_no)\n\t@line[line_no]\n      end\n    end\n  rescue LoadError\n  end\nend\n"
  },
  {
    "path": "lib/irb/lc/error.rb",
    "content": "#\n#   irb/lc/error.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nrequire \"e2mmap\"\n\nmodule IRB\n\n  # exceptions\n  extend Exception2MessageMapper\n  def_exception :UnrecognizedSwitch, \"Unrecognized switch: %s\"\n  def_exception :NotImplementedError, \"Need to define `%s'\"\n  def_exception :CantReturnToNormalMode, \"Can't return to normal mode.\"\n  def_exception :IllegalParameter, \"Illegal parameter(%s).\"\n  def_exception :IrbAlreadyDead, \"Irb is already dead.\"\n  def_exception :IrbSwitchedToCurrentThread, \"Switched to current thread.\"\n  def_exception :NoSuchJob, \"No such job(%s).\"\n  def_exception :CantShiftToMultiIrbMode, \"Can't shift to multi irb mode.\"\n  def_exception :CantChangeBinding, \"Can't change binding to (%s).\"\n  def_exception :UndefinedPromptMode, \"Undefined prompt mode(%s).\"\n\nend\n\n"
  },
  {
    "path": "lib/irb/lc/help-message",
    "content": "#\n#   irb/lc/help-message.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nUsage:  irb.rb [options] [programfile] [arguments]\n  -f\t\t    Suppress read of ~/.irbrc \n  -m\t\t    Bc mode (load mathn, fraction or matrix are available)\n  -d                Set $DEBUG to true (same as `ruby -d')\n  -r load-module    Same as `ruby -r'\n  -I path           Specify $LOAD_PATH directory\n  --inspect\t    Use `inspect' for output (default except for bc mode)\n  --noinspect\t    Don't use inspect for output\n  --readline\t    Use Readline extension module\n  --noreadline\t    Don't use Readline extension module\n  --prompt prompt-mode\n  --prompt-mode prompt-mode\n\t\t    Switch prompt mode. Pre-defined prompt modes are\n\t\t    `default', `simple', `xmp' and `inf-ruby'\n  --inf-ruby-mode   Use prompt appropriate for inf-ruby-mode on emacs. \n\t\t    Suppresses --readline. \n  --simple-prompt   Simple prompt mode\n  --noprompt\t    No prompt mode\n  --tracer\t    Display trace for each execution of commands.\n  --back-trace-limit n\n\t\t    Display backtrace top n and tail n. The default\n\t\t    value is 16. \n  --irb_debug n\t    Set internal debug level to n (not for popular use)\n  -v, --version\t    Print the version of irb\n"
  },
  {
    "path": "lib/irb/lc/ja/error.rb",
    "content": "#\n#   irb/lc/ja/error.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nrequire \"e2mmap\"\n\nmodule IRB\n  # exceptions\n  extend Exception2MessageMapper\n  def_exception :UnrecognizedSwitch, '\u001b$B%9%$%C%A\u001b(B(%s)\u001b$B$,J,$j$^$;$s\u001b(B'\n  def_exception :NotImplementedError, '`%s\\'\u001b$B$NDj5A$,I,MW$G$9\u001b(B'\n  def_exception :CantReturnToNormalMode, 'Normal\u001b$B%b!<%I$KLa$l$^$;$s\u001b(B.'\n  def_exception :IllegalParameter, '\u001b$B%Q%i%a!<%?\u001b(B(%s)\u001b$B$,4V0c$C$F$$$^$9\u001b(B.'\n  def_exception :IrbAlreadyDead, 'Irb\u001b$B$O4{$K;`$s$G$$$^$9\u001b(B.'\n  def_exception :IrbSwitchedToCurrentThread, '\u001b$B%+%l%s%H%9%l%C%I$K@Z$jBX$o$j$^$7$?\u001b(B.'\n  def_exception :NoSuchJob, '\u001b$B$=$N$h$&$J%8%g%V\u001b(B(%s)\u001b$B$O$\"$j$^$;$s\u001b(B.'\n  def_exception :CantShiftToMultiIrbMode, 'multi-irb mode\u001b$B$K0\\$l$^$;$s\u001b(B.'\n  def_exception :CantChangeBinding, '\u001b$B%P%$%s%G%#%s%0\u001b(B(%s)\u001b$B$KJQ99$G$-$^$;$s\u001b(B.'\n  def_exception :UndefinedPromptMode, '\u001b$B%W%m%s%W%H%b!<%I\u001b(B(%s)\u001b$B$ODj5A$5$l$F$$$^$;$s\u001b(B.'\nend\n"
  },
  {
    "path": "lib/irb/lc/ja/help-message",
    "content": "#\n#   irb/lc/ja/help-message.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nUsage:  irb.rb [options] [programfile] [arguments]\n  -f\t\t    ~/.irbrc \u001b$B$rFI$_9~$^$J$$\u001b(B.\n  -m\t\t    bc\u001b$B%b!<%I\u001b(B(\u001b$BJ,?t\u001b(B, \u001b$B9TNs$N7W;;$,$G$-$k\u001b(B)\n  -d                $DEBUG \u001b$B$r\u001b(Btrue\u001b$B$K$9$k\u001b(B(ruby -d \u001b$B$HF1$8\u001b(B)\n  -r load-module    ruby -r \u001b$B$HF1$8\u001b(B.\n  -I path           $LOAD_PATH \u001b$B$K\u001b(B path \u001b$B$rDI2C$9$k\u001b(B.\n  --inspect\t    \u001b$B7k2L=PNO$K\u001b(Binspect\u001b$B$rMQ$$$k\u001b(B(bc\u001b$B%b!<%I0J30$O%G%U%)%k%H\u001b(B). \n  --noinspect\t    \u001b$B7k2L=PNO$K\u001b(Binspect\u001b$B$rMQ$$$J$$\u001b(B.\n  --readline\t    readline\u001b$B%i%$%V%i%j$rMxMQ$9$k\u001b(B.\n  --noreadline\t    readline\u001b$B%i%$%V%i%j$rMxMQ$7$J$$\u001b(B. \n  --prompt prompt-mode/--prompt-mode prompt-mode\n\t\t    \u001b$B%W%m%s%W%H%b!<%I$r@ZBX$($^$9\u001b(B. \u001b$B8=:_Dj5A$5$l$F$$$k%W\u001b(B\n\t\t    \u001b$B%m%s%W%H%b!<%I$O\u001b(B, default, simple, xmp, inf-ruby\u001b$B$,\u001b(B\n\t\t    \u001b$BMQ0U$5$l$F$$$^$9\u001b(B. \n  --inf-ruby-mode   emacs\u001b$B$N\u001b(Binf-ruby-mode\u001b$BMQ$N%W%m%s%W%HI=<($r9T$J$&\u001b(B. \u001b$BFC\u001b(B\n\t\t    \u001b$B$K;XDj$,$J$$8B$j\u001b(B, readline\u001b$B%i%$%V%i%j$O;H$o$J$/$J$k\u001b(B.\n  --simple-prompt   \u001b$BHs>o$K%7%s%W%k$J%W%m%s%W%H$rMQ$$$k%b!<%I$G$9\u001b(B.\n  --noprompt\t    \u001b$B%W%m%s%W%HI=<($r9T$J$o$J$$\u001b(B.\n  --tracer\t    \u001b$B%3%^%s%I<B9T;~$K%H%l!<%9$r9T$J$&\u001b(B.\n  --back-trace-limit n\n\t\t    \u001b$B%P%C%/%H%l!<%9I=<($r%P%C%/%H%l!<%9$NF,$+$i\u001b(B n, \u001b$B8e$m\u001b(B\n\t\t    \u001b$B$+$i\u001b(Bn\u001b$B$@$19T$J$&\u001b(B. \u001b$B%G%U%)%k%H$O\u001b(B16 \n  --irb_debug n\t    irb\u001b$B$N%G%P%C%0%G%P%C%0%l%Y%k$r\u001b(Bn\u001b$B$K@_Dj$9$k\u001b(B(\u001b$BMxMQ$7$J\u001b(B\n\t\t    \u001b$B$$J}$,L5Fq$G$7$g$&\u001b(B).\n  -v, --version\t    irb\u001b$B$N%P!<%8%g%s$rI=<($9$k\u001b(B\n"
  },
  {
    "path": "lib/irb/locale.rb",
    "content": "#\n#   irb/locale.rb - internationalization module\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nautoload :Kconv, \"kconv\"\n\nmodule IRB\n  class Locale\n    @RCS_ID='-$Id$-'\n\n    JPDefaultLocale = \"ja\"\n    LOCALE_DIR = \"/lc/\"\n\n    def initialize(locale = nil)\n      @lang = locale || ENV[\"IRB_LANG\"] || ENV[\"LC_MESSAGES\"] || ENV[\"LC_ALL\"] || ENV[\"LANG\"] || \"C\" \n    end\n\n    attr_reader :lang\n\n    def lc2kconv(lang)\n      case lang\n      when \"ja_JP.ujis\", \"ja_JP.euc\", \"ja_JP.eucJP\"\n        Kconv::EUC\n      when \"ja_JP.sjis\", \"ja_JP.SJIS\"\n        Kconv::SJIS\n      when /ja_JP.utf-?8/i\n\tKconv::UTF8\n      end\n    end\n    private :lc2kconv\n\n    def String(mes)\n      mes = super(mes)\n      case @lang\n      when /^ja/\n\tmes = Kconv::kconv(mes, lc2kconv(@lang))\n      else\n\tmes\n      end\n      mes\n    end\n\n    def format(*opts)\n      String(super(*opts))\n    end\n\n    def gets(*rs)\n      String(super(*rs))\n    end\n\n    def readline(*rs)\n      String(super(*rs))\n    end\n\n    def print(*opts)\n      ary = opts.collect{|opt| String(opt)}\n      super(*ary)\n    end\n\n    def printf(*opts)\n      s = format(*opts)\n      print s\n    end\n\n    def puts(*opts)\n      ary = opts.collect{|opt| String(opt)}\n      super(*ary)\n    end\n\n    def require(file, priv = nil)\n      rex = Regexp.new(\"lc/#{Regexp.quote(file)}\\.(so|o|sl|rb)?\")\n      return false if $\".find{|f| f =~ rex}\n\n      case file\n      when /\\.rb$/\n\tbegin\n\t  load(file, priv)\n\t  $\".push file\n\t  return true\n\trescue LoadError\n\tend\n      when /\\.(so|o|sl)$/\n\treturn super\n      end\n\n      begin\n\tload(f = file + \".rb\")\n\t$\".push f  #\"\n\treturn true\n      rescue LoadError\n\treturn ruby_require(file)\n      end\n    end\n\n    alias toplevel_load load\n    \n    def load(file, priv=nil)\n      dir = File.dirname(file)\n      dir = \"\" if dir == \".\"\n      base = File.basename(file)\n\n      if /^ja(_JP)?$/ =~ @lang\n \tback, @lang = @lang, \"C\"\n      end\n      begin\n\tif dir[0] == ?/ #/\n\t  lc_path = search_file(dir, base)\n\t  return real_load(lc_path, priv) if lc_path\n\tend\n\t\n\tfor path in $:\n\t  lc_path = search_file(path + \"/\" + dir, base)\n\t  return real_load(lc_path, priv) if lc_path\n\tend\n      ensure\n\t@lang = back if back\n      end\n      raise LoadError, \"No such file to load -- #{file}\"\n    end \n\n    def real_load(path, priv)\n      src = self.String(File.read(path))\n      if priv\n\teval(\"self\", TOPLEVEL_BINDING).extend(Module.new {eval(src, nil, path)})\n      else\n\teval(src, TOPLEVEL_BINDING, path)\n      end\n    end\n    private :real_load\n\n    def find(file , paths = $:)\n      dir = File.dirname(file)\n      dir = \"\" if dir == \".\"\n      base = File.basename(file)\n      if dir[0] == ?/ #/\n\t  return lc_path = search_file(dir, base)\n      else\n\tfor path in $:\n\t  if lc_path = search_file(path + \"/\" + dir, base)\n\t    return lc_path\n\t  end\n\tend\n      end\n      nil\n    end\n\n    def search_file(path, file)\n      if File.exist?(p1 = path + lc_path(file, \"C\"))\n\tif File.exist?(p2 = path + lc_path(file))\n\t  return p2\n\telse\n\tend\n\treturn p1\n      else\n      end\n      nil\n    end\n    private :search_file\n\n    def lc_path(file = \"\", lc = @lang)\n      case lc\n      when \"C\"\n\tLOCALE_DIR + file\n      when /^ja/\n\tLOCALE_DIR + \"ja/\" + file\n      else\n\tLOCALE_DIR + @lang + \"/\" + file\n      end\n    end\n    private :lc_path\n  end\nend\n\n\n\n\n"
  },
  {
    "path": "lib/irb/notifier.rb",
    "content": "#\n#   notifier.rb - output methods used by irb \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\nrequire \"irb/output-method\"\n\nmodule IRB\n  module Notifier\n    extend Exception2MessageMapper\n    def_exception :ErrUndefinedNotifier, \n      \"undefined notifier level: %d is specified\"\n    def_exception :ErrUnrecognizedLevel, \n      \"unrecognized notifier level: %s is specified\"\n\n    def def_notifier(prefix = \"\", output_method = StdioOutputMethod.new)\n      CompositeNotifier.new(prefix, output_method)\n    end\n    module_function :def_notifier\n  \n    class AbstructNotifier\n      def initialize(prefix, base_notifier)\n\t@prefix = prefix\n\t@base_notifier = base_notifier\n      end\n\n      attr_reader :prefix\n\n      def notify?\n\ttrue\n      end\n\n      def print(*opts)\n\t@base_notifier.print prefix, *opts if notify?\n      end\n\n      def printn(*opts)\n\t@base_notifier.printn prefix, *opts if notify?\n      end\n\n      def printf(format, *opts)\n\t@base_notifier.printf(prefix + format, *opts) if notify?\n      end\n\n      def puts(*objs)\n\tif notify?\n\t  @base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s})\n\tend\n      end\n\n      def pp(*objs)\n\tif notify?\n\t  @base_notifier.ppx @prefix, *objs\n\tend\n      end\n\n      def ppx(prefix, *objs)\n\tif notify?\n\t  @base_notifier.ppx @prefix+prefix, *objs\n\tend\n      end\n\n      def exec_if\n\tyield(@base_notifier) if notify?\n      end\n    end\n\n    class CompositeNotifier<AbstructNotifier\n      def initialize(prefix, base_notifier)\n\tsuper\n\n\t@notifiers = [D_NOMSG]\n\t@level_notifier = D_NOMSG\n      end\n\n      attr_reader :notifiers\n\n      def def_notifier(level, prefix = \"\")\n\tnotifier = LeveledNotifier.new(self, level, prefix)\n\t@notifiers[level] = notifier\n\tnotifier\n      end\n\n      attr_reader :level_notifier\n      alias level level_notifier\n\n      def level_notifier=(value)\n\tcase value\n\twhen AbstructNotifier\n\t  @level_notifier = value\n\twhen Integer\n\t  l = @notifiers[value]\n\t  Notifier.Raise ErrUndefinedNotifer, value unless l\n\t  @level_notifier = l\n\telse\n\t  Notifier.Raise ErrUnrecognizedLevel, value unless l\n\tend\n      end\n\n      alias level= level_notifier=\n    end\n\n    class LeveledNotifier<AbstructNotifier\n      include Comparable\n\n      def initialize(base, level, prefix)\n\tsuper(prefix, base)\n\t\n\t@level = level\n      end\n\n      attr_reader :level\n\n      def <=>(other)\n\t@level <=> other.level\n      end\n      \n      def notify?\n\t@base_notifier.level >= self\n      end\n    end\n\n    class NoMsgNotifier<LeveledNotifier\n      def initialize\n\t@base_notifier = nil\n\t@level = 0\n\t@prefix = \"\"\n      end\n\n      def notify?\n\tfalse\n      end\n    end\n\n    D_NOMSG = NoMsgNotifier.new\n  end\nend\n"
  },
  {
    "path": "lib/irb/output-method.rb",
    "content": "#\n#   output-method.rb - optput methods used by irb \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\n\nmodule IRB\n  # OutputMethod\n  #   StdioOutputMethod\n\n  class OutputMethod\n    @RCS_ID='-$Id$-'\n\n    def print(*opts)\n      IRB.fail NotImplementError, \"print\"\n    end\n\n    def printn(*opts)\n      print opts.join(\" \"), \"\\n\"\n    end\n\n    # extend printf\n    def printf(format, *opts)\n      if /(%*)%I/ =~ format\n\tformat, opts = parse_printf_format(format, opts)\n      end\n      print sprintf(format, *opts)\n    end\n\n    # %\n    # <ե饰>  [#0- +]\n    # <Ǿե> (\\*|\\*[1-9][0-9]*\\$|[1-9][0-9]*)\n    # <>.(\\*|\\*[1-9][0-9]*\\$|[1-9][0-9]*|)?\n    # #<Ĺʸ>(hh|h|l|ll|L|q|j|z|t)\n    # <Ѵʸ>[diouxXeEfgGcsb%] \n    def parse_printf_format(format, opts)\n      return format, opts if $1.size % 2 == 1\n    end\n\n    def foo(format)\n      pos = 0\n      inspects = []\n      format.scan(/%[#0\\-+ ]?(\\*(?=[^0-9])|\\*[1-9][0-9]*\\$|[1-9][0-9]*(?=[^0-9]))?(\\.(\\*(?=[^0-9])|\\*[1-9][0-9]*\\$|[1-9][0-9]*(?=[^0-9])))?(([1-9][0-9]*\\$)*)([diouxXeEfgGcsb%])/) {|f, p, pp, pos, new_pos, c|\n\tputs [f, p, pp, pos, new_pos, c].join(\"!\")\n\tpos = new_pos if new_pos\n\tif c == \"I\"\n\t  inspects.push pos.to_i \n\t  (f||\"\")+(p||\"\")+(pp||\"\")+(pos||\"\")+\"s\"\n\telse\n\t  $&\n\tend\n      }\n    end\n\n    def puts(*objs)\n      for obj in objs\n\tprint(*obj)\n\tprint \"\\n\"\n      end\n    end\n\n    def pp(*objs)\n      puts(*objs.collect{|obj| obj.inspect})\n    end\n\n    def ppx(prefix, *objs)\n      puts(*objs.collect{|obj| prefix+obj.inspect})\n    end\n\n  end\n\n  class StdioOutputMethod<OutputMethod\n    def print(*opts)\n      STDOUT.print(*opts)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/irb/ruby-lex.rb",
    "content": "#\n#   irb/ruby-lex.rb - ruby lexcal analyzer\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\nrequire \"irb/slex\"\nrequire \"irb/ruby-token\"\n\nclass RubyLex\n  @RCS_ID='-$Id$-'\n\n  extend Exception2MessageMapper\n  def_exception(:AlreadyDefinedToken, \"Already defined token(%s)\")\n  def_exception(:TkReading2TokenNoKey, \"key nothing(key='%s')\")\n  def_exception(:TkSymbol2TokenNoKey, \"key nothing(key='%s')\")\n  def_exception(:TkReading2TokenDuplicateError, \n\t\t\"key duplicate(token_n='%s', key='%s')\")\n  def_exception(:SyntaxError, \"%s\")\n\n  def_exception(:TerminateLineInput, \"Terminate Line Input\")\n  \n  include RubyToken\n\n  class << self\n    attr_accessor :debug_level\n    def debug?\n      @debug_level > 0\n    end\n  end\n  @debug_level = 0\n\n  def initialize\n    lex_init\n    set_input(STDIN)\n\n    @seek = 0\n    @exp_line_no = @line_no = 1\n    @base_char_no = 0\n    @char_no = 0\n    @rests = []\n    @readed = []\n    @here_readed = []\n\n    @indent = 0\n    @indent_stack = []\n    @lex_state = EXPR_BEG\n    @space_seen = false\n    @here_header = false\n    \n    @continue = false\n    @line = \"\"\n\n    @skip_space = false\n    @readed_auto_clean_up = false\n    @exception_on_syntax_error = true\n\n    @prompt = nil\n  end\n\n  attr_accessor :skip_space\n  attr_accessor :readed_auto_clean_up\n  attr_accessor :exception_on_syntax_error\n\n  attr_reader :seek\n  attr_reader :char_no\n  attr_reader :line_no\n  attr_reader :indent\n\n  # io functions\n  def set_input(io, p = nil, &block)\n    @io = io\n    if p.respond_to?(:call)\n      @input = p\n    elsif block_given?\n      @input = block\n    else\n      @input = Proc.new{@io.gets}\n    end\n  end\n\n  def get_readed\n    if idx = @readed.reverse.index(\"\\n\")\n      @base_char_no = idx\n    else\n      @base_char_no += @readed.size\n    end\n    \n    readed = @readed.join(\"\")\n    @readed = []\n    readed\n  end\n\n  def getc\n    while @rests.empty?\n#      return nil unless buf_input\n      @rests.push nil unless buf_input\n    end\n    c = @rests.shift\n    if @here_header\n      @here_readed.push c\n    else\n      @readed.push c\n    end\n    @seek += 1\n    if c == \"\\n\"\n      @line_no += 1 \n      @char_no = 0\n    else\n      @char_no += 1\n    end\n    c\n  end\n\n  def gets\n    l = \"\"\n    while c = getc\n      l.concat(c)\n      break if c == \"\\n\"\n    end\n    return nil if l == \"\" and c.nil?\n    l\n  end\n\n  def eof?\n    @io.eof?\n  end\n\n  def getc_of_rests\n    if @rests.empty?\n      nil\n    else\n      getc\n    end\n  end\n\n  def ungetc(c = nil)\n    if @here_readed.empty?\n      c2 = @readed.pop\n    else\n      c2 = @here_readed.pop\n    end\n    c = c2 unless c\n    @rests.unshift c #c = \n      @seek -= 1\n    if c == \"\\n\"\n      @line_no -= 1 \n      if idx = @readed.reverse.index(\"\\n\")\n\t@char_no = @readed.size - idx\n      else\n\t@char_no = @base_char_no + @readed.size\n      end\n    else\n      @char_no -= 1\n    end\n  end\n\n  def peek_equal?(str)\n    chrs = str.split(//)\n    until @rests.size >= chrs.size\n      return false unless buf_input\n    end\n    @rests[0, chrs.size] == chrs\n  end\n\n  def peek_match?(regexp)\n    while @rests.empty?\n      return false unless buf_input\n    end\n    regexp =~ @rests.join(\"\")\n  end\n\n  def peek(i = 0)\n    while @rests.size <= i\n      return nil unless buf_input\n    end\n    @rests[i]\n  end\n\n  def buf_input\n    prompt\n    line = @input.call\n    return nil unless line\n    @rests.concat line.split(//)\n    true\n  end\n  private :buf_input\n\n  def set_prompt(p = nil, &block)\n    p = block if block_given?\n    if p.respond_to?(:call)\n      @prompt = p\n    else\n      @prompt = Proc.new{print p}\n    end\n  end\n\n  def prompt\n    if @prompt\n      @prompt.call(@ltype, @indent, @continue, @line_no)\n    end\n  end\n\n  def initialize_input\n    @ltype = nil\n    @quoted = nil\n    @indent = 0\n    @indent_stack = []\n    @lex_state = EXPR_BEG\n    @space_seen = false\n    @here_header = false\n    \n    @continue = false\n    prompt\n\n    @line = \"\"\n    @exp_line_no = @line_no\n  end\n  \n  def each_top_level_statement\n    initialize_input\n    catch(:TERM_INPUT) do\n      loop do\n\tbegin\n\t  @continue = false\n\t  prompt\n\t  unless l = lex\n\t    throw :TERM_INPUT if @line == ''\n\t  else\n\t    #p l\n\t    @line.concat l\n\t    if @ltype or @continue or @indent > 0\n\t      next\n\t    end\n\t  end\n\t  if @line != \"\\n\"\n\t    yield @line, @exp_line_no\n\t  end\n\t  break unless l\n\t  @line = ''\n\t  @exp_line_no = @line_no\n\n\t  @indent = 0\n\t  @indent_stack = []\n\t  prompt\n\trescue TerminateLineInput\n\t  initialize_input\n\t  prompt\n\t  get_readed\n\tend\n      end\n    end\n  end\n\n  def lex\n    until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&\n\t     !@continue or\n\t     tk.nil?)\n      #p tk\n      #p @lex_state\n      #p self\n    end\n    line = get_readed\n    #      print self.inspect\n    if line == \"\" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?\n      nil\n    else\n      line\n    end\n  end\n\n  def token\n    #      require \"tracer\"\n    #      Tracer.on\n    @prev_seek = @seek\n    @prev_line_no = @line_no\n    @prev_char_no = @char_no\n    begin\n      begin\n\ttk = @OP.match(self)\n\t@space_seen = tk.kind_of?(TkSPACE)\n      rescue SyntaxError\n\traise if @exception_on_syntax_error\n\ttk = TkError.new(@seek, @line_no, @char_no)\n      end\n    end while @skip_space and tk.kind_of?(TkSPACE)\n    if @readed_auto_clean_up\n      get_readed\n    end\n    #      Tracer.off\n    tk\n  end\n  \n  ENINDENT_CLAUSE = [\n    \"case\", \"class\", \"def\", \"do\", \"for\", \"if\",\n    \"module\", \"unless\", \"until\", \"while\", \"begin\" #, \"when\"\n  ]\n  DEINDENT_CLAUSE = [\"end\" #, \"when\"\n  ]\n\n  PERCENT_LTYPE = {\n    \"q\" => \"\\'\",\n    \"Q\" => \"\\\"\",\n    \"x\" => \"\\`\",\n    \"r\" => \"/\",\n    \"w\" => \"]\",\n    \"W\" => \"]\",\n    \"s\" => \":\"\n  }\n  \n  PERCENT_PAREN = {\n    \"{\" => \"}\",\n    \"[\" => \"]\",\n    \"<\" => \">\",\n    \"(\" => \")\"\n  }\n\n  Ltype2Token = {\n    \"\\'\" => TkSTRING,\n    \"\\\"\" => TkSTRING,\n    \"\\`\" => TkXSTRING,\n    \"/\" => TkREGEXP,\n    \"]\" => TkDSTRING,\n    \":\" => TkSYMBOL\n  }\n  DLtype2Token = {\n    \"\\\"\" => TkDSTRING,\n    \"\\`\" => TkDXSTRING,\n    \"/\" => TkDREGEXP,\n  }\n\n  def lex_init()\n    @OP = IRB::SLex.new\n    @OP.def_rules(\"\\0\", \"\\004\", \"\\032\") do |op, io|\n      Token(TkEND_OF_SCRIPT)\n    end\n\n    @OP.def_rules(\" \", \"\\t\", \"\\f\", \"\\r\", \"\\13\") do |op, io|\n      @space_seen = true\n      while getc =~ /[ \\t\\f\\r\\13]/; end\n      ungetc\n      Token(TkSPACE)\n    end\n\n    @OP.def_rule(\"#\") do |op, io|\n      identify_comment\n    end\n\n    @OP.def_rule(\"=begin\",\n\t\t proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\\s/}) do \n      |op, io|\n      @ltype = \"=\"\n      until getc == \"\\n\"; end\n      until peek_equal?(\"=end\") && peek(4) =~ /\\s/\n\tuntil getc == \"\\n\"; end\n      end\n      gets\n      @ltype = nil\n      Token(TkRD_COMMENT)\n    end\n\n    @OP.def_rule(\"\\n\") do |op, io|\n      print \"\\\\n\\n\" if RubyLex.debug?\n      case @lex_state\n      when EXPR_BEG, EXPR_FNAME, EXPR_DOT\n\t@continue = true\n      else\n\t@continue = false\n\t@lex_state = EXPR_BEG\n\tuntil (@indent_stack.empty? || \n\t       [TkLPAREN, TkLBRACK, TkLBRACE, \n\t\t TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))\n\t  @indent_stack.pop\n\tend\n      end\n      @here_header = false\n      @here_readed = []\n      Token(TkNL)\n    end\n\n    @OP.def_rules(\"*\", \"**\",\t\n\t\t  \"=\", \"==\", \"===\", \n\t\t  \"=~\", \"<=>\",\t\n\t\t  \"<\", \"<=\",\n\t\t  \">\", \">=\", \">>\") do\n      |op, io|\n      case @lex_state\n      when EXPR_FNAME, EXPR_DOT\n\t@lex_state = EXPR_ARG\n      else\n\t@lex_state = EXPR_BEG\n      end\n      Token(op)\n    end\n\n    @OP.def_rules(\"!\", \"!=\", \"!~\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op)\n    end\n\n    @OP.def_rules(\"<<\") do\n      |op, io|\n      tk = nil\n      if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&\n\t  (@lex_state != EXPR_ARG || @space_seen)\n\tc = peek(0)\n\tif /\\S/ =~ c && (/[\"'`]/ =~ c || /[\\w_]/ =~ c || c == \"-\")\n\t  tk = identify_here_document\n\tend\n      end\n      unless tk\n\ttk = Token(op)\n\tcase @lex_state\n\twhen EXPR_FNAME, EXPR_DOT\n\t  @lex_state = EXPR_ARG\n\telse\n\t  @lex_state = EXPR_BEG\n\tend\n      end\n      tk\n    end\n\n    @OP.def_rules(\"'\", '\"') do\n      |op, io|\n      identify_string(op)\n    end\n\n    @OP.def_rules(\"`\") do\n      |op, io|\n      if @lex_state == EXPR_FNAME\n\t@lex_state = EXPR_END\n\tToken(op)\n      else\n\tidentify_string(op)\n      end\n    end\n\n    @OP.def_rules('?') do\n      |op, io|\n      if @lex_state == EXPR_END\n\t@lex_state = EXPR_BEG\n\tToken(TkQUESTION)\n      else\n\tch = getc\n\tif @lex_state == EXPR_ARG && ch =~ /\\s/\n\t  ungetc\n\t  @lex_state = EXPR_BEG;\n\t  Token(TkQUESTION)\n\telse\n\t  if (ch == '\\\\') \n\t    read_escape\n\t  end\n\t  @lex_state = EXPR_END\n\t  Token(TkINTEGER)\n\tend\n      end\n    end\n\n    @OP.def_rules(\"&\", \"&&\", \"|\", \"||\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op)\n    end\n    \n    @OP.def_rules(\"+=\", \"-=\", \"*=\", \"**=\", \n\t\t  \"&=\", \"|=\", \"^=\", \"<<=\", \">>=\", \"||=\", \"&&=\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      op =~ /^(.*)=$/\n      Token(TkOPASGN, $1)\n    end\n\n    @OP.def_rule(\"+@\", proc{|op, io| @lex_state == EXPR_FNAME}) do\n      |op, io|\n      @lex_state = EXPR_ARG\n      Token(op)\n    end\n\n    @OP.def_rule(\"-@\", proc{|op, io| @lex_state == EXPR_FNAME}) do\n      |op, io|\n      @lex_state = EXPR_ARG\n      Token(op)\n    end\n\n    @OP.def_rules(\"+\", \"-\") do\n      |op, io|\n      catch(:RET) do\n\tif @lex_state == EXPR_ARG\n\t  if @space_seen and peek(0) =~ /[0-9]/\n\t    throw :RET, identify_number\n\t  else\n\t    @lex_state = EXPR_BEG\n\t  end\n\telsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/\n\t  throw :RET, identify_number\n\telse\n\t  @lex_state = EXPR_BEG\n\tend\n\tToken(op)\n      end\n    end\n\n    @OP.def_rule(\".\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      if peek(0) =~ /[0-9]/\n\tungetc\n\tidentify_number\n      else\n\t# for \"obj.if\" etc.\n\t@lex_state = EXPR_DOT\n\tToken(TkDOT)\n      end\n    end\n\n    @OP.def_rules(\"..\", \"...\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op)\n    end\n\n    lex_int2\n  end\n  \n  def lex_int2\n    @OP.def_rules(\"]\", \"}\", \")\") do\n      |op, io|\n      @lex_state = EXPR_END\n      @indent -= 1\n      @indent_stack.pop\n      Token(op)\n    end\n\n    @OP.def_rule(\":\") do\n      |op, io|\n      if @lex_state == EXPR_END || peek(0) =~ /\\s/\n\t@lex_state = EXPR_BEG\n\tToken(TkCOLON)\n      else\n\t@lex_state = EXPR_FNAME;\n\tToken(TkSYMBEG)\n      end\n    end\n\n    @OP.def_rule(\"::\") do\n       |op, io|\n#      p @lex_state.id2name, @space_seen\n      if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen\n\t@lex_state = EXPR_BEG\n\tToken(TkCOLON3)\n      else\n\t@lex_state = EXPR_DOT\n\tToken(TkCOLON2)\n      end\n    end\n\n    @OP.def_rule(\"/\") do\n      |op, io|\n      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\tidentify_string(op)\n      elsif peek(0) == '='\n\tgetc\n\t@lex_state = EXPR_BEG\n\tToken(TkOPASGN, \"/\") #/)\n      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\\s/\n\tidentify_string(op)\n      else \n\t@lex_state = EXPR_BEG\n\tToken(\"/\") #/)\n      end\n    end\n\n    @OP.def_rules(\"^\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(\"^\")\n    end\n\n    #       @OP.def_rules(\"^=\") do\n    # \t@lex_state = EXPR_BEG\n    # \tToken(OP_ASGN, :^)\n    #       end\n    \n    @OP.def_rules(\",\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op)\n    end\n\n    @OP.def_rules(\";\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      until (@indent_stack.empty? || \n\t     [TkLPAREN, TkLBRACK, TkLBRACE, \n\t       TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))\n\t@indent_stack.pop\n      end\n      Token(op)\n    end\n\n    @OP.def_rule(\"~\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(\"~\")\n    end\n\n    @OP.def_rule(\"~@\", proc{|op, io| @lex_state == EXPR_FNAME}) do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(\"~\")\n    end\n    \n    @OP.def_rule(\"(\") do\n      |op, io|\n      @indent += 1\n      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\t@lex_state = EXPR_BEG\n\ttk_c = TkfLPAREN\n      else\n\t@lex_state = EXPR_BEG\n\ttk_c = TkLPAREN\n      end\n      @indent_stack.push tk_c\n      tk = Token(tk_c)\n    end\n\n    @OP.def_rule(\"[]\", proc{|op, io| @lex_state == EXPR_FNAME}) do\n      |op, io|\n      @lex_state = EXPR_ARG\n      Token(\"[]\")\n    end\n\n    @OP.def_rule(\"[]=\", proc{|op, io| @lex_state == EXPR_FNAME}) do\n      |op, io|\n      @lex_state = EXPR_ARG\n      Token(\"[]=\")\n    end\n\n    @OP.def_rule(\"[\") do\n      |op, io|\n      @indent += 1\n      if @lex_state == EXPR_FNAME\n\ttk_c = TkfLBRACK\n      else\n\tif @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\t  tk_c = TkLBRACK\n\telsif @lex_state == EXPR_ARG && @space_seen\n\t  tk_c = TkLBRACK\n\telse\n\t  tk_c = TkfLBRACK\n\tend\n\t@lex_state = EXPR_BEG\n      end\n      @indent_stack.push tk_c\n      Token(tk_c)\n    end\n\n    @OP.def_rule(\"{\") do\n      |op, io|\n      @indent += 1\n      if @lex_state != EXPR_END && @lex_state != EXPR_ARG\n\ttk_c = TkLBRACE\n      else\n\ttk_c = TkfLBRACE\n      end\n      @lex_state = EXPR_BEG\n      @indent_stack.push tk_c\n      Token(tk_c)\n    end\n\n    @OP.def_rule('\\\\') do\n      |op, io|\n      if getc == \"\\n\"\n\t@space_seen = true\n\t@continue = true\n\tToken(TkSPACE)\n      else\n\tungetc\n\tToken(\"\\\\\")\n      end\n    end\n\n    @OP.def_rule('%') do\n      |op, io|\n      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\tidentify_quotation\n      elsif peek(0) == '='\n\tgetc\n\tToken(TkOPASGN, :%)\n      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\\s/\n\tidentify_quotation\n      else\n\t@lex_state = EXPR_BEG\n\tToken(\"%\") #))\n      end\n    end\n\n    @OP.def_rule('$') do\n      |op, io|\n      identify_gvar\n    end\n\n    @OP.def_rule('@') do\n      |op, io|\n      if peek(0) =~ /[\\w_@]/\n\tungetc\n\tidentify_identifier\n      else\n\tToken(\"@\")\n      end\n    end\n\n    #       @OP.def_rule(\"def\", proc{|op, io| /\\s/ =~ io.peek(0)}) do \n    # \t|op, io|\n    # \t@indent += 1\n    # \t@lex_state = EXPR_FNAME\n    # #\t@lex_state = EXPR_END\n    # #\tuntil @rests[0] == \"\\n\" or @rests[0] == \";\"\n    # #\t  rests.shift\n    # #\tend\n    #       end\n\n    @OP.def_rule(\"\") do\n      |op, io|\n      printf \"MATCH: start %s: %s\\n\", op, io.inspect if RubyLex.debug?\n      if peek(0) =~ /[0-9]/\n\tt = identify_number\n      elsif peek(0) =~ /[\\w_]/\n\tt = identify_identifier\n      end\n      printf \"MATCH: end %s: %s\\n\", op, io.inspect if RubyLex.debug?\n      t\n    end\n    \n    p @OP if RubyLex.debug?\n  end\n  \n  def identify_gvar\n    @lex_state = EXPR_END\n    \n    case ch = getc\n    when /[~_*$?!@\\/\\\\;,=:<>\".]/   #\"\n      Token(TkGVAR, \"$\" + ch)\n    when \"-\"\n      Token(TkGVAR, \"$-\" + getc)\n    when \"&\", \"`\", \"'\", \"+\"\n      Token(TkBACK_REF, \"$\"+ch)\n    when /[1-9]/\n      while getc =~ /[0-9]/; end\n      ungetc\n      Token(TkNTH_REF)\n    when /\\w/\n      ungetc\n      ungetc\n      identify_identifier\n    else \n      ungetc\n      Token(\"$\")\n    end\n  end\n  \n  def identify_identifier\n    token = \"\"\n    if peek(0) =~ /[$@]/\n      token.concat(c = getc)\n      if c == \"@\" and peek(0) == \"@\"\n\ttoken.concat getc\n      end\n    end\n\n    while (ch = getc) =~ /\\w|_/\n      print \":\", ch, \":\" if RubyLex.debug?\n      token.concat ch\n    end\n    ungetc\n    \n    if (ch == \"!\" || ch == \"?\") && token[0,1] =~ /\\w/ && peek(0) != \"=\"\n      token.concat getc\n    end\n\n    # almost fix token\n\n    case token\n    when /^\\$/\n      return Token(TkGVAR, token)\n    when /^\\@\\@/\n      @lex_state = EXPR_END\n      # p Token(TkCVAR, token)\n      return Token(TkCVAR, token)\n    when /^\\@/\n      @lex_state = EXPR_END\n      return Token(TkIVAR, token)\n    end\n    \n    if @lex_state != EXPR_DOT\n      print token, \"\\n\" if RubyLex.debug?\n\n      token_c, *trans = TkReading2Token[token]\n      if token_c\n\t# reserved word?\n\n\tif (@lex_state != EXPR_BEG &&\n\t    @lex_state != EXPR_FNAME &&\n\t    trans[1])\n\t  # modifiers\n\t  token_c = TkSymbol2Token[trans[1]]\n\t  @lex_state = trans[0]\n\telse\n\t  if @lex_state != EXPR_FNAME\n\t    if ENINDENT_CLAUSE.include?(token)\n\t      # check for ``class = val'' etc.\n\t      valid = true\n\t      case token\n\t      when \"class\"\n\t\tvalid = false unless peek_match?(/^\\s*(<<|\\w|::)/)\n\t      when \"def\"\n\t\tvalid = false if peek_match?(/^\\s*(([+-\\/*&\\|^]|<<|>>|\\|\\||\\&\\&)=|\\&\\&|\\|\\|)/)\n\t      when \"do\"\n\t\tvalid = false if peek_match?(/^\\s*([+-\\/*]?=|\\*|<|>|\\&)/)\n\t      when *ENINDENT_CLAUSE\n\t\tvalid = false if peek_match?(/^\\s*([+-\\/*]?=|\\*|<|>|\\&|\\|)/)\n\t      else\n\t\t# no nothing\n\t      end\n\t      if valid\n\t\tif token == \"do\"\n\t\t  if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last)\n\t\t    @indent += 1\n\t\t    @indent_stack.push token_c\n\t\t  end\n\t\telse\n\t\t  @indent += 1\n\t\t  @indent_stack.push token_c\n\t\tend\n#\t\tp @indent_stack\n\t      end\n\n\t    elsif DEINDENT_CLAUSE.include?(token)\n\t      @indent -= 1\n\t      @indent_stack.pop\n\t    end\n\t    @lex_state = trans[0]\n\t  else\n\t    @lex_state = EXPR_END\n\t  end\n\tend\n\treturn Token(token_c, token)\n      end\n    end\n\n    if @lex_state == EXPR_FNAME\n      @lex_state = EXPR_END\n      if peek(0) == '='\n\ttoken.concat getc\n      end\n    elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT\n      @lex_state = EXPR_ARG\n    else\n      @lex_state = EXPR_END\n    end\n\n    if token[0, 1] =~ /[A-Z]/\n      return Token(TkCONSTANT, token)\n    elsif token[token.size - 1, 1] =~ /[!?]/\n      return Token(TkFID, token)\n    else\n      return Token(TkIDENTIFIER, token)\n    end\n  end\n\n  def identify_here_document\n    ch = getc\n#    if lt = PERCENT_LTYPE[ch]\n    if ch == \"-\"\n      ch = getc\n      indent = true\n    end\n    if /['\"`]/ =~ ch\n      lt = ch\n      quoted = \"\"\n      while (c = getc) && c != lt\n\tquoted.concat c\n      end\n    else\n      lt = '\"'\n      quoted = ch.dup\n      while (c = getc) && c =~ /\\w/\n\tquoted.concat c\n      end\n      ungetc\n    end\n\n    ltback, @ltype = @ltype, lt\n    reserve = []\n    while ch = getc\n      reserve.push ch\n      if ch == \"\\\\\"\n\treserve.push ch = getc\n      elsif ch == \"\\n\"\n\tbreak\n      end\n    end\n\n    @here_header = false\n    while l = gets\n      l = l.sub(/(:?\\r)?\\n\\z/, '')\n      if (indent ? l.strip : l) == quoted\n \tbreak\n      end\n    end\n\n    @here_header = true\n    @here_readed.concat reserve\n    while ch = reserve.pop\n      ungetc ch\n    end\n\n    @ltype = ltback\n    @lex_state = EXPR_END\n    Token(Ltype2Token[lt])\n  end\n  \n  def identify_quotation\n    ch = getc\n    if lt = PERCENT_LTYPE[ch]\n      ch = getc\n    elsif ch =~ /\\W/\n      lt = \"\\\"\"\n    else\n      RubyLex.fail SyntaxError, \"unknown type of %string\"\n    end\n#     if ch !~ /\\W/\n#       ungetc\n#       next\n#     end\n    #@ltype = lt\n    @quoted = ch unless @quoted = PERCENT_PAREN[ch]\n    identify_string(lt, @quoted)\n  end\n\n  def identify_number\n    @lex_state = EXPR_END\n\n    if peek(0) == \"0\" && peek(1) !~ /[.eE]/\n      getc\n      case peek(0)\n      when /[xX]/\n\tch = getc\n\tmatch = /[0-9a-fA-F_]/\n      when /[bB]/\n\tch = getc\n\tmatch = /[01_]/\n      when /[oO]/\n\tch = getc\n\tmatch = /[0-7_]/\n      when /[dD]/\n\tch = getc\n\tmatch = /[0-9_]/\n      when /[0-7]/\n\tmatch = /[0-7_]/\n      when /[89]/\n\tRubyLex.fail SyntaxError, \"Illegal octal digit\"\n      else \n\treturn Token(TkINTEGER)\n      end\n      \n      len0 = true\n      non_digit = false\n      while ch = getc\n\tif match =~ ch\n\t  if ch == \"_\"\n\t    if non_digit\n\t      RubyLex.fail SyntaxError, \"trailing `#{ch}' in number\"\n\t    else\n\t      non_digit = ch\n\t    end\n\t  else\n\t    non_digit = false\n\t    len0 = false\n\t  end\n\telse\n\t  ungetc\n\t  if len0\n\t    RubyLex.fail SyntaxError, \"numeric literal without digits\"\n\t  end\n\t  if non_digit\n\t    RubyLex.fail SyntaxError, \"trailing `#{non_digit}' in number\"\n\t  end\n\t  break\n\tend\n      end\n      return Token(TkINTEGER)\n    end\n    \n    type = TkINTEGER\n    allow_point = true\n    allow_e = true\n    non_digit = false\n    while ch = getc\n      case ch\n      when /[0-9]/\n\tnon_digit = false\n      when \"_\"\n\tnon_digit = ch\n      when allow_point && \".\"\n\tif non_digit\n\t  RubyLex.fail SyntaxError, \"trailing `#{non_digit}' in number\"\n\tend\n\ttype = TkFLOAT\n\tif peek(0) !~ /[0-9]/\n\t  type = TkINTEGER\n\t  ungetc\n\t  break\n\tend\n\tallow_point = false\n      when allow_e && \"e\", allow_e && \"E\"\n\tif non_digit\n\t  RubyLex.fail SyntaxError, \"trailing `#{non_digit}' in number\"\n\tend\n\ttype = TkFLOAT\n\tif peek(0) =~ /[+-]/\n\t  getc\n\tend\n\tallow_e = false\n\tallow_point = false\n\tnon_digit = ch\n      else\n\tif non_digit\n\t  RubyLex.fail SyntaxError, \"trailing `#{non_digit}' in number\"\n\tend\n\tungetc\n\tbreak\n      end\n    end\n    Token(type)\n  end\n  \n  def identify_string(ltype, quoted = ltype)\n    @ltype = ltype\n    @quoted = quoted\n    subtype = nil\n    begin\n      nest = 0\n      while ch = getc\n\tif @quoted == ch and nest == 0\n\t  break\n\telsif @ltype != \"'\" && @ltype != \"]\" && @ltype != \":\" and ch == \"#\"\n\t  subtype = true\n\telsif ch == '\\\\' #'\n\t  read_escape\n\tend\n\tif PERCENT_PAREN.values.include?(@quoted) \n\t  if PERCENT_PAREN[ch] == @quoted\n\t    nest += 1\n\t  elsif ch == @quoted\n\t    nest -= 1\n\t  end\n\tend\n      end\n      if @ltype == \"/\"\n\tif peek(0) =~ /i|m|x|o|e|s|u|n/\n\t  getc\n\tend\n      end\n      if subtype\n\tToken(DLtype2Token[ltype])\n      else\n\tToken(Ltype2Token[ltype])\n      end\n    ensure\n      @ltype = nil\n      @quoted = nil\n      @lex_state = EXPR_END\n    end\n  end\n  \n  def identify_comment\n    @ltype = \"#\"\n\n    while ch = getc\n#      if ch == \"\\\\\" #\"\n#\tread_escape\n#      end\n      if ch == \"\\n\"\n\t@ltype = nil\n\tungetc\n\tbreak\n      end\n    end\n    return Token(TkCOMMENT)\n  end\n  \n  def read_escape\n    case ch = getc\n    when \"\\n\", \"\\r\", \"\\f\"\n    when \"\\\\\", \"n\", \"t\", \"r\", \"f\", \"v\", \"a\", \"e\", \"b\", \"s\" #\"\n    when /[0-7]/\n      ungetc ch\n      3.times do\n\tcase ch = getc\n\twhen /[0-7]/\n\twhen nil\n\t  break\n\telse\n\t  ungetc\n\t  break\n\tend\n      end\n      \n    when \"x\"\n      2.times do\n\tcase ch = getc\n\twhen /[0-9a-fA-F]/\n\twhen nil\n\t  break\n\telse\n\t  ungetc\n\t  break\n\tend\n      end\n\n    when \"M\"\n      if (ch = getc) != '-'\n\tungetc\n      else\n\tif (ch = getc) == \"\\\\\" #\"\n\t  read_escape\n\tend\n      end\n\n    when \"C\", \"c\" #, \"^\"\n      if ch == \"C\" and (ch = getc) != \"-\"\n\tungetc\n      elsif (ch = getc) == \"\\\\\" #\"\n\tread_escape\n      end\n    else\n      # other characters \n    end\n  end\nend\n"
  },
  {
    "path": "lib/irb/ruby-token.rb",
    "content": "#\n#   irb/ruby-token.rb - ruby tokens \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nmodule RubyToken\n  EXPR_BEG = :EXPR_BEG\n  EXPR_MID = :EXPR_MID\n  EXPR_END = :EXPR_END\n  EXPR_ARG = :EXPR_ARG\n  EXPR_FNAME = :EXPR_FNAME\n  EXPR_DOT = :EXPR_DOT\n  EXPR_CLASS = :EXPR_CLASS\n\n  # for ruby 1.4X\n  if !defined?(Symbol)\n    Symbol = Integer\n  end\n  \n  class Token\n    def initialize(seek, line_no, char_no)\n      @seek = seek\n      @line_no = line_no\n      @char_no = char_no\n    end\n    attr :seek\n    attr :line_no\n    attr :char_no\n  end\n\n  class TkNode < Token\n    def initialize(seek, line_no, char_no)\n      super\n    end\n    attr :node\n  end\n\n  class TkId < Token\n    def initialize(seek, line_no, char_no, name)\n      super(seek, line_no, char_no)\n      @name = name\n    end\n    attr :name\n  end\n\n  class TkVal < Token\n    def initialize(seek, line_no, char_no, value = nil)\n      super(seek, line_no, char_no)\n      @value = value\n    end\n    attr :value\n  end\n\n  class TkOp < Token\n    attr :name, true\n  end\n\n  class TkOPASGN < TkOp\n    def initialize(seek, line_no, char_no, op)\n      super(seek, line_no, char_no)\n      op = TkReading2Token[op][0] unless op.kind_of?(Symbol)\n      @op = op\n    end\n    attr :op\n  end\n\n  class TkUnknownChar < Token\n    def initialize(seek, line_no, char_no, id)\n      super(seek, line_no, char_no)\n      @name = name\n    end\n    attr :name\n  end\n\n  class TkError < Token\n  end\n\n  def Token(token, value = nil)\n    case token\n    when String\n      if (tk = TkReading2Token[token]).nil?\n\tIRB.fail TkReading2TokenNoKey, token\n      end\n      tk = Token(tk[0], value) \n      if tk.kind_of?(TkOp)\n\ttk.name = token\n      end\n      return tk\n    when Symbol\n      if (tk = TkSymbol2Token[token]).nil?\n\tIRB.fail TkSymbol2TokenNoKey, token\n      end\n      return Token(tk[0], value) \n    else \n      if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?\n\ttoken.new(@prev_seek, @prev_line_no, @prev_char_no)\n      else\n\ttoken.new(@prev_seek, @prev_line_no, @prev_char_no, value)\n      end\n    end\n  end\n\n  TokenDefinitions = [\n    [:TkCLASS,      TkId,  \"class\",  EXPR_CLASS],\n    [:TkMODULE,     TkId,  \"module\", EXPR_BEG],\n    [:TkDEF,\t    TkId,  \"def\",    EXPR_FNAME],\n    [:TkUNDEF,      TkId,  \"undef\",  EXPR_FNAME],\n    [:TkBEGIN,      TkId,  \"begin\",  EXPR_BEG],\n    [:TkRESCUE,     TkId,  \"rescue\", EXPR_MID],\n    [:TkENSURE,     TkId,  \"ensure\", EXPR_BEG],\n    [:TkEND,\t    TkId,  \"end\",    EXPR_END],\n    [:TkIF,         TkId,  \"if\",     EXPR_BEG, :TkIF_MOD],\n    [:TkUNLESS,     TkId,  \"unless\", EXPR_BEG, :TkUNLESS_MOD],\n    [:TkTHEN,\t    TkId,  \"then\",   EXPR_BEG],\n    [:TkELSIF,      TkId,  \"elsif\",  EXPR_BEG],\n    [:TkELSE,\t    TkId,  \"else\",   EXPR_BEG],\n    [:TkCASE,\t    TkId,  \"case\",   EXPR_BEG],\n    [:TkWHEN,\t    TkId,  \"when\",   EXPR_BEG],\n    [:TkWHILE,      TkId,  \"while\",  EXPR_BEG, :TkWHILE_MOD],\n    [:TkUNTIL,      TkId,  \"until\",  EXPR_BEG, :TkUNTIL_MOD],\n    [:TkFOR,\t    TkId,  \"for\",    EXPR_BEG],\n    [:TkBREAK,      TkId,  \"break\",  EXPR_END],\n    [:TkNEXT,\t    TkId,  \"next\",   EXPR_END],\n    [:TkREDO,\t    TkId,  \"redo\",   EXPR_END],\n    [:TkRETRY,      TkId,  \"retry\",  EXPR_END],\n    [:TkIN,\t    TkId,  \"in\",     EXPR_BEG],\n    [:TkDO,\t    TkId,  \"do\",     EXPR_BEG],\n    [:TkRETURN,     TkId,  \"return\", EXPR_MID],\n    [:TkYIELD,      TkId,  \"yield\",  EXPR_END],\n    [:TkSUPER,      TkId,  \"super\",  EXPR_END],\n    [:TkSELF,\t    TkId,  \"self\",   EXPR_END],\n    [:TkNIL, \t    TkId,  \"nil\",    EXPR_END],\n    [:TkTRUE,\t    TkId,  \"true\",   EXPR_END],\n    [:TkFALSE,      TkId,  \"false\",  EXPR_END],\n    [:TkAND,\t    TkId,  \"and\",    EXPR_BEG],\n    [:TkOR, \t    TkId,  \"or\",     EXPR_BEG],\n    [:TkNOT,\t    TkId,  \"not\",    EXPR_BEG],\n    [:TkIF_MOD,     TkId],\n    [:TkUNLESS_MOD, TkId],\n    [:TkWHILE_MOD,  TkId],\n    [:TkUNTIL_MOD,  TkId],\n    [:TkALIAS,      TkId,  \"alias\",    EXPR_FNAME],\n    [:TkDEFINED,    TkId,  \"defined?\", EXPR_END],\n    [:TklBEGIN,     TkId,  \"BEGIN\",    EXPR_END],\n    [:TklEND,\t    TkId,  \"END\",      EXPR_END],\n    [:Tk__LINE__,   TkId,  \"__LINE__\", EXPR_END],\n    [:Tk__FILE__,   TkId,  \"__FILE__\", EXPR_END],\n\n    [:TkIDENTIFIER, TkId],\n    [:TkFID,\t    TkId],\n    [:TkGVAR,\t    TkId],\n    [:TkCVAR,\t    TkId],\n    [:TkIVAR,\t    TkId],\n    [:TkCONSTANT,   TkId],\n\n    [:TkINTEGER,    TkVal],\n    [:TkFLOAT,      TkVal],\n    [:TkSTRING,     TkVal],\n    [:TkXSTRING,    TkVal],\n    [:TkREGEXP,     TkVal],\n    [:TkSYMBOL,     TkVal],\n\n    [:TkDSTRING,    TkNode],\n    [:TkDXSTRING,   TkNode],\n    [:TkDREGEXP,    TkNode],\n    [:TkNTH_REF,    TkNode],\n    [:TkBACK_REF,   TkNode],\n\n    [:TkUPLUS,      TkOp,   \"+@\"],\n    [:TkUMINUS,     TkOp,   \"-@\"],\n    [:TkPOW,\t    TkOp,   \"**\"],\n    [:TkCMP,\t    TkOp,   \"<=>\"],\n    [:TkEQ,\t    TkOp,   \"==\"],\n    [:TkEQQ,\t    TkOp,   \"===\"],\n    [:TkNEQ,\t    TkOp,   \"!=\"],\n    [:TkGEQ,\t    TkOp,   \">=\"],\n    [:TkLEQ,\t    TkOp,   \"<=\"],\n    [:TkANDOP,      TkOp,   \"&&\"],\n    [:TkOROP,\t    TkOp,   \"||\"],\n    [:TkMATCH,      TkOp,   \"=~\"],\n    [:TkNMATCH,     TkOp,   \"!~\"],\n    [:TkDOT2,\t    TkOp,   \"..\"],\n    [:TkDOT3,\t    TkOp,   \"...\"],\n    [:TkAREF,\t    TkOp,   \"[]\"],\n    [:TkASET,\t    TkOp,   \"[]=\"],\n    [:TkLSHFT,      TkOp,   \"<<\"],\n    [:TkRSHFT,      TkOp,   \">>\"],\n    [:TkCOLON2,     TkOp],\n    [:TkCOLON3,     TkOp],\n#   [:OPASGN,\t    TkOp],               # +=, -=  etc. #\n    [:TkASSOC,      TkOp,   \"=>\"],\n    [:TkQUESTION,   TkOp,   \"?\"],\t #?\n    [:TkCOLON,      TkOp,   \":\"],        #:\n    \n    [:TkfLPAREN],         # func( #\n    [:TkfLBRACK],         # func[ #\n    [:TkfLBRACE],         # func{ #\n    [:TkSTAR],            # *arg\n    [:TkAMPER],           # &arg #\n    [:TkSYMBEG],          # :SYMBOL\n\n    [:TkGT,\t    TkOp,   \">\"],\n    [:TkLT,\t    TkOp,   \"<\"],\n    [:TkPLUS,\t    TkOp,   \"+\"],\n    [:TkMINUS,      TkOp,   \"-\"],\n    [:TkMULT,\t    TkOp,   \"*\"],\n    [:TkDIV,\t    TkOp,   \"/\"],\n    [:TkMOD,\t    TkOp,   \"%\"],\n    [:TkBITOR,      TkOp,   \"|\"],\n    [:TkBITXOR,     TkOp,   \"^\"],\n    [:TkBITAND,     TkOp,   \"&\"],\n    [:TkBITNOT,     TkOp,   \"~\"],\n    [:TkNOTOP,      TkOp,   \"!\"],\n\n    [:TkBACKQUOTE,  TkOp,   \"`\"],\n\n    [:TkASSIGN,     Token,  \"=\"],\n    [:TkDOT,\t    Token,  \".\"],\n    [:TkLPAREN,     Token,  \"(\"],  #(exp)\n    [:TkLBRACK,     Token,  \"[\"],  #[arry]\n    [:TkLBRACE,     Token,  \"{\"],  #{hash}\n    [:TkRPAREN,     Token,  \")\"],\n    [:TkRBRACK,     Token,  \"]\"],\n    [:TkRBRACE,     Token,  \"}\"],\n    [:TkCOMMA,      Token,  \",\"],\n    [:TkSEMICOLON,  Token,  \";\"],\n\n    [:TkCOMMENT],\n    [:TkRD_COMMENT],\n    [:TkSPACE],\n    [:TkNL],\n    [:TkEND_OF_SCRIPT],\n\n    [:TkBACKSLASH,  TkUnknownChar,  \"\\\\\"],\n    [:TkAT,\t    TkUnknownChar,  \"@\"],\n    [:TkDOLLAR,     TkUnknownChar,  \"$\"],\n  ]\n\n  # {reading => token_class}\n  # {reading => [token_class, *opt]}\n  TkReading2Token = {}\n  TkSymbol2Token = {}\n\n  def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)\n    token_n = token_n.id2name if token_n.kind_of?(Symbol)\n    if RubyToken.const_defined?(token_n)\n      IRB.fail AlreadyDefinedToken, token_n\n    end\n    token_c = eval(\"class #{token_n} < #{super_token}; end; #{token_n}\")\n    \n    if reading\n      if TkReading2Token[reading]\n\tIRB.fail TkReading2TokenDuplicateError, token_n, reading\n      end\n      if opts.empty?\n\tTkReading2Token[reading] = [token_c]\n      else\n\tTkReading2Token[reading] = [token_c].concat(opts)\n      end\n    end\n    TkSymbol2Token[token_n.intern] = token_c\n  end\n\n  for defs in TokenDefinitions\n    def_token(*defs)\n  end\nend\n"
  },
  {
    "path": "lib/irb/slex.rb",
    "content": "#\n#   irb/slex.rb - simple lex analyzer\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\nrequire \"irb/notifier\"\n\nmodule IRB\n  class SLex\n    @RCS_ID='-$Id$-'\n\n    extend Exception2MessageMapper\n    def_exception :ErrNodeNothing, \"node nothing\"\n    def_exception :ErrNodeAlreadyExists, \"node already exists\"\n\n    DOUT = Notifier::def_notifier(\"SLex::\")\n    D_WARN = DOUT::def_notifier(1, \"Warn: \")\n    D_DEBUG = DOUT::def_notifier(2, \"Debug: \")\n    D_DETAIL = DOUT::def_notifier(4, \"Detail: \")\n    \n    DOUT.level = Notifier::D_NOMSG\n\n    def initialize\n      @head = Node.new(\"\")\n    end\n    \n    def def_rule(token, preproc = nil, postproc = nil, &block)\n      D_DETAIL.pp token\n\n      postproc = block if block_given?\n      node = create(token, preproc, postproc)\n    end\n    \n    def def_rules(*tokens, &block)\n      if block_given?\n\tp = block\n      end\n      for token in tokens\n\tdef_rule(token, nil, p)\n      end\n    end\n    \n    def preproc(token, proc)\n      node = search(token)\n      node.preproc=proc\n    end\n    \n    #\u001b$BMW%A%'%C%/\u001b(B? \n    def postproc(token)\n      node = search(token, proc)\n      node.postproc=proc\n    end\n    \n    def search(token)\n      @head.search(token.split(//))\n    end\n\n    def create(token, preproc = nil, postproc = nil)\n      @head.create_subnode(token.split(//), preproc, postproc)\n    end\n    \n    def match(token)\n      case token\n      when Array\n      when String\n\treturn match(token.split(//))\n      else\n\treturn @head.match_io(token)\n      end\n      ret = @head.match(token)\n      D_DETAIL.exec_if{D_DEATIL.printf \"match end: %s:%s\\n\", ret, token.inspect}\n      ret\n    end\n    \n    def inspect\n      format(\"<SLex: @head = %s>\", @head.inspect)\n    end\n\n    #----------------------------------------------------------------------\n    #\n    #   class Node - \n    #\n    #----------------------------------------------------------------------\n    class Node\n      # if postproc is nil, this node is an abstract node.\n      # if postproc is non-nil, this node is a real node.\n      def initialize(preproc = nil, postproc = nil)\n\t@Tree = {}\n\t@preproc = preproc\n\t@postproc = postproc\n      end\n\n      attr_accessor :preproc\n      attr_accessor :postproc\n      \n      def search(chrs, opt = nil)\n\treturn self if chrs.empty?\n\tch = chrs.shift\n\tif node = @Tree[ch]\n\t  node.search(chrs, opt)\n\telse\n\t  if opt\n\t    chrs.unshift ch\n\t    self.create_subnode(chrs)\n\t  else\n\t    SLex.fail ErrNodeNothing\n\t  end\n\tend\n      end\n      \n      def create_subnode(chrs, preproc = nil, postproc = nil)\n\tif chrs.empty?\n\t  if @postproc\n\t    D_DETAIL.pp node\n\t    SLex.fail ErrNodeAlreadyExists\n\t  else\n\t    D_DEBUG.puts \"change abstract node to real node.\"\n\t    @preproc = preproc\n\t    @postproc = postproc\n\t  end\n\t  return self\n\tend\n\t\n\tch = chrs.shift\n\tif node = @Tree[ch]\n\t  if chrs.empty?\n\t    if node.postproc\n\t      DebugLogger.pp node\n\t      DebugLogger.pp self\n\t      DebugLogger.pp ch\n\t      DebugLogger.pp chrs\n\t      SLex.fail ErrNodeAlreadyExists\n\t    else\n\t      D_WARN.puts \"change abstract node to real node\"\n\t      node.preproc = preproc\n\t      node.postproc = postproc\n\t    end\n\t  else\n\t    node.create_subnode(chrs, preproc, postproc)\n\t  end\n\telse\n\t  if chrs.empty?\n\t    node = Node.new(preproc, postproc)\n\t  else\n\t    node = Node.new\n\t    node.create_subnode(chrs, preproc, postproc)\n\t  end\n\t  @Tree[ch] = node\n\tend\n\tnode\n      end\n\n      #\n      # chrs: String\n      #       character array\n      #       io must have getc()/ungetc(); and ungetc() must be\n      #       able to be called arbitrary number of times. \n      #\n      def match(chrs, op = \"\")\n\tD_DETAIL.print \"match>: \", chrs, \"op:\", op, \"\\n\"\n\tif chrs.empty?\n\t  if @preproc.nil? || @preproc.call(op, chrs)\n\t    DOUT.printf(D_DETAIL, \"op1: %s\\n\", op)\n\t    @postproc.call(op, chrs)\n\t  else\n\t    nil\n\t  end\n\telse\n\t  ch = chrs.shift\n\t  if node = @Tree[ch]\n\t    if ret = node.match(chrs, op+ch)\n\t      return ret\n\t    else\n\t      chrs.unshift ch\n\t      if @postproc and @preproc.nil? || @preproc.call(op, chrs)\n\t\tDOUT.printf(D_DETAIL, \"op2: %s\\n\", op.inspect)\n\t\tret = @postproc.call(op, chrs)\n\t\treturn ret\n\t      else\n\t\treturn nil\n\t      end\n\t    end\n\t  else\n\t    chrs.unshift ch\n\t    if @postproc and @preproc.nil? || @preproc.call(op, chrs)\n\t      DOUT.printf(D_DETAIL, \"op3: %s\\n\", op)\n\t      @postproc.call(op, chrs)\n\t      return \"\"\n\t    else\n\t      return nil\n\t    end\n\t  end\n\tend\n      end\n\n      def match_io(io, op = \"\")\n\tif op == \"\"\n\t  ch = io.getc\n\t  if ch == nil\n\t    return nil\n\t  end\n\telse\n\t  ch = io.getc_of_rests\n\tend\n\tif ch.nil?\n\t  if @preproc.nil? || @preproc.call(op, io)\n\t    D_DETAIL.printf(\"op1: %s\\n\", op)\n\t    @postproc.call(op, io)\n\t  else\n\t    nil\n\t  end\n\telse\n\t  if node = @Tree[ch]\n\t    if ret = node.match_io(io, op+ch)\n\t      ret\n\t    else\n\t      io.ungetc ch\n\t      if @postproc and @preproc.nil? || @preproc.call(op, io)\n\t\tDOUT.exec_if{D_DETAIL.printf \"op2: %s\\n\", op.inspect}\n\t\t@postproc.call(op, io)\n\t      else\n\t\tnil\n\t      end\n\t    end\n\t  else\n\t    io.ungetc ch\n\t    if @postproc and @preproc.nil? || @preproc.call(op, io)\n\t      D_DETAIL.printf(\"op3: %s\\n\", op)\n\t      @postproc.call(op, io)\n\t    else\n\t      nil\n\t    end\n\t  end\n\tend\n      end\n    end\n  end\nend\n\nSLex=IRB::SLex\n\nif $0 == __FILE__\n  #    Tracer.on\n  case $1\n  when \"1\"\n    tr = SLex.new\n    print \"0: \", tr.inspect, \"\\n\"\n    tr.def_rule(\"=\") {print \"=\\n\"}\n    print \"1: \", tr.inspect, \"\\n\"\n    tr.def_rule(\"==\") {print \"==\\n\"}\n    print \"2: \", tr.inspect, \"\\n\"\n    \n    print \"case 1:\\n\"\n    print tr.match(\"=\"), \"\\n\"\n    print \"case 2:\\n\"\n    print tr.match(\"==\"), \"\\n\"\n    print \"case 3:\\n\"\n    print tr.match(\"=>\"), \"\\n\"\n    \n  when \"2\"\n    tr = SLex.new\n    print \"0: \", tr.inspect, \"\\n\"\n    tr.def_rule(\"=\") {print \"=\\n\"}\n    print \"1: \", tr.inspect, \"\\n\"\n    tr.def_rule(\"==\", proc{false}) {print \"==\\n\"}\n    print \"2: \", tr.inspect, \"\\n\"\n    \n    print \"case 1:\\n\"\n    print tr.match(\"=\"), \"\\n\"\n    print \"case 2:\\n\"\n    print tr.match(\"==\"), \"\\n\"\n    print \"case 3:\\n\"\n    print tr.match(\"=>\"), \"\\n\"\n  end\n  exit\nend\n\n"
  },
  {
    "path": "lib/irb/version.rb",
    "content": "#\n#   irb/version.rb - irb version definition file\n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n#\n# --\n#\n#   \n#\n\nmodule IRB\n  @RELEASE_VERSION = \"0.9.5\"\n  @LAST_UPDATE_DATE = \"05/04/13\"\nend\n"
  },
  {
    "path": "lib/irb/workspace.rb",
    "content": "#\n#   irb/workspace-binding.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\nmodule IRB\n  class WorkSpace\n    # create new workspace. set self to main if specified, otherwise\n    # inherit main from TOPLEVEL_BINDING.\n    def initialize(*main)\n      if main[0].kind_of?(Binding)\n\t@binding = main.shift\n      elsif IRB.conf[:SINGLE_IRB]\n\t@binding = TOPLEVEL_BINDING\n      else\n\tcase IRB.conf[:CONTEXT_MODE]\n\twhen 0\t# binding in proc on TOPLEVEL_BINDING\n\t  @binding = eval(\"proc{binding}.call\",\n\t\t      TOPLEVEL_BINDING, \n\t\t      __FILE__,\n\t\t      __LINE__)\n\twhen 1\t# binding in loaded file\n\t  require \"tempfile\"\n\t  f = Tempfile.open(\"irb-binding\")\n\t  f.print <<EOF\n\t  $binding = binding\nEOF\n\t  f.close\n\t  load f.path\n\t  @binding = $binding\n\n\twhen 2\t# binding in loaded file(thread use)\n\t  unless defined? BINDING_QUEUE\n\t    require \"thread\"\n\t    \n\t    IRB.const_set(\"BINDING_QUEUE\", SizedQueue.new(1))\n\t    Thread.abort_on_exception = true\n\t    Thread.start do\n\t      eval \"require \\\"irb/ws-for-case-2\\\"\", TOPLEVEL_BINDING, __FILE__, __LINE__\n\t    end\n\t    Thread.pass\n\t  end\n\t  @binding = BINDING_QUEUE.pop\n\n\twhen 3\t# binging in function on TOPLEVEL_BINDING(default)\n\t  @binding = eval(\"def irb_binding; binding; end; irb_binding\",\n\t\t      TOPLEVEL_BINDING, \n\t\t      __FILE__,\n\t\t      __LINE__ - 3)\n\tend\n      end\n      if main.empty?\n\t@main = eval(\"self\", @binding)\n      else\n\t@main = main[0]\n\tIRB.conf[:__MAIN__] = @main\n\tcase @main\n\twhen Module\n\t  @binding = eval(\"IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)\", @binding, __FILE__, __LINE__)\n\telse\n\t  begin \n\t    @binding = eval(\"IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)\", @binding, __FILE__, __LINE__)\n\t  rescue TypeError\n\t    IRB.fail CantChangeBinding, @main.inspect\n\t  end\n\tend\n      end\n      eval(\"_=nil\", @binding)\n    end\n\n    attr_reader :binding\n    attr_reader :main\n\n    def evaluate(context, statements, file = __FILE__, line = __LINE__)\n      eval(statements, @binding, file, line)\n    end\n  \n    # error message manipulator\n    def filter_backtrace(bt)\n      case IRB.conf[:CONTEXT_MODE]\n      when 0\n\treturn nil if bt =~ /\\(irb_local_binding\\)/\n      when 1\n\tif(bt =~ %r!/tmp/irb-binding! or\n\t   bt =~ %r!irb/.*\\.rb! or\n\t   bt =~ /irb\\.rb/)\n\t  return nil\n\tend\n      when 2\n\treturn nil if bt =~ /irb\\/.*\\.rb/\n      when 3\n\treturn nil if bt =~ /irb\\/.*\\.rb/\n\tbt.sub!(/:\\s*in `irb_binding'/){\"\"} \n      end\n      bt\n    end\n\n    def IRB.delete_caller\n    end\n  end\nend\n"
  },
  {
    "path": "lib/irb/ws-for-case-2.rb",
    "content": "#\n#   irb/ws-for-case-2.rb - \n#   \t$Release Version: 0.9.5$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#   \n#\n\nwhile true\n  IRB::BINDING_QUEUE.push b = binding\nend\n"
  },
  {
    "path": "lib/irb/xmp.rb",
    "content": "#\n#   xmp.rb - irb version of gotoken xmp\n#   \t$Release Version: 0.9$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nippon Rational Inc.)\n#\n# --\n#\n#   \n#\n\nrequire \"irb\"\nrequire \"irb/frame\"\n\nclass XMP\n  @RCS_ID='-$Id$-'\n\n  def initialize(bind = nil)\n    IRB.init_config(nil)\n    #IRB.parse_opts\n    #IRB.load_modules\n\n    IRB.conf[:PROMPT_MODE] = :XMP\n\n    bind = IRB::Frame.top(1) unless bind\n    ws = IRB::WorkSpace.new(bind)\n    @io = StringInputMethod.new\n    @irb = IRB::Irb.new(ws, @io)\n    @irb.context.ignore_sigint = false\n\n#    IRB.conf[:IRB_RC].call(@irb.context) if IRB.conf[:IRB_RC]\n    IRB.conf[:MAIN_CONTEXT] = @irb.context\n  end\n\n  def puts(exps)\n    @io.puts exps\n\n    if @irb.context.ignore_sigint\n      begin\n\ttrap_proc_b = trap(\"SIGINT\"){@irb.signal_handle}\n\tcatch(:IRB_EXIT) do\n\t  @irb.eval_input\n\tend\n      ensure\n\ttrap(\"SIGINT\", trap_proc_b)\n      end\n    else\n      catch(:IRB_EXIT) do\n\t@irb.eval_input\n      end\n    end\n  end\n\n  class StringInputMethod < IRB::InputMethod\n    def initialize\n      super\n      @exps = []\n    end\n\n    def eof?\n      @exps.empty?\n    end\n\n    def gets\n      while l = @exps.shift\n\tnext if /^\\s+$/ =~ l\n\tl.concat \"\\n\"\n\tprint @prompt, l\n\tbreak\n      end\n      l\n    end\n\n    def puts(exps)\n      @exps.concat exps.split(/\\n/)\n    end\n  end\nend\n\ndef xmp(exps, bind = nil)\n  bind = IRB::Frame.top(1) unless bind\n  xmp = XMP.new(bind)\n  xmp.puts exps\n  xmp\nend\n"
  },
  {
    "path": "lib/irb.rb",
    "content": "#\n#   irb.rb - irb main module\n#   \t$Release Version: 0.9.5 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ruby-lang.org)\n#\n# --\n#\n#\n#\nrequire \"e2mmap\"\n\nrequire \"irb/init\"\nrequire \"irb/context\"\nrequire \"irb/extend-command\"\n#require \"irb/workspace\"\n\nrequire \"irb/ruby-lex\"\nrequire \"irb/input-method\"\nrequire \"irb/locale\"\n\nSTDOUT.sync = true\n\nmodule IRB\n  @RCS_ID='-$Id$-'\n\n  class Abort < Exception;end\n\n  #\n  @CONF = {}\n\n  def IRB.conf\n    @CONF\n  end\n\n  # IRB version method\n  def IRB.version\n    if v = @CONF[:VERSION] then return v end\n\n    require \"irb/version\"\n    rv = @RELEASE_VERSION.sub(/\\.0/, \"\")\n    @CONF[:VERSION] = format(\"irb %s(%s)\", rv, @LAST_UPDATE_DATE)\n  end\n\n  def IRB.CurrentContext\n    IRB.conf[:MAIN_CONTEXT]\n  end\n\n  # initialize IRB and start TOP_LEVEL irb\n  def IRB.start(ap_path = nil)\n    $0 = File::basename(ap_path, \".rb\") if ap_path\n\n    IRB.setup(ap_path)\n\n    if @CONF[:SCRIPT]\n      irb = Irb.new(nil, @CONF[:SCRIPT])\n    else\n      irb = Irb.new\n    end\n\n    @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]\n    @CONF[:MAIN_CONTEXT] = irb.context\n\n    trap(\"SIGINT\") do\n      irb.signal_handle\n    end\n\n    begin\n      catch(:IRB_EXIT) do\n\tirb.eval_input\n      end\n    ensure\n      irb_at_exit\n    end\n#    print \"\\n\"\n  end\n\n  def IRB.irb_at_exit\n    @CONF[:AT_EXIT].each{|hook| hook.call}\n  end\n\n  def IRB.irb_exit(irb, ret)\n    throw :IRB_EXIT, ret\n  end\n\n  def IRB.irb_abort(irb, exception = Abort)\n    if defined? Thread\n      irb.context.thread.raise exception, \"abort then interrupt!!\"\n    else\n      raise exception, \"abort then interrupt!!\"\n    end\n  end\n\n  #\n  # irb interpriter main routine \n  #\n  class Irb\n    def initialize(workspace = nil, input_method = nil, output_method = nil)\n      @context = Context.new(self, workspace, input_method, output_method)\n      @context.main.extend ExtendCommandBundle\n      @signal_status = :IN_IRB\n\n      @scanner = RubyLex.new\n      @scanner.exception_on_syntax_error = false\n    end\n    attr_reader :context\n    attr_accessor :scanner\n\n    def eval_input\n      @scanner.set_prompt do\n\t|ltype, indent, continue, line_no|\n\tif ltype\n\t  f = @context.prompt_s\n\telsif continue\n\t  f = @context.prompt_c\n\telsif indent > 0\n\t  f = @context.prompt_n\n\telse @context.prompt_i\n\t  f = @context.prompt_i\n\tend\n\tf = \"\" unless f\n\tif @context.prompting?\n\t  @context.io.prompt = p = prompt(f, ltype, indent, line_no)\n\telse\n\t  @context.io.prompt = p = \"\"\n\tend\n\tif @context.auto_indent_mode\n\t  unless ltype\n            ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\\z/].size +\n\t      indent * 2 - p.size\n\t    ind += 2 if continue\n\t    @context.io.prompt = p + \" \" * ind if ind > 0\n\t  end\n\tend\n      end\n       \n      @scanner.set_input(@context.io) do\n\tsignal_status(:IN_INPUT) do\n\t  if l = @context.io.gets\n\t    print l if @context.verbose?\n\t  else\n\t    if @context.ignore_eof? and @context.io.readable_atfer_eof?\n\t      l = \"\\n\"\n\t      if @context.verbose?\n\t\tprintf \"Use \\\"exit\\\" to leave %s\\n\", @context.ap_name\n\t      end\n\t    end\n\t  end\n\t  l\n\tend\n      end\n\n      @scanner.each_top_level_statement do |line, line_no|\n\tsignal_status(:IN_EVAL) do\n\t  begin\n            line.untaint\n\t    @context.evaluate(line, line_no)\n\t    output_value if @context.echo?\n\t    exc = nil\n\t  rescue Interrupt => exc\n\t  rescue SystemExit, SignalException\n\t    raise\n\t  rescue Exception => exc\n\t  end\n\t  if exc\n\t    print exc.class, \": \", exc, \"\\n\"\n\t    if exc.backtrace[0] =~ /irb(2)?(\\/.*|-.*|\\.rb)?:/ && exc.class.to_s !~ /^IRB/\n\t      irb_bug = true \n\t    else\n\t      irb_bug = false\n\t    end\n\t    \n\t    messages = []\n\t    lasts = []\n\t    levels = 0\n\t    for m in exc.backtrace\n\t      m = @context.workspace.filter_backtrace(m) unless irb_bug\n\t      if m\n\t\tif messages.size < @context.back_trace_limit\n\t\t  messages.push \"\\tfrom \"+m\n\t\telse\n\t\t  lasts.push \"\\tfrom \"+m\n\t\t  if lasts.size > @context.back_trace_limit\n\t\t    lasts.shift \n\t\t    levels += 1\n\t\t  end\n\t\tend\n\t      end\n\t    end\n\t    print messages.join(\"\\n\"), \"\\n\"\n\t    unless lasts.empty?\n\t      printf \"... %d levels...\\n\", levels if levels > 0\n\t      print lasts.join(\"\\n\")\n\t    end\n\t    print \"Maybe IRB bug!!\\n\" if irb_bug\n\t  end\n          if $SAFE > 2\n            abort \"Error: irb does not work for $SAFE level higher than 2\"\n          end\n\tend\n      end\n    end\n\n    def suspend_name(path = nil, name = nil)\n      @context.irb_path, back_path = path, @context.irb_path if path\n      @context.irb_name, back_name = name, @context.irb_name if name\n      begin\n\tyield back_path, back_name\n      ensure\n\t@context.irb_path = back_path if path\n\t@context.irb_name = back_name if name\n      end\n    end\n\n    def suspend_workspace(workspace)\n      @context.workspace, back_workspace = workspace, @context.workspace\n      begin\n\tyield back_workspace\n      ensure\n\t@context.workspace = back_workspace\n      end\n    end\n\n    def suspend_input_method(input_method)\n      back_io = @context.io\n      @context.instance_eval{@io = input_method}\n      begin\n\tyield back_io\n      ensure\n\t@context.instance_eval{@io = back_io}\n      end\n    end\n\n    def suspend_context(context)\n      @context, back_context = context, @context\n      begin\n\tyield back_context\n      ensure\n\t@context = back_context\n      end\n    end\n\n    def signal_handle\n      unless @context.ignore_sigint?\n\tprint \"\\nabort!!\\n\" if @context.verbose?\n\texit\n      end\n\n      case @signal_status\n      when :IN_INPUT\n\tprint \"^C\\n\"\n\traise RubyLex::TerminateLineInput\n      when :IN_EVAL\n\tIRB.irb_abort(self)\n      when :IN_LOAD\n\tIRB.irb_abort(self, LoadAbort)\n      when :IN_IRB\n\t# ignore\n      else\n\t# ignore other cases as well\n      end\n    end\n\n    def signal_status(status)\n      return yield if @signal_status == :IN_LOAD\n\n      signal_status_back = @signal_status\n      @signal_status = status\n      begin\n\tyield\n      ensure\n\t@signal_status = signal_status_back\n      end\n    end\n\n    def prompt(prompt, ltype, indent, line_no)\n      p = prompt.dup\n      p.gsub!(/%([0-9]+)?([a-zA-Z])/) do\n\tcase $2\n\twhen \"N\"\n\t  @context.irb_name\n\twhen \"m\"\n\t  @context.main.to_s\n\twhen \"M\"\n\t  @context.main.inspect\n\twhen \"l\"\n\t  ltype\n\twhen \"i\"\n\t  if $1 \n\t    format(\"%\" + $1 + \"d\", indent)\n\t  else\n\t    indent.to_s\n\t  end\n\twhen \"n\"\n\t  if $1 \n\t    format(\"%\" + $1 + \"d\", line_no)\n\t  else\n\t    line_no.to_s\n\t  end\n\twhen \"%\"\n\t  \"%\"\n\tend\n      end\n      p\n    end\n\n    def output_value\n      if @context.inspect?\n        printf @context.return_format, @context.last_value.inspect\n      else\n        printf @context.return_format, @context.last_value\n      end\n    end\n\n    def inspect\n      ary = []\n      for iv in instance_variables\n\tcase iv\n\twhen \"@signal_status\"\n\t  ary.push format(\"%s=:%s\", iv, @signal_status.id2name)\n\twhen \"@context\"\n\t  ary.push format(\"%s=%s\", iv, eval(iv).__to_s__)\n\telse\n\t  ary.push format(\"%s=%s\", iv, eval(iv))\n\tend\n      end\n      format(\"#<%s: %s>\", self.class, ary.join(\", \"))\n    end\n  end\n\n  # Singleton method\n  def @CONF.inspect\n    IRB.version unless self[:VERSION]\n\n    array = []\n    for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}\n      case k\n      when :MAIN_CONTEXT, :__TMP__EHV__\n\tarray.push format(\"CONF[:%s]=...myself...\", k.id2name)\n      when :PROMPT\n\ts = v.collect{\n\t  |kk, vv|\n\t  ss = vv.collect{|kkk, vvv| \":#{kkk.id2name}=>#{vvv.inspect}\"}\n\t  format(\":%s=>{%s}\", kk.id2name, ss.join(\", \"))\n\t}\n\tarray.push format(\"CONF[:%s]={%s}\", k.id2name, s.join(\", \"))\n      else\n\tarray.push format(\"CONF[:%s]=%s\", k.id2name, v.inspect)\n      end\n    end\n    array.join(\"\\n\")\n  end\nend\n"
  },
  {
    "path": "lib/jcode.rb",
    "content": "# jcode.rb - ruby code to handle japanese (EUC/SJIS) string\n\nif $VERBOSE && $KCODE == \"NONE\"\n  warn \"Warning: $KCODE is NONE.\"\nend\n\n$vsave, $VERBOSE = $VERBOSE, false\nclass String\n  warn \"feel free for some warnings:\\n\" if $VERBOSE\n\n  def _regex_quote(str)\n    str.gsub(/(\\\\[\\[\\]\\-\\\\])|\\\\(.)|([\\[\\]\\\\])/) do\n      $1 || $2 || '\\\\' + $3\n    end\n  end\n  private :_regex_quote\n\n  PATTERN_SJIS = '[\\x81-\\x9f\\xe0-\\xef][\\x40-\\x7e\\x80-\\xfc]'\n  PATTERN_EUC = '[\\xa1-\\xfe][\\xa1-\\xfe]'\n  PATTERN_UTF8 = '[\\xc0-\\xdf][\\x80-\\xbf]|[\\xe0-\\xef][\\x80-\\xbf][\\x80-\\xbf]'\n\n  RE_SJIS = Regexp.new(PATTERN_SJIS, 0, 'n')\n  RE_EUC = Regexp.new(PATTERN_EUC, 0, 'n')\n  RE_UTF8 = Regexp.new(PATTERN_UTF8, 0, 'n')\n\n  SUCC = {}\n  SUCC['s'] = Hash.new(1)\n  for i in 0 .. 0x3f\n    SUCC['s'][i.chr] = 0x40 - i\n  end\n  SUCC['s'][\"\\x7e\"] = 0x80 - 0x7e\n  SUCC['s'][\"\\xfd\"] = 0x100 - 0xfd\n  SUCC['s'][\"\\xfe\"] = 0x100 - 0xfe\n  SUCC['s'][\"\\xff\"] = 0x100 - 0xff\n  SUCC['e'] = Hash.new(1)\n  for i in 0 .. 0xa0\n    SUCC['e'][i.chr] = 0xa1 - i\n  end\n  SUCC['e'][\"\\xfe\"] = 2\n  SUCC['u'] = Hash.new(1)\n  for i in 0 .. 0x7f\n    SUCC['u'][i.chr] = 0x80 - i\n  end\n  SUCC['u'][\"\\xbf\"] = 0x100 - 0xbf\n\n  def mbchar?\n    case $KCODE[0]\n    when ?s, ?S\n      self =~ RE_SJIS\n    when ?e, ?E\n      self =~ RE_EUC\n    when ?u, ?U\n      self =~ RE_UTF8\n    else\n      nil\n    end\n  end\n\n  def end_regexp\n    case $KCODE[0]\n    when ?s, ?S\n      /#{PATTERN_SJIS}$/on\n    when ?e, ?E\n      /#{PATTERN_EUC}$/on\n    when ?u, ?U\n      /#{PATTERN_UTF8}$/on\n    else\n      /.$/on\n    end\n  end\n\n  alias original_succ! succ!\n  private :original_succ!\n\n  alias original_succ succ\n  private :original_succ\n\n  def succ!\n    reg = end_regexp\n    if  $KCODE != 'NONE' && self =~ reg\n      succ_table = SUCC[$KCODE[0,1].downcase]\n      begin\n\tself[-1] += succ_table[self[-1]]\n\tself[-2] += 1 if self[-1] == 0\n      end while self !~ reg\n      self\n    else\n      original_succ!\n    end\n  end\n\n  def succ\n    str = self.dup\n    str.succ! or str\n  end\n\n  private\n\n  def _expand_ch str\n    a = []\n    str.scan(/(?:\\\\(.)|([^\\\\]))-(?:\\\\(.)|([^\\\\]))|(?:\\\\(.)|(.))/m) do\n      from = $1 || $2\n      to = $3 || $4\n      one = $5 || $6\n      if one\n\ta.push one\n      elsif from.length != to.length\n\tnext\n      elsif from.length == 1\n\tfrom[0].upto(to[0]) { |c| a.push c.chr }\n      else\n\tfrom.upto(to) { |c| a.push c }\n      end\n    end\n    a\n  end\n\n  def expand_ch_hash from, to\n    h = {}\n    afrom = _expand_ch(from)\n    ato = _expand_ch(to)\n    afrom.each_with_index do |x,i| h[x] = ato[i] || ato[-1] end\n    h\n  end\n\n  HashCache = {}\n  TrPatternCache = {}\n  DeletePatternCache = {}\n  SqueezePatternCache = {}\n\n  public\n\n  def tr!(from, to)\n    return nil if from == \"\"\n    return self.delete!(from) if to == \"\"\n\n    pattern = TrPatternCache[from] ||= /[#{_regex_quote(from)}]/\n    if from[0] == ?^\n      last = /.$/.match(to)[0]\n      self.gsub!(pattern, last)\n    else\n      h = HashCache[from + \"1-0\" + to] ||= expand_ch_hash(from, to)\n      self.gsub!(pattern) do |c| h[c] end\n    end\n  end\n\n  def tr(from, to)\n    (str = self.dup).tr!(from, to) or str\n  end\n\n  def delete!(del)\n    return nil if del == \"\"\n    self.gsub!(DeletePatternCache[del] ||= /[#{_regex_quote(del)}]+/, '')\n  end\n\n  def delete(del)\n    (str = self.dup).delete!(del) or str\n  end\n\n  def squeeze!(del=nil)\n    return nil if del == \"\"\n    pattern =\n      if del\n\tSqueezePatternCache[del] ||= /([#{_regex_quote(del)}])\\1+/\n      else\n\t/(.|\\n)\\1+/\n      end\n    self.gsub!(pattern, '\\1')\n  end\n\n  def squeeze(del=nil)\n    (str = self.dup).squeeze!(del) or str\n  end\n\n  def tr_s!(from, to)\n    return self.delete!(from) if to.length == 0\n\n    pattern = SqueezePatternCache[from] ||= /([#{_regex_quote(from)}])\\1*/\n    if from[0] == ?^\n      last = /.$/.match(to)[0]\n      self.gsub!(pattern, last)\n    else\n      h = HashCache[from + \"1-0\" + to] ||= expand_ch_hash(from, to)\n      self.gsub!(pattern) do h[$1] end\n    end\n  end\n\n  def tr_s(from, to)\n    (str = self.dup).tr_s!(from,to) or str\n  end\n\n  def chop!\n    self.gsub!(/(?:.|\\r?\\n)\\z/, '')\n  end\n\n  def chop\n    (str = self.dup).chop! or str\n  end\n\n  def jlength\n    self.gsub(/[^\\Wa-zA-Z_\\d]/, ' ').length\n  end\n  alias jsize jlength\n\n  def jcount(str)\n    self.delete(\"^#{str}\").jlength\n  end\n\n  def each_char\n    if block_given?\n      scan(/./m) do |x|\n        yield x\n      end\n    else\n      scan(/./m)\n    end\n  end\n\nend\n$VERBOSE = $vsave\n"
  },
  {
    "path": "lib/logger.rb",
    "content": "# logger.rb - simple logging utility\n# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.\n\nrequire 'monitor'\n\n# Simple logging utility.\n#\n# Author:: NAKAMURA, Hiroshi  <nakahiro@sarion.co.jp>\n# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair\n# License::\n#   You can redistribute it and/or modify it under the same terms of Ruby's\n#   license; either the dual license version in 2003, or any later version.\n# Revision:: $Id$\n#\n# == Description\n#\n# The Logger class provides a simple but sophisticated logging utility that\n# anyone can use because it's included in the Ruby 1.8.x standard library.\n#\n# The HOWTOs below give a code-based overview of Logger's usage, but the basic\n# concept is as follows.  You create a Logger object (output to a file or\n# elsewhere), and use it to log messages.  The messages will have varying\n# levels (+info+, +error+, etc), reflecting their varying importance.  The\n# levels, and their meanings, are:\n#\n# +FATAL+:: an unhandleable error that results in a program crash\n# +ERROR+:: a handleable error condition\n# +WARN+::  a warning\n# +INFO+::  generic (useful) information about system operation\n# +DEBUG+:: low-level information for developers\n#\n# So each message has a level, and the Logger itself has a level, which acts\n# as a filter, so you can control the amount of information emitted from the\n# logger without having to remove actual messages.\n#\n# For instance, in a production system, you may have your logger(s) set to\n# +INFO+ (or +WARN+ if you don't want the log files growing large with\n# repetitive information).  When you are developing it, though, you probably\n# want to know about the program's internal state, and would set them to\n# +DEBUG+.\n#\n# === Example\n#\n# A simple example demonstrates the above explanation:\n#\n#   log = Logger.new(STDOUT)\n#   log.level = Logger::WARN\n#\n#   log.debug(\"Created logger\")\n#   log.info(\"Program started\")\n#   log.warn(\"Nothing to do!\")\n#\n#   begin\n#     File.each_line(path) do |line|\n#       unless line =~ /^(\\w+) = (.*)$/\n#         log.error(\"Line in wrong format: #{line}\")\n#       end\n#     end\n#   rescue => err\n#     log.fatal(\"Caught exception; exiting\")\n#     log.fatal(err)\n#   end\n#\n# Because the Logger's level is set to +WARN+, only the warning, error, and\n# fatal messages are recorded.  The debug and info messages are silently\n# discarded.\n#\n# === Features\n#\n# There are several interesting features that Logger provides, like\n# auto-rolling of log files, setting the format of log messages, and\n# specifying a program name in conjunction with the message.  The next section\n# shows you how to achieve these things.\n#\n#\n# == HOWTOs\n#\n# === How to create a logger\n#\n# The options below give you various choices, in more or less increasing\n# complexity.\n#\n# 1. Create a logger which logs messages to STDERR/STDOUT.\n#\n#      logger = Logger.new(STDERR)\n#      logger = Logger.new(STDOUT)\n#\n# 2. Create a logger for the file which has the specified name.\n#\n#      logger = Logger.new('logfile.log')\n#\n# 3. Create a logger for the specified file.\n#\n#      file = File.open('foo.log', File::WRONLY | File::APPEND)\n#      # To create new (and to remove old) logfile, add File::CREAT like;\n#      #   file = open('foo.log', File::WRONLY | File::APPEND | File::CREAT)\n#      logger = Logger.new(file)\n#\n# 4. Create a logger which ages logfile once it reaches a certain size.  Leave\n#    10 \"old log files\" and each file is about 1,024,000 bytes.\n#\n#      logger = Logger.new('foo.log', 10, 1024000)\n#\n# 5. Create a logger which ages logfile daily/weekly/monthly.\n#\n#      logger = Logger.new('foo.log', 'daily')\n#      logger = Logger.new('foo.log', 'weekly')\n#      logger = Logger.new('foo.log', 'monthly')\n#\n# === How to log a message\n#\n# Notice the different methods (+fatal+, +error+, +info+) being used to log\n# messages of various levels.  Other methods in this family are +warn+ and\n# +debug+.  +add+ is used below to log a message of an arbitrary (perhaps\n# dynamic) level.\n#\n# 1. Message in block.\n#\n#      logger.fatal { \"Argument 'foo' not given.\" }\n#\n# 2. Message as a string.\n#\n#      logger.error \"Argument #{ @foo } mismatch.\"\n#\n# 3. With progname.\n#\n#      logger.info('initialize') { \"Initializing...\" }\n#\n# 4. With severity.\n#\n#      logger.add(Logger::FATAL) { 'Fatal error!' }\n#\n# === How to close a logger\n#\n#      logger.close\n#\n# === Setting severity threshold\n#\n# 1. Original interface.\n#\n#      logger.sev_threshold = Logger::WARN\n#\n# 2. Log4r (somewhat) compatible interface.\n#\n#      logger.level = Logger::INFO\n#      \n#      DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN\n#\n#\n# == Format\n#\n# Log messages are rendered in the output stream in a certain format.  The\n# default format and a sample are shown below:\n#\n# Log format:\n#   SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message\n#\n# Log sample:\n#   I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074]  INFO -- Main: info.\n#\n# You may change the date and time format in this manner:\n#\n#   logger.datetime_format = \"%Y-%m-%d %H:%M:%S\"\n#         # e.g. \"2004-01-03 00:54:26\"\n#\n# There is currently no supported way to change the overall format, but you may\n# have some luck hacking the Format constant.\n#\n\n\nclass Logger\n  VERSION = \"1.2.6\"\n  id, name, rev = %w$Id$\n  ProgName = name ? \"#{name.chomp(\",v\")}/#{rev}\" : \"logger.rb\"\n\n  class Error < RuntimeError; end\n  class ShiftingError < Error; end\n\n  # Logging severity.\n  module Severity\n    DEBUG = 0\n    INFO = 1\n    WARN = 2\n    ERROR = 3\n    FATAL = 4\n    UNKNOWN = 5\n  end\n  include Severity\n\n  # Logging severity threshold (e.g. <tt>Logger::INFO</tt>).\n  attr_accessor :level\n\n  # Logging program name.\n  attr_accessor :progname\n\n  # Logging date-time format (string passed to +strftime+).\n  def datetime_format=(datetime_format)\n    @default_formatter.datetime_format = datetime_format\n  end\n\n  def datetime_format\n    @default_formatter.datetime_format\n  end\n\n  # Logging formatter.  formatter#call is invoked with 4 arguments; severity,\n  # time, progname and msg for each log.  Bear in mind that time is a Time and\n  # msg is an Object that user passed and it could not be a String.  It is\n  # expected to return a logdev#write-able Object.  Default formatter is used\n  # when no formatter is set.\n  attr_accessor :formatter\n\n  alias sev_threshold level\n  alias sev_threshold= level=\n\n  # Returns +true+ iff the current severity level allows for the printing of\n  # +DEBUG+ messages.\n  def debug?; @level <= DEBUG; end\n\n  # Returns +true+ iff the current severity level allows for the printing of\n  # +INFO+ messages.\n  def info?; @level <= INFO; end\n\n  # Returns +true+ iff the current severity level allows for the printing of\n  # +WARN+ messages.\n  def warn?; @level <= WARN; end\n\n  # Returns +true+ iff the current severity level allows for the printing of\n  # +ERROR+ messages.\n  def error?; @level <= ERROR; end\n\n  # Returns +true+ iff the current severity level allows for the printing of\n  # +FATAL+ messages.\n  def fatal?; @level <= FATAL; end\n\n  #\n  # === Synopsis\n  #\n  #   Logger.new(name, shift_age = 7, shift_size = 1048576)\n  #   Logger.new(name, shift_age = 'weekly')\n  #\n  # === Args\n  #\n  # +logdev+::\n  #   The log device.  This is a filename (String) or IO object (typically\n  #   +STDOUT+, +STDERR+, or an open file).\n  # +shift_age+::\n  #   Number of old log files to keep, *or* frequency of rotation (+daily+,\n  #   +weekly+ or +monthly+).\n  # +shift_size+::\n  #   Maximum logfile size (only applies when +shift_age+ is a number).\n  #\n  # === Description\n  #\n  # Create an instance.\n  #\n  def initialize(logdev, shift_age = 0, shift_size = 1048576)\n    @progname = nil\n    @level = DEBUG\n    @default_formatter = Formatter.new\n    @formatter = nil\n    @logdev = nil\n    if logdev\n      @logdev = LogDevice.new(logdev, :shift_age => shift_age,\n        :shift_size => shift_size)\n    end\n  end\n\n  #\n  # === Synopsis\n  #\n  #   Logger#add(severity, message = nil, progname = nil) { ... }\n  #\n  # === Args\n  #\n  # +severity+::\n  #   Severity.  Constants are defined in Logger namespace: +DEBUG+, +INFO+,\n  #   +WARN+, +ERROR+, +FATAL+, or +UNKNOWN+.\n  # +message+::\n  #   The log message.  A String or Exception.\n  # +progname+::\n  #   Program name string.  Can be omitted.  Treated as a message if no +message+ and\n  #   +block+ are given.\n  # +block+::\n  #   Can be omitted.  Called to get a message string if +message+ is nil.\n  #\n  # === Return\n  #\n  # +true+ if successful, +false+ otherwise.\n  #\n  # When the given severity is not high enough (for this particular logger), log\n  # no message, and return +true+.\n  #\n  # === Description\n  #\n  # Log a message if the given severity is high enough.  This is the generic\n  # logging method.  Users will be more inclined to use #debug, #info, #warn,\n  # #error, and #fatal.\n  #\n  # <b>Message format</b>: +message+ can be any object, but it has to be\n  # converted to a String in order to log it.  Generally, +inspect+ is used\n  # if the given object is not a String.\n  # A special case is an +Exception+ object, which will be printed in detail,\n  # including message, class, and backtrace.  See #msg2str for the\n  # implementation if required.\n  #\n  # === Bugs\n  #\n  # * Logfile is not locked.\n  # * Append open does not need to lock file.\n  # * But on the OS which supports multi I/O, records possibly be mixed.\n  #\n  def add(severity, message = nil, progname = nil, &block)\n    severity ||= UNKNOWN\n    if @logdev.nil? or severity < @level\n      return true\n    end\n    progname ||= @progname\n    if message.nil?\n      if block_given?\n\tmessage = yield\n      else\n\tmessage = progname\n\tprogname = @progname\n      end\n    end\n    @logdev.write(\n      format_message(format_severity(severity), Time.now, progname, message))\n    true\n  end\n  alias log add\n\n  #\n  # Dump given message to the log device without any formatting.  If no log\n  # device exists, return +nil+.\n  #\n  def <<(msg)\n    unless @logdev.nil?\n      @logdev.write(msg)\n    end\n  end\n\n  #\n  # Log a +DEBUG+ message.\n  #\n  # See #info for more information.\n  #\n  def debug(progname = nil, &block)\n    add(DEBUG, nil, progname, &block)\n  end\n\n  #\n  # Log an +INFO+ message.\n  #\n  # The message can come either from the +progname+ argument or the +block+.  If\n  # both are provided, then the +block+ is used as the message, and +progname+\n  # is used as the program name.\n  #\n  # === Examples\n  #\n  #   logger.info(\"MainApp\") { \"Received connection from #{ip}\" }\n  #   # ...\n  #   logger.info \"Waiting for input from user\"\n  #   # ...\n  #   logger.info { \"User typed #{input}\" }\n  #\n  # You'll probably stick to the second form above, unless you want to provide a\n  # program name (which you can do with <tt>Logger#progname=</tt> as well).\n  #\n  # === Return\n  #\n  # See #add.\n  #\n  def info(progname = nil, &block)\n    add(INFO, nil, progname, &block)\n  end\n\n  #\n  # Log a +WARN+ message.\n  #\n  # See #info for more information.\n  #\n  def warn(progname = nil, &block)\n    add(WARN, nil, progname, &block)\n  end\n\n  #\n  # Log an +ERROR+ message.\n  #\n  # See #info for more information.\n  #\n  def error(progname = nil, &block)\n    add(ERROR, nil, progname, &block)\n  end\n\n  #\n  # Log a +FATAL+ message.\n  #\n  # See #info for more information.\n  #\n  def fatal(progname = nil, &block)\n    add(FATAL, nil, progname, &block)\n  end\n\n  #\n  # Log an +UNKNOWN+ message.  This will be printed no matter what the logger\n  # level.\n  #\n  # See #info for more information.\n  #\n  def unknown(progname = nil, &block)\n    add(UNKNOWN, nil, progname, &block)\n  end\n\n  #\n  # Close the logging device.\n  #\n  def close\n    @logdev.close if @logdev\n  end\n\nprivate\n\n  # Severity label for logging. (max 5 char)\n  SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY)\n\n  def format_severity(severity)\n    SEV_LABEL[severity] || 'ANY'\n  end\n\n  def format_message(severity, datetime, progname, msg)\n    (@formatter || @default_formatter).call(severity, datetime, progname, msg)\n  end\n\n\n  class Formatter\n    Format = \"%s, [%s#%d] %5s -- %s: %s\\n\"\n\n    attr_accessor :datetime_format\n\n    def initialize\n      @datetime_format = nil\n    end\n\n    def call(severity, time, progname, msg)\n      Format % [severity[0..0], format_datetime(time), $$, severity, progname,\n        msg2str(msg)]\n    end\n\n  private\n\n    def format_datetime(time)\n      if @datetime_format.nil?\n        time.strftime(\"%Y-%m-%dT%H:%M:%S.\") << \"%06d \" % time.usec\n      else\n        time.strftime(@datetime_format)\n      end\n    end\n\n    def msg2str(msg)\n      case msg\n      when ::String\n        msg\n      when ::Exception\n        \"#{ msg.message } (#{ msg.class })\\n\" <<\n          (msg.backtrace || []).join(\"\\n\")\n      else\n        msg.inspect\n      end\n    end\n  end\n\n\n  class LogDevice\n    attr_reader :dev\n    attr_reader :filename\n\n    class LogDeviceMutex\n      include MonitorMixin\n    end\n\n    def initialize(log = nil, opt = {})\n      @dev = @filename = @shift_age = @shift_size = nil\n      @mutex = LogDeviceMutex.new\n      if log.respond_to?(:write) and log.respond_to?(:close)\n\t@dev = log\n      else\n\t@dev = open_logfile(log)\n\t@dev.sync = true\n\t@filename = log\n\t@shift_age = opt[:shift_age] || 7\n\t@shift_size = opt[:shift_size] || 1048576\n      end\n    end\n\n    def write(message)\n      @mutex.synchronize do\n        if @shift_age and @dev.respond_to?(:stat)\n          begin\n            check_shift_log\n          rescue\n            raise Logger::ShiftingError.new(\"Shifting failed. #{$!}\")\n          end\n        end\n        @dev.write(message)\n      end\n    end\n\n    def close\n      @mutex.synchronize do\n        @dev.close\n      end\n    end\n\n  private\n\n    def open_logfile(filename)\n      if (FileTest.exist?(filename))\n     \topen(filename, (File::WRONLY | File::APPEND))\n      else\n       \tcreate_logfile(filename)\n      end\n    end\n\n    def create_logfile(filename)\n      logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))\n      logdev.sync = true\n      add_log_header(logdev)\n      logdev\n    end\n\n    def add_log_header(file)\n      file.write(\n     \t\"# Logfile created on %s by %s\\n\" % [Time.now.to_s, Logger::ProgName]\n    )\n    end\n\n    SiD = 24 * 60 * 60\n\n    def check_shift_log\n      if @shift_age.is_a?(Integer)\n        # Note: always returns false if '0'.\n        if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size)\n          shift_log_age\n        end\n      else\n        now = Time.now\n        if @dev.stat.mtime <= previous_period_end(now)\n          shift_log_period(now)\n        end\n      end\n    end\n\n    def shift_log_age\n      (@shift_age-3).downto(0) do |i|\n        if FileTest.exist?(\"#{@filename}.#{i}\")\n          File.rename(\"#{@filename}.#{i}\", \"#{@filename}.#{i+1}\")\n        end\n      end\n      @dev.close\n      File.rename(\"#{@filename}\", \"#{@filename}.0\")\n      @dev = create_logfile(@filename)\n      return true\n    end\n\n    def shift_log_period(now)\n      postfix = previous_period_end(now).strftime(\"%Y%m%d\")\t# YYYYMMDD\n      age_file = \"#{@filename}.#{postfix}\"\n      if FileTest.exist?(age_file)\n        raise RuntimeError.new(\"'#{ age_file }' already exists.\")\n      end\n      @dev.close\n      File.rename(\"#{@filename}\", age_file)\n      @dev = create_logfile(@filename)\n      return true\n    end\n\n    def previous_period_end(now)\n      case @shift_age\n      when /^daily$/\n        eod(now - 1 * SiD)\n      when /^weekly$/\n        eod(now - ((now.wday + 1) * SiD))\n      when /^monthly$/\n        eod(now - now.mday * SiD)\n      else\n        now\n      end\n    end\n\n    def eod(t)\n      Time.mktime(t.year, t.month, t.mday, 23, 59, 59)\n    end\n  end\n\n\n  #\n  # == Description\n  #\n  # Application -- Add logging support to your application.\n  #\n  # == Usage\n  #\n  # 1. Define your application class as a sub-class of this class.\n  # 2. Override 'run' method in your class to do many things.\n  # 3. Instantiate it and invoke 'start'.\n  #\n  # == Example\n  #\n  #   class FooApp < Application\n  #     def initialize(foo_app, application_specific, arguments)\n  #       super('FooApp') # Name of the application.\n  #     end\n  #\n  #     def run\n  #       ...\n  #       log(WARN, 'warning', 'my_method1')\n  #       ...\n  #       @log.error('my_method2') { 'Error!' }\n  #       ...\n  #     end\n  #   end\n  #\n  #   status = FooApp.new(....).start\n  #\n  class Application\n    include Logger::Severity\n\n    attr_reader :appname\n    attr_reader :logdev\n\n    #\n    # == Synopsis\n    #\n    #   Application.new(appname = '')\n    #\n    # == Args\n    #\n    # +appname+:: Name of the application.\n    #\n    # == Description\n    #\n    # Create an instance.  Log device is +STDERR+ by default.  This can be\n    # changed with #set_log.\n    #\n    def initialize(appname = nil)\n      @appname = appname\n      @log = Logger.new(STDERR)\n      @log.progname = @appname\n      @level = @log.level\n    end\n\n    #\n    # Start the application.  Return the status code.\n    #\n    def start\n      status = -1\n      begin\n\tlog(INFO, \"Start of #{ @appname }.\")\n\tstatus = run\n      rescue\n\tlog(FATAL, \"Detected an exception. Stopping ... #{$!} (#{$!.class})\\n\" << $@.join(\"\\n\"))\n      ensure\n\tlog(INFO, \"End of #{ @appname }. (status: #{ status.to_s })\")\n      end\n      status\n    end\n\n    #\n    # Sets the log device for this application.  See the class Logger for an\n    # explanation of the arguments.\n    #\n    def set_log(logdev, shift_age = 0, shift_size = 1024000)\n      @log = Logger.new(logdev, shift_age, shift_size)\n      @log.progname = @appname\n      @log.level = @level\n    end\n\n    def log=(logdev)\n      set_log(logdev)\n    end\n\n    #\n    # Set the logging threshold, just like <tt>Logger#level=</tt>.\n    #\n    def level=(level)\n      @level = level\n      @log.level = @level\n    end\n\n    #\n    # See Logger#add.  This application's +appname+ is used.\n    #\n    def log(severity, message = nil, &block)\n      @log.add(severity, message, @appname, &block) if @log\n    end\n\n  private\n\n    def run\n      raise RuntimeError.new('Method run must be defined in the derived class.')\n    end\n  end\nend\n"
  },
  {
    "path": "lib/mailread.rb",
    "content": "# The Mail class represents an internet mail message (as per RFC822, RFC2822)\n# with headers and a body. \nclass Mail\n\n  # Create a new Mail where +f+ is either a stream which responds to gets(),\n  # or a path to a file.  If +f+ is a path it will be opened.\n  #\n  # The whole message is read so it can be made available through the #header,\n  # #[] and #body methods.\n  #\n  # The \"From \" line is ignored if the mail is in mbox format.\n  def initialize(f)\n    unless defined? f.gets\n      f = open(f, \"r\")\n      opened = true\n    end\n\n    @header = {}\n    @body = []\n    begin\n      while line = f.gets()\n\tline.chop!\n\tnext if /^From /=~line\t# skip From-line\n\tbreak if /^$/=~line\t# end of header\n\n\tif /^(\\S+?):\\s*(.*)/=~line\n\t  (attr = $1).capitalize!\n\t  @header[attr] = $2\n\telsif attr\n\t  line.sub!(/^\\s*/, '')\n\t  @header[attr] += \"\\n\" + line\n\tend\n      end\n  \n      return unless line\n\n      while line = f.gets()\n\tbreak if /^From /=~line\n\t@body.push(line)\n      end\n    ensure\n      f.close if opened\n    end\n  end\n\n  # Return the headers as a Hash.\n  def header\n    return @header\n  end\n\n  # Return the message body as an Array of lines\n  def body\n    return @body\n  end\n\n  # Return the header corresponding to +field+. \n  #\n  # Matching is case-insensitive.\n  def [](field)\n    @header[field.capitalize]\n  end\nend\n"
  },
  {
    "path": "lib/mathn.rb",
    "content": "#\n#   mathn.rb - \n#   \t$Release Version: 0.5 $\n#   \t$Revision: 1.1.1.1.4.1 $\n#   \t$Date: 1998/01/16 12:36:05 $\n#   \tby Keiju ISHITSUKA(SHL Japan Inc.)\n#\n# --\n#\n#   \n#\n\nrequire \"complex.rb\"\nrequire \"rational.rb\"\nrequire \"matrix.rb\"\n\nclass Integer\n\n  def gcd2(int)\n    a = self.abs\n    b = int.abs\n    a, b = b, a if a < b\n    \n    pd_a = a.prime_division\n    pd_b = b.prime_division\n    \n    gcd = 1\n    for pair in pd_a\n      as = pd_b.assoc(pair[0])\n      if as\n\tgcd *= as[0] ** [as[1], pair[1]].min\n      end\n    end\n    return gcd\n  end\n  \n  def Integer.from_prime_division(pd)\n    value = 1\n    for prime, index in pd\n      value *= prime**index\n    end\n    value\n  end\n  \n  def prime_division\n    raise ZeroDivisionError if self == 0\n    ps = Prime.new\n    value = self\n    pv = []\n    for prime in ps\n      count = 0\n      while (value1, mod = value.divmod(prime)\n\t     mod) == 0\n\tvalue = value1\n\tcount += 1\n      end\n      if count != 0\n\tpv.push [prime, count]\n      end\n      break if prime * prime  >= value\n    end\n    if value > 1\n      pv.push [value, 1]\n    end\n    return pv\n  end\nend\n  \nclass Prime\n  include Enumerable\n\n  def initialize\n    @seed = 1\n    @primes = []\n    @counts = []\n  end\n  \n  def succ\n    i = -1\n    size = @primes.size\n    while i < size\n      if i == -1\n\t@seed += 1\n\ti += 1\n      else\n\twhile @seed > @counts[i]\n\t  @counts[i] += @primes[i]\n\tend\n\tif @seed != @counts[i]\n\t  i += 1\n\telse\n\t  i = -1\n\tend\n      end\n    end\n    @primes.push @seed\n    @counts.push @seed + @seed\n    return @seed\n  end\n  alias next succ\n\n  def each\n    loop do\n      yield succ\n    end\n  end\nend\n\nclass Fixnum\n  alias / quo\nend\n\nclass Bignum\n  alias / quo\nend\n\nclass Rational\n  Unify = true\n\n  def inspect\n    format \"%s/%s\", numerator.inspect, denominator.inspect\n  end\n\n  alias power! **\n\n  def ** (other)\n    if other.kind_of?(Rational)\n      other2 = other\n      if self < 0\n\treturn Complex.new!(self, 0) ** other\n      elsif other == 0\n\treturn Rational(1,1)\n      elsif self == 0\n\treturn Rational(0,1)\n      elsif self == 1\n\treturn Rational(1,1)\n      end\n      \n      npd = numerator.prime_division\n      dpd = denominator.prime_division\n      if other < 0\n\tother = -other\n\tnpd, dpd = dpd, npd\n      end\n      \n      for elm in npd\n\telm[1] = elm[1] * other\n\tif !elm[1].kind_of?(Integer) and elm[1].denominator != 1\n         return Float(self) ** other2\n\tend\n\telm[1] = elm[1].to_i\n      end\n      \n      for elm in dpd\n\telm[1] = elm[1] * other\n\tif !elm[1].kind_of?(Integer) and elm[1].denominator != 1\n         return Float(self) ** other2\n\tend\n\telm[1] = elm[1].to_i\n      end\n      \n      num = Integer.from_prime_division(npd)\n      den = Integer.from_prime_division(dpd)\n      \n      Rational(num,den)\n      \n    elsif other.kind_of?(Integer)\n      if other > 0\n\tnum = numerator ** other\n\tden = denominator ** other\n      elsif other < 0\n\tnum = denominator ** -other\n\tden = numerator ** -other\n      elsif other == 0\n\tnum = 1\n\tden = 1\n      end\n      Rational.new!(num, den)\n    elsif other.kind_of?(Float)\n      Float(self) ** other\n    else\n      x , y = other.coerce(self)\n      x ** y\n    end\n  end\n\n  def power2(other)\n    if other.kind_of?(Rational)\n      if self < 0\n\treturn Complex(self, 0) ** other\n      elsif other == 0\n\treturn Rational(1,1)\n      elsif self == 0\n\treturn Rational(0,1)\n      elsif self == 1\n\treturn Rational(1,1)\n      end\n      \n      dem = nil\n      x = self.denominator.to_f.to_i\n      neard = self.denominator.to_f ** (1.0/other.denominator.to_f)\n      loop do\n\tif (neard**other.denominator == self.denominator)\n\t  dem = neaed\n\t  break\n\tend\n      end\n      nearn = self.numerator.to_f ** (1.0/other.denominator.to_f)\n      Rational(num,den)\n      \n    elsif other.kind_of?(Integer)\n      if other > 0\n\tnum = numerator ** other\n\tden = denominator ** other\n      elsif other < 0\n\tnum = denominator ** -other\n\tden = numerator ** -other\n      elsif other == 0\n\tnum = 1\n\tden = 1\n      end\n      Rational.new!(num, den)\n    elsif other.kind_of?(Float)\n      Float(self) ** other\n    else\n      x , y = other.coerce(self)\n      x ** y\n    end\n  end\nend\n\nmodule Math\n  def sqrt(a)\n    if a.kind_of?(Complex)\n      abs = sqrt(a.real*a.real + a.image*a.image)\n#      if not abs.kind_of?(Rational)\n#\treturn a**Rational(1,2)\n#      end\n      x = sqrt((a.real + abs)/Rational(2))\n      y = sqrt((-a.real + abs)/Rational(2))\n#      if !(x.kind_of?(Rational) and y.kind_of?(Rational))\n#\treturn a**Rational(1,2)\n#      end\n      if a.image >= 0 \n\tComplex(x, y)\n      else\n\tComplex(x, -y)\n      end\n    elsif a >= 0\n      rsqrt(a)\n    else\n      Complex(0,rsqrt(-a))\n    end\n  end\n  \n  def rsqrt(a)\n    if a.kind_of?(Float)\n      sqrt!(a)\n    elsif a.kind_of?(Rational)\n      rsqrt(a.numerator)/rsqrt(a.denominator)\n    else\n      src = a\n      max = 2 ** 32\n      byte_a = [src & 0xffffffff]\n      # ruby's bug\n      while (src >= max) and (src >>= 32)\n\tbyte_a.unshift src & 0xffffffff\n      end\n      \n      answer = 0\n      main = 0\n      side = 0\n      for elm in byte_a\n\tmain = (main << 32) + elm\n\tside <<= 16\n\tif answer != 0\n\t  if main * 4  < side * side\n\t    applo = main.div(side)\n\t  else \n\t    applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1\n\t  end\n\telse\n\t  applo = sqrt!(main).to_i + 1\n\tend\n\t\n\twhile (x = (side + applo) * applo) > main\n\t  applo -= 1\n\tend\n\tmain -= x\n\tanswer = (answer << 16) + applo\n\tside += applo * 2\n      end\n      if main == 0\n\tanswer\n      else\n\tsqrt!(a)\n      end\n    end\n  end\n\n  module_function :sqrt\n  module_function :rsqrt\nend\n\nclass Complex\n  Unify = true\nend\n\n"
  },
  {
    "path": "lib/matrix.rb",
    "content": "#!/usr/local/bin/ruby\n#--\n#   matrix.rb - \n#       $Release Version: 1.0$\n#       $Revision: 1.11 $\n#       $Date: 1999/10/06 11:01:53 $\n#       Original Version from Smalltalk-80 version\n#          on July 23, 1985 at 8:37:17 am\n#       by Keiju ISHITSUKA\n#++\n#\n# = matrix.rb\n#\n# An implementation of Matrix and Vector classes.\n#\n# Author:: Keiju ISHITSUKA\n# Documentation:: Gavin Sinclair (sourced from <i>Ruby in a Nutshell</i> (Matsumoto, O'Reilly)) \n#\n# See classes Matrix and Vector for documentation. \n#\n\n\nrequire \"e2mmap.rb\"\n\nmodule ExceptionForMatrix # :nodoc:\n  extend Exception2MessageMapper\n  def_e2message(TypeError, \"wrong argument type %s (expected %s)\")\n  def_e2message(ArgumentError, \"Wrong # of arguments(%d for %d)\")\n  \n  def_exception(\"ErrDimensionMismatch\", \"\\#{self.name} dimension mismatch\")\n  def_exception(\"ErrNotRegular\", \"Not Regular Matrix\")\n  def_exception(\"ErrOperationNotDefined\", \"This operation(%s) can\\\\'t defined\")\nend\n\n#\n# The +Matrix+ class represents a mathematical matrix, and provides methods for creating\n# special-case matrices (zero, identity, diagonal, singular, vector), operating on them\n# arithmetically and algebraically, and determining their mathematical properties (trace, rank,\n# inverse, determinant).\n#\n# Note that although matrices should theoretically be rectangular, this is not\n# enforced by the class.\n#\n# Also note that the determinant of integer matrices may be incorrectly calculated unless you\n# also <tt>require 'mathn'</tt>.  This may be fixed in the future.\n#\n# == Method Catalogue\n#\n# To create a matrix:\n# * <tt> Matrix[*rows]                  </tt>\n# * <tt> Matrix.[](*rows)               </tt>\n# * <tt> Matrix.rows(rows, copy = true) </tt>\n# * <tt> Matrix.columns(columns)        </tt>\n# * <tt> Matrix.diagonal(*values)       </tt>\n# * <tt> Matrix.scalar(n, value)        </tt>\n# * <tt> Matrix.scalar(n, value)        </tt>\n# * <tt> Matrix.identity(n)             </tt>\n# * <tt> Matrix.unit(n)                 </tt>\n# * <tt> Matrix.I(n)                    </tt>\n# * <tt> Matrix.zero(n)                 </tt>\n# * <tt> Matrix.row_vector(row)         </tt>\n# * <tt> Matrix.column_vector(column)   </tt>\n#\n# To access Matrix elements/columns/rows/submatrices/properties: \n# * <tt>  [](i, j)                      </tt>\n# * <tt> #row_size                      </tt>\n# * <tt> #column_size                   </tt>\n# * <tt> #row(i)                        </tt>\n# * <tt> #column(j)                     </tt>\n# * <tt> #collect                       </tt>\n# * <tt> #map                           </tt>\n# * <tt> #minor(*param)                 </tt>\n#\n# Properties of a matrix:\n# * <tt> #regular?                      </tt>\n# * <tt> #singular?                     </tt>\n# * <tt> #square?                       </tt>\n#\n# Matrix arithmetic:\n# * <tt>  *(m)                          </tt>\n# * <tt>  +(m)                          </tt>\n# * <tt>  -(m)                          </tt>\n# * <tt> #/(m)                          </tt>\n# * <tt> #inverse                       </tt>\n# * <tt> #inv                           </tt>\n# * <tt>  **                            </tt>\n#\n# Matrix functions:\n# * <tt> #determinant                   </tt>\n# * <tt> #det                           </tt>\n# * <tt> #rank                          </tt>\n# * <tt> #trace                         </tt>\n# * <tt> #tr                            </tt>\n# * <tt> #transpose                     </tt>\n# * <tt> #t                             </tt>\n#\n# Conversion to other data types:\n# * <tt> #coerce(other)                 </tt>\n# * <tt> #row_vectors                   </tt>\n# * <tt> #column_vectors                </tt>\n# * <tt> #to_a                          </tt>\n#\n# String representations:\n# * <tt> #to_s                          </tt>\n# * <tt> #inspect                       </tt>\n#\nclass Matrix\n  @RCS_ID='-$Id: matrix.rb,v 1.11 1999/10/06 11:01:53 keiju Exp keiju $-'\n  \n#  extend Exception2MessageMapper\n  include ExceptionForMatrix\n  \n  # instance creations\n  private_class_method :new\n  \n  #\n  # Creates a matrix where each argument is a row.\n  #   Matrix[ [25, 93], [-1, 66] ]\n  #      =>  25 93\n  #          -1 66\n  #\n  def Matrix.[](*rows)\n    new(:init_rows, rows, false)\n  end\n  \n  #\n  # Creates a matrix where +rows+ is an array of arrays, each of which is a row\n  # to the matrix.  If the optional argument +copy+ is false, use the given\n  # arrays as the internal structure of the matrix without copying.\n  #   Matrix.rows([[25, 93], [-1, 66]])\n  #      =>  25 93\n  #          -1 66\n  def Matrix.rows(rows, copy = true)\n    new(:init_rows, rows, copy)\n  end\n  \n  #\n  # Creates a matrix using +columns+ as an array of column vectors.\n  #   Matrix.columns([[25, 93], [-1, 66]])\n  #      =>  25 -1\n  #          93 66\n  #\n  #\n  def Matrix.columns(columns)\n    rows = (0 .. columns[0].size - 1).collect {\n      |i|\n      (0 .. columns.size - 1).collect {\n        |j|\n        columns[j][i]\n      }\n    }\n    Matrix.rows(rows, false)\n  end\n  \n  #\n  # Creates a matrix where the diagonal elements are composed of +values+.\n  #   Matrix.diagonal(9, 5, -3)\n  #     =>  9  0  0\n  #         0  5  0\n  #         0  0 -3\n  #\n  def Matrix.diagonal(*values)\n    size = values.size\n    rows = (0 .. size  - 1).collect {\n      |j|\n      row = Array.new(size).fill(0, 0, size)\n      row[j] = values[j]\n      row\n    }\n    rows(rows, false)\n  end\n  \n  #\n  # Creates an +n+ by +n+ diagonal matrix where each diagonal element is\n  # +value+.\n  #   Matrix.scalar(2, 5)\n  #     => 5 0\n  #        0 5\n  #\n  def Matrix.scalar(n, value)\n    Matrix.diagonal(*Array.new(n).fill(value, 0, n))\n  end\n\n  #\n  # Creates an +n+ by +n+ identity matrix.\n  #   Matrix.identity(2)\n  #     => 1 0\n  #        0 1\n  #\n  def Matrix.identity(n)\n    Matrix.scalar(n, 1)\n  end\n  class << Matrix \n    alias unit identity\n    alias I identity\n  end\n  \n  #\n  # Creates an +n+ by +n+ zero matrix.\n  #   Matrix.zero(2)\n  #     => 0 0\n  #        0 0\n  #\n  def Matrix.zero(n)\n    Matrix.scalar(n, 0)\n  end\n  \n  #\n  # Creates a single-row matrix where the values of that row are as given in\n  # +row+.\n  #   Matrix.row_vector([4,5,6])\n  #     => 4 5 6\n  #\n  def Matrix.row_vector(row)\n    case row\n    when Vector\n      Matrix.rows([row.to_a], false)\n    when Array\n      Matrix.rows([row.dup], false)\n    else\n      Matrix.rows([[row]], false)\n    end\n  end\n  \n  #\n  # Creates a single-column matrix where the values of that column are as given\n  # in +column+.\n  #   Matrix.column_vector([4,5,6])\n  #     => 4\n  #        5\n  #        6\n  #\n  def Matrix.column_vector(column)\n    case column\n    when Vector\n      Matrix.columns([column.to_a])\n    when Array\n      Matrix.columns([column])\n    else\n      Matrix.columns([[column]])\n    end\n  end\n\n  #\n  # This method is used by the other methods that create matrices, and is of no\n  # use to general users.\n  #\n  def initialize(init_method, *argv)\n    self.send(init_method, *argv)\n  end\n  \n  def init_rows(rows, copy)\n    if copy\n      @rows = rows.collect{|row| row.dup}\n    else\n      @rows = rows\n    end\n    self\n  end\n  private :init_rows\n  \n  #\n  # Returns element (+i+,+j+) of the matrix.  That is: row +i+, column +j+.\n  #\n  def [](i, j)\n    @rows[i][j]\n  end\n\n  #\n  # Returns the number of rows.\n  #\n  def row_size\n    @rows.size\n  end\n  \n  #\n  # Returns the number of columns.  Note that it is possible to construct a\n  # matrix with uneven columns (e.g. Matrix[ [1,2,3], [4,5] ]), but this is\n  # mathematically unsound.  This method uses the first row to determine the\n  # result.\n  #\n  def column_size\n    @rows[0].size\n  end\n\n  #\n  # Returns row vector number +i+ of the matrix as a Vector (starting at 0 like\n  # an array).  When a block is given, the elements of that vector are iterated.\n  #\n  def row(i) # :yield: e\n    if block_given?\n      for e in @rows[i]\n        yield e\n      end\n    else\n      Vector.elements(@rows[i])\n    end\n  end\n\n  #\n  # Returns column vector number +j+ of the matrix as a Vector (starting at 0\n  # like an array).  When a block is given, the elements of that vector are\n  # iterated.\n  #\n  def column(j) # :yield: e\n    if block_given?\n      0.upto(row_size - 1) do\n        |i|\n        yield @rows[i][j]\n      end\n    else\n      col = (0 .. row_size - 1).collect {\n        |i|\n        @rows[i][j]\n      }\n      Vector.elements(col, false)\n    end\n  end\n  \n  #\n  # Returns a matrix that is the result of iteration of the given block over all\n  # elements of the matrix.\n  #   Matrix[ [1,2], [3,4] ].collect { |i| i**2 }\n  #     => 1  4\n  #        9 16\n  #\n  def collect # :yield: e\n    rows = @rows.collect{|row| row.collect{|e| yield e}}\n    Matrix.rows(rows, false)\n  end\n  alias map collect\n  \n  #\n  # Returns a section of the matrix.  The parameters are either:\n  # *  start_row, nrows, start_col, ncols; OR\n  # *  col_range, row_range\n  #\n  #   Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)\n  #     => 9 0 0\n  #        0 5 0\n  #\n  def minor(*param)\n    case param.size\n    when 2\n      from_row = param[0].first\n      size_row = param[0].end - from_row\n      size_row += 1 unless param[0].exclude_end?\n      from_col = param[1].first\n      size_col = param[1].end - from_col\n      size_col += 1 unless param[1].exclude_end?\n    when 4\n      from_row = param[0]\n      size_row = param[1]\n      from_col = param[2]\n      size_col = param[3]\n    else\n      Matrix.Raise ArgumentError, param.inspect\n    end\n    \n    rows = @rows[from_row, size_row].collect{\n      |row|\n      row[from_col, size_col]\n    }\n    Matrix.rows(rows, false)\n  end\n \n  #--\n  # TESTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n\n  #\n  # Returns +true+ if this is a regular matrix.\n  #\n  def regular?\n    square? and rank == column_size\n  end\n  \n  #\n  # Returns +true+ is this is a singular (i.e. non-regular) matrix.\n  #\n  def singular?\n    not regular?\n  end\n\n  #\n  # Returns +true+ is this is a square matrix.  See note in column_size about this\n  # being unreliable, though.\n  #\n  def square?\n    column_size == row_size\n  end\n  \n  #--\n  # OBJECT METHODS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n\n  #\n  # Returns +true+ if and only if the two matrices contain equal elements.\n  #\n  def ==(other)\n    return false unless Matrix === other\n    \n    other.compare_by_row_vectors(@rows)\n  end\n  alias eql? ==\n  \n  #\n  # Not really intended for general consumption.\n  #\n  def compare_by_row_vectors(rows)\n    return false unless @rows.size == rows.size\n    \n    0.upto(@rows.size - 1) do\n      |i|\n      return false unless @rows[i] == rows[i]\n    end\n    true\n  end\n  \n  #\n  # Returns a clone of the matrix, so that the contents of each do not reference\n  # identical objects.\n  #\n  def clone\n    Matrix.rows(@rows)\n  end\n  \n  #\n  # Returns a hash-code for the matrix.\n  #\n  def hash\n    value = 0\n    for row in @rows\n      for e in row\n        value ^= e.hash\n      end\n    end\n    return value\n  end\n  \n  #--\n  # ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # Matrix multiplication.\n  #   Matrix[[2,4], [6,8]] * Matrix.identity(2)\n  #     => 2 4\n  #        6 8\n  #\n  def *(m) # m is matrix or vector or number\n    case(m)\n    when Numeric\n      rows = @rows.collect {\n        |row|\n        row.collect {\n          |e|\n          e * m\n        }\n      }\n      return Matrix.rows(rows, false)\n    when Vector\n      m = Matrix.column_vector(m)\n      r = self * m\n      return r.column(0)\n    when Matrix\n      Matrix.Raise ErrDimensionMismatch if column_size != m.row_size\n    \n      rows = (0 .. row_size - 1).collect {\n        |i|\n        (0 .. m.column_size - 1).collect {\n          |j|\n          vij = 0\n          0.upto(column_size - 1) do\n            |k|\n            vij += self[i, k] * m[k, j]\n          end\n          vij\n        }\n      }\n      return Matrix.rows(rows, false)\n    else\n      x, y = m.coerce(self)\n      return x * y\n    end\n  end\n  \n  #\n  # Matrix addition.\n  #   Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]\n  #     =>  6  0\n  #        -4 12\n  #\n  def +(m)\n    case m\n    when Numeric\n      Matrix.Raise ErrOperationNotDefined, \"+\"\n    when Vector\n      m = Matrix.column_vector(m)\n    when Matrix\n    else\n      x, y = m.coerce(self)\n      return x + y\n    end\n    \n    Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size\n    \n    rows = (0 .. row_size - 1).collect {\n      |i|\n      (0 .. column_size - 1).collect {\n        |j|\n        self[i, j] + m[i, j]\n      }\n    }\n    Matrix.rows(rows, false)\n  end\n\n  #\n  # Matrix subtraction.\n  #   Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]\n  #     => -8  2\n  #         8  1\n  #\n  def -(m)\n    case m\n    when Numeric\n      Matrix.Raise ErrOperationNotDefined, \"-\"\n    when Vector\n      m = Matrix.column_vector(m)\n    when Matrix\n    else\n      x, y = m.coerce(self)\n      return x - y\n    end\n    \n    Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size\n    \n    rows = (0 .. row_size - 1).collect {\n      |i|\n      (0 .. column_size - 1).collect {\n        |j|\n        self[i, j] - m[i, j]\n      }\n    }\n    Matrix.rows(rows, false)\n  end\n  \n  #\n  # Matrix division (multiplication by the inverse).\n  #   Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]\n  #     => -7  1\n  #        -3 -6\n  #\n  def /(other)\n    case other\n    when Numeric\n      rows = @rows.collect {\n        |row|\n        row.collect {\n          |e|\n          e / other\n        }\n      }\n      return Matrix.rows(rows, false)\n    when Matrix\n      return self * other.inverse\n    else\n      x, y = other.coerce(self)\n      rerurn x / y\n    end\n  end\n\n  #\n  # Returns the inverse of the matrix.\n  #   Matrix[[1, 2], [2, 1]].inverse\n  #     => -1  1\n  #         0 -1\n  #\n  def inverse\n    Matrix.Raise ErrDimensionMismatch unless square?\n    Matrix.I(row_size).inverse_from(self)\n  end\n  alias inv inverse\n\n  #\n  # Not for public consumption?\n  #\n  def inverse_from(src)\n    size = row_size - 1\n    a = src.to_a\n    \n    for k in 0..size\n      i = k\n      akk = a[k][k].abs\n      for j in (k+1)..size\n        v = a[j][k].abs\n        if v > akk\n          i = j\n          akk = v\n        end\n      end\n      Matrix.Raise ErrNotRegular if akk == 0\n      if i != k\n        a[i], a[k] = a[k], a[i]\n        @rows[i], @rows[k] = @rows[k], @rows[i]\n      end\n      akk = a[k][k]\n      \n      for i in 0 .. size\n        next if i == k\n        q = a[i][k] / akk\n        a[i][k] = 0\n        \n        (k + 1).upto(size) do   \n          |j|\n          a[i][j] -= a[k][j] * q\n        end\n        0.upto(size) do\n          |j|\n          @rows[i][j] -= @rows[k][j] * q\n        end\n      end\n      \n      (k + 1).upto(size) do\n        |j|\n        a[k][j] /= akk\n      end\n      0.upto(size) do\n        |j|\n        @rows[k][j] /= akk\n      end\n    end\n    self\n  end\n  #alias reciprocal inverse\n  \n  #\n  # Matrix exponentiation.  Defined for integer powers only.  Equivalent to\n  # multiplying the matrix by itself N times.\n  #   Matrix[[7,6], [3,9]] ** 2\n  #     => 67 96\n  #        48 99\n  #\n  def ** (other)\n    if other.kind_of?(Integer)\n      x = self\n      if other <= 0\n        x = self.inverse\n        return Matrix.identity(self.column_size) if other == 0\n        other = -other\n      end\n      z = x\n      n = other  - 1\n      while n != 0\n        while (div, mod = n.divmod(2)\n               mod == 0)\n          x = x * x\n          n = div\n        end\n        z *= x\n        n -= 1\n      end\n      z\n    elsif other.kind_of?(Float) || defined?(Rational) && other.kind_of?(Rational)\n      Matrix.Raise ErrOperationNotDefined, \"**\"\n    else\n      Matrix.Raise ErrOperationNotDefined, \"**\"\n    end\n  end\n  \n  #--\n  # MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # Returns the determinant of the matrix.  If the matrix is not square, the\n  # result is 0.\n  #   Matrix[[7,6], [3,9]].determinant\n  #     => 63\n  #\n  def determinant\n    return 0 unless square?\n    \n    size = row_size - 1\n    a = to_a\n    \n    det = 1\n    k = 0\n    begin \n      if (akk = a[k][k]) == 0\n        i = k\n        begin\n          return 0 if (i += 1) > size\n        end while a[i][k] == 0\n        a[i], a[k] = a[k], a[i]\n        akk = a[k][k]\n        det *= -1\n      end\n      (k + 1).upto(size) do\n        |i|\n        q = a[i][k] / akk\n        (k + 1).upto(size) do\n          |j|\n          a[i][j] -= a[k][j] * q\n        end\n      end\n      det *= akk\n    end while (k += 1) <= size\n    det\n  end\n  alias det determinant\n        \n  #\n  # Returns the rank of the matrix.  Beware that using Float values, with their\n  # usual lack of precision, can affect the value returned by this method.  Use\n  # Rational values instead if this is important to you.\n  #   Matrix[[7,6], [3,9]].rank\n  #     => 2\n  #\n  def rank\n    if column_size > row_size\n      a = transpose.to_a\n      a_column_size = row_size\n      a_row_size = column_size\n    else\n      a = to_a\n      a_column_size = column_size\n      a_row_size = row_size\n    end\n    rank = 0\n    k = 0\n    begin\n      if (akk = a[k][k]) == 0\n        i = k\n        exists = true\n        begin\n          if (i += 1) > a_column_size - 1\n            exists = false\n            break\n          end\n        end while a[i][k] == 0\n        if exists\n          a[i], a[k] = a[k], a[i]\n          akk = a[k][k]\n        else\n          i = k\n          exists = true\n          begin\n            if (i += 1) > a_row_size - 1\n              exists = false\n              break\n            end\n          end while a[k][i] == 0\n          if exists\n            k.upto(a_column_size - 1) do\n              |j|\n              a[j][k], a[j][i] = a[j][i], a[j][k]\n            end\n            akk = a[k][k]\n          else\n            next\n          end\n        end\n      end\n      (k + 1).upto(a_row_size - 1) do\n        |i|\n        q = a[i][k] / akk\n        (k + 1).upto(a_column_size - 1) do\n          |j|\n          a[i][j] -= a[k][j] * q\n        end\n      end\n      rank += 1\n    end while (k += 1) <= a_column_size - 1\n    return rank\n  end\n\n  #\n  # Returns the trace (sum of diagonal elements) of the matrix.\n  #   Matrix[[7,6], [3,9]].trace\n  #     => 16\n  #\n  def trace\n    tr = 0\n    0.upto(column_size - 1) do\n      |i|\n      tr += @rows[i][i]\n    end\n    tr\n  end\n  alias tr trace\n  \n  #\n  # Returns the transpose of the matrix.\n  #   Matrix[[1,2], [3,4], [5,6]]\n  #     => 1 2\n  #        3 4\n  #        5 6\n  #   Matrix[[1,2], [3,4], [5,6]].transpose\n  #     => 1 3 5\n  #        2 4 6\n  #\n  def transpose\n    Matrix.columns(@rows)\n  end\n  alias t transpose\n  \n  #--\n  # CONVERTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # FIXME: describe #coerce.\n  #\n  def coerce(other)\n    case other\n    when Numeric\n      return Scalar.new(other), self\n    else\n      raise TypeError, \"#{self.class} can't be coerced into #{other.class}\"\n    end\n  end\n\n  #\n  # Returns an array of the row vectors of the matrix.  See Vector.\n  #\n  def row_vectors\n    rows = (0 .. row_size - 1).collect {\n      |i|\n      row(i)\n    }\n    rows\n  end\n  \n  #\n  # Returns an array of the column vectors of the matrix.  See Vector.\n  #\n  def column_vectors\n    columns = (0 .. column_size - 1).collect {\n      |i|\n      column(i)\n    }\n    columns\n  end\n  \n  #\n  # Returns an array of arrays that describe the rows of the matrix.\n  #\n  def to_a\n    @rows.collect{|row| row.collect{|e| e}}\n  end\n  \n  #--\n  # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # Overrides Object#to_s\n  #\n  def to_s\n    \"Matrix[\" + @rows.collect{\n      |row|\n      \"[\" + row.collect{|e| e.to_s}.join(\", \") + \"]\"\n    }.join(\", \")+\"]\"\n  end\n  \n  #\n  # Overrides Object#inspect\n  #\n  def inspect\n    \"Matrix\"+@rows.inspect\n  end\n  \n  # Private CLASS\n  \n  class Scalar < Numeric # :nodoc:\n    include ExceptionForMatrix\n    \n    def initialize(value)\n      @value = value\n    end\n    \n    # ARITHMETIC\n    def +(other)\n      case other\n      when Numeric\n        Scalar.new(@value + other)\n      when Vector, Matrix\n        Scalar.Raise WrongArgType, other.class, \"Numeric or Scalar\"\n      when Scalar\n        Scalar.new(@value + other.value)\n      else\n        x, y = other.coerce(self)\n        x + y\n      end\n    end\n    \n    def -(other)\n      case other\n      when Numeric\n        Scalar.new(@value - other)\n      when Vector, Matrix\n        Scalar.Raise WrongArgType, other.class, \"Numeric or Scalar\"\n      when Scalar\n        Scalar.new(@value - other.value)\n      else\n        x, y = other.coerce(self)\n        x - y\n      end\n    end\n    \n    def *(other)\n      case other\n      when Numeric\n        Scalar.new(@value * other)\n      when Vector, Matrix\n        other.collect{|e| @value * e}\n      else\n        x, y = other.coerce(self)\n        x * y\n      end\n    end\n    \n    def / (other)\n      case other\n      when Numeric\n        Scalar.new(@value / other)\n      when Vector\n        Scalar.Raise WrongArgType, other.class, \"Numeric or Scalar or Matrix\"\n      when Matrix\n        self * _M.inverse\n      else\n        x, y = other.coerce(self)\n        x / y\n      end\n    end\n    \n    def ** (other)\n      case other\n      when Numeric\n        Scalar.new(@value ** other)\n      when Vector\n        Scalar.Raise WrongArgType, other.class, \"Numeric or Scalar or Matrix\"\n      when Matrix\n        other.powered_by(self)\n      else\n        x, y = other.coerce(self)\n        x ** y\n      end\n    end\n  end\nend\n\n\n#\n# The +Vector+ class represents a mathematical vector, which is useful in its own right, and\n# also constitutes a row or column of a Matrix.\n#\n# == Method Catalogue\n#\n# To create a Vector:\n# * <tt>  Vector.[](*array)                   </tt>\n# * <tt>  Vector.elements(array, copy = true) </tt>\n#\n# To access elements:\n# * <tt>  [](i)                               </tt>\n#\n# To enumerate the elements:\n# * <tt> #each2(v)                            </tt>\n# * <tt> #collect2(v)                         </tt>\n#\n# Vector arithmetic:\n# * <tt>  *(x) \"is matrix or number\"          </tt>\n# * <tt>  +(v)                                </tt>\n# * <tt>  -(v)                                </tt>\n#\n# Vector functions:\n# * <tt> #inner_product(v)                    </tt>\n# * <tt> #collect                             </tt>\n# * <tt> #map                                 </tt>\n# * <tt> #map2(v)                             </tt>\n# * <tt> #r                                   </tt>\n# * <tt> #size                                </tt>\n#\n# Conversion to other data types:\n# * <tt> #covector                            </tt>\n# * <tt> #to_a                                </tt>\n# * <tt> #coerce(other)                       </tt>\n#\n# String representations:\n# * <tt> #to_s                                </tt>\n# * <tt> #inspect                             </tt>\n#\nclass Vector\n  include ExceptionForMatrix\n  \n  #INSTANCE CREATION\n  \n  private_class_method :new\n\n  #\n  # Creates a Vector from a list of elements.\n  #   Vector[7, 4, ...]\n  #\n  def Vector.[](*array)\n    new(:init_elements, array, copy = false)\n  end\n  \n  #\n  # Creates a vector from an Array.  The optional second argument specifies\n  # whether the array itself or a copy is used internally.\n  #\n  def Vector.elements(array, copy = true)\n    new(:init_elements, array, copy)\n  end\n  \n  #\n  # For internal use.\n  #\n  def initialize(method, array, copy)\n    self.send(method, array, copy)\n  end\n  \n  #\n  # For internal use.\n  #\n  def init_elements(array, copy)\n    if copy\n      @elements = array.dup\n    else\n      @elements = array\n    end\n  end\n  \n  # ACCESSING\n         \n  #\n  # Returns element number +i+ (starting at zero) of the vector.\n  #\n  def [](i)\n    @elements[i]\n  end\n  \n  #\n  # Returns the number of elements in the vector.\n  #\n  def size\n    @elements.size\n  end\n  \n  #--\n  # ENUMERATIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n\n  #\n  # Iterate over the elements of this vector and +v+ in conjunction.\n  #\n  def each2(v) # :yield: e1, e2\n    Vector.Raise ErrDimensionMismatch if size != v.size\n    0.upto(size - 1) do\n      |i|\n      yield @elements[i], v[i]\n    end\n  end\n  \n  #\n  # Collects (as in Enumerable#collect) over the elements of this vector and +v+\n  # in conjunction.\n  #\n  def collect2(v) # :yield: e1, e2\n    Vector.Raise ErrDimensionMismatch if size != v.size\n    (0 .. size - 1).collect do\n      |i|\n      yield @elements[i], v[i]\n    end\n  end\n\n  #--\n  # COMPARING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n\n  #\n  # Returns +true+ iff the two vectors have the same elements in the same order.\n  #\n  def ==(other)\n    return false unless Vector === other\n    \n    other.compare_by(@elements)\n  end\n  alias eql? ==\n  \n  #\n  # For internal use.\n  #\n  def compare_by(elements)\n    @elements == elements\n  end\n  \n  #\n  # Return a copy of the vector.\n  #\n  def clone\n    Vector.elements(@elements)\n  end\n  \n  #\n  # Return a hash-code for the vector.\n  #\n  def hash\n    @elements.hash\n  end\n  \n  #--\n  # ARITHMETIC -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # Multiplies the vector by +x+, where +x+ is a number or another vector.\n  #\n  def *(x)\n    case x\n    when Numeric\n      els = @elements.collect{|e| e * x}\n      Vector.elements(els, false)\n    when Matrix\n      Matrix.column_vector(self) * x\n    else\n      s, x = x.coerce(self)\n      s * x\n    end\n  end\n\n  #\n  # Vector addition.\n  #\n  def +(v)\n    case v\n    when Vector\n      Vector.Raise ErrDimensionMismatch if size != v.size\n      els = collect2(v) {\n        |v1, v2|\n        v1 + v2\n      }\n      Vector.elements(els, false)\n    when Matrix\n      Matrix.column_vector(self) + v\n    else\n      s, x = v.coerce(self)\n      s + x\n    end\n  end\n\n  #\n  # Vector subtraction.\n  #\n  def -(v)\n    case v\n    when Vector\n      Vector.Raise ErrDimensionMismatch if size != v.size\n      els = collect2(v) {\n        |v1, v2|\n        v1 - v2\n      }\n      Vector.elements(els, false)\n    when Matrix\n      Matrix.column_vector(self) - v\n    else\n      s, x = v.coerce(self)\n      s - x\n    end\n  end\n  \n  #--\n  # VECTOR FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # Returns the inner product of this vector with the other.\n  #   Vector[4,7].inner_product Vector[10,1]  => 47\n  #\n  def inner_product(v)\n    Vector.Raise ErrDimensionMismatch if size != v.size\n    \n    p = 0\n    each2(v) {\n      |v1, v2|\n      p += v1 * v2\n    }\n    p\n  end\n  \n  #\n  # Like Array#collect.\n  #\n  def collect # :yield: e\n    els = @elements.collect {\n      |v|\n      yield v\n    }\n    Vector.elements(els, false)\n  end\n  alias map collect\n  \n  #\n  # Like Vector#collect2, but returns a Vector instead of an Array.\n  #\n  def map2(v) # :yield: e1, e2\n    els = collect2(v) {\n      |v1, v2|\n      yield v1, v2\n    }\n    Vector.elements(els, false)\n  end\n  \n  #\n  # Returns the modulus (Pythagorean distance) of the vector.\n  #   Vector[5,8,2].r => 9.643650761\n  #\n  def r\n    v = 0\n    for e in @elements\n      v += e*e\n    end\n    return Math.sqrt(v)\n  end\n  \n  #--\n  # CONVERTING\n  #++\n\n  #\n  # Creates a single-row matrix from this vector.\n  #\n  def covector\n    Matrix.row_vector(self)\n  end\n  \n  #\n  # Returns the elements of the vector in an array.\n  #\n  def to_a\n    @elements.dup\n  end\n  \n  #\n  # FIXME: describe Vector#coerce.\n  #\n  def coerce(other)\n    case other\n    when Numeric\n      return Scalar.new(other), self\n    else\n      raise TypeError, \"#{self.class} can't be coerced into #{other.class}\"\n    end\n  end\n  \n  #--\n  # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n  #++\n  \n  #\n  # Overrides Object#to_s\n  #\n  def to_s\n    \"Vector[\" + @elements.join(\", \") + \"]\"\n  end\n  \n  #\n  # Overrides Object#inspect\n  #\n  def inspect\n    str = \"Vector\"+@elements.inspect\n  end\nend\n\n\n# Documentation comments:\n#  - Matrix#coerce and Vector#coerce need to be documented\n"
  },
  {
    "path": "lib/mkmf.rb",
    "content": "# module to create Makefile for extension modules\n# invoke like: ruby -r mkmf extconf.rb\n\nrequire 'rbconfig'\nrequire 'fileutils'\nrequire 'shellwords'\n\nCONFIG = Config::MAKEFILE_CONFIG\nORIG_LIBPATH = ENV['LIB']\n\nCXX_EXT = %w[cc cxx cpp]\nif /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']\n  CXX_EXT.concat(%w[C])\nend\nSRC_EXT = %w[c m].concat(CXX_EXT)\n$static = $config_h = nil\n$default_static = $static\n\nunless defined? $configure_args\n  $configure_args = {}\n  args = CONFIG[\"configure_args\"]\n  if ENV[\"CONFIGURE_ARGS\"]\n    args << \" \" << ENV[\"CONFIGURE_ARGS\"]\n  end\n  for arg in Shellwords::shellwords(args)\n    arg, val = arg.split('=', 2)\n    next unless arg\n    arg.tr!('_', '-')\n    if arg.sub!(/^(?!--)/, '--')\n      val or next\n      arg.downcase!\n    end\n    next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg\n    $configure_args[arg] = val || true\n  end\n  for arg in ARGV\n    arg, val = arg.split('=', 2)\n    next unless arg\n    arg.tr!('_', '-')\n    if arg.sub!(/^(?!--)/, '--')\n      val or next\n      arg.downcase!\n    end\n    $configure_args[arg] = val || true\n  end\nend\n\n$libdir = CONFIG[\"libdir\"]\n$rubylibdir = CONFIG[\"rubylibdir\"]\n$archdir = CONFIG[\"archdir\"]\n$sitedir = CONFIG[\"sitedir\"]\n$sitelibdir = CONFIG[\"sitelibdir\"]\n$sitearchdir = CONFIG[\"sitearchdir\"]\n$vendordir = CONFIG[\"vendordir\"]\n$vendorlibdir = CONFIG[\"vendorlibdir\"]\n$vendorarchdir = CONFIG[\"vendorarchdir\"]\n\n$mswin = /mswin/ =~ RUBY_PLATFORM\n$bccwin = /bccwin/ =~ RUBY_PLATFORM\n$mingw = /mingw/ =~ RUBY_PLATFORM\n$cygwin = /cygwin/ =~ RUBY_PLATFORM\n$human = /human/ =~ RUBY_PLATFORM\n$netbsd = /netbsd/ =~ RUBY_PLATFORM\n$os2 = /os2/ =~ RUBY_PLATFORM\n$beos = /beos/ =~ RUBY_PLATFORM\n$solaris = /solaris/ =~ RUBY_PLATFORM\n$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\\A([[:alpha:]]:)?/ : /\\A/)\n\n# :stopdoc:\n\ndef config_string(key, config = CONFIG)\n  s = config[key] and !s.empty? and block_given? ? yield(s) : s\nend\n\ndef dir_re(dir)\n  Regexp.new('\\$(?:\\('+dir+'\\)|\\{'+dir+'\\})(?:\\$(?:\\(target_prefix\\)|\\{target_prefix\\}))?')\nend\n\nINSTALL_DIRS = [\n  [dir_re('commondir'), \"$(RUBYCOMMONDIR)\"],\n  [dir_re('sitedir'), \"$(RUBYCOMMONDIR)\"],\n  [dir_re('vendordir'), \"$(RUBYCOMMONDIR)\"],\n  [dir_re('rubylibdir'), \"$(RUBYLIBDIR)\"],\n  [dir_re('archdir'), \"$(RUBYARCHDIR)\"],\n  [dir_re('sitelibdir'), \"$(RUBYLIBDIR)\"],\n  [dir_re('vendorlibdir'), \"$(RUBYLIBDIR)\"],\n  [dir_re('sitearchdir'), \"$(RUBYARCHDIR)\"],\n  [dir_re('bindir'), \"$(BINDIR)\"],\n  [dir_re('vendorarchdir'), \"$(RUBYARCHDIR)\"],\n]\n\ndef install_dirs(target_prefix = nil)\n  if $extout\n    dirs = [\n      ['BINDIR',        '$(extout)/bin'],\n      ['RUBYCOMMONDIR', '$(extout)/common'],\n      ['RUBYLIBDIR',    '$(RUBYCOMMONDIR)$(target_prefix)'],\n      ['RUBYARCHDIR',   '$(extout)/$(arch)$(target_prefix)'],\n      ['extout',        \"#$extout\"],\n      ['extout_prefix', \"#$extout_prefix\"],\n    ]\n  elsif $extmk\n    dirs = [\n      ['BINDIR',        '$(bindir)'],\n      ['RUBYCOMMONDIR', '$(rubylibdir)'],\n      ['RUBYLIBDIR',    '$(rubylibdir)$(target_prefix)'],\n      ['RUBYARCHDIR',   '$(archdir)$(target_prefix)'],\n    ]\n  elsif $configure_args.has_key?('--vendor')\n    dirs = [\n      ['BINDIR',        '$(bindir)'],\n      ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],\n      ['RUBYLIBDIR',    '$(vendorlibdir)$(target_prefix)'],\n      ['RUBYARCHDIR',   '$(vendorarchdir)$(target_prefix)'],\n    ]\n  else\n    dirs = [\n      ['BINDIR',        '$(bindir)'],\n      ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],\n      ['RUBYLIBDIR',    '$(sitelibdir)$(target_prefix)'],\n      ['RUBYARCHDIR',   '$(sitearchdir)$(target_prefix)'],\n    ]\n  end\n  dirs << ['target_prefix', (target_prefix ? \"/#{target_prefix}\" : \"\")]\n  dirs\nend\n\ndef map_dir(dir, map = nil)\n  map ||= INSTALL_DIRS\n  map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}\nend\n\ntopdir = File.dirname(libdir = File.dirname(__FILE__))\nextdir = File.expand_path(\"ext\", topdir)\n$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+\"/\"\nif not $extmk and File.exist?(($hdrdir = Config::CONFIG[\"archdir\"]) + \"/ruby.h\")\n  $topdir = $hdrdir\nelsif File.exist?(($hdrdir = ($top_srcdir ||= topdir))  + \"/ruby.h\") and\n    File.exist?(($topdir ||= Config::CONFIG[\"topdir\"]) + \"/config.h\")\nelse\n  abort \"mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h\"\nend\n\nOUTFLAG = CONFIG['OUTFLAG']\nCPPOUTFILE = CONFIG['CPPOUTFILE']\n\nCONFTEST_C = \"conftest.c\"\n\nclass String\n  # Wraps a string in escaped quotes if it contains whitespace.\n  def quote\n    /\\s/ =~ self ? \"\\\"#{self}\\\"\" : \"#{self}\"\n  end\n\n  # Generates a string used as cpp macro name.\n  def tr_cpp\n    strip.upcase.tr_s(\"^A-Z0-9_\", \"_\")\n  end\nend\nclass Array\n  # Wraps all strings in escaped quotes if they contain whitespace.\n  def quote\n    map {|s| s.quote}\n  end\nend\n\ndef rm_f(*files)\n  FileUtils.rm_f(Dir[files.join(\"\\0\")])\nend\n\n# Returns time stamp of the +target+ file if it exists and is newer\n# than or equal to all of +times+.\ndef modified?(target, times)\n  (t = File.mtime(target)) rescue return nil\n  Array === times or times = [times]\n  t if times.all? {|n| n <= t}\nend\n\ndef merge_libs(*libs)\n  libs.inject([]) do |x, y|\n    xy = x & y\n    xn = yn = 0\n    y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}\n    y.each_with_index do |v, yi|\n      if xy.include?(v)\n        xi = [x.index(v), xn].max()\n        x[xi, 1] = y[yn..yi]\n        xn, yn = xi + (yi - yn + 1), yi + 1\n      end\n    end\n    x.concat(y[yn..-1] || [])\n  end\nend\n\n# This is a custom logging module. It generates an mkmf.log file when you\n# run your extconf.rb script. This can be useful for debugging unexpected\n# failures.\n#\n# This module and its associated methods are meant for internal use only.\n#\nmodule Logging\n  @log = nil\n  @logfile = 'mkmf.log'\n  @orgerr = $stderr.dup\n  @orgout = $stdout.dup\n  @postpone = 0\n  @quiet = $extmk\n\n  def self::open\n    @log ||= File::open(@logfile, 'w')\n    @log.sync = true\n    $stderr.reopen(@log)\n    $stdout.reopen(@log)\n    yield\n  ensure\n    $stderr.reopen(@orgerr)\n    $stdout.reopen(@orgout)\n  end\n\n  def self::message(*s)\n    @log ||= File::open(@logfile, 'w')\n    @log.sync = true\n    @log.printf(*s)\n  end\n\n  def self::logfile file\n    @logfile = file\n    if @log and not @log.closed?\n      @log.flush\n      @log.close\n      @log = nil\n    end\n  end\n  \n  def self::postpone\n    tmplog = \"mkmftmp#{@postpone += 1}.log\"\n    open do\n      log, *save = @log, @logfile, @orgout, @orgerr\n      @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log\n      begin\n        log.print(open {yield})\n        @log.close\n        File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}\n      ensure\n        @log, @logfile, @orgout, @orgerr = log, *save\n        @postpone -= 1\n        rm_f tmplog\n      end\n    end\n  end\n\n  class << self\n    attr_accessor :quiet\n  end\nend\n\ndef xsystem command\n  varpat = /\\$\\((\\w+)\\)|\\$\\{(\\w+)\\}/\n  if varpat =~ command\n    vars = Hash.new {|h, k| h[k] = ''; ENV[k]}\n    command = command.dup\n    nil while command.gsub!(varpat) {vars[$1||$2]}\n  end\n  Logging::open do\n    puts command.quote\n    system(command)\n  end\nend\n\ndef xpopen command, *mode, &block\n  Logging::open do\n    case mode[0]\n    when nil, /^r/\n      puts \"#{command} |\"\n    else\n      puts \"| #{command}\"\n    end\n    IO.popen(command, *mode, &block)\n  end\nend\n\ndef log_src(src)\n  src = src.split(/^/)\n  fmt = \"%#{src.size.to_s.size}d: %s\"\n  Logging::message <<\"EOM\"\nchecked program was:\n/* begin */\nEOM\n  src.each_with_index {|line, no| Logging::message fmt, no+1, line}\n  Logging::message <<\"EOM\"\n/* end */\n\nEOM\nend\n\ndef create_tmpsrc(src)\n  src = yield(src) if block_given?\n  src = src.gsub(/[ \\t]+$/, '').gsub(/\\A\\n+|^\\n+$/, '').sub(/[^\\n]\\z/, \"\\\\&\\n\")\n  open(CONFTEST_C, \"wb\") do |cfile|\n    cfile.print src\n  end\n  src\nend\n\ndef try_do(src, command, &b)\n  src = create_tmpsrc(src, &b)\n  xsystem(command)\nensure\n  log_src(src)\nend\n\ndef link_command(ldflags, opt=\"\", libpath=$DEFLIBPATH|$LIBPATH)\n  conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote,\n                              'src' => CONFTEST_C,\n                              'INCFLAGS' => $INCFLAGS,\n                              'CPPFLAGS' => $CPPFLAGS,\n                              'CFLAGS' => \"#$CFLAGS\",\n                              'ARCH_FLAG' => \"#$ARCH_FLAG\",\n                              'LDFLAGS' => \"#$LDFLAGS #{ldflags}\",\n                              'LIBPATH' => libpathflag(libpath),\n                              'LOCAL_LIBS' => \"#$LOCAL_LIBS #$libs\",\n                              'LIBS' => \"#$LIBRUBYARG_STATIC #{opt} #$LIBS\")\n  Config::expand(TRY_LINK.dup, conf)\nend\n\ndef cc_command(opt=\"\")\n  conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)\n  Config::expand(\"$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}\",\n\t\t conf)\nend\n\ndef cpp_command(outfile, opt=\"\")\n  conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)\n  Config::expand(\"$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}\",\n\t\t conf)\nend\n\ndef libpathflag(libpath=$DEFLIBPATH|$LIBPATH)\n  libpath.map{|x|\n    case x\n    when \"$(topdir)\", /\\A\\./\n      LIBPATHFLAG\n    else\n      LIBPATHFLAG+RPATHFLAG\n    end % x.quote\n  }.join\nend\n\ndef try_link0(src, opt=\"\", &b)\n  try_do(src, link_command(\"\", opt), &b)\nend\n\ndef try_link(src, opt=\"\", &b)\n  try_link0(src, opt, &b)\nensure\n  rm_f \"conftest*\", \"c0x32*\"\nend\n\ndef try_compile(src, opt=\"\", &b)\n  try_do(src, cc_command(opt), &b)\nensure\n  rm_f \"conftest*\"\nend\n\ndef try_cpp(src, opt=\"\", &b)\n  try_do(src, cpp_command(CPPOUTFILE, opt), &b)\nensure\n  rm_f \"conftest*\"\nend\n\ndef cpp_include(header)\n  if header\n    header = [header] unless header.kind_of? Array\n    header.map {|h| \"#include <#{h}>\\n\"}.join\n  else\n    \"\"\n  end\nend\n\ndef with_cppflags(flags)\n  cppflags = $CPPFLAGS\n  $CPPFLAGS = flags\n  ret = yield\nensure\n  $CPPFLAGS = cppflags unless ret\nend\n\ndef with_cflags(flags)\n  cflags = $CFLAGS\n  $CFLAGS = flags\n  ret = yield\nensure\n  $CFLAGS = cflags unless ret\nend\n\ndef with_ldflags(flags)\n  ldflags = $LDFLAGS\n  $LDFLAGS = flags\n  ret = yield\nensure\n  $LDFLAGS = ldflags unless ret\nend\n\ndef try_static_assert(expr, headers = nil, opt = \"\", &b)\n  headers = cpp_include(headers)\n  try_compile(<<SRC, opt, &b)\n#{COMMON_HEADERS}\n#{headers}\n/*top*/\nint conftest_const[(#{expr}) ? 1 : -1];\nSRC\nend\n\ndef try_constant(const, headers = nil, opt = \"\", &b)\n  includes = cpp_include(headers)\n  if CROSS_COMPILING\n    if try_static_assert(\"#{const} > 0\", headers, opt)\n      # positive constant\n    elsif try_static_assert(\"#{const} < 0\", headers, opt)\n      neg = true\n      const = \"-(#{const})\"\n    elsif try_static_assert(\"#{const} == 0\", headers, opt)\n      return 0\n    else\n      # not a constant\n      return nil\n    end\n    upper = 1\n    lower = 0\n    until try_static_assert(\"#{const} <= #{upper}\", headers, opt)\n      lower = upper\n      upper <<= 1\n    end\n    return nil unless lower\n    while upper > lower + 1\n      mid = (upper + lower) / 2\n      if try_static_assert(\"#{const} > #{mid}\", headers, opt)\n        lower = mid\n      else\n        upper = mid\n      end\n    end\n    upper = -upper if neg\n    return upper\n  else\n    src = %{#{COMMON_HEADERS}\n#{includes}\n#include <stdio.h>\n/*top*/\nint conftest_const = (int)(#{const});\nint main() {printf(\"%d\\\\n\", conftest_const); return 0;}\n}\n    if try_link0(src, opt, &b)\n      xpopen(\"./conftest\") do |f|\n        return Integer(f.gets)\n      end\n    end\n  end\n  nil\nend\n\ndef try_func(func, libs, headers = nil, &b)\n  headers = cpp_include(headers)\n  try_link(<<\"SRC\", libs, &b) or try_link(<<\"SRC\", libs, &b)\n#{COMMON_HEADERS}\n#{headers}\n/*top*/\nint main() { return 0; }\nint t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }\nSRC\n#{headers}\n/*top*/\nint main() { return 0; }\nint t() { #{func}(); return 0; }\nSRC\nend\n\ndef try_var(var, headers = nil, &b)\n  headers = cpp_include(headers)\n  try_compile(<<\"SRC\", &b)\n#{COMMON_HEADERS}\n#{headers}\n/*top*/\nint main() { return 0; }\nint t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }\nSRC\nend\n\ndef egrep_cpp(pat, src, opt = \"\", &b)\n  src = create_tmpsrc(src, &b)\n  xpopen(cpp_command('', opt)) do |f|\n    if Regexp === pat\n      puts(\"    ruby -ne 'print if #{pat.inspect}'\")\n      f.grep(pat) {|l|\n\tputs \"#{f.lineno}: #{l}\"\n\treturn true\n      }\n      false\n    else\n      puts(\"    egrep '#{pat}'\")\n      begin\n\tstdin = $stdin.dup\n\t$stdin.reopen(f)\n\tsystem(\"egrep\", pat)\n      ensure\n\t$stdin.reopen(stdin)\n      end\n    end\n  end\nensure\n  rm_f \"conftest*\"\n  log_src(src)\nend\n\n# This is used internally by the have_macro? method.\ndef macro_defined?(macro, src, opt = \"\", &b)\n  src = src.sub(/[^\\n]\\z/, \"\\\\&\\n\")\n  try_compile(src + <<\"SRC\", opt, &b)\n/*top*/\n#ifndef #{macro}\n# error\n>>>>>> #{macro} undefined <<<<<<\n#endif\nSRC\nend\n\ndef try_run(src, opt = \"\", &b)\n  if try_link0(src, opt, &b)\n    xsystem(\"./conftest\")\n  else\n    nil\n  end\nensure\n  rm_f \"conftest*\"\nend\n\ndef install_files(mfile, ifiles, map = nil, srcprefix = nil)\n  ifiles or return\n  ifiles.empty? and return\n  srcprefix ||= '$(srcdir)'\n  Config::expand(srcdir = srcprefix.dup)\n  dirs = []\n  path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}\n  ifiles.each do |files, dir, prefix|\n    dir = map_dir(dir, map)\n    prefix &&= %r|\\A#{Regexp.quote(prefix)}/?|\n    if /\\A\\.\\// =~ files\n      # install files which are in current working directory.\n      files = files[2..-1]\n      len = nil\n    else\n      # install files which are under the $(srcdir).\n      files = File.join(srcdir, files)\n      len = srcdir.size\n    end\n    f = nil\n    Dir.glob(files) do |f|\n      f[0..len] = \"\" if len\n      case File.basename(f)\n      when *$NONINSTALLFILES\n        next\n      end\n      d = File.dirname(f)\n      d.sub!(prefix, \"\") if prefix\n      d = (d.empty? || d == \".\") ? dir : File.join(dir, d)\n      f = File.join(srcprefix, f) if len\n      path[d] << f\n    end\n    unless len or f\n      d = File.dirname(files)\n      d.sub!(prefix, \"\") if prefix\n      d = (d.empty? || d == \".\") ? dir : File.join(dir, d)\n      path[d] << files\n    end\n  end\n  dirs\nend\n\ndef install_rb(mfile, dest, srcdir = nil)\n  install_files(mfile, [[\"lib/**/*.rb\", dest, \"lib\"]], nil, srcdir)\nend\n\ndef append_library(libs, lib) # :no-doc:\n  format(LIBARG, lib) + \" \" + libs\nend\n\ndef message(*s)\n  unless Logging.quiet and not $VERBOSE\n    printf(*s)\n    $stdout.flush\n  end\nend\n\n# This emits a string to stdout that allows users to see the results of the\n# various have* and find* methods as they are tested.\n#\n# Internal use only.\n#\ndef checking_for(m, fmt = nil)\n  f = caller[0][/in `(.*)'$/, 1] and f << \": \" #` for vim\n  m = \"checking #{/\\Acheck/ =~ f ? '' : 'for '}#{m}... \"\n  message \"%s\", m\n  a = r = nil\n  Logging::postpone do\n    r = yield\n    a = (fmt ? fmt % r : r ? \"yes\" : \"no\") << \"\\n\"\n    \"#{f}#{m}-------------------- #{a}\\n\"\n  end\n  message(a)\n  Logging::message \"--------------------\\n\\n\"\n  r\nend\n\ndef checking_message(target, place = nil, opt = nil)\n  [[\"in\", place], [\"with\", opt]].inject(\"#{target}\") do |msg, (pre, noun)|\n    if noun\n      [[:to_str], [:join, \",\"], [:to_s]].each do |meth, *args|\n        if noun.respond_to?(meth)\n          break noun = noun.send(meth, *args)\n        end\n      end\n      msg << \" #{pre} #{noun}\" unless noun.empty?\n    end\n    msg\n  end\nend\n\n# :startdoc:\n\n# Returns whether or not +macro+ is defined either in the common header\n# files or within any +headers+ you provide.\n#\n# Any options you pass to +opt+ are passed along to the compiler.\n#\ndef have_macro(macro, headers = nil, opt = \"\", &b)\n  checking_for checking_message(macro, headers, opt) do\n    macro_defined?(macro, cpp_include(headers), opt, &b)\n  end\nend\n\n# Returns whether or not the given entry point +func+ can be found within\n# +lib+.  If +func+ is nil, the 'main()' entry point is used by default.\n# If found, it adds the library to list of libraries to be used when linking\n# your extension.\n#\n# If +headers+ are provided, it will include those header files as the\n# header files it looks in when searching for +func+.\n#\n# The real name of the library to be linked can be altered by\n# '--with-FOOlib' configuration option.\n#\ndef have_library(lib, func = nil, headers = nil, &b)\n  func = \"main\" if !func or func.empty?\n  lib = with_config(lib+'lib', lib)\n  checking_for checking_message(\"#{func}()\", LIBARG%lib) do\n    if COMMON_LIBS.include?(lib)\n      true\n    else\n      libs = append_library($libs, lib)\n      if try_func(func, libs, headers, &b)\n        $libs = libs\n        true\n      else\n        false\n      end\n    end\n  end\nend\n\n# Returns whether or not the entry point +func+ can be found within the library\n# +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.\n# If +func+ is nil , then the main() function is used as the entry point.\n#\n# If +lib+ is found, then the path it was found on is added to the list of\n# library paths searched and linked against.\n#\ndef find_library(lib, func, *paths, &b)\n  func = \"main\" if !func or func.empty?\n  lib = with_config(lib+'lib', lib)\n  paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten\n  checking_for \"#{func}() in #{LIBARG%lib}\" do\n    libpath = $LIBPATH\n    libs = append_library($libs, lib)\n    begin\n      until r = try_func(func, libs, &b) or paths.empty?\n\t$LIBPATH = libpath | [paths.shift]\n      end\n      if r\n\t$libs = libs\n\tlibpath = nil\n      end\n    ensure\n      $LIBPATH = libpath if libpath\n    end\n    r\n  end\nend\n\n# Returns whether or not the function +func+ can be found in the common\n# header files, or within any +headers+ that you provide.  If found, a\n# macro is passed as a preprocessor constant to the compiler using the\n# function name, in uppercase, prepended with 'HAVE_'.\n#\n# For example, if have_func('foo') returned true, then the HAVE_FOO\n# preprocessor macro would be passed to the compiler.\n#\ndef have_func(func, headers = nil, &b)\n  checking_for checking_message(\"#{func}()\", headers) do\n    if try_func(func, $libs, headers, &b)\n      $defs.push(format(\"-DHAVE_%s\", func.tr_cpp))\n      true\n    else\n      false\n    end\n  end\nend\n\n# Returns whether or not the variable +var+ can be found in the common\n# header files, or within any +headers+ that you provide.  If found, a\n# macro is passed as a preprocessor constant to the compiler using the\n# variable name, in uppercase, prepended with 'HAVE_'.\n#\n# For example, if have_var('foo') returned true, then the HAVE_FOO\n# preprocessor macro would be passed to the compiler.\n#\ndef have_var(var, headers = nil, &b)\n  checking_for checking_message(var, headers) do\n    if try_var(var, headers, &b)\n      $defs.push(format(\"-DHAVE_%s\", var.tr_cpp))\n      true\n    else\n      false\n    end\n  end\nend\n\n# Returns whether or not the given +header+ file can be found on your system.\n# If found, a macro is passed as a preprocessor constant to the compiler using\n# the header file name, in uppercase, prepended with 'HAVE_'.\n#\n# For example, if have_header('foo.h') returned true, then the HAVE_FOO_H\n# preprocessor macro would be passed to the compiler.\n#\ndef have_header(header, &b)\n  checking_for header do\n    if try_cpp(cpp_include(header), &b)\n      $defs.push(format(\"-DHAVE_%s\", header.tr(\"a-z./\\055\", \"A-Z___\")))\n      true\n    else\n      false\n    end\n  end\nend\n\n# Instructs mkmf to search for the given +header+ in any of the +paths+\n# provided, and returns whether or not it was found in those paths.\n#\n# If the header is found then the path it was found on is added to the list\n# of included directories that are sent to the compiler (via the -I switch).\n#\ndef find_header(header, *paths)\n  message = checking_message(header, paths)\n  header = cpp_include(header)\n  checking_for message do\n    if try_cpp(header)\n      true\n    else\n      found = false\n      paths.each do |dir|\n        opt = \"-I#{dir}\".quote\n        if try_cpp(header, opt)\n          $INCFLAGS << \" \" << opt\n          found = true\n          break\n        end\n      end\n      found\n    end\n  end\nend\n\n# Returns whether or not the struct of type +type+ contains +member+.  If\n# it does not, or the struct type can't be found, then false is returned.  You\n# may optionally specify additional +headers+ in which to look for the struct\n# (in addition to the common header files).\n#\n# If found, a macro is passed as a preprocessor constant to the compiler using\n# the member name, in uppercase, prepended with 'HAVE_ST_'.\n#\n# For example, if have_struct_member('struct foo', 'bar') returned true, then the\n# HAVE_ST_BAR preprocessor macro would be passed to the compiler.\n# \ndef have_struct_member(type, member, headers = nil, &b)\n  checking_for checking_message(\"#{type}.#{member}\", headers) do\n    if try_compile(<<\"SRC\", &b)\n#{COMMON_HEADERS}\n#{cpp_include(headers)}\n/*top*/\nint main() { return 0; }\nint s = (char *)&((#{type}*)0)->#{member} - (char *)0;\nSRC\n      $defs.push(format(\"-DHAVE_ST_%s\", member.tr_cpp))\n      true\n    else\n      false\n    end\n  end\nend\n\ndef try_type(type, headers = nil, opt = \"\", &b)\n  if try_compile(<<\"SRC\", opt, &b)\n#{COMMON_HEADERS}\n#{cpp_include(headers)}\n/*top*/\ntypedef #{type} conftest_type;\nint conftestval[sizeof(conftest_type)?1:-1];\nSRC\n    $defs.push(format(\"-DHAVE_TYPE_%s\", type.tr_cpp))\n    true\n  else\n    false\n  end\nend\n\n# Returns whether or not the static type +type+ is defined.  You may\n# optionally pass additional +headers+ to check against in addition to the\n# common header files.\n#\n# You may also pass additional flags to +opt+ which are then passed along to\n# the compiler.\n#\n# If found, a macro is passed as a preprocessor constant to the compiler using\n# the type name, in uppercase, prepended with 'HAVE_TYPE_'.\n#\n# For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO\n# preprocessor macro would be passed to the compiler.\n#\ndef have_type(type, headers = nil, opt = \"\", &b)\n  checking_for checking_message(type, headers, opt) do\n    try_type(type, headers, opt, &b)\n  end\nend\n\n# Returns where the static type +type+ is defined.\n#\n# You may also pass additional flags to +opt+ which are then passed along to\n# the compiler.\n#\n# See also +have_type+.\n#\ndef find_type(type, opt, *headers, &b)\n  opt ||= \"\"\n  fmt = \"not found\"\n  def fmt.%(x)\n    x ? x.respond_to?(:join) ? x.join(\",\") : x : self\n  end\n  checking_for checking_message(type, nil, opt), fmt do\n    headers.find do |h|\n      try_type(type, h, opt, &b)\n    end\n  end\nend\n\ndef try_const(const, headers = nil, opt = \"\", &b)\n  const, type = *const\n  if try_compile(<<\"SRC\", opt, &b)\n#{COMMON_HEADERS}\n#{cpp_include(headers)}\n/*top*/\ntypedef #{type || 'int'} conftest_type;\nconftest_type conftestval = #{type ? '' : '(int)'}#{const};\nSRC\n    $defs.push(format(\"-DHAVE_CONST_%s\", const.tr_cpp))\n    true\n  else\n    false\n  end\nend\n\n# Returns whether or not the constant +const+ is defined.  You may\n# optionally pass the +type+ of +const+ as <code>[const, type]</code>,\n# like as:\n#\n#   have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], \"pthread.h\")\n#\n# You may also pass additional +headers+ to check against in addition\n# to the common header files, and additional flags to +opt+ which are\n# then passed along to the compiler.\n#\n# If found, a macro is passed as a preprocessor constant to the compiler using\n# the type name, in uppercase, prepended with 'HAVE_CONST_'.\n#\n# For example, if have_const('foo') returned true, then the HAVE_CONST_FOO\n# preprocessor macro would be passed to the compiler.\n#\ndef have_const(const, headers = nil, opt = \"\", &b)\n  checking_for checking_message([*const].compact.join(' '), headers, opt) do\n    try_const(const, headers, opt, &b)\n  end\nend\n\n# Returns the size of the given +type+.  You may optionally specify additional\n# +headers+ to search in for the +type+.\n#\n# If found, a macro is passed as a preprocessor constant to the compiler using\n# the type name, in uppercase, prepended with 'SIZEOF_', followed by the type\n# name, followed by '=X' where 'X' is the actual size.\n#\n# For example, if check_sizeof('mystruct') returned 12, then the\n# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.\n#\ndef check_sizeof(type, headers = nil, &b)\n  expr = \"sizeof(#{type})\"\n  fmt = \"%d\"\n  def fmt.%(x)\n    x ? super : \"failed\"\n  end\n  checking_for checking_message(\"size of #{type}\", headers), fmt do\n    if size = try_constant(expr, headers, &b)\n      $defs.push(format(\"-DSIZEOF_%s=%d\", type.tr_cpp, size))\n      size\n    end\n  end\nend\n\n# :stopdoc:\n\n# Used internally by the what_type? method to determine if +type+ is a scalar\n# pointer.\ndef scalar_ptr_type?(type, member = nil, headers = nil, &b)\n  try_compile(<<\"SRC\", &b)   # pointer\n#{COMMON_HEADERS}\n#{cpp_include(headers)}\n/*top*/\nvolatile #{type} conftestval;\nint main() { return 0; }\nint t() {return (int)(1-*(conftestval#{member ? \".#{member}\" : \"\"}));}\nSRC\nend\n\n# Used internally by the what_type? method to determine if +type+ is a scalar\n# pointer.\ndef scalar_type?(type, member = nil, headers = nil, &b)\n  try_compile(<<\"SRC\", &b)   # pointer\n#{COMMON_HEADERS}\n#{cpp_include(headers)}\n/*top*/\nvolatile #{type} conftestval;\nint main() { return 0; }\nint t() {return (int)(1-(conftestval#{member ? \".#{member}\" : \"\"}));}\nSRC\nend\n\ndef what_type?(type, member = nil, headers = nil, &b)\n  m = \"#{type}\"\n  name = type\n  if member\n    m << \".\" << member\n    name = \"(((#{type} *)0)->#{member})\"\n  end\n  fmt = \"seems %s\"\n  def fmt.%(x)\n    x ? super : \"unknown\"\n  end\n  checking_for checking_message(m, headers), fmt do\n    if scalar_ptr_type?(type, member, headers, &b)\n      if try_static_assert(\"sizeof(*#{name}) == 1\", headers)\n        \"string\"\n      end\n    elsif scalar_type?(type, member, headers, &b)\n      if try_static_assert(\"sizeof(#{name}) > sizeof(long)\", headers)\n        \"long long\"\n      elsif try_static_assert(\"sizeof(#{name}) > sizeof(int)\", headers)\n        \"long\"\n      elsif try_static_assert(\"sizeof(#{name}) > sizeof(short)\", headers)\n        \"int\"\n      elsif try_static_assert(\"sizeof(#{name}) > 1\", headers)\n        \"short\"\n      else\n        \"char\"\n      end\n    end\n  end\nend\n\n# This method is used internally by the find_executable method.\n#\n# Internal use only.\n#\ndef find_executable0(bin, path = nil)\n  ext = config_string('EXEEXT')\n  if File.expand_path(bin) == bin\n    return bin if File.executable?(bin)\n    ext and File.executable?(file = bin + ext) and return file\n    return nil\n  end\n  if path ||= ENV['PATH']\n    path = path.split(File::PATH_SEPARATOR)\n  else\n    path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]\n  end\n  file = nil\n  path.each do |dir|\n    return file if File.executable?(file = File.join(dir, bin))\n    return file if ext and File.executable?(file << ext)\n  end\n  nil\nend\n\n# :startdoc:\n\n# Searches for the executable +bin+ on +path+. The default path is your\n# PATH environment variable. If that isn't defined, it will resort to\n# searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.\n#\n# If found, it will return the full path, including the executable name,\n# of where it was found.\n#\n# Note that this method does not actually affect the generated Makefile.\n#\ndef find_executable(bin, path = nil)\n  checking_for checking_message(bin, path) do\n    find_executable0(bin, path)\n  end\nend\n\n# :stopdoc:\n\ndef arg_config(config, *defaults, &block)\n  $arg_config << [config, *defaults]\n  defaults << nil if !block and defaults.empty?\n  $configure_args.fetch(config.tr('_', '-'), *defaults, &block)\nend\n\n# :startdoc:\n\n# Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>\n# option. Returns true if the with option is given, false if the without\n# option is given, and the default value otherwise.\n#\n# This can be useful for adding custom definitions, such as debug information.\n#\n# Example:\n#\n#    if with_config(\"debug\")\n#       $defs.push(\"-DOSSL_DEBUG\") unless $defs.include? \"-DOSSL_DEBUG\"\n#    end\n#\ndef with_config(config, *defaults)\n  config = config.sub(/^--with[-_]/, '')\n  val = arg_config(\"--with-\"+config) do\n    if arg_config(\"--without-\"+config)\n      false\n    elsif block_given?\n      yield(config, *defaults)\n    else\n      break *defaults\n    end\n  end\n  case val\n  when \"yes\"\n    true\n  when \"no\"\n    false\n  else\n    val\n  end\nend\n\n# Tests for the presence of an --enable-<tt>config</tt> or\n# --disable-<tt>config</tt> option. Returns true if the enable option is given,\n# false if the disable option is given, and the default value otherwise.\n#\n# This can be useful for adding custom definitions, such as debug information.\n#\n# Example:\n#\n#    if enable_config(\"debug\")\n#       $defs.push(\"-DOSSL_DEBUG\") unless $defs.include? \"-DOSSL_DEBUG\"\n#    end\n#\ndef enable_config(config, *defaults)\n  if arg_config(\"--enable-\"+config)\n    true\n  elsif arg_config(\"--disable-\"+config)\n    false\n  elsif block_given?\n    yield(config, *defaults)\n  else\n    return *defaults\n  end\nend\n\n# Generates a header file consisting of the various macro definitions generated\n# by other methods such as have_func and have_header. These are then wrapped in\n# a custom #ifndef based on the +header+ file name, which defaults to\n# 'extconf.h'.\n#\n# For example:\n# \n#    # extconf.rb\n#    require 'mkmf'\n#    have_func('realpath')\n#    have_header('sys/utime.h')\n#    create_header\n#    create_makefile('foo')\n#\n# The above script would generate the following extconf.h file:\n#\n#    #ifndef EXTCONF_H\n#    #define EXTCONF_H\n#    #define HAVE_REALPATH 1\n#    #define HAVE_SYS_UTIME_H 1\n#    #endif\n#\n# Given that the create_header method generates a file based on definitions\n# set earlier in your extconf.rb file, you will probably want to make this\n# one of the last methods you call in your script.\n#\ndef create_header(header = \"extconf.h\")\n  message \"creating %s\\n\", header\n  sym = header.tr(\"a-z./\\055\", \"A-Z___\")\n  hdr = [\"#ifndef #{sym}\\n#define #{sym}\\n\"]\n  for line in $defs\n    case line\n    when /^-D([^=]+)(?:=(.*))?/\n      hdr << \"#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\\n\"\n    when /^-U(.*)/\n      hdr << \"#undef #$1\\n\"\n    end\n  end\n  hdr << \"#endif\\n\"\n  hdr = hdr.join\n  unless (IO.read(header) == hdr rescue false)\n    open(header, \"w\") do |hfile|\n      hfile.write(hdr)\n    end\n  end\n  $extconf_h = header\nend\n\n# Sets a +target+ name that the user can then use to configure various 'with'\n# options with on the command line by using that name.  For example, if the\n# target is set to \"foo\", then the user could use the --with-foo-dir command\n# line option.\n#\n# You may pass along additional 'include' or 'lib' defaults via the +idefault+\n# and +ldefault+ parameters, respectively.\n#\n# Note that dir_config only adds to the list of places to search for libraries\n# and include files.  It does not link the libraries into your application.\n#\ndef dir_config(target, idefault=nil, ldefault=nil)\n  if dir = with_config(target + \"-dir\", (idefault unless ldefault))\n    defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)\n    idefault = ldefault = nil\n  end\n\n  idir = with_config(target + \"-include\", idefault)\n  $arg_config.last[1] ||= \"${#{target}-dir}/include\"\n  ldir = with_config(target + \"-lib\", ldefault)\n  $arg_config.last[1] ||= \"${#{target}-dir}/lib\"\n\n  idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []\n  if defaults\n    idirs.concat(defaults.collect {|dir| dir + \"/include\"})\n    idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)\n  end\n  unless idirs.empty?\n    idirs.collect! {|dir| \"-I\" + dir}\n    idirs -= Shellwords.shellwords($CPPFLAGS)\n    unless idirs.empty?\n      $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(\" \")\n    end\n  end\n\n  ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []\n  if defaults\n    ldirs.concat(defaults.collect {|dir| dir + \"/lib\"})\n    ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)\n  end\n  $LIBPATH = ldirs | $LIBPATH\n\n  [idir, ldir]\nend\n\n# :stopdoc:\n\n# Handles meta information about installed libraries. Uses your platform's\n# pkg-config program if it has one.\ndef pkg_config(pkg)\n  if pkgconfig = with_config(\"#{pkg}-config\") and find_executable0(pkgconfig)\n    # iff package specific config command is given\n    get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}\n  elsif ($PKGCONFIG ||= \n         (pkgconfig = with_config(\"pkg-config\", (\"pkg-config\" unless CROSS_COMPILING))) &&\n         find_executable0(pkgconfig) && pkgconfig) and\n      system(\"#{$PKGCONFIG} --exists #{pkg}\")\n    # default to pkg-config command\n    get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}\n  elsif find_executable0(pkgconfig = \"#{pkg}-config\")\n    # default to package specific config command, as a last resort.\n    get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}\n  end\n  if get\n    cflags = get['cflags']\n    ldflags = get['libs']\n    libs = get['libs-only-l']\n    ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(\" \")\n    $CFLAGS += \" \" << cflags\n    $LDFLAGS += \" \" << ldflags\n    $libs += \" \" << libs\n    Logging::message \"package configuration for %s\\n\", pkg\n    Logging::message \"cflags: %s\\nldflags: %s\\nlibs: %s\\n\\n\",\n                     cflags, ldflags, libs\n    [cflags, ldflags, libs]\n  else\n    Logging::message \"package configuration for %s is not found\\n\", pkg\n    nil\n  end\nend\n\ndef with_destdir(dir)\n  dir = dir.sub($dest_prefix_pattern, '')\n  /\\A\\$[\\(\\{]/ =~ dir ? dir : \"$(DESTDIR)\"+dir\nend\n\n# Converts forward slashes to backslashes. Aimed at MS Windows.\n#\n# Internal use only.\n#\ndef winsep(s)\n  s.tr('/', '\\\\')\nend\n\n# Converts native path to format acceptable in Makefile\n#\n# Internal use only.\n#\nif !CROSS_COMPILING\n  case CONFIG['build_os']\n  when 'mingw32'\n    def mkintpath(path)\n      # mingw uses make from msys and it needs special care\n      # converts from C:\\some\\path to /C/some/path\n      path = path.dup\n      path.tr!('\\\\', '/')\n      path.sub!(/\\A([A-Za-z]):(?=\\/)/, '/\\1')\n      path\n    end\n  end\nend\nunless defined?(mkintpath)\n  def mkintpath(path)\n    path\n  end\nend\n\ndef configuration(srcdir)\n  mk = []\n  vpath = %w[$(srcdir) $(topdir) $(hdrdir)]\n  if !CROSS_COMPILING\n    case CONFIG['build_os']\n    when 'cygwin'\n      if CONFIG['target_os'] != 'cygwin'\n        vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \\&)')}\n      end\n    when 'msdosdjgpp'\n      CONFIG['PATH_SEPARATOR'] = ';'\n    end\n  end\n  mk << %{\nSHELL = /bin/sh\n\n#### Start of system configuration section. ####\n#{\nif $extmk\n  \"top_srcdir = \" + $top_srcdir.sub(%r\"\\A#{Regexp.quote($topdir)}/\", \"$(topdir)/\")\nend\n}\nsrcdir = #{srcdir.gsub(/\\$\\((srcdir)\\)|\\$\\{(srcdir)\\}/) {mkintpath(CONFIG[$1||$2])}.quote}\ntopdir = #{mkintpath($extmk ? CONFIG[\"topdir\"] : $topdir).quote}\nhdrdir = #{$extmk ? mkintpath(CONFIG[\"hdrdir\"]).quote : '$(topdir)'}\nVPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}\n}\n  if $extmk\n    mk << \"RUBYLIB = -\\nRUBYOPT = -rpurelib.rb\\n\"\n  end\n  if destdir = CONFIG[\"prefix\"][$dest_prefix_pattern, 1]\n    mk << \"\\nDESTDIR = #{destdir}\\n\"\n  end\n  CONFIG.each do |key, var|\n    next unless /prefix$/ =~ key\n    mk << \"#{key} = #{with_destdir(var)}\\n\"\n  end\n  CONFIG.each do |key, var|\n    next if /^abs_/ =~ key\n    next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1\n    mk << \"#{key} = #{with_destdir(var)}\\n\"\n  end\n  if !$extmk and !$configure_args.has_key?('--ruby') and\n      sep = config_string('BUILD_FILE_SEPARATOR')\n    sep = \":/=#{sep}\"\n  else\n    sep = \"\"\n  end\n  extconf_h = $extconf_h ? \"-DRUBY_EXTCONF_H=\\\\\\\"$(RUBY_EXTCONF_H)\\\\\\\" \" : $defs.join(\" \")<<\" \"\n  mk << %{\nCC = #{CONFIG['CC']}\nLIBRUBY = #{CONFIG['LIBRUBY']}\nLIBRUBY_A = #{CONFIG['LIBRUBY_A']}\nLIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED\nLIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC\n\nRUBY_EXTCONF_H = #{$extconf_h}\nCFLAGS   = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG\nINCFLAGS = -I. #$INCFLAGS\nDEFS     = #{CONFIG['DEFS']}\nCPPFLAGS = #{extconf_h}#{$CPPFLAGS}\nCXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}\nldflags  = #{$LDFLAGS}\ndldflags = #{$DLDFLAGS}\narchflag = #{$ARCH_FLAG}\nDLDFLAGS = $(ldflags) $(dldflags) $(archflag)\nLDSHARED = #{CONFIG['LDSHARED']}\nAR = #{CONFIG['AR']}\nEXEEXT = #{CONFIG['EXEEXT']}\n\nRUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}\nRUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}\narch = #{CONFIG['arch']}\nsitearch = #{CONFIG['sitearch']}\nruby_version = #{Config::CONFIG['ruby_version']}\nruby = #{$ruby}\nRUBY = $(ruby#{sep})\nRM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}\nMAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}\nINSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}\nINSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}\nINSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}\nCOPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}\n\n#### End of system configuration section. ####\n\npreload = #{$preload ? $preload.join(' ') : ''}\n}\n  if $nmake == ?b\n    mk.each do |x|\n      x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\\s*=.*\\n/) do\n        \"!ifndef \" + $1 + \"\\n\" +\n        $& +\n\t\"!endif\\n\"\n      end\n    end\n  end\n  mk\nend\n\ndef dummy_makefile(srcdir)\n  configuration(srcdir) << <<RULES << CLEANINGS\nCLEANFILES = #{$cleanfiles.join(' ')}\nDISTCLEANFILES = #{$distcleanfiles.join(' ')}\n\nall install static install-so install-rb: Makefile\n\nRULES\nend\n# :startdoc:\n\n# Generates the Makefile for your extension, passing along any options and\n# preprocessor constants that you may have generated through other methods.\n#\n# The +target+ name should correspond the name of the global function name\n# defined within your C extension, minus the 'Init_'.  For example, if your\n# C extension is defined as 'Init_foo', then your target would simply be 'foo'.\n#\n# If any '/' characters are present in the target name, only the last name\n# is interpreted as the target name, and the rest are considered toplevel\n# directory names, and the generated Makefile will be altered accordingly to\n# follow that directory structure.\n#\n# For example, if you pass 'test/foo' as a target name, your extension will\n# be installed under the 'test' directory.  This means that in order to\n# load the file within a Ruby program later, that directory structure will\n# have to be followed, e.g. \"require 'test/foo'\".\n#\n# The +srcprefix+ should be used when your source files are not in the same\n# directory as your build script. This will not only eliminate the need for\n# you to manually copy the source files into the same directory as your build\n# script, but it also sets the proper +target_prefix+ in the generated\n# Makefile.\n#\n# Setting the +target_prefix+ will, in turn, install the generated binary in\n# a directory under your Config::CONFIG['sitearchdir'] that mimics your local\n# filesystem when you run 'make install'.\n#\n# For example, given the following file tree:\n#\n#    ext/\n#       extconf.rb\n#       test/\n#          foo.c\n#\n# And given the following code:\n#\n#    create_makefile('test/foo', 'test')\n#\n# That will set the +target_prefix+ in the generated Makefile to 'test'. That,\n# in turn, will create the following file tree when installed via the\n# 'make install' command:\n#\n#    /path/to/ruby/sitearchdir/test/foo.so\n#\n# It is recommended that you use this approach to generate your makefiles,\n# instead of copying files around manually, because some third party\n# libraries may depend on the +target_prefix+ being set properly.\n#\n# The +srcprefix+ argument can be used to override the default source\n# directory, i.e. the current directory . It is included as part of the VPATH\n# and added to the list of INCFLAGS.\n#\ndef create_makefile(target, srcprefix = nil)\n  $target = target\n  libpath = $DEFLIBPATH|$LIBPATH\n  message \"creating Makefile\\n\"\n  rm_f \"conftest*\"\n  if CONFIG[\"DLEXT\"] == $OBJEXT\n    for lib in libs = $libs.split\n      lib.sub!(/-l(.*)/, %%\"lib\\\\1.#{$LIBEXT}\"%)\n    end\n    $defs.push(format(\"-DEXTLIB='%s'\", libs.join(\",\")))\n  end\n\n  if target.include?('/')\n    target_prefix, target = File.split(target)\n    target_prefix[0,0] = '/'\n  else\n    target_prefix = \"\"\n  end\n\n  srcprefix ||= '$(srcdir)'\n  Config::expand(srcdir = srcprefix.dup)\n\n  if not $objs\n    $objs = []\n    srcs = Dir[File.join(srcdir, \"*.{#{SRC_EXT.join(%q{,})}}\")]\n    for f in srcs\n      obj = File.basename(f, \".*\") << \".o\"\n      $objs.push(obj) unless $objs.index(obj)\n    end\n  elsif !(srcs = $srcs)\n    srcs = $objs.collect {|obj| obj.sub(/\\.o\\z/, '.c')}\n  end\n  $srcs = srcs\n  for i in $objs\n    i.sub!(/\\.o\\z/, \".#{$OBJEXT}\")\n  end\n  $objs = $objs.join(\" \")\n\n  target = nil if $objs == \"\"\n\n  if target and EXPORT_PREFIX\n    if File.exist?(File.join(srcdir, target + '.def'))\n      deffile = \"$(srcdir)/$(TARGET).def\"\n      unless EXPORT_PREFIX.empty?\n        makedef = %{-pe \"sub!(/^(?=\\\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i\"}\n      end\n    else\n      makedef = %{-e \"puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'\"}\n    end\n    if makedef\n      $distcleanfiles << '$(DEFFILE)'\n      origdef = deffile\n      deffile = \"$(TARGET)-$(arch).def\"\n    end\n  end\n  origdef ||= ''\n\n  libpath = libpathflag(libpath)\n\n  dllib = target ? \"$(TARGET).#{CONFIG['DLEXT']}\" : \"\"\n  staticlib = target ? \"$(TARGET).#$LIBEXT\" : \"\"\n  mfile = open(\"Makefile\", \"wb\")\n  mfile.print configuration(srcprefix)\n  mfile.print \"\nlibpath = #{($DEFLIBPATH|$LIBPATH).join(\" \")}\nLIBPATH = #{libpath}\nDEFFILE = #{deffile}\n\nCLEANFILES = #{$cleanfiles.join(' ')}\nDISTCLEANFILES = #{$distcleanfiles.join(' ')}\n\nextout = #{$extout}\nextout_prefix = #{$extout_prefix}\ntarget_prefix = #{target_prefix}\nLOCAL_LIBS = #{$LOCAL_LIBS}\nLIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}\nSRCS = #{srcs.collect(&File.method(:basename)).join(' ')}\nOBJS = #{$objs}\nTARGET = #{target}\nDLLIB = #{dllib}\nEXTSTATIC = #{$static || \"\"}\nSTATIC_LIB = #{staticlib unless $static.nil?}\n#{!$extout && defined?($installed_list) ? \"INSTALLED_LIST = #{$installed_list}\\n\" : \"\"}\n\"\n  install_dirs.each {|d| mfile.print(\"%-14s= %s\\n\" % d) if /^[[:upper:]]/ =~ d[0]}\n  n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'\n  mfile.print \"\nTARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)\nCLEANLIBS     = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map\nCLEANOBJS     = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak\n\nall:\t\t#{$extout ? \"install\" : target ? \"$(DLLIB)\" : \"Makefile\"}\nstatic:\t\t$(STATIC_LIB)#{$extout ? \" install-rb\" : \"\"}\n\"\n  mfile.print CLEANINGS\n  dirs = []\n  mfile.print \"install: install-so install-rb\\n\\n\"\n  sodir = (dir = \"$(RUBYARCHDIR)\").dup\n  mfile.print(\"install-so: \")\n  if target\n    f = \"$(DLLIB)\"\n    dest = \"#{dir}/#{f}\"\n    mfile.puts dir, \"install-so: #{dest}\"\n    unless $extout\n      mfile.print \"#{dest}: #{f}\\n\"\n      if (sep = config_string('BUILD_FILE_SEPARATOR'))\n        f.gsub!(\"/\", sep)\n        dir.gsub!(\"/\", sep)\n        sep = \":/=\"+sep\n        f.gsub!(/(\\$\\(\\w+)(\\))/) {$1+sep+$2}\n        f.gsub!(/(\\$\\{\\w+)(\\})/) {$1+sep+$2}\n        dir.gsub!(/(\\$\\(\\w+)(\\))/) {$1+sep+$2}\n        dir.gsub!(/(\\$\\{\\w+)(\\})/) {$1+sep+$2}\n      end\n      mfile.print \"\\t$(INSTALL_PROG) #{f} #{dir}\\n\"\n      if defined?($installed_list)\n\tmfile.print \"\\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\\n\"\n      end\n    end\n  else\n    mfile.puts \"Makefile\"\n  end\n  mfile.print(\"install-rb: pre-install-rb install-rb-default\\n\")\n  mfile.print(\"install-rb-default: pre-install-rb-default\\n\")\n  mfile.print(\"pre-install-rb: Makefile\\n\")\n  mfile.print(\"pre-install-rb-default: Makefile\\n\")\n  for sfx, i in [[\"-default\", [[\"lib/**/*.rb\", \"$(RUBYLIBDIR)\", \"lib\"]]], [\"\", $INSTALLFILES]]\n    files = install_files(mfile, i, nil, srcprefix) or next\n    for dir, *files in files\n      unless dirs.include?(dir)\n\tdirs << dir\n\tmfile.print \"pre-install-rb#{sfx}: #{dir}\\n\"\n      end\n      files.each do |f|\n\tdest = \"#{dir}/#{File.basename(f)}\"\n\tmfile.print(\"install-rb#{sfx}: #{dest}\\n\")\n\tmfile.print(\"#{dest}: #{f} #{dir}\\n\\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) \")\n\tsep = config_string('BUILD_FILE_SEPARATOR')\n\tif sep\n\t  f = f.gsub(\"/\", sep)\n\t  sep = \":/=\"+sep\n\t  f = f.gsub(/(\\$\\(\\w+)(\\))/) {$1+sep+$2}\n\t  f = f.gsub(/(\\$\\{\\w+)(\\})/) {$1+sep+$2}\n\telse\n\t  sep = \"\"\n\tend\n\tmfile.print(\"#{f} $(@D#{sep})\\n\")\n\tif defined?($installed_list) and !$extout\n\t  mfile.print(\"\\t@echo #{dest}>>$(INSTALLED_LIST)\\n\")\n\tend\n      end\n    end\n  end\n  dirs.unshift(sodir) if target and !dirs.include?(sodir)\n  dirs.each {|dir| mfile.print \"#{dir}:\\n\\t$(MAKEDIRS) $@\\n\"}\n\n  mfile.print <<-SITEINSTALL\n\nsite-install: site-install-so site-install-rb\nsite-install-so: install-so\nsite-install-rb: install-rb\n\n  SITEINSTALL\n\n  return unless target\n\n  mfile.puts SRC_EXT.collect {|ext| \".path.#{ext} = $(VPATH)\"} if $nmake == ?b\n  mfile.print \".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\\n\"\n  mfile.print \"\\n\"\n\n  CXX_EXT.each do |ext|\n    COMPILE_RULES.each do |rule|\n      mfile.printf(rule, ext, $OBJEXT)\n      mfile.printf(\"\\n\\t%s\\n\\n\", COMPILE_CXX)\n    end\n  end\n  %w[c].each do |ext|\n    COMPILE_RULES.each do |rule|\n      mfile.printf(rule, ext, $OBJEXT)\n      mfile.printf(\"\\n\\t%s\\n\\n\", COMPILE_C)\n    end\n  end\n\n  mfile.print \"$(RUBYARCHDIR)/\" if $extout\n  mfile.print \"$(DLLIB): \"\n  mfile.print \"$(DEFFILE) \" if makedef\n  mfile.print \"$(OBJS) Makefile\\n\"\n  mfile.print \"\\t@-$(RM) $@\\n\"\n  mfile.print \"\\t@-$(MAKEDIRS) $(@D)\\n\" if $extout\n  link_so = LINK_SO.gsub(/^/, \"\\t\")\n  mfile.print link_so, \"\\n\\n\"\n  unless $static.nil?\n    mfile.print \"$(STATIC_LIB): $(OBJS)\\n\\t\"\n    mfile.print \"$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)\"\n    config_string('RANLIB') do |ranlib|\n      mfile.print \"\\n\\t@-#{ranlib} $(DLLIB) 2> /dev/null || true\"\n    end\n  end\n  mfile.print \"\\n\\n\"\n  if makedef\n    mfile.print \"$(DEFFILE): #{origdef}\\n\"\n    mfile.print \"\\t$(RUBY) #{makedef} #{origdef} > $@\\n\\n\"\n  end\n\n  depend = File.join(srcdir, \"depend\")\n  if File.exist?(depend)\n    suffixes = []\n    depout = []\n    open(depend, \"r\") do |dfile|\n      mfile.printf \"###\\n\"\n      cont = implicit = nil\n      impconv = proc do\n\tCOMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}\n\timplicit = nil\n      end\n      ruleconv = proc do |line|\n\tif implicit\n\t  if /\\A\\t/ =~ line\n\t    implicit[1] << line\n\t    next\n\t  else\n\t    impconv[]\n\t  end\n\tend\n\tif m = /\\A\\.(\\w+)\\.(\\w+)(?:\\s*:)/.match(line)\n\t  suffixes << m[1] << m[2]\n\t  implicit = [[m[1], m[2]], [m.post_match]]\n\t  next\n\telsif RULE_SUBST and /\\A(?!\\s*\\w+\\s*=)[$\\w][^#]*:/ =~ line\n\t  line.gsub!(%r\"(\\s)(?!\\.)([^$(){}+=:\\s\\/\\\\,]+)(?=\\s|\\z)\") {$1 + RULE_SUBST % $2}\n\tend\n\tdepout << line\n      end\n      while line = dfile.gets()\n\tline.gsub!(/\\.o\\b/, \".#{$OBJEXT}\")\n\tline.gsub!(/\\$\\((?:hdr|top)dir\\)\\/config.h/, $config_h) if $config_h\n\tif /(?:^|[^\\\\])(?:\\\\\\\\)*\\\\$/ =~ line\n\t  (cont ||= []) << line\n\t  next\n\telsif cont\n\t  line = (cont << line).join\n\t  cont = nil\n\tend\n\truleconv.call(line)\n      end\n      if cont\n\truleconv.call(cont.join)\n      elsif implicit\n\timpconv.call\n      end\n    end\n    unless suffixes.empty?\n      mfile.print \".SUFFIXES: .\", suffixes.uniq.join(\" .\"), \"\\n\\n\"\n    end\n    mfile.print \"$(OBJS): $(RUBY_EXTCONF_H)\\n\\n\" if $extconf_h\n    mfile.print depout\n  else\n    headers = %w[ruby.h defines.h]\n    if RULE_SUBST\n      headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}\n    end\n    headers << $config_h if $config_h\n    headers << \"$(RUBY_EXTCONF_H)\" if $extconf_h\n    mfile.print \"$(OBJS): \", headers.join(' '), \"\\n\"\n  end\n\n  $makefile_created = true\nensure\n  mfile.close if mfile\nend\n\n# :stopdoc:\n\ndef init_mkmf(config = CONFIG)\n  $makefile_created = false\n  $arg_config = []\n  $enable_shared = config['ENABLE_SHARED'] == 'yes'\n  $defs = []\n  $extconf_h = nil\n  $CFLAGS = with_config(\"cflags\", arg_config(\"CFLAGS\", config[\"CFLAGS\"])).dup\n  $ARCH_FLAG = with_config(\"arch_flag\", arg_config(\"ARCH_FLAG\", config[\"ARCH_FLAG\"])).dup\n  $CPPFLAGS = with_config(\"cppflags\", arg_config(\"CPPFLAGS\", config[\"CPPFLAGS\"])).dup\n  $LDFLAGS = with_config(\"ldflags\", arg_config(\"LDFLAGS\", config[\"LDFLAGS\"])).dup\n  $INCFLAGS = \"-I$(topdir) -I$(hdrdir) -I$(srcdir)\"\n  $DLDFLAGS = with_config(\"dldflags\", arg_config(\"DLDFLAGS\", config[\"DLDFLAGS\"])).dup\n  $LIBEXT = config['LIBEXT'].dup\n  $OBJEXT = config[\"OBJEXT\"].dup\n  $LIBS = \"#{config['LIBS']} #{config['DLDLIBS']}\"\n  $LIBRUBYARG = \"\"\n  $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']\n  $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']\n  $DEFLIBPATH = $extmk ? [\"$(topdir)\"] : CROSS_COMPILING ? [] : [\"$(libdir)\"]\n  $DEFLIBPATH.unshift(\".\")\n  $LIBPATH = []\n  $INSTALLFILES = []\n  $NONINSTALLFILES = [/~\\z/, /\\A#.*#\\z/, /\\A\\.#/, /\\.bak\\z/i, /\\.orig\\z/, /\\.rej\\z/, /\\.l[ao]\\z/, /\\.o\\z/]\n\n  $objs = nil\n  $srcs = nil\n  $libs = \"\"\n  if $enable_shared or Config.expand(config[\"LIBRUBY\"].dup) != Config.expand(config[\"LIBRUBY_A\"].dup)\n    $LIBRUBYARG = config['LIBRUBYARG']\n  end\n\n  $LOCAL_LIBS = \"\"\n\n  $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []\n  $cleanfiles << \"mkmf.log\"\n  $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []\n\n  $extout ||= nil\n  $extout_prefix ||= nil\n\n  $arg_config.clear\n  dir_config(\"opt\")\nend\n\nFailedMessage = <<MESSAGE\nCould not create Makefile due to some reason, probably lack of\nnecessary libraries and/or headers.  Check the mkmf.log file for more\ndetails.  You may need configuration options.\n\nProvided configuration options:\nMESSAGE\n\n# Returns whether or not the Makefile was successfully generated. If not,\n# the script will abort with an error message.\n#\n# Internal use only.\n#\ndef mkmf_failed(path)\n  unless $makefile_created or File.exist?(\"Makefile\")\n    opts = $arg_config.collect {|t, n| \"\\t#{t}#{n ? \"=#{n}\" : \"\"}\\n\"}\n    abort \"*** #{path} failed ***\\n\" + FailedMessage + opts.join\n  end\nend\n\n# :startdoc:\n\ninit_mkmf\n\n$make = with_config(\"make-prog\", ENV[\"MAKE\"] || \"make\")\nmake, = Shellwords.shellwords($make)\n$nmake = nil\ncase\nwhen $mswin\n  $nmake = ?m if /nmake/i =~ make\nwhen $bccwin\n  $nmake = ?b if /Borland/i =~ `#{make} -h`\nend\n\nConfig::CONFIG[\"srcdir\"] = CONFIG[\"srcdir\"] =\n  $srcdir = arg_config(\"--srcdir\", File.dirname($0))\n$configure_args[\"--topsrcdir\"] ||= $srcdir\nif $curdir = arg_config(\"--curdir\")\n  Config.expand(curdir = $curdir.dup)\nelse\n  curdir = $curdir = \".\"\nend\nunless File.expand_path(Config::CONFIG[\"topdir\"]) == File.expand_path(curdir)\n  CONFIG[\"topdir\"] = $curdir\n  Config::CONFIG[\"topdir\"] = curdir\nend\n$configure_args[\"--topdir\"] ||= $curdir\n$ruby = arg_config(\"--ruby\", File.join(Config::CONFIG[\"bindir\"], CONFIG[\"ruby_install_name\"]))\n\nsplit = Shellwords.method(:shellwords).to_proc\n\nEXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}\n\nhdr = []\nconfig_string('COMMON_MACROS') do |s|\n  Shellwords.shellwords(s).each do |w|\n    hdr << \"#define \" + w.split(/=/, 2).join(\" \")\n  end\nend\nconfig_string('COMMON_HEADERS') do |s|\n  Shellwords.shellwords(s).each {|s| hdr << \"#include <#{s}>\"}\nend\nCOMMON_HEADERS = hdr.join(\"\\n\")\nCOMMON_LIBS = config_string('COMMON_LIBS', &split) || []\n\nCOMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]\nRULE_SUBST = config_string('RULE_SUBST')\nCOMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<'\nCOMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<'\nTRY_LINK = config_string('TRY_LINK') ||\n  \"$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) \" \\\n  \"$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)\"\nLINK_SO = config_string('LINK_SO') ||\n  if CONFIG[\"DLEXT\"] == $OBJEXT\n    \"ld $(DLDFLAGS) -r -o $@ $(OBJS)\\n\"\n  else\n    \"$(LDSHARED) #{OUTFLAG}$@ $(OBJS) \" \\\n    \"$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)\"\n  end\nLIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L\"%s\"'\nRPATHFLAG = config_string('RPATHFLAG') || ''\nLIBARG = config_string('LIBARG') || '-l%s'\n\nsep = config_string('BUILD_FILE_SEPARATOR') {|sep| \":/=#{sep}\" if sep != \"/\"} || \"\"\nCLEANINGS = \"\nclean:\n\t\t@-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})\n\ndistclean:\tclean\n\t\t@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log\n\t\t@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})\n\nrealclean:\tdistclean\n\"\n\nif not $extmk and /\\A(extconf|makefile).rb\\z/ =~ File.basename($0)\n  END {mkmf_failed($0)}\nend\n"
  },
  {
    "path": "lib/monitor.rb",
    "content": "=begin\n\n= monitor.rb\n\nCopyright (C) 2001  Shugo Maeda <shugo@ruby-lang.org>\n\nThis library is distributed under the terms of the Ruby license.\nYou can freely distribute/modify this library.\n\n== example\n\nThis is a simple example.\n\n  require 'monitor.rb'\n  \n  buf = []\n  buf.extend(MonitorMixin)\n  empty_cond = buf.new_cond\n  \n  # consumer\n  Thread.start do\n    loop do\n      buf.synchronize do\n        empty_cond.wait_while { buf.empty? }\n        print buf.shift\n      end\n    end\n  end\n  \n  # producer\n  while line = ARGF.gets\n    buf.synchronize do\n      buf.push(line)\n      empty_cond.signal\n    end\n  end\n\nThe consumer thread waits for the producer thread to push a line\nto buf while buf.empty?, and the producer thread (main thread)\nreads a line from ARGF and push it to buf, then call\nempty_cond.signal.\n\n=end\n  \n\n#\n# Adds monitor functionality to an arbitrary object by mixing the module with\n# +include+.  For example:\n#\n#    require 'monitor.rb'\n#    \n#    buf = []\n#    buf.extend(MonitorMixin)\n#    empty_cond = buf.new_cond\n#    \n#    # consumer\n#    Thread.start do\n#      loop do\n#        buf.synchronize do\n#          empty_cond.wait_while { buf.empty? }\n#          print buf.shift\n#        end\n#      end\n#    end\n#    \n#    # producer\n#    while line = ARGF.gets\n#      buf.synchronize do\n#        buf.push(line)\n#        empty_cond.signal\n#      end\n#    end\n# \n# The consumer thread waits for the producer thread to push a line\n# to buf while buf.empty?, and the producer thread (main thread)\n# reads a line from ARGF and push it to buf, then call\n# empty_cond.signal.\n#\nmodule MonitorMixin\n  #\n  # FIXME: This isn't documented in Nutshell.\n  #\n  # Since MonitorMixin.new_cond returns a ConditionVariable, and the example\n  # above calls while_wait and signal, this class should be documented.\n  #\n  class ConditionVariable\n    class Timeout < Exception; end\n    \n    # Create a new timer with the argument timeout, and add the\n    # current thread to the list of waiters.  Then the thread is\n    # stopped.  It will be resumed when a corresponding #signal \n    # occurs.\n    def wait(timeout = nil)\n      @monitor.instance_eval {mon_check_owner()}\n      timer = create_timer(timeout)\n      \n      Thread.critical = true\n      count = @monitor.instance_eval {mon_exit_for_cond()}\n      @waiters.push(Thread.current)\n\n      begin\n\tThread.stop\n        return true\n      rescue Timeout\n        return false\n      ensure\n\tThread.critical = true\n\tbegin\n\t  if timer && timer.alive?\n\t    Thread.kill(timer)\n\t  end\n\t  if @waiters.include?(Thread.current)  # interrupted?\n\t    @waiters.delete(Thread.current)\n\t  end\n\t  @monitor.instance_eval {mon_enter_for_cond(count)}\n\tensure\n\t  Thread.critical = false\n\tend\n      end\n    end\n    \n\n    # call #wait while the supplied block returns +true+.\n    def wait_while\n      while yield\n\twait\n      end\n    end\n    \n    # call #wait until the supplied block returns +true+.\n    def wait_until\n      until yield\n\twait\n      end\n    end\n    \n    # Wake up and run the next waiter\n    def signal\n      @monitor.instance_eval {mon_check_owner()}\n      Thread.critical = true\n      t = @waiters.shift\n      t.wakeup if t\n      Thread.critical = false\n      Thread.pass\n    end\n    \n    # Wake up all the waiters.\n    def broadcast\n      @monitor.instance_eval {mon_check_owner()}\n      Thread.critical = true\n      for t in @waiters\n\tt.wakeup\n      end\n      @waiters.clear\n      Thread.critical = false\n      Thread.pass\n    end\n    \n    def count_waiters\n      return @waiters.length\n    end\n    \n    private\n\n    def initialize(monitor)\n      @monitor = monitor\n      @waiters = []\n    end\n\n    def create_timer(timeout)\n      if timeout\n\twaiter = Thread.current\n\treturn Thread.start {\n\t  Thread.pass\n\t  sleep(timeout)\n\t  Thread.critical = true\n\t  waiter.raise(Timeout.new)\n\t}\n      else\n        return nil\n      end\n    end\n  end\n  \n  def self.extend_object(obj)\n    super(obj)\n    obj.instance_eval {mon_initialize()}\n  end\n  \n  #\n  # Attempts to enter exclusive section.  Returns +false+ if lock fails.\n  #\n  def mon_try_enter\n    result = false\n    Thread.critical = true\n    if @mon_owner.nil?\n      @mon_owner = Thread.current\n    end\n    if @mon_owner == Thread.current\n      @mon_count += 1\n      result = true\n    end\n    Thread.critical = false\n    return result\n  end\n  # For backward compatibility\n  alias try_mon_enter mon_try_enter\n\n  #\n  # Enters exclusive section.\n  #\n  def mon_enter\n    Thread.critical = true\n    mon_acquire(@mon_entering_queue)\n    @mon_count += 1\n  ensure\n    Thread.critical = false\n  end\n  \n  #\n  # Leaves exclusive section.\n  #\n  def mon_exit\n    mon_check_owner\n    Thread.critical = true\n    @mon_count -= 1\n    if @mon_count == 0\n      mon_release\n    end\n    Thread.critical = false\n    Thread.pass\n  end\n\n  #\n  # Enters exclusive section and executes the block.  Leaves the exclusive\n  # section automatically when the block exits.  See example under\n  # +MonitorMixin+.\n  #\n  def mon_synchronize\n    mon_enter\n    begin\n      yield\n    ensure\n      mon_exit\n    end\n  end\n  alias synchronize mon_synchronize\n  \n  #\n  # FIXME: This isn't documented in Nutshell.\n  # \n  # Create a new condition variable for this monitor.\n  # This facilitates control of the monitor with #signal and #wait.\n  #\n  def new_cond\n    return ConditionVariable.new(self)\n  end\n\n  private\n\n  def initialize(*args)\n    super\n    mon_initialize\n  end\n\n  # called by initialize method to set defaults for instance variables.\n  def mon_initialize\n    @mon_owner = nil\n    @mon_count = 0\n    @mon_entering_queue = []\n    @mon_waiting_queue = []\n  end\n\n  # Throw a ThreadError exception if the current thread\n  # does't own the monitor\n  def mon_check_owner\n    if @mon_owner != Thread.current\n      raise ThreadError, \"current thread not owner\"\n    end\n  end\n\n  def mon_acquire(queue)\n    while @mon_owner && @mon_owner != Thread.current\n      queue.push(Thread.current)\n      Thread.stop\n      Thread.critical = true\n    end\n    @mon_owner = Thread.current\n  end\n\n  # mon_release requires Thread.critical == true\n  def mon_release\n    @mon_owner = nil\n    while t = @mon_waiting_queue.shift || @mon_entering_queue.shift\n      if t.alive?\n        t.wakeup\n        return\n      end\n    end\n  end\n\n  def mon_enter_for_cond(count)\n    mon_acquire(@mon_waiting_queue)\n    @mon_count = count\n  end\n\n  def mon_exit_for_cond\n    count = @mon_count\n    @mon_count = 0\n    return count\n  ensure\n    mon_release\n  end\nend\n\n# Monitors provide means of mutual exclusion for Thread programming.\n# A critical region is created by means of the synchronize method,\n# which takes a block.\n# The condition variables (created with #new_cond) may be used \n# to control the execution of a monitor with #signal and #wait.\n#\n# the Monitor class wraps MonitorMixin, and provides aliases\n#  alias try_enter try_mon_enter\n#  alias enter mon_enter\n#  alias exit mon_exit\n# to access its methods more concisely.\nclass Monitor\n  include MonitorMixin\n  alias try_enter try_mon_enter\n  alias enter mon_enter\n  alias exit mon_exit\nend\n\n\n# Documentation comments:\n#  - All documentation comes from Nutshell.\n#  - MonitorMixin.new_cond appears in the example, but is not documented in\n#    Nutshell.\n#  - All the internals (internal modules Accessible and Initializable, class\n#    ConditionVariable) appear in RDoc.  It might be good to hide them, by\n#    making them private, or marking them :nodoc:, etc.\n#  - The entire example from the RD section at the top is replicated in the RDoc\n#    comment for MonitorMixin.  Does the RD section need to remain?\n#  - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but\n#    not synchronize.\n#  - mon_owner is in Nutshell, but appears as an accessor in a separate module\n#    here, so is hard/impossible to RDoc.  Some other useful accessors\n#    (mon_count and some queue stuff) are also in this module, and don't appear\n#    directly in the RDoc output.\n#  - in short, it may be worth changing the code layout in this file to make the\n#    documentation easier\n\n# Local variables:\n# mode: Ruby\n# tab-width: 8\n# End:\n"
  },
  {
    "path": "lib/mutex_m.rb",
    "content": "#--\n#   mutex_m.rb - \n#   \t$Release Version: 3.0$\n#   \t$Revision: 1.7 $\n#   \t$Date: 1998/02/27 04:28:57 $\n#       Original from mutex.rb\n#   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n#       modified by matz\n#       patched by akira yamada\n#++\n#\n# == Usage\n#\n# Extend an object and use it like a Mutex object:\n#\n#   require \"mutex_m.rb\"\n#   obj = Object.new\n#   obj.extend Mutex_m\n#   # ...\n#\n# Or, include Mutex_m in a class to have its instances behave like a Mutex\n# object:\n#\n#   class Foo\n#     include Mutex_m\n#     # ...\n#   end\n#   \n#   obj = Foo.new\n\nmodule Mutex_m\n  def Mutex_m.define_aliases(cl)\n    cl.module_eval %q{\n      alias locked? mu_locked?\n      alias lock mu_lock\n      alias unlock mu_unlock\n      alias try_lock mu_try_lock\n      alias synchronize mu_synchronize\n    }\n  end  \n\n  def Mutex_m.append_features(cl)\n    super\n    define_aliases(cl) unless cl.instance_of?(Module)\n  end\n  \n  def Mutex_m.extend_object(obj)\n    super\n    obj.mu_extended\n  end\n\n  def mu_extended\n    unless (defined? locked? and\n\t    defined? lock and\n\t    defined? unlock and\n\t    defined? try_lock and\n\t    defined? synchronize)\n      Mutex_m.define_aliases(class<<self;self;end)\n    end\n    mu_initialize\n  end\n  \n  # locking \n  def mu_synchronize\n    begin\n      mu_lock\n      yield\n    ensure\n      mu_unlock\n    end\n  end\n  \n  def mu_locked?\n    @mu_locked\n  end\n  \n  def mu_try_lock\n    result = false\n    Thread.critical = true\n    unless @mu_locked\n      @mu_locked = true\n      result = true\n    end\n    Thread.critical = false\n    result\n  end\n  \n  def mu_lock\n    while (Thread.critical = true; @mu_locked)\n      @mu_waiting.push Thread.current\n      Thread.stop\n    end\n    @mu_locked = true\n    Thread.critical = false\n    self\n  end\n  \n  def mu_unlock\n    return unless @mu_locked\n    Thread.critical = true\n    wait = @mu_waiting\n    @mu_waiting = []\n    @mu_locked = false\n    Thread.critical = false\n    for w in wait\n      w.run\n    end\n    self\n  end\n  \n  private\n  \n  def mu_initialize\n    @mu_waiting = []\n    @mu_locked = false;\n  end\n\n  def initialize(*args)\n    mu_initialize\n    super\n  end\nend\n"
  },
  {
    "path": "lib/net/ftp.rb",
    "content": "# \n# = net/ftp.rb - FTP Client Library\n# \n# Written by Shugo Maeda <shugo@ruby-lang.org>.\n#\n# Documentation by Gavin Sinclair, sourced from \"Programming Ruby\" (Hunt/Thomas)\n# and \"Ruby In a Nutshell\" (Matsumoto), used with permission.\n# \n# This library is distributed under the terms of the Ruby license.\n# You can freely distribute/modify this library.\n#\n# It is included in the Ruby standard library.\n#\n# See the Net::FTP class for an overview.\n#\n\nrequire \"socket\"\nrequire \"monitor\"\n\nmodule Net\n\n  # :stopdoc:\n  class FTPError < StandardError; end\n  class FTPReplyError < FTPError; end\n  class FTPTempError < FTPError; end \n  class FTPPermError < FTPError; end \n  class FTPProtoError < FTPError; end\n  # :startdoc:\n\n  #\n  # This class implements the File Transfer Protocol.  If you have used a\n  # command-line FTP program, and are familiar with the commands, you will be\n  # able to use this class easily.  Some extra features are included to take\n  # advantage of Ruby's style and strengths.\n  #\n  # == Example\n  # \n  #   require 'net/ftp'\n  #\n  # === Example 1\n  #  \n  #   ftp = Net::FTP.new('ftp.netlab.co.jp')\n  #   ftp.login\n  #   files = ftp.chdir('pub/lang/ruby/contrib')\n  #   files = ftp.list('n*')\n  #   ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)\n  #   ftp.close\n  #\n  # === Example 2\n  #\n  #   Net::FTP.open('ftp.netlab.co.jp') do |ftp|\n  #     ftp.login\n  #     files = ftp.chdir('pub/lang/ruby/contrib')\n  #     files = ftp.list('n*')\n  #     ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024)\n  #   end\n  #\n  # == Major Methods\n  #\n  # The following are the methods most likely to be useful to users:\n  # - FTP.open\n  # - #getbinaryfile\n  # - #gettextfile\n  # - #putbinaryfile\n  # - #puttextfile\n  # - #chdir\n  # - #nlst\n  # - #size\n  # - #rename\n  # - #delete\n  #\n  class FTP\n    include MonitorMixin\n    \n    # :stopdoc:\n    FTP_PORT = 21\n    CRLF = \"\\r\\n\"\n    DEFAULT_BLOCKSIZE = 4096\n    # :startdoc:\n    \n    # When +true+, transfers are performed in binary mode.  Default: +true+.\n    attr_accessor :binary\n\n    # When +true+, the connection is in passive mode.  Default: +false+.\n    attr_accessor :passive\n\n    # When +true+, all traffic to and from the server is written\n    # to +$stdout+.  Default: +false+.\n    attr_accessor :debug_mode\n\n    # Sets or retrieves the +resume+ status, which decides whether incomplete\n    # transfers are resumed or restarted.  Default: +false+.\n    attr_accessor :resume\n\n    # The server's welcome message.\n    attr_reader :welcome\n\n    # The server's last response code.\n    attr_reader :last_response_code\n    alias lastresp last_response_code\n\n    # The server's last response.\n    attr_reader :last_response\n    \n    #\n    # A synonym for <tt>FTP.new</tt>, but with a mandatory host parameter.\n    #\n    # If a block is given, it is passed the +FTP+ object, which will be closed\n    # when the block finishes, or when an exception is raised.\n    #\n    def FTP.open(host, user = nil, passwd = nil, acct = nil)\n      if block_given?\n        ftp = new(host, user, passwd, acct)\n        begin\n          yield ftp\n        ensure\n          ftp.close\n        end\n      else\n        new(host, user, passwd, acct)\n      end\n    end\n    \n    #\n    # Creates and returns a new +FTP+ object. If a +host+ is given, a connection\n    # is made. Additionally, if the +user+ is given, the given user name,\n    # password, and (optionally) account are used to log in.  See #login.\n    #\n    def initialize(host = nil, user = nil, passwd = nil, acct = nil)\n      super()\n      @binary = true\n      @passive = false\n      @debug_mode = false\n      @resume = false\n      if host\n\tconnect(host)\n\tif user\n\t  login(user, passwd, acct)\n\tend\n      end\n    end\n\n    # Obsolete\n    def return_code\n      $stderr.puts(\"warning: Net::FTP#return_code is obsolete and do nothing\")\n      return \"\\n\"\n    end\n\n    # Obsolete\n    def return_code=(s)\n      $stderr.puts(\"warning: Net::FTP#return_code= is obsolete and do nothing\")\n    end\n\n    def open_socket(host, port)\n      if defined? SOCKSSocket and ENV[\"SOCKS_SERVER\"]\n\t@passive = true\n\treturn SOCKSSocket.open(host, port)\n      else\n\treturn TCPSocket.open(host, port)\n      end\n    end\n    private :open_socket\n    \n    #\n    # Establishes an FTP connection to host, optionally overriding the default\n    # port. If the environment variable +SOCKS_SERVER+ is set, sets up the\n    # connection through a SOCKS proxy. Raises an exception (typically\n    # <tt>Errno::ECONNREFUSED</tt>) if the connection cannot be established.\n    #\n    def connect(host, port = FTP_PORT)\n      if @debug_mode\n\tprint \"connect: \", host, \", \", port, \"\\n\"\n      end\n      synchronize do\n\t@sock = open_socket(host, port)\n\tvoidresp\n      end\n    end\n\n    #\n    # WRITEME or make private\n    #\n    def set_socket(sock, get_greeting = true)\n      synchronize do\n\t@sock = sock\n\tif get_greeting\n\t  voidresp\n\tend\n      end\n    end\n\n    def sanitize(s)\n      if s =~ /^PASS /i\n\treturn s[0, 5] + \"*\" * (s.length - 5)\n      else\n\treturn s\n      end\n    end\n    private :sanitize\n    \n    def putline(line)\n      if @debug_mode\n\tprint \"put: \", sanitize(line), \"\\n\"\n      end\n      line = line + CRLF\n      @sock.write(line)\n    end\n    private :putline\n    \n    def getline\n      line = @sock.readline # if get EOF, raise EOFError\n      line.sub!(/(\\r\\n|\\n|\\r)\\z/n, \"\")\n      if @debug_mode\n\tprint \"get: \", sanitize(line), \"\\n\"\n      end\n      return line\n    end\n    private :getline\n    \n    def getmultiline\n      line = getline\n      buff = line\n      if line[3] == ?-\n\t  code = line[0, 3]\n\tbegin\n\t  line = getline\n\t  buff << \"\\n\" << line\n\tend until line[0, 3] == code and line[3] != ?-\n      end\n      return buff << \"\\n\"\n    end\n    private :getmultiline\n    \n    def getresp\n      @last_response = getmultiline\n      @last_response_code = @last_response[0, 3]\n      case @last_response_code\n      when /\\A[123]/\n\treturn @last_response\n      when /\\A4/\n\traise FTPTempError, @last_response\n      when /\\A5/\n\traise FTPPermError, @last_response\n      else\n\traise FTPProtoError, @last_response\n      end\n    end\n    private :getresp\n    \n    def voidresp\n      resp = getresp\n      if resp[0] != ?2\n\traise FTPReplyError, resp\n      end\n    end\n    private :voidresp\n    \n    #\n    # Sends a command and returns the response.\n    #\n    def sendcmd(cmd)\n      synchronize do\n\tputline(cmd)\n\treturn getresp\n      end\n    end\n    \n    #\n    # Sends a command and expect a response beginning with '2'.\n    #\n    def voidcmd(cmd)\n      synchronize do\n\tputline(cmd)\n\tvoidresp\n      end\n    end\n    \n    def sendport(host, port)\n      af = (@sock.peeraddr)[0]\n      if af == \"AF_INET\"\n\tcmd = \"PORT \" + (host.split(\".\") + port.divmod(256)).join(\",\")\n      elsif af == \"AF_INET6\"\n\tcmd = sprintf(\"EPRT |2|%s|%d|\", host, port)\n      else\n\traise FTPProtoError, host\n      end\n      voidcmd(cmd)\n    end\n    private :sendport\n    \n    def makeport\n      sock = TCPServer.open(@sock.addr[3], 0)\n      port = sock.addr[1]\n      host = sock.addr[3]\n      resp = sendport(host, port)\n      return sock\n    end\n    private :makeport\n    \n    def makepasv\n      if @sock.peeraddr[0] == \"AF_INET\"\n\thost, port = parse227(sendcmd(\"PASV\"))\n      else\n\thost, port = parse229(sendcmd(\"EPSV\"))\n\t#     host, port = parse228(sendcmd(\"LPSV\"))\n      end\n      return host, port\n    end\n    private :makepasv\n    \n    def transfercmd(cmd, rest_offset = nil)\n      if @passive\n\thost, port = makepasv\n\tconn = open_socket(host, port)\n\tif @resume and rest_offset\n\t  resp = sendcmd(\"REST \" + rest_offset.to_s) \n\t  if resp[0] != ?3\n\t    raise FTPReplyError, resp\n\t  end\n\tend\n\tresp = sendcmd(cmd)\n        # skip 2XX for some ftp servers\n        resp = getresp if resp[0] == ?2\n\tif resp[0] != ?1\n\t  raise FTPReplyError, resp\n\tend\n      else\n\tsock = makeport\n\tif @resume and rest_offset\n\t  resp = sendcmd(\"REST \" + rest_offset.to_s) \n\t  if resp[0] != ?3\n\t    raise FTPReplyError, resp\n\t  end\n\tend\n\tresp = sendcmd(cmd)\n        # skip 2XX for some ftp servers\n        resp = getresp if resp[0] == ?2\n\tif resp[0] != ?1\n\t  raise FTPReplyError, resp\n\tend\n\tconn = sock.accept\n\tsock.close\n      end\n      return conn\n    end\n    private :transfercmd\n    \n    def getaddress\n      thishost = Socket.gethostname rescue \"\"\n      if not thishost.index(\".\")\n        thishost = Socket.gethostbyname(thishost)[0] rescue \"\"\n      end\n      if ENV.has_key?(\"LOGNAME\")\n\trealuser = ENV[\"LOGNAME\"]\n      elsif ENV.has_key?(\"USER\")\n\trealuser = ENV[\"USER\"]\n      else\n\trealuser = \"anonymous\"\n      end\n      return realuser + \"@\" + thishost\n    end\n    private :getaddress\n    \n    #\n    # Logs in to the remote host. The session must have been previously\n    # connected.  If +user+ is the string \"anonymous\" and the +password+ is\n    # +nil+, a password of <tt>user@host</tt> is synthesized. If the +acct+\n    # parameter is not +nil+, an FTP ACCT command is sent following the\n    # successful login.  Raises an exception on error (typically\n    # <tt>Net::FTPPermError</tt>).\n    #\n    def login(user = \"anonymous\", passwd = nil, acct = nil)\n      if user == \"anonymous\" and passwd == nil\n\tpasswd = getaddress\n      end\n      \n      resp = \"\"\n      synchronize do\n\tresp = sendcmd('USER ' + user)\n\tif resp[0] == ?3\n          raise FTPReplyError, resp if passwd.nil?\n\t  resp = sendcmd('PASS ' + passwd)\n\tend\n\tif resp[0] == ?3\n          raise FTPReplyError, resp if acct.nil?\n\t  resp = sendcmd('ACCT ' + acct)\n\tend\n      end\n      if resp[0] != ?2\n\traise FTPReplyError, resp\n      end\n      @welcome = resp\n    end\n    \n    #\n    # Puts the connection into binary (image) mode, issues the given command,\n    # and fetches the data returned, passing it to the associated block in\n    # chunks of +blocksize+ characters. Note that +cmd+ is a server command\n    # (such as \"RETR myfile\").\n    #\n    def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data\n      synchronize do\n\tvoidcmd(\"TYPE I\")\n\tconn = transfercmd(cmd, rest_offset)\n\tloop do\n\t  data = conn.read(blocksize)\n\t  break if data == nil\n\t  yield(data)\n\tend\n\tconn.close\n\tvoidresp\n      end\n    end\n    \n    #\n    # Puts the connection into ASCII (text) mode, issues the given command, and\n    # passes the resulting data, one line at a time, to the associated block. If\n    # no block is given, prints the lines. Note that +cmd+ is a server command\n    # (such as \"RETR myfile\").\n    #\n    def retrlines(cmd) # :yield: line\n      synchronize do\n\tvoidcmd(\"TYPE A\")\n\tconn = transfercmd(cmd)\n\tloop do\n\t  line = conn.gets\n\t  break if line == nil\n\t  if line[-2, 2] == CRLF\n\t    line = line[0 .. -3]\n\t  elsif line[-1] == ?\\n\n\t    line = line[0 .. -2]\n\t  end\n\t  yield(line)\n\tend\n\tconn.close\n\tvoidresp\n      end\n    end\n    \n    #\n    # Puts the connection into binary (image) mode, issues the given server-side\n    # command (such as \"STOR myfile\"), and sends the contents of the file named\n    # +file+ to the server. If the optional block is given, it also passes it\n    # the data, in chunks of +blocksize+ characters.\n    #\n    def storbinary(cmd, file, blocksize, rest_offset = nil, &block) # :yield: data\n      if rest_offset\n        file.seek(rest_offset, IO::SEEK_SET)\n      end\n      synchronize do\n\tvoidcmd(\"TYPE I\")\n\tconn = transfercmd(cmd, rest_offset)\n\tloop do\n\t  buf = file.read(blocksize)\n\t  break if buf == nil\n\t  conn.write(buf)\n\t  yield(buf) if block\n\tend\n\tconn.close\n\tvoidresp\n      end\n    end\n    \n    #\n    # Puts the connection into ASCII (text) mode, issues the given server-side\n    # command (such as \"STOR myfile\"), and sends the contents of the file\n    # named +file+ to the server, one line at a time. If the optional block is\n    # given, it also passes it the lines.\n    #\n    def storlines(cmd, file, &block) # :yield: line\n      synchronize do\n\tvoidcmd(\"TYPE A\")\n\tconn = transfercmd(cmd)\n\tloop do\n\t  buf = file.gets\n\t  break if buf == nil\n\t  if buf[-2, 2] != CRLF\n\t    buf = buf.chomp + CRLF\n\t  end\n\t  conn.write(buf)\n\t  yield(buf) if block\n\tend\n\tconn.close\n\tvoidresp\n      end\n    end\n\n    #\n    # Retrieves +remotefile+ in binary mode, storing the result in +localfile+.\n    # If a block is supplied, it is passed the retrieved data in +blocksize+\n    # chunks.\n    #\n    def getbinaryfile(remotefile, localfile = File.basename(remotefile),\n\t\t      blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data\n      if @resume\n\trest_offset = File.size?(localfile)\n\tf = open(localfile, \"a\")\n      else\n\trest_offset = nil\n\tf = open(localfile, \"w\")\n      end\n      begin\n\tf.binmode\n\tretrbinary(\"RETR \" + remotefile, blocksize, rest_offset) do |data|\n\t  f.write(data)\n\t  yield(data) if block\n\tend\n      ensure\n\tf.close\n      end\n    end\n    \n    #\n    # Retrieves +remotefile+ in ASCII (text) mode, storing the result in\n    # +localfile+. If a block is supplied, it is passed the retrieved data one\n    # line at a time.\n    #\n    def gettextfile(remotefile, localfile = File.basename(remotefile), &block) # :yield: line\n      f = open(localfile, \"w\")\n      begin\n\tretrlines(\"RETR \" + remotefile) do |line|\n\t  f.puts(line)\n\t  yield(line) if block\n\tend\n      ensure\n\tf.close\n      end\n    end\n\n    #\n    # Retrieves +remotefile+ in whatever mode the session is set (text or\n    # binary).  See #gettextfile and #getbinaryfile.\n    #\n    def get(remotefile, localfile = File.basename(remotefile),\n\t    blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data\n      unless @binary\n\tgettextfile(remotefile, localfile, &block)\n      else\n\tgetbinaryfile(remotefile, localfile, blocksize, &block)\n      end\n    end\n    \n    #\n    # Transfers +localfile+ to the server in binary mode, storing the result in\n    # +remotefile+. If a block is supplied, calls it, passing in the transmitted\n    # data in +blocksize+ chunks.\n    #\n    def putbinaryfile(localfile, remotefile = File.basename(localfile),\n\t\t      blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data\n      if @resume\n        begin\n          rest_offset = size(remotefile)\n        rescue Net::FTPPermError\n          rest_offset = nil\n        end\n      else\n\trest_offset = nil\n      end\n      f = open(localfile)\n      begin\n\tf.binmode\n\tstorbinary(\"STOR \" + remotefile, f, blocksize, rest_offset, &block)\n      ensure\n\tf.close\n      end\n    end\n    \n    #\n    # Transfers +localfile+ to the server in ASCII (text) mode, storing the result\n    # in +remotefile+. If callback or an associated block is supplied, calls it,\n    # passing in the transmitted data one line at a time.\n    #\n    def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line\n      f = open(localfile)\n      begin\n\tstorlines(\"STOR \" + remotefile, f, &block)\n      ensure\n\tf.close\n      end\n    end\n\n    #\n    # Transfers +localfile+ to the server in whatever mode the session is set\n    # (text or binary).  See #puttextfile and #putbinaryfile.\n    #\n    def put(localfile, remotefile = File.basename(localfile),\n\t    blocksize = DEFAULT_BLOCKSIZE, &block)\n      unless @binary\n\tputtextfile(localfile, remotefile, &block)\n      else\n\tputbinaryfile(localfile, remotefile, blocksize, &block)\n      end\n    end\n\n    #\n    # Sends the ACCT command.  TODO: more info.\n    #\n    def acct(account)\n      cmd = \"ACCT \" + account\n      voidcmd(cmd)\n    end\n    \n    #\n    # Returns an array of filenames in the remote directory.\n    #\n    def nlst(dir = nil)\n      cmd = \"NLST\"\n      if dir\n\tcmd = cmd + \" \" + dir\n      end\n      files = []\n      retrlines(cmd) do |line|\n\tfiles.push(line)\n      end\n      return files\n    end\n    \n    #\n    # Returns an array of file information in the directory (the output is like\n    # `ls -l`).  If a block is given, it iterates through the listing.\n    #\n    def list(*args, &block) # :yield: line\n      cmd = \"LIST\"\n      args.each do |arg|\n\tcmd = cmd + \" \" + arg\n      end\n      if block\n\tretrlines(cmd, &block)\n      else\n\tlines = []\n\tretrlines(cmd) do |line|\n\t  lines << line\n\tend\n\treturn lines\n      end\n    end\n    alias ls list\n    alias dir list\n    \n    #\n    # Renames a file on the server.\n    #\n    def rename(fromname, toname)\n      resp = sendcmd(\"RNFR \" + fromname)\n      if resp[0] != ?3\n\traise FTPReplyError, resp\n      end\n      voidcmd(\"RNTO \" + toname)\n    end\n    \n    #\n    # Deletes a file on the server.\n    #\n    def delete(filename)\n      resp = sendcmd(\"DELE \" + filename)\n      if resp[0, 3] == \"250\"\n\treturn\n      elsif resp[0] == ?5\n\traise FTPPermError, resp\n      else\n\traise FTPReplyError, resp\n      end\n    end\n    \n    #\n    # Changes the (remote) directory.\n    #\n    def chdir(dirname)\n      if dirname == \"..\"\n\tbegin\n\t  voidcmd(\"CDUP\")\n\t  return\n\trescue FTPPermError => e\n\t  if e.message[0, 3] != \"500\"\n\t    raise e\n\t  end\n\tend\n      end\n      cmd = \"CWD \" + dirname\n      voidcmd(cmd)\n    end\n    \n    #\n    # Returns the size of the given (remote) filename.\n    #\n    def size(filename)\n      voidcmd(\"TYPE I\")\n      resp = sendcmd(\"SIZE \" + filename)\n      if resp[0, 3] != \"213\" \n\traise FTPReplyError, resp\n      end\n      return resp[3..-1].strip.to_i\n    end\n    \n    MDTM_REGEXP = /^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)/  # :nodoc:\n    \n    #\n    # Returns the last modification time of the (remote) file.  If +local+ is\n    # +true+, it is returned as a local time, otherwise it's a UTC time.\n    #\n    def mtime(filename, local = false)\n      str = mdtm(filename)\n      ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}\n      return local ? Time.local(*ary) : Time.gm(*ary)\n    end\n    \n    #\n    # Creates a remote directory.\n    #\n    def mkdir(dirname)\n      resp = sendcmd(\"MKD \" + dirname)\n      return parse257(resp)\n    end\n    \n    #\n    # Removes a remote directory.\n    #\n    def rmdir(dirname)\n      voidcmd(\"RMD \" + dirname)\n    end\n    \n    #\n    # Returns the current remote directory.\n    #\n    def pwd\n      resp = sendcmd(\"PWD\")\n      return parse257(resp)\n    end\n    alias getdir pwd\n    \n    #\n    # Returns system information.\n    #\n    def system\n      resp = sendcmd(\"SYST\")\n      if resp[0, 3] != \"215\"\n\traise FTPReplyError, resp\n      end\n      return resp[4 .. -1]\n    end\n    \n    #\n    # Aborts the previous command (ABOR command).\n    #\n    def abort\n      line = \"ABOR\" + CRLF\n      print \"put: ABOR\\n\" if @debug_mode\n      @sock.send(line, Socket::MSG_OOB)\n      resp = getmultiline\n      unless [\"426\", \"226\", \"225\"].include?(resp[0, 3])\n\traise FTPProtoError, resp\n      end\n      return resp\n    end\n    \n    #\n    # Returns the status (STAT command).\n    #\n    def status\n      line = \"STAT\" + CRLF\n      print \"put: STAT\\n\" if @debug_mode\n      @sock.send(line, Socket::MSG_OOB)\n      return getresp\n    end\n    \n    #\n    # Issues the MDTM command.  TODO: more info.\n    #\n    def mdtm(filename)\n      resp = sendcmd(\"MDTM \" + filename)\n      if resp[0, 3] == \"213\"\n\treturn resp[3 .. -1].strip\n      end\n    end\n    \n    #\n    # Issues the HELP command.\n    #\n    def help(arg = nil)\n      cmd = \"HELP\"\n      if arg\n\tcmd = cmd + \" \" + arg\n      end\n      sendcmd(cmd)\n    end\n    \n    #\n    # Exits the FTP session.\n    #\n    def quit\n      voidcmd(\"QUIT\")\n    end\n\n    #\n    # Issues a NOOP command.\n    #\n    def noop\n      voidcmd(\"NOOP\")\n    end\n\n    #\n    # Issues a SITE command.\n    #\n    def site(arg)\n      cmd = \"SITE \" + arg\n      voidcmd(cmd)\n    end\n    \n    #\n    # Closes the connection.  Further operations are impossible until you open\n    # a new connection with #connect.\n    #\n    def close\n      @sock.close if @sock and not @sock.closed?\n    end\n    \n    #\n    # Returns +true+ iff the connection is closed.\n    #\n    def closed?\n      @sock == nil or @sock.closed?\n    end\n    \n    def parse227(resp)\n      if resp[0, 3] != \"227\"\n\traise FTPReplyError, resp\n      end\n      left = resp.index(\"(\")\n      right = resp.index(\")\")\n      if left == nil or right == nil\n\traise FTPProtoError, resp\n      end\n      numbers = resp[left + 1 .. right - 1].split(\",\")\n      if numbers.length != 6\n\traise FTPProtoError, resp\n      end\n      host = numbers[0, 4].join(\".\")\n      port = (numbers[4].to_i << 8) + numbers[5].to_i\n      return host, port\n    end\n    private :parse227\n    \n    def parse228(resp)\n      if resp[0, 3] != \"228\"\n\traise FTPReplyError, resp\n      end\n      left = resp.index(\"(\")\n      right = resp.index(\")\")\n      if left == nil or right == nil\n\traise FTPProtoError, resp\n      end\n      numbers = resp[left + 1 .. right - 1].split(\",\")\n      if numbers[0] == \"4\"\n\tif numbers.length != 9 || numbers[1] != \"4\" || numbers[2 + 4] != \"2\"\n\t  raise FTPProtoError, resp\n\tend\n\thost = numbers[2, 4].join(\".\")\n\tport = (numbers[7].to_i << 8) + numbers[8].to_i\n      elsif numbers[0] == \"6\"\n\tif numbers.length != 21 || numbers[1] != \"16\" || numbers[2 + 16] != \"2\"\n\t  raise FTPProtoError, resp\n\tend\n\tv6 = [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\"]\n\tfor i in 0 .. 7\n\t  v6[i] = sprintf(\"%02x%02x\", numbers[(i * 2) + 2].to_i,\n\t\t\t  numbers[(i * 2) + 3].to_i)\n\tend\n\thost = v6[0, 8].join(\":\")\n\tport = (numbers[19].to_i << 8) + numbers[20].to_i\n      end \n      return host, port\n    end\n    private :parse228\n    \n    def parse229(resp)\n      if resp[0, 3] != \"229\"\n\traise FTPReplyError, resp\n      end\n      left = resp.index(\"(\")\n      right = resp.index(\")\")\n      if left == nil or right == nil\n\traise FTPProtoError, resp\n      end\n      numbers = resp[left + 1 .. right - 1].split(resp[left + 1, 1])\n      if numbers.length != 4\n\traise FTPProtoError, resp\n      end\n      port = numbers[3].to_i\n      host = (@sock.peeraddr())[3]\n      return host, port\n    end\n    private :parse229\n    \n    def parse257(resp)\n      if resp[0, 3] != \"257\"\n\traise FTPReplyError, resp\n      end\n      if resp[3, 2] != ' \"'\n\treturn \"\"\n      end\n      dirname = \"\"\n      i = 5\n      n = resp.length\n      while i < n\n\tc = resp[i, 1]\n\ti = i + 1\n\tif c == '\"'\n\t  if i > n or resp[i, 1] != '\"'\n\t    break\n\t  end\n\t  i = i + 1\n\tend\n\tdirname = dirname + c\n      end\n      return dirname\n    end\n    private :parse257\n  end\n\nend\n\n\n# Documentation comments:\n#  - sourced from pickaxe and nutshell, with improvements (hopefully)\n#  - three methods should be private (search WRITEME)\n#  - two methods need more information (search TODO)\n"
  },
  {
    "path": "lib/net/http.rb",
    "content": "#\n# = net/http.rb\n#\n# Copyright (c) 1999-2006 Yukihiro Matsumoto\n# Copyright (c) 1999-2006 Minero Aoki\n# Copyright (c) 2001 GOTOU Yuuzou\n# \n# Written and maintained by Minero Aoki <aamine@loveruby.net>.\n# HTTPS support added by GOTOU Yuuzou <gotoyuzo@notwork.org>.\n#\n# This file is derived from \"http-access.rb\".\n#\n# Documented by Minero Aoki; converted to RDoc by William Webber.\n# \n# This program is free software. You can re-distribute and/or\n# modify this program under the same terms of ruby itself ---\n# Ruby Distribution License or GNU General Public License.\n#\n# See Net::HTTP for an overview and examples. \n# \n# NOTE: You can find Japanese version of this document here:\n# http://www.ruby-lang.org/ja/man/?cmd=view;name=net%2Fhttp.rb\n# \n#--\n# $Id$\n#++ \n\nrequire 'net/protocol'\nrequire 'uri'\n\nmodule Net   #:nodoc:\n\n  # :stopdoc:\n  class HTTPBadResponse < StandardError; end\n  class HTTPHeaderSyntaxError < StandardError; end\n  # :startdoc:\n\n  # == What Is This Library?\n  # \n  # This library provides your program functions to access WWW\n  # documents via HTTP, Hyper Text Transfer Protocol version 1.1.\n  # For details of HTTP, refer [RFC2616]\n  # (http://www.ietf.org/rfc/rfc2616.txt).\n  # \n  # == Examples\n  # \n  # === Getting Document From WWW Server\n  # \n  # Example #1: Simple GET+print\n  # \n  #     require 'net/http'\n  #     Net::HTTP.get_print 'www.example.com', '/index.html'\n  # \n  # Example #2: Simple GET+print by URL\n  # \n  #     require 'net/http'\n  #     require 'uri'\n  #     Net::HTTP.get_print URI.parse('http://www.example.com/index.html')\n  # \n  # Example #3: More generic GET+print\n  # \n  #     require 'net/http'\n  #     require 'uri'\n  #\n  #     url = URI.parse('http://www.example.com/index.html')\n  #     res = Net::HTTP.start(url.host, url.port) {|http|\n  #       http.get('/index.html')\n  #     }\n  #     puts res.body\n  #\n  # Example #4: More generic GET+print\n  # \n  #     require 'net/http'\n  #\n  #     url = URI.parse('http://www.example.com/index.html')\n  #     req = Net::HTTP::Get.new(url.path)\n  #     res = Net::HTTP.start(url.host, url.port) {|http|\n  #       http.request(req)\n  #     }\n  #     puts res.body\n  # \n  # === Posting Form Data\n  # \n  #     require 'net/http'\n  #     require 'uri'\n  #\n  #     #1: Simple POST\n  #     res = Net::HTTP.post_form(URI.parse('http://www.example.com/search.cgi'),\n  #                               {'q'=>'ruby', 'max'=>'50'})\n  #     puts res.body\n  #\n  #     #2: POST with basic authentication\n  #     res = Net::HTTP.post_form(URI.parse('http://jack:pass@www.example.com/todo.cgi'),\n  #                                         {'from'=>'2005-01-01', 'to'=>'2005-03-31'})\n  #     puts res.body\n  #\n  #     #3: Detailed control\n  #     url = URI.parse('http://www.example.com/todo.cgi')\n  #     req = Net::HTTP::Post.new(url.path)\n  #     req.basic_auth 'jack', 'pass'\n  #     req.set_form_data({'from'=>'2005-01-01', 'to'=>'2005-03-31'}, ';')\n  #     res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }\n  #     case res\n  #     when Net::HTTPSuccess, Net::HTTPRedirection\n  #       # OK\n  #     else\n  #       res.error!\n  #     end\n  # \n  # === Accessing via Proxy\n  # \n  # Net::HTTP.Proxy creates http proxy class. It has same\n  # methods of Net::HTTP but its instances always connect to\n  # proxy, instead of given host.\n  # \n  #     require 'net/http'\n  # \n  #     proxy_addr = 'your.proxy.host'\n  #     proxy_port = 8080\n  #             :\n  #     Net::HTTP::Proxy(proxy_addr, proxy_port).start('www.example.com') {|http|\n  #       # always connect to your.proxy.addr:8080\n  #             :\n  #     }\n  # \n  # Since Net::HTTP.Proxy returns Net::HTTP itself when proxy_addr is nil,\n  # there's no need to change code if there's proxy or not.\n  # \n  # There are two additional parameters in Net::HTTP.Proxy which allow to\n  # specify proxy user name and password:\n  # \n  #     Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user = nil, proxy_pass = nil)\n  # \n  # You may use them to work with authorization-enabled proxies:\n  # \n  #     require 'net/http'\n  #     require 'uri'\n  #     \n  #     proxy_host = 'your.proxy.host'\n  #     proxy_port = 8080\n  #     uri = URI.parse(ENV['http_proxy'])\n  #     proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo\n  #     Net::HTTP::Proxy(proxy_host, proxy_port,\n  #                      proxy_user, proxy_pass).start('www.example.com') {|http|\n  #       # always connect to your.proxy.addr:8080 using specified username and password\n  #             :\n  #     }\n  #\n  # Note that net/http never rely on HTTP_PROXY environment variable.\n  # If you want to use proxy, set it explicitly.\n  # \n  # === Following Redirection\n  # \n  #     require 'net/http'\n  #     require 'uri'\n  # \n  #     def fetch(uri_str, limit = 10)\n  #       # You should choose better exception. \n  #       raise ArgumentError, 'HTTP redirect too deep' if limit == 0\n  # \n  #       response = Net::HTTP.get_response(URI.parse(uri_str))\n  #       case response\n  #       when Net::HTTPSuccess     then response\n  #       when Net::HTTPRedirection then fetch(response['location'], limit - 1)\n  #       else\n  #         response.error!\n  #       end\n  #     end\n  # \n  #     print fetch('http://www.ruby-lang.org')\n  # \n  # Net::HTTPSuccess and Net::HTTPRedirection is a HTTPResponse class.\n  # All HTTPResponse objects belong to its own response class which\n  # indicate HTTP result status. For details of response classes,\n  # see section \"HTTP Response Classes\".\n  # \n  # === Basic Authentication\n  # \n  #     require 'net/http'\n  # \n  #     Net::HTTP.start('www.example.com') {|http|\n  #       req = Net::HTTP::Get.new('/secret-page.html')\n  #       req.basic_auth 'account', 'password'\n  #       response = http.request(req)\n  #       print response.body\n  #     }\n  # \n  # === HTTP Request Classes\n  #\n  # Here is HTTP request class hierarchy.\n  #\n  #   Net::HTTPRequest\n  #       Net::HTTP::Get\n  #       Net::HTTP::Head\n  #       Net::HTTP::Post\n  #       Net::HTTP::Put\n  #       Net::HTTP::Proppatch\n  #       Net::HTTP::Lock\n  #       Net::HTTP::Unlock\n  #       Net::HTTP::Options\n  #       Net::HTTP::Propfind\n  #       Net::HTTP::Delete\n  #       Net::HTTP::Move\n  #       Net::HTTP::Copy\n  #       Net::HTTP::Mkcol\n  #       Net::HTTP::Trace\n  #\n  # === HTTP Response Classes\n  #\n  # Here is HTTP response class hierarchy.\n  # All classes are defined in Net module.\n  #\n  #   HTTPResponse\n  #       HTTPUnknownResponse\n  #       HTTPInformation                    # 1xx\n  #           HTTPContinue                       # 100\n  #           HTTPSwitchProtocl                  # 101\n  #       HTTPSuccess                        # 2xx\n  #           HTTPOK                             # 200\n  #           HTTPCreated                        # 201\n  #           HTTPAccepted                       # 202\n  #           HTTPNonAuthoritativeInformation    # 203\n  #           HTTPNoContent                      # 204\n  #           HTTPResetContent                   # 205\n  #           HTTPPartialContent                 # 206\n  #       HTTPRedirection                    # 3xx\n  #           HTTPMultipleChoice                 # 300\n  #           HTTPMovedPermanently               # 301\n  #           HTTPFound                          # 302\n  #           HTTPSeeOther                       # 303\n  #           HTTPNotModified                    # 304\n  #           HTTPUseProxy                       # 305\n  #           HTTPTemporaryRedirect              # 307\n  #       HTTPClientError                    # 4xx\n  #           HTTPBadRequest                     # 400\n  #           HTTPUnauthorized                   # 401\n  #           HTTPPaymentRequired                # 402\n  #           HTTPForbidden                      # 403\n  #           HTTPNotFound                       # 404\n  #           HTTPMethodNotAllowed               # 405\n  #           HTTPNotAcceptable                  # 406\n  #           HTTPProxyAuthenticationRequired    # 407\n  #           HTTPRequestTimeOut                 # 408\n  #           HTTPConflict                       # 409\n  #           HTTPGone                           # 410\n  #           HTTPLengthRequired                 # 411\n  #           HTTPPreconditionFailed             # 412\n  #           HTTPRequestEntityTooLarge          # 413\n  #           HTTPRequestURITooLong              # 414\n  #           HTTPUnsupportedMediaType           # 415\n  #           HTTPRequestedRangeNotSatisfiable   # 416\n  #           HTTPExpectationFailed              # 417\n  #       HTTPServerError                    # 5xx\n  #           HTTPInternalServerError            # 500\n  #           HTTPNotImplemented                 # 501\n  #           HTTPBadGateway                     # 502\n  #           HTTPServiceUnavailable             # 503\n  #           HTTPGatewayTimeOut                 # 504\n  #           HTTPVersionNotSupported            # 505\n  # \n  # == Switching Net::HTTP versions\n  # \n  # You can use net/http.rb 1.1 features (bundled with Ruby 1.6)\n  # by calling HTTP.version_1_1. Calling Net::HTTP.version_1_2\n  # allows you to use 1.2 features again.\n  # \n  #     # example\n  #     Net::HTTP.start {|http1| ...(http1 has 1.2 features)... }\n  # \n  #     Net::HTTP.version_1_1\n  #     Net::HTTP.start {|http2| ...(http2 has 1.1 features)... }\n  # \n  #     Net::HTTP.version_1_2\n  #     Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }\n  # \n  # This function is NOT thread-safe.\n  #\n  class HTTP < Protocol\n\n    # :stopdoc:\n    Revision = %q$Revision$.split[1]\n    HTTPVersion = '1.1'\n    @newimpl = true\n    # :startdoc:\n\n    # Turns on net/http 1.2 (ruby 1.8) features.\n    # Defaults to ON in ruby 1.8.\n    #\n    # I strongly recommend to call this method always.\n    #\n    #   require 'net/http'\n    #   Net::HTTP.version_1_2\n    #\n    def HTTP.version_1_2\n      @newimpl = true\n    end\n\n    # Turns on net/http 1.1 (ruby 1.6) features.\n    # Defaults to OFF in ruby 1.8.\n    def HTTP.version_1_1\n      @newimpl = false\n    end\n\n    # true if net/http is in version 1.2 mode.\n    # Defaults to true.\n    def HTTP.version_1_2?\n      @newimpl\n    end\n\n    # true if net/http is in version 1.1 compatible mode.\n    # Defaults to true.\n    def HTTP.version_1_1?\n      not @newimpl\n    end\n\n    class << HTTP\n      alias is_version_1_1? version_1_1?   #:nodoc:\n      alias is_version_1_2? version_1_2?   #:nodoc:\n    end\n\n    #\n    # short cut methods\n    #\n\n    #\n    # Get body from target and output it to +$stdout+.  The\n    # target can either be specified as (+uri+), or as\n    # (+host+, +path+, +port+ = 80); so: \n    #\n    #    Net::HTTP.get_print URI.parse('http://www.example.com/index.html')\n    #\n    # or:\n    #\n    #    Net::HTTP.get_print 'www.example.com', '/index.html'\n    #\n    def HTTP.get_print(uri_or_host, path = nil, port = nil)\n      get_response(uri_or_host, path, port) {|res|\n        res.read_body do |chunk|\n          $stdout.print chunk\n        end\n      }\n      nil\n    end\n\n    # Send a GET request to the target and return the response\n    # as a string.  The target can either be specified as\n    # (+uri+), or as (+host+, +path+, +port+ = 80); so:\n    # \n    #    print Net::HTTP.get(URI.parse('http://www.example.com/index.html'))\n    #\n    # or:\n    #\n    #    print Net::HTTP.get('www.example.com', '/index.html')\n    #\n    def HTTP.get(uri_or_host, path = nil, port = nil)\n      get_response(uri_or_host, path, port).body\n    end\n\n    # Send a GET request to the target and return the response\n    # as a Net::HTTPResponse object.  The target can either be specified as\n    # (+uri+), or as (+host+, +path+, +port+ = 80); so:\n    # \n    #    res = Net::HTTP.get_response(URI.parse('http://www.example.com/index.html'))\n    #    print res.body\n    #\n    # or:\n    #\n    #    res = Net::HTTP.get_response('www.example.com', '/index.html')\n    #    print res.body\n    #\n    def HTTP.get_response(uri_or_host, path = nil, port = nil, &block)\n      if path\n        host = uri_or_host\n        new(host, port || HTTP.default_port).start {|http|\n          return http.request_get(path, &block)\n        }\n      else\n        uri = uri_or_host\n        new(uri.host, uri.port).start {|http|\n          return http.request_get(uri.request_uri, &block)\n        }\n      end\n    end\n\n    # Posts HTML form data to the +URL+.\n    # Form data must be represented as a Hash of String to String, e.g:\n    #\n    #   { \"cmd\" => \"search\", \"q\" => \"ruby\", \"max\" => \"50\" }\n    #\n    # This method also does Basic Authentication iff +URL+.user exists.\n    #\n    # Example:\n    #\n    #   require 'net/http'\n    #   require 'uri'\n    #\n    #   HTTP.post_form URI.parse('http://www.example.com/search.cgi'),\n    #                  { \"q\" => \"ruby\", \"max\" => \"50\" }\n    #\n    def HTTP.post_form(url, params)\n      req = Post.new(url.path)\n      req.form_data = params\n      req.basic_auth url.user, url.password if url.user\n      new(url.host, url.port).start {|http|\n        http.request(req)\n      }\n    end\n\n    #\n    # HTTP session management\n    #\n\n    # The default port to use for HTTP requests; defaults to 80.\n    def HTTP.default_port\n      http_default_port()\n    end\n\n    # The default port to use for HTTP requests; defaults to 80.\n    def HTTP.http_default_port\n      80\n    end\n\n    # The default port to use for HTTPS requests; defaults to 443.\n    def HTTP.https_default_port\n      443\n    end\n\n    def HTTP.socket_type   #:nodoc: obsolete\n      BufferedIO\n    end\n\n    # creates a new Net::HTTP object and opens its TCP connection and \n    # HTTP session.  If the optional block is given, the newly \n    # created Net::HTTP object is passed to it and closed when the \n    # block finishes.  In this case, the return value of this method\n    # is the return value of the block.  If no block is given, the\n    # return value of this method is the newly created Net::HTTP object\n    # itself, and the caller is responsible for closing it upon completion.\n    def HTTP.start(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil, &block) # :yield: +http+\n      new(address, port, p_addr, p_port, p_user, p_pass).start(&block)\n    end\n\n    class << HTTP\n      alias newobj new\n    end\n\n    # Creates a new Net::HTTP object.\n    # If +proxy_addr+ is given, creates an Net::HTTP object with proxy support.\n    # This method does not open the TCP connection.\n    def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)\n      h = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)\n      h.instance_eval {\n        @newimpl = ::Net::HTTP.version_1_2?\n      }\n      h\n    end\n\n    # Creates a new Net::HTTP object for the specified +address+.\n    # This method does not open the TCP connection.\n    def initialize(address, port = nil)\n      @address = address\n      @port    = (port || HTTP.default_port)\n      @curr_http_version = HTTPVersion\n      @seems_1_0_server = false\n      @close_on_empty_response = false\n      @socket  = nil\n      @started = false\n      @open_timeout = nil\n      @read_timeout = 60\n      @debug_output = nil\n      @use_ssl = false\n      @ssl_context = nil\n    end\n\n    def inspect\n      \"#<#{self.class} #{@address}:#{@port} open=#{started?}>\"\n    end\n\n    # *WARNING* This method causes serious security hole.\n    # Never use this method in production code.\n    #\n    # Set an output stream for debugging.\n    #\n    #   http = Net::HTTP.new\n    #   http.set_debug_output $stderr\n    #   http.start { .... }\n    #\n    def set_debug_output(output)\n      warn 'Net::HTTP#set_debug_output called after HTTP started' if started?\n      @debug_output = output\n    end\n\n    # The host name to connect to.\n    attr_reader :address\n\n    # The port number to connect to.\n    attr_reader :port\n\n    # Seconds to wait until connection is opened.\n    # If the HTTP object cannot open a connection in this many seconds,\n    # it raises a TimeoutError exception.\n    attr_accessor :open_timeout\n\n    # Seconds to wait until reading one block (by one read(2) call).\n    # If the HTTP object cannot open a connection in this many seconds,\n    # it raises a TimeoutError exception.\n    attr_reader :read_timeout\n\n    # Setter for the read_timeout attribute.\n    def read_timeout=(sec)\n      @socket.read_timeout = sec if @socket\n      @read_timeout = sec\n    end\n\n    # returns true if the HTTP session is started.\n    def started?\n      @started\n    end\n\n    alias active? started?   #:nodoc: obsolete\n\n    attr_accessor :close_on_empty_response\n\n    # returns true if use SSL/TLS with HTTP.\n    def use_ssl?\n      false   # redefined in net/https\n    end\n\n    # Opens TCP connection and HTTP session.\n    # \n    # When this method is called with block, gives a HTTP object\n    # to the block and closes the TCP connection / HTTP session\n    # after the block executed.\n    #\n    # When called with a block, returns the return value of the\n    # block; otherwise, returns self.\n    #\n    def start  # :yield: http\n      raise IOError, 'HTTP session already opened' if @started\n      if block_given?\n        begin\n          do_start\n          return yield(self)\n        ensure\n          do_finish\n        end\n      end\n      do_start\n      self\n    end\n\n    def do_start\n      connect\n      @started = true\n    end\n    private :do_start\n\n    def connect\n      D \"opening connection to #{conn_address()}...\"\n      s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }\n      D \"opened\"\n      if use_ssl?\n        unless @ssl_context.verify_mode\n          warn \"warning: peer certificate won't be verified in this SSL session\"\n          @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE\n        end\n        s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)\n        s.sync_close = true\n      end\n      @socket = BufferedIO.new(s)\n      @socket.read_timeout = @read_timeout\n      @socket.debug_output = @debug_output\n      if use_ssl?\n        if proxy?\n          @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',\n                                    @address, @port, HTTPVersion)\n          @socket.writeline \"Host: #{@address}:#{@port}\"\n          if proxy_user\n            credential = [\"#{proxy_user}:#{proxy_pass}\"].pack('m')\n            credential.delete!(\"\\r\\n\")\n            @socket.writeline \"Proxy-Authorization: Basic #{credential}\"\n          end\n          @socket.writeline ''\n          HTTPResponse.read_new(@socket).value\n        end\n        s.connect\n        if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE\n          s.post_connection_check(@address)\n        end\n      end\n      on_connect\n    end\n    private :connect\n\n    def on_connect\n    end\n    private :on_connect\n\n    # Finishes HTTP session and closes TCP connection.\n    # Raises IOError if not started.\n    def finish\n      raise IOError, 'HTTP session not yet started' unless started?\n      do_finish\n    end\n\n    def do_finish\n      @started = false\n      @socket.close if @socket and not @socket.closed?\n      @socket = nil\n    end\n    private :do_finish\n\n    #\n    # proxy\n    #\n\n    public\n\n    # no proxy\n    @is_proxy_class = false\n    @proxy_addr = nil\n    @proxy_port = nil\n    @proxy_user = nil\n    @proxy_pass = nil\n\n    # Creates an HTTP proxy class.\n    # Arguments are address/port of proxy host and username/password\n    # if authorization on proxy server is required.\n    # You can replace the HTTP class with created proxy class.\n    # \n    # If ADDRESS is nil, this method returns self (Net::HTTP).\n    # \n    #     # Example\n    #     proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080)\n    #                     :\n    #     proxy_class.start('www.ruby-lang.org') {|http|\n    #       # connecting proxy.foo.org:8080\n    #                     :\n    #     }\n    # \n    def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)\n      return self unless p_addr\n      delta = ProxyDelta\n      proxyclass = Class.new(self)\n      proxyclass.module_eval {\n        include delta\n        # with proxy\n        @is_proxy_class = true\n        @proxy_address = p_addr\n        @proxy_port    = p_port || default_port()\n        @proxy_user    = p_user\n        @proxy_pass    = p_pass\n      }\n      proxyclass\n    end\n\n    class << HTTP\n      # returns true if self is a class which was created by HTTP::Proxy.\n      def proxy_class?\n        @is_proxy_class\n      end\n\n      attr_reader :proxy_address\n      attr_reader :proxy_port\n      attr_reader :proxy_user\n      attr_reader :proxy_pass\n    end\n\n    # True if self is a HTTP proxy class.\n    def proxy?\n      self.class.proxy_class?\n    end\n\n    # Address of proxy host. If self does not use a proxy, nil.\n    def proxy_address\n      self.class.proxy_address\n    end\n\n    # Port number of proxy host. If self does not use a proxy, nil.\n    def proxy_port\n      self.class.proxy_port\n    end\n\n    # User name for accessing proxy. If self does not use a proxy, nil.\n    def proxy_user\n      self.class.proxy_user\n    end\n\n    # User password for accessing proxy. If self does not use a proxy, nil.\n    def proxy_pass\n      self.class.proxy_pass\n    end\n\n    alias proxyaddr proxy_address   #:nodoc: obsolete\n    alias proxyport proxy_port      #:nodoc: obsolete\n\n    private\n\n    # without proxy\n\n    def conn_address\n      address()\n    end\n\n    def conn_port\n      port()\n    end\n\n    def edit_path(path)\n      path\n    end\n\n    module ProxyDelta   #:nodoc: internal use only\n      private\n\n      def conn_address\n        proxy_address()\n      end\n\n      def conn_port\n        proxy_port()\n      end\n\n      def edit_path(path)\n        use_ssl? ? path : \"http://#{addr_port()}#{path}\"\n      end\n    end\n\n    #\n    # HTTP operations\n    #\n\n    public\n\n    # Gets data from +path+ on the connected-to host.\n    # +header+ must be a Hash like { 'Accept' => '*/*', ... }.\n    #\n    # In version 1.1 (ruby 1.6), this method returns a pair of objects,\n    # a Net::HTTPResponse object and the entity body string.\n    # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse\n    # object.\n    #\n    # If called with a block, yields each fragment of the\n    # entity body in turn as a string as it is read from\n    # the socket.  Note that in this case, the returned response\n    # object will *not* contain a (meaningful) body.\n    #\n    # +dest+ argument is obsolete.\n    # It still works but you must not use it.\n    #\n    # In version 1.1, this method might raise an exception for \n    # 3xx (redirect). In this case you can get a HTTPResponse object\n    # by \"anException.response\".\n    #\n    # In version 1.2, this method never raises exception.\n    #\n    #     # version 1.1 (bundled with Ruby 1.6)\n    #     response, body = http.get('/index.html')\n    #\n    #     # version 1.2 (bundled with Ruby 1.8 or later)\n    #     response = http.get('/index.html')\n    #     \n    #     # using block\n    #     File.open('result.txt', 'w') {|f|\n    #       http.get('/~foo/') do |str|\n    #         f.write str\n    #       end\n    #     }\n    #\n    def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+\n      res = nil\n      request(Get.new(path, initheader)) {|r|\n        r.read_body dest, &block\n        res = r\n      }\n      unless @newimpl\n        res.value\n        return res, res.body\n      end\n\n      res\n    end\n\n    # Gets only the header from +path+ on the connected-to host.\n    # +header+ is a Hash like { 'Accept' => '*/*', ... }.\n    # \n    # This method returns a Net::HTTPResponse object.\n    # \n    # In version 1.1, this method might raise an exception for \n    # 3xx (redirect). On the case you can get a HTTPResponse object\n    # by \"anException.response\".\n    # In version 1.2, this method never raises an exception.\n    # \n    #     response = nil\n    #     Net::HTTP.start('some.www.server', 80) {|http|\n    #       response = http.head('/index.html')\n    #     }\n    #     p response['content-type']\n    #\n    def head(path, initheader = nil) \n      res = request(Head.new(path, initheader))\n      res.value unless @newimpl\n      res\n    end\n\n    # Posts +data+ (must be a String) to +path+. +header+ must be a Hash\n    # like { 'Accept' => '*/*', ... }.\n    # \n    # In version 1.1 (ruby 1.6), this method returns a pair of objects, a\n    # Net::HTTPResponse object and an entity body string.\n    # In version 1.2 (ruby 1.8), this method returns a Net::HTTPResponse object.\n    # \n    # If called with a block, yields each fragment of the\n    # entity body in turn as a string as it are read from\n    # the socket.  Note that in this case, the returned response\n    # object will *not* contain a (meaningful) body.\n    #\n    # +dest+ argument is obsolete.\n    # It still works but you must not use it.\n    # \n    # In version 1.1, this method might raise an exception for \n    # 3xx (redirect). In this case you can get an HTTPResponse object\n    # by \"anException.response\".\n    # In version 1.2, this method never raises exception.\n    # \n    #     # version 1.1\n    #     response, body = http.post('/cgi-bin/search.rb', 'query=foo')\n    # \n    #     # version 1.2\n    #     response = http.post('/cgi-bin/search.rb', 'query=foo')\n    # \n    #     # using block\n    #     File.open('result.txt', 'w') {|f|\n    #       http.post('/cgi-bin/search.rb', 'query=foo') do |str|\n    #         f.write str\n    #       end\n    #     }\n    #\n    # You should set Content-Type: header field for POST.\n    # If no Content-Type: field given, this method uses\n    # \"application/x-www-form-urlencoded\" by default.\n    #\n    def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+\n      res = nil\n      request(Post.new(path, initheader), data) {|r|\n        r.read_body dest, &block\n        res = r\n      }\n      unless @newimpl\n        res.value\n        return res, res.body\n      end\n      res\n    end\n\n    def put(path, data, initheader = nil)   #:nodoc:\n      res = request(Put.new(path, initheader), data)\n      res.value unless @newimpl\n      res\n    end\n\n    # Sends a PROPPATCH request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def proppatch(path, body, initheader = nil)\n      request(Proppatch.new(path, initheader), body)\n    end\n\n    # Sends a LOCK request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def lock(path, body, initheader = nil)\n      request(Lock.new(path, initheader), body)\n    end\n\n    # Sends a UNLOCK request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def unlock(path, body, initheader = nil)\n      request(Unlock.new(path, initheader), body)\n    end\n\n    # Sends a OPTIONS request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def options(path, initheader = nil)\n      request(Options.new(path, initheader))\n    end\n\n    # Sends a PROPFIND request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def propfind(path, body = nil, initheader = {'Depth' => '0'})\n      request(Propfind.new(path, initheader), body)\n    end\n\n    # Sends a DELETE request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def delete(path, initheader = {'Depth' => 'Infinity'})\n      request(Delete.new(path, initheader))\n    end\n\n    # Sends a MOVE request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def move(path, initheader = nil)\n      request(Move.new(path, initheader))\n    end\n\n    # Sends a COPY request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def copy(path, initheader = nil)\n      request(Copy.new(path, initheader))\n    end\n\n    # Sends a MKCOL request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def mkcol(path, body = nil, initheader = nil)\n      request(Mkcol.new(path, initheader), body)\n    end\n\n    # Sends a TRACE request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    def trace(path, initheader = nil)\n      request(Trace.new(path, initheader))\n    end\n\n    # Sends a GET request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    # \n    # When called with a block, yields an HTTPResponse object.\n    # The body of this response will not have been read yet;\n    # the caller can process it using HTTPResponse#read_body,\n    # if desired.\n    #\n    # Returns the response.\n    # \n    # This method never raises Net::* exceptions.\n    # \n    #     response = http.request_get('/index.html')\n    #     # The entity body is already read here.\n    #     p response['content-type']\n    #     puts response.body\n    # \n    #     # using block\n    #     http.request_get('/index.html') {|response|\n    #       p response['content-type']\n    #       response.read_body do |str|   # read body now\n    #         print str\n    #       end\n    #     }\n    #\n    def request_get(path, initheader = nil, &block) # :yield: +response+\n      request(Get.new(path, initheader), &block)\n    end\n\n    # Sends a HEAD request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    #\n    # Returns the response.\n    # \n    # This method never raises Net::* exceptions.\n    # \n    #     response = http.request_head('/index.html')\n    #     p response['content-type']\n    #\n    def request_head(path, initheader = nil, &block)\n      request(Head.new(path, initheader), &block)\n    end\n\n    # Sends a POST request to the +path+ and gets a response,\n    # as an HTTPResponse object.\n    # \n    # When called with a block, yields an HTTPResponse object.\n    # The body of this response will not have been read yet;\n    # the caller can process it using HTTPResponse#read_body,\n    # if desired.\n    #\n    # Returns the response.\n    # \n    # This method never raises Net::* exceptions.\n    # \n    #     # example\n    #     response = http.request_post('/cgi-bin/nice.rb', 'datadatadata...')\n    #     p response.status\n    #     puts response.body          # body is already read\n    # \n    #     # using block\n    #     http.request_post('/cgi-bin/nice.rb', 'datadatadata...') {|response|\n    #       p response.status\n    #       p response['content-type']\n    #       response.read_body do |str|   # read body now\n    #         print str\n    #       end\n    #     }\n    #\n    def request_post(path, data, initheader = nil, &block) # :yield: +response+\n      request Post.new(path, initheader), data, &block\n    end\n\n    def request_put(path, data, initheader = nil, &block)   #:nodoc:\n      request Put.new(path, initheader), data, &block\n    end\n\n    alias get2   request_get    #:nodoc: obsolete\n    alias head2  request_head   #:nodoc: obsolete\n    alias post2  request_post   #:nodoc: obsolete\n    alias put2   request_put    #:nodoc: obsolete\n\n\n    # Sends an HTTP request to the HTTP server.\n    # This method also sends DATA string if DATA is given.\n    #\n    # Returns a HTTPResponse object.\n    # \n    # This method never raises Net::* exceptions.\n    #\n    #    response = http.send_request('GET', '/index.html')\n    #    puts response.body\n    #\n    def send_request(name, path, data = nil, header = nil)\n      r = HTTPGenericRequest.new(name,(data ? true : false),true,path,header)\n      request r, data\n    end\n\n    # Sends an HTTPRequest object REQUEST to the HTTP server.\n    # This method also sends DATA string if REQUEST is a post/put request.\n    # Giving DATA for get/head request causes ArgumentError.\n    # \n    # When called with a block, yields an HTTPResponse object.\n    # The body of this response will not have been read yet;\n    # the caller can process it using HTTPResponse#read_body,\n    # if desired.\n    #\n    # Returns a HTTPResponse object.\n    # \n    # This method never raises Net::* exceptions.\n    #\n    def request(req, body = nil, &block)  # :yield: +response+\n      unless started?\n        start {\n          req['connection'] ||= 'close'\n          return request(req, body, &block)\n        }\n      end\n      if proxy_user()\n        unless use_ssl?\n          req.proxy_basic_auth proxy_user(), proxy_pass()\n        end\n      end\n\n      req.set_body_internal body\n      begin\n        begin_transport req\n        req.exec @socket, @curr_http_version, edit_path(req.path)\n        begin\n          res = HTTPResponse.read_new(@socket)\n        end while res.kind_of?(HTTPContinue)\n        res.reading_body(@socket, req.response_body_permitted?) {\n          yield res if block_given?\n        }\n        end_transport req, res\n      rescue => exception\n        D \"Conn close because of error #{exception}\"\n        @socket.close unless @socket.closed?\n        raise exception\n      end\n\n      res\n    end\n\n    private\n\n    def begin_transport(req)\n      if @socket.closed?\n        connect\n      end\n      if @seems_1_0_server\n        req['connection'] ||= 'close'\n      end\n      if not req.response_body_permitted? and @close_on_empty_response\n        req['connection'] ||= 'close'\n      end\n      req['host'] ||= addr_port()\n    end\n\n    def end_transport(req, res)\n      @curr_http_version = res.http_version\n      if not res.body and @close_on_empty_response\n        D 'Conn close'\n        @socket.close\n      elsif keep_alive?(req, res)\n        D 'Conn keep-alive'\n        if @socket.closed?\n          D 'Conn (but seems 1.0 server)'\n          @seems_1_0_server = true\n        end\n      else\n        D 'Conn close'\n        @socket.close\n      end\n    end\n\n    def keep_alive?(req, res)\n      return false if /close/i =~ req['connection'].to_s\n      return false if @seems_1_0_server\n      return true  if /keep-alive/i =~ res['connection'].to_s\n      return false if /close/i      =~ res['connection'].to_s\n      return true  if /keep-alive/i =~ res['proxy-connection'].to_s\n      return false if /close/i      =~ res['proxy-connection'].to_s\n      (@curr_http_version == '1.1')\n    end\n\n    #\n    # utils\n    #\n\n    private\n\n    def addr_port\n      if use_ssl?\n        address() + (port == HTTP.https_default_port ? '' : \":#{port()}\")\n      else\n        address() + (port == HTTP.http_default_port ? '' : \":#{port()}\")\n      end\n    end\n\n    def D(msg)\n      return unless @debug_output\n      @debug_output << msg\n      @debug_output << \"\\n\"\n    end\n\n  end\n\n  HTTPSession = HTTP\n\n\n  #\n  # Header module.\n  #\n  # Provides access to @header in the mixed-into class as a hash-like\n  # object, except with case-insensitive keys.  Also provides\n  # methods for accessing commonly-used header values in a more\n  # convenient format.\n  #\n  module HTTPHeader\n\n    def initialize_http_header(initheader)\n      @header = {}\n      return unless initheader\n      initheader.each do |key, value|\n        warn \"net/http: warning: duplicated HTTP header: #{key}\" if key?(key) and $VERBOSE\n        @header[key.downcase] = [value.strip]\n      end\n    end\n\n    def size   #:nodoc: obsolete\n      @header.size\n    end\n\n    alias length size   #:nodoc: obsolete\n\n    # Returns the header field corresponding to the case-insensitive key.\n    # For example, a key of \"Content-Type\" might return \"text/html\"\n    def [](key)\n      a = @header[key.downcase] or return nil\n      a.join(', ')\n    end\n\n    # Sets the header field corresponding to the case-insensitive key.\n    def []=(key, val)\n      unless val\n        @header.delete key.downcase\n        return val\n      end\n      @header[key.downcase] = [val]\n    end\n\n    # [Ruby 1.8.3]\n    # Adds header field instead of replace.\n    # Second argument +val+ must be a String.\n    # See also #[]=, #[] and #get_fields.\n    #\n    #   request.add_field 'X-My-Header', 'a'\n    #   p request['X-My-Header']              #=> \"a\"\n    #   p request.get_fields('X-My-Header')   #=> [\"a\"]\n    #   request.add_field 'X-My-Header', 'b'\n    #   p request['X-My-Header']              #=> \"a, b\"\n    #   p request.get_fields('X-My-Header')   #=> [\"a\", \"b\"]\n    #   request.add_field 'X-My-Header', 'c'\n    #   p request['X-My-Header']              #=> \"a, b, c\"\n    #   p request.get_fields('X-My-Header')   #=> [\"a\", \"b\", \"c\"]\n    #\n    def add_field(key, val)\n      if @header.key?(key.downcase)\n        @header[key.downcase].push val\n      else\n        @header[key.downcase] = [val]\n      end\n    end\n\n    # [Ruby 1.8.3]\n    # Returns an array of header field strings corresponding to the\n    # case-insensitive +key+.  This method allows you to get duplicated\n    # header fields without any processing.  See also #[].\n    #\n    #   p response.get_fields('Set-Cookie')\n    #     #=> [\"session=al98axx; expires=Fri, 31-Dec-1999 23:58:23\",\n    #          \"query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23\"]\n    #   p response['Set-Cookie']\n    #     #=> \"session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23\"\n    #\n    def get_fields(key)\n      return nil unless @header[key.downcase]\n      @header[key.downcase].dup\n    end\n\n    # Returns the header field corresponding to the case-insensitive key.\n    # Returns the default value +args+, or the result of the block, or nil,\n    # if there's no header field named key.  See Hash#fetch\n    def fetch(key, *args, &block)   #:yield: +key+\n      a = @header.fetch(key.downcase, *args, &block)\n      a.join(', ')\n    end\n\n    # Iterates for each header names and values.\n    def each_header   #:yield: +key+, +value+\n      @header.each do |k,va|\n        yield k, va.join(', ')\n      end\n    end\n\n    alias each each_header\n\n    # Iterates for each header names.\n    def each_name(&block)   #:yield: +key+\n      @header.each_key(&block)\n    end\n\n    alias each_key each_name\n\n    # Iterates for each capitalized header names.\n    def each_capitalized_name(&block)   #:yield: +key+\n      @header.each_key do |k|\n        yield capitalize(k)\n      end\n    end\n\n    # Iterates for each header values.\n    def each_value   #:yield: +value+\n      @header.each_value do |va|\n        yield va.join(', ')\n      end\n    end\n\n    # Removes a header field.\n    def delete(key)\n      @header.delete(key.downcase)\n    end\n\n    # true if +key+ header exists.\n    def key?(key)\n      @header.key?(key.downcase)\n    end\n\n    # Returns a Hash consist of header names and values.\n    def to_hash\n      @header.dup\n    end\n\n    # As for #each_header, except the keys are provided in capitalized form.\n    def each_capitalized\n      @header.each do |k,v|\n        yield capitalize(k), v.join(', ')\n      end\n    end\n\n    alias canonical_each each_capitalized\n\n    def capitalize(name)\n      name.split(/-/).map {|s| s.capitalize }.join('-')\n    end\n    private :capitalize\n\n    # Returns an Array of Range objects which represents Range: header field,\n    # or +nil+ if there is no such header.\n    def range\n      return nil unless @header['range']\n      self['Range'].split(/,/).map {|spec|\n        m = /bytes\\s*=\\s*(\\d+)?\\s*-\\s*(\\d+)?/i.match(spec) or\n                raise HTTPHeaderSyntaxError, \"wrong Range: #{spec}\"\n        d1 = m[1].to_i\n        d2 = m[2].to_i\n        if    m[1] and m[2] then  d1..d2\n        elsif m[1]          then  d1..-1\n        elsif          m[2] then -d2..-1\n        else\n          raise HTTPHeaderSyntaxError, 'range is not specified'\n        end\n      }\n    end\n\n    # Set Range: header from Range (arg r) or beginning index and\n    # length from it (arg idx&len).\n    #\n    #   req.range = (0..1023)\n    #   req.set_range 0, 1023\n    #\n    def set_range(r, e = nil)\n      unless r\n        @header.delete 'range'\n        return r\n      end\n      r = (r...r+e) if e\n      case r\n      when Numeric\n        n = r.to_i\n        rangestr = (n > 0 ? \"0-#{n-1}\" : \"-#{-n}\")\n      when Range\n        first = r.first\n        last = r.last\n        last -= 1 if r.exclude_end?\n        if last == -1\n          rangestr = (first > 0 ? \"#{first}-\" : \"-#{-first}\")\n        else\n          raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0\n          raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0\n          raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last\n          rangestr = \"#{first}-#{last}\"\n        end\n      else\n        raise TypeError, 'Range/Integer is required'\n      end\n      @header['range'] = [\"bytes=#{rangestr}\"]\n      r\n    end\n\n    alias range= set_range\n\n    # Returns an Integer object which represents the Content-Length: header field\n    # or +nil+ if that field is not provided.\n    def content_length\n      return nil unless key?('Content-Length')\n      len = self['Content-Length'].slice(/\\d+/) or\n          raise HTTPHeaderSyntaxError, 'wrong Content-Length format'\n      len.to_i\n    end\n    \n    def content_length=(len)\n      unless len\n        @header.delete 'content-length'\n        return nil\n      end\n      @header['content-length'] = [len.to_i.to_s]\n    end\n\n    # Returns \"true\" if the \"transfer-encoding\" header is present and\n    # set to \"chunked\".  This is an HTTP/1.1 feature, allowing the \n    # the content to be sent in \"chunks\" without at the outset\n    # stating the entire content length.\n    def chunked?\n      return false unless @header['transfer-encoding']\n      field = self['Transfer-Encoding']\n      (/(?:\\A|[^\\-\\w])chunked(?![\\-\\w])/i =~ field) ? true : false\n    end\n\n    # Returns a Range object which represents Content-Range: header field.\n    # This indicates, for a partial entity body, where this fragment\n    # fits inside the full entity body, as range of byte offsets.\n    def content_range\n      return nil unless @header['content-range']\n      m = %r<bytes\\s+(\\d+)-(\\d+)/(\\d+|\\*)>i.match(self['Content-Range']) or\n          raise HTTPHeaderSyntaxError, 'wrong Content-Range format'\n      m[1].to_i .. m[2].to_i + 1\n    end\n\n    # The length of the range represented in Content-Range: header.\n    def range_length\n      r = content_range() or return nil\n      r.end - r.begin\n    end\n\n    # Returns a content type string such as \"text/html\".\n    # This method returns nil if Content-Type: header field does not exist.\n    def content_type\n      return nil unless main_type()\n      if sub_type()\n      then \"#{main_type()}/#{sub_type()}\"\n      else main_type()\n      end\n    end\n\n    # Returns a content type string such as \"text\".\n    # This method returns nil if Content-Type: header field does not exist.\n    def main_type\n      return nil unless @header['content-type']\n      self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip\n    end\n    \n    # Returns a content type string such as \"html\".\n    # This method returns nil if Content-Type: header field does not exist\n    # or sub-type is not given (e.g. \"Content-Type: text\").\n    def sub_type\n      return nil unless @header['content-type']\n      main, sub = *self['Content-Type'].split(';').first.to_s.split('/')\n      return nil unless sub\n      sub.strip\n    end\n\n    # Returns content type parameters as a Hash as like\n    # {\"charset\" => \"iso-2022-jp\"}.\n    def type_params\n      result = {}\n      list = self['Content-Type'].to_s.split(';')\n      list.shift\n      list.each do |param|\n        k, v = *param.split('=', 2)\n        result[k.strip] = v.strip\n      end\n      result\n    end\n\n    # Set Content-Type: header field by +type+ and +params+.\n    # +type+ must be a String, +params+ must be a Hash.\n    def set_content_type(type, params = {})\n      @header['content-type'] = [type + params.map{|k,v|\"; #{k}=#{v}\"}.join('')]\n    end\n\n    alias content_type= set_content_type\n\n    # Set header fields and a body from HTML form data.\n    # +params+ should be a Hash containing HTML form data.\n    # Optional argument +sep+ means data record separator.\n    #\n    # This method also set Content-Type: header field to\n    # application/x-www-form-urlencoded.\n    def set_form_data(params, sep = '&')\n      self.body = params.map {|k,v| \"#{urlencode(k.to_s)}=#{urlencode(v.to_s)}\" }.join(sep)\n      self.content_type = 'application/x-www-form-urlencoded'\n    end\n\n    alias form_data= set_form_data\n\n    def urlencode(str)\n      str.gsub(/[^a-zA-Z0-9_\\.\\-]/n) {|s| sprintf('%%%02x', s[0]) }\n    end\n    private :urlencode\n\n    # Set the Authorization: header for \"Basic\" authorization.\n    def basic_auth(account, password)\n      @header['authorization'] = [basic_encode(account, password)]\n    end\n\n    # Set Proxy-Authorization: header for \"Basic\" authorization.\n    def proxy_basic_auth(account, password)\n      @header['proxy-authorization'] = [basic_encode(account, password)]\n    end\n\n    def basic_encode(account, password)\n      'Basic ' + [\"#{account}:#{password}\"].pack('m').delete(\"\\r\\n\")\n    end\n    private :basic_encode\n\n  end\n\n\n  #\n  # Parent of HTTPRequest class.  Do not use this directly; use\n  # a subclass of HTTPRequest.\n  #\n  # Mixes in the HTTPHeader module.\n  #\n  class HTTPGenericRequest\n\n    include HTTPHeader\n\n    def initialize(m, reqbody, resbody, path, initheader = nil)\n      @method = m\n      @request_has_body = reqbody\n      @response_has_body = resbody\n      raise ArgumentError, \"HTTP request path is empty\" if path.empty?\n      @path = path\n      initialize_http_header initheader\n      self['Accept'] ||= '*/*'\n      @body = nil\n      @body_stream = nil\n    end\n\n    attr_reader :method\n    attr_reader :path\n\n    def inspect\n      \"\\#<#{self.class} #{@method}>\"\n    end\n\n    def request_body_permitted?\n      @request_has_body\n    end\n\n    def response_body_permitted?\n      @response_has_body\n    end\n\n    def body_exist?\n      warn \"Net::HTTPRequest#body_exist? is obsolete; use response_body_permitted?\" if $VERBOSE\n      response_body_permitted?\n    end\n\n    attr_reader :body\n\n    def body=(str)\n      @body = str\n      @body_stream = nil\n      str\n    end\n\n    attr_reader :body_stream\n\n    def body_stream=(input)\n      @body = nil\n      @body_stream = input\n      input\n    end\n\n    def set_body_internal(str)   #:nodoc: internal use only\n      raise ArgumentError, \"both of body argument and HTTPRequest#body set\" if str and (@body or @body_stream)\n      self.body = str if str\n    end\n\n    #\n    # write\n    #\n\n    def exec(sock, ver, path)   #:nodoc: internal use only\n      if @body\n        send_request_with_body sock, ver, path, @body\n      elsif @body_stream\n        send_request_with_body_stream sock, ver, path, @body_stream\n      else\n        write_header sock, ver, path\n      end\n    end\n\n    private\n\n    def send_request_with_body(sock, ver, path, body)\n      self.content_length = body.length\n      delete 'Transfer-Encoding'\n      supply_default_content_type\n      write_header sock, ver, path\n      sock.write body\n    end\n\n    def send_request_with_body_stream(sock, ver, path, f)\n      unless content_length() or chunked?\n        raise ArgumentError,\n            \"Content-Length not given and Transfer-Encoding is not `chunked'\"\n      end\n      supply_default_content_type\n      write_header sock, ver, path\n      if chunked?\n        while s = f.read(1024)\n          sock.write(sprintf(\"%x\\r\\n\", s.length) << s << \"\\r\\n\")\n        end\n        sock.write \"0\\r\\n\\r\\n\"\n      else\n        while s = f.read(1024)\n          sock.write s\n        end\n      end\n    end\n\n    def supply_default_content_type\n      return if content_type()\n      warn 'net/http: warning: Content-Type did not set; using application/x-www-form-urlencoded' if $VERBOSE\n      set_content_type 'application/x-www-form-urlencoded'\n    end\n\n    def write_header(sock, ver, path)\n      buf = \"#{@method} #{path} HTTP/#{ver}\\r\\n\"\n      each_capitalized do |k,v|\n        buf << \"#{k}: #{v}\\r\\n\"\n      end\n      buf << \"\\r\\n\"\n      sock.write buf\n    end\n  \n  end\n\n\n  # \n  # HTTP request class. This class wraps request header and entity path.\n  # You *must* use its subclass, Net::HTTP::Get, Post, Head.\n  # \n  class HTTPRequest < HTTPGenericRequest\n\n    # Creates HTTP request object.\n    def initialize(path, initheader = nil)\n      super self.class::METHOD,\n            self.class::REQUEST_HAS_BODY,\n            self.class::RESPONSE_HAS_BODY,\n            path, initheader\n    end\n  end\n\n\n  class HTTP   # reopen\n    #\n    # HTTP 1.1 methods --- RFC2616\n    #\n\n    class Get < HTTPRequest\n      METHOD = 'GET'\n      REQUEST_HAS_BODY  = false\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Head < HTTPRequest\n      METHOD = 'HEAD'\n      REQUEST_HAS_BODY = false\n      RESPONSE_HAS_BODY = false\n    end\n\n    class Post < HTTPRequest\n      METHOD = 'POST'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Put < HTTPRequest\n      METHOD = 'PUT'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Delete < HTTPRequest\n      METHOD = 'DELETE'\n      REQUEST_HAS_BODY = false\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Options < HTTPRequest\n      METHOD = 'OPTIONS'\n      REQUEST_HAS_BODY = false\n      RESPONSE_HAS_BODY = false\n    end\n\n    class Trace < HTTPRequest\n      METHOD = 'TRACE'\n      REQUEST_HAS_BODY = false\n      RESPONSE_HAS_BODY = true\n    end\n\n    #\n    # WebDAV methods --- RFC2518\n    #\n\n    class Propfind < HTTPRequest\n      METHOD = 'PROPFIND'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Proppatch < HTTPRequest\n      METHOD = 'PROPPATCH'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Mkcol < HTTPRequest\n      METHOD = 'MKCOL'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Copy < HTTPRequest\n      METHOD = 'COPY'\n      REQUEST_HAS_BODY = false\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Move < HTTPRequest\n      METHOD = 'MOVE'\n      REQUEST_HAS_BODY = false\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Lock < HTTPRequest\n      METHOD = 'LOCK'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n\n    class Unlock < HTTPRequest\n      METHOD = 'UNLOCK'\n      REQUEST_HAS_BODY = true\n      RESPONSE_HAS_BODY = true\n    end\n  end\n\n\n  ###\n  ### Response\n  ###\n\n  # HTTP exception class.\n  # You must use its subclasses.\n  module HTTPExceptions\n    def initialize(msg, res)   #:nodoc:\n      super msg\n      @response = res\n    end\n    attr_reader :response\n    alias data response    #:nodoc: obsolete\n  end\n  class HTTPError < ProtocolError\n    include HTTPExceptions\n  end\n  class HTTPRetriableError < ProtoRetriableError\n    include HTTPExceptions\n  end\n  class HTTPServerException < ProtoServerError\n    # We cannot use the name \"HTTPServerError\", it is the name of the response.\n    include HTTPExceptions\n  end\n  class HTTPFatalError < ProtoFatalError\n    include HTTPExceptions\n  end\n\n\n  # HTTP response class. This class wraps response header and entity.\n  # Mixes in the HTTPHeader module, which provides access to response\n  # header values both via hash-like methods and individual readers.\n  # Note that each possible HTTP response code defines its own \n  # HTTPResponse subclass.  These are listed below.\n  # All classes are\n  # defined under the Net module. Indentation indicates inheritance.\n  # \n  #   xxx        HTTPResponse\n  # \n  #     1xx        HTTPInformation\n  #       100        HTTPContinue    \n  #       101        HTTPSwitchProtocol\n  # \n  #     2xx        HTTPSuccess\n  #       200        HTTPOK\n  #       201        HTTPCreated\n  #       202        HTTPAccepted\n  #       203        HTTPNonAuthoritativeInformation\n  #       204        HTTPNoContent\n  #       205        HTTPResetContent\n  #       206        HTTPPartialContent\n  # \n  #     3xx        HTTPRedirection\n  #       300        HTTPMultipleChoice\n  #       301        HTTPMovedPermanently\n  #       302        HTTPFound\n  #       303        HTTPSeeOther\n  #       304        HTTPNotModified\n  #       305        HTTPUseProxy\n  #       307        HTTPTemporaryRedirect\n  # \n  #     4xx        HTTPClientError\n  #       400        HTTPBadRequest\n  #       401        HTTPUnauthorized\n  #       402        HTTPPaymentRequired\n  #       403        HTTPForbidden\n  #       404        HTTPNotFound\n  #       405        HTTPMethodNotAllowed\n  #       406        HTTPNotAcceptable\n  #       407        HTTPProxyAuthenticationRequired\n  #       408        HTTPRequestTimeOut\n  #       409        HTTPConflict\n  #       410        HTTPGone\n  #       411        HTTPLengthRequired\n  #       412        HTTPPreconditionFailed\n  #       413        HTTPRequestEntityTooLarge\n  #       414        HTTPRequestURITooLong\n  #       415        HTTPUnsupportedMediaType\n  #       416        HTTPRequestedRangeNotSatisfiable\n  #       417        HTTPExpectationFailed\n  # \n  #     5xx        HTTPServerError\n  #       500        HTTPInternalServerError\n  #       501        HTTPNotImplemented\n  #       502        HTTPBadGateway\n  #       503        HTTPServiceUnavailable\n  #       504        HTTPGatewayTimeOut\n  #       505        HTTPVersionNotSupported\n  # \n  #     xxx        HTTPUnknownResponse\n  #\n  class HTTPResponse\n    # true if the response has body.\n    def HTTPResponse.body_permitted?\n      self::HAS_BODY\n    end\n\n    def HTTPResponse.exception_type   # :nodoc: internal use only\n      self::EXCEPTION_TYPE\n    end\n  end   # reopened after\n\n  # :stopdoc:\n\n  class HTTPUnknownResponse < HTTPResponse\n    HAS_BODY = true\n    EXCEPTION_TYPE = HTTPError\n  end\n  class HTTPInformation < HTTPResponse           # 1xx\n    HAS_BODY = false\n    EXCEPTION_TYPE = HTTPError\n  end\n  class HTTPSuccess < HTTPResponse               # 2xx\n    HAS_BODY = true\n    EXCEPTION_TYPE = HTTPError\n  end\n  class HTTPRedirection < HTTPResponse           # 3xx\n    HAS_BODY = true\n    EXCEPTION_TYPE = HTTPRetriableError\n  end\n  class HTTPClientError < HTTPResponse           # 4xx\n    HAS_BODY = true\n    EXCEPTION_TYPE = HTTPServerException   # for backward compatibility\n  end\n  class HTTPServerError < HTTPResponse           # 5xx\n    HAS_BODY = true\n    EXCEPTION_TYPE = HTTPFatalError    # for backward compatibility\n  end\n\n  class HTTPContinue < HTTPInformation           # 100\n    HAS_BODY = false\n  end\n  class HTTPSwitchProtocol < HTTPInformation     # 101\n    HAS_BODY = false\n  end\n\n  class HTTPOK < HTTPSuccess                            # 200\n    HAS_BODY = true\n  end\n  class HTTPCreated < HTTPSuccess                       # 201\n    HAS_BODY = true\n  end\n  class HTTPAccepted < HTTPSuccess                      # 202\n    HAS_BODY = true\n  end\n  class HTTPNonAuthoritativeInformation < HTTPSuccess   # 203\n    HAS_BODY = true\n  end\n  class HTTPNoContent < HTTPSuccess                     # 204\n    HAS_BODY = false\n  end\n  class HTTPResetContent < HTTPSuccess                  # 205\n    HAS_BODY = false\n  end\n  class HTTPPartialContent < HTTPSuccess                # 206\n    HAS_BODY = true\n  end\n\n  class HTTPMultipleChoice < HTTPRedirection     # 300\n    HAS_BODY = true\n  end\n  class HTTPMovedPermanently < HTTPRedirection   # 301\n    HAS_BODY = true\n  end\n  class HTTPFound < HTTPRedirection              # 302\n    HAS_BODY = true\n  end\n  HTTPMovedTemporarily = HTTPFound\n  class HTTPSeeOther < HTTPRedirection           # 303\n    HAS_BODY = true\n  end\n  class HTTPNotModified < HTTPRedirection        # 304\n    HAS_BODY = false\n  end\n  class HTTPUseProxy < HTTPRedirection           # 305\n    HAS_BODY = false\n  end\n  # 306 unused\n  class HTTPTemporaryRedirect < HTTPRedirection  # 307\n    HAS_BODY = true\n  end\n\n  class HTTPBadRequest < HTTPClientError                    # 400\n    HAS_BODY = true\n  end\n  class HTTPUnauthorized < HTTPClientError                  # 401\n    HAS_BODY = true\n  end\n  class HTTPPaymentRequired < HTTPClientError               # 402\n    HAS_BODY = true\n  end\n  class HTTPForbidden < HTTPClientError                     # 403\n    HAS_BODY = true\n  end\n  class HTTPNotFound < HTTPClientError                      # 404\n    HAS_BODY = true\n  end\n  class HTTPMethodNotAllowed < HTTPClientError              # 405\n    HAS_BODY = true\n  end\n  class HTTPNotAcceptable < HTTPClientError                 # 406\n    HAS_BODY = true\n  end\n  class HTTPProxyAuthenticationRequired < HTTPClientError   # 407\n    HAS_BODY = true\n  end\n  class HTTPRequestTimeOut < HTTPClientError                # 408\n    HAS_BODY = true\n  end\n  class HTTPConflict < HTTPClientError                      # 409\n    HAS_BODY = true\n  end\n  class HTTPGone < HTTPClientError                          # 410\n    HAS_BODY = true\n  end\n  class HTTPLengthRequired < HTTPClientError                # 411\n    HAS_BODY = true\n  end\n  class HTTPPreconditionFailed < HTTPClientError            # 412\n    HAS_BODY = true\n  end\n  class HTTPRequestEntityTooLarge < HTTPClientError         # 413\n    HAS_BODY = true\n  end\n  class HTTPRequestURITooLong < HTTPClientError             # 414\n    HAS_BODY = true\n  end\n  HTTPRequestURITooLarge = HTTPRequestURITooLong\n  class HTTPUnsupportedMediaType < HTTPClientError          # 415\n    HAS_BODY = true\n  end\n  class HTTPRequestedRangeNotSatisfiable < HTTPClientError  # 416\n    HAS_BODY = true\n  end\n  class HTTPExpectationFailed < HTTPClientError             # 417\n    HAS_BODY = true\n  end\n\n  class HTTPInternalServerError < HTTPServerError   # 500\n    HAS_BODY = true\n  end\n  class HTTPNotImplemented < HTTPServerError        # 501\n    HAS_BODY = true\n  end\n  class HTTPBadGateway < HTTPServerError            # 502\n    HAS_BODY = true\n  end\n  class HTTPServiceUnavailable < HTTPServerError    # 503\n    HAS_BODY = true\n  end\n  class HTTPGatewayTimeOut < HTTPServerError        # 504\n    HAS_BODY = true\n  end\n  class HTTPVersionNotSupported < HTTPServerError   # 505\n    HAS_BODY = true\n  end\n\n  # :startdoc:\n\n\n  class HTTPResponse   # reopen\n\n    CODE_CLASS_TO_OBJ = {\n      '1' => HTTPInformation,\n      '2' => HTTPSuccess,\n      '3' => HTTPRedirection,\n      '4' => HTTPClientError,\n      '5' => HTTPServerError\n    }\n    CODE_TO_OBJ = {\n      '100' => HTTPContinue,\n      '101' => HTTPSwitchProtocol,\n\n      '200' => HTTPOK,\n      '201' => HTTPCreated,\n      '202' => HTTPAccepted,\n      '203' => HTTPNonAuthoritativeInformation,\n      '204' => HTTPNoContent,\n      '205' => HTTPResetContent,\n      '206' => HTTPPartialContent,\n\n      '300' => HTTPMultipleChoice,\n      '301' => HTTPMovedPermanently,\n      '302' => HTTPFound,\n      '303' => HTTPSeeOther,\n      '304' => HTTPNotModified,\n      '305' => HTTPUseProxy,\n      '307' => HTTPTemporaryRedirect,\n\n      '400' => HTTPBadRequest,\n      '401' => HTTPUnauthorized,\n      '402' => HTTPPaymentRequired,\n      '403' => HTTPForbidden,\n      '404' => HTTPNotFound,\n      '405' => HTTPMethodNotAllowed,\n      '406' => HTTPNotAcceptable,\n      '407' => HTTPProxyAuthenticationRequired,\n      '408' => HTTPRequestTimeOut,\n      '409' => HTTPConflict,\n      '410' => HTTPGone,\n      '411' => HTTPLengthRequired,\n      '412' => HTTPPreconditionFailed,\n      '413' => HTTPRequestEntityTooLarge,\n      '414' => HTTPRequestURITooLong,\n      '415' => HTTPUnsupportedMediaType,\n      '416' => HTTPRequestedRangeNotSatisfiable,\n      '417' => HTTPExpectationFailed,\n\n      '500' => HTTPInternalServerError,\n      '501' => HTTPNotImplemented,\n      '502' => HTTPBadGateway,\n      '503' => HTTPServiceUnavailable,\n      '504' => HTTPGatewayTimeOut,\n      '505' => HTTPVersionNotSupported\n    }\n\n    class << HTTPResponse\n      def read_new(sock)   #:nodoc: internal use only\n        httpv, code, msg = read_status_line(sock)\n        res = response_class(code).new(httpv, code, msg)\n        each_response_header(sock) do |k,v|\n          res.add_field k, v\n        end\n        res\n      end\n\n      private\n\n      def read_status_line(sock)\n        str = sock.readline\n        m = /\\AHTTP(?:\\/(\\d+\\.\\d+))?\\s+(\\d\\d\\d)\\s*(.*)\\z/in.match(str) or\n          raise HTTPBadResponse, \"wrong status line: #{str.dump}\"\n        m.captures\n      end\n\n      def response_class(code)\n        CODE_TO_OBJ[code] or\n        CODE_CLASS_TO_OBJ[code[0,1]] or\n        HTTPUnknownResponse\n      end\n\n      def each_response_header(sock)\n        while true\n          line = sock.readuntil(\"\\n\", true).sub(/\\s+\\z/, '')\n          break if line.empty?\n          m = /\\A([^:]+):\\s*/.match(line) or\n              raise HTTPBadResponse, 'wrong header line format'\n          yield m[1], m.post_match\n        end\n      end\n    end\n\n    # next is to fix bug in RDoc, where the private inside class << self\n    # spills out.\n    public \n\n    include HTTPHeader\n\n    def initialize(httpv, code, msg)   #:nodoc: internal use only\n      @http_version = httpv\n      @code         = code\n      @message      = msg\n      initialize_http_header nil\n      @body = nil\n      @read = false\n    end\n\n    # The HTTP version supported by the server.\n    attr_reader :http_version\n\n    # HTTP result code string. For example, '302'.  You can also\n    # determine the response type by which response subclass the\n    # response object is an instance of.\n    attr_reader :code\n\n    # HTTP result message. For example, 'Not Found'.\n    attr_reader :message\n    alias msg message   # :nodoc: obsolete\n\n    def inspect\n      \"#<#{self.class} #{@code} #{@message} readbody=#{@read}>\"\n    end\n\n    # For backward compatibility.\n    # To allow Net::HTTP 1.1 style assignment\n    # e.g.\n    #    response, body = Net::HTTP.get(....)\n    # \n    def to_ary\n      warn \"net/http.rb: warning: Net::HTTP v1.1 style assignment found at #{caller(1)[0]}; use `response = http.get(...)' instead.\" if $VERBOSE\n      res = self.dup\n      class << res\n        undef to_ary\n      end\n      [res, res.body]\n    end\n\n    #\n    # response <-> exception relationship\n    #\n\n    def code_type   #:nodoc:\n      self.class\n    end\n\n    def error!   #:nodoc:\n      raise error_type().new(@code + ' ' + @message.dump, self)\n    end\n\n    def error_type   #:nodoc:\n      self.class::EXCEPTION_TYPE\n    end\n\n    # Raises HTTP error if the response is not 2xx.\n    def value\n      error! unless self.kind_of?(HTTPSuccess)\n    end\n\n    #\n    # header (for backward compatibility only; DO NOT USE)\n    #\n\n    def response   #:nodoc:\n      warn \"#{caller(1)[0]}: warning: HTTPResponse#response is obsolete\" if $VERBOSE\n      self\n    end\n\n    def header   #:nodoc:\n      warn \"#{caller(1)[0]}: warning: HTTPResponse#header is obsolete\" if $VERBOSE\n      self\n    end\n\n    def read_header   #:nodoc:\n      warn \"#{caller(1)[0]}: warning: HTTPResponse#read_header is obsolete\" if $VERBOSE\n      self\n    end\n\n    #\n    # body\n    #\n\n    def reading_body(sock, reqmethodallowbody)  #:nodoc: internal use only\n      @socket = sock\n      @body_exist = reqmethodallowbody && self.class.body_permitted?\n      begin\n        yield\n        self.body   # ensure to read body\n      ensure\n        @socket = nil\n      end\n    end\n\n    # Gets entity body.  If the block given, yields it to +block+.\n    # The body is provided in fragments, as it is read in from the socket.\n    #\n    # Calling this method a second or subsequent time will return the\n    # already read string.\n    #\n    #   http.request_get('/index.html') {|res|\n    #     puts res.read_body\n    #   }\n    #\n    #   http.request_get('/index.html') {|res|\n    #     p res.read_body.object_id   # 538149362\n    #     p res.read_body.object_id   # 538149362\n    #   }\n    #\n    #   # using iterator\n    #   http.request_get('/index.html') {|res|\n    #     res.read_body do |segment|\n    #       print segment\n    #     end\n    #   }\n    #\n    def read_body(dest = nil, &block)\n      if @read\n        raise IOError, \"#{self.class}\\#read_body called twice\" if dest or block\n        return @body\n      end\n      to = procdest(dest, block)\n      stream_check\n      if @body_exist\n        read_body_0 to\n        @body = to\n      else\n        @body = nil\n      end\n      @read = true\n\n      @body\n    end\n\n    # Returns the entity body.\n    #\n    # Calling this method a second or subsequent time will return the\n    # already read string.\n    #\n    #   http.request_get('/index.html') {|res|\n    #     puts res.body\n    #   }\n    #\n    #   http.request_get('/index.html') {|res|\n    #     p res.body.object_id   # 538149362\n    #     p res.body.object_id   # 538149362\n    #   }\n    #\n    def body\n      read_body()\n    end\n\n    alias entity body   #:nodoc: obsolete\n\n    private\n\n    def read_body_0(dest)\n      if chunked?\n        read_chunked dest\n        return\n      end\n      clen = content_length()\n      if clen\n        @socket.read clen, dest, true   # ignore EOF\n        return\n      end\n      clen = range_length()\n      if clen\n        @socket.read clen, dest\n        return\n      end\n      @socket.read_all dest\n    end\n\n    def read_chunked(dest)\n      len = nil\n      total = 0\n      while true\n        line = @socket.readline\n        hexlen = line.slice(/[0-9a-fA-F]+/) or\n            raise HTTPBadResponse, \"wrong chunk size line: #{line}\"\n        len = hexlen.hex\n        break if len == 0\n        @socket.read len, dest; total += len\n        @socket.read 2   # \\r\\n\n      end\n      until @socket.readline.empty?\n        # none\n      end\n    end\n\n    def stream_check\n      raise IOError, 'attempt to read body out of block' if @socket.closed?\n    end\n\n    def procdest(dest, block)\n      raise ArgumentError, 'both arg and block given for HTTP method' \\\n          if dest and block\n      if block\n        ReadAdapter.new(block)\n      else\n        dest || ''\n      end\n    end\n\n  end\n\n\n  # :enddoc:\n\n  #--\n  # for backward compatibility\n  class HTTP\n    ProxyMod = ProxyDelta\n  end\n  module NetPrivate\n    HTTPRequest = ::Net::HTTPRequest\n  end\n\n  HTTPInformationCode = HTTPInformation\n  HTTPSuccessCode     = HTTPSuccess\n  HTTPRedirectionCode = HTTPRedirection\n  HTTPRetriableCode   = HTTPRedirection\n  HTTPClientErrorCode = HTTPClientError\n  HTTPFatalErrorCode  = HTTPClientError\n  HTTPServerErrorCode = HTTPServerError\n  HTTPResponceReceiver = HTTPResponse\n\nend   # module Net\n"
  },
  {
    "path": "lib/net/https.rb",
    "content": "=begin\n\n= $RCSfile$ -- SSL/TLS enhancement for Net::HTTP.\n\n== Info\n  'OpenSSL for Ruby 2' project\n  Copyright (C) 2001 GOTOU Yuuzou <gotoyuzo@notwork.org>\n  All rights reserved.\n\n== Licence\n  This program is licenced under the same licence as Ruby.\n  (See the file 'LICENCE'.)\n\n== Requirements\n  This program requires Net 1.2.0 or higher version.\n  You can get it from RAA or Ruby's CVS repository.\n\n== Version\n  $Id$\n  \n  2001-11-06: Contiributed to Ruby/OpenSSL project.\n  2004-03-06: Some code is merged in to net/http.\n\n== Example\n\nHere is a simple HTTP client:\n\n    require 'net/http'\n    require 'uri'\n\n    uri = URI.parse(ARGV[0] || 'http://localhost/')\n    http = Net::HTTP.new(uri.host, uri.port)\n    http.start {\n      http.request_get(uri.path) {|res|\n        print res.body\n      }\n    }\n\nIt can be replaced by the following code:\n\n    require 'net/https'\n    require 'uri'\n\n    uri = URI.parse(ARGV[0] || 'https://localhost/')\n    http = Net::HTTP.new(uri.host, uri.port)\n    http.use_ssl = true if uri.scheme == \"https\"  # enable SSL/TLS\n    http.start {\n      http.request_get(uri.path) {|res|\n        print res.body\n      }\n    }\n\n== class Net::HTTP\n\n=== Instance Methods\n\n: use_ssl?\n    returns true if use SSL/TLS with HTTP.\n\n: use_ssl=((|true_or_false|))\n    sets use_ssl.\n\n: peer_cert\n    return the X.509 certificates the server presented.\n\n: key, key=((|key|))\n    Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.\n    (This method is appeared in Michal Rokos's OpenSSL extension.)\n\n: cert, cert=((|cert|))\n    Sets an OpenSSL::X509::Certificate object as client certificate\n    (This method is appeared in Michal Rokos's OpenSSL extension).\n\n: ca_file, ca_file=((|path|))\n    Sets path of a CA certification file in PEM format.\n    The file can contrain several CA certificats.\n\n: ca_path, ca_path=((|path|))\n    Sets path of a CA certification directory containing certifications\n    in PEM format.\n\n: verify_mode, verify_mode=((|mode|))\n    Sets the flags for server the certification verification at\n    begining of SSL/TLS session.\n    OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable.\n\n: verify_callback, verify_callback=((|proc|))\n    Sets the verify callback for the server certification verification.\n\n: verify_depth, verify_depth=((|num|))\n    Sets the maximum depth for the certificate chain verification.\n\n: cert_store, cert_store=((|store|))\n    Sets the X509::Store to verify peer certificate.\n\n: ssl_timeout, ssl_timeout=((|sec|))\n    Sets the SSL timeout seconds.\n\n=end\n\nrequire 'net/http'\nrequire 'openssl'\n\nmodule Net\n\n  class HTTP\n    remove_method :use_ssl?\n    def use_ssl?\n      @use_ssl\n    end\n\n    # For backward compatibility.\n    alias use_ssl use_ssl?\n\n    # Turn on/off SSL.\n    # This flag must be set before starting session.\n    # If you change use_ssl value after session started,\n    # a Net::HTTP object raises IOError.\n    def use_ssl=(flag)\n      flag = (flag ? true : false)\n      raise IOError, \"use_ssl value changed, but session already started\" \\\n          if started? and @use_ssl != flag\n      if flag and not @ssl_context\n        @ssl_context = OpenSSL::SSL::SSLContext.new\n      end\n      @use_ssl = flag\n    end\n\n    def self.ssl_context_accessor(name)\n      module_eval(<<-End, __FILE__, __LINE__ + 1)\n        def #{name}\n          return nil unless @ssl_context\n          @ssl_context.#{name}\n        end\n\n        def #{name}=(val)\n          @ssl_context ||= OpenSSL::SSL::SSLContext.new\n          @ssl_context.#{name} = val\n        end\n      End\n    end\n\n    ssl_context_accessor :key\n    ssl_context_accessor :cert\n    ssl_context_accessor :ca_file\n    ssl_context_accessor :ca_path\n    ssl_context_accessor :verify_mode\n    ssl_context_accessor :verify_callback\n    ssl_context_accessor :verify_depth\n    ssl_context_accessor :cert_store\n\n    def ssl_timeout\n      return nil unless @ssl_context\n      @ssl_context.timeout\n    end\n\n    def ssl_timeout=(sec)\n      raise ArgumentError, 'Net::HTTP#ssl_timeout= called but use_ssl=false' \\\n          unless use_ssl?\n      @ssl_context ||= OpenSSL::SSL::SSLContext.new\n      @ssl_context.timeout = sec\n    end\n\n    # For backward compatibility\n    alias timeout= ssl_timeout=\n\n    def peer_cert\n      return nil if not use_ssl? or not @socket\n      @socket.io.peer_cert\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/net/imap.rb",
    "content": "#\n# = net/imap.rb\n#\n# Copyright (C) 2000  Shugo Maeda <shugo@ruby-lang.org>\n#\n# This library is distributed under the terms of the Ruby license.\n# You can freely distribute/modify this library.\n#\n# Documentation: Shugo Maeda, with RDoc conversion and overview by William\n# Webber.\n#\n# See Net::IMAP for documentation. \n#\n\n\nrequire \"socket\"\nrequire \"monitor\"\nrequire \"digest/md5\"\nbegin\n  require \"openssl\"\nrescue LoadError\nend\n\nmodule Net\n\n  #\n  # Net::IMAP implements Internet Message Access Protocol (IMAP) client\n  # functionality.  The protocol is described in [IMAP].\n  #\n  # == IMAP Overview\n  #\n  # An IMAP client connects to a server, and then authenticates\n  # itself using either #authenticate() or #login().  Having\n  # authenticated itself, there is a range of commands\n  # available to it.  Most work with mailboxes, which may be\n  # arranged in an hierarchical namespace, and each of which\n  # contains zero or more messages.  How this is implemented on\n  # the server is implementation-dependent; on a UNIX server, it\n  # will frequently be implemented as a files in mailbox format\n  # within a hierarchy of directories.\n  #\n  # To work on the messages within a mailbox, the client must\n  # first select that mailbox, using either #select() or (for\n  # read-only access) #examine().  Once the client has successfully\n  # selected a mailbox, they enter _selected_ state, and that\n  # mailbox becomes the _current_ mailbox, on which mail-item\n  # related commands implicitly operate.  \n  #\n  # Messages have two sorts of identifiers: message sequence\n  # numbers, and UIDs.  \n  #\n  # Message sequence numbers number messages within a mail box \n  # from 1 up to the number of items in the mail box.  If new\n  # message arrives during a session, it receives a sequence\n  # number equal to the new size of the mail box.  If messages\n  # are expunged from the mailbox, remaining messages have their\n  # sequence numbers \"shuffled down\" to fill the gaps.\n  #\n  # UIDs, on the other hand, are permanently guaranteed not to\n  # identify another message within the same mailbox, even if \n  # the existing message is deleted.  UIDs are required to\n  # be assigned in ascending (but not necessarily sequential)\n  # order within a mailbox; this means that if a non-IMAP client\n  # rearranges the order of mailitems within a mailbox, the\n  # UIDs have to be reassigned.  An IMAP client cannot thus\n  # rearrange message orders.\n  #\n  # == Examples of Usage\n  #\n  # === List sender and subject of all recent messages in the default mailbox\n  #\n  #   imap = Net::IMAP.new('mail.example.com')\n  #   imap.authenticate('LOGIN', 'joe_user', 'joes_password')\n  #   imap.examine('INBOX')\n  #   imap.search([\"RECENT\"]).each do |message_id|\n  #     envelope = imap.fetch(message_id, \"ENVELOPE\")[0].attr[\"ENVELOPE\"]\n  #     puts \"#{envelope.from[0].name}: \\t#{envelope.subject}\"\n  #   end\n  #\n  # === Move all messages from April 2003 from \"Mail/sent-mail\" to \"Mail/sent-apr03\"\n  #\n  #   imap = Net::IMAP.new('mail.example.com')\n  #   imap.authenticate('LOGIN', 'joe_user', 'joes_password')\n  #   imap.select('Mail/sent-mail')\n  #   if not imap.list('Mail/', 'sent-apr03')\n  #     imap.create('Mail/sent-apr03')\n  #   end\n  #   imap.search([\"BEFORE\", \"30-Apr-2003\", \"SINCE\", \"1-Apr-2003\"]).each do |message_id|\n  #     imap.copy(message_id, \"Mail/sent-apr03\")\n  #     imap.store(message_id, \"+FLAGS\", [:Deleted])\n  #   end\n  #   imap.expunge\n  # \n  # == Thread Safety\n  #\n  # Net::IMAP supports concurrent threads. For example,\n  # \n  #   imap = Net::IMAP.new(\"imap.foo.net\", \"imap2\")\n  #   imap.authenticate(\"cram-md5\", \"bar\", \"password\")\n  #   imap.select(\"inbox\")\n  #   fetch_thread = Thread.start { imap.fetch(1..-1, \"UID\") }\n  #   search_result = imap.search([\"BODY\", \"hello\"])\n  #   fetch_result = fetch_thread.value\n  #   imap.disconnect\n  # \n  # This script invokes the FETCH command and the SEARCH command concurrently.\n  #\n  # == Errors\n  #\n  # An IMAP server can send three different types of responses to indicate\n  # failure:\n  #\n  # NO:: the attempted command could not be successfully completed.  For\n  #      instance, the username/password used for logging in are incorrect;\n  #      the selected mailbox does not exists; etc.  \n  #\n  # BAD:: the request from the client does not follow the server's \n  #       understanding of the IMAP protocol.  This includes attempting\n  #       commands from the wrong client state; for instance, attempting\n  #       to perform a SEARCH command without having SELECTed a current\n  #       mailbox.  It can also signal an internal server\n  #       failure (such as a disk crash) has occurred.\n  #\n  # BYE:: the server is saying goodbye.  This can be part of a normal\n  #       logout sequence, and can be used as part of a login sequence\n  #       to indicate that the server is (for some reason) unwilling\n  #       to accept our connection.  As a response to any other command,\n  #       it indicates either that the server is shutting down, or that\n  #       the server is timing out the client connection due to inactivity.\n  #\n  # These three error response are represented by the errors\n  # Net::IMAP::NoResponseError, Net::IMAP::BadResponseError, and\n  # Net::IMAP::ByeResponseError, all of which are subclasses of\n  # Net::IMAP::ResponseError.  Essentially, all methods that involve\n  # sending a request to the server can generate one of these errors.\n  # Only the most pertinent instances have been documented below.\n  #\n  # Because the IMAP class uses Sockets for communication, its methods\n  # are also susceptible to the various errors that can occur when\n  # working with sockets.  These are generally represented as\n  # Errno errors.  For instance, any method that involves sending a\n  # request to the server and/or receiving a response from it could\n  # raise an Errno::EPIPE error if the network connection unexpectedly\n  # goes down.  See the socket(7), ip(7), tcp(7), socket(2), connect(2),\n  # and associated man pages.\n  #\n  # Finally, a Net::IMAP::DataFormatError is thrown if low-level data\n  # is found to be in an incorrect format (for instance, when converting\n  # between UTF-8 and UTF-16), and Net::IMAP::ResponseParseError is \n  # thrown if a server response is non-parseable. \n  #\n  #\n  # == References\n  #\n  # [[IMAP]]\n  #    M. Crispin, \"INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1\",\n  #    RFC 2060, December 1996.  (Note: since obsoleted by RFC 3501)\n  #\n  # [[LANGUAGE-TAGS]]\n  #    Alvestrand, H., \"Tags for the Identification of\n  #    Languages\", RFC 1766, March 1995.\n  #\n  # [[MD5]]\n  #    Myers, J., and M. Rose, \"The Content-MD5 Header Field\", RFC\n  #    1864, October 1995.\n  #\n  # [[MIME-IMB]]\n  #    Freed, N., and N. Borenstein, \"MIME (Multipurpose Internet\n  #    Mail Extensions) Part One: Format of Internet Message Bodies\", RFC\n  #    2045, November 1996.\n  #\n  # [[RFC-822]]\n  #    Crocker, D., \"Standard for the Format of ARPA Internet Text\n  #    Messages\", STD 11, RFC 822, University of Delaware, August 1982.\n  #\n  # [[RFC-2087]]\n  #    Myers, J., \"IMAP4 QUOTA extension\", RFC 2087, January 1997.\n  #\n  # [[RFC-2086]]\n  #    Myers, J., \"IMAP4 ACL extension\", RFC 2086, January 1997.\n  #\n  # [[RFC-2195]]\n  #    Klensin, J., Catoe, R., and Krumviede, P., \"IMAP/POP AUTHorize Extension\n  #    for Simple Challenge/Response\", RFC 2195, September 1997.\n  #\n  # [[SORT-THREAD-EXT]]\n  #    Crispin, M., \"INTERNET MESSAGE ACCESS PROTOCOL - SORT and THREAD\n  #    Extensions\", draft-ietf-imapext-sort, May 2003.\n  #\n  # [[OSSL]]\n  #    http://www.openssl.org\n  #\n  # [[RSSL]]\n  #    http://savannah.gnu.org/projects/rubypki\n  #\n  # [[UTF7]]\n  #    Goldsmith, D. and Davis, M., \"UTF-7: A Mail-Safe Transformation Format of\n  #    Unicode\", RFC 2152, May 1997.\n  #\n  class IMAP\n    include MonitorMixin\n    if defined?(OpenSSL)\n      include OpenSSL\n      include SSL\n    end\n\n    #  Returns an initial greeting response from the server.\n    attr_reader :greeting\n\n    # Returns recorded untagged responses.  For example:\n    #\n    #   imap.select(\"inbox\")\n    #   p imap.responses[\"EXISTS\"][-1]\n    #   #=> 2\n    #   p imap.responses[\"UIDVALIDITY\"][-1]\n    #   #=> 968263756\n    attr_reader :responses\n\n    # Returns all response handlers.\n    attr_reader :response_handlers\n\n    # The thread to receive exceptions.\n    attr_accessor :client_thread\n\n    # Flag indicating a message has been seen\n    SEEN = :Seen\n\n    # Flag indicating a message has been answered\n    ANSWERED = :Answered\n\n    # Flag indicating a message has been flagged for special or urgent\n    # attention\n    FLAGGED = :Flagged\n\n    # Flag indicating a message has been marked for deletion.  This\n    # will occur when the mailbox is closed or expunged.\n    DELETED = :Deleted\n\n    # Flag indicating a message is only a draft or work-in-progress version.\n    DRAFT = :Draft\n\n    # Flag indicating that the message is \"recent\", meaning that this\n    # session is the first session in which the client has been notified\n    # of this message.\n    RECENT = :Recent\n\n    # Flag indicating that a mailbox context name cannot contain\n    # children.\n    NOINFERIORS = :Noinferiors\n\n    # Flag indicating that a mailbox is not selected.\n    NOSELECT = :Noselect\n\n    # Flag indicating that a mailbox has been marked \"interesting\" by\n    # the server; this commonly indicates that the mailbox contains\n    # new messages.\n    MARKED = :Marked\n\n    # Flag indicating that the mailbox does not contains new messages.\n    UNMARKED = :Unmarked\n\n    # Returns the debug mode.\n    def self.debug\n      return @@debug\n    end\n\n    # Sets the debug mode.\n    def self.debug=(val)\n      return @@debug = val\n    end\n\n    # Adds an authenticator for Net::IMAP#authenticate.  +auth_type+\n    # is the type of authentication this authenticator supports\n    # (for instance, \"LOGIN\").  The +authenticator+ is an object\n    # which defines a process() method to handle authentication with\n    # the server.  See Net::IMAP::LoginAuthenticator and \n    # Net::IMAP::CramMD5Authenticator for examples.\n    #\n    # If +auth_type+ refers to an existing authenticator, it will be\n    # replaced by the new one.\n    def self.add_authenticator(auth_type, authenticator)\n      @@authenticators[auth_type] = authenticator\n    end\n\n    # Disconnects from the server.\n    def disconnect\n      begin\n        # try to call SSL::SSLSocket#io.\n        @sock.io.shutdown\n      rescue NoMethodError\n        # @sock is not an SSL::SSLSocket.\n        @sock.shutdown\n      end\n      @receiver_thread.join\n      @sock.close\n    end\n\n    # Returns true if disconnected from the server.\n    def disconnected?\n      return @sock.closed?\n    end\n\n    # Sends a CAPABILITY command, and returns an array of\n    # capabilities that the server supports.  Each capability\n    # is a string.  See [IMAP] for a list of possible\n    # capabilities.\n    #\n    # Note that the Net::IMAP class does not modify its\n    # behaviour according to the capabilities of the server;\n    # it is up to the user of the class to ensure that \n    # a certain capability is supported by a server before\n    # using it.\n    def capability\n      synchronize do\n        send_command(\"CAPABILITY\")\n        return @responses.delete(\"CAPABILITY\")[-1]\n      end\n    end\n\n    # Sends a NOOP command to the server. It does nothing.\n    def noop\n      send_command(\"NOOP\")\n    end\n\n    # Sends a LOGOUT command to inform the server that the client is\n    # done with the connection.\n    def logout\n      send_command(\"LOGOUT\")\n    end\n\n    # Sends an AUTHENTICATE command to authenticate the client.\n    # The +auth_type+ parameter is a string that represents\n    # the authentication mechanism to be used. Currently Net::IMAP\n    # supports authentication mechanisms:\n    #\n    #   LOGIN:: login using cleartext user and password. \n    #   CRAM-MD5:: login with cleartext user and encrypted password\n    #              (see [RFC-2195] for a full description).  This\n    #              mechanism requires that the server have the user's\n    #              password stored in clear-text password.\n    #\n    # For both these mechanisms, there should be two +args+: username\n    # and (cleartext) password.  A server may not support one or other\n    # of these mechanisms; check #capability() for a capability of\n    # the form \"AUTH=LOGIN\" or \"AUTH=CRAM-MD5\".\n    #\n    # Authentication is done using the appropriate authenticator object:\n    # see @@authenticators for more information on plugging in your own\n    # authenticator.\n    #\n    # For example:\n    #\n    #    imap.authenticate('LOGIN', user, password)\n    #\n    # A Net::IMAP::NoResponseError is raised if authentication fails.\n    def authenticate(auth_type, *args)\n      auth_type = auth_type.upcase\n      unless @@authenticators.has_key?(auth_type)\n        raise ArgumentError,\n          format('unknown auth type - \"%s\"', auth_type)\n      end\n      authenticator = @@authenticators[auth_type].new(*args)\n      send_command(\"AUTHENTICATE\", auth_type) do |resp|\n        if resp.instance_of?(ContinuationRequest)\n          data = authenticator.process(resp.data.text.unpack(\"m\")[0])\n          s = [data].pack(\"m\").gsub(/\\n/, \"\")\n          send_string_data(s)\n          put_string(CRLF)\n        end\n      end\n    end\n\n    # Sends a LOGIN command to identify the client and carries\n    # the plaintext +password+ authenticating this +user+.  Note\n    # that, unlike calling #authenticate() with an +auth_type+\n    # of \"LOGIN\", #login() does *not* use the login authenticator.\n    #\n    # A Net::IMAP::NoResponseError is raised if authentication fails.\n    def login(user, password)\n      send_command(\"LOGIN\", user, password)\n    end\n\n    # Sends a SELECT command to select a +mailbox+ so that messages\n    # in the +mailbox+ can be accessed. \n    #\n    # After you have selected a mailbox, you may retrieve the\n    # number of items in that mailbox from @responses[\"EXISTS\"][-1],\n    # and the number of recent messages from @responses[\"RECENT\"][-1].\n    # Note that these values can change if new messages arrive\n    # during a session; see #add_response_handler() for a way of\n    # detecting this event.\n    #\n    # A Net::IMAP::NoResponseError is raised if the mailbox does not\n    # exist or is for some reason non-selectable.\n    def select(mailbox)\n      synchronize do\n        @responses.clear\n        send_command(\"SELECT\", mailbox)\n      end\n    end\n\n    # Sends a EXAMINE command to select a +mailbox+ so that messages\n    # in the +mailbox+ can be accessed.  Behaves the same as #select(),\n    # except that the selected +mailbox+ is identified as read-only.\n    #\n    # A Net::IMAP::NoResponseError is raised if the mailbox does not\n    # exist or is for some reason non-examinable.\n    def examine(mailbox)\n      synchronize do\n        @responses.clear\n        send_command(\"EXAMINE\", mailbox)\n      end\n    end\n\n    # Sends a CREATE command to create a new +mailbox+.\n    #\n    # A Net::IMAP::NoResponseError is raised if a mailbox with that name\n    # cannot be created.\n    def create(mailbox)\n      send_command(\"CREATE\", mailbox)\n    end\n\n    # Sends a DELETE command to remove the +mailbox+.\n    #\n    # A Net::IMAP::NoResponseError is raised if a mailbox with that name\n    # cannot be deleted, either because it does not exist or because the\n    # client does not have permission to delete it.\n    def delete(mailbox)\n      send_command(\"DELETE\", mailbox)\n    end\n\n    # Sends a RENAME command to change the name of the +mailbox+ to\n    # +newname+.\n    #\n    # A Net::IMAP::NoResponseError is raised if a mailbox with the \n    # name +mailbox+ cannot be renamed to +newname+ for whatever\n    # reason; for instance, because +mailbox+ does not exist, or\n    # because there is already a mailbox with the name +newname+.\n    def rename(mailbox, newname)\n      send_command(\"RENAME\", mailbox, newname)\n    end\n\n    # Sends a SUBSCRIBE command to add the specified +mailbox+ name to\n    # the server's set of \"active\" or \"subscribed\" mailboxes as returned\n    # by #lsub().\n    #\n    # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be\n    # subscribed to, for instance because it does not exist.\n    def subscribe(mailbox)\n      send_command(\"SUBSCRIBE\", mailbox)\n    end\n\n    # Sends a UNSUBSCRIBE command to remove the specified +mailbox+ name\n    # from the server's set of \"active\" or \"subscribed\" mailboxes.\n    #\n    # A Net::IMAP::NoResponseError is raised if +mailbox+ cannot be\n    # unsubscribed from, for instance because the client is not currently\n    # subscribed to it.\n    def unsubscribe(mailbox)\n      send_command(\"UNSUBSCRIBE\", mailbox)\n    end\n\n    # Sends a LIST command, and returns a subset of names from\n    # the complete set of all names available to the client.\n    # +refname+ provides a context (for instance, a base directory\n    # in a directory-based mailbox hierarchy).  +mailbox+ specifies\n    # a mailbox or (via wildcards) mailboxes under that context.\n    # Two wildcards may be used in +mailbox+: '*', which matches\n    # all characters *including* the hierarchy delimiter (for instance,\n    # '/' on a UNIX-hosted directory-based mailbox hierarchy); and '%',\n    # which matches all characters *except* the hierarchy delimiter.\n    #\n    # If +refname+ is empty, +mailbox+ is used directly to determine\n    # which mailboxes to match.  If +mailbox+ is empty, the root\n    # name of +refname+ and the hierarchy delimiter are returned.\n    #\n    # The return value is an array of +Net::IMAP::MailboxList+. For example:\n    #\n    #   imap.create(\"foo/bar\")\n    #   imap.create(\"foo/baz\")\n    #   p imap.list(\"\", \"foo/%\")\n    #   #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim=\"/\", name=\"foo/\">, \\\\ \n    #        #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim=\"/\", name=\"foo/bar\">, \\\\ \n    #        #<Net::IMAP::MailboxList attr=[:Noinferiors], delim=\"/\", name=\"foo/baz\">]\n    def list(refname, mailbox)\n      synchronize do\n        send_command(\"LIST\", refname, mailbox)\n        return @responses.delete(\"LIST\")\n      end\n    end\n\n    # Sends the GETQUOTAROOT command along with specified +mailbox+.\n    # This command is generally available to both admin and user.\n    # If mailbox exists, returns an array containing objects of\n    # Net::IMAP::MailboxQuotaRoot and Net::IMAP::MailboxQuota.\n    def getquotaroot(mailbox)\n      synchronize do\n        send_command(\"GETQUOTAROOT\", mailbox)\n        result = []\n        result.concat(@responses.delete(\"QUOTAROOT\"))\n        result.concat(@responses.delete(\"QUOTA\"))\n        return result\n      end\n    end\n\n    # Sends the GETQUOTA command along with specified +mailbox+.\n    # If this mailbox exists, then an array containing a\n    # Net::IMAP::MailboxQuota object is returned.  This\n    # command generally is only available to server admin.\n    def getquota(mailbox)\n      synchronize do\n        send_command(\"GETQUOTA\", mailbox)\n        return @responses.delete(\"QUOTA\")\n      end\n    end\n\n    # Sends a SETQUOTA command along with the specified +mailbox+ and\n    # +quota+.  If +quota+ is nil, then quota will be unset for that\n    # mailbox.  Typically one needs to be logged in as server admin\n    # for this to work.  The IMAP quota commands are described in\n    # [RFC-2087].\n    def setquota(mailbox, quota)\n      if quota.nil?\n        data = '()'\n      else\n        data = '(STORAGE ' + quota.to_s + ')'\n      end\n      send_command(\"SETQUOTA\", mailbox, RawData.new(data))\n    end\n\n    # Sends the SETACL command along with +mailbox+, +user+ and the\n    # +rights+ that user is to have on that mailbox.  If +rights+ is nil,\n    # then that user will be stripped of any rights to that mailbox.\n    # The IMAP ACL commands are described in [RFC-2086].\n    def setacl(mailbox, user, rights)\n      if rights.nil? \n        send_command(\"SETACL\", mailbox, user, \"\")\n      else\n        send_command(\"SETACL\", mailbox, user, rights)\n      end\n    end\n\n    # Send the GETACL command along with specified +mailbox+.\n    # If this mailbox exists, an array containing objects of\n    # Net::IMAP::MailboxACLItem will be returned.\n    def getacl(mailbox)\n      synchronize do\n        send_command(\"GETACL\", mailbox)\n        return @responses.delete(\"ACL\")[-1]\n      end\n    end\n\n    # Sends a LSUB command, and returns a subset of names from the set\n    # of names that the user has declared as being \"active\" or\n    # \"subscribed\".  +refname+ and +mailbox+ are interpreted as \n    # for #list().\n    # The return value is an array of +Net::IMAP::MailboxList+.\n    def lsub(refname, mailbox)\n      synchronize do\n        send_command(\"LSUB\", refname, mailbox)\n        return @responses.delete(\"LSUB\")\n      end\n    end\n\n    # Sends a STATUS command, and returns the status of the indicated\n    # +mailbox+. +attr+ is a list of one or more attributes that\n    # we are request the status of.  Supported attributes include:\n    #\n    #   MESSAGES:: the number of messages in the mailbox.\n    #   RECENT:: the number of recent messages in the mailbox.\n    #   UNSEEN:: the number of unseen messages in the mailbox.\n    #\n    # The return value is a hash of attributes. For example:\n    #\n    #   p imap.status(\"inbox\", [\"MESSAGES\", \"RECENT\"])\n    #   #=> {\"RECENT\"=>0, \"MESSAGES\"=>44}\n    #\n    # A Net::IMAP::NoResponseError is raised if status values \n    # for +mailbox+ cannot be returned, for instance because it\n    # does not exist.\n    def status(mailbox, attr)\n      synchronize do\n        send_command(\"STATUS\", mailbox, attr)\n        return @responses.delete(\"STATUS\")[-1].attr\n      end\n    end\n\n    # Sends a APPEND command to append the +message+ to the end of\n    # the +mailbox+. The optional +flags+ argument is an array of \n    # flags to initially passing to the new message.  The optional\n    # +date_time+ argument specifies the creation time to assign to the \n    # new message; it defaults to the current time.\n    # For example:\n    #\n    #   imap.append(\"inbox\", <<EOF.gsub(/\\n/, \"\\r\\n\"), [:Seen], Time.now)\n    #   Subject: hello\n    #   From: shugo@ruby-lang.org\n    #   To: shugo@ruby-lang.org\n    #   \n    #   hello world\n    #   EOF\n    #\n    # A Net::IMAP::NoResponseError is raised if the mailbox does\n    # not exist (it is not created automatically), or if the flags,\n    # date_time, or message arguments contain errors.\n    def append(mailbox, message, flags = nil, date_time = nil)\n      args = []\n      if flags\n        args.push(flags)\n      end\n      args.push(date_time) if date_time\n      args.push(Literal.new(message))\n      send_command(\"APPEND\", mailbox, *args)\n    end\n\n    # Sends a CHECK command to request a checkpoint of the currently\n    # selected mailbox.  This performs implementation-specific\n    # housekeeping, for instance, reconciling the mailbox's \n    # in-memory and on-disk state.\n    def check\n      send_command(\"CHECK\")\n    end\n\n    # Sends a CLOSE command to close the currently selected mailbox.\n    # The CLOSE command permanently removes from the mailbox all\n    # messages that have the \\Deleted flag set.\n    def close\n      send_command(\"CLOSE\")\n    end\n\n    # Sends a EXPUNGE command to permanently remove from the currently\n    # selected mailbox all messages that have the \\Deleted flag set.\n    def expunge\n      synchronize do\n        send_command(\"EXPUNGE\")\n        return @responses.delete(\"EXPUNGE\")\n      end\n    end\n\n    # Sends a SEARCH command to search the mailbox for messages that\n    # match the given searching criteria, and returns message sequence\n    # numbers.  +keys+ can either be a string holding the entire \n    # search string, or a single-dimension array of search keywords and \n    # arguments.  The following are some common search criteria;\n    # see [IMAP] section 6.4.4 for a full list.\n    #\n    # <message set>:: a set of message sequence numbers.  ',' indicates\n    #                 an interval, ':' indicates a range.  For instance,\n    #                 '2,10:12,15' means \"2,10,11,12,15\".\n    #\n    # BEFORE <date>:: messages with an internal date strictly before\n    #                 <date>.  The date argument has a format similar\n    #                 to 8-Aug-2002.\n    #\n    # BODY <string>:: messages that contain <string> within their body.\n    #\n    # CC <string>:: messages containing <string> in their CC field.\n    #\n    # FROM <string>:: messages that contain <string> in their FROM field.\n    #\n    # NEW:: messages with the \\Recent, but not the \\Seen, flag set.\n    #\n    # NOT <search-key>:: negate the following search key.\n    #\n    # OR <search-key> <search-key>:: \"or\" two search keys together.\n    #\n    # ON <date>:: messages with an internal date exactly equal to <date>, \n    #             which has a format similar to 8-Aug-2002.\n    #\n    # SINCE <date>:: messages with an internal date on or after <date>.\n    #\n    # SUBJECT <string>:: messages with <string> in their subject.\n    #\n    # TO <string>:: messages with <string> in their TO field.\n    # \n    # For example:\n    #\n    #   p imap.search([\"SUBJECT\", \"hello\", \"NOT\", \"NEW\"])\n    #   #=> [1, 6, 7, 8]\n    def search(keys, charset = nil)\n      return search_internal(\"SEARCH\", keys, charset)\n    end\n\n    # As for #search(), but returns unique identifiers.\n    def uid_search(keys, charset = nil)\n      return search_internal(\"UID SEARCH\", keys, charset)\n    end\n\n    # Sends a FETCH command to retrieve data associated with a message\n    # in the mailbox. The +set+ parameter is a number or an array of\n    # numbers or a Range object. The number is a message sequence\n    # number.  +attr+ is a list of attributes to fetch; see the\n    # documentation for Net::IMAP::FetchData for a list of valid\n    # attributes.\n    # The return value is an array of Net::IMAP::FetchData. For example:\n    #\n    #   p imap.fetch(6..8, \"UID\")\n    #   #=> [#<Net::IMAP::FetchData seqno=6, attr={\"UID\"=>98}>, \\\\ \n    #        #<Net::IMAP::FetchData seqno=7, attr={\"UID\"=>99}>, \\\\ \n    #        #<Net::IMAP::FetchData seqno=8, attr={\"UID\"=>100}>]\n    #   p imap.fetch(6, \"BODY[HEADER.FIELDS (SUBJECT)]\")\n    #   #=> [#<Net::IMAP::FetchData seqno=6, attr={\"BODY[HEADER.FIELDS (SUBJECT)]\"=>\"Subject: test\\r\\n\\r\\n\"}>]\n    #   data = imap.uid_fetch(98, [\"RFC822.SIZE\", \"INTERNALDATE\"])[0]\n    #   p data.seqno\n    #   #=> 6\n    #   p data.attr[\"RFC822.SIZE\"]\n    #   #=> 611\n    #   p data.attr[\"INTERNALDATE\"]\n    #   #=> \"12-Oct-2000 22:40:59 +0900\"\n    #   p data.attr[\"UID\"]\n    #   #=> 98\n    def fetch(set, attr)\n      return fetch_internal(\"FETCH\", set, attr)\n    end\n\n    # As for #fetch(), but +set+ contains unique identifiers.\n    def uid_fetch(set, attr)\n      return fetch_internal(\"UID FETCH\", set, attr)\n    end\n\n    # Sends a STORE command to alter data associated with messages\n    # in the mailbox, in particular their flags. The +set+ parameter \n    # is a number or an array of numbers or a Range object. Each number \n    # is a message sequence number.  +attr+ is the name of a data item \n    # to store: 'FLAGS' means to replace the message's flag list\n    # with the provided one; '+FLAGS' means to add the provided flags;\n    # and '-FLAGS' means to remove them.  +flags+ is a list of flags.\n    #\n    # The return value is an array of Net::IMAP::FetchData. For example:\n    #\n    #   p imap.store(6..8, \"+FLAGS\", [:Deleted])\n    #   #=> [#<Net::IMAP::FetchData seqno=6, attr={\"FLAGS\"=>[:Seen, :Deleted]}>, \\\\ \n    #        #<Net::IMAP::FetchData seqno=7, attr={\"FLAGS\"=>[:Seen, :Deleted]}>, \\\\  \n    #        #<Net::IMAP::FetchData seqno=8, attr={\"FLAGS\"=>[:Seen, :Deleted]}>]\n    def store(set, attr, flags)\n      return store_internal(\"STORE\", set, attr, flags)\n    end\n\n    # As for #store(), but +set+ contains unique identifiers.\n    def uid_store(set, attr, flags)\n      return store_internal(\"UID STORE\", set, attr, flags)\n    end\n\n    # Sends a COPY command to copy the specified message(s) to the end\n    # of the specified destination +mailbox+. The +set+ parameter is\n    # a number or an array of numbers or a Range object. The number is\n    # a message sequence number.\n    def copy(set, mailbox)\n      copy_internal(\"COPY\", set, mailbox)\n    end\n\n    # As for #copy(), but +set+ contains unique identifiers.\n    def uid_copy(set, mailbox)\n      copy_internal(\"UID COPY\", set, mailbox)\n    end\n\n    # Sends a SORT command to sort messages in the mailbox.\n    # Returns an array of message sequence numbers. For example:\n    #\n    #   p imap.sort([\"FROM\"], [\"ALL\"], \"US-ASCII\")\n    #   #=> [1, 2, 3, 5, 6, 7, 8, 4, 9]\n    #   p imap.sort([\"DATE\"], [\"SUBJECT\", \"hello\"], \"US-ASCII\")\n    #   #=> [6, 7, 8, 1]\n    #\n    # See [SORT-THREAD-EXT] for more details.\n    def sort(sort_keys, search_keys, charset)\n      return sort_internal(\"SORT\", sort_keys, search_keys, charset)\n    end\n\n    # As for #sort(), but returns an array of unique identifiers.\n    def uid_sort(sort_keys, search_keys, charset)\n      return sort_internal(\"UID SORT\", sort_keys, search_keys, charset)\n    end\n\n    # Adds a response handler. For example, to detect when \n    # the server sends us a new EXISTS response (which normally\n    # indicates new messages being added to the mail box), \n    # you could add the following handler after selecting the\n    # mailbox.\n    #\n    #   imap.add_response_handler { |resp|\n    #     if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == \"EXISTS\"\n    #       puts \"Mailbox now has #{resp.data} messages\"\n    #     end\n    #   }\n    #\n    def add_response_handler(handler = Proc.new)\n      @response_handlers.push(handler)\n    end\n\n    # Removes the response handler.\n    def remove_response_handler(handler)\n      @response_handlers.delete(handler)\n    end\n\n    # As for #search(), but returns message sequence numbers in threaded\n    # format, as a Net::IMAP::ThreadMember tree.  The supported algorithms\n    # are:\n    #\n    # ORDEREDSUBJECT:: split into single-level threads according to subject,\n    #                  ordered by date.\n    # REFERENCES:: split into threads by parent/child relationships determined\n    #              by which message is a reply to which.\n    #\n    # Unlike #search(), +charset+ is a required argument.  US-ASCII\n    # and UTF-8 are sample values.\n    #\n    # See [SORT-THREAD-EXT] for more details.\n    def thread(algorithm, search_keys, charset)\n      return thread_internal(\"THREAD\", algorithm, search_keys, charset)\n    end\n\n    # As for #thread(), but returns unique identifiers instead of \n    # message sequence numbers.\n    def uid_thread(algorithm, search_keys, charset)\n      return thread_internal(\"UID THREAD\", algorithm, search_keys, charset)\n    end\n\n    # Decode a string from modified UTF-7 format to UTF-8.\n    #\n    # UTF-7 is a 7-bit encoding of Unicode [UTF7].  IMAP uses a\n    # slightly modified version of this to encode mailbox names\n    # containing non-ASCII characters; see [IMAP] section 5.1.3.\n    #\n    # Net::IMAP does _not_ automatically encode and decode\n    # mailbox names to and from utf7.\n    def self.decode_utf7(s)\n      return s.gsub(/&(.*?)-/n) {\n        if $1.empty?\n          \"&\"\n        else\n          base64 = $1.tr(\",\", \"/\")\n          x = base64.length % 4\n          if x > 0\n            base64.concat(\"=\" * (4 - x))\n          end\n          u16tou8(base64.unpack(\"m\")[0])\n        end\n      }\n    end\n\n    # Encode a string from UTF-8 format to modified UTF-7.\n    def self.encode_utf7(s)\n      return s.gsub(/(&)|([^\\x20-\\x25\\x27-\\x7e]+)/n) { |x|\n        if $1\n          \"&-\"\n        else\n          base64 = [u8tou16(x)].pack(\"m\")\n          \"&\" + base64.delete(\"=\\n\").tr(\"/\", \",\") + \"-\"\n        end\n      }\n    end\n\n    private\n\n    CRLF = \"\\r\\n\"      # :nodoc:\n    PORT = 143         # :nodoc:\n\n    @@debug = false\n    @@authenticators = {}\n\n    # Creates a new Net::IMAP object and connects it to the specified\n    # +port+ (143 by default) on the named +host+.  If +usessl+ is true, \n    # then an attempt will\n    # be made to use SSL (now TLS) to connect to the server.  For this\n    # to work OpenSSL [OSSL] and the Ruby OpenSSL [RSSL]\n    # extensions need to be installed.  The +certs+ parameter indicates\n    # the path or file containing the CA cert of the server, and the\n    # +verify+ parameter is for the OpenSSL verification callback.\n    #\n    # The most common errors are:\n    #\n    # Errno::ECONNREFUSED:: connection refused by +host+ or an intervening\n    #                       firewall.\n    # Errno::ETIMEDOUT:: connection timed out (possibly due to packets\n    #                    being dropped by an intervening firewall).\n    # Errno::ENETUNREACH:: there is no route to that network.\n    # SocketError:: hostname not known or other socket error.\n    # Net::IMAP::ByeResponseError:: we connected to the host, but they \n    #                               immediately said goodbye to us.\n    def initialize(host, port = PORT, usessl = false, certs = nil, verify = false)\n      super()\n      @host = host\n      @port = port\n      @tag_prefix = \"RUBY\"\n      @tagno = 0\n      @parser = ResponseParser.new\n      @sock = TCPSocket.open(host, port)\n      if usessl\n        unless defined?(OpenSSL)\n          raise \"SSL extension not installed\"\n        end\n        @usessl = true\n\n        # verify the server.\n        context = SSLContext::new()\n        context.ca_file = certs if certs && FileTest::file?(certs)\n        context.ca_path = certs if certs && FileTest::directory?(certs)\n        context.verify_mode = VERIFY_PEER if verify\n        if defined?(VerifyCallbackProc)\n          context.verify_callback = VerifyCallbackProc \n        end\n        @sock = SSLSocket.new(@sock, context)\n        @sock.connect   # start ssl session.\n        @sock.post_connection_check(@host) if verify\n      else\n        @usessl = false\n      end\n      @responses = Hash.new([].freeze)\n      @tagged_responses = {}\n      @response_handlers = []\n      @response_arrival = new_cond\n      @continuation_request = nil\n      @logout_command_tag = nil\n      @debug_output_bol = true\n\n      @greeting = get_response\n      if @greeting.name == \"BYE\"\n        @sock.close\n        raise ByeResponseError, @greeting.raw_data\n      end\n\n      @client_thread = Thread.current\n      @receiver_thread = Thread.start {\n        receive_responses\n      }\n    end\n\n    def receive_responses\n      while true\n        begin\n          resp = get_response\n        rescue Exception\n          @sock.close\n          @client_thread.raise($!)\n          break\n        end\n        break unless resp\n        begin\n          synchronize do\n            case resp\n            when TaggedResponse\n              @tagged_responses[resp.tag] = resp\n              @response_arrival.broadcast\n              if resp.tag == @logout_command_tag\n                return\n              end\n            when UntaggedResponse\n              record_response(resp.name, resp.data)\n              if resp.data.instance_of?(ResponseText) &&\n                  (code = resp.data.code)\n                record_response(code.name, code.data)\n              end\n              if resp.name == \"BYE\" && @logout_command_tag.nil?\n                @sock.close\n                raise ByeResponseError, resp.raw_data\n              end\n            when ContinuationRequest\n              @continuation_request = resp\n              @response_arrival.broadcast\n            end\n            @response_handlers.each do |handler|\n              handler.call(resp)\n            end\n          end\n        rescue Exception\n          @client_thread.raise($!)\n        end\n      end\n    end\n\n    def get_tagged_response(tag)\n      until @tagged_responses.key?(tag)\n        @response_arrival.wait\n      end\n      return pick_up_tagged_response(tag)\n    end\n\n    def pick_up_tagged_response(tag)\n      resp = @tagged_responses.delete(tag)\n      case resp.name\n      when /\\A(?:NO)\\z/ni\n        raise NoResponseError, resp.data.text\n      when /\\A(?:BAD)\\z/ni\n        raise BadResponseError, resp.data.text\n      else\n        return resp\n      end\n    end\n\n    def get_response\n      buff = \"\"\n      while true\n        s = @sock.gets(CRLF)\n        break unless s\n        buff.concat(s)\n        if /\\{(\\d+)\\}\\r\\n/n =~ s\n          s = @sock.read($1.to_i)\n          buff.concat(s)\n        else\n          break\n        end\n      end\n      return nil if buff.length == 0\n      if @@debug\n        $stderr.print(buff.gsub(/^/n, \"S: \"))\n      end\n      return @parser.parse(buff)\n    end\n\n    def record_response(name, data)\n      unless @responses.has_key?(name)\n        @responses[name] = []\n      end\n      @responses[name].push(data)\n    end\n\n    def send_command(cmd, *args, &block)\n      synchronize do\n        tag = Thread.current[:net_imap_tag] = generate_tag\n        put_string(tag + \" \" + cmd)\n        args.each do |i|\n          put_string(\" \")\n          send_data(i)\n        end\n        put_string(CRLF)\n        if cmd == \"LOGOUT\"\n          @logout_command_tag = tag\n        end\n        if block\n          add_response_handler(block)\n        end\n        begin\n          return get_tagged_response(tag)\n        ensure\n          if block\n            remove_response_handler(block)\n          end\n        end\n      end\n    end\n\n    def generate_tag\n      @tagno += 1\n      return format(\"%s%04d\", @tag_prefix, @tagno)\n    end\n    \n    def put_string(str)\n      @sock.print(str)\n      if @@debug\n        if @debug_output_bol\n          $stderr.print(\"C: \")\n        end\n        $stderr.print(str.gsub(/\\n(?!\\z)/n, \"\\nC: \"))\n        if /\\r\\n\\z/n.match(str)\n          @debug_output_bol = true\n        else\n          @debug_output_bol = false\n        end\n      end\n    end\n\n    def send_data(data)\n      case data\n      when nil\n        put_string(\"NIL\")\n      when String\n        send_string_data(data)\n      when Integer\n        send_number_data(data)\n      when Array\n        send_list_data(data)\n      when Time\n        send_time_data(data)\n      when Symbol\n        send_symbol_data(data)\n      else\n        data.send_data(self)\n      end\n    end\n\n    def send_string_data(str)\n      case str\n      when \"\"\n        put_string('\"\"')\n      when /[\\x80-\\xff\\r\\n]/n\n        # literal\n        send_literal(str)\n      when /[(){ \\x00-\\x1f\\x7f%*\"\\\\]/n\n        # quoted string\n        send_quoted_string(str)\n      else\n        put_string(str)\n      end\n    end\n    \n    def send_quoted_string(str)\n      put_string('\"' + str.gsub(/[\"\\\\]/n, \"\\\\\\\\\\\\&\") + '\"')\n    end\n\n    def send_literal(str)\n      put_string(\"{\" + str.length.to_s + \"}\" + CRLF)\n      while @continuation_request.nil? &&\n        !@tagged_responses.key?(Thread.current[:net_imap_tag])\n        @response_arrival.wait\n      end\n      if @continuation_request.nil?\n        pick_up_tagged_response(Thread.current[:net_imap_tag])\n        raise ResponseError.new(\"expected continuation request\")\n      end\n      @continuation_request = nil\n      put_string(str)\n    end\n\n    def send_number_data(num)\n      if num < 0 || num >= 4294967296\n        raise DataFormatError, num.to_s\n      end\n      put_string(num.to_s)\n    end\n\n    def send_list_data(list)\n      put_string(\"(\")\n      first = true\n      list.each do |i|\n        if first\n          first = false\n        else\n          put_string(\" \")\n        end\n        send_data(i)\n      end\n      put_string(\")\")\n    end\n\n    DATE_MONTH = %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)\n\n    def send_time_data(time)\n      t = time.dup.gmtime\n      s = format('\"%2d-%3s-%4d %02d:%02d:%02d +0000\"',\n                 t.day, DATE_MONTH[t.month - 1], t.year,\n                 t.hour, t.min, t.sec)\n      put_string(s)\n    end\n\n    def send_symbol_data(symbol)\n      put_string(\"\\\\\" + symbol.to_s)\n    end\n\n    def search_internal(cmd, keys, charset)\n      if keys.instance_of?(String)\n        keys = [RawData.new(keys)]\n      else\n        normalize_searching_criteria(keys)\n      end\n      synchronize do\n        if charset\n          send_command(cmd, \"CHARSET\", charset, *keys)\n        else\n          send_command(cmd, *keys)\n        end\n        return @responses.delete(\"SEARCH\")[-1]\n      end\n    end\n\n    def fetch_internal(cmd, set, attr)\n      if attr.instance_of?(String)\n        attr = RawData.new(attr)\n      end\n      synchronize do\n        @responses.delete(\"FETCH\")\n        send_command(cmd, MessageSet.new(set), attr)\n        return @responses.delete(\"FETCH\")\n      end\n    end\n\n    def store_internal(cmd, set, attr, flags)\n      if attr.instance_of?(String)\n        attr = RawData.new(attr)\n      end\n      synchronize do\n        @responses.delete(\"FETCH\")\n        send_command(cmd, MessageSet.new(set), attr, flags)\n        return @responses.delete(\"FETCH\")\n      end\n    end\n\n    def copy_internal(cmd, set, mailbox)\n      send_command(cmd, MessageSet.new(set), mailbox)\n    end\n\n    def sort_internal(cmd, sort_keys, search_keys, charset)\n      if search_keys.instance_of?(String)\n        search_keys = [RawData.new(search_keys)]\n      else\n        normalize_searching_criteria(search_keys)\n      end\n      normalize_searching_criteria(search_keys)\n      synchronize do\n        send_command(cmd, sort_keys, charset, *search_keys)\n        return @responses.delete(\"SORT\")[-1]\n      end\n    end\n\n    def thread_internal(cmd, algorithm, search_keys, charset)\n      if search_keys.instance_of?(String)\n        search_keys = [RawData.new(search_keys)]\n      else\n        normalize_searching_criteria(search_keys)\n      end\n      normalize_searching_criteria(search_keys)\n      send_command(cmd, algorithm, charset, *search_keys)\n      return @responses.delete(\"THREAD\")[-1]\n    end\n\n    def normalize_searching_criteria(keys)\n      keys.collect! do |i|\n        case i\n        when -1, Range, Array\n          MessageSet.new(i)\n        else\n          i\n        end\n      end\n    end\n\n    def self.u16tou8(s)\n      len = s.length\n      if len < 2\n        return \"\"\n      end\n      buf = \"\"\n      i = 0\n      while i < len\n        c = s[i] << 8 | s[i + 1]\n        i += 2\n        if c == 0xfeff\n          next\n        elsif c < 0x0080\n          buf.concat(c)\n        elsif c < 0x0800\n          b2 = c & 0x003f\n          b1 = c >> 6\n          buf.concat(b1 | 0xc0)\n          buf.concat(b2 | 0x80)\n        elsif c >= 0xdc00 && c < 0xe000\n          raise DataFormatError, \"invalid surrogate detected\"\n        elsif c >= 0xd800 && c < 0xdc00\n          if i + 2 > len\n            raise DataFormatError, \"invalid surrogate detected\"\n          end\n          low = s[i] << 8 | s[i + 1]\n          i += 2\n          if low < 0xdc00 || low > 0xdfff\n            raise DataFormatError, \"invalid surrogate detected\"\n          end\n          c = (((c & 0x03ff)) << 10 | (low & 0x03ff)) + 0x10000\n          b4 = c & 0x003f\n          b3 = (c >> 6) & 0x003f\n          b2 = (c >> 12) & 0x003f\n          b1 = c >> 18;\n          buf.concat(b1 | 0xf0)\n          buf.concat(b2 | 0x80)\n          buf.concat(b3 | 0x80)\n          buf.concat(b4 | 0x80)\n        else # 0x0800-0xffff\n          b3 = c & 0x003f\n          b2 = (c >> 6) & 0x003f\n          b1 = c >> 12\n          buf.concat(b1 | 0xe0)\n          buf.concat(b2 | 0x80)\n          buf.concat(b3 | 0x80)\n        end\n      end\n      return buf\n    end\n    private_class_method :u16tou8\n\n    def self.u8tou16(s)\n      len = s.length\n      buf = \"\"\n      i = 0\n      while i < len\n        c = s[i]\n        if (c & 0x80) == 0\n          buf.concat(0x00)\n          buf.concat(c)\n          i += 1\n        elsif (c & 0xe0) == 0xc0 &&\n            len >= 2 &&\n            (s[i + 1] & 0xc0) == 0x80\n          if c == 0xc0 || c == 0xc1\n            raise DataFormatError, format(\"non-shortest UTF-8 sequence (%02x)\", c)\n          end\n          u = ((c & 0x1f) << 6) | (s[i + 1] & 0x3f)\n          buf.concat(u >> 8)\n          buf.concat(u & 0x00ff)\n          i += 2\n        elsif (c & 0xf0) == 0xe0 &&\n            i + 2 < len &&\n            (s[i + 1] & 0xc0) == 0x80 &&\n            (s[i + 2] & 0xc0) == 0x80\n          if c == 0xe0 && s[i + 1] < 0xa0\n            raise DataFormatError, format(\"non-shortest UTF-8 sequence (%02x)\", c)\n          end\n          u = ((c & 0x0f) << 12) | ((s[i + 1] & 0x3f) << 6) | (s[i + 2] & 0x3f)\n          # surrogate chars\n          if u >= 0xd800 && u <= 0xdfff\n            raise DataFormatError, format(\"none-UTF-16 char detected (%04x)\", u)\n          end\n          buf.concat(u >> 8)\n          buf.concat(u & 0x00ff)\n          i += 3\n        elsif (c & 0xf8) == 0xf0 &&\n            i + 3 < len &&\n            (s[i + 1] & 0xc0) == 0x80 &&\n            (s[i + 2] & 0xc0) == 0x80 &&\n            (s[i + 3] & 0xc0) == 0x80\n          if c == 0xf0 && s[i + 1] < 0x90\n            raise DataFormatError, format(\"non-shortest UTF-8 sequence (%02x)\", c)\n          end\n          u = ((c & 0x07) << 18) | ((s[i + 1] & 0x3f) << 12) |\n            ((s[i + 2] & 0x3f) << 6) | (s[i + 3] & 0x3f)\n          if u < 0x10000\n            buf.concat(u >> 8)\n            buf.concat(u & 0x00ff)\n          elsif u < 0x110000\n            high = ((u - 0x10000) >> 10) | 0xd800\n            low = (u & 0x03ff) | 0xdc00\n            buf.concat(high >> 8)\n            buf.concat(high & 0x00ff)\n            buf.concat(low >> 8)\n            buf.concat(low & 0x00ff)\n          else\n            raise DataFormatError, format(\"none-UTF-16 char detected (%04x)\", u)\n          end\n          i += 4\n        else\n          raise DataFormatError, format(\"illegal UTF-8 sequence (%02x)\", c)\n        end\n      end\n      return buf\n    end\n    private_class_method :u8tou16\n\n    class RawData # :nodoc:\n      def send_data(imap)\n        imap.send(:put_string, @data)\n      end\n\n      private\n\n      def initialize(data)\n        @data = data\n      end\n    end\n\n    class Atom # :nodoc:\n      def send_data(imap)\n        imap.send(:put_string, @data)\n      end\n\n      private\n\n      def initialize(data)\n        @data = data\n      end\n    end\n\n    class QuotedString # :nodoc:\n      def send_data(imap)\n        imap.send(:send_quoted_string, @data)\n      end\n\n      private\n\n      def initialize(data)\n        @data = data\n      end\n    end\n\n    class Literal # :nodoc:\n      def send_data(imap)\n        imap.send(:send_literal, @data)\n      end\n\n      private\n\n      def initialize(data)\n        @data = data\n      end\n    end\n\n    class MessageSet # :nodoc:\n      def send_data(imap)\n        imap.send(:put_string, format_internal(@data))\n      end\n\n      private\n\n      def initialize(data)\n        @data = data\n      end\n\n      def format_internal(data)\n        case data\n        when \"*\"\n          return data\n        when Integer\n          ensure_nz_number(data)\n          if data == -1\n            return \"*\"\n          else\n            return data.to_s\n          end\n        when Range\n          return format_internal(data.first) +\n            \":\" + format_internal(data.last)\n        when Array\n          return data.collect {|i| format_internal(i)}.join(\",\")\n        when ThreadMember\n          return data.seqno.to_s +\n            \":\" + data.children.collect {|i| format_internal(i).join(\",\")}\n        else\n          raise DataFormatError, data.inspect\n        end\n      end\n\n      def ensure_nz_number(num)\n        if num < -1 || num == 0 || num >= 4294967296\n          msg = \"nz_number must be non-zero unsigned 32-bit integer: \" +\n                num.inspect\n          raise DataFormatError, msg\n        end\n      end\n    end\n\n    # Net::IMAP::ContinuationRequest represents command continuation requests.\n    # \n    # The command continuation request response is indicated by a \"+\" token\n    # instead of a tag.  This form of response indicates that the server is\n    # ready to accept the continuation of a command from the client.  The\n    # remainder of this response is a line of text.\n    # \n    #   continue_req    ::= \"+\" SPACE (resp_text / base64)\n    # \n    # ==== Fields:\n    # \n    # data:: Returns the data (Net::IMAP::ResponseText).\n    # \n    # raw_data:: Returns the raw data string.\n    ContinuationRequest = Struct.new(:data, :raw_data)\n\n    # Net::IMAP::UntaggedResponse represents untagged responses.\n    # \n    # Data transmitted by the server to the client and status responses\n    # that do not indicate command completion are prefixed with the token\n    # \"*\", and are called untagged responses.\n    # \n    #   response_data   ::= \"*\" SPACE (resp_cond_state / resp_cond_bye /\n    #                       mailbox_data / message_data / capability_data)\n    # \n    # ==== Fields:\n    # \n    # name:: Returns the name such as \"FLAGS\", \"LIST\", \"FETCH\"....\n    # \n    # data:: Returns the data such as an array of flag symbols,\n    #         a ((<Net::IMAP::MailboxList>)) object....\n    # \n    # raw_data:: Returns the raw data string.\n    UntaggedResponse = Struct.new(:name, :data, :raw_data)\n     \n    # Net::IMAP::TaggedResponse represents tagged responses.\n    # \n    # The server completion result response indicates the success or\n    # failure of the operation.  It is tagged with the same tag as the\n    # client command which began the operation.\n    # \n    #   response_tagged ::= tag SPACE resp_cond_state CRLF\n    #   \n    #   tag             ::= 1*<any ATOM_CHAR except \"+\">\n    #   \n    #   resp_cond_state ::= (\"OK\" / \"NO\" / \"BAD\") SPACE resp_text\n    # \n    # ==== Fields:\n    # \n    # tag:: Returns the tag.\n    # \n    # name:: Returns the name. the name is one of \"OK\", \"NO\", \"BAD\".\n    # \n    # data:: Returns the data. See ((<Net::IMAP::ResponseText>)).\n    # \n    # raw_data:: Returns the raw data string.\n    #\n    TaggedResponse = Struct.new(:tag, :name, :data, :raw_data)\n     \n    # Net::IMAP::ResponseText represents texts of responses.\n    # The text may be prefixed by the response code.\n    # \n    #   resp_text       ::= [\"[\" resp_text_code \"]\" SPACE] (text_mime2 / text)\n    #                       ;; text SHOULD NOT begin with \"[\" or \"=\"\n    # \n    # ==== Fields:\n    # \n    # code:: Returns the response code. See ((<Net::IMAP::ResponseCode>)).\n    #       \n    # text:: Returns the text.\n    # \n    ResponseText = Struct.new(:code, :text)\n\n    # \n    # Net::IMAP::ResponseCode represents response codes.\n    # \n    #   resp_text_code  ::= \"ALERT\" / \"PARSE\" /\n    #                       \"PERMANENTFLAGS\" SPACE \"(\" #(flag / \"\\*\") \")\" /\n    #                       \"READ-ONLY\" / \"READ-WRITE\" / \"TRYCREATE\" /\n    #                       \"UIDVALIDITY\" SPACE nz_number /\n    #                       \"UNSEEN\" SPACE nz_number /\n    #                       atom [SPACE 1*<any TEXT_CHAR except \"]\">]\n    # \n    # ==== Fields:\n    # \n    # name:: Returns the name such as \"ALERT\", \"PERMANENTFLAGS\", \"UIDVALIDITY\"....\n    # \n    # data:: Returns the data if it exists.\n    #\n    ResponseCode = Struct.new(:name, :data)\n\n    # Net::IMAP::MailboxList represents contents of the LIST response.\n    # \n    #   mailbox_list    ::= \"(\" #(\"\\Marked\" / \"\\Noinferiors\" /\n    #                       \"\\Noselect\" / \"\\Unmarked\" / flag_extension) \")\"\n    #                       SPACE (<\"> QUOTED_CHAR <\"> / nil) SPACE mailbox\n    # \n    # ==== Fields:\n    # \n    # attr:: Returns the name attributes. Each name attribute is a symbol\n    #        capitalized by String#capitalize, such as :Noselect (not :NoSelect).\n    # \n    # delim:: Returns the hierarchy delimiter\n    # \n    # name:: Returns the mailbox name.\n    #\n    MailboxList = Struct.new(:attr, :delim, :name)\n\n    # Net::IMAP::MailboxQuota represents contents of GETQUOTA response.\n    # This object can also be a response to GETQUOTAROOT.  In the syntax\n    # specification below, the delimiter used with the \"#\" construct is a\n    # single space (SPACE).\n    # \n    #    quota_list      ::= \"(\" #quota_resource \")\"\n    # \n    #    quota_resource  ::= atom SPACE number SPACE number\n    # \n    #    quota_response  ::= \"QUOTA\" SPACE astring SPACE quota_list\n    # \n    # ==== Fields:\n    # \n    # mailbox:: The mailbox with the associated quota.\n    # \n    # usage:: Current storage usage of mailbox.\n    # \n    # quota:: Quota limit imposed on mailbox.\n    #\n    MailboxQuota = Struct.new(:mailbox, :usage, :quota)\n\n    # Net::IMAP::MailboxQuotaRoot represents part of the GETQUOTAROOT\n    # response. (GETQUOTAROOT can also return Net::IMAP::MailboxQuota.)\n    # \n    #    quotaroot_response ::= \"QUOTAROOT\" SPACE astring *(SPACE astring)\n    # \n    # ==== Fields:\n    # \n    # mailbox:: The mailbox with the associated quota.\n    # \n    # quotaroots:: Zero or more quotaroots that effect the quota on the\n    #              specified mailbox.\n    #\n    MailboxQuotaRoot = Struct.new(:mailbox, :quotaroots)\n\n    # Net::IMAP::MailboxACLItem represents response from GETACL.\n    # \n    #    acl_data        ::= \"ACL\" SPACE mailbox *(SPACE identifier SPACE rights)\n    # \n    #    identifier      ::= astring\n    # \n    #    rights          ::= astring\n    # \n    # ==== Fields:\n    # \n    # user:: Login name that has certain rights to the mailbox\n    #        that was specified with the getacl command.\n    # \n    # rights:: The access rights the indicated user has to the\n    #          mailbox.\n    #\n    MailboxACLItem = Struct.new(:user, :rights)\n\n    # Net::IMAP::StatusData represents contents of the STATUS response.\n    # \n    # ==== Fields:\n    # \n    # mailbox:: Returns the mailbox name.\n    # \n    # attr:: Returns a hash. Each key is one of \"MESSAGES\", \"RECENT\", \"UIDNEXT\",\n    #        \"UIDVALIDITY\", \"UNSEEN\". Each value is a number.\n    # \n    StatusData = Struct.new(:mailbox, :attr)\n\n    # Net::IMAP::FetchData represents contents of the FETCH response.\n    # \n    # ==== Fields:\n    # \n    # seqno:: Returns the message sequence number.\n    #         (Note: not the unique identifier, even for the UID command response.)\n    # \n    # attr:: Returns a hash. Each key is a data item name, and each value is\n    #        its value.\n    # \n    #        The current data items are:\n    # \n    #        [BODY]\n    #           A form of BODYSTRUCTURE without extension data.\n    #        [BODY[<section>]<<origin_octet>>]\n    #           A string expressing the body contents of the specified section.\n    #        [BODYSTRUCTURE]\n    #           An object that describes the [MIME-IMB] body structure of a message.\n    #           See Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText,\n    #           Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart.\n    #        [ENVELOPE]\n    #           A Net::IMAP::Envelope object that describes the envelope\n    #           structure of a message.\n    #        [FLAGS]\n    #           A array of flag symbols that are set for this message. flag symbols\n    #           are capitalized by String#capitalize.\n    #        [INTERNALDATE]\n    #           A string representing the internal date of the message.\n    #        [RFC822]\n    #           Equivalent to BODY[].\n    #        [RFC822.HEADER]\n    #           Equivalent to BODY.PEEK[HEADER].\n    #        [RFC822.SIZE]\n    #           A number expressing the [RFC-822] size of the message.\n    #        [RFC822.TEXT]\n    #           Equivalent to BODY[TEXT].\n    #        [UID]\n    #           A number expressing the unique identifier of the message.\n    # \n    FetchData = Struct.new(:seqno, :attr)\n\n    # Net::IMAP::Envelope represents envelope structures of messages.\n    # \n    # ==== Fields:\n    # \n    # date:: Returns a string that represents the date.\n    # \n    # subject:: Returns a string that represents the subject.\n    # \n    # from:: Returns an array of Net::IMAP::Address that represents the from.\n    # \n    # sender:: Returns an array of Net::IMAP::Address that represents the sender.\n    # \n    # reply_to:: Returns an array of Net::IMAP::Address that represents the reply-to.\n    # \n    # to:: Returns an array of Net::IMAP::Address that represents the to.\n    # \n    # cc:: Returns an array of Net::IMAP::Address that represents the cc.\n    # \n    # bcc:: Returns an array of Net::IMAP::Address that represents the bcc.\n    # \n    # in_reply_to:: Returns a string that represents the in-reply-to.\n    # \n    # message_id:: Returns a string that represents the message-id.\n    # \n    Envelope = Struct.new(:date, :subject, :from, :sender, :reply_to,\n                          :to, :cc, :bcc, :in_reply_to, :message_id)\n\n    # \n    # Net::IMAP::Address represents electronic mail addresses.\n    # \n    # ==== Fields:\n    # \n    # name:: Returns the phrase from [RFC-822] mailbox.\n    # \n    # route:: Returns the route from [RFC-822] route-addr.\n    # \n    # mailbox:: nil indicates end of [RFC-822] group.\n    #           If non-nil and host is nil, returns [RFC-822] group name.\n    #           Otherwise, returns [RFC-822] local-part\n    # \n    # host:: nil indicates [RFC-822] group syntax.\n    #        Otherwise, returns [RFC-822] domain name.\n    #\n    Address = Struct.new(:name, :route, :mailbox, :host)\n\n    # \n    # Net::IMAP::ContentDisposition represents Content-Disposition fields.\n    # \n    # ==== Fields:\n    # \n    # dsp_type:: Returns the disposition type.\n    # \n    # param:: Returns a hash that represents parameters of the Content-Disposition\n    #         field.\n    # \n    ContentDisposition = Struct.new(:dsp_type, :param)\n\n    # Net::IMAP::ThreadMember represents a thread-node returned \n    # by Net::IMAP#thread\n    #\n    # ==== Fields:\n    #\n    # seqno:: The sequence number of this message.\n    #\n    # children:: an array of Net::IMAP::ThreadMember objects for mail\n    # items that are children of this in the thread.\n    #\n    ThreadMember = Struct.new(:seqno, :children)\n\n    # Net::IMAP::BodyTypeBasic represents basic body structures of messages.\n    # \n    # ==== Fields:\n    # \n    # media_type:: Returns the content media type name as defined in [MIME-IMB].\n    # \n    # subtype:: Returns the content subtype name as defined in [MIME-IMB].\n    # \n    # param:: Returns a hash that represents parameters as defined in [MIME-IMB].\n    # \n    # content_id:: Returns a string giving the content id as defined in [MIME-IMB].\n    # \n    # description:: Returns a string giving the content description as defined in\n    #               [MIME-IMB].\n    # \n    # encoding:: Returns a string giving the content transfer encoding as defined in\n    #            [MIME-IMB].\n    # \n    # size:: Returns a number giving the size of the body in octets.\n    # \n    # md5:: Returns a string giving the body MD5 value as defined in [MD5].\n    # \n    # disposition:: Returns a Net::IMAP::ContentDisposition object giving\n    #               the content disposition.\n    # \n    # language:: Returns a string or an array of strings giving the body\n    #            language value as defined in [LANGUAGE-TAGS].\n    # \n    # extension:: Returns extension data.\n    # \n    # multipart?:: Returns false.\n    # \n    class BodyTypeBasic < Struct.new(:media_type, :subtype,\n                                     :param, :content_id,\n                                     :description, :encoding, :size,\n                                     :md5, :disposition, :language,\n                                     :extension)\n      def multipart?\n        return false\n      end\n\n      # Obsolete: use +subtype+ instead.  Calling this will\n      # generate a warning message to +stderr+, then return \n      # the value of +subtype+.\n      def media_subtype\n        $stderr.printf(\"warning: media_subtype is obsolete.\\n\")\n        $stderr.printf(\"         use subtype instead.\\n\")\n        return subtype\n      end\n    end\n\n    # Net::IMAP::BodyTypeText represents TEXT body structures of messages.\n    # \n    # ==== Fields:\n    # \n    # lines:: Returns the size of the body in text lines.\n    # \n    # And Net::IMAP::BodyTypeText has all fields of Net::IMAP::BodyTypeBasic.\n    # \n    class BodyTypeText < Struct.new(:media_type, :subtype,\n                                    :param, :content_id,\n                                    :description, :encoding, :size,\n                                    :lines,\n                                    :md5, :disposition, :language,\n                                    :extension)\n      def multipart?\n        return false\n      end\n\n      # Obsolete: use +subtype+ instead.  Calling this will\n      # generate a warning message to +stderr+, then return \n      # the value of +subtype+.\n      def media_subtype\n        $stderr.printf(\"warning: media_subtype is obsolete.\\n\")\n        $stderr.printf(\"         use subtype instead.\\n\")\n        return subtype\n      end\n    end\n\n    # Net::IMAP::BodyTypeMessage represents MESSAGE/RFC822 body structures of messages.\n    # \n    # ==== Fields:\n    # \n    # envelope:: Returns a Net::IMAP::Envelope giving the envelope structure.\n    # \n    # body:: Returns an object giving the body structure.\n    # \n    # And Net::IMAP::BodyTypeMessage has all methods of Net::IMAP::BodyTypeText.\n    #\n    class BodyTypeMessage < Struct.new(:media_type, :subtype,\n                                       :param, :content_id,\n                                       :description, :encoding, :size,\n                                       :envelope, :body, :lines,\n                                       :md5, :disposition, :language,\n                                       :extension)\n      def multipart?\n        return false\n      end\n\n      # Obsolete: use +subtype+ instead.  Calling this will\n      # generate a warning message to +stderr+, then return \n      # the value of +subtype+.\n      def media_subtype\n        $stderr.printf(\"warning: media_subtype is obsolete.\\n\")\n        $stderr.printf(\"         use subtype instead.\\n\")\n        return subtype\n      end\n    end\n\n    # Net::IMAP::BodyTypeMultipart represents multipart body structures \n    # of messages.\n    # \n    # ==== Fields:\n    # \n    # media_type:: Returns the content media type name as defined in [MIME-IMB].\n    # \n    # subtype:: Returns the content subtype name as defined in [MIME-IMB].\n    # \n    # parts:: Returns multiple parts.\n    # \n    # param:: Returns a hash that represents parameters as defined in [MIME-IMB].\n    # \n    # disposition:: Returns a Net::IMAP::ContentDisposition object giving\n    #               the content disposition.\n    # \n    # language:: Returns a string or an array of strings giving the body\n    #            language value as defined in [LANGUAGE-TAGS].\n    # \n    # extension:: Returns extension data.\n    # \n    # multipart?:: Returns true.\n    # \n    class BodyTypeMultipart < Struct.new(:media_type, :subtype,\n                                         :parts,\n                                         :param, :disposition, :language,\n                                         :extension)\n      def multipart?\n        return true\n      end\n\n      # Obsolete: use +subtype+ instead.  Calling this will\n      # generate a warning message to +stderr+, then return \n      # the value of +subtype+.\n      def media_subtype\n        $stderr.printf(\"warning: media_subtype is obsolete.\\n\")\n        $stderr.printf(\"         use subtype instead.\\n\")\n        return subtype\n      end\n    end\n\n    class ResponseParser # :nodoc:\n      def parse(str)\n        @str = str\n        @pos = 0\n        @lex_state = EXPR_BEG\n        @token = nil\n        return response\n      end\n\n      private\n\n      EXPR_BEG          = :EXPR_BEG\n      EXPR_DATA         = :EXPR_DATA\n      EXPR_TEXT         = :EXPR_TEXT\n      EXPR_RTEXT        = :EXPR_RTEXT\n      EXPR_CTEXT        = :EXPR_CTEXT\n\n      T_SPACE   = :SPACE\n      T_NIL     = :NIL\n      T_NUMBER  = :NUMBER\n      T_ATOM    = :ATOM\n      T_QUOTED  = :QUOTED\n      T_LPAR    = :LPAR\n      T_RPAR    = :RPAR\n      T_BSLASH  = :BSLASH\n      T_STAR    = :STAR\n      T_LBRA    = :LBRA\n      T_RBRA    = :RBRA\n      T_LITERAL = :LITERAL\n      T_PLUS    = :PLUS\n      T_PERCENT = :PERCENT\n      T_CRLF    = :CRLF\n      T_EOF     = :EOF\n      T_TEXT    = :TEXT\n\n      BEG_REGEXP = /\\G(?:\\\n(?# 1:  SPACE   )( +)|\\\n(?# 2:  NIL     )(NIL)(?=[\\x80-\\xff(){ \\x00-\\x1f\\x7f%*\"\\\\\\[\\]+])|\\\n(?# 3:  NUMBER  )(\\d+)(?=[\\x80-\\xff(){ \\x00-\\x1f\\x7f%*\"\\\\\\[\\]+])|\\\n(?# 4:  ATOM    )([^\\x80-\\xff(){ \\x00-\\x1f\\x7f%*\"\\\\\\[\\]+]+)|\\\n(?# 5:  QUOTED  )\"((?:[^\\x00\\r\\n\"\\\\]|\\\\[\"\\\\])*)\"|\\\n(?# 6:  LPAR    )(\\()|\\\n(?# 7:  RPAR    )(\\))|\\\n(?# 8:  BSLASH  )(\\\\)|\\\n(?# 9:  STAR    )(\\*)|\\\n(?# 10: LBRA    )(\\[)|\\\n(?# 11: RBRA    )(\\])|\\\n(?# 12: LITERAL )\\{(\\d+)\\}\\r\\n|\\\n(?# 13: PLUS    )(\\+)|\\\n(?# 14: PERCENT )(%)|\\\n(?# 15: CRLF    )(\\r\\n)|\\\n(?# 16: EOF     )(\\z))/ni\n\n      DATA_REGEXP = /\\G(?:\\\n(?# 1:  SPACE   )( )|\\\n(?# 2:  NIL     )(NIL)|\\\n(?# 3:  NUMBER  )(\\d+)|\\\n(?# 4:  QUOTED  )\"((?:[^\\x00\\r\\n\"\\\\]|\\\\[\"\\\\])*)\"|\\\n(?# 5:  LITERAL )\\{(\\d+)\\}\\r\\n|\\\n(?# 6:  LPAR    )(\\()|\\\n(?# 7:  RPAR    )(\\)))/ni\n\n      TEXT_REGEXP = /\\G(?:\\\n(?# 1:  TEXT    )([^\\x00\\r\\n]*))/ni\n\n      RTEXT_REGEXP = /\\G(?:\\\n(?# 1:  LBRA    )(\\[)|\\\n(?# 2:  TEXT    )([^\\x00\\r\\n]*))/ni\n\n      CTEXT_REGEXP = /\\G(?:\\\n(?# 1:  TEXT    )([^\\x00\\r\\n\\]]*))/ni\n\n      Token = Struct.new(:symbol, :value)\n\n      def response\n        token = lookahead\n        case token.symbol\n        when T_PLUS\n          result = continue_req\n        when T_STAR\n          result = response_untagged\n        else\n          result = response_tagged\n        end\n        match(T_CRLF)\n        match(T_EOF)\n        return result\n      end\n\n      def continue_req\n        match(T_PLUS)\n        match(T_SPACE)\n        return ContinuationRequest.new(resp_text, @str)\n      end\n\n      def response_untagged\n        match(T_STAR)\n        match(T_SPACE)\n        token = lookahead\n        if token.symbol == T_NUMBER\n          return numeric_response\n        elsif token.symbol == T_ATOM\n          case token.value\n          when /\\A(?:OK|NO|BAD|BYE|PREAUTH)\\z/ni\n            return response_cond\n          when /\\A(?:FLAGS)\\z/ni\n            return flags_response\n          when /\\A(?:LIST|LSUB)\\z/ni\n            return list_response\n          when /\\A(?:QUOTA)\\z/ni\n            return getquota_response\n          when /\\A(?:QUOTAROOT)\\z/ni\n            return getquotaroot_response\n          when /\\A(?:ACL)\\z/ni\n            return getacl_response\n          when /\\A(?:SEARCH|SORT)\\z/ni\n            return search_response\n          when /\\A(?:THREAD)\\z/ni\n            return thread_response\n          when /\\A(?:STATUS)\\z/ni\n            return status_response\n          when /\\A(?:CAPABILITY)\\z/ni\n            return capability_response\n          else\n            return text_response\n          end\n        else\n          parse_error(\"unexpected token %s\", token.symbol)\n        end\n      end\n\n      def response_tagged\n        tag = atom\n        match(T_SPACE)\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return TaggedResponse.new(tag, name, resp_text, @str)\n      end\n\n      def response_cond\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return UntaggedResponse.new(name, resp_text, @str)\n      end\n\n      def numeric_response\n        n = number\n        match(T_SPACE)\n        token = match(T_ATOM)\n        name = token.value.upcase\n        case name\n        when \"EXISTS\", \"RECENT\", \"EXPUNGE\"\n          return UntaggedResponse.new(name, n, @str)\n        when \"FETCH\"\n          shift_token\n          match(T_SPACE)\n          data = FetchData.new(n, msg_att)\n          return UntaggedResponse.new(name, data, @str)\n        end\n      end\n\n      def msg_att\n        match(T_LPAR)\n        attr = {}\n        while true\n          token = lookahead\n          case token.symbol\n          when T_RPAR\n            shift_token\n            break\n          when T_SPACE\n            shift_token\n            token = lookahead\n          end\n          case token.value\n          when /\\A(?:ENVELOPE)\\z/ni\n            name, val = envelope_data\n          when /\\A(?:FLAGS)\\z/ni\n            name, val = flags_data\n          when /\\A(?:INTERNALDATE)\\z/ni\n            name, val = internaldate_data\n          when /\\A(?:RFC822(?:\\.HEADER|\\.TEXT)?)\\z/ni\n            name, val = rfc822_text\n          when /\\A(?:RFC822\\.SIZE)\\z/ni\n            name, val = rfc822_size\n          when /\\A(?:BODY(?:STRUCTURE)?)\\z/ni\n            name, val = body_data\n          when /\\A(?:UID)\\z/ni\n            name, val = uid_data\n          else\n            parse_error(\"unknown attribute `%s'\", token.value)\n          end\n          attr[name] = val\n        end\n        return attr\n      end\n\n      def envelope_data\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return name, envelope\n      end\n\n      def envelope\n        @lex_state = EXPR_DATA\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          result = nil\n        else\n          match(T_LPAR)\n          date = nstring\n          match(T_SPACE)\n          subject = nstring\n          match(T_SPACE)\n          from = address_list\n          match(T_SPACE)\n          sender = address_list\n          match(T_SPACE)\n          reply_to = address_list\n          match(T_SPACE)\n          to = address_list\n          match(T_SPACE)\n          cc = address_list\n          match(T_SPACE)\n          bcc = address_list\n          match(T_SPACE)\n          in_reply_to = nstring\n          match(T_SPACE)\n          message_id = nstring\n          match(T_RPAR)\n          result = Envelope.new(date, subject, from, sender, reply_to,\n                                to, cc, bcc, in_reply_to, message_id)\n        end\n        @lex_state = EXPR_BEG\n        return result\n      end\n\n      def flags_data\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return name, flag_list\n      end\n\n      def internaldate_data\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        token = match(T_QUOTED)\n        return name, token.value\n      end\n\n      def rfc822_text\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return name, nstring\n      end\n\n      def rfc822_size\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return name, number\n      end\n\n      def body_data\n        token = match(T_ATOM)\n        name = token.value.upcase\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n          return name, body\n        end\n        name.concat(section)\n        token = lookahead\n        if token.symbol == T_ATOM\n          name.concat(token.value)\n          shift_token\n        end\n        match(T_SPACE)\n        data = nstring\n        return name, data\n      end\n\n      def body\n        @lex_state = EXPR_DATA\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          result = nil\n        else\n          match(T_LPAR)\n          token = lookahead\n          if token.symbol == T_LPAR\n            result = body_type_mpart\n          else\n            result = body_type_1part\n          end\n          match(T_RPAR)\n        end\n        @lex_state = EXPR_BEG\n        return result\n      end\n\n      def body_type_1part\n        token = lookahead\n        case token.value\n        when /\\A(?:TEXT)\\z/ni\n          return body_type_text\n        when /\\A(?:MESSAGE)\\z/ni\n          return body_type_msg\n        else\n          return body_type_basic\n        end\n      end\n\n      def body_type_basic\n        mtype, msubtype = media_type\n        token = lookahead\n        if token.symbol == T_RPAR\n          return BodyTypeBasic.new(mtype, msubtype)\n        end\n        match(T_SPACE)\n        param, content_id, desc, enc, size = body_fields\n        md5, disposition, language, extension = body_ext_1part\n        return BodyTypeBasic.new(mtype, msubtype,\n                                 param, content_id,\n                                 desc, enc, size,\n                                 md5, disposition, language, extension)\n      end\n\n      def body_type_text\n        mtype, msubtype = media_type\n        match(T_SPACE)\n        param, content_id, desc, enc, size = body_fields\n        match(T_SPACE)\n        lines = number\n        md5, disposition, language, extension = body_ext_1part\n        return BodyTypeText.new(mtype, msubtype,\n                                param, content_id,\n                                desc, enc, size,\n                                lines,\n                                md5, disposition, language, extension)\n      end\n\n      def body_type_msg\n        mtype, msubtype = media_type\n        match(T_SPACE)\n        param, content_id, desc, enc, size = body_fields\n        match(T_SPACE)\n        env = envelope\n        match(T_SPACE)\n        b = body\n        match(T_SPACE)\n        lines = number\n        md5, disposition, language, extension = body_ext_1part\n        return BodyTypeMessage.new(mtype, msubtype,\n                                   param, content_id,\n                                   desc, enc, size,\n                                   env, b, lines,\n                                   md5, disposition, language, extension)\n      end\n\n      def body_type_mpart\n        parts = []\n        while true\n          token = lookahead\n          if token.symbol == T_SPACE\n            shift_token\n            break\n          end\n          parts.push(body)\n        end\n        mtype = \"MULTIPART\"\n        msubtype = case_insensitive_string\n        param, disposition, language, extension = body_ext_mpart\n        return BodyTypeMultipart.new(mtype, msubtype, parts,\n                                     param, disposition, language,\n                                     extension)\n      end\n\n      def media_type\n        mtype = case_insensitive_string\n        match(T_SPACE)\n        msubtype = case_insensitive_string\n        return mtype, msubtype\n      end\n\n      def body_fields\n        param = body_fld_param\n        match(T_SPACE)\n        content_id = nstring\n        match(T_SPACE)\n        desc = nstring\n        match(T_SPACE)\n        enc = case_insensitive_string\n        match(T_SPACE)\n        size = number\n        return param, content_id, desc, enc, size\n      end\n\n      def body_fld_param\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        end\n        match(T_LPAR)\n        param = {}\n        while true\n          token = lookahead\n          case token.symbol\n          when T_RPAR\n            shift_token\n            break\n          when T_SPACE\n            shift_token\n          end\n          name = case_insensitive_string\n          match(T_SPACE)\n          val = string\n          param[name] = val\n        end\n        return param\n      end\n\n      def body_ext_1part\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return nil\n        end\n        md5 = nstring\n\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return md5\n        end\n        disposition = body_fld_dsp\n\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return md5, disposition\n        end\n        language = body_fld_lang\n\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return md5, disposition, language\n        end\n\n        extension = body_extensions\n        return md5, disposition, language, extension\n      end\n\n      def body_ext_mpart\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return nil\n        end\n        param = body_fld_param\n\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return param\n        end\n        disposition = body_fld_dsp\n        match(T_SPACE)\n        language = body_fld_lang\n\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n        else\n          return param, disposition, language\n        end\n\n        extension = body_extensions\n        return param, disposition, language, extension\n      end\n\n      def body_fld_dsp\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        end\n        match(T_LPAR)\n        dsp_type = case_insensitive_string\n        match(T_SPACE)\n        param = body_fld_param\n        match(T_RPAR)\n        return ContentDisposition.new(dsp_type, param)\n      end\n\n      def body_fld_lang\n        token = lookahead\n        if token.symbol == T_LPAR\n          shift_token\n          result = []\n          while true\n            token = lookahead\n            case token.symbol\n            when T_RPAR\n              shift_token\n              return result\n            when T_SPACE\n              shift_token\n            end\n            result.push(case_insensitive_string)\n          end\n        else\n          lang = nstring\n          if lang\n            return lang.upcase\n          else\n            return lang\n          end\n        end\n      end\n\n      def body_extensions\n        result = []\n        while true\n          token = lookahead\n          case token.symbol\n          when T_RPAR\n            return result\n          when T_SPACE\n            shift_token\n          end\n          result.push(body_extension)\n        end\n      end\n\n      def body_extension\n        token = lookahead\n        case token.symbol\n        when T_LPAR\n          shift_token\n          result = body_extensions\n          match(T_RPAR)\n          return result\n        when T_NUMBER\n          return number\n        else\n          return nstring\n        end\n      end\n\n      def section\n        str = \"\"\n        token = match(T_LBRA)\n        str.concat(token.value)\n        token = match(T_ATOM, T_NUMBER, T_RBRA)\n        if token.symbol == T_RBRA\n          str.concat(token.value)\n          return str\n        end\n        str.concat(token.value)\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n          str.concat(token.value)\n          token = match(T_LPAR)\n          str.concat(token.value)\n          while true\n            token = lookahead\n            case token.symbol\n            when T_RPAR\n              str.concat(token.value)\n              shift_token\n              break\n            when T_SPACE\n              shift_token\n              str.concat(token.value)\n            end\n            str.concat(format_string(astring))\n          end\n        end\n        token = match(T_RBRA)\n        str.concat(token.value)\n        return str\n      end\n\n      def format_string(str)\n        case str\n        when \"\"\n          return '\"\"'\n        when /[\\x80-\\xff\\r\\n]/n\n          # literal\n          return \"{\" + str.length.to_s + \"}\" + CRLF + str\n        when /[(){ \\x00-\\x1f\\x7f%*\"\\\\]/n\n          # quoted string\n          return '\"' + str.gsub(/[\"\\\\]/n, \"\\\\\\\\\\\\&\") + '\"'\n        else\n          # atom\n          return str\n        end\n      end\n\n      def uid_data\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return name, number\n      end\n\n      def text_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        @lex_state = EXPR_TEXT\n        token = match(T_TEXT)\n        @lex_state = EXPR_BEG\n        return UntaggedResponse.new(name, token.value)\n      end\n\n      def flags_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return UntaggedResponse.new(name, flag_list, @str)\n      end\n\n      def list_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        return UntaggedResponse.new(name, mailbox_list, @str)\n      end\n\n      def mailbox_list\n        attr = flag_list\n        match(T_SPACE)\n        token = match(T_QUOTED, T_NIL)\n        if token.symbol == T_NIL\n          delim = nil\n        else\n          delim = token.value\n        end\n        match(T_SPACE)\n        name = astring\n        return MailboxList.new(attr, delim, name)\n      end\n\n      def getquota_response\n        # If quota never established, get back\n        # `NO Quota root does not exist'.\n        # If quota removed, get `()' after the\n        # folder spec with no mention of `STORAGE'.\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        mailbox = astring\n        match(T_SPACE)\n        match(T_LPAR)\n        token = lookahead\n        case token.symbol\n        when T_RPAR\n          shift_token\n          data = MailboxQuota.new(mailbox, nil, nil)\n          return UntaggedResponse.new(name, data, @str)\n        when T_ATOM\n          shift_token\n          match(T_SPACE)\n          token = match(T_NUMBER)\n          usage = token.value\n          match(T_SPACE)\n          token = match(T_NUMBER)\n          quota = token.value\n          match(T_RPAR)\n          data = MailboxQuota.new(mailbox, usage, quota)\n          return UntaggedResponse.new(name, data, @str)\n        else\n          parse_error(\"unexpected token %s\", token.symbol)\n        end\n      end\n\n      def getquotaroot_response\n        # Similar to getquota, but only admin can use getquota.\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        mailbox = astring\n        quotaroots = []\n        while true\n          token = lookahead\n          break unless token.symbol == T_SPACE\n          shift_token\n          quotaroots.push(astring)\n        end\n        data = MailboxQuotaRoot.new(mailbox, quotaroots)\n        return UntaggedResponse.new(name, data, @str)\n      end\n\n      def getacl_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        mailbox = astring\n        data = []\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n          while true\n            token = lookahead\n            case token.symbol\n            when T_CRLF\n              break\n            when T_SPACE\n              shift_token\n            end\n            user = astring\n            match(T_SPACE)\n            rights = astring\n            ##XXX data.push([user, rights])\n            data.push(MailboxACLItem.new(user, rights))\n          end\n        end\n        return UntaggedResponse.new(name, data, @str)\n      end\n\n      def search_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        token = lookahead\n        if token.symbol == T_SPACE\n          shift_token\n          data = []\n          while true\n            token = lookahead\n            case token.symbol\n            when T_CRLF\n              break\n            when T_SPACE\n              shift_token\n            end\n            data.push(number)\n          end\n        else\n          data = []\n        end\n        return UntaggedResponse.new(name, data, @str)\n      end\n\n      def thread_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        token = lookahead\n\n        if token.symbol == T_SPACE\n          threads = []\n\n          while true\n            shift_token\n            token = lookahead\n\n            case token.symbol\n            when T_LPAR\n              threads << thread_branch(token)\n            when T_CRLF\n              break\n            end\n          end\n        else\n          # no member\n          threads = []\n        end\n\n        return UntaggedResponse.new(name, threads, @str)\n      end\n\n      def thread_branch(token)\n        rootmember = nil\n        lastmember = nil\n        \n        while true\n          shift_token    # ignore first T_LPAR\n          token = lookahead\n          \n          case token.symbol\n          when T_NUMBER\n            # new member\n            newmember = ThreadMember.new(number, [])\n            if rootmember.nil?\n              rootmember = newmember\n            else    \n              lastmember.children << newmember\n            end     \n            lastmember = newmember\n          when T_SPACE \n            # do nothing \n          when T_LPAR\n            if rootmember.nil?\n              # dummy member\n              lastmember = rootmember = ThreadMember.new(nil, [])\n            end     \n            \n            lastmember.children << thread_branch(token)\n          when T_RPAR\n            break   \n          end     \n        end\n        \n        return rootmember\n      end\n\n      def status_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        mailbox = astring\n        match(T_SPACE)\n        match(T_LPAR)\n        attr = {}\n        while true\n          token = lookahead\n          case token.symbol\n          when T_RPAR\n            shift_token\n            break\n          when T_SPACE\n            shift_token\n          end\n          token = match(T_ATOM)\n          key = token.value.upcase\n          match(T_SPACE)\n          val = number\n          attr[key] = val\n        end\n        data = StatusData.new(mailbox, attr)\n        return UntaggedResponse.new(name, data, @str)\n      end\n\n      def capability_response\n        token = match(T_ATOM)\n        name = token.value.upcase\n        match(T_SPACE)\n        data = []\n        while true\n          token = lookahead\n          case token.symbol\n          when T_CRLF\n            break\n          when T_SPACE\n            shift_token\n          end\n          data.push(atom.upcase)\n        end\n        return UntaggedResponse.new(name, data, @str)\n      end\n\n      def resp_text\n        @lex_state = EXPR_RTEXT\n        token = lookahead\n        if token.symbol == T_LBRA\n          code = resp_text_code\n        else\n          code = nil\n        end\n        token = match(T_TEXT)\n        @lex_state = EXPR_BEG\n        return ResponseText.new(code, token.value)\n      end\n\n      def resp_text_code\n        @lex_state = EXPR_BEG\n        match(T_LBRA)\n        token = match(T_ATOM)\n        name = token.value.upcase\n        case name\n        when /\\A(?:ALERT|PARSE|READ-ONLY|READ-WRITE|TRYCREATE|NOMODSEQ)\\z/n\n          result = ResponseCode.new(name, nil)\n        when /\\A(?:PERMANENTFLAGS)\\z/n\n          match(T_SPACE)\n          result = ResponseCode.new(name, flag_list)\n        when /\\A(?:UIDVALIDITY|UIDNEXT|UNSEEN)\\z/n\n          match(T_SPACE)\n          result = ResponseCode.new(name, number)\n        else\n          token = lookahead\n          if token.symbol == T_SPACE\n            shift_token\n            @lex_state = EXPR_CTEXT\n            token = match(T_TEXT)\n            @lex_state = EXPR_BEG\n            result = ResponseCode.new(name, token.value)\n          else\n            result = ResponseCode.new(name, nil)\n          end\n        end\n        match(T_RBRA)\n        @lex_state = EXPR_RTEXT\n        return result\n      end\n\n      def address_list\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        else\n          result = []\n          match(T_LPAR)\n          while true\n            token = lookahead\n            case token.symbol\n            when T_RPAR\n              shift_token\n              break\n            when T_SPACE\n              shift_token\n            end\n            result.push(address)\n          end\n          return result\n        end\n      end\n\n      ADDRESS_REGEXP = /\\G\\\n(?# 1: NAME     )(?:NIL|\"((?:[^\\x80-\\xff\\x00\\r\\n\"\\\\]|\\\\[\"\\\\])*)\") \\\n(?# 2: ROUTE    )(?:NIL|\"((?:[^\\x80-\\xff\\x00\\r\\n\"\\\\]|\\\\[\"\\\\])*)\") \\\n(?# 3: MAILBOX  )(?:NIL|\"((?:[^\\x80-\\xff\\x00\\r\\n\"\\\\]|\\\\[\"\\\\])*)\") \\\n(?# 4: HOST     )(?:NIL|\"((?:[^\\x80-\\xff\\x00\\r\\n\"\\\\]|\\\\[\"\\\\])*)\")\\\n\\)/ni\n\n      def address\n        match(T_LPAR)\n        if @str.index(ADDRESS_REGEXP, @pos)\n          # address does not include literal.\n          @pos = $~.end(0)\n          name = $1\n          route = $2\n          mailbox = $3\n          host = $4\n          for s in [name, route, mailbox, host]\n            if s\n              s.gsub!(/\\\\([\"\\\\])/n, \"\\\\1\")\n            end\n          end\n        else\n          name = nstring\n          match(T_SPACE)\n          route = nstring\n          match(T_SPACE)\n          mailbox = nstring\n          match(T_SPACE)\n          host = nstring\n          match(T_RPAR)\n        end\n        return Address.new(name, route, mailbox, host)\n      end\n\n#        def flag_list\n#       result = []\n#       match(T_LPAR)\n#       while true\n#         token = lookahead\n#         case token.symbol\n#         when T_RPAR\n#           shift_token\n#           break\n#         when T_SPACE\n#           shift_token\n#         end\n#         result.push(flag)\n#       end\n#       return result\n#        end\n\n#        def flag\n#       token = lookahead\n#       if token.symbol == T_BSLASH\n#         shift_token\n#         token = lookahead\n#         if token.symbol == T_STAR\n#           shift_token\n#           return token.value.intern\n#         else\n#           return atom.intern\n#         end\n#       else\n#         return atom\n#       end\n#        end\n\n      FLAG_REGEXP = /\\\n(?# FLAG        )\\\\([^\\x80-\\xff(){ \\x00-\\x1f\\x7f%\"\\\\]+)|\\\n(?# ATOM        )([^\\x80-\\xff(){ \\x00-\\x1f\\x7f%*\"\\\\]+)/n\n\n      def flag_list\n        if @str.index(/\\(([^)]*)\\)/ni, @pos)\n          @pos = $~.end(0)\n          return $1.scan(FLAG_REGEXP).collect { |flag, atom|\n            atom || flag.capitalize.intern\n          }\n        else\n          parse_error(\"invalid flag list\")\n        end\n      end\n\n      def nstring\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        else\n          return string\n        end\n      end\n\n      def astring\n        token = lookahead\n        if string_token?(token)\n          return string\n        else\n          return atom\n        end\n      end\n\n      def string\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        end\n        token = match(T_QUOTED, T_LITERAL)\n        return token.value\n      end\n\n      STRING_TOKENS = [T_QUOTED, T_LITERAL, T_NIL]\n\n      def string_token?(token)\n        return STRING_TOKENS.include?(token.symbol)\n      end\n\n      def case_insensitive_string\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        end\n        token = match(T_QUOTED, T_LITERAL)\n        return token.value.upcase\n      end\n\n      def atom\n        result = \"\"\n        while true\n          token = lookahead\n          if atom_token?(token)\n            result.concat(token.value)\n            shift_token\n          else\n            if result.empty?\n              parse_error(\"unexpected token %s\", token.symbol)\n            else\n              return result\n            end\n          end\n        end\n      end\n\n      ATOM_TOKENS = [\n        T_ATOM,\n        T_NUMBER,\n        T_NIL,\n        T_LBRA,\n        T_RBRA,\n        T_PLUS\n      ]\n\n      def atom_token?(token)\n        return ATOM_TOKENS.include?(token.symbol)\n      end\n\n      def number\n        token = lookahead\n        if token.symbol == T_NIL\n          shift_token\n          return nil\n        end\n        token = match(T_NUMBER)\n        return token.value.to_i\n      end\n\n      def nil_atom\n        match(T_NIL)\n        return nil\n      end\n\n      def match(*args)\n        token = lookahead\n        unless args.include?(token.symbol)\n          parse_error('unexpected token %s (expected %s)',\n                      token.symbol.id2name,\n                      args.collect {|i| i.id2name}.join(\" or \"))\n        end\n        shift_token\n        return token\n      end\n\n      def lookahead\n        unless @token\n          @token = next_token\n        end\n        return @token\n      end\n\n      def shift_token\n        @token = nil\n      end\n\n      def next_token\n        case @lex_state\n        when EXPR_BEG\n          if @str.index(BEG_REGEXP, @pos)\n            @pos = $~.end(0)\n            if $1\n              return Token.new(T_SPACE, $+)\n            elsif $2\n              return Token.new(T_NIL, $+)\n            elsif $3\n              return Token.new(T_NUMBER, $+)\n            elsif $4\n              return Token.new(T_ATOM, $+)\n            elsif $5\n              return Token.new(T_QUOTED,\n                               $+.gsub(/\\\\([\"\\\\])/n, \"\\\\1\"))\n            elsif $6\n              return Token.new(T_LPAR, $+)\n            elsif $7\n              return Token.new(T_RPAR, $+)\n            elsif $8\n              return Token.new(T_BSLASH, $+)\n            elsif $9\n              return Token.new(T_STAR, $+)\n            elsif $10\n              return Token.new(T_LBRA, $+)\n            elsif $11\n              return Token.new(T_RBRA, $+)\n            elsif $12\n              len = $+.to_i\n              val = @str[@pos, len]\n              @pos += len\n              return Token.new(T_LITERAL, val)\n            elsif $13\n              return Token.new(T_PLUS, $+)\n            elsif $14\n              return Token.new(T_PERCENT, $+)\n            elsif $15\n              return Token.new(T_CRLF, $+)\n            elsif $16\n              return Token.new(T_EOF, $+)\n            else\n              parse_error(\"[Net::IMAP BUG] BEG_REGEXP is invalid\")\n            end\n          else\n            @str.index(/\\S*/n, @pos)\n            parse_error(\"unknown token - %s\", $&.dump)\n          end\n        when EXPR_DATA\n          if @str.index(DATA_REGEXP, @pos)\n            @pos = $~.end(0)\n            if $1\n              return Token.new(T_SPACE, $+)\n            elsif $2\n              return Token.new(T_NIL, $+)\n            elsif $3\n              return Token.new(T_NUMBER, $+)\n            elsif $4\n              return Token.new(T_QUOTED,\n                               $+.gsub(/\\\\([\"\\\\])/n, \"\\\\1\"))\n            elsif $5\n              len = $+.to_i\n              val = @str[@pos, len]\n              @pos += len\n              return Token.new(T_LITERAL, val)\n            elsif $6\n              return Token.new(T_LPAR, $+)\n            elsif $7\n              return Token.new(T_RPAR, $+)\n            else\n              parse_error(\"[Net::IMAP BUG] DATA_REGEXP is invalid\")\n            end\n          else\n            @str.index(/\\S*/n, @pos)\n            parse_error(\"unknown token - %s\", $&.dump)\n          end\n        when EXPR_TEXT\n          if @str.index(TEXT_REGEXP, @pos)\n            @pos = $~.end(0)\n            if $1\n              return Token.new(T_TEXT, $+)\n            else\n              parse_error(\"[Net::IMAP BUG] TEXT_REGEXP is invalid\")\n            end\n          else\n            @str.index(/\\S*/n, @pos)\n            parse_error(\"unknown token - %s\", $&.dump)\n          end\n        when EXPR_RTEXT\n          if @str.index(RTEXT_REGEXP, @pos)\n            @pos = $~.end(0)\n            if $1\n              return Token.new(T_LBRA, $+)\n            elsif $2\n              return Token.new(T_TEXT, $+)\n            else\n              parse_error(\"[Net::IMAP BUG] RTEXT_REGEXP is invalid\")\n            end\n          else\n            @str.index(/\\S*/n, @pos)\n            parse_error(\"unknown token - %s\", $&.dump)\n          end\n        when EXPR_CTEXT\n          if @str.index(CTEXT_REGEXP, @pos)\n            @pos = $~.end(0)\n            if $1\n              return Token.new(T_TEXT, $+)\n            else\n              parse_error(\"[Net::IMAP BUG] CTEXT_REGEXP is invalid\")\n            end\n          else\n            @str.index(/\\S*/n, @pos) #/\n            parse_error(\"unknown token - %s\", $&.dump)\n          end\n        else\n          parse_error(\"illegal @lex_state - %s\", @lex_state.inspect)\n        end\n      end\n\n      def parse_error(fmt, *args)\n        if IMAP.debug\n          $stderr.printf(\"@str: %s\\n\", @str.dump)\n          $stderr.printf(\"@pos: %d\\n\", @pos)\n          $stderr.printf(\"@lex_state: %s\\n\", @lex_state)\n          if @token\n            $stderr.printf(\"@token.symbol: %s\\n\", @token.symbol)\n            $stderr.printf(\"@token.value: %s\\n\", @token.value.inspect)\n          end\n        end\n        raise ResponseParseError, format(fmt, *args)\n      end\n    end\n\n    # Authenticator for the \"LOGIN\" authentication type.  See\n    # #authenticate().\n    class LoginAuthenticator\n      def process(data)\n        case @state\n        when STATE_USER\n          @state = STATE_PASSWORD\n          return @user\n        when STATE_PASSWORD\n          return @password\n        end\n      end\n\n      private\n\n      STATE_USER = :USER\n      STATE_PASSWORD = :PASSWORD\n\n      def initialize(user, password)\n        @user = user\n        @password = password\n        @state = STATE_USER\n      end\n    end\n    add_authenticator \"LOGIN\", LoginAuthenticator\n\n    # Authenticator for the \"CRAM-MD5\" authentication type.  See\n    # #authenticate().\n    class CramMD5Authenticator\n      def process(challenge)\n        digest = hmac_md5(challenge, @password)\n        return @user + \" \" + digest\n      end\n\n      private\n\n      def initialize(user, password)\n        @user = user\n        @password = password\n      end\n\n      def hmac_md5(text, key)\n        if key.length > 64\n          key = Digest::MD5.digest(key)\n        end\n\n        k_ipad = key + \"\\0\" * (64 - key.length)\n        k_opad = key + \"\\0\" * (64 - key.length)\n        for i in 0..63\n          k_ipad[i] ^= 0x36\n          k_opad[i] ^= 0x5c\n        end\n\n        digest = Digest::MD5.digest(k_ipad + text)\n\n        return Digest::MD5.hexdigest(k_opad + digest)\n      end\n    end\n    add_authenticator \"CRAM-MD5\", CramMD5Authenticator\n\n    # Superclass of IMAP errors.\n    class Error < StandardError\n    end\n\n    # Error raised when data is in the incorrect format.\n    class DataFormatError < Error\n    end\n\n    # Error raised when a response from the server is non-parseable.\n    class ResponseParseError < Error\n    end\n\n    # Superclass of all errors used to encapsulate \"fail\" responses\n    # from the server.\n    class ResponseError < Error\n    end\n\n    # Error raised upon a \"NO\" response from the server, indicating\n    # that the client command could not be completed successfully.\n    class NoResponseError < ResponseError\n    end\n\n    # Error raised upon a \"BAD\" response from the server, indicating\n    # that the client command violated the IMAP protocol, or an internal\n    # server failure has occurred.\n    class BadResponseError < ResponseError\n    end\n\n    # Error raised upon a \"BYE\" response from the server, indicating \n    # that the client is not being allowed to login, or has been timed\n    # out due to inactivity.\n    class ByeResponseError < ResponseError\n    end\n  end\nend\n\nif __FILE__ == $0\n  # :enddoc:\n  require \"getoptlong\"\n\n  $stdout.sync = true\n  $port = nil\n  $user = ENV[\"USER\"] || ENV[\"LOGNAME\"]\n  $auth = \"login\"\n  $ssl = false\n\n  def usage\n    $stderr.print <<EOF\nusage: #{$0} [options] <host>\n\n  --help                        print this message\n  --port=PORT                   specifies port\n  --user=USER                   specifies user\n  --auth=AUTH                   specifies auth type\n  --ssl                         use ssl\nEOF\n  end\n\n  def get_password\n    print \"password: \"\n    system(\"stty\", \"-echo\")\n    begin\n      return gets.chop\n    ensure\n      system(\"stty\", \"echo\")\n      print \"\\n\"\n    end\n  end\n\n  def get_command\n    printf(\"%s@%s> \", $user, $host)\n    if line = gets\n      return line.strip.split(/\\s+/)\n    else\n      return nil\n    end\n  end\n\n  parser = GetoptLong.new\n  parser.set_options(['--debug', GetoptLong::NO_ARGUMENT],\n                     ['--help', GetoptLong::NO_ARGUMENT],\n                     ['--port', GetoptLong::REQUIRED_ARGUMENT],\n                     ['--user', GetoptLong::REQUIRED_ARGUMENT],\n                     ['--auth', GetoptLong::REQUIRED_ARGUMENT],\n                     ['--ssl', GetoptLong::NO_ARGUMENT])\n  begin\n    parser.each_option do |name, arg|\n      case name\n      when \"--port\"\n        $port = arg\n      when \"--user\"\n        $user = arg\n      when \"--auth\"\n        $auth = arg\n      when \"--ssl\"\n        $ssl = true\n      when \"--debug\"\n        Net::IMAP.debug = true\n      when \"--help\"\n        usage\n        exit(1)\n      end\n    end\n  rescue\n    usage\n    exit(1)\n  end\n\n  $host = ARGV.shift\n  unless $host\n    usage\n    exit(1)\n  end\n  $port ||= $ssl ? 993 : 143\n    \n  imap = Net::IMAP.new($host, $port, $ssl)\n  begin\n    password = get_password\n    imap.authenticate($auth, $user, password)\n    while true\n      cmd, *args = get_command\n      break unless cmd\n      begin\n        case cmd\n        when \"list\"\n          for mbox in imap.list(\"\", args[0] || \"*\")\n            if mbox.attr.include?(Net::IMAP::NOSELECT)\n              prefix = \"!\"\n            elsif mbox.attr.include?(Net::IMAP::MARKED)\n              prefix = \"*\"\n            else\n              prefix = \" \"\n            end\n            print prefix, mbox.name, \"\\n\"\n          end\n        when \"select\"\n          imap.select(args[0] || \"inbox\")\n          print \"ok\\n\"\n        when \"close\"\n          imap.close\n          print \"ok\\n\"\n        when \"summary\"\n          unless messages = imap.responses[\"EXISTS\"][-1]\n            puts \"not selected\"\n            next\n          end\n          if messages > 0\n            for data in imap.fetch(1..-1, [\"ENVELOPE\"])\n              print data.seqno, \": \", data.attr[\"ENVELOPE\"].subject, \"\\n\"\n            end\n          else\n            puts \"no message\"\n          end\n        when \"fetch\"\n          if args[0]\n            data = imap.fetch(args[0].to_i, [\"RFC822.HEADER\", \"RFC822.TEXT\"])[0]\n            puts data.attr[\"RFC822.HEADER\"]\n            puts data.attr[\"RFC822.TEXT\"]\n          else\n            puts \"missing argument\"\n          end\n        when \"logout\", \"exit\", \"quit\"\n          break\n        when \"help\", \"?\"\n          print <<EOF\nlist [pattern]                  list mailboxes\nselect [mailbox]                select mailbox\nclose                           close mailbox\nsummary                         display summary\nfetch [msgno]                   display message\nlogout                          logout\nhelp, ?                         display help message\nEOF\n        else\n          print \"unknown command: \", cmd, \"\\n\"\n        end\n      rescue Net::IMAP::Error\n        puts $!\n      end\n    end\n  ensure\n    imap.logout\n    imap.disconnect\n  end\nend\n\n"
  },
  {
    "path": "lib/net/pop.rb",
    "content": "# = net/pop.rb\n#\n# Copyright (c) 1999-2007 Yukihiro Matsumoto.\n#\n# Copyright (c) 1999-2007 Minero Aoki.\n# \n# Written & maintained by Minero Aoki <aamine@loveruby.net>.\n#\n# Documented by William Webber and Minero Aoki.\n# \n# This program is free software. You can re-distribute and/or\n# modify this program under the same terms as Ruby itself,\n# Ruby Distribute License.\n# \n# NOTE: You can find Japanese version of this document at:\n# http://www.ruby-lang.org/ja/man/html/net_pop.html\n# \n#   $Id$\n# \n# See Net::POP3 for documentation.\n#\n\nrequire 'net/protocol'\nrequire 'digest/md5'\nrequire 'timeout'\n\nbegin\n  require \"openssl/ssl\"\nrescue LoadError\nend\n\nmodule Net\n\n  # Non-authentication POP3 protocol error\n  # (reply code \"-ERR\", except authentication).\n  class POPError < ProtocolError; end\n\n  # POP3 authentication error.\n  class POPAuthenticationError < ProtoAuthError; end\n\n  # Unexpected response from the server.\n  class POPBadResponse < POPError; end\n\n  #\n  # = Net::POP3\n  #\n  # == What is This Library?\n  # \n  # This library provides functionality for retrieving \n  # email via POP3, the Post Office Protocol version 3. For details\n  # of POP3, see [RFC1939] (http://www.ietf.org/rfc/rfc1939.txt).\n  # \n  # == Examples\n  # \n  # === Retrieving Messages \n  # \n  # This example retrieves messages from the server and deletes them \n  # on the server.\n  #\n  # Messages are written to files named 'inbox/1', 'inbox/2', ....\n  # Replace 'pop.example.com' with your POP3 server address, and\n  # 'YourAccount' and 'YourPassword' with the appropriate account\n  # details.\n  # \n  #     require 'net/pop'\n  # \n  #     pop = Net::POP3.new('pop.example.com')\n  #     pop.start('YourAccount', 'YourPassword')             # (1)\n  #     if pop.mails.empty?\n  #       puts 'No mail.'\n  #     else\n  #       i = 0\n  #       pop.each_mail do |m|   # or \"pop.mails.each ...\"   # (2)\n  #         File.open(\"inbox/#{i}\", 'w') do |f|\n  #           f.write m.pop\n  #         end\n  #         m.delete\n  #         i += 1\n  #       end\n  #       puts \"#{pop.mails.size} mails popped.\"\n  #     end\n  #     pop.finish                                           # (3)\n  # \n  # 1. Call Net::POP3#start and start POP session.\n  # 2. Access messages by using POP3#each_mail and/or POP3#mails.\n  # 3. Close POP session by calling POP3#finish or use the block form of #start.\n  # \n  # === Shortened Code\n  # \n  # The example above is very verbose. You can shorten the code by using\n  # some utility methods. First, the block form of Net::POP3.start can\n  # be used instead of POP3.new, POP3#start and POP3#finish.\n  # \n  #     require 'net/pop'\n  # \n  #     Net::POP3.start('pop.example.com', 110,\n  #                     'YourAccount', 'YourPassword') do |pop|\n  #       if pop.mails.empty?\n  #         puts 'No mail.'\n  #       else\n  #         i = 0\n  #         pop.each_mail do |m|   # or \"pop.mails.each ...\"\n  #           File.open(\"inbox/#{i}\", 'w') do |f|\n  #             f.write m.pop\n  #           end\n  #           m.delete\n  #           i += 1\n  #         end\n  #         puts \"#{pop.mails.size} mails popped.\"\n  #       end\n  #     end\n  # \n  # POP3#delete_all is an alternative for #each_mail and #delete.\n  # \n  #     require 'net/pop'\n  # \n  #     Net::POP3.start('pop.example.com', 110,\n  #                     'YourAccount', 'YourPassword') do |pop|\n  #       if pop.mails.empty?\n  #         puts 'No mail.'\n  #       else\n  #         i = 1\n  #         pop.delete_all do |m|\n  #           File.open(\"inbox/#{i}\", 'w') do |f|\n  #             f.write m.pop\n  #           end\n  #           i += 1\n  #         end\n  #       end\n  #     end\n  # \n  # And here is an even shorter example.\n  # \n  #     require 'net/pop'\n  # \n  #     i = 0\n  #     Net::POP3.delete_all('pop.example.com', 110,\n  #                          'YourAccount', 'YourPassword') do |m|\n  #       File.open(\"inbox/#{i}\", 'w') do |f|\n  #         f.write m.pop\n  #       end\n  #       i += 1\n  #     end\n  # \n  # === Memory Space Issues\n  # \n  # All the examples above get each message as one big string.\n  # This example avoids this.\n  # \n  #     require 'net/pop'\n  # \n  #     i = 1\n  #     Net::POP3.delete_all('pop.example.com', 110,\n  #                          'YourAccount', 'YourPassword') do |m|\n  #       File.open(\"inbox/#{i}\", 'w') do |f|\n  #         m.pop do |chunk|    # get a message little by little.\n  #           f.write chunk\n  #         end\n  #         i += 1\n  #       end\n  #     end\n  # \n  # === Using APOP\n  # \n  # The net/pop library supports APOP authentication.\n  # To use APOP, use the Net::APOP class instead of the Net::POP3 class.\n  # You can use the utility method, Net::POP3.APOP(). For example:\n  # \n  #     require 'net/pop'\n  # \n  #     # Use APOP authentication if $isapop == true\n  #     pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)\n  #     pop.start(YourAccount', 'YourPassword') do |pop|\n  #       # Rest of the code is the same.\n  #     end\n  # \n  # === Fetch Only Selected Mail Using 'UIDL' POP Command\n  # \n  # If your POP server provides UIDL functionality,\n  # you can grab only selected mails from the POP server.\n  # e.g.\n  # \n  #     def need_pop?( id )\n  #       # determine if we need pop this mail...\n  #     end\n  # \n  #     Net::POP3.start('pop.example.com', 110,\n  #                     'Your account', 'Your password') do |pop|\n  #       pop.mails.select { |m| need_pop?(m.unique_id) }.each do |m|\n  #         do_something(m.pop)\n  #       end\n  #     end\n  # \n  # The POPMail#unique_id() method returns the unique-id of the message as a\n  # String. Normally the unique-id is a hash of the message.\n  # \n  class POP3 < Protocol\n\n    Revision = %q$Revision$.split[1]\n\n    #\n    # Class Parameters\n    #\n\n    def POP3.default_port\n      default_pop3_port()\n    end\n\n    # The default port for POP3 connections, port 110\n    def POP3.default_pop3_port\n      110\n    end\n    \n    # The default port for POP3S connections, port 995\n    def POP3.default_pop3s_port\n      995\n    end\n\n    def POP3.socket_type   #:nodoc: obsolete\n      Net::InternetMessageIO\n    end\n\n    #\n    # Utilities\n    #\n\n    # Returns the APOP class if +isapop+ is true; otherwise, returns\n    # the POP class.  For example:\n    #\n    #     # Example 1\n    #     pop = Net::POP3::APOP($is_apop).new(addr, port)\n    #\n    #     # Example 2\n    #     Net::POP3::APOP($is_apop).start(addr, port) do |pop|\n    #       ....\n    #     end\n    #\n    def POP3.APOP(isapop)\n      isapop ? APOP : POP3\n    end\n\n    # Starts a POP3 session and iterates over each POPMail object,\n    # yielding it to the +block+.\n    # This method is equivalent to:\n    #\n    #     Net::POP3.start(address, port, account, password) do |pop|\n    #       pop.each_mail do |m|\n    #         yield m\n    #       end\n    #     end\n    #\n    # This method raises a POPAuthenticationError if authentication fails.\n    #\n    # === Example\n    #\n    #     Net::POP3.foreach('pop.example.com', 110,\n    #                       'YourAccount', 'YourPassword') do |m|\n    #       file.write m.pop\n    #       m.delete if $DELETE\n    #     end\n    #\n    def POP3.foreach(address, port = nil,\n                     account = nil, password = nil,\n                     isapop = false, &block)  # :yields: message\n      start(address, port, account, password, isapop) {|pop|\n        pop.each_mail(&block)\n      }\n    end\n\n    # Starts a POP3 session and deletes all messages on the server.\n    # If a block is given, each POPMail object is yielded to it before\n    # being deleted.\n    #\n    # This method raises a POPAuthenticationError if authentication fails.\n    #\n    # === Example\n    #\n    #     Net::POP3.delete_all('pop.example.com', 110,\n    #                          'YourAccount', 'YourPassword') do |m|\n    #       file.write m.pop\n    #     end\n    #\n    def POP3.delete_all(address, port = nil,\n                        account = nil, password = nil,\n                        isapop = false, &block)\n      start(address, port, account, password, isapop) {|pop|\n        pop.delete_all(&block)\n      }\n    end\n\n    # Opens a POP3 session, attempts authentication, and quits.\n    #\n    # This method raises POPAuthenticationError if authentication fails.\n    #\n    # === Example: normal POP3\n    #\n    #     Net::POP3.auth_only('pop.example.com', 110,\n    #                         'YourAccount', 'YourPassword')\n    #\n    # === Example: APOP\n    #\n    #     Net::POP3.auth_only('pop.example.com', 110,\n    #                         'YourAccount', 'YourPassword', true)\n    #\n    def POP3.auth_only(address, port = nil,\n                       account = nil, password = nil,\n                       isapop = false)\n      new(address, port, isapop).auth_only account, password\n    end\n\n    # Starts a pop3 session, attempts authentication, and quits.\n    # This method must not be called while POP3 session is opened.\n    # This method raises POPAuthenticationError if authentication fails.\n    def auth_only(account, password)\n      raise IOError, 'opening previously opened POP session' if started?\n      start(account, password) {\n        ;\n      }\n    end\n\n    #\n    # SSL\n    #\n\n    @ssl_params = nil\n\n    # call-seq:\n    #    Net::POP.enable_ssl(params = {})\n    #\n    # Enable SSL for all new instances.\n    # +params+ is passed to OpenSSL::SSLContext#set_params.\n    def POP3.enable_ssl(*args)\n      @ssl_params = create_ssl_params(*args)\n    end\n\n    def POP3.create_ssl_params(verify_or_params = {}, certs = nil)\n      begin\n        params = verify_or_params.to_hash\n      rescue NoMethodError\n        params = {}\n        params[:verify_mode] = verify_or_params\n        if certs\n          if File.file?(certs)\n            params[:ca_file] = certs\n          elsif File.directory?(certs)\n            params[:ca_path] = certs\n          end\n        end\n      end\n      return params\n    end\n\n    # Disable SSL for all new instances.\n    def POP3.disable_ssl\n      @ssl_params = nil\n    end\n\n    def POP3.ssl_params\n      return @ssl_params\n    end\n\n    def POP3.use_ssl?\n      return !@ssl_params.nil?\n    end\n\n    def POP3.verify\n      return @ssl_params[:verify_mode]\n    end\n\n    def POP3.certs\n      return @ssl_params[:ca_file] || @ssl_params[:ca_path]\n    end\n\n    #\n    # Session management\n    #\n\n    # Creates a new POP3 object and open the connection.  Equivalent to \n    #\n    #   Net::POP3.new(address, port, isapop).start(account, password)\n    #\n    # If +block+ is provided, yields the newly-opened POP3 object to it,\n    # and automatically closes it at the end of the session.\n    #\n    # === Example\n    #\n    #    Net::POP3.start(addr, port, account, password) do |pop|\n    #      pop.each_mail do |m|\n    #        file.write m.pop\n    #        m.delete\n    #      end\n    #    end\n    #\n    def POP3.start(address, port = nil,\n                   account = nil, password = nil,\n                   isapop = false, &block)   # :yield: pop\n      new(address, port, isapop).start(account, password, &block)\n    end\n    \n    # Creates a new POP3 object.\n    #\n    # +address+ is the hostname or ip address of your POP3 server.\n    #\n    # The optional +port+ is the port to connect to.\n    #\n    # The optional +isapop+ specifies whether this connection is going\n    # to use APOP authentication; it defaults to +false+.\n    #\n    # This method does *not* open the TCP connection.\n    def initialize(addr, port = nil, isapop = false)\n      @address = addr\n      @ssl_params = POP3.ssl_params\n      @port = port\n      @apop = isapop\n      \n      @command = nil\n      @socket = nil\n      @started = false\n      @open_timeout = 30\n      @read_timeout = 60\n      @debug_output = nil\n\n      @mails = nil\n      @n_mails = nil\n      @n_bytes = nil\n    end\n\n    # Does this instance use APOP authentication?\n    def apop?\n      @apop\n    end\n\n    # does this instance use SSL?\n    def use_ssl?\n      return !@ssl_params.nil?\n    end\n   \n    # call-seq:\n    #    Net::POP#enable_ssl(params = {})\n    #\n    # Enables SSL for this instance.  Must be called before the connection is\n    # established to have any effect.\n    # +params[:port]+ is port to establish the SSL connection on; Defaults to 995.\n    # +params+ (except :port) is passed to OpenSSL::SSLContext#set_params.\n    def enable_ssl(verify_or_params = {}, certs = nil, port = nil)\n      begin\n        @ssl_params = verify_or_params.to_hash.dup\n        @port = @ssl_params.delete(:port) || @port\n      rescue NoMethodError\n        @ssl_params = POP3.create_ssl_params(verify_or_params, certs)\n        @port = port || @port\n      end\n    end\n    \n    def disable_ssl\n      @ssl_params = nil\n    end\n\n    # Provide human-readable stringification of class state.\n    def inspect\n      \"#<#{self.class} #{@address}:#{@port} open=#{@started}>\"\n    end\n\n    # *WARNING*: This method causes a serious security hole.\n    # Use this method only for debugging.\n    #\n    # Set an output stream for debugging.\n    #\n    # === Example\n    #\n    #   pop = Net::POP.new(addr, port)\n    #   pop.set_debug_output $stderr\n    #   pop.start(account, passwd) do |pop|\n    #     ....\n    #   end\n    #\n    def set_debug_output(arg)\n      @debug_output = arg\n    end\n\n    # The address to connect to.\n    attr_reader :address\n\n    # The port number to connect to.\n    def port\n      return @port || (use_ssl? ? POP3.default_pop3s_port : POP3.default_pop3_port)\n    end\n\n    # Seconds to wait until a connection is opened.\n    # If the POP3 object cannot open a connection within this time,\n    # it raises a TimeoutError exception.\n    attr_accessor :open_timeout\n\n    # Seconds to wait until reading one block (by one read(1) call).\n    # If the POP3 object cannot complete a read() within this time,\n    # it raises a TimeoutError exception.\n    attr_reader :read_timeout\n\n    # Set the read timeout.\n    def read_timeout=(sec)\n      @command.socket.read_timeout = sec if @command\n      @read_timeout = sec\n    end\n\n    # +true+ if the POP3 session has started.\n    def started?\n      @started\n    end\n\n    alias active? started?   #:nodoc: obsolete\n\n    # Starts a POP3 session.\n    #\n    # When called with block, gives a POP3 object to the block and\n    # closes the session after block call finishes.\n    #\n    # This method raises a POPAuthenticationError if authentication fails.\n    def start(account, password) # :yield: pop\n      raise IOError, 'POP session already started' if @started\n      if block_given?\n        begin\n          do_start account, password\n          return yield(self)\n        ensure\n          do_finish\n        end\n      else\n        do_start account, password\n        return self\n      end\n    end\n\n    def do_start(account, password)\n      s = timeout(@open_timeout) { TCPSocket.open(@address, port) }\n      if use_ssl?\n        raise 'openssl library not installed' unless defined?(OpenSSL)\n        context = OpenSSL::SSL::SSLContext.new\n        context.set_params(@ssl_params)\n        s = OpenSSL::SSL::SSLSocket.new(s, context)\n        s.sync_close = true\n        s.connect\n        if context.verify_mode != OpenSSL::SSL::VERIFY_NONE\n          s.post_connection_check(@address)\n        end\n      end\n      @socket = InternetMessageIO.new(s)\n      logging \"POP session started: #{@address}:#{@port} (#{@apop ? 'APOP' : 'POP'})\"\n      @socket.read_timeout = @read_timeout\n      @socket.debug_output = @debug_output\n      on_connect\n      @command = POP3Command.new(@socket)\n      if apop?\n        @command.apop account, password\n      else\n        @command.auth account, password\n      end\n      @started = true\n    ensure\n      # Authentication failed, clean up connection.\n      unless @started\n        s.close if s and not s.closed?\n        @socket = nil\n        @command = nil\n      end\n    end\n    private :do_start\n\n    def on_connect\n    end\n    private :on_connect\n\n    # Finishes a POP3 session and closes TCP connection.\n    def finish\n      raise IOError, 'POP session not yet started' unless started?\n      do_finish\n    end\n\n    def do_finish\n      @mails = nil\n      @n_mails = nil\n      @n_bytes = nil\n      @command.quit if @command\n    ensure\n      @started = false\n      @command = nil\n      @socket.close if @socket and not @socket.closed?\n      @socket = nil\n    end\n    private :do_finish\n\n    def command\n      raise IOError, 'POP session not opened yet' \\\n                                      if not @socket or @socket.closed?\n      @command\n    end\n    private :command\n\n    #\n    # POP protocol wrapper\n    #\n\n    # Returns the number of messages on the POP server.\n    def n_mails\n      return @n_mails if @n_mails\n      @n_mails, @n_bytes = command().stat\n      @n_mails\n    end\n\n    # Returns the total size in bytes of all the messages on the POP server.\n    def n_bytes\n      return @n_bytes if @n_bytes\n      @n_mails, @n_bytes = command().stat\n      @n_bytes\n    end\n\n    # Returns an array of Net::POPMail objects, representing all the\n    # messages on the server.  This array is renewed when the session\n    # restarts; otherwise, it is fetched from the server the first time\n    # this method is called (directly or indirectly) and cached.\n    #\n    # This method raises a POPError if an error occurs.\n    def mails\n      return @mails.dup if @mails\n      if n_mails() == 0\n        # some popd raises error for LIST on the empty mailbox.\n        @mails = []\n        return []\n      end\n\n      @mails = command().list.map {|num, size|\n        POPMail.new(num, size, self, command())\n      }\n      @mails.dup\n    end\n\n    # Yields each message to the passed-in block in turn.\n    # Equivalent to:\n    # \n    #   pop3.mails.each do |popmail|\n    #     ....\n    #   end\n    #\n    # This method raises a POPError if an error occurs.\n    def each_mail(&block)  # :yield: message\n      mails().each(&block)\n    end\n\n    alias each each_mail\n\n    # Deletes all messages on the server.\n    #\n    # If called with a block, yields each message in turn before deleting it.\n    #\n    # === Example\n    #\n    #     n = 1\n    #     pop.delete_all do |m|\n    #       File.open(\"inbox/#{n}\") do |f|\n    #         f.write m.pop\n    #       end\n    #       n += 1\n    #     end\n    #\n    # This method raises a POPError if an error occurs.\n    #\n    def delete_all # :yield: message\n      mails().each do |m|\n        yield m if block_given?\n        m.delete unless m.deleted?\n      end\n    end\n\n    # Resets the session.  This clears all \"deleted\" marks from messages.\n    #\n    # This method raises a POPError if an error occurs.\n    def reset\n      command().rset\n      mails().each do |m|\n        m.instance_eval {\n          @deleted = false\n        }\n      end\n    end\n\n    def set_all_uids   #:nodoc: internal use only (called from POPMail#uidl)\n      command().uidl.each do |num, uid|\n        @mails.find {|m| m.number == num }.uid = uid\n      end\n    end\n\n    def logging(msg)\n      @debug_output << msg + \"\\n\" if @debug_output\n    end\n\n  end   # class POP3\n\n  # class aliases\n  POP = POP3\n  POPSession  = POP3\n  POP3Session = POP3\n\n  #\n  # This class is equivalent to POP3, except that it uses APOP authentication.\n  #\n  class APOP < POP3\n    # Always returns true.\n    def apop?\n      true\n    end\n  end\n\n  # class aliases\n  APOPSession = APOP\n\n  #\n  # This class represents a message which exists on the POP server.\n  # Instances of this class are created by the POP3 class; they should\n  # not be directly created by the user.\n  #\n  class POPMail\n\n    def initialize(num, len, pop, cmd)   #:nodoc:\n      @number = num\n      @length = len\n      @pop = pop\n      @command = cmd\n      @deleted = false\n      @uid = nil\n    end\n\n    # The sequence number of the message on the server.\n    attr_reader :number\n\n    # The length of the message in octets.\n    attr_reader :length\n    alias size length\n\n    # Provide human-readable stringification of class state.\n    def inspect\n      \"#<#{self.class} #{@number}#{@deleted ? ' deleted' : ''}>\"\n    end\n\n    #\n    # This method fetches the message.  If called with a block, the\n    # message is yielded to the block one chunk at a time.  If called\n    # without a block, the message is returned as a String.  The optional \n    # +dest+ argument will be prepended to the returned String; this\n    # argument is essentially obsolete.\n    #\n    # === Example without block\n    #\n    #     POP3.start('pop.example.com', 110,\n    #                'YourAccount, 'YourPassword') do |pop|\n    #       n = 1\n    #       pop.mails.each do |popmail|\n    #         File.open(\"inbox/#{n}\", 'w') do |f|\n    #           f.write popmail.pop              \n    #         end\n    #         popmail.delete\n    #         n += 1\n    #       end\n    #     end\n    #\n    # === Example with block\n    #\n    #     POP3.start('pop.example.com', 110,\n    #                'YourAccount, 'YourPassword') do |pop|\n    #       n = 1\n    #       pop.mails.each do |popmail|\n    #         File.open(\"inbox/#{n}\", 'w') do |f|\n    #           popmail.pop do |chunk|            ####\n    #             f.write chunk\n    #           end\n    #         end\n    #         n += 1\n    #       end\n    #     end\n    #\n    # This method raises a POPError if an error occurs.\n    #\n    def pop( dest = '', &block ) # :yield: message_chunk\n      if block_given?\n        @command.retr(@number, &block)\n        nil\n      else\n        @command.retr(@number) do |chunk|\n          dest << chunk\n        end\n        dest\n      end\n    end\n\n    alias all pop    #:nodoc: obsolete\n    alias mail pop   #:nodoc: obsolete\n\n    # Fetches the message header and +lines+ lines of body. \n    #\n    # The optional +dest+ argument is obsolete.\n    #\n    # This method raises a POPError if an error occurs.\n    def top(lines, dest = '')\n      @command.top(@number, lines) do |chunk|\n        dest << chunk\n      end\n      dest\n    end\n\n    # Fetches the message header.     \n    #\n    # The optional +dest+ argument is obsolete.\n    #\n    # This method raises a POPError if an error occurs.\n    def header(dest = '')\n      top(0, dest)\n    end\n\n    # Marks a message for deletion on the server.  Deletion does not\n    # actually occur until the end of the session; deletion may be\n    # cancelled for _all_ marked messages by calling POP3#reset().\n    #\n    # This method raises a POPError if an error occurs.\n    #\n    # === Example\n    #\n    #     POP3.start('pop.example.com', 110,\n    #                'YourAccount, 'YourPassword') do |pop|\n    #       n = 1\n    #       pop.mails.each do |popmail|\n    #         File.open(\"inbox/#{n}\", 'w') do |f|\n    #           f.write popmail.pop\n    #         end\n    #         popmail.delete         ####\n    #         n += 1\n    #       end\n    #     end\n    #\n    def delete\n      @command.dele @number\n      @deleted = true\n    end\n\n    alias delete! delete    #:nodoc: obsolete\n\n    # True if the mail has been deleted.\n    def deleted?\n      @deleted\n    end\n\n    # Returns the unique-id of the message.\n    # Normally the unique-id is a hash string of the message.\n    #\n    # This method raises a POPError if an error occurs.\n    def unique_id\n      return @uid if @uid\n      @pop.set_all_uids\n      @uid\n    end\n\n    alias uidl unique_id\n\n    def uid=(uid)   #:nodoc: internal use only\n      @uid = uid\n    end\n\n  end   # class POPMail\n\n\n  class POP3Command   #:nodoc: internal use only\n\n    def initialize(sock)\n      @socket = sock\n      @error_occured = false\n      res = check_response(critical { recv_response() })\n      @apop_stamp = res.slice(/<[!-~]+@[!-~]+>/)\n    end\n\n    def inspect\n      \"#<#{self.class} socket=#{@socket}>\"\n    end\n\n    def auth(account, password)\n      check_response_auth(critical {\n        check_response_auth(get_response('USER %s', account))\n        get_response('PASS %s', password)\n      })\n    end\n\n    def apop(account, password)\n      raise POPAuthenticationError, 'not APOP server; cannot login' \\\n                                                      unless @apop_stamp\n      check_response_auth(critical {\n        get_response('APOP %s %s',\n                     account,\n                     Digest::MD5.hexdigest(@apop_stamp + password))\n      })\n    end\n\n    def list\n      critical {\n        getok 'LIST'\n        list = []\n        @socket.each_list_item do |line|\n          m = /\\A(\\d+)[ \\t]+(\\d+)/.match(line) or\n                  raise POPBadResponse, \"bad response: #{line}\"\n          list.push  [m[1].to_i, m[2].to_i]\n        end\n        return list\n      }\n    end\n\n    def stat\n      res = check_response(critical { get_response('STAT') })\n      m = /\\A\\+OK\\s+(\\d+)\\s+(\\d+)/.match(res) or\n              raise POPBadResponse, \"wrong response format: #{res}\"\n      [m[1].to_i, m[2].to_i]\n    end\n\n    def rset\n      check_response(critical { get_response('RSET') })\n    end\n\n    def top(num, lines = 0, &block)\n      critical {\n        getok('TOP %d %d', num, lines)\n        @socket.each_message_chunk(&block)\n      }\n    end\n\n    def retr(num, &block)\n      critical {\n        getok('RETR %d', num)\n        @socket.each_message_chunk(&block)\n      }\n    end\n    \n    def dele(num)\n      check_response(critical { get_response('DELE %d', num) })\n    end\n\n    def uidl(num = nil)\n      if num\n        res = check_response(critical { get_response('UIDL %d', num) })\n        return res.split(/ /)[1]\n      else\n        critical {\n          getok('UIDL')\n          table = {}\n          @socket.each_list_item do |line|\n            num, uid = line.split\n            table[num.to_i] = uid\n          end\n          return table\n        }\n      end\n    end\n\n    def quit\n      check_response(critical { get_response('QUIT') })\n    end\n\n    private\n\n    def getok(fmt, *fargs)\n      @socket.writeline sprintf(fmt, *fargs)\n      check_response(recv_response())\n    end\n\n    def get_response(fmt, *fargs)\n      @socket.writeline sprintf(fmt, *fargs)\n      recv_response()\n    end\n\n    def recv_response\n      @socket.readline\n    end\n\n    def check_response(res)\n      raise POPError, res unless /\\A\\+OK/i =~ res\n      res\n    end\n\n    def check_response_auth(res)\n      raise POPAuthenticationError, res unless /\\A\\+OK/i =~ res\n      res\n    end\n\n    def critical\n      return '+OK dummy ok response' if @error_occured\n      begin\n        return yield()\n      rescue Exception\n        @error_occured = true\n        raise\n      end\n    end\n\n  end   # class POP3Command\n\nend   # module Net\n"
  },
  {
    "path": "lib/net/protocol.rb",
    "content": "#\n# = net/protocol.rb\n#\n#--\n# Copyright (c) 1999-2005 Yukihiro Matsumoto\n# Copyright (c) 1999-2005 Minero Aoki\n#\n# written and maintained by Minero Aoki <aamine@loveruby.net>\n#\n# This program is free software. You can re-distribute and/or\n# modify this program under the same terms as Ruby itself,\n# Ruby Distribute License or GNU General Public License.\n#\n# $Id$\n#++\n#\n# WARNING: This file is going to remove.\n# Do not rely on the implementation written in this file.\n#\n\nrequire 'socket'\nrequire 'timeout'\n\nmodule Net # :nodoc:\n\n  class Protocol   #:nodoc: internal use only\n    private\n    def Protocol.protocol_param(name, val)\n      module_eval(<<-End, __FILE__, __LINE__ + 1)\n        def #{name}\n          #{val}\n        end\n      End\n    end\n  end\n\n\n  class ProtocolError          < StandardError; end\n  class ProtoSyntaxError       < ProtocolError; end\n  class ProtoFatalError        < ProtocolError; end\n  class ProtoUnknownError      < ProtocolError; end\n  class ProtoServerError       < ProtocolError; end\n  class ProtoAuthError         < ProtocolError; end\n  class ProtoCommandError      < ProtocolError; end\n  class ProtoRetriableError    < ProtocolError; end\n  ProtocRetryError = ProtoRetriableError\n\n\n  class BufferedIO   #:nodoc: internal use only\n    def initialize(io)\n      @io = io\n      @read_timeout = 60\n      @debug_output = nil\n      @rbuf = ''\n    end\n\n    attr_reader :io\n    attr_accessor :read_timeout\n    attr_accessor :debug_output\n\n    def inspect\n      \"#<#{self.class} io=#{@io}>\"\n    end\n\n    def closed?\n      @io.closed?\n    end\n\n    def close\n      @io.close\n    end\n\n    #\n    # Read\n    #\n\n    public\n\n    def read(len, dest = '', ignore_eof = false)\n      LOG \"reading #{len} bytes...\"\n      read_bytes = 0\n      begin\n        while read_bytes + @rbuf.size < len\n          dest << (s = rbuf_consume(@rbuf.size))\n          read_bytes += s.size\n          rbuf_fill\n        end\n        dest << (s = rbuf_consume(len - read_bytes))\n        read_bytes += s.size\n      rescue EOFError\n        raise unless ignore_eof\n      end\n      LOG \"read #{read_bytes} bytes\"\n      dest\n    end\n\n    def read_all(dest = '')\n      LOG 'reading all...'\n      read_bytes = 0\n      begin\n        while true\n          dest << (s = rbuf_consume(@rbuf.size))\n          read_bytes += s.size\n          rbuf_fill\n        end\n      rescue EOFError\n        ;\n      end\n      LOG \"read #{read_bytes} bytes\"\n      dest\n    end\n\n    def readuntil(terminator, ignore_eof = false)\n      begin\n        until idx = @rbuf.index(terminator)\n          rbuf_fill\n        end\n        return rbuf_consume(idx + terminator.size)\n      rescue EOFError\n        raise unless ignore_eof\n        return rbuf_consume(@rbuf.size)\n      end\n    end\n        \n    def readline\n      readuntil(\"\\n\").chop\n    end\n\n    private\n\n    BUFSIZE = 1024 * 16\n\n    def rbuf_fill\n      timeout(@read_timeout) {\n        @rbuf << @io.sysread(BUFSIZE)\n      }\n    end\n\n    def rbuf_consume(len)\n      s = @rbuf.slice!(0, len)\n      @debug_output << %Q[-> #{s.dump}\\n] if @debug_output\n      s\n    end\n\n    #\n    # Write\n    #\n\n    public\n\n    def write(str)\n      writing {\n        write0 str\n      }\n    end\n\n    def writeline(str)\n      writing {\n        write0 str + \"\\r\\n\"\n      }\n    end\n\n    private\n\n    def writing\n      @written_bytes = 0\n      @debug_output << '<- ' if @debug_output\n      yield\n      @debug_output << \"\\n\" if @debug_output\n      bytes = @written_bytes\n      @written_bytes = nil\n      bytes\n    end\n\n    def write0(str)\n      @debug_output << str.dump if @debug_output\n      len = @io.write(str)\n      @written_bytes += len\n      len\n    end\n\n    #\n    # Logging\n    #\n\n    private\n\n    def LOG_off\n      @save_debug_out = @debug_output\n      @debug_output = nil\n    end\n\n    def LOG_on\n      @debug_output = @save_debug_out\n    end\n\n    def LOG(msg)\n      return unless @debug_output\n      @debug_output << msg + \"\\n\"\n    end\n  end\n\n\n  class InternetMessageIO < BufferedIO   #:nodoc: internal use only\n    def InternetMessageIO.old_open(addr, port,\n        open_timeout = nil, read_timeout = nil, debug_output = nil)\n      debug_output << \"opening connection to #{addr}...\\n\" if debug_output\n      s = timeout(open_timeout) { TCPsocket.new(addr, port) }\n      io = new(s)\n      io.read_timeout = read_timeout\n      io.debug_output = debug_output\n      io\n    end\n\n    def initialize(io)\n      super\n      @wbuf = nil\n    end\n\n    #\n    # Read\n    #\n\n    def each_message_chunk\n      LOG 'reading message...'\n      LOG_off()\n      read_bytes = 0\n      while (line = readuntil(\"\\r\\n\")) != \".\\r\\n\"\n        read_bytes += line.size\n        yield line.sub(/\\A\\./, '')\n      end\n      LOG_on()\n      LOG \"read message (#{read_bytes} bytes)\"\n    end\n  \n    # *library private* (cannot handle 'break')\n    def each_list_item\n      while (str = readuntil(\"\\r\\n\")) != \".\\r\\n\"\n        yield str.chop\n      end\n    end\n\n    def write_message_0(src)\n      prev = @written_bytes\n      each_crlf_line(src) do |line|\n        write0 line.sub(/\\A\\./, '..')\n      end\n      @written_bytes - prev\n    end\n\n    #\n    # Write\n    #\n\n    def write_message(src)\n      LOG \"writing message from #{src.class}\"\n      LOG_off()\n      len = writing {\n        using_each_crlf_line {\n          write_message_0 src\n        }\n      }\n      LOG_on()\n      LOG \"wrote #{len} bytes\"\n      len\n    end\n\n    def write_message_by_block(&block)\n      LOG 'writing message from block'\n      LOG_off()\n      len = writing {\n        using_each_crlf_line {\n          begin\n            block.call(WriteAdapter.new(self, :write_message_0))\n          rescue LocalJumpError\n            # allow `break' from writer block\n          end\n        }\n      }\n      LOG_on()\n      LOG \"wrote #{len} bytes\"\n      len\n    end\n\n    private\n\n    def using_each_crlf_line\n      @wbuf = ''\n      yield\n      if not @wbuf.empty?   # unterminated last line\n        write0 @wbuf.chomp + \"\\r\\n\"\n      elsif @written_bytes == 0   # empty src\n        write0 \"\\r\\n\"\n      end\n      write0 \".\\r\\n\"\n      @wbuf = nil\n    end\n\n    def each_crlf_line(src)\n      buffer_filling(@wbuf, src) do\n        while line = @wbuf.slice!(/\\A.*(?:\\n|\\r\\n|\\r(?!\\z))/n)\n          yield line.chomp(\"\\n\") + \"\\r\\n\"\n        end\n      end\n    end\n\n    def buffer_filling(buf, src)\n      case src\n      when String    # for speeding up.\n        0.step(src.size - 1, 1024) do |i|\n          buf << src[i, 1024]\n          yield\n        end\n      when File    # for speeding up.\n        while s = src.read(1024)\n          buf << s\n          yield\n        end\n      else    # generic reader\n        src.each do |s|\n          buf << s\n          yield if buf.size > 1024\n        end\n        yield unless buf.empty?\n      end\n    end\n  end\n\n\n  #\n  # The writer adapter class\n  #\n  class WriteAdapter\n    def initialize(socket, method)\n      @socket = socket\n      @method_id = method\n    end\n\n    def inspect\n      \"#<#{self.class} socket=#{@socket.inspect}>\"\n    end\n\n    def write(str)\n      @socket.__send__(@method_id, str)\n    end\n\n    alias print write\n\n    def <<(str)\n      write str\n      self\n    end\n\n    def puts(str = '')\n      write str.chomp(\"\\n\") + \"\\n\"\n    end\n\n    def printf(*args)\n      write sprintf(*args)\n    end\n  end\n\n\n  class ReadAdapter   #:nodoc: internal use only\n    def initialize(block)\n      @block = block\n    end\n\n    def inspect\n      \"#<#{self.class}>\"\n    end\n\n    def <<(str)\n      call_block(str, &@block) if @block\n    end\n\n    private\n\n    # This method is needed because @block must be called by yield,\n    # not Proc#call.  You can see difference when using `break' in\n    # the block.\n    def call_block(str)\n      yield str\n    end\n  end\n\n\n  module NetPrivate   #:nodoc: obsolete\n    Socket = ::Net::InternetMessageIO\n  end\n\nend   # module Net\n"
  },
  {
    "path": "lib/net/smtp.rb",
    "content": "# = net/smtp.rb\n# \n# Copyright (c) 1999-2007 Yukihiro Matsumoto.\n#\n# Copyright (c) 1999-2007 Minero Aoki.\n# \n# Written & maintained by Minero Aoki <aamine@loveruby.net>.\n#\n# Documented by William Webber and Minero Aoki.\n# \n# This program is free software. You can re-distribute and/or\n# modify this program under the same terms as Ruby itself.\n# \n# NOTE: You can find Japanese version of this document at:\n# http://www.ruby-lang.org/ja/man/html/net_smtp.html\n# \n# $Id$\n#\n# See Net::SMTP for documentation. \n# \n\nrequire 'net/protocol'\nrequire 'digest/md5'\nrequire 'timeout'\nbegin\n  require 'openssl'\nrescue LoadError\nend\n\nmodule Net\n\n  # Module mixed in to all SMTP error classes\n  module SMTPError\n    # This *class* is a module for backward compatibility.\n    # In later release, this module becomes a class.\n  end\n\n  # Represents an SMTP authentication error.\n  class SMTPAuthenticationError < ProtoAuthError\n    include SMTPError\n  end\n\n  # Represents SMTP error code 420 or 450, a temporary error.\n  class SMTPServerBusy < ProtoServerError\n    include SMTPError\n  end\n\n  # Represents an SMTP command syntax error (error code 500)\n  class SMTPSyntaxError < ProtoSyntaxError\n    include SMTPError\n  end\n\n  # Represents a fatal SMTP error (error code 5xx, except for 500)\n  class SMTPFatalError < ProtoFatalError\n    include SMTPError\n  end\n\n  # Unexpected reply code returned from server.\n  class SMTPUnknownError < ProtoUnknownError\n    include SMTPError\n  end\n\n  # Command is not supported on server.\n  class SMTPUnsupportedCommand < ProtocolError\n    include SMTPError\n  end\n\n  #\n  # = Net::SMTP\n  #\n  # == What is This Library?\n  # \n  # This library provides functionality to send internet\n  # mail via SMTP, the Simple Mail Transfer Protocol. For details of\n  # SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).\n  # \n  # == What is This Library NOT?\n  # \n  # This library does NOT provide functions to compose internet mails.\n  # You must create them by yourself. If you want better mail support,\n  # try RubyMail or TMail. You can get both libraries from RAA.\n  # (http://www.ruby-lang.org/en/raa.html)\n  # \n  # FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt).\n  # \n  # == Examples\n  # \n  # === Sending Messages\n  # \n  # You must open a connection to an SMTP server before sending messages.\n  # The first argument is the address of your SMTP server, and the second \n  # argument is the port number. Using SMTP.start with a block is the simplest \n  # way to do this. This way, the SMTP connection is closed automatically \n  # after the block is executed.\n  # \n  #     require 'net/smtp'\n  #     Net::SMTP.start('your.smtp.server', 25) do |smtp|\n  #       # Use the SMTP object smtp only in this block.\n  #     end\n  # \n  # Replace 'your.smtp.server' with your SMTP server. Normally\n  # your system manager or internet provider supplies a server\n  # for you.\n  # \n  # Then you can send messages.\n  # \n  #     msgstr = <<END_OF_MESSAGE\n  #     From: Your Name <your@mail.address>\n  #     To: Destination Address <someone@example.com>\n  #     Subject: test message\n  #     Date: Sat, 23 Jun 2001 16:26:43 +0900\n  #     Message-Id: <unique.message.id.string@example.com>\n  # \n  #     This is a test message.\n  #     END_OF_MESSAGE\n  # \n  #     require 'net/smtp'\n  #     Net::SMTP.start('your.smtp.server', 25) do |smtp|\n  #       smtp.send_message msgstr,\n  #                         'your@mail.address',\n  #                         'his_addess@example.com'\n  #     end\n  # \n  # === Closing the Session\n  # \n  # You MUST close the SMTP session after sending messages, by calling \n  # the #finish method:\n  # \n  #     # using SMTP#finish\n  #     smtp = Net::SMTP.start('your.smtp.server', 25)\n  #     smtp.send_message msgstr, 'from@address', 'to@address'\n  #     smtp.finish\n  # \n  # You can also use the block form of SMTP.start/SMTP#start.  This closes\n  # the SMTP session automatically:\n  # \n  #     # using block form of SMTP.start\n  #     Net::SMTP.start('your.smtp.server', 25) do |smtp|\n  #       smtp.send_message msgstr, 'from@address', 'to@address'\n  #     end\n  # \n  # I strongly recommend this scheme.  This form is simpler and more robust.\n  # \n  # === HELO domain\n  # \n  # In almost all situations, you must provide a third argument\n  # to SMTP.start/SMTP#start. This is the domain name which you are on\n  # (the host to send mail from). It is called the \"HELO domain\".\n  # The SMTP server will judge whether it should send or reject\n  # the SMTP session by inspecting the HELO domain.\n  # \n  #     Net::SMTP.start('your.smtp.server', 25,\n  #                     'mail.from.domain') { |smtp| ... }\n  # \n  # === SMTP Authentication\n  # \n  # The Net::SMTP class supports three authentication schemes;\n  # PLAIN, LOGIN and CRAM MD5.  (SMTP Authentication: [RFC2554])\n  # To use SMTP authentication, pass extra arguments to \n  # SMTP.start/SMTP#start.\n  # \n  #     # PLAIN\n  #     Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',\n  #                     'Your Account', 'Your Password', :plain)\n  #     # LOGIN\n  #     Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',\n  #                     'Your Account', 'Your Password', :login)\n  # \n  #     # CRAM MD5\n  #     Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',\n  #                     'Your Account', 'Your Password', :cram_md5)\n  #\n  class SMTP\n\n    Revision = %q$Revision$.split[1]\n\n    # The default SMTP port number, 25.\n    def SMTP.default_port\n      25\n    end\n\n    # The default mail submission port number, 587.\n    def SMTP.default_submission_port\n      587\n    end\n\n    # The default SMTPS port number, 465.\n    def SMTP.default_tls_port\n      465\n    end\n\n    class << self\n      alias default_ssl_port default_tls_port\n    end\n\n    def SMTP.default_ssl_context\n      OpenSSL::SSL::SSLContext.new\n    end\n    \n    #\n    # Creates a new Net::SMTP object.\n    #\n    # +address+ is the hostname or ip address of your SMTP\n    # server.  +port+ is the port to connect to; it defaults to\n    # port 25.\n    #\n    # This method does not open the TCP connection.  You can use\n    # SMTP.start instead of SMTP.new if you want to do everything\n    # at once.  Otherwise, follow SMTP.new with SMTP#start.\n    #\n    def initialize(address, port = nil)\n      @address = address\n      @port = (port || SMTP.default_port)\n      @esmtp = true\n      @capabilities = nil\n      @socket = nil\n      @started = false\n      @open_timeout = 30\n      @read_timeout = 60\n      @error_occured = false\n      @debug_output = nil\n      @tls = false\n      @starttls = false\n      @ssl_context = nil\n    end\n    \n    # Provide human-readable stringification of class state.\n    def inspect\n      \"#<#{self.class} #{@address}:#{@port} started=#{@started}>\"\n    end\n\n    # +true+ if the SMTP object uses ESMTP (which it does by default).\n    def esmtp?\n      @esmtp\n    end\n\n    #\n    # Set whether to use ESMTP or not.  This should be done before \n    # calling #start.  Note that if #start is called in ESMTP mode,\n    # and the connection fails due to a ProtocolError, the SMTP\n    # object will automatically switch to plain SMTP mode and\n    # retry (but not vice versa).\n    #\n    def esmtp=(bool)\n      @esmtp = bool\n    end\n\n    alias esmtp esmtp?\n\n    # true if server advertises STARTTLS.\n    # You cannot get valid value before opening SMTP session.\n    def capable_starttls?\n      capable?('STARTTLS')\n    end\n\n    def capable?(key)\n      return nil unless @capabilities\n      @capabilities[key] ? true : false\n    end\n    private :capable?\n\n    # true if server advertises AUTH PLAIN.\n    # You cannot get valid value before opening SMTP session.\n    def capable_plain_auth?\n      auth_capable?('PLAIN')\n    end\n\n    # true if server advertises AUTH LOGIN.\n    # You cannot get valid value before opening SMTP session.\n    def capable_login_auth?\n      auth_capable?('LOGIN')\n    end\n\n    # true if server advertises AUTH CRAM-MD5.\n    # You cannot get valid value before opening SMTP session.\n    def capable_cram_md5_auth?\n      auth_capable?('CRAM-MD5')\n    end\n\n    def auth_capable?(type)\n      return nil unless @capabilities\n      return false unless @capabilities['AUTH']\n      @capabilities['AUTH'].include?(type)\n    end\n    private :auth_capable?\n\n    # Returns supported authentication methods on this server.\n    # You cannot get valid value before opening SMTP session.\n    def capable_auth_types\n      return [] unless @capabilities\n      return [] unless @capabilities['AUTH']\n      @capabilities['AUTH']\n    end\n\n    # true if this object uses SMTP/TLS (SMTPS).\n    def tls?\n      @tls\n    end\n\n    alias ssl? tls?\n\n    # Enables SMTP/TLS (SMTPS: SMTP over direct TLS connection) for\n    # this object.  Must be called before the connection is established\n    # to have any effect.  +context+ is a OpenSSL::SSL::SSLContext object.\n    def enable_tls(context = SMTP.default_ssl_context)\n      raise 'openssl library not installed' unless defined?(OpenSSL)\n      raise ArgumentError, \"SMTPS and STARTTLS is exclusive\" if @starttls\n      @tls = true\n      @ssl_context = context\n    end\n\n    alias enable_ssl enable_tls\n    \n    # Disables SMTP/TLS for this object.  Must be called before the\n    # connection is established to have any effect.\n    def disable_tls\n      @tls = false\n      @ssl_context = nil\n    end\n\n    alias disable_ssl disable_tls\n\n    # Returns truth value if this object uses STARTTLS.\n    # If this object always uses STARTTLS, returns :always.\n    # If this object uses STARTTLS when the server support TLS, returns :auto.\n    def starttls?\n      @starttls\n    end\n\n    # true if this object uses STARTTLS.\n    def starttls_always?\n      @starttls == :always\n    end\n\n    # true if this object uses STARTTLS when server advertises STARTTLS.\n    def starttls_auto?\n      @starttls == :auto\n    end\n    \n    # Enables SMTP/TLS (STARTTLS) for this object.\n    # +context+ is a OpenSSL::SSL::SSLContext object.\n    def enable_starttls(context = SMTP.default_ssl_context)\n      raise 'openssl library not installed' unless defined?(OpenSSL)\n      raise ArgumentError, \"SMTPS and STARTTLS is exclusive\" if @tls\n      @starttls = :always\n      @ssl_context = context\n    end\n\n    # Enables SMTP/TLS (STARTTLS) for this object if server accepts.\n    # +context+ is a OpenSSL::SSL::SSLContext object.\n    def enable_starttls_auto(context = SMTP.default_ssl_context)\n      raise 'openssl library not installed' unless defined?(OpenSSL)\n      raise ArgumentError, \"SMTPS and STARTTLS is exclusive\" if @tls\n      @starttls = :auto\n      @ssl_context = context\n    end\n\n    # Disables SMTP/TLS (STARTTLS) for this object.  Must be called\n    # before the connection is established to have any effect.\n    def disable_starttls\n      @starttls = false\n      @ssl_context = nil\n    end\n\n    # The address of the SMTP server to connect to.\n    attr_reader :address\n\n    # The port number of the SMTP server to connect to.\n    attr_reader :port\n\n    # Seconds to wait while attempting to open a connection.\n    # If the connection cannot be opened within this time, a\n    # TimeoutError is raised.\n    attr_accessor :open_timeout\n\n    # Seconds to wait while reading one block (by one read(2) call).\n    # If the read(2) call does not complete within this time, a\n    # TimeoutError is raised.\n    attr_reader :read_timeout\n\n    # Set the number of seconds to wait until timing-out a read(2)\n    # call.\n    def read_timeout=(sec)\n      @socket.read_timeout = sec if @socket\n      @read_timeout = sec\n    end\n\n    #\n    # WARNING: This method causes serious security holes.\n    # Use this method for only debugging.\n    #\n    # Set an output stream for debug logging.\n    # You must call this before #start.\n    #\n    #   # example\n    #   smtp = Net::SMTP.new(addr, port)\n    #   smtp.set_debug_output $stderr\n    #   smtp.start do |smtp|\n    #     ....\n    #   end\n    #\n    def debug_output=(arg)\n      @debug_output = arg\n    end\n\n    alias set_debug_output debug_output=\n\n    #\n    # SMTP session control\n    #\n\n    #\n    # Creates a new Net::SMTP object and connects to the server.\n    #\n    # This method is equivalent to:\n    # \n    #   Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)\n    #\n    # === Example\n    #\n    #     Net::SMTP.start('your.smtp.server') do |smtp|\n    #       smtp.send_message msgstr, 'from@example.com', ['dest@example.com']\n    #     end\n    #\n    # === Block Usage\n    #\n    # If called with a block, the newly-opened Net::SMTP object is yielded\n    # to the block, and automatically closed when the block finishes.  If called\n    # without a block, the newly-opened Net::SMTP object is returned to\n    # the caller, and it is the caller's responsibility to close it when\n    # finished.\n    #\n    # === Parameters\n    #\n    # +address+ is the hostname or ip address of your smtp server.\n    #\n    # +port+ is the port to connect to; it defaults to port 25.\n    #\n    # +helo+ is the _HELO_ _domain_ provided by the client to the\n    # server (see overview comments); it defaults to 'localhost.localdomain'. \n    #\n    # The remaining arguments are used for SMTP authentication, if required\n    # or desired.  +user+ is the account name; +secret+ is your password\n    # or other authentication token; and +authtype+ is the authentication\n    # type, one of :plain, :login, or :cram_md5.  See the discussion of\n    # SMTP Authentication in the overview notes.\n    #\n    # === Errors\n    #\n    # This method may raise:\n    #\n    # * Net::SMTPAuthenticationError\n    # * Net::SMTPServerBusy\n    # * Net::SMTPSyntaxError\n    # * Net::SMTPFatalError\n    # * Net::SMTPUnknownError\n    # * IOError\n    # * TimeoutError\n    #\n    def SMTP.start(address, port = nil, helo = 'localhost.localdomain',\n                   user = nil, secret = nil, authtype = nil,\n                   &block)   # :yield: smtp\n      new(address, port).start(helo, user, secret, authtype, &block)\n    end\n\n    # +true+ if the SMTP session has been started.\n    def started?\n      @started\n    end\n\n    #\n    # Opens a TCP connection and starts the SMTP session.\n    #\n    # === Parameters\n    #\n    # +helo+ is the _HELO_ _domain_ that you'll dispatch mails from; see\n    # the discussion in the overview notes.\n    #\n    # If both of +user+ and +secret+ are given, SMTP authentication \n    # will be attempted using the AUTH command.  +authtype+ specifies \n    # the type of authentication to attempt; it must be one of\n    # :login, :plain, and :cram_md5.  See the notes on SMTP Authentication\n    # in the overview. \n    #\n    # === Block Usage\n    #\n    # When this methods is called with a block, the newly-started SMTP\n    # object is yielded to the block, and automatically closed after\n    # the block call finishes.  Otherwise, it is the caller's \n    # responsibility to close the session when finished.\n    #\n    # === Example\n    #\n    # This is very similar to the class method SMTP.start.\n    #\n    #     require 'net/smtp' \n    #     smtp = Net::SMTP.new('smtp.mail.server', 25)\n    #     smtp.start(helo_domain, account, password, authtype) do |smtp|\n    #       smtp.send_message msgstr, 'from@example.com', ['dest@example.com']\n    #     end \n    #\n    # The primary use of this method (as opposed to SMTP.start)\n    # is probably to set debugging (#set_debug_output) or ESMTP\n    # (#esmtp=), which must be done before the session is\n    # started.  \n    #\n    # === Errors\n    #\n    # If session has already been started, an IOError will be raised.\n    #\n    # This method may raise:\n    #\n    # * Net::SMTPAuthenticationError\n    # * Net::SMTPServerBusy\n    # * Net::SMTPSyntaxError\n    # * Net::SMTPFatalError\n    # * Net::SMTPUnknownError\n    # * IOError\n    # * TimeoutError\n    #\n    def start(helo = 'localhost.localdomain',\n              user = nil, secret = nil, authtype = nil)   # :yield: smtp\n      if block_given?\n        begin\n          do_start helo, user, secret, authtype\n          return yield(self)\n        ensure\n          do_finish\n        end\n      else\n        do_start helo, user, secret, authtype\n        return self\n      end\n    end\n\n    # Finishes the SMTP session and closes TCP connection.\n    # Raises IOError if not started.\n    def finish\n      raise IOError, 'not yet started' unless started?\n      do_finish\n    end\n\n    private\n\n    def do_start(helo_domain, user, secret, authtype)\n      raise IOError, 'SMTP session already started' if @started\n      if user or secret\n        check_auth_method(authtype || DEFAULT_AUTH_TYPE)\n        check_auth_args user, secret\n      end\n      s = timeout(@open_timeout) { TCPSocket.open(@address, @port) }   \n      logging \"Connection opened: #{@address}:#{@port}\"\n      @socket = new_internet_message_io(tls? ? tlsconnect(s) : s)\n      check_response critical { recv_response() }\n      do_helo helo_domain\n      if starttls_always? or (capable_starttls? and starttls_auto?)\n        unless capable_starttls?\n          raise SMTPUnsupportedCommand,\n              \"STARTTLS is not supported on this server\"\n        end\n        starttls\n        @socket = new_internet_message_io(tlsconnect(s))\n        # helo response may be different after STARTTLS\n        do_helo helo_domain\n      end\n      authenticate user, secret, (authtype || DEFAULT_AUTH_TYPE) if user\n      @started = true\n    ensure\n      unless @started\n        # authentication failed, cancel connection.\n        s.close if s and not s.closed?\n        @socket = nil\n      end\n    end\n\n    def tlsconnect(s)\n      s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)\n      logging \"TLS connection started\"\n      s.sync_close = true\n      s.connect\n      if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE\n        s.post_connection_check(@address)\n      end\n      s\n    end\n\n    def new_internet_message_io(s)\n      io = InternetMessageIO.new(s)\n      io.read_timeout = @read_timeout\n      io.debug_output = @debug_output\n      io\n    end\n\n    def do_helo(helo_domain)\n      res = @esmtp ? ehlo(helo_domain) : helo(helo_domain)\n      @capabilities = res.capabilities\n    rescue SMTPError\n      if @esmtp\n        @esmtp = false\n        @error_occured = false\n        retry\n      end\n      raise\n    end\n\n    def do_finish\n      quit if @socket and not @socket.closed? and not @error_occured\n    ensure\n      @started = false\n      @error_occured = false\n      @socket.close if @socket and not @socket.closed?\n      @socket = nil\n    end\n\n    #\n    # Message Sending\n    #\n\n    public\n\n    #\n    # Sends +msgstr+ as a message.  Single CR (\"\\r\") and LF (\"\\n\") found\n    # in the +msgstr+, are converted into the CR LF pair.  You cannot send a\n    # binary message with this method. +msgstr+ should include both \n    # the message headers and body.\n    #\n    # +from_addr+ is a String representing the source mail address.\n    #\n    # +to_addr+ is a String or Strings or Array of Strings, representing\n    # the destination mail address or addresses.\n    #\n    # === Example\n    #\n    #     Net::SMTP.start('smtp.example.com') do |smtp|\n    #       smtp.send_message msgstr,\n    #                         'from@example.com',\n    #                         ['dest@example.com', 'dest2@example.com']\n    #     end\n    #\n    # === Errors\n    #\n    # This method may raise:\n    #\n    # * Net::SMTPServerBusy\n    # * Net::SMTPSyntaxError\n    # * Net::SMTPFatalError\n    # * Net::SMTPUnknownError\n    # * IOError\n    # * TimeoutError\n    #\n    def send_message(msgstr, from_addr, *to_addrs)\n      raise IOError, 'closed session' unless @socket\n      mailfrom from_addr\n      rcptto_list to_addrs\n      data msgstr\n    end\n\n    alias send_mail send_message\n    alias sendmail send_message   # obsolete\n\n    #\n    # Opens a message writer stream and gives it to the block.\n    # The stream is valid only in the block, and has these methods:\n    #\n    # puts(str = '')::       outputs STR and CR LF.\n    # print(str)::           outputs STR.\n    # printf(fmt, *args)::   outputs sprintf(fmt,*args).\n    # write(str)::           outputs STR and returns the length of written bytes.\n    # <<(str)::              outputs STR and returns self.\n    #\n    # If a single CR (\"\\r\") or LF (\"\\n\") is found in the message,\n    # it is converted to the CR LF pair.  You cannot send a binary\n    # message with this method.\n    #\n    # === Parameters\n    #\n    # +from_addr+ is a String representing the source mail address.\n    #\n    # +to_addr+ is a String or Strings or Array of Strings, representing\n    # the destination mail address or addresses.\n    #\n    # === Example\n    #\n    #     Net::SMTP.start('smtp.example.com', 25) do |smtp|\n    #       smtp.open_message_stream('from@example.com', ['dest@example.com']) do |f|\n    #         f.puts 'From: from@example.com'\n    #         f.puts 'To: dest@example.com'\n    #         f.puts 'Subject: test message'\n    #         f.puts\n    #         f.puts 'This is a test message.'\n    #       end\n    #     end\n    #\n    # === Errors\n    #\n    # This method may raise:\n    #\n    # * Net::SMTPServerBusy\n    # * Net::SMTPSyntaxError\n    # * Net::SMTPFatalError\n    # * Net::SMTPUnknownError\n    # * IOError\n    # * TimeoutError\n    #\n    def open_message_stream(from_addr, *to_addrs, &block)   # :yield: stream\n      raise IOError, 'closed session' unless @socket\n      mailfrom from_addr\n      rcptto_list to_addrs\n      data(&block)\n    end\n\n    alias ready open_message_stream   # obsolete\n\n    #\n    # Authentication\n    #\n\n    public\n\n    DEFAULT_AUTH_TYPE = :plain\n\n    def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)\n      check_auth_method authtype\n      check_auth_args user, secret\n      send auth_method(authtype), user, secret\n    end\n\n    def auth_plain(user, secret)\n      check_auth_args user, secret\n      res = critical {\n        get_response('AUTH PLAIN ' + base64_encode(\"\\0#{user}\\0#{secret}\"))\n      }\n      check_auth_response res\n      res\n    end\n\n    def auth_login(user, secret)\n      check_auth_args user, secret\n      res = critical {\n        check_auth_continue get_response('AUTH LOGIN')\n        check_auth_continue get_response(base64_encode(user))\n        get_response(base64_encode(secret))\n      }\n      check_auth_response res\n      res\n    end\n\n    def auth_cram_md5(user, secret)\n      check_auth_args user, secret\n      res = critical {\n        res0 = get_response('AUTH CRAM-MD5')\n        check_auth_continue res0\n        crammed = cram_md5_response(secret, res0.cram_md5_challenge)\n        get_response(base64_encode(\"#{user} #{crammed}\"))\n      }\n      check_auth_response res\n      res\n    end\n\n    private\n\n    def check_auth_method(type)\n      unless respond_to?(auth_method(type), true)\n        raise ArgumentError, \"wrong authentication type #{type}\"\n      end\n    end\n\n    def auth_method(type)\n      \"auth_#{type.to_s.downcase}\".intern\n    end\n\n    def check_auth_args(user, secret)\n      unless user\n        raise ArgumentError, 'SMTP-AUTH requested but missing user name'\n      end\n      unless secret\n        raise ArgumentError, 'SMTP-AUTH requested but missing secret phrase'\n      end\n    end\n\n    def base64_encode(str)\n      # expects \"str\" may not become too long\n      [str].pack('m').gsub(/\\s+/, '')\n    end\n\n    IMASK = 0x36\n    OMASK = 0x5c\n\n    # CRAM-MD5: [RFC2195]\n    def cram_md5_response(secret, challenge)\n      tmp = Digest::MD5.digest(cram_secret(secret, IMASK) + challenge)\n      Digest::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)\n    end\n\n    CRAM_BUFSIZE = 64\n\n    def cram_secret(secret, mask)\n      secret = Digest::MD5.digest(secret) if secret.size > CRAM_BUFSIZE\n      buf = secret.ljust(CRAM_BUFSIZE, \"\\0\")\n      0.upto(buf.size - 1) do |i|\n        buf[i] = (buf[i].ord ^ mask).chr\n      end\n      buf\n    end\n\n    #\n    # SMTP command dispatcher\n    #\n\n    public\n\n    def starttls\n      getok('STARTTLS')\n    end\n\n    def helo(domain)\n      getok(\"HELO #{domain}\")\n    end\n\n    def ehlo(domain)\n      getok(\"EHLO #{domain}\")\n    end\n\n    def mailfrom(from_addr)\n      if $SAFE > 0\n        raise SecurityError, 'tainted from_addr' if from_addr.tainted?\n      end\n      getok(\"MAIL FROM:<#{from_addr}>\")\n    end\n\n    def rcptto_list(to_addrs)\n      raise ArgumentError, 'mail destination not given' if to_addrs.empty?\n      to_addrs.flatten.each do |addr|\n        rcptto addr\n      end\n    end\n\n    def rcptto(to_addr)\n      if $SAFE > 0\n        raise SecurityError, 'tainted to_addr' if to_addr.tainted?\n      end\n      getok(\"RCPT TO:<#{to_addr}>\")\n    end\n\n    # This method sends a message.\n    # If +msgstr+ is given, sends it as a message.\n    # If block is given, yield a message writer stream.\n    # You must write message before the block is closed.\n    #\n    #   # Example 1 (by string)\n    #   smtp.data(<<EndMessage)\n    #   From: john@example.com\n    #   To: betty@example.com\n    #   Subject: I found a bug\n    #   \n    #   Check vm.c:58879.\n    #   EndMessage\n    #\n    #   # Example 2 (by block)\n    #   smtp.data {|f|\n    #     f.puts \"From: john@example.com\"\n    #     f.puts \"To: betty@example.com\"\n    #     f.puts \"Subject: I found a bug\"\n    #     f.puts \"\"\n    #     f.puts \"Check vm.c:58879.\"\n    #   }\n    #\n    def data(msgstr = nil, &block)   #:yield: stream\n      if msgstr and block\n        raise ArgumentError, \"message and block are exclusive\"\n      end\n      unless msgstr or block\n        raise ArgumentError, \"message or block is required\"\n      end\n      res = critical {\n        check_continue get_response('DATA')\n        if msgstr\n          @socket.write_message msgstr\n        else\n          @socket.write_message_by_block(&block)\n        end\n        recv_response()\n      }\n      check_response res\n      res\n    end\n\n    def quit\n      getok('QUIT')\n    end\n\n    private\n\n    def getok(reqline)\n      res = critical {\n        @socket.writeline reqline\n        recv_response()\n      }\n      check_response res\n      res\n    end\n\n    def get_response(reqline)\n      @socket.writeline reqline\n      recv_response()\n    end\n\n    def recv_response\n      buf = ''\n      while true\n        line = @socket.readline\n        buf << line << \"\\n\"\n        break unless line[3,1] == '-'   # \"210-PIPELINING\"\n      end\n      Response.parse(buf)\n    end\n\n    def critical(&block)\n      return '200 dummy reply code' if @error_occured\n      begin\n        return yield()\n      rescue Exception\n        @error_occured = true\n        raise\n      end\n    end\n\n    def check_response(res)\n      unless res.success?\n        raise res.exception_class, res.message\n      end\n    end\n\n    def check_continue(res)\n      unless res.continue?\n        raise SMTPUnknownError, \"could not get 3xx (#{res.status})\"\n      end\n    end\n\n    def check_auth_response(res)\n      unless res.success?\n        raise SMTPAuthenticationError, res.message\n      end\n    end\n\n    def check_auth_continue(res)\n      unless res.continue?\n        raise res.exception_class, res.message\n      end\n    end\n\n    class Response\n      def Response.parse(str)\n        new(str[0,3], str)\n      end\n\n      def initialize(status, string)\n        @status = status\n        @string = string\n      end\n\n      attr_reader :status\n      attr_reader :string\n\n      def status_type_char\n        @status[0, 1]\n      end\n\n      def success?\n        status_type_char() == '2'\n      end\n\n      def continue?\n        status_type_char() == '3'\n      end\n\n      def message\n        @string.lines.first\n      end\n\n      def cram_md5_challenge\n        @string.split(/ /)[1].unpack('m')[0]\n      end\n\n      def capabilities\n        return {} unless @string[3, 1] == '-'\n        h = {}\n        @string.lines.drop(1).each do |line|\n          k, *v = line[4..-1].chomp.split(nil)\n          h[k] = v\n        end\n        h\n      end\n\n      def exception_class\n        case @status\n        when /\\A4/  then SMTPServerBusy\n        when /\\A50/ then SMTPSyntaxError\n        when /\\A53/ then SMTPAuthenticationError\n        when /\\A5/  then SMTPFatalError\n        else             SMTPUnknownError\n        end\n      end\n    end\n\n    def logging(msg)\n      @debug_output << msg + \"\\n\" if @debug_output\n    end\n\n  end   # class SMTP\n\n  SMTPSession = SMTP\n\nend\n"
  },
  {
    "path": "lib/net/telnet.rb",
    "content": "# = net/telnet.rb - Simple Telnet Client Library\n# \n# Author:: Wakou Aoyama <wakou@ruby-lang.org>\n# Documentation:: William Webber and Wakou Aoyama \n#\n# This file holds the class Net::Telnet, which provides client-side\n# telnet functionality.\n#\n# For documentation, see Net::Telnet.\n#\n\nrequire \"socket\"\nrequire \"delegate\"\nrequire \"timeout\"\nrequire \"English\"\n \nmodule Net\n\n  #\n  # == Net::Telnet\n  #\n  # Provides telnet client functionality.\n  #\n  # This class also has, through delegation, all the methods of a\n  # socket object (by default, a +TCPSocket+, but can be set by the\n  # +Proxy+ option to <tt>new()</tt>).  This provides methods such as\n  # <tt>close()</tt> to end the session and <tt>sysread()</tt> to read\n  # data directly from the host, instead of via the <tt>waitfor()</tt>\n  # mechanism.  Note that if you do use <tt>sysread()</tt> directly\n  # when in telnet mode, you should probably pass the output through\n  # <tt>preprocess()</tt> to extract telnet command sequences.\n  #\n  # == Overview\n  #\n  # The telnet protocol allows a client to login remotely to a user\n  # account on a server and execute commands via a shell.  The equivalent\n  # is done by creating a Net::Telnet class with the +Host+ option\n  # set to your host, calling #login() with your user and password,\n  # issuing one or more #cmd() calls, and then calling #close()\n  # to end the session.  The #waitfor(), #print(), #puts(), and\n  # #write() methods, which #cmd() is implemented on top of, are\n  # only needed if you are doing something more complicated.\n  #\n  # A Net::Telnet object can also be used to connect to non-telnet\n  # services, such as SMTP or HTTP.  In this case, you normally\n  # want to provide the +Port+ option to specify the port to\n  # connect to, and set the +Telnetmode+ option to false to prevent\n  # the client from attempting to interpret telnet command sequences.\n  # Generally, #login() will not work with other protocols, and you\n  # have to handle authentication yourself.\n  #\n  # For some protocols, it will be possible to specify the +Prompt+\n  # option once when you create the Telnet object and use #cmd() calls; \n  # for others, you will have to specify the response sequence to\n  # look for as the Match option to every #cmd() call, or call\n  # #puts() and #waitfor() directly; for yet others, you will have \n  # to use #sysread() instead of #waitfor() and parse server \n  # responses yourself.\n  #\n  # It is worth noting that when you create a new Net::Telnet object,\n  # you can supply a proxy IO channel via the Proxy option.  This\n  # can be used to attach the Telnet object to other Telnet objects,\n  # to already open sockets, or to any read-write IO object.  This\n  # can be useful, for instance, for setting up a test fixture for\n  # unit testing.\n  # \n  # == Examples\n  # \n  # === Log in and send a command, echoing all output to stdout\n  # \n  #   localhost = Net::Telnet::new(\"Host\" => \"localhost\",\n  #                                \"Timeout\" => 10,\n  #                                \"Prompt\" => /[$%#>] \\z/n)\n  #   localhost.login(\"username\", \"password\") { |c| print c }\n  #   localhost.cmd(\"command\") { |c| print c }\n  #   localhost.close\n  # \n  # \n  # === Check a POP server to see if you have mail\n  # \n  #   pop = Net::Telnet::new(\"Host\" => \"your_destination_host_here\",\n  #                          \"Port\" => 110,\n  #                          \"Telnetmode\" => false,\n  #                          \"Prompt\" => /^\\+OK/n)\n  #   pop.cmd(\"user \" + \"your_username_here\") { |c| print c }\n  #   pop.cmd(\"pass \" + \"your_password_here\") { |c| print c }\n  #   pop.cmd(\"list\") { |c| print c }\n  #\n  # == References\n  #\n  # There are a large number of RFCs relevant to the Telnet protocol.\n  # RFCs 854-861 define the base protocol.  For a complete listing\n  # of relevant RFCs, see\n  # http://www.omnifarious.org/~hopper/technical/telnet-rfc.html\n  #\n  class Telnet < SimpleDelegator\n\n    # :stopdoc:\n    IAC   = 255.chr # \"\\377\" # \"\\xff\" # interpret as command\n    DONT  = 254.chr # \"\\376\" # \"\\xfe\" # you are not to use option \n    DO    = 253.chr # \"\\375\" # \"\\xfd\" # please, you use option \n    WONT  = 252.chr # \"\\374\" # \"\\xfc\" # I won't use option \n    WILL  = 251.chr # \"\\373\" # \"\\xfb\" # I will use option \n    SB    = 250.chr # \"\\372\" # \"\\xfa\" # interpret as subnegotiation \n    GA    = 249.chr # \"\\371\" # \"\\xf9\" # you may reverse the line \n    EL    = 248.chr # \"\\370\" # \"\\xf8\" # erase the current line \n    EC    = 247.chr # \"\\367\" # \"\\xf7\" # erase the current character \n    AYT   = 246.chr # \"\\366\" # \"\\xf6\" # are you there \n    AO    = 245.chr # \"\\365\" # \"\\xf5\" # abort output--but let prog finish \n    IP    = 244.chr # \"\\364\" # \"\\xf4\" # interrupt process--permanently \n    BREAK = 243.chr # \"\\363\" # \"\\xf3\" # break \n    DM    = 242.chr # \"\\362\" # \"\\xf2\" # data mark--for connect. cleaning \n    NOP   = 241.chr # \"\\361\" # \"\\xf1\" # nop \n    SE    = 240.chr # \"\\360\" # \"\\xf0\" # end sub negotiation \n    EOR   = 239.chr # \"\\357\" # \"\\xef\" # end of record (transparent mode) \n    ABORT = 238.chr # \"\\356\" # \"\\xee\" # Abort process \n    SUSP  = 237.chr # \"\\355\" # \"\\xed\" # Suspend process \n    EOF   = 236.chr # \"\\354\" # \"\\xec\" # End of file \n    SYNCH = 242.chr # \"\\362\" # \"\\xf2\" # for telfunc calls \n\n    OPT_BINARY         =   0.chr # \"\\000\" # \"\\x00\" # Binary Transmission \n    OPT_ECHO           =   1.chr # \"\\001\" # \"\\x01\" # Echo \n    OPT_RCP            =   2.chr # \"\\002\" # \"\\x02\" # Reconnection \n    OPT_SGA            =   3.chr # \"\\003\" # \"\\x03\" # Suppress Go Ahead \n    OPT_NAMS           =   4.chr # \"\\004\" # \"\\x04\" # Approx Message Size Negotiation \n    OPT_STATUS         =   5.chr # \"\\005\" # \"\\x05\" # Status \n    OPT_TM             =   6.chr # \"\\006\" # \"\\x06\" # Timing Mark \n    OPT_RCTE           =   7.chr # \"\\a\"   # \"\\x07\" # Remote Controlled Trans and Echo \n    OPT_NAOL           =   8.chr # \"\\010\" # \"\\x08\" # Output Line Width \n    OPT_NAOP           =   9.chr # \"\\t\"   # \"\\x09\" # Output Page Size \n    OPT_NAOCRD         =  10.chr # \"\\n\"   # \"\\x0a\" # Output Carriage-Return Disposition \n    OPT_NAOHTS         =  11.chr # \"\\v\"   # \"\\x0b\" # Output Horizontal Tab Stops \n    OPT_NAOHTD         =  12.chr # \"\\f\"   # \"\\x0c\" # Output Horizontal Tab Disposition \n    OPT_NAOFFD         =  13.chr # \"\\r\"   # \"\\x0d\" # Output Formfeed Disposition \n    OPT_NAOVTS         =  14.chr # \"\\016\" # \"\\x0e\" # Output Vertical Tabstops \n    OPT_NAOVTD         =  15.chr # \"\\017\" # \"\\x0f\" # Output Vertical Tab Disposition \n    OPT_NAOLFD         =  16.chr # \"\\020\" # \"\\x10\" # Output Linefeed Disposition \n    OPT_XASCII         =  17.chr # \"\\021\" # \"\\x11\" # Extended ASCII \n    OPT_LOGOUT         =  18.chr # \"\\022\" # \"\\x12\" # Logout \n    OPT_BM             =  19.chr # \"\\023\" # \"\\x13\" # Byte Macro \n    OPT_DET            =  20.chr # \"\\024\" # \"\\x14\" # Data Entry Terminal \n    OPT_SUPDUP         =  21.chr # \"\\025\" # \"\\x15\" # SUPDUP \n    OPT_SUPDUPOUTPUT   =  22.chr # \"\\026\" # \"\\x16\" # SUPDUP Output \n    OPT_SNDLOC         =  23.chr # \"\\027\" # \"\\x17\" # Send Location \n    OPT_TTYPE          =  24.chr # \"\\030\" # \"\\x18\" # Terminal Type \n    OPT_EOR            =  25.chr # \"\\031\" # \"\\x19\" # End of Record \n    OPT_TUID           =  26.chr # \"\\032\" # \"\\x1a\" # TACACS User Identification \n    OPT_OUTMRK         =  27.chr # \"\\e\"   # \"\\x1b\" # Output Marking \n    OPT_TTYLOC         =  28.chr # \"\\034\" # \"\\x1c\" # Terminal Location Number \n    OPT_3270REGIME     =  29.chr # \"\\035\" # \"\\x1d\" # Telnet 3270 Regime \n    OPT_X3PAD          =  30.chr # \"\\036\" # \"\\x1e\" # X.3 PAD \n    OPT_NAWS           =  31.chr # \"\\037\" # \"\\x1f\" # Negotiate About Window Size \n    OPT_TSPEED         =  32.chr # \" \"    # \"\\x20\" # Terminal Speed \n    OPT_LFLOW          =  33.chr # \"!\"    # \"\\x21\" # Remote Flow Control \n    OPT_LINEMODE       =  34.chr # \"\\\"\"   # \"\\x22\" # Linemode \n    OPT_XDISPLOC       =  35.chr # \"#\"    # \"\\x23\" # X Display Location \n    OPT_OLD_ENVIRON    =  36.chr # \"$\"    # \"\\x24\" # Environment Option \n    OPT_AUTHENTICATION =  37.chr # \"%\"    # \"\\x25\" # Authentication Option \n    OPT_ENCRYPT        =  38.chr # \"&\"    # \"\\x26\" # Encryption Option \n    OPT_NEW_ENVIRON    =  39.chr # \"'\"    # \"\\x27\" # New Environment Option \n    OPT_EXOPL          = 255.chr # \"\\377\" # \"\\xff\" # Extended-Options-List \n\n    NULL = \"\\000\" \n    CR   = \"\\015\"   \n    LF   = \"\\012\" \n    EOL  = CR + LF \n    REVISION = '$Id$'\n    # :startdoc:\n\n    #\n    # Creates a new Net::Telnet object.\n    #\n    # Attempts to connect to the host (unless the Proxy option is\n    # provided: see below).  If a block is provided, it is yielded\n    # status messages on the attempt to connect to the server, of\n    # the form:\n    # \n    #   Trying localhost...\n    #   Connected to localhost.\n    #\n    # +options+ is a hash of options.  The following example lists\n    # all options and their default values.\n    # \n    #   host = Net::Telnet::new(\n    #            \"Host\"       => \"localhost\",  # default: \"localhost\"\n    #            \"Port\"       => 23,           # default: 23\n    #            \"Binmode\"    => false,        # default: false\n    #            \"Output_log\" => \"output_log\", # default: nil (no output)\n    #            \"Dump_log\"   => \"dump_log\",   # default: nil (no output)\n    #            \"Prompt\"     => /[$%#>] \\z/n, # default: /[$%#>] \\z/n\n    #            \"Telnetmode\" => true,         # default: true\n    #            \"Timeout\"    => 10,           # default: 10\n    #              # if ignore timeout then set \"Timeout\" to false.\n    #            \"Waittime\"   => 0,            # default: 0\n    #            \"Proxy\"      => proxy         # default: nil\n    #                            # proxy is Net::Telnet or IO object\n    #          )\n    #\n    # The options have the following meanings:\n    #\n    # Host:: the hostname or IP address of the host to connect to, as a String. \n    #        Defaults to \"localhost\".\n    #\n    # Port:: the port to connect to.  Defaults to 23.\n    #\n    # Binmode:: if false (the default), newline substitution is performed.  \n    #           Outgoing LF is\n    #           converted to CRLF, and incoming CRLF is converted to LF.  If\n    #           true, this substitution is not performed.  This value can\n    #           also be set with the #binmode() method.  The \n    #           outgoing conversion only applies to the #puts() and #print()\n    #           methods, not the #write() method.  The precise nature of\n    #           the newline conversion is also affected by the telnet options\n    #           SGA and BIN.\n    #\n    # Output_log:: the name of the file to write connection status messages\n    #              and all received traffic to.  In the case of a proper\n    #              Telnet session, this will include the client input as\n    #              echoed by the host; otherwise, it only includes server\n    #              responses.  Output is appended verbatim to this file.  \n    #              By default, no output log is kept.\n    #\n    # Dump_log:: as for Output_log, except that output is written in hexdump\n    #            format (16 bytes per line as hex pairs, followed by their\n    #            printable equivalent), with connection status messages\n    #            preceded by '#', sent traffic preceded by '>', and \n    #            received traffic preceded by '<'.  By default, not dump log\n    #            is kept.\n    #\n    # Prompt:: a regular expression matching the host's command-line prompt\n    #          sequence.  This is needed by the Telnet class to determine\n    #          when the output from a command has finished and the host is\n    #          ready to receive a new command.  By default, this regular\n    #          expression is /[$%#>] \\z/n.\n    #\n    # Telnetmode:: a boolean value, true by default.  In telnet mode, \n    #              traffic received from the host is parsed for special\n    #              command sequences, and these sequences are escaped\n    #              in outgoing traffic sent using #puts() or #print()\n    #              (but not #write()).  If you are using the Net::Telnet\n    #              object to connect to a non-telnet service (such as\n    #              SMTP or POP), this should be set to \"false\" to prevent\n    #              undesired data corruption.  This value can also be set\n    #              by the #telnetmode() method.\n    #\n    # Timeout:: the number of seconds to wait before timing out both the\n    #           initial attempt to connect to host (in this constructor),\n    #           and all attempts to read data from the host (in #waitfor(),\n    #           #cmd(), and #login()).  Exceeding this timeout causes a\n    #           TimeoutError to be raised.  The default value is 10 seconds.\n    #           You can disable the timeout by setting this value to false.\n    #           In this case, the connect attempt will eventually timeout\n    #           on the underlying connect(2) socket call with an\n    #           Errno::ETIMEDOUT error (but generally only after a few\n    #           minutes), but other attempts to read data from the host\n    #           will hand indefinitely if no data is forthcoming.\n    #\n    # Waittime:: the amount of time to wait after seeing what looks like a \n    #            prompt (that is, received data that matches the Prompt\n    #            option regular expression) to see if more data arrives.\n    #            If more data does arrive in this time, Net::Telnet assumes\n    #            that what it saw was not really a prompt.  This is to try to \n    #            avoid false matches, but it can also lead to missing real\n    #            prompts (if, for instance, a background process writes to\n    #            the terminal soon after the prompt is displayed).  By\n    #            default, set to 0, meaning not to wait for more data.\n    #\n    # Proxy:: a proxy object to used instead of opening a direct connection\n    #         to the host.  Must be either another Net::Telnet object or\n    #         an IO object.  If it is another Net::Telnet object, this \n    #         instance will use that one's socket for communication.  If an\n    #         IO object, it is used directly for communication.  Any other\n    #         kind of object will cause an error to be raised.\n    #\n    def initialize(options) # :yield: mesg \n      @options = options\n      @options[\"Host\"]       = \"localhost\"   unless @options.has_key?(\"Host\")\n      @options[\"Port\"]       = 23            unless @options.has_key?(\"Port\")\n      @options[\"Prompt\"]     = /[$%#>] \\z/n  unless @options.has_key?(\"Prompt\")\n      @options[\"Timeout\"]    = 10            unless @options.has_key?(\"Timeout\")\n      @options[\"Waittime\"]   = 0             unless @options.has_key?(\"Waittime\")\n      unless @options.has_key?(\"Binmode\")\n        @options[\"Binmode\"]    = false         \n      else\n        unless (true == @options[\"Binmode\"] or false == @options[\"Binmode\"])\n          raise ArgumentError, \"Binmode option must be true or false\"\n        end\n      end\n\n      unless @options.has_key?(\"Telnetmode\")\n        @options[\"Telnetmode\"] = true          \n      else\n        unless (true == @options[\"Telnetmode\"] or false == @options[\"Telnetmode\"])\n          raise ArgumentError, \"Telnetmode option must be true or false\"\n        end\n      end\n\n      @telnet_option = { \"SGA\" => false, \"BINARY\" => false }\n\n      if @options.has_key?(\"Output_log\")\n        @log = File.open(@options[\"Output_log\"], 'a+')\n        @log.sync = true\n        @log.binmode\n      end\n\n      if @options.has_key?(\"Dump_log\")\n        @dumplog = File.open(@options[\"Dump_log\"], 'a+')\n        @dumplog.sync = true\n        @dumplog.binmode\n        def @dumplog.log_dump(dir, x)  # :nodoc:\n          len = x.length\n          addr = 0\n          offset = 0\n          while 0 < len\n            if len < 16\n              line = x[offset, len]\n            else\n              line = x[offset, 16]\n            end\n            hexvals = line.unpack('H*')[0]\n            hexvals += ' ' * (32 - hexvals.length)\n            hexvals = format(\"%s %s %s %s  \" * 4, *hexvals.unpack('a2' * 16))\n            line = line.gsub(/[\\000-\\037\\177-\\377]/n, '.')\n            printf \"%s 0x%5.5x: %s%s\\n\", dir, addr, hexvals, line\n            addr += 16\n            offset += 16\n            len -= 16\n          end\n          print \"\\n\"\n        end\n      end\n\n      if @options.has_key?(\"Proxy\")\n        if @options[\"Proxy\"].kind_of?(Net::Telnet)\n          @sock = @options[\"Proxy\"].sock\n        elsif @options[\"Proxy\"].kind_of?(IO)\n          @sock = @options[\"Proxy\"]\n        else\n          raise \"Error: Proxy must be an instance of Net::Telnet or IO.\"\n        end\n      else\n        message = \"Trying \" + @options[\"Host\"] + \"...\\n\"\n        yield(message) if block_given?\n        @log.write(message) if @options.has_key?(\"Output_log\")\n        @dumplog.log_dump('#', message) if @options.has_key?(\"Dump_log\")\n\n        begin\n          if @options[\"Timeout\"] == false\n            @sock = TCPSocket.open(@options[\"Host\"], @options[\"Port\"])\n          else\n            timeout(@options[\"Timeout\"]) do\n              @sock = TCPSocket.open(@options[\"Host\"], @options[\"Port\"])\n            end\n          end\n        rescue TimeoutError\n          raise TimeoutError, \"timed out while opening a connection to the host\"\n        rescue\n          @log.write($ERROR_INFO.to_s + \"\\n\") if @options.has_key?(\"Output_log\")\n          @dumplog.log_dump('#', $ERROR_INFO.to_s + \"\\n\") if @options.has_key?(\"Dump_log\")\n          raise\n        end\n        @sock.sync = true\n        @sock.binmode\n\n        message = \"Connected to \" + @options[\"Host\"] + \".\\n\"\n        yield(message) if block_given?\n        @log.write(message) if @options.has_key?(\"Output_log\")\n        @dumplog.log_dump('#', message) if @options.has_key?(\"Dump_log\")\n      end\n\n      super(@sock)\n    end # initialize\n\n    # The socket the Telnet object is using.  Note that this object becomes\n    # a delegate of the Telnet object, so normally you invoke its methods\n    # directly on the Telnet object.\n    attr :sock \n\n    # Set telnet command interpretation on (+mode+ == true) or off\n    # (+mode+ == false), or return the current value (+mode+ not\n    # provided).  It should be on for true telnet sessions, off if\n    # using Net::Telnet to connect to a non-telnet service such\n    # as SMTP.\n    def telnetmode(mode = nil)\n      case mode\n      when nil\n        @options[\"Telnetmode\"]\n      when true, false\n        @options[\"Telnetmode\"] = mode\n      else\n        raise ArgumentError, \"argument must be true or false, or missing\"\n      end\n    end\n\n    # Turn telnet command interpretation on (true) or off (false).  It\n    # should be on for true telnet sessions, off if using Net::Telnet\n    # to connect to a non-telnet service such as SMTP.\n    def telnetmode=(mode)\n      if (true == mode or false == mode)\n        @options[\"Telnetmode\"] = mode\n      else\n        raise ArgumentError, \"argument must be true or false\"\n      end\n    end\n\n    # Turn newline conversion on (+mode+ == false) or off (+mode+ == true),\n    # or return the current value (+mode+ is not specified).\n    def binmode(mode = nil)\n      case mode\n      when nil\n        @options[\"Binmode\"] \n      when true, false\n        @options[\"Binmode\"] = mode\n      else\n        raise ArgumentError, \"argument must be true or false\"\n      end\n    end\n\n    # Turn newline conversion on (false) or off (true).\n    def binmode=(mode)\n      if (true == mode or false == mode)\n        @options[\"Binmode\"] = mode\n      else\n        raise ArgumentError, \"argument must be true or false\"\n      end\n    end\n\n    # Preprocess received data from the host.\n    #\n    # Performs newline conversion and detects telnet command sequences.\n    # Called automatically by #waitfor().  You should only use this \n    # method yourself if you have read input directly using sysread()\n    # or similar, and even then only if in telnet mode.\n    def preprocess(string)\n      # combine CR+NULL into CR\n      string = string.gsub(/#{CR}#{NULL}/no, CR) if @options[\"Telnetmode\"]\n\n      # combine EOL into \"\\n\"\n      string = string.gsub(/#{EOL}/no, \"\\n\") unless @options[\"Binmode\"]\n\n      string.gsub(/#{IAC}(\n                   [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|\n                   [#{DO}#{DONT}#{WILL}#{WONT}]\n                     [#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|\n                   #{SB}[^#{IAC}]*#{IAC}#{SE}\n                 )/xno) do\n        if    IAC == $1  # handle escaped IAC characters\n          IAC\n        elsif AYT == $1  # respond to \"IAC AYT\" (are you there)\n          self.write(\"nobody here but us pigeons\" + EOL)\n          ''\n        elsif DO[0] == $1[0]  # respond to \"IAC DO x\"\n          if OPT_BINARY[0] == $1[1]\n            @telnet_option[\"BINARY\"] = true\n            self.write(IAC + WILL + OPT_BINARY)\n          else\n            self.write(IAC + WONT + $1[1..1])\n          end\n          ''\n        elsif DONT[0] == $1[0]  # respond to \"IAC DON'T x\" with \"IAC WON'T x\"\n          self.write(IAC + WONT + $1[1..1])\n          ''\n        elsif WILL[0] == $1[0]  # respond to \"IAC WILL x\"\n          if    OPT_BINARY[0] == $1[1]\n            self.write(IAC + DO + OPT_BINARY)\n          elsif OPT_ECHO[0] == $1[1]\n            self.write(IAC + DO + OPT_ECHO)\n          elsif OPT_SGA[0]  == $1[1]\n            @telnet_option[\"SGA\"] = true\n            self.write(IAC + DO + OPT_SGA)\n          else\n            self.write(IAC + DONT + $1[1..1])\n          end\n          ''\n        elsif WONT[0] == $1[0]  # respond to \"IAC WON'T x\"\n          if    OPT_ECHO[0] == $1[1]\n            self.write(IAC + DONT + OPT_ECHO)\n          elsif OPT_SGA[0]  == $1[1]\n            @telnet_option[\"SGA\"] = false\n            self.write(IAC + DONT + OPT_SGA)\n          else\n            self.write(IAC + DONT + $1[1..1])\n          end\n          ''\n        else\n          ''\n        end\n      end\n    end # preprocess\n\n    # Read data from the host until a certain sequence is matched.\n    #\n    # If a block is given, the received data will be yielded as it\n    # is read in (not necessarily all in one go), or nil if EOF \n    # occurs before any data is received.  Whether a block is given\n    # or not, all data read will be returned in a single string, or again \n    # nil if EOF occurs before any data is received.  Note that\n    # received data includes the matched sequence we were looking for.\n    #\n    # +options+ can be either a regular expression or a hash of options.\n    # If a regular expression, this specifies the data to wait for.\n    # If a hash, this can specify the following options:\n    #\n    # Match:: a regular expression, specifying the data to wait for.\n    # Prompt:: as for Match; used only if Match is not specified.\n    # String:: as for Match, except a string that will be converted\n    #          into a regular expression.  Used only if Match and\n    #          Prompt are not specified.\n    # Timeout:: the number of seconds to wait for data from the host\n    #           before raising a TimeoutError.  If set to false, \n    #           no timeout will occur.  If not specified, the\n    #           Timeout option value specified when this instance\n    #           was created will be used, or, failing that, the\n    #           default value of 10 seconds.\n    # Waittime:: the number of seconds to wait after matching against\n    #            the input data to see if more data arrives.  If more\n    #            data arrives within this time, we will judge ourselves\n    #            not to have matched successfully, and will continue\n    #            trying to match.  If not specified, the Waittime option\n    #            value specified when this instance was created will be\n    #            used, or, failing that, the default value of 0 seconds,\n    #            which means not to wait for more input.\n    # FailEOF:: if true, when the remote end closes the connection then an\n    #           EOFError will be raised. Otherwise, defaults to the old\n    #           behaviour that the function will return whatever data\n    #           has been received already, or nil if nothing was received.\n    #           \n    def waitfor(options) # :yield: recvdata\n      time_out = @options[\"Timeout\"]\n      waittime = @options[\"Waittime\"]\n      fail_eof = @options[\"FailEOF\"]\n\n      if options.kind_of?(Hash)\n        prompt   = if options.has_key?(\"Match\")\n                     options[\"Match\"]\n                   elsif options.has_key?(\"Prompt\")\n                     options[\"Prompt\"]\n                   elsif options.has_key?(\"String\")\n                     Regexp.new( Regexp.quote(options[\"String\"]) )\n                   end\n        time_out = options[\"Timeout\"]  if options.has_key?(\"Timeout\")\n        waittime = options[\"Waittime\"] if options.has_key?(\"Waittime\")\n        fail_eof = options[\"FailEOF\"]  if options.has_key?(\"FailEOF\")\n      else\n        prompt = options\n      end\n\n      if time_out == false\n        time_out = nil\n      end\n\n      line = ''\n      buf = ''\n      rest = ''\n      until(prompt === line and not IO::select([@sock], nil, nil, waittime))\n        unless IO::select([@sock], nil, nil, time_out)\n          raise TimeoutError, \"timed out while waiting for more data\"\n        end\n        begin\n          c = @sock.readpartial(1024 * 1024)\n          @dumplog.log_dump('<', c) if @options.has_key?(\"Dump_log\")\n          if @options[\"Telnetmode\"]\n            c = rest + c\n            if Integer(c.rindex(/#{IAC}#{SE}/no)) <\n               Integer(c.rindex(/#{IAC}#{SB}/no))\n              buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)])\n              rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1]\n            elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\\z/no) ||\n                       c.rindex(/\\r\\z/no)\n              buf = preprocess(c[0 ... pt])\n              rest = c[pt .. -1]\n            else\n              buf = preprocess(c)\n              rest = ''\n            end\n         else\n           # Not Telnetmode.\n           #\n           # We cannot use preprocess() on this data, because that\n           # method makes some Telnetmode-specific assumptions.\n           buf = rest + c\n           rest = ''\n           unless @options[\"Binmode\"]\n             if pt = buf.rindex(/\\r\\z/no)\n               buf = buf[0 ... pt]\n               rest = buf[pt .. -1]\n             end\n             buf.gsub!(/#{EOL}/no, \"\\n\")\n           end\n          end\n          @log.print(buf) if @options.has_key?(\"Output_log\")\n          line += buf\n          yield buf if block_given?\n        rescue EOFError # End of file reached\n          raise if fail_eof\n          if line == ''\n            line = nil\n            yield nil if block_given?\n          end\n          break\n        end\n      end\n      line\n    end\n\n    # Write +string+ to the host.\n    #\n    # Does not perform any conversions on +string+.  Will log +string+ to the\n    # dumplog, if the Dump_log option is set.\n    def write(string)\n      length = string.length\n      while 0 < length\n        IO::select(nil, [@sock])\n        @dumplog.log_dump('>', string[-length..-1]) if @options.has_key?(\"Dump_log\")\n        length -= @sock.syswrite(string[-length..-1])\n      end\n    end\n\n    # Sends a string to the host.\n    #\n    # This does _not_ automatically append a newline to the string.  Embedded\n    # newlines may be converted and telnet command sequences escaped \n    # depending upon the values of telnetmode, binmode, and telnet options\n    # set by the host.\n    def print(string)\n      string = string.gsub(/#{IAC}/no, IAC + IAC) if @options[\"Telnetmode\"]\n\n      if @options[\"Binmode\"]\n        self.write(string)\n      else\n        if @telnet_option[\"BINARY\"] and @telnet_option[\"SGA\"]\n          # IAC WILL SGA IAC DO BIN send EOL --> CR\n          self.write(string.gsub(/\\n/n, CR))\n        elsif @telnet_option[\"SGA\"]\n          # IAC WILL SGA send EOL --> CR+NULL\n          self.write(string.gsub(/\\n/n, CR + NULL))\n        else\n          # NONE send EOL --> CR+LF\n          self.write(string.gsub(/\\n/n, EOL))\n        end\n      end\n    end\n\n    # Sends a string to the host.\n    #\n    # Same as #print(), but appends a newline to the string.\n    def puts(string)\n      self.print(string + \"\\n\")\n    end\n\n    # Send a command to the host.\n    #\n    # More exactly, sends a string to the host, and reads in all received\n    # data until is sees the prompt or other matched sequence.\n    #\n    # If a block is given, the received data will be yielded to it as\n    # it is read in.  Whether a block is given or not, the received data \n    # will be return as a string.  Note that the received data includes\n    # the prompt and in most cases the host's echo of our command.\n    #\n    # +options+ is either a String, specified the string or command to\n    # send to the host; or it is a hash of options.  If a hash, the\n    # following options can be specified:\n    #\n    # String:: the command or other string to send to the host.\n    # Match:: a regular expression, the sequence to look for in\n    #         the received data before returning.  If not specified,\n    #         the Prompt option value specified when this instance\n    #         was created will be used, or, failing that, the default\n    #         prompt of /[$%#>] \\z/n.\n    # Timeout:: the seconds to wait for data from the host before raising\n    #           a Timeout error.  If not specified, the Timeout option\n    #           value specified when this instance was created will be\n    #           used, or, failing that, the default value of 10 seconds.\n    #\n    # The command or other string will have the newline sequence appended\n    # to it.\n    def cmd(options) # :yield: recvdata\n      match    = @options[\"Prompt\"]\n      time_out = @options[\"Timeout\"]\n\n      if options.kind_of?(Hash)\n        string   = options[\"String\"]\n        match    = options[\"Match\"]   if options.has_key?(\"Match\")\n        time_out = options[\"Timeout\"] if options.has_key?(\"Timeout\")\n      else\n        string = options\n      end\n\n      self.puts(string)\n      if block_given?\n        waitfor({\"Prompt\" => match, \"Timeout\" => time_out}){|c| yield c }\n      else\n        waitfor({\"Prompt\" => match, \"Timeout\" => time_out})\n      end\n    end\n\n    # Login to the host with a given username and password.\n    #\n    # The username and password can either be provided as two string\n    # arguments in that order, or as a hash with keys \"Name\" and\n    # \"Password\".    \n    #\n    # This method looks for the strings \"login\" and \"Password\" from the\n    # host to determine when to send the username and password.  If the\n    # login sequence does not follow this pattern (for instance, you\n    # are connecting to a service other than telnet), you will need\n    # to handle login yourself.\n    #\n    # The password can be omitted, either by only\n    # provided one String argument, which will be used as the username,\n    # or by providing a has that has no \"Password\" key.  In this case,\n    # the method will not look for the \"Password:\" prompt; if it is\n    # sent, it will have to be dealt with by later calls.\n    #\n    # The method returns all data received during the login process from\n    # the host, including the echoed username but not the password (which\n    # the host should not echo).  If a block is passed in, this received\n    # data is also yielded to the block as it is received.\n    def login(options, password = nil) # :yield: recvdata\n      login_prompt = /[Ll]ogin[: ]*\\z/n\n      password_prompt = /[Pp]ass(?:word|phrase)[: ]*\\z/n\n      if options.kind_of?(Hash)\n        username = options[\"Name\"]\n        password = options[\"Password\"]\n\tlogin_prompt = options[\"LoginPrompt\"] if options[\"LoginPrompt\"]\n\tpassword_prompt = options[\"PasswordPrompt\"] if options[\"PasswordPrompt\"]\n      else\n        username = options\n      end\n\n      if block_given?\n        line = waitfor(login_prompt){|c| yield c }\n        if password\n          line += cmd({\"String\" => username,\n                       \"Match\" => password_prompt}){|c| yield c }\n          line += cmd(password){|c| yield c }\n        else\n          line += cmd(username){|c| yield c }\n        end\n      else\n        line = waitfor(login_prompt)\n        if password\n          line += cmd({\"String\" => username,\n                       \"Match\" => password_prompt})\n          line += cmd(password)\n        else\n          line += cmd(username)\n        end\n      end\n      line\n    end\n\n  end  # class Telnet\nend  # module Net\n\n"
  },
  {
    "path": "lib/observer.rb",
    "content": "#\n# observer.rb implements the _Observer_ object-oriented design pattern.  The\n# following documentation is copied, with modifications, from \"Programming\n# Ruby\", by Hunt and Thomas; http://www.rubycentral.com/book/lib_patterns.html.\n#\n# == About\n#\n# The Observer pattern, also known as Publish/Subscribe, provides a simple\n# mechanism for one object to inform a set of interested third-party objects\n# when its state changes. \n#\n# == Mechanism\n#\n# In the Ruby implementation, the notifying class mixes in the +Observable+\n# module, which provides the methods for managing the associated observer\n# objects.\n#\n# The observers must implement the +update+ method to receive notifications.\n#\n# The observable object must:\n# * assert that it has +changed+\n# * call +notify_observers+\n#\n# == Example\n#\n# The following example demonstrates this nicely.  A +Ticker+, when run,\n# continually receives the stock +Price+ for its +@symbol+.  A +Warner+ is a\n# general observer of the price, and two warners are demonstrated, a +WarnLow+\n# and a +WarnHigh+, which print a warning if the price is below or above their\n# set limits, respectively.\n#\n# The +update+ callback allows the warners to run without being explicitly\n# called.  The system is set up with the +Ticker+ and several observers, and the\n# observers do their duty without the top-level code having to interfere.\n#\n# Note that the contract between publisher and subscriber (observable and\n# observer) is not declared or enforced.  The +Ticker+ publishes a time and a\n# price, and the warners receive that.  But if you don't ensure that your\n# contracts are correct, nothing else can warn you.\n#\n#   require \"observer\"\n#   \n#   class Ticker          ### Periodically fetch a stock price.\n#     include Observable\n#   \n#     def initialize(symbol)\n#       @symbol = symbol\n#     end\n#   \n#     def run\n#       lastPrice = nil\n#       loop do\n#         price = Price.fetch(@symbol)\n#         print \"Current price: #{price}\\n\"\n#         if price != lastPrice\n#           changed                 # notify observers\n#           lastPrice = price\n#           notify_observers(Time.now, price)\n#         end\n#         sleep 1\n#       end\n#     end\n#   end\n#\n#   class Price           ### A mock class to fetch a stock price (60 - 140).\n#     def Price.fetch(symbol)\n#       60 + rand(80)\n#     end\n#   end\n#   \n#   class Warner          ### An abstract observer of Ticker objects.\n#     def initialize(ticker, limit)\n#       @limit = limit\n#       ticker.add_observer(self)\n#     end\n#   end\n#   \n#   class WarnLow < Warner\n#     def update(time, price)       # callback for observer\n#       if price < @limit\n#         print \"--- #{time.to_s}: Price below #@limit: #{price}\\n\"\n#       end\n#     end\n#   end\n#   \n#   class WarnHigh < Warner\n#     def update(time, price)       # callback for observer\n#       if price > @limit\n#         print \"+++ #{time.to_s}: Price above #@limit: #{price}\\n\"\n#       end\n#     end\n#   end\n#\n#   ticker = Ticker.new(\"MSFT\")\n#   WarnLow.new(ticker, 80)\n#   WarnHigh.new(ticker, 120)\n#   ticker.run\n#\n# Produces:\n#\n#   Current price: 83\n#   Current price: 75\n#   --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 75\n#   Current price: 90\n#   Current price: 134\n#   +++ Sun Jun 09 00:10:25 CDT 2002: Price above 120: 134\n#   Current price: 134\n#   Current price: 112\n#   Current price: 79\n#   --- Sun Jun 09 00:10:25 CDT 2002: Price below 80: 79\n\n\n#\n# Implements the Observable design pattern as a mixin so that other objects can\n# be notified of changes in state.  See observer.rb for details and an example.\n#\nmodule Observable\n\n  #\n  # Add +observer+ as an observer on this object. +observer+ will now receive\n  # notifications.\n  #\n  def add_observer(observer)\n    @observer_peers = [] unless defined? @observer_peers\n    unless observer.respond_to? :update\n      raise NoMethodError, \"observer needs to respond to `update'\" \n    end\n    @observer_peers.push observer\n  end\n\n  #\n  # Delete +observer+ as an observer on this object. It will no longer receive\n  # notifications.\n  #\n  def delete_observer(observer)\n    @observer_peers.delete observer if defined? @observer_peers\n  end\n\n  #\n  # Delete all observers associated with this object.\n  #\n  def delete_observers\n    @observer_peers.clear if defined? @observer_peers\n  end\n\n  #\n  # Return the number of observers associated with this object.\n  #\n  def count_observers\n    if defined? @observer_peers\n      @observer_peers.size\n    else\n      0\n    end\n  end\n\n  #\n  # Set the changed state of this object.  Notifications will be sent only if\n  # the changed +state+ is +true+.\n  #\n  def changed(state=true)\n    @observer_state = state\n  end\n\n  #\n  # Query the changed state of this object.\n  #\n  def changed?\n    if defined? @observer_state and @observer_state\n      true\n    else\n      false\n    end\n  end\n\n  #\n  # If this object's changed state is +true+, invoke the update method in each\n  # currently associated observer in turn, passing it the given arguments. The\n  # changed state is then set to +false+.\n  #\n  def notify_observers(*arg)\n    if defined? @observer_state and @observer_state\n      if defined? @observer_peers\n\tfor i in @observer_peers.dup\n\t  i.update(*arg)\n\tend\n      end\n      @observer_state = false\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/open-uri.rb",
    "content": "require 'uri'\nrequire 'stringio'\nrequire 'time'\n\nmodule Kernel\n  private\n  alias open_uri_original_open open # :nodoc:\n\n  # makes possible to open various resources including URIs.\n  # If the first argument respond to `open' method,\n  # the method is called with the rest arguments.\n  #\n  # If the first argument is a string which begins with xxx://,\n  # it is parsed by URI.parse.  If the parsed object respond to `open' method,\n  # the method is called with the rest arguments.\n  #\n  # Otherwise original open is called.\n  #\n  # Since open-uri.rb provides URI::HTTP#open, URI::HTTPS#open and\n  # URI::FTP#open,\n  # Kernel[#.]open can accepts such URIs and strings which begins with\n  # http://, https:// and ftp://.\n  # In these case, the opened file object is extended by OpenURI::Meta.\n  def open(name, *rest, &block) # :doc:\n    if name.respond_to?(:open)\n      name.open(*rest, &block)\n    elsif name.respond_to?(:to_str) &&\n          %r{\\A[A-Za-z][A-Za-z0-9+\\-\\.]*://} =~ name &&\n          (uri = URI.parse(name)).respond_to?(:open)\n      uri.open(*rest, &block)\n    else\n      open_uri_original_open(name, *rest, &block)\n    end\n  end\n  module_function :open\nend\n\n# OpenURI is an easy-to-use wrapper for net/http, net/https and net/ftp.\n#\n#== Example\n#\n# It is possible to open http/https/ftp URL as usual like opening a file:\n#\n#   open(\"http://www.ruby-lang.org/\") {|f|\n#     f.each_line {|line| p line}\n#   }\n#\n# The opened file has several methods for meta information as follows since\n# it is extended by OpenURI::Meta.\n#\n#   open(\"http://www.ruby-lang.org/en\") {|f|\n#     f.each_line {|line| p line}\n#     p f.base_uri         # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>\n#     p f.content_type     # \"text/html\"\n#     p f.charset          # \"iso-8859-1\"\n#     p f.content_encoding # []\n#     p f.last_modified    # Thu Dec 05 02:45:02 UTC 2002\n#   }\n#\n# Additional header fields can be specified by an optional hash argument.\n#\n#   open(\"http://www.ruby-lang.org/en/\",\n#     \"User-Agent\" => \"Ruby/#{RUBY_VERSION}\",\n#     \"From\" => \"foo@bar.invalid\",\n#     \"Referer\" => \"http://www.ruby-lang.org/\") {|f|\n#     # ...\n#   }\n#\n# The environment variables such as http_proxy, https_proxy and ftp_proxy\n# are in effect by default.  :proxy => nil disables proxy.\n#\n#   open(\"http://www.ruby-lang.org/en/raa.html\", :proxy => nil) {|f|\n#     # ...\n#   }\n#\n# URI objects can be opened in a similar way.\n#\n#   uri = URI.parse(\"http://www.ruby-lang.org/en/\")\n#   uri.open {|f|\n#     # ...\n#   }\n#\n# URI objects can be read directly. The returned string is also extended by\n# OpenURI::Meta.\n#\n#   str = uri.read\n#   p str.base_uri\n#\n# Author:: Tanaka Akira <akr@m17n.org>\n\nmodule OpenURI\n  Options = {\n    :proxy => true,\n    :progress_proc => true,\n    :content_length_proc => true,\n    :http_basic_authentication => true,\n  }\n\n  def OpenURI.check_options(options) # :nodoc:\n    options.each {|k, v|\n      next unless Symbol === k\n      unless Options.include? k\n        raise ArgumentError, \"unrecognized option: #{k}\"\n      end\n    }\n  end\n\n  def OpenURI.scan_open_optional_arguments(*rest) # :nodoc:\n    if !rest.empty? && (String === rest.first || Integer === rest.first)\n      mode = rest.shift\n      if !rest.empty? && Integer === rest.first\n        perm = rest.shift\n      end\n    end\n    return mode, perm, rest\n  end\n\n  def OpenURI.open_uri(name, *rest) # :nodoc:\n    uri = URI::Generic === name ? name : URI.parse(name)\n    mode, perm, rest = OpenURI.scan_open_optional_arguments(*rest)\n    options = rest.shift if !rest.empty? && Hash === rest.first\n    raise ArgumentError.new(\"extra arguments\") if !rest.empty?\n    options ||= {}\n    OpenURI.check_options(options)\n\n    unless mode == nil ||\n           mode == 'r' || mode == 'rb' ||\n           mode == File::RDONLY\n      raise ArgumentError.new(\"invalid access mode #{mode} (#{uri.class} resource is read only.)\")\n    end\n\n    io = open_loop(uri, options)\n    if block_given?\n      begin\n        yield io\n      ensure\n        io.close\n      end\n    else\n      io\n    end\n  end\n\n  def OpenURI.open_loop(uri, options) # :nodoc:\n    case opt_proxy = options.fetch(:proxy, true)\n    when true\n      find_proxy = lambda {|u| u.find_proxy}\n    when nil, false\n      find_proxy = lambda {|u| nil}\n    when String\n      opt_proxy = URI.parse(opt_proxy)\n      find_proxy = lambda {|u| opt_proxy}\n    when URI::Generic\n      find_proxy = lambda {|u| opt_proxy}\n    else\n      raise ArgumentError.new(\"Invalid proxy option: #{opt_proxy}\")\n    end\n\n    uri_set = {}\n    buf = nil\n    while true\n      redirect = catch(:open_uri_redirect) {\n        buf = Buffer.new\n        uri.buffer_open(buf, find_proxy.call(uri), options)\n        nil\n      }\n      if redirect\n        if redirect.relative?\n          # Although it violates RFC2616, Location: field may have relative\n          # URI.  It is converted to absolute URI using uri as a base URI.\n          redirect = uri + redirect\n        end\n        unless OpenURI.redirectable?(uri, redirect)\n          raise \"redirection forbidden: #{uri} -> #{redirect}\"\n        end\n        if options.include? :http_basic_authentication\n          # send authentication only for the URI directly specified.\n          options = options.dup\n          options.delete :http_basic_authentication\n        end\n        uri = redirect\n        raise \"HTTP redirection loop: #{uri}\" if uri_set.include? uri.to_s\n        uri_set[uri.to_s] = true\n      else\n        break\n      end\n    end\n    io = buf.io\n    io.base_uri = uri\n    io\n  end\n\n  def OpenURI.redirectable?(uri1, uri2) # :nodoc:\n    # This test is intended to forbid a redirection from http://... to\n    # file:///etc/passwd.\n    # However this is ad hoc.  It should be extensible/configurable.\n    uri1.scheme.downcase == uri2.scheme.downcase ||\n    (/\\A(?:http|ftp)\\z/i =~ uri1.scheme && /\\A(?:http|ftp)\\z/i =~ uri2.scheme)\n  end\n\n  def OpenURI.open_http(buf, target, proxy, options) # :nodoc:\n    if proxy\n      raise \"Non-HTTP proxy URI: #{proxy}\" if proxy.class != URI::HTTP\n    end\n\n    if target.userinfo && \"1.9.0\" <= RUBY_VERSION\n      # don't raise for 1.8 because compatibility.\n      raise ArgumentError, \"userinfo not supported.  [RFC3986]\"\n    end\n\n    require 'net/http'\n    klass = Net::HTTP\n    if URI::HTTP === target\n      # HTTP or HTTPS\n      if proxy\n        klass = Net::HTTP::Proxy(proxy.host, proxy.port)\n      end\n      target_host = target.host\n      target_port = target.port\n      request_uri = target.request_uri\n    else\n      # FTP over HTTP proxy\n      target_host = proxy.host\n      target_port = proxy.port\n      request_uri = target.to_s\n    end\n\n    http = klass.new(target_host, target_port)\n    if target.class == URI::HTTPS\n      require 'net/https'\n      http.use_ssl = true\n      http.verify_mode = OpenSSL::SSL::VERIFY_PEER\n      store = OpenSSL::X509::Store.new\n      store.set_default_paths\n      http.cert_store = store\n    end\n\n    header = {}\n    options.each {|k, v| header[k] = v if String === k }\n\n    resp = nil\n    http.start {\n      req = Net::HTTP::Get.new(request_uri, header)\n      if options.include? :http_basic_authentication\n        user, pass = options[:http_basic_authentication]\n        req.basic_auth user, pass\n      end\n      http.request(req) {|response|\n        resp = response\n        if options[:content_length_proc] && Net::HTTPSuccess === resp\n          if resp.key?('Content-Length')\n            options[:content_length_proc].call(resp['Content-Length'].to_i)\n          else\n            options[:content_length_proc].call(nil)\n          end\n        end\n        resp.read_body {|str|\n          buf << str\n          if options[:progress_proc] && Net::HTTPSuccess === resp\n            options[:progress_proc].call(buf.size)\n          end\n        }\n      }\n    }\n    io = buf.io\n    io.rewind\n    io.status = [resp.code, resp.message]\n    resp.each {|name,value| buf.io.meta_add_field name, value }\n    case resp\n    when Net::HTTPSuccess\n    when Net::HTTPMovedPermanently, # 301\n         Net::HTTPFound, # 302\n         Net::HTTPSeeOther, # 303\n         Net::HTTPTemporaryRedirect # 307\n      throw :open_uri_redirect, URI.parse(resp['location'])\n    else\n      raise OpenURI::HTTPError.new(io.status.join(' '), io)\n    end\n  end\n\n  class HTTPError < StandardError\n    def initialize(message, io)\n      super(message)\n      @io = io\n    end\n    attr_reader :io\n  end\n\n  class Buffer # :nodoc:\n    def initialize\n      @io = StringIO.new\n      @size = 0\n    end\n    attr_reader :size\n\n    StringMax = 10240\n    def <<(str)\n      @io << str\n      @size += str.length\n      if StringIO === @io && StringMax < @size\n        require 'tempfile'\n        io = Tempfile.new('open-uri')\n        io.binmode\n        Meta.init io, @io if @io.respond_to? :meta\n        io << @io.string\n        @io = io\n      end\n    end\n\n    def io\n      Meta.init @io unless @io.respond_to? :meta\n      @io\n    end\n  end\n\n  # Mixin for holding meta-information.\n  module Meta\n    def Meta.init(obj, src=nil) # :nodoc:\n      obj.extend Meta\n      obj.instance_eval {\n        @base_uri = nil\n        @meta = {}\n      }\n      if src\n        obj.status = src.status\n        obj.base_uri = src.base_uri\n        src.meta.each {|name, value|\n          obj.meta_add_field(name, value)\n        }\n      end\n    end\n\n    # returns an Array which consists status code and message.\n    attr_accessor :status\n\n    # returns a URI which is base of relative URIs in the data.\n    # It may differ from the URI supplied by a user because redirection.\n    attr_accessor :base_uri\n\n    # returns a Hash which represents header fields.\n    # The Hash keys are downcased for canonicalization.\n    attr_reader :meta\n\n    def meta_add_field(name, value) # :nodoc:\n      @meta[name.downcase] = value\n    end\n\n    # returns a Time which represents Last-Modified field.\n    def last_modified\n      if v = @meta['last-modified']\n        Time.httpdate(v)\n      else\n        nil\n      end\n    end\n\n    RE_LWS = /[\\r\\n\\t ]+/n\n    RE_TOKEN = %r{[^\\x00- ()<>@,;:\\\\\"/\\[\\]?={}\\x7f]+}n\n    RE_QUOTED_STRING = %r{\"(?:[\\r\\n\\t !#-\\[\\]-~\\x80-\\xff]|\\\\[\\x00-\\x7f])*\"}n\n    RE_PARAMETERS = %r{(?:;#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?=#{RE_LWS}?(?:#{RE_TOKEN}|#{RE_QUOTED_STRING})#{RE_LWS}?)*}n\n\n    def content_type_parse # :nodoc:\n      v = @meta['content-type']\n      # The last (?:;#{RE_LWS}?)? matches extra \";\" which violates RFC2045.\n      if v && %r{\\A#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?/(#{RE_TOKEN})#{RE_LWS}?(#{RE_PARAMETERS})(?:;#{RE_LWS}?)?\\z}no =~ v\n        type = $1.downcase\n        subtype = $2.downcase\n        parameters = []\n        $3.scan(/;#{RE_LWS}?(#{RE_TOKEN})#{RE_LWS}?=#{RE_LWS}?(?:(#{RE_TOKEN})|(#{RE_QUOTED_STRING}))/no) {|att, val, qval|\n          val = qval.gsub(/[\\r\\n\\t !#-\\[\\]-~\\x80-\\xff]+|(\\\\[\\x00-\\x7f])/) { $1 ? $1[1,1] : $& } if qval\n          parameters << [att.downcase, val]\n        }\n        [\"#{type}/#{subtype}\", *parameters]\n      else\n        nil\n      end\n    end\n\n    # returns \"type/subtype\" which is MIME Content-Type.\n    # It is downcased for canonicalization.\n    # Content-Type parameters are stripped.\n    def content_type\n      type, *parameters = content_type_parse\n      type || 'application/octet-stream'\n    end\n\n    # returns a charset parameter in Content-Type field.\n    # It is downcased for canonicalization.\n    #\n    # If charset parameter is not given but a block is given,\n    # the block is called and its result is returned.\n    # It can be used to guess charset.\n    #\n    # If charset parameter and block is not given,\n    # nil is returned except text type in HTTP.\n    # In that case, \"iso-8859-1\" is returned as defined by RFC2616 3.7.1.\n    def charset\n      type, *parameters = content_type_parse\n      if pair = parameters.assoc('charset')\n        pair.last.downcase\n      elsif block_given?\n        yield\n      elsif type && %r{\\Atext/} =~ type &&\n            @base_uri && /\\Ahttp\\z/i =~ @base_uri.scheme\n        \"iso-8859-1\" # RFC2616 3.7.1\n      else\n        nil\n      end\n    end\n\n    # returns a list of encodings in Content-Encoding field\n    # as an Array of String.\n    # The encodings are downcased for canonicalization.\n    def content_encoding\n      v = @meta['content-encoding']\n      if v && %r{\\A#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?(?:,#{RE_LWS}?#{RE_TOKEN}#{RE_LWS}?)*}o =~ v\n        v.scan(RE_TOKEN).map {|content_coding| content_coding.downcase}\n      else\n        []\n      end\n    end\n  end\n\n  # Mixin for HTTP and FTP URIs.\n  module OpenRead\n    # OpenURI::OpenRead#open provides `open' for URI::HTTP and URI::FTP.\n    #\n    # OpenURI::OpenRead#open takes optional 3 arguments as:\n    # OpenURI::OpenRead#open([mode [, perm]] [, options]) [{|io| ... }]\n    #\n    # `mode', `perm' is same as Kernel#open.\n    #\n    # However, `mode' must be read mode because OpenURI::OpenRead#open doesn't\n    # support write mode (yet).\n    # Also `perm' is just ignored because it is meaningful only for file\n    # creation.\n    #\n    # `options' must be a hash.\n    #\n    # Each pairs which key is a string in the hash specify a extra header\n    # field for HTTP.\n    # I.e. it is ignored for FTP without HTTP proxy.\n    #\n    # The hash may include other options which key is a symbol:\n    #\n    # [:proxy]\n    #  Synopsis:\n    #    :proxy => \"http://proxy.foo.com:8000/\"\n    #    :proxy => URI.parse(\"http://proxy.foo.com:8000/\")\n    #    :proxy => true\n    #    :proxy => false\n    #    :proxy => nil\n    #   \n    #  If :proxy option is specified, the value should be String, URI,\n    #  boolean or nil.\n    #  When String or URI is given, it is treated as proxy URI.\n    #  When true is given or the option itself is not specified,\n    #  environment variable `scheme_proxy' is examined.\n    #  `scheme' is replaced by `http', `https' or `ftp'.\n    #  When false or nil is given, the environment variables are ignored and\n    #  connection will be made to a server directly.\n    #\n    # [:http_basic_authentication]\n    #  Synopsis:\n    #    :http_basic_authentication=>[user, password]\n    #\n    #  If :http_basic_authentication is specified,\n    #  the value should be an array which contains 2 strings:\n    #  username and password.\n    #  It is used for HTTP Basic authentication defined by RFC 2617.\n    #\n    # [:content_length_proc]\n    #  Synopsis:\n    #    :content_length_proc => lambda {|content_length| ... }\n    # \n    #  If :content_length_proc option is specified, the option value procedure\n    #  is called before actual transfer is started.\n    #  It takes one argument which is expected content length in bytes.\n    # \n    #  If two or more transfer is done by HTTP redirection, the procedure\n    #  is called only one for a last transfer.\n    # \n    #  When expected content length is unknown, the procedure is called with\n    #  nil.\n    #  It is happen when HTTP response has no Content-Length header.\n    #\n    # [:progress_proc]\n    #  Synopsis:\n    #    :progress_proc => lambda {|size| ...}\n    #\n    #  If :progress_proc option is specified, the proc is called with one\n    #  argument each time when `open' gets content fragment from network.\n    #  The argument `size' `size' is a accumulated transfered size in bytes.\n    #\n    #  If two or more transfer is done by HTTP redirection, the procedure\n    #  is called only one for a last transfer.\n    #\n    #  :progress_proc and :content_length_proc are intended to be used for\n    #  progress bar.\n    #  For example, it can be implemented as follows using Ruby/ProgressBar.\n    #\n    #    pbar = nil\n    #    open(\"http://...\",\n    #      :content_length_proc => lambda {|t|\n    #        if t && 0 < t\n    #          pbar = ProgressBar.new(\"...\", t)\n    #          pbar.file_transfer_mode\n    #        end\n    #      },\n    #      :progress_proc => lambda {|s|\n    #        pbar.set s if pbar\n    #      }) {|f| ... }\n    #\n    # OpenURI::OpenRead#open returns an IO like object if block is not given.\n    # Otherwise it yields the IO object and return the value of the block.\n    # The IO object is extended with OpenURI::Meta.\n    def open(*rest, &block)\n      OpenURI.open_uri(self, *rest, &block)\n    end\n\n    # OpenURI::OpenRead#read([options]) reads a content referenced by self and\n    # returns the content as string.\n    # The string is extended with OpenURI::Meta.\n    # The argument `options' is same as OpenURI::OpenRead#open.\n    def read(options={})\n      self.open(options) {|f|\n        str = f.read\n        Meta.init str, f\n        str\n      }\n    end\n  end\nend\n\nmodule URI\n  class Generic\n    # returns a proxy URI.\n    # The proxy URI is obtained from environment variables such as http_proxy,\n    # ftp_proxy, no_proxy, etc.\n    # If there is no proper proxy, nil is returned.\n    #\n    # Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.)\n    # are examined too.\n    #\n    # But http_proxy and HTTP_PROXY is treated specially under CGI environment.\n    # It's because HTTP_PROXY may be set by Proxy: header.\n    # So HTTP_PROXY is not used.\n    # http_proxy is not used too if the variable is case insensitive.\n    # CGI_HTTP_PROXY can be used instead.\n    def find_proxy\n      name = self.scheme.downcase + '_proxy'\n      proxy_uri = nil\n      if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?\n        # HTTP_PROXY conflicts with *_proxy for proxy settings and\n        # HTTP_* for header information in CGI.\n        # So it should be careful to use it.\n        pairs = ENV.reject {|k, v| /\\Ahttp_proxy\\z/i !~ k }\n        case pairs.length\n        when 0 # no proxy setting anyway.\n          proxy_uri = nil\n        when 1\n          k, v = pairs.shift\n          if k == 'http_proxy' && ENV[k.upcase] == nil\n            # http_proxy is safe to use because ENV is case sensitive.\n            proxy_uri = ENV[name]\n          else\n            proxy_uri = nil\n          end\n        else # http_proxy is safe to use because ENV is case sensitive.\n          proxy_uri = ENV.to_hash[name]\n        end\n        if !proxy_uri\n          # Use CGI_HTTP_PROXY.  cf. libwww-perl.\n          proxy_uri = ENV[\"CGI_#{name.upcase}\"]\n        end\n      elsif name == 'http_proxy'\n        unless proxy_uri = ENV[name]\n          if proxy_uri = ENV[name.upcase]\n            warn 'The environment variable HTTP_PROXY is discouraged.  Use http_proxy.'\n          end\n        end\n      else\n        proxy_uri = ENV[name] || ENV[name.upcase]\n      end\n\n      if proxy_uri && self.host\n        require 'socket'\n        begin\n          addr = IPSocket.getaddress(self.host)\n          proxy_uri = nil if /\\A127\\.|\\A::1\\z/ =~ addr\n        rescue SocketError\n        end\n      end\n\n      if proxy_uri\n        proxy_uri = URI.parse(proxy_uri)\n        name = 'no_proxy'\n        if no_proxy = ENV[name] || ENV[name.upcase]\n          no_proxy.scan(/([^:,]*)(?::(\\d+))?/) {|host, port|\n            if /(\\A|\\.)#{Regexp.quote host}\\z/i =~ self.host &&\n               (!port || self.port == port.to_i)\n              proxy_uri = nil\n              break\n            end\n          }\n        end\n        proxy_uri\n      else\n        nil\n      end\n    end\n  end\n\n  class HTTP\n    def buffer_open(buf, proxy, options) # :nodoc:\n      OpenURI.open_http(buf, self, proxy, options)\n    end\n\n    include OpenURI::OpenRead\n  end\n\n  class FTP\n    def buffer_open(buf, proxy, options) # :nodoc:\n      if proxy\n        OpenURI.open_http(buf, self, proxy, options)\n        return\n      end\n      require 'net/ftp'\n\n      directories = self.path.split(%r{/}, -1)\n      directories.shift if directories[0] == '' # strip a field before leading slash\n      directories.each {|d|\n        d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack(\"H2\") }\n      }\n      unless filename = directories.pop\n        raise ArgumentError, \"no filename: #{self.inspect}\"\n      end\n      directories.each {|d|\n        if /[\\r\\n]/ =~ d\n          raise ArgumentError, \"invalid directory: #{d.inspect}\"\n        end\n      }\n      if /[\\r\\n]/ =~ filename\n        raise ArgumentError, \"invalid filename: #{filename.inspect}\"\n      end\n      typecode = self.typecode\n      if typecode && /\\A[aid]\\z/ !~ typecode\n        raise ArgumentError, \"invalid typecode: #{typecode.inspect}\"\n      end\n\n      # The access sequence is defined by RFC 1738\n      ftp = Net::FTP.open(self.host)\n      # todo: extract user/passwd from .netrc.\n      user = 'anonymous'\n      passwd = nil\n      user, passwd = self.userinfo.split(/:/) if self.userinfo\n      ftp.login(user, passwd)\n      directories.each {|cwd|\n        ftp.voidcmd(\"CWD #{cwd}\")\n      }\n      if typecode\n        # xxx: typecode D is not handled.\n        ftp.voidcmd(\"TYPE #{typecode.upcase}\")\n      end\n      if options[:content_length_proc]\n        options[:content_length_proc].call(ftp.size(filename))\n      end\n      ftp.retrbinary(\"RETR #{filename}\", 4096) { |str|\n        buf << str\n        options[:progress_proc].call(buf.size) if options[:progress_proc]\n      }\n      ftp.close\n      buf.io.rewind\n    end\n\n    include OpenURI::OpenRead\n  end\nend\n"
  },
  {
    "path": "lib/open3.rb",
    "content": "#\n# = open3.rb: Popen, but with stderr, too\n#\n# Author:: Yukihiro Matsumoto\n# Documentation:: Konrad Meyer\n#\n# Open3 gives you access to stdin, stdout, and stderr when running other\n# programs.\n#\n\n#\n# Open3 grants you access to stdin, stdout, and stderr when running another\n# program. Example:\n#\n#   require \"open3\"\n#   include Open3\n#   \n#   stdin, stdout, stderr = popen3('nroff -man')\n#\n# Open3.popen3 can also take a block which will receive stdin, stdout and\n# stderr as parameters.  This ensures stdin, stdout and stderr are closed\n# once the block exits. Example:\n#\n#   require \"open3\"\n#\n#   Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }\n#\n\nmodule Open3\n  # \n  # Open stdin, stdout, and stderr streams and start external executable.\n  # Non-block form:\n  #   \n  #   require 'open3'\n  #\n  #   stdin, stdout, stderr = Open3.popen3(cmd)\n  #\n  # Block form:\n  #\n  #   require 'open3'\n  #\n  #   Open3.popen3(cmd) { |stdin, stdout, stderr| ... }\n  #\n  # The parameter +cmd+ is passed directly to Kernel#exec.\n  #\n  # _popen3_ is like _system_ in that you can pass extra parameters, and the\n  # strings won't be mangled by shell expansion.\n  #\n  #   stdin, stdout, stderr = Open3.popen3('identify', '/weird path/with spaces/and \"strange\" characters.jpg')\n  #   result = stdout.read\n  #\n  def popen3(*cmd)\n    pw = IO::pipe   # pipe[0] for read, pipe[1] for write\n    pr = IO::pipe\n    pe = IO::pipe\n\n    pid = fork{\n      # child\n      fork{\n\t# grandchild\n\tpw[1].close\n\tSTDIN.reopen(pw[0])\n\tpw[0].close\n\n\tpr[0].close\n\tSTDOUT.reopen(pr[1])\n\tpr[1].close\n\n\tpe[0].close\n\tSTDERR.reopen(pe[1])\n\tpe[1].close\n\n\texec(*cmd)\n      }\n      exit!(0)\n    }\n\n    pw[0].close\n    pr[1].close\n    pe[1].close\n    Process.waitpid(pid)\n    pi = [pw[1], pr[0], pe[0]]\n    pw[1].sync = true\n    if defined? yield\n      begin\n\treturn yield(*pi)\n      ensure\n\tpi.each{|p| p.close unless p.closed?}\n      end\n    end\n    pi\n  end\n  module_function :popen3\nend\n\nif $0 == __FILE__\n  a = Open3.popen3(\"nroff -man\")\n  Thread.start do\n    while line = gets\n      a[0].print line\n    end\n    a[0].close\n  end\n  while line = a[1].gets\n    print \":\", line\n  end\nend\n"
  },
  {
    "path": "lib/optparse/date.rb",
    "content": "require 'optparse'\nrequire 'date'\n\nOptionParser.accept(DateTime) do |s,|\n  begin\n    DateTime.parse(s) if s\n  rescue ArgumentError\n    raise OptionParser::InvalidArgument, s\n  end\nend\nOptionParser.accept(Date) do |s,|\n  begin\n    Date.parse(s) if s\n  rescue ArgumentError\n    raise OptionParser::InvalidArgument, s\n  end\nend\n"
  },
  {
    "path": "lib/optparse/shellwords.rb",
    "content": "# -*- ruby -*-\n\nrequire 'shellwords'\nrequire 'optparse'\n\nOptionParser.accept(Shellwords) {|s,| Shellwords.shellwords(s)}\n"
  },
  {
    "path": "lib/optparse/time.rb",
    "content": "require 'optparse'\nrequire 'time'\n\nOptionParser.accept(Time) do |s,|\n  begin\n    (Time.httpdate(s) rescue Time.parse(s)) if s\n  rescue\n    raise OptionParser::InvalidArgument, s\n  end\nend\n"
  },
  {
    "path": "lib/optparse/uri.rb",
    "content": "# -*- ruby -*-\n\nrequire 'optparse'\nrequire 'uri'\n\nOptionParser.accept(URI) {|s,| URI.parse(s) if s}\n"
  },
  {
    "path": "lib/optparse/version.rb",
    "content": "# OptionParser internal utility\n\nclass << OptionParser\n  def show_version(*pkg)\n    progname = ARGV.options.program_name\n    result = false\n    show = proc do |klass, cname, version|\n      str = \"#{progname}\"\n      unless klass == ::Object and cname == :VERSION\n        version = version.join(\".\") if Array === version\n        str << \": #{klass}\" unless klass == Object\n        str << \" version #{version}\"\n      end\n      [:Release, :RELEASE].find do |rel|\n        if klass.const_defined?(rel)\n          str << \" (#{klass.const_get(rel)})\"\n        end\n      end\n      puts str\n      result = true\n    end\n    if pkg.size == 1 and pkg[0] == \"all\"\n      self.search_const(::Object, /\\AV(?:ERSION|ersion)\\z/) do |klass, cname, version|\n        unless cname[1] == ?e and klass.const_defined?(:Version)\n          show.call(klass, cname.intern, version)\n        end\n      end\n    else\n      pkg.each do |pkg|\n        begin\n          pkg = pkg.split(/::|\\//).inject(::Object) {|m, c| m.const_get(c)}\n          v = case\n              when pkg.const_defined?(:Version)\n                pkg.const_get(n = :Version)\n              when pkg.const_defined?(:VERSION)\n                pkg.const_get(n = :VERSION)\n              else\n                n = nil\n                \"unknown\"\n              end\n          show.call(pkg, n, v)\n        rescue NameError\n        end\n      end\n    end\n    result\n  end\n\n  def each_const(path, klass = ::Object)\n    path.split(/::|\\//).inject(klass) do |klass, name|\n      raise NameError, path unless Module === klass\n      klass.constants.grep(/#{name}/i) do |c|\n        klass.const_defined?(c) or next\n        c = klass.const_get(c)\n      end\n    end\n  end\n\n  def search_const(klass, name)\n    klasses = [klass]\n    while klass = klasses.shift\n      klass.constants.each do |cname|\n        klass.const_defined?(cname) or next\n        const = klass.const_get(cname)\n        yield klass, cname, const if name === cname\n        klasses << const if Module === const and const != ::Object\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/optparse.rb",
    "content": "#\n# optparse.rb - command-line option analysis with the OptionParser class.\n# \n# Author:: Nobu Nakada\n# Documentation:: Nobu Nakada and Gavin Sinclair.\n#\n# See OptionParser for documentation. \n#\n\n\n# == Developer Documentation (not for RDoc output) \n# \n# === Class tree\n#\n# - OptionParser:: front end\n# - OptionParser::Switch:: each switches\n# - OptionParser::List:: options list\n# - OptionParser::ParseError:: errors on parsing\n#   - OptionParser::AmbiguousOption\n#   - OptionParser::NeedlessArgument\n#   - OptionParser::MissingArgument\n#   - OptionParser::InvalidOption\n#   - OptionParser::InvalidArgument\n#     - OptionParser::AmbiguousArgument\n#\n# === Object relationship diagram\n#\n#   +--------------+\n#   | OptionParser |<>-----+\n#   +--------------+       |                      +--------+\n#                          |                    ,-| Switch |\n#        on_head -------->+---------------+    /  +--------+\n#        accept/reject -->| List          |<|>-\n#                         |               |<|>-  +----------+\n#        on ------------->+---------------+    `-| argument |\n#                           :           :        |  class   |\n#                         +---------------+      |==========|\n#        on_tail -------->|               |      |pattern   |\n#                         +---------------+      |----------|\n#   OptionParser.accept ->| DefaultList   |      |converter |\n#                reject   |(shared between|      +----------+\n#                         | all instances)|\n#                         +---------------+\n#\n# == OptionParser\n#\n# === Introduction\n#\n# OptionParser is a class for command-line option analysis.  It is much more\n# advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented\n# solution.\n#\n# === Features\n# \n# 1. The argument specification and the code to handle it are written in the\n#    same place.\n# 2. It can output an option summary; you don't need to maintain this string\n#    separately.\n# 3. Optional and mandatory arguments are specified very gracefully.\n# 4. Arguments can be automatically converted to a specified class.\n# 5. Arguments can be restricted to a certain set.\n#\n# All of these features are demonstrated in the examples below.\n#\n# === Minimal example\n#\n#   require 'optparse'\n#\n#   options = {}\n#   OptionParser.new do |opts|\n#     opts.banner = \"Usage: example.rb [options]\"\n#\n#     opts.on(\"-v\", \"--[no-]verbose\", \"Run verbosely\") do |v|\n#       options[:verbose] = v\n#     end\n#   end.parse!\n#\n#   p options\n#   p ARGV\n#\n# === Complete example\n#\n# The following example is a complete Ruby program.  You can run it and see the\n# effect of specifying various options.  This is probably the best way to learn\n# the features of +optparse+.\n#\n#   require 'optparse'\n#   require 'optparse/time'\n#   require 'ostruct'\n#   require 'pp'\n#   \n#   class OptparseExample\n#   \n#     CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]\n#     CODE_ALIASES = { \"jis\" => \"iso-2022-jp\", \"sjis\" => \"shift_jis\" }\n#   \n#     #\n#     # Return a structure describing the options.\n#     #\n#     def self.parse(args)\n#       # The options specified on the command line will be collected in *options*.\n#       # We set default values here.\n#       options = OpenStruct.new\n#       options.library = []\n#       options.inplace = false\n#       options.encoding = \"utf8\"\n#       options.transfer_type = :auto\n#       options.verbose = false\n#       \n#       opts = OptionParser.new do |opts|\n#         opts.banner = \"Usage: example.rb [options]\"\n#       \n#         opts.separator \"\"\n#         opts.separator \"Specific options:\"\n#       \n#         # Mandatory argument.\n#         opts.on(\"-r\", \"--require LIBRARY\",\n#                 \"Require the LIBRARY before executing your script\") do |lib|\n#           options.library << lib\n#         end\n#       \n#         # Optional argument; multi-line description.\n#         opts.on(\"-i\", \"--inplace [EXTENSION]\",\n#                 \"Edit ARGV files in place\",\n#                 \"  (make backup if EXTENSION supplied)\") do |ext|\n#           options.inplace = true\n#           options.extension = ext || ''\n#           options.extension.sub!(/\\A\\.?(?=.)/, \".\")  # Ensure extension begins with dot.\n#         end\n#       \n#         # Cast 'delay' argument to a Float.\n#         opts.on(\"--delay N\", Float, \"Delay N seconds before executing\") do |n|\n#           options.delay = n\n#         end\n#       \n#         # Cast 'time' argument to a Time object.\n#         opts.on(\"-t\", \"--time [TIME]\", Time, \"Begin execution at given time\") do |time|\n#           options.time = time\n#         end\n#       \n#         # Cast to octal integer.\n#         opts.on(\"-F\", \"--irs [OCTAL]\", OptionParser::OctalInteger,\n#                 \"Specify record separator (default \\\\0)\") do |rs|\n#           options.record_separator = rs\n#         end\n#       \n#         # List of arguments.\n#         opts.on(\"--list x,y,z\", Array, \"Example 'list' of arguments\") do |list|\n#           options.list = list\n#         end\n#       \n#         # Keyword completion.  We are specifying a specific set of arguments (CODES\n#         # and CODE_ALIASES - notice the latter is a Hash), and the user may provide\n#         # the shortest unambiguous text.\n#         code_list = (CODE_ALIASES.keys + CODES).join(',')\n#         opts.on(\"--code CODE\", CODES, CODE_ALIASES, \"Select encoding\",\n#                 \"  (#{code_list})\") do |encoding|\n#           options.encoding = encoding\n#         end\n#       \n#         # Optional argument with keyword completion.\n#         opts.on(\"--type [TYPE]\", [:text, :binary, :auto],\n#                 \"Select transfer type (text, binary, auto)\") do |t|\n#           options.transfer_type = t\n#         end\n#       \n#         # Boolean switch.\n#         opts.on(\"-v\", \"--[no-]verbose\", \"Run verbosely\") do |v|\n#           options.verbose = v\n#         end\n#       \n#         opts.separator \"\"\n#         opts.separator \"Common options:\"\n#       \n#         # No argument, shows at tail.  This will print an options summary.\n#         # Try it and see!\n#         opts.on_tail(\"-h\", \"--help\", \"Show this message\") do\n#           puts opts\n#           exit\n#         end\n#       \n#         # Another typical switch to print the version.\n#         opts.on_tail(\"--version\", \"Show version\") do\n#           puts OptionParser::Version.join('.')\n#           exit\n#         end\n#       end\n#       \n#       opts.parse!(args)\n#       options\n#     end  # parse()\n#   \n#   end  # class OptparseExample\n#   \n#   options = OptparseExample.parse(ARGV)\n#   pp options\n#\n# === Further documentation\n#\n# The above examples should be enough to learn how to use this class.  If you\n# have any questions, email me (gsinclair@soyabean.com.au) and I will update\n# this document.\n#\nclass OptionParser\n  # :stopdoc:\n  RCSID = %w$Id$[1..-1].each {|s| s.freeze}.freeze\n  Version = (RCSID[1].split('.').collect {|s| s.to_i}.extend(Comparable).freeze if RCSID[1])\n  LastModified = (Time.gm(*RCSID[2, 2].join('-').scan(/\\d+/).collect {|s| s.to_i}) if RCSID[2])\n  Release = RCSID[2]\n\n  NoArgument = [NO_ARGUMENT = :NONE, nil].freeze\n  RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze\n  OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze\n  # :startdoc:\n\n  #\n  # Keyword completion module.  This allows partial arguments to be specified\n  # and resolved against a list of acceptable values.\n  #\n  module Completion\n    def complete(key, icase = false, pat = nil)\n      pat ||= Regexp.new('\\A' + Regexp.quote(key).gsub(/\\w+\\b/, '\\&\\w*'),\n                         icase)\n      canon, sw, k, v, cn = nil\n      candidates = []\n      each do |k, *v|\n        (if Regexp === k\n           kn = nil\n           k === key\n         else\n           kn = defined?(k.id2name) ? k.id2name : k\n           pat === kn\n         end) or next\n        v << k if v.empty?\n        candidates << [k, v, kn]\n      end\n      candidates = candidates.sort_by {|k, v, kn| kn.size}\n      if candidates.size == 1\n        canon, sw, * = candidates[0]\n      elsif candidates.size > 1\n        canon, sw, cn = candidates.shift\n        candidates.each do |k, v, kn|\n          next if sw == v\n          if String === cn and String === kn\n            if cn.rindex(kn, 0)\n              canon, sw, cn = k, v, kn\n              next\n            elsif kn.rindex(cn, 0)\n              next\n            end\n          end\n          throw :ambiguous, key\n        end\n      end\n      if canon\n        block_given? or return key, *sw\n        yield(key, *sw)\n      end\n    end\n\n    def convert(opt = nil, val = nil, *)\n      val\n    end\n  end\n\n\n  #\n  # Map from option/keyword string to object with completion.\n  #\n  class OptionMap < Hash\n    include Completion\n  end\n\n\n  #\n  # Individual switch class.  Not important to the user.\n  #\n  # Defined within Switch are several Switch-derived classes: NoArgument,\n  # RequiredArgument, etc. \n  #\n  class Switch\n    attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block\n\n    #\n    # Guesses argument style from +arg+.  Returns corresponding\n    # OptionParser::Switch class (OptionalArgument, etc.).\n    #\n    def self.guess(arg)\n      case arg\n      when \"\"\n        t = self\n      when /\\A=?\\[/\n        t = Switch::OptionalArgument\n      when /\\A\\s+\\[/\n        t = Switch::PlacedArgument\n      else\n        t = Switch::RequiredArgument\n      end\n      self >= t or incompatible_argument_styles(arg, t)\n      t\n    end\n\n    def self.incompatible_argument_styles(arg, t)\n      raise ArgumentError, \"#{arg}: incompatible argument styles\\n  #{self}, #{t}\"\n    end\n\n    def self.pattern\n      NilClass\n    end\n\n    def initialize(pattern = nil, conv = nil,\n                   short = nil, long = nil, arg = nil,\n                   desc = ([] if short or long), block = Proc.new)\n      raise if Array === pattern\n      @pattern, @conv, @short, @long, @arg, @desc, @block =\n        pattern, conv, short, long, arg, desc, block\n    end\n\n    #\n    # Parses +arg+ and returns rest of +arg+ and matched portion to the\n    # argument pattern. Yields when the pattern doesn't match substring.\n    #\n    def parse_arg(arg)\n      pattern or return nil, arg\n      unless m = pattern.match(arg)\n        yield(InvalidArgument, arg)\n        return arg, nil\n      end\n      if String === m\n        m = [s = m]\n      else\n        m = m.to_a\n        s = m[0]\n        return nil, m unless String === s\n      end\n      raise InvalidArgument, arg unless arg.rindex(s, 0)\n      return nil, m if s.length == arg.length\n      yield(InvalidArgument, arg) # didn't match whole arg\n      return arg[s.length..-1], m\n    end\n    private :parse_arg\n\n    #\n    # Parses argument, converts and returns +arg+, +block+ and result of\n    # conversion. Yields at semi-error condition instead of raising an\n    # exception.\n    #\n    def conv_arg(arg, val = nil)\n      if conv\n        val = conv.call(*val)\n      else\n        val = proc {|val| val}.call(*val)\n      end\n      return arg, block, val\n    end\n    private :conv_arg\n\n    #\n    # Produces the summary text. Each line of the summary is yielded to the\n    # block (without newline).\n    #\n    # +sdone+::  Already summarized short style options keyed hash.\n    # +ldone+::  Already summarized long style options keyed hash.\n    # +width+::  Width of left side (option part). In other words, the right\n    #            side (description part) starts after +width+ columns.\n    # +max+::    Maximum width of left side -> the options are filled within\n    #            +max+ columns.\n    # +indent+:: Prefix string indents all summarized lines.\n    #\n    def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = \"\")\n      sopts, lopts, s = [], [], nil\n      @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short\n      @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long\n      return if sopts.empty? and lopts.empty? # completely hidden\n\n      left = [sopts.join(', ')]\n      right = desc.dup\n\n      while s = lopts.shift\n        l = left[-1].length + s.length\n        l += arg.length if left.size == 1 && arg\n        l < max or sopts.empty? or left << ''\n        left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s\n      end\n\n      left[0] << arg if arg\n      mlen = left.collect {|s| s.length}.max.to_i\n      while mlen > width and l = left.shift\n        mlen = left.collect {|s| s.length}.max.to_i if l.length == mlen\n        yield(indent + l)\n      end\n\n      while begin l = left.shift; r = right.shift; l or r end\n        l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?\n        yield(indent + l)\n      end\n\n      self\n    end\n\n    def add_banner(to)  # :nodoc:\n      unless @short or @long\n        s = desc.join\n        to << \" [\" + s + \"]...\" unless s.empty?\n      end\n      to\n    end\n\n    def match_nonswitch?(str) # :nodoc:\n      @pattern =~ str unless @short or @long\n    end\n\n    #\n    # Main name of the switch.\n    #\n    def switch_name\n      (long.first || short.first).sub(/\\A-+(?:\\[no-\\])?/, '')\n    end\n\n    #\n    # Switch that takes no arguments.\n    #\n    class NoArgument < self\n\n      #\n      # Raises an exception if any arguments given.\n      #\n      def parse(arg, argv)\n        yield(NeedlessArgument, arg) if arg\n        conv_arg(arg)\n      end\n\n      def self.incompatible_argument_styles(*)\n      end\n\n      def self.pattern\n        Object\n      end\n    end\n\n    #\n    # Switch that takes an argument.\n    #\n    class RequiredArgument < self\n\n      #\n      # Raises an exception if argument is not present.\n      #\n      def parse(arg, argv)\n        unless arg\n          raise MissingArgument if argv.empty?\n          arg = argv.shift\n        end\n        conv_arg(*parse_arg(arg) {|*exc| raise(*exc)})\n      end\n    end\n\n    #\n    # Switch that can omit argument.\n    #\n    class OptionalArgument < self\n\n      #\n      # Parses argument if given, or uses default value.\n      #\n      def parse(arg, argv, &error)\n        if arg\n          conv_arg(*parse_arg(arg, &error))\n        else\n          conv_arg(arg)\n        end\n      end\n    end\n\n    #\n    # Switch that takes an argument, which does not begin with '-'.\n    #\n    class PlacedArgument < self\n\n      #\n      # Returns nil if argument is not present or begins with '-'.\n      #\n      def parse(arg, argv, &error)\n        if !(val = arg) and (argv.empty? or /\\A-/ =~ (val = argv[0]))\n          return nil, block, nil\n        end\n        opt = (val = parse_arg(val, &error))[1]\n        val = conv_arg(*val)\n        if opt and !arg\n          argv.shift\n        else\n          val[0] = nil\n        end\n        val\n      end\n    end\n  end\n\n  #\n  # Simple option list providing mapping from short and/or long option\n  # string to OptionParser::Switch and mapping from acceptable argument to\n  # matching pattern and converter pair. Also provides summary feature.\n  #\n  class List\n    # Map from acceptable argument types to pattern and converter pairs.\n    attr_reader :atype\n    \n    # Map from short style option switches to actual switch objects.\n    attr_reader :short\n    \n    # Map from long style option switches to actual switch objects.\n    attr_reader :long\n    \n    # List of all switches and summary string.\n    attr_reader :list\n\n    #\n    # Just initializes all instance variables.\n    #\n    def initialize\n      @atype = {}\n      @short = OptionMap.new\n      @long = OptionMap.new\n      @list = []\n    end\n\n    #\n    # See OptionParser.accept.\n    #\n    def accept(t, pat = /.*/nm, &block)\n      if pat\n        pat.respond_to?(:match) or raise TypeError, \"has no `match'\"\n      else\n        pat = t if t.respond_to?(:match)\n      end\n      unless block\n        block = pat.method(:convert).to_proc if pat.respond_to?(:convert)\n      end\n      @atype[t] = [pat, block]\n    end\n\n    #\n    # See OptionParser.reject.\n    #\n    def reject(t)\n      @atype.delete(t)\n    end\n\n    #\n    # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.\n    #\n    # +sw+::     OptionParser::Switch instance to be added.\n    # +sopts+::  Short style option list.\n    # +lopts+::  Long style option list.\n    # +nlopts+:: Negated long style options list.\n    #\n    def update(sw, sopts, lopts, nsw = nil, nlopts = nil)\n      o = nil\n      sopts.each {|o| @short[o] = sw} if sopts\n      lopts.each {|o| @long[o] = sw} if lopts\n      nlopts.each {|o| @long[o] = nsw} if nsw and nlopts\n      used = @short.invert.update(@long.invert)\n      @list.delete_if {|o| Switch === o and !used[o]}\n    end\n    private :update\n\n    #\n    # Inserts +switch+ at the head of the list, and associates short, long\n    # and negated long options. Arguments are:\n    # \n    # +switch+::      OptionParser::Switch instance to be inserted.\n    # +short_opts+::  List of short style options.\n    # +long_opts+::   List of long style options.\n    # +nolong_opts+:: List of long style options with \"no-\" prefix.\n    #\n    #   prepend(switch, short_opts, long_opts, nolong_opts)\n    #\n    def prepend(*args)\n      update(*args)\n      @list.unshift(args[0])\n    end\n\n    #\n    # Appends +switch+ at the tail of the list, and associates short, long\n    # and negated long options. Arguments are:\n    # \n    # +switch+::      OptionParser::Switch instance to be inserted.\n    # +short_opts+::  List of short style options.\n    # +long_opts+::   List of long style options.\n    # +nolong_opts+:: List of long style options with \"no-\" prefix.\n    #\n    #   append(switch, short_opts, long_opts, nolong_opts)\n    #\n    def append(*args)\n      update(*args)\n      @list.push(args[0])\n    end\n\n    #\n    # Searches +key+ in +id+ list. The result is returned or yielded if a\n    # block is given. If it isn't found, nil is returned.\n    #\n    def search(id, key)\n      if list = __send__(id)\n        val = list.fetch(key) {return nil}\n        block_given? ? yield(val) : val\n      end\n    end\n\n    #\n    # Searches list +id+ for +opt+ and the optional patterns for completion\n    # +pat+. If +icase+ is true, the search is case insensitive. The result\n    # is returned or yielded if a block is given. If it isn't found, nil is\n    # returned.\n    #\n    def complete(id, opt, icase = false, *pat, &block)\n      __send__(id).complete(opt, icase, *pat, &block)\n    end\n\n    #\n    # Iterates over each option, passing the option to the +block+.\n    #\n    def each_option(&block)\n      list.each(&block)\n    end\n\n    #\n    # Creates the summary table, passing each line to the +block+ (without\n    # newline). The arguments +args+ are passed along to the summarize\n    # method which is called on every option.\n    #\n    def summarize(*args, &block)\n      sum = []\n      list.reverse_each do |opt|\n        if opt.respond_to?(:summarize) # perhaps OptionParser::Switch\n          s = []\n          opt.summarize(*args) {|l| s << l}\n          sum.concat(s.reverse)\n        elsif !opt or opt.empty?\n          sum << \"\"\n        elsif opt.respond_to?(:each_line)\n          sum.concat([*opt.each_line].reverse)\n        else\n          sum.concat([*opt.each].reverse)\n        end\n      end\n      sum.reverse_each(&block)\n    end\n\n    def add_banner(to)  # :nodoc:\n      list.each do |opt|\n        if opt.respond_to?(:add_banner)\n          opt.add_banner(to)\n        end\n      end\n      to\n    end\n  end\n\n  #\n  # Hash with completion search feature. See OptionParser::Completion.\n  #\n  class CompletingHash < Hash\n    include Completion\n\n    #\n    # Completion for hash key.\n    #\n    def match(key)\n      return key, *fetch(key) {\n        raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}\n      }\n    end\n  end\n\n  # :stopdoc:\n\n  #\n  # Enumeration of acceptable argument styles. Possible values are:\n  #\n  # NO_ARGUMENT::       The switch takes no arguments. (:NONE)\n  # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)\n  # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)\n  #\n  # Use like --switch=argument (long style) or -Xargument (short style). For\n  # short style, only portion matched to argument pattern is dealed as\n  # argument.\n  #\n  ArgumentStyle = {}\n  NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}\n  RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}\n  OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}\n  ArgumentStyle.freeze\n\n  #\n  # Switches common used such as '--', and also provides default\n  # argument classes\n  #\n  DefaultList = List.new\n  DefaultList.short['-'] = Switch::NoArgument.new {}\n  DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}\n\n  #\n  # Default options for ARGV, which never appear in option summary.\n  #\n  Officious = {}\n\n  #\n  # --help\n  # Shows option summary.\n  #\n  Officious['help'] = proc do |parser|\n    Switch::NoArgument.new do\n      puts parser.help\n      exit\n    end\n  end\n\n  #\n  # --version\n  # Shows version string if Version is defined.\n  #\n  Officious['version'] = proc do |parser|\n    Switch::OptionalArgument.new do |pkg|\n      if pkg\n        begin\n          require 'optparse/version'\n        rescue LoadError\n        else\n          show_version(*pkg.split(/,/)) or\n            abort(\"#{parser.program_name}: no version found in package #{pkg}\")\n          exit\n        end\n      end\n      v = parser.ver or abort(\"#{parser.program_name}: version unknown\")\n      puts v\n      exit\n    end\n  end\n\n  # :startdoc:\n\n  #\n  # Class methods\n  #\n\n  #\n  # Initializes a new instance and evaluates the optional block in context\n  # of the instance. Arguments +args+ are passed to #new, see there for\n  # description of parameters.\n  # \n  # This method is *deprecated*, its behavior corresponds to the older #new\n  # method.\n  #\n  def self.with(*args, &block)\n    opts = new(*args)\n    opts.instance_eval(&block)\n    opts\n  end\n\n  #\n  # Returns an incremented value of +default+ according to +arg+.\n  #\n  def self.inc(arg, default = nil)\n    case arg\n    when Integer\n      arg.nonzero?\n    when nil\n      default.to_i + 1\n    end\n  end\n  def inc(*args)\n    self.class.inc(*args)\n  end\n\n  #\n  # Initializes the instance and yields itself if called with a block.\n  #\n  # +banner+:: Banner message.\n  # +width+::  Summary width.\n  # +indent+:: Summary indent.\n  #\n  def initialize(banner = nil, width = 32, indent = ' ' * 4)\n    @stack = [DefaultList, List.new, List.new]\n    @program_name = nil\n    @banner = banner\n    @summary_width = width\n    @summary_indent = indent\n    @default_argv = ARGV\n    add_officious\n    yield self if block_given?\n  end\n\n  def add_officious  # :nodoc:\n    list = base()\n    Officious.each do |opt, block|\n      list.long[opt] ||= block.call(self)\n    end\n  end\n\n  #\n  # Terminates option parsing. Optional parameter +arg+ is a string pushed\n  # back to be the first non-option argument.\n  #\n  def terminate(arg = nil)\n    self.class.terminate(arg)\n  end\n  def self.terminate(arg = nil)\n    throw :terminate, arg\n  end\n\n  @stack = [DefaultList]\n  def self.top() DefaultList end\n\n  #\n  # Directs to accept specified class +t+. The argument string is passed to\n  # the block in which it should be converted to the desired class.\n  #\n  # +t+::   Argument class specifier, any object including Class.\n  # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.\n  #\n  #   accept(t, pat, &block)\n  #\n  def accept(*args, &blk) top.accept(*args, &blk) end\n  #\n  # See #accept.\n  #\n  def self.accept(*args, &blk) top.accept(*args, &blk) end\n\n  #\n  # Directs to reject specified class argument.\n  #\n  # +t+:: Argument class specifier, any object including Class.\n  #\n  #   reject(t)\n  #\n  def reject(*args, &blk) top.reject(*args, &blk) end\n  #\n  # See #reject.\n  #\n  def self.reject(*args, &blk) top.reject(*args, &blk) end\n\n  #\n  # Instance methods\n  #\n\n  # Heading banner preceding summary.\n  attr_writer :banner\n\n  # Program name to be emitted in error message and default banner,\n  # defaults to $0.\n  attr_writer :program_name\n\n  # Width for option list portion of summary. Must be Numeric.\n  attr_accessor :summary_width\n\n  # Indentation for summary. Must be String (or have + String method).\n  attr_accessor :summary_indent\n\n  # Strings to be parsed in default.\n  attr_accessor :default_argv\n\n  #\n  # Heading banner preceding summary.\n  #\n  def banner\n    unless @banner\n      @banner = \"Usage: #{program_name} [options]\"\n      visit(:add_banner, @banner)\n    end\n    @banner\n  end\n\n  #\n  # Program name to be emitted in error message and default banner, defaults\n  # to $0.\n  #\n  def program_name\n    @program_name || File.basename($0, '.*')\n  end\n\n  # for experimental cascading :-)\n  alias set_banner banner=\n  alias set_program_name program_name=\n  alias set_summary_width summary_width=\n  alias set_summary_indent summary_indent=\n\n  # Version\n  attr_writer :version\n  # Release code\n  attr_writer :release\n\n  #\n  # Version\n  #\n  def version\n    @version || (defined?(::Version) && ::Version)\n  end\n\n  #\n  # Release code\n  #\n  def release\n    @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)\n  end\n\n  #\n  # Returns version string from program_name, version and release.\n  #\n  def ver\n    if v = version\n      str = \"#{program_name} #{[v].join('.')}\"\n      str << \" (#{v})\" if v = release\n      str\n    end\n  end\n\n  def warn(mesg = $!)\n    super(\"#{program_name}: #{mesg}\")\n  end\n\n  def abort(mesg = $!)\n    super(\"#{program_name}: #{mesg}\")\n  end\n\n  #\n  # Subject of #on / #on_head, #accept / #reject\n  #\n  def top\n    @stack[-1]\n  end\n\n  #\n  # Subject of #on_tail.\n  #\n  def base\n    @stack[1]\n  end\n\n  #\n  # Pushes a new List.\n  #\n  def new\n    @stack.push(List.new)\n    if block_given?\n      yield self\n    else\n      self\n    end\n  end\n\n  #\n  # Removes the last List.\n  #\n  def remove\n    @stack.pop\n  end\n\n  #\n  # Puts option summary into +to+ and returns +to+. Yields each line if\n  # a block is given.\n  #\n  # +to+:: Output destination, which must have method <<. Defaults to [].\n  # +width+:: Width of left side, defaults to @summary_width.\n  # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.\n  # +indent+:: Indentation, defaults to @summary_indent.\n  #\n  def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)\n    blk ||= proc {|l| to << (l.index($/, -1) ? l : l + $/)}\n    visit(:summarize, {}, {}, width, max, indent, &blk)\n    to\n  end\n\n  #\n  # Returns option summary string.\n  #\n  def help; summarize(banner.to_s.sub(/\\n?\\z/, \"\\n\")) end\n  alias to_s help\n\n  #\n  # Returns option summary list.\n  #\n  def to_a; summarize(banner.to_a.dup) end\n\n  #\n  # Checks if an argument is given twice, in which case an ArgumentError is\n  # raised. Called from OptionParser#switch only.\n  #\n  # +obj+:: New argument.\n  # +prv+:: Previously specified argument.\n  # +msg+:: Exception message.\n  #\n  def notwice(obj, prv, msg)\n    unless !prv or prv == obj\n      begin\n        raise ArgumentError, \"argument #{msg} given twice: #{obj}\"\n      rescue\n        $@[0, 2] = nil\n        raise\n      end\n    end\n    obj\n  end\n  private :notwice\n\n  #\n  # Creates an OptionParser::Switch from the parameters. The parsed argument\n  # value is passed to the given block, where it can be processed.\n  #\n  # See at the beginning of OptionParser for some full examples.\n  #\n  # +opts+ can include the following elements:\n  #\n  # [Argument style:]\n  #   One of the following:\n  #     :NONE, :REQUIRED, :OPTIONAL\n  #\n  # [Argument pattern:]\n  #   Acceptable option argument format, must be pre-defined with\n  #   OptionParser.accept or OptionParser#accept, or Regexp. This can appear\n  #   once or assigned as String if not present, otherwise causes an\n  #   ArgumentError. Examples:\n  #     Float, Time, Array\n  #\n  # [Possible argument values:]\n  #   Hash or Array.\n  #     [:text, :binary, :auto]\n  #     %w[iso-2022-jp shift_jis euc-jp utf8 binary]\n  #     { \"jis\" => \"iso-2022-jp\", \"sjis\" => \"shift_jis\" }\n  #\n  # [Long style switch:]\n  #   Specifies a long style switch which takes a mandatory, optional or no\n  #   argument. It's a string of the following form:\n  #     \"--switch=MANDATORY\" or \"--switch MANDATORY\"\n  #     \"--switch[=OPTIONAL]\"\n  #     \"--switch\"\n  #\n  # [Short style switch:]\n  #   Specifies short style switch which takes a mandatory, optional or no\n  #   argument. It's a string of the following form:\n  #     \"-xMANDATORY\"\n  #     \"-x[OPTIONAL]\"\n  #     \"-x\"\n  #   There is also a special form which matches character range (not full\n  #   set of regular expression):\n  #     \"-[a-z]MANDATORY\"\n  #     \"-[a-z][OPTIONAL]\" \n  #     \"-[a-z]\"\n  #\n  # [Argument style and description:]\n  #   Instead of specifying mandatory or optional arguments directly in the\n  #   switch parameter, this separate parameter can be used.\n  #     \"=MANDATORY\"\n  #     \"=[OPTIONAL]\"\n  #\n  # [Description:]\n  #   Description string for the option.\n  #     \"Run verbosely\"\n  # \n  # [Handler:]\n  #   Handler for the parsed argument value. Either give a block or pass a\n  #   Proc or Method as an argument.\n  #\n  def make_switch(opts, block = nil)\n    short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []\n    ldesc, sdesc, desc, arg = [], [], []\n    default_style = Switch::NoArgument\n    default_pattern = nil\n    klass = nil\n    o = nil\n    n, q, a = nil\n\n    opts.each do |o|\n      # argument class\n      next if search(:atype, o) do |pat, c|\n        klass = notwice(o, klass, 'type')\n        if not_style and not_style != Switch::NoArgument\n          not_pattern, not_conv = pat, c\n        else\n          default_pattern, conv = pat, c\n        end\n      end\n\n      # directly specified pattern(any object possible to match)\n      if !(String === o) and o.respond_to?(:match)\n        pattern = notwice(o, pattern, 'pattern')\n        conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)\n        next\n      end\n\n      # anything others\n      case o\n      when Proc, Method\n        block = notwice(o, block, 'block')\n      when Array, Hash\n        case pattern\n        when CompletingHash\n        when nil\n          pattern = CompletingHash.new\n          conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)\n        else\n          raise ArgumentError, \"argument pattern given twice\"\n        end\n        o.each {|(o, *v)| pattern[o] = v.fetch(0) {o}}\n      when Module\n        raise ArgumentError, \"unsupported argument type: #{o}\"\n      when *ArgumentStyle.keys\n        style = notwice(ArgumentStyle[o], style, 'style')\n      when /^--no-([^\\[\\]=\\s]*)(.+)?/\n        q, a = $1, $2\n        o = notwice(a ? Object : TrueClass, klass, 'type')\n        not_pattern, not_conv = search(:atype, o) unless not_style\n        not_style = (not_style || default_style).guess(arg = a) if a\n        default_style = Switch::NoArgument\n        default_pattern, conv = search(:atype, FalseClass) unless default_pattern\n        ldesc << \"--no-#{q}\"\n        long << 'no-' + (q = q.downcase)\n        nolong << q\n      when /^--\\[no-\\]([^\\[\\]=\\s]*)(.+)?/\n        q, a = $1, $2\n        o = notwice(a ? Object : TrueClass, klass, 'type')\n        if a\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        ldesc << \"--[no-]#{q}\"\n        long << (o = q.downcase)\n        not_pattern, not_conv = search(:atype, FalseClass) unless not_style\n        not_style = Switch::NoArgument\n        nolong << 'no-' + o\n      when /^--([^\\[\\]=\\s]*)(.+)?/\n        q, a = $1, $2\n        if a\n          o = notwice(NilClass, klass, 'type')\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        ldesc << \"--#{q}\"\n        long << (o = q.downcase)\n      when /^-(\\[\\^?\\]?(?:[^\\\\\\]]|\\\\.)*\\])(.+)?/\n        q, a = $1, $2\n        o = notwice(Object, klass, 'type')\n        if a\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        sdesc << \"-#{q}\"\n        short << Regexp.new(q)\n      when /^-(.)(.+)?/\n        q, a = $1, $2\n        if a\n          o = notwice(NilClass, klass, 'type')\n          default_style = default_style.guess(arg = a)\n          default_pattern, conv = search(:atype, o) unless default_pattern\n        end\n        sdesc << \"-#{q}\"\n        short << q\n      when /^=/\n        style = notwice(default_style.guess(arg = o), style, 'style')\n        default_pattern, conv = search(:atype, Object) unless default_pattern\n      else\n        desc.push(o)\n      end\n    end\n\n    default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern\n    if !(short.empty? and long.empty?)\n      s = (style || default_style).new(pattern || default_pattern,\n                                       conv, sdesc, ldesc, arg, desc, block)\n    elsif !block\n      raise ArgumentError, \"no switch given\" if style or pattern\n      s = desc\n    else\n      short << pattern\n      s = (style || default_style).new(pattern,\n                                       conv, nil, nil, arg, desc, block)\n    end\n    return s, short, long,\n      (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),\n      nolong\n  end\n\n  def define(*opts, &block)\n    top.append(*(sw = make_switch(opts, block)))\n    sw[0]\n  end\n\n  #\n  # Add option switch and handler. See #make_switch for an explanation of\n  # parameters.\n  #\n  def on(*opts, &block)\n    define(*opts, &block)\n    self\n  end\n  alias def_option define\n\n  def define_head(*opts, &block)\n    top.prepend(*(sw = make_switch(opts, block)))\n    sw[0]\n  end\n\n  #\n  # Add option switch like with #on, but at head of summary.\n  #\n  def on_head(*opts, &block)\n    define_head(*opts, &block)\n    self\n  end\n  alias def_head_option define_head\n\n  def define_tail(*opts, &block)\n    base.append(*(sw = make_switch(opts, block)))\n    sw[0]\n  end\n\n  #\n  # Add option switch like with #on, but at tail of summary.\n  #\n  def on_tail(*opts, &block)\n    define_tail(*opts, &block)\n    self\n  end\n  alias def_tail_option define_tail\n\n  #\n  # Add separator in summary.\n  #\n  def separator(string)\n    top.append(string, nil, nil)\n  end\n\n  #\n  # Parses command line arguments +argv+ in order. When a block is given,\n  # each non-option argument is yielded.\n  #\n  # Returns the rest of +argv+ left unparsed.\n  #\n  def order(*argv, &block)\n    argv = argv[0].dup if argv.size == 1 and Array === argv[0]\n    order!(argv, &block)\n  end\n\n  #\n  # Same as #order, but removes switches destructively.\n  #\n  def order!(argv = default_argv, &nonopt)\n    parse_in_order(argv, &nonopt)\n  end\n\n  def parse_in_order(argv = default_argv, setter = nil, &nonopt)  # :nodoc:\n    opt, arg, sw, val, rest = nil\n    nonopt ||= proc {|arg| throw :terminate, arg}\n    argv.unshift(arg) if arg = catch(:terminate) {\n      while arg = argv.shift\n        case arg\n        # long option\n        when /\\A--([^=]*)(?:=(.*))?/nm\n          opt, rest = $1, $2\n          begin\n            sw, = complete(:long, opt, true)\n          rescue ParseError\n            raise $!.set_option(arg, true)\n          end\n          begin\n            opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}\n            val = cb.call(val) if cb\n            setter.call(sw.switch_name, val) if setter\n          rescue ParseError\n            raise $!.set_option(arg, rest)\n          end\n\n        # short option\n        when /\\A-(.)((=).*|.+)?/nm\n          opt, has_arg, eq, val, rest = $1, $3, $3, $2, $2\n          begin\n            sw, = search(:short, opt)\n            unless sw\n              begin\n                sw, = complete(:short, opt)\n                # short option matched.\n                val = arg.sub(/\\A-/, '')\n                has_arg = true\n              rescue InvalidOption\n                # if no short options match, try completion with long\n                # options.\n                sw, = complete(:long, opt)\n                eq ||= !rest\n              end\n            end\n          rescue ParseError\n            raise $!.set_option(arg, true)\n          end\n          begin\n            opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}\n            raise InvalidOption, arg if has_arg and !eq and arg == \"-#{opt}\"\n            argv.unshift(opt) if opt and (opt = opt.sub(/\\A-*/, '-')) != '-'\n            val = cb.call(val) if cb\n            setter.call(sw.switch_name, val) if setter\n          rescue ParseError\n            raise $!.set_option(arg, arg.length > 2)\n          end\n\n        # non-option argument\n        else\n          catch(:prune) do\n            visit(:each_option) do |sw|\n              sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)\n            end\n            nonopt.call(arg)\n          end\n        end\n      end\n\n      nil\n    }\n\n    visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}\n\n    argv\n  end\n  private :parse_in_order\n\n  #\n  # Parses command line arguments +argv+ in permutation mode and returns\n  # list of non-option arguments.\n  #\n  def permute(*argv)\n    argv = argv[0].dup if argv.size == 1 and Array === argv[0]\n    permute!(argv)\n  end\n\n  #\n  # Same as #permute, but removes switches destructively.\n  #\n  def permute!(argv = default_argv)\n    nonopts = []\n    arg = nil\n    order!(argv) {|arg| nonopts << arg}\n    argv[0, 0] = nonopts\n    argv\n  end\n\n  #\n  # Parses command line arguments +argv+ in order when environment variable\n  # POSIXLY_CORRECT is set, and in permutation mode otherwise.\n  #\n  def parse(*argv)\n    argv = argv[0].dup if argv.size == 1 and Array === argv[0]\n    parse!(argv)\n  end\n\n  #\n  # Same as #parse, but removes switches destructively.\n  #\n  def parse!(argv = default_argv)\n    if ENV.include?('POSIXLY_CORRECT')\n      order!(argv)\n    else\n      permute!(argv)\n    end\n  end\n\n  #\n  # Wrapper method for getopts.rb.\n  #\n  #   params = ARGV.getopts(\"ab:\", \"foo\", \"bar:\")\n  #   # params[:a] = true   # -a\n  #   # params[:b] = \"1\"    # -b1\n  #   # params[:foo] = \"1\"  # --foo\n  #   # params[:bar] = \"x\"  # --bar x\n  #\n  def getopts(*args)\n    argv = Array === args.first ? args.shift : default_argv\n    single_options, *long_options = *args\n\n    result = {}\n\n    single_options.scan(/(.)(:)?/) do |opt, val|\n      if val\n        result[opt] = nil\n        define(\"-#{opt} VAL\")\n      else\n        result[opt] = false\n        define(\"-#{opt}\")\n      end\n    end if single_options\n\n    long_options.each do |arg|\n      opt, val = arg.split(':', 2)\n      if val\n        result[opt] = val.empty? ? nil : val\n        define(\"--#{opt} VAL\")\n      else\n        result[opt] = false\n        define(\"--#{opt}\")\n      end\n    end\n\n    parse_in_order(argv, result.method(:[]=))\n    result\n  end\n\n  #\n  # See #getopts.\n  #\n  def self.getopts(*args)\n    new.getopts(*args)\n  end\n\n  #\n  # Traverses @stack, sending each element method +id+ with +args+ and\n  # +block+.\n  #\n  def visit(id, *args, &block)\n    el = nil\n    @stack.reverse_each do |el|\n      el.send(id, *args, &block)\n    end\n    nil\n  end\n  private :visit\n\n  #\n  # Searches +key+ in @stack for +id+ hash and returns or yields the result.\n  #\n  def search(id, key)\n    block_given = block_given?\n    visit(:search, id, key) do |k|\n      return block_given ? yield(k) : k\n    end\n  end\n  private :search\n\n  #\n  # Completes shortened long style option switch and returns pair of\n  # canonical switch and switch descriptor OptionParser::Switch.\n  #\n  # +id+::    Searching table.\n  # +opt+::   Searching key.\n  # +icase+:: Search case insensitive if true.\n  # +pat+::   Optional pattern for completion.\n  #\n  def complete(typ, opt, icase = false, *pat)\n    if pat.empty?\n      search(typ, opt) {|sw| return [sw, opt]} # exact match or...\n    end\n    raise AmbiguousOption, catch(:ambiguous) {\n      visit(:complete, typ, opt, icase, *pat) {|opt, *sw| return sw}\n      raise InvalidOption, opt\n    }\n  end\n  private :complete\n\n  #\n  # Loads options from file names as +filename+. Does nothing when the file\n  # is not present. Returns whether successfully loaded.\n  #\n  # +filename+ defaults to basename of the program without suffix in a\n  # directory ~/.options.\n  #\n  def load(filename = nil)\n    begin\n      filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')\n    rescue\n      return false\n    end\n    begin\n      parse(*IO.readlines(filename).each {|s| s.chomp!})\n      true\n    rescue Errno::ENOENT, Errno::ENOTDIR\n      false\n    end\n  end\n\n  #\n  # Parses environment variable +env+ or its uppercase with splitting like a\n  # shell.\n  #\n  # +env+ defaults to the basename of the program.\n  #\n  def environment(env = File.basename($0, '.*'))\n    env = ENV[env] || ENV[env.upcase] or return\n    require 'shellwords'\n    parse(*Shellwords.shellwords(env))\n  end\n\n  #\n  # Acceptable argument classes\n  #\n\n  #\n  # Any string and no conversion. This is fall-back.\n  #\n  accept(Object) {|s,|s or s.nil?}\n\n  accept(NilClass) {|s,|s}\n\n  #\n  # Any non-empty string, and no conversion.\n  #\n  accept(String, /.+/nm) {|s,*|s}\n\n  #\n  # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal\n  # for 0x, and decimal for others; with optional sign prefix. Converts to\n  # Integer.\n  #\n  decimal = '\\d+(?:_\\d+)*'\n  binary = 'b[01]+(?:_[01]+)*'\n  hex = 'x[\\da-f]+(?:_[\\da-f]+)*'\n  octal = \"0(?:[0-7]*(?:_[0-7]+)*|#{binary}|#{hex})\"\n  integer = \"#{octal}|#{decimal}\"\n  accept(Integer, %r\"\\A[-+]?(?:#{integer})\"io) {|s,| Integer(s) if s}\n\n  #\n  # Float number format, and converts to Float.\n  #\n  float = \"(?:#{decimal}(?:\\\\.(?:#{decimal})?)?|\\\\.#{decimal})(?:E[-+]?#{decimal})?\"\n  floatpat = %r\"\\A[-+]?#{float}\"io\n  accept(Float, floatpat) {|s,| s.to_f if s}\n\n  #\n  # Generic numeric format, converts to Integer for integer format, Float\n  # for float format.\n  #\n  accept(Numeric, %r\"\\A[-+]?(?:#{octal}|#{float})\"io) {|s,| eval(s) if s}\n\n  #\n  # Decimal integer format, to be converted to Integer.\n  #\n  DecimalInteger = /\\A[-+]?#{decimal}/io\n  accept(DecimalInteger) {|s,| s.to_i if s}\n\n  #\n  # Ruby/C like octal/hexadecimal/binary integer format, to be converted to\n  # Integer.\n  #\n  OctalInteger = /\\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))/io\n  accept(OctalInteger) {|s,| s.oct if s}\n\n  #\n  # Decimal integer/float number format, to be converted to Integer for\n  # integer format, Float for float format.\n  #\n  DecimalNumeric = floatpat     # decimal integer is allowed as float also.\n  accept(DecimalNumeric) {|s,| eval(s) if s}\n\n  #\n  # Boolean switch, which means whether it is present or not, whether it is\n  # absent or not with prefix no-, or it takes an argument\n  # yes/no/true/false/+/-.\n  #\n  yesno = CompletingHash.new\n  %w[- no false].each {|el| yesno[el] = false}\n  %w[+ yes true].each {|el| yesno[el] = true}\n  yesno['nil'] = false          # shoud be nil?\n  accept(TrueClass, yesno) {|arg, val| val == nil or val}\n  #\n  # Similar to TrueClass, but defaults to false.\n  #\n  accept(FalseClass, yesno) {|arg, val| val != nil and val}\n\n  #\n  # List of strings separated by \",\".\n  #\n  accept(Array) do |s,|\n    if s\n      s = s.split(',').collect {|s| s unless s.empty?}\n    end\n    s\n  end\n\n  #\n  # Regular expression with options.\n  #\n  accept(Regexp, %r\"\\A/((?:\\\\.|[^\\\\])*)/([[:alpha:]]+)?\\z|.*\") do |all, s, o|\n    f = 0\n    if o\n      f |= Regexp::IGNORECASE if /i/ =~ o\n      f |= Regexp::MULTILINE if /m/ =~ o\n      f |= Regexp::EXTENDED if /x/ =~ o\n      k = o.delete(\"^imx\")\n    end\n    Regexp.new(s || all, f, k)\n  end\n\n  #\n  # Exceptions\n  #\n\n  #\n  # Base class of exceptions from OptionParser.\n  #\n  class ParseError < RuntimeError\n    # Reason which caused the error.\n    Reason = 'parse error'.freeze\n\n    def initialize(*args)\n      @args = args\n      @reason = nil\n    end\n\n    attr_reader :args\n    attr_writer :reason\n\n    #\n    # Pushes back erred argument(s) to +argv+.\n    #\n    def recover(argv)\n      argv[0, 0] = @args\n      argv\n    end\n\n    def set_option(opt, eq)\n      if eq\n        @args[0] = opt\n      else\n        @args.unshift(opt)\n      end\n      self\n    end\n\n    #\n    # Returns error reason. Override this for I18N.\n    #\n    def reason\n      @reason || self.class::Reason\n    end\n\n    def inspect\n      \"#<#{self.class.to_s}: #{args.join(' ')}>\"\n    end\n\n    #\n    # Default stringizing method to emit standard error message.\n    #\n    def message\n      reason + ': ' + args.join(' ')\n    end\n\n    alias to_s message\n  end\n\n  #\n  # Raises when ambiguously completable string is encountered.\n  #\n  class AmbiguousOption < ParseError\n    const_set(:Reason, 'ambiguous option'.freeze)\n  end\n\n  #\n  # Raises when there is an argument for a switch which takes no argument.\n  #\n  class NeedlessArgument < ParseError\n    const_set(:Reason, 'needless argument'.freeze)\n  end\n\n  #\n  # Raises when a switch with mandatory argument has no argument.\n  #\n  class MissingArgument < ParseError\n    const_set(:Reason, 'missing argument'.freeze)\n  end\n\n  #\n  # Raises when switch is undefined.\n  #\n  class InvalidOption < ParseError\n    const_set(:Reason, 'invalid option'.freeze)\n  end\n\n  #\n  # Raises when the given argument does not match required format.\n  #\n  class InvalidArgument < ParseError\n    const_set(:Reason, 'invalid argument'.freeze)\n  end\n\n  #\n  # Raises when the given argument word can't be completed uniquely.\n  #\n  class AmbiguousArgument < InvalidArgument\n    const_set(:Reason, 'ambiguous argument'.freeze)\n  end\n\n  #\n  # Miscellaneous\n  #\n\n  #\n  # Extends command line arguments array (ARGV) to parse itself.\n  #\n  module Arguable\n\n    #\n    # Sets OptionParser object, when +opt+ is +false+ or +nil+, methods\n    # OptionParser::Arguable#options and OptionParser::Arguable#options= are\n    # undefined. Thus, there is no ways to access the OptionParser object\n    # via the receiver object.\n    #\n    def options=(opt)\n      unless @optparse = opt\n        class << self\n          undef_method(:options)\n          undef_method(:options=)\n        end\n      end\n    end\n\n    #\n    # Actual OptionParser object, automatically created if nonexistent.\n    #\n    # If called with a block, yields the OptionParser object and returns the\n    # result of the block. If an OptionParser::ParseError exception occurs\n    # in the block, it is rescued, a error message printed to STDERR and\n    # +nil+ returned.\n    #\n    def options\n      @optparse ||= OptionParser.new\n      @optparse.default_argv = self\n      block_given? or return @optparse\n      begin\n        yield @optparse\n      rescue ParseError\n        @optparse.warn $!\n        nil\n      end\n    end\n\n    #\n    # Parses +self+ destructively in order and returns +self+ containing the\n    # rest arguments left unparsed.\n    #\n    def order!(&blk) options.order!(self, &blk) end\n\n    #\n    # Parses +self+ destructively in permutation mode and returns +self+\n    # containing the rest arguments left unparsed.\n    #\n    def permute!() options.permute!(self) end\n\n    #\n    # Parses +self+ destructively and returns +self+ containing the\n    # rest arguments left unparsed.\n    #\n    def parse!() options.parse!(self) end\n\n    #\n    # Substitution of getopts is possible as follows. Also see\n    # OptionParser#getopts.\n    #\n    #   def getopts(*args)\n    #     ($OPT = ARGV.getopts(*args)).each do |opt, val|\n    #       eval \"$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val\"\n    #     end\n    #   rescue OptionParser::ParseError\n    #   end\n    #\n    def getopts(*args)\n      options.getopts(self, *args)\n    end\n\n    #\n    # Initializes instance variable.\n    #\n    def self.extend_object(obj)\n      super\n      obj.instance_eval {@optparse = nil}\n    end\n    def initialize(*args)\n      super\n      @optparse = nil\n    end\n  end\n\n  #\n  # Acceptable argument classes. Now contains DecimalInteger, OctalInteger\n  # and DecimalNumeric. See Acceptable argument classes (in source code).\n  #\n  module Acceptables\n    const_set(:DecimalInteger, OptionParser::DecimalInteger)\n    const_set(:OctalInteger, OptionParser::OctalInteger)\n    const_set(:DecimalNumeric, OptionParser::DecimalNumeric)\n  end\nend\n\n# ARGV is arguable by OptionParser\nARGV.extend(OptionParser::Arguable)\n\nif $0 == __FILE__\n  Version = OptionParser::Version\n  ARGV.options {|q|\n    q.parse!.empty? or puts \"what's #{ARGV.join(' ')}?\"\n  } or abort(ARGV.options.to_s)\nend\n"
  },
  {
    "path": "lib/ostruct.rb",
    "content": "#\n# = ostruct.rb: OpenStruct implementation\n#\n# Author:: Yukihiro Matsumoto\n# Documentation:: Gavin Sinclair\n#\n# OpenStruct allows the creation of data objects with arbitrary attributes.\n# See OpenStruct for an example.\n#\n\n#\n# OpenStruct allows you to create data objects and set arbitrary attributes.\n# For example:\n#\n#   require 'ostruct' \n#\n#   record = OpenStruct.new\n#   record.name    = \"John Smith\"\n#   record.age     = 70\n#   record.pension = 300\n#   \n#   puts record.name     # -> \"John Smith\"\n#   puts record.address  # -> nil\n#\n# It is like a hash with a different way to access the data.  In fact, it is\n# implemented with a hash, and you can initialize it with one.\n#\n#   hash = { \"country\" => \"Australia\", :population => 20_000_000 }\n#   data = OpenStruct.new(hash)\n#\n#   p data        # -> <OpenStruct country=\"Australia\" population=20000000>\n#\nclass OpenStruct\n  #\n  # Create a new OpenStruct object.  The optional +hash+, if given, will\n  # generate attributes and values.  For example.\n  #\n  #   require 'ostruct'\n  #   hash = { \"country\" => \"Australia\", :population => 20_000_000 }\n  #   data = OpenStruct.new(hash)\n  #\n  #   p data        # -> <OpenStruct country=\"Australia\" population=20000000>\n  #\n  # By default, the resulting OpenStruct object will have no attributes. \n  #\n  def initialize(hash=nil)\n    @table = {}\n    if hash\n      for k,v in hash\n        @table[k.to_sym] = v\n        new_ostruct_member(k)\n      end\n    end\n  end\n\n  # Duplicate an OpenStruct object members. \n  def initialize_copy(orig)\n    super\n    @table = @table.dup\n  end\n\n  def marshal_dump\n    @table\n  end\n  def marshal_load(x)\n    @table = x\n    @table.each_key{|key| new_ostruct_member(key)}\n  end\n\n  def modifiable\n    if self.frozen?\n      raise TypeError, \"can't modify frozen #{self.class}\", caller(2)\n    end\n    @table\n  end\n  protected :modifiable\n\n  def new_ostruct_member(name)\n    name = name.to_sym\n    unless self.respond_to?(name)\n      class << self; self; end.class_eval do\n        define_method(name) { @table[name] }\n        define_method(\"#{name}=\") { |x| modifiable[name] = x }\n      end\n    end\n    name\n  end\n\n  def method_missing(mid, *args) # :nodoc:\n    mname = mid.id2name\n    len = args.length\n    if mname.chomp!('=')\n      if len != 1\n        raise ArgumentError, \"wrong number of arguments (#{len} for 1)\", caller(1)\n      end\n      modifiable[new_ostruct_member(mname)] = args[0]\n    elsif len == 0\n      @table[mid]\n    else\n      raise NoMethodError, \"undefined method `#{mname}' for #{self}\", caller(1)\n    end\n  end\n\n  #\n  # Remove the named field from the object.\n  #\n  def delete_field(name)\n    @table.delete name.to_sym\n  end\n\n  InspectKey = :__inspect_key__ # :nodoc:\n\n  #\n  # Returns a string containing a detailed summary of the keys and values.\n  #\n  def inspect\n    str = \"#<#{self.class}\"\n\n    ids = (Thread.current[InspectKey] ||= [])\n    if ids.include?(object_id)\n      return str << ' ...>'\n    end\n\n    ids << object_id\n    begin\n      first = true\n      for k,v in @table\n        str << \",\" unless first\n        first = false\n        str << \" #{k}=#{v.inspect}\"\n      end\n      return str << '>'\n    ensure\n      ids.pop\n    end\n  end\n  alias :to_s :inspect\n\n  attr_reader :table # :nodoc:\n  protected :table\n\n  #\n  # Compare this object and +other+ for equality.\n  #\n  def ==(other)\n    return false unless(other.kind_of?(OpenStruct))\n    return @table == other.table\n  end\nend\n"
  },
  {
    "path": "lib/parsearg.rb",
    "content": "#\n#\t\tparsearg.rb - parse arguments\n#\t\t\t$Release Version: $\n#\t\t\t$Revision$\n#\t\t\t$Date$\n#\t\t\tby Yasuo OHBA(SHL Japan Inc. Technology Dept.)\n#\n# --\n#\n#\t\n#\n\nwarn \"Warning:#{caller[0].sub(/:in `.*'\\z/, '')}: parsearg is deprecated after Ruby 1.8.1; use optparse instead\"\n\n$RCS_ID=%q$Header$\n\nrequire \"getopts\"\n\ndef printUsageAndExit()\n  if $USAGE\n    eval($USAGE)\n  end\n  exit()\nend\n\ndef setParenthesis(ex, opt, c)\n  if opt != \"\"\n    ex = sprintf(\"%s$OPT_%s%s\", ex, opt, c)\n  else\n    ex = sprintf(\"%s%s\", ex, c)\n  end\n  return ex\nend\n\ndef setOrAnd(ex, opt, c)\n  if opt != \"\"\n    ex = sprintf(\"%s$OPT_%s %s%s \", ex, opt, c, c)\n  else\n    ex = sprintf(\"%s %s%s \", ex, c, c)\n  end\n  return ex\nend\n\ndef setExpression(ex, opt, op)\n  if !op\n    ex = sprintf(\"%s$OPT_%s\", ex, opt)\n    return ex\n  end\n  case op.chr\n  when \"(\", \")\"\n    ex = setParenthesis(ex, opt, op.chr)\n  when \"|\", \"&\"\n    ex = setOrAnd(ex, opt, op.chr)\n  else\n    return nil\n  end\n  return ex\nend\n\n# parseArgs is obsolete.  Use OptionParser instead.\n\ndef parseArgs(argc, nopt, single_opts, *opts)\n  if (noOptions = getopts(single_opts, *opts)) == nil\n    printUsageAndExit()\n  end\n  if nopt\n    ex = nil\n    pos = 0\n    for o in nopt.split(/[()|&]/)\n      pos += o.length\n      ex = setExpression(ex, o, nopt[pos])\n      pos += 1\n    end\n    begin\n      if !eval(ex)\n\tprintUsageAndExit()\n      end\n    rescue\n      print \"Format Error!! : \\\"\" + nopt + \"\\\"\\t[parseArgs]\\n\"\n      exit!(-1)\n    end\n  end\n  if ARGV.length < argc\n    printUsageAndExit()\n  end\n  return noOptions\nend\n"
  },
  {
    "path": "lib/parsedate.rb",
    "content": "#\n# = parsedate.rb: Parses dates\n#\n# Author:: Tadayoshi Funaba\n# Documentation:: Konrad Meyer\n#\n# ParseDate munches on a date and turns it into an array of values.\n#\n\n#\n# ParseDate converts a date into an array of values.\n# For example:\n#\n#   require 'parsedate'\n#\n#   ParseDate.parsedate \"Tuesday, July 6th, 2007, 18:35:20 UTC\"\n#   # => [2007, 7, 6, 18, 35, 20, \"UTC\", 2]\n#\n# The order is of the form [year, month, day of month, hour, minute, second,\n# timezone, day of the week].\n\nrequire 'date/format'\n\nmodule ParseDate\n  #\n  # Parse a string representation of a date into values.\n  # For example:\n  #\n  #   require 'parsedate'\n  #\n  #   ParseDate.parsedate \"Tuesday, July 5th, 2007, 18:35:20 UTC\"\n  #   # => [2007, 7, 5, 18, 35, 20, \"UTC\", 2]\n  #\n  # The order is of the form [year, month, day of month, hour, minute,\n  # second, timezone, day of week].\n  #\n  # ParseDate.parsedate can also take a second argument, +comp+, which\n  # is a boolean telling the method to compensate for dates with years\n  # expressed as two digits. Example:\n  #\n  #   require 'parsedate'\n  #\n  #   ParseDate.parsedate \"Mon Dec 25 00 06:53:24 UTC\", true\n  #   # => [2000, 12, 25, 6, 53, 24, \"UTC\", 1]\n  #\n  def parsedate(str, comp=false)\n    Date._parse(str, comp).\n      values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday)\n  end\n\n  module_function :parsedate\n\nend\n"
  },
  {
    "path": "lib/pathname.rb",
    "content": "#\n# = pathname.rb\n#\n# Object-Oriented Pathname Class\n#\n# Author:: Tanaka Akira <akr@m17n.org>\n# Documentation:: Author and Gavin Sinclair\n#\n# For documentation, see class Pathname.\n#\n# <tt>pathname.rb</tt> is distributed with Ruby since 1.8.0.\n#\n\n#\n# == Pathname\n#\n# Pathname represents a pathname which locates a file in a filesystem.\n# The pathname depends on OS: Unix, Windows, etc.\n# Pathname library works with pathnames of local OS.\n# However non-Unix pathnames are supported experimentally.\n#\n# It does not represent the file itself.\n# A Pathname can be relative or absolute.  It's not until you try to\n# reference the file that it even matters whether the file exists or not.\n#\n# Pathname is immutable.  It has no method for destructive update.\n#\n# The value of this class is to manipulate file path information in a neater\n# way than standard Ruby provides.  The examples below demonstrate the\n# difference.  *All* functionality from File, FileTest, and some from Dir and\n# FileUtils is included, in an unsurprising way.  It is essentially a facade for\n# all of these, and more.\n#\n# == Examples\n#\n# === Example 1: Using Pathname\n#\n#   require 'pathname'\n#   p = Pathname.new(\"/usr/bin/ruby\")\n#   size = p.size              # 27662\n#   isdir = p.directory?       # false\n#   dir  = p.dirname           # Pathname:/usr/bin\n#   base = p.basename          # Pathname:ruby\n#   dir, base = p.split        # [Pathname:/usr/bin, Pathname:ruby]\n#   data = p.read\n#   p.open { |f| _ } \n#   p.each_line { |line| _ }\n#\n# === Example 2: Using standard Ruby\n#\n#   p = \"/usr/bin/ruby\"\n#   size = File.size(p)        # 27662\n#   isdir = File.directory?(p) # false\n#   dir  = File.dirname(p)     # \"/usr/bin\"\n#   base = File.basename(p)    # \"ruby\"\n#   dir, base = File.split(p)  # [\"/usr/bin\", \"ruby\"]\n#   data = File.read(p)\n#   File.open(p) { |f| _ } \n#   File.foreach(p) { |line| _ }\n#\n# === Example 3: Special features\n#\n#   p1 = Pathname.new(\"/usr/lib\")   # Pathname:/usr/lib\n#   p2 = p1 + \"ruby/1.8\"            # Pathname:/usr/lib/ruby/1.8\n#   p3 = p1.parent                  # Pathname:/usr\n#   p4 = p2.relative_path_from(p3)  # Pathname:lib/ruby/1.8\n#   pwd = Pathname.pwd              # Pathname:/home/gavin\n#   pwd.absolute?                   # true\n#   p5 = Pathname.new \".\"           # Pathname:.\n#   p5 = p5 + \"music/../articles\"   # Pathname:music/../articles\n#   p5.cleanpath                    # Pathname:articles\n#   p5.realpath                     # Pathname:/home/gavin/articles\n#   p5.children                     # [Pathname:/home/gavin/articles/linux, ...]\n# \n# == Breakdown of functionality\n#\n# === Core methods\n#\n# These methods are effectively manipulating a String, because that's all a path\n# is.  Except for #mountpoint?, #children, and #realpath, they don't access the\n# filesystem.\n#\n# - +\n# - #join\n# - #parent\n# - #root?\n# - #absolute?\n# - #relative?\n# - #relative_path_from\n# - #each_filename\n# - #cleanpath\n# - #realpath\n# - #children\n# - #mountpoint?\n#\n# === File status predicate methods\n#\n# These methods are a facade for FileTest:\n# - #blockdev?\n# - #chardev?\n# - #directory?\n# - #executable?\n# - #executable_real?\n# - #exist?\n# - #file?\n# - #grpowned?\n# - #owned?\n# - #pipe?\n# - #readable?\n# - #world_readable?\n# - #readable_real?\n# - #setgid?\n# - #setuid?\n# - #size\n# - #size?\n# - #socket?\n# - #sticky?\n# - #symlink?\n# - #writable?\n# - #world_writable?\n# - #writable_real?\n# - #zero?\n#\n# === File property and manipulation methods\n#\n# These methods are a facade for File:\n# - #atime\n# - #ctime\n# - #mtime\n# - #chmod(mode)\n# - #lchmod(mode)\n# - #chown(owner, group)\n# - #lchown(owner, group)\n# - #fnmatch(pattern, *args)\n# - #fnmatch?(pattern, *args)\n# - #ftype\n# - #make_link(old)\n# - #open(*args, &block)\n# - #readlink\n# - #rename(to)\n# - #stat\n# - #lstat\n# - #make_symlink(old)\n# - #truncate(length)\n# - #utime(atime, mtime)\n# - #basename(*args)\n# - #dirname\n# - #extname\n# - #expand_path(*args)\n# - #split\n#\n# === Directory methods\n#\n# These methods are a facade for Dir:\n# - Pathname.glob(*args)\n# - Pathname.getwd / Pathname.pwd\n# - #rmdir\n# - #entries\n# - #each_entry(&block)\n# - #mkdir(*args)\n# - #opendir(*args)\n#\n# === IO\n#\n# These methods are a facade for IO:\n# - #each_line(*args, &block)\n# - #read(*args)\n# - #readlines(*args)\n# - #sysopen(*args)\n#\n# === Utilities\n#\n# These methods are a mixture of Find, FileUtils, and others:\n# - #find(&block)\n# - #mkpath\n# - #rmtree\n# - #unlink / #delete\n#\n#\n# == Method documentation\n#\n# As the above section shows, most of the methods in Pathname are facades.  The\n# documentation for these methods generally just says, for instance, \"See\n# FileTest.writable?\", as you should be familiar with the original method\n# anyway, and its documentation (e.g. through +ri+) will contain more\n# information.  In some cases, a brief description will follow.\n#\nclass Pathname\n\n  # :stopdoc:\n  if RUBY_VERSION < \"1.9\"\n    TO_PATH = :to_str\n  else\n    # to_path is implemented so Pathname objects are usable with File.open, etc.\n    TO_PATH = :to_path\n  end\n  # :startdoc:\n\n  #\n  # Create a Pathname object from the given String (or String-like object).\n  # If +path+ contains a NUL character (<tt>\\0</tt>), an ArgumentError is raised.\n  #\n  def initialize(path)\n    path = path.__send__(TO_PATH) if path.respond_to? TO_PATH\n    @path = path.dup\n\n    if /\\0/ =~ @path\n      raise ArgumentError, \"pathname contains \\\\0: #{@path.inspect}\"\n    end\n\n    self.taint if @path.tainted?\n  end\n\n  def freeze() super; @path.freeze; self end\n  def taint() super; @path.taint; self end\n  def untaint() super; @path.untaint; self end\n\n  #\n  # Compare this pathname with +other+.  The comparison is string-based.\n  # Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>)\n  # can refer to the same file.\n  #\n  def ==(other)\n    return false unless Pathname === other\n    other.to_s == @path\n  end\n  alias === ==\n  alias eql? ==\n\n  # Provides for comparing pathnames, case-sensitively.\n  def <=>(other)\n    return nil unless Pathname === other\n    @path.tr('/', \"\\0\") <=> other.to_s.tr('/', \"\\0\")\n  end\n\n  def hash # :nodoc:\n    @path.hash\n  end\n\n  # Return the path as a String.\n  def to_s\n    @path.dup\n  end\n\n  # to_path is implemented so Pathname objects are usable with File.open, etc.\n  alias_method TO_PATH, :to_s\n\n  def inspect # :nodoc:\n    \"#<#{self.class}:#{@path}>\"\n  end\n\n  # Return a pathname which is substituted by String#sub.\n  def sub(pattern, *rest, &block)\n    if block\n      path = @path.sub(pattern, *rest) {|*args|\n        begin\n          old = Thread.current[:pathname_sub_matchdata]\n          Thread.current[:pathname_sub_matchdata] = $~\n          eval(\"$~ = Thread.current[:pathname_sub_matchdata]\", block.binding)\n        ensure\n          Thread.current[:pathname_sub_matchdata] = old\n        end\n        yield *args\n      }\n    else\n      path = @path.sub(pattern, *rest)\n    end\n    self.class.new(path)\n  end\n\n  if File::ALT_SEPARATOR\n    SEPARATOR_PAT = /[#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}]/\n  else\n    SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/\n  end\n\n  # chop_basename(path) -> [pre-basename, basename] or nil\n  def chop_basename(path)\n    base = File.basename(path)\n    if /\\A#{SEPARATOR_PAT}?\\z/ =~ base\n      return nil\n    else\n      return path[0, path.rindex(base)], base\n    end\n  end\n  private :chop_basename\n\n  # split_names(path) -> prefix, [name, ...]\n  def split_names(path)\n    names = []\n    while r = chop_basename(path)\n      path, basename = r\n      names.unshift basename\n    end\n    return path, names\n  end\n  private :split_names\n\n  def prepend_prefix(prefix, relpath)\n    if relpath.empty?\n      File.dirname(prefix)\n    elsif /#{SEPARATOR_PAT}/ =~ prefix\n      prefix = File.dirname(prefix)\n      prefix = File.join(prefix, \"\") if File.basename(prefix + 'a') != 'a'\n      prefix + relpath\n    else\n      prefix + relpath\n    end\n  end\n  private :prepend_prefix\n\n  # Returns clean pathname of +self+ with consecutive slashes and useless dots\n  # removed.  The filesystem is not accessed.\n  #\n  # If +consider_symlink+ is +true+, then a more conservative algorithm is used\n  # to avoid breaking symbolic linkages.  This may retain more <tt>..</tt>\n  # entries than absolutely necessary, but without accessing the filesystem,\n  # this can't be avoided.  See #realpath.\n  #\n  def cleanpath(consider_symlink=false)\n    if consider_symlink\n      cleanpath_conservative\n    else\n      cleanpath_aggressive\n    end\n  end\n\n  #\n  # Clean the path simply by resolving and removing excess \".\" and \"..\" entries.\n  # Nothing more, nothing less.\n  #\n  def cleanpath_aggressive\n    path = @path\n    names = []\n    pre = path\n    while r = chop_basename(pre)\n      pre, base = r\n      case base\n      when '.'\n      when '..'\n        names.unshift base\n      else\n        if names[0] == '..'\n          names.shift\n        else\n          names.unshift base\n        end\n      end\n    end\n    if /#{SEPARATOR_PAT}/o =~ File.basename(pre)\n      names.shift while names[0] == '..'\n    end\n    self.class.new(prepend_prefix(pre, File.join(*names)))\n  end\n  private :cleanpath_aggressive\n\n  # has_trailing_separator?(path) -> bool\n  def has_trailing_separator?(path)\n    if r = chop_basename(path)\n      pre, basename = r\n      pre.length + basename.length < path.length\n    else\n      false\n    end\n  end\n  private :has_trailing_separator?\n\n  # add_trailing_separator(path) -> path\n  def add_trailing_separator(path)\n    if File.basename(path + 'a') == 'a'\n      path\n    else\n      File.join(path, \"\") # xxx: Is File.join is appropriate to add separator?\n    end\n  end\n  private :add_trailing_separator\n\n  def del_trailing_separator(path)\n    if r = chop_basename(path)\n      pre, basename = r\n      pre + basename\n    elsif /#{SEPARATOR_PAT}+\\z/o =~ path\n      $` + File.dirname(path)[/#{SEPARATOR_PAT}*\\z/o]\n    else\n      path\n    end\n  end\n  private :del_trailing_separator\n\n  def cleanpath_conservative\n    path = @path\n    names = []\n    pre = path\n    while r = chop_basename(pre)\n      pre, base = r\n      names.unshift base if base != '.'\n    end\n    if /#{SEPARATOR_PAT}/o =~ File.basename(pre)\n      names.shift while names[0] == '..'\n    end\n    if names.empty?\n      self.class.new(File.dirname(pre))\n    else\n      if names.last != '..' && File.basename(path) == '.'\n        names << '.'\n      end\n      result = prepend_prefix(pre, File.join(*names))\n      if /\\A(?:\\.|\\.\\.)\\z/ !~ names.last && has_trailing_separator?(path)\n        self.class.new(add_trailing_separator(result))\n      else\n        self.class.new(result)\n      end\n    end\n  end\n  private :cleanpath_conservative\n\n  def realpath_rec(prefix, unresolved, h)\n    resolved = []\n    until unresolved.empty?\n      n = unresolved.shift\n      if n == '.'\n        next\n      elsif n == '..'\n        resolved.pop\n      else\n        path = prepend_prefix(prefix, File.join(*(resolved + [n])))\n        if h.include? path\n          if h[path] == :resolving\n            raise Errno::ELOOP.new(path)\n          else\n            prefix, *resolved = h[path]\n          end\n        else\n          s = File.lstat(path)\n          if s.symlink?\n            h[path] = :resolving\n            link_prefix, link_names = split_names(File.readlink(path))\n            if link_prefix == ''\n              prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h)\n            else\n              prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h)\n            end\n          else\n            resolved << n\n            h[path] = [prefix, *resolved]\n          end\n        end\n      end\n    end\n    return prefix, *resolved\n  end\n  private :realpath_rec\n\n  #\n  # Returns a real (absolute) pathname of +self+ in the actual filesystem.\n  # The real pathname doesn't contain symlinks or useless dots.\n  #\n  # No arguments should be given; the old behaviour is *obsoleted*. \n  #\n  def realpath\n    path = @path\n    prefix, names = split_names(path)\n    if prefix == ''\n      prefix, names2 = split_names(Dir.pwd)\n      names = names2 + names\n    end\n    prefix, *names = realpath_rec(prefix, names, {})\n    self.class.new(prepend_prefix(prefix, File.join(*names)))\n  end\n\n  # #parent returns the parent directory.\n  #\n  # This is same as <tt>self + '..'</tt>.\n  def parent\n    self + '..'\n  end\n\n  # #mountpoint? returns +true+ if <tt>self</tt> points to a mountpoint.\n  def mountpoint?\n    begin\n      stat1 = self.lstat\n      stat2 = self.parent.lstat\n      stat1.dev == stat2.dev && stat1.ino == stat2.ino ||\n        stat1.dev != stat2.dev\n    rescue Errno::ENOENT\n      false\n    end\n  end\n\n  #\n  # #root? is a predicate for root directories.  I.e. it returns +true+ if the\n  # pathname consists of consecutive slashes.\n  #\n  # It doesn't access actual filesystem.  So it may return +false+ for some\n  # pathnames which points to roots such as <tt>/usr/..</tt>.\n  #\n  def root?\n    !!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)\n  end\n\n  # Predicate method for testing whether a path is absolute.\n  # It returns +true+ if the pathname begins with a slash.\n  def absolute?\n    !relative?\n  end\n\n  # The opposite of #absolute?\n  def relative?\n    path = @path\n    while r = chop_basename(path)\n      path, basename = r\n    end\n    path == ''\n  end\n\n  #\n  # Iterates over each component of the path.\n  #\n  #   Pathname.new(\"/usr/bin/ruby\").each_filename {|filename| ... }\n  #     # yields \"usr\", \"bin\", and \"ruby\".\n  #\n  def each_filename # :yield: filename\n    prefix, names = split_names(@path)\n    names.each {|filename| yield filename }\n    nil\n  end\n\n  # Iterates over and yields a new Pathname object\n  # for each element in the given path in descending order.\n  #\n  #  Pathname.new('/path/to/some/file.rb').descend {|v| p v}\n  #     #<Pathname:/>\n  #     #<Pathname:/path>\n  #     #<Pathname:/path/to>\n  #     #<Pathname:/path/to/some>\n  #     #<Pathname:/path/to/some/file.rb>\n  #\n  #  Pathname.new('path/to/some/file.rb').descend {|v| p v}\n  #     #<Pathname:path>\n  #     #<Pathname:path/to>\n  #     #<Pathname:path/to/some>\n  #     #<Pathname:path/to/some/file.rb>\n  #\n  # It doesn't access actual filesystem.\n  #\n  # This method is available since 1.8.5.\n  #\n  def descend\n    vs = []\n    ascend {|v| vs << v }\n    vs.reverse_each {|v| yield v }\n    nil\n  end\n\n  # Iterates over and yields a new Pathname object\n  # for each element in the given path in ascending order.\n  #\n  #  Pathname.new('/path/to/some/file.rb').ascend {|v| p v}\n  #     #<Pathname:/path/to/some/file.rb>\n  #     #<Pathname:/path/to/some>\n  #     #<Pathname:/path/to>\n  #     #<Pathname:/path>\n  #     #<Pathname:/>\n  #\n  #  Pathname.new('path/to/some/file.rb').ascend {|v| p v}\n  #     #<Pathname:path/to/some/file.rb>\n  #     #<Pathname:path/to/some>\n  #     #<Pathname:path/to>\n  #     #<Pathname:path>\n  #\n  # It doesn't access actual filesystem.\n  #\n  # This method is available since 1.8.5.\n  #\n  def ascend\n    path = @path\n    yield self\n    while r = chop_basename(path)\n      path, name = r\n      break if path.empty?\n      yield self.class.new(del_trailing_separator(path))\n    end\n  end\n\n  #\n  # Pathname#+ appends a pathname fragment to this one to produce a new Pathname\n  # object.\n  #\n  #   p1 = Pathname.new(\"/usr\")      # Pathname:/usr\n  #   p2 = p1 + \"bin/ruby\"           # Pathname:/usr/bin/ruby\n  #   p3 = p1 + \"/etc/passwd\"        # Pathname:/etc/passwd\n  #\n  # This method doesn't access the file system; it is pure string manipulation. \n  #\n  def +(other)\n    other = Pathname.new(other) unless Pathname === other\n    Pathname.new(plus(@path, other.to_s))\n  end\n\n  def plus(path1, path2) # -> path\n    prefix2 = path2\n    index_list2 = []\n    basename_list2 = []\n    while r2 = chop_basename(prefix2)\n      prefix2, basename2 = r2\n      index_list2.unshift prefix2.length\n      basename_list2.unshift basename2\n    end\n    return path2 if prefix2 != ''\n    prefix1 = path1\n    while true\n      while !basename_list2.empty? && basename_list2.first == '.'\n        index_list2.shift\n        basename_list2.shift\n      end\n      break unless r1 = chop_basename(prefix1)\n      prefix1, basename1 = r1\n      next if basename1 == '.'\n      if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..'\n        prefix1 = prefix1 + basename1\n        break\n      end\n      index_list2.shift\n      basename_list2.shift\n    end\n    r1 = chop_basename(prefix1)\n    if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)\n      while !basename_list2.empty? && basename_list2.first == '..'\n        index_list2.shift\n        basename_list2.shift\n      end\n    end\n    if !basename_list2.empty?\n      suffix2 = path2[index_list2.first..-1]\n      r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2\n    else\n      r1 ? prefix1 : File.dirname(prefix1)\n    end\n  end\n  private :plus\n\n  #\n  # Pathname#join joins pathnames.\n  #\n  # <tt>path0.join(path1, ..., pathN)</tt> is the same as\n  # <tt>path0 + path1 + ... + pathN</tt>.\n  #\n  def join(*args)\n    args.unshift self\n    result = args.pop\n    result = Pathname.new(result) unless Pathname === result\n    return result if result.absolute?\n    args.reverse_each {|arg|\n      arg = Pathname.new(arg) unless Pathname === arg\n      result = arg + result\n      return result if result.absolute?\n    }\n    result\n  end\n\n  #\n  # Returns the children of the directory (files and subdirectories, not\n  # recursive) as an array of Pathname objects.  By default, the returned\n  # pathnames will have enough information to access the files.  If you set\n  # +with_directory+ to +false+, then the returned pathnames will contain the\n  # filename only.\n  #\n  # For example:\n  #   p = Pathname(\"/usr/lib/ruby/1.8\")\n  #   p.children\n  #       # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,\n  #              Pathname:/usr/lib/ruby/1.8/Env.rb,\n  #              Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]\n  #   p.children(false)\n  #       # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]\n  #\n  # Note that the result never contain the entries <tt>.</tt> and <tt>..</tt> in\n  # the directory because they are not children.\n  #\n  # This method has existed since 1.8.1.\n  #\n  def children(with_directory=true)\n    with_directory = false if @path == '.'\n    result = []\n    Dir.foreach(@path) {|e|\n      next if e == '.' || e == '..'\n      if with_directory\n        result << self.class.new(File.join(@path, e))\n      else\n        result << self.class.new(e)\n      end\n    }\n    result\n  end\n\n  #\n  # #relative_path_from returns a relative path from the argument to the\n  # receiver.  If +self+ is absolute, the argument must be absolute too.  If\n  # +self+ is relative, the argument must be relative too.\n  #\n  # #relative_path_from doesn't access the filesystem.  It assumes no symlinks.\n  #\n  # ArgumentError is raised when it cannot find a relative path.\n  #\n  # This method has existed since 1.8.1.\n  #\n  def relative_path_from(base_directory)\n    dest_directory = self.cleanpath.to_s\n    base_directory = base_directory.cleanpath.to_s\n    dest_prefix = dest_directory\n    dest_names = []\n    while r = chop_basename(dest_prefix)\n      dest_prefix, basename = r\n      dest_names.unshift basename if basename != '.'\n    end\n    base_prefix = base_directory\n    base_names = []\n    while r = chop_basename(base_prefix)\n      base_prefix, basename = r\n      base_names.unshift basename if basename != '.'\n    end\n    if dest_prefix != base_prefix\n      raise ArgumentError, \"different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}\"\n    end\n    while !dest_names.empty? &&\n          !base_names.empty? &&\n          dest_names.first == base_names.first\n      dest_names.shift\n      base_names.shift\n    end\n    if base_names.include? '..'\n      raise ArgumentError, \"base_directory has ..: #{base_directory.inspect}\"\n    end\n    base_names.fill('..')\n    relpath_names = base_names + dest_names\n    if relpath_names.empty?\n      Pathname.new('.')\n    else\n      Pathname.new(File.join(*relpath_names))\n    end\n  end\nend\n\nclass Pathname    # * IO *\n  #\n  # #each_line iterates over the line in the file.  It yields a String object\n  # for each line.\n  #\n  # This method has existed since 1.8.1.\n  #\n  def each_line(*args, &block) # :yield: line\n    IO.foreach(@path, *args, &block)\n  end\n\n  # Pathname#foreachline is *obsoleted* at 1.8.1.  Use #each_line.\n  def foreachline(*args, &block)\n    warn \"Pathname#foreachline is obsoleted.  Use Pathname#each_line.\"\n    each_line(*args, &block)\n  end\n\n  # See <tt>IO.read</tt>.  Returns all the bytes from the file, or the first +N+\n  # if specified.\n  def read(*args) IO.read(@path, *args) end\n\n  # See <tt>IO.readlines</tt>.  Returns all the lines from the file.\n  def readlines(*args) IO.readlines(@path, *args) end\n\n  # See <tt>IO.sysopen</tt>.\n  def sysopen(*args) IO.sysopen(@path, *args) end\nend\n\n\nclass Pathname    # * File *\n\n  # See <tt>File.atime</tt>.  Returns last access time.\n  def atime() File.atime(@path) end\n\n  # See <tt>File.ctime</tt>.  Returns last (directory entry, not file) change time.\n  def ctime() File.ctime(@path) end\n\n  # See <tt>File.mtime</tt>.  Returns last modification time.\n  def mtime() File.mtime(@path) end\n\n  # See <tt>File.chmod</tt>.  Changes permissions.\n  def chmod(mode) File.chmod(mode, @path) end\n\n  # See <tt>File.lchmod</tt>.\n  def lchmod(mode) File.lchmod(mode, @path) end\n\n  # See <tt>File.chown</tt>.  Change owner and group of file.\n  def chown(owner, group) File.chown(owner, group, @path) end\n\n  # See <tt>File.lchown</tt>.\n  def lchown(owner, group) File.lchown(owner, group, @path) end\n\n  # See <tt>File.fnmatch</tt>.  Return +true+ if the receiver matches the given\n  # pattern.\n  def fnmatch(pattern, *args) File.fnmatch(pattern, @path, *args) end\n\n  # See <tt>File.fnmatch?</tt> (same as #fnmatch).\n  def fnmatch?(pattern, *args) File.fnmatch?(pattern, @path, *args) end\n\n  # See <tt>File.ftype</tt>.  Returns \"type\" of file (\"file\", \"directory\",\n  # etc).\n  def ftype() File.ftype(@path) end\n\n  # See <tt>File.link</tt>.  Creates a hard link.\n  def make_link(old) File.link(old, @path) end\n\n  # See <tt>File.open</tt>.  Opens the file for reading or writing.\n  def open(*args, &block) # :yield: file\n    File.open(@path, *args, &block)\n  end\n\n  # See <tt>File.readlink</tt>.  Read symbolic link.\n  def readlink() self.class.new(File.readlink(@path)) end\n\n  # See <tt>File.rename</tt>.  Rename the file.\n  def rename(to) File.rename(@path, to) end\n\n  # See <tt>File.stat</tt>.  Returns a <tt>File::Stat</tt> object.\n  def stat() File.stat(@path) end\n\n  # See <tt>File.lstat</tt>.\n  def lstat() File.lstat(@path) end\n\n  # See <tt>File.symlink</tt>.  Creates a symbolic link.\n  def make_symlink(old) File.symlink(old, @path) end\n\n  # See <tt>File.truncate</tt>.  Truncate the file to +length+ bytes.\n  def truncate(length) File.truncate(@path, length) end\n\n  # See <tt>File.utime</tt>.  Update the access and modification times.\n  def utime(atime, mtime) File.utime(atime, mtime, @path) end\n\n  # See <tt>File.basename</tt>.  Returns the last component of the path.\n  def basename(*args) self.class.new(File.basename(@path, *args)) end\n\n  # See <tt>File.dirname</tt>.  Returns all but the last component of the path.\n  def dirname() self.class.new(File.dirname(@path)) end\n\n  # See <tt>File.extname</tt>.  Returns the file's extension.\n  def extname() File.extname(@path) end\n\n  # See <tt>File.expand_path</tt>.\n  def expand_path(*args) self.class.new(File.expand_path(@path, *args)) end\n\n  # See <tt>File.split</tt>.  Returns the #dirname and the #basename in an\n  # Array.\n  def split() File.split(@path).map {|f| self.class.new(f) } end\n\n  # Pathname#link is confusing and *obsoleted* because the receiver/argument\n  # order is inverted to corresponding system call.\n  def link(old)\n    warn 'Pathname#link is obsoleted.  Use Pathname#make_link.'\n    File.link(old, @path)\n  end\n\n  # Pathname#symlink is confusing and *obsoleted* because the receiver/argument\n  # order is inverted to corresponding system call.\n  def symlink(old)\n    warn 'Pathname#symlink is obsoleted.  Use Pathname#make_symlink.'\n    File.symlink(old, @path)\n  end\nend\n\n\nclass Pathname    # * FileTest *\n\n  # See <tt>FileTest.blockdev?</tt>.\n  def blockdev?() FileTest.blockdev?(@path) end\n\n  # See <tt>FileTest.chardev?</tt>.\n  def chardev?() FileTest.chardev?(@path) end\n\n  # See <tt>FileTest.executable?</tt>.\n  def executable?() FileTest.executable?(@path) end\n\n  # See <tt>FileTest.executable_real?</tt>.\n  def executable_real?() FileTest.executable_real?(@path) end\n\n  # See <tt>FileTest.exist?</tt>.\n  def exist?() FileTest.exist?(@path) end\n\n  # See <tt>FileTest.grpowned?</tt>.\n  def grpowned?() FileTest.grpowned?(@path) end\n\n  # See <tt>FileTest.directory?</tt>.\n  def directory?() FileTest.directory?(@path) end\n\n  # See <tt>FileTest.file?</tt>.\n  def file?() FileTest.file?(@path) end\n\n  # See <tt>FileTest.pipe?</tt>.\n  def pipe?() FileTest.pipe?(@path) end\n\n  # See <tt>FileTest.socket?</tt>.\n  def socket?() FileTest.socket?(@path) end\n\n  # See <tt>FileTest.owned?</tt>.\n  def owned?() FileTest.owned?(@path) end\n\n  # See <tt>FileTest.readable?</tt>.\n  def readable?() FileTest.readable?(@path) end\n\n  # See <tt>FileTest.world_readable?</tt>.\n  def world_readable?() FileTest.world_readable?(@path) end\n\n  # See <tt>FileTest.readable_real?</tt>.\n  def readable_real?() FileTest.readable_real?(@path) end\n\n  # See <tt>FileTest.setuid?</tt>.\n  def setuid?() FileTest.setuid?(@path) end\n\n  # See <tt>FileTest.setgid?</tt>.\n  def setgid?() FileTest.setgid?(@path) end\n\n  # See <tt>FileTest.size</tt>.\n  def size() FileTest.size(@path) end\n\n  # See <tt>FileTest.size?</tt>.\n  def size?() FileTest.size?(@path) end\n\n  # See <tt>FileTest.sticky?</tt>.\n  def sticky?() FileTest.sticky?(@path) end\n\n  # See <tt>FileTest.symlink?</tt>.\n  def symlink?() FileTest.symlink?(@path) end\n\n  # See <tt>FileTest.writable?</tt>.\n  def writable?() FileTest.writable?(@path) end\n\n  # See <tt>FileTest.world_writable?</tt>.\n  def world_writable?() FileTest.world_writable?(@path) end\n\n  # See <tt>FileTest.writable_real?</tt>.\n  def writable_real?() FileTest.writable_real?(@path) end\n\n  # See <tt>FileTest.zero?</tt>.\n  def zero?() FileTest.zero?(@path) end\nend\n\n\nclass Pathname    # * Dir *\n  # See <tt>Dir.glob</tt>.  Returns or yields Pathname objects.\n  def Pathname.glob(*args) # :yield: p\n    if block_given?\n      Dir.glob(*args) {|f| yield self.new(f) }\n    else\n      Dir.glob(*args).map {|f| self.new(f) }\n    end\n  end\n\n  # See <tt>Dir.getwd</tt>.  Returns the current working directory as a Pathname.\n  def Pathname.getwd() self.new(Dir.getwd) end\n  class << self; alias pwd getwd end\n\n  # Pathname#chdir is *obsoleted* at 1.8.1.\n  def chdir(&block)\n    warn \"Pathname#chdir is obsoleted.  Use Dir.chdir.\"\n    Dir.chdir(@path, &block)\n  end\n\n  # Pathname#chroot is *obsoleted* at 1.8.1.\n  def chroot\n    warn \"Pathname#chroot is obsoleted.  Use Dir.chroot.\"\n    Dir.chroot(@path)\n  end\n\n  # Return the entries (files and subdirectories) in the directory, each as a\n  # Pathname object.\n  def entries() Dir.entries(@path).map {|f| self.class.new(f) } end\n\n  # Iterates over the entries (files and subdirectories) in the directory.  It\n  # yields a Pathname object for each entry.\n  #\n  # This method has existed since 1.8.1.\n  def each_entry(&block) # :yield: p\n    Dir.foreach(@path) {|f| yield self.class.new(f) }\n  end\n\n  # Pathname#dir_foreach is *obsoleted* at 1.8.1.\n  def dir_foreach(*args, &block)\n    warn \"Pathname#dir_foreach is obsoleted.  Use Pathname#each_entry.\"\n    each_entry(*args, &block)\n  end\n\n  # See <tt>Dir.mkdir</tt>.  Create the referenced directory.\n  def mkdir(*args) Dir.mkdir(@path, *args) end\n\n  # See <tt>Dir.rmdir</tt>.  Remove the referenced directory.\n  def rmdir() Dir.rmdir(@path) end\n\n  # See <tt>Dir.open</tt>.\n  def opendir(&block) # :yield: dir\n    Dir.open(@path, &block)\n  end\nend\n\n\nclass Pathname    # * Find *\n  #\n  # Pathname#find is an iterator to traverse a directory tree in a depth first\n  # manner.  It yields a Pathname for each file under \"this\" directory.\n  #\n  # Since it is implemented by <tt>find.rb</tt>, <tt>Find.prune</tt> can be used\n  # to control the traverse.\n  #\n  # If +self+ is <tt>.</tt>, yielded pathnames begin with a filename in the\n  # current directory, not <tt>./</tt>.\n  #\n  def find(&block) # :yield: p\n    require 'find'\n    if @path == '.'\n      Find.find(@path) {|f| yield self.class.new(f.sub(%r{\\A\\./}, '')) }\n    else\n      Find.find(@path) {|f| yield self.class.new(f) }\n    end\n  end\nend\n\n\nclass Pathname    # * FileUtils *\n  # See <tt>FileUtils.mkpath</tt>.  Creates a full path, including any\n  # intermediate directories that don't yet exist.\n  def mkpath\n    require 'fileutils'\n    FileUtils.mkpath(@path)\n    nil\n  end\n\n  # See <tt>FileUtils.rm_r</tt>.  Deletes a directory and all beneath it.\n  def rmtree\n    # The name \"rmtree\" is borrowed from File::Path of Perl.\n    # File::Path provides \"mkpath\" and \"rmtree\".\n    require 'fileutils'\n    FileUtils.rm_r(@path)\n    nil\n  end\nend\n\n\nclass Pathname    # * mixed *\n  # Removes a file or directory, using <tt>File.unlink</tt> or\n  # <tt>Dir.unlink</tt> as necessary.\n  def unlink()\n    begin\n      Dir.unlink @path\n    rescue Errno::ENOTDIR\n      File.unlink @path\n    end\n  end\n  alias delete unlink\n\n  # This method is *obsoleted* at 1.8.1.  Use #each_line or #each_entry.\n  def foreach(*args, &block)\n    warn \"Pathname#foreach is obsoleted.  Use each_line or each_entry.\"\n    if FileTest.directory? @path\n      # For polymorphism between Dir.foreach and IO.foreach,\n      # Pathname#foreach doesn't yield Pathname object.\n      Dir.foreach(@path, *args, &block)\n    else\n      IO.foreach(@path, *args, &block)\n    end\n  end\nend\n\nmodule Kernel\n  # create a pathname object.\n  #\n  # This method is available since 1.8.5.\n  def Pathname(path) # :doc:\n    Pathname.new(path)\n  end\n  private :Pathname\nend\n"
  },
  {
    "path": "lib/ping.rb",
    "content": "#\n# = ping.rb: Check a host for upness\n#\n# Author:: Yukihiro Matsumoto\n# Documentation:: Konrad Meyer\n# \n# Performs the function of the basic network testing tool, ping.\n# See: Ping.\n#\n\nrequire 'timeout'\nrequire \"socket\"\n\n# \n# Ping contains routines to test for the reachability of remote hosts.\n# Currently the only routine implemented is pingecho().\n#\n# Ping.pingecho uses a TCP echo (not an ICMP echo) to determine if the\n# remote host is reachable. This is usually adequate to tell that a remote\n# host is available to telnet, ftp, or ssh to.\n#\n# Warning: Ping.pingecho may block for a long time if DNS resolution is\n# slow. Requiring 'resolv-replace' allows non-blocking name resolution.\n#\n# Usage:\n# \n#   require 'ping'\n#\n#   puts \"'jimmy' is alive and kicking\" if Ping.pingecho('jimmy', 10)\n#\nmodule Ping\n\n  # \n  # Return true if we can open a connection to the hostname or IP address\n  # +host+ on port +service+ (which defaults to the \"echo\" port) waiting up\n  # to +timeout+ seconds.\n  #\n  # Example:\n  #\n  #   require 'ping'\n  #\n  #   Ping.pingecho \"google.com\", 10, 80\n  #\n  def pingecho(host, timeout=5, service=\"echo\")\n    begin\n      timeout(timeout) do\n\ts = TCPSocket.new(host, service)\n\ts.close\n      end\n    rescue Errno::ECONNREFUSED\n      return true\n    rescue Timeout::Error, StandardError\n      return false\n    end\n    return true\n  end\n  module_function :pingecho\nend\n\nif $0 == __FILE__\n  host = ARGV[0]\n  host ||= \"localhost\"\n  printf(\"%s alive? - %s\\n\", host,  Ping::pingecho(host, 5))\nend\n"
  },
  {
    "path": "lib/pp.rb",
    "content": "# == Pretty-printer for Ruby objects.\n# \n# = Which seems better?\n# \n# non-pretty-printed output by #p is:\n#   #<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline=\"\\n\", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>\n# \n# pretty-printed output by #pp is:\n#   #<PP:0x81fedf0\n#    @buffer=[],\n#    @buffer_width=0,\n#    @genspace=#<Proc:0x81feda0>,\n#    @group_queue=\n#     #<PrettyPrint::GroupQueue:0x81fed3c\n#      @queue=\n#       [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],\n#        []]>,\n#    @group_stack=\n#     [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],\n#    @indent=0,\n#    @maxwidth=79,\n#    @newline=\"\\n\",\n#    @output=#<IO:0x8114ee4>,\n#    @output_width=2>\n# \n# I like the latter.  If you do too, this library is for you.\n# \n# = Usage\n# \n#   pp(obj)\n#\n# output +obj+ to +$>+ in pretty printed format.\n# \n# It returns +nil+.\n# \n# = Output Customization\n# To define your customized pretty printing function for your classes,\n# redefine a method #pretty_print(+pp+) in the class.\n# It takes an argument +pp+ which is an instance of the class PP.\n# The method should use PP#text, PP#breakable, PP#nest, PP#group and\n# PP#pp to print the object.\n#\n# = Author\n# Tanaka Akira <akr@m17n.org>\n\nrequire 'prettyprint'\n\nmodule Kernel\n  # returns a pretty printed object as a string.\n  def pretty_inspect\n    PP.pp(self, '')\n  end\n\n  private\n  # prints arguments in pretty form.\n  #\n  # pp returns nil.\n  def pp(*objs) # :doc:\n    objs.each {|obj|\n      PP.pp(obj)\n    }\n    nil\n  end\n  module_function :pp\nend\n\nclass PP < PrettyPrint\n  # Outputs +obj+ to +out+ in pretty printed format of\n  # +width+ columns in width.\n  # \n  # If +out+ is omitted, +$>+ is assumed.\n  # If +width+ is omitted, 79 is assumed.\n  # \n  # PP.pp returns +out+.\n  def PP.pp(obj, out=$>, width=79)\n    q = PP.new(out, width)\n    q.guard_inspect_key {q.pp obj}\n    q.flush\n    #$pp = q\n    out << \"\\n\"\n  end\n\n  # Outputs +obj+ to +out+ like PP.pp but with no indent and\n  # newline.\n  # \n  # PP.singleline_pp returns +out+.\n  def PP.singleline_pp(obj, out=$>)\n    q = SingleLine.new(out)\n    q.guard_inspect_key {q.pp obj}\n    q.flush\n    out\n  end\n\n  # :stopdoc:\n  def PP.mcall(obj, mod, meth, *args, &block)\n    mod.instance_method(meth).bind(obj).call(*args, &block)\n  end\n  # :startdoc:\n\n  @sharing_detection = false\n  class << self\n    # Returns the sharing detection flag as a boolean value.\n    # It is false by default.\n    attr_accessor :sharing_detection\n  end\n\n  module PPMethods\n    InspectKey = :__inspect_key__\n\n    def guard_inspect_key\n      if Thread.current[InspectKey] == nil\n        Thread.current[InspectKey] = []\n      end\n\n      save = Thread.current[InspectKey]\n\n      begin\n        Thread.current[InspectKey] = []\n        yield\n      ensure\n        Thread.current[InspectKey] = save\n      end\n    end\n\n    # Adds +obj+ to the pretty printing buffer\n    # using Object#pretty_print or Object#pretty_print_cycle.\n    # \n    # Object#pretty_print_cycle is used when +obj+ is already\n    # printed, a.k.a the object reference chain has a cycle.\n    def pp(obj)\n      id = obj.__id__\n\n      if Thread.current[InspectKey].include? id\n        group {obj.pretty_print_cycle self}\n        return\n      end\n\n      begin\n        Thread.current[InspectKey] << id\n        group {obj.pretty_print self}\n      ensure\n        Thread.current[InspectKey].pop unless PP.sharing_detection\n      end\n    end\n\n    # A convenience method which is same as follows:\n    # \n    #   group(1, '#<' + obj.class.name, '>') { ... }\n    def object_group(obj, &block) # :yield:\n      group(1, '#<' + obj.class.name, '>', &block)\n    end\n\n    def object_address_group(obj, &block)\n      id = \"%x\" % (obj.__id__ * 2)\n      id.sub!(/\\Af(?=[[:xdigit:]]{2}+\\z)/, '') if id.sub!(/\\A\\.\\./, '')\n      group(1, \"\\#<#{obj.class}:0x#{id}\", '>', &block)\n    end\n\n    # A convenience method which is same as follows:\n    # \n    #   text ','\n    #   breakable\n    def comma_breakable\n      text ','\n      breakable\n    end\n\n    # Adds a separated list.\n    # The list is separated by comma with breakable space, by default.\n    # \n    # #seplist iterates the +list+ using +iter_method+.\n    # It yields each object to the block given for #seplist.\n    # The procedure +separator_proc+ is called between each yields.\n    # \n    # If the iteration is zero times, +separator_proc+ is not called at all.\n    # \n    # If +separator_proc+ is nil or not given,\n    # +lambda { comma_breakable }+ is used.\n    # If +iter_method+ is not given, :each is used.\n    # \n    # For example, following 3 code fragments has similar effect.\n    # \n    #   q.seplist([1,2,3]) {|v| xxx v }\n    # \n    #   q.seplist([1,2,3], lambda { comma_breakable }, :each) {|v| xxx v }\n    # \n    #   xxx 1\n    #   q.comma_breakable\n    #   xxx 2\n    #   q.comma_breakable\n    #   xxx 3\n    def seplist(list, sep=nil, iter_method=:each) # :yield: element\n      sep ||= lambda { comma_breakable }\n      first = true\n      list.__send__(iter_method) {|*v|\n        if first\n          first = false\n        else\n          sep.call\n        end\n        yield(*v)\n      }\n    end\n\n    def pp_object(obj)\n      object_address_group(obj) {\n        seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v|\n          breakable\n          v = v.to_s if Symbol === v\n          text v\n          text '='\n          group(1) {\n            breakable ''\n            pp(obj.instance_eval(v))\n          }\n        }\n      }\n    end\n\n    def pp_hash(obj)\n      group(1, '{', '}') {\n        seplist(obj, nil, :each_pair) {|k, v|\n          group {\n            pp k\n            text '=>'\n            group(1) {\n              breakable ''\n              pp v\n            }\n          }\n        }\n      }\n    end\n  end\n\n  include PPMethods\n\n  class SingleLine < PrettyPrint::SingleLine\n    include PPMethods\n  end\n\n  module ObjectMixin\n    # 1. specific pretty_print\n    # 2. specific inspect\n    # 3. specific to_s if instance variable is empty\n    # 4. generic pretty_print\n\n    # A default pretty printing method for general objects.\n    # It calls #pretty_print_instance_variables to list instance variables.\n    # \n    # If +self+ has a customized (redefined) #inspect method,\n    # the result of self.inspect is used but it obviously has no\n    # line break hints.\n    # \n    # This module provides predefined #pretty_print methods for some of\n    # the most commonly used built-in classes for convenience.\n    def pretty_print(q)\n      if /\\(Kernel\\)#/ !~ Object.instance_method(:method).bind(self).call(:inspect).inspect\n        q.text self.inspect\n      elsif /\\(Kernel\\)#/ !~ Object.instance_method(:method).bind(self).call(:to_s).inspect && instance_variables.empty?\n        q.text self.to_s\n      else\n        q.pp_object(self)\n      end\n    end\n\n    # A default pretty printing method for general objects that are\n    # detected as part of a cycle.\n    def pretty_print_cycle(q)\n      q.object_address_group(self) {\n        q.breakable\n        q.text '...'\n      }\n    end\n\n    # Returns a sorted array of instance variable names.\n    # \n    # This method should return an array of names of instance variables as symbols or strings as:\n    # +[:@a, :@b]+.\n    def pretty_print_instance_variables\n      instance_variables.sort\n    end\n\n    # Is #inspect implementation using #pretty_print.\n    # If you implement #pretty_print, it can be used as follows.\n    # \n    #   alias inspect pretty_print_inspect\n    #\n    # However, doing this requires that every class that #inspect is called on\n    # implement #pretty_print, or a RuntimeError will be raised.\n    def pretty_print_inspect\n      if /\\(PP::ObjectMixin\\)#/ =~ Object.instance_method(:method).bind(self).call(:pretty_print).inspect\n        raise \"pretty_print is not overridden for #{self.class}\"\n      end\n      PP.singleline_pp(self, '')\n    end\n  end\nend\n\nclass Array\n  def pretty_print(q)\n    q.group(1, '[', ']') {\n      q.seplist(self) {|v|\n        q.pp v\n      }\n    }\n  end\n\n  def pretty_print_cycle(q)\n    q.text(empty? ? '[]' : '[...]')\n  end\nend\n\nclass Hash\n  def pretty_print(q)\n    q.pp_hash self\n  end\n\n  def pretty_print_cycle(q)\n    q.text(empty? ? '{}' : '{...}')\n  end\nend\n\nclass << ENV\n  def pretty_print(q)\n    q.pp_hash self\n  end\nend\n\nclass Struct\n  def pretty_print(q)\n    q.group(1, '#<struct ' + PP.mcall(self, Kernel, :class).name, '>') {\n      q.seplist(PP.mcall(self, Struct, :members), lambda { q.text \",\" }) {|member|\n        q.breakable\n        q.text member.to_s\n        q.text '='\n        q.group(1) {\n          q.breakable ''\n          q.pp self[member]\n        }\n      }\n    }\n  end\n\n  def pretty_print_cycle(q)\n    q.text sprintf(\"#<struct %s:...>\", PP.mcall(self, Kernel, :class).name)\n  end\nend\n\nclass Range\n  def pretty_print(q)\n    q.pp self.begin\n    q.breakable ''\n    q.text(self.exclude_end? ? '...' : '..')\n    q.breakable ''\n    q.pp self.end\n  end\nend\n\nclass File\n  class Stat\n    def pretty_print(q)\n      require 'etc.so'\n      q.object_group(self) {\n        q.breakable\n        q.text sprintf(\"dev=0x%x\", self.dev); q.comma_breakable\n        q.text \"ino=\"; q.pp self.ino; q.comma_breakable\n        q.group {\n          m = self.mode\n          q.text sprintf(\"mode=0%o\", m)\n          q.breakable\n          q.text sprintf(\"(%s %c%c%c%c%c%c%c%c%c)\",\n            self.ftype,\n            (m & 0400 == 0 ? ?- : ?r),\n            (m & 0200 == 0 ? ?- : ?w),\n            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :\n                             (m & 04000 == 0 ? ?x : ?s)),\n            (m & 0040 == 0 ? ?- : ?r),\n            (m & 0020 == 0 ? ?- : ?w),\n            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :\n                             (m & 02000 == 0 ? ?x : ?s)),\n            (m & 0004 == 0 ? ?- : ?r),\n            (m & 0002 == 0 ? ?- : ?w),\n            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :\n                             (m & 01000 == 0 ? ?x : ?t)))\n        }\n        q.comma_breakable\n        q.text \"nlink=\"; q.pp self.nlink; q.comma_breakable\n        q.group {\n          q.text \"uid=\"; q.pp self.uid\n          begin\n            pw = Etc.getpwuid(self.uid)\n          rescue ArgumentError\n          end\n          if pw\n            q.breakable; q.text \"(#{pw.name})\"\n          end\n        }\n        q.comma_breakable\n        q.group {\n          q.text \"gid=\"; q.pp self.gid\n          begin\n            gr = Etc.getgrgid(self.gid)\n          rescue ArgumentError\n          end\n          if gr\n            q.breakable; q.text \"(#{gr.name})\"\n          end\n        }\n        q.comma_breakable\n        q.group {\n          q.text sprintf(\"rdev=0x%x\", self.rdev)\n          q.breakable\n          q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor)\n        }\n        q.comma_breakable\n        q.text \"size=\"; q.pp self.size; q.comma_breakable\n        q.text \"blksize=\"; q.pp self.blksize; q.comma_breakable\n        q.text \"blocks=\"; q.pp self.blocks; q.comma_breakable\n        q.group {\n          t = self.atime\n          q.text \"atime=\"; q.pp t\n          q.breakable; q.text \"(#{t.tv_sec})\"\n        }\n        q.comma_breakable\n        q.group {\n          t = self.mtime\n          q.text \"mtime=\"; q.pp t\n          q.breakable; q.text \"(#{t.tv_sec})\"\n        }\n        q.comma_breakable\n        q.group {\n          t = self.ctime\n          q.text \"ctime=\"; q.pp t\n          q.breakable; q.text \"(#{t.tv_sec})\"\n        }\n      }\n    end\n  end\nend\n\nclass MatchData\n  def pretty_print(q)\n    q.object_group(self) {\n      q.breakable\n      q.seplist(1..self.size, lambda { q.breakable }) {|i|\n        q.pp self[i-1]\n      }\n    }\n  end\nend\n\nclass Object\n  include PP::ObjectMixin\nend\n\n[Numeric, Symbol, FalseClass, TrueClass, NilClass, Module].each {|c|\n  c.class_eval {\n    def pretty_print_cycle(q)\n      q.text inspect\n    end\n  }\n}\n\n[Numeric, FalseClass, TrueClass, Module].each {|c|\n  c.class_eval {\n    def pretty_print(q)\n      q.text inspect\n    end\n  }\n}\n\n# :enddoc:\nif __FILE__ == $0\n  require 'test/unit'\n\n  class PPTest < Test::Unit::TestCase\n    def test_list0123_12\n      assert_equal(\"[0, 1, 2, 3]\\n\", PP.pp([0,1,2,3], '', 12))\n    end\n\n    def test_list0123_11\n      assert_equal(\"[0,\\n 1,\\n 2,\\n 3]\\n\", PP.pp([0,1,2,3], '', 11))\n    end\n\n    OverriddenStruct = Struct.new(\"OverriddenStruct\", :members, :class)\n    def test_struct_override_members # [ruby-core:7865]\n      a = OverriddenStruct.new(1,2)\n      assert_equal(\"#<struct Struct::OverriddenStruct members=1, class=2>\\n\", PP.pp(a, ''))\n    end\n\n    def test_redefined_method\n      o = \"\"\n      def o.method\n      end\n      assert_equal(%(\"\"\\n), PP.pp(o, \"\"))\n    end\n  end\n\n  class HasInspect\n    def initialize(a)\n      @a = a\n    end\n\n    def inspect\n      return \"<inspect:#{@a.inspect}>\"\n    end\n  end\n\n  class HasPrettyPrint\n    def initialize(a)\n      @a = a\n    end\n\n    def pretty_print(q)\n      q.text \"<pretty_print:\"\n      q.pp @a\n      q.text \">\"\n    end\n  end\n\n  class HasBoth\n    def initialize(a)\n      @a = a\n    end\n\n    def inspect\n      return \"<inspect:#{@a.inspect}>\"\n    end\n\n    def pretty_print(q)\n      q.text \"<pretty_print:\"\n      q.pp @a\n      q.text \">\"\n    end\n  end\n\n  class PrettyPrintInspect < HasPrettyPrint\n    alias inspect pretty_print_inspect\n  end\n\n  class PrettyPrintInspectWithoutPrettyPrint\n    alias inspect pretty_print_inspect\n  end\n\n  class PPInspectTest < Test::Unit::TestCase\n    def test_hasinspect\n      a = HasInspect.new(1)\n      assert_equal(\"<inspect:1>\\n\", PP.pp(a, ''))\n    end\n\n    def test_hasprettyprint\n      a = HasPrettyPrint.new(1)\n      assert_equal(\"<pretty_print:1>\\n\", PP.pp(a, ''))\n    end\n\n    def test_hasboth\n      a = HasBoth.new(1)\n      assert_equal(\"<pretty_print:1>\\n\", PP.pp(a, ''))\n    end\n\n    def test_pretty_print_inspect\n      a = PrettyPrintInspect.new(1)\n      assert_equal(\"<pretty_print:1>\", a.inspect)\n      a = PrettyPrintInspectWithoutPrettyPrint.new\n      assert_raise(RuntimeError) { a.inspect }\n    end\n\n    def test_proc\n      a = proc {1}\n      assert_equal(\"#{a.inspect}\\n\", PP.pp(a, ''))\n    end\n\n    def test_to_s_with_iv\n      a = Object.new\n      def a.to_s() \"aaa\" end\n      a.instance_eval { @a = nil }\n      result = PP.pp(a, '')\n      assert_equal(\"#{a.inspect}\\n\", result)\n      assert_match(/\\A#<Object.*>\\n\\z/m, result)\n      a = 1.0\n      a.instance_eval { @a = nil }\n      result = PP.pp(a, '')\n      assert_equal(\"#{a.inspect}\\n\", result)\n    end\n    \n    def test_to_s_without_iv\n      a = Object.new\n      def a.to_s() \"aaa\" end\n      result = PP.pp(a, '')\n      assert_equal(\"#{a.inspect}\\n\", result)\n      assert_equal(\"aaa\\n\", result)\n    end\n  end\n\n  class PPCycleTest < Test::Unit::TestCase\n    def test_array\n      a = []\n      a << a\n      assert_equal(\"[[...]]\\n\", PP.pp(a, ''))\n      assert_equal(\"#{a.inspect}\\n\", PP.pp(a, ''))\n    end\n\n    def test_hash\n      a = {}\n      a[0] = a\n      assert_equal(\"{0=>{...}}\\n\", PP.pp(a, ''))\n      assert_equal(\"#{a.inspect}\\n\", PP.pp(a, ''))\n    end\n\n    S = Struct.new(\"S\", :a, :b)\n    def test_struct\n      a = S.new(1,2)\n      a.b = a\n      assert_equal(\"#<struct Struct::S a=1, b=#<struct Struct::S:...>>\\n\", PP.pp(a, ''))\n      assert_equal(\"#{a.inspect}\\n\", PP.pp(a, ''))\n    end\n\n    def test_object\n      a = Object.new\n      a.instance_eval {@a = a}\n      assert_equal(a.inspect + \"\\n\", PP.pp(a, ''))\n    end\n\n    def test_anonymous\n      a = Class.new.new\n      assert_equal(a.inspect + \"\\n\", PP.pp(a, ''))\n    end\n\n    def test_withinspect\n      a = []\n      a << HasInspect.new(a)\n      assert_equal(\"[<inspect:[...]>]\\n\", PP.pp(a, ''))\n      assert_equal(\"#{a.inspect}\\n\", PP.pp(a, ''))\n    end\n\n    def test_share_nil\n      begin\n        PP.sharing_detection = true\n        a = [nil, nil]\n        assert_equal(\"[nil, nil]\\n\", PP.pp(a, ''))\n      ensure\n        PP.sharing_detection = false\n      end\n    end\n  end\n\n  class PPSingleLineTest < Test::Unit::TestCase\n    def test_hash\n      assert_equal(\"{1=>1}\", PP.singleline_pp({ 1 => 1}, '')) # [ruby-core:02699]\n      assert_equal(\"[1#{', 1'*99}]\", PP.singleline_pp([1]*100, ''))\n    end\n  end\nend\n"
  },
  {
    "path": "lib/prettyprint.rb",
    "content": "# $Id$\n\n# This class implements a pretty printing algorithm. It finds line breaks and\n# nice indentations for grouped structure.\n# \n# By default, the class assumes that primitive elements are strings and each\n# byte in the strings have single column in width. But it can be used for\n# other situations by giving suitable arguments for some methods:\n# * newline object and space generation block for PrettyPrint.new\n# * optional width argument for PrettyPrint#text\n# * PrettyPrint#breakable\n#\n# There are several candidate uses:\n# * text formatting using proportional fonts\n# * multibyte characters which has columns different to number of bytes\n# * non-string formatting\n#\n# == Bugs\n# * Box based formatting?\n# * Other (better) model/algorithm?\n# \n# == References\n# Christian Lindig, Strictly Pretty, March 2000,\n# http://www.st.cs.uni-sb.de/~lindig/papers/#pretty\n# \n# Philip Wadler, A prettier printer, March 1998,\n# http://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier\n# \n# == Author\n# Tanaka Akira <akr@m17n.org>\n# \nclass PrettyPrint\n\n  # This is a convenience method which is same as follows:\n  # \n  #   begin\n  #     q = PrettyPrint.new(output, maxwidth, newline, &genspace)\n  #     ...\n  #     q.flush\n  #     output\n  #   end\n  # \n  def PrettyPrint.format(output='', maxwidth=79, newline=\"\\n\", genspace=lambda {|n| ' ' * n})\n    q = PrettyPrint.new(output, maxwidth, newline, &genspace)\n    yield q\n    q.flush\n    output\n  end\n\n  # This is similar to PrettyPrint::format but the result has no breaks.\n  #\n  # +maxwidth+, +newline+ and +genspace+ are ignored.\n  #\n  # The invocation of +breakable+ in the block doesn't break a line and is\n  # treated as just an invocation of +text+.\n  #\n  def PrettyPrint.singleline_format(output='', maxwidth=nil, newline=nil, genspace=nil)\n    q = SingleLine.new(output)\n    yield q\n    output\n  end\n\n  # Creates a buffer for pretty printing.\n  #\n  # +output+ is an output target. If it is not specified, '' is assumed. It\n  # should have a << method which accepts the first argument +obj+ of\n  # PrettyPrint#text, the first argument +sep+ of PrettyPrint#breakable, the\n  # first argument +newline+ of PrettyPrint.new, and the result of a given\n  # block for PrettyPrint.new.\n  #\n  # +maxwidth+ specifies maximum line length. If it is not specified, 79 is\n  # assumed. However actual outputs may overflow +maxwidth+ if long\n  # non-breakable texts are provided.\n  #\n  # +newline+ is used for line breaks. \"\\n\" is used if it is not specified.\n  #\n  # The block is used to generate spaces. {|width| ' ' * width} is used if it\n  # is not given.\n  #\n  def initialize(output='', maxwidth=79, newline=\"\\n\", &genspace)\n    @output = output\n    @maxwidth = maxwidth\n    @newline = newline\n    @genspace = genspace || lambda {|n| ' ' * n}\n\n    @output_width = 0\n    @buffer_width = 0\n    @buffer = []\n\n    root_group = Group.new(0)\n    @group_stack = [root_group]\n    @group_queue = GroupQueue.new(root_group)\n    @indent = 0\n  end\n  attr_reader :output, :maxwidth, :newline, :genspace\n  attr_reader :indent, :group_queue\n\n  def current_group\n    @group_stack.last\n  end\n\n  # first? is a predicate to test the call is a first call to first? with\n  # current group.\n  #\n  # It is useful to format comma separated values as:\n  #\n  #   q.group(1, '[', ']') {\n  #     xxx.each {|yyy|\n  #       unless q.first?\n  #         q.text ','\n  #         q.breakable\n  #       end\n  #       ... pretty printing yyy ...\n  #     }\n  #   }\n  #\n  # first? is obsoleted in 1.8.2.\n  #\n  def first?\n    warn \"PrettyPrint#first? is obsoleted at 1.8.2.\"\n    current_group.first?\n  end\n\n  def break_outmost_groups\n    while @maxwidth < @output_width + @buffer_width\n      return unless group = @group_queue.deq\n      until group.breakables.empty?\n        data = @buffer.shift\n        @output_width = data.output(@output, @output_width)\n        @buffer_width -= data.width\n      end\n      while !@buffer.empty? && Text === @buffer.first\n        text = @buffer.shift\n        @output_width = text.output(@output, @output_width)\n        @buffer_width -= text.width\n      end\n    end\n  end\n\n  # This adds +obj+ as a text of +width+ columns in width.\n  #\n  # If +width+ is not specified, obj.length is used.\n  #\n  def text(obj, width=obj.length)\n    if @buffer.empty?\n      @output << obj\n      @output_width += width\n    else\n      text = @buffer.last\n      unless Text === text\n        text = Text.new\n        @buffer << text\n      end\n      text.add(obj, width)\n      @buffer_width += width\n      break_outmost_groups\n    end\n  end\n\n  def fill_breakable(sep=' ', width=sep.length)\n    group { breakable sep, width }\n  end\n\n  # This tells \"you can break a line here if necessary\", and a +width+\\-column\n  # text +sep+ is inserted if a line is not broken at the point.\n  #\n  # If +sep+ is not specified, \" \" is used.\n  #\n  # If +width+ is not specified, +sep.length+ is used. You will have to\n  # specify this when +sep+ is a multibyte character, for example.\n  #\n  def breakable(sep=' ', width=sep.length)\n    group = @group_stack.last\n    if group.break?\n      flush\n      @output << @newline\n      @output << @genspace.call(@indent)\n      @output_width = @indent\n      @buffer_width = 0\n    else\n      @buffer << Breakable.new(sep, width, self)\n      @buffer_width += width\n      break_outmost_groups\n    end\n  end\n\n  # Groups line break hints added in the block. The line break hints are all\n  # to be used or not.\n  #\n  # If +indent+ is specified, the method call is regarded as nested by\n  # nest(indent) { ... }.\n  #\n  # If +open_obj+ is specified, <tt>text open_obj, open_width</tt> is called\n  # before grouping. If +close_obj+ is specified, <tt>text close_obj,\n  # close_width</tt> is called after grouping.\n  #\n  def group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length)\n    text open_obj, open_width\n    group_sub {\n      nest(indent) {\n        yield\n      }\n    }\n    text close_obj, close_width\n  end\n\n  def group_sub\n    group = Group.new(@group_stack.last.depth + 1)\n    @group_stack.push group\n    @group_queue.enq group\n    begin\n      yield\n    ensure\n      @group_stack.pop\n      if group.breakables.empty?\n        @group_queue.delete group\n      end\n    end\n  end\n\n  # Increases left margin after newline with +indent+ for line breaks added in\n  # the block.\n  #\n  def nest(indent)\n    @indent += indent\n    begin\n      yield\n    ensure\n      @indent -= indent\n    end\n  end\n\n  # outputs buffered data.\n  #\n  def flush\n    @buffer.each {|data|\n      @output_width = data.output(@output, @output_width)\n    }\n    @buffer.clear\n    @buffer_width = 0\n  end\n\n  class Text\n    def initialize\n      @objs = []\n      @width = 0\n    end\n    attr_reader :width\n\n    def output(out, output_width)\n      @objs.each {|obj| out << obj}\n      output_width + @width\n    end\n\n    def add(obj, width)\n      @objs << obj\n      @width += width\n    end\n  end\n\n  class Breakable\n    def initialize(sep, width, q)\n      @obj = sep\n      @width = width\n      @pp = q\n      @indent = q.indent\n      @group = q.current_group\n      @group.breakables.push self\n    end\n    attr_reader :obj, :width, :indent\n\n    def output(out, output_width)\n      @group.breakables.shift\n      if @group.break?\n        out << @pp.newline\n        out << @pp.genspace.call(@indent)\n        @indent\n      else\n        @pp.group_queue.delete @group if @group.breakables.empty?\n        out << @obj\n        output_width + @width\n      end\n    end\n  end\n\n  class Group\n    def initialize(depth)\n      @depth = depth\n      @breakables = []\n      @break = false\n    end\n    attr_reader :depth, :breakables\n\n    def break\n      @break = true\n    end\n\n    def break?\n      @break\n    end\n\n    def first?\n      if defined? @first\n        false\n      else\n        @first = false\n        true\n      end\n    end\n  end\n\n  class GroupQueue\n    def initialize(*groups)\n      @queue = []\n      groups.each {|g| enq g}\n    end\n\n    def enq(group)\n      depth = group.depth\n      @queue << [] until depth < @queue.length\n      @queue[depth] << group\n    end\n\n    def deq\n      @queue.each {|gs|\n        (gs.length-1).downto(0) {|i|\n          unless gs[i].breakables.empty?\n            group = gs.slice!(i, 1).first\n            group.break\n            return group\n          end\n        }\n        gs.each {|group| group.break}\n        gs.clear\n      }\n      return nil\n    end\n\n    def delete(group)\n      @queue[group.depth].delete(group)\n    end\n  end\n\n  class SingleLine\n    def initialize(output, maxwidth=nil, newline=nil)\n      @output = output\n      @first = [true]\n    end\n\n    def text(obj, width=nil)\n      @output << obj\n    end\n\n    def breakable(sep=' ', width=nil)\n      @output << sep\n    end\n\n    def nest(indent)\n      yield\n    end\n\n    def group(indent=nil, open_obj='', close_obj='', open_width=nil, close_width=nil)\n      @first.push true\n      @output << open_obj\n      yield\n      @output << close_obj\n      @first.pop\n    end\n\n    def flush\n    end\n\n    def first?\n      result = @first[-1]\n      @first[-1] = false\n      result\n    end\n  end\nend\n\nif __FILE__ == $0\n  require 'test/unit'\n\n  class WadlerExample < Test::Unit::TestCase # :nodoc:\n    def setup\n      @tree = Tree.new(\"aaaa\", Tree.new(\"bbbbb\", Tree.new(\"ccc\"),\n                                                 Tree.new(\"dd\")),\n                               Tree.new(\"eee\"),\n                               Tree.new(\"ffff\", Tree.new(\"gg\"),\n                                                Tree.new(\"hhh\"),\n                                                Tree.new(\"ii\")))\n    end\n\n    def hello(width)\n      PrettyPrint.format('', width) {|hello|\n        hello.group {\n          hello.group {\n            hello.group {\n              hello.group {\n                hello.text 'hello'\n                hello.breakable; hello.text 'a'\n              }\n              hello.breakable; hello.text 'b'\n            }\n            hello.breakable; hello.text 'c'\n          }\n          hello.breakable; hello.text 'd'\n        }\n      }\n    end\n\n    def test_hello_00_06\n      expected = <<'End'.chomp\nhello\na\nb\nc\nd\nEnd\n      assert_equal(expected, hello(0))\n      assert_equal(expected, hello(6))\n    end\n\n    def test_hello_07_08\n      expected = <<'End'.chomp\nhello a\nb\nc\nd\nEnd\n      assert_equal(expected, hello(7))\n      assert_equal(expected, hello(8))\n    end\n\n    def test_hello_09_10\n      expected = <<'End'.chomp\nhello a b\nc\nd\nEnd\n      out = hello(9); assert_equal(expected, out)\n      out = hello(10); assert_equal(expected, out)\n    end\n\n    def test_hello_11_12\n      expected = <<'End'.chomp\nhello a b c\nd\nEnd\n      assert_equal(expected, hello(11))\n      assert_equal(expected, hello(12))\n    end\n\n    def test_hello_13\n      expected = <<'End'.chomp\nhello a b c d\nEnd\n      assert_equal(expected, hello(13))\n    end\n\n    def tree(width)\n      PrettyPrint.format('', width) {|q| @tree.show(q)}\n    end\n\n    def test_tree_00_19\n      expected = <<'End'.chomp\naaaa[bbbbb[ccc,\n           dd],\n     eee,\n     ffff[gg,\n          hhh,\n          ii]]\nEnd\n      assert_equal(expected, tree(0))\n      assert_equal(expected, tree(19))\n    end\n\n    def test_tree_20_22\n      expected = <<'End'.chomp\naaaa[bbbbb[ccc, dd],\n     eee,\n     ffff[gg,\n          hhh,\n          ii]]\nEnd\n      assert_equal(expected, tree(20))\n      assert_equal(expected, tree(22))\n    end\n\n    def test_tree_23_43\n      expected = <<'End'.chomp\naaaa[bbbbb[ccc, dd],\n     eee,\n     ffff[gg, hhh, ii]]\nEnd\n      assert_equal(expected, tree(23))\n      assert_equal(expected, tree(43))\n    end\n\n    def test_tree_44\n      assert_equal(<<'End'.chomp, tree(44))\naaaa[bbbbb[ccc, dd], eee, ffff[gg, hhh, ii]]\nEnd\n    end\n\n    def tree_alt(width)\n      PrettyPrint.format('', width) {|q| @tree.altshow(q)}\n    end\n\n    def test_tree_alt_00_18\n      expected = <<'End'.chomp\naaaa[\n  bbbbb[\n    ccc,\n    dd\n  ],\n  eee,\n  ffff[\n    gg,\n    hhh,\n    ii\n  ]\n]\nEnd\n      assert_equal(expected, tree_alt(0))\n      assert_equal(expected, tree_alt(18))\n    end\n\n    def test_tree_alt_19_20\n      expected = <<'End'.chomp\naaaa[\n  bbbbb[ ccc, dd ],\n  eee,\n  ffff[\n    gg,\n    hhh,\n    ii\n  ]\n]\nEnd\n      assert_equal(expected, tree_alt(19))\n      assert_equal(expected, tree_alt(20))\n    end\n\n    def test_tree_alt_20_49\n      expected = <<'End'.chomp\naaaa[\n  bbbbb[ ccc, dd ],\n  eee,\n  ffff[ gg, hhh, ii ]\n]\nEnd\n      assert_equal(expected, tree_alt(21))\n      assert_equal(expected, tree_alt(49))\n    end\n\n    def test_tree_alt_50\n      expected = <<'End'.chomp\naaaa[ bbbbb[ ccc, dd ], eee, ffff[ gg, hhh, ii ] ]\nEnd\n      assert_equal(expected, tree_alt(50))\n    end\n\n    class Tree # :nodoc:\n      def initialize(string, *children)\n        @string = string\n        @children = children\n      end\n\n      def show(q)\n        q.group {\n          q.text @string\n          q.nest(@string.length) {\n            unless @children.empty?\n              q.text '['\n              q.nest(1) {\n                first = true\n                @children.each {|t|\n                  if first\n                    first = false\n                  else\n                    q.text ','\n                    q.breakable\n                  end\n                  t.show(q)\n                }\n              }\n              q.text ']'\n            end\n          }\n        }\n      end\n\n      def altshow(q)\n        q.group {\n          q.text @string\n          unless @children.empty?\n            q.text '['\n            q.nest(2) {\n              q.breakable\n              first = true\n              @children.each {|t|\n                if first\n                  first = false\n                else\n                  q.text ','\n                  q.breakable\n                end\n                t.altshow(q)\n              }\n            }\n            q.breakable\n            q.text ']'\n          end\n        }\n      end\n\n    end\n  end\n\n  class StrictPrettyExample < Test::Unit::TestCase # :nodoc:\n    def prog(width)\n      PrettyPrint.format('', width) {|q|\n        q.group {\n          q.group {q.nest(2) {\n                       q.text \"if\"; q.breakable;\n                       q.group {\n                         q.nest(2) {\n                           q.group {q.text \"a\"; q.breakable; q.text \"==\"}\n                           q.breakable; q.text \"b\"}}}}\n          q.breakable\n          q.group {q.nest(2) {\n                       q.text \"then\"; q.breakable;\n                       q.group {\n                         q.nest(2) {\n                           q.group {q.text \"a\"; q.breakable; q.text \"<<\"}\n                           q.breakable; q.text \"2\"}}}}\n          q.breakable\n          q.group {q.nest(2) {\n                       q.text \"else\"; q.breakable;\n                       q.group {\n                         q.nest(2) {\n                           q.group {q.text \"a\"; q.breakable; q.text \"+\"}\n                           q.breakable; q.text \"b\"}}}}}\n      }\n    end\n\n    def test_00_04\n      expected = <<'End'.chomp\nif\n  a\n    ==\n    b\nthen\n  a\n    <<\n    2\nelse\n  a\n    +\n    b\nEnd\n      assert_equal(expected, prog(0))\n      assert_equal(expected, prog(4))\n    end\n\n    def test_05\n      expected = <<'End'.chomp\nif\n  a\n    ==\n    b\nthen\n  a\n    <<\n    2\nelse\n  a +\n    b\nEnd\n      assert_equal(expected, prog(5))\n    end\n\n    def test_06\n      expected = <<'End'.chomp\nif\n  a ==\n    b\nthen\n  a <<\n    2\nelse\n  a +\n    b\nEnd\n      assert_equal(expected, prog(6))\n    end\n\n    def test_07\n      expected = <<'End'.chomp\nif\n  a ==\n    b\nthen\n  a <<\n    2\nelse\n  a + b\nEnd\n      assert_equal(expected, prog(7))\n    end\n\n    def test_08\n      expected = <<'End'.chomp\nif\n  a == b\nthen\n  a << 2\nelse\n  a + b\nEnd\n      assert_equal(expected, prog(8))\n    end\n\n    def test_09\n      expected = <<'End'.chomp\nif a == b\nthen\n  a << 2\nelse\n  a + b\nEnd\n      assert_equal(expected, prog(9))\n    end\n\n    def test_10\n      expected = <<'End'.chomp\nif a == b\nthen\n  a << 2\nelse a + b\nEnd\n      assert_equal(expected, prog(10))\n    end\n\n    def test_11_31\n      expected = <<'End'.chomp\nif a == b\nthen a << 2\nelse a + b\nEnd\n      assert_equal(expected, prog(11))\n      assert_equal(expected, prog(15))\n      assert_equal(expected, prog(31))\n    end\n\n    def test_32\n      expected = <<'End'.chomp\nif a == b then a << 2 else a + b\nEnd\n      assert_equal(expected, prog(32))\n    end\n\n  end\n\n  class TailGroup < Test::Unit::TestCase # :nodoc:\n    def test_1\n      out = PrettyPrint.format('', 10) {|q|\n        q.group {\n          q.group {\n            q.text \"abc\"\n            q.breakable\n            q.text \"def\"\n          }\n          q.group {\n            q.text \"ghi\"\n            q.breakable\n            q.text \"jkl\"\n          }\n        }\n      }\n      assert_equal(\"abc defghi\\njkl\", out)\n    end\n  end\n\n  class NonString < Test::Unit::TestCase # :nodoc:\n    def format(width)\n      PrettyPrint.format([], width, 'newline', lambda {|n| \"#{n} spaces\"}) {|q|\n        q.text(3, 3)\n        q.breakable(1, 1)\n        q.text(3, 3)\n      }\n    end\n\n    def test_6\n      assert_equal([3, \"newline\", \"0 spaces\", 3], format(6))\n    end\n\n    def test_7\n      assert_equal([3, 1, 3], format(7))\n    end\n\n  end\n\n  class Fill < Test::Unit::TestCase # :nodoc:\n    def format(width)\n      PrettyPrint.format('', width) {|q|\n        q.group {\n          q.text 'abc'\n          q.fill_breakable\n          q.text 'def'\n          q.fill_breakable\n          q.text 'ghi'\n          q.fill_breakable\n          q.text 'jkl'\n          q.fill_breakable\n          q.text 'mno'\n          q.fill_breakable\n          q.text 'pqr'\n          q.fill_breakable\n          q.text 'stu'\n        }\n      }\n    end\n\n    def test_00_06\n      expected = <<'End'.chomp\nabc\ndef\nghi\njkl\nmno\npqr\nstu\nEnd\n      assert_equal(expected, format(0))\n      assert_equal(expected, format(6))\n    end\n\n    def test_07_10\n      expected = <<'End'.chomp\nabc def\nghi jkl\nmno pqr\nstu\nEnd\n      assert_equal(expected, format(7))\n      assert_equal(expected, format(10))\n    end\n\n    def test_11_14\n      expected = <<'End'.chomp\nabc def ghi\njkl mno pqr\nstu\nEnd\n      assert_equal(expected, format(11))\n      assert_equal(expected, format(14))\n    end\n\n    def test_15_18\n      expected = <<'End'.chomp\nabc def ghi jkl\nmno pqr stu\nEnd\n      assert_equal(expected, format(15))\n      assert_equal(expected, format(18))\n    end\n\n    def test_19_22\n      expected = <<'End'.chomp\nabc def ghi jkl mno\npqr stu\nEnd\n      assert_equal(expected, format(19))\n      assert_equal(expected, format(22))\n    end\n\n    def test_23_26\n      expected = <<'End'.chomp\nabc def ghi jkl mno pqr\nstu\nEnd\n      assert_equal(expected, format(23))\n      assert_equal(expected, format(26))\n    end\n\n    def test_27\n      expected = <<'End'.chomp\nabc def ghi jkl mno pqr stu\nEnd\n      assert_equal(expected, format(27))\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/profile.rb",
    "content": "require 'profiler'\n\nEND {\n  Profiler__::print_profile(STDERR)\n}\nProfiler__::start_profile\n"
  },
  {
    "path": "lib/profiler.rb",
    "content": "module Profiler__\n  # internal values\n  @@start = @@stack = @@map = nil\n  PROFILE_PROC = proc{|event, file, line, id, binding, klass|\n    case event\n    when \"call\", \"c-call\"\n      now = Process.times[0]\n      @@stack.push [now, 0.0]\n    when \"return\", \"c-return\"\n      now = Process.times[0]\n      key = [klass, id]\n      if tick = @@stack.pop\n        data = (@@map[key] ||= [0, 0.0, 0.0, key])\n        data[0] += 1\n        cost = now - tick[0]\n        data[1] += cost\n        data[2] += cost - tick[1]\n        @@stack[-1][1] += cost if @@stack[-1]\n      end\n    end\n  }\nmodule_function\n  def start_profile\n    @@start = Process.times[0]\n    @@stack = []\n    @@map = {}\n    set_trace_func PROFILE_PROC\n  end\n  def stop_profile\n    set_trace_func nil\n  end\n  def print_profile(f)\n    stop_profile\n    total = Process.times[0] - @@start\n    if total == 0 then total = 0.01 end\n    data = @@map.values\n    data.sort!{|a,b| b[2] <=> a[2]}\n    sum = 0\n    f.printf \"  %%   cumulative   self              self     total\\n\"\n    f.printf \" time   seconds   seconds    calls  ms/call  ms/call  name\\n\"\n    for d in data\n      sum += d[2]\n      f.printf \"%6.2f %8.2f  %8.2f %8d \", d[2]/total*100, sum, d[2], d[0]\n      f.printf \"%8.2f %8.2f  %s\\n\", d[2]*1000/d[0], d[1]*1000/d[0], get_name(*d[3])\n    end\n    f.printf \"%6.2f %8.2f  %8.2f %8d \", 0.0, total, 0.0, 1     # ???\n    f.printf \"%8.2f %8.2f  %s\\n\", 0.0, total*1000, \"#toplevel\" # ???\n  end\n  def get_name(klass, id)\n    name = klass.to_s || \"\"\n    if klass.kind_of? Class\n      name += \"#\"\n    else\n      name += \".\"\n    end\n    name + id.id2name\n  end\n  private :get_name\nend\n"
  },
  {
    "path": "lib/pstore.rb",
    "content": "# = PStore -- Transactional File Storage for Ruby Objects\n#\n# pstore.rb -\n#   originally by matz\n#   documentation by Kev Jackson and James Edward Gray II\n#\n# See PStore for documentation.\n\n\nrequire \"fileutils\"\nrequire \"digest/md5\"\n\n#\n# PStore implements a file based persistence mechanism based on a Hash.  User\n# code can store hierarchies of Ruby objects (values) into the data store file\n# by name (keys).  An object hierarchy may be just a single object.  User code \n# may later read values back from the data store or even update data, as needed.\n# \n# The transactional behavior ensures that any changes succeed or fail together.\n# This can be used to ensure that the data store is not left in a transitory\n# state, where some values were updated but others were not.\n# \n# Behind the scenes, Ruby objects are stored to the data store file with \n# Marshal.  That carries the usual limitations.  Proc objects cannot be \n# marshalled, for example.\n#\n# == Usage example:\n# \n#  require \"pstore\"\n#  \n#  # a mock wiki object...\n#  class WikiPage\n#    def initialize( page_name, author, contents )\n#      @page_name = page_name\n#      @revisions = Array.new\n#      \n#      add_revision(author, contents)\n#    end\n#    \n#    attr_reader :page_name\n#    \n#    def add_revision( author, contents )\n#      @revisions << { :created  => Time.now,\n#                      :author   => author,\n#                      :contents => contents }\n#    end\n#    \n#    def wiki_page_references\n#      [@page_name] + @revisions.last[:contents].scan(/\\b(?:[A-Z]+[a-z]+){2,}/)\n#    end\n#    \n#    # ...\n#  end\n#  \n#  # create a new page...\n#  home_page = WikiPage.new( \"HomePage\", \"James Edward Gray II\",\n#                            \"A page about the JoysOfDocumentation...\" )\n#  \n#  # then we want to update page data and the index together, or not at all...\n#  wiki = PStore.new(\"wiki_pages.pstore\")\n#  wiki.transaction do  # begin transaction; do all of this or none of it\n#    # store page...\n#    wiki[home_page.page_name] = home_page\n#    # ensure that an index has been created...\n#    wiki[:wiki_index] ||= Array.new\n#    # update wiki index...\n#    wiki[:wiki_index].push(*home_page.wiki_page_references)\n#  end                   # commit changes to wiki data store file\n#  \n#  ### Some time later... ###\n#  \n#  # read wiki data...\n#  wiki.transaction(true) do  # begin read-only transaction, no changes allowed\n#    wiki.roots.each do |data_root_name|\n#      p data_root_name\n#      p wiki[data_root_name]\n#    end\n#  end\n#\nclass PStore\n  binmode = defined?(File::BINARY) ? File::BINARY : 0\n  RDWR_ACCESS = File::RDWR | File::CREAT | binmode\n  RD_ACCESS = File::RDONLY | binmode\n  WR_ACCESS = File::WRONLY | File::CREAT | File::TRUNC | binmode\n\n  # The error type thrown by all PStore methods.\n  class Error < StandardError\n  end\n\n  # \n  # To construct a PStore object, pass in the _file_ path where you would like \n  # the data to be stored.\n  # \n  def initialize(file)\n    dir = File::dirname(file)\n    unless File::directory? dir\n      raise PStore::Error, format(\"directory %s does not exist\", dir)\n    end\n    if File::exist? file and not File::readable? file\n      raise PStore::Error, format(\"file %s not readable\", file)\n    end\n    @transaction = false\n    @filename = file\n    @abort = false\n  end\n\n  # Raises PStore::Error if the calling code is not in a PStore#transaction.\n  def in_transaction\n    raise PStore::Error, \"not in transaction\" unless @transaction\n  end\n  # \n  # Raises PStore::Error if the calling code is not in a PStore#transaction or\n  # if the code is in a read-only PStore#transaction.\n  # \n  def in_transaction_wr()\n    in_transaction()\n    raise PStore::Error, \"in read-only transaction\" if @rdonly\n  end\n  private :in_transaction, :in_transaction_wr\n\n  #\n  # Retrieves a value from the PStore file data, by _name_.  The hierarchy of \n  # Ruby objects stored under that root _name_ will be returned.\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction.  It will\n  # raise PStore::Error if called at any other time.\n  #\n  def [](name)\n    in_transaction\n    @table[name]\n  end\n  #\n  # This method is just like PStore#[], save that you may also provide a \n  # _default_ value for the object.  In the event the specified _name_ is not \n  # found in the data store, your _default_ will be returned instead.  If you do \n  # not specify a default, PStore::Error will be raised if the object is not \n  # found.\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction.  It will\n  # raise PStore::Error if called at any other time.\n  #\n  def fetch(name, default=PStore::Error)\n    in_transaction\n    unless @table.key? name\n      if default==PStore::Error\n\traise PStore::Error, format(\"undefined root name `%s'\", name)\n      else\n\treturn default\n      end\n    end\n    @table[name]\n  end\n  #\n  # Stores an individual Ruby object or a hierarchy of Ruby objects in the data\n  # store file under the root _name_.  Assigning to a _name_ already in the data\n  # store clobbers the old data.\n  # \n  # == Example:\n  # \n  #  require \"pstore\"\n  #  \n  #  store = PStore.new(\"data_file.pstore\")\n  #  store.transaction do  # begin transaction\n  #    # load some data into the store...\n  #    store[:single_object] = \"My data...\"\n  #    store[:obj_heirarchy] = { \"Kev Jackson\" => [\"rational.rb\", \"pstore.rb\"],\n  #                              \"James Gray\"  => [\"erb.rb\", \"pstore.rb\"] }\n  #  end                   # commit changes to data store file\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction and it cannot\n  # be read-only.  It will raise PStore::Error if called at any other time.\n  #\n  def []=(name, value)\n    in_transaction_wr()\n    @table[name] = value\n  end\n  #\n  # Removes an object hierarchy from the data store, by _name_.\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction and it cannot\n  # be read-only.  It will raise PStore::Error if called at any other time.\n  #\n  def delete(name)\n    in_transaction_wr()\n    @table.delete name\n  end\n\n  #\n  # Returns the names of all object hierarchies currently in the store.\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction.  It will\n  # raise PStore::Error if called at any other time.\n  #\n  def roots\n    in_transaction\n    @table.keys\n  end\n  #\n  # Returns true if the supplied _name_ is currently in the data store.\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction.  It will\n  # raise PStore::Error if called at any other time.\n  #\n  def root?(name)\n    in_transaction\n    @table.key? name\n  end\n  # Returns the path to the data store file.\n  def path\n    @filename\n  end\n\n  #\n  # Ends the current PStore#transaction, committing any changes to the data\n  # store immediately.\n  # \n  # == Example:\n  # \n  #  require \"pstore\"\n  #   \n  #  store = PStore.new(\"data_file.pstore\")\n  #  store.transaction do  # begin transaction\n  #    # load some data into the store...\n  #    store[:one] = 1\n  #    store[:two] = 2\n  #  \n  #    store.commit        # end transaction here, committing changes\n  #  \n  #    store[:three] = 3   # this change is never reached\n  #  end\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction.  It will\n  # raise PStore::Error if called at any other time.\n  #\n  def commit\n    in_transaction\n    @abort = false\n    throw :pstore_abort_transaction\n  end\n  #\n  # Ends the current PStore#transaction, discarding any changes to the data\n  # store.\n  # \n  # == Example:\n  # \n  #  require \"pstore\"\n  #   \n  #  store = PStore.new(\"data_file.pstore\")\n  #  store.transaction do  # begin transaction\n  #    store[:one] = 1     # this change is not applied, see below...\n  #    store[:two] = 2     # this change is not applied, see below...\n  #  \n  #    store.abort         # end transaction here, discard all changes\n  #  \n  #    store[:three] = 3   # this change is never reached\n  #  end\n  # \n  # *WARNING*:  This method is only valid in a PStore#transaction.  It will\n  # raise PStore::Error if called at any other time.\n  #\n  def abort\n    in_transaction\n    @abort = true\n    throw :pstore_abort_transaction\n  end\n\n  #\n  # Opens a new transaction for the data store.  Code executed inside a block\n  # passed to this method may read and write data to and from the data store \n  # file.\n  # \n  # At the end of the block, changes are committed to the data store\n  # automatically.  You may exit the transaction early with a call to either \n  # PStore#commit or PStore#abort.  See those methods for details about how\n  # changes are handled.  Raising an uncaught Exception in the block is \n  # equivalent to calling PStore#abort.\n  # \n  # If _read_only_ is set to +true+, you will only be allowed to read from the\n  # data store during the transaction and any attempts to change the data will\n  # raise a PStore::Error.\n  # \n  # Note that PStore does not support nested transactions.\n  #\n  def transaction(read_only=false)  # :yields:  pstore\n    raise PStore::Error, \"nested transaction\" if @transaction\n    begin\n      @rdonly = read_only\n      @abort = false\n      @transaction = true\n      value = nil\n      new_file = @filename + \".new\"\n\n      content = nil\n      unless read_only\n        file = File.open(@filename, RDWR_ACCESS)\n        file.flock(File::LOCK_EX)\n        commit_new(file) if FileTest.exist?(new_file)\n        content = file.read()\n      else\n        begin\n          file = File.open(@filename, RD_ACCESS)\n          file.flock(File::LOCK_SH)\n          content = (File.open(new_file, RD_ACCESS) {|n| n.read} rescue file.read())\n        rescue Errno::ENOENT\n          content = \"\"\n        end\n      end\n\n      if content != \"\"\n\t@table = load(content)\n        if !read_only\n          size = content.size\n          md5 = Digest::MD5.digest(content)\n        end\n      else\n\t@table = {}\n      end\n      content = nil\t\t# unreference huge data\n\n      begin\n\tcatch(:pstore_abort_transaction) do\n\t  value = yield(self)\n\tend\n      rescue Exception\n\t@abort = true\n\traise\n      ensure\n\tif !read_only and !@abort\n          tmp_file = @filename + \".tmp\"\n\t  content = dump(@table)\n\t  if !md5 || size != content.size || md5 != Digest::MD5.digest(content)\n            File.open(tmp_file, WR_ACCESS) {|t| t.write(content)}\n            File.rename(tmp_file, new_file)\n            commit_new(file)\n          end\n          content = nil\t\t# unreference huge data\n\tend\n      end\n    ensure\n      @table = nil\n      @transaction = false\n      file.close if file\n    end\n    value\n  end\n\n  # This method is just a wrapped around Marshal.dump.\n  def dump(table)  # :nodoc:\n    Marshal::dump(table)\n  end\n\n  # This method is just a wrapped around Marshal.load.\n  def load(content)  # :nodoc:\n    Marshal::load(content)\n  end\n\n  # This method is just a wrapped around Marshal.load.\n  def load_file(file)  # :nodoc:\n    Marshal::load(file)\n  end\n\n  private\n  # Commits changes to the data store file.\n  def commit_new(f)\n    f.truncate(0)\n    f.rewind\n    new_file = @filename + \".new\"\n    File.open(new_file, RD_ACCESS) do |nf|\n      FileUtils.copy_stream(nf, f)\n    end\n    File.unlink(new_file)\n  end\nend\n\n# :enddoc:\n\nif __FILE__ == $0\n  db = PStore.new(\"/tmp/foo\")\n  db.transaction do\n    p db.roots\n    ary = db[\"root\"] = [1,2,3,4]\n    ary[1] = [1,1.5]\n  end\n\n  1000.times do\n    db.transaction do\n      db[\"root\"][0] += 1\n      p db[\"root\"][0]\n    end\n  end\n\n  db.transaction(true) do\n    p db[\"root\"]\n  end\nend\n"
  },
  {
    "path": "lib/racc/parser.rb",
    "content": "#\n# $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $\n#\n# Copyright (c) 1999-2006 Minero Aoki\n#\n# This program is free software.\n# You can distribute/modify this program under the same terms of ruby.\n#\n# As a special exception, when this code is copied by Racc\n# into a Racc output file, you may use that output file\n# without restriction.\n#\n\nunless defined?(NotImplementedError)\n  NotImplementedError = NotImplementError\nend\n\nmodule Racc\n  class ParseError < StandardError; end\nend\nunless defined?(::ParseError)\n  ParseError = Racc::ParseError\nend\n\nmodule Racc\n\n  unless defined?(Racc_No_Extentions)\n    Racc_No_Extentions = false\n  end\n\n  class Parser\n\n    Racc_Runtime_Version = '1.4.5'\n    Racc_Runtime_Revision = '$originalRevision: 1.8 $'.split[1]\n\n    Racc_Runtime_Core_Version_R = '1.4.5'\n    Racc_Runtime_Core_Revision_R = '$originalRevision: 1.8 $'.split[1]\n    begin\n      require 'racc/cparse'\n    # Racc_Runtime_Core_Version_C  = (defined in extention)\n      Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]\n      unless new.respond_to?(:_racc_do_parse_c, true)\n        raise LoadError, 'old cparse.so'\n      end\n      if Racc_No_Extentions\n        raise LoadError, 'selecting ruby version of racc runtime core'\n      end\n\n      Racc_Main_Parsing_Routine    = :_racc_do_parse_c\n      Racc_YY_Parse_Method         = :_racc_yyparse_c\n      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_C\n      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_C\n      Racc_Runtime_Type            = 'c'\n    rescue LoadError\n      Racc_Main_Parsing_Routine    = :_racc_do_parse_rb\n      Racc_YY_Parse_Method         = :_racc_yyparse_rb\n      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_R\n      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_R\n      Racc_Runtime_Type            = 'ruby'\n    end\n\n    def Parser.racc_runtime_type\n      Racc_Runtime_Type\n    end\n\n    private\n\n    def _racc_setup\n      @yydebug = false unless self.class::Racc_debug_parser\n      @yydebug = false unless defined?(@yydebug)\n      if @yydebug\n        @racc_debug_out = $stderr unless defined?(@racc_debug_out)\n        @racc_debug_out ||= $stderr\n      end\n      arg = self.class::Racc_arg\n      arg[13] = true if arg.size < 14\n      arg\n    end\n\n    def _racc_init_sysvars\n      @racc_state  = [0]\n      @racc_tstack = []\n      @racc_vstack = []\n\n      @racc_t = nil\n      @racc_val = nil\n\n      @racc_read_next = true\n\n      @racc_user_yyerror = false\n      @racc_error_status = 0\n    end\n\n    ###\n    ### do_parse\n    ###\n\n    def do_parse\n      __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)\n    end\n\n    def next_token\n      raise NotImplementedError, \"#{self.class}\\#next_token is not defined\"\n    end\n\n    def _racc_do_parse_rb(arg, in_debug)\n      action_table, action_check, action_default, action_pointer,\n      goto_table,   goto_check,   goto_default,   goto_pointer,\n      nt_base,      reduce_table, token_table,    shift_n,\n      reduce_n,     use_result,   * = arg\n\n      _racc_init_sysvars\n      tok = act = i = nil\n      nerr = 0\n\n      catch(:racc_end_parse) {\n        while true\n          if i = action_pointer[@racc_state[-1]]\n            if @racc_read_next\n              if @racc_t != 0   # not EOF\n                tok, @racc_val = next_token()\n                unless tok      # EOF\n                  @racc_t = 0\n                else\n                  @racc_t = (token_table[tok] or 1)   # error token\n                end\n                racc_read_token(@racc_t, tok, @racc_val) if @yydebug\n                @racc_read_next = false\n              end\n            end\n            i += @racc_t\n            unless i >= 0 and\n                   act = action_table[i] and\n                   action_check[i] == @racc_state[-1]\n              act = action_default[@racc_state[-1]]\n            end\n          else\n            act = action_default[@racc_state[-1]]\n          end\n          while act = _racc_evalact(act, arg)\n            ;\n          end\n        end\n      }\n    end\n\n    ###\n    ### yyparse\n    ###\n\n    def yyparse(recv, mid)\n      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)\n    end\n\n    def _racc_yyparse_rb(recv, mid, arg, c_debug)\n      action_table, action_check, action_default, action_pointer,\n      goto_table,   goto_check,   goto_default,   goto_pointer,\n      nt_base,      reduce_table, token_table,    shift_n,\n      reduce_n,     use_result,   * = arg\n\n      _racc_init_sysvars\n      tok = nil\n      act = nil\n      i = nil\n      nerr = 0\n\n      catch(:racc_end_parse) {\n        until i = action_pointer[@racc_state[-1]]\n          while act = _racc_evalact(action_default[@racc_state[-1]], arg)\n            ;\n          end\n        end\n        recv.__send__(mid) do |tok, val|\n          unless tok\n            @racc_t = 0\n          else\n            @racc_t = (token_table[tok] or 1)   # error token\n          end\n          @racc_val = val\n          @racc_read_next = false\n\n          i += @racc_t\n          unless i >= 0 and\n                 act = action_table[i] and\n                 action_check[i] == @racc_state[-1]\n            act = action_default[@racc_state[-1]]\n          end\n          while act = _racc_evalact(act, arg)\n            ;\n          end\n\n          while not (i = action_pointer[@racc_state[-1]]) or\n                not @racc_read_next or\n                @racc_t == 0   # $\n            unless i and i += @racc_t and\n                   i >= 0 and\n                   act = action_table[i] and\n                   action_check[i] == @racc_state[-1]\n              act = action_default[@racc_state[-1]]\n            end\n            while act = _racc_evalact(act, arg)\n              ;\n            end\n          end\n        end\n      }\n    end\n\n    ###\n    ### common\n    ###\n\n    def _racc_evalact(act, arg)\n      action_table, action_check, action_default, action_pointer,\n      goto_table,   goto_check,   goto_default,   goto_pointer,\n      nt_base,      reduce_table, token_table,    shift_n,\n      reduce_n,     use_result,   * = arg\n      nerr = 0   # tmp\n\n      if act > 0 and act < shift_n\n        #\n        # shift\n        #\n        if @racc_error_status > 0\n          @racc_error_status -= 1 unless @racc_t == 1   # error token\n        end\n        @racc_vstack.push @racc_val\n        @racc_state.push act\n        @racc_read_next = true\n        if @yydebug\n          @racc_tstack.push @racc_t\n          racc_shift @racc_t, @racc_tstack, @racc_vstack\n        end\n\n      elsif act < 0 and act > -reduce_n\n        #\n        # reduce\n        #\n        code = catch(:racc_jump) {\n          @racc_state.push _racc_do_reduce(arg, act)\n          false\n        }\n        if code\n          case code\n          when 1 # yyerror\n            @racc_user_yyerror = true   # user_yyerror\n            return -reduce_n\n          when 2 # yyaccept\n            return shift_n\n          else\n            raise '[Racc Bug] unknown jump code'\n          end\n        end\n\n      elsif act == shift_n\n        #\n        # accept\n        #\n        racc_accept if @yydebug\n        throw :racc_end_parse, @racc_vstack[0]\n\n      elsif act == -reduce_n\n        #\n        # error\n        #\n        case @racc_error_status\n        when 0\n          unless arg[21]    # user_yyerror\n            nerr += 1\n            on_error @racc_t, @racc_val, @racc_vstack\n          end\n        when 3\n          if @racc_t == 0   # is $\n            throw :racc_end_parse, nil\n          end\n          @racc_read_next = true\n        end\n        @racc_user_yyerror = false\n        @racc_error_status = 3\n        while true\n          if i = action_pointer[@racc_state[-1]]\n            i += 1   # error token\n            if  i >= 0 and\n                (act = action_table[i]) and\n                action_check[i] == @racc_state[-1]\n              break\n            end\n          end\n          throw :racc_end_parse, nil if @racc_state.size <= 1\n          @racc_state.pop\n          @racc_vstack.pop\n          if @yydebug\n            @racc_tstack.pop\n            racc_e_pop @racc_state, @racc_tstack, @racc_vstack\n          end\n        end\n        return act\n\n      else\n        raise \"[Racc Bug] unknown action #{act.inspect}\"\n      end\n\n      racc_next_state(@racc_state[-1], @racc_state) if @yydebug\n\n      nil\n    end\n\n    def _racc_do_reduce(arg, act)\n      action_table, action_check, action_default, action_pointer,\n      goto_table,   goto_check,   goto_default,   goto_pointer,\n      nt_base,      reduce_table, token_table,    shift_n,\n      reduce_n,     use_result,   * = arg\n      state = @racc_state\n      vstack = @racc_vstack\n      tstack = @racc_tstack\n\n      i = act * -3\n      len       = reduce_table[i]\n      reduce_to = reduce_table[i+1]\n      method_id = reduce_table[i+2]\n      void_array = []\n\n      tmp_t = tstack[-len, len] if @yydebug\n      tmp_v = vstack[-len, len]\n      tstack[-len, len] = void_array if @yydebug\n      vstack[-len, len] = void_array\n      state[-len, len]  = void_array\n\n      # tstack must be updated AFTER method call\n      if use_result\n        vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])\n      else\n        vstack.push __send__(method_id, tmp_v, vstack)\n      end\n      tstack.push reduce_to\n\n      racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug\n\n      k1 = reduce_to - nt_base\n      if i = goto_pointer[k1]\n        i += state[-1]\n        if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1\n          return curstate\n        end\n      end\n      goto_default[k1]\n    end\n\n    def on_error(t, val, vstack)\n      raise ParseError, sprintf(\"\\nparse error on value %s (%s)\",\n                                val.inspect, token_to_str(t) || '?')\n    end\n\n    def yyerror\n      throw :racc_jump, 1\n    end\n\n    def yyaccept\n      throw :racc_jump, 2\n    end\n\n    def yyerrok\n      @racc_error_status = 0\n    end\n\n    #\n    # for debugging output\n    #\n\n    def racc_read_token(t, tok, val)\n      @racc_debug_out.print 'read    '\n      @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '\n      @racc_debug_out.puts val.inspect\n      @racc_debug_out.puts\n    end\n\n    def racc_shift(tok, tstack, vstack)\n      @racc_debug_out.puts \"shift   #{racc_token2str tok}\"\n      racc_print_stacks tstack, vstack\n      @racc_debug_out.puts\n    end\n\n    def racc_reduce(toks, sim, tstack, vstack)\n      out = @racc_debug_out\n      out.print 'reduce '\n      if toks.empty?\n        out.print ' <none>'\n      else\n        toks.each {|t| out.print ' ', racc_token2str(t) }\n      end\n      out.puts \" --> #{racc_token2str(sim)}\"\n          \n      racc_print_stacks tstack, vstack\n      @racc_debug_out.puts\n    end\n\n    def racc_accept\n      @racc_debug_out.puts 'accept'\n      @racc_debug_out.puts\n    end\n\n    def racc_e_pop(state, tstack, vstack)\n      @racc_debug_out.puts 'error recovering mode: pop token'\n      racc_print_states state\n      racc_print_stacks tstack, vstack\n      @racc_debug_out.puts\n    end\n\n    def racc_next_state(curstate, state)\n      @racc_debug_out.puts  \"goto    #{curstate}\"\n      racc_print_states state\n      @racc_debug_out.puts\n    end\n\n    def racc_print_stacks(t, v)\n      out = @racc_debug_out\n      out.print '        ['\n      t.each_index do |i|\n        out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'\n      end\n      out.puts ' ]'\n    end\n\n    def racc_print_states(s)\n      out = @racc_debug_out\n      out.print '        ['\n      s.each {|st| out.print ' ', st }\n      out.puts ' ]'\n    end\n\n    def racc_token2str(tok)\n      self.class::Racc_token_to_s_table[tok] or\n          raise \"[Racc Bug] can't convert token #{tok} to string\"\n    end\n\n    def token_to_str(t)\n      self.class::Racc_token_to_s_table[t]\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/README",
    "content": "= RDOC - Ruby Documentation System\n\nThis package contains Rdoc and SimpleMarkup. Rdoc is an application\nthat produces documentation for one or more Ruby source files. We work\nsimilarly to JavaDoc, parsing the source, and extracting the\ndefinition for classes, modules, and methods (along with includes and\nrequires).  We associate with these optional documentation contained\nin the immediately preceding comment block, and then render the result\nusing a pluggable output formatter. (Currently, HTML is the only\nsupported format. Markup is a library that converts plain text into\nvarious output formats. The Markup library is used to interpret the\ncomment blocks that Rdoc uses to document methods, classes, and so on.\n\nThis library contains two packages, rdoc itself and a text markup\nlibrary, 'markup'. \n\n== Roadmap\n\n* If you want to use Rdoc to create documentation for your Ruby source\n  files, read on.\n* If you want to include extensions written in C, see rdoc/parsers/parse_c.rb.\n* For information on the various markups available in comment\n  blocks, see markup/simple_markup.rb.\n* If you want to drive Rdoc programatically, see RDoc::RDoc.\n* If you want to use the library to format text blocks into HTML,\n  have a look at SM::SimpleMarkup.\n* If you want to try writing your own HTML output template, see\n  RDoc::Page.\n\n== Summary\n\nOnce installed, you can create documentation using the 'rdoc' command\n(the command is 'rdoc.bat' under Windows)\n\n  % rdoc [options]  [names...]\n\nType \"rdoc --help\" for an up-to-date option summary.\n\nA typical use might be to generate documentation for a package of Ruby\nsource (such as rdoc itself). \n\n  % rdoc\n\nThis command generates documentation for all the Ruby and C source\nfiles in and below the current directory. These will be stored in a\ndocumentation tree starting in the subdirectory 'doc'.\n\nYou can make this slightly more useful for your readers by having the\nindex page contain the documentation for the primary file. In our\ncase, we could type\n\n  % rdoc --main rdoc/rdoc.rb\n\nYou'll find information on the various formatting tricks you can use\nin comment blocks in the documentation this generates.\n\nRDoc uses file extensions to determine how to process each file. File\nnames ending <tt>.rb</tt> and <tt>.rbw</tt> are assumed to be Ruby\nsource. Files ending <tt>.c</tt> are parsed as C files. All other\nfiles are assumed to contain just SimpleMarkup-style markup (with or\nwithout leading '#' comment markers). If directory names are passed to\nRDoc, they are scanned recursively for C and Ruby source files only.\n\n== Credits\n\n* The Ruby parser in rdoc/parse.rb is based heavily on the outstanding\n  work of Keiju ISHITSUKA of Nippon Rational Inc, who produced the Ruby\n  parser for irb and the rtags package.\n\n* Code to diagram classes and modules was written by Sergey A Yanovitsky\n  (Jah) of Enticla. \n\n* Charset patch from MoonWolf.\n\n* Rich Kilmer wrote the kilmer.rb output template.\n\n* Dan Brickley led the design of the RDF format.\n\n== License\n\nRDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers.  It\nis free software, and may be redistributed under the terms specified\nin the README file of the Ruby distribution.\n\n= Usage\n\nRDoc is invoked from the command line using:\n\n   % rdoc <options> [name...]\n\nFiles are parsed, and the information they contain collected, before\nany output is produced. This allows cross references between all files\nto be resolved. If a name is a directory, it is traversed. If no\nnames are specified, all Ruby files in the current directory (and\nsubdirectories) are processed.\n\nOptions are:\n\n[<tt>--accessor</tt> <i>name[,name...]</i>]\n    specifies the name(s) of additional methods that should be treated\n    as if they were <tt>attr_</tt><i>xxx</i> methods. Specifying\n    \"--accessor db_opt\" means lines such as\n\n         db_opt :name, :age\n  \n    will get parsed and displayed in the documentation. Each name may have an\n    optional \"=flagtext\" appended, in which case the given flagtext will appear\n    where (for example) the 'rw' appears for attr_accessor.\n\n[<tt>--all</tt>]\n    include protected and private methods in the output (by default\n    only public methods are included)\n\n[<tt>--charset</tt> _charset_]\n    Set the character set for the generated HTML.\n\n[<tt>--diagram</tt>]\n    include diagrams showing modules and classes.  This is currently\n    an experimental feature, and may not be supported by all output\n    templates. You need dot V1.8.6 or later to use the --diagram\n    option correctly (http://www.research.att.com/sw/tools/graphviz/).\n\n[<tt>--exclude</tt> <i>pattern</i>]\n    exclude files and directories matching this pattern from processing\n\n[<tt>--extension</tt> <i>new=old</i>]\n    treat files ending <i>.new</i> as if they ended\n    <i>.old</i>. Saying '--extension cgi=rb' causes RDoc to treat .cgi\n    files as Ruby source.\n\n[<tt>fileboxes</tt>]\n    Classes are put in boxes which represents files, where these\n    classes reside. Classes shared between more than one file are\n    shown with list of files that sharing them.  Silently discarded if\n    --diagram is not given Experimental.\n\n[<tt>--fmt</tt> _fmt_]\n    generate output in a particular format.\n\n[<tt>--help</tt>]\n    generate a usage summary.\n\n[<tt>--help-output</tt>]\n    explain the various output options.\n\n[<tt>--image-format</tt> <i>gif/png/jpg/jpeg</i>]\n    sets output image format for diagrams. Can be png, gif, jpeg,\n    jpg. If this option is omitted, png is used. Requires --diagram.\n\n[<tt>--include</tt> <i>dir,...</i>]\n    specify one or more directories to be searched when satisfying\n    :+include+: directives. Multiple <tt>--include</tt> options may be\n    given. The directory containing the file currently being processed\n    is always searched.\n\n[<tt>--inline-source</tt>]\n    By default, the source code of methods is shown in a popup. With\n    this option, it's displayed inline.\n\n[<tt>line-numbers</tt>]\n    include line numbers in the source code\n\n[<tt>--main</tt> _name_]\n    the class of module _name_ will appear on the index page. If you\n    want to set a particular file as a main page (a README, for\n    example) simply specifiy its name as the first on the command\n    line.\n\n[<tt>--merge</tt>]\n    when generating _ri_ output, if classes being processed already\n    exist in the destination directory, merge in the current details\n    rather than overwrite them.\n\n[<tt>--one-file</tt>]\n    place all the output into a single file\n\n[<tt>--op</tt> _dir_]\n    set the output directory to _dir_ (the default is the directory\n    \"doc\")\n\n[<tt>--op-name</tt> _name_]\n    set the name of the output. Has no effect for HTML.\n    \"doc\")\n\n[<tt>--opname</tt> _name_]\n    set the output name (has no effect for HTML).\n\n[<tt>--promiscuous</tt>]\n    If a module or class is defined in more than one source file, and\n    you click on a particular file's name in the top navigation pane,\n    RDoc will normally only show you the inner classes and modules of\n    that class that are defined in the particular file. Using this\n    option makes it show all classes and modules defined in the class,\n    regardless of the file they were defined in.\n\n[<tt>--quiet</tt>]\n    do not display progress messages\n\n[<tt>--ri</tt>, <tt>--ri-site</tt>, _and_ <tt>--ri-system</tt>]\n    generate output than can be read by the _ri_ command-line tool.\n    By default --ri places its output in ~/.rdoc, --ri-site in\n    $datadir/ri/<ver>/site, and --ri-system in\n    $datadir/ri/<ver>/system. All can be overridden with a subsequent\n    --op option. All default directories are in ri's default search\n    path.\n\n[<tt>--show-hash</tt>]\n    A name of the form #name in a comment is a possible hyperlink to\n    an instance method name. When displayed, the '#' is removed unless\n    this option is specified\n\n[<tt>--style</tt> <i>stylesheet url</i>]\n    specifies the URL of an external stylesheet to use (rather than\n    generating one of our own)\n\n[<tt>tab-width</tt> _n_]\n    set the width of tab characters (default 8)\n\n[<tt>--template</tt> <i>name</i>]\n    specify an alternate template to use when generating output (the\n    default is 'standard'). This template should be in a directory\n    accessible via $: as rdoc/generators/xxxx_template, where 'xxxx'\n    depends on the output formatter.\n\n[<tt>--version</tt>]\n   display  RDoc's version\n\n[<tt>--webcvs</tt> _url_]\n    Specify a URL for linking to a web frontend to CVS. If the URL\n    contains a '\\%s', the name of the current file will be\n    substituted; if the URL doesn't contain a '\\%s', the filename will\n    be appended to it.\n\n= Example\n\nA typical small Ruby program commented using RDoc might be as follows. You\ncan see the formatted result in EXAMPLE.rb and Anagram.\n\n      :include: EXAMPLE.rb\n\n= Markup\n\nComment blocks can be written fairly naturally, either using '#' on\nsuccessive lines of the comment, or by including the comment in \nan =begin/=end block. If you use the latter form, the =begin line\nmust be flagged with an RDoc tag:\n\n  =begin rdoc\n  Documentation to \n  be processed by RDoc.\n  =end\n\nParagraphs are lines that share the left margin. Text indented past\nthis margin are formatted verbatim.\n\n1. Lists are typed as indented paragraphs with:\n   * a '*' or '-' (for bullet lists)\n   * a digit followed by a period for \n     numbered lists\n   * an upper or lower case letter followed\n     by a period for alpha lists.\n\n   For example, the input that produced the above paragraph looked like\n       1. Lists are typed as indented \n          paragraphs with:\n          * a '*' or '-' (for bullet lists)\n          * a digit followed by a period for \n            numbered lists\n          * an upper or lower case letter followed\n            by a period for alpha lists.\n\n2. Labeled lists (sometimes called description\n   lists) are typed using square brackets for the label.\n      [cat]   small domestic animal\n      [+cat+] command to copy standard input\n\n3. Labeled lists may also be produced by putting a double colon\n   after the label. This sets the result in tabular form, so the\n   descriptions all line up. This was used to create the 'author'\n   block at the bottom of this description.\n      cat::   small domestic animal\n      +cat+:: command to copy standard input\n\n   For both kinds of labeled lists, if the body text starts on the same\n   line as the label, then the start of that text determines the block\n   indent for the rest of the body. The text may also start on the line\n   following the label, indented from the start of the label. This is\n   often preferable if the label is long. Both the following are\n   valid labeled list entries:\n\n      <tt>--output</tt> <i>name [, name]</i>::\n          specify the name of one or more output files. If multiple\n          files are present, the first is used as the index.\n\n      <tt>--quiet:</tt>:: do not output the names, sizes, byte counts,\n                          index areas, or bit ratios of units as\n                          they are processed.\n\n4. Headings are entered using equals signs\n\n      = Level One Heading\n      == Level Two Heading\n   and so on\n\n5. Rules (horizontal lines) are entered using three or\n   more hyphens.\n\n6. Non-verbatim text can be marked up:\n\n   _italic_::     \\_word_ or \\<em>text</em>\n   *bold*::       \\*word* or \\<b>text</b>\n   +typewriter+:: \\+word+ or \\<tt>text</tt>\n\n   The first form only works around 'words', where a word is a\n   sequence of upper and lower case letters and underscores. Putting a\n   backslash before inline markup stops it being interpreted, which is\n   how I created the table above:\n\n     _italic_::     \\_word_ or \\<em>text</em>\n     *bold*::       \\*word* or \\<b>text</b>\n     +typewriter+:: \\+word+ or \\<tt>text</tt>\n\n7. Names of classes, source files, and any method names\n   containing an underscore or preceded by a hash\n   character are automatically hyperlinked from\n   comment text to their description. \n\n8. Hyperlinks to the web starting http:, mailto:, ftp:, or www. are\n   recognized. An HTTP url that references an external image file is\n   converted into an inline <IMG..>.  Hyperlinks starting 'link:' are\n   assumed to refer to local files whose path is relative to the --op\n   directory.\n\n   Hyperlinks can also be of the form <tt>label</tt>[url], in which\n   case the label is used in the displayed text, and <tt>url</tt> is\n   used as the target. If <tt>label</tt> contains multiple words,\n   put it in braces: <em>{multi word label}[</em>url<em>]</em>.\n       \n9. Method parameter lists are extracted and displayed with\n   the method description. If a method calls +yield+, then\n   the parameters passed to yield will also be displayed:\n\n      def fred\n        ...\n        yield line, address\n\n   This will get documented as\n\n      fred() { |line, address| ... }\n\n   You can override this using a comment containing \n   ':yields: ...' immediately after the method definition\n\n      def fred      # :yields: index, position\n        ...\n        yield line, address\n\n   which will get documented as\n\n       fred() { |index, position| ... }\n\n\n10. ':yields:' is an example of a documentation modifier. These appear\n    immediately after the start of the document element they are modifying.\n    Other modifiers include\n\n    [<tt>:nodoc:</tt><i>[all]</i>]\n         don't include this element in the documentation.  For classes\n         and modules, the methods, aliases, constants, and attributes\n         directly within the affected class or module will also be\n         omitted.  By default, though, modules and classes within that\n         class of module _will_ be documented. This is turned off by\n         adding the +all+ modifier.\n\n              module SM  #:nodoc:\n                class Input\n                end\n              end\n              module Markup #:nodoc: all\n                class Output\n                end\n              end\n\n         In the above code, only class <tt>SM::Input</tt> will be\n         documented.\n\n    [<tt>:doc:</tt>]\n         force a method or attribute to be documented even if it\n         wouldn't otherwise be. Useful if, for example, you want to\n         include documentation of a particular private method.\n\n    [<tt>:notnew:</tt>]\n         only applicable to the +initialize+ instance method. Normally\n         RDoc assumes that the documentation and parameters for\n         #initialize are actually for the ::new method, and so fakes\n         out a ::new for the class. THe :notnew: modifier stops\n         this. Remember that #initialize is protected, so you won't\n         see the documentation unless you use the -a command line\n         option.\n\n\n11. RDoc stops processing comments if it finds a comment\n    line containing '<tt>#--</tt>'. This can be used to \n    separate external from internal comments, or \n    to stop a comment being associated with a method, \n    class, or module. Commenting can be turned back on with\n    a line that starts '<tt>#++</tt>'.\n\n        # Extract the age and calculate the\n        # date-of-birth.\n        #--\n        # FIXME: fails if the birthday falls on\n        # February 29th\n        #++\n        # The DOB is returned as a Time object.\n\n        def get_dob(person)\n           ...\n\n12. Comment blocks can contain other directives:\n\n    [<tt>:section: title</tt>]\n        Starts a new section in the output. The title following\n\t<tt>:section:</tt> is used as the section heading, and the\n\tremainder of the comment containing the section is used as\n\tintroductory text. Subsequent methods, aliases, attributes,\n\tand classes will be documented in this section. A :section:\n\tcomment block may have one or more lines before the :section:\n\tdirective. These will be removed, and any identical lines at\n\tthe end of the block are also removed. This allows you to add\n\tvisual cues such as\n\n           # ----------------------------------------\n\t   # :section: My Section\n\t   # This is the section that I wrote.\n\t   # See it glisten in the noon-day sun.\n           # ----------------------------------------\n\n    [<tt>call-seq:</tt>]\n        lines up to the next blank line in the comment are treated as\n        the method's calling sequence, overriding the\n        default parsing of method parameters and yield arguments.\n\n    [<tt>:include:</tt><i>filename</i>] \n         include the contents of the named file at this point. The\n         file will be searched for in the directories listed by\n         the <tt>--include</tt> option, or in the current\n         directory by default.  The contents of the file will be\n         shifted to have the same indentation as the ':' at the\n         start of the :include: directive.\n\n    [<tt>:title:</tt><i>text</i>]\n         Sets the title for the document. Equivalent to the --title command\n         line parameter. (The command line parameter overrides any :title:\n         directive in the source).\n\n    [<tt>:enddoc:</tt>]\n         Document nothing further at the current level.\n\n    [<tt>:main:</tt><i>name</i>]\n         Equivalent to the --main command line parameter.\n\n    [<tt>:stopdoc: / :startdoc:</tt>]\n         Stop and start adding new documentation elements to the\n         current container. For example, if a class has a number of\n         constants that you don't want to document, put a\n         <tt>:stopdoc:</tt> before the first, and a\n         <tt>:startdoc:</tt> after the last. If you don't specifiy a\n         <tt>:startdoc:</tt> by the end of the container, disables\n         documentation for the entire class or module.\n\n\n---\n\nSee also markup/simple_markup.rb.\n\n= Other stuff\n\nAuthor::   Dave Thomas <dave@pragmaticprogrammer.com>\nRequires:: Ruby 1.8.1 or later\nLicense::  Copyright (c) 2001-2003 Dave Thomas.\n           Released under the same license as Ruby.\n\n== Warranty\n\nThis software is provided \"as is\" and without any express or\nimplied warranties, including, without limitation, the implied\nwarranties of merchantibility and fitness for a particular\npurpose.\n"
  },
  {
    "path": "lib/rdoc/code_objects.rb",
    "content": "# We represent the various high-level code constructs that appear\n# in Ruby programs: classes, modules, methods, and so on.\n\nrequire 'rdoc/tokenstream'\n\nmodule RDoc\n\n\n  # We contain the common stuff for contexts (which are containers)\n  # and other elements (methods, attributes and so on)\n  #\n  class CodeObject\n\n    attr_accessor :parent\n\n    # We are the model of the code, but we know that at some point\n    # we will be worked on by viewers. By implementing the Viewable\n    # protocol, viewers can associated themselves with these objects.\n\n    attr_accessor :viewer\n\n    # are we done documenting (ie, did we come across a :enddoc:)?\n\n    attr_accessor :done_documenting\n\n    # Which section are we in\n\n    attr_accessor :section\n\n    # do we document ourselves?\n\n    attr_reader :document_self\n\n    def document_self=(val)\n      @document_self = val\n      if !val\n\tremove_methods_etc\n      end\n    end\n\n    # set and cleared by :startdoc: and :enddoc:, this is used to toggle\n    # the capturing of documentation\n    def start_doc\n      @document_self = true\n      @document_children = true\n    end\n\n    def stop_doc\n      @document_self = false\n      @document_children = false\n    end\n\n    # do we document ourselves and our children\n\n    attr_reader :document_children\n\n    def document_children=(val)\n      @document_children = val\n      if !val\n\tremove_classes_and_modules\n      end\n    end\n\n    # Do we _force_ documentation, even is we wouldn't normally show the entity\n    attr_accessor :force_documentation\n\n    # Default callbacks to nothing, but this is overridden for classes\n    # and modules\n    def remove_classes_and_modules\n    end\n\n    def remove_methods_etc\n    end\n\n    def initialize\n      @document_self = true\n      @document_children = true\n      @force_documentation = false\n      @done_documenting = false\n    end\n\n    # Access the code object's comment\n    attr_reader :comment\n\n    # Update the comment, but don't overwrite a real comment\n    # with an empty one\n    def comment=(comment)\n      @comment = comment unless comment.empty?\n    end\n\n    # There's a wee trick we pull. Comment blocks can have directives that\n    # override the stuff we extract during the parse. So, we have a special\n    # class method, attr_overridable, that lets code objects list\n    # those directives. Wehn a comment is assigned, we then extract\n    # out any matching directives and update our object\n\n    def CodeObject.attr_overridable(name, *aliases)\n      @overridables ||= {}\n\n      attr_accessor name\n\n      aliases.unshift name\n      aliases.each do |directive_name|\n        @overridables[directive_name.to_s] = name\n      end\n    end\n\n  end\n\n  # A Context is something that can hold modules, classes, methods, \n  # attributes, aliases, requires, and includes. Classes, modules, and\n  # files are all Contexts.\n\n  class Context < CodeObject\n    attr_reader   :name, :method_list, :attributes, :aliases, :constants\n    attr_reader   :requires, :includes, :in_files, :visibility\n\n    attr_reader   :sections\n\n    class Section\n      attr_reader :title, :comment, :sequence\n\n      @@sequence = \"SEC00000\"\n\n      def initialize(title, comment)\n        @title = title\n        @@sequence.succ!\n        @sequence = @@sequence.dup\n        set_comment(comment)\n      end\n\n      private\n\n      # Set the comment for this section from the original comment block\n      # If the first line contains :section:, strip it and use the rest. Otherwise\n      # remove lines up to the line containing :section:, and look for \n      # those lines again at the end and remove them. This lets us write\n      #\n      #   # ---------------------\n      #   # :SECTION: The title\n      #   # The body\n      #   # ---------------------\n\n      def set_comment(comment)\n        return unless comment\n\n        if comment =~ /^.*?:section:.*$/\n          start = $`\n          rest = $'\n          if start.empty?\n            @comment = rest\n          else\n            @comment = rest.sub(/#{start.chomp}\\Z/, '')\n          end\n        else\n          @comment = comment\n        end\n        @comment = nil if @comment.empty?\n      end\n    end\n\n\n    def initialize\n      super()\n\n      @in_files    = []\n\n      @name    ||= \"unknown\"\n      @comment ||= \"\"\n      @parent  = nil\n      @visibility = :public\n\n      @current_section = Section.new(nil, nil)\n      @sections = [ @current_section ]\n\n      initialize_methods_etc\n      initialize_classes_and_modules\n    end\n\n    # map the class hash to an array externally\n    def classes\n      @classes.values\n    end\n\n    # map the module hash to an array externally\n    def modules\n      @modules.values\n    end\n\n    # Change the default visibility for new methods\n    def ongoing_visibility=(vis)\n      @visibility = vis\n    end\n\n    # Given an array +methods+ of method names, set the\n    # visibility of the corresponding AnyMethod object\n\n    def set_visibility_for(methods, vis, singleton=false)\n      count = 0\n      @method_list.each do |m|\n        if methods.include?(m.name) && m.singleton == singleton\n          m.visibility = vis\n          count += 1\n        end\n      end\n\n      return if count == methods.size || singleton\n\n      # perhaps we need to look at attributes\n\n      @attributes.each do |a|\n        if methods.include?(a.name)\n          a.visibility = vis\n          count += 1\n        end\n      end\n    end\n\n    # Record the file that we happen to find it in\n    def record_location(toplevel)\n      @in_files << toplevel unless @in_files.include?(toplevel)\n    end\n\n    # Return true if at least part of this thing was defined in +file+\n    def defined_in?(file)\n      @in_files.include?(file)\n    end\n\n    def add_class(class_type, name, superclass)\n      add_class_or_module(@classes, class_type, name, superclass)\n    end\n\n    def add_module(class_type, name)\n      add_class_or_module(@modules, class_type, name, nil)\n    end\n\n    def add_method(a_method)\n      puts \"Adding #@visibility method #{a_method.name} to #@name\" if $DEBUG\n      a_method.visibility = @visibility\n      add_to(@method_list, a_method)\n    end\n\n    def add_attribute(an_attribute)\n      add_to(@attributes, an_attribute)\n    end\n\n    def add_alias(an_alias)\n      meth = find_instance_method_named(an_alias.old_name)\n      if meth\n        new_meth = AnyMethod.new(an_alias.text, an_alias.new_name)\n        new_meth.is_alias_for = meth\n        new_meth.singleton    = meth.singleton\n        new_meth.params       = meth.params\n        new_meth.comment = \"Alias for \\##{meth.name}\"\n        meth.add_alias(new_meth)\n        add_method(new_meth)\n      else\n        add_to(@aliases, an_alias)\n      end\n    end\n\n    def add_include(an_include)\n      add_to(@includes, an_include)\n    end\n\n    def add_constant(const)\n      add_to(@constants, const)\n    end\n\n    # Requires always get added to the top-level (file) context\n    def add_require(a_require)\n      if self.kind_of? TopLevel\n        add_to(@requires, a_require)\n      else\n        parent.add_require(a_require)\n      end\n    end\n\n    def add_class_or_module(collection, class_type, name, superclass=nil)\n      cls = collection[name]\n      if cls\n        puts \"Reusing class/module #{name}\" if $DEBUG\n      else\n        cls = class_type.new(name, superclass)\n        puts \"Adding class/module #{name} to #@name\" if $DEBUG\n#        collection[name] = cls if @document_self  && !@done_documenting\n        collection[name] = cls if !@done_documenting\n        cls.parent = self\n        cls.section = @current_section\n      end\n      cls\n    end\n\n    def add_to(array, thing)\n      array <<  thing if @document_self  && !@done_documenting\n      thing.parent = self\n      thing.section = @current_section\n    end\n\n    # If a class's documentation is turned off after we've started\n    # collecting methods etc., we need to remove the ones\n    # we have\n\n    def remove_methods_etc\n      initialize_methods_etc\n    end\n\n    def initialize_methods_etc\n      @method_list = []\n      @attributes  = []\n      @aliases     = []\n      @requires    = []\n      @includes    = []\n      @constants   = []\n    end\n\n    # and remove classes and modules when we see a :nodoc: all\n    def remove_classes_and_modules\n      initialize_classes_and_modules\n    end\n\n    def initialize_classes_and_modules\n      @classes     = {}\n      @modules     = {}\n    end\n\n    # Find a named module\n    def find_module_named(name)\n      return self if self.name == name\n      res = @modules[name] || @classes[name]\n      return res if res\n      find_enclosing_module_named(name)\n    end\n\n    # find a module at a higher scope\n    def find_enclosing_module_named(name)\n      parent && parent.find_module_named(name)\n    end\n\n    # Iterate over all the classes and modules in\n    # this object\n\n    def each_classmodule\n      @modules.each_value {|m| yield m}\n      @classes.each_value {|c| yield c}\n    end\n\n    def each_method\n      @method_list.each {|m| yield m}\n    end\n\n    def each_attribute \n      @attributes.each {|a| yield a}\n    end\n\n    def each_constant\n      @constants.each {|c| yield c}\n    end\n\n    # Return the toplevel that owns us\n\n    def toplevel\n      return @toplevel if defined? @toplevel\n      @toplevel = self\n      @toplevel = @toplevel.parent until TopLevel === @toplevel\n      @toplevel\n    end\n\n    # allow us to sort modules by name\n    def <=>(other)\n      name <=> other.name\n    end\n\n    # Look up the given symbol. If method is non-nil, then\n    # we assume the symbol references a module that\n    # contains that method\n    def find_symbol(symbol, method=nil)\n      result = nil\n      case symbol\n      when /^::(.*)/\n        result = toplevel.find_symbol($1)\n      when /::/\n        modules = symbol.split(/::/)\n        unless modules.empty?\n          module_name = modules.shift\n          result = find_module_named(module_name)\n          if result\n            modules.each do |module_name|\n              result = result.find_module_named(module_name)\n              break unless result\n            end\n          end\n        end\n      else\n        # if a method is specified, then we're definitely looking for\n        # a module, otherwise it could be any symbol\n        if method\n          result = find_module_named(symbol)\n        else\n          result = find_local_symbol(symbol)\n          if result.nil?\n            if symbol =~ /^[A-Z]/\n              result = parent\n              while result && result.name != symbol\n                result = result.parent\n              end\n            end\n          end\n        end\n      end\n      if result && method\n        if !result.respond_to?(:find_local_symbol)\n          p result.name\n          p method\n          fail\n        end\n        result = result.find_local_symbol(method)\n      end\n      result\n    end\n           \n    def find_local_symbol(symbol)\n      res = find_method_named(symbol) ||\n            find_constant_named(symbol) ||\n            find_attribute_named(symbol) ||\n            find_module_named(symbol) \n    end\n\n    # Handle sections\n\n    def set_current_section(title, comment)\n      @current_section = Section.new(title, comment)\n      @sections << @current_section\n    end\n\n    private\n\n    # Find a named method, or return nil\n    def find_method_named(name)\n      @method_list.find {|meth| meth.name == name}\n    end\n\n    # Find a named instance method, or return nil\n    def find_instance_method_named(name)\n      @method_list.find {|meth| meth.name == name && !meth.singleton}\n    end\n\n    # Find a named constant, or return nil\n    def find_constant_named(name)\n      @constants.find {|m| m.name == name}\n    end\n\n    # Find a named attribute, or return nil\n    def find_attribute_named(name)\n      @attributes.find {|m| m.name == name}\n    end\n    \n  end\n\n\n  # A TopLevel context is a source file\n\n  class TopLevel < Context\n    attr_accessor :file_stat\n    attr_accessor :file_relative_name\n    attr_accessor :file_absolute_name\n    attr_accessor :diagram\n    \n    @@all_classes = {}\n    @@all_modules = {}\n\n    def TopLevel::reset\n      @@all_classes = {}\n      @@all_modules = {}\n    end\n\n    def initialize(file_name)\n      super()\n      @name = \"TopLevel\"\n      @file_relative_name = file_name\n      @file_absolute_name = file_name\n      @file_stat          = File.stat(file_name)\n      @diagram            = nil\n    end\n\n    def full_name\n      nil\n    end\n\n    # Adding a class or module to a TopLevel is special, as we only\n    # want one copy of a particular top-level class. For example,\n    # if both file A and file B implement class C, we only want one\n    # ClassModule object for C. This code arranges to share\n    # classes and modules between files.\n\n    def add_class_or_module(collection, class_type, name, superclass)\n      cls = collection[name]\n      if cls\n        puts \"Reusing class/module #{name}\" if $DEBUG\n      else\n        if class_type == NormalModule\n          all = @@all_modules\n        else\n          all = @@all_classes\n        end\n        cls = all[name]\n        if !cls\n          cls = class_type.new(name, superclass)\n          all[name] = cls  unless @done_documenting\n        end\n        puts \"Adding class/module #{name} to #@name\" if $DEBUG\n        collection[name] = cls unless @done_documenting\n        cls.parent = self\n      end\n      cls\n    end\n\n    def TopLevel.all_classes_and_modules\n      @@all_classes.values + @@all_modules.values\n    end\n\n    def TopLevel.find_class_named(name)\n     @@all_classes.each_value do |c|\n        res = c.find_class_named(name) \n        return res if res\n      end\n      nil\n    end\n\n    def find_local_symbol(symbol)\n      find_class_or_module_named(symbol) || super\n    end\n\n    def find_class_or_module_named(symbol)\n      @@all_classes.each_value {|c| return c if c.name == symbol}\n      @@all_modules.each_value {|m| return m if m.name == symbol}\n      nil\n    end\n\n    # Find a named module\n    def find_module_named(name)\n      find_class_or_module_named(name) || find_enclosing_module_named(name)\n    end\n\n\n  end\n\n  # ClassModule is the base class for objects representing either a\n  # class or a module.\n\n  class ClassModule < Context\n\n    attr_reader   :superclass\n    attr_accessor :diagram\n\n    def initialize(name, superclass = nil)\n      @name       = name\n      @diagram    = nil\n      @superclass = superclass\n      @comment    = \"\"\n      super()\n    end\n\n    # Return the fully qualified name of this class or module\n    def full_name\n      if @parent && @parent.full_name\n        @parent.full_name + \"::\" + @name\n      else\n        @name\n      end\n    end\n\n    def http_url(prefix)\n      path = full_name.split(\"::\")\n      File.join(prefix, *path) + \".html\"\n    end\n\n    # Return +true+ if this object represents a module\n    def is_module?\n      false\n    end\n\n    # to_s is simply for debugging\n    def to_s\n      res = self.class.name + \": \" + @name \n      res << @comment.to_s\n      res << super\n      res\n    end\n\n    def find_class_named(name)\n      return self if full_name == name\n      @classes.each_value {|c| return c if c.find_class_named(name) }\n      nil\n    end\n  end\n\n  # Anonymous classes\n  class AnonClass < ClassModule\n  end\n\n  # Normal classes\n  class NormalClass < ClassModule\n  end\n\n  # Singleton classes\n  class SingleClass < ClassModule\n  end\n\n  # Module\n  class NormalModule < ClassModule\n    def is_module?\n      true\n    end\n  end\n\n\n  # AnyMethod is the base class for objects representing methods\n\n  class AnyMethod < CodeObject\n    attr_accessor :name\n    attr_accessor :visibility\n    attr_accessor :block_params\n    attr_accessor :dont_rename_initialize\n    attr_accessor :singleton\n    attr_reader   :aliases           # list of other names for this method\n    attr_accessor :is_alias_for      # or a method we're aliasing\n\n    attr_overridable :params, :param, :parameters, :parameter\n\n    attr_accessor :call_seq\n\n\n    include TokenStream\n\n    def initialize(text, name)\n      super()\n      @text = text\n      @name = name\n      @token_stream  = nil\n      @visibility    = :public\n      @dont_rename_initialize = false\n      @block_params  = nil\n      @aliases       = []\n      @is_alias_for  = nil\n      @comment = \"\"\n      @call_seq = nil\n    end\n\n    def <=>(other)\n      @name <=> other.name\n    end\n\n    def to_s\n      res = self.class.name + \": \" + @name + \" (\" + @text + \")\\n\"\n      res << @comment.to_s\n      res\n    end\n\n    def param_seq\n      p = params.gsub(/\\s*\\#.*/, '')\n      p = p.tr(\"\\n\", \" \").squeeze(\" \")\n      p = \"(\" + p + \")\" unless p[0] == ?(\n\n      if (block = block_params)\n        # If this method has explicit block parameters, remove any\n        # explicit &block\n$stderr.puts p\n        p.sub!(/,?\\s*&\\w+/)\n$stderr.puts p\n\n        block.gsub!(/\\s*\\#.*/, '')\n        block = block.tr(\"\\n\", \" \").squeeze(\" \")\n        if block[0] == ?(\n          block.sub!(/^\\(/, '').sub!(/\\)/, '')\n        end\n        p << \" {|#{block}| ...}\"\n      end\n      p\n    end\n\n    def add_alias(method)\n      @aliases << method\n    end\n  end\n\n\n  # Represent an alias, which is an old_name/ new_name pair associated\n  # with a particular context\n  class Alias < CodeObject\n    attr_accessor :text, :old_name, :new_name, :comment\n    \n    def initialize(text, old_name, new_name, comment)\n      super()\n      @text = text\n      @old_name = old_name\n      @new_name = new_name\n      self.comment = comment\n    end\n\n    def to_s\n      \"alias: #{self.old_name} ->  #{self.new_name}\\n#{self.comment}\"\n    end\n  end\n\n  # Represent a constant\n  class Constant < CodeObject\n    attr_accessor :name, :value\n\n    def initialize(name, value, comment)\n      super()\n      @name = name\n      @value = value\n      self.comment = comment\n    end\n  end\n\n  # Represent attributes\n  class Attr < CodeObject\n    attr_accessor :text, :name, :rw, :visibility\n\n    def initialize(text, name, rw, comment)\n      super()\n      @text = text\n      @name = name\n      @rw = rw\n      @visibility = :public\n      self.comment = comment\n    end\n\n    def to_s\n      \"attr: #{self.name} #{self.rw}\\n#{self.comment}\"\n    end\n\n    def <=>(other)\n      self.name <=> other.name\n    end\n  end\n\n  # a required file\n\n  class Require < CodeObject\n    attr_accessor :name\n\n    def initialize(name, comment)\n      super()\n      @name = name.gsub(/'|\"/, \"\") #'\n      self.comment = comment\n    end\n\n  end\n\n  # an included module\n  class Include < CodeObject\n    attr_accessor :name\n\n    def initialize(name, comment)\n      super()\n      @name = name\n      self.comment = comment\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/diagram.rb",
    "content": "# A wonderful hack by to draw package diagrams using the dot package.\n# Originally written by  Jah, team Enticla.\n#\n# You must have the V1.7 or later in your path\n# http://www.research.att.com/sw/tools/graphviz/\n\nrequire \"rdoc/dot/dot\"\nrequire 'rdoc/options'\n\nmodule RDoc\n\n  # Draw a set of diagrams representing the modules and classes in the\n  # system. We draw one diagram for each file, and one for each toplevel\n  # class or module. This means there will be overlap. However, it also\n  # means that you'll get better context for objects.\n  #\n  # To use, simply\n  #\n  #   d = Diagram.new(info)   # pass in collection of top level infos\n  #   d.draw\n  #\n  # The results will be written to the +dot+ subdirectory. The process\n  # also sets the +diagram+ attribute in each object it graphs to\n  # the name of the file containing the image. This can be used\n  # by output generators to insert images.\n\n  class Diagram\n\n    FONT = \"Arial\"\n\n    DOT_PATH = \"dot\"\n\n    # Pass in the set of top level objects. The method also creates\n    # the subdirectory to hold the images\n\n    def initialize(info, options)\n      @info = info\n      @options = options\n      @counter = 0\n      File.makedirs(DOT_PATH)\n      @diagram_cache = {}\n    end\n\n    # Draw the diagrams. We traverse the files, drawing a diagram for\n    # each. We also traverse each top-level class and module in that\n    # file drawing a diagram for these too. \n\n    def draw\n      unless @options.quiet\n        $stderr.print \"Diagrams: \"\n        $stderr.flush\n      end\n\n      @info.each_with_index do |i, file_count|\n        @done_modules = {}\n        @local_names = find_names(i)\n        @global_names = []\n        @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel',\n                                    'fontname' => FONT,\n                                    'fontsize' => '8',\n                                    'bgcolor'  => 'lightcyan1',\n                                    'compound' => 'true')\n        \n        # it's a little hack %) i'm too lazy to create a separate class\n        # for default node\n        graph << DOT::DOTNode.new('name' => 'node',\n                                  'fontname' => FONT,\n                                  'color' => 'black',\n                                  'fontsize' => 8)\n        \n        i.modules.each do |mod|\n          draw_module(mod, graph, true, i.file_relative_name)\n        end\n        add_classes(i, graph, i.file_relative_name)\n\n        i.diagram = convert_to_png(\"f_#{file_count}\", graph)\n        \n        # now go through and document each top level class and\n        # module independently\n        i.modules.each_with_index do |mod, count|\n          @done_modules = {}\n          @local_names = find_names(mod)\n          @global_names = []\n\n          @global_graph = graph = DOT::DOTDigraph.new('name' => 'TopLevel',\n                                      'fontname' => FONT,\n                                      'fontsize' => '8',\n                                      'bgcolor'  => 'lightcyan1',\n                                      'compound' => 'true')\n\n          graph << DOT::DOTNode.new('name' => 'node',\n                                    'fontname' => FONT,\n                                    'color' => 'black',\n                                    'fontsize' => 8)\n          draw_module(mod, graph, true)\n          mod.diagram = convert_to_png(\"m_#{file_count}_#{count}\", \n                                       graph) \n        end\n      end\n      $stderr.puts unless @options.quiet\n    end\n\n    #######\n    private\n    #######\n\n    def find_names(mod)\n      return [mod.full_name] + mod.classes.collect{|cl| cl.full_name} +\n        mod.modules.collect{|m| find_names(m)}.flatten\n    end\n\n    def find_full_name(name, mod)\n      full_name = name.dup\n      return full_name if @local_names.include?(full_name)\n      mod_path = mod.full_name.split('::')[0..-2]\n      unless mod_path.nil?\n        until mod_path.empty?\n          full_name = mod_path.pop + '::' + full_name\n          return full_name if @local_names.include?(full_name)\n        end\n      end\n      return name\n    end\n\n    def draw_module(mod, graph, toplevel = false, file = nil)\n      return if  @done_modules[mod.full_name] and not toplevel\n\n      @counter += 1\n      url = mod.http_url(\"classes\")\n      m = DOT::DOTSubgraph.new('name' => \"cluster_#{mod.full_name.gsub( /:/,'_' )}\",\n                               'label' => mod.name,\n                               'fontname' => FONT,\n                               'color' => 'blue', \n                               'style' => 'filled', \n                               'URL'   => %{\"#{url}\"},\n                               'fillcolor' => toplevel ? 'palegreen1' : 'palegreen3')\n      \n      @done_modules[mod.full_name] = m\n      add_classes(mod, m, file)\n      graph << m\n\n      unless mod.includes.empty?\n        mod.includes.each do |m|\n          m_full_name = find_full_name(m.name, mod)\n          if @local_names.include?(m_full_name)\n            @global_graph << DOT::DOTEdge.new('from' => \"#{m_full_name.gsub( /:/,'_' )}\",\n                                      'to' => \"#{mod.full_name.gsub( /:/,'_' )}\",\n                                      'ltail' => \"cluster_#{m_full_name.gsub( /:/,'_' )}\",\n                                      'lhead' => \"cluster_#{mod.full_name.gsub( /:/,'_' )}\")\n          else\n            unless @global_names.include?(m_full_name)\n              path = m_full_name.split(\"::\")\n              url = File.join('classes', *path) + \".html\"\n              @global_graph << DOT::DOTNode.new('name' => \"#{m_full_name.gsub( /:/,'_' )}\",\n                                        'shape' => 'box',\n                                        'label' => \"#{m_full_name}\",\n                                        'URL'   => %{\"#{url}\"})\n              @global_names << m_full_name\n            end\n            @global_graph << DOT::DOTEdge.new('from' => \"#{m_full_name.gsub( /:/,'_' )}\",\n                                      'to' => \"#{mod.full_name.gsub( /:/,'_' )}\",\n                                      'lhead' => \"cluster_#{mod.full_name.gsub( /:/,'_' )}\")\n          end\n        end\n      end\n    end\n\n    def add_classes(container, graph, file = nil )\n\n      use_fileboxes = Options.instance.fileboxes\n\n      files = {}\n\n      # create dummy node (needed if empty and for module includes)\n      if container.full_name\n        graph << DOT::DOTNode.new('name'     => \"#{container.full_name.gsub( /:/,'_' )}\",\n                                  'label'    => \"\",\n                                  'width'  => (container.classes.empty? and \n                                               container.modules.empty?) ? \n                                  '0.75' : '0.01',\n                                  'height' => '0.01',\n                                  'shape' => 'plaintext')\n      end\n      container.classes.each_with_index do |cl, cl_index|\n        last_file = cl.in_files[-1].file_relative_name\n\n        if use_fileboxes && !files.include?(last_file)\n          @counter += 1\n          files[last_file] =\n            DOT::DOTSubgraph.new('name'     => \"cluster_#{@counter}\",\n                                 'label'    => \"#{last_file}\",\n                                 'fontname' => FONT,\n                                 'color'=>\n                                 last_file == file ? 'red' : 'black')\n        end\n\n        next if cl.name == 'Object' || cl.name[0,2] == \"<<\"\n\n        url = cl.http_url(\"classes\")\n        \n        label = cl.name.dup\n        if use_fileboxes && cl.in_files.length > 1\n          label <<  '\\n[' + \n                        cl.in_files.collect {|i|\n                             i.file_relative_name \n                        }.sort.join( '\\n' ) +\n                    ']'\n        end \n                \n        attrs = {\n          'name' => \"#{cl.full_name.gsub( /:/, '_' )}\",\n          'fontcolor' => 'black',\n          'style'=>'filled',\n          'color'=>'palegoldenrod',\n          'label' => label,\n          'shape' => 'ellipse',\n          'URL'   => %{\"#{url}\"}\n        }\n\n        c = DOT::DOTNode.new(attrs)\n        \n        if use_fileboxes\n          files[last_file].push c \n        else\n          graph << c\n        end\n      end\n      \n      if use_fileboxes\n        files.each_value do |val|\n          graph << val\n        end\n      end\n      \n      unless container.classes.empty?\n        container.classes.each_with_index do |cl, cl_index|\n          cl.includes.each do |m|\n            m_full_name = find_full_name(m.name, cl)\n            if @local_names.include?(m_full_name)\n              @global_graph << DOT::DOTEdge.new('from' => \"#{m_full_name.gsub( /:/,'_' )}\",\n                                      'to' => \"#{cl.full_name.gsub( /:/,'_' )}\",\n                                      'ltail' => \"cluster_#{m_full_name.gsub( /:/,'_' )}\")\n            else\n              unless @global_names.include?(m_full_name)\n                path = m_full_name.split(\"::\")\n                url = File.join('classes', *path) + \".html\"\n                @global_graph << DOT::DOTNode.new('name' => \"#{m_full_name.gsub( /:/,'_' )}\",\n                                          'shape' => 'box',\n                                          'label' => \"#{m_full_name}\",\n                                          'URL'   => %{\"#{url}\"})\n                @global_names << m_full_name\n              end\n              @global_graph << DOT::DOTEdge.new('from' => \"#{m_full_name.gsub( /:/,'_' )}\",\n                                      'to' => \"#{cl.full_name.gsub( /:/, '_')}\")\n            end\n          end\n\n          sclass = cl.superclass\n          next if sclass.nil? || sclass == 'Object'\n          sclass_full_name = find_full_name(sclass,cl)\n          unless @local_names.include?(sclass_full_name) or @global_names.include?(sclass_full_name)\n            path = sclass_full_name.split(\"::\")\n            url = File.join('classes', *path) + \".html\"\n            @global_graph << DOT::DOTNode.new(\n                       'name' => \"#{sclass_full_name.gsub( /:/, '_' )}\",\n                       'label' => sclass_full_name,\n                       'URL'   => %{\"#{url}\"})\n            @global_names << sclass_full_name\n          end\n          @global_graph << DOT::DOTEdge.new('from' => \"#{sclass_full_name.gsub( /:/,'_' )}\",\n                                    'to' => \"#{cl.full_name.gsub( /:/, '_')}\")\n        end\n      end\n\n      container.modules.each do |submod|\n        draw_module(submod, graph)\n      end\n      \n    end\n\n    def convert_to_png(file_base, graph)\n      str = graph.to_s\n      return @diagram_cache[str] if @diagram_cache[str]\n      op_type = Options.instance.image_format\n      dotfile = File.join(DOT_PATH, file_base)\n      src = dotfile + \".dot\"\n      dot = dotfile + \".\" + op_type\n\n      unless @options.quiet\n        $stderr.print \".\"\n        $stderr.flush\n      end\n\n      File.open(src, 'w+' ) do |f|\n        f << str << \"\\n\"\n      end\n      \n      system \"dot\", \"-T#{op_type}\", src, \"-o\", dot\n\n      # Now construct the imagemap wrapper around\n      # that png\n\n      ret = wrap_in_image_map(src, dot)\n      @diagram_cache[str] = ret\n      return ret\n    end\n\n    # Extract the client-side image map from dot, and use it\n    # to generate the imagemap proper. Return the whole\n    # <map>..<img> combination, suitable for inclusion on\n    # the page\n\n    def wrap_in_image_map(src, dot)\n      res = %{<map id=\"map\" name=\"map\">\\n}\n      dot_map = `dot -Tismap #{src}`\n      dot_map.each do |area|\n        unless area =~ /^rectangle \\((\\d+),(\\d+)\\) \\((\\d+),(\\d+)\\) ([\\/\\w.]+)\\s*(.*)/\n          $stderr.puts \"Unexpected output from dot:\\n#{area}\"\n          return nil\n        end\n        \n        xs, ys = [$1.to_i, $3.to_i], [$2.to_i, $4.to_i]\n        url, area_name = $5, $6\n\n        res <<  %{  <area shape=\"rect\" coords=\"#{xs.min},#{ys.min},#{xs.max},#{ys.max}\" }\n        res <<  %{     href=\"#{url}\" alt=\"#{area_name}\" />\\n}\n      end\n      res << \"</map>\\n\"\n#      map_file = src.sub(/.dot/, '.map')\n#      system(\"dot -Timap #{src} -o #{map_file}\")\n      res << %{<img src=\"#{dot}\" usemap=\"#map\" border=\"0\" alt=\"#{dot}\">}\n      return res\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/dot/dot.rb",
    "content": "module DOT\n\n    # these glogal vars are used to make nice graph source\n    $tab = '    '\n    $tab2 = $tab * 2\n\n    # if we don't like 4 spaces, we can change it any time\n    def change_tab( t )\n        $tab = t\n        $tab2 = t * 2\n    end\n\n    # options for node declaration\n    NODE_OPTS = [\n        'bgcolor',\n        'color',\n        'fontcolor',\n        'fontname',\n        'fontsize',\n        'height',\n        'width',\n        'label',\n        'layer',\n        'rank',\n        'shape',\n        'shapefile',\n        'style',\n        'URL',\n    ]\n\n    # options for edge declaration\n    EDGE_OPTS = [\n        'color',\n        'decorate',\n        'dir',\n        'fontcolor',\n        'fontname',\n        'fontsize',\n        'id',\n        'label',\n        'layer',\n        'lhead',\n        'ltail',\n        'minlen',\n        'style',\n        'weight'\n    ]\n\n    # options for graph declaration\n    GRAPH_OPTS = [\n        'bgcolor',\n        'center',\n        'clusterrank',\n        'color',\n        'compound',\n        'concentrate',\n        'fillcolor',\n        'fontcolor',\n        'fontname',\n        'fontsize',\n        'label',\n        'layerseq',\n        'margin',\n        'mclimit',\n        'nodesep',\n        'nslimit',\n        'ordering',\n        'orientation',\n        'page',\n        'rank',\n        'rankdir',\n        'ranksep',\n        'ratio',\n        'size',\n        'style',\n        'URL'\n    ]\n\n    # a root class for any element in dot notation\n    class DOTSimpleElement\n        attr_accessor :name\n\n        def initialize( params = {} )\n            @label = params['name'] ? params['name'] : ''\n        end\n\n        def to_s\n            @name\n        end\n    end\n\n    # an element that has options ( node, edge or graph )\n    class DOTElement < DOTSimpleElement\n        #attr_reader :parent\n        attr_accessor :name, :options\n\n        def initialize( params = {}, option_list = [] )\n            super( params )\n            @name = params['name'] ? params['name'] : nil\n            @parent = params['parent'] ? params['parent'] : nil\n            @options = {}\n            option_list.each{ |i|\n                @options[i] = params[i] if params[i]\n            }\n            @options['label'] ||= @name if @name != 'node'\n        end\n\n        def each_option\n            @options.each{ |i| yield i }\n        end\n\n        def each_option_pair\n            @options.each_pair{ |key, val| yield key, val }\n        end\n\n        #def parent=( thing )\n        #    @parent.delete( self ) if defined?( @parent ) and @parent\n        #    @parent = thing\n        #end\n    end\n\n\n    # this is used when we build nodes that have shape=record\n    # ports don't have options :)\n    class DOTPort < DOTSimpleElement\n        attr_accessor :label\n\n        def initialize( params = {} )\n            super( params )\n            @name = params['label'] ? params['label'] : ''\n        end\n        def to_s\n            ( @name && @name != \"\" ? \"<#{@name}>\" : \"\" ) + \"#{@label}\"\n        end\n    end\n\n    # node element\n    class DOTNode < DOTElement\n\n        def initialize( params = {}, option_list = NODE_OPTS )\n            super( params, option_list )\n            @ports = params['ports'] ? params['ports'] : []\n        end\n\n        def each_port\n            @ports.each{ |i| yield i }\n        end\n\n        def << ( thing )\n            @ports << thing\n        end\n\n        def push ( thing )\n            @ports.push( thing )\n        end\n\n        def pop\n            @ports.pop\n        end\n\n        def to_s( t = '' )\n\n            label = @options['shape'] != 'record' && @ports.length == 0 ?\n                @options['label'] ?\n                    t + $tab + \"label = \\\"#{@options['label']}\\\"\\n\" :\n                    '' :\n                t + $tab + 'label = \"' + \" \\\\\\n\" +\n                t + $tab2 + \"#{@options['label']}| \\\\\\n\" +\n                @ports.collect{ |i|\n                    t + $tab2 + i.to_s\n                }.join( \"| \\\\\\n\" ) + \" \\\\\\n\" +\n                t + $tab + '\"' + \"\\n\"\n\n            t + \"#{@name} [\\n\" +\n            @options.to_a.collect{ |i|\n                i[1] && i[0] != 'label' ?\n                    t + $tab + \"#{i[0]} = #{i[1]}\" : nil\n            }.compact.join( \",\\n\" ) + ( label != '' ? \",\\n\" : \"\\n\" ) +\n            label +\n            t + \"]\\n\"\n        end\n    end\n\n    # subgraph element is the same to graph, but has another header in dot\n    # notation\n    class DOTSubgraph < DOTElement\n\n        def initialize( params = {}, option_list = GRAPH_OPTS )\n            super( params, option_list )\n            @nodes = params['nodes'] ? params['nodes'] : []\n            @dot_string = 'subgraph'\n        end\n\n        def each_node\n            @nodes.each{ |i| yield i }\n        end\n\n        def << ( thing )\n            @nodes << thing\n        end\n\n        def push( thing )\n            @nodes.push( thing )\n        end\n\n        def pop\n            @nodes.pop\n        end\n\n        def to_s( t = '' )\n          hdr = t + \"#{@dot_string} #{@name} {\\n\"\n\n          options = @options.to_a.collect{ |name, val|\n            val && name != 'label' ?\n            t + $tab + \"#{name} = #{val}\" :\n              name ? t + $tab + \"#{name} = \\\"#{val}\\\"\" : nil\n          }.compact.join( \"\\n\" ) + \"\\n\"\n\n          nodes = @nodes.collect{ |i|\n            i.to_s( t + $tab )\n          }.join( \"\\n\" ) + \"\\n\"\n          hdr + options + nodes + t + \"}\\n\"\n        end\n    end\n\n    # this is graph\n    class DOTDigraph < DOTSubgraph\n        def initialize( params = {}, option_list = GRAPH_OPTS )\n            super( params, option_list )\n            @dot_string = 'digraph'\n        end\n    end\n\n    # this is edge\n    class DOTEdge < DOTElement\n        attr_accessor :from, :to\n        def initialize( params = {}, option_list = EDGE_OPTS )\n            super( params, option_list )\n            @from = params['from'] ? params['from'] : nil\n            @to = params['to'] ? params['to'] : nil\n        end\n\n        def to_s( t = '' )\n            t + \"#{@from} -> #{to} [\\n\" +\n            @options.to_a.collect{ |i|\n                i[1] && i[0] != 'label' ?\n                    t + $tab + \"#{i[0]} = #{i[1]}\" :\n                    i[1] ? t + $tab + \"#{i[0]} = \\\"#{i[1]}\\\"\" : nil\n            }.compact.join( \"\\n\" ) + \"\\n\" + t + \"]\\n\"\n        end\n    end\nend\n\n\n\n"
  },
  {
    "path": "lib/rdoc/generators/chm_generator.rb",
    "content": "require 'rdoc/generators/html_generator'\n\nmodule Generators\n\n  class CHMGenerator < HTMLGenerator\n\n    HHC_PATH = \"c:/Program Files/HTML Help Workshop/hhc.exe\"\n\n    # Standard generator factory\n    def CHMGenerator.for(options)\n      CHMGenerator.new(options)\n    end\n\n    \n    def initialize(*args)\n      super\n      @op_name = @options.op_name || \"rdoc\"\n      check_for_html_help_workshop\n    end\n\n    def check_for_html_help_workshop\n      stat = File.stat(HHC_PATH)\n    rescue\n      $stderr <<\n\t\"\\n.chm output generation requires that Microsoft's Html Help\\n\" <<\n\t\"Workshop is installed. RDoc looks for it in:\\n\\n    \" <<\n\tHHC_PATH <<\n\t\"\\n\\nYou can download a copy for free from:\\n\\n\" <<\n\t\"    http://msdn.microsoft.com/library/default.asp?\" <<\n\t\"url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp\\n\\n\"\n      \n      exit 99\n    end\n\n    # Generate the html as normal, then wrap it\n    # in a help project\n    def generate(info)\n      super\n      @project_name = @op_name + \".hhp\"\n      create_help_project\n    end\n\n    # The project contains the project file, a table of contents\n    # and an index\n    def create_help_project\n      create_project_file\n      create_contents_and_index\n      compile_project\n    end\n\n    # The project file links together all the various\n    # files that go to make up the help.\n\n    def create_project_file\n      template = TemplatePage.new(RDoc::Page::HPP_FILE)\n      values = { \"title\" => @options.title, \"opname\" => @op_name }\n      files = []\n      @files.each do |f|\n\tfiles << { \"html_file_name\" => f.path }\n      end\n\n      values['all_html_files'] = files\n      \n      File.open(@project_name, \"w\") do |f|\n        template.write_html_on(f, values)\n      end\n    end\n\n    # The contents is a list of all files and modules.\n    # For each we include  as sub-entries the list\n    # of methods they contain. As we build the contents\n    # we also build an index file\n\n    def create_contents_and_index\n      contents = []\n      index    = []\n\n      (@files+@classes).sort.each do |entry|\n\tcontent_entry = { \"c_name\" => entry.name, \"ref\" => entry.path }\n\tindex << { \"name\" => entry.name, \"aref\" => entry.path }\n\n\tinternals = []\n\n\tmethods = entry.build_method_summary_list(entry.path)\n\n\tcontent_entry[\"methods\"] = methods unless methods.empty?\n        contents << content_entry\n\tindex.concat methods\n      end\n\n      values = { \"contents\" => contents }\n      template = TemplatePage.new(RDoc::Page::CONTENTS)\n      File.open(\"contents.hhc\", \"w\") do |f|\n\ttemplate.write_html_on(f, values)\n      end\n\n      values = { \"index\" => index }\n      template = TemplatePage.new(RDoc::Page::CHM_INDEX)\n      File.open(\"index.hhk\", \"w\") do |f|\n\ttemplate.write_html_on(f, values)\n      end      \n    end\n\n    # Invoke the windows help compiler to compiler the project\n    def compile_project\n      system(HHC_PATH, @project_name)\n    end\n\n  end\n\n\nend\n"
  },
  {
    "path": "lib/rdoc/generators/html_generator.rb",
    "content": "# We're responsible for generating all the HTML files\n# from the object tree defined in code_objects.rb. We\n# generate:\n#\n# [files]   an html file for each input file given. These\n#           input files appear as objects of class\n#           TopLevel\n#\n# [classes] an html file for each class or module encountered.\n#           These classes are not grouped by file: if a file\n#           contains four classes, we'll generate an html\n#           file for the file itself, and four html files \n#           for the individual classes. \n#\n# [indices] we generate three indices for files, classes,\n#           and methods. These are displayed in a browser\n#           like window with three index panes across the\n#           top and the selected description below\n#\n# Method descriptions appear in whatever entity (file, class,\n# or module) that contains them.\n#\n# We generate files in a structure below a specified subdirectory,\n# normally +doc+.\n#\n#  opdir\n#     |\n#     |___ files\n#     |       |__  per file summaries\n#     |\n#     |___ classes\n#             |__ per class/module descriptions\n#\n# HTML is generated using the Template class.\n#\n\nrequire 'ftools'\n\nrequire 'rdoc/options'\nrequire 'rdoc/template'\nrequire 'rdoc/markup/simple_markup'\nrequire 'rdoc/markup/simple_markup/to_html'\nrequire 'cgi'\n\nmodule Generators\n\n  # Name of sub-direcories that hold file and class/module descriptions\n\n  FILE_DIR  = \"files\"\n  CLASS_DIR = \"classes\"\n  CSS_NAME  = \"rdoc-style.css\"\n  \n\n  ##\n  # Build a hash of all items that can be cross-referenced.\n  # This is used when we output required and included names: \n  # if the names appear in this hash, we can generate\n  # an html cross reference to the appropriate description.\n  # We also use this when parsing comment blocks: any decorated \n  # words matching an entry in this list are hyperlinked.\n\n  class AllReferences\n    @@refs = {}\n    \n    def AllReferences::reset\n      @@refs = {}\n    end\n\n    def AllReferences.add(name, html_class)\n      @@refs[name] = html_class\n    end\n\n    def AllReferences.[](name)\n      @@refs[name]\n    end\n\n    def AllReferences.keys\n      @@refs.keys\n    end\n  end\n\n\n  ##\n  # Subclass of the SM::ToHtml class that supports looking\n  # up words in the AllReferences list. Those that are\n  # found (like AllReferences in this comment) will\n  # be hyperlinked\n\n  class HyperlinkHtml < SM::ToHtml\n    # We need to record the html path of our caller so we can generate\n    # correct relative paths for any hyperlinks that we find\n    def initialize(from_path, context)\n      super()\n      @from_path = from_path\n\n      @parent_name = context.parent_name\n      @parent_name += \"::\" if @parent_name\n      @context = context\n    end\n\n    # We're invoked when any text matches the CROSSREF pattern\n    # (defined in MarkUp). If we fine the corresponding reference,\n    # generate a hyperlink. If the name we're looking for contains\n    # no punctuation, we look for it up the module/class chain. For\n    # example, HyperlinkHtml is found, even without the Generators::\n    # prefix, because we look for it in module Generators first.\n\n    def handle_special_CROSSREF(special)\n      name = special.text\n      if name[0,1] == '#'\n        lookup = name[1..-1]\n        name = lookup unless Options.instance.show_hash\n      else\n        lookup = name\n      end\n\n      # Find class, module, or method in class or module.\n      if /([A-Z]\\w*)[.\\#](\\w+[!?=]?)/ =~ lookup\n        container = $1\n        method = $2\n        ref = @context.find_symbol(container, method)\n      elsif /([A-Za-z]\\w*)[.\\#](\\w+(\\([\\.\\w+\\*\\/\\+\\-\\=\\<\\>]+\\))?)/ =~ lookup\n        container = $1\n        method = $2\n        ref = @context.find_symbol(container, method)\n      else\n        ref = @context.find_symbol(lookup)\n      end\n\n      if ref and ref.document_self\n        \"<a href=\\\"#{ref.as_href(@from_path)}\\\">#{name}</a>\"\n      else\n        name\n      end\n    end\n\n\n    # Generate a hyperlink for url, labeled with text. Handle the\n    # special cases for img: and link: described under handle_special_HYPEDLINK\n    def gen_url(url, text)\n      if url =~ /([A-Za-z]+):(.*)/\n        type = $1\n        path = $2\n      else\n        type = \"http\"\n        path = url\n        url  = \"http://#{url}\"\n      end\n\n      if type == \"link\"\n        if path[0,1] == '#'     # is this meaningful?\n          url = path\n        else\n          url = HTMLGenerator.gen_url(@from_path, path)\n        end\n      end\n\n      if (type == \"http\" || type == \"link\") && \n          url =~ /\\.(gif|png|jpg|jpeg|bmp)$/\n\n        \"<img src=\\\"#{url}\\\" />\"\n      else\n        \"<a href=\\\"#{url}\\\">#{text.sub(%r{^#{type}:/*}, '')}</a>\"\n      end\n    end\n\n    # And we're invoked with a potential external hyperlink mailto:\n    # just gets inserted. http: links are checked to see if they\n    # reference an image. If so, that image gets inserted using an\n    # <img> tag. Otherwise a conventional <a href> is used.  We also\n    # support a special type of hyperlink, link:, which is a reference\n    # to a local file whose path is relative to the --op directory.\n\n    def handle_special_HYPERLINK(special)\n      url = special.text\n      gen_url(url, url)\n    end\n\n    # HEre's a hypedlink where the label is different to the URL\n    #  <label>[url]\n    #\n    \n    def handle_special_TIDYLINK(special)\n      text = special.text\n#      unless text =~ /(\\S+)\\[(.*?)\\]/\n      unless text =~ /\\{(.*?)\\}\\[(.*?)\\]/ or text =~ /(\\S+)\\[(.*?)\\]/ \n        return text\n      end\n      label = $1\n      url   = $2\n      gen_url(url, label)\n    end\n\n  end\n\n\n  \n  #####################################################################\n  #\n  # Handle common markup tasks for the various Html classes\n  #\n\n  module MarkUp\n\n    # Convert a string in markup format into HTML. We keep a cached\n    # SimpleMarkup object lying around after the first time we're\n    # called per object.\n\n    def markup(str, remove_para=false)\n      return '' unless str\n      unless defined? @markup\n        @markup = SM::SimpleMarkup.new\n\n        # class names, variable names, or instance variables\n        @markup.add_special(/(\n                               \\w+(::\\w+)*[.\\#]\\w+(\\([\\.\\w+\\*\\/\\+\\-\\=\\<\\>]+\\))?  # A::B.meth(**) (for operator in Fortran95)\n                             | \\#\\w+(\\([.\\w\\*\\/\\+\\-\\=\\<\\>]+\\))?  #  meth(**) (for operator in Fortran95)\n                             | \\b([A-Z]\\w*(::\\w+)*[.\\#]\\w+)  #    A::B.meth\n                             | \\b([A-Z]\\w+(::\\w+)*)       #    A::B..\n                             | \\#\\w+[!?=]?                #    #meth_name \n                             | \\b\\w+([_\\/\\.]+\\w+)*[!?=]?  #    meth_name\n                             )/x, \n                            :CROSSREF)\n\n        # external hyperlinks\n        @markup.add_special(/((link:|https?:|mailto:|ftp:|www\\.)\\S+\\w)/, :HYPERLINK)\n\n        # and links of the form  <text>[<url>]\n        @markup.add_special(/(((\\{.*?\\})|\\b\\S+?)\\[\\S+?\\.\\S+?\\])/, :TIDYLINK)\n#        @markup.add_special(/\\b(\\S+?\\[\\S+?\\.\\S+?\\])/, :TIDYLINK)\n\n      end\n      unless defined? @html_formatter\n        @html_formatter = HyperlinkHtml.new(self.path, self)\n      end\n\n      # Convert leading comment markers to spaces, but only\n      # if all non-blank lines have them\n\n      if str =~ /^(?>\\s*)[^\\#]/\n        content = str\n      else\n        content = str.gsub(/^\\s*(#+)/)  { $1.tr('#',' ') }\n      end\n\n      res = @markup.convert(content, @html_formatter)\n      if remove_para\n        res.sub!(/^<p>/, '')\n        res.sub!(/<\\/p>$/, '')\n      end\n      res\n    end\n\n    # Qualify a stylesheet URL; if if +css_name+ does not begin with '/' or\n    # 'http[s]://', prepend a prefix relative to +path+. Otherwise, return it\n    # unmodified.\n\n    def style_url(path, css_name=nil)\n#      $stderr.puts \"style_url( #{path.inspect}, #{css_name.inspect} )\"\n      css_name ||= CSS_NAME\n      if %r{^(https?:/)?/} =~ css_name\n        return css_name\n      else\n        return HTMLGenerator.gen_url(path, css_name)\n      end\n    end\n\n    # Build a webcvs URL with the given 'url' argument. URLs with a '%s' in them\n    # get the file's path sprintfed into them; otherwise they're just catenated\n    # together.\n\n    def cvs_url(url, full_path)\n      if /%s/ =~ url\n        return sprintf( url, full_path )\n      else\n        return url + full_path\n      end\n    end\n  end\n\n\n  #####################################################################\n  #\n  # A Context is built by the parser to represent a container: contexts\n  # hold classes, modules, methods, require lists and include lists.\n  # ClassModule and TopLevel are the context objects we process here\n  # \n  class ContextUser\n\n    include MarkUp\n\n    attr_reader :context\n    \n    def initialize(context, options)\n      @context = context\n      @options = options\n    end\n      \n    # convenience method to build a hyperlink\n    def href(link, cls, name)\n      %{<a href=\"#{link}\" class=\"#{cls}\">#{name}</a>} #\"\n    end\n\n    # return a reference to outselves to be used as an href=\n    # the form depends on whether we're all in one file\n    # or in multiple files\n\n    def as_href(from_path)\n      if @options.all_one_file\n        \"#\" + path\n      else\n        HTMLGenerator.gen_url(from_path, path)\n      end\n    end\n\n    # Create a list of HtmlMethod objects for each method\n    # in the corresponding context object. If the @options.show_all\n    # variable is set (corresponding to the <tt>--all</tt> option,\n    # we include all methods, otherwise just the public ones.\n\n    def collect_methods\n      list = @context.method_list\n      unless @options.show_all\n        list = list.find_all {|m| m.visibility == :public || m.visibility == :protected || m.force_documentation }\n      end\n      @methods = list.collect {|m| HtmlMethod.new(m, self, @options) }\n    end\n\n    # Build a summary list of all the methods in this context\n    def build_method_summary_list(path_prefix=\"\")\n      collect_methods unless @methods\n      meths = @methods.sort\n      res = []\n      meths.each do |meth|\n\tres << {\n          \"name\" => CGI.escapeHTML(meth.name),\n          \"aref\" => \"#{path_prefix}\\##{meth.aref}\" \n        }\n      end\n      res\n    end\n\n\n    # Build a list of aliases for which we couldn't find a\n    # corresponding method\n    def build_alias_summary_list(section)\n      values = []\n      @context.aliases.each do |al|\n        next unless al.section == section\n        res = {\n          'old_name' => al.old_name,\n          'new_name' => al.new_name,\n        }\n        if al.comment && !al.comment.empty?\n          res['desc'] = markup(al.comment, true)\n        end\n        values << res\n      end\n      values\n    end\n    \n    # Build a list of constants\n    def build_constants_summary_list(section)\n      values = []\n      @context.constants.each do |co|\n        next unless co.section == section\n        res = {\n          'name'  => co.name,\n          'value' => CGI.escapeHTML(co.value)\n        }\n        res['desc'] = markup(co.comment, true) if co.comment && !co.comment.empty?\n        values << res\n      end\n      values\n    end\n    \n    def build_requires_list(context)\n      potentially_referenced_list(context.requires) {|fn| [fn + \".rb\"] }\n    end\n\n    def build_include_list(context)\n      potentially_referenced_list(context.includes)\n    end\n\n    # Build a list from an array of <i>Htmlxxx</i> items. Look up each\n    # in the AllReferences hash: if we find a corresponding entry,\n    # we generate a hyperlink to it, otherwise just output the name.\n    # However, some names potentially need massaging. For example,\n    # you may require a Ruby file without the .rb extension,\n    # but the file names we know about may have it. To deal with\n    # this, we pass in a block which performs the massaging,\n    # returning an array of alternative names to match\n\n    def potentially_referenced_list(array)\n      res = []\n      array.each do |i|\n        ref = AllReferences[i.name] \n#         if !ref\n#           container = @context.parent\n#           while !ref && container\n#             name = container.name + \"::\" + i.name\n#             ref = AllReferences[name] \n#             container = container.parent\n#           end\n#         end\n\n        ref = @context.find_symbol(i.name)\n        ref = ref.viewer if ref\n\n        if !ref && block_given?\n          possibles = yield(i.name)\n          while !ref and !possibles.empty?\n            ref = AllReferences[possibles.shift]\n          end\n        end\n        h_name = CGI.escapeHTML(i.name)\n        if ref and ref.document_self\n          path = url(ref.path)\n          res << { \"name\" => h_name, \"aref\" => path }\n        else\n          res << { \"name\" => h_name }\n        end\n      end\n      res\n    end\n\n    # Build an array of arrays of method details. The outer array has up\n    # to six entries, public, private, and protected for both class\n    # methods, the other for instance methods. The inner arrays contain\n    # a hash for each method\n\n    def build_method_detail_list(section)\n      outer = []\n\n      methods = @methods.sort\n      for singleton in [true, false]\n        for vis in [ :public, :protected, :private ] \n          res = []\n          methods.each do |m|\n            if m.section == section and\n                m.document_self and \n                m.visibility == vis and \n                m.singleton == singleton\n              row = {}\n              if m.call_seq\n                row[\"callseq\"] = m.call_seq.gsub(/->/, '&rarr;')\n              else\n                row[\"name\"]        = CGI.escapeHTML(m.name)\n                row[\"params\"]      = m.params\n              end\n              desc = m.description.strip\n              row[\"m_desc\"]      = desc unless desc.empty?\n              row[\"aref\"]        = m.aref\n              row[\"visibility\"]  = m.visibility.to_s\n\n              alias_names = []\n              m.aliases.each do |other|\n                if other.viewer   # won't be if the alias is private\n                  alias_names << {\n                    'name' => other.name,\n                    'aref'  => other.viewer.as_href(path)\n                  } \n                end\n              end\n              unless alias_names.empty?\n                row[\"aka\"] = alias_names\n              end\n\n              if @options.inline_source\n                code = m.source_code\n                row[\"sourcecode\"] = code if code\n              else\n                code = m.src_url\n                if code\n                  row[\"codeurl\"] = code\n                  row[\"imgurl\"]  = m.img_url\n                end\n              end\n              res << row\n            end\n          end\n          if res.size > 0 \n            outer << {\n              \"type\"    => vis.to_s.capitalize,\n              \"category\"    => singleton ? \"Class\" : \"Instance\",\n              \"methods\" => res\n            }\n          end\n        end\n      end\n      outer\n    end\n\n    # Build the structured list of classes and modules contained\n    # in this context. \n\n    def build_class_list(level, from, section, infile=nil)\n      res = \"\"\n      prefix = \"&nbsp;&nbsp;::\" * level;\n\n      from.modules.sort.each do |mod|\n        next unless mod.section == section\n        next if infile && !mod.defined_in?(infile)\n        if mod.document_self\n          res << \n            prefix <<\n            \"Module \" <<\n            href(url(mod.viewer.path), \"link\", mod.full_name) <<\n            \"<br />\\n\" <<\n            build_class_list(level + 1, mod, section, infile)\n        end\n      end\n\n      from.classes.sort.each do |cls|\n        next unless cls.section == section\n        next if infile && !cls.defined_in?(infile)\n        if cls.document_self\n          res      <<\n            prefix << \n            \"Class \" <<\n            href(url(cls.viewer.path), \"link\", cls.full_name) <<\n            \"<br />\\n\" <<\n            build_class_list(level + 1, cls, section, infile)\n        end\n      end\n\n      res\n    end\n    \n    def url(target)\n      HTMLGenerator.gen_url(path, target)\n    end\n\n    def aref_to(target)\n      if @options.all_one_file\n        \"#\" + target\n      else\n        url(target)\n      end\n    end\n\n    def document_self\n      @context.document_self\n    end\n\n    def diagram_reference(diagram)\n      res = diagram.gsub(/((?:src|href)=\")(.*?)\"/) {\n        $1 + url($2) + '\"'\n      }\n      res\n    end\n\n\n    # Find a symbol in ourselves or our parent\n    def find_symbol(symbol, method=nil)\n      res = @context.find_symbol(symbol, method)\n      if res\n        res = res.viewer\n      end\n      res\n    end\n\n    # create table of contents if we contain sections\n      \n    def add_table_of_sections\n      toc = []\n      @context.sections.each do |section|\n        if section.title\n          toc << {\n            'secname' => section.title,\n            'href'    => section.sequence\n          }\n        end\n      end\n      \n      @values['toc'] = toc unless toc.empty?\n    end\n\n\n  end\n\n  #####################################################################\n  #\n  # Wrap a ClassModule context\n\n  class HtmlClass < ContextUser\n\n    attr_reader :path\n\n    def initialize(context, html_file, prefix, options)\n      super(context, options)\n\n      @html_file = html_file\n      @is_module = context.is_module?\n      @values    = {}\n\n      context.viewer = self\n\n      if options.all_one_file\n        @path = context.full_name\n      else\n        @path = http_url(context.full_name, prefix)\n      end\n\n      collect_methods\n\n      AllReferences.add(name, self)\n    end\n\n    # return the relative file name to store this class in,\n    # which is also its url\n    def http_url(full_name, prefix)\n      path = full_name.dup\n      if path['<<']\n        path.gsub!(/<<\\s*(\\w*)/) { \"from-#$1\" }\n      end\n      File.join(prefix, path.split(\"::\")) + \".html\"\n    end\n\n\n    def name\n      @context.full_name\n    end\n\n    def parent_name\n      @context.parent.full_name\n    end\n\n    def index_name\n      name\n    end\n\n    def write_on(f)\n      value_hash\n      template = TemplatePage.new(RDoc::Page::BODY,\n                                      RDoc::Page::CLASS_PAGE,\n                                      RDoc::Page::METHOD_LIST)\n      template.write_html_on(f, @values)\n    end\n\n    def value_hash\n      class_attribute_values\n      add_table_of_sections\n\n      @values[\"charset\"] = @options.charset\n      @values[\"style_url\"] = style_url(path, @options.css)\n\n      d = markup(@context.comment)\n      @values[\"description\"] = d unless d.empty?\n\n      ml = build_method_summary_list\n      @values[\"methods\"] = ml unless ml.empty?\n\n      il = build_include_list(@context)\n      @values[\"includes\"] = il unless il.empty?\n\n      @values[\"sections\"] = @context.sections.map do |section|\n\n        secdata = {\n          \"sectitle\" => section.title,\n          \"secsequence\" => section.sequence,\n          \"seccomment\" => markup(section.comment)\n        }\n\n        al = build_alias_summary_list(section)\n        secdata[\"aliases\"] = al unless al.empty?\n        \n        co = build_constants_summary_list(section)\n        secdata[\"constants\"] = co unless co.empty?\n        \n        al = build_attribute_list(section)\n        secdata[\"attributes\"] = al unless al.empty?\n        \n        cl = build_class_list(0, @context, section)\n        secdata[\"classlist\"] = cl unless cl.empty?\n        \n        mdl = build_method_detail_list(section)\n        secdata[\"method_list\"] = mdl unless mdl.empty?\n\n        secdata\n      end\n\n      @values\n    end\n\n    def build_attribute_list(section)\n      atts = @context.attributes.sort\n      res = []\n      atts.each do |att|\n        next unless att.section == section\n        if att.visibility == :public || att.visibility == :protected || @options.show_all\n          entry = {\n            \"name\"   => CGI.escapeHTML(att.name), \n            \"rw\"     => att.rw, \n            \"a_desc\" => markup(att.comment, true)\n          }\n          unless att.visibility == :public || att.visibility == :protected\n            entry[\"rw\"] << \"-\"\n          end\n          res << entry\n        end\n      end\n      res\n    end\n\n    def class_attribute_values\n      h_name = CGI.escapeHTML(name)\n\n      @values[\"classmod\"]  = @is_module ? \"Module\" : \"Class\"\n      @values[\"title\"]     = \"#{@values['classmod']}: #{h_name}\"\n\n      c = @context\n      c = c.parent while c and !c.diagram\n      if c && c.diagram\n        @values[\"diagram\"] = diagram_reference(c.diagram)\n      end\n\n      @values[\"full_name\"] = h_name\n\n      parent_class = @context.superclass\n\n      if parent_class\n\t@values[\"parent\"] = CGI.escapeHTML(parent_class)\n\n\tif parent_name\n\t  lookup = parent_name + \"::\" + parent_class\n\telse\n\t  lookup = parent_class\n\tend\n\n\tparent_url = AllReferences[lookup] || AllReferences[parent_class]\n\n\tif parent_url and parent_url.document_self\n\t  @values[\"par_url\"] = aref_to(parent_url.path)\n\tend\n      end\n\n      files = []\n      @context.in_files.each do |f|\n        res = {}\n        full_path = CGI.escapeHTML(f.file_absolute_name)\n\n        res[\"full_path\"]     = full_path\n        res[\"full_path_url\"] = aref_to(f.viewer.path) if f.document_self\n\n        if @options.webcvs\n          res[\"cvsurl\"] = cvs_url( @options.webcvs, full_path )\n        end\n\n        files << res\n      end\n\n      @values['infiles'] = files\n    end\n\n    def <=>(other)\n      self.name <=> other.name\n    end\n\n  end\n\n  #####################################################################\n  #\n  # Handles the mapping of a file's information to HTML. In reality,\n  # a file corresponds to a +TopLevel+ object, containing modules,\n  # classes, and top-level methods. In theory it _could_ contain\n  # attributes and aliases, but we ignore these for now.\n\n  class HtmlFile < ContextUser\n\n    attr_reader :path\n    attr_reader :name\n\n    def initialize(context, options, file_dir)\n      super(context, options)\n\n      @values = {}\n\n      if options.all_one_file\n        @path = filename_to_label\n      else\n        @path = http_url(file_dir)\n      end\n\n      @name = @context.file_relative_name\n\n      collect_methods\n      AllReferences.add(name, self)\n      context.viewer = self\n    end\n\n    def http_url(file_dir)\n      File.join(file_dir, @context.file_relative_name.tr('.', '_')) +\n        \".html\"\n    end\n\n    def filename_to_label\n      @context.file_relative_name.gsub(/%|\\/|\\?|\\#/) {|s| '%' + (\"%x\" % s[0]) }\n    end\n\n    def index_name\n      name\n    end\n\n    def parent_name\n      nil\n    end\n\n    def value_hash\n      file_attribute_values\n      add_table_of_sections\n\n      @values[\"charset\"]   = @options.charset\n      @values[\"href\"]      = path\n      @values[\"style_url\"] = style_url(path, @options.css)\n\n      if @context.comment\n        d = markup(@context.comment)\n        @values[\"description\"] = d if d.size > 0\n      end\n\n      ml = build_method_summary_list\n      @values[\"methods\"] = ml unless ml.empty?\n\n      il = build_include_list(@context)\n      @values[\"includes\"] = il unless il.empty?\n\n      rl = build_requires_list(@context)\n      @values[\"requires\"] = rl unless rl.empty?\n\n      if @options.promiscuous\n        file_context = nil\n      else\n        file_context = @context\n      end\n\n\n      @values[\"sections\"] = @context.sections.map do |section|\n\n        secdata = {\n          \"sectitle\" => section.title,\n          \"secsequence\" => section.sequence,\n          \"seccomment\" => markup(section.comment)\n        }\n\n        cl = build_class_list(0, @context, section, file_context)\n        @values[\"classlist\"] = cl unless cl.empty?\n\n        mdl = build_method_detail_list(section)\n        secdata[\"method_list\"] = mdl unless mdl.empty?\n\n        al = build_alias_summary_list(section)\n        secdata[\"aliases\"] = al unless al.empty?\n        \n        co = build_constants_summary_list(section)\n        @values[\"constants\"] = co unless co.empty?\n\n        secdata\n      end\n      \n      @values\n    end\n    \n    def write_on(f)\n      value_hash\n      template = TemplatePage.new(RDoc::Page::BODY,\n                                  RDoc::Page::FILE_PAGE,\n                                  RDoc::Page::METHOD_LIST)\n      template.write_html_on(f, @values)\n    end\n\n    def file_attribute_values\n      full_path = @context.file_absolute_name\n      short_name = File.basename(full_path)\n      \n      @values[\"title\"] = CGI.escapeHTML(\"File: #{short_name}\")\n\n      if @context.diagram\n        @values[\"diagram\"] = diagram_reference(@context.diagram)\n      end\n\n      @values[\"short_name\"]   = CGI.escapeHTML(short_name)\n      @values[\"full_path\"]    = CGI.escapeHTML(full_path)\n      @values[\"dtm_modified\"] = @context.file_stat.mtime.to_s\n\n      if @options.webcvs\n        @values[\"cvsurl\"] = cvs_url( @options.webcvs, @values[\"full_path\"] )\n      end\n    end\n\n    def <=>(other)\n      self.name <=> other.name\n    end\n  end\n\n  #####################################################################\n\n  class HtmlMethod\n    include MarkUp\n\n    attr_reader :context\n    attr_reader :src_url\n    attr_reader :img_url\n    attr_reader :source_code\n\n    @@seq = \"M000000\"\n\n    @@all_methods = []\n\n    def HtmlMethod::reset\n      @@all_methods = []\n    end\n\n    def initialize(context, html_class, options)\n      @context    = context\n      @html_class = html_class\n      @options    = options\n      @@seq       = @@seq.succ\n      @seq        = @@seq\n      @@all_methods << self\n\n      context.viewer = self\n\n      if (ts = @context.token_stream)\n        @source_code = markup_code(ts)\n        unless @options.inline_source\n          @src_url = create_source_code_file(@source_code)\n          @img_url = HTMLGenerator.gen_url(path, 'source.png')\n        end\n      end\n\n      AllReferences.add(name, self)\n    end\n    \n    # return a reference to outselves to be used as an href=\n    # the form depends on whether we're all in one file\n    # or in multiple files\n\n    def as_href(from_path)\n      if @options.all_one_file\n        \"#\" + path\n      else\n        HTMLGenerator.gen_url(from_path, path)\n      end\n    end\n\n    def name\n      @context.name\n    end\n\n    def section\n      @context.section\n    end\n\n    def index_name\n      \"#{@context.name} (#{@html_class.name})\"\n    end\n\n    def parent_name\n      if @context.parent.parent\n        @context.parent.parent.full_name\n      else\n        nil\n      end\n    end\n\n    def aref\n      @seq\n    end\n\n    def path\n      if @options.all_one_file\n\taref\n      else\n\t@html_class.path + \"#\" + aref\n      end\n    end\n\n    def description\n      markup(@context.comment)\n    end\n\n    def visibility\n      @context.visibility\n    end\n\n    def singleton\n      @context.singleton\n    end\n\n    def call_seq\n      cs = @context.call_seq\n      if cs\n        cs.gsub(/\\n/, \"<br />\\n\")\n      else\n        nil\n      end\n    end\n\n    def params\n      # params coming from a call-seq in 'C' will start with the\n      # method name\n      p = @context.params\n      if p !~ /^\\w/\n        p = @context.params.gsub(/\\s*\\#.*/, '')\n        p = p.tr(\"\\n\", \" \").squeeze(\" \")\n        p = \"(\" + p + \")\" unless p[0] == ?(\n        \n        if (block = @context.block_params)\n         # If this method has explicit block parameters, remove any\n         # explicit &block\n\n         p.sub!(/,?\\s*&\\w+/, '')\n\n          block.gsub!(/\\s*\\#.*/, '')\n          block = block.tr(\"\\n\", \" \").squeeze(\" \")\n          if block[0] == ?(\n            block.sub!(/^\\(/, '').sub!(/\\)/, '')\n          end\n          p << \" {|#{block.strip}| ...}\"\n        end\n      end\n      CGI.escapeHTML(p)\n    end\n    \n    def create_source_code_file(code_body)\n      meth_path = @html_class.path.sub(/\\.html$/, '.src')\n      File.makedirs(meth_path)\n      file_path = File.join(meth_path, @seq) + \".html\"\n\n      template = TemplatePage.new(RDoc::Page::SRC_PAGE)\n      File.open(file_path, \"w\") do |f|\n        values = {\n          'title'     => CGI.escapeHTML(index_name),\n          'code'      => code_body,\n          'style_url' => style_url(file_path, @options.css),\n          'charset'   => @options.charset\n        }\n        template.write_html_on(f, values)\n      end\n      HTMLGenerator.gen_url(path, file_path)\n    end\n\n    def HtmlMethod.all_methods\n      @@all_methods\n    end\n\n    def <=>(other)\n      @context <=> other.context\n    end\n\n    ##\n    # Given a sequence of source tokens, mark up the source code\n    # to make it look purty.\n\n\n    def markup_code(tokens)\n      src = \"\"\n      tokens.each do |t|\n        next unless t\n        #    p t.class\n#        style = STYLE_MAP[t.class]\n        style = case t\n                when RubyToken::TkCONSTANT then \"ruby-constant\"\n                when RubyToken::TkKW       then \"ruby-keyword kw\"\n                when RubyToken::TkIVAR     then \"ruby-ivar\"\n                when RubyToken::TkOp       then \"ruby-operator\"\n                when RubyToken::TkId       then \"ruby-identifier\"\n                when RubyToken::TkNode     then \"ruby-node\"\n                when RubyToken::TkCOMMENT  then \"ruby-comment cmt\"\n                when RubyToken::TkREGEXP   then \"ruby-regexp re\"\n                when RubyToken::TkSTRING   then \"ruby-value str\"\n                when RubyToken::TkVal      then \"ruby-value\"\n                else\n                    nil\n                end\n\n        text = CGI.escapeHTML(t.text)\n\n        if style\n          src << \"<span class=\\\"#{style}\\\">#{text}</span>\"\n        else\n          src << text\n        end\n      end\n\n      add_line_numbers(src) if Options.instance.include_line_numbers\n      src\n    end\n\n    # we rely on the fact that the first line of a source code\n    # listing has \n    #    # File xxxxx, line dddd\n\n    def add_line_numbers(src)\n      if src =~ /\\A.*, line (\\d+)/\n        first = $1.to_i - 1\n        last  = first + src.count(\"\\n\")\n        size = last.to_s.length\n        real_fmt = \"%#{size}d: \"\n        fmt = \" \" * (size+2)\n        src.gsub!(/^/) do\n          res = sprintf(fmt, first) \n          first += 1\n          fmt = real_fmt\n          res\n        end\n      end\n    end\n\n    def document_self\n      @context.document_self\n    end\n\n    def aliases\n      @context.aliases\n    end\n\n    def find_symbol(symbol, method=nil)\n      res = @context.parent.find_symbol(symbol, method)\n      if res\n        res = res.viewer\n      end\n      res\n    end\n  end\n\n  #####################################################################\n\n  class HTMLGenerator\n\n    include MarkUp\n\n    ##\n    # convert a target url to one that is relative to a given\n    # path\n    \n    def HTMLGenerator.gen_url(path, target)\n      from          = File.dirname(path)\n      to, to_file   = File.split(target)\n      \n      from = from.split(\"/\")\n      to   = to.split(\"/\")\n      \n      while from.size > 0 and to.size > 0 and from[0] == to[0]\n        from.shift\n        to.shift\n      end\n      \n      from.fill(\"..\")\n      from.concat(to)\n      from << to_file\n      File.join(*from)\n    end\n\n    # Generators may need to return specific subclasses depending\n    # on the options they are passed. Because of this\n    # we create them using a factory\n\n    def HTMLGenerator.for(options)\n      AllReferences::reset\n      HtmlMethod::reset\n\n      if options.all_one_file\n        HTMLGeneratorInOne.new(options)\n      else\n        HTMLGenerator.new(options)\n      end\n    end\n\n    class <<self\n      protected :new\n    end\n\n    # Set up a new HTML generator. Basically all we do here is load\n    # up the correct output temlate\n\n    def initialize(options) #:not-new:\n      @options    = options\n      load_html_template\n    end\n\n\n    ##\n    # Build the initial indices and output objects\n    # based on an array of TopLevel objects containing\n    # the extracted information. \n\n    def generate(toplevels)\n      @toplevels  = toplevels\n      @files      = []\n      @classes    = []\n\n      write_style_sheet\n      gen_sub_directories()\n      build_indices\n      generate_html\n    end\n\n    private\n\n    ##\n    # Load up the HTML template specified in the options.\n    # If the template name contains a slash, use it literally\n    #\n    def load_html_template\n      template = @options.template\n      unless template =~ %r{/|\\\\}\n        template = File.join(\"rdoc/generators/template\",\n                             @options.generator.key, template)\n      end\n      require template\n      extend RDoc::Page\n    rescue LoadError\n      $stderr.puts \"Could not find HTML template '#{template}'\"\n      exit 99\n    end\n\n    ##\n    # Write out the style sheet used by the main frames\n    #\n    \n    def write_style_sheet\n      template = TemplatePage.new(RDoc::Page::STYLE)\n      unless @options.css\n        File.open(CSS_NAME, \"w\") do |f|\n          values = { \"fonts\" => RDoc::Page::FONTS }\n          template.write_html_on(f, values)\n        end\n      end\n    end\n\n    ##\n    # See the comments at the top for a description of the\n    # directory structure\n\n    def gen_sub_directories\n      File.makedirs(FILE_DIR, CLASS_DIR)\n    rescue \n      $stderr.puts $!.message\n      exit 1\n    end\n\n    ##\n    # Generate:\n    #\n    # * a list of HtmlFile objects for each TopLevel object.\n    # * a list of HtmlClass objects for each first level\n    #   class or module in the TopLevel objects\n    # * a complete list of all hyperlinkable terms (file,\n    #   class, module, and method names)\n\n    def build_indices\n\n      @toplevels.each do |toplevel|\n        @files << HtmlFile.new(toplevel, @options, FILE_DIR)\n      end\n\n      RDoc::TopLevel.all_classes_and_modules.each do |cls|\n        build_class_list(cls, @files[0], CLASS_DIR)\n      end\n    end\n\n    def build_class_list(from, html_file, class_dir)\n      @classes << HtmlClass.new(from, html_file, class_dir, @options)\n      from.each_classmodule do |mod|\n        build_class_list(mod, html_file, class_dir)\n      end\n    end\n\n    ##\n    # Generate all the HTML\n    #\n    def generate_html\n      # the individual descriptions for files and classes\n      gen_into(@files)\n      gen_into(@classes)\n      # and the index files\n      gen_file_index\n      gen_class_index\n      gen_method_index\n      gen_main_index\n      \n      # this method is defined in the template file\n      write_extra_pages if defined? write_extra_pages\n    end\n\n    def gen_into(list)\n      list.each do |item|\n        if item.document_self\n          op_file = item.path\n          File.makedirs(File.dirname(op_file))\n          File.open(op_file, \"w\") { |file| item.write_on(file) }\n        end\n      end\n\n    end\n\n    def gen_file_index\n      gen_an_index(@files, 'Files', \n                   RDoc::Page::FILE_INDEX, \n                   \"fr_file_index.html\")\n    end\n\n    def gen_class_index\n      gen_an_index(@classes, 'Classes',\n                   RDoc::Page::CLASS_INDEX,\n                   \"fr_class_index.html\")\n    end\n\n    def gen_method_index\n      gen_an_index(HtmlMethod.all_methods, 'Methods', \n                   RDoc::Page::METHOD_INDEX,\n                   \"fr_method_index.html\")\n    end\n\n    \n    def gen_an_index(collection, title, template, filename)\n      template = TemplatePage.new(RDoc::Page::FR_INDEX_BODY, template)\n      res = []\n      collection.sort.each do |f|\n        if f.document_self\n          res << { \"href\" => f.path, \"name\" => f.index_name }\n        end\n      end\n\n      values = {\n        \"entries\"    => res,\n        'list_title' => CGI.escapeHTML(title),\n        'index_url'  => main_url,\n        'charset'    => @options.charset,\n        'style_url'  => style_url('', @options.css),\n      }\n\n      File.open(filename, \"w\") do |f|\n        template.write_html_on(f, values)\n      end\n    end\n\n    # The main index page is mostly a template frameset, but includes\n    # the initial page. If the <tt>--main</tt> option was given,\n    # we use this as our main page, otherwise we use the\n    # first file specified on the command line.\n\n    def gen_main_index\n      template = TemplatePage.new(RDoc::Page::INDEX)\n      File.open(\"index.html\", \"w\") do |f|\n        values = {\n          \"initial_page\" => main_url,\n          'title'        => CGI.escapeHTML(@options.title),\n          'charset'      => @options.charset\n        }\n        if @options.inline_source\n          values['inline_source'] = true\n        end\n        template.write_html_on(f, values)\n      end\n    end\n\n    # return the url of the main page\n    def main_url\n      main_page = @options.main_page\n      ref = nil\n      if main_page\n        ref = AllReferences[main_page]\n        if ref\n          ref = ref.path\n        else\n          $stderr.puts \"Could not find main page #{main_page}\"\n        end\n      end\n\n      unless ref\n        for file in @files\n          if file.document_self\n            ref = file.path \n            break\n          end\n        end\n      end\n\n      unless ref\n        $stderr.puts \"Couldn't find anything to document\"\n        $stderr.puts \"Perhaps you've used :stopdoc: in all classes\"\n        exit(1)\n      end\n\n      ref\n    end\n\n\n  end\n\n\n  ######################################################################\n\n\n  class HTMLGeneratorInOne < HTMLGenerator\n\n    def initialize(*args)\n      super\n    end\n\n    ##\n    # Build the initial indices and output objects\n    # based on an array of TopLevel objects containing\n    # the extracted information. \n\n    def generate(info)\n      @toplevels  = info\n      @files      = []\n      @classes    = []\n      @hyperlinks = {}\n\n      build_indices\n      generate_xml\n    end\n\n\n    ##\n    # Generate:\n    #\n    # * a list of HtmlFile objects for each TopLevel object.\n    # * a list of HtmlClass objects for each first level\n    #   class or module in the TopLevel objects\n    # * a complete list of all hyperlinkable terms (file,\n    #   class, module, and method names)\n\n    def build_indices\n\n      @toplevels.each do |toplevel|\n        @files << HtmlFile.new(toplevel, @options, FILE_DIR)\n      end\n\n      RDoc::TopLevel.all_classes_and_modules.each do |cls|\n        build_class_list(cls, @files[0], CLASS_DIR)\n      end\n    end\n\n    def build_class_list(from, html_file, class_dir)\n      @classes << HtmlClass.new(from, html_file, class_dir, @options)\n      from.each_classmodule do |mod|\n        build_class_list(mod, html_file, class_dir)\n      end\n    end\n\n    ##\n    # Generate all the HTML. For the one-file case, we generate\n    # all the information in to one big hash\n    #\n    def generate_xml\n      values = { \n        'charset' => @options.charset,\n        'files'   => gen_into(@files),\n        'classes' => gen_into(@classes),\n        'title'        => CGI.escapeHTML(@options.title),\n      }\n      \n      # this method is defined in the template file\n      write_extra_pages if defined? write_extra_pages\n\n      template = TemplatePage.new(RDoc::Page::ONE_PAGE)\n\n      if @options.op_name\n        opfile = File.open(@options.op_name, \"w\")\n      else\n        opfile = $stdout\n      end\n      template.write_html_on(opfile, values)\n    end\n\n    def gen_into(list)\n      res = []\n      list.each do |item|\n        res << item.value_hash\n      end\n      res\n    end\n\n    def gen_file_index\n      gen_an_index(@files, 'Files')\n    end\n\n    def gen_class_index\n      gen_an_index(@classes, 'Classes')\n    end\n\n    def gen_method_index\n      gen_an_index(HtmlMethod.all_methods, 'Methods')\n    end\n\n    \n    def gen_an_index(collection, title)\n      res = []\n      collection.sort.each do |f|\n        if f.document_self\n          res << { \"href\" => f.path, \"name\" => f.index_name }\n        end\n      end\n\n      return {\n        \"entries\" => res,\n        'list_title' => title,\n        'index_url'  => main_url,\n      }\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/generators/ri_generator.rb",
    "content": "# We're responsible for generating all the HTML files\n# from the object tree defined in code_objects.rb. We\n# generate:\n#\n# [files]   an html file for each input file given. These\n#           input files appear as objects of class\n#           TopLevel\n#\n# [classes] an html file for each class or module encountered.\n#           These classes are not grouped by file: if a file\n#           contains four classes, we'll generate an html\n#           file for the file itself, and four html files \n#           for the individual classes. \n#\n# [indices] we generate three indices for files, classes,\n#           and methods. These are displayed in a browser\n#           like window with three index panes across the\n#           top and the selected description below\n#\n# Method descriptions appear in whatever entity (file, class,\n# or module) that contains them.\n#\n# We generate files in a structure below a specified subdirectory,\n# normally +doc+.\n#\n#  opdir\n#     |\n#     |___ files\n#     |       |__  per file summaries\n#     |\n#     |___ classes\n#             |__ per class/module descriptions\n#\n# HTML is generated using the Template class.\n#\n\nrequire 'ftools'\n\nrequire 'rdoc/options'\nrequire 'rdoc/template'\nrequire 'rdoc/markup/simple_markup'\nrequire 'rdoc/markup/simple_markup/to_flow'\nrequire 'cgi'\n\nrequire 'rdoc/ri/ri_cache'\nrequire 'rdoc/ri/ri_reader'\nrequire 'rdoc/ri/ri_writer'\nrequire 'rdoc/ri/ri_descriptions'\n\nmodule Generators\n\n\n  class RIGenerator\n\n    # Generators may need to return specific subclasses depending\n    # on the options they are passed. Because of this\n    # we create them using a factory\n\n    def RIGenerator.for(options)\n      new(options)\n    end\n\n    class <<self\n      protected :new\n    end\n\n    # Set up a new HTML generator. Basically all we do here is load\n    # up the correct output temlate\n\n    def initialize(options) #:not-new:\n      @options   = options\n      @ri_writer = RI::RiWriter.new(\".\")\n      @markup    = SM::SimpleMarkup.new\n      @to_flow   = SM::ToFlow.new\n    end\n\n\n    ##\n    # Build the initial indices and output objects\n    # based on an array of TopLevel objects containing\n    # the extracted information. \n\n    def generate(toplevels)\n      RDoc::TopLevel.all_classes_and_modules.each do |cls|\n        process_class(cls)\n      end\n    end\n\n    def process_class(from_class)\n      generate_class_info(from_class)\n\n      # now recure into this classes constituent classess\n      from_class.each_classmodule do |mod|\n        process_class(mod)\n      end\n    end\n\n    def generate_class_info(cls)\n      if cls === RDoc::NormalModule\n        cls_desc = RI::ModuleDescription.new\n      else\n        cls_desc = RI::ClassDescription.new\n        cls_desc.superclass  = cls.superclass\n      end\n      cls_desc.name        = cls.name\n      cls_desc.full_name   = cls.full_name\n      cls_desc.comment     = markup(cls.comment)\n\n      cls_desc.attributes =cls.attributes.sort.map do |a|\n        RI::Attribute.new(a.name, a.rw, markup(a.comment))\n      end\n\n      cls_desc.constants = cls.constants.map do |c|\n        RI::Constant.new(c.name, c.value, markup(c.comment))\n      end\n\n      cls_desc.includes = cls.includes.map do |i|\n        RI::IncludedModule.new(i.name)\n      end\n\n      class_methods, instance_methods = method_list(cls)\n\n      cls_desc.class_methods = class_methods.map do |m|\n        RI::MethodSummary.new(m.name)\n      end\n      cls_desc.instance_methods = instance_methods.map do |m|\n        RI::MethodSummary.new(m.name)\n      end\n\n      update_or_replace(cls_desc)\n\n      class_methods.each do |m|\n        generate_method_info(cls_desc, m)\n      end\n\n      instance_methods.each do |m|\n        generate_method_info(cls_desc, m)\n      end\n    end\n\n\n    def generate_method_info(cls_desc, method)\n      meth_desc = RI::MethodDescription.new\n      meth_desc.name = method.name\n      meth_desc.full_name = cls_desc.full_name\n      if method.singleton\n        meth_desc.full_name += \"::\"\n      else\n        meth_desc.full_name += \"#\"\n      end\n      meth_desc.full_name << method.name\n\n      meth_desc.comment = markup(method.comment)\n      meth_desc.params = params_of(method)\n      meth_desc.visibility = method.visibility.to_s\n      meth_desc.is_singleton = method.singleton\n      meth_desc.block_params = method.block_params\n\n      meth_desc.aliases = method.aliases.map do |a|\n        RI::AliasName.new(a.name)\n      end\n\n      @ri_writer.add_method(cls_desc, meth_desc)\n    end\n\n    private\n\n    # return a list of class and instance methods that we'll be\n    # documenting\n\n    def method_list(cls)\n      list = cls.method_list\n      unless @options.show_all\n        list = list.find_all do |m|\n          m.visibility == :public || m.visibility == :protected || m.force_documentation\n        end\n      end\n\n      c = []\n      i = []\n      list.sort.each do |m|\n        if m.singleton\n          c << m\n        else\n          i << m\n        end\n      end\n      return c,i\n    end\n    \n    def params_of(method)\n      if method.call_seq\n        method.call_seq\n      else\n        params = method.params || \"\"\n        \n        p = params.gsub(/\\s*\\#.*/, '')\n        p = p.tr(\"\\n\", \" \").squeeze(\" \")\n        p = \"(\" + p + \")\" unless p[0] == ?(\n        \n        if (block = method.block_params)\n          block.gsub!(/\\s*\\#.*/, '')\n          block = block.tr(\"\\n\", \" \").squeeze(\" \")\n          if block[0] == ?(\n            block.sub!(/^\\(/, '').sub!(/\\)/, '')\n          end\n          p << \" {|#{block.strip}| ...}\"\n        end\n        p\n      end\n    end\n\n    def markup(comment)\n      return nil if !comment || comment.empty?\n\n      # Convert leading comment markers to spaces, but only\n      # if all non-blank lines have them\n      \n      if comment =~ /^(?>\\s*)[^\\#]/\n        content = comment\n      else\n        content = comment.gsub(/^\\s*(#+)/)  { $1.tr('#',' ') }\n      end\n      @markup.convert(content, @to_flow)\n    end\n\n\n    # By default we replace existing classes with the\n    # same name. If the --merge option was given, we instead\n    # merge this definition into an existing class. We add\n    # our methods, aliases, etc to that class, but do not\n    # change the class's description.\n\n    def update_or_replace(cls_desc)\n      old_cls = nil\n\n      if @options.merge\n        rdr = RI::RiReader.new(RI::RiCache.new(@options.op_dir))\n\n        namespace = rdr.top_level_namespace\n        namespace = rdr.lookup_namespace_in(cls_desc.name, namespace)\n        if namespace.empty?\n          $stderr.puts \"You asked me to merge this source into existing \"\n          $stderr.puts \"documentation. This file references a class or \"\n          $stderr.puts \"module called #{cls_desc.name} which I don't\"\n          $stderr.puts \"have existing documentation for.\"\n          $stderr.puts \n          $stderr.puts \"Perhaps you need to generate its documentation first\"\n          exit 1\n        else\n          old_cls = namespace[0]\n        end\n      end\n\n      if old_cls.nil?\n        # no merge: simply overwrite\n        @ri_writer.remove_class(cls_desc)\n        @ri_writer.add_class(cls_desc)\n      else\n        # existing class: merge in\n        old_desc = rdr.get_class(old_cls)\n\n        old_desc.merge_in(cls_desc)\n        @ri_writer.add_class(old_desc)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/generators/template/chm/chm.rb",
    "content": "module RDoc\nmodule Page\n\nrequire \"rdoc/generators/template/html/html\"\n\n# This is a nasty little hack, but hhc doesn't support the <?xml\n# tag, so...\n\nBODY.sub!(/<\\?xml.*\\?>/, '')\nSRC_PAGE.sub!(/<\\?xml.*\\?>/, '')\n\nHPP_FILE = %{\n[OPTIONS]\nAuto Index = Yes\nCompatibility=1.1 or later\nCompiled file=%opname%.chm\nContents file=contents.hhc\nFull-text search=Yes\nIndex file=index.hhk\nLanguage=0x409 English(United States)\nTitle=%title%\n\n[FILES]\nSTART:all_html_files\n%html_file_name%\nEND:all_html_files\n}\n\nCONTENTS = %{\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n<HEAD>\n<meta name=\"GENERATOR\" content=\"Microsoft&reg; HTML Help Workshop 4.1\">\n<!-- Sitemap 1.0 -->\n</HEAD><BODY>\n<OBJECT type=\"text/site properties\">\n\t<param name=\"Foreground\" value=\"0x80\">\n\t<param name=\"Window Styles\" value=\"0x800025\">\n\t<param name=\"ImageType\" value=\"Folder\">\n</OBJECT>\n<UL>\nSTART:contents\n\t<LI> <OBJECT type=\"text/sitemap\">\n\t\t<param name=\"Name\" value=\"%c_name%\">\n\t\t<param name=\"Local\" value=\"%ref%\">\n\t\t</OBJECT>\nIF:methods\n<ul>\nSTART:methods\n\t<LI> <OBJECT type=\"text/sitemap\">\n\t\t<param name=\"Name\" value=\"%name%\">\n\t\t<param name=\"Local\" value=\"%aref%\">\n\t\t</OBJECT>\nEND:methods\n</ul>\nENDIF:methods\n        </LI>\nEND:contents\n</UL>\n</BODY></HTML>\n}\n\n\nCHM_INDEX  = %{\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n<HEAD>\n<meta name=\"GENERATOR\" content=\"Microsoft&reg; HTML Help Workshop 4.1\">\n<!-- Sitemap 1.0 -->\n</HEAD><BODY>\n<OBJECT type=\"text/site properties\">\n\t<param name=\"Foreground\" value=\"0x80\">\n\t<param name=\"Window Styles\" value=\"0x800025\">\n\t<param name=\"ImageType\" value=\"Folder\">\n</OBJECT>\n<UL>\nSTART:index\n\t<LI> <OBJECT type=\"text/sitemap\">\n\t\t<param name=\"Name\" value=\"%name%\">\n\t\t<param name=\"Local\" value=\"%aref%\">\n\t\t</OBJECT>\nEND:index\n</UL>\n</BODY></HTML>\n}\nend\nend\n"
  },
  {
    "path": "lib/rdoc/generators/template/html/hefss.rb",
    "content": "module RDoc\nmodule Page\n\n\nFONTS = \"Verdana, Arial, Helvetica, sans-serif\"\n\nSTYLE = %{\nbody,p { font-family: Verdana, Arial, Helvetica, sans-serif; \n       color: #000040; background: #BBBBBB;\n}\n\ntd { font-family: Verdana, Arial, Helvetica, sans-serif; \n       color: #000040;\n}\n\n.attr-rw { font-size: small; color: #444488 }\n\n.title-row {color:      #eeeeff;\n\t    background: #BBBBDD;\n}\n\n.big-title-font { color: white;\n                  font-family: Verdana, Arial, Helvetica, sans-serif;\n                  font-size: large; \n                  height: 50px}\n\n.small-title-font { color: purple;\n                    font-family: Verdana, Arial, Helvetica, sans-serif;\n                    font-size: small; }\n\n.aqua { color: purple }\n\n.method-name, attr-name {\n      font-family: monospace; font-weight: bold;\n}\n\n.tablesubtitle {\n   width: 100%;\n   margin-top: 1ex;\n   margin-bottom: .5ex;\n   padding: 5px 0px 5px 20px;\n   font-size: large;\n   color: purple;\n   background: #BBBBCC;\n}\n\n.tablesubsubtitle {\n   width: 100%;\n   margin-top: 1ex;\n   margin-bottom: .5ex;\n   padding: 5px 0px 5px 20px;\n   font-size: medium;\n   color: white;\n   background: #BBBBCC;\n}\n\n.name-list {\n  font-family: monospace;\n  margin-left: 40px;\n  margin-bottom: 2ex;\n  line-height: 140%;\n}\n\n.description {\n  margin-left: 40px;\n  margin-bottom: 2ex;\n  line-height: 140%;\n}\n\n.methodtitle {\n  font-size: medium;\n  text_decoration: none;\n  padding: 3px 3px 3px 20px;\n  color: #0000AA;\n}\n\n.column-title {\n  font-size: medium;\n  font-weight: bold;\n  text_decoration: none;\n  padding: 3px 3px 3px 20px;\n  color: #3333CC;\n  }\n\n.variable-name {\n  font-family: monospace;\n  font-size: medium;\n  text_decoration: none;\n  padding: 3px 3px 3px 20px;\n  color: #0000AA;\n}\n\n.row-name {\n  font-size: medium;\n  font-weight: medium;\n  font-family: monospace;\n  text_decoration: none;\n  padding: 3px 3px 3px 20px;\n}\n\n.paramsig {\n   font-size: small;\n}\n\n.srcbut { float: right }\n\n}\n\n\n############################################################################\n\n\nBODY = %{\n<html><head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n  <link rel=\"stylesheet\" href=\"%style_url%\" type=\"text/css\" media=\"screen\" />\n  <script type=\"text/javascript\" language=\"JavaScript\">\n  <!--\n  function popCode(url) {\n    parent.frames.source.location = url\n  }\n  //-->\n  </script>\n</head>\n<body bgcolor=\"#BBBBBB\">\n\n!INCLUDE!  <!-- banner header -->\n\nIF:diagram\n<table width=\"100%\"><tr><td align=\"center\">\n%diagram%\n</td></tr></table>\nENDIF:diagram\n\nIF:description\n<div class=\"description\">%description%</div>\nENDIF:description\n\nIF:requires\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Required files</td></tr>\n</table><br />\n<div class=\"name-list\">\nSTART:requires\nHREF:aref:name:\nEND:requires\nENDIF:requires\n</div>\n\nIF:methods\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Subroutines and Functions</td></tr>\n</table><br />\n<div class=\"name-list\">\nSTART:methods\nHREF:aref:name:,\nEND:methods\n</div>\nENDIF:methods\n\nIF:attributes\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Arguments</td></tr>\n</table><br />\n<table cellspacing=\"5\">\nSTART:attributes\n     <tr valign=\"top\">\nIF:rw\n       <td align=\"center\" class=\"attr-rw\">&nbsp;[%rw%]&nbsp;</td>\nENDIF:rw\nIFNOT:rw\n       <td></td>\nENDIF:rw\n       <td class=\"attr-name\">%name%</td>\n       <td>%a_desc%</td>\n     </tr>\nEND:attributes\n</table>\nENDIF:attributes\n\nIF:classlist\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Modules</td></tr>\n</table><br />\n%classlist%<br />\nENDIF:classlist\n\n  !INCLUDE!  <!-- method descriptions -->\n\n</body>\n</html>\n}\n\n###############################################################################\n\nFILE_PAGE = <<_FILE_PAGE_\n<table width=\"100%\">\n <tr class=\"title-row\">\n <td><table width=\"100%\"><tr>\n   <td class=\"big-title-font\" colspan=\"2\"><font size=\"-3\"><b>File</b><br /></font>%short_name%</td>\n   <td align=\"right\"><table cellspacing=\"0\" cellpadding=\"2\">\n         <tr>\n           <td  class=\"small-title-font\">Path:</td>\n           <td class=\"small-title-font\">%full_path%\nIF:cvsurl\n\t\t\t\t&nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\n           </td>\n         </tr>\n         <tr>\n           <td class=\"small-title-font\">Modified:</td>\n           <td class=\"small-title-font\">%dtm_modified%</td>\n         </tr>\n        </table>\n    </td></tr></table></td>\n  </tr>\n</table><br />\n_FILE_PAGE_\n\n###################################################################\n\nCLASS_PAGE = %{\n<table width=\"100%\" border=\"0\" cellspacing=\"0\">\n <tr class=\"title-row\">\n <td class=\"big-title-font\">\n   <font size=\"-3\"><b>%classmod%</b><br /></font>%full_name%\n </td>\n <td align=\"right\">\n   <table cellspacing=\"0\" cellpadding=\"2\">\n     <tr valign=\"top\">\n      <td class=\"small-title-font\">In:</td>\n      <td class=\"small-title-font\">\nSTART:infiles\nHREF:full_path_url:full_path:\nIF:cvsurl\n&nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\nEND:infiles\n      </td>\n     </tr>\nIF:parent\n     <tr>\n      <td class=\"small-title-font\">Parent:</td>\n      <td class=\"small-title-font\">\nIF:par_url\n        <a href=\"%par_url%\" class=\"cyan\">\nENDIF:par_url\n%parent%\nIF:par_url\n         </a>\nENDIF:par_url\n      </td>\n     </tr>\nENDIF:parent\n   </table>\n  </td>\n  </tr>\n</table><br />\n}\n\n###################################################################\n\nMETHOD_LIST = %{\nIF:includes\n<div class=\"tablesubsubtitle\">Uses</div><br />\n<div class=\"name-list\">\nSTART:includes\n    <span class=\"method-name\">HREF:aref:name:</span>\nEND:includes\n</div>\nENDIF:includes\n\nIF:method_list\nSTART:method_list\nIF:methods\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">%type% %category% methods</td></tr>\n</table>\nSTART:methods\n<table width=\"100%\" cellspacing=\"0\" cellpadding=\"5\" border=\"0\">\n<tr><td class=\"methodtitle\">\n<a name=\"%aref%\">\n<b>%name%</b>%params% \nIF:codeurl\n<a href=\"%codeurl%\" target=\"source\" class=\"srclink\">src</a>\nENDIF:codeurl\n</a></td></tr>\n</table>\nIF:m_desc\n<div class=\"description\">\n%m_desc%\n</div>\nENDIF:m_desc\nEND:methods\nENDIF:methods\nEND:method_list\nENDIF:method_list\n}\n\n=begin\n=end\n\n########################## Source code ##########################\n\nSRC_PAGE = %{\n<html>\n<head><title>%title%</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<style type=\"text/css\">\n  .kw { color: #3333FF; font-weight: bold }\n  .cmt { color: green; font-style: italic }\n  .str { color: #662222; font-style: italic }\n  .re  { color: #662222; }\n.ruby-comment    { color: green; font-style: italic }\n.ruby-constant   { color: #4433aa; font-weight: bold; }\n.ruby-identifier { color: #222222;  }\n.ruby-ivar       { color: #2233dd; }\n.ruby-keyword    { color: #3333FF; font-weight: bold }\n.ruby-node       { color: #777777; }\n.ruby-operator   { color: #111111;  }\n.ruby-regexp     { color: #662222; }\n.ruby-value      { color: #662222; font-style: italic }\n</style>\n</head>\n<body bgcolor=\"#BBBBBB\">\n<pre>%code%</pre>\n</body>\n</html>\n}\n\n########################## Index ################################\n\nFR_INDEX_BODY = %{\n!INCLUDE!\n}\n\nFILE_INDEX = %{\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<style type=\"text/css\">\n<!--\n  body {\nbackground-color: #bbbbbb;\n     font-family: #{FONTS}; \n       font-size: 11px; \n      font-style: normal;\n     line-height: 14px; \n           color: #000040;\n  }\ndiv.banner {\n  background: #bbbbcc;\n  color:      white;\n  padding: 1;\n  margin: 0;\n  font-size: 90%;\n  font-weight: bold;\n  line-height: 1.1;\n  text-align: center;\n  width: 100%;\n}\n  \n-->\n</style>\n<base target=\"docwin\">\n</head>\n<body>\n<div class=\"banner\">%list_title%</div>\nSTART:entries\n<a href=\"%href%\">%name%</a><br />\nEND:entries\n</body></html>\n}\n\nCLASS_INDEX = FILE_INDEX\nMETHOD_INDEX = FILE_INDEX\n\nINDEX = %{\n<html>\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n</head>\n\n<frameset cols=\"20%,*\">\n    <frameset rows=\"15%,35%,50%\">\n        <frame src=\"fr_file_index.html\"   title=\"Files\" name=\"Files\">\n        <frame src=\"fr_class_index.html\"  name=\"Modules\">\n        <frame src=\"fr_method_index.html\" name=\"Subroutines and Functions\">\n    </frameset>\n    <frameset rows=\"80%,20%\">\n      <frame  src=\"%initial_page%\" name=\"docwin\">\n      <frame  src=\"blank.html\" name=\"source\">\n    </frameset>\n    <noframes>\n          <body bgcolor=\"#BBBBBB\">\n            Click <a href=\"html/index.html\">here</a> for a non-frames\n            version of this page.\n          </body>\n    </noframes>\n</frameset>\n\n</html>\n}\n\n# and a blank page to use as a target\nBLANK = %{\n<html><body bgcolor=\"#BBBBBB\"></body></html>\n}\n\ndef write_extra_pages\n  template = TemplatePage.new(BLANK)\n  File.open(\"blank.html\", \"w\") { |f| template.write_html_on(f, {}) }\nend\n\nend\nend\n"
  },
  {
    "path": "lib/rdoc/generators/template/html/html.rb",
    "content": "#\n# = CSS2 RDoc HTML template\n#\n# This is a template for RDoc that uses XHTML 1.0 Transitional and dictates a\n# bit more of the appearance of the output to cascading stylesheets than the\n# default. It was designed for clean inline code display, and uses DHTMl to\n# toggle the visbility of each method's source with each click on the '[source]'\n# link.\n#\n# == Authors\n#\n# * Michael Granger <ged@FaerieMUD.org>\n#\n# Copyright (c) 2002, 2003 The FaerieMUD Consortium. Some rights reserved.\n#\n# This work is licensed under the Creative Commons Attribution License. To view\n# a copy of this license, visit http://creativecommons.org/licenses/by/1.0/ or\n# send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California\n# 94305, USA.\n#\n\nmodule RDoc\n  module Page\n\n    FONTS = \"Verdana,Arial,Helvetica,sans-serif\"\n\nSTYLE = %{\nbody {\n    font-family: Verdana,Arial,Helvetica,sans-serif;\n    font-size:   90%;\n    margin: 0;\n    margin-left: 40px;\n    padding: 0;\n    background: white;\n}\n\nh1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }\nh1 { font-size: 150%; }\nh2,h3,h4 { margin-top: 1em; }\n\na { background: #eef; color: #039; text-decoration: none; }\na:hover { background: #039; color: #eef; }\n\n/* Override the base stylesheet's Anchor inside a table cell */\ntd > a {\n  background: transparent;\n  color: #039;\n  text-decoration: none;\n}\n\n/* and inside a section title */\n.section-title > a {\n  background: transparent;\n  color: #eee;\n  text-decoration: none;\n}\n\n/* === Structural elements =================================== */\n\ndiv#index {\n    margin: 0;\n    margin-left: -40px;\n    padding: 0;\n    font-size: 90%;\n}\n\n\ndiv#index a {\n    margin-left: 0.7em;\n}\n\ndiv#index .section-bar {\n   margin-left: 0px;\n   padding-left: 0.7em;\n   background: #ccc;\n   font-size: small;\n}\n\n\ndiv#classHeader, div#fileHeader {\n    width: auto;\n    color: white;\n    padding: 0.5em 1.5em 0.5em 1.5em;\n    margin: 0;\n    margin-left: -40px;\n    border-bottom: 3px solid #006;\n}\n\ndiv#classHeader a, div#fileHeader a {\n    background: inherit;\n    color: white;\n}\n\ndiv#classHeader td, div#fileHeader td {\n    background: inherit;\n    color: white;\n}\n\n\ndiv#fileHeader {\n    background: #057;\n}\n\ndiv#classHeader {\n    background: #048;\n}\n\n\n.class-name-in-header {\n  font-size:  180%;\n  font-weight: bold;\n}\n\n\ndiv#bodyContent {\n    padding: 0 1.5em 0 1.5em;\n}\n\ndiv#description {\n    padding: 0.5em 1.5em;\n    background: #efefef;\n    border: 1px dotted #999;\n}\n\ndiv#description h1,h2,h3,h4,h5,h6 {\n    color: #125;;\n    background: transparent;\n}\n\ndiv#validator-badges {\n    text-align: center;\n}\ndiv#validator-badges img { border: 0; }\n\ndiv#copyright {\n    color: #333;\n    background: #efefef;\n    font: 0.75em sans-serif;\n    margin-top: 5em;\n    margin-bottom: 0;\n    padding: 0.5em 2em;\n}\n\n\n/* === Classes =================================== */\n\ntable.header-table {\n    color: white;\n    font-size: small;\n}\n\n.type-note {\n    font-size: small;\n    color: #DEDEDE;\n}\n\n.xxsection-bar {\n    background: #eee;\n    color: #333;\n    padding: 3px;\n}\n\n.section-bar {\n   color: #333;\n   border-bottom: 1px solid #999;\n    margin-left: -20px;\n}\n\n\n.section-title {\n    background: #79a;\n    color: #eee;\n    padding: 3px;\n    margin-top: 2em;\n    margin-left: -30px;\n    border: 1px solid #999;\n}\n\n.top-aligned-row {  vertical-align: top }\n.bottom-aligned-row { vertical-align: bottom }\n\n/* --- Context section classes ----------------------- */\n\n.context-row { }\n.context-item-name { font-family: monospace; font-weight: bold; color: black; }\n.context-item-value { font-size: small; color: #448; }\n.context-item-desc { color: #333; padding-left: 2em; }\n\n/* --- Method classes -------------------------- */\n.method-detail {\n    background: #efefef;\n    padding: 0;\n    margin-top: 0.5em;\n    margin-bottom: 1em;\n    border: 1px dotted #ccc;\n}\n.method-heading {\n  color: black;\n  background: #ccc;\n  border-bottom: 1px solid #666;\n  padding: 0.2em 0.5em 0 0.5em;\n}\n.method-signature { color: black; background: inherit; }\n.method-name { font-weight: bold; }\n.method-args { font-style: italic; }\n.method-description { padding: 0 0.5em 0 0.5em; }\n\n/* --- Source code sections -------------------- */\n\na.source-toggle { font-size: 90%; }\ndiv.method-source-code {\n    background: #262626;\n    color: #ffdead;\n    margin: 1em;\n    padding: 0.5em;\n    border: 1px dashed #999;\n    overflow: hidden;\n}\n\ndiv.method-source-code pre { color: #ffdead; overflow: hidden; }\n\n/* --- Ruby keyword styles --------------------- */\n\n.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }\n\n.ruby-constant  { color: #7fffd4; background: transparent; }\n.ruby-keyword { color: #00ffff; background: transparent; }\n.ruby-ivar    { color: #eedd82; background: transparent; }\n.ruby-operator  { color: #00ffee; background: transparent; }\n.ruby-identifier { color: #ffdead; background: transparent; }\n.ruby-node    { color: #ffa07a; background: transparent; }\n.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }\n.ruby-regexp  { color: #ffa07a; background: transparent; }\n.ruby-value   { color: #7fffd4; background: transparent; }\n}\n\n\n#####################################################################\n### H E A D E R   T E M P L A T E  \n#####################################################################\n\nXHTML_PREAMBLE = %{<?xml version=\"1.0\" encoding=\"%charset%\"?>\n<!DOCTYPE html \n     PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n     \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n}\n\nHEADER = XHTML_PREAMBLE + %{\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\" />\n  <meta http-equiv=\"Content-Script-Type\" content=\"text/javascript\" />\n  <link rel=\"stylesheet\" href=\"%style_url%\" type=\"text/css\" media=\"screen\" />\n  <script type=\"text/javascript\">\n  // <![CDATA[\n\n  function popupCode( url ) {\n    window.open(url, \"Code\", \"resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400\")\n  }\n\n  function toggleCode( id ) {\n    if ( document.getElementById )\n      elem = document.getElementById( id );\n    else if ( document.all )\n      elem = eval( \"document.all.\" + id );\n    else\n      return false;\n\n    elemStyle = elem.style;\n    \n    if ( elemStyle.display != \"block\" ) {\n      elemStyle.display = \"block\"\n    } else {\n      elemStyle.display = \"none\"\n    }\n\n    return true;\n  }\n  \n  // Make codeblocks hidden by default\n  document.writeln( \"<style type=\\\\\"text/css\\\\\">div.method-source-code { display: none }</style>\" )\n  \n  // ]]>\n  </script>\n\n</head>\n<body>\n}\n\n\n#####################################################################\n### C O N T E X T   C O N T E N T   T E M P L A T E\n#####################################################################\n\nCONTEXT_CONTENT = %{\n}\n\n\n#####################################################################\n### F O O T E R   T E M P L A T E\n#####################################################################\nFOOTER = %{\n<div id=\"validator-badges\">\n  <p><small><a href=\"http://validator.w3.org/check/referer\">[Validate]</a></small></p>\n</div>\n\n</body>\n</html>\n}\n\n\n#####################################################################\n### F I L E   P A G E   H E A D E R   T E M P L A T E\n#####################################################################\n\nFILE_PAGE = %{\n  <div id=\"fileHeader\">\n    <h1>%short_name%</h1>\n    <table class=\"header-table\">\n    <tr class=\"top-aligned-row\">\n      <td><strong>Path:</strong></td>\n      <td>%full_path%\nIF:cvsurl\n        &nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\n      </td>\n    </tr>\n    <tr class=\"top-aligned-row\">\n      <td><strong>Last Update:</strong></td>\n      <td>%dtm_modified%</td>\n    </tr>\n    </table>\n  </div>\n}\n\n\n#####################################################################\n### C L A S S   P A G E   H E A D E R   T E M P L A T E\n#####################################################################\n\nCLASS_PAGE = %{\n    <div id=\"classHeader\">\n        <table class=\"header-table\">\n        <tr class=\"top-aligned-row\">\n          <td><strong>%classmod%</strong></td>\n          <td class=\"class-name-in-header\">%full_name%</td>\n        </tr>\n        <tr class=\"top-aligned-row\">\n            <td><strong>In:</strong></td>\n            <td>\nSTART:infiles\nIF:full_path_url\n                <a href=\"%full_path_url%\">\nENDIF:full_path_url\n                %full_path%\nIF:full_path_url\n                </a>\nENDIF:full_path_url\nIF:cvsurl\n        &nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\n        <br />\nEND:infiles\n            </td>\n        </tr>\n\nIF:parent\n        <tr class=\"top-aligned-row\">\n            <td><strong>Parent:</strong></td>\n            <td>\nIF:par_url\n                <a href=\"%par_url%\">\nENDIF:par_url\n                %parent%\nIF:par_url\n               </a>\nENDIF:par_url\n            </td>\n        </tr>\nENDIF:parent\n        </table>\n    </div>\n}\n\n\n#####################################################################\n### M E T H O D   L I S T   T E M P L A T E\n#####################################################################\n\nMETHOD_LIST = %{\n\n  <div id=\"contextContent\">\nIF:diagram\n    <div id=\"diagram\">\n      %diagram%\n    </div>\nENDIF:diagram\n\nIF:description\n    <div id=\"description\">\n      %description%\n    </div>\nENDIF:description\n\nIF:requires\n    <div id=\"requires-list\">\n      <h3 class=\"section-bar\">Required files</h3>\n\n      <div class=\"name-list\">\nSTART:requires\n      HREF:aref:name:&nbsp;&nbsp;\nEND:requires\n      </div>\n    </div>\nENDIF:requires\n\nIF:toc\n    <div id=\"contents-list\">\n      <h3 class=\"section-bar\">Contents</h3>\n      <ul>\nSTART:toc\n      <li><a href=\"#%href%\">%secname%</a></li>\nEND:toc\n     </ul>\nENDIF:toc\n   </div>\n\nIF:methods\n    <div id=\"method-list\">\n      <h3 class=\"section-bar\">Methods</h3>\n\n      <div class=\"name-list\">\nSTART:methods\n      HREF:aref:name:&nbsp;&nbsp;\nEND:methods\n      </div>\n    </div>\nENDIF:methods\n\n  </div>\n\n\n    <!-- if includes -->\nIF:includes\n    <div id=\"includes\">\n      <h3 class=\"section-bar\">Included Modules</h3>\n\n      <div id=\"includes-list\">\nSTART:includes\n        <span class=\"include-name\">HREF:aref:name:</span>\nEND:includes\n      </div>\n    </div>\nENDIF:includes\n\nSTART:sections\n    <div id=\"section\">\nIF:sectitle\n      <h2 class=\"section-title\"><a name=\"%secsequence%\">%sectitle%</a></h2>\nIF:seccomment\n      <div class=\"section-comment\">\n        %seccomment%\n      </div>      \nENDIF:seccomment\nENDIF:sectitle\n\nIF:classlist\n    <div id=\"class-list\">\n      <h3 class=\"section-bar\">Classes and Modules</h3>\n\n      %classlist%\n    </div>\nENDIF:classlist\n\nIF:constants\n    <div id=\"constants-list\">\n      <h3 class=\"section-bar\">Constants</h3>\n\n      <div class=\"name-list\">\n        <table summary=\"Constants\">\nSTART:constants\n        <tr class=\"top-aligned-row context-row\">\n          <td class=\"context-item-name\">%name%</td>\n          <td>=</td>\n          <td class=\"context-item-value\">%value%</td>\nIF:desc\n          <td width=\"3em\">&nbsp;</td>\n          <td class=\"context-item-desc\">%desc%</td>\nENDIF:desc\n        </tr>\nEND:constants\n        </table>\n      </div>\n    </div>\nENDIF:constants\n\nIF:aliases\n    <div id=\"aliases-list\">\n      <h3 class=\"section-bar\">External Aliases</h3>\n\n      <div class=\"name-list\">\n                        <table summary=\"aliases\">\nSTART:aliases\n        <tr class=\"top-aligned-row context-row\">\n          <td class=\"context-item-name\">%old_name%</td>\n          <td>-&gt;</td>\n          <td class=\"context-item-value\">%new_name%</td>\n        </tr>\nIF:desc\n      <tr class=\"top-aligned-row context-row\">\n        <td>&nbsp;</td>\n        <td colspan=\"2\" class=\"context-item-desc\">%desc%</td>\n      </tr>\nENDIF:desc\nEND:aliases\n                        </table>\n      </div>\n    </div>\nENDIF:aliases\n\n\nIF:attributes\n    <div id=\"attribute-list\">\n      <h3 class=\"section-bar\">Attributes</h3>\n\n      <div class=\"name-list\">\n        <table>\nSTART:attributes\n        <tr class=\"top-aligned-row context-row\">\n          <td class=\"context-item-name\">%name%</td>\nIF:rw\n          <td class=\"context-item-value\">&nbsp;[%rw%]&nbsp;</td>\nENDIF:rw\nIFNOT:rw\n          <td class=\"context-item-value\">&nbsp;&nbsp;</td>\nENDIF:rw\n          <td class=\"context-item-desc\">%a_desc%</td>\n        </tr>\nEND:attributes\n        </table>\n      </div>\n    </div>\nENDIF:attributes\n      \n\n\n    <!-- if method_list -->\nIF:method_list\n    <div id=\"methods\">\nSTART:method_list\nIF:methods\n      <h3 class=\"section-bar\">%type% %category% methods</h3>\n\nSTART:methods\n      <div id=\"method-%aref%\" class=\"method-detail\">\n        <a name=\"%aref%\"></a>\n\n        <div class=\"method-heading\">\nIF:codeurl\n          <a href=\"%codeurl%\" target=\"Code\" class=\"method-signature\"\n            onclick=\"popupCode('%codeurl%');return false;\">\nENDIF:codeurl\nIF:sourcecode\n          <a href=\"#%aref%\" class=\"method-signature\">\nENDIF:sourcecode\nIF:callseq\n          <span class=\"method-name\">%callseq%</span>\nENDIF:callseq\nIFNOT:callseq\n          <span class=\"method-name\">%name%</span><span class=\"method-args\">%params%</span>\nENDIF:callseq\nIF:codeurl\n          </a>\nENDIF:codeurl\nIF:sourcecode\n          </a>\nENDIF:sourcecode\n        </div>\n      \n        <div class=\"method-description\">\nIF:m_desc\n          %m_desc%\nENDIF:m_desc\nIF:sourcecode\n          <p><a class=\"source-toggle\" href=\"#\"\n            onclick=\"toggleCode('%aref%-source');return false;\">[Source]</a></p>\n          <div class=\"method-source-code\" id=\"%aref%-source\">\n<pre>\n%sourcecode%\n</pre>\n          </div>\nENDIF:sourcecode\n        </div>\n      </div>\n\nEND:methods\nENDIF:methods\nEND:method_list\n\n    </div>\nENDIF:method_list\nEND:sections\n}\n\n\n#####################################################################\n### B O D Y   T E M P L A T E\n#####################################################################\n\nBODY = HEADER + %{\n\n!INCLUDE!  <!-- banner header -->\n\n  <div id=\"bodyContent\">\n\n} +  METHOD_LIST + %{\n\n  </div>\n\n} + FOOTER\n\n\n\n#####################################################################\n### S O U R C E   C O D E   T E M P L A T E\n#####################################################################\n\nSRC_PAGE = XHTML_PREAMBLE + %{\n<html>\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\" />\n  <link rel=\"stylesheet\" href=\"%style_url%\" type=\"text/css\" media=\"screen\" />\n</head>\n<body class=\"standalone-code\">\n  <pre>%code%</pre>\n</body>\n</html>\n}\n\n\n#####################################################################\n### I N D E X   F I L E   T E M P L A T E S\n#####################################################################\n\nFR_INDEX_BODY = %{\n!INCLUDE!\n}\n\nFILE_INDEX = XHTML_PREAMBLE + %{\n<!--\n\n    %list_title%\n\n  -->\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n  <title>%list_title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\" />\n  <link rel=\"stylesheet\" href=\"%style_url%\" type=\"text/css\" />\n  <base target=\"docwin\" />\n</head>\n<body>\n<div id=\"index\">\n  <h1 class=\"section-bar\">%list_title%</h1>\n  <div id=\"index-entries\">\nSTART:entries\n    <a href=\"%href%\">%name%</a><br />\nEND:entries\n  </div>\n</div>\n</body>\n</html>\n}\n\nCLASS_INDEX = FILE_INDEX\nMETHOD_INDEX = FILE_INDEX\n\nINDEX = %{<?xml version=\"1.0\" encoding=\"%charset%\"?>\n<!DOCTYPE html \n     PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\"\n     \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n\n<!--\n\n    %title%\n\n  -->\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\" />\n</head>\n<frameset rows=\"20%, 80%\">\n    <frameset cols=\"25%,35%,45%\">\n        <frame src=\"fr_file_index.html\"   title=\"Files\" name=\"Files\" />\n        <frame src=\"fr_class_index.html\"  name=\"Classes\" />\n        <frame src=\"fr_method_index.html\" name=\"Methods\" />\n    </frameset>\n    <frame src=\"%initial_page%\" name=\"docwin\" />\n</frameset>\n</html>\n}\n\n\n\n  end # module Page\nend # class RDoc\n\nrequire 'rdoc/generators/template/html/one_page_html'\n"
  },
  {
    "path": "lib/rdoc/generators/template/html/kilmer.rb",
    "content": "module RDoc\nmodule Page\n\n\nFONTS = \"Verdana, Arial, Helvetica, sans-serif\"\n\nSTYLE = %{\nbody,td,p { font-family: %fonts%; \n       color: #000040;\n}\n\n.attr-rw { font-size: xx-small; color: #444488 }\n\n.title-row { background-color: #CCCCFF;\n             color:      #000010;\n}\n\n.big-title-font { \n  color: black;\n  font-weight: bold;\n  font-family: %fonts%; \n  font-size: large; \n  height: 60px;\n  padding: 10px 3px 10px 3px;\n}\n\n.small-title-font { color: black;\n                    font-family: %fonts%;\n                    font-size:10; }\n\n.aqua { color: black }\n\n.method-name, .attr-name {\n      font-family: font-family: %fonts%; \n      font-weight: bold;\n      font-size: small;\n      margin-left: 20px;\n      color: #000033;\n}\n\n.tablesubtitle, .tablesubsubtitle {\n   width: 100%;\n   margin-top: 1ex;\n   margin-bottom: .5ex;\n   padding: 5px 0px 5px 3px;\n   font-size: large;\n   color: black;\n   background-color: #CCCCFF;\n   border: thin;\n}\n\n.name-list {\n  margin-left: 5px;\n  margin-bottom: 2ex;\n  line-height: 105%;\n}\n\n.description {\n  margin-left: 5px;\n  margin-bottom: 2ex;\n  line-height: 105%;\n  font-size: small;\n}\n\n.methodtitle {\n  font-size: small;\n  font-weight: bold;\n  text-decoration: none;\n  color: #000033;\n  background-color: white; \n}\n\n.srclink {\n  font-size: small;\n  font-weight: bold;\n  text-decoration: none;\n  color: #0000DD;\n  background-color: white;\n}\n\n.paramsig {\n   font-size: small;\n}\n\n.srcbut { float: right }\n\n}\n\n\n############################################################################\n\n\nBODY = %{\n<html><head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n  <link rel=\"stylesheet\" href=\"%style_url%\" type=\"text/css\" media=\"screen\" />\n  <script type=\"text/javascript\" language=\"JavaScript\">\n  <!--\n  function popCode(url) {\n    parent.frames.source.location = url\n  }\n  //-->\n  </script>\n</head>\n<body bgcolor=\"white\">\n\n!INCLUDE!  <!-- banner header -->\n\nIF:diagram\n<table width=\"100%\"><tr><td align=\"center\">\n%diagram%\n</td></tr></table>\nENDIF:diagram\n\nIF:description\n<div class=\"description\">%description%</div>\nENDIF:description\n\nIF:requires\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Required files</td></tr>\n</table><br />\n<div class=\"name-list\">\nSTART:requires\nHREF:aref:name:\nEND:requires\nENDIF:requires\n</div>\n\nIF:methods\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Methods</td></tr>\n</table><br />\n<div class=\"name-list\">\nSTART:methods\nHREF:aref:name:,\nEND:methods\n</div>\nENDIF:methods\n\n\nSTART:sections\n    <div id=\"section\">\nIF:sectitle\n      <h2 class=\"section-title\"><a name=\"%secsequence%\">%sectitle%</a></h2>\nIF:seccomment\n      <div class=\"section-comment\">\n        %seccomment%\n      </div>      \nENDIF:seccomment\nENDIF:sectitle\n\nIF:attributes\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Attributes</td></tr>\n</table><br />\n<table cellspacing=\"5\">\nSTART:attributes\n     <tr valign=\"top\">\nIF:rw\n       <td align=\"center\" class=\"attr-rw\">&nbsp;[%rw%]&nbsp;</td>\nENDIF:rw\nIFNOT:rw\n       <td></td>\nENDIF:rw\n       <td class=\"attr-name\">%name%</td>\n       <td>%a_desc%</td>\n     </tr>\nEND:attributes\n</table>\nENDIF:attributes\n\nIF:classlist\n<table cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Classes and Modules</td></tr>\n</table><br />\n%classlist%<br />\nENDIF:classlist\n\n  !INCLUDE!  <!-- method descriptions -->\n\nEND:sections\n\n</body>\n</html>\n}\n\n###############################################################################\n\nFILE_PAGE = <<_FILE_PAGE_\n<table width=\"100%\">\n <tr class=\"title-row\">\n <td><table width=\"100%\"><tr>\n   <td class=\"big-title-font\" colspan=\"2\"><font size=\"-3\"><b>File</b><br /></font>%short_name%</td>\n   <td align=\"right\"><table cellspacing=\"0\" cellpadding=\"2\">\n         <tr>\n           <td  class=\"small-title-font\">Path:</td>\n           <td class=\"small-title-font\">%full_path%\nIF:cvsurl\n\t\t\t\t&nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\n           </td>\n         </tr>\n         <tr>\n           <td class=\"small-title-font\">Modified:</td>\n           <td class=\"small-title-font\">%dtm_modified%</td>\n         </tr>\n        </table>\n    </td></tr></table></td>\n  </tr>\n</table><br />\n_FILE_PAGE_\n\n###################################################################\n\nCLASS_PAGE = %{\n<table width=\"100%\" border=\"0\" cellspacing=\"0\">\n <tr class=\"title-row\">\n <td class=\"big-title-font\">\n   <font size=\"-3\"><b>%classmod%</b><br /></font>%full_name%\n </td>\n <td align=\"right\">\n   <table cellspacing=\"0\" cellpadding=\"2\">\n     <tr valign=\"top\">\n      <td class=\"small-title-font\">In:</td>\n      <td class=\"small-title-font\">\nSTART:infiles\nHREF:full_path_url:full_path:\nIF:cvsurl\n&nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\nEND:infiles\n      </td>\n     </tr>\nIF:parent\n     <tr>\n      <td class=\"small-title-font\">Parent:</td>\n      <td class=\"small-title-font\">\nIF:par_url\n        <a href=\"%par_url%\" class=\"cyan\">\nENDIF:par_url\n%parent%\nIF:par_url\n         </a>\nENDIF:par_url\n      </td>\n     </tr>\nENDIF:parent\n   </table>\n  </td>\n  </tr>\n</table><br />\n}\n\n###################################################################\n\nMETHOD_LIST = %{\nIF:includes\n<div class=\"tablesubsubtitle\">Included modules</div><br />\n<div class=\"name-list\">\nSTART:includes\n    <span class=\"method-name\">HREF:aref:name:</span>\nEND:includes\n</div>\nENDIF:includes\n\nIF:method_list\nSTART:method_list\nIF:methods\n<table cellpadding=5 width=\"100%\">\n<tr><td class=\"tablesubtitle\">%type% %category% methods</td></tr>\n</table>\nSTART:methods\n<table width=\"100%\" cellspacing=\"0\" cellpadding=\"5\" border=\"0\">\n<tr><td class=\"methodtitle\">\n<a name=\"%aref%\">\nIF:callseq\n<b>%callseq%</b>\nENDIF:callseq\nIFNOT:callseq\n <b>%name%</b>%params%\nENDIF:callseq\nIF:codeurl\n<a href=\"%codeurl%\" target=\"source\" class=\"srclink\">src</a>\nENDIF:codeurl\n</a></td></tr>\n</table>\nIF:m_desc\n<div class=\"description\">\n%m_desc%\n</div>\nENDIF:m_desc\nIF:aka\n<div class=\"aka\">\nThis method is also aliased as\nSTART:aka\n<a href=\"%aref%\">%name%</a>\nEND:aka\n</div>\nENDIF:aka\nIF:sourcecode\n<pre class=\"source\">\n%sourcecode%\n</pre>\nENDIF:sourcecode\nEND:methods\nENDIF:methods\nEND:method_list\nENDIF:method_list\n}\n\n=begin\n=end\n\n########################## Source code ##########################\n\nSRC_PAGE = %{\n<html>\n<head><title>%title%</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<style type=\"text/css\">\n.ruby-comment    { color: green; font-style: italic }\n.ruby-constant   { color: #4433aa; font-weight: bold; }\n.ruby-identifier { color: #222222;  }\n.ruby-ivar       { color: #2233dd; }\n.ruby-keyword    { color: #3333FF; font-weight: bold }\n.ruby-node       { color: #777777; }\n.ruby-operator   { color: #111111;  }\n.ruby-regexp     { color: #662222; }\n.ruby-value      { color: #662222; font-style: italic }\n  .kw { color: #3333FF; font-weight: bold }\n  .cmt { color: green; font-style: italic }\n  .str { color: #662222; font-style: italic }\n  .re  { color: #662222; }\n</style>\n</head>\n<body bgcolor=\"white\">\n<pre>%code%</pre>\n</body>\n</html>\n}\n\n########################## Index ################################\n\nFR_INDEX_BODY = %{\n!INCLUDE!\n}\n\nFILE_INDEX = %{\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<style>\n<!--\n  body {\nbackground-color: #ddddff;\n     font-family: #{FONTS}; \n       font-size: 11px; \n      font-style: normal;\n     line-height: 14px; \n           color: #000040;\n  }\ndiv.banner {\n  background: #0000aa;\n  color:      white;\n  padding: 1;\n  margin: 0;\n  font-size: 90%;\n  font-weight: bold;\n  line-height: 1.1;\n  text-align: center;\n  width: 100%;\n}\n  \n-->\n</style>\n<base target=\"docwin\">\n</head>\n<body>\n<div class=\"banner\">%list_title%</div>\nSTART:entries\n<a href=\"%href%\">%name%</a><br />\nEND:entries\n</body></html>\n}\n\nCLASS_INDEX = FILE_INDEX\nMETHOD_INDEX = FILE_INDEX\n\nINDEX = %{\n<html>\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n</head>\n\n<frameset cols=\"20%,*\">\n    <frameset rows=\"15%,35%,50%\">\n        <frame src=\"fr_file_index.html\"   title=\"Files\" name=\"Files\">\n        <frame src=\"fr_class_index.html\"  name=\"Classes\">\n        <frame src=\"fr_method_index.html\" name=\"Methods\">\n    </frameset>\nIF:inline_source\n      <frame  src=\"%initial_page%\" name=\"docwin\">\nENDIF:inline_source\nIFNOT:inline_source\n    <frameset rows=\"80%,20%\">\n      <frame  src=\"%initial_page%\" name=\"docwin\">\n      <frame  src=\"blank.html\" name=\"source\">\n    </frameset>\nENDIF:inline_source\n    <noframes>\n          <body bgcolor=\"white\">\n            Click <a href=\"html/index.html\">here</a> for a non-frames\n            version of this page.\n          </body>\n    </noframes>\n</frameset>\n\n</html>\n}\n\n# and a blank page to use as a target\nBLANK = %{\n<html><body bgcolor=\"white\"></body></html>\n}\n\ndef write_extra_pages\n  template = TemplatePage.new(BLANK)\n  File.open(\"blank.html\", \"w\") { |f| template.write_html_on(f, {}) }\nend\n\nend\nend\n"
  },
  {
    "path": "lib/rdoc/generators/template/html/old_html.rb",
    "content": "module RDoc\n\n# This is how you define the HTML that RDoc generates. Simply create\n# a file in rdoc/generators/html_templates that creates the\n# module RDoc::Page and populate it as described below. Then invoke\n# rdoc using the --template <name of your file> option, and\n# your template will be used.\n#\n# The constants defining pages use a simple templating system:\n#\n# * The templating system is passed a hash. Keys in the hash correspond\n#   to tags on this page. The tag %abc% is looked up in the hash,\n#   and is replaced by the corresponding hash value.\n#\n# * Some tags are optional. You can detect this using IF/ENDIF\n#\n#      IF: title\n#      The value of title is %title%\n#      ENDIF: title\n#\n# * Some entries in the hash have values that are arrays, where each\n#   entry in the array is itself a hash. These are used to generate\n#   lists using the START: construct. For example, given a hash\n#   containing\n# \n#      { 'people' => [ { 'name' => 'Fred', 'age' => '12' },\n#                      { 'name' => 'Mary', 'age' => '21' } ]\n#\n#   You could generate a simple table using\n#\n#      <table>\n#      START:people\n#        <tr><td>%name%<td>%age%</tr>\n#      END:people\n#      </table>\n#\n#   These lists can be nested to an arbitrary depth\n#\n# * the construct HREF:url:name: generates <a href=\"%url%\">%name%</a>\n#   if +url+ is defined in the hash, or %name% otherwise.\n#\n#\n# Your file must contain the following constants\n#\n# [*FONTS*]  a list of fonts to be used\n# [*STYLE*]  a CSS section (without the <style> or comments). This is\n#            used to generate a style.css file\n#\n# [*BODY*] \n#   The main body of all non-index RDoc pages. BODY will contain\n#   two !INCLUDE!s. The first is used to include a document-type\n#   specific header (FILE_PAGE or CLASS_PAGE). The second include\n#   is for the method list (METHOD_LIST). THe body is passed:\n#\n#   %title%::\n#       the page's title\n#\n#   %style_url%::\n#       the url of a style sheet for this page\n#\n#   %diagram%::\n#       the optional URL of a diagram for this page\n#\n#   %description%::\n#       a (potentially multi-paragraph) string containing the\n#       description for th file/class/module.\n#\n#   %requires%::\n#       an optional list of %aref%/%name% pairs, one for each module\n#       required by this file.\n#\n#   %methods%::\n#       an optional list of %aref%/%name%, one for each method\n#       documented on this page. This is intended to be an index.\n#\n#   %attributes%::  \n#       An optional list. For each attribute it contains:\n#       %name%::   the attribute name\n#       %rw%::     r/o, w/o, or r/w\n#       %a_desc%:: description of the attribute\n#\n#   %classlist%:: \n#       An optional string containing an already-formatted list of\n#       classes and modules documented in this file\n#\n#   For FILE_PAGE entries, the body will be passed\n#\n#   %short_name%::  \n#       The name of the file\n#\n#   %full_path%::\n#       The full path to the file\n#\n#   %dtm_modified%::\n#       The date/time the file was last changed\n#\n#   For class and module pages, the body will be passed\n#\n#   %classmod%::\n#       The name of the class or module\n#\n#   %files%::\n#       A list. For each file this class is defined in, it contains:\n#       %full_path_url%:: an (optional) URL of the RDoc page\n#                         for this file\n#       %full_path%::     the name of the file\n#\n#   %par_url%::\n#       The (optional) URL of the RDoc page documenting this class's\n#       parent class\n#\n#   %parent%::\n#       The name of this class's parent.\n#\n#   For both files and classes, the body is passed the following information\n#   on includes and methods:\n#\n#   %includes%::    \n#       Optional list of included modules. For each, it receives\n#       %aref%:: optional URL to RDoc page for the module\n#       %name%:: the name of the module\n#\n#   %method_list%::\n#       Optional list of methods of a particular class and category.\n#\n#   Each method list entry contains:\n#\n#   %type%::        public/private/protected\n#   %category%::    instance/class\n#   %methods%::     a list of method descriptions\n#\n#   Each method description contains:\n#\n#   %aref%::        a target aref, used when referencing this method\n#                   description. You should code this as <a name=\"%aref%\">\n#   %codeurl%::     the optional URL to the page containing this method's\n#                   source code.\n#   %name%::        the method's name\n#   %params%::      the method's parameters\n#   %callseq%::     a full calling sequence\n#   %m_desc%::      the (potentially multi-paragraph) description of\n#                   this method.\n#\n# [*CLASS_PAGE*]\n#         Header for pages documenting classes and modules. See\n#         BODY above for the available parameters.\n#\n# [*FILE_PAGE*]\n#         Header for pages documenting files. See\n#         BODY above for the available parameters.\n#\n# [*METHOD_LIST*]\n#         Controls the display of the listing of methods. See BODY for\n#         parameters.\n#\n# [*INDEX*]\n#         The top-level index page. For a browser-like environment\n#         define a frame set that includes the file, class, and \n#         method indices. Passed\n#         %title%:: title of page\n#         %initial_page% :: url of initial page to display\n#\n# [*CLASS_INDEX*]\n#         Individual files for the three indexes. Passed:\n#         %index_url%:: URL of main index page\n#         %entries%::   List of\n#                       %name%:: name of an index entry\n#                       %href%:: url of corresponding page\n# [*METHOD_INDEX*]\n#         Same as CLASS_INDEX for methods\n#\n# [*FILE_INDEX*]\n#         Same as CLASS_INDEX for methods\n#\n# [*FR_INDEX_BODY*]\n#         A wrapper around CLASS_INDEX, METHOD_INDEX, and FILE_INDEX.\n#         If those index strings contain the complete HTML for the\n#         output, then FR_INDEX_BODY can simply be !INCLUDE!\n#\n# [*SRC_PAGE*]\n#         Page used to display source code. Passed %title% and %code%,\n#         the latter being a multi-line string of code.\n\nmodule Page\n\nFONTS = \"Verdana, Arial, Helvetica, sans-serif\"\n\nSTYLE = %{\nbody,td,p { font-family: %fonts%; \n       color: #000040;\n}\n\n.attr-rw { font-size: x-small; color: #444488 }\n\n.title-row { background: #0000aa;\n             color:      #eeeeff;\n}\n\n.big-title-font { color: white;\n                  font-family: %fonts%;\n                  font-size: large; \n                  height: 50px}\n\n.small-title-font { color: aqua;\n                    font-family: %fonts%;\n                    font-size: xx-small; }\n\n.aqua { color: aqua }\n\n.method-name, attr-name {\n      font-family: monospace; font-weight: bold;\n}\n\n.tablesubtitle, .tablesubsubtitle {\n   width: 100%;\n   margin-top: 1ex;\n   margin-bottom: .5ex;\n   padding: 5px 0px 5px 20px;\n   font-size: large;\n   color: aqua;\n   background: #3333cc;\n}\n\n.name-list {\n  font-family: monospace;\n  margin-left: 40px;\n  margin-bottom: 2ex;\n  line-height: 140%;\n}\n\n.description {\n  margin-left: 40px;\n  margin-top: -2ex;\n  margin-bottom: 2ex;\n}\n\n.description p {\n  line-height: 140%;\n}\n\n.aka {\n  margin-left: 40px;\n  margin-bottom: 2ex;\n  line-height: 100%;\n  font-size:   small;\n  color:       #808080;\n}\n\n.methodtitle {\n  font-size: medium;\n  text-decoration: none;\n  color: #0000AA;\n  background: white; \n}\n\n.paramsig {\n   font-size: small;\n}\n\n.srcbut { float: right }\n\npre { font-size: 1.2em; }\ntt  { font-size: 1.2em; }\n\npre.source {\n  border-style: groove;\n  background-color: #ddddff;\n  margin-left:  40px;\n  padding: 1em 0em 1em 2em;\n}\n\n.classlist {\n  margin-left: 40px;\n  margin-bottom: 2ex;\n  line-height: 140%;\n}\n\nli {\n  display:    list-item;\n  margin-top: .6em;\n}\n\n.ruby-comment    { color: green; font-style: italic }\n.ruby-constant   { color: #4433aa; font-weight: bold; }\n.ruby-identifier { color: #222222;  }\n.ruby-ivar       { color: #2233dd; }\n.ruby-keyword    { color: #3333FF; font-weight: bold }\n.ruby-node       { color: #777777; }\n.ruby-operator   { color: #111111;  }\n.ruby-regexp     { color: #662222; }\n.ruby-value      { color: #662222; font-style: italic }\n\n}\n\n\n############################################################################\n\n\nHEADER = %{\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\" />\n  <link rel=StyleSheet href=\"%style_url%\" type=\"text/css\" media=\"screen\" />\n  <script type=\"text/javascript\" language=\"JavaScript\">\n  <!--\n  function popCode(url) {\n    window.open(url, \"Code\", \n          \"resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400\")\n  }\n  //-->\n  </script>\n</head>\n}\n\n\n###################################################################\n\nMETHOD_LIST = %{\nIF:includes\n<table summary=\"Included modules\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Included modules</td></tr>\n</table>\n<div class=\"name-list\">\nSTART:includes\n    <span class=\"method-name\">HREF:aref:name:</span>\nEND:includes\n</div>\nENDIF:includes\n\nIF:method_list\nSTART:method_list\nIF:methods\n<table summary=\"Method list\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">%type% %category% methods</td></tr>\n</table>\nSTART:methods\n<table summary=\"method\"  width=\"100%\" cellspacing=\"0\" cellpadding=\"5\" border=\"0\">\n<tr><td class=\"methodtitle\">\n<a name=\"%aref%\"></a>\nIF:codeurl\n<a href=\"%codeurl%\" target=\"Code\" class=\"methodtitle\"\n onClick=\"popCode('%codeurl%');return false;\">\nENDIF:codeurl\nIF:callseq\n<b>%callseq%</b>\nENDIF:callseq\nIFNOT:callseq\n<b>%name%</b>%params%\nENDIF:callseq\nIF:codeurl\n</a>\nENDIF:codeurl\n</td></tr>\n</table>\nIF:m_desc\n<div class=\"description\">\n%m_desc%\n</div>\nENDIF:m_desc\nIF:aka\n<div class=\"aka\">\nThis method is also aliased as\nSTART:aka\n<a href=\"%aref%\">%name%</a>\nEND:aka\n</div>\nENDIF:aka\nIF:sourcecode\n<pre class=\"source\">\n%sourcecode%\n</pre>\nENDIF:sourcecode\nEND:methods\nENDIF:methods\nEND:method_list\nENDIF:method_list\n}\n\n###################################################################\n\nCONTEXT_CONTENT = %{\nIF:diagram\n<table summary=\"Diagram of classes and modules\" width=\"100%\">\n<tr><td align=\"center\">\n%diagram%\n</td></tr></table>\nENDIF:diagram\n\n\nIF:description\n<div class=\"description\">%description%</div>\nENDIF:description\n\nIF:requires\n<table summary=\"Requires\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Required files</td></tr>\n</table>\n<div class=\"name-list\">\nSTART:requires\nHREF:aref:name:&nbsp; &nbsp;\nEND:requires\n</div>\nENDIF:requires\n\nIF:methods\n<table summary=\"Methods\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Methods</td></tr>\n</table>\n<div class=\"name-list\">\nSTART:methods\nHREF:aref:name:&nbsp; &nbsp;\nEND:methods\n</div>\nENDIF:methods\n\nIF:constants\n<table summary=\"Constants\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Constants</td></tr>\n</table>\n<table cellpadding=\"5\">\nSTART:constants\n<tr valign=\"top\"><td>%name%</td><td>=</td><td>%value%</td></tr>\nIF:desc\n<tr><td></td><td></td><td>%desc%</td></tr>\nENDIF:desc\nEND:constants\n</table>\nENDIF:constants\n\nIF:aliases\n<table summary=\"Aliases\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">External Aliases</td></tr>\n</table>\n<div class=\"name-list\">\nSTART:aliases\n%old_name% -> %new_name%<br />\nEND:aliases\n</div>\nENDIF:aliases\n\nIF:attributes\n<table summary=\"Attributes\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Attributes</td></tr>\n</table>\n<table summary=\"Attribute details\" cellspacing=\"5\">\nSTART:attributes\n     <tr valign=\"top\">\n       <td class=\"attr-name\">%name%</td>\nIF:rw\n       <td align=\"center\" class=\"attr-rw\">&nbsp;[%rw%]&nbsp;</td>\nENDIF:rw\nIFNOT:rw\n       <td></td>\nENDIF:rw\n       <td>%a_desc%</td>\n     </tr>\nEND:attributes\n</table>\nENDIF:attributes\n\nIF:classlist\n<table summary=\"List of classes\" cellpadding=\"5\" width=\"100%\">\n<tr><td class=\"tablesubtitle\">Classes and Modules</td></tr>\n</table>\n<div class=\"classlist\">\n%classlist%\n</div>\nENDIF:classlist\n}\n\n###############################################################################\n\nBODY = HEADER + %{\n<body bgcolor=\"white\">\n!INCLUDE!  <!-- banner header -->\n} +\nCONTEXT_CONTENT + METHOD_LIST +\n%{\n</body>\n</html>\n}\n\n\n###############################################################################\n\nFILE_PAGE = <<_FILE_PAGE_\n<table summary=\"Information on file\" width=\"100%\">\n <tr class=\"title-row\">\n <td><table summary=\"layout\" width=\"100%\"><tr>\n   <td class=\"big-title-font\" colspan=\"2\">%short_name%</td>\n   <td align=\"right\"><table summary=\"layout\" cellspacing=\"0\" cellpadding=\"2\">\n         <tr>\n           <td  class=\"small-title-font\">Path:</td>\n           <td class=\"small-title-font\">%full_path%\nIF:cvsurl\n\t\t\t\t&nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\n           </td>\n         </tr>\n         <tr>\n           <td class=\"small-title-font\">Modified:</td>\n           <td class=\"small-title-font\">%dtm_modified%</td>\n         </tr>\n        </table>\n    </td></tr></table></td>\n  </tr>\n</table>\n_FILE_PAGE_\n\n###################################################################\n\nCLASS_PAGE = %{\n<table summary=\"Information on class\" width=\"100%\" border=\"0\" cellspacing=\"0\">\n <tr class=\"title-row\">\n <td class=\"big-title-font\">\n   <sup><font color=\"aqua\">%classmod%</font></sup> %full_name%\n </td>\n <td align=\"right\">\n   <table summary=\"layout\" cellspacing=\"0\" cellpadding=\"2\">\n     <tr valign=\"top\">\n      <td class=\"small-title-font\">In:</td>\n      <td class=\"small-title-font\">\nSTART:infiles\nIF:full_path_url\n        <a href=\"%full_path_url%\" class=\"aqua\">\nENDIF:full_path_url\n%full_path%\nIF:full_path_url\n         </a>\nENDIF:full_path_url\nIF:cvsurl\n         &nbsp;(<a href=\"%cvsurl%\"><acronym title=\"Concurrent Versioning System\">CVS</acronym></a>)\nENDIF:cvsurl\n<br />\nEND:infiles\n      </td>\n     </tr>\nIF:parent\n     <tr>\n      <td class=\"small-title-font\">Parent:</td>\n      <td class=\"small-title-font\">\nIF:par_url\n        <a href=\"%par_url%\" class=\"aqua\">\nENDIF:par_url\n%parent%\nIF:par_url\n         </a>\nENDIF:par_url\n      </td>\n     </tr>\nENDIF:parent\n   </table>\n  </td>\n  </tr>\n</table>\n}\n\n=begin\n=end\n\n########################## Source code ##########################\n\nSRC_PAGE = %{\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<title>%title%</title>\n<link rel=\"stylesheet\" href=\"%style_url%\" type=\"text/css\" media=\"screen\" />\n</head>\n<body bgcolor=\"white\">\n<pre>%code%</pre>\n</body>\n</html>\n}\n\n########################## Index ################################\n\nFR_INDEX_BODY = %{\n!INCLUDE!\n}\n\nFILE_INDEX = %{\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<title>%list_title%</title>\n<style type=\"text/css\">\n<!--\n  body {\nbackground-color: #ddddff;\n     font-family: #{FONTS}; \n       font-size: 11px; \n      font-style: normal;\n     line-height: 14px; \n           color: #000040;\n  }\ndiv.banner {\n  background: #0000aa;\n  color:      white;\n  padding: 1;\n  margin: 0;\n  font-size: 90%;\n  font-weight: bold;\n  line-height: 1.1;\n  text-align: center;\n  width: 100%;\n}\n\nA.xx { color: white; font-weight: bold; }\n-->\n</style>\n<base target=\"docwin\">\n</head>\n<body>\n<div class=\"banner\"><a href=\"%index_url%\" class=\"xx\">%list_title%</a></div>\nSTART:entries\n<a href=\"%href%\">%name%</a><br />\nEND:entries\n</body></html>\n}\n\nCLASS_INDEX = FILE_INDEX\nMETHOD_INDEX = FILE_INDEX\n\nINDEX = %{\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\">\n<title>%title%</title></head>\n\n<frameset rows=\"20%, 80%\">\n    <frameset cols=\"25%,35%,45%\">\n        <frame src=\"fr_file_index.html\"   title=\"Files\" name=\"Files\">\n        <frame src=\"fr_class_index.html\"  name=\"Classes\">\n        <frame src=\"fr_method_index.html\" name=\"Methods\">\n    </frameset>\n    <frame  src=\"%initial_page%\" name=\"docwin\">\n    <noframes>\n          <body bgcolor=\"white\">\n            Sorry, RDoc currently only generates HTML using frames.\n          </body>\n    </noframes>\n</frameset>\n\n</html>\n}\n\n######################################################################\n#\n# The following is used for the -1 option\n#\n\nCONTENTS_XML = %{\nIF:description\n%description%\nENDIF:description\n\nIF:requires\n<h4>Requires:</h4>\n<ul>\nSTART:requires\nIF:aref\n<li><a href=\"%aref%\">%name%</a></li>\nENDIF:aref\nIFNOT:aref\n<li>%name%</li>\nENDIF:aref \nEND:requires\n</ul>\nENDIF:requires\n\nIF:attributes\n<h4>Attributes</h4>\n<table>\nSTART:attributes\n<tr><td>%name%</td><td>%rw%</td><td>%a_desc%</td></tr>\nEND:attributes\n</table>\nENDIF:attributes\n\nIF:includes\n<h4>Includes</h4>\n<ul>\nSTART:includes\nIF:aref\n<li><a href=\"%aref%\">%name%</a></li>\nENDIF:aref\nIFNOT:aref\n<li>%name%</li>\nENDIF:aref \nEND:includes\n</ul>\nENDIF:includes\n\nIF:method_list\n<h3>Methods</h3>\nSTART:method_list\nIF:methods\nSTART:methods\n<h4>%type% %category% method: <a name=\"%aref%\">%name%%params%</a></h4>\n\nIF:m_desc\n%m_desc%\nENDIF:m_desc\n\nIF:sourcecode\n<blockquote><pre>\n%sourcecode%\n</pre></blockquote>\nENDIF:sourcecode\nEND:methods\nENDIF:methods\nEND:method_list\nENDIF:method_list\n}\n\n\nend\nend\n\nrequire 'rdoc/generators/template/html/one_page_html'\n"
  },
  {
    "path": "lib/rdoc/generators/template/html/one_page_html.rb",
    "content": "module RDoc\nmodule Page\n######################################################################\n#\n# The following is used for the -1 option\n#\n\nCONTENTS_XML = %{\nIF:description\n%description%\nENDIF:description\n\nIF:requires\n<h4>Requires:</h4>\n<ul>\nSTART:requires\nIF:aref\n<li><a href=\"%aref%\">%name%</a></li>\nENDIF:aref\nIFNOT:aref\n<li>%name%</li>\nENDIF:aref \nEND:requires\n</ul>\nENDIF:requires\n\nIF:attributes\n<h4>Attributes</h4>\n<table>\nSTART:attributes\n<tr><td>%name%</td><td>%rw%</td><td>%a_desc%</td></tr>\nEND:attributes\n</table>\nENDIF:attributes\n\nIF:includes\n<h4>Includes</h4>\n<ul>\nSTART:includes\nIF:aref\n<li><a href=\"%aref%\">%name%</a></li>\nENDIF:aref\nIFNOT:aref\n<li>%name%</li>\nENDIF:aref \nEND:includes\n</ul>\nENDIF:includes\n\nIF:method_list\n<h3>Methods</h3>\nSTART:method_list\nIF:methods\nSTART:methods\n<h4>%type% %category% method: \nIF:callseq\n<a name=\"%aref%\">%callseq%</a>\nENDIF:callseq\nIFNOT:callseq\n<a name=\"%aref%\">%name%%params%</a></h4>\nENDIF:callseq\n\nIF:m_desc\n%m_desc%\nENDIF:m_desc\n\nIF:sourcecode\n<blockquote><pre>\n%sourcecode%\n</pre></blockquote>\nENDIF:sourcecode\nEND:methods\nENDIF:methods\nEND:method_list\nENDIF:method_list\n}\n\n########################################################################\n\nONE_PAGE = %{\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html>\n<head>\n  <title>%title%</title>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%charset%\" />\n</head>\n<body>\nSTART:files\n<h2>File: %short_name%</h2>\n<table>\n  <tr><td>Path:</td><td>%full_path%</td></tr>\n  <tr><td>Modified:</td><td>%dtm_modified%</td></tr>\n</table>\n} + CONTENTS_XML + %{\nEND:files\n\nIF:classes\n<h2>Classes</h2>\nSTART:classes\nIF:parent\n<h3>%classmod% %full_name% &lt; HREF:par_url:parent:</h3>\nENDIF:parent\nIFNOT:parent\n<h3>%classmod% %full_name%</h3>\nENDIF:parent\n\nIF:infiles\n(in files\nSTART:infiles\nHREF:full_path_url:full_path:\nEND:infiles\n)\nENDIF:infiles\n} + CONTENTS_XML + %{\nEND:classes\nENDIF:classes\n</body>\n</html>\n}\n\nend\nend\n"
  },
  {
    "path": "lib/rdoc/generators/template/xml/rdf.rb",
    "content": "module RDoc\nmodule Page\n\n\n\nCONTENTS_RDF = %{\nIF:description\n    <description rd:parseType=\"Literal\">\n%description%\n    </description>\nENDIF:description\n\nIF:requires\nSTART:requires\n         <rd:required-file rd:name=\"%name%\" />\nEND:requires\nENDIF:requires\n\nIF:attributes\nSTART:attributes\n        <contents>\n        <Attribute rd:name=\"%name%\">\nIF:rw\n          <attribute-rw>%rw%</attribute-rw>\nENDIF:rw\n          <description rdf:parseType=\"Literal\">%a_desc%</description>\n        </Attribute>\n        </contents>\nEND:attributes\nENDIF:attributes\n\nIF:includes\n      <IncludedModuleList>\nSTART:includes\n        <included-module rd:name=\"%name%\"  />\nEND:includes\n      </IncludedModuleList>\nENDIF:includes\n\nIF:method_list\nSTART:method_list\nIF:methods\nSTART:methods\n\t<contents>\n        <Method rd:name=\"%name%\" rd:visibility=\"%type%\"\n                rd:category=\"%category%\" rd:id=\"%aref%\">\n          <parameters>%params%</parameters>\nIF:m_desc\n          <description rdf:parseType=\"Literal\">\n%m_desc%\n          </description>\nENDIF:m_desc\nIF:sourcecode\n          <source-code-listing rdf:parseType=\"Literal\">\n%sourcecode%\n          </source-code-listing>\nENDIF:sourcecode\n        </Method>\n       </contents>\nEND:methods\nENDIF:methods\nEND:method_list\nENDIF:method_list\n     <!-- end method list -->\n}\n\n########################################################################\n\nONE_PAGE = %{<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n        xmlns=\"http://pragprog.com/rdoc/rdoc.rdf#\"\n        xmlns:rd=\"http://pragprog.com/rdoc/rdoc.rdf#\">\n\n<!-- RDoc -->\nSTART:files\n  <rd:File rd:name=\"%short_name%\" rd:id=\"%href%\">\n      <path>%full_path%</path>\n      <dtm-modified>%dtm_modified%</dtm-modified>\n} + CONTENTS_RDF + %{\n  </rd:File>\nEND:files\nSTART:classes\n  <%classmod% rd:name=\"%full_name%\" rd:id=\"%full_name%\">\n    <classmod-info>\nIF:infiles\n      <InFiles>\nSTART:infiles\n        <infile>\n          <File rd:name=\"%full_path%\"\nIF:full_path_url\n                rdf:about=\"%full_path_url%\"\nENDIF:full_path_url\n           />\n         </infile>\nEND:infiles\n      </InFiles>\nENDIF:infiles\nIF:parent\n     <superclass>HREF:par_url:parent:</superclass>\nENDIF:parent\n    </classmod-info>\n} + CONTENTS_RDF + %{\n  </%classmod%>\nEND:classes\n<!-- /RDoc -->\n</rdf:RDF>\n}\n\n\nend\nend\n\n"
  },
  {
    "path": "lib/rdoc/generators/template/xml/xml.rb",
    "content": "module RDoc\nmodule Page\n\n\n\nCONTENTS_XML = %{\nIF:description\n    <description>\n%description%\n    </description>\nENDIF:description\n    <contents>\nIF:requires\n      <required-file-list>\nSTART:requires\n         <required-file name=\"%name%\"\nIF:aref \n                        href=\"%aref%\"\nENDIF:aref\n         />\nEND:requires\n      </required-file-list>\nENDIF:requires\nIF:attributes\n      <attribute-list>\nSTART:attributes\n        <attribute name=\"%name%\">\nIF:rw\n          <attribute-rw>%rw%</attribute-rw>\nENDIF:rw\n          <description>%a_desc%</description>\n        </attribute>\nEND:attributes\n      </attribute-list>\nENDIF:attributes\nIF:includes\n      <included-module-list>\nSTART:includes\n        <included-module name=\"%name%\"\nIF:aref\n                         href=\"%aref%\"\nENDIF:aref\n        />\nEND:includes\n      </included-module-list>\nENDIF:includes\nIF:method_list\n      <method-list>\nSTART:method_list\nIF:methods\nSTART:methods\n        <method name=\"%name%\" type=\"%type%\" category=\"%category%\" id=\"%aref%\">\n          <parameters>%params%</parameters>\nIF:m_desc\n          <description>\n%m_desc%\n          </description>\nENDIF:m_desc\nIF:sourcecode\n          <source-code-listing>\n%sourcecode%\n          </source-code-listing>\nENDIF:sourcecode\n        </method>\nEND:methods\nENDIF:methods\nEND:method_list\n      </method-list>\nENDIF:method_list\n     </contents>\n}\n\n########################################################################\n\nONE_PAGE = %{<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rdoc>\n<file-list>\nSTART:files\n  <file name=\"%short_name%\" id=\"%href%\">\n    <file-info>\n      <path>%full_path%</path>\n      <dtm-modified>%dtm_modified%</dtm-modified>\n    </file-info>\n} + CONTENTS_XML + %{\n  </file>\nEND:files\n</file-list>\n<class-module-list>\nSTART:classes\n  <%classmod% name=\"%full_name%\" id=\"%full_name%\">\n    <classmod-info>\nIF:infiles\n      <infiles>      \nSTART:infiles\n        <infile>HREF:full_path_url:full_path:</infile>\nEND:infiles\n      </infiles>\nENDIF:infiles\nIF:parent\n     <superclass>HREF:par_url:parent:</superclass>\nENDIF:parent\n    </classmod-info>\n} + CONTENTS_XML + %{\n  </%classmod%>\nEND:classes\n</class-module-list>\n</rdoc>\n}\n\n\nend\nend\n"
  },
  {
    "path": "lib/rdoc/generators/xml_generator.rb",
    "content": "\nrequire 'ftools'\n\nrequire 'rdoc/options'\nrequire 'rdoc/markup/simple_markup'\nrequire 'rdoc/markup/simple_markup/to_html'\nrequire 'rdoc/generators/html_generator'\n\nmodule Generators\n\n  # Generate XML output as one big file\n\n  class XMLGenerator < HTMLGenerator\n\n    # Standard generator factory\n    def XMLGenerator.for(options)\n      XMLGenerator.new(options)\n    end\n\n    \n    def initialize(*args)\n      super\n    end\n\n    ##\n    # Build the initial indices and output objects\n    # based on an array of TopLevel objects containing\n    # the extracted information. \n\n    def generate(info)\n      @info       = info\n      @files      = []\n      @classes    = []\n      @hyperlinks = {}\n\n      build_indices\n      generate_xml\n    end\n\n\n    ##\n    # Generate:\n    #\n    # * a list of HtmlFile objects for each TopLevel object.\n    # * a list of HtmlClass objects for each first level\n    #   class or module in the TopLevel objects\n    # * a complete list of all hyperlinkable terms (file,\n    #   class, module, and method names)\n\n    def build_indices\n\n      @info.each do |toplevel|\n        @files << HtmlFile.new(toplevel, @options, FILE_DIR)\n      end\n\n      RDoc::TopLevel.all_classes_and_modules.each do |cls|\n        build_class_list(cls, @files[0], CLASS_DIR)\n      end\n    end\n\n    def build_class_list(from, html_file, class_dir)\n      @classes << HtmlClass.new(from, html_file, class_dir, @options)\n      from.each_classmodule do |mod|\n        build_class_list(mod, html_file, class_dir)\n      end\n    end\n\n    ##\n    # Generate all the HTML. For the one-file case, we generate\n    # all the information in to one big hash\n    #\n    def generate_xml\n      values = { \n        'charset' => @options.charset,\n        'files'   => gen_into(@files),\n        'classes' => gen_into(@classes)\n      }\n      \n      # this method is defined in the template file\n      write_extra_pages if defined? write_extra_pages\n\n      template = TemplatePage.new(RDoc::Page::ONE_PAGE)\n\n      if @options.op_name\n        opfile = File.open(@options.op_name, \"w\")\n      else\n        opfile = $stdout\n      end\n      template.write_html_on(opfile, values)\n    end\n\n    def gen_into(list)\n      res = []\n      list.each do |item|\n        res << item.value_hash\n      end\n      res\n    end\n\n    def gen_file_index\n      gen_an_index(@files, 'Files')\n    end\n\n    def gen_class_index\n      gen_an_index(@classes, 'Classes')\n    end\n\n    def gen_method_index\n      gen_an_index(HtmlMethod.all_methods, 'Methods')\n    end\n\n    \n    def gen_an_index(collection, title)\n      res = []\n      collection.sort.each do |f|\n        if f.document_self\n          res << { \"href\" => f.path, \"name\" => f.index_name }\n        end\n      end\n\n      return {\n        \"entries\" => res,\n        'list_title' => title,\n        'index_url'  => main_url,\n      }\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/markup/.document",
    "content": "simple_markup\nsimple_markup.rb\n"
  },
  {
    "path": "lib/rdoc/markup/sample/rdoc2latex.rb",
    "content": "#!/usr/local/bin/ruby\n# Illustration of a script to convert an RDoc-style file to a LaTeX\n# document\n\nrequire 'rdoc/markup/simple_markup'\nrequire 'rdoc/markup/simple_markup/to_latex'\n\np = SM::SimpleMarkup.new\nh = SM::ToLaTeX.new\n\n#puts \"\\\\documentclass{report}\"\n#puts \"\\\\usepackage{tabularx}\"\n#puts \"\\\\usepackage{parskip}\"\n#puts \"\\\\begin{document}\"\nputs p.convert(ARGF.read, h)\n#puts \"\\\\end{document}\"\n"
  },
  {
    "path": "lib/rdoc/markup/sample/sample.rb",
    "content": "# This program illustrates the basic use of the SimpleMarkup\n# class. It extracts the first comment block from the \n# simple_markup.rb file and converts it into HTML on\n# standard output. Run it using\n#\n#  % ruby sample.rb\n#\n# You should be in the sample/ directory when you do this,\n# as it hardwires the path to the files it needs to require.\n# This isn't necessary in the code you write once you've \n# installed the package.\n#\n# For a better way of formatting code comment blocks (and more)\n# see the rdoc package.\n#\n\n$:.unshift \"../../..\"\n\nrequire 'rdoc/markup/simple_markup'\nrequire 'rdoc/markup/simple_markup/to_html'\n\n# Extract the comment block from the source file\n\ninput_string = \"\"\n\nFile.foreach(\"../simple_markup.rb\") do |line|\n  break unless line.gsub!(/^\\# ?/, '')\n  input_string << line\nend\n\n# Create a markup object\nmarkup = SM::SimpleMarkup.new\n\n# Attach it to an HTML formatter\nh = SM::ToHtml.new\n\n# And convert out comment block to html. Wrap it a body\n# tag pair to let browsers view it\n\nputs \"<html><body>\"\nputs markup.convert(input_string, h)\nputs \"</body></html>\"\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/fragments.rb",
    "content": "require 'rdoc/markup/simple_markup/lines.rb'\n#require 'rdoc/markup/simple_markup/to_flow.rb'\n\nmodule SM\n\n  ##\n  # A Fragment is a chunk of text, subclassed as a paragraph, a list\n  # entry, or verbatim text\n\n  class Fragment\n    attr_reader   :level, :param, :txt\n    attr_accessor :type\n\n    def initialize(level, param, type, txt)\n      @level = level\n      @param = param\n      @type  = type\n      @txt   = \"\"\n      add_text(txt) if txt\n    end\n\n    def add_text(txt)\n      @txt << \" \" if @txt.length > 0\n      @txt << txt.tr_s(\"\\n \", \"  \").strip\n    end\n\n    def to_s\n      \"L#@level: #{self.class.name.split('::')[-1]}\\n#@txt\"\n    end\n\n    ######\n    # This is a simple factory system that lets us associate fragement\n    # types (a string) with a subclass of fragment\n\n    TYPE_MAP = {}\n\n    def Fragment.type_name(name)\n      TYPE_MAP[name] = self\n    end\n\n    def Fragment.for(line)\n      klass =  TYPE_MAP[line.type] ||\n        raise(\"Unknown line type: '#{line.type.inspect}:' '#{line.text}'\")\n      return klass.new(line.level, line.param, line.flag, line.text)\n    end\n  end\n\n  ##\n  # A paragraph is a fragment which gets wrapped to fit. We remove all\n  # newlines when we're created, and have them put back on output\n\n  class Paragraph < Fragment\n    type_name Line::PARAGRAPH\n  end\n\n  class BlankLine < Paragraph\n    type_name Line::BLANK\n  end\n\n  class Heading < Paragraph\n    type_name Line::HEADING\n\n    def head_level\n      @param.to_i\n    end\n  end\n\n  ##\n  # A List is a fragment with some kind of label\n  #\n\n  class ListBase < Paragraph\n    # List types\n    BULLET  = :BULLET\n    NUMBER  = :NUMBER\n    UPPERALPHA  = :UPPERALPHA\n    LOWERALPHA  = :LOWERALPHA\n    LABELED = :LABELED\n    NOTE    = :NOTE\n  end\n\n  class ListItem < ListBase\n    type_name Line::LIST\n\n    #  def label\n    #    am = AttributeManager.new(@param)\n    #    am.flow\n    #  end\n  end\n\n  class ListStart < ListBase\n    def initialize(level, param, type)\n      super(level, param, type, nil)\n    end\n  end\n\n  class ListEnd < ListBase\n    def initialize(level, type)\n      super(level, \"\", type, nil)\n    end\n  end\n\n  ##\n  # Verbatim code contains lines that don't get wrapped.\n\n  class Verbatim < Fragment\n    type_name  Line::VERBATIM\n\n    def add_text(txt)\n      @txt << txt.chomp << \"\\n\"\n    end\n\n  end\n\n  ##\n  # A horizontal rule\n  class Rule < Fragment\n    type_name Line::RULE\n  end\n\n\n  # Collect groups of lines together. Each group\n  # will end up containing a flow of text\n\n  class LineCollection\n    \n    def initialize\n      @fragments = []\n    end\n\n    def add(fragment)\n      @fragments << fragment\n    end\n\n    def each(&b)\n      @fragments.each(&b)\n    end\n\n    # For testing\n    def to_a\n      @fragments.map {|fragment| fragment.to_s}\n    end\n\n    # Factory for different fragment types\n    def fragment_for(*args)\n      Fragment.for(*args)\n    end\n\n    # tidy up at the end\n    def normalize\n      change_verbatim_blank_lines\n      add_list_start_and_ends\n      add_list_breaks\n      tidy_blank_lines\n    end\n\n    def to_s\n      @fragments.join(\"\\n----\\n\")\n    end\n\n    def accept(am, visitor)\n\n      visitor.start_accepting\n\n      @fragments.each do |fragment|\n        case fragment\n        when Verbatim\n          visitor.accept_verbatim(am, fragment)\n        when Rule\n          visitor.accept_rule(am, fragment)\n        when ListStart\n          visitor.accept_list_start(am, fragment)\n        when ListEnd\n          visitor.accept_list_end(am, fragment)\n        when ListItem\n          visitor.accept_list_item(am, fragment)\n        when BlankLine\n          visitor.accept_blank_line(am, fragment)\n        when Heading\n          visitor.accept_heading(am, fragment)\n        when Paragraph\n          visitor.accept_paragraph(am, fragment)\n        end\n      end\n\n      visitor.end_accepting\n    end\n    #######\n    private\n    #######\n\n    # If you have:\n    #\n    #    normal paragraph text.\n    #\n    #       this is code\n    #   \n    #       and more code\n    #\n    # You'll end up with the fragments Paragraph, BlankLine, \n    # Verbatim, BlankLine, Verbatim, BlankLine, etc\n    #\n    # The BlankLine in the middle of the verbatim chunk needs to\n    # be changed to a real verbatim newline, and the two\n    # verbatim blocks merged\n    #\n    #    \n    def change_verbatim_blank_lines\n      frag_block = nil\n      blank_count = 0\n      @fragments.each_with_index do |frag, i|\n        if frag_block.nil?\n          frag_block = frag if Verbatim === frag\n        else\n          case frag\n          when Verbatim\n            blank_count.times { frag_block.add_text(\"\\n\") }\n            blank_count = 0\n            frag_block.add_text(frag.txt)\n            @fragments[i] = nil    # remove out current fragment\n          when BlankLine\n            if frag_block\n              blank_count += 1\n              @fragments[i] = nil\n            end\n          else\n            frag_block = nil\n            blank_count = 0\n          end\n        end\n      end\n      @fragments.compact!\n    end\n\n    # List nesting is implicit given the level of\n    # Make it explicit, just to make life a tad\n    # easier for the output processors\n\n    def add_list_start_and_ends\n      level = 0\n      res = []\n      type_stack = []\n\n      @fragments.each do |fragment|\n        # $stderr.puts \"#{level} : #{fragment.class.name} : #{fragment.level}\"\n        new_level = fragment.level\n        while (level < new_level)\n          level += 1\n          type = fragment.type\n          res << ListStart.new(level, fragment.param, type) if type\n          type_stack.push type\n          # $stderr.puts \"Start: #{level}\"\n        end\n\n        while level > new_level\n          type = type_stack.pop\n          res << ListEnd.new(level, type) if type\n          level -= 1\n          # $stderr.puts \"End: #{level}, #{type}\"\n        end\n\n        res << fragment\n        level = fragment.level\n      end\n      level.downto(1) do |i|\n        type = type_stack.pop\n        res << ListEnd.new(i, type) if type\n      end\n\n      @fragments = res\n    end\n\n    # now insert start/ends between list entries at the\n    # same level that have different element types\n\n    def add_list_breaks\n      res = @fragments\n\n      @fragments = []\n      list_stack = []\n\n      res.each do |fragment|\n        case fragment\n        when ListStart\n          list_stack.push fragment\n        when ListEnd\n          start = list_stack.pop\n          fragment.type = start.type\n        when ListItem\n          l = list_stack.last\n          if fragment.type != l.type\n            @fragments << ListEnd.new(l.level, l.type)\n            start = ListStart.new(l.level, fragment.param, fragment.type)\n            @fragments << start\n            list_stack.pop\n            list_stack.push start\n          end\n        else\n          ;\n        end\n        @fragments << fragment\n      end\n    end\n\n    # Finally tidy up the blank lines:\n    # * change Blank/ListEnd into ListEnd/Blank\n    # * remove blank lines at the front\n\n    def tidy_blank_lines\n      (@fragments.size - 1).times do |i|\n        if @fragments[i].kind_of?(BlankLine) and \n            @fragments[i+1].kind_of?(ListEnd)\n          @fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i] \n        end\n      end\n\n      # remove leading blanks\n      @fragments.each_with_index do |f, i|\n        break unless f.kind_of? BlankLine\n        @fragments[i] = nil\n      end\n\n      @fragments.compact!\n    end\n\n  end\n  \nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/inline.rb",
    "content": "module SM\n\n  # We manage a set of attributes. Each attribute has a symbol name\n  # and a bit value\n\n  class Attribute\n    SPECIAL = 1\n\n    @@name_to_bitmap = { :_SPECIAL_ => SPECIAL }\n    @@next_bitmap = 2\n\n    def Attribute.bitmap_for(name)\n      bitmap = @@name_to_bitmap[name]\n      if !bitmap\n        bitmap = @@next_bitmap\n        @@next_bitmap <<= 1\n        @@name_to_bitmap[name] = bitmap\n      end\n      bitmap\n    end\n\n    def Attribute.as_string(bitmap)\n      return \"none\" if bitmap.zero?\n      res = []\n      @@name_to_bitmap.each do |name, bit|\n        res << name if (bitmap & bit) != 0\n      end\n      res.join(\",\")\n    end\n\n    def Attribute.each_name_of(bitmap)\n      @@name_to_bitmap.each do |name, bit|\n        next if bit == SPECIAL\n        yield name.to_s if (bitmap & bit) != 0\n      end\n    end\n  end\n\n\n  # An AttrChanger records a change in attributes. It contains\n  # a bitmap of the attributes to turn on, and a bitmap of those to\n  # turn off\n\n  AttrChanger = Struct.new(:turn_on, :turn_off)\n  class AttrChanger\n    def to_s\n      \"Attr: +#{Attribute.as_string(@turn_on)}/-#{Attribute.as_string(@turn_on)}\"\n    end\n  end\n\n  # An array of attributes which parallels the characters in a string\n  class AttrSpan\n    def initialize(length)\n      @attrs = Array.new(length, 0)\n    end\n\n    def set_attrs(start, length, bits)\n      for i in start ... (start+length)\n        @attrs[i] |= bits\n      end\n    end\n\n    def [](n)\n      @attrs[n]\n    end\n  end\n\n  ##\n  # Hold details of a special sequence\n\n  class Special\n    attr_reader   :type\n    attr_accessor :text\n\n    def initialize(type, text)\n      @type, @text = type, text\n    end\n\n    def ==(o)\n      self.text == o.text && self.type == o.type\n    end\n\n    def to_s\n      \"Special: type=#{type}, text=#{text.dump}\"\n    end\n  end\n  \n  class AttributeManager\n\n    NULL = \"\\000\".freeze\n\n    ##\n    # We work by substituting non-printing characters in to the\n    # text. For now I'm assuming that I can substitute\n    # a character in the range 0..8 for a 7 bit character\n    # without damaging the encoded string, but this might\n    # be optimistic\n    #\n\n    A_PROTECT  = 004\n    PROTECT_ATTR  = A_PROTECT.chr\n\n    # This maps delimiters that occur around words (such as\n    # *bold* or +tt+) where the start and end delimiters\n    # and the same. This lets us optimize the regexp\n    MATCHING_WORD_PAIRS = {}\n\n    # And this is used when the delimiters aren't the same. In this\n    # case the hash maps a pattern to the attribute character\n    WORD_PAIR_MAP = {}\n\n    # This maps HTML tags to the corresponding attribute char\n    HTML_TAGS = {}\n\n    # And this maps _special_ sequences to a name. A special sequence\n    # is something like a WikiWord\n    SPECIAL = {}\n\n    # Return an attribute object with the given turn_on\n    # and turn_off bits set\n\n    def attribute(turn_on, turn_off)\n      AttrChanger.new(turn_on, turn_off)\n    end\n\n\n    def change_attribute(current, new)\n      diff = current ^ new\n      attribute(new & diff, current & diff)\n    end\n\n    def changed_attribute_by_name(current_set, new_set)\n      current = new = 0\n      current_set.each {|name| current |= Attribute.bitmap_for(name) }\n      new_set.each {|name| new |= Attribute.bitmap_for(name) }\n      change_attribute(current, new)\n    end\n\n    def copy_string(start_pos, end_pos)\n      res = @str[start_pos...end_pos]\n      res.gsub!(/\\000/, '')\n      res\n    end\n\n    # Map attributes like <b>text</b>to the sequence \\001\\002<char>\\001\\003<char>,\n    # where <char> is a per-attribute specific character\n\n    def convert_attrs(str, attrs)\n      # first do matching ones\n      tags = MATCHING_WORD_PAIRS.keys.join(\"\")\n      re = \"(^|\\\\W)([#{tags}])([A-Za-z_]+?)\\\\2(\\\\W|\\$)\"\n#      re = \"(^|\\\\W)([#{tags}])(\\\\S+?)\\\\2(\\\\W|\\$)\"\n      1 while str.gsub!(Regexp.new(re)) {\n        attr = MATCHING_WORD_PAIRS[$2];\n        attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr)\n        $1 + NULL*$2.length + $3 + NULL*$2.length + $4\n      }\n\n      # then non-matching\n      unless WORD_PAIR_MAP.empty?\n        WORD_PAIR_MAP.each do |regexp, attr|\n          str.gsub!(regexp) { \n            attrs.set_attrs($`.length + $1.length, $2.length, attr)\n            NULL*$1.length + $2 + NULL*$3.length\n          }\n        end\n      end\n    end\n\n    def convert_html(str, attrs)\n      tags = HTML_TAGS.keys.join(\"|\")\n      re = \"<(#{tags})>(.*?)</\\\\1>\"\n      1 while str.gsub!(Regexp.new(re, Regexp::IGNORECASE)) {\n        attr = HTML_TAGS[$1.downcase]\n        html_length = $1.length + 2\n        seq = NULL * html_length\n        attrs.set_attrs($`.length + html_length, $2.length, attr)\n        seq + $2 + seq + NULL\n      }\n    end\n\n    def convert_specials(str, attrs)\n      unless SPECIAL.empty?\n        SPECIAL.each do |regexp, attr|\n          str.scan(regexp) do\n            attrs.set_attrs($`.length, $&.length, attr | Attribute::SPECIAL)\n          end\n        end\n      end\n    end\n\n    # A \\ in front of a character that would normally be\n    # processed turns off processing. We do this by turning\n    # \\< into <#{PROTECT}\n    \n    PROTECTABLE = [ \"<\" << \"\\\\\" ]  #\"\n\n\n    def mask_protected_sequences\n      protect_pattern = Regexp.new(\"\\\\\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])\")\n      @str.gsub!(protect_pattern, \"\\\\1#{PROTECT_ATTR}\")\n    end\n\n    def unmask_protected_sequences\n      @str.gsub!(/(.)#{PROTECT_ATTR}/, \"\\\\1\\000\")\n    end\n\n    def initialize\n      add_word_pair(\"*\", \"*\", :BOLD)\n      add_word_pair(\"_\", \"_\", :EM)\n      add_word_pair(\"+\", \"+\", :TT)\n      \n      add_html(\"em\", :EM)\n      add_html(\"i\",  :EM)\n      add_html(\"b\",  :BOLD)\n      add_html(\"tt\",   :TT)\n      add_html(\"code\", :TT)\n\n      add_special(/<!--(.*?)-->/, :COMMENT)\n    end\n\n    def add_word_pair(start, stop, name)\n      raise \"Word flags may not start '<'\" if start[0] == ?<\n      bitmap = Attribute.bitmap_for(name)\n      if start == stop\n        MATCHING_WORD_PAIRS[start] = bitmap\n      else\n        pattern = Regexp.new(\"(\" + Regexp.escape(start) + \")\" +\n#                             \"([A-Za-z]+)\" +\n                             \"(\\\\S+)\" +\n                             \"(\" + Regexp.escape(stop) +\")\")\n        WORD_PAIR_MAP[pattern] = bitmap\n      end\n      PROTECTABLE << start[0,1]\n      PROTECTABLE.uniq!\n    end\n\n    def add_html(tag, name)\n      HTML_TAGS[tag.downcase] = Attribute.bitmap_for(name)\n    end\n\n    def add_special(pattern, name)\n      SPECIAL[pattern] = Attribute.bitmap_for(name)\n    end\n\n    def flow(str)\n      @str = str\n\n      puts(\"Before flow, str='#{@str.dump}'\") if $DEBUG\n      mask_protected_sequences\n \n      @attrs = AttrSpan.new(@str.length)\n\n      puts(\"After protecting, str='#{@str.dump}'\") if $DEBUG\n      convert_attrs(@str, @attrs)\n      convert_html(@str, @attrs)\n      convert_specials(str, @attrs)\n      unmask_protected_sequences\n      puts(\"After flow, str='#{@str.dump}'\") if $DEBUG\n      return split_into_flow\n    end\n\n    def display_attributes\n      puts\n      puts @str.tr(NULL, \"!\")\n      bit = 1\n      16.times do |bno|\n        line = \"\"\n        @str.length.times do |i|\n          if (@attrs[i] & bit) == 0\n            line << \" \"\n          else\n            if bno.zero?\n              line << \"S\"\n            else\n              line << (\"%d\" % (bno+1))\n            end\n          end\n        end\n        puts(line) unless line =~ /^ *$/\n        bit <<= 1\n      end\n    end\n\n    def split_into_flow\n\n      display_attributes if $DEBUG\n\n      res = []\n      current_attr = 0\n      str = \"\"\n\n      \n      str_len = @str.length\n\n      # skip leading invisible text\n      i = 0\n      i += 1 while i < str_len and @str[i].zero?\n      start_pos = i\n\n      # then scan the string, chunking it on attribute changes\n      while i < str_len\n        new_attr = @attrs[i]\n        if new_attr != current_attr\n          if i > start_pos\n            res << copy_string(start_pos, i)\n            start_pos = i\n          end\n\n          res << change_attribute(current_attr, new_attr)\n          current_attr = new_attr\n\n          if (current_attr & Attribute::SPECIAL) != 0\n            i += 1 while i < str_len and (@attrs[i] & Attribute::SPECIAL) != 0\n            res << Special.new(current_attr, copy_string(start_pos, i))\n            start_pos = i\n            next\n          end\n        end\n\n        # move on, skipping any invisible characters\n        begin\n          i += 1\n        end while i < str_len and @str[i].zero?\n      end\n      \n      # tidy up trailing text\n      if start_pos < str_len\n        res << copy_string(start_pos, str_len)\n      end\n\n      # and reset to all attributes off\n      res << change_attribute(current_attr, 0) if current_attr != 0\n\n      return res\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/lines.rb",
    "content": "##########################################################################\n#\n# We store the lines we're working on as objects of class Line.\n# These contain the text of the line, along with a flag indicating the\n# line type, and an indentation level\n\nmodule SM\n\n  class Line\n    INFINITY = 9999\n\n    BLANK     = :BLANK\n    HEADING   = :HEADING\n    LIST      = :LIST\n    RULE      = :RULE\n    PARAGRAPH = :PARAGRAPH\n    VERBATIM  = :VERBATIM\n    \n    # line type\n    attr_accessor :type\n\n    # The indentation nesting level\n    attr_accessor :level\n\n    # The contents\n    attr_accessor :text\n\n    # A prefix or parameter. For LIST lines, this is\n    # the text that introduced the list item (the label)\n    attr_accessor  :param\n\n    # A flag. For list lines, this is the type of the list\n    attr_accessor :flag\n\n    # the number of leading spaces\n    attr_accessor :leading_spaces\n\n    # true if this line has been deleted from the list of lines\n    attr_accessor :deleted\n    \n\n    def initialize(text)\n      @text    = text.dup\n      @deleted = false\n\n      # expand tabs\n      1 while @text.gsub!(/\\t+/) { ' ' * (8*$&.length - $`.length % 8)}  && $~ #`\n\n      # Strip trailing whitespace\n      @text.sub!(/\\s+$/, '')\n\n      # and look for leading whitespace\n      if @text.length > 0\n        @text =~ /^(\\s*)/\n        @leading_spaces = $1.length\n      else\n        @leading_spaces = INFINITY\n      end\n    end\n\n    # Return true if this line is blank\n    def isBlank?\n      @text.length.zero?\n    end\n\n    # stamp a line with a type, a level, a prefix, and a flag\n    def stamp(type, level, param=\"\", flag=nil)\n      @type, @level, @param, @flag = type, level, param, flag\n    end\n\n    ##\n    # Strip off the leading margin\n    #\n\n    def strip_leading(size)\n      if @text.size > size\n        @text[0,size] = \"\"\n      else\n        @text = \"\"\n      end\n    end\n\n    def to_s\n      \"#@type#@level: #@text\"\n    end\n  end\n\n  ###############################################################################\n  #\n  # A container for all the lines\n  #\n\n  class Lines\n    include Enumerable\n\n    attr_reader :lines   # for debugging\n\n    def initialize(lines)\n      @lines = lines\n      rewind\n    end\n\n    def empty?\n      @lines.size.zero?\n    end\n\n    def each\n      @lines.each do |line|\n        yield line unless line.deleted\n      end\n    end\n\n#    def [](index)\n#      @lines[index]\n#    end\n\n    def rewind\n      @nextline = 0\n    end\n\n    def next\n      begin\n        res = @lines[@nextline]\n        @nextline += 1 if @nextline < @lines.size\n      end while res and res.deleted and @nextline < @lines.size\n      res\n    end\n\n    def unget\n      @nextline -= 1\n    end\n\n    def delete(a_line)\n      a_line.deleted = true\n    end\n\n    def normalize\n      margin = @lines.collect{|l| l.leading_spaces}.min\n      margin = 0 if margin == Line::INFINITY\n      @lines.each {|line| line.strip_leading(margin) } if margin > 0\n    end\n\n    def as_text\n      @lines.map {|l| l.text}.join(\"\\n\")\n    end\n\n    def line_types\n      @lines.map {|l| l.type }\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/preprocess.rb",
    "content": "module SM\n\n  ## \n  # Handle common directives that can occur in a block of text:\n  #\n  # : include : filename\n  #\n\n  class PreProcess\n\n    def initialize(input_file_name, include_path)\n      @input_file_name = input_file_name\n      @include_path = include_path\n    end\n\n    # Look for common options in a chunk of text. Options that\n    # we don't handle are passed back to our caller\n    # as |directive, param| \n\n    def handle(text)\n      text.gsub!(/^([ \\t#]*):(\\w+):\\s*(.+)?\\n/) do \n        prefix    = $1\n        directive = $2.downcase\n        param     = $3\n\n        case directive\n        when \"include\"\n          filename = param.split[0]\n          include_file(filename, prefix)\n\n        else\n          yield(directive, param)\n        end\n      end\n    end\n\n    #######\n    private\n    #######\n\n    # Include a file, indenting it correctly\n\n    def include_file(name, indent)\n      if (full_name = find_include_file(name))\n        content = File.open(full_name) {|f| f.read}\n        # strip leading '#'s, but only if all lines start with them\n        if content =~ /^[^#]/\n          content.gsub(/^/, indent)\n        else\n          content.gsub(/^#?/, indent)\n        end\n      else\n        $stderr.puts \"Couldn't find file to include: '#{name}'\"\n        ''\n      end\n    end\n\n    # Look for the given file in the directory containing the current\n    # file, and then in each of the directories specified in the\n    # RDOC_INCLUDE path\n\n    def find_include_file(name)\n      to_search = [ File.dirname(@input_file_name) ].concat @include_path\n      to_search.each do |dir|\n        full_name = File.join(dir, name)\n        stat = File.stat(full_name) rescue next\n        return full_name if stat.readable?\n      end\n      nil\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/to_flow.rb",
    "content": "require 'rdoc/markup/simple_markup/fragments'\nrequire 'rdoc/markup/simple_markup/inline'\nrequire 'cgi'\n\nmodule SM\n\n  module Flow\n    P = Struct.new(:body)\n    VERB = Struct.new(:body)\n    RULE = Struct.new(:width)\n    class LIST\n      attr_reader :type, :contents\n      def initialize(type)\n        @type = type\n        @contents = []\n      end\n      def <<(stuff)\n        @contents << stuff\n      end\n    end\n    LI = Struct.new(:label, :body)\n    H = Struct.new(:level, :text)\n  end\n\n  class ToFlow\n    LIST_TYPE_TO_HTML = {\n      SM::ListBase::BULLET     =>  [ \"<ul>\", \"</ul>\" ],\n      SM::ListBase::NUMBER     =>  [ \"<ol>\", \"</ol>\" ],\n      SM::ListBase::UPPERALPHA =>  [ \"<ol>\", \"</ol>\" ],\n      SM::ListBase::LOWERALPHA =>  [ \"<ol>\", \"</ol>\" ],\n      SM::ListBase::LABELED    =>  [ \"<dl>\", \"</dl>\" ],\n      SM::ListBase::NOTE       =>  [ \"<table>\", \"</table>\" ],\n    }\n\n    InlineTag = Struct.new(:bit, :on, :off)\n\n    def initialize\n      init_tags\n    end\n\n    ##\n    # Set up the standard mapping of attributes to HTML tags\n    #\n    def init_tags\n      @attr_tags = [\n        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), \"<b>\", \"</b>\"),\n        InlineTag.new(SM::Attribute.bitmap_for(:TT),   \"<tt>\", \"</tt>\"),\n        InlineTag.new(SM::Attribute.bitmap_for(:EM),   \"<em>\", \"</em>\"),\n      ]\n    end\n\n    ##\n    # Add a new set of HTML tags for an attribute. We allow\n    # separate start and end tags for flexibility\n    #\n    def add_tag(name, start, stop)\n      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)\n    end\n\n    ##\n    # Given an HTML tag, decorate it with class information\n    # and the like if required. This is a no-op in the base\n    # class, but is overridden in HTML output classes that\n    # implement style sheets\n\n    def annotate(tag)\n      tag\n    end\n\n    ## \n    # Here's the client side of the visitor pattern\n\n    def start_accepting\n      @res = []\n      @list_stack = []\n    end\n\n    def end_accepting\n      @res\n    end\n\n    def accept_paragraph(am, fragment)\n      @res << Flow::P.new((convert_flow(am.flow(fragment.txt))))\n    end\n\n    def accept_verbatim(am, fragment)\n      @res << Flow::VERB.new((convert_flow(am.flow(fragment.txt))))\n    end\n\n    def accept_rule(am, fragment)\n      size = fragment.param\n      size = 10 if size > 10\n      @res << Flow::RULE.new(size)\n    end\n\n    def accept_list_start(am, fragment)\n      @list_stack.push(@res)\n      list = Flow::LIST.new(fragment.type)\n      @res << list\n      @res = list\n    end\n\n    def accept_list_end(am, fragment)\n      @res = @list_stack.pop\n    end\n\n    def accept_list_item(am, fragment)\n      @res << Flow::LI.new(fragment.param, convert_flow(am.flow(fragment.txt)))\n    end\n\n    def accept_blank_line(am, fragment)\n      # @res << annotate(\"<p />\") << \"\\n\"\n    end\n\n    def accept_heading(am, fragment)\n      @res << Flow::H.new(fragment.head_level, convert_flow(am.flow(fragment.txt)))\n    end\n\n\n    #######################################################################\n\n    private\n\n    #######################################################################\n\n    def on_tags(res, item)\n      attr_mask = item.turn_on\n      return if attr_mask.zero?\n\n      @attr_tags.each do |tag|\n        if attr_mask & tag.bit != 0\n          res << annotate(tag.on)\n        end\n      end\n    end\n\n    def off_tags(res, item)\n      attr_mask = item.turn_off\n      return if attr_mask.zero?\n\n      @attr_tags.reverse_each do |tag|\n        if attr_mask & tag.bit != 0\n          res << annotate(tag.off)\n        end\n      end\n    end\n\n    def convert_flow(flow)\n      res = \"\"\n      flow.each do |item|\n        case item\n        when String\n          res << convert_string(item)\n        when AttrChanger\n          off_tags(res, item)\n          on_tags(res,  item)\n        when Special\n          res << convert_special(item)\n        else\n          raise \"Unknown flow element: #{item.inspect}\"\n        end\n      end\n      res\n    end\n\n    # some of these patterns are taken from SmartyPants...\n\n    def convert_string(item)\n      CGI.escapeHTML(item)\n    end\n\n    def convert_special(special)\n      handled = false\n      Attribute.each_name_of(special.type) do |name|\n        method_name = \"handle_special_#{name}\"\n        if self.respond_to? method_name\n          special.text = send(method_name, special)\n          handled = true\n        end\n      end\n      raise \"Unhandled special: #{special}\" unless handled\n      special.text\n    end\n\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/to_html.rb",
    "content": "require 'rdoc/markup/simple_markup/fragments'\nrequire 'rdoc/markup/simple_markup/inline'\n\nrequire 'cgi'\n\nmodule SM\n\n  class ToHtml\n\n    LIST_TYPE_TO_HTML = {\n      ListBase::BULLET =>  [ \"<ul>\", \"</ul>\" ],\n      ListBase::NUMBER =>  [ \"<ol>\", \"</ol>\" ],\n      ListBase::UPPERALPHA =>  [ \"<ol>\", \"</ol>\" ],\n      ListBase::LOWERALPHA =>  [ \"<ol>\", \"</ol>\" ],\n      ListBase::LABELED => [ \"<dl>\", \"</dl>\" ],\n      ListBase::NOTE    => [ \"<table>\", \"</table>\" ],\n    }\n\n    InlineTag = Struct.new(:bit, :on, :off)\n\n    def initialize\n      init_tags\n    end\n\n    ##\n    # Set up the standard mapping of attributes to HTML tags\n    #\n    def init_tags\n      @attr_tags = [\n        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), \"<b>\", \"</b>\"),\n        InlineTag.new(SM::Attribute.bitmap_for(:TT),   \"<tt>\", \"</tt>\"),\n        InlineTag.new(SM::Attribute.bitmap_for(:EM),   \"<em>\", \"</em>\"),\n      ]\n    end\n\n    ##\n    # Add a new set of HTML tags for an attribute. We allow\n    # separate start and end tags for flexibility\n    #\n    def add_tag(name, start, stop)\n      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)\n    end\n\n    ##\n    # Given an HTML tag, decorate it with class information\n    # and the like if required. This is a no-op in the base\n    # class, but is overridden in HTML output classes that\n    # implement style sheets\n\n    def annotate(tag)\n      tag\n    end\n\n    ## \n    # Here's the client side of the visitor pattern\n\n    def start_accepting\n      @res = \"\"\n      @in_list_entry = []\n    end\n\n    def end_accepting\n      @res\n    end\n\n    def accept_paragraph(am, fragment)\n      @res << annotate(\"<p>\") + \"\\n\"\n      @res << wrap(convert_flow(am.flow(fragment.txt)))\n      @res << annotate(\"</p>\") + \"\\n\"\n    end\n\n    def accept_verbatim(am, fragment)\n      @res << annotate(\"<pre>\") + \"\\n\"\n      @res << CGI.escapeHTML(fragment.txt)\n      @res << annotate(\"</pre>\") << \"\\n\"\n    end\n\n    def accept_rule(am, fragment)\n      size = fragment.param\n      size = 10 if size > 10\n      @res << \"<hr size=\\\"#{size}\\\"></hr>\"\n    end\n\n    def accept_list_start(am, fragment)\n      @res << html_list_name(fragment.type, true) <<\"\\n\"\n      @in_list_entry.push false\n    end\n\n    def accept_list_end(am, fragment)\n      if tag = @in_list_entry.pop\n        @res << annotate(tag) << \"\\n\"\n      end\n      @res << html_list_name(fragment.type, false) <<\"\\n\"\n    end\n\n    def accept_list_item(am, fragment)\n      if tag = @in_list_entry.last\n        @res << annotate(tag) << \"\\n\"\n      end\n      @res << list_item_start(am, fragment)\n      @res << wrap(convert_flow(am.flow(fragment.txt))) << \"\\n\"\n      @in_list_entry[-1] = list_end_for(fragment.type)\n    end\n\n    def accept_blank_line(am, fragment)\n      # @res << annotate(\"<p />\") << \"\\n\"\n    end\n\n    def accept_heading(am, fragment)\n      @res << convert_heading(fragment.head_level, am.flow(fragment.txt))\n    end\n\n    # This is a higher speed (if messier) version of wrap\n\n    def wrap(txt, line_len = 76)\n      res = \"\"\n      sp = 0\n      ep = txt.length\n      while sp < ep\n        # scan back for a space\n        p = sp + line_len - 1\n        if p >= ep\n          p = ep\n        else\n          while p > sp and txt[p] != ?\\s\n            p -= 1\n          end\n          if p <= sp\n            p = sp + line_len\n            while p < ep and txt[p] != ?\\s\n              p += 1\n            end\n          end\n        end\n        res << txt[sp...p] << \"\\n\"\n        sp = p\n        sp += 1 while sp < ep and txt[sp] == ?\\s\n      end\n      res\n    end\n\n    #######################################################################\n\n    private\n\n    #######################################################################\n\n    def on_tags(res, item)\n      attr_mask = item.turn_on\n      return if attr_mask.zero?\n\n      @attr_tags.each do |tag|\n        if attr_mask & tag.bit != 0\n          res << annotate(tag.on)\n        end\n      end\n    end\n\n    def off_tags(res, item)\n      attr_mask = item.turn_off\n      return if attr_mask.zero?\n\n      @attr_tags.reverse_each do |tag|\n        if attr_mask & tag.bit != 0\n          res << annotate(tag.off)\n        end\n      end\n    end\n\n    def convert_flow(flow)\n      res = \"\"\n      flow.each do |item|\n        case item\n        when String\n          res << convert_string(item)\n        when AttrChanger\n          off_tags(res, item)\n          on_tags(res,  item)\n        when Special\n          res << convert_special(item)\n        else\n          raise \"Unknown flow element: #{item.inspect}\"\n        end\n      end\n      res\n    end\n\n    # some of these patterns are taken from SmartyPants...\n\n    def convert_string(item)\n      CGI.escapeHTML(item).\n      \n      \n      # convert -- to em-dash, (-- to en-dash)\n        gsub(/---?/, '&#8212;'). #gsub(/--/, '&#8211;').\n\n      # convert ... to elipsis (and make sure .... becomes .<elipsis>)\n        gsub(/\\.\\.\\.\\./, '.&#8230;').gsub(/\\.\\.\\./, '&#8230;').\n\n      # convert single closing quote\n        gsub(%r{([^ \\t\\r\\n\\[\\{\\(])\\'}) { \"#$1&#8217;\" }.\n        gsub(%r{\\'(?=\\W|s\\b)}) { \"&#8217;\" }.\n\n      # convert single opening quote\n        gsub(/'/, '&#8216;').\n\n      # convert double closing quote\n        gsub(%r{([^ \\t\\r\\n\\[\\{\\(])\\'(?=\\W)}) { \"#$1&#8221;\" }.\n\n      # convert double opening quote\n        gsub(/'/, '&#8220;').\n\n      # convert copyright\n        gsub(/\\(c\\)/, '&#169;').\n\n      # convert and registered trademark\n        gsub(/\\(r\\)/, '&#174;')\n\n    end\n\n    def convert_special(special)\n      handled = false\n      Attribute.each_name_of(special.type) do |name|\n        method_name = \"handle_special_#{name}\"\n        if self.respond_to? method_name\n          special.text = send(method_name, special)\n          handled = true\n        end\n      end\n      raise \"Unhandled special: #{special}\" unless handled\n      special.text\n    end\n\n    def convert_heading(level, flow)\n      res =\n        annotate(\"<h#{level}>\") + \n        convert_flow(flow) + \n        annotate(\"</h#{level}>\\n\")\n    end\n\n    def html_list_name(list_type, is_open_tag)\n      tags = LIST_TYPE_TO_HTML[list_type] || raise(\"Invalid list type: #{list_type.inspect}\")\n      annotate(tags[ is_open_tag ? 0 : 1])\n    end\n\n    def list_item_start(am, fragment)\n      case fragment.type\n      when ListBase::BULLET, ListBase::NUMBER\n        annotate(\"<li>\")\n\n      when ListBase::UPPERALPHA\n\tannotate(\"<li type=\\\"A\\\">\")\n\n      when ListBase::LOWERALPHA\n\tannotate(\"<li type=\\\"a\\\">\")\n\n      when ListBase::LABELED\n        annotate(\"<dt>\") +\n          convert_flow(am.flow(fragment.param)) + \n          annotate(\"</dt>\") +\n          annotate(\"<dd>\")\n\n      when ListBase::NOTE\n        annotate(\"<tr>\") +\n          annotate(\"<td valign=\\\"top\\\">\") +\n          convert_flow(am.flow(fragment.param)) + \n          annotate(\"</td>\") +\n          annotate(\"<td>\")\n      else\n        raise \"Invalid list type\"\n      end\n    end\n\n    def list_end_for(fragment_type)\n      case fragment_type\n      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA\n        \"</li>\"\n      when ListBase::LABELED\n        \"</dd>\"\n      when ListBase::NOTE\n        \"</td></tr>\"\n      else\n        raise \"Invalid list type\"\n      end\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup/to_latex.rb",
    "content": "require 'rdoc/markup/simple_markup/fragments'\nrequire 'rdoc/markup/simple_markup/inline'\n\nrequire 'cgi'\n\nmodule SM\n\n  # Convert SimpleMarkup to basic LaTeX report format\n\n  class ToLaTeX\n\n    BS = \"\\020\"   # \\\n    OB = \"\\021\"   # {\n    CB = \"\\022\"   # }\n    DL = \"\\023\"   # Dollar\n\n    BACKSLASH   = \"#{BS}symbol#{OB}92#{CB}\"\n    HAT         = \"#{BS}symbol#{OB}94#{CB}\"\n    BACKQUOTE   = \"#{BS}symbol#{OB}0#{CB}\"\n    TILDE       = \"#{DL}#{BS}sim#{DL}\"\n    LESSTHAN    = \"#{DL}<#{DL}\"\n    GREATERTHAN = \"#{DL}>#{DL}\"\n\n    def self.l(str)\n      str.tr('\\\\', BS).tr('{', OB).tr('}', CB).tr('$', DL)\n    end\n\n    def l(arg)\n      SM::ToLaTeX.l(arg)\n    end\n\n    LIST_TYPE_TO_LATEX = {\n      ListBase::BULLET =>  [ l(\"\\\\begin{itemize}\"), l(\"\\\\end{itemize}\") ],\n      ListBase::NUMBER =>  [ l(\"\\\\begin{enumerate}\"), l(\"\\\\end{enumerate}\"), \"\\\\arabic\" ],\n      ListBase::UPPERALPHA =>  [ l(\"\\\\begin{enumerate}\"), l(\"\\\\end{enumerate}\"), \"\\\\Alph\" ],\n      ListBase::LOWERALPHA =>  [ l(\"\\\\begin{enumerate}\"), l(\"\\\\end{enumerate}\"), \"\\\\alph\" ],\n      ListBase::LABELED => [ l(\"\\\\begin{description}\"), l(\"\\\\end{description}\") ],\n      ListBase::NOTE    => [\n        l(\"\\\\begin{tabularx}{\\\\linewidth}{@{} l X @{}}\"), \n        l(\"\\\\end{tabularx}\") ],\n    }\n\n    InlineTag = Struct.new(:bit, :on, :off)\n\n    def initialize\n      init_tags\n      @list_depth = 0\n      @prev_list_types = []\n    end\n\n    ##\n    # Set up the standard mapping of attributes to LaTeX\n    #\n    def init_tags\n      @attr_tags = [\n        InlineTag.new(SM::Attribute.bitmap_for(:BOLD), l(\"\\\\textbf{\"), l(\"}\")),\n        InlineTag.new(SM::Attribute.bitmap_for(:TT),   l(\"\\\\texttt{\"), l(\"}\")),\n        InlineTag.new(SM::Attribute.bitmap_for(:EM),   l(\"\\\\emph{\"), l(\"}\")),\n      ]\n    end\n\n    ##\n    # Escape a LaTeX string\n    def escape(str)\n# $stderr.print \"FE: \", str\n      s = str.\n#        sub(/\\s+$/, '').\n        gsub(/([_\\${}&%#])/, \"#{BS}\\\\1\").\n        gsub(/\\\\/, BACKSLASH).\n        gsub(/\\^/, HAT).\n        gsub(/~/,  TILDE).\n        gsub(/</,  LESSTHAN).\n        gsub(/>/,  GREATERTHAN).\n        gsub(/,,/, \",{},\").\n        gsub(/\\`/,  BACKQUOTE)\n# $stderr.print \"-> \", s, \"\\n\"\n      s\n    end\n\n    ##\n    # Add a new set of LaTeX tags for an attribute. We allow\n    # separate start and end tags for flexibility\n    #\n    def add_tag(name, start, stop)\n      @attr_tags << InlineTag.new(SM::Attribute.bitmap_for(name), start, stop)\n    end\n\n\n    ## \n    # Here's the client side of the visitor pattern\n\n    def start_accepting\n      @res = \"\"\n      @in_list_entry = []\n    end\n\n    def end_accepting\n      @res.tr(BS, '\\\\').tr(OB, '{').tr(CB, '}').tr(DL, '$')\n    end\n\n    def accept_paragraph(am, fragment)\n      @res << wrap(convert_flow(am.flow(fragment.txt)))\n      @res << \"\\n\"\n    end\n\n    def accept_verbatim(am, fragment)\n      @res << \"\\n\\\\begin{code}\\n\"\n      @res << fragment.txt.sub(/[\\n\\s]+\\Z/, '')\n      @res << \"\\n\\\\end{code}\\n\\n\"\n    end\n\n    def accept_rule(am, fragment)\n      size = fragment.param\n      size = 10 if size > 10\n      @res << \"\\n\\n\\\\rule{\\\\linewidth}{#{size}pt}\\n\\n\"\n    end\n\n    def accept_list_start(am, fragment)\n      @res << list_name(fragment.type, true) <<\"\\n\"\n      @in_list_entry.push false\n    end\n\n    def accept_list_end(am, fragment)\n      if tag = @in_list_entry.pop\n        @res << tag << \"\\n\"\n      end\n      @res << list_name(fragment.type, false) <<\"\\n\"\n    end\n\n    def accept_list_item(am, fragment)\n      if tag = @in_list_entry.last\n        @res << tag << \"\\n\"\n      end\n      @res << list_item_start(am, fragment)\n      @res << wrap(convert_flow(am.flow(fragment.txt))) << \"\\n\"\n      @in_list_entry[-1] = list_end_for(fragment.type)\n    end\n\n    def accept_blank_line(am, fragment)\n      # @res << \"\\n\"\n    end\n\n    def accept_heading(am, fragment)\n      @res << convert_heading(fragment.head_level, am.flow(fragment.txt))\n    end\n\n    # This is a higher speed (if messier) version of wrap\n\n    def wrap(txt, line_len = 76)\n      res = \"\"\n      sp = 0\n      ep = txt.length\n      while sp < ep\n        # scan back for a space\n        p = sp + line_len - 1\n        if p >= ep\n          p = ep\n        else\n          while p > sp and txt[p] != ?\\s\n            p -= 1\n          end\n          if p <= sp\n            p = sp + line_len\n            while p < ep and txt[p] != ?\\s\n              p += 1\n            end\n          end\n        end\n        res << txt[sp...p] << \"\\n\"\n        sp = p\n        sp += 1 while sp < ep and txt[sp] == ?\\s\n      end\n      res\n    end\n\n    #######################################################################\n\n    private\n\n    #######################################################################\n\n    def on_tags(res, item)\n      attr_mask = item.turn_on\n      return if attr_mask.zero?\n\n      @attr_tags.each do |tag|\n        if attr_mask & tag.bit != 0\n          res << tag.on\n        end\n      end\n    end\n\n    def off_tags(res, item)\n      attr_mask = item.turn_off\n      return if attr_mask.zero?\n\n      @attr_tags.reverse_each do |tag|\n        if attr_mask & tag.bit != 0\n          res << tag.off\n        end\n      end\n    end\n\n    def convert_flow(flow)\n      res = \"\"\n      flow.each do |item|\n        case item\n        when String\n#          $stderr.puts \"Converting '#{item}'\"\n          res << convert_string(item)\n        when AttrChanger\n          off_tags(res, item)\n          on_tags(res,  item)\n        when Special\n          res << convert_special(item)\n        else\n          raise \"Unknown flow element: #{item.inspect}\"\n        end\n      end\n      res\n    end\n\n    # some of these patterns are taken from SmartyPants...\n\n    def convert_string(item)\n\n      escape(item).\n      \n      \n      # convert ... to elipsis (and make sure .... becomes .<elipsis>)\n        gsub(/\\.\\.\\.\\./, '.\\ldots{}').gsub(/\\.\\.\\./, '\\ldots{}').\n\n      # convert single closing quote\n        gsub(%r{([^ \\t\\r\\n\\[\\{\\(])\\'}) { \"#$1'\" }.\n        gsub(%r{\\'(?=\\W|s\\b)}) { \"'\" }.\n\n      # convert single opening quote\n        gsub(/'/, '`').\n\n      # convert double closing quote\n        gsub(%r{([^ \\t\\r\\n\\[\\{\\(])\\\"(?=\\W)}) { \"#$1''\" }.\n\n      # convert double opening quote\n        gsub(/\"/, \"``\").\n\n      # convert copyright\n        gsub(/\\(c\\)/, '\\copyright{}')\n\n    end\n\n    def convert_special(special)\n      handled = false\n      Attribute.each_name_of(special.type) do |name|\n        method_name = \"handle_special_#{name}\"\n        if self.respond_to? method_name\n          special.text = send(method_name, special)\n          handled = true\n        end\n      end\n      raise \"Unhandled special: #{special}\" unless handled\n      special.text\n    end\n\n    def convert_heading(level, flow)\n      res =\n        case level\n        when 1 then \"\\\\chapter{\"\n        when 2 then \"\\\\section{\"\n        when 3 then \"\\\\subsection{\"\n        when 4 then \"\\\\subsubsection{\"\n        else  \"\\\\paragraph{\"\n        end +\n        convert_flow(flow) + \n        \"}\\n\"\n    end\n\n    def list_name(list_type, is_open_tag)\n      tags = LIST_TYPE_TO_LATEX[list_type] || raise(\"Invalid list type: #{list_type.inspect}\")\n      if tags[2] # enumerate\n        if is_open_tag\n          @list_depth += 1\n          if @prev_list_types[@list_depth] != tags[2]\n            case @list_depth\n            when 1\n              roman = \"i\"\n            when 2\n              roman = \"ii\"\n            when 3\n              roman = \"iii\"\n            when 4\n              roman = \"iv\"\n            else\n              raise(\"Too deep list: level #{@list_depth}\")\n            end\n            @prev_list_types[@list_depth] = tags[2]\n            return l(\"\\\\renewcommand{\\\\labelenum#{roman}}{#{tags[2]}{enum#{roman}}}\") + \"\\n\" + tags[0]\n          end\n        else\n          @list_depth -= 1\n        end\n      end\n      tags[ is_open_tag ? 0 : 1]\n    end\n\n    def list_item_start(am, fragment)\n      case fragment.type\n      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA\n        \"\\\\item \"\n\n      when ListBase::LABELED\n        \"\\\\item[\" + convert_flow(am.flow(fragment.param)) + \"] \"\n\n      when ListBase::NOTE\n          convert_flow(am.flow(fragment.param)) + \" & \"\n      else\n        raise \"Invalid list type\"\n      end\n    end\n\n    def list_end_for(fragment_type)\n      case fragment_type\n      when ListBase::BULLET, ListBase::NUMBER, ListBase::UPPERALPHA, ListBase::LOWERALPHA, ListBase::LABELED\n        \"\"\n      when ListBase::NOTE\n        \"\\\\\\\\\\n\"\n      else\n        raise \"Invalid list type\"\n      end\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/markup/simple_markup.rb",
    "content": "# = Introduction\n#\n# SimpleMarkup parses plain text documents and attempts to decompose\n# them into their constituent parts. Some of these parts are high-level:\n# paragraphs, chunks of verbatim text, list entries and the like. Other\n# parts happen at the character level: a piece of bold text, a word in\n# code font. This markup is similar in spirit to that used on WikiWiki\n# webs, where folks create web pages using a simple set of formatting\n# rules.\n#\n# SimpleMarkup itself does no output formatting: this is left to a\n# different set of classes.\n#\n# SimpleMarkup is extendable at runtime: you can add new markup\n# elements to be recognised in the documents that SimpleMarkup parses.\n#\n# SimpleMarkup is intended to be the basis for a family of tools which\n# share the common requirement that simple, plain-text should be\n# rendered in a variety of different output formats and media. It is\n# envisaged that SimpleMarkup could be the basis for formating RDoc\n# style comment blocks, Wiki entries, and online FAQs.\n#\n# = Basic Formatting\n#\n# * SimpleMarkup looks for a document's natural left margin. This is\n#   used as the initial margin for the document.\n#\n# * Consecutive lines starting at this margin are considered to be a\n#   paragraph.\n#\n# * If a paragraph starts with a \"*\", \"-\", or with \"<digit>.\", then it is\n#   taken to be the start of a list. The margin in increased to be the\n#   first non-space following the list start flag. Subsequent lines\n#   should be indented to this new margin until the list ends. For\n#   example:\n#\n#      * this is a list with three paragraphs in\n#        the first item. This is the first paragraph.\n#\n#        And this is the second paragraph.\n#\n#        1. This is an indented, numbered list.\n#        2. This is the second item in that list\n#\n#        This is the third conventional paragraph in the\n#        first list item.\n#\n#      * This is the second item in the original list\n#\n# * You can also construct labeled lists, sometimes called description\n#   or definition lists. Do this by putting the label in square brackets\n#   and indenting the list body:\n#\n#       [cat]  a small furry mammal\n#              that seems to sleep a lot\n#\n#       [ant]  a little insect that is known\n#              to enjoy picnics\n#\n#   A minor variation on labeled lists uses two colons to separate the\n#   label from the list body:\n#\n#       cat::  a small furry mammal\n#              that seems to sleep a lot\n#\n#       ant::  a little insect that is known\n#              to enjoy picnics\n#     \n#   This latter style guarantees that the list bodies' left margins are\n#   aligned: think of them as a two column table.\n#\n# * Any line that starts to the right of the current margin is treated\n#   as verbatim text. This is useful for code listings. The example of a\n#   list above is also verbatim text.\n#\n# * A line starting with an equals sign (=) is treated as a\n#   heading. Level one headings have one equals sign, level two headings\n#   have two,and so on.\n#\n# * A line starting with three or more hyphens (at the current indent)\n#   generates a horizontal rule. THe more hyphens, the thicker the rule\n#   (within reason, and if supported by the output device)\n#\n# * You can use markup within text (except verbatim) to change the\n#   appearance of parts of that text. Out of the box, SimpleMarkup\n#   supports word-based and general markup.\n#\n#   Word-based markup uses flag characters around individual words:\n#\n#   [\\*word*]  displays word in a *bold* font\n#   [\\_word_]  displays word in an _emphasized_ font\n#   [\\+word+]  displays word in a +code+ font\n#\n#   General markup affects text between a start delimiter and and end\n#   delimiter. Not surprisingly, these delimiters look like HTML markup.\n#\n#   [\\<b>text...</b>]    displays word in a *bold* font\n#   [\\<em>text...</em>]  displays word in an _emphasized_ font\n#   [\\<i>text...</i>]    displays word in an _emphasized_ font\n#   [\\<tt>text...</tt>]  displays word in a +code+ font\n#\n#   Unlike conventional Wiki markup, general markup can cross line\n#   boundaries. You can turn off the interpretation of markup by\n#   preceding the first character with a backslash, so \\\\\\<b>bold\n#   text</b> and \\\\\\*bold* produce \\<b>bold text</b> and \\*bold\n#   respectively.\n#\n# = Using SimpleMarkup\n#\n# For information on using SimpleMarkup programatically, \n# see SM::SimpleMarkup.\n#\n# Author::   Dave Thomas,  dave@pragmaticprogrammer.com\n# Version::  0.0\n# License::  Ruby license\n\n\n\nrequire 'rdoc/markup/simple_markup/fragments'\nrequire 'rdoc/markup/simple_markup/lines.rb'\n\nmodule SM  #:nodoc:\n\n  # == Synopsis\n  #\n  # This code converts <tt>input_string</tt>, which is in the format\n  # described in markup/simple_markup.rb, to HTML. The conversion\n  # takes place in the +convert+ method, so you can use the same\n  # SimpleMarkup object to convert multiple input strings.\n  #\n  #   require 'rdoc/markup/simple_markup'\n  #   require 'rdoc/markup/simple_markup/to_html'\n  #\n  #   p = SM::SimpleMarkup.new\n  #   h = SM::ToHtml.new\n  #\n  #   puts p.convert(input_string, h)\n  #\n  # You can extend the SimpleMarkup parser to recognise new markup\n  # sequences, and to add special processing for text that matches a\n  # regular epxression. Here we make WikiWords significant to the parser,\n  # and also make the sequences {word} and \\<no>text...</no> signify\n  # strike-through text. When then subclass the HTML output class to deal\n  # with these:\n  #\n  #   require 'rdoc/markup/simple_markup'\n  #   require 'rdoc/markup/simple_markup/to_html'\n  #\n  #   class WikiHtml < SM::ToHtml\n  #     def handle_special_WIKIWORD(special)\n  #       \"<font color=red>\" + special.text + \"</font>\"\n  #     end\n  #   end\n  #\n  #   p = SM::SimpleMarkup.new\n  #   p.add_word_pair(\"{\", \"}\", :STRIKE)\n  #   p.add_html(\"no\", :STRIKE)\n  #\n  #   p.add_special(/\\b([A-Z][a-z]+[A-Z]\\w+)/, :WIKIWORD)\n  #\n  #   h = WikiHtml.new\n  #   h.add_tag(:STRIKE, \"<strike>\", \"</strike>\")\n  #\n  #   puts \"<body>\" + p.convert(ARGF.read, h) + \"</body>\"\n  #\n  # == Output Formatters\n  #\n  # _missing_\n  #\n  #\n\n  class SimpleMarkup\n\n    SPACE = ?\\s\n\n    # List entries look like:\n    #  *       text\n    #  1.      text\n    #  [label] text\n    #  label:: text\n    #\n    # Flag it as a list entry, and\n    # work out the indent for subsequent lines\n\n    SIMPLE_LIST_RE = /^(\n                  (  \\*          (?# bullet)\n                    |-           (?# bullet)\n                    |\\d+\\.       (?# numbered )\n                    |[A-Za-z]\\.  (?# alphabetically numbered )\n                  )\n                  \\s+\n                )\\S/x\n\n    LABEL_LIST_RE = /^(\n                        (  \\[.*?\\]    (?# labeled  )\n                          |\\S.*::     (?# note     )\n                        )(?:\\s+|$)\n                      )/x\n\n\n    ##\n    # take a block of text and use various heuristics to determine\n    # it's structure (paragraphs, lists, and so on). Invoke an\n    # event handler as we identify significant chunks.\n    #\n\n    def initialize\n      @am = AttributeManager.new\n      @output = nil\n    end\n\n    ##\n    # Add to the sequences used to add formatting to an individual word \n    # (such as *bold*). Matching entries will generate attibutes\n    # that the output formatters can recognize by their +name+\n\n    def add_word_pair(start, stop, name)\n      @am.add_word_pair(start, stop, name)\n    end\n\n    ##\n    # Add to the sequences recognized as general markup\n    #\n\n    def add_html(tag, name)\n      @am.add_html(tag, name)\n    end\n\n    ##\n    # Add to other inline sequences. For example, we could add\n    # WikiWords using something like:\n    #\n    #    parser.add_special(/\\b([A-Z][a-z]+[A-Z]\\w+)/, :WIKIWORD)\n    #\n    # Each wiki word will be presented to the output formatter \n    # via the accept_special method\n    #\n\n    def add_special(pattern, name)\n      @am.add_special(pattern, name)\n    end\n\n\n    # We take a string, split it into lines, work out the type of\n    # each line, and from there deduce groups of lines (for example\n    # all lines in a paragraph). We then invoke the output formatter\n    # using a Visitor to display the result\n\n    def convert(str, op)\n      @lines = Lines.new(str.split(/\\r?\\n/).collect { |aLine| \n                           Line.new(aLine) })\n      return \"\" if @lines.empty?\n      @lines.normalize\n      assign_types_to_lines\n      group = group_lines\n      # call the output formatter to handle the result\n      #      group.to_a.each {|i| p i}\n      group.accept(@am, op)\n    end\n\n\n    #######\n    private\n    #######\n\n\n    ##\n    # Look through the text at line indentation. We flag each line as being\n    # Blank, a paragraph, a list element, or verbatim text\n    #\n\n    def assign_types_to_lines(margin = 0, level = 0)\n\n      while line = @lines.next\n        if line.isBlank?\n          line.stamp(Line::BLANK, level)\n          next\n        end\n        \n        # if a line contains non-blanks before the margin, then it must belong\n        # to an outer level\n\n        text = line.text\n        \n        for i in 0...margin\n          if text[i] != SPACE\n            @lines.unget\n            return\n          end\n        end\n\n        active_line = text[margin..-1]\n\n        # Rules (horizontal lines) look like\n        #\n        #  ---   (three or more hyphens)\n        #\n        # The more hyphens, the thicker the rule\n        #\n\n        if /^(---+)\\s*$/ =~ active_line\n          line.stamp(Line::RULE, level, $1.length-2)\n          next\n        end\n\n        # Then look for list entries. First the ones that have to have\n        # text following them (* xxx, - xxx, and dd. xxx)\n\n        if SIMPLE_LIST_RE =~ active_line\n\n          offset = margin + $1.length\n          prefix = $2\n          prefix_length = prefix.length\n\n          flag = case prefix\n                 when \"*\",\"-\" then ListBase::BULLET\n                 when /^\\d/   then ListBase::NUMBER\n                 when /^[A-Z]/ then ListBase::UPPERALPHA\n                 when /^[a-z]/ then ListBase::LOWERALPHA\n                 else raise \"Invalid List Type: #{self.inspect}\"\n                 end\n\n          line.stamp(Line::LIST, level+1, prefix, flag)\n          text[margin, prefix_length] = \" \" * prefix_length\n          assign_types_to_lines(offset, level + 1)\n          next\n        end\n\n\n        if LABEL_LIST_RE =~ active_line\n          offset = margin + $1.length\n          prefix = $2\n          prefix_length = prefix.length\n\n          next if handled_labeled_list(line, level, margin, offset, prefix)\n        end\n\n        # Headings look like\n        # = Main heading\n        # == Second level\n        # === Third\n        #\n        # Headings reset the level to 0\n\n        if active_line[0] == ?= and active_line =~ /^(=+)\\s*(.*)/\n          prefix_length = $1.length\n          prefix_length = 6 if prefix_length > 6\n          line.stamp(Line::HEADING, 0, prefix_length)\n          line.strip_leading(margin + prefix_length)\n          next\n        end\n        \n        # If the character's a space, then we have verbatim text,\n        # otherwise \n\n        if active_line[0] == SPACE\n          line.strip_leading(margin) if margin > 0\n          line.stamp(Line::VERBATIM, level)\n        else\n          line.stamp(Line::PARAGRAPH, level)\n        end\n      end\n    end\n\n    # Handle labeled list entries, We have a special case\n    # to deal with. Because the labels can be long, they force\n    # the remaining block of text over the to right:\n    #\n    # this is a long label that I wrote:: and here is the\n    #                                     block of text with\n    #                                     a silly margin\n    #\n    # So we allow the special case. If the label is followed\n    # by nothing, and if the following line is indented, then\n    # we take the indent of that line as the new margin\n    #\n    # this is a long label that I wrote::\n    #     here is a more reasonably indented block which\n    #     will ab attached to the label.\n    #\n    \n    def handled_labeled_list(line, level, margin, offset, prefix)\n      prefix_length = prefix.length\n      text = line.text\n      flag = nil\n      case prefix\n      when /^\\[/\n        flag = ListBase::LABELED\n        prefix = prefix[1, prefix.length-2]\n      when /:$/\n        flag = ListBase::NOTE\n        prefix.chop!\n      else raise \"Invalid List Type: #{self.inspect}\"\n      end\n      \n      # body is on the next line\n      \n      if text.length <= offset\n        original_line = line\n        line = @lines.next\n        return(false) unless line\n        text = line.text\n        \n        for i in 0..margin\n          if text[i] != SPACE\n            @lines.unget\n            return false\n          end\n        end\n        i = margin\n        i += 1 while text[i] == SPACE\n        if i >= text.length\n          @lines.unget\n          return false\n        else\n          offset = i\n          prefix_length = 0\n          @lines.delete(original_line)\n        end\n      end\n      \n      line.stamp(Line::LIST, level+1, prefix, flag)\n      text[margin, prefix_length] = \" \" * prefix_length\n      assign_types_to_lines(offset, level + 1)\n      return true\n    end\n\n    # Return a block consisting of fragments which are\n    # paragraphs, list entries or verbatim text. We merge consecutive\n    # lines of the same type and level together. We are also slightly\n    # tricky with lists: the lines following a list introduction\n    # look like paragraph lines at the next level, and we remap them\n    # into list entries instead\n\n    def group_lines\n      @lines.rewind\n\n      inList = false\n      wantedType = wantedLevel = nil\n\n      block = LineCollection.new\n      group = nil\n\n      while line = @lines.next\n        if line.level == wantedLevel and line.type == wantedType\n          group.add_text(line.text)\n        else\n          group = block.fragment_for(line)\n          block.add(group)\n          if line.type == Line::LIST\n            wantedType = Line::PARAGRAPH\n          else\n            wantedType = line.type\n          end\n          wantedLevel = line.type == Line::HEADING ? line.param : line.level\n        end\n      end\n\n      block.normalize\n      block\n    end\n\n    ## for debugging, we allow access to our line contents as text\n    def content\n      @lines.as_text\n    end\n    public :content\n\n    ## for debugging, return the list of line types\n    def get_line_types\n      @lines.line_types\n    end\n    public :get_line_types\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/markup/test/AllTests.rb",
    "content": "require 'TestParse.rb'\nrequire 'TestInline.rb'\n"
  },
  {
    "path": "lib/rdoc/markup/test/TestInline.rb",
    "content": "require \"test/unit\"\n\n$:.unshift \"../../..\"\n\nrequire \"rdoc/markup/simple_markup/inline\"\n\nclass TestInline < Test::Unit::TestCase\n\n\n  def setup\n    @am = SM::AttributeManager.new\n\n    @bold_on  = @am.changed_attribute_by_name([], [:BOLD])\n    @bold_off = @am.changed_attribute_by_name([:BOLD], [])\n    \n    @tt_on    = @am.changed_attribute_by_name([], [:TT])\n    @tt_off   = @am.changed_attribute_by_name([:TT], [])\n    \n    @em_on    = @am.changed_attribute_by_name([], [:EM])\n    @em_off   = @am.changed_attribute_by_name([:EM], [])\n    \n    @bold_em_on   = @am.changed_attribute_by_name([], [:BOLD] | [:EM])\n    @bold_em_off  = @am.changed_attribute_by_name([:BOLD] | [:EM], [])\n    \n    @em_then_bold = @am.changed_attribute_by_name([:EM], [:EM] | [:BOLD])\n    \n    @em_to_bold   = @am.changed_attribute_by_name([:EM], [:BOLD])\n    \n    @am.add_word_pair(\"{\", \"}\", :WOMBAT)\n    @wombat_on    = @am.changed_attribute_by_name([], [:WOMBAT])\n    @wombat_off   = @am.changed_attribute_by_name([:WOMBAT], [])\n  end\n\n  def crossref(text)\n    [ @am.changed_attribute_by_name([], [:CROSSREF] | [:_SPECIAL_]),\n      SM::Special.new(33, text),\n      @am.changed_attribute_by_name([:CROSSREF] | [:_SPECIAL_], [])\n    ]\n  end\n\n  def test_special\n    # class names, variable names, file names, or instance variables\n    @am.add_special(/(\n                       \\b([A-Z]\\w+(::\\w+)*)\n                       | \\#\\w+[!?=]?\n                       | \\b\\w+([_\\/\\.]+\\w+)+[!?=]?\n                      )/x, \n                    :CROSSREF)\n    \n    assert_equal([\"cat\"], @am.flow(\"cat\"))\n\n    assert_equal([\"cat \", crossref(\"#fred\"), \" dog\"].flatten,\n                  @am.flow(\"cat #fred dog\"))\n\n    assert_equal([crossref(\"#fred\"), \" dog\"].flatten,\n                  @am.flow(\"#fred dog\"))\n\n    assert_equal([\"cat \", crossref(\"#fred\")].flatten, @am.flow(\"cat #fred\"))\n  end\n\n  def test_basic\n    assert_equal([\"cat\"], @am.flow(\"cat\"))\n\n    assert_equal([\"cat \", @bold_on, \"and\", @bold_off, \" dog\"],\n                  @am.flow(\"cat *and* dog\"))\n\n    assert_equal([\"cat \", @bold_on, \"AND\", @bold_off, \" dog\"],\n                  @am.flow(\"cat *AND* dog\"))\n\n    assert_equal([\"cat \", @em_on, \"And\", @em_off, \" dog\"],\n                  @am.flow(\"cat _And_ dog\"))\n\n    assert_equal([\"cat *and dog*\"], @am.flow(\"cat *and dog*\"))\n\n    assert_equal([\"*cat and* dog\"], @am.flow(\"*cat and* dog\"))\n\n    assert_equal([\"cat *and \", @bold_on, \"dog\", @bold_off],\n                  @am.flow(\"cat *and *dog*\"))\n\n    assert_equal([\"cat \", @em_on, \"and\", @em_off, \" dog\"],\n                  @am.flow(\"cat _and_ dog\"))\n\n    assert_equal([\"cat_and_dog\"],\n                  @am.flow(\"cat_and_dog\"))\n\n    assert_equal([\"cat \", @tt_on, \"and\", @tt_off, \" dog\"],\n                  @am.flow(\"cat +and+ dog\"))\n\n    assert_equal([\"cat \", @bold_on, \"a_b_c\", @bold_off, \" dog\"],\n                  @am.flow(\"cat *a_b_c* dog\"))\n\n    assert_equal([\"cat __ dog\"],\n                  @am.flow(\"cat __ dog\"))\n\n    assert_equal([\"cat \", @em_on, \"_\", @em_off, \" dog\"],\n                  @am.flow(\"cat ___ dog\"))\n\n  end\n\n  def test_combined\n    assert_equal([\"cat \", @em_on, \"and\", @em_off, \" \", @bold_on, \"dog\", @bold_off],\n                  @am.flow(\"cat _and_ *dog*\"))\n\n    assert_equal([\"cat \", @em_on, \"a__nd\", @em_off, \" \", @bold_on, \"dog\", @bold_off], \n                  @am.flow(\"cat _a__nd_ *dog*\"))\n  end\n\n  def test_html_like\n    assert_equal([\"cat \", @tt_on, \"dog\", @tt_off], @am.flow(\"cat <tt>dog</Tt>\"))\n\n    assert_equal([\"cat \", @em_on, \"and\", @em_off, \" \", @bold_on, \"dog\", @bold_off], \n                  @am.flow(\"cat <i>and</i> <B>dog</b>\"))\n    \n    assert_equal([\"cat \", @em_on, \"and \", @em_then_bold, \"dog\", @bold_em_off], \n                  @am.flow(\"cat <i>and <B>dog</B></I>\"))\n    \n    assert_equal([\"cat \", @em_on, \"and \", @em_to_bold, \"dog\", @bold_off], \n                  @am.flow(\"cat <i>and </i><b>dog</b>\"))\n    \n    assert_equal([\"cat \", @em_on, \"and \", @em_to_bold, \"dog\", @bold_off], \n                  @am.flow(\"cat <i>and <b></i>dog</b>\"))\n    \n    assert_equal([@tt_on, \"cat\", @tt_off, \" \", @em_on, \"and \", @em_to_bold, \"dog\", @bold_off], \n                  @am.flow(\"<tt>cat</tt> <i>and <b></i>dog</b>\"))\n\n    assert_equal([\"cat \", @em_on, \"and \", @em_then_bold, \"dog\", @bold_em_off], \n                  @am.flow(\"cat <i>and <b>dog</b></i>\"))\n    \n    assert_equal([\"cat \", @bold_em_on, \"and\", @bold_em_off, \" dog\"], \n                  @am.flow(\"cat <i><b>and</b></i> dog\"))\n    \n    \n  end\n\n  def test_protect\n    assert_equal(['cat \\\\ dog'], @am.flow('cat \\\\ dog'))\n\n    assert_equal([\"cat <tt>dog</Tt>\"], @am.flow(\"cat \\\\<tt>dog</Tt>\"))\n\n    assert_equal([\"cat \", @em_on, \"and\", @em_off, \" <B>dog</b>\"], \n                  @am.flow(\"cat <i>and</i> \\\\<B>dog</b>\"))\n    \n    assert_equal([\"*word* or <b>text</b>\"], @am.flow(\"\\\\*word* or \\\\<b>text</b>\"))\n\n    assert_equal([\"_cat_\", @em_on, \"dog\", @em_off], \n                  @am.flow(\"\\\\_cat_<i>dog</i>\"))\n  end\n\n  def test_adding\n    assert_equal([\"cat \", @wombat_on, \"and\", @wombat_off, \" dog\" ],\n                  @am.flow(\"cat {and} dog\"))\n#    assert_equal([\"cat {and} dog\" ], @am.flow(\"cat \\\\{and} dog\"))\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/markup/test/TestParse.rb",
    "content": "require 'test/unit'\n\n$:.unshift \"../../..\"\n\nrequire 'rdoc/markup/simple_markup'\n\ninclude SM\n\nclass TestParse < Test::Unit::TestCase\n\n  class MockOutput\n    def start_accepting\n      @res = []\n      end\n    \n    def end_accepting\n      @res\n    end\n\n    def accept_paragraph(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_verbatim(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_list_start(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_list_end(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_list_item(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_blank_line(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_heading(am, fragment)\n      @res << fragment.to_s\n    end\n\n    def accept_rule(am, fragment)\n      @res << fragment.to_s\n    end\n\n  end\n\n  def basic_conv(str)\n    sm = SimpleMarkup.new\n    mock = MockOutput.new\n    sm.convert(str, mock)\n    sm.content\n  end\n\n  def line_types(str, expected)\n    p = SimpleMarkup.new\n    mock = MockOutput.new\n    p.convert(str, mock)\n    assert_equal(expected, p.get_line_types.map{|type| type.to_s[0,1]}.join(''))\n  end\n\n  def line_groups(str, expected)\n    p = SimpleMarkup.new\n    mock = MockOutput.new\n\n    block = p.convert(str, mock)\n\n    if block != expected\n      rows = (0...([expected.size, block.size].max)).collect{|i|\n        [expected[i]||\"nil\", block[i]||\"nil\"] \n      }\n      printf \"\\n\\n%35s %35s\\n\", \"Expected\", \"Got\"\n      rows.each {|e,g| printf \"%35s %35s\\n\", e.dump, g.dump }\n    end\n\n    assert_equal(expected, block)\n  end\n\n  def test_tabs\n    str = \"hello\\n  dave\"\n    assert_equal(str, basic_conv(str))\n    str = \"hello\\n\\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n  \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n   \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n    \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n     \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n      \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n       \\tdave\"\n    assert_equal(\"hello\\n        dave\", basic_conv(str))\n    str = \"hello\\n        \\tdave\"\n    assert_equal(\"hello\\n                dave\", basic_conv(str))\n    str = \".\\t\\t.\"\n    assert_equal(\".               .\", basic_conv(str))\n  end\n\n  def test_whitespace\n    assert_equal(\"hello\", basic_conv(\"hello\"))\n    assert_equal(\"hello\", basic_conv(\" hello \"))\n    assert_equal(\"hello\", basic_conv(\" \\t \\t hello\\t\\t\"))\n\n    assert_equal(\"1\\n 2\\n  3\", basic_conv(\"1\\n 2\\n  3\"))\n    assert_equal(\"1\\n 2\\n  3\", basic_conv(\"  1\\n   2\\n    3\"))\n\n    assert_equal(\"1\\n 2\\n  3\\n1\\n 2\", basic_conv(\"1\\n 2\\n  3\\n1\\n 2\"))\n    assert_equal(\"1\\n 2\\n  3\\n1\\n 2\", basic_conv(\"  1\\n   2\\n    3\\n  1\\n   2\"))\n\n    assert_equal(\"1\\n 2\\n\\n  3\", basic_conv(\"  1\\n   2\\n\\n    3\"))\n  end\n\n  def test_types\n    str = \"now is the time\"\n    line_types(str, 'P')\n\n    str = \"now is the time\\nfor all good men\"\n    line_types(str, 'PP')\n\n    str = \"now is the time\\n  code\\nfor all good men\"\n    line_types(str, 'PVP')\n\n    str = \"now is the time\\n  code\\n more code\\nfor all good men\"\n    line_types(str, 'PVVP')\n\n    str = \"now is\\n---\\nthe time\"\n    line_types(str, 'PRP')\n\n    str = %{\\\n       now is\n       * l1\n       * l2\n       the time}\n    line_types(str, 'PLLP')\n\n    str = %{\\\n       now is\n       * l1\n         l1+\n       * l2\n       the time}\n    line_types(str, 'PLPLP')\n\n    str = %{\\\n       now is\n       * l1\n         * l1.1\n       * l2\n       the time}\n    line_types(str, 'PLLLP')\n\n    str = %{\\\n       now is\n       * l1\n         * l1.1\n           text\n             code\n             code\n\n           text\n       * l2\n       the time}\n    line_types(str, 'PLLPVVBPLP')\n\n    str = %{\\\n       now is\n       1. l1\n          * l1.1\n       2. l2\n       the time}\n    line_types(str, 'PLLLP')\n\n    str = %{\\\n       now is\n       [cat] l1\n             * l1.1\n       [dog] l2\n       the time}\n    line_types(str, 'PLLLP')\n\n    str = %{\\\n       now is\n       [cat] l1\n             continuation\n       [dog] l2\n       the time}\n    line_types(str, 'PLPLP')\n  end\n\n  def test_groups\n    str = \"now is the time\"\n    line_groups(str, [\"L0: Paragraph\\nnow is the time\"] )\n\n    str = \"now is the time\\nfor all good men\"\n    line_groups(str, [\"L0: Paragraph\\nnow is the time for all good men\"] )\n\n    str = %{\\\n      now is the time\n        code _line_ here\n      for all good men}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is the time\",\n                  \"L0: Verbatim\\n  code _line_ here\\n\",\n                  \"L0: Paragraph\\nfor all good men\"\n                ] )\n\n    str = \"now is the time\\n  code\\n more code\\nfor all good men\"\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is the time\",\n                  \"L0: Verbatim\\n  code\\n more code\\n\",\n                  \"L0: Paragraph\\nfor all good men\"\n                ] )\n\n    str = %{\\\n       now is\n       * l1\n       * l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n    str = %{\\\n       now is\n       * l1\n         l1+\n       * l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1 l1+\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n    str = %{\\\n       now is\n       * l1\n         * l1.1\n       * l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1\",\n                  \"L2: ListStart\\n\",\n                  \"L2: ListItem\\nl1.1\",\n                  \"L2: ListEnd\\n\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    str = %{\\\n       now is\n       * l1\n         * l1.1\n           text\n             code\n               code\n\n           text\n       * l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1\",\n                  \"L2: ListStart\\n\",\n                  \"L2: ListItem\\nl1.1 text\",\n                  \"L2: Verbatim\\n  code\\n    code\\n\",\n                  \"L2: Paragraph\\ntext\",\n                  \"L2: ListEnd\\n\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    str = %{\\\n       now is\n       1. l1\n          * l1.1\n       2. l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1\",\n                  \"L2: ListStart\\n\",\n                  \"L2: ListItem\\nl1.1\",\n                  \"L2: ListEnd\\n\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n    str = %{\\\n       now is\n       [cat] l1\n             * l1.1\n       [dog] l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1\",\n                  \"L2: ListStart\\n\",\n                  \"L2: ListItem\\nl1.1\",\n                  \"L2: ListEnd\\n\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n    str = %{\\\n       now is\n       [cat] l1\n             continuation\n       [dog] l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1 continuation\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n    \n  end\n\n  def test_verbatim_merge\n    str = %{\\\n       now is\n          code\n       the time}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L0: Verbatim\\n   code\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    str = %{\\\n       now is\n          code\n          code1\n       the time}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L0: Verbatim\\n   code\\n   code1\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    str = %{\\\n       now is\n          code\n\n          code1\n       the time}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L0: Verbatim\\n   code\\n\\n   code1\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    str = %{\\\n       now is\n          code\n\n          code1\n\n       the time}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L0: Verbatim\\n   code\\n\\n   code1\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    str = %{\\\n       now is\n          code\n\n          code1\n\n          code2\n       the time}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L0: Verbatim\\n   code\\n\\n   code1\\n\\n   code2\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n    # Folds multiple blank lines\n    str = %{\\\n       now is\n          code\n\n\n          code1\n\n       the time}\n\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L0: Verbatim\\n   code\\n\\n   code1\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n\n  end\n \n  def test_list_split\n    str = %{\\\n       now is\n       * l1\n       1. n1\n       2. n2\n       * l2\n       the time}\n    line_groups(str,\n                [ \"L0: Paragraph\\nnow is\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl1\",\n                  \"L1: ListEnd\\n\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nn1\",\n                  \"L1: ListItem\\nn2\",\n                  \"L1: ListEnd\\n\",\n                  \"L1: ListStart\\n\",\n                  \"L1: ListItem\\nl2\",\n                  \"L1: ListEnd\\n\",\n                  \"L0: Paragraph\\nthe time\"\n                ])\n\n  end\n\n\n  def test_headings\n    str = \"= heading one\"\n    line_groups(str, \n                [ \"L0: Heading\\nheading one\"\n                ])\n\n    str = \"=== heading three\"\n    line_groups(str, \n                [ \"L0: Heading\\nheading three\"\n                ])\n\n    str = \"text\\n   === heading three\"\n    line_groups(str, \n                [ \"L0: Paragraph\\ntext\",\n                  \"L0: Verbatim\\n   === heading three\\n\"\n                ])\n\n    str = \"text\\n   code\\n   === heading three\"\n    line_groups(str, \n                [ \"L0: Paragraph\\ntext\",\n                  \"L0: Verbatim\\n   code\\n   === heading three\\n\"\n                ])\n\n    str = \"text\\n   code\\n=== heading three\"\n    line_groups(str, \n                [ \"L0: Paragraph\\ntext\",\n                  \"L0: Verbatim\\n   code\\n\",\n                  \"L0: Heading\\nheading three\"\n                ])\n\n  end\n\n  \nend\n"
  },
  {
    "path": "lib/rdoc/options.rb",
    "content": "# We handle the parsing of options, and subsequently as a singleton\n# object to be queried for option values\n\nrequire \"rdoc/ri/ri_paths\"\n\nclass Options\n\n  require 'singleton'\n  require 'getoptlong'\n\n  include Singleton\n\n  # files matching this pattern will be excluded\n  attr_accessor :exclude\n\n  # the name of the output directory\n  attr_accessor :op_dir\n  \n  # the name to use for the output\n  attr_reader :op_name\n\n  # include private and protected methods in the\n  # output\n  attr_accessor :show_all\n  \n  # name of the file, class or module to display in\n  # the initial index page (if not specified\n  # the first file we encounter is used)\n  attr_accessor :main_page\n\n  # merge into classes of the name name when generating ri\n  attr_reader :merge\n\n  # Don't display progress as we process the files\n  attr_reader :quiet\n\n  # description of the output generator (set with the <tt>-fmt</tt>\n  # option\n  attr_accessor :generator\n\n  # and the list of files to be processed\n  attr_reader :files\n\n  # array of directories to search for files to satisfy an :include:\n  attr_reader :rdoc_include\n\n  # title to be used out the output\n  #attr_writer :title\n\n  # template to be used when generating output\n  attr_reader :template\n\n  # should diagrams be drawn\n  attr_reader :diagram\n\n  # should we draw fileboxes in diagrams\n  attr_reader :fileboxes\n\n  # include the '#' at the front of hyperlinked instance method names\n  attr_reader :show_hash\n\n  # image format for diagrams\n  attr_reader :image_format\n\n  # character-set\n  attr_reader :charset\n\n  # should source code be included inline, or displayed in a popup\n  attr_reader :inline_source\n\n  # should the output be placed into a single file\n  attr_reader :all_one_file\n\n  # the number of columns in a tab\n  attr_reader :tab_width\n\n  # include line numbers in the source listings\n  attr_reader :include_line_numbers\n\n  # pattern for additional attr_... style methods\n  attr_reader :extra_accessors\n  attr_reader :extra_accessor_flags\n\n  # URL of stylesheet\n  attr_reader :css\n\n  # URL of web cvs frontend\n  attr_reader :webcvs\n\n  # Are we promiscuous about showing module contents across\n  # multiple files\n  attr_reader :promiscuous\n\n  # scan newer sources than the flag file if true.\n  attr_reader :force_update\n\n  module OptionList\n\n    OPTION_LIST = [\n      [ \"--accessor\",      \"-A\",   \"accessorname[,..]\",\n        \"comma separated list of additional class methods\\n\" +\n        \"that should be treated like 'attr_reader' and\\n\" +\n        \"friends. Option may be repeated. Each accessorname\\n\" +\n        \"may have '=text' appended, in which case that text\\n\" +\n        \"appears where the r/w/rw appears for normal accessors.\"],\n                                                                   \n      [ \"--all\",           \"-a\",   nil,\n        \"include all methods (not just public)\\nin the output\" ],\n\n      [ \"--charset\",       \"-c\",   \"charset\",\n        \"specifies HTML character-set\" ],\n\n      [ \"--debug\",         \"-D\",   nil,\n        \"displays lots on internal stuff\" ],\n\n      [ \"--diagram\",       \"-d\",   nil,\n        \"Generate diagrams showing modules and classes.\\n\" +\n        \"You need dot V1.8.6 or later to use the --diagram\\n\" +\n        \"option correctly. Dot is available from\\n\"+\n        \"http://www.research.att.com/sw/tools/graphviz/\" ],\n\n      [ \"--exclude\",       \"-x\",   \"pattern\",\n        \"do not process files or directories matching\\n\" +\n        \"pattern. Files given explicitly on the command\\n\" +\n        \"line will never be excluded.\" ],\n\n      [ \"--extension\",     \"-E\",   \"new=old\",\n        \"Treat files ending with .new as if they ended with\\n\" +\n        \".old. Using '-E cgi=rb' will cause xxx.cgi to be\\n\" +\n        \"parsed as a Ruby file\"],\n\n      [ \"--fileboxes\",     \"-F\",   nil,\n        \"classes are put in boxes which represents\\n\" +\n        \"files, where these classes reside. Classes\\n\" +\n        \"shared between more than one file are\\n\" +\n        \"shown with list of files that sharing them.\\n\" +\n        \"Silently discarded if --diagram is not given\\n\" +\n        \"Experimental.\" ],\n\n      [ \"--force-update\",  \"-U\",   nil,\n        \"forces to scan all sources even if newer than\\n\" +\n        \"the flag file.\" ],\n\n      [ \"--fmt\",           \"-f\",   \"format name\",\n        \"set the output formatter (see below)\" ],\n\n      [ \"--help\",          \"-h\",   nil,\n        \"you're looking at it\" ],\n\n      [ \"--help-output\",   \"-O\",   nil,\n        \"explain the various output options\" ],\n\n      [ \"--image-format\",  \"-I\",   \"gif/png/jpg/jpeg\",\n        \"Sets output image format for diagrams. Can\\n\" +\n        \"be png, gif, jpeg, jpg. If this option is\\n\" +\n        \"omitted, png is used. Requires --diagram.\" ],\n\n      [ \"--include\",       \"-i\",   \"dir[,dir...]\",\n        \"set (or add to) the list of directories\\n\" +\n        \"to be searched when satisfying :include:\\n\" +\n        \"requests. Can be used more than once.\" ],\n\n      [ \"--inline-source\", \"-S\",   nil,\n        \"Show method source code inline, rather\\n\" +\n        \"than via a popup link\" ],\n\n      [ \"--line-numbers\", \"-N\", nil,\n        \"Include line numbers in the source code\" ],\n\n      [ \"--main\",          \"-m\",   \"name\",\n        \"'name' will be the initial page displayed\" ],\n\n      [ \"--merge\",         \"-M\",   nil,\n        \"when creating ri output, merge processed classes\\n\" +\n        \"into previously documented classes of the name name\"],\n\n      [ \"--one-file\",      \"-1\",   nil,\n        \"put all the output into a single file\" ],\n\n      [ \"--op\",            \"-o\",   \"dir\",\n        \"set the output directory\" ],\n\n      [ \"--opname\",       \"-n\",    \"name\",\n        \"Set the 'name' of the output. Has no\\n\" +\n        \"effect for HTML.\" ],\n\n      [ \"--promiscuous\",   \"-p\",   nil,\n        \"When documenting a file that contains a module\\n\" +\n        \"or class also defined in other files, show\\n\" +\n        \"all stuff for that module/class in each files\\n\" +\n        \"page. By default, only show stuff defined in\\n\" +\n        \"that particular file.\" ],\n\n      [ \"--quiet\",         \"-q\",   nil,\n        \"don't show progress as we parse\" ],\n\n      [ \"--ri\",            \"-r\",   nil,\n       \"generate output for use by 'ri.' The files are\\n\" +\n       \"stored in the '.rdoc' directory under your home\\n\"+\n       \"directory unless overridden by a subsequent\\n\" +\n       \"--op parameter, so no special privileges are needed.\" ],\n\n      [ \"--ri-site\",       \"-R\",   nil,\n       \"generate output for use by 'ri.' The files are\\n\" +\n       \"stored in a site-wide directory, making them accessible\\n\"+\n       \"to others, so special privileges are needed.\" ],\n\n      [ \"--ri-system\",     \"-Y\",   nil,\n       \"generate output for use by 'ri.' The files are\\n\" +\n       \"stored in a system-level directory, making them accessible\\n\"+\n       \"to others, so special privileges are needed. This option\\n\"+\n       \"is intended to be used during Ruby installations\" ],\n\n      [ \"--show-hash\",     \"-H\",   nil,\n        \"A name of the form #name in a comment\\n\" +\n        \"is a possible hyperlink to an instance\\n\" +\n        \"method name. When displayed, the '#' is\\n\" +\n        \"removed unless this option is specified\" ],\n\n      [ \"--style\",         \"-s\",   \"stylesheet url\",\n        \"specifies the URL of a separate stylesheet.\" ],\n\n      [ \"--tab-width\",     \"-w\",   \"n\",\n        \"Set the width of tab characters (default 8)\"],\n\n      [ \"--template\",      \"-T\",   \"template name\",\n        \"Set the template used when generating output\" ],\n\n      [ \"--title\",         \"-t\",   \"text\",\n        \"Set 'txt' as the title for the output\" ],\n\n      [ \"--version\",       \"-v\",   nil,\n        \"display  RDoc's version\" ],\n\n      [ \"--webcvs\",        \"-W\",   \"url\",\n        \"Specify a URL for linking to a web frontend\\n\" +\n        \"to CVS. If the URL contains a '\\%s', the\\n\" +\n        \"name of the current file will be substituted;\\n\" +\n        \"if the URL doesn't contain a '\\%s', the\\n\" +\n        \"filename will be appended to it.\" ],\n    ]\n\n    def OptionList.options\n      OPTION_LIST.map do |long, short, arg,|\n        [ long, \n          short, \n          arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT \n        ]\n      end\n    end\n\n\n    def OptionList.strip_output(text)\n      text =~ /^\\s+/\n      leading_spaces = $&\n      text.gsub!(/^#{leading_spaces}/, '')\n      $stdout.puts text\n    end\n\n\n    # Show an error and exit\n\n    def OptionList.error(msg)\n      $stderr.puts\n      $stderr.puts msg\n      $stderr.puts \"\\nFor help on options, try 'rdoc --help'\\n\\n\"\n      exit 1\n    end\n\n    # Show usage and exit\n    \n    def OptionList.usage(generator_names)\n      \n      puts\n      puts(VERSION_STRING)\n      puts\n\n      name = File.basename($0)\n      OptionList.strip_output(<<-EOT)\n          Usage:\n\n            #{name} [options]  [names...]\n\n          Files are parsed, and the information they contain\n          collected, before any output is produced. This allows cross\n          references between all files to be resolved. If a name is a\n          directory, it is traversed. If no names are specified, all\n          Ruby files in the current directory (and subdirectories) are\n          processed.\n\n          Options:\n\n      EOT\n\n      OPTION_LIST.each do |long, short, arg, desc|\n        opt = sprintf(\"%20s\", \"#{long}, #{short}\")\n        oparg = sprintf(\"%-7s\", arg)\n        print \"#{opt} #{oparg}\"\n        desc = desc.split(\"\\n\")\n        if arg.nil? || arg.length < 7\n          puts desc.shift\n        else\n          puts\n        end\n        desc.each do |line|\n          puts(\" \"*28 + line)\n        end\n        puts\n      end\n\n      puts \"\\nAvailable output formatters: \" +\n        generator_names.sort.join(', ') + \"\\n\\n\"\n\n      puts \"For information on where the output goes, use\\n\\n\"\n      puts \"   rdoc --help-output\\n\\n\"\n\n      exit 0\n    end\n\n    def OptionList.help_output\n      OptionList.strip_output(<<-EOT)\n      How RDoc generates output depends on the output formatter being\n      used, and on the options you give.\n\n      - HTML output is normally produced into a number of separate files\n        (one per class, module, and file, along with various indices). \n        These files will appear in the directory given by the --op\n        option (doc/ by default).\n\n      - XML output by default is written to standard output. If a\n        --opname option is given, the output will instead be written\n        to a file with that name in the output directory.\n\n      - .chm files (Windows help files) are written in the --op directory.\n        If an --opname parameter is present, that name is used, otherwise\n        the file will be called rdoc.chm.\n\n      For information on other RDoc options, use \"rdoc --help\".\n      EOT\n      exit 0\n    end\n  end\n\n  # Parse command line options. We're passed a hash containing\n  # output generators, keyed by the generator name\n\n  def parse(argv, generators)\n    old_argv = ARGV.dup\n    begin\n      ARGV.replace(argv)\n      @op_dir = \"doc\"\n      @op_name = nil\n      @show_all = false\n      @main_page = nil\n      @marge     = false\n      @exclude   = []\n      @quiet = false\n      @generator_name = 'html'\n      @generator = generators[@generator_name]\n      @rdoc_include = []\n      @title = nil\n      @template = nil\n      @diagram = false\n      @fileboxes = false\n      @show_hash = false\n      @image_format = 'png'\n      @inline_source = false\n      @all_one_file  = false\n      @tab_width = 8\n      @include_line_numbers = false\n      @extra_accessor_flags = {}\n      @promiscuous = false\n      @force_update = false\n\n      @css = nil\n      @webcvs = nil\n\n      @charset = case $KCODE\n                 when /^S/i\n                   'Shift_JIS'\n                 when /^E/i\n                   'EUC-JP'\n                 else\n                   'iso-8859-1'\n                 end\n\n      accessors = []\n\n      go = GetoptLong.new(*OptionList.options)\n      go.quiet = true\n\n      go.each do |opt, arg|\n\tcase opt\n        when \"--all\"           then @show_all      = true\n        when \"--charset\"       then @charset       = arg\n        when \"--debug\"         then $DEBUG         = true\n        when \"--exclude\"       then @exclude       << Regexp.new(arg)\n        when \"--inline-source\" then @inline_source = true\n        when \"--line-numbers\"  then @include_line_numbers = true\n        when \"--main\"          then @main_page     = arg\n        when \"--merge\"         then @merge         = true\n        when \"--one-file\"      then @all_one_file  = @inline_source = true\n        when \"--op\"            then @op_dir        = arg\n        when \"--opname\"        then @op_name       = arg\n        when \"--promiscuous\"   then @promiscuous   = true\n        when \"--quiet\"         then @quiet         = true\n        when \"--show-hash\"     then @show_hash     = true\n        when \"--style\"         then @css           = arg\n        when \"--template\"      then @template      = arg\n        when \"--title\"         then @title         = arg\n        when \"--webcvs\"        then @webcvs        = arg\n\n        when \"--accessor\" \n          arg.split(/,/).each do |accessor|\n            if accessor =~ /^(\\w+)(=(.*))?$/\n              accessors << $1\n              @extra_accessor_flags[$1] = $3\n            end\n          end\n\n        when \"--diagram\"\n          check_diagram\n          @diagram = true\n\n        when \"--fileboxes\"\n          @fileboxes = true if @diagram\n\n\twhen \"--fmt\"\n          @generator_name = arg.downcase\n          setup_generator(generators)\n\n        when \"--help\"      \n          OptionList.usage(generators.keys)\n\n        when \"--help-output\"      \n          OptionList.help_output\n\n        when \"--image-format\"\n          if ['gif', 'png', 'jpeg', 'jpg'].include?(arg)\n            @image_format = arg\n          else\n            raise GetoptLong::InvalidOption.new(\"unknown image format: #{arg}\")\n          end\n\n        when \"--include\"   \n          @rdoc_include.concat arg.split(/\\s*,\\s*/)\n\n        when \"--ri\", \"--ri-site\", \"--ri-system\"\n          @generator_name = \"ri\"\n          @op_dir = case opt\n                    when \"--ri\" then RI::Paths::HOMEDIR \n                    when \"--ri-site\" then RI::Paths::SITEDIR\n                    when \"--ri-system\" then RI::Paths::SYSDIR\n                    else fail opt\n                    end\n          setup_generator(generators)\n\n        when \"--tab-width\"\n          begin\n            @tab_width     = Integer(arg)\n          rescue \n            $stderr.puts \"Invalid tab width: '#{arg}'\"\n            exit 1\n          end\n\n        when \"--extension\"\n          new, old = arg.split(/=/, 2)\n          OptionList.error(\"Invalid parameter to '-E'\") unless new && old\n          unless RDoc::ParserFactory.alias_extension(old, new)\n            OptionList.error(\"Unknown extension .#{old} to -E\")\n          end\n\n        when \"--force-update\"\n          @force_update = true\n\n\twhen \"--version\"\n\t  puts VERSION_STRING\n\t  exit\n\tend\n\n      end\n\n      @files = ARGV.dup\n\n      @rdoc_include << \".\" if @rdoc_include.empty?\n\n      if @exclude.empty?\n        @exclude = nil\n      else\n        @exclude = Regexp.new(@exclude.join(\"|\"))\n      end\n\n      check_files\n\n      # If no template was specified, use the default\n      # template for the output formatter\n\n      @template ||= @generator_name\n\n      # Generate a regexp from the accessors\n      unless accessors.empty?\n        re = '^(' + accessors.map{|a| Regexp.quote(a)}.join('|') + ')$' \n        @extra_accessors = Regexp.new(re)\n      end\n\n    rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error\n      OptionList.error(error.message)\n\n    ensure\n      ARGV.replace(old_argv)\n    end\n  end\n\n\n  def title\n    @title ||= \"RDoc Documentation\"\n  end\n  \n  # Set the title, but only if not already set. This means that a title set from \n  # the command line trumps one set in a source file\n\n  def title=(string)\n    @title ||= string\n  end\n\n\n  private\n\n  # Set up an output generator for the format in @generator_name\n  def setup_generator(generators)\n    @generator = generators[@generator_name]\n    if !@generator\n      OptionList.error(\"Invalid output formatter\")\n    end\n    \n    if @generator_name == \"xml\"\n      @all_one_file = true\n      @inline_source = true\n    end\n  end\n\n  # Check that the right version of 'dot' is available.\n  # Unfortuately this doesn't work correctly under Windows NT, \n  # so we'll bypass the test under Windows\n\n  def check_diagram\n    return if RUBY_PLATFORM =~ /mswin|cygwin|mingw|bccwin/\n\n    ok = false\n    ver = nil\n    IO.popen(\"dot -V 2>&1\") do |io|\n      ver = io.read\n      if ver =~ /dot.+version(?:\\s+gviz)?\\s+(\\d+)\\.(\\d+)/\n        ok = ($1.to_i > 1) || ($1.to_i == 1 && $2.to_i >= 8)\n      end\n    end\n    unless ok\n      if ver =~ /^dot.+version/\n        $stderr.puts \"Warning: You may need dot V1.8.6 or later to use\\n\",\n          \"the --diagram option correctly. You have:\\n\\n   \",\n          ver,\n          \"\\nDiagrams might have strange background colors.\\n\\n\"\n      else\n        $stderr.puts \"You need the 'dot' program to produce diagrams.\",\n          \"(see http://www.research.att.com/sw/tools/graphviz/)\\n\\n\"\n        exit\n      end\n#      exit\n    end\n  end\n  \n  # Check that the files on the command line exist\n  \n  def check_files\n    @files.each do |f|\n      stat = File.stat f rescue error(\"File not found: #{f}\")\n      error(\"File '#{f}' not readable\") unless stat.readable?\n    end\n  end\n\n  def error(str)\n    $stderr.puts str\n    exit(1)\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/parsers/parse_c.rb",
    "content": "# Classes and modules built in to the interpreter. We need\n# these to define superclasses of user objects\n\nrequire \"rdoc/code_objects\"\nrequire \"rdoc/parsers/parserfactory\"\nrequire \"rdoc/options\"\nrequire \"rdoc/rdoc\"\n\nmodule RDoc\n\n  ##\n  # Ruby's built-in classes.\n\n  KNOWN_CLASSES = {\n    \"rb_cObject\"           => \"Object\",\n    \"rb_cArray\"            => \"Array\",\n    \"rb_cBignum\"           => \"Bignum\",\n    \"rb_cClass\"            => \"Class\",\n    \"rb_cDir\"              => \"Dir\",\n    \"rb_cData\"             => \"Data\",\n    \"rb_cFalseClass\"       => \"FalseClass\",\n    \"rb_cFile\"             => \"File\",\n    \"rb_cFixnum\"           => \"Fixnum\",\n    \"rb_cFloat\"            => \"Float\",\n    \"rb_cHash\"             => \"Hash\",\n    \"rb_cInteger\"          => \"Integer\",\n    \"rb_cIO\"               => \"IO\",\n    \"rb_cModule\"           => \"Module\",\n    \"rb_cNilClass\"         => \"NilClass\",\n    \"rb_cNumeric\"          => \"Numeric\",\n    \"rb_cProc\"             => \"Proc\",\n    \"rb_cRange\"            => \"Range\",\n    \"rb_cRegexp\"           => \"Regexp\",\n    \"rb_cString\"           => \"String\",\n    \"rb_cSymbol\"           => \"Symbol\",\n    \"rb_cThread\"           => \"Thread\",\n    \"rb_cTime\"             => \"Time\",\n    \"rb_cTrueClass\"        => \"TrueClass\",\n    \"rb_cStruct\"           => \"Struct\",\n    \"rb_eException\"        => \"Exception\",\n    \"rb_eStandardError\"    => \"StandardError\",\n    \"rb_eSystemExit\"       => \"SystemExit\",\n    \"rb_eInterrupt\"        => \"Interrupt\",\n    \"rb_eSignal\"           => \"Signal\",\n    \"rb_eFatal\"            => \"Fatal\",\n    \"rb_eArgError\"         => \"ArgError\",\n    \"rb_eEOFError\"         => \"EOFError\",\n    \"rb_eIndexError\"       => \"IndexError\",\n    \"rb_eRangeError\"       => \"RangeError\",\n    \"rb_eIOError\"          => \"IOError\",\n    \"rb_eRuntimeError\"     => \"RuntimeError\",\n    \"rb_eSecurityError\"    => \"SecurityError\",\n    \"rb_eSystemCallError\"  => \"SystemCallError\",\n    \"rb_eTypeError\"        => \"TypeError\",\n    \"rb_eZeroDivError\"     => \"ZeroDivError\",\n    \"rb_eNotImpError\"      => \"NotImpError\",\n    \"rb_eNoMemError\"       => \"NoMemError\",\n    \"rb_eFloatDomainError\" => \"FloatDomainError\",\n    \"rb_eScriptError\"      => \"ScriptError\",\n    \"rb_eNameError\"        => \"NameError\",\n    \"rb_eSyntaxError\"      => \"SyntaxError\",\n    \"rb_eLoadError\"        => \"LoadError\",\n\n    \"rb_mKernel\"           => \"Kernel\",\n    \"rb_mComparable\"       => \"Comparable\",\n    \"rb_mEnumerable\"       => \"Enumerable\",\n    \"rb_mPrecision\"        => \"Precision\",\n    \"rb_mErrno\"            => \"Errno\",\n    \"rb_mFileTest\"         => \"FileTest\",\n    \"rb_mGC\"               => \"GC\",\n    \"rb_mMath\"             => \"Math\",\n    \"rb_mProcess\"          => \"Process\"\n  }\n\n  ##\n  # We attempt to parse C extension files. Basically we look for\n  # the standard patterns that you find in extensions: <tt>rb_define_class,\n  # rb_define_method</tt> and so on. We also try to find the corresponding\n  # C source for the methods and extract comments, but if we fail\n  # we don't worry too much.\n  #\n  # The comments associated with a Ruby method are extracted from the C\n  # comment block associated with the routine that _implements_ that\n  # method, that is to say the method whose name is given in the\n  # <tt>rb_define_method</tt> call. For example, you might write:\n  #\n  #  /*\n  #   * Returns a new array that is a one-dimensional flattening of this\n  #   * array (recursively). That is, for every element that is an array,\n  #   * extract its elements into the new array.\n  #   *\n  #   *    s = [ 1, 2, 3 ]           #=> [1, 2, 3]\n  #   *    t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]\n  #   *    a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]\n  #   *    a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n  #   */\n  #   static VALUE\n  #   rb_ary_flatten(ary)\n  #       VALUE ary;\n  #   {\n  #       ary = rb_obj_dup(ary);\n  #       rb_ary_flatten_bang(ary);\n  #       return ary;\n  #   }\n  #\n  #   ...\n  #\n  #   void\n  #   Init_Array()\n  #   {\n  #     ...\n  #     rb_define_method(rb_cArray, \"flatten\", rb_ary_flatten, 0);\n  #\n  # Here RDoc will determine from the rb_define_method line that there's a\n  # method called \"flatten\" in class Array, and will look for the implementation\n  # in the method rb_ary_flatten. It will then use the comment from that\n  # method in the HTML output. This method must be in the same source file\n  # as the rb_define_method.\n  #\n  # C classes can be diagrammed (see /tc/dl/ruby/ruby/error.c), and RDoc\n  # integrates C and Ruby source into one tree\n  #\n  # The comment blocks may include special directives:\n  #\n  # [Document-class: <i>name</i>]\n  #   This comment block is documentation for the given class. Use this\n  #   when the <tt>Init_xxx</tt> method is not named after the class.\n  #\n  # [Document-method: <i>name</i>]\n  #   This comment documents the named method. Use when RDoc cannot\n  #   automatically find the method from it's declaration\n  #\n  # [call-seq:  <i>text up to an empty line</i>]\n  #   Because C source doesn't give descriptive names to Ruby-level parameters,\n  #   you need to document the calling sequence explicitly\n  #\n  # In addition, RDoc assumes by default that the C method implementing a \n  # Ruby function is in the same source file as the rb_define_method call.\n  # If this isn't the case, add the comment \n  #\n  #    rb_define_method(....);  // in: filename\n  #\n  # As an example, we might have an extension that defines multiple classes\n  # in its Init_xxx method. We could document them using\n  #\n  #  \n  #  /*\n  #   * Document-class:  MyClass\n  #   *\n  #   * Encapsulate the writing and reading of the configuration\n  #   * file. ...\n  #   */\n  #  \n  #  /*\n  #   * Document-method: read_value\n  #   *\n  #   * call-seq:\n  #   *   cfg.read_value(key)            -> value\n  #   *   cfg.read_value(key} { |key| }  -> value\n  #   *\n  #   * Return the value corresponding to +key+ from the configuration.\n  #   * In the second form, if the key isn't found, invoke the\n  #   * block and return its value.\n  #   */\n  #\n\n  class C_Parser\n\n    attr_accessor :progress\n\n    extend ParserFactory\n    parse_files_matching(/\\.(?:([CcHh])\\1?|c([+xp])\\2|y)\\z/)\n\n    @@known_bodies = {}\n\n    # prepare to parse a C file\n    def initialize(top_level, file_name, body, options, stats)\n      @known_classes = KNOWN_CLASSES.dup\n      @body = handle_tab_width(handle_ifdefs_in(body))\n      @options = options\n      @stats   = stats\n      @top_level = top_level\n      @classes = Hash.new\n      @file_dir = File.dirname(file_name)\n      @progress = $stderr unless options.quiet\n    end\n\n    # Extract the classes/modules and methods from a C file\n    # and return the corresponding top-level object\n    def scan\n      remove_commented_out_lines\n      do_classes\n      do_constants\n      do_methods\n      do_includes\n      do_aliases\n      @top_level\n    end\n\n    #######\n    private\n    #######\n\n    def progress(char)\n      unless @options.quiet\n        @progress.print(char)\n        @progress.flush\n      end\n    end\n\n    def warn(msg)\n      $stderr.puts\n      $stderr.puts msg\n      $stderr.flush\n    end\n\n    def remove_private_comments(comment)\n       comment.gsub!(/\\/?\\*--(.*?)\\/?\\*\\+\\+/m, '')\n       comment.sub!(/\\/?\\*--.*/m, '')\n    end\n\n    ##\n    # removes lines that are commented out that might otherwise get picked up\n    # when scanning for classes and methods\n\n    def remove_commented_out_lines\n      @body.gsub!(%r{//.*rb_define_}, '//')\n    end\n    \n    def handle_class_module(var_name, class_mod, class_name, parent, in_module)\n      progress(class_mod[0, 1])\n\n      parent_name = @known_classes[parent] || parent\n\n      if in_module\n        enclosure = @classes[in_module]\n        unless enclosure\n          if enclosure = @known_classes[in_module]\n            handle_class_module(in_module, (/^rb_m/ =~ in_module ? \"module\" : \"class\"),\n                                enclosure, nil, nil)\n            enclosure = @classes[in_module]\n          end\n        end\n        unless enclosure\n          warn(\"Enclosing class/module '#{in_module}' for \" +\n                \"#{class_mod} #{class_name} not known\")\n          return\n        end\n      else\n        enclosure = @top_level\n      end\n\n      if class_mod == \"class\" \n        cm = enclosure.add_class(NormalClass, class_name, parent_name)\n        @stats.num_classes += 1\n      else\n        cm = enclosure.add_module(NormalModule, class_name)\n        @stats.num_modules += 1\n      end\n      cm.record_location(enclosure.toplevel)\n\n      find_class_comment(cm.full_name, cm)\n      @classes[var_name] = cm\n      @known_classes[var_name] = cm.full_name\n    end\n\n    ##\n    # Look for class or module documentation above Init_+class_name+(void),\n    # in a Document-class +class_name+ (or module) comment or above an\n    # rb_define_class (or module).  If a comment is supplied above a matching\n    # Init_ and a rb_define_class the Init_ comment is used.\n    #\n    #   /*\n    #    * This is a comment for Foo\n    #    */\n    #   Init_Foo(void) {\n    #       VALUE cFoo = rb_define_class(\"Foo\", rb_cObject);\n    #   }\n    #\n    #   /*\n    #    * Document-class: Foo\n    #    * This is a comment for Foo\n    #    */\n    #   Init_foo(void) {\n    #       VALUE cFoo = rb_define_class(\"Foo\", rb_cObject);\n    #   }\n    #\n    #   /*\n    #    * This is a comment for Foo\n    #    */\n    #   VALUE cFoo = rb_define_class(\"Foo\", rb_cObject);\n\n    def find_class_comment(class_name, class_meth)\n      comment = nil\n      if @body =~ %r{((?>/\\*.*?\\*/\\s+))\n                     (static\\s+)?void\\s+Init_#{class_name}\\s*(?:_\\(\\s*)?\\(\\s*(?:void\\s*)?\\)}xmi\n        comment = $1\n      elsif @body =~ %r{Document-(class|module):\\s#{class_name}\\s*?\\n((?>.*?\\*/))}m\n        comment = $2\n      else\n        if @body =~ /rb_define_(class|module)/m then\n          class_name = class_name.split(\"::\").last\n          comments = []\n          @body.split(/(\\/\\*.*?\\*\\/)\\s*?\\n/m).each_with_index do |chunk, index|\n            comments[index] = chunk\n            if chunk =~ /rb_define_(class|module).*?\"(#{class_name})\"/m then\n              comment = comments[index-1]\n              break\n            end\n          end\n        end\n      end\n      class_meth.comment = mangle_comment(comment) if comment\n    end\n    \n    ############################################################\n\n    def do_classes\n      @body.scan(/(\\w+)\\s* = \\s*rb_define_module\\s*\\(\\s*\"(\\w+)\"\\s*\\)/mx) do \n        |var_name, class_name|\n        handle_class_module(var_name, \"module\", class_name, nil, nil)\n      end\n      \n      # The '.' lets us handle SWIG-generated files\n      @body.scan(/([\\w\\.]+)\\s* = \\s*rb_define_class\\s*\n                \\( \n                   \\s*\"(\\w+)\",\n                   \\s*(\\w+)\\s*\n                \\)/mx) do \n        \n        |var_name, class_name, parent|\n        handle_class_module(var_name, \"class\", class_name, parent, nil)\n      end\n      \n      @body.scan(/(\\w+)\\s*=\\s*boot_defclass\\s*\\(\\s*\"(\\w+?)\",\\s*(\\w+?)\\s*\\)/) do\n        |var_name, class_name, parent|\n        parent = nil if parent == \"0\"\n        handle_class_module(var_name, \"class\", class_name, parent, nil)\n      end\n\n      @body.scan(/(\\w+)\\s* = \\s*rb_define_module_under\\s*\n                \\( \n                   \\s*(\\w+),\n                   \\s*\"(\\w+)\"\n                \\s*\\)/mx) do \n        \n        |var_name, in_module, class_name|\n        handle_class_module(var_name, \"module\", class_name, nil, in_module)\n      end\n      \n      @body.scan(/([\\w\\.]+)\\s* = \\s*rb_define_class_under\\s*\n                \\( \n                   \\s*(\\w+),\n                   \\s*\"(\\w+)\",\n                   \\s*(\\w+)\\s*\n                \\s*\\)/mx) do \n        \n        |var_name, in_module, class_name, parent|\n        handle_class_module(var_name, \"class\", class_name, parent, in_module)\n      end\n      \n    end\n\n\t\t###########################################################\n\n    def do_constants\n      @body.scan(%r{\\Wrb_define_\n                     (\n                        variable |\n                        readonly_variable |\n                        const |\n                        global_const |\n                      )\n                 \\s*\\( \n                   (?:\\s*(\\w+),)?\n                   \\s*\"(\\w+)\",\n                   \\s*(.*?)\\s*\\)\\s*;\n                   }xm) do\n        \n        |type, var_name, const_name, definition|\n        var_name = \"rb_cObject\" if !var_name or var_name == \"rb_mKernel\"\n\t\t\t\thandle_constants(type, var_name, const_name, definition)\n      end\n    end\n    \n    ############################################################\n    \n    def do_methods\n\n      @body.scan(%r{rb_define_\n                     (\n                        singleton_method |\n                        method           |\n                        module_function  |\n                        private_method\n                     )\n                     \\s*\\(\\s*([\\w\\.]+),\n                       \\s*\"([^\"]+)\",\n                       \\s*(?:RUBY_METHOD_FUNC\\(|VALUEFUNC\\()?(\\w+)\\)?,\n                       \\s*(-?\\w+)\\s*\\)\n                     (?:;\\s*/[*/]\\s+in\\s+(\\w+?\\.[cy]))?\n                   }xm) do\n        |type, var_name, meth_name, meth_body, param_count, source_file|\n       #\" \n\n        # Ignore top-object and weird struct.c dynamic stuff\n        next if var_name == \"ruby_top_self\" \n        next if var_name == \"nstr\"\n        next if var_name == \"envtbl\"\n        next if var_name == \"argf\"   # it'd be nice to handle this one\n\n        var_name = \"rb_cObject\" if var_name == \"rb_mKernel\"\n        handle_method(type, var_name, meth_name, \n                      meth_body, param_count, source_file)\n      end\n\n      @body.scan(%r{rb_define_attr\\(\n                               \\s*([\\w\\.]+),\n                               \\s*\"([^\"]+)\",\n                               \\s*(\\d+),\n                               \\s*(\\d+)\\s*\\);\n                  }xm) do  #\"\n        |var_name, attr_name, attr_reader, attr_writer|\n        \n        #var_name = \"rb_cObject\" if var_name == \"rb_mKernel\"\n        handle_attr(var_name, attr_name,\n                    attr_reader.to_i != 0,\n                    attr_writer.to_i != 0)\n      end\n\n      @body.scan(%r{rb_define_global_function\\s*\\(\n                               \\s*\"([^\"]+)\",\n                               \\s*(?:RUBY_METHOD_FUNC\\(|VALUEFUNC\\()?(\\w+)\\)?,\n                               \\s*(-?\\w+)\\s*\\)\n                  (?:;\\s*/[*/]\\s+in\\s+(\\w+?\\.[cy]))?\n                  }xm) do  #\"\n        |meth_name, meth_body, param_count, source_file|\n        handle_method(\"method\", \"rb_mKernel\", meth_name, \n                      meth_body, param_count, source_file)\n      end\n  \n      @body.scan(/define_filetest_function\\s*\\(\n                               \\s*\"([^\"]+)\",\n                               \\s*(?:RUBY_METHOD_FUNC\\(|VALUEFUNC\\()?(\\w+)\\)?,\n                               \\s*(-?\\w+)\\s*\\)/xm) do  #\"\n        |meth_name, meth_body, param_count|\n        \n        handle_method(\"method\", \"rb_mFileTest\", meth_name, meth_body, param_count)\n        handle_method(\"singleton_method\", \"rb_cFile\", meth_name, meth_body, param_count)\n      end\n   end\n\n    ############################################################\n    \n    def do_aliases\n      @body.scan(%r{rb_define_alias\\s*\\(\\s*(\\w+),\\s*\"([^\"]+)\",\\s*\"([^\"]+)\"\\s*\\)}m) do\n        |var_name, new_name, old_name|\n        @stats.num_methods += 1\n        class_name = @known_classes[var_name] || var_name\n        class_obj  = find_class(var_name, class_name)\n\n        class_obj.add_alias(Alias.new(\"\", old_name, new_name, \"\"))\n      end\n   end\n\n    ##\n    # Adds constant comments.  By providing some_value: at the start ofthe\n    # comment you can override the C value of the comment to give a friendly\n    # definition.\n    #\n    #   /* 300: The perfect score in bowling */\n    #   rb_define_const(cFoo, \"PERFECT\", INT2FIX(300);\n    #\n    # Will override +INT2FIX(300)+ with the value +300+ in the output RDoc.\n    # Values may include quotes and escaped colons (\\:).\n\n    def handle_constants(type, var_name, const_name, definition)\n      #@stats.num_constants += 1\n      class_name = @known_classes[var_name]\n      \n      return unless class_name\n\n      class_obj  = find_class(var_name, class_name)\n\n      unless class_obj\n        warn(\"Enclosing class/module '#{const_name}' for not known\")\n        return\n      end\n      \n      comment = find_const_comment(type, const_name)\n\n      # In the case of rb_define_const, the definition and comment are in\n      # \"/* definition: comment */\" form.  The literal ':' and '\\' characters\n      # can be escaped with a backslash.\n      if type.downcase == 'const' then\n         elements = mangle_comment(comment).split(':')\n         if elements.nil? or elements.empty? then\n            con = Constant.new(const_name, definition, mangle_comment(comment))\n         else\n            new_definition = elements[0..-2].join(':')\n            if new_definition.empty? then # Default to literal C definition\n               new_definition = definition\n            else\n               new_definition.gsub!(\"\\:\", \":\")\n               new_definition.gsub!(\"\\\\\", '\\\\')\n            end\n            new_definition.sub!(/\\A(\\s+)/, '')\n            new_comment = $1.nil? ? elements.last : \"#{$1}#{elements.last.lstrip}\"\n            con = Constant.new(const_name, new_definition,\n                               mangle_comment(new_comment))\n         end\n      else\n         con = Constant.new(const_name, definition, mangle_comment(comment))\n      end\n\n      class_obj.add_constant(con)\n    end\n\n    ##\n    # Finds a comment matching +type+ and +const_name+ either above the\n    # comment or in the matching Document- section.\n\n    def find_const_comment(type, const_name)\n      if @body =~ %r{((?>^\\s*/\\*.*?\\*/\\s+))\n                     rb_define_#{type}\\((?:\\s*(\\w+),)?\\s*\"#{const_name}\"\\s*,.*?\\)\\s*;}xmi\n        $1\n      elsif @body =~ %r{Document-(?:const|global|variable):\\s#{const_name}\\s*?\\n((?>.*?\\*/))}m\n        $1\n      else\n        ''\n      end\n    end\n\n    ###########################################################\n\n    def handle_attr(var_name, attr_name, reader, writer)\n      rw = ''\n      if reader \n        #@stats.num_methods += 1\n        rw << 'R'\n      end\n      if writer\n        #@stats.num_methods += 1\n        rw << 'W'\n      end\n\n      class_name = @known_classes[var_name]\n\n      return unless class_name\n      \n      class_obj  = find_class(var_name, class_name)\n\n      if class_obj\n        comment = find_attr_comment(attr_name)\n        unless comment.empty?\n          comment = mangle_comment(comment)\n        end\n        att = Attr.new('', attr_name, rw, comment)\n        class_obj.add_attribute(att)\n      end\n\n    end\n\n    ###########################################################\n\n    def find_attr_comment(attr_name)\n      if @body =~ %r{((?>/\\*.*?\\*/\\s+))\n                     rb_define_attr\\((?:\\s*(\\w+),)?\\s*\"#{attr_name}\"\\s*,.*?\\)\\s*;}xmi\n        $1\n      elsif @body =~ %r{Document-attr:\\s#{attr_name}\\s*?\\n((?>.*?\\*/))}m\n        $1\n      else\n        ''\n      end\n    end\n\n    ###########################################################\n\n    def handle_method(type, var_name, meth_name, \n                      meth_body, param_count, source_file = nil)\n      progress(\".\")\n\n      @stats.num_methods += 1\n      class_name = @known_classes[var_name]\n\n      return unless class_name\n\n      class_obj  = find_class(var_name, class_name)\n      \n      if class_obj\n        if meth_name == \"initialize\"\n          meth_name = \"new\"\n          type = \"singleton_method\"\n        end\n        meth_obj = AnyMethod.new(\"\", meth_name)\n        meth_obj.singleton =\n\t  %w{singleton_method module_function}.include?(type) \n        \n        p_count = (Integer(param_count) rescue -1)\n        \n        if p_count < 0\n          meth_obj.params = \"(...)\"\n        elsif p_count == 0\n          meth_obj.params = \"()\"\n        else\n          meth_obj.params = \"(\" +\n                            (1..p_count).map{|i| \"p#{i}\"}.join(\", \") + \n                                                \")\"\n        end\n\n        if source_file\n          file_name = File.join(@file_dir, source_file)\n          body = (@@known_bodies[source_file] ||= File.read(file_name))\n        else\n          body = @body\n        end\n        if find_body(meth_body, meth_obj, body) and meth_obj.document_self\n          class_obj.add_method(meth_obj)\n        end\n      end\n    end\n    \n    ############################################################\n\n    # Find the C code corresponding to a Ruby method\n    def find_body(meth_name, meth_obj, body, quiet = false)\n      case body\n      when %r{((?>/\\*.*?\\*/\\s*))(?:static\\s+)?VALUE\\s+#{meth_name}\n              \\s*(\\(.*?\\)).*?^}xm\n        comment, params = $1, $2\n        body_text = $&\n\n        remove_private_comments(comment) if comment\n\n        # see if we can find the whole body\n        \n        re = Regexp.escape(body_text) + '[^(]*^\\{.*?^\\}'\n        if Regexp.new(re, Regexp::MULTILINE).match(body)\n          body_text = $&\n        end\n\n        # The comment block may have been overridden with a\n        # 'Document-method' block. This happens in the interpreter\n        # when multiple methods are vectored through to the same\n        # C method but those methods are logically distinct (for\n        # example Kernel.hash and Kernel.object_id share the same\n        # implementation\n\n        override_comment = find_override_comment(meth_obj.name)\n        comment = override_comment if override_comment\n\n        find_modifiers(comment, meth_obj) if comment\n        \n#        meth_obj.params = params\n        meth_obj.start_collecting_tokens\n        meth_obj.add_token(RubyToken::Token.new(1,1).set_text(body_text))\n        meth_obj.comment = mangle_comment(comment)\n      when %r{((?>/\\*.*?\\*/\\s*))^\\s*\\#\\s*define\\s+#{meth_name}\\s+(\\w+)}m\n        comment = $1\n        find_body($2, meth_obj, body, true)\n        find_modifiers(comment, meth_obj)\n        meth_obj.comment = mangle_comment(comment) + meth_obj.comment\n      when %r{^\\s*\\#\\s*define\\s+#{meth_name}\\s+(\\w+)}m\n        unless find_body($1, meth_obj, body, true)\n          warn \"No definition for #{meth_name}\" unless quiet\n          return false\n        end\n      else\n\n        # No body, but might still have an override comment\n        comment = find_override_comment(meth_obj.name)\n\n        if comment\n          find_modifiers(comment, meth_obj)\n          meth_obj.comment = mangle_comment(comment)\n        else\n          warn \"No definition for #{meth_name}\" unless quiet\n          return false\n        end\n      end\n      true\n    end\n\n\n    ##\n    # If the comment block contains a section that looks like:\n    #\n    #    call-seq:\n    #        Array.new\n    #        Array.new(10)\n    #\n    # use it for the parameters.\n\n    def find_modifiers(comment, meth_obj)\n      if comment.sub!(/:nodoc:\\s*^\\s*\\*?\\s*$/m, '') or\n         comment.sub!(/\\A\\/\\*\\s*:nodoc:\\s*\\*\\/\\Z/, '')\n        meth_obj.document_self = false\n      end\n      if comment.sub!(/call-seq:(.*?)^\\s*\\*?\\s*$/m, '') or\n         comment.sub!(/\\A\\/\\*\\s*call-seq:(.*?)\\*\\/\\Z/, '')\n        seq = $1\n        seq.gsub!(/^\\s*\\*\\s*/, '')\n        meth_obj.call_seq = seq\n      end\n    end\n\n    ############################################################\n\n    def find_override_comment(meth_name)\n      name = Regexp.escape(meth_name)\n      if @body =~ %r{Document-method:\\s#{name}\\s*?\\n((?>.*?\\*/))}m\n        $1\n      end\n    end\n\n    ##\n    # Look for includes of the form:\n    #\n    #     rb_include_module(rb_cArray, rb_mEnumerable);\n\n    def do_includes\n      @body.scan(/rb_include_module\\s*\\(\\s*(\\w+?),\\s*(\\w+?)\\s*\\)/) do |c,m|\n        if cls = @classes[c]\n          m = @known_classes[m] || m\n          cls.add_include(Include.new(m, \"\"))\n        end\n      end\n    end\n\n    ##\n    # Remove the /*'s and leading asterisks from C comments\n    \n    def mangle_comment(comment)\n      comment.sub!(%r{/\\*+}) { \" \" * $&.length }\n      comment.sub!(%r{\\*+/}) { \" \" * $&.length }\n      comment.gsub!(/^[ \\t]*\\*/m) { \" \" * $&.length }\n      comment\n    end\n\n    def find_class(raw_name, name)\n      unless @classes[raw_name]\n        if raw_name =~ /^rb_m/ \n          @classes[raw_name] = @top_level.add_module(NormalModule, name)\n        else\n          @classes[raw_name] = @top_level.add_class(NormalClass, name, nil)\n        end\n      end\n      @classes[raw_name]\n    end\n\n    def handle_tab_width(body)\n      if /\\t/ =~ body\n        tab_width = Options.instance.tab_width\n        body.split(/\\n/).map do |line|\n          1 while line.gsub!(/\\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)}  && $~ #`\n          line\n        end .join(\"\\n\")\n      else\n        body\n      end\n    end\n\n    ##\n    # Removes #ifdefs that would otherwise confuse us\n    \n    def handle_ifdefs_in(body)\n      body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\\n(.*?)#endif.*?\\n/m) { $1 }\n    end\n    \n  end\n\nend\n\n"
  },
  {
    "path": "lib/rdoc/parsers/parse_f95.rb",
    "content": "#= parse_f95.rb - Fortran95 Parser\n#\n#== Overview\n#\n#\"parse_f95.rb\" parses Fortran95 files with suffixes \"f90\", \"F90\", \"f95\"\n#and \"F95\". Fortran95 files are expected to be conformed to Fortran95\n#standards.\n#\n#== Rules\n#\n#Fundamental rules are same as that of the Ruby parser.\n#But comment markers are '!' not '#'.\n#\n#=== Correspondence between RDoc documentation and Fortran95 programs\n#\n#\"parse_f95.rb\" parses main programs, modules, subroutines, functions,\n#derived-types, public variables, public constants,\n#defined operators and defined assignments.\n#These components are described in items of RDoc documentation, as follows.\n#\n#Files :: Files (same as Ruby)\n#Classes :: Modules\n#Methods :: Subroutines, functions, variables, constants, derived-types, defined operators, defined assignments\n#Required files :: Files in which imported modules, external subroutines and external functions are defined.\n#Included Modules :: List of imported modules\n#Attributes :: List of derived-types, List of imported modules all of whose components are published again\n#\n#Components listed in 'Methods' (subroutines, functions, ...)\n#defined in modules are described in the item of 'Classes'.\n#On the other hand, components defined in main programs or\n#as external procedures are described in the item of 'Files'.\n#\n#=== Components parsed by default\n#\n#By default, documentation on public components (subroutines, functions, \n#variables, constants, derived-types, defined operators, \n#defined assignments) are generated. \n#With \"--all\" option, documentation on all components\n#are generated (almost same as the Ruby parser).\n#\n#=== Information parsed automatically\n#\n#The following information is automatically parsed.\n#\n#* Types of arguments\n#* Types of variables and constants\n#* Types of variables in the derived types, and initial values\n#* NAMELISTs and types of variables in them, and initial values\n#\n#Aliases by interface statement are described in the item of 'Methods'.\n#\n#Components which are imported from other modules and published again \n#are described in the item of 'Methods'.\n#\n#=== Format of comment blocks\n#\n#Comment blocks should be written as follows.\n#Comment blocks are considered to be ended when the line without '!'\n#appears.\n#The indentation is not necessary.\n#\n#     ! (Top of file)\n#     !\n#     ! Comment blocks for the files.\n#     !\n#     !--\n#     ! The comment described in the part enclosed by\n#     ! \"!--\" and \"!++\" is ignored.\n#     !++\n#     !\n#     module hogehoge\n#       !\n#       ! Comment blocks for the modules (or the programs).\n#       !\n#\n#       private\n#\n#       logical            :: a     ! a private variable\n#       real, public       :: b     ! a public variable\n#       integer, parameter :: c = 0 ! a public constant\n#\n#       public :: c\n#       public :: MULTI_ARRAY\n#       public :: hoge, foo\n#\n#       type MULTI_ARRAY\n#         !\n#         ! Comment blocks for the derived-types.\n#         !\n#         real, pointer :: var(:) =>null() ! Comments block for the variables.\n#         integer       :: num = 0\n#       end type MULTI_ARRAY\n#\n#     contains\n#\n#       subroutine hoge( in,   &   ! Comment blocks between continuation lines are ignored.\n#           &            out )\n#         !\n#         ! Comment blocks for the subroutines or functions\n#         !\n#         character(*),intent(in):: in ! Comment blocks for the arguments.\n#         character(*),intent(out),allocatable,target  :: in\n#                                      ! Comment blocks can be\n#                                      ! written under Fortran statements.\n#\n#         character(32) :: file ! This comment parsed as a variable in below NAMELIST.\n#         integer       :: id\n#\n#         namelist /varinfo_nml/ file, id\n#                 !\n#                 ! Comment blocks for the NAMELISTs.\n#                 ! Information about variables are described above.\n#                 !\n#\n#       ....\n#\n#       end subroutine hoge\n#\n#       integer function foo( in )\n#         !\n#         ! This part is considered as comment block.\n#\n#         ! Comment blocks under blank lines are ignored.\n#         !\n#         integer, intent(in):: inA ! This part is considered as comment block.\n#\n#                                   ! This part is ignored.\n#\n#       end function foo\n#\n#       subroutine hide( in,   &\n#         &              out )      !:nodoc:\n#         !\n#         ! If \"!:nodoc:\" is described at end-of-line in subroutine\n#         ! statement as above, the subroutine is ignored.\n#         ! This assignment can be used to modules, subroutines,\n#         ! functions, variables, constants, derived-types,\n#         ! defined operators, defined assignments,\n#         ! list of imported modules (\"use\" statement).\n#         !\n#\n#       ....\n#\n#       end subroutine hide\n#\n#     end module hogehoge\n#\n\n\nrequire \"rdoc/code_objects\"\n\nmodule RDoc\n\n  class Token\n\n    NO_TEXT = \"??\".freeze\n\n    def initialize(line_no, char_no)\n      @line_no = line_no\n      @char_no = char_no\n      @text    = NO_TEXT\n    end\n    # Because we're used in contexts that expect to return a token,\n    # we set the text string and then return ourselves\n    def set_text(text)\n      @text = text\n      self\n    end\n\n    attr_reader :line_no, :char_no, :text\n\n  end\n\n  # See rdoc/parsers/parse_f95.rb\n\n  class Fortran95parser\n\n    extend ParserFactory\n    parse_files_matching(/\\.((f|F)9(0|5)|F)$/)\n\n    @@external_aliases = []\n    @@public_methods   = []\n\n    # \"false\":: Comments are below source code\n    # \"true\" :: Comments are upper source code\n    COMMENTS_ARE_UPPER  = false\n\n    # Internal alias message\n    INTERNAL_ALIAS_MES = \"Alias for\"\n\n    # External alias message\n    EXTERNAL_ALIAS_MES = \"The entity is\"\n\n    # prepare to parse a Fortran 95 file\n    def initialize(top_level, file_name, body, options, stats)\n      @body = body\n      @stats = stats\n      @file_name  = file_name\n      @options = options\n      @top_level = top_level\n      @progress = $stderr unless options.quiet\n    end\n\n    # define code constructs\n    def scan\n\n      # remove private comment\n      remaining_code = remove_private_comments(@body)\n\n      # continuation lines are united to one line\n      remaining_code = united_to_one_line(remaining_code)\n\n      # semicolons are replaced to line feed\n      remaining_code = semicolon_to_linefeed(remaining_code)\n\n      # collect comment for file entity\n      whole_comment, remaining_code = collect_first_comment(remaining_code)\n      @top_level.comment = whole_comment\n\n      # String \"remaining_code\" is converted to Array \"remaining_lines\"\n      remaining_lines = remaining_code.split(\"\\n\")\n\n      # \"module\" or \"program\" parts are parsed (new)\n      #\n      level_depth = 0\n      block_searching_flag = nil\n      block_searching_lines = []\n      pre_comment = []\n      module_program_trailing = \"\"\n      module_program_name = \"\"\n      other_block_level_depth = 0\n      other_block_searching_flag = nil\n      remaining_lines.collect!{|line|\n        if !block_searching_flag && !other_block_searching_flag\n          if line =~ /^\\s*?module\\s+(\\w+)\\s*?(!.*?)?$/i\n            block_searching_flag = :module\n            block_searching_lines << line\n            module_program_name = $1\n            module_program_trailing = find_comments($2)\n            next false\n          elsif line =~ /^\\s*?program\\s+(\\w+)\\s*?(!.*?)?$/i ||\n                 line =~ /^\\s*?\\w/ && !block_start?(line)\n            block_searching_flag = :program\n            block_searching_lines << line\n            module_program_name = $1 || \"\"\n            module_program_trailing = find_comments($2)\n            next false\n\n          elsif block_start?(line)\n            other_block_searching_flag = true\n            next line\n\n          elsif line =~ /^\\s*?!\\s?(.*)/\n            pre_comment << line\n            next line\n          else\n            pre_comment = []\n            next line\n          end\n        elsif other_block_searching_flag\n          other_block_level_depth += 1 if block_start?(line)\n          other_block_level_depth -= 1 if block_end?(line)\n          if other_block_level_depth < 0\n            other_block_level_depth = 0\n            other_block_searching_flag = nil\n          end\n          next line\n        end\n\n        block_searching_lines << line\n        level_depth += 1 if block_start?(line)\n        level_depth -= 1 if block_end?(line)\n        if level_depth >= 0\n          next false\n        end\n\n        # \"module_program_code\" is formatted.\n        # \":nodoc:\" flag is checked.\n        #\n        module_program_code = block_searching_lines.join(\"\\n\")\n        module_program_code = remove_empty_head_lines(module_program_code)\n        if module_program_trailing =~ /^:nodoc:/\n          # next loop to search next block\n          level_depth = 0\n          block_searching_flag = false\n          block_searching_lines = []\n          pre_comment = []\n          next false\n        end\n\n        # NormalClass is created, and added to @top_level\n        #\n        if block_searching_flag == :module\n          module_name = module_program_name\n          module_code = module_program_code\n          module_trailing = module_program_trailing\n          progress \"m\"\n          @stats.num_modules += 1\n          f9x_module = @top_level.add_module NormalClass, module_name\n          f9x_module.record_location @top_level\n\n          f9x_comment = COMMENTS_ARE_UPPER ? \n            find_comments(pre_comment.join(\"\\n\"))  + \"\\n\" + module_trailing :\n              module_trailing + \"\\n\" + find_comments(module_code.sub(/^.*$\\n/i, ''))\n          f9x_module.comment = f9x_comment\n          parse_program_or_module(f9x_module, module_code)\n\n          TopLevel.all_files.each do |name, toplevel|\n            if toplevel.include_includes?(module_name, @options.ignore_case)\n              if !toplevel.include_requires?(@file_name, @options.ignore_case)\n                toplevel.add_require(Require.new(@file_name, \"\"))\n              end\n            end\n            toplevel.each_classmodule{|m|\n              if m.include_includes?(module_name, @options.ignore_case)\n                if !m.include_requires?(@file_name, @options.ignore_case)\n                  m.add_require(Require.new(@file_name, \"\"))\n                end\n              end\n            }\n          end\n        elsif block_searching_flag == :program\n          program_name = module_program_name\n          program_code = module_program_code\n          program_trailing = module_program_trailing\n          progress \"p\"\n          program_comment = COMMENTS_ARE_UPPER ? \n            find_comments(pre_comment.join(\"\\n\")) + \"\\n\" + program_trailing : \n              program_trailing + \"\\n\" + find_comments(program_code.sub(/^.*$\\n/i, ''))\n          program_comment = \"\\n\\n= <i>Program</i> <tt>#{program_name}</tt>\\n\\n\" \\\n                            + program_comment\n          @top_level.comment << program_comment\n          parse_program_or_module(@top_level, program_code, :private)\n        end\n\n        # next loop to search next block\n        level_depth = 0\n        block_searching_flag = false\n        block_searching_lines = []\n        pre_comment = []\n        next false\n      }\n\n      remaining_lines.delete_if{ |line|\n        line == false\n      }\n\n      # External subprograms and functions are parsed\n      #\n      parse_program_or_module(@top_level, remaining_lines.join(\"\\n\"),\n                              :public, true)\n\n      @top_level\n    end  # End of scan\n\n    private\n\n    def parse_program_or_module(container, code,\n                                visibility=:public, external=nil)\n      return unless container\n      return unless code\n      remaining_lines = code.split(\"\\n\")\n      remaining_code = \"#{code}\"\n\n      #\n      # Parse variables before \"contains\" in module\n      #\n      level_depth = 0\n      before_contains_lines = []\n      before_contains_code = nil\n      before_contains_flag = nil\n      remaining_lines.each{ |line|\n        if !before_contains_flag\n          if line =~ /^\\s*?module\\s+\\w+\\s*?(!.*?)?$/i\n            before_contains_flag = true\n          end\n        else\n          break if line =~ /^\\s*?contains\\s*?(!.*?)?$/i\n          level_depth += 1 if block_start?(line)\n          level_depth -= 1 if block_end?(line)\n          break if level_depth < 0\n          before_contains_lines << line\n        end\n      }\n      before_contains_code = before_contains_lines.join(\"\\n\")\n      if before_contains_code\n        before_contains_code.gsub!(/^\\s*?interface\\s+.*?\\s+end\\s+interface.*?$/im, \"\")\n        before_contains_code.gsub!(/^\\s*?type[\\s\\,]+.*?\\s+end\\s+type.*?$/im, \"\")\n      end\n\n      #\n      # Parse global \"use\"\n      #\n      use_check_code = \"#{before_contains_code}\"\n      cascaded_modules_list = []\n      while use_check_code =~ /^\\s*?use\\s+(\\w+)(.*?)(!.*?)?$/i\n        use_check_code = $~.pre_match\n        use_check_code << $~.post_match\n        used_mod_name = $1.strip.chomp\n        used_list = $2 || \"\"\n        used_trailing = $3 || \"\"\n        next if used_trailing =~ /!:nodoc:/\n        if !container.include_includes?(used_mod_name, @options.ignore_case)\n          progress \".\"\n          container.add_include Include.new(used_mod_name, \"\")\n        end\n        if ! (used_list =~ /\\,\\s*?only\\s*?:/i )\n          cascaded_modules_list << \"\\#\" + used_mod_name\n        end\n      end\n\n      #\n      # Parse public and private, and store information.\n      # This information is used when \"add_method\" and\n      # \"set_visibility_for\" are called.\n      #\n      visibility_default, visibility_info = \n                parse_visibility(remaining_lines.join(\"\\n\"), visibility, container)\n      @@public_methods.concat visibility_info\n      if visibility_default == :public\n        if !cascaded_modules_list.empty?\n          cascaded_modules = \n            Attr.new(\"Cascaded Modules\",\n                     \"Imported modules all of whose components are published again\",\n                     \"\",\n                     cascaded_modules_list.join(\", \"))\n          container.add_attribute(cascaded_modules)\n        end\n      end\n\n      #\n      # Check rename elements\n      #\n      use_check_code = \"#{before_contains_code}\"\n      while use_check_code =~ /^\\s*?use\\s+(\\w+)\\s*?\\,(.+)$/i\n        use_check_code = $~.pre_match\n        use_check_code << $~.post_match\n        used_mod_name = $1.strip.chomp\n        used_elements = $2.sub(/\\s*?only\\s*?:\\s*?/i, '')\n        used_elements.split(\",\").each{ |used|\n          if /\\s*?(\\w+)\\s*?=>\\s*?(\\w+)\\s*?/ =~ used\n            local = $1\n            org = $2\n            @@public_methods.collect!{ |pub_meth|\n              if local == pub_meth[\"name\"] ||\n                  local.upcase == pub_meth[\"name\"].upcase &&\n                  @options.ignore_case\n                pub_meth[\"name\"] = org\n                pub_meth[\"local_name\"] = local\n              end\n              pub_meth\n            }\n          end\n        }\n      end\n\n      #\n      # Parse private \"use\"\n      #\n      use_check_code = remaining_lines.join(\"\\n\")\n      while use_check_code =~ /^\\s*?use\\s+(\\w+)(.*?)(!.*?)?$/i\n        use_check_code = $~.pre_match\n        use_check_code << $~.post_match\n        used_mod_name = $1.strip.chomp\n        used_trailing = $3 || \"\"\n        next if used_trailing =~ /!:nodoc:/\n        if !container.include_includes?(used_mod_name, @options.ignore_case)\n          progress \".\"\n          container.add_include Include.new(used_mod_name, \"\")\n        end\n      end\n\n      container.each_includes{ |inc|\n        TopLevel.all_files.each do |name, toplevel|\n          indicated_mod = toplevel.find_symbol(inc.name,\n                                               nil, @options.ignore_case)\n          if indicated_mod\n            indicated_name = indicated_mod.parent.file_relative_name\n            if !container.include_requires?(indicated_name, @options.ignore_case)\n              container.add_require(Require.new(indicated_name, \"\"))\n            end\n            break\n          end\n        end\n      }\n\n      #\n      # Parse derived-types definitions\n      #\n      derived_types_comment = \"\"\n      remaining_code = remaining_lines.join(\"\\n\")\n      while remaining_code =~ /^\\s*?\n                                    type[\\s\\,]+(public|private)?\\s*?(::)?\\s*?\n                                    (\\w+)\\s*?(!.*?)?$\n                                    (.*?)\n                                    ^\\s*?end\\s+type.*?$\n                              /imx\n        remaining_code = $~.pre_match\n        remaining_code << $~.post_match\n        typename = $3.chomp.strip\n        type_elements = $5 || \"\"\n        type_code = remove_empty_head_lines($&)\n        type_trailing = find_comments($4)\n        next if type_trailing =~ /^:nodoc:/\n        type_visibility = $1\n        type_comment = COMMENTS_ARE_UPPER ? \n          find_comments($~.pre_match) + \"\\n\" + type_trailing :\n            type_trailing + \"\\n\" + find_comments(type_code.sub(/^.*$\\n/i, ''))\n        type_element_visibility_public = true\n        type_code.split(\"\\n\").each{ |line|\n          if /^\\s*?private\\s*?$/ =~ line\n            type_element_visibility_public = nil\n            break\n          end\n        } if type_code\n\n        args_comment = \"\"\n        type_args_info = nil\n\n        if @options.show_all\n          args_comment = find_arguments(nil, type_code, true)\n        else\n          type_public_args_list = []\n          type_args_info = definition_info(type_code)\n          type_args_info.each{ |arg|\n            arg_is_public = type_element_visibility_public\n            arg_is_public = true if arg.include_attr?(\"public\")\n            arg_is_public = nil if arg.include_attr?(\"private\")\n            type_public_args_list << arg.varname if arg_is_public\n          }\n          args_comment = find_arguments(type_public_args_list, type_code)\n        end\n\n        type = AnyMethod.new(\"type #{typename}\", typename)\n        type.singleton = false\n        type.params = \"\"\n        type.comment = \"<b><em> Derived Type </em></b> :: <tt></tt>\\n\"\n        type.comment << args_comment if args_comment\n        type.comment << type_comment if type_comment\n        progress \"t\"\n        @stats.num_methods += 1\n        container.add_method type\n\n        set_visibility(container, typename, visibility_default, @@public_methods)\n\n        if type_visibility\n          type_visibility.gsub!(/\\s/,'')\n          type_visibility.gsub!(/\\,/,'')\n          type_visibility.gsub!(/:/,'')\n          type_visibility.downcase!\n          if type_visibility == \"public\"\n            container.set_visibility_for([typename], :public)\n          elsif type_visibility == \"private\"\n            container.set_visibility_for([typename], :private)\n          end\n        end\n\n        check_public_methods(type, container.name)\n\n        if @options.show_all\n          derived_types_comment << \", \" unless derived_types_comment.empty?\n          derived_types_comment << typename\n        else\n          if type.visibility == :public\n          derived_types_comment << \", \" unless derived_types_comment.empty?\n          derived_types_comment << typename\n          end\n        end\n\n      end\n\n      if !derived_types_comment.empty?\n        derived_types_table = \n          Attr.new(\"Derived Types\", \"Derived_Types\", \"\", \n                   derived_types_comment)\n        container.add_attribute(derived_types_table)\n      end\n\n      #\n      # move interface scope\n      #\n      interface_code = \"\"\n      while remaining_code =~ /^\\s*?\n                                   interface(\n                                              \\s+\\w+                      |\n                                              \\s+operator\\s*?\\(.*?\\)       |\n                                              \\s+assignment\\s*?\\(\\s*?=\\s*?\\)\n                                            )?\\s*?$\n                                   (.*?)\n                                   ^\\s*?end\\s+interface.*?$\n                              /imx\n        interface_code << remove_empty_head_lines($&) + \"\\n\"\n        remaining_code = $~.pre_match\n        remaining_code << $~.post_match\n      end\n\n      #\n      # Parse global constants or variables in modules\n      #\n      const_var_defs = definition_info(before_contains_code)\n      const_var_defs.each{|defitem|\n        next if defitem.nodoc\n        const_or_var_type = \"Variable\"\n        const_or_var_progress = \"v\"\n        if defitem.include_attr?(\"parameter\")\n          const_or_var_type = \"Constant\"\n          const_or_var_progress = \"c\"\n        end\n        const_or_var = AnyMethod.new(const_or_var_type, defitem.varname)\n        const_or_var.singleton = false\n        const_or_var.params = \"\"\n        self_comment = find_arguments([defitem.varname], before_contains_code)\n        const_or_var.comment = \"<b><em>\" + const_or_var_type + \"</em></b> :: <tt></tt>\\n\"\n        const_or_var.comment << self_comment if self_comment\n        progress const_or_var_progress\n        @stats.num_methods += 1\n        container.add_method const_or_var\n\n        set_visibility(container, defitem.varname, visibility_default, @@public_methods)\n\n        if defitem.include_attr?(\"public\")\n          container.set_visibility_for([defitem.varname], :public)\n        elsif defitem.include_attr?(\"private\")\n          container.set_visibility_for([defitem.varname], :private)\n        end\n\n        check_public_methods(const_or_var, container.name)\n\n      } if const_var_defs\n\n      remaining_lines = remaining_code.split(\"\\n\")\n\n      # \"subroutine\" or \"function\" parts are parsed (new)\n      #\n      level_depth = 0\n      block_searching_flag = nil\n      block_searching_lines = []\n      pre_comment = []\n      procedure_trailing = \"\"\n      procedure_name = \"\"\n      procedure_params = \"\"\n      procedure_prefix = \"\"\n      procedure_result_arg = \"\"\n      procedure_type = \"\"\n      contains_lines = []\n      contains_flag = nil\n      remaining_lines.collect!{|line|\n        if !block_searching_flag\n          # subroutine\n          if line =~ /^\\s*?\n                           (recursive|pure|elemental)?\\s*?\n                           subroutine\\s+(\\w+)\\s*?(\\(.*?\\))?\\s*?(!.*?)?$\n                     /ix\n            block_searching_flag = :subroutine\n            block_searching_lines << line\n\n            procedure_name = $2.chomp.strip\n            procedure_params = $3 || \"\"\n            procedure_prefix = $1 || \"\"\n            procedure_trailing = $4 || \"!\"\n            next false\n\n          # function\n          elsif line =~ /^\\s*?\n                         (recursive|pure|elemental)?\\s*?\n                         (\n                             character\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | type\\s*?\\([\\w\\s]+?\\)\\s+\n                           | integer\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | real\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | double\\s+precision\\s+\n                           | logical\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | complex\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                         )?\n                         function\\s+(\\w+)\\s*?\n                         (\\(.*?\\))?(\\s+result\\((.*?)\\))?\\s*?(!.*?)?$\n                        /ix\n            block_searching_flag = :function\n            block_searching_lines << line\n\n            procedure_prefix = $1 || \"\"\n            procedure_type = $2 ? $2.chomp.strip : nil\n            procedure_name = $8.chomp.strip\n            procedure_params = $9 || \"\"\n            procedure_result_arg = $11 ? $11.chomp.strip : procedure_name\n            procedure_trailing = $12 || \"!\"\n            next false\n          elsif line =~ /^\\s*?!\\s?(.*)/\n            pre_comment << line\n            next line\n          else\n            pre_comment = []\n            next line\n          end\n        end\n        contains_flag = true if line =~ /^\\s*?contains\\s*?(!.*?)?$/\n        block_searching_lines << line\n        contains_lines << line if contains_flag\n\n        level_depth += 1 if block_start?(line)\n        level_depth -= 1 if block_end?(line)\n        if level_depth >= 0\n          next false\n        end\n\n        # \"procedure_code\" is formatted.\n        # \":nodoc:\" flag is checked.\n        #\n        procedure_code = block_searching_lines.join(\"\\n\")\n        procedure_code = remove_empty_head_lines(procedure_code)\n        if procedure_trailing =~ /^!:nodoc:/\n          # next loop to search next block\n          level_depth = 0\n          block_searching_flag = nil\n          block_searching_lines = []\n          pre_comment = []\n          procedure_trailing = \"\"\n          procedure_name = \"\"\n          procedure_params = \"\"\n          procedure_prefix = \"\"\n          procedure_result_arg = \"\"\n          procedure_type = \"\"\n          contains_lines = []\n          contains_flag = nil\n          next false\n        end\n\n        # AnyMethod is created, and added to container\n        #\n        subroutine_function = nil\n        if block_searching_flag == :subroutine\n          subroutine_prefix   = procedure_prefix\n          subroutine_name     = procedure_name\n          subroutine_params   = procedure_params\n          subroutine_trailing = procedure_trailing\n          subroutine_code     = procedure_code\n\n          subroutine_comment = COMMENTS_ARE_UPPER ? \n            pre_comment.join(\"\\n\") + \"\\n\" + subroutine_trailing : \n              subroutine_trailing + \"\\n\" + subroutine_code.sub(/^.*$\\n/i, '')\n          subroutine = AnyMethod.new(\"subroutine\", subroutine_name)\n          parse_subprogram(subroutine, subroutine_params,\n                           subroutine_comment, subroutine_code,\n                           before_contains_code, nil, subroutine_prefix)\n          progress \"s\"\n          @stats.num_methods += 1\n          container.add_method subroutine\n          subroutine_function = subroutine\n\n        elsif block_searching_flag == :function\n          function_prefix     = procedure_prefix\n          function_type       = procedure_type\n          function_name       = procedure_name\n          function_params_org = procedure_params\n          function_result_arg = procedure_result_arg\n          function_trailing   = procedure_trailing\n          function_code_org   = procedure_code\n\n          function_comment = COMMENTS_ARE_UPPER ?\n            pre_comment.join(\"\\n\") + \"\\n\" + function_trailing :\n              function_trailing + \"\\n \" + function_code_org.sub(/^.*$\\n/i, '')\n\n          function_code = \"#{function_code_org}\"\n          if function_type\n            function_code << \"\\n\" + function_type + \" :: \" + function_result_arg\n          end\n\n          function_params =\n            function_params_org.sub(/^\\(/, \"\\(#{function_result_arg}, \")\n\n          function = AnyMethod.new(\"function\", function_name)\n          parse_subprogram(function, function_params,\n                           function_comment, function_code,\n                           before_contains_code, true, function_prefix)\n\n          # Specific modification due to function\n          function.params.sub!(/\\(\\s*?#{function_result_arg}\\s*?,\\s*?/, \"\\( \")\n          function.params << \" result(\" + function_result_arg + \")\"\n          function.start_collecting_tokens\n          function.add_token Token.new(1,1).set_text(function_code_org)\n\n          progress \"f\"\n          @stats.num_methods += 1\n          container.add_method function\n          subroutine_function = function\n\n        end\n\n        # The visibility of procedure is specified\n        #\n        set_visibility(container, procedure_name, \n                       visibility_default, @@public_methods)\n\n        # The alias for this procedure from external modules\n        #\n        check_external_aliases(procedure_name,\n                               subroutine_function.params,\n                               subroutine_function.comment, subroutine_function) if external\n        check_public_methods(subroutine_function, container.name)\n\n\n        # contains_lines are parsed as private procedures\n        if contains_flag\n          parse_program_or_module(container,\n                                  contains_lines.join(\"\\n\"), :private)\n        end\n\n        # next loop to search next block\n        level_depth = 0\n        block_searching_flag = nil\n        block_searching_lines = []\n        pre_comment = []\n        procedure_trailing = \"\"\n        procedure_name = \"\"\n        procedure_params = \"\"\n        procedure_prefix = \"\"\n        procedure_result_arg = \"\"\n        contains_lines = []\n        contains_flag = nil\n        next false\n      } # End of remaining_lines.collect!{|line|\n\n      # Array remains_lines is converted to String remains_code again\n      #\n      remaining_code = remaining_lines.join(\"\\n\")\n\n      #\n      # Parse interface\n      #\n      interface_scope = false\n      generic_name = \"\"\n      interface_code.split(\"\\n\").each{ |line|\n        if /^\\s*?\n                 interface(\n                            \\s+\\w+|\n                            \\s+operator\\s*?\\(.*?\\)|\n                            \\s+assignment\\s*?\\(\\s*?=\\s*?\\)\n                          )?\n                 \\s*?(!.*?)?$\n           /ix =~ line\n          generic_name = $1 ? $1.strip.chomp : nil\n          interface_trailing = $2 || \"!\"\n          interface_scope = true\n          interface_scope = false if interface_trailing =~ /!:nodoc:/\n#          if generic_name =~ /operator\\s*?\\((.*?)\\)/i\n#            operator_name = $1\n#            if operator_name && !operator_name.empty?\n#              generic_name = \"#{operator_name}\"\n#            end\n#          end\n#          if generic_name =~ /assignment\\s*?\\((.*?)\\)/i\n#            assignment_name = $1\n#            if assignment_name && !assignment_name.empty?\n#              generic_name = \"#{assignment_name}\"\n#            end\n#          end\n        end\n        if /^\\s*?end\\s+interface/i =~ line\n          interface_scope = false\n          generic_name = nil\n        end\n        # internal alias\n        if interface_scope && /^\\s*?module\\s+procedure\\s+(.*?)(!.*?)?$/i =~ line\n          procedures = $1.strip.chomp\n          procedures_trailing = $2 || \"!\"\n          next if procedures_trailing =~ /!:nodoc:/\n          procedures.split(\",\").each{ |proc|\n            proc.strip!\n            proc.chomp!\n            next if generic_name == proc || !generic_name\n            old_meth = container.find_symbol(proc, nil, @options.ignore_case)\n            next if !old_meth\n            nolink = old_meth.visibility == :private ? true : nil\n            nolink = nil if @options.show_all\n            new_meth = \n               initialize_external_method(generic_name, proc, \n                                          old_meth.params, nil, \n                                          old_meth.comment, \n                                          old_meth.clone.token_stream[0].text, \n                                          true, nolink)\n            new_meth.singleton = old_meth.singleton\n\n            progress \"i\"\n            @stats.num_methods += 1\n            container.add_method new_meth\n\n            set_visibility(container, generic_name, visibility_default, @@public_methods)\n\n            check_public_methods(new_meth, container.name)\n\n          }\n        end\n\n        # external aliases\n        if interface_scope\n          # subroutine\n          proc = nil\n          params = nil\n          procedures_trailing = nil\n          if line =~ /^\\s*?\n                           (recursive|pure|elemental)?\\s*?\n                           subroutine\\s+(\\w+)\\s*?(\\(.*?\\))?\\s*?(!.*?)?$\n                     /ix\n            proc = $2.chomp.strip\n            generic_name = proc unless generic_name\n            params = $3 || \"\"\n            procedures_trailing = $4 || \"!\"\n\n          # function\n          elsif line =~ /^\\s*?\n                         (recursive|pure|elemental)?\\s*?\n                         (\n                             character\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | type\\s*?\\([\\w\\s]+?\\)\\s+\n                           | integer\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | real\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | double\\s+precision\\s+\n                           | logical\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                           | complex\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                         )?\n                         function\\s+(\\w+)\\s*?\n                         (\\(.*?\\))?(\\s+result\\((.*?)\\))?\\s*?(!.*?)?$\n                        /ix\n            proc = $8.chomp.strip\n            generic_name = proc unless generic_name\n            params = $9 || \"\"\n            procedures_trailing = $12 || \"!\"\n          else\n            next\n          end\n          next if procedures_trailing =~ /!:nodoc:/\n          indicated_method = nil\n          indicated_file   = nil\n          TopLevel.all_files.each do |name, toplevel|\n            indicated_method = toplevel.find_local_symbol(proc, @options.ignore_case)\n            indicated_file = name\n            break if indicated_method\n          end\n\n          if indicated_method\n            external_method = \n              initialize_external_method(generic_name, proc, \n                                         indicated_method.params, \n                                         indicated_file, \n                                         indicated_method.comment)\n\n            progress \"e\"\n            @stats.num_methods += 1\n            container.add_method external_method\n            set_visibility(container, generic_name, visibility_default, @@public_methods)\n            if !container.include_requires?(indicated_file, @options.ignore_case)\n              container.add_require(Require.new(indicated_file, \"\"))\n            end\n            check_public_methods(external_method, container.name)\n\n          else\n            @@external_aliases << {\n              \"new_name\"  => generic_name,\n              \"old_name\"  => proc,\n              \"file_or_module\" => container,\n              \"visibility\" => find_visibility(container, generic_name, @@public_methods) || visibility_default\n            }\n          end\n        end\n\n      } if interface_code # End of interface_code.split(\"\\n\").each ...\n\n      #\n      # Already imported methods are removed from @@public_methods.\n      # Remainders are assumed to be imported from other modules.\n      #\n      @@public_methods.delete_if{ |method| method[\"entity_is_discovered\"]}\n\n      @@public_methods.each{ |pub_meth|\n        next unless pub_meth[\"file_or_module\"].name == container.name\n        pub_meth[\"used_modules\"].each{ |used_mod|\n          TopLevel.all_classes_and_modules.each{ |modules|\n            if modules.name == used_mod ||\n                modules.name.upcase == used_mod.upcase &&\n                @options.ignore_case\n              modules.method_list.each{ |meth|\n                if meth.name == pub_meth[\"name\"] ||\n                    meth.name.upcase == pub_meth[\"name\"].upcase &&\n                    @options.ignore_case\n                  new_meth = initialize_public_method(meth,\n                                                      modules.name)\n                  if pub_meth[\"local_name\"]\n                    new_meth.name = pub_meth[\"local_name\"]\n                  end\n                  progress \"e\"\n                  @stats.num_methods += 1\n                  container.add_method new_meth\n                end\n              }\n            end\n          }\n        }\n      }\n\n      container\n    end  # End of parse_program_or_module\n\n    #\n    # Parse arguments, comment, code of subroutine and function.\n    # Return AnyMethod object.\n    #\n    def parse_subprogram(subprogram, params, comment, code, \n                         before_contains=nil, function=nil, prefix=nil)\n      subprogram.singleton = false\n      prefix = \"\" if !prefix\n      arguments = params.sub(/\\(/, \"\").sub(/\\)/, \"\").split(\",\") if params\n      args_comment, params_opt = \n        find_arguments(arguments, code.sub(/^s*?contains\\s*?(!.*?)?$.*/im, \"\"),\n                       nil, nil, true)\n      params_opt = \"( \" + params_opt + \" ) \" if params_opt\n      subprogram.params = params_opt || \"\"\n      namelist_comment = find_namelists(code, before_contains)\n\n      block_comment = find_comments comment\n      if function\n        subprogram.comment = \"<b><em> Function </em></b> :: <em>#{prefix}</em>\\n\"\n      else\n        subprogram.comment = \"<b><em> Subroutine </em></b> :: <em>#{prefix}</em>\\n\"\n      end\n      subprogram.comment << args_comment if args_comment\n      subprogram.comment << block_comment if block_comment\n      subprogram.comment << namelist_comment if namelist_comment\n\n      # For output source code\n      subprogram.start_collecting_tokens\n      subprogram.add_token Token.new(1,1).set_text(code)\n\n      subprogram\n    end\n\n    #\n    # Collect comment for file entity\n    #\n    def collect_first_comment(body)\n      comment = \"\"\n      not_comment = \"\"\n      comment_start = false\n      comment_end   = false\n      body.split(\"\\n\").each{ |line|\n        if comment_end\n          not_comment << line\n          not_comment << \"\\n\"\n        elsif /^\\s*?!\\s?(.*)$/i =~ line\n          comment_start = true\n          comment << $1\n          comment << \"\\n\"\n        elsif /^\\s*?$/i =~ line\n          comment_end = true if comment_start && COMMENTS_ARE_UPPER\n        else\n          comment_end = true\n          not_comment << line\n          not_comment << \"\\n\"\n        end\n      }\n      return comment, not_comment\n    end\n\n\n    # Return comments of definitions of arguments\n    #\n    # If \"all\" argument is true, information of all arguments are returned.\n    # If \"modified_params\" is true, list of arguments are decorated,\n    # for example, optional arguments are parenthetic as \"[arg]\".\n    #\n    def find_arguments(args, text, all=nil, indent=nil, modified_params=nil)\n      return unless args || all\n      indent = \"\" unless indent\n      args = [\"all\"] if all\n      params = \"\" if modified_params\n      comma = \"\"\n      return unless text\n      args_rdocforms = \"\\n\"\n      remaining_lines = \"#{text}\"\n      definitions = definition_info(remaining_lines)\n      args.each{ |arg|\n        arg.strip!\n        arg.chomp!\n        definitions.each { |defitem|\n          if arg == defitem.varname.strip.chomp || all\n            args_rdocforms << <<-\"EOF\"\n\n#{indent}<tt><b>#{defitem.varname.chomp.strip}#{defitem.arraysuffix}</b> #{defitem.inivalue}</tt> :: \n#{indent}   <tt>#{defitem.types.chomp.strip}</tt>\nEOF\n            if !defitem.comment.chomp.strip.empty?\n              comment = \"\"\n              defitem.comment.split(\"\\n\").each{ |line|\n                comment << \"       \" + line + \"\\n\"\n              }\n              args_rdocforms << <<-\"EOF\"\n\n#{indent}   <tt></tt> :: \n#{indent}       <tt></tt>\n#{indent}       #{comment.chomp.strip}\nEOF\n            end\n\n            if modified_params\n              if defitem.include_attr?(\"optional\")\n                params << \"#{comma}[#{arg}]\"\n              else\n                params << \"#{comma}#{arg}\"\n              end\n              comma = \", \"\n            end\n          end\n        }\n      }\n      if modified_params\n        return args_rdocforms, params\n      else\n        return args_rdocforms\n      end\n    end\n\n    # Return comments of definitions of namelists\n    #\n    def find_namelists(text, before_contains=nil)\n      return nil if !text\n      result = \"\"\n      lines = \"#{text}\"\n      before_contains = \"\" if !before_contains\n      while lines =~ /^\\s*?namelist\\s+\\/\\s*?(\\w+)\\s*?\\/([\\s\\w\\,]+)$/i\n        lines = $~.post_match\n        nml_comment = COMMENTS_ARE_UPPER ? \n            find_comments($~.pre_match) : find_comments($~.post_match)\n        nml_name = $1\n        nml_args = $2.split(\",\")\n        result << \"\\n\\n=== NAMELIST <tt><b>\" + nml_name + \"</tt></b>\\n\\n\"\n        result << nml_comment + \"\\n\" if nml_comment\n        if lines.split(\"\\n\")[0] =~ /^\\//i\n          lines = \"namelist \" + lines\n        end\n        result << find_arguments(nml_args, \"#{text}\" + \"\\n\" + before_contains)\n      end\n      return result\n    end\n\n    #\n    # Comments just after module or subprogram, or arguments are\n    # returned. If \"COMMENTS_ARE_UPPER\" is true, comments just before\n    # modules or subprograms are returned\n    #\n    def find_comments text\n      return \"\" unless text\n      lines = text.split(\"\\n\")\n      lines.reverse! if COMMENTS_ARE_UPPER\n      comment_block = Array.new\n      lines.each do |line|\n        break if line =~ /^\\s*?\\w/ || line =~ /^\\s*?$/\n        if COMMENTS_ARE_UPPER\n          comment_block.unshift line.sub(/^\\s*?!\\s?/,\"\")\n        else\n          comment_block.push line.sub(/^\\s*?!\\s?/,\"\")\n        end\n      end\n      nice_lines = comment_block.join(\"\\n\").split \"\\n\\s*?\\n\"\n      nice_lines[0] ||= \"\"\n      nice_lines.shift\n    end\n\n    def progress(char)\n      unless @options.quiet\n        @progress.print(char)\n        @progress.flush\n      end\n    end\n\n    #\n    # Create method for internal alias\n    #\n    def initialize_public_method(method, parent)\n      return if !method || !parent\n\n      new_meth = AnyMethod.new(\"External Alias for module\", method.name)\n      new_meth.singleton    = method.singleton\n      new_meth.params       = method.params.clone\n      new_meth.comment      = remove_trailing_alias(method.comment.clone)\n      new_meth.comment      << \"\\n\\n#{EXTERNAL_ALIAS_MES} #{parent.strip.chomp}\\##{method.name}\"\n\n      return new_meth\n    end\n\n    #\n    # Create method for external alias\n    #\n    # If argument \"internal\" is true, file is ignored.\n    #\n    def initialize_external_method(new, old, params, file, comment, token=nil,\n                                   internal=nil, nolink=nil)\n      return nil unless new || old\n\n      if internal\n        external_alias_header = \"#{INTERNAL_ALIAS_MES} \"\n        external_alias_text   = external_alias_header + old \n      elsif file\n        external_alias_header = \"#{EXTERNAL_ALIAS_MES} \"\n        external_alias_text   = external_alias_header + file + \"#\" + old\n      else\n        return nil\n      end\n      external_meth = AnyMethod.new(external_alias_text, new)\n      external_meth.singleton    = false\n      external_meth.params       = params\n      external_comment = remove_trailing_alias(comment) + \"\\n\\n\" if comment\n      external_meth.comment = external_comment || \"\"\n      if nolink && token\n        external_meth.start_collecting_tokens\n        external_meth.add_token Token.new(1,1).set_text(token)\n      else\n        external_meth.comment << external_alias_text\n      end\n\n      return external_meth\n    end\n\n\n\n    #\n    # Parse visibility\n    #\n    def parse_visibility(code, default, container)\n      result = []\n      visibility_default = default || :public\n\n      used_modules = []\n      container.includes.each{|i| used_modules << i.name} if container\n\n      remaining_code = code.gsub(/^\\s*?type[\\s\\,]+.*?\\s+end\\s+type.*?$/im, \"\")\n      remaining_code.split(\"\\n\").each{ |line|\n        if /^\\s*?private\\s*?$/ =~ line\n          visibility_default = :private\n          break\n        end\n      } if remaining_code\n\n      remaining_code.split(\"\\n\").each{ |line|\n        if /^\\s*?private\\s*?(::)?\\s+(.*)\\s*?(!.*?)?/i =~ line\n          methods = $2.sub(/!.*$/, '')\n          methods.split(\",\").each{ |meth|\n            meth.sub!(/!.*$/, '')\n            meth.gsub!(/:/, '')\n            result << {\n              \"name\" => meth.chomp.strip,\n              \"visibility\" => :private,\n              \"used_modules\" => used_modules.clone,\n              \"file_or_module\" => container,\n              \"entity_is_discovered\" => nil,\n              \"local_name\" => nil\n            }\n          }\n        elsif /^\\s*?public\\s*?(::)?\\s+(.*)\\s*?(!.*?)?/i =~ line\n          methods = $2.sub(/!.*$/, '')\n          methods.split(\",\").each{ |meth|\n            meth.sub!(/!.*$/, '')\n            meth.gsub!(/:/, '')\n            result << {\n              \"name\" => meth.chomp.strip,\n              \"visibility\" => :public,\n              \"used_modules\" => used_modules.clone,\n              \"file_or_module\" => container,\n              \"entity_is_discovered\" => nil,\n              \"local_name\" => nil\n            }\n          }\n        end\n      } if remaining_code\n\n      if container\n        result.each{ |vis_info|\n          vis_info[\"parent\"] = container.name\n        }\n      end\n\n      return visibility_default, result\n    end\n\n    #\n    # Set visibility\n    #\n    # \"subname\" element of \"visibility_info\" is deleted.\n    #\n    def set_visibility(container, subname, visibility_default, visibility_info)\n      return unless container || subname || visibility_default || visibility_info\n      not_found = true\n      visibility_info.collect!{ |info|\n        if info[\"name\"] == subname ||\n            @options.ignore_case && info[\"name\"].upcase == subname.upcase\n          if info[\"file_or_module\"].name == container.name\n            container.set_visibility_for([subname], info[\"visibility\"])\n            info[\"entity_is_discovered\"] = true\n            not_found = false\n          end\n        end\n        info\n      }\n      if not_found\n        return container.set_visibility_for([subname], visibility_default)\n      else\n        return container\n      end\n    end\n\n    #\n    # Find visibility\n    #\n    def find_visibility(container, subname, visibility_info)\n      return nil if !subname || !visibility_info\n      visibility_info.each{ |info|\n        if info[\"name\"] == subname ||\n            @options.ignore_case && info[\"name\"].upcase == subname.upcase\n          if info[\"parent\"] == container.name\n            return info[\"visibility\"]\n          end\n        end\n      }\n      return nil\n    end\n\n    #\n    # Check external aliases\n    #\n    def check_external_aliases(subname, params, comment, test=nil)\n      @@external_aliases.each{ |alias_item|\n        if subname == alias_item[\"old_name\"] ||\n                    subname.upcase == alias_item[\"old_name\"].upcase &&\n                            @options.ignore_case\n\n          new_meth = initialize_external_method(alias_item[\"new_name\"], \n                                                subname, params, @file_name, \n                                                comment)\n          new_meth.visibility = alias_item[\"visibility\"]\n\n          progress \"e\"\n          @stats.num_methods += 1\n          alias_item[\"file_or_module\"].add_method(new_meth)\n\n          if !alias_item[\"file_or_module\"].include_requires?(@file_name, @options.ignore_case)\n            alias_item[\"file_or_module\"].add_require(Require.new(@file_name, \"\"))\n          end\n        end\n      }\n    end\n\n    #\n    # Check public_methods\n    #\n    def check_public_methods(method, parent)\n      return if !method || !parent\n      @@public_methods.each{ |alias_item|\n        parent_is_used_module = nil\n        alias_item[\"used_modules\"].each{ |used_module|\n          if used_module == parent ||\n              used_module.upcase == parent.upcase &&\n              @options.ignore_case\n            parent_is_used_module = true\n          end\n        }\n        next if !parent_is_used_module\n\n        if method.name == alias_item[\"name\"] ||\n            method.name.upcase == alias_item[\"name\"].upcase &&\n            @options.ignore_case\n\n          new_meth = initialize_public_method(method, parent)\n          if alias_item[\"local_name\"]\n            new_meth.name = alias_item[\"local_name\"]\n          end\n\n          progress \"e\"\n          @stats.num_methods += 1\n          alias_item[\"file_or_module\"].add_method new_meth\n        end\n      }\n    end\n\n    #\n    # Continuous lines are united.\n    #\n    # Comments in continuous lines are removed.\n    #\n    def united_to_one_line(f90src)\n      return \"\" unless f90src\n      lines = f90src.split(\"\\n\")\n      previous_continuing = false\n      now_continuing = false\n      body = \"\"\n      lines.each{ |line|\n        words = line.split(\"\")\n        next if words.empty? && previous_continuing\n        commentout = false\n        brank_flag = true ; brank_char = \"\"\n        squote = false    ; dquote = false\n        ignore = false\n        words.collect! { |char|\n          if previous_continuing && brank_flag\n            now_continuing = true\n            ignore         = true\n            case char\n            when \"!\"                       ; break\n            when \" \" ; brank_char << char  ; next \"\"\n            when \"&\"\n              brank_flag = false\n              now_continuing = false\n              next \"\"\n            else \n              brank_flag     = false\n              now_continuing = false\n              ignore         = false\n              next brank_char + char\n            end\n          end\n          ignore = false\n\n          if now_continuing\n            next \"\"\n          elsif !(squote) && !(dquote) && !(commentout)\n            case char\n            when \"!\" ; commentout = true     ; next char\n            when \"\\\"\"; dquote = true         ; next char\n            when \"\\'\"; squote = true         ; next char\n            when \"&\" ; now_continuing = true ; next \"\"\n            else next char\n            end\n          elsif commentout\n            next char\n          elsif squote\n            case char\n            when \"\\'\"; squote = false ; next char\n            else next char\n            end\n          elsif dquote\n            case char\n            when \"\\\"\"; dquote = false ; next char\n            else next char\n            end\n          end\n        }\n        if !ignore && !previous_continuing || !brank_flag\n          if previous_continuing\n            body << words.join(\"\")\n          else\n            body << \"\\n\" + words.join(\"\")\n          end\n        end\n        previous_continuing = now_continuing ? true : nil\n        now_continuing = nil\n      }\n      return body\n    end\n\n\n    #\n    # Continuous line checker\n    #\n    def continuous_line?(line)\n      continuous = false\n      if /&\\s*?(!.*)?$/ =~ line\n        continuous = true\n        if comment_out?($~.pre_match)\n          continuous = false\n        end\n      end\n      return continuous\n    end\n\n    #\n    # Comment out checker\n    #\n    def comment_out?(line)\n      return nil unless line\n      commentout = false\n      squote = false ; dquote = false\n      line.split(\"\").each { |char|\n        if !(squote) && !(dquote)\n          case char\n          when \"!\" ; commentout = true ; break\n          when \"\\\"\"; dquote = true\n          when \"\\'\"; squote = true\n          else next\n          end\n        elsif squote\n          case char\n          when \"\\'\"; squote = false\n          else next\n          end\n        elsif dquote\n          case char\n          when \"\\\"\"; dquote = false\n          else next\n          end\n        end\n      }\n      return commentout\n    end\n\n    #\n    # Semicolons are replaced to line feed.\n    #\n    def semicolon_to_linefeed(text)\n      return \"\" unless text\n      lines = text.split(\"\\n\")\n      lines.collect!{ |line|\n        words = line.split(\"\")\n        commentout = false\n        squote = false ; dquote = false\n        words.collect! { |char|\n          if !(squote) && !(dquote) && !(commentout)\n            case char\n            when \"!\" ; commentout = true ; next char\n            when \"\\\"\"; dquote = true     ; next char\n            when \"\\'\"; squote = true     ; next char\n            when \";\" ;                     \"\\n\"\n            else next char\n            end\n          elsif commentout\n            next char\n          elsif squote\n            case char\n            when \"\\'\"; squote = false ; next char\n            else next char\n            end\n          elsif dquote\n            case char\n            when \"\\\"\"; dquote = false ; next char\n            else next char\n            end\n          end\n        }\n        words.join(\"\")\n      }\n      return lines.join(\"\\n\")\n    end\n\n    #\n    # Which \"line\" is start of block (module, program, block data,\n    # subroutine, function) statement ?\n    #\n    def block_start?(line)\n      return nil if !line\n\n      if line =~ /^\\s*?module\\s+(\\w+)\\s*?(!.*?)?$/i    ||\n          line =~ /^\\s*?program\\s+(\\w+)\\s*?(!.*?)?$/i  ||\n          line =~ /^\\s*?block\\s+data(\\s+\\w+)?\\s*?(!.*?)?$/i     ||\n          line =~ \\\n                  /^\\s*?\n                   (recursive|pure|elemental)?\\s*?\n                   subroutine\\s+(\\w+)\\s*?(\\(.*?\\))?\\s*?(!.*?)?$\n                  /ix ||\n          line =~ \\\n                  /^\\s*?\n                   (recursive|pure|elemental)?\\s*?\n                   (\n                       character\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                     | type\\s*?\\([\\w\\s]+?\\)\\s+\n                     | integer\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                     | real\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                     | double\\s+precision\\s+\n                     | logical\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                     | complex\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?\\s+\n                   )?\n                   function\\s+(\\w+)\\s*?\n                   (\\(.*?\\))?(\\s+result\\((.*?)\\))?\\s*?(!.*?)?$\n                  /ix\n        return true\n      end\n\n      return nil\n    end\n\n    #\n    # Which \"line\" is end of block (module, program, block data,\n    # subroutine, function) statement ?\n    #\n    def block_end?(line)\n      return nil if !line\n\n      if line =~ /^\\s*?end\\s*?(!.*?)?$/i                 ||\n          line =~ /^\\s*?end\\s+module(\\s+\\w+)?\\s*?(!.*?)?$/i       ||\n          line =~ /^\\s*?end\\s+program(\\s+\\w+)?\\s*?(!.*?)?$/i      ||\n          line =~ /^\\s*?end\\s+block\\s+data(\\s+\\w+)?\\s*?(!.*?)?$/i  ||\n          line =~ /^\\s*?end\\s+subroutine(\\s+\\w+)?\\s*?(!.*?)?$/i   ||\n          line =~ /^\\s*?end\\s+function(\\s+\\w+)?\\s*?(!.*?)?$/i\n        return true\n      end\n\n      return nil\n    end\n\n    #\n    # Remove \"Alias for\" in end of comments\n    #\n    def remove_trailing_alias(text)\n      return \"\" if !text\n      lines = text.split(\"\\n\").reverse\n      comment_block = Array.new\n      checked = false\n      lines.each do |line|\n        if !checked \n          if /^\\s?#{INTERNAL_ALIAS_MES}/ =~ line ||\n              /^\\s?#{EXTERNAL_ALIAS_MES}/ =~ line\n            checked = true\n            next\n          end\n        end\n        comment_block.unshift line\n      end\n      nice_lines = comment_block.join(\"\\n\")\n      nice_lines ||= \"\"\n      return nice_lines\n    end\n\n    # Empty lines in header are removed\n    def remove_empty_head_lines(text)\n      return \"\" unless text\n      lines = text.split(\"\\n\")\n      header = true\n      lines.delete_if{ |line|\n        header = false if /\\S/ =~ line\n        header && /^\\s*?$/ =~ line\n      }\n      lines.join(\"\\n\")\n    end\n\n\n    # header marker \"=\", \"==\", ... are removed\n    def remove_header_marker(text)\n      return text.gsub(/^\\s?(=+)/, '<tt></tt>\\1')\n    end\n\n    def remove_private_comments(body)\n      body.gsub!(/^\\s*!--\\s*?$.*?^\\s*!\\+\\+\\s*?$/m, '')\n      return body\n    end\n\n\n    #\n    # Information of arguments of subroutines and functions in Fortran95\n    #\n    class Fortran95Definition\n\n      # Name of variable\n      #\n      attr_reader   :varname\n\n      # Types of variable\n      #\n      attr_reader   :types\n\n      # Initial Value\n      #\n      attr_reader   :inivalue\n\n      # Suffix of array\n      #\n      attr_reader   :arraysuffix\n\n      # Comments\n      #\n      attr_accessor   :comment\n\n      # Flag of non documentation\n      #\n      attr_accessor   :nodoc\n\n      def initialize(varname, types, inivalue, arraysuffix, comment,\n                     nodoc=false)\n        @varname = varname\n        @types = types\n        @inivalue = inivalue\n        @arraysuffix = arraysuffix\n        @comment = comment\n        @nodoc = nodoc\n      end\n\n      def to_s\n        return <<-EOF\n<Fortran95Definition: \n  varname=#{@varname}, types=#{types},\n  inivalue=#{@inivalue}, arraysuffix=#{@arraysuffix}, nodoc=#{@nodoc}, \n  comment=\n#{@comment}\n>\nEOF\n      end\n\n      #\n      # If attr is included, true is returned\n      #\n      def include_attr?(attr)\n        return if !attr\n        @types.split(\",\").each{ |type|\n          return true if type.strip.chomp.upcase == attr.strip.chomp.upcase\n        }\n        return nil\n      end\n\n    end # End of Fortran95Definition\n\n    #\n    # Parse string argument \"text\", and Return Array of\n    # Fortran95Definition object\n    #\n    def definition_info(text)\n      return nil unless text\n      lines = \"#{text}\"\n      defs = Array.new\n      comment = \"\"\n      trailing_comment = \"\"\n      under_comment_valid = false\n      lines.split(\"\\n\").each{ |line|\n        if /^\\s*?!\\s?(.*)/ =~ line\n          if COMMENTS_ARE_UPPER\n            comment << remove_header_marker($1)\n            comment << \"\\n\"\n          elsif defs[-1] && under_comment_valid\n            defs[-1].comment << \"\\n\"\n            defs[-1].comment << remove_header_marker($1)\n          end\n          next\n        elsif /^\\s*?$/ =~ line\n          comment = \"\"\n          under_comment_valid = false\n          next\n        end\n        type = \"\"\n        characters = \"\"\n        if line =~ /^\\s*?\n                    (\n                        character\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?[\\s\\,]*\n                      | type\\s*?\\([\\w\\s]+?\\)[\\s\\,]*\n                      | integer\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?[\\s\\,]*\n                      | real\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?[\\s\\,]*\n                      | double\\s+precision[\\s\\,]*\n                      | logical\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?[\\s\\,]*\n                      | complex\\s*?(\\([\\w\\s\\=\\(\\)\\*]+?\\))?[\\s\\,]*\n                    )\n                    (.*?::)?\n                    (.+)$\n                   /ix\n          characters = $8\n          type = $1\n          type << $7.gsub(/::/, '').gsub(/^\\s*?\\,/, '') if $7\n        else\n          under_comment_valid = false\n          next\n        end\n        squote = false ; dquote = false ; bracket = 0\n        iniflag = false; commentflag = false\n        varname = \"\" ; arraysuffix = \"\" ; inivalue = \"\"\n        start_pos = defs.size\n        characters.split(\"\").each { |char|\n          if !(squote) && !(dquote) && bracket <= 0 && !(iniflag) && !(commentflag)\n            case char\n            when \"!\" ; commentflag = true\n            when \"(\" ; bracket += 1       ; arraysuffix = char\n            when \"\\\"\"; dquote = true\n            when \"\\'\"; squote = true\n            when \"=\" ; iniflag = true     ; inivalue << char\n            when \",\"\n              defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment)\n              varname = \"\" ; arraysuffix = \"\" ; inivalue = \"\"\n              under_comment_valid = true\n            when \" \" ; next\n            else     ; varname << char\n            end\n          elsif commentflag\n            comment << remove_header_marker(char)\n            trailing_comment << remove_header_marker(char)\n          elsif iniflag\n            if dquote\n              case char\n              when \"\\\"\" ; dquote = false ; inivalue << char\n              else      ; inivalue << char\n              end\n            elsif squote\n              case char\n              when \"\\'\" ; squote = false ; inivalue << char\n              else      ; inivalue << char\n              end\n            elsif bracket > 0\n              case char\n              when \"(\" ; bracket += 1 ; inivalue << char\n              when \")\" ; bracket -= 1 ; inivalue << char\n              else     ; inivalue << char\n              end\n            else\n              case char\n              when \",\"\n                defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment)\n                varname = \"\" ; arraysuffix = \"\" ; inivalue = \"\"\n                iniflag = false\n                under_comment_valid = true\n              when \"(\" ; bracket += 1 ; inivalue << char\n              when \"\\\"\"; dquote = true  ; inivalue << char\n              when \"\\'\"; squote = true  ; inivalue << char\n              when \"!\" ; commentflag = true\n              else     ; inivalue << char\n              end\n            end\n          elsif !(squote) && !(dquote) && bracket > 0\n            case char\n            when \"(\" ; bracket += 1 ; arraysuffix << char\n            when \")\" ; bracket -= 1 ; arraysuffix << char\n            else     ; arraysuffix << char\n            end\n          elsif squote\n            case char\n            when \"\\'\"; squote = false ; inivalue << char\n            else     ; inivalue << char\n            end\n          elsif dquote\n            case char\n            when \"\\\"\"; dquote = false ; inivalue << char\n            else     ; inivalue << char\n            end\n          end\n        }\n        defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment)\n        if trailing_comment =~ /^:nodoc:/\n          defs[start_pos..-1].collect!{ |defitem|\n            defitem.nodoc = true\n          }\n        end\n        varname = \"\" ; arraysuffix = \"\" ; inivalue = \"\"\n        comment = \"\"\n        under_comment_valid = true\n        trailing_comment = \"\"\n      }\n      return defs\n    end\n\n\n  end # class Fortran95parser\n\nend # module RDoc\n"
  },
  {
    "path": "lib/rdoc/parsers/parse_rb.rb",
    "content": "#!/usr/local/bin/ruby\n\n# Parse a Ruby source file, building a set of objects\n# representing the modules, classes, methods,\n# requires, and includes we find (these classes\n# are defined in code_objects.rb).\n\n# This file contains stuff stolen outright from:\n#\n#   rtags.rb - \n#   ruby-lex.rb - ruby lexcal analizer\n#   ruby-token.rb - ruby tokens \n#   \tby Keiju ISHITSUKA (Nippon Rational Inc.)\n#\n\nrequire \"e2mmap\"\nrequire \"irb/slex\"\n\nrequire \"rdoc/code_objects\"\nrequire \"rdoc/tokenstream\"\n\nrequire \"rdoc/markup/simple_markup/preprocess\"\n\nrequire \"rdoc/parsers/parserfactory\"\n\n$TOKEN_DEBUG = $DEBUG\n\n# Definitions of all tokens involved in the lexical analysis\n\nmodule RubyToken\n  EXPR_BEG   = :EXPR_BEG\n  EXPR_MID   = :EXPR_MID\n  EXPR_END   = :EXPR_END\n  EXPR_ARG   = :EXPR_ARG\n  EXPR_FNAME = :EXPR_FNAME\n  EXPR_DOT   = :EXPR_DOT\n  EXPR_CLASS = :EXPR_CLASS\n  \n  class Token\n    NO_TEXT = \"??\".freeze\n    attr :text\n\n    def initialize(line_no, char_no)\n      @line_no = line_no\n      @char_no = char_no\n      @text    = NO_TEXT\n    end\n\n    # Because we're used in contexts that expect to return a token,\n    # we set the text string and then return ourselves\n    def set_text(text)\n      @text = text\n      self\n    end\n\n    attr_reader :line_no, :char_no, :text\n  end\n\n  class TkNode < Token\n    attr :node\n  end\n\n  class TkId < Token\n    def initialize(line_no, char_no, name)\n      super(line_no, char_no)\n      @name = name\n    end\n    attr :name\n  end\n\n  class TkKW < TkId\n  end\n\n  class TkVal < Token\n    def initialize(line_no, char_no, value = nil)\n      super(line_no, char_no)\n      set_text(value)\n    end\n  end\n\n  class TkOp < Token\n    def name\n      self.class.op_name\n    end\n  end\n\n  class TkOPASGN < TkOp\n    def initialize(line_no, char_no, op)\n      super(line_no, char_no)\n      op = TkReading2Token[op] unless op.kind_of?(Symbol)\n      @op = op\n    end\n    attr :op\n  end\n\n  class TkUnknownChar < Token\n    def initialize(line_no, char_no, id)\n      super(line_no, char_no)\n      @name = char_no.chr\n    end\n    attr :name\n  end\n\n  class TkError < Token\n  end\n\n  def set_token_position(line, char)\n    @prev_line_no = line\n    @prev_char_no = char\n  end\n\n  def Token(token, value = nil)\n    tk = nil\n    case token\n    when String, Symbol\n      source = token.kind_of?(String) ? TkReading2Token : TkSymbol2Token\n      if (tk = source[token]).nil?\n\tIRB.fail TkReading2TokenNoKey, token\n      end\n      tk = Token(tk[0], value) \n    else \n      tk = if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?\n             token.new(@prev_line_no, @prev_char_no)\n           else\n             token.new(@prev_line_no, @prev_char_no, value)\n           end\n    end\n    tk\n  end\n\n  TokenDefinitions = [\n    [:TkCLASS,      TkKW,  \"class\",  EXPR_CLASS],\n    [:TkMODULE,     TkKW,  \"module\", EXPR_BEG],\n    [:TkDEF,\t    TkKW,  \"def\",    EXPR_FNAME],\n    [:TkUNDEF,      TkKW,  \"undef\",  EXPR_FNAME],\n    [:TkBEGIN,      TkKW,  \"begin\",  EXPR_BEG],\n    [:TkRESCUE,     TkKW,  \"rescue\", EXPR_MID],\n    [:TkENSURE,     TkKW,  \"ensure\", EXPR_BEG],\n    [:TkEND,\t    TkKW,  \"end\",    EXPR_END],\n    [:TkIF,         TkKW,  \"if\",     EXPR_BEG, :TkIF_MOD],\n    [:TkUNLESS,     TkKW,  \"unless\", EXPR_BEG, :TkUNLESS_MOD],\n    [:TkTHEN,\t    TkKW,  \"then\",   EXPR_BEG],\n    [:TkELSIF,      TkKW,  \"elsif\",  EXPR_BEG],\n    [:TkELSE,\t    TkKW,  \"else\",   EXPR_BEG],\n    [:TkCASE,\t    TkKW,  \"case\",   EXPR_BEG],\n    [:TkWHEN,\t    TkKW,  \"when\",   EXPR_BEG],\n    [:TkWHILE,      TkKW,  \"while\",  EXPR_BEG, :TkWHILE_MOD],\n    [:TkUNTIL,      TkKW,  \"until\",  EXPR_BEG, :TkUNTIL_MOD],\n    [:TkFOR,\t    TkKW,  \"for\",    EXPR_BEG],\n    [:TkBREAK,      TkKW,  \"break\",  EXPR_END],\n    [:TkNEXT,\t    TkKW,  \"next\",   EXPR_END],\n    [:TkREDO,\t    TkKW,  \"redo\",   EXPR_END],\n    [:TkRETRY,      TkKW,  \"retry\",  EXPR_END],\n    [:TkIN,\t    TkKW,  \"in\",     EXPR_BEG],\n    [:TkDO,\t    TkKW,  \"do\",     EXPR_BEG],\n    [:TkRETURN,     TkKW,  \"return\", EXPR_MID],\n    [:TkYIELD,      TkKW,  \"yield\",  EXPR_END],\n    [:TkSUPER,      TkKW,  \"super\",  EXPR_END],\n    [:TkSELF,\t    TkKW,  \"self\",   EXPR_END],\n    [:TkNIL, \t    TkKW,  \"nil\",    EXPR_END],\n    [:TkTRUE,\t    TkKW,  \"true\",   EXPR_END],\n    [:TkFALSE,      TkKW,  \"false\",  EXPR_END],\n    [:TkAND,\t    TkKW,  \"and\",    EXPR_BEG],\n    [:TkOR, \t    TkKW,  \"or\",     EXPR_BEG],\n    [:TkNOT,\t    TkKW,  \"not\",    EXPR_BEG],\n    [:TkIF_MOD,     TkKW],\n    [:TkUNLESS_MOD, TkKW],\n    [:TkWHILE_MOD,  TkKW],\n    [:TkUNTIL_MOD,  TkKW],\n    [:TkALIAS,      TkKW,  \"alias\",    EXPR_FNAME],\n    [:TkDEFINED,    TkKW,  \"defined?\", EXPR_END],\n    [:TklBEGIN,     TkKW,  \"BEGIN\",    EXPR_END],\n    [:TklEND,\t    TkKW,  \"END\",      EXPR_END],\n    [:Tk__LINE__,   TkKW,  \"__LINE__\", EXPR_END],\n    [:Tk__FILE__,   TkKW,  \"__FILE__\", EXPR_END],\n\n    [:TkIDENTIFIER, TkId],\n    [:TkFID,\t    TkId],\n    [:TkGVAR,\t    TkId],\n    [:TkIVAR,\t    TkId],\n    [:TkCONSTANT,   TkId],\n\n    [:TkINTEGER,    TkVal],\n    [:TkFLOAT,      TkVal],\n    [:TkSTRING,     TkVal],\n    [:TkXSTRING,    TkVal],\n    [:TkREGEXP,     TkVal],\n    [:TkCOMMENT,    TkVal],\n\n    [:TkDSTRING,    TkNode],\n    [:TkDXSTRING,   TkNode],\n    [:TkDREGEXP,    TkNode],\n    [:TkNTH_REF,    TkId],\n    [:TkBACK_REF,   TkId],\n\n    [:TkUPLUS,      TkOp,   \"+@\"],\n    [:TkUMINUS,     TkOp,   \"-@\"],\n    [:TkPOW,\t    TkOp,   \"**\"],\n    [:TkCMP,\t    TkOp,   \"<=>\"],\n    [:TkEQ,\t    TkOp,   \"==\"],\n    [:TkEQQ,\t    TkOp,   \"===\"],\n    [:TkNEQ,\t    TkOp,   \"!=\"],\n    [:TkGEQ,\t    TkOp,   \">=\"],\n    [:TkLEQ,\t    TkOp,   \"<=\"],\n    [:TkANDOP,      TkOp,   \"&&\"],\n    [:TkOROP,\t    TkOp,   \"||\"],\n    [:TkMATCH,      TkOp,   \"=~\"],\n    [:TkNMATCH,     TkOp,   \"!~\"],\n    [:TkDOT2,\t    TkOp,   \"..\"],\n    [:TkDOT3,\t    TkOp,   \"...\"],\n    [:TkAREF,\t    TkOp,   \"[]\"],\n    [:TkASET,\t    TkOp,   \"[]=\"],\n    [:TkLSHFT,      TkOp,   \"<<\"],\n    [:TkRSHFT,      TkOp,   \">>\"],\n    [:TkCOLON2,     TkOp],\n    [:TkCOLON3,     TkOp],\n#   [:OPASGN,\t    TkOp],               # +=, -=  etc. #\n    [:TkASSOC,      TkOp,   \"=>\"],\n    [:TkQUESTION,   TkOp,   \"?\"],\t #?\n    [:TkCOLON,      TkOp,   \":\"],        #:\n    \n    [:TkfLPAREN],         # func( #\n    [:TkfLBRACK],         # func[ #\n    [:TkfLBRACE],         # func{ #\n    [:TkSTAR],            # *arg\n    [:TkAMPER],           # &arg #\n    [:TkSYMBOL,     TkId],          # :SYMBOL\n    [:TkSYMBEG,     TkId], \n    [:TkGT,\t    TkOp,   \">\"],\n    [:TkLT,\t    TkOp,   \"<\"],\n    [:TkPLUS,\t    TkOp,   \"+\"],\n    [:TkMINUS,      TkOp,   \"-\"],\n    [:TkMULT,\t    TkOp,   \"*\"],\n    [:TkDIV,\t    TkOp,   \"/\"],\n    [:TkMOD,\t    TkOp,   \"%\"],\n    [:TkBITOR,      TkOp,   \"|\"],\n    [:TkBITXOR,     TkOp,   \"^\"],\n    [:TkBITAND,     TkOp,   \"&\"],\n    [:TkBITNOT,     TkOp,   \"~\"],\n    [:TkNOTOP,      TkOp,   \"!\"],\n\n    [:TkBACKQUOTE,  TkOp,   \"`\"],\n\n    [:TkASSIGN,     Token,  \"=\"],\n    [:TkDOT,\t    Token,  \".\"],\n    [:TkLPAREN,     Token,  \"(\"],  #(exp)\n    [:TkLBRACK,     Token,  \"[\"],  #[arry]\n    [:TkLBRACE,     Token,  \"{\"],  #{hash}\n    [:TkRPAREN,     Token,  \")\"],\n    [:TkRBRACK,     Token,  \"]\"],\n    [:TkRBRACE,     Token,  \"}\"],\n    [:TkCOMMA,      Token,  \",\"],\n    [:TkSEMICOLON,  Token,  \";\"],\n\n    [:TkRD_COMMENT],\n    [:TkSPACE],\n    [:TkNL],\n    [:TkEND_OF_SCRIPT],\n\n    [:TkBACKSLASH,  TkUnknownChar,  \"\\\\\"],\n    [:TkAT,\t    TkUnknownChar,  \"@\"],\n    [:TkDOLLAR,     TkUnknownChar,  \"\\$\"], #\"\n  ]\n\n  # {reading => token_class}\n  # {reading => [token_class, *opt]}\n  TkReading2Token = {}\n  TkSymbol2Token = {}\n\n  def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)\n    token_n = token_n.id2name unless token_n.kind_of?(String)\n    if RubyToken.const_defined?(token_n)\n      IRB.fail AlreadyDefinedToken, token_n\n    end\n\n    token_c =  Class.new super_token\n    RubyToken.const_set token_n, token_c\n#    token_c.inspect\n \n    if reading\n      if TkReading2Token[reading]\n\tIRB.fail TkReading2TokenDuplicateError, token_n, reading\n      end\n      if opts.empty?\n\tTkReading2Token[reading] = [token_c]\n      else\n\tTkReading2Token[reading] = [token_c].concat(opts)\n      end\n    end\n    TkSymbol2Token[token_n.intern] = token_c\n\n    if token_c <= TkOp\n      token_c.class_eval %{\n        def self.op_name; \"#{reading}\"; end\n      }\n    end\n  end\n\n  for defs in TokenDefinitions\n    def_token(*defs)\n  end\n\n  NEWLINE_TOKEN = TkNL.new(0,0)\n  NEWLINE_TOKEN.set_text(\"\\n\")\n\nend\n\n\n\n# Lexical analyzer for Ruby source\n\nclass RubyLex\n\n  ######################################################################\n  #\n  # Read an input stream character by character. We allow for unlimited\n  # ungetting of characters just read.\n  #\n  # We simplify the implementation greatly by reading the entire input\n  # into a buffer initially, and then simply traversing it using\n  # pointers.\n  #\n  # We also have to allow for the <i>here document diversion</i>. This\n  # little gem comes about when the lexer encounters a here\n  # document. At this point we effectively need to split the input\n  # stream into two parts: one to read the body of the here document,\n  # the other to read the rest of the input line where the here\n  # document was initially encountered. For example, we might have\n  #\n  #   do_something(<<-A, <<-B)\n  #     stuff\n  #     for\n  #   A\n  #     stuff\n  #     for\n  #   B\n  #\n  # When the lexer encounters the <<A, it reads until the end of the\n  # line, and keeps it around for later. It then reads the body of the\n  # here document.  Once complete, it needs to read the rest of the\n  # original line, but then skip the here document body.\n  #\n  \n  class BufferedReader\n    \n    attr_reader :line_num\n    \n    def initialize(content)\n      if /\\t/ =~ content\n        tab_width = Options.instance.tab_width\n        content = content.split(/\\n/).map do |line|\n          1 while line.gsub!(/\\t+/) { ' ' * (tab_width*$&.length - $`.length % tab_width)}  && $~ #`\n          line\n        end .join(\"\\n\")\n      end\n      @content   = content\n      @content << \"\\n\" unless @content[-1,1] == \"\\n\"\n      @size      = @content.size\n      @offset    = 0\n      @hwm       = 0\n      @line_num  = 1\n      @read_back_offset = 0\n      @last_newline = 0\n      @newline_pending = false\n    end\n    \n    def column\n      @offset - @last_newline\n    end\n    \n    def getc\n      return nil if @offset >= @size\n      ch = @content[@offset, 1]\n      \n      @offset += 1\n      @hwm = @offset if @hwm < @offset\n      \n      if @newline_pending\n        @line_num += 1\n        @last_newline = @offset - 1\n        @newline_pending = false\n      end\n      \n      if ch == \"\\n\"\n        @newline_pending = true\n      end\n      ch\n    end\n    \n    def getc_already_read\n      getc\n    end\n    \n    def ungetc(ch)\n      raise \"unget past beginning of file\" if @offset <= 0\n      @offset -= 1\n      if @content[@offset] == ?\\n\n        @newline_pending = false\n      end\n    end\n    \n    def get_read\n      res = @content[@read_back_offset...@offset]\n      @read_back_offset = @offset\n      res\n    end\n    \n    def peek(at)\n      pos = @offset + at\n      if pos >= @size\n        nil\n      else\n        @content[pos, 1]\n      end\n    end\n    \n    def peek_equal(str)\n      @content[@offset, str.length] == str\n    end\n    \n    def divert_read_from(reserve)\n      @content[@offset, 0] = reserve\n      @size      = @content.size\n    end\n  end\n\n  # end of nested class BufferedReader\n\n  extend Exception2MessageMapper\n  def_exception(:AlreadyDefinedToken, \"Already defined token(%s)\")\n  def_exception(:TkReading2TokenNoKey, \"key nothing(key='%s')\")\n  def_exception(:TkSymbol2TokenNoKey, \"key nothing(key='%s')\")\n  def_exception(:TkReading2TokenDuplicateError, \n\t\t\"key duplicate(token_n='%s', key='%s')\")\n  def_exception(:SyntaxError, \"%s\")\n  \n  include RubyToken\n  include IRB\n\n  attr_reader :continue\n  attr_reader :lex_state\n\n  def RubyLex.debug?\n    false\n  end\n\n  def initialize(content)\n    lex_init\n\n    @reader = BufferedReader.new(content)\n\n    @exp_line_no = @line_no = 1\n    @base_char_no = 0\n    @indent = 0\n\n    @ltype = nil\n    @quoted = nil\n    @lex_state = EXPR_BEG\n    @space_seen = false\n    \n    @continue = false\n    @line = \"\"\n\n    @skip_space = false\n    @read_auto_clean_up = false\n    @exception_on_syntax_error = true\n  end\n\n  attr :skip_space, true\n  attr :read_auto_clean_up, true\n  attr :exception_on_syntax_error, true\n\n  attr :indent\n\n  # io functions\n  def line_no\n    @reader.line_num\n  end\n\n  def char_no\n    @reader.column\n  end\n\n  def get_read\n    @reader.get_read\n  end\n\n  def getc\n    @reader.getc\n  end\n\n  def getc_of_rests\n    @reader.getc_already_read\n  end\n\n  def gets\n    c = getc or return\n    l = \"\"\n    begin\n      l.concat c unless c == \"\\r\"\n      break if c == \"\\n\"\n    end while c = getc\n    l\n  end\n\n\n  def ungetc(c = nil)\n    @reader.ungetc(c)\n  end\n\n  def peek_equal?(str)\n    @reader.peek_equal(str)\n  end\n\n  def peek(i = 0)\n    @reader.peek(i)\n  end\n\n  def lex\n    until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&\n\t     !@continue or\n\t     tk.nil?)\n    end\n    line = get_read\n\n    if line == \"\" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?\n      nil\n    else\n      line\n    end\n  end\n\n  def token\n    set_token_position(line_no, char_no)\n    begin\n      begin\n\ttk = @OP.match(self)\n\t@space_seen = tk.kind_of?(TkSPACE)\n      rescue SyntaxError\n\tabort if @exception_on_syntax_error\n\ttk = TkError.new(line_no, char_no)\n      end\n    end while @skip_space and tk.kind_of?(TkSPACE)\n    if @read_auto_clean_up\n      get_read\n    end\n#   throw :eof unless tk\n    p tk if $DEBUG\n    tk\n  end\n  \n  ENINDENT_CLAUSE = [\n    \"case\", \"class\", \"def\", \"do\", \"for\", \"if\",\n    \"module\", \"unless\", \"until\", \"while\", \"begin\" #, \"when\"\n  ]\n  DEINDENT_CLAUSE = [\"end\" #, \"when\"\n  ]\n\n  PERCENT_LTYPE = {\n    \"q\" => \"\\'\",\n    \"Q\" => \"\\\"\",\n    \"x\" => \"\\`\",\n    \"r\" => \"/\",\n    \"w\" => \"]\"\n  }\n  \n  PERCENT_PAREN = {\n    \"{\" => \"}\",\n    \"[\" => \"]\",\n    \"<\" => \">\",\n    \"(\" => \")\"\n  }\n\n  Ltype2Token = {\n    \"\\'\" => TkSTRING,\n    \"\\\"\" => TkSTRING,\n    \"\\`\" => TkXSTRING,\n    \"/\" => TkREGEXP,\n    \"]\" => TkDSTRING\n  }\n  Ltype2Token.default = TkSTRING\n\n  DLtype2Token = {\n    \"\\\"\" => TkDSTRING,\n    \"\\`\" => TkDXSTRING,\n    \"/\" => TkDREGEXP,\n  }\n\n  def lex_init()\n    @OP = SLex.new\n    @OP.def_rules(\"\\0\", \"\\004\", \"\\032\") do |chars, io|\n      Token(TkEND_OF_SCRIPT).set_text(chars)\n    end\n\n    @OP.def_rules(\" \", \"\\t\", \"\\f\", \"\\r\", \"\\13\") do |chars, io|\n      @space_seen = TRUE\n      while (ch = getc) =~ /[ \\t\\f\\r\\13]/\n        chars << ch\n      end\n      ungetc\n      Token(TkSPACE).set_text(chars)\n    end\n\n    @OP.def_rule(\"#\") do\n      |op, io|\n      identify_comment\n    end\n\n    @OP.def_rule(\"=begin\", proc{@prev_char_no == 0 && peek(0) =~ /\\s/}) do\n      |op, io|\n      str = op\n      @ltype = \"=\"\n\n\n      begin\n        line = \"\"\n        begin\n          ch = getc\n          line << ch\n        end until ch == \"\\n\"\n        str << line\n      end until line =~ /^=end/\n\n      ungetc\n\n      @ltype = nil\n\n      if str =~ /\\A=begin\\s+rdoc/i\n        str.sub!(/\\A=begin.*\\n/, '')\n        str.sub!(/^=end.*/m, '')\n        Token(TkCOMMENT).set_text(str)\n      else\n        Token(TkRD_COMMENT)#.set_text(str)\n      end\n    end\n\n    @OP.def_rule(\"\\n\") do\n      print \"\\\\n\\n\" if RubyLex.debug?\n      case @lex_state\n      when EXPR_BEG, EXPR_FNAME, EXPR_DOT\n\t@continue = TRUE\n      else\n\t@continue = FALSE\n\t@lex_state = EXPR_BEG\n      end\n      Token(TkNL).set_text(\"\\n\")\n    end\n\n    @OP.def_rules(\"*\", \"**\",\t\n\t\t  \"!\", \"!=\", \"!~\",\n\t\t  \"=\", \"==\", \"===\", \n\t\t  \"=~\", \"<=>\",\t\n\t\t  \"<\", \"<=\",\n\t\t  \">\", \">=\", \">>\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op).set_text(op)\n    end\n\n    @OP.def_rules(\"<<\") do\n      |op, io|\n      tk = nil\n      if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&\n\t  (@lex_state != EXPR_ARG || @space_seen)\n\tc = peek(0)\n\tif /[-\\w_\\\"\\'\\`]/ =~ c\n\t  tk = identify_here_document\n\tend\n      end\n      if !tk\n        @lex_state = EXPR_BEG\n        tk = Token(op).set_text(op)\n      end\n      tk\n    end\n\n    @OP.def_rules(\"'\", '\"') do\n      |op, io|\n      identify_string(op)\n    end\n\n    @OP.def_rules(\"`\") do\n      |op, io|\n      if @lex_state == EXPR_FNAME\n\tToken(op).set_text(op)\n      else\n\tidentify_string(op)\n      end\n    end\n\n    @OP.def_rules('?') do\n      |op, io|\n      if @lex_state == EXPR_END\n\t@lex_state = EXPR_BEG\n\tToken(TkQUESTION).set_text(op)\n      else\n\tch = getc\n\tif @lex_state == EXPR_ARG && ch !~ /\\s/\n\t  ungetc\n\t  @lex_state = EXPR_BEG;\n\t  Token(TkQUESTION).set_text(op)\n\telse\n          str = op\n          str << ch\n\t  if (ch == '\\\\') #'\n\t    str << read_escape\n\t  end\n\t  @lex_state = EXPR_END\n\t  Token(TkINTEGER).set_text(str)\n\tend\n      end\n    end\n\n    @OP.def_rules(\"&\", \"&&\", \"|\", \"||\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op).set_text(op)\n    end\n    \n    @OP.def_rules(\"+=\", \"-=\", \"*=\", \"**=\", \n\t\t  \"&=\", \"|=\", \"^=\", \"<<=\", \">>=\", \"||=\", \"&&=\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      op =~ /^(.*)=$/\n      Token(TkOPASGN, $1).set_text(op)\n    end\n\n    @OP.def_rule(\"+@\", proc{@lex_state == EXPR_FNAME}) do |op, io|\n      Token(TkUPLUS).set_text(op)\n    end\n\n    @OP.def_rule(\"-@\", proc{@lex_state == EXPR_FNAME}) do |op, io|\n      Token(TkUMINUS).set_text(op)\n    end\n\n    @OP.def_rules(\"+\", \"-\") do\n      |op, io|\n      catch(:RET) do\n\tif @lex_state == EXPR_ARG\n\t  if @space_seen and peek(0) =~ /[0-9]/\n\t    throw :RET, identify_number(op)\n\t  else\n\t    @lex_state = EXPR_BEG\n\t  end\n\telsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/\n\t  throw :RET, identify_number(op)\n\telse\n\t  @lex_state = EXPR_BEG\n\tend\n\tToken(op).set_text(op)\n      end\n    end\n\n    @OP.def_rule(\".\") do\n      @lex_state = EXPR_BEG\n      if peek(0) =~ /[0-9]/\n\tungetc\n\tidentify_number(\"\")\n      else\n\t# for obj.if\n\t@lex_state = EXPR_DOT\n\tToken(TkDOT).set_text(\".\")\n      end\n    end\n\n    @OP.def_rules(\"..\", \"...\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op).set_text(op)\n    end\n\n    lex_int2\n  end\n  \n  def lex_int2\n    @OP.def_rules(\"]\", \"}\", \")\") do\n      |op, io|\n      @lex_state = EXPR_END\n      @indent -= 1\n      Token(op).set_text(op)\n    end\n\n    @OP.def_rule(\":\") do\n      if @lex_state == EXPR_END || peek(0) =~ /\\s/\n\t@lex_state = EXPR_BEG\n\ttk = Token(TkCOLON)\n      else\n\t@lex_state = EXPR_FNAME;\n\ttk = Token(TkSYMBEG)\n      end\n      tk.set_text(\":\")\n    end\n\n    @OP.def_rule(\"::\") do\n#      p @lex_state.id2name, @space_seen\n      if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen\n\t@lex_state = EXPR_BEG\n\ttk = Token(TkCOLON3)\n      else\n\t@lex_state = EXPR_DOT\n\ttk = Token(TkCOLON2)\n      end\n      tk.set_text(\"::\")\n    end\n\n    @OP.def_rule(\"/\") do\n      |op, io|\n      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\tidentify_string(op)\n      elsif peek(0) == '='\n\tgetc\n\t@lex_state = EXPR_BEG\n\tToken(TkOPASGN, :/).set_text(\"/=\") #\")\n      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\\s/\n\tidentify_string(op)\n      else \n\t@lex_state = EXPR_BEG\n        Token(\"/\").set_text(op)\n      end\n    end\n\n    @OP.def_rules(\"^\") do\n      @lex_state = EXPR_BEG\n      Token(\"^\").set_text(\"^\")\n    end\n\n    #       @OP.def_rules(\"^=\") do\n    # \t@lex_state = EXPR_BEG\n    # \tToken(TkOPASGN, :^)\n    #       end\n    \n    @OP.def_rules(\",\", \";\") do\n      |op, io|\n      @lex_state = EXPR_BEG\n      Token(op).set_text(op)\n    end\n\n    @OP.def_rule(\"~\") do\n      @lex_state = EXPR_BEG\n      Token(\"~\").set_text(\"~\")\n    end\n\n    @OP.def_rule(\"~@\", proc{@lex_state = EXPR_FNAME}) do\n      @lex_state = EXPR_BEG\n      Token(\"~\").set_text(\"~@\")\n    end\n    \n    @OP.def_rule(\"(\") do\n      @indent += 1\n      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\t@lex_state = EXPR_BEG\n\ttk = Token(TkfLPAREN)\n      else\n\t@lex_state = EXPR_BEG\n\ttk = Token(TkLPAREN)\n      end\n      tk.set_text(\"(\")\n    end\n\n    @OP.def_rule(\"[]\", proc{@lex_state == EXPR_FNAME}) do\n      Token(\"[]\").set_text(\"[]\")\n    end\n\n    @OP.def_rule(\"[]=\", proc{@lex_state == EXPR_FNAME}) do\n      Token(\"[]=\").set_text(\"[]=\")\n    end\n\n    @OP.def_rule(\"[\") do\n      @indent += 1\n      if @lex_state == EXPR_FNAME\n\tt = Token(TkfLBRACK)\n      else\n\tif @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\t  t = Token(TkLBRACK)\n\telsif @lex_state == EXPR_ARG && @space_seen\n\t  t = Token(TkLBRACK)\n\telse\n\t  t = Token(TkfLBRACK)\n\tend\n\t@lex_state = EXPR_BEG\n      end\n      t.set_text(\"[\")\n    end\n\n    @OP.def_rule(\"{\") do\n      @indent += 1\n      if @lex_state != EXPR_END && @lex_state != EXPR_ARG\n\tt = Token(TkLBRACE)\n      else\n\tt = Token(TkfLBRACE)\n      end\n      @lex_state = EXPR_BEG\n      t.set_text(\"{\")\n    end\n\n    @OP.def_rule('\\\\') do   #'\n      if getc == \"\\n\" \n\t@space_seen = true\n\t@continue = true\n\tToken(TkSPACE).set_text(\"\\\\\\n\")\n      else \n\tungetc\n\tToken(\"\\\\\").set_text(\"\\\\\")  #\"\n      end \n    end \n\n    @OP.def_rule('%') do\n      |op, io|\n      if @lex_state == EXPR_BEG || @lex_state == EXPR_MID\n\tidentify_quotation('%')\n      elsif peek(0) == '='\n\tgetc\n\tToken(TkOPASGN, \"%\").set_text(\"%=\")\n      elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\\s/\n\tidentify_quotation('%')\n      else\n\t@lex_state = EXPR_BEG\n\tToken(\"%\").set_text(\"%\")\n      end\n    end\n\n    @OP.def_rule('$') do  #'\n      identify_gvar\n    end\n\n    @OP.def_rule('@') do\n      if peek(0) =~ /[@\\w_]/\n\tungetc\n\tidentify_identifier\n      else\n\tToken(\"@\").set_text(\"@\")\n      end\n    end\n\n    #       @OP.def_rule(\"def\", proc{|op, io| /\\s/ =~ io.peek(0)}) do \n    # \t|op, io|\n    # \t@indent += 1\n    # \t@lex_state = EXPR_FNAME\n    # #\t@lex_state = EXPR_END\n    # #\tuntil @rests[0] == \"\\n\" or @rests[0] == \";\"\n    # #\t  rests.shift\n    # #\tend\n    #       end\n\n    @OP.def_rule(\"__END__\", proc{@prev_char_no == 0 && peek(0) =~ /[\\r\\n]/}) do\n      throw :eof\n    end\n\n    @OP.def_rule(\"\") do\n      |op, io|\n      printf \"MATCH: start %s: %s\\n\", op, io.inspect if RubyLex.debug?\n      if peek(0) =~ /[0-9]/\n\tt = identify_number(\"\")\n      elsif peek(0) =~ /[\\w_]/\n\tt = identify_identifier\n      end\n      printf \"MATCH: end %s: %s\\n\", op, io.inspect if RubyLex.debug?\n      t\n    end\n    \n    p @OP if RubyLex.debug?\n  end\n  \n  def identify_gvar\n    @lex_state = EXPR_END\n    str = \"$\"\n\n    tk = case ch = getc\n         when /[~_*$?!@\\/\\\\;,=:<>\".]/   #\"\n           str << ch\n           Token(TkGVAR, str)\n           \n         when \"-\"\n           str << \"-\" << getc\n           Token(TkGVAR, str)\n           \n         when \"&\", \"`\", \"'\", \"+\"\n           str << ch\n           Token(TkBACK_REF, str)\n           \n         when /[1-9]/\n           str << ch\n           while (ch = getc) =~ /[0-9]/\n             str << ch\n           end\n           ungetc\n           Token(TkNTH_REF)\n         when /\\w/\n           ungetc\n           ungetc\n           return identify_identifier\n         else \n           ungetc\n           Token(\"$\")     \n         end\n    tk.set_text(str)\n  end\n  \n  def identify_identifier\n    token = \"\"\n    token.concat getc if peek(0) =~ /[$@]/\n    token.concat getc if peek(0) == \"@\"\n\n    while (ch = getc) =~ /\\w|_/\n      print \":\", ch, \":\" if RubyLex.debug?\n      token.concat ch\n    end\n    ungetc\n    \n    if ch == \"!\" or ch == \"?\"\n      token.concat getc\n    end\n    # fix token\n\n    # $stderr.puts \"identifier - #{token}, state = #@lex_state\"\n\n    case token\n    when /^\\$/\n      return Token(TkGVAR, token).set_text(token)\n    when /^\\@/\n      @lex_state = EXPR_END\n      return Token(TkIVAR, token).set_text(token)\n    end\n    \n    if @lex_state != EXPR_DOT\n      print token, \"\\n\" if RubyLex.debug?\n\n      token_c, *trans = TkReading2Token[token]\n      if token_c\n\t# reserved word?\n\n\tif (@lex_state != EXPR_BEG &&\n\t    @lex_state != EXPR_FNAME &&\n\t    trans[1])\n\t  # modifiers\n\t  token_c = TkSymbol2Token[trans[1]]\n\t  @lex_state = trans[0]\n\telse\n\t  if @lex_state != EXPR_FNAME\n\t    if ENINDENT_CLAUSE.include?(token)\n\t      @indent += 1\n\t    elsif DEINDENT_CLAUSE.include?(token)\n\t      @indent -= 1\n\t    end\n\t    @lex_state = trans[0]\n\t  else\n\t    @lex_state = EXPR_END\n\t  end\n\tend\n\treturn Token(token_c, token).set_text(token)\n      end\n    end\n\n    if @lex_state == EXPR_FNAME\n      @lex_state = EXPR_END\n      if peek(0) == '='\n\ttoken.concat getc\n      end\n    elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT\n      @lex_state = EXPR_ARG\n    else\n      @lex_state = EXPR_END\n    end\n\n    if token[0, 1] =~ /[A-Z]/\n      return Token(TkCONSTANT, token).set_text(token)\n    elsif token[token.size - 1, 1] =~ /[!?]/\n      return Token(TkFID, token).set_text(token)\n    else\n      return Token(TkIDENTIFIER, token).set_text(token)\n    end\n  end\n\n  def identify_here_document\n    ch = getc\n    if ch == \"-\"\n      ch = getc\n      indent = true\n    end\n    if /['\"`]/ =~ ch            # '\n      lt = ch\n      quoted = \"\"\n      while (c = getc) && c != lt\n\tquoted.concat c\n      end\n    else\n      lt = '\"'\n      quoted = ch.dup\n      while (c = getc) && c =~ /\\w/\n\tquoted.concat c\n      end\n      ungetc\n    end\n\n    ltback, @ltype = @ltype, lt\n    reserve = \"\"\n\n    while ch = getc\n      reserve << ch\n      if ch == \"\\\\\"    #\"\n        ch = getc\n\treserve << ch\n      elsif ch == \"\\n\"\n\tbreak\n      end\n    end\n\n    str = \"\"\n    while (l = gets)\n      l.chomp!\n      l.strip! if indent\n      break if l == quoted\n      str << l.chomp << \"\\n\"\n    end\n\n    @reader.divert_read_from(reserve)\n\n    @ltype = ltback\n    @lex_state = EXPR_END\n    Token(Ltype2Token[lt], str).set_text(str.dump)\n  end\n  \n  def identify_quotation(initial_char)\n    ch = getc\n    if lt = PERCENT_LTYPE[ch]\n      initial_char += ch\n      ch = getc\n    elsif ch =~ /\\W/\n      lt = \"\\\"\"\n    else\n      RubyLex.fail SyntaxError, \"unknown type of %string ('#{ch}')\"\n    end\n#     if ch !~ /\\W/\n#       ungetc\n#       next\n#     end\n    #@ltype = lt\n    @quoted = ch unless @quoted = PERCENT_PAREN[ch]\n    identify_string(lt, @quoted, ch, initial_char)\n  end\n\n  def identify_number(start)\n    str = start.dup\n\n    if start == \"+\" or start == \"-\" or start == \"\"\n      start = getc\n      str << start\n    end\n\n    @lex_state = EXPR_END\n\n    if start == \"0\"\n      if peek(0) == \"x\"\n        ch = getc\n        str << ch\n        match = /[0-9a-f_]/\n      else\n        match = /[0-7_]/\n      end\n      while ch = getc\n        if ch !~ match\n          ungetc\n          break\n        else\n          str << ch\n        end\n      end\n      return Token(TkINTEGER).set_text(str)\n    end\n\n    type = TkINTEGER\n    allow_point = TRUE\n    allow_e = TRUE\n    while ch = getc\n      case ch\n      when /[0-9_]/\n        str << ch\n\n      when allow_point && \".\"\n\ttype = TkFLOAT\n\tif peek(0) !~ /[0-9]/\n\t  ungetc\n\t  break\n\tend\n        str << ch\n\tallow_point = false\n\n      when allow_e && \"e\", allow_e && \"E\"\n        str << ch\n\ttype = TkFLOAT\n\tif peek(0) =~ /[+-]/\n\t  str << getc\n\tend\n\tallow_e = false\n\tallow_point = false\n      else\n\tungetc\n\tbreak\n      end\n    end\n    Token(type).set_text(str)\n  end\n  \n  def identify_string(ltype, quoted = ltype, opener=nil, initial_char = nil)\n    @ltype = ltype\n    @quoted = quoted\n    subtype = nil\n\n    str = \"\"\n    str << initial_char if initial_char\n    str << (opener||quoted)\n\n    nest = 0\n    begin\n      while ch = getc \n\tstr << ch\n\tif @quoted == ch \n          if nest == 0\n            break\n          else\n            nest -= 1\n          end\n        elsif opener == ch\n          nest += 1\n\telsif @ltype != \"'\" && @ltype != \"]\" and ch == \"#\"\n          ch = getc\n          if ch == \"{\"\n            subtype = true\n            str << ch << skip_inner_expression\n          else\n            ungetc(ch)\n          end\n\telsif ch == '\\\\' #'\n\t  str << read_escape\n\tend\n      end\n      if @ltype == \"/\"\n\tif peek(0) =~ /i|o|n|e|s/\n\t  str << getc\n\tend\n      end\n      if subtype\n\tToken(DLtype2Token[ltype], str)\n      else\n\tToken(Ltype2Token[ltype], str)\n      end.set_text(str)\n    ensure\n      @ltype = nil\n      @quoted = nil\n      @lex_state = EXPR_END\n    end\n  end\n\n  def skip_inner_expression\n    res = \"\"\n    nest = 0\n    while (ch = getc)\n      res << ch\n      if ch == '}'\n        break if nest.zero?\n        nest -= 1\n      elsif ch == '{'\n        nest += 1\n      end\n    end\n    res\n  end\n\n  def identify_comment\n    @ltype = \"#\"\n    comment = \"#\"\n    while ch = getc\n      if ch == \"\\\\\"\n        ch = getc\n        if ch == \"\\n\"\n          ch = \" \"\n        else\n          comment << \"\\\\\" \n        end\n      else\n        if ch == \"\\n\"\n          @ltype = nil\n          ungetc\n          break\n        end\n      end\n      comment << ch\n    end\n    return Token(TkCOMMENT).set_text(comment)\n  end\n  \n  def read_escape\n    res = \"\"\n    case ch = getc\n    when /[0-7]/\n      ungetc ch\n      3.times do\n\tcase ch = getc\n\twhen /[0-7]/\n\twhen nil\n\t  break\n\telse\n\t  ungetc\n\t  break\n\tend\n        res << ch\n      end\n      \n    when \"x\"\n      res << ch\n      2.times do\n\tcase ch = getc\n\twhen /[0-9a-fA-F]/\n\twhen nil\n\t  break\n\telse\n\t  ungetc\n\t  break\n\tend\n        res << ch\n      end\n\n    when \"M\"\n      res << ch\n      if (ch = getc) != '-'\n\tungetc\n      else\n        res << ch\n\tif (ch = getc) == \"\\\\\" #\"\n          res << ch\n\t  res << read_escape\n        else\n          res << ch\n\tend\n      end\n\n    when \"C\", \"c\" #, \"^\"\n      res << ch\n      if ch == \"C\" and (ch = getc) != \"-\"\n\tungetc\n      else\n        res << ch\n        if (ch = getc) == \"\\\\\" #\"\n          res << ch\n          res << read_escape\n        else\n          res << ch\n        end\n      end\n    else\n      res << ch\n    end\n    res\n  end\nend\n\n\n\n# Extract code elements from a source file, returning a TopLevel\n# object containing the constituent file elements.\n#\n# This file is based on rtags\n\nmodule RDoc\n\n  GENERAL_MODIFIERS = [ 'nodoc' ].freeze\n\n  CLASS_MODIFIERS = GENERAL_MODIFIERS\n\n  ATTR_MODIFIERS  = GENERAL_MODIFIERS\n\n  CONSTANT_MODIFIERS = GENERAL_MODIFIERS\n\n  METHOD_MODIFIERS = GENERAL_MODIFIERS + \n    [ 'arg', 'args', 'yield', 'yields', 'notnew', 'not-new', 'not_new', 'doc' ]\n\n\n  class RubyParser\n    include RubyToken\n    include TokenStream\n\n    extend ParserFactory\n\n    parse_files_matching(/\\.rbw?$/)\n\n\n    def initialize(top_level, file_name, content, options, stats)\n      @options = options\n      @stats   = stats\n      @size = 0\n      @token_listeners = nil\n      @input_file_name = file_name\n      @scanner = RubyLex.new(content)\n      @scanner.exception_on_syntax_error = false\n      @top_level = top_level\n      @progress = $stderr unless options.quiet\n    end\n\n    def scan\n      @tokens = []\n      @unget_read = []\n      @read = []\n      catch(:eof) do\n        catch(:enddoc) do\n          begin\n            parse_toplevel_statements(@top_level)\n          rescue Exception => e\n            $stderr.puts \"\\n\\n\"\n            $stderr.puts \"RDoc failure in #@input_file_name at or around \" +\n                         \"line #{@scanner.line_no} column #{@scanner.char_no}\"\n            $stderr.puts \n            $stderr.puts \"Before reporting this, could you check that the file\"\n            $stderr.puts \"you're documenting compiles cleanly--RDoc is not a\"\n            $stderr.puts \"full Ruby parser, and gets confused easily if fed\"\n            $stderr.puts \"invalid programs.\"\n            $stderr.puts\n            $stderr.puts \"The internal error was:\\n\\n\"\n            \n            e.set_backtrace(e.backtrace[0,4])\n            raise\n          end\n        end\n      end\n      @top_level\n    end\n\n    private \n\n    def make_message(msg)\n      prefix = \"\\n\" + @input_file_name + \":\"\n      if @scanner\n        prefix << \"#{@scanner.line_no}:#{@scanner.char_no}: \"\n      end\n      return prefix + msg\n    end\n\n    def warn(msg)\n      return if @options.quiet\n      msg = make_message msg\n      $stderr.puts msg\n    end\n\n    def error(msg)\n      msg = make_message msg\n      $stderr.puts msg\n      exit(1)\n    end\n\n    def progress(char)\n      unless @options.quiet\n        @progress.print(char)\n\t@progress.flush\n      end\n    end\n\n    def add_token_listener(obj)\n      @token_listeners ||= []\n      @token_listeners << obj\n    end\n\n    def remove_token_listener(obj)\n      @token_listeners.delete(obj)\n    end\n\n    def get_tk\n      tk = nil\n      if @tokens.empty?\n\ttk = @scanner.token\n\t@read.push @scanner.get_read\n\tputs \"get_tk1 => #{tk.inspect}\" if $TOKEN_DEBUG\n      else\n\t@read.push @unget_read.shift\n\ttk = @tokens.shift\n\tputs \"get_tk2 => #{tk.inspect}\" if $TOKEN_DEBUG\n      end\n\n      if tk.kind_of?(TkSYMBEG)\n        set_token_position(tk.line_no, tk.char_no)\n        tk1 = get_tk\n        if tk1.kind_of?(TkId) || tk1.kind_of?(TkOp)\n          tk = Token(TkSYMBOL).set_text(\":\" + tk1.name)\n          # remove the identifier we just read (we're about to\n          # replace it with a symbol)\n          @token_listeners.each do |obj|\n            obj.pop_token\n          end if @token_listeners\n        else\n          warn(\"':' not followed by identifier or operator\")\n          tk = tk1\n        end\n      end\n\n      # inform any listeners of our shiny new token\n      @token_listeners.each do |obj|\n        obj.add_token(tk)\n      end if @token_listeners\n\n      tk\n    end\n\n    def peek_tk\n      unget_tk(tk = get_tk)\n      tk\n    end\n\n    def unget_tk(tk)\n      @tokens.unshift tk\n      @unget_read.unshift @read.pop\n\n      # Remove this token from any listeners\n      @token_listeners.each do |obj|\n        obj.pop_token\n      end if @token_listeners\n    end\n\n    def skip_tkspace(skip_nl = true)\n      tokens = []\n      while ((tk = get_tk).kind_of?(TkSPACE) ||\n\t     (skip_nl && tk.kind_of?(TkNL)))\n\ttokens.push tk\n      end\n      unget_tk(tk)\n      tokens\n    end\n\n    def get_tkread\n      read = @read.join(\"\")\n      @read = []\n      read\n    end\n\n    def peek_read\n      @read.join('')\n    end\n\n    NORMAL = \"::\"\n    SINGLE = \"<<\"\n\n    # Look for the first comment in a file that isn't\n    # a shebang line.\n\n    def collect_first_comment\n      skip_tkspace\n      res = ''\n      first_line = true\n\n      tk = get_tk\n      while tk.kind_of?(TkCOMMENT)\n        if first_line && /\\A#!/ =~ tk.text\n          skip_tkspace\n          tk = get_tk\n        elsif first_line && /\\A#\\s*-\\*-/ =~ tk.text\n          first_line = false\n          skip_tkspace\n          tk = get_tk\n        else\n          first_line = false\n          res << tk.text << \"\\n\"\n          tk = get_tk\n          if tk.kind_of? TkNL\n            skip_tkspace(false)\n            tk = get_tk\n          end\n        end\n      end\n      unget_tk(tk)\n      res\n    end\n\n    def parse_toplevel_statements(container)\n      comment = collect_first_comment\n      look_for_directives_in(container, comment)\n      container.comment = comment unless comment.empty?\n      parse_statements(container, NORMAL, nil, comment)\n    end\n    \n    def parse_statements(container, single=NORMAL, current_method=nil, comment='')\n      nest = 1\n      save_visibility = container.visibility\n      \n#      if container.kind_of?(TopLevel)\n#      else\n#        comment = ''\n#      end\n\n      non_comment_seen = true\n      \n      while tk = get_tk\n        \n        keep_comment = false\n        \n        non_comment_seen = true unless tk.kind_of?(TkCOMMENT)\n        \n\tcase tk\n\n        when TkNL\n          skip_tkspace(true)   # Skip blanks and newlines\n          tk = get_tk\n          if tk.kind_of?(TkCOMMENT)\n            if non_comment_seen\n              comment = ''\n              non_comment_seen = false\n            end\n            while tk.kind_of?(TkCOMMENT)\n              comment << tk.text << \"\\n\"\n              tk = get_tk          # this is the newline \n              skip_tkspace(false)  # leading spaces\n              tk = get_tk\n            end\n            unless comment.empty?\n              look_for_directives_in(container, comment) \n              if container.done_documenting\n                container.ongoing_visibility = save_visibility\n#                return\n              end\n            end\n            keep_comment = true\n          else\n            non_comment_seen = true\n          end\n          unget_tk(tk)\n          keep_comment = true\n\n\n\twhen TkCLASS\n\t  if container.document_children\n            parse_class(container, single, tk, comment)\n\t  else\n\t    nest += 1\n          end\n\n\twhen TkMODULE\n\t  if container.document_children\n            parse_module(container, single, tk, comment)\n\t  else\n\t    nest += 1\n          end\n\n\twhen TkDEF\n\t  if container.document_self\n\t    parse_method(container, single, tk, comment)\n\t  else\n\t    nest += 1\n          end\n\n        when TkCONSTANT\n          if container.document_self\n            parse_constant(container, single, tk, comment)\n          end\n\n\twhen TkALIAS\n \t  if container.document_self\n\t    parse_alias(container, single, tk, comment)\n\t  end\n\n        when TkYIELD\n          if current_method.nil?\n            warn(\"Warning: yield outside of method\") if container.document_self\n          else\n            parse_yield(container, single, tk, current_method)\n          end\n\n          # Until and While can have a 'do', which shouldn't increas\n          # the nesting. We can't solve the general case, but we can\n          # handle most occurrences by ignoring a do at the end of a line\n\n        when  TkUNTIL, TkWHILE\n          nest += 1\n          puts \"FOUND #{tk.class} in #{container.name}, nest = #{nest}, \" +\n            \"line #{tk.line_no}\" if $DEBUG\n          skip_optional_do_after_expression\n\n          # 'for' is trickier\n        when TkFOR\n          nest += 1\n          puts \"FOUND #{tk.class} in #{container.name}, nest = #{nest}, \" +\n            \"line #{tk.line_no}\" if $DEBUG\n          skip_for_variable\n          skip_optional_do_after_expression\n\n\twhen TkCASE, TkDO, TkIF, TkUNLESS, TkBEGIN\n\t  nest += 1\n          puts \"Found #{tk.class} in #{container.name}, nest = #{nest}, \" +\n            \"line #{tk.line_no}\" if $DEBUG\n\n\twhen TkIDENTIFIER\n          if nest == 1 and current_method.nil?\n            case tk.name\n            when \"private\", \"protected\", \"public\",\n                 \"private_class_method\", \"public_class_method\"\n              parse_visibility(container, single, tk)\n              keep_comment = true\n            when \"attr\"\n              parse_attr(container, single, tk, comment)\n            when /^attr_(reader|writer|accessor)$/, @options.extra_accessors\n              parse_attr_accessor(container, single, tk, comment)\n            when \"alias_method\"\n              if container.document_self\n\t        parse_alias(container, single, tk, comment)\n\t      end\n            end\n\t  end\n\t  \n\t  case tk.name\n\t  when \"require\"\n\t    parse_require(container, comment)\n\t  when \"include\"\n\t    parse_include(container, comment)\n\t  end\n\n\n\twhen TkEND\n          nest -= 1\n          puts \"Found 'end' in #{container.name}, nest = #{nest}, line #{tk.line_no}\" if $DEBUG\n          puts \"Method = #{current_method.name}\" if $DEBUG and current_method\n\t  if nest == 0\n            read_documentation_modifiers(container, CLASS_MODIFIERS)\n            container.ongoing_visibility = save_visibility\n            return\n          end\n\n\tend\n\n        comment = '' unless keep_comment\n\tbegin\n\t  get_tkread\n\t  skip_tkspace(false)\n\tend while peek_tk == TkNL\n\n      end\n    end\n    \n    def parse_class(container, single, tk, comment, &block)\n      progress(\"c\")\n\n      @stats.num_classes += 1\n\n      container, name_t = get_class_or_module(container)\n\n      case name_t\n      when TkCONSTANT\n\tname = name_t.name\n        superclass = \"Object\"\n\n        if peek_tk.kind_of?(TkLT)\n          get_tk\n          skip_tkspace(true)\n          superclass = get_class_specification\n          superclass = \"<unknown>\" if superclass.empty?\n        end\n\n\tif single == SINGLE\n\t  cls_type = SingleClass\n\telse\n\t  cls_type = NormalClass\n\tend\n\n        cls = container.add_class(cls_type, name, superclass)\n        read_documentation_modifiers(cls, CLASS_MODIFIERS)\n        cls.record_location(@top_level)\n\tparse_statements(cls)\n        cls.comment = comment\n\n      when TkLSHFT\n\tcase name = get_class_specification\n\twhen \"self\", container.name\n\t  parse_statements(container, SINGLE, &block)\n\telse\n          other = TopLevel.find_class_named(name)\n          unless other\n#            other = @top_level.add_class(NormalClass, name, nil)\n#            other.record_location(@top_level)\n#            other.comment = comment\n            other = NormalClass.new(\"Dummy\", nil)\n          end\n          read_documentation_modifiers(other, CLASS_MODIFIERS)\n          parse_statements(other, SINGLE, &block)\n\tend\n\n      else\n\twarn(\"Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}\")\n      end\n    end\n\n    def parse_module(container, single, tk, comment)\n      progress(\"m\")\n      @stats.num_modules += 1\n      container, name_t  = get_class_or_module(container)\n#      skip_tkspace\n      name = name_t.name\n      mod = container.add_module(NormalModule, name)\n      mod.record_location(@top_level)\n      read_documentation_modifiers(mod, CLASS_MODIFIERS)\n      parse_statements(mod)\n      mod.comment = comment\n    end\n\n    # Look for the name of a class of module (optionally with a leading :: or\n    # with :: separated named) and return the ultimate name and container\n\n    def get_class_or_module(container)\n      skip_tkspace\n      name_t = get_tk\n\n      # class ::A -> A is in the top level\n      if name_t.kind_of?(TkCOLON2)\n        name_t = get_tk\n        container = @top_level\n      end\n\n      skip_tkspace(false)\n\n      while peek_tk.kind_of?(TkCOLON2)\n        prev_container = container\n        container = container.find_module_named(name_t.name)\n        if !container\n#          warn(\"Couldn't find module #{name_t.name}\")\n          container = prev_container.add_module(NormalModule, name_t.name)\n        end\n        get_tk\n        name_t = get_tk\n      end\n      skip_tkspace(false)\n      return [container, name_t]\n    end\n\n    def parse_constant(container, single, tk, comment)\n      name = tk.name\n      skip_tkspace(false)\n      eq_tk = get_tk\n\n      unless eq_tk.kind_of?(TkASSIGN)\n        unget_tk(eq_tk)\n        return\n      end\n\n\n      nest = 0\n      get_tkread\n\n      tk = get_tk\n      if tk.kind_of? TkGT\n        unget_tk(tk)\n        unget_tk(eq_tk)\n        return\n      end\n\n      loop do\n        puts(\"Param: #{tk}, #{@scanner.continue} \" +\n          \"#{@scanner.lex_state} #{nest}\")  if $DEBUG\n\n        case tk\n        when TkSEMICOLON\n          break\n        when TkLPAREN, TkfLPAREN\n          nest += 1\n        when TkRPAREN\n          nest -= 1\n        when TkCOMMENT\n          if nest <= 0 && @scanner.lex_state == EXPR_END\n            unget_tk(tk)\n            break\n          end\n        when TkNL\n          if (@scanner.lex_state == EXPR_END and nest <= 0) || !@scanner.continue\n            unget_tk(tk)\n            break\n          end\n        end\n        tk = get_tk\n      end\n\n      res = get_tkread.tr(\"\\n\", \" \").strip\n      res = \"\" if res == \";\"\n      con = Constant.new(name, res, comment)\n      read_documentation_modifiers(con, CONSTANT_MODIFIERS)\n      if con.document_self\n\tcontainer.add_constant(con)\n      end\n    end\n\n    def parse_method(container, single, tk, comment)\n      progress(\".\")\n      @stats.num_methods += 1\n      line_no = tk.line_no\n      column  = tk.char_no\n      \n      start_collecting_tokens\n      add_token(tk)\n      add_token_listener(self)\n      \n      @scanner.instance_eval{@lex_state = EXPR_FNAME}\n      skip_tkspace(false)\n      name_t = get_tk\n      back_tk = skip_tkspace\n      meth = nil\n      added_container = false\n\n      dot = get_tk\n      if dot.kind_of?(TkDOT) or dot.kind_of?(TkCOLON2)\n\t@scanner.instance_eval{@lex_state = EXPR_FNAME}\n\tskip_tkspace\n\tname_t2 = get_tk\n\tcase name_t\n\twhen TkSELF\n\t  name = name_t2.name\n\twhen TkCONSTANT\n          name = name_t2.name\n          prev_container = container\n          container = container.find_module_named(name_t.name)\n          if !container\n            added_container = true\n            obj = name_t.name.split(\"::\").inject(Object) do |state, item|\n              state.const_get(item)\n            end rescue nil\n\n            type = obj.class == Class ? NormalClass : NormalModule\n            if not [Class, Module].include?(obj.class)\n              warn(\"Couldn't find #{name_t.name}. Assuming it's a module\")\n            end\n\n            if type == NormalClass then\n              container = prev_container.add_class(type, name_t.name, obj.superclass.name)\n            else\n              container = prev_container.add_module(type, name_t.name)\n            end\n          end\n\telse\n\t  # warn(\"Unexpected token '#{name_t2.inspect}'\")\n\t  # break\n          skip_method(container)\n          return\n\tend\n\tmeth =  AnyMethod.new(get_tkread, name)\n        meth.singleton = true\n      else\n\tunget_tk dot\n\tback_tk.reverse_each do\n\t  |tk|\n\t  unget_tk tk\n\tend\n\tname = name_t.name\n\n        meth =  AnyMethod.new(get_tkread, name)\n        meth.singleton = (single == SINGLE)\n      end\n\n      remove_token_listener(self)\n\n      meth.start_collecting_tokens\n      indent = TkSPACE.new(1,1)\n      indent.set_text(\" \" * column)\n\n      meth.add_tokens([TkCOMMENT.new(line_no,\n                                     1,\n                                     \"# File #{@top_level.file_absolute_name}, line #{line_no}\"),\n                        NEWLINE_TOKEN,\n                        indent])\n\n      meth.add_tokens(@token_stream)\n\n      add_token_listener(meth)\n\n      @scanner.instance_eval{@continue = false}\n      parse_method_parameters(meth)\n\n      if meth.document_self\n        container.add_method(meth)\n      elsif added_container\n        container.document_self = false\n      end\n\n      # Having now read the method parameters and documentation modifiers, we\n      # now know whether we have to rename #initialize to ::new\n\n      if name == \"initialize\" && !meth.singleton\n        if meth.dont_rename_initialize\n          meth.visibility = :protected\n        else\n          meth.singleton = true\n          meth.name = \"new\"\n          meth.visibility = :public\n        end\n      end\n      \n      parse_statements(container, single, meth)\n      \n      remove_token_listener(meth)\n\n      # Look for a 'call-seq' in the comment, and override the\n      # normal parameter stuff\n\n      if comment.sub!(/:?call-seq:(.*?)^\\s*\\#?\\s*$/m, '')\n        seq = $1\n        seq.gsub!(/^\\s*\\#\\s*/, '')\n        meth.call_seq = seq\n      end\n      \n      meth.comment = comment\n\n    end\n    \n    def skip_method(container)\n      meth =  AnyMethod.new(\"\", \"anon\")\n      parse_method_parameters(meth)\n      parse_statements(container, false, meth)\n    end\n    \n    # Capture the method's parameters. Along the way,\n    # look for a comment containing \n    #\n    #    # yields: ....\n    #\n    # and add this as the block_params for the method\n\n    def parse_method_parameters(method)\n      res = parse_method_or_yield_parameters(method)\n      res = \"(\" + res + \")\" unless res[0] == ?(\n      method.params = res unless method.params\n      if method.block_params.nil?\n          skip_tkspace(false)\n\t  read_documentation_modifiers(method, METHOD_MODIFIERS)\n      end\n    end\n\n    def parse_method_or_yield_parameters(method=nil, modifiers=METHOD_MODIFIERS)\n      skip_tkspace(false)\n      tk = get_tk\n\n      # Little hack going on here. In the statement\n      #  f = 2*(1+yield)\n      # We see the RPAREN as the next token, so we need\n      # to exit early. This still won't catch all cases\n      # (such as \"a = yield + 1\"\n      end_token = case tk\n                  when TkLPAREN, TkfLPAREN\n                    TkRPAREN\n                  when TkRPAREN\n                    return \"\"\n                  else\n                    TkNL\n                  end\n      nest = 0\n\n      loop do\n        puts(\"Param: #{tk.inspect}, #{@scanner.continue} \" +\n          \"#{@scanner.lex_state} #{nest}\")  if $DEBUG\n        case tk\n        when TkSEMICOLON\n          break\n        when TkLBRACE\n          nest += 1\n        when TkRBRACE\n          # we might have a.each {|i| yield i }\n          unget_tk(tk) if nest.zero?\n          nest -= 1\n          break if nest <= 0\n        when TkLPAREN, TkfLPAREN\n          nest += 1\n        when end_token\n          if end_token == TkRPAREN\n            nest -= 1\n            break if @scanner.lex_state == EXPR_END and nest <= 0\n          else\n            break unless @scanner.continue\n          end\n        when method && method.block_params.nil? && TkCOMMENT\n\t  unget_tk(tk)\n\t  read_documentation_modifiers(method, modifiers)\n        end\n        tk = get_tk\n      end\n      res = get_tkread.tr(\"\\n\", \" \").strip\n      res = \"\" if res == \";\"\n      res\n    end\n\n    # skip the var [in] part of a 'for' statement\n    def skip_for_variable\n      skip_tkspace(false)\n      tk = get_tk\n      skip_tkspace(false)\n      tk = get_tk\n      unget_tk(tk) unless tk.kind_of?(TkIN)\n    end\n\n    # while, until, and for have an optional \n    def skip_optional_do_after_expression\n      skip_tkspace(false)\n      tk = get_tk\n      case tk\n      when TkLPAREN, TkfLPAREN\n        end_token = TkRPAREN\n      else\n        end_token = TkNL\n      end\n\n      nest = 0\n      @scanner.instance_eval{@continue = false}\n\n      loop do\n        puts(\"\\nWhile: #{tk}, #{@scanner.continue} \" +\n          \"#{@scanner.lex_state} #{nest}\") if $DEBUG\n        case tk\n        when TkSEMICOLON\n          break\n        when TkLPAREN, TkfLPAREN\n          nest += 1\n        when TkDO\n          break if nest.zero?\n        when end_token\n          if end_token == TkRPAREN\n            nest -= 1\n            break if @scanner.lex_state == EXPR_END and nest.zero?\n          else\n            break unless @scanner.continue\n          end\n        end\n        tk = get_tk\n      end\n      skip_tkspace(false)\n      if peek_tk.kind_of? TkDO\n        get_tk\n      end\n    end\n    \n    # Return a superclass, which can be either a constant\n    # of an expression\n\n    def get_class_specification\n      tk = get_tk\n      return \"self\" if tk.kind_of?(TkSELF)\n        \n      res = \"\"\n      while tk.kind_of?(TkCOLON2) ||\n          tk.kind_of?(TkCOLON3)   ||\n          tk.kind_of?(TkCONSTANT)   \n        \n        res += tk.text\n        tk = get_tk\n      end\n\n      unget_tk(tk)\n      skip_tkspace(false)\n\n      get_tkread # empty out read buffer\n\n      tk = get_tk\n\n      case tk\n      when TkNL, TkCOMMENT, TkSEMICOLON\n        unget_tk(tk)\n        return res\n      end\n\n      res += parse_call_parameters(tk)\n      res\n    end\n\n    def parse_call_parameters(tk)\n\n      end_token = case tk\n                  when TkLPAREN, TkfLPAREN\n                    TkRPAREN\n                  when TkRPAREN\n                    return \"\"\n                  else\n                    TkNL\n                  end\n      nest = 0\n\n      loop do\n        puts(\"Call param: #{tk}, #{@scanner.continue} \" +\n          \"#{@scanner.lex_state} #{nest}\") if $DEBUG\n        case tk\n        when TkSEMICOLON\n          break\n        when TkLPAREN, TkfLPAREN\n          nest += 1\n        when end_token\n          if end_token == TkRPAREN\n            nest -= 1\n            break if @scanner.lex_state == EXPR_END and nest <= 0\n          else\n            break unless @scanner.continue\n          end\n        when TkCOMMENT\n\t  unget_tk(tk)\n\t  break\n        end\n        tk = get_tk\n      end\n      res = get_tkread.tr(\"\\n\", \" \").strip\n      res = \"\" if res == \";\"\n      res\n    end\n\n\n    # Parse a constant, which might be qualified by\n    # one or more class or module names\n\n    def get_constant\n      res = \"\"\n      skip_tkspace(false)\n      tk = get_tk\n\n      while tk.kind_of?(TkCOLON2) ||\n          tk.kind_of?(TkCOLON3)   ||\n          tk.kind_of?(TkCONSTANT)          \n        \n        res += tk.text\n        tk = get_tk\n      end\n\n#      if res.empty?\n#        warn(\"Unexpected token #{tk} in constant\")\n#      end \n      unget_tk(tk)\n      res\n    end\n\n    # Get a constant that may be surrounded by parens\n    \n    def get_constant_with_optional_parens\n      skip_tkspace(false)\n      nest = 0\n      while (tk = peek_tk).kind_of?(TkLPAREN)  || tk.kind_of?(TkfLPAREN)\n        get_tk\n        skip_tkspace(true)\n        nest += 1\n      end\n\n      name = get_constant\n\n      while nest > 0\n        skip_tkspace(true)\n        tk = get_tk\n        nest -= 1 if tk.kind_of?(TkRPAREN)\n      end\n      name\n    end\n\n    # Directives are modifier comments that can appear after class, module,\n    # or method names. For example\n    #\n    #   def fred    # :yields:  a, b\n    #\n    # or\n    #\n    #   class SM  # :nodoc:\n    #\n    # we return the directive name and any parameters as a two element array\n    \n    def read_directive(allowed)\n      tk = get_tk\n      puts \"directive: #{tk.inspect}\" if $DEBUG\n      result = nil\n      if tk.kind_of?(TkCOMMENT) \n        if tk.text =~ /\\s*:?(\\w+):\\s*(.*)/\n          directive = $1.downcase\n          if allowed.include?(directive)\n            result = [directive, $2]\n          end\n        end\n      else\n        unget_tk(tk)\n      end\n      result\n    end\n\n    \n    def read_documentation_modifiers(context, allow)\n      dir = read_directive(allow)\n\n      case dir[0]\n\n      when \"notnew\", \"not_new\", \"not-new\"\n        context.dont_rename_initialize = true\n\n      when \"nodoc\"\n        context.document_self = false\n\tif dir[1].downcase == \"all\"\n\t  context.document_children = false\n\tend\n\n      when \"doc\"\n        context.document_self = true\n        context.force_documentation = true\n\n      when \"yield\", \"yields\"\n        unless context.params.nil?\n          context.params.sub!(/(,|)\\s*&\\w+/,'') # remove parameter &proc\n        end\n\tcontext.block_params = dir[1]\n\n      when \"arg\", \"args\"\n        context.params = dir[1]\n      end if dir\n    end\n\n    \n    # Look for directives in a normal comment block:\n    #\n    #   #--       - don't display comment from this point forward\n    #  \n    #\n    # This routine modifies it's parameter\n\n    def look_for_directives_in(context, comment)\n\n      preprocess = SM::PreProcess.new(@input_file_name,\n                                      @options.rdoc_include)\n\n      preprocess.handle(comment) do |directive, param|\n        case directive\n        when \"stopdoc\"\n          context.stop_doc\n          \"\"\n        when \"startdoc\"\n          context.start_doc\n          context.force_documentation = true\n          \"\"\n\n        when \"enddoc\"\n          #context.done_documenting = true\n          #\"\"\n          throw :enddoc\n\n        when \"main\"\n          options = Options.instance\n          options.main_page = param\n\t  \"\"\n\n        when \"title\"\n          options = Options.instance\n          options.title = param\n          \"\"\n\n        when \"section\"\n          context.set_current_section(param, comment)\n          comment.replace(\"\") # 1.8 doesn't support #clear\n          break \n        else\n          warn \"Unrecognized directive '#{directive}'\"\n          break\n        end\n      end\n\n      remove_private_comments(comment)\n    end\n\n    def remove_private_comments(comment)\n      comment.gsub!(/^#--.*?^#\\+\\+/m, '')\n      comment.sub!(/^#--.*/m, '')\n    end\n\n\n\n    def get_symbol_or_name\n      tk = get_tk\n      case tk\n      when  TkSYMBOL\n        tk.text.sub(/^:/, '')\n      when TkId, TkOp\n        tk.name\n      when TkSTRING\n        tk.text\n      else\n        raise \"Name or symbol expected (got #{tk})\"\n      end\n    end\n    \n    def parse_alias(context, single, tk, comment)\n      skip_tkspace\n      if (peek_tk.kind_of? TkLPAREN)\n        get_tk\n        skip_tkspace\n      end\n      new_name = get_symbol_or_name\n      @scanner.instance_eval{@lex_state = EXPR_FNAME}\n      skip_tkspace\n      if (peek_tk.kind_of? TkCOMMA)\n        get_tk\n        skip_tkspace\n      end\n      old_name = get_symbol_or_name\n\n      al = Alias.new(get_tkread, old_name, new_name, comment)\n      read_documentation_modifiers(al, ATTR_MODIFIERS)\n      if al.document_self\n\tcontext.add_alias(al)\n      end\n    end\n\n    def parse_yield_parameters\n      parse_method_or_yield_parameters\n    end\n\n  def parse_yield(context, single, tk, method)\n    if method.block_params.nil?\n      get_tkread\n      @scanner.instance_eval{@continue = false}\n      method.block_params = parse_yield_parameters\n    end\n  end\n\n  def parse_require(context, comment)\n    skip_tkspace_comment\n    tk = get_tk\n    if tk.kind_of? TkLPAREN\n      skip_tkspace_comment\n      tk = get_tk\n    end\n\n    name = nil\n    case tk\n    when TkSTRING\n      name = tk.text\n#    when TkCONSTANT, TkIDENTIFIER, TkIVAR, TkGVAR\n#      name = tk.name\n    when TkDSTRING\n      warn \"Skipping require of dynamic string: #{tk.text}\"\n #   else\n #     warn \"'require' used as variable\"\n    end\n    if name\n      context.add_require(Require.new(name, comment))\n    else\n      unget_tk(tk)\n    end\n  end\n\n  def parse_include(context, comment)\n    loop do\n      skip_tkspace_comment\n      name = get_constant_with_optional_parens\n      unless name.empty?\n        context.add_include(Include.new(name, comment))\n      end\n      return unless peek_tk.kind_of?(TkCOMMA)\n      get_tk\n    end\n  end\n\n    def get_bool\n      skip_tkspace\n      tk = get_tk\n      case tk\n      when TkTRUE\n        true\n      when TkFALSE, TkNIL\n        false\n      else\n        unget_tk tk\n        true\n      end\n    end\n\n    def parse_attr(context, single, tk, comment)\n      args = parse_symbol_arg(1)\n      if args.size > 0\n\tname = args[0]\n        rw = \"R\"\n        skip_tkspace(false)\n        tk = get_tk\n        if tk.kind_of? TkCOMMA\n          rw = \"RW\" if get_bool\n        else\n          unget_tk tk\n        end\n\tatt = Attr.new(get_tkread, name, rw, comment)\n\tread_documentation_modifiers(att, ATTR_MODIFIERS)\n\tif att.document_self\n\t  context.add_attribute(att)\n\tend\n      else\n\twarn(\"'attr' ignored - looks like a variable\")\n      end    \n\n    end\n\n    def parse_visibility(container, single, tk)\n      singleton = (single == SINGLE)\n      vis = case tk.name\n            when \"private\"   then :private\n            when \"protected\" then :protected\n            when \"public\"    then :public\n            when \"private_class_method\"\n              singleton = true\n              :private\n            when \"public_class_method\"\n              singleton = true\n              :public\n            else raise \"Invalid visibility: #{tk.name}\"\n            end\n            \n      skip_tkspace_comment(false)\n      case peek_tk\n        # Ryan Davis suggested the extension to ignore modifiers, because he\n        # often writes\n        #\n        #   protected unless $TESTING\n        #\n      when TkNL, TkUNLESS_MOD, TkIF_MOD\n#        error(\"Missing argument\") if singleton        \n        container.ongoing_visibility = vis\n      else\n        args = parse_symbol_arg\n        container.set_visibility_for(args, vis, singleton)\n      end\n    end\n\n    def parse_attr_accessor(context, single, tk, comment)\n      args = parse_symbol_arg\n      read = get_tkread\n      rw = \"?\"\n\n      # If nodoc is given, don't document any of them\n\n      tmp = CodeObject.new\n      read_documentation_modifiers(tmp, ATTR_MODIFIERS)\n      return unless tmp.document_self\n\n      case tk.name\n      when \"attr_reader\"   then rw = \"R\"\n      when \"attr_writer\"   then rw = \"W\"\n      when \"attr_accessor\" then rw = \"RW\"\n      else\n        rw = @options.extra_accessor_flags[tk.name]\n      end\n      \n      for name in args\n\tatt = Attr.new(get_tkread, name, rw, comment)\n        context.add_attribute(att)\n      end    \n    end\n\n    def skip_tkspace_comment(skip_nl = true)\n      loop do\n        skip_tkspace(skip_nl)\n        return unless peek_tk.kind_of? TkCOMMENT\n        get_tk\n      end\n    end\n\n    def parse_symbol_arg(no = nil)\n\n      args = []\n      skip_tkspace_comment\n      case tk = get_tk\n      when TkLPAREN\n\tloop do\n\t  skip_tkspace_comment\n\t  if tk1 = parse_symbol_in_arg\n\t    args.push tk1\n\t    break if no and args.size >= no\n\t  end\n\t  \n\t  skip_tkspace_comment\n\t  case tk2 = get_tk\n\t  when TkRPAREN\n\t    break\n\t  when TkCOMMA\n\t  else\n           warn(\"unexpected token: '#{tk2.inspect}'\") if $DEBUG\n\t    break\n\t  end\n\tend\n      else\n\tunget_tk tk\n\tif tk = parse_symbol_in_arg\n\t  args.push tk\n\t  return args if no and args.size >= no\n\tend\n\n\tloop do\n#\t  skip_tkspace_comment(false)\n\t  skip_tkspace(false)\n\n\t  tk1 = get_tk\n\t  unless tk1.kind_of?(TkCOMMA) \n\t    unget_tk tk1\n\t    break\n\t  end\n\t  \n\t  skip_tkspace_comment\n\t  if tk = parse_symbol_in_arg\n\t    args.push tk\n\t    break if no and args.size >= no\n\t  end\n\tend\n      end\n      args\n    end\n\n    def parse_symbol_in_arg\n      case tk = get_tk\n      when TkSYMBOL\n        tk.text.sub(/^:/, '')\n      when TkSTRING\n\teval @read[-1]\n      else\n\twarn(\"Expected symbol or string, got #{tk.inspect}\") if $DEBUG\n\tnil\n      end\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/rdoc/parsers/parse_simple.rb",
    "content": "# Parse a non-source file. We basically take the whole thing \n# as one big comment. If the first character in the file\n# is '#', we strip leading pound signs.\n\n\nrequire \"rdoc/code_objects\"\nrequire \"rdoc/markup/simple_markup/preprocess\"\n\nmodule RDoc\n  # See rdoc/parsers/parse_c.rb\n\n  class SimpleParser\n    \n    # prepare to parse a plain file\n    def initialize(top_level, file_name, body, options, stats)\n      \n      preprocess = SM::PreProcess.new(file_name, options.rdoc_include)\n      \n      preprocess.handle(body) do |directive, param|\n        $stderr.puts \"Unrecognized directive '#{directive}' in #{file_name}\"\n      end\n      \n      @body = body\n      @options = options\n      @top_level = top_level\n    end\n    \n    # Extract the file contents and attach them to the toplevel as a\n    # comment\n    \n    def scan\n      #    @body.gsub(/^(\\s\\n)+/, '')\n      @top_level.comment = remove_private_comments(@body)\n      @top_level\n    end\n\n    def remove_private_comments(comment)\n      comment.gsub(/^--.*?^\\+\\+/m, '').sub(/^--.*/m, '')\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/parsers/parserfactory.rb",
    "content": "require \"rdoc/parsers/parse_simple\"\n\nmodule RDoc\n\n  # A parser is simple a class that implements\n  #\n  #   #initialize(file_name, body, options)\n  #\n  # and\n  #\n  #   #scan\n  #\n  # The initialize method takes a file name to be used, the body of the\n  # file, and an RDoc::Options object. The scan method is then called\n  # to return an appropriately parsed TopLevel code object.\n  #\n  # The ParseFactory is used to redirect to the correct parser given a filename\n  # extension. This magic works because individual parsers have to register \n  # themselves with us as they are loaded in. The do this using the following\n  # incantation\n  #\n  #\n  #    require \"rdoc/parsers/parsefactory\"\n  #    \n  #    module RDoc\n  #    \n  #      class XyzParser\n  #        extend ParseFactory                  <<<<\n  #        parse_files_matching /\\.xyz$/        <<<<\n  #    \n  #        def initialize(file_name, body, options)\n  #          ...\n  #        end\n  #    \n  #        def scan\n  #          ...\n  #        end\n  #      end\n  #    end\n  #\n  # Just to make life interesting, if we suspect a plain text file, we\n  # also look for a shebang line just in case it's a potential\n  # shell script\n\n\n\n  module ParserFactory\n\n    @@parsers = []\n\n    Parsers = Struct.new(:regexp, :parser)\n\n    # Record the fact that a particular class parses files that\n    # match a given extension\n\n    def parse_files_matching(regexp)\n      @@parsers.unshift Parsers.new(regexp, self)\n    end\n\n    # Return a parser that can handle a particular extension\n\n    def ParserFactory.can_parse(file_name)\n      @@parsers.find {|p| p.regexp.match(file_name) }\n    end\n\n    # Alias an extension to another extension. After this call,\n    # files ending \"new_ext\" will be parsed using the same parser\n    # as \"old_ext\"\n\n    def ParserFactory.alias_extension(old_ext, new_ext)\n      parser = ParserFactory.can_parse(\"xxx.#{old_ext}\")\n      return false unless parser\n      @@parsers.unshift Parsers.new(Regexp.new(\"\\\\.#{new_ext}$\"), parser.parser)\n      true\n    end\n\n    # Find the correct parser for a particular file name. Return a \n    # SimpleParser for ones that we don't know\n\n    def ParserFactory.parser_for(top_level, file_name, body, options, stats)\n      # If no extension, look for shebang\n      if file_name !~ /\\.\\w+$/ && body =~ %r{\\A#!(.+)}\n        shebang = $1\n        case shebang\n        when %r{env\\s+ruby}, %r{/ruby}\n          file_name = \"dummy.rb\"\n        end\n      end\n      parser_description = can_parse(file_name)\n      if parser_description\n        parser = parser_description.parser \n      else\n        parser = SimpleParser\n      end\n\n      parser.new(top_level, file_name, body, options, stats)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/rdoc.rb",
    "content": "# See README.\n#\n \n\nVERSION_STRING = %{RDoc V1.0.1 - 20041108}\n\n\nrequire 'rdoc/parsers/parse_rb.rb'\nrequire 'rdoc/parsers/parse_c.rb'\nrequire 'rdoc/parsers/parse_f95.rb'\n\nrequire 'rdoc/parsers/parse_simple.rb'\nrequire 'rdoc/options'\n\nrequire 'rdoc/diagram'\n\nrequire 'find'\nrequire 'ftools'\nrequire 'time'\n\n# We put rdoc stuff in the RDoc module to avoid namespace\n# clutter.\n#\n# ToDo: This isn't universally true.\n#\n# :include: README\n\nmodule RDoc\n\n  # Name of the dotfile that contains the description of files to be\n  # processed in the current directory\n  DOT_DOC_FILENAME = \".document\"\n\n  # Simple stats collector\n  class Stats\n    attr_accessor :num_files, :num_classes, :num_modules, :num_methods\n    def initialize\n      @num_files = @num_classes = @num_modules = @num_methods = 0\n      @start = Time.now\n    end\n    def print\n      puts \"Files:   #@num_files\"\n      puts \"Classes: #@num_classes\"\n      puts \"Modules: #@num_modules\"\n      puts \"Methods: #@num_methods\"\n      puts \"Elapsed: \" + sprintf(\"%0.3fs\", Time.now - @start)\n    end\n  end\n\n\n  # Exception thrown by any rdoc error. Only the #message part is\n  # of use externally.\n\n  class RDocError < Exception\n  end\n\n  # Encapsulate the production of rdoc documentation. Basically\n  # you can use this as you would invoke rdoc from the command\n  # line:\n  #\n  #    rdoc = RDoc::RDoc.new\n  #    rdoc.document(args)\n  #\n  # where _args_ is an array of strings, each corresponding to\n  # an argument you'd give rdoc on the command line. See rdoc/rdoc.rb \n  # for details.\n  \n  class RDoc\n\n    ##\n    # This is the list of output generators that we\n    # support\n    \n    Generator = Struct.new(:file_name, :class_name, :key)\n    \n    GENERATORS = {}\n    $:.collect {|d|\n      File::expand_path(d)\n    }.find_all {|d|\n      File::directory?(\"#{d}/rdoc/generators\")\n    }.each {|dir|\n      Dir::entries(\"#{dir}/rdoc/generators\").each {|gen|\n        next unless /(\\w+)_generator.rb$/ =~ gen\n        type = $1\n        unless GENERATORS.has_key? type\n          GENERATORS[type] = Generator.new(\"rdoc/generators/#{gen}\",\n                                           \"#{type.upcase}Generator\".intern,\n                                           type)\n        end\n      }\n    }                                                    \n\n    #######\n    private\n    #######\n\n    ##\n    # Report an error message and exit\n    \n    def error(msg)\n      raise RDocError.new(msg)\n    end\n    \n    ##\n    # Create an output dir if it doesn't exist. If it does\n    # exist, but doesn't contain the flag file <tt>created.rid</tt>\n    # then we refuse to use it, as we may clobber some\n    # manually generated documentation\n    \n    def setup_output_dir(op_dir, force)\n      flag_file = output_flag_file(op_dir)\n      if File.exist?(op_dir)\n        unless File.directory?(op_dir)\n          error \"'#{op_dir}' exists, and is not a directory\" \n        end\n        begin\n          created = File.read(flag_file)\n        rescue SystemCallError\n          error \"\\nDirectory #{op_dir} already exists, but it looks like it\\n\" +\n            \"isn't an RDoc directory. Because RDoc doesn't want to risk\\n\" +\n            \"destroying any of your existing files, you'll need to\\n\" +\n            \"specify a different output directory name (using the\\n\" +\n            \"--op <dir> option).\\n\\n\"\n        else\n          last = (Time.parse(created) unless force rescue nil)\n        end\n      else\n        File.makedirs(op_dir)\n      end\n      last\n    end\n\n    # Update the flag file in an output directory.\n    def update_output_dir(op_dir, time)\n      File.open(output_flag_file(op_dir), \"w\") {|f| f.puts time.rfc2822 }\n    end\n\n    # Return the path name of the flag file in an output directory.\n    def output_flag_file(op_dir)\n      File.join(op_dir, \"created.rid\")\n    end\n\n    # The .document file contains a list of file and directory name\n    # patterns, representing candidates for documentation. It may\n    # also contain comments (starting with '#')\n    def parse_dot_doc_file(in_dir, filename, options)\n      # read and strip comments\n      patterns = File.read(filename).gsub(/#.*/, '')\n\n      result = []\n\n      patterns.split.each do |patt|\n        candidates = Dir.glob(File.join(in_dir, patt))\n        result.concat(normalized_file_list(options,  candidates))\n      end\n      result\n    end\n\n\n    # Given a list of files and directories, create a list\n    # of all the Ruby files they contain. \n    #\n    # If +force_doc+ is true, we always add the given files.\n    # If false, only add files that we guarantee we can parse\n    # It is true when looking at files given on the command line,\n    # false when recursing through subdirectories. \n    #\n    # The effect of this is that if you want a file with a non-\n    # standard extension parsed, you must name it explicity.\n    #\n\n    def normalized_file_list(options, relative_files, force_doc = false, exclude_pattern=nil)\n      file_list = []\n\n      relative_files.each do |rel_file_name|\n        next if exclude_pattern && exclude_pattern =~ rel_file_name\n        stat = File.stat(rel_file_name)\n        case type = stat.ftype\n        when \"file\"\n          next if @last_created and stat.mtime < @last_created\n          file_list << rel_file_name.sub(/^\\.\\//, '') if force_doc || ParserFactory.can_parse(rel_file_name)\n        when \"directory\"\n          next if rel_file_name == \"CVS\" || rel_file_name == \".svn\"\n          dot_doc = File.join(rel_file_name, DOT_DOC_FILENAME)\n          if File.file?(dot_doc)\n            file_list.concat(parse_dot_doc_file(rel_file_name, dot_doc, options))\n          else\n            file_list.concat(list_files_in_directory(rel_file_name, options))\n          end\n        else\n          raise RDocError.new(\"I can't deal with a #{type} #{rel_file_name}\")\n        end\n      end\n      file_list\n    end\n\n    # Return a list of the files to be processed in\n    # a directory. We know that this directory doesn't have\n    # a .document file, so we're looking for real files. However\n    # we may well contain subdirectories which must\n    # be tested for .document files\n    def list_files_in_directory(dir, options)\n      normalized_file_list(options, Dir.glob(File.join(dir, \"*\")), false, options.exclude)\n    end\n\n\n    # Parse each file on the command line, recursively entering\n    # directories\n\n    def parse_files(options)\n \n      file_info = []\n\n      files = options.files\n      files = [\".\"] if files.empty?\n\n      file_list = normalized_file_list(options, files, true)\n\n      file_list.each do |fn|\n        $stderr.printf(\"\\n%35s: \", File.basename(fn)) unless options.quiet\n        \n        content = File.open(fn, \"r\") {|f| f.read}\n\n        top_level = TopLevel.new(fn)\n        parser = ParserFactory.parser_for(top_level, fn, content, options, @stats)\n        file_info << parser.scan\n        @stats.num_files += 1\n      end\n\n      file_info\n    end\n\n\n    public\n\n    ###################################################################\n    #\n    # Format up one or more files according to the given arguments.\n    # For simplicity, _argv_ is an array of strings, equivalent to the\n    # strings that would be passed on the command line. (This isn't a\n    # coincidence, as we _do_ pass in ARGV when running\n    # interactively). For a list of options, see rdoc/rdoc.rb. By\n    # default, output will be stored in a directory called +doc+ below\n    # the current directory, so make sure you're somewhere writable\n    # before invoking.\n    #\n    # Throws: RDocError on error\n\n    def document(argv)\n\n      TopLevel::reset\n\n      @stats = Stats.new\n\n      options = Options.instance\n      options.parse(argv, GENERATORS)\n\n      @last_created = nil\n      unless options.all_one_file\n        @last_created = setup_output_dir(options.op_dir, options.force_update)\n      end\n      start_time = Time.now\n\n      file_info = parse_files(options)\n\n      if file_info.empty?\n        $stderr.puts \"\\nNo newer files.\" unless options.quiet\n      else\n        gen = options.generator\n\n        $stderr.puts \"\\nGenerating #{gen.key.upcase}...\" unless options.quiet\n\n        require gen.file_name\n\n        gen_class = Generators.const_get(gen.class_name)\n        gen = gen_class.for(options)\n\n        pwd = Dir.pwd\n\n        Dir.chdir(options.op_dir)  unless options.all_one_file\n\n        begin\n          Diagram.new(file_info, options).draw if options.diagram\n          gen.generate(file_info)\n          update_output_dir(\".\", start_time)\n        ensure\n          Dir.chdir(pwd)\n        end\n      end\n\n      unless options.quiet\n        puts\n        @stats.print\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/rdoc/ri/ri_cache.rb",
    "content": "module RI\n\n  class ClassEntry\n\n    attr_reader :name\n    attr_reader :path_names\n    \n    def initialize(path_name, name, in_class)\n      @path_names = [ path_name ]\n      @name = name\n      @in_class = in_class\n      @class_methods    = []\n      @instance_methods = []\n      @inferior_classes = []\n    end\n\n    # We found this class in more tha one place, so add\n    # in the name from there.\n    def add_path(path)\n      @path_names << path\n    end\n\n    # read in our methods and any classes\n    # and modules in our namespace. Methods are\n    # stored in files called name-c|i.yaml,\n    # where the 'name' portion is the external\n    # form of the method name and the c|i is a class|instance\n    # flag\n\n    def load_from(dir)\n      Dir.foreach(dir) do |name|\n        next if name =~ /^\\./\n\n        # convert from external to internal form, and\n        # extract the instance/class flag\n\n        if name =~ /^(.*?)-(c|i).yaml$/\n          external_name = $1\n          is_class_method = $2 == \"c\"\n          internal_name = RiWriter.external_to_internal(external_name)\n          list = is_class_method ? @class_methods : @instance_methods\n          path = File.join(dir, name)\n          list << MethodEntry.new(path, internal_name, is_class_method, self)\n        else\n          full_name = File.join(dir, name)\n          if File.directory?(full_name)\n            inf_class = @inferior_classes.find {|c| c.name == name }\n            if inf_class\n              inf_class.add_path(full_name)\n            else\n              inf_class = ClassEntry.new(full_name, name, self)\n              @inferior_classes << inf_class\n            end\n            inf_class.load_from(full_name)\n          end\n        end\n      end\n    end\n\n    # Return a list of any classes or modules that we contain\n    # that match a given string\n\n    def contained_modules_matching(name)\n      @inferior_classes.find_all {|c| c.name[name]}\n    end\n\n    def classes_and_modules\n      @inferior_classes\n    end\n\n    # Return an exact match to a particular name\n    def contained_class_named(name)\n      @inferior_classes.find {|c| c.name == name}\n    end\n\n    # return the list of local methods matching name\n    # We're split into two because we need distinct behavior\n    # when called from the _toplevel_\n    def methods_matching(name, is_class_method)\n      local_methods_matching(name, is_class_method)\n    end\n\n    # Find methods matching 'name' in ourselves and in\n    # any classes we contain\n    def recursively_find_methods_matching(name, is_class_method)\n      res = local_methods_matching(name, is_class_method)\n      @inferior_classes.each do |c|\n        res.concat(c.recursively_find_methods_matching(name, is_class_method))\n      end\n      res\n    end\n\n\n    # Return our full name\n    def full_name\n      res = @in_class.full_name\n      res << \"::\" unless res.empty?\n      res << @name\n    end\n\n    # Return a list of all out method names\n    def all_method_names\n      res = @class_methods.map {|m| m.full_name }\n      @instance_methods.each {|m| res << m.full_name}\n      res\n    end\n\n    private\n\n    # Return a list of all our methods matching a given string.\n    # Is +is_class_methods+ if 'nil', we don't care if the method\n    # is a class method or not, otherwise we only return\n    # those methods that match\n    def local_methods_matching(name, is_class_method)\n\n      list = case is_class_method\n             when nil then  @class_methods + @instance_methods\n             when true then @class_methods\n             when false then @instance_methods\n             else fail \"Unknown is_class_method: #{is_class_method.inspect}\"\n             end\n\n      list.find_all {|m| m.name;  m.name[name]}\n    end\n  end\n\n  # A TopLevelEntry is like a class entry, but when asked to search\n  # for methods searches all classes, not just itself\n\n  class TopLevelEntry < ClassEntry\n    def methods_matching(name, is_class_method)\n      res = recursively_find_methods_matching(name, is_class_method)\n    end\n\n    def full_name\n      \"\"\n    end\n\n    def module_named(name)\n      \n    end\n\n  end\n\n  class MethodEntry\n    attr_reader :name\n    attr_reader :path_name\n\n    def initialize(path_name, name, is_class_method, in_class)\n      @path_name = path_name\n      @name = name\n      @is_class_method = is_class_method\n      @in_class = in_class\n    end\n\n    def full_name\n      res = @in_class.full_name\n      unless res.empty?\n        if @is_class_method\n          res << \"::\"\n        else\n          res << \"#\"\n        end\n      end\n      res << @name\n    end\n  end\n\n  # We represent everything know about all 'ri' files\n  # accessible to this program\n\n  class RiCache\n\n    attr_reader :toplevel\n\n    def initialize(dirs)\n      # At the top level we have a dummy module holding the\n      # overall namespace\n      @toplevel = TopLevelEntry.new('', '::', nil)\n\n      dirs.each do |dir|\n        @toplevel.load_from(dir)\n      end\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/ri/ri_descriptions.rb",
    "content": "require 'yaml'\nrequire 'rdoc/markup/simple_markup/fragments'\n\n# Descriptions are created by RDoc (in ri_generator) and\n# written out in serialized form into the documentation\n# tree. ri then reads these to generate the documentation\n\nmodule RI\n  class NamedThing\n    attr_reader :name\n    def initialize(name)\n      @name = name\n    end\n    def <=>(other)\n      @name <=> other.name\n    end\n\n    def hash\n      @name.hash\n    end\n\n    def eql?(other)\n      @name.eql?(other)\n    end\n  end\n\n#  Alias          = Struct.new(:old_name, :new_name)\n\n  class AliasName < NamedThing\n  end\n\n  class Attribute < NamedThing\n    attr_reader :rw, :comment\n    def initialize(name, rw, comment)\n      super(name)\n      @rw = rw\n      @comment = comment\n    end\n  end\n\n  class Constant < NamedThing\n    attr_reader :value, :comment\n    def initialize(name, value, comment)\n      super(name)\n      @value = value\n      @comment = comment\n    end\n  end\n\n  class IncludedModule < NamedThing\n  end\n\n\n  class MethodSummary < NamedThing\n    def initialize(name=\"\")\n      super\n    end\n  end\n\n\n\n  class Description\n    attr_accessor :name\n    attr_accessor :full_name\n    attr_accessor :comment\n\n    def serialize\n      self.to_yaml\n    end\n\n    def Description.deserialize(from)\n      YAML.load(from)\n    end\n\n    def <=>(other)\n      @name <=> other.name\n    end\n  end\n  \n  class ModuleDescription < Description\n    \n    attr_accessor :class_methods\n    attr_accessor :instance_methods\n    attr_accessor :attributes\n    attr_accessor :constants\n    attr_accessor :includes\n\n    # merge in another class desscription into this one\n    def merge_in(old)\n      merge(@class_methods, old.class_methods)\n      merge(@instance_methods, old.instance_methods)\n      merge(@attributes, old.attributes)\n      merge(@constants, old.constants)\n      merge(@includes, old.includes)\n      if @comment.nil? || @comment.empty?\n        @comment = old.comment\n      else\n        unless old.comment.nil? or old.comment.empty? then\n          @comment << SM::Flow::RULE.new\n          @comment.concat old.comment\n        end\n      end\n    end\n\n    def display_name\n      \"Module\"\n    end\n\n    # the 'ClassDescription' subclass overrides this\n    # to format up the name of a parent\n    def superclass_string\n      nil\n    end\n\n    private\n\n    def merge(into, from)\n      names = {}\n      into.each {|i| names[i.name] = i }\n      from.each {|i| names[i.name] = i }\n      into.replace(names.keys.sort.map {|n| names[n]})\n    end\n  end\n  \n  class ClassDescription < ModuleDescription\n    attr_accessor :superclass\n\n    def display_name\n      \"Class\"\n    end\n\n    def superclass_string\n      if @superclass && @superclass != \"Object\"\n        @superclass\n      else\n        nil\n      end\n    end\n  end\n\n\n  class MethodDescription < Description\n    \n    attr_accessor :is_class_method\n    attr_accessor :visibility\n    attr_accessor :block_params\n    attr_accessor :is_singleton\n    attr_accessor :aliases\n    attr_accessor :is_alias_for\n    attr_accessor :params\n\n  end\n  \nend\n"
  },
  {
    "path": "lib/rdoc/ri/ri_display.rb",
    "content": "require 'rdoc/ri/ri_util'\nrequire 'rdoc/ri/ri_formatter'\nrequire 'rdoc/ri/ri_options'\n\n\n# This is a kind of 'flag' module. If you want to write your\n# own 'ri' display module (perhaps because you'r writing\n# an IDE or somesuch beast), you simply write a class\n# which implements the various 'display' methods in 'DefaultDisplay',\n# and include the 'RiDisplay' module in that class. \n#\n# To access your class from the command line, you can do\n#\n#    ruby -r <your source file>  ../ri ....\n#\n# If folks _really_ want to do this from the command line,\n# I'll build an option in\n\nmodule RiDisplay\n  @@display_class = nil\n\n  def RiDisplay.append_features(display_class)\n    @@display_class = display_class\n  end\n\n  def RiDisplay.new(*args)\n    @@display_class.new(*args)\n  end\nend\n\n######################################################################\n#\n# A paging display module. Uses the ri_formatter class to do the\n# actual presentation\n#\n\nclass  DefaultDisplay\n\n  include RiDisplay\n\n  def initialize(options)\n    @options = options\n    @formatter = @options.formatter.new(@options, \"     \")\n  end    \n  \n  \n  ######################################################################\n  \n  def display_usage\n    page do\n      RI::Options::OptionList.usage(short_form=true)\n    end\n  end\n\n\n  ######################################################################\n  \n  def display_method_info(method)\n    page do\n      @formatter.draw_line(method.full_name)\n      display_params(method)\n      @formatter.draw_line\n      display_flow(method.comment)\n      if method.aliases && !method.aliases.empty?\n        @formatter.blankline\n        aka = \"(also known as \"\n        aka << method.aliases.map {|a| a.name }.join(\", \") \n        aka << \")\"\n        @formatter.wrap(aka)\n      end\n    end\n  end\n  \n  ######################################################################\n  \n  def display_class_info(klass, ri_reader)\n    page do \n      superclass = klass.superclass_string\n      \n      if superclass\n        superclass = \" < \" + superclass\n      else\n        superclass = \"\"\n      end\n      \n      @formatter.draw_line(klass.display_name + \": \" +\n                           klass.full_name + superclass)\n      \n      display_flow(klass.comment)\n      @formatter.draw_line \n    \n      unless klass.includes.empty?\n        @formatter.blankline\n        @formatter.display_heading(\"Includes:\", 2, \"\")\n        incs = []\n        klass.includes.each do |inc|\n          inc_desc = ri_reader.find_class_by_name(inc.name)\n          if inc_desc\n            str = inc.name + \"(\"\n            str << inc_desc.instance_methods.map{|m| m.name}.join(\", \")\n            str << \")\"\n            incs << str\n          else\n            incs << inc.name\n          end\n      end\n        @formatter.wrap(incs.sort.join(', '))\n      end\n      \n      unless klass.constants.empty?\n        @formatter.blankline\n        @formatter.display_heading(\"Constants:\", 2, \"\")\n        len = 0\n        klass.constants.each { |c| len = c.name.length if c.name.length > len }\n        len += 2\n        klass.constants.each do |c|\n          @formatter.wrap(c.value, \n                          @formatter.indent+((c.name+\":\").ljust(len)))\n        end \n      end\n      \n      unless klass.class_methods.empty?\n        @formatter.blankline\n        @formatter.display_heading(\"Class methods:\", 2, \"\")\n        @formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', '))\n      end\n      \n      unless klass.instance_methods.empty?\n        @formatter.blankline\n        @formatter.display_heading(\"Instance methods:\", 2, \"\")\n        @formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', '))\n      end\n      \n      unless klass.attributes.empty?\n        @formatter.blankline\n        @formatter.wrap(\"Attributes:\", \"\")\n        @formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', '))\n      end\n    end\n  end\n  \n  ######################################################################\n  \n  # Display a list of method names\n  \n  def display_method_list(methods)\n    page do\n      puts \"More than one method matched your request. You can refine\"\n      puts \"your search by asking for information on one of:\\n\\n\"\n      @formatter.wrap(methods.map {|m| m.full_name} .join(\", \"))\n    end\n  end\n  \n  ######################################################################\n  \n  def display_class_list(namespaces)\n    page do\n      puts \"More than one class or module matched your request. You can refine\"\n      puts \"your search by asking for information on one of:\\n\\n\"\n      @formatter.wrap(namespaces.map {|m| m.full_name}.join(\", \"))\n    end\n  end\n  \n  ######################################################################\n\n  def list_known_classes(classes)\n    if classes.empty?\n      warn_no_database\n    else\n      page do \n        @formatter.draw_line(\"Known classes and modules\")\n        @formatter.blankline\n        @formatter.wrap(classes.sort.join(\", \"))\n      end\n    end\n  end\n\n  ######################################################################\n\n  def list_known_names(names)\n    if names.empty?\n      warn_no_database\n    else\n      page do \n        names.each {|n| @formatter.raw_print_line(n)}\n      end\n    end\n  end\n\n  ######################################################################\n\n  private\n\n  ######################################################################\n\n  def page\n    return yield unless pager = setup_pager\n    begin\n      save_stdout = STDOUT.clone\n      STDOUT.reopen(pager)\n      yield\n    ensure\n      STDOUT.reopen(save_stdout)\n      save_stdout.close\n      pager.close\n    end\n  end\n\n  ######################################################################\n\n  def setup_pager\n    unless @options.use_stdout\n      for pager in [ ENV['PAGER'], \"less\", \"more\", 'pager' ].compact.uniq\n        return IO.popen(pager, \"w\") rescue nil\n      end\n      @options.use_stdout = true\n      nil\n    end\n  end\n\n  ######################################################################\n  \n  def display_params(method)\n\n    params = method.params\n\n    if params[0,1] == \"(\"\n      if method.is_singleton\n        params = method.full_name + params\n      else\n        params = method.name + params\n      end\n    end\n    params.split(/\\n/).each do |p|\n      @formatter.wrap(p) \n      @formatter.break_to_newline\n    end\n  end\n  ######################################################################\n  \n  def display_flow(flow)\n    if !flow || flow.empty?\n      @formatter.wrap(\"(no description...)\")\n    else\n      @formatter.display_flow(flow)\n    end\n  end\n\n  ######################################################################\n  \n  def warn_no_database\n    puts \"Before using ri, you need to generate documentation\"\n    puts \"using 'rdoc' with the --ri option\"\n  end\nend  # class RiDisplay\n"
  },
  {
    "path": "lib/rdoc/ri/ri_driver.rb",
    "content": "require 'rdoc/ri/ri_paths'\nrequire 'rdoc/usage'\nrequire 'rdoc/ri/ri_cache'\nrequire 'rdoc/ri/ri_util'\nrequire 'rdoc/ri/ri_reader'\nrequire 'rdoc/ri/ri_formatter'\nrequire 'rdoc/ri/ri_options'\n\n\n######################################################################\n\nclass  RiDriver\n\n  def initialize\n    @options = RI::Options.instance\n\n    args = ARGV\n    if ENV[\"RI\"]\n      args = ENV[\"RI\"].split.concat(ARGV)\n    end\n\n    @options.parse(args)\n\n    path = @options.path\n    report_missing_documentation @options.raw_path if path.empty?\n\n    @ri_reader = RI::RiReader.new(RI::RiCache.new(path))\n    @display   = @options.displayer\n  end\n  \n  # Couldn't find documentation in +path+, so tell the user what to do\n\n  def report_missing_documentation(path)\n    STDERR.puts \"No ri documentation found in:\"\n    path.each do |d|\n      STDERR.puts \"     #{d}\"\n    end\n    STDERR.puts \"\\nWas rdoc run to create documentation?\\n\\n\"\n    RDoc::usage(\"Installing Documentation\")\n  end\n  \n  ######################################################################\n  \n  # If the list of matching methods contains exactly one entry, or\n  # if it contains an entry that exactly matches the requested method,\n  # then display that entry, otherwise display the list of\n  # matching method names\n  \n  def report_method_stuff(requested_method_name, methods)\n    if methods.size == 1\n      method = @ri_reader.get_method(methods[0])\n      @display.display_method_info(method)\n    else\n      entries = methods.find_all {|m| m.name == requested_method_name}\n      if entries.size == 1\n        method = @ri_reader.get_method(entries[0])\n        @display.display_method_info(method)\n      else\n        @display.display_method_list(methods)\n      end\n    end\n  end\n  \n  ######################################################################\n  \n  def report_class_stuff(namespaces)\n    if namespaces.size == 1\n      klass = @ri_reader.get_class(namespaces[0])\n      @display.display_class_info(klass, @ri_reader)\n    else \n#      entries = namespaces.find_all {|m| m.full_name == requested_class_name}\n#      if entries.size == 1\n#        klass = @ri_reader.get_class(entries[0])\n#        @display.display_class_info(klass, @ri_reader)\n#      else\n        @display.display_class_list(namespaces)\n#      end\n    end\n  end\n  \n  ######################################################################\n  \n  \n  def get_info_for(arg)\n    desc = NameDescriptor.new(arg)\n\n    namespaces = @ri_reader.top_level_namespace\n    \n    for class_name in desc.class_names\n      namespaces = @ri_reader.lookup_namespace_in(class_name, namespaces)\n      if namespaces.empty?\n        raise RiError.new(\"Nothing known about #{arg}\")\n      end\n    end\n\n    # at this point, if we have multiple possible namespaces, but one\n    # is an exact match for our requested class, prune down to just it\n\n    full_class_name = desc.full_class_name\n    entries = namespaces.find_all {|m| m.full_name == full_class_name}\n    namespaces = entries if entries.size == 1\n\n    if desc.method_name.nil?\n      report_class_stuff(namespaces)\n    else\n      methods = @ri_reader.find_methods(desc.method_name, \n                                        desc.is_class_method,\n                                        namespaces)\n\n      if methods.empty?\n        raise RiError.new(\"Nothing known about #{arg}\")\n      else\n        report_method_stuff(desc.method_name, methods)\n      end\n    end\n  end\n\n  ######################################################################\n\n  def process_args\n    if @options.list_classes\n      classes = @ri_reader.full_class_names\n      @display.list_known_classes(classes)\n    elsif @options.list_names\n      names = @ri_reader.all_names\n      @display.list_known_names(names)\n    else\n      if ARGV.size.zero?\n        @display.display_usage\n      else\n        begin\n          ARGV.each do |arg|\n            get_info_for(arg)\n          end\n        rescue RiError => e\n          STDERR.puts(e.message)\n          exit(1)\n        end\n      end\n    end\n  end\n\nend  # class RiDriver\n"
  },
  {
    "path": "lib/rdoc/ri/ri_formatter.rb",
    "content": "module RI\n  class TextFormatter\n\n    attr_reader :indent\n    \n    def initialize(options, indent)\n      @options = options\n      @width   = options.width\n      @indent  = indent\n    end\n    \n    \n    ######################################################################\n    \n    def draw_line(label=nil)\n      len = @width\n      len -= (label.size+1) if label\n      print \"-\"*len\n      if label\n        print(\" \")\n        bold_print(label) \n      end\n      puts\n    end\n    \n    ######################################################################\n    \n    def wrap(txt,  prefix=@indent, linelen=@width)\n      return unless txt && !txt.empty?\n      work = conv_markup(txt)\n      textLen = linelen - prefix.length\n      patt = Regexp.new(\"^(.{0,#{textLen}})[ \\n]\")\n      next_prefix = prefix.tr(\"^ \", \" \")\n\n      res = []\n\n      while work.length > textLen\n        if work =~ patt\n          res << $1\n          work.slice!(0, $&.length)\n        else\n          res << work.slice!(0, textLen)\n        end\n      end\n      res << work if work.length.nonzero?\n      puts(prefix + res.join(\"\\n\" + next_prefix))\n    end\n\n    ######################################################################\n\n    def blankline\n      puts\n    end\n    \n    ######################################################################\n\n    # called when we want to ensure a nbew 'wrap' starts on a newline\n    # Only needed for HtmlFormatter, because the rest do their\n    # own line breaking\n\n    def break_to_newline\n    end\n    \n    ######################################################################\n\n    def bold_print(txt)\n      print txt\n    end\n\n    ######################################################################\n\n    def raw_print_line(txt)\n      puts txt\n    end\n\n    ######################################################################\n\n    # convert HTML entities back to ASCII\n    def conv_html(txt)\n      txt.\n          gsub(/&gt;/, '>').\n          gsub(/&lt;/, '<').\n          gsub(/&quot;/, '\"').\n          gsub(/&amp;/, '&')\n          \n    end\n\n    # convert markup into display form\n    def conv_markup(txt)\n      txt.\n          gsub(%r{<tt>(.*?)</tt>}) { \"+#$1+\" } .\n          gsub(%r{<code>(.*?)</code>}) { \"+#$1+\" } .\n          gsub(%r{<b>(.*?)</b>}) { \"*#$1*\" } .\n          gsub(%r{<em>(.*?)</em>}) { \"_#$1_\" }\n    end\n\n    ######################################################################\n\n    def display_list(list)\n      case list.type\n\n      when SM::ListBase::BULLET \n        prefixer = proc { |ignored| @indent + \"*   \" }\n\n      when SM::ListBase::NUMBER,\n      SM::ListBase::UPPERALPHA,\n      SM::ListBase::LOWERALPHA\n\n        start = case list.type\n                when SM::ListBase::NUMBER      then 1\n                when  SM::ListBase::UPPERALPHA then 'A'\n                when SM::ListBase::LOWERALPHA  then 'a'\n                end\n        prefixer = proc do |ignored|\n          res = @indent + \"#{start}.\".ljust(4)\n          start = start.succ\n          res\n        end\n        \n      when SM::ListBase::LABELED\n        prefixer = proc do |li|\n          li.label\n        end\n\n      when SM::ListBase::NOTE\n        longest = 0\n        list.contents.each do |item|\n          if item.kind_of?(SM::Flow::LI) && item.label.length > longest\n            longest = item.label.length\n          end\n        end\n\n        prefixer = proc do |li|\n          @indent + li.label.ljust(longest+1)\n        end\n\n      else\n        fail \"unknown list type\"\n\n      end\n\n      list.contents.each do |item|\n        if item.kind_of? SM::Flow::LI\n          prefix = prefixer.call(item)\n          display_flow_item(item, prefix)\n        else\n          display_flow_item(item)\n        end\n       end\n    end\n\n    ######################################################################\n\n    def display_flow_item(item, prefix=@indent)\n      case item\n      when SM::Flow::P, SM::Flow::LI\n        wrap(conv_html(item.body), prefix)\n        blankline\n        \n      when SM::Flow::LIST\n        display_list(item)\n\n      when SM::Flow::VERB\n        display_verbatim_flow_item(item, @indent)\n\n      when SM::Flow::H\n        display_heading(conv_html(item.text), item.level, @indent)\n\n      when SM::Flow::RULE\n        draw_line\n\n      else\n        fail \"Unknown flow element: #{item.class}\"\n      end\n    end\n\n    ######################################################################\n\n    def display_verbatim_flow_item(item, prefix=@indent)\n        item.body.split(/\\n/).each do |line|\n          print @indent, conv_html(line), \"\\n\"\n        end\n        blankline\n    end\n\n    ######################################################################\n\n    def display_heading(text, level, indent)\n      text = strip_attributes(text)\n      case level\n      when 1\n        ul = \"=\" * text.length\n        puts\n        puts text.upcase\n        puts ul\n#        puts\n        \n      when 2\n        ul = \"-\" * text.length\n        puts\n        puts text\n        puts ul\n#        puts\n      else\n        print indent, text, \"\\n\"\n      end\n    end\n\n\n    def display_flow(flow)\n      flow.each do |f|\n        display_flow_item(f)\n      end\n    end\n\n    def strip_attributes(txt)\n      tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})\n      text = [] \n      attributes = 0\n      tokens.each do |tok|\n        case tok\n        when %r{^</(\\w+)>$}, %r{^<(\\w+)>$}\n          ;\n        else\n          text << tok\n        end\n      end\n      text.join\n    end\n\n\n  end\n  \n  \n  ######################################################################\n  # Handle text with attributes. We're a base class: there are\n  # different presentation classes (one, for example, uses overstrikes\n  # to handle bold and underlining, while another using ANSI escape\n  # sequences\n  \n  class AttributeFormatter < TextFormatter\n    \n    BOLD      = 1\n    ITALIC    = 2\n    CODE      = 4\n\n    ATTR_MAP = {\n      \"b\"    => BOLD,\n      \"code\" => CODE,\n      \"em\"   => ITALIC,\n      \"i\"    => ITALIC,\n      \"tt\"   => CODE\n    }\n\n    # TODO: struct?\n    class AttrChar\n      attr_reader :char\n      attr_reader :attr\n\n      def initialize(char, attr)\n        @char = char\n        @attr = attr\n      end\n    end\n\n    \n    class AttributeString\n      attr_reader :txt\n\n      def initialize\n        @txt = []\n        @optr = 0\n      end\n\n      def <<(char)\n        @txt << char\n      end\n\n      def empty?\n        @optr >= @txt.length\n      end\n\n      # accept non space, then all following spaces\n      def next_word\n        start = @optr\n        len = @txt.length\n\n        while @optr < len && @txt[@optr].char != \" \"\n          @optr += 1\n        end\n\n        while @optr < len && @txt[@optr].char == \" \"\n          @optr += 1\n        end\n\n        @txt[start...@optr]\n      end\n    end\n\n    ######################################################################\n    # overrides base class. Looks for <tt>...</tt> etc sequences\n    # and generates an array of AttrChars. This array is then used\n    # as the basis for the split\n\n    def wrap(txt,  prefix=@indent, linelen=@width)\n      return unless txt && !txt.empty?\n\n      txt = add_attributes_to(txt)\n      next_prefix = prefix.tr(\"^ \", \" \")\n      linelen -= prefix.size\n\n      line = []\n\n      until txt.empty?\n        word = txt.next_word\n        if word.size + line.size > linelen\n          write_attribute_text(prefix, line)\n          prefix = next_prefix\n          line = []\n        end\n        line.concat(word)\n      end\n\n      write_attribute_text(prefix, line) if line.length > 0\n    end\n\n    protected\n\n    # overridden in specific formatters\n\n    def write_attribute_text(prefix, line)\n      print prefix\n      line.each do |achar|\n        print achar.char\n      end\n      puts\n    end\n\n    # again, overridden\n\n    def bold_print(txt)\n      print txt\n    end\n\n    private\n\n    def add_attributes_to(txt)\n      tokens = txt.split(%r{(</?(?:b|code|em|i|tt)>)})\n      text = AttributeString.new\n      attributes = 0\n      tokens.each do |tok|\n        case tok\n        when %r{^</(\\w+)>$} then attributes &= ~(ATTR_MAP[$1]||0)\n        when %r{^<(\\w+)>$}  then attributes  |= (ATTR_MAP[$1]||0)\n        else\n          tok.split(//).each {|ch| text << AttrChar.new(ch, attributes)}\n        end\n      end\n      text\n    end\n\n  end\n\n\n  ##################################################\n  \n  # This formatter generates overstrike-style formatting, which\n  # works with pagers such as man and less.\n\n  class OverstrikeFormatter < AttributeFormatter\n\n    BS = \"\\C-h\"\n\n    def write_attribute_text(prefix, line)\n      print prefix\n      line.each do |achar|\n        attr = achar.attr\n        if (attr & (ITALIC+CODE)) != 0\n          print \"_\", BS\n        end\n        if (attr & BOLD) != 0\n          print achar.char, BS\n        end\n        print achar.char\n      end\n      puts\n    end\n\n    # draw a string in bold\n    def bold_print(text)\n      text.split(//).each do |ch|\n        print ch, BS, ch\n      end\n    end\n  end\n\n  ##################################################\n  \n  # This formatter uses ANSI escape sequences\n  # to colorize stuff\n  # works with pages such as man and less.\n\n  class AnsiFormatter < AttributeFormatter\n\n    def initialize(*args)\n      print \"\\033[0m\"\n      super\n    end\n\n    def write_attribute_text(prefix, line)\n      print prefix\n      curr_attr = 0\n      line.each do |achar|\n        attr = achar.attr\n        if achar.attr != curr_attr\n          update_attributes(achar.attr)\n          curr_attr = achar.attr\n        end\n        print achar.char\n      end\n      update_attributes(0) unless curr_attr.zero?\n      puts\n    end\n\n\n    def bold_print(txt)\n      print \"\\033[1m#{txt}\\033[m\"\n    end\n\n    HEADINGS = {\n      1 => [ \"\\033[1;32m\", \"\\033[m\" ] ,\n      2 => [\"\\033[4;32m\", \"\\033[m\" ],\n      3 => [\"\\033[32m\", \"\\033[m\" ]\n    }\n\n    def display_heading(text, level, indent)\n      level = 3 if level > 3\n      heading = HEADINGS[level]\n      print indent\n      print heading[0]\n      print strip_attributes(text)\n      puts heading[1]\n    end\n    \n    private\n\n    ATTR_MAP = {\n      BOLD   => \"1\",\n      ITALIC => \"33\",\n      CODE   => \"36\"\n    }\n\n    def update_attributes(attr)\n      str = \"\\033[\"\n      for quality in [ BOLD, ITALIC, CODE]\n        unless (attr & quality).zero?\n          str << ATTR_MAP[quality]\n        end\n      end\n      print str, \"m\"\n    end\n  end\n\n  ##################################################\n  \n  # This formatter uses HTML.\n\n  class HtmlFormatter < AttributeFormatter\n\n    def initialize(*args)\n      super\n    end\n\n    def write_attribute_text(prefix, line)\n      curr_attr = 0\n      line.each do |achar|\n        attr = achar.attr\n        if achar.attr != curr_attr\n          update_attributes(curr_attr, achar.attr)\n          curr_attr = achar.attr\n        end\n        print(escape(achar.char))\n      end\n      update_attributes(curr_attr, 0) unless curr_attr.zero?\n    end\n\n    def draw_line(label=nil)\n      if label != nil\n        bold_print(label)\n      end\n      puts(\"<hr>\")\n    end\n\n    def bold_print(txt)\n      tag(\"b\") { txt }\n    end\n\n    def blankline()\n      puts(\"<p>\")\n    end\n\n    def break_to_newline\n      puts(\"<br>\")\n    end\n\n    def display_heading(text, level, indent)\n      level = 4 if level > 4\n      tag(\"h#{level}\") { text }\n      puts\n    end\n    \n    ######################################################################\n\n    def display_list(list)\n\n      case list.type\n      when SM::ListBase::BULLET \n        list_type = \"ul\"\n        prefixer = proc { |ignored| \"<li>\" }\n\n      when SM::ListBase::NUMBER,\n      SM::ListBase::UPPERALPHA,\n      SM::ListBase::LOWERALPHA\n        list_type = \"ol\"\n        prefixer = proc { |ignored| \"<li>\" }\n        \n      when SM::ListBase::LABELED\n        list_type = \"dl\"\n        prefixer = proc do |li|\n          \"<dt><b>\" + escape(li.label) + \"</b><dd>\"\n        end\n\n      when SM::ListBase::NOTE\n        list_type = \"table\"\n        prefixer = proc do |li|\n          %{<tr valign=\"top\"><td>#{li.label.gsub(/ /, '&nbsp;')}</td><td>}\n        end\n      else\n        fail \"unknown list type\"\n      end\n\n      print \"<#{list_type}>\"\n      list.contents.each do |item|\n        if item.kind_of? SM::Flow::LI\n          prefix = prefixer.call(item)\n          print prefix\n          display_flow_item(item, prefix)\n        else\n          display_flow_item(item)\n        end\n      end\n      print \"</#{list_type}>\"\n    end\n\n    def display_verbatim_flow_item(item, prefix=@indent)\n        print(\"<pre>\")\n        puts item.body\n        puts(\"</pre>\")\n    end\n\n    private\n\n    ATTR_MAP = {\n      BOLD   => \"b>\",\n      ITALIC => \"i>\",\n      CODE   => \"tt>\"\n    }\n\n    def update_attributes(current, wanted)\n      str = \"\"\n      # first turn off unwanted ones\n      off = current & ~wanted\n      for quality in [ BOLD, ITALIC, CODE]\n        if (off & quality) > 0\n          str << \"</\" + ATTR_MAP[quality]\n        end\n      end\n\n      # now turn on wanted\n      for quality in [ BOLD, ITALIC, CODE]\n        unless (wanted & quality).zero?\n          str << \"<\" << ATTR_MAP[quality]\n        end\n      end\n      print str\n    end\n\n    def tag(code)\n        print(\"<#{code}>\")\n        print(yield)\n        print(\"</#{code}>\")\n    end\n\n    def escape(str)\n      str.\n          gsub(/&/n, '&amp;').\n          gsub(/\\\"/n, '&quot;').\n          gsub(/>/n, '&gt;').\n          gsub(/</n, '&lt;')\n    end\n\n  end\n\n  ##################################################\n  \n  # This formatter reduces extra lines for a simpler output.\n  # It improves way output looks for tools like IRC bots.\n\n  class SimpleFormatter < TextFormatter\n\n    ######################################################################\n\n    # No extra blank lines\n\n    def blankline\n    end\n\n    ######################################################################\n\n    # Display labels only, no lines\n\n    def draw_line(label=nil)\n      unless label.nil? then\n        bold_print(label) \n        puts\n      end\n    end\n\n    ######################################################################\n\n    # Place heading level indicators inline with heading.\n\n    def display_heading(text, level, indent)\n      text = strip_attributes(text)\n      case level\n      when 1\n        puts \"= \" + text.upcase\n      when 2\n        puts \"-- \" + text\n      else\n        print indent, text, \"\\n\"\n      end\n    end\n\n  end\n\n\n  # Finally, fill in the list of known formatters\n\n  class TextFormatter\n\n    FORMATTERS = {\n      \"ansi\"   => AnsiFormatter,\n      \"bs\"     => OverstrikeFormatter,\n      \"html\"   => HtmlFormatter,\n      \"plain\"  => TextFormatter,\n      \"simple\" => SimpleFormatter,\n    }\n      \n    def TextFormatter.list\n      FORMATTERS.keys.sort.join(\", \")\n    end\n\n    def TextFormatter.for(name)\n      FORMATTERS[name.downcase]\n    end\n\n  end\n\nend\n\n\n"
  },
  {
    "path": "lib/rdoc/ri/ri_options.rb",
    "content": "# We handle the parsing of options, and subsequently as a singleton\n# object to be queried for option values\n\nmodule RI\n\n  require 'rdoc/ri/ri_paths'\n  require 'rdoc/ri/ri_display'\n\n  VERSION_STRING = \"ri v1.0.1 - 20041108\"\n\n  class Options\n    \n    require 'singleton'\n    require 'getoptlong'\n    \n    include Singleton\n\n    # No not use a pager. Writable, because ri sets it if it\n    # can't find a pager\n    attr_accessor :use_stdout\n\n    # should we just display a class list and exit\n    attr_reader :list_classes\n\n    # should we display a list of all names\n    attr_reader :list_names\n\n    # The width of the output line\n    attr_reader :width\n\n    # the formatting we apply to the output\n    attr_reader :formatter\n\n    # the directory we search for original documentation\n    attr_reader :doc_dir\n\n    module OptionList\n      \n      OPTION_LIST = [\n        [ \"--help\",          \"-h\",   nil,\n          \"you're looking at it\" ],\n\n        [ \"--classes\",      \"-c\",   nil,\n          \"Display the names of classes and modules we\\n\" +\n          \"know about\"],\n\n        [ \"--doc-dir\",      \"-d\",   \"<dirname>\",\n          \"A directory to search for documentation. If not\\n\" +\n          \"specified, we search the standard rdoc/ri directories.\\n\" +\n          \"May be repeated.\"],\n\n        [ \"--system\",       nil,    nil,\n          \"Include documentation from Ruby's standard library:\\n  \" +\n          RI::Paths::SYSDIR ],\n\n        [ \"--site\",         nil,    nil,\n          \"Include documentation from libraries installed in site_lib:\\n  \" +\n          RI::Paths::SITEDIR ],\n\n        [ \"--home\",         nil,    nil,\n          \"Include documentation stored in ~/.rdoc:\\n  \" +\n          (RI::Paths::HOMEDIR || \"No ~/.rdoc found\") ],\n\n        [ \"--gems\",         nil,    nil,\n          \"Include documentation from RubyGems:\\n\" +\n          (RI::Paths::GEMDIRS ?\n           Gem.path.map { |dir| \"  #{dir}/doc/*/ri\" }.join(\"\\n\") :\n           \"No Rubygems ri found.\") ],\n\n        [ \"--format\",       \"-f\",   \"<name>\",\n          \"Format to use when displaying output:\\n\" +\n          \"   \" + RI::TextFormatter.list + \"\\n\" +\n          \"Use 'bs' (backspace) with most pager programs.\\n\" +\n          \"To use ANSI, either also use the -T option, or\\n\" +\n          \"tell your pager to allow control characters\\n\" +\n          \"(for example using the -R option to less)\"],\n\n        [ \"--list-names\",    \"-l\",   nil,\n          \"List all the names known to RDoc, one per line\"\n        ],\n\n        [ \"--no-pager\",      \"-T\",   nil,\n          \"Send output directly to stdout.\" \n        ],\n\n        [ \"--width\",         \"-w\",   \"output width\",\n        \"Set the width of the output\" ],\n\n        [ \"--version\",       \"-v\",   nil,\n         \"Display the version of ri\"\n        ],\n\n      ]\n\n      def OptionList.options\n        OPTION_LIST.map do |long, short, arg,|\n          option = []\n          option << long\n          option << short unless short.nil?\n          option << (arg ? GetoptLong::REQUIRED_ARGUMENT :\n                           GetoptLong::NO_ARGUMENT)\n          option\n        end\n      end\n\n\n      def OptionList.strip_output(text)\n        text =~ /^\\s+/\n        leading_spaces = $&\n        text.gsub!(/^#{leading_spaces}/, '')\n        $stdout.puts text\n      end\n      \n      \n      # Show an error and exit\n      \n      def OptionList.error(msg)\n        $stderr.puts\n        $stderr.puts msg\n        name = File.basename $PROGRAM_NAME\n        $stderr.puts \"\\nFor help on options, try '#{name} --help'\\n\\n\"\n        exit 1\n      end\n      \n      # Show usage and exit\n      \n      def OptionList.usage(short_form=false)\n        \n        puts\n        puts(RI::VERSION_STRING)\n        puts\n        \n        name = File.basename($0)\n\n        directories = [\n          RI::Paths::SYSDIR,\n          RI::Paths::SITEDIR,\n          RI::Paths::HOMEDIR\n        ]\n\n        if RI::Paths::GEMDIRS then\n          Gem.path.each do |dir|\n            directories << \"#{dir}/doc/*/ri\"\n          end\n        end\n\n        directories = directories.join(\"\\n    \")\n\n        OptionList.strip_output(<<-EOT)\n          Usage:\n\n            #{name} [options]  [names...]\n\n          Display information on Ruby classes, modules, and methods.\n          Give the names of classes or methods to see their documentation.\n          Partial names may be given: if the names match more than\n          one entity, a list will be shown, otherwise details on\n          that entity will be displayed.\n\n          Nested classes and modules can be specified using the normal\n          Name::Name notation, and instance methods can be distinguished\n          from class methods using \".\" (or \"#\") instead of \"::\".\n\n          For example:\n\n              #{name}  File\n              #{name}  File.new\n              #{name}  F.n\n              #{name}  zip\n\n          Note that shell quoting may be required for method names\n          containing punctuation:\n\n              #{name} 'Array.[]'\n              #{name} compact\\\\!\n\n          By default ri searches for documentation in the following\n          directories:\n\n              #{directories}\n\n          Specifying the --system, --site, --home, --gems or --doc-dir\n          options will limit ri to searching only the specified\n          directories.\n\n        EOT\n\n        if short_form\n          puts \"For help on options, type '#{name} -h'\"\n          puts \"For a list of classes I know about, type '#{name} -c'\"\n        else\n          puts \"Options:\\n\\n\"\n          OPTION_LIST.each do|long, short, arg, desc|\n            opt = ''\n            opt << (short ? sprintf(\"%15s\", \"#{long}, #{short}\") :\n                            sprintf(\"%15s\", long))\n            if arg\n              opt << \" \" << arg\n            end\n            print opt\n            desc = desc.split(\"\\n\")\n            if opt.size < 17\n              print \" \"*(18-opt.size)\n              puts desc.shift\n            else\n              puts\n            end\n            desc.each do |line|\n              puts(\" \"*18 + line)\n            end\n            puts\n          end\n          puts \"Options may also be passed in the 'RI' environment variable\"\n          exit 0\n        end\n      end\n    end\n\n    # Show the version and exit\n    def show_version\n      puts VERSION_STRING\n      exit(0)\n    end\n\n    def initialize\n      @use_stdout   = !STDOUT.tty?\n      @width        = 72\n      @formatter    = RI::TextFormatter.for(\"plain\") \n      @list_classes = false\n      @list_names   = false\n\n      # By default all paths are used.  If any of these are true, only those\n      # directories are used.\n      @use_system = false\n      @use_site = false\n      @use_home = false\n      @use_gems = false\n      @doc_dirs = []\n    end\n\n    # Parse command line options.\n\n    def parse(args)\n    \n      old_argv = ARGV.dup\n\n      ARGV.replace(args)\n\n      begin\n\n        go = GetoptLong.new(*OptionList.options)\n        go.quiet = true\n\n        go.each do |opt, arg|\n          case opt\n          when \"--help\"       then OptionList.usage\n          when \"--version\"    then show_version\n          when \"--list-names\" then @list_names = true\n          when \"--no-pager\"   then @use_stdout = true\n          when \"--classes\"    then @list_classes = true\n\n          when \"--system\"     then @use_system = true\n          when \"--site\"       then @use_site = true\n          when \"--home\"       then @use_home = true\n          when \"--gems\"       then @use_gems = true\n\n          when \"--doc-dir\"\n            if File.directory?(arg)\n              @doc_dirs << arg\n            else\n              $stderr.puts \"Invalid directory: #{arg}\"\n              exit 1\n            end\n\n          when \"--format\"\n            @formatter = RI::TextFormatter.for(arg)\n            unless @formatter\n              $stderr.print \"Invalid formatter (should be one of \"\n              $stderr.puts RI::TextFormatter.list + \")\"\n              exit 1\n            end\n          when \"--width\"\n            begin\n              @width = Integer(arg)\n            rescue \n              $stderr.puts \"Invalid width: '#{arg}'\"\n              exit 1\n            end\n          end\n        end\n\n      rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error\n        OptionList.error(error.message)\n\n      end\n    end\n\n    # Return the selected documentation directories.\n\n    def path\n      RI::Paths.path(@use_system, @use_site, @use_home, @use_gems, *@doc_dirs)\n    end\n\n    def raw_path\n      RI::Paths.raw_path(@use_system, @use_site, @use_home, @use_gems,\n                         *@doc_dirs)\n    end\n\n    # Return an instance of the displayer (the thing that actually writes\n    # the information). This allows us to load in new displayer classes\n    # at runtime (for example to help with IDE integration)\n    \n    def displayer\n      ::RiDisplay.new(self)\n    end\n  end\n\nend\n\n"
  },
  {
    "path": "lib/rdoc/ri/ri_paths.rb",
    "content": "module RI\n\n  # Encapsulate all the strangeness to do with finding out\n  # where to find RDoc files\n  #\n  # We basically deal with three directories:\n  #\n  # 1. The 'system' documentation directory, which holds\n  #    the documentation distributed with Ruby, and which\n  #    is managed by the Ruby install process\n  # 2. The 'site' directory, which contains site-wide\n  #    documentation added locally.\n  # 3. The 'user' documentation directory, stored under the\n  #    user's own home directory.\n  #\n  # There's contention about all this, but for now:\n  #\n  # system:: $datadir/ri/<ver>/system/...\n  # site::   $datadir/ri/<ver>/site/...\n  # user::   ~/.rdoc\n\n  module Paths\n\n    #:stopdoc:\n    require 'rbconfig'\n    \n    DOC_DIR  = \"doc/rdoc\"\n\n    version = Config::CONFIG['ruby_version']\n\n    base    = File.join(Config::CONFIG['datadir'], \"ri\", version)\n    SYSDIR  = File.join(base, \"system\")\n    SITEDIR = File.join(base, \"site\")\n    homedir = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']\n\n    if homedir\n      HOMEDIR = File.join(homedir, \".rdoc\")\n    else\n      HOMEDIR = nil\n    end\n\n    # This is the search path for 'ri'\n    PATH = [ SYSDIR, SITEDIR, HOMEDIR ].find_all {|p| p && File.directory?(p)}\n\n    begin\n      require 'rubygems'\n\n      # HACK dup'd from Gem.latest_partials and friends\n      all_paths = []\n\n      all_paths = Gem.path.map do |dir|\n        Dir[File.join(dir, 'doc', '*', 'ri')]\n      end.flatten\n\n      ri_paths = {}\n\n      all_paths.each do |dir|\n        base = File.basename File.dirname(dir)\n        if base =~ /(.*)-((\\d+\\.)*\\d+)/ then\n          name, version = $1, $2\n          ver = Gem::Version.new version\n          if ri_paths[name].nil? or ver > ri_paths[name][0] then\n            ri_paths[name] = [ver, dir]\n          end\n        end\n      end\n\n      GEMDIRS = ri_paths.map { |k,v| v.last }.sort\n      GEMDIRS.each { |dir| RI::Paths::PATH << dir }\n    rescue LoadError\n      GEMDIRS = nil\n    end\n\n    # Returns the selected documentation directories as an Array, or PATH if no\n    # overriding directories were given.\n\n    def self.path(use_system, use_site, use_home, use_gems, *extra_dirs)\n      path = raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)\n      return path.select { |directory| File.directory? directory }\n    end\n\n    # Returns the selected documentation directories including nonexistent\n    # directories.  Used to print out what paths were searched if no ri was\n    # found.\n\n    def self.raw_path(use_system, use_site, use_home, use_gems, *extra_dirs)\n      return PATH unless use_system or use_site or use_home or use_gems or\n                         not extra_dirs.empty?\n\n      path = []\n      path << extra_dirs unless extra_dirs.empty?\n      path << RI::Paths::SYSDIR if use_system\n      path << RI::Paths::SITEDIR if use_site\n      path << RI::Paths::HOMEDIR if use_home\n      path << RI::Paths::GEMDIRS if use_gems\n\n      return path.flatten.compact\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/ri/ri_reader.rb",
    "content": "require 'rdoc/ri/ri_descriptions'\nrequire 'rdoc/ri/ri_writer'\nrequire 'rdoc/markup/simple_markup/to_flow'\n\nmodule RI\n  class RiReader\n\n    def initialize(ri_cache)\n      @cache = ri_cache\n    end\n\n    def top_level_namespace\n      [ @cache.toplevel ]\n    end\n\n    def lookup_namespace_in(target, namespaces)\n      result = []\n      for n in namespaces\n        result.concat(n.contained_modules_matching(target))\n      end\n      result\n    end\n\n    def find_class_by_name(full_name)\n      names = full_name.split(/::/)\n      ns = @cache.toplevel\n      for name in names\n        ns = ns.contained_class_named(name)\n        return nil if ns.nil?\n      end\n      get_class(ns)\n    end\n\n    def find_methods(name, is_class_method, namespaces)\n      result = []\n      namespaces.each do |ns|\n        result.concat ns.methods_matching(name, is_class_method)\n      end\n      result\n    end\n\n    # return the MethodDescription for a given MethodEntry\n    # by deserializing the YAML\n    def get_method(method_entry)\n      path = method_entry.path_name\n      File.open(path) { |f| RI::Description.deserialize(f) }\n    end\n\n    # Return a class description\n    def get_class(class_entry)\n      result = nil\n      for path in class_entry.path_names\n        path = RiWriter.class_desc_path(path, class_entry)\n        desc = File.open(path) {|f| RI::Description.deserialize(f) }\n        if result\n          result.merge_in(desc)\n        else\n          result = desc\n        end\n      end\n      result\n    end\n\n    # return the names of all classes and modules\n    def full_class_names\n      res = []\n      find_classes_in(res, @cache.toplevel)\n    end\n\n    # return a list of all classes, modules, and methods\n    def all_names\n      res = []\n      find_names_in(res, @cache.toplevel)\n    end\n\n    # ----\n    private\n    # ----\n\n    def find_classes_in(res, klass)\n      classes = klass.classes_and_modules\n      for c in classes\n        res << c.full_name\n        find_classes_in(res, c)\n      end\n      res\n    end\n\n    def find_names_in(res, klass)\n      classes = klass.classes_and_modules\n      for c in classes\n        res << c.full_name\n        res.concat c.all_method_names\n        find_names_in(res, c)\n      end\n      res\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/ri/ri_util.rb",
    "content": "######################################################################\n\nclass RiError < Exception; end\n#\n# Break argument into its constituent class or module names, an\n# optional method type, and a method name\n\nclass NameDescriptor\n\n  attr_reader :class_names\n  attr_reader :method_name\n\n  # true and false have the obvious meaning. nil means we don't care\n  attr_reader :is_class_method\n\n  # arg may be\n  # 1. a class or module name (optionally qualified with other class\n  #    or module names (Kernel, File::Stat etc)\n  # 2. a method name\n  # 3. a method name qualified by a optionally fully qualified class\n  #    or module name\n  #\n  # We're fairly casual about delimiters: folks can say Kernel::puts,\n  # Kernel.puts, or Kernel\\#puts for example. There's one exception:\n  # if you say IO::read, we look for a class method, but if you\n  # say IO.read, we look for an instance method\n\n  def initialize(arg)\n    @class_names = []\n    separator = nil\n\n    tokens = arg.split(/(\\.|::|#)/)\n\n    # Skip leading '::', '#' or '.', but remember it might\n    # be a method name qualifier\n    separator = tokens.shift if tokens[0] =~ /^(\\.|::|#)/\n\n    # Skip leading '::', but remember we potentially have an inst\n\n    # leading stuff must be class names\n    \n    while tokens[0] =~ /^[A-Z]/\n      @class_names << tokens.shift\n      unless tokens.empty?\n        separator = tokens.shift\n        break unless separator == \"::\"\n      end\n    end\n    \n    # Now must have a single token, the method name, or an empty\n    # array\n    unless tokens.empty?\n      @method_name = tokens.shift\n      # We may now have a trailing !, ?, or = to roll into\n      # the method name\n      if !tokens.empty? && tokens[0] =~ /^[!?=]$/\n        @method_name << tokens.shift\n      end\n\n      if @method_name =~ /::|\\.|#/ or !tokens.empty?\n        raise RiError.new(\"Bad argument: #{arg}\") \n      end\n      if separator && separator != '.'\n        @is_class_method = separator == \"::\"\n      end\n    end\n  end\n\n  # Return the full class name (with '::' between the components)\n  # or \"\" if there's no class name\n\n  def full_class_name\n    @class_names.join(\"::\")\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/ri/ri_writer.rb",
    "content": "require 'fileutils'\n\nmodule RI\n  class RiWriter\n\n    def RiWriter.class_desc_path(dir, class_desc)\n      File.join(dir, \"cdesc-\" + class_desc.name + \".yaml\")\n    end\n\n    \n    # Convert a name from internal form (containing punctuation)\n    # to an external form (where punctuation is replaced\n    # by %xx)\n\n    def RiWriter.internal_to_external(name)\n      name.gsub(/\\W/) { sprintf(\"%%%02x\", $&[0]) }\n    end\n\n    # And the reverse operation\n    def RiWriter.external_to_internal(name)\n      name.gsub(/%([0-9a-f]{2,2})/) { $1.to_i(16).chr }\n    end\n\n    def initialize(base_dir)\n      @base_dir = base_dir\n    end\n\n    def remove_class(class_desc)\n      FileUtils.rm_rf(path_to_dir(class_desc.full_name))\n    end\n\n    def add_class(class_desc)\n      dir = path_to_dir(class_desc.full_name)\n      FileUtils.mkdir_p(dir)\n      class_file_name = RiWriter.class_desc_path(dir, class_desc)\n      File.open(class_file_name, \"w\") do |f|\n        f.write(class_desc.serialize)\n      end\n    end\n\n    def add_method(class_desc, method_desc)\n      dir = path_to_dir(class_desc.full_name)\n      file_name = RiWriter.internal_to_external(method_desc.name)\n      meth_file_name = File.join(dir, file_name)\n      if method_desc.is_singleton\n        meth_file_name += \"-c.yaml\"\n      else\n        meth_file_name += \"-i.yaml\"\n      end\n\n      File.open(meth_file_name, \"w\") do |f|\n        f.write(method_desc.serialize)\n      end\n    end\n\n    private\n\n    def path_to_dir(class_name)\n      File.join(@base_dir, *class_name.split('::'))\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/template.rb",
    "content": "# Cheap-n-cheerful HTML page template system. You create a \n# template containing:\n#\n# * variable names between percent signs (<tt>%fred%</tt>)\n# * blocks of repeating stuff:\n#\n#     START:key\n#       ... stuff\n#     END:key\n#\n# You feed the code a hash. For simple variables, the values\n# are resolved directly from the hash. For blocks, the hash entry\n# corresponding to +key+ will be an array of hashes. The block will\n# be generated once for each entry. Blocks can be nested arbitrarily\n# deeply.\n#\n# The template may also contain\n#\n#   IF:key\n#     ... stuff\n#   ENDIF:key\n#\n# _stuff_ will only be included in the output if the corresponding\n# key is set in the value hash.\n#\n# Usage:  Given a set of templates <tt>T1, T2,</tt> etc\n#\n#            values = { \"name\" => \"Dave\", state => \"TX\" }\n#\n#            t = TemplatePage.new(T1, T2, T3)\n#            File.open(name, \"w\") {|f| t.write_html_on(f, values)}\n#         or\n#            res = ''\n#            t.write_html_on(res, values)\n#\n#\n\nclass TemplatePage\n\n  ##########\n  # A context holds a stack of key/value pairs (like a symbol\n  # table). When asked to resolve a key, it first searches the top of\n  # the stack, then the next level, and so on until it finds a match\n  # (or runs out of entries)\n\n  class Context\n    def initialize\n      @stack = []\n    end\n\n    def push(hash)\n      @stack.push(hash)\n    end\n\n    def pop\n      @stack.pop\n    end\n\n    # Find a scalar value, throwing an exception if not found. This\n    # method is used when substituting the %xxx% constructs\n\n    def find_scalar(key)\n      @stack.reverse_each do |level|\n        if val = level[key]\n          return val unless val.kind_of? Array\n        end\n      end\n      raise \"Template error: can't find variable '#{key}'\"\n    end\n\n    # Lookup any key in the stack of hashes\n\n    def lookup(key)\n      @stack.reverse_each do |level|\n        val = level[key]\n        return val if val\n      end\n      nil\n    end\n  end\n\n  #########\n  # Simple class to read lines out of a string\n\n  class LineReader\n    # we're initialized with an array of lines\n    def initialize(lines)\n      @lines = lines\n    end\n\n    # read the next line \n    def read\n      @lines.shift\n    end\n\n    # Return a list of lines up to the line that matches\n    # a pattern. That last line is discarded.\n    def read_up_to(pattern)\n      res = []\n      while line = read\n        if pattern.match(line)\n          return LineReader.new(res) \n        else\n          res << line\n        end\n      end\n      raise \"Missing end tag in template: #{pattern.source}\"\n    end\n\n    # Return a copy of ourselves that can be modified without\n    # affecting us\n    def dup\n      LineReader.new(@lines.dup)\n    end\n  end\n\n\n\n  # +templates+ is an array of strings containing the templates.\n  # We start at the first, and substitute in subsequent ones\n  # where the string <tt>!INCLUDE!</tt> occurs. For example,\n  # we could have the overall page template containing\n  #\n  #   <html><body>\n  #     <h1>Master</h1>\n  #     !INCLUDE!\n  #   </bost></html>\n  #\n  # and substitute subpages in to it by passing [master, sub_page].\n  # This gives us a cheap way of framing pages\n\n  def initialize(*templates)\n    result = \"!INCLUDE!\"\n    templates.each do |content|\n      result.sub!(/!INCLUDE!/, content)\n    end\n    @lines = LineReader.new(result.split($/))\n  end\n\n  # Render the templates into HTML, storing the result on +op+ \n  # using the method <tt><<</tt>. The <tt>value_hash</tt> contains\n  # key/value pairs used to drive the substitution (as described above)\n\n  def write_html_on(op, value_hash)\n    @context = Context.new\n    op << substitute_into(@lines, value_hash).tr(\"\\000\", '\\\\')\n  end\n\n\n  # Substitute a set of key/value pairs into the given template. \n  # Keys with scalar values have them substituted directly into\n  # the page. Those with array values invoke <tt>substitute_array</tt>\n  # (below), which examples a block of the template once for each \n  # row in the array.\n  #\n  # This routine also copes with the <tt>IF:</tt>_key_ directive,\n  # removing chunks of the template if the corresponding key\n  # does not appear in the hash, and the START: directive, which\n  # loops its contents for each value in an array\n\n  def substitute_into(lines, values)\n    @context.push(values)\n    skip_to = nil\n    result = []\n\n    while line = lines.read\n\n      case line\n\n      when /^IF:(\\w+)/\n        lines.read_up_to(/^ENDIF:#$1/) unless @context.lookup($1)\n\n    when /^IFNOT:(\\w+)/\n        lines.read_up_to(/^ENDIF:#$1/) if @context.lookup($1)\n\n      when /^ENDIF:/\n        ;\n\n      when /^START:(\\w+)/\n        tag = $1\n        body = lines.read_up_to(/^END:#{tag}/)\n        inner_values = @context.lookup(tag)\n        raise \"unknown tag: #{tag}\" unless inner_values\n        raise \"not array: #{tag}\"   unless inner_values.kind_of?(Array)\n        inner_values.each do |vals|\n          result << substitute_into(body.dup, vals)\n        end\n      else\n        result << expand_line(line.dup)\n      end\n    end\n\n    @context.pop\n\n    result.join(\"\\n\")\n  end\n\n  # Given an individual line, we look for %xxx% constructs and \n  # HREF:ref:name: constructs, substituting for each.\n\n  def expand_line(line)\n    # Generate a cross reference if a reference is given,\n    # otherwise just fill in the name part\n\n    line.gsub!(/HREF:(\\w+?):(\\w+?):/) {\n      ref = @context.lookup($1)\n      name = @context.find_scalar($2)\n\n      if ref and !ref.kind_of?(Array)\n\t\"<a href=\\\"#{ref}\\\">#{name}</a>\"\n      else\n\tname\n      end\n    }\n\n    # Substitute in values for %xxx% constructs.  This is made complex\n    # because the replacement string may contain characters that are\n    # meaningful to the regexp (like \\1)\n\n    line = line.gsub(/%([a-zA-Z]\\w*)%/) {\n      val = @context.find_scalar($1) \n      val.tr('\\\\', \"\\000\")\n    }\n\n\n    line\n  rescue Exception => e\n    $stderr.puts \"Error in template: #{e}\"\n    $stderr.puts \"Original line: #{line}\"\n    exit\n  end\n\nend\n\n"
  },
  {
    "path": "lib/rdoc/tokenstream.rb",
    "content": "# A TokenStream is a list of tokens, gathered during the parse\n# of some entity (say a method). Entities populate these streams\n# by being registered with the lexer. Any class can collect tokens\n# by including TokenStream. From the outside, you use such an object\n# by calling the start_collecting_tokens method, followed by calls\n# to add_token and pop_token\n\nmodule TokenStream\n  def token_stream\n    @token_stream\n  end\n\n  def start_collecting_tokens\n    @token_stream = []\n  end\n  def add_token(tk)\n    @token_stream << tk\n  end\n  def add_tokens(tks)\n    tks.each  {|tk| add_token(tk)}\n  end\n  def pop_token\n    @token_stream.pop\n  end\nend\n"
  },
  {
    "path": "lib/rdoc/usage.rb",
    "content": "# = Synopsis\n#\n# This library allows command-line tools to encapsulate their usage\n# as a comment at the top of the main file. Calling <tt>RDoc::usage</tt>\n# then displays some or all of that comment, and optionally exits\n# the program with an exit status. We always look for the comment\n# in the main program file, so it is safe to call this method\n# from anywhere in the executing program.\n#\n# = Usage\n#\n#   RDoc::usage( [ exit_status ], [ section, ...])\n#   RDoc::usage_no_exit( [ section, ...])\n#\n# where:\n#\n# exit_status::\n#     the integer exit code (default zero). RDoc::usage will exit\n#     the calling program with this status.\n#\n# section::\n#     an optional list of section names. If specified, only the\n#     sections with the given names as headings will be output.\n#     For example, this section is named 'Usage', and the next\n#     section is named 'Examples'. The section names are case\n#     insensitive.\n#\n# = Examples\n#\n#    # Comment block describing usage\n#    # with (optional) section headings\n#    # . . .\n#\n#    require 'rdoc/usage'\n#\n#    # Display all usage and exit with a status of 0\n#\n#    RDoc::usage\n#\n#    # Display all usage and exit with a status of 99\n#\n#    RDoc::usage(99)\n#\n#    # Display usage in the 'Summary' section only, then\n#    # exit with a status of 99\n#\n#    RDoc::usage(99, 'Summary')\n#\n#    # Display information in the Author and Copyright\n#    # sections, then exit 0.\n#    \n#    RDoc::usage('Author', 'Copyright')\n#\n#    # Display information in the Author and Copyright\n#    # sections, but don't exit\n#  \n#    RDoc::usage_no_exit('Author', 'Copyright')\n#\n# = Author\n#\n# Dave Thomas, The Pragmatic Programmers, LLC\n#\n# = Copyright\n#\n# Copyright (c) 2004 Dave Thomas.\n# Licensed under the same terms as Ruby\n#\n\nrequire 'rdoc/markup/simple_markup'\nrequire 'rdoc/markup/simple_markup/to_flow'\nrequire 'rdoc/ri/ri_formatter'\nrequire 'rdoc/ri/ri_options'\n\nmodule RDoc\n\n  # Display usage information from the comment at the top of\n  # the file. String arguments identify specific sections of the\n  # comment to display. An optional integer first argument\n  # specifies the exit status  (defaults to 0)\n\n  def RDoc.usage(*args)\n    exit_code = 0\n\n    if args.size > 0\n      status = args[0]\n      if status.respond_to?(:to_int)\n        exit_code = status.to_int\n        args.shift\n      end\n    end\n\n    # display the usage and exit with the given code\n    usage_no_exit(*args)\n    exit(exit_code)\n  end\n\n  # Display usage\n  def RDoc.usage_no_exit(*args)\n    main_program_file = caller[-1].sub(/:\\d+$/, '')\n    comment = File.open(main_program_file) do |file|\n      find_comment(file)\n    end\n\n    comment = comment.gsub(/^\\s*#/, '')\n\n    markup = SM::SimpleMarkup.new\n    flow_convertor = SM::ToFlow.new\n    \n    flow = markup.convert(comment, flow_convertor)\n\n    format = \"plain\"\n\n    unless args.empty?\n      flow = extract_sections(flow, args)\n    end\n\n    options = RI::Options.instance\n    if args = ENV[\"RI\"]\n      options.parse(args.split)\n    end\n    formatter = options.formatter.new(options, \"\")\n    formatter.display_flow(flow)\n  end\n\n  ######################################################################\n\n  private\n\n  # Find the first comment in the file (that isn't a shebang line)\n  # If the file doesn't start with a comment, report the fact\n  # and return empty string\n\n  def RDoc.gets(file)\n    if (line = file.gets) && (line =~ /^#!/) # shebang\n      throw :exit, find_comment(file)\n    else\n      line\n    end\n  end\n\n  def RDoc.find_comment(file)\n    catch(:exit) do\n      # skip leading blank lines\n      0 while (line = gets(file)) && (line =~ /^\\s*$/)\n\n      comment = []\n      while line && line =~ /^\\s*#/\n        comment << line\n        line = gets(file)\n      end\n\n      0 while line && (line = gets(file))\n      return no_comment if comment.empty?\n      return comment.join\n    end\n  end\n\n\n  #####\n  # Given an array of flow items and an array of section names, extract those\n  # sections from the flow which have headings corresponding to\n  # a section name in the list. Return them in the order\n  # of names in the +sections+ array.\n\n  def RDoc.extract_sections(flow, sections)\n    result = []\n    sections.each do |name|\n      name = name.downcase\n      copy_upto_level = nil\n\n      flow.each do |item|\n        case item\n        when SM::Flow::H\n          if copy_upto_level && item.level >= copy_upto_level\n            copy_upto_level = nil\n          else\n            if item.text.downcase == name\n              result << item\n              copy_upto_level = item.level\n            end\n          end\n        else\n          if copy_upto_level\n            result << item\n          end\n        end\n      end\n    end\n    if result.empty?\n      puts \"Note to developer: requested section(s) [#{sections.join(', ')}] \" +\n           \"not found\"\n      result = flow\n    end\n    result\n  end\n\n  #####\n  # Report the fact that no doc comment count be found\n  def RDoc.no_comment\n    $stderr.puts \"No usage information available for this program\"\n    \"\"\n  end\nend\n\n\nif $0 == __FILE__\n\n  RDoc::usage(*ARGV)\n\nend\n"
  },
  {
    "path": "lib/readbytes.rb",
    "content": "# TruncatedDataError is raised when IO#readbytes fails to read enough data.\n\nclass TruncatedDataError<IOError\n  def initialize(mesg, data) # :nodoc:\n    @data = data\n    super(mesg)\n  end\n\n  # The read portion of an IO#readbytes attempt.\n  attr_reader :data\nend\n\nclass IO\n  # Reads exactly +n+ bytes.\n  #\n  # If the data read is nil an EOFError is raised.\n  #\n  # If the data read is too short a TruncatedDataError is raised and the read\n  # data is obtainable via its #data method.\n  def readbytes(n)\n    str = read(n)\n    if str == nil\n      raise EOFError, \"End of file reached\"\n    end\n    if str.size < n\n      raise TruncatedDataError.new(\"data truncated\", str) \n    end\n    str\n  end\nend\n\nif __FILE__ == $0\n  begin\n    loop do\n      print STDIN.readbytes(6)\n    end\n  rescue TruncatedDataError\n    p $!.data\n    raise\n  end\nend\n"
  },
  {
    "path": "lib/resolv-replace.rb",
    "content": "require 'socket'\nrequire 'resolv'\n\nclass << IPSocket\n  alias original_resolv_getaddress getaddress\n  def getaddress(host)\n    begin\n      return Resolv.getaddress(host).to_s\n    rescue Resolv::ResolvError\n      raise SocketError, \"Hostname not known: #{host}\"\n    end\n  end\nend\n\nclass TCPSocket\n  alias original_resolv_initialize initialize\n  def initialize(host, serv, *rest)\n    rest[0] = IPSocket.getaddress(rest[0]) unless rest.empty?\n    original_resolv_initialize(IPSocket.getaddress(host), serv, *rest)\n  end\nend\n\nclass UDPSocket\n  alias original_resolv_bind bind\n  def bind(host, port)\n    host = IPSocket.getaddress(host) if host != \"\"\n    original_resolv_bind(host, port)\n  end\n\n  alias original_resolv_connect connect\n  def connect(host, port)\n    original_resolv_connect(IPSocket.getaddress(host), port)\n  end\n\n  alias original_resolv_send send\n  def send(mesg, flags, *rest)\n    if rest.length == 2\n      host, port = rest\n      begin\n        addrs = Resolv.getaddresses(host)\n      rescue Resolv::ResolvError\n        raise SocketError, \"Hostname not known: #{host}\"\n      end\n      err = nil\n      addrs[0...-1].each {|addr|\n        begin\n          return original_resolv_send(mesg, flags, addr, port)\n        rescue SystemCallError\n        end\n      }\n      original_resolv_send(mesg, flags, addrs[-1], port)\n    else\n      original_resolv_send(mesg, flags, *rest)\n    end\n  end\nend\n\nclass SOCKSSocket\n  alias original_resolv_initialize initialize\n  def initialize(host, serv)\n    original_resolv_initialize(IPSocket.getaddress(host), port)\n  end\nend if defined? SOCKSSocket\n"
  },
  {
    "path": "lib/resolv.rb",
    "content": "require 'socket'\nrequire 'fcntl'\nrequire 'timeout'\nrequire 'thread'\n\nbegin\n  require 'securerandom'\nrescue LoadError\nend\n\n# Resolv is a thread-aware DNS resolver library written in Ruby.  Resolv can\n# handle multiple DNS requests concurrently without blocking.  The ruby\n# interpreter.\n#\n# See also resolv-replace.rb to replace the libc resolver with # Resolv.\n# \n# Resolv can look up various DNS resources using the DNS module directly.\n# \n# Examples:\n# \n#   p Resolv.getaddress \"www.ruby-lang.org\"\n#   p Resolv.getname \"210.251.121.214\"\n# \n#   Resolv::DNS.open do |dns|\n#     ress = dns.getresources \"www.ruby-lang.org\", Resolv::DNS::Resource::IN::A\n#     p ress.map { |r| r.address }\n#     ress = dns.getresources \"ruby-lang.org\", Resolv::DNS::Resource::IN::MX\n#     p ress.map { |r| [r.exchange.to_s, r.preference] }\n#   end\n# \n# \n# == Bugs\n# \n# * NIS is not supported.\n# * /etc/nsswitch.conf is not supported.\n\nclass Resolv\n\n  ##\n  # Looks up the first IP address for +name+.\n  \n  def self.getaddress(name)\n    DefaultResolver.getaddress(name)\n  end\n\n  ##\n  # Looks up all IP address for +name+.\n  \n  def self.getaddresses(name)\n    DefaultResolver.getaddresses(name)\n  end\n\n  ##\n  # Iterates over all IP addresses for +name+.\n\n  def self.each_address(name, &block)\n    DefaultResolver.each_address(name, &block)\n  end\n\n  ##\n  # Looks up the hostname of +address+.\n\n  def self.getname(address)\n    DefaultResolver.getname(address)\n  end\n\n  ##\n  # Looks up all hostnames for +address+.\n\n  def self.getnames(address)\n    DefaultResolver.getnames(address)\n  end\n\n  ##\n  # Iterates over all hostnames for +address+.\n\n  def self.each_name(address, &proc)\n    DefaultResolver.each_name(address, &proc)\n  end\n\n  ##\n  # Creates a new Resolv using +resolvers+.\n\n  def initialize(resolvers=[Hosts.new, DNS.new])\n    @resolvers = resolvers\n  end\n\n  ##\n  # Looks up the first IP address for +name+.\n  \n  def getaddress(name)\n    each_address(name) {|address| return address}\n    raise ResolvError.new(\"no address for #{name}\")\n  end\n\n  ##\n  # Looks up all IP address for +name+.\n  \n  def getaddresses(name)\n    ret = []\n    each_address(name) {|address| ret << address}\n    return ret\n  end\n\n  ##\n  # Iterates over all IP addresses for +name+.\n\n  def each_address(name)\n    if AddressRegex =~ name\n      yield name\n      return\n    end\n    yielded = false\n    @resolvers.each {|r|\n      r.each_address(name) {|address|\n        yield address.to_s\n        yielded = true\n      }\n      return if yielded\n    }\n  end\n\n  ##\n  # Looks up the hostname of +address+.\n\n  def getname(address)\n    each_name(address) {|name| return name}\n    raise ResolvError.new(\"no name for #{address}\")\n  end\n\n  ##\n  # Looks up all hostnames for +address+.\n\n  def getnames(address)\n    ret = []\n    each_name(address) {|name| ret << name}\n    return ret\n  end\n\n  ##\n  # Iterates over all hostnames for +address+.\n\n  def each_name(address)\n    yielded = false\n    @resolvers.each {|r|\n      r.each_name(address) {|name|\n        yield name.to_s\n        yielded = true\n      }\n      return if yielded\n    }\n  end\n\n  ##\n  # Indicates a failure to resolve a name or address.\n\n  class ResolvError < StandardError; end\n\n  ##\n  # Indicates a timeout resolving a name or address.\n\n  class ResolvTimeout < TimeoutError; end\n\n  ##\n  # DNS::Hosts is a hostname resolver that uses the system hosts file.\n\n  class Hosts\n    if /mswin32|mingw|bccwin/ =~ RUBY_PLATFORM\n      require 'win32/resolv'\n      DefaultFileName = Win32::Resolv.get_hosts_path\n    else\n      DefaultFileName = '/etc/hosts'\n    end\n\n    ##\n    # Creates a new DNS::Hosts, using +filename+ for its data source.\n\n    def initialize(filename = DefaultFileName)\n      @filename = filename\n      @mutex = Mutex.new\n      @initialized = nil\n    end\n\n    def lazy_initialize # :nodoc:\n      @mutex.synchronize {\n        unless @initialized\n          @name2addr = {}\n          @addr2name = {}\n          open(@filename) {|f|\n            f.each {|line|\n              line.sub!(/#.*/, '')\n              addr, hostname, *aliases = line.split(/\\s+/)\n              next unless addr\n              addr.untaint\n              hostname.untaint\n              @addr2name[addr] = [] unless @addr2name.include? addr\n              @addr2name[addr] << hostname\n              @addr2name[addr] += aliases\n              @name2addr[hostname] = [] unless @name2addr.include? hostname\n              @name2addr[hostname] << addr\n              aliases.each {|n|\n                n.untaint\n                @name2addr[n] = [] unless @name2addr.include? n\n                @name2addr[n] << addr\n              }\n            }\n          }\n          @name2addr.each {|name, arr| arr.reverse!}\n          @initialized = true\n        end\n      }\n      self\n    end\n\n    ##\n    # Gets the IP address of +name+ from the hosts file.\n\n    def getaddress(name)\n      each_address(name) {|address| return address}\n      raise ResolvError.new(\"#{@filename} has no name: #{name}\")\n    end\n\n    ##\n    # Gets all IP addresses for +name+ from the hosts file.\n\n    def getaddresses(name)\n      ret = []\n      each_address(name) {|address| ret << address}\n      return ret\n    end\n\n    ##\n    # Iterates over all IP addresses for +name+ retrieved from the hosts file.\n\n    def each_address(name, &proc)\n      lazy_initialize\n      if @name2addr.include?(name)\n        @name2addr[name].each(&proc)\n      end\n    end\n\n    ##\n    # Gets the hostname of +address+ from the hosts file.\n\n    def getname(address)\n      each_name(address) {|name| return name}\n      raise ResolvError.new(\"#{@filename} has no address: #{address}\")\n    end\n\n    ##\n    # Gets all hostnames for +address+ from the hosts file.\n\n    def getnames(address)\n      ret = []\n      each_name(address) {|name| ret << name}\n      return ret\n    end\n\n    ##\n    # Iterates over all hostnames for +address+ retrieved from the hosts file.\n\n    def each_name(address, &proc)\n      lazy_initialize\n      if @addr2name.include?(address)\n        @addr2name[address].each(&proc)\n      end\n    end\n  end\n\n  ##\n  # Resolv::DNS is a DNS stub resolver.\n  #\n  # Information taken from the following places:\n  #\n  # * STD0013\n  # * RFC 1035\n  # * ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters\n  # * etc.\n\n  class DNS\n\n    ##\n    # Default DNS Port\n\n    Port = 53\n\n    ##\n    # Default DNS UDP packet size\n\n    UDPSize = 512\n\n    ##\n    # Group of DNS resolver threads (obsolete)\n\n    DNSThreadGroup = ThreadGroup.new\n\n    ##\n    # Creates a new DNS resolver.  See Resolv::DNS.new for argument details.\n    #\n    # Yields the created DNS resolver to the block, if given, otherwise\n    # returns it.\n\n    def self.open(*args)\n      dns = new(*args)\n      return dns unless block_given?\n      begin\n        yield dns\n      ensure\n        dns.close\n      end\n    end\n\n    ##\n    # Creates a new DNS resolver.\n    #\n    # +config_info+ can be:\n    # \n    # nil:: Uses /etc/resolv.conf.\n    # String:: Path to a file using /etc/resolv.conf's format.\n    # Hash:: Must contain :nameserver, :search and :ndots keys.\n    #\n    # Example:\n    #\n    #   Resolv::DNS.new(:nameserver => ['210.251.121.21'],\n    #                   :search => ['ruby-lang.org'],\n    #                   :ndots => 1)\n\n    def initialize(config_info=nil)\n      @mutex = Mutex.new\n      @config = Config.new(config_info)\n      @initialized = nil\n    end\n\n    def lazy_initialize # :nodoc:\n      @mutex.synchronize {\n        unless @initialized\n          @config.lazy_initialize\n          @initialized = true\n        end\n      }\n      self\n    end\n\n    ##\n    # Closes the DNS resolver.\n\n    def close\n      @mutex.synchronize {\n        if @initialized\n          @initialized = false\n        end\n      }\n    end\n\n    ##\n    # Gets the IP address of +name+ from the DNS resolver.\n    #\n    # +name+ can be a Resolv::DNS::Name or a String.  Retrieved address will\n    # be a Resolv::IPv4 or Resolv::IPv6\n\n    def getaddress(name)\n      each_address(name) {|address| return address}\n      raise ResolvError.new(\"DNS result has no information for #{name}\")\n    end\n\n    ##\n    # Gets all IP addresses for +name+ from the DNS resolver.\n    #\n    # +name+ can be a Resolv::DNS::Name or a String.  Retrieved addresses will\n    # be a Resolv::IPv4 or Resolv::IPv6\n\n    def getaddresses(name)\n      ret = []\n      each_address(name) {|address| ret << address}\n      return ret\n    end\n\n    ##\n    # Iterates over all IP addresses for +name+ retrieved from the DNS\n    # resolver.\n    #\n    # +name+ can be a Resolv::DNS::Name or a String.  Retrieved addresses will\n    # be a Resolv::IPv4 or Resolv::IPv6\n\n    def each_address(name)\n      each_resource(name, Resource::IN::A) {|resource| yield resource.address}\n      each_resource(name, Resource::IN::AAAA) {|resource| yield resource.address}\n    end\n\n    ##\n    # Gets the hostname for +address+ from the DNS resolver.\n    #\n    # +address+ must be a Resolv::IPv4, Resolv::IPv6 or a String.  Retrieved\n    # name will be a Resolv::DNS::Name.\n\n    def getname(address)\n      each_name(address) {|name| return name}\n      raise ResolvError.new(\"DNS result has no information for #{address}\")\n    end\n\n    ##\n    # Gets all hostnames for +address+ from the DNS resolver.\n    #\n    # +address+ must be a Resolv::IPv4, Resolv::IPv6 or a String.  Retrieved\n    # names will be Resolv::DNS::Name instances.\n\n    def getnames(address)\n      ret = []\n      each_name(address) {|name| ret << name}\n      return ret\n    end\n\n    ##\n    # Iterates over all hostnames for +address+ retrieved from the DNS\n    # resolver.\n    #\n    # +address+ must be a Resolv::IPv4, Resolv::IPv6 or a String.  Retrieved\n    # names will be Resolv::DNS::Name instances.\n\n    def each_name(address)\n      case address\n      when Name\n        ptr = address\n      when IPv4::Regex\n        ptr = IPv4.create(address).to_name\n      when IPv6::Regex\n        ptr = IPv6.create(address).to_name\n      else\n        raise ResolvError.new(\"cannot interpret as address: #{address}\")\n      end\n      each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}\n    end\n\n    ##\n    # Look up the +typeclass+ DNS resource of +name+.\n    #\n    # +name+ must be a Resolv::DNS::Name or a String.\n    #\n    # +typeclass+ should be one of the following:\n    #\n    # * Resolv::DNS::Resource::IN::A\n    # * Resolv::DNS::Resource::IN::AAAA\n    # * Resolv::DNS::Resource::IN::ANY\n    # * Resolv::DNS::Resource::IN::CNAME\n    # * Resolv::DNS::Resource::IN::HINFO\n    # * Resolv::DNS::Resource::IN::MINFO\n    # * Resolv::DNS::Resource::IN::MX\n    # * Resolv::DNS::Resource::IN::NS\n    # * Resolv::DNS::Resource::IN::PTR\n    # * Resolv::DNS::Resource::IN::SOA\n    # * Resolv::DNS::Resource::IN::TXT\n    # * Resolv::DNS::Resource::IN::WKS\n    #\n    # Returned resource is represented as a Resolv::DNS::Resource instance,\n    # i.e. Resolv::DNS::Resource::IN::A.\n\n    def getresource(name, typeclass)\n      each_resource(name, typeclass) {|resource| return resource}\n      raise ResolvError.new(\"DNS result has no information for #{name}\")\n    end\n\n    ##\n    # Looks up all +typeclass+ DNS resources for +name+.  See #getresource for\n    # argument details.\n  \n    def getresources(name, typeclass)\n      ret = []\n      each_resource(name, typeclass) {|resource| ret << resource}\n      return ret\n    end\n\n    ##\n    # Iterates over all +typeclass+ DNS resources for +name+.  See\n    # #getresource for argument details.\n  \n    def each_resource(name, typeclass, &proc)\n      lazy_initialize\n      requester = make_requester\n      senders = {}\n      begin\n        @config.resolv(name) {|candidate, tout, nameserver|\n          msg = Message.new\n          msg.rd = 1\n          msg.add_question(candidate, typeclass)\n          unless sender = senders[[candidate, nameserver]]\n            sender = senders[[candidate, nameserver]] =\n              requester.sender(msg, candidate, nameserver)\n          end\n          reply, reply_name = requester.request(sender, tout)\n          case reply.rcode\n          when RCode::NoError\n            extract_resources(reply, reply_name, typeclass, &proc)\n            return\n          when RCode::NXDomain\n            raise Config::NXDomain.new(reply_name.to_s)\n          else\n            raise Config::OtherResolvError.new(reply_name.to_s)\n          end\n        }\n      ensure\n        requester.close\n      end\n    end\n\n    def make_requester # :nodoc:\n      if nameserver = @config.single?\n        Requester::ConnectedUDP.new(nameserver)\n      else\n        Requester::UnconnectedUDP.new\n      end\n    end\n\n    def extract_resources(msg, name, typeclass) # :nodoc:\n      if typeclass < Resource::ANY\n        n0 = Name.create(name)\n        msg.each_answer {|n, ttl, data|\n          yield data if n0 == n\n        }\n      end\n      yielded = false\n      n0 = Name.create(name)\n      msg.each_answer {|n, ttl, data|\n        if n0 == n\n          case data\n          when typeclass\n            yield data\n            yielded = true\n          when Resource::CNAME\n            n0 = data.name\n          end\n        end\n      }\n      return if yielded\n      msg.each_answer {|n, ttl, data|\n        if n0 == n\n          case data\n          when typeclass\n            yield data\n          end\n        end\n      }\n    end\n\n    if defined? SecureRandom\n      def self.random(arg) # :nodoc:\n        begin\n          SecureRandom.random_number(arg)\n        rescue NotImplementedError\n          rand(arg)\n        end\n      end\n    else\n      def self.random(arg) # :nodoc:\n        rand(arg)\n      end\n    end\n\n\n    def self.rangerand(range) # :nodoc:\n      base = range.begin\n      len = range.end - range.begin\n      if !range.exclude_end?\n        len += 1\n      end\n      base + random(len)\n    end\n\n    RequestID = {}\n    RequestIDMutex = Mutex.new\n\n    def self.allocate_request_id(host, port) # :nodoc:\n      id = nil\n      RequestIDMutex.synchronize {\n        h = (RequestID[[host, port]] ||= {})\n        begin\n          id = rangerand(0x0000..0xffff)\n        end while h[id] \n        h[id] = true\n      }\n      id\n    end\n\n    def self.free_request_id(host, port, id) # :nodoc:\n      RequestIDMutex.synchronize {\n        key = [host, port]\n        if h = RequestID[key]\n          h.delete id\n          if h.empty?\n            RequestID.delete key\n          end\n        end\n      }\n    end\n\n    def self.bind_random_port(udpsock, is_ipv6=false) # :nodoc:\n      begin\n        port = rangerand(1024..65535)\n        udpsock.bind(is_ipv6 ? \"::\" : \"\", port)\n      rescue Errno::EADDRINUSE\n        retry\n      end\n    end\n\n    class Requester # :nodoc:\n      def initialize\n        @senders = {}\n        @sock = nil\n      end\n\n      def request(sender, tout)\n        timelimit = Time.now + tout\n        sender.send\n        while (now = Time.now) < timelimit\n          timeout = timelimit - now\n          if !IO.select([@sock], nil, nil, timeout)\n            raise ResolvTimeout\n          end\n          reply, from = recv_reply\n          begin\n            msg = Message.decode(reply)\n          rescue DecodeError\n            next # broken DNS message ignored\n          end\n          if s = @senders[[from,msg.id]]\n            break\n          else\n            # unexpected DNS message ignored\n          end\n        end\n        return msg, s.data\n      end\n\n      def close\n        sock = @sock\n        @sock = nil\n        sock.close if sock\n      end\n\n      class Sender # :nodoc:\n        def initialize(msg, data, sock)\n          @msg = msg\n          @data = data\n          @sock = sock\n        end\n      end\n\n      class UnconnectedUDP < Requester # :nodoc:\n        def initialize\n          super()\n          @sock = UDPSocket.new\n          @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD\n          DNS.bind_random_port(@sock)\n        end\n\n        def recv_reply\n          reply, from = @sock.recvfrom(UDPSize)\n          return reply, [from[3],from[1]]\n        end\n\n        def sender(msg, data, host, port=Port)\n          service = [host, port]\n          id = DNS.allocate_request_id(host, port)\n          request = msg.encode\n          request[0,2] = [id].pack('n')\n          return @senders[[service, id]] =\n            Sender.new(request, data, @sock, host, port)\n        end\n\n        def close\n          super\n          @senders.each_key {|service, id|\n            DNS.free_request_id(service[0], service[1], id)\n          }\n        end\n\n        class Sender < Requester::Sender # :nodoc:\n          def initialize(msg, data, sock, host, port)\n            super(msg, data, sock)\n            @host = host\n            @port = port\n          end\n          attr_reader :data\n\n          def send\n            @sock.send(@msg, 0, @host, @port)\n          end\n        end\n      end\n\n      class ConnectedUDP < Requester # :nodoc:\n        def initialize(host, port=Port)\n          super()\n          @host = host\n          @port = port\n          is_ipv6 = host.index(':')\n          @sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)\n          DNS.bind_random_port(@sock, is_ipv6)\n          @sock.connect(host, port)\n          @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD\n        end\n\n        def recv_reply\n          reply = @sock.recv(UDPSize)\n          return reply, nil\n        end\n\n        def sender(msg, data, host=@host, port=@port)\n          unless host == @host && port == @port\n            raise RequestError.new(\"host/port don't match: #{host}:#{port}\")\n          end\n          id = DNS.allocate_request_id(@host, @port)\n          request = msg.encode\n          request[0,2] = [id].pack('n')\n          return @senders[[nil,id]] = Sender.new(request, data, @sock)\n        end\n\n        def close\n          super\n          @senders.each_key {|from, id|\n            DNS.free_request_id(@host, @port, id)\n          }\n        end\n\n        class Sender < Requester::Sender # :nodoc:\n          def send\n            @sock.send(@msg, 0)\n          end\n          attr_reader :data\n        end\n      end\n\n      class TCP < Requester # :nodoc:\n        def initialize(host, port=Port)\n          super()\n          @host = host\n          @port = port\n          @sock = TCPSocket.new(@host, @port)\n          @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD\n          @senders = {}\n        end\n\n        def recv_reply\n          len = @sock.read(2).unpack('n')[0]\n          reply = @sock.read(len)\n          return reply, nil\n        end\n\n        def sender(msg, data, host=@host, port=@port)\n          unless host == @host && port == @port\n            raise RequestError.new(\"host/port don't match: #{host}:#{port}\")\n          end\n          id = DNS.allocate_request_id(@host, @port)\n          request = msg.encode\n          request[0,2] = [request.length, id].pack('nn')\n          return @senders[[nil,id]] = Sender.new(request, data, @sock)\n        end\n\n        class Sender < Requester::Sender # :nodoc:\n          def send\n            @sock.print(@msg)\n            @sock.flush\n          end\n          attr_reader :data\n        end\n\n        def close\n          super\n          @senders.each_key {|from,id|\n            DNS.free_request_id(@host, @port, id)\n          }\n        end\n      end\n\n      ##\n      # Indicates a problem with the DNS request.\n\n      class RequestError < StandardError\n      end\n    end\n\n    class Config # :nodoc:\n      def initialize(config_info=nil)\n        @mutex = Mutex.new\n        @config_info = config_info\n        @initialized = nil\n      end\n\n      def Config.parse_resolv_conf(filename)\n        nameserver = []\n        search = nil\n        ndots = 1\n        open(filename) {|f|\n          f.each {|line|\n            line.sub!(/[#;].*/, '')\n            keyword, *args = line.split(/\\s+/)\n            args.each { |arg|\n              arg.untaint\n            }\n            next unless keyword\n            case keyword\n            when 'nameserver'\n              nameserver += args\n            when 'domain'\n              next if args.empty?\n              search = [args[0]]\n            when 'search'\n              next if args.empty?\n              search = args\n            when 'options'\n              args.each {|arg|\n                case arg\n                when /\\Andots:(\\d+)\\z/\n                  ndots = $1.to_i\n                end\n              }\n            end\n          }\n        }\n        return { :nameserver => nameserver, :search => search, :ndots => ndots }\n      end\n\n      def Config.default_config_hash(filename=\"/etc/resolv.conf\")\n        if File.exist? filename\n          config_hash = Config.parse_resolv_conf(filename)\n        else\n          if /mswin32|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM\n            require 'win32/resolv'\n            search, nameserver = Win32::Resolv.get_resolv_info\n            config_hash = {}\n            config_hash[:nameserver] = nameserver if nameserver\n            config_hash[:search] = [search].flatten if search\n          end\n        end\n        config_hash\n      end\n\n      def lazy_initialize\n        @mutex.synchronize {\n          unless @initialized\n            @nameserver = []\n            @search = nil\n            @ndots = 1\n            case @config_info\n            when nil\n              config_hash = Config.default_config_hash\n            when String\n              config_hash = Config.parse_resolv_conf(@config_info)\n            when Hash\n              config_hash = @config_info.dup\n              if String === config_hash[:nameserver]\n                config_hash[:nameserver] = [config_hash[:nameserver]]\n              end\n              if String === config_hash[:search]\n                config_hash[:search] = [config_hash[:search]]\n              end\n            else\n              raise ArgumentError.new(\"invalid resolv configuration: #{@config_info.inspect}\")\n            end\n            @nameserver = config_hash[:nameserver] if config_hash.include? :nameserver\n            @search = config_hash[:search] if config_hash.include? :search\n            @ndots = config_hash[:ndots] if config_hash.include? :ndots\n\n            @nameserver = ['0.0.0.0'] if @nameserver.empty?\n            if @search\n              @search = @search.map {|arg| Label.split(arg) }\n            else\n              hostname = Socket.gethostname\n              if /\\./ =~ hostname\n                @search = [Label.split($')]\n              else\n                @search = [[]]\n              end\n            end\n\n            if !@nameserver.kind_of?(Array) ||\n               !@nameserver.all? {|ns| String === ns }\n              raise ArgumentError.new(\"invalid nameserver config: #{@nameserver.inspect}\")\n            end\n\n            if !@search.kind_of?(Array) ||\n               !@search.all? {|ls| ls.all? {|l| Label::Str === l } }\n              raise ArgumentError.new(\"invalid search config: #{@search.inspect}\")\n            end\n\n            if !@ndots.kind_of?(Integer)\n              raise ArgumentError.new(\"invalid ndots config: #{@ndots.inspect}\")\n            end\n\n            @initialized = true\n          end\n        }\n        self\n      end\n\n      def single?\n        lazy_initialize\n        if @nameserver.length == 1\n          return @nameserver[0]\n        else\n          return nil\n        end\n      end\n\n      def generate_candidates(name)\n        candidates = nil\n        name = Name.create(name)\n        if name.absolute?\n          candidates = [name]\n        else\n          if @ndots <= name.length - 1\n            candidates = [Name.new(name.to_a)]\n          else\n            candidates = []\n          end\n          candidates.concat(@search.map {|domain| Name.new(name.to_a + domain)})\n        end\n        return candidates\n      end\n\n      InitialTimeout = 5\n\n      def generate_timeouts\n        ts = [InitialTimeout]\n        ts << ts[-1] * 2 / @nameserver.length\n        ts << ts[-1] * 2\n        ts << ts[-1] * 2\n        return ts\n      end\n\n      def resolv(name)\n        candidates = generate_candidates(name)\n        timeouts = generate_timeouts\n        begin\n          candidates.each {|candidate|\n            begin\n              timeouts.each {|tout|\n                @nameserver.each {|nameserver|\n                  begin\n                    yield candidate, tout, nameserver\n                  rescue ResolvTimeout\n                  end\n                }\n              }\n              raise ResolvError.new(\"DNS resolv timeout: #{name}\")\n            rescue NXDomain\n            end\n          }\n        rescue ResolvError\n        end\n      end\n\n      ##\n      # Indicates no such domain was found.\n\n      class NXDomain < ResolvError\n      end\n\n      ##\n      # Indicates some other unhandled resolver error was encountered.\n\n      class OtherResolvError < ResolvError\n      end\n    end\n\n    module OpCode # :nodoc:\n      Query = 0\n      IQuery = 1\n      Status = 2\n      Notify = 4\n      Update = 5\n    end\n\n    module RCode # :nodoc:\n      NoError = 0\n      FormErr = 1\n      ServFail = 2\n      NXDomain = 3\n      NotImp = 4\n      Refused = 5\n      YXDomain = 6\n      YXRRSet = 7\n      NXRRSet = 8\n      NotAuth = 9\n      NotZone = 10\n      BADVERS = 16\n      BADSIG = 16\n      BADKEY = 17\n      BADTIME = 18\n      BADMODE = 19\n      BADNAME = 20\n      BADALG = 21\n    end\n\n    ##\n    # Indicates that the DNS response was unable to be decoded.\n\n    class DecodeError < StandardError\n    end\n\n    ##\n    # Indicates that the DNS request was unable to be encoded.\n\n    class EncodeError < StandardError\n    end\n\n    module Label # :nodoc:\n      def self.split(arg)\n        labels = []\n        arg.scan(/[^\\.]+/) {labels << Str.new($&)}\n        return labels\n      end\n\n      class Str # :nodoc:\n        def initialize(string)\n          @string = string\n          @downcase = string.downcase\n        end\n        attr_reader :string, :downcase\n\n        def to_s\n          return @string\n        end\n\n        def inspect\n          return \"#<#{self.class} #{self.to_s}>\"\n        end\n\n        def ==(other)\n          return @downcase == other.downcase\n        end\n\n        def eql?(other)\n          return self == other\n        end\n\n        def hash\n          return @downcase.hash\n        end\n      end\n    end\n\n    ##\n    # A representation of a DNS name.\n\n    class Name\n      \n      ##\n      # Creates a new DNS name from +arg+.  +arg+ can be:\n      #\n      # Name:: returns +arg+.\n      # String:: Creates a new Name.\n\n      def self.create(arg)\n        case arg\n        when Name\n          return arg\n        when String\n          return Name.new(Label.split(arg), /\\.\\z/ =~ arg ? true : false)\n        else\n          raise ArgumentError.new(\"cannot interpret as DNS name: #{arg.inspect}\")\n        end\n      end\n\n      def initialize(labels, absolute=true) # :nodoc:\n        @labels = labels\n        @absolute = absolute\n      end\n\n      def inspect # :nodoc:\n        \"#<#{self.class}: #{self.to_s}#{@absolute ? '.' : ''}>\"\n      end\n\n      ##\n      # True if this name is absolute.\n\n      def absolute?\n        return @absolute\n      end\n\n      def ==(other) # :nodoc:\n        return false unless Name === other\n        return @labels.join == other.to_a.join && @absolute == other.absolute?\n      end\n\n      alias eql? == # :nodoc:\n\n      ##\n      # Returns true if +other+ is a subdomain.\n      #\n      # Example:\n      #\n      #   domain = Resolv::DNS::Name.create(\"y.z\")\n      #   p Resolv::DNS::Name.create(\"w.x.y.z\").subdomain_of?(domain) #=> true\n      #   p Resolv::DNS::Name.create(\"x.y.z\").subdomain_of?(domain) #=> true\n      #   p Resolv::DNS::Name.create(\"y.z\").subdomain_of?(domain) #=> false\n      #   p Resolv::DNS::Name.create(\"z\").subdomain_of?(domain) #=> false\n      #   p Resolv::DNS::Name.create(\"x.y.z.\").subdomain_of?(domain) #=> false\n      #   p Resolv::DNS::Name.create(\"w.z\").subdomain_of?(domain) #=> false\n      #\n\n      def subdomain_of?(other)\n        raise ArgumentError, \"not a domain name: #{other.inspect}\" unless Name === other\n        return false if @absolute != other.absolute?\n        other_len = other.length\n        return false if @labels.length <= other_len\n        return @labels[-other_len, other_len] == other.to_a\n      end\n\n      def hash # :nodoc:\n        return @labels.hash ^ @absolute.hash\n      end\n\n      def to_a # :nodoc:\n        return @labels\n      end\n\n      def length # :nodoc:\n        return @labels.length\n      end\n\n      def [](i) # :nodoc:\n        return @labels[i]\n      end\n\n      ##\n      # returns the domain name as a string.\n      #\n      # The domain name doesn't have a trailing dot even if the name object is\n      # absolute.\n      #\n      # Example:\n      #\n      #   p Resolv::DNS::Name.create(\"x.y.z.\").to_s #=> \"x.y.z\"\n      #   p Resolv::DNS::Name.create(\"x.y.z\").to_s #=> \"x.y.z\"\n\n      def to_s\n        return @labels.join('.')\n      end\n    end\n\n    class Message # :nodoc:\n      @@identifier = -1\n\n      def initialize(id = (@@identifier += 1) & 0xffff)\n        @id = id\n        @qr = 0\n        @opcode = 0\n        @aa = 0\n        @tc = 0\n        @rd = 0 # recursion desired\n        @ra = 0 # recursion available\n        @rcode = 0\n        @question = []\n        @answer = []\n        @authority = []\n        @additional = []\n      end\n\n      attr_accessor :id, :qr, :opcode, :aa, :tc, :rd, :ra, :rcode\n      attr_reader :question, :answer, :authority, :additional\n\n      def ==(other)\n        return @id == other.id &&\n               @qr == other.qr &&\n               @opcode == other.opcode &&\n               @aa == other.aa &&\n               @tc == other.tc &&\n               @rd == other.rd &&\n               @ra == other.ra &&\n               @rcode == other.rcode &&\n               @question == other.question &&\n               @answer == other.answer &&\n               @authority == other.authority &&\n               @additional == other.additional\n      end\n\n      def add_question(name, typeclass)\n        @question << [Name.create(name), typeclass]\n      end\n\n      def each_question\n        @question.each {|name, typeclass|\n          yield name, typeclass\n        }\n      end\n\n      def add_answer(name, ttl, data)\n        @answer << [Name.create(name), ttl, data]\n      end\n\n      def each_answer\n        @answer.each {|name, ttl, data|\n          yield name, ttl, data\n        }\n      end\n\n      def add_authority(name, ttl, data)\n        @authority << [Name.create(name), ttl, data]\n      end\n\n      def each_authority\n        @authority.each {|name, ttl, data|\n          yield name, ttl, data\n        }\n      end\n\n      def add_additional(name, ttl, data)\n        @additional << [Name.create(name), ttl, data]\n      end\n\n      def each_additional\n        @additional.each {|name, ttl, data|\n          yield name, ttl, data\n        }\n      end\n\n      def each_resource\n        each_answer {|name, ttl, data| yield name, ttl, data}\n        each_authority {|name, ttl, data| yield name, ttl, data}\n        each_additional {|name, ttl, data| yield name, ttl, data}\n      end\n\n      def encode\n        return MessageEncoder.new {|msg|\n          msg.put_pack('nnnnnn',\n            @id,\n            (@qr & 1) << 15 |\n            (@opcode & 15) << 11 |\n            (@aa & 1) << 10 |\n            (@tc & 1) << 9 |\n            (@rd & 1) << 8 |\n            (@ra & 1) << 7 |\n            (@rcode & 15),\n            @question.length,\n            @answer.length,\n            @authority.length,\n            @additional.length)\n          @question.each {|q|\n            name, typeclass = q\n            msg.put_name(name)\n            msg.put_pack('nn', typeclass::TypeValue, typeclass::ClassValue)\n          }\n          [@answer, @authority, @additional].each {|rr|\n            rr.each {|r|\n              name, ttl, data = r\n              msg.put_name(name)\n              msg.put_pack('nnN', data.class::TypeValue, data.class::ClassValue, ttl)\n              msg.put_length16 {data.encode_rdata(msg)}\n            }\n          }\n        }.to_s\n      end\n\n      class MessageEncoder # :nodoc:\n        def initialize\n          @data = ''\n          @names = {}\n          yield self\n        end\n\n        def to_s\n          return @data\n        end\n\n        def put_bytes(d)\n          @data << d\n        end\n\n        def put_pack(template, *d)\n          @data << d.pack(template)\n        end\n\n        def put_length16\n          length_index = @data.length\n          @data << \"\\0\\0\"\n          data_start = @data.length\n          yield\n          data_end = @data.length\n          @data[length_index, 2] = [data_end - data_start].pack(\"n\")\n        end\n\n        def put_string(d)\n          self.put_pack(\"C\", d.length)\n          @data << d\n        end\n\n        def put_string_list(ds)\n          ds.each {|d|\n            self.put_string(d)\n          }\n        end\n\n        def put_name(d)\n          put_labels(d.to_a)\n        end\n\n        def put_labels(d)\n          d.each_index {|i|\n            domain = d[i..-1]\n            if idx = @names[domain]\n              self.put_pack(\"n\", 0xc000 | idx)\n              return\n            else\n              @names[domain] = @data.length\n              self.put_label(d[i])\n            end\n          }\n          @data << \"\\0\"\n        end\n\n        def put_label(d)\n          self.put_string(d.to_s)\n        end\n      end\n\n      def Message.decode(m)\n        o = Message.new(0)\n        MessageDecoder.new(m) {|msg|\n          id, flag, qdcount, ancount, nscount, arcount =\n            msg.get_unpack('nnnnnn')\n          o.id = id\n          o.qr = (flag >> 15) & 1\n          o.opcode = (flag >> 11) & 15\n          o.aa = (flag >> 10) & 1\n          o.tc = (flag >> 9) & 1\n          o.rd = (flag >> 8) & 1\n          o.ra = (flag >> 7) & 1\n          o.rcode = flag & 15\n          (1..qdcount).each {\n            name, typeclass = msg.get_question\n            o.add_question(name, typeclass)\n          }\n          (1..ancount).each {\n            name, ttl, data = msg.get_rr\n            o.add_answer(name, ttl, data)\n          }\n          (1..nscount).each {\n            name, ttl, data = msg.get_rr\n            o.add_authority(name, ttl, data)\n          }\n          (1..arcount).each {\n            name, ttl, data = msg.get_rr\n            o.add_additional(name, ttl, data)\n          }\n        }\n        return o\n      end\n\n      class MessageDecoder # :nodoc:\n        def initialize(data)\n          @data = data\n          @index = 0\n          @limit = data.length\n          yield self\n        end\n\n        def get_length16\n          len, = self.get_unpack('n')\n          save_limit = @limit\n          @limit = @index + len\n          d = yield(len)\n          if @index < @limit\n            raise DecodeError.new(\"junk exists\")\n          elsif @limit < @index\n            raise DecodeError.new(\"limit exceeded\")\n          end\n          @limit = save_limit\n          return d\n        end\n\n        def get_bytes(len = @limit - @index)\n          d = @data[@index, len]\n          @index += len\n          return d\n        end\n\n        def get_unpack(template)\n          len = 0\n          template.each_byte {|byte|\n            case byte\n            when ?c, ?C\n              len += 1\n            when ?n\n              len += 2\n            when ?N\n              len += 4\n            else\n              raise StandardError.new(\"unsupported template: '#{byte.chr}' in '#{template}'\")\n            end\n          }\n          raise DecodeError.new(\"limit exceeded\") if @limit < @index + len\n          arr = @data.unpack(\"@#{@index}#{template}\")\n          @index += len\n          return arr\n        end\n\n        def get_string\n          len = @data[@index]\n          raise DecodeError.new(\"limit exceeded\") if @limit < @index + 1 + len\n          d = @data[@index + 1, len]\n          @index += 1 + len\n          return d\n        end\n\n        def get_string_list\n          strings = []\n          while @index < @limit\n            strings << self.get_string\n          end\n          strings\n        end\n\n        def get_name\n          return Name.new(self.get_labels)\n        end\n\n        def get_labels(limit=nil)\n          limit = @index if !limit || @index < limit\n          d = []\n          while true\n            case @data[@index]\n            when 0\n              @index += 1\n              return d\n            when 192..255\n              idx = self.get_unpack('n')[0] & 0x3fff\n              if limit <= idx\n                raise DecodeError.new(\"non-backward name pointer\")\n              end\n              save_index = @index\n              @index = idx\n              d += self.get_labels(limit)\n              @index = save_index\n              return d\n            else\n              d << self.get_label\n            end\n          end\n          return d\n        end\n\n        def get_label\n          return Label::Str.new(self.get_string)\n        end\n\n        def get_question\n          name = self.get_name\n          type, klass = self.get_unpack(\"nn\")\n          return name, Resource.get_class(type, klass)\n        end\n\n        def get_rr\n          name = self.get_name\n          type, klass, ttl = self.get_unpack('nnN')\n          typeclass = Resource.get_class(type, klass)\n          return name, ttl, self.get_length16 {typeclass.decode_rdata(self)}\n        end\n      end\n    end\n\n    ##\n    # A DNS query abstract class.\n\n    class Query\n      def encode_rdata(msg) # :nodoc:\n        raise EncodeError.new(\"#{self.class} is query.\") \n      end\n\n      def self.decode_rdata(msg) # :nodoc:\n        raise DecodeError.new(\"#{self.class} is query.\") \n      end\n    end\n\n    ##\n    # A DNS resource abstract class.\n\n    class Resource < Query\n\n      ##\n      # Remaining Time To Live for this Resource.\n\n      attr_reader :ttl\n\n      ClassHash = {} # :nodoc:\n\n      def encode_rdata(msg) # :nodoc:\n        raise NotImplementedError.new\n      end\n\n      def self.decode_rdata(msg) # :nodoc:\n        raise NotImplementedError.new\n      end\n\n      def ==(other) # :nodoc:\n        return self.class == other.class &&\n          self.instance_variables == other.instance_variables &&\n          self.instance_variables.collect {|name| self.instance_eval name} ==\n            other.instance_variables.collect {|name| other.instance_eval name}\n      end\n\n      def eql?(other) # :nodoc:\n        return self == other\n      end\n\n      def hash # :nodoc:\n        h = 0\n        self.instance_variables.each {|name|\n          h ^= self.instance_eval(\"#{name}.hash\")\n        }\n        return h\n      end\n\n      def self.get_class(type_value, class_value) # :nodoc:\n        return ClassHash[[type_value, class_value]] ||\n               Generic.create(type_value, class_value)\n      end\n\n      ##\n      # A generic resource abstract class.\n\n      class Generic < Resource\n\n        ##\n        # Creates a new generic resource.\n\n        def initialize(data)\n          @data = data\n        end\n\n        ##\n        # Data for this generic resource.\n\n        attr_reader :data\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_bytes(data)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          return self.new(msg.get_bytes)\n        end\n\n        def self.create(type_value, class_value) # :nodoc:\n          c = Class.new(Generic)\n          c.const_set(:TypeValue, type_value)\n          c.const_set(:ClassValue, class_value)\n          Generic.const_set(\"Type#{type_value}_Class#{class_value}\", c)\n          ClassHash[[type_value, class_value]] = c\n          return c\n        end\n      end\n\n      ##\n      # Domain Name resource abstract class.\n\n      class DomainName < Resource\n\n        ##\n        # Creates a new DomainName from +name+.\n\n        def initialize(name)\n          @name = name\n        end\n\n        ##\n        # The name of this DomainName.\n\n        attr_reader :name\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_name(@name)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          return self.new(msg.get_name)\n        end\n      end\n\n      # Standard (class generic) RRs\n\n      ClassValue = nil # :nodoc:\n\n      ##\n      # An authoritative name server.\n\n      class NS < DomainName\n        TypeValue = 2 # :nodoc:\n      end\n\n      ##\n      # The canonical name for an alias.\n\n      class CNAME < DomainName\n        TypeValue = 5 # :nodoc:\n      end\n\n      ##\n      # Start Of Authority resource.\n\n      class SOA < Resource\n\n        TypeValue = 6 # :nodoc:\n\n        ##\n        # Creates a new SOA record.  See the attr documentation for the\n        # details of each argument.\n\n        def initialize(mname, rname, serial, refresh, retry_, expire, minimum)\n          @mname = mname\n          @rname = rname\n          @serial = serial\n          @refresh = refresh\n          @retry = retry_\n          @expire = expire\n          @minimum = minimum\n        end\n\n        ##\n        # Name of the host where the master zone file for this zone resides.\n\n        attr_reader :mname\n\n        ##\n        # The person responsible for this domain name.\n\n        attr_reader :rname\n\n        ##\n        # The version number of the zone file.\n\n        attr_reader :serial\n\n        ##\n        # How often, in seconds, a secondary name server is to check for\n        # updates from the primary name server.\n\n        attr_reader :refresh\n\n        ##\n        # How often, in seconds, a secondary name server is to retry after a\n        # failure to check for a refresh.\n\n        attr_reader :retry\n\n        ##\n        # Time in seconds that a secondary name server is to use the data\n        # before refreshing from the primary name server.\n\n        attr_reader :expire\n\n        ##\n        # The minimum number of seconds to be used for TTL values in RRs.\n\n        attr_reader :minimum\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_name(@mname)\n          msg.put_name(@rname)\n          msg.put_pack('NNNNN', @serial, @refresh, @retry, @expire, @minimum)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          mname = msg.get_name\n          rname = msg.get_name\n          serial, refresh, retry_, expire, minimum = msg.get_unpack('NNNNN')\n          return self.new(\n            mname, rname, serial, refresh, retry_, expire, minimum)\n        end\n      end\n\n      ##\n      # A Pointer to another DNS name.\n\n      class PTR < DomainName\n        TypeValue = 12 # :nodoc:\n      end\n\n      ##\n      # Host Information resource.\n\n      class HINFO < Resource\n\n        TypeValue = 13 # :nodoc:\n\n        ##\n        # Creates a new HINFO running +os+ on +cpu+.\n\n        def initialize(cpu, os)\n          @cpu = cpu\n          @os = os\n        end\n\n        ##\n        # CPU architecture for this resource.\n\n        attr_reader :cpu\n\n        ##\n        # Operating system for this resource.\n\n        attr_reader :os\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_string(@cpu)\n          msg.put_string(@os)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          cpu = msg.get_string\n          os = msg.get_string\n          return self.new(cpu, os)\n        end\n      end\n\n      ##\n      # Mailing list or mailbox information.\n\n      class MINFO < Resource\n\n        TypeValue = 14 # :nodoc:\n\n        def initialize(rmailbx, emailbx)\n          @rmailbx = rmailbx\n          @emailbx = emailbx\n        end\n\n        ##\n        # Domain name responsible for this mail list or mailbox.\n\n        attr_reader :rmailbx\n\n        ##\n        # Mailbox to use for error messages related to the mail list or mailbox.\n\n        attr_reader :emailbx\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_name(@rmailbx)\n          msg.put_name(@emailbx)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          rmailbx = msg.get_string\n          emailbx = msg.get_string\n          return self.new(rmailbx, emailbx)\n        end\n      end\n\n      ##\n      # Mail Exchanger resource.\n\n      class MX < Resource\n\n        TypeValue= 15 # :nodoc:\n\n        ##\n        # Creates a new MX record with +preference+, accepting mail at\n        # +exchange+.\n\n        def initialize(preference, exchange)\n          @preference = preference\n          @exchange = exchange\n        end\n\n        ##\n        # The preference for this MX.\n\n        attr_reader :preference\n\n        ##\n        # The host of this MX.\n\n        attr_reader :exchange\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_pack('n', @preference)\n          msg.put_name(@exchange)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          preference, = msg.get_unpack('n')\n          exchange = msg.get_name\n          return self.new(preference, exchange)\n        end\n      end\n\n      ##\n      # Unstructured text resource.\n\n      class TXT < Resource\n\n        TypeValue = 16 # :nodoc:\n\n        def initialize(first_string, *rest_strings)\n          @strings = [first_string, *rest_strings]\n        end\n\n        ##\n        # Returns an Array of Strings for this TXT record.\n\n        attr_reader :strings\n\n        ##\n        # Returns the first string from +strings+.\n\n        def data\n          @strings[0]\n        end\n\n        def encode_rdata(msg) # :nodoc:\n          msg.put_string_list(@strings)\n        end\n\n        def self.decode_rdata(msg) # :nodoc:\n          strings = msg.get_string_list\n          return self.new(*strings)\n        end\n      end\n\n      ##\n      # A Query type requesting any RR.\n\n      class ANY < Query\n        TypeValue = 255 # :nodoc:\n      end\n\n      ClassInsensitiveTypes = [ # :nodoc:\n        NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY\n      ]\n\n      ##\n      # module IN contains ARPA Internet specific RRs.\n\n      module IN\n\n        ClassValue = 1 # :nodoc:\n\n        ClassInsensitiveTypes.each {|s|\n          c = Class.new(s)\n          c.const_set(:TypeValue, s::TypeValue)\n          c.const_set(:ClassValue, ClassValue)\n          ClassHash[[s::TypeValue, ClassValue]] = c\n          self.const_set(s.name.sub(/.*::/, ''), c)\n        }\n\n        ##\n        # IPv4 Address resource\n\n        class A < Resource\n          TypeValue = 1\n          ClassValue = IN::ClassValue\n          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:\n\n          ##\n          # Creates a new A for +address+.\n\n          def initialize(address)\n            @address = IPv4.create(address)\n          end\n\n          ##\n          # The Resolv::IPv4 address for this A.\n\n          attr_reader :address\n\n          def encode_rdata(msg) # :nodoc:\n            msg.put_bytes(@address.address)\n          end\n\n          def self.decode_rdata(msg) # :nodoc:\n            return self.new(IPv4.new(msg.get_bytes(4)))\n          end\n        end\n\n        ##\n        # Well Known Service resource.\n\n        class WKS < Resource\n          TypeValue = 11\n          ClassValue = IN::ClassValue\n          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:\n\n          def initialize(address, protocol, bitmap)\n            @address = IPv4.create(address)\n            @protocol = protocol\n            @bitmap = bitmap\n          end\n\n          ##\n          # The host these services run on.\n\n          attr_reader :address\n\n          ##\n          # IP protocol number for these services.\n\n          attr_reader :protocol\n\n          ##\n          # A bit map of enabled services on this host.\n          #\n          # If protocol is 6 (TCP) then the 26th bit corresponds to the SMTP\n          # service (port 25).  If this bit is set, then an SMTP server should\n          # be listening on TCP port 25; if zero, SMTP service is not\n          # supported.\n\n          attr_reader :bitmap\n\n          def encode_rdata(msg) # :nodoc:\n            msg.put_bytes(@address.address)\n            msg.put_pack(\"n\", @protocol)\n            msg.put_bytes(@bitmap)\n          end\n\n          def self.decode_rdata(msg) # :nodoc:\n            address = IPv4.new(msg.get_bytes(4))\n            protocol, = msg.get_unpack(\"n\")\n            bitmap = msg.get_bytes\n            return self.new(address, protocol, bitmap)\n          end\n        end\n\n        ##\n        # An IPv6 address record.\n\n        class AAAA < Resource\n          TypeValue = 28\n          ClassValue = IN::ClassValue\n          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:\n\n          ##\n          # Creates a new AAAA for +address+.\n\n          def initialize(address)\n            @address = IPv6.create(address)\n          end\n          \n          ##\n          # The Resolv::IPv6 address for this AAAA.\n\n          attr_reader :address\n\n          def encode_rdata(msg) # :nodoc:\n            msg.put_bytes(@address.address)\n          end\n\n          def self.decode_rdata(msg) # :nodoc:\n            return self.new(IPv6.new(msg.get_bytes(16)))\n          end\n        end\n\n        ##\n        # SRV resource record defined in RFC 2782\n        # \n        # These records identify the hostname and port that a service is\n        # available at.\n\n        class SRV < Resource\n          TypeValue = 33\n          ClassValue = IN::ClassValue\n          ClassHash[[TypeValue, ClassValue]] = self # :nodoc:\n\n          # Create a SRV resource record.\n          #\n          # See the documentation for #priority, #weight, #port and #target\n          # for +priority+, +weight+, +port and +target+ respectively.\n\n          def initialize(priority, weight, port, target)\n            @priority = priority.to_int\n            @weight = weight.to_int\n            @port = port.to_int\n            @target = Name.create(target)\n          end\n\n          # The priority of this target host.\n          #\n          # A client MUST attempt to contact the target host with the\n          # lowest-numbered priority it can reach; target hosts with the same\n          # priority SHOULD be tried in an order defined by the weight field.\n          # The range is 0-65535.  Note that it is not widely implemented and\n          # should be set to zero.\n\n          attr_reader :priority\n\n          # A server selection mechanism.\n          #\n          # The weight field specifies a relative weight for entries with the\n          # same priority. Larger weights SHOULD be given a proportionately\n          # higher probability of being selected. The range of this number is\n          # 0-65535.  Domain administrators SHOULD use Weight 0 when there\n          # isn't any server selection to do, to make the RR easier to read\n          # for humans (less noisy). Note that it is not widely implemented\n          # and should be set to zero.\n\n          attr_reader :weight\n\n          # The port on this target host of this service.\n          #\n          # The range is 0-65535.\n\n          attr_reader :port\n\n          # The domain name of the target host.\n          #\n          # A target of \".\" means that the service is decidedly not available\n          # at this domain.\n\n          attr_reader :target\n\n          def encode_rdata(msg) # :nodoc:\n            msg.put_pack(\"n\", @priority)\n            msg.put_pack(\"n\", @weight)\n            msg.put_pack(\"n\", @port)\n            msg.put_name(@target)\n          end\n\n          def self.decode_rdata(msg) # :nodoc:\n            priority, = msg.get_unpack(\"n\")\n            weight,   = msg.get_unpack(\"n\")\n            port,     = msg.get_unpack(\"n\")\n            target    = msg.get_name\n            return self.new(priority, weight, port, target)\n          end\n        end\n      end\n    end\n  end\n\n  ##\n  # A Resolv::DNS IPv4 address.\n\n  class IPv4\n\n    ##\n    # Regular expression IPv4 addresses must match.\n\n    Regex = /\\A(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\z/\n\n    def self.create(arg)\n      case arg\n      when IPv4\n        return arg\n      when Regex\n        if (0..255) === (a = $1.to_i) &&\n           (0..255) === (b = $2.to_i) &&\n           (0..255) === (c = $3.to_i) &&\n           (0..255) === (d = $4.to_i)\n          return self.new([a, b, c, d].pack(\"CCCC\"))\n        else\n          raise ArgumentError.new(\"IPv4 address with invalid value: \" + arg)\n        end\n      else\n        raise ArgumentError.new(\"cannot interpret as IPv4 address: #{arg.inspect}\")\n      end\n    end\n\n    def initialize(address) # :nodoc:\n      unless address.kind_of?(String) && address.length == 4\n        raise ArgumentError.new('IPv4 address must be 4 bytes')\n      end\n      @address = address\n    end\n\n    ##\n    # A String representation of this IPv4 address.\n\n    ##\n    # The raw IPv4 address as a String.\n\n    attr_reader :address\n\n    def to_s # :nodoc:\n      return sprintf(\"%d.%d.%d.%d\", *@address.unpack(\"CCCC\"))\n    end\n\n    def inspect # :nodoc:\n      return \"#<#{self.class} #{self.to_s}>\"\n    end\n\n    ##\n    # Turns this IPv4 address into a Resolv::DNS::Name.\n\n    def to_name\n      return DNS::Name.create(\n        '%d.%d.%d.%d.in-addr.arpa.' % @address.unpack('CCCC').reverse)\n    end\n\n    def ==(other) # :nodoc:\n      return @address == other.address\n    end\n\n    def eql?(other) # :nodoc:\n      return self == other\n    end\n\n    def hash # :nodoc:\n      return @address.hash\n    end\n  end\n\n  ##\n  # A Resolv::DNS IPv6 address.\n\n  class IPv6\n\n    ##\n    # IPv6 address format a:b:c:d:e:f:g:h\n    Regex_8Hex = /\\A\n      (?:[0-9A-Fa-f]{1,4}:){7}\n         [0-9A-Fa-f]{1,4}\n      \\z/x\n\n    ##\n    # Compressed IPv6 address format a::b\n\n    Regex_CompressedHex = /\\A\n      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::\n      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\n      \\z/x\n\n    ##\n    # IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z\n\n    Regex_6Hex4Dec = /\\A\n      ((?:[0-9A-Fa-f]{1,4}:){6,6})\n      (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\n      \\z/x\n\n    ##\n    # Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z\n\n    Regex_CompressedHex4Dec = /\\A\n      ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::\n      ((?:[0-9A-Fa-f]{1,4}:)*)\n      (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\n      \\z/x\n\n    ##\n    # A composite IPv6 address Regexp.\n\n    Regex = /\n      (?:#{Regex_8Hex}) |\n      (?:#{Regex_CompressedHex}) |\n      (?:#{Regex_6Hex4Dec}) |\n      (?:#{Regex_CompressedHex4Dec})/x\n\n    ##\n    # Creates a new IPv6 address from +arg+ which may be:\n    #\n    # IPv6:: returns +arg+.\n    # String:: +arg+ must match one of the IPv6::Regex* constants\n\n    def self.create(arg)\n      case arg\n      when IPv6\n        return arg\n      when String\n        address = ''\n        if Regex_8Hex =~ arg\n          arg.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}\n        elsif Regex_CompressedHex =~ arg\n          prefix = $1\n          suffix = $2\n          a1 = ''\n          a2 = ''\n          prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}\n          suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}\n          omitlen = 16 - a1.length - a2.length\n          address << a1 << \"\\0\" * omitlen << a2\n        elsif Regex_6Hex4Dec =~ arg\n          prefix, a, b, c, d = $1, $2.to_i, $3.to_i, $4.to_i, $5.to_i\n          if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d\n            prefix.scan(/[0-9A-Fa-f]+/) {|hex| address << [hex.hex].pack('n')}\n            address << [a, b, c, d].pack('CCCC')\n          else\n            raise ArgumentError.new(\"not numeric IPv6 address: \" + arg)\n          end\n        elsif Regex_CompressedHex4Dec =~ arg\n          prefix, suffix, a, b, c, d = $1, $2, $3.to_i, $4.to_i, $5.to_i, $6.to_i\n          if (0..255) === a && (0..255) === b && (0..255) === c && (0..255) === d\n            a1 = ''\n            a2 = ''\n            prefix.scan(/[0-9A-Fa-f]+/) {|hex| a1 << [hex.hex].pack('n')}\n            suffix.scan(/[0-9A-Fa-f]+/) {|hex| a2 << [hex.hex].pack('n')}\n            omitlen = 12 - a1.length - a2.length\n            address << a1 << \"\\0\" * omitlen << a2 << [a, b, c, d].pack('CCCC')\n          else\n            raise ArgumentError.new(\"not numeric IPv6 address: \" + arg)\n          end\n        else\n          raise ArgumentError.new(\"not numeric IPv6 address: \" + arg)\n        end\n        return IPv6.new(address)\n      else\n        raise ArgumentError.new(\"cannot interpret as IPv6 address: #{arg.inspect}\")\n      end\n    end\n\n    def initialize(address) # :nodoc:\n      unless address.kind_of?(String) && address.length == 16\n        raise ArgumentError.new('IPv6 address must be 16 bytes')\n      end\n      @address = address\n    end\n\n    ##\n    # The raw IPv6 address as a String.\n\n    attr_reader :address\n\n    def to_s # :nodoc:\n      address = sprintf(\"%X:%X:%X:%X:%X:%X:%X:%X\", *@address.unpack(\"nnnnnnnn\"))\n      unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')\n        address.sub!(/(^|:)0(:|$)/, '::')\n      end\n      return address\n    end\n\n    def inspect # :nodoc:\n      return \"#<#{self.class} #{self.to_s}>\"\n    end\n\n    ##\n    # Turns this IPv6 address into a Resolv::DNS::Name.\n    #--\n    # ip6.arpa should be searched too. [RFC3152]\n\n    def to_name\n      return DNS::Name.new(\n        @address.unpack(\"H32\")[0].split(//).reverse + ['ip6', 'arpa'])\n    end\n\n    def ==(other) # :nodoc:\n      return @address == other.address\n    end\n\n    def eql?(other) # :nodoc:\n      return self == other\n    end\n\n    def hash # :nodoc:\n      return @address.hash\n    end\n  end\n\n  ##\n  # Default resolver to use for Resolv class methods.\n\n  DefaultResolver = self.new\n\n  ##\n  # Address Regexp to use for matching IP addresses.\n\n  AddressRegex = /(?:#{IPv4::Regex})|(?:#{IPv6::Regex})/\n\nend\n\n"
  },
  {
    "path": "lib/rexml/attlistdecl.rb",
    "content": "#vim:ts=2 sw=2 noexpandtab:\nrequire 'rexml/child'\nrequire 'rexml/source'\n\nmodule REXML\n\t# This class needs:\n\t# * Documentation\n\t# * Work!  Not all types of attlists are intelligently parsed, so we just\n\t# spew back out what we get in.  This works, but it would be better if\n\t# we formatted the output ourselves.\n\t#\n\t# AttlistDecls provide *just* enough support to allow namespace\n\t# declarations.  If you need some sort of generalized support, or have an\n\t# interesting idea about how to map the hideous, terrible design of DTD\n\t# AttlistDecls onto an intuitive Ruby interface, let me know.  I'm desperate\n\t# for anything to make DTDs more palateable.\n\tclass AttlistDecl < Child\n\t\tinclude Enumerable\n\n\t\t# What is this?  Got me.\n\t\tattr_reader :element_name\n\n\t\t# Create an AttlistDecl, pulling the information from a Source.  Notice\n\t\t# that this isn't very convenient; to create an AttlistDecl, you basically\n\t\t# have to format it yourself, and then have the initializer parse it.\n\t\t# Sorry, but for the forseeable future, DTD support in REXML is pretty\n\t\t# weak on convenience.  Have I mentioned how much I hate DTDs?\n\t\tdef initialize(source)\n\t\t\tsuper()\n\t\t\tif (source.kind_of? Array)\n\t\t\t\t@element_name, @pairs, @contents = *source\n\t\t\tend\n\t\tend\n\t\n\t\t# Access the attlist attribute/value pairs.\n\t\t#  value = attlist_decl[ attribute_name ]\n\t\tdef [](key)\n\t\t\t@pairs[key]\n\t\tend\n\n\t\t# Whether an attlist declaration includes the given attribute definition\n\t\t#  if attlist_decl.include? \"xmlns:foobar\"\n\t\tdef include?(key)\n\t\t\t@pairs.keys.include? key\n\t\tend\n\n\t\t# Iterate over the key/value pairs:\n\t\t#  attlist_decl.each { |attribute_name, attribute_value| ... }\n\t\tdef each(&block)\n\t\t\t@pairs.each(&block)\n\t\tend\n\n\t\t# Write out exactly what we got in.\n\t\tdef write out, indent=-1\n\t\t\tout << @contents\n\t\tend\n\n\t\tdef node_type\n\t\t\t:attlistdecl\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/attribute.rb",
    "content": "require \"rexml/namespace\"\nrequire 'rexml/text'\n\nmodule REXML\n\t# Defines an Element Attribute; IE, a attribute=value pair, as in:\n\t# <element attribute=\"value\"/>.  Attributes can be in their own\n\t# namespaces.  General users of REXML will not interact with the\n\t# Attribute class much.\n\tclass Attribute\n\t\tinclude Node\n\t\tinclude Namespace\n\n\t\t# The element to which this attribute belongs\n\t\tattr_reader :element\n\t\t# The normalized value of this attribute.  That is, the attribute with\n\t\t# entities intact.\n\t\tattr_writer :normalized\t\n\t\tPATTERN = /\\s*(#{NAME_STR})\\s*=\\s*([\"'])(.*?)\\2/um\n\n\t\t# Constructor.\n    # FIXME: The parser doesn't catch illegal characters in attributes\n    #\n    # first:: \n    #   Either: an Attribute, which this new attribute will become a\n    #   clone of; or a String, which is the name of this attribute\n    # second::\n    #   If +first+ is an Attribute, then this may be an Element, or nil.\n    #   If nil, then the Element parent of this attribute is the parent\n    #   of the +first+ Attribute.  If the first argument is a String, \n    #   then this must also be a String, and is the content of the attribute.  \n    #   If this is the content, it must be fully normalized (contain no\n    #   illegal characters).\n    # parent::\n    #   Ignored unless +first+ is a String; otherwise, may be the Element \n    #   parent of this attribute, or nil.\n    #\n\t\t#\n\t\t#  Attribute.new( attribute_to_clone )\n\t\t#  Attribute.new( attribute_to_clone, parent_element )\n\t\t#  Attribute.new( \"attr\", \"attr_value\" )\n\t\t#  Attribute.new( \"attr\", \"attr_value\", parent_element )\n\t\tdef initialize( first, second=nil, parent=nil )\n\t\t\t@normalized = @unnormalized = @element = nil\n\t\t\tif first.kind_of? Attribute\n\t\t\t\tself.name = first.expanded_name\n\t\t\t\t@unnormalized = first.value\n\t\t\t\tif second.kind_of? Element\n\t\t\t\t\t@element = second\n\t\t\t\telse\n\t\t\t\t\t@element = first.element\n\t\t\t\tend\n\t\t\telsif first.kind_of? String\n\t\t\t\t@element = parent\n\t\t\t\tself.name = first\n\t\t\t\t@normalized = second.to_s\n\t\t\telse\n\t\t\t\traise \"illegal argument #{first.class.name} to Attribute constructor\"\n\t\t\tend\n\t\tend\n\n\t\t# Returns the namespace of the attribute.\n\t\t# \n\t\t#  e = Element.new( \"elns:myelement\" )\n\t\t#  e.add_attribute( \"nsa:a\", \"aval\" )\n\t\t#  e.add_attribute( \"b\", \"bval\" )\n\t\t#  e.attributes.get_attribute( \"a\" ).prefix   # -> \"nsa\"\n\t\t#  e.attributes.get_attribute( \"b\" ).prefix   # -> \"elns\"\n\t\t#  a = Attribute.new( \"x\", \"y\" )\n\t\t#  a.prefix                                   # -> \"\"\n\t\tdef prefix\n\t\t\tpf = super\n\t\t\tif pf == \"\"\n\t\t\t\tpf = @element.prefix if @element\n\t\t\tend\n\t\t\tpf\n\t\tend\n\n\t\t# Returns the namespace URL, if defined, or nil otherwise\n\t\t# \n\t\t#  e = Element.new(\"el\")\n\t\t#  e.add_attributes({\"xmlns:ns\", \"http://url\"})\n\t\t#  e.namespace( \"ns\" )              # -> \"http://url\"\n\t\tdef namespace arg=nil\n\t\t\targ = prefix if arg.nil?\n\t\t\t@element.namespace arg\n\t\tend\n\n\t\t# Returns true if other is an Attribute and has the same name and value,\n\t\t# false otherwise.\n\t\tdef ==( other )\n\t\t\tother.kind_of?(Attribute) and other.name==name and other.value==value\n\t\tend\n\n\t\t# Creates (and returns) a hash from both the name and value\n\t\tdef hash\n\t\t\tname.hash + value.hash\n\t\tend\n\n\t\t# Returns this attribute out as XML source, expanding the name\n\t\t#\n\t\t#  a = Attribute.new( \"x\", \"y\" )\n\t\t#  a.to_string     # -> \"x='y'\"\n\t\t#  b = Attribute.new( \"ns:x\", \"y\" )\n\t\t#  b.to_string     # -> \"ns:x='y'\"\n\t\tdef to_string\n\t\t\tif @element and @element.context and @element.context[:attribute_quote] == :quote\n\t\t\t\t%Q^#@expanded_name=\"#{to_s().gsub(/\"/, '&quote;')}\"^\n\t\t\telse\n\t\t\t\t\"#@expanded_name='#{to_s().gsub(/'/, '&apos;')}'\"\n\t\t\tend\n\t\tend\n\n\t\t# Returns the attribute value, with entities replaced\n\t\tdef to_s\n\t\t\treturn @normalized if @normalized\n\n\t\t\tdoctype = nil\n\t\t\tif @element\n\t\t\t\tdoc = @element.document\n\t\t\t\tdoctype = doc.doctype if doc\n\t\t\tend\n\n\t\t\t@normalized = Text::normalize( @unnormalized, doctype )\n\t\t\t@unnormalized = nil\n      @normalized\n\t\tend\n\n\t\t# Returns the UNNORMALIZED value of this attribute.  That is, entities\n\t\t# have been expanded to their values\n\t\tdef value\n\t\t\treturn @unnormalized if @unnormalized\n\t\t\tdoctype = nil\n\t\t\tif @element\n\t\t\t\tdoc = @element.document\n\t\t\t\tdoctype = doc.doctype if doc\n\t\t\tend\n\t\t\t@unnormalized = Text::unnormalize( @normalized, doctype )\n\t\t\t@normalized = nil\n      @unnormalized\n\t\tend\n\n\t\t# Returns a copy of this attribute\n\t\tdef clone\n\t\t\tAttribute.new self\n\t\tend\n\n\t\t# Sets the element of which this object is an attribute.  Normally, this\n\t\t# is not directly called.\n\t\t#\n\t\t# Returns this attribute\n\t\tdef element=( element )\n\t\t\t@element = element\n\t\t\tself\n\t\tend\n\n\t\t# Removes this Attribute from the tree, and returns true if successfull\n\t\t# \n\t\t# This method is usually not called directly.\n\t\tdef remove\n\t\t\t@element.attributes.delete self.name unless @element.nil?\n\t\tend\n\n\t\t# Writes this attribute (EG, puts 'key=\"value\"' to the output)\n\t\tdef write( output, indent=-1 )\n\t\t\toutput << to_string\n\t\tend\n\n    def node_type\n      :attribute\n    end\n\n    def inspect\n      rv = \"\"\n      write( rv )\n      rv\n    end\n\n    def xpath\n      path = @element.xpath\n      path += \"/@#{self.expanded_name}\"\n      return path\n    end\n\tend\nend\n#vim:ts=2 sw=2 noexpandtab:\n"
  },
  {
    "path": "lib/rexml/cdata.rb",
    "content": "require \"rexml/text\"\n\nmodule REXML\n\tclass CData < Text\n\t\tSTART = '<![CDATA['\n\t\tSTOP = ']]>'\n\t\tILLEGAL = /(\\]\\]>)/\n\n\t\t#\tConstructor.  CData is data between <![CDATA[ ... ]]>\n\t\t#\n\t\t# _Examples_\n\t\t#  CData.new( source )\n\t\t#  CData.new( \"Here is some CDATA\" )\n\t\t#  CData.new( \"Some unprocessed data\", respect_whitespace_TF, parent_element )\n\t\tdef initialize( first, whitespace=true, parent=nil )\n\t\t\tsuper( first, whitespace, parent, true, true, ILLEGAL )\n\t\tend\n\n\t\t# Make a copy of this object\n\t\t# \n\t\t# _Examples_\n\t\t#  c = CData.new( \"Some text\" )\n\t\t#  d = c.clone\n\t\t#  d.to_s        # -> \"Some text\"\n\t\tdef clone\n\t\t\tCData.new self\n\t\tend\n\n\t\t# Returns the content of this CData object\n\t\t#\n\t\t# _Examples_\n\t\t#  c = CData.new( \"Some text\" )\n\t\t#  c.to_s        # -> \"Some text\"\n\t\tdef to_s\n\t\t\t@string\n\t\tend\n\n    def value\n      @string\n    end\n\n    # == DEPRECATED\n    # See the rexml/formatters package\n    #\n\t\t# Generates XML output of this object\n\t\t#\n\t\t# output::\n\t\t#   Where to write the string.  Defaults to $stdout\n\t\t# indent::\n    #   The amount to indent this node by\n\t\t# transitive::\n    #   Ignored\n\t\t# ie_hack::\n    #   Ignored\n\t\t#\n\t\t# _Examples_\n\t\t#  c = CData.new( \" Some text \" )\n\t\t#  c.write( $stdout )     #->  <![CDATA[ Some text ]]>\n\t\tdef write( output=$stdout, indent=-1, transitive=false, ie_hack=false )\n      Kernel.warn( \"#{self.class.name}.write is deprecated\" )\n\t\t\tindent( output, indent )\n\t\t\toutput << START\n\t\t\toutput << @string\n\t\t\toutput << STOP\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/child.rb",
    "content": "require \"rexml/node\"\n\nmodule REXML\n\t##\n\t# A Child object is something contained by a parent, and this class\n\t# contains methods to support that.  Most user code will not use this\n\t# class directly.\n\tclass Child\n\t\tinclude Node\n\t\tattr_reader :parent\t\t# The Parent of this object\n\n\t\t# Constructor.  Any inheritors of this class should call super to make\n\t\t# sure this method is called.\n\t\t# parent::\n\t\t#   if supplied, the parent of this child will be set to the\n\t\t#   supplied value, and self will be added to the parent\n\t\tdef initialize( parent = nil )\n\t\t\t@parent = nil  \n\t\t\t# Declare @parent, but don't define it.  The next line sets the \n\t\t\t# parent.\n\t\t\tparent.add( self ) if parent\n\t\tend\n\n\t\t# Replaces this object with another object.  Basically, calls\n\t\t# Parent.replace_child\n\t\t#\n\t\t# Returns:: self\n\t\tdef replace_with( child )\n\t\t\t@parent.replace_child( self, child )\n\t\t\tself\n\t\tend\n\n\t\t# Removes this child from the parent.\n\t\t#\n\t\t# Returns:: self\n\t\tdef remove\n\t\t\tunless @parent.nil?\n\t\t\t\t@parent.delete self\n\t\t\tend\n\t\t\tself\n\t\tend\n\n\t\t# Sets the parent of this child to the supplied argument.\n\t\t#\n\t\t# other::\n\t\t#   Must be a Parent object.  If this object is the same object as the\n\t\t#   existing parent of this child, no action is taken. Otherwise, this\n\t\t#   child is removed from the current parent (if one exists), and is added\n\t\t#   to the new parent.\n\t\t# Returns:: The parent added\n\t\tdef parent=( other )\n\t\t\treturn @parent if @parent == other\n\t\t\t@parent.delete self if defined? @parent and @parent\n\t\t\t@parent = other\n\t\tend\n\n\t\talias :next_sibling :next_sibling_node\n\t\talias :previous_sibling :previous_sibling_node\n\n\t\t# Sets the next sibling of this child.  This can be used to insert a child\n\t\t# after some other child.\n\t\t#  a = Element.new(\"a\")\n\t\t#  b = a.add_element(\"b\")\n\t\t#  c = Element.new(\"c\")\n\t\t#  b.next_sibling = c\n\t\t#  # => <a><b/><c/></a>\n\t\tdef next_sibling=( other )\n\t\t  parent.insert_after self, other\n\t\tend\n\n\t\t# Sets the previous sibling of this child.  This can be used to insert a \n\t\t# child before some other child.\n\t\t#  a = Element.new(\"a\")\n\t\t#  b = a.add_element(\"b\")\n\t\t#  c = Element.new(\"c\")\n\t\t#  b.previous_sibling = c\n\t\t#  # => <a><b/><c/></a>\n\t\tdef previous_sibling=(other)\n\t\t  parent.insert_before self, other\n\t\tend\n\n\t\t# Returns:: the document this child belongs to, or nil if this child\n\t\t# belongs to no document\n\t\tdef document\n\t\t\treturn parent.document unless parent.nil?\n\t\t\tnil\n\t\tend\n\n\t\t# This doesn't yet handle encodings\n\t\tdef bytes\n\t\t\tencoding = document.encoding\n\n\t\t\tto_s\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/comment.rb",
    "content": "require \"rexml/child\"\n\nmodule REXML\n\t##\n\t# Represents an XML comment; that is, text between \\<!-- ... -->\n\tclass Comment < Child\n\t\tinclude Comparable\n\t\tSTART = \"<!--\"\n\t\tSTOP = \"-->\"\n\n\t\t# The content text\n\n\t\tattr_accessor :string\n\n\t\t##\n\t\t# Constructor.  The first argument can be one of three types:\n\t\t# @param first If String, the contents of this comment are set to the \n\t\t# argument.  If Comment, the argument is duplicated.  If\n\t\t# Source, the argument is scanned for a comment.\n\t\t# @param second If the first argument is a Source, this argument \n\t\t# should be nil, not supplied, or a Parent to be set as the parent \n\t\t# of this object\n\t\tdef initialize( first, second = nil )\n\t\t\t#puts \"IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}\"\n\t\t\tsuper(second)\n\t\t\tif first.kind_of? String\n\t\t\t\t@string = first\n\t\t\telsif first.kind_of? Comment\n\t\t\t\t@string = first.string\n\t\t\tend\n\t\tend\n\n\t\tdef clone\n\t\t\tComment.new self\n\t\tend\n\n    # == DEPRECATED\n    # See REXML::Formatters\n    #\n\t\t# output::\n\t\t#\t Where to write the string\n\t\t# indent::\n\t\t#\t An integer.\tIf -1, no indenting will be used; otherwise, the\n\t\t#\t indentation will be this number of spaces, and children will be\n\t\t#\t indented an additional amount.\n\t\t# transitive::\n\t\t#\t Ignored by this class.\tThe contents of comments are never modified.\n\t\t# ie_hack::\n\t\t#\t Needed for conformity to the child API, but not used by this class.\n\t\tdef write( output, indent=-1, transitive=false, ie_hack=false )\n      Kernel.warn(\"Comment.write is deprecated.  See REXML::Formatters\")\n\t\t\tindent( output, indent )\n\t\t\toutput << START\n\t\t\toutput << @string\n\t\t\toutput << STOP\n\t\tend\n\n\t\talias :to_s :string\n\n\t\t##\n\t\t# Compares this Comment to another; the contents of the comment are used\n\t\t# in the comparison.\n\t\tdef <=>(other)\n\t\t\tother.to_s <=> @string\n\t\tend\n\n\t\t##\n\t\t# Compares this Comment to another; the contents of the comment are used\n\t\t# in the comparison.\n\t\tdef ==( other )\n\t\t\tother.kind_of? Comment and\n\t\t\t(other <=> self) == 0\n\t\tend\n\n    def node_type\n      :comment\n    end\n\tend\nend\n#vim:ts=2 sw=2 noexpandtab:\n"
  },
  {
    "path": "lib/rexml/doctype.rb",
    "content": "require \"rexml/parent\"\nrequire \"rexml/parseexception\"\nrequire \"rexml/namespace\"\nrequire 'rexml/entity'\nrequire 'rexml/attlistdecl'\nrequire 'rexml/xmltokens'\n\nmodule REXML\n  # Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE\n  # ... >.  DOCTYPES can be used to declare the DTD of a document, as well as\n  # being used to declare entities used in the document.\n  class DocType < Parent\n    include XMLTokens\n    START = \"<!DOCTYPE\"\n    STOP = \">\"\n    SYSTEM = \"SYSTEM\"\n    PUBLIC = \"PUBLIC\"\n    DEFAULT_ENTITIES = { \n      'gt'=>EntityConst::GT, \n      'lt'=>EntityConst::LT, \n      'quot'=>EntityConst::QUOT, \n      \"apos\"=>EntityConst::APOS \n    }\n\n    # name is the name of the doctype\n    # external_id is the referenced DTD, if given\n    attr_reader :name, :external_id, :entities, :namespaces\n\n    # Constructor\n    #\n    #   dt = DocType.new( 'foo', '-//I/Hate/External/IDs' )\n    #   # <!DOCTYPE foo '-//I/Hate/External/IDs'>\n    #   dt = DocType.new( doctype_to_clone )\n    #   # Incomplete.  Shallow clone of doctype\n    #\n    # +Note+ that the constructor: \n    #\n    #  Doctype.new( Source.new( \"<!DOCTYPE foo 'bar'>\" ) )\n    #\n    # is _deprecated_.  Do not use it.  It will probably disappear.\n    def initialize( first, parent=nil )\n      @entities = DEFAULT_ENTITIES\n      @long_name = @uri = nil\n      if first.kind_of? String\n        super()\n        @name = first\n        @external_id = parent\n      elsif first.kind_of? DocType\n        super( parent )\n        @name = first.name\n        @external_id = first.external_id\n      elsif first.kind_of? Array\n        super( parent )\n        @name = first[0]\n        @external_id = first[1]\n        @long_name = first[2]\n        @uri = first[3]\n      elsif first.kind_of? Source\n        super( parent )\n        parser = Parsers::BaseParser.new( first )\n        event = parser.pull\n        if event[0] == :start_doctype\n          @name, @external_id, @long_name, @uri, = event[1..-1]\n        end\n      else\n        super()\n      end\n    end\n\n    def node_type\n      :doctype\n    end\n\n    def attributes_of element\n      rv = []\n      each do |child|\n        child.each do |key,val|\n          rv << Attribute.new(key,val)\n        end if child.kind_of? AttlistDecl and child.element_name == element\n      end\n      rv\n    end\n\n    def attribute_of element, attribute\n      att_decl = find do |child|\n        child.kind_of? AttlistDecl and\n        child.element_name == element and\n        child.include? attribute\n      end\n      return nil unless att_decl\n      att_decl[attribute]\n    end\n\n    def clone\n      DocType.new self\n    end\n\n    # output::\n    #   Where to write the string\n    # indent::\n    #   An integer.  If -1, no indentation will be used; otherwise, the\n    #   indentation will be this number of spaces, and children will be\n    #   indented an additional amount.\n    # transitive::\n    #   Ignored\n    # ie_hack::\n    #   Ignored\n    def write( output, indent=0, transitive=false, ie_hack=false )\n      f = REXML::Formatters::Default.new\n      indent( output, indent )\n      output << START\n      output << ' '\n      output << @name\n      output << \" #@external_id\" if @external_id\n      output << \" #{@long_name.inspect}\" if @long_name\n      output << \" #{@uri.inspect}\" if @uri\n      unless @children.empty?\n        next_indent = indent + 1\n        output << ' ['\n        child = nil    # speed\n        @children.each { |child|\n          output << \"\\n\"\n          f.write( child, output )\n        }\n        output << \"\\n]\"\n      end\n      output << STOP\n    end\n\n    def context\n      @parent.context\n    end\n\n    def entity( name )\n      @entities[name].unnormalized if @entities[name]\n    end\n\n    def add child\n      super(child)\n      @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES\n      @entities[ child.name ] = child if child.kind_of? Entity\n    end\n    \n    # This method retrieves the public identifier identifying the document's \n    # DTD.\n    #\n    # Method contributed by Henrik Martensson\n    def public\n      case @external_id\n      when \"SYSTEM\"\n        nil\n      when \"PUBLIC\"\n        strip_quotes(@long_name)\n      end\n    end\n    \n    # This method retrieves the system identifier identifying the document's DTD\n    #\n    # Method contributed by Henrik Martensson\n    def system\n      case @external_id\n      when \"SYSTEM\"\n        strip_quotes(@long_name)\n      when \"PUBLIC\"\n        @uri.kind_of?(String) ? strip_quotes(@uri) : nil\n      end\n    end\n    \n    # This method returns a list of notations that have been declared in the\n    # _internal_ DTD subset. Notations in the external DTD subset are not \n    # listed.\n    #\n    # Method contributed by Henrik Martensson\n    def notations\n      children().select {|node| node.kind_of?(REXML::NotationDecl)}\n    end\n    \n    # Retrieves a named notation. Only notations declared in the internal\n    # DTD subset can be retrieved.\n    #\n    # Method contributed by Henrik Martensson\n    def notation(name)\n      notations.find { |notation_decl|\n        notation_decl.name == name\n      }\n    end\n    \n    private\n    \n    # Method contributed by Henrik Martensson\n    def strip_quotes(quoted_string)\n      quoted_string =~ /^[\\'\\\"].*[\\´\\\"]$/ ?\n        quoted_string[1, quoted_string.length-2] :\n        quoted_string\n    end\n  end\n\n  # We don't really handle any of these since we're not a validating\n  # parser, so we can be pretty dumb about them.  All we need to be able\n  # to do is spew them back out on a write()\n\n  # This is an abstract class.  You never use this directly; it serves as a\n  # parent class for the specific declarations.\n  class Declaration < Child\n    def initialize src\n      super()\n      @string = src\n    end\n\n    def to_s\n      @string+'>'\n    end\n\n    # == DEPRECATED\n    # See REXML::Formatters\n    #\n    def write( output, indent )\n      output << to_s\n    end\n  end\n  \n  public\n  class ElementDecl < Declaration\n    def initialize( src )\n      super\n    end\n  end\n\n  class ExternalEntity < Child\n    def initialize( src )\n      super()\n      @entity = src\n    end\n    def to_s\n      @entity\n    end\n    def write( output, indent )\n      output << @entity\n    end\n  end\n\n  class NotationDecl < Child\n    attr_accessor :public, :system\n    def initialize name, middle, pub, sys\n      super(nil)\n      @name = name\n      @middle = middle\n      @public = pub\n      @system = sys\n    end\n\n    def to_s\n      \"<!NOTATION #@name #@middle#{\n        @public ? ' ' + public.inspect : '' \n      }#{\n        @system ? ' ' +@system.inspect : ''\n      }>\"\n    end\n\n    def write( output, indent=-1 )\n      output << to_s\n    end\n    \n    # This method retrieves the name of the notation.\n    #\n    # Method contributed by Henrik Martensson\n    def name\n      @name\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/document.rb",
    "content": "require \"rexml/element\"\nrequire \"rexml/xmldecl\"\nrequire \"rexml/source\"\nrequire \"rexml/comment\"\nrequire \"rexml/doctype\"\nrequire \"rexml/instruction\"\nrequire \"rexml/rexml\"\nrequire \"rexml/parseexception\"\nrequire \"rexml/output\"\nrequire \"rexml/parsers/baseparser\"\nrequire \"rexml/parsers/streamparser\"\nrequire \"rexml/parsers/treeparser\"\n\nmodule REXML\n  # Represents a full XML document, including PIs, a doctype, etc.  A\n  # Document has a single child that can be accessed by root().\n  # Note that if you want to have an XML declaration written for a document\n  # you create, you must add one; REXML documents do not write a default\n\t# declaration for you.  See |DECLARATION| and |write|.\n\tclass Document < Element\n\t\t# A convenient default XML declaration.  If you want an XML declaration,\n\t\t# the easiest way to add one is mydoc << Document::DECLARATION\n    # +DEPRECATED+\n    # Use: mydoc << XMLDecl.default\n\t\tDECLARATION = XMLDecl.default\n\n\t\t# Constructor\n\t\t# @param source if supplied, must be a Document, String, or IO. \n\t\t# Documents have their context and Element attributes cloned.\n\t  # Strings are expected to be valid XML documents.  IOs are expected\n\t  # to be sources of valid XML documents.\n\t  # @param context if supplied, contains the context of the document;\n\t  # this should be a Hash.\n\t\tdef initialize( source = nil, context = {} )\n      @entity_expansion_count = 0\n\t\t\tsuper()\n\t\t\t@context = context\n\t\t\treturn if source.nil?\n\t\t\tif source.kind_of? Document\n\t\t\t\t@context = source.context\n\t\t\t\tsuper source\n\t\t\telse\n\t\t\t\tbuild(  source )\n\t\t\tend\n\t\tend\n\n    def node_type\n      :document\n    end\n\n\t\t# Should be obvious\n\t\tdef clone\n\t\t\tDocument.new self\n\t\tend\n\n\t\t# According to the XML spec, a root node has no expanded name\n\t\tdef expanded_name\n\t\t\t''\n\t\t\t#d = doc_type\n\t\t\t#d ? d.name : \"UNDEFINED\"\n\t\tend\n\n\t\talias :name :expanded_name\n\n\t\t# We override this, because XMLDecls and DocTypes must go at the start\n\t\t# of the document\n\t\tdef add( child )\n\t\t\tif child.kind_of? XMLDecl\n\t\t\t\t@children.unshift child\n        child.parent = self\n\t\t\telsif child.kind_of? DocType\n        # Find first Element or DocType node and insert the decl right \n        # before it.  If there is no such node, just insert the child at the\n        # end.  If there is a child and it is an DocType, then replace it.\n        insert_before_index = 0\n        @children.find { |x| \n          insert_before_index += 1\n          x.kind_of?(Element) || x.kind_of?(DocType)\n        }\n        if @children[ insert_before_index ] # Not null = not end of list\n          if @children[ insert_before_index ].kind_of DocType\n            @children[ insert_before_index ] = child\n          else\n            @children[ index_before_index-1, 0 ] = child\n          end\n        else  # Insert at end of list\n          @children[insert_before_index] = child\n        end\n\t\t\t\tchild.parent = self\n\t\t\telse\n\t\t\t\trv = super\n\t\t\t\traise \"attempted adding second root element to document\" if @elements.size > 1\n\t\t\t\trv\n\t\t\tend\n\t\tend\n\t\talias :<< :add\n\n\t\tdef add_element(arg=nil, arg2=nil)\n\t\t\trv = super\n\t\t\traise \"attempted adding second root element to document\" if @elements.size > 1\n\t\t\trv\n\t\tend\n\n\t\t# @return the root Element of the document, or nil if this document\n\t\t# has no children.\n\t\tdef root\n      elements[1]\n      #self\n      #@children.find { |item| item.kind_of? Element }\n\t\tend\n\n\t\t# @return the DocType child of the document, if one exists,\n\t\t# and nil otherwise.\n\t\tdef doctype\n\t\t\t@children.find { |item| item.kind_of? DocType }\n\t\tend\n\n\t\t# @return the XMLDecl of this document; if no XMLDecl has been\n\t\t# set, the default declaration is returned.\n\t\tdef xml_decl\n\t\t\trv = @children[0]\n      return rv if rv.kind_of? XMLDecl\n      rv = @children.unshift(XMLDecl.default)[0]\n\t\tend\n\n\t\t# @return the XMLDecl version of this document as a String.\n\t\t# If no XMLDecl has been set, returns the default version.\n\t\tdef version\n\t\t\txml_decl().version\n\t\tend\n\n\t\t# @return the XMLDecl encoding of this document as a String.\n\t\t# If no XMLDecl has been set, returns the default encoding.\n\t\tdef encoding\n\t\t\txml_decl().encoding\n\t\tend\n\n\t\t# @return the XMLDecl standalone value of this document as a String.\n\t\t# If no XMLDecl has been set, returns the default setting.\n\t\tdef stand_alone?\n\t\t\txml_decl().stand_alone?\n\t\tend\n\n    # Write the XML tree out, optionally with indent.  This writes out the\n    # entire XML document, including XML declarations, doctype declarations,\n    # and processing instructions (if any are given).\n    #\n    # A controversial point is whether Document should always write the XML\n    # declaration (<?xml version='1.0'?>) whether or not one is given by the\n    # user (or source document).  REXML does not write one if one was not\n    # specified, because it adds unnecessary bandwidth to applications such\n    # as XML-RPC.\n    #\n    # See also the classes in the rexml/formatters package for the proper way\n    # to change the default formatting of XML output\n    #\n    # _Examples_\n    #   Document.new(\"<a><b/></a>\").serialize\n    #\n    #   output_string = \"\"\n    #   tr = Transitive.new( output_string )\n    #   Document.new(\"<a><b/></a>\").serialize( tr )\n    #\n    # output::\n    #\t  output an object which supports '<< string'; this is where the\n    #   document will be written.\n    # indent::\n    #   An integer.  If -1, no indenting will be used; otherwise, the\n    #   indentation will be twice this number of spaces, and children will be\n    #   indented an additional amount.  For a value of 3, every item will be \n    #   indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1\n    # trans::\n    #   If transitive is true and indent is >= 0, then the output will be\n    #   pretty-printed in such a way that the added whitespace does not affect\n    #   the absolute *value* of the document -- that is, it leaves the value\n    #   and number of Text nodes in the document unchanged.\n    # ie_hack::\n    #   Internet Explorer is the worst piece of crap to have ever been\n    #   written, with the possible exception of Windows itself.  Since IE is\n    #   unable to parse proper XML, we have to provide a hack to generate XML\n    #   that IE's limited abilities can handle.  This hack inserts a space \n    #   before the /> on empty tags.  Defaults to false\n\t\tdef write( output=$stdout, indent=-1, trans=false, ie_hack=false )\n      if xml_decl.encoding != \"UTF-8\" && !output.kind_of?(Output)\n        output = Output.new( output, xml_decl.encoding )\n      end\n      formatter = if indent > -1\n          if trans\n            REXML::Formatters::Transitive.new( indent, ie_hack )\n          else\n            REXML::Formatters::Pretty.new( indent, ie_hack )\n          end\n        else\n          REXML::Formatters::Default.new( ie_hack )\n        end\n      formatter.write( self, output )\n\t\tend\n\n\t\t\n\t\tdef Document::parse_stream( source, listener )\n\t\t\tParsers::StreamParser.new( source, listener ).parse\n\t\tend\n\n    @@entity_expansion_limit = 10_000\n\n    # Set the entity expansion limit. By default the limit is set to 10000.\n    def Document::entity_expansion_limit=( val )\n      @@entity_expansion_limit = val\n    end\n\n    # Get the entity expansion limit. By default the limit is set to 10000.\n    def Document::entity_expansion_limit\n      return @@entity_expansion_limit\n    end\n\n    attr_reader :entity_expansion_count\n    \n    def record_entity_expansion\n      @entity_expansion_count += 1\n      if @entity_expansion_count > @@entity_expansion_limit\n        raise \"number of entity expansions exceeded, processing aborted.\"\n      end\n    end\n\n\t\tprivate\n\t\tdef build( source )\n      Parsers::TreeParser.new( source, self ).parse\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/dtd/attlistdecl.rb",
    "content": "require \"rexml/child\"\nmodule REXML\n\tmodule DTD\n\t\tclass AttlistDecl < Child\n\t\t\tSTART = \"<!ATTLIST\"\n\t\t\tSTART_RE = /^\\s*#{START}/um\n\t\t\tPATTERN_RE = /\\s*(#{START}.*?>)/um\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/dtd/dtd.rb",
    "content": "require \"rexml/dtd/elementdecl\"\nrequire \"rexml/dtd/entitydecl\"\nrequire \"rexml/comment\"\nrequire \"rexml/dtd/notationdecl\"\nrequire \"rexml/dtd/attlistdecl\"\nrequire \"rexml/parent\"\n\nmodule REXML\n\tmodule DTD\n\t\tclass Parser\n\t\t\tdef Parser.parse( input )\n\t\t\t\tcase input\n\t\t\t\twhen String\n\t\t\t\t\tparse_helper input\n\t\t\t\twhen File\n\t\t\t\t\tparse_helper input.read\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# Takes a String and parses it out\n\t\t\tdef Parser.parse_helper( input )\n\t\t\t\tcontents = Parent.new\n\t\t\t\twhile input.size > 0\n\t\t\t\t\tcase input\n\t\t\t\t\twhen ElementDecl.PATTERN_RE\n\t\t\t\t\t\tmatch = $&\n\t\t\t\t\t\tsource = $'\n\t\t\t\t\t\tcontents << ElementDecl.new( match )\n\t\t\t\t\twhen AttlistDecl.PATTERN_RE\n\t\t\t\t\t\tmatchdata = $~\n\t\t\t\t\t\tsource = $'\n\t\t\t\t\t\tcontents << AttlistDecl.new( matchdata )\n\t\t\t\t\twhen EntityDecl.PATTERN_RE\n\t\t\t\t\t\tmatchdata = $~\n\t\t\t\t\t\tsource = $'\n\t\t\t\t\t\tcontents << EntityDecl.new( matchdata )\n\t\t\t\t\twhen Comment.PATTERN_RE\n\t\t\t\t\t\tmatchdata = $~\n\t\t\t\t\t\tsource = $'\n\t\t\t\t\t\tcontents << Comment.new( matchdata )\n\t\t\t\t\twhen NotationDecl.PATTERN_RE\n\t\t\t\t\t\tmatchdata = $~\n\t\t\t\t\t\tsource = $'\n\t\t\t\t\t\tcontents << NotationDecl.new( matchdata )\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tcontents\n\t\t\tend\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/dtd/elementdecl.rb",
    "content": "require \"rexml/child\"\nmodule REXML\n\tmodule DTD\n\t\tclass ElementDecl < Child\n\t\t\tSTART = \"<!ELEMENT\"\n\t\t\tSTART_RE = /^\\s*#{START}/um\n\t\t\tPATTERN_RE = /^\\s*(#{START}.*?)>/um\n\t\t\tPATTERN_RE = /^\\s*#{START}\\s+((?:[:\\w_][-\\.\\w_]*:)?[-!\\*\\.\\w_]*)(.*?)>/\n\t\t\t#\\s*(((([\"']).*?\\5)|[^\\/'\">]*)*?)(\\/)?>/um, true)\n\n\t\t\tdef initialize match\n\t\t\t\t@name = match[1]\n\t\t\t\t@rest = match[2]\n\t\t\tend\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/dtd/entitydecl.rb",
    "content": "require \"rexml/child\"\nmodule REXML\n\tmodule DTD\n\t\tclass EntityDecl < Child\n\t\t\tSTART = \"<!ENTITY\"\n\t\t\tSTART_RE = /^\\s*#{START}/um\n\t\t\tPUBLIC = /^\\s*#{START}\\s+(?:%\\s+)?(\\w+)\\s+PUBLIC\\s+(([\"']).*?\\3)\\s+(([\"']).*?\\5)\\s*>/um\n\t\t\tSYSTEM = /^\\s*#{START}\\s+(?:%\\s+)?(\\w+)\\s+SYSTEM\\s+(([\"']).*?\\3)(?:\\s+NDATA\\s+\\w+)?\\s*>/um\n\t\t\tPLAIN = /^\\s*#{START}\\s+(\\w+)\\s+(([\"']).*?\\3)\\s*>/um\n\t\t\tPERCENT = /^\\s*#{START}\\s+%\\s+(\\w+)\\s+(([\"']).*?\\3)\\s*>/um\n\t\t\t# <!ENTITY name SYSTEM \"...\">\n\t\t\t# <!ENTITY name \"...\">\n\t\t\tdef initialize src\n\t\t\t\tsuper()\n\t\t\t\tmd = nil\n\t\t\t\tif src.match( PUBLIC )\n\t\t\t\t\tmd = src.match( PUBLIC, true )\n\t\t\t\t\t@middle = \"PUBLIC\"\n\t\t\t\t\t@content = \"#{md[2]} #{md[4]}\"\n\t\t\t\telsif src.match( SYSTEM )\n\t\t\t\t\tmd = src.match( SYSTEM, true )\n\t\t\t\t\t@middle = \"SYSTEM\"\n\t\t\t\t\t@content = md[2]\n\t\t\t\telsif src.match( PLAIN )\n\t\t\t\t\tmd = src.match( PLAIN, true )\n\t\t\t\t\t@middle = \"\"\n\t\t\t\t\t@content = md[2]\n\t\t\t\telsif src.match( PERCENT )\n\t\t\t\t\tmd = src.match( PERCENT, true )\n\t\t\t\t\t@middle = \"\"\n\t\t\t\t\t@content = md[2]\n\t\t\t\tend\n\t\t\t\traise ParseException.new(\"failed Entity match\", src) if md.nil?\n\t\t\t\t@name = md[1]\n\t\t\tend\n\n\t\t\tdef to_s\n\t\t\t\trv = \"<!ENTITY #@name \"\n\t\t\t\trv << \"#@middle \" if @middle.size > 0\n\t\t\t\trv << @content\n\t\t\t\trv\n\t\t\tend\n\n\t\t\tdef write( output, indent )\n        indent( output, indent )\n\t\t\t\toutput << to_s\n\t\t\tend\n\n\t\t\tdef EntityDecl.parse_source source, listener\n\t\t\t\tmd = source.match( PATTERN_RE, true )\n\t\t\t\tthing = md[0].squeeze(\" \\t\\n\\r\")\n\t\t\t\tlistener.send inspect.downcase, thing \n\t\t\tend\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/dtd/notationdecl.rb",
    "content": "require \"rexml/child\"\nmodule REXML\n\tmodule DTD\n\t\tclass NotationDecl < Child\n\t\t\tSTART = \"<!NOTATION\"\n\t\t\tSTART_RE = /^\\s*#{START}/um\n\t\t\tPUBLIC = /^\\s*#{START}\\s+(\\w[\\w-]*)\\s+(PUBLIC)\\s+(([\"']).*?\\4)\\s*>/um\n\t\t\tSYSTEM = /^\\s*#{START}\\s+(\\w[\\w-]*)\\s+(SYSTEM)\\s+(([\"']).*?\\4)\\s*>/um\n\t\t\tdef initialize src\n\t\t\t\tsuper()\n\t\t\t\tif src.match( PUBLIC )\n\t\t\t\t\tmd = src.match( PUBLIC, true )\n\t\t\t\telsif src.match( SYSTEM )\n\t\t\t\t\tmd = src.match( SYSTEM, true )\n\t\t\t\telse\n\t\t\t\t\traise ParseException.new( \"error parsing notation: no matching pattern\", src )\n\t\t\t\tend\n\t\t\t\t@name = md[1]\n\t\t\t\t@middle = md[2]\n\t\t\t\t@rest = md[3]\n\t\t\tend\n\n\t\t\tdef to_s\n\t\t\t\t\"<!NOTATION #@name #@middle #@rest>\"\n\t\t\tend\n\n\t\t\tdef write( output, indent )\n        indent( output, indent )\n\t\t\t\toutput << to_s\n\t\t\tend\n\n\t\t\tdef NotationDecl.parse_source source, listener\n\t\t\t\tmd = source.match( PATTERN_RE, true )\n\t\t\t\tthing = md[0].squeeze(\" \\t\\n\\r\")\n\t\t\t\tlistener.send inspect.downcase, thing \n\t\t\tend\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/element.rb",
    "content": "require \"rexml/parent\"\nrequire \"rexml/namespace\"\nrequire \"rexml/attribute\"\nrequire \"rexml/cdata\"\nrequire \"rexml/xpath\"\nrequire \"rexml/parseexception\"\n\nmodule REXML\n  # An implementation note about namespaces:\n  # As we parse, when we find namespaces we put them in a hash and assign\n  # them a unique ID.  We then convert the namespace prefix for the node\n  # to the unique ID.  This makes namespace lookup much faster for the\n  # cost of extra memory use.  We save the namespace prefix for the\n  # context node and convert it back when we write it.\n  @@namespaces = {}\n\n  # Represents a tagged XML element.  Elements are characterized by\n  # having children, attributes, and names, and can themselves be\n  # children.\n  class Element < Parent\n    include Namespace\n\n    UNDEFINED = \"UNDEFINED\";\t\t# The default name\n\n    # Mechanisms for accessing attributes and child elements of this\n    # element.\n    attr_reader :attributes, :elements\n    # The context holds information about the processing environment, such as\n    # whitespace handling.\n    attr_accessor :context\n\n    # Constructor\n    # arg:: \n    # \tif not supplied, will be set to the default value.\n    # \tIf a String, the name of this object will be set to the argument.\n    # \tIf an Element, the object will be shallowly cloned; name, \n    # \tattributes, and namespaces will be copied.  Children will +not+ be\n    # \tcopied.\n    # parent:: \n    # \tif supplied, must be a Parent, and will be used as\n    # \tthe parent of this object.\n    # context::\n    # \tIf supplied, must be a hash containing context items.  Context items\n    # \tinclude:\n    # * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of\n    #   strings being the names of the elements to respect\n    #   whitespace for.  Defaults to :+all+.\n    # * <tt>:compress_whitespace</tt> the value can be :+all+ or an array of\n    #   strings being the names of the elements to ignore whitespace on.\n    #   Overrides :+respect_whitespace+.\n    # * <tt>:ignore_whitespace_nodes</tt> the value can be :+all+ or an array\n    #   of strings being the names of the elements in which to ignore\n    #   whitespace-only nodes.  If this is set, Text nodes which contain only\n    #   whitespace will not be added to the document tree.\n    # * <tt>:raw</tt> can be :+all+, or an array of strings being the names of\n    #   the elements to process in raw mode.  In raw mode, special\n    #   characters in text is not converted to or from entities.\n    def initialize( arg = UNDEFINED, parent=nil, context=nil )\n      super(parent)\n\n      @elements = Elements.new(self)\n      @attributes = Attributes.new(self)\n      @context = context\n\n      if arg.kind_of? String\n        self.name = arg\n      elsif arg.kind_of? Element\n        self.name = arg.expanded_name\n        arg.attributes.each_attribute{ |attribute|\n          @attributes << Attribute.new( attribute )\n        }\n        @context = arg.context\n      end\n    end\n\n    def inspect\n      rv = \"<#@expanded_name\"\n\n      @attributes.each_attribute do |attr|\n        rv << \" \"\n        attr.write( rv, 0 )\n      end\n\n      if children.size > 0\n        rv << \"> ... </>\"\n      else\n        rv << \"/>\"\n      end\n    end\n\n\n    # Creates a shallow copy of self.\n    #   d = Document.new \"<a><b/><b/><c><d/></c></a>\"\n    #   new_a = d.root.clone\n    #   puts new_a  # => \"<a/>\"\n    def clone\n      self.class.new self\n    end\n\n    # Evaluates to the root node of the document that this element \n    # belongs to. If this element doesn't belong to a document, but does\n    # belong to another Element, the parent's root will be returned, until the\n    # earliest ancestor is found.\n    #\n    # Note that this is not the same as the document element.\n    # In the following example, <a> is the document element, and the root\n    # node is the parent node of the document element.  You may ask yourself\n    # why the root node is useful: consider the doctype and XML declaration,\n    # and any processing instructions before the document element... they\n    # are children of the root node, or siblings of the document element.\n    # The only time this isn't true is when an Element is created that is\n    # not part of any Document.  In this case, the ancestor that has no\n    # parent acts as the root node.\n    #  d = Document.new '<a><b><c/></b></a>'\n    #  a = d[1] ; c = a[1][1]\n    #  d.root_node == d   # TRUE\n    #  a.root_node        # namely, d\n    #  c.root_node        # again, d\n    def root_node\n      parent.nil? ? self : parent.root_node\n    end\n\n    def root\n      return elements[1] if self.kind_of? Document\n      return self if parent.kind_of? Document or parent.nil?\n      return parent.root\n    end\n\n    # Evaluates to the document to which this element belongs, or nil if this\n    # element doesn't belong to a document.\n    def document\n      rt = root\n      rt.parent if rt\n    end\n\n    # Evaluates to +true+ if whitespace is respected for this element.  This\n    # is the case if:\n    # 1. Neither :+respect_whitespace+ nor :+compress_whitespace+ has any value\n    # 2. The context has :+respect_whitespace+ set to :+all+ or\n    #    an array containing the name of this element, and \n    #    :+compress_whitespace+ isn't set to :+all+ or an array containing the \n    #    name of this element.\n    # The evaluation is tested against +expanded_name+, and so is namespace\n    # sensitive.\n    def whitespace\n      @whitespace = nil\n      if @context\n        if @context[:respect_whitespace]\n          @whitespace = (@context[:respect_whitespace] == :all or\n                         @context[:respect_whitespace].include? expanded_name)\n        end\n        @whitespace = false if (@context[:compress_whitespace] and\n                                (@context[:compress_whitespace] == :all or\n                                 @context[:compress_whitespace].include? expanded_name)\n                               )\n      end\n      @whitespace = true unless @whitespace == false\n      @whitespace\n    end\n\n    def ignore_whitespace_nodes\n      @ignore_whitespace_nodes = false\n      if @context\n        if @context[:ignore_whitespace_nodes]\n          @ignore_whitespace_nodes = \n            (@context[:ignore_whitespace_nodes] == :all or\n             @context[:ignore_whitespace_nodes].include? expanded_name)\n        end\n      end\n    end\n\n    # Evaluates to +true+ if raw mode is set for this element.  This\n    # is the case if the context has :+raw+ set to :+all+ or\n    # an array containing the name of this element.\n    #\n    # The evaluation is tested against +expanded_name+, and so is namespace\n    # sensitive.\n    def raw\n      @raw = (@context and @context[:raw] and\n              (@context[:raw] == :all or\n               @context[:raw].include? expanded_name))\n               @raw\n    end\n\n    #once :whitespace, :raw, :ignore_whitespace_nodes\n\n    #################################################\n    # Namespaces                                    #\n    #################################################\n\n    # Evaluates to an +Array+ containing the prefixes (names) of all defined\n    # namespaces at this context node.\n    #  doc = Document.new(\"<a xmlns:x='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>\")\n    #  doc.elements['//b'].prefixes # -> ['x', 'y']\n    def prefixes\n      prefixes = []\n      prefixes = parent.prefixes if parent\n      prefixes |= attributes.prefixes\n      return prefixes\n    end\n\n    def namespaces\n      namespaces = {}\n      namespaces = parent.namespaces if parent\n      namespaces = namespaces.merge( attributes.namespaces )\n      return namespaces\n    end\n\n    # Evalutas to the URI for a prefix, or the empty string if no such \n    # namespace is declared for this element. Evaluates recursively for\n    # ancestors.  Returns the default namespace, if there is one.\n    # prefix:: \n    #   the prefix to search for.  If not supplied, returns the default\n    #   namespace if one exists\n    # Returns:: \n    #   the namespace URI as a String, or nil if no such namespace\n    #   exists.  If the namespace is undefined, returns an empty string\n    #  doc = Document.new(\"<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>\")\n    #  b = doc.elements['//b']\n    #  b.namespace           # -> '1'\n    #  b.namespace(\"y\")      # -> '2'\n    def namespace(prefix=nil)\n      if prefix.nil?\n        prefix = prefix()\n      end\n      if prefix == ''\n        prefix = \"xmlns\"\n      else\n        prefix = \"xmlns:#{prefix}\" unless prefix[0,5] == 'xmlns'\n      end\n      ns = attributes[ prefix ]\n      ns = parent.namespace(prefix) if ns.nil? and parent\n      ns = '' if ns.nil? and prefix == 'xmlns'\n      return ns\n    end\n\n    # Adds a namespace to this element.\n    # prefix:: \n    #   the prefix string, or the namespace URI if +uri+ is not\n    #   supplied\n    # uri::    \n    #   the namespace URI.  May be nil, in which +prefix+ is used as\n    #   the URI\n    # Evaluates to: this Element\n    #  a = Element.new(\"a\")\n    #  a.add_namespace(\"xmlns:foo\", \"bar\" )\n    #  a.add_namespace(\"foo\", \"bar\")  # shorthand for previous line\n    #  a.add_namespace(\"twiddle\")\n    #  puts a   #-> <a xmlns:foo='bar' xmlns='twiddle'/>\n    def add_namespace( prefix, uri=nil )\n      unless uri\n        @attributes[\"xmlns\"] = prefix\n      else\n        prefix = \"xmlns:#{prefix}\" unless prefix =~ /^xmlns:/\n        @attributes[ prefix ] = uri\n      end\n      self\n    end\n\n    # Removes a namespace from this node.  This only works if the namespace is\n    # actually declared in this node.  If no argument is passed, deletes the\n    # default namespace.\n    #\n    # Evaluates to: this element\n    #  doc = Document.new \"<a xmlns:foo='bar' xmlns='twiddle'/>\"\n    #  doc.root.delete_namespace\n    #  puts doc     # -> <a xmlns:foo='bar'/>\n    #  doc.root.delete_namespace 'foo'\n    #  puts doc     # -> <a/>\n    def delete_namespace namespace=\"xmlns\"\n      namespace = \"xmlns:#{namespace}\" unless namespace == 'xmlns'\n      attribute = attributes.get_attribute(namespace)\n      attribute.remove unless attribute.nil?\n      self\n    end\n\n    #################################################\n    # Elements                                      #\n    #################################################\n\n    # Adds a child to this element, optionally setting attributes in\n    # the element.\n    # element:: \n    #   optional.  If Element, the element is added.\n    #   Otherwise, a new Element is constructed with the argument (see\n    #   Element.initialize).\n    # attrs:: \n    #   If supplied, must be a Hash containing String name,value \n    #   pairs, which will be used to set the attributes of the new Element.\n    # Returns:: the Element that was added\n    #  el = doc.add_element 'my-tag'\n    #  el = doc.add_element 'my-tag', {'attr1'=>'val1', 'attr2'=>'val2'}\n    #  el = Element.new 'my-tag'\n    #  doc.add_element el\n    def add_element element, attrs=nil\n      raise \"First argument must be either an element name, or an Element object\" if element.nil?\n      el = @elements.add(element)\n      attrs.each do |key, value|\n        el.attributes[key]=Attribute.new(key,value,self)\n      end\tif attrs.kind_of? Hash\n      el\n    end\n\n    # Deletes a child element.\n    # element:: \n    #   Must be an +Element+, +String+, or +Integer+.  If Element, \n    #   the element is removed.  If String, the element is found (via XPath) \n    #   and removed.  <em>This means that any parent can remove any\n    #   descendant.<em>  If Integer, the Element indexed by that number will be\n    #   removed.\n    # Returns:: the element that was removed.\n    #  doc.delete_element \"/a/b/c[@id='4']\"\n    #  doc.delete_element doc.elements[\"//k\"]\n    #  doc.delete_element 1\n    def delete_element element\n      @elements.delete element\n    end\n\n    # Evaluates to +true+ if this element has at least one child Element\n    #  doc = Document.new \"<a><b/><c>Text</c></a>\"\n    #  doc.root.has_elements               # -> true\n    #  doc.elements[\"/a/b\"].has_elements   # -> false\n    #  doc.elements[\"/a/c\"].has_elements   # -> false\n    def has_elements?\n      !@elements.empty?\n    end\n\n    # Iterates through the child elements, yielding for each Element that\n    # has a particular attribute set.\n    # key:: \n    #   the name of the attribute to search for\n    # value:: \n    #   the value of the attribute\n    # max:: \n    #   (optional) causes this method to return after yielding \n    #   for this number of matching children\n    # name:: \n    #   (optional) if supplied, this is an XPath that filters\n    #   the children to check.\n    #\n    #  doc = Document.new \"<a><b @id='1'/><c @id='2'/><d @id='1'/><e/></a>\"\n    #  # Yields b, c, d\n    #  doc.root.each_element_with_attribute( 'id' ) {|e| p e}\n    #  # Yields b, d\n    #  doc.root.each_element_with_attribute( 'id', '1' ) {|e| p e}\n    #  # Yields b\n    #  doc.root.each_element_with_attribute( 'id', '1', 1 ) {|e| p e}\n    #  # Yields d\n    #  doc.root.each_element_with_attribute( 'id', '1', 0, 'd' ) {|e| p e}\n    def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element\n      each_with_something( proc {|child| \n        if value.nil?\n          child.attributes[key] != nil\n        else\n          child.attributes[key]==value\n        end\n      }, max, name, &block )\n    end\n\n    # Iterates through the children, yielding for each Element that\n    # has a particular text set.\n    # text:: \n    #   the text to search for.  If nil, or not supplied, will iterate\n    #   over all +Element+ children that contain at least one +Text+ node.\n    # max:: \n    #   (optional) causes this method to return after yielding\n    #   for this number of matching children\n    # name:: \n    #   (optional) if supplied, this is an XPath that filters\n    #   the children to check.\n    #\n    #  doc = Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'\n    #  # Yields b, c, d\n    #  doc.each_element_with_text {|e|p e}\n    #  # Yields b, c\n    #  doc.each_element_with_text('b'){|e|p e}\n    #  # Yields b\n    #  doc.each_element_with_text('b', 1){|e|p e}\n    #  # Yields d\n    #  doc.each_element_with_text(nil, 0, 'd'){|e|p e}\n    def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element\n      each_with_something( proc {|child| \n        if text.nil?\n          child.has_text?\n        else\n          child.text == text\n        end\n      }, max, name, &block )\n    end\n\n    # Synonym for Element.elements.each\n    def each_element( xpath=nil, &block ) # :yields: Element\n      @elements.each( xpath, &block )\n    end\n\n    # Synonym for Element.to_a\n    # This is a little slower than calling elements.each directly.\n    # xpath:: any XPath by which to search for elements in the tree\n    # Returns:: an array of Elements that match the supplied path\n    def get_elements( xpath )\n      @elements.to_a( xpath )\n    end\n\n    # Returns the next sibling that is an element, or nil if there is\n    # no Element sibling after this one\n    #  doc = Document.new '<a><b/>text<c/></a>'\n    #  doc.root.elements['b'].next_element          #-> <c/>\n    #  doc.root.elements['c'].next_element          #-> nil\n    def next_element\n      element = next_sibling\n      element = element.next_sibling until element.nil? or element.kind_of? Element \n      return element\n    end\n\n    # Returns the previous sibling that is an element, or nil if there is\n    # no Element sibling prior to this one\n    #  doc = Document.new '<a><b/>text<c/></a>'\n    #  doc.root.elements['c'].previous_element          #-> <b/>\n    #  doc.root.elements['b'].previous_element          #-> nil\n    def previous_element\n      element = previous_sibling\n      element = element.previous_sibling until element.nil? or element.kind_of? Element\n      return element\n    end\n\n\n    #################################################\n    # Text                                          #\n    #################################################\n\n    # Evaluates to +true+ if this element has at least one Text child\n    def has_text?\n      not text().nil?\n    end\n\n    # A convenience method which returns the String value of the _first_\n    # child text element, if one exists, and +nil+ otherwise.\n    #\n    # <em>Note that an element may have multiple Text elements, perhaps\n    # separated by other children</em>.  Be aware that this method only returns\n    # the first Text node.\n    #\n    # This method returns the +value+ of the first text child node, which\n    # ignores the +raw+ setting, so always returns normalized text. See\n    # the Text::value documentation.\n    #\n    #  doc = Document.new \"<p>some text <b>this is bold!</b> more text</p>\"\n    #  # The element 'p' has two text elements, \"some text \" and \" more text\".\n    #  doc.root.text              #-> \"some text \"\n    def text( path = nil )\n      rv = get_text(path)\n      return rv.value unless rv.nil?\n      nil\n    end\n\n    # Returns the first child Text node, if any, or +nil+ otherwise.\n    # This method returns the actual +Text+ node, rather than the String content.\n    #  doc = Document.new \"<p>some text <b>this is bold!</b> more text</p>\"\n    #  # The element 'p' has two text elements, \"some text \" and \" more text\".\n    #  doc.root.get_text.value            #-> \"some text \"\n    def get_text path = nil\n      rv = nil\n      if path\n        element = @elements[ path ]\n        rv = element.get_text unless element.nil?\n      else\n        rv = @children.find { |node| node.kind_of? Text }\n      end\n      return rv\n    end\n\n    # Sets the first Text child of this object.  See text() for a\n    # discussion about Text children.\n    #\n    # If a Text child already exists, the child is replaced by this\n    # content.  This means that Text content can be deleted by calling\n    # this method with a nil argument.  In this case, the next Text\n    # child becomes the first Text child.  In no case is the order of\n    # any siblings disturbed.\n    # text:: \n    #   If a String, a new Text child is created and added to\n    #   this Element as the first Text child.  If Text, the text is set\n    #   as the first Child element.  If nil, then any existing first Text\n    #   child is removed.\n    # Returns:: this Element.\n    #  doc = Document.new '<a><b/></a>'\n    #  doc.root.text = 'Sean'      #-> '<a><b/>Sean</a>'\n    #  doc.root.text = 'Elliott'   #-> '<a><b/>Elliott</a>'\n    #  doc.root.add_element 'c'    #-> '<a><b/>Elliott<c/></a>'\n    #  doc.root.text = 'Russell'   #-> '<a><b/>Russell<c/></a>'\n    #  doc.root.text = nil         #-> '<a><b/><c/></a>'\n    def text=( text )\n      if text.kind_of? String\n        text = Text.new( text, whitespace(), nil, raw() )\n      elsif !text.nil? and !text.kind_of? Text\n        text = Text.new( text.to_s, whitespace(), nil, raw() )\n      end\n      old_text = get_text\n      if text.nil?\n        old_text.remove unless old_text.nil?\n      else\n        if old_text.nil?\n          self << text\n        else\n          old_text.replace_with( text )\n        end\n      end\n      return self\n    end\n\n    # A helper method to add a Text child.  Actual Text instances can\n    # be added with regular Parent methods, such as add() and <<()\n    # text::\n    #   if a String, a new Text instance is created and added\n    #   to the parent.  If Text, the object is added directly.\n    # Returns:: this Element\n    #  e = Element.new('a')          #-> <e/>\n    #  e.add_text 'foo'              #-> <e>foo</e>\n    #  e.add_text Text.new(' bar')    #-> <e>foo bar</e>\n    # Note that at the end of this example, the branch has <b>3</b> nodes; the 'e'\n    # element and <b>2</b> Text node children.\n    def add_text( text )\n      if text.kind_of? String \n        if @children[-1].kind_of? Text\n          @children[-1] << text\n          return\n        end\n        text = Text.new( text, whitespace(), nil, raw() )\n      end\n      self << text unless text.nil?\n      return self\n    end\n\n    def node_type\n      :element\n    end\n\n    def xpath\n      path_elements = []\n      cur = self\n      path_elements << __to_xpath_helper( self )\n      while cur.parent\n        cur = cur.parent\n        path_elements << __to_xpath_helper( cur )\n      end\n      return path_elements.reverse.join( \"/\" )\n    end\n\n    #################################################\n    # Attributes                                    #\n    #################################################\n\n    def attribute( name, namespace=nil )\n      prefix = nil\n      prefix = namespaces.index(namespace) if namespace\n      prefix = nil if prefix == 'xmlns'\n      attributes.get_attribute( \"#{prefix ? prefix + ':' : ''}#{name}\" )\n    end\n\n    # Evaluates to +true+ if this element has any attributes set, false\n    # otherwise.\n    def has_attributes?\n      return !@attributes.empty?\n    end\n\n    # Adds an attribute to this element, overwriting any existing attribute\n    # by the same name.\n    # key::\n    #   can be either an Attribute or a String.  If an Attribute,\n    #   the attribute is added to the list of Element attributes.  If String,\n    #   the argument is used as the name of the new attribute, and the value\n    #   parameter must be supplied.\n    # value:: \n    #   Required if +key+ is a String, and ignored if the first argument is\n    #   an Attribute.  This is a String, and is used as the value\n    #   of the new Attribute.  This should be the unnormalized value of the\n    #   attribute (without entities).\n    # Returns:: the Attribute added\n    #  e = Element.new 'e'\n    #  e.add_attribute( 'a', 'b' )               #-> <e a='b'/>\n    #  e.add_attribute( 'x:a', 'c' )             #-> <e a='b' x:a='c'/>\n    #  e.add_attribute Attribute.new('b', 'd')   #-> <e a='b' x:a='c' b='d'/>\n    def add_attribute( key, value=nil )\n      if key.kind_of? Attribute\n        @attributes << key\n      else\n        @attributes[key] = value\n      end\n    end\n\n    # Add multiple attributes to this element.\n    # hash:: is either a hash, or array of arrays\n    #  el.add_attributes( {\"name1\"=>\"value1\", \"name2\"=>\"value2\"} )\n    #  el.add_attributes( [ [\"name1\",\"value1\"], [\"name2\"=>\"value2\"] ] )\n    def add_attributes hash\n      if hash.kind_of? Hash\n        hash.each_pair {|key, value| @attributes[key] = value }\n      elsif hash.kind_of? Array\n        hash.each { |value| @attributes[ value[0] ] = value[1] }\n      end\n    end\n\n    # Removes an attribute\n    # key::\n    #   either an Attribute or a String.  In either case, the\n    #   attribute is found by matching the attribute name to the argument,\n    #   and then removed.  If no attribute is found, no action is taken.\n    # Returns:: \n    #   the attribute removed, or nil if this Element did not contain\n    #   a matching attribute\n    #  e = Element.new('E')\n    #  e.add_attribute( 'name', 'Sean' )             #-> <E name='Sean'/>\n    #  r = e.add_attribute( 'sur:name', 'Russell' )  #-> <E name='Sean' sur:name='Russell'/>\n    #  e.delete_attribute( 'name' )                  #-> <E sur:name='Russell'/>\n    #  e.delete_attribute( r )                       #-> <E/>\n    def delete_attribute(key)\n      attr = @attributes.get_attribute(key)\n      attr.remove unless attr.nil?\n    end\n\n    #################################################\n    # Other Utilities                               #\n    #################################################\n\n    # Get an array of all CData children.  \n    # IMMUTABLE\n    def cdatas\n      find_all { |child| child.kind_of? CData }.freeze\n    end\n\n    # Get an array of all Comment children.\n    # IMMUTABLE\n    def comments\n      find_all { |child| child.kind_of? Comment }.freeze\n    end\n\n    # Get an array of all Instruction children.\n    # IMMUTABLE\n    def instructions\n      find_all { |child| child.kind_of? Instruction }.freeze\n    end\n\n    # Get an array of all Text children.\n    # IMMUTABLE\n    def texts\n      find_all { |child| child.kind_of? Text }.freeze\n    end\n\n    # == DEPRECATED\n    # See REXML::Formatters\n    #\n    # Writes out this element, and recursively, all children.\n    # output::\n    #\t  output an object which supports '<< string'; this is where the\n    #   document will be written.\n    # indent::\n    #   An integer.  If -1, no indenting will be used; otherwise, the\n    #   indentation will be this number of spaces, and children will be\n    #   indented an additional amount.  Defaults to -1\n    # transitive::\n    #   If transitive is true and indent is >= 0, then the output will be\n    #   pretty-printed in such a way that the added whitespace does not affect\n    #   the parse tree of the document\n    # ie_hack::\n    #   Internet Explorer is the worst piece of crap to have ever been\n    #   written, with the possible exception of Windows itself.  Since IE is\n    #   unable to parse proper XML, we have to provide a hack to generate XML\n    #   that IE's limited abilities can handle.  This hack inserts a space \n    #   before the /> on empty tags.  Defaults to false\n    #\n    #  out = ''\n    #  doc.write( out )     #-> doc is written to the string 'out'\n    #  doc.write( $stdout ) #-> doc written to the console\n    def write(writer=$stdout, indent=-1, transitive=false, ie_hack=false)\n      Kernel.warn(\"#{self.class.name}.write is deprecated.  See REXML::Formatters\")\n      formatter = if indent > -1\n          if transitive\n            REXML::Formatters::Transitive.new( indent, ie_hack )\n          else\n            REXML::Formatters::Pretty.new( indent, ie_hack )\n          end\n        else\n          REXML::Formatters::Default.new( ie_hack )\n        end\n      formatter.write( self, output )\n    end\n\n\n    private\n    def __to_xpath_helper node\n      rv = node.expanded_name.clone\n      if node.parent\n        results = node.parent.find_all {|n| \n          n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name \n        }\n        if results.length > 1\n          idx = results.index( node )\n          rv << \"[#{idx+1}]\"\n        end\n      end\n      rv\n    end\n\n    # A private helper method\n    def each_with_something( test, max=0, name=nil )\n      num = 0\n      child=nil\n      @elements.each( name ){ |child|\n        yield child if test.call(child) and num += 1\n        return if max>0 and num == max\n      }\n    end\n  end\n\n  ########################################################################\n  # ELEMENTS                                                             #\n  ########################################################################\n\n  # A class which provides filtering of children for Elements, and\n  # XPath search support.  You are expected to only encounter this class as\n  # the <tt>element.elements</tt> object.  Therefore, you are \n  # _not_ expected to instantiate this yourself.\n  class Elements\n    include Enumerable\n    # Constructor\n    # parent:: the parent Element\n    def initialize parent\n      @element = parent\n    end\n\n    # Fetches a child element.  Filters only Element children, regardless of\n    # the XPath match.\n    # index:: \n    #   the search parameter.  This is either an Integer, which\n    #   will be used to find the index'th child Element, or an XPath,\n    #   which will be used to search for the Element.  <em>Because\n    #   of the nature of XPath searches, any element in the connected XML\n    #   document can be fetched through any other element.</em>  <b>The\n    #   Integer index is 1-based, not 0-based.</b>  This means that the first\n    #   child element is at index 1, not 0, and the +n+th element is at index\n    #   +n+, not <tt>n-1</tt>.  This is because XPath indexes element children\n    #   starting from 1, not 0, and the indexes should be the same.\n    # name:: \n    #   optional, and only used in the first argument is an\n    #   Integer.  In that case, the index'th child Element that has the\n    #   supplied name will be returned.  Note again that the indexes start at 1.\n    # Returns:: the first matching Element, or nil if no child matched\n    #  doc = Document.new '<a><b/><c id=\"1\"/><c id=\"2\"/><d/></a>'\n    #  doc.root.elements[1]       #-> <b/>\n    #  doc.root.elements['c']     #-> <c id=\"1\"/>\n    #  doc.root.elements[2,'c']   #-> <c id=\"2\"/>\n    def []( index, name=nil)\n      if index.kind_of? Integer\n        raise \"index (#{index}) must be >= 1\" if index < 1\n        name = literalize(name) if name\n        num = 0\n        child = nil\n        @element.find { |child|\n          child.kind_of? Element and\n          (name.nil? ? true : child.has_name?( name )) and \n          (num += 1) == index\n        }\n      else\n        return XPath::first( @element, index )\n        #{ |element| \n        #\treturn element if element.kind_of? Element\n        #}\n        #return nil\n      end\n    end\n\n    # Sets an element, replacing any previous matching element.  If no\n    # existing element is found ,the element is added.\n    # index:: Used to find a matching element to replace.  See []().\n    # element:: \n    #   The element to replace the existing element with\n    #   the previous element\n    # Returns:: nil if no previous element was found.\n    #\n    #  doc = Document.new '<a/>'\n    #  doc.root.elements[10] = Element.new('b')    #-> <a><b/></a>\n    #  doc.root.elements[1]                        #-> <b/>\n    #  doc.root.elements[1] = Element.new('c')     #-> <a><c/></a>\n    #  doc.root.elements['c'] = Element.new('d')   #-> <a><d/></a>\n    def []=( index, element )\n      previous = self[index]\n      if previous.nil?\n        @element.add element\n      else\n        previous.replace_with element\n      end\n      return previous\n    end\n\n    # Returns +true+ if there are no +Element+ children, +false+ otherwise\n    def empty?\n      @element.find{ |child| child.kind_of? Element}.nil?\n    end\n\n    # Returns the index of the supplied child (starting at 1), or -1 if \n    # the element is not a child\n    # element:: an +Element+ child\n    def index element\n      rv = 0\n      found = @element.find do |child| \n        child.kind_of? Element and\n        (rv += 1) and\n        child == element\n      end\n      return rv if found == element\n      return -1\n    end\n\n    # Deletes a child Element\n    # element:: \n    #   Either an Element, which is removed directly; an\n    #   xpath, where the first matching child is removed; or an Integer,\n    #   where the n'th Element is removed.\n    # Returns:: the removed child\n    #  doc = Document.new '<a><b/><c/><c id=\"1\"/></a>'\n    #  b = doc.root.elements[1]\n    #  doc.root.elements.delete b           #-> <a><c/><c id=\"1\"/></a>\n    #  doc.elements.delete(\"a/c[@id='1']\")  #-> <a><c/></a>\n    #  doc.root.elements.delete 1           #-> <a/>\n    def delete element\n      if element.kind_of? Element\n        @element.delete element\n      else\n        el = self[element]\n        el.remove if el\n      end\n    end\n\n    # Removes multiple elements.  Filters for Element children, regardless of\n    # XPath matching.\n    # xpath:: all elements matching this String path are removed.\n    # Returns:: an Array of Elements that have been removed\n    #  doc = Document.new '<a><c/><c/><c/><c/></a>'\n    #  deleted = doc.elements.delete_all 'a/c' #-> [<c/>, <c/>, <c/>, <c/>]\n    def delete_all( xpath )\n      rv = []\n      XPath::each( @element, xpath) {|element| \n        rv << element if element.kind_of? Element\n      }\n      rv.each do |element|\n        @element.delete element\n        element.remove\n      end\n      return rv\n    end\n\n    # Adds an element\n    # element:: \n    #   if supplied, is either an Element, String, or\n    #   Source (see Element.initialize).  If not supplied or nil, a\n    #   new, default Element will be constructed\n    # Returns:: the added Element\n    #  a = Element.new('a')\n    #  a.elements.add(Element.new('b'))  #-> <a><b/></a>\n    #  a.elements.add('c')               #-> <a><b/><c/></a>\n    def add element=nil\n      rv = nil\n      if element.nil?\n        Element.new(\"\", self, @element.context)\n      elsif not element.kind_of?(Element)\n        Element.new(element, self, @element.context)\n      else\n        @element << element\n        element.context = @element.context\n        element\n      end\n    end\n\n    alias :<< :add\n\n    # Iterates through all of the child Elements, optionally filtering\n    # them by a given XPath\n    # xpath:: \n    #   optional.  If supplied, this is a String XPath, and is used to \n    #   filter the children, so that only matching children are yielded.  Note\n    #   that XPaths are automatically filtered for Elements, so that\n    #   non-Element children will not be yielded\n    #  doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'\n    #  doc.root.each {|e|p e}       #-> Yields b, c, d, b, c, d elements\n    #  doc.root.each('b') {|e|p e}  #-> Yields b, b elements\n    #  doc.root.each('child::node()')  {|e|p e}\n    #  #-> Yields <b/>, <c/>, <d/>, <b/>, <c/>, <d/>\n    #  XPath.each(doc.root, 'child::node()', &block)\n    #  #-> Yields <b/>, <c/>, <d/>, sean, <b/>, <c/>, <d/>\n    def each( xpath=nil, &block)\n      XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element }\n    end\n\n    def collect( xpath=nil, &block )\n      collection = []\n      XPath::each( @element, xpath ) {|e| \n        collection << yield(e)  if e.kind_of?(Element) \n      }\n      collection\n    end\n\n    def inject( xpath=nil, initial=nil, &block )\n      first = true\n      XPath::each( @element, xpath ) {|e|\n        if (e.kind_of? Element)\n          if (first and initial == nil)\n            initial = e\n            first = false\n          else\n            initial = yield( initial, e ) if e.kind_of? Element\n          end\n        end\n      }\n      initial\n    end\n\n    # Returns the number of +Element+ children of the parent object.\n    #  doc = Document.new '<a>sean<b/>elliott<b/>russell<b/></a>'\n    #  doc.root.size            #-> 6, 3 element and 3 text nodes\n    #  doc.root.elements.size   #-> 3\n    def size\n      count = 0\n      @element.each {|child| count+=1 if child.kind_of? Element }\n      count\n    end\n\n    # Returns an Array of Element children.  An XPath may be supplied to\n    # filter the children.  Only Element children are returned, even if the\n    # supplied XPath matches non-Element children.\n    #  doc = Document.new '<a>sean<b/>elliott<c/></a>'\n    #  doc.root.elements.to_a                  #-> [ <b/>, <c/> ]\n    #  doc.root.elements.to_a(\"child::node()\") #-> [ <b/>, <c/> ] \n    #  XPath.match(doc.root, \"child::node()\")  #-> [ sean, <b/>, elliott, <c/> ]\n    def to_a( xpath=nil )\n      rv = XPath.match( @element, xpath )\n      return rv.find_all{|e| e.kind_of? Element} if xpath\n      rv\n    end\n\n    private\n    # Private helper class.  Removes quotes from quoted strings\n    def literalize name\n      name = name[1..-2] if name[0] == ?' or name[0] == ?\"               #'\n      name\n    end\n  end\n\n  ########################################################################\n  # ATTRIBUTES                                                           #\n  ########################################################################\n\n  # A class that defines the set of Attributes of an Element and provides \n  # operations for accessing elements in that set.\n  class Attributes < Hash\n    # Constructor\n    # element:: the Element of which this is an Attribute\n    def initialize element\n      @element = element\n    end\n\n    # Fetches an attribute value.  If you want to get the Attribute itself,\n    # use get_attribute()\n    # name:: an XPath attribute name.  Namespaces are relevant here.\n    # Returns:: \n    #   the String value of the matching attribute, or +nil+ if no\n    #   matching attribute was found.  This is the unnormalized value\n    #   (with entities expanded).\n    # \n    #  doc = Document.new \"<a foo:att='1' bar:att='2' att='&lt;'/>\"\n    #  doc.root.attributes['att']         #-> '<'\n    #  doc.root.attributes['bar:att']     #-> '2'\n    def [](name)\n      attr = get_attribute(name)\n      return attr.value unless attr.nil?\n      return nil\n    end\n\n    def to_a\n      values.flatten\n    end\n\n    # Returns the number of attributes the owning Element contains.\n    #  doc = Document \"<a x='1' y='2' foo:x='3'/>\"\n    #  doc.root.attributes.length        #-> 3\n    def length\n      c = 0\n      each_attribute { c+=1 }\n      c\n    end\n    alias :size :length\n\n    # Iterates over the attributes of an Element.  Yields actual Attribute\n    # nodes, not String values.\n    # \n    #  doc = Document.new '<a x=\"1\" y=\"2\"/>'\n    #  doc.root.attributes.each_attribute {|attr|\n    #    p attr.expanded_name+\" => \"+attr.value\n    #  }\n    def each_attribute # :yields: attribute\n      each_value do |val|\n        if val.kind_of? Attribute\n          yield val\n        else\n          val.each_value { |atr| yield atr }\n        end\n      end\n    end\n\n    # Iterates over each attribute of an Element, yielding the expanded name\n    # and value as a pair of Strings.\n    #\n    #  doc = Document.new '<a x=\"1\" y=\"2\"/>'\n    #  doc.root.attributes.each {|name, value| p name+\" => \"+value }\n    def each\n      each_attribute do |attr|\n        yield attr.expanded_name, attr.value\n      end\n    end\n\n    # Fetches an attribute\n    # name:: \n    #   the name by which to search for the attribute.  Can be a\n    #   <tt>prefix:name</tt> namespace name.\n    # Returns:: The first matching attribute, or nil if there was none.  This\n    # value is an Attribute node, not the String value of the attribute.\n    #  doc = Document.new '<a x:foo=\"1\" foo=\"2\" bar=\"3\"/>'\n    #  doc.root.attributes.get_attribute(\"foo\").value    #-> \"2\"\n    #  doc.root.attributes.get_attribute(\"x:foo\").value  #-> \"1\"\n    def get_attribute( name )\n      attr = fetch( name, nil )\n      if attr.nil?\n        return nil if name.nil?\n        # Look for prefix\n        name =~ Namespace::NAMESPLIT\n        prefix, n = $1, $2\n        if prefix\n          attr = fetch( n, nil )\n          # check prefix\n          if attr == nil\n          elsif attr.kind_of? Attribute\n            return attr if prefix == attr.prefix\n          else\n            attr = attr[ prefix ]\n            return attr\n          end\n        end\n        element_document = @element.document\n        if element_document and element_document.doctype\n          expn = @element.expanded_name\n          expn = element_document.doctype.name if expn.size == 0\n          attr_val = element_document.doctype.attribute_of(expn, name)\n          return Attribute.new( name, attr_val ) if attr_val\n        end\n        return nil\n      end\n      if attr.kind_of? Hash\n        attr = attr[ @element.prefix ]\n      end\n      return attr\n    end\n\n    # Sets an attribute, overwriting any existing attribute value by the\n    # same name.  Namespace is significant.\n    # name:: the name of the attribute\n    # value:: \n    #   (optional) If supplied, the value of the attribute.  If\n    #   nil, any existing matching attribute is deleted.\n    # Returns:: \n    #   Owning element\n    #  doc = Document.new \"<a x:foo='1' foo='3'/>\"\n    #  doc.root.attributes['y:foo'] = '2'\n    #  doc.root.attributes['foo'] = '4'\n    #  doc.root.attributes['x:foo'] = nil\n    def []=( name, value )\n      if value.nil?\t\t# Delete the named attribute\n        attr = get_attribute(name)\n        delete attr\n        return\n      end\n      element_document = @element.document\n      unless value.kind_of? Attribute\n        if @element.document and @element.document.doctype\n          value = Text::normalize( value, @element.document.doctype )\n        else\n          value = Text::normalize( value, nil )\n        end\n        value = Attribute.new(name, value)\n      end\n      value.element = @element\n      old_attr = fetch(value.name, nil)\n      if old_attr.nil?\n        store(value.name, value)\n      elsif old_attr.kind_of? Hash\n        old_attr[value.prefix] = value\n      elsif old_attr.prefix != value.prefix\n        # Check for conflicting namespaces\n        raise ParseException.new( \n          \"Namespace conflict in adding attribute \\\"#{value.name}\\\": \"+\n          \"Prefix \\\"#{old_attr.prefix}\\\" = \"+\n          \"\\\"#{@element.namespace(old_attr.prefix)}\\\" and prefix \"+\n          \"\\\"#{value.prefix}\\\" = \\\"#{@element.namespace(value.prefix)}\\\"\") if \n          value.prefix != \"xmlns\" and old_attr.prefix != \"xmlns\" and\n          @element.namespace( old_attr.prefix ) == \n            @element.namespace( value.prefix )\n          store value.name, { old_attr.prefix\t=> old_attr,\n            value.prefix\t\t=> value }\n      else\n        store value.name, value\n      end\n      return @element\n    end\n\n    # Returns an array of Strings containing all of the prefixes declared \n    # by this set of # attributes.  The array does not include the default\n    # namespace declaration, if one exists.\n    #  doc = Document.new(\"<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' \"+\n    #        \"z='glorp' p:k='gru'/>\")\n    #  prefixes = doc.root.attributes.prefixes    #-> ['x', 'y']\n    def prefixes\n      ns = []\n      each_attribute do |attribute|\n        ns << attribute.name if attribute.prefix == 'xmlns'\n      end\n      if @element.document and @element.document.doctype\n        expn = @element.expanded_name\n        expn = @element.document.doctype.name if expn.size == 0\n        @element.document.doctype.attributes_of(expn).each {\n          |attribute|\n          ns << attribute.name if attribute.prefix == 'xmlns'\n        }\n      end\n      ns\n    end\n\n    def namespaces\n      namespaces = {}\n      each_attribute do |attribute|\n        namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'\n      end\n      if @element.document and @element.document.doctype\n        expn = @element.expanded_name\n        expn = @element.document.doctype.name if expn.size == 0\n        @element.document.doctype.attributes_of(expn).each {\n          |attribute|\n          namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'\n        }\n      end\n      namespaces\n    end\n\n    # Removes an attribute\n    # attribute:: \n    #   either a String, which is the name of the attribute to remove --\n    #   namespaces are significant here -- or the attribute to remove.\n    # Returns:: the owning element\n    #  doc = Document.new \"<a y:foo='0' x:foo='1' foo='3' z:foo='4'/>\"\n    #  doc.root.attributes.delete 'foo'   #-> <a y:foo='0' x:foo='1' z:foo='4'/>\"\n    #  doc.root.attributes.delete 'x:foo' #-> <a y:foo='0' z:foo='4'/>\"\n    #  attr = doc.root.attributes.get_attribute('y:foo')\n    #  doc.root.attributes.delete attr    #-> <a z:foo='4'/>\"\n    def delete( attribute )\n      name = nil\n      prefix = nil\n      if attribute.kind_of? Attribute\n        name = attribute.name\n        prefix = attribute.prefix\n      else\n        attribute =~ Namespace::NAMESPLIT\n        prefix, name = $1, $2\n        prefix = '' unless prefix\n      end\n      old = fetch(name, nil)\n      attr = nil\n      if old.kind_of? Hash # the supplied attribute is one of many\n        attr = old.delete(prefix)\n        if old.size == 1\n          repl = nil\n          old.each_value{|v| repl = v}\n          store name, repl\n        end\n      elsif old.nil?\n        return @element\n      else # the supplied attribute is a top-level one\n        attr = old\n        res = super(name)\n      end\n      @element\n    end\n\n    # Adds an attribute, overriding any existing attribute by the\n    # same name.  Namespaces are significant.\n    # attribute:: An Attribute\n    def add( attribute )\n      self[attribute.name] = attribute\n    end\n\n    alias :<< :add\n\n    # Deletes all attributes matching a name.  Namespaces are significant.\n    # name:: \n    #   A String; all attributes that match this path will be removed\n    # Returns:: an Array of the Attributes that were removed\n    def delete_all( name )\n      rv = []\n      each_attribute { |attribute| \n        rv << attribute if attribute.expanded_name == name\n      }\n      rv.each{ |attr| attr.remove }\n      return rv\n    end\n\n    # The +get_attribute_ns+ method retrieves a method by its namespace\n    # and name. Thus it is possible to reliably identify an attribute\n    # even if an XML processor has changed the prefix.\n    # \n    # Method contributed by Henrik Martensson\n    def get_attribute_ns(namespace, name)\n      each_attribute() { |attribute|\n        if name == attribute.name &&\n          namespace == attribute.namespace()\n          return attribute\n        end\n      }\n      nil\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encoding.rb",
    "content": "# -*- mode: ruby; ruby-indent-level: 2; indent-tabs-mode: t; tab-width: 2 -*- vim: sw=2 ts=2\nmodule REXML\n  module Encoding\n    @encoding_methods = {}\n    def self.register(enc, &block)\n      @encoding_methods[enc] = block\n    end\n    def self.apply(obj, enc)\n      @encoding_methods[enc][obj]\n    end\n    def self.encoding_method(enc)\n      @encoding_methods[enc]\n    end\n\n    # Native, default format is UTF-8, so it is declared here rather than in\n    # an encodings/ definition.\n    UTF_8 = 'UTF-8'\n    UTF_16 = 'UTF-16'\n    UNILE = 'UNILE'\n\n    # ID ---> Encoding name\n    attr_reader :encoding\n    def encoding=( enc )\n      old_verbosity = $VERBOSE\n      begin\n        $VERBOSE = false\n        enc = enc.nil? ? nil : enc.upcase\n        return false if defined? @encoding and enc == @encoding\n        if enc and enc != UTF_8\n          @encoding = enc\n          raise ArgumentError, \"Bad encoding name #@encoding\" unless @encoding =~ /^[\\w-]+$/\n          @encoding.untaint \n          begin\n            require 'rexml/encodings/ICONV.rb'\n            Encoding.apply(self, \"ICONV\")\n          rescue LoadError, Exception\n            begin\n              enc_file = File.join( \"rexml\", \"encodings\", \"#@encoding.rb\" )\n              require enc_file\n              Encoding.apply(self, @encoding)\n            rescue LoadError => err\n              puts err.message\n              raise ArgumentError, \"No decoder found for encoding #@encoding.  Please install iconv.\"\n            end\n          end\n        else\n          @encoding = UTF_8\n          require 'rexml/encodings/UTF-8.rb'\n          Encoding.apply(self, @encoding)\n        end\n      ensure\n        $VERBOSE = old_verbosity\n      end\n      true\n    end\n\n    def check_encoding str\n      # We have to recognize UTF-16, LSB UTF-16, and UTF-8\n      if str[0] == 0xfe && str[1] == 0xff\n        str[0,2] = \"\"\n        return UTF_16\n      elsif str[0] == 0xff && str[1] == 0xfe\n        str[0,2] = \"\"\n        return UNILE\n      end\n      str =~ /^\\s*<\\?xml\\s+version\\s*=\\s*(['\"]).*?\\1\\s+encoding\\s*=\\s*([\"'])(.*?)\\2/um\n      return $3.upcase if $3\n      return UTF_8\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/CP-1252.rb",
    "content": "#\n# This class was contributed by Mikko Tiihonen mikko DOT tiihonen AT hut DOT fi\n#\nmodule REXML\n  module Encoding\n  \tregister( \"CP-1252\" ) do |o|\n  \t\tclass << o\n  \t\t\talias encode encode_cp1252\n\t\t\talias decode decode_cp1252\n  \t\tend\n  \tend\n\n    # Convert from UTF-8\n    def encode_cp1252(content)\n      array_utf8 = content.unpack('U*')\n      array_enc = []\n      array_utf8.each do |num|\n        case num\n          # shortcut first bunch basic characters\n        when 0..0xFF; array_enc << num\n          # characters added compared to iso-8859-1\n        when 0x20AC; array_enc << 0x80 # 0xe2 0x82 0xac\n        when 0x201A; array_enc << 0x82 # 0xe2 0x82 0x9a\n        when 0x0192; array_enc << 0x83 # 0xc6 0x92\n        when 0x201E; array_enc << 0x84 # 0xe2 0x82 0x9e\n        when 0x2026; array_enc << 0x85 # 0xe2 0x80 0xa6\n        when 0x2020; array_enc << 0x86 # 0xe2 0x80 0xa0\n        when 0x2021; array_enc << 0x87 # 0xe2 0x80 0xa1\n        when 0x02C6; array_enc << 0x88 # 0xcb 0x86\n        when 0x2030; array_enc << 0x89 # 0xe2 0x80 0xb0\n        when 0x0160; array_enc << 0x8A # 0xc5 0xa0\n        when 0x2039; array_enc << 0x8B # 0xe2 0x80 0xb9\n        when 0x0152; array_enc << 0x8C # 0xc5 0x92\n        when 0x017D; array_enc << 0x8E # 0xc5 0xbd\n        when 0x2018; array_enc << 0x91 # 0xe2 0x80 0x98\n        when 0x2019; array_enc << 0x92 # 0xe2 0x80 0x99\n        when 0x201C; array_enc << 0x93 # 0xe2 0x80 0x9c\n        when 0x201D; array_enc << 0x94 # 0xe2 0x80 0x9d\n        when 0x2022; array_enc << 0x95 # 0xe2 0x80 0xa2\n        when 0x2013; array_enc << 0x96 # 0xe2 0x80 0x93\n        when 0x2014; array_enc << 0x97 # 0xe2 0x80 0x94\n        when 0x02DC; array_enc << 0x98 # 0xcb 0x9c\n        when 0x2122; array_enc << 0x99 # 0xe2 0x84 0xa2\n        when 0x0161; array_enc << 0x9A # 0xc5 0xa1\n        when 0x203A; array_enc << 0x9B # 0xe2 0x80 0xba\n        when 0x0152; array_enc << 0x9C # 0xc5 0x93\n        when 0x017E; array_enc << 0x9E # 0xc5 0xbe\n        when 0x0178; array_enc << 0x9F # 0xc5 0xb8\n        else\n          # all remaining basic characters can be used directly\n          if num <= 0xFF\n            array_enc << num\n          else\n            # Numeric entity (&#nnnn;); shard by  Stefan Scholl\n            array_enc.concat \"&\\##{num};\".unpack('C*')\n          end\n        end\n      end\n      array_enc.pack('C*')\n    end\n    \n    # Convert to UTF-8\n    def decode_cp1252(str)\n      array_latin9 = str.unpack('C*')\n      array_enc = []\n      array_latin9.each do |num|\n        case num\n          # characters that added compared to iso-8859-1\n        when 0x80; array_enc << 0x20AC # 0xe2 0x82 0xac\n        when 0x82; array_enc << 0x201A # 0xe2 0x82 0x9a\n        when 0x83; array_enc << 0x0192 # 0xc6 0x92\n        when 0x84; array_enc << 0x201E # 0xe2 0x82 0x9e\n        when 0x85; array_enc << 0x2026 # 0xe2 0x80 0xa6\n        when 0x86; array_enc << 0x2020 # 0xe2 0x80 0xa0\n        when 0x87; array_enc << 0x2021 # 0xe2 0x80 0xa1\n        when 0x88; array_enc << 0x02C6 # 0xcb 0x86\n        when 0x89; array_enc << 0x2030 # 0xe2 0x80 0xb0\n        when 0x8A; array_enc << 0x0160 # 0xc5 0xa0\n        when 0x8B; array_enc << 0x2039 # 0xe2 0x80 0xb9\n        when 0x8C; array_enc << 0x0152 # 0xc5 0x92\n        when 0x8E; array_enc << 0x017D # 0xc5 0xbd\n        when 0x91; array_enc << 0x2018 # 0xe2 0x80 0x98\n        when 0x92; array_enc << 0x2019 # 0xe2 0x80 0x99\n        when 0x93; array_enc << 0x201C # 0xe2 0x80 0x9c\n        when 0x94; array_enc << 0x201D # 0xe2 0x80 0x9d\n        when 0x95; array_enc << 0x2022 # 0xe2 0x80 0xa2\n        when 0x96; array_enc << 0x2013 # 0xe2 0x80 0x93\n        when 0x97; array_enc << 0x2014 # 0xe2 0x80 0x94\n        when 0x98; array_enc << 0x02DC # 0xcb 0x9c\n        when 0x99; array_enc << 0x2122 # 0xe2 0x84 0xa2\n        when 0x9A; array_enc << 0x0161 # 0xc5 0xa1\n        when 0x9B; array_enc << 0x203A # 0xe2 0x80 0xba\n        when 0x9C; array_enc << 0x0152 # 0xc5 0x93\n        when 0x9E; array_enc << 0x017E # 0xc5 0xbe\n        when 0x9F; array_enc << 0x0178 # 0xc5 0xb8\n        else\n          array_enc << num\n        end\n      end\n      array_enc.pack('U*')\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/EUC-JP.rb",
    "content": "module REXML\n  module Encoding\n    begin\n      require 'uconv'\n\n      def decode_eucjp(str)\n        Uconv::euctou8(str)\n      end\n\n      def encode_eucjp content\n        Uconv::u8toeuc(content)\n      end\n    rescue LoadError\n      require 'nkf'\n\n      EUCTOU8 = '-Ewm0'\n      U8TOEUC = '-Wem0'\n\n      def decode_eucjp(str)\n        NKF.nkf(EUCTOU8, str)\n      end\n\n      def encode_eucjp content\n        NKF.nkf(U8TOEUC, content)\n      end\n    end\n\n    register(\"EUC-JP\") do |obj|\n      class << obj\n        alias decode decode_eucjp\n        alias encode encode_eucjp\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/ICONV.rb",
    "content": "require \"iconv\"\nraise LoadError unless defined? Iconv\n\nmodule REXML\n  module Encoding\n    def decode_iconv(str)\n      Iconv.conv(UTF_8, @encoding, str)\n    end\n\n    def encode_iconv(content)\n      Iconv.conv(@encoding, UTF_8, content)\n    end\n\n    register(\"ICONV\") do |obj|\n      Iconv.conv(UTF_8, obj.encoding, nil)\n      class << obj\n        alias decode decode_iconv\n        alias encode encode_iconv\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/ISO-8859-1.rb",
    "content": "require 'rexml/encodings/US-ASCII'\n\nmodule REXML\n  module Encoding\n    register(\"ISO-8859-1\", &encoding_method(\"US-ASCII\"))\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/ISO-8859-15.rb",
    "content": "#\n# This class was contributed by Mikko Tiihonen mikko DOT tiihonen AT hut DOT fi\n#\nmodule REXML\n  module Encoding\n  \tregister(\"ISO-8859-15\") do |o|\n  \t\talias encode to_iso_8859_15\n      alias decode from_iso_8859_15\n  \tend\n\n    # Convert from UTF-8\n    def to_iso_8859_15(content)\n      array_utf8 = content.unpack('U*')\n      array_enc = []\n      array_utf8.each do |num|\n        case num\n          # shortcut first bunch basic characters\n        when 0..0xA3; array_enc << num\n          # characters removed compared to iso-8859-1\n        when 0xA4; array_enc << '&#164;'\n        when 0xA6; array_enc << '&#166;'\n        when 0xA8; array_enc << '&#168;'\n        when 0xB4; array_enc << '&#180;'\n        when 0xB8; array_enc << '&#184;'\n        when 0xBC; array_enc << '&#188;'\n        when 0xBD; array_enc << '&#189;'\n        when 0xBE; array_enc << '&#190;'\n          # characters added compared to iso-8859-1\n        when 0x20AC; array_enc << 0xA4 # 0xe2 0x82 0xac\n        when 0x0160; array_enc << 0xA6 # 0xc5 0xa0\n        when 0x0161; array_enc << 0xA8 # 0xc5 0xa1\n        when 0x017D; array_enc << 0xB4 # 0xc5 0xbd\n        when 0x017E; array_enc << 0xB8 # 0xc5 0xbe\n        when 0x0152; array_enc << 0xBC # 0xc5 0x92\n        when 0x0153; array_enc << 0xBD # 0xc5 0x93\n        when 0x0178; array_enc << 0xBE # 0xc5 0xb8\n        else\n          # all remaining basic characters can be used directly\n          if num <= 0xFF\n            array_enc << num\n          else\n            # Numeric entity (&#nnnn;); shard by  Stefan Scholl\n            array_enc.concat \"&\\##{num};\".unpack('C*')\n          end\n        end\n      end\n      array_enc.pack('C*')\n    end\n    \n    # Convert to UTF-8\n    def from_iso_8859_15(str)\n      array_latin9 = str.unpack('C*')\n      array_enc = []\n      array_latin9.each do |num|\n        case num\n          # characters that differ compared to iso-8859-1\n        when 0xA4; array_enc << 0x20AC\n        when 0xA6; array_enc << 0x0160\n        when 0xA8; array_enc << 0x0161\n        when 0xB4; array_enc << 0x017D\n        when 0xB8; array_enc << 0x017E\n        when 0xBC; array_enc << 0x0152\n        when 0xBD; array_enc << 0x0153\n        when 0xBE; array_enc << 0x0178\n        else\n          array_enc << num\n        end\n      end\n      array_enc.pack('U*')\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/SHIFT-JIS.rb",
    "content": "module REXML\n  module Encoding\n    begin\n      require 'uconv'\n\n      def decode_sjis content\n        Uconv::sjistou8(content)\n      end\n\n      def encode_sjis(str)\n        Uconv::u8tosjis(str)\n      end\n    rescue LoadError\n      require 'nkf'\n\n      SJISTOU8 = '-Swm0x'\n      U8TOSJIS = '-Wsm0x'\n\n      def decode_sjis(str)\n        NKF.nkf(SJISTOU8, str)\n      end\n\n      def encode_sjis content\n        NKF.nkf(U8TOSJIS, content)\n      end\n    end\n\n    b = proc do |obj|\n      class << obj\n        alias decode decode_sjis\n        alias encode encode_sjis\n      end\n    end\n    register(\"SHIFT-JIS\", &b)\n    register(\"SHIFT_JIS\", &b)\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/SHIFT_JIS.rb",
    "content": "require 'rexml/encodings/SHIFT-JIS'\n"
  },
  {
    "path": "lib/rexml/encodings/UNILE.rb",
    "content": "module REXML\n  module Encoding\n    def encode_unile content\n      array_utf8 = content.unpack(\"U*\")\n      array_enc = []\n      array_utf8.each do |num|\n        if ((num>>16) > 0)\n          array_enc << ??\n          array_enc << 0\n        else\n          array_enc << (num & 0xFF)\n          array_enc << (num >> 8)\n        end\n      end\n      array_enc.pack('C*')\n    end\n\n    def decode_unile(str)\n      array_enc=str.unpack('C*')\n      array_utf8 = []\n      0.step(array_enc.size-1, 2){|i| \n        array_utf8 << (array_enc.at(i) + array_enc.at(i+1)*0x100)\n      }\n      array_utf8.pack('U*')\n    end\n\n    register(UNILE) do |obj|\n      class << obj\n        alias decode decode_unile\n        alias encode encode_unile\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/US-ASCII.rb",
    "content": "module REXML\n  module Encoding\n    # Convert from UTF-8\n    def encode_ascii content\n      array_utf8 = content.unpack('U*')\n      array_enc = []\n      array_utf8.each do |num|\n        if num <= 0x7F\n          array_enc << num\n        else\n          # Numeric entity (&#nnnn;); shard by  Stefan Scholl\n          array_enc.concat \"&\\##{num};\".unpack('C*')\n        end\n      end\n      array_enc.pack('C*')\n    end\n\n    # Convert to UTF-8\n    def decode_ascii(str)\n      str.unpack('C*').pack('U*')\n    end\n\n    register(\"US-ASCII\") do |obj|\n      class << obj\n        alias decode decode_ascii\n        alias encode encode_ascii\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/UTF-16.rb",
    "content": "module REXML\n  module Encoding\n    def encode_utf16 content\n      array_utf8 = content.unpack(\"U*\")\n      array_enc = []\n      array_utf8.each do |num|\n        if ((num>>16) > 0)\n          array_enc << 0\n          array_enc << ??\n        else\n          array_enc << (num >> 8)\n          array_enc << (num & 0xFF)\n        end\n      end\n      array_enc.pack('C*')\n    end\n\n    def decode_utf16(str)\n      str = str[2..-1] if /^\\376\\377/n =~ str\n      array_enc=str.unpack('C*')\n      array_utf8 = []\n      0.step(array_enc.size-1, 2){|i| \n        array_utf8 << (array_enc.at(i+1) + array_enc.at(i)*0x100)\n      }\n      array_utf8.pack('U*')\n    end\n\n    register(UTF_16) do |obj|\n      class << obj\n        alias decode decode_utf16\n        alias encode encode_utf16\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/encodings/UTF-8.rb",
    "content": "module REXML\n  module Encoding\n    def encode_utf8 content\n      content\n    end\n\n    def decode_utf8(str)\n      str\n    end\n\n    register(UTF_8) do |obj|\n      class << obj\n        alias decode decode_utf8\n        alias encode encode_utf8\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/entity.rb",
    "content": "require 'rexml/child'\nrequire 'rexml/source'\nrequire 'rexml/xmltokens'\n\nmodule REXML\n\t# God, I hate DTDs.  I really do.  Why this idiot standard still\n\t# plagues us is beyond me.\n\tclass Entity < Child\n\t\tinclude XMLTokens\n\t\tPUBIDCHAR = \"\\x20\\x0D\\x0Aa-zA-Z0-9\\\\-()+,./:=?;!*@$_%#\"\n\t\tSYSTEMLITERAL = %Q{((?:\"[^\"]*\")|(?:'[^']*'))}\n\t\tPUBIDLITERAL = %Q{(\"[#{PUBIDCHAR}']*\"|'[#{PUBIDCHAR}]*')}\n\t\tEXTERNALID = \"(?:(?:(SYSTEM)\\\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\\\s+#{PUBIDLITERAL}\\\\s+#{SYSTEMLITERAL}))\"\n\t\tNDATADECL = \"\\\\s+NDATA\\\\s+#{NAME}\"\n\t\tPEREFERENCE = \"%#{NAME};\"\n\t\tENTITYVALUE = %Q{((?:\"(?:[^%&\"]|#{PEREFERENCE}|#{REFERENCE})*\")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}\n\t\tPEDEF = \"(?:#{ENTITYVALUE}|#{EXTERNALID})\"\n\t\tENTITYDEF = \"(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))\"\n\t\tPEDECL = \"<!ENTITY\\\\s+(%)\\\\s+#{NAME}\\\\s+#{PEDEF}\\\\s*>\"\n\t\tGEDECL = \"<!ENTITY\\\\s+#{NAME}\\\\s+#{ENTITYDEF}\\\\s*>\"\n\t\tENTITYDECL = /\\s*(?:#{GEDECL})|(?:#{PEDECL})/um\n\n\t\tattr_reader :name, :external, :ref, :ndata, :pubid\n\n\t\t# Create a new entity.  Simple entities can be constructed by passing a\n\t\t# name, value to the constructor; this creates a generic, plain entity\n\t\t# reference. For anything more complicated, you have to pass a Source to\n\t\t# the constructor with the entity definiton, or use the accessor methods.\n\t\t# +WARNING+: There is no validation of entity state except when the entity\n\t\t# is read from a stream.  If you start poking around with the accessors,\n\t\t# you can easily create a non-conformant Entity.  The best thing to do is\n\t\t# dump the stupid DTDs and use XMLSchema instead.\n\t\t# \n\t\t#  e = Entity.new( 'amp', '&' )\n\t\tdef initialize stream, value=nil, parent=nil, reference=false\n\t\t\tsuper(parent)\n\t\t\t@ndata = @pubid = @value = @external = nil\n\t\t\tif stream.kind_of? Array\n\t\t\t\t@name = stream[1]\n\t\t\t\tif stream[-1] == '%'\n\t\t\t\t\t@reference = true \n\t\t\t\t\tstream.pop\n\t\t\t\telse\n\t\t\t\t\t@reference = false\n\t\t\t\tend\n\t\t\t\tif stream[2] =~ /SYSTEM|PUBLIC/\n\t\t\t\t\t@external = stream[2]\n\t\t\t\t\tif @external == 'SYSTEM'\n\t\t\t\t\t\t@ref = stream[3]\n\t\t\t\t\t\t@ndata = stream[4] if stream.size == 5\n\t\t\t\t\telse\n\t\t\t\t\t\t@pubid = stream[3]\n\t\t\t\t\t\t@ref = stream[4]\n\t\t\t\t\tend\n\t\t\t\telse\n\t\t\t\t\t@value = stream[2]\n\t\t\t\tend\n\t\t\telse\n\t\t\t\t@reference = reference\n\t\t\t\t@external = nil\n\t\t\t\t@name = stream\n\t\t\t\t@value = value\n\t\t\tend\n\t\tend\n\n\t\t# Evaluates whether the given string matchs an entity definition,\n\t\t# returning true if so, and false otherwise.\n\t\tdef Entity::matches? string\n\t\t\t(ENTITYDECL =~ string) == 0\n\t\tend\n\n\t\t# Evaluates to the unnormalized value of this entity; that is, replacing\n\t\t# all entities -- both %ent; and &ent; entities.  This differs from\n\t\t# +value()+ in that +value+ only replaces %ent; entities.\n\t\tdef unnormalized\n                        document.record_entity_expansion unless document.nil?\n\t\t\tv = value()\n\t\t\treturn nil if v.nil?\n\t\t\t@unnormalized = Text::unnormalize(v, parent)\n\t\t\t@unnormalized\n\t\tend\n\n\t\t#once :unnormalized\n\n\t\t# Returns the value of this entity unprocessed -- raw.  This is the\n\t\t# normalized value; that is, with all %ent; and &ent; entities intact\n\t\tdef normalized\n\t\t\t@value\n\t\tend\n\n\t\t# Write out a fully formed, correct entity definition (assuming the Entity\n\t\t# object itself is valid.)\n    #\n    # out::\n    #   An object implementing <TT>&lt;&lt;<TT> to which the entity will be\n    #   output\n    # indent::\n    #   *DEPRECATED* and ignored\n\t\tdef write out, indent=-1\n\t\t\tout << '<!ENTITY '\n\t\t\tout << '% ' if @reference\n\t\t\tout << @name\n\t\t\tout << ' '\n\t\t\tif @external\n\t\t\t\tout << @external << ' '\n\t\t\t\tif @pubid\n\t\t\t\t\tq = @pubid.include?('\"')?\"'\":'\"'\n\t\t\t\t\tout << q << @pubid << q << ' '\n\t\t\t\tend\n\t\t\t\tq = @ref.include?('\"')?\"'\":'\"'\n\t\t\t\tout << q << @ref << q\n\t\t\t\tout << ' NDATA ' << @ndata if @ndata\n\t\t\telse\n\t\t\t\tq = @value.include?('\"')?\"'\":'\"'\n\t\t\t\tout << q << @value << q\n\t\t\tend\n\t\t\tout << '>'\n\t\tend\n\n\t\t# Returns this entity as a string.  See write().\n\t\tdef to_s\n\t\t\trv = ''\n\t\t\twrite rv\n\t\t\trv\n\t\tend\n\n\t\tPEREFERENCE_RE = /#{PEREFERENCE}/um\n\t\t# Returns the value of this entity.  At the moment, only internal entities\n\t\t# are processed.  If the value contains internal references (IE,\n\t\t# %blah;), those are replaced with their values.  IE, if the doctype\n\t\t# contains:\n\t\t#  <!ENTITY % foo \"bar\">\n\t\t#  <!ENTITY yada \"nanoo %foo; nanoo>\n\t\t# then:\n\t\t#  doctype.entity('yada').value   #-> \"nanoo bar nanoo\"\n\t\tdef value\n\t\t\tif @value\n\t\t\t\tmatches = @value.scan(PEREFERENCE_RE)\n\t\t\t\trv = @value.clone\n\t\t\t\tif @parent\n\t\t\t\t\tmatches.each do |entity_reference|\n\t\t\t\t\t\tentity_value = @parent.entity( entity_reference[0] )\n\t\t\t\t\t\trv.gsub!( /%#{entity_reference};/um, entity_value )\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\treturn rv\n\t\t\tend\n\t\t\tnil\n\t\tend\n\tend\n\n\t# This is a set of entity constants -- the ones defined in the XML\n\t# specification.  These are +gt+, +lt+, +amp+, +quot+ and +apos+.\n\tmodule EntityConst\n\t\t# +>+\n\t\tGT = Entity.new( 'gt', '>' )\n\t\t# +<+\n\t\tLT = Entity.new( 'lt', '<' )\n\t\t# +&+\n\t\tAMP = Entity.new( 'amp', '&' )\n\t\t# +\"+\n\t\tQUOT = Entity.new( 'quot', '\"' )\n\t\t# +'+\n\t\tAPOS = Entity.new( 'apos', \"'\" )\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/formatters/default.rb",
    "content": "module REXML\n  module Formatters\n    class Default\n      # Prints out the XML document with no formatting -- except if id_hack is\n      # set.\n      #\n      # ie_hack::\n      #   If set to true, then inserts whitespace before the close of an empty\n      #   tag, so that IE's bad XML parser doesn't choke.\n      def initialize( ie_hack=false )\n        @ie_hack = ie_hack\n      end\n\n      # Writes the node to some output.\n      #\n      # node::\n      #   The node to write\n      # output::\n      #   A class implementing <TT>&lt;&lt;</TT>.  Pass in an Output object to\n      #   change the output encoding.\n      def write( node, output )\n        case node\n\n        when Document \n          if node.xml_decl.encoding != \"UTF-8\" && !output.kind_of?(Output)\n            output = Output.new( output, node.xml_decl.encoding )\n          end\n          write_document( node, output )\n\n        when Element\n          write_element( node, output )\n\n        when Declaration, ElementDecl, NotationDecl, ExternalEntity, Entity,\n             Attribute, AttlistDecl\n          node.write( output,-1 )\n\n        when Instruction\n          write_instruction( node, output )\n\n        when DocType, XMLDecl\n          node.write( output )\n\n        when Comment\n          write_comment( node, output )\n\n        when CData\n          write_cdata( node, output )\n\n        when Text\n          write_text( node, output )\n\n        else\n          raise Exception.new(\"XML FORMATTING ERROR\")\n\n        end\n      end\n\n      protected\n      def write_document( node, output )\n        node.children.each { |child| write( child, output ) }\n      end\n\n      def write_element( node, output )\n        output << \"<#{node.expanded_name}\"\n\n        node.attributes.each_attribute do |attr|\n          output << \" \"\n          attr.write( output )\n        end unless node.attributes.empty?\n\n        if node.children.empty?\n          output << \" \" if @ie_hack\n          output << \"/\" \n        else\n          output << \">\"\n          node.children.each { |child|\n            write( child, output )\n          }\n          output << \"</#{node.expanded_name}\"\n        end\n        output << \">\"\n      end\n\n      def write_text( node, output )\n        output << node.to_s()\n      end\n\n      def write_comment( node, output )\n        output << Comment::START\n        output << node.to_s\n        output << Comment::STOP\n      end\n\n      def write_cdata( node, output )\n        output << CData::START\n        output << node.to_s\n        output << CData::STOP\n      end\n\n      def write_instruction( node, output )\n        output << Instruction::START.sub(/\\\\/u, '')\n        output << node.target\n        output << ' '\n        output << node.content\n        output << Instruction::STOP.sub(/\\\\/u, '')\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/formatters/pretty.rb",
    "content": "require 'rexml/formatters/default'\n\nmodule REXML\n  module Formatters\n    # Pretty-prints an XML document.  This destroys whitespace in text nodes\n    # and will insert carriage returns and indentations.\n    #\n    # TODO: Add an option to print attributes on new lines\n    class Pretty < Default\n\n      # If compact is set to true, then the formatter will attempt to use as\n      # little space as possible\n      attr_accessor :compact\n      # The width of a page.  Used for formatting text\n      attr_accessor :width\n\n      # Create a new pretty printer.\n      #\n      # output::\n      #   An object implementing '<<(String)', to which the output will be written.\n      # indentation::\n      #   An integer greater than 0.  The indentation of each level will be\n      #   this number of spaces.  If this is < 1, the behavior of this object\n      #   is undefined.  Defaults to 2.\n      # ie_hack::\n      #   If true, the printer will insert whitespace before closing empty\n      #   tags, thereby allowing Internet Explorer's feeble XML parser to\n      #   function. Defaults to false.\n      def initialize( indentation=2, ie_hack=false )\n        @indentation = indentation\n        @level = 0\n        @ie_hack = ie_hack\n        @width = 80\n      end\n\n      protected\n      def write_element(node, output)\n        output << ' '*@level\n        output << \"<#{node.expanded_name}\"\n\n        node.attributes.each_attribute do |attr|\n          output << \" \"\n          attr.write( output )\n        end unless node.attributes.empty?\n\n        if node.children.empty?\n          if @ie_hack\n            output << \" \"\n          end\n          output << \"/\" \n        else\n          output << \">\"\n          # If compact and all children are text, and if the formatted output\n          # is less than the specified width, then try to print everything on\n          # one line\n          skip = false\n          if compact\n            if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}\n              string = \"\"\n              old_level = @level\n              @level = 0\n              node.children.each { |child| write( child, string ) }\n              @level = old_level\n              if string.length < @width\n                output << string\n                skip = true\n              end\n            end\n          end\n          unless skip\n            output << \"\\n\"\n            @level += @indentation\n            node.children.each { |child|\n              next if child.kind_of?(Text) and child.to_s.strip.length == 0\n              write( child, output )\n              output << \"\\n\"\n            }\n            @level -= @indentation\n            output << ' '*@level\n          end\n          output << \"</#{node.expanded_name}\"\n        end\n        output << \">\"\n      end\n\n      def write_text( node, output )\n        s = node.to_s()\n        s.gsub!(/\\s/,' ')\n        s.squeeze!(\" \")\n        s = wrap(s, 80-@level)\n        s = indent_text(s, @level, \" \", true)\n        output << (' '*@level + s)\n      end\n\n      def write_comment( node, output)\n        output << ' ' * @level\n        super\n      end\n\n      def write_cdata( node, output)\n        output << ' ' * @level\n        super\n      end\n\n      def write_document( node, output )\n        # Ok, this is a bit odd.  All XML documents have an XML declaration,\n        # but it may not write itself if the user didn't specifically add it,\n        # either through the API or in the input document.  If it doesn't write\n        # itself, then we don't need a carriage return... which makes this\n        # logic more complex.\n        node.children.each { |child|\n          next if child == node.children[-1] and child.instance_of?(Text)\n          unless child == node.children[0] or child.instance_of?(Text) or\n            (child == node.children[1] and !node.children[0].writethis)\n            output << \"\\n\"\n          end\n          write( child, output )\n        }\n      end\n\n      private\n      def indent_text(string, level=1, style=\"\\t\", indentfirstline=true)\n        return string if level < 0\n        string.gsub(/\\n/, \"\\n#{style*level}\")\n      end\n\n      def wrap(string, width)\n        # Recursively wrap string at width.\n        return string if string.length <= width\n        place = string.rindex(' ', width) # Position in string with last ' ' before cutoff\n        return string if place.nil?\n        return string[0,place] + \"\\n\" + wrap(string[place+1..-1], width)\n      end\n\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/rexml/formatters/transitive.rb",
    "content": "require 'rexml/formatters/pretty'\n\nmodule REXML\n  module Formatters\n    # The Transitive formatter writes an XML document that parses to an\n    # identical document as the source document.  This means that no extra\n    # whitespace nodes are inserted, and whitespace within text nodes is\n    # preserved.  Within these constraints, the document is pretty-printed,\n    # with whitespace inserted into the metadata to introduce formatting.\n    #\n    # Note that this is only useful if the original XML is not already\n    # formatted.  Since this formatter does not alter whitespace nodes, the\n    # results of formatting already formatted XML will be odd.\n    class Transitive < Default\n      def initialize( indentation=2 )\n        @indentation = indentation\n        @level = 0\n      end\n\n      protected\n      def write_element( node, output )\n        output << \"<#{node.expanded_name}\"\n\n        node.attributes.each_attribute do |attr|\n          output << \" \"\n          attr.write( output )\n        end unless node.attributes.empty?\n\n        output << \"\\n\"\n        output << ' '*@level\n        if node.children.empty?\n          output << \"/\" \n        else\n          output << \">\"\n          # If compact and all children are text, and if the formatted output\n          # is less than the specified width, then try to print everything on\n          # one line\n          skip = false\n          @level += @indentation\n          node.children.each { |child|\n            write( child, output )\n          }\n          @level -= @indentation\n          output << \"</#{node.expanded_name}\"\n          output << \"\\n\"\n          output << ' '*@level\n        end\n        output << \">\"\n      end\n\n      def write_text( node, output )\n        output << node.to_s()\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/functions.rb",
    "content": "module REXML\n  # If you add a method, keep in mind two things:\n  # (1) the first argument will always be a list of nodes from which to\n  # filter.  In the case of context methods (such as position), the function\n  # should return an array with a value for each child in the array.\n  # (2) all method calls from XML will have \"-\" replaced with \"_\".\n  # Therefore, in XML, \"local-name()\" is identical (and actually becomes)\n  # \"local_name()\"\n  module Functions\n    @@context = nil\n    @@namespace_context = {}\n    @@variables = {}\n\n    def Functions::namespace_context=(x) ; @@namespace_context=x ; end\n    def Functions::variables=(x) ; @@variables=x ; end\n    def Functions::namespace_context ; @@namespace_context ; end\n    def Functions::variables ; @@variables ; end\n\n    def Functions::context=(value); @@context = value; end\n\n    def Functions::text( )\n      if @@context[:node].node_type == :element\n        return @@context[:node].find_all{|n| n.node_type == :text}.collect{|n| n.value}\n      elsif @@context[:node].node_type == :text\n        return @@context[:node].value\n      else\n        return false\n      end\n    end\n\n    def Functions::last( )\n      @@context[:size]\n    end\n\n    def Functions::position( )\n      @@context[:index]\n    end\n\n    def Functions::count( node_set )\n      node_set.size\n    end\n\n    # Since REXML is non-validating, this method is not implemented as it\n    # requires a DTD\n    def Functions::id( object )\n    end\n\n    # UNTESTED\n    def Functions::local_name( node_set=nil )\n      get_namespace( node_set ) do |node|\n        return node.local_name \n      end\n    end\n\n    def Functions::namespace_uri( node_set=nil )\n      get_namespace( node_set ) {|node| node.namespace}\n    end\n\n    def Functions::name( node_set=nil )\n      get_namespace( node_set ) do |node| \n        node.expanded_name\n      end\n    end\n\n    # Helper method.\n    def Functions::get_namespace( node_set = nil )\n      if node_set == nil\n        yield @@context[:node] if defined? @@context[:node].namespace\n      else  \n        if node_set.respond_to? :each\n          node_set.each { |node| yield node if defined? node.namespace }\n        elsif node_set.respond_to? :namespace\n          yield node_set\n        end\n      end\n    end\n\n    # A node-set is converted to a string by returning the string-value of the\n    # node in the node-set that is first in document order. If the node-set is\n    # empty, an empty string is returned.\n    #\n    # A number is converted to a string as follows\n    #\n    # NaN is converted to the string NaN \n    #\n    # positive zero is converted to the string 0 \n    #\n    # negative zero is converted to the string 0 \n    #\n    # positive infinity is converted to the string Infinity \n    #\n    # negative infinity is converted to the string -Infinity \n    #\n    # if the number is an integer, the number is represented in decimal form\n    # as a Number with no decimal point and no leading zeros, preceded by a\n    # minus sign (-) if the number is negative\n    #\n    # otherwise, the number is represented in decimal form as a Number\n    # including a decimal point with at least one digit before the decimal\n    # point and at least one digit after the decimal point, preceded by a\n    # minus sign (-) if the number is negative; there must be no leading zeros\n    # before the decimal point apart possibly from the one required digit\n    # immediately before the decimal point; beyond the one required digit\n    # after the decimal point there must be as many, but only as many, more\n    # digits as are needed to uniquely distinguish the number from all other\n    # IEEE 754 numeric values.\n    #\n    # The boolean false value is converted to the string false. The boolean\n    # true value is converted to the string true.\n    #\n    # An object of a type other than the four basic types is converted to a\n    # string in a way that is dependent on that type.\n    def Functions::string( object=nil )\n      #object = @context unless object\n      if object.instance_of? Array\n        string( object[0] )\n      elsif defined? object.node_type\n        if object.node_type == :attribute\n          object.value\n        elsif object.node_type == :element || object.node_type == :document\n          string_value(object)\n        else\n          object.to_s\n        end\n      elsif object.nil?\n        return \"\"\n      else\n        object.to_s\n      end\n    end\n\n    def Functions::string_value( o )\n      rv = \"\"\n      o.children.each { |e|\n        if e.node_type == :text\n          rv << e.to_s\n        elsif e.node_type == :element\n          rv << string_value( e )\n        end\n      }\n      rv\n    end\n\n    # UNTESTED\n    def Functions::concat( *objects )\n      objects.join\n    end\n\n    # Fixed by Mike Stok\n    def Functions::starts_with( string, test )\n      string(string).index(string(test)) == 0\n    end\n\n    # Fixed by Mike Stok\n    def Functions::contains( string, test )\n      string(string).include?(string(test))\n    end\n\n    # Kouhei fixed this \n    def Functions::substring_before( string, test )\n      ruby_string = string(string)\n      ruby_index = ruby_string.index(string(test))\n      if ruby_index.nil?\n        \"\"\n      else\n        ruby_string[ 0...ruby_index ]\n      end\n    end\n \n    # Kouhei fixed this too\n    def Functions::substring_after( string, test )\n      ruby_string = string(string)\n      test_string = string(test)\n      return $1 if ruby_string =~ /#{test}(.*)/\n      \"\"\n    end\n\n    # Take equal portions of Mike Stok and Sean Russell; mix \n    # vigorously, and pour into a tall, chilled glass.  Serves 10,000.\n    def Functions::substring( string, start, length=nil )\n      ruby_string = string(string)\n      ruby_length = if length.nil? \n                      ruby_string.length.to_f\n                    else\n                      number(length)\n                    end\n      ruby_start = number(start)\n\n      # Handle the special cases\n      return '' if (\n        ruby_length.nan? or \n        ruby_start.nan? or\n        ruby_start.infinite?\n      )\n\n      infinite_length = ruby_length.infinite? == 1\n      ruby_length = ruby_string.length if infinite_length\n        \n      # Now, get the bounds.  The XPath bounds are 1..length; the ruby bounds \n      # are 0..length.  Therefore, we have to offset the bounds by one.\n      ruby_start = ruby_start.round - 1\n      ruby_length = ruby_length.round\n\n      if ruby_start < 0\n       ruby_length += ruby_start unless infinite_length\n       ruby_start = 0\n      end\n      return '' if ruby_length <= 0\n      ruby_string[ruby_start,ruby_length]\n    end\n\n    # UNTESTED\n    def Functions::string_length( string )\n      string(string).length\n    end\n\n    # UNTESTED\n    def Functions::normalize_space( string=nil )\n      string = string(@@context[:node]) if string.nil?\n      if string.kind_of? Array\n        string.collect{|x| string.to_s.strip.gsub(/\\s+/um, ' ') if string}\n      else\n        string.to_s.strip.gsub(/\\s+/um, ' ')\n      end\n    end\n\n    # This is entirely Mike Stok's beast\n    def Functions::translate( string, tr1, tr2 )\n      from = string(tr1)\n      to = string(tr2)\n\n      # the map is our translation table.\n      #\n      # if a character occurs more than once in the\n      # from string then we ignore the second &\n      # subsequent mappings\n      #\n      # if a character maps to nil then we delete it\n      # in the output.  This happens if the from\n      # string is longer than the to string\n      #\n      # there's nothing about - or ^ being special in\n      # http://www.w3.org/TR/xpath#function-translate\n      # so we don't build ranges or negated classes\n\n      map = Hash.new\n      0.upto(from.length - 1) { |pos|\n        from_char = from[pos]\n        unless map.has_key? from_char\n          map[from_char] = \n          if pos < to.length\n            to[pos]\n          else\n            nil\n          end\n        end\n      }\n\n      string(string).unpack('U*').collect { |c|\n        if map.has_key? c then map[c] else c end\n      }.compact.pack('U*')\n    end\n\n    # UNTESTED\n    def Functions::boolean( object=nil )\n      if object.kind_of? String\n        if object =~ /\\d+/u\n          return object.to_f != 0\n        else\n          return object.size > 0\n        end\n      elsif object.kind_of? Array\n        object = object.find{|x| x and true}\n      end\n      return object ? true : false\n    end\n\n    # UNTESTED\n    def Functions::not( object )\n      not boolean( object )\n    end\n\n    # UNTESTED\n    def Functions::true( )\n      true\n    end\n\n    # UNTESTED\n    def Functions::false(  )\n      false\n    end\n\n    # UNTESTED\n    def Functions::lang( language )\n      lang = false\n      node = @@context[:node]\n      attr = nil\n      until node.nil?\n        if node.node_type == :element\n          attr = node.attributes[\"xml:lang\"]\n          unless attr.nil?\n            lang = compare_language(string(language), attr)\n            break\n          else\n          end\n        end\n        node = node.parent\n      end\n      lang\n    end\n\n    def Functions::compare_language lang1, lang2\n      lang2.downcase.index(lang1.downcase) == 0\n    end\n\n    # a string that consists of optional whitespace followed by an optional\n    # minus sign followed by a Number followed by whitespace is converted to\n    # the IEEE 754 number that is nearest (according to the IEEE 754\n    # round-to-nearest rule) to the mathematical value represented by the\n    # string; any other string is converted to NaN\n    #\n    # boolean true is converted to 1; boolean false is converted to 0\n    #\n    # a node-set is first converted to a string as if by a call to the string\n    # function and then converted in the same way as a string argument\n    #\n    # an object of a type other than the four basic types is converted to a\n    # number in a way that is dependent on that type\n    def Functions::number( object=nil )\n      object = @@context[:node] unless object\n      case object\n      when true\n        Float(1)\n      when false\n        Float(0)\n      when Array\n        number(string( object ))\n      when Numeric\n        object.to_f\n      else\n        str = string( object )\n        # If XPath ever gets scientific notation...\n        #if str =~ /^\\s*-?(\\d*\\.?\\d+|\\d+\\.)([Ee]\\d*)?\\s*$/\n        if str =~ /^\\s*-?(\\d*\\.?\\d+|\\d+\\.)\\s*$/\n          str.to_f\n        else\n          (0.0 / 0.0)\n        end\n      end\n    end\n\n    def Functions::sum( nodes )\n      nodes = [nodes] unless nodes.kind_of? Array\n      nodes.inject(0) { |r,n| r += number(string(n)) }\n    end\n    \n    def Functions::floor( number )\n      number(number).floor\n    end\n\n    def Functions::ceiling( number )\n      number(number).ceil\n    end\n\n    def Functions::round( number )\n      begin\n        number(number).round\n      rescue FloatDomainError\n        number(number)\n      end\n    end\n\n    def Functions::processing_instruction( node )\n      node.node_type == :processing_instruction\n    end\n\n    def Functions::method_missing( id )\n      puts \"METHOD MISSING #{id.id2name}\"\n      XPath.match( @@context[:node], id.id2name )\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/instruction.rb",
    "content": "require \"rexml/child\"\nrequire \"rexml/source\"\n\nmodule REXML\n\t# Represents an XML Instruction; IE, <? ... ?>\n\t# TODO: Add parent arg (3rd arg) to constructor\n\tclass Instruction < Child\n\t\tSTART = '<\\?'\n\t\tSTOP = '\\?>'\n\n\t\t# target is the \"name\" of the Instruction; IE, the \"tag\" in <?tag ...?>\n\t\t# content is everything else.\n\t\tattr_accessor :target, :content\n\n\t\t# Constructs a new Instruction\n\t\t# @param target can be one of a number of things.  If String, then \n\t\t# the target of this instruction is set to this.  If an Instruction,\n\t\t# then the Instruction is shallowly cloned (target and content are\n\t\t# copied).  If a Source, then the source is scanned and parsed for\n\t\t# an Instruction declaration.\n\t\t# @param content Must be either a String, or a Parent.  Can only\n\t\t# be a Parent if the target argument is a Source.  Otherwise, this\n\t\t# String is set as the content of this instruction.\n\t\tdef initialize(target, content=nil)\n\t\t\tif target.kind_of? String\n\t\t\t\tsuper()\n\t\t\t\t@target = target\n\t\t\t\t@content = content\n\t\t\telsif target.kind_of? Instruction\n\t\t\t\tsuper(content)\n\t\t\t\t@target = target.target\n\t\t\t\t@content = target.content\n\t\t\tend\n\t\t\t@content.strip! if @content\n\t\tend\n\n\t\tdef clone\n\t\t\tInstruction.new self\n\t\tend\n\t\t\n    # == DEPRECATED\n    # See the rexml/formatters package\n    #\n\t\tdef write writer, indent=-1, transitive=false, ie_hack=false\n      Kernel.warn( \"#{self.class.name}.write is deprecated\" )\n\t\t\tindent(writer, indent)\n\t\t\twriter << START.sub(/\\\\/u, '')\n\t\t\twriter << @target\n\t\t\twriter << ' '\n\t\t\twriter << @content\n\t\t\twriter << STOP.sub(/\\\\/u, '')\n\t\tend\n\n\t\t# @return true if other is an Instruction, and the content and target\n\t\t# of the other matches the target and content of this object.\n\t\tdef ==( other )\n\t\t\tother.kind_of? Instruction and\n\t\t\tother.target == @target and\n\t\t\tother.content == @content\n\t\tend\n\n    def node_type\n      :processing_instruction\n    end\n\n    def inspect\n      \"<?p-i #{target} ...?>\"\n    end\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/light/node.rb",
    "content": "require 'rexml/xmltokens'\nrequire 'rexml/light/node'\n\n# [ :element, parent, name, attributes, children* ]\n\t# a = Node.new\n\t# a << \"B\"\t\t# => <a>B</a>\n\t# a.b\t\t\t# => <a>B<b/></a>\n\t# a.b[1]\t\t\t# => <a>B<b/><b/><a>\n\t# a.b[1][\"x\"] = \"y\"\t# => <a>B<b/><b x=\"y\"/></a>\n\t# a.b[0].c\t\t# => <a>B<b><c/></b><b x=\"y\"/></a>\n\t# a.b.c << \"D\"\t\t# => <a>B<b><c>D</c></b><b x=\"y\"/></a>\nmodule REXML\n\tmodule Light\n\t\t# Represents a tagged XML element.  Elements are characterized by\n\t\t# having children, attributes, and names, and can themselves be\n\t\t# children.\n\t\tclass Node\n\t\t\tNAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u\n\t\t\tPARENTS = [ :element, :document, :doctype ]\n\t\t\t# Create a new element.\n\t\t\tdef initialize node=nil\n\t\t\t\t@node = node\n\t\t\t\tif node.kind_of? String\n\t\t\t\t\tnode = [ :text, node ]\n\t\t\t\telsif node.nil?\n\t\t\t\t\tnode = [ :document, nil, nil ]\n\t\t\t\telsif node[0] == :start_element\n\t\t\t\t\tnode[0] = :element\n\t\t\t\telsif node[0] == :start_doctype\n\t\t\t\t\tnode[0] = :doctype\n\t\t\t\telsif node[0] == :start_document\n\t\t\t\t\tnode[0] = :document\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tdef size\n\t\t\t\tif PARENTS.include? @node[0]\n\t\t\t\t\t@node[-1].size\n\t\t\t\telse\n\t\t\t\t\t0\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tdef each( &block )\n\t\t\t\tsize.times { |x| yield( at(x+4) ) }\n\t\t\tend\n\n\t\t\tdef name\n\t\t\t\tat(2)\n\t\t\tend\n\n\t\t\tdef name=( name_str, ns=nil )\n\t\t\t\tpfx = ''\n\t\t\t\tpfx = \"#{prefix(ns)}:\" if ns\n\t\t\t\t_old_put(2, \"#{pfx}#{name_str}\")\n\t\t\tend\n\n\t\t\tdef parent=( node )\n\t\t\t\t_old_put(1,node)\n\t\t\tend\n\n\t\t\tdef local_name\n\t\t\t\tnamesplit\n\t\t\t\t@name\n\t\t\tend\n\n\t\t\tdef local_name=( name_str )\n\t\t\t\t_old_put( 1, \"#@prefix:#{name_str}\" )\n\t\t\tend\n\n\t\t\tdef prefix( namespace=nil )\n\t\t\t\tprefix_of( self, namespace )\n\t\t\tend\n\n\t\t\tdef namespace( prefix=prefix() )\n\t\t\t\tnamespace_of( self, prefix )\n\t\t\tend\n\n\t\t\tdef namespace=( namespace )\n\t\t\t\t@prefix = prefix( namespace )\n\t\t\t\tpfx = ''\n\t\t\t\tpfx = \"#@prefix:\" if @prefix.size > 0\n\t\t\t\t_old_put(1, \"#{pfx}#@name\")\n\t\t\tend\n\n\t\t\tdef []( reference, ns=nil )\n\t\t\t\tif reference.kind_of? String\n\t\t\t\t\tpfx = ''\n\t\t\t\t\tpfx = \"#{prefix(ns)}:\" if ns\n\t\t\t\t\tat(3)[\"#{pfx}#{reference}\"]\n\t\t\t\telsif reference.kind_of? Range\n\t\t\t\t\t_old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )\n\t\t\t\telse\n\t\t\t\t\t_old_get( 4+reference )\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tdef =~( path )\n\t\t\t\tXPath.match( self, path )\n\t\t\tend\n\n\t\t\t# Doesn't handle namespaces yet\n\t\t\tdef []=( reference, ns, value=nil )\n\t\t\t\tif reference.kind_of? String\n\t\t\t\t\tvalue = ns unless value\n\t\t\t\t\tat( 3 )[reference] = value\n\t\t\t\telsif reference.kind_of? Range\n\t\t\t\t\t_old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )\n\t\t\t\telse\n\t\t\t\t\tif value\n\t\t\t\t\t\t_old_put( 4+reference, ns, value )\n\t\t\t\t\telse\n\t\t\t\t\t\t_old_put( 4+reference, ns )\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\n\t\t\t# Append a child to this element, optionally under a provided namespace.\n\t\t\t# The namespace argument is ignored if the element argument is an Element\n\t\t\t# object.  Otherwise, the element argument is a string, the namespace (if\n\t\t\t# provided) is the namespace the element is created in.\n\t\t\tdef << element\n\t\t\t\tif node_type() == :text\n\t\t\t\t\tat(-1) << element\n\t\t\t\telse\n\t\t\t\t\tnewnode = Node.new( element )\n\t\t\t\t\tnewnode.parent = self\n\t\t\t\t\tself.push( newnode )\n\t\t\t\tend\n\t\t\t\tat(-1)\n\t\t\tend\n\n\t\t\tdef node_type\n\t\t\t\t_old_get(0)\n\t\t\tend\n\n\t\t\tdef text=( foo )\n\t\t\t\treplace = at(4).kind_of?(String)? 1 : 0\n\t\t\t\tself._old_put(4,replace, normalizefoo)\n\t\t\tend\n\n\t\t\tdef root\n\t\t\t\tcontext = self\n\t\t\t\tcontext = context.at(1) while context.at(1)\n\t\t\tend\n\n\t\t\tdef has_name?( name, namespace = '' )\n\t\t\t\tat(3) == name and namespace() == namespace\n\t\t\tend\n\n\t\t\tdef children\n\t\t\t\tself\n\t\t\tend\n\n\t\t\tdef parent\n\t\t\t\tat(1)\n\t\t\tend\n\n\t\t\tdef to_s\n\n\t\t\tend\n\n\t\t\tprivate\n\n\t\t\tdef namesplit\n\t\t\t\treturn if @name.defined?\n\t\t\t\tat(2) =~ NAMESPLIT\n\t\t\t\t@prefix = '' || $1\n\t\t\t\t@name = $2\n\t\t\tend\n\n\t\t\tdef namespace_of( node, prefix=nil )\n\t\t\t\tif not prefix\n\t\t\t\t\tname = at(2)\n\t\t\t\t\tname =~ NAMESPLIT\n\t\t\t\t\tprefix = $1\n\t\t\t\tend\n\t\t\t\tto_find = 'xmlns'\n\t\t\t\tto_find = \"xmlns:#{prefix}\" if not prefix.nil?\n\t\t\t\tns = at(3)[ to_find ]\n\t\t\t\tns ? ns : namespace_of( @node[0], prefix )\n\t\t\tend\n\n\t\t\tdef prefix_of( node, namespace=nil )\n\t\t\t\tif not namespace\n\t\t\t\t\tname = node.name\n\t\t\t\t\tname =~ NAMESPLIT\n\t\t\t\t\t$1\n\t\t\t\telse\n\t\t\t\t\tns = at(3).find { |k,v| v == namespace }\n\t\t\t\t\tns ? ns : prefix_of( node.parent, namespace )\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/namespace.rb",
    "content": "require 'rexml/xmltokens'\n\nmodule REXML\n\t# Adds named attributes to an object.\n\tmodule Namespace\n\t\t# The name of the object, valid if set\n\t\tattr_reader :name, :expanded_name\n\t\t# The expanded name of the object, valid if name is set\n\t\tattr_accessor :prefix\n\t\tinclude XMLTokens\n\t\tNAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u\n\n\t\t# Sets the name and the expanded name\n\t\tdef name=( name )\n\t\t\t@expanded_name = name\n\t\t\tname =~ NAMESPLIT\n\t\t\tif $1\n\t\t\t\t@prefix = $1\n\t\t\telse\n\t\t\t\t@prefix = \"\"\n\t\t\t\t@namespace = \"\"\n\t\t\tend\n\t\t\t@name = $2\n\t\tend\n\n\t\t# Compares names optionally WITH namespaces\n\t\tdef has_name?( other, ns=nil )\n\t\t\tif ns\n\t\t\t\treturn (namespace() == ns and name() == other)\n\t\t\telsif other.include? \":\"\n\t\t\t\treturn fully_expanded_name == other\n\t\t\telse\n\t\t\t\treturn name == other\n\t\t\tend\n\t\tend\n\n\t\talias :local_name :name\n\n\t\t# Fully expand the name, even if the prefix wasn't specified in the\n\t\t# source file.\n\t\tdef fully_expanded_name\n\t\t\tns = prefix\n\t\t\treturn \"#{ns}:#@name\" if ns.size > 0 \n\t\t\treturn @name\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/node.rb",
    "content": "require \"rexml/parseexception\"\nrequire \"rexml/formatters/pretty\"\nrequire \"rexml/formatters/default\"\n\nmodule REXML\n\t# Represents a node in the tree.  Nodes are never encountered except as\n\t# superclasses of other objects.  Nodes have siblings.\n\tmodule Node\n\t\t# @return the next sibling (nil if unset)\n\t\tdef next_sibling_node\n\t\t\treturn nil if @parent.nil?\n\t\t\t@parent[ @parent.index(self) + 1 ]\n\t\tend\n\n\t\t# @return the previous sibling (nil if unset)\n\t\tdef previous_sibling_node\n\t\t\treturn nil if @parent.nil?\n\t\t\tind = @parent.index(self)\n\t\t\treturn nil if ind == 0\n\t\t\t@parent[ ind - 1 ]\n\t\tend\n\n    # indent::\n    #   *DEPRECATED* This parameter is now ignored.  See the formatters in the\n    #   REXML::Formatters package for changing the output style.\n\t\tdef to_s indent=nil\n      unless indent.nil?\n        Kernel.warn( \"#{self.class.name}.to_s(indent) parameter is deprecated\" )\n        f = REXML::Formatters::Pretty.new( indent )\n        f.write( self, rv = \"\" )\n      else\n        f = REXML::Formatters::Default.new\n        f.write( self, rv = \"\" )\n      end\n      return rv\n\t\tend\n\n\t\tdef indent to, ind\n \t\t\tif @parent and @parent.context and not @parent.context[:indentstyle].nil? then\n \t\t\t\tindentstyle = @parent.context[:indentstyle]\n \t\t\telse\n \t\t\t\tindentstyle = '  '\n \t\t\tend\n \t\t\tto << indentstyle*ind unless ind<1\n\t\tend\n\n\t\tdef parent?\n\t\t\tfalse;\n\t\tend\n\n\n\t\t# Visit all subnodes of +self+ recursively\n\t\tdef each_recursive(&block) # :yields: node\n\t\t\tself.elements.each {|node|\n\t\t\t\tblock.call(node)\n\t\t\t\tnode.each_recursive(&block)\n\t\t\t}\n\t\tend\n\n\t\t# Find (and return) first subnode (recursively) for which the block \n    # evaluates to true. Returns +nil+ if none was found.\n\t\tdef find_first_recursive(&block) # :yields: node\n      each_recursive {|node|\n        return node if block.call(node)\n      }\n      return nil\n    end\n\n    # Returns the position that +self+ holds in its parent's array, indexed\n    # from 1.\n    def index_in_parent\n      parent.index(self)+1\n    end\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/output.rb",
    "content": "require 'rexml/encoding'\n\nmodule REXML\n\tclass Output\n\t\tinclude Encoding\n    \n    attr_reader :encoding\n\n\t\tdef initialize real_IO, encd=\"iso-8859-1\"\n\t\t\t@output = real_IO\n\t\t\tself.encoding = encd\n\n\t\t\t@to_utf = encd == UTF_8 ? false : true\n\t\tend\n\n\t\tdef <<( content )\n\t\t\t@output << (@to_utf ? self.encode(content) : content)\n\t\tend\n\n    def to_s\n      \"Output[#{encoding}]\"\n    end\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/parent.rb",
    "content": "require \"rexml/child\"\n\nmodule REXML\n  # A parent has children, and has methods for accessing them.  The Parent\n  # class is never encountered except as the superclass for some other\n  # object.\n  class Parent < Child\n    include Enumerable\n    \n    # Constructor\n    # @param parent if supplied, will be set as the parent of this object\n    def initialize parent=nil\n      super(parent)\n      @children = []\n    end\n    \n    def add( object )\n      #puts \"PARENT GOTS #{size} CHILDREN\"\n      object.parent = self\n      @children << object\n      #puts \"PARENT NOW GOTS #{size} CHILDREN\"\n      object\n    end\n    \n    alias :push :add\n    alias :<< :push\n    \n    def unshift( object )\n      object.parent = self\n      @children.unshift object\n    end\n    \n    def delete( object )\n      found = false\n      @children.delete_if {|c| c.equal?(object) and found = true }\n      object.parent = nil if found\n    end\n    \n    def each(&block)\n      @children.each(&block)\n    end\n    \n    def delete_if( &block )\n      @children.delete_if(&block)\n    end\n    \n    def delete_at( index )\n      @children.delete_at index\n    end\n    \n    def each_index( &block )\n      @children.each_index(&block)\n    end\n    \n    # Fetches a child at a given index\n    # @param index the Integer index of the child to fetch\n    def []( index )\n      @children[index]\n    end\n    \n    alias :each_child :each\n    \n    \n    \n    # Set an index entry.  See Array.[]=\n    # @param index the index of the element to set\n    # @param opt either the object to set, or an Integer length\n    # @param child if opt is an Integer, this is the child to set\n    # @return the parent (self)\n    def []=( *args )\n      args[-1].parent = self\n      @children[*args[0..-2]] = args[-1]\n    end\n    \n    # Inserts an child before another child\n    # @param child1 this is either an xpath or an Element.  If an Element,\n    # child2 will be inserted before child1 in the child list of the parent.\n    # If an xpath, child2 will be inserted before the first child to match\n    # the xpath.\n    # @param child2 the child to insert\n    # @return the parent (self)\n    def insert_before( child1, child2 )\n      if child1.kind_of? String\n        child1 = XPath.first( self, child1 )\n        child1.parent.insert_before child1, child2\n      else\n        ind = index(child1)\n        child2.parent.delete(child2) if child2.parent\n        @children[ind,0] = child2\n        child2.parent = self\n      end\n      self\n    end\n    \n    # Inserts an child after another child\n    # @param child1 this is either an xpath or an Element.  If an Element,\n    # child2 will be inserted after child1 in the child list of the parent.\n    # If an xpath, child2 will be inserted after the first child to match\n    # the xpath.\n    # @param child2 the child to insert\n    # @return the parent (self)\n    def insert_after( child1, child2 )\n      if child1.kind_of? String\n        child1 = XPath.first( self, child1 )\n        child1.parent.insert_after child1, child2\n      else\n        ind = index(child1)+1\n        child2.parent.delete(child2) if child2.parent\n        @children[ind,0] = child2\n        child2.parent = self\n      end\n      self\n    end\n    \n    def to_a\n      @children.dup\n    end\n    \n    # Fetches the index of a given child\n    # @param child the child to get the index of\n    # @return the index of the child, or nil if the object is not a child\n    # of this parent.\n    def index( child )\n      count = -1\n      @children.find { |i| count += 1 ; i.hash == child.hash }\n      count\n    end\n    \n    # @return the number of children of this parent\n    def size\n      @children.size\n    end\n    \n    alias :length :size\n    \n    # Replaces one child with another, making sure the nodelist is correct\n    # @param to_replace the child to replace (must be a Child)\n    # @param replacement the child to insert into the nodelist (must be a \n    # Child)\n    def replace_child( to_replace, replacement )\n      @children.map! {|c| c.equal?( to_replace ) ? replacement : c }\n      to_replace.parent = nil\n      replacement.parent = self\n    end\n    \n    # Deeply clones this object.  This creates a complete duplicate of this\n    # Parent, including all descendants.\n    def deep_clone\n      cl = clone()\n      each do |child|\n        if child.kind_of? Parent\n          cl << child.deep_clone\n        else\n          cl << child.clone\n        end\n      end\n      cl\n    end\n    \n    alias :children :to_a\n    \n    def parent?\n      true\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/parseexception.rb",
    "content": "module REXML\n  class ParseException < RuntimeError\n    attr_accessor :source, :parser, :continued_exception\n\n    def initialize( message, source=nil, parser=nil, exception=nil )\n      super(message)\n      @source = source\n      @parser = parser\n      @continued_exception = exception\n    end\n\n    def to_s\n      # Quote the original exception, if there was one\n      if @continued_exception\n        err = @continued_exception.inspect\n        err << \"\\n\"\n        err << @continued_exception.backtrace.join(\"\\n\")\n        err << \"\\n...\\n\"\n      else\n        err = \"\"\n      end\n\n      # Get the stack trace and error message\n      err << super\n\n      # Add contextual information\n      if @source\n        err << \"\\nLine: #{line}\\n\"\n        err << \"Position: #{position}\\n\"\n        err << \"Last 80 unconsumed characters:\\n\"\n        err << @source.buffer[0..80].gsub(/\\n/, ' ')\n      end\n      \n      err\n    end\n\n    def position\n      @source.current_line[0] if @source and defined? @source.current_line and\n      @source.current_line\n    end\n\n    def line\n      @source.current_line[2] if @source and defined? @source.current_line and \n      @source.current_line\n    end\n\n    def context\n      @source.current_line\n    end\n  end  \nend\n"
  },
  {
    "path": "lib/rexml/parsers/baseparser.rb",
    "content": "require 'rexml/parseexception'\nrequire 'rexml/undefinednamespaceexception'\nrequire 'rexml/source'\nrequire 'set'\n\nmodule REXML\n  module Parsers\n    # = Using the Pull Parser\n    # <em>This API is experimental, and subject to change.</em>\n    #  parser = PullParser.new( \"<a>text<b att='val'/>txet</a>\" )\n    #  while parser.has_next?\n    #    res = parser.next\n    #    puts res[1]['att'] if res.start_tag? and res[0] == 'b'\n    #  end\n    # See the PullEvent class for information on the content of the results.\n    # The data is identical to the arguments passed for the various events to\n    # the StreamListener API.\n    #\n    # Notice that:\n    #  parser = PullParser.new( \"<a>BAD DOCUMENT\" )\n    #  while parser.has_next?\n    #    res = parser.next\n    #    raise res[1] if res.error?\n    #  end\n    #\n    # Nat Price gave me some good ideas for the API.\n    class BaseParser\n      NCNAME_STR= '[\\w:][\\-\\w\\d.]*'\n      NAME_STR= \"(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})\"\n      UNAME_STR= \"(?:#{NCNAME_STR}:)?#{NCNAME_STR}\"\n\n      NAMECHAR = '[\\-\\w\\d\\.:]'\n      NAME = \"([\\\\w:]#{NAMECHAR}*)\"\n      NMTOKEN = \"(?:#{NAMECHAR})+\"\n      NMTOKENS = \"#{NMTOKEN}(\\\\s+#{NMTOKEN})*\"\n      REFERENCE = \"(?:&#{NAME};|&#\\\\d+;|&#x[0-9a-fA-F]+;)\"\n      REFERENCE_RE = /#{REFERENCE}/\n\n      DOCTYPE_START = /\\A\\s*<!DOCTYPE\\s/um\n      DOCTYPE_PATTERN = /\\s*<!DOCTYPE\\s+(.*?)(\\[|>)/um\n      ATTRIBUTE_PATTERN = /\\s*(#{NAME_STR})\\s*=\\s*([\"'])(.*?)\\4/um\n      COMMENT_START = /\\A<!--/u\n      COMMENT_PATTERN = /<!--(.*?)-->/um\n      CDATA_START = /\\A<!\\[CDATA\\[/u\n      CDATA_END = /^\\s*\\]\\s*>/um\n      CDATA_PATTERN = /<!\\[CDATA\\[(.*?)\\]\\]>/um\n      XMLDECL_START = /\\A<\\?xml\\s/u;\n      XMLDECL_PATTERN = /<\\?xml\\s+(.*?)\\?>/um\n      INSTRUCTION_START = /\\A<\\?/u\n      INSTRUCTION_PATTERN = /<\\?(.*?)(\\s+.*?)?\\?>/um\n      TAG_MATCH = /^<((?>#{NAME_STR}))\\s*((?>\\s+#{UNAME_STR}\\s*=\\s*([\"']).*?\\5)*)\\s*(\\/)?>/um\n      CLOSE_MATCH = /^\\s*<\\/(#{NAME_STR})\\s*>/um\n\n      VERSION = /\\bversion\\s*=\\s*[\"'](.*?)['\"]/um\n      ENCODING = /\\bencoding\\s*=\\s*[\"'](.*?)['\"]/um\n      STANDALONE = /\\bstandalone\\s*=\\s[\"'](.*?)['\"]/um\n\n      ENTITY_START = /^\\s*<!ENTITY/\n      IDENTITY = /^([!\\*\\w\\-]+)(\\s+#{NCNAME_STR})?(\\s+[\"'](.*?)['\"])?(\\s+['\"](.*?)[\"'])?/u\n      ELEMENTDECL_START = /^\\s*<!ELEMENT/um\n      ELEMENTDECL_PATTERN = /^\\s*(<!ELEMENT.*?)>/um\n      SYSTEMENTITY = /^\\s*(%.*?;)\\s*$/um\n      ENUMERATION = \"\\\\(\\\\s*#{NMTOKEN}(?:\\\\s*\\\\|\\\\s*#{NMTOKEN})*\\\\s*\\\\)\"\n      NOTATIONTYPE = \"NOTATION\\\\s+\\\\(\\\\s*#{NAME}(?:\\\\s*\\\\|\\\\s*#{NAME})*\\\\s*\\\\)\"\n      ENUMERATEDTYPE = \"(?:(?:#{NOTATIONTYPE})|(?:#{ENUMERATION}))\"\n      ATTTYPE = \"(CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS|#{ENUMERATEDTYPE})\"\n      ATTVALUE = \"(?:\\\"((?:[^<&\\\"]|#{REFERENCE})*)\\\")|(?:'((?:[^<&']|#{REFERENCE})*)')\"\n      DEFAULTDECL = \"(#REQUIRED|#IMPLIED|(?:(#FIXED\\\\s+)?#{ATTVALUE}))\"\n      ATTDEF = \"\\\\s+#{NAME}\\\\s+#{ATTTYPE}\\\\s+#{DEFAULTDECL}\"\n      ATTDEF_RE = /#{ATTDEF}/\n      ATTLISTDECL_START = /^\\s*<!ATTLIST/um\n      ATTLISTDECL_PATTERN = /^\\s*<!ATTLIST\\s+#{NAME}(?:#{ATTDEF})*\\s*>/um\n      NOTATIONDECL_START = /^\\s*<!NOTATION/um\n      PUBLIC = /^\\s*<!NOTATION\\s+(\\w[\\-\\w]*)\\s+(PUBLIC)\\s+([\"'])(.*?)\\3(?:\\s+([\"'])(.*?)\\5)?\\s*>/um\n      SYSTEM = /^\\s*<!NOTATION\\s+(\\w[\\-\\w]*)\\s+(SYSTEM)\\s+([\"'])(.*?)\\3\\s*>/um\n\n      TEXT_PATTERN = /\\A([^<]*)/um\n\n      # Entity constants\n      PUBIDCHAR = \"\\x20\\x0D\\x0Aa-zA-Z0-9\\\\-()+,./:=?;!*@$_%#\"\n      SYSTEMLITERAL = %Q{((?:\"[^\"]*\")|(?:'[^']*'))}\n      PUBIDLITERAL = %Q{(\"[#{PUBIDCHAR}']*\"|'[#{PUBIDCHAR}]*')}\n      EXTERNALID = \"(?:(?:(SYSTEM)\\\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\\\s+#{PUBIDLITERAL}\\\\s+#{SYSTEMLITERAL}))\"\n      NDATADECL = \"\\\\s+NDATA\\\\s+#{NAME}\"\n      PEREFERENCE = \"%#{NAME};\"\n      ENTITYVALUE = %Q{((?:\"(?:[^%&\"]|#{PEREFERENCE}|#{REFERENCE})*\")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}\n      PEDEF = \"(?:#{ENTITYVALUE}|#{EXTERNALID})\"\n      ENTITYDEF = \"(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))\"\n      PEDECL = \"<!ENTITY\\\\s+(%)\\\\s+#{NAME}\\\\s+#{PEDEF}\\\\s*>\"\n      GEDECL = \"<!ENTITY\\\\s+#{NAME}\\\\s+#{ENTITYDEF}\\\\s*>\"\n      ENTITYDECL = /\\s*(?:#{GEDECL})|(?:#{PEDECL})/um\n\n      EREFERENCE = /&(?!#{NAME};)/\n\n      DEFAULT_ENTITIES = { \n        'gt' => [/&gt;/, '&gt;', '>', />/], \n        'lt' => [/&lt;/, '&lt;', '<', /</], \n        'quot' => [/&quot;/, '&quot;', '\"', /\"/], \n        \"apos\" => [/&apos;/, \"&apos;\", \"'\", /'/] \n      }\n\n\n      ######################################################################\n      # These are patterns to identify common markup errors, to make the\n      # error messages more informative.\n      ######################################################################\n      MISSING_ATTRIBUTE_QUOTES = /^<#{NAME_STR}\\s+#{NAME_STR}\\s*=\\s*[^\"']/um\n\n      def initialize( source )\n        self.stream = source\n      end\n\n      def add_listener( listener )\n        if !defined?(@listeners) or !@listeners\n          @listeners = []\n          instance_eval <<-EOL\n            alias :_old_pull :pull\n            def pull\n              event = _old_pull\n              @listeners.each do |listener|\n                listener.receive event\n              end\n              event\n            end\n          EOL\n        end\n        @listeners << listener\n      end\n\n      attr_reader :source\n\n      def stream=( source )\n        @source = SourceFactory.create_from( source )\n        @closed = nil\n        @document_status = nil\n        @tags = []\n        @stack = []\n        @entities = []\n        @nsstack = []\n      end\n\n      def position\n        if @source.respond_to? :position\n          @source.position\n        else\n          # FIXME\n          0\n        end\n      end\n\n      # Returns true if there are no more events\n      def empty?\n        return (@source.empty? and @stack.empty?)\n      end\n\n      # Returns true if there are more events.  Synonymous with !empty?\n      def has_next?\n        return !(@source.empty? and @stack.empty?)\n      end\n\n      # Push an event back on the head of the stream.  This method\n      # has (theoretically) infinite depth.\n      def unshift token\n        @stack.unshift(token)\n      end\n\n      # Peek at the +depth+ event in the stack.  The first element on the stack\n      # is at depth 0.  If +depth+ is -1, will parse to the end of the input\n      # stream and return the last event, which is always :end_document.\n      # Be aware that this causes the stream to be parsed up to the +depth+ \n      # event, so you can effectively pre-parse the entire document (pull the \n      # entire thing into memory) using this method.  \n      def peek depth=0\n        raise %Q[Illegal argument \"#{depth}\"] if depth < -1\n        temp = []\n        if depth == -1\n          temp.push(pull()) until empty?\n        else\n          while @stack.size+temp.size < depth+1\n            temp.push(pull())\n          end\n        end\n        @stack += temp if temp.size > 0\n        @stack[depth]\n      end\n\n      # Returns the next event.  This is a +PullEvent+ object.\n      def pull\n        if @closed\n          x, @closed = @closed, nil\n          return [ :end_element, x ]\n        end\n        return [ :end_document ] if empty?\n        return @stack.shift if @stack.size > 0\n        #STDERR.puts @source.encoding\n        @source.read if @source.buffer.size<2\n        #STDERR.puts \"BUFFER = #{@source.buffer.inspect}\"\n        if @document_status == nil\n          #@source.consume( /^\\s*/um )\n          word = @source.match( /^((?:\\s+)|(?:<[^>]*>))/um )\n          word = word[1] unless word.nil?\n          #STDERR.puts \"WORD = #{word.inspect}\"\n          case word\n          when COMMENT_START\n            return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ]\n          when XMLDECL_START\n            #STDERR.puts \"XMLDECL\"\n            results = @source.match( XMLDECL_PATTERN, true )[1]\n            version = VERSION.match( results )\n            version = version[1] unless version.nil?\n            encoding = ENCODING.match(results)\n            encoding = encoding[1] unless encoding.nil?\n            @source.encoding = encoding\n            standalone = STANDALONE.match(results)\n            standalone = standalone[1] unless standalone.nil?\n            return [ :xmldecl, version, encoding, standalone ]\n          when INSTRUCTION_START\n            return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]\n          when DOCTYPE_START\n            md = @source.match( DOCTYPE_PATTERN, true )\n            @nsstack.unshift(curr_ns=Set.new)\n            identity = md[1]\n            close = md[2]\n            identity =~ IDENTITY\n            name = $1\n            raise REXML::ParseException.new(\"DOCTYPE is missing a name\") if name.nil?\n            pub_sys = $2.nil? ? nil : $2.strip\n            long_name = $4.nil? ? nil : $4.strip\n            uri = $6.nil? ? nil : $6.strip\n            args = [ :start_doctype, name, pub_sys, long_name, uri ]\n            if close == \">\"\n              @document_status = :after_doctype\n              @source.read if @source.buffer.size<2\n              md = @source.match(/^\\s*/um, true)\n              @stack << [ :end_doctype ]\n            else\n              @document_status = :in_doctype\n            end\n            return args\n          when /^\\s+/\n          else\n            @document_status = :after_doctype\n            @source.read if @source.buffer.size<2\n            md = @source.match(/\\s*/um, true)\n          end\n        end\n        if @document_status == :in_doctype\n          md = @source.match(/\\s*(.*?>)/um)\n          case md[1]\n          when SYSTEMENTITY \n            match = @source.match( SYSTEMENTITY, true )[1]\n            return [ :externalentity, match ]\n\n          when ELEMENTDECL_START\n            return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]\n\n          when ENTITY_START\n            match = @source.match( ENTITYDECL, true ).to_a.compact\n            match[0] = :entitydecl\n            ref = false\n            if match[1] == '%'\n              ref = true\n              match.delete_at 1\n            end\n            # Now we have to sort out what kind of entity reference this is\n            if match[2] == 'SYSTEM'\n              # External reference\n              match[3] = match[3][1..-2] # PUBID\n              match.delete_at(4) if match.size > 4 # Chop out NDATA decl\n              # match is [ :entity, name, SYSTEM, pubid(, ndata)? ]\n            elsif match[2] == 'PUBLIC'\n              # External reference\n              match[3] = match[3][1..-2] # PUBID\n              match[4] = match[4][1..-2] # HREF\n              # match is [ :entity, name, PUBLIC, pubid, href ]\n            else\n              match[2] = match[2][1..-2]\n              match.pop if match.size == 4\n              # match is [ :entity, name, value ]\n            end\n            match << '%' if ref\n            return match\n          when ATTLISTDECL_START\n            md = @source.match( ATTLISTDECL_PATTERN, true )\n            raise REXML::ParseException.new( \"Bad ATTLIST declaration!\", @source ) if md.nil?\n            element = md[1]\n            contents = md[0]\n\n            pairs = {}\n            values = md[0].scan( ATTDEF_RE )\n            values.each do |attdef|\n              unless attdef[3] == \"#IMPLIED\"\n                attdef.compact!\n                val = attdef[3]\n                val = attdef[4] if val == \"#FIXED \"\n                pairs[attdef[0]] = val\n                if attdef[0] =~ /^xmlns:(.*)/\n                  @nsstack[0] << $1\n                end\n              end\n            end\n            return [ :attlistdecl, element, pairs, contents ]\n          when NOTATIONDECL_START\n            md = nil\n            if @source.match( PUBLIC )\n              md = @source.match( PUBLIC, true )\n              vals = [md[1],md[2],md[4],md[6]]\n            elsif @source.match( SYSTEM )\n              md = @source.match( SYSTEM, true )\n              vals = [md[1],md[2],nil,md[4]]\n            else\n              raise REXML::ParseException.new( \"error parsing notation: no matching pattern\", @source )\n            end\n            return [ :notationdecl, *vals ]\n          when CDATA_END\n            @document_status = :after_doctype\n            @source.match( CDATA_END, true )\n            return [ :end_doctype ]\n          end\n        end\n        begin\n          if @source.buffer[0] == ?<\n            if @source.buffer[1] == ?/\n              @nsstack.shift\n              last_tag = @tags.pop\n              #md = @source.match_to_consume( '>', CLOSE_MATCH)\n              md = @source.match( CLOSE_MATCH, true )\n              raise REXML::ParseException.new( \"Missing end tag for \"+\n                \"'#{last_tag}' (got \\\"#{md[1]}\\\")\", \n                @source) unless last_tag == md[1]\n              return [ :end_element, last_tag ]\n            elsif @source.buffer[1] == ?!\n              md = @source.match(/\\A(\\s*[^>]*>)/um)\n              #STDERR.puts \"SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}\"\n              raise REXML::ParseException.new(\"Malformed node\", @source) unless md\n              if md[0][2] == ?-\n                md = @source.match( COMMENT_PATTERN, true )\n                return [ :comment, md[1] ] if md\n              else\n                md = @source.match( CDATA_PATTERN, true )\n                return [ :cdata, md[1] ] if md\n              end\n              raise REXML::ParseException.new( \"Declarations can only occur \"+\n                \"in the doctype declaration.\", @source)\n            elsif @source.buffer[1] == ??\n              md = @source.match( INSTRUCTION_PATTERN, true )\n              return [ :processing_instruction, md[1], md[2] ] if md\n              raise REXML::ParseException.new( \"Bad instruction declaration\",\n                @source)\n            else\n              # Get the next tag\n              md = @source.match(TAG_MATCH, true)\n              unless md\n                # Check for missing attribute quotes\n                raise REXML::ParseException.new(\"missing attribute quote\", @source) if @source.match(MISSING_ATTRIBUTE_QUOTES )\n                raise REXML::ParseException.new(\"malformed XML: missing tag start\", @source) \n              end\n              attributes = {}\n              prefixes = Set.new\n              prefixes << md[2] if md[2]\n              @nsstack.unshift(curr_ns=Set.new)\n              if md[4].size > 0\n                attrs = md[4].scan( ATTRIBUTE_PATTERN )\n                raise REXML::ParseException.new( \"error parsing attributes: [#{attrs.join ', '}], excess = \\\"#$'\\\"\", @source) if $' and $'.strip.size > 0\n                attrs.each { |a,b,c,d,e| \n                  if b == \"xmlns\"\n                    if c == \"xml\"\n                      if d != \"http://www.w3.org/XML/1998/namespace\"\n                        msg = \"The 'xml' prefix must not be bound to any other namespace \"+\n                        \"(http://www.w3.org/TR/REC-xml-names/#ns-decl)\"\n                        raise REXML::ParseException.new( msg, @source, self )\n                      end\n                    elsif c == \"xmlns\"\n                      msg = \"The 'xmlns' prefix must not be declared \"+\n                      \"(http://www.w3.org/TR/REC-xml-names/#ns-decl)\"\n                      raise REXML::ParseException.new( msg, @source, self)\n                    end\n                    curr_ns << c\n                  elsif b\n                    prefixes << b unless b == \"xml\"\n                  end\n                  attributes[a] = e \n                }\n              end\n        \n              # Verify that all of the prefixes have been defined\n              for prefix in prefixes\n                unless @nsstack.find{|k| k.member?(prefix)}\n                  raise UndefinedNamespaceException.new(prefix,@source,self)\n                end\n              end\n\n              if md[6]\n                @closed = md[1]\n                @nsstack.shift\n              else\n                @tags.push( md[1] )\n              end\n              return [ :start_element, md[1], attributes ]\n            end\n          else\n            md = @source.match( TEXT_PATTERN, true )\n            if md[0].length == 0\n              @source.match( /(\\s+)/, true )\n            end\n            #STDERR.puts \"GOT #{md[1].inspect}\" unless md[0].length == 0\n            #return [ :text, \"\" ] if md[0].length == 0\n            # unnormalized = Text::unnormalize( md[1], self )\n            # return PullEvent.new( :text, md[1], unnormalized )\n            return [ :text, md[1] ]\n          end\n        rescue REXML::UndefinedNamespaceException\n          raise\n        rescue REXML::ParseException\n          raise\n        rescue Exception, NameError => error\n          raise REXML::ParseException.new( \"Exception parsing\",\n            @source, self, (error ? error : $!) )\n        end\n        return [ :dummy ]\n      end\n\n      def entity( reference, entities )\n        value = nil\n        value = entities[ reference ] if entities\n        if not value\n          value = DEFAULT_ENTITIES[ reference ]\n          value = value[2] if value\n        end\n        unnormalize( value, entities ) if value\n      end\n\n      # Escapes all possible entities\n      def normalize( input, entities=nil, entity_filter=nil )\n        copy = input.clone\n        # Doing it like this rather than in a loop improves the speed\n        copy.gsub!( EREFERENCE, '&amp;' )\n        entities.each do |key, value|\n          copy.gsub!( value, \"&#{key};\" ) unless entity_filter and \n                                      entity_filter.include?(entity)\n        end if entities\n        copy.gsub!( EREFERENCE, '&amp;' )\n        DEFAULT_ENTITIES.each do |key, value|\n          copy.gsub!( value[3], value[1] )\n        end\n        copy\n      end\n\n      # Unescapes all possible entities\n      def unnormalize( string, entities=nil, filter=nil )\n        rv = string.clone\n        rv.gsub!( /\\r\\n?/, \"\\n\" )\n        matches = rv.scan( REFERENCE_RE )\n        return rv if matches.size == 0\n        rv.gsub!( /&#0*((?:\\d+)|(?:x[a-fA-F0-9]+));/ ) {|m|\n          m=$1\n          m = \"0#{m}\" if m[0] == ?x\n          [Integer(m)].pack('U*')\n        }\n        matches.collect!{|x|x[0]}.compact!\n        if matches.size > 0\n          matches.each do |entity_reference|\n            unless filter and filter.include?(entity_reference)\n              entity_value = entity( entity_reference, entities )\n              if entity_value\n                re = /&#{entity_reference};/\n                rv.gsub!( re, entity_value )\n              end\n            end\n          end\n          matches.each do |entity_reference|\n            unless filter and filter.include?(entity_reference)\n              er = DEFAULT_ENTITIES[entity_reference]\n              rv.gsub!( er[0], er[2] ) if er\n            end\n          end\n          rv.gsub!( /&amp;/, '&' )\n        end\n        rv\n      end\n    end\n  end\nend\n\n=begin\n  case event[0]\n  when :start_element\n  when :text\n  when :end_element\n  when :processing_instruction\n  when :cdata\n  when :comment\n  when :xmldecl\n  when :start_doctype\n  when :end_doctype\n  when :externalentity\n  when :elementdecl\n  when :entity\n  when :attlistdecl\n  when :notationdecl\n  when :end_doctype\n  end\n=end\n"
  },
  {
    "path": "lib/rexml/parsers/lightparser.rb",
    "content": "require 'rexml/parsers/streamparser'\nrequire 'rexml/parsers/baseparser'\nrequire 'rexml/light/node'\n\nmodule REXML\n\tmodule Parsers\n\t\tclass LightParser\n\t\t\tdef initialize stream\n\t\t\t\t@stream = stream\n\t\t\t\t@parser = REXML::Parsers::BaseParser.new( stream )\n\t\t\tend\n\n      def add_listener( listener )\n        @parser.add_listener( listener )\n      end\n\n      def rewind\n        @stream.rewind\n        @parser.stream = @stream\n      end\n\n\t\t\tdef parse\n\t\t\t\troot = context = [ :document ]\n\t\t\t\twhile true\n\t\t\t\t\tevent = @parser.pull\n\t\t\t\t\tcase event[0]\n\t\t\t\t\twhen :end_document\n\t\t\t\t\t\tbreak\n\t\t\t\t\twhen :end_doctype\n\t\t\t\t\t\tcontext = context[1]\n\t\t\t\t\twhen :start_element, :start_doctype\n\t\t\t\t\t\tnew_node = event\n\t\t\t\t\t\tcontext << new_node\n\t\t\t\t\t\tnew_node[1,0] = [context]\n\t\t\t\t\t\tcontext = new_node\n\t\t\t\t\twhen :end_element, :end_doctype\n\t\t\t\t\t\tcontext = context[1]\n\t\t\t\t\telse\n\t\t\t\t\t\tnew_node = event\n\t\t\t\t\t\tcontext << new_node\n\t\t\t\t\t\tnew_node[1,0] = [context]\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\troot\n\t\t\tend\n\t\tend\n\n\t\t# An element is an array.  The array contains:\n\t\t#  0\t\t\tThe parent element\n\t\t#  1\t\t\tThe tag name\n\t\t#  2\t\t\tA hash of attributes\n\t\t#  3..-1\tThe child elements\n\t\t# An element is an array of size > 3\n\t\t# Text is a String\n\t\t# PIs are [ :processing_instruction, target, data ]\n\t\t# Comments are [ :comment, data ]\n\t\t# DocTypes are DocType structs\n\t\t# The root is an array with XMLDecls, Text, DocType, Array, Text\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/parsers/pullparser.rb",
    "content": "require 'forwardable'\n\nrequire 'rexml/parseexception'\nrequire 'rexml/parsers/baseparser'\nrequire 'rexml/xmltokens'\n\nmodule REXML\n  module Parsers\n    # = Using the Pull Parser\n    # <em>This API is experimental, and subject to change.</em>\n    #  parser = PullParser.new( \"<a>text<b att='val'/>txet</a>\" )\n    #  while parser.has_next?\n    #    res = parser.next\n    #    puts res[1]['att'] if res.start_tag? and res[0] == 'b'\n    #  end\n    # See the PullEvent class for information on the content of the results.\n    # The data is identical to the arguments passed for the various events to\n    # the StreamListener API.\n    #\n    # Notice that:\n    #  parser = PullParser.new( \"<a>BAD DOCUMENT\" )\n    #  while parser.has_next?\n    #    res = parser.next\n    #    raise res[1] if res.error?\n    #  end\n    #\n    # Nat Price gave me some good ideas for the API.\n    class PullParser\n      include XMLTokens\n      extend Forwardable\n\n      def_delegators( :@parser, :has_next? )\n      def_delegators( :@parser, :entity )\n      def_delegators( :@parser, :empty? )\n      def_delegators( :@parser, :source )\n\n      def initialize stream\n        @entities = {}\n        @listeners = nil\n        @parser = BaseParser.new( stream )\n        @my_stack = []\n      end\n\n      def add_listener( listener )\n        @listeners = [] unless @listeners\n        @listeners << listener\n      end\n\n      def each\n        while has_next?\n          yield self.pull\n        end\n      end\n\n      def peek depth=0\n        if @my_stack.length <= depth\n          (depth - @my_stack.length + 1).times {\n            e = PullEvent.new(@parser.pull)\n            @my_stack.push(e)\n          }\n        end\n        @my_stack[depth]\n      end\n\n      def pull\n        return @my_stack.shift if @my_stack.length > 0\n\n        event = @parser.pull\n        case event[0]\n        when :entitydecl\n          @entities[ event[1] ] = \n            event[2] unless event[2] =~ /PUBLIC|SYSTEM/\n        when :text\n          unnormalized = @parser.unnormalize( event[1], @entities )\n          event << unnormalized\n        end\n        PullEvent.new( event )\n      end\n\n      def unshift token\n        @my_stack.unshift token\n      end\n    end\n\n    # A parsing event.  The contents of the event are accessed as an +Array?,\n    # and the type is given either by the ...? methods, or by accessing the\n    # +type+ accessor.  The contents of this object vary from event to event,\n    # but are identical to the arguments passed to +StreamListener+s for each\n    # event.\n    class PullEvent\n      # The type of this event.  Will be one of :tag_start, :tag_end, :text,\n      # :processing_instruction, :comment, :doctype, :attlistdecl, :entitydecl,\n      # :notationdecl, :entity, :cdata, :xmldecl, or :error.\n      def initialize(arg)\n        @contents = arg\n      end\n\n      def []( start, endd=nil)\n        if start.kind_of? Range\n          @contents.slice( start.begin+1 .. start.end )\n        elsif start.kind_of? Numeric\n          if endd.nil?\n            @contents.slice( start+1 )\n          else\n            @contents.slice( start+1, endd )\n          end\n        else\n          raise \"Illegal argument #{start.inspect} (#{start.class})\"\n        end\n      end\n\n      def event_type\n        @contents[0]\n      end\n\n      # Content: [ String tag_name, Hash attributes ]\n      def start_element?\n        @contents[0] == :start_element\n      end\n\n      # Content: [ String tag_name ]\n      def end_element?\n        @contents[0] == :end_element\n      end\n\n      # Content: [ String raw_text, String unnormalized_text ]\n      def text?\n        @contents[0] == :text\n      end\n\n      # Content: [ String text ]\n      def instruction?\n        @contents[0] == :processing_instruction\n      end\n\n      # Content: [ String text ]\n      def comment?\n        @contents[0] == :comment\n      end\n\n      # Content: [ String name, String pub_sys, String long_name, String uri ]\n      def doctype?\n        @contents[0] == :start_doctype\n      end\n\n      # Content: [ String text ]\n      def attlistdecl?\n        @contents[0] == :attlistdecl\n      end\n\n      # Content: [ String text ]\n      def elementdecl?\n        @contents[0] == :elementdecl\n      end\n\n      # Due to the wonders of DTDs, an entity declaration can be just about\n      # anything.  There's no way to normalize it; you'll have to interpret the\n      # content yourself.  However, the following is true:\n      #\n      # * If the entity declaration is an internal entity:\n      #   [ String name, String value ]\n      # Content: [ String text ]\n      def entitydecl?\n        @contents[0] == :entitydecl\n      end\n\n      # Content: [ String text ]\n      def notationdecl?\n        @contents[0] == :notationdecl\n      end\n\n      # Content: [ String text ]\n      def entity?\n        @contents[0] == :entity\n      end\n\n      # Content: [ String text ]\n      def cdata?\n        @contents[0] == :cdata\n      end\n\n      # Content: [ String version, String encoding, String standalone ]\n      def xmldecl?\n        @contents[0] == :xmldecl\n      end\n\n      def error?\n        @contents[0] == :error\n      end\n\n      def inspect\n        @contents[0].to_s + \": \" + @contents[1..-1].inspect\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/parsers/sax2parser.rb",
    "content": "require 'rexml/parsers/baseparser'\nrequire 'rexml/parseexception'\nrequire 'rexml/namespace'\nrequire 'rexml/text'\n\nmodule REXML\n\tmodule Parsers\n    # SAX2Parser\n\t\tclass SAX2Parser\n\t\t\tdef initialize source\n\t\t\t\t@parser = BaseParser.new(source)\n\t\t\t\t@listeners = []\n\t\t\t\t@procs = []\n\t\t\t\t@namespace_stack = []\n\t\t\t\t@has_listeners = false\n\t\t\t\t@tag_stack = []\n        @entities = {}\n\t\t\tend\n\n      def source\n        @parser.source\n      end\n\t\t\t\n      def add_listener( listener )\n        @parser.add_listener( listener )\n      end\n\n\t\t\t# Listen arguments:\n\t\t\t#\n\t\t\t# Symbol, Array, Block\n\t\t\t# \tListen to Symbol events on Array elements\n\t\t\t# Symbol, Block\n\t\t\t#   Listen to Symbol events\n\t\t\t# Array, Listener\n\t\t\t# \tListen to all events on Array elements\n\t\t\t# Array, Block\n\t\t\t# \tListen to :start_element events on Array elements\n\t\t\t# Listener\n\t\t\t# \tListen to All events\n\t\t\t#\n\t\t\t# Symbol can be one of: :start_element, :end_element,\n\t\t\t# :start_prefix_mapping, :end_prefix_mapping, :characters,\n\t\t\t# :processing_instruction, :doctype, :attlistdecl, :elementdecl,\n\t\t\t# :entitydecl, :notationdecl, :cdata, :xmldecl, :comment\n      #\n      # There is an additional symbol that can be listened for: :progress.\n      # This will be called for every event generated, passing in the current \n      # stream position.\n\t\t\t#\n\t\t\t# Array contains regular expressions or strings which will be matched\n\t\t\t# against fully qualified element names.\n\t\t\t#\n\t\t\t# Listener must implement the methods in SAX2Listener\n\t\t\t#\n\t\t\t# Block will be passed the same arguments as a SAX2Listener method would\n\t\t\t# be, where the method name is the same as the matched Symbol.\n\t\t\t# See the SAX2Listener for more information.\n\t\t\tdef listen( *args, &blok )\n\t\t\t\tif args[0].kind_of? Symbol\n\t\t\t\t\tif args.size == 2\n\t\t\t\t\t\targs[1].each { |match| @procs << [args[0], match, blok] }\n\t\t\t\t\telse\n\t\t\t\t\t\tadd( [args[0], nil, blok] )\n\t\t\t\t\tend\n\t\t\t\telsif args[0].kind_of? Array\n\t\t\t\t\tif args.size == 2\n\t\t\t\t\t\targs[0].each { |match| add( [nil, match, args[1]] ) }\n\t\t\t\t\telse\n\t\t\t\t\t\targs[0].each { |match| add( [ :start_element, match, blok ] ) }\n\t\t\t\t\tend\n\t\t\t\telse\n\t\t\t\t\tadd([nil, nil, args[0]])\n\t\t\t\tend\n\t\t\tend\n\t\t\t\n\t\t\tdef deafen( listener=nil, &blok )\n\t\t\t\tif listener\n\t\t\t\t\t@listeners.delete_if {|item| item[-1] == listener }\n\t\t\t\t\t@has_listeners = false if @listeners.size == 0\n\t\t\t\telse\n\t\t\t\t\t@procs.delete_if {|item| item[-1] == blok }\n\t\t\t\tend\n\t\t\tend\n\t\t\t\n\t\t\tdef parse\n\t\t\t\t@procs.each { |sym,match,block| block.call if sym == :start_document }\n\t\t\t\t@listeners.each { |sym,match,block| \n\t\t\t\t\tblock.start_document if sym == :start_document or sym.nil?\n\t\t\t\t}\n\t\t\t\troot = context = []\n\t\t\t\twhile true\n\t\t\t\t\tevent = @parser.pull\n\t\t\t\t\tcase event[0]\n\t\t\t\t\twhen :end_document\n\t\t\t\t\t\thandle( :end_document )\n\t\t\t\t\t\tbreak\n          when :start_doctype\n            handle( :doctype, *event[1..-1])\n\t\t\t\t\twhen :end_doctype\n\t\t\t\t\t\tcontext = context[1]\n\t\t\t\t\twhen :start_element\n\t\t\t\t\t\t@tag_stack.push(event[1])\n\t\t\t\t\t\t# find the observers for namespaces\n\t\t\t\t\t\tprocs = get_procs( :start_prefix_mapping, event[1] )\n\t\t\t\t\t\tlisteners = get_listeners( :start_prefix_mapping, event[1] )\n\t\t\t\t\t\tif procs or listeners\n\t\t\t\t\t\t\t# break out the namespace declarations\n\t\t\t\t\t\t\t# The attributes live in event[2]\n\t\t\t\t\t\t\tevent[2].each {|n, v| event[2][n] = @parser.normalize(v)}\n\t\t\t\t\t\t\tnsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }\n\t\t\t\t\t\t\tnsdecl.collect! { |n, value| [ n[6..-1], value ] }\n\t\t\t\t\t\t\t@namespace_stack.push({})\n\t\t\t\t\t\t\tnsdecl.each do |n,v|\n\t\t\t\t\t\t\t\t@namespace_stack[-1][n] = v\n\t\t\t\t\t\t\t\t# notify observers of namespaces\n\t\t\t\t\t\t\t\tprocs.each { |ob| ob.call( n, v ) } if procs\n\t\t\t\t\t\t\t\tlisteners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\t\tevent[1] =~ Namespace::NAMESPLIT\n\t\t\t\t\t\tprefix = $1\n\t\t\t\t\t\tlocal = $2\n\t\t\t\t\t\turi = get_namespace(prefix)\n\t\t\t\t\t\t# find the observers for start_element\n\t\t\t\t\t\tprocs = get_procs( :start_element, event[1] )\n\t\t\t\t\t\tlisteners = get_listeners( :start_element, event[1] )\n\t\t\t\t\t\t# notify observers\n\t\t\t\t\t\tprocs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs\n\t\t\t\t\t\tlisteners.each { |ob| \n\t\t\t\t\t\t\tob.start_element( uri, local, event[1], event[2] ) \n\t\t\t\t\t\t} if listeners\n\t\t\t\t\twhen :end_element\n\t\t\t\t\t\t@tag_stack.pop\n\t\t\t\t\t\tevent[1] =~ Namespace::NAMESPLIT\n\t\t\t\t\t\tprefix = $1\n\t\t\t\t\t\tlocal = $2\n\t\t\t\t\t\turi = get_namespace(prefix)\n\t\t\t\t\t\t# find the observers for start_element\n\t\t\t\t\t\tprocs = get_procs( :end_element, event[1] )\n\t\t\t\t\t\tlisteners = get_listeners( :end_element, event[1] )\n\t\t\t\t\t\t# notify observers\n\t\t\t\t\t\tprocs.each { |ob| ob.call( uri, local, event[1] ) } if procs\n\t\t\t\t\t\tlisteners.each { |ob| \n\t\t\t\t\t\t\tob.end_element( uri, local, event[1] ) \n\t\t\t\t\t\t} if listeners\n\n\t\t\t\t\t\tnamespace_mapping = @namespace_stack.pop\n\t\t\t\t\t\t# find the observers for namespaces\n\t\t\t\t\t\tprocs = get_procs( :end_prefix_mapping, event[1] )\n\t\t\t\t\t\tlisteners = get_listeners( :end_prefix_mapping, event[1] )\n\t\t\t\t\t\tif procs or listeners\n\t\t\t\t\t\t\tnamespace_mapping.each do |prefix, uri|\n\t\t\t\t\t\t\t\t# notify observers of namespaces\n\t\t\t\t\t\t\t\tprocs.each { |ob| ob.call( prefix ) } if procs\n\t\t\t\t\t\t\t\tlisteners.each { |ob| ob.end_prefix_mapping(prefix) } if listeners\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\twhen :text\n            #normalized = @parser.normalize( event[1] )\n            #handle( :characters, normalized )\n            copy = event[1].clone\n            @entities.each { |key, value| copy = copy.gsub(\"&#{key};\", value) }\n            copy.gsub!( Text::NUMERICENTITY ) {|m|\n              m=$1\n              m = \"0#{m}\" if m[0] == ?x\n              [Integer(m)].pack('U*')\n            }\n            handle( :characters, copy )\n          when :entitydecl\n            @entities[ event[1] ] = event[2] if event.size == 3\n\t\t\t\t\t\thandle( *event )\n\t\t\t\t\twhen :processing_instruction, :comment, :attlistdecl, \n\t\t\t\t\t\t:elementdecl, :cdata, :notationdecl, :xmldecl\n\t\t\t\t\t\thandle( *event )\n\t\t\t\t\tend\n          handle( :progress, @parser.position )\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tprivate\n\t\t\tdef handle( symbol, *arguments )\n\t\t\t\ttag = @tag_stack[-1]\n\t\t\t\tprocs = get_procs( symbol, tag )\n\t\t\t\tlisteners = get_listeners( symbol, tag )\n\t\t\t\t# notify observers\n\t\t\t\tprocs.each { |ob| ob.call( *arguments ) } if procs\n\t\t\t\tlisteners.each { |l| \n\t\t\t\t\tl.send( symbol.to_s, *arguments ) \n\t\t\t\t} if listeners\n\t\t\tend\n\n\t\t\t# The following methods are duplicates, but it is faster than using\n\t\t\t# a helper\n\t\t\tdef get_procs( symbol, name )\n\t\t\t\treturn nil if @procs.size == 0\n\t\t\t\t@procs.find_all do |sym, match, block|\n          #puts sym.inspect+\"==\"+symbol.inspect+ \"\\t\"+match.inspect+\"==\"+name.inspect+ \"\\t\"+( (sym.nil? or symbol == sym) and ((name.nil? and match.nil?) or match.nil? or ( (name == match) or (match.kind_of? Regexp and name =~ match)))).to_s\n\t\t\t\t\t(\n\t\t\t\t\t\t(sym.nil? or symbol == sym) and \n\t\t\t\t\t\t((name.nil? and match.nil?) or match.nil? or (\n\t\t\t\t\t\t\t(name == match) or\n\t\t\t\t\t\t\t(match.kind_of? Regexp and name =~ match)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\tend.collect{|x| x[-1]}\n\t\t\tend\n\t\t\tdef get_listeners( symbol, name )\n\t\t\t\treturn nil if @listeners.size == 0\n\t\t\t\t@listeners.find_all do |sym, match, block|\n\t\t\t\t\t(\n\t\t\t\t\t\t(sym.nil? or symbol == sym) and \n\t\t\t\t\t\t((name.nil? and match.nil?) or match.nil? or (\n\t\t\t\t\t\t\t(name == match) or\n\t\t\t\t\t\t\t(match.kind_of? Regexp and name =~ match)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\tend.collect{|x| x[-1]}\n\t\t\tend\n\n\t\t\tdef add( pair )\n\t\t\t\tif pair[-1].respond_to? :call\n\t\t\t\t\t@procs << pair unless @procs.include? pair\n\t\t\t\telse\n\t\t\t\t\t@listeners << pair unless @listeners.include? pair\n\t\t\t\t\t@has_listeners = true\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tdef get_namespace( prefix ) \n        uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) ||\n\t\t\t\t\t(@namespace_stack.find { |ns| not ns[nil].nil? })\n\t\t\t\turis[-1][prefix] unless uris.nil? or 0 == uris.size\n\t\t\tend\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/parsers/streamparser.rb",
    "content": "module REXML\n  module Parsers\n    class StreamParser\n      def initialize source, listener\n        @listener = listener\n        @parser = BaseParser.new( source )\n      end\n      \n      def add_listener( listener )\n        @parser.add_listener( listener )\n      end\n      \n      def parse\n        # entity string\n        while true\n          event = @parser.pull\n          case event[0]\n          when :end_document\n            return\n          when :start_element\n            attrs = event[2].each do |n, v|\n              event[2][n] = @parser.unnormalize( v )\n            end\n            @listener.tag_start( event[1], attrs )\n          when :end_element\n            @listener.tag_end( event[1] )\n          when :text\n            normalized = @parser.unnormalize( event[1] )\n            @listener.text( normalized )\n          when :processing_instruction\n            @listener.instruction( *event[1,2] )\n          when :start_doctype\n            @listener.doctype( *event[1..-1] )\n          when :end_doctype\n            # FIXME: remove this condition for milestone:3.2\n            @listener.doctype_end if @listener.respond_to? :doctype_end\n          when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl\n            @listener.send( event[0].to_s, *event[1..-1] )\n          when :entitydecl, :notationdecl\n            @listener.send( event[0].to_s, event[1..-1] )\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/parsers/treeparser.rb",
    "content": "require 'rexml/validation/validationexception'\nrequire 'rexml/undefinednamespaceexception'\n\nmodule REXML\n  module Parsers\n    class TreeParser\n      def initialize( source, build_context = Document.new )\n        @build_context = build_context\n        @parser = Parsers::BaseParser.new( source )\n      end\n\n      def add_listener( listener )\n        @parser.add_listener( listener )\n      end\n\n      def parse\n        tag_stack = []\n        in_doctype = false\n        entities = nil\n        begin\n          while true\n            event = @parser.pull\n            #STDERR.puts \"TREEPARSER GOT #{event.inspect}\"\n            case event[0]\n            when :end_document\n              unless tag_stack.empty?\n                #raise ParseException.new(\"No close tag for #{tag_stack.inspect}\")\n                raise ParseException.new(\"No close tag for #{@build_context.xpath}\")\n              end\n              return\n            when :start_element\n              tag_stack.push(event[1])\n              el = @build_context = @build_context.add_element( event[1], event[2] )\n            when :end_element\n              tag_stack.pop\n              @build_context = @build_context.parent\n            when :text\n              if not in_doctype\n                if @build_context[-1].instance_of? Text\n                  @build_context[-1] << event[1]\n                else\n                  @build_context.add( \n                    Text.new(event[1], @build_context.whitespace, nil, true) \n                  ) unless (\n                    @build_context.ignore_whitespace_nodes and\n                    event[1].strip.size==0\n                  )\n                end\n              end\n            when :comment\n              c = Comment.new( event[1] )\n              @build_context.add( c )\n            when :cdata\n              c = CData.new( event[1] )\n              @build_context.add( c )\n            when :processing_instruction\n              @build_context.add( Instruction.new( event[1], event[2] ) )\n            when :end_doctype\n              in_doctype = false\n              entities.each { |k,v| entities[k] = @build_context.entities[k].value }\n              @build_context = @build_context.parent\n            when :start_doctype\n              doctype = DocType.new( event[1..-1], @build_context )\n              @build_context = doctype\n              entities = {}\n              in_doctype = true\n            when :attlistdecl\n              n = AttlistDecl.new( event[1..-1] )\n              @build_context.add( n )\n            when :externalentity\n              n = ExternalEntity.new( event[1] )\n              @build_context.add( n )\n            when :elementdecl\n              n = ElementDecl.new( event[1] )\n              @build_context.add(n)\n            when :entitydecl\n              entities[ event[1] ] = event[2] unless event[2] =~ /PUBLIC|SYSTEM/\n              @build_context.add(Entity.new(event))\n            when :notationdecl\n              n = NotationDecl.new( *event[1..-1] )\n              @build_context.add( n )\n            when :xmldecl\n              x = XMLDecl.new( event[1], event[2], event[3] )\n              @build_context.add( x )\n            end\n          end\n        rescue REXML::Validation::ValidationException\n          raise\n        rescue REXML::UndefinedNamespaceException\n          raise\n        rescue\n          raise ParseException.new( $!.message, @parser.source, @parser, $! )\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/parsers/ultralightparser.rb",
    "content": "require 'rexml/parsers/streamparser'\nrequire 'rexml/parsers/baseparser'\n\nmodule REXML\n\tmodule Parsers\n\t\tclass UltraLightParser\n\t\t\tdef initialize stream\n\t\t\t\t@stream = stream\n\t\t\t\t@parser = REXML::Parsers::BaseParser.new( stream )\n\t\t\tend\n\n      def add_listener( listener )\n        @parser.add_listener( listener )\n      end\n\n      def rewind\n        @stream.rewind\n        @parser.stream = @stream\n      end\n\n\t\t\tdef parse\n\t\t\t\troot = context = []\n\t\t\t\twhile true\n\t\t\t\t\tevent = @parser.pull\n\t\t\t\t\tcase event[0]\n\t\t\t\t\twhen :end_document\n\t\t\t\t\t\tbreak\n\t\t\t\t\twhen :end_doctype\n\t\t\t\t\t\tcontext = context[1]\n\t\t\t\t\twhen :start_element, :doctype\n\t\t\t\t\t\tcontext << event\n\t\t\t\t\t\tevent[1,0] = [context]\n\t\t\t\t\t\tcontext = event\n\t\t\t\t\twhen :end_element\n\t\t\t\t\t\tcontext = context[1]\n\t\t\t\t\telse\n\t\t\t\t\t\tcontext << event\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\troot\n\t\t\tend\n\t\tend\n\n\t\t# An element is an array.  The array contains:\n\t\t#  0\t\t\tThe parent element\n\t\t#  1\t\t\tThe tag name\n\t\t#  2\t\t\tA hash of attributes\n\t\t#  3..-1\tThe child elements\n\t\t# An element is an array of size > 3\n\t\t# Text is a String\n\t\t# PIs are [ :processing_instruction, target, data ]\n\t\t# Comments are [ :comment, data ]\n\t\t# DocTypes are DocType structs\n\t\t# The root is an array with XMLDecls, Text, DocType, Array, Text\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/parsers/xpathparser.rb",
    "content": "require 'rexml/namespace'\nrequire 'rexml/xmltokens'\n\nmodule REXML\n  module Parsers\n    # You don't want to use this class.  Really.  Use XPath, which is a wrapper\n    # for this class.  Believe me.  You don't want to poke around in here.\n    # There is strange, dark magic at work in this code.  Beware.  Go back!  Go\n    # back while you still can!\n    class XPathParser\n      include XMLTokens\n      LITERAL    = /^'([^']*)'|^\"([^\"]*)\"/u\n\n      def namespaces=( namespaces )\n        Functions::namespace_context = namespaces\n        @namespaces = namespaces\n      end\n\n      def parse path\n        path.gsub!(/([\\(\\[])\\s+/, '\\1') # Strip ignorable spaces\n        path.gsub!( /\\s+([\\]\\)])/, '\\1' )\n        parsed = []\n        path = OrExpr(path, parsed)\n        parsed\n      end\n\n      def predicate path\n        parsed = []\n        Predicate( \"[#{path}]\", parsed )\n        parsed\n      end\n\n      def abbreviate( path )\n        path = path.kind_of?(String) ? parse( path ) : path\n        string = \"\"\n        document = false\n        while path.size > 0\n          op = path.shift\n          case op\n          when :node\n          when :attribute\n\t\t\t\t\t\tstring << \"/\" if string.size > 0\n\t\t\t\t\t\tstring << \"@\"\n          when :child\n\t\t\t\t\t\tstring << \"/\" if string.size > 0\n          when :descendant_or_self\n            string << \"/\"\n          when :self\n            string << \".\"\n          when :parent\n            string << \"..\"\n          when :any\n            string << \"*\"\n\t\t\t\t\twhen :text\n\t\t\t\t\t\tstring << \"text()\"\n          when :following, :following_sibling, \n                :ancestor, :ancestor_or_self, :descendant, \n                :namespace, :preceding, :preceding_sibling\n            string << \"/\" unless string.size == 0\n            string << op.to_s.tr(\"_\", \"-\")\n            string << \"::\"\n          when :qname\n            prefix = path.shift\n            name = path.shift\n            string << prefix+\":\" if prefix.size > 0\n            string << name\n          when :predicate\n            string << '['\n            string << predicate_to_string( path.shift ) {|x| abbreviate( x ) }\n            string << ']'\n          when :document\n            document = true\n\t\t\t\t\twhen :function\n\t\t\t\t\t\tstring << path.shift\n\t\t\t\t\t\tstring << \"( \"\n\t\t\t\t\t\tstring << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}\n\t\t\t\t\t\tstring << \" )\"\n\t\t\t\t\twhen :literal\n\t\t\t\t\t\tstring << %Q{ \"#{path.shift}\" }\n          else\n            string << \"/\" unless string.size == 0\n            string << \"UNKNOWN(\"\n            string << op.inspect\n            string << \")\"\n          end\n        end\n\t\t\t\tstring = \"/\"+string if document\n        return string\n      end\n\n      def expand( path )\n        path = path.kind_of?(String) ? parse( path ) : path\n        string = \"\"\n        document = false\n        while path.size > 0\n          op = path.shift\n          case op\n          when :node\n            string << \"node()\"\n          when :attribute, :child, :following, :following_sibling, \n                :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,\n                :namespace, :preceding, :preceding_sibling, :self, :parent\n            string << \"/\" unless string.size == 0\n            string << op.to_s.tr(\"_\", \"-\")\n            string << \"::\"\n          when :any\n            string << \"*\"\n          when :qname\n            prefix = path.shift\n            name = path.shift\n            string << prefix+\":\" if prefix.size > 0\n            string << name\n          when :predicate\n            string << '['\n            string << predicate_to_string( path.shift ) { |x| expand(x) }\n            string << ']'\n          when :document\n            document = true\n          else\n            string << \"/\" unless string.size == 0\n            string << \"UNKNOWN(\"\n            string << op.inspect\n            string << \")\"\n          end\n        end\n        string = \"/\"+string if document\n        return string\n      end\n\n      def predicate_to_string( path, &block )\n        string = \"\"\n        case path[0]\n        when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union\n          op = path.shift\n          case op\n          when :eq\n            op = \"=\"\n          when :lt\n            op = \"<\"\n          when :gt\n            op = \">\"\n          when :lteq\n            op = \"<=\"\n          when :gteq\n            op = \">=\"\n          when :neq\n            op = \"!=\"\n          when :union\n            op = \"|\"\n          end\n          left = predicate_to_string( path.shift, &block )\n          right = predicate_to_string( path.shift, &block )\n          string << \" \"\n          string << left\n          string << \" \"\n          string << op.to_s\n          string << \" \"\n          string << right\n          string << \" \"\n        when :function\n          path.shift\n          name = path.shift\n          string << name\n          string << \"( \"\n          string << predicate_to_string( path.shift, &block )\n          string << \" )\"\n        when :literal\n          path.shift\n          string << \" \"\n          string << path.shift.inspect\n          string << \" \"\n        else\n          string << \" \"\n          string << yield( path )\n          string << \" \"\n        end\n        return string.squeeze(\" \")\n      end\n\n      private\n      #LocationPath\n      #  | RelativeLocationPath\n      #  | '/' RelativeLocationPath?\n      #  | '//' RelativeLocationPath\n      def LocationPath path, parsed\n        #puts \"LocationPath '#{path}'\"\n        path = path.strip\n        if path[0] == ?/\n          parsed << :document\n          if path[1] == ?/\n            parsed << :descendant_or_self\n            parsed << :node\n            path = path[2..-1]\n          else\n            path = path[1..-1]\n          end\n        end\n        #puts parsed.inspect\n        return RelativeLocationPath( path, parsed ) if path.size > 0\n      end\n\n      #RelativeLocationPath\n      #  |                                                    Step\n      #    | (AXIS_NAME '::' | '@' | '')                     AxisSpecifier\n      #      NodeTest\n      #        Predicate\n      #    | '.' | '..'                                      AbbreviatedStep\n      #  |  RelativeLocationPath '/' Step\n      #  | RelativeLocationPath '//' Step\n      AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/\n      def RelativeLocationPath path, parsed\n        #puts \"RelativeLocationPath #{path}\"\n        while path.size > 0\n          # (axis or @ or <child::>) nodetest predicate  >\n          # OR                                          >  / Step\n          # (. or ..)                                    >\n          if path[0] == ?.\n            if path[1] == ?.\n              parsed << :parent\n              parsed << :node\n              path = path[2..-1]\n            else\n              parsed << :self\n              parsed << :node\n              path = path[1..-1]\n            end\n          else\n            if path[0] == ?@\n              #puts \"ATTRIBUTE\"\n              parsed << :attribute\n              path = path[1..-1]\n              # Goto Nodetest\n            elsif path =~ AXIS\n              parsed << $1.tr('-','_').intern\n              path = $'\n              # Goto Nodetest\n            else\n              parsed << :child\n            end\n\n            #puts \"NODETESTING '#{path}'\"\n            n = []\n            path = NodeTest( path, n)\n            #puts \"NODETEST RETURNED '#{path}'\"\n\n            if path[0] == ?[\n              path = Predicate( path, n )\n            end\n\n            parsed.concat(n)\n          end\n          \n          if path.size > 0\n            if path[0] == ?/\n              if path[1] == ?/\n                parsed << :descendant_or_self\n                parsed << :node\n                path = path[2..-1]\n              else\n                path = path[1..-1]\n              end\n            else\n              return path\n            end\n          end\n        end\n        return path\n      end\n\n      # Returns a 1-1 map of the nodeset\n      # The contents of the resulting array are either:\n      #   true/false, if a positive match\n      #   String, if a name match\n      #NodeTest\n      #  | ('*' | NCNAME ':' '*' | QNAME)                NameTest\n      #  | NODE_TYPE '(' ')'                              NodeType\n      #  | PI '(' LITERAL ')'                            PI\n      #    | '[' expr ']'                                Predicate\n      NCNAMETEST= /^(#{NCNAME_STR}):\\*/u\n      QNAME     = Namespace::NAMESPLIT\n      NODE_TYPE  = /^(comment|text|node)\\(\\s*\\)/m\n      PI        = /^processing-instruction\\(/\n      def NodeTest path, parsed\n        #puts \"NodeTest with #{path}\"\n        res = nil\n        case path\n        when /^\\*/\n          path = $'\n          parsed << :any\n        when NODE_TYPE\n          type = $1\n          path = $'\n          parsed << type.tr('-', '_').intern\n        when PI\n          path = $'\n          literal = nil\n          if path !~ /^\\s*\\)/\n            path =~ LITERAL\n            literal = $1\n            path = $'\n            raise ParseException.new(\"Missing ')' after processing instruction\") if path[0] != ?)\n            path = path[1..-1]\n          end\n          parsed << :processing_instruction\n          parsed << (literal || '')\n        when NCNAMETEST\n          #puts \"NCNAMETEST\"\n          prefix = $1\n          path = $'\n          parsed << :namespace\n          parsed << prefix\n        when QNAME\n          #puts \"QNAME\"\n          prefix = $1\n          name = $2\n          path = $'\n          prefix = \"\" unless prefix\n          parsed << :qname\n          parsed << prefix\n          parsed << name\n        end\n        return path\n      end\n\n      # Filters the supplied nodeset on the predicate(s)\n      def Predicate path, parsed\n        #puts \"PREDICATE with #{path}\"\n        return nil unless path[0] == ?[\n        predicates = []\n        while path[0] == ?[\n          path, expr = get_group(path)\n          predicates << expr[1..-2] if expr\n        end\n        #puts \"PREDICATES = #{predicates.inspect}\"\n        predicates.each{ |expr| \n          #puts \"ORING #{expr}\"\n          preds = []\n          parsed << :predicate\n          parsed << preds\n          OrExpr(expr, preds) \n        }\n        #puts \"PREDICATES = #{predicates.inspect}\"\n        path\n      end\n\n      # The following return arrays of true/false, a 1-1 mapping of the\n      # supplied nodeset, except for axe(), which returns a filtered\n      # nodeset\n\n      #| OrExpr S 'or' S AndExpr\n      #| AndExpr\n      def OrExpr path, parsed\n        #puts \"OR >>> #{path}\"\n        n = []\n        rest = AndExpr( path, n )\n        #puts \"OR <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*( or )/\n            n = [ :or, n, [] ]\n            rest = AndExpr( $', n[-1] )\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace(n)\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| AndExpr S 'and' S EqualityExpr\n      #| EqualityExpr\n      def AndExpr path, parsed\n        #puts \"AND >>> #{path}\"\n        n = []\n        rest = EqualityExpr( path, n )\n        #puts \"AND <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*( and )/\n            n = [ :and, n, [] ]\n            #puts \"AND >>> #{rest}\"\n            rest = EqualityExpr( $', n[-1] )\n            #puts \"AND <<< #{rest}\"\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace(n)\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| EqualityExpr ('=' | '!=')  RelationalExpr\n      #| RelationalExpr\n      def EqualityExpr path, parsed\n        #puts \"EQUALITY >>> #{path}\"\n        n = []\n        rest = RelationalExpr( path, n )\n        #puts \"EQUALITY <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*(!?=)\\s*/\n            if $1[0] == ?!\n              n = [ :neq, n, [] ]\n            else\n              n = [ :eq, n, [] ]\n            end\n            rest = RelationalExpr( $', n[-1] )\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace(n)\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| RelationalExpr ('<' | '>' | '<=' | '>=') AdditiveExpr\n      #| AdditiveExpr\n      def RelationalExpr path, parsed\n        #puts \"RELATION >>> #{path}\"\n        n = []\n        rest = AdditiveExpr( path, n )\n        #puts \"RELATION <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*([<>]=?)\\s*/\n            if $1[0] == ?<\n              sym = \"lt\"\n            else\n              sym = \"gt\"\n            end\n            sym << \"eq\" if $1[-1] == ?=\n            n = [ sym.intern, n, [] ]\n            rest = AdditiveExpr( $', n[-1] )\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace(n)\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| AdditiveExpr ('+' | S '-') MultiplicativeExpr\n      #| MultiplicativeExpr\n      def AdditiveExpr path, parsed\n        #puts \"ADDITIVE >>> #{path}\"\n        n = []\n        rest = MultiplicativeExpr( path, n )\n        #puts \"ADDITIVE <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*(\\+| -)\\s*/\n            if $1[0] == ?+\n              n = [ :plus, n, [] ]\n            else\n              n = [ :minus, n, [] ]\n            end\n            rest = MultiplicativeExpr( $', n[-1] )\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace(n)\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| MultiplicativeExpr ('*' | S ('div' | 'mod') S) UnaryExpr\n      #| UnaryExpr\n      def MultiplicativeExpr path, parsed\n        #puts \"MULT >>> #{path}\"\n        n = []\n        rest = UnaryExpr( path, n )\n        #puts \"MULT <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*(\\*| div | mod )\\s*/\n            if $1[0] == ?*\n              n = [ :mult, n, [] ]\n            elsif $1.include?( \"div\" )\n              n = [ :div, n, [] ]\n            else\n              n = [ :mod, n, [] ]\n            end\n            rest = UnaryExpr( $', n[-1] )\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace(n)\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| '-' UnaryExpr\n      #| UnionExpr\n      def UnaryExpr path, parsed\n        path =~ /^(\\-*)/\n        path = $'\n        if $1 and (($1.size % 2) != 0)\n          mult = -1\n        else\n          mult = 1\n        end\n        parsed << :neg if mult < 0\n\n        #puts \"UNARY >>> #{path}\"\n        n = []\n        path = UnionExpr( path, n )\n        #puts \"UNARY <<< #{path}\"\n        parsed.concat( n )\n        path\n      end\n\n      #| UnionExpr '|' PathExpr\n      #| PathExpr\n      def UnionExpr path, parsed\n        #puts \"UNION >>> #{path}\"\n        n = []\n        rest = PathExpr( path, n )\n        #puts \"UNION <<< #{rest}\"\n        if rest != path\n          while rest =~ /^\\s*(\\|)\\s*/\n            n = [ :union, n, [] ]\n            rest = PathExpr( $', n[-1] )\n          end\n        end\n        if parsed.size == 0 and n.size != 0\n          parsed.replace( n )\n        elsif n.size > 0\n          parsed << n\n        end\n        rest\n      end\n\n      #| LocationPath\n      #| FilterExpr ('/' | '//') RelativeLocationPath\n      def PathExpr path, parsed\n        path =~ /^\\s*/\n        path = $'\n        #puts \"PATH >>> #{path}\"\n        n = []\n        rest = FilterExpr( path, n )\n        #puts \"PATH <<< '#{rest}'\"\n        if rest != path\n          if rest and rest[0] == ?/\n            return RelativeLocationPath(rest, n)\n          end\n        end\n        #puts \"BEFORE WITH '#{rest}'\"\n        rest = LocationPath(rest, n) if rest =~ /\\A[\\/\\.\\@\\[\\w_*]/\n        parsed.concat(n)\n        return rest\n      end\n\n      #| FilterExpr Predicate\n      #| PrimaryExpr\n      def FilterExpr path, parsed\n        #puts \"FILTER >>> #{path}\"\n        n = []\n        path = PrimaryExpr( path, n )\n        #puts \"FILTER <<< #{path}\"\n        path = Predicate(path, n) if path and path[0] == ?[\n        #puts \"FILTER <<< #{path}\"\n        parsed.concat(n)\n        path\n      end\n\n      #| VARIABLE_REFERENCE\n      #| '(' expr ')'\n      #| LITERAL\n      #| NUMBER\n      #| FunctionCall\n      VARIABLE_REFERENCE  = /^\\$(#{NAME_STR})/u\n      NUMBER              = /^(\\d*\\.?\\d+)/\n      NT        = /^comment|text|processing-instruction|node$/\n      def PrimaryExpr path, parsed\n        arry = []\n        case path\n        when VARIABLE_REFERENCE\n          varname = $1\n          path = $'\n          parsed << :variable\n          parsed << varname\n          #arry << @variables[ varname ]\n        when /^(\\w[-\\w]*)(?:\\()/\n          #puts \"PrimaryExpr :: Function >>> #$1 -- '#$''\"\n          fname = $1\n          tmp = $'\n          #puts \"#{fname} =~ #{NT.inspect}\"\n          return path if fname =~ NT\n          path = tmp\n          parsed << :function\n          parsed << fname\n          path = FunctionCall(path, parsed)\n        when NUMBER\n          #puts \"LITERAL or NUMBER: #$1\"\n          varname = $1.nil? ? $2 : $1\n          path = $'\n          parsed << :literal \n          parsed << (varname.include?('.') ? varname.to_f : varname.to_i)\n        when LITERAL\n          #puts \"LITERAL or NUMBER: #$1\"\n          varname = $1.nil? ? $2 : $1\n          path = $'\n          parsed << :literal \n          parsed << varname\n        when /^\\(/                                               #/\n          path, contents = get_group(path)\n          contents = contents[1..-2]\n          n = []\n          OrExpr( contents, n )\n          parsed.concat(n)\n        end\n        path\n      end\n\n      #| FUNCTION_NAME '(' ( expr ( ',' expr )* )? ')'\n      def FunctionCall rest, parsed\n        path, arguments = parse_args(rest)\n        argset = []\n        for argument in arguments\n          args = []\n          OrExpr( argument, args )\n          argset << args\n        end\n        parsed << argset\n        path\n      end\n\n      # get_group( '[foo]bar' ) -> ['bar', '[foo]']\n      def get_group string\n        ind = 0\n        depth = 0\n        st = string[0,1]\n        en = (st == \"(\" ? \")\" : \"]\")\n        begin\n          case string[ind,1]\n          when st\n            depth += 1\n          when en\n            depth -= 1\n          end\n          ind += 1\n        end while depth > 0 and ind < string.length\n        return nil unless depth==0\n        [string[ind..-1], string[0..ind-1]]\n      end\n      \n      def parse_args( string )\n        arguments = []\n        ind = 0\n\t\t\t\tinquot = false\n\t\t\t\tinapos = false\n        depth = 1\n        begin\n          case string[ind]\n          when ?\"\n          \tinquot = !inquot unless inapos\n          when ?'\n          \tinapos = !inapos unless inquot\n          else\n          \tunless inquot or inapos\n          \t\tcase string[ind]\n\t\t\t\t\t\t\twhen ?(\n\t\t\t\t\t\t\t\tdepth += 1\n                if depth == 1\n                \tstring = string[1..-1]\n                \tind -= 1\n                end\n\t\t\t\t\t\t\twhen ?)\n\t\t\t\t\t\t\t\tdepth -= 1\n\t\t\t\t\t\t\t\tif depth == 0\n\t\t\t\t\t\t\t\t\ts = string[0,ind].strip\n\t\t\t\t\t\t\t\t\targuments << s unless s == \"\"\n\t\t\t\t\t\t\t\t\tstring = string[ind+1..-1]\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\twhen ?,\n\t\t\t\t\t\t\t\tif depth == 1\n\t\t\t\t\t\t\t\t\ts = string[0,ind].strip\n\t\t\t\t\t\t\t\t\targuments << s unless s == \"\"\n\t\t\t\t\t\t\t\t\tstring = string[ind+1..-1]\n\t\t\t\t\t\t\t\t\tind = -1 \n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n            end\n          end\n          ind += 1\n        end while depth > 0 and ind < string.length\n        return nil unless depth==0\n        [string,arguments]\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/quickpath.rb",
    "content": "require 'rexml/functions'\nrequire 'rexml/xmltokens'\n\nmodule REXML\n\tclass QuickPath\n\t\tinclude Functions\n\t\tinclude XMLTokens\n\n\t\tEMPTY_HASH = {}\n\n\t\tdef QuickPath::first element, path, namespaces=EMPTY_HASH\n\t\t\tmatch(element, path, namespaces)[0]\n\t\tend\n\n\t\tdef QuickPath::each element, path, namespaces=EMPTY_HASH, &block\n\t\t\tpath = \"*\" unless path\n\t\t\tmatch(element, path, namespaces).each( &block )\n\t\tend\n\n\t\tdef QuickPath::match element, path, namespaces=EMPTY_HASH\n\t\t\traise \"nil is not a valid xpath\" unless path\n\t\t\tresults = nil\n\t\t\tFunctions::namespace_context = namespaces\n\t\t\tcase path\n\t\t\twhen /^\\/([^\\/]|$)/u\n\t\t\t\t# match on root\n\t\t\t\tpath = path[1..-1]\n\t\t\t\treturn [element.root.parent] if path == ''\n\t\t\t\tresults = filter([element.root], path)\n\t\t\twhen /^[-\\w]*::/u\n\t\t\t\tresults = filter([element], path)\n\t\t\twhen /^\\*/u\n\t\t\t\tresults = filter(element.to_a, path)\n\t\t\twhen /^[\\[!\\w:]/u\n\t\t\t\t# match on child\n\t\t\t\tmatches = []\n\t\t\t\tchildren = element.to_a\n\t\t\t\tresults = filter(children, path)\n\t\t\telse\n\t\t\t\tresults = filter([element], path)\n\t\t\tend\n\t\t\treturn results\n\t\tend\n\n\t\t# Given an array of nodes it filters the array based on the path. The\n\t\t# result is that when this method returns, the array will contain elements\n\t\t# which match the path\n\t\tdef QuickPath::filter elements, path\n\t\t\treturn elements if path.nil? or path == '' or elements.size == 0\n\t\t\tcase path\n\t\t\twhen /^\\/\\//u\t\t\t\t\t\t\t\t\t\t\t# Descendant\n\t\t\t\treturn axe( elements, \"descendant-or-self\", $' )\n\t\t\twhen /^\\/?\\b(\\w[-\\w]*)\\b::/u\t\t\t\t\t\t\t# Axe\n\t\t\t\taxe_name = $1\n\t\t\t\trest = $'\n\t\t\t\treturn axe( elements, $1, $' )\n\t\t\twhen /^\\/(?=\\b([:!\\w][-\\.\\w]*:)?[-!\\*\\.\\w]*\\b([^:(]|$)|\\*)/u\t# Child\n\t\t\t\trest = $'\n\t\t\t\tresults = []\n\t\t\t\telements.each do |element|\n\t\t\t\t\tresults |= filter( element.to_a, rest )\n\t\t\t\tend\n\t\t\t\treturn results\n\t\t\twhen /^\\/?(\\w[-\\w]*)\\(/u\t\t\t\t\t\t\t# / Function\n\t\t\t\treturn function( elements, $1, $' )\n\t\t\twhen Namespace::NAMESPLIT\t\t# Element name\n\t\t\t\tname = $2\n\t\t\t\tns = $1\n\t\t\t\trest = $'\n\t\t\t\telements.delete_if do |element|\n\t\t\t\t\t!(element.kind_of? Element and \n\t\t\t\t\t\t(element.expanded_name == name or\n\t\t\t\t\t\t (element.name == name and\n\t\t\t\t\t\t  element.namespace == Functions.namespace_context[ns])))\n\t\t\t\tend\n\t\t\t\treturn filter( elements, rest )\n\t\t\twhen /^\\/\\[/u\n\t\t\t\tmatches = []\n\t\t\t\telements.each do |element|\n\t\t\t\t\tmatches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element\n\t\t\t\tend\n\t\t\t\treturn matches\n\t\t\twhen /^\\[/u\t\t\t\t\t\t\t\t\t\t\t\t# Predicate\n\t\t\t\treturn predicate( elements, path )\n\t\t\twhen /^\\/?\\.\\.\\./u\t\t\t\t\t\t\t\t\t\t# Ancestor\n\t\t\t\treturn axe( elements, \"ancestor\", $' )\n\t\t\twhen /^\\/?\\.\\./u\t\t\t\t\t\t\t\t\t\t\t# Parent\n\t\t\t\treturn filter( elements.collect{|e|e.parent}, $' )\n\t\t\twhen /^\\/?\\./u\t\t\t\t\t\t\t\t\t\t\t\t# Self\n\t\t\t\treturn filter( elements, $' )\n\t\t\twhen /^\\*/u\t\t\t\t\t\t\t\t\t\t\t\t\t# Any\n\t\t\t\tresults = []\n\t\t\t\telements.each do |element|\n\t\t\t\t\tresults |= filter( [element], $' ) if element.kind_of? Element\n\t\t\t\t\t#if element.kind_of? Element\n\t\t\t\t\t#\tchildren = element.to_a\n\t\t\t\t\t#\tchildren.delete_if { |child| !child.kind_of?(Element) }\n\t\t\t\t\t#\tresults |= filter( children, $' )\n\t\t\t\t\t#end\n\t\t\t\tend\n\t\t\t\treturn results\n\t\t\tend\n\t\t\treturn []\n\t\tend\n\n\t\tdef QuickPath::axe( elements, axe_name, rest )\n\t\t\tmatches = []\n\t\t\tmatches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u\n\t\t\tcase axe_name\n\t\t\twhen /^descendant/u\n\t\t\t\telements.each do |element|\n\t\t\t\t\tmatches |= filter( element.to_a, \"descendant-or-self::#{rest}\" ) if element.kind_of? Element\n\t\t\t\tend\n\t\t\twhen /^ancestor/u\n\t\t\t\telements.each do |element|\n\t\t\t\t\twhile element.parent\n\t\t\t\t\t\tmatches << element.parent\n\t\t\t\t\t\telement = element.parent\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tmatches = filter( matches, rest )\n\t\t\twhen \"self\"\n\t\t\t\tmatches = filter( elements, rest )\n\t\t\twhen \"child\"\n\t\t\t\telements.each do |element|\n\t\t\t\t\tmatches |= filter( element.to_a, rest ) if element.kind_of? Element\n\t\t\t\tend\n\t\t\twhen \"attribute\"\n\t\t\t\telements.each do |element|\n\t\t\t\t\tmatches << element.attributes[ rest ] if element.kind_of? Element\n\t\t\t\tend\n\t\t\twhen \"parent\"\n\t\t\t\tmatches = filter(elements.collect{|element| element.parent}.uniq, rest)\n\t\t\twhen \"following-sibling\"\n\t\t\t\tmatches = filter(elements.collect{|element| element.next_sibling}.uniq,\n\t\t\t\t\trest)\n\t\t\twhen \"previous-sibling\"\n\t\t\t\tmatches = filter(elements.collect{|element| \n\t\t\t\t\telement.previous_sibling}.uniq, rest )\n\t\t\tend\n\t\t\treturn matches.uniq\n\t\tend\n\n\t\t# A predicate filters a node-set with respect to an axis to produce a\n\t\t# new node-set. For each node in the node-set to be filtered, the \n\t\t# PredicateExpr is evaluated with that node as the context node, with \n\t\t# the number of nodes in the node-set as the context size, and with the \n\t\t# proximity position of the node in the node-set with respect to the\n\t\t# axis as the context position; if PredicateExpr evaluates to true for\n\t\t# that node, the node is included in the new node-set; otherwise, it is\n\t\t# not included.\n\t\t#\n\t\t# A PredicateExpr is evaluated by evaluating the Expr and converting\n\t\t# the result to a boolean. If the result is a number, the result will\n\t\t# be converted to true if the number is equal to the context position\n\t\t# and will be converted to false otherwise; if the result is not a\n\t\t# number, then the result will be converted as if by a call to the\n\t\t# boolean function. Thus a location path para[3] is equivalent to\n\t\t# para[position()=3].\n\t\tdef QuickPath::predicate( elements, path ) \n\t\t\tind = 1\n\t\t\tbcount = 1\n\t\t\twhile bcount > 0\n\t\t\t\tbcount += 1 if path[ind] == ?[\n\t\t\t\tbcount -= 1 if path[ind] == ?]\n\t\t\t\tind += 1\n\t\t\tend\n\t\t\tind -= 1\n\t\t\tpredicate = path[1..ind-1]\n\t\t\trest = path[ind+1..-1]\n\n\t\t\t# have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'\n\t\t\tpredicate.gsub!( /([^\\s(and)(or)<>=]+)\\s*([<>=])\\s*([^\\s(and)(or)<>=]+)\\s*([<>=])\\s*([^\\s(and)(or)<>=]+)/u ) { \n\t\t\t\t\"#$1 #$2 #$3 and #$3 #$4 #$5\"\n\t\t\t}\n\t\t\t# Let's do some Ruby trickery to avoid some work:\n\t\t\tpredicate.gsub!( /&/u, \"&&\" )\n\t\t\tpredicate.gsub!( /=/u, \"==\" )\n\t\t\tpredicate.gsub!( /@(\\w[-\\w.]*)/u ) {\n\t\t\t\t\"attribute(\\\"#$1\\\")\" \n\t\t\t}\n\t\t\tpredicate.gsub!( /\\bmod\\b/u, \"%\" )\n\t\t\tpredicate.gsub!( /\\b(\\w[-\\w.]*\\()/u ) {\n\t\t\t\tfname = $1\n\t\t\t\tfname.gsub( /-/u, \"_\" )\n\t\t\t}\n\t\t\t\n\t\t\tFunctions.pair = [ 0, elements.size ]\n\t\t\tresults = []\n\t\t\telements.each do |element|\n\t\t\t\tFunctions.pair[0] += 1\n\t\t\t\tFunctions.node = element\n\t\t\t\tres = eval( predicate )\n\t\t\t\tcase res\n\t\t\t\twhen true\n\t\t\t\t\tresults << element\n\t\t\t\twhen Fixnum\n\t\t\t\t\tresults << element if Functions.pair[0] == res\n\t\t\t\twhen String\n\t\t\t\t\tresults << element\n\t\t\t\tend\n\t\t\tend\n\t\t\treturn filter( results, rest )\n\t\tend\n\n\t\tdef QuickPath::attribute( name )\n\t\t\treturn Functions.node.attributes[name] if Functions.node.kind_of? Element\n\t\tend\n\n\t\tdef QuickPath::name()\n\t\t\treturn Functions.node.name if Functions.node.kind_of? Element\n\t\tend\n\n\t\tdef QuickPath::method_missing( id, *args )\n\t\t\tbegin\n\t\t\t\tFunctions.send( id.id2name, *args )\n\t\t\trescue Exception\n\t\t\t\traise \"METHOD: #{id.id2name}(#{args.join ', '})\\n#{$!.message}\"\n\t\t\tend\n\t\tend\n\n\t\tdef QuickPath::function( elements, fname, rest )\n\t\t\targs = parse_args( elements, rest )\n\t\t\tFunctions.pair = [0, elements.size]\n\t\t\tresults = []\n\t\t\telements.each do |element|\n\t\t\t\tFunctions.pair[0] += 1\n\t\t\t\tFunctions.node = element\n\t\t\t\tres = Functions.send( fname, *args )\n\t\t\t\tcase res\n\t\t\t\twhen true\n\t\t\t\t\tresults << element\n\t\t\t\twhen Fixnum\n\t\t\t\t\tresults << element if Functions.pair[0] == res\n\t\t\t\tend\n\t\t\tend\n\t\t\treturn results\n\t\tend\n\n\t\tdef QuickPath::parse_args( element, string )\n\t\t\t# /.*?(?:\\)|,)/\n\t\t\targuments = []\n\t\t\tbuffer = \"\"\n\t\t\twhile string and string != \"\"\n\t\t\t\tc = string[0]\n\t\t\t\tstring.sub!(/^./u, \"\")\n\t\t\t\tcase c\n\t\t\t\twhen ?,\n\t\t\t\t\t# if depth = 1, then we start a new argument\n\t\t\t\t\targuments << evaluate( buffer )\n\t\t\t\t\t#arguments << evaluate( string[0..count] )\n\t\t\t\twhen ?(\n\t\t\t\t\t# start a new method call\n\t\t\t\t\tfunction( element, buffer, string )\n\t\t\t\t\tbuffer = \"\"\n\t\t\t\twhen ?)\n\t\t\t\t\t# close the method call and return arguments\n\t\t\t\t\treturn arguments\n\t\t\t\telse\n\t\t\t\t\tbuffer << c\n\t\t\t\tend\n\t\t\tend\n\t\t\t\"\"\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/rexml.rb",
    "content": "# -*- encoding: utf-8 -*-\n# REXML is an XML toolkit for Ruby[http://www.ruby-lang.org], in Ruby.\n#\n# REXML is a _pure_ Ruby, XML 1.0 conforming,\n# non-validating[http://www.w3.org/TR/2004/REC-xml-20040204/#sec-conformance]\n# toolkit with an intuitive API.  REXML passes 100% of the non-validating Oasis\n# tests[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml],\n# and provides tree, stream, SAX2, pull, and lightweight APIs.  REXML also \n# includes a full XPath[http://www.w3c.org/tr/xpath] 1.0 implementation. Since \n# Ruby 1.8, REXML is included in the standard Ruby distribution.\n#\n# Main page:: http://www.germane-software.com/software/rexml\n# Author:: Sean Russell <serATgermaneHYPHENsoftwareDOTcom>\n# Version:: 3.1.7.2\n# Date:: 2007/275\n# Revision:: $Revision$\n# \n# This API documentation can be downloaded from the REXML home page, or can\n# be accessed online[http://www.germane-software.com/software/rexml_doc]\n#\n# A tutorial is available in the REXML distribution in docs/tutorial.html,\n# or can be accessed \n# online[http://www.germane-software.com/software/rexml/docs/tutorial.html]\nmodule REXML\n  COPYRIGHT = \"Copyright \\xC2\\xA9 2001-2006 Sean Russell <ser@germane-software.com>\"\n  VERSION = \"3.1.7.3\"\n  DATE = \"2007/275\"\n  REVISION = \"$Revision$\".gsub(/\\$Revision:|\\$/,'').strip\n\n  Copyright = COPYRIGHT\n  Version = VERSION\nend\n"
  },
  {
    "path": "lib/rexml/sax2listener.rb",
    "content": "module REXML\n\t# A template for stream parser listeners.\n\t# Note that the declarations (attlistdecl, elementdecl, etc) are trivially\n\t# processed; REXML doesn't yet handle doctype entity declarations, so you \n\t# have to parse them out yourself.\n\t# === Missing methods from SAX2\n\t#  ignorable_whitespace\n\t# === Methods extending SAX2 \n\t# +WARNING+\n\t# These methods are certainly going to change, until DTDs are fully\n\t# supported.  Be aware of this.\n\t#  start_document\n\t#  end_document\n\t#  doctype\n\t#  elementdecl\n\t#  attlistdecl\n\t#  entitydecl\n\t#  notationdecl\n\t#  cdata\n\t#  xmldecl\n\t#  comment\n\tmodule SAX2Listener\n\t\tdef start_document\n\t\tend\n\t\tdef end_document\n\t\tend\n\t\tdef start_prefix_mapping prefix, uri\n\t\tend\n\t\tdef end_prefix_mapping prefix\n\t\tend\n\t\tdef start_element uri, localname, qname, attributes\n\t\tend\n\t\tdef end_element uri, localname, qname\n\t\tend\n\t\tdef characters text\n\t\tend\n\t\tdef processing_instruction target, data\n\t\tend\n\t\t# Handles a doctype declaration. Any attributes of the doctype which are\n\t\t# not supplied will be nil.  # EG, <!DOCTYPE me PUBLIC \"foo\" \"bar\">\n\t\t# @p name the name of the doctype; EG, \"me\"\n\t\t# @p pub_sys \"PUBLIC\", \"SYSTEM\", or nil.  EG, \"PUBLIC\"\n\t\t# @p long_name the supplied long name, or nil.  EG, \"foo\"\n\t\t# @p uri the uri of the doctype, or nil.  EG, \"bar\"\n\t\tdef doctype name, pub_sys, long_name, uri\n\t\tend\n\t\t# If a doctype includes an ATTLIST declaration, it will cause this\n\t\t# method to be called.  The content is the declaration itself, unparsed.\n\t\t# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as \"el\n\t\t# attr CDATA #REQUIRED\".  This is the same for all of the .*decl\n\t\t# methods.\n\t\tdef attlistdecl(element, pairs, contents)\n\t\tend\n\t\t# <!ELEMENT ...>\n\t\tdef elementdecl content\n\t\tend\n\t\t# <!ENTITY ...>\n\t\t# The argument passed to this method is an array of the entity\n\t\t# declaration.  It can be in a number of formats, but in general it\n\t\t# returns (example, result):\n\t\t#  <!ENTITY % YN '\"Yes\"'>  \n\t\t#  [\"%\", \"YN\", \"'\\\"Yes\\\"'\", \"\\\"\"]\n\t\t#  <!ENTITY % YN 'Yes'>\n\t\t#  [\"%\", \"YN\", \"'Yes'\", \"s\"]\n\t\t#  <!ENTITY WhatHeSaid \"He said %YN;\">\n\t\t#  [\"WhatHeSaid\", \"\\\"He said %YN;\\\"\", \"YN\"]\n\t\t#  <!ENTITY open-hatch SYSTEM \"http://www.textuality.com/boilerplate/OpenHatch.xml\">\n\t\t#  [\"open-hatch\", \"SYSTEM\", \"\\\"http://www.textuality.com/boilerplate/OpenHatch.xml\\\"\"]\n\t\t#  <!ENTITY open-hatch PUBLIC \"-//Textuality//TEXT Standard open-hatch boilerplate//EN\" \"http://www.textuality.com/boilerplate/OpenHatch.xml\">\n\t\t#  [\"open-hatch\", \"PUBLIC\", \"\\\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\\\"\", \"\\\"http://www.textuality.com/boilerplate/OpenHatch.xml\\\"\"]\n\t\t#  <!ENTITY hatch-pic SYSTEM \"../grafix/OpenHatch.gif\" NDATA gif>\n\t\t#  [\"hatch-pic\", \"SYSTEM\", \"\\\"../grafix/OpenHatch.gif\\\"\", \"\\n\\t\\t\\t\\t\\t\\t\\tNDATA gif\", \"gif\"]\n\t\tdef entitydecl name, decl\n\t\tend\n\t\t# <!NOTATION ...>\n\t\tdef notationdecl content\n\t\tend\n\t\t# Called when <![CDATA[ ... ]]> is encountered in a document.\n\t\t# @p content \"...\"\n\t\tdef cdata content\n\t\tend\n\t\t# Called when an XML PI is encountered in the document.\n\t\t# EG: <?xml version=\"1.0\" encoding=\"utf\"?>\n\t\t# @p version the version attribute value.  EG, \"1.0\"\n\t\t# @p encoding the encoding attribute value, or nil.  EG, \"utf\"\n\t\t# @p standalone the standalone attribute value, or nil.  EG, nil\n    # @p spaced the declaration is followed by a line break\n\t\tdef xmldecl version, encoding, standalone\n\t\tend\n\t\t# Called when a comment is encountered.\n\t\t# @p comment The content of the comment\n\t\tdef comment comment\n\t\tend\n    def progress position\n    end\n\tend\t\nend\n"
  },
  {
    "path": "lib/rexml/source.rb",
    "content": "require 'rexml/encoding'\n\nmodule REXML\n  # Generates Source-s.  USE THIS CLASS.\n  class SourceFactory\n    # Generates a Source object\n    # @param arg Either a String, or an IO\n    # @return a Source, or nil if a bad argument was given\n    def SourceFactory::create_from(arg)\n      if arg.kind_of? String\n        Source.new(arg)\n      elsif arg.respond_to? :read and\n            arg.respond_to? :readline and\n            arg.respond_to? :nil? and\n            arg.respond_to? :eof?\n        IOSource.new(arg)\n      elsif arg.kind_of? Source\n        arg\n      else\n        raise \"#{arg.class} is not a valid input stream.  It must walk \\n\"+\n          \"like either a String, an IO, or a Source.\"\n      end\n    end\n  end\n\n  # A Source can be searched for patterns, and wraps buffers and other\n  # objects and provides consumption of text\n  class Source\n    include Encoding\n    # The current buffer (what we're going to read next)\n    attr_reader :buffer\n    # The line number of the last consumed text\n    attr_reader :line\n    attr_reader :encoding\n\n    # Constructor\n    # @param arg must be a String, and should be a valid XML document\n    # @param encoding if non-null, sets the encoding of the source to this\n    # value, overriding all encoding detection\n    def initialize(arg, encoding=nil)\n      @orig = @buffer = arg\n      if encoding\n        self.encoding = encoding\n      else\n        self.encoding = check_encoding( @buffer )\n      end\n      @line = 0\n    end\n\n\n    # Inherited from Encoding\n    # Overridden to support optimized en/decoding\n    def encoding=(enc)\n      return unless super\n      @line_break = encode( '>' )\n      if enc != UTF_8\n        @buffer = decode(@buffer)\n        @to_utf = true\n      else\n        @to_utf = false\n      end\n    end\n\n    # Scans the source for a given pattern.  Note, that this is not your\n    # usual scan() method.  For one thing, the pattern argument has some\n    # requirements; for another, the source can be consumed.  You can easily\n    # confuse this method.  Originally, the patterns were easier\n    # to construct and this method more robust, because this method \n    # generated search regexes on the fly; however, this was \n    # computationally expensive and slowed down the entire REXML package \n    # considerably, since this is by far the most commonly called method.\n    # @param pattern must be a Regexp, and must be in the form of\n    # /^\\s*(#{your pattern, with no groups})(.*)/.  The first group\n    # will be returned; the second group is used if the consume flag is\n    # set.\n    # @param consume if true, the pattern returned will be consumed, leaving\n    # everything after it in the Source.\n    # @return the pattern, if found, or nil if the Source is empty or the\n    # pattern is not found.\n    def scan(pattern, cons=false)\n      return nil if @buffer.nil?\n      rv = @buffer.scan(pattern)\n      @buffer = $' if cons and rv.size>0\n      rv\n    end\n\n    def read\n    end\n\n    def consume( pattern )\n      @buffer = $' if pattern.match( @buffer )\n    end\n\n    def match_to( char, pattern )\n      return pattern.match(@buffer)\n    end\n\n    def match_to_consume( char, pattern )\n      md = pattern.match(@buffer)\n      @buffer = $'\n      return md\n    end\n\n    def match(pattern, cons=false)\n      md = pattern.match(@buffer)\n      @buffer = $' if cons and md\n      return md\n    end\n\n    # @return true if the Source is exhausted\n    def empty?\n      @buffer == \"\"\n    end\n\n    def position\n      @orig.index( @buffer )\n    end\n\n    # @return the current line in the source\n    def current_line\n      lines = @orig.split\n      res = lines.grep @buffer[0..30]\n      res = res[-1] if res.kind_of? Array\n      lines.index( res ) if res\n    end\n  end\n\n  # A Source that wraps an IO.  See the Source class for method\n  # documentation\n  class IOSource < Source\n    #attr_reader :block_size\n\n    # block_size has been deprecated\n    def initialize(arg, block_size=500, encoding=nil)\n      @er_source = @source = arg\n      @to_utf = false\n\n      # Determining the encoding is a deceptively difficult issue to resolve.\n      # First, we check the first two bytes for UTF-16.  Then we\n      # assume that the encoding is at least ASCII enough for the '>', and\n      # we read until we get one of those.  This gives us the XML declaration,\n      # if there is one.  If there isn't one, the file MUST be UTF-8, as per\n      # the XML spec.  If there is one, we can determine the encoding from\n      # it.\n      @buffer = \"\"\n      str = @source.read( 2 )\n      if encoding\n        self.encoding = encoding\n      elsif 0xfe == str[0] && 0xff == str[1]\n        @line_break = \"\\000>\"\n      elsif 0xff == str[0] && 0xfe == str[1]\n        @line_break = \">\\000\"\n      elsif 0xef == str[0] && 0xbb == str[1]\n        str += @source.read(1)\n        str = '' if (0xbf == str[2])\n        @line_break = \">\"\n      else\n        @line_break = \">\"\n      end\n      super str+@source.readline( @line_break )\n    end\n\n    def scan(pattern, cons=false)\n      rv = super\n      # You'll notice that this next section is very similar to the same\n      # section in match(), but just a liiittle different.  This is\n      # because it is a touch faster to do it this way with scan()\n      # than the way match() does it; enough faster to warrent duplicating\n      # some code\n      if rv.size == 0\n        until @buffer =~ pattern or @source.nil?\n          begin\n            # READLINE OPT\n            #str = @source.read(@block_size)\n            str = @source.readline(@line_break)\n            str = decode(str) if @to_utf and str\n            @buffer << str\n          rescue Iconv::IllegalSequence\n            raise\n          rescue\n            @source = nil\n          end\n        end\n        rv = super\n      end\n      rv.taint\n      rv\n    end\n\n    def read\n      begin\n        str = @source.readline(@line_break)\n        str = decode(str) if @to_utf and str \n        @buffer << str\n      rescue Exception, NameError\n        @source = nil\n      end\n    end\n\n    def consume( pattern )\n      match( pattern, true )\n    end\n\n    def match( pattern, cons=false )\n      rv = pattern.match(@buffer)\n      @buffer = $' if cons and rv\n      while !rv and @source\n        begin\n          str = @source.readline(@line_break)\n          str = decode(str) if @to_utf and str\n          @buffer << str\n          rv = pattern.match(@buffer)\n          @buffer = $' if cons and rv\n        rescue\n          @source = nil\n        end\n      end\n      rv.taint\n      rv\n    end\n    \n    def empty?\n      super and ( @source.nil? || @source.eof? )\n    end\n\n    def position\n      @er_source.stat.pipe? ? 0 : @er_source.pos\n    end\n\n    # @return the current line in the source\n    def current_line\n      begin\n        pos = @er_source.pos        # The byte position in the source\n        lineno = @er_source.lineno  # The XML < position in the source\n        @er_source.rewind\n        line = 0                    # The \\r\\n position in the source\n        begin\n          while @er_source.pos < pos\n            @er_source.readline\n            line += 1\n          end\n        rescue\n        end\n      rescue IOError\n        pos = -1\n        line = -1\n      end\n      [pos, lineno, line]\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/streamlistener.rb",
    "content": "module REXML\n\t# A template for stream parser listeners.\n\t# Note that the declarations (attlistdecl, elementdecl, etc) are trivially\n\t# processed; REXML doesn't yet handle doctype entity declarations, so you \n\t# have to parse them out yourself.\n\tmodule StreamListener\n\t\t# Called when a tag is encountered.\n\t\t# @p name the tag name\n\t\t# @p attrs an array of arrays of attribute/value pairs, suitable for\n\t\t# use with assoc or rassoc.  IE, <tag attr1=\"value1\" attr2=\"value2\">\n\t\t# will result in \n\t\t# tag_start( \"tag\", # [[\"attr1\",\"value1\"],[\"attr2\",\"value2\"]])\n\t\tdef tag_start name, attrs\n\t\tend\n\t\t# Called when the end tag is reached.  In the case of <tag/>, tag_end\n\t\t# will be called immidiately after tag_start\n\t\t# @p the name of the tag\n\t\tdef tag_end name\n\t\tend\n\t\t# Called when text is encountered in the document\n\t\t# @p text the text content.\n\t\tdef text text\n\t\tend\n\t\t# Called when an instruction is encountered.  EG: <?xsl sheet='foo'?>\n\t\t# @p name the instruction name; in the example, \"xsl\"\n\t\t# @p instruction the rest of the instruction.  In the example,\n\t\t# \"sheet='foo'\"\n\t\tdef instruction name, instruction\n\t\tend\n\t\t# Called when a comment is encountered.\n\t\t# @p comment The content of the comment\n\t\tdef comment comment\n\t\tend\n\t\t# Handles a doctype declaration. Any attributes of the doctype which are\n\t\t# not supplied will be nil.  # EG, <!DOCTYPE me PUBLIC \"foo\" \"bar\">\n\t\t# @p name the name of the doctype; EG, \"me\"\n\t\t# @p pub_sys \"PUBLIC\", \"SYSTEM\", or nil.  EG, \"PUBLIC\"\n\t\t# @p long_name the supplied long name, or nil.  EG, \"foo\"\n\t\t# @p uri the uri of the doctype, or nil.  EG, \"bar\"\n\t\tdef doctype name, pub_sys, long_name, uri\n\t\tend\n\t\t# Called when the doctype is done\n\t\tdef doctype_end\n\t\tend\n\t\t# If a doctype includes an ATTLIST declaration, it will cause this\n\t\t# method to be called.  The content is the declaration itself, unparsed.\n\t\t# EG, <!ATTLIST el attr CDATA #REQUIRED> will come to this method as \"el\n\t\t# attr CDATA #REQUIRED\".  This is the same for all of the .*decl\n\t\t# methods.\n\t\tdef attlistdecl element_name, attributes, raw_content\n\t\tend\n\t\t# <!ELEMENT ...>\n\t\tdef elementdecl content\n\t\tend\n\t\t# <!ENTITY ...>\n\t\t# The argument passed to this method is an array of the entity\n\t\t# declaration.  It can be in a number of formats, but in general it\n\t\t# returns (example, result):\n\t\t#  <!ENTITY % YN '\"Yes\"'>  \n\t\t#  [\"%\", \"YN\", \"'\\\"Yes\\\"'\", \"\\\"\"]\n\t\t#  <!ENTITY % YN 'Yes'>\n\t\t#  [\"%\", \"YN\", \"'Yes'\", \"s\"]\n\t\t#  <!ENTITY WhatHeSaid \"He said %YN;\">\n\t\t#  [\"WhatHeSaid\", \"\\\"He said %YN;\\\"\", \"YN\"]\n\t\t#  <!ENTITY open-hatch SYSTEM \"http://www.textuality.com/boilerplate/OpenHatch.xml\">\n\t\t#  [\"open-hatch\", \"SYSTEM\", \"\\\"http://www.textuality.com/boilerplate/OpenHatch.xml\\\"\"]\n\t\t#  <!ENTITY open-hatch PUBLIC \"-//Textuality//TEXT Standard open-hatch boilerplate//EN\" \"http://www.textuality.com/boilerplate/OpenHatch.xml\">\n\t\t#  [\"open-hatch\", \"PUBLIC\", \"\\\"-//Textuality//TEXT Standard open-hatch boilerplate//EN\\\"\", \"\\\"http://www.textuality.com/boilerplate/OpenHatch.xml\\\"\"]\n\t\t#  <!ENTITY hatch-pic SYSTEM \"../grafix/OpenHatch.gif\" NDATA gif>\n\t\t#  [\"hatch-pic\", \"SYSTEM\", \"\\\"../grafix/OpenHatch.gif\\\"\", \"\\n\\t\\t\\t\\t\\t\\t\\tNDATA gif\", \"gif\"]\n\t\tdef entitydecl content\n\t\tend\n\t\t# <!NOTATION ...>\n\t\tdef notationdecl content\n\t\tend\n\t\t# Called when %foo; is encountered in a doctype declaration.\n\t\t# @p content \"foo\"\n\t\tdef entity content\n\t\tend\n\t\t# Called when <![CDATA[ ... ]]> is encountered in a document.\n\t\t# @p content \"...\"\n\t\tdef cdata content\n\t\tend\n\t\t# Called when an XML PI is encountered in the document.\n\t\t# EG: <?xml version=\"1.0\" encoding=\"utf\"?>\n\t\t# @p version the version attribute value.  EG, \"1.0\"\n\t\t# @p encoding the encoding attribute value, or nil.  EG, \"utf\"\n\t\t# @p standalone the standalone attribute value, or nil.  EG, nil\n\t\tdef xmldecl version, encoding, standalone\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/syncenumerator.rb",
    "content": "module REXML\n  class SyncEnumerator\n    include Enumerable\n\n    # Creates a new SyncEnumerator which enumerates rows of given\n    # Enumerable objects.\n    def initialize(*enums)\n      @gens = enums\n      @biggest = @gens[0]\n      @gens.each {|x| @biggest = x if x.size > @biggest.size }\n    end\n\n    # Returns the number of enumerated Enumerable objects, i.e. the size\n    # of each row.\n    def size\n      @gens.size\n    end\n\n    # Returns the number of enumerated Enumerable objects, i.e. the size\n    # of each row.\n    def length\n      @gens.length\n    end\n\n    # Enumerates rows of the Enumerable objects.\n    def each\n      @biggest.zip( *@gens ) {|a|\n        yield(*a[1..-1])\n      }\n      self\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/text.rb",
    "content": "require 'rexml/entity'\nrequire 'rexml/doctype'\nrequire 'rexml/child'\nrequire 'rexml/doctype'\nrequire 'rexml/parseexception'\n\nmodule REXML\n  # Represents text nodes in an XML document\n  class Text < Child\n    include Comparable\n    # The order in which the substitutions occur\n    SPECIALS = [ /&(?!#?[\\w-]+;)/u, /</u, />/u, /\"/u, /'/u, /\\r/u ]\n    SUBSTITUTES = ['&amp;', '&lt;', '&gt;', '&quot;', '&apos;', '&#13;']\n    # Characters which are substituted in written strings\n    SLAICEPS = [ '<', '>', '\"', \"'\", '&' ]\n    SETUTITSBUS = [ /&lt;/u, /&gt;/u, /&quot;/u, /&apos;/u, /&amp;/u ]\n\n    # If +raw+ is true, then REXML leaves the value alone\n    attr_accessor :raw\n\n    ILLEGAL = /(<|&(?!(#{Entity::NAME})|(#0*((?:\\d+)|(?:x[a-fA-F0-9]+)));))/um\n    NUMERICENTITY = /&#0*((?:\\d+)|(?:x[a-fA-F0-9]+));/ \n\n    # Constructor\n    # +arg+ if a String, the content is set to the String.  If a Text,\n    # the object is shallowly cloned.  \n    #\n    # +respect_whitespace+ (boolean, false) if true, whitespace is\n    # respected\n    #\n    # +parent+ (nil) if this is a Parent object, the parent\n    # will be set to this.  \n    #\n    # +raw+ (nil) This argument can be given three values.\n    # If true, then the value of used to construct this object is expected to \n    # contain no unescaped XML markup, and REXML will not change the text. If \n    # this value is false, the string may contain any characters, and REXML will\n    # escape any and all defined entities whose values are contained in the\n    # text.  If this value is nil (the default), then the raw value of the \n    # parent will be used as the raw value for this node.  If there is no raw\n    # value for the parent, and no value is supplied, the default is false.\n    # Use this field if you have entities defined for some text, and you don't\n    # want REXML to escape that text in output.\n    #   Text.new( \"<&\", false, nil, false ) #-> \"&lt;&amp;\"\n    #   Text.new( \"&lt;&amp;\", false, nil, false ) #-> \"&amp;lt;&amp;amp;\"\n    #   Text.new( \"<&\", false, nil, true )  #-> Parse exception\n    #   Text.new( \"&lt;&amp;\", false, nil, true )  #-> \"&lt;&amp;\"\n    #   # Assume that the entity \"s\" is defined to be \"sean\"\n    #   # and that the entity    \"r\" is defined to be \"russell\"\n    #   Text.new( \"sean russell\" )          #-> \"&s; &r;\"\n    #   Text.new( \"sean russell\", false, nil, true ) #-> \"sean russell\"\n    #\n    # +entity_filter+ (nil) This can be an array of entities to match in the\n    # supplied text.  This argument is only useful if +raw+ is set to false.\n    #   Text.new( \"sean russell\", false, nil, false, [\"s\"] ) #-> \"&s; russell\"\n    #   Text.new( \"sean russell\", false, nil, true, [\"s\"] ) #-> \"sean russell\"\n    # In the last example, the +entity_filter+ argument is ignored.\n    #\n    # +pattern+ INTERNAL USE ONLY\n    def initialize(arg, respect_whitespace=false, parent=nil, raw=nil, \n      entity_filter=nil, illegal=ILLEGAL )\n\n      @raw = false\n\n      if parent\n        super( parent )\n        @raw = parent.raw \n      else\n        @parent = nil\n      end\n\n      @raw = raw unless raw.nil?\n      @entity_filter = entity_filter\n      @normalized = @unnormalized = nil\n\n      if arg.kind_of? String\n        @string = arg.clone\n        @string.squeeze!(\" \\n\\t\") unless respect_whitespace\n      elsif arg.kind_of? Text\n        @string = arg.to_s\n        @raw = arg.raw\n      elsif\n        raise \"Illegal argument of type #{arg.type} for Text constructor (#{arg})\"\n      end\n\n      @string.gsub!( /\\r\\n?/, \"\\n\" )\n\n      # check for illegal characters\n      if @raw\n        if @string =~ illegal\n          raise \"Illegal character '#{$1}' in raw string \\\"#{@string}\\\"\"\n        end\n      end\n    end\n\n    def node_type\n      :text\n    end\n\n    def empty?\n      @string.size==0\n    end\n\n\n    def clone\n      return Text.new(self)\n    end\n\n\n    # Appends text to this text node.  The text is appended in the +raw+ mode\n    # of this text node.\n    def <<( to_append )\n      @string << to_append.gsub( /\\r\\n?/, \"\\n\" )\n    end\n\n\n    # +other+ a String or a Text\n    # +returns+ the result of (to_s <=> arg.to_s)\n    def <=>( other )\n      to_s() <=> other.to_s\n    end\n\n    REFERENCE = /#{Entity::REFERENCE}/\n    # Returns the string value of this text node.  This string is always\n    # escaped, meaning that it is a valid XML text node string, and all\n    # entities that can be escaped, have been inserted.  This method respects\n    # the entity filter set in the constructor.\n    #   \n    #   # Assume that the entity \"s\" is defined to be \"sean\", and that the \n    #   # entity \"r\" is defined to be \"russell\"\n    #   t = Text.new( \"< & sean russell\", false, nil, false, ['s'] ) \n    #   t.to_s   #-> \"&lt; &amp; &s; russell\"\n    #   t = Text.new( \"< & &s; russell\", false, nil, false ) \n    #   t.to_s   #-> \"&lt; &amp; &s; russell\"\n    #   u = Text.new( \"sean russell\", false, nil, true )\n    #   u.to_s   #-> \"sean russell\"\n    def to_s\n      return @string if @raw\n      return @normalized if @normalized\n\n      doctype = nil\n      if @parent\n        doc = @parent.document\n        doctype = doc.doctype if doc\n      end\n\n      @normalized = Text::normalize( @string, doctype, @entity_filter )\n    end\n\n    def inspect\n      @string.inspect\n    end\n\n    # Returns the string value of this text.  This is the text without\n    # entities, as it might be used programmatically, or printed to the\n    # console.  This ignores the 'raw' attribute setting, and any\n    # entity_filter.\n    #\n    #   # Assume that the entity \"s\" is defined to be \"sean\", and that the \n    #   # entity \"r\" is defined to be \"russell\"\n    #   t = Text.new( \"< & sean russell\", false, nil, false, ['s'] ) \n    #   t.value   #-> \"< & sean russell\"\n    #   t = Text.new( \"< & &s; russell\", false, nil, false )\n    #   t.value   #-> \"< & sean russell\"\n    #   u = Text.new( \"sean russell\", false, nil, true )\n    #   u.value   #-> \"sean russell\"\n    def value\n      return @unnormalized if @unnormalized\n      doctype = nil\n      if @parent\n        doc = @parent.document\n        doctype = doc.doctype if doc\n      end\n      @unnormalized = Text::unnormalize( @string, doctype )\n    end\n\n    # Sets the contents of this text node.  This expects the text to be \n    # unnormalized.  It returns self.\n    #\n    #   e = Element.new( \"a\" )\n    #   e.add_text( \"foo\" )   # <a>foo</a>\n    #   e[0].value = \"bar\"    # <a>bar</a>\n    #   e[0].value = \"<a>\"    # <a>&lt;a&gt;</a>\n    def value=( val )\n      @string = val.gsub( /\\r\\n?/, \"\\n\" )\n      @unnormalized = nil\n      @normalized = nil\n      @raw = false\n    end\n \n     def wrap(string, width, addnewline=false)\n       # Recursively wrap string at width.\n       return string if string.length <= width\n       place = string.rindex(' ', width) # Position in string with last ' ' before cutoff\n       if addnewline then\n         return \"\\n\" + string[0,place] + \"\\n\" + wrap(string[place+1..-1], width)\n       else\n         return string[0,place] + \"\\n\" + wrap(string[place+1..-1], width)\n       end\n     end\n\n    def indent_text(string, level=1, style=\"\\t\", indentfirstline=true)\n      return string if level < 0\n      new_string = ''\n      string.each { |line|\n        indent_string = style * level\n        new_line = (indent_string + line).sub(/[\\s]+$/,'')\n        new_string << new_line\n      }\n      new_string.strip! unless indentfirstline\n      return new_string\n    end\n \n    # == DEPRECATED\n    # See REXML::Formatters\n    #\n    def write( writer, indent=-1, transitive=false, ie_hack=false ) \n      Kernel.warn(\"#{self.class.name}.write is deprecated.  See REXML::Formatters\")\n      formatter = if indent > -1\n          REXML::Formatters::Pretty.new( indent )\n        else\n          REXML::Formatters::Default.new\n        end\n      formatter.write( self, writer )\n    end\n\n    # FIXME\n    # This probably won't work properly\n    def xpath\n      path = @parent.xpath\n      path += \"/text()\"\n      return path\n    end\n\n    # Writes out text, substituting special characters beforehand.\n    # +out+ A String, IO, or any other object supporting <<( String )\n    # +input+ the text to substitute and the write out\n    #\n    #   z=utf8.unpack(\"U*\")\n    #   ascOut=\"\"\n    #   z.each{|r|\n    #     if r <  0x100\n    #       ascOut.concat(r.chr)\n    #     else\n    #       ascOut.concat(sprintf(\"&#x%x;\", r))\n    #     end\n    #   }\n    #   puts ascOut\n    def write_with_substitution out, input\n      copy = input.clone\n      # Doing it like this rather than in a loop improves the speed\n      copy.gsub!( SPECIALS[0], SUBSTITUTES[0] )\n      copy.gsub!( SPECIALS[1], SUBSTITUTES[1] )\n      copy.gsub!( SPECIALS[2], SUBSTITUTES[2] )\n      copy.gsub!( SPECIALS[3], SUBSTITUTES[3] )\n      copy.gsub!( SPECIALS[4], SUBSTITUTES[4] )\n      copy.gsub!( SPECIALS[5], SUBSTITUTES[5] )\n      out << copy\n    end\n\n    # Reads text, substituting entities\n    def Text::read_with_substitution( input, illegal=nil )\n      copy = input.clone\n\n      if copy =~ illegal\n        raise ParseException.new( \"malformed text: Illegal character #$& in \\\"#{copy}\\\"\" )\n      end if illegal\n      \n      copy.gsub!( /\\r\\n?/, \"\\n\" )\n      if copy.include? ?&\n        copy.gsub!( SETUTITSBUS[0], SLAICEPS[0] )\n        copy.gsub!( SETUTITSBUS[1], SLAICEPS[1] )\n        copy.gsub!( SETUTITSBUS[2], SLAICEPS[2] )\n        copy.gsub!( SETUTITSBUS[3], SLAICEPS[3] )\n        copy.gsub!( SETUTITSBUS[4], SLAICEPS[4] )\n        copy.gsub!( /&#0*((?:\\d+)|(?:x[a-f0-9]+));/ ) {|m|\n          m=$1\n          #m='0' if m==''\n          m = \"0#{m}\" if m[0] == ?x\n          [Integer(m)].pack('U*')\n        }\n      end\n      copy\n    end\n\n    EREFERENCE = /&(?!#{Entity::NAME};)/\n    # Escapes all possible entities\n    def Text::normalize( input, doctype=nil, entity_filter=nil )\n      copy = input.to_s\n      # Doing it like this rather than in a loop improves the speed\n      #copy = copy.gsub( EREFERENCE, '&amp;' )\n      copy = copy.gsub( \"&\", \"&amp;\" )\n      if doctype\n        # Replace all ampersands that aren't part of an entity\n        doctype.entities.each_value do |entity|\n          copy = copy.gsub( entity.value, \n            \"&#{entity.name};\" ) if entity.value and \n              not( entity_filter and entity_filter.include?(entity) )\n        end\n      else\n        # Replace all ampersands that aren't part of an entity\n        DocType::DEFAULT_ENTITIES.each_value do |entity|\n          copy = copy.gsub(entity.value, \"&#{entity.name};\" )\n        end\n      end\n      copy\n    end\n\n    # Unescapes all possible entities\n    def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )\n      rv = string.clone\n      rv.gsub!( /\\r\\n?/, \"\\n\" )\n      matches = rv.scan( REFERENCE )\n      return rv if matches.size == 0\n      rv.gsub!( NUMERICENTITY ) {|m|\n        m=$1\n        m = \"0#{m}\" if m[0] == ?x\n        [Integer(m)].pack('U*')\n      }\n      matches.collect!{|x|x[0]}.compact!\n      if matches.size > 0\n        if doctype\n          matches.each do |entity_reference|\n            unless filter and filter.include?(entity_reference)\n              entity_value = doctype.entity( entity_reference )\n              re = /&#{entity_reference};/\n              rv.gsub!( re, entity_value ) if entity_value\n            end\n          end\n        else\n          matches.each do |entity_reference|\n            unless filter and filter.include?(entity_reference)\n              entity_value = DocType::DEFAULT_ENTITIES[ entity_reference ]\n              re = /&#{entity_reference};/\n              rv.gsub!( re, entity_value.value ) if entity_value\n            end\n          end\n        end\n        rv.gsub!( /&amp;/, '&' )\n      end\n      rv\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/undefinednamespaceexception.rb",
    "content": "require 'rexml/parseexception'\nmodule REXML\n  class UndefinedNamespaceException < ParseException\n    def initialize( prefix, source, parser )\n      super( \"Undefined prefix #{prefix} found\" )\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/validation/relaxng.rb",
    "content": "require \"rexml/validation/validation\"\nrequire \"rexml/parsers/baseparser\"\n\nmodule REXML\n  module Validation\n    # Implemented:\n    # * empty\n    # * element\n    # * attribute\n    # * text\n    # * optional\n    # * choice\n    # * oneOrMore\n    # * zeroOrMore\n    # * group\n    # * value\n    # * interleave\n    # * mixed\n    # * ref\n    # * grammar\n    # * start\n    # * define\n    #\n    # Not implemented:\n    # * data\n    # * param\n    # * include\n    # * externalRef\n    # * notAllowed\n    # * anyName\n    # * nsName\n    # * except\n    # * name\n    class RelaxNG\n      include Validator\n\n      INFINITY = 1.0 / 0.0\n      EMPTY = Event.new( nil )\n      TEXT = [:start_element, \"text\"]\n      attr_accessor :current\n      attr_accessor :count\n      attr_reader :references\n\n      # FIXME: Namespaces\n      def initialize source\n        parser = REXML::Parsers::BaseParser.new( source )\n\n        @count = 0\n        @references = {}\n        @root = @current = Sequence.new(self)\n        @root.previous = true\n        states = [ @current ]\n        begin\n          event = parser.pull\n          case event[0]\n          when :start_element\n            case event[1]\n            when \"empty\"\n            when \"element\", \"attribute\", \"text\", \"value\"\n              states[-1] << event\n            when \"optional\"\n              states << Optional.new( self )\n              states[-2] << states[-1]\n            when \"choice\"\n              states << Choice.new( self )\n              states[-2] << states[-1]\n            when \"oneOrMore\"\n              states << OneOrMore.new( self )\n              states[-2] << states[-1]\n            when \"zeroOrMore\"\n              states << ZeroOrMore.new( self )\n              states[-2] << states[-1]\n            when \"group\"\n              states << Sequence.new( self )\n              states[-2] << states[-1]\n            when \"interleave\"\n              states << Interleave.new( self )\n              states[-2] << states[-1]\n            when \"mixed\"\n              states << Interleave.new( self )\n              states[-2] << states[-1]\n              states[-1] << TEXT \n            when \"define\"\n              states << [ event[2][\"name\"] ]\n            when \"ref\"\n              states[-1] << Ref.new( event[2][\"name\"] )\n            when \"anyName\"\n              states << AnyName.new( self )\n              states[-2] << states[-1]\n            when \"nsName\"\n            when \"except\"\n            when \"name\"\n            when \"data\"\n            when \"param\"\n            when \"include\"\n            when \"grammar\"\n            when \"start\"\n            when \"externalRef\"\n            when \"notAllowed\"\n            end\n          when :end_element\n            case event[1]\n            when \"element\", \"attribute\"\n              states[-1] << event\n            when \"zeroOrMore\", \"oneOrMore\", \"choice\", \"optional\", \n              \"interleave\", \"group\", \"mixed\"\n              states.pop\n            when \"define\"\n              ref = states.pop\n              @references[ ref.shift ] = ref\n            #when \"empty\"\n            end\n          when :end_document\n            states[-1] << event\n          when :text\n            states[-1] << event\n          end\n        end while event[0] != :end_document\n      end\n\n      def receive event\n        validate( event )\n      end\n    end\n\n    class State\n      def initialize( context )\n        @previous = []\n        @events = []\n        @current = 0\n        @count = context.count += 1\n        @references = context.references\n        @value = false\n      end\n\n      def reset\n        return if @current == 0\n        @current = 0\n        @events.each {|s| s.reset if s.kind_of? State }\n      end\n\n      def previous=( previous ) \n        @previous << previous\n      end\n\n      def next( event )\n        #print \"In next with #{event.inspect}.  \"\n        #puts \"Next (#@current) is #{@events[@current]}\"\n        #p @previous\n        return @previous.pop.next( event ) if @events[@current].nil?\n        expand_ref_in( @events, @current ) if @events[@current].class == Ref\n        if ( @events[@current].kind_of? State )\n          @current += 1\n          @events[@current-1].previous = self\n          return @events[@current-1].next( event )\n        end\n        #puts \"Current isn't a state\"\n        if ( @events[@current].matches?(event) )\n          @current += 1\n          if @events[@current].nil?\n            #puts \"#{inspect[0,5]} 1RETURNING #{@previous.inspect[0,5]}\"\n            return @previous.pop\n          elsif @events[@current].kind_of? State\n            @current += 1\n            #puts \"#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}\"\n            @events[@current-1].previous = self\n            return @events[@current-1]\n          else\n            #puts \"#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}\"\n            return self\n          end\n        else\n          return nil\n        end\n      end\n\n      def to_s\n        # Abbreviated:\n        self.class.name =~ /(?:::)(\\w)\\w+$/\n        # Full:\n        #self.class.name =~ /(?:::)(\\w+)$/\n        \"#$1.#@count\"\n      end\n\n      def inspect\n        \"< #{to_s} #{@events.collect{|e| \n          pre = e == @events[@current] ? '#' : ''\n          pre + e.inspect unless self == e\n        }.join(', ')} >\"\n      end\n\n      def expected\n        return [@events[@current]]\n      end\n\n      def <<( event )\n        add_event_to_arry( @events, event )\n      end\n\n\n      protected\n      def expand_ref_in( arry, ind )\n        new_events = []\n        @references[ arry[ind].to_s ].each{ |evt| \n          add_event_to_arry(new_events,evt)\n        }\n        arry[ind,1] = new_events\n      end\n\n      def add_event_to_arry( arry, evt ) \n        evt = generate_event( evt )\n        if evt.kind_of? String \n          arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value\n          @value = false\n        else\n          arry << evt\n        end\n      end\n\n      def generate_event( event )\n        return event if event.kind_of? State or event.class == Ref\n        evt = nil\n        arg = nil\n        case event[0]\n        when :start_element\n          case event[1]\n          when \"element\"\n            evt = :start_element\n            arg = event[2][\"name\"]\n          when \"attribute\"\n            evt = :start_attribute\n            arg = event[2][\"name\"]\n          when \"text\"\n            evt = :text\n          when \"value\"\n            evt = :text\n            @value = true\n          end\n        when :text\n          return event[1]\n        when :end_document\n          return Event.new( event[0] )\n        else # then :end_element\n          case event[1]\n          when \"element\"\n            evt = :end_element\n          when \"attribute\"\n            evt = :end_attribute\n          end\n        end\n        return Event.new( evt, arg )\n      end\n    end\n\n\n    class Sequence < State\n      def matches?(event)\n        @events[@current].matches?( event )\n      end\n    end\n\n\n    class Optional < State\n      def next( event )\n        if @current == 0\n          rv = super\n          return rv if rv\n          @prior = @previous.pop\n          return @prior.next( event )\n        end\n        super\n      end\n\n      def matches?(event)\n        @events[@current].matches?(event) || \n        (@current == 0 and @previous[-1].matches?(event))\n      end\n\n      def expected\n        return [ @prior.expected, @events[0] ].flatten if @current == 0\n        return [@events[@current]]\n      end\n    end\n\n\n    class ZeroOrMore < Optional\n      def next( event )\n        expand_ref_in( @events, @current ) if @events[@current].class == Ref\n        if ( @events[@current].matches?(event) )\n          @current += 1\n          if @events[@current].nil?\n            @current = 0\n            return self\n          elsif @events[@current].kind_of? State\n            @current += 1\n            @events[@current-1].previous = self\n            return @events[@current-1]\n          else\n            return self\n          end\n        else\n          @prior = @previous.pop\n          return @prior.next( event ) if @current == 0\n          return nil\n        end\n      end\n\n      def expected\n        return [ @prior.expected, @events[0] ].flatten if @current == 0\n        return [@events[@current]]\n      end\n    end\n\n\n    class OneOrMore < State\n      def initialize context\n        super\n        @ord = 0\n      end\n\n      def reset\n        super \n        @ord = 0\n      end\n\n      def next( event )\n        expand_ref_in( @events, @current ) if @events[@current].class == Ref\n        if ( @events[@current].matches?(event) )\n          @current += 1\n          @ord += 1\n          if @events[@current].nil?\n            @current = 0\n            return self\n          elsif @events[@current].kind_of? State\n            @current += 1\n            @events[@current-1].previous = self\n            return @events[@current-1]\n          else\n            return self\n          end\n        else\n          return @previous.pop.next( event ) if @current == 0 and @ord > 0\n          return nil\n        end\n      end\n\n      def matches?( event )\n        @events[@current].matches?(event) || \n        (@current == 0 and @ord > 0 and @previous[-1].matches?(event))\n      end\n\n      def expected\n        if @current == 0 and @ord > 0\n          return [@previous[-1].expected, @events[0]].flatten\n        else\n          return [@events[@current]]\n        end\n      end\n    end\n\n\n    class Choice < State\n      def initialize context\n        super\n        @choices = []\n      end\n\n      def reset\n        super\n        @events = []\n        @choices.each { |c| c.each { |s| s.reset if s.kind_of? State } }\n      end\n\n      def <<( event )\n        add_event_to_arry( @choices, event )\n      end\n\n      def next( event )\n        # Make the choice if we haven't\n        if @events.size == 0\n          c = 0 ; max = @choices.size\n          while c < max\n            if @choices[c][0].class == Ref\n              expand_ref_in( @choices[c], 0 )\n              @choices += @choices[c]\n              @choices.delete( @choices[c] )\n              max -= 1\n            else\n              c += 1\n            end\n          end\n          @events = @choices.find { |evt| evt[0].matches? event }\n          # Remove the references\n          # Find the events\n        end\n        #puts \"In next with #{event.inspect}.\"\n        #puts \"events is #{@events.inspect}\"\n        unless @events\n          @events = []\n          return nil\n        end\n        #puts \"current = #@current\"\n        super\n      end\n\n      def matches?( event )\n        return @events[@current].matches?( event ) if @events.size > 0\n        !@choices.find{|evt| evt[0].matches?(event)}.nil?\n      end\n\n      def expected\n        #puts \"IN CHOICE EXPECTED\"\n        #puts \"EVENTS = #{@events.inspect}\"\n        return [@events[@current]] if @events.size > 0\n        return @choices.collect do |x| \n          if x[0].kind_of? State\n            x[0].expected\n          else\n            x[0]\n          end\n        end.flatten\n      end\n\n      def inspect\n        \"< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >\"\n      end\n\n      protected\n      def add_event_to_arry( arry, evt ) \n        if evt.kind_of? State or evt.class == Ref\n          arry << [evt]\n        elsif evt[0] == :text \n         if arry[-1] and\n            arry[-1][-1].kind_of?( Event ) and \n            arry[-1][-1].event_type == :text and @value\n\n            arry[-1][-1].event_arg = evt[1]\n            @value = false\n          end\n        else\n          arry << [] if evt[0] == :start_element\n          arry[-1] << generate_event( evt )\n        end\n      end\n    end\n\n\n    class Interleave < Choice\n      def initialize context\n        super\n        @choice = 0\n      end\n\n      def reset\n        @choice = 0\n      end\n\n      def next_current( event )\n        # Expand references\n        c = 0 ; max = @choices.size\n        while c < max\n          if @choices[c][0].class == Ref\n            expand_ref_in( @choices[c], 0 )\n            @choices += @choices[c]\n            @choices.delete( @choices[c] )\n            max -= 1\n          else\n            c += 1\n          end\n        end\n        @events = @choices[@choice..-1].find { |evt| evt[0].matches? event }\n        @current = 0\n        if @events\n          # reorder the choices\n          old = @choices[@choice]\n          idx = @choices.index( @events )\n          @choices[@choice] = @events\n          @choices[idx] = old\n          @choice += 1\n        end\n        \n       #puts \"In next with #{event.inspect}.\"\n       #puts \"events is #{@events.inspect}\"\n        @events = [] unless @events\n      end\n\n\n      def next( event )\n        # Find the next series\n        next_current(event) unless @events[@current]\n        return nil unless @events[@current]\n\n        expand_ref_in( @events, @current ) if @events[@current].class == Ref \n       #puts \"In next with #{event.inspect}.\"\n       #puts \"Next (#@current) is #{@events[@current]}\"\n        if ( @events[@current].kind_of? State )\n          @current += 1\n          @events[@current-1].previous = self\n          return @events[@current-1].next( event )\n        end\n       #puts \"Current isn't a state\"\n        return @previous.pop.next( event ) if @events[@current].nil?\n        if ( @events[@current].matches?(event) )\n          @current += 1\n          if @events[@current].nil?\n           #puts \"#{inspect[0,5]} 1RETURNING self\" unless @choices[@choice].nil?\n            return self unless @choices[@choice].nil?\n           #puts \"#{inspect[0,5]} 1RETURNING #{@previous[-1].inspect[0,5]}\"\n            return @previous.pop\n          elsif @events[@current].kind_of? State\n            @current += 1\n           #puts \"#{inspect[0,5]} 2RETURNING (#{@current-1}) #{@events[@current-1].inspect[0,5]}; on return, next is #{@events[@current]}\"\n            @events[@current-1].previous = self\n            return @events[@current-1]\n          else\n           #puts \"#{inspect[0,5]} RETURNING self w/ next(#@current) = #{@events[@current]}\"\n            return self\n          end\n        else\n          return nil\n        end\n      end\n\n      def matches?( event )\n        return @events[@current].matches?( event ) if @events[@current]\n        !@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil?\n      end\n\n      def expected\n        #puts \"IN CHOICE EXPECTED\"\n        #puts \"EVENTS = #{@events.inspect}\"\n        return [@events[@current]] if @events[@current]\n        return @choices[@choice..-1].collect do |x| \n          if x[0].kind_of? State\n            x[0].expected\n          else\n            x[0]\n          end\n        end.flatten\n      end\n\n      def inspect\n        \"< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >\"\n      end\n    end\n\n    class Ref\n      def initialize value\n        @value = value\n      end\n      def to_s\n        @value\n      end\n      def inspect\n        \"{#{to_s}}\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/validation/validation.rb",
    "content": "require 'rexml/validation/validationexception'\n\nmodule REXML\n  module Validation\n    module Validator\n      NILEVENT = [ nil ]\n      def reset\n        @current = @root\n        @root.reset\n        @root.previous = true\n        @attr_stack = []\n        self\n      end\n      def dump\n        puts @root.inspect\n      end\n      def validate( event ) \n        #puts \"Current: #@current\"\n        #puts \"Event: #{event.inspect}\"\n        @attr_stack = [] unless defined? @attr_stack\n        match = @current.next(event)\n        raise ValidationException.new( \"Validation error.  Expected: \"+\n          @current.expected.join( \" or \" )+\" from #{@current.inspect} \"+\n          \" but got #{Event.new( event[0], event[1] ).inspect}\" ) unless match\n        @current = match\n\n        # Check for attributes\n        case event[0]\n        when :start_element\n          #puts \"Checking attributes\"\n          @attr_stack << event[2]\n          begin\n            sattr = [:start_attribute, nil]\n            eattr = [:end_attribute]\n            text = [:text, nil]\n            k,v = event[2].find { |k,v| \n              sattr[1] = k\n              #puts \"Looking for #{sattr.inspect}\"\n              m = @current.next( sattr )\n              #puts \"Got #{m.inspect}\"\n              if m \n                # If the state has text children...\n                #puts \"Looking for #{eattr.inspect}\"\n                #puts \"Expect #{m.expected}\"\n                if m.matches?( eattr )\n                  #puts \"Got end\"\n                  @current = m\n                else\n                  #puts \"Didn't get end\"\n                  text[1] = v\n                  #puts \"Looking for #{text.inspect}\"\n                  m = m.next( text )\n                  #puts \"Got #{m.inspect}\"\n                  text[1] = nil\n                  return false unless m\n                  @current = m if m\n                end\n                m = @current.next( eattr )\n                if m\n                  @current = m\n                  true\n                else\n                  false\n                end\n              else\n                false\n              end\n            }\n            event[2].delete(k) if k\n          end while k\n        when :end_element\n          attrs = @attr_stack.pop\n          raise ValidationException.new( \"Validation error.  Illegal \"+\n            \" attributes: #{attrs.inspect}\") if attrs.length > 0\n        end\n      end\n    end\n\n    class Event\n      def initialize(event_type, event_arg=nil )\n        @event_type = event_type\n        @event_arg = event_arg\n      end\n\n      attr_reader :event_type\n      attr_accessor :event_arg\n\n      def done?\n        @done\n      end\n\n      def single?\n        return (@event_type != :start_element and @event_type != :start_attribute)\n      end\n\n      def matches?( event )\n        #puts \"#@event_type =? #{event[0]} && #@event_arg =? #{event[1]} \"\n        return false unless event[0] == @event_type\n        case event[0]\n        when nil\n          return true\n        when :start_element\n          return true if event[1] == @event_arg\n        when :end_element\n          return true\n        when :start_attribute\n          return true if event[1] == @event_arg\n        when :end_attribute\n          return true\n        when :end_document\n          return true\n        when :text\n          return (@event_arg.nil? or @event_arg == event[1])\n=begin\n        when :processing_instruction\n          false\n        when :xmldecl\n          false\n        when :start_doctype\n          false\n        when :end_doctype\n          false\n        when :externalentity\n          false\n        when :elementdecl\n          false\n        when :entity\n          false\n        when :attlistdecl\n          false\n        when :notationdecl\n          false\n        when :end_doctype\n          false\n=end\n        else\n          false\n        end\n      end\n\n      def ==( other )\n        return false unless other.kind_of? Event\n        @event_type == other.event_type and @event_arg == other.event_arg\n      end\n\n      def to_s\n        inspect\n      end\n\n      def inspect\n        \"#{@event_type.inspect}( #@event_arg )\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/validation/validationexception.rb",
    "content": "module REXML\n  module Validation\n    class ValidationException < RuntimeError\n      def initialize msg\n        super\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rexml/xmldecl.rb",
    "content": "require 'rexml/encoding'\nrequire 'rexml/source'\n\nmodule REXML\n\t# NEEDS DOCUMENTATION\n\tclass XMLDecl < Child\n\t\tinclude Encoding\n\n\t\tDEFAULT_VERSION = \"1.0\";\n\t\tDEFAULT_ENCODING = \"UTF-8\";\n\t\tDEFAULT_STANDALONE = \"no\";\n\t\tSTART = '<\\?xml';\n\t\tSTOP = '\\?>';\n\n\t\tattr_accessor :version, :standalone\n    attr_reader :writeencoding, :writethis\n\n\t\tdef initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)\n      @writethis = true\n      @writeencoding = !encoding.nil?\n\t\t\tif version.kind_of? XMLDecl\n\t\t\t\tsuper()\n\t\t\t\t@version = version.version\n\t\t\t\tself.encoding = version.encoding\n        @writeencoding = version.writeencoding\n\t\t\t\t@standalone = version.standalone\n\t\t\telse\n\t\t\t\tsuper()\n\t\t\t\t@version = version\n\t\t\t\tself.encoding = encoding\n\t\t\t\t@standalone = standalone\n\t\t\tend\n\t\t\t@version = DEFAULT_VERSION if @version.nil?\n\t\tend\n\n\t\tdef clone\n\t\t\tXMLDecl.new(self)\n\t\tend\n\n    # indent::\n    #   Ignored.  There must be no whitespace before an XML declaration\n    # transitive::\n    #   Ignored\n    # ie_hack::\n    #   Ignored\n\t\tdef write(writer, indent=-1, transitive=false, ie_hack=false)\n      return nil unless @writethis or writer.kind_of? Output\n\t\t\twriter << START.sub(/\\\\/u, '')\n      if writer.kind_of? Output\n        writer << \" #{content writer.encoding}\"\n      else\n        writer << \" #{content encoding}\"\n      end\n\t\t\twriter << STOP.sub(/\\\\/u, '')\n\t\tend\n\n\t\tdef ==( other )\n\t\t  other.kind_of?(XMLDecl) and\n\t\t  other.version == @version and\n\t\t  other.encoding == self.encoding and\n\t\t  other.standalone == @standalone\n\t\tend\n\n\t\tdef xmldecl version, encoding, standalone\n\t\t\t@version = version\n\t\t\tself.encoding = encoding\n\t\t\t@standalone = standalone\n\t\tend\n\n\t\tdef node_type\n\t\t\t:xmldecl\n\t\tend\n\n\t\talias :stand_alone? :standalone\n    alias :old_enc= :encoding=\n\n    def encoding=( enc )\n      if enc.nil?\n        self.old_enc = \"UTF-8\"\n        @writeencoding = false\n      else\n        self.old_enc = enc\n        @writeencoding = true\n      end\n      self.dowrite\n    end\n\n    # Only use this if you do not want the XML declaration to be written;\n    # this object is ignored by the XML writer.  Otherwise, instantiate your\n    # own XMLDecl and add it to the document.\n    #\n    # Note that XML 1.1 documents *must* include an XML declaration\n    def XMLDecl.default\n      rv = XMLDecl.new( \"1.0\" )\n      rv.nowrite\n      rv\n    end\n\n    def nowrite\n      @writethis = false\n    end\n\n    def dowrite\n      @writethis = true\n    end\n\n    def inspect\n      START.sub(/\\\\/u, '') + \" ... \" + STOP.sub(/\\\\/u, '')\n    end\n\n\t\tprivate\n\t\tdef content(enc)\n\t\t\trv = \"version='#@version'\"\n\t\t\trv << \" encoding='#{enc}'\" if @writeencoding || enc !~ /utf-8/i\n\t\t\trv << \" standalone='#@standalone'\" if @standalone\n\t\t\trv\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/xmltokens.rb",
    "content": "module REXML\n\t# Defines a number of tokens used for parsing XML.  Not for general\n\t# consumption.\n\tmodule XMLTokens\n\t\tNCNAME_STR= '[\\w:][\\-\\w\\d.]*'\n\t\tNAME_STR= \"(?:#{NCNAME_STR}:)?#{NCNAME_STR}\"\n\n\t\tNAMECHAR = '[\\-\\w\\d\\.:]'\n\t\tNAME = \"([\\\\w:]#{NAMECHAR}*)\"\n\t\tNMTOKEN = \"(?:#{NAMECHAR})+\"\n\t\tNMTOKENS = \"#{NMTOKEN}(\\\\s+#{NMTOKEN})*\"\n\t\tREFERENCE = \"(?:&#{NAME};|&#\\\\d+;|&#x[0-9a-fA-F]+;)\"\n\n\t\t#REFERENCE = \"(?:#{ENTITYREF}|#{CHARREF})\"\n\t\t#ENTITYREF = \"&#{NAME};\"\n\t\t#CHARREF = \"&#\\\\d+;|&#x[0-9a-fA-F]+;\"\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/xpath.rb",
    "content": "require 'rexml/functions'\nrequire 'rexml/xpath_parser'\n\nmodule REXML\n\t# Wrapper class.  Use this class to access the XPath functions.\n\tclass XPath\n\t\tinclude Functions\n\t\tEMPTY_HASH = {}\n\n\t\t# Finds and returns the first node that matches the supplied xpath.\n\t\t# element::\n\t\t# \tThe context element\n\t\t# path::\n\t\t# \tThe xpath to search for.  If not supplied or nil, returns the first\n\t\t# \tnode matching '*'.\n\t\t# namespaces::\n\t\t# \tIf supplied, a Hash which defines a namespace mapping.\n\t\t#\n\t\t#  XPath.first( node )\n\t\t#  XPath.first( doc, \"//b\"} )\n\t\t#  XPath.first( node, \"a/x:b\", { \"x\"=>\"http://doofus\" } )\n    def XPath::first element, path=nil, namespaces=nil, variables={}\n      raise \"The namespaces argument, if supplied, must be a hash object.\" unless namespaces.nil? or namespaces.kind_of?(Hash)\n      raise \"The variables argument, if supplied, must be a hash object.\" unless variables.kind_of?(Hash)\n\t\t\tparser = XPathParser.new\n\t\t\tparser.namespaces = namespaces\n\t\t\tparser.variables = variables\n\t\t\tpath = \"*\" unless path\n\t\t\telement = [element] unless element.kind_of? Array\n\t\t\tparser.parse(path, element).flatten[0]\n\t\tend\n\n\t\t# Iterates over nodes that match the given path, calling the supplied\n\t\t# block with the match.\n\t\t# element::\n\t\t#   The context element\n\t\t# path::\n\t\t#   The xpath to search for.  If not supplied or nil, defaults to '*'\n\t\t# namespaces::\n\t\t# \tIf supplied, a Hash which defines a namespace mapping\n\t\t#\n\t\t#  XPath.each( node ) { |el| ... }\n\t\t#  XPath.each( node, '/*[@attr='v']' ) { |el| ... }\n\t\t#  XPath.each( node, 'ancestor::x' ) { |el| ... }\n\t\tdef XPath::each element, path=nil, namespaces=nil, variables={}, &block\n      raise \"The namespaces argument, if supplied, must be a hash object.\" unless namespaces.nil? or namespaces.kind_of?(Hash)\n      raise \"The variables argument, if supplied, must be a hash object.\" unless variables.kind_of?(Hash)\n\t\t\tparser = XPathParser.new\n\t\t\tparser.namespaces = namespaces\n\t\t\tparser.variables = variables\n\t\t\tpath = \"*\" unless path\n\t\t\telement = [element] unless element.kind_of? Array\n\t\t\tparser.parse(path, element).each( &block )\n\t\tend\n\n\t\t# Returns an array of nodes matching a given XPath.  \n\t\tdef XPath::match element, path=nil, namespaces=nil, variables={}\n\t\t\tparser = XPathParser.new\n\t\t\tparser.namespaces = namespaces\n\t\t\tparser.variables = variables\n\t\t\tpath = \"*\" unless path\n\t\t\telement = [element] unless element.kind_of? Array\n\t\t\tparser.parse(path,element)\n\t\tend\n\tend\nend\n"
  },
  {
    "path": "lib/rexml/xpath_parser.rb",
    "content": "require 'rexml/namespace'\nrequire 'rexml/xmltokens'\nrequire 'rexml/attribute'\nrequire 'rexml/syncenumerator'\nrequire 'rexml/parsers/xpathparser'\n\nclass Object\n  def dclone\n    clone\n  end\nend\nclass Symbol\n  def dclone ; self ; end\nend\nclass Fixnum\n  def dclone ; self ; end\nend\nclass Float\n  def dclone ; self ; end\nend\nclass Array\n  def dclone\n    klone = self.clone\n    klone.clear\n    self.each{|v| klone << v.dclone}\n    klone\n  end\nend\n\nmodule REXML\n  # You don't want to use this class.  Really.  Use XPath, which is a wrapper\n  # for this class.  Believe me.  You don't want to poke around in here.\n  # There is strange, dark magic at work in this code.  Beware.  Go back!  Go\n  # back while you still can!\n  class XPathParser\n    include XMLTokens\n    LITERAL    = /^'([^']*)'|^\"([^\"]*)\"/u\n\n    def initialize( )\n      @parser = REXML::Parsers::XPathParser.new\n      @namespaces = nil\n      @variables = {}\n    end\n\n    def namespaces=( namespaces={} )\n      Functions::namespace_context = namespaces\n      @namespaces = namespaces\n    end\n\n    def variables=( vars={} )\n      Functions::variables = vars\n      @variables = vars\n    end\n\n    def parse path, nodeset\n     #puts \"#\"*40\n     path_stack = @parser.parse( path )\n     #puts \"PARSE: #{path} => #{path_stack.inspect}\"\n     #puts \"PARSE: nodeset = #{nodeset.inspect}\"\n     match( path_stack, nodeset )\n    end\n\n    def get_first path, nodeset\n     #puts \"#\"*40\n     path_stack = @parser.parse( path )\n     #puts \"PARSE: #{path} => #{path_stack.inspect}\"\n     #puts \"PARSE: nodeset = #{nodeset.inspect}\"\n     first( path_stack, nodeset )\n    end\n\n    def predicate path, nodeset\n      path_stack = @parser.parse( path )\n      expr( path_stack, nodeset )\n    end\n\n    def []=( variable_name, value )\n      @variables[ variable_name ] = value\n    end\n\n\n    # Performs a depth-first (document order) XPath search, and returns the\n    # first match.  This is the fastest, lightest way to return a single result.\n    #\n    # FIXME: This method is incomplete!\n    def first( path_stack, node )\n      #puts \"#{depth}) Entering match( #{path.inspect}, #{tree.inspect} )\"\n      return nil if path.size == 0\n\n      case path[0]\n      when :document\n        # do nothing \n        return first( path[1..-1], node )\n      when :child\n        for c in node.children\n          #puts \"#{depth}) CHILD checking #{name(c)}\"\n          r = first( path[1..-1], c )\n          #puts \"#{depth}) RETURNING #{r.inspect}\" if r\n          return r if r\n        end\n      when :qname\n        name = path[2]\n        #puts \"#{depth}) QNAME #{name(tree)} == #{name} (path => #{path.size})\"\n        if node.name == name\n          #puts \"#{depth}) RETURNING #{tree.inspect}\" if path.size == 3\n          return node if path.size == 3\n          return first( path[3..-1], node )\n        else\n          return nil\n        end\n      when :descendant_or_self\n        r = first( path[1..-1], node )\n        return r if r\n        for c in node.children\n          r = first( path, c )\n          return r if r\n        end\n      when :node\n        return first( path[1..-1], node )\n      when :any\n        return first( path[1..-1], node )\n      end\n      return nil\n    end\n\n\n    def match( path_stack, nodeset ) \n      #puts \"MATCH: path_stack = #{path_stack.inspect}\"\n      #puts \"MATCH: nodeset = #{nodeset.inspect}\"\n      r = expr( path_stack, nodeset )\n      #puts \"MAIN EXPR => #{r.inspect}\"\n      r\n    end\n\n    private\n\n\n    # Returns a String namespace for a node, given a prefix\n    # The rules are:\n    # \n    #  1. Use the supplied namespace mapping first.\n    #  2. If no mapping was supplied, use the context node to look up the namespace\n    def get_namespace( node, prefix )\n      if @namespaces\n        return @namespaces[prefix] || ''\n      else\n        return node.namespace( prefix ) if node.node_type == :element\n        return ''\n      end\n    end\n\n\n    # Expr takes a stack of path elements and a set of nodes (either a Parent\n    # or an Array and returns an Array of matching nodes\n    ALL = [ :attribute, :element, :text, :processing_instruction, :comment ]\n    ELEMENTS = [ :element ]\n    def expr( path_stack, nodeset, context=nil )\n      #puts \"#\"*15\n      #puts \"In expr with #{path_stack.inspect}\"\n      #puts \"Returning\" if path_stack.length == 0 || nodeset.length == 0\n      node_types = ELEMENTS\n      return nodeset if path_stack.length == 0 || nodeset.length == 0\n      while path_stack.length > 0\n        #puts \"#\"*5\n        #puts \"Path stack = #{path_stack.inspect}\"\n        #puts \"Nodeset is #{nodeset.inspect}\"\n        if nodeset.length == 0\n          path_stack.clear\n          return []\n        end\n        case (op = path_stack.shift)\n        when :document\n          nodeset = [ nodeset[0].root_node ]\n          #puts \":document, nodeset = #{nodeset.inspect}\"\n\n        when :qname\n          #puts \"IN QNAME\"\n          prefix = path_stack.shift\n          name = path_stack.shift\n          nodeset.delete_if do |node|\n            # FIXME: This DOUBLES the time XPath searches take\n            ns = get_namespace( node, prefix )\n            #puts \"NS = #{ns.inspect}\"\n            #puts \"node.node_type == :element => #{node.node_type == :element}\"\n            if node.node_type == :element\n              #puts \"node.name == #{name} => #{node.name == name}\"\n              if node.name == name\n                #puts \"node.namespace == #{ns.inspect} => #{node.namespace == ns}\"\n              end\n            end\n            !(node.node_type == :element and \n              node.name == name and \n              node.namespace == ns )\n          end\n          node_types = ELEMENTS\n\n        when :any\n          #puts \"ANY 1: nodeset = #{nodeset.inspect}\"\n          #puts \"ANY 1: node_types = #{node_types.inspect}\"\n          nodeset.delete_if { |node| !node_types.include?(node.node_type) }\n          #puts \"ANY 2: nodeset = #{nodeset.inspect}\"\n\n        when :self\n          # This space left intentionally blank\n\n        when :processing_instruction\n          target = path_stack.shift\n          nodeset.delete_if do |node|\n            (node.node_type != :processing_instruction) or \n            ( target!='' and ( node.target != target ) )\n          end\n\n        when :text\n          nodeset.delete_if { |node| node.node_type != :text }\n\n        when :comment\n          nodeset.delete_if { |node| node.node_type != :comment }\n\n        when :node\n          # This space left intentionally blank\n          node_types = ALL\n\n        when :child\n          new_nodeset = []\n          nt = nil\n          for node in nodeset\n            nt = node.node_type\n            new_nodeset += node.children if nt == :element or nt == :document\n          end\n          nodeset = new_nodeset\n          node_types = ELEMENTS\n\n        when :literal\n          return path_stack.shift\n        \n        when :attribute\n          new_nodeset = []\n          case path_stack.shift\n          when :qname\n            prefix = path_stack.shift\n            name = path_stack.shift\n            for element in nodeset\n              if element.node_type == :element\n                #puts \"Element name = #{element.name}\"\n                #puts \"get_namespace( #{element.inspect}, #{prefix} ) = #{get_namespace(element, prefix)}\"\n                attrib = element.attribute( name, get_namespace(element, prefix) )\n                #puts \"attrib = #{attrib.inspect}\"\n                new_nodeset << attrib if attrib\n              end\n            end\n          when :any\n            #puts \"ANY\"\n            for element in nodeset\n              if element.node_type == :element\n                new_nodeset += element.attributes.to_a\n              end\n            end\n          end\n          nodeset = new_nodeset\n\n        when :parent\n          #puts \"PARENT 1: nodeset = #{nodeset}\"\n          nodeset = nodeset.collect{|n| n.parent}.compact\n          #nodeset = expr(path_stack.dclone, nodeset.collect{|n| n.parent}.compact)\n          #puts \"PARENT 2: nodeset = #{nodeset.inspect}\"\n          node_types = ELEMENTS\n\n        when :ancestor\n          new_nodeset = []\n          for node in nodeset\n            while node.parent\n              node = node.parent\n              new_nodeset << node unless new_nodeset.include? node\n            end\n          end\n          nodeset = new_nodeset\n          node_types = ELEMENTS\n\n        when :ancestor_or_self\n          new_nodeset = []\n          for node in nodeset\n            if node.node_type == :element\n              new_nodeset << node\n              while ( node.parent )\n                node = node.parent\n                new_nodeset << node unless new_nodeset.include? node\n              end\n            end\n          end\n          nodeset = new_nodeset\n          node_types = ELEMENTS\n\n        when :predicate\n          new_nodeset = []\n          subcontext = { :size => nodeset.size }\n          pred = path_stack.shift\n          nodeset.each_with_index { |node, index|\n            subcontext[ :node ] = node\n            #puts \"PREDICATE SETTING CONTEXT INDEX TO #{index+1}\"\n            subcontext[ :index ] = index+1\n            pc = pred.dclone\n            #puts \"#{node.hash}) Recursing with #{pred.inspect} and [#{node.inspect}]\"\n            result = expr( pc, [node], subcontext )\n            result = result[0] if result.kind_of? Array and result.length == 1\n            #puts \"#{node.hash}) Result = #{result.inspect} (#{result.class.name})\"\n            if result.kind_of? Numeric\n              #puts \"Adding node #{node.inspect}\" if result == (index+1)\n              new_nodeset << node if result == (index+1)\n            elsif result.instance_of? Array\n              if result.size > 0 and result.inject(false) {|k,s| s or k}\n                #puts \"Adding node #{node.inspect}\" if result.size > 0\n                new_nodeset << node if result.size > 0\n              end\n            else\n              #puts \"Adding node #{node.inspect}\" if result\n              new_nodeset << node if result\n            end\n          }\n          #puts \"New nodeset = #{new_nodeset.inspect}\"\n          #puts \"Path_stack  = #{path_stack.inspect}\"\n          nodeset = new_nodeset\n=begin\n          predicate = path_stack.shift\n          ns = nodeset.clone\n          result = expr( predicate, ns )\n          #puts \"Result = #{result.inspect} (#{result.class.name})\"\n          #puts \"nodeset = #{nodeset.inspect}\"\n          if result.kind_of? Array\n            nodeset = result.zip(ns).collect{|m,n| n if m}.compact\n          else\n            nodeset = result ? nodeset : []\n          end\n          #puts \"Outgoing NS = #{nodeset.inspect}\"\n=end\n\n        when :descendant_or_self\n          rv = descendant_or_self( path_stack, nodeset )\n          path_stack.clear\n          nodeset = rv\n          node_types = ELEMENTS\n\n        when :descendant\n          results = []\n          nt = nil\n          for node in nodeset\n            nt = node.node_type\n            results += expr( path_stack.dclone.unshift( :descendant_or_self ),\n              node.children ) if nt == :element or nt == :document\n          end\n          nodeset = results\n          node_types = ELEMENTS\n\n        when :following_sibling\n          #puts \"FOLLOWING_SIBLING 1: nodeset = #{nodeset}\"\n          results = []\n          nodeset.each do |node|\n            next if node.parent.nil?\n            all_siblings = node.parent.children\n            current_index = all_siblings.index( node )\n            following_siblings = all_siblings[ current_index+1 .. -1 ]\n            results += expr( path_stack.dclone, following_siblings )\n          end\n          #puts \"FOLLOWING_SIBLING 2: nodeset = #{nodeset}\"\n          nodeset = results\n\n        when :preceding_sibling\n          results = []\n          nodeset.each do |node|\n            next if node.parent.nil?\n            all_siblings = node.parent.children\n            current_index = all_siblings.index( node )\n            preceding_siblings = all_siblings[ 0, current_index ].reverse\n            results += preceding_siblings\n          end\n          nodeset = results\n          node_types = ELEMENTS\n\n        when :preceding\n          new_nodeset = []\n          for node in nodeset\n            new_nodeset += preceding( node )\n          end\n          #puts \"NEW NODESET => #{new_nodeset.inspect}\"\n          nodeset = new_nodeset\n          node_types = ELEMENTS\n\n        when :following\n          new_nodeset = []\n          for node in nodeset\n            new_nodeset += following( node )\n          end\n          nodeset = new_nodeset\n          node_types = ELEMENTS\n\n        when :namespace\n          #puts \"In :namespace\"\n          new_nodeset = []\n          prefix = path_stack.shift\n          for node in nodeset\n            if (node.node_type == :element or node.node_type == :attribute)\n              if @namespaces\n                namespaces = @namespaces\n              elsif (node.node_type == :element)\n                namespaces = node.namespaces\n              else\n                namespaces = node.element.namesapces\n              end\n              #puts \"Namespaces = #{namespaces.inspect}\"\n              #puts \"Prefix = #{prefix.inspect}\"\n              #puts \"Node.namespace = #{node.namespace}\"\n              if (node.namespace == namespaces[prefix])\n                new_nodeset << node\n              end\n            end\n          end\n          nodeset = new_nodeset\n\n        when :variable\n          var_name = path_stack.shift\n          return @variables[ var_name ]\n\n        # :and, :or, :eq, :neq, :lt, :lteq, :gt, :gteq\n\t\t\t\t# TODO: Special case for :or and :and -- not evaluate the right\n\t\t\t\t# operand if the left alone determines result (i.e. is true for\n\t\t\t\t# :or and false for :and).\n        when :eq, :neq, :lt, :lteq, :gt, :gteq, :and, :or\n          left = expr( path_stack.shift, nodeset.dup, context )\n          #puts \"LEFT => #{left.inspect} (#{left.class.name})\"\n          right = expr( path_stack.shift, nodeset.dup, context )\n          #puts \"RIGHT => #{right.inspect} (#{right.class.name})\"\n          res = equality_relational_compare( left, op, right )\n          #puts \"RES => #{res.inspect}\"\n          return res\n\n        when :and\n          left = expr( path_stack.shift, nodeset.dup, context )\n          #puts \"LEFT => #{left.inspect} (#{left.class.name})\"\n          if left == false || left.nil? || !left.inject(false) {|a,b| a | b}\n            return []\n          end\n          right = expr( path_stack.shift, nodeset.dup, context )\n          #puts \"RIGHT => #{right.inspect} (#{right.class.name})\"\n          res = equality_relational_compare( left, op, right )\n          #puts \"RES => #{res.inspect}\"\n          return res\n\n        when :div\n          left = Functions::number(expr(path_stack.shift, nodeset, context)).to_f\n          right = Functions::number(expr(path_stack.shift, nodeset, context)).to_f\n          return (left / right)\n\n        when :mod\n          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          return (left % right)\n\n        when :mult\n          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          return (left * right)\n\n        when :plus\n          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          return (left + right)\n\n        when :minus\n          left = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          right = Functions::number(expr(path_stack.shift, nodeset, context )).to_f\n          return (left - right)\n\n        when :union\n          left = expr( path_stack.shift, nodeset, context )\n          right = expr( path_stack.shift, nodeset, context )\n          return (left | right)\n\n        when :neg\n          res = expr( path_stack, nodeset, context )\n          return -(res.to_f)\n\n        when :not\n        when :function\n          func_name = path_stack.shift.tr('-','_')\n          arguments = path_stack.shift\n          #puts \"FUNCTION 0: #{func_name}(#{arguments.collect{|a|a.inspect}.join(', ')})\" \n          subcontext = context ? nil : { :size => nodeset.size }\n\n          res = []\n          cont = context\n          nodeset.each_with_index { |n, i| \n            if subcontext\n              subcontext[:node]  = n\n              subcontext[:index] = i\n              cont = subcontext\n            end\n            arg_clone = arguments.dclone\n            args = arg_clone.collect { |arg| \n              #puts \"FUNCTION 1: Calling expr( #{arg.inspect}, [#{n.inspect}] )\"\n              expr( arg, [n], cont ) \n            }\n            #puts \"FUNCTION 2: #{func_name}(#{args.collect{|a|a.inspect}.join(', ')})\" \n            Functions.context = cont\n            res << Functions.send( func_name, *args )\n            #puts \"FUNCTION 3: #{res[-1].inspect}\"\n          }\n          return res\n\n        end\n      end # while\n      #puts \"EXPR returning #{nodeset.inspect}\"\n      return nodeset\n    end\n\n\n    ##########################################################\n    # FIXME\n    # The next two methods are BAD MOJO!\n    # This is my achilles heel.  If anybody thinks of a better\n    # way of doing this, be my guest.  This really sucks, but \n    # it is a wonder it works at all.\n    # ########################################################\n    \n    def descendant_or_self( path_stack, nodeset )\n      rs = []\n      #puts \"#\"*80\n      #puts \"PATH_STACK = #{path_stack.inspect}\"\n      #puts \"NODESET = #{nodeset.collect{|n|n.inspect}.inspect}\"\n      d_o_s( path_stack, nodeset, rs )\n      #puts \"RS = #{rs.collect{|n|n.inspect}.inspect}\"\n      document_order(rs.flatten.compact)\n      #rs.flatten.compact\n    end\n\n    def d_o_s( p, ns, r )\n      #puts \"IN DOS with #{ns.inspect}; ALREADY HAVE #{r.inspect}\"\n      nt = nil\n      ns.each_index do |i|\n        n = ns[i]\n        #puts \"P => #{p.inspect}\"\n        x = expr( p.dclone, [ n ] )\n        nt = n.node_type\n        d_o_s( p, n.children, x ) if nt == :element or nt == :document and n.children.size > 0\n        r.concat(x) if x.size > 0\n      end\n    end\n\n\n    # Reorders an array of nodes so that they are in document order\n    # It tries to do this efficiently.\n    #\n    # FIXME: I need to get rid of this, but the issue is that most of the XPath \n    # interpreter functions as a filter, which means that we lose context going\n    # in and out of function calls.  If I knew what the index of the nodes was,\n    # I wouldn't have to do this.  Maybe add a document IDX for each node?\n    # Problems with mutable documents.  Or, rewrite everything.\n    def document_order( array_of_nodes )\n      new_arry = []\n      array_of_nodes.each { |node|\n        node_idx = [] \n        np = node.node_type == :attribute ? node.element : node\n        while np.parent and np.parent.node_type == :element\n          node_idx << np.parent.index( np )\n          np = np.parent\n        end\n        new_arry << [ node_idx.reverse, node ]\n      }\n      #puts \"new_arry = #{new_arry.inspect}\"\n      new_arry.sort{ |s1, s2| s1[0] <=> s2[0] }.collect{ |s| s[1] }\n    end\n\n\n    def recurse( nodeset, &block )\n      for node in nodeset\n        yield node\n        recurse( node, &block ) if node.node_type == :element\n      end\n    end\n\n\n\n    # Builds a nodeset of all of the preceding nodes of the supplied node,\n    # in reverse document order\n    # preceding:: includes every element in the document that precedes this node, \n    # except for ancestors\n    def preceding( node )\n      #puts \"IN PRECEDING\"\n      ancestors = []\n      p = node.parent\n      while p\n        ancestors << p\n        p = p.parent\n      end\n\n      acc = []\n      p = preceding_node_of( node )\n      #puts \"P = #{p.inspect}\"\n      while p\n        if ancestors.include? p\n          ancestors.delete(p)\n        else\n          acc << p\n        end\n        p = preceding_node_of( p )\n        #puts \"P = #{p.inspect}\"\n      end\n      acc\n    end\n\n    def preceding_node_of( node )\n     #puts \"NODE: #{node.inspect}\"\n     #puts \"PREVIOUS NODE: #{node.previous_sibling_node.inspect}\"\n     #puts \"PARENT NODE: #{node.parent}\"\n      psn = node.previous_sibling_node \n      if psn.nil?\n        if node.parent.nil? or node.parent.class == Document \n          return nil\n        end\n        return node.parent\n        #psn = preceding_node_of( node.parent )\n      end\n      while psn and psn.kind_of? Element and psn.children.size > 0\n        psn = psn.children[-1]\n      end\n      psn\n    end\n\n    def following( node )\n      #puts \"IN PRECEDING\"\n      acc = []\n      p = next_sibling_node( node )\n      #puts \"P = #{p.inspect}\"\n      while p\n        acc << p\n        p = following_node_of( p )\n        #puts \"P = #{p.inspect}\"\n      end\n      acc\n    end\n\n    def following_node_of( node )\n      #puts \"NODE: #{node.inspect}\"\n      #puts \"PREVIOUS NODE: #{node.previous_sibling_node.inspect}\"\n      #puts \"PARENT NODE: #{node.parent}\"\n      if node.kind_of? Element and node.children.size > 0\n        return node.children[0]\n      end\n      return next_sibling_node(node)\n    end\n\n    def next_sibling_node(node)\n      psn = node.next_sibling_node \n      while psn.nil?\n        if node.parent.nil? or node.parent.class == Document \n          return nil\n        end\n        node = node.parent\n        psn = node.next_sibling_node\n        #puts \"psn = #{psn.inspect}\"\n      end\n      return psn\n    end\n\n    def norm b\n      case b\n      when true, false\n        return b\n      when 'true', 'false'\n        return Functions::boolean( b )\n      when /^\\d+(\\.\\d+)?$/\n        return Functions::number( b )\n      else\n        return Functions::string( b )\n      end\n    end\n\n    def equality_relational_compare( set1, op, set2 )\n      #puts \"EQ_REL_COMP(#{set1.inspect} #{op.inspect} #{set2.inspect})\"\n      if set1.kind_of? Array and set2.kind_of? Array\n\t\t\t  #puts \"#{set1.size} & #{set2.size}\"\n        if set1.size == 1 and set2.size == 1\n          set1 = set1[0]\n          set2 = set2[0]\n        elsif set1.size == 0 or set2.size == 0\n          nd = set1.size==0 ? set2 : set1\n          rv = nd.collect { |il| compare( il, op, nil ) }\n          #puts \"RV = #{rv.inspect}\"\n          return rv\n        else\n          res = []\n          enum = SyncEnumerator.new( set1, set2 ).each { |i1, i2|\n            #puts \"i1 = #{i1.inspect} (#{i1.class.name})\"\n            #puts \"i2 = #{i2.inspect} (#{i2.class.name})\"\n            i1 = norm( i1 )\n            i2 = norm( i2 )\n            res << compare( i1, op, i2 )\n          }\n          return res\n        end\n      end\n\t\t  #puts \"EQ_REL_COMP: #{set1.inspect} (#{set1.class.name}), #{op}, #{set2.inspect} (#{set2.class.name})\"\n      #puts \"COMPARING VALUES\"\n      # If one is nodeset and other is number, compare number to each item\n      # in nodeset s.t. number op number(string(item))\n      # If one is nodeset and other is string, compare string to each item\n      # in nodeset s.t. string op string(item)\n      # If one is nodeset and other is boolean, compare boolean to each item\n      # in nodeset s.t. boolean op boolean(item)\n      if set1.kind_of? Array or set2.kind_of? Array\n\t\t\t  #puts \"ISA ARRAY\"\n        if set1.kind_of? Array\n          a = set1\n          b = set2\n        else\n          a = set2\n          b = set1\n        end\n\n        case b\n        when true, false\n          return a.collect {|v| compare( Functions::boolean(v), op, b ) }\n        when Numeric\n          return a.collect {|v| compare( Functions::number(v), op, b )}\n        when /^\\d+(\\.\\d+)?$/\n          b = Functions::number( b )\n          #puts \"B = #{b.inspect}\"\n          return a.collect {|v| compare( Functions::number(v), op, b )}\n        else\n\t\t\t\t  #puts \"Functions::string( #{b}(#{b.class.name}) ) = #{Functions::string(b)}\"\n          b = Functions::string( b )\n          return a.collect { |v| compare( Functions::string(v), op, b ) }\n        end\n      else\n        # If neither is nodeset,\n        #   If op is = or !=\n        #     If either boolean, convert to boolean\n        #     If either number, convert to number\n        #     Else, convert to string\n        #   Else\n        #     Convert both to numbers and compare\n        s1 = set1.to_s\n        s2 = set2.to_s\n        #puts \"EQ_REL_COMP: #{set1}=>#{s1}, #{set2}=>#{s2}\"\n        if s1 == 'true' or s1 == 'false' or s2 == 'true' or s2 == 'false'\n          #puts \"Functions::boolean(#{set1})=>#{Functions::boolean(set1)}\"\n          #puts \"Functions::boolean(#{set2})=>#{Functions::boolean(set2)}\"\n          set1 = Functions::boolean( set1 )\n          set2 = Functions::boolean( set2 )\n        else\n          if op == :eq or op == :neq\n            if s1 =~ /^\\d+(\\.\\d+)?$/ or s2 =~ /^\\d+(\\.\\d+)?$/\n              set1 = Functions::number( s1 )\n              set2 = Functions::number( s2 )\n            else\n              set1 = Functions::string( set1 )\n              set2 = Functions::string( set2 )\n            end\n          else\n            set1 = Functions::number( set1 )\n            set2 = Functions::number( set2 )\n          end\n        end\n        #puts \"EQ_REL_COMP: #{set1} #{op} #{set2}\"\n        #puts \">>> #{compare( set1, op, set2 )}\"\n        return compare( set1, op, set2 )\n      end\n      return false\n    end\n\n    def compare a, op, b\n      #puts \"COMPARE #{a.inspect}(#{a.class.name}) #{op} #{b.inspect}(#{b.class.name})\"\n      case op\n      when :eq\n        a == b\n      when :neq\n        a != b\n      when :lt\n        a < b\n      when :lteq\n        a <= b\n      when :gt\n        a > b\n      when :gteq\n        a >= b\n      when :and\n        a and b\n      when :or\n        a or b\n      else\n        false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rinda/rinda.rb",
    "content": "require 'drb/drb'\nrequire 'thread'\n\n##\n# A module to implement the Linda distributed computing paradigm in Ruby.\n#\n# Rinda is part of DRb (dRuby).\n#\n# == Example(s)\n#\n# See the sample/drb/ directory in the Ruby distribution, from 1.8.2 onwards.\n#\n#--\n# TODO\n# == Introduction to Linda/rinda?\n#\n# == Why is this library separate from DRb?\n\nmodule Rinda\n\n  ##\n  # Rinda error base class\n\n  class RindaError < RuntimeError; end\n\n  ##\n  # Raised when a hash-based tuple has an invalid key.\n\n  class InvalidHashTupleKey < RindaError; end\n\n  ##\n  # Raised when trying to use a canceled tuple.\n\n  class RequestCanceledError < ThreadError; end\n\n  ##\n  # Raised when trying to use an expired tuple.\n\n  class RequestExpiredError < ThreadError; end\n\n  ##\n  # A tuple is the elementary object in Rinda programming.\n  # Tuples may be matched against templates if the tuple and\n  # the template are the same size.\n\n  class Tuple\n\n    ##\n    # Creates a new Tuple from +ary_or_hash+ which must be an Array or Hash.\n\n    def initialize(ary_or_hash)\n      if hash?(ary_or_hash)\n        init_with_hash(ary_or_hash)\n      else\n        init_with_ary(ary_or_hash)\n      end\n    end\n\n    ##\n    # The number of elements in the tuple.\n    \n    def size\n      @tuple.size\n    end\n\n    ##\n    # Accessor method for elements of the tuple.\n\n    def [](k)\n      @tuple[k]\n    end\n\n    ##\n    # Fetches item +k+ from the tuple.\n\n    def fetch(k)\n      @tuple.fetch(k)\n    end\n\n    ##\n    # Iterate through the tuple, yielding the index or key, and the\n    # value, thus ensuring arrays are iterated similarly to hashes.\n\n    def each # FIXME\n      if Hash === @tuple\n        @tuple.each { |k, v| yield(k, v) }\n      else\n        @tuple.each_with_index { |v, k| yield(k, v) }\n      end\n    end\n\n    ##\n    # Return the tuple itself\n    def value\n      @tuple\n    end\n\n    private\n\n    def hash?(ary_or_hash)\n      ary_or_hash.respond_to?(:keys)\n    end\n\n    ##\n    # Munges +ary+ into a valid Tuple.\n\n    def init_with_ary(ary)\n      @tuple = Array.new(ary.size)\n      @tuple.size.times do |i|\n        @tuple[i] = ary[i]\n      end\n    end\n\n    ##\n    # Ensures +hash+ is a valid Tuple.\n\n    def init_with_hash(hash)\n      @tuple = Hash.new\n      hash.each do |k, v|\n        raise InvalidHashTupleKey unless String === k\n        @tuple[k] = v\n      end\n    end\n\n  end\n\n  ##\n  # Templates are used to match tuples in Rinda.\n\n  class Template < Tuple\n\n    ##\n    # Matches this template against +tuple+.  The +tuple+ must be the same\n    # size as the template.  An element with a +nil+ value in a template acts\n    # as a wildcard, matching any value in the corresponding position in the\n    # tuple.  Elements of the template match the +tuple+ if the are #== or\n    # #===.\n    #\n    #   Template.new([:foo, 5]).match   Tuple.new([:foo, 5]) # => true\n    #   Template.new([:foo, nil]).match Tuple.new([:foo, 5]) # => true\n    #   Template.new([String]).match    Tuple.new(['hello']) # => true\n    #\n    #   Template.new([:foo]).match      Tuple.new([:foo, 5]) # => false\n    #   Template.new([:foo, 6]).match   Tuple.new([:foo, 5]) # => false\n    #   Template.new([:foo, nil]).match Tuple.new([:foo])    # => false\n    #   Template.new([:foo, 6]).match   Tuple.new([:foo])    # => false\n\n    def match(tuple)\n      return false unless tuple.respond_to?(:size)\n      return false unless tuple.respond_to?(:fetch)\n      return false unless self.size == tuple.size\n      each do |k, v|\n        begin\n          it = tuple.fetch(k)\n        rescue\n          return false\n        end\n        next if v.nil?\n        next if v == it\n        next if v === it\n        return false\n      end\n      return true\n    end\n    \n    ##\n    # Alias for #match.\n\n    def ===(tuple)\n      match(tuple)\n    end\n\n  end\n  \n  ##\n  # <i>Documentation?</i>\n\n  class DRbObjectTemplate\n\n    ##\n    # Creates a new DRbObjectTemplate that will match against +uri+ and +ref+.\n\n    def initialize(uri=nil, ref=nil)\n      @drb_uri = uri\n      @drb_ref = ref\n    end\n    \n    ##\n    # This DRbObjectTemplate matches +ro+ if the remote object's drburi and\n    # drbref are the same.  +nil+ is used as a wildcard.\n\n    def ===(ro)\n      return true if super(ro)\n      unless @drb_uri.nil?\n        return false unless (@drb_uri === ro.__drburi rescue false)\n      end\n      unless @drb_ref.nil?\n        return false unless (@drb_ref === ro.__drbref rescue false)\n      end\n      true\n    end\n\n  end\n\n  ##\n  # TupleSpaceProxy allows a remote Tuplespace to appear as local.\n\n  class TupleSpaceProxy\n\n    ##\n    # Creates a new TupleSpaceProxy to wrap +ts+.\n\n    def initialize(ts)\n      @ts = ts\n    end\n    \n    ##\n    # Adds +tuple+ to the proxied TupleSpace.  See TupleSpace#write.\n\n    def write(tuple, sec=nil)\n      @ts.write(tuple, sec)\n    end\n    \n    ##\n    # Takes +tuple+ from the proxied TupleSpace.  See TupleSpace#take.\n\n    def take(tuple, sec=nil, &block)\n      port = []\n      @ts.move(DRbObject.new(port), tuple, sec, &block)\n      port[0]\n    end\n    \n    ##\n    # Reads +tuple+ from the proxied TupleSpace.  See TupleSpace#read.\n\n    def read(tuple, sec=nil, &block)\n      @ts.read(tuple, sec, &block)\n    end\n    \n    ##\n    # Reads all tuples matching +tuple+ from the proxied TupleSpace.  See\n    # TupleSpace#read_all.\n\n    def read_all(tuple)\n      @ts.read_all(tuple)\n    end\n    \n    ##\n    # Registers for notifications of event +ev+ on the proxied TupleSpace.\n    # See TupleSpace#notify\n\n    def notify(ev, tuple, sec=nil)\n      @ts.notify(ev, tuple, sec)\n    end\n\n  end\n\n  ##\n  # An SimpleRenewer allows a TupleSpace to check if a TupleEntry is still\n  # alive.\n\n  class SimpleRenewer\n\n    include DRbUndumped\n\n    ##\n    # Creates a new SimpleRenewer that keeps an object alive for another +sec+\n    # seconds.\n\n    def initialize(sec=180)\n      @sec = sec\n    end\n\n    ##\n    # Called by the TupleSpace to check if the object is still alive.\n\n    def renew\n      @sec\n    end\n  end\n\nend\n\n"
  },
  {
    "path": "lib/rinda/ring.rb",
    "content": "#\n# Note: Rinda::Ring API is unstable.\n#\nrequire 'drb/drb'\nrequire 'rinda/rinda'\nrequire 'thread'\n\nmodule Rinda\n\n  ##\n  # The default port Ring discovery will use.\n\n  Ring_PORT = 7647\n\n  ##\n  # A RingServer allows a Rinda::TupleSpace to be located via UDP broadcasts.\n  # Service location uses the following steps:\n  #\n  # 1. A RingServer begins listening on the broadcast UDP address.\n  # 2. A RingFinger sends a UDP packet containing the DRb URI where it will\n  #    listen for a reply.\n  # 3. The RingServer receives the UDP packet and connects back to the\n  #    provided DRb URI with the DRb service.\n\n  class RingServer\n\n    include DRbUndumped\n\n    ##\n    # Advertises +ts+ on the UDP broadcast address at +port+.\n\n    def initialize(ts, port=Ring_PORT)\n      @ts = ts\n      @soc = UDPSocket.open\n      @soc.bind('', port)\n      @w_service = write_service\n      @r_service = reply_service\n    end\n\n    ##\n    # Creates a thread that picks up UDP packets and passes them to do_write\n    # for decoding.\n\n    def write_service\n      Thread.new do\n\tloop do\n\t  msg = @soc.recv(1024)\n\t  do_write(msg)\n\tend\n      end\n    end\n  \n    ##\n    # Extracts the response URI from +msg+ and adds it to TupleSpace where it\n    # will be picked up by +reply_service+ for notification.\n\n    def do_write(msg)\n      Thread.new do\n\tbegin\n\t  tuple, sec = Marshal.load(msg)\n\t  @ts.write(tuple, sec)\n\trescue\n\tend\n      end\n    end\n\n    ##\n    # Creates a thread that notifies waiting clients from the TupleSpace.\n\n    def reply_service\n      Thread.new do\n\tloop do\n\t  do_reply\n\tend\n      end\n    end\n    \n    ##\n    # Pulls lookup tuples out of the TupleSpace and sends their DRb object the\n    # address of the local TupleSpace.\n\n    def do_reply\n      tuple = @ts.take([:lookup_ring, nil])\n      Thread.new { tuple[1].call(@ts) rescue nil}\n    rescue\n    end\n\n  end\n\n  ##\n  # RingFinger is used by RingServer clients to discover the RingServer's\n  # TupleSpace.  Typically, all a client needs to do is call\n  # RingFinger.primary to retrieve the remote TupleSpace, which it can then\n  # begin using.\n\n  class RingFinger\n\n    @@broadcast_list = ['<broadcast>', 'localhost']\n\n    @@finger = nil\n\n    ##\n    # Creates a singleton RingFinger and looks for a RingServer.  Returns the\n    # created RingFinger.\n\n    def self.finger\n      unless @@finger \n\t@@finger = self.new\n\t@@finger.lookup_ring_any\n      end\n      @@finger\n    end\n\n    ##\n    # Returns the first advertised TupleSpace.\n\n    def self.primary\n      finger.primary\n    end\n\n    ##\n    # Contains all discovered TupleSpaces except for the primary.\n\n    def self.to_a\n      finger.to_a\n    end\n\n    ##\n    # The list of addresses where RingFinger will send query packets.\n\n    attr_accessor :broadcast_list\n\n    ##\n    # The port that RingFinger will send query packets to.\n\n    attr_accessor :port\n\n    ##\n    # Contain the first advertised TupleSpace after lookup_ring_any is called.\n\n    attr_accessor :primary\n\n    ##\n    # Creates a new RingFinger that will look for RingServers at +port+ on\n    # the addresses in +broadcast_list+.\n\n    def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT)\n      @broadcast_list = broadcast_list || ['localhost']\n      @port = port\n      @primary = nil\n      @rings = []\n    end\n\n    ##\n    # Contains all discovered TupleSpaces except for the primary.\n\n    def to_a\n      @rings\n    end\n\n    ##\n    # Iterates over all discovered TupleSpaces starting with the primary.\n\n    def each\n      lookup_ring_any unless @primary\n      return unless @primary\n      yield(@primary)\n      @rings.each { |x| yield(x) }\n    end\n\n    ##\n    # Looks up RingServers waiting +timeout+ seconds.  RingServers will be\n    # given +block+ as a callback, which will be called with the remote\n    # TupleSpace.\n\n    def lookup_ring(timeout=5, &block)\n      return lookup_ring_any(timeout) unless block_given?\n\n      msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])\n      @broadcast_list.each do |it|\n\tsoc = UDPSocket.open\n\tbegin\n\t  soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)\n\t  soc.send(msg, 0, it, @port)\n\trescue\n\t  nil\n\tensure\n\t  soc.close\n\tend\n      end\n      sleep(timeout)\n    end\n\n    ##\n    # Returns the first found remote TupleSpace.  Any further recovered\n    # TupleSpaces can be found by calling +to_a+.\n\n    def lookup_ring_any(timeout=5)\n      queue = Queue.new\n\n      th = Thread.new do\n\tself.lookup_ring(timeout) do |ts|\n\t  queue.push(ts)\n\tend\n\tqueue.push(nil)\n\twhile it = queue.pop\n\t  @rings.push(it)\n\tend\n      end\n      \n      @primary = queue.pop\n      raise('RingNotFound') if @primary.nil?\n      @primary\n    end\n\n  end\n\n  ##\n  # RingProvider uses a RingServer advertised TupleSpace as a name service.\n  # TupleSpace clients can register themselves with the remote TupleSpace and\n  # look up other provided services via the remote TupleSpace.\n  #\n  # Services are registered with a tuple of the format [:name, klass,\n  # DRbObject, description].\n\n  class RingProvider\n\n    ##\n    # Creates a RingProvider that will provide a +klass+ service running on\n    # +front+, with a +description+.  +renewer+ is optional.\n\n    def initialize(klass, front, desc, renewer = nil)\n      @tuple = [:name, klass, front, desc]\n      @renewer = renewer || Rinda::SimpleRenewer.new\n    end\n\n    ##\n    # Advertises this service on the primary remote TupleSpace.\n\n    def provide\n      ts = Rinda::RingFinger.primary\n      ts.write(@tuple, @renewer)\n    end\n\n  end\n\nend\n\nif __FILE__ == $0\n  DRb.start_service\n  case ARGV.shift\n  when 's'\n    require 'rinda/tuplespace'\n    ts = Rinda::TupleSpace.new\n    place = Rinda::RingServer.new(ts)\n    $stdin.gets\n  when 'w'\n    finger = Rinda::RingFinger.new(nil)\n    finger.lookup_ring do |ts|\n      p ts\n      ts.write([:hello, :world])\n    end\n  when 'r'\n    finger = Rinda::RingFinger.new(nil)\n    finger.lookup_ring do |ts|\n      p ts\n      p ts.take([nil, nil])\n    end\n  end\nend\n\n"
  },
  {
    "path": "lib/rinda/tuplespace.rb",
    "content": "require 'monitor'\nrequire 'thread'\nrequire 'drb/drb'\nrequire 'rinda/rinda'\nrequire 'enumerator'\nrequire 'forwardable'\n\nmodule Rinda\n\n  ##\n  # A TupleEntry is a Tuple (i.e. a possible entry in some Tuplespace)\n  # together with expiry and cancellation data.\n\n  class TupleEntry\n\n    include DRbUndumped\n\n    attr_accessor :expires\n\n    ##\n    # Creates a TupleEntry based on +ary+ with an optional renewer or expiry\n    # time +sec+.\n    #\n    # A renewer must implement the +renew+ method which returns a Numeric,\n    # nil, or true to indicate when the tuple has expired.\n\n    def initialize(ary, sec=nil)\n      @cancel = false\n      @expires = nil\n      @tuple = make_tuple(ary)\n      @renewer = nil\n      renew(sec)\n    end\n\n    ##\n    # Marks this TupleEntry as canceled.\n\n    def cancel\n      @cancel = true\n    end\n\n    ##\n    # A TupleEntry is dead when it is canceled or expired.\n\n    def alive?\n      !canceled? && !expired?\n    end\n\n    ##\n    # Return the object which makes up the tuple itself: the Array\n    # or Hash.\n\n    def value; @tuple.value; end\n\n    ##\n    # Returns the canceled status.\n\n    def canceled?; @cancel; end\n\n    ##\n    # Has this tuple expired? (true/false).\n    #\n    # A tuple has expired when its expiry timer based on the +sec+ argument to\n    # #initialize runs out.\n\n    def expired?\n      return true unless @expires\n      return false if @expires > Time.now\n      return true if @renewer.nil?\n      renew(@renewer)\n      return true unless @expires\n      return @expires < Time.now\n    end\n\n    ##\n    # Reset the expiry time according to +sec_or_renewer+.  \n    #\n    # +nil+::    it is set to expire in the far future.\n    # +false+::  it has expired.\n    # Numeric::  it will expire in that many seconds.\n    #\n    # Otherwise the argument refers to some kind of renewer object\n    # which will reset its expiry time. \n\n    def renew(sec_or_renewer)\n      sec, @renewer = get_renewer(sec_or_renewer)\n      @expires = make_expires(sec)\n    end\n\n    ##\n    # Returns an expiry Time based on +sec+ which can be one of:\n    # Numeric:: +sec+ seconds into the future\n    # +true+::  the expiry time is the start of 1970 (i.e. expired)\n    # +nil+::   it is  Tue Jan 19 03:14:07 GMT Standard Time 2038 (i.e. when\n    #           UNIX clocks will die)\n\n    def make_expires(sec=nil)\n      case sec\n      when Numeric\n        Time.now + sec\n      when true\n        Time.at(1)\n      when nil\n        Time.at(2**31-1)\n      end\n    end\n\n    ##\n    # Retrieves +key+ from the tuple.\n\n    def [](key)\n      @tuple[key]\n    end\n\n    ##\n    # Fetches +key+ from the tuple.\n\n    def fetch(key)\n      @tuple.fetch(key)\n    end\n\n    ##\n    # The size of the tuple.\n\n    def size\n      @tuple.size\n    end\n\n    ##\n    # Creates a Rinda::Tuple for +ary+.\n\n    def make_tuple(ary)\n      Rinda::Tuple.new(ary)\n    end\n\n    private\n\n    ##\n    # Returns a valid argument to make_expires and the renewer or nil.\n    #\n    # Given +true+, +nil+, or Numeric, returns that value and +nil+ (no actual\n    # renewer).  Otherwise it returns an expiry value from calling +it.renew+\n    # and the renewer.\n\n    def get_renewer(it)\n      case it\n      when Numeric, true, nil\n        return it, nil\n      else\n        begin\n          return it.renew, it\n        rescue Exception\n          return it, nil\n        end\n      end\n    end\n\n  end\n\n  ##\n  # A TemplateEntry is a Template together with expiry and cancellation data.\n\n  class TemplateEntry < TupleEntry\n    ##\n    # Matches this TemplateEntry against +tuple+.  See Template#match for\n    # details on how a Template matches a Tuple.\n\n    def match(tuple)\n      @tuple.match(tuple)\n    end\n    \n    alias === match\n\n    def make_tuple(ary) # :nodoc:\n      Rinda::Template.new(ary)\n    end\n\n  end\n\n  ##\n  # <i>Documentation?</i>\n\n  class WaitTemplateEntry < TemplateEntry\n\n    attr_reader :found\n\n    def initialize(place, ary, expires=nil)\n      super(ary, expires)\n      @place = place\n      @cond = place.new_cond\n      @found = nil\n    end\n\n    def cancel\n      super\n      signal\n    end\n\n    def wait\n      @cond.wait\n    end\n\n    def read(tuple)\n      @found = tuple\n      signal\n    end\n\n    def signal\n      @place.synchronize do\n        @cond.signal\n      end\n    end\n\n  end\n\n  ##\n  # A NotifyTemplateEntry is returned by TupleSpace#notify and is notified of\n  # TupleSpace changes.  You may receive either your subscribed event or the\n  # 'close' event when iterating over notifications.\n  #\n  # See TupleSpace#notify_event for valid notification types.\n  #\n  # == Example\n  #\n  #   ts = Rinda::TupleSpace.new\n  #   observer = ts.notify 'write', [nil]\n  #   \n  #   Thread.start do\n  #     observer.each { |t| p t }\n  #   end\n  #   \n  #   3.times { |i| ts.write [i] }\n  #\n  # Outputs:\n  #\n  #   ['write', [0]]\n  #   ['write', [1]]\n  #   ['write', [2]]\n\n  class NotifyTemplateEntry < TemplateEntry\n\n    ##\n    # Creates a new NotifyTemplateEntry that watches +place+ for +event+s that\n    # match +tuple+.\n\n    def initialize(place, event, tuple, expires=nil)\n      ary = [event, Rinda::Template.new(tuple)]\n      super(ary, expires)\n      @queue = Queue.new\n      @done = false\n    end\n\n    ##\n    # Called by TupleSpace to notify this NotifyTemplateEntry of a new event.\n\n    def notify(ev)\n      @queue.push(ev)\n    end\n\n    ##\n    # Retrieves a notification.  Raises RequestExpiredError when this\n    # NotifyTemplateEntry expires.\n\n    def pop\n      raise RequestExpiredError if @done\n      it = @queue.pop\n      @done = true if it[0] == 'close'\n      return it\n    end\n\n    ##\n    # Yields event/tuple pairs until this NotifyTemplateEntry expires.\n\n    def each # :yields: event, tuple\n      while !@done\n        it = pop\n        yield(it)\n      end\n    rescue \n    ensure\n      cancel\n    end\n\n  end\n\n  ##\n  # TupleBag is an unordered collection of tuples. It is the basis\n  # of Tuplespace.\n\n  class TupleBag\n    class TupleBin\n      extend Forwardable\n      def_delegators '@bin', :find_all, :delete_if, :each, :empty?\n\n      def initialize\n        @bin = []\n      end\n      \n      def add(tuple)\n        @bin.push(tuple)\n      end\n      \n      def delete(tuple)\n        idx = @bin.rindex(tuple)\n        @bin.delete_at(idx) if idx\n      end\n      \n      def find(&blk)\n        @bin.reverse_each do |x|\n          return x if yield(x)\n        end\n        nil\n      end\n    end\n\n    def initialize # :nodoc:\n      @hash = {}\n      @enum = Enumerable::Enumerator.new(self, :each_entry)\n    end\n\n    ##\n    # +true+ if the TupleBag to see if it has any expired entries.\n\n    def has_expires?\n      @enum.find do |tuple|\n        tuple.expires\n      end\n    end\n\n    ##\n    # Add +tuple+ to the TupleBag.\n\n    def push(tuple)\n      key = bin_key(tuple)\n      @hash[key] ||= TupleBin.new\n      @hash[key].add(tuple)\n    end\n\n    ##\n    # Removes +tuple+ from the TupleBag.\n\n    def delete(tuple)\n      key = bin_key(tuple)\n      bin = @hash[key]\n      return nil unless bin\n      bin.delete(tuple)\n      @hash.delete(key) if bin.empty?\n      tuple\n    end\n\n    ##\n    # Finds all live tuples that match +template+.\n    def find_all(template)\n      bin_for_find(template).find_all do |tuple|\n        tuple.alive? && template.match(tuple)\n      end\n    end\n\n    ##\n    # Finds a live tuple that matches +template+.\n\n    def find(template)\n      bin_for_find(template).find do |tuple|\n        tuple.alive? && template.match(tuple)\n      end\n    end\n\n    ##\n    # Finds all tuples in the TupleBag which when treated as templates, match\n    # +tuple+ and are alive.\n\n    def find_all_template(tuple)\n      @enum.find_all do |template|\n        template.alive? && template.match(tuple)\n      end\n    end\n\n    ##\n    # Delete tuples which dead tuples from the TupleBag, returning the deleted\n    # tuples.\n\n    def delete_unless_alive\n      deleted = []\n      @hash.each do |key, bin|\n        bin.delete_if do |tuple|\n          if tuple.alive?\n            false\n          else\n            deleted.push(tuple)\n            true\n          end\n        end\n      end\n      deleted\n    end\n\n    private\n    def each_entry(&blk)\n      @hash.each do |k, v|\n        v.each(&blk)\n      end\n    end\n\n    def bin_key(tuple)\n      head = tuple[0]\n      if head.class == Symbol\n        return head\n      else\n        false\n      end\n    end\n\n    def bin_for_find(template)\n      key = bin_key(template)\n      key ? @hash.fetch(key, []) : @enum\n    end\n  end\n\n  ##\n  # The Tuplespace manages access to the tuples it contains,\n  # ensuring mutual exclusion requirements are met.\n  #\n  # The +sec+ option for the write, take, move, read and notify methods may\n  # either be a number of seconds or a Renewer object.\n\n  class TupleSpace\n\n    include DRbUndumped\n    include MonitorMixin\n\n    ##\n    # Creates a new TupleSpace.  +period+ is used to control how often to look\n    # for dead tuples after modifications to the TupleSpace.\n    #\n    # If no dead tuples are found +period+ seconds after the last\n    # modification, the TupleSpace will stop looking for dead tuples.\n\n    def initialize(period=60)\n      super()\n      @bag = TupleBag.new\n      @read_waiter = TupleBag.new\n      @take_waiter = TupleBag.new\n      @notify_waiter = TupleBag.new\n      @period = period\n      @keeper = nil\n    end\n\n    ##\n    # Adds +tuple+\n\n    def write(tuple, sec=nil)\n      entry = create_entry(tuple, sec)\n      synchronize do\n        if entry.expired?\n          @read_waiter.find_all_template(entry).each do |template|\n            template.read(tuple)\n          end\n          notify_event('write', entry.value)\n          notify_event('delete', entry.value)\n        else\n          @bag.push(entry)\n          start_keeper if entry.expires\n          @read_waiter.find_all_template(entry).each do |template|\n            template.read(tuple)\n          end\n          @take_waiter.find_all_template(entry).each do |template|\n            template.signal\n          end\n          notify_event('write', entry.value)\n        end\n      end\n      entry\n    end\n\n    ##\n    # Removes +tuple+\n\n    def take(tuple, sec=nil, &block)\n      move(nil, tuple, sec, &block)\n    end\n\n    ##\n    # Moves +tuple+ to +port+.\n\n    def move(port, tuple, sec=nil)\n      template = WaitTemplateEntry.new(self, tuple, sec)\n      yield(template) if block_given?\n      synchronize do\n        entry = @bag.find(template)\n        if entry\n          port.push(entry.value) if port\n          @bag.delete(entry)\n          notify_event('take', entry.value)\n          return entry.value\n        end\n        raise RequestExpiredError if template.expired?\n\n        begin\n          @take_waiter.push(template)\n          start_keeper if template.expires\n          while true\n            raise RequestCanceledError if template.canceled?\n            raise RequestExpiredError if template.expired?\n            entry = @bag.find(template)\n            if entry\n              port.push(entry.value) if port\n              @bag.delete(entry)\n              notify_event('take', entry.value)\n              return entry.value\n            end\n            template.wait\n          end\n        ensure\n          @take_waiter.delete(template)\n        end\n      end\n    end\n\n    ##\n    # Reads +tuple+, but does not remove it.\n\n    def read(tuple, sec=nil)\n      template = WaitTemplateEntry.new(self, tuple, sec)\n      yield(template) if block_given?\n      synchronize do\n        entry = @bag.find(template)\n        return entry.value if entry\n        raise RequestExpiredError if template.expired?\n\n        begin\n          @read_waiter.push(template)\n          start_keeper if template.expires\n          template.wait\n          raise RequestCanceledError if template.canceled?\n          raise RequestExpiredError if template.expired?\n          return template.found\n        ensure\n          @read_waiter.delete(template)\n        end\n      end\n    end\n\n    ##\n    # Returns all tuples matching +tuple+.  Does not remove the found tuples.\n\n    def read_all(tuple)\n      template = WaitTemplateEntry.new(self, tuple, nil)\n      synchronize do\n        entry = @bag.find_all(template)\n        entry.collect do |e|\n          e.value\n        end\n      end\n    end\n\n    ##\n    # Registers for notifications of +event+.  Returns a NotifyTemplateEntry.\n    # See NotifyTemplateEntry for examples of how to listen for notifications.\n    #\n    # +event+ can be:\n    # 'write'::  A tuple was added\n    # 'take'::   A tuple was taken or moved\n    # 'delete':: A tuple was lost after being overwritten or expiring\n    #\n    # The TupleSpace will also notify you of the 'close' event when the\n    # NotifyTemplateEntry has expired.\n\n    def notify(event, tuple, sec=nil)\n      template = NotifyTemplateEntry.new(self, event, tuple, sec)\n      synchronize do\n        @notify_waiter.push(template)\n      end\n      template\n    end\n\n    private\n\n    def create_entry(tuple, sec)\n      TupleEntry.new(tuple, sec)\n    end\n\n    ##\n    # Removes dead tuples.\n\n    def keep_clean\n      synchronize do\n        @read_waiter.delete_unless_alive.each do |e|\n          e.signal\n        end\n        @take_waiter.delete_unless_alive.each do |e|\n          e.signal\n        end\n        @notify_waiter.delete_unless_alive.each do |e|\n          e.notify(['close'])\n        end\n        @bag.delete_unless_alive.each do |e|\n          notify_event('delete', e.value)\n        end\n      end\n    end\n\n    ##\n    # Notifies all registered listeners for +event+ of a status change of\n    # +tuple+.\n\n    def notify_event(event, tuple)\n      ev = [event, tuple]\n      @notify_waiter.find_all_template(ev).each do |template|\n        template.notify(ev)\n      end\n    end\n\n    ##\n    # Creates a thread that scans the tuplespace for expired tuples.\n\n    def start_keeper\n      return if @keeper && @keeper.alive?\n      @keeper = Thread.new do\n        while true\n          sleep(@period)\n          synchronize do\n            break unless need_keeper?\n            keep_clean\n          end\n        end\n      end\n    end\n\n    ##\n    # Checks the tuplespace to see if it needs cleaning.\n\n    def need_keeper?\n      return true if @bag.has_expires?\n      return true if @read_waiter.has_expires?\n      return true if @take_waiter.has_expires?\n      return true if @notify_waiter.has_expires?\n    end\n\n  end\n\nend\n\n"
  },
  {
    "path": "lib/rss/0.9.rb",
    "content": "require \"rss/parser\"\n\nmodule RSS\n\n  module RSS09\n    NSPOOL = {}\n    ELEMENTS = []\n\n    def self.append_features(klass)\n      super\n      \n      klass.install_must_call_validator('', \"\")\n    end\n  end\n\n  class Rss < Element\n\n    include RSS09\n    include RootElementMixin\n\n    %w(channel).each do |name|\n      install_have_child_element(name, \"\", nil)\n    end\n\n    attr_writer :feed_version\n    alias_method(:rss_version, :feed_version)\n    alias_method(:rss_version=, :feed_version=)\n\n    def initialize(feed_version, version=nil, encoding=nil, standalone=nil)\n      super\n      @feed_type = \"rss\"\n    end\n\n    def items\n      if @channel\n        @channel.items\n      else\n        []\n      end\n    end\n\n    def image\n      if @channel\n        @channel.image\n      else\n        nil\n      end\n    end\n\n    def textinput\n      if @channel\n        @channel.textInput\n      else\n        nil\n      end\n    end\n\n    def setup_maker_elements(maker)\n      super\n      items.each do |item|\n        item.setup_maker(maker.items)\n      end\n      image.setup_maker(maker) if image\n      textinput.setup_maker(maker) if textinput\n    end\n\n    private\n    def _attrs\n      [\n        [\"version\", true, \"feed_version\"],\n      ]\n    end\n\n    class Channel < Element\n\n      include RSS09\n\n      [\n        [\"title\", nil, :text],\n        [\"link\", nil, :text],\n        [\"description\", nil, :text],\n        [\"language\", nil, :text],\n        [\"copyright\", \"?\", :text],\n        [\"managingEditor\", \"?\", :text],\n        [\"webMaster\", \"?\", :text],\n        [\"rating\", \"?\", :text],\n        [\"pubDate\", \"?\", :date, :rfc822],\n        [\"lastBuildDate\", \"?\", :date, :rfc822],\n        [\"docs\", \"?\", :text],\n        [\"cloud\", \"?\", :have_attribute],\n        [\"skipDays\", \"?\", :have_child],\n        [\"skipHours\", \"?\", :have_child],\n        [\"image\", nil, :have_child],\n        [\"item\", \"*\", :have_children],\n        [\"textInput\", \"?\", :have_child],\n      ].each do |name, occurs, type, *args|\n        __send__(\"install_#{type}_element\", name, \"\", occurs, name, *args)\n      end\n      alias date pubDate\n      alias date= pubDate=\n\n      private\n      def maker_target(maker)\n        maker.channel\n      end\n\n      def setup_maker_elements(channel)\n        super\n        [\n          [skipDays, \"day\"],\n          [skipHours, \"hour\"],\n        ].each do |skip, key|\n          if skip\n            skip.__send__(\"#{key}s\").each do |val|\n              target_skips = channel.__send__(\"skip#{key.capitalize}s\")\n              new_target = target_skips.__send__(\"new_#{key}\")\n              new_target.content = val.content\n            end\n          end\n        end\n      end\n\n      def not_need_to_call_setup_maker_variables\n        %w(image textInput)\n      end\n    \n      class SkipDays < Element\n        include RSS09\n\n        [\n          [\"day\", \"*\"]\n        ].each do |name, occurs|\n          install_have_children_element(name, \"\", occurs)\n        end\n\n        class Day < Element\n          include RSS09\n\n          content_setup\n\n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.content = args[0]\n            end\n          end\n      \n        end\n        \n      end\n      \n      class SkipHours < Element\n        include RSS09\n\n        [\n          [\"hour\", \"*\"]\n        ].each do |name, occurs|\n          install_have_children_element(name, \"\", occurs)\n        end\n\n        class Hour < Element\n          include RSS09\n\n          content_setup(:integer)\n\n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.content = args[0]\n            end\n          end\n        end\n        \n      end\n      \n      class Image < Element\n\n        include RSS09\n        \n        %w(url title link).each do |name|\n          install_text_element(name, \"\", nil)\n        end\n        [\n          [\"width\", :integer],\n          [\"height\", :integer],\n          [\"description\"],\n        ].each do |name, type|\n          install_text_element(name, \"\", \"?\", name, type)\n        end\n\n        def initialize(*args)\n          if Utils.element_initialize_arguments?(args)\n            super\n          else\n            super()\n            self.url = args[0]\n            self.title = args[1]\n            self.link = args[2]\n            self.width = args[3]\n            self.height = args[4]\n            self.description = args[5]\n          end\n        end\n\n        private\n        def maker_target(maker)\n          maker.image\n        end\n      end\n\n      class Cloud < Element\n\n        include RSS09\n\n        [\n          [\"domain\", \"\", true],\n          [\"port\", \"\", true, :integer],\n          [\"path\", \"\", true],\n          [\"registerProcedure\", \"\", true],\n          [\"protocol\", \"\", true],\n        ].each do |name, uri, required, type|\n          install_get_attribute(name, uri, required, type)\n        end\n\n        def initialize(*args)\n          if Utils.element_initialize_arguments?(args)\n            super\n          else\n            super()\n            self.domain = args[0]\n            self.port = args[1]\n            self.path = args[2]\n            self.registerProcedure = args[3]\n            self.protocol = args[4]\n          end\n        end\n      end\n      \n      class Item < Element\n        \n        include RSS09\n\n        [\n          [\"title\", '?', :text],\n          [\"link\", '?', :text],\n          [\"description\", '?', :text],\n          [\"category\", '*', :have_children, \"categories\"],\n          [\"source\", '?', :have_child],\n          [\"enclosure\", '?', :have_child],\n        ].each do |tag, occurs, type, *args|\n          __send__(\"install_#{type}_element\", tag, \"\", occurs, tag, *args)\n        end\n\n        private\n        def maker_target(items)\n          if items.respond_to?(\"items\")\n            # For backward compatibility\n            items = items.items\n          end\n          items.new_item\n        end\n\n        def setup_maker_element(item)\n          super\n          @enclosure.setup_maker(item) if @enclosure\n          @source.setup_maker(item) if @source\n        end\n        \n        class Source < Element\n\n          include RSS09\n\n          [\n            [\"url\", \"\", true]\n          ].each do |name, uri, required|\n            install_get_attribute(name, uri, required)\n          end\n          \n          content_setup\n\n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.url = args[0]\n              self.content = args[1]\n            end\n          end\n\n          private\n          def maker_target(item)\n            item.source\n          end\n\n          def setup_maker_attributes(source)\n            source.url = url\n            source.content = content\n          end\n        end\n\n        class Enclosure < Element\n\n          include RSS09\n\n          [\n            [\"url\", \"\", true],\n            [\"length\", \"\", true, :integer],\n            [\"type\", \"\", true],\n          ].each do |name, uri, required, type|\n            install_get_attribute(name, uri, required, type)\n          end\n\n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.url = args[0]\n              self.length = args[1]\n              self.type = args[2]\n            end\n          end\n\n          private\n          def maker_target(item)\n            item.enclosure\n          end\n\n          def setup_maker_attributes(enclosure)\n            enclosure.url = url\n            enclosure.length = length\n            enclosure.type = type\n          end\n        end\n\n        class Category < Element\n\n          include RSS09\n          \n          [\n            [\"domain\", \"\", false]\n          ].each do |name, uri, required|\n            install_get_attribute(name, uri, required)\n          end\n\n          content_setup\n\n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.domain = args[0]\n              self.content = args[1]\n            end\n          end\n\n          private\n          def maker_target(item)\n            item.new_category\n          end\n\n          def setup_maker_attributes(category)\n            category.domain = domain\n            category.content = content\n          end\n          \n        end\n\n      end\n      \n      class TextInput < Element\n\n        include RSS09\n\n        %w(title description name link).each do |name|\n          install_text_element(name, \"\", nil)\n        end\n\n        def initialize(*args)\n          if Utils.element_initialize_arguments?(args)\n            super\n          else\n            super()\n            self.title = args[0]\n            self.description = args[1]\n            self.name = args[2]\n            self.link = args[3]\n          end\n        end\n\n        private\n        def maker_target(maker)\n          maker.textinput\n        end\n      end\n      \n    end\n    \n  end\n\n  RSS09::ELEMENTS.each do |name|\n    BaseListener.install_get_text_element(\"\", name, name)\n  end\n\n  module ListenerMixin\n    private\n    def initial_start_rss(tag_name, prefix, attrs, ns)\n      check_ns(tag_name, prefix, ns, \"\")\n      \n      @rss = Rss.new(attrs['version'], @version, @encoding, @standalone)\n      @rss.do_validate = @do_validate\n      @rss.xml_stylesheets = @xml_stylesheets\n      @last_element = @rss\n      pr = Proc.new do |text, tags|\n        @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate\n      end\n      @proc_stack.push(pr)\n    end\n    \n  end\n\nend\n"
  },
  {
    "path": "lib/rss/1.0.rb",
    "content": "require \"rss/parser\"\n\nmodule RSS\n\n  module RSS10\n    NSPOOL = {}\n    ELEMENTS = []\n\n    def self.append_features(klass)\n      super\n      \n      klass.install_must_call_validator('', ::RSS::URI)\n    end\n\n  end\n\n  class RDF < Element\n\n    include RSS10\n    include RootElementMixin\n\n    class << self\n\n      def required_uri\n        URI\n      end\n\n    end\n\n    @tag_name = 'RDF'\n\n    PREFIX = 'rdf'\n    URI = \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n\n    install_ns('', ::RSS::URI)\n    install_ns(PREFIX, URI)\n\n    [\n      [\"channel\", nil],\n      [\"image\", \"?\"],\n      [\"item\", \"+\", :children],\n      [\"textinput\", \"?\"],\n    ].each do |tag, occurs, type|\n      type ||= :child\n      __send__(\"install_have_#{type}_element\", tag, ::RSS::URI, occurs)\n    end\n\n    alias_method(:rss_version, :feed_version)\n    def initialize(version=nil, encoding=nil, standalone=nil)\n      super('1.0', version, encoding, standalone)\n      @feed_type = \"rss\"\n    end\n\n    def full_name\n      tag_name_with_prefix(PREFIX)\n    end\n\n    class Li < Element\n\n      include RSS10\n\n      class << self\n        def required_uri\n          URI\n        end\n      end\n      \n      [\n        [\"resource\", [URI, \"\"], true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required)\n      end\n      \n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.resource = args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(PREFIX)\n      end\n    end\n\n    class Seq < Element\n\n      include RSS10\n\n      Li = ::RSS::RDF::Li\n\n      class << self\n        def required_uri\n          URI\n        end\n      end\n\n      @tag_name = 'Seq'\n      \n      install_have_children_element(\"li\", URI, \"*\")\n      install_must_call_validator('rdf', ::RSS::RDF::URI)\n      \n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          @li = args[0] if args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(PREFIX)\n      end\n      \n      def setup_maker(target)\n        lis.each do |li|\n          target << li.resource\n        end\n      end\n    end\n\n    class Bag < Element\n\n      include RSS10\n\n      Li = ::RSS::RDF::Li\n\n      class << self\n        def required_uri\n          URI\n        end\n      end\n\n      @tag_name = 'Bag'\n      \n      install_have_children_element(\"li\", URI, \"*\")\n      install_must_call_validator('rdf', URI)\n      \n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          @li = args[0] if args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(PREFIX)\n      end\n      \n      def setup_maker(target)\n        lis.each do |li|\n          target << li.resource\n        end\n      end\n    end\n\n    class Channel < Element\n\n      include RSS10\n      \n      class << self\n\n        def required_uri\n          ::RSS::URI\n        end\n\n      end\n\n      [\n        [\"about\", URI, true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{PREFIX}:#{name}\")\n      end\n\n      [\n        ['title', nil, :text],\n        ['link', nil, :text],\n        ['description', nil, :text],\n        ['image', '?', :have_child],\n        ['items', nil, :have_child],\n        ['textinput', '?', :have_child],\n      ].each do |tag, occurs, type|\n        __send__(\"install_#{type}_element\", tag, ::RSS::URI, occurs)\n      end\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n        end\n      end\n\n      private\n      def maker_target(maker)\n        maker.channel\n      end\n      \n      def setup_maker_attributes(channel)\n        channel.about = about\n      end\n\n      class Image < Element\n        \n        include RSS10\n\n        class << self\n          \n          def required_uri\n            ::RSS::URI\n          end\n\n        end\n\n        [\n          [\"resource\", URI, true]\n        ].each do |name, uri, required|\n          install_get_attribute(name, uri, required, nil, nil,\n                                \"#{PREFIX}:#{name}\")\n        end\n      \n        def initialize(*args)\n          if Utils.element_initialize_arguments?(args)\n            super\n          else\n            super()\n            self.resource = args[0]\n          end\n        end\n      end\n\n      class Textinput < Element\n        \n        include RSS10\n\n        class << self\n          \n          def required_uri\n            ::RSS::URI\n          end\n\n        end\n\n        [\n          [\"resource\", URI, true]\n        ].each do |name, uri, required|\n          install_get_attribute(name, uri, required, nil, nil,\n                                \"#{PREFIX}:#{name}\")\n        end\n      \n        def initialize(*args)\n          if Utils.element_initialize_arguments?(args)\n            super\n          else\n            super()\n            self.resource = args[0]\n          end\n        end\n      end\n      \n      class Items < Element\n\n        include RSS10\n\n        Seq = ::RSS::RDF::Seq\n\n        class << self\n          \n          def required_uri\n            ::RSS::URI\n          end\n          \n        end\n\n        install_have_child_element(\"Seq\", URI, nil)\n        install_must_call_validator('rdf', URI)\n        \n        def initialize(*args)\n          if Utils.element_initialize_arguments?(args)\n            super\n          else\n            super()\n            self.Seq = args[0]\n          end\n          self.Seq ||= Seq.new\n        end\n\n        def resources\n          if @Seq\n            @Seq.lis.collect do |li|\n              li.resource\n            end\n          else\n            []\n          end\n        end\n      end\n    end\n\n    class Image < Element\n\n      include RSS10\n\n      class << self\n        \n        def required_uri\n          ::RSS::URI\n        end\n\n      end\n\n      [\n        [\"about\", URI, true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{PREFIX}:#{name}\")\n      end\n\n      %w(title url link).each do |name|\n        install_text_element(name, ::RSS::URI, nil)\n      end\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n        end\n      end\n\n      private\n      def maker_target(maker)\n        maker.image\n      end\n    end\n\n    class Item < Element\n\n      include RSS10\n\n      class << self\n\n        def required_uri\n          ::RSS::URI\n        end\n        \n      end\n\n\n      [\n        [\"about\", URI, true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{PREFIX}:#{name}\")\n      end\n\n      [\n        [\"title\", nil],\n        [\"link\", nil],\n        [\"description\", \"?\"],\n      ].each do |tag, occurs|\n        install_text_element(tag, ::RSS::URI, occurs)\n      end\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n        end\n      end\n\n      private\n      def maker_target(items)\n        if items.respond_to?(\"items\")\n          # For backward compatibility\n          items = items.items\n        end\n        items.new_item\n      end\n    end\n\n    class Textinput < Element\n\n      include RSS10\n\n      class << self\n\n        def required_uri\n          ::RSS::URI\n        end\n\n      end\n\n      [\n        [\"about\", URI, true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{PREFIX}:#{name}\")\n      end\n\n      %w(title description name link).each do |name|\n        install_text_element(name, ::RSS::URI, nil)\n      end\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n        end\n      end\n\n      private\n      def maker_target(maker)\n        maker.textinput\n      end\n    end\n\n  end\n\n  RSS10::ELEMENTS.each do |name|\n    BaseListener.install_get_text_element(URI, name, name)\n  end\n\n  module ListenerMixin\n    private\n    def initial_start_RDF(tag_name, prefix, attrs, ns)\n      check_ns(tag_name, prefix, ns, RDF::URI)\n\n      @rss = RDF.new(@version, @encoding, @standalone)\n      @rss.do_validate = @do_validate\n      @rss.xml_stylesheets = @xml_stylesheets\n      @last_element = @rss\n      pr = Proc.new do |text, tags|\n        @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate\n      end\n      @proc_stack.push(pr)\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/rss/2.0.rb",
    "content": "require \"rss/0.9\"\n\nmodule RSS\n\n  class Rss\n\n    class Channel\n\n      [\n        [\"generator\"],\n        [\"ttl\", :integer],\n      ].each do |name, type|\n        install_text_element(name, \"\", \"?\", name, type)\n      end\n\n      [\n        %w(category categories),\n      ].each do |name, plural_name|\n        install_have_children_element(name, \"\", \"*\", name, plural_name)\n      end\n\n      [\n        [\"image\", \"?\"],\n        [\"language\", \"?\"],\n      ].each do |name, occurs|\n        install_model(name, \"\", occurs)\n      end\n\n      Category = Item::Category\n\n      class Item\n      \n        [\n          [\"comments\", \"?\"],\n          [\"author\", \"?\"],\n        ].each do |name, occurs|\n          install_text_element(name, \"\", occurs)\n        end\n\n        [\n          [\"pubDate\", '?'],\n        ].each do |name, occurs|\n          install_date_element(name, \"\", occurs, name, 'rfc822')\n        end\n        alias date pubDate\n        alias date= pubDate=\n\n        [\n          [\"guid\", '?'],\n        ].each do |name, occurs|\n          install_have_child_element(name, \"\", occurs)\n        end\n\n        private\n        alias _setup_maker_element setup_maker_element\n        def setup_maker_element(item)\n          _setup_maker_element(item)\n          @guid.setup_maker(item) if @guid\n        end\n        \n        class Guid < Element\n          \n          include RSS09\n\n          [\n            [\"isPermaLink\", \"\", false, :boolean]\n          ].each do |name, uri, required, type|\n            install_get_attribute(name, uri, required, type)\n          end\n\n          content_setup\n\n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.isPermaLink = args[0]\n              self.content = args[1]\n            end\n          end\n\n          alias_method :_PermaLink?, :PermaLink?\n          private :_PermaLink?\n          def PermaLink?\n            perma = _PermaLink?\n            perma or perma.nil?\n          end\n\n          private\n          def maker_target(item)\n            item.guid\n          end\n\n          def setup_maker_attributes(guid)\n            guid.isPermaLink = isPermaLink\n            guid.content = content\n          end\n        end\n\n      end\n\n    end\n\n  end\n\n  RSS09::ELEMENTS.each do |name|\n    BaseListener.install_get_text_element(\"\", name, name)\n  end\n\nend\n"
  },
  {
    "path": "lib/rss/atom.rb",
    "content": "require 'base64'\nrequire 'rss/parser'\n\nmodule RSS\n  module Atom\n    URI = \"http://www.w3.org/2005/Atom\"\n    XHTML_URI = \"http://www.w3.org/1999/xhtml\"\n\n    module CommonModel\n      NSPOOL = {}\n      ELEMENTS = []\n\n      def self.append_features(klass)\n        super\n        klass.install_must_call_validator(\"atom\", URI)\n        [\n         [\"lang\", :xml],\n         [\"base\", :xml],\n        ].each do |name, uri, required|\n          klass.install_get_attribute(name, uri, required, [nil, :inherit])\n        end\n        klass.class_eval do\n          class << self\n            def required_uri\n              URI\n            end\n\n            def need_parent?\n              true\n            end\n          end\n        end\n      end\n    end\n\n    module ContentModel\n      module ClassMethods\n        def content_type\n          @content_type ||= nil\n        end\n      end\n\n      class << self\n        def append_features(klass)\n          super\n          klass.extend(ClassMethods)\n          klass.content_setup(klass.content_type, klass.tag_name)\n        end\n      end\n\n      def maker_target(target)\n        target\n      end\n\n      private\n      def setup_maker_element_writer\n        \"#{self.class.name.split(/::/).last.downcase}=\"\n      end\n\n      def setup_maker_element(target)\n        target.__send__(setup_maker_element_writer, content)\n        super\n      end\n    end\n\n    module URIContentModel\n      class  << self\n        def append_features(klass)\n          super\n          klass.class_eval do\n            @content_type = [nil, :uri]\n            include(ContentModel)\n          end\n        end\n      end\n    end\n\n    module TextConstruct\n      def self.append_features(klass)\n        super\n        klass.class_eval do\n          [\n           [\"type\", \"\"],\n          ].each do |name, uri, required|\n            install_get_attribute(name, uri, required, :text_type)\n          end\n\n          content_setup\n          add_need_initialize_variable(\"xhtml\")\n\n          class << self\n            def xml_getter\n              \"xhtml\"\n            end\n\n            def xml_setter\n              \"xhtml=\"\n            end\n          end\n        end\n      end\n\n      attr_writer :xhtml\n      def xhtml\n        return @xhtml if @xhtml.nil?\n        if @xhtml.is_a?(XML::Element) and\n            [@xhtml.name, @xhtml.uri] == [\"div\", XHTML_URI]\n          return @xhtml\n        end\n\n        children = @xhtml\n        children = [children] unless children.is_a?(Array)\n        XML::Element.new(\"div\", nil, XHTML_URI,\n                         {\"xmlns\" => XHTML_URI}, children)\n      end\n\n      def have_xml_content?\n        @type == \"xhtml\"\n      end\n\n      def atom_validate(ignore_unknown_element, tags, uri)\n        if have_xml_content?\n          if @xhtml.nil?\n            raise MissingTagError.new(\"div\", tag_name)\n          end\n          unless [@xhtml.name, @xhtml.uri] == [\"div\", XHTML_URI]\n            raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name)\n          end\n        end\n      end\n\n      private\n      def maker_target(target)\n        target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}\n      end\n\n      def setup_maker_attributes(target)\n        target.type = type\n        target.content = content\n        target.xml_content = @xhtml\n      end\n    end\n\n    module PersonConstruct\n      def self.append_features(klass)\n        super\n        klass.class_eval do\n          [\n           [\"name\", nil],\n           [\"uri\", \"?\"],\n           [\"email\", \"?\"],\n          ].each do |tag, occurs|\n            install_have_attribute_element(tag, URI, occurs, nil, :content)\n          end\n        end\n      end\n\n      def maker_target(target)\n        target.__send__(\"new_#{self.class.name.split(/::/).last.downcase}\")\n      end\n\n      class Name < RSS::Element\n        include CommonModel\n        include ContentModel\n      end\n\n      class Uri < RSS::Element\n        include CommonModel\n        include URIContentModel\n      end\n\n      class Email < RSS::Element\n        include CommonModel\n        include ContentModel\n      end\n    end\n\n    module DateConstruct\n      def self.append_features(klass)\n        super\n        klass.class_eval do\n          @content_type = :w3cdtf\n          include(ContentModel)\n        end\n      end\n\n      def atom_validate(ignore_unknown_element, tags, uri)\n        raise NotAvailableValueError.new(tag_name, \"\") if content.nil?\n      end\n    end\n\n    module DuplicateLinkChecker\n      def validate_duplicate_links(links)\n        link_infos = {}\n        links.each do |link|\n          rel = link.rel || \"alternate\"\n          next unless rel == \"alternate\"\n          key = [link.hreflang, link.type]\n          if link_infos.has_key?(key)\n            raise TooMuchTagError.new(\"link\", tag_name)\n          end\n          link_infos[key] = true\n        end\n      end\n    end\n\n    class Feed < RSS::Element\n      include RootElementMixin\n      include CommonModel\n      include DuplicateLinkChecker\n\n      install_ns('', URI)\n\n      [\n       [\"author\", \"*\", :children],\n       [\"category\", \"*\", :children, \"categories\"],\n       [\"contributor\", \"*\", :children],\n       [\"generator\", \"?\"],\n       [\"icon\", \"?\", nil, :content],\n       [\"id\", nil, nil, :content],\n       [\"link\", \"*\", :children],\n       [\"logo\", \"?\"],\n       [\"rights\", \"?\"],\n       [\"subtitle\", \"?\", nil, :content],\n       [\"title\", nil, nil, :content],\n       [\"updated\", nil, nil, :content],\n       [\"entry\", \"*\", :children, \"entries\"],\n      ].each do |tag, occurs, type, *args|\n        type ||= :child\n        __send__(\"install_have_#{type}_element\",\n                 tag, URI, occurs, tag, *args)\n      end\n\n      def initialize(version=nil, encoding=nil, standalone=nil)\n        super(\"1.0\", version, encoding, standalone)\n        @feed_type = \"atom\"\n        @feed_subtype = \"feed\"\n      end\n\n      alias_method :items, :entries\n\n      def have_author?\n        authors.any? {|author| !author.to_s.empty?} or\n          entries.any? {|entry| entry.have_author?(false)}\n      end\n\n      private\n      def atom_validate(ignore_unknown_element, tags, uri)\n        unless have_author?\n          raise MissingTagError.new(\"author\", tag_name)\n        end\n        validate_duplicate_links(links)\n      end\n\n      def have_required_elements?\n        super and have_author?\n      end\n\n      def maker_target(maker)\n        maker.channel\n      end\n\n      def setup_maker_element(channel)\n        prev_dc_dates = channel.dc_dates.to_a.dup\n        super\n        channel.about = id.content if id\n        channel.dc_dates.replace(prev_dc_dates)\n      end\n\n      def setup_maker_elements(channel)\n        super\n        items = channel.maker.items\n        entries.each do |entry|\n          entry.setup_maker(items)\n        end\n      end\n\n      class Author < RSS::Element\n        include CommonModel\n        include PersonConstruct\n      end\n\n      class Category < RSS::Element\n        include CommonModel\n\n        [\n         [\"term\", \"\", true],\n         [\"scheme\", \"\", false, [nil, :uri]],\n         [\"label\", \"\"],\n        ].each do |name, uri, required, type|\n          install_get_attribute(name, uri, required, type)\n        end\n\n        private\n        def maker_target(target)\n          target.new_category\n        end\n      end\n\n      class Contributor < RSS::Element\n        include CommonModel\n        include PersonConstruct\n      end\n\n      class Generator < RSS::Element\n        include CommonModel\n        include ContentModel\n\n        [\n         [\"uri\", \"\", false, [nil, :uri]],\n         [\"version\", \"\"],\n        ].each do |name, uri, required, type|\n          install_get_attribute(name, uri, required, type)\n        end\n\n        private\n        def setup_maker_attributes(target)\n          target.generator do |generator|\n            generator.uri = uri if uri\n            generator.version = version if version\n          end\n        end\n      end\n\n      class Icon < RSS::Element\n        include CommonModel\n        include URIContentModel\n      end\n\n      class Id < RSS::Element\n        include CommonModel\n        include URIContentModel\n      end\n\n      class Link < RSS::Element\n        include CommonModel\n\n        [\n         [\"href\", \"\", true, [nil, :uri]],\n         [\"rel\", \"\"],\n         [\"type\", \"\"],\n         [\"hreflang\", \"\"],\n         [\"title\", \"\"],\n         [\"length\", \"\"],\n        ].each do |name, uri, required, type|\n          install_get_attribute(name, uri, required, type)\n        end\n\n        private\n        def maker_target(target)\n          target.new_link\n        end\n      end\n\n      class Logo < RSS::Element\n        include CommonModel\n        include URIContentModel\n\n        def maker_target(target)\n          target.maker.image\n        end\n\n        private\n        def setup_maker_element_writer\n          \"url=\"\n        end\n      end\n\n      class Rights < RSS::Element\n        include CommonModel\n        include TextConstruct\n      end\n\n      class Subtitle < RSS::Element\n        include CommonModel\n        include TextConstruct\n      end\n\n      class Title < RSS::Element\n        include CommonModel\n        include TextConstruct\n      end\n\n      class Updated < RSS::Element\n        include CommonModel\n        include DateConstruct\n      end\n\n      class Entry < RSS::Element\n        include CommonModel\n        include DuplicateLinkChecker\n\n        [\n         [\"author\", \"*\", :children],\n         [\"category\", \"*\", :children, \"categories\"],\n         [\"content\", \"?\", :child],\n         [\"contributor\", \"*\", :children],\n         [\"id\", nil, nil, :content],\n         [\"link\", \"*\", :children],\n         [\"published\", \"?\", :child, :content],\n         [\"rights\", \"?\", :child],\n         [\"source\", \"?\"],\n         [\"summary\", \"?\", :child],\n         [\"title\", nil],\n         [\"updated\", nil, :child, :content],\n        ].each do |tag, occurs, type, *args|\n          type ||= :attribute\n          __send__(\"install_have_#{type}_element\",\n                   tag, URI, occurs, tag, *args)\n        end\n\n        def have_author?(check_parent=true)\n          authors.any? {|author| !author.to_s.empty?} or\n            (check_parent and @parent and @parent.have_author?) or\n            (source and source.have_author?)\n        end\n\n        private\n        def atom_validate(ignore_unknown_element, tags, uri)\n          unless have_author?\n            raise MissingTagError.new(\"author\", tag_name)\n          end\n          validate_duplicate_links(links)\n        end\n\n        def have_required_elements?\n          super and have_author?\n        end\n\n        def maker_target(items)\n          if items.respond_to?(\"items\")\n            # For backward compatibility\n            items = items.items\n          end\n          items.new_item\n        end\n\n        Author = Feed::Author\n        Category = Feed::Category\n\n        class Content < RSS::Element\n          include CommonModel\n\n          class << self\n            def xml_setter\n              \"xml=\"\n            end\n\n            def xml_getter\n              \"xml\"\n            end\n          end\n\n          [\n           [\"type\", \"\"],\n           [\"src\", \"\", false, [nil, :uri]],\n          ].each do |name, uri, required, type|\n            install_get_attribute(name, uri, required, type)\n          end\n\n          content_setup\n          add_need_initialize_variable(\"xml\")\n\n          attr_writer :xml\n          def have_xml_content?\n            inline_xhtml? or inline_other_xml?\n          end\n\n          def xml\n            return @xml unless inline_xhtml?\n            return @xml if @xml.nil?\n            if @xml.is_a?(XML::Element) and\n                [@xml.name, @xml.uri] == [\"div\", XHTML_URI]\n              return @xml\n            end\n\n            children = @xml\n            children = [children] unless children.is_a?(Array)\n            XML::Element.new(\"div\", nil, XHTML_URI,\n                             {\"xmlns\" => XHTML_URI}, children)\n          end\n\n          def xhtml\n            if inline_xhtml?\n              xml\n            else\n              nil\n            end\n          end\n\n          def atom_validate(ignore_unknown_element, tags, uri)\n            if out_of_line?\n              raise MissingAttributeError.new(tag_name, \"type\") if @type.nil?\n              unless (content.nil? or content.empty?)\n                raise NotAvailableValueError.new(tag_name, content)\n              end\n            elsif inline_xhtml?\n              if @xml.nil?\n                raise MissingTagError.new(\"div\", tag_name)\n              end\n              unless @xml.name == \"div\" and @xml.uri == XHTML_URI\n                raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name)\n              end\n            end\n          end\n\n          def inline_text?\n            !out_of_line? and [nil, \"text\", \"html\"].include?(@type)\n          end\n\n          def inline_html?\n            return false if out_of_line?\n            @type == \"html\" or mime_split == [\"text\", \"html\"]\n          end\n\n          def inline_xhtml?\n            !out_of_line? and @type == \"xhtml\"\n          end\n\n          def inline_other?\n            return false if out_of_line?\n            media_type, subtype = mime_split\n            return false if media_type.nil? or subtype.nil?\n            true\n          end\n\n          def inline_other_text?\n            return false unless inline_other?\n            return false if inline_other_xml?\n\n            media_type, subtype = mime_split\n            return true if \"text\" == media_type.downcase\n            false\n          end\n\n          def inline_other_xml?\n            return false unless inline_other?\n\n            media_type, subtype = mime_split\n            normalized_mime_type = \"#{media_type}/#{subtype}\".downcase\n            if /(?:\\+xml|^xml)$/ =~ subtype or\n                %w(text/xml-external-parsed-entity\n                   application/xml-external-parsed-entity\n                   application/xml-dtd).find {|x| x == normalized_mime_type}\n              return true\n            end\n            false\n          end\n\n          def inline_other_base64?\n            inline_other? and !inline_other_text? and !inline_other_xml?\n          end\n\n          def out_of_line?\n            not @src.nil?\n          end\n\n          def mime_split\n            media_type = subtype = nil\n            if /\\A\\s*([a-z]+)\\/([a-z\\+]+)\\s*(?:;.*)?\\z/i =~ @type.to_s\n              media_type = $1.downcase\n              subtype = $2.downcase\n            end\n            [media_type, subtype]\n          end\n\n          def need_base64_encode?\n            inline_other_base64?\n          end\n\n          private\n          def empty_content?\n            out_of_line? or super\n          end\n        end\n\n        Contributor = Feed::Contributor\n        Id = Feed::Id\n        Link = Feed::Link\n\n        class Published < RSS::Element\n          include CommonModel\n          include DateConstruct\n        end\n\n        Rights = Feed::Rights\n\n        class Source < RSS::Element\n          include CommonModel\n\n          [\n           [\"author\", \"*\", :children],\n           [\"category\", \"*\", :children, \"categories\"],\n           [\"contributor\", \"*\", :children],\n           [\"generator\", \"?\"],\n           [\"icon\", \"?\"],\n           [\"id\", \"?\", nil, :content],\n           [\"link\", \"*\", :children],\n           [\"logo\", \"?\"],\n           [\"rights\", \"?\"],\n           [\"subtitle\", \"?\"],\n           [\"title\", \"?\"],\n           [\"updated\", \"?\", nil, :content],\n          ].each do |tag, occurs, type, *args|\n            type ||= :attribute\n            __send__(\"install_have_#{type}_element\",\n                     tag, URI, occurs, tag, *args)\n          end\n\n          def have_author?\n            !author.to_s.empty?\n          end\n\n          Author = Feed::Author\n          Category = Feed::Category\n          Contributor = Feed::Contributor\n          Generator = Feed::Generator\n          Icon = Feed::Icon\n          Id = Feed::Id\n          Link = Feed::Link\n          Logo = Feed::Logo\n          Rights = Feed::Rights\n          Subtitle = Feed::Subtitle\n          Title = Feed::Title\n          Updated = Feed::Updated\n        end\n\n        class Summary < RSS::Element\n          include CommonModel\n          include TextConstruct\n        end\n\n        Title = Feed::Title\n        Updated = Feed::Updated\n      end\n    end\n\n    class Entry < RSS::Element\n      include RootElementMixin\n      include CommonModel\n      include DuplicateLinkChecker\n\n      [\n       [\"author\", \"*\", :children],\n       [\"category\", \"*\", :children, \"categories\"],\n       [\"content\", \"?\"],\n       [\"contributor\", \"*\", :children],\n       [\"id\", nil, nil, :content],\n       [\"link\", \"*\", :children],\n       [\"published\", \"?\", :child, :content],\n       [\"rights\", \"?\"],\n       [\"source\", \"?\"],\n       [\"summary\", \"?\"],\n       [\"title\", nil],\n       [\"updated\", nil, nil, :content],\n      ].each do |tag, occurs, type, *args|\n        type ||= :attribute\n        __send__(\"install_have_#{type}_element\",\n                 tag, URI, occurs, tag, *args)\n      end\n\n      def initialize(version=nil, encoding=nil, standalone=nil)\n        super(\"1.0\", version, encoding, standalone)\n        @feed_type = \"atom\"\n        @feed_subtype = \"entry\"\n      end\n\n      def items\n        [self]\n      end\n\n      def setup_maker(maker)\n        maker = maker.maker if maker.respond_to?(\"maker\")\n        super(maker)\n      end\n\n      def have_author?\n        authors.any? {|author| !author.to_s.empty?} or\n          (source and source.have_author?)\n      end\n\n      private\n      def atom_validate(ignore_unknown_element, tags, uri)\n        unless have_author?\n          raise MissingTagError.new(\"author\", tag_name)\n        end\n        validate_duplicate_links(links)\n      end\n\n      def have_required_elements?\n        super and have_author?\n      end\n\n      def maker_target(maker)\n        maker.items.new_item\n      end\n\n      Author = Feed::Entry::Author\n      Category = Feed::Entry::Category\n      Content = Feed::Entry::Content\n      Contributor = Feed::Entry::Contributor\n      Id = Feed::Entry::Id\n      Link = Feed::Entry::Link\n      Published = Feed::Entry::Published\n      Rights = Feed::Entry::Rights\n      Source = Feed::Entry::Source\n      Summary = Feed::Entry::Summary\n      Title = Feed::Entry::Title\n      Updated = Feed::Entry::Updated\n    end\n  end\n\n  Atom::CommonModel::ELEMENTS.each do |name|\n    BaseListener.install_get_text_element(Atom::URI, name, \"#{name}=\")\n  end\n\n  module ListenerMixin\n    private\n    def initial_start_feed(tag_name, prefix, attrs, ns)\n      check_ns(tag_name, prefix, ns, Atom::URI)\n\n      @rss = Atom::Feed.new(@version, @encoding, @standalone)\n      @rss.do_validate = @do_validate\n      @rss.xml_stylesheets = @xml_stylesheets\n      @rss.lang = attrs[\"xml:lang\"]\n      @rss.base = attrs[\"xml:base\"]\n      @last_element = @rss\n      pr = Proc.new do |text, tags|\n        @rss.validate_for_stream(tags) if @do_validate\n      end\n      @proc_stack.push(pr)\n    end\n\n    def initial_start_entry(tag_name, prefix, attrs, ns)\n      check_ns(tag_name, prefix, ns, Atom::URI)\n\n      @rss = Atom::Entry.new(@version, @encoding, @standalone)\n      @rss.do_validate = @do_validate\n      @rss.xml_stylesheets = @xml_stylesheets\n      @rss.lang = attrs[\"xml:lang\"]\n      @rss.base = attrs[\"xml:base\"]\n      @last_element = @rss\n      pr = Proc.new do |text, tags|\n        @rss.validate_for_stream(tags) if @do_validate\n      end\n      @proc_stack.push(pr)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/content/1.0.rb",
    "content": "require 'rss/1.0'\nrequire 'rss/content'\n\nmodule RSS\n  RDF.install_ns(CONTENT_PREFIX, CONTENT_URI)\n\n  class RDF\n    class Item; include ContentModel; end\n  end\nend\n"
  },
  {
    "path": "lib/rss/content/2.0.rb",
    "content": "require \"rss/2.0\"\nrequire \"rss/content\"\n\nmodule RSS\n  Rss.install_ns(CONTENT_PREFIX, CONTENT_URI)\n\n  class Rss\n    class Channel\n      class Item; include ContentModel; end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/content.rb",
    "content": "require \"rss/rss\"\n\nmodule RSS\n  CONTENT_PREFIX = 'content'\n  CONTENT_URI = \"http://purl.org/rss/1.0/modules/content/\"\n\n  module ContentModel\n    extend BaseModel\n\n    ELEMENTS = [\"#{CONTENT_PREFIX}_encoded\"]\n\n    def self.append_features(klass)\n      super\n\n      klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)\n      ELEMENTS.each do |full_name|\n        name = full_name[(CONTENT_PREFIX.size + 1)..-1]\n        klass.install_text_element(name, CONTENT_URI, \"?\", full_name)\n      end\n    end\n  end\n\n  prefix_size = CONTENT_PREFIX.size + 1\n  ContentModel::ELEMENTS.each do |full_name|\n    name = full_name[prefix_size..-1]\n    BaseListener.install_get_text_element(CONTENT_URI, name, full_name)\n  end\nend\n\nrequire 'rss/content/1.0'\nrequire 'rss/content/2.0'\n"
  },
  {
    "path": "lib/rss/converter.rb",
    "content": "require \"rss/utils\"\n\nmodule RSS\n\n  class Converter\n    \n    include Utils\n\n    def initialize(to_enc, from_enc=nil)\n      normalized_to_enc = to_enc.downcase.gsub(/-/, '_')\n      from_enc ||= 'utf-8'\n      normalized_from_enc = from_enc.downcase.gsub(/-/, '_')\n      if normalized_to_enc == normalized_from_enc\n        def_same_enc()\n      else\n        def_diff_enc = \"def_to_#{normalized_to_enc}_from_#{normalized_from_enc}\"\n        if respond_to?(def_diff_enc)\n          __send__(def_diff_enc)\n        else\n          def_else_enc(to_enc, from_enc)\n        end\n      end\n    end\n\n    def convert(value)\n      value\n    end\n\n    def def_convert(depth=0)\n      instance_eval(<<-EOC, *get_file_and_line_from_caller(depth))\n      def convert(value)\n        if value.kind_of?(String)\n          #{yield('value')}\n        else\n          value\n        end\n      end\n      EOC\n    end\n\n    def def_iconv_convert(to_enc, from_enc, depth=0)\n      begin\n        require \"iconv\"\n        @iconv = Iconv.new(to_enc, from_enc)\n        def_convert(depth+1) do |value|\n          <<-EOC\n          begin\n            @iconv.iconv(#{value})\n          rescue Iconv::Failure\n            raise ConversionError.new(#{value}, \"#{to_enc}\", \"#{from_enc}\")\n          end\n          EOC\n        end\n      rescue LoadError, ArgumentError, SystemCallError\n        raise UnknownConversionMethodError.new(to_enc, from_enc)\n      end\n    end\n    \n    def def_else_enc(to_enc, from_enc)\n      def_iconv_convert(to_enc, from_enc, 0)\n    end\n    \n    def def_same_enc()\n      def_convert do |value|\n        value\n      end\n    end\n\n    def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)\n      begin\n        require \"uconv\"\n        def_convert(1) do |value|\n          <<-EOC\n          begin\n            Uconv.#{meth}(#{value})\n          rescue Uconv::Error\n            raise ConversionError.new(#{value}, \"#{to_enc}\", \"#{from_enc}\")\n          end\n          EOC\n        end\n      rescue LoadError\n        require 'nkf'\n        if NKF.const_defined?(:UTF8)\n          def_convert(1) do |value|\n            \"NKF.nkf(#{nkf_arg.dump}, #{value})\"\n          end\n        else\n          def_iconv_convert(to_enc, from_enc, 1)\n        end\n      end\n    end\n\n    def def_to_euc_jp_from_utf_8\n      def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')\n    end\n    \n    def def_to_utf_8_from_euc_jp\n      def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')\n    end\n    \n    def def_to_shift_jis_from_utf_8\n      def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')\n    end\n    \n    def def_to_utf_8_from_shift_jis\n      def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')\n    end\n    \n    def def_to_euc_jp_from_shift_jis\n      require \"nkf\"\n      def_convert do |value|\n        \"NKF.nkf('-Se', #{value})\"\n      end\n    end\n    \n    def def_to_shift_jis_from_euc_jp\n      require \"nkf\"\n      def_convert do |value|\n        \"NKF.nkf('-Es', #{value})\"\n      end\n    end\n    \n    def def_to_euc_jp_from_iso_2022_jp\n      require \"nkf\"\n      def_convert do |value|\n        \"NKF.nkf('-Je', #{value})\"\n      end\n    end\n    \n    def def_to_iso_2022_jp_from_euc_jp\n      require \"nkf\"\n      def_convert do |value|\n        \"NKF.nkf('-Ej', #{value})\"\n      end\n    end\n\n    def def_to_utf_8_from_iso_8859_1\n      def_convert do |value|\n        \"#{value}.unpack('C*').pack('U*')\"\n      end\n    end\n    \n    def def_to_iso_8859_1_from_utf_8\n      def_convert do |value|\n        <<-EOC\n        array_utf8 = #{value}.unpack('U*')\n        array_enc = []\n        array_utf8.each do |num|\n          if num <= 0xFF\n            array_enc << num\n          else\n            array_enc.concat \"&\\#\\#{num};\".unpack('C*')\n          end\n        end\n        array_enc.pack('C*')\n        EOC\n      end\n    end\n    \n  end\n  \nend\n"
  },
  {
    "path": "lib/rss/dublincore/1.0.rb",
    "content": "require \"rss/1.0\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n  RDF.install_ns(DC_PREFIX, DC_URI)\n\n  class RDF\n    class Channel; include DublinCoreModel; end\n    class Image; include DublinCoreModel; end\n    class Item; include DublinCoreModel; end\n    class Textinput; include DublinCoreModel; end\n  end\nend\n"
  },
  {
    "path": "lib/rss/dublincore/2.0.rb",
    "content": "require \"rss/2.0\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n  Rss.install_ns(DC_PREFIX, DC_URI)\n\n  class Rss\n    class Channel\n      include DublinCoreModel\n      class Item; include DublinCoreModel; end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/dublincore/atom.rb",
    "content": "require \"rss/atom\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n  module Atom\n    Feed.install_ns(DC_PREFIX, DC_URI)\n\n    class Feed\n      include DublinCoreModel\n      class Entry; include DublinCoreModel; end\n    end\n\n    class Entry\n      include DublinCoreModel\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/dublincore.rb",
    "content": "require \"rss/rss\"\n\nmodule RSS\n  DC_PREFIX = 'dc'\n  DC_URI = \"http://purl.org/dc/elements/1.1/\"\n\n  module BaseDublinCoreModel\n    def append_features(klass)\n      super\n\n      return if klass.instance_of?(Module)\n      DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|\n        plural = plural_name || \"#{name}s\"\n        full_name = \"#{DC_PREFIX}_#{name}\"\n        full_plural_name = \"#{DC_PREFIX}_#{plural}\"\n        klass_name = \"DublinCore#{Utils.to_class_name(name)}\"\n        klass.install_must_call_validator(DC_PREFIX, DC_URI)\n        klass.install_have_children_element(name, DC_URI, \"*\",\n                                            full_name, full_plural_name)\n        klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))\n          remove_method :#{full_name}\n          remove_method :#{full_name}=\n          remove_method :set_#{full_name}\n\n          def #{full_name}\n            @#{full_name}.first and @#{full_name}.first.value\n          end\n          \n          def #{full_name}=(new_value)\n            @#{full_name}[0] = Utils.new_with_value_if_need(#{klass_name}, new_value)\n          end\n          alias set_#{full_name} #{full_name}=\n        EOC\n      end\n      klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))\n        if method_defined?(:date)\n          alias date_without_#{DC_PREFIX}_date= date=\n\n          def date=(value)\n            self.date_without_#{DC_PREFIX}_date = value\n            self.#{DC_PREFIX}_date = value\n          end\n        else\n          alias date #{DC_PREFIX}_date\n          alias date= #{DC_PREFIX}_date=\n        end\n\n        # For backward compatibility\n        alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list\n      EOC\n    end\n  end\n  \n  module DublinCoreModel\n\n    extend BaseModel\n    extend BaseDublinCoreModel\n\n    TEXT_ELEMENTS = {\n      \"title\" => nil,\n      \"description\" => nil,\n      \"creator\" => nil,\n      \"subject\" => nil,\n      \"publisher\" => nil,\n      \"contributor\" => nil,\n      \"type\" => nil,\n      \"format\" => nil,\n      \"identifier\" => nil,\n      \"source\" => nil,\n      \"language\" => nil,\n      \"relation\" => nil,\n      \"coverage\" => nil,\n      \"rights\" => \"rights_list\"\n    }\n\n    DATE_ELEMENTS = {\n      \"date\" => \"w3cdtf\",\n    }\n    \n    ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a\n    DublinCoreModel::DATE_ELEMENTS.each do |name, |\n      ELEMENT_NAME_INFOS << [name, nil]\n    end\n    \n    ELEMENTS = TEXT_ELEMENTS.keys + DATE_ELEMENTS.keys\n\n    ELEMENTS.each do |name, plural_name|\n      module_eval(<<-EOC, *get_file_and_line_from_caller(0))\n        class DublinCore#{Utils.to_class_name(name)} < Element\n          include RSS10\n          \n          content_setup\n\n          class << self\n            def required_prefix\n              DC_PREFIX\n            end\n        \n            def required_uri\n              DC_URI\n            end\n          end\n\n          @tag_name = #{name.dump}\n\n          alias_method(:value, :content)\n          alias_method(:value=, :content=)\n          \n          def initialize(*args)\n            if Utils.element_initialize_arguments?(args)\n              super\n            else\n              super()\n              self.content = args[0]\n            end\n          end\n      \n          def full_name\n            tag_name_with_prefix(DC_PREFIX)\n          end\n\n          def maker_target(target)\n            target.new_#{name}\n          end\n\n          def setup_maker_attributes(#{name})\n            #{name}.content = content\n          end\n        end\n      EOC\n    end\n\n    DATE_ELEMENTS.each do |name, type|\n      tag_name = \"#{DC_PREFIX}:#{name}\"\n      module_eval(<<-EOC, *get_file_and_line_from_caller(0))\n        class DublinCore#{Utils.to_class_name(name)} < Element\n          remove_method(:content=)\n          remove_method(:value=)\n\n          date_writer(\"content\", #{type.dump}, #{tag_name.dump})\n\n          alias_method(:value=, :content=)\n        end\n      EOC\n    end\n  end\n\n  # For backward compatibility\n  DublincoreModel = DublinCoreModel\n\n  DublinCoreModel::ELEMENTS.each do |name|\n    class_name = Utils.to_class_name(name)\n    BaseListener.install_class_name(DC_URI, name, \"DublinCore#{class_name}\")\n  end\n\n  DublinCoreModel::ELEMENTS.collect! {|name| \"#{DC_PREFIX}_#{name}\"}\nend\n\nrequire 'rss/dublincore/1.0'\nrequire 'rss/dublincore/2.0'\nrequire 'rss/dublincore/atom'\n"
  },
  {
    "path": "lib/rss/image.rb",
    "content": "require 'rss/1.0'\nrequire 'rss/dublincore'\n\nmodule RSS\n\n  IMAGE_PREFIX = 'image'\n  IMAGE_URI = 'http://purl.org/rss/1.0/modules/image/'\n\n  RDF.install_ns(IMAGE_PREFIX, IMAGE_URI)\n\n  IMAGE_ELEMENTS = []\n\n  %w(item favicon).each do |name|\n    class_name = Utils.to_class_name(name)\n    BaseListener.install_class_name(IMAGE_URI, name, \"Image#{class_name}\")\n    IMAGE_ELEMENTS << \"#{IMAGE_PREFIX}_#{name}\"\n  end\n  \n  module ImageModelUtils\n    def validate_one_tag_name(ignore_unknown_element, name, tags)\n      if !ignore_unknown_element\n        invalid = tags.find {|tag| tag != name}\n        raise UnknownTagError.new(invalid, IMAGE_URI) if invalid\n      end\n      raise TooMuchTagError.new(name, tag_name) if tags.size > 1\n    end\n  end\n  \n  module ImageItemModel\n    include ImageModelUtils\n    extend BaseModel\n\n    def self.append_features(klass)\n      super\n\n      klass.install_have_child_element(\"item\", IMAGE_URI, \"?\",\n                                       \"#{IMAGE_PREFIX}_item\")\n      klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)\n    end\n\n    class ImageItem < Element\n      include RSS10\n      include DublinCoreModel\n\n      @tag_name = \"item\"\n      \n      class << self\n        def required_prefix\n          IMAGE_PREFIX\n        end\n        \n        def required_uri\n          IMAGE_URI\n        end\n      end\n\n      install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)\n\n      [\n        [\"about\", ::RSS::RDF::URI, true],\n        [\"resource\", ::RSS::RDF::URI, false],\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{::RSS::RDF::PREFIX}:#{name}\")\n      end\n\n      %w(width height).each do |tag|\n        full_name = \"#{IMAGE_PREFIX}_#{tag}\"\n        disp_name = \"#{IMAGE_PREFIX}:#{tag}\"\n        install_text_element(tag, IMAGE_URI, \"?\",\n                             full_name, :integer, disp_name)\n        BaseListener.install_get_text_element(IMAGE_URI, tag, full_name)\n      end\n\n      alias width= image_width=\n      alias width image_width\n      alias height= image_height=\n      alias height image_height\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n          self.resource = args[1]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(IMAGE_PREFIX)\n      end\n\n      private\n      def maker_target(target)\n        target.image_item\n      end\n\n      def setup_maker_attributes(item)\n        item.about = self.about\n        item.resource = self.resource\n      end\n    end\n  end\n  \n  module ImageFaviconModel\n    include ImageModelUtils\n    extend BaseModel\n    \n    def self.append_features(klass)\n      super\n\n      unless klass.class == Module\n        klass.install_have_child_element(\"favicon\", IMAGE_URI, \"?\",\n                                         \"#{IMAGE_PREFIX}_favicon\")\n        klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)\n      end\n    end\n\n    class ImageFavicon < Element\n      include RSS10\n      include DublinCoreModel\n\n      @tag_name = \"favicon\"\n      \n      class << self\n        def required_prefix\n          IMAGE_PREFIX\n        end\n        \n        def required_uri\n          IMAGE_URI\n        end\n      end\n\n      [\n        [\"about\", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX],\n        [\"size\", IMAGE_URI, true, IMAGE_PREFIX],\n      ].each do |name, uri, required, prefix|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{prefix}:#{name}\")\n      end\n\n      AVAILABLE_SIZES = %w(small medium large)\n      alias_method :set_size, :size=\n      private :set_size\n      def size=(new_value)\n        if @do_validate and !new_value.nil?\n          new_value = new_value.strip\n          unless AVAILABLE_SIZES.include?(new_value)\n            attr_name = \"#{IMAGE_PREFIX}:size\"\n            raise NotAvailableValueError.new(full_name, new_value, attr_name)\n          end\n        end\n        set_size(new_value)\n      end\n      \n      alias image_size= size=\n      alias image_size size\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n          self.size = args[1]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(IMAGE_PREFIX)\n      end\n\n      private\n      def maker_target(target)\n        target.image_favicon\n      end\n\n      def setup_maker_attributes(favicon)\n        favicon.about = self.about\n        favicon.size = self.size\n      end\n    end\n\n  end\n\n  class RDF\n    class Channel; include ImageFaviconModel; end\n    class Item; include ImageItemModel; end\n  end\n\nend\n"
  },
  {
    "path": "lib/rss/itunes.rb",
    "content": "require 'rss/2.0'\n\nmodule RSS\n  ITUNES_PREFIX = 'itunes'\n  ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd'\n\n  Rss.install_ns(ITUNES_PREFIX, ITUNES_URI)\n\n  module ITunesModelUtils\n    include Utils\n\n    def def_class_accessor(klass, name, type, *args)\n        normalized_name = name.gsub(/-/, \"_\")\n      full_name = \"#{ITUNES_PREFIX}_#{normalized_name}\"\n      klass_name = \"ITunes#{Utils.to_class_name(normalized_name)}\"\n\n      case type\n      when :element, :attribute\n        klass::ELEMENTS << full_name\n        def_element_class_accessor(klass, name, full_name, klass_name, *args)\n      when :elements\n        klass::ELEMENTS << full_name\n        def_elements_class_accessor(klass, name, full_name, klass_name, *args)\n      else\n        klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)\n        klass.install_text_element(normalized_name, ITUNES_URI, \"?\",\n                                   full_name, type, name)\n      end\n    end\n\n    def def_element_class_accessor(klass, name, full_name, klass_name,\n                                   recommended_attribute_name=nil)\n      klass.install_have_child_element(name, ITUNES_PREFIX, \"?\", full_name)\n    end\n\n    def def_elements_class_accessor(klass, name, full_name, klass_name,\n                                    plural_name, recommended_attribute_name=nil)\n      full_plural_name = \"#{ITUNES_PREFIX}_#{plural_name}\"\n      klass.install_have_children_element(name, ITUNES_PREFIX, \"*\",\n                                          full_name, full_plural_name)\n    end\n  end\n\n  module ITunesBaseModel\n    extend ITunesModelUtils\n\n    ELEMENTS = []\n\n    ELEMENT_INFOS = [[\"author\"],\n                     [\"block\", :yes_other],\n                     [\"explicit\", :yes_clean_other],\n                     [\"keywords\", :csv],\n                     [\"subtitle\"],\n                     [\"summary\"]]\n  end\n\n  module ITunesChannelModel\n    extend BaseModel\n    extend ITunesModelUtils\n    include ITunesBaseModel\n\n    ELEMENTS = []\n\n    class << self\n      def append_features(klass)\n        super\n\n        return if klass.instance_of?(Module)\n        ELEMENT_INFOS.each do |name, type, *additional_infos|\n          def_class_accessor(klass, name, type, *additional_infos)\n        end\n      end\n    end\n\n    ELEMENT_INFOS = [\n                     [\"category\", :elements, \"categories\", \"text\"],\n                     [\"image\", :attribute, \"href\"],\n                     [\"owner\", :element],\n                     [\"new-feed-url\"],\n                    ] + ITunesBaseModel::ELEMENT_INFOS\n\n    class ITunesCategory < Element\n      include RSS09\n\n      @tag_name = \"category\"\n\n      class << self\n        def required_prefix\n          ITUNES_PREFIX\n        end\n\n        def required_uri\n          ITUNES_URI\n        end\n      end\n\n      [\n        [\"text\", \"\", true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required)\n      end\n\n      ITunesCategory = self\n      install_have_children_element(\"category\", ITUNES_URI, \"*\",\n                                    \"#{ITUNES_PREFIX}_category\",\n                                    \"#{ITUNES_PREFIX}_categories\")\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.text = args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(ITUNES_PREFIX)\n      end\n\n      private\n      def maker_target(categories)\n        if text or !itunes_categories.empty?\n          categories.new_category\n        else\n          nil\n        end\n      end\n\n      def setup_maker_attributes(category)\n        category.text = text if text\n      end\n\n      def setup_maker_elements(category)\n        super(category)\n        itunes_categories.each do |sub_category|\n          sub_category.setup_maker(category)\n        end\n      end\n    end\n\n    class ITunesImage < Element\n      include RSS09\n\n      @tag_name = \"image\"\n\n      class << self\n        def required_prefix\n          ITUNES_PREFIX\n        end\n\n        def required_uri\n          ITUNES_URI\n        end\n      end\n\n      [\n        [\"href\", \"\", true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required)\n      end\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.href = args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(ITUNES_PREFIX)\n      end\n\n      private\n      def maker_target(target)\n        if href\n          target.itunes_image {|image| image}\n        else\n          nil\n        end\n      end\n\n      def setup_maker_attributes(image)\n        image.href = href\n      end\n    end\n\n    class ITunesOwner < Element\n      include RSS09\n\n      @tag_name = \"owner\"\n\n      class << self\n        def required_prefix\n          ITUNES_PREFIX\n        end\n\n        def required_uri\n          ITUNES_URI\n        end\n      end\n\n      install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)\n      [\n        [\"name\"],\n        [\"email\"],\n      ].each do |name,|\n        ITunesBaseModel::ELEMENT_INFOS << name\n        install_text_element(name, ITUNES_URI, nil, \"#{ITUNES_PREFIX}_#{name}\")\n      end\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.itunes_name = args[0]\n          self.itunes_email = args[1]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(ITUNES_PREFIX)\n      end\n\n      private\n      def maker_target(target)\n        target.itunes_owner\n      end\n\n      def setup_maker_element(owner)\n        super(owner)\n        owner.itunes_name = itunes_name\n        owner.itunes_email = itunes_email\n      end\n    end\n  end\n\n  module ITunesItemModel\n    extend BaseModel\n    extend ITunesModelUtils\n    include ITunesBaseModel\n\n    class << self\n      def append_features(klass)\n        super\n\n        return if klass.instance_of?(Module)\n        ELEMENT_INFOS.each do |name, type|\n          def_class_accessor(klass, name, type)\n        end\n      end\n    end\n\n    ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS +\n      [[\"duration\", :element, \"content\"]]\n\n    class ITunesDuration < Element\n      include RSS09\n\n      @tag_name = \"duration\"\n\n      class << self\n        def required_prefix\n          ITUNES_PREFIX\n        end\n\n        def required_uri\n          ITUNES_URI\n        end\n\n        def parse(duration, do_validate=true)\n          if do_validate and /\\A(?:\n                                  \\d?\\d:[0-5]\\d:[0-5]\\d|\n                                  [0-5]?\\d:[0-5]\\d\n                                )\\z/x !~ duration\n            raise ArgumentError,\n                    \"must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: \" +\n                    duration.inspect\n          end\n\n          components = duration.split(':')\n          components[3..-1] = nil if components.size > 3\n\n          components.unshift(\"00\") until components.size == 3\n\n          components.collect do |component|\n            component.to_i\n          end\n        end\n\n        def construct(hour, minute, second)\n          components = [minute, second]\n          if components.include?(nil)\n            nil\n          else\n            components.unshift(hour) if hour and hour > 0\n            components.collect do |component|\n              \"%02d\" % component\n            end.join(\":\")\n          end\n        end\n      end\n\n      content_setup\n      alias_method(:value, :content)\n      remove_method(:content=)\n\n      attr_reader :hour, :minute, :second\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          args = args[0] if args.size == 1 and args[0].is_a?(Array)\n          if args.size == 1\n            self.content = args[0]\n          elsif args.size > 3\n            raise ArgumentError,\n                    \"must be (do_validate, params), (content), \" +\n                    \"(minute, second), ([minute, second]), \"  +\n                    \"(hour, minute, second) or ([hour, minute, second]): \" +\n                    args.inspect\n          else\n            @second, @minute, @hour = args.reverse\n            update_content\n          end\n        end\n      end\n\n      def content=(value)\n        if value.nil?\n          @content = nil\n        elsif value.is_a?(self.class)\n          self.content = value.content\n        else\n          begin\n            @hour, @minute, @second = self.class.parse(value, @do_validate)\n          rescue ArgumentError\n            raise NotAvailableValueError.new(tag_name, value)\n          end\n          @content = value\n        end\n      end\n      alias_method(:value=, :content=)\n\n      def hour=(hour)\n        @hour = @do_validate ? Integer(hour) : hour.to_i\n        update_content\n        hour\n      end\n\n      def minute=(minute)\n        @minute = @do_validate ? Integer(minute) : minute.to_i\n        update_content\n        minute\n      end\n\n      def second=(second)\n        @second = @do_validate ? Integer(second) : second.to_i\n        update_content\n        second\n      end\n\n      def full_name\n        tag_name_with_prefix(ITUNES_PREFIX)\n      end\n\n      private\n      def update_content\n        @content = self.class.construct(hour, minute, second)\n      end\n\n      def maker_target(target)\n        if @content\n          target.itunes_duration {|duration| duration}\n        else\n          nil\n        end\n      end\n\n      def setup_maker_element(duration)\n        super(duration)\n        duration.content = @content\n      end\n    end\n  end\n\n  class Rss\n    class Channel\n      include ITunesChannelModel\n      class Item; include ITunesItemModel; end\n    end\n  end\n\n  element_infos =\n    ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS\n  element_infos.each do |name, type|\n    case type\n    when :element, :elements, :attribute\n      class_name = Utils.to_class_name(name)\n      BaseListener.install_class_name(ITUNES_URI, name, \"ITunes#{class_name}\")\n    else\n      accessor_base = \"#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}\"\n      BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/0.9.rb",
    "content": "require \"rss/0.9\"\n\nrequire \"rss/maker/base\"\n\nmodule RSS\n  module Maker\n    \n    class RSS09 < RSSBase\n      \n      def initialize(feed_version=\"0.92\")\n        super\n        @feed_type = \"rss\"\n      end\n      \n      private\n      def make_feed\n        Rss.new(@feed_version, @version, @encoding, @standalone)\n      end\n\n      def setup_elements(rss)\n        setup_channel(rss)\n      end\n\n      class Channel < ChannelBase\n        def to_feed(rss)\n          channel = Rss::Channel.new\n          set = setup_values(channel)\n          _not_set_required_variables = not_set_required_variables\n          if _not_set_required_variables.empty?\n            rss.channel = channel\n            set_parent(channel, rss)\n            setup_items(rss)\n            setup_image(rss)\n            setup_textinput(rss)\n            setup_other_elements(rss, channel)\n            rss\n          else\n            raise NotSetError.new(\"maker.channel\", _not_set_required_variables)\n          end\n        end\n        \n        private\n        def setup_items(rss)\n          @maker.items.to_feed(rss)\n        end\n        \n        def setup_image(rss)\n          @maker.image.to_feed(rss)\n        end\n        \n        def setup_textinput(rss)\n          @maker.textinput.to_feed(rss)\n        end\n        \n        def variables\n          super + [\"pubDate\"]\n        end\n\n        def required_variable_names\n          %w(link language)\n        end\n\n        def not_set_required_variables\n          vars = super\n          vars << \"description\" unless description {|d| d.have_required_values?}\n          vars << \"title\" unless title {|t| t.have_required_values?}\n          vars\n        end\n\n        class SkipDays < SkipDaysBase\n          def to_feed(rss, channel)\n            unless @days.empty?\n              skipDays = Rss::Channel::SkipDays.new\n              channel.skipDays = skipDays\n              set_parent(skipDays, channel)\n              @days.each do |day|\n                day.to_feed(rss, skipDays.days)\n              end\n            end\n          end\n          \n          class Day < DayBase\n            def to_feed(rss, days)\n              day = Rss::Channel::SkipDays::Day.new\n              set = setup_values(day)\n              if set\n                days << day\n                set_parent(day, days)\n                setup_other_elements(rss, day)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n        end\n        \n        class SkipHours < SkipHoursBase\n          def to_feed(rss, channel)\n            unless @hours.empty?\n              skipHours = Rss::Channel::SkipHours.new\n              channel.skipHours = skipHours\n              set_parent(skipHours, channel)\n              @hours.each do |hour|\n                hour.to_feed(rss, skipHours.hours)\n              end\n            end\n          end\n          \n          class Hour < HourBase\n            def to_feed(rss, hours)\n              hour = Rss::Channel::SkipHours::Hour.new\n              set = setup_values(hour)\n              if set\n                hours << hour\n                set_parent(hour, hours)\n                setup_other_elements(rss, hour)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n        end\n        \n        class Cloud < CloudBase\n          def to_feed(*args)\n          end\n        end\n\n        class Categories < CategoriesBase\n          def to_feed(*args)\n          end\n\n          class Category < CategoryBase\n          end\n        end\n\n        class Links < LinksBase\n          def to_feed(rss, channel)\n            return if @links.empty?\n            @links.first.to_feed(rss, channel)\n          end\n\n          class Link < LinkBase\n            def to_feed(rss, channel)\n              if have_required_values?\n                channel.link = href\n              else\n                raise NotSetError.new(\"maker.channel.link\",\n                                      not_set_required_variables)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(href)\n            end\n          end\n        end\n\n        class Authors < AuthorsBase\n          def to_feed(rss, channel)\n          end\n\n          class Author < AuthorBase\n            def to_feed(rss, channel)\n            end\n          end\n        end\n\n        class Contributors < ContributorsBase\n          def to_feed(rss, channel)\n          end\n\n          class Contributor < ContributorBase\n          end\n        end\n\n        class Generator < GeneratorBase\n          def to_feed(rss, channel)\n          end\n        end\n\n        class Copyright < CopyrightBase\n          def to_feed(rss, channel)\n            channel.copyright = content if have_required_values?\n          end\n\n          private\n          def required_variable_names\n            %w(content)\n          end\n        end\n\n        class Description < DescriptionBase\n          def to_feed(rss, channel)\n            channel.description = content if have_required_values?\n          end\n\n          private\n          def required_variable_names\n            %w(content)\n          end\n        end\n\n        class Title < TitleBase\n          def to_feed(rss, channel)\n            channel.title = content if have_required_values?\n          end\n\n          private\n          def required_variable_names\n            %w(content)\n          end\n        end\n      end\n\n      class Image < ImageBase\n        def to_feed(rss)\n          image = Rss::Channel::Image.new\n          set = setup_values(image)\n          if set\n            image.link = link\n            rss.channel.image = image\n            set_parent(image, rss.channel)\n            setup_other_elements(rss, image)\n          elsif required_element?\n            raise NotSetError.new(\"maker.image\", not_set_required_variables)\n          end\n        end\n\n        private\n        def required_variable_names\n          %w(url title link)\n        end\n\n        def required_element?\n          true\n        end\n      end\n      \n      class Items < ItemsBase\n        def to_feed(rss)\n          if rss.channel\n            normalize.each do |item|\n              item.to_feed(rss)\n            end\n            setup_other_elements(rss, rss.items)\n          end\n        end\n        \n        class Item < ItemBase\n          def to_feed(rss)\n            item = Rss::Channel::Item.new\n            set = setup_values(item)\n            _not_set_required_variables = not_set_required_variables\n            if _not_set_required_variables.empty?\n              rss.items << item\n              set_parent(item, rss.channel)\n              setup_other_elements(rss, item)\n            elsif variable_is_set?\n              raise NotSetError.new(\"maker.items\", _not_set_required_variables)\n            end\n          end\n\n          private\n          def required_variable_names\n            []\n          end\n\n          def not_set_required_variables\n            vars = super\n            if @maker.feed_version == \"0.91\"\n              vars << \"title\" unless title {|t| t.have_required_values?}\n              vars << \"link\" unless link {|l| l.have_required_values?}\n            end\n            vars\n          end\n\n          class Guid < GuidBase\n            def to_feed(*args)\n            end\n          end\n\n          class Enclosure < EnclosureBase\n            def to_feed(*args)\n            end\n          end\n\n          class Source < SourceBase\n            def to_feed(*args)\n            end\n\n            class Authors < AuthorsBase\n              def to_feed(*args)\n              end\n\n              class Author < AuthorBase\n              end\n            end\n\n            class Categories < CategoriesBase\n              def to_feed(*args)\n              end\n\n              class Category < CategoryBase\n              end\n            end\n\n            class Contributors < ContributorsBase\n              def to_feed(*args)\n              end\n\n              class Contributor < ContributorBase\n              end\n            end\n\n            class Generator < GeneratorBase\n              def to_feed(*args)\n              end\n            end\n\n            class Icon < IconBase\n              def to_feed(*args)\n              end\n            end\n\n            class Links < LinksBase\n              def to_feed(*args)\n              end\n\n              class Link < LinkBase\n              end\n            end\n\n            class Logo < LogoBase\n              def to_feed(*args)\n              end\n            end\n\n            class Rights < RightsBase\n              def to_feed(*args)\n              end\n            end\n\n            class Subtitle < SubtitleBase\n              def to_feed(*args)\n              end\n            end\n\n            class Title < TitleBase\n              def to_feed(*args)\n              end\n            end\n          end\n\n          class Categories < CategoriesBase\n            def to_feed(*args)\n            end\n\n            class Category < CategoryBase\n            end\n          end\n\n          class Authors < AuthorsBase\n            def to_feed(*args)\n            end\n\n            class Author < AuthorBase\n            end\n          end\n\n          class Links < LinksBase\n            def to_feed(rss, item)\n              return if @links.empty?\n              @links.first.to_feed(rss, item)\n            end\n\n            class Link < LinkBase\n              def to_feed(rss, item)\n                if have_required_values?\n                  item.link = href\n                else\n                  raise NotSetError.new(\"maker.link\",\n                                        not_set_required_variables)\n                end\n              end\n\n              private\n              def required_variable_names\n                %w(href)\n              end\n            end\n          end\n\n          class Contributors < ContributorsBase\n            def to_feed(rss, item)\n            end\n\n            class Contributor < ContributorBase\n            end\n          end\n\n          class Rights < RightsBase\n            def to_feed(rss, item)\n            end\n          end\n\n          class Description < DescriptionBase\n            def to_feed(rss, item)\n              item.description = content if have_required_values?\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n\n          class Content < ContentBase\n            def to_feed(rss, item)\n            end\n          end\n\n          class Title < TitleBase\n            def to_feed(rss, item)\n              item.title = content if have_required_values?\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n        end\n      end\n      \n      class Textinput < TextinputBase\n        def to_feed(rss)\n          textInput = Rss::Channel::TextInput.new\n          set = setup_values(textInput)\n          if set\n            rss.channel.textInput = textInput\n            set_parent(textInput, rss.channel)\n            setup_other_elements(rss, textInput)\n          end\n        end\n\n        private\n        def required_variable_names\n          %w(title description name link)\n        end\n      end\n    end\n    \n    add_maker(\"0.9\", \"0.92\", RSS09)\n    add_maker(\"0.91\", \"0.91\", RSS09)\n    add_maker(\"0.92\", \"0.92\", RSS09)\n    add_maker(\"rss0.91\", \"0.91\", RSS09)\n    add_maker(\"rss0.92\", \"0.92\", RSS09)\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/1.0.rb",
    "content": "require \"rss/1.0\"\n\nrequire \"rss/maker/base\"\n\nmodule RSS\n  module Maker\n\n    class RSS10 < RSSBase\n\n      def initialize(feed_version=\"1.0\")\n        super\n        @feed_type = \"rss\"\n      end\n\n      private\n      def make_feed\n        RDF.new(@version, @encoding, @standalone)\n      end\n\n      def setup_elements(rss)\n        setup_channel(rss)\n        setup_image(rss)\n        setup_items(rss)\n        setup_textinput(rss)\n      end\n\n      class Channel < ChannelBase\n\n        def to_feed(rss)\n          set_default_values do\n            _not_set_required_variables = not_set_required_variables\n            if _not_set_required_variables.empty?\n              channel = RDF::Channel.new(@about)\n              set = setup_values(channel)\n              channel.dc_dates.clear\n              rss.channel = channel\n              set_parent(channel, rss)\n              setup_items(rss)\n              setup_image(rss)\n              setup_textinput(rss)\n              setup_other_elements(rss, channel)\n            else\n              raise NotSetError.new(\"maker.channel\", _not_set_required_variables)\n            end\n          end\n        end\n\n        private\n        def setup_items(rss)\n          items = RDF::Channel::Items.new\n          seq = items.Seq\n          set_parent(items, seq)\n          target_items = @maker.items.normalize\n          raise NotSetError.new(\"maker\", [\"items\"]) if target_items.empty?\n          target_items.each do |item|\n            li = RDF::Channel::Items::Seq::Li.new(item.link)\n            seq.lis << li\n            set_parent(li, seq)\n          end\n          rss.channel.items = items\n          set_parent(rss.channel, items)\n        end\n        \n        def setup_image(rss)\n          if @maker.image.have_required_values?\n            image = RDF::Channel::Image.new(@maker.image.url)\n            rss.channel.image = image\n            set_parent(image, rss.channel)\n          end\n        end\n\n        def setup_textinput(rss)\n          if @maker.textinput.have_required_values?\n            textinput = RDF::Channel::Textinput.new(@maker.textinput.link)\n            rss.channel.textinput = textinput\n            set_parent(textinput, rss.channel)\n          end\n        end\n\n        def required_variable_names\n          %w(about link)\n        end\n\n        def not_set_required_variables\n          vars = super\n          vars << \"description\" unless description {|d| d.have_required_values?}\n          vars << \"title\" unless title {|t| t.have_required_values?}\n          vars\n        end\n\n        class SkipDays < SkipDaysBase\n          def to_feed(*args)\n          end\n          \n          class Day < DayBase\n          end\n        end\n        \n        class SkipHours < SkipHoursBase\n          def to_feed(*args)\n          end\n\n          class Hour < HourBase\n          end\n        end\n        \n        class Cloud < CloudBase\n          def to_feed(*args)\n          end\n        end\n\n        class Categories < CategoriesBase\n          def to_feed(*args)\n          end\n\n          class Category < CategoryBase\n          end\n        end\n\n        class Links < LinksBase\n          def to_feed(rss, channel)\n            return if @links.empty?\n            @links.first.to_feed(rss, channel)\n          end\n\n          class Link < LinkBase\n            def to_feed(rss, channel)\n              if have_required_values?\n                channel.link = href\n              else\n                raise NotSetError.new(\"maker.channel.link\",\n                                      not_set_required_variables)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(href)\n            end\n          end\n        end\n\n        class Authors < AuthorsBase\n          def to_feed(rss, channel)\n          end\n\n          class Author < AuthorBase\n            def to_feed(rss, channel)\n            end\n          end\n        end\n\n        class Contributors < ContributorsBase\n          def to_feed(rss, channel)\n          end\n\n          class Contributor < ContributorBase\n          end\n        end\n\n        class Generator < GeneratorBase\n          def to_feed(rss, channel)\n          end\n        end\n\n        class Copyright < CopyrightBase\n          def to_feed(rss, channel)\n          end\n        end\n\n        class Description < DescriptionBase\n          def to_feed(rss, channel)\n            channel.description = content if have_required_values?\n          end\n\n          private\n          def required_variable_names\n            %w(content)\n          end\n        end\n\n        class Title < TitleBase\n          def to_feed(rss, channel)\n            channel.title = content if have_required_values?\n          end\n\n          private\n          def required_variable_names\n            %w(content)\n          end\n        end\n      end\n\n      class Image < ImageBase\n        def to_feed(rss)\n          if @url\n            image = RDF::Image.new(@url)\n            set = setup_values(image)\n            if set\n              rss.image = image\n              set_parent(image, rss)\n              setup_other_elements(rss, image)\n            end\n          end\n        end\n\n        def have_required_values?\n          super and @maker.channel.have_required_values?\n        end\n\n        private\n        def variables\n          super + [\"link\"]\n        end\n\n        def required_variable_names\n          %w(url title link)\n        end\n      end\n\n      class Items < ItemsBase\n        def to_feed(rss)\n          if rss.channel\n            normalize.each do |item|\n              item.to_feed(rss)\n            end\n            setup_other_elements(rss, rss.items)\n          end\n        end\n\n        class Item < ItemBase\n          def to_feed(rss)\n            set_default_values do\n              item = RDF::Item.new(link)\n              set = setup_values(item)\n              if set\n                item.dc_dates.clear\n                rss.items << item\n                set_parent(item, rss)\n                setup_other_elements(rss, item)\n              elsif !have_required_values?\n                raise NotSetError.new(\"maker.item\", not_set_required_variables)\n              end\n            end\n          end\n\n          private\n          def required_variable_names\n            %w(link)\n          end\n\n          def variables\n            super + %w(link)\n          end\n\n          def not_set_required_variables\n            set_default_values do\n              vars = super\n              vars << \"title\" unless title {|t| t.have_required_values?}\n              vars\n            end\n          end\n\n          class Guid < GuidBase\n            def to_feed(*args)\n            end\n          end\n\n          class Enclosure < EnclosureBase\n            def to_feed(*args)\n            end\n          end\n\n          class Source < SourceBase\n            def to_feed(*args)\n            end\n\n            class Authors < AuthorsBase\n              def to_feed(*args)\n              end\n\n              class Author < AuthorBase\n              end\n            end\n\n            class Categories < CategoriesBase\n              def to_feed(*args)\n              end\n\n              class Category < CategoryBase\n              end\n            end\n\n            class Contributors < ContributorsBase\n              def to_feed(*args)\n              end\n\n              class Contributor < ContributorBase\n              end\n            end\n\n            class Generator < GeneratorBase\n              def to_feed(*args)\n              end\n            end\n\n            class Icon < IconBase\n              def to_feed(*args)\n              end\n            end\n\n            class Links < LinksBase\n              def to_feed(*args)\n              end\n\n              class Link < LinkBase\n              end\n            end\n\n            class Logo < LogoBase\n              def to_feed(*args)\n              end\n            end\n\n            class Rights < RightsBase\n              def to_feed(*args)\n              end\n            end\n\n            class Subtitle < SubtitleBase\n              def to_feed(*args)\n              end\n            end\n\n            class Title < TitleBase\n              def to_feed(*args)\n              end\n            end\n          end\n\n          class Categories < CategoriesBase\n            def to_feed(*args)\n            end\n\n            class Category < CategoryBase\n            end\n          end\n\n          class Authors < AuthorsBase\n            def to_feed(*args)\n            end\n\n            class Author < AuthorBase\n            end\n          end\n\n          class Links < LinksBase\n            def to_feed(*args)\n            end\n\n            class Link < LinkBase\n            end\n          end\n\n          class Contributors < ContributorsBase\n            def to_feed(rss, item)\n            end\n\n            class Contributor < ContributorBase\n            end\n          end\n\n          class Rights < RightsBase\n            def to_feed(rss, item)\n            end\n          end\n\n          class Description < DescriptionBase\n            def to_feed(rss, item)\n              item.description = content if have_required_values?\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n\n          class Content < ContentBase\n            def to_feed(rss, item)\n            end\n          end\n\n          class Title < TitleBase\n            def to_feed(rss, item)\n              item.title = content if have_required_values?\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n        end\n      end\n      \n      class Textinput < TextinputBase\n        def to_feed(rss)\n          if @link\n            textinput = RDF::Textinput.new(@link)\n            set = setup_values(textinput)\n            if set\n              rss.textinput = textinput\n              set_parent(textinput, rss)\n              setup_other_elements(rss, textinput)\n            end\n          end\n        end\n\n        def have_required_values?\n          super and @maker.channel.have_required_values?\n        end\n\n        private\n        def required_variable_names\n          %w(title description name link)\n        end\n      end\n    end\n\n    add_maker(\"1.0\", \"1.0\", RSS10)\n    add_maker(\"rss1.0\", \"1.0\", RSS10)\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/2.0.rb",
    "content": "require \"rss/2.0\"\n\nrequire \"rss/maker/0.9\"\n\nmodule RSS\n  module Maker\n    \n    class RSS20 < RSS09\n      \n      def initialize(feed_version=\"2.0\")\n        super\n      end\n\n      class Channel < RSS09::Channel\n\n        private\n        def required_variable_names\n          %w(link)\n        end\n        \n        class SkipDays < RSS09::Channel::SkipDays\n          class Day < RSS09::Channel::SkipDays::Day\n          end\n        end\n        \n        class SkipHours < RSS09::Channel::SkipHours\n          class Hour < RSS09::Channel::SkipHours::Hour\n          end\n        end\n        \n        class Cloud < RSS09::Channel::Cloud\n          def to_feed(rss, channel)\n            cloud = Rss::Channel::Cloud.new\n            set = setup_values(cloud)\n            if set\n              channel.cloud = cloud\n              set_parent(cloud, channel)\n              setup_other_elements(rss, cloud)\n            end\n          end\n\n          private\n          def required_variable_names\n            %w(domain port path registerProcedure protocol)\n          end\n        end\n\n        class Categories < RSS09::Channel::Categories\n          def to_feed(rss, channel)\n            @categories.each do |category|\n              category.to_feed(rss, channel)\n            end\n          end\n          \n          class Category < RSS09::Channel::Categories::Category\n            def to_feed(rss, channel)\n              category = Rss::Channel::Category.new\n              set = setup_values(category)\n              if set\n                channel.categories << category\n                set_parent(category, channel)\n                setup_other_elements(rss, category)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n        end\n\n        class Generator < GeneratorBase\n          def to_feed(rss, channel)\n            channel.generator = content\n          end\n\n          private\n          def required_variable_names\n            %w(content)\n          end\n        end\n      end\n      \n      class Image < RSS09::Image\n        private\n        def required_element?\n          false\n        end\n      end\n      \n      class Items < RSS09::Items\n        class Item < RSS09::Items::Item\n          private\n          def required_variable_names\n            []\n          end\n\n          def not_set_required_variables\n            vars = super\n            if !title {|t| t.have_required_values?} and\n                !description {|d| d.have_required_values?}\n              vars << \"title or description\"\n            end\n            vars\n          end\n\n          def variables\n            super + [\"pubDate\"]\n          end\n\n          class Guid < RSS09::Items::Item::Guid\n            def to_feed(rss, item)\n              guid = Rss::Channel::Item::Guid.new\n              set = setup_values(guid)\n              if set\n                item.guid = guid\n                set_parent(guid, item)\n                setup_other_elements(rss, guid)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(content)\n            end\n          end\n\n          class Enclosure < RSS09::Items::Item::Enclosure\n            def to_feed(rss, item)\n              enclosure = Rss::Channel::Item::Enclosure.new\n              set = setup_values(enclosure)\n              if set\n                item.enclosure = enclosure\n                set_parent(enclosure, item)\n                setup_other_elements(rss, enclosure)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(url length type)\n            end\n          end\n\n          class Source < RSS09::Items::Item::Source\n            def to_feed(rss, item)\n              source = Rss::Channel::Item::Source.new\n              set = setup_values(source)\n              if set\n                item.source = source\n                set_parent(source, item)\n                setup_other_elements(rss, source)\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(url content)\n            end\n\n            class Links < RSS09::Items::Item::Source::Links\n              def to_feed(rss, source)\n                return if @links.empty?\n                @links.first.to_feed(rss, source)\n              end\n\n              class Link < RSS09::Items::Item::Source::Links::Link\n                def to_feed(rss, source)\n                  source.url = href\n                end\n              end\n            end\n          end\n\n          class Categories < RSS09::Items::Item::Categories\n            def to_feed(rss, item)\n              @categories.each do |category|\n                category.to_feed(rss, item)\n              end\n            end\n          \n            class Category < RSS09::Items::Item::Categories::Category\n              def to_feed(rss, item)\n                category = Rss::Channel::Item::Category.new\n                set = setup_values(category)\n                if set\n                  item.categories << category\n                  set_parent(category, item)\n                  setup_other_elements(rss)\n                end\n              end\n\n              private\n              def required_variable_names\n                %w(content)\n              end\n            end\n          end\n\n          class Authors < RSS09::Items::Item::Authors\n            def to_feed(rss, item)\n              return if @authors.empty?\n              @authors.first.to_feed(rss, item)\n            end\n\n            class Author < RSS09::Items::Item::Authors::Author\n              def to_feed(rss, item)\n                item.author = name\n              end\n            end\n          end\n        end\n      end\n      \n      class Textinput < RSS09::Textinput\n      end\n    end\n    \n    add_maker(\"2.0\", \"2.0\", RSS20)\n    add_maker(\"rss2.0\", \"2.0\", RSS20)\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/atom.rb",
    "content": "require \"rss/atom\"\n\nrequire \"rss/maker/base\"\n\nmodule RSS\n  module Maker\n    module AtomPersons\n      module_function\n      def def_atom_persons(klass, name, maker_name, plural=nil)\n        plural ||= \"#{name}s\"\n        klass_name = Utils.to_class_name(name)\n        plural_klass_name = Utils.to_class_name(plural)\n\n        klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          class #{plural_klass_name} < #{plural_klass_name}Base\n            class #{klass_name} < #{klass_name}Base\n              def to_feed(feed, current)\n                #{name} = feed.class::#{klass_name}.new\n                set = setup_values(#{name})\n                unless set\n                  raise NotSetError.new(#{maker_name.dump},\n                                        not_set_required_variables)\n                end\n                current.#{plural} << #{name}\n                set_parent(#{name}, current)\n                setup_other_elements(#{name})\n              end\n\n              private\n              def required_variable_names\n                %w(name)\n              end\n            end\n          end\nEOC\n      end\n    end\n\n    module AtomTextConstruct\n      class << self\n        def def_atom_text_construct(klass, name, maker_name, klass_name=nil,\n                                    atom_klass_name=nil)\n          klass_name ||= Utils.to_class_name(name)\n          atom_klass_name ||= Utils.to_class_name(name)\n\n          klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            class #{klass_name} < #{klass_name}Base\n              include #{self.name}\n              def to_feed(feed, current)\n                #{name} = current.class::#{atom_klass_name}.new\n                if setup_values(#{name})\n                  current.#{name} = #{name}\n                  set_parent(#{name}, current)\n                  setup_other_elements(feed)\n                elsif variable_is_set?\n                  raise NotSetError.new(#{maker_name.dump},\n                                        not_set_required_variables)\n                end\n              end\n            end\n          EOC\n        end\n      end\n\n      private\n      def required_variable_names\n        if type == \"xhtml\"\n          %w(xml_content)\n        else\n          %w(content)\n        end\n      end\n\n      def variables\n        if type == \"xhtml\"\n          super + %w(xhtml)\n        else\n          super\n        end\n      end\n    end\n\n    module AtomCategory\n      def to_feed(feed, current)\n        category = feed.class::Category.new\n        set = setup_values(category)\n        if set\n          current.categories << category\n          set_parent(category, current)\n          setup_other_elements(feed)\n        else\n          raise NotSetError.new(self.class.not_set_name,\n                                not_set_required_variables)\n        end\n      end\n\n      private\n      def required_variable_names\n        %w(term)\n      end\n\n      def variables\n        super + [\"term\", \"scheme\"]\n      end\n    end\n\n    module AtomLink\n      def to_feed(feed, current)\n        link = feed.class::Link.new\n        set = setup_values(link)\n        if set\n          current.links << link\n          set_parent(link, current)\n          setup_other_elements(feed)\n        else\n          raise NotSetError.new(self.class.not_set_name,\n                                not_set_required_variables)\n        end\n      end\n\n      private\n      def required_variable_names\n        %w(href)\n      end\n    end\n\n    module AtomGenerator\n      def to_feed(feed, current)\n        generator = current.class::Generator.new\n        if setup_values(generator)\n          current.generator = generator\n          set_parent(generator, current)\n          setup_other_elements(feed)\n        elsif variable_is_set?\n          raise NotSetError.new(self.class.not_set_name,\n                                not_set_required_variables)\n        end\n      end\n\n      private\n      def required_variable_names\n        %w(content)\n      end\n    end\n\n    module AtomLogo\n      def to_feed(feed, current)\n        logo = current.class::Logo.new\n        class << logo\n          alias_method(:uri=, :content=)\n        end\n        set = setup_values(logo)\n        class << logo\n          remove_method(:uri=)\n        end\n        if set\n          current.logo = logo\n          set_parent(logo, current)\n          setup_other_elements(feed)\n        elsif variable_is_set?\n          raise NotSetError.new(self.class.not_set_name,\n                                not_set_required_variables)\n        end\n      end\n\n      private\n      def required_variable_names\n        %w(uri)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/base.rb",
    "content": "require 'forwardable'\n\nrequire 'rss/rss'\n\nmodule RSS\n  module Maker\n    class Base\n      extend Utils::InheritedReader\n\n      OTHER_ELEMENTS = []\n      NEED_INITIALIZE_VARIABLES = []\n\n      class << self\n        def other_elements\n          inherited_array_reader(\"OTHER_ELEMENTS\")\n        end\n        def need_initialize_variables\n          inherited_array_reader(\"NEED_INITIALIZE_VARIABLES\")\n        end\n\n        def inherited_base\n          ::RSS::Maker::Base\n        end\n\n        def inherited(subclass)\n          subclass.const_set(\"OTHER_ELEMENTS\", [])\n          subclass.const_set(\"NEED_INITIALIZE_VARIABLES\", [])\n        end\n\n        def add_other_element(variable_name)\n          self::OTHER_ELEMENTS << variable_name\n        end\n\n        def add_need_initialize_variable(variable_name, init_value=\"nil\")\n          self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value]\n        end\n\n        def def_array_element(name, plural=nil, klass_name=nil)\n          include Enumerable\n          extend Forwardable\n\n          plural ||= \"#{name}s\"\n          klass_name ||= Utils.to_class_name(name)\n          def_delegators(\"@#{plural}\", :<<, :[], :[]=, :first, :last)\n          def_delegators(\"@#{plural}\", :push, :pop, :shift, :unshift)\n          def_delegators(\"@#{plural}\", :each, :size, :empty?, :clear)\n\n          add_need_initialize_variable(plural, \"[]\")\n\n          module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            def new_#{name}\n              #{name} = self.class::#{klass_name}.new(@maker)\n              @#{plural} << #{name}\n              if block_given?\n                yield #{name}\n              else\n                #{name}\n              end\n            end\n            alias new_child new_#{name}\n\n            def to_feed(*args)\n              @#{plural}.each do |#{name}|\n                #{name}.to_feed(*args)\n              end\n            end\n\n            def replace(elements)\n              @#{plural}.replace(elements.to_a)\n            end\n          EOC\n        end\n\n        def def_classed_element_without_accessor(name, class_name=nil)\n          class_name ||= Utils.to_class_name(name)\n          add_other_element(name)\n          add_need_initialize_variable(name, \"make_#{name}\")\n          module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            private\n            def setup_#{name}(feed, current)\n              @#{name}.to_feed(feed, current)\n            end\n\n            def make_#{name}\n              self.class::#{class_name}.new(@maker)\n            end\n          EOC\n        end\n\n        def def_classed_element(name, class_name=nil, attribute_name=nil)\n          def_classed_element_without_accessor(name, class_name)\n          if attribute_name\n            module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n              def #{name}\n                if block_given?\n                  yield(@#{name})\n                else\n                  @#{name}.#{attribute_name}\n                end\n              end\n\n              def #{name}=(new_value)\n                @#{name}.#{attribute_name} = new_value\n              end\n            EOC\n          else\n            attr_reader name\n          end\n        end\n\n        def def_classed_elements(name, attribute, plural_class_name=nil,\n                                 plural_name=nil, new_name=nil)\n          plural_name ||= \"#{name}s\"\n          new_name ||= name\n          def_classed_element(plural_name, plural_class_name)\n          local_variable_name = \"_#{name}\"\n          new_value_variable_name = \"new_value\"\n          additional_setup_code = nil\n          if block_given?\n            additional_setup_code = yield(local_variable_name,\n                                          new_value_variable_name)\n          end\n          module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            def #{name}\n              #{local_variable_name} = #{plural_name}.first\n              #{local_variable_name} ? #{local_variable_name}.#{attribute} : nil\n            end\n\n            def #{name}=(#{new_value_variable_name})\n              #{local_variable_name} =\n                #{plural_name}.first || #{plural_name}.new_#{new_name}\n              #{additional_setup_code}\n              #{local_variable_name}.#{attribute} = #{new_value_variable_name}\n            end\n          EOC\n        end\n\n        def def_other_element(name)\n          attr_accessor name\n          def_other_element_without_accessor(name)\n        end\n\n        def def_other_element_without_accessor(name)\n          add_need_initialize_variable(name)\n          add_other_element(name)\n          module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            def setup_#{name}(feed, current)\n              if !@#{name}.nil? and current.respond_to?(:#{name}=)\n                current.#{name} = @#{name}\n              end\n            end\n          EOC\n        end\n\n        def def_csv_element(name, type=nil)\n          def_other_element_without_accessor(name)\n          attr_reader(name)\n          converter = \"\"\n          if type == :integer\n            converter = \"{|v| Integer(v)}\"\n          end\n          module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            def #{name}=(value)\n              @#{name} = Utils::CSV.parse(value)#{converter}\n            end\n          EOC\n        end\n      end\n\n      attr_reader :maker\n      def initialize(maker)\n        @maker = maker\n        @default_values_are_set = false\n        initialize_variables\n      end\n\n      def have_required_values?\n        not_set_required_variables.empty?\n      end\n\n      def variable_is_set?\n        variables.any? {|var| not __send__(var).nil?}\n      end\n\n      private\n      def initialize_variables\n        self.class.need_initialize_variables.each do |variable_name, init_value|\n          instance_eval(\"@#{variable_name} = #{init_value}\", __FILE__, __LINE__)\n        end\n      end\n\n      def setup_other_elements(feed, current=nil)\n        current ||= current_element(feed)\n        self.class.other_elements.each do |element|\n          __send__(\"setup_#{element}\", feed, current)\n        end\n      end\n\n      def current_element(feed)\n        feed\n      end\n\n      def set_default_values(&block)\n        return yield if @default_values_are_set\n\n        begin\n          @default_values_are_set = true\n          _set_default_values(&block)\n        ensure\n          @default_values_are_set = false\n        end\n      end\n\n      def _set_default_values(&block)\n        yield\n      end\n\n      def setup_values(target)\n        set = false\n        if have_required_values?\n          variables.each do |var|\n            setter = \"#{var}=\"\n            if target.respond_to?(setter)\n              value = __send__(var)\n              if value\n                target.__send__(setter, value)\n                set = true\n              end\n            end\n          end\n        end\n        set\n      end\n\n      def set_parent(target, parent)\n        target.parent = parent if target.class.need_parent?\n      end\n\n      def variables\n        self.class.need_initialize_variables.find_all do |name, init|\n          \"nil\" == init\n        end.collect do |name, init|\n          name\n        end\n      end\n\n      def not_set_required_variables\n        required_variable_names.find_all do |var|\n          __send__(var).nil?\n        end\n      end\n\n      def required_variables_are_set?\n        required_variable_names.each do |var|\n          return false if __send__(var).nil?\n        end\n        true\n      end\n    end\n\n    module AtomPersonConstructBase\n      def self.append_features(klass)\n        super\n\n        klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          %w(name uri email).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n        EOC\n      end\n    end\n\n    module AtomTextConstructBase\n      module EnsureXMLContent\n        class << self\n          def included(base)\n            super\n            base.class_eval do\n              %w(type content xml_content).each do |element|\n                attr_reader element\n                attr_writer element if element != \"xml_content\"\n                add_need_initialize_variable(element)\n              end\n\n              alias_method(:xhtml, :xml_content)\n            end\n          end\n        end\n\n        def ensure_xml_content(content)\n          xhtml_uri = ::RSS::Atom::XHTML_URI\n          unless content.is_a?(RSS::XML::Element) and\n              [\"div\", xhtml_uri] == [content.name, content.uri]\n            children = content\n            children = [children] unless content.is_a?(Array)\n            children = set_xhtml_uri_as_default_uri(children)\n            content = RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                            {\"xmlns\" => xhtml_uri},\n                                            children)\n          end\n          content\n        end\n\n        def xml_content=(content)\n          @xml_content = ensure_xml_content(content)\n        end\n\n        def xhtml=(content)\n          self.xml_content = content\n        end\n\n        private\n        def set_xhtml_uri_as_default_uri(children)\n          children.collect do |child|\n            if child.is_a?(RSS::XML::Element) and\n                child.prefix.nil? and child.uri.nil?\n              RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,\n                                    child.attributes.dup,\n                                    set_xhtml_uri_as_default_uri(child.children))\n            else\n              child\n            end\n          end\n        end\n      end\n\n      def self.append_features(klass)\n        super\n\n        klass.class_eval do\n          include EnsureXMLContent\n        end\n      end\n    end\n\n    module SetupDefaultDate\n      private\n      def _set_default_values(&block)\n        keep = {\n          :date => date,\n          :dc_dates => dc_dates.to_a.dup,\n        }\n        _date = date\n        if _date and !dc_dates.any? {|dc_date| dc_date.value == _date}\n          dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self)\n          dc_date.value = _date.dup\n          dc_dates.unshift(dc_date)\n        end\n        self.date ||= self.dc_date\n        super(&block)\n      ensure\n        date = keep[:date]\n        dc_dates.replace(keep[:dc_dates])\n      end\n    end\n\n    class RSSBase < Base\n      class << self\n        def make(version, &block)\n          new(version).make(&block)\n        end\n      end\n\n      %w(xml_stylesheets channel image items textinput).each do |element|\n        attr_reader element\n        add_need_initialize_variable(element, \"make_#{element}\")\n        module_eval(<<-EOC, __FILE__, __LINE__)\n          private\n          def setup_#{element}(feed)\n            @#{element}.to_feed(feed)\n          end\n\n          def make_#{element}\n            self.class::#{Utils.to_class_name(element)}.new(self)\n          end\n        EOC\n      end\n      \n      attr_reader :feed_version\n      alias_method(:rss_version, :feed_version)\n      attr_accessor :version, :encoding, :standalone\n\n      def initialize(feed_version)\n        super(self)\n        @feed_type = nil\n        @feed_subtype = nil\n        @feed_version = feed_version\n        @version = \"1.0\"\n        @encoding = \"UTF-8\"\n        @standalone = nil\n      end\n      \n      def make\n        if block_given?\n          yield(self)\n          to_feed\n        else\n          nil\n        end\n      end\n\n      def to_feed\n        feed = make_feed\n        setup_xml_stylesheets(feed)\n        setup_elements(feed)\n        setup_other_elements(feed)\n        if feed.valid?\n          feed\n        else\n          nil\n        end\n      end\n      \n      private\n      remove_method :make_xml_stylesheets\n      def make_xml_stylesheets\n        XMLStyleSheets.new(self)\n      end\n    end\n\n    class XMLStyleSheets < Base\n      def_array_element(\"xml_stylesheet\", nil, \"XMLStyleSheet\")\n\n      class XMLStyleSheet < Base\n\n        ::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute|\n          attr_accessor attribute\n          add_need_initialize_variable(attribute)\n        end\n        \n        def to_feed(feed)\n          xss = ::RSS::XMLStyleSheet.new\n          guess_type_if_need(xss)\n          set = setup_values(xss)\n          if set\n            feed.xml_stylesheets << xss\n          end\n        end\n\n        private\n        def guess_type_if_need(xss)\n          if @type.nil?\n            xss.href = @href\n            @type = xss.type\n          end\n        end\n\n        def required_variable_names\n          %w(href type)\n        end\n      end\n    end\n    \n    class ChannelBase < Base\n      include SetupDefaultDate\n\n      %w(cloud categories skipDays skipHours).each do |name|\n        def_classed_element(name)\n      end\n\n      %w(generator copyright description title).each do |name|\n        def_classed_element(name, nil, \"content\")\n      end\n\n      [\n       [\"link\", \"href\", Proc.new {|target,| \"#{target}.href = 'self'\"}],\n       [\"author\", \"name\"],\n       [\"contributor\", \"name\"],\n      ].each do |name, attribute, additional_setup_maker|\n        def_classed_elements(name, attribute, &additional_setup_maker)\n      end\n\n      %w(id about language\n         managingEditor webMaster rating docs date\n         lastBuildDate ttl).each do |element|\n        attr_accessor element\n        add_need_initialize_variable(element)\n      end\n\n      def pubDate\n        date\n      end\n\n      def pubDate=(date)\n        self.date = date\n      end\n\n      def updated\n        date\n      end\n\n      def updated=(date)\n        self.date = date\n      end\n\n      alias_method(:rights, :copyright)\n      alias_method(:rights=, :copyright=)\n\n      alias_method(:subtitle, :description)\n      alias_method(:subtitle=, :description=)\n\n      def icon\n        image_favicon.about\n      end\n\n      def icon=(url)\n        image_favicon.about = url\n      end\n\n      def logo\n        maker.image.url\n      end\n\n      def logo=(url)\n        maker.image.url = url\n      end\n\n      class SkipDaysBase < Base\n        def_array_element(\"day\")\n\n        class DayBase < Base\n          %w(content).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n        end\n      end\n      \n      class SkipHoursBase < Base\n        def_array_element(\"hour\")\n\n        class HourBase < Base\n          %w(content).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n        end\n      end\n      \n      class CloudBase < Base\n        %w(domain port path registerProcedure protocol).each do |element|\n          attr_accessor element\n          add_need_initialize_variable(element)\n        end\n      end\n\n      class CategoriesBase < Base\n        def_array_element(\"category\", \"categories\")\n\n        class CategoryBase < Base\n          %w(domain content label).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n\n          alias_method(:term, :domain)\n          alias_method(:term=, :domain=)\n          alias_method(:scheme, :content)\n          alias_method(:scheme=, :content=)\n        end\n      end\n\n      class LinksBase < Base\n        def_array_element(\"link\")\n\n        class LinkBase < Base\n          %w(href rel type hreflang title length).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n        end\n      end\n\n      class AuthorsBase < Base\n        def_array_element(\"author\")\n\n        class AuthorBase < Base\n          include AtomPersonConstructBase\n        end\n      end\n\n      class ContributorsBase < Base\n        def_array_element(\"contributor\")\n\n        class ContributorBase < Base\n          include AtomPersonConstructBase\n        end\n      end\n\n      class GeneratorBase < Base\n        %w(uri version content).each do |element|\n          attr_accessor element\n          add_need_initialize_variable(element)\n        end\n      end\n\n      class CopyrightBase < Base\n        include AtomTextConstructBase\n      end\n\n      class DescriptionBase < Base\n        include AtomTextConstructBase\n      end\n\n      class TitleBase < Base\n        include AtomTextConstructBase\n      end\n    end\n    \n    class ImageBase < Base\n      %w(title url width height description).each do |element|\n        attr_accessor element\n        add_need_initialize_variable(element)\n      end\n\n      def link\n        @maker.channel.link\n      end\n    end\n    \n    class ItemsBase < Base\n      def_array_element(\"item\")\n\n      attr_accessor :do_sort, :max_size\n      \n      def initialize(maker)\n        super\n        @do_sort = false\n        @max_size = -1\n      end\n      \n      def normalize\n        if @max_size >= 0\n          sort_if_need[0...@max_size]\n        else\n          sort_if_need[0..@max_size]\n        end\n      end\n\n      private\n      def sort_if_need\n        if @do_sort.respond_to?(:call)\n          @items.sort do |x, y|\n            @do_sort.call(x, y)\n          end\n        elsif @do_sort\n          @items.sort do |x, y|\n            y <=> x\n          end\n        else\n          @items\n        end\n      end\n\n      class ItemBase < Base\n        include SetupDefaultDate\n\n        %w(guid enclosure source categories content).each do |name|\n          def_classed_element(name)\n        end\n\n        %w(rights description title).each do |name|\n          def_classed_element(name, nil, \"content\")\n        end\n\n        [\n         [\"author\", \"name\"],\n         [\"link\", \"href\", Proc.new {|target,| \"#{target}.href = 'alternate'\"}],\n         [\"contributor\", \"name\"],\n        ].each do |name, attribute|\n          def_classed_elements(name, attribute)\n\tend\n\n        %w(date comments id published).each do |element|\n          attr_accessor element\n          add_need_initialize_variable(element)\n        end\n\n        def pubDate\n          date\n        end\n\n        def pubDate=(date)\n          self.date = date\n        end\n\n        def updated\n          date\n        end\n\n        def updated=(date)\n          self.date = date\n        end\n\n        alias_method(:summary, :description)\n        alias_method(:summary=, :description=)\n\n        def <=>(other)\n          _date = date || dc_date\n          _other_date = other.date || other.dc_date\n          if _date and _other_date\n            _date <=> _other_date\n          elsif _date\n            1\n          elsif _other_date\n            -1\n          else\n            0\n          end\n        end\n\n        class GuidBase < Base\n          %w(isPermaLink content).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n        end\n\n        class EnclosureBase < Base\n          %w(url length type).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n        end\n\n        class SourceBase < Base\n          %w(authors categories contributors generator icon\n             logo rights subtitle title).each do |name|\n            def_classed_element(name)\n          end\n\n          [\n           [\"link\", \"href\"],\n          ].each do |name, attribute|\n            def_classed_elements(name, attribute)\n          end\n\n          %w(id content date).each do |element|\n            attr_accessor element\n            add_need_initialize_variable(element)\n          end\n\n          alias_method(:url, :link)\n          alias_method(:url=, :link=)\n\n          def updated\n            date\n          end\n\n          def updated=(date)\n            self.date = date\n          end\n\n          private\n          AuthorsBase = ChannelBase::AuthorsBase\n          CategoriesBase = ChannelBase::CategoriesBase\n          ContributorsBase = ChannelBase::ContributorsBase\n          GeneratorBase = ChannelBase::GeneratorBase\n\n          class IconBase < Base\n            %w(url).each do |element|\n              attr_accessor element\n              add_need_initialize_variable(element)\n            end\n          end\n\n          LinksBase = ChannelBase::LinksBase\n\n          class LogoBase < Base\n            %w(uri).each do |element|\n              attr_accessor element\n              add_need_initialize_variable(element)\n            end\n          end\n\n          class RightsBase < Base\n            include AtomTextConstructBase\n          end\n\n          class SubtitleBase < Base\n            include AtomTextConstructBase\n          end\n\n          class TitleBase < Base\n            include AtomTextConstructBase\n          end\n        end\n\n        CategoriesBase = ChannelBase::CategoriesBase\n        AuthorsBase = ChannelBase::AuthorsBase\n        LinksBase = ChannelBase::LinksBase\n        ContributorsBase = ChannelBase::ContributorsBase\n\n        class RightsBase < Base\n          include AtomTextConstructBase\n        end\n\n        class DescriptionBase < Base\n          include AtomTextConstructBase\n        end\n\n        class ContentBase < Base\n          include AtomTextConstructBase::EnsureXMLContent\n\n          %w(src).each do |element|\n            attr_accessor(element)\n            add_need_initialize_variable(element)\n          end\n\n          def xml_content=(content)\n            content = ensure_xml_content(content) if inline_xhtml?\n            @xml_content = content\n          end\n\n          alias_method(:xml, :xml_content)\n          alias_method(:xml=, :xml_content=)\n\n          def inline_text?\n            [nil, \"text\", \"html\"].include?(@type)\n          end\n\n          def inline_html?\n            @type == \"html\"\n          end\n\n          def inline_xhtml?\n            @type == \"xhtml\"\n          end\n\n          def inline_other?\n            !out_of_line? and ![nil, \"text\", \"html\", \"xhtml\"].include?(@type)\n          end\n\n          def inline_other_text?\n            return false if @type.nil? or out_of_line?\n            /\\Atext\\//i.match(@type) ? true : false\n          end\n\n          def inline_other_xml?\n            return false if @type.nil? or out_of_line?\n            /[\\+\\/]xml\\z/i.match(@type) ? true : false\n          end\n\n          def inline_other_base64?\n            return false if @type.nil? or out_of_line?\n            @type.include?(\"/\") and !inline_other_text? and !inline_other_xml?\n          end\n\n          def out_of_line?\n            not @src.nil? and @content.nil?\n          end\n        end\n\n        class TitleBase < Base\n          include AtomTextConstructBase\n        end\n      end\n    end\n\n    class TextinputBase < Base\n      %w(title description name link).each do |element|\n        attr_accessor element\n        add_need_initialize_variable(element)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/content.rb",
    "content": "require 'rss/content'\nrequire 'rss/maker/1.0'\nrequire 'rss/maker/2.0'\n\nmodule RSS\n  module Maker\n    module ContentModel\n      def self.append_features(klass)\n        super\n\n        ::RSS::ContentModel::ELEMENTS.each do |name|\n          klass.def_other_element(name)\n        end\n      end\n    end\n\n    class ItemsBase\n      class ItemBase; include ContentModel; end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/dublincore.rb",
    "content": "require 'rss/dublincore'\nrequire 'rss/maker/1.0'\n\nmodule RSS\n  module Maker\n    module DublinCoreModel\n      def self.append_features(klass)\n        super\n\n        ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|\n          plural_name ||= \"#{name}s\"\n          full_name = \"#{RSS::DC_PREFIX}_#{name}\"\n          full_plural_name = \"#{RSS::DC_PREFIX}_#{plural_name}\"\n          klass_name = Utils.to_class_name(name)\n          plural_klass_name = \"DublinCore#{Utils.to_class_name(plural_name)}\"\n          full_plural_klass_name = \"self.class::#{plural_klass_name}\"\n          full_klass_name = \"#{full_plural_klass_name}::#{klass_name}\"\n          klass.def_classed_elements(full_name, \"value\", plural_klass_name,\n                                     full_plural_name, name)\n          klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n            def new_#{full_name}(value=nil)\n              _#{full_name} = #{full_plural_name}.new_#{name}\n              _#{full_name}.value = value\n              if block_given?\n                yield _#{full_name}\n              else\n                _#{full_name}\n              end\n            end\n          EOC\n        end\n\n        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          # For backward compatibility\n          alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list\n        EOC\n      end\n\n      ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|\n        plural_name ||= \"#{name}s\"\n        full_name ||= \"#{DC_PREFIX}_#{name}\"\n        full_plural_name ||= \"#{DC_PREFIX}_#{plural_name}\"\n        klass_name = Utils.to_class_name(name)\n        full_klass_name = \"DublinCore#{klass_name}\"\n        plural_klass_name = \"DublinCore#{Utils.to_class_name(plural_name)}\"\n        module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        class #{plural_klass_name}Base < Base\n          def_array_element(#{name.dump}, #{full_plural_name.dump},\n                            #{full_klass_name.dump})\n\n          class #{full_klass_name}Base < Base\n            attr_accessor :value\n            add_need_initialize_variable(\"value\")\n            alias_method(:content, :value)\n            alias_method(:content=, :value=)\n\n            def have_required_values?\n              @value\n            end\n\n            def to_feed(feed, current)\n              if value and current.respond_to?(:#{full_name})\n                new_item = current.class::#{full_klass_name}.new(value)\n                current.#{full_plural_name} << new_item\n              end\n            end\n          end\n          #{klass_name}Base = #{full_klass_name}Base\n        end\n        EOC\n      end\n\n      def self.install_dublin_core(klass)\n        ::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|\n          plural_name ||= \"#{name}s\"\n          klass_name = Utils.to_class_name(name)\n          full_klass_name = \"DublinCore#{klass_name}\"\n          plural_klass_name = \"DublinCore#{Utils.to_class_name(plural_name)}\"\n          klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          class #{plural_klass_name} < #{plural_klass_name}Base\n            class #{full_klass_name} < #{full_klass_name}Base\n            end\n            #{klass_name} = #{full_klass_name}\n          end\nEOC\n        end\n      end\n    end\n\n    class ChannelBase\n      include DublinCoreModel\n    end\n    \n    class ImageBase; include DublinCoreModel; end\n    class ItemsBase\n      class ItemBase\n        include DublinCoreModel\n      end\n    end\n    class TextinputBase; include DublinCoreModel; end\n\n    makers.each do |maker|\n      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        class Channel\n          DublinCoreModel.install_dublin_core(self)\n        end\n\n        class Image\n          DublinCoreModel.install_dublin_core(self)\n        end\n\n        class Items\n          class Item\n            DublinCoreModel.install_dublin_core(self)\n          end\n        end\n\n        class Textinput\n          DublinCoreModel.install_dublin_core(self)\n        end\n      EOC\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/entry.rb",
    "content": "require \"rss/maker/atom\"\nrequire \"rss/maker/feed\"\n\nmodule RSS\n  module Maker\n    module Atom\n      class Entry < RSSBase\n        def initialize(feed_version=\"1.0\")\n          super\n          @feed_type = \"atom\"\n          @feed_subtype = \"entry\"\n        end\n\n        private\n        def make_feed\n          ::RSS::Atom::Entry.new(@version, @encoding, @standalone)\n        end\n\n        def setup_elements(entry)\n          setup_items(entry)\n        end\n\n        class Channel < ChannelBase\n          class SkipDays < SkipDaysBase\n            class Day < DayBase\n            end\n          end\n\n          class SkipHours < SkipHoursBase\n            class Hour < HourBase\n            end\n          end\n\n          class Cloud < CloudBase\n          end\n\n          Categories = Feed::Channel::Categories\n          Links = Feed::Channel::Links\n          Authors = Feed::Channel::Authors\n          Contributors = Feed::Channel::Contributors\n\n          class Generator < GeneratorBase\n            include AtomGenerator\n\n            def self.not_set_name\n              \"maker.channel.generator\"\n            end\n          end\n\n          Copyright = Feed::Channel::Copyright\n\n          class Description < DescriptionBase\n          end\n\n          Title = Feed::Channel::Title\n        end\n\n        class Image < ImageBase\n        end\n\n        class Items < ItemsBase\n          def to_feed(entry)\n            (normalize.first || Item.new(@maker)).to_feed(entry)\n          end\n\n          class Item < ItemBase\n            def to_feed(entry)\n              set_default_values do\n                setup_values(entry)\n                entry.dc_dates.clear\n                setup_other_elements(entry)\n                unless have_required_values?\n                  raise NotSetError.new(\"maker.item\", not_set_required_variables)\n                end\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(id updated)\n            end\n\n            def variables\n              super + [\"updated\"]\n            end\n\n            def variable_is_set?\n              super or !authors.empty?\n            end\n\n            def not_set_required_variables\n              set_default_values do\n                vars = super\n                if authors.all? {|author| !author.have_required_values?}\n                  vars << \"author\"\n                end\n                vars << \"title\" unless title {|t| t.have_required_values?}\n                vars\n              end\n            end\n\n            def _set_default_values(&block)\n              keep = {\n                :authors => authors.to_a.dup,\n                :contributors => contributors.to_a.dup,\n                :categories => categories.to_a.dup,\n                :id => id,\n                :links => links.to_a.dup,\n                :rights => @rights,\n                :title => @title,\n                :updated => updated,\n              }\n              authors.replace(@maker.channel.authors) if keep[:authors].empty?\n              if keep[:contributors].empty?\n                contributors.replace(@maker.channel.contributors)\n              end\n              if keep[:categories].empty?\n                categories.replace(@maker.channel.categories)\n              end\n              self.id ||= link || @maker.channel.id\n              links.replace(@maker.channel.links) if keep[:links].empty?\n              unless keep[:rights].variable_is_set?\n                @maker.channel.rights {|r| @rights = r}\n              end\n              unless keep[:title].variable_is_set?\n                @maker.channel.title {|t| @title = t}\n              end\n              self.updated ||= @maker.channel.updated\n              super(&block)\n            ensure\n              authors.replace(keep[:authors])\n              contributors.replace(keep[:contributors])\n              categories.replace(keep[:categories])\n              links.replace(keep[:links])\n              self.id = keep[:id]\n              @rights = keep[:rights]\n              @title = keep[:title]\n              self.updated = keep[:prev_updated]\n            end\n\n            Guid = Feed::Items::Item::Guid\n            Enclosure = Feed::Items::Item::Enclosure\n            Source = Feed::Items::Item::Source\n            Categories = Feed::Items::Item::Categories\n            Authors = Feed::Items::Item::Authors\n            Contributors = Feed::Items::Item::Contributors\n            Links = Feed::Items::Item::Links\n            Rights = Feed::Items::Item::Rights\n            Description = Feed::Items::Item::Description\n            Title = Feed::Items::Item::Title\n            Content = Feed::Items::Item::Content\n          end\n        end\n\n        class Textinput < TextinputBase\n        end\n      end\n    end\n\n    add_maker(\"atom:entry\", \"1.0\", Atom::Entry)\n    add_maker(\"atom1.0:entry\", \"1.0\", Atom::Entry)\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/feed.rb",
    "content": "require \"rss/maker/atom\"\n\nmodule RSS\n  module Maker\n    module Atom\n      class Feed < RSSBase\n        def initialize(feed_version=\"1.0\")\n          super\n          @feed_type = \"atom\"\n          @feed_subtype = \"feed\"\n        end\n\n        private\n        def make_feed\n          ::RSS::Atom::Feed.new(@version, @encoding, @standalone)\n        end\n\n        def setup_elements(feed)\n          setup_channel(feed)\n          setup_image(feed)\n          setup_items(feed)\n        end\n\n        class Channel < ChannelBase\n          def to_feed(feed)\n            set_default_values do\n              setup_values(feed)\n              feed.dc_dates.clear\n              setup_other_elements(feed)\n              if image_favicon.about\n                icon = feed.class::Icon.new\n                icon.content = image_favicon.about\n                feed.icon = icon\n              end\n              unless have_required_values?\n                raise NotSetError.new(\"maker.channel\",\n                                      not_set_required_variables)\n              end\n            end\n          end\n\n          def have_required_values?\n            super and\n              (!authors.empty? or\n               @maker.items.any? {|item| !item.authors.empty?})\n          end\n\n          private\n          def required_variable_names\n            %w(id updated)\n          end\n\n          def variables\n            super + %w(id updated)\n          end\n\n          def variable_is_set?\n            super or !authors.empty?\n          end\n\n          def not_set_required_variables\n            vars = super\n            if authors.empty? and\n                @maker.items.all? {|item| item.author.to_s.empty?}\n              vars << \"author\"\n            end\n            vars << \"title\" unless title {|t| t.have_required_values?}\n            vars\n          end\n\n          def _set_default_values(&block)\n            keep = {\n              :id => id,\n              :updated => updated,\n            }\n            self.id ||= about\n            self.updated ||= dc_date\n            super(&block)\n          ensure\n            self.id = keep[:id]\n            self.updated = keep[:updated]\n          end\n\n          class SkipDays < SkipDaysBase\n            def to_feed(*args)\n            end\n\n            class Day < DayBase\n            end\n          end\n\n          class SkipHours < SkipHoursBase\n            def to_feed(*args)\n            end\n\n            class Hour < HourBase\n            end\n          end\n\n          class Cloud < CloudBase\n            def to_feed(*args)\n            end\n          end\n\n          class Categories < CategoriesBase\n            class Category < CategoryBase\n              include AtomCategory\n\n              def self.not_set_name\n                \"maker.channel.category\"\n              end\n            end\n          end\n\n          class Links < LinksBase\n            class Link < LinkBase\n              include AtomLink\n\n              def self.not_set_name\n                \"maker.channel.link\"\n              end\n            end\n          end\n\n          AtomPersons.def_atom_persons(self, \"author\", \"maker.channel.author\")\n          AtomPersons.def_atom_persons(self, \"contributor\",\n                                       \"maker.channel.contributor\")\n\n          class Generator < GeneratorBase\n            include AtomGenerator\n\n            def self.not_set_name\n              \"maker.channel.generator\"\n            end\n          end\n\n          AtomTextConstruct.def_atom_text_construct(self, \"rights\",\n                                                    \"maker.channel.copyright\",\n                                                    \"Copyright\")\n          AtomTextConstruct.def_atom_text_construct(self, \"subtitle\",\n                                                    \"maker.channel.description\",\n                                                    \"Description\")\n          AtomTextConstruct.def_atom_text_construct(self, \"title\",\n                                                    \"maker.channel.title\")\n        end\n\n        class Image < ImageBase\n          def to_feed(feed)\n            logo = feed.class::Logo.new\n            class << logo\n              alias_method(:url=, :content=)\n            end\n            set = setup_values(logo)\n            class << logo\n              remove_method(:url=)\n            end\n            if set\n              feed.logo = logo\n              set_parent(logo, feed)\n              setup_other_elements(feed, logo)\n            elsif variable_is_set?\n              raise NotSetError.new(\"maker.image\", not_set_required_variables)\n            end\n          end\n\n          private\n          def required_variable_names\n            %w(url)\n          end\n        end\n\n        class Items < ItemsBase\n          def to_feed(feed)\n            normalize.each do |item|\n              item.to_feed(feed)\n            end\n            setup_other_elements(feed, feed.entries)\n          end\n\n          class Item < ItemBase\n            def to_feed(feed)\n              set_default_values do\n                entry = feed.class::Entry.new\n                set = setup_values(entry)\n                setup_other_elements(feed, entry)\n                if set\n                  feed.entries << entry\n                  set_parent(entry, feed)\n                elsif variable_is_set?\n                  raise NotSetError.new(\"maker.item\", not_set_required_variables)\n                end\n              end\n            end\n\n            def have_required_values?\n              set_default_values do\n                super and title {|t| t.have_required_values?}\n              end\n            end\n\n            private\n            def required_variable_names\n              %w(id updated)\n            end\n\n            def variables\n              super + [\"updated\"]\n            end\n\n            def not_set_required_variables\n              vars = super\n              vars << \"title\" unless title {|t| t.have_required_values?}\n              vars\n            end\n\n            def _set_default_values(&block)\n              keep = {\n                :id => id,\n                :updated => updated,\n              }\n              self.id ||= link\n              self.updated ||= dc_date\n              super(&block)\n            ensure\n              self.id = keep[:id]\n              self.updated = keep[:updated]\n            end\n\n            class Guid < GuidBase\n              def to_feed(feed, current)\n              end\n            end\n\n            class Enclosure < EnclosureBase\n              def to_feed(feed, current)\n              end\n            end\n\n            class Source < SourceBase\n              def to_feed(feed, current)\n                source = current.class::Source.new\n                setup_values(source)\n                current.source = source\n                set_parent(source, current)\n                setup_other_elements(feed, source)\n                current.source = nil if source.to_s == \"<source/>\"\n              end\n\n              private\n              def required_variable_names\n                []\n              end\n\n              def variables\n                super + [\"updated\"]\n              end\n\n              AtomPersons.def_atom_persons(self, \"author\",\n                                           \"maker.item.source.author\")\n              AtomPersons.def_atom_persons(self, \"contributor\",\n                                           \"maker.item.source.contributor\")\n\n              class Categories < CategoriesBase\n                class Category < CategoryBase\n                  include AtomCategory\n\n                  def self.not_set_name\n                    \"maker.item.source.category\"\n                  end\n                end\n              end\n\n              class Generator < GeneratorBase\n                include AtomGenerator\n\n                def self.not_set_name\n                  \"maker.item.source.generator\"\n                end\n              end\n\n              class Icon < IconBase\n                def to_feed(feed, current)\n                  icon = current.class::Icon.new\n                  class << icon\n                    alias_method(:url=, :content=)\n                  end\n                  set = setup_values(icon)\n                  class << icon\n                    remove_method(:url=)\n                  end\n                  if set\n                    current.icon = icon\n                    set_parent(icon, current)\n                    setup_other_elements(feed, icon)\n                  elsif variable_is_set?\n                    raise NotSetError.new(\"maker.item.source.icon\",\n                                          not_set_required_variables)\n                  end\n                end\n\n                private\n                def required_variable_names\n                  %w(url)\n                end\n              end\n\n              class Links < LinksBase\n                class Link < LinkBase\n                  include AtomLink\n\n                  def self.not_set_name\n                    \"maker.item.source.link\"\n                  end\n                end\n              end\n\n              class Logo < LogoBase\n                include AtomLogo\n\n                def self.not_set_name\n                  \"maker.item.source.logo\"\n                end\n              end\n\n              maker_name_base = \"maker.item.source.\"\n              maker_name = \"#{maker_name_base}rights\"\n              AtomTextConstruct.def_atom_text_construct(self, \"rights\",\n                                                        maker_name)\n              maker_name = \"#{maker_name_base}subtitle\"\n              AtomTextConstruct.def_atom_text_construct(self, \"subtitle\",\n                                                        maker_name)\n              maker_name = \"#{maker_name_base}title\"\n              AtomTextConstruct.def_atom_text_construct(self, \"title\",\n                                                        maker_name)\n            end\n\n            class Categories < CategoriesBase\n              class Category < CategoryBase\n                include AtomCategory\n\n                def self.not_set_name\n                  \"maker.item.category\"\n                end\n              end\n            end\n\n            AtomPersons.def_atom_persons(self, \"author\", \"maker.item.author\")\n            AtomPersons.def_atom_persons(self, \"contributor\",\n                                         \"maker.item.contributor\")\n\n            class Links < LinksBase\n              class Link < LinkBase\n                include AtomLink\n\n                def self.not_set_name\n                  \"maker.item.link\"\n                end\n              end\n            end\n\n            AtomTextConstruct.def_atom_text_construct(self, \"rights\",\n                                                      \"maker.item.rights\")\n            AtomTextConstruct.def_atom_text_construct(self, \"summary\",\n                                                      \"maker.item.description\",\n                                                      \"Description\")\n            AtomTextConstruct.def_atom_text_construct(self, \"title\",\n                                                      \"maker.item.title\")\n\n            class Content < ContentBase\n              def to_feed(feed, current)\n                content = current.class::Content.new\n                if setup_values(content)\n                  content.src = nil if content.src and content.content\n                  current.content = content\n                  set_parent(content, current)\n                  setup_other_elements(feed, content)\n                elsif variable_is_set?\n                  raise NotSetError.new(\"maker.item.content\",\n                                        not_set_required_variables)\n                end\n              end\n\n              alias_method(:xml, :xml_content)\n\n              private\n              def required_variable_names\n                if out_of_line?\n                  %w(type)\n                elsif xml_type?\n                  %w(xml_content)\n                else\n                  %w(content)\n                end\n              end\n\n              def variables\n                if out_of_line?\n                  super\n                elsif xml_type?\n                  super + %w(xml)\n                else\n                  super\n                end\n              end\n\n              def xml_type?\n                _type = type\n                return false if _type.nil?\n                _type == \"xhtml\" or\n                  /(?:\\+xml|\\/xml)$/i =~ _type or\n                  %w(text/xml-external-parsed-entity\n                     application/xml-external-parsed-entity\n                     application/xml-dtd).include?(_type.downcase)\n              end\n            end\n          end\n        end\n\n        class Textinput < TextinputBase\n        end\n      end\n    end\n\n    add_maker(\"atom\", \"1.0\", Atom::Feed)\n    add_maker(\"atom:feed\", \"1.0\", Atom::Feed)\n    add_maker(\"atom1.0\", \"1.0\", Atom::Feed)\n    add_maker(\"atom1.0:feed\", \"1.0\", Atom::Feed)\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/image.rb",
    "content": "require 'rss/image'\nrequire 'rss/maker/1.0'\nrequire 'rss/maker/dublincore'\n\nmodule RSS\n  module Maker\n    module ImageItemModel\n      def self.append_features(klass)\n        super\n\n        name = \"#{RSS::IMAGE_PREFIX}_item\"\n        klass.def_classed_element(name)\n      end\n\n      def self.install_image_item(klass)\n\tklass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          class ImageItem < ImageItemBase\n            DublinCoreModel.install_dublin_core(self)\n          end\nEOC\n      end\n\n      class ImageItemBase < Base\n        include Maker::DublinCoreModel\n\n        attr_accessor :about, :resource, :image_width, :image_height\n        add_need_initialize_variable(\"about\")\n        add_need_initialize_variable(\"resource\")\n        add_need_initialize_variable(\"image_width\")\n        add_need_initialize_variable(\"image_height\")\n        alias width= image_width=\n        alias width image_width\n        alias height= image_height=\n        alias height image_height\n\n        def have_required_values?\n          @about\n        end\n\n        def to_feed(feed, current)\n          if current.respond_to?(:image_item=) and have_required_values?\n            item = current.class::ImageItem.new\n            setup_values(item)\n            setup_other_elements(item)\n            current.image_item = item\n          end\n        end\n      end\n    end\n\n    module ImageFaviconModel\n      def self.append_features(klass)\n        super\n\n        name = \"#{RSS::IMAGE_PREFIX}_favicon\"\n        klass.def_classed_element(name)\n      end\n\n      def self.install_image_favicon(klass)\n\tklass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          class ImageFavicon < ImageFaviconBase\n            DublinCoreModel.install_dublin_core(self)\n          end\n        EOC\n      end\n\n      class ImageFaviconBase < Base\n        include Maker::DublinCoreModel\n\n        attr_accessor :about, :image_size\n        add_need_initialize_variable(\"about\")\n        add_need_initialize_variable(\"image_size\")\n        alias size image_size\n        alias size= image_size=\n\n        def have_required_values?\n          @about and @image_size\n        end\n\n        def to_feed(feed, current)\n          if current.respond_to?(:image_favicon=) and have_required_values?\n            favicon = current.class::ImageFavicon.new\n            setup_values(favicon)\n            setup_other_elements(favicon)\n            current.image_favicon = favicon\n          end\n        end\n      end\n    end\n\n    class ChannelBase; include Maker::ImageFaviconModel; end\n    \n    class ItemsBase\n      class ItemBase; include Maker::ImageItemModel; end\n    end\n\n    makers.each do |maker|\n      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        class Channel\n          ImageFaviconModel.install_image_favicon(self)\n        end\n\n        class Items\n          class Item\n            ImageItemModel.install_image_item(self)\n          end\n        end\n      EOC\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/itunes.rb",
    "content": "require 'rss/itunes'\nrequire 'rss/maker/2.0'\n\nmodule RSS\n  module Maker\n    module ITunesBaseModel\n      def def_class_accessor(klass, name, type, *args)\n        name = name.gsub(/-/, \"_\").gsub(/^itunes_/, '')\n        full_name = \"#{RSS::ITUNES_PREFIX}_#{name}\"\n        case type\n        when nil\n          klass.def_other_element(full_name)\n        when :yes_other\n          def_yes_other_accessor(klass, full_name)\n        when :yes_clean_other\n          def_yes_clean_other_accessor(klass, full_name)\n        when :csv\n          def_csv_accessor(klass, full_name)\n        when :element, :attribute\n          recommended_attribute_name, = *args\n          klass_name = \"ITunes#{Utils.to_class_name(name)}\"\n          klass.def_classed_element(full_name, klass_name,\n                                    recommended_attribute_name)\n        when :elements\n          plural_name, recommended_attribute_name = args\n          plural_name ||= \"#{name}s\"\n          full_plural_name = \"#{RSS::ITUNES_PREFIX}_#{plural_name}\"\n          klass_name = \"ITunes#{Utils.to_class_name(name)}\"\n          plural_klass_name = \"ITunes#{Utils.to_class_name(plural_name)}\"\n          def_elements_class_accessor(klass, name, full_name, full_plural_name,\n                                      klass_name, plural_klass_name,\n                                      recommended_attribute_name)\n        end\n      end\n\n      def def_yes_other_accessor(klass, full_name)\n        klass.def_other_element(full_name)\n        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          def #{full_name}?\n            Utils::YesOther.parse(@#{full_name})\n          end\n        EOC\n      end\n\n      def def_yes_clean_other_accessor(klass, full_name)\n        klass.def_other_element(full_name)\n        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          def #{full_name}?\n            Utils::YesCleanOther.parse(#{full_name})\n          end\n        EOC\n      end\n\n      def def_csv_accessor(klass, full_name)\n        klass.def_csv_element(full_name)\n      end\n\n      def def_elements_class_accessor(klass, name, full_name, full_plural_name,\n                                      klass_name, plural_klass_name,\n                                      recommended_attribute_name=nil)\n        if recommended_attribute_name\n          klass.def_classed_elements(full_name, recommended_attribute_name,\n                                     plural_klass_name, full_plural_name)\n        else\n          klass.def_classed_element(full_plural_name, plural_klass_name)\n        end\n        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          def new_#{full_name}(text=nil)\n            #{full_name} = @#{full_plural_name}.new_#{name}\n            #{full_name}.text = text\n            if block_given?\n              yield #{full_name}\n            else\n              #{full_name}\n            end\n          end\n        EOC\n      end\n    end\n\n    module ITunesChannelModel\n      extend ITunesBaseModel\n\n      class << self\n        def append_features(klass)\n          super\n\n          ::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args|\n            def_class_accessor(klass, name, type, *args)\n          end\n        end\n      end\n\n      class ITunesCategoriesBase < Base\n        def_array_element(\"category\", \"itunes_categories\",\n                          \"ITunesCategory\")\n        class ITunesCategoryBase < Base\n          attr_accessor :text\n          add_need_initialize_variable(\"text\")\n          def_array_element(\"category\", \"itunes_categories\",\n                            \"ITunesCategory\")\n\n          def have_required_values?\n            text\n          end\n\n          alias_method :to_feed_for_categories, :to_feed\n          def to_feed(feed, current)\n            if text and current.respond_to?(:itunes_category)\n              new_item = current.class::ITunesCategory.new(text)\n              to_feed_for_categories(feed, new_item)\n              current.itunes_categories << new_item\n            end\n          end\n        end\n      end\n\n      class ITunesImageBase < Base\n        add_need_initialize_variable(\"href\")\n        attr_accessor(\"href\")\n\n        def to_feed(feed, current)\n          if @href and current.respond_to?(:itunes_image)\n            current.itunes_image ||= current.class::ITunesImage.new\n            current.itunes_image.href = @href\n          end\n        end\n      end\n\n      class ITunesOwnerBase < Base\n        %w(itunes_name itunes_email).each do |name|\n          add_need_initialize_variable(name)\n          attr_accessor(name)\n        end\n\n        def to_feed(feed, current)\n          if current.respond_to?(:itunes_owner=)\n            _not_set_required_variables = not_set_required_variables\n            if (required_variable_names - _not_set_required_variables).empty?\n              return\n            end\n\n            unless have_required_values?\n              raise NotSetError.new(\"maker.channel.itunes_owner\",\n                                    _not_set_required_variables)\n            end\n            current.itunes_owner ||= current.class::ITunesOwner.new\n            current.itunes_owner.itunes_name = @itunes_name\n            current.itunes_owner.itunes_email = @itunes_email\n          end\n        end\n\n        private\n        def required_variable_names\n          %w(itunes_name itunes_email)\n        end\n      end\n    end\n\n    module ITunesItemModel\n      extend ITunesBaseModel\n\n      class << self\n        def append_features(klass)\n          super\n\n          ::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args|\n            def_class_accessor(klass, name, type, *args)\n          end\n        end\n      end\n\n      class ITunesDurationBase < Base\n        attr_reader :content\n        add_need_initialize_variable(\"content\")\n\n        %w(hour minute second).each do |name|\n          attr_reader(name)\n          add_need_initialize_variable(name, '0')\n        end\n\n        def content=(content)\n          if content.nil?\n            @hour, @minute, @second, @content = nil\n          else\n            @hour, @minute, @second =\n              ::RSS::ITunesItemModel::ITunesDuration.parse(content)\n            @content = content\n          end\n        end\n\n        def hour=(hour)\n          @hour = Integer(hour)\n          update_content\n        end\n\n        def minute=(minute)\n          @minute = Integer(minute)\n          update_content\n        end\n\n        def second=(second)\n          @second = Integer(second)\n          update_content\n        end\n\n        def to_feed(feed, current)\n          if @content and current.respond_to?(:itunes_duration=)\n            current.itunes_duration ||= current.class::ITunesDuration.new\n            current.itunes_duration.content = @content\n          end\n        end\n\n        private\n        def update_content\n          components = [@hour, @minute, @second]\n          @content =\n            ::RSS::ITunesItemModel::ITunesDuration.construct(*components)\n        end\n      end\n    end\n\n    class ChannelBase\n      include Maker::ITunesChannelModel\n      class ITunesCategories < ITunesCategoriesBase\n        class ITunesCategory < ITunesCategoryBase\n          ITunesCategory = self\n        end\n      end\n\n      class ITunesImage < ITunesImageBase; end\n      class ITunesOwner < ITunesOwnerBase; end\n    end\n\n    class ItemsBase\n      class ItemBase\n        include Maker::ITunesItemModel\n        class ITunesDuration < ITunesDurationBase; end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/slash.rb",
    "content": "require 'rss/slash'\nrequire 'rss/maker/1.0'\n\nmodule RSS\n  module Maker\n    module SlashModel\n      def self.append_features(klass)\n        super\n\n        ::RSS::SlashModel::ELEMENT_INFOS.each do |name, type|\n          full_name = \"#{RSS::SLASH_PREFIX}_#{name}\"\n          case type\n          when :csv_integer\n            klass.def_csv_element(full_name, :integer)\n          else\n            klass.def_other_element(full_name)\n          end\n        end\n\n        klass.module_eval do\n          alias_method(:slash_hit_parades, :slash_hit_parade)\n          alias_method(:slash_hit_parades=, :slash_hit_parade=)\n        end\n      end\n    end\n\n    class ItemsBase\n      class ItemBase\n        include SlashModel\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/syndication.rb",
    "content": "require 'rss/syndication'\nrequire 'rss/maker/1.0'\n\nmodule RSS\n  module Maker\n    module SyndicationModel\n      def self.append_features(klass)\n        super\n\n        ::RSS::SyndicationModel::ELEMENTS.each do |name|\n          klass.def_other_element(name)\n        end\n      end\n    end\n\n    class ChannelBase; include SyndicationModel; end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/taxonomy.rb",
    "content": "require 'rss/taxonomy'\nrequire 'rss/maker/1.0'\nrequire 'rss/maker/dublincore'\n\nmodule RSS\n  module Maker\n    module TaxonomyTopicsModel\n      def self.append_features(klass)\n        super\n\n        klass.def_classed_element(\"#{RSS::TAXO_PREFIX}_topics\",\n                                  \"TaxonomyTopics\")\n      end\n\n      def self.install_taxo_topics(klass)\n        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          class TaxonomyTopics < TaxonomyTopicsBase\n            def to_feed(feed, current)\n              if current.respond_to?(:taxo_topics)\n                topics = current.class::TaxonomyTopics.new\n                bag = topics.Bag\n                @resources.each do |resource|\n                  bag.lis << RDF::Bag::Li.new(resource)\n                end\n                current.taxo_topics = topics\n              end\n            end\n          end\nEOC\n      end\n\n      class TaxonomyTopicsBase < Base\n        attr_reader :resources\n        def_array_element(\"resource\")\n        remove_method :new_resource\n      end\n    end\n\n    module TaxonomyTopicModel\n      def self.append_features(klass)\n        super\n\n        class_name = \"TaxonomyTopics\"\n        klass.def_classed_elements(\"#{TAXO_PREFIX}_topic\", \"value\", class_name)\n      end\n\n      def self.install_taxo_topic(klass)\n        klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          class TaxonomyTopics < TaxonomyTopicsBase\n            class TaxonomyTopic < TaxonomyTopicBase\n              DublinCoreModel.install_dublin_core(self)\n              TaxonomyTopicsModel.install_taxo_topics(self)\n\n              def to_feed(feed, current)\n                if current.respond_to?(:taxo_topics)\n                  topic = current.class::TaxonomyTopic.new(value)\n                  topic.taxo_link = value\n                  taxo_topics.to_feed(feed, topic) if taxo_topics\n                  current.taxo_topics << topic\n                  setup_other_elements(feed, topic)\n                end\n              end\n            end\n          end\nEOC\n      end\n\n      class TaxonomyTopicsBase < Base\n        def_array_element(\"topic\", nil, \"TaxonomyTopic\")\n        alias_method(:new_taxo_topic, :new_topic) # For backward compatibility\n\n        class TaxonomyTopicBase < Base\n          include DublinCoreModel\n          include TaxonomyTopicsModel\n          \n          attr_accessor :value\n          add_need_initialize_variable(\"value\")\n          alias_method(:taxo_link, :value)\n          alias_method(:taxo_link=, :value=)\n          \n          def have_required_values?\n            @value\n          end\n        end\n      end\n    end\n\n    class RSSBase\n      include TaxonomyTopicModel\n    end\n    \n    class ChannelBase\n      include TaxonomyTopicsModel\n    end\n    \n    class ItemsBase\n      class ItemBase\n        include TaxonomyTopicsModel\n      end\n    end\n\n    makers.each do |maker|\n      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        TaxonomyTopicModel.install_taxo_topic(self)\n\n        class Channel\n          TaxonomyTopicsModel.install_taxo_topics(self)\n        end\n\n        class Items\n          class Item\n            TaxonomyTopicsModel.install_taxo_topics(self)\n          end\n        end\n      EOC\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker/trackback.rb",
    "content": "require 'rss/trackback'\nrequire 'rss/maker/1.0'\nrequire 'rss/maker/2.0'\n\nmodule RSS\n  module Maker\n    module TrackBackModel\n      def self.append_features(klass)\n        super\n\n        klass.def_other_element(\"#{RSS::TRACKBACK_PREFIX}_ping\")\n        klass.def_classed_elements(\"#{RSS::TRACKBACK_PREFIX}_about\", \"value\",\n                                   \"TrackBackAbouts\")\n      end\n\n      class TrackBackAboutsBase < Base\n        def_array_element(\"about\", nil, \"TrackBackAbout\")\n\n        class TrackBackAboutBase < Base\n          attr_accessor :value\n          add_need_initialize_variable(\"value\")\n          \n          alias_method(:resource, :value)\n          alias_method(:resource=, :value=)\n          alias_method(:content, :value)\n          alias_method(:content=, :value=)\n\n          def have_required_values?\n            @value\n          end\n\n          def to_feed(feed, current)\n            if current.respond_to?(:trackback_abouts) and have_required_values?\n              about = current.class::TrackBackAbout.new\n              setup_values(about)\n              setup_other_elements(about)\n              current.trackback_abouts << about\n            end\n          end\n        end\n      end\n    end\n\n    class ItemsBase\n      class ItemBase; include TrackBackModel; end\n    end\n\n    makers.each do |maker|\n      maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        class Items\n          class Item\n            class TrackBackAbouts < TrackBackAboutsBase\n              class TrackBackAbout < TrackBackAboutBase\n              end\n            end\n          end\n        end\n      EOC\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/maker.rb",
    "content": "require \"rss/rss\"\n\nmodule RSS\n  module Maker\n    MAKERS = {}\n\n    class << self\n      def make(version, &block)\n        m = maker(version)\n        raise UnsupportedMakerVersionError.new(version) if m.nil?\n        m[:maker].make(m[:version], &block)\n      end\n\n      def maker(version)\n        MAKERS[version]\n      end\n\n      def add_maker(version, normalized_version, maker)\n        MAKERS[version] = {:maker => maker, :version => normalized_version}\n      end\n\n      def versions\n        MAKERS.keys.uniq.sort\n      end\n\n      def makers\n        MAKERS.values.collect {|info| info[:maker]}.uniq\n      end\n    end\n  end\nend\n\nrequire \"rss/maker/1.0\"\nrequire \"rss/maker/2.0\"\nrequire \"rss/maker/feed\"\nrequire \"rss/maker/entry\"\nrequire \"rss/maker/content\"\nrequire \"rss/maker/dublincore\"\nrequire \"rss/maker/slash\"\nrequire \"rss/maker/syndication\"\nrequire \"rss/maker/taxonomy\"\nrequire \"rss/maker/trackback\"\nrequire \"rss/maker/image\"\nrequire \"rss/maker/itunes\"\n"
  },
  {
    "path": "lib/rss/parser.rb",
    "content": "require \"forwardable\"\nrequire \"open-uri\"\n\nrequire \"rss/rss\"\nrequire \"rss/xml\"\n\nmodule RSS\n\n  class NotWellFormedError < Error\n    attr_reader :line, :element\n\n    # Create a new NotWellFormedError for an error at +line+\n    # in +element+.  If a block is given the return value of\n    # the block ends up in the error message.\n    def initialize(line=nil, element=nil)\n      message = \"This is not well formed XML\"\n      if element or line\n        message << \"\\nerror occurred\"\n        message << \" in #{element}\" if element\n        message << \" at about #{line} line\" if line\n      end\n      message << \"\\n#{yield}\" if block_given?\n      super(message)\n    end\n  end\n\n  class XMLParserNotFound < Error\n    def initialize\n      super(\"available XML parser was not found in \" <<\n            \"#{AVAILABLE_PARSER_LIBRARIES.inspect}.\")\n    end\n  end\n\n  class NotValidXMLParser < Error\n    def initialize(parser)\n      super(\"#{parser} is not an available XML parser. \" <<\n            \"Available XML parser\"<<\n            (AVAILABLE_PARSERS.size > 1 ? \"s are \": \" is \") <<\n            \"#{AVAILABLE_PARSERS.inspect}.\")\n    end\n  end\n\n  class NSError < InvalidRSSError\n    attr_reader :tag, :prefix, :uri\n    def initialize(tag, prefix, require_uri)\n      @tag, @prefix, @uri = tag, prefix, require_uri\n      super(\"prefix <#{prefix}> doesn't associate uri \" <<\n            \"<#{require_uri}> in tag <#{tag}>\")\n    end\n  end\n\n  class Parser\n\n    extend Forwardable\n\n    class << self\n\n      @@default_parser = nil\n\n      def default_parser\n        @@default_parser || AVAILABLE_PARSERS.first\n      end\n\n      # Set @@default_parser to new_value if it is one of the\n      # available parsers. Else raise NotValidXMLParser error.\n      def default_parser=(new_value)\n        if AVAILABLE_PARSERS.include?(new_value)\n          @@default_parser = new_value\n        else\n          raise NotValidXMLParser.new(new_value)\n        end\n      end\n\n      def parse(rss, do_validate=true, ignore_unknown_element=true,\n                parser_class=default_parser)\n        parser = new(rss, parser_class)\n        parser.do_validate = do_validate\n        parser.ignore_unknown_element = ignore_unknown_element\n        parser.parse\n      end\n    end\n\n    def_delegators(:@parser, :parse, :rss,\n                   :ignore_unknown_element,\n                   :ignore_unknown_element=, :do_validate,\n                   :do_validate=)\n\n    def initialize(rss, parser_class=self.class.default_parser)\n      @parser = parser_class.new(normalize_rss(rss))\n    end\n\n    private\n\n    # Try to get the XML associated with +rss+.\n    # Return +rss+ if it already looks like XML, or treat it as a URI,\n    # or a file to get the XML,\n    def normalize_rss(rss)\n      return rss if maybe_xml?(rss)\n\n      uri = to_uri(rss)\n      \n      if uri.respond_to?(:read)\n        uri.read\n      elsif !rss.tainted? and File.readable?(rss)\n        File.open(rss) {|f| f.read}\n      else\n        rss\n      end\n    end\n\n    # maybe_xml? tests if source is a string that looks like XML.\n    def maybe_xml?(source)\n      source.is_a?(String) and /</ =~ source\n    end\n\n    # Attempt to convert rss to a URI, but just return it if \n    # there's a ::URI::Error\n    def to_uri(rss)\n      return rss if rss.is_a?(::URI::Generic)\n\n      begin\n        ::URI.parse(rss)\n      rescue ::URI::Error\n        rss\n      end\n    end\n  end\n\n  class BaseParser\n\n    class << self\n      def raise_for_undefined_entity?\n        listener.raise_for_undefined_entity?\n      end\n    end\n    \n    def initialize(rss)\n      @listener = self.class.listener.new\n      @rss = rss\n    end\n\n    def rss\n      @listener.rss\n    end\n\n    def ignore_unknown_element\n      @listener.ignore_unknown_element\n    end\n\n    def ignore_unknown_element=(new_value)\n      @listener.ignore_unknown_element = new_value\n    end\n\n    def do_validate\n      @listener.do_validate\n    end\n\n    def do_validate=(new_value)\n      @listener.do_validate = new_value\n    end\n\n    def parse\n      if @listener.rss.nil?\n        _parse\n      end\n      @listener.rss\n    end\n\n  end\n\n  class BaseListener\n\n    extend Utils\n\n    class << self\n\n      @@accessor_bases = {}\n      @@registered_uris = {}\n      @@class_names = {}\n\n      # return the setter for the uri, tag_name pair, or nil.\n      def setter(uri, tag_name)\n        _getter = getter(uri, tag_name)\n        if _getter\n          \"#{_getter}=\"\n        else\n          nil\n        end\n      end\n\n      def getter(uri, tag_name)\n        (@@accessor_bases[uri] || {})[tag_name]\n      end\n\n      # return the tag_names for setters associated with uri\n      def available_tags(uri)\n        (@@accessor_bases[uri] || {}).keys\n      end\n      \n      # register uri against this name.\n      def register_uri(uri, name)\n        @@registered_uris[name] ||= {}\n        @@registered_uris[name][uri] = nil\n      end\n      \n      # test if this uri is registered against this name\n      def uri_registered?(uri, name)\n        @@registered_uris[name].has_key?(uri)\n      end\n\n      # record class_name for the supplied uri and tag_name\n      def install_class_name(uri, tag_name, class_name)\n        @@class_names[uri] ||= {}\n        @@class_names[uri][tag_name] = class_name\n      end\n\n      # retrieve class_name for the supplied uri and tag_name\n      # If it doesn't exist, capitalize the tag_name\n      def class_name(uri, tag_name)\n        name = (@@class_names[uri] || {})[tag_name]\n        return name if name\n\n        tag_name = tag_name.gsub(/[_\\-]([a-z]?)/) do\n          $1.upcase\n        end\n        tag_name[0, 1].upcase + tag_name[1..-1]\n      end\n\n      def install_get_text_element(uri, name, accessor_base)\n        install_accessor_base(uri, name, accessor_base)\n        def_get_text_element(uri, name, *get_file_and_line_from_caller(1))\n      end\n      \n      def raise_for_undefined_entity?\n        true\n      end\n    \n      private\n      # set the accessor for the uri, tag_name pair\n      def install_accessor_base(uri, tag_name, accessor_base)\n        @@accessor_bases[uri] ||= {}\n        @@accessor_bases[uri][tag_name] = accessor_base.chomp(\"=\")\n      end\n\n      def def_get_text_element(uri, element_name, file, line)\n        register_uri(uri, element_name)\n        method_name = \"start_#{element_name}\"\n        unless private_method_defined?(method_name)\n          define_method(method_name) do |name, prefix, attrs, ns|\n            uri = _ns(ns, prefix)\n            if self.class.uri_registered?(uri, element_name)\n              start_get_text_element(name, prefix, ns, uri)\n            else\n              start_else_element(name, prefix, attrs, ns)\n            end\n          end\n          private(method_name)\n        end\n      end\n    end\n  end\n\n  module ListenerMixin\n    attr_reader :rss\n\n    attr_accessor :ignore_unknown_element\n    attr_accessor :do_validate\n\n    def initialize\n      @rss = nil\n      @ignore_unknown_element = true\n      @do_validate = true\n      @ns_stack = [{\"xml\" => :xml}]\n      @tag_stack = [[]]\n      @text_stack = ['']\n      @proc_stack = []\n      @last_element = nil\n      @version = @encoding = @standalone = nil\n      @xml_stylesheets = []\n      @xml_child_mode = false\n      @xml_element = nil\n      @last_xml_element = nil\n    end\n    \n    # set instance vars for version, encoding, standalone\n    def xmldecl(version, encoding, standalone)\n      @version, @encoding, @standalone = version, encoding, standalone\n    end\n\n    def instruction(name, content)\n      if name == \"xml-stylesheet\"\n        params = parse_pi_content(content)\n        if params.has_key?(\"href\")\n          @xml_stylesheets << XMLStyleSheet.new(params)\n        end\n      end\n    end\n\n    def tag_start(name, attributes)\n      @text_stack.push('')\n\n      ns = @ns_stack.last.dup\n      attrs = {}\n      attributes.each do |n, v|\n        if /\\Axmlns(?:\\z|:)/ =~ n\n          ns[$POSTMATCH] = v\n        else\n          attrs[n] = v\n        end\n      end\n      @ns_stack.push(ns)\n\n      prefix, local = split_name(name)\n      @tag_stack.last.push([_ns(ns, prefix), local])\n      @tag_stack.push([])\n      if @xml_child_mode\n        previous = @last_xml_element\n        element_attrs = attributes.dup\n        unless previous\n          ns.each do |ns_prefix, value|\n            next if ns_prefix == \"xml\"\n            key = ns_prefix.empty? ? \"xmlns\" : \"xmlns:#{ns_prefix}\"\n            element_attrs[key] ||= value\n          end\n        end\n        next_element = XML::Element.new(local,\n                                        prefix.empty? ? nil : prefix,\n                                        _ns(ns, prefix),\n                                        element_attrs)\n        previous << next_element if previous\n        @last_xml_element = next_element\n        pr = Proc.new do |text, tags|\n          if previous\n            @last_xml_element = previous\n          else\n            @xml_element = @last_xml_element\n            @last_xml_element = nil\n          end\n        end\n        @proc_stack.push(pr)\n      else\n        if @rss.nil? and respond_to?(\"initial_start_#{local}\", true)\n          __send__(\"initial_start_#{local}\", local, prefix, attrs, ns.dup)\n        elsif respond_to?(\"start_#{local}\", true)\n          __send__(\"start_#{local}\", local, prefix, attrs, ns.dup)\n        else\n          start_else_element(local, prefix, attrs, ns.dup)\n        end\n      end\n    end\n\n    def tag_end(name)\n      if DEBUG\n        p \"end tag #{name}\"\n        p @tag_stack\n      end\n      text = @text_stack.pop\n      tags = @tag_stack.pop\n      pr = @proc_stack.pop\n      pr.call(text, tags) unless pr.nil?\n      @ns_stack.pop\n    end\n\n    def text(data)\n      if @xml_child_mode\n        @last_xml_element << data if @last_xml_element\n      else\n        @text_stack.last << data\n      end\n    end\n\n    private\n    def _ns(ns, prefix)\n      ns.fetch(prefix, \"\")\n    end\n\n    CONTENT_PATTERN = /\\s*([^=]+)=([\"'])([^\\2]+?)\\2/\n    # Extract the first name=\"value\" pair from content.\n    # Works with single quotes according to the constant\n    # CONTENT_PATTERN. Return a Hash.\n    def parse_pi_content(content)\n      params = {}\n      content.scan(CONTENT_PATTERN) do |name, quote, value|\n        params[name] = value\n      end\n      params\n    end\n\n    def start_else_element(local, prefix, attrs, ns)\n      class_name = self.class.class_name(_ns(ns, prefix), local)\n      current_class = @last_element.class\n      if class_name and\n          (current_class.const_defined?(class_name) or\n           current_class.constants.include?(class_name))\n        next_class = current_class.const_get(class_name)\n        start_have_something_element(local, prefix, attrs, ns, next_class)\n      else\n        if !@do_validate or @ignore_unknown_element\n          @proc_stack.push(nil)\n        else\n          parent = \"ROOT ELEMENT???\"\n          if current_class.tag_name\n            parent = current_class.tag_name\n          end\n          raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)\n        end\n      end\n    end\n\n    NAMESPLIT = /^(?:([\\w:][-\\w\\d.]*):)?([\\w:][-\\w\\d.]*)/\n    def split_name(name)\n      name =~ NAMESPLIT\n      [$1 || '', $2]\n    end\n\n    def check_ns(tag_name, prefix, ns, require_uri)\n      unless _ns(ns, prefix) == require_uri\n        if @do_validate\n          raise NSError.new(tag_name, prefix, require_uri)\n        else\n          # Force bind required URI with prefix\n          @ns_stack.last[prefix] = require_uri\n        end\n      end\n    end\n\n    def start_get_text_element(tag_name, prefix, ns, required_uri)\n      pr = Proc.new do |text, tags|\n        setter = self.class.setter(required_uri, tag_name)\n        if @last_element.respond_to?(setter)\n          if @do_validate\n            getter = self.class.getter(required_uri, tag_name)\n            if @last_element.__send__(getter)\n              raise TooMuchTagError.new(tag_name, @last_element.tag_name)\n            end\n          end\n          @last_element.__send__(setter, text.to_s)\n        else\n          if @do_validate and !@ignore_unknown_element\n            raise NotExpectedTagError.new(tag_name, _ns(ns, prefix),\n                                          @last_element.tag_name)\n          end\n        end\n      end\n      @proc_stack.push(pr)\n    end\n\n    def start_have_something_element(tag_name, prefix, attrs, ns, klass)\n      check_ns(tag_name, prefix, ns, klass.required_uri)\n      attributes = collect_attributes(tag_name, prefix, attrs, ns, klass)\n      @proc_stack.push(setup_next_element(tag_name, klass, attributes))\n    end\n\n    def collect_attributes(tag_name, prefix, attrs, ns, klass)\n      attributes = {}\n      klass.get_attributes.each do |a_name, a_uri, required, element_name|\n        if a_uri.is_a?(String) or !a_uri.respond_to?(:include?)\n          a_uri = [a_uri]\n        end\n        unless a_uri == [\"\"]\n          for prefix, uri in ns\n            if a_uri.include?(uri)\n              val = attrs[\"#{prefix}:#{a_name}\"]\n              break if val\n            end\n          end\n        end\n        if val.nil? and a_uri.include?(\"\")\n          val = attrs[a_name]\n        end\n\n        if @do_validate and required and val.nil?\n          unless a_uri.include?(\"\")\n            for prefix, uri in ns\n              if a_uri.include?(uri)\n                a_name = \"#{prefix}:#{a_name}\"\n              end\n            end\n          end\n          raise MissingAttributeError.new(tag_name, a_name)\n        end\n\n        attributes[a_name] = val\n      end\n      attributes\n    end\n\n    def setup_next_element(tag_name, klass, attributes)\n      previous = @last_element\n      next_element = klass.new(@do_validate, attributes)\n      previous.set_next_element(tag_name, next_element)\n      @last_element = next_element\n      @last_element.parent = previous if klass.need_parent?\n      @xml_child_mode = @last_element.have_xml_content?\n\n      Proc.new do |text, tags|\n        p(@last_element.class) if DEBUG\n        if @xml_child_mode\n          @last_element.content = @xml_element.to_s\n          xml_setter = @last_element.class.xml_setter\n          @last_element.__send__(xml_setter, @xml_element)\n          @xml_element = nil\n          @xml_child_mode = false\n        else\n          if klass.have_content?\n            if @last_element.need_base64_encode?\n              text = Base64.decode64(text.lstrip)\n            end\n            @last_element.content = text\n          end\n        end\n        if @do_validate\n          @last_element.validate_for_stream(tags, @ignore_unknown_element)\n        end\n        @last_element = previous\n      end\n    end\n  end\n\n  unless const_defined? :AVAILABLE_PARSER_LIBRARIES\n    AVAILABLE_PARSER_LIBRARIES = [\n      [\"rss/xmlparser\", :XMLParserParser],\n      [\"rss/xmlscanner\", :XMLScanParser],\n      [\"rss/rexmlparser\", :REXMLParser],\n    ]\n  end\n\n  AVAILABLE_PARSERS = []\n\n  AVAILABLE_PARSER_LIBRARIES.each do |lib, parser|\n    begin\n      require lib\n      AVAILABLE_PARSERS.push(const_get(parser))\n    rescue LoadError\n    end\n  end\n\n  if AVAILABLE_PARSERS.empty?\n    raise XMLParserNotFound\n  end\nend\n"
  },
  {
    "path": "lib/rss/rexmlparser.rb",
    "content": "require \"rexml/document\"\nrequire \"rexml/streamlistener\"\n\n/\\A(\\d+)\\.(\\d+)(?:\\.\\d+)+\\z/ =~ REXML::Version\nif ([$1.to_i, $2.to_i] <=> [2, 5]) < 0\n  raise LoadError, \"needs REXML 2.5 or later (#{REXML::Version})\"\nend\n\nmodule RSS\n  \n  class REXMLParser < BaseParser\n\n    class << self\n      def listener\n        REXMLListener\n      end\n    end\n    \n    private\n    def _parse\n      begin\n        REXML::Document.parse_stream(@rss, @listener)\n      rescue RuntimeError => e\n        raise NotWellFormedError.new{e.message}\n      rescue REXML::ParseException => e\n        context = e.context\n        line = context[0] if context\n        raise NotWellFormedError.new(line){e.message}\n      end\n    end\n    \n  end\n  \n  class REXMLListener < BaseListener\n\n    include REXML::StreamListener\n    include ListenerMixin\n\n    class << self\n      def raise_for_undefined_entity?\n        false\n      end\n    end\n    \n    def xmldecl(version, encoding, standalone)\n      super(version, encoding, standalone == \"yes\")\n      # Encoding is converted to UTF-8 when REXML parse XML.\n      @encoding = 'UTF-8'\n    end\n\n    alias_method(:cdata, :text)\n  end\n\nend\n"
  },
  {
    "path": "lib/rss/rss.rb",
    "content": "require \"time\"\n\nclass Time\n  class << self\n    unless respond_to?(:w3cdtf)\n      def w3cdtf(date)\n        if /\\A\\s*\n            (-?\\d+)-(\\d\\d)-(\\d\\d)\n            (?:T\n            (\\d\\d):(\\d\\d)(?::(\\d\\d))?\n            (\\.\\d+)?\n            (Z|[+-]\\d\\d:\\d\\d)?)?\n            \\s*\\z/ix =~ date and (($5 and $8) or (!$5 and !$8))\n          datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]\n          usec = 0\n          usec = $7.to_f * 1000000 if $7\n          zone = $8\n          if zone\n            off = zone_offset(zone, datetime[0])\n            datetime = apply_offset(*(datetime + [off]))\n            datetime << usec\n            time = Time.utc(*datetime)\n            time.localtime unless zone_utc?(zone)\n            time\n          else\n            datetime << usec\n            Time.local(*datetime)\n          end\n        else\n          raise ArgumentError.new(\"invalid date: #{date.inspect}\")\n        end\n      end\n    end\n  end\n\n  unless method_defined?(:w3cdtf)\n    def w3cdtf\n      if usec.zero?\n        fraction_digits = 0\n      else\n        fraction_digits = Math.log10(usec.to_s.sub(/0*$/, '').to_i).floor + 1\n      end\n      xmlschema(fraction_digits)\n    end\n  end\nend\n\nrequire \"English\"\nrequire \"rss/utils\"\nrequire \"rss/converter\"\nrequire \"rss/xml-stylesheet\"\n\nmodule RSS\n\n  VERSION = \"0.2.4\"\n\n  URI = \"http://purl.org/rss/1.0/\"\n\n  DEBUG = false\n\n  class Error < StandardError; end\n\n  class OverlappedPrefixError < Error\n    attr_reader :prefix\n    def initialize(prefix)\n      @prefix = prefix\n    end\n  end\n\n  class InvalidRSSError < Error; end\n\n  class MissingTagError < InvalidRSSError\n    attr_reader :tag, :parent\n    def initialize(tag, parent)\n      @tag, @parent = tag, parent\n      super(\"tag <#{tag}> is missing in tag <#{parent}>\")\n    end\n  end\n\n  class TooMuchTagError < InvalidRSSError\n    attr_reader :tag, :parent\n    def initialize(tag, parent)\n      @tag, @parent = tag, parent\n      super(\"tag <#{tag}> is too much in tag <#{parent}>\")\n    end\n  end\n\n  class MissingAttributeError < InvalidRSSError\n    attr_reader :tag, :attribute\n    def initialize(tag, attribute)\n      @tag, @attribute = tag, attribute\n      super(\"attribute <#{attribute}> is missing in tag <#{tag}>\")\n    end\n  end\n\n  class UnknownTagError < InvalidRSSError\n    attr_reader :tag, :uri\n    def initialize(tag, uri)\n      @tag, @uri = tag, uri\n      super(\"tag <#{tag}> is unknown in namespace specified by uri <#{uri}>\")\n    end\n  end\n\n  class NotExpectedTagError < InvalidRSSError\n    attr_reader :tag, :uri, :parent\n    def initialize(tag, uri, parent)\n      @tag, @uri, @parent = tag, uri, parent\n      super(\"tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>\")\n    end\n  end\n  # For backward compatibility :X\n  NotExceptedTagError = NotExpectedTagError\n\n  class NotAvailableValueError < InvalidRSSError\n    attr_reader :tag, :value, :attribute\n    def initialize(tag, value, attribute=nil)\n      @tag, @value, @attribute = tag, value, attribute\n      message = \"value <#{value}> of \"\n      message << \"attribute <#{attribute}> of \" if attribute\n      message << \"tag <#{tag}> is not available.\"\n      super(message)\n    end\n  end\n\n  class UnknownConversionMethodError < Error\n    attr_reader :to, :from\n    def initialize(to, from)\n      @to = to\n      @from = from\n      super(\"can't convert to #{to} from #{from}.\")\n    end\n  end\n  # for backward compatibility\n  UnknownConvertMethod = UnknownConversionMethodError\n\n  class ConversionError < Error\n    attr_reader :string, :to, :from\n    def initialize(string, to, from)\n      @string = string\n      @to = to\n      @from = from\n      super(\"can't convert #{@string} to #{to} from #{from}.\")\n    end\n  end\n\n  class NotSetError < Error\n    attr_reader :name, :variables\n    def initialize(name, variables)\n      @name = name\n      @variables = variables\n      super(\"required variables of #{@name} are not set: #{@variables.join(', ')}\")\n    end\n  end\n\n  class UnsupportedMakerVersionError < Error\n    attr_reader :version\n    def initialize(version)\n      @version = version\n      super(\"Maker doesn't support version: #{@version}\")\n    end\n  end\n\n  module BaseModel\n    include Utils\n\n    def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil)\n      name ||= tag_name\n      add_need_initialize_variable(name)\n      install_model(tag_name, uri, occurs, name)\n\n      writer_type, reader_type = type\n      def_corresponded_attr_writer name, writer_type\n      def_corresponded_attr_reader name, reader_type\n      install_element(name) do |n, elem_name|\n        <<-EOC\n        if @#{n}\n          \"\\#{@#{n}.to_s(need_convert, indent)}\"\n        else\n          ''\n        end\nEOC\n      end\n    end\n    alias_method(:install_have_attribute_element, :install_have_child_element)\n\n    def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil)\n      name ||= tag_name\n      plural_name ||= \"#{name}s\"\n      add_have_children_element(name, plural_name)\n      add_plural_form(name, plural_name)\n      install_model(tag_name, uri, occurs, plural_name, true)\n\n      def_children_accessor(name, plural_name)\n      install_element(name, \"s\") do |n, elem_name|\n        <<-EOC\n        rv = []\n        @#{n}.each do |x|\n          value = \"\\#{x.to_s(need_convert, indent)}\"\n          rv << value if /\\\\A\\\\s*\\\\z/ !~ value\n        end\n        rv.join(\"\\n\")\nEOC\n      end\n    end\n\n    def install_text_element(tag_name, uri, occurs, name=nil, type=nil,\n                             disp_name=nil)\n      name ||= tag_name\n      disp_name ||= name\n      self::ELEMENTS << name unless self::ELEMENTS.include?(name)\n      add_need_initialize_variable(name)\n      install_model(tag_name, uri, occurs, name)\n\n      def_corresponded_attr_writer(name, type, disp_name)\n      def_corresponded_attr_reader(name, type || :convert)\n      install_element(name) do |n, elem_name|\n        <<-EOC\n        if respond_to?(:#{n}_content)\n          content = #{n}_content\n        else\n          content = @#{n}\n        end\n        if content\n          rv = \"\\#{indent}<#{elem_name}>\"\n          value = html_escape(content)\n          if need_convert\n            rv << convert(value)\n          else\n            rv << value\n          end\n    \t    rv << \"</#{elem_name}>\"\n          rv\n        else\n          ''\n        end\nEOC\n      end\n    end\n\n    def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)\n      name ||= tag_name\n      type ||= :w3cdtf\n      disp_name ||= name\n      self::ELEMENTS << name\n      add_need_initialize_variable(name)\n      install_model(tag_name, uri, occurs, name)\n\n      # accessor\n      convert_attr_reader name\n      date_writer(name, type, disp_name)\n      \n      install_element(name) do |n, elem_name|\n        <<-EOC\n        if @#{n}\n          rv = \"\\#{indent}<#{elem_name}>\"\n          value = html_escape(@#{n}.#{type})\n          if need_convert\n            rv << convert(value)\n          else\n            rv << value\n          end\n    \t    rv << \"</#{elem_name}>\"\n          rv\n        else\n          ''\n        end\nEOC\n      end\n\n    end\n\n    private\n    def install_element(name, postfix=\"\")\n      elem_name = name.sub('_', ':')\n      method_name = \"#{name}_element#{postfix}\"\n      add_to_element_method(method_name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{method_name}(need_convert=true, indent='')\n        #{yield(name, elem_name)}\n      end\n      private :#{method_name}\nEOC\n    end\n\n    def inherit_convert_attr_reader(*attrs)\n      attrs.each do |attr|\n        attr = attr.id2name if attr.kind_of?(Integer)\n        module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n        def #{attr}_without_inherit\n          convert(@#{attr})\n        end\n\n        def #{attr}\n          if @#{attr}\n            #{attr}_without_inherit\n          elsif @parent\n            @parent.#{attr}\n          else\n            nil\n          end\n        end\nEOC\n      end\n    end\n\n    def uri_convert_attr_reader(*attrs)\n      attrs.each do |attr|\n        attr = attr.id2name if attr.kind_of?(Integer)\n        module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n        def #{attr}_without_base\n          convert(@#{attr})\n        end\n\n        def #{attr}\n          value = #{attr}_without_base\n          return nil if value.nil?\n          if /\\\\A[a-z][a-z0-9+.\\\\-]*:/i =~ value\n            value\n          else\n            \"\\#{base}\\#{value}\"\n          end\n        end\nEOC\n      end\n    end\n\n    def convert_attr_reader(*attrs)\n      attrs.each do |attr|\n        attr = attr.id2name if attr.kind_of?(Integer)\n        module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n        def #{attr}\n          convert(@#{attr})\n        end\nEOC\n      end\n    end\n\n    def yes_clean_other_attr_reader(*attrs)\n      attrs.each do |attr|\n        attr = attr.id2name if attr.kind_of?(Integer)\n        module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          attr_reader(:#{attr})\n          def #{attr}?\n            YesCleanOther.parse(@#{attr})\n          end\n        EOC\n      end\n    end\n\n    def yes_other_attr_reader(*attrs)\n      attrs.each do |attr|\n        attr = attr.id2name if attr.kind_of?(Integer)\n        module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          attr_reader(:#{attr})\n          def #{attr}?\n            Utils::YesOther.parse(@#{attr})\n          end\n        EOC\n      end\n    end\n\n    def csv_attr_reader(*attrs)\n      separator = nil\n      if attrs.last.is_a?(Hash)\n        options = attrs.pop\n        separator = options[:separator]\n      end\n      separator ||= \", \"\n      attrs.each do |attr|\n        attr = attr.id2name if attr.kind_of?(Integer)\n        module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n          attr_reader(:#{attr})\n          def #{attr}_content\n            if @#{attr}.nil?\n              @#{attr}\n            else\n              @#{attr}.join(#{separator.dump})\n            end\n          end\n        EOC\n      end\n    end\n\n    def date_writer(name, type, disp_name=name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{name}=(new_value)\n        if new_value.nil?\n          @#{name} = new_value\n        elsif new_value.kind_of?(Time)\n          @#{name} = new_value.dup\n        else\n          if @do_validate\n            begin\n              @#{name} = Time.__send__('#{type}', new_value)\n            rescue ArgumentError\n              raise NotAvailableValueError.new('#{disp_name}', new_value)\n            end\n          else\n            @#{name} = nil\n            if /\\\\A\\\\s*\\\\z/ !~ new_value.to_s\n              begin\n                unless Date._parse(new_value, false).empty?\n                  @#{name} = Time.parse(new_value)\n                end\n              rescue ArgumentError\n              end\n            end\n          end\n        end\n\n        # Is it need?\n        if @#{name}\n          class << @#{name}\n            undef_method(:to_s)\n            alias_method(:to_s, :#{type})\n          end\n        end\n\n      end\nEOC\n    end\n\n    def integer_writer(name, disp_name=name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{name}=(new_value)\n        if new_value.nil?\n          @#{name} = new_value\n        else\n          if @do_validate\n            begin\n              @#{name} = Integer(new_value)\n            rescue ArgumentError\n              raise NotAvailableValueError.new('#{disp_name}', new_value)\n            end\n          else\n            @#{name} = new_value.to_i\n          end\n        end\n      end\nEOC\n    end\n\n    def positive_integer_writer(name, disp_name=name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{name}=(new_value)\n        if new_value.nil?\n          @#{name} = new_value\n        else\n          if @do_validate\n            begin\n              tmp = Integer(new_value)\n              raise ArgumentError if tmp <= 0\n              @#{name} = tmp\n            rescue ArgumentError\n              raise NotAvailableValueError.new('#{disp_name}', new_value)\n            end\n          else\n            @#{name} = new_value.to_i\n          end\n        end\n      end\nEOC\n    end\n\n    def boolean_writer(name, disp_name=name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{name}=(new_value)\n        if new_value.nil?\n          @#{name} = new_value\n        else\n          if @do_validate and\n              ![true, false, \"true\", \"false\"].include?(new_value)\n            raise NotAvailableValueError.new('#{disp_name}', new_value)\n          end\n          if [true, false].include?(new_value)\n            @#{name} = new_value\n          else\n            @#{name} = new_value == \"true\"\n          end\n        end\n      end\nEOC\n    end\n\n    def text_type_writer(name, disp_name=name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{name}=(new_value)\n        if @do_validate and\n            ![\"text\", \"html\", \"xhtml\", nil].include?(new_value)\n          raise NotAvailableValueError.new('#{disp_name}', new_value)\n        end\n        @#{name} = new_value\n      end\nEOC\n    end\n\n    def content_writer(name, disp_name=name)\n      klass_name = \"self.class::#{Utils.to_class_name(name)}\"\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{name}=(new_value)\n        if new_value.is_a?(#{klass_name})\n          @#{name} = new_value\n        else\n          @#{name} = #{klass_name}.new\n          @#{name}.content = new_value\n        end\n      end\nEOC\n    end\n\n    def yes_clean_other_writer(name, disp_name=name)\n      module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        def #{name}=(value)\n          value = (value ? \"yes\" : \"no\") if [true, false].include?(value)\n          @#{name} = value\n        end\n      EOC\n    end\n\n    def yes_other_writer(name, disp_name=name)\n      module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        def #{name}=(new_value)\n          if [true, false].include?(new_value)\n            new_value = new_value ? \"yes\" : \"no\"\n          end\n          @#{name} = new_value\n        end\n      EOC\n    end\n\n    def csv_writer(name, disp_name=name)\n      module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        def #{name}=(new_value)\n          @#{name} = Utils::CSV.parse(new_value)\n        end\n      EOC\n    end\n\n    def csv_integer_writer(name, disp_name=name)\n      module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        def #{name}=(new_value)\n          @#{name} = Utils::CSV.parse(new_value) {|v| Integer(v)}\n        end\n      EOC\n    end\n\n    def def_children_accessor(accessor_name, plural_name)\n      module_eval(<<-EOC, *get_file_and_line_from_caller(2))\n      def #{plural_name}\n        @#{accessor_name}\n      end\n\n      def #{accessor_name}(*args)\n        if args.empty?\n          @#{accessor_name}.first\n        else\n          @#{accessor_name}[*args]\n        end\n      end\n\n      def #{accessor_name}=(*args)\n        receiver = self.class.name\n        warn(\"Warning:\\#{caller.first.sub(/:in `.*'\\z/, '')}: \" \\\n             \"Don't use `\\#{receiver}\\##{accessor_name} = XXX'/\" \\\n             \"`\\#{receiver}\\#set_#{accessor_name}(XXX)'. \" \\\n             \"Those APIs are not sense of Ruby. \" \\\n             \"Use `\\#{receiver}\\##{plural_name} << XXX' instead of them.\")\n        if args.size == 1\n          @#{accessor_name}.push(args[0])\n        else\n          @#{accessor_name}.__send__(\"[]=\", *args)\n        end\n      end\n      alias_method(:set_#{accessor_name}, :#{accessor_name}=)\nEOC\n    end\n  end\n\n  module SetupMaker\n    def setup_maker(maker)\n      target = maker_target(maker)\n      unless target.nil?\n        setup_maker_attributes(target)\n        setup_maker_element(target)\n        setup_maker_elements(target)\n      end\n    end\n\n    private\n    def maker_target(maker)\n      nil\n    end\n\n    def setup_maker_attributes(target)\n    end\n\n    def setup_maker_element(target)\n      self.class.need_initialize_variables.each do |var|\n        value = __send__(var)\n        next if value.nil?\n        if value.respond_to?(\"setup_maker\") and\n            !not_need_to_call_setup_maker_variables.include?(var)\n          value.setup_maker(target)\n        else\n          setter = \"#{var}=\"\n          if target.respond_to?(setter)\n            target.__send__(setter, value)\n          end\n        end\n      end\n    end\n\n    def not_need_to_call_setup_maker_variables\n      []\n    end\n\n    def setup_maker_elements(parent)\n      self.class.have_children_elements.each do |name, plural_name|\n        if parent.respond_to?(plural_name)\n          target = parent.__send__(plural_name)\n          __send__(plural_name).each do |elem|\n            elem.setup_maker(target)\n          end\n        end\n      end\n    end\n  end\n\n  class Element\n    extend BaseModel\n    include Utils\n    extend Utils::InheritedReader\n    include SetupMaker\n\n    INDENT = \"  \"\n    \n    MUST_CALL_VALIDATORS = {}\n    MODELS = []\n    GET_ATTRIBUTES = []\n    HAVE_CHILDREN_ELEMENTS = []\n    TO_ELEMENT_METHODS = []\n    NEED_INITIALIZE_VARIABLES = []\n    PLURAL_FORMS = {}\n\n    class << self\n      def must_call_validators\n        inherited_hash_reader(\"MUST_CALL_VALIDATORS\")\n      end\n      def models\n        inherited_array_reader(\"MODELS\")\n      end\n      def get_attributes\n        inherited_array_reader(\"GET_ATTRIBUTES\")\n      end\n      def have_children_elements\n        inherited_array_reader(\"HAVE_CHILDREN_ELEMENTS\")\n      end\n      def to_element_methods\n        inherited_array_reader(\"TO_ELEMENT_METHODS\")\n      end\n      def need_initialize_variables\n        inherited_array_reader(\"NEED_INITIALIZE_VARIABLES\")\n      end\n      def plural_forms\n        inherited_hash_reader(\"PLURAL_FORMS\")\n      end\n\n      def inherited_base\n        ::RSS::Element\n      end\n\n      def inherited(klass)\n        klass.const_set(\"MUST_CALL_VALIDATORS\", {})\n        klass.const_set(\"MODELS\", [])\n        klass.const_set(\"GET_ATTRIBUTES\", [])\n        klass.const_set(\"HAVE_CHILDREN_ELEMENTS\", [])\n        klass.const_set(\"TO_ELEMENT_METHODS\", [])\n        klass.const_set(\"NEED_INITIALIZE_VARIABLES\", [])\n        klass.const_set(\"PLURAL_FORMS\", {})\n\n        tag_name = klass.name.split(/::/).last\n        tag_name[0, 1] = tag_name[0, 1].downcase\n        klass.instance_variable_set(\"@tag_name\", tag_name)\n        klass.instance_variable_set(\"@have_content\", false)\n      end\n\n      def install_must_call_validator(prefix, uri)\n        self::MUST_CALL_VALIDATORS[uri] = prefix\n      end\n\n      def install_model(tag, uri, occurs=nil, getter=nil, plural=false)\n        getter ||= tag\n        if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}\n          m[2] = occurs\n        else\n          self::MODELS << [tag, uri, occurs, getter, plural]\n        end\n      end\n\n      def install_get_attribute(name, uri, required=true,\n                                type=nil, disp_name=nil,\n                                element_name=nil)\n        disp_name ||= name\n        element_name ||= name\n        writer_type, reader_type = type\n        def_corresponded_attr_writer name, writer_type, disp_name\n        def_corresponded_attr_reader name, reader_type\n        if type == :boolean and /^is/ =~ name\n          alias_method \"#{$POSTMATCH}?\", name\n        end\n        self::GET_ATTRIBUTES << [name, uri, required, element_name]\n        add_need_initialize_variable(disp_name)\n      end\n\n      def def_corresponded_attr_writer(name, type=nil, disp_name=nil)\n        disp_name ||= name\n        case type\n        when :integer\n          integer_writer name, disp_name\n        when :positive_integer\n          positive_integer_writer name, disp_name\n        when :boolean\n          boolean_writer name, disp_name\n        when :w3cdtf, :rfc822, :rfc2822\n          date_writer name, type, disp_name\n        when :text_type\n          text_type_writer name, disp_name\n        when :content\n          content_writer name, disp_name\n        when :yes_clean_other\n          yes_clean_other_writer name, disp_name\n        when :yes_other\n          yes_other_writer name, disp_name\n        when :csv\n          csv_writer name\n        when :csv_integer\n          csv_integer_writer name\n        else\n          attr_writer name\n        end\n      end\n\n      def def_corresponded_attr_reader(name, type=nil)\n        case type\n        when :inherit\n          inherit_convert_attr_reader name\n        when :uri\n          uri_convert_attr_reader name\n        when :yes_clean_other\n          yes_clean_other_attr_reader name\n        when :yes_other\n          yes_other_attr_reader name\n        when :csv\n          csv_attr_reader name\n        when :csv_integer\n          csv_attr_reader name, :separator => \",\"\n        else\n          convert_attr_reader name\n        end\n      end\n\n      def content_setup(type=nil, disp_name=nil)\n        writer_type, reader_type = type\n        def_corresponded_attr_writer :content, writer_type, disp_name\n        def_corresponded_attr_reader :content, reader_type\n        @have_content = true\n      end\n\n      def have_content?\n        @have_content\n      end\n\n      def add_have_children_element(variable_name, plural_name)\n        self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]\n      end\n\n      def add_to_element_method(method_name)\n        self::TO_ELEMENT_METHODS << method_name\n      end\n\n      def add_need_initialize_variable(variable_name)\n        self::NEED_INITIALIZE_VARIABLES << variable_name\n      end\n\n      def add_plural_form(singular, plural)\n        self::PLURAL_FORMS[singular] = plural\n      end\n\n      def required_prefix\n        nil\n      end\n\n      def required_uri\n        \"\"\n      end\n\n      def need_parent?\n        false\n      end\n\n      def install_ns(prefix, uri)\n        if self::NSPOOL.has_key?(prefix)\n          raise OverlappedPrefixError.new(prefix)\n        end\n        self::NSPOOL[prefix] = uri\n      end\n\n      def tag_name\n        @tag_name\n      end\n    end\n\n    attr_accessor :parent, :do_validate\n\n    def initialize(do_validate=true, attrs=nil)\n      @parent = nil\n      @converter = nil\n      if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))\n        do_validate, attrs = true, do_validate\n      end\n      @do_validate = do_validate\n      initialize_variables(attrs || {})\n    end\n\n    def tag_name\n      self.class.tag_name\n    end\n\n    def full_name\n      tag_name\n    end\n    \n    def converter=(converter)\n      @converter = converter\n      targets = children.dup\n      self.class.have_children_elements.each do |variable_name, plural_name|\n        targets.concat(__send__(plural_name))\n      end\n      targets.each do |target|\n        target.converter = converter unless target.nil?\n      end\n    end\n\n    def convert(value)\n      if @converter\n        @converter.convert(value)\n      else\n        value\n      end\n    end\n\n    def valid?(ignore_unknown_element=true)\n      validate(ignore_unknown_element)\n      true\n    rescue RSS::Error\n      false\n    end\n\n    def validate(ignore_unknown_element=true)\n      do_validate = @do_validate\n      @do_validate = true\n      validate_attribute\n      __validate(ignore_unknown_element)\n    ensure\n      @do_validate = do_validate\n    end\n    \n    def validate_for_stream(tags, ignore_unknown_element=true)\n      validate_attribute\n      __validate(ignore_unknown_element, tags, false)\n    end\n\n    def to_s(need_convert=true, indent='')\n      if self.class.have_content?\n        return \"\" if !empty_content? and !content_is_set?\n        rv = tag(indent) do |next_indent|\n          if empty_content?\n            \"\"\n          else\n            xmled_content\n          end\n        end\n      else\n        rv = tag(indent) do |next_indent|\n          self.class.to_element_methods.collect do |method_name|\n            __send__(method_name, false, next_indent)\n          end\n        end\n      end\n      rv = convert(rv) if need_convert\n      rv\n    end\n\n    def have_xml_content?\n      false\n    end\n\n    def need_base64_encode?\n      false\n    end\n\n    def set_next_element(tag_name, next_element)\n      klass = next_element.class\n      prefix = \"\"\n      prefix << \"#{klass.required_prefix}_\" if klass.required_prefix\n      key = \"#{prefix}#{tag_name.gsub(/-/, '_')}\"\n      if self.class.plural_forms.has_key?(key)\n        ary = __send__(\"#{self.class.plural_forms[key]}\")\n        ary << next_element\n      else\n        __send__(\"#{key}=\", next_element)\n      end\n    end\n\n    protected\n    def have_required_elements?\n      self.class::MODELS.all? do |tag, uri, occurs, getter|\n        if occurs.nil? or occurs == \"+\"\n          child = __send__(getter)\n          if child.is_a?(Array)\n            children = child\n            children.any? {|c| c.have_required_elements?}\n          else\n            !child.to_s.empty?\n          end\n        else\n          true\n        end\n      end\n    end\n\n    private\n    def initialize_variables(attrs)\n      normalized_attrs = {}\n      attrs.each do |key, value|\n        normalized_attrs[key.to_s] = value\n      end\n      self.class.need_initialize_variables.each do |variable_name|\n        value = normalized_attrs[variable_name.to_s]\n        if value\n          __send__(\"#{variable_name}=\", value)\n        else\n          instance_variable_set(\"@#{variable_name}\", nil)\n        end\n      end\n      initialize_have_children_elements\n      @content = normalized_attrs[\"content\"] if self.class.have_content?\n    end\n\n    def initialize_have_children_elements\n      self.class.have_children_elements.each do |variable_name, plural_name|\n        instance_variable_set(\"@#{variable_name}\", [])\n      end\n    end\n\n    def tag(indent, additional_attrs={}, &block)\n      next_indent = indent + INDENT\n\n      attrs = collect_attrs\n      return \"\" if attrs.nil?\n\n      return \"\" unless have_required_elements?\n\n      attrs.update(additional_attrs)\n      start_tag = make_start_tag(indent, next_indent, attrs.dup)\n\n      if block\n        content = block.call(next_indent)\n      else\n        content = []\n      end\n\n      if content.is_a?(String)\n        content = [content]\n        start_tag << \">\"\n        end_tag = \"</#{full_name}>\"\n      else\n        content = content.reject{|x| x.empty?}\n        if content.empty?\n          return \"\" if attrs.empty?\n          end_tag = \"/>\"\n        else\n          start_tag << \">\\n\"\n          end_tag = \"\\n#{indent}</#{full_name}>\"\n        end\n      end\n      \n      start_tag + content.join(\"\\n\") + end_tag\n    end\n\n    def make_start_tag(indent, next_indent, attrs)\n      start_tag = [\"#{indent}<#{full_name}\"]\n      unless attrs.empty?\n        start_tag << attrs.collect do |key, value|\n          %Q[#{h key}=\"#{h value}\"]\n        end.join(\"\\n#{next_indent}\")\n      end\n      start_tag.join(\" \")\n    end\n\n    def collect_attrs\n      attrs = {}\n      _attrs.each do |name, required, alias_name|\n        value = __send__(alias_name || name)\n        return nil if required and value.nil?\n        next if value.nil?\n        return nil if attrs.has_key?(name)\n        attrs[name] = value\n      end\n      attrs\n    end\n    \n    def tag_name_with_prefix(prefix)\n      \"#{prefix}:#{tag_name}\"\n    end\n\n    # For backward compatibility\n    def calc_indent\n      ''\n    end\n\n    def children\n      rv = []\n      self.class.models.each do |name, uri, occurs, getter|\n        value = __send__(getter)\n        next if value.nil?\n        value = [value] unless value.is_a?(Array)\n        value.each do |v|\n          rv << v if v.is_a?(Element)\n        end\n      end\n      rv\n    end\n\n    def _tags\n      rv = []\n      self.class.models.each do |name, uri, occurs, getter, plural|\n        value = __send__(getter)\n        next if value.nil?\n        if plural and value.is_a?(Array)\n          rv.concat([[uri, name]] * value.size)\n        else\n          rv << [uri, name]\n        end\n      end\n      rv\n    end\n\n    def _attrs\n      self.class.get_attributes.collect do |name, uri, required, element_name|\n        [element_name, required, name]\n      end\n    end\n\n    def __validate(ignore_unknown_element, tags=_tags, recursive=true)\n      if recursive\n        children.compact.each do |child|\n          child.validate\n        end\n      end\n      must_call_validators = self.class.must_call_validators\n      tags = tag_filter(tags.dup)\n      p tags if DEBUG\n      must_call_validators.each do |uri, prefix|\n        _validate(ignore_unknown_element, tags[uri], uri)\n        meth = \"#{prefix}_validate\"\n        if !prefix.empty? and respond_to?(meth, true)\n          __send__(meth, ignore_unknown_element, tags[uri], uri)\n        end\n      end\n    end\n\n    def validate_attribute\n      _attrs.each do |a_name, required, alias_name|\n        value = instance_variable_get(\"@#{alias_name || a_name}\")\n        if required and value.nil?\n          raise MissingAttributeError.new(tag_name, a_name)\n        end\n        __send__(\"#{alias_name || a_name}=\", value)\n      end\n    end\n\n    def _validate(ignore_unknown_element, tags, uri, models=self.class.models)\n      count = 1\n      do_redo = false\n      not_shift = false\n      tag = nil\n      models = models.find_all {|model| model[1] == uri}\n      element_names = models.collect {|model| model[0]}\n      if tags\n        tags_size = tags.size\n        tags = tags.sort_by {|x| element_names.index(x) || tags_size}\n      end\n\n      _tags = tags.dup if tags\n      models.each_with_index do |model, i|\n        name, model_uri, occurs, getter = model\n\n        if DEBUG\n          p \"before\"\n          p tags\n          p model\n        end\n\n        if not_shift\n          not_shift = false\n        elsif tags\n          tag = tags.shift\n        end\n\n        if DEBUG\n          p \"mid\"\n          p count\n        end\n\n        case occurs\n        when '?'\n          if count > 2\n            raise TooMuchTagError.new(name, tag_name)\n          else\n            if name == tag\n              do_redo = true\n            else\n              not_shift = true\n            end\n          end\n        when '*'\n          if name == tag\n            do_redo = true\n          else\n            not_shift = true\n          end\n        when '+'\n          if name == tag\n            do_redo = true\n          else\n            if count > 1\n              not_shift = true\n            else\n              raise MissingTagError.new(name, tag_name)\n            end\n          end\n        else\n          if name == tag\n            if models[i+1] and models[i+1][0] != name and\n                tags and tags.first == name\n              raise TooMuchTagError.new(name, tag_name)\n            end\n          else\n            raise MissingTagError.new(name, tag_name)\n          end\n        end\n\n        if DEBUG\n          p \"after\"\n          p not_shift\n          p do_redo\n          p tag\n        end\n\n        if do_redo\n          do_redo = false\n          count += 1\n          redo\n        else\n          count = 1\n        end\n\n      end\n\n      if !ignore_unknown_element and !tags.nil? and !tags.empty?\n        raise NotExpectedTagError.new(tags.first, uri, tag_name)\n      end\n\n    end\n\n    def tag_filter(tags)\n      rv = {}\n      tags.each do |tag|\n        rv[tag[0]] = [] unless rv.has_key?(tag[0])\n        rv[tag[0]].push(tag[1])\n      end\n      rv\n    end\n\n    def empty_content?\n      false\n    end\n\n    def content_is_set?\n      if have_xml_content?\n        __send__(self.class.xml_getter)\n      else\n        content\n      end\n    end\n\n    def xmled_content\n      if have_xml_content?\n        __send__(self.class.xml_getter).to_s\n      else\n        _content = content\n        _content = Base64.encode64(_content) if need_base64_encode?\n        h(_content)\n      end\n    end\n  end\n\n  module RootElementMixin\n\n    include XMLStyleSheetMixin\n    \n    attr_reader :output_encoding\n    attr_reader :feed_type, :feed_subtype, :feed_version\n    attr_accessor :version, :encoding, :standalone\n    def initialize(feed_version, version=nil, encoding=nil, standalone=nil)\n      super()\n      @feed_type = nil\n      @feed_subtype = nil\n      @feed_version = feed_version\n      @version = version || '1.0'\n      @encoding = encoding\n      @standalone = standalone\n      @output_encoding = nil\n    end\n\n    def feed_info\n      [@feed_type, @feed_version, @feed_subtype]\n    end\n\n    def output_encoding=(enc)\n      @output_encoding = enc\n      self.converter = Converter.new(@output_encoding, @encoding)\n    end\n\n    def setup_maker(maker)\n      maker.version = version\n      maker.encoding = encoding\n      maker.standalone = standalone\n\n      xml_stylesheets.each do |xss|\n        xss.setup_maker(maker)\n      end\n\n      super\n    end\n\n    def to_feed(type, &block)\n      Maker.make(type) do |maker|\n        setup_maker(maker)\n        block.call(maker) if block\n      end\n    end\n\n    def to_rss(type, &block)\n      to_feed(\"rss#{type}\", &block)\n    end\n\n    def to_atom(type, &block)\n      to_feed(\"atom:#{type}\", &block)\n    end\n\n    def to_xml(type=nil, &block)\n      if type.nil? or same_feed_type?(type)\n        to_s\n      else\n        to_feed(type, &block).to_s\n      end\n    end\n\n    private\n    def same_feed_type?(type)\n      if /^(atom|rss)?(\\d+\\.\\d+)?(?::(.+))?$/i =~ type\n        feed_type = ($1 || @feed_type).downcase\n        feed_version = $2 || @feed_version\n        feed_subtype = $3 || @feed_subtype\n        [feed_type, feed_version, feed_subtype] == feed_info\n      else\n        false\n      end\n    end\n\n    def tag(indent, attrs={}, &block)\n      rv = super(indent, ns_declarations.merge(attrs), &block)\n      return rv if rv.empty?\n      \"#{xmldecl}#{xml_stylesheet_pi}#{rv}\"\n    end\n\n    def xmldecl\n      rv = %Q[<?xml version=\"#{@version}\"]\n      if @output_encoding or @encoding\n        rv << %Q[ encoding=\"#{@output_encoding or @encoding}\"]\n      end\n      rv << %Q[ standalone=\"yes\"] if @standalone\n      rv << \"?>\\n\"\n      rv\n    end\n    \n    def ns_declarations\n      decls = {}\n      self.class::NSPOOL.collect do |prefix, uri|\n        prefix = \":#{prefix}\" unless prefix.empty?\n        decls[\"xmlns#{prefix}\"] = uri\n      end\n      decls\n    end\n\n    def maker_target(target)\n      target\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/slash.rb",
    "content": "require 'rss/1.0'\n\nmodule RSS\n  SLASH_PREFIX = 'slash'\n  SLASH_URI = \"http://purl.org/rss/1.0/modules/slash/\"\n\n  RDF.install_ns(SLASH_PREFIX, SLASH_URI)\n\n  module SlashModel\n    extend BaseModel\n\n    ELEMENT_INFOS = \\\n    [\n     [\"section\"],\n     [\"department\"],\n     [\"comments\", :positive_integer],\n     [\"hit_parade\", :csv_integer],\n    ]\n\n    class << self\n      def append_features(klass)\n        super\n\n        return if klass.instance_of?(Module)\n        klass.install_must_call_validator(SLASH_PREFIX, SLASH_URI)\n        ELEMENT_INFOS.each do |name, type, *additional_infos|\n          full_name = \"#{SLASH_PREFIX}_#{name}\"\n          klass.install_text_element(full_name, SLASH_URI, \"?\",\n                                     full_name, type, name)\n        end\n\n        klass.module_eval do\n          alias_method(:slash_hit_parades, :slash_hit_parade)\n          undef_method(:slash_hit_parade)\n          alias_method(:slash_hit_parade, :slash_hit_parade_content)\n        end\n      end\n    end\n  end\n\n  class RDF\n    class Item; include SlashModel; end\n  end\n\n  SlashModel::ELEMENT_INFOS.each do |name, type|\n    accessor_base = \"#{SLASH_PREFIX}_#{name}\"\n    BaseListener.install_get_text_element(SLASH_URI, name, accessor_base)\n  end\nend\n"
  },
  {
    "path": "lib/rss/syndication.rb",
    "content": "require \"rss/1.0\"\n\nmodule RSS\n\n  SY_PREFIX = 'sy'\n  SY_URI = \"http://purl.org/rss/1.0/modules/syndication/\"\n\n  RDF.install_ns(SY_PREFIX, SY_URI)\n\n  module SyndicationModel\n    \n    extend BaseModel\n    \n    ELEMENTS = []\n    \n    def self.append_features(klass)\n      super\n\n      klass.install_must_call_validator(SY_PREFIX, SY_URI)\n      klass.module_eval do\n        [\n          [\"updatePeriod\"],\n          [\"updateFrequency\", :positive_integer]\n        ].each do |name, type|\n          install_text_element(name, SY_URI, \"?\",\n                               \"#{SY_PREFIX}_#{name}\", type,\n                               \"#{SY_PREFIX}:#{name}\")\n        end\n\n        %w(updateBase).each do |name|\n          install_date_element(name, SY_URI, \"?\",\n                               \"#{SY_PREFIX}_#{name}\", 'w3cdtf',\n                               \"#{SY_PREFIX}:#{name}\")\n        end\n      end\n\n      klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)\n        alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)\n        def sy_updatePeriod=(new_value)\n          new_value = new_value.strip\n          validate_sy_updatePeriod(new_value) if @do_validate\n          self._sy_updatePeriod = new_value\n        end\n      EOC\n    end\n\n    private\n    SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly)\n    def validate_sy_updatePeriod(value)\n      unless SY_UPDATEPERIOD_AVAILABLE_VALUES.include?(value)\n        raise NotAvailableValueError.new(\"updatePeriod\", value)\n      end\n    end\n  end\n\n  class RDF\n    class Channel; include SyndicationModel; end\n  end\n\n  prefix_size = SY_PREFIX.size + 1\n  SyndicationModel::ELEMENTS.uniq!\n  SyndicationModel::ELEMENTS.each do |full_name|\n    name = full_name[prefix_size..-1]\n    BaseListener.install_get_text_element(SY_URI, name, full_name)\n  end\n\nend\n"
  },
  {
    "path": "lib/rss/taxonomy.rb",
    "content": "require \"rss/1.0\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n\n  TAXO_PREFIX = \"taxo\"\n  TAXO_URI = \"http://purl.org/rss/1.0/modules/taxonomy/\"\n\n  RDF.install_ns(TAXO_PREFIX, TAXO_URI)\n\n  TAXO_ELEMENTS = []\n\n  %w(link).each do |name|\n    full_name = \"#{TAXO_PREFIX}_#{name}\"\n    BaseListener.install_get_text_element(TAXO_URI, name, full_name)\n    TAXO_ELEMENTS << \"#{TAXO_PREFIX}_#{name}\"\n  end\n\n  %w(topic topics).each do |name|\n    class_name = Utils.to_class_name(name)\n    BaseListener.install_class_name(TAXO_URI, name, \"Taxonomy#{class_name}\")\n    TAXO_ELEMENTS << \"#{TAXO_PREFIX}_#{name}\"\n  end\n\n  module TaxonomyTopicsModel\n    extend BaseModel\n    \n    def self.append_features(klass)\n      super\n\n      klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI)\n      %w(topics).each do |name|\n        klass.install_have_child_element(name, TAXO_URI, \"?\",\n                                         \"#{TAXO_PREFIX}_#{name}\")\n      end\n    end\n\n    class TaxonomyTopics < Element\n      include RSS10\n      \n      Bag = ::RSS::RDF::Bag\n\n      class << self\n        def required_prefix\n          TAXO_PREFIX\n        end\n        \n        def required_uri\n          TAXO_URI\n        end\n      end\n\n      @tag_name = \"topics\"\n      \n      install_have_child_element(\"Bag\", RDF::URI, nil)\n      install_must_call_validator('rdf', RDF::URI)\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.Bag = args[0]\n        end\n        self.Bag ||= Bag.new\n      end\n\n      def full_name\n        tag_name_with_prefix(TAXO_PREFIX)\n      end\n\n      def maker_target(target)\n        target.taxo_topics\n      end\n\n      def resources\n        if @Bag\n          @Bag.lis.collect do |li|\n            li.resource\n          end\n        else\n          []\n        end\n      end\n    end\n  end\n  \n  module TaxonomyTopicModel\n    extend BaseModel\n    \n    def self.append_features(klass)\n      super\n      var_name = \"#{TAXO_PREFIX}_topic\"\n      klass.install_have_children_element(\"topic\", TAXO_URI, \"*\", var_name)\n    end\n\n    class TaxonomyTopic < Element\n      include RSS10\n\n      include DublinCoreModel\n      include TaxonomyTopicsModel\n      \n      class << self\n        def required_prefix\n          TAXO_PREFIX\n        end\n        \n        def required_uri\n          TAXO_URI\n        end\n      end\n\n      @tag_name = \"topic\"\n\n      install_get_attribute(\"about\", ::RSS::RDF::URI, true, nil, nil,\n                            \"#{RDF::PREFIX}:about\")\n      install_text_element(\"link\", TAXO_URI, \"?\", \"#{TAXO_PREFIX}_link\")\n        \n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.about = args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(TAXO_PREFIX)\n      end\n\n      def maker_target(target)\n        target.new_taxo_topic\n      end\n    end\n  end\n\n  class RDF\n    include TaxonomyTopicModel\n    class Channel\n      include TaxonomyTopicsModel\n    end\n    class Item; include TaxonomyTopicsModel; end\n  end\nend\n"
  },
  {
    "path": "lib/rss/trackback.rb",
    "content": "require 'rss/1.0'\nrequire 'rss/2.0'\n\nmodule RSS\n\n  TRACKBACK_PREFIX = 'trackback'\n  TRACKBACK_URI = 'http://madskills.com/public/xml/rss/module/trackback/'\n\n  RDF.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)\n  Rss.install_ns(TRACKBACK_PREFIX, TRACKBACK_URI)\n\n  module TrackBackUtils\n    private\n    def trackback_validate(ignore_unknown_element, tags, uri)\n      return if tags.nil?\n      if tags.find {|tag| tag == \"about\"} and\n          !tags.find {|tag| tag == \"ping\"}\n        raise MissingTagError.new(\"#{TRACKBACK_PREFIX}:ping\", tag_name)\n      end\n    end\n  end\n\n  module BaseTrackBackModel\n\n    ELEMENTS = %w(ping about)\n    \n    def append_features(klass)\n      super\n\n      unless klass.class == Module\n        klass.module_eval {include TrackBackUtils}\n\n        klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI)\n        %w(ping).each do |name|\n          var_name = \"#{TRACKBACK_PREFIX}_#{name}\"\n          klass_name = \"TrackBack#{Utils.to_class_name(name)}\"\n          klass.install_have_child_element(name, TRACKBACK_URI, \"?\", var_name)\n          klass.module_eval(<<-EOC, __FILE__, __LINE__)\n            remove_method :#{var_name}\n            def #{var_name}\n              @#{var_name} and @#{var_name}.value\n            end\n\n            remove_method :#{var_name}=\n            def #{var_name}=(value)\n              @#{var_name} = Utils.new_with_value_if_need(#{klass_name}, value)\n            end\n          EOC\n        end\n        \n        [%w(about s)].each do |name, postfix|\n          var_name = \"#{TRACKBACK_PREFIX}_#{name}\"\n          klass_name = \"TrackBack#{Utils.to_class_name(name)}\"\n          klass.install_have_children_element(name, TRACKBACK_URI, \"*\",\n                                              var_name)\n          klass.module_eval(<<-EOC, __FILE__, __LINE__)\n            remove_method :#{var_name}\n            def #{var_name}(*args)\n              if args.empty?\n                @#{var_name}.first and @#{var_name}.first.value\n              else\n                ret = @#{var_name}.__send__(\"[]\", *args)\n                if ret.is_a?(Array)\n                  ret.collect {|x| x.value}\n                else\n                  ret.value\n                end\n              end\n            end\n\n            remove_method :#{var_name}=\n            remove_method :set_#{var_name}\n            def #{var_name}=(*args)\n              if args.size == 1\n                item = Utils.new_with_value_if_need(#{klass_name}, args[0])\n                @#{var_name}.push(item)\n              else\n                new_val = args.last\n                if new_val.is_a?(Array)\n                  new_val = new_value.collect do |val|\n                    Utils.new_with_value_if_need(#{klass_name}, val)\n                  end\n                else\n                  new_val = Utils.new_with_value_if_need(#{klass_name}, new_val)\n                end\n                @#{var_name}.__send__(\"[]=\", *(args[0..-2] + [new_val]))\n              end\n            end\n            alias set_#{var_name} #{var_name}=\n          EOC\n        end\n      end\n    end\n  end\n\n  module TrackBackModel10\n    extend BaseModel\n    extend BaseTrackBackModel\n\n    class TrackBackPing < Element\n      include RSS10\n\n      class << self\n\n        def required_prefix\n          TRACKBACK_PREFIX\n        end\n        \n        def required_uri\n          TRACKBACK_URI\n        end\n\n      end\n\n      @tag_name = \"ping\"\n\n      [\n        [\"resource\", ::RSS::RDF::URI, true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{::RSS::RDF::PREFIX}:#{name}\")\n      end\n\n      alias_method(:value, :resource)\n      alias_method(:value=, :resource=)\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.resource = args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(TRACKBACK_PREFIX)\n      end\n    end\n\n    class TrackBackAbout < Element\n      include RSS10\n\n      class << self\n        \n        def required_prefix\n          TRACKBACK_PREFIX\n        end\n        \n        def required_uri\n          TRACKBACK_URI\n        end\n\n      end\n      \n      @tag_name = \"about\"\n\n      [\n        [\"resource\", ::RSS::RDF::URI, true]\n      ].each do |name, uri, required|\n        install_get_attribute(name, uri, required, nil, nil,\n                              \"#{::RSS::RDF::PREFIX}:#{name}\")\n      end\n\n      alias_method(:value, :resource)\n      alias_method(:value=, :resource=)\n      \n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.resource = args[0]\n        end\n      end\n\n      def full_name\n        tag_name_with_prefix(TRACKBACK_PREFIX)\n      end\n\n      private\n      def maker_target(abouts)\n        abouts.new_about\n      end\n\n      def setup_maker_attributes(about)\n        about.resource = self.resource\n      end\n      \n    end\n  end\n\n  module TrackBackModel20\n    extend BaseModel\n    extend BaseTrackBackModel\n\n    class TrackBackPing < Element\n      include RSS09\n\n      @tag_name = \"ping\"\n      \n      content_setup\n\n      class << self\n\n        def required_prefix\n          TRACKBACK_PREFIX\n        end\n        \n        def required_uri\n          TRACKBACK_URI\n        end\n\n      end\n      \n      alias_method(:value, :content)\n      alias_method(:value=, :content=)\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.content = args[0]\n        end\n      end\n      \n      def full_name\n        tag_name_with_prefix(TRACKBACK_PREFIX)\n      end\n      \n    end\n\n    class TrackBackAbout < Element\n      include RSS09\n\n      @tag_name = \"about\"\n      \n      content_setup\n\n      class << self\n        \n        def required_prefix\n          TRACKBACK_PREFIX\n        end\n        \n        def required_uri\n          TRACKBACK_URI\n        end\n\n      end\n\n      alias_method(:value, :content)\n      alias_method(:value=, :content=)\n\n      def initialize(*args)\n        if Utils.element_initialize_arguments?(args)\n          super\n        else\n          super()\n          self.content = args[0]\n        end\n      end\n      \n      def full_name\n        tag_name_with_prefix(TRACKBACK_PREFIX)\n      end\n      \n    end\n  end\n\n  class RDF\n    class Item; include TrackBackModel10; end\n  end\n\n  class Rss\n    class Channel\n      class Item; include TrackBackModel20; end\n    end\n  end\n\n  BaseTrackBackModel::ELEMENTS.each do |name|\n    class_name = Utils.to_class_name(name)\n    BaseListener.install_class_name(TRACKBACK_URI, name,\n                                    \"TrackBack#{class_name}\")\n  end\n\n  BaseTrackBackModel::ELEMENTS.collect! {|name| \"#{TRACKBACK_PREFIX}_#{name}\"}\nend\n"
  },
  {
    "path": "lib/rss/utils.rb",
    "content": "module RSS\n  module Utils\n    module_function\n\n    # Convert a name_with_underscores to CamelCase.\n    def to_class_name(name)\n      name.split(/[_\\-]/).collect do |part|\n        \"#{part[0, 1].upcase}#{part[1..-1]}\"\n      end.join(\"\")\n    end\n    \n    def get_file_and_line_from_caller(i=0)\n      file, line, = caller[i].split(':')\n      line = line.to_i\n      line += 1 if i.zero?\n      [file, line]\n    end\n\n    # escape '&', '\"', '<' and '>' for use in HTML.\n    def html_escape(s)\n      s.to_s.gsub(/&/, \"&amp;\").gsub(/\\\"/, \"&quot;\").gsub(/>/, \"&gt;\").gsub(/</, \"&lt;\")\n    end\n    alias h html_escape\n    \n    # If +value+ is an instance of class +klass+, return it, else\n    # create a new instance of +klass+ with value +value+.\n    def new_with_value_if_need(klass, value)\n      if value.is_a?(klass)\n        value\n      else\n        klass.new(value)\n      end\n    end\n\n    def element_initialize_arguments?(args)\n      [true, false].include?(args[0]) and args[1].is_a?(Hash)\n    end\n\n    module YesCleanOther\n      module_function\n      def parse(value)\n        if [true, false, nil].include?(value)\n          value\n        else\n          case value.to_s\n          when /\\Ayes\\z/i\n            true\n          when /\\Aclean\\z/i\n            false\n          else\n            nil\n          end\n        end\n      end\n    end\n\n    module YesOther\n      module_function\n      def parse(value)\n        if [true, false].include?(value)\n          value\n        else\n          /\\Ayes\\z/i.match(value.to_s) ? true : false\n        end\n      end\n    end\n\n    module CSV\n      module_function\n      def parse(value, &block)\n        if value.is_a?(String)\n          value = value.strip.split(/\\s*,\\s*/)\n          value = value.collect(&block) if block_given?\n          value\n        else\n          value\n        end\n      end\n    end\n\n    module InheritedReader\n      def inherited_reader(constant_name)\n        base_class = inherited_base\n        result = base_class.const_get(constant_name)\n        found_base_class = false\n        ancestors.reverse_each do |klass|\n          if found_base_class\n            if klass.const_defined?(constant_name)\n              result = yield(result, klass.const_get(constant_name))\n            end\n          else\n            found_base_class = klass == base_class\n          end\n        end\n        result\n      end\n\n      def inherited_array_reader(constant_name)\n        inherited_reader(constant_name) do |result, current|\n          current + result\n        end\n      end\n\n      def inherited_hash_reader(constant_name)\n        inherited_reader(constant_name) do |result, current|\n          result.merge(current)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/xml-stylesheet.rb",
    "content": "require \"rss/utils\"\n\nmodule RSS\n\n  module XMLStyleSheetMixin\n    attr_accessor :xml_stylesheets\n    def initialize(*args)\n      super\n      @xml_stylesheets = []\n    end\n    \n    private\n    def xml_stylesheet_pi\n      xsss = @xml_stylesheets.collect do |xss|\n        pi = xss.to_s\n        pi = nil if /\\A\\s*\\z/ =~ pi\n        pi\n      end.compact\n      xsss.push(\"\") unless xsss.empty?\n      xsss.join(\"\\n\")\n    end\n  end\n\n  class XMLStyleSheet\n\n    include Utils\n\n    ATTRIBUTES = %w(href type title media charset alternate)\n\n    GUESS_TABLE = {\n      \"xsl\" => \"text/xsl\",\n      \"css\" => \"text/css\",\n    }\n\n    attr_accessor(*ATTRIBUTES)\n    attr_accessor(:do_validate)\n    def initialize(*attrs)\n      if attrs.size == 1 and\n          (attrs.first.is_a?(Hash) or attrs.first.is_a?(Array))\n        attrs = attrs.first\n      end\n      @do_validate = true\n      ATTRIBUTES.each do |attr|\n        __send__(\"#{attr}=\", nil)\n      end\n      vars = ATTRIBUTES.dup\n      vars.unshift(:do_validate)\n      attrs.each do |name, value|\n        if vars.include?(name.to_s)\n          __send__(\"#{name}=\", value)\n        end\n      end\n    end\n\n    def to_s\n      rv = \"\"\n      if @href\n        rv << %Q[<?xml-stylesheet]\n        ATTRIBUTES.each do |name|\n          if __send__(name)\n            rv << %Q[ #{name}=\"#{h __send__(name)}\"]\n          end\n        end\n        rv << %Q[?>]\n      end\n      rv\n    end\n\n    remove_method(:href=)\n    def href=(value)\n      @href = value\n      if @href and @type.nil?\n        @type = guess_type(@href)\n      end\n      @href\n    end\n\n    remove_method(:alternate=)\n    def alternate=(value)\n      if value.nil? or /\\A(?:yes|no)\\z/ =~ value\n        @alternate = value\n      else\n        if @do_validate\n          args = [\"?xml-stylesheet?\", %Q[alternate=\"#{value}\"]]\n          raise NotAvailableValueError.new(*args)\n        end\n      end\n      @alternate\n    end\n\n    def setup_maker(maker)\n      xss = maker.xml_stylesheets.new_xml_stylesheet\n      ATTRIBUTES.each do |attr|\n        xss.__send__(\"#{attr}=\", __send__(attr))\n      end\n    end\n    \n    private\n    def guess_type(filename)\n      /\\.([^.]+)$/ =~ filename\n      GUESS_TABLE[$1]\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/rss/xml.rb",
    "content": "require \"rss/utils\"\n\nmodule RSS\n  module XML\n    class Element\n      include Enumerable\n\n      attr_reader :name, :prefix, :uri, :attributes, :children\n      def initialize(name, prefix=nil, uri=nil, attributes={}, children=[])\n        @name = name\n        @prefix = prefix\n        @uri = uri\n        @attributes = attributes\n        if children.is_a?(String) or !children.respond_to?(:each)\n          @children = [children]\n        else\n          @children = children\n        end\n      end\n\n      def [](name)\n        @attributes[name]\n      end\n\n      def []=(name, value)\n        @attributes[name] = value\n      end\n\n      def <<(child)\n        @children << child\n      end\n\n      def each(&block)\n        @children.each(&block)\n      end\n\n      def ==(other)\n        other.kind_of?(self.class) and\n          @name == other.name and\n          @uri == other.uri and\n          @attributes == other.attributes and\n          @children == other.children\n      end\n\n      def to_s\n        rv = \"<#{full_name}\"\n        attributes.each do |key, value|\n          rv << \" #{Utils.html_escape(key)}=\\\"#{Utils.html_escape(value)}\\\"\"\n        end\n        if children.empty?\n          rv << \"/>\"\n        else\n          rv << \">\"\n          children.each do |child|\n            rv << child.to_s\n          end\n          rv << \"</#{full_name}>\"\n        end\n        rv\n      end\n\n      def full_name\n        if @prefix\n          \"#{@prefix}:#{@name}\"\n        else\n          @name\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/rss/xmlparser.rb",
    "content": "begin\n  require \"xml/parser\"\nrescue LoadError\n  require \"xmlparser\"\nend\n\nbegin\n  require \"xml/encoding-ja\"\nrescue LoadError\n  require \"xmlencoding-ja\"\n  if defined?(Kconv)\n    module XMLEncoding_ja\n      class SJISHandler\n        include Kconv\n      end\n    end\n  end\nend\n\nmodule XML\n  class Parser\n    unless defined?(Error)\n      Error = ::XMLParserError\n    end\n  end\nend\n\nmodule RSS\n  \n  class REXMLLikeXMLParser < ::XML::Parser\n    \n    include ::XML::Encoding_ja\n\n    def listener=(listener)\n      @listener = listener\n    end\n\n    def startElement(name, attrs)\n      @listener.tag_start(name, attrs)\n    end\n    \n    def endElement(name)\n      @listener.tag_end(name)\n    end\n\n    def character(data)\n      @listener.text(data)\n    end\n\n    def xmlDecl(version, encoding, standalone)\n      @listener.xmldecl(version, encoding, standalone == 1)\n    end\n\n    def processingInstruction(target, content)\n      @listener.instruction(target, content)\n    end\n\n  end\n\n  class XMLParserParser < BaseParser\n\n    class << self\n      def listener\n        XMLParserListener\n      end\n    end\n    \n    private\n    def _parse\n      begin\n        parser = REXMLLikeXMLParser.new\n        parser.listener = @listener\n        parser.parse(@rss)\n      rescue ::XML::Parser::Error => e\n        raise NotWellFormedError.new(parser.line){e.message}\n      end\n    end\n    \n  end\n  \n  class XMLParserListener < BaseListener\n\n    include ListenerMixin\n    \n    def xmldecl(version, encoding, standalone)\n      super\n      # Encoding is converted to UTF-8 when XMLParser parses XML.\n      @encoding = 'UTF-8'\n    end\n\n  end\n\nend\n"
  },
  {
    "path": "lib/rss/xmlscanner.rb",
    "content": "require 'xmlscan/scanner'\nrequire 'stringio'\n\nmodule RSS\n  \n  class XMLScanParser < BaseParser\n    \n    class << self\n      def listener\n        XMLScanListener\n      end\n    end\n    \n    private\n    def _parse\n      begin\n        if @rss.is_a?(String)\n          input = StringIO.new(@rss)\n        else\n          input = @rss\n        end\n        scanner = XMLScan::XMLScanner.new(@listener)\n        scanner.parse(input)\n      rescue XMLScan::Error => e\n        lineno = e.lineno || scanner.lineno || input.lineno\n        raise NotWellFormedError.new(lineno){e.message}\n      end\n    end\n    \n  end\n\n  class XMLScanListener < BaseListener\n    \n    include XMLScan::Visitor\n    include ListenerMixin\n\n    ENTITIES = {\n      'lt' => '<',\n      'gt' => '>',\n      'amp' => '&',\n      'quot' => '\"',\n      'apos' => '\\''\n    }\n\n    def on_xmldecl_version(str)\n      @version = str\n    end\n\n    def on_xmldecl_encoding(str)\n      @encoding = str\n    end\n\n    def on_xmldecl_standalone(str)\n      @standalone = str\n    end\n\n    def on_xmldecl_end\n      xmldecl(@version, @encoding, @standalone == \"yes\")\n    end\n\n    alias_method(:on_pi, :instruction)\n    alias_method(:on_chardata, :text)\n    alias_method(:on_cdata, :text)\n\n    def on_etag(name)\n      tag_end(name)\n    end\n\n    def on_entityref(ref)\n      text(entity(ref))\n    end\n\n    def on_charref(code)\n      text([code].pack('U'))\n    end\n\n    alias_method(:on_charref_hex, :on_charref)\n\n    def on_stag(name)\n      @attrs = {}\n    end\n\n    def on_attribute(name)\n      @attrs[name] = @current_attr = ''\n    end\n\n    def on_attr_value(str)\n      @current_attr << str\n    end\n\n    def on_attr_entityref(ref)\n      @current_attr << entity(ref)\n    end\n\n    def on_attr_charref(code)\n      @current_attr << [code].pack('U')\n    end\n\n    alias_method(:on_attr_charref_hex, :on_attr_charref)\n\n    def on_stag_end(name)\n      tag_start(name, @attrs)\n    end\n\n    def on_stag_end_empty(name)\n      tag_start(name, @attrs)\n      tag_end(name)\n    end\n\n    private\n    def entity(ref)\n      ent = ENTITIES[ref]\n      if ent\n        ent\n      else\n        wellformed_error(\"undefined entity: #{ref}\")\n      end\n    end\n  end\n\nend\n"
  },
  {
    "path": "lib/rss.rb",
    "content": "# Copyright (c) 2003-2007 Kouhei Sutou.  You can redistribute it and/or\n# modify it under the same terms as Ruby.\n#\n# Author:: Kouhei Sutou <kou@cozmixng.org>\n# Tutorial:: http://www.cozmixng.org/~rwiki/?cmd=view;name=RSS+Parser%3A%3ATutorial.en\n\nrequire 'rss/1.0'\nrequire 'rss/2.0'\nrequire 'rss/atom'\nrequire 'rss/content'\nrequire 'rss/dublincore'\nrequire 'rss/image'\nrequire 'rss/itunes'\nrequire 'rss/slash'\nrequire 'rss/syndication'\nrequire 'rss/taxonomy'\nrequire 'rss/trackback'\n\nrequire \"rss/maker\"\n"
  },
  {
    "path": "lib/rubyunit.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'runit/testcase'\nrequire 'test/unit'\n"
  },
  {
    "path": "lib/runit/assert.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/assertions'\nrequire 'runit/error'\n\nmodule RUNIT\n  module Assert\n    include Test::Unit::Assertions\n\n    def setup_assert\n    end\n\n    def assert_no_exception(*args, &block)\n      assert_nothing_raised(*args, &block)\n    end\n\n    # To deal with the fact that RubyUnit does not check that the\n    # regular expression is, indeed, a regular expression, if it is\n    # not, we do our own assertion using the same semantics as\n    # RubyUnit\n    def assert_match(actual_string, expected_re, message=\"\")\n      _wrap_assertion {\n        full_message = build_message(message, \"Expected <?> to match <?>\", actual_string, expected_re)\n        assert_block(full_message) {\n          expected_re =~ actual_string\n        }\n        Regexp.last_match\n      }\n    end\n\n    def assert_not_nil(actual, message=\"\")\n      assert(!actual.nil?, message)\n    end\n\n    def assert_not_match(actual_string, expected_re, message=\"\")\n      assert_no_match(expected_re, actual_string, message)\n    end\n\n    def assert_matches(*args)\n      assert_match(*args)\n    end\n\n    def assert_fail(message=\"\")\n      flunk(message)\n    end\n\n    def assert_equal_float(expected, actual, delta, message=\"\")\n      assert_in_delta(expected, actual, delta, message)\n    end\n\n    def assert_send(object, method, *args)\n      super([object, method, *args])\n    end\n\n    def assert_exception(exception, message=\"\", &block)\n      assert_raises(exception, message, &block)\n    end\n\n    def assert_respond_to(method, object, message=\"\")\n      if (called_internally?)\n        super\n      else\n        super(object, method, message)\n      end\n    end\n\n    def called_internally?\n      /assertions\\.rb/.match(caller[1])\n    end\n  end\nend\n"
  },
  {
    "path": "lib/runit/cui/testrunner.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/ui/console/testrunner'\nrequire 'runit/testresult'\n\nmodule RUNIT\n  module CUI\n    class TestRunner < Test::Unit::UI::Console::TestRunner\n      @@quiet_mode = false\n      \n      def self.run(suite)\n        self.new().run(suite)\n      end\n      \n      def initialize\n        super nil\n      end\n      \n      def run(suite, quiet_mode=@@quiet_mode)\n        @suite = suite\n        def @suite.suite\n          self\n        end\n        @output_level = (quiet_mode ? Test::Unit::UI::PROGRESS_ONLY : Test::Unit::UI::VERBOSE)\n        start\n      end\n      \n      def create_mediator(suite)\n        mediator = Test::Unit::UI::TestRunnerMediator.new(suite)\n        class << mediator\n          attr_writer :result_delegate\n          def create_result\n            return @result_delegate.create_result\n          end\n        end\n        mediator.result_delegate = self\n        return mediator\n      end\n      \n      def create_result\n        return RUNIT::TestResult.new\n      end\n      \n      def self.quiet_mode=(boolean)\n        @@quiet_mode = boolean\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/runit/error.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/assertionfailederror.rb'\n\nmodule RUNIT\n  AssertionFailedError = Test::Unit::AssertionFailedError\nend\n"
  },
  {
    "path": "lib/runit/testcase.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'runit/testresult'\nrequire 'runit/testsuite'\nrequire 'runit/assert'\nrequire 'runit/error'\nrequire 'test/unit/testcase'\n\nmodule RUNIT\n  class TestCase < Test::Unit::TestCase  \n    include RUNIT::Assert\n    \n    def self.suite\n      method_names = instance_methods(true)\n      tests = method_names.delete_if { |method_name| method_name !~ /^test/ }\n      suite = TestSuite.new(name)\n      tests.each {\n        |test|\n        catch(:invalid_test) {\n          suite << new(test, name)\n        }\n      }\n      return suite\n    end\n    \n    def initialize(test_name, suite_name=self.class.name)\n      super(test_name)\n    end\n    \n    def assert_equals(*args)\n      assert_equal(*args)\n    end\n    \n    def name\n      super.sub(/^(.*?)\\((.*)\\)$/, '\\2#\\1')\n    end\n    \n    def run(result, &progress_block)\n      progress_block = proc {} unless (block_given?)\n      super(result, &progress_block)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/runit/testresult.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/testresult'\n\nmodule RUNIT\n  class TestResult < Test::Unit::TestResult\n    attr_reader(:errors, :failures)\n    def succeed?\n      return passed?\n    end\n    def failure_size\n      return failure_count\n    end\n    def run_asserts\n      return assertion_count\n    end\n    def error_size\n      return error_count\n    end\n    def run_tests\n      return run_count\n    end\n    def add_failure(failure)\n      def failure.at\n        return location\n      end\n      def failure.err\n        return message\n      end\n      super(failure)\n    end\n    def add_error(error)\n      def error.at\n        return location\n      end\n      def error.err\n        return exception\n      end\n      super(error)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/runit/testsuite.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/testsuite'\n\nmodule RUNIT\n  class TestSuite < Test::Unit::TestSuite\n    def add_test(*args)\n      add(*args)\n    end\n    \n    def add(*args)\n      self.<<(*args)\n    end\n    \n    def count_test_cases\n      return size\n    end\n    \n    def run(result, &progress_block)\n      progress_block = proc {} unless (block_given?)\n      super(result, &progress_block)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/runit/topublic.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nmodule RUNIT\n  module ToPublic\n  end\nend\n"
  },
  {
    "path": "lib/scanf.rb",
    "content": "# scanf for Ruby\n#\n# $Revision$\n# $Id$\n# $Author$\n# $Date$\n#\n# A product of the Austin Ruby Codefest (Austin, Texas, August 2002)\n\n=begin\n\n=scanf for Ruby\n\n==Description\n\nscanf for Ruby is an implementation of the C function scanf(3),\nmodified as necessary for Ruby compatibility.\n\nThe methods provided are String#scanf, IO#scanf, and\nKernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf.  IO#scanf\ncan be used on any IO stream, including file handles and sockets.\nscanf can be called either with or without a block.\n\nscanf for Ruby scans an input string or stream according to a\n<b>format</b>, as described below (\"Conversions\"), and returns an\narray of matches between the format and the input.  The format is\ndefined in a string, and is similar (though not identical) to the\nformats used in Kernel#printf and Kernel#sprintf.\n\nThe format may contain <b>conversion specifiers</b>, which tell scanf\nwhat form (type) each particular matched substring should be converted\nto (e.g., decimal integer, floating point number, literal string,\netc.)  The matches and conversions take place from left to right, and\nthe conversions themselves are returned as an array.\n\nThe format string may also contain characters other than those in the\nconversion specifiers.  White space (blanks, tabs, or newlines) in the\nformat string matches any amount of white space, including none, in\nthe input.  Everything else matches only itself.\n\nScanning stops, and scanf returns, when any input character fails to\nmatch the specifications in the format string, or when input is\nexhausted, or when everything in the format string has been\nmatched. All matches found up to the stopping point are returned in\nthe return array (or yielded to the block, if a block was given).\n\n\n==Basic usage\n\n   require 'scanf.rb'\n\n   # String#scanf and IO#scanf take a single argument (a format string)\n   array = aString.scanf(\"%d%s\")\n   array = anIO.scanf(\"%d%s\")\n\n   # Kernel#scanf reads from STDIN\n   array = scanf(\"%d%s\")\n\n==Block usage\n\nWhen called with a block, scanf keeps scanning the input, cycling back\nto the beginning of the format string, and yields a new array of\nconversions to the block every time the format string is matched\n(including partial matches, but not including complete failures).  The\nactual return value of scanf when called with a block is an array\ncontaining the results of all the executions of the block. \n\n   str = \"123 abc 456 def 789 ghi\"\n   str.scanf(\"%d%s\") { |num,str| [ num * 2, str.upcase ] }\n     # => [[246, \"ABC\"], [912, \"DEF\"], [1578, \"GHI\"]]\n\n==Conversions\n\nThe single argument to scanf is a format string, which generally\nincludes one or more conversion specifiers. Conversion specifiers\nbegin with the percent character ('%') and include information about\nwhat scanf should next scan for (string, decimal number, single\ncharacter, etc.).\n\nThere may be an optional maximum field width, expressed as a decimal\ninteger, between the % and the conversion. If no width is given, a\ndefault of `infinity' is used (with the exception of the %c specifier;\nsee below).  Otherwise, given a field width of <em>n</em> for a given\nconversion, at most <em>n</em> characters are scanned in processing\nthat conversion.  Before conversion begins, most conversions skip\nwhite space in the input string; this white space is not counted\nagainst the field width.\n\nThe following conversions are available. (See the files EXAMPLES\nand <tt>tests/scanftests.rb</tt> for examples.)\n\n[%]\n  Matches a literal `%'. That is, `%%' in the format string matches a\n  single input `%' character. No conversion is done, and the resulting\n  '%' is not included in the return array.\n\n[d]\n  Matches an optionally signed decimal integer.\n\n[u]\n  Same as d.\n\n[i] \n  Matches an optionally signed integer. The integer is read in base\n  16 if it begins with `0x' or `0X', in base 8 if it begins with `0',\n  and in base 10 other- wise. Only characters that correspond to the\n  base are recognized.\n\n[o]\n  Matches an optionally signed octal integer.\n\n[x,X]\n  Matches an optionally signed hexadecimal integer,\n\n[f,g,e,E]\n  Matches an optionally signed floating-point number.\n\n[s]\n  Matches a sequence of non-white-space character. The input string stops at\n  white space or at the maximum field width, whichever occurs first.\n\n[c]\n  Matches a single character, or a sequence of <em>n</em> characters if a\n  field width of <em>n</em> is specified. The usual skip of leading white\n  space is suppressed. To skip white space first, use an explicit space in\n  the format.\n\n[<tt>[</tt>]\n  Matches a nonempty sequence of characters from the specified set\n  of accepted characters.  The usual skip of leading white space is\n  suppressed.  This bracketed sub-expression is interpreted exactly like a\n  character class in a Ruby regular expression.  (In fact, it is placed as-is\n  in a regular expression.)  The matching against the input string ends with\n  the appearance of a character not in (or, with a circumflex, in) the set,\n  or when the field width runs out, whichever comes first.\n\n===Assignment suppression\n\nTo require that a particular match occur, but without including the result\nin the return array, place the <b>assignment suppression flag</b>, which is\nthe star character ('*'), immediately after the leading '%' of a format\nspecifier (just before the field width, if any).\n\n==Examples\n\nSee the files <tt>EXAMPLES</tt> and <tt>tests/scanftests.rb</tt>.\n\n==scanf for Ruby compared with scanf in C\n\nscanf for Ruby is based on the C function scanf(3), but with modifications,\ndictated mainly by the underlying differences between the languages.\n\n===Unimplemented flags and specifiers\n\n* The only flag implemented in scanf for Ruby is '<tt>*</tt>' (ignore\n  upcoming conversion). Many of the flags available in C versions of scanf(4)\n  have to do with the type of upcoming pointer arguments, and are literally\n  meaningless in Ruby.\n\n* The <tt>n</tt> specifier (store number of characters consumed so far in\n  next pointer) is not implemented.\n\n* The <tt>p</tt> specifier (match a pointer value) is not implemented.\n\n===Altered specifiers\n\n[o,u,x,X]\n  In scanf for Ruby, all of these specifiers scan for an optionally signed\n  integer, rather than for an unsigned integer like their C counterparts.\n\n===Return values\n\nscanf for Ruby returns an array of successful conversions, whereas\nscanf(3) returns the number of conversions successfully\ncompleted. (See below for more details on scanf for Ruby's return\nvalues.)\n\n==Return values\n\nWithout a block, scanf returns an array containing all the conversions\nit has found. If none are found, scanf will return an empty array. An\nunsuccesful match is never ignored, but rather always signals the end\nof the scanning operation. If the first unsuccessful match takes place\nafter one or more successful matches have already taken place, the\nreturned array will contain the results of those successful matches.\n\nWith a block scanf returns a 'map'-like array of transformations from\nthe block -- that is, an array reflecting what the block did with each\nyielded result from the iterative scanf operation.  (See \"Block\nusage\", above.)\n\n==Test suite\n\nscanf for Ruby includes a suite of unit tests (requiring the\n<tt>TestUnit</tt> package), which can be run with the command <tt>ruby\ntests/scanftests.rb</tt> or the command <tt>make test</tt>.\n\n==Current limitations and bugs\n\nWhen using IO#scanf under Windows, make sure you open your files in\nbinary mode:\n\n    File.open(\"filename\", \"rb\")\n\nso that scanf can keep track of characters correctly.\n\nSupport for character classes is reasonably complete (since it\nessentially piggy-backs on Ruby's regular expression handling of\ncharacter classes), but users are advised that character class testing\nhas not been exhaustive, and that they should exercise some caution\nin using any of the more complex and/or arcane character class\nidioms.\n\n\n==Technical notes\n\n===Rationale behind scanf for Ruby\n\nThe impetus for a scanf implementation in Ruby comes chiefly from the fact\nthat existing pattern matching operations, such as Regexp#match and\nString#scan, return all results as strings, which have to be converted to\nintegers or floats explicitly in cases where what's ultimately wanted are\ninteger or float values.\n\n===Design of scanf for Ruby\n\nscanf for Ruby is essentially a <format string>-to-<regular\nexpression> converter.\n\nWhen scanf is called, a FormatString object is generated from the\nformat string (\"%d%s...\") argument. The FormatString object breaks the\nformat string down into atoms (\"%d\", \"%5f\", \"blah\", etc.), and from\neach atom it creates a FormatSpecifier object, which it\nsaves.\n\nEach FormatSpecifier has a regular expression fragment and a \"handler\"\nassociated with it. For example, the regular expression fragment\nassociated with the format \"%d\" is \"([-+]?\\d+)\", and the handler\nassociated with it is a wrapper around String#to_i. scanf itself calls\nFormatString#match, passing in the input string. FormatString#match\niterates through its FormatSpecifiers; for each one, it matches the\ncorresponding regular expression fragment against the string. If\nthere's a match, it sends the matched string to the handler associated\nwith the FormatSpecifier.\n\nThus, to follow up the \"%d\" example: if \"123\" occurs in the input\nstring when a FormatSpecifier consisting of \"%d\" is reached, the \"123\"\nwill be matched against \"([-+]?\\d+)\", and the matched string will be\nrendered into an integer by a call to to_i.\n\nThe rendered match is then saved to an accumulator array, and the\ninput string is reduced to the post-match substring. Thus the string\nis \"eaten\" from the left as the FormatSpecifiers are applied in\nsequence.  (This is done to a duplicate string; the original string is\nnot altered.)\n\nAs soon as a regular expression fragment fails to match the string, or\nwhen the FormatString object runs out of FormatSpecifiers, scanning\nstops and results accumulated so far are returned in an array.\n\n==License and copyright\n\nCopyright:: (c) 2002-2003 David Alan Black\nLicense:: Distributed on the same licensing terms as Ruby itself\n\n==Warranty disclaimer\n\nThis software is provided \"as is\" and without any express or implied\nwarranties, including, without limitation, the implied warranties of\nmerchantibility and fitness for a particular purpose.\n\n==Credits and acknowledgements\n\nscanf for Ruby was developed as the major activity of the Austin\nRuby Codefest (Austin, Texas, August 2002).\n\nPrincipal author:: David Alan Black (mailto:dblack@superlink.net)\nCo-author:: Hal Fulton (mailto:hal9000@hypermetrics.com)\nProject contributors:: Nolan Darilek, Jason Johnston\n\nThanks to Hal Fulton for hosting the Codefest.\n\nThanks to Matz for suggestions about the class design.  \n\nThanks to Gavin Sinclair for some feedback on the documentation.\n\nThe text for parts of this document, especially the Description and\nConversions sections, above, were adapted from the Linux Programmer's\nManual manpage for scanf(3), dated 1995-11-01.\n\n==Bugs and bug reports\n\nscanf for Ruby is based on something of an amalgam of C scanf\nimplementations and documentation, rather than on a single canonical\ndescription. Suggestions for features and behaviors which appear in\nother scanfs, and would be meaningful in Ruby, are welcome, as are\nreports of suspicious behaviors and/or bugs. (Please see \"Credits and\nacknowledgements\", above, for email addresses.)\n\n=end\n\nmodule Scanf\n\n  class FormatSpecifier\n\n    attr_reader :re_string, :matched_string, :conversion, :matched\n\n    private\n\n    def skip;  /^\\s*%\\*/.match(@spec_string); end\n\n    def extract_float(s); s.to_f if s &&! skip; end\n    def extract_decimal(s); s.to_i if s &&! skip; end\n    def extract_hex(s); s.hex if s &&! skip; end\n    def extract_octal(s); s.oct if s &&! skip; end\n    def extract_integer(s); Integer(s) if s &&! skip; end\n    def extract_plain(s); s unless skip; end\n\n    def nil_proc(s); nil; end\n\n    public\n\n    def to_s\n      @spec_string\n    end\n\n    def count_space?\n      /(?:\\A|\\S)%\\*?\\d*c|\\[/.match(@spec_string)\n    end\n\n    def initialize(str)\n      @spec_string = str\n      h = '[A-Fa-f0-9]'\n\n      @re_string, @handler = \n        case @spec_string\n\n          # %[[:...:]]\n        when /%\\*?(\\[\\[:[a-z]+:\\]\\])/\n          [ \"(#{$1}+)\", :extract_plain ]\n\n          # %5[[:...:]]\n        when /%\\*?(\\d+)(\\[\\[:[a-z]+:\\]\\])/\n          [ \"(#{$2}{1,#{$1}})\", :extract_plain ]\n\n          # %[...]\n        when /%\\*?\\[([^\\]]*)\\]/\n          yes = $1\n          if /^\\^/.match(yes) then no = yes[1..-1] else no = '^' + yes end\n          [ \"([#{yes}]+)(?=[#{no}]|\\\\z)\", :extract_plain ]\n\n          # %5[...]\n        when /%\\*?(\\d+)\\[([^\\]]*)\\]/\n          yes = $2\n          w = $1\n          [ \"([#{yes}]{1,#{w}})\", :extract_plain ]\n\n          # %i\n        when /%\\*?i/\n          [ \"([-+]?(?:(?:0[0-7]+)|(?:0[Xx]#{h}+)|(?:[1-9]\\\\d*)))\", :extract_integer ]\n\n          # %5i\n        when /%\\*?(\\d+)i/\n          n = $1.to_i\n          s = \"(\"\n          if n > 1 then s += \"[1-9]\\\\d{1,#{n-1}}|\" end\n          if n > 1 then s += \"0[0-7]{1,#{n-1}}|\" end\n          if n > 2 then s += \"[-+]0[0-7]{1,#{n-2}}|\" end\n          if n > 2 then s += \"[-+][1-9]\\\\d{1,#{n-2}}|\" end\n          if n > 2 then s += \"0[Xx]#{h}{1,#{n-2}}|\" end\n          if n > 3 then s += \"[-+]0[Xx]#{h}{1,#{n-3}}|\" end\n          s += \"\\\\d\"\n          s += \")\"\n          [ s, :extract_integer ]\n\n          # %d, %u\n        when /%\\*?[du]/\n          [ '([-+]?\\d+)', :extract_decimal ]\n\n          # %5d, %5u\n        when /%\\*?(\\d+)[du]/\n          n = $1.to_i\n          s = \"(\"\n          if n > 1 then s += \"[-+]\\\\d{1,#{n-1}}|\" end\n          s += \"\\\\d{1,#{$1}})\"\n          [ s, :extract_decimal ]\n\n          # %x\n        when /%\\*?[Xx]/\n          [ \"([-+]?(?:0[Xx])?#{h}+)\", :extract_hex ]\n\n          # %5x\n        when /%\\*?(\\d+)[Xx]/\n          n = $1.to_i\n          s = \"(\"\n          if n > 3 then s += \"[-+]0[Xx]#{h}{1,#{n-3}}|\" end\n          if n > 2 then s += \"0[Xx]#{h}{1,#{n-2}}|\" end\n          if n > 1 then s += \"[-+]#{h}{1,#{n-1}}|\" end\n          s += \"#{h}{1,#{n}}\"\n          s += \")\"\n          [ s, :extract_hex ]\n\n          # %o\n        when /%\\*?o/\n          [ '([-+]?[0-7]+)', :extract_octal ]\n\n          # %5o\n        when /%\\*?(\\d+)o/\n          [ \"([-+][0-7]{1,#{$1.to_i-1}}|[0-7]{1,#{$1}})\", :extract_octal ]\n\n          # %f\n        when /%\\*?f/\n          [ '([-+]?((\\d+(?>(?=[^\\d.]|$)))|(\\d*(\\.(\\d*([eE][-+]?\\d+)?)))))', :extract_float ]\n\n          # %5f\n        when /%\\*?(\\d+)f/\n          [ \"(\\\\S{1,#{$1}})\", :extract_float ]\n\n          # %5s\n        when /%\\*?(\\d+)s/\n          [ \"(\\\\S{1,#{$1}})\", :extract_plain ]\n\n          # %s\n        when /%\\*?s/\n          [ '(\\S+)', :extract_plain ]\n\n          # %c\n        when /\\s%\\*?c/\n          [ \"\\\\s*(.)\", :extract_plain ]\n\n          # %c\n        when /%\\*?c/\n          [ \"(.)\", :extract_plain ]\n\n          # %5c (whitespace issues are handled by the count_*_space? methods)\n        when /%\\*?(\\d+)c/\n          [ \"(.{1,#{$1}})\", :extract_plain ]\n\n          # %%\n        when /%%/\n          [ '(\\s*%)', :nil_proc ]\n\n          # literal characters\n        else\n          [ \"(#{Regexp.escape(@spec_string)})\", :nil_proc ]\n        end\n\n      @re_string = '\\A' + @re_string\n    end\n\n    def to_re\n      Regexp.new(@re_string,Regexp::MULTILINE)\n    end\n\n    def match(str)\n      @matched = false\n      s = str.dup\n      s.sub!(/\\A\\s+/,'') unless count_space?\n      res = to_re.match(s)\n      if res\n        @conversion = send(@handler, res[1])\n        @matched_string = @conversion.to_s\n        @matched = true\n      end\n      res\n    end\n\n    def letter\n      /%\\*?\\d*([a-z\\[])/.match(@spec_string).to_a[1]\n    end\n\n    def width\n      w = /%\\*?(\\d+)/.match(@spec_string).to_a[1]\n      w && w.to_i\n    end\n\n    def mid_match?\n      return false unless @matched\n      cc_no_width    = letter == '[' &&! width\n      c_or_cc_width  = (letter == 'c' || letter == '[') && width\n      width_left     = c_or_cc_width && (matched_string.size < width)\n\n      return width_left || cc_no_width\n    end\n    \n  end\n\n  class FormatString\n\n    attr_reader :string_left, :last_spec_tried,\n                :last_match_tried, :matched_count, :space\n\n    SPECIFIERS = 'diuXxofeEgsc'\n    REGEX = /\n        # possible space, followed by...\n          (?:\\s*\n          # percent sign, followed by...\n            %\n            # another percent sign, or...\n              (?:%|\n        \t # optional assignment suppression flag\n        \t \\*?\n        \t # optional maximum field width\n        \t \\d*\n        \t   # named character class, ...\n        \t   (?:\\[\\[:\\w+:\\]\\]|\n        \t   # traditional character class, or...\n        \t      \\[[^\\]]*\\]|\n        \t   # specifier letter.\n        \t      [#{SPECIFIERS}])))|\n            # or miscellaneous characters\n              [^%\\s]+/ix\n\n    def initialize(str)\n      @specs = []\n      @i = 1\n      s = str.to_s\n      return unless /\\S/.match(s)\n      @space = true if /\\s\\z/.match(s)\n      @specs.replace s.scan(REGEX).map {|spec| FormatSpecifier.new(spec) }\n    end\n\n    def to_s\n      @specs.join('')\n    end\n\n    def prune(n=matched_count)\n      n.times { @specs.shift }\n    end\n\n    def spec_count\n      @specs.size\n    end\n\n    def last_spec\n      @i == spec_count - 1\n    end\n\n    def match(str)\n      accum = []\n      @string_left = str\n      @matched_count = 0\n\n      @specs.each_with_index do |spec,@i|\n        @last_spec_tried = spec\n        @last_match_tried = spec.match(@string_left)\n        break unless @last_match_tried\n        @matched_count += 1\n\n        accum << spec.conversion\n\n        @string_left = @last_match_tried.post_match\n        break if @string_left.empty?\n      end\n      return accum.compact\n    end\n  end\nend\n\nclass IO\n\n# The trick here is doing a match where you grab one *line*\n# of input at a time.  The linebreak may or may not occur\n# at the boundary where the string matches a format specifier.\n# And if it does, some rule about whitespace may or may not\n# be in effect...\n#\n# That's why this is much more elaborate than the string\n# version.\n#\n# For each line:\n# Match succeeds (non-emptily)\n# and the last attempted spec/string sub-match succeeded:\n#\n#   could the last spec keep matching?\n#     yes: save interim results and continue (next line)\n#\n# The last attempted spec/string did not match:\n#\n# are we on the next-to-last spec in the string?\n#   yes:\n#     is fmt_string.string_left all spaces?\n#       yes: does current spec care about input space?\n#         yes: fatal failure\n#         no: save interim results and continue\n#   no: continue  [this state could be analyzed further]\n#\n#\n\n  def scanf(str,&b)\n    return block_scanf(str,&b) if b\n    return [] unless str.size > 0\n\n    start_position = pos rescue 0\n    matched_so_far = 0\n    source_buffer = \"\"\n    result_buffer = []\n    final_result = []\n\n    fstr = Scanf::FormatString.new(str)\n\n    loop do\n      if eof || (tty? &&! fstr.match(source_buffer))\n        final_result.concat(result_buffer)\n        break\n      end\n\n      source_buffer << gets\n\n      current_match = fstr.match(source_buffer)\n\n      spec = fstr.last_spec_tried\n\n      if spec.matched\n        if spec.mid_match?\n          result_buffer.replace(current_match)\n          next\n        end\n\n      elsif (fstr.matched_count == fstr.spec_count - 1)\n        if /\\A\\s*\\z/.match(fstr.string_left)\n          break if spec.count_space?\n          result_buffer.replace(current_match)\n          next\n        end\n      end\n\n      final_result.concat(current_match)\n\n      matched_so_far += source_buffer.size\n      source_buffer.replace(fstr.string_left)\n      matched_so_far -= source_buffer.size\n      break if fstr.last_spec\n      fstr.prune\n    end\n    seek(start_position + matched_so_far, IO::SEEK_SET) rescue Errno::ESPIPE\n    soak_up_spaces if fstr.last_spec && fstr.space\n\n    return final_result\n  end\n\n  private\n\n  def soak_up_spaces\n    c = getc\n    ungetc(c) if c\n    until eof ||! c || /\\S/.match(c.chr)\n      c = getc\n    end\n    ungetc(c) if (c && /\\S/.match(c.chr))\n  end\n\n  def block_scanf(str)\n    final = []\n# Sub-ideal, since another FS gets created in scanf.\n# But used here to determine the number of specifiers.\n    fstr = Scanf::FormatString.new(str)\n    last_spec = fstr.last_spec\n    begin\n      current = scanf(str)\n      break if current.empty?\n      final.push(yield(current))\n    end until eof || fstr.last_spec_tried == last_spec\n    return final\n  end\nend\n\nclass String\n\n  def scanf(fstr,&b)\n    if b\n      block_scanf(fstr,&b)\n    else\n      fs = \n        if fstr.is_a? Scanf::FormatString\n          fstr \n        else \n          Scanf::FormatString.new(fstr)\n        end\n      fs.match(self)\n    end\n  end\n\n  def block_scanf(fstr,&b)\n    fs = Scanf::FormatString.new(fstr)\n    str = self.dup\n    final = []\n    begin\n      current = str.scanf(fs)\n      final.push(yield(current)) unless current.empty?\n      str = fs.string_left\n    end until current.empty? || str.empty?\n    return final\n  end\nend\n\nmodule Kernel\n  private\n  def scanf(fs,&b)\n    STDIN.scanf(fs,&b)\n  end\nend\n"
  },
  {
    "path": "lib/securerandom.rb",
    "content": "# = Secure random number generator interface.\n#\n# This library is an interface for secure random number generator which is\n# suitable for generating session key in HTTP cookies, etc.\n#\n# It supports following secure random number generators.\n#\n# * openssl\n# * /dev/urandom\n#\n# == Example\n#\n# # random hexadecimal string.\n# p SecureRandom.hex(10) #=> \"52750b30ffbc7de3b362\"\n# p SecureRandom.hex(10) #=> \"92b15d6c8dc4beb5f559\"\n# p SecureRandom.hex(11) #=> \"6aca1b5c58e4863e6b81b8\"\n# p SecureRandom.hex(12) #=> \"94b2fff3e7fd9b9c391a2306\"\n# p SecureRandom.hex(13) #=> \"39b290146bea6ce975c37cfc23\"\n# ...\n#\n# # random base64 string.\n# p SecureRandom.base64(10) #=> \"EcmTPZwWRAozdA==\"\n# p SecureRandom.base64(10) #=> \"9b0nsevdwNuM/w==\"\n# p SecureRandom.base64(10) #=> \"KO1nIU+p9DKxGg==\"\n# p SecureRandom.base64(11) #=> \"l7XEiFja+8EKEtY=\"\n# p SecureRandom.base64(12) #=> \"7kJSM/MzBJI+75j8\"\n# p SecureRandom.base64(13) #=> \"vKLJ0tXBHqQOuIcSIg==\"\n# ...\n#\n# # random binary string.\n# p SecureRandom.random_bytes(10) #=> \"\\016\\t{\\370g\\310pbr\\301\"\n# p SecureRandom.random_bytes(10) #=> \"\\323U\\030TO\\234\\357\\020\\a\\337\"\n# ...\n\nbegin\n  require 'openssl'\nrescue LoadError\nend\n\nmodule SecureRandom\n  # SecureRandom.random_bytes generates a random binary string.\n  #\n  # The argument n specifies the length of the result string.\n  #\n  # If n is not specified, 16 is assumed.\n  # It may be larger in future.\n  #\n  # If secure random number generator is not available,\n  # NotImplementedError is raised.\n  def self.random_bytes(n=nil)\n    n ||= 16\n    if defined? OpenSSL::Random\n      return OpenSSL::Random.random_bytes(n)\n    end\n    if !defined?(@has_urandom) || @has_urandom\n      @has_urandom = false\n      flags = File::RDONLY\n      flags |= File::NONBLOCK if defined? File::NONBLOCK\n      flags |= File::NOCTTY if defined? File::NOCTTY\n      flags |= File::NOFOLLOW if defined? File::NOFOLLOW\n      begin\n        File.open(\"/dev/urandom\", flags) {|f|\n          unless f.stat.chardev?\n            raise Errno::ENOENT\n          end\n          @has_urandom = true\n          ret = f.readpartial(n)\n          if ret.length != n\n            raise NotImplementedError, \"Unexpected partial read from random device\"\n          end\n          return ret\n        }\n      rescue Errno::ENOENT\n        raise NotImplementedError, \"No random device\"\n      end\n    end\n    raise NotImplementedError, \"No random device\"\n  end\n\n  # SecureRandom.hex generates a random hex string.\n  #\n  # The argument n specifies the length of the random length.\n  # The length of the result string is twice of n.\n  #\n  # If n is not specified, 16 is assumed.\n  # It may be larger in future.\n  #\n  # If secure random number generator is not available,\n  # NotImplementedError is raised.\n  def self.hex(n=nil)\n    random_bytes(n).unpack(\"H*\")[0]\n  end\n\n  # SecureRandom.base64 generates a random base64 string.\n  #\n  # The argument n specifies the length of the random length.\n  # The length of the result string is about 4/3 of n.\n  #\n  # If n is not specified, 16 is assumed.\n  # It may be larger in future.\n  #\n  # If secure random number generator is not available,\n  # NotImplementedError is raised.\n  def self.base64(n=nil)\n    [random_bytes(n)].pack(\"m*\").delete(\"\\n\")\n  end\n\n  # SecureRandom.random_number generates a random number.\n  #\n  # If an positive integer is given as n,\n  # SecureRandom.random_number returns an integer:\n  # 0 <= SecureRandom.random_number(n) < n.\n  #\n  # If 0 is given or an argument is not given,\n  # SecureRandom.random_number returns an float:\n  # 0.0 <= SecureRandom.random_number() < 1.0.\n  def self.random_number(n=0)\n    if 0 < n\n      hex = n.to_s(16)\n      hex = '0' + hex if (hex.length & 1) == 1\n      bin = [hex].pack(\"H*\")\n      mask = bin[0]\n      mask |= mask >> 1\n      mask |= mask >> 2\n      mask |= mask >> 4\n      begin\n        rnd = SecureRandom.random_bytes(bin.length)\n        rnd[0] = (rnd[0] & mask).chr\n      end until rnd < bin\n      rnd.unpack(\"H*\")[0].hex\n    else\n      # assumption: Float::MANT_DIG <= 64\n      i64 = SecureRandom.random_bytes(8).unpack(\"Q\")[0]\n      Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/set.rb",
    "content": "#!/usr/bin/env ruby\n#--\n# set.rb - defines the Set class\n#++\n# Copyright (c) 2002-2008 Akinori MUSHA <knu@iDaemons.org>\n#\n# Documentation by Akinori MUSHA and Gavin Sinclair. \n#\n# All rights reserved.  You can redistribute and/or modify it under the same\n# terms as Ruby.\n#\n#   $Id$\n#\n# == Overview \n# \n# This library provides the Set class, which deals with a collection\n# of unordered values with no duplicates.  It is a hybrid of Array's\n# intuitive inter-operation facilities and Hash's fast lookup.  If you\n# need to keep values ordered, use the SortedSet class.\n#\n# The method +to_set+ is added to Enumerable for convenience.\n#\n# See the Set class for an example of usage.\n\n\n#\n# Set implements a collection of unordered values with no duplicates.\n# This is a hybrid of Array's intuitive inter-operation facilities and\n# Hash's fast lookup.\n#\n# Several methods accept any Enumerable object (implementing +each+)\n# for greater flexibility: new, replace, merge, subtract, |, &, -, ^.\n#\n# The equality of each couple of elements is determined according to\n# Object#eql? and Object#hash, since Set uses Hash as storage.\n#\n# Finally, if you are using class Set, you can also use Enumerable#to_set\n# for convenience.\n#\n# == Example\n#\n#   require 'set'\n#   s1 = Set.new [1, 2]                   # -> #<Set: {1, 2}>\n#   s2 = [1, 2].to_set                    # -> #<Set: {1, 2}>\n#   s1 == s2                              # -> true\n#   s1.add(\"foo\")                         # -> #<Set: {1, 2, \"foo\"}>\n#   s1.merge([2, 6])                      # -> #<Set: {6, 1, 2, \"foo\"}>\n#   s1.subset? s2                         # -> false\n#   s2.subset? s1                         # -> true\n#\n# == Contact\n#\n#   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)\n#\nclass Set\n  include Enumerable\n\n  # Creates a new set containing the given objects.\n  def self.[](*ary)\n    new(ary)\n  end\n\n  # Creates a new set containing the elements of the given enumerable\n  # object.\n  #\n  # If a block is given, the elements of enum are preprocessed by the\n  # given block.\n  def initialize(enum = nil, &block) # :yields: o\n    @hash ||= Hash.new\n\n    enum.nil? and return\n\n    if block\n      enum.each { |o| add(block[o]) }\n    else\n      merge(enum)\n    end\n  end\n\n  # Copy internal hash.\n  def initialize_copy(orig)\n    @hash = orig.instance_eval{@hash}.dup\n  end\n\n  # Returns the number of elements.\n  def size\n    @hash.size\n  end\n  alias length size\n\n  # Returns true if the set contains no elements.\n  def empty?\n    @hash.empty?\n  end\n\n  # Removes all elements and returns self.\n  def clear\n    @hash.clear\n    self\n  end\n\n  # Replaces the contents of the set with the contents of the given\n  # enumerable object and returns self.\n  def replace(enum)\n    if enum.class == self.class\n      @hash.replace(enum.instance_eval { @hash })\n    else\n      enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n      clear\n      enum.each { |o| add(o) }\n    end\n\n    self\n  end\n\n  # Converts the set to an array.  The order of elements is uncertain.\n  def to_a\n    @hash.keys\n  end\n\n  def flatten_merge(set, seen = Set.new)\n    set.each { |e|\n      if e.is_a?(Set)\n\tif seen.include?(e_id = e.object_id)\n\t  raise ArgumentError, \"tried to flatten recursive Set\"\n\tend\n\n\tseen.add(e_id)\n\tflatten_merge(e, seen)\n\tseen.delete(e_id)\n      else\n\tadd(e)\n      end\n    }\n\n    self\n  end\n  protected :flatten_merge\n\n  # Returns a new set that is a copy of the set, flattening each\n  # containing set recursively.\n  def flatten\n    self.class.new.flatten_merge(self)\n  end\n\n  # Equivalent to Set#flatten, but replaces the receiver with the\n  # result in place.  Returns nil if no modifications were made.\n  def flatten!\n    if detect { |e| e.is_a?(Set) }\n      replace(flatten())\n    else\n      nil\n    end\n  end\n\n  # Returns true if the set contains the given object.\n  def include?(o)\n    @hash.include?(o)\n  end\n  alias member? include?\n\n  # Returns true if the set is a superset of the given set.\n  def superset?(set)\n    set.is_a?(Set) or raise ArgumentError, \"value must be a set\"\n    return false if size < set.size\n    set.all? { |o| include?(o) }\n  end\n\n  # Returns true if the set is a proper superset of the given set.\n  def proper_superset?(set)\n    set.is_a?(Set) or raise ArgumentError, \"value must be a set\"\n    return false if size <= set.size\n    set.all? { |o| include?(o) }\n  end\n\n  # Returns true if the set is a subset of the given set.\n  def subset?(set)\n    set.is_a?(Set) or raise ArgumentError, \"value must be a set\"\n    return false if set.size < size\n    all? { |o| set.include?(o) }\n  end\n\n  # Returns true if the set is a proper subset of the given set.\n  def proper_subset?(set)\n    set.is_a?(Set) or raise ArgumentError, \"value must be a set\"\n    return false if set.size <= size\n    all? { |o| set.include?(o) }\n  end\n\n  # Calls the given block once for each element in the set, passing\n  # the element as parameter.  Returns an enumerator if no block is\n  # given.\n  def each\n    block_given? or return enum_for(__method__)\n    @hash.each_key { |o| yield(o) }\n    self\n  end\n\n  # Adds the given object to the set and returns self.  Use +merge+ to\n  # add several elements at once.\n  def add(o)\n    @hash[o] = true\n    self\n  end\n  alias << add\n\n  # Adds the given object to the set and returns self.  If the\n  # object is already in the set, returns nil.\n  def add?(o)\n    if include?(o)\n      nil\n    else\n      add(o)\n    end\n  end\n\n  # Deletes the given object from the set and returns self.  Use +subtract+ to\n  # delete several items at once.\n  def delete(o)\n    @hash.delete(o)\n    self\n  end\n\n  # Deletes the given object from the set and returns self.  If the\n  # object is not in the set, returns nil.\n  def delete?(o)\n    if include?(o)\n      delete(o)\n    else\n      nil\n    end\n  end\n\n  # Deletes every element of the set for which block evaluates to\n  # true, and returns self.\n  def delete_if\n    to_a.each { |o| @hash.delete(o) if yield(o) }\n    self\n  end\n\n  # Do collect() destructively.\n  def collect!\n    set = self.class.new\n    each { |o| set << yield(o) }\n    replace(set)\n  end\n  alias map! collect!\n\n  # Equivalent to Set#delete_if, but returns nil if no changes were\n  # made.\n  def reject!\n    n = size\n    delete_if { |o| yield(o) }\n    size == n ? nil : self\n  end\n\n  # Merges the elements of the given enumerable object to the set and\n  # returns self.\n  def merge(enum)\n    if enum.is_a?(Set)\n      @hash.update(enum.instance_eval { @hash })\n    else\n      enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n      enum.each { |o| add(o) }\n    end\n\n    self\n  end\n\n  # Deletes every element that appears in the given enumerable object\n  # and returns self.\n  def subtract(enum)\n    enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n    enum.each { |o| delete(o) }\n    self\n  end\n\n  # Returns a new set built by merging the set and the elements of the\n  # given enumerable object.\n  def |(enum)\n    enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n    dup.merge(enum)\n  end\n  alias + |\t\t##\n  alias union |\t\t##\n\n  # Returns a new set built by duplicating the set, removing every\n  # element that appears in the given enumerable object.\n  def -(enum)\n    enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n    dup.subtract(enum)\n  end\n  alias difference -\t##\n\n  # Returns a new set containing elements common to the set and the\n  # given enumerable object.\n  def &(enum)\n    enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n    n = self.class.new\n    enum.each { |o| n.add(o) if include?(o) }\n    n\n  end\n  alias intersection &\t##\n\n  # Returns a new set containing elements exclusive between the set\n  # and the given enumerable object.  (set ^ enum) is equivalent to\n  # ((set | enum) - (set & enum)).\n  def ^(enum)\n    enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n    n = Set.new(enum)\n    each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }\n    n\n  end\n\n  # Returns true if two sets are equal.  The equality of each couple\n  # of elements is defined according to Object#eql?.\n  def ==(set)\n    equal?(set) and return true\n\n    set.is_a?(Set) && size == set.size or return false\n\n    hash = @hash.dup\n    set.all? { |o| hash.include?(o) }\n  end\n\n  def hash\t# :nodoc:\n    @hash.hash\n  end\n\n  def eql?(o)\t# :nodoc:\n    return false unless o.is_a?(Set)\n    @hash.eql?(o.instance_eval{@hash})\n  end\n\n  # Classifies the set by the return value of the given block and\n  # returns a hash of {value => set of elements} pairs.  The block is\n  # called once for each element of the set, passing the element as\n  # parameter.\n  #\n  # e.g.:\n  #\n  #   require 'set'\n  #   files = Set.new(Dir.glob(\"*.rb\"))\n  #   hash = files.classify { |f| File.mtime(f).year }\n  #   p hash    # => {2000=>#<Set: {\"a.rb\", \"b.rb\"}>,\n  #             #     2001=>#<Set: {\"c.rb\", \"d.rb\", \"e.rb\"}>,\n  #             #     2002=>#<Set: {\"f.rb\"}>}\n  def classify # :yields: o\n    h = {}\n\n    each { |i|\n      x = yield(i)\n      (h[x] ||= self.class.new).add(i)\n    }\n\n    h\n  end\n\n  # Divides the set into a set of subsets according to the commonality\n  # defined by the given block.\n  #\n  # If the arity of the block is 2, elements o1 and o2 are in common\n  # if block.call(o1, o2) is true.  Otherwise, elements o1 and o2 are\n  # in common if block.call(o1) == block.call(o2).\n  #\n  # e.g.:\n  #\n  #   require 'set'\n  #   numbers = Set[1, 3, 4, 6, 9, 10, 11]\n  #   set = numbers.divide { |i,j| (i - j).abs == 1 }\n  #   p set     # => #<Set: {#<Set: {1}>,\n  #             #            #<Set: {11, 9, 10}>,\n  #             #            #<Set: {3, 4}>,\n  #             #            #<Set: {6}>}>\n  def divide(&func)\n    if func.arity == 2\n      require 'tsort'\n\n      class << dig = {}\t\t# :nodoc:\n\tinclude TSort\n\n\talias tsort_each_node each_key\n\tdef tsort_each_child(node, &block)\n\t  fetch(node).each(&block)\n\tend\n      end\n\n      each { |u|\n\tdig[u] = a = []\n\teach{ |v| func.call(u, v) and a << v }\n      }\n\n      set = Set.new()\n      dig.each_strongly_connected_component { |css|\n\tset.add(self.class.new(css))\n      }\n      set\n    else\n      Set.new(classify(&func).values)\n    end\n  end\n\n  InspectKey = :__inspect_key__         # :nodoc:\n\n  # Returns a string containing a human-readable representation of the\n  # set. (\"#<Set: {element1, element2, ...}>\")\n  def inspect\n    ids = (Thread.current[InspectKey] ||= [])\n\n    if ids.include?(object_id)\n      return sprintf('#<%s: {...}>', self.class.name)\n    end\n\n    begin\n      ids << object_id\n      return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])\n    ensure\n      ids.pop\n    end\n  end\n\n  def pretty_print(pp)\t# :nodoc:\n    pp.text sprintf('#<%s: {', self.class.name)\n    pp.nest(1) {\n      pp.seplist(self) { |o|\n\tpp.pp o\n      }\n    }\n    pp.text \"}>\"\n  end\n\n  def pretty_print_cycle(pp)\t# :nodoc:\n    pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')\n  end\nend\n\n# SortedSet implements a set which elements are sorted in order.  See Set.\nclass SortedSet < Set\n  @@setup = false\n\n  class << self\n    def [](*ary)\t# :nodoc:\n      new(ary)\n    end\n\n    def setup\t# :nodoc:\n      @@setup and return\n\n      module_eval {\n        # a hack to shut up warning\n        alias old_init initialize\n        remove_method :old_init\n      }\n      begin\n\trequire 'rbtree'\n\n\tmodule_eval %{\n\t  def initialize(*args, &block)\n\t    @hash = RBTree.new\n\t    super\n\t  end\n\t}\n      rescue LoadError\n\tmodule_eval %{\n\t  def initialize(*args, &block)\n\t    @keys = nil\n\t    super\n\t  end\n\n\t  def clear\n\t    @keys = nil\n\t    super\n\t  end\n\n\t  def replace(enum)\n\t    @keys = nil\n\t    super\n\t  end\n\n\t  def add(o)\n\t    @keys = nil\n\t    @hash[o] = true\n\t    self\n\t  end\n\t  alias << add\n\n\t  def delete(o)\n\t    @keys = nil\n\t    @hash.delete(o)\n\t    self\n\t  end\n\n\t  def delete_if\n\t    n = @hash.size\n\t    super\n\t    @keys = nil if @hash.size != n\n\t    self\n\t  end\n\n\t  def merge(enum)\n\t    @keys = nil\n\t    super\n\t  end\n\n\t  def each\n\t    block_given? or return enum_for(__method__)\n\t    to_a.each { |o| yield(o) }\n\t    self\n\t  end\n\n\t  def to_a\n\t    (@keys = @hash.keys).sort! unless @keys\n\t    @keys\n\t  end\n\t}\n      end\n\n      @@setup = true\n    end\n  end\n\n  def initialize(*args, &block)\t# :nodoc:\n    SortedSet.setup\n    initialize(*args, &block)\n  end\nend\n\nmodule Enumerable\n  # Makes a set from the enumerable object with given arguments.\n  # Needs to +require \"set\"+ to use this method.\n  def to_set(klass = Set, *args, &block)\n    klass.new(self, *args, &block)\n  end\nend\n\n# =begin\n# == RestricedSet class\n# RestricedSet implements a set with restrictions defined by a given\n# block.\n# \n# === Super class\n#     Set\n# \n# === Class Methods\n# --- RestricedSet::new(enum = nil) { |o| ... }\n# --- RestricedSet::new(enum = nil) { |rset, o| ... }\n#     Creates a new restricted set containing the elements of the given\n#     enumerable object.  Restrictions are defined by the given block.\n# \n#     If the block's arity is 2, it is called with the RestrictedSet\n#     itself and an object to see if the object is allowed to be put in\n#     the set.\n# \n#     Otherwise, the block is called with an object to see if the object\n#     is allowed to be put in the set.\n# \n# === Instance Methods\n# --- restriction_proc\n#     Returns the restriction procedure of the set.\n# \n# =end\n# \n# class RestricedSet < Set\n#   def initialize(*args, &block)\n#     @proc = block or raise ArgumentError, \"missing a block\"\n# \n#     if @proc.arity == 2\n#       instance_eval %{\n# \tdef add(o)\n# \t  @hash[o] = true if @proc.call(self, o)\n# \t  self\n# \tend\n# \talias << add\n# \n# \tdef add?(o)\n# \t  if include?(o) || !@proc.call(self, o)\n# \t    nil\n# \t  else\n# \t    @hash[o] = true\n# \t    self\n# \t  end\n# \tend\n# \n# \tdef replace(enum)\n# \t  enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n# \t  clear\n# \t  enum.each { |o| add(o) }\n# \n# \t  self\n# \tend\n# \n# \tdef merge(enum)\n# \t  enum.is_a?(Enumerable) or raise ArgumentError, \"value must be enumerable\"\n# \t  enum.each { |o| add(o) }\n# \n# \t  self\n# \tend\n#       }\n#     else\n#       instance_eval %{\n# \tdef add(o)\n#         if @proc.call(o)\n# \t    @hash[o] = true \n#         end\n# \t  self\n# \tend\n# \talias << add\n# \n# \tdef add?(o)\n# \t  if include?(o) || !@proc.call(o)\n# \t    nil\n# \t  else\n# \t    @hash[o] = true\n# \t    self\n# \t  end\n# \tend\n#       }\n#     end\n# \n#     super(*args)\n#   end\n# \n#   def restriction_proc\n#     @proc\n#   end\n# end\n\nif $0 == __FILE__\n  eval DATA.read, nil, $0, __LINE__+4\nend\n\n__END__\n\nrequire 'test/unit'\n\nclass TC_Set < Test::Unit::TestCase\n  def test_aref\n    assert_nothing_raised {\n      Set[]\n      Set[nil]\n      Set[1,2,3]\n    }\n\n    assert_equal(0, Set[].size)\n    assert_equal(1, Set[nil].size)\n    assert_equal(1, Set[[]].size)\n    assert_equal(1, Set[[nil]].size)\n\n    set = Set[2,4,6,4]\n    assert_equal(Set.new([2,4,6]), set)\n  end\n\n  def test_s_new\n    assert_nothing_raised {\n      Set.new()\n      Set.new(nil)\n      Set.new([])\n      Set.new([1,2])\n      Set.new('a'..'c')\n      Set.new('XYZ')\n    }\n    assert_raises(ArgumentError) {\n      Set.new(false)\n    }\n    assert_raises(ArgumentError) {\n      Set.new(1)\n    }\n    assert_raises(ArgumentError) {\n      Set.new(1,2)\n    }\n\n    assert_equal(0, Set.new().size)\n    assert_equal(0, Set.new(nil).size)\n    assert_equal(0, Set.new([]).size)\n    assert_equal(1, Set.new([nil]).size)\n\n    ary = [2,4,6,4]\n    set = Set.new(ary)\n    ary.clear\n    assert_equal(false, set.empty?)\n    assert_equal(3, set.size)\n\n    ary = [1,2,3]\n\n    s = Set.new(ary) { |o| o * 2 }\n    assert_equal([2,4,6], s.sort)\n  end\n\n  def test_clone\n    set1 = Set.new\n    set2 = set1.clone\n    set1 << 'abc'\n    assert_equal(Set.new, set2)\n  end\n\n  def test_dup\n    set1 = Set[1,2]\n    set2 = set1.dup\n\n    assert_not_same(set1, set2)\n\n    assert_equal(set1, set2)\n\n    set1.add(3)\n\n    assert_not_equal(set1, set2)\n  end\n\n  def test_size\n    assert_equal(0, Set[].size)\n    assert_equal(2, Set[1,2].size)\n    assert_equal(2, Set[1,2,1].size)\n  end\n\n  def test_empty?\n    assert_equal(true, Set[].empty?)\n    assert_equal(false, Set[1, 2].empty?)\n  end\n\n  def test_clear\n    set = Set[1,2]\n    ret = set.clear\n\n    assert_same(set, ret)\n    assert_equal(true, set.empty?)\n  end\n\n  def test_replace\n    set = Set[1,2]\n    ret = set.replace('a'..'c')\n\n    assert_same(set, ret)\n    assert_equal(Set['a','b','c'], set)\n  end\n\n  def test_to_a\n    set = Set[1,2,3,2]\n    ary = set.to_a\n\n    assert_equal([1,2,3], ary.sort)\n  end\n\n  def test_flatten\n    # test1\n    set1 = Set[\n      1,\n      Set[\n\t5,\n\tSet[7,\n\t  Set[0]\n\t],\n\tSet[6,2],\n\t1\n      ],\n      3,\n      Set[3,4]\n    ]\n\n    set2 = set1.flatten\n    set3 = Set.new(0..7)\n\n    assert_not_same(set2, set1)\n    assert_equal(set3, set2)\n\n    # test2; destructive\n    orig_set1 = set1\n    set1.flatten!\n\n    assert_same(orig_set1, set1)\n    assert_equal(set3, set1)\n\n    # test3; multiple occurrences of a set in an set\n    set1 = Set[1, 2]\n    set2 = Set[set1, Set[set1, 4], 3]\n\n    assert_nothing_raised {\n      set2.flatten!\n    }\n\n    assert_equal(Set.new(1..4), set2)\n\n    # test4; recursion\n    set2 = Set[]\n    set1 = Set[1, set2]\n    set2.add(set1)\n\n    assert_raises(ArgumentError) {\n      set1.flatten!\n    }\n\n    # test5; miscellaneous\n    empty = Set[]\n    set =  Set[Set[empty, \"a\"],Set[empty, \"b\"]]\n\n    assert_nothing_raised {\n      set.flatten\n    }\n\n    set1 = empty.merge(Set[\"no_more\", set])\n\n    assert_nil(Set.new(0..31).flatten!)\n\n    x = Set[Set[],Set[1,2]].flatten!\n    y = Set[1,2]\n\n    assert_equal(x, y)\n  end\n\n  def test_include?\n    set = Set[1,2,3]\n\n    assert_equal(true, set.include?(1))\n    assert_equal(true, set.include?(2))\n    assert_equal(true, set.include?(3))\n    assert_equal(false, set.include?(0))\n    assert_equal(false, set.include?(nil))\n\n    set = Set[\"1\",nil,\"2\",nil,\"0\",\"1\",false]\n    assert_equal(true, set.include?(nil))\n    assert_equal(true, set.include?(false))\n    assert_equal(true, set.include?(\"1\"))\n    assert_equal(false, set.include?(0))\n    assert_equal(false, set.include?(true))\n  end\n\n  def test_superset?\n    set = Set[1,2,3]\n\n    assert_raises(ArgumentError) {\n      set.superset?()\n    }\n\n    assert_raises(ArgumentError) {\n      set.superset?(2)\n    }\n\n    assert_raises(ArgumentError) {\n      set.superset?([2])\n    }\n\n    assert_equal(true, set.superset?(Set[]))\n    assert_equal(true, set.superset?(Set[1,2]))\n    assert_equal(true, set.superset?(Set[1,2,3]))\n    assert_equal(false, set.superset?(Set[1,2,3,4]))\n    assert_equal(false, set.superset?(Set[1,4]))\n\n    assert_equal(true, Set[].superset?(Set[]))\n  end\n\n  def test_proper_superset?\n    set = Set[1,2,3]\n\n    assert_raises(ArgumentError) {\n      set.proper_superset?()\n    }\n\n    assert_raises(ArgumentError) {\n      set.proper_superset?(2)\n    }\n\n    assert_raises(ArgumentError) {\n      set.proper_superset?([2])\n    }\n\n    assert_equal(true, set.proper_superset?(Set[]))\n    assert_equal(true, set.proper_superset?(Set[1,2]))\n    assert_equal(false, set.proper_superset?(Set[1,2,3]))\n    assert_equal(false, set.proper_superset?(Set[1,2,3,4]))\n    assert_equal(false, set.proper_superset?(Set[1,4]))\n\n    assert_equal(false, Set[].proper_superset?(Set[]))\n  end\n\n  def test_subset?\n    set = Set[1,2,3]\n\n    assert_raises(ArgumentError) {\n      set.subset?()\n    }\n\n    assert_raises(ArgumentError) {\n      set.subset?(2)\n    }\n\n    assert_raises(ArgumentError) {\n      set.subset?([2])\n    }\n\n    assert_equal(true, set.subset?(Set[1,2,3,4]))\n    assert_equal(true, set.subset?(Set[1,2,3]))\n    assert_equal(false, set.subset?(Set[1,2]))\n    assert_equal(false, set.subset?(Set[]))\n\n    assert_equal(true, Set[].subset?(Set[1]))\n    assert_equal(true, Set[].subset?(Set[]))\n  end\n\n  def test_proper_subset?\n    set = Set[1,2,3]\n\n    assert_raises(ArgumentError) {\n      set.proper_subset?()\n    }\n\n    assert_raises(ArgumentError) {\n      set.proper_subset?(2)\n    }\n\n    assert_raises(ArgumentError) {\n      set.proper_subset?([2])\n    }\n\n    assert_equal(true, set.proper_subset?(Set[1,2,3,4]))\n    assert_equal(false, set.proper_subset?(Set[1,2,3]))\n    assert_equal(false, set.proper_subset?(Set[1,2]))\n    assert_equal(false, set.proper_subset?(Set[]))\n\n    assert_equal(false, Set[].proper_subset?(Set[]))\n  end\n\n  def test_each\n    ary = [1,3,5,7,10,20]\n    set = Set.new(ary)\n\n    ret = set.each { |o| }\n    assert_same(set, ret)\n\n    e = set.each\n    assert_instance_of(Enumerable::Enumerator, e)\n\n    assert_nothing_raised {\n      set.each { |o|\n\tary.delete(o) or raise \"unexpected element: #{o}\"\n      }\n\n      ary.empty? or raise \"forgotten elements: #{ary.join(', ')}\"\n    }\n  end\n\n  def test_add\n    set = Set[1,2,3]\n\n    ret = set.add(2)\n    assert_same(set, ret)\n    assert_equal(Set[1,2,3], set)\n\n    ret = set.add?(2)\n    assert_nil(ret)\n    assert_equal(Set[1,2,3], set)\n\n    ret = set.add(4)\n    assert_same(set, ret)\n    assert_equal(Set[1,2,3,4], set)\n\n    ret = set.add?(5)\n    assert_same(set, ret)\n    assert_equal(Set[1,2,3,4,5], set)\n  end\n\n  def test_delete\n    set = Set[1,2,3]\n\n    ret = set.delete(4)\n    assert_same(set, ret)\n    assert_equal(Set[1,2,3], set)\n\n    ret = set.delete?(4)\n    assert_nil(ret)\n    assert_equal(Set[1,2,3], set)\n\n    ret = set.delete(2)\n    assert_equal(set, ret)\n    assert_equal(Set[1,3], set)\n\n    ret = set.delete?(1)\n    assert_equal(set, ret)\n    assert_equal(Set[3], set)\n  end\n\n  def test_delete_if\n    set = Set.new(1..10)\n    ret = set.delete_if { |i| i > 10 }\n    assert_same(set, ret)\n    assert_equal(Set.new(1..10), set)\n\n    set = Set.new(1..10)\n    ret = set.delete_if { |i| i % 3 == 0 }\n    assert_same(set, ret)\n    assert_equal(Set[1,2,4,5,7,8,10], set)\n  end\n\n  def test_collect!\n    set = Set[1,2,3,'a','b','c',-1..1,2..4]\n\n    ret = set.collect! { |i|\n      case i\n      when Numeric\n\ti * 2\n      when String\n\ti.upcase\n      else\n\tnil\n      end\n    }\n\n    assert_same(set, ret)\n    assert_equal(Set[2,4,6,'A','B','C',nil], set)\n  end\n\n  def test_reject!\n    set = Set.new(1..10)\n\n    ret = set.reject! { |i| i > 10 }\n    assert_nil(ret)\n    assert_equal(Set.new(1..10), set)\n\n    ret = set.reject! { |i| i % 3 == 0 }\n    assert_same(set, ret)\n    assert_equal(Set[1,2,4,5,7,8,10], set)\n  end\n\n  def test_merge\n    set = Set[1,2,3]\n\n    ret = set.merge([2,4,6])\n    assert_same(set, ret)\n    assert_equal(Set[1,2,3,4,6], set)\n  end\n\n  def test_subtract\n    set = Set[1,2,3]\n\n    ret = set.subtract([2,4,6])\n    assert_same(set, ret)\n    assert_equal(Set[1,3], set)\n  end\n\n  def test_plus\n    set = Set[1,2,3]\n\n    ret = set + [2,4,6]\n    assert_not_same(set, ret)\n    assert_equal(Set[1,2,3,4,6], ret)\n  end\n\n  def test_minus\n    set = Set[1,2,3]\n\n    ret = set - [2,4,6]\n    assert_not_same(set, ret)\n    assert_equal(Set[1,3], ret)\n  end\n\n  def test_and\n    set = Set[1,2,3,4]\n\n    ret = set & [2,4,6]\n    assert_not_same(set, ret)\n    assert_equal(Set[2,4], ret)\n  end\n\n  def test_xor\n    set = Set[1,2,3,4]\n    ret = set ^ [2,4,5,5]\n    assert_not_same(set, ret)\n    assert_equal(Set[1,3,5], ret)\n  end\n\n  def test_eq\n    set1 = Set[2,3,1]\n    set2 = Set[1,2,3]\n\n    assert_equal(set1, set1)\n    assert_equal(set1, set2)\n    assert_not_equal(Set[1], [1])\n\n    set1 = Class.new(Set)[\"a\", \"b\"]\n    set2 = Set[\"a\", \"b\", set1]\n    set1 = set1.add(set1.clone)\n\n#    assert_equal(set1, set2)\n#    assert_equal(set2, set1)\n    assert_equal(set2, set2.clone)\n    assert_equal(set1.clone, set1)\n\n    assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], \"[ruby-dev:26127]\")\n  end\n\n  # def test_hash\n  # end\n\n  # def test_eql?\n  # end\n\n  def test_classify\n    set = Set.new(1..10)\n    ret = set.classify { |i| i % 3 }\n\n    assert_equal(3, ret.size)\n    assert_instance_of(Hash, ret)\n    ret.each_value { |value| assert_instance_of(Set, value) }\n    assert_equal(Set[3,6,9], ret[0])\n    assert_equal(Set[1,4,7,10], ret[1])\n    assert_equal(Set[2,5,8], ret[2])\n  end\n\n  def test_divide\n    set = Set.new(1..10)\n    ret = set.divide { |i| i % 3 }\n\n    assert_equal(3, ret.size)\n    n = 0\n    ret.each { |s| n += s.size }\n    assert_equal(set.size, n)\n    assert_equal(set, ret.flatten)\n\n    set = Set[7,10,5,11,1,3,4,9,0]\n    ret = set.divide { |a,b| (a - b).abs == 1 }\n\n    assert_equal(4, ret.size)\n    n = 0\n    ret.each { |s| n += s.size }\n    assert_equal(set.size, n)\n    assert_equal(set, ret.flatten)\n    ret.each { |s|\n      if s.include?(0)\n\tassert_equal(Set[0,1], s)\n      elsif s.include?(3)\n\tassert_equal(Set[3,4,5], s)\n      elsif s.include?(7)\n\tassert_equal(Set[7], s)\n      elsif s.include?(9)\n\tassert_equal(Set[9,10,11], s)\n      else\n\traise \"unexpected group: #{s.inspect}\"\n      end\n    }\n  end\n\n  def test_inspect\n    set1 = Set[1]\n\n    assert_equal('#<Set: {1}>', set1.inspect)\n\n    set2 = Set[Set[0], 1, 2, set1]\n    assert_equal(false, set2.inspect.include?('#<Set: {...}>'))\n\n    set1.add(set2)\n    assert_equal(true, set1.inspect.include?('#<Set: {...}>'))\n  end\n\n  # def test_pretty_print\n  # end\n\n  # def test_pretty_print_cycle\n  # end\nend\n\nclass TC_SortedSet < Test::Unit::TestCase\n  def test_sortedset\n    s = SortedSet[4,5,3,1,2]\n\n    assert_equal([1,2,3,4,5], s.to_a)\n\n    prev = nil\n    s.each { |o| assert(prev < o) if prev; prev = o }\n    assert_not_nil(prev)\n\n    s.map! { |o| -2 * o }\n\n    assert_equal([-10,-8,-6,-4,-2], s.to_a)\n\n    prev = nil\n    ret = s.each { |o| assert(prev < o) if prev; prev = o }\n    assert_not_nil(prev)\n    assert_same(s, ret)\n\n    s = SortedSet.new([2,1,3]) { |o| o * -2 }\n    assert_equal([-6,-4,-2], s.to_a)\n\n    s = SortedSet.new(['one', 'two', 'three', 'four'])\n    a = []\n    ret = s.delete_if { |o| a << o; o.start_with?('t') }\n    assert_same(s, ret)\n    assert_equal(['four', 'one'], s.to_a)\n    assert_equal(['four', 'one', 'three', 'two'], a)\n\n    s = SortedSet.new(['one', 'two', 'three', 'four'])\n    a = []\n    ret = s.reject! { |o| a << o; o.start_with?('t') }\n    assert_same(s, ret)\n    assert_equal(['four', 'one'], s.to_a)\n    assert_equal(['four', 'one', 'three', 'two'], a)\n\n    s = SortedSet.new(['one', 'two', 'three', 'four'])\n    a = []\n    ret = s.reject! { |o| a << o; false }\n    assert_same(nil, ret)\n    assert_equal(['four', 'one', 'three', 'two'], s.to_a)\n    assert_equal(['four', 'one', 'three', 'two'], a)\n  end\nend\n\nclass TC_Enumerable < Test::Unit::TestCase\n  def test_to_set\n    ary = [2,5,4,3,2,1,3]\n\n    set = ary.to_set\n    assert_instance_of(Set, set)\n    assert_equal([1,2,3,4,5], set.sort)\n\n    set = ary.to_set { |o| o * -2 }\n    assert_instance_of(Set, set)\n    assert_equal([-10,-8,-6,-4,-2], set.sort)\n\n    set = ary.to_set(SortedSet)\n    assert_instance_of(SortedSet, set)\n    assert_equal([1,2,3,4,5], set.to_a)\n\n    set = ary.to_set(SortedSet) { |o| o * -2 }\n    assert_instance_of(SortedSet, set)\n    assert_equal([-10,-8,-6,-4,-2], set.sort)\n  end\nend\n\n# class TC_RestricedSet < Test::Unit::TestCase\n#   def test_s_new\n#     assert_raises(ArgumentError) { RestricedSet.new }\n# \n#     s = RestricedSet.new([-1,2,3]) { |o| o > 0 }\n#     assert_equal([2,3], s.sort)\n#   end\n# \n#   def test_restriction_proc\n#     s = RestricedSet.new([-1,2,3]) { |o| o > 0 }\n# \n#     f = s.restriction_proc\n#     assert_instance_of(Proc, f)\n#     assert(f[1])\n#     assert(!f[0])\n#   end\n# \n#   def test_replace\n#     s = RestricedSet.new(-3..3) { |o| o > 0 }\n#     assert_equal([1,2,3], s.sort)\n# \n#     s.replace([-2,0,3,4,5])\n#     assert_equal([3,4,5], s.sort)\n#   end\n# \n#   def test_merge\n#     s = RestricedSet.new { |o| o > 0 }\n#     s.merge(-5..5)\n#     assert_equal([1,2,3,4,5], s.sort)\n# \n#     s.merge([10,-10,-8,8])\n#     assert_equal([1,2,3,4,5,8,10], s.sort)\n#   end\n# end\n"
  },
  {
    "path": "lib/shell/builtin-command.rb",
    "content": "#\n#   shell/builtin-command.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nrequire \"shell/filter\"\n\nclass Shell\n  class BuiltInCommand<Filter\n    def wait?\n      false\n    end\n    def active?\n      true\n    end\n  end\n\n  class Echo < BuiltInCommand\n    def initialize(sh, *strings)\n      super sh\n      @strings = strings\n    end\n    \n    def each(rs = nil)\n      rs =  @shell.record_separator unless rs\n      for str  in @strings\n\tyield str + rs\n      end\n    end\n  end\n\n  class Cat < BuiltInCommand\n    def initialize(sh, *filenames)\n      super sh\n      @cat_files = filenames\n    end\n\n    def each(rs = nil)\n      if @cat_files.empty?\n\tsuper\n      else\n\tfor src in @cat_files\n\t  @shell.foreach(src, rs){|l| yield l}\n\tend\n      end\n    end\n  end\n\n  class Glob < BuiltInCommand\n    def initialize(sh, pattern)\n      super sh\n\n      @pattern = pattern\n      Thread.critical = true\n      back = Dir.pwd\n      begin\n\tDir.chdir @shell.cwd\n\t@files = Dir[pattern]\n      ensure\n\tDir.chdir back\n\tThread.critical = false\n      end\n    end\n\n    def each(rs = nil)\n      rs =  @shell.record_separator unless rs\n      for f  in @files\n\tyield f+rs\n      end\n    end\n  end\n\n#   class Sort < Cat\n#     def initialize(sh, *filenames)\n#       super\n#     end\n#\n#     def each(rs = nil)\n#       ary = []\n#       super{|l|\tary.push l}\n#       for l in ary.sort!\n# \tyield l\n#       end\n#     end\n#   end\n\n  class AppendIO < BuiltInCommand\n    def initialize(sh, io, filter)\n      super sh\n      @input = filter\n      @io = io\n    end\n\n    def input=(filter)\n      @input.input=filter\n      for l in @input\n\t@io << l\n      end\n    end\n\n  end\n\n  class AppendFile < AppendIO\n    def initialize(sh, to_filename, filter)\n      @file_name = to_filename\n      io = sh.open(to_filename, \"a\")\n      super(sh, io, filter)\n    end\n\n    def input=(filter)\n      begin\n\tsuper\n      ensure\n\t@io.close\n      end\n    end\n  end\n\n  class Tee < BuiltInCommand\n    def initialize(sh, filename)\n      super sh\n      @to_filename = filename\n    end\n\n    def each(rs = nil)\n      to = @shell.open(@to_filename, \"w\")\n      begin\n\tsuper{|l| to << l; yield l}\n      ensure\n\tto.close\n      end\n    end\n  end\n\n  class Concat < BuiltInCommand\n    def initialize(sh, *jobs)\n      super(sh)\n      @jobs = jobs\n    end\n\n    def each(rs = nil)\n      while job = @jobs.shift\n\tjob.each{|l| yield l}\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/shell/command-processor.rb",
    "content": "#\n#   shell/command-controller.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nippon Rational Inc.)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\nrequire \"ftools\"\nrequire \"thread\"\n\nrequire \"shell/error\"\nrequire \"shell/filter\"\nrequire \"shell/system-command\"\nrequire \"shell/builtin-command\"\n\nclass Shell\n  class CommandProcessor\n#    include Error\n\n    #\n    # initialize of Shell and related classes.\n    #\n    NoDelegateMethods = [\"initialize\", \"expand_path\"]\n    def self.initialize\n\n      install_builtin_commands\n\n      # define CommandProccessor#methods to Shell#methods and Filter#methods\n      for m in CommandProcessor.instance_methods(false) - NoDelegateMethods\n\tadd_delegate_command_to_shell(m)\n      end\n      \n      def self.method_added(id)\n\tadd_delegate_command_to_shell(id)\n      end\n    end\n\n    #\n    # include run file.\n    #\n    def self.run_config\n      begin\n\tload File.expand_path(\"~/.rb_shell\") if ENV.key?(\"HOME\")\n      rescue LoadError, Errno::ENOENT\n      rescue\n\tprint \"load error: #{rc}\\n\"\n\tprint $!.class, \": \", $!, \"\\n\"\n\tfor err in $@[0, $@.size - 2]\n\t  print \"\\t\", err, \"\\n\"\n\tend\n      end\n    end\n\n    def initialize(shell)\n      @shell = shell\n      @system_commands = {}\n    end\n\n    #\n    # CommandProcessor#expand_path(path)\n    #\t  path:\t  String\n    #\t  return: String\n    #\treturns the absolute path for <path>\n    #\n    def expand_path(path)\n      @shell.expand_path(path)\n    end\n\n    #\n    # File related commands\n    # Shell#foreach\n    # Shell#open\n    # Shell#unlink\n    # Shell#test\n    #\n    # -\n    #\t\n    # CommandProcessor#foreach(path, rs)\n    #\t  path: String\n    #\t  rs:\tString - record separator\n    #\t  iterator\n    #\tSame as:\n    #\t  File#foreach (when path is file)\n    #\t  Dir#foreach (when path is directory)\n    #\tpath is relative to pwd\n    #\n    def foreach(path = nil, *rs)\n      path = \".\" unless path\n      path = expand_path(path)\n\n      if File.directory?(path)\n\tDir.foreach(path){|fn| yield fn}\n      else\n\tIO.foreach(path, *rs){|l| yield l}\n      end\n    end\n\n    #\n    # CommandProcessor#open(path, mode)\n    #\t  path:\t  String\n    #\t  mode:\t  String\n    #\t  return: File or Dir\n    #\tSame as:\n    #\t  File#open (when path is file)\n    #\t  Dir#open  (when path is directory)\n    #\tmode has an effect only when path is a file\n    #\n    def open(path, mode)\n      path = expand_path(path)\n      if File.directory?(path)\n\tDir.open(path)\n      else\n\teffect_umask do\n\t  File.open(path, mode)\n\tend\n      end\n    end\n    #  public :open\n\n    #\n    # CommandProcessor#unlink(path)\n    #\tsame as:\n    #\t  Dir#unlink  (when path is directory)\n    #\t  File#unlink (when path is file)\n    #\n    def unlink(path)\n      path = expand_path(path)\n      if File.directory?(path)\n\tDir.unlink(path)\n      else\n\tIO.unlink(path)\n      end\n    end\n\n    #\n    # CommandProcessor#test(command, file1, file2)\n    # CommandProcessor#[command, file1, file2]\n    #\t  command: char or String or Symbol\n    #\t  file1:   String\n    #\t  file2:   String(optional)\n    #\t  return: Boolean\n    #\tsame as:\n    #\t  test()\t   (when command is char or length 1 string or symbol)\n    #\t  FileTest.command (others)\n    #\texample:\n    #\t  sh[?e, \"foo\"]\n    #\t  sh[:e, \"foo\"]\n    #\t  sh[\"e\", \"foo\"]\n    #\t  sh[:exists?, \"foo\"]\n    #\t  sh[\"exists?\", \"foo\"]\n    #\t  \n    alias top_level_test test\n    def test(command, file1, file2=nil)\n      file1 = expand_path(file1)\n      file2 = expand_path(file2) if file2\n      command = command.id2name if command.kind_of?(Symbol)\n\n      case command\n      when Integer\n\tif file2\n\t  top_level_test(command, file1, file2)\n\telse\n\t  top_level_test(command, file1)\n\tend\n      when String\n\tif command.size == 1\n\t  if file2\n\t    top_level_test(command, file1, file2)\n\t  else\n\t    top_level_test(command, file1)\n\t  end\n\telse\n\t  if file2\n\t    FileTest.send(command, file1, file2)\n\t  else\n\t    FileTest.send(command, file1)\n\t  end\n\tend\n      end\n    end\n    alias [] test\n\n    #\n    # Dir related methods\n    #\n    # Shell#mkdir\n    # Shell#rmdir\n    #\n    #--\n    #\n    # CommandProcessor#mkdir(*path)\n    #\t  path: String\n    #\tsame as Dir.mkdir()\n    #\t  \n    def mkdir(*path)\n      for dir in path\n\tDir.mkdir(expand_path(dir))\n      end\n    end\n\n    #\n    # CommandProcessor#rmdir(*path)\n    #\t  path: String\n    #\tsame as Dir.rmdir()\n    #\t  \n    def rmdir(*path)\n      for dir in path\n\tDir.rmdir(expand_path(dir))\n      end\n    end\n\n    #\n    # CommandProcessor#system(command, *opts)\n    #\t  command: String\n    #\t  opts:\t   String\n    #\t  return:  SystemCommand\n    #\tSame as system() function\n    #\texample:\n    #\t  print sh.system(\"ls\", \"-l\")\n    #\t  sh.system(\"ls\", \"-l\") | sh.head > STDOUT\n    # \n    def system(command, *opts)\n      if opts.empty?\n\tif command =~ /\\*|\\?|\\{|\\}|\\[|\\]|<|>|\\(|\\)|~|&|\\||\\\\|\\$|;|'|`|\"|\\n/\n\t  return SystemCommand.new(@shell, find_system_command(\"sh\"), \"-c\", command)\n\telse\n\t  command, *opts = command.split(/\\s+/)\n\tend\n      end\n      SystemCommand.new(@shell, find_system_command(command), *opts)\n    end\n\n    #\n    # ProcessCommand#rehash\n    #\tclear command hash table.\n    #\n    def rehash\n      @system_commands = {}\n    end\n\n    #\n    # ProcessCommand#transact\n    #\n    def check_point\n      @shell.process_controller.wait_all_jobs_execution\n    end\n    alias finish_all_jobs check_point\n\n    def transact(&block)\n      begin\n\t@shell.instance_eval(&block)\n      ensure\n\tcheck_point\n      end\n    end\n\n    #\n    # internal commands\n    #\n    def out(dev = STDOUT, &block)\n      dev.print transact(&block)\n    end\n\n    def echo(*strings)\n      Echo.new(@shell, *strings)\n    end\n\n    def cat(*filenames)\n      Cat.new(@shell, *filenames)\n    end\n\n    #   def sort(*filenames)\n    #     Sort.new(self, *filenames)\n    #   end\n\n    def glob(pattern)\n      Glob.new(@shell, pattern)\n    end\n\n    def append(to, filter)\n      case to\n      when String\n\tAppendFile.new(@shell, to, filter)\n      when IO\n\tAppendIO.new(@shell, to, filter)\n      else\n\tShell.Fail Error::CantApplyMethod, \"append\", to.class\n      end\n    end\n\n    def tee(file)\n      Tee.new(@shell, file)\n    end\n\n    def concat(*jobs)\n      Concat.new(@shell, *jobs)\n    end\n\n    # %pwd, %cwd -> @pwd\n    def notify(*opts, &block)\n      Thread.exclusive do\n\tShell.notify(*opts) {|mes|\n\t  yield mes if iterator?\n\t\n\t  mes.gsub!(\"%pwd\", \"#{@cwd}\")\n\t  mes.gsub!(\"%cwd\", \"#{@cwd}\")\n\t}\n      end\n    end\n\n    #\n    # private functions\n    #\n    def effect_umask\n      if @shell.umask\n\tThread.critical = true\n\tsave = File.umask\n\tbegin\n\t  yield\n\tensure\n\t  File.umask save\n\t  Thread.critical = false\n\tend\n      else\n\tyield\n      end\n    end\n    private :effect_umask\n\n    def find_system_command(command)\n      return command if /^\\// =~ command\n      case path = @system_commands[command]\n      when String\n\tif exists?(path)\n\t  return path\n\telse\n\t  Shell.Fail Error::CommandNotFound, command\n\tend\n      when false\n\tShell.Fail Error::CommandNotFound, command\n      end\n\n      for p in @shell.system_path\n\tpath = join(p, command)\n\tif FileTest.exists?(path)\n\t  @system_commands[command] = path\n\t  return path\n\tend\n      end\n      @system_commands[command] = false\n      Shell.Fail Error::CommandNotFound, command\n    end\n\n    #\n    # CommandProcessor.def_system_command(command, path)\n    #\t  command:  String\n    #\t  path:\t    String\n    #\tdefine 'command()' method as method.\n    #\n    def self.def_system_command(command, path = command)\n      begin\n\teval((d = %Q[def #{command}(*opts)\n     \t          SystemCommand.new(@shell, '#{path}', *opts)\n               end]), nil, __FILE__, __LINE__ - 1)\n      rescue SyntaxError\n\tShell.notify \"warn: Can't define #{command} path: #{path}.\" \n      end\n      Shell.notify \"Define #{command} path: #{path}.\", Shell.debug?\n      Shell.notify(\"Definition of #{command}: \", d, \n\t     Shell.debug.kind_of?(Integer) && Shell.debug > 1)\n    end\n\n    def self.undef_system_command(command)\n      command = command.id2name if command.kind_of?(Symbol)\n      remove_method(command)\n      Shell.module_eval{remove_method(command)}\n      Filter.module_eval{remove_method(command)}\n      self\n    end\n\n    # define command alias\n    # ex)\n    # def_alias_command(\"ls_c\", \"ls\", \"-C\", \"-F\")\n    # def_alias_command(\"ls_c\", \"ls\"){|*opts| [\"-C\", \"-F\", *opts]}\n    #\n    @alias_map = {}\n    def self.alias_map\n      @alias_map\n    end\n    def self.alias_command(ali, command, *opts, &block)\n      ali = ali.id2name if ali.kind_of?(Symbol)\n      command = command.id2name if command.kind_of?(Symbol)\n      begin\n\tif iterator?\n\t  @alias_map[ali.intern] = proc\n\n\t  eval((d = %Q[def #{ali}(*opts)\n                          @shell.__send__(:#{command},\n                                          *(CommandProcessor.alias_map[:#{ali}].call *opts))\n\t                end]), nil, __FILE__, __LINE__ - 1)\n    \n\telse\n           args = opts.collect{|opt| '\"' + opt + '\"'}.join(\",\")\n           eval((d = %Q[def #{ali}(*opts)\n                          @shell.__send__(:#{command}, #{args}, *opts)\n                        end]), nil, __FILE__, __LINE__ - 1)\n\tend\n      rescue SyntaxError\n\tShell.notify \"warn: Can't alias #{ali} command: #{command}.\" \n\tShell.notify(\"Definition of #{ali}: \", d)\n\traise\n      end\n      Shell.notify \"Define #{ali} command: #{command}.\", Shell.debug?\n      Shell.notify(\"Definition of #{ali}: \", d, \n\t     Shell.debug.kind_of?(Integer) && Shell.debug > 1)\n      self\n    end\n   \n    def self.unalias_command(ali)\n      ali = ali.id2name if ali.kind_of?(Symbol)\n      @alias_map.delete ali.intern\n      undef_system_command(ali)\n    end\n   \n    #\n    # CommandProcessor.def_builtin_commands(delegation_class, command_specs)\n    #\t  delegation_class: Class or Module\n    #\t  command_specs: [[command_name, [argument,...]],...]\n    #\t     command_name: String\n    #\t     arguments:\t   String\n    #\t\tFILENAME?? -> expand_path(filename??)\n    #\t\t*FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(\", \")\n    #\tdefine command_name(argument,...) as\n    #\t    delegation_class.command_name(argument,...)\n    #\n    def self.def_builtin_commands(delegation_class, command_specs)\n      for meth, args in command_specs\n\targ_str = args.collect{|arg| arg.downcase}.join(\", \")\n\tcall_arg_str = args.collect{\n\t  |arg|\n\t  case arg\n\t  when /^(FILENAME.*)$/\n\t    format(\"expand_path(%s)\", $1.downcase)\n\t  when /^(\\*FILENAME.*)$/\n\t    # \\*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(\", \")\n\t    $1.downcase + '.collect{|fn| expand_path(fn)}'\n\t  else\n\t    arg\n\t  end\n\t}.join(\", \")\n\td = %Q[def #{meth}(#{arg_str})\n\t\t    #{delegation_class}.#{meth}(#{call_arg_str})\n\t\t end]\n\tShell.notify \"Define #{meth}(#{arg_str})\", Shell.debug?\n\tShell.notify(\"Definition of #{meth}: \", d, \n\t     Shell.debug.kind_of?(Integer) && Shell.debug > 1)\n\teval d\n      end\n    end\n\n    #\n    # CommandProcessor.install_system_commands(pre)\n    #\t    pre: String - command name prefix\n    # defines every command which belongs in default_system_path via\n    # CommandProcessor.command().  It doesn't define already defined\n    # methods twice.  By default, \"pre_\" is prefixes to each method\n    # name.  Characters that may not be used in a method name are\n    # all converted to '_'.  Definition errors are just ignored.\n    #\n    def self.install_system_commands(pre = \"sys_\")\n      defined_meth = {}\n      for m in Shell.methods\n\tdefined_meth[m] = true\n      end\n      sh = Shell.new\n      for path in Shell.default_system_path\n\tnext unless sh.directory? path\n\tsh.cd path\n\tsh.foreach do\n\t  |cn|\n\t  if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)\n\t    command = (pre + cn).gsub(/\\W/, \"_\").sub(/^([0-9])/, '_\\1')\n\t    begin\n\t      def_system_command(command, sh.expand_path(cn))\n\t    rescue\n\t      Shell.notify \"warn: Can't define #{command} path: #{cn}\"\n\t    end\n\t    defined_meth[command] = command\n\t  end\n\tend\n      end\n    end\n\n    #----------------------------------------------------------------------\n    #\n    #  class initializing methods  - \n    #\n    #----------------------------------------------------------------------\n    def self.add_delegate_command_to_shell(id)\n      id = id.intern if id.kind_of?(String)\n      name = id.id2name\n      if Shell.method_defined?(id)\n\tShell.notify \"warn: override definnition of Shell##{name}.\"\n\tShell.notify \"warn: alias Shell##{name} to Shell##{name}_org.\\n\"\n\tShell.module_eval \"alias #{name}_org #{name}\"\n      end\n      Shell.notify \"method added: Shell##{name}.\", Shell.debug?\n      Shell.module_eval(%Q[def #{name}(*args, &block)\n\t\t\t    begin\n\t\t\t      @command_processor.__send__(:#{name}, *args, &block)\n\t\t\t    rescue Exception\n\t\t\t      $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`\n\t                      $@.delete_if{|s| /^\\\\(eval\\\\):/ =~ s}\n\t\t\t    raise\n\t\t\t    end\n                          end], __FILE__, __LINE__)\n\n      if Shell::Filter.method_defined?(id)\n\tShell.notify \"warn: override definnition of Shell::Filter##{name}.\"\n\tShell.notify \"warn: alias Shell##{name} to Shell::Filter##{name}_org.\"\n\tFilter.module_eval \"alias #{name}_org #{name}\"\n      end\n      Shell.notify \"method added: Shell::Filter##{name}.\", Shell.debug?\n      Filter.module_eval(%Q[def #{name}(*args, &block)\n\t\t\t    begin\n\t\t\t      self | @shell.__send__(:#{name}, *args, &block)\n\t\t\t    rescue Exception\n\t\t\t      $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`\n\t                      $@.delete_if{|s| /^\\\\(eval\\\\):/ =~ s}\n\t\t\t    raise\n\t\t\t    end\n                          end], __FILE__, __LINE__)\n    end\n\n    #\n    # define default builtin commands\n    #\n    def self.install_builtin_commands\n      # method related File.\n      #\t(exclude open/foreach/unlink)\n      normal_delegation_file_methods = [\n\t[\"atime\", [\"FILENAME\"]],\n\t[\"basename\", [\"fn\", \"*opts\"]],\n\t[\"chmod\", [\"mode\", \"*FILENAMES\"]], \n\t[\"chown\", [\"owner\", \"group\", \"*FILENAME\"]],\n\t[\"ctime\", [\"FILENAMES\"]],\n\t[\"delete\", [\"*FILENAMES\"]],\n\t[\"dirname\", [\"FILENAME\"]],\n\t[\"ftype\", [\"FILENAME\"]],\n\t[\"join\", [\"*items\"]],\n\t[\"link\", [\"FILENAME_O\", \"FILENAME_N\"]],\n\t[\"lstat\", [\"FILENAME\"]],\n\t[\"mtime\", [\"FILENAME\"]],\n\t[\"readlink\", [\"FILENAME\"]],\n\t[\"rename\", [\"FILENAME_FROM\", \"FILENAME_TO\"]],\n\t#      [\"size\", [\"FILENAME\"]],\n\t[\"split\", [\"pathname\"]],\n\t[\"stat\", [\"FILENAME\"]],\n\t[\"symlink\", [\"FILENAME_O\", \"FILENAME_N\"]],\n\t[\"truncate\", [\"FILENAME\", \"length\"]],\n\t[\"utime\", [\"atime\", \"mtime\", \"*FILENAMES\"]]]\n\n      def_builtin_commands(File, normal_delegation_file_methods)\n      alias_method :rm, :delete\n\n      # method related FileTest\n      def_builtin_commands(FileTest, \n\t\t   FileTest.singleton_methods(false).collect{|m| [m, [\"FILENAME\"]]})\n\n      # method related ftools\n      normal_delegation_ftools_methods = [\n\t[\"syscopy\", [\"FILENAME_FROM\", \"FILENAME_TO\"]],\n\t[\"copy\", [\"FILENAME_FROM\", \"FILENAME_TO\"]],\n\t[\"move\", [\"FILENAME_FROM\", \"FILENAME_TO\"]],\n\t[\"compare\", [\"FILENAME_FROM\", \"FILENAME_TO\"]],\n\t[\"safe_unlink\", [\"*FILENAMES\"]],\n\t[\"makedirs\", [\"*FILENAMES\"]],\n\t#    [\"chmod\", [\"mode\", \"*FILENAMES\"]],\n\t[\"install\", [\"FILENAME_FROM\", \"FILENAME_TO\", \"mode\"]],\n      ]\n      def_builtin_commands(File,\n\t\t   normal_delegation_ftools_methods)\n      alias_method :cmp, :compare\n      alias_method :mv, :move\n      alias_method :cp, :copy\n      alias_method :rm_f, :safe_unlink\n      alias_method :mkpath, :makedirs\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/shell/error.rb",
    "content": "#\n#   shell/error.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\n\nclass Shell\n  module Error\n    extend Exception2MessageMapper\n    def_e2message TypeError, \"wrong argument type %s (expected %s)\"\n\n    def_exception :DirStackEmpty, \"Directory stack empty.\"\n    def_exception :CantDefine, \"Can't define method(%s, %s).\"\n    def_exception :CantApplyMethod, \"This method(%s) does not apply to this type(%s).\"\n    def_exception :CommandNotFound, \"Command not found(%s).\"\n  end\nend\n\n"
  },
  {
    "path": "lib/shell/filter.rb",
    "content": "#\n#   shell/filter.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nclass Shell\n  #\n  # Filter\n  # A method to require\n  #    each()\n  #\n  class Filter\n    include Enumerable\n\n    def initialize(sh)\n      @shell = sh\t  # parent shell\n      @input = nil\t  # input filter\n    end\n\n    attr_reader :input\n\n    def input=(filter)\n      @input = filter\n    end\n    \n    def each(rs = nil)\n      rs = @shell.record_separator unless rs\n      if @input\n\t@input.each(rs){|l| yield l}\n      end\n    end\n\n    def < (src)\n      case src\n      when String\n\tcat = Cat.new(@shell, src)\n\tcat | self\n      when IO\n\tself.input = src\n\tself\n      else\n\tShell.Fail Error::CantApplyMethod, \"<\", to.class\n      end\n    end\n\n    def > (to)\n      case to\n      when String\n\tdst = @shell.open(to, \"w\")\n\tbegin\n\t  each(){|l| dst << l}\n\tensure\n\t  dst.close\n\tend\n      when IO\n\teach(){|l| to << l}\n      else\n\tShell.Fail Error::CantApplyMethod, \">\", to.class\n      end\n      self\n    end\n\n    def >> (to)\n      begin\n\tShell.cd(@shell.pwd).append(to, self)\n      rescue CantApplyMethod\n\tShell.Fail Error::CantApplyMethod, \">>\", to.class\n      end\n    end\n\n    def | (filter)\n      filter.input = self\n      if active?\n\t@shell.process_controller.start_job filter\n      end\n      filter\n    end\n\n    def + (filter)\n      Join.new(@shell, self, filter)\n    end\n\n    def to_a\n      ary = []\n      each(){|l| ary.push l}\n      ary\n    end\n\n    def to_s\n      str = \"\"\n      each(){|l| str.concat l}\n      str\n    end\n\n    def inspect\n      if @shell.debug.kind_of?(Integer) && @shell.debug > 2\n\tsuper\n      else\n\tto_s\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/shell/process-controller.rb",
    "content": "#\n#   shell/process-controller.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nrequire \"mutex_m\"\nrequire \"monitor\"\nrequire \"sync\"\n\nclass Shell\n  class ProcessController\n\n    @ProcessControllers = {}\n    @ProcessControllers.extend Mutex_m\n\n    class<<self\n\n      def process_controllers_exclusive\n\tbegin\n\t  @ProcessControllers.lock unless Thread.critical \n\t  yield\n\tensure\n\t  @ProcessControllers.unlock unless Thread.critical \n\tend\n      end\n\n      def activate(pc)\n\tprocess_controllers_exclusive do\n\t  @ProcessControllers[pc] ||= 0\n\t  @ProcessControllers[pc] += 1\n\tend\n      end\n\n      def inactivate(pc)\n\tprocess_controllers_exclusive do\n\t  if @ProcessControllers[pc]\n\t    if (@ProcessControllers[pc] -= 1) == 0\n\t      @ProcessControllers.delete(pc)\n\t    end\n\t  end\n\tend\n      end\n\n      def each_active_object\n\tprocess_controllers_exclusive do\n\t  for ref in @ProcessControllers.keys\n\t    yield ref\n\t  end\n\tend\n      end\n    end\n\n    def initialize(shell)\n      @shell = shell\n      @waiting_jobs = []\n      @active_jobs = []\n      @jobs_sync = Sync.new\n\n      @job_monitor = Mutex.new\n      @job_condition = ConditionVariable.new\n    end\n\n    def jobs\n      jobs = []\n      @jobs_sync.synchronize(:SH) do\n\tjobs.concat @waiting_jobs\n\tjobs.concat @active_jobs\n      end\n      jobs\n    end\n\n    def active_jobs\n      @active_jobs\n    end\n\n    def waiting_jobs\n      @waiting_jobs\n    end\n    \n    def jobs_exist?\n      @jobs_sync.synchronize(:SH) do\n\t@active_jobs.empty? or @waiting_jobs.empty?\n      end\n    end\n\n    def active_jobs_exist?\n      @jobs_sync.synchronize(:SH) do\n\t@active_jobs.empty?\n      end\n    end\n\n    def waiting_jobs_exist?\n      @jobs_sync.synchronize(:SH) do\n\t@waiting_jobs.empty?\n      end\n    end\n\n    # schedule a command\n    def add_schedule(command)\n      @jobs_sync.synchronize(:EX) do\n\tProcessController.activate(self)\n\tif @active_jobs.empty?\n\t  start_job command\n\telse\n\t  @waiting_jobs.push(command)\n\tend\n      end\n    end\n\n    # start a job\n    def start_job(command = nil)\n      @jobs_sync.synchronize(:EX) do\n\tif command\n\t  return if command.active?\n\t  @waiting_jobs.delete command\n\telse\n\t  command = @waiting_jobs.shift\n\t  return unless command\n\tend\n\t@active_jobs.push command\n\tcommand.start\n\n\t# start all jobs that input from the job\n\tfor job in @waiting_jobs\n\t  start_job(job) if job.input == command\n\tend\n      end\n    end\n\n    def waiting_job?(job)\n      @jobs_sync.synchronize(:SH) do\n\t@waiting_jobs.include?(job)\n      end\n    end\n\n    def active_job?(job)\n      @jobs_sync.synchronize(:SH) do\n\t@active_jobs.include?(job)\n      end\n    end\n\n    # terminate a job\n    def terminate_job(command)\n      @jobs_sync.synchronize(:EX) do\n\t@active_jobs.delete command\n\tProcessController.inactivate(self)\n\tif @active_jobs.empty?\n\t  start_job\n\tend\n      end\n    end\n\n    # kill a job\n    def kill_job(sig, command)\n      @jobs_sync.synchronize(:SH) do\n\tif @waiting_jobs.delete command\n\t  ProcessController.inactivate(self)\n\t  return\n\telsif @active_jobs.include?(command)\n\t  begin\n\t    r = command.kill(sig)\n\t    ProcessController.inactivate(self)\n\t  rescue\n\t    print \"Shell: Warn: $!\\n\" if @shell.verbose?\n\t    return nil\n\t  end\n\t  @active_jobs.delete command\n\t  r\n\tend\n      end\n    end\n\n    # wait for all jobs to terminate\n    def wait_all_jobs_execution\n      @job_monitor.synchronize do\n\tbegin\n\t  while !jobs.empty?\n\t    @job_condition.wait(@job_monitor)\n\t  end\n\tensure\n\t  redo unless jobs.empty?\n\tend\n      end\n    end\n\n    # simple fork\n    def sfork(command, &block)\n      pipe_me_in, pipe_peer_out = IO.pipe\n      pipe_peer_in, pipe_me_out = IO.pipe\n      Thread.critical = true\n\n      STDOUT.flush\n      ProcessController.each_active_object do |pc|\n\tfor jobs in pc.active_jobs\n\t  jobs.flush\n\tend\n      end\n      \n      pid = fork {\n\tThread.critical = true\n\n\tThread.list.each do |th| \n\t  th.kill unless [Thread.main, Thread.current].include?(th)\n\tend\n\n\tSTDIN.reopen(pipe_peer_in)\n\tSTDOUT.reopen(pipe_peer_out)\n\n\tObjectSpace.each_object(IO) do |io| \n\t  if ![STDIN, STDOUT, STDERR].include?(io)\n\t    io.close unless io.closed?\n\t  end\n\tend\n\tyield\n      }\n\n      pipe_peer_in.close\n      pipe_peer_out.close\n      command.notify \"job(%name:##{pid}) start\", @shell.debug?\n      Thread.critical = false\n\n      th = Thread.start {\n\tThread.critical = true\n\tbegin\n\t  _pid = nil\n\t  command.notify(\"job(%id) start to waiting finish.\", @shell.debug?)\n\t  Thread.critical = false\n\t  _pid = Process.waitpid(pid, nil)\n\trescue Errno::ECHILD\n\t  command.notify \"warn: job(%id) was done already waitipd.\"\n\t  _pid = true\n\tensure\n\t  # when the process ends, wait until the command termintes\n\t  if _pid\n\t  else\n\t    command.notify(\"notice: Process finishing...\",\n\t\t\t   \"wait for Job[%id] to finish.\",\n\t\t\t   \"You can use Shell#transact or Shell#check_point for more safe execution.\")\n\t    redo\n\t  end\n\t  Thread.exclusive do\n\t    @job_monitor.synchronize do \n\t      terminate_job(command)\n\t      @job_condition.signal\n\t      command.notify \"job(%id) finish.\", @shell.debug?\n\t    end\n\t  end\n\tend\n      }\n      return pid, pipe_me_in, pipe_me_out\n    end\n  end\nend\n"
  },
  {
    "path": "lib/shell/system-command.rb",
    "content": "#\n#   shell/system-command.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nrequire \"shell/filter\"\n\nclass Shell\n  class SystemCommand < Filter\n    def initialize(sh, command, *opts)\n      if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}\n\tShell.Fail Error::TypeError, t.class, \"String\"\n      end\n      super(sh)\n      @command = command\n      @opts = opts\n      \n      @input_queue = Queue.new\n      @pid = nil\n\n      sh.process_controller.add_schedule(self)\n    end\n\n    attr_reader :command\n    alias name command\n\n    def wait?\n      @shell.process_controller.waiting_job?(self)\n    end\n\n    def active?\n      @shell.process_controller.active_job?(self)\n    end\n\n    def input=(inp)\n      super\n      if active?\n\tstart_export\n      end\n    end\n\n    def start\n      @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {\n\tDir.chdir @shell.pwd\n\texec(@command, *@opts)\n      }\n      if @input\n\tstart_export\n      end\n      start_import\n    end\n\n    def flush\n      @pipe_out.flush if @pipe_out and !@pipe_out.closed?\n    end\n\n    def terminate\n      begin\n\t@pipe_in.close\n      rescue IOError\n      end\n      begin\n\t@pipe_out.close\n      rescue IOError\n      end\n    end\n\n    def kill(sig)\n      if @pid\n\tProcess.kill(sig, @pid)\n      end\n    end\n\n\n    def start_import\n#      Thread.critical = true\n      notify \"Job(%id) start imp-pipe.\", @shell.debug?\n      rs = @shell.record_separator unless rs\n      _eop = true\n#      Thread.critical = false\n      th = Thread.start {\n\tThread.critical = true\n\tbegin\n\t  Thread.critical = false\n\t  while l = @pipe_in.gets\n\t    @input_queue.push l\n\t  end\n\t  _eop = false\n\trescue Errno::EPIPE\n\t  _eop = false\n\tensure\n\t  if _eop\n\t    notify(\"warn: Process finishing...\",\n\t\t   \"wait for Job[%id] to finish pipe importing.\",\n\t\t   \"You can use Shell#transact or Shell#check_point for more safe execution.\")\n#\t    Tracer.on\n\t    Thread.current.run\n\t    redo\n\t  end\n\t  Thread.exclusive do\n\t    notify \"job(%id}) close imp-pipe.\", @shell.debug?\n\t    @input_queue.push :EOF\n\t    @pipe_in.close\n\t  end\n\tend\n      }\n    end\n\n    def start_export\n      notify \"job(%id) start exp-pipe.\", @shell.debug?\n      _eop = true\n      th = Thread.start{\n\tThread.critical = true\n\tbegin\n\t  Thread.critical = false\n\t  @input.each{|l| @pipe_out.print l}\n\t  _eop = false\n\trescue Errno::EPIPE\n\t  _eop = false\n\tensure\n\t  if _eop\n\t    notify(\"shell: warn: Process finishing...\",\n\t\t   \"wait for Job(%id) to finish pipe exporting.\",\n\t\t   \"You can use Shell#transact or Shell#check_point for more safe execution.\")\n#\t    Tracer.on\n\t    redo\n\t  end\n\t  Thread.exclusive do\n\t    notify \"job(%id) close exp-pipe.\", @shell.debug?\n\t    @pipe_out.close\n\t  end\n\tend\n      }\n    end\n\n    alias super_each each\n    def each(rs = nil)\n      while (l = @input_queue.pop) != :EOF\n\tyield l\n      end\n    end\n\n    # ex)\n    #    if you wish to output: \n    #\t    \"shell: job(#{@command}:#{@pid}) close pipe-out.\"\n    #\t then \n    #\t    mes: \"job(%id) close pipe-out.\"\n    #    yorn: Boolean(@shell.debug? or @shell.verbose?)\n    def notify(*opts, &block)\n      Thread.exclusive do\n\t@shell.notify(*opts) {|mes|\n\t  yield mes if iterator?\n\n\t  mes.gsub!(\"%id\", \"#{@command}:##{@pid}\")\n\t  mes.gsub!(\"%name\", \"#{@command}\")\n\t  mes.gsub!(\"%pid\", \"#{@pid}\")\n\t}\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/shell/version.rb",
    "content": "#\n#   version.rb - shell version definition file\n#   \t$Release Version: 0.6.0$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)\n#\n# --\n#\n#   \n#\n\nclass Shell\n  @RELEASE_VERSION = \"0.6.0\"\n  @LAST_UPDATE_DATE = \"01/03/19\"\nend\n"
  },
  {
    "path": "lib/shell.rb",
    "content": "#\n#   shell.rb - \n#   \t$Release Version: 0.6.0 $\n#   \t$Revision: 1.8 $\n#   \t$Date: 2001/03/19 09:01:11 $\n#   \tby Keiju ISHITSUKA(Nippon Rational Inc.)\n#\n# --\n#\n#   \n#\n\nrequire \"e2mmap\"\nrequire \"thread\"\n\nrequire \"shell/error\"\nrequire \"shell/command-processor\"\nrequire \"shell/process-controller\"\n\nclass Shell\n  @RCS_ID='-$Id: shell.rb,v 1.8 2001/03/19 09:01:11 keiju Exp keiju $-'\n\n  include Error\n  extend Exception2MessageMapper\n\n#  @cascade = true\n  # debug: true -> normal debug\n  # debug: 1    -> eval definition debug\n  # debug: 2    -> detail inspect debug\n  @debug = false\n  @verbose = true\n\n  class << Shell\n    attr :cascade, true\n    attr :debug, true\n    attr :verbose, true\n\n#    alias cascade? cascade\n    alias debug? debug\n    alias verbose? verbose\n    @verbose = true\n\n    def debug=(val)\n      @debug = val\n      @verbose = val if val\n    end\n\n    def cd(path)\n      sh = new\n      sh.cd path\n      sh\n    end\n\n    def default_system_path\n      if @default_system_path\n\t@default_system_path\n      else\n\tENV[\"PATH\"].split(\":\")\n      end\n    end\n\n    def default_system_path=(path)\n      @default_system_path = path\n    end\n\n    def default_record_separator\n      if @default_record_separator\n\t@default_record_separator\n      else\n\t$/\n      end\n    end\n\n    def default_record_separator=(rs)\n      @default_record_separator = rs\n    end\n  end\n\n  def initialize\n    @cwd = Dir.pwd\n    @dir_stack = []\n    @umask = nil\n\n    @system_path = Shell.default_system_path\n    @record_separator = Shell.default_record_separator\n\n    @command_processor = CommandProcessor.new(self)\n    @process_controller = ProcessController.new(self)\n\n    @verbose = Shell.verbose\n    @debug = Shell.debug\n  end\n\n  attr_reader :system_path\n\n  def system_path=(path)\n    @system_path = path\n    rehash\n  end\n\n  attr :umask, true\n  attr :record_separator, true\n\n  attr :verbose, true\n  attr :debug, true\n\n  def debug=(val)\n    @debug = val\n    @verbose = val if val\n  end\n\n  alias verbose? verbose\n  alias debug? debug\n\n  attr_reader :command_processor\n  attr_reader :process_controller\n\n  def expand_path(path)\n    File.expand_path(path, @cwd)\n  end\n\n  # Most Shell commands are defined via CommandProcessor\n\n  #\n  # Dir related methods\n  #\n  # Shell#cwd/dir/getwd/pwd\n  # Shell#chdir/cd\n  # Shell#pushdir/pushd\n  # Shell#popdir/popd\n  # Shell#mkdir\n  # Shell#rmdir\n\n  attr :cwd\n  alias dir cwd\n  alias getwd cwd\n  alias pwd cwd\n\n  attr :dir_stack\n  alias dirs dir_stack\n\n  # If called as iterator, it restores the current directory when the\n  # block ends.\n  def chdir(path = nil)\n    if iterator?\n      cwd_old = @cwd\n      begin\n\tchdir(path)\n\tyield\n      ensure\n\tchdir(cwd_old)\n      end\n    else\n      path = \"~\" unless path\n      @cwd = expand_path(path)\n      notify \"current dir: #{@cwd}\"\n      rehash\n      self\n    end\n  end\n  alias cd chdir\n\n  def pushdir(path = nil)\n    if iterator?\n      pushdir(path)\n      begin\n\tyield\n      ensure\n\tpopdir\n      end\n    elsif path\n      @dir_stack.push @cwd\n      chdir path\n      notify \"dir stack: [#{@dir_stack.join ', '}]\"\n      self\n    else\n      if pop = @dir_stack.pop\n\t@dir_stack.push @cwd\n\tchdir pop\n\tnotify \"dir stack: [#{@dir_stack.join ', '}]\"\n\tself\n      else\n\tShell.Fail DirStackEmpty\n      end\n    end\n  end\n  alias pushd pushdir\n\n  def popdir\n    if pop = @dir_stack.pop\n      chdir pop\n      notify \"dir stack: [#{@dir_stack.join ', '}]\"\n      self\n    else\n      Shell.Fail DirStackEmpty\n    end\n  end\n  alias popd popdir\n\n\n  #\n  # process management\n  #\n  def jobs\n    @process_controller.jobs\n  end\n\n  def kill(sig, command)\n    @process_controller.kill_job(sig, command)\n  end\n\n  #\n  # command definitions\n  #\n  def Shell.def_system_command(command, path = command)\n    CommandProcessor.def_system_command(command, path)\n  end\n\n  def Shell.undef_system_command(command)\n    CommandProcessor.undef_system_command(command)\n  end\n\n  def Shell.alias_command(ali, command, *opts, &block)\n    CommandProcessor.alias_command(ali, command, *opts, &block)\n  end\n\n  def Shell.unalias_command(ali)\n    CommandProcessor.unalias_command(ali)\n  end\n\n  def Shell.install_system_commands(pre = \"sys_\")\n    CommandProcessor.install_system_commands(pre)\n  end\n\n  #\n  def inspect\n    if debug.kind_of?(Integer) && debug > 2\n      super\n    else\n      to_s\n    end\n  end\n\n  def self.notify(*opts, &block)\n    Thread.exclusive do\n    if opts[-1].kind_of?(String)\n      yorn = verbose?\n    else\n      yorn = opts.pop\n    end\n    return unless yorn\n\n    _head = true\n    print opts.collect{|mes|\n      mes = mes.dup\n      yield mes if iterator?\n      if _head\n\t_head = false\n\t\"shell: \" + mes\n      else\n\t\"       \" + mes\n      end\n    }.join(\"\\n\")+\"\\n\"\n    end\n  end\n\n  CommandProcessor.initialize\n  CommandProcessor.run_config\nend\n"
  },
  {
    "path": "lib/shellwords.rb",
    "content": "#\n# shellwords.rb: Manipulates strings a la UNIX Bourne shell\n#\n\n#\n# This module manipulates strings according to the word parsing rules\n# of the UNIX Bourne shell.\n#\n# The shellwords() function was originally a port of shellwords.pl,\n# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).\n#\n# Authors:\n#   - Wakou Aoyama\n#   - Akinori MUSHA <knu@iDaemons.org>\n#\n# Contact:\n#   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)\n#\nmodule Shellwords\n  #\n  # Splits a string into an array of tokens in the same way the UNIX\n  # Bourne shell does.\n  #\n  #   argv = Shellwords.split('here are \"two words\"')\n  #   argv #=> [\"here\", \"are\", \"two words\"]\n  #\n  # +String#shellsplit+ is a shorthand for this function.\n  #\n  #   argv = 'here are \"two words\"'.shellsplit\n  #   argv #=> [\"here\", \"are\", \"two words\"]\n  #\n  def shellsplit(line)\n    line = String.new(line) rescue\n      raise(ArgumentError, \"Argument must be a string\")\n    line.lstrip!\n    words = []\n    until line.empty?\n      field = ''\n      loop do\n\tif line.sub!(/\\A\"(([^\"\\\\]|\\\\.)*)\"/, '') then\n\t  snippet = $1.gsub(/\\\\(.)/, '\\1')\n\telsif line =~ /\\A\"/ then\n\t  raise ArgumentError, \"Unmatched double quote: #{line}\"\n\telsif line.sub!(/\\A'([^']*)'/, '') then\n\t  snippet = $1\n\telsif line =~ /\\A'/ then\n\t  raise ArgumentError, \"Unmatched single quote: #{line}\"\n\telsif line.sub!(/\\A\\\\(.)?/, '') then\n\t  snippet = $1 || '\\\\'\n\telsif line.sub!(/\\A([^\\s\\\\'\"]+)/, '') then\n\t  snippet = $1\n\telse\n\t  line.lstrip!\n\t  break\n\tend\n\tfield.concat(snippet)\n      end\n      words.push(field)\n    end\n    words\n  end\n\n  alias shellwords shellsplit\n\n  module_function :shellsplit, :shellwords\n\n  class << self\n    alias split shellsplit\n  end\n\n  #\n  # Escapes a string so that it can be safely used in a Bourne shell\n  # command line.\n  #\n  # Note that a resulted string should be used unquoted and is not\n  # intended for use in double quotes nor in single quotes.\n  #\n  #   open(\"| grep #{Shellwords.escape(pattern)} file\") { |pipe|\n  #     # ...\n  #   }\n  #\n  # +String#shellescape+ is a shorthand for this function.\n  #\n  #   open(\"| grep #{pattern.shellescape} file\") { |pipe|\n  #     # ...\n  #   }\n  #\n  def shellescape(str)\n    # An empty argument will be skipped, so return empty quotes.\n    return \"''\" if str.empty?\n\n    str = str.dup\n\n    # Process as a single byte sequence because not all shell\n    # implementations are multibyte aware.\n    str.gsub!(/([^A-Za-z0-9_\\-.,:\\/@\\n])/n, \"\\\\\\\\\\\\1\")\n\n    # A LF cannot be escaped with a backslash because a backslash + LF\n    # combo is regarded as line continuation and simply ignored.\n    str.gsub!(/\\n/, \"'\\n'\")\n\n    return str\n  end\n\n  module_function :shellescape\n\n  class << self\n    alias escape shellescape\n  end\n\n  #\n  # Builds a command line string from an argument list +array+ joining\n  # all elements escaped for Bourne shell and separated by a space.\n  #\n  #   open('|' + Shellwords.join(['grep', pattern, *files])) { |pipe|\n  #     # ...\n  #   }\n  #\n  # +Array#shelljoin+ is a shorthand for this function.\n  #\n  #   open('|' + ['grep', pattern, *files].shelljoin) { |pipe|\n  #     # ...\n  #   }\n  #\n  def shelljoin(array)\n    array.map { |arg| shellescape(arg) }.join(' ')\n  end\n\n  module_function :shelljoin\n\n  class << self\n    alias join shelljoin\n  end\nend\n\nclass String\n  #\n  # call-seq:\n  #   str.shellsplit => array\n  #\n  # Splits +str+ into an array of tokens in the same way the UNIX\n  # Bourne shell does.  See +Shellwords::shellsplit+ for details.\n  #\n  def shellsplit\n    Shellwords.split(self)\n  end\n\n  #\n  # call-seq:\n  #   str.shellescape => string\n  #\n  # Escapes +str+ so that it can be safely used in a Bourne shell\n  # command line.  See +Shellwords::shellescape+ for details.\n  #\n  def shellescape\n    Shellwords.escape(self)\n  end\nend\n\nclass Array\n  #\n  # call-seq:\n  #   array.shelljoin => string\n  #\n  # Builds a command line string from an argument list +array+ joining\n  # all elements escaped for Bourne shell and separated by a space.\n  # See +Shellwords::shelljoin+ for details.\n  #\n  def shelljoin\n    Shellwords.join(self)\n  end\nend\n"
  },
  {
    "path": "lib/singleton.rb",
    "content": "# The Singleton module implements the Singleton pattern.\n#\n# Usage:\n#    class Klass\n#       include Singleton\n#       # ...\n#    end\n#\n# *  this ensures that only one instance of Klass lets call it\n#    ``the instance'' can be created.\n#\n#    a,b  = Klass.instance, Klass.instance\n#    a == b   # => true\n#    a.new    #  NoMethodError - new is private ...\n#\n# *  ``The instance'' is created at instantiation time, in other\n#    words the first call of Klass.instance(), thus\n#\n#      class OtherKlass\n#        include Singleton\n#        # ...\n#      end\n#      ObjectSpace.each_object(OtherKlass){} # => 0.\n#\n# *  This behavior is preserved under inheritance and cloning.\n#\n#\n#\n# This is achieved by marking\n# *  Klass.new and Klass.allocate - as private\n#\n# Providing (or modifying) the class methods\n# *  Klass.inherited(sub_klass) and Klass.clone()  -\n#    to ensure that the Singleton pattern is properly\n#    inherited and cloned.\n#\n# *  Klass.instance()  -  returning ``the instance''. After a\n#    successful self modifying (normally the first) call the\n#    method body is a simple:\n#\n#       def Klass.instance()\n#         return @__instance__\n#       end\n#\n# *  Klass._load(str)  -  calling Klass.instance()\n#\n# *  Klass._instantiate?()  -  returning ``the instance'' or\n#    nil. This hook method puts a second (or nth) thread calling\n#    Klass.instance() on a waiting loop. The return value\n#    signifies the successful completion or premature termination\n#    of the first, or more generally, current \"instantiation thread\".\n#\n#\n# The instance method of Singleton are\n# * clone and dup - raising TypeErrors to prevent cloning or duping\n#\n# *  _dump(depth) - returning the empty string.  Marshalling strips\n#    by default all state information, e.g. instance variables and\n#    taint state, from ``the instance''.  Providing custom _load(str)\n#    and _dump(depth) hooks allows the (partially) resurrections of\n#    a previous state of ``the instance''.\n\n\n\nmodule Singleton\n  #  disable build-in copying methods\n  def clone\n    raise TypeError, \"can't clone instance of singleton #{self.class}\"\n  end\n  def dup\n    raise TypeError, \"can't dup instance of singleton #{self.class}\"\n  end\n\n  #  default marshalling strategy\n  def _dump(depth=-1)\n    ''\n  end\nend\n\n\nclass << Singleton\n  #  Method body of first instance call.\n  FirstInstanceCall = proc do\n    #  @__instance__ takes on one of the following values\n    #  * nil     -  before and after a failed creation\n    #  * false  -  during creation\n    #  * sub_class instance  -  after a successful creation\n    #  the form makes up for the lack of returns in progs\n    Thread.critical = true\n    if  @__instance__.nil?\n      @__instance__  = false\n      Thread.critical = false\n      begin\n        @__instance__ = new\n      ensure\n        if @__instance__\n          class <<self\n            remove_method :instance\n            def instance; @__instance__ end\n          end\n        else\n          @__instance__ = nil #  failed instance creation\n        end\n      end\n    elsif  _instantiate?()\n      Thread.critical = false\n    else\n      @__instance__  = false\n      Thread.critical = false\n      begin\n        @__instance__ = new\n      ensure\n        if @__instance__\n          class <<self\n            remove_method :instance\n            def instance; @__instance__ end\n          end\n        else\n          @__instance__ = nil\n        end\n      end\n    end\n    @__instance__\n  end\n\n  module SingletonClassMethods\n    # properly clone the Singleton pattern - did you know\n    # that duping doesn't copy class methods?\n    def clone\n      Singleton.__init__(super)\n    end\n\n    def _load(str)\n      instance\n    end\n\n    private\n\n    #  ensure that the Singleton pattern is properly inherited\n    def inherited(sub_klass)\n      super\n      Singleton.__init__(sub_klass)\n    end\n\n    # waiting-loop hook\n    def _instantiate?()\n      while false.equal?(@__instance__)\n        Thread.critical = false\n        sleep(0.08)   # timeout\n        Thread.critical = true\n      end\n      @__instance__\n    end\n  end\n\n  def __init__(klass)\n    klass.instance_eval { @__instance__ = nil }\n    class << klass\n      define_method(:instance,FirstInstanceCall)\n    end\n    klass\n  end\n\n  private\n  #  extending an object with Singleton is a bad idea\n  undef_method :extend_object\n\n  def append_features(mod)\n    #  help out people counting on transitive mixins\n    unless mod.instance_of?(Class)\n      raise TypeError, \"Inclusion of the OO-Singleton module in module #{mod}\"\n    end\n    super\n  end\n\n  def included(klass)\n    super\n    klass.private_class_method  :new, :allocate\n    klass.extend SingletonClassMethods\n    Singleton.__init__(klass)\n  end\nend\n\n\n\nif __FILE__ == $0\n\ndef num_of_instances(klass)\n    \"#{ObjectSpace.each_object(klass){}} #{klass} instance(s)\"\nend\n\n# The basic and most important example.\n\nclass SomeSingletonClass\n  include Singleton\nend\nputs \"There are #{num_of_instances(SomeSingletonClass)}\"\n\na = SomeSingletonClass.instance\nb = SomeSingletonClass.instance # a and b are same object\nputs \"basic test is #{a == b}\"\n\nbegin\n  SomeSingletonClass.new\nrescue  NoMethodError => mes\n  puts mes\nend\n\n\n\nputs \"\\nThreaded example with exception and customized #_instantiate?() hook\"; p\nThread.abort_on_exception = false\n\nclass Ups < SomeSingletonClass\n  def initialize\n    self.class.__sleep\n    puts \"initialize called by thread ##{Thread.current[:i]}\"\n  end\nend\n\nclass << Ups\n  def _instantiate?\n    @enter.push Thread.current[:i]\n    while false.equal?(@__instance__)\n      Thread.critical = false\n      sleep 0.08\n      Thread.critical = true\n    end\n    @leave.push Thread.current[:i]\n    @__instance__\n  end\n\n  def __sleep\n    sleep(rand(0.08))\n  end\n\n  def new\n    begin\n      __sleep\n      raise  \"boom - thread ##{Thread.current[:i]} failed to create instance\"\n    ensure\n      # simple flip-flop\n      class << self\n        remove_method :new\n      end\n    end\n  end\n\n  def instantiate_all\n    @enter = []\n    @leave = []\n    1.upto(9) {|i|\n      Thread.new {\n        begin\n          Thread.current[:i] = i\n          __sleep\n          instance\n        rescue RuntimeError => mes\n          puts mes\n        end\n      }\n    }\n    puts \"Before there were #{num_of_instances(self)}\"\n    sleep 3\n    puts \"Now there is #{num_of_instances(self)}\"\n    puts \"#{@enter.join '; '} was the order of threads entering the waiting loop\"\n    puts \"#{@leave.join '; '} was the order of threads leaving the waiting loop\"\n  end\nend\n\n\nUps.instantiate_all\n# results in message like\n# Before there were 0 Ups instance(s)\n# boom - thread #6 failed to create instance\n# initialize called by thread #3\n# Now there is 1 Ups instance(s)\n# 3; 2; 1; 8; 4; 7; 5 was the order of threads entering the waiting loop\n# 3; 2; 1; 7; 4; 8; 5 was the order of threads leaving the waiting loop\n\n\nputs \"\\nLets see if class level cloning really works\"\nYup = Ups.clone\ndef Yup.new\n  begin\n    __sleep\n    raise  \"boom - thread ##{Thread.current[:i]} failed to create instance\"\n  ensure\n    # simple flip-flop\n    class << self\n      remove_method :new\n    end\n  end\nend\nYup.instantiate_all\n\n\nputs \"\\n\\n\",\"Customized marshalling\"\nclass A\n  include Singleton\n  attr_accessor :persist, :die\n  def _dump(depth)\n    # this strips the @die information from the instance\n    Marshal.dump(@persist,depth)\n  end\nend\n\ndef A._load(str)\n  instance.persist = Marshal.load(str)\n  instance\nend\n\na = A.instance\na.persist = [\"persist\"]\na.die = \"die\"\na.taint\n\nstored_state = Marshal.dump(a)\n# change state\na.persist = nil\na.die = nil\nb = Marshal.load(stored_state)\np a == b  #  => true\np a.persist  #  => [\"persist\"]\np a.die      #  => nil\n\n\nputs \"\\n\\nSingleton with overridden default #inherited() hook\"\nclass Up\nend\ndef Up.inherited(sub_klass)\n  puts \"#{sub_klass} subclasses #{self}\"\nend\n\n\nclass Middle < Up\n  include Singleton\nend\n\nclass Down < Middle; end\n\nputs  \"and basic \\\"Down test\\\" is #{Down.instance == Down.instance}\\n\nVarious exceptions\"\n\nbegin\n  module AModule\n    include Singleton\n  end\nrescue TypeError => mes\n  puts mes  #=> Inclusion of the OO-Singleton module in module AModule\nend\n\nbegin\n  'aString'.extend Singleton\nrescue NoMethodError => mes\n  puts mes  #=> undefined method `extend_object' for Singleton:Module\nend\n\nend\n"
  },
  {
    "path": "lib/soap/attachment.rb",
    "content": "# soap/attachment.rb: SOAP4R - SwA implementation.\n# Copyright (C) 2002, 2003  Jamie Herre and NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/baseData'\nrequire 'soap/mapping'\n\n\nmodule SOAP\n\n\nclass SOAPAttachment < SOAPExternalReference\n  attr_reader :data\n\n  def initialize(value)\n    super()\n    @data = value\n  end\n\nprivate\n\n  def external_contentid\n    @data.contentid\n  end\nend\n\n\nclass Attachment\n  attr_reader :io\n  attr_accessor :contenttype\n\n  def initialize(string_or_readable = nil)\n    @string_or_readable = string_or_readable\n    @contenttype = \"application/octet-stream\"\n    @contentid = nil\n  end\n\n  def contentid\n    @contentid ||= Attachment.contentid(self)\n  end\n\n  def contentid=(contentid)\n    @contentid = contentid\n  end\n\n  def mime_contentid\n    '<' + contentid + '>'\n  end\n\n  def content\n    if @content == nil and @string_or_readable != nil\n      @content = @string_or_readable.respond_to?(:read) ?\n\t@string_or_readable.read : @string_or_readable\n    end\n    @content\n  end\n\n  def to_s\n    content\n  end\n\n  def write(out)\n    out.write(content)\n  end\n\n  def save(filename)\n    File.open(filename, \"wb\") do |f|\n      write(f)\n    end\n  end\n\n  def self.contentid(obj)\n    # this needs to be fixed\n    [obj.__id__.to_s, Process.pid.to_s].join('.')\n  end\n\n  def self.mime_contentid(obj)\n    '<' + contentid(obj) + '>'\n  end\nend\n\n\nmodule Mapping\n  class AttachmentFactory < SOAP::Mapping::Factory\n    def obj2soap(soap_class, obj, info, map)\n      soap_obj = soap_class.new(obj)\n      mark_marshalled_obj(obj, soap_obj)\n      soap_obj\n    end\n\n    def soap2obj(obj_class, node, info, map)\n      obj = node.data\n      mark_unmarshalled_obj(node, obj)\n      return true, obj\n    end\n  end\n\n  DefaultRegistry.add(::SOAP::Attachment, ::SOAP::SOAPAttachment,\n    AttachmentFactory.new, nil)\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/baseData.rb",
    "content": "# soap/baseData.rb: SOAP4R - Base type library\n# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/datatypes'\nrequire 'soap/soap'\n\n\nmodule SOAP\n\n\n###\n## Mix-in module for SOAP base type classes.\n#\nmodule SOAPModuleUtils\n  include SOAP\n\npublic\n\n  def decode(elename)\n    d = self.new\n    d.elename = elename\n    d\n  end\nend\n\n\n###\n## for SOAP type(base and compound)\n#\nmodule SOAPType\n  attr_accessor :encodingstyle\n  attr_accessor :elename\n  attr_accessor :id\n  attr_reader :precedents\n  attr_accessor :root\n  attr_accessor :parent\n  attr_accessor :position\n  attr_reader :extraattr\n  attr_accessor :definedtype\n\n  def initialize(*arg)\n    super\n    @encodingstyle = nil\n    @elename = XSD::QName::EMPTY\n    @id = nil\n    @precedents = []\n    @root = false\n    @parent = nil\n    @position = nil\n    @definedtype = nil\n    @extraattr = {}\n  end\n\n  def inspect\n    if self.is_a?(XSD::NSDBase)\n      sprintf(\"#<%s:0x%x %s %s>\", self.class.name, __id__, self.elename, self.type)\n    else\n      sprintf(\"#<%s:0x%x %s>\", self.class.name, __id__, self.elename)\n    end\n  end\n\n  def rootnode\n    node = self\n    while node = node.parent\n      break if SOAPEnvelope === node\n    end\n    node\n  end\nend\n\n\n###\n## for SOAP base type\n#\nmodule SOAPBasetype\n  include SOAPType\n  include SOAP\n\n  def initialize(*arg)\n    super\n  end\nend\n\n\n###\n## for SOAP compound type\n#\nmodule SOAPCompoundtype\n  include SOAPType\n  include SOAP\n\n  def initialize(*arg)\n    super\n  end\nend\n\n\n###\n## Convenience datatypes.\n#\nclass SOAPReference < XSD::NSDBase\n  include SOAPBasetype\n  extend SOAPModuleUtils\n\npublic\n\n  attr_accessor :refid\n\n  # Override the definition in SOAPBasetype.\n  def initialize(obj = nil)\n    super()\n    @type = XSD::QName::EMPTY\n    @refid = nil\n    @obj = nil\n    __setobj__(obj) if obj\n  end\n\n  def __getobj__\n    @obj\n  end\n\n  def __setobj__(obj)\n    @obj = obj\n    @refid = @obj.id || SOAPReference.create_refid(@obj)\n    @obj.id = @refid unless @obj.id\n    @obj.precedents << self\n    # Copies NSDBase information\n    @obj.type = @type unless @obj.type\n  end\n\n  # Why don't I use delegate.rb?\n  # -> delegate requires target object type at initialize time.\n  # Why don't I use forwardable.rb?\n  # -> forwardable requires a list of forwarding methods.\n  #\n  # ToDo: Maybe I should use forwardable.rb and give it a methods list like\n  # delegate.rb...\n  #\n  def method_missing(msg_id, *params)\n    if @obj\n      @obj.send(msg_id, *params)\n    else\n      nil\n    end\n  end\n\n  def refidstr\n    '#' + @refid\n  end\n\n  def self.create_refid(obj)\n    'id' + obj.__id__.to_s\n  end\n\n  def self.decode(elename, refidstr)\n    if /\\A#(.*)\\z/ =~ refidstr\n      refid = $1\n    elsif /\\Acid:(.*)\\z/ =~ refidstr\n      refid = $1\n    else\n      raise ArgumentError.new(\"illegal refid #{refidstr}\")\n    end\n    d = super(elename)\n    d.refid = refid\n    d\n  end\nend\n\n\nclass SOAPExternalReference < XSD::NSDBase\n  include SOAPBasetype\n  extend SOAPModuleUtils\n\n  def initialize\n    super()\n    @type = XSD::QName::EMPTY\n  end\n\n  def referred\n    rootnode.external_content[external_contentid] = self\n  end\n\n  def refidstr\n    'cid:' + external_contentid\n  end\n\nprivate\n\n  def external_contentid\n    raise NotImplementedError.new\n  end\nend\n\n\nclass SOAPNil < XSD::XSDNil\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\n# SOAPRawString is for sending raw string.  In contrast to SOAPString,\n# SOAP4R does not do XML encoding and does not convert its CES.  The string it\n# holds is embedded to XML instance directly as a 'xsd:string'.\nclass SOAPRawString < XSD::XSDString\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\n\n###\n## Basic datatypes.\n#\nclass SOAPAnySimpleType < XSD::XSDAnySimpleType\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPString < XSD::XSDString\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPBoolean < XSD::XSDBoolean\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPDecimal < XSD::XSDDecimal\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPFloat < XSD::XSDFloat\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPDouble < XSD::XSDDouble\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPDuration < XSD::XSDDuration\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPDateTime < XSD::XSDDateTime\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPTime < XSD::XSDTime\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPDate < XSD::XSDDate\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPGYearMonth < XSD::XSDGYearMonth\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPGYear < XSD::XSDGYear\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPGMonthDay < XSD::XSDGMonthDay\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPGDay < XSD::XSDGDay\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPGMonth < XSD::XSDGMonth\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPHexBinary < XSD::XSDHexBinary\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPBase64 < XSD::XSDBase64Binary\n  include SOAPBasetype\n  extend SOAPModuleUtils\n  Type = QName.new(EncodingNamespace, Base64Literal)\n\npublic\n  # Override the definition in SOAPBasetype.\n  def initialize(value = nil)\n    super(value)\n    @type = Type\n  end\n\n  def as_xsd\n    @type = XSD::XSDBase64Binary::Type\n  end\nend\n\nclass SOAPAnyURI < XSD::XSDAnyURI\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPQName < XSD::XSDQName\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\n\nclass SOAPInteger < XSD::XSDInteger\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPNonPositiveInteger < XSD::XSDNonPositiveInteger\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPNegativeInteger < XSD::XSDNegativeInteger\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPLong < XSD::XSDLong\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPInt < XSD::XSDInt\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPShort < XSD::XSDShort\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPByte < XSD::XSDByte\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPNonNegativeInteger < XSD::XSDNonNegativeInteger\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPUnsignedLong < XSD::XSDUnsignedLong\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPUnsignedInt < XSD::XSDUnsignedInt\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPUnsignedShort < XSD::XSDUnsignedShort\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPUnsignedByte < XSD::XSDUnsignedByte\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\nclass SOAPPositiveInteger < XSD::XSDPositiveInteger\n  include SOAPBasetype\n  extend SOAPModuleUtils\nend\n\n\n###\n## Compound datatypes.\n#\nclass SOAPStruct < XSD::NSDBase\n  include SOAPCompoundtype\n  include Enumerable\n\npublic\n\n  def initialize(type = nil)\n    super()\n    @type = type || XSD::QName::EMPTY\n    @array = []\n    @data = []\n  end\n\n  def to_s()\n    str = ''\n    self.each do |key, data|\n      str << \"#{key}: #{data}\\n\"\n    end\n    str\n  end\n\n  def add(name, value)\n    add_member(name, value)\n  end\n\n  def [](idx)\n    if idx.is_a?(Range)\n      @data[idx]\n    elsif idx.is_a?(Integer)\n      if (idx > @array.size)\n        raise ArrayIndexOutOfBoundsError.new('In ' << @type.name)\n      end\n      @data[idx]\n    else\n      if @array.include?(idx)\n\t@data[@array.index(idx)]\n      else\n\tnil\n      end\n    end\n  end\n\n  def []=(idx, data)\n    if @array.include?(idx)\n      data.parent = self if data.respond_to?(:parent=)\n      @data[@array.index(idx)] = data\n    else\n      add(idx, data)\n    end\n  end\n\n  def key?(name)\n    @array.include?(name)\n  end\n\n  def members\n    @array\n  end\n\n  def to_obj\n    hash = {}\n    proptype = {}\n    each do |k, v|\n      value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s\n      case proptype[k]\n      when :single\n        hash[k] = [hash[k], value]\n        proptype[k] = :multi\n      when :multi\n        hash[k] << value\n      else\n        hash[k] = value\n        proptype[k] = :single\n      end\n    end\n    hash\n  end\n\n  def each\n    idx = 0\n    while idx < @array.length\n      yield(@array[idx], @data[idx])\n      idx += 1\n    end\n  end\n\n  def replace\n    members.each do |member|\n      self[member] = yield(self[member])\n    end\n  end\n\n  def self.decode(elename, type)\n    s = SOAPStruct.new(type)\n    s.elename = elename\n    s\n  end\n\nprivate\n\n  def add_member(name, value = nil)\n    value = SOAPNil.new() if value.nil?\n    @array.push(name)\n    value.elename = value.elename.dup_name(name)\n    @data.push(value)\n    value.parent = self if value.respond_to?(:parent=)\n    value\n  end\nend\n\n\n# SOAPElement is not typed so it is not derived from NSDBase.\nclass SOAPElement\n  include Enumerable\n\n  attr_accessor :encodingstyle\n\n  attr_accessor :elename\n  attr_accessor :id\n  attr_reader :precedents\n  attr_accessor :root\n  attr_accessor :parent\n  attr_accessor :position\n  attr_accessor :extraattr\n\n  attr_accessor :qualified\n\n  def initialize(elename, text = nil)\n    if !elename.is_a?(XSD::QName)\n      elename = XSD::QName.new(nil, elename)\n    end\n    @encodingstyle = LiteralNamespace\n    @elename = elename\n    @id = nil\n    @precedents = []\n    @root = false\n    @parent = nil\n    @position = nil\n    @extraattr = {}\n\n    @qualified = nil\n\n    @array = []\n    @data = []\n    @text = text\n  end\n\n  def inspect\n    sprintf(\"#<%s:0x%x %s>\", self.class.name, __id__, self.elename)\n  end\n\n  # Text interface.\n  attr_accessor :text\n  alias data text\n\n  # Element interfaces.\n  def add(value)\n    add_member(value.elename.name, value)\n  end\n\n  def [](idx)\n    if @array.include?(idx)\n      @data[@array.index(idx)]\n    else\n      nil\n    end\n  end\n\n  def []=(idx, data)\n    if @array.include?(idx)\n      data.parent = self if data.respond_to?(:parent=)\n      @data[@array.index(idx)] = data\n    else\n      add(data)\n    end\n  end\n\n  def key?(name)\n    @array.include?(name)\n  end\n\n  def members\n    @array\n  end\n\n  def to_obj\n    if members.empty?\n      @text\n    else\n      hash = {}\n      proptype = {}\n      each do |k, v|\n        value = v.respond_to?(:to_obj) ? v.to_obj : v.to_s\n        case proptype[k]\n        when :single\n          hash[k] = [hash[k], value]\n          proptype[k] = :multi\n        when :multi\n          hash[k] << value\n        else\n          hash[k] = value\n          proptype[k] = :single\n        end\n      end\n      hash\n    end\n  end\n\n  def each\n    idx = 0\n    while idx < @array.length\n      yield(@array[idx], @data[idx])\n      idx += 1\n    end\n  end\n\n  def self.decode(elename)\n    o = SOAPElement.new(elename)\n    o\n  end\n\n  def self.from_obj(obj, namespace = nil)\n    o = SOAPElement.new(nil)\n    case obj\n    when nil\n      o.text = nil\n    when Hash\n      obj.each do |elename, value|\n        if value.is_a?(Array)\n          value.each do |subvalue|\n            child = from_obj(subvalue, namespace)\n            child.elename = to_elename(elename, namespace)\n            o.add(child)\n          end\n        else\n          child = from_obj(value, namespace)\n          child.elename = to_elename(elename, namespace)\n          o.add(child)\n        end\n      end\n    else\n      o.text = obj.to_s\n    end\n    o\n  end\n\n  def self.to_elename(obj, namespace = nil)\n    if obj.is_a?(XSD::QName)\n      obj\n    elsif /\\A(.+):([^:]+)\\z/ =~ obj.to_s\n      XSD::QName.new($1, $2)\n    else\n      XSD::QName.new(namespace, obj.to_s)\n    end\n  end\n\nprivate\n\n  def add_member(name, value)\n    add_accessor(name)\n    @array.push(name)\n    @data.push(value)\n    value.parent = self if value.respond_to?(:parent=)\n    value\n  end\n\n  if RUBY_VERSION > \"1.7.0\"\n    def add_accessor(name)\n      methodname = name\n      if self.respond_to?(methodname)\n        methodname = safe_accessor_name(methodname)\n      end\n      Mapping.define_singleton_method(self, methodname) do\n        @data[@array.index(name)]\n      end\n      Mapping.define_singleton_method(self, methodname + '=') do |value|\n        @data[@array.index(name)] = value\n      end\n    end\n  else\n    def add_accessor(name)\n      methodname = safe_accessor_name(name)\n      instance_eval <<-EOS\n        def #{methodname}\n          @data[@array.index(#{name.dump})]\n        end\n\n        def #{methodname}=(value)\n          @data[@array.index(#{name.dump})] = value\n        end\n      EOS\n    end\n  end\n\n  def safe_accessor_name(name)\n    \"var_\" << name.gsub(/[^a-zA-Z0-9_]/, '')\n  end\nend\n\n\nclass SOAPArray < XSD::NSDBase\n  include SOAPCompoundtype\n  include Enumerable\n\npublic\n\n  attr_accessor :sparse\n\n  attr_reader :offset, :rank\n  attr_accessor :size, :size_fixed\n  attr_reader :arytype\n\n  def initialize(type = nil, rank = 1, arytype = nil)\n    super()\n    @type = type || ValueArrayName\n    @rank = rank\n    @data = Array.new\n    @sparse = false\n    @offset = Array.new(rank, 0)\n    @size = Array.new(rank, 0)\n    @size_fixed = false\n    @position = nil\n    @arytype = arytype\n  end\n\n  def offset=(var)\n    @offset = var\n    @sparse = true\n  end\n\n  def add(value)\n    self[*(@offset)] = value\n  end\n\n  def [](*idxary)\n    if idxary.size != @rank\n      raise ArgumentError.new(\"given #{idxary.size} params does not match rank: #{@rank}\")\n    end\n\n    retrieve(idxary)\n  end\n\n  def []=(*idxary)\n    value = idxary.slice!(-1)\n\n    if idxary.size != @rank\n      raise ArgumentError.new(\"given #{idxary.size} params(#{idxary})\" +\n        \" does not match rank: #{@rank}\")\n    end\n\n    idx = 0\n    while idx < idxary.size\n      if idxary[idx] + 1 > @size[idx]\n\t@size[idx] = idxary[idx] + 1\n      end\n      idx += 1\n    end\n\n    data = retrieve(idxary[0, idxary.size - 1])\n    data[idxary.last] = value\n\n    if value.is_a?(SOAPType)\n      value.elename = ITEM_NAME\n      # Sync type\n      unless @type.name\n\t@type = XSD::QName.new(value.type.namespace,\n\t  SOAPArray.create_arytype(value.type.name, @rank))\n      end\n      value.type ||= @type\n    end\n\n    @offset = idxary\n    value.parent = self if value.respond_to?(:parent=)\n    offsetnext\n  end\n\n  def each\n    @data.each do |data|\n      yield(data)\n    end\n  end\n\n  def to_a\n    @data.dup\n  end\n\n  def replace\n    @data = deep_map(@data) do |ele|\n      yield(ele)\n    end\n  end\n\n  def deep_map(ary, &block)\n    ary.collect do |ele|\n      if ele.is_a?(Array)\n\tdeep_map(ele, &block)\n      else\n\tnew_obj = block.call(ele)\n\tnew_obj.elename = ITEM_NAME\n\tnew_obj\n      end\n    end\n  end\n\n  def include?(var)\n    traverse_data(@data) do |v, *rank|\n      if v.is_a?(SOAPBasetype) && v.data == var\n\treturn true\n      end\n    end\n    false\n  end\n\n  def traverse\n    traverse_data(@data) do |v, *rank|\n      unless @sparse\n       yield(v)\n      else\n       yield(v, *rank) if v && !v.is_a?(SOAPNil)\n      end\n    end\n  end\n\n  def soap2array(ary)\n    traverse_data(@data) do |v, *position|\n      iteary = ary\n      rank = 1\n      while rank < position.size\n\tidx = position[rank - 1]\n\tif iteary[idx].nil?\n\t  iteary = iteary[idx] = Array.new\n\telse\n\t  iteary = iteary[idx]\n\tend\n        rank += 1\n      end\n      if block_given?\n\titeary[position.last] = yield(v)\n      else\n\titeary[position.last] = v\n      end\n    end\n  end\n\n  def position\n    @position\n  end\n\nprivate\n\n  ITEM_NAME = XSD::QName.new(nil, 'item')\n\n  def retrieve(idxary)\n    data = @data\n    rank = 1\n    while rank <= idxary.size\n      idx = idxary[rank - 1]\n      if data[idx].nil?\n\tdata = data[idx] = Array.new\n      else\n\tdata = data[idx]\n      end\n      rank += 1\n    end\n    data\n  end\n\n  def traverse_data(data, rank = 1)\n    idx = 0\n    while idx < ranksize(rank)\n      if rank < @rank\n\ttraverse_data(data[idx], rank + 1) do |*v|\n\t  v[1, 0] = idx\n       \t  yield(*v)\n\tend\n      else\n\tyield(data[idx], idx)\n      end\n      idx += 1\n    end\n  end\n\n  def ranksize(rank)\n    @size[rank - 1]\n  end\n\n  def offsetnext\n    move = false\n    idx = @offset.size - 1\n    while !move && idx >= 0\n      @offset[idx] += 1\n      if @size_fixed\n\tif @offset[idx] < @size[idx]\n\t  move = true\n\telse\n\t  @offset[idx] = 0\n\t  idx -= 1\n\tend\n      else\n\tmove = true\n      end\n    end\n  end\n\n  # Module function\n\npublic\n\n  def self.decode(elename, type, arytype)\n    typestr, nofary = parse_type(arytype.name)\n    rank = nofary.count(',') + 1\n    plain_arytype = XSD::QName.new(arytype.namespace, typestr)\n    o = SOAPArray.new(type, rank, plain_arytype)\n    size = []\n    nofary.split(',').each do |s|\n      if s.empty?\n\tsize.clear\n\tbreak\n      else\n\tsize << s.to_i\n      end\n    end\n    unless size.empty?\n      o.size = size\n      o.size_fixed = true\n    end\n    o.elename = elename\n    o\n  end\n\nprivate\n\n  def self.create_arytype(typename, rank)\n    \"#{typename}[\" << ',' * (rank - 1) << ']'\n  end\n\n  TypeParseRegexp = Regexp.new('^(.+)\\[([\\d,]*)\\]$')\n\n  def self.parse_type(string)\n    TypeParseRegexp =~ string\n    return $1, $2\n  end\nend\n\n\nrequire 'soap/mapping/typeMap'\n\n\nend\n"
  },
  {
    "path": "lib/soap/element.rb",
    "content": "# SOAP4R - SOAP elements library\n# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'soap/baseData'\n\n\nmodule SOAP\n\n\n###\n## SOAP elements\n#\nmodule SOAPEnvelopeElement; end\n\nclass SOAPFault < SOAPStruct\n  include SOAPEnvelopeElement\n  include SOAPCompoundtype\n\npublic\n\n  def faultcode\n    self['faultcode']\n  end\n\n  def faultstring\n    self['faultstring']\n  end\n\n  def faultactor\n    self['faultactor']\n  end\n\n  def detail\n    self['detail']\n  end\n\n  def faultcode=(rhs)\n    self['faultcode'] = rhs\n  end\n\n  def faultstring=(rhs)\n    self['faultstring'] = rhs\n  end\n\n  def faultactor=(rhs)\n    self['faultactor'] = rhs\n  end\n\n  def detail=(rhs)\n    self['detail'] = rhs\n  end\n\n  def initialize(faultcode = nil, faultstring = nil, faultactor = nil, detail = nil)\n    super(EleFaultName)\n    @elename = EleFaultName\n    @encodingstyle = EncodingNamespace\n\n    if faultcode\n      self.faultcode = faultcode\n      self.faultstring = faultstring\n      self.faultactor = faultactor\n      self.detail = detail\n      self.faultcode.elename = EleFaultCodeName if self.faultcode\n      self.faultstring.elename = EleFaultStringName if self.faultstring\n      self.faultactor.elename = EleFaultActorName if self.faultactor\n      self.detail.elename = EleFaultDetailName if self.detail\n    end\n    faultcode.parent = self if faultcode\n    faultstring.parent = self if faultstring\n    faultactor.parent = self if faultactor\n    detail.parent = self if detail\n  end\n\n  def encode(generator, ns, attrs = {})\n    SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace)\n    SOAPGenerator.assign_ns(attrs, ns, EncodingNamespace)\n    attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace\n    name = ns.name(@elename)\n    generator.encode_tag(name, attrs)\n    yield(self.faultcode)\n    yield(self.faultstring)\n    yield(self.faultactor)\n    yield(self.detail) if self.detail\n    generator.encode_tag_end(name, true)\n  end\nend\n\n\nclass SOAPBody < SOAPStruct\n  include SOAPEnvelopeElement\n\n  def initialize(data = nil, is_fault = false)\n    super(nil)\n    @elename = EleBodyName\n    @encodingstyle = nil\n    if data\n      if data.respond_to?(:elename)\n        add(data.elename.name, data)\n      else\n        data.to_a.each do |datum|\n          add(datum.elename.name, datum)\n        end\n      end\n    end\n    @is_fault = is_fault\n  end\n\n  def encode(generator, ns, attrs = {})\n    name = ns.name(@elename)\n    generator.encode_tag(name, attrs)\n    if @is_fault\n      yield(@data)\n    else\n      @data.each do |data|\n\tyield(data)\n      end\n    end\n    generator.encode_tag_end(name, true)\n  end\n\n  def root_node\n    @data.each do |node|\n      if node.root == 1\n\treturn node\n      end\n    end\n    # No specified root...\n    @data.each do |node|\n      if node.root != 0\n\treturn node\n      end\n    end\n\n    raise Parser::FormatDecodeError.new('no root element')\n  end\nend\n\n\nclass SOAPHeaderItem < XSD::NSDBase\n  include SOAPEnvelopeElement\n  include SOAPCompoundtype\n\npublic\n\n  attr_accessor :element\n  attr_accessor :mustunderstand\n  attr_accessor :encodingstyle\n\n  def initialize(element, mustunderstand = true, encodingstyle = nil)\n    super()\n    @type = nil\n    @element = element\n    @mustunderstand = mustunderstand\n    @encodingstyle = encodingstyle\n    element.parent = self if element\n  end\n\n  def encode(generator, ns, attrs = {})\n    attrs.each do |key, value|\n      @element.extraattr[key] = value\n    end\n    @element.extraattr[ns.name(AttrMustUnderstandName)] =\n      (@mustunderstand ? '1' : '0')\n    if @encodingstyle\n      @element.extraattr[ns.name(AttrEncodingStyleName)] = @encodingstyle\n    end\n    @element.encodingstyle = @encodingstyle if !@element.encodingstyle\n    yield(@element)\n  end\nend\n\n\nclass SOAPHeader < SOAPStruct\n  include SOAPEnvelopeElement\n\n  def initialize\n    super(nil)\n    @elename = EleHeaderName\n    @encodingstyle = nil\n  end\n\n  def encode(generator, ns, attrs = {})\n    name = ns.name(@elename)\n    generator.encode_tag(name, attrs)\n    @data.each do |data|\n      yield(data)\n    end\n    generator.encode_tag_end(name, true)\n  end\n\n  def add(name, value)\n    mu = (value.extraattr[AttrMustUnderstandName] == '1')\n    encstyle = value.extraattr[AttrEncodingStyleName]\n    item = SOAPHeaderItem.new(value, mu, encstyle)\n    super(name, item)\n  end\n\n  def length\n    @data.length\n  end\n  alias size length\nend\n\n\nclass SOAPEnvelope < XSD::NSDBase\n  include SOAPEnvelopeElement\n  include SOAPCompoundtype\n\n  attr_reader :header\n  attr_reader :body\n  attr_reader :external_content\n\n  def initialize(header = nil, body = nil)\n    super()\n    @type = nil\n    @elename = EleEnvelopeName\n    @encodingstyle = nil\n    @header = header\n    @body = body\n    @external_content = {}\n    header.parent = self if header\n    body.parent = self if body\n  end\n\n  def header=(header)\n    header.parent = self\n    @header = header\n  end\n\n  def body=(body)\n    body.parent = self\n    @body = body\n  end\n\n  def encode(generator, ns, attrs = {})\n    SOAPGenerator.assign_ns(attrs, ns, elename.namespace, SOAPNamespaceTag)\n    name = ns.name(@elename)\n    generator.encode_tag(name, attrs)\n\n    yield(@header) if @header and @header.length > 0\n    yield(@body)\n\n    generator.encode_tag_end(name, true)\n  end\n\n  def to_ary\n    [header, body]\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/encodingstyle/aspDotNetHandler.rb",
    "content": "# SOAP4R - ASP.NET EncodingStyle handler library\n# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/encodingstyle/handler'\n\n\nmodule SOAP\nmodule EncodingStyle\n\n\nclass ASPDotNetHandler < Handler\n  Namespace = 'http://tempuri.org/ASP.NET'\n  add_handler\n\n  def initialize(charset = nil)\n    super(charset)\n    @textbuf = ''\n    @decode_typemap = nil\n  end\n\n\n  ###\n  ## encode interface.\n  #\n  def encode_data(generator, ns, data, parent)\n    attrs = {}\n    # ASPDotNetHandler is intended to be used for accessing an ASP.NET doc/lit\n    # service as an rpc/encoded service.  in the situation, local elements\n    # should be qualified.  propagate parent's namespace to children.\n    if data.elename.namespace.nil?\n      data.elename.namespace = parent.elename.namespace\n    end\n    name = generator.encode_name(ns, data, attrs)\n    case data\n    when SOAPRawString\n      generator.encode_tag(name, attrs)\n      generator.encode_rawstring(data.to_s)\n    when XSD::XSDString\n      generator.encode_tag(name, attrs)\n      generator.encode_string(@charset ?\n        XSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)\n    when XSD::XSDAnySimpleType\n      generator.encode_tag(name, attrs)\n      generator.encode_string(data.to_s)\n    when SOAPStruct\n      generator.encode_tag(name, attrs)\n      data.each do |key, value|\n        generator.encode_child(ns, value, data)\n      end\n    when SOAPArray\n      generator.encode_tag(name, attrs)\n      data.traverse do |child, *rank|\n\tdata.position = nil\n        generator.encode_child(ns, child, data)\n      end\n    else\n      raise EncodingStyleError.new(\n        \"unknown object:#{data} in this encodingStyle\")\n    end\n  end\n\n  def encode_data_end(generator, ns, data, parent)\n    name = generator.encode_name_end(ns, data)\n    cr = data.is_a?(SOAPCompoundtype)\n    generator.encode_tag_end(name, cr)\n  end\n\n\n  ###\n  ## decode interface.\n  #\n  class SOAPTemporalObject\n    attr_accessor :parent\n\n    def initialize\n      @parent = nil\n    end\n  end\n\n  class SOAPUnknown < SOAPTemporalObject\n    def initialize(handler, elename)\n      super()\n      @handler = handler\n      @elename = elename\n    end\n\n    def as_struct\n      o = SOAPStruct.decode(@elename, XSD::AnyTypeName)\n      o.parent = @parent\n      o.type.name = @name\n      @handler.decode_parent(@parent, o)\n      o\n    end\n\n    def as_string\n      o = SOAPString.decode(@elename)\n      o.parent = @parent\n      @handler.decode_parent(@parent, o)\n      o\n    end\n\n    def as_nil\n      o = SOAPNil.decode(@elename)\n      o.parent = @parent\n      @handler.decode_parent(@parent, o)\n      o\n    end\n  end\n\n  def decode_tag(ns, elename, attrs, parent)\n    @textbuf = ''\n    o = SOAPUnknown.new(self, elename)\n    o.parent = parent\n    o\n  end\n\n  def decode_tag_end(ns, node)\n    o = node.node\n    if o.is_a?(SOAPUnknown)\n      newnode = o.as_string\n#\tif /\\A\\s*\\z/ =~ @textbuf\n#\t  o.as_struct\n#\telse\n#\t  o.as_string\n#\tend\n      node.replace_node(newnode)\n      o = node.node\n    end\n\n    decode_textbuf(o)\n    @textbuf = ''\n  end\n\n  def decode_text(ns, text)\n    # @textbuf is set at decode_tag_end.\n    @textbuf << text\n  end\n\n  def decode_prologue\n  end\n\n  def decode_epilogue\n  end\n\n  def decode_parent(parent, node)\n    case parent.node\n    when SOAPUnknown\n      newparent = parent.node.as_struct\n      node.parent = newparent\n      parent.replace_node(newparent)\n      decode_parent(parent, node)\n\n    when SOAPStruct\n      data = parent.node[node.elename.name]\n      case data\n      when nil\n\tparent.node.add(node.elename.name, node)\n      when SOAPArray\n\tname, type_ns = node.elename.name, node.type.namespace\n\tdata.add(node)\n\tnode.elename, node.type.namespace = name, type_ns\n      else\n\tparent.node[node.elename.name] = SOAPArray.new\n\tname, type_ns = data.elename.name, data.type.namespace\n\tparent.node[node.elename.name].add(data)\n\tdata.elename.name, data.type.namespace = name, type_ns\n\tname, type_ns = node.elename.name, node.type.namespace\n\tparent.node[node.elename.name].add(node)\n\tnode.elename.name, node.type.namespace = name, type_ns\n      end\n\n    when SOAPArray\n      if node.position\n\tparent.node[*(decode_arypos(node.position))] = node\n\tparent.node.sparse = true\n      else\n\tparent.node.add(node)\n      end\n\n    when SOAPBasetype\n      raise EncodingStyleError.new(\"SOAP base type must not have a child\")\n\n    else\n      # SOAPUnknown does not have parent.\n      # raise EncodingStyleError.new(\"illegal parent: #{parent}\")\n    end\n  end\n\nprivate\n\n  def decode_textbuf(node)\n    if node.is_a?(XSD::XSDString)\n      if @charset\n\tnode.set(XSD::Charset.encoding_from_xml(@textbuf, @charset))\n      else\n\tnode.set(@textbuf)\n      end\n    else\n      # Nothing to do...\n    end\n  end\nend\n\nASPDotNetHandler.new\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/encodingstyle/handler.rb",
    "content": "# SOAP4R - EncodingStyle handler library\n# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/soap'\nrequire 'soap/baseData'\nrequire 'soap/element'\n\n\nmodule SOAP\nmodule EncodingStyle\n\n\nclass Handler\n  @@handlers = {}\n\n  class EncodingStyleError < Error; end\n\n  class << self\n    def uri\n      self::Namespace\n    end\n\n    def handler(uri)\n      @@handlers[uri]\n    end\n\n    def each\n      @@handlers.each do |key, value|\n\tyield(value)\n      end\n    end\n\n  private\n\n    def add_handler\n      @@handlers[self.uri] = self\n    end\n  end\n\n  attr_reader :charset\n  attr_accessor :generate_explicit_type\n  def decode_typemap=(definedtypes)\n    @decode_typemap = definedtypes\n  end\n\n  def initialize(charset)\n    @charset = charset\n    @generate_explicit_type = true\n    @decode_typemap = nil\n  end\n\n  ###\n  ## encode interface.\n  #\n  # Returns a XML instance as a string.\n  def encode_data(generator, ns, data, parent)\n    raise NotImplementError\n  end\n\n  def encode_data_end(generator, ns, data, parent)\n    raise NotImplementError\n  end\n\n  def encode_prologue\n  end\n\n  def encode_epilogue\n  end\n\n  ###\n  ## decode interface.\n  #\n  # Returns SOAP/OM data.\n  def decode_tag(ns, name, attrs, parent)\n    raise NotImplementError.new('Method decode_tag must be defined in derived class.')\n  end\n\n  def decode_tag_end(ns, name)\n    raise NotImplementError.new('Method decode_tag_end must be defined in derived class.')\n  end\n\n  def decode_text(ns, text)\n    raise NotImplementError.new('Method decode_text must be defined in derived class.')\n  end\n\n  def decode_prologue\n  end\n\n  def decode_epilogue\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/encodingstyle/literalHandler.rb",
    "content": "# SOAP4R - XML Literal EncodingStyle handler library\n# Copyright (C) 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/encodingstyle/handler'\n\n\nmodule SOAP\nmodule EncodingStyle\n\n\nclass LiteralHandler < Handler\n  Namespace = SOAP::LiteralNamespace\n  add_handler\n\n  def initialize(charset = nil)\n    super(charset)\n    @textbuf = ''\n  end\n\n\n  ###\n  ## encode interface.\n  #\n  def encode_data(generator, ns, data, parent)\n    attrs = {}\n    name = generator.encode_name(ns, data, attrs)\n    data.extraattr.each do |k, v|\n      # ToDo: check generator.attributeformdefault here\n      if k.is_a?(XSD::QName)\n        if k.namespace\n          SOAPGenerator.assign_ns(attrs, ns, k.namespace)\n          k = ns.name(k)\n        else\n          k = k.name\n        end\n      end\n      attrs[k] = v\n    end\n    case data\n    when SOAPRawString\n      generator.encode_tag(name, attrs)\n      generator.encode_rawstring(data.to_s)\n    when XSD::XSDString\n      generator.encode_tag(name, attrs)\n      str = data.to_s\n      str = XSD::Charset.encoding_to_xml(str, @charset) if @charset\n      generator.encode_string(str)\n    when XSD::XSDAnySimpleType\n      generator.encode_tag(name, attrs)\n      generator.encode_string(data.to_s)\n    when SOAPStruct\n      generator.encode_tag(name, attrs)\n      data.each do |key, value|\n        generator.encode_child(ns, value, data)\n      end\n    when SOAPArray\n      generator.encode_tag(name, attrs)\n      data.traverse do |child, *rank|\n\tdata.position = nil\n        generator.encode_child(ns, child, data)\n      end\n    when SOAPElement\n      # passes 2 times for simplifying namespace definition\n      data.each do |key, value|\n        if value.elename.namespace\n          SOAPGenerator.assign_ns(attrs, ns, value.elename.namespace)\n        end\n      end\n      generator.encode_tag(name, attrs)\n      generator.encode_rawstring(data.text) if data.text\n      data.each do |key, value|\n        generator.encode_child(ns, value, data)\n      end\n    else\n      raise EncodingStyleError.new(\n        \"unknown object:#{data} in this encodingStyle\")\n    end\n  end\n\n  def encode_data_end(generator, ns, data, parent)\n    name = generator.encode_name_end(ns, data)\n    cr = (data.is_a?(SOAPCompoundtype) or\n      (data.is_a?(SOAPElement) and !data.text))\n    generator.encode_tag_end(name, cr)\n  end\n\n\n  ###\n  ## decode interface.\n  #\n  class SOAPTemporalObject\n    attr_accessor :parent\n\n    def initialize\n      @parent = nil\n    end\n  end\n\n  class SOAPUnknown < SOAPTemporalObject\n    def initialize(handler, elename, extraattr)\n      super()\n      @handler = handler\n      @elename = elename\n      @extraattr = extraattr\n    end\n\n    def as_element\n      o = SOAPElement.decode(@elename)\n      o.parent = @parent\n      o.extraattr.update(@extraattr)\n      @handler.decode_parent(@parent, o)\n      o\n    end\n\n    def as_string\n      o = SOAPString.decode(@elename)\n      o.parent = @parent\n      o.extraattr.update(@extraattr)\n      @handler.decode_parent(@parent, o)\n      o\n    end\n\n    def as_nil\n      o = SOAPNil.decode(@elename)\n      o.parent = @parent\n      o.extraattr.update(@extraattr)\n      @handler.decode_parent(@parent, o)\n      o\n    end\n  end\n\n  def decode_tag(ns, elename, attrs, parent)\n    @textbuf = ''\n    o = SOAPUnknown.new(self, elename, decode_attrs(ns, attrs))\n    o.parent = parent\n    o\n  end\n\n  def decode_tag_end(ns, node)\n    o = node.node\n    if o.is_a?(SOAPUnknown)\n      newnode = if /\\A\\s*\\z/ =~ @textbuf\n\t  o.as_element\n\telse\n\t  o.as_string\n\tend\n      node.replace_node(newnode)\n      o = node.node\n    end\n\n    decode_textbuf(o)\n    @textbuf = ''\n  end\n\n  def decode_text(ns, text)\n    # @textbuf is set at decode_tag_end.\n    @textbuf << text\n  end\n\n  def decode_attrs(ns, attrs)\n    extraattr = {}\n    attrs.each do |key, value|\n      qname = ns.parse_local(key)\n      extraattr[qname] = value\n    end\n    extraattr\n  end\n\n  def decode_prologue\n  end\n\n  def decode_epilogue\n  end\n\n  def decode_parent(parent, node)\n    return unless parent.node\n    case parent.node\n    when SOAPUnknown\n      newparent = parent.node.as_element\n      node.parent = newparent\n      parent.replace_node(newparent)\n      decode_parent(parent, node)\n    when SOAPElement\n      parent.node.add(node)\n      node.parent = parent.node\n    when SOAPStruct\n      parent.node.add(node.elename.name, node)\n      node.parent = parent.node\n    when SOAPArray\n      if node.position\n\tparent.node[*(decode_arypos(node.position))] = node\n\tparent.node.sparse = true\n      else\n\tparent.node.add(node)\n      end\n      node.parent = parent.node\n    else\n      raise EncodingStyleError.new(\"illegal parent: #{parent.node}\")\n    end\n  end\n\nprivate\n\n  def decode_textbuf(node)\n    if node.is_a?(XSD::XSDString)\n      if @charset\n\tnode.set(XSD::Charset.encoding_from_xml(@textbuf, @charset))\n      else\n\tnode.set(@textbuf)\n      end\n    else\n      # Nothing to do...\n    end\n  end\nend\n\nLiteralHandler.new\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/encodingstyle/soapHandler.rb",
    "content": "# SOAP4R - SOAP EncodingStyle handler library\n# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/encodingstyle/handler'\n\n\nmodule SOAP\nmodule EncodingStyle\n\n\nclass SOAPHandler < Handler\n  Namespace = SOAP::EncodingNamespace\n  add_handler\n\n  def initialize(charset = nil)\n    super(charset)\n    @refpool = []\n    @idpool = []\n    @textbuf = ''\n    @is_first_top_ele = true\n  end\n\n\n  ###\n  ## encode interface.\n  #\n  def encode_data(generator, ns, data, parent)\n    attrs = encode_attrs(generator, ns, data, parent)\n    if parent && parent.is_a?(SOAPArray) && parent.position\n      attrs[ns.name(AttrPositionName)] = \"[#{parent.position.join(',')}]\"\n    end\n    name = generator.encode_name(ns, data, attrs)\n    case data\n    when SOAPReference\n      attrs['href'] = data.refidstr\n      generator.encode_tag(name, attrs)\n    when SOAPExternalReference\n      data.referred\n      attrs['href'] = data.refidstr\n      generator.encode_tag(name, attrs)\n    when SOAPRawString\n      generator.encode_tag(name, attrs)\n      generator.encode_rawstring(data.to_s)\n    when XSD::XSDString\n      generator.encode_tag(name, attrs)\n      generator.encode_string(@charset ?\n\tXSD::Charset.encoding_to_xml(data.to_s, @charset) : data.to_s)\n    when XSD::XSDAnySimpleType\n      generator.encode_tag(name, attrs)\n      generator.encode_string(data.to_s)\n    when SOAPStruct\n      generator.encode_tag(name, attrs)\n      data.each do |key, value|\n        generator.encode_child(ns, value, data)\n      end\n    when SOAPArray\n      generator.encode_tag(name, attrs)\n      data.traverse do |child, *rank|\n\tdata.position = data.sparse ? rank : nil\n        generator.encode_child(ns, child, data)\n      end\n    else\n      raise EncodingStyleError.new(\n\t\"unknown object:#{data} in this encodingStyle\")\n    end\n  end\n\n  def encode_data_end(generator, ns, data, parent)\n    name = generator.encode_name_end(ns, data)\n    cr = data.is_a?(SOAPCompoundtype)\n    generator.encode_tag_end(name, cr)\n  end\n\n\n  ###\n  ## decode interface.\n  #\n  class SOAPTemporalObject\n    attr_accessor :parent\n    attr_accessor :position\n    attr_accessor :id\n    attr_accessor :root\n\n    def initialize\n      @parent = nil\n      @position = nil\n      @id = nil\n      @root = nil\n    end\n  end\n\n  class SOAPUnknown < SOAPTemporalObject\n    attr_reader :type\n    attr_accessor :definedtype\n    attr_reader :extraattr\n\n    def initialize(handler, elename, type, extraattr)\n      super()\n      @handler = handler\n      @elename = elename\n      @type = type\n      @extraattr = extraattr\n      @definedtype = nil\n    end\n\n    def as_struct\n      o = SOAPStruct.decode(@elename, @type)\n      o.id = @id\n      o.root = @root\n      o.parent = @parent\n      o.position = @position\n      o.extraattr.update(@extraattr)\n      @handler.decode_parent(@parent, o)\n      o\n    end\n\n    def as_string\n      o = SOAPString.decode(@elename)\n      o.id = @id\n      o.root = @root\n      o.parent = @parent\n      o.position = @position\n      o.extraattr.update(@extraattr)\n      @handler.decode_parent(@parent, o)\n      o\n    end\n\n    def as_nil\n      o = SOAPNil.decode(@elename)\n      o.id = @id\n      o.root = @root\n      o.parent = @parent\n      o.position = @position\n      o.extraattr.update(@extraattr)\n      @handler.decode_parent(@parent, o)\n      o\n    end\n  end\n\n  def decode_tag(ns, elename, attrs, parent)\n    @textbuf = ''\n    is_nil, type, arytype, root, offset, position, href, id, extraattr =\n      decode_attrs(ns, attrs)\n    o = nil\n    if is_nil\n      o = SOAPNil.decode(elename)\n    elsif href\n      o = SOAPReference.decode(elename, href)\n      @refpool << o\n    elsif @decode_typemap\n      o = decode_tag_by_wsdl(ns, elename, type, parent.node, arytype, extraattr)\n    else\n      o = decode_tag_by_type(ns, elename, type, parent.node, arytype, extraattr)\n    end\n\n    if o.is_a?(SOAPArray)\n      if offset\n\to.offset = decode_arypos(offset)\n\to.sparse = true\n      else\n\to.sparse = false\n      end\n    end\n\n    o.parent = parent\n    o.id = id\n    o.root = root\n    o.position = position\n\n    unless o.is_a?(SOAPTemporalObject)\n      @idpool << o if o.id\n      decode_parent(parent, o)\n    end\n    o\n  end\n\n  def decode_tag_end(ns, node)\n    o = node.node\n    if o.is_a?(SOAPUnknown)\n      newnode = if /\\A\\s*\\z/ =~ @textbuf\n\to.as_struct\n      else\n\to.as_string\n      end\n      if newnode.id\n\t@idpool << newnode\n      end\n      node.replace_node(newnode)\n      o = node.node\n    end\n    decode_textbuf(o)\n    # unlink definedtype\n    o.definedtype = nil\n  end\n\n  def decode_text(ns, text)\n    @textbuf << text\n  end\n\n  def decode_prologue\n    @refpool.clear\n    @idpool.clear\n    @is_first_top_ele = true\n  end\n\n  def decode_epilogue\n    decode_resolve_id\n  end\n\n  def decode_parent(parent, node)\n    return unless parent.node\n    case parent.node\n    when SOAPUnknown\n      newparent = parent.node.as_struct\n      node.parent = newparent\n      if newparent.id\n\t@idpool << newparent\n      end\n      parent.replace_node(newparent)\n      decode_parent(parent, node)\n    when SOAPStruct\n      parent.node.add(node.elename.name, node)\n      node.parent = parent.node\n    when SOAPArray\n      if node.position\n\tparent.node[*(decode_arypos(node.position))] = node\n\tparent.node.sparse = true\n      else\n\tparent.node.add(node)\n      end\n      node.parent = parent.node\n    else\n      raise EncodingStyleError.new(\"illegal parent: #{parent.node}\")\n    end\n  end\n\nprivate\n\n  def content_ranksize(typename)\n    typename.scan(/\\[[\\d,]*\\]$/)[0]\n  end\n\n  def content_typename(typename)\n    typename.sub(/\\[,*\\]$/, '')\n  end\n\n  def create_arytype(ns, data)\n    XSD::QName.new(data.arytype.namespace,\n      content_typename(data.arytype.name) + \"[#{data.size.join(',')}]\")\n  end\n\n  def encode_attrs(generator, ns, data, parent)\n    attrs = {}\n    return attrs if data.is_a?(SOAPReference)\n\n    if !parent || parent.encodingstyle != EncodingNamespace\n      if @generate_explicit_type\n        SOAPGenerator.assign_ns(attrs, ns, EnvelopeNamespace)\n        attrs[ns.name(AttrEncodingStyleName)] = EncodingNamespace\n      end\n      data.encodingstyle = EncodingNamespace\n    end\n\n    if data.is_a?(SOAPNil)\n      attrs[ns.name(XSD::AttrNilName)] = XSD::NilValue\n    elsif @generate_explicit_type\n      if data.type.namespace\n        SOAPGenerator.assign_ns(attrs, ns, data.type.namespace)\n      end\n      if data.is_a?(SOAPArray)\n\tif data.arytype.namespace\n          SOAPGenerator.assign_ns(attrs, ns, data.arytype.namespace)\n   \tend\n\tSOAPGenerator.assign_ns(attrs, ns, EncodingNamespace)\n\tattrs[ns.name(AttrArrayTypeName)] = ns.name(create_arytype(ns, data))\n\tif data.type.name\n\t  attrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type)\n\tend\n      elsif parent && parent.is_a?(SOAPArray) && (parent.arytype == data.type)\n\t# No need to add.\n      elsif !data.type.namespace\n\t# No need to add.\n      else\n\tattrs[ns.name(XSD::AttrTypeName)] = ns.name(data.type)\n      end\n    end\n\n    data.extraattr.each do |key, value|\n      SOAPGenerator.assign_ns(attrs, ns, key.namespace)\n      attrs[ns.name(key)] = encode_attr_value(generator, ns, key, value)\n    end\n    if data.id\n      attrs['id'] = data.id\n    end\n    attrs\n  end\n\n  def encode_attr_value(generator, ns, qname, value)\n    if value.is_a?(SOAPType)\n      ref = SOAPReference.new(value)\n      generator.add_reftarget(qname.name, value)\n      ref.refidstr\n    else\n      value.to_s\n    end\n  end\n\n  def decode_tag_by_wsdl(ns, elename, typestr, parent, arytypestr, extraattr)\n    o = nil\n    if parent.class == SOAPBody\n      # root element: should branch by root attribute?\n      if @is_first_top_ele\n\t# Unqualified name is allowed here.\n\t@is_first_top_ele = false\n\ttype = @decode_typemap[elename] ||\n\t  @decode_typemap.find_name(elename.name)\n\tif type\n\t  o = SOAPStruct.new(elename)\n\t  o.definedtype = type\n\t  return o\n\tend\n      end\n      # multi-ref element.\n      if typestr\n\ttypename = ns.parse(typestr)\n\ttypedef = @decode_typemap[typename]\n\tif typedef\n          return decode_definedtype(elename, typename, typedef, arytypestr)\n\tend\n      end\n      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,\n\textraattr)\n    end\n\n    if parent.type == XSD::AnyTypeName\n      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,\n\textraattr)\n    end\n\n    # parent.definedtype == nil means the parent is SOAPUnknown.  SOAPUnknown\n    # is generated by decode_tag_by_type when its type is anyType.\n    parenttype = parent.definedtype || @decode_typemap[parent.type]\n    unless parenttype\n      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,\n\textraattr)\n    end\n\n    definedtype_name = parenttype.child_type(elename)\n    if definedtype_name and (klass = TypeMap[definedtype_name])\n      return decode_basetype(klass, elename)\n    elsif definedtype_name == XSD::AnyTypeName\n      return decode_tag_by_type(ns, elename, typestr, parent, arytypestr,\n\textraattr)\n    end\n\n    if definedtype_name\n      typedef = @decode_typemap[definedtype_name]\n    else\n      typedef = parenttype.child_defined_complextype(elename)\n    end\n    decode_definedtype(elename, definedtype_name, typedef, arytypestr)\n  end\n\n  def decode_definedtype(elename, typename, typedef, arytypestr)\n    unless typedef\n      raise EncodingStyleError.new(\"unknown type '#{typename}'\")\n    end\n    if typedef.is_a?(::WSDL::XMLSchema::SimpleType)\n      decode_defined_simpletype(elename, typename, typedef, arytypestr)\n    else\n      decode_defined_complextype(elename, typename, typedef, arytypestr)\n    end\n  end\n\n  def decode_basetype(klass, elename)\n    klass.decode(elename)\n  end\n\n  def decode_defined_simpletype(elename, typename, typedef, arytypestr)\n    o = decode_basetype(TypeMap[typedef.base], elename)\n    o.definedtype = typedef\n    o\n  end\n\n  def decode_defined_complextype(elename, typename, typedef, arytypestr)\n    case typedef.compoundtype\n    when :TYPE_STRUCT, :TYPE_MAP\n      o = SOAPStruct.decode(elename, typename)\n      o.definedtype = typedef\n      return o\n    when :TYPE_ARRAY\n      expected_arytype = typedef.find_arytype\n      if arytypestr\n\tactual_arytype = XSD::QName.new(expected_arytype.namespace,\n\t  content_typename(expected_arytype.name) <<\n\t  content_ranksize(arytypestr))\n\to = SOAPArray.decode(elename, typename, actual_arytype)\n      else\n\to = SOAPArray.new(typename, 1, expected_arytype)\n\to.elename = elename\n      end\n      o.definedtype = typedef\n      return o\n    when :TYPE_EMPTY\n      o = SOAPNil.decode(elename)\n      o.definedtype = typedef\n      return o\n    else\n      raise RuntimeError.new(\n        \"Unknown kind of complexType: #{typedef.compoundtype}\")\n    end\n    nil\n  end\n\n  def decode_tag_by_type(ns, elename, typestr, parent, arytypestr, extraattr)\n    if arytypestr\n      type = typestr ? ns.parse(typestr) : ValueArrayName\n      node = SOAPArray.decode(elename, type, ns.parse(arytypestr))\n      node.extraattr.update(extraattr)\n      return node\n    end\n\n    type = nil\n    if typestr\n      type = ns.parse(typestr)\n    elsif parent.is_a?(SOAPArray)\n      type = parent.arytype\n    else\n      # Since it's in dynamic(without any type) encoding process,\n      # assumes entity as its type itself.\n      #   <SOAP-ENC:Array ...> => type Array in SOAP-ENC.\n      #   <Country xmlns=\"foo\"> => type Country in foo.\n      type = elename\n    end\n\n    if (klass = TypeMap[type])\n      node = decode_basetype(klass, elename)\n      node.extraattr.update(extraattr)\n      return node\n    end\n\n    # Unknown type... Struct or String\n    SOAPUnknown.new(self, elename, type, extraattr)\n  end\n\n  def decode_textbuf(node)\n    case node\n    when XSD::XSDHexBinary, XSD::XSDBase64Binary\n      node.set_encoded(@textbuf)\n    when XSD::XSDString\n      if @charset\n\t@textbuf = XSD::Charset.encoding_from_xml(@textbuf, @charset)\n      end\n      if node.definedtype\n        node.definedtype.check_lexical_format(@textbuf)\n      end\n      node.set(@textbuf)\n    when SOAPNil\n      # Nothing to do.\n    when SOAPBasetype\n      node.set(@textbuf)\n    else\n      # Nothing to do...\n    end\n    @textbuf = ''\n  end\n\n  NilLiteralMap = {\n    'true' => true,\n    '1' => true,\n    'false' => false,\n    '0' => false\n  }\n  RootLiteralMap = {\n    '1' => 1,\n    '0' => 0\n  }\n  def decode_attrs(ns, attrs)\n    is_nil = false\n    type = nil\n    arytype = nil\n    root = nil\n    offset = nil\n    position = nil\n    href = nil\n    id = nil\n    extraattr = {}\n\n    attrs.each do |key, value|\n      qname = ns.parse(key)\n      case qname.namespace\n      when XSD::InstanceNamespace\n        case qname.name\n        when XSD::NilLiteral\n          is_nil = NilLiteralMap[value] or\n            raise EncodingStyleError.new(\"cannot accept attribute value: #{value} as the value of xsi:#{XSD::NilLiteral} (expected 'true', 'false', '1', or '0')\")\n          next\n        when XSD::AttrType\n          type = value\n          next\n        end\n      when EncodingNamespace\n        case qname.name\n        when AttrArrayType\n          arytype = value\n          next\n        when AttrRoot\n          root = RootLiteralMap[value] or\n            raise EncodingStyleError.new(\n\t      \"illegal root attribute value: #{value}\")\n          next\n        when AttrOffset\n          offset = value\n          next\n        when AttrPosition\n          position = value\n          next\n        end\n      end\n      if key == 'href'\n        href = value\n        next\n      elsif key == 'id'\n        id = value\n        next\n      end\n      qname = ns.parse_local(key)\n      extraattr[qname] = decode_attr_value(ns, qname, value)\n    end\n\n    return is_nil, type, arytype, root, offset, position, href, id, extraattr\n  end\n\n  def decode_attr_value(ns, qname, value)\n    if /\\A#/ =~ value\n      o = SOAPReference.decode(nil, value)\n      @refpool << o\n      o\n    else\n      value\n    end\n  end\n\n  def decode_arypos(position)\n    /^\\[(.+)\\]$/ =~ position\n    $1.split(',').collect { |s| s.to_i }\n  end\n\n  def decode_resolve_id\n    count = @refpool.length\t# To avoid infinite loop\n    while !@refpool.empty? && count > 0\n      @refpool = @refpool.find_all { |ref|\n\to = @idpool.find { |item|\n\t  item.id == ref.refid\n\t}\n\tif o.is_a?(SOAPReference)\n\t  true\t# link of link.\n\telsif o\n\t  ref.__setobj__(o)\n\t  false\n\telsif o = ref.rootnode.external_content[ref.refid]\n\t  ref.__setobj__(o)\n      \t  false\n\telse\n\t  raise EncodingStyleError.new(\"unresolved reference: #{ref.refid}\")\n\tend\n      }\n      count -= 1\n    end\n  end\nend\n\nSOAPHandler.new\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/generator.rb",
    "content": "# SOAP4R - SOAP XML Instance Generator library.\n# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/ns'\nrequire 'soap/soap'\nrequire 'soap/baseData'\nrequire 'soap/encodingstyle/handler'\n\n\nmodule SOAP\n\n\n###\n## CAUTION: MT-unsafe\n#\nclass SOAPGenerator\n  include SOAP\n\n  class FormatEncodeError < Error; end\n\npublic\n\n  attr_accessor :charset\n  attr_accessor :default_encodingstyle\n  attr_accessor :generate_explicit_type\n  attr_accessor :use_numeric_character_reference\n\n  def initialize(opt = {})\n    @reftarget = nil\n    @handlers = {}\n    @charset = opt[:charset] || XSD::Charset.xml_encoding_label\n    @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace\n    @generate_explicit_type =\n      opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true\n    @elementformdefault = opt[:elementformdefault]\n    @attributeformdefault = opt[:attributeformdefault]\n    @use_numeric_character_reference = opt[:use_numeric_character_reference]\n    @indentstr = opt[:no_indent] ? '' : '  '\n    @buf = @indent = @curr = nil\n  end\n\n  def generate(obj, io = nil)\n    @buf = io || ''\n    @indent = ''\n\n    prologue\n    @handlers.each do |uri, handler|\n      handler.encode_prologue\n    end\n\n    ns = XSD::NS.new\n    @buf << xmldecl\n    encode_data(ns, obj, nil)\n\n    @handlers.each do |uri, handler|\n      handler.encode_epilogue\n    end\n    epilogue\n\n    @buf\n  end\n\n  def encode_data(ns, obj, parent)\n    if obj.is_a?(SOAPEnvelopeElement)\n      encode_element(ns, obj, parent)\n      return\n    end\n    if @reftarget && !obj.precedents.empty?\n      add_reftarget(obj.elename.name, obj)\n      ref = SOAPReference.new(obj)\n      ref.elename = ref.elename.dup_name(obj.elename.name)\n      obj.precedents.clear\t# Avoid cyclic delay.\n      obj.encodingstyle = parent.encodingstyle\n      # SOAPReference is encoded here.\n      obj = ref\n    end\n    encodingstyle = obj.encodingstyle\n    # Children's encodingstyle is derived from its parent.\n    encodingstyle ||= parent.encodingstyle if parent\n    obj.encodingstyle = encodingstyle\n    handler = find_handler(encodingstyle || @default_encodingstyle)\n    unless handler\n      raise FormatEncodeError.new(\"Unknown encodingStyle: #{ encodingstyle }.\")\n    end\n    if !obj.elename.name\n      raise FormatEncodeError.new(\"Element name not defined: #{ obj }.\")\n    end\n    handler.encode_data(self, ns, obj, parent)\n    handler.encode_data_end(self, ns, obj, parent)\n  end\n\n  def add_reftarget(name, node)\n    unless @reftarget\n      raise FormatEncodeError.new(\"Reftarget is not defined.\")\n    end\n    @reftarget.add(name, node)\n  end\n\n  def encode_child(ns, child, parent)\n    indent_backup, @indent = @indent, @indent + @indentstr\n    encode_data(ns.clone_ns, child, parent)\n    @indent = indent_backup\n  end\n\n  def encode_element(ns, obj, parent)\n    attrs = {}\n    if obj.is_a?(SOAPBody)\n      @reftarget = obj\n      obj.encode(self, ns, attrs) do |child|\n\tindent_backup, @indent = @indent, @indent + @indentstr\n        encode_data(ns.clone_ns, child, obj)\n\t@indent = indent_backup\n      end\n      @reftarget = nil\n    else\n      if obj.is_a?(SOAPEnvelope)\n        # xsi:nil=\"true\" can appear even if dumping without explicit type.\n        SOAPGenerator.assign_ns(attrs, ns,\n\t  XSD::InstanceNamespace, XSINamespaceTag)\n        if @generate_explicit_type\n          SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag)\n        end\n      end\n      obj.encode(self, ns, attrs) do |child|\n\tindent_backup, @indent = @indent, @indent + @indentstr\n        encode_data(ns.clone_ns, child, obj)\n\t@indent = indent_backup\n      end\n    end\n  end\n\n  def encode_name(ns, data, attrs)\n    if element_local?(data)\n      data.elename.name\n    else\n      if element_qualified?(data)\n        SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '')\n      else\n        SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace)\n      end\n      ns.name(data.elename)\n    end\n  end\n\n  def encode_name_end(ns, data)\n    if element_local?(data)\n      data.elename.name\n    else\n      ns.name(data.elename)\n    end\n  end\n\n  def encode_tag(elename, attrs = nil)\n    if !attrs or attrs.empty?\n      @buf << \"\\n#{ @indent }<#{ elename }>\"\n    elsif attrs.size == 1\n      key, value = attrs.shift\n      @buf << %Q[\\n#{ @indent }<#{ elename } #{ key }=\"#{ value }\">]\n    else\n      @buf << \"\\n#{ @indent }<#{ elename } \" <<\n        attrs.collect { |key, value|\n          %Q[#{ key }=\"#{ value }\"]\n        }.join(\"\\n#{ @indent }#{ @indentstr * 2 }\") <<\n\t'>'\n    end\n  end\n\n  def encode_tag_end(elename, cr = nil)\n    if cr\n      @buf << \"\\n#{ @indent }</#{ elename }>\"\n    else\n      @buf << \"</#{ elename }>\"\n    end\n  end\n\n  def encode_rawstring(str)\n    @buf << str\n  end\n\n  EncodeMap = {\n    '&' => '&amp;',\n    '<' => '&lt;',\n    '>' => '&gt;',\n    '\"' => '&quot;',\n    '\\'' => '&apos;',\n    \"\\r\" => '&#xd;'\n  }\n  EncodeCharRegexp = Regexp.new(\"[#{EncodeMap.keys.join}]\")\n  def encode_string(str)\n    if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str)\n      str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] }\n      @buf << str.unpack(\"U*\").collect { |c|\n        if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f)\n          c.chr\n        else\n          sprintf(\"&#x%x;\", c)\n        end\n      }.join\n    else\n      @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] }\n    end\n  end\n\n  def element_local?(element)\n    element.elename.namespace.nil?\n  end\n\n  def element_qualified?(element)\n    if element.respond_to?(:qualified)\n      if element.qualified.nil?\n        @elementformdefault\n      else\n        element.qualified\n      end\n    else\n      @elementformdefault\n    end\n  end\n\n  def self.assign_ns(attrs, ns, namespace, tag = nil)\n    if namespace.nil?\n      raise FormatEncodeError.new(\"empty namespace\")\n    end\n    unless ns.assigned?(namespace)\n      tag = ns.assign(namespace, tag)\n      if tag == ''\n        attr = 'xmlns'\n      else\n        attr = \"xmlns:#{tag}\"\n      end\n      attrs[attr] = namespace\n    end\n  end\n\nprivate\n\n  def prologue\n  end\n\n  def epilogue\n  end\n\n  def find_handler(encodingstyle)\n    unless @handlers.key?(encodingstyle)\n      handler = SOAP::EncodingStyle::Handler.handler(encodingstyle).new(@charset)\n      handler.generate_explicit_type = @generate_explicit_type\n      handler.encode_prologue\n      @handlers[encodingstyle] = handler\n    end\n    @handlers[encodingstyle]\n  end\n\n  def xmldecl\n    if @charset\n      %Q[<?xml version=\"1.0\" encoding=\"#{ @charset }\" ?>]\n    else\n      %Q[<?xml version=\"1.0\" ?>]\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/header/handler.rb",
    "content": "# SOAP4R - SOAP Header handler item\n# Copyright (C) 2003, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/element'\n\n\nmodule SOAP\nmodule Header\n\n\nclass Handler\n  attr_reader :elename\n  attr_reader :mustunderstand\n  attr_reader :encodingstyle\n\n  def initialize(elename)\n    @elename = elename\n    @mustunderstand = false\n    @encodingstyle = nil\n  end\n\n  # Should return a SOAP/OM, a SOAPHeaderItem or nil.\n  def on_outbound\n    nil\n  end\n\n  # Given header is a SOAPHeaderItem or nil.\n  def on_inbound(header, mustunderstand = false)\n    # do something.\n  end\n\n  def on_outbound_headeritem\n    item = on_outbound\n    if item.nil?\n      nil\n    elsif item.is_a?(::SOAP::SOAPHeaderItem)\n      item.elename = @elename\n      item\n    else\n      item.elename = @elename\n      ::SOAP::SOAPHeaderItem.new(item, @mustunderstand, @encodingstyle)\n    end\n  end\n\n  def on_inbound_headeritem(header)\n    on_inbound(header.element, header.mustunderstand)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/header/handlerset.rb",
    "content": "# SOAP4R - SOAP Header handler set\n# Copyright (C) 2003, 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/namedelements'\n\n\nmodule SOAP\nmodule Header\n\n\nclass HandlerSet\n  def initialize\n    @store = XSD::NamedElements.new\n  end\n\n  def dup\n    obj = HandlerSet.new\n    obj.store = @store.dup\n    obj\n  end\n\n  def add(handler)\n    @store << handler\n  end\n  alias << add\n\n  def delete(handler)\n    @store.delete(handler)\n  end\n\n  def include?(handler)\n    @store.include?(handler)\n  end\n\n  # returns: Array of SOAPHeaderItem\n  def on_outbound\n    @store.collect { |handler|\n      handler.on_outbound_headeritem\n    }.compact\n  end\n\n  # headers: SOAPHeaderItem enumerable object\n  def on_inbound(headers)\n    headers.each do |name, item|\n      handler = @store.find { |handler|\n        handler.elename == item.element.elename\n      }\n      if handler\n        handler.on_inbound_headeritem(item)\n      elsif item.mustunderstand\n        raise UnhandledMustUnderstandHeaderError.new(item.element.elename.to_s)\n      end\n    end\n  end\n\nprotected\n\n  def store=(store)\n    @store = store\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/header/simplehandler.rb",
    "content": "# SOAP4R - SOAP Simple header item handler\n# Copyright (C) 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/header/handler'\nrequire 'soap/baseData'\n\n\nmodule SOAP\nmodule Header\n\n\nclass SimpleHandler < SOAP::Header::Handler\n  def initialize(elename)\n    super(elename)\n  end\n\n  # Should return a Hash, String or nil.\n  def on_simple_outbound\n    nil\n  end\n\n  # Given header is a Hash, String or nil.\n  def on_simple_inbound(header, mustunderstand)\n  end\n\n  def on_outbound\n    h = on_simple_outbound\n    h ? SOAPElement.from_obj(h, elename.namespace) : nil\n  end\n\n  def on_inbound(header, mustunderstand)\n    h = header.respond_to?(:to_obj) ? header.to_obj : header.data\n    on_simple_inbound(h, mustunderstand)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/httpconfigloader.rb",
    "content": "# SOAP4R - HTTP config loader.\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/property'\n\n\nmodule SOAP\n\n\nmodule HTTPConfigLoader\nmodule_function\n\n  def set_options(client, options)\n    client.proxy = options[\"proxy\"]\n    options.add_hook(\"proxy\") do |key, value|\n      client.proxy = value\n    end\n    client.no_proxy = options[\"no_proxy\"]\n    options.add_hook(\"no_proxy\") do |key, value|\n      client.no_proxy = value\n    end\n    if client.respond_to?(:protocol_version=)\n      client.protocol_version = options[\"protocol_version\"]\n      options.add_hook(\"protocol_version\") do |key, value|\n        client.protocol_version = value\n      end\n    end\n    ssl_config = options[\"ssl_config\"] ||= ::SOAP::Property.new\n    set_ssl_config(client, ssl_config)\n    ssl_config.add_hook(true) do |key, value|\n      set_ssl_config(client, ssl_config)\n    end\n    basic_auth = options[\"basic_auth\"] ||= ::SOAP::Property.new\n    set_basic_auth(client, basic_auth)\n    basic_auth.add_hook do |key, value|\n      set_basic_auth(client, basic_auth)\n    end\n    options.add_hook(\"connect_timeout\") do |key, value|\n      client.connect_timeout = value\n    end\n    options.add_hook(\"send_timeout\") do |key, value|\n      client.send_timeout = value\n    end\n    options.add_hook(\"receive_timeout\") do |key, value|\n      client.receive_timeout = value\n    end\n  end\n\n  def set_basic_auth(client, basic_auth)\n    basic_auth.values.each do |url, userid, passwd|\n      client.set_basic_auth(url, userid, passwd)\n    end\n  end\n\n  def set_ssl_config(client, ssl_config)\n    ssl_config.each do |key, value|\n      cfg = client.ssl_config\n      if cfg.nil?\n        raise NotImplementedError.new(\"SSL not supported\")\n      end\n      case key\n      when 'client_cert'\n        cfg.client_cert = cert_from_file(value)\n      when 'client_key'\n        cfg.client_key = key_from_file(value)\n      when 'client_ca'\n        cfg.client_ca = value\n      when 'ca_path'\n        cfg.set_trust_ca(value)\n      when 'ca_file'\n        cfg.set_trust_ca(value)\n      when 'crl'\n        cfg.set_crl(value)\n      when 'verify_mode'\n        cfg.verify_mode = ssl_config_int(value)\n      when 'verify_depth'\n        cfg.verify_depth = ssl_config_int(value)\n      when 'options'\n        cfg.options = value\n      when 'ciphers'\n        cfg.ciphers = value\n      when 'verify_callback'\n        cfg.verify_callback = value\n      when 'cert_store'\n        cfg.cert_store = value\n      else\n        raise ArgumentError.new(\"unknown ssl_config property #{key}\")\n      end\n    end\n  end\n\n  def ssl_config_int(value)\n    if value.nil? or value.to_s.empty?\n      nil\n    else\n      begin\n        Integer(value)\n      rescue ArgumentError\n        ::SOAP::Property::Util.const_from_name(value.to_s)\n      end\n    end\n  end\n\n  def cert_from_file(filename)\n    OpenSSL::X509::Certificate.new(File.open(filename) { |f| f.read })\n  end\n\n  def key_from_file(filename)\n    OpenSSL::PKey::RSA.new(File.open(filename) { |f| f.read })\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/mapping/factory.rb",
    "content": "# SOAP4R - Mapping factory.\n# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule SOAP\nmodule Mapping\n\n\nclass Factory\n  include TraverseSupport\n\n  def initialize\n    # nothing to do\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    raise NotImplementError.new\n    # return soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    raise NotImplementError.new\n    # return convert_succeeded_or_not, obj\n  end\n\n  def setiv2obj(obj, node, map)\n    return if node.nil?\n    if obj.is_a?(Array)\n      setiv2ary(obj, node, map)\n    else\n      setiv2struct(obj, node, map)\n    end\n  end\n\n  def setiv2soap(node, obj, map)\n    if obj.class.class_variables.include?('@@schema_element')\n      obj.class.class_eval('@@schema_element').each do |name, info|\n        type, qname = info\n        if qname\n          elename = qname.name\n        else\n          elename = Mapping.name2elename(name)\n        end\n        node.add(elename,\n          Mapping._obj2soap(obj.instance_variable_get('@' + name), map))\n      end\n    else\n      # should we sort instance_variables?\n      obj.instance_variables.each do |var|\n        name = var.sub(/^@/, '')\n        elename = Mapping.name2elename(name)\n        node.add(elename,\n          Mapping._obj2soap(obj.instance_variable_get(var), map))\n      end\n    end\n  end\n\nprivate\n\n  def setiv2ary(obj, node, map)\n    node.each do |name, value|\n      Array.instance_method(:<<).bind(obj).call(Mapping._soap2obj(value, map))\n    end\n  end\n\n  def setiv2struct(obj, node, map)\n    vars = {}\n    node.each do |name, value|\n      vars[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)\n    end\n    Mapping.set_attributes(obj, vars)\n  end\nend\n\nclass StringFactory_ < Factory\n  def initialize(allow_original_mapping = false)\n    super()\n    @allow_original_mapping = allow_original_mapping\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    if !@allow_original_mapping and !obj.instance_variables.empty?\n      return nil\n    end\n    begin\n      unless XSD::Charset.is_ces(obj, Thread.current[:SOAPExternalCES])\n        return nil\n      end\n      encoded = XSD::Charset.encoding_conv(obj,\n        Thread.current[:SOAPExternalCES], XSD::Charset.encoding)\n      soap_obj = soap_class.new(encoded)\n    rescue XSD::ValueSpaceError\n      return nil\n    end\n    mark_marshalled_obj(obj, soap_obj)\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    obj = Mapping.create_empty_object(obj_class)\n    decoded = XSD::Charset.encoding_conv(node.data, XSD::Charset.encoding,\n      Thread.current[:SOAPExternalCES])\n    obj.replace(decoded)\n    mark_unmarshalled_obj(node, obj)\n    return true, obj\n  end\nend\n\nclass BasetypeFactory_ < Factory\n  def initialize(allow_original_mapping = false)\n    super()\n    @allow_original_mapping = allow_original_mapping\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    if !@allow_original_mapping and !obj.instance_variables.empty?\n      return nil\n    end\n    soap_obj = nil\n    begin\n      soap_obj = soap_class.new(obj)\n    rescue XSD::ValueSpaceError\n      return nil\n    end\n    if @allow_original_mapping\n      # Basetype except String should not be multiref-ed in SOAP/1.1.\n      mark_marshalled_obj(obj, soap_obj)\n    end\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    obj = node.data\n    mark_unmarshalled_obj(node, obj)\n    return true, obj\n  end\nend\n\nclass DateTimeFactory_ < Factory\n  def initialize(allow_original_mapping = false)\n    super()\n    @allow_original_mapping = allow_original_mapping\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    if !@allow_original_mapping and\n\tTime === obj and !obj.instance_variables.empty?\n      return nil\n    end\n    soap_obj = nil\n    begin\n      soap_obj = soap_class.new(obj)\n    rescue XSD::ValueSpaceError\n      return nil\n    end\n    mark_marshalled_obj(obj, soap_obj)\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    if node.respond_to?(:to_obj)\n      obj = node.to_obj(obj_class)\n      return false if obj.nil?\n      mark_unmarshalled_obj(node, obj)\n      return true, obj\n    else\n      return false\n    end\n  end\nend\n\nclass Base64Factory_ < Factory\n  def obj2soap(soap_class, obj, info, map)\n    return nil unless obj.instance_variables.empty?\n    soap_obj = soap_class.new(obj)\n    mark_marshalled_obj(obj, soap_obj) if soap_obj\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    obj = node.string\n    mark_unmarshalled_obj(node, obj)\n    return true, obj\n  end\nend\n\nclass URIFactory_ < Factory\n  def obj2soap(soap_class, obj, info, map)\n    soap_obj = soap_class.new(obj)\n    mark_marshalled_obj(obj, soap_obj) if soap_obj\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    obj = node.data\n    mark_unmarshalled_obj(node, obj)\n    return true, obj\n  end\nend\n\nclass ArrayFactory_ < Factory\n  def initialize(allow_original_mapping = false)\n    super()\n    @allow_original_mapping = allow_original_mapping\n  end\n\n  # [[1], [2]] is converted to Array of Array, not 2-D Array.\n  # To create M-D Array, you must call Mapping.ary2md.\n  def obj2soap(soap_class, obj, info, map)\n    if !@allow_original_mapping and !obj.instance_variables.empty?\n      return nil\n    end\n    arytype = Mapping.obj2element(obj)\n    if arytype.name\n      arytype.namespace ||= RubyTypeNamespace\n    else\n      arytype = XSD::AnyTypeName\n    end\n    soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)\n    mark_marshalled_obj(obj, soap_obj)\n    obj.each do |item|\n      soap_obj.add(Mapping._obj2soap(item, map))\n    end\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    obj = Mapping.create_empty_object(obj_class)\n    mark_unmarshalled_obj(node, obj)\n    node.soap2array(obj) do |elem|\n      elem ? Mapping._soap2obj(elem, map) : nil\n    end\n    return true, obj\n  end\nend\n\nclass TypedArrayFactory_ < Factory\n  def initialize(allow_original_mapping = false)\n    super()\n    @allow_original_mapping = allow_original_mapping\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    if !@allow_original_mapping and !obj.instance_variables.empty?\n      return nil\n    end\n    arytype = info[:type] || info[0]\n    soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)\n    mark_marshalled_obj(obj, soap_obj)\n    obj.each do |var|\n      soap_obj.add(Mapping._obj2soap(var, map))\n    end\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    if node.rank > 1\n      return false\n    end\n    arytype = info[:type] || info[0]\n    unless node.arytype == arytype\n      return false\n    end\n    obj = Mapping.create_empty_object(obj_class)\n    mark_unmarshalled_obj(node, obj)\n    node.soap2array(obj) do |elem|\n      elem ? Mapping._soap2obj(elem, map) : nil\n    end\n    return true, obj\n  end\nend\n\nclass TypedStructFactory_ < Factory\n  def obj2soap(soap_class, obj, info, map)\n    type = info[:type] || info[0]\n    soap_obj = soap_class.new(type)\n    mark_marshalled_obj(obj, soap_obj)\n    if obj.class <= SOAP::Marshallable\n      setiv2soap(soap_obj, obj, map)\n    else\n      setiv2soap(soap_obj, obj, map)\n    end\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    type = info[:type] || info[0]\n    unless node.type == type\n      return false\n    end\n    obj = Mapping.create_empty_object(obj_class)\n    mark_unmarshalled_obj(node, obj)\n    setiv2obj(obj, node, map)\n    return true, obj\n  end\nend\n\nMapQName = XSD::QName.new(ApacheSOAPTypeNamespace, 'Map')\nclass HashFactory_ < Factory\n  def initialize(allow_original_mapping = false)\n    super()\n    @allow_original_mapping = allow_original_mapping\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    if !@allow_original_mapping and !obj.instance_variables.empty?\n      return nil\n    end\n    if !obj.default.nil? or\n\t(obj.respond_to?(:default_proc) and obj.default_proc)\n      return nil\n    end\n    soap_obj = SOAPStruct.new(MapQName)\n    mark_marshalled_obj(obj, soap_obj)\n    obj.each do |key, value|\n      elem = SOAPStruct.new\n      elem.add(\"key\", Mapping._obj2soap(key, map))\n      elem.add(\"value\", Mapping._obj2soap(value, map))\n      # ApacheAxis allows only 'item' here.\n      soap_obj.add(\"item\", elem)\n    end\n    soap_obj\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    unless node.type == MapQName\n      return false\n    end\n    if node.class == SOAPStruct and node.key?('default')\n      return false\n    end\n    obj = Mapping.create_empty_object(obj_class)\n    mark_unmarshalled_obj(node, obj)\n    if node.class == SOAPStruct\n      node.each do |key, value|\n\tobj[Mapping._soap2obj(value['key'], map)] =\n\t  Mapping._soap2obj(value['value'], map)\n      end\n    else\n      node.each do |value|\n\tobj[Mapping._soap2obj(value['key'], map)] =\n\t  Mapping._soap2obj(value['value'], map)\n      end\n    end\n    return true, obj\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/mapping/mapping.rb",
    "content": "# SOAP4R - Ruby type mapping utility.\n# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\n\n\nmodule SOAP\n\n\nmodule Mapping\n  RubyTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/1.6'\n  RubyTypeInstanceNamespace =\n    'http://www.ruby-lang.org/xmlns/ruby/type-instance'\n  RubyCustomTypeNamespace = 'http://www.ruby-lang.org/xmlns/ruby/type/custom'\n  ApacheSOAPTypeNamespace = 'http://xml.apache.org/xml-soap'\n\n\n  # TraverseSupport breaks following thread variables.\n  #   Thread.current[:SOAPMarshalDataKey]\n  module TraverseSupport\n    def mark_marshalled_obj(obj, soap_obj)\n      raise if obj.nil?\n      Thread.current[:SOAPMarshalDataKey][obj.__id__] = soap_obj\n    end\n\n    def mark_unmarshalled_obj(node, obj)\n      return if obj.nil?\n      # node.id is not Object#id but SOAPReference#id\n      Thread.current[:SOAPMarshalDataKey][node.id] = obj\n    end\n  end\n\n\n  EMPTY_OPT = {}\n  def self.obj2soap(obj, registry = nil, type = nil, opt = EMPTY_OPT)\n    registry ||= Mapping::DefaultRegistry\n    soap_obj = nil\n    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do\n      Thread.current[:SOAPMarshalDataKey] = {}\n      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE\n      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]\n      soap_obj = _obj2soap(obj, registry, type)\n    end\n    soap_obj\n  end\n\n  def self.soap2obj(node, registry = nil, klass = nil, opt = EMPTY_OPT)\n    registry ||= Mapping::DefaultRegistry\n    obj = nil\n    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do\n      Thread.current[:SOAPMarshalDataKey] = {}\n      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE\n      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]\n      obj = _soap2obj(node, registry, klass)\n    end\n    obj\n  end\n\n  def self.ary2soap(ary, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)\n    registry ||= Mapping::DefaultRegistry\n    type = XSD::QName.new(type_ns, typename)\n    soap_ary = SOAPArray.new(ValueArrayName, 1, type)\n    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do\n      Thread.current[:SOAPMarshalDataKey] = {}\n      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE\n      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]\n      ary.each do |ele|\n        soap_ary.add(_obj2soap(ele, registry, type))\n      end\n    end\n    soap_ary\n  end\n\n  def self.ary2md(ary, rank, type_ns = XSD::Namespace, typename = XSD::AnyTypeLiteral, registry = nil, opt = EMPTY_OPT)\n    registry ||= Mapping::DefaultRegistry\n    type = XSD::QName.new(type_ns, typename)\n    md_ary = SOAPArray.new(ValueArrayName, rank, type)\n    protect_threadvars(:SOAPMarshalDataKey, :SOAPExternalCES, :SOAPMarshalNoReference) do\n      Thread.current[:SOAPMarshalDataKey] = {}\n      Thread.current[:SOAPExternalCES] = opt[:external_ces] || $KCODE\n      Thread.current[:SOAPMarshalNoReference] = opt[:no_reference]\n      add_md_ary(md_ary, ary, [], registry)\n    end\n    md_ary\n  end\n\n  def self.fault2exception(fault, registry = nil)\n    registry ||= Mapping::DefaultRegistry\n    detail = if fault.detail\n        soap2obj(fault.detail, registry) || \"\"\n      else\n        \"\"\n      end\n    if detail.is_a?(Mapping::SOAPException)\n      begin\n        e = detail.to_e\n\tremote_backtrace = e.backtrace\n        e.set_backtrace(nil)\n        raise e # ruby sets current caller as local backtrace of e => e2.\n      rescue Exception => e\n\te.set_backtrace(remote_backtrace + e.backtrace[1..-1])\n        raise\n      end\n    else\n      fault.detail = detail\n      fault.set_backtrace(\n        if detail.is_a?(Array)\n\t  detail\n        else\n          [detail.to_s]\n        end\n      )\n      raise\n    end\n  end\n\n  def self._obj2soap(obj, registry, type = nil)\n    if referent = Thread.current[:SOAPMarshalDataKey][obj.__id__] and\n        !Thread.current[:SOAPMarshalNoReference]\n      SOAPReference.new(referent)\n    elsif registry\n      registry.obj2soap(obj, type)\n    else\n      raise MappingError.new(\"no mapping registry given\")\n    end\n  end\n\n  def self._soap2obj(node, registry, klass = nil)\n    if node.nil?\n      return nil\n    elsif node.is_a?(SOAPReference)\n      target = node.__getobj__\n      # target.id is not Object#id but SOAPReference#id\n      if referent = Thread.current[:SOAPMarshalDataKey][target.id] and\n          !Thread.current[:SOAPMarshalNoReference]\n        return referent\n      else\n        return _soap2obj(target, registry, klass)\n      end\n    end\n    return registry.soap2obj(node, klass)\n  end\n\n  if Object.respond_to?(:allocate)\n    # ruby/1.7 or later.\n    def self.create_empty_object(klass)\n      klass.allocate\n    end\n  else\n    MARSHAL_TAG = {\n      String => ['\"', 1],\n      Regexp => ['/', 2],\n      Array => ['[', 1],\n      Hash => ['{', 1]\n    }\n    def self.create_empty_object(klass)\n      if klass <= Struct\n\tname = klass.name\n\treturn ::Marshal.load(sprintf(\"\\004\\006S:%c%s\\000\", name.length + 5, name))\n      end\n      if MARSHAL_TAG.has_key?(klass)\n\ttag, terminate = MARSHAL_TAG[klass]\n\treturn ::Marshal.load(sprintf(\"\\004\\006%s%s\", tag, \"\\000\" * terminate))\n      end\n      MARSHAL_TAG.each do |k, v|\n\tif klass < k\n\t  name = klass.name\n\t  tag, terminate = v\n\t  return ::Marshal.load(sprintf(\"\\004\\006C:%c%s%s%s\", name.length + 5, name, tag, \"\\000\" * terminate))\n\tend\n      end\n      name = klass.name\n      ::Marshal.load(sprintf(\"\\004\\006o:%c%s\\000\", name.length + 5, name))\n    end\n  end\n\n  # Allow only (Letter | '_') (Letter | Digit | '-' | '_')* here.\n  # Caution: '.' is not allowed here.\n  # To follow XML spec., it should be NCName.\n  #   (denied chars) => .[0-F][0-F]\n  #   ex. a.b => a.2eb\n  #\n  def self.name2elename(name)\n    name.gsub(/([^a-zA-Z0-9:_\\-]+)/n) {\n      '.' << $1.unpack('H2' * $1.size).join('.')\n    }.gsub(/::/n, '..')\n  end\n\n  def self.elename2name(name)\n    name.gsub(/\\.\\./n, '::').gsub(/((?:\\.[0-9a-fA-F]{2})+)/n) {\n      [$1.delete('.')].pack('H*')\n    }\n  end\n\n  def self.const_from_name(name, lenient = false)\n    const = ::Object\n    name.sub(/\\A::/, '').split('::').each do |const_str|\n      if XSD::CodeGen::GenSupport.safeconstname?(const_str)\n        if const.const_defined?(const_str)\n          const = const.const_get(const_str)\n          next\n        end\n      elsif lenient\n        const_str = XSD::CodeGen::GenSupport.safeconstname(const_str)\n        if const.const_defined?(const_str)\n          const = const.const_get(const_str)\n          next\n        end\n      end\n      return nil\n    end\n    const\n  end\n\n  def self.class_from_name(name, lenient = false)\n    const = const_from_name(name, lenient)\n    if const.is_a?(::Class)\n      const\n    else\n      nil\n    end\n  end\n\n  def self.module_from_name(name, lenient = false)\n    const = const_from_name(name, lenient)\n    if const.is_a?(::Module)\n      const\n    else\n      nil\n    end\n  end\n\n  def self.class2qname(klass)\n    name = schema_type_definition(klass)\n    namespace = schema_ns_definition(klass)\n    XSD::QName.new(namespace, name)\n  end\n\n  def self.class2element(klass)\n    type = Mapping.class2qname(klass)\n    type.name ||= Mapping.name2elename(klass.name)\n    type.namespace ||= RubyCustomTypeNamespace\n    type\n  end\n\n  def self.obj2element(obj)\n    name = namespace = nil\n    ivars = obj.instance_variables\n    if ivars.include?('@schema_type')\n      name = obj.instance_variable_get('@schema_type')\n    end\n    if ivars.include?('@schema_ns')\n      namespace = obj.instance_variable_get('@schema_ns')\n    end\n    if !name or !namespace\n      class2qname(obj.class)\n    else\n      XSD::QName.new(namespace, name)\n    end\n  end\n\n  def self.define_singleton_method(obj, name, &block)\n    sclass = (class << obj; self; end)\n    sclass.class_eval {\n      define_method(name, &block)\n    }\n  end\n\n  def self.get_attribute(obj, attr_name)\n    if obj.is_a?(::Hash)\n      obj[attr_name] || obj[attr_name.intern]\n    else\n      name = XSD::CodeGen::GenSupport.safevarname(attr_name)\n      if obj.instance_variables.include?('@' + name)\n        obj.instance_variable_get('@' + name)\n      elsif ((obj.is_a?(::Struct) or obj.is_a?(Marshallable)) and\n          obj.respond_to?(name))\n        obj.__send__(name)\n      end\n    end\n  end\n\n  def self.set_attributes(obj, values)\n    if obj.is_a?(::SOAP::Mapping::Object)\n      values.each do |attr_name, value|\n        obj.__add_xmlele_value(attr_name, value)\n      end\n    else\n      values.each do |attr_name, value|\n        name = XSD::CodeGen::GenSupport.safevarname(attr_name)\n        setter = name + \"=\"\n        if obj.respond_to?(setter)\n          obj.__send__(setter, value)\n        else\n          obj.instance_variable_set('@' + name, value)\n          begin\n            define_attr_accessor(obj, name,\n              proc { instance_variable_get('@' + name) },\n              proc { |value| instance_variable_set('@' + name, value) })\n          rescue TypeError\n            # singleton class may not exist (e.g. Float)\n          end\n        end\n      end\n    end\n  end\n\n  def self.define_attr_accessor(obj, name, getterproc, setterproc = nil)\n    define_singleton_method(obj, name, &getterproc)\n    define_singleton_method(obj, name + '=', &setterproc) if setterproc\n  end\n\n  def self.schema_type_definition(klass)\n    class_schema_variable(:schema_type, klass)\n  end\n\n  def self.schema_ns_definition(klass)\n    class_schema_variable(:schema_ns, klass)\n  end\n\n  def self.schema_element_definition(klass)\n    schema_element = class_schema_variable(:schema_element, klass) or return nil\n    schema_ns = schema_ns_definition(klass)\n    elements = []\n    as_array = []\n    schema_element.each do |varname, definition|\n      class_name, name = definition\n      if /\\[\\]$/ =~ class_name\n        class_name = class_name.sub(/\\[\\]$/, '')\n        as_array << (name ? name.name : varname)\n      end\n      elements << [name || XSD::QName.new(schema_ns, varname), class_name]\n    end\n    [elements, as_array]\n  end\n\n  def self.schema_attribute_definition(klass)\n    class_schema_variable(:schema_attribute, klass)\n  end\n\n  class << Mapping\n  private\n\n    def class_schema_variable(sym, klass)\n      var = \"@@#{sym}\"\n      klass.class_variables.include?(var) ? klass.class_eval(var) : nil\n    end\n\n    def protect_threadvars(*symbols)\n      backup = {}\n      begin\n        symbols.each do |sym|\n          backup[sym] = Thread.current[sym]\n        end\n        yield\n      ensure\n        symbols.each do |sym|\n          Thread.current[sym] = backup[sym]\n        end\n      end\n    end\n\n    def add_md_ary(md_ary, ary, indices, registry)\n      for idx in 0..(ary.size - 1)\n        if ary[idx].is_a?(Array)\n          add_md_ary(md_ary, ary[idx], indices + [idx], registry)\n        else\n          md_ary[*(indices + [idx])] = _obj2soap(ary[idx], registry)\n        end\n      end\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/mapping/registry.rb",
    "content": "# SOAP4R - Mapping registry.\n# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/baseData'\nrequire 'soap/mapping/mapping'\nrequire 'soap/mapping/typeMap'\nrequire 'soap/mapping/factory'\nrequire 'soap/mapping/rubytypeFactory'\n\n\nmodule SOAP\n\n\nmodule Marshallable\n  # @@type_ns = Mapping::RubyCustomTypeNamespace\nend\n\n\nmodule Mapping\n\n  \nmodule MappedException; end\n\n\nRubyTypeName = XSD::QName.new(RubyTypeInstanceNamespace, 'rubyType')\nRubyExtendName = XSD::QName.new(RubyTypeInstanceNamespace, 'extends')\nRubyIVarName = XSD::QName.new(RubyTypeInstanceNamespace, 'ivars')\n\n\n# Inner class to pass an exception.\nclass SOAPException; include Marshallable\n  attr_reader :excn_type_name, :cause\n  def initialize(e)\n    @excn_type_name = Mapping.name2elename(e.class.to_s)\n    @cause = e\n  end\n\n  def to_e\n    if @cause.is_a?(::Exception)\n      @cause.extend(::SOAP::Mapping::MappedException)\n      return @cause\n    elsif @cause.respond_to?(:message) and @cause.respond_to?(:backtrace)\n      e = RuntimeError.new(@cause.message)\n      e.set_backtrace(@cause.backtrace)\n      return e\n    end\n    klass = Mapping.class_from_name(Mapping.elename2name(@excn_type_name.to_s))\n    if klass.nil? or not klass <= ::Exception\n      return RuntimeError.new(@cause.inspect)\n    end\n    obj = klass.new(@cause.message)\n    obj.extend(::SOAP::Mapping::MappedException)\n    obj\n  end\nend\n\n\n# For anyType object: SOAP::Mapping::Object not ::Object\nclass Object; include Marshallable\n  def initialize\n    @__xmlele_type = {}\n    @__xmlele = []\n    @__xmlattr = {}\n  end\n\n  def inspect\n    sprintf(\"#<%s:0x%x%s>\", self.class.name, __id__,\n      @__xmlele.collect { |name, value| \" #{name}=#{value.inspect}\" }.join)\n  end\n\n  def __xmlattr\n    @__xmlattr\n  end\n\n  def __xmlele\n    @__xmlele\n  end\n\n  def [](qname)\n    unless qname.is_a?(XSD::QName)\n      qname = XSD::QName.new(nil, qname)\n    end\n    @__xmlele.each do |k, v|\n      return v if k == qname\n    end\n    # fallback\n    @__xmlele.each do |k, v|\n      return v if k.name == qname.name\n    end\n    nil\n  end\n\n  def []=(qname, value)\n    unless qname.is_a?(XSD::QName)\n      qname = XSD::QName.new(nil, qname)\n    end\n    found = false\n    @__xmlele.each do |pair|\n      if pair[0] == qname\n        found = true\n        pair[1] = value\n      end\n    end\n    unless found\n      __define_attr_accessor(qname)\n      @__xmlele << [qname, value]\n    end\n    @__xmlele_type[qname] = :single\n  end\n\n  def __add_xmlele_value(qname, value)\n    found = false\n    @__xmlele.map! do |k, v|\n      if k == qname\n        found = true\n        [k, __set_xmlele_value(k, v, value)]\n      else\n        [k, v]\n      end\n    end\n    unless found\n      __define_attr_accessor(qname)\n      @__xmlele << [qname, value]\n      @__xmlele_type[qname] = :single\n    end\n    value\n  end\n\nprivate\n\n  if RUBY_VERSION > \"1.7.0\"\n    def __define_attr_accessor(qname)\n      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)\n      Mapping.define_attr_accessor(self, name,\n        proc { self[qname] },\n        proc { |value| self[qname] = value })\n    end\n  else\n    def __define_attr_accessor(qname)\n      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)\n      instance_eval <<-EOS\n        def #{name}\n          self[#{qname.dump}]\n        end\n\n        def #{name}=(value)\n          self[#{qname.dump}] = value\n        end\n      EOS\n    end\n  end\n\n  def __set_xmlele_value(key, org, value)\n    case @__xmlele_type[key]\n    when :multi\n      org << value\n      org\n    when :single\n      @__xmlele_type[key] = :multi\n      [org, value]\n    else\n      raise RuntimeError.new(\"unknown type\")\n    end\n  end\nend\n\n\nclass MappingError < Error; end\n\n\nclass Registry\n  class Map\n    def initialize(registry)\n      @obj2soap = {}\n      @soap2obj = {}\n      @registry = registry\n    end\n\n    def obj2soap(obj)\n      klass = obj.class\n      if map = @obj2soap[klass]\n        map.each do |soap_class, factory, info|\n          ret = factory.obj2soap(soap_class, obj, info, @registry)\n          return ret if ret\n        end\n      end\n      ancestors = klass.ancestors\n      ancestors.delete(klass)\n      ancestors.delete(::Object)\n      ancestors.delete(::Kernel)\n      ancestors.each do |klass|\n        if map = @obj2soap[klass]\n          map.each do |soap_class, factory, info|\n            if info[:derived_class]\n              ret = factory.obj2soap(soap_class, obj, info, @registry)\n              return ret if ret\n            end\n          end\n        end\n      end\n      nil\n    end\n\n    def soap2obj(node, klass = nil)\n      if map = @soap2obj[node.class]\n        map.each do |obj_class, factory, info|\n          next if klass and obj_class != klass\n          conv, obj = factory.soap2obj(obj_class, node, info, @registry)\n          return true, obj if conv\n        end\n      end\n      return false, nil\n    end\n\n    # Give priority to former entry.\n    def init(init_map = [])\n      clear\n      init_map.reverse_each do |obj_class, soap_class, factory, info|\n        add(obj_class, soap_class, factory, info)\n      end\n    end\n\n    # Give priority to latter entry.\n    def add(obj_class, soap_class, factory, info)\n      info ||= {}\n      (@obj2soap[obj_class] ||= []).unshift([soap_class, factory, info])\n      (@soap2obj[soap_class] ||= []).unshift([obj_class, factory, info])\n    end\n\n    def clear\n      @obj2soap.clear\n      @soap2obj.clear\n    end\n\n    def find_mapped_soap_class(target_obj_class)\n      map = @obj2soap[target_obj_class]\n      map.empty? ? nil : map[0][1]\n    end\n\n    def find_mapped_obj_class(target_soap_class)\n      map = @soap2obj[target_soap_class]\n      map.empty? ? nil : map[0][0]\n    end\n  end\n\n  StringFactory = StringFactory_.new\n  BasetypeFactory = BasetypeFactory_.new\n  DateTimeFactory = DateTimeFactory_.new\n  ArrayFactory = ArrayFactory_.new\n  Base64Factory = Base64Factory_.new\n  URIFactory = URIFactory_.new\n  TypedArrayFactory = TypedArrayFactory_.new\n  TypedStructFactory = TypedStructFactory_.new\n\n  HashFactory = HashFactory_.new\n\n  SOAPBaseMap = [\n    [::NilClass,     ::SOAP::SOAPNil,        BasetypeFactory],\n    [::TrueClass,    ::SOAP::SOAPBoolean,    BasetypeFactory],\n    [::FalseClass,   ::SOAP::SOAPBoolean,    BasetypeFactory],\n    [::String,       ::SOAP::SOAPString,     StringFactory],\n    [::DateTime,     ::SOAP::SOAPDateTime,   DateTimeFactory],\n    [::Date,         ::SOAP::SOAPDate,       DateTimeFactory],\n    [::Time,         ::SOAP::SOAPDateTime,   DateTimeFactory],\n    [::Time,         ::SOAP::SOAPTime,       DateTimeFactory],\n    [::Float,        ::SOAP::SOAPDouble,     BasetypeFactory,\n      {:derived_class => true}],\n    [::Float,        ::SOAP::SOAPFloat,      BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPInt,        BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPLong,       BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPInteger,    BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPShort,      BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPByte,       BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPNonPositiveInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPNegativeInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPNonNegativeInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPPositiveInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedLong, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedInt, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedShort, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedByte, BasetypeFactory,\n      {:derived_class => true}],\n    [::URI::Generic, ::SOAP::SOAPAnyURI,     URIFactory,\n      {:derived_class => true}],\n    [::String,       ::SOAP::SOAPBase64,     Base64Factory],\n    [::String,       ::SOAP::SOAPHexBinary,  Base64Factory],\n    [::String,       ::SOAP::SOAPDecimal,    BasetypeFactory],\n    [::String,       ::SOAP::SOAPDuration,   BasetypeFactory],\n    [::String,       ::SOAP::SOAPGYearMonth, BasetypeFactory],\n    [::String,       ::SOAP::SOAPGYear,      BasetypeFactory],\n    [::String,       ::SOAP::SOAPGMonthDay,  BasetypeFactory],\n    [::String,       ::SOAP::SOAPGDay,       BasetypeFactory],\n    [::String,       ::SOAP::SOAPGMonth,     BasetypeFactory],\n    [::String,       ::SOAP::SOAPQName,      BasetypeFactory],\n\n    [::Hash,         ::SOAP::SOAPArray,      HashFactory],\n    [::Hash,         ::SOAP::SOAPStruct,     HashFactory],\n\n    [::Array,        ::SOAP::SOAPArray,      ArrayFactory,\n      {:derived_class => true}],\n\n    [::SOAP::Mapping::SOAPException,\n\t\t     ::SOAP::SOAPStruct,     TypedStructFactory,\n      {:type => XSD::QName.new(RubyCustomTypeNamespace, \"SOAPException\")}],\n ]\n\n  RubyOriginalMap = [\n    [::NilClass,     ::SOAP::SOAPNil,        BasetypeFactory],\n    [::TrueClass,    ::SOAP::SOAPBoolean,    BasetypeFactory],\n    [::FalseClass,   ::SOAP::SOAPBoolean,    BasetypeFactory],\n    [::String,       ::SOAP::SOAPString,     StringFactory],\n    [::DateTime,     ::SOAP::SOAPDateTime,   DateTimeFactory],\n    [::Date,         ::SOAP::SOAPDate,       DateTimeFactory],\n    [::Time,         ::SOAP::SOAPDateTime,   DateTimeFactory],\n    [::Time,         ::SOAP::SOAPTime,       DateTimeFactory],\n    [::Float,        ::SOAP::SOAPDouble,     BasetypeFactory,\n      {:derived_class => true}],\n    [::Float,        ::SOAP::SOAPFloat,      BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPInt,        BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPLong,       BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPInteger,    BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPShort,      BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPByte,       BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPNonPositiveInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPNegativeInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPNonNegativeInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPPositiveInteger, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedLong, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedInt, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedShort, BasetypeFactory,\n      {:derived_class => true}],\n    [::Integer,      ::SOAP::SOAPUnsignedByte, BasetypeFactory,\n      {:derived_class => true}],\n    [::URI::Generic, ::SOAP::SOAPAnyURI,     URIFactory,\n      {:derived_class => true}],\n    [::String,       ::SOAP::SOAPBase64,     Base64Factory],\n    [::String,       ::SOAP::SOAPHexBinary,  Base64Factory],\n    [::String,       ::SOAP::SOAPDecimal,    BasetypeFactory],\n    [::String,       ::SOAP::SOAPDuration,   BasetypeFactory],\n    [::String,       ::SOAP::SOAPGYearMonth, BasetypeFactory],\n    [::String,       ::SOAP::SOAPGYear,      BasetypeFactory],\n    [::String,       ::SOAP::SOAPGMonthDay,  BasetypeFactory],\n    [::String,       ::SOAP::SOAPGDay,       BasetypeFactory],\n    [::String,       ::SOAP::SOAPGMonth,     BasetypeFactory],\n    [::String,       ::SOAP::SOAPQName,      BasetypeFactory],\n\n    [::Hash,         ::SOAP::SOAPArray,      HashFactory],\n    [::Hash,         ::SOAP::SOAPStruct,     HashFactory],\n\n    # Does not allow Array's subclass here.\n    [::Array,        ::SOAP::SOAPArray,      ArrayFactory],\n\n    [::SOAP::Mapping::SOAPException,\n                     ::SOAP::SOAPStruct,     TypedStructFactory,\n      {:type => XSD::QName.new(RubyCustomTypeNamespace, \"SOAPException\")}],\n  ]\n\n  attr_accessor :default_factory\n  attr_accessor :excn_handler_obj2soap\n  attr_accessor :excn_handler_soap2obj\n\n  def initialize(config = {})\n    @config = config\n    @map = Map.new(self)\n    if @config[:allow_original_mapping]\n      @allow_original_mapping = true\n      @map.init(RubyOriginalMap)\n    else\n      @allow_original_mapping = false\n      @map.init(SOAPBaseMap)\n    end\n    @allow_untyped_struct = @config.key?(:allow_untyped_struct) ?\n      @config[:allow_untyped_struct] : true\n    @rubytype_factory = RubytypeFactory.new(\n      :allow_untyped_struct => @allow_untyped_struct,\n      :allow_original_mapping => @allow_original_mapping\n    )\n    @default_factory = @rubytype_factory\n    @excn_handler_obj2soap = nil\n    @excn_handler_soap2obj = nil\n  end\n\n  def add(obj_class, soap_class, factory, info = nil)\n    @map.add(obj_class, soap_class, factory, info)\n  end\n  alias set add\n\n  # general Registry ignores type_qname\n  def obj2soap(obj, type_qname = nil)\n    soap = _obj2soap(obj)\n    if @allow_original_mapping\n      addextend2soap(soap, obj)\n    end\n    soap\n  end\n\n  def soap2obj(node, klass = nil)\n    obj = _soap2obj(node, klass)\n    if @allow_original_mapping\n      addextend2obj(obj, node.extraattr[RubyExtendName])\n      addiv2obj(obj, node.extraattr[RubyIVarName])\n    end\n    obj\n  end\n\n  def find_mapped_soap_class(obj_class)\n    @map.find_mapped_soap_class(obj_class)\n  end\n\n  def find_mapped_obj_class(soap_class)\n    @map.find_mapped_obj_class(soap_class)\n  end\n\nprivate\n\n  def _obj2soap(obj)\n    ret = nil\n    if obj.is_a?(SOAPStruct) or obj.is_a?(SOAPArray)\n      obj.replace do |ele|\n        Mapping._obj2soap(ele, self)\n      end\n      return obj\n    elsif obj.is_a?(SOAPBasetype)\n      return obj\n    end\n    begin \n      ret = @map.obj2soap(obj) ||\n        @default_factory.obj2soap(nil, obj, nil, self)\n      return ret if ret\n    rescue MappingError\n    end\n    if @excn_handler_obj2soap\n      ret = @excn_handler_obj2soap.call(obj) { |yield_obj|\n        Mapping._obj2soap(yield_obj, self)\n      }\n      return ret if ret\n    end\n    raise MappingError.new(\"Cannot map #{ obj.class.name } to SOAP/OM.\")\n  end\n\n  # Might return nil as a mapping result.\n  def _soap2obj(node, klass = nil)\n    if node.extraattr.key?(RubyTypeName)\n      conv, obj = @rubytype_factory.soap2obj(nil, node, nil, self)\n      return obj if conv\n    else\n      conv, obj = @map.soap2obj(node, klass)\n      return obj if conv\n      conv, obj = @default_factory.soap2obj(nil, node, nil, self)\n      return obj if conv\n    end\n    if @excn_handler_soap2obj\n      begin\n        return @excn_handler_soap2obj.call(node) { |yield_node|\n\t    Mapping._soap2obj(yield_node, self)\n\t  }\n      rescue Exception\n      end\n    end\n    raise MappingError.new(\"Cannot map #{ node.type.name } to Ruby object.\")\n  end\n\n  def addiv2obj(obj, attr)\n    return unless attr\n    vars = {}\n    attr.__getobj__.each do |name, value|\n      vars[name] = Mapping._soap2obj(value, self)\n    end\n    Mapping.set_attributes(obj, vars)\n  end\n\n  if RUBY_VERSION >= '1.8.0'\n    def addextend2obj(obj, attr)\n      return unless attr\n      attr.split(/ /).reverse_each do |mstr|\n\tobj.extend(Mapping.module_from_name(mstr))\n      end\n    end\n  else\n    # (class < false; self; end).ancestors includes \"TrueClass\" under 1.6...\n    def addextend2obj(obj, attr)\n      return unless attr\n      attr.split(/ /).reverse_each do |mstr|\n\tm = Mapping.module_from_name(mstr)\n\tobj.extend(m)\n      end\n    end\n  end\n\n  def addextend2soap(node, obj)\n    return if obj.is_a?(Symbol) or obj.is_a?(Fixnum)\n    list = (class << obj; self; end).ancestors - obj.class.ancestors\n    unless list.empty?\n      node.extraattr[RubyExtendName] = list.collect { |c|\n\tif c.name.empty?\n  \t  raise TypeError.new(\"singleton can't be dumped #{ obj }\")\n   \tend\n\tc.name\n      }.join(\" \")\n    end\n  end\n\nend\n\n\nDefaultRegistry = Registry.new\nRubyOriginalRegistry = Registry.new(:allow_original_mapping => true)\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/mapping/rubytypeFactory.rb",
    "content": "# SOAP4R - Ruby type mapping factory.\n# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule SOAP\nmodule Mapping\n\n\nclass RubytypeFactory < Factory\n  TYPE_STRING = XSD::QName.new(RubyTypeNamespace, 'String')\n  TYPE_TIME = XSD::QName.new(RubyTypeNamespace, 'Time')\n  TYPE_ARRAY = XSD::QName.new(RubyTypeNamespace, 'Array')\n  TYPE_REGEXP = XSD::QName.new(RubyTypeNamespace, 'Regexp')\n  TYPE_RANGE = XSD::QName.new(RubyTypeNamespace, 'Range')\n  TYPE_CLASS = XSD::QName.new(RubyTypeNamespace, 'Class')\n  TYPE_MODULE = XSD::QName.new(RubyTypeNamespace, 'Module')\n  TYPE_SYMBOL = XSD::QName.new(RubyTypeNamespace, 'Symbol')\n  TYPE_STRUCT = XSD::QName.new(RubyTypeNamespace, 'Struct')\n  TYPE_HASH = XSD::QName.new(RubyTypeNamespace, 'Map')\n\n  def initialize(config = {})\n    @config = config\n    @allow_untyped_struct = @config.key?(:allow_untyped_struct) ?\n      @config[:allow_untyped_struct] : true\n    @allow_original_mapping = @config.key?(:allow_original_mapping) ?\n      @config[:allow_original_mapping] : false\n    @string_factory = StringFactory_.new(true)\n    @basetype_factory = BasetypeFactory_.new(true)\n    @datetime_factory = DateTimeFactory_.new(true)\n    @array_factory = ArrayFactory_.new(true)\n    @hash_factory = HashFactory_.new(true)\n  end\n\n  def obj2soap(soap_class, obj, info, map)\n    param = nil\n    case obj\n    when ::String\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @string_factory.obj2soap(SOAPString, obj, info, map)\n      if obj.class != String\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      addiv2soapattr(param, obj, map)\n    when ::Time\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @datetime_factory.obj2soap(SOAPDateTime, obj, info, map)\n      if obj.class != Time\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      addiv2soapattr(param, obj, map)\n    when ::Array\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @array_factory.obj2soap(nil, obj, info, map)\n      if obj.class != Array\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      addiv2soapattr(param, obj, map)\n    when ::NilClass\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @basetype_factory.obj2soap(SOAPNil, obj, info, map)\n      addiv2soapattr(param, obj, map)\n    when ::FalseClass, ::TrueClass\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @basetype_factory.obj2soap(SOAPBoolean, obj, info, map)\n      addiv2soapattr(param, obj, map)\n    when ::Integer\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @basetype_factory.obj2soap(SOAPInt, obj, info, map)\n      param ||= @basetype_factory.obj2soap(SOAPInteger, obj, info, map)\n      param ||= @basetype_factory.obj2soap(SOAPDecimal, obj, info, map)\n      addiv2soapattr(param, obj, map)\n    when ::Float\n      unless @allow_original_mapping\n        return nil\n      end\n      param = @basetype_factory.obj2soap(SOAPDouble, obj, info, map)\n      if obj.class != Float\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      addiv2soapattr(param, obj, map)\n    when ::Hash\n      unless @allow_original_mapping\n        return nil\n      end\n      if obj.respond_to?(:default_proc) && obj.default_proc\n        raise TypeError.new(\"cannot dump hash with default proc\")\n      end\n      param = SOAPStruct.new(TYPE_HASH)\n      mark_marshalled_obj(obj, param)\n      if obj.class != Hash\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      obj.each do |key, value|\n        elem = SOAPStruct.new # Undefined type.\n        elem.add(\"key\", Mapping._obj2soap(key, map))\n        elem.add(\"value\", Mapping._obj2soap(value, map))\n        param.add(\"item\", elem)\n      end\n      param.add('default', Mapping._obj2soap(obj.default, map))\n      addiv2soapattr(param, obj, map)\n    when ::Regexp\n      unless @allow_original_mapping\n        return nil\n      end\n      param = SOAPStruct.new(TYPE_REGEXP)\n      mark_marshalled_obj(obj, param)\n      if obj.class != Regexp\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      param.add('source', SOAPBase64.new(obj.source))\n      if obj.respond_to?('options')\n        # Regexp#options is from Ruby/1.7\n        options = obj.options\n      else\n        options = 0\n        obj.inspect.sub(/^.*\\//, '').each_byte do |c|\n          options += case c\n            when ?i\n              1\n            when ?x\n              2\n            when ?m\n              4\n            when ?n\n              16\n            when ?e\n              32\n            when ?s\n              48\n            when ?u\n              64\n            end\n        end\n      end\n      param.add('options', SOAPInt.new(options))\n      addiv2soapattr(param, obj, map)\n    when ::Range\n      unless @allow_original_mapping\n        return nil\n      end\n      param = SOAPStruct.new(TYPE_RANGE)\n      mark_marshalled_obj(obj, param)\n      if obj.class != Range\n        param.extraattr[RubyTypeName] = obj.class.name\n      end\n      param.add('begin', Mapping._obj2soap(obj.begin, map))\n      param.add('end', Mapping._obj2soap(obj.end, map))\n      param.add('exclude_end', SOAP::SOAPBoolean.new(obj.exclude_end?))\n      addiv2soapattr(param, obj, map)\n    when ::Class\n      unless @allow_original_mapping\n        return nil\n      end\n      if obj.to_s[0] == ?#\n        raise TypeError.new(\"can't dump anonymous class #{obj}\")\n      end\n      param = SOAPStruct.new(TYPE_CLASS)\n      mark_marshalled_obj(obj, param)\n      param.add('name', SOAPString.new(obj.name))\n      addiv2soapattr(param, obj, map)\n    when ::Module\n      unless @allow_original_mapping\n        return nil\n      end\n      if obj.to_s[0] == ?#\n        raise TypeError.new(\"can't dump anonymous module #{obj}\")\n      end\n      param = SOAPStruct.new(TYPE_MODULE)\n      mark_marshalled_obj(obj, param)\n      param.add('name', SOAPString.new(obj.name))\n      addiv2soapattr(param, obj, map)\n    when ::Symbol\n      unless @allow_original_mapping\n        return nil\n      end\n      param = SOAPStruct.new(TYPE_SYMBOL)\n      mark_marshalled_obj(obj, param)\n      param.add('id', SOAPString.new(obj.id2name))\n      addiv2soapattr(param, obj, map)\n    when ::Struct\n      unless @allow_original_mapping\n        # treat it as an user defined class. [ruby-talk:104980]\n        #param = unknownobj2soap(soap_class, obj, info, map)\n        param = SOAPStruct.new(XSD::AnyTypeName)\n        mark_marshalled_obj(obj, param)\n        obj.members.each do |member|\n          param.add(Mapping.name2elename(member),\n            Mapping._obj2soap(obj[member], map))\n        end\n      else\n        param = SOAPStruct.new(TYPE_STRUCT)\n        mark_marshalled_obj(obj, param)\n        param.add('type', ele_type = SOAPString.new(obj.class.to_s))\n        ele_member = SOAPStruct.new\n        obj.members.each do |member|\n          ele_member.add(Mapping.name2elename(member),\n            Mapping._obj2soap(obj[member], map))\n        end\n        param.add('member', ele_member)\n        addiv2soapattr(param, obj, map)\n      end\n    when ::IO, ::Binding, ::Continuation, ::Data, ::Dir, ::File::Stat,\n        ::MatchData, Method, ::Proc, ::Thread, ::ThreadGroup\n        # from 1.8: Process::Status, UnboundMethod\n      return nil\n    when ::SOAP::Mapping::Object\n      param = SOAPStruct.new(XSD::AnyTypeName)\n      mark_marshalled_obj(obj, param)\n      obj.__xmlele.each do |key, value|\n        param.add(key.name, Mapping._obj2soap(value, map))\n      end\n      obj.__xmlattr.each do |key, value|\n        param.extraattr[key] = value\n      end\n    when ::Exception\n      typestr = Mapping.name2elename(obj.class.to_s)\n      param = SOAPStruct.new(XSD::QName.new(RubyTypeNamespace, typestr))\n      mark_marshalled_obj(obj, param)\n      param.add('message', Mapping._obj2soap(obj.message, map))\n      param.add('backtrace', Mapping._obj2soap(obj.backtrace, map))\n      addiv2soapattr(param, obj, map)\n    else\n      param = unknownobj2soap(soap_class, obj, info, map)\n    end\n    param\n  end\n\n  def soap2obj(obj_class, node, info, map)\n    rubytype = node.extraattr[RubyTypeName]\n    if rubytype or node.type.namespace == RubyTypeNamespace\n      rubytype2obj(node, info, map, rubytype)\n    elsif node.type == XSD::AnyTypeName or node.type == XSD::AnySimpleTypeName\n      anytype2obj(node, info, map)\n    else\n      unknowntype2obj(node, info, map)\n    end\n  end\n\nprivate\n\n  def addiv2soapattr(node, obj, map)\n    return if obj.instance_variables.empty?\n    ivars = SOAPStruct.new    # Undefined type.\n    setiv2soap(ivars, obj, map)\n    node.extraattr[RubyIVarName] = ivars\n  end\n\n  def unknownobj2soap(soap_class, obj, info, map)\n    if obj.class.name.empty?\n      raise TypeError.new(\"can't dump anonymous class #{obj}\")\n    end\n    singleton_class = class << obj; self; end\n    if !singleton_methods_true(obj).empty? or\n\t!singleton_class.instance_variables.empty?\n      raise TypeError.new(\"singleton can't be dumped #{obj}\")\n    end\n    if !(singleton_class.ancestors - obj.class.ancestors).empty?\n      typestr = Mapping.name2elename(obj.class.to_s)\n      type = XSD::QName.new(RubyTypeNamespace, typestr)\n    else\n      type = Mapping.class2element(obj.class)\n    end\n    param = SOAPStruct.new(type)\n    mark_marshalled_obj(obj, param)\n    setiv2soap(param, obj, map)\n    param\n  end\n\n  if RUBY_VERSION >= '1.8.0'\n    def singleton_methods_true(obj)\n      obj.singleton_methods(true)\n    end\n  else\n    def singleton_methods_true(obj)\n      obj.singleton_methods\n    end\n  end\n\n  def rubytype2obj(node, info, map, rubytype)\n    klass = rubytype ? Mapping.class_from_name(rubytype) : nil\n    obj = nil\n    case node\n    when SOAPString\n      return @string_factory.soap2obj(klass || String, node, info, map)\n    when SOAPDateTime\n      #return @datetime_factory.soap2obj(klass || Time, node, info, map)\n      klass ||= Time\n      t = node.to_time\n      arg = [t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec]\n      obj = t.gmt? ? klass.gm(*arg) : klass.local(*arg)\n      mark_unmarshalled_obj(node, obj)\n      return true, obj\n    when SOAPArray\n      return @array_factory.soap2obj(klass || Array, node, info, map)\n    when SOAPNil, SOAPBoolean, SOAPInt, SOAPInteger, SOAPDecimal, SOAPDouble\n      return @basetype_factory.soap2obj(nil, node, info, map)\n    when SOAPStruct\n      return rubytypestruct2obj(node, info, map, rubytype)\n    else\n      raise\n    end\n  end\n\n  def rubytypestruct2obj(node, info, map, rubytype)\n    klass = rubytype ? Mapping.class_from_name(rubytype) : nil\n    obj = nil\n    case node.type\n    when TYPE_HASH\n      klass = rubytype ? Mapping.class_from_name(rubytype) : Hash\n      obj = Mapping.create_empty_object(klass)\n      mark_unmarshalled_obj(node, obj)\n      node.each do |key, value|\n        next unless key == 'item'\n        obj[Mapping._soap2obj(value['key'], map)] =\n          Mapping._soap2obj(value['value'], map)\n      end\n      if node.key?('default')\n        obj.default = Mapping._soap2obj(node['default'], map)\n      end\n    when TYPE_REGEXP\n      klass = rubytype ? Mapping.class_from_name(rubytype) : Regexp\n      obj = Mapping.create_empty_object(klass)\n      mark_unmarshalled_obj(node, obj)\n      source = node['source'].string\n      options = node['options'].data || 0\n      Regexp.instance_method(:initialize).bind(obj).call(source, options)\n    when TYPE_RANGE\n      klass = rubytype ? Mapping.class_from_name(rubytype) : Range\n      obj = Mapping.create_empty_object(klass)\n      mark_unmarshalled_obj(node, obj)\n      first = Mapping._soap2obj(node['begin'], map)\n      last = Mapping._soap2obj(node['end'], map)\n      exclude_end = node['exclude_end'].data\n      Range.instance_method(:initialize).bind(obj).call(first, last, exclude_end)\n    when TYPE_CLASS\n      obj = Mapping.class_from_name(node['name'].data)\n    when TYPE_MODULE\n      obj = Mapping.class_from_name(node['name'].data)\n    when TYPE_SYMBOL\n      obj = node['id'].data.intern\n    when TYPE_STRUCT\n      typestr = Mapping.elename2name(node['type'].data)\n      klass = Mapping.class_from_name(typestr)\n      if klass.nil?\n        return false\n      end\n      unless klass <= ::Struct\n        return false\n      end\n      obj = Mapping.create_empty_object(klass)\n      mark_unmarshalled_obj(node, obj)\n      node['member'].each do |name, value|\n        obj[Mapping.elename2name(name)] = Mapping._soap2obj(value, map)\n      end\n    else\n      return unknowntype2obj(node, info, map)\n    end\n    return true, obj\n  end\n\n  def anytype2obj(node, info, map)\n    case node\n    when SOAPBasetype\n      return true, node.data\n    when SOAPStruct\n      klass = ::SOAP::Mapping::Object\n      obj = klass.new\n      mark_unmarshalled_obj(node, obj)\n      node.each do |name, value|\n        obj.__add_xmlele_value(XSD::QName.new(nil, name),\n          Mapping._soap2obj(value, map))\n      end\n      unless node.extraattr.empty?\n        obj.instance_variable_set('@__xmlattr', node.extraattr)\n      end\n      return true, obj\n    else\n      return false\n    end\n  end\n\n  def unknowntype2obj(node, info, map)\n    case node\n    when SOAPBasetype\n      return true, node.data\n    when SOAPArray\n      return @array_factory.soap2obj(Array, node, info, map)\n    when SOAPStruct\n      obj = unknownstruct2obj(node, info, map)\n      return true, obj if obj\n      if !@allow_untyped_struct\n        return false\n      end\n      return anytype2obj(node, info, map)\n    else\n      # Basetype which is not defined...\n      return false\n    end\n  end\n\n  def unknownstruct2obj(node, info, map)\n    unless node.type.name\n      return nil\n    end\n    typestr = Mapping.elename2name(node.type.name)\n    klass = Mapping.class_from_name(typestr)\n    if klass.nil? and @allow_untyped_struct\n      klass = Mapping.class_from_name(typestr, true)    # lenient\n    end\n    if klass.nil?\n      return nil\n    end\n    if klass <= ::Exception\n      return exception2obj(klass, node, map)\n    end\n    klass_type = Mapping.class2qname(klass)\n    return nil unless node.type.match(klass_type)\n    obj = nil\n    begin\n      obj = Mapping.create_empty_object(klass)\n    rescue\n      # type name \"data\" tries Data.new which raises TypeError\n      nil\n    end\n    mark_unmarshalled_obj(node, obj)\n    setiv2obj(obj, node, map)\n    obj\n  end\n\n  def exception2obj(klass, node, map)\n    message = Mapping._soap2obj(node['message'], map)\n    backtrace = Mapping._soap2obj(node['backtrace'], map)\n    obj = Mapping.create_empty_object(klass)\n    obj = obj.exception(message)\n    mark_unmarshalled_obj(node, obj)\n    obj.set_backtrace(backtrace)\n    obj\n  end\n\n  # Only creates empty array.  Do String#replace it with real string.\n  def array2obj(node, map, rubytype)\n    klass = rubytype ? Mapping.class_from_name(rubytype) : Array\n    obj = Mapping.create_empty_object(klass)\n    mark_unmarshalled_obj(node, obj)\n    obj\n  end\n\n  # Only creates empty string.  Do String#replace it with real string.\n  def string2obj(node, map, rubytype)\n    klass = rubytype ? Mapping.class_from_name(rubytype) : String\n    obj = Mapping.create_empty_object(klass)\n    mark_unmarshalled_obj(node, obj)\n    obj\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/mapping/typeMap.rb",
    "content": "# SOAP4R - Base type mapping definition\n# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule SOAP\n\n\nTypeMap = {\n  XSD::XSDAnySimpleType::Type => SOAPAnySimpleType,\n  XSD::XSDString::Type => SOAPString,\n  XSD::XSDBoolean::Type => SOAPBoolean,\n  XSD::XSDDecimal::Type => SOAPDecimal,\n  XSD::XSDFloat::Type => SOAPFloat,\n  XSD::XSDDouble::Type => SOAPDouble,\n  XSD::XSDDuration::Type => SOAPDuration,\n  XSD::XSDDateTime::Type => SOAPDateTime,\n  XSD::XSDTime::Type => SOAPTime,\n  XSD::XSDDate::Type => SOAPDate,\n  XSD::XSDGYearMonth::Type => SOAPGYearMonth,\n  XSD::XSDGYear::Type => SOAPGYear,\n  XSD::XSDGMonthDay::Type => SOAPGMonthDay,\n  XSD::XSDGDay::Type => SOAPGDay,\n  XSD::XSDGMonth::Type => SOAPGMonth,\n  XSD::XSDHexBinary::Type => SOAPHexBinary,\n  XSD::XSDBase64Binary::Type => SOAPBase64,\n  XSD::XSDAnyURI::Type => SOAPAnyURI,\n  XSD::XSDQName::Type => SOAPQName,\n  XSD::XSDInteger::Type => SOAPInteger,\n  XSD::XSDNonPositiveInteger::Type => SOAPNonPositiveInteger,\n  XSD::XSDNegativeInteger::Type => SOAPNegativeInteger,\n  XSD::XSDLong::Type => SOAPLong,\n  XSD::XSDInt::Type => SOAPInt,\n  XSD::XSDShort::Type => SOAPShort,\n  XSD::XSDByte::Type => SOAPByte,\n  XSD::XSDNonNegativeInteger::Type => SOAPNonNegativeInteger,\n  XSD::XSDUnsignedLong::Type => SOAPUnsignedLong,\n  XSD::XSDUnsignedInt::Type => SOAPUnsignedInt,\n  XSD::XSDUnsignedShort::Type => SOAPUnsignedShort,\n  XSD::XSDUnsignedByte::Type => SOAPUnsignedByte,\n  XSD::XSDPositiveInteger::Type => SOAPPositiveInteger,\n\n  SOAP::SOAPBase64::Type => SOAPBase64,\n}\n\n\nend\n"
  },
  {
    "path": "lib/soap/mapping/wsdlencodedregistry.rb",
    "content": "# SOAP4R - WSDL encoded mapping registry.\n# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'xsd/namedelements'\nrequire 'soap/baseData'\nrequire 'soap/mapping/mapping'\nrequire 'soap/mapping/typeMap'\n\n\nmodule SOAP\nmodule Mapping\n\n\nclass WSDLEncodedRegistry < Registry\n  include TraverseSupport\n\n  attr_reader :definedelements\n  attr_reader :definedtypes\n  attr_accessor :excn_handler_obj2soap\n  attr_accessor :excn_handler_soap2obj\n\n  def initialize(definedtypes = XSD::NamedElements::Empty)\n    @definedtypes = definedtypes\n    # @definedelements = definedelements  needed?\n    @excn_handler_obj2soap = nil\n    @excn_handler_soap2obj = nil\n    # For mapping AnyType element.\n    @rubytype_factory = RubytypeFactory.new(\n      :allow_untyped_struct => true,\n      :allow_original_mapping => true\n    )\n    @schema_element_cache = {}\n  end\n\n  def obj2soap(obj, qname = nil)\n    soap_obj = nil\n    if type = @definedtypes[qname]\n      soap_obj = obj2typesoap(obj, type)\n    else\n      soap_obj = any2soap(obj, qname)\n    end\n    return soap_obj if soap_obj\n    if @excn_handler_obj2soap\n      soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|\n        Mapping._obj2soap(yield_obj, self)\n      }\n      return soap_obj if soap_obj\n    end\n    if qname\n      raise MappingError.new(\"cannot map #{obj.class.name} as #{qname}\")\n    else\n      raise MappingError.new(\"cannot map #{obj.class.name} to SOAP/OM\")\n    end\n  end\n\n  # map anything for now: must refer WSDL while mapping.  [ToDo]\n  def soap2obj(node, obj_class = nil)\n    begin\n      return any2obj(node, obj_class)\n    rescue MappingError\n    end\n    if @excn_handler_soap2obj\n      begin\n        return @excn_handler_soap2obj.call(node) { |yield_node|\n\t    Mapping._soap2obj(yield_node, self)\n\t  }\n      rescue Exception\n      end\n    end\n    raise MappingError.new(\"cannot map #{node.type.name} to Ruby object\")\n  end\n\nprivate\n\n  def any2soap(obj, qname)\n    if obj.nil?\n      SOAPNil.new\n    elsif qname.nil? or qname == XSD::AnyTypeName\n      @rubytype_factory.obj2soap(nil, obj, nil, self)\n    elsif obj.is_a?(XSD::NSDBase)\n      soap2soap(obj, qname)\n    elsif (type = TypeMap[qname])\n      base2soap(obj, type)\n    else\n      nil\n    end\n  end\n\n  def soap2soap(obj, type_qname)\n    if obj.is_a?(SOAPBasetype)\n      obj\n    elsif obj.is_a?(SOAPStruct) && (type = @definedtypes[type_qname])\n      soap_obj = obj\n      mark_marshalled_obj(obj, soap_obj)\n      elements2soap(obj, soap_obj, type.content.elements)\n      soap_obj\n    elsif obj.is_a?(SOAPArray) && (type = @definedtypes[type_qname])\n      soap_obj = obj\n      contenttype = type.child_type\n      mark_marshalled_obj(obj, soap_obj)\n      obj.replace do |ele|\n\tMapping._obj2soap(ele, self, contenttype)\n      end\n      soap_obj\n    else\n      nil\n    end\n  end\n\n  def obj2typesoap(obj, type)\n    if type.is_a?(::WSDL::XMLSchema::SimpleType)\n      simpleobj2soap(obj, type)\n    else\n      complexobj2soap(obj, type)\n    end\n  end\n\n  def simpleobj2soap(obj, type)\n    type.check_lexical_format(obj)\n    return SOAPNil.new if obj.nil?      # ToDo: check nillable.\n    o = base2soap(obj, TypeMap[type.base])\n    o\n  end\n\n  def complexobj2soap(obj, type)\n    case type.compoundtype\n    when :TYPE_STRUCT\n      struct2soap(obj, type.name, type)\n    when :TYPE_ARRAY\n      array2soap(obj, type.name, type)\n    when :TYPE_MAP\n      map2soap(obj, type.name, type)\n    when :TYPE_SIMPLE\n      simpleobj2soap(obj, type.simplecontent)\n    when :TYPE_EMPTY\n      raise MappingError.new(\"should be empty\") unless obj.nil?\n      SOAPNil.new\n    else\n      raise MappingError.new(\"unknown compound type: #{type.compoundtype}\")\n    end\n  end\n\n  def base2soap(obj, type)\n    soap_obj = nil\n    if type <= XSD::XSDString\n      str = XSD::Charset.encoding_conv(obj.to_s,\n        Thread.current[:SOAPExternalCES], XSD::Charset.encoding)\n      soap_obj = type.new(str)\n      mark_marshalled_obj(obj, soap_obj)\n    else\n      soap_obj = type.new(obj)\n    end\n    soap_obj\n  end\n\n  def struct2soap(obj, type_qname, type)\n    return SOAPNil.new if obj.nil?      # ToDo: check nillable.\n    soap_obj = SOAPStruct.new(type_qname)\n    unless obj.nil?\n      mark_marshalled_obj(obj, soap_obj)\n      elements2soap(obj, soap_obj, type.content.elements)\n    end\n    soap_obj\n  end\n\n  def array2soap(obj, type_qname, type)\n    return SOAPNil.new if obj.nil?      # ToDo: check nillable.\n    arytype = type.child_type\n    soap_obj = SOAPArray.new(ValueArrayName, 1, arytype)\n    unless obj.nil?\n      mark_marshalled_obj(obj, soap_obj)\n      obj.each do |item|\n        soap_obj.add(Mapping._obj2soap(item, self, arytype))\n      end\n    end\n    soap_obj\n  end\n\n  MapKeyName = XSD::QName.new(nil, \"key\")\n  MapValueName = XSD::QName.new(nil, \"value\")\n  def map2soap(obj, type_qname, type)\n    return SOAPNil.new if obj.nil?      # ToDo: check nillable.\n    keytype = type.child_type(MapKeyName) || XSD::AnyTypeName\n    valuetype = type.child_type(MapValueName) || XSD::AnyTypeName\n    soap_obj = SOAPStruct.new(MapQName)\n    unless obj.nil?\n      mark_marshalled_obj(obj, soap_obj)\n      obj.each do |key, value|\n        elem = SOAPStruct.new\n        elem.add(\"key\", Mapping._obj2soap(key, self, keytype))\n        elem.add(\"value\", Mapping._obj2soap(value, self, valuetype))\n        # ApacheAxis allows only 'item' here.\n        soap_obj.add(\"item\", elem)\n      end\n    end\n    soap_obj\n  end\n\n  def elements2soap(obj, soap_obj, elements)\n    elements.each do |element|\n      name = element.name.name\n      child_obj = Mapping.get_attribute(obj, name)\n      soap_obj.add(name,\n        Mapping._obj2soap(child_obj, self, element.type || element.name))\n    end\n  end\n\n  def any2obj(node, obj_class)\n    unless obj_class\n      typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name)\n      obj_class = Mapping.class_from_name(typestr)\n    end\n    if obj_class and obj_class.class_variables.include?('@@schema_element')\n      soap2stubobj(node, obj_class)\n    else\n      Mapping._soap2obj(node, Mapping::DefaultRegistry, obj_class)\n    end\n  end\n\n  def soap2stubobj(node, obj_class)\n    obj = Mapping.create_empty_object(obj_class)\n    unless node.is_a?(SOAPNil)\n      add_elements2stubobj(node, obj)\n    end\n    obj\n  end\n\n  def add_elements2stubobj(node, obj)\n    elements, as_array = schema_element_definition(obj.class)\n    vars = {}\n    node.each do |name, value|\n      item = elements.find { |k, v| k.name == name }\n      if item\n        elename, class_name = item\n        if klass = Mapping.class_from_name(class_name)\n          # klass must be a SOAPBasetype or a class\n          if klass.ancestors.include?(::SOAP::SOAPBasetype)\n            if value.respond_to?(:data)\n              child = klass.new(value.data).data\n            else\n              child = klass.new(nil).data\n            end\n          else\n            child = Mapping._soap2obj(value, self, klass)\n          end\n        elsif klass = Mapping.module_from_name(class_name)\n          # simpletype\n          if value.respond_to?(:data)\n            child = value.data\n          else\n            raise MappingError.new(\n              \"cannot map to a module value: #{class_name}\")\n          end\n        else\n          raise MappingError.new(\"unknown class: #{class_name}\")\n        end\n      else      # untyped element is treated as anyType.\n        child = Mapping._soap2obj(value, self)\n      end\n      vars[name] = child\n    end\n    Mapping.set_attributes(obj, vars)\n  end\n\n  # it caches @@schema_element.  this means that @@schema_element must not be\n  # changed while a lifetime of a WSDLLiteralRegistry.\n  def schema_element_definition(klass)\n    @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/mapping/wsdlliteralregistry.rb",
    "content": "# SOAP4R - WSDL literal mapping registry.\n# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/baseData'\nrequire 'soap/mapping/mapping'\nrequire 'soap/mapping/typeMap'\nrequire 'xsd/codegen/gensupport'\nrequire 'xsd/namedelements'\n\n\nmodule SOAP\nmodule Mapping\n\n\nclass WSDLLiteralRegistry < Registry\n  attr_reader :definedelements\n  attr_reader :definedtypes\n  attr_accessor :excn_handler_obj2soap\n  attr_accessor :excn_handler_soap2obj\n\n  def initialize(definedtypes = XSD::NamedElements::Empty,\n      definedelements = XSD::NamedElements::Empty)\n    @definedtypes = definedtypes\n    @definedelements = definedelements\n    @excn_handler_obj2soap = nil\n    @excn_handler_soap2obj = nil\n    @schema_element_cache = {}\n    @schema_attribute_cache = {}\n  end\n\n  def obj2soap(obj, qname)\n    soap_obj = nil\n    if ele = @definedelements[qname]\n      soap_obj = obj2elesoap(obj, ele)\n    elsif type = @definedtypes[qname]\n      soap_obj = obj2typesoap(obj, type, true)\n    else\n      soap_obj = any2soap(obj, qname)\n    end\n    return soap_obj if soap_obj\n    if @excn_handler_obj2soap\n      soap_obj = @excn_handler_obj2soap.call(obj) { |yield_obj|\n        Mapping.obj2soap(yield_obj, nil, nil, MAPPING_OPT)\n      }\n      return soap_obj if soap_obj\n    end\n    raise MappingError.new(\"cannot map #{obj.class.name} as #{qname}\")\n  end\n\n  # node should be a SOAPElement\n  def soap2obj(node, obj_class = nil)\n    # obj_class is given when rpc/literal service.  but ignored for now.\n    begin\n      return any2obj(node)\n    rescue MappingError\n    end\n    if @excn_handler_soap2obj\n      begin\n        return @excn_handler_soap2obj.call(node) { |yield_node|\n\t    Mapping.soap2obj(yield_node, nil, nil, MAPPING_OPT)\n\t  }\n      rescue Exception\n      end\n    end\n    if node.respond_to?(:type)\n      raise MappingError.new(\"cannot map #{node.type.name} to Ruby object\")\n    else\n      raise MappingError.new(\"cannot map #{node.elename.name} to Ruby object\")\n    end\n  end\n\nprivate\n\n  MAPPING_OPT = { :no_reference => true }\n\n  def obj2elesoap(obj, ele)\n    o = nil\n    qualified = (ele.elementform == 'qualified')\n    if ele.type\n      if type = @definedtypes[ele.type]\n        o = obj2typesoap(obj, type, qualified)\n      elsif type = TypeMap[ele.type]\n        o = base2soap(obj, type)\n      else\n        raise MappingError.new(\"cannot find type #{ele.type}\")\n      end\n    elsif ele.local_complextype\n      o = obj2typesoap(obj, ele.local_complextype, qualified)\n      add_attributes2soap(obj, o)\n    elsif ele.local_simpletype\n      o = obj2typesoap(obj, ele.local_simpletype, qualified)\n    else\n      raise MappingError.new('illegal schema?')\n    end\n    o.elename = ele.name\n    o\n  end\n\n  def obj2typesoap(obj, type, qualified)\n    if type.is_a?(::WSDL::XMLSchema::SimpleType)\n      simpleobj2soap(obj, type)\n    else\n      complexobj2soap(obj, type, qualified)\n    end\n  end\n\n  def simpleobj2soap(obj, type)\n    type.check_lexical_format(obj)\n    return SOAPNil.new if obj.nil?      # ToDo: check nillable.\n    o = base2soap(obj, TypeMap[type.base])\n    o\n  end\n\n  def complexobj2soap(obj, type, qualified)\n    o = SOAPElement.new(type.name)\n    o.qualified = qualified\n    type.each_element do |child_ele|\n      child = Mapping.get_attribute(obj, child_ele.name.name)\n      if child.nil?\n        if child_ele.nillable\n          # ToDo: test\n          # add empty element\n          child_soap = obj2elesoap(nil, child_ele)\n          o.add(child_soap)\n        elsif Integer(child_ele.minoccurs) == 0\n          # nothing to do\n        else\n          raise MappingError.new(\"nil not allowed: #{child_ele.name.name}\")\n        end\n      elsif child_ele.map_as_array?\n        child.each do |item|\n          child_soap = obj2elesoap(item, child_ele)\n          o.add(child_soap)\n        end\n      else\n        child_soap = obj2elesoap(child, child_ele)\n        o.add(child_soap)\n      end\n    end\n    o\n  end\n\n  def any2soap(obj, qname)\n    if obj.is_a?(SOAPElement)\n      obj\n    elsif obj.class.class_variables.include?('@@schema_element')\n      stubobj2soap(obj, qname)\n    elsif obj.is_a?(SOAP::Mapping::Object)\n      mappingobj2soap(obj, qname)\n    elsif obj.is_a?(Hash)\n      ele = SOAPElement.from_obj(obj)\n      ele.elename = qname\n      ele\n    else\n      # expected to be a basetype or an anyType.\n      # SOAPStruct, etc. is used instead of SOAPElement.\n      begin\n        ele = Mapping.obj2soap(obj, nil, nil, MAPPING_OPT)\n        ele.elename = qname\n        ele\n      rescue MappingError\n        ele = SOAPElement.new(qname, obj.to_s)\n      end\n      if obj.respond_to?(:__xmlattr)\n        obj.__xmlattr.each do |key, value|\n          ele.extraattr[key] = value\n        end\n      end\n      ele\n    end\n  end\n\n  def stubobj2soap(obj, qname)\n    ele = SOAPElement.new(qname)\n    ele.qualified =\n      (obj.class.class_variables.include?('@@schema_qualified') and\n      obj.class.class_eval('@@schema_qualified'))\n    add_elements2soap(obj, ele)\n    add_attributes2soap(obj, ele)\n    ele\n  end\n\n  def mappingobj2soap(obj, qname)\n    ele = SOAPElement.new(qname)\n    obj.__xmlele.each do |key, value|\n      if value.is_a?(::Array)\n        value.each do |item|\n          ele.add(obj2soap(item, key))\n        end\n      else\n        ele.add(obj2soap(value, key))\n      end\n    end\n    obj.__xmlattr.each do |key, value|\n      ele.extraattr[key] = value\n    end\n    ele\n  end\n\n  def add_elements2soap(obj, ele)\n    elements, as_array = schema_element_definition(obj.class)\n    if elements\n      elements.each do |elename, type|\n        if child = Mapping.get_attribute(obj, elename.name)\n          if as_array.include?(elename.name)\n            child.each do |item|\n              ele.add(obj2soap(item, elename))\n            end\n          else\n            ele.add(obj2soap(child, elename))\n          end\n        elsif obj.is_a?(::Array) and as_array.include?(elename.name)\n          obj.each do |item|\n            ele.add(obj2soap(item, elename))\n          end\n        end\n      end\n    end\n  end\n  \n  def add_attributes2soap(obj, ele)\n    attributes = schema_attribute_definition(obj.class)\n    if attributes\n      attributes.each do |qname, param|\n        attr = obj.__send__('xmlattr_' +\n          XSD::CodeGen::GenSupport.safevarname(qname.name))\n        ele.extraattr[qname] = attr\n      end\n    end\n  end\n\n  def base2soap(obj, type)\n    soap_obj = nil\n    if type <= XSD::XSDString\n      str = XSD::Charset.encoding_conv(obj.to_s,\n        Thread.current[:SOAPExternalCES], XSD::Charset.encoding)\n      soap_obj = type.new(str)\n    else\n      soap_obj = type.new(obj)\n    end\n    soap_obj\n  end\n\n  def anytype2obj(node)\n    if node.is_a?(::SOAP::SOAPBasetype)\n      return node.data\n    end\n    klass = ::SOAP::Mapping::Object\n    obj = klass.new\n    obj\n  end\n\n  def any2obj(node, obj_class = nil)\n    unless obj_class\n      typestr = XSD::CodeGen::GenSupport.safeconstname(node.elename.name)\n      obj_class = Mapping.class_from_name(typestr)\n    end\n    if obj_class and obj_class.class_variables.include?('@@schema_element')\n      soapele2stubobj(node, obj_class)\n    elsif node.is_a?(SOAPElement) or node.is_a?(SOAPStruct)\n        # SOAPArray for literal?\n      soapele2plainobj(node)\n    else\n      obj = Mapping.soap2obj(node, nil, obj_class, MAPPING_OPT)\n      add_attributes2plainobj(node, obj)\n      obj\n    end\n  end\n\n  def soapele2stubobj(node, obj_class)\n    obj = Mapping.create_empty_object(obj_class)\n    add_elements2stubobj(node, obj)\n    add_attributes2stubobj(node, obj)\n    obj\n  end\n\n  def soapele2plainobj(node)\n    obj = anytype2obj(node)\n    add_elements2plainobj(node, obj)\n    add_attributes2plainobj(node, obj)\n    obj\n  end\n\n  def add_elements2stubobj(node, obj)\n    elements, as_array = schema_element_definition(obj.class)\n    vars = {}\n    node.each do |name, value|\n      item = elements.find { |k, v| k.name == name }\n      if item\n        elename, class_name = item\n        if klass = Mapping.class_from_name(class_name)\n          # klass must be a SOAPBasetype or a class\n          if klass.ancestors.include?(::SOAP::SOAPBasetype)\n            if value.respond_to?(:data)\n              child = klass.new(value.data).data\n            else\n              child = klass.new(nil).data\n            end\n          else\n            child = any2obj(value, klass)\n          end\n        elsif klass = Mapping.module_from_name(class_name)\n          # simpletype\n          if value.respond_to?(:data)\n            child = value.data\n          else\n            raise MappingError.new(\n              \"cannot map to a module value: #{class_name}\")\n          end\n        else\n          raise MappingError.new(\"unknown class/module: #{class_name}\")\n        end\n      else      # untyped element is treated as anyType.\n        child = any2obj(value)\n      end\n      if as_array.include?(elename.name)\n        (vars[name] ||= []) << child\n      else\n        vars[name] = child\n      end\n    end\n    Mapping.set_attributes(obj, vars)\n  end\n\n  def add_attributes2stubobj(node, obj)\n    if attributes = schema_attribute_definition(obj.class)\n      define_xmlattr(obj)\n      attributes.each do |qname, class_name|\n        attr = node.extraattr[qname]\n        next if attr.nil? or attr.empty?\n        klass = Mapping.class_from_name(class_name)\n        if klass.ancestors.include?(::SOAP::SOAPBasetype)\n          child = klass.new(attr).data\n        else\n          child = attr\n        end\n        obj.__xmlattr[qname] = child\n        define_xmlattr_accessor(obj, qname)\n      end\n    end\n  end\n\n  def add_elements2plainobj(node, obj)\n    node.each do |name, value|\n      obj.__add_xmlele_value(value.elename, any2obj(value))\n    end\n  end\n\n  def add_attributes2plainobj(node, obj)\n    return if node.extraattr.empty?\n    define_xmlattr(obj)\n    node.extraattr.each do |qname, value|\n      obj.__xmlattr[qname] = value\n      define_xmlattr_accessor(obj, qname)\n    end\n  end\n\n  if RUBY_VERSION > \"1.7.0\"\n    def define_xmlattr_accessor(obj, qname)\n      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)\n      Mapping.define_attr_accessor(obj, 'xmlattr_' + name,\n        proc { @__xmlattr[qname] },\n        proc { |value| @__xmlattr[qname] = value })\n    end\n  else\n    def define_xmlattr_accessor(obj, qname)\n      name = XSD::CodeGen::GenSupport.safemethodname(qname.name)\n      obj.instance_eval <<-EOS\n        def #{name}\n          @__xmlattr[#{qname.dump}]\n        end\n\n        def #{name}=(value)\n          @__xmlattr[#{qname.dump}] = value\n        end\n      EOS\n    end\n  end\n\n  if RUBY_VERSION > \"1.7.0\"\n    def define_xmlattr(obj)\n      obj.instance_variable_set('@__xmlattr', {})\n      unless obj.respond_to?(:__xmlattr)\n        Mapping.define_attr_accessor(obj, :__xmlattr, proc { @__xmlattr })\n      end\n    end\n  else\n    def define_xmlattr(obj)\n      obj.instance_variable_set('@__xmlattr', {})\n      unless obj.respond_to?(:__xmlattr)\n        obj.instance_eval <<-EOS\n          def __xmlattr\n            @__xmlattr\n          end\n        EOS\n      end\n    end\n  end\n\n  # it caches @@schema_element.  this means that @@schema_element must not be\n  # changed while a lifetime of a WSDLLiteralRegistry.\n  def schema_element_definition(klass)\n    @schema_element_cache[klass] ||= Mapping.schema_element_definition(klass)\n  end\n\n  def schema_attribute_definition(klass)\n    @schema_attribute_cache[klass] ||= Mapping.schema_attribute_definition(klass)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/mapping.rb",
    "content": "# SOAP4R - Ruby type mapping utility.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/mapping/mapping'\nrequire 'soap/mapping/registry'\n"
  },
  {
    "path": "lib/soap/marshal.rb",
    "content": "# SOAP4R - Marshalling/Unmarshalling Ruby's object using SOAP Encoding.\n# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire \"soap/mapping\"\nrequire \"soap/processor\"\n\n\nmodule SOAP\n\n\nmodule Marshal\n  # Trying xsd:dateTime data to be recovered as aTime.\n  MarshalMappingRegistry = Mapping::Registry.new(\n    :allow_original_mapping => true)\n  MarshalMappingRegistry.add(\n    Time,\n    ::SOAP::SOAPDateTime,\n    ::SOAP::Mapping::Registry::DateTimeFactory\n  )\n\n  class << self\n  public\n    def dump(obj, io = nil)\n      marshal(obj, MarshalMappingRegistry, io)\n    end\n\n    def load(stream)\n      unmarshal(stream, MarshalMappingRegistry)\n    end\n\n    def marshal(obj, mapping_registry = MarshalMappingRegistry, io = nil)\n      elename = Mapping.name2elename(obj.class.to_s)\n      soap_obj = Mapping.obj2soap(obj, mapping_registry)\n      body = SOAPBody.new\n      body.add(elename, soap_obj)\n      env = SOAPEnvelope.new(nil, body)\n      SOAP::Processor.marshal(env, {}, io)\n    end\n\n    def unmarshal(stream, mapping_registry = MarshalMappingRegistry)\n      env = SOAP::Processor.unmarshal(stream)\n      if env.nil?\n\traise ArgumentError.new(\"Illegal SOAP marshal format.\")\n      end\n      Mapping.soap2obj(env.body.root_node, mapping_registry)\n    end\n  end\nend\n\n\nend\n\n\nSOAPMarshal = SOAP::Marshal\n"
  },
  {
    "path": "lib/soap/mimemessage.rb",
    "content": "# SOAP4R - MIME Message implementation.\n# Copyright (C) 2002  Jamie Herre.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/attachment'\n\n\nmodule SOAP\n\n\n# Classes for MIME message handling.  Should be put somewhere else!\n# Tried using the 'tmail' module but found that I needed something\n# lighter in weight.\n\n\nclass MIMEMessage\n  class MIMEMessageError < StandardError; end\n\n  MultipartContentType = 'multipart/\\w+'\n\n  class Header\n    attr_accessor :str, :key, :root\n\n    def initialize\n      @attrs = {}\n    end\n\n    def [](key)\n      @attrs[key]\n    end\n\n    def []=(key, value)\n      @attrs[key] = value\n    end\n\n    def to_s\n      @key + \": \" + @str\n    end\n  end\n\n  class Headers < Hash\n    def self.parse(str)\n      new.parse(str)\n    end\n\n    def parse(str)\n      header_cache = nil\n      str.each do |line|\n\tcase line\n\twhen /^\\A[^\\: \\t]+:\\s*.+$/\n\t  parse_line(header_cache) if header_cache\n\t  header_cache = line.sub(/\\r?\\n\\z/, '')\n\twhen /^\\A\\s+(.*)$/\n\t  # a continuous line at the beginning line crashes here.\n\t  header_cache << line\n\telse\n\t  raise RuntimeError.new(\"unexpected header: #{line.inspect}\")\n\tend\n      end\n      parse_line(header_cache) if header_cache\n      self\n    end\n\n    def parse_line(line)\n      if /^\\A([^\\: \\t]+):\\s*(.+)\\z/ =~ line\n    \theader = parse_rhs($2.strip)\n\theader.key = $1.strip\n\tself[header.key.downcase] = header\n      else\n\traise RuntimeError.new(\"unexpected header line: #{line.inspect}\")\n      end\n    end\n\n    def parse_rhs(str)\n      a = str.split(/;+\\s+/)\n      header = Header.new\n      header.str = str\n      header.root = a.shift\n      a.each do |pair|\n\tif pair =~ /(\\w+)\\s*=\\s*\"?([^\"]+)\"?/\n\t  header[$1.downcase] = $2\n\telse\n\t  raise RuntimeError.new(\"unexpected header component: #{pair.inspect}\")\n\tend\n      end\n      header\n    end\n\n    def add(key, value)\n      if key != nil and value != nil\n\theader = parse_rhs(value)\n\theader.key = key\n\tself[key.downcase] = header\n      end\n    end\n\n    def to_s\n      self.values.collect { |hdr|\n\thdr.to_s\n      }.join(\"\\r\\n\")\n    end\n  end\n\n  class Part\n    attr_accessor :headers, :body\n\n    def initialize\n      @headers = Headers.new\n      @headers.add(\"Content-Transfer-Encoding\", \"8bit\")\n      @body = nil\n      @contentid = nil\n    end\n\n    def self.parse(str)\n      new.parse(str)\n    end\n\n    def parse(str)\n      headers, body = str.split(/\\r\\n\\r\\n/s)\n      if headers != nil and body != nil\n\t@headers = Headers.parse(headers)\n\t@body = body.sub(/\\r\\n\\z/, '')\n      else\n\traise RuntimeError.new(\"unexpected part: #{str.inspect}\")\n      end\n      self\n    end\n\n    def contentid\n      if @contentid == nil and @headers.key?('content-id')\n\t@contentid = @headers['content-id'].str\n\t@contentid = $1 if @contentid =~ /^<(.+)>$/\n      end\n      @contentid\n    end\n\n    alias content body\n\n    def to_s\n      @headers.to_s + \"\\r\\n\\r\\n\" + @body\n    end\n  end\n\n  def initialize\n    @parts = []\n    @headers = Headers.new\n    @root = nil\n  end\n\n  def self.parse(head, str)\n    new.parse(head, str)\n  end\n\n  attr_reader :parts, :headers\n\n  def close\n    @headers.add(\n      \"Content-Type\",\n      \"multipart/related; type=\\\"text/xml\\\"; boundary=\\\"#{boundary}\\\"; start=\\\"#{@parts[0].contentid}\\\"\"\n    )\n  end\n\n  def parse(head, str)\n    @headers = Headers.parse(head + \"\\r\\n\" + \"From: jfh\\r\\n\")\n    boundary = @headers['content-type']['boundary']\n    if boundary != nil\n      parts = str.split(/--#{Regexp.quote(boundary)}\\s*(?:\\r\\n|--\\r\\n)/)\n      part = parts.shift\t# preamble must be ignored.\n      @parts = parts.collect { |part| Part.parse(part) }\n    else\n      @parts = [Part.parse(str)]\n    end\n    if @parts.length < 1\n      raise MIMEMessageError.new(\"This message contains no valid parts!\")\n    end\n    self\n  end\n\n  def root\n    if @root == nil\n      start = @headers['content-type']['start']\n      @root = (start && @parts.find { |prt| prt.contentid == start }) ||\n\t@parts[0]\n    end\n    @root\n  end\n\n  def boundary\n    if @boundary == nil\n      @boundary = \"----=Part_\" + __id__.to_s + rand.to_s\n    end\n    @boundary\n  end\n\n  def add_part(content)\n    part = Part.new\n    part.headers.add(\"Content-Type\",\n      \"text/xml; charset=\" + XSD::Charset.xml_encoding_label)\n    part.headers.add(\"Content-ID\", Attachment.contentid(part))\n    part.body = content\n    @parts.unshift(part)\n  end\n\n  def add_attachment(attach)\n    part = Part.new\n    part.headers.add(\"Content-Type\", attach.contenttype)\n    part.headers.add(\"Content-ID\", attach.mime_contentid)\n    part.body = attach.content\n    @parts.unshift(part)\n  end\n\n  def has_parts?\n    (@parts.length > 0)\n  end\n\n  def headers_str\n    @headers.to_s\n  end\n\n  def content_str\n    str = ''\n    @parts.each do |prt|\n      str << \"--\" + boundary + \"\\r\\n\"\n      str << prt.to_s + \"\\r\\n\"\n    end\n    str << '--' + boundary + \"--\\r\\n\"\n    str\n  end\n\n  def to_s\n    str = headers_str + \"\\r\\n\\r\\n\" + content_str\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/netHttpClient.rb",
    "content": "# SOAP4R - net/http wrapper\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'net/http'\n\n\nmodule SOAP\n\n\nclass NetHttpClient\n\n  SSLEnabled = begin\n      require 'net/https'\n      true\n    rescue LoadError\n      false\n    end\n\n  attr_reader :proxy\n  attr_accessor :no_proxy\n  attr_accessor :debug_dev\n  attr_accessor :ssl_config\t\t# ignored for now.\n  attr_accessor :protocol_version\t# ignored for now.\n  attr_accessor :connect_timeout\n  attr_accessor :send_timeout           # ignored for now.\n  attr_accessor :receive_timeout\n\n  def initialize(proxy = nil, agent = nil)\n    @proxy = proxy ? URI.parse(proxy) : nil\n    @agent = agent\n    @debug_dev = nil\n    @session_manager = SessionManager.new\n    @no_proxy = @ssl_config = @protocol_version = nil\n    @connect_timeout = @send_timeout = @receive_timeout = nil\n  end\n\n  def test_loopback_response\n    raise NotImplementedError.new(\"not supported for now\")\n  end\n  \n  def proxy=(proxy)\n    if proxy.nil?\n      @proxy = nil\n    else\n      if proxy.is_a?(URI)\n        @proxy = proxy\n      else\n        @proxy = URI.parse(proxy)\n      end\n      if @proxy.scheme == nil or @proxy.scheme.downcase != 'http' or\n\t  @proxy.host == nil or @proxy.port == nil\n\traise ArgumentError.new(\"unsupported proxy `#{proxy}'\")\n      end\n    end\n    reset_all\n    @proxy\n  end\n\n  def set_basic_auth(uri, user_id, passwd)\n    # net/http does not handle url.\n    @basic_auth = [user_id, passwd]\n    raise NotImplementedError.new(\"basic_auth is not supported under soap4r + net/http.\")\n  end\n\n  def set_cookie_store(filename)\n    raise NotImplementedError.new\n  end\n\n  def save_cookie_store(filename)\n    raise NotImplementedError.new\n  end\n\n  def reset(url)\n    # no persistent connection.  ignored.\n  end\n\n  def reset_all\n    # no persistent connection.  ignored.\n  end\n\n  def post(url, req_body, header = {})\n    unless url.is_a?(URI)\n      url = URI.parse(url)\n    end\n    extra = header.dup\n    extra['User-Agent'] = @agent if @agent\n    res = start(url) { |http|\n      http.post(url.request_uri, req_body, extra)\n    }\n    Response.new(res)\n  end\n\n  def get_content(url, header = {})\n    unless url.is_a?(URI)\n      url = URI.parse(url)\n    end\n    extra = header.dup\n    extra['User-Agent'] = @agent if @agent\n    res = start(url) { |http|\n\thttp.get(url.request_uri, extra)\n      }\n    res.body\n  end\n\nprivate\n\n  def start(url)\n    http = create_connection(url)\n    response = nil\n    http.start { |worker|\n      response = yield(worker)\n      worker.finish\n    }\n    @debug_dev << response.body if @debug_dev\n    response\n  end\n\n  def create_connection(url)\n    proxy_host = proxy_port = nil\n    unless no_proxy?(url)\n      proxy_host = @proxy.host\n      proxy_port = @proxy.port\n    end\n    http = Net::HTTP::Proxy(proxy_host, proxy_port).new(url.host, url.port)\n    if http.respond_to?(:set_debug_output)\n      http.set_debug_output(@debug_dev)\n    end\n    http.open_timeout = @connect_timeout if @connect_timeout\n    http.read_timeout = @receive_timeout if @receive_timeout\n    case url\n    when URI::HTTPS\n      if SSLEnabled\n\thttp.use_ssl = true\n      else\n\traise RuntimeError.new(\"Cannot connect to #{url} (OpenSSL is not installed.)\")\n      end\n    when URI::HTTP\n      # OK\n    else\n      raise RuntimeError.new(\"Cannot connect to #{url} (Not HTTP.)\")\n    end\n    http\n  end\n\n  NO_PROXY_HOSTS = ['localhost']\n\n  def no_proxy?(uri)\n    if !@proxy or NO_PROXY_HOSTS.include?(uri.host)\n      return true\n    end\n    if @no_proxy\n      @no_proxy.scan(/([^:,]*)(?::(\\d+))?/) do |host, port|\n  \tif /(\\A|\\.)#{Regexp.quote(host)}\\z/i =~ uri.host &&\n\t    (!port || uri.port == port.to_i)\n\t  return true\n\tend\n      end\n    else\n      false\n    end\n  end\n\n  class SessionManager\n    attr_accessor :connect_timeout\n    attr_accessor :send_timeout\n    attr_accessor :receive_timeout\n  end\n\n  class Response\n    attr_reader :content\n    attr_reader :status\n    attr_reader :reason\n    attr_reader :contenttype\n\n    def initialize(res)\n      @status = res.code.to_i\n      @reason = res.message\n      @contenttype = res['content-type']\n      @content = res.body\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/parser.rb",
    "content": "# SOAP4R - SOAP XML Instance Parser library.\n# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/ns'\nrequire 'xsd/xmlparser'\nrequire 'soap/soap'\nrequire 'soap/baseData'\nrequire 'soap/encodingstyle/handler'\n\n\nmodule SOAP\n\n\nclass Parser\n  include SOAP\n\n  class ParseError < Error; end\n  class FormatDecodeError < ParseError; end\n  class UnexpectedElementError < ParseError; end\n\nprivate\n\n  class ParseFrame\n    attr_reader :node\n    attr_reader :name\n    attr_reader :ns, :encodingstyle\n\n    class NodeContainer\n      def initialize(node)\n\t@node = node\n      end\n\n      def node\n\t@node\n      end\n\n      def replace_node(node)\n\t@node = node\n      end\n    end\n\n  public\n\n    def initialize(ns, name, node, encodingstyle)\n      @ns = ns\n      @name = name\n      self.node = node\n      @encodingstyle = encodingstyle\n    end\n\n    def node=(node)\n      @node = NodeContainer.new(node)\n    end\n  end\n\npublic\n\n  attr_accessor :envelopenamespace\n  attr_accessor :default_encodingstyle\n  attr_accessor :decode_typemap\n  attr_accessor :allow_unqualified_element\n\n  def initialize(opt = {})\n    @opt = opt\n    @parser = XSD::XMLParser.create_parser(self, opt)\n    @parsestack = nil\n    @lastnode = nil\n    @handlers = {}\n    @envelopenamespace = opt[:envelopenamespace] || EnvelopeNamespace\n    @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace\n    @decode_typemap = opt[:decode_typemap] || nil\n    @allow_unqualified_element = opt[:allow_unqualified_element] || false\n  end\n\n  def charset\n    @parser.charset\n  end\n\n  def parse(string_or_readable)\n    @parsestack = []\n    @lastnode = nil\n\n    @handlers.each do |uri, handler|\n      handler.decode_prologue\n    end\n\n    @parser.do_parse(string_or_readable)\n\n    unless @parsestack.empty?\n      raise FormatDecodeError.new(\"Unbalanced tag in XML.\")\n    end\n\n    @handlers.each do |uri, handler|\n      handler.decode_epilogue\n    end\n\n    @lastnode\n  end\n\n  def start_element(name, attrs)\n    lastframe = @parsestack.last\n    ns = parent = parent_encodingstyle = nil\n    if lastframe\n      ns = lastframe.ns.clone_ns\n      parent = lastframe.node\n      parent_encodingstyle = lastframe.encodingstyle\n    else\n      ns = XSD::NS.new\n      parent = ParseFrame::NodeContainer.new(nil)\n      parent_encodingstyle = nil\n    end\n\n    attrs = XSD::XMLParser.filter_ns(ns, attrs)\n    encodingstyle = find_encodingstyle(ns, attrs)\n\n    # Children's encodingstyle is derived from its parent.\n    if encodingstyle.nil?\n      if parent.node.is_a?(SOAPHeader)\n        encodingstyle = LiteralNamespace\n      else\n        encodingstyle = parent_encodingstyle || @default_encodingstyle\n      end\n    end\n\n    node = decode_tag(ns, name, attrs, parent, encodingstyle)\n\n    @parsestack << ParseFrame.new(ns, name, node, encodingstyle)\n  end\n\n  def characters(text)\n    lastframe = @parsestack.last\n    if lastframe\n      # Need not to be cloned because character does not have attr.\n      decode_text(lastframe.ns, text, lastframe.encodingstyle)\n    else\n      # Ignore Text outside of SOAP Envelope.\n      p text if $DEBUG\n    end\n  end\n\n  def end_element(name)\n    lastframe = @parsestack.pop\n    unless name == lastframe.name\n      raise UnexpectedElementError.new(\"Closing element name '#{ name }' does not match with opening element '#{ lastframe.name }'.\")\n    end\n    decode_tag_end(lastframe.ns, lastframe.node, lastframe.encodingstyle)\n    @lastnode = lastframe.node.node\n  end\n\nprivate\n\n  def find_encodingstyle(ns, attrs)\n    attrs.each do |key, value|\n      if (ns.compare(@envelopenamespace, AttrEncodingStyle, key))\n\treturn value\n      end\n    end\n    nil\n  end\n\n  def decode_tag(ns, name, attrs, parent, encodingstyle)\n    ele = ns.parse(name)\n\n    # Envelope based parsing.\n    if ((ele.namespace == @envelopenamespace) ||\n\t(@allow_unqualified_element && ele.namespace.nil?))\n      o = decode_soap_envelope(ns, ele, attrs, parent)\n      return o if o\n    end\n\n    # Encoding based parsing.\n    handler = find_handler(encodingstyle)\n    if handler\n      return handler.decode_tag(ns, ele, attrs, parent)\n    else\n      raise FormatDecodeError.new(\"Unknown encodingStyle: #{ encodingstyle }.\")\n    end\n  end\n\n  def decode_tag_end(ns, node, encodingstyle)\n    return unless encodingstyle\n\n    handler = find_handler(encodingstyle)\n    if handler\n      return handler.decode_tag_end(ns, node)\n    else\n      raise FormatDecodeError.new(\"Unknown encodingStyle: #{ encodingstyle }.\")\n    end\n  end\n\n  def decode_text(ns, text, encodingstyle)\n    handler = find_handler(encodingstyle)\n\n    if handler\n      handler.decode_text(ns, text)\n    else\n      # How should I do?\n    end\n  end\n\n  def decode_soap_envelope(ns, ele, attrs, parent)\n    o = nil\n    if ele.name == EleEnvelope\n      o = SOAPEnvelope.new\n      if ext = @opt[:external_content]\n\text.each do |k, v|\n\t  o.external_content[k] = v\n\tend\n      end\n    elsif ele.name == EleHeader\n      unless parent.node.is_a?(SOAPEnvelope)\n\traise FormatDecodeError.new(\"Header should be a child of Envelope.\")\n      end\n      o = SOAPHeader.new\n      parent.node.header = o\n    elsif ele.name == EleBody\n      unless parent.node.is_a?(SOAPEnvelope)\n\traise FormatDecodeError.new(\"Body should be a child of Envelope.\")\n      end\n      o = SOAPBody.new\n      parent.node.body = o\n    elsif ele.name == EleFault\n      unless parent.node.is_a?(SOAPBody)\n\traise FormatDecodeError.new(\"Fault should be a child of Body.\")\n      end\n      o = SOAPFault.new\n      parent.node.fault = o\n    end\n    o\n  end\n\n  def find_handler(encodingstyle)\n    unless @handlers.key?(encodingstyle)\n      handler_factory = SOAP::EncodingStyle::Handler.handler(encodingstyle) ||\n\tSOAP::EncodingStyle::Handler.handler(EncodingNamespace)\n      handler = handler_factory.new(@parser.charset)\n      handler.decode_typemap = @decode_typemap\n      handler.decode_prologue\n      @handlers[encodingstyle] = handler\n    end\n    @handlers[encodingstyle]\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/processor.rb",
    "content": "# SOAP4R - marshal/unmarshal interface.\n# Copyright (C) 2000, 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/datatypes'\nrequire 'soap/soap'\nrequire 'soap/element'\nrequire 'soap/parser'\nrequire 'soap/generator'\nrequire 'soap/encodingstyle/soapHandler'\nrequire 'soap/encodingstyle/literalHandler'\nrequire 'soap/encodingstyle/aspDotNetHandler'\n\n\nmodule SOAP\n\n\nmodule Processor\n  @@default_parser_option = {}\n\n  class << self\n  public\n\n    def marshal(env, opt = {}, io = nil)\n      generator = create_generator(opt)\n      marshalled_str = generator.generate(env, io)\n      unless env.external_content.empty?\n\topt[:external_content] = env.external_content\n      end\n      marshalled_str\n    end\n\n    def unmarshal(stream, opt = {})\n      parser = create_parser(opt)\n      parser.parse(stream)\n    end\n\n    def default_parser_option=(rhs)\n      @@default_parser_option = rhs\n    end\n\n    def default_parser_option\n      @@default_parser_option\n    end\n\n  private\n\n    def create_generator(opt)\n      SOAPGenerator.new(opt)\n    end\n\n    def create_parser(opt)\n      if opt.empty?\n\topt = @@default_parser_option\n      end\n      ::SOAP::Parser.new(opt)\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/property.rb",
    "content": "# soap/property.rb: SOAP4R - Property implementation.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule SOAP\n\n\n# Property stream format:\n#\n#   line separator is \\r?\\n.  1 line per a property.\n#   line which begins with '#' is a comment line.  empty line is ignored, too.\n#   key/value separator is ':' or '='.\n#   '\\' as escape character.  but line separator cannot be escaped.\n#   \\s at the head/tail of key/value are trimmed.\n#\n#   '[' + key + ']' indicates property section.  for example,\n#\n#     [aaa.bbb]\n#     ccc = ddd\n#     eee.fff = ggg\n#     []\n#     aaa.hhh = iii\n#\n#   is the same as;\n#\n#     aaa.bbb.ccc = ddd\n#     aaa.bbb.eee.fff = ggg\n#     aaa.hhh = iii\n#\nclass Property\n  FrozenError = (RUBY_VERSION >= \"1.9.0\") ? RuntimeError : TypeError\n\n  include Enumerable\n\n  module Util\n    def const_from_name(fqname)\n      fqname.split(\"::\").inject(Kernel) { |klass, name| klass.const_get(name) }\n    end\n    module_function :const_from_name\n\n    def require_from_name(fqname)\n      require File.join(fqname.split(\"::\").collect { |ele| ele.downcase })\n    end\n    module_function :require_from_name\n  end\n\n  def self.load(stream)\n    new.load(stream)\n  end\n\n  def self.loadproperty(propname)\n    new.loadproperty(propname)\n  end\n\n  def initialize\n    @store = Hash.new\n    @hook = Hash.new\n    @self_hook = Array.new\n    @locked = false\n  end\n\n  KEY_REGSRC = '([^=:\\\\\\\\]*(?:\\\\\\\\.[^=:\\\\\\\\]*)*)'\n  DEF_REGSRC = '\\\\s*' + KEY_REGSRC + '\\\\s*[=:]\\\\s*(.*)'\n  COMMENT_REGEXP = Regexp.new('^(?:#.*|)$')\n  CATDEF_REGEXP = Regexp.new(\"^\\\\[\\\\s*#{KEY_REGSRC}\\\\s*\\\\]$\")\n  LINE_REGEXP = Regexp.new(\"^#{DEF_REGSRC}$\")\n  def load(stream)\n    key_prefix = \"\"\n    stream.each_with_index do |line, lineno|\n      line.sub!(/\\r?\\n\\z/, '')\n      case line\n      when COMMENT_REGEXP\n\tnext\n      when CATDEF_REGEXP\n\tkey_prefix = $1.strip\n      when LINE_REGEXP\n\tkey, value = $1.strip, $2.strip\n\tkey = \"#{key_prefix}.#{key}\" unless key_prefix.empty?\n\tkey, value = loadstr(key), loadstr(value)\n\tself[key] = value\n      else\n\traise TypeError.new(\n\t  \"property format error at line #{lineno + 1}: `#{line}'\")\n      end\n    end\n    self\n  end\n\n  # find property from $:.\n  def loadproperty(propname)\n    return loadpropertyfile(propname) if File.file?(propname)\n    $:.each do |path|\n      if File.file?(file = File.join(path, propname))\n        return loadpropertyfile(file)\n      end\n    end\n    nil\n  end\n\n  # name: a Symbol, String or an Array\n  def [](name)\n    referent(name_to_a(name))\n  end\n\n  # name: a Symbol, String or an Array\n  # value: an Object\n  def []=(name, value)\n    name_pair = name_to_a(name).freeze\n    hooks = assign(name_pair, value)\n    hooks.each do |hook|\n      hook.call(name_pair, value)\n    end\n    value\n  end\n\n  # value: an Object\n  # key is generated by property\n  def <<(value)\n    self[generate_new_key] = value\n  end\n\n  # name: a Symbol, String or an Array; nil means hook to the root\n  # cascade: true/false; for cascading hook of sub key\n  # hook: block which will be called with 2 args, name and value\n  def add_hook(name = nil, cascade = false, &hook)\n    if name == nil or name == true or name == false\n      cascade = name\n      assign_self_hook(cascade, &hook)\n    else\n      assign_hook(name_to_a(name), cascade, &hook)\n    end\n  end\n\n  def each\n    @store.each do |key, value|\n      yield(key, value)\n    end\n  end\n\n  def empty?\n    @store.empty?\n  end\n\n  def keys\n    @store.keys\n  end\n\n  def values\n    @store.values\n  end\n\n  def lock(cascade = false)\n    if cascade\n      each_key do |key|\n\tkey.lock(cascade)\n      end\n    end\n    @locked = true\n    self\n  end\n\n  def unlock(cascade = false)\n    @locked = false\n    if cascade\n      each_key do |key|\n\tkey.unlock(cascade)\n      end\n    end\n    self\n  end\n\n  def locked?\n    @locked\n  end\n\nprotected\n\n  def deref_key(key)\n    check_lock(key)\n    ref = @store[key] ||= self.class.new\n    unless propkey?(ref)\n      raise ArgumentError.new(\"key `#{key}' already defined as a value\")\n    end\n    ref\n  end\n\n  def local_referent(key)\n    check_lock(key)\n    if propkey?(@store[key]) and @store[key].locked?\n      raise FrozenError.new(\"cannot split any key from locked property\")\n    end\n    @store[key]\n  end\n\n  def local_assign(key, value)\n    check_lock(key)\n    if @locked\n      if propkey?(value)\n\traise FrozenError.new(\"cannot add any key to locked property\")\n      elsif propkey?(@store[key])\n\traise FrozenError.new(\"cannot override any key in locked property\")\n      end\n    end\n    @store[key] = value\n  end\n\n  def local_hook(key, direct)\n    hooks = []\n    (@self_hook + (@hook[key] || NO_HOOK)).each do |hook, cascade|\n      hooks << hook if direct or cascade\n    end\n    hooks\n  end\n\n  def local_assign_hook(key, cascade, &hook)\n    check_lock(key)\n    @store[key] ||= nil\n    (@hook[key] ||= []) << [hook, cascade]\n  end\n\nprivate\n\n  NO_HOOK = [].freeze\n\n  def referent(ary)\n    ary[0..-2].inject(self) { |ref, name|\n      ref.deref_key(to_key(name))\n    }.local_referent(to_key(ary.last))\n  end\n\n  def assign(ary, value)\n    ref = self\n    hook = NO_HOOK\n    ary[0..-2].each do |name|\n      key = to_key(name)\n      hook += ref.local_hook(key, false)\n      ref = ref.deref_key(key)\n    end\n    last_key = to_key(ary.last)\n    ref.local_assign(last_key, value)\n    hook + ref.local_hook(last_key, true)\n  end\n\n  def assign_hook(ary, cascade, &hook)\n    ary[0..-2].inject(self) { |ref, name|\n      ref.deref_key(to_key(name))\n    }.local_assign_hook(to_key(ary.last), cascade, &hook)\n  end\n\n  def assign_self_hook(cascade, &hook)\n    check_lock(nil)\n    @self_hook << [hook, cascade]\n  end\n\n  def each_key\n    self.each do |key, value|\n      if propkey?(value)\n\tyield(value)\n      end\n    end\n  end\n\n  def check_lock(key)\n    if @locked and (key.nil? or !@store.key?(key))\n      raise FrozenError.new(\"cannot add any key to locked property\")\n    end\n  end\n\n  def propkey?(value)\n    value.is_a?(::SOAP::Property)\n  end\n\n  def name_to_a(name)\n    case name\n    when Symbol\n      [name]\n    when String\n      name.scan(/[^.\\\\]+(?:\\\\.[^.\\\\])*/)\t# split with unescaped '.'\n    when Array\n      name\n    else\n      raise ArgumentError.new(\"Unknown name #{name}(#{name.class})\")\n    end\n  end\n\n  def to_key(name)\n    name.to_s.downcase\n  end\n\n  def generate_new_key\n    if @store.empty?\n      \"0\"\n    else\n      (key_max + 1).to_s\n    end\n  end\n\n  def key_max\n    (@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i\n  end\n\n  def loadpropertyfile(file)\n    puts \"find property at #{file}\" if $DEBUG\n    File.open(file) do |f|\n      load(f)\n    end\n  end\n\n  def loadstr(str)\n    str.gsub(/\\\\./) { |c| eval(\"\\\"#{c}\\\"\") }\n  end\nend\n\n\nend\n\n\n# for ruby/1.6.\nunless Enumerable.instance_methods.include?('inject')\n  module Enumerable\n    def inject(init)\n      result = init\n      each do |item|\n\tresult = yield(result, item)\n      end\n      result\n    end\n  end\nend\n"
  },
  {
    "path": "lib/soap/rpc/cgistub.rb",
    "content": "# SOAP4R - CGI/mod_ruby stub library\n# Copyright (C) 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/streamHandler'\nrequire 'webrick/httpresponse'\nrequire 'webrick/httpstatus'\nrequire 'logger'\nrequire 'soap/rpc/soaplet'\n\n\nmodule SOAP\nmodule RPC\n\n\n###\n# SYNOPSIS\n#   CGIStub.new\n#\n# DESCRIPTION\n#   To be written...\n#\nclass CGIStub < Logger::Application\n  include SOAP\n  include WEBrick\n\n  class SOAPRequest\n    attr_reader :body\n\n    def [](var); end\n\n    def meta_vars; end\n  end\n\n  class SOAPStdinRequest < SOAPRequest\n    attr_reader :body\n\n    def initialize(stream)\n      size = ENV['CONTENT_LENGTH'].to_i || 0\n      @body = stream.read(size)\n    end\n\n    def [](var)\n      ENV[var.gsub(/-/, '_').upcase]\n    end\n\n    def meta_vars\n      {\n        'HTTP_SOAPACTION' => ENV['HTTP_SOAPAction']\n      }\n    end\n  end\n\n  class SOAPFCGIRequest < SOAPRequest\n    attr_reader :body\n\n    def initialize(request)\n      @request = request\n      @body = @request.in.read\n    end\n\n    def [](var)\n      @request.env[var.gsub(/-/, '_').upcase]\n    end\n\n    def meta_vars\n      {\n        'HTTP_SOAPACTION' => @request.env['HTTP_SOAPAction']\n      }\n    end\n  end\n\n  def initialize(appname, default_namespace)\n    super(appname)\n    set_log(STDERR)\n    self.level = ERROR\n    @default_namespace = default_namespace\n    @remote_host = ENV['REMOTE_HOST'] || ENV['REMOTE_ADDR'] || 'unknown'\n    @router = ::SOAP::RPC::Router.new(self.class.name)\n    @soaplet = ::SOAP::RPC::SOAPlet.new(@router)\n    on_init\n  end\n  \n  def on_init\n    # do extra initialization in a derived class if needed.\n  end\n\n  def mapping_registry\n    @router.mapping_registry\n  end\n\n  def mapping_registry=(value)\n    @router.mapping_registry = value\n  end\n\n  def generate_explicit_type\n    @router.generate_explicit_type\n  end\n\n  def generate_explicit_type=(generate_explicit_type)\n    @router.generate_explicit_type = generate_explicit_type\n  end\n\n  # servant entry interface\n\n  def add_rpc_servant(obj, namespace = @default_namespace)\n    @router.add_rpc_servant(obj, namespace)\n  end\n  alias add_servant add_rpc_servant\n\n  def add_headerhandler(obj)\n    @router.add_headerhandler(obj)\n  end\n  alias add_rpc_headerhandler add_headerhandler\n\n  # method entry interface\n\n  def add_rpc_method(obj, name, *param)\n    add_rpc_method_with_namespace_as(@default_namespace, obj, name, name, *param)\n  end\n  alias add_method add_rpc_method\n\n  def add_rpc_method_as(obj, name, name_as, *param)\n    add_rpc_method_with_namespace_as(@default_namespace, obj, name, name_as, *param)\n  end\n  alias add_method_as add_rpc_method_as\n\n  def add_rpc_method_with_namespace(namespace, obj, name, *param)\n    add_rpc_method_with_namespace_as(namespace, obj, name, name, *param)\n  end\n  alias add_method_with_namespace add_rpc_method_with_namespace\n\n  def add_rpc_method_with_namespace_as(namespace, obj, name, name_as, *param)\n    qname = XSD::QName.new(namespace, name_as)\n    soapaction = nil\n    param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)\n    @router.add_rpc_operation(obj, qname, soapaction, name, param_def)\n  end\n  alias add_method_with_namespace_as add_rpc_method_with_namespace_as\n\n  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})\n    @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)\n  end\n\n  def add_document_operation(receiver, soapaction, name, param_def, opt = {})\n    @router.add_document_operation(receiver, soapaction, name, param_def, opt)\n  end\n\n  def set_fcgi_request(request)\n    @fcgi = request\n  end\n\nprivate\n\n  HTTPVersion = WEBrick::HTTPVersion.new('1.0')       # dummy; ignored\n\n  def run\n    res = WEBrick::HTTPResponse.new({:HTTPVersion => HTTPVersion})\n    begin\n      @log.info { \"received a request from '#{ @remote_host }'\" }\n      if @fcgi\n        req = SOAPFCGIRequest.new(@fcgi)\n      else\n        req = SOAPStdinRequest.new($stdin)\n      end\n      @soaplet.do_POST(req, res)\n    rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex\n      res.set_error(ex)\n    rescue HTTPStatus::Error => ex\n      res.set_error(ex)\n    rescue HTTPStatus::Status => ex\n      res.status = ex.code\n    rescue StandardError, NameError => ex # for Ruby 1.6\n      res.set_error(ex, true)\n    ensure\n      if defined?(MOD_RUBY)\n        r = Apache.request\n        r.status = res.status\n        r.content_type = res.content_type\n        r.send_http_header\n        buf = res.body\n      else\n        buf = ''\n        res.send_response(buf)\n        buf.sub!(/^[^\\r]+\\r\\n/, '')       # Trim status line.\n      end\n      @log.debug { \"SOAP CGI Response:\\n#{ buf }\" }\n      if @fcgi\n        @fcgi.out.print buf\n        @fcgi.finish\n        @fcgi = nil\n      else\n        print buf\n      end\n    end\n    0\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/driver.rb",
    "content": "# SOAP4R - SOAP RPC driver\n# Copyright (C) 2000, 2001, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/soap'\nrequire 'soap/mapping'\nrequire 'soap/mapping/wsdlliteralregistry'\nrequire 'soap/rpc/rpc'\nrequire 'soap/rpc/proxy'\nrequire 'soap/rpc/element'\nrequire 'soap/streamHandler'\nrequire 'soap/property'\nrequire 'soap/header/handlerset'\n\n\nmodule SOAP\nmodule RPC\n\n\nclass Driver\n  class << self\n    if RUBY_VERSION >= \"1.7.0\"\n      def __attr_proxy(symbol, assignable = false)\n        name = symbol.to_s\n        define_method(name) {\n          @proxy.__send__(name)\n        }\n        if assignable\n          aname = name + '='\n          define_method(aname) { |rhs|\n            @proxy.__send__(aname, rhs)\n          }\n        end\n      end\n    else\n      def __attr_proxy(symbol, assignable = false)\n        name = symbol.to_s\n        module_eval <<-EOS\n          def #{name}\n            @proxy.#{name}\n          end\n        EOS\n        if assignable\n          module_eval <<-EOS\n            def #{name}=(value)\n              @proxy.#{name} = value\n            end\n          EOS\n        end\n      end\n    end\n  end\n\n  __attr_proxy :endpoint_url, true\n  __attr_proxy :mapping_registry, true\n  __attr_proxy :default_encodingstyle, true\n  __attr_proxy :generate_explicit_type, true\n  __attr_proxy :allow_unqualified_element, true\n  __attr_proxy :headerhandler\n  __attr_proxy :streamhandler\n  __attr_proxy :test_loopback_response\n  __attr_proxy :reset_stream\n\n  attr_reader :proxy\n  attr_reader :options\n  attr_accessor :soapaction\n\n  def inspect\n    \"#<#{self.class}:#{@proxy.inspect}>\"\n  end\n\n  def httpproxy\n    options[\"protocol.http.proxy\"]\n  end\n\n  def httpproxy=(httpproxy)\n    options[\"protocol.http.proxy\"] = httpproxy\n  end\n\n  def wiredump_dev\n    options[\"protocol.http.wiredump_dev\"]\n  end\n\n  def wiredump_dev=(wiredump_dev)\n    options[\"protocol.http.wiredump_dev\"] = wiredump_dev\n  end\n\n  def mandatorycharset\n    options[\"protocol.mandatorycharset\"]\n  end\n\n  def mandatorycharset=(mandatorycharset)\n    options[\"protocol.mandatorycharset\"] = mandatorycharset\n  end\n\n  def wiredump_file_base\n    options[\"protocol.wiredump_file_base\"]\n  end\n\n  def wiredump_file_base=(wiredump_file_base)\n    options[\"protocol.wiredump_file_base\"] = wiredump_file_base\n  end\n\n  def initialize(endpoint_url, namespace = nil, soapaction = nil)\n    @namespace = namespace\n    @soapaction = soapaction\n    @options = setup_options\n    @wiredump_file_base = nil\n    @proxy = Proxy.new(endpoint_url, @soapaction, @options)\n  end\n\n  def loadproperty(propertyname)\n    unless options.loadproperty(propertyname)\n      raise LoadError.new(\"No such property to load -- #{propertyname}\")\n    end\n  end\n\n  def add_rpc_method(name, *params)\n    add_rpc_method_with_soapaction_as(name, name, @soapaction, *params)\n  end\n\n  def add_rpc_method_as(name, name_as, *params)\n    add_rpc_method_with_soapaction_as(name, name_as, @soapaction, *params)\n  end\n\n  def add_rpc_method_with_soapaction(name, soapaction, *params)\n    add_rpc_method_with_soapaction_as(name, name, soapaction, *params)\n  end\n\n  def add_rpc_method_with_soapaction_as(name, name_as, soapaction, *params)\n    param_def = SOAPMethod.create_rpc_param_def(params)\n    qname = XSD::QName.new(@namespace, name_as)\n    @proxy.add_rpc_method(qname, soapaction, name, param_def)\n    add_rpc_method_interface(name, param_def)\n  end\n\n  # add_method is for shortcut of typical rpc/encoded method definition.\n  alias add_method add_rpc_method\n  alias add_method_as add_rpc_method_as\n  alias add_method_with_soapaction add_rpc_method_with_soapaction\n  alias add_method_with_soapaction_as add_rpc_method_with_soapaction_as\n\n  def add_document_method(name, soapaction, req_qname, res_qname)\n    param_def = SOAPMethod.create_doc_param_def(req_qname, res_qname)\n    @proxy.add_document_method(soapaction, name, param_def)\n    add_document_method_interface(name, param_def)\n  end\n\n  def add_rpc_operation(qname, soapaction, name, param_def, opt = {})\n    @proxy.add_rpc_operation(qname, soapaction, name, param_def, opt)\n    add_rpc_method_interface(name, param_def)\n  end\n\n  def add_document_operation(soapaction, name, param_def, opt = {})\n    @proxy.add_document_operation(soapaction, name, param_def, opt)\n    add_document_method_interface(name, param_def)\n  end\n\n  def invoke(headers, body)\n    if headers and !headers.is_a?(SOAPHeader)\n      headers = create_header(headers)\n    end\n    set_wiredump_file_base(body.elename.name)\n    env = @proxy.invoke(headers, body)\n    if env.nil?\n      return nil, nil\n    else\n      return env.header, env.body\n    end\n  end\n\n  def call(name, *params)\n    set_wiredump_file_base(name)\n    @proxy.call(name, *params)\n  end\n\nprivate\n\n  def set_wiredump_file_base(name)\n    if @wiredump_file_base\n      @proxy.set_wiredump_file_base(\"#{@wiredump_file_base}_#{name}\")\n    end\n  end\n\n  def create_header(headers)\n    header = SOAPHeader.new()\n    headers.each do |content, mustunderstand, encodingstyle|\n      header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle))\n    end\n    header\n  end\n\n  def setup_options\n    if opt = Property.loadproperty(::SOAP::PropertyName)\n      opt = opt[\"client\"]\n    end\n    opt ||= Property.new\n    opt.add_hook(\"protocol.mandatorycharset\") do |key, value|\n      @proxy.mandatorycharset = value\n    end\n    opt.add_hook(\"protocol.wiredump_file_base\") do |key, value|\n      @wiredump_file_base = value\n    end\n    opt[\"protocol.http.charset\"] ||= XSD::Charset.xml_encoding_label\n    opt[\"protocol.http.proxy\"] ||= Env::HTTP_PROXY\n    opt[\"protocol.http.no_proxy\"] ||= Env::NO_PROXY\n    opt\n  end\n\n  def add_rpc_method_interface(name, param_def)\n    param_count = RPC::SOAPMethod.param_count(param_def,\n      RPC::SOAPMethod::IN, RPC::SOAPMethod::INOUT)\n    add_method_interface(name, param_count)\n  end\n\n  def add_document_method_interface(name, param_def)\n    param_count = RPC::SOAPMethod.param_count(param_def, RPC::SOAPMethod::IN)\n    add_method_interface(name, param_count)\n  end\n\n  if RUBY_VERSION > \"1.7.0\"\n    def add_method_interface(name, param_count)\n      ::SOAP::Mapping.define_singleton_method(self, name) do |*arg|\n        unless arg.size == param_count\n          raise ArgumentError.new(\n          \"wrong number of arguments (#{arg.size} for #{param_count})\")\n        end\n        call(name, *arg)\n      end\n      self.method(name)\n    end\n  else\n    def add_method_interface(name, param_count)\n      instance_eval <<-EOS\n        def #{name}(*arg)\n          unless arg.size == #{param_count}\n            raise ArgumentError.new(\n              \"wrong number of arguments (\\#{arg.size} for #{param_count})\")\n          end\n          call(#{name.dump}, *arg)\n        end\n      EOS\n      self.method(name)\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/element.rb",
    "content": "# SOAP4R - RPC element definition.\n# Copyright (C) 2000, 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/baseData'\n\n\nmodule SOAP\n\n# Add method definitions for RPC to common definition in element.rb\nclass SOAPBody < SOAPStruct\n  public\n\n  def request\n    root_node\n  end\n\n  def response\n    root = root_node\n    if !@is_fault\n      if root.nil?\n        nil\n      elsif root.is_a?(SOAPBasetype)\n        root\n      else\n        # Initial element is [retval].\n        root[0]\n      end\n    else\n      root\n    end\n  end\n\n  def outparams\n    root = root_node\n    if !@is_fault and !root.nil? and !root.is_a?(SOAPBasetype)\n      op = root[1..-1]\n      op = nil if op && op.empty?\n      op\n    else\n      nil\n    end\n  end\n\n  def fault\n    if @is_fault\n      self['fault']\n    else\n      nil\n    end\n  end\n\n  def fault=(fault)\n    @is_fault = true\n    add_member('fault', fault)\n  end\nend\n\n\nmodule RPC\n\n\nclass RPCError < Error; end\nclass MethodDefinitionError < RPCError; end\nclass ParameterError < RPCError; end\n\nclass SOAPMethod < SOAPStruct\n  RETVAL = 'retval'\n  IN = 'in'\n  OUT = 'out'\n  INOUT = 'inout'\n\n  attr_reader :param_def\n  attr_reader :inparam\n  attr_reader :outparam\n  attr_reader :retval_name\n  attr_reader :retval_class_name\n\n  def initialize(qname, param_def = nil)\n    super(nil)\n    @elename = qname\n    @encodingstyle = nil\n\n    @param_def = param_def\n\n    @signature = []\n    @inparam_names = []\n    @inoutparam_names = []\n    @outparam_names = []\n\n    @inparam = {}\n    @outparam = {}\n    @retval_name = nil\n    @retval_class_name = nil\n\n    init_param(@param_def) if @param_def\n  end\n\n  def have_outparam?\n    @outparam_names.size > 0\n  end\n\n  def input_params\n    collect_params(IN, INOUT)\n  end\n\n  def output_params\n    collect_params(OUT, INOUT)\n  end\n\n  def set_param(params)\n    params.each do |param, data|\n      @inparam[param] = data\n      data.elename.name = param\n      data.parent = self\n    end\n  end\n\n  def set_outparam(params)\n    params.each do |param, data|\n      @outparam[param] = data\n      data.elename.name = param\n    end\n  end\n\n  def SOAPMethod.param_count(param_def, *type)\n    count = 0\n    param_def.each do |io_type, name, param_type|\n      if type.include?(io_type)\n        count += 1\n      end\n    end\n    count\n  end\n\n  def SOAPMethod.derive_rpc_param_def(obj, name, *param)\n    if param.size == 1 and param[0].is_a?(Array)\n      return param[0]\n    end\n    if param.empty?\n      method = obj.method(name)\n      param_names = (1..method.arity.abs).collect { |i| \"p#{i}\" }\n    else\n      param_names = param\n    end\n    create_rpc_param_def(param_names)\n  end\n\n  def SOAPMethod.create_rpc_param_def(param_names)\n    param_def = []\n    param_names.each do |param_name|\n      param_def.push([IN, param_name, nil])\n    end\n    param_def.push([RETVAL, 'return', nil])\n    param_def\n  end\n\n  def SOAPMethod.create_doc_param_def(req_qnames, res_qnames)\n    req_qnames = [req_qnames] if req_qnames.is_a?(XSD::QName)\n    res_qnames = [res_qnames] if res_qnames.is_a?(XSD::QName)\n    param_def = []\n    req_qnames.each do |qname|\n      param_def << [IN, qname.name, [nil, qname.namespace, qname.name]]\n    end\n    res_qnames.each do |qname|\n      param_def << [OUT, qname.name, [nil, qname.namespace, qname.name]]\n    end\n    param_def\n  end\n\nprivate\n\n  def collect_params(*type)\n    names = []\n    @signature.each do |io_type, name, param_type|\n      names << name if type.include?(io_type)\n    end\n    names\n  end\n\n  def init_param(param_def)\n    param_def.each do |io_type, name, param_type|\n      case io_type\n      when IN\n        @signature.push([IN, name, param_type])\n        @inparam_names.push(name)\n      when OUT\n        @signature.push([OUT, name, param_type])\n        @outparam_names.push(name)\n      when INOUT\n        @signature.push([INOUT, name, param_type])\n        @inoutparam_names.push(name)\n      when RETVAL\n        if @retval_name\n          raise MethodDefinitionError.new('duplicated retval')\n        end\n        @retval_name = name\n        @retval_class_name = nil\n        if param_type\n          if param_type[0].is_a?(String)\n            @retval_class_name = Mapping.class_from_name(param_type[0])\n          else\n            @retval_class_name = param_type[0]\n          end\n        end\n      else\n        raise MethodDefinitionError.new(\"unknown type: #{io_type}\")\n      end\n    end\n  end\nend\n\n\nclass SOAPMethodRequest < SOAPMethod\n  attr_accessor :soapaction\n\n  def SOAPMethodRequest.create_request(qname, *params)\n    param_def = []\n    param_value = []\n    i = 0\n    params.each do |param|\n      param_name = \"p#{i}\"\n      i += 1\n      param_def << [IN, param_name, nil]\n      param_value << [param_name, param]\n    end\n    param_def << [RETVAL, 'return', nil]\n    o = new(qname, param_def)\n    o.set_param(param_value)\n    o\n  end\n\n  def initialize(qname, param_def = nil, soapaction = nil)\n    check_elename(qname)\n    super(qname, param_def)\n    @soapaction = soapaction\n  end\n\n  def each\n    input_params.each do |name|\n      unless @inparam[name]\n        raise ParameterError.new(\"parameter: #{name} was not given\")\n      end\n      yield(name, @inparam[name])\n    end\n  end\n\n  def dup\n    req = self.class.new(@elename.dup, @param_def, @soapaction)\n    req.encodingstyle = @encodingstyle\n    req\n  end\n\n  def create_method_response(response_name = nil)\n    response_name ||=\n      XSD::QName.new(@elename.namespace, @elename.name + 'Response')\n    SOAPMethodResponse.new(response_name, @param_def)\n  end\n\nprivate\n\n  def check_elename(qname)\n    # NCName & ruby's method name\n    unless /\\A[\\w_][\\w\\d_\\-]*\\z/ =~ qname.name\n      raise MethodDefinitionError.new(\"element name '#{qname.name}' not allowed\")\n    end\n  end\nend\n\n\nclass SOAPMethodResponse < SOAPMethod\n\n  def initialize(qname, param_def = nil)\n    super(qname, param_def)\n    @retval = nil\n  end\n\n  def retval=(retval)\n    @retval = retval\n    @retval.elename = @retval.elename.dup_name(@retval_name || 'return')\n    retval.parent = self\n    retval\n  end\n\n  def each\n    if @retval_name and !@retval.is_a?(SOAPVoid)\n      yield(@retval_name, @retval)\n    end\n\n    output_params.each do |name|\n      unless @outparam[name]\n        raise ParameterError.new(\"parameter: #{name} was not given\")\n      end\n      yield(name, @outparam[name])\n    end\n  end\nend\n\n\n# To return(?) void explicitly.\n#  def foo(input_var)\n#    ...\n#    return SOAP::RPC::SOAPVoid.new\n#  end\nclass SOAPVoid < XSD::XSDAnySimpleType\n  include SOAPBasetype\n  extend SOAPModuleUtils\n  Name = XSD::QName.new(Mapping::RubyCustomTypeNamespace, nil)\n\npublic\n  def initialize()\n    @elename = Name\n    @id = nil\n    @precedents = []\n    @parent = nil\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/httpserver.rb",
    "content": "# SOAP4R - WEBrick HTTP Server\n# Copyright (C) 2003, 2004 by NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'logger'\nrequire 'soap/rpc/soaplet'\nrequire 'soap/streamHandler'\nrequire 'webrick'\n\n\nmodule SOAP\nmodule RPC\n\n\nclass HTTPServer < Logger::Application\n  attr_reader :server\n  attr_accessor :default_namespace\n\n  def initialize(config)\n    super(config[:SOAPHTTPServerApplicationName] || self.class.name)\n    @default_namespace = config[:SOAPDefaultNamespace]\n    @webrick_config = config.dup\n    self.level = Logger::Severity::ERROR # keep silent by default\n    @webrick_config[:Logger] ||= @log\n    @log = @webrick_config[:Logger]     # sync logger of App and HTTPServer\n    @router = ::SOAP::RPC::Router.new(self.class.name)\n    @soaplet = ::SOAP::RPC::SOAPlet.new(@router)\n    on_init\n    @server = WEBrick::HTTPServer.new(@webrick_config)\n    @server.mount('/', @soaplet)\n  end\n\n  def on_init\n    # do extra initialization in a derived class if needed.\n  end\n\n  def status\n    @server.status if @server\n  end\n\n  def shutdown\n    @server.shutdown if @server\n  end\n\n  def mapping_registry\n    @router.mapping_registry\n  end\n\n  def mapping_registry=(mapping_registry)\n    @router.mapping_registry = mapping_registry\n  end\n\n  def generate_explicit_type\n    @router.generate_explicit_type\n  end\n\n  def generate_explicit_type=(generate_explicit_type)\n    @router.generate_explicit_type = generate_explicit_type\n  end\n\n  # servant entry interface\n\n  def add_rpc_request_servant(factory, namespace = @default_namespace)\n    @router.add_rpc_request_servant(factory, namespace)\n  end\n\n  def add_rpc_servant(obj, namespace = @default_namespace)\n    @router.add_rpc_servant(obj, namespace)\n  end\n  \n  def add_request_headerhandler(factory)\n    @router.add_request_headerhandler(factory)\n  end\n\n  def add_headerhandler(obj)\n    @router.add_headerhandler(obj)\n  end\n  alias add_rpc_headerhandler add_headerhandler\n\n  # method entry interface\n\n  def add_rpc_method(obj, name, *param)\n    add_rpc_method_as(obj, name, name, *param)\n  end\n  alias add_method add_rpc_method\n\n  def add_rpc_method_as(obj, name, name_as, *param)\n    qname = XSD::QName.new(@default_namespace, name_as)\n    soapaction = nil\n    param_def = SOAPMethod.derive_rpc_param_def(obj, name, *param)\n    @router.add_rpc_operation(obj, qname, soapaction, name, param_def)\n  end\n  alias add_method_as add_rpc_method_as\n\n  def add_document_method(obj, soapaction, name, req_qnames, res_qnames)\n    param_def = SOAPMethod.create_doc_param_def(req_qnames, res_qnames)\n    @router.add_document_operation(obj, soapaction, name, param_def)\n  end\n\n  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})\n    @router.add_rpc_operation(receiver, qname, soapaction, name, param_def, opt)\n  end\n\n  def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {})\n    @router.add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt)\n  end\n\n  def add_document_operation(receiver, soapaction, name, param_def, opt = {})\n    @router.add_document_operation(receiver, soapaction, name, param_def, opt)\n  end\n\n  def add_document_request_operation(factory, soapaction, name, param_def, opt = {})\n    @router.add_document_request_operation(factory, soapaction, name, param_def, opt)\n  end\n\nprivate\n\n  def run\n    @server.start\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/proxy.rb",
    "content": "# SOAP4R - RPC Proxy library.\n# Copyright (C) 2000, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/soap'\nrequire 'soap/processor'\nrequire 'soap/mapping'\nrequire 'soap/rpc/rpc'\nrequire 'soap/rpc/element'\nrequire 'soap/streamHandler'\nrequire 'soap/mimemessage'\n\n\nmodule SOAP\nmodule RPC\n\n\nclass Proxy\n  include SOAP\n\npublic\n\n  attr_accessor :soapaction\n  attr_accessor :mandatorycharset\n  attr_accessor :allow_unqualified_element\n  attr_accessor :default_encodingstyle\n  attr_accessor :generate_explicit_type\n  attr_reader :headerhandler\n  attr_reader :streamhandler\n\n  attr_accessor :mapping_registry\n  attr_accessor :literal_mapping_registry\n\n  attr_reader :operation\n\n  def initialize(endpoint_url, soapaction, options)\n    @endpoint_url = endpoint_url\n    @soapaction = soapaction\n    @options = options\n    @streamhandler = HTTPStreamHandler.new(\n      @options[\"protocol.http\"] ||= ::SOAP::Property.new)\n    @operation = {}\n    @mandatorycharset = nil\n    @allow_unqualified_element = true\n    @default_encodingstyle = nil\n    @generate_explicit_type = true\n    @headerhandler = Header::HandlerSet.new\n    @mapping_registry = nil\n    @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new\n  end\n\n  def inspect\n    \"#<#{self.class}:#{@endpoint_url}>\"\n  end\n\n  def endpoint_url\n    @endpoint_url\n  end\n\n  def endpoint_url=(endpoint_url)\n    @endpoint_url = endpoint_url\n    reset_stream\n  end\n\n  def reset_stream\n    @streamhandler.reset(@endpoint_url)\n  end\n\n  def set_wiredump_file_base(wiredump_file_base)\n    @streamhandler.wiredump_file_base = wiredump_file_base\n  end\n\n  def test_loopback_response\n    @streamhandler.test_loopback_response\n  end\n\n  def add_rpc_operation(qname, soapaction, name, param_def, opt = {})\n    opt[:request_qname] = qname\n    opt[:request_style] ||= :rpc\n    opt[:response_style] ||= :rpc\n    opt[:request_use] ||= :encoded\n    opt[:response_use] ||= :encoded\n    @operation[name] = Operation.new(soapaction, param_def, opt)\n  end\n\n  def add_document_operation(soapaction, name, param_def, opt = {})\n    opt[:request_style] ||= :document\n    opt[:response_style] ||= :document\n    opt[:request_use] ||= :literal\n    opt[:response_use] ||= :literal\n    # default values of these values are unqualified in XML Schema.\n    # set true for backward compatibility.\n    unless opt.key?(:elementformdefault)\n      opt[:elementformdefault] = true\n    end\n    unless opt.key?(:attributeformdefault)\n      opt[:attributeformdefault] = true\n    end\n    @operation[name] = Operation.new(soapaction, param_def, opt)\n  end\n\n  # add_method is for shortcut of typical rpc/encoded method definition.\n  alias add_method add_rpc_operation\n  alias add_rpc_method add_rpc_operation\n  alias add_document_method add_document_operation\n\n  def invoke(req_header, req_body, opt = nil)\n    opt ||= create_encoding_opt\n    route(req_header, req_body, opt, opt)\n  end\n\n  def call(name, *params)\n    unless op_info = @operation[name]\n      raise MethodDefinitionError, \"method: #{name} not defined\"\n    end\n    mapping_opt = create_mapping_opt\n    req_header = create_request_header\n    req_body = SOAPBody.new(\n      op_info.request_body(params, @mapping_registry,\n        @literal_mapping_registry, mapping_opt)\n    )\n    reqopt = create_encoding_opt(\n      :soapaction => op_info.soapaction || @soapaction,\n      :envelopenamespace => @options[\"soap.envelope.requestnamespace\"],\n      :default_encodingstyle =>\n        @default_encodingstyle || op_info.request_default_encodingstyle,\n      :elementformdefault => op_info.elementformdefault,\n      :attributeformdefault => op_info.attributeformdefault\n    )\n    resopt = create_encoding_opt(\n      :envelopenamespace => @options[\"soap.envelope.responsenamespace\"],\n      :default_encodingstyle =>\n        @default_encodingstyle || op_info.response_default_encodingstyle,\n      :elementformdefault => op_info.elementformdefault,\n      :attributeformdefault => op_info.attributeformdefault\n    )\n    env = route(req_header, req_body, reqopt, resopt)\n    raise EmptyResponseError unless env\n    receive_headers(env.header)\n    begin\n      check_fault(env.body)\n    rescue ::SOAP::FaultError => e\n      op_info.raise_fault(e, @mapping_registry, @literal_mapping_registry)\n    end\n    op_info.response_obj(env.body, @mapping_registry,\n      @literal_mapping_registry, mapping_opt)\n  end\n\n  def route(req_header, req_body, reqopt, resopt)\n    req_env = ::SOAP::SOAPEnvelope.new(req_header, req_body)\n    unless reqopt[:envelopenamespace].nil?\n      set_envelopenamespace(req_env, reqopt[:envelopenamespace])\n    end\n    reqopt[:external_content] = nil\n    conn_data = marshal(req_env, reqopt)\n    if ext = reqopt[:external_content]\n      mime = MIMEMessage.new\n      ext.each do |k, v|\n      \tmime.add_attachment(v.data)\n      end\n      mime.add_part(conn_data.send_string + \"\\r\\n\")\n      mime.close\n      conn_data.send_string = mime.content_str\n      conn_data.send_contenttype = mime.headers['content-type'].str\n    end\n    conn_data = @streamhandler.send(@endpoint_url, conn_data,\n      reqopt[:soapaction])\n    if conn_data.receive_string.empty?\n      return nil\n    end\n    unmarshal(conn_data, resopt)\n  end\n\n  def check_fault(body)\n    if body.fault\n      raise SOAP::FaultError.new(body.fault)\n    end\n  end\n\nprivate\n\n  def set_envelopenamespace(env, namespace)\n    env.elename = XSD::QName.new(namespace, env.elename.name)\n    if env.header\n      env.header.elename = XSD::QName.new(namespace, env.header.elename.name)\n    end\n    if env.body\n      env.body.elename = XSD::QName.new(namespace, env.body.elename.name)\n    end\n  end\n\n  def create_request_header\n    headers = @headerhandler.on_outbound\n    if headers.empty?\n      nil\n    else\n      h = ::SOAP::SOAPHeader.new\n      headers.each do |header|\n        h.add(header.elename.name, header)\n      end\n      h\n    end\n  end\n\n  def receive_headers(headers)\n    @headerhandler.on_inbound(headers) if headers\n  end\n\n  def marshal(env, opt)\n    send_string = Processor.marshal(env, opt)\n    StreamHandler::ConnectionData.new(send_string)\n  end\n\n  def unmarshal(conn_data, opt)\n    contenttype = conn_data.receive_contenttype\n    if /#{MIMEMessage::MultipartContentType}/i =~ contenttype\n      opt[:external_content] = {}\n      mime = MIMEMessage.parse(\"Content-Type: \" + contenttype,\n\tconn_data.receive_string)\n      mime.parts.each do |part|\n\tvalue = Attachment.new(part.content)\n\tvalue.contentid = part.contentid\n\tobj = SOAPAttachment.new(value)\n\topt[:external_content][value.contentid] = obj if value.contentid\n      end\n      opt[:charset] = @mandatorycharset ||\n\tStreamHandler.parse_media_type(mime.root.headers['content-type'].str)\n      env = Processor.unmarshal(mime.root.content, opt)\n    else\n      opt[:charset] = @mandatorycharset ||\n\t::SOAP::StreamHandler.parse_media_type(contenttype)\n      env = Processor.unmarshal(conn_data.receive_string, opt)\n    end\n    unless env.is_a?(::SOAP::SOAPEnvelope)\n      raise ResponseFormatError.new(\n        \"response is not a SOAP envelope: #{conn_data.receive_string}\")\n    end\n    env\n  end\n\n  def create_header(headers)\n    header = SOAPHeader.new()\n    headers.each do |content, mustunderstand, encodingstyle|\n      header.add(SOAPHeaderItem.new(content, mustunderstand, encodingstyle))\n    end\n    header\n  end\n\n  def create_encoding_opt(hash = nil)\n    opt = {}\n    opt[:default_encodingstyle] = @default_encodingstyle\n    opt[:allow_unqualified_element] = @allow_unqualified_element\n    opt[:generate_explicit_type] = @generate_explicit_type\n    opt[:no_indent] = @options[\"soap.envelope.no_indent\"]\n    opt[:use_numeric_character_reference] =\n      @options[\"soap.envelope.use_numeric_character_reference\"]\n    opt.update(hash) if hash\n    opt\n  end\n\n  def create_mapping_opt(hash = nil)\n    opt = {\n      :external_ces => @options[\"soap.mapping.external_ces\"]\n    }\n    opt.update(hash) if hash\n    opt\n  end\n\n  class Operation\n    attr_reader :soapaction\n    attr_reader :request_style\n    attr_reader :response_style\n    attr_reader :request_use\n    attr_reader :response_use\n    attr_reader :elementformdefault\n    attr_reader :attributeformdefault\n\n    def initialize(soapaction, param_def, opt)\n      @soapaction = soapaction\n      @request_style = opt[:request_style]\n      @response_style = opt[:response_style]\n      @request_use = opt[:request_use]\n      @response_use = opt[:response_use]\n      # set nil(unqualified) by default\n      @elementformdefault = opt[:elementformdefault]\n      @attributeformdefault = opt[:attributeformdefault]\n      check_style(@request_style)\n      check_style(@response_style)\n      check_use(@request_use)\n      check_use(@response_use)\n      if @request_style == :rpc\n        @rpc_request_qname = opt[:request_qname]\n        if @rpc_request_qname.nil?\n          raise MethodDefinitionError.new(\"rpc_request_qname must be given\")\n        end\n        @rpc_method_factory =\n          RPC::SOAPMethodRequest.new(@rpc_request_qname, param_def, @soapaction)\n      else\n        @doc_request_qnames = []\n        @doc_request_qualified = []\n        @doc_response_qnames = []\n        @doc_response_qualified = []\n        param_def.each do |inout, paramname, typeinfo, eleinfo|\n          klass_not_used, nsdef, namedef = typeinfo\n          qualified = eleinfo\n          if namedef.nil?\n            raise MethodDefinitionError.new(\"qname must be given\")\n          end\n          case inout\n          when SOAPMethod::IN\n            @doc_request_qnames << XSD::QName.new(nsdef, namedef)\n            @doc_request_qualified << qualified\n          when SOAPMethod::OUT\n            @doc_response_qnames << XSD::QName.new(nsdef, namedef)\n            @doc_response_qualified << qualified\n          else\n            raise MethodDefinitionError.new(\n              \"illegal inout definition for document style: #{inout}\")\n          end\n        end\n      end\n    end\n\n    def request_default_encodingstyle\n      (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace\n    end\n\n    def response_default_encodingstyle\n      (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace\n    end\n\n    def request_body(values, mapping_registry, literal_mapping_registry, opt)\n      if @request_style == :rpc\n        request_rpc(values, mapping_registry, literal_mapping_registry, opt)\n      else\n        request_doc(values, mapping_registry, literal_mapping_registry, opt)\n      end\n    end\n\n    def response_obj(body, mapping_registry, literal_mapping_registry, opt)\n      if @response_style == :rpc\n        response_rpc(body, mapping_registry, literal_mapping_registry, opt)\n      else\n        response_doc(body, mapping_registry, literal_mapping_registry, opt)\n      end\n    end\n\n    def raise_fault(e, mapping_registry, literal_mapping_registry)\n      if @response_style == :rpc\n        Mapping.fault2exception(e, mapping_registry)\n      else\n        Mapping.fault2exception(e, literal_mapping_registry)\n      end\n    end\n\n  private\n\n    def check_style(style)\n      unless [:rpc, :document].include?(style)\n        raise MethodDefinitionError.new(\"unknown style: #{style}\")\n      end\n    end\n\n    def check_use(use)\n      unless [:encoded, :literal].include?(use)\n        raise MethodDefinitionError.new(\"unknown use: #{use}\")\n      end\n    end\n\n    def request_rpc(values, mapping_registry, literal_mapping_registry, opt)\n      if @request_use == :encoded\n        request_rpc_enc(values, mapping_registry, opt)\n      else\n        request_rpc_lit(values, literal_mapping_registry, opt)\n      end\n    end\n\n    def request_doc(values, mapping_registry, literal_mapping_registry, opt)\n      if @request_use == :encoded\n        request_doc_enc(values, mapping_registry, opt)\n      else\n        request_doc_lit(values, literal_mapping_registry, opt)\n      end\n    end\n\n    def request_rpc_enc(values, mapping_registry, opt)\n      method = @rpc_method_factory.dup\n      names = method.input_params\n      obj = create_request_obj(names, values)\n      soap = Mapping.obj2soap(obj, mapping_registry, @rpc_request_qname, opt)\n      method.set_param(soap)\n      method\n    end\n\n    def request_rpc_lit(values, mapping_registry, opt)\n      method = @rpc_method_factory.dup\n      params = {}\n      idx = 0\n      method.input_params.each do |name|\n        params[name] = Mapping.obj2soap(values[idx], mapping_registry, \n          XSD::QName.new(nil, name), opt)\n        idx += 1\n      end\n      method.set_param(params)\n      method\n    end\n\n    def request_doc_enc(values, mapping_registry, opt)\n      (0...values.size).collect { |idx|\n        ele = Mapping.obj2soap(values[idx], mapping_registry, nil, opt)\n        ele.elename = @doc_request_qnames[idx]\n        ele\n      }\n    end\n\n    def request_doc_lit(values, mapping_registry, opt)\n      (0...values.size).collect { |idx|\n        ele = Mapping.obj2soap(values[idx], mapping_registry,\n          @doc_request_qnames[idx], opt)\n        ele.encodingstyle = LiteralNamespace\n        if ele.respond_to?(:qualified)\n          ele.qualified = @doc_request_qualified[idx]\n        end\n        ele\n      }\n    end\n\n    def response_rpc(body, mapping_registry, literal_mapping_registry, opt)\n      if @response_use == :encoded\n        response_rpc_enc(body, mapping_registry, opt)\n      else\n        response_rpc_lit(body, literal_mapping_registry, opt)\n      end\n    end\n\n    def response_doc(body, mapping_registry, literal_mapping_registry, opt)\n      if @response_use == :encoded\n        return *response_doc_enc(body, mapping_registry, opt)\n      else\n        return *response_doc_lit(body, literal_mapping_registry, opt)\n      end\n    end\n\n    def response_rpc_enc(body, mapping_registry, opt)\n      ret = nil\n      if body.response\n        ret = Mapping.soap2obj(body.response, mapping_registry,\n          @rpc_method_factory.retval_class_name, opt)\n      end\n      if body.outparams\n        outparams = body.outparams.collect { |outparam|\n          Mapping.soap2obj(outparam, mapping_registry, nil, opt)\n        }\n        [ret].concat(outparams)\n      else\n        ret\n      end\n    end\n\n    def response_rpc_lit(body, mapping_registry, opt)\n      body.root_node.collect { |key, value|\n        Mapping.soap2obj(value, mapping_registry,\n          @rpc_method_factory.retval_class_name, opt)\n      }\n    end\n\n    def response_doc_enc(body, mapping_registry, opt)\n      body.collect { |key, value|\n        Mapping.soap2obj(value, mapping_registry, nil, opt)\n      }\n    end\n\n    def response_doc_lit(body, mapping_registry, opt)\n      body.collect { |key, value|\n        Mapping.soap2obj(value, mapping_registry)\n      }\n    end\n\n    def create_request_obj(names, params)\n      o = Object.new\n      idx = 0\n      while idx < params.length\n        o.instance_variable_set('@' + names[idx], params[idx])\n        idx += 1\n      end\n      o\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/router.rb",
    "content": "# SOAP4R - RPC Routing library\n# Copyright (C) 2001, 2002, 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/soap'\nrequire 'soap/processor'\nrequire 'soap/mapping'\nrequire 'soap/mapping/wsdlliteralregistry'\nrequire 'soap/rpc/rpc'\nrequire 'soap/rpc/element'\nrequire 'soap/streamHandler'\nrequire 'soap/mimemessage'\nrequire 'soap/header/handlerset'\n\n\nmodule SOAP\nmodule RPC\n\n\nclass Router\n  include SOAP\n\n  attr_reader :actor\n  attr_accessor :mapping_registry\n  attr_accessor :literal_mapping_registry\n  attr_accessor :generate_explicit_type\n  attr_accessor :external_ces\n\n  def initialize(actor)\n    @actor = actor\n    @mapping_registry = nil\n    @headerhandler = Header::HandlerSet.new\n    @literal_mapping_registry = ::SOAP::Mapping::WSDLLiteralRegistry.new\n    @generate_explicit_type = true\n    @external_ces = nil\n    @operation_by_soapaction = {}\n    @operation_by_qname = {}\n    @headerhandlerfactory = []\n  end\n\n  ###\n  ## header handler interface\n  #\n  def add_request_headerhandler(factory)\n    unless factory.respond_to?(:create)\n      raise TypeError.new(\"factory must respond to 'create'\")\n    end\n    @headerhandlerfactory << factory\n  end\n\n  def add_headerhandler(handler)\n    @headerhandler.add(handler)\n  end\n\n  ###\n  ## servant definition interface\n  #\n  def add_rpc_request_servant(factory, namespace)\n    unless factory.respond_to?(:create)\n      raise TypeError.new(\"factory must respond to 'create'\")\n    end\n    obj = factory.create        # a dummy instance for introspection\n    ::SOAP::RPC.defined_methods(obj).each do |name|\n      begin\n        qname = XSD::QName.new(namespace, name)\n        param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)\n        opt = create_styleuse_option(:rpc, :encoded)\n        add_rpc_request_operation(factory, qname, nil, name, param_def, opt)\n      rescue SOAP::RPC::MethodDefinitionError => e\n        p e if $DEBUG\n      end\n    end\n  end\n\n  def add_rpc_servant(obj, namespace)\n    ::SOAP::RPC.defined_methods(obj).each do |name|\n      begin\n        qname = XSD::QName.new(namespace, name)\n        param_def = ::SOAP::RPC::SOAPMethod.derive_rpc_param_def(obj, name)\n        opt = create_styleuse_option(:rpc, :encoded)\n        add_rpc_operation(obj, qname, nil, name, param_def, opt)\n      rescue SOAP::RPC::MethodDefinitionError => e\n        p e if $DEBUG\n      end\n    end\n  end\n  alias add_servant add_rpc_servant\n\n  ###\n  ## operation definition interface\n  #\n  def add_rpc_operation(receiver, qname, soapaction, name, param_def, opt = {})\n    ensure_styleuse_option(opt, :rpc, :encoded)\n    opt[:request_qname] = qname\n    op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,\n      opt)\n    if opt[:request_style] != :rpc\n      raise RPCRoutingError.new(\"illegal request_style given\")\n    end\n    assign_operation(soapaction, qname, op)\n  end\n  alias add_method add_rpc_operation\n  alias add_rpc_method add_rpc_operation\n\n  def add_rpc_request_operation(factory, qname, soapaction, name, param_def, opt = {})\n    ensure_styleuse_option(opt, :rpc, :encoded)\n    opt[:request_qname] = qname\n    op = RequestScopeOperation.new(soapaction, factory, name, param_def, opt)\n    if opt[:request_style] != :rpc\n      raise RPCRoutingError.new(\"illegal request_style given\")\n    end\n    assign_operation(soapaction, qname, op)\n  end\n\n  def add_document_operation(receiver, soapaction, name, param_def, opt = {})\n    #\n    # adopt workaround for doc/lit wrapper method\n    # (you should consider to simply use rpc/lit service)\n    #\n    #unless soapaction\n    #  raise RPCRoutingError.new(\"soapaction is a must for document method\")\n    #end\n    ensure_styleuse_option(opt, :document, :literal)\n    op = ApplicationScopeOperation.new(soapaction, receiver, name, param_def,\n      opt)\n    if opt[:request_style] != :document\n      raise RPCRoutingError.new(\"illegal request_style given\")\n    end\n    assign_operation(soapaction, first_input_part_qname(param_def), op)\n  end\n  alias add_document_method add_document_operation\n\n  def add_document_request_operation(factory, soapaction, name, param_def, opt = {})\n    #\n    # adopt workaround for doc/lit wrapper method\n    # (you should consider to simply use rpc/lit service)\n    #\n    #unless soapaction\n    #  raise RPCRoutingError.new(\"soapaction is a must for document method\")\n    #end\n    ensure_styleuse_option(opt, :document, :literal)\n    op = RequestScopeOperation.new(soapaction, receiver, name, param_def, opt)\n    if opt[:request_style] != :document\n      raise RPCRoutingError.new(\"illegal request_style given\")\n    end\n    assign_operation(soapaction, first_input_part_qname(param_def), op)\n  end\n\n  def route(conn_data)\n    # we cannot set request_default_encodingsyle before parsing the content.\n    env = unmarshal(conn_data)\n    if env.nil?\n      raise ArgumentError.new(\"illegal SOAP marshal format\")\n    end\n    op = lookup_operation(conn_data.soapaction, env.body)\n    headerhandler = @headerhandler.dup\n    @headerhandlerfactory.each do |f|\n      headerhandler.add(f.create)\n    end\n    receive_headers(headerhandler, env.header)\n    soap_response = default_encodingstyle = nil\n    begin\n      soap_response =\n        op.call(env.body, @mapping_registry, @literal_mapping_registry,\n          create_mapping_opt)\n      default_encodingstyle = op.response_default_encodingstyle\n    rescue Exception\n      soap_response = fault($!)\n      default_encodingstyle = nil\n    end\n    conn_data.is_fault = true if soap_response.is_a?(SOAPFault)\n    header = call_headers(headerhandler)\n    body = SOAPBody.new(soap_response)\n    env = SOAPEnvelope.new(header, body)\n    marshal(conn_data, env, default_encodingstyle)\n  end\n\n  # Create fault response string.\n  def create_fault_response(e)\n    env = SOAPEnvelope.new(SOAPHeader.new, SOAPBody.new(fault(e)))\n    opt = {}\n    opt[:external_content] = nil\n    response_string = Processor.marshal(env, opt)\n    conn_data = StreamHandler::ConnectionData.new(response_string)\n    conn_data.is_fault = true\n    if ext = opt[:external_content]\n      mimeize(conn_data, ext)\n    end\n    conn_data\n  end\n\nprivate\n\n  def first_input_part_qname(param_def)\n    param_def.each do |inout, paramname, typeinfo|\n      if inout == SOAPMethod::IN\n        klass, nsdef, namedef = typeinfo\n        return XSD::QName.new(nsdef, namedef)\n      end\n    end\n    nil\n  end\n\n  def create_styleuse_option(style, use)\n    opt = {}\n    opt[:request_style] = opt[:response_style] = style\n    opt[:request_use] = opt[:response_use] = use\n    opt\n  end\n\n  def ensure_styleuse_option(opt, style, use)\n    opt[:request_style] ||= style\n    opt[:response_style] ||= style\n    opt[:request_use] ||= use\n    opt[:response_use] ||= use\n  end\n\n  def assign_operation(soapaction, qname, op)\n    assigned = false\n    if soapaction and !soapaction.empty?\n      @operation_by_soapaction[soapaction] = op\n      assigned = true\n    end\n    if qname\n      @operation_by_qname[qname] = op\n      assigned = true\n    end\n    unless assigned\n      raise RPCRoutingError.new(\"cannot assign operation\")\n    end\n  end\n\n  def lookup_operation(soapaction, body)\n    if op = @operation_by_soapaction[soapaction]\n      return op\n    end\n    qname = body.root_node.elename\n    if op = @operation_by_qname[qname]\n      return op\n    end\n    if soapaction\n      raise RPCRoutingError.new(\n        \"operation: #{soapaction} #{qname} not supported\")\n    else\n      raise RPCRoutingError.new(\"operation: #{qname} not supported\")\n    end\n  end\n\n  def call_headers(headerhandler)\n    headers = headerhandler.on_outbound\n    if headers.empty?\n      nil\n    else\n      h = ::SOAP::SOAPHeader.new\n      headers.each do |header|\n        h.add(header.elename.name, header)\n      end\n      h\n    end\n  end\n\n  def receive_headers(headerhandler, headers)\n    headerhandler.on_inbound(headers) if headers\n  end\n\n  def unmarshal(conn_data)\n    opt = {}\n    contenttype = conn_data.receive_contenttype\n    if /#{MIMEMessage::MultipartContentType}/i =~ contenttype\n      opt[:external_content] = {}\n      mime = MIMEMessage.parse(\"Content-Type: \" + contenttype,\n        conn_data.receive_string)\n      mime.parts.each do |part|\n\tvalue = Attachment.new(part.content)\n\tvalue.contentid = part.contentid\n\tobj = SOAPAttachment.new(value)\n\topt[:external_content][value.contentid] = obj if value.contentid\n      end\n      opt[:charset] =\n\tStreamHandler.parse_media_type(mime.root.headers['content-type'].str)\n      env = Processor.unmarshal(mime.root.content, opt)\n    else\n      opt[:charset] = ::SOAP::StreamHandler.parse_media_type(contenttype)\n      env = Processor.unmarshal(conn_data.receive_string, opt)\n    end\n    charset = opt[:charset]\n    conn_data.send_contenttype = \"text/xml; charset=\\\"#{charset}\\\"\"\n    env\n  end\n\n  def marshal(conn_data, env, default_encodingstyle = nil)\n    opt = {}\n    opt[:external_content] = nil\n    opt[:default_encodingstyle] = default_encodingstyle\n    opt[:generate_explicit_type] = @generate_explicit_type\n    response_string = Processor.marshal(env, opt)\n    conn_data.send_string = response_string\n    if ext = opt[:external_content]\n      mimeize(conn_data, ext)\n    end\n    conn_data\n  end\n\n  def mimeize(conn_data, ext)\n    mime = MIMEMessage.new\n    ext.each do |k, v|\n      mime.add_attachment(v.data)\n    end\n    mime.add_part(conn_data.send_string + \"\\r\\n\")\n    mime.close\n    conn_data.send_string = mime.content_str\n    conn_data.send_contenttype = mime.headers['content-type'].str\n    conn_data\n  end\n\n  # Create fault response.\n  def fault(e)\n    detail = Mapping::SOAPException.new(e)\n    SOAPFault.new(\n      SOAPString.new('Server'),\n      SOAPString.new(e.to_s),\n      SOAPString.new(@actor),\n      Mapping.obj2soap(detail, @mapping_registry))\n  end\n\n  def create_mapping_opt\n    { :external_ces => @external_ces }\n  end\n\n  class Operation\n    attr_reader :name\n    attr_reader :soapaction\n    attr_reader :request_style\n    attr_reader :response_style\n    attr_reader :request_use\n    attr_reader :response_use\n\n    def initialize(soapaction, name, param_def, opt)\n      @soapaction = soapaction\n      @name = name\n      @request_style = opt[:request_style]\n      @response_style = opt[:response_style]\n      @request_use = opt[:request_use]\n      @response_use = opt[:response_use]\n      check_style(@request_style)\n      check_style(@response_style)\n      check_use(@request_use)\n      check_use(@response_use)\n      if @response_style == :rpc\n        request_qname = opt[:request_qname] or raise\n        @rpc_method_factory =\n          RPC::SOAPMethodRequest.new(request_qname, param_def, @soapaction)\n        @rpc_response_qname = opt[:response_qname]\n      else\n        @doc_request_qnames = []\n        @doc_request_qualified = []\n        @doc_response_qnames = []\n        @doc_response_qualified = []\n        param_def.each do |inout, paramname, typeinfo, eleinfo|\n          klass, nsdef, namedef = typeinfo\n          qualified = eleinfo\n          case inout\n          when SOAPMethod::IN\n            @doc_request_qnames << XSD::QName.new(nsdef, namedef)\n            @doc_request_qualified << qualified\n          when SOAPMethod::OUT\n            @doc_response_qnames << XSD::QName.new(nsdef, namedef)\n            @doc_response_qualified << qualified\n          else\n            raise ArgumentError.new(\n              \"illegal inout definition for document style: #{inout}\")\n          end\n        end\n      end\n    end\n\n    def request_default_encodingstyle\n      (@request_use == :encoded) ? EncodingNamespace : LiteralNamespace\n    end\n\n    def response_default_encodingstyle\n      (@response_use == :encoded) ? EncodingNamespace : LiteralNamespace\n    end\n\n    def call(body, mapping_registry, literal_mapping_registry, opt)\n      if @request_style == :rpc\n        values = request_rpc(body, mapping_registry, literal_mapping_registry,\n          opt)\n      else\n        values = request_document(body, mapping_registry,\n          literal_mapping_registry, opt)\n      end\n      result = receiver.method(@name.intern).call(*values)\n      return result if result.is_a?(SOAPFault)\n      if @response_style == :rpc\n        response_rpc(result, mapping_registry, literal_mapping_registry, opt)\n      else\n        response_doc(result, mapping_registry, literal_mapping_registry, opt)\n      end\n    end\n\n  private\n\n    def receiver\n      raise NotImplementedError.new('must be defined in derived class')\n    end\n\n    def request_rpc(body, mapping_registry, literal_mapping_registry, opt)\n      request = body.request\n      unless request.is_a?(SOAPStruct)\n        raise RPCRoutingError.new(\"not an RPC style\")\n      end\n      if @request_use == :encoded\n        request_rpc_enc(request, mapping_registry, opt)\n      else\n        request_rpc_lit(request, literal_mapping_registry, opt)\n      end\n    end\n\n    def request_document(body, mapping_registry, literal_mapping_registry, opt)\n      # ToDo: compare names with @doc_request_qnames\n      if @request_use == :encoded\n        request_doc_enc(body, mapping_registry, opt)\n      else\n        request_doc_lit(body, literal_mapping_registry, opt)\n      end\n    end\n\n    def request_rpc_enc(request, mapping_registry, opt)\n      param = Mapping.soap2obj(request, mapping_registry, nil, opt)\n      request.collect { |key, value|\n        param[key]\n      }\n    end\n\n    def request_rpc_lit(request, mapping_registry, opt)\n      request.collect { |key, value|\n        Mapping.soap2obj(value, mapping_registry, nil, opt)\n      }\n    end\n\n    def request_doc_enc(body, mapping_registry, opt)\n      body.collect { |key, value|\n        Mapping.soap2obj(value, mapping_registry, nil, opt)\n      }\n    end\n\n    def request_doc_lit(body, mapping_registry, opt)\n      body.collect { |key, value|\n        Mapping.soap2obj(value, mapping_registry, nil, opt)\n      }\n    end\n\n    def response_rpc(result, mapping_registry, literal_mapping_registry, opt)\n      if @response_use == :encoded\n        response_rpc_enc(result, mapping_registry, opt)\n      else\n        response_rpc_lit(result, literal_mapping_registry, opt)\n      end\n    end\n    \n    def response_doc(result, mapping_registry, literal_mapping_registry, opt)\n      if @doc_response_qnames.size == 1 and !result.is_a?(Array)\n        result = [result]\n      end\n      if result.size != @doc_response_qnames.size\n        raise \"required #{@doc_response_qnames.size} responses \" +\n          \"but #{result.size} given\"\n      end\n      if @response_use == :encoded\n        response_doc_enc(result, mapping_registry, opt)\n      else\n        response_doc_lit(result, literal_mapping_registry, opt)\n      end\n    end\n\n    def response_rpc_enc(result, mapping_registry, opt)\n      soap_response =\n        @rpc_method_factory.create_method_response(@rpc_response_qname)\n      if soap_response.have_outparam?\n        unless result.is_a?(Array)\n          raise RPCRoutingError.new(\"out parameter was not returned\")\n        end\n        outparams = {}\n        i = 1\n        soap_response.output_params.each do |outparam|\n          outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry,\n            nil, opt)\n          i += 1\n        end\n        soap_response.set_outparam(outparams)\n        soap_response.retval = Mapping.obj2soap(result[0], mapping_registry,\n          nil, opt)\n      else\n        soap_response.retval = Mapping.obj2soap(result, mapping_registry, nil,\n          opt)\n      end\n      soap_response\n    end\n\n    def response_rpc_lit(result, mapping_registry, opt)\n      soap_response =\n        @rpc_method_factory.create_method_response(@rpc_response_qname)\n      if soap_response.have_outparam?\n        unless result.is_a?(Array)\n          raise RPCRoutingError.new(\"out parameter was not returned\")\n        end\n        outparams = {}\n        i = 1\n        soap_response.output_params.each do |outparam|\n          outparams[outparam] = Mapping.obj2soap(result[i], mapping_registry,\n            XSD::QName.new(nil, outparam), opt)\n          i += 1\n        end\n        soap_response.set_outparam(outparams)\n        soap_response.retval = Mapping.obj2soap(result[0], mapping_registry,\n          XSD::QName.new(nil, soap_response.elename), opt)\n      else\n        soap_response.retval = Mapping.obj2soap(result, mapping_registry,\n          XSD::QName.new(nil, soap_response.elename), opt)\n      end\n      soap_response\n    end\n\n    def response_doc_enc(result, mapping_registry, opt)\n      (0...result.size).collect { |idx|\n        ele = Mapping.obj2soap(result[idx], mapping_registry, nil, opt)\n        ele.elename = @doc_response_qnames[idx]\n        ele\n      }\n    end\n\n    def response_doc_lit(result, mapping_registry, opt)\n      (0...result.size).collect { |idx|\n        ele = Mapping.obj2soap(result[idx], mapping_registry,\n          @doc_response_qnames[idx])\n        ele.encodingstyle = LiteralNamespace\n        if ele.respond_to?(:qualified)\n          ele.qualified = @doc_response_qualified[idx]\n        end\n        ele\n      }\n    end\n\n    def check_style(style)\n      unless [:rpc, :document].include?(style)\n        raise ArgumentError.new(\"unknown style: #{style}\")\n      end\n    end\n\n    def check_use(use)\n      unless [:encoded, :literal].include?(use)\n        raise ArgumentError.new(\"unknown use: #{use}\")\n      end\n    end\n  end\n\n  class ApplicationScopeOperation < Operation\n    def initialize(soapaction, receiver, name, param_def, opt)\n      super(soapaction, name, param_def, opt)\n      @receiver = receiver\n    end\n\n  private\n\n    def receiver\n      @receiver\n    end\n  end\n\n  class RequestScopeOperation < Operation\n    def initialize(soapaction, receiver_factory, name, param_def, opt)\n      super(soapaction, name, param_def, opt)\n      unless receiver_factory.respond_to?(:create)\n        raise TypeError.new(\"factory must respond to 'create'\")\n      end\n      @receiver_factory = receiver_factory\n    end\n\n  private\n\n    def receiver\n      @receiver_factory.create\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/rpc.rb",
    "content": "# SOAP4R - RPC utility.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule SOAP\n\n\nmodule RPC\n  ServerException = Mapping::MappedException\n\n  def self.defined_methods(obj)\n    if obj.is_a?(Module)\n      obj.methods - Module.methods\n    else\n      obj.methods - Object.instance_methods(true)\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/rpc/soaplet.rb",
    "content": "# SOAP4R - SOAP handler servlet for WEBrick\n# Copyright (C) 2001-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'webrick/httpservlet/abstract'\nrequire 'webrick/httpstatus'\nrequire 'soap/rpc/router'\nrequire 'soap/streamHandler'\nbegin\n  require 'stringio'\n  require 'zlib'\nrescue LoadError\n  warn(\"Loading stringio or zlib failed.  No gzipped response supported.\") if $DEBUG\nend\n\n\nwarn(\"Overriding WEBrick::Log#debug\") if $DEBUG\nrequire 'webrick/log'\nmodule WEBrick\n  class Log < BasicLog\n    alias __debug debug\n    def debug(msg = nil)\n      if block_given? and msg.nil?\n        __debug(yield)\n      else\n        __debug(msg)\n      end\n    end\n  end\nend\n\n\nmodule SOAP\nmodule RPC\n\n\nclass SOAPlet < WEBrick::HTTPServlet::AbstractServlet\npublic\n  attr_reader :options\n\n  def initialize(router = nil)\n    @router = router || ::SOAP::RPC::Router.new(self.class.name)\n    @options = {}\n    @config = {}\n  end\n\n  # for backward compatibility\n  def app_scope_router\n    @router\n  end\n\n  # for backward compatibility\n  def add_servant(obj, namespace)\n    @router.add_rpc_servant(obj, namespace)\n  end\n\n  def allow_content_encoding_gzip=(allow)\n    @options[:allow_content_encoding_gzip] = allow\n  end\n\n  ###\n  ## Servlet interfaces for WEBrick.\n  #\n  def get_instance(config, *options)\n    @config = config\n    self\n  end\n\n  def require_path_info?\n    false\n  end\n\n  def do_GET(req, res)\n    res.header['Allow'] = 'POST'\n    raise WEBrick::HTTPStatus::MethodNotAllowed, \"GET request not allowed\"\n  end\n\n  def do_POST(req, res)\n    logger.debug { \"SOAP request: \" + req.body } if logger\n    begin\n      conn_data = ::SOAP::StreamHandler::ConnectionData.new\n      setup_req(conn_data, req)\n      @router.external_ces = @options[:external_ces]\n      conn_data = @router.route(conn_data)\n      setup_res(conn_data, req, res)\n    rescue Exception => e\n      conn_data = @router.create_fault_response(e)\n      res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR\n      res.body = conn_data.send_string\n      res['content-type'] = conn_data.send_contenttype || \"text/xml\"\n    end\n    if res.body.is_a?(IO)\n      res.chunked = true\n      logger.debug { \"SOAP response: (chunked response not logged)\" } if logger\n    else\n      logger.debug { \"SOAP response: \" + res.body } if logger\n    end\n  end\n\nprivate\n\n  def logger\n    @config[:Logger]\n  end\n\n  def setup_req(conn_data, req)\n    conn_data.receive_string = req.body\n    conn_data.receive_contenttype = req['content-type']\n    conn_data.soapaction = parse_soapaction(req.meta_vars['HTTP_SOAPACTION'])\n  end\n\n  def setup_res(conn_data, req, res)\n    res['content-type'] = conn_data.send_contenttype\n    if conn_data.is_fault\n      res.status = WEBrick::HTTPStatus::RC_INTERNAL_SERVER_ERROR\n    end\n    if outstring = encode_gzip(req, conn_data.send_string)\n      res['content-encoding'] = 'gzip'\n      res['content-length'] = outstring.size\n      res.body = outstring\n    else\n      res.body = conn_data.send_string\n    end\n  end\n\n  def parse_soapaction(soapaction)\n    if !soapaction.nil? and !soapaction.empty?\n      if /^\"(.+)\"$/ =~ soapaction\n        return $1\n      end\n    end\n    nil\n  end\n\n  def encode_gzip(req, outstring)\n    unless encode_gzip?(req)\n      return nil\n    end\n    begin\n      ostream = StringIO.new\n      gz = Zlib::GzipWriter.new(ostream)\n      gz.write(outstring)\n      ostream.string\n    ensure\n      gz.close\n    end\n  end\n\n  def encode_gzip?(req)\n    @options[:allow_content_encoding_gzip] and defined?(::Zlib) and\n      req['accept-encoding'] and\n      req['accept-encoding'].split(/,\\s*/).include?('gzip')\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/rpc/standaloneServer.rb",
    "content": "# SOAP4R - WEBrick Server\n# Copyright (C) 2003 by NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/rpc/httpserver'\n\n\nmodule SOAP\nmodule RPC\n\n\nclass StandaloneServer < HTTPServer\n  def initialize(appname, default_namespace, host = \"0.0.0.0\", port = 8080)\n    @appname = appname\n    @default_namespace = default_namespace\n    @host = host\n    @port = port\n    super(create_config)\n  end\n\n  alias add_servant add_rpc_servant\n  alias add_headerhandler add_rpc_headerhandler\n\nprivate\n\n  def create_config\n    {\n      :BindAddress => @host,\n      :Port => @port,\n      :AccessLog => [],\n      :SOAPDefaultNamespace => @default_namespace,\n      :SOAPHTTPServerApplicationName => @appname,\n    }\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/soap/soap.rb",
    "content": "# soap/soap.rb: SOAP4R - Base definitions.\n# Copyright (C) 2000-2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'xsd/charset'\n\n\nmodule SOAP\n\n\nVERSION = Version = '1.5.5'\nPropertyName = 'soap/property'\n\nEnvelopeNamespace = 'http://schemas.xmlsoap.org/soap/envelope/'\nEncodingNamespace = 'http://schemas.xmlsoap.org/soap/encoding/'\nLiteralNamespace = 'http://xml.apache.org/xml-soap/literalxml'\n\nNextActor = 'http://schemas.xmlsoap.org/soap/actor/next'\n\nEleEnvelope = 'Envelope'\nEleHeader = 'Header'\nEleBody = 'Body'\nEleFault = 'Fault'\nEleFaultString = 'faultstring'\nEleFaultActor = 'faultactor'\nEleFaultCode = 'faultcode'\nEleFaultDetail = 'detail'\n\nAttrMustUnderstand = 'mustUnderstand'\nAttrEncodingStyle = 'encodingStyle'\nAttrActor = 'actor'\nAttrRoot = 'root'\nAttrArrayType = 'arrayType'\nAttrOffset = 'offset'\nAttrPosition = 'position'\nValueArray = 'Array'\n\nEleEnvelopeName = XSD::QName.new(EnvelopeNamespace, EleEnvelope).freeze\nEleHeaderName = XSD::QName.new(EnvelopeNamespace, EleHeader).freeze\nEleBodyName = XSD::QName.new(EnvelopeNamespace, EleBody).freeze\nEleFaultName = XSD::QName.new(EnvelopeNamespace, EleFault).freeze\nEleFaultStringName = XSD::QName.new(nil, EleFaultString).freeze\nEleFaultActorName = XSD::QName.new(nil, EleFaultActor).freeze\nEleFaultCodeName = XSD::QName.new(nil, EleFaultCode).freeze\nEleFaultDetailName = XSD::QName.new(nil, EleFaultDetail).freeze\nAttrMustUnderstandName = XSD::QName.new(EnvelopeNamespace, AttrMustUnderstand).freeze\nAttrEncodingStyleName = XSD::QName.new(EnvelopeNamespace, AttrEncodingStyle).freeze\nAttrRootName = XSD::QName.new(EncodingNamespace, AttrRoot).freeze\nAttrArrayTypeName = XSD::QName.new(EncodingNamespace, AttrArrayType).freeze\nAttrOffsetName = XSD::QName.new(EncodingNamespace, AttrOffset).freeze\nAttrPositionName = XSD::QName.new(EncodingNamespace, AttrPosition).freeze\nValueArrayName = XSD::QName.new(EncodingNamespace, ValueArray).freeze\n\nBase64Literal = 'base64'\n\nSOAPNamespaceTag = 'env'\nXSDNamespaceTag = 'xsd'\nXSINamespaceTag = 'xsi'\n\nMediaType = 'text/xml'\n\nclass Error < StandardError; end\n\nclass StreamError < Error; end\nclass HTTPStreamError < StreamError; end\nclass PostUnavailableError < HTTPStreamError; end\nclass MPostUnavailableError < HTTPStreamError; end\n\nclass ArrayIndexOutOfBoundsError < Error; end\nclass ArrayStoreError < Error; end\n\nclass RPCRoutingError < Error; end\nclass EmptyResponseError < Error; end\nclass ResponseFormatError < Error; end\n\nclass UnhandledMustUnderstandHeaderError < Error; end\n\nclass FaultError < Error\n  attr_reader :faultcode\n  attr_reader :faultstring\n  attr_reader :faultactor\n  attr_accessor :detail\n\n  def initialize(fault)\n    @faultcode = fault.faultcode\n    @faultstring = fault.faultstring\n    @faultactor = fault.faultactor\n    @detail = fault.detail\n    super(self.to_s)\n  end\n\n  def to_s\n    str = nil\n    if @faultstring and @faultstring.respond_to?('data')\n      str = @faultstring.data\n    end\n    str || '(No faultstring)'\n  end\nend\n\n\nmodule Env\n  def self.getenv(name)\n    ENV[name.downcase] || ENV[name.upcase]\n  end\n\n  use_proxy = getenv('soap_use_proxy') == 'on'\n  HTTP_PROXY = use_proxy ? getenv('http_proxy') : nil\n  NO_PROXY = use_proxy ? getenv('no_proxy') : nil\nend\n\n\nend\n\n\nunless Object.respond_to?(:instance_variable_get)\n  class Object\n    def instance_variable_get(ivarname)\n      instance_eval(ivarname)\n    end\n\n    def instance_variable_set(ivarname, value)\n      instance_eval(\"#{ivarname} = value\")\n    end\n  end\nend\n\n\nunless Kernel.respond_to?(:warn)\n  module Kernel\n    def warn(msg)\n      STDERR.puts(msg + \"\\n\") unless $VERBOSE.nil?\n    end\n  end\nend\n"
  },
  {
    "path": "lib/soap/streamHandler.rb",
    "content": "# SOAP4R - Stream handler.\n# Copyright (C) 2000, 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/soap'\nrequire 'soap/httpconfigloader'\nbegin\n  require 'stringio'\n  require 'zlib'\nrescue LoadError\n  warn(\"Loading stringio or zlib failed.  No gzipped response support.\") if $DEBUG\nend\n\n\nmodule SOAP\n\n\nclass StreamHandler\n  RUBY_VERSION_STRING = \"ruby #{ RUBY_VERSION } (#{ RUBY_RELEASE_DATE }) [#{ RUBY_PLATFORM }]\"\n\n  class ConnectionData\n    attr_accessor :send_string\n    attr_accessor :send_contenttype\n    attr_accessor :receive_string\n    attr_accessor :receive_contenttype\n    attr_accessor :is_fault\n    attr_accessor :soapaction\n\n    def initialize(send_string = nil)\n      @send_string = send_string\n      @send_contenttype = nil\n      @receive_string = nil\n      @receive_contenttype = nil\n      @is_fault = false\n      @soapaction = nil\n    end\n  end\n\n  def self.parse_media_type(str)\n    if /^#{ MediaType }(?:\\s*;\\s*charset=([^\"]+|\"[^\"]+\"))?$/i !~ str\n      return nil\n    end\n    charset = $1\n    charset.gsub!(/\"/, '') if charset\n    charset || 'us-ascii'\n  end\n\n  def self.create_media_type(charset)\n    \"#{ MediaType }; charset=#{ charset }\"\n  end\nend\n\n\nclass HTTPStreamHandler < StreamHandler\n  include SOAP\n\n  begin\n    require 'http-access2'\n    if HTTPAccess2::VERSION < \"2.0\"\n      raise LoadError.new(\"http-access/2.0 or later is required.\")\n    end\n    Client = HTTPAccess2::Client\n    RETRYABLE = true\n  rescue LoadError\n    warn(\"Loading http-access2 failed.  Net/http is used.\") if $DEBUG\n    require 'soap/netHttpClient'\n    Client = SOAP::NetHttpClient\n    RETRYABLE = false\n  end\n\n\npublic\n  \n  attr_reader :client\n  attr_accessor :wiredump_file_base\n  \n  MAX_RETRY_COUNT = 10       \t# [times]\n\n  def initialize(options)\n    super()\n    @client = Client.new(nil, \"SOAP4R/#{ Version }\")\n    @wiredump_file_base = nil\n    @charset = @wiredump_dev = nil\n    @options = options\n    set_options\n    @client.debug_dev = @wiredump_dev\n    @cookie_store = nil\n    @accept_encoding_gzip = false\n  end\n\n  def test_loopback_response\n    @client.test_loopback_response\n  end\n\n  def accept_encoding_gzip=(allow)\n    @accept_encoding_gzip = allow\n  end\n\n  def inspect\n    \"#<#{self.class}>\"\n  end\n\n  def send(endpoint_url, conn_data, soapaction = nil, charset = @charset)\n    conn_data.soapaction ||= soapaction # for backward conpatibility\n    send_post(endpoint_url, conn_data, charset)\n  end\n\n  def reset(endpoint_url = nil)\n    if endpoint_url.nil?\n      @client.reset_all\n    else\n      @client.reset(endpoint_url)\n    end\n    @client.save_cookie_store if @cookie_store\n  end\n\nprivate\n\n  def set_options\n    HTTPConfigLoader.set_options(@client, @options)\n    @charset = @options[\"charset\"] || XSD::Charset.xml_encoding_label\n    @options.add_hook(\"charset\") do |key, value|\n      @charset = value\n    end\n    @wiredump_dev = @options[\"wiredump_dev\"]\n    @options.add_hook(\"wiredump_dev\") do |key, value|\n      @wiredump_dev = value\n      @client.debug_dev = @wiredump_dev\n    end\n    set_cookie_store_file(@options[\"cookie_store_file\"])\n    @options.add_hook(\"cookie_store_file\") do |key, value|\n      set_cookie_store_file(value)\n    end\n    ssl_config = @options[\"ssl_config\"]\n    basic_auth = @options[\"basic_auth\"]\n    @options.lock(true)\n    ssl_config.unlock\n    basic_auth.unlock\n  end\n\n  def set_cookie_store_file(value)\n    value = nil if value and value.empty?\n    @cookie_store = value\n    @client.set_cookie_store(@cookie_store) if @cookie_store\n  end\n\n  def send_post(endpoint_url, conn_data, charset)\n    conn_data.send_contenttype ||= StreamHandler.create_media_type(charset)\n\n    if @wiredump_file_base\n      filename = @wiredump_file_base + '_request.xml'\n      f = File.open(filename, \"w\")\n      f << conn_data.send_string\n      f.close\n    end\n\n    extra = {}\n    extra['Content-Type'] = conn_data.send_contenttype\n    extra['SOAPAction'] = \"\\\"#{ conn_data.soapaction }\\\"\"\n    extra['Accept-Encoding'] = 'gzip' if send_accept_encoding_gzip?\n    send_string = conn_data.send_string\n    @wiredump_dev << \"Wire dump:\\n\\n\" if @wiredump_dev\n    begin\n      retry_count = 0\n      while true\n        res = @client.post(endpoint_url, send_string, extra)\n        if RETRYABLE and HTTP::Status.redirect?(res.status)\n          retry_count += 1\n          if retry_count >= MAX_RETRY_COUNT\n            raise HTTPStreamError.new(\"redirect count exceeded\")\n          end\n          endpoint_url = res.header[\"location\"][0]\n          puts \"redirected to #{endpoint_url}\" if $DEBUG\n        else\n          break\n        end\n      end\n    rescue\n      @client.reset(endpoint_url)\n      raise\n    end\n    @wiredump_dev << \"\\n\\n\" if @wiredump_dev\n    receive_string = res.content\n    if @wiredump_file_base\n      filename = @wiredump_file_base + '_response.xml'\n      f = File.open(filename, \"w\")\n      f << receive_string\n      f.close\n    end\n    case res.status\n    when 405\n      raise PostUnavailableError.new(\"#{ res.status }: #{ res.reason }\")\n    when 200, 500\n      # Nothing to do.\n    else\n      raise HTTPStreamError.new(\"#{ res.status }: #{ res.reason }\")\n    end\n    if res.respond_to?(:header) and !res.header['content-encoding'].empty? and\n        res.header['content-encoding'][0].downcase == 'gzip'\n      receive_string = decode_gzip(receive_string)\n    end\n    conn_data.receive_string = receive_string\n    conn_data.receive_contenttype = res.contenttype\n    conn_data\n  end\n\n  def send_accept_encoding_gzip?\n    @accept_encoding_gzip and defined?(::Zlib)\n  end\n\n  def decode_gzip(instring)\n    unless send_accept_encoding_gzip?\n      raise HTTPStreamError.new(\"Gzipped response content.\")\n    end\n    begin\n      gz = Zlib::GzipReader.new(StringIO.new(instring))\n      gz.read\n    ensure\n      gz.close\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/soap/wsdlDriver.rb",
    "content": "# SOAP4R - SOAP WSDL driver\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/parser'\nrequire 'wsdl/importer'\nrequire 'xsd/qname'\nrequire 'xsd/codegen/gensupport'\nrequire 'soap/mapping/wsdlencodedregistry'\nrequire 'soap/mapping/wsdlliteralregistry'\nrequire 'soap/rpc/driver'\nrequire 'wsdl/soap/methodDefCreator'\n\n\nmodule SOAP\n\n\nclass WSDLDriverFactory\n  class FactoryError < StandardError; end\n\n  attr_reader :wsdl\n\n  def initialize(wsdl)\n    @wsdl = import(wsdl)\n    @methoddefcreator = WSDL::SOAP::MethodDefCreator.new(@wsdl)\n  end\n  \n  def inspect\n    \"#<#{self.class}:#{@wsdl.name}>\"\n  end\n\n  def create_rpc_driver(servicename = nil, portname = nil)\n    port = find_port(servicename, portname)\n    drv = SOAP::RPC::Driver.new(port.soap_address.location)\n    init_driver(drv, port)\n    add_operation(drv, port)\n    drv\n  end\n\n  # depricated old interface\n  def create_driver(servicename = nil, portname = nil)\n    warn(\"WSDLDriverFactory#create_driver is depricated.  Use create_rpc_driver instead.\")\n    port = find_port(servicename, portname)\n    WSDLDriver.new(@wsdl, port, nil)\n  end\n\n  # Backward compatibility.\n  alias createDriver create_driver\n\nprivate\n\n  def find_port(servicename = nil, portname = nil)\n    service = port = nil\n    if servicename\n      service = @wsdl.service(\n        XSD::QName.new(@wsdl.targetnamespace, servicename))\n    else\n      service = @wsdl.services[0]\n    end\n    if service.nil?\n      raise FactoryError.new(\"service #{servicename} not found in WSDL\")\n    end\n    if portname\n      port = service.ports[XSD::QName.new(@wsdl.targetnamespace, portname)]\n      if port.nil?\n        raise FactoryError.new(\"port #{portname} not found in WSDL\")\n      end\n    else\n      port = service.ports.find { |port| !port.soap_address.nil? }\n      if port.nil?\n        raise FactoryError.new(\"no ports have soap:address\")\n      end\n    end\n    if port.soap_address.nil?\n      raise FactoryError.new(\"soap:address element not found in WSDL\")\n    end\n    port\n  end\n\n  def init_driver(drv, port)\n    wsdl_elements = @wsdl.collect_elements\n    wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes\n    rpc_decode_typemap = wsdl_types +\n      @wsdl.soap_rpc_complextypes(port.find_binding)\n    drv.proxy.mapping_registry =\n      Mapping::WSDLEncodedRegistry.new(rpc_decode_typemap)\n    drv.proxy.literal_mapping_registry =\n      Mapping::WSDLLiteralRegistry.new(wsdl_types, wsdl_elements)\n  end\n\n  def add_operation(drv, port)\n    port.find_binding.operations.each do |op_bind|\n      op_name = op_bind.soapoperation_name\n      soapaction = op_bind.soapaction || ''\n      orgname = op_name.name\n      name = XSD::CodeGen::GenSupport.safemethodname(orgname)\n      param_def = create_param_def(op_bind)\n      opt = {\n        :request_style => op_bind.soapoperation_style,\n        :response_style => op_bind.soapoperation_style,\n        :request_use => op_bind.input.soapbody_use,\n        :response_use => op_bind.output.soapbody_use,\n        :elementformdefault => false,\n        :attributeformdefault => false\n      }\n      if op_bind.soapoperation_style == :rpc\n        drv.add_rpc_operation(op_name, soapaction, name, param_def, opt)\n      else\n        drv.add_document_operation(soapaction, name, param_def, opt)\n      end\n      if orgname != name and orgname.capitalize == name.capitalize\n        ::SOAP::Mapping.define_singleton_method(drv, orgname) do |*arg|\n          __send__(name, *arg)\n        end\n      end\n    end\n  end\n\n  def import(location)\n    WSDL::Importer.import(location)\n  end\n\n  def create_param_def(op_bind)\n    op = op_bind.find_operation\n    if op_bind.soapoperation_style == :rpc\n      param_def = @methoddefcreator.collect_rpcparameter(op)\n    else\n      param_def = @methoddefcreator.collect_documentparameter(op)\n    end\n    # the first element of typedef in param_def is a String like\n    # \"::SOAP::SOAPStruct\".  turn this String to a class.\n    param_def.collect { |io, name, typedef|\n      typedef[0] = Mapping.class_from_name(typedef[0])\n      [io, name, typedef]\n    }\n  end\n\n  def partqname(part)\n    if part.type\n      part.type\n    else\n      part.element\n    end\n  end\n\n  def param_def(type, name, klass, partqname)\n    [type, name, [klass, partqname.namespace, partqname.name]]\n  end\n\n  def filter_parts(partsdef, partssource)\n    parts = partsdef.split(/\\s+/)\n    partssource.find_all { |part| parts.include?(part.name) }\n  end\nend\n\n\nclass WSDLDriver\n  class << self\n    if RUBY_VERSION >= \"1.7.0\"\n      def __attr_proxy(symbol, assignable = false)\n        name = symbol.to_s\n        define_method(name) {\n          @servant.__send__(name)\n        }\n        if assignable\n          aname = name + '='\n          define_method(aname) { |rhs|\n            @servant.__send__(aname, rhs)\n          }\n        end\n      end\n    else\n      def __attr_proxy(symbol, assignable = false)\n        name = symbol.to_s\n        module_eval <<-EOS\n          def #{name}\n            @servant.#{name}\n          end\n        EOS\n        if assignable\n          module_eval <<-EOS\n            def #{name}=(value)\n              @servant.#{name} = value\n            end\n          EOS\n        end\n      end\n    end\n  end\n\n  __attr_proxy :options\n  __attr_proxy :headerhandler\n  __attr_proxy :streamhandler\n  __attr_proxy :test_loopback_response\n  __attr_proxy :endpoint_url, true\n  __attr_proxy :mapping_registry, true\t\t# for RPC unmarshal\n  __attr_proxy :wsdl_mapping_registry, true\t# for RPC marshal\n  __attr_proxy :default_encodingstyle, true\n  __attr_proxy :generate_explicit_type, true\n  __attr_proxy :allow_unqualified_element, true\n\n  def httpproxy\n    @servant.options[\"protocol.http.proxy\"]\n  end\n\n  def httpproxy=(httpproxy)\n    @servant.options[\"protocol.http.proxy\"] = httpproxy\n  end\n\n  def wiredump_dev\n    @servant.options[\"protocol.http.wiredump_dev\"]\n  end\n\n  def wiredump_dev=(wiredump_dev)\n    @servant.options[\"protocol.http.wiredump_dev\"] = wiredump_dev\n  end\n\n  def mandatorycharset\n    @servant.options[\"protocol.mandatorycharset\"]\n  end\n\n  def mandatorycharset=(mandatorycharset)\n    @servant.options[\"protocol.mandatorycharset\"] = mandatorycharset\n  end\n\n  def wiredump_file_base\n    @servant.options[\"protocol.wiredump_file_base\"]\n  end\n\n  def wiredump_file_base=(wiredump_file_base)\n    @servant.options[\"protocol.wiredump_file_base\"] = wiredump_file_base\n  end\n\n  def initialize(wsdl, port, logdev)\n    @servant = Servant__.new(self, wsdl, port, logdev)\n  end\n\n  def inspect\n    \"#<#{self.class}:#{@servant.port.name}>\"\n  end\n\n  def reset_stream\n    @servant.reset_stream\n  end\n\n  # Backward compatibility.\n  alias generateEncodeType= generate_explicit_type=\n\n  class Servant__\n    include SOAP\n\n    attr_reader :options\n    attr_reader :port\n\n    attr_accessor :soapaction\n    attr_accessor :default_encodingstyle\n    attr_accessor :allow_unqualified_element\n    attr_accessor :generate_explicit_type\n    attr_accessor :mapping_registry\n    attr_accessor :wsdl_mapping_registry\n\n    def initialize(host, wsdl, port, logdev)\n      @host = host\n      @wsdl = wsdl\n      @port = port\n      @logdev = logdev\n      @soapaction = nil\n      @options = setup_options\n      @default_encodingstyle = nil\n      @allow_unqualified_element = nil\n      @generate_explicit_type = false\n      @mapping_registry = nil\t\t# for rpc unmarshal\n      @wsdl_mapping_registry = nil\t# for rpc marshal\n      @wiredump_file_base = nil\n      @mandatorycharset = nil\n      @wsdl_elements = @wsdl.collect_elements\n      @wsdl_types = @wsdl.collect_complextypes + @wsdl.collect_simpletypes\n      @rpc_decode_typemap = @wsdl_types +\n\t@wsdl.soap_rpc_complextypes(port.find_binding)\n      @wsdl_mapping_registry = Mapping::WSDLEncodedRegistry.new(\n        @rpc_decode_typemap)\n      @doc_mapper = Mapping::WSDLLiteralRegistry.new(\n        @wsdl_types, @wsdl_elements)\n      endpoint_url = @port.soap_address.location\n      # Convert a map which key is QName, to a Hash which key is String.\n      @operation = {}\n      @port.inputoperation_map.each do |op_name, op_info|\n        orgname = op_name.name\n        name = XSD::CodeGen::GenSupport.safemethodname(orgname)\n\t@operation[name] = @operation[orgname] = op_info\n\tadd_method_interface(op_info)\n      end\n      @proxy = ::SOAP::RPC::Proxy.new(endpoint_url, @soapaction, @options)\n    end\n\n    def inspect\n      \"#<#{self.class}:#{@proxy.inspect}>\"\n    end\n\n    def endpoint_url\n      @proxy.endpoint_url\n    end\n\n    def endpoint_url=(endpoint_url)\n      @proxy.endpoint_url = endpoint_url\n    end\n\n    def headerhandler\n      @proxy.headerhandler\n    end\n\n    def streamhandler\n      @proxy.streamhandler\n    end\n\n    def test_loopback_response\n      @proxy.test_loopback_response\n    end\n\n    def reset_stream\n      @proxy.reset_stream\n    end\n\n    def rpc_call(name, *values)\n      set_wiredump_file_base(name)\n      unless op_info = @operation[name]\n        raise RuntimeError, \"method: #{name} not defined\"\n      end\n      req_header = create_request_header\n      req_body = create_request_body(op_info, *values)\n      reqopt = create_options({\n        :soapaction => op_info.soapaction || @soapaction})\n      resopt = create_options({\n        :decode_typemap => @rpc_decode_typemap})\n      env = @proxy.route(req_header, req_body, reqopt, resopt)\n      raise EmptyResponseError unless env\n      receive_headers(env.header)\n      begin\n        @proxy.check_fault(env.body)\n      rescue ::SOAP::FaultError => e\n\tMapping.fault2exception(e)\n      end\n      ret = env.body.response ?\n\tMapping.soap2obj(env.body.response, @mapping_registry) : nil\n      if env.body.outparams\n\toutparams = env.body.outparams.collect { |outparam|\n  \t  Mapping.soap2obj(outparam)\n   \t}\n    \treturn [ret].concat(outparams)\n      else\n      \treturn ret\n      end\n    end\n\n    # req_header: [[element, mustunderstand, encodingstyle(QName/String)], ...]\n    # req_body: SOAPBasetype/SOAPCompoundtype\n    def document_send(name, header_obj, body_obj)\n      set_wiredump_file_base(name)\n      unless op_info = @operation[name]\n        raise RuntimeError, \"method: #{name} not defined\"\n      end\n      req_header = header_obj ? header_from_obj(header_obj, op_info) : nil\n      req_body = body_from_obj(body_obj, op_info)\n      opt = create_options({\n        :soapaction => op_info.soapaction || @soapaction,\n        :decode_typemap => @wsdl_types})\n      env = @proxy.invoke(req_header, req_body, opt)\n      raise EmptyResponseError unless env\n      if env.body.fault\n\traise ::SOAP::FaultError.new(env.body.fault)\n      end\n      res_body_obj = env.body.response ?\n\tMapping.soap2obj(env.body.response, @mapping_registry) : nil\n      return env.header, res_body_obj\n    end\n\n  private\n\n    def create_options(hash = nil)\n      opt = {}\n      opt[:default_encodingstyle] = @default_encodingstyle\n      opt[:allow_unqualified_element] = @allow_unqualified_element\n      opt[:generate_explicit_type] = @generate_explicit_type\n      opt.update(hash) if hash\n      opt\n    end\n\n    def set_wiredump_file_base(name)\n      if @wiredump_file_base\n      \t@proxy.set_wiredump_file_base(@wiredump_file_base + \"_#{name}\")\n      end\n    end\n\n    def create_request_header\n      headers = @proxy.headerhandler.on_outbound\n      if headers.empty?\n\tnil\n      else\n\th = SOAPHeader.new\n\theaders.each do |header|\n\t  h.add(header.elename.name, header)\n\tend\n\th\n      end\n    end\n\n    def receive_headers(headers)\n      @proxy.headerhandler.on_inbound(headers) if headers\n    end\n\n    def create_request_body(op_info, *values)\n      method = create_method_struct(op_info, *values)\n      SOAPBody.new(method)\n    end\n\n    def create_method_struct(op_info, *params)\n      parts_names = op_info.bodyparts.collect { |part| part.name }\n      obj = create_method_obj(parts_names, params)\n      method = Mapping.obj2soap(obj, @wsdl_mapping_registry, op_info.op_name)\n      if method.members.size != parts_names.size\n\tnew_method = SOAPStruct.new\n\tmethod.each do |key, value|\n\t  if parts_names.include?(key)\n\t    new_method.add(key, value)\n\t  end\n\tend\n\tmethod = new_method\n      end\n      method.elename = op_info.op_name\n      method.type = XSD::QName.new\t# Request should not be typed.\n      method\n    end\n\n    def create_method_obj(names, params)\n      o = Object.new\n      idx = 0\n      while idx < params.length\n        o.instance_variable_set('@' + names[idx], params[idx])\n        idx += 1\n      end\n      o\n    end\n\n    def header_from_obj(obj, op_info)\n      if obj.is_a?(SOAPHeader)\n\tobj\n      elsif op_info.headerparts.empty?\n\tif obj.nil?\n\t  nil\n\telse\n\t  raise RuntimeError.new(\"no header definition in schema: #{obj}\")\n\tend\n      elsif op_info.headerparts.size == 1\n       \tpart = op_info.headerparts[0]\n\theader = SOAPHeader.new()\n\theader.add(headeritem_from_obj(obj, part.element || part.eletype))\n\theader\n      else\n\theader = SOAPHeader.new()\n\top_info.headerparts.each do |part|\n\t  child = Mapping.get_attribute(obj, part.name)\n\t  ele = headeritem_from_obj(child, part.element || part.eletype)\n\t  header.add(part.name, ele)\n\tend\n\theader\n      end\n    end\n\n    def headeritem_from_obj(obj, name)\n      if obj.nil?\n\tSOAPElement.new(name)\n      elsif obj.is_a?(SOAPHeaderItem)\n\tobj\n      else\n        Mapping.obj2soap(obj, @doc_mapper, name)\n      end\n    end\n\n    def body_from_obj(obj, op_info)\n      if obj.is_a?(SOAPBody)\n\tobj\n      elsif op_info.bodyparts.empty?\n\tif obj.nil?\n\t  nil\n\telse\n\t  raise RuntimeError.new(\"no body found in schema\")\n\tend\n      elsif op_info.bodyparts.size == 1\n       \tpart = op_info.bodyparts[0]\n\tele = bodyitem_from_obj(obj, part.element || part.type)\n\tSOAPBody.new(ele)\n      else\n\tbody = SOAPBody.new\n\top_info.bodyparts.each do |part|\n\t  child = Mapping.get_attribute(obj, part.name)\n\t  ele = bodyitem_from_obj(child, part.element || part.type)\n\t  body.add(ele.elename.name, ele)\n\tend\n\tbody\n      end\n    end\n\n    def bodyitem_from_obj(obj, name)\n      if obj.nil?\n\tSOAPElement.new(name)\n      elsif obj.is_a?(SOAPElement)\n\tobj\n      else\n        Mapping.obj2soap(obj, @doc_mapper, name)\n      end\n    end\n\n    def add_method_interface(op_info)\n      name = XSD::CodeGen::GenSupport.safemethodname(op_info.op_name.name)\n      orgname = op_info.op_name.name\n      parts_names = op_info.bodyparts.collect { |part| part.name }\n      case op_info.style\n      when :document\n        if orgname != name and orgname.capitalize == name.capitalize\n          add_document_method_interface(orgname, parts_names)\n        end\n\tadd_document_method_interface(name, parts_names)\n      when :rpc\n        if orgname != name and orgname.capitalize == name.capitalize\n          add_rpc_method_interface(orgname, parts_names)\n        end\n\tadd_rpc_method_interface(name, parts_names)\n      else\n\traise RuntimeError.new(\"unknown style: #{op_info.style}\")\n      end\n    end\n\n    def add_rpc_method_interface(name, parts_names)\n      ::SOAP::Mapping.define_singleton_method(@host, name) do |*arg|\n        unless arg.size == parts_names.size\n          raise ArgumentError.new(\n            \"wrong number of arguments (#{arg.size} for #{parts_names.size})\")\n        end\n        @servant.rpc_call(name, *arg)\n      end\n      @host.method(name)\n    end\n\n    def add_document_method_interface(name, parts_names)\n      ::SOAP::Mapping.define_singleton_method(@host, name) do |h, b|\n        @servant.document_send(name, h, b)\n      end\n      @host.method(name)\n    end\n\n    def setup_options\n      if opt = Property.loadproperty(::SOAP::PropertyName)\n\topt = opt[\"client\"]\n      end\n      opt ||= Property.new\n      opt.add_hook(\"protocol.mandatorycharset\") do |key, value|\n\t@mandatorycharset = value\n      end\n      opt.add_hook(\"protocol.wiredump_file_base\") do |key, value|\n\t@wiredump_file_base = value\n      end\n      opt[\"protocol.http.charset\"] ||= XSD::Charset.xml_encoding_label\n      opt[\"protocol.http.proxy\"] ||= Env::HTTP_PROXY\n      opt[\"protocol.http.no_proxy\"] ||= Env::NO_PROXY\n      opt\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/sync.rb",
    "content": "#\n#   sync.rb - 2 phase lock with counter\n#   \t$Release Version: 1.0$\n#   \t$Revision$\n#   \t$Date$\n#   \tby Keiju ISHITSUKA(keiju@ishitsuka.com)\n#\n# --\n#  Sync_m, Synchronizer_m\n#  Usage:\n#   obj.extend(Sync_m)\n#   or\n#   class Foo\n#\tinclude Sync_m\n#\t:\n#   end\n#\n#   Sync_m#sync_mode\n#   Sync_m#sync_locked?, locked?\n#   Sync_m#sync_shared?, shared?\n#   Sync_m#sync_exclusive?, sync_exclusive?\n#   Sync_m#sync_try_lock, try_lock\n#   Sync_m#sync_lock, lock\n#   Sync_m#sync_unlock, unlock\n#\n#   Sync, Synchronicer:\n#\tinclude Sync_m\n#   Usage:\n#   sync = Sync.new\n#\n#   Sync#mode\n#   Sync#locked?\n#   Sync#shared?\n#   Sync#exclusive?\n#   Sync#try_lock(mode) -- mode = :EX, :SH, :UN\n#   Sync#lock(mode)     -- mode = :EX, :SH, :UN\n#   Sync#unlock\n#   Sync#synchronize(mode) {...}\n#   \n#\n\nunless defined? Thread\n  fail \"Thread not available for this ruby interpreter\"\nend\n\nmodule Sync_m\n  RCS_ID='-$Header$-'\n  \n  # lock mode\n  UN = :UN\n  SH = :SH\n  EX = :EX\n  \n  # exceptions\n  class Err < StandardError\n    def Err.Fail(*opt)\n      Thread.critical = false\n      fail self, sprintf(self::Message, *opt)\n    end\n    \n    class UnknownLocker < Err\n      Message = \"Thread(%s) not locked.\"\n      def UnknownLocker.Fail(th)\n\tsuper(th.inspect)\n      end\n    end\n    \n    class LockModeFailer < Err\n      Message = \"Unknown lock mode(%s)\"\n      def LockModeFailer.Fail(mode)\n\tif mode.id2name\n\t  mode = id2name\n\tend\n\tsuper(mode)\n      end\n    end\n  end\n  \n  def Sync_m.define_aliases(cl)\n    cl.module_eval %q{\n      alias locked? sync_locked?\n      alias shared? sync_shared?\n      alias exclusive? sync_exclusive?\n      alias lock sync_lock\n      alias unlock sync_unlock\n      alias try_lock sync_try_lock\n      alias synchronize sync_synchronize\n    }\n  end\n  \n  def Sync_m.append_features(cl)\n    super\n    unless cl.instance_of?(Module)\n      # do nothing for Modules\n      # make aliases and include the proper module.\n      define_aliases(cl)\n    end\n  end\n  \n  def Sync_m.extend_object(obj)\n    super\n    obj.sync_extended\n  end\n\n  def sync_extended\n    unless (defined? locked? and\n\t    defined? shared? and\n\t    defined? exclusive? and\n\t    defined? lock and\n\t    defined? unlock and\n\t    defined? try_lock and\n\t    defined? synchronize)\n      Sync_m.define_aliases(class<<self;self;end)\n    end\n    sync_initialize\n  end\n\n  # accessing\n  def sync_locked?\n    sync_mode != UN\n  end\n  \n  def sync_shared?\n    sync_mode == SH\n  end\n  \n  def sync_exclusive?\n    sync_mode == EX\n  end\n  \n  # locking methods.\n  def sync_try_lock(mode = EX)\n    return unlock if mode == UN\n    \n    Thread.critical = true\n    ret = sync_try_lock_sub(mode)\n    Thread.critical = false\n    ret\n  end\n  \n  def sync_lock(m = EX)\n    return unlock if m == UN\n\n    until (Thread.critical = true; sync_try_lock_sub(m))\n      if sync_sh_locker[Thread.current]\n\tsync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]\n\tsync_sh_locker.delete(Thread.current)\n      else\n\tsync_waiting.push Thread.current\n      end\n      Thread.stop\n    end\n    Thread.critical = false\n    self\n  end\n  \n  def sync_unlock(m = EX)\n    Thread.critical = true\n    if sync_mode == UN\n      Thread.critical = false\n      Err::UnknownLocker.Fail(Thread.current)\n    end\n    \n    m = sync_mode if m == EX and sync_mode == SH\n    \n    runnable = false\n    case m\n    when UN\n      Thread.critical = false\n      Err::UnknownLocker.Fail(Thread.current)\n      \n    when EX\n      if sync_ex_locker == Thread.current\n\tif (self.sync_ex_count = sync_ex_count - 1) == 0\n\t  self.sync_ex_locker = nil\n\t  if sync_sh_locker.include?(Thread.current)\n\t    self.sync_mode = SH\n\t  else\n\t    self.sync_mode = UN\n\t  end\n\t  runnable = true\n\tend\n      else\n\tErr::UnknownLocker.Fail(Thread.current)\n      end\n      \n    when SH\n      if (count = sync_sh_locker[Thread.current]).nil?\n\tErr::UnknownLocker.Fail(Thread.current)\n      else\n\tif (sync_sh_locker[Thread.current] = count - 1) == 0 \n\t  sync_sh_locker.delete(Thread.current)\n\t  if sync_sh_locker.empty? and sync_ex_count == 0\n\t    self.sync_mode = UN\n\t    runnable = true\n\t  end\n\tend\n      end\n    end\n    \n    if runnable\n      if sync_upgrade_waiting.size > 0\n\tfor k, v in sync_upgrade_waiting\n\t  sync_sh_locker[k] = v\n\tend\n\twait = sync_upgrade_waiting\n\tself.sync_upgrade_waiting = []\n\tThread.critical = false\n\t\n\tfor w, v in wait\n\t  w.run\n\tend\n      else\n\twait = sync_waiting\n\tself.sync_waiting = []\n\tThread.critical = false\n\tfor w in wait\n\t  w.run\n\tend\n      end\n    end\n    \n    Thread.critical = false\n    self\n  end\n  \n  def sync_synchronize(mode = EX)\n    begin\n      sync_lock(mode)\n      yield\n    ensure\n      sync_unlock\n    end\n  end\n\n  attr :sync_mode, true\n    \n  attr :sync_waiting, true\n  attr :sync_upgrade_waiting, true\n  attr :sync_sh_locker, true\n  attr :sync_ex_locker, true\n  attr :sync_ex_count, true\n    \n  private\n\n  def sync_initialize\n    @sync_mode = UN\n    @sync_waiting = []\n    @sync_upgrade_waiting = []\n    @sync_sh_locker = Hash.new\n    @sync_ex_locker = nil\n    @sync_ex_count = 0\n  end\n\n  def initialize(*args)\n    sync_initialize\n    super\n  end\n    \n  def sync_try_lock_sub(m)\n    case m\n    when SH\n      case sync_mode\n      when UN\n\tself.sync_mode = m\n\tsync_sh_locker[Thread.current] = 1\n\tret = true\n      when SH\n\tcount = 0 unless count = sync_sh_locker[Thread.current]\n\tsync_sh_locker[Thread.current] = count + 1\n\tret = true\n      when EX\n\t# in EX mode, lock will upgrade to EX lock\n\tif sync_ex_locker == Thread.current\n\t  self.sync_ex_count = sync_ex_count + 1\n\t  ret = true\n\telse\n\t  ret = false\n\tend\n      end\n    when EX\n      if sync_mode == UN or\n\tsync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current) \n\tself.sync_mode = m\n\tself.sync_ex_locker = Thread.current\n\tself.sync_ex_count = 1\n\tret = true\n      elsif sync_mode == EX && sync_ex_locker == Thread.current\n\tself.sync_ex_count = sync_ex_count + 1\n\tret = true\n      else\n\tret = false\n      end\n    else\n      Thread.critical = false\n      Err::LockModeFailer.Fail mode\n    end\n    return ret\n  end\nend\nSynchronizer_m = Sync_m\n\nclass Sync\n  #Sync_m.extend_class self\n  include Sync_m\n    \n  def initialize\n    super\n  end\n    \nend\nSynchronizer = Sync\n"
  },
  {
    "path": "lib/tempfile.rb",
    "content": "#\n# tempfile - manipulates temporary files\n#\n# $Id$\n#\n\nrequire 'delegate'\nrequire 'tmpdir'\n\n# A class for managing temporary files.  This library is written to be\n# thread safe.\nclass Tempfile < DelegateClass(File)\n  MAX_TRY = 10\n  @@cleanlist = []\n\n  # Creates a temporary file of mode 0600 in the temporary directory,\n  # opens it with mode \"w+\", and returns a Tempfile object which\n  # represents the created temporary file.  A Tempfile object can be\n  # treated just like a normal File object.\n  #\n  # The basename parameter is used to determine the name of a\n  # temporary file.  If an Array is given, the first element is used\n  # as prefix string and the second as suffix string, respectively.\n  # Otherwise it is treated as prefix string.\n  #\n  # If tmpdir is omitted, the temporary directory is determined by\n  # Dir::tmpdir provided by 'tmpdir.rb'.\n  # When $SAFE > 0 and the given tmpdir is tainted, it uses\n  # /tmp. (Note that ENV values are tainted by default)\n  def initialize(basename, tmpdir=Dir::tmpdir)\n    if $SAFE > 0 and tmpdir.tainted?\n      tmpdir = '/tmp'\n    end\n\n    lock = nil\n    n = failure = 0\n    \n    begin\n      Thread.critical = true\n\n      begin\n\ttmpname = File.join(tmpdir, make_tmpname(basename, n))\n\tlock = tmpname + '.lock'\n\tn += 1\n      end while @@cleanlist.include?(tmpname) or\n\tFile.exist?(lock) or File.exist?(tmpname)\n\n      Dir.mkdir(lock)\n    rescue\n      failure += 1\n      retry if failure < MAX_TRY\n      raise \"cannot generate tempfile `%s'\" % tmpname\n    ensure\n      Thread.critical = false\n    end\n\n    @data = [tmpname]\n    @clean_proc = Tempfile.callback(@data)\n    ObjectSpace.define_finalizer(self, @clean_proc)\n\n    @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)\n    @tmpname = tmpname\n    @@cleanlist << @tmpname\n    @data[1] = @tmpfile\n    @data[2] = @@cleanlist\n\n    super(@tmpfile)\n\n    # Now we have all the File/IO methods defined, you must not\n    # carelessly put bare puts(), etc. after this.\n\n    Dir.rmdir(lock)\n  end\n\n  def make_tmpname(basename, n)\n    case basename\n    when Array\n      prefix, suffix = *basename\n    else\n      prefix, suffix = basename, ''\n    end\n \n    t = Time.now.strftime(\"%Y%m%d\")\n    path = \"#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}-#{n}#{suffix}\"\n  end\n  private :make_tmpname\n\n  # Opens or reopens the file with mode \"r+\".\n  def open\n    @tmpfile.close if @tmpfile\n    @tmpfile = File.open(@tmpname, 'r+')\n    @data[1] = @tmpfile\n    __setobj__(@tmpfile)\n  end\n\n  def _close\t# :nodoc:\n    @tmpfile.close if @tmpfile\n    @tmpfile = nil\n    @data[1] = nil if @data\n  end    \n  protected :_close\n\n  # Closes the file.  If the optional flag is true, unlinks the file\n  # after closing.\n  #\n  # If you don't explicitly unlink the temporary file, the removal\n  # will be delayed until the object is finalized.\n  def close(unlink_now=false)\n    if unlink_now\n      close!\n    else\n      _close\n    end\n  end\n\n  # Closes and unlinks the file.\n  def close!\n    _close\n    @clean_proc.call\n    ObjectSpace.undefine_finalizer(self)\n    @data = @tmpname = nil\n  end\n\n  # Unlinks the file.  On UNIX-like systems, it is often a good idea\n  # to unlink a temporary file immediately after creating and opening\n  # it, because it leaves other programs zero chance to access the\n  # file.\n  def unlink\n    # keep this order for thread safeness\n    begin\n      File.unlink(@tmpname) if File.exist?(@tmpname)\n      @@cleanlist.delete(@tmpname)\n      @data = @tmpname = nil\n      ObjectSpace.undefine_finalizer(self)\n    rescue Errno::EACCES\n      # may not be able to unlink on Windows; just ignore\n    end\n  end\n  alias delete unlink\n\n  # Returns the full path name of the temporary file.\n  def path\n    @tmpname\n  end\n\n  # Returns the size of the temporary file.  As a side effect, the IO\n  # buffer is flushed before determining the size.\n  def size\n    if @tmpfile\n      @tmpfile.flush\n      @tmpfile.stat.size\n    else\n      0\n    end\n  end\n  alias length size\n\n  class << self\n    def callback(data)\t# :nodoc:\n      pid = $$\n      lambda{\n\tif pid == $$ \n\t  path, tmpfile, cleanlist = *data\n\n\t  print \"removing \", path, \"...\" if $DEBUG\n\n\t  tmpfile.close if tmpfile\n\n\t  # keep this order for thread safeness\n\t  File.unlink(path) if File.exist?(path)\n\t  cleanlist.delete(path) if cleanlist\n\n\t  print \"done\\n\" if $DEBUG\n\tend\n      }\n    end\n\n    # If no block is given, this is a synonym for new().\n    #\n    # If a block is given, it will be passed tempfile as an argument,\n    # and the tempfile will automatically be closed when the block\n    # terminates.  In this case, open() returns nil.\n    def open(*args)\n      tempfile = new(*args)\n\n      if block_given?\n\tbegin\n\t  yield(tempfile)\n\tensure\n\t  tempfile.close\n\tend\n\n\tnil\n      else\n\ttempfile\n      end\n    end\n  end\nend\n\nif __FILE__ == $0\n#  $DEBUG = true\n  f = Tempfile.new(\"foo\")\n  f.print(\"foo\\n\")\n  f.close\n  f.open\n  p f.gets # => \"foo\\n\"\n  f.close!\nend\n"
  },
  {
    "path": "lib/test/unit/assertionfailederror.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nmodule Test\n  module Unit\n\n    # Thrown by Test::Unit::Assertions when an assertion fails.\n    class AssertionFailedError < StandardError\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/assertions.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/assertionfailederror'\nrequire 'test/unit/util/backtracefilter'\n\nmodule Test\n  module Unit\n\n    ##\n    # Test::Unit::Assertions contains the standard Test::Unit assertions.\n    # Assertions is included in Test::Unit::TestCase.\n    #\n    # To include it in your own code and use its functionality, you simply\n    # need to rescue Test::Unit::AssertionFailedError. Additionally you may\n    # override add_assertion to get notified whenever an assertion is made.\n    #\n    # Notes:\n    # * The message to each assertion, if given, will be propagated with the\n    #   failure.\n    # * It is easy to add your own assertions based on assert_block().\n    #\n    # = Example Custom Assertion\n    #\n    #   def deny(boolean, message = nil)\n    #     message = build_message message, '<?> is not false or nil.', boolean\n    #     assert_block message do\n    #       not boolean\n    #     end\n    #   end\n\n    module Assertions\n\n      ##\n      # The assertion upon which all other assertions are based. Passes if the\n      # block yields true.\n      #\n      # Example:\n      #   assert_block \"Couldn't do the thing\" do\n      #     do_the_thing\n      #   end\n\n      public\n      def assert_block(message=\"assert_block failed.\") # :yields: \n        _wrap_assertion do\n          if (! yield)\n            raise AssertionFailedError.new(message.to_s)\n          end\n        end\n      end\n\n      ##\n      # Asserts that +boolean+ is not false or nil.\n      #\n      # Example:\n      #   assert [1, 2].include?(5)\n\n      public\n      def assert(boolean, message=nil)\n        _wrap_assertion do\n          assert_block(\"assert should not be called with a block.\") { !block_given? }\n          assert_block(build_message(message, \"<?> is not true.\", boolean)) { boolean }\n        end\n      end\n\n      ##\n      # Passes if +expected+ == +actual.\n      #\n      # Note that the ordering of arguments is important, since a helpful\n      # error message is generated when this one fails that tells you the\n      # values of expected and actual.\n      #\n      # Example:\n      #   assert_equal 'MY STRING', 'my string'.upcase\n\n      public\n      def assert_equal(expected, actual, message=nil)\n        full_message = build_message(message, <<EOT, expected, actual)\n<?> expected but was\n<?>.\nEOT\n        assert_block(full_message) { expected == actual }\n      end\n\n      private\n      def _check_exception_class(args) # :nodoc:\n        args.partition do |klass|\n          next if klass.instance_of?(Module)\n          assert(Exception >= klass, \"Should expect a class of exception, #{klass}\")\n          true\n        end\n      end\n\n      private\n      def _expected_exception?(actual_exception, exceptions, modules) # :nodoc:\n        exceptions.include?(actual_exception.class) or\n          modules.any? {|mod| actual_exception.is_a?(mod)}\n      end\n\n      ##\n      # Passes if the block raises one of the given exceptions.\n      #\n      # Example:\n      #   assert_raise RuntimeError, LoadError do\n      #     raise 'Boom!!!'\n      #   end\n\n      public\n      def assert_raise(*args)\n        _wrap_assertion do\n          if Module === args.last\n            message = \"\"\n          else\n            message = args.pop\n          end\n          exceptions, modules = _check_exception_class(args)\n          expected = args.size == 1 ? args.first : args\n          actual_exception = nil\n          full_message = build_message(message, \"<?> exception expected but none was thrown.\", expected)\n          assert_block(full_message) do\n            begin\n              yield\n            rescue Exception => actual_exception\n              break\n            end\n            false\n          end\n          full_message = build_message(message, \"<?> exception expected but was\\n?\", expected, actual_exception)\n          assert_block(full_message) {_expected_exception?(actual_exception, exceptions, modules)}\n          actual_exception\n        end\n      end\n\n      ##\n      # Alias of assert_raise.\n      #\n      # Will be deprecated in 1.9, and removed in 2.0.\n\n      public\n      def assert_raises(*args, &block)\n        assert_raise(*args, &block)\n      end\n\n      ##\n      # Passes if +object+ .instance_of? +klass+\n      #\n      # Example:\n      #   assert_instance_of String, 'foo'\n\n      public\n      def assert_instance_of(klass, object, message=\"\")\n        _wrap_assertion do\n          assert_equal(Class, klass.class, \"assert_instance_of takes a Class as its first argument\")\n          full_message = build_message(message, <<EOT, object, klass, object.class)\n<?> expected to be an instance of\n<?> but was\n<?>.\nEOT\n          assert_block(full_message){object.instance_of?(klass)}\n        end\n      end\n\n      ##\n      # Passes if +object+ is nil.\n      #\n      # Example:\n      #   assert_nil [1, 2].uniq!\n\n      public\n      def assert_nil(object, message=\"\")\n        assert_equal(nil, object, message)\n      end\n\n      ##\n      # Passes if +object+ .kind_of? +klass+\n      #\n      # Example:\n      #   assert_kind_of Object, 'foo'\n\n      public\n      def assert_kind_of(klass, object, message=\"\")\n        _wrap_assertion do\n          assert(klass.kind_of?(Module), \"The first parameter to assert_kind_of should be a kind_of Module.\")\n          full_message = build_message(message, \"<?>\\nexpected to be kind_of\\\\?\\n<?> but was\\n<?>.\", object, klass, object.class)\n          assert_block(full_message){object.kind_of?(klass)}\n        end\n      end\n\n      ##\n      # Passes if +object+ .respond_to? +method+\n      #\n      # Example:\n      #   assert_respond_to 'bugbear', :slice\n\n      public\n      def assert_respond_to(object, method, message=\"\")\n        _wrap_assertion do\n          full_message = build_message(nil, \"<?>\\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to\\\\?(:to_str).\", method)\n\n          assert_block(full_message) do\n            method.kind_of?(Symbol) || method.respond_to?(:to_str)\n          end\n          full_message = build_message(message, <<EOT, object, object.class, method)\n<?>\nof type <?>\nexpected to respond_to\\\\?<?>.\nEOT\n          assert_block(full_message) { object.respond_to?(method) }\n        end\n      end\n\n      ##\n      # Passes if +string+ =~ +pattern+.\n      #\n      # Example:\n      #   assert_match(/\\d+/, 'five, 6, seven')\n\n      public\n      def assert_match(pattern, string, message=\"\")\n        _wrap_assertion do\n          pattern = case(pattern)\n            when String\n              Regexp.new(Regexp.escape(pattern))\n            else\n              pattern\n          end\n          full_message = build_message(message, \"<?> expected to be =~\\n<?>.\", string, pattern)\n          assert_block(full_message) { string =~ pattern }\n        end\n      end\n\n      ##\n      # Passes if +actual+ .equal? +expected+ (i.e. they are the same\n      # instance).\n      #\n      # Example:\n      #   o = Object.new\n      #   assert_same o, o\n\n      public\n      def assert_same(expected, actual, message=\"\")\n        full_message = build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__)\n<?>\nwith id <?> expected to be equal\\\\? to\n<?>\nwith id <?>.\nEOT\n        assert_block(full_message) { actual.equal?(expected) }\n      end\n\n      ##\n      # Compares the +object1+ with +object2+ using +operator+.\n      #\n      # Passes if object1.__send__(operator, object2) is true.\n      #\n      # Example:\n      #   assert_operator 5, :>=, 4\n\n      public\n      def assert_operator(object1, operator, object2, message=\"\")\n        _wrap_assertion do\n          full_message = build_message(nil, \"<?>\\ngiven as the operator for #assert_operator must be a Symbol or #respond_to\\\\?(:to_str).\", operator)\n          assert_block(full_message){operator.kind_of?(Symbol) || operator.respond_to?(:to_str)}\n          full_message = build_message(message, <<EOT, object1, AssertionMessage.literal(operator), object2)\n<?> expected to be\n?\n<?>.\nEOT\n          assert_block(full_message) { object1.__send__(operator, object2) }\n        end\n      end\n\n      ##\n      # Passes if block does not raise an exception.\n      #\n      # Example:\n      #   assert_nothing_raised do\n      #     [1, 2].uniq\n      #   end\n\n      public\n      def assert_nothing_raised(*args)\n        _wrap_assertion do\n          if Module === args.last\n            message = \"\"\n          else\n            message = args.pop\n          end\n          exceptions, modules = _check_exception_class(args)\n          begin\n            yield\n          rescue Exception => e\n            if ((args.empty? && !e.instance_of?(AssertionFailedError)) ||\n                _expected_exception?(e, exceptions, modules))\n              assert_block(build_message(message, \"Exception raised:\\n?\", e)){false}\n            else\n              raise\n            end\n          end\n          nil\n        end\n      end\n\n      ##\n      # Flunk always fails.\n      #\n      # Example:\n      #   flunk 'Not done testing yet.'\n\n      public\n      def flunk(message=\"Flunked\")\n        assert_block(build_message(message)){false}\n      end\n\n      ##\n      # Passes if ! +actual+ .equal? +expected+\n      #\n      # Example:\n      #   assert_not_same Object.new, Object.new\n\n      public\n      def assert_not_same(expected, actual, message=\"\")\n        full_message = build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__)\n<?>\nwith id <?> expected to not be equal\\\\? to\n<?>\nwith id <?>.\nEOT\n        assert_block(full_message) { !actual.equal?(expected) }\n      end\n\n      ##\n      # Passes if +expected+ != +actual+\n      #\n      # Example:\n      #   assert_not_equal 'some string', 5\n\n      public\n      def assert_not_equal(expected, actual, message=\"\")\n        full_message = build_message(message, \"<?> expected to be != to\\n<?>.\", expected, actual)\n        assert_block(full_message) { expected != actual }\n      end\n\n      ##\n      # Passes if ! +object+ .nil?\n      #\n      # Example:\n      #   assert_not_nil '1 two 3'.sub!(/two/, '2')\n\n      public\n      def assert_not_nil(object, message=\"\")\n        full_message = build_message(message, \"<?> expected to not be nil.\", object)\n        assert_block(full_message){!object.nil?}\n      end\n\n      ##\n      # Passes if +regexp+ !~ +string+ \n      #\n      # Example:\n      #   assert_no_match(/two/, 'one 2 three')\n\n      public\n      def assert_no_match(regexp, string, message=\"\")\n        _wrap_assertion do\n          assert_instance_of(Regexp, regexp, \"The first argument to assert_no_match should be a Regexp.\")\n          full_message = build_message(message, \"<?> expected to not match\\n<?>.\", regexp, string)\n          assert_block(full_message) { regexp !~ string }\n        end\n      end\n\n      UncaughtThrow = {NameError => /^uncaught throw \\`(.+)\\'$/,\n                       ThreadError => /^uncaught throw \\`(.+)\\' in thread /} #`\n\n      ##\n      # Passes if the block throws +expected_symbol+\n      #\n      # Example:\n      #   assert_throws :done do\n      #     throw :done\n      #   end\n\n      public\n      def assert_throws(expected_symbol, message=\"\", &proc)\n        _wrap_assertion do\n          assert_instance_of(Symbol, expected_symbol, \"assert_throws expects the symbol that should be thrown for its first argument\")\n          assert_block(\"Should have passed a block to assert_throws.\"){block_given?}\n          caught = true\n          begin\n            catch(expected_symbol) do\n              proc.call\n              caught = false\n            end\n            full_message = build_message(message, \"<?> should have been thrown.\", expected_symbol)\n            assert_block(full_message){caught}\n          rescue NameError, ThreadError => error\n            if UncaughtThrow[error.class] !~ error.message\n              raise error\n            end\n            full_message = build_message(message, \"<?> expected to be thrown but\\n<?> was thrown.\", expected_symbol, $1.intern)\n            flunk(full_message)\n          end\n        end\n      end\n\n      ##\n      # Passes if block does not throw anything.\n      #\n      # Example:\n      #  assert_nothing_thrown do\n      #    [1, 2].uniq\n      #  end\n\n      public\n      def assert_nothing_thrown(message=\"\", &proc)\n        _wrap_assertion do\n          assert(block_given?, \"Should have passed a block to assert_nothing_thrown\")\n          begin\n            proc.call\n          rescue NameError, ThreadError => error\n            if UncaughtThrow[error.class] !~ error.message\n              raise error\n            end\n            full_message = build_message(message, \"<?> was thrown when nothing was expected\", $1.intern)\n            flunk(full_message)\n          end\n          assert(true, \"Expected nothing to be thrown\")\n        end\n      end\n\n      ##\n      # Passes if +expected_float+ and +actual_float+ are equal\n      # within +delta+ tolerance.\n      #\n      # Example:\n      #   assert_in_delta 0.05, (50000.0 / 10**6), 0.00001\n\n      public\n      def assert_in_delta(expected_float, actual_float, delta, message=\"\")\n        _wrap_assertion do\n          {expected_float => \"first float\", actual_float => \"second float\", delta => \"delta\"}.each do |float, name|\n            assert_respond_to(float, :to_f, \"The arguments must respond to to_f; the #{name} did not\")\n          end\n          assert_operator(delta, :>=, 0.0, \"The delta should not be negative\")\n          full_message = build_message(message, <<EOT, expected_float, actual_float, delta)\n<?> and\n<?> expected to be within\n<?> of each other.\nEOT\n          assert_block(full_message) { (expected_float.to_f - actual_float.to_f).abs <= delta.to_f }\n        end\n      end\n\n      ##\n      # Passes if the method send returns a true value.\n      #\n      # +send_array+ is composed of:\n      # * A receiver\n      # * A method\n      # * Arguments to the method\n      #\n      # Example:\n      #   assert_send [[1, 2], :include?, 4]\n\n      public\n      def assert_send(send_array, message=\"\")\n        _wrap_assertion do\n          assert_instance_of(Array, send_array, \"assert_send requires an array of send information\")\n          assert(send_array.size >= 2, \"assert_send requires at least a receiver and a message name\")\n          full_message = build_message(message, <<EOT, send_array[0], AssertionMessage.literal(send_array[1].to_s), send_array[2..-1])\n<?> expected to respond to\n<?(?)> with a true value.\nEOT\n          assert_block(full_message) { send_array[0].__send__(send_array[1], *send_array[2..-1]) }\n        end\n      end\n\n      ##\n      # Builds a failure message.  +head+ is added before the +template+ and\n      # +arguments+ replaces the '?'s positionally in the template.\n\n      public\n      def build_message(head, template=nil, *arguments)\n        template &&= template.chomp\n        return AssertionMessage.new(head, template, arguments)\n      end\n\n      private\n      def _wrap_assertion\n        @_assertion_wrapped ||= false\n        unless (@_assertion_wrapped)\n          @_assertion_wrapped = true\n          begin\n            add_assertion\n            return yield\n          ensure\n            @_assertion_wrapped = false\n          end\n        else\n          return yield\n        end\n      end\n      \n      ##\n      # Called whenever an assertion is made.  Define this in classes that\n      # include Test::Unit::Assertions to record assertion counts.\n\n      private\n      def add_assertion\n      end\n\n      ##\n      # Select whether or not to use the pretty-printer. If this option is set\n      # to false before any assertions are made, pp.rb will not be required.\n\n      public\n      def self.use_pp=(value)\n        AssertionMessage.use_pp = value\n      end\n      \n      # :stopdoc:\n\n      class AssertionMessage\n        @use_pp = true\n        class << self\n          attr_accessor :use_pp\n        end\n\n        class Literal\n          def initialize(value)\n            @value = value\n          end\n          \n          def inspect\n            @value.to_s\n          end\n        end\n\n        class Template\n          def self.create(string)\n            parts = (string ? string.scan(/(?=[^\\\\])\\?|(?:\\\\\\?|[^\\?])+/m) : [])\n            self.new(parts)\n          end\n\n          attr_reader :count\n\n          def initialize(parts)\n            @parts = parts\n            @count = parts.find_all{|e| e == '?'}.size\n          end\n\n          def result(parameters)\n            raise \"The number of parameters does not match the number of substitutions.\" if(parameters.size != count)\n            params = parameters.dup\n            @parts.collect{|e| e == '?' ? params.shift : e.gsub(/\\\\\\?/m, '?')}.join('')\n          end\n        end\n\n        def self.literal(value)\n          Literal.new(value)\n        end\n\n        include Util::BacktraceFilter\n\n        def initialize(head, template_string, parameters)\n          @head = head\n          @template_string = template_string\n          @parameters = parameters\n        end\n\n        def convert(object)\n          case object\n            when Exception\n              <<EOM.chop\nClass: <#{convert(object.class)}>\nMessage: <#{convert(object.message)}>\n---Backtrace---\n#{filter_backtrace(object.backtrace).join(\"\\n\")}\n---------------\nEOM\n            else\n              if(self.class.use_pp)\n                begin\n                  require 'pp'\n                rescue LoadError\n                  self.class.use_pp = false\n                  return object.inspect\n                end unless(defined?(PP))\n                PP.pp(object, '').chomp\n              else\n                object.inspect\n              end\n          end\n        end\n\n        def template\n          @template ||= Template.create(@template_string)\n        end\n\n        def add_period(string)\n          (string =~ /\\.\\Z/ ? string : string + '.')\n        end\n\n        def to_s\n          message_parts = []\n          if (@head)\n            head = @head.to_s \n            unless(head.empty?)\n              message_parts << add_period(head)\n            end\n          end\n          tail = template.result(@parameters.collect{|e| convert(e)})\n          message_parts << tail unless(tail.empty?)\n          message_parts.join(\"\\n\")\n        end\n      end\n\n      # :startdoc:\n\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/autorunner.rb",
    "content": "require 'test/unit'\nrequire 'test/unit/ui/testrunnerutilities'\nrequire 'optparse'\n\nmodule Test\n  module Unit\n    class AutoRunner\n      def self.run(force_standalone=false, default_dir=nil, argv=ARGV, &block)\n        r = new(force_standalone || standalone?, &block)\n        r.base = default_dir\n        r.process_args(argv)\n        r.run\n      end\n      \n      def self.standalone?\n        return false unless(\"-e\" == $0)\n        ObjectSpace.each_object(Class) do |klass|\n          return false if(klass < TestCase)\n        end\n        true\n      end\n\n      RUNNERS = {\n        :console => proc do |r|\n          require 'test/unit/ui/console/testrunner'\n          Test::Unit::UI::Console::TestRunner\n        end,\n        :gtk => proc do |r|\n          require 'test/unit/ui/gtk/testrunner'\n          Test::Unit::UI::GTK::TestRunner\n        end,\n        :gtk2 => proc do |r|\n          require 'test/unit/ui/gtk2/testrunner'\n          Test::Unit::UI::GTK2::TestRunner\n        end,\n        :fox => proc do |r|\n          require 'test/unit/ui/fox/testrunner'\n          Test::Unit::UI::Fox::TestRunner\n        end,\n        :tk => proc do |r|\n          require 'test/unit/ui/tk/testrunner'\n          Test::Unit::UI::Tk::TestRunner\n        end,\n      }\n\n      OUTPUT_LEVELS = [\n        [:silent, UI::SILENT],\n        [:progress, UI::PROGRESS_ONLY],\n        [:normal, UI::NORMAL],\n        [:verbose, UI::VERBOSE],\n      ]\n\n      COLLECTORS = {\n        :objectspace => proc do |r|\n          require 'test/unit/collector/objectspace'\n          c = Collector::ObjectSpace.new\n          c.filter = r.filters\n          c.collect($0.sub(/\\.rb\\Z/, ''))\n        end,\n        :dir => proc do |r|\n          require 'test/unit/collector/dir'\n          c = Collector::Dir.new\n          c.filter = r.filters\n          c.pattern.concat(r.pattern) if(r.pattern)\n          c.exclude.concat(r.exclude) if(r.exclude)\n          c.base = r.base\n          $:.push(r.base) if r.base\n          c.collect(*(r.to_run.empty? ? ['.'] : r.to_run))\n        end,\n      }\n\n      attr_reader :suite\n      attr_accessor :output_level, :filters, :to_run, :pattern, :exclude, :base, :workdir\n      attr_writer :runner, :collector\n\n      def initialize(standalone)\n        Unit.run = true\n        @standalone = standalone\n        @runner = RUNNERS[:console]\n        @collector = COLLECTORS[(standalone ? :dir : :objectspace)]\n        @filters = []\n        @to_run = []\n        @output_level = UI::NORMAL\n        @workdir = nil\n        yield(self) if(block_given?)\n      end\n\n      def process_args(args = ARGV)\n        begin\n          options.order!(args) {|arg| @to_run << arg}\n        rescue OptionParser::ParseError => e\n          puts e\n          puts options\n          $! = nil\n          abort\n        else\n          @filters << proc{false} unless(@filters.empty?)\n        end\n        not @to_run.empty?\n      end\n\n      def options\n        @options ||= OptionParser.new do |o|\n          o.banner = \"Test::Unit automatic runner.\"\n          o.banner << \"\\nUsage: #{$0} [options] [-- untouched arguments]\"\n\n          o.on\n          o.on('-r', '--runner=RUNNER', RUNNERS,\n               \"Use the given RUNNER.\",\n               \"(\" + keyword_display(RUNNERS) + \")\") do |r|\n            @runner = r\n          end\n\n          if(@standalone)\n            o.on('-b', '--basedir=DIR', \"Base directory of test suites.\") do |b|\n              @base = b\n            end\n\n            o.on('-w', '--workdir=DIR', \"Working directory to run tests.\") do |w|\n              @workdir = w\n            end\n\n            o.on('-a', '--add=TORUN', Array,\n                 \"Add TORUN to the list of things to run;\",\n                 \"can be a file or a directory.\") do |a|\n              @to_run.concat(a)\n            end\n\n            @pattern = []\n            o.on('-p', '--pattern=PATTERN', Regexp,\n                 \"Match files to collect against PATTERN.\") do |e|\n              @pattern << e\n            end\n\n            @exclude = []\n            o.on('-x', '--exclude=PATTERN', Regexp,\n                 \"Ignore files to collect against PATTERN.\") do |e|\n              @exclude << e\n            end\n          end\n\n          o.on('-n', '--name=NAME', String,\n               \"Runs tests matching NAME.\",\n               \"(patterns may be used).\") do |n|\n            n = (%r{\\A/(.*)/\\Z} =~ n ? Regexp.new($1) : n)\n            case n\n            when Regexp\n              @filters << proc{|t| n =~ t.method_name ? true : nil}\n            else\n              @filters << proc{|t| n == t.method_name ? true : nil}\n            end\n          end\n\n          o.on('-t', '--testcase=TESTCASE', String,\n               \"Runs tests in TestCases matching TESTCASE.\",\n               \"(patterns may be used).\") do |n|\n            n = (%r{\\A/(.*)/\\Z} =~ n ? Regexp.new($1) : n)\n            case n\n            when Regexp\n              @filters << proc{|t| n =~ t.class.name ? true : nil}\n            else\n              @filters << proc{|t| n == t.class.name ? true : nil}\n            end\n          end\n\n          o.on('-I', \"--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]\",\n               \"Appends directory list to $LOAD_PATH.\") do |dirs|\n            $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR))\n          end\n\n          o.on('-v', '--verbose=[LEVEL]', OUTPUT_LEVELS,\n               \"Set the output level (default is verbose).\",\n               \"(\" + keyword_display(OUTPUT_LEVELS) + \")\") do |l|\n            @output_level = l || UI::VERBOSE\n          end\n\n          o.on('--',\n               \"Stop processing options so that the\",\n               \"remaining options will be passed to the\",\n               \"test.\"){o.terminate}\n\n          o.on('-h', '--help', 'Display this help.'){puts o; exit}\n\n          o.on_tail\n          o.on_tail('Deprecated options:')\n\n          o.on_tail('--console', 'Console runner (use --runner).') do\n            warn(\"Deprecated option (--console).\")\n            @runner = RUNNERS[:console]\n          end\n\n          o.on_tail('--gtk', 'GTK runner (use --runner).') do\n            warn(\"Deprecated option (--gtk).\")\n            @runner = RUNNERS[:gtk]\n          end\n\n          o.on_tail('--fox', 'Fox runner (use --runner).') do\n            warn(\"Deprecated option (--fox).\")\n            @runner = RUNNERS[:fox]\n          end\n\n          o.on_tail\n        end\n      end\n\n      def keyword_display(array)\n        list = array.collect {|e, *| e.to_s}\n        Array === array or list.sort!\n        list.collect {|e| e.sub(/^(.)([A-Za-z]+)(?=\\w*$)/, '\\\\1[\\\\2]')}.join(\", \")\n      end\n\n      def run\n        @suite = @collector[self]\n        result = @runner[self] or return false\n        Dir.chdir(@workdir) if @workdir\n        result.run(@suite, @output_level).passed?\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/collector/dir.rb",
    "content": "require 'test/unit/testsuite'\nrequire 'test/unit/collector'\n\nmodule Test\n  module Unit\n    module Collector\n      class Dir\n        include Collector\n\n        attr_reader :pattern, :exclude\n        attr_accessor :base\n\n        def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil)\n          super()\n          @dir = dir\n          @file = file\n          @object_space = object_space\n          @req = req\n          @pattern = [/\\btest_.*\\.rb\\Z/m]\n          @exclude = []\n        end\n\n        def collect(*from)\n          basedir = @base\n          $:.push(basedir) if basedir\n          if(from.empty?)\n            recursive_collect('.', find_test_cases)\n          elsif(from.size == 1)\n            recursive_collect(from.first, find_test_cases)\n          else\n            suites = []\n            from.each do |f|\n              suite = recursive_collect(f, find_test_cases)\n              suites << suite unless(suite.tests.empty?)\n            end\n            suite = TestSuite.new(\"[#{from.join(', ')}]\")\n            sort(suites).each{|s| suite << s}\n            suite\n          end\n        ensure\n          $:.delete_at($:.rindex(basedir)) if basedir\n        end\n\n        def find_test_cases(ignore=[])\n          cases = []\n          @object_space.each_object(Class) do |c|\n            cases << c if(c < TestCase && !ignore.include?(c))\n          end\n          ignore.concat(cases)\n          cases\n        end\n\n        def recursive_collect(name, already_gathered)\n          sub_suites = []\n          path = realdir(name)\n          if @file.directory?(path)\n\t    dir_name = name unless name == '.'\n            @dir.entries(path).each do |e|\n              next if(e == '.' || e == '..')\n              e_name = dir_name ? @file.join(dir_name, e) : e\n              if @file.directory?(realdir(e_name))\n                next if /\\ACVS\\z/ =~ e\n                sub_suite = recursive_collect(e_name, already_gathered)\n                sub_suites << sub_suite unless(sub_suite.empty?)\n              else\n                next if /~\\z/ =~ e_name or /\\A\\.\\#/ =~ e\n                if @pattern and !@pattern.empty?\n                  next unless @pattern.any? {|pat| pat =~ e_name}\n                end\n                if @exclude and !@exclude.empty?\n                  next if @exclude.any? {|pat| pat =~ e_name}\n                end\n                collect_file(e_name, sub_suites, already_gathered)\n              end\n            end\n          else\n            collect_file(name, sub_suites, already_gathered)\n          end\n          suite = TestSuite.new(@file.basename(name))\n          sort(sub_suites).each{|s| suite << s}\n          suite\n        end\n\n        def collect_file(name, suites, already_gathered)\n          dir = @file.dirname(@file.expand_path(name, @base))\n          $:.unshift(dir)\n          if(@req)\n            @req.require(name)\n          else\n            require(name)\n          end\n          find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)}\n        ensure\n          $:.delete_at($:.rindex(dir)) if(dir)\n        end\n\n\tdef realdir(path)\n\t  if @base\n\t    @file.join(@base, path)\n\t  else\n\t    path\n\t  end\n\tend\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/collector/objectspace.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/collector'\n\nmodule Test\n  module Unit\n    module Collector\n      class ObjectSpace\n        include Collector\n        \n        NAME = 'collected from the ObjectSpace'\n        \n        def initialize(source=::ObjectSpace)\n          super()\n          @source = source\n        end\n        \n        def collect(name=NAME)\n          suite = TestSuite.new(name)\n          sub_suites = []\n          @source.each_object(Class) do |klass|\n            if(Test::Unit::TestCase > klass)\n              add_suite(sub_suites, klass.suite)\n            end\n          end\n          sort(sub_suites).each{|s| suite << s}\n          suite\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/collector.rb",
    "content": "module Test\n  module Unit\n    module Collector\n      def initialize\n        @filters = []\n      end\n\n      def filter=(filters)\n        @filters = case(filters)\n          when Proc\n            [filters]\n          when Array\n            filters\n        end\n      end\n\n      def add_suite(destination, suite)\n        to_delete = suite.tests.find_all{|t| !include?(t)}\n        to_delete.each{|t| suite.delete(t)}\n        destination << suite unless(suite.size == 0)\n      end\n\n      def include?(test)\n        return true if(@filters.empty?)\n        @filters.each do |filter|\n          result = filter[test]\n          if(result.nil?)\n            next\n          elsif(!result)\n            return false\n          else\n            return true\n          end\n        end\n        true\n      end\n\n      def sort(suites)\n        suites.sort_by{|s| s.name}\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/error.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/util/backtracefilter'\n\nmodule Test\n  module Unit\n\n    # Encapsulates an error in a test. Created by\n    # Test::Unit::TestCase when it rescues an exception thrown\n    # during the processing of a test.\n    class Error\n      include Util::BacktraceFilter\n\n      attr_reader(:test_name, :exception)\n\n      SINGLE_CHARACTER = 'E'\n\n      # Creates a new Error with the given test_name and\n      # exception.\n      def initialize(test_name, exception)\n        @test_name = test_name\n        @exception = exception\n      end\n\n      # Returns a single character representation of an error.\n      def single_character_display\n        SINGLE_CHARACTER\n      end\n\n      # Returns the message associated with the error.\n      def message\n        \"#{@exception.class.name}: #{@exception.message}\"\n      end\n\n      # Returns a brief version of the error description.\n      def short_display\n        \"#@test_name: #{message.split(\"\\n\")[0]}\"\n      end\n\n      # Returns a verbose version of the error description.\n      def long_display\n        backtrace = filter_backtrace(@exception.backtrace).join(\"\\n    \")\n        \"Error:\\n#@test_name:\\n#{message}\\n    #{backtrace}\"\n      end\n\n      # Overridden to return long_display.\n      def to_s\n        long_display\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/failure.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nmodule Test\n  module Unit\n\n    # Encapsulates a test failure. Created by Test::Unit::TestCase\n    # when an assertion fails.\n    class Failure\n      attr_reader :test_name, :location, :message\n      \n      SINGLE_CHARACTER = 'F'\n\n      # Creates a new Failure with the given location and\n      # message.\n      def initialize(test_name, location, message)\n        @test_name = test_name\n        @location = location\n        @message = message\n      end\n      \n      # Returns a single character representation of a failure.\n      def single_character_display\n        SINGLE_CHARACTER\n      end\n\n      # Returns a brief version of the error description.\n      def short_display\n        \"#@test_name: #{@message.split(\"\\n\")[0]}\"\n      end\n\n      # Returns a verbose version of the error description.\n      def long_display\n        location_display = if(location.size == 1)\n          location[0].sub(/\\A(.+:\\d+).*/, ' [\\\\1]')\n        else\n          \"\\n    [#{location.join(\"\\n     \")}]\"\n        end\n        \"Failure:\\n#@test_name#{location_display}:\\n#@message\"\n      end\n\n      # Overridden to return long_display.\n      def to_s\n        long_display\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/testcase.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/assertions'\nrequire 'test/unit/failure'\nrequire 'test/unit/error'\nrequire 'test/unit/testsuite'\nrequire 'test/unit/assertionfailederror'\nrequire 'test/unit/util/backtracefilter'\n\nmodule Test\n  module Unit\n\n    # Ties everything together. If you subclass and add your own\n    # test methods, it takes care of making them into tests and\n    # wrapping those tests into a suite. It also does the\n    # nitty-gritty of actually running an individual test and\n    # collecting its results into a Test::Unit::TestResult object.\n    class TestCase\n      include Assertions\n      include Util::BacktraceFilter\n      \n      attr_reader :method_name\n      \n      STARTED = name + \"::STARTED\"\n      FINISHED = name + \"::FINISHED\"\n\n      ##\n      # These exceptions are not caught by #run.\n\n      PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, Interrupt,\n                                SystemExit]\n\n      # Creates a new instance of the fixture for running the\n      # test represented by test_method_name.\n      def initialize(test_method_name)\n        unless(respond_to?(test_method_name) and\n               (method(test_method_name).arity == 0 ||\n                method(test_method_name).arity == -1))\n          throw :invalid_test\n        end\n        @method_name = test_method_name\n        @test_passed = true\n      end\n\n      # Rolls up all of the test* methods in the fixture into\n      # one suite, creating a new instance of the fixture for\n      # each method.\n      def self.suite\n        method_names = public_instance_methods(true)\n        tests = method_names.delete_if {|method_name| method_name !~ /^test./}\n        suite = TestSuite.new(name)\n        tests.sort.each do\n          |test|\n          catch(:invalid_test) do\n            suite << new(test)\n          end\n        end\n        if (suite.empty?)\n          catch(:invalid_test) do\n            suite << new(\"default_test\")\n          end\n        end\n        return suite\n      end\n\n      # Runs the individual test method represented by this\n      # instance of the fixture, collecting statistics, failures\n      # and errors in result.\n      def run(result)\n        yield(STARTED, name)\n        @_result = result\n        begin\n          setup\n          __send__(@method_name)\n        rescue AssertionFailedError => e\n          add_failure(e.message, e.backtrace)\n        rescue Exception\n          raise if PASSTHROUGH_EXCEPTIONS.include? $!.class\n          add_error($!)\n        ensure\n          begin\n            teardown\n          rescue AssertionFailedError => e\n            add_failure(e.message, e.backtrace)\n          rescue Exception\n            raise if PASSTHROUGH_EXCEPTIONS.include? $!.class\n            add_error($!)\n          end\n        end\n        result.add_run\n        yield(FINISHED, name)\n      end\n\n      # Called before every test method runs. Can be used\n      # to set up fixture information.\n      def setup\n      end\n\n      # Called after every test method runs. Can be used to tear\n      # down fixture information.\n      def teardown\n      end\n      \n      def default_test\n        flunk(\"No tests were specified\")\n      end\n\n      # Returns whether this individual test passed or\n      # not. Primarily for use in teardown so that artifacts\n      # can be left behind if the test fails.\n      def passed?\n        return @test_passed\n      end\n      private :passed?\n\n      def size\n        1\n      end\n\n      def add_assertion\n        @_result.add_assertion\n      end\n      private :add_assertion\n\n      def add_failure(message, all_locations=caller())\n        @test_passed = false\n        @_result.add_failure(Failure.new(name, filter_backtrace(all_locations), message))\n      end\n      private :add_failure\n\n      def add_error(exception)\n        @test_passed = false\n        @_result.add_error(Error.new(name, exception))\n      end\n      private :add_error\n\n      # Returns a human-readable name for the specific test that\n      # this instance of TestCase represents.\n      def name\n        \"#{@method_name}(#{self.class.name})\"\n      end\n\n      # Overridden to return #name.\n      def to_s\n        name\n      end\n      \n      # It's handy to be able to compare TestCase instances.\n      def ==(other)\n        return false unless(other.kind_of?(self.class))\n        return false unless(@method_name == other.method_name)\n        self.class == other.class\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/testresult.rb",
    "content": "#--\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/util/observable'\n\nmodule Test\n  module Unit\n\n    # Collects Test::Unit::Failure and Test::Unit::Error so that\n    # they can be displayed to the user. To this end, observers\n    # can be added to it, allowing the dynamic updating of, say, a\n    # UI.\n    class TestResult\n      include Util::Observable\n\n      CHANGED = \"CHANGED\"\n      FAULT = \"FAULT\"\n\n      attr_reader(:run_count, :assertion_count)\n\n      # Constructs a new, empty TestResult.\n      def initialize\n        @run_count, @assertion_count = 0, 0\n        @failures, @errors = Array.new, Array.new\n      end\n\n      # Records a test run.\n      def add_run\n        @run_count += 1\n        notify_listeners(CHANGED, self)\n      end\n\n      # Records a Test::Unit::Failure.\n      def add_failure(failure)\n        @failures << failure\n        notify_listeners(FAULT, failure)\n        notify_listeners(CHANGED, self)\n      end\n\n      # Records a Test::Unit::Error.\n      def add_error(error)\n        @errors << error\n        notify_listeners(FAULT, error)\n        notify_listeners(CHANGED, self)\n      end\n\n      # Records an individual assertion.\n      def add_assertion\n        @assertion_count += 1\n        notify_listeners(CHANGED, self)\n      end\n\n      # Returns a string contain the recorded runs, assertions,\n      # failures and errors in this TestResult.\n      def to_s\n        \"#{run_count} tests, #{assertion_count} assertions, #{failure_count} failures, #{error_count} errors\"\n      end\n\n      # Returns whether or not this TestResult represents\n      # successful completion.\n      def passed?\n        return @failures.empty? && @errors.empty?\n      end\n\n      # Returns the number of failures this TestResult has\n      # recorded.\n      def failure_count\n        return @failures.size\n      end\n\n      # Returns the number of errors this TestResult has\n      # recorded.\n      def error_count\n        return @errors.size\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/testsuite.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nmodule Test\n  module Unit\n\n    # A collection of tests which can be #run.\n    #\n    # Note: It is easy to confuse a TestSuite instance with\n    # something that has a static suite method; I know because _I_\n    # have trouble keeping them straight. Think of something that\n    # has a suite method as simply providing a way to get a\n    # meaningful TestSuite instance.\n    class TestSuite\n      attr_reader :name, :tests\n      \n      STARTED = name + \"::STARTED\"\n      FINISHED = name + \"::FINISHED\"\n\n      # Creates a new TestSuite with the given name.\n      def initialize(name=\"Unnamed TestSuite\")\n        @name = name\n        @tests = []\n      end\n\n      # Runs the tests and/or suites contained in this\n      # TestSuite.\n      def run(result, &progress_block)\n        yield(STARTED, name)\n        @tests.each do |test|\n          test.run(result, &progress_block)\n        end\n        yield(FINISHED, name)\n      end\n\n      # Adds the test to the suite.\n      def <<(test)\n        @tests << test\n        self\n      end\n\n      def delete(test)\n        @tests.delete(test)\n      end\n\n      # Retuns the rolled up number of tests in this suite;\n      # i.e. if the suite contains other suites, it counts the\n      # tests within those suites, not the suites themselves.\n      def size\n        total_size = 0\n        @tests.each { |test| total_size += test.size }\n        total_size\n      end\n      \n      def empty?\n        tests.empty?\n      end\n\n      # Overridden to return the name given the suite at\n      # creation.\n      def to_s\n        @name\n      end\n      \n      # It's handy to be able to compare TestSuite instances.\n      def ==(other)\n        return false unless(other.kind_of?(self.class))\n        return false unless(@name == other.name)\n        @tests == other.tests\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/ui/console/testrunner.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/ui/testrunnermediator'\nrequire 'test/unit/ui/testrunnerutilities'\n\nmodule Test\n  module Unit\n    module UI\n      module Console\n\n        # Runs a Test::Unit::TestSuite on the console.\n        class TestRunner\n          extend TestRunnerUtilities\n\n          # Creates a new TestRunner for running the passed\n          # suite. If quiet_mode is true, the output while\n          # running is limited to progress dots, errors and\n          # failures, and the final result. io specifies\n          # where runner output should go to; defaults to\n          # STDOUT.\n          def initialize(suite, output_level=NORMAL, io=STDOUT)\n            if (suite.respond_to?(:suite))\n              @suite = suite.suite\n            else\n              @suite = suite\n            end\n            @output_level = output_level\n            @io = io\n            @already_outputted = false\n            @faults = []\n          end\n\n          # Begins the test run.\n          def start\n            setup_mediator\n            attach_to_mediator\n            return start_mediator\n          end\n\n          private\n          def setup_mediator\n            @mediator = create_mediator(@suite)\n            suite_name = @suite.to_s\n            if ( @suite.kind_of?(Module) )\n              suite_name = @suite.name\n            end\n            output(\"Loaded suite #{suite_name}\")\n          end\n          \n          def create_mediator(suite)\n            return TestRunnerMediator.new(suite)\n          end\n          \n          def attach_to_mediator\n            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))\n            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))\n            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))\n            @mediator.add_listener(TestCase::STARTED, &method(:test_started))\n            @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))\n          end\n          \n          def start_mediator\n            return @mediator.run_suite\n          end\n          \n          def add_fault(fault)\n            @faults << fault\n            output_single(fault.single_character_display, PROGRESS_ONLY)\n            @already_outputted = true\n          end\n          \n          def started(result)\n            @result = result\n            output(\"Started\")\n          end\n          \n          def finished(elapsed_time)\n            nl\n            output(\"Finished in #{elapsed_time} seconds.\")\n            @faults.each_with_index do |fault, index|\n              nl\n              output(\"%3d) %s\" % [index + 1, fault.long_display])\n            end\n            nl\n            output(@result)\n          end\n          \n          def test_started(name)\n            output_single(name + \": \", VERBOSE)\n          end\n          \n          def test_finished(name)\n            output_single(\".\", PROGRESS_ONLY) unless (@already_outputted)\n            nl(VERBOSE)\n            @already_outputted = false\n          end\n          \n          def nl(level=NORMAL)\n            output(\"\", level)\n          end\n          \n          def output(something, level=NORMAL)\n            @io.puts(something) if (output?(level))\n            @io.flush\n          end\n          \n          def output_single(something, level=NORMAL)\n            @io.write(something) if (output?(level))\n            @io.flush\n          end\n          \n          def output?(level)\n            level <= @output_level\n          end\n        end\n      end\n    end\n  end\nend\n\nif __FILE__ == $0\n  Test::Unit::UI::Console::TestRunner.start_command_line_test\nend\n"
  },
  {
    "path": "lib/test/unit/ui/fox/testrunner.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'fox'\nrequire 'test/unit/ui/testrunnermediator'\nrequire 'test/unit/ui/testrunnerutilities'\n\ninclude Fox\n\nmodule Test\n  module Unit\n    module UI\n      module Fox\n\n        # Runs a Test::Unit::TestSuite in a Fox UI. Obviously,\n        # this one requires you to have Fox\n        # (http://www.fox-toolkit.org/fox.html) and the Ruby\n        # Fox extension (http://fxruby.sourceforge.net/)\n        # installed.\n        class TestRunner\n\n          extend TestRunnerUtilities\n          \n          RED_STYLE = FXRGBA(0xFF,0,0,0xFF) #0xFF000000\n          GREEN_STYLE = FXRGBA(0,0xFF,0,0xFF) #0x00FF0000\n\n          # Creates a new TestRunner for running the passed\n          # suite.\n          def initialize(suite, output_level = NORMAL)\n            if (suite.respond_to?(:suite))\n              @suite = suite.suite\n            else\n              @suite = suite\n            end\n\n            @result = nil\n            @red = false\n          end\n  \n          # Begins the test run.\n          def start\n            setup_ui\n            setup_mediator\n            attach_to_mediator\n            start_ui\n            @result\n          end\n\n          def setup_mediator\n            @mediator = TestRunnerMediator.new(@suite)\n            suite_name = @suite.to_s\n            if ( @suite.kind_of?(Module) )\n              suite_name = @suite.name\n            end\n            @suite_name_entry.text = suite_name\n          end\n          \n          def attach_to_mediator\n            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))\n            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))\n            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))\n            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))\n            @mediator.add_listener(TestCase::STARTED, &method(:test_started))\n            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))\n          end\n  \n          def start_ui\n            @application.create\n            @window.show(PLACEMENT_SCREEN)\n            @application.addTimeout(1) do\n              @mediator.run_suite\n            end\n            @application.run\n          end\n          \n          def stop\n            @application.exit(0)\n          end\n          \n          def reset_ui(count)\n            @test_progress_bar.barColor = GREEN_STYLE\n            @test_progress_bar.total = count\n            @test_progress_bar.progress = 0\n            @red = false\n  \n            @test_count_label.text = \"0\"\n            @assertion_count_label.text = \"0\"\n            @failure_count_label.text = \"0\"\n            @error_count_label.text = \"0\"\n  \n            @fault_list.clearItems\n          end\n          \n          def add_fault(fault)\n            if ( ! @red )\n              @test_progress_bar.barColor = RED_STYLE\n              @red = true\n            end\n            item = FaultListItem.new(fault)\n            @fault_list.appendItem(item)\n          end\n          \n          def show_fault(fault)\n            raw_show_fault(fault.long_display)\n          end\n          \n          def raw_show_fault(string)\n            @detail_text.setText(string)\n          end\n          \n          def clear_fault\n            raw_show_fault(\"\")\n          end\n          \n          def result_changed(result)\n            @test_progress_bar.progress = result.run_count\n  \n            @test_count_label.text = result.run_count.to_s\n            @assertion_count_label.text = result.assertion_count.to_s\n            @failure_count_label.text = result.failure_count.to_s\n            @error_count_label.text = result.error_count.to_s\n\n             # repaint now!\n             @info_panel.repaint\n             @application.flush\n          end\n          \n          def started(result)\n            @result = result\n            output_status(\"Started...\")\n          end\n          \n          def test_started(test_name)\n            output_status(\"Running #{test_name}...\")\n          end\n          \n          def finished(elapsed_time)\n            output_status(\"Finished in #{elapsed_time} seconds\")\n          end\n          \n          def output_status(string)\n            @status_entry.text = string\n            @status_entry.repaint\n          end\n  \n          def setup_ui\n            @application = create_application\n            create_tooltip(@application)\n\n            @window = create_window(@application)\n            \n            @status_entry = create_entry(@window)\n            \n            main_panel = create_main_panel(@window)\n            \n            suite_panel = create_suite_panel(main_panel)\n            create_label(suite_panel, \"Suite:\")\n            @suite_name_entry = create_entry(suite_panel)\n            create_button(suite_panel, \"&Run\\tRun the current suite\", proc { @mediator.run_suite })\n            \n            @test_progress_bar = create_progress_bar(main_panel)\n            \n            @info_panel = create_info_panel(main_panel)\n            create_label(@info_panel, \"Tests:\")\n            @test_count_label = create_label(@info_panel, \"0\")\n            create_label(@info_panel, \"Assertions:\")\n            @assertion_count_label = create_label(@info_panel, \"0\")\n            create_label(@info_panel, \"Failures:\")\n            @failure_count_label = create_label(@info_panel, \"0\")\n            create_label(@info_panel, \"Errors:\")\n            @error_count_label = create_label(@info_panel, \"0\")\n            \n            list_panel = create_list_panel(main_panel)\n            @fault_list = create_fault_list(list_panel)\n            \n            detail_panel = create_detail_panel(main_panel)\n            @detail_text = create_text(detail_panel)\n          end\n          \n          def create_application\n            app = FXApp.new(\"TestRunner\", \"Test::Unit\")\n            app.init([])\n            app\n          end\n          \n          def create_window(app)\n            FXMainWindow.new(app, \"Test::Unit TestRunner\", nil, nil, DECOR_ALL, 0, 0, 450)\n          end\n          \n          def create_tooltip(app)\n            FXTooltip.new(app)\n          end\n  \n          def create_main_panel(parent)\n            panel = FXVerticalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y)\n            panel.vSpacing = 10\n            panel\n          end\n  \n          def create_suite_panel(parent)\n            FXHorizontalFrame.new(parent, LAYOUT_SIDE_LEFT | LAYOUT_FILL_X)\n          end\n          \n          def create_button(parent, text, action)\n            FXButton.new(parent, text).connect(SEL_COMMAND, &action)\n          end\n          \n          def create_progress_bar(parent)\n            FXProgressBar.new(parent, nil, 0, PROGRESSBAR_NORMAL | LAYOUT_FILL_X)\n          end\n          \n          def create_info_panel(parent)\n            FXMatrix.new(parent, 1, MATRIX_BY_ROWS | LAYOUT_FILL_X)\n          end\n          \n          def create_label(parent, text)\n            FXLabel.new(parent, text, nil, JUSTIFY_CENTER_X | LAYOUT_FILL_COLUMN)\n          end\n          \n          def create_list_panel(parent)\n            FXHorizontalFrame.new(parent, LAYOUT_FILL_X | FRAME_SUNKEN | FRAME_THICK)\n          end\n          \n          def create_fault_list(parent)\n            list = FXList.new(parent, 10, nil, 0, LIST_SINGLESELECT | LAYOUT_FILL_X) #, 0, 0, 0, 150)\n            list.connect(SEL_COMMAND) do |sender, sel, ptr|\n              if sender.retrieveItem(sender.currentItem).selected?\n                show_fault(sender.retrieveItem(sender.currentItem).fault)\n              else\n                clear_fault\n              end\n            end\n            list\n          end\n          \n          def create_detail_panel(parent)\n            FXHorizontalFrame.new(parent, LAYOUT_FILL_X | LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK)\n          end\n          \n          def create_text(parent)\n            FXText.new(parent, nil, 0, TEXT_READONLY | LAYOUT_FILL_X | LAYOUT_FILL_Y)\n          end\n          \n          def create_entry(parent)\n            entry = FXTextField.new(parent, 30, nil, 0, TEXTFIELD_NORMAL | LAYOUT_SIDE_BOTTOM | LAYOUT_FILL_X)\n            entry.disable\n            entry\n          end\n        end\n  \n        class FaultListItem < FXListItem\n          attr_reader(:fault)\n          def initialize(fault)\n            super(fault.short_display)\n            @fault = fault\n          end\n        end\n      end\n    end\n  end\nend\n\nif __FILE__ == $0\n  Test::Unit::UI::Fox::TestRunner.start_command_line_test\nend\n"
  },
  {
    "path": "lib/test/unit/ui/gtk/testrunner.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'gtk'\nrequire 'test/unit/ui/testrunnermediator'\nrequire 'test/unit/ui/testrunnerutilities'\n\nmodule Test\n  module Unit\n    module UI\n      module GTK\n\n        # Runs a Test::Unit::TestSuite in a Gtk UI. Obviously,\n        # this one requires you to have Gtk\n        # (http://www.gtk.org/) and the Ruby Gtk extension\n        # (http://ruby-gnome.sourceforge.net/) installed.\n        class TestRunner\n          extend TestRunnerUtilities\n\n          # Creates a new TestRunner for running the passed\n          # suite.\n          def initialize(suite, output_level = NORMAL)\n            if (suite.respond_to?(:suite))\n              @suite = suite.suite\n            else\n              @suite = suite\n            end\n            @result = nil\n\n            @runner = Thread.current\n            @restart_signal = Class.new(Exception)\n            @viewer = Thread.start do\n              @runner.join rescue @runner.run\n              Gtk.main\n            end\n            @viewer.join rescue nil # wait deadlock to handshake\n          end\n\n          # Begins the test run.\n          def start\n            setup_mediator\n            setup_ui\n            attach_to_mediator\n            start_ui\n            @result\n          end\n\n          private\n          def setup_mediator\n            @mediator = TestRunnerMediator.new(@suite)\n            suite_name = @suite.to_s\n            if ( @suite.kind_of?(Module) )\n              suite_name = @suite.name\n            end\n            suite_name_entry.set_text(suite_name)\n          end\n          \n          def attach_to_mediator\n            run_button.signal_connect(\"clicked\", nil, &method(:run_test))\n            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))\n            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))\n            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))\n            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))\n            @mediator.add_listener(TestCase::STARTED, &method(:test_started))\n            @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))\n            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))\n          end\n\n          def run_test(*)\n            @runner.raise(@restart_signal)\n          end\n          \n          def start_ui\n            @viewer.run\n            running = false\n            begin\n              loop do\n                if (running ^= true)\n                  run_button.child.text = \"Stop\"\n                  @mediator.run_suite\n                else\n                  run_button.child.text = \"Run\"\n                  @viewer.join\n                  break\n                end\n              end\n            rescue @restart_signal\n              retry\n            rescue\n            end\n          end\n          \n          def stop(*)\n            Gtk.main_quit\n          end\n          \n          def reset_ui(count)\n            test_progress_bar.set_style(green_style)\n            test_progress_bar.configure(0, 0, count)\n            @red = false\n  \n            run_count_label.set_text(\"0\")\n            assertion_count_label.set_text(\"0\")\n            failure_count_label.set_text(\"0\")\n            error_count_label.set_text(\"0\")\n  \n            fault_list.remove_items(fault_list.children)\n          end\n          \n          def add_fault(fault)\n            if ( ! @red )\n              test_progress_bar.set_style(red_style)\n              @red = true\n            end\n            item = FaultListItem.new(fault)\n            item.show\n            fault_list.append_items([item])\n          end\n          \n          def show_fault(fault)\n            raw_show_fault(fault.long_display)\n          end\n          \n          def raw_show_fault(string)\n            fault_detail_label.set_text(string)\n            outer_detail_sub_panel.queue_resize\n          end\n          \n          def clear_fault\n            raw_show_fault(\"\")\n          end\n          \n          def result_changed(result)\n            run_count_label.set_text(result.run_count.to_s)\n            assertion_count_label.set_text(result.assertion_count.to_s)\n            failure_count_label.set_text(result.failure_count.to_s)\n            error_count_label.set_text(result.error_count.to_s)\n          end\n          \n          def started(result)\n            @result = result\n            output_status(\"Started...\")\n          end\n          \n          def test_started(test_name)\n            output_status(\"Running #{test_name}...\")\n          end\n          \n          def test_finished(test_name)\n            test_progress_bar.set_value(test_progress_bar.get_value + 1)\n          end\n          \n          def finished(elapsed_time)\n            output_status(\"Finished in #{elapsed_time} seconds\")\n          end\n          \n          def output_status(string)\n            status_entry.set_text(string)\n          end\n  \n          def setup_ui\n            main_window.signal_connect(\"destroy\", nil, &method(:stop))\n            main_window.show_all\n            fault_list.signal_connect(\"select-child\", nil) {\n              | list, item, data |\n              show_fault(item.fault)\n            }\n            fault_list.signal_connect(\"unselect-child\", nil) {\n              clear_fault\n            }\n            @red = false\n          end\n          \n          def main_window\n            lazy_initialize(:main_window) {\n              @main_window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)\n              @main_window.set_title(\"Test::Unit TestRunner\")\n              @main_window.set_usize(800, 600)\n              @main_window.set_uposition(20, 20)\n              @main_window.set_policy(true, true, false)\n              @main_window.add(main_panel)\n            }\n          end\n          \n          def main_panel\n            lazy_initialize(:main_panel) {\n              @main_panel = Gtk::VBox.new(false, 0)\n              @main_panel.pack_start(suite_panel, false, false, 0)\n              @main_panel.pack_start(progress_panel, false, false, 0)\n              @main_panel.pack_start(info_panel, false, false, 0)\n              @main_panel.pack_start(list_panel, false, false, 0)\n              @main_panel.pack_start(detail_panel, true, true, 0)\n              @main_panel.pack_start(status_panel, false, false, 0)\n            }\n          end\n          \n          def suite_panel\n            lazy_initialize(:suite_panel) {\n              @suite_panel = Gtk::HBox.new(false, 10)\n              @suite_panel.border_width(10)\n              @suite_panel.pack_start(Gtk::Label.new(\"Suite:\"), false, false, 0)\n              @suite_panel.pack_start(suite_name_entry, true, true, 0)\n              @suite_panel.pack_start(run_button, false, false, 0)\n            }\n          end\n          \n          def suite_name_entry\n            lazy_initialize(:suite_name_entry) {\n              @suite_name_entry = Gtk::Entry.new\n              @suite_name_entry.set_editable(false)\n            }\n          end\n          \n          def run_button\n            lazy_initialize(:run_button) {\n              @run_button = Gtk::Button.new(\"Run\")\n            }\n          end\n          \n          def progress_panel\n            lazy_initialize(:progress_panel) {\n              @progress_panel = Gtk::HBox.new(false, 10)\n              @progress_panel.border_width(10)\n              @progress_panel.pack_start(test_progress_bar, true, true, 0)\n            }\n          end\n          \n          def test_progress_bar\n            lazy_initialize(:test_progress_bar) {\n              @test_progress_bar = EnhancedProgressBar.new\n              @test_progress_bar.set_usize(@test_progress_bar.allocation.width,\n                                           info_panel.size_request.height)\n              @test_progress_bar.set_style(green_style)\n            }\n          end\n          \n          def green_style\n            lazy_initialize(:green_style) {\n              @green_style = Gtk::Style.new\n              @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000)\n            }\n          end\n          \n          def red_style\n            lazy_initialize(:red_style) {\n              @red_style = Gtk::Style.new\n              @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000)\n            }\n          end\n          \n          def info_panel\n            lazy_initialize(:info_panel) {\n              @info_panel = Gtk::HBox.new(false, 0)\n              @info_panel.border_width(10)\n              @info_panel.pack_start(Gtk::Label.new(\"Runs:\"), false, false, 0)\n              @info_panel.pack_start(run_count_label, true, false, 0)\n              @info_panel.pack_start(Gtk::Label.new(\"Assertions:\"), false, false, 0)\n              @info_panel.pack_start(assertion_count_label, true, false, 0)\n              @info_panel.pack_start(Gtk::Label.new(\"Failures:\"), false, false, 0)\n              @info_panel.pack_start(failure_count_label, true, false, 0)\n              @info_panel.pack_start(Gtk::Label.new(\"Errors:\"), false, false, 0)\n              @info_panel.pack_start(error_count_label, true, false, 0)\n            }\n          end\n          \n          def run_count_label\n            lazy_initialize(:run_count_label) {\n              @run_count_label = Gtk::Label.new(\"0\")\n              @run_count_label.set_justify(Gtk::JUSTIFY_LEFT)\n            }\n          end\n          \n          def assertion_count_label\n            lazy_initialize(:assertion_count_label) {\n              @assertion_count_label = Gtk::Label.new(\"0\")\n              @assertion_count_label.set_justify(Gtk::JUSTIFY_LEFT)\n            }\n          end\n          \n          def failure_count_label\n            lazy_initialize(:failure_count_label) {\n              @failure_count_label = Gtk::Label.new(\"0\")\n              @failure_count_label.set_justify(Gtk::JUSTIFY_LEFT)\n            }\n          end\n          \n          def error_count_label\n            lazy_initialize(:error_count_label) {\n              @error_count_label = Gtk::Label.new(\"0\")\n              @error_count_label.set_justify(Gtk::JUSTIFY_LEFT)\n            }\n          end\n          \n          def list_panel\n            lazy_initialize(:list_panel) {\n              @list_panel = Gtk::HBox.new\n              @list_panel.border_width(10)\n              @list_panel.pack_start(list_scrolled_window, true, true, 0)\n            }\n          end\n          \n          def list_scrolled_window\n            lazy_initialize(:list_scrolled_window) {\n              @list_scrolled_window = Gtk::ScrolledWindow.new\n              @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)\n              @list_scrolled_window.set_usize(@list_scrolled_window.allocation.width, 150)\n              @list_scrolled_window.add_with_viewport(fault_list)\n            }\n          end\n          \n          def fault_list\n            lazy_initialize(:fault_list) {\n              @fault_list = Gtk::List.new\n            }\n          end\n          \n          def detail_panel\n            lazy_initialize(:detail_panel) {\n              @detail_panel = Gtk::HBox.new\n              @detail_panel.border_width(10)\n              @detail_panel.pack_start(detail_scrolled_window, true, true, 0)\n            }\n          end\n          \n          def detail_scrolled_window\n            lazy_initialize(:detail_scrolled_window) {\n              @detail_scrolled_window = Gtk::ScrolledWindow.new\n              @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)\n              @detail_scrolled_window.set_usize(400, @detail_scrolled_window.allocation.height)\n              @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel)\n            }\n          end\n          \n          def outer_detail_sub_panel\n            lazy_initialize(:outer_detail_sub_panel) {\n              @outer_detail_sub_panel = Gtk::VBox.new\n              @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0)\n            }\n          end\n          \n          def inner_detail_sub_panel\n            lazy_initialize(:inner_detail_sub_panel) {\n              @inner_detail_sub_panel = Gtk::HBox.new\n              @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0)\n            }\n          end\n          \n          def fault_detail_label\n            lazy_initialize(:fault_detail_label) {\n              @fault_detail_label = EnhancedLabel.new(\"\")\n              style = Gtk::Style.new\n              font = Gdk::Font.font_load(\"-*-Courier New-medium-r-normal--*-120-*-*-*-*-*-*\")\n              begin\n                style.set_font(font)\n              rescue ArgumentError; end\n              @fault_detail_label.set_style(style)\n              @fault_detail_label.set_justify(Gtk::JUSTIFY_LEFT)\n              @fault_detail_label.set_line_wrap(false)\n            }\n          end\n          \n          def status_panel\n            lazy_initialize(:status_panel) {\n              @status_panel = Gtk::HBox.new\n              @status_panel.border_width(10)\n              @status_panel.pack_start(status_entry, true, true, 0)\n            }\n          end\n          \n          def status_entry\n            lazy_initialize(:status_entry) {\n              @status_entry = Gtk::Entry.new\n              @status_entry.set_editable(false)\n            }\n          end\n  \n          def lazy_initialize(symbol)\n            if (!instance_eval(\"defined?(@#{symbol.to_s})\"))\n              yield\n            end\n            return instance_eval(\"@\" + symbol.to_s)\n          end\n        end\n  \n        class EnhancedProgressBar < Gtk::ProgressBar\n          def set_style(style)\n            super\n            hide\n            show\n          end\n        end\n  \n        class EnhancedLabel < Gtk::Label\n          def set_text(text)\n            super(text.gsub(/\\n\\t/, \"\\n\" + (\" \" * 4)))\n          end\n        end\n  \n        class FaultListItem < Gtk::ListItem\n          attr_reader(:fault)\n          def initialize(fault)\n            super(fault.short_display)\n            @fault = fault\n          end\n        end\n      end\n    end\n  end\nend\n\nif __FILE__ == $0\n  Test::Unit::UI::GTK::TestRunner.start_command_line_test\nend\n"
  },
  {
    "path": "lib/test/unit/ui/gtk2/testrunner.rb",
    "content": "#--\n#\n# Author:: Kenta MURATA.\n# Copyright:: Copyright (c) 2000-2002 Kenta MURATA. All rights reserved.\n# License:: Ruby license.\n\nrequire \"gtk2\"\nrequire \"test/unit/ui/testrunnermediator\"\nrequire \"test/unit/ui/testrunnerutilities\"\n\nmodule Test\n  module Unit\n    module UI\n      module GTK2\n\n        Gtk.init\n\n        class EnhancedLabel < Gtk::Label\n          def set_text(text)\n            super(text.gsub(/\\n\\t/, \"\\n    \"))\n          end\n        end\n\n        class FaultList < Gtk::TreeView\n          def initialize\n            @faults = []\n            @model = Gtk::ListStore.new(String, String)\n            super(@model)\n            column = Gtk::TreeViewColumn.new\n            column.visible = false\n            append_column(column)\n            renderer = Gtk::CellRendererText.new\n            column = Gtk::TreeViewColumn.new(\"Failures\", renderer, {:text => 1})\n            append_column(column)\n            selection.mode = Gtk::SELECTION_SINGLE\n            set_rules_hint(true)\n            set_headers_visible(false)\n          end # def initialize\n\n          def add_fault(fault)\n            @faults.push(fault)\n            iter = @model.append\n            iter.set_value(0, (@faults.length - 1).to_s)\n            iter.set_value(1, fault.short_display)\n          end # def add_fault(fault)\n\n          def get_fault(iter)\n            @faults[iter.get_value(0).to_i]\n          end # def get_fault\n\n          def clear\n            model.clear\n          end # def clear\n        end\n\n        class TestRunner\n          extend TestRunnerUtilities\n\n          def lazy_initialize(symbol)\n            if !instance_eval(\"defined?(@#{symbol})\") then\n              yield\n            end\n            return instance_eval(\"@#{symbol}\")\n          end\n          private :lazy_initialize\n\n          def status_entry\n            lazy_initialize(:status_entry) do\n              @status_entry = Gtk::Entry.new\n              @status_entry.editable = false\n            end\n          end\n          private :status_entry\n\n          def status_panel\n            lazy_initialize(:status_panel) do\n              @status_panel = Gtk::HBox.new\n              @status_panel.border_width = 10\n              @status_panel.pack_start(status_entry, true, true, 0)\n            end\n          end\n          private :status_panel\n\n          def fault_detail_label\n            lazy_initialize(:fault_detail_label) do\n              @fault_detail_label = EnhancedLabel.new(\"\")\n#              style = Gtk::Style.new\n#              font = Gdk::Font.\n#               font_load(\"-*-Courier 10 Pitch-medium-r-normal--*-120-*-*-*-*-*-*\")\n#              style.set_font(font)\n#              @fault_detail_label.style = style\n              @fault_detail_label.justify = Gtk::JUSTIFY_LEFT\n              @fault_detail_label.wrap = false\n            end\n          end\n          private :fault_detail_label\n\n          def inner_detail_sub_panel\n            lazy_initialize(:inner_detail_sub_panel) do\n              @inner_detail_sub_panel = Gtk::HBox.new\n              @inner_detail_sub_panel.pack_start(fault_detail_label, false, false, 0)\n            end\n          end\n          private :inner_detail_sub_panel\n\n          def outer_detail_sub_panel\n            lazy_initialize(:outer_detail_sub_panel) do\n              @outer_detail_sub_panel = Gtk::VBox.new\n              @outer_detail_sub_panel.pack_start(inner_detail_sub_panel, false, false, 0)\n            end\n          end\n          private :outer_detail_sub_panel\n\n          def detail_scrolled_window\n            lazy_initialize(:detail_scrolled_window) do\n              @detail_scrolled_window = Gtk::ScrolledWindow.new\n              @detail_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)\n              @detail_scrolled_window.\n                set_size_request(400, @detail_scrolled_window.allocation.height)\n              @detail_scrolled_window.add_with_viewport(outer_detail_sub_panel)\n            end\n          end\n          private :detail_scrolled_window\n\n          def detail_panel\n            lazy_initialize(:detail_panel) do\n              @detail_panel = Gtk::HBox.new\n              @detail_panel.border_width = 10\n              @detail_panel.pack_start(detail_scrolled_window, true, true, 0)\n            end\n          end\n          private :detail_panel\n\n          def fault_list\n            lazy_initialize(:fault_list) do\n              @fault_list = FaultList.new\n            end\n          end\n          private :fault_list\n\n          def list_scrolled_window\n            lazy_initialize(:list_scrolled_window) do\n              @list_scrolled_window = Gtk::ScrolledWindow.new\n              @list_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)\n              @list_scrolled_window.\n                set_size_request(@list_scrolled_window.allocation.width, 150)\n              @list_scrolled_window.add_with_viewport(fault_list)\n            end\n          end\n          private :list_scrolled_window\n\n          def list_panel\n            lazy_initialize(:list_panel) do\n              @list_panel = Gtk::HBox.new\n              @list_panel.border_width = 10\n              @list_panel.pack_start(list_scrolled_window, true, true, 0)\n            end\n          end\n          private :list_panel\n\n          def error_count_label\n            lazy_initialize(:error_count_label) do\n              @error_count_label = Gtk::Label.new(\"0\")\n              @error_count_label.justify = Gtk::JUSTIFY_LEFT\n            end\n          end\n          private :error_count_label\n\n          def failure_count_label\n            lazy_initialize(:failure_count_label) do\n              @failure_count_label = Gtk::Label.new(\"0\")\n              @failure_count_label.justify = Gtk::JUSTIFY_LEFT\n            end\n          end\n          private :failure_count_label\n\n          def assertion_count_label\n            lazy_initialize(:assertion_count_label) do\n              @assertion_count_label = Gtk::Label.new(\"0\")\n              @assertion_count_label.justify = Gtk::JUSTIFY_LEFT\n            end\n          end\n          private :assertion_count_label\n\n          def run_count_label\n            lazy_initialize(:run_count_label) do\n              @run_count_label = Gtk::Label.new(\"0\")\n              @run_count_label.justify = Gtk::JUSTIFY_LEFT\n            end\n          end\n          private :run_count_label\n          \n          def info_panel\n            lazy_initialize(:info_panel) do\n              @info_panel = Gtk::HBox.new(false, 0)\n              @info_panel.border_width = 10\n              @info_panel.pack_start(Gtk::Label.new(\"Runs:\"), false, false, 0)\n              @info_panel.pack_start(run_count_label, true, false, 0)\n              @info_panel.pack_start(Gtk::Label.new(\"Assertions:\"), false, false, 0)\n              @info_panel.pack_start(assertion_count_label, true, false, 0)\n              @info_panel.pack_start(Gtk::Label.new(\"Failures:\"), false, false, 0)\n              @info_panel.pack_start(failure_count_label, true, false, 0)\n              @info_panel.pack_start(Gtk::Label.new(\"Errors:\"), false, false, 0)\n              @info_panel.pack_start(error_count_label, true, false, 0)\n            end\n          end # def info_panel\n          private :info_panel\n\n          def green_style\n            lazy_initialize(:green_style) do\n              @green_style = Gtk::Style.new\n              @green_style.set_bg(Gtk::STATE_PRELIGHT, 0x0000, 0xFFFF, 0x0000)\n            end\n          end # def green_style\n          private :green_style\n          \n          def red_style\n            lazy_initialize(:red_style) do\n              @red_style = Gtk::Style.new\n              @red_style.set_bg(Gtk::STATE_PRELIGHT, 0xFFFF, 0x0000, 0x0000)\n            end\n          end # def red_style\n          private :red_style\n          \n          def test_progress_bar\n            lazy_initialize(:test_progress_bar) {\n              @test_progress_bar = Gtk::ProgressBar.new\n              @test_progress_bar.fraction = 0.0\n              @test_progress_bar.\n                set_size_request(@test_progress_bar.allocation.width,\n                                 info_panel.size_request[1])\n              @test_progress_bar.style = green_style\n            }\n          end # def test_progress_bar\n          private :test_progress_bar\n          \n          def progress_panel\n            lazy_initialize(:progress_panel) do\n              @progress_panel = Gtk::HBox.new(false, 10)\n              @progress_panel.border_width = 10\n              @progress_panel.pack_start(test_progress_bar, true, true, 0)\n            end\n          end # def progress_panel\n\n          def run_button\n            lazy_initialize(:run_button) do\n              @run_button = Gtk::Button.new(\"Run\")\n            end\n          end # def run_button\n\n          def suite_name_entry\n            lazy_initialize(:suite_name_entry) do\n              @suite_name_entry = Gtk::Entry.new\n              @suite_name_entry.editable = false\n            end\n          end # def suite_name_entry\n          private :suite_name_entry\n\n          def suite_panel\n            lazy_initialize(:suite_panel) do\n              @suite_panel = Gtk::HBox.new(false, 10)\n              @suite_panel.border_width = 10\n              @suite_panel.pack_start(Gtk::Label.new(\"Suite:\"), false, false, 0)\n              @suite_panel.pack_start(suite_name_entry, true, true, 0)\n              @suite_panel.pack_start(run_button, false, false, 0)\n            end\n          end # def suite_panel\n          private :suite_panel\n\n          def main_panel\n            lazy_initialize(:main_panel) do\n              @main_panel = Gtk::VBox.new(false, 0)\n              @main_panel.pack_start(suite_panel, false, false, 0)\n              @main_panel.pack_start(progress_panel, false, false, 0)\n              @main_panel.pack_start(info_panel, false, false, 0)\n              @main_panel.pack_start(list_panel, false, false, 0)\n              @main_panel.pack_start(detail_panel, true, true, 0)\n              @main_panel.pack_start(status_panel, false, false, 0)\n            end\n          end # def main_panel\n          private :main_panel\n\n          def main_window\n            lazy_initialize(:main_window) do\n              @main_window = Gtk::Window.new(Gtk::Window::TOPLEVEL)\n              @main_window.set_title(\"Test::Unit TestRunner\")\n              @main_window.set_default_size(800, 600)\n              @main_window.set_resizable(true)\n              @main_window.add(main_panel)\n            end\n          end # def main_window\n          private :main_window\n\n          def setup_ui\n            main_window.signal_connect(\"destroy\", nil) { stop }\n            main_window.show_all\n            fault_list.selection.signal_connect(\"changed\", nil) do\n              |selection, data|\n              if selection.selected then\n                show_fault(fault_list.get_fault(selection.selected))\n              else\n                clear_fault\n              end\n            end\n          end # def setup_ui\n          private :setup_ui\n\n          def output_status(string)\n            status_entry.set_text(string)\n          end # def output_status(string)\n          private :output_status\n\n          def finished(elapsed_time)\n            test_progress_bar.fraction = 1.0\n            output_status(\"Finished in #{elapsed_time} seconds\")\n          end # def finished(elapsed_time)\n          private :finished\n\n          def test_started(test_name)\n            output_status(\"Running #{test_name}...\")\n          end # def test_started(test_name)\n          private :test_started\n\n          def started(result)\n            @result = result\n            output_status(\"Started...\")\n          end # def started(result)\n          private :started\n\n          def test_finished(result)\n            test_progress_bar.fraction += 1.0 / @count\n          end # def test_finished(result)\n\n          def result_changed(result)\n            run_count_label.label = result.run_count.to_s\n            assertion_count_label.label = result.assertion_count.to_s\n            failure_count_label.label = result.failure_count.to_s\n            error_count_label.label = result.error_count.to_s\n          end # def result_changed(result)\n          private :result_changed\n\n          def clear_fault\n            raw_show_fault(\"\")\n          end # def clear_fault\n          private :clear_fault\n\n          def raw_show_fault(string)\n            fault_detail_label.set_text(string)\n            outer_detail_sub_panel.queue_resize\n          end # def raw_show_fault(string)\n          private :raw_show_fault\n\n          def show_fault(fault)\n            raw_show_fault(fault.long_display)\n          end # def show_fault(fault)\n          private :show_fault\n\n          def add_fault(fault)\n            if not @red then\n              test_progress_bar.style = red_style\n              @red = true\n            end\n            fault_list.add_fault(fault)\n          end # def add_fault(fault)\n          private :add_fault\n\n          def reset_ui(count)\n            test_progress_bar.style = green_style\n            test_progress_bar.fraction = 0.0\n            @count = count + 1\n            @red = false\n\n            run_count_label.set_text(\"0\")\n            assertion_count_label.set_text(\"0\")\n            failure_count_label.set_text(\"0\")\n            error_count_label.set_text(\"0\")\n\n            fault_list.clear\n          end # def reset_ui(count)\n          private :reset_ui\n\n          def stop\n            Gtk.main_quit\n          end # def stop\n          private :stop\n\n          def run_test\n            @runner.raise(@restart_signal)\n          end\n          private :run_test\n\n          def start_ui\n            @viewer.run\n            running = false\n            begin\n              loop do\n                if (running ^= true)\n                  run_button.child.text = \"Stop\"\n                  @mediator.run_suite\n                else\n                  run_button.child.text = \"Run\"\n                  @viewer.join\n                  break\n                end\n              end\n            rescue @restart_signal\n              retry\n            rescue\n            end\n          end # def start_ui\n          private :start_ui\n\n          def attach_to_mediator\n            run_button.signal_connect(\"clicked\", nil) { run_test }\n            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))\n            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))\n            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))\n            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))\n            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))\n            @mediator.add_listener(TestCase::STARTED, &method(:test_started))\n            @mediator.add_listener(TestCase::FINISHED, &method(:test_finished))\n          end # def attach_to_mediator\n          private :attach_to_mediator\n\n          def setup_mediator\n            @mediator = TestRunnerMediator.new(@suite)\n            suite_name = @suite.to_s\n            if @suite.kind_of?(Module) then\n              suite_name = @suite.name\n            end\n            suite_name_entry.set_text(suite_name)\n          end # def setup_mediator\n          private :setup_mediator\n\n          def start\n            setup_mediator\n            setup_ui\n            attach_to_mediator\n            start_ui\n            @result\n          end # def start\n\n          def initialize(suite, output_level = NORMAL)\n            if suite.respond_to?(:suite) then\n              @suite = suite.suite\n            else\n              @suite = suite\n            end\n            @result = nil\n\n            @runner = Thread.current\n            @restart_signal = Class.new(Exception)\n            @viewer = Thread.start do\n              @runner.join rescue @runner.run\n              Gtk.main\n            end\n            @viewer.join rescue nil # wait deadlock to handshake\n          end # def initialize(suite)\n\n        end # class TestRunner\n\n      end # module GTK2\n    end # module UI\n  end # module Unit\nend # module Test\n"
  },
  {
    "path": "lib/test/unit/ui/testrunnermediator.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'test/unit/util/observable'\nrequire 'test/unit/testresult'\n\nmodule Test\n  module Unit\n    module UI\n\n      # Provides an interface to write any given UI against,\n      # hopefully making it easy to write new UIs.\n      class TestRunnerMediator\n        RESET = name + \"::RESET\"\n        STARTED = name + \"::STARTED\"\n        FINISHED = name + \"::FINISHED\"\n        \n        include Util::Observable\n        \n        # Creates a new TestRunnerMediator initialized to run\n        # the passed suite.\n        def initialize(suite)\n          @suite = suite\n        end\n\n        # Runs the suite the TestRunnerMediator was created\n        # with.\n        def run_suite\n          Unit.run = true\n          begin_time = Time.now\n          notify_listeners(RESET, @suite.size)\n          result = create_result\n          notify_listeners(STARTED, result)\n          result_listener = result.add_listener(TestResult::CHANGED) do |updated_result|\n            notify_listeners(TestResult::CHANGED, updated_result)\n          end\n          \n          fault_listener = result.add_listener(TestResult::FAULT) do |fault|\n            notify_listeners(TestResult::FAULT, fault)\n          end\n          \n          @suite.run(result) do |channel, value|\n            notify_listeners(channel, value)\n          end\n          \n          result.remove_listener(TestResult::FAULT, fault_listener)\n          result.remove_listener(TestResult::CHANGED, result_listener)\n          end_time = Time.now\n          elapsed_time = end_time - begin_time\n          notify_listeners(FINISHED, elapsed_time) #\"Finished in #{elapsed_time} seconds.\")\n          return result\n        end\n\n        private\n        # A factory method to create the result the mediator\n        # should run with. Can be overridden by subclasses if\n        # one wants to use a different result.\n        def create_result\n          return TestResult.new\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/ui/testrunnerutilities.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nmodule Test\n  module Unit\n    module UI\n\n      SILENT = 0\n      PROGRESS_ONLY = 1\n      NORMAL = 2\n      VERBOSE = 3\n\n      # Provides some utilities common to most, if not all,\n      # TestRunners.\n      #\n      #--\n      #\n      # Perhaps there ought to be a TestRunner superclass? There\n      # seems to be a decent amount of shared code between test\n      # runners.\n\n      module TestRunnerUtilities\n\n        # Creates a new TestRunner and runs the suite.\n        def run(suite, output_level=NORMAL)\n          return new(suite, output_level).start\n        end\n\n        # Takes care of the ARGV parsing and suite\n        # determination necessary for running one of the\n        # TestRunners from the command line.\n        def start_command_line_test\n          if ARGV.empty?\n            puts \"You should supply the name of a test suite file to the runner\"\n            exit\n          end\n          require ARGV[0].gsub(/.+::/, '')\n          new(eval(ARGV[0])).start\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/ui/tk/testrunner.rb",
    "content": "#--\n#\n# Original Author:: Nathaniel Talbott.\n# Author:: Kazuhiro NISHIYAMA.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# Copyright:: Copyright (c) 2003 Kazuhiro NISHIYAMA. All rights reserved.\n# License:: Ruby license.\n\nrequire 'tk'\nrequire 'test/unit/ui/testrunnermediator'\nrequire 'test/unit/ui/testrunnerutilities'\n\nmodule Test\n  module Unit\n    module UI\n      module Tk\n\n        # Runs a Test::Unit::TestSuite in a Tk UI. Obviously,\n        # this one requires you to have Tk\n        # and the Ruby Tk extension installed.\n        class TestRunner\n          extend TestRunnerUtilities\n\n          # Creates a new TestRunner for running the passed\n          # suite.\n          def initialize(suite, output_level = NORMAL)\n            if (suite.respond_to?(:suite))\n              @suite = suite.suite\n            else\n              @suite = suite\n            end\n            @result = nil\n\n            @red = false\n            @fault_detail_list = []\n            @runner = Thread.current\n            @restart_signal = Class.new(Exception)\n            @viewer = Thread.start do\n              @runner.join rescue @runner.run\n              ::Tk.mainloop\n            end\n            @viewer.join rescue nil # wait deadlock to handshake\n          end\n\n          # Begins the test run.\n          def start\n            setup_ui\n            setup_mediator\n            attach_to_mediator\n            start_ui\n            @result\n          end\n\n          private\n          def setup_mediator\n            @mediator = TestRunnerMediator.new(@suite)\n            suite_name = @suite.to_s\n            if ( @suite.kind_of?(Module) )\n              suite_name = @suite.name\n            end\n            @suite_name_entry.value = suite_name\n          end\n\n          def attach_to_mediator\n            @run_button.command(method(:run_test))\n            @fault_list.bind('ButtonPress-1', proc{|y|\n              fault = @fault_detail_list[@fault_list.nearest(y)]\n              if fault\n                show_fault(fault)\n              end\n            }, '%y')\n            @mediator.add_listener(TestRunnerMediator::RESET, &method(:reset_ui))\n            @mediator.add_listener(TestResult::FAULT, &method(:add_fault))\n            @mediator.add_listener(TestResult::CHANGED, &method(:result_changed))\n            @mediator.add_listener(TestRunnerMediator::STARTED, &method(:started))\n            @mediator.add_listener(TestCase::STARTED, &method(:test_started))\n            @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:finished))\n          end\n\n          def run_test\n            @runner.raise(@restart_signal)\n          end\n\n          def start_ui\n            @viewer.run\n            running = false\n            begin\n              loop do\n                if (running ^= true)\n                  @run_button.configure('text'=>'Stop')\n                  @mediator.run_suite\n                else\n                  @run_button.configure('text'=>'Run')\n                  @viewer.join\n                  break\n                end\n              end\n            rescue @restart_signal\n              retry\n            rescue\n            end\n          end\n\n          def stop\n            ::Tk.exit\n          end\n\n          def reset_ui(count)\n            @test_total_count = count.to_f\n            @test_progress_bar.configure('background'=>'green')\n            @test_progress_bar.place('relwidth'=>(count.zero? ? 0 : 0/count))\n            @red = false\n\n            @test_count_label.value = 0\n            @assertion_count_label.value = 0\n            @failure_count_label.value = 0\n            @error_count_label.value = 0\n\n            @fault_list.delete(0, 'end')\n            @fault_detail_list = []\n            clear_fault\n          end\n\n          def add_fault(fault)\n            if ( ! @red )\n              @test_progress_bar.configure('background'=>'red')\n              @red = true\n            end\n            @fault_detail_list.push fault\n            @fault_list.insert('end', fault.short_display)\n          end\n\n          def show_fault(fault)\n            raw_show_fault(fault.long_display)\n          end\n\n          def raw_show_fault(string)\n            @detail_text.value = string\n          end\n\n          def clear_fault\n            raw_show_fault(\"\")\n          end\n\n          def result_changed(result)\n            @test_count_label.value = result.run_count\n            @test_progress_bar.place('relwidth'=>result.run_count/@test_total_count)\n            @assertion_count_label.value = result.assertion_count\n            @failure_count_label.value = result.failure_count\n            @error_count_label.value = result.error_count\n          end\n\n          def started(result)\n            @result = result\n            output_status(\"Started...\")\n          end\n\n          def test_started(test_name)\n            output_status(\"Running #{test_name}...\")\n          end\n\n          def finished(elapsed_time)\n            output_status(\"Finished in #{elapsed_time} seconds\")\n          end\n\n          def output_status(string)\n            @status_entry.value = string\n          end\n\n          def setup_ui\n            @status_entry = TkVariable.new\n            l = TkLabel.new(nil, 'textvariable'=>@status_entry, 'relief'=>'sunken')\n            l.pack('side'=>'bottom', 'fill'=>'x')\n\n            suite_frame = TkFrame.new.pack('fill'=>'x')\n\n            @run_button = TkButton.new(suite_frame, 'text'=>'Run')\n            @run_button.pack('side'=>'right')\n\n            TkLabel.new(suite_frame, 'text'=>'Suite:').pack('side'=>'left')\n            @suite_name_entry = TkVariable.new\n            l = TkLabel.new(suite_frame, 'textvariable'=>@suite_name_entry, 'relief'=>'sunken')\n            l.pack('side'=>'left', 'fill'=>'x', 'expand'=>true)\n\n            f = TkFrame.new(nil, 'relief'=>'sunken', 'borderwidth'=>3, 'height'=>20).pack('fill'=>'x', 'padx'=>1)\n            @test_progress_bar = TkFrame.new(f, 'background'=>'green').place('anchor'=>'nw', 'relwidth'=>0.0, 'relheight'=>1.0)\n\n            info_frame = TkFrame.new.pack('fill'=>'x')\n            @test_count_label = create_count_label(info_frame, 'Tests:')\n            @assertion_count_label = create_count_label(info_frame, 'Assertions:')\n            @failure_count_label = create_count_label(info_frame, 'Failures:')\n            @error_count_label = create_count_label(info_frame, 'Errors:')\n\n\t    if (::Tk.info('command', TkPanedWindow::TkCommandNames[0]) != \"\")\n\t      # use panedwindow\n\t      paned_frame = TkPanedWindow.new(\"orient\"=>\"vertical\").pack('fill'=>'both', 'expand'=>true)\n\n\t      fault_list_frame = TkFrame.new(paned_frame)\n\t      detail_frame = TkFrame.new(paned_frame)\n\n\t      paned_frame.add(fault_list_frame, detail_frame)\n\t    else\n\t      # no panedwindow\n\t      paned_frame = nil\n\t      fault_list_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)\n\t      detail_frame = TkFrame.new.pack('fill'=>'both', 'expand'=>true)\n\t    end\n\n\t    TkGrid.rowconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0)\n\t    TkGrid.columnconfigure(fault_list_frame, 0, 'weight'=>1, 'minsize'=>0)\n\n            fault_scrollbar_y = TkScrollbar.new(fault_list_frame)\n            fault_scrollbar_x = TkScrollbar.new(fault_list_frame)\n            @fault_list = TkListbox.new(fault_list_frame)\n            @fault_list.yscrollbar(fault_scrollbar_y)\n            @fault_list.xscrollbar(fault_scrollbar_x)\n\n\t    TkGrid.rowconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0)\n\t    TkGrid.columnconfigure(detail_frame, 0, 'weight'=>1, 'minsize'=>0)\n\n\t    ::Tk.grid(@fault_list, fault_scrollbar_y, 'sticky'=>'news')\n\t    ::Tk.grid(fault_scrollbar_x, 'sticky'=>'news')\n\n            detail_scrollbar_y = TkScrollbar.new(detail_frame)\n            detail_scrollbar_x = TkScrollbar.new(detail_frame)\n            @detail_text = TkText.new(detail_frame, 'height'=>10, 'wrap'=>'none') {\n              bindtags(bindtags - [TkText])\n\t    }\n\t    @detail_text.yscrollbar(detail_scrollbar_y)\n\t    @detail_text.xscrollbar(detail_scrollbar_x)\n\n\t    ::Tk.grid(@detail_text, detail_scrollbar_y, 'sticky'=>'news')\n\t    ::Tk.grid(detail_scrollbar_x, 'sticky'=>'news')\n\n\t    # rubber-style pane\n\t    if paned_frame\n\t      ::Tk.update\n\t      @height = paned_frame.winfo_height\n\t      paned_frame.bind('Configure', proc{|h|\n\t\tpaned_frame.sash_place(0, 0, paned_frame.sash_coord(0)[1] * h / @height)\n\t\t@height = h\n\t      }, '%h')\n\t    end\n          end\n\n          def create_count_label(parent, label)\n            TkLabel.new(parent, 'text'=>label).pack('side'=>'left', 'expand'=>true)\n            v = TkVariable.new(0)\n            TkLabel.new(parent, 'textvariable'=>v).pack('side'=>'left', 'expand'=>true)\n            v\n          end\n        end\n      end\n    end\n  end\nend\n\nif __FILE__ == $0\n  Test::Unit::UI::Tk::TestRunner.start_command_line_test\nend\n"
  },
  {
    "path": "lib/test/unit/util/backtracefilter.rb",
    "content": "module Test\n  module Unit\n    module Util\n      module BacktraceFilter\n        TESTUNIT_FILE_SEPARATORS = %r{[\\\\/:]}\n        TESTUNIT_PREFIX = __FILE__.split(TESTUNIT_FILE_SEPARATORS)[0..-3]\n        TESTUNIT_RB_FILE = /\\.rb\\Z/\n        \n        def filter_backtrace(backtrace, prefix=nil)\n          return [\"No backtrace\"] unless(backtrace)\n          split_p = if(prefix)\n            prefix.split(TESTUNIT_FILE_SEPARATORS)\n          else\n            TESTUNIT_PREFIX\n          end\n          match = proc do |e|\n            split_e = e.split(TESTUNIT_FILE_SEPARATORS)[0, split_p.size]\n            next false unless(split_e[0..-2] == split_p[0..-2])\n            split_e[-1].sub(TESTUNIT_RB_FILE, '') == split_p[-1]\n          end\n          return backtrace unless(backtrace.detect(&match))\n          found_prefix = false\n          new_backtrace = backtrace.reverse.reject do |e|\n            if(match[e])\n              found_prefix = true\n              true\n            elsif(found_prefix)\n              false\n            else\n              true\n            end\n          end.reverse\n          new_backtrace = (new_backtrace.empty? ? backtrace : new_backtrace)\n          new_backtrace = new_backtrace.reject(&match)\n          new_backtrace.empty? ? backtrace : new_backtrace\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/util/observable.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/util/procwrapper'\n\nmodule Test\n  module Unit\n    module Util\n\n      # This is a utility class that allows anything mixing\n      # it in to notify a set of listeners about interesting\n      # events.\n      module Observable\n        # We use this for defaults since nil might mean something\n        NOTHING = \"NOTHING/#{__id__}\"\n\n        # Adds the passed proc as a listener on the\n        # channel indicated by channel_name. listener_key\n        # is used to remove the listener later; if none is\n        # specified, the proc itself is used.\n        #\n        # Whatever is used as the listener_key is\n        # returned, making it very easy to use the proc\n        # itself as the listener_key:\n        #\n        #  listener = add_listener(\"Channel\") { ... }\n        #  remove_listener(\"Channel\", listener)\n        def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value\n          unless(block_given?)\n            raise ArgumentError.new(\"No callback was passed as a listener\")\n          end\n      \n          key = listener_key\n          if (listener_key == NOTHING)\n            listener_key = listener\n            key = ProcWrapper.new(listener)\n          end\n      \n          channels[channel_name] ||= {}\n          channels[channel_name][key] = listener\n          return listener_key\n        end\n\n        # Removes the listener indicated by listener_key\n        # from the channel indicated by\n        # channel_name. Returns the registered proc, or\n        # nil if none was found.\n        def remove_listener(channel_name, listener_key)\n          channel = channels[channel_name]\n          return nil unless (channel)\n          key = listener_key\n          if (listener_key.instance_of?(Proc))\n            key = ProcWrapper.new(listener_key)\n          end\n          if (channel.has_key?(key))\n            return channel.delete(key)\n          end\n          return nil\n        end\n\n        # Calls all the procs registered on the channel\n        # indicated by channel_name. If value is\n        # specified, it is passed in to the procs,\n        # otherwise they are called with no arguments.\n        #\n        #--\n        #\n        # Perhaps this should be private? Would it ever\n        # make sense for an external class to call this\n        # method directly?\n        def notify_listeners(channel_name, *arguments)\n          channel = channels[channel_name]\n          return 0 unless (channel)\n          listeners = channel.values\n          listeners.each { |listener| listener.call(*arguments) }\n          return listeners.size\n        end\n\n        private\n        def channels\n          @channels ||= {}\n          return @channels\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit/util/procwrapper.rb",
    "content": "#--\n#\n# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nmodule Test\n  module Unit\n    module Util\n\n      # Allows the storage of a Proc passed through '&' in a\n      # hash.\n      #\n      # Note: this may be inefficient, since the hash being\n      # used is not necessarily very good. In Observable,\n      # efficiency is not too important, since the hash is\n      # only accessed when adding and removing listeners,\n      # not when notifying.\n\n      class ProcWrapper\n\n        # Creates a new wrapper for a_proc.\n        def initialize(a_proc)\n          @a_proc = a_proc\n          @hash = a_proc.inspect.sub(/^(#<#{a_proc.class}:)/){''}.sub(/(>)$/){''}.hex\n        end\n\n        def hash\n          return @hash\n        end\n\n        def ==(other)\n          case(other)\n            when ProcWrapper\n              return @a_proc == other.to_proc\n            else\n              return super\n          end\n        end\n        alias :eql? :==\n\n        def to_proc\n          return @a_proc\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/test/unit.rb",
    "content": "require 'test/unit/testcase'\nrequire 'test/unit/autorunner'\n\nmodule Test # :nodoc:\n  #\n  # = Test::Unit - Ruby Unit Testing Framework\n  # \n  # == Introduction\n  # \n  # Unit testing is making waves all over the place, largely due to the\n  # fact that it is a core practice of XP. While XP is great, unit testing\n  # has been around for a long time and has always been a good idea. One\n  # of the keys to good unit testing, though, is not just writing tests,\n  # but having tests. What's the difference? Well, if you just _write_ a\n  # test and throw it away, you have no guarantee that something won't\n  # change later which breaks your code. If, on the other hand, you _have_\n  # tests (obviously you have to write them first), and run them as often\n  # as possible, you slowly build up a wall of things that cannot break\n  # without you immediately knowing about it. This is when unit testing\n  # hits its peak usefulness.\n  # \n  # Enter Test::Unit, a framework for unit testing in Ruby, helping you to\n  # design, debug and evaluate your code by making it easy to write and\n  # have tests for it.\n  # \n  # \n  # == Notes\n  # \n  # Test::Unit has grown out of and superceded Lapidary.\n  # \n  # \n  # == Feedback\n  # \n  # I like (and do my best to practice) XP, so I value early releases,\n  # user feedback, and clean, simple, expressive code. There is always\n  # room for improvement in everything I do, and Test::Unit is no\n  # exception. Please, let me know what you think of Test::Unit as it\n  # stands, and what you'd like to see expanded/changed/improved/etc. If\n  # you find a bug, let me know ASAP; one good way to let me know what the\n  # bug is is to submit a new test that catches it :-) Also, I'd love to\n  # hear about any successes you have with Test::Unit, and any\n  # documentation you might add will be greatly appreciated. My contact\n  # info is below.\n  # \n  # \n  # == Contact Information\n  # \n  # A lot of discussion happens about Ruby in general on the ruby-talk\n  # mailing list (http://www.ruby-lang.org/en/ml.html), and you can ask\n  # any questions you might have there. I monitor the list, as do many\n  # other helpful Rubyists, and you're sure to get a quick answer. Of\n  # course, you're also welcome to email me (Nathaniel Talbott) directly\n  # at mailto:testunit@talbott.ws, and I'll do my best to help you out.\n  # \n  # \n  # == Credits\n  # \n  # I'd like to thank...\n  # \n  # Matz, for a great language!\n  # \n  # Masaki Suketa, for his work on RubyUnit, which filled a vital need in\n  # the Ruby world for a very long time. I'm also grateful for his help in\n  # polishing Test::Unit and getting the RubyUnit compatibility layer\n  # right. His graciousness in allowing Test::Unit to supercede RubyUnit\n  # continues to be a challenge to me to be more willing to defer my own\n  # rights.\n  # \n  # Ken McKinlay, for his interest and work on unit testing, and for his\n  # willingness to dialog about it. He was also a great help in pointing\n  # out some of the holes in the RubyUnit compatibility layer.\n  # \n  # Dave Thomas, for the original idea that led to the extremely simple\n  # \"require 'test/unit'\", plus his code to improve it even more by\n  # allowing the selection of tests from the command-line. Also, without\n  # RDoc, the documentation for Test::Unit would stink a lot more than it\n  # does now.\n  # \n  # Everyone who's helped out with bug reports, feature ideas,\n  # encouragement to continue, etc. It's a real privilege to be a part of\n  # the Ruby community.\n  # \n  # The guys at RoleModel Software, for putting up with me repeating, \"But\n  # this would be so much easier in Ruby!\" whenever we're coding in Java.\n  # \n  # My Creator, for giving me life, and giving it more abundantly.\n  # \n  # \n  # == License\n  # \n  # Test::Unit is copyright (c) 2000-2003 Nathaniel Talbott. It is free\n  # software, and is distributed under the Ruby license. See the COPYING\n  # file in the standard Ruby distribution for details.\n  # \n  # \n  # == Warranty\n  # \n  # This software is provided \"as is\" and without any express or\n  # implied warranties, including, without limitation, the implied\n  # warranties of merchantibility and fitness for a particular\n  # purpose.\n  # \n  # \n  # == Author\n  # \n  # Nathaniel Talbott.\n  # Copyright (c) 2000-2003, Nathaniel Talbott\n  #\n  # ----\n  #\n  # = Usage\n  #\n  # The general idea behind unit testing is that you write a _test_\n  # _method_ that makes certain _assertions_ about your code, working\n  # against a _test_ _fixture_. A bunch of these _test_ _methods_ are\n  # bundled up into a _test_ _suite_ and can be run any time the\n  # developer wants. The results of a run are gathered in a _test_\n  # _result_ and displayed to the user through some UI. So, lets break\n  # this down and see how Test::Unit provides each of these necessary\n  # pieces.\n  #\n  #\n  # == Assertions\n  #\n  # These are the heart of the framework. Think of an assertion as a\n  # statement of expected outcome, i.e. \"I assert that x should be equal\n  # to y\". If, when the assertion is executed, it turns out to be\n  # correct, nothing happens, and life is good. If, on the other hand,\n  # your assertion turns out to be false, an error is propagated with\n  # pertinent information so that you can go back and make your\n  # assertion succeed, and, once again, life is good. For an explanation\n  # of the current assertions, see Test::Unit::Assertions.\n  #\n  #\n  # == Test Method & Test Fixture\n  #\n  # Obviously, these assertions have to be called within a context that\n  # knows about them and can do something meaningful with their\n  # pass/fail value. Also, it's handy to collect a bunch of related\n  # tests, each test represented by a method, into a common test class\n  # that knows how to run them. The tests will be in a separate class\n  # from the code they're testing for a couple of reasons. First of all,\n  # it allows your code to stay uncluttered with test code, making it\n  # easier to maintain. Second, it allows the tests to be stripped out\n  # for deployment, since they're really there for you, the developer,\n  # and your users don't need them. Third, and most importantly, it\n  # allows you to set up a common test fixture for your tests to run\n  # against.\n  #\n  # What's a test fixture? Well, tests do not live in a vacuum; rather,\n  # they're run against the code they are testing. Often, a collection\n  # of tests will run against a common set of data, also called a\n  # fixture. If they're all bundled into the same test class, they can\n  # all share the setting up and tearing down of that data, eliminating\n  # unnecessary duplication and making it much easier to add related\n  # tests.\n  #\n  # Test::Unit::TestCase wraps up a collection of test methods together\n  # and allows you to easily set up and tear down the same test fixture\n  # for each test. This is done by overriding #setup and/or #teardown,\n  # which will be called before and after each test method that is\n  # run. The TestCase also knows how to collect the results of your\n  # assertions into a Test::Unit::TestResult, which can then be reported\n  # back to you... but I'm getting ahead of myself. To write a test,\n  # follow these steps:\n  #\n  # * Make sure Test::Unit is in your library path.\n  # * require 'test/unit' in your test script.\n  # * Create a class that subclasses Test::Unit::TestCase.\n  # * Add a method that begins with \"test\" to your class.\n  # * Make assertions in your test method.\n  # * Optionally define #setup and/or #teardown to set up and/or tear\n  #   down your common test fixture.\n  # * You can now run your test as you would any other Ruby\n  #   script... try it and see!\n  #\n  # A really simple test might look like this (#setup and #teardown are\n  # commented out to indicate that they are completely optional):\n  #\n  #     require 'test/unit'\n  #     \n  #     class TC_MyTest < Test::Unit::TestCase\n  #       # def setup\n  #       # end\n  #     \n  #       # def teardown\n  #       # end\n  #     \n  #       def test_fail\n  #         assert(false, 'Assertion was false.')\n  #       end\n  #     end\n  #\n  #\n  # == Test Runners\n  #\n  # So, now you have this great test class, but you still need a way to\n  # run it and view any failures that occur during the run. This is\n  # where Test::Unit::UI::Console::TestRunner (and others, such as\n  # Test::Unit::UI::GTK::TestRunner) comes into play. The console test\n  # runner is automatically invoked for you if you require 'test/unit'\n  # and simply run the file. To use another runner, or to manually\n  # invoke a runner, simply call its run class method and pass in an\n  # object that responds to the suite message with a\n  # Test::Unit::TestSuite. This can be as simple as passing in your\n  # TestCase class (which has a class suite method). It might look\n  # something like this:\n  #\n  #    require 'test/unit/ui/console/testrunner'\n  #    Test::Unit::UI::Console::TestRunner.run(TC_MyTest)\n  #\n  #\n  # == Test Suite\n  #\n  # As more and more unit tests accumulate for a given project, it\n  # becomes a real drag running them one at a time, and it also\n  # introduces the potential to overlook a failing test because you\n  # forget to run it. Suddenly it becomes very handy that the\n  # TestRunners can take any object that returns a Test::Unit::TestSuite\n  # in response to a suite method. The TestSuite can, in turn, contain\n  # other TestSuites or individual tests (typically created by a\n  # TestCase). In other words, you can easily wrap up a group of\n  # TestCases and TestSuites like this:\n  #\n  #  require 'test/unit/testsuite'\n  #  require 'tc_myfirsttests'\n  #  require 'tc_moretestsbyme'\n  #  require 'ts_anothersetoftests'\n  #\n  #  class TS_MyTests\n  #    def self.suite\n  #      suite = Test::Unit::TestSuite.new\n  #      suite << TC_MyFirstTests.suite\n  #      suite << TC_MoreTestsByMe.suite\n  #      suite << TS_AnotherSetOfTests.suite\n  #      return suite\n  #    end\n  #  end\n  #  Test::Unit::UI::Console::TestRunner.run(TS_MyTests)\n  #\n  # Now, this is a bit cumbersome, so Test::Unit does a little bit more\n  # for you, by wrapping these up automatically when you require\n  # 'test/unit'. What does this mean? It means you could write the above\n  # test case like this instead:\n  #\n  #  require 'test/unit'\n  #  require 'tc_myfirsttests'\n  #  require 'tc_moretestsbyme'\n  #  require 'ts_anothersetoftests'\n  #\n  # Test::Unit is smart enough to find all the test cases existing in\n  # the ObjectSpace and wrap them up into a suite for you. It then runs\n  # the dynamic suite using the console TestRunner.\n  #\n  #\n  # == Questions?\n  #\n  # I'd really like to get feedback from all levels of Ruby\n  # practitioners about typos, grammatical errors, unclear statements,\n  # missing points, etc., in this document (or any other).\n  #\n\n  module Unit\n    # Set true when Test::Unit has run.  If set to true Test::Unit\n    # will not automatically run at exit.\n    def self.run=(flag)\n      @run = flag\n    end\n\n    # Already tests have run?\n    def self.run?\n      @run ||= false\n    end\n  end\nend\n\nat_exit do\n  unless $! || Test::Unit.run?\n    Kernel.exit Test::Unit::AutoRunner.run\n  end\nend\n"
  },
  {
    "path": "lib/thread.rb",
    "content": "#\n# NOTE:\n#   This file is overwritten by ext/thread/lib/thread.rb unless ruby\n#   is configured with --disable-fastthread.\n#\n#\t\tthread.rb - thread support classes\n#\t\t\t$Date$\n#\t\t\tby Yukihiro Matsumoto <matz@netlab.co.jp>\n#\n# Copyright (C) 2001  Yukihiro Matsumoto\n# Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n# Copyright (C) 2000  Information-technology Promotion Agency, Japan\n#\n\nunless defined? Thread\n  fail \"Thread not available for this ruby interpreter\"\nend\n\nclass Thread\n  #\n  # Wraps a block in Thread.critical, restoring the original value upon exit\n  # from the critical section.\n  #\n  def Thread.exclusive\n    _old = Thread.critical\n    begin\n      Thread.critical = true\n      return yield\n    ensure\n      Thread.critical = _old\n    end\n  end\nend\n\n#\n# Mutex implements a simple semaphore that can be used to coordinate access to\n# shared data from multiple concurrent threads.\n#\n# Example:\n#\n#   require 'thread'\n#   semaphore = Mutex.new\n#   \n#   a = Thread.new {\n#     semaphore.synchronize {\n#       # access shared resource\n#     }\n#   }\n#   \n#   b = Thread.new {\n#     semaphore.synchronize {\n#       # access shared resource\n#     }\n#   }\n#\nclass Mutex\n  #\n  # Creates a new Mutex\n  #\n  def initialize\n    @waiting = []\n    @locked = false;\n    @waiting.taint\t\t# enable tainted comunication\n    self.taint\n  end\n\n  #\n  # Returns +true+ if this lock is currently held by some thread.\n  #\n  def locked?\n    @locked\n  end\n\n  #\n  # Attempts to obtain the lock and returns immediately. Returns +true+ if the\n  # lock was granted.\n  #\n  def try_lock\n    result = false\n    Thread.critical = true\n    unless @locked\n      @locked = true\n      result = true\n    end\n    Thread.critical = false\n    result\n  end\n\n  #\n  # Attempts to grab the lock and waits if it isn't available.\n  #\n  def lock\n    while (Thread.critical = true; @locked)\n      @waiting.push Thread.current\n      Thread.stop\n    end\n    @locked = true\n    Thread.critical = false\n    self\n  end\n\n  #\n  # Releases the lock. Returns +nil+ if ref wasn't locked.\n  #\n  def unlock\n    return unless @locked\n    Thread.critical = true\n    @locked = false\n    begin\n      t = @waiting.shift\n      t.wakeup if t\n    rescue ThreadError\n      retry\n    end\n    Thread.critical = false\n    begin\n      t.run if t\n    rescue ThreadError\n    end\n    self\n  end\n\n  #\n  # Obtains a lock, runs the block, and releases the lock when the block\n  # completes.  See the example under Mutex.\n  #\n  def synchronize\n    lock\n    begin\n      yield\n    ensure\n      unlock\n    end\n  end\n\n  #\n  # If the mutex is locked, unlocks the mutex, wakes one waiting thread, and\n  # yields in a critical section.\n  #\n  def exclusive_unlock\n    return unless @locked\n    Thread.exclusive do\n      @locked = false\n      begin\n\tt = @waiting.shift\n\tt.wakeup if t\n      rescue ThreadError\n\tretry\n      end\n      yield\n    end\n    self\n  end\nend\n\n# \n# ConditionVariable objects augment class Mutex. Using condition variables,\n# it is possible to suspend while in the middle of a critical section until a\n# resource becomes available.\n#\n# Example:\n#\n#   require 'thread'\n#\n#   mutex = Mutex.new\n#   resource = ConditionVariable.new\n#   \n#   a = Thread.new {\n#     mutex.synchronize {\n#       # Thread 'a' now needs the resource\n#       resource.wait(mutex)\n#       # 'a' can now have the resource\n#     }\n#   }\n#   \n#   b = Thread.new {\n#     mutex.synchronize {\n#       # Thread 'b' has finished using the resource\n#       resource.signal\n#     }\n#   }\n#\nclass ConditionVariable\n  #\n  # Creates a new ConditionVariable\n  #\n  def initialize\n    @waiters = []\n  end\n  \n  #\n  # Releases the lock held in +mutex+ and waits; reacquires the lock on wakeup.\n  #\n  def wait(mutex)\n    begin\n      mutex.exclusive_unlock do\n        @waiters.push(Thread.current)\n        Thread.stop\n      end\n    ensure\n      mutex.lock\n    end\n  end\n  \n  #\n  # Wakes up the first thread in line waiting for this lock.\n  #\n  def signal\n    begin\n      t = @waiters.shift\n      t.run if t\n    rescue ThreadError\n      retry\n    end\n  end\n    \n  #\n  # Wakes up all threads waiting for this lock.\n  #\n  def broadcast\n    waiters0 = nil\n    Thread.exclusive do\n      waiters0 = @waiters.dup\n      @waiters.clear\n    end\n    for t in waiters0\n      begin\n\tt.run\n      rescue ThreadError\n      end\n    end\n  end\nend\n\n#\n# This class provides a way to synchronize communication between threads.\n#\n# Example:\n#\n#   require 'thread'\n#   \n#   queue = Queue.new\n#   \n#   producer = Thread.new do\n#     5.times do |i|\n#       sleep rand(i) # simulate expense\n#       queue << i\n#       puts \"#{i} produced\"\n#     end\n#   end\n#   \n#   consumer = Thread.new do\n#     5.times do |i|\n#       value = queue.pop\n#       sleep rand(i/2) # simulate expense\n#       puts \"consumed #{value}\"\n#     end\n#   end\n#   \n#   consumer.join\n#\nclass Queue\n  #\n  # Creates a new queue.\n  #\n  def initialize\n    @que = []\n    @waiting = []\n    @que.taint\t\t# enable tainted comunication\n    @waiting.taint\n    self.taint\n  end\n\n  #\n  # Pushes +obj+ to the queue.\n  #\n  def push(obj)\n    Thread.critical = true\n    @que.push obj\n    begin\n      t = @waiting.shift\n      t.wakeup if t\n    rescue ThreadError\n      retry\n    ensure\n      Thread.critical = false\n    end\n    begin\n      t.run if t\n    rescue ThreadError\n    end\n  end\n\n  #\n  # Alias of push\n  #\n  alias << push\n\n  #\n  # Alias of push\n  #\n  alias enq push\n\n  #\n  # Retrieves data from the queue.  If the queue is empty, the calling thread is\n  # suspended until data is pushed onto the queue.  If +non_block+ is true, the\n  # thread isn't suspended, and an exception is raised.\n  #\n  def pop(non_block=false)\n    while (Thread.critical = true; @que.empty?)\n      raise ThreadError, \"queue empty\" if non_block\n      @waiting.push Thread.current\n      Thread.stop\n    end\n    @que.shift\n  ensure\n    Thread.critical = false\n  end\n\n  #\n  # Alias of pop\n  #\n  alias shift pop\n\n  #\n  # Alias of pop\n  #\n  alias deq pop\n\n  #\n  # Returns +true+ is the queue is empty.\n  #\n  def empty?\n    @que.empty?\n  end\n\n  #\n  # Removes all objects from the queue.\n  #\n  def clear\n    @que.clear\n  end\n\n  #\n  # Returns the length of the queue.\n  #\n  def length\n    @que.length\n  end\n\n  #\n  # Alias of length.\n  #\n  alias size length\n\n  #\n  # Returns the number of threads waiting on the queue.\n  #\n  def num_waiting\n    @waiting.size\n  end\nend\n\n#\n# This class represents queues of specified size capacity.  The push operation\n# may be blocked if the capacity is full.\n#\n# See Queue for an example of how a SizedQueue works.\n#\nclass SizedQueue<Queue\n  #\n  # Creates a fixed-length queue with a maximum size of +max+.\n  #\n  def initialize(max)\n    raise ArgumentError, \"queue size must be positive\" unless max > 0\n    @max = max\n    @queue_wait = []\n    @queue_wait.taint\t\t# enable tainted comunication\n    super()\n  end\n\n  #\n  # Returns the maximum size of the queue.\n  #\n  def max\n    @max\n  end\n\n  #\n  # Sets the maximum size of the queue.\n  #\n  def max=(max)\n    Thread.critical = true\n    if max <= @max\n      @max = max\n      Thread.critical = false\n    else\n      diff = max - @max\n      @max = max\n      Thread.critical = false\n      diff.times do\n\tbegin\n\t  t = @queue_wait.shift\n\t  t.run if t\n\trescue ThreadError\n\t  retry\n\tend\n      end\n    end\n    max\n  end\n\n  #\n  # Pushes +obj+ to the queue.  If there is no space left in the queue, waits\n  # until space becomes available.\n  #\n  def push(obj)\n    Thread.critical = true\n    while @que.length >= @max\n      @queue_wait.push Thread.current\n      Thread.stop\n      Thread.critical = true\n    end\n    super\n  end\n\n  #\n  # Alias of push\n  #\n  alias << push\n\n  #\n  # Alias of push\n  #\n  alias enq push\n\n  #\n  # Retrieves data from the queue and runs a waiting thread, if any.\n  #\n  def pop(*args)\n    retval = super\n    Thread.critical = true\n    if @que.length < @max\n      begin\n\tt = @queue_wait.shift\n\tt.wakeup if t\n      rescue ThreadError\n\tretry\n      ensure\n\tThread.critical = false\n      end\n      begin\n\tt.run if t\n      rescue ThreadError\n      end\n    end\n    retval\n  end\n\n  #\n  # Alias of pop\n  #\n  alias shift pop\n\n  #\n  # Alias of pop\n  #\n  alias deq pop\n\n  #\n  # Returns the number of threads waiting on the queue.\n  #\n  def num_waiting\n    @waiting.size + @queue_wait.size\n  end\nend\n\n# Documentation comments:\n#  - How do you make RDoc inherit documentation from superclass?\n"
  },
  {
    "path": "lib/thwait.rb",
    "content": "#\n#   thwait.rb - thread synchronization class\n#   \t$Release Version: 0.9 $\n#   \t$Revision: 1.3 $\n#   \t$Date: 1998/06/26 03:19:34 $\n#   \tby Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)\n#\n# --\n#  feature:\n#  provides synchronization for multiple threads.\n#\n#  class methods:\n#  * ThreadsWait.all_waits(thread1,...)\n#    waits until all of specified threads are terminated.\n#    if a block is supplied for the method, evaluates it for\n#    each thread termination.\n#  * th = ThreadsWait.new(thread1,...)\n#    creates synchronization object, specifying thread(s) to wait.\n#  \n#  methods:\n#  * th.threads\n#    list threads to be synchronized\n#  * th.empty?\n#    is there any thread to be synchronized.\n#  * th.finished?\n#    is there already terminated thread.\n#  * th.join(thread1,...) \n#    wait for specified thread(s).\n#  * th.join_nowait(threa1,...)\n#    specifies thread(s) to wait.  non-blocking.\n#  * th.next_wait\n#    waits until any of specified threads is terminated.\n#  * th.all_waits\n#    waits until all of specified threads are terminated.\n#    if a block is supplied for the method, evaluates it for\n#    each thread termination.\n#\n\nrequire \"thread.rb\"\nrequire \"e2mmap.rb\"\n\n#\n# This class watches for termination of multiple threads.  Basic functionality\n# (wait until specified threads have terminated) can be accessed through the\n# class method ThreadsWait::all_waits.  Finer control can be gained using\n# instance methods.\n#\n# Example:\n#\n#   ThreadsWait.all_wait(thr1, thr2, ...) do |t|\n#     STDERR.puts \"Thread #{t} has terminated.\"\n#   end\n#\nclass ThreadsWait\n  RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'\n  \n  Exception2MessageMapper.extend_to(binding)\n  def_exception(\"ErrNoWaitingThread\", \"No threads for waiting.\")\n  def_exception(\"ErrNoFinishedThread\", \"No finished threads.\")\n  \n  #\n  # Waits until all specified threads have terminated.  If a block is provided,\n  # it is executed for each thread termination.\n  #\n  def ThreadsWait.all_waits(*threads) # :yield: thread\n    tw = ThreadsWait.new(*threads)\n    if block_given?\n      tw.all_waits do |th|\n\tyield th\n      end\n    else\n      tw.all_waits\n    end\n  end\n  \n  #\n  # Creates a ThreadsWait object, specifying the threads to wait on.\n  # Non-blocking.\n  #\n  def initialize(*threads)\n    @threads = []\n    @wait_queue = Queue.new\n    join_nowait(*threads) unless threads.empty?\n  end\n  \n  # Returns the array of threads in the wait queue.\n  attr :threads\n  \n  #\n  # Returns +true+ if there are no threads to be synchronized.\n  #\n  def empty?\n    @threads.empty?\n  end\n  \n  #\n  # Returns +true+ if any thread has terminated.\n  #\n  def finished?\n    !@wait_queue.empty?\n  end\n  \n  #\n  # Waits for specified threads to terminate.\n  #\n  def join(*threads)\n    join_nowait(*threads)\n    next_wait\n  end\n  \n  #\n  # Specifies the threads that this object will wait for, but does not actually\n  # wait.\n  #\n  def join_nowait(*threads)\n    threads.flatten!\n    @threads.concat threads\n    for th in threads\n      Thread.start(th) do |t|\n\tbegin\n\t  t.join\n\tensure\n\t  @wait_queue.push t\n\tend\n      end\n    end\n  end\n  \n  #\n  # Waits until any of the specified threads has terminated, and returns the one\n  # that does.\n  #\n  # If there is no thread to wait, raises +ErrNoWaitingThread+.  If +nonblock+\n  # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.\n  #\n  def next_wait(nonblock = nil)\n    ThreadsWait.fail ErrNoWaitingThread if @threads.empty?\n    begin\n      @threads.delete(th = @wait_queue.pop(nonblock))\n      th\n    rescue ThreadError\n      ThreadsWait.fail ErrNoFinishedThread\n    end\n  end\n  \n  #\n  # Waits until all of the specified threads are terminated.  If a block is\n  # supplied for the method, it is executed for each thread termination.\n  #\n  # Raises exceptions in the same manner as +next_wait+.\n  #\n  def all_waits\n    until @threads.empty?\n      th = next_wait\n      yield th if block_given?\n    end\n  end\nend\n\nThWait = ThreadsWait\n\n\n# Documentation comments:\n#  - Source of documentation is evenly split between Nutshell, existing\n#    comments, and my own rephrasing.\n#  - I'm not particularly confident that the comments are all exactly correct.\n#  - The history, etc., up the top appears in the RDoc output.  Perhaps it would\n#    be better to direct that not to appear, and put something else there\n#    instead.\n"
  },
  {
    "path": "lib/time.rb",
    "content": "\n#\n# == Introduction\n# \n# This library extends the Time class:\n# * conversion between date string and time object.\n#   * date-time defined by RFC 2822\n#   * HTTP-date defined by RFC 2616\n#   * dateTime defined by XML Schema Part 2: Datatypes (ISO 8601)\n#   * various formats handled by Date._parse (string to time only)\n# \n# == Design Issues\n# \n# === Specialized interface\n# \n# This library provides methods dedicated to special purposes:\n# * RFC 2822, RFC 2616 and XML Schema.\n# * They makes usual life easier.\n# \n# === Doesn't depend on strftime\n# \n# This library doesn't use +strftime+.  Especially #rfc2822 doesn't depend\n# on +strftime+ because:\n# \n# * %a and %b are locale sensitive\n# \n#   Since they are locale sensitive, they may be replaced to\n#   invalid weekday/month name in some locales.\n#   Since ruby-1.6 doesn't invoke setlocale by default,\n#   the problem doesn't arise until some external library invokes setlocale.\n#   Ruby/GTK is the example of such library.\n# \n# * %z is not portable\n# \n#   %z is required to generate zone in date-time of RFC 2822\n#   but it is not portable.\n#\n# == Revision Information\n#\n# $Id$\n#\n\nrequire 'parsedate'\n\n#\n# Implements the extensions to the Time class that are described in the\n# documentation for the time.rb library.\n#\nclass Time\n  class << Time\n\n    ZoneOffset = {\n      'UTC' => 0,\n      # ISO 8601\n      'Z' => 0,\n      # RFC 822\n      'UT' => 0, 'GMT' => 0,\n      'EST' => -5, 'EDT' => -4,\n      'CST' => -6, 'CDT' => -5,\n      'MST' => -7, 'MDT' => -6,\n      'PST' => -8, 'PDT' => -7,\n      # Following definition of military zones is original one.\n      # See RFC 1123 and RFC 2822 for the error in RFC 822.\n      'A' => +1, 'B' => +2, 'C' => +3, 'D' => +4,  'E' => +5,  'F' => +6, \n      'G' => +7, 'H' => +8, 'I' => +9, 'K' => +10, 'L' => +11, 'M' => +12,\n      'N' => -1, 'O' => -2, 'P' => -3, 'Q' => -4,  'R' => -5,  'S' => -6, \n      'T' => -7, 'U' => -8, 'V' => -9, 'W' => -10, 'X' => -11, 'Y' => -12,\n    }\n    def zone_offset(zone, year=self.now.year)\n      off = nil\n      zone = zone.upcase\n      if /\\A([+-])(\\d\\d):?(\\d\\d)\\z/ =~ zone\n        off = ($1 == '-' ? -1 : 1) * ($2.to_i * 60 + $3.to_i) * 60\n      elsif /\\A[+-]\\d\\d\\z/ =~ zone\n        off = zone.to_i * 3600\n      elsif ZoneOffset.include?(zone)\n        off = ZoneOffset[zone] * 3600\n      elsif ((t = self.local(year, 1, 1)).zone.upcase == zone rescue false)\n        off = t.utc_offset\n      elsif ((t = self.local(year, 7, 1)).zone.upcase == zone rescue false)\n        off = t.utc_offset\n      end\n      off\n    end\n\n    def zone_utc?(zone)\n      # * +0000 means localtime. [RFC 2822]\n      # * GMT is a localtime abbreviation in Europe/London, etc.\n      if /\\A(?:-00:00|-0000|-00|UTC|Z|UT)\\z/i =~ zone\n        true\n      else\n        false\n      end\n    end\n    private :zone_utc?\n\n    LeapYearMonthDays = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n    CommonYearMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n    def month_days(y, m)\n      if ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0)\n        LeapYearMonthDays[m-1]\n      else\n        CommonYearMonthDays[m-1]\n      end\n    end\n    private :month_days\n\n    def apply_offset(year, mon, day, hour, min, sec, off)\n      if off < 0\n        off = -off\n        off, o = off.divmod(60)\n        if o != 0 then sec += o; o, sec = sec.divmod(60); off += o end\n        off, o = off.divmod(60)\n        if o != 0 then min += o; o, min = min.divmod(60); off += o end\n        off, o = off.divmod(24)\n        if o != 0 then hour += o; o, hour = hour.divmod(24); off += o end\n        if off != 0\n          day += off\n          if month_days(year, mon) < day\n            mon += 1\n            if 12 < mon\n              mon = 1\n              year += 1\n            end\n            day = 1\n          end\n        end\n      elsif 0 < off\n        off, o = off.divmod(60)\n        if o != 0 then sec -= o; o, sec = sec.divmod(60); off -= o end\n        off, o = off.divmod(60)\n        if o != 0 then min -= o; o, min = min.divmod(60); off -= o end\n        off, o = off.divmod(24)\n        if o != 0 then hour -= o; o, hour = hour.divmod(24); off -= o end\n        if off != 0 then\n          day -= off\n          if day < 1\n            mon -= 1\n            if mon < 1\n              year -= 1\n              mon = 12\n            end\n            day = month_days(year, mon)\n          end\n        end\n      end\n      return year, mon, day, hour, min, sec\n    end\n    private :apply_offset\n\n    def make_time(year, mon, day, hour, min, sec, sec_fraction, zone, now)\n      usec = nil\n      usec = (sec_fraction * 1000000).to_i if sec_fraction\n      if now\n        begin\n          break if year; year = now.year\n          break if mon; mon = now.mon\n          break if day; day = now.day\n          break if hour; hour = now.hour\n          break if min; min = now.min\n          break if sec; sec = now.sec\n          break if sec_fraction; usec = now.tv_usec\n        end until true\n      end\n\n      year ||= 1970\n      mon ||= 1\n      day ||= 1\n      hour ||= 0\n      min ||= 0\n      sec ||= 0\n      usec ||= 0\n\n      off = nil\n      off = zone_offset(zone, year) if zone\n\n      if off\n        year, mon, day, hour, min, sec =\n          apply_offset(year, mon, day, hour, min, sec, off)\n        t = self.utc(year, mon, day, hour, min, sec, usec)\n        t.localtime if !zone_utc?(zone)\n        t\n      else\n        self.local(year, mon, day, hour, min, sec, usec)\n      end\n    end\n    private :make_time\n\n    #\n    # Parses +date+ using Date._parse and converts it to a Time object.\n    #\n    # If a block is given, the year described in +date+ is converted by the\n    # block.  For example:\n    #\n    #     Time.parse(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}\n    #\n    # If the upper components of the given time are broken or missing, they are\n    # supplied with those of +now+.  For the lower components, the minimum\n    # values (1 or 0) are assumed if broken or missing.  For example:\n    #\n    #     # Suppose it is \"Thu Nov 29 14:33:20 GMT 2001\" now and\n    #     # your timezone is GMT:\n    #     Time.parse(\"16:30\")     #=> Thu Nov 29 16:30:00 GMT 2001\n    #     Time.parse(\"7/23\")      #=> Mon Jul 23 00:00:00 GMT 2001\n    #     Time.parse(\"Aug 31\")    #=> Fri Aug 31 00:00:00 GMT 2001\n    #\n    # Since there are numerous conflicts among locally defined timezone\n    # abbreviations all over the world, this method is not made to\n    # understand all of them.  For example, the abbreviation \"CST\" is\n    # used variously as:\n    #\n    #     -06:00 in America/Chicago,\n    #     -05:00 in America/Havana,\n    #     +08:00 in Asia/Harbin,\n    #     +09:30 in Australia/Darwin,\n    #     +10:30 in Australia/Adelaide,\n    #     etc.\n    #\n    # Based on the fact, this method only understands the timezone\n    # abbreviations described in RFC 822 and the system timezone, in the\n    # order named. (i.e. a definition in RFC 822 overrides the system\n    # timezone definition.)  The system timezone is taken from\n    # <tt>Time.local(year, 1, 1).zone</tt> and\n    # <tt>Time.local(year, 7, 1).zone</tt>.\n    # If the extracted timezone abbreviation does not match any of them,\n    # it is ignored and the given time is regarded as a local time.\n    #\n    # ArgumentError is raised if Date._parse cannot extract information from\n    # +date+ or Time class cannot represent specified date.\n    #\n    # This method can be used as fail-safe for other parsing methods as:\n    #\n    #   Time.rfc2822(date) rescue Time.parse(date)\n    #   Time.httpdate(date) rescue Time.parse(date)\n    #   Time.xmlschema(date) rescue Time.parse(date)\n    #\n    # A failure for Time.parse should be checked, though.\n    #\n    def parse(date, now=self.now)\n      d = Date._parse(date, false)\n      year = d[:year]\n      year = yield(year) if year && block_given?\n      make_time(year, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)\n    end\n\n    MonthValue = {\n      'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6,\n      'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' =>10, 'NOV' =>11, 'DEC' =>12\n    }\n\n    #\n    # Parses +date+ as date-time defined by RFC 2822 and converts it to a Time\n    # object.  The format is identical to the date format defined by RFC 822 and\n    # updated by RFC 1123.\n    #\n    # ArgumentError is raised if +date+ is not compliant with RFC 2822\n    # or Time class cannot represent specified date.\n    #\n    # See #rfc2822 for more information on this format.\n    #\n    def rfc2822(date)\n      if /\\A\\s*\n          (?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\\s*,\\s*)?\n          (\\d{1,2})\\s+\n          (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s+\n          (\\d{2,})\\s+\n          (\\d{2})\\s*\n          :\\s*(\\d{2})\\s*\n          (?::\\s*(\\d{2}))?\\s+\n          ([+-]\\d{4}|\n           UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date\n        # Since RFC 2822 permit comments, the regexp has no right anchor.\n        day = $1.to_i\n        mon = MonthValue[$2.upcase]\n        year = $3.to_i\n        hour = $4.to_i\n        min = $5.to_i\n        sec = $6 ? $6.to_i : 0\n        zone = $7\n\n        # following year completion is compliant with RFC 2822.\n        year = if year < 50\n                 2000 + year\n               elsif year < 1000\n                 1900 + year\n               else\n                 year\n               end\n\n        year, mon, day, hour, min, sec =\n          apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))\n        t = self.utc(year, mon, day, hour, min, sec)\n        t.localtime if !zone_utc?(zone)\n        t\n      else\n        raise ArgumentError.new(\"not RFC 2822 compliant date: #{date.inspect}\")\n      end\n    end\n    alias rfc822 rfc2822\n\n    #\n    # Parses +date+ as HTTP-date defined by RFC 2616 and converts it to a Time\n    # object.\n    #\n    # ArgumentError is raised if +date+ is not compliant with RFC 2616 or Time\n    # class cannot represent specified date.\n    #\n    # See #httpdate for more information on this format.\n    #\n    def httpdate(date)\n      if /\\A\\s*\n          (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\x20\n          (\\d{2})\\x20\n          (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\x20\n          (\\d{4})\\x20\n          (\\d{2}):(\\d{2}):(\\d{2})\\x20\n          GMT\n          \\s*\\z/ix =~ date\n        self.rfc2822(date)\n      elsif /\\A\\s*\n             (?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday),\\x20\n             (\\d\\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\\d\\d)\\x20\n             (\\d\\d):(\\d\\d):(\\d\\d)\\x20\n             GMT\n             \\s*\\z/ix =~ date\n        self.parse(date)\n      elsif /\\A\\s*\n             (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\\x20\n             (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\x20\n             (\\d\\d|\\x20\\d)\\x20\n             (\\d\\d):(\\d\\d):(\\d\\d)\\x20\n             (\\d{4})\n             \\s*\\z/ix =~ date\n        self.utc($6.to_i, MonthValue[$1.upcase], $2.to_i,\n                 $3.to_i, $4.to_i, $5.to_i)\n      else\n        raise ArgumentError.new(\"not RFC 2616 compliant date: #{date.inspect}\")\n      end\n    end\n\n    #\n    # Parses +date+ as dateTime defined by XML Schema and converts it to a Time\n    # object.  The format is restricted version of the format defined by ISO\n    # 8601.\n    #\n    # ArgumentError is raised if +date+ is not compliant with the format or Time\n    # class cannot represent specified date.\n    #\n    # See #xmlschema for more information on this format.\n    #\n    def xmlschema(date)\n      if /\\A\\s*\n          (-?\\d+)-(\\d\\d)-(\\d\\d)\n          T\n          (\\d\\d):(\\d\\d):(\\d\\d)\n          (\\.\\d*)?\n          (Z|[+-]\\d\\d:\\d\\d)?\n          \\s*\\z/ix =~ date\n        year = $1.to_i\n        mon = $2.to_i\n        day = $3.to_i\n        hour = $4.to_i\n        min = $5.to_i\n        sec = $6.to_i\n        usec = 0\n        usec = ($7[1..-1] + '000000')[0,6].to_i if $7\n        if $8\n          zone = $8\n          year, mon, day, hour, min, sec =\n            apply_offset(year, mon, day, hour, min, sec, zone_offset(zone))\n          self.utc(year, mon, day, hour, min, sec, usec)\n        else\n          self.local(year, mon, day, hour, min, sec, usec)\n        end\n      else\n        raise ArgumentError.new(\"invalid date: #{date.inspect}\")\n      end\n    end\n    alias iso8601 xmlschema\n  end # class << self\n\n  #\n  # Returns a string which represents the time as date-time defined by RFC 2822:\n  #\n  #   day-of-week, DD month-name CCYY hh:mm:ss zone\n  #\n  # where zone is [+-]hhmm.\n  #\n  # If +self+ is a UTC time, -0000 is used as zone.\n  #\n  def rfc2822\n    sprintf('%s, %02d %s %d %02d:%02d:%02d ',\n      RFC2822_DAY_NAME[wday],\n      day, RFC2822_MONTH_NAME[mon-1], year,\n      hour, min, sec) +\n    if utc?\n      '-0000'\n    else\n      off = utc_offset\n      sign = off < 0 ? '-' : '+'\n      sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))\n    end\n  end\n  alias rfc822 rfc2822\n\n  RFC2822_DAY_NAME = [\n    'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'\n  ]\n  RFC2822_MONTH_NAME = [\n    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'\n  ]\n\n  #\n  # Returns a string which represents the time as rfc1123-date of HTTP-date\n  # defined by RFC 2616: \n  # \n  #   day-of-week, DD month-name CCYY hh:mm:ss GMT\n  #\n  # Note that the result is always UTC (GMT).\n  #\n  def httpdate\n    t = dup.utc\n    sprintf('%s, %02d %s %d %02d:%02d:%02d GMT',\n      RFC2822_DAY_NAME[t.wday],\n      t.day, RFC2822_MONTH_NAME[t.mon-1], t.year,\n      t.hour, t.min, t.sec)\n  end\n\n  #\n  # Returns a string which represents the time as dateTime defined by XML\n  # Schema:\n  #\n  #   CCYY-MM-DDThh:mm:ssTZD\n  #   CCYY-MM-DDThh:mm:ss.sssTZD\n  #\n  # where TZD is Z or [+-]hh:mm.\n  #\n  # If self is a UTC time, Z is used as TZD.  [+-]hh:mm is used otherwise.\n  #\n  # +fractional_seconds+ specifies a number of digits of fractional seconds.\n  # Its default value is 0.\n  #\n  def xmlschema(fraction_digits=0)\n    sprintf('%d-%02d-%02dT%02d:%02d:%02d',\n      year, mon, day, hour, min, sec) +\n    if fraction_digits == 0\n      ''\n    elsif fraction_digits <= 6\n      '.' + sprintf('%06d', usec)[0, fraction_digits]\n    else\n      '.' + sprintf('%06d', usec) + '0' * (fraction_digits - 6)\n    end +\n    if utc?\n      'Z'\n    else\n      off = utc_offset\n      sign = off < 0 ? '-' : '+'\n      sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))\n    end\n  end\n  alias iso8601 xmlschema\nend\n\nif __FILE__ == $0\n  require 'test/unit'\n\n  class TimeExtentionTest < Test::Unit::TestCase # :nodoc:\n    def test_rfc822\n      assert_equal(Time.utc(1976, 8, 26, 14, 30) + 4 * 3600,\n                   Time.rfc2822(\"26 Aug 76 14:30 EDT\"))\n      assert_equal(Time.utc(1976, 8, 27, 9, 32) + 7 * 3600,\n                   Time.rfc2822(\"27 Aug 76 09:32 PDT\"))\n    end\n\n    def test_rfc2822\n      assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600,\n                   Time.rfc2822(\"Fri, 21 Nov 1997 09:55:06 -0600\"))\n      assert_equal(Time.utc(2003, 7, 1, 10, 52, 37) - 2 * 3600,\n                   Time.rfc2822(\"Tue, 1 Jul 2003 10:52:37 +0200\"))\n      assert_equal(Time.utc(1997, 11, 21, 10, 1, 10) + 6 * 3600,\n                   Time.rfc2822(\"Fri, 21 Nov 1997 10:01:10 -0600\"))\n      assert_equal(Time.utc(1997, 11, 21, 11, 0, 0) + 6 * 3600,\n                   Time.rfc2822(\"Fri, 21 Nov 1997 11:00:00 -0600\"))\n      assert_equal(Time.utc(1997, 11, 24, 14, 22, 1) + 8 * 3600,\n                   Time.rfc2822(\"Mon, 24 Nov 1997 14:22:01 -0800\"))\n      begin\n        Time.at(-1)\n      rescue ArgumentError\n        # ignore\n      else\n        assert_equal(Time.utc(1969, 2, 13, 23, 32, 54) + 3 * 3600 + 30 * 60,\n                     Time.rfc2822(\"Thu, 13 Feb 1969 23:32:54 -0330\"))\n        assert_equal(Time.utc(1969, 2, 13, 23, 32, 0) + 3 * 3600 + 30 * 60,\n                     Time.rfc2822(\" Thu,\n        13\n          Feb\n            1969\n        23:32\n                 -0330 (Newfoundland Time)\"))\n      end\n      assert_equal(Time.utc(1997, 11, 21, 9, 55, 6),\n                   Time.rfc2822(\"21 Nov 97 09:55:06 GMT\"))\n      assert_equal(Time.utc(1997, 11, 21, 9, 55, 6) + 6 * 3600,\n                   Time.rfc2822(\"Fri, 21 Nov 1997 09 :   55  :  06 -0600\"))\n      assert_raise(ArgumentError) {\n        # inner comment is not supported.\n        Time.rfc2822(\"Fri, 21 Nov 1997 09(comment):   55  :  06 -0600\")\n      }\n    end\n\n    def test_rfc2616\n      t = Time.utc(1994, 11, 6, 8, 49, 37)\n      assert_equal(t, Time.httpdate(\"Sun, 06 Nov 1994 08:49:37 GMT\"))\n      assert_equal(t, Time.httpdate(\"Sunday, 06-Nov-94 08:49:37 GMT\"))\n      assert_equal(t, Time.httpdate(\"Sun Nov  6 08:49:37 1994\"))\n      assert_equal(Time.utc(1995, 11, 15, 6, 25, 24),\n                   Time.httpdate(\"Wed, 15 Nov 1995 06:25:24 GMT\"))\n      assert_equal(Time.utc(1995, 11, 15, 4, 58, 8),\n                   Time.httpdate(\"Wed, 15 Nov 1995 04:58:08 GMT\"))\n      assert_equal(Time.utc(1994, 11, 15, 8, 12, 31),\n                   Time.httpdate(\"Tue, 15 Nov 1994 08:12:31 GMT\"))\n      assert_equal(Time.utc(1994, 12, 1, 16, 0, 0),\n                   Time.httpdate(\"Thu, 01 Dec 1994 16:00:00 GMT\"))\n      assert_equal(Time.utc(1994, 10, 29, 19, 43, 31),\n                   Time.httpdate(\"Sat, 29 Oct 1994 19:43:31 GMT\"))\n      assert_equal(Time.utc(1994, 11, 15, 12, 45, 26),\n                   Time.httpdate(\"Tue, 15 Nov 1994 12:45:26 GMT\"))\n      assert_equal(Time.utc(1999, 12, 31, 23, 59, 59),\n                   Time.httpdate(\"Fri, 31 Dec 1999 23:59:59 GMT\"))\n    end\n\n    def test_rfc3339\n      t = Time.utc(1985, 4, 12, 23, 20, 50, 520000)\n      s = \"1985-04-12T23:20:50.52Z\"\n      assert_equal(t, Time.iso8601(s))\n      assert_equal(s, t.iso8601(2))\n\n      t = Time.utc(1996, 12, 20, 0, 39, 57)\n      s = \"1996-12-19T16:39:57-08:00\"\n      assert_equal(t, Time.iso8601(s))\n      # There is no way to generate time string with arbitrary timezone.\n      s = \"1996-12-20T00:39:57Z\"\n      assert_equal(t, Time.iso8601(s))\n      assert_equal(s, t.iso8601)\n\n      t = Time.utc(1990, 12, 31, 23, 59, 60)\n      s = \"1990-12-31T23:59:60Z\"\n      assert_equal(t, Time.iso8601(s))\n      # leap second is representable only if timezone file has it.\n      s = \"1990-12-31T15:59:60-08:00\"\n      assert_equal(t, Time.iso8601(s))\n\n      begin\n        Time.at(-1)\n      rescue ArgumentError\n        # ignore\n      else\n        t = Time.utc(1937, 1, 1, 11, 40, 27, 870000)\n        s = \"1937-01-01T12:00:27.87+00:20\"\n        assert_equal(t, Time.iso8601(s))\n      end\n    end\n\n    # http://www.w3.org/TR/xmlschema-2/\n    def test_xmlschema\n      assert_equal(Time.utc(1999, 5, 31, 13, 20, 0) + 5 * 3600,\n                   Time.xmlschema(\"1999-05-31T13:20:00-05:00\"))\n      assert_equal(Time.local(2000, 1, 20, 12, 0, 0),\n                   Time.xmlschema(\"2000-01-20T12:00:00\"))\n      assert_equal(Time.utc(2000, 1, 20, 12, 0, 0),\n                   Time.xmlschema(\"2000-01-20T12:00:00Z\"))\n      assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) - 12 * 3600,\n                   Time.xmlschema(\"2000-01-20T12:00:00+12:00\"))\n      assert_equal(Time.utc(2000, 1, 20, 12, 0, 0) + 13 * 3600,\n                   Time.xmlschema(\"2000-01-20T12:00:00-13:00\"))\n      assert_equal(Time.utc(2000, 3, 4, 23, 0, 0) - 3 * 3600,\n                   Time.xmlschema(\"2000-03-04T23:00:00+03:00\"))\n      assert_equal(Time.utc(2000, 3, 4, 20, 0, 0),\n                   Time.xmlschema(\"2000-03-04T20:00:00Z\"))\n      assert_equal(Time.local(2000, 1, 15, 0, 0, 0),\n                   Time.xmlschema(\"2000-01-15T00:00:00\"))\n      assert_equal(Time.local(2000, 2, 15, 0, 0, 0),\n                   Time.xmlschema(\"2000-02-15T00:00:00\"))\n      assert_equal(Time.local(2000, 1, 15, 12, 0, 0),\n                   Time.xmlschema(\"2000-01-15T12:00:00\"))\n      assert_equal(Time.utc(2000, 1, 16, 12, 0, 0),\n                   Time.xmlschema(\"2000-01-16T12:00:00Z\"))\n      assert_equal(Time.local(2000, 1, 1, 12, 0, 0),\n                   Time.xmlschema(\"2000-01-01T12:00:00\"))\n      assert_equal(Time.utc(1999, 12, 31, 23, 0, 0),\n                   Time.xmlschema(\"1999-12-31T23:00:00Z\"))\n      assert_equal(Time.local(2000, 1, 16, 12, 0, 0),\n                   Time.xmlschema(\"2000-01-16T12:00:00\"))\n      assert_equal(Time.local(2000, 1, 16, 0, 0, 0),\n                   Time.xmlschema(\"2000-01-16T00:00:00\"))\n      assert_equal(Time.utc(2000, 1, 12, 12, 13, 14),\n                   Time.xmlschema(\"2000-01-12T12:13:14Z\"))\n      assert_equal(Time.utc(2001, 4, 17, 19, 23, 17, 300000),\n                   Time.xmlschema(\"2001-04-17T19:23:17.3Z\"))\n    end\n\n    def test_encode_xmlschema\n      t = Time.utc(2001, 4, 17, 19, 23, 17, 300000)\n      assert_equal(\"2001-04-17T19:23:17Z\", t.xmlschema)\n      assert_equal(\"2001-04-17T19:23:17.3Z\", t.xmlschema(1))\n      assert_equal(\"2001-04-17T19:23:17.300000Z\", t.xmlschema(6))\n      assert_equal(\"2001-04-17T19:23:17.3000000Z\", t.xmlschema(7))\n\n      t = Time.utc(2001, 4, 17, 19, 23, 17, 123456)\n      assert_equal(\"2001-04-17T19:23:17.1234560Z\", t.xmlschema(7))\n      assert_equal(\"2001-04-17T19:23:17.123456Z\", t.xmlschema(6))\n      assert_equal(\"2001-04-17T19:23:17.12345Z\", t.xmlschema(5))\n      assert_equal(\"2001-04-17T19:23:17.1Z\", t.xmlschema(1))\n\n      begin\n        Time.at(-1)\n      rescue ArgumentError\n        # ignore\n      else\n        t = Time.utc(1960, 12, 31, 23, 0, 0, 123456)\n        assert_equal(\"1960-12-31T23:00:00.123456Z\", t.xmlschema(6))\n      end\n\n      assert_equal(249, Time.xmlschema(\"2008-06-05T23:49:23.000249+09:00\").usec)\n    end\n\n    def test_completion\n      now = Time.local(2001,11,29,21,26,35)\n      assert_equal(Time.local( 2001,11,29,21,12),\n                   Time.parse(\"2001/11/29 21:12\", now))\n      assert_equal(Time.local( 2001,11,29),\n                   Time.parse(\"2001/11/29\", now))\n      assert_equal(Time.local( 2001,11,29),\n                   Time.parse(     \"11/29\", now))\n      #assert_equal(Time.local(2001,11,1), Time.parse(\"Nov\", now))\n      assert_equal(Time.local( 2001,11,29,10,22),\n                   Time.parse(           \"10:22\", now))\n    end\n\n    def test_invalid\n      # They were actually used in some web sites.\n      assert_raise(ArgumentError) { Time.httpdate(\"1 Dec 2001 10:23:57 GMT\") }\n      assert_raise(ArgumentError) { Time.httpdate(\"Sat, 1 Dec 2001 10:25:42 GMT\") }\n      assert_raise(ArgumentError) { Time.httpdate(\"Sat,  1-Dec-2001 10:53:55 GMT\") }\n      assert_raise(ArgumentError) { Time.httpdate(\"Saturday, 01-Dec-2001 10:15:34 GMT\") }\n      assert_raise(ArgumentError) { Time.httpdate(\"Saturday, 01-Dec-101 11:10:07 GMT\") }\n      assert_raise(ArgumentError) { Time.httpdate(\"Fri, 30 Nov 2001 21:30:00 JST\") }\n\n      # They were actually used in some mails.\n      assert_raise(ArgumentError) { Time.rfc2822(\"01-5-20\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"7/21/00\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"2001-8-28\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"00-5-6 1:13:06\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"2001-9-27 9:36:49\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"2000-12-13 11:01:11\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"2001/10/17 04:29:55\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"9/4/2001 9:23:19 PM\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"01 Nov 2001 09:04:31\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"13 Feb 2001 16:4 GMT\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"01 Oct 00 5:41:19 PM\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"2 Jul 00 00:51:37 JST\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"01 11 2001 06:55:57 -0500\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"18 \\343\\366\\356\\341\\370 2000\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, Oct 2001  18:53:32\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 2 Nov 2001 03:47:54\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 27 Jul 2001 11.14.14 +0200\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Thu, 2 Nov 2000 04:13:53 -600\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wed, 5 Apr 2000 22:57:09 JST\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Mon, 11 Sep 2000 19:47:33 00000\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 28 Apr 2000 20:40:47 +-900\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 19 Jan 2001 8:15:36 AM -0500\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Thursday, Sep 27 2001 7:42:35 AM EST\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"3/11/2001 1:31:57 PM Pacific Daylight Time\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Mi, 28 Mrz 2001 11:51:36\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"P, 30 sept 2001 23:03:14\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"fr, 11 aug 2000 18:39:22\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fr, 21 Sep 2001 17:44:03 -1000\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Mo, 18 Jun 2001 19:21:40 -1000\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"l\\366, 12 aug 2000 18:53:20\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"l\\366, 26 maj 2001 00:15:58\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Dom, 30 Sep 2001 17:36:30\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"%&, 31 %2/ 2000 15:44:47 -0500\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"dom, 26 ago 2001 03:57:07 -0300\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"ter, 04 set 2001 16:27:58 -0300\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wen, 3 oct 2001 23:17:49 -0400\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wen, 3 oct 2001 23:17:49 -0400\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"ele, 11 h: 2000 12:42:15 -0500\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Tue, 14 Aug 2001 3:55:3 +0200\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 25 Aug 2000 9:3:48 +0800\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 1 Dec 2000 0:57:50 EST\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Mon, 7 May 2001 9:39:51 +0200\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wed, 1 Aug 2001 16:9:15 +0200\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wed, 23 Aug 2000 9:17:36 +0800\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Fri, 11 Aug 2000 10:4:42 +0800\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Sat, 15 Sep 2001 13:22:2 +0300\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wed,16 \\276\\305\\324\\302 2001 20:06:25 +0800\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"Wed,7 \\312\\256\\322\\273\\324\\302 2001 23:47:22 +0800\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"=?iso-8859-1?Q?(=C5=DA),?= 10   2 2001 23:32:26 +0900 (JST)\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"\\307\\341\\314\\343\\332\\311, 30 \\344\\346\\335\\343\\310\\321 2001 10:01:06\") }\n      assert_raise(ArgumentError) { Time.rfc2822(\"=?iso-8859-1?Q?(=BF=E5),?= 12  =?iso-8859-1?Q?9=B7=EE?= 2001 14:52:41\\n+0900 (JST)\") }\n    end\n\n    def test_zone_0000\n      assert_equal(true, Time.parse(\"2000-01-01T00:00:00Z\").utc?)\n      assert_equal(true, Time.parse(\"2000-01-01T00:00:00-00:00\").utc?)\n      assert_equal(false, Time.parse(\"2000-01-01T00:00:00+00:00\").utc?)\n      assert_equal(false, Time.parse(\"Sat, 01 Jan 2000 00:00:00 GMT\").utc?)\n      assert_equal(true, Time.parse(\"Sat, 01 Jan 2000 00:00:00 -0000\").utc?)\n      assert_equal(false, Time.parse(\"Sat, 01 Jan 2000 00:00:00 +0000\").utc?)\n      assert_equal(false, Time.rfc2822(\"Sat, 01 Jan 2000 00:00:00 GMT\").utc?)\n      assert_equal(true, Time.rfc2822(\"Sat, 01 Jan 2000 00:00:00 -0000\").utc?)\n      assert_equal(false, Time.rfc2822(\"Sat, 01 Jan 2000 00:00:00 +0000\").utc?)\n      assert_equal(true, Time.rfc2822(\"Sat, 01 Jan 2000 00:00:00 UTC\").utc?)\n    end\n\n    def test_parse_leap_second\n      t = Time.utc(1998,12,31,23,59,59)\n      assert_equal(t, Time.parse(\"Thu Dec 31 23:59:59 UTC 1998\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 23:59:59 -0000 1998\"));t.localtime\n      assert_equal(t, Time.parse(\"Fri Jan  1 08:59:59 +0900 1999\"))\n      assert_equal(t, Time.parse(\"Fri Jan  1 00:59:59 +0100 1999\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 23:59:59 +0000 1998\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 22:59:59 -0100 1998\"));t.utc\n      t += 1\n      assert_equal(t, Time.parse(\"Thu Dec 31 23:59:60 UTC 1998\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 23:59:60 -0000 1998\"));t.localtime\n      assert_equal(t, Time.parse(\"Fri Jan  1 08:59:60 +0900 1999\"))\n      assert_equal(t, Time.parse(\"Fri Jan  1 00:59:60 +0100 1999\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 23:59:60 +0000 1998\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 22:59:60 -0100 1998\"));t.utc\n      t += 1 if t.sec == 60\n      assert_equal(t, Time.parse(\"Thu Jan  1 00:00:00 UTC 1999\"))\n      assert_equal(t, Time.parse(\"Fri Jan  1 00:00:00 -0000 1999\"));t.localtime\n      assert_equal(t, Time.parse(\"Fri Jan  1 09:00:00 +0900 1999\"))\n      assert_equal(t, Time.parse(\"Fri Jan  1 01:00:00 +0100 1999\"))\n      assert_equal(t, Time.parse(\"Fri Jan  1 00:00:00 +0000 1999\"))\n      assert_equal(t, Time.parse(\"Fri Dec 31 23:00:00 -0100 1998\"))\n    end\n\n    def test_rfc2822_leap_second\n      t = Time.utc(1998,12,31,23,59,59)\n      assert_equal(t, Time.rfc2822(\"Thu, 31 Dec 1998 23:59:59 UTC\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 23:59:59 -0000\"));t.localtime                                  \n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 08:59:59 +0900\"))\n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 00:59:59 +0100\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 23:59:59 +0000\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 22:59:59 -0100\"));t.utc                                  \n      t += 1\n      assert_equal(t, Time.rfc2822(\"Thu, 31 Dec 1998 23:59:60 UTC\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 23:59:60 -0000\"));t.localtime                                  \n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 08:59:60 +0900\"))\n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 00:59:60 +0100\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 23:59:60 +0000\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 22:59:60 -0100\"));t.utc                                  \n      t += 1 if t.sec == 60\n      assert_equal(t, Time.rfc2822(\"Thu,  1 Jan 1999 00:00:00 UTC\"))\n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 00:00:00 -0000\"));t.localtime                                  \n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 09:00:00 +0900\"))\n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 01:00:00 +0100\"))\n      assert_equal(t, Time.rfc2822(\"Fri,  1 Jan 1999 00:00:00 +0000\"))\n      assert_equal(t, Time.rfc2822(\"Fri, 31 Dec 1998 23:00:00 -0100\"))\n    end\n\n    def test_xmlschema_leap_second\n      t = Time.utc(1998,12,31,23,59,59)\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:59:59Z\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:59:59-00:00\"));t.localtime\n      assert_equal(t, Time.xmlschema(\"1999-01-01T08:59:59+09:00\"))\n      assert_equal(t, Time.xmlschema(\"1999-01-01T00:59:59+01:00\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:59:59+00:00\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T22:59:59-01:00\"));t.utc\n      t += 1\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:59:60Z\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:59:60-00:00\"));t.localtime\n      assert_equal(t, Time.xmlschema(\"1999-01-01T08:59:60+09:00\"))\n      assert_equal(t, Time.xmlschema(\"1999-01-01T00:59:60+01:00\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:59:60+00:00\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T22:59:60-01:00\"));t.utc\n      t += 1 if t.sec == 60\n      assert_equal(t, Time.xmlschema(\"1999-01-01T00:00:00Z\"))\n      assert_equal(t, Time.xmlschema(\"1999-01-01T00:00:00-00:00\"));t.localtime\n      assert_equal(t, Time.xmlschema(\"1999-01-01T09:00:00+09:00\"))\n      assert_equal(t, Time.xmlschema(\"1999-01-01T01:00:00+01:00\"))\n      assert_equal(t, Time.xmlschema(\"1999-01-01T00:00:00+00:00\"))\n      assert_equal(t, Time.xmlschema(\"1998-12-31T23:00:00-01:00\"))\n    end\n\n    def test_ruby_talk_152866\n      t = Time::xmlschema('2005-08-30T22:48:00-07:00')\n      assert_equal(31, t.day)\n      assert_equal(8, t.mon)\n    end\n\n    def test_parse_fraction\n      assert_equal(500000, Time.parse(\"2000-01-01T00:00:00.5+00:00\").tv_usec)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/timeout.rb",
    "content": "#--\n# = timeout.rb\n#\n# execution timeout\n#\n# = Copyright\n#\n# Copyright:: (C) 2000  Network Applied Communication Laboratory, Inc.\n# Copyright:: (C) 2000  Information-technology Promotion Agency, Japan\n#\n#++\n#\n# = Description\n#\n# A way of performing a potentially long-running operation in a thread, and\n# terminating it's execution if it hasn't finished within fixed amount of\n# time.\n#\n# Previous versions of timeout didn't use a module for namespace. This version\n# provides both Timeout.timeout, and a backwards-compatible #timeout.\n#\n# = Synopsis\n#\n#   require 'timeout'\n#   status = Timeout::timeout(5) {\n#     # Something that should be interrupted if it takes too much time...\n#   }\n#\n\nmodule Timeout\n\n  ##\n  # Raised by Timeout#timeout when the block times out.\n\n  class Error < Interrupt\n  end\n  class ExitException < ::Exception # :nodoc:\n  end\n\n  THIS_FILE = /\\A#{Regexp.quote(__FILE__)}:/o\n  CALLER_OFFSET = ((c = caller[0]) && THIS_FILE =~ c) ? 1 : 0\n\n  ##\n  # Executes the method's block. If the block execution terminates before +sec+\n  # seconds has passed, it returns true. If not, it terminates the execution\n  # and raises +exception+ (which defaults to Timeout::Error).\n  #\n  # Note that this is both a method of module Timeout, so you can 'include\n  # Timeout' into your classes so they have a #timeout method, as well as a\n  # module method, so you can call it directly as Timeout.timeout().\n\n  def timeout(sec, klass = nil)\n    return yield if sec == nil or sec.zero?\n    raise ThreadError, \"timeout within critical session\" if Thread.critical\n    exception = klass || Class.new(ExitException)\n    begin\n      x = Thread.current\n      y = Thread.start {\n        sleep sec\n        x.raise exception, \"execution expired\" if x.alive?\n      }\n      yield sec\n      #    return true\n    rescue exception => e\n      rej = /\\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\\z/o\n      (bt = e.backtrace).reject! {|m| rej =~ m}\n      level = -caller(CALLER_OFFSET).size\n      while THIS_FILE =~ bt[level]\n        bt.delete_at(level)\n        level += 1\n      end\n      raise if klass            # if exception class is specified, it\n                                # would be expected outside.\n      raise Error, e.message, e.backtrace\n    ensure\n      y.kill if y and y.alive?\n    end\n  end\n\n  module_function :timeout\n\nend\n\n##\n# Identical to:\n#\n#   Timeout::timeout(n, e, &block).\n#\n# Defined for backwards compatibility with earlier versions of timeout.rb, see\n# Timeout#timeout.\n\ndef timeout(n, e = nil, &block) # :nodoc:\n  Timeout::timeout(n, e, &block)\nend\n\n##\n# Another name for Timeout::Error, defined for backwards compatibility with\n# earlier versions of timeout.rb.\n\nTimeoutError = Timeout::Error # :nodoc:\n\nif __FILE__ == $0\n  p timeout(5) {\n    45\n  }\n  p timeout(5, TimeoutError) {\n    45\n  }\n  p timeout(nil) {\n    54\n  }\n  p timeout(0) {\n    54\n  }\n  p timeout(5) {\n    loop {\n      p 10\n      sleep 1\n    }\n  }\nend\n\n"
  },
  {
    "path": "lib/tmpdir.rb",
    "content": "#\n# tmpdir - retrieve temporary directory path\n#\n# $Id$\n#\n\nrequire 'fileutils'\n\nclass Dir\n\n  @@systmpdir = '/tmp'\n\n  begin\n    require 'Win32API'\n    CSIDL_LOCAL_APPDATA = 0x001c\n    max_pathlen = 260\n    windir = \"\\0\"*(max_pathlen+1)\n    begin\n      getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L')\n      raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0\n      windir = File.expand_path(windir.rstrip)\n    rescue RuntimeError\n      begin\n        getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L')\n      rescue RuntimeError\n        getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L')\n      end\n      len = getdir.call(windir, windir.size)\n      windir = File.expand_path(windir[0, len])\n    end\n    temp = File.join(windir.untaint, 'temp')\n    @@systmpdir = temp if File.directory?(temp) and File.writable?(temp)\n  rescue LoadError\n  end\n\n  ##\n  # Returns the operating system's temporary file path.\n\n  def Dir::tmpdir\n    tmp = '.'\n    if $SAFE > 0\n      tmp = @@systmpdir\n    else\n      for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'],\n\t          ENV['USERPROFILE'], @@systmpdir, '/tmp']\n\tif dir and File.directory?(dir) and File.writable?(dir)\n\t  tmp = dir\n\t  break\n\tend\n      end\n      File.expand_path(tmp)\n    end\n  end\n\n  # Dir.mktmpdir creates a temporary directory.\n  #\n  # The directory is created with 0700 permission.\n  #\n  # The prefix and suffix of the name of the directory is specified by\n  # the optional first argument, <i>prefix_suffix</i>.\n  # - If it is not specified or nil, \"d\" is used as the prefix and no suffix is used.\n  # - If it is a string, it is used as the prefix and no suffix is used.\n  # - If it is an array, first element is used as the prefix and second element is used as a suffix.\n  #\n  #  Dir.mktmpdir {|dir| dir is \".../d...\" }\n  #  Dir.mktmpdir(\"foo\") {|dir| dir is \".../foo...\" }\n  #  Dir.mktmpdir([\"foo\", \"bar\"]) {|dir| dir is \".../foo...bar\" }\n  #\n  # The directory is created under Dir.tmpdir or\n  # the optional second argument <i>tmpdir</i> if non-nil value is given.\n  #\n  #  Dir.mktmpdir {|dir| dir is \"#{Dir.tmpdir}/d...\" }\n  #  Dir.mktmpdir(nil, \"/var/tmp\") {|dir| dir is \"/var/tmp/d...\" }\n  #\n  # If a block is given,\n  # it is yielded with the path of the directory.\n  # The directory and its contents are removed\n  # using FileUtils.remove_entry_secure before Dir.mktmpdir returns.\n  # The value of the block is returned.\n  #\n  #  Dir.mktmpdir {|dir|\n  #    # use the directory...\n  #    open(\"#{dir}/foo\", \"w\") { ... }\n  #  }\n  #\n  # If a block is not given,\n  # The path of the directory is returned.\n  # In this case, Dir.mktmpdir doesn't remove the directory.\n  #\n  #  dir = Dir.mktmpdir\n  #  begin\n  #    # use the directory...\n  #    open(\"#{dir}/foo\", \"w\") { ... }\n  #  ensure\n  #    # remove the directory.\n  #    FileUtils.remove_entry_secure dir\n  #  end\n  #\n  def Dir.mktmpdir(prefix_suffix=nil, tmpdir=nil)\n    case prefix_suffix\n    when nil\n      prefix = \"d\"\n      suffix = \"\"\n    when String\n      prefix = prefix_suffix\n      suffix = \"\"\n    when Array\n      prefix = prefix_suffix[0]\n      suffix = prefix_suffix[1]\n    else\n      raise ArgumentError, \"unexpected prefix_suffix: #{prefix_suffix.inspect}\"\n    end\n    tmpdir ||= Dir.tmpdir\n    t = Time.now.strftime(\"%Y%m%d\")\n    n = nil\n    begin\n      path = \"#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}\"\n      path << \"-#{n}\" if n\n      path << suffix\n      Dir.mkdir(path, 0700)\n    rescue Errno::EEXIST\n      n ||= 0\n      n += 1\n      retry\n    end\n\n    if block_given?\n      begin\n        yield path\n      ensure\n        FileUtils.remove_entry_secure path\n      end\n    else\n      path\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tracer.rb",
    "content": "#\n#   tracer.rb - \n#   \t$Release Version: 0.2$\n#   \t$Revision: 1.8 $\n#   \t$Date: 1998/05/19 03:42:49 $\n#   \tby Keiju ISHITSUKA(Nippon Rational Inc.)\n#\n# --\n#\n#   \n#\n\n#\n# tracer main class\n#\nclass Tracer\n  @RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-'\n\n  @stdout = STDOUT\n  @verbose = false\n  class << self\n    attr :verbose, true\n    alias verbose? verbose\n    attr :stdout, true\n  end\n  \n  EVENT_SYMBOL = {\n    \"line\" => \"-\",\n    \"call\" => \">\",\n    \"return\" => \"<\",\n    \"class\" => \"C\",\n    \"end\" => \"E\",\n    \"c-call\" => \">\",\n    \"c-return\" => \"<\",\n  }\n  \n  def initialize\n    @threads = Hash.new\n    if defined? Thread.main\n      @threads[Thread.main.object_id] = 0\n    else\n      @threads[Thread.current.object_id] = 0\n    end\n\n    @get_line_procs = {}\n\n    @filters = []\n  end\n  \n  def stdout\n    Tracer.stdout\n  end\n\n  def on\n    if block_given?\n      on\n      begin\n\tyield\n      ensure\n\toff\n      end\n    else\n      set_trace_func method(:trace_func).to_proc\n      stdout.print \"Trace on\\n\" if Tracer.verbose?\n    end\n  end\n  \n  def off\n    set_trace_func nil\n    stdout.print \"Trace off\\n\" if Tracer.verbose?\n  end\n\n  def add_filter(p = proc)\n    @filters.push p\n  end\n\n  def set_get_line_procs(file, p = proc)\n    @get_line_procs[file] = p\n  end\n  \n  def get_line(file, line)\n    if p = @get_line_procs[file]\n      return p.call(line)\n    end\n\n    unless list = SCRIPT_LINES__[file]\n      begin\n\tf = open(file)\n\tbegin \n\t  SCRIPT_LINES__[file] = list = f.readlines\n\tensure\n\t  f.close\n\tend\n      rescue\n\tSCRIPT_LINES__[file] = list = []\n      end\n    end\n\n    if l = list[line - 1]\n      l\n    else\n      \"-\\n\"\n    end\n  end\n  \n  def get_thread_no\n    if no = @threads[Thread.current.object_id]\n      no\n    else\n      @threads[Thread.current.object_id] = @threads.size\n    end\n  end\n  \n  def trace_func(event, file, line, id, binding, klass, *)\n    return if file == __FILE__\n    \n    for p in @filters\n      return unless p.call event, file, line, id, binding, klass\n    end\n    \n    saved_crit = Thread.critical\n    Thread.critical = true\n    stdout.printf(\"#%d:%s:%d:%s:%s: %s\",\n      get_thread_no,\n      file,\n      line,\n      klass || '',\n      EVENT_SYMBOL[event],\n      get_line(file, line))\n    Thread.critical = saved_crit\n  end\n\n  Single = new\n  def Tracer.on\n    if block_given?\n      Single.on{yield}\n    else\n      Single.on\n    end\n  end\n  \n  def Tracer.off\n    Single.off\n  end\n  \n  def Tracer.set_get_line_procs(file_name, p = proc)\n    Single.set_get_line_procs(file_name, p)\n  end\n\n  def Tracer.add_filter(p = proc)\n    Single.add_filter(p)\n  end\n  \nend\n\nSCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__\n\nif $0 == __FILE__\n  # direct call\n    \n  $0 = ARGV[0]\n  ARGV.shift\n  Tracer.on\n  require $0\nelsif caller(0).size == 1\n  Tracer.on\nend\n"
  },
  {
    "path": "lib/tsort.rb",
    "content": "#!/usr/bin/env ruby\n#--\n# tsort.rb - provides a module for topological sorting and strongly connected components.\n#++\n#\n\n#\n# TSort implements topological sorting using Tarjan's algorithm for\n# strongly connected components.\n#\n# TSort is designed to be able to be used with any object which can be\n# interpreted as a directed graph.\n#\n# TSort requires two methods to interpret an object as a graph,\n# tsort_each_node and tsort_each_child.\n#\n# * tsort_each_node is used to iterate for all nodes over a graph.\n# * tsort_each_child is used to iterate for child nodes of a given node.\n#\n# The equality of nodes are defined by eql? and hash since\n# TSort uses Hash internally.\n#\n# == A Simple Example\n#\n# The following example demonstrates how to mix the TSort module into an\n# existing class (in this case, Hash). Here, we're treating each key in\n# the hash as a node in the graph, and so we simply alias the required\n# #tsort_each_node method to Hash's #each_key method. For each key in the\n# hash, the associated value is an array of the node's child nodes. This\n# choice in turn leads to our implementation of the required #tsort_each_child\n# method, which fetches the array of child nodes and then iterates over that\n# array using the user-supplied block.\n#\n#   require 'tsort'\n#   \n#   class Hash\n#     include TSort\n#     alias tsort_each_node each_key\n#     def tsort_each_child(node, &block)\n#       fetch(node).each(&block)\n#     end\n#   end\n#   \n#   {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort\n#   #=> [3, 2, 1, 4]\n#   \n#   {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components\n#   #=> [[4], [2, 3], [1]]\n#\n# == A More Realistic Example\n#\n# A very simple `make' like tool can be implemented as follows:\n#\n#   require 'tsort'\n#   \n#   class Make\n#     def initialize\n#       @dep = {}\n#       @dep.default = []\n#     end\n#     \n#     def rule(outputs, inputs=[], &block)\n#       triple = [outputs, inputs, block]\n#       outputs.each {|f| @dep[f] = [triple]}\n#       @dep[triple] = inputs\n#     end\n#     \n#     def build(target)\n#       each_strongly_connected_component_from(target) {|ns|\n#         if ns.length != 1\n#           fs = ns.delete_if {|n| Array === n}\n#           raise TSort::Cyclic.new(\"cyclic dependencies: #{fs.join ', '}\")\n#         end\n#         n = ns.first\n#         if Array === n\n#           outputs, inputs, block = n\n#           inputs_time = inputs.map {|f| File.mtime f}.max\n#           begin\n#             outputs_time = outputs.map {|f| File.mtime f}.min\n#           rescue Errno::ENOENT\n#             outputs_time = nil\n#           end\n#           if outputs_time == nil ||\n#              inputs_time != nil && outputs_time <= inputs_time\n#             sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i\n#             block.call\n#           end\n#         end\n#       }\n#     end\n#     \n#     def tsort_each_child(node, &block)\n#       @dep[node].each(&block)\n#     end\n#     include TSort\n#   end\n#   \n#   def command(arg)\n#     print arg, \"\\n\"\n#     system arg\n#   end\n#   \n#   m = Make.new\n#   m.rule(%w[t1]) { command 'date > t1' }\n#   m.rule(%w[t2]) { command 'date > t2' }\n#   m.rule(%w[t3]) { command 'date > t3' }\n#   m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }\n#   m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }\n#   m.build('t5')\n#\n# == Bugs\n#\n# * 'tsort.rb' is wrong name because this library uses\n#   Tarjan's algorithm for strongly connected components.\n#   Although 'strongly_connected_components.rb' is correct but too long.\n#\n# == References\n#\n# R. E. Tarjan, \"Depth First Search and Linear Graph Algorithms\",\n# <em>SIAM Journal on Computing</em>, Vol. 1, No. 2, pp. 146-160, June 1972.\n#\n\nmodule TSort\n  class Cyclic < StandardError\n  end\n\n  #\n  # Returns a topologically sorted array of nodes.\n  # The array is sorted from children to parents, i.e.\n  # the first element has no child and the last node has no parent.\n  #\n  # If there is a cycle, TSort::Cyclic is raised.\n  #\n  def tsort\n    result = []\n    tsort_each {|element| result << element}\n    result\n  end\n\n  #\n  # The iterator version of the #tsort method.\n  # <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but\n  # modification of _obj_ during the iteration may lead to unexpected results.\n  #\n  # #tsort_each returns +nil+.\n  # If there is a cycle, TSort::Cyclic is raised.\n  #\n  def tsort_each # :yields: node\n    each_strongly_connected_component {|component|\n      if component.size == 1\n        yield component.first\n      else\n        raise Cyclic.new(\"topological sort failed: #{component.inspect}\")\n      end\n    }\n  end\n\n  #\n  # Returns strongly connected components as an array of arrays of nodes.\n  # The array is sorted from children to parents.\n  # Each elements of the array represents a strongly connected component.\n  #\n  def strongly_connected_components\n    result = []\n    each_strongly_connected_component {|component| result << component}\n    result\n  end\n\n  #\n  # The iterator version of the #strongly_connected_components method.\n  # <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to\n  # <tt><em>obj</em>.strongly_connected_components.each</tt>, but\n  # modification of _obj_ during the iteration may lead to unexpected results.\n  #\n  #\n  # #each_strongly_connected_component returns +nil+.\n  #\n  def each_strongly_connected_component # :yields: nodes\n    id_map = {}\n    stack = []\n    tsort_each_node {|node|\n      unless id_map.include? node\n        each_strongly_connected_component_from(node, id_map, stack) {|c|\n          yield c\n        }\n      end\n    }\n    nil\n  end\n\n  #\n  # Iterates over strongly connected component in the subgraph reachable from \n  # _node_.\n  #\n  # Return value is unspecified.\n  #\n  # #each_strongly_connected_component_from doesn't call #tsort_each_node.\n  #\n  def each_strongly_connected_component_from(node, id_map={}, stack=[]) # :yields: nodes\n    minimum_id = node_id = id_map[node] = id_map.size\n    stack_length = stack.length\n    stack << node\n\n    tsort_each_child(node) {|child|\n      if id_map.include? child\n        child_id = id_map[child]\n        minimum_id = child_id if child_id && child_id < minimum_id\n      else\n        sub_minimum_id =\n          each_strongly_connected_component_from(child, id_map, stack) {|c|\n            yield c\n          }\n        minimum_id = sub_minimum_id if sub_minimum_id < minimum_id\n      end\n    }\n\n    if node_id == minimum_id\n      component = stack.slice!(stack_length .. -1)\n      component.each {|n| id_map[n] = nil}\n      yield component\n    end\n\n    minimum_id\n  end\n\n  #\n  # Should be implemented by a extended class.\n  #\n  # #tsort_each_node is used to iterate for all nodes over a graph.\n  #\n  def tsort_each_node # :yields: node\n    raise NotImplementedError.new\n  end\n\n  #\n  # Should be implemented by a extended class.\n  #\n  # #tsort_each_child is used to iterate for child nodes of _node_.\n  #\n  def tsort_each_child(node) # :yields: child\n    raise NotImplementedError.new\n  end\nend\n\nif __FILE__ == $0\n  require 'test/unit'\n\n  class TSortHash < Hash # :nodoc:\n    include TSort\n    alias tsort_each_node each_key\n    def tsort_each_child(node, &block)\n      fetch(node).each(&block)\n    end\n  end\n\n  class TSortArray < Array # :nodoc:\n    include TSort\n    alias tsort_each_node each_index\n    def tsort_each_child(node, &block)\n      fetch(node).each(&block)\n    end\n  end\n\n  class TSortTest < Test::Unit::TestCase # :nodoc:\n    def test_dag\n      h = TSortHash[{1=>[2, 3], 2=>[3], 3=>[]}]\n      assert_equal([3, 2, 1], h.tsort)\n      assert_equal([[3], [2], [1]], h.strongly_connected_components)\n    end\n\n    def test_cycle\n      h = TSortHash[{1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}]\n      assert_equal([[4], [2, 3], [1]],\n        h.strongly_connected_components.map {|nodes| nodes.sort})\n      assert_raise(TSort::Cyclic) { h.tsort }\n    end\n\n    def test_array\n      a = TSortArray[[1], [0], [0], [2]]\n      assert_equal([[0, 1], [2], [3]],\n        a.strongly_connected_components.map {|nodes| nodes.sort})\n\n      a = TSortArray[[], [0]]\n      assert_equal([[0], [1]],\n        a.strongly_connected_components.map {|nodes| nodes.sort})\n    end\n  end\n\nend\n\n"
  },
  {
    "path": "lib/un.rb",
    "content": "# \n# = un.rb\n# \n# Copyright (c) 2003 WATANABE Hirofumi <eban@ruby-lang.org>\n# \n# This program is free software.\n# You can distribute/modify this program under the same terms of Ruby.\n# \n# == Utilities to replace common UNIX commands in Makefiles etc\n#\n# == SYNOPSIS\n#\n#   ruby -run -e cp -- [OPTION] SOURCE DEST\n#   ruby -run -e ln -- [OPTION] TARGET LINK_NAME\n#   ruby -run -e mv -- [OPTION] SOURCE DEST\n#   ruby -run -e rm -- [OPTION] FILE\n#   ruby -run -e mkdir -- [OPTION] DIRS\n#   ruby -run -e rmdir -- [OPTION] DIRS\n#   ruby -run -e install -- [OPTION] SOURCE DEST\n#   ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE\n#   ruby -run -e touch -- [OPTION] FILE\n#   ruby -run -e help [COMMAND]\n\nrequire \"fileutils\"\nrequire \"optparse\"\n\nmodule FileUtils\n#  @fileutils_label = \"\"\n  @fileutils_output = $stdout\nend\n\ndef setup(options = \"\")\n  ARGV.map! do |x|\n    case x\n    when /^-/\n      x.delete \"^-#{options}v\"\n    when /[*?\\[{]/\n      Dir[x]\n    else\n      x\n    end\n  end\n  ARGV.flatten!\n  ARGV.delete_if{|x| x == \"-\"}\n  opt_hash = {}\n  OptionParser.new do |o|\n    options.scan(/.:?/) do |s|\n      o.on(\"-\" + s.tr(\":\", \" \")) do |val|\n        opt_hash[s.delete(\":\").intern] = val\n      end\n    end\n    o.on(\"-v\") do opt_hash[:verbose] = true end\n    o.parse!\n  end\n  yield ARGV, opt_hash\nend\n\n##\n# Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY\n#\n#   ruby -run -e cp -- [OPTION] SOURCE DEST\n#\n#   -p\t\tpreserve file attributes if possible\n#   -r\t\tcopy recursively\n#   -v\t\tverbose\n#\n\ndef cp\n  setup(\"pr\") do |argv, options|\n    cmd = \"cp\"\n    cmd += \"_r\" if options.delete :r\n    options[:preserve] = true if options.delete :p\n    dest = argv.pop\n    argv = argv[0] if argv.size == 1\n    FileUtils.send cmd, argv, dest, options\n  end\nend\n\n##\n# Create a link to the specified TARGET with LINK_NAME.\n#\n#   ruby -run -e ln -- [OPTION] TARGET LINK_NAME\n#\n#   -s\t\tmake symbolic links instead of hard links\n#   -f\t\tremove existing destination files\n#   -v\t\tverbose\n#\n\ndef ln\n  setup(\"sf\") do |argv, options|\n    cmd = \"ln\"\n    cmd += \"_s\" if options.delete :s\n    options[:force] = true if options.delete :f\n    dest = argv.pop\n    argv = argv[0] if argv.size == 1\n    FileUtils.send cmd, argv, dest, options\n  end\nend\n\n##\n# Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n#\n#   ruby -run -e mv -- [OPTION] SOURCE DEST\n#\n#   -v\t\tverbose\n#\n\ndef mv\n  setup do |argv, options|\n    dest = argv.pop\n    argv = argv[0] if argv.size == 1\n    FileUtils.mv argv, dest, options\n  end\nend\n\n##\n# Remove the FILE\n#\n#   ruby -run -e rm -- [OPTION] FILE\n#\n#   -f\t\tignore nonexistent files\n#   -r\t\tremove the contents of directories recursively\n#   -v\t\tverbose\n#\n\ndef rm\n  setup(\"fr\") do |argv, options|\n    cmd = \"rm\"\n    cmd += \"_r\" if options.delete :r\n    options[:force] = true if options.delete :f\n    FileUtils.send cmd, argv, options\n  end\nend\n\n##\n# Create the DIR, if they do not already exist.\n#\n#   ruby -run -e mkdir -- [OPTION] DIR\n#\n#   -p\t\tno error if existing, make parent directories as needed\n#   -v\t\tverbose\n#\n\ndef mkdir\n  setup(\"p\") do |argv, options|\n    cmd = \"mkdir\"\n    cmd += \"_p\" if options.delete :p\n    FileUtils.send cmd, argv, options\n  end\nend\n\n##\n# Remove the DIR.\n#\n#   ruby -run -e rmdir -- [OPTION] DIR\n#\n#   -v\t\tverbose\n#\n\ndef rmdir\n  setup do |argv, options|\n    FileUtils.rmdir argv, options\n  end\nend\n\n##\n# Copy SOURCE to DEST.\n#\n#   ruby -run -e install -- [OPTION] SOURCE DEST\n#\n#   -p\t\tapply access/modification times of SOURCE files to\n#  \t\tcorresponding destination files\n#   -m\t\tset permission mode (as in chmod), instead of 0755\n#   -v\t\tverbose\n#\n\ndef install\n  setup(\"pm:\") do |argv, options|\n    options[:mode] = (mode = options.delete :m) ? mode.oct : 0755\n    options[:preserve] = true if options.delete :p\n    dest = argv.pop\n    argv = argv[0] if argv.size == 1\n    FileUtils.install argv, dest, options\n  end\nend\n\n##\n# Change the mode of each FILE to OCTAL-MODE.\n#\n#   ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE\n#\n#   -v\t\tverbose\n#\n\ndef chmod\n  setup do |argv, options|\n    mode = argv.shift.oct\n    FileUtils.chmod mode, argv, options\n  end\nend\n\n##\n# Update the access and modification times of each FILE to the current time.\n#\n#   ruby -run -e touch -- [OPTION] FILE\n#\n#   -v\t\tverbose\n#\n\ndef touch\n  setup do |argv, options|\n    FileUtils.touch argv, options\n  end\nend\n\n##\n# Display help message.\n#\n#   ruby -run -e help [COMMAND]\n#\n\ndef help\n  setup do |argv,|\n    all = argv.empty?\n    open(__FILE__) do |me|\n      while me.gets(\"##\\n\")\n\tif help = me.gets(\"\\n\\n\")\n\t  if all or argv.delete help[/-e \\w+/].sub(/-e /, \"\")\n\t    print help.gsub(/^# ?/, \"\")\n\t  end\n\tend\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/uri/common.rb",
    "content": "# = uri/common.rb\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# Revision:: $Id$\n# License:: \n#   You can redistribute it and/or modify it under the same term as Ruby.\n#\n\nmodule URI\n  module REGEXP\n    #\n    # Patterns used to parse URI's\n    #\n    module PATTERN\n      # :stopdoc:\n\n      # RFC 2396 (URI Generic Syntax)\n      # RFC 2732 (IPv6 Literal Addresses in URL's)\n      # RFC 2373 (IPv6 Addressing Architecture)\n\n      # alpha         = lowalpha | upalpha\n      ALPHA = \"a-zA-Z\"\n      # alphanum      = alpha | digit\n      ALNUM = \"#{ALPHA}\\\\d\"\n\n      # hex           = digit | \"A\" | \"B\" | \"C\" | \"D\" | \"E\" | \"F\" |\n      #                         \"a\" | \"b\" | \"c\" | \"d\" | \"e\" | \"f\"\n      HEX     = \"a-fA-F\\\\d\"\n      # escaped       = \"%\" hex hex\n      ESCAPED = \"%[#{HEX}]{2}\"\n      # mark          = \"-\" | \"_\" | \".\" | \"!\" | \"~\" | \"*\" | \"'\" |\n      #                 \"(\" | \")\"\n      # unreserved    = alphanum | mark\n      UNRESERVED = \"-_.!~*'()#{ALNUM}\"\n      # reserved      = \";\" | \"/\" | \"?\" | \":\" | \"@\" | \"&\" | \"=\" | \"+\" |\n      #                 \"$\" | \",\"\n      # reserved      = \";\" | \"/\" | \"?\" | \":\" | \"@\" | \"&\" | \"=\" | \"+\" | \n      #                 \"$\" | \",\" | \"[\" | \"]\" (RFC 2732)\n      RESERVED = \";/?:@&=+$,\\\\[\\\\]\"\n\n      # uric          = reserved | unreserved | escaped\n      URIC = \"(?:[#{UNRESERVED}#{RESERVED}]|#{ESCAPED})\"\n      # uric_no_slash = unreserved | escaped | \";\" | \"?\" | \":\" | \"@\" |\n      #                 \"&\" | \"=\" | \"+\" | \"$\" | \",\"\n      URIC_NO_SLASH = \"(?:[#{UNRESERVED};?:@&=+$,]|#{ESCAPED})\"\n      # query         = *uric\n      QUERY = \"#{URIC}*\"\n      # fragment      = *uric\n      FRAGMENT = \"#{URIC}*\"\n\n      # domainlabel   = alphanum | alphanum *( alphanum | \"-\" ) alphanum\n      DOMLABEL = \"(?:[#{ALNUM}](?:[-#{ALNUM}]*[#{ALNUM}])?)\"\n      # toplabel      = alpha | alpha *( alphanum | \"-\" ) alphanum\n      TOPLABEL = \"(?:[#{ALPHA}](?:[-#{ALNUM}]*[#{ALNUM}])?)\"\n      # hostname      = *( domainlabel \".\" ) toplabel [ \".\" ]\n      HOSTNAME = \"(?:#{DOMLABEL}\\\\.)*#{TOPLABEL}\\\\.?\"\n\n      # RFC 2373, APPENDIX B:\n      # IPv6address = hexpart [ \":\" IPv4address ]\n      # IPv4address   = 1*3DIGIT \".\" 1*3DIGIT \".\" 1*3DIGIT \".\" 1*3DIGIT\n      # hexpart = hexseq | hexseq \"::\" [ hexseq ] | \"::\" [ hexseq ]\n      # hexseq  = hex4 *( \":\" hex4)\n      # hex4    = 1*4HEXDIG\n      #\n      # XXX: This definition has a flaw. \"::\" + IPv4address must be\n      # allowed too.  Here is a replacement.\n      #\n      # IPv4address = 1*3DIGIT \".\" 1*3DIGIT \".\" 1*3DIGIT \".\" 1*3DIGIT\n      IPV4ADDR = \"\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\"\n      # hex4     = 1*4HEXDIG\n      HEX4 = \"[#{HEX}]{1,4}\"\n      # lastpart = hex4 | IPv4address\n      LASTPART = \"(?:#{HEX4}|#{IPV4ADDR})\"\n      # hexseq1  = *( hex4 \":\" ) hex4\n      HEXSEQ1 = \"(?:#{HEX4}:)*#{HEX4}\"\n      # hexseq2  = *( hex4 \":\" ) lastpart\n      HEXSEQ2 = \"(?:#{HEX4}:)*#{LASTPART}\"\n      # IPv6address = hexseq2 | [ hexseq1 ] \"::\" [ hexseq2 ]\n      IPV6ADDR = \"(?:#{HEXSEQ2}|(?:#{HEXSEQ1})?::(?:#{HEXSEQ2})?)\"\n\n      # IPv6prefix  = ( hexseq1 | [ hexseq1 ] \"::\" [ hexseq1 ] ) \"/\" 1*2DIGIT\n      # unused\n\n      # ipv6reference = \"[\" IPv6address \"]\" (RFC 2732)\n      IPV6REF = \"\\\\[#{IPV6ADDR}\\\\]\"\n\n      # host          = hostname | IPv4address\n      # host          = hostname | IPv4address | IPv6reference (RFC 2732)\n      HOST = \"(?:#{HOSTNAME}|#{IPV4ADDR}|#{IPV6REF})\"\n      # port          = *digit\n      PORT = '\\d*'\n      # hostport      = host [ \":\" port ]\n      HOSTPORT = \"#{HOST}(?::#{PORT})?\"\n\n      # userinfo      = *( unreserved | escaped |\n      #                    \";\" | \":\" | \"&\" | \"=\" | \"+\" | \"$\" | \",\" )\n      USERINFO = \"(?:[#{UNRESERVED};:&=+$,]|#{ESCAPED})*\"\n\n      # pchar         = unreserved | escaped |\n      #                 \":\" | \"@\" | \"&\" | \"=\" | \"+\" | \"$\" | \",\"\n      PCHAR = \"(?:[#{UNRESERVED}:@&=+$,]|#{ESCAPED})\"\n      # param         = *pchar\n      PARAM = \"#{PCHAR}*\"\n      # segment       = *pchar *( \";\" param )\n      SEGMENT = \"#{PCHAR}*(?:;#{PARAM})*\"\n      # path_segments = segment *( \"/\" segment )\n      PATH_SEGMENTS = \"#{SEGMENT}(?:/#{SEGMENT})*\"\n\n      # server        = [ [ userinfo \"@\" ] hostport ]\n      SERVER = \"(?:#{USERINFO}@)?#{HOSTPORT}\"\n      # reg_name      = 1*( unreserved | escaped | \"$\" | \",\" |\n      #                     \";\" | \":\" | \"@\" | \"&\" | \"=\" | \"+\" )\n      REG_NAME = \"(?:[#{UNRESERVED}$,;:@&=+]|#{ESCAPED})+\"\n      # authority     = server | reg_name\n      AUTHORITY = \"(?:#{SERVER}|#{REG_NAME})\"\n\n      # rel_segment   = 1*( unreserved | escaped |\n      #                     \";\" | \"@\" | \"&\" | \"=\" | \"+\" | \"$\" | \",\" )\n      REL_SEGMENT = \"(?:[#{UNRESERVED};@&=+$,]|#{ESCAPED})+\"\n\n      # scheme        = alpha *( alpha | digit | \"+\" | \"-\" | \".\" )\n      SCHEME = \"[#{ALPHA}][-+.#{ALPHA}\\\\d]*\"\n\n      # abs_path      = \"/\"  path_segments\n      ABS_PATH = \"/#{PATH_SEGMENTS}\"\n      # rel_path      = rel_segment [ abs_path ]\n      REL_PATH = \"#{REL_SEGMENT}(?:#{ABS_PATH})?\"\n      # net_path      = \"//\" authority [ abs_path ]\n      NET_PATH   = \"//#{AUTHORITY}(?:#{ABS_PATH})?\"\n\n      # hier_part     = ( net_path | abs_path ) [ \"?\" query ]\n      HIER_PART   = \"(?:#{NET_PATH}|#{ABS_PATH})(?:\\\\?(?:#{QUERY}))?\"\n      # opaque_part   = uric_no_slash *uric\n      OPAQUE_PART = \"#{URIC_NO_SLASH}#{URIC}*\"\n\n      # absoluteURI   = scheme \":\" ( hier_part | opaque_part )\n      ABS_URI   = \"#{SCHEME}:(?:#{HIER_PART}|#{OPAQUE_PART})\"\n      # relativeURI   = ( net_path | abs_path | rel_path ) [ \"?\" query ]\n      REL_URI = \"(?:#{NET_PATH}|#{ABS_PATH}|#{REL_PATH})(?:\\\\?#{QUERY})?\"\n\n      # URI-reference = [ absoluteURI | relativeURI ] [ \"#\" fragment ]\n      URI_REF = \"(?:#{ABS_URI}|#{REL_URI})?(?:##{FRAGMENT})?\"\n\n      # XXX:\n      X_ABS_URI = \"\n        (#{PATTERN::SCHEME}):                     (?# 1: scheme)\n        (?:\n           (#{PATTERN::OPAQUE_PART})              (?# 2: opaque)\n        |\n           (?:(?:\n             //(?:\n                 (?:(?:(#{PATTERN::USERINFO})@)?  (?# 3: userinfo)\n                   (?:(#{PATTERN::HOST})(?::(\\\\d*))?))?(?# 4: host, 5: port)\n               |\n                 (#{PATTERN::REG_NAME})           (?# 6: registry)\n               )\n             |\n             (?!//))                              (?# XXX: '//' is the mark for hostport)\n             (#{PATTERN::ABS_PATH})?              (?# 7: path)\n           )(?:\\\\?(#{PATTERN::QUERY}))?           (?# 8: query)\n        )\n        (?:\\\\#(#{PATTERN::FRAGMENT}))?            (?# 9: fragment)\n      \"\n      X_REL_URI = \"\n        (?:\n          (?:\n            //\n            (?:\n              (?:(#{PATTERN::USERINFO})@)?       (?# 1: userinfo)\n                (#{PATTERN::HOST})?(?::(\\\\d*))?  (?# 2: host, 3: port)\n            |\n              (#{PATTERN::REG_NAME})             (?# 4: registry)\n            )\n          )\n        |\n          (#{PATTERN::REL_SEGMENT})              (?# 5: rel_segment)\n        )?\n        (#{PATTERN::ABS_PATH})?                  (?# 6: abs_path)\n        (?:\\\\?(#{PATTERN::QUERY}))?              (?# 7: query)\n        (?:\\\\#(#{PATTERN::FRAGMENT}))?           (?# 8: fragment)\n      \"\n      # :startdoc:\n    end # PATTERN\n\n    # :stopdoc:\n\n    # for URI::split\n    ABS_URI = Regexp.new('^' + PATTERN::X_ABS_URI + '$', #'\n                         Regexp::EXTENDED, 'N').freeze\n    REL_URI = Regexp.new('^' + PATTERN::X_REL_URI + '$', #'\n                         Regexp::EXTENDED, 'N').freeze\n\n    # for URI::extract\n    URI_REF     = Regexp.new(PATTERN::URI_REF, false, 'N').freeze\n    ABS_URI_REF = Regexp.new(PATTERN::X_ABS_URI, Regexp::EXTENDED, 'N').freeze\n    REL_URI_REF = Regexp.new(PATTERN::X_REL_URI, Regexp::EXTENDED, 'N').freeze\n\n    # for URI::escape/unescape\n    ESCAPED = Regexp.new(PATTERN::ESCAPED, false, 'N').freeze\n    UNSAFE  = Regexp.new(\"[^#{PATTERN::UNRESERVED}#{PATTERN::RESERVED}]\",\n                         false, 'N').freeze\n\n    # for Generic#initialize\n    SCHEME   = Regexp.new(\"^#{PATTERN::SCHEME}$\", false, 'N').freeze #\"\n    USERINFO = Regexp.new(\"^#{PATTERN::USERINFO}$\", false, 'N').freeze #\"\n    HOST     = Regexp.new(\"^#{PATTERN::HOST}$\", false, 'N').freeze #\"\n    PORT     = Regexp.new(\"^#{PATTERN::PORT}$\", false, 'N').freeze #\"\n    OPAQUE   = Regexp.new(\"^#{PATTERN::OPAQUE_PART}$\", false, 'N').freeze #\"\n    REGISTRY = Regexp.new(\"^#{PATTERN::REG_NAME}$\", false, 'N').freeze #\"\n    ABS_PATH = Regexp.new(\"^#{PATTERN::ABS_PATH}$\", false, 'N').freeze #\"\n    REL_PATH = Regexp.new(\"^#{PATTERN::REL_PATH}$\", false, 'N').freeze #\"\n    QUERY    = Regexp.new(\"^#{PATTERN::QUERY}$\", false, 'N').freeze #\"\n    FRAGMENT = Regexp.new(\"^#{PATTERN::FRAGMENT}$\", false, 'N').freeze #\"\n    # :startdoc:\n  end # REGEXP\n\n  module Util # :nodoc:\n    def make_components_hash(klass, array_hash)\n      tmp = {}\n      if array_hash.kind_of?(Array) &&\n          array_hash.size == klass.component.size - 1\n        klass.component[1..-1].each_index do |i|\n          begin\n            tmp[klass.component[i + 1]] = array_hash[i].clone\n          rescue TypeError\n            tmp[klass.component[i + 1]] = array_hash[i]\n          end\n        end\n\n      elsif array_hash.kind_of?(Hash)\n        array_hash.each do |key, value|\n          begin\n            tmp[key] = value.clone\n          rescue TypeError\n            tmp[key] = value\n          end\n        end\n      else\n        raise ArgumentError, \n          \"expected Array of or Hash of components of #{klass.to_s} (#{klass.component[1..-1].join(', ')})\"\n      end\n      tmp[:scheme] = klass.to_s.sub(/\\A.*::/, '').downcase\n\n      return tmp\n    end\n    module_function :make_components_hash\n  end\n\n  module Escape\n    include REGEXP\n\n    #\n    # == Synopsis\n    #\n    #   URI.escape(str [, unsafe])\n    #\n    # == Args\n    #\n    # +str+::\n    #   String to replaces in.\n    # +unsafe+::\n    #   Regexp that matches all symbols that must be replaced with codes.\n    #   By default uses <tt>REGEXP::UNSAFE</tt>.\n    #   When this argument is a String, it represents a character set.\n    #\n    # == Description\n    #\n    # Escapes the string, replacing all unsafe characters with codes.\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   enc_uri = URI.escape(\"http://example.com/?a=\\11\\15\")\n    #   p enc_uri\n    #   # => \"http://example.com/?a=%09%0D\"\n    #\n    #   p URI.unescape(enc_uri)\n    #   # => \"http://example.com/?a=\\t\\r\"\n    #\n    #   p URI.escape(\"@?@!\", \"!?\")\n    #   # => \"@%3F@%21\"\n    #\n    def escape(str, unsafe = UNSAFE)\n      unless unsafe.kind_of?(Regexp)\n        # perhaps unsafe is String object\n        unsafe = Regexp.new(\"[#{Regexp.quote(unsafe)}]\", false, 'N')\n      end\n      str.gsub(unsafe) do |us|\n        tmp = ''\n        us.each_byte do |uc|\n          tmp << sprintf('%%%02X', uc)\n        end\n        tmp\n      end\n    end\n    alias encode escape\n    #\n    # == Synopsis\n    #\n    #   URI.unescape(str)\n    #\n    # == Args\n    #\n    # +str+::\n    #   Unescapes the string.\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   enc_uri = URI.escape(\"http://example.com/?a=\\11\\15\")\n    #   p enc_uri\n    #   # => \"http://example.com/?a=%09%0D\"\n    #\n    #   p URI.unescape(enc_uri)\n    #   # => \"http://example.com/?a=\\t\\r\"\n    #\n    def unescape(str)\n      str.gsub(ESCAPED) do\n        $&[1,2].hex.chr\n      end\n    end\n    alias decode unescape\n  end\n\n  include REGEXP\n  extend Escape\n\n  @@schemes = {}\n  \n  #\n  # Base class for all URI exceptions.\n  #\n  class Error < StandardError; end\n  #\n  # Not a URI.\n  #\n  class InvalidURIError < Error; end\n  #\n  # Not a URI component.\n  #\n  class InvalidComponentError < Error; end\n  #\n  # URI is valid, bad usage is not.\n  #\n  class BadURIError < Error; end\n\n  #\n  # == Synopsis\n  #\n  #   URI::split(uri)\n  #\n  # == Args\n  #\n  # +uri+::\n  #   String with URI.\n  #\n  # == Description\n  #\n  # Splits the string on following parts and returns array with result:\n  #\n  #   * Scheme\n  #   * Userinfo\n  #   * Host\n  #   * Port\n  #   * Registry\n  #   * Path\n  #   * Opaque\n  #   * Query\n  #   * Fragment\n  # \n  # == Usage\n  #\n  #   require 'uri'\n  #\n  #   p URI.split(\"http://www.ruby-lang.org/\")\n  #   # => [\"http\", nil, \"www.ruby-lang.org\", nil, nil, \"/\", nil, nil, nil]\n  #\n  def self.split(uri)\n    case uri\n    when ''\n      # null uri\n\n    when ABS_URI\n      scheme, opaque, userinfo, host, port, \n        registry, path, query, fragment = $~[1..-1]\n\n      # URI-reference = [ absoluteURI | relativeURI ] [ \"#\" fragment ]\n\n      # absoluteURI   = scheme \":\" ( hier_part | opaque_part )\n      # hier_part     = ( net_path | abs_path ) [ \"?\" query ]\n      # opaque_part   = uric_no_slash *uric\n\n      # abs_path      = \"/\"  path_segments\n      # net_path      = \"//\" authority [ abs_path ]\n\n      # authority     = server | reg_name\n      # server        = [ [ userinfo \"@\" ] hostport ]\n\n      if !scheme\n        raise InvalidURIError, \n          \"bad URI(absolute but no scheme): #{uri}\"\n      end\n      if !opaque && (!path && (!host && !registry))\n        raise InvalidURIError,\n          \"bad URI(absolute but no path): #{uri}\" \n      end\n\n    when REL_URI\n      scheme = nil\n      opaque = nil\n\n      userinfo, host, port, registry, \n        rel_segment, abs_path, query, fragment = $~[1..-1]\n      if rel_segment && abs_path\n        path = rel_segment + abs_path\n      elsif rel_segment\n        path = rel_segment\n      elsif abs_path\n        path = abs_path\n      end\n\n      # URI-reference = [ absoluteURI | relativeURI ] [ \"#\" fragment ]\n\n      # relativeURI   = ( net_path | abs_path | rel_path ) [ \"?\" query ]\n\n      # net_path      = \"//\" authority [ abs_path ]\n      # abs_path      = \"/\"  path_segments\n      # rel_path      = rel_segment [ abs_path ]\n\n      # authority     = server | reg_name\n      # server        = [ [ userinfo \"@\" ] hostport ]\n\n    else\n      raise InvalidURIError, \"bad URI(is not URI?): #{uri}\"\n    end\n\n    path = '' if !path && !opaque # (see RFC2396 Section 5.2)\n    ret = [\n      scheme, \n      userinfo, host, port,         # X\n      registry,                        # X\n      path,                         # Y\n      opaque,                        # Y\n      query,\n      fragment\n    ]\n    return ret\n  end\n\n  #\n  # == Synopsis\n  #\n  #   URI::parse(uri_str)\n  #\n  # == Args\n  #\n  # +uri_str+::\n  #   String with URI.\n  #\n  # == Description\n  #\n  # Creates one of the URI's subclasses instance from the string.\n  #  \n  # == Raises\n  #\n  # URI::InvalidURIError\n  #   Raised if URI given is not a correct one.\n  #\n  # == Usage\n  #\n  #   require 'uri'\n  #\n  #   uri = URI.parse(\"http://www.ruby-lang.org/\")\n  #   p uri\n  #   # => #<URI::HTTP:0x202281be URL:http://www.ruby-lang.org/>\n  #   p uri.scheme \n  #   # => \"http\" \n  #   p uri.host \n  #   # => \"www.ruby-lang.org\" \n  # \n  def self.parse(uri)\n    scheme, userinfo, host, port, \n      registry, path, opaque, query, fragment = self.split(uri)\n\n    if scheme && @@schemes.include?(scheme.upcase)\n      @@schemes[scheme.upcase].new(scheme, userinfo, host, port, \n                                   registry, path, opaque, query, \n                                   fragment)\n    else\n      Generic.new(scheme, userinfo, host, port, \n                  registry, path, opaque, query, \n                  fragment)\n    end\n  end\n\n  #\n  # == Synopsis\n  #\n  #   URI::join(str[, str, ...])\n  #\n  # == Args\n  #\n  # +str+::\n  #   String(s) to work with\n  #\n  # == Description\n  #\n  # Joins URIs.\n  #\n  # == Usage\n  #\n  #   require 'uri'\n  #\n  #   p URI.join(\"http://localhost/\",\"main.rbx\")\n  #   # => #<URI::HTTP:0x2022ac02 URL:http://localhost/main.rbx>\n  #\n  def self.join(*str)\n    u = self.parse(str[0])\n    str[1 .. -1].each do |x|\n      u = u.merge(x)\n    end\n    u\n  end\n\n  #\n  # == Synopsis\n  #\n  #   URI::extract(str[, schemes][,&blk])\n  #\n  # == Args\n  #\n  # +str+:: \n  #   String to extract URIs from.\n  # +schemes+::\n  #   Limit URI matching to a specific schemes.\n  #\n  # == Description\n  #\n  # Extracts URIs from a string. If block given, iterates through all matched URIs.\n  # Returns nil if block given or array with matches.\n  #\n  # == Usage\n  #\n  #   require \"uri\"\n  #\n  #   URI.extract(\"text here http://foo.example.org/bla and here mailto:test@example.com and here also.\")\n  #   # => [\"http://foo.example.com/bla\", \"mailto:test@example.com\"]\n  #\n  def self.extract(str, schemes = nil, &block)\n    if block_given?\n      str.scan(regexp(schemes)) { yield $& }\n      nil\n    else\n      result = []\n      str.scan(regexp(schemes)) { result.push $& }\n      result\n    end\n  end\n\n  #\n  # == Synopsis\n  #\n  #   URI::regexp([match_schemes])\n  #\n  # == Args\n  #\n  # +match_schemes+:: \n  #   Array of schemes. If given, resulting regexp matches to URIs\n  #   whose scheme is one of the match_schemes.\n  # \n  # == Description\n  # Returns a Regexp object which matches to URI-like strings.\n  # The Regexp object returned by this method includes arbitrary\n  # number of capture group (parentheses).  Never rely on it's number.\n  # \n  # == Usage\n  #\n  #   require 'uri'\n  #\n  #   # extract first URI from html_string\n  #   html_string.slice(URI.regexp)\n  # \n  #   # remove ftp URIs\n  #   html_string.sub(URI.regexp(['ftp'])\n  # \n  #   # You should not rely on the number of parentheses\n  #   html_string.scan(URI.regexp) do |*matches|\n  #     p $&\n  #   end\n  #\n  def self.regexp(schemes = nil)\n    unless schemes\n      ABS_URI_REF\n    else\n      /(?=#{Regexp.union(*schemes)}:)#{PATTERN::X_ABS_URI}/xn\n    end\n  end\n\nend\n\nmodule Kernel\n  # alias for URI.parse.\n  #\n  # This method is introduced at 1.8.2.\n  def URI(uri_str) # :doc:\n    URI.parse(uri_str)\n  end\n  module_function :URI\nend\n"
  },
  {
    "path": "lib/uri/ftp.rb",
    "content": "#\n# = uri/ftp.rb\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# License:: You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n#\n\nrequire 'uri/generic'\n\nmodule URI\n\n  #\n  # FTP URI syntax is defined by RFC1738 section 3.2.\n  #\n  class FTP < Generic\n    DEFAULT_PORT = 21\n\n    COMPONENT = [\n      :scheme, \n      :userinfo, :host, :port,\n      :path, :typecode\n    ].freeze\n    #\n    # Typecode is \"a\", \"i\" or \"d\". \n    #\n    # * \"a\" indicates a text file (the FTP command was ASCII)\n    # * \"i\" indicates a binary file (FTP command IMAGE)\n    # * \"d\" indicates the contents of a directory should be displayed\n    #\n    TYPECODE = ['a', 'i', 'd'].freeze\n    TYPECODE_PREFIX = ';type='.freeze\n\n    def self.new2(user, password, host, port, path, \n                  typecode = nil, arg_check = true)\n      typecode = nil if typecode.size == 0\n      if typecode && !TYPECODE.include?(typecode)\n        raise ArgumentError,\n          \"bad typecode is specified: #{typecode}\"\n      end\n\n      # do escape\n\n      self.new('ftp',\n               [user, password], \n               host, port, nil, \n               typecode ? path + TYPECODE_PREFIX + typecode : path, \n               nil, nil, nil, arg_check)\n    end\n\n    #\n    # == Description\n    #\n    # Creates a new URI::FTP object from components, with syntax checking.  \n    #\n    # The components accepted are +userinfo+, +host+, +port+, +path+ and \n    # +typecode+.\n    #\n    # The components should be provided either as an Array, or as a Hash \n    # with keys formed by preceding the component names with a colon. \n    #\n    # If an Array is used, the components must be passed in the order\n    # [userinfo, host, port, path, typecode]\n    #\n    # If the path supplied is absolute, it will be escaped in order to\n    # make it absolute in the URI. Examples:\n    #\n    #     require 'uri'\n    #\n    #     uri = URI::FTP.build(['user:password', 'ftp.example.com', nil, \n    #       '/path/file.> zip', 'i'])\n    #     puts uri.to_s  ->  ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=a\n    #\n    #     uri2 = URI::FTP.build({:host => 'ftp.example.com', \n    #       :path => 'ruby/src'})\n    #     puts uri2.to_s  ->  ftp://ftp.example.com/ruby/src\n    #\n    def self.build(args)\n\n      # Fix the incoming path to be generic URL syntax\n      # FTP path  ->  URL path\n      # foo/bar       /foo/bar\n      # /foo/bar      /%2Ffoo/bar\n      #\n      if args.kind_of?(Array)\n        args[3] = '/' + args[3].sub(/^\\//, '%2F')\n      else\n        args[:path] = '/' + args[:path].sub(/^\\//, '%2F')\n      end\n\n      tmp = Util::make_components_hash(self, args)\n\n      if tmp[:typecode]\n        if tmp[:typecode].size == 1\n          tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode] \n        end\n        tmp[:path] << tmp[:typecode]\n      end\n\n      return super(tmp)\n    end\n\n    #\n    # == Description\n    #\n    # Creates a new URI::FTP object from generic URL components with no\n    # syntax checking.\n    #\n    # Unlike build(), this method does not escape the path component as\n    # required by RFC1738; instead it is treated as per RFC2396.\n    #\n    # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, \n    # +opaque+, +query+ and +fragment+, in that order.\n    #\n    def initialize(*arg)\n      super(*arg)\n      @typecode = nil\n      tmp = @path.index(TYPECODE_PREFIX)\n      if tmp\n        typecode = @path[tmp + TYPECODE_PREFIX.size..-1]\n        self.set_path(@path[0..tmp - 1])\n        \n        if arg[-1]\n          self.typecode = typecode\n        else\n          self.set_typecode(typecode)\n        end\n      end\n    end\n    attr_reader :typecode\n\n    def check_typecode(v)\n      if TYPECODE.include?(v)\n        return true\n      else\n        raise InvalidComponentError,\n          \"bad typecode(expected #{TYPECODE.join(', ')}): #{v}\"\n      end\n    end\n    private :check_typecode\n\n    def set_typecode(v)\n      @typecode = v\n    end\n    protected :set_typecode\n\n    def typecode=(typecode)\n      check_typecode(typecode)\n      set_typecode(typecode)\n      typecode\n    end\n\n    def merge(oth) # :nodoc:\n      tmp = super(oth)\n      if self != tmp\n        tmp.set_typecode(oth.typecode)\n      end\n\n      return tmp\n    end\n\n    # Returns the path from an FTP URI.\n    #\n    # RFC 1738 specifically states that the path for an FTP URI does not\n    # include the / which separates the URI path from the URI host. Example:\n    #\n    #     ftp://ftp.example.com/pub/ruby \n    #\n    # The above URI indicates that the client should connect to \n    # ftp.example.com then cd pub/ruby from the initial login directory.\n    #\n    # If you want to cd to an absolute directory, you must include an\n    # escaped / (%2F) in the path. Example:\n    #\n    #     ftp://ftp.example.com/%2Fpub/ruby\n    #\n    # This method will then return \"/pub/ruby\"\n    #\n    def path\n      return @path.sub(/^\\//,'').sub(/^%2F/i,'/')\n    end\n\n    def to_s\n      save_path = nil\n      if @typecode\n        save_path = @path\n        @path = @path + TYPECODE_PREFIX + @typecode\n      end\n      str = super\n      if @typecode\n        @path = save_path\n      end\n\n      return str\n    end\n  end\n  @@schemes['FTP'] = FTP\nend\n"
  },
  {
    "path": "lib/uri/generic.rb",
    "content": "#\n# = uri/generic.rb\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# License:: You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n#\n\nrequire 'uri/common'\n\nmodule URI\n  \n  #\n  # Base class for all URI classes.\n  # Implements generic URI syntax as per RFC 2396.\n  #\n  class Generic\n    include URI\n    include REGEXP\n\n    DEFAULT_PORT = nil\n\n    #\n    # Returns default port\n    #\n    def self.default_port\n      self::DEFAULT_PORT\n    end\n\n    def default_port\n      self.class.default_port\n    end\n\n    COMPONENT = [\n      :scheme, \n      :userinfo, :host, :port, :registry, \n      :path, :opaque, \n      :query, \n      :fragment\n    ].freeze\n\n    #\n    # Components of the URI in the order.\n    #\n    def self.component\n      self::COMPONENT\n    end\n\n    USE_REGISTRY = false\n\n    #\n    # DOC: FIXME!\n    #\n    def self.use_registry\n      self::USE_REGISTRY\n    end\n\n    #\n    # == Synopsis\n    #\n    # See #new\n    #\n    # == Description\n    #\n    # At first, tries to create a new URI::Generic instance using\n    # URI::Generic::build. But, if exception URI::InvalidComponentError is raised, \n    # then it URI::Escape.escape all URI components and tries again.\n    #\n    #\n    def self.build2(args)\n      begin\n        return self.build(args)\n      rescue InvalidComponentError\n        if args.kind_of?(Array)\n          return self.build(args.collect{|x| \n            if x\n              URI.escape(x)\n            else\n              x\n            end\n          })\n        elsif args.kind_of?(Hash)\n          tmp = {}\n          args.each do |key, value|\n            tmp[key] = if value\n                URI.escape(value)\n              else\n                value\n              end\n          end\n          return self.build(tmp)\n        end\n      end\n    end\n\n    #\n    # == Synopsis\n    #\n    # See #new\n    #\n    # == Description\n    #\n    # Creates a new URI::Generic instance from components of URI::Generic\n    # with check.  Components are: scheme, userinfo, host, port, registry, path,\n    # opaque, query and fragment. You can provide arguments either by an Array or a Hash.\n    # See #new for hash keys to use or for order of array items.\n    #\n    def self.build(args)\n      if args.kind_of?(Array) &&\n          args.size == ::URI::Generic::COMPONENT.size\n        tmp = args\n      elsif args.kind_of?(Hash)\n        tmp = ::URI::Generic::COMPONENT.collect do |c|\n          if args.include?(c)\n            args[c]\n          else\n            nil\n          end\n        end\n      else\n        raise ArgumentError, \n        \"expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})\"\n      end\n\n      tmp << true\n      return self.new(*tmp)\n    end\n    #\n    # == Args\n    #\n    # +scheme+::\n    #   Protocol scheme, i.e. 'http','ftp','mailto' and so on.\n    # +userinfo+::\n    #   User name and password, i.e. 'sdmitry:bla'\n    # +host+::\n    #   Server host name\n    # +port+::\n    #   Server port\n    # +registry+::\n    #   DOC: FIXME!\n    # +path+::\n    #   Path on server\n    # +opaque+::\n    #   DOC: FIXME!\n    # +query+::\n    #   Query data\n    # +fragment+::\n    #   A part of URI after '#' sign\n    # +arg_check+::\n    #   Check arguments [false by default]\n    #\n    # == Description\n    #\n    # Creates a new URI::Generic instance from ``generic'' components without check.\n    #\n    def initialize(scheme, \n                   userinfo, host, port, registry, \n                   path, opaque, \n                   query, \n                   fragment,\n                   arg_check = false)\n      @scheme = nil\n      @user = nil\n      @password = nil\n      @host = nil\n      @port = nil\n      @path = nil\n      @query = nil\n      @opaque = nil\n      @registry = nil\n      @fragment = nil\n\n      if arg_check\n        self.scheme = scheme\n        self.userinfo = userinfo\n        self.host = host\n        self.port = port\n        self.path = path\n        self.query = query\n        self.opaque = opaque\n        self.registry = registry\n        self.fragment = fragment\n      else\n        self.set_scheme(scheme)\n        self.set_userinfo(userinfo)\n        self.set_host(host)\n        self.set_port(port)\n        self.set_path(path)\n        self.set_query(query)\n        self.set_opaque(opaque)\n        self.set_registry(registry)\n        self.set_fragment(fragment)\n      end\n      if @registry && !self.class.use_registry\n        raise InvalidURIError, \n          \"the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)\"\n      end\n      \n      @scheme.freeze if @scheme\n      self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)\n      self.set_port(self.default_port) if self.default_port && !@port\n    end\n    attr_reader :scheme\n    attr_reader :host\n    attr_reader :port\n    attr_reader :registry\n    attr_reader :path\n    attr_reader :query\n    attr_reader :opaque\n    attr_reader :fragment\n\n    # replace self by other URI object\n    def replace!(oth)\n      if self.class != oth.class\n        raise ArgumentError, \"expected #{self.class} object\"\n      end\n\n      component.each do |c|\n        self.__send__(\"#{c}=\", oth.__send__(c))\n      end\n    end\n    private :replace!\n\n    def component\n      self.class.component\n    end\n\n    def check_scheme(v)\n      if v && SCHEME !~ v\n        raise InvalidComponentError,\n          \"bad component(expected scheme component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_scheme\n\n    def set_scheme(v)\n      @scheme = v\n    end\n    protected :set_scheme\n\n    def scheme=(v)\n      check_scheme(v)\n      set_scheme(v)\n      v\n    end\n\n    def check_userinfo(user, password = nil)\n      if !password\n        user, password = split_userinfo(user)\n      end\n      check_user(user)\n      check_password(password, user)\n\n      return true\n    end\n    private :check_userinfo\n\n    def check_user(v)\n      if @registry || @opaque\n        raise InvalidURIError, \n          \"can not set user with registry or opaque\"\n      end\n\n      return v unless v\n\n      if USERINFO !~ v\n        raise InvalidComponentError,\n          \"bad component(expected userinfo component or user component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_user\n\n    def check_password(v, user = @user)\n      if @registry || @opaque\n        raise InvalidURIError, \n          \"can not set password with registry or opaque\"\n      end\n      return v unless v\n\n      if !user\n        raise InvalidURIError,\n          \"password component depends user component\"\n      end\n\n      if USERINFO !~ v\n        raise InvalidComponentError,\n          \"bad component(expected user component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_password\n\n    #\n    # Sets userinfo, argument is string like 'name:pass'\n    #\n    def userinfo=(userinfo)\n      if userinfo.nil?\n        return nil\n      end\n      check_userinfo(*userinfo)\n      set_userinfo(*userinfo)\n      # returns userinfo\n    end\n\n    def user=(user)\n      check_user(user)\n      set_user(user)\n      # returns user\n    end\n    \n    def password=(password)\n      check_password(password)\n      set_password(password)\n      # returns password\n    end\n\n    def set_userinfo(user, password = nil)\n      unless password \n        user, password = split_userinfo(user)\n      end\n      @user     = user\n      @password = password if password\n\n      [@user, @password]\n    end\n    protected :set_userinfo\n\n    def set_user(v)\n      set_userinfo(v, @password)\n      v\n    end\n    protected :set_user\n\n    def set_password(v)\n      @password = v\n      # returns v\n    end\n    protected :set_password\n\n    def split_userinfo(ui)\n      return nil, nil unless ui\n      user, password = ui.split(/:/, 2)\n\n      return user, password\n    end\n    private :split_userinfo\n\n    def escape_userpass(v)\n      v = URI.escape(v, /[@:\\/]/o) # RFC 1738 section 3.1 #/\n    end\n    private :escape_userpass\n\n    def userinfo\n      if @user.nil?\n        nil\n      elsif @password.nil?\n        @user\n      else\n        @user + ':' + @password\n      end\n    end\n\n    def user\n      @user\n    end\n\n    def password\n      @password\n    end\n\n    def check_host(v)\n      return v unless v\n\n      if @registry || @opaque\n        raise InvalidURIError, \n          \"can not set host with registry or opaque\"\n      elsif HOST !~ v\n        raise InvalidComponentError,\n          \"bad component(expected host component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_host\n\n    def set_host(v)\n      @host = v\n    end\n    protected :set_host\n\n    def host=(v)\n      check_host(v)\n      set_host(v)\n      v\n    end\n\n    def check_port(v)\n      return v unless v\n\n      if @registry || @opaque\n        raise InvalidURIError, \n          \"can not set port with registry or opaque\"\n      elsif !v.kind_of?(Fixnum) && PORT !~ v\n        raise InvalidComponentError,\n          \"bad component(expected port component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_port\n\n    def set_port(v)\n      unless !v || v.kind_of?(Fixnum)\n        if v.empty?\n          v = nil\n        else\n          v = v.to_i\n        end\n      end\n      @port = v\n    end\n    protected :set_port\n\n    def port=(v)\n      check_port(v)\n      set_port(v)\n      port\n    end\n\n    def check_registry(v)\n      return v unless v\n\n      # raise if both server and registry are not nil, because:\n      # authority     = server | reg_name\n      # server        = [ [ userinfo \"@\" ] hostport ]\n      if @host || @port || @user # userinfo = @user + ':' + @password\n        raise InvalidURIError, \n          \"can not set registry with host, port, or userinfo\"\n      elsif v && REGISTRY !~ v\n        raise InvalidComponentError,\n          \"bad component(expected registry component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_registry\n\n    def set_registry(v)\n      @registry = v\n    end\n    protected :set_registry\n\n    def registry=(v)\n      check_registry(v)\n      set_registry(v)\n      v\n    end\n\n    def check_path(v)\n      # raise if both hier and opaque are not nil, because:\n      # absoluteURI   = scheme \":\" ( hier_part | opaque_part )\n      # hier_part     = ( net_path | abs_path ) [ \"?\" query ]\n      if v && @opaque\n        raise InvalidURIError, \n          \"path conflicts with opaque\"\n      end\n\n      if @scheme\n        if v && v != '' && ABS_PATH !~ v\n          raise InvalidComponentError, \n            \"bad component(expected absolute path component): #{v}\"\n        end\n      else\n        if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v\n          raise InvalidComponentError, \n            \"bad component(expected relative path component): #{v}\"\n        end\n      end\n\n      return true\n    end\n    private :check_path\n\n    def set_path(v)\n      @path = v\n    end\n    protected :set_path\n\n    def path=(v)\n      check_path(v)\n      set_path(v)\n      v\n    end\n\n    def check_query(v)\n      return v unless v\n\n      # raise if both hier and opaque are not nil, because:\n      # absoluteURI   = scheme \":\" ( hier_part | opaque_part )\n      # hier_part     = ( net_path | abs_path ) [ \"?\" query ]\n      if @opaque\n        raise InvalidURIError, \n          \"query conflicts with opaque\"\n      end\n\n      if v && v != '' && QUERY !~ v\n          raise InvalidComponentError, \n            \"bad component(expected query component): #{v}\"\n        end\n\n      return true\n    end\n    private :check_query\n\n    def set_query(v)\n      @query = v\n    end\n    protected :set_query\n\n    def query=(v)\n      check_query(v)\n      set_query(v)\n      v\n    end\n\n    def check_opaque(v)\n      return v unless v\n\n      # raise if both hier and opaque are not nil, because:\n      # absoluteURI   = scheme \":\" ( hier_part | opaque_part )\n      # hier_part     = ( net_path | abs_path ) [ \"?\" query ]\n      if @host || @port || @user || @path  # userinfo = @user + ':' + @password\n        raise InvalidURIError, \n          \"can not set opaque with host, port, userinfo or path\"\n      elsif v && OPAQUE !~ v\n        raise InvalidComponentError,\n          \"bad component(expected opaque component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_opaque\n\n    def set_opaque(v)\n      @opaque = v\n    end\n    protected :set_opaque\n\n    def opaque=(v)\n      check_opaque(v)\n      set_opaque(v)\n      v\n    end\n\n    def check_fragment(v)\n      return v unless v\n\n      if v && v != '' && FRAGMENT !~ v\n        raise InvalidComponentError, \n          \"bad component(expected fragment component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_fragment\n\n    def set_fragment(v)\n      @fragment = v\n    end\n    protected :set_fragment\n\n    def fragment=(v)\n      check_fragment(v)\n      set_fragment(v)\n      v\n    end\n\n    #\n    # Checks if URI has a path\n    #\n    def hierarchical?\n      if @path\n        true\n      else\n        false\n      end\n    end\n\n    #\n    # Checks if URI is an absolute one\n    #\n    def absolute?\n      if @scheme\n        true\n      else\n        false\n      end\n    end\n    alias absolute absolute?\n\n    #\n    # Checks if URI is relative\n    #\n    def relative?\n      !absolute?\n    end\n\n    def split_path(path)\n      path.split(%r{/+}, -1)\n    end\n    private :split_path\n\n    def merge_path(base, rel)\n\n      # RFC2396, Section 5.2, 5)\n      # RFC2396, Section 5.2, 6)\n      base_path = split_path(base)\n      rel_path  = split_path(rel)\n\n      # RFC2396, Section 5.2, 6), a)\n      base_path << '' if base_path.last == '..'\n      while i = base_path.index('..')\n        base_path.slice!(i - 1, 2)\n      end\n\n      if (first = rel_path.first) and first.empty?\n        base_path.clear\n        rel_path.shift\n      end\n\n      # RFC2396, Section 5.2, 6), c)\n      # RFC2396, Section 5.2, 6), d)\n      rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'\n      rel_path.delete('.')\n\n      # RFC2396, Section 5.2, 6), e)\n      tmp = []\n      rel_path.each do |x|\n        if x == '..' &&\n            !(tmp.empty? || tmp.last == '..')\n          tmp.pop\n        else\n          tmp << x\n        end\n      end\n\n      add_trailer_slash = !tmp.empty?\n      if base_path.empty?\n        base_path = [''] # keep '/' for root directory\n      elsif add_trailer_slash\n        base_path.pop\n      end\n      while x = tmp.shift\n        if x == '..'\n          # RFC2396, Section 4\n          # a .. or . in an absolute path has no special meaning\n          base_path.pop if base_path.size > 1\n        else\n          # if x == '..'\n          #   valid absolute (but abnormal) path \"/../...\"\n          # else\n          #   valid absolute path\n          # end\n          base_path << x\n          tmp.each {|t| base_path << t}\n          add_trailer_slash = false\n          break\n        end\n      end\n      base_path.push('') if add_trailer_slash\n\n      return base_path.join('/')\n    end\n    private :merge_path\n\n    #\n    # == Args\n    #\n    # +oth+::\n    #    URI or String\n    #\n    # == Description\n    #\n    # Destructive form of #merge\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   uri = URI.parse(\"http://my.example.com\")\n    #   uri.merge!(\"/main.rbx?page=1\")\n    #   p uri\n    #   # =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>\n    #\n    def merge!(oth)\n      t = merge(oth)\n      if self == t\n        nil\n      else\n        replace!(t)\n        self\n      end\n    end\n\n    #\n    # == Args\n    #\n    # +oth+::\n    #    URI or String\n    #\n    # == Description\n    #\n    # Merges two URI's.\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   uri = URI.parse(\"http://my.example.com\")\n    #   p uri.merge(\"/main.rbx?page=1\")\n    #   # =>  #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>\n    #\n    def merge(oth)\n      begin\n        base, rel = merge0(oth)\n      rescue\n        raise $!.class, $!.message\n      end\n\n      if base == rel\n        return base\n      end\n\n      authority = rel.userinfo || rel.host || rel.port\n\n      # RFC2396, Section 5.2, 2)\n      if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query\n        base.set_fragment(rel.fragment) if rel.fragment\n        return base\n      end\n\n      base.set_query(nil)\n      base.set_fragment(nil)\n\n      # RFC2396, Section 5.2, 4)\n      if !authority\n        base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path\n      else\n        # RFC2396, Section 5.2, 4)\n        base.set_path(rel.path) if rel.path\n      end\n\n      # RFC2396, Section 5.2, 7)\n      base.set_userinfo(rel.userinfo) if rel.userinfo\n      base.set_host(rel.host)         if rel.host\n      base.set_port(rel.port)         if rel.port\n      base.set_query(rel.query)       if rel.query\n      base.set_fragment(rel.fragment) if rel.fragment\n\n      return base\n    end # merge\n    alias + merge\n\n    # return base and rel.\n    # you can modify `base', but can not `rel'.\n    def merge0(oth)\n      case oth\n      when Generic\n      when String\n        oth = URI.parse(oth)\n      else\n        raise ArgumentError,\n          \"bad argument(expected URI object or URI string)\"\n      end\n\n      if self.relative? && oth.relative?\n        raise BadURIError, \n          \"both URI are relative\"\n      end\n\n      if self.absolute? && oth.absolute?\n        #raise BadURIError, \n        #  \"both URI are absolute\"\n        # hmm... should return oth for usability?\n        return oth, oth\n      end\n\n      if self.absolute?\n        return self.dup, oth\n      else\n        return oth, oth\n      end\n    end\n    private :merge0\n\n    def route_from_path(src, dst)\n      # RFC2396, Section 4.2\n      return '' if src == dst\n\n      src_path = split_path(src)\n      dst_path = split_path(dst)\n\n      # hmm... dst has abnormal absolute path, \n      # like \"/./\", \"/../\", \"/x/../\", ...\n      if dst_path.include?('..') ||\n          dst_path.include?('.')\n        return dst.dup\n      end\n\n      src_path.pop\n\n      # discard same parts\n      while dst_path.first == src_path.first\n        break if dst_path.empty?\n\n        src_path.shift\n        dst_path.shift\n      end\n\n      tmp = dst_path.join('/')\n\n      # calculate\n      if src_path.empty?\n        if tmp.empty?\n          return './'\n        elsif dst_path.first.include?(':') # (see RFC2396 Section 5)\n          return './' + tmp\n        else\n          return tmp\n        end\n      end\n\n      return '../' * src_path.size + tmp\n    end\n    private :route_from_path\n\n    def route_from0(oth)\n      case oth\n      when Generic\n      when String\n        oth = URI.parse(oth)\n      else\n        raise ArgumentError,\n          \"bad argument(expected URI object or URI string)\"\n      end\n\n      if self.relative?\n        raise BadURIError, \n          \"relative URI: #{self}\"\n      end\n      if oth.relative?\n        raise BadURIError, \n          \"relative URI: #{oth}\"\n      end\n\n      if self.scheme != oth.scheme\n        return self, self.dup\n      end\n      rel = URI::Generic.new(nil, # it is relative URI\n                             self.userinfo, self.host, self.port, \n                             self.registry, self.path, self.opaque,\n                             self.query, self.fragment)\n\n      if rel.userinfo != oth.userinfo ||\n          rel.host.to_s.downcase != oth.host.to_s.downcase ||\n          rel.port != oth.port\n\tif self.userinfo.nil? && self.host.nil?\n\t  return self, self.dup\n\tend\n        rel.set_port(nil) if rel.port == oth.default_port\n        return rel, rel\n      end\n      rel.set_userinfo(nil)\n      rel.set_host(nil)\n      rel.set_port(nil)\n\n      if rel.path && rel.path == oth.path\n        rel.set_path('')\n        rel.set_query(nil) if rel.query == oth.query\n        return rel, rel\n      elsif rel.opaque && rel.opaque == oth.opaque\n        rel.set_opaque('')\n        rel.set_query(nil) if rel.query == oth.query\n        return rel, rel\n      end\n\n      # you can modify `rel', but can not `oth'.\n      return oth, rel\n    end\n    private :route_from0\n    #\n    # == Args\n    #\n    # +oth+::\n    #    URI or String\n    #\n    # == Description\n    #\n    # Calculates relative path from oth to self\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   uri = URI.parse('http://my.example.com/main.rbx?page=1')\n    #   p uri.route_from('http://my.example.com')\n    #   #=> #<URI::Generic:0x20218858 URL:/main.rbx?page=1>\n    #\n    def route_from(oth)\n      # you can modify `rel', but can not `oth'.\n      begin\n        oth, rel = route_from0(oth)\n      rescue\n        raise $!.class, $!.message\n      end\n      if oth == rel\n        return rel\n      end\n\n      rel.set_path(route_from_path(oth.path, self.path))\n      if rel.path == './' && self.query\n        # \"./?foo\" -> \"?foo\"\n        rel.set_path('')\n      end\n\n      return rel\n    end\n\n    alias - route_from\n\n    #\n    # == Args\n    #\n    # +oth+::\n    #    URI or String\n    #\n    # == Description\n    #\n    # Calculates relative path to oth from self\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   uri = URI.parse('http://my.example.com')\n    #   p uri.route_to('http://my.example.com/main.rbx?page=1')\n    #   #=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>\n    #    \n    def route_to(oth)\n      case oth\n      when Generic\n      when String\n        oth = URI.parse(oth)\n      else\n        raise ArgumentError,\n          \"bad argument(expected URI object or URI string)\"\n      end\n\n      oth.route_from(self)\n    end\n\n    #\n    # Returns normalized URI\n    # \n    def normalize\n      uri = dup\n      uri.normalize!\n      uri\n    end\n\n    #\n    # Destructive version of #normalize\n    #\n    def normalize!\n      if path && path == ''\n        set_path('/')\n      end\n      if host && host != host.downcase\n        set_host(self.host.downcase)\n      end        \n    end\n\n    def path_query\n      str = @path\n      if @query\n        str += '?' + @query\n      end\n      str\n    end\n    private :path_query\n\n    #\n    # Constructs String from URI\n    # \n    def to_s\n      str = ''\n      if @scheme\n        str << @scheme\n        str << ':'\n      end\n\n      if @opaque\n        str << @opaque\n\n      else\n        if @registry\n          str << @registry\n        else\n          if @host\n            str << '//'\n          end\n          if self.userinfo\n            str << self.userinfo\n            str << '@'\n          end\n          if @host\n            str << @host\n          end\n          if @port && @port != self.default_port\n            str << ':'\n            str << @port.to_s\n          end\n        end\n\n        str << path_query\n      end\n\n      if @fragment\n        str << '#'\n        str << @fragment\n      end\n\n      str\n    end\n\n    #\n    # Compares to URI's\n    #\n    def ==(oth)\n      if self.class == oth.class\n        self.normalize.component_ary == oth.normalize.component_ary\n      else\n        false\n      end\n    end\n\n    def hash\n      self.component_ary.hash\n    end\n\n    def eql?(oth)\n      self.component_ary.eql?(oth.component_ary)\n    end\n\n=begin\n\n--- URI::Generic#===(oth)\n\n=end\n#    def ===(oth)\n#      raise NotImplementedError\n#    end\n\n=begin\n=end\n    def component_ary\n      component.collect do |x|\n        self.send(x)\n      end\n    end\n    protected :component_ary\n\n    # == Args\n    #\n    # +components+::\n    #    Multiple Symbol arguments defined in URI::HTTP\n    #\n    # == Description\n    #\n    # Selects specified components from URI\n    #\n    # == Usage\n    #\n    #   require 'uri'\n    #\n    #   uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx')\n    #   p uri.select(:userinfo, :host, :path)\n    #   # => [\"myuser:mypass\", \"my.example.com\", \"/test.rbx\"]\n    #\n    def select(*components)\n      components.collect do |c|\n        if component.include?(c)\n          self.send(c)\n        else\n          raise ArgumentError, \n            \"expected of components of #{self.class} (#{self.class.component.join(', ')})\"\n        end\n      end\n    end\n\n    @@to_s = Kernel.instance_method(:to_s)\n    def inspect\n      @@to_s.bind(self).call.sub!(/>\\z/) {\" URL:#{self}>\"}\n    end\n\n    def coerce(oth)\n      case oth\n      when String\n        oth = URI.parse(oth)\n      else\n        super\n      end\n\n      return oth, self\n    end\n  end\nend\n"
  },
  {
    "path": "lib/uri/http.rb",
    "content": "#\n# = uri/http.rb\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# License:: You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n#\n\nrequire 'uri/generic'\n\nmodule URI\n\n  #\n  # The syntax of HTTP URIs is defined in RFC1738 section 3.3.\n  #\n  # Note that the Ruby URI library allows HTTP URLs containing usernames and\n  # passwords. This is not legal as per the RFC, but used to be \n  # supported in Internet Explorer 5 and 6, before the MS04-004 security \n  # update. See <URL:http://support.microsoft.com/kb/834489>.\n  #\n  class HTTP < Generic\n    DEFAULT_PORT = 80\n\n    COMPONENT = [\n      :scheme, \n      :userinfo, :host, :port, \n      :path, \n      :query, \n      :fragment\n    ].freeze\n\n    #\n    # == Description\n    #\n    # Create a new URI::HTTP object from components, with syntax checking.\n    #\n    # The components accepted are userinfo, host, port, path, query and\n    # fragment.\n    #\n    # The components should be provided either as an Array, or as a Hash \n    # with keys formed by preceding the component names with a colon. \n    #\n    # If an Array is used, the components must be passed in the order\n    # [userinfo, host, port, path, query, fragment].\n    #\n    # Example:\n    #\n    #     newuri = URI::HTTP.build({:host => 'www.example.com', \n    #       :path> => '/foo/bar'})\n    #\n    #     newuri = URI::HTTP.build([nil, \"www.example.com\", nil, \"/path\", \n    #       \"query\", 'fragment'])\n    #\n    # Currently, if passed userinfo components this method generates \n    # invalid HTTP URIs as per RFC 1738.\n    #\n    def self.build(args)\n      tmp = Util::make_components_hash(self, args)\n      return super(tmp)\n    end\n\n    #\n    # == Description\n    #\n    # Create a new URI::HTTP object from generic URI components as per\n    # RFC 2396. No HTTP-specific syntax checking (as per RFC 1738) is \n    # performed.\n    #\n    # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+, \n    # +opaque+, +query+ and +fragment+, in that order.\n    #\n    # Example:\n    #\n    #     uri = URI::HTTP.new(['http', nil, \"www.example.com\", nil, \"/path\",\n    #       \"query\", 'fragment'])\n    #\n    def initialize(*arg)\n      super(*arg)\n    end\n\n    #\n    # == Description\n    #\n    # Returns the full path for an HTTP request, as required by Net::HTTP::Get.\n    #\n    # If the URI contains a query, the full path is URI#path + '?' + URI#query.\n    # Otherwise, the path is simply URI#path.\n    #\n    def request_uri\n      r = path_query\n      if r[0] != ?/\n        r = '/' + r\n      end\n\n      r\n    end\n  end\n\n  @@schemes['HTTP'] = HTTP\nend\n"
  },
  {
    "path": "lib/uri/https.rb",
    "content": "#\n# = uri/https.rb\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# License:: You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n#\n\nrequire 'uri/http'\n\nmodule URI\n\n  # The default port for HTTPS URIs is 443, and the scheme is 'https:' rather\n  # than 'http:'. Other than that, HTTPS URIs are identical to HTTP URIs;\n  # see URI::HTTP.\n  class HTTPS < HTTP\n    DEFAULT_PORT = 443\n  end\n  @@schemes['HTTPS'] = HTTPS\nend\n"
  },
  {
    "path": "lib/uri/ldap.rb",
    "content": "#\n# = uri/ldap.rb\n#\n# Author:: \n#  Takaaki Tateishi <ttate@jaist.ac.jp>\n#  Akira Yamada <akira@ruby-lang.org>\n# License:: \n#   URI::LDAP is copyrighted free software by Takaaki Tateishi and Akira Yamada.\n#   You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n#\n\nrequire 'uri/generic'\n\nmodule URI\n\n  #\n  # LDAP URI SCHEMA (described in RFC2255)\n  # ldap://<host>/<dn>[?<attrs>[?<scope>[?<filter>[?<extensions>]]]]\n  #\n  class LDAP < Generic\n\n    DEFAULT_PORT = 389\n    \n    COMPONENT = [\n      :scheme,\n      :host, :port,\n      :dn,\n      :attributes,\n      :scope,\n      :filter,\n      :extensions,\n    ].freeze\n\n    SCOPE = [\n      SCOPE_ONE = 'one',\n      SCOPE_SUB = 'sub',\n      SCOPE_BASE = 'base',\n    ].freeze\n\n    def self.build(args)\n      tmp = Util::make_components_hash(self, args)\n\n      if tmp[:dn]\n        tmp[:path] = tmp[:dn]\n      end\n\n      query = []\n      [:extensions, :filter, :scope, :attributes].collect do |x|\n        next if !tmp[x] && query.size == 0\n        query.unshift(tmp[x])\n      end\n\n      tmp[:query] = query.join('?')\n\n      return super(tmp)\n    end\n\n    def initialize(*arg)\n      super(*arg)\n\n      if @fragment\n        raise InvalidURIError, 'bad LDAP URL'\n      end\n\n      parse_dn\n      parse_query\n    end\n\n    def parse_dn\n      @dn = @path[1..-1]\n    end\n    private :parse_dn\n\n    def parse_query\n      @attributes = nil\n      @scope      = nil\n      @filter     = nil\n      @extensions = nil\n\n      if @query\n        attrs, scope, filter, extensions = @query.split('?')\n\n        @attributes = attrs if attrs && attrs.size > 0\n        @scope      = scope if scope && scope.size > 0\n        @filter     = filter if filter && filter.size > 0\n        @extensions = extensions if extensions && extensions.size > 0\n      end\n    end\n    private :parse_query\n\n    def build_path_query\n      @path = '/' + @dn\n\n      query = []\n      [@extensions, @filter, @scope, @attributes].each do |x|\n        next if !x && query.size == 0\n        query.unshift(x)\n      end\n      @query = query.join('?')\n    end\n    private :build_path_query\n\n    def dn\n      @dn\n    end\n\n    def set_dn(val)\n      @dn = val\n      build_path_query\n      @dn\n    end\n    protected :set_dn\n\n    def dn=(val)\n      set_dn(val)\n      val\n    end\n\n    def attributes\n      @attributes\n    end\n\n    def set_attributes(val)\n      @attributes = val\n      build_path_query\n      @attributes\n    end\n    protected :set_attributes\n\n    def attributes=(val)\n      set_attributes(val)\n      val\n    end\n\n    def scope\n      @scope\n    end\n\n    def set_scope(val)\n      @scope = val\n      build_path_query\n      @scope\n    end\n    protected :set_scope\n\n    def scope=(val)\n      set_scope(val)\n      val\n    end\n\n    def filter\n      @filter\n    end\n\n    def set_filter(val)\n      @filter = val\n      build_path_query\n      @filter\n    end\n    protected :set_filter\n\n    def filter=(val)\n      set_filter(val)\n      val\n    end\n\n    def extensions\n      @extensions\n    end\n\n    def set_extensions(val)\n      @extensions = val\n      build_path_query\n      @extensions\n    end\n    protected :set_extensions\n\n    def extensions=(val)\n      set_extensions(val)\n      val\n    end\n\n    def hierarchical?\n      false\n    end\n  end\n\n  @@schemes['LDAP'] = LDAP\nend\n"
  },
  {
    "path": "lib/uri/ldaps.rb",
    "content": "require 'uri/ldap'\n\nmodule URI\n\n  # The default port for LDAPS URIs is 636, and the scheme is 'ldaps:' rather\n  # than 'ldap:'. Other than that, LDAPS URIs are identical to LDAP URIs;\n  # see URI::LDAP.\n  class LDAPS < LDAP\n    DEFAULT_PORT = 636\n  end\n  @@schemes['LDAPS'] = LDAPS\nend\n"
  },
  {
    "path": "lib/uri/mailto.rb",
    "content": "#\n# = uri/mailto.rb\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# License:: You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n#\n\nrequire 'uri/generic'\n\nmodule URI\n\n  #\n  # RFC2368, The mailto URL scheme\n  #\n  class MailTo < Generic\n    include REGEXP\n\n    DEFAULT_PORT = nil\n\n    COMPONENT = [ :scheme, :to, :headers ].freeze\n\n    # :stopdoc:\n    #  \"hname\" and \"hvalue\" are encodings of an RFC 822 header name and\n    #  value, respectively. As with \"to\", all URL reserved characters must\n    #  be encoded.\n    #\n    #  \"#mailbox\" is as specified in RFC 822 [RFC822]. This means that it\n    #  consists of zero or more comma-separated mail addresses, possibly\n    #  including \"phrase\" and \"comment\" components. Note that all URL\n    #  reserved characters in \"to\" must be encoded: in particular,\n    #  parentheses, commas, and the percent sign (\"%\"), which commonly occur\n    #  in the \"mailbox\" syntax.\n    #\n    #  Within mailto URLs, the characters \"?\", \"=\", \"&\" are reserved.\n\n    # hname      =  *urlc\n    # hvalue     =  *urlc\n    # header     =  hname \"=\" hvalue\n    HEADER_PATTERN = \"(?:[^?=&]*=[^?=&]*)\".freeze\n    HEADER_REGEXP  = Regexp.new(HEADER_PATTERN, 'N').freeze\n    # headers    =  \"?\" header *( \"&\" header )\n    # to         =  #mailbox\n    # mailtoURL  =  \"mailto:\" [ to ] [ headers ]\n    MAILBOX_PATTERN = \"(?:#{PATTERN::ESCAPED}|[^(),%?=&])\".freeze\n    MAILTO_REGEXP = Regexp.new(\" # :nodoc:\n      \\\\A\n      (#{MAILBOX_PATTERN}*?)                          (?# 1: to)\n      (?:\n        \\\\?\n        (#{HEADER_PATTERN}(?:\\\\&#{HEADER_PATTERN})*)  (?# 2: headers)\n      )?\n      (?:\n        \\\\#\n        (#{PATTERN::FRAGMENT})                        (?# 3: fragment)\n      )?\n      \\\\z\n    \", Regexp::EXTENDED, 'N').freeze\n    # :startdoc:\n\n    #\n    # == Description\n    #\n    # Creates a new URI::MailTo object from components, with syntax checking.\n    #\n    # Components can be provided as an Array or Hash. If an Array is used,\n    # the components must be supplied as [to, headers].\n    #\n    # If a Hash is used, the keys are the component names preceded by colons.\n    #\n    # The headers can be supplied as a pre-encoded string, such as \n    # \"subject=subscribe&cc=address\", or as an Array of Arrays like\n    # [['subject', 'subscribe'], ['cc', 'address']]\n    #\n    # Examples:\n    # \n    #    require 'uri'\n    #    \n    #    m1 = URI::MailTo.build(['joe@example.com', 'subject=Ruby'])\n    #    puts m1.to_s  ->  mailto:joe@example.com?subject=Ruby\n    #    \n    #    m2 = URI::MailTo.build(['john@example.com', [['Subject', 'Ruby'], ['Cc', 'jack@example.com']]])\n    #    puts m2.to_s  ->  mailto:john@example.com?Subject=Ruby&Cc=jack@example.com\n    #    \n    #    m3 = URI::MailTo.build({:to => 'listman@example.com', :headers => [['subject', 'subscribe']]})\n    #    puts m3.to_s  ->  mailto:listman@example.com?subject=subscribe\n    #\n    def self.build(args)\n      tmp = Util::make_components_hash(self, args)\n\n      if tmp[:to]\n        tmp[:opaque] = tmp[:to]\n      else\n        tmp[:opaque] = ''\n      end\n\n      if tmp[:headers]\n        tmp[:opaque] << '?'\n\n        if tmp[:headers].kind_of?(Array)\n          tmp[:opaque] << tmp[:headers].collect { |x|\n            if x.kind_of?(Array)\n              x[0] + '=' + x[1..-1].to_s\n            else\n              x.to_s\n            end\n          }.join('&')\n\n        elsif tmp[:headers].kind_of?(Hash)\n          tmp[:opaque] << tmp[:headers].collect { |h,v|\n            h + '=' + v\n          }.join('&')\n\n        else\n          tmp[:opaque] << tmp[:headers].to_s\n        end\n      end\n\n      return super(tmp)\n    end\n\n    #\n    # == Description\n    #\n    # Creates a new URI::MailTo object from generic URL components with\n    # no syntax checking.\n    #\n    # This method is usually called from URI::parse, which checks\n    # the validity of each component.\n    #\n    def initialize(*arg)\n      super(*arg)\n\n      @to = nil\n      @headers = []\n\n      if MAILTO_REGEXP =~ @opaque\n         if arg[-1]\n          self.to = $1\n          self.headers = $2\n        else\n          set_to($1)\n          set_headers($2)\n        end\n\n      else\n        raise InvalidComponentError,\n          \"unrecognised opaque part for mailtoURL: #{@opaque}\"\n      end\n    end\n\n    # The primary e-mail address of the URL, as a String\n    attr_reader :to\n\n    # E-mail headers set by the URL, as an Array of Arrays\n    attr_reader :headers\n\n    def check_to(v)\n      return true unless v\n      return true if v.size == 0\n\n      if OPAQUE !~ v || /\\A#{MAILBOX_PATTERN}*\\z/o !~ v\n        raise InvalidComponentError,\n          \"bad component(expected opaque component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_to\n\n    def set_to(v)\n      @to = v\n    end\n    protected :set_to\n\n    def to=(v)\n      check_to(v)\n      set_to(v)\n      v\n    end\n\n    def check_headers(v)\n      return true unless v\n      return true if v.size == 0\n\n      if OPAQUE !~ v || \n          /\\A(#{HEADER_PATTERN}(?:\\&#{HEADER_PATTERN})*)\\z/o !~ v\n        raise InvalidComponentError,\n          \"bad component(expected opaque component): #{v}\"\n      end\n\n      return true\n    end\n    private :check_headers\n\n    def set_headers(v)\n      @headers = []\n      if v\n        v.scan(HEADER_REGEXP) do |x|\n          @headers << x.split(/=/o, 2)\n        end\n      end\n    end\n    protected :set_headers\n\n    def headers=(v)\n      check_headers(v)\n      set_headers(v)\n      v\n    end\n\n    def to_s\n      @scheme + ':' + \n        if @to \n          @to\n        else\n          ''\n        end + \n        if @headers.size > 0\n          '?' + @headers.collect{|x| x.join('=')}.join('&')\n        else\n          ''\n        end +\n        if @fragment\n          '#' + @fragment\n        else\n          ''\n        end\n    end\n    \n    # Returns the RFC822 e-mail text equivalent of the URL, as a String.\n    #\n    # Example:\n    #\n    #   require 'uri'\n    #\n    #   uri = URI.parse(\"mailto:ruby-list@ruby-lang.org?Subject=subscribe&cc=myaddr\")\n    #   uri.to_mailtext\n    #   # => \"To: ruby-list@ruby-lang.org\\nSubject: subscribe\\nCc: myaddr\\n\\n\\n\"\n    #\n    def to_mailtext\n      to = URI::unescape(@to)\n      head = ''\n      body = ''\n      @headers.each do |x|\n        case x[0]\n        when 'body'\n          body = URI::unescape(x[1])\n        when 'to'\n          to << ', ' + URI::unescape(x[1])\n        else\n          head << URI::unescape(x[0]).capitalize + ': ' +\n            URI::unescape(x[1])  + \"\\n\"\n        end\n      end\n\n      return \"To: #{to}\n#{head}\n#{body}\n\"\n    end\n    alias to_rfc822text to_mailtext\n  end\n\n  @@schemes['MAILTO'] = MailTo\nend\n"
  },
  {
    "path": "lib/uri.rb",
    "content": "#\n# URI support for Ruby\n#\n# Author:: Akira Yamada <akira@ruby-lang.org>\n# Documentation:: Akira Yamada <akira@ruby-lang.org>, Dmitry V. Sabanin <sdmitry@lrn.ru>\n# License:: \n#  Copyright (c) 2001 akira yamada <akira@ruby-lang.org>\n#  You can redistribute it and/or modify it under the same term as Ruby.\n# Revision:: $Id$\n# \n# See URI for documentation\n#\n\nmodule URI\n  # :stopdoc:\n  VERSION_CODE = '000911'.freeze\n  VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze\n  # :startdoc:\n\nend\n\nrequire 'uri/common'\nrequire 'uri/generic'\nrequire 'uri/ftp'\nrequire 'uri/http'\nrequire 'uri/https'\nrequire 'uri/ldap'\nrequire 'uri/ldaps'\nrequire 'uri/mailto'\n"
  },
  {
    "path": "lib/weakref.rb",
    "content": "require \"delegate\"\n\n# WeakRef is a class to represent a reference to an object that is not seen by\n# the tracing phase of the garbage collector.  This allows the referenced\n# object to be garbage collected as if nothing is referring to it. Because\n# WeakRef delegates method calls to the referenced object, it may be used in\n# place of that object, i.e. it is of the same duck type.\n#\n# Usage:\n#\n#   foo = Object.new\n#   foo = Object.new\n#   p foo.to_s\t\t\t# original's class\n#   foo = WeakRef.new(foo)\n#   p foo.to_s\t\t\t# should be same class\n#   ObjectSpace.garbage_collect\n#   p foo.to_s\t\t\t# should raise exception (recycled)\nclass WeakRef<Delegator\n\n  # RefError is raised if an object cannot be referenced by a WeakRef.\n  class RefError<StandardError\n  end\n\n  @@id_map =  {}                # obj -> [ref,...]\n  @@id_rev_map =  {}            # ref -> obj\n  @@final = lambda{|id|\n    __old_status = Thread.critical\n    Thread.critical = true\n    begin\n      rids = @@id_map[id]\n      if rids\n\tfor rid in rids\n\t  @@id_rev_map.delete(rid)\n\tend\n\t@@id_map.delete(id)\n      end\n      rid = @@id_rev_map[id]\n      if rid\n\t@@id_rev_map.delete(id)\n\t@@id_map[rid].delete(id)\n\t@@id_map.delete(rid) if @@id_map[rid].empty?\n      end\n    ensure\n      Thread.critical = __old_status\n    end\n  }\n\n  # Create a new WeakRef from +orig+.\n  def initialize(orig)\n    super\n    __setobj__(orig)\n  end\n\n  # Return the object this WeakRef references. Raises RefError if the object\n  # has been garbage collected.  The object returned is the object to which\n  # method calls are delegated (see Delegator).\n  def __getobj__\n    unless @@id_rev_map[self.__id__] == @__id\n      raise RefError, \"Illegal Reference - probably recycled\", caller(2)\n    end\n    begin\n      ObjectSpace._id2ref(@__id)\n    rescue RangeError\n      raise RefError, \"Illegal Reference - probably recycled\", caller(2)\n    end\n  end\n\n  def __setobj__(obj)\n    @__id = obj.__id__\n    __old_status = Thread.critical\n    begin\n      Thread.critical = true\n      unless @@id_rev_map.key?(self)\n        ObjectSpace.define_finalizer obj, @@final\n        ObjectSpace.define_finalizer self, @@final\n      end\n      @@id_map[@__id] = [] unless @@id_map[@__id]\n    ensure\n      Thread.critical = __old_status\n    end\n    @@id_map[@__id].push self.__id__\n    @@id_rev_map[self.__id__] = @__id\n  end\n\n  # Returns true if the referenced object still exists, and false if it has\n  # been garbage collected.\n  def weakref_alive?\n    @@id_rev_map[self.__id__] == @__id\n  end\nend\n\nif __FILE__ == $0\n  require 'thread'\n  foo = Object.new\n  p foo.to_s\t\t\t# original's class\n  foo = WeakRef.new(foo)\n  p foo.to_s\t\t\t# should be same class\n  ObjectSpace.garbage_collect\n  p foo.to_s\t\t\t# should raise exception (recycled)\nend\n"
  },
  {
    "path": "lib/webrick/accesslog.rb",
    "content": "#\n# accesslog.rb -- Access log handling utilities\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2002 keita yamaguchi\n# Copyright (c) 2002 Internet Programming with Ruby writers\n#\n# $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $\n\nmodule WEBrick\n  module AccessLog\n    class AccessLogError < StandardError; end\n\n    CLF_TIME_FORMAT     = \"[%d/%b/%Y:%H:%M:%S %Z]\"\n    COMMON_LOG_FORMAT   = \"%h %l %u %t \\\"%r\\\" %s %b\"\n    CLF                 = COMMON_LOG_FORMAT\n    REFERER_LOG_FORMAT  = \"%{Referer}i -> %U\"\n    AGENT_LOG_FORMAT    = \"%{User-Agent}i\"\n    COMBINED_LOG_FORMAT = \"#{CLF} \\\"%{Referer}i\\\" \\\"%{User-agent}i\\\"\"\n\n    module_function\n\n    # This format specification is a subset of mod_log_config of Apache.\n    #   http://httpd.apache.org/docs/mod/mod_log_config.html#formats\n    def setup_params(config, req, res)\n      params = Hash.new(\"\")\n      params[\"a\"] = req.peeraddr[3]\n      params[\"b\"] = res.sent_size\n      params[\"e\"] = ENV\n      params[\"f\"] = res.filename || \"\"\n      params[\"h\"] = req.peeraddr[2]\n      params[\"i\"] = req\n      params[\"l\"] = \"-\"\n      params[\"m\"] = req.request_method\n      params[\"n\"] = req.attributes\n      params[\"o\"] = res\n      params[\"p\"] = req.port\n      params[\"q\"] = req.query_string\n      params[\"r\"] = req.request_line.sub(/\\x0d?\\x0a\\z/o, '')\n      params[\"s\"] = res.status       # won't support \"%>s\"\n      params[\"t\"] = req.request_time\n      params[\"T\"] = Time.now - req.request_time\n      params[\"u\"] = req.user || \"-\"\n      params[\"U\"] = req.unparsed_uri\n      params[\"v\"] = config[:ServerName]\n      params\n    end\n\n    def format(format_string, params)\n      format_string.gsub(/\\%(?:\\{(.*?)\\})?>?([a-zA-Z%])/){\n         param, spec = $1, $2\n         case spec[0]\n         when ?e, ?i, ?n, ?o\n           raise AccessLogError,\n             \"parameter is required for \\\"#{spec}\\\"\" unless param\n           param = params[spec][param] ? escape(param) : \"-\"\n         when ?t\n           params[spec].strftime(param || CLF_TIME_FORMAT)\n         when ?%\n           \"%\"\n         else\n           escape(params[spec].to_s)\n         end\n      }\n    end\n\n    def escape(data)\n      if data.tainted?\n        data.gsub(/[[:cntrl:]\\\\]+/) {$&.dump[1...-1]}.untaint\n      else\n        data\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/cgi.rb",
    "content": "#\n# cgi.rb -- Yet another CGI library\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $Id$\n\nrequire \"webrick/httprequest\"\nrequire \"webrick/httpresponse\"\nrequire \"webrick/config\"\nrequire \"stringio\"\n\nmodule WEBrick\n  class CGI\n    CGIError = Class.new(StandardError)\n\n    attr_reader :config, :logger\n\n    def initialize(*args)\n      if defined?(MOD_RUBY)\n        unless ENV.has_key?(\"GATEWAY_INTERFACE\")\n          Apache.request.setup_cgi_env\n        end\n      end\n      if %r{HTTP/(\\d+\\.\\d+)} =~ ENV[\"SERVER_PROTOCOL\"]\n        httpv = $1\n      end\n      @config = WEBrick::Config::HTTP.dup.update(\n        :ServerSoftware => ENV[\"SERVER_SOFTWARE\"] || \"null\",\n        :HTTPVersion    => HTTPVersion.new(httpv || \"1.0\"),\n        :RunOnCGI       => true,   # to detect if it runs on CGI.\n        :NPH            => false   # set true to run as NPH script.\n      )\n      if config = args.shift\n        @config.update(config)\n      end\n      @config[:Logger] ||= WEBrick::BasicLog.new($stderr)\n      @logger = @config[:Logger]\n      @options = args\n    end\n\n    def [](key)\n      @config[key]\n    end\n\n    def start(env=ENV, stdin=$stdin, stdout=$stdout)\n      sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)\n      req = HTTPRequest.new(@config)\n      res = HTTPResponse.new(@config)\n      unless @config[:NPH] or defined?(MOD_RUBY)\n        def res.setup_header\n          unless @header[\"status\"]\n            phrase = HTTPStatus::reason_phrase(@status)\n            @header[\"status\"] = \"#{@status} #{phrase}\"\n          end\n          super\n        end\n        def res.status_line\n          \"\"\n        end\n      end\n\n      begin\n        req.parse(sock)\n        req.script_name = (env[\"SCRIPT_NAME\"] || File.expand_path($0)).dup\n        req.path_info = (env[\"PATH_INFO\"] || \"\").dup\n        req.query_string = env[\"QUERY_STRING\"]\n        req.user = env[\"REMOTE_USER\"]\n        res.request_method = req.request_method\n        res.request_uri = req.request_uri\n        res.request_http_version = req.http_version\n        res.keep_alive = req.keep_alive?\n        self.service(req, res)\n      rescue HTTPStatus::Error => ex\n        res.set_error(ex)\n      rescue HTTPStatus::Status => ex\n        res.status = ex.code\n      rescue Exception => ex \n        @logger.error(ex)\n        res.set_error(ex, true)\n      ensure\n        req.fixup\n        if defined?(MOD_RUBY)\n          res.setup_header\n          Apache.request.status_line = \"#{res.status} #{res.reason_phrase}\"\n          Apache.request.status = res.status\n          table = Apache.request.headers_out\n          res.header.each{|key, val|\n            case key\n            when /^content-encoding$/i\n              Apache::request.content_encoding = val\n            when /^content-type$/i\n              Apache::request.content_type = val\n            else\n              table[key] = val.to_s\n            end\n          }\n          res.cookies.each{|cookie|\n            table.add(\"Set-Cookie\", cookie.to_s)\n          }\n          Apache.request.send_http_header\n          res.send_body(sock)\n        else\n          res.send_response(sock)\n        end\n      end\n    end\n\n    def service(req, res)\n      method_name = \"do_\" + req.request_method.gsub(/-/, \"_\")\n      if respond_to?(method_name)\n        __send__(method_name, req, res)\n      else\n        raise HTTPStatus::MethodNotAllowed,\n              \"unsupported method `#{req.request_method}'.\"\n      end\n    end\n\n    class Socket\n      include Enumerable\n\n      private\n  \n      def initialize(config, env, stdin, stdout)\n        @config = config\n        @env = env\n        @header_part = StringIO.new\n        @body_part = stdin\n        @out_port = stdout\n        @out_port.binmode\n  \n        @server_addr = @env[\"SERVER_ADDR\"] || \"0.0.0.0\"\n        @server_name = @env[\"SERVER_NAME\"]\n        @server_port = @env[\"SERVER_PORT\"]\n        @remote_addr = @env[\"REMOTE_ADDR\"]\n        @remote_host = @env[\"REMOTE_HOST\"] || @remote_addr\n        @remote_port = @env[\"REMOTE_PORT\"] || 0\n\n        begin\n          @header_part << request_line << CRLF\n          setup_header\n          @header_part << CRLF\n          @header_part.rewind\n        rescue Exception => ex\n          raise CGIError, \"invalid CGI environment\"\n        end\n      end\n\n      def request_line\n        meth = @env[\"REQUEST_METHOD\"] || \"GET\"\n        unless url = @env[\"REQUEST_URI\"]\n          url = (@env[\"SCRIPT_NAME\"] || File.expand_path($0)).dup\n          url << @env[\"PATH_INFO\"].to_s\n          url = WEBrick::HTTPUtils.escape_path(url)\n          if query_string = @env[\"QUERY_STRING\"]\n            unless query_string.empty?\n              url << \"?\" << query_string\n            end\n          end\n        end\n        # we cannot get real HTTP version of client ;)\n        httpv = @config[:HTTPVersion]\n        return \"#{meth} #{url} HTTP/#{httpv}\"\n      end\n  \n      def setup_header\n        add_header(\"CONTENT_TYPE\", \"Content-Type\")\n        add_header(\"CONTENT_LENGTH\", \"Content-length\")\n        @env.each_key{|name|\n          if /^HTTP_(.*)/ =~ name\n            add_header(name, $1.gsub(/_/, \"-\"))\n          end\n        }\n      end\n  \n      def add_header(envname, hdrname)\n        if value = @env[envname]\n          unless value.empty?\n            @header_part << hdrname << \": \" << value << CRLF\n          end\n        end\n      end\n\n      def input\n        @header_part.eof? ? @body_part : @header_part\n      end\n  \n      public\n  \n      def peeraddr\n        [nil, @remote_port, @remote_host, @remote_addr]\n      end\n  \n      def addr\n        [nil, @server_port, @server_name, @server_addr]\n      end\n  \n      def gets(eol=LF)\n        input.gets(eol)\n      end\n  \n      def read(size=nil)\n        input.read(size)\n      end\n\n      def each\n        input.each{|line| yield(line) }\n      end\n  \n      def <<(data)\n        @out_port << data\n      end\n\n      def cert\n        return nil unless defined?(OpenSSL)\n        if pem = @env[\"SSL_SERVER_CERT\"]\n          OpenSSL::X509::Certificate.new(pem) unless pem.empty?\n        end\n      end\n\n      def peer_cert\n        return nil unless defined?(OpenSSL)\n        if pem = @env[\"SSL_CLIENT_CERT\"]\n          OpenSSL::X509::Certificate.new(pem) unless pem.empty?\n        end\n      end\n\n      def peer_cert_chain\n        return nil unless defined?(OpenSSL)\n        if @env[\"SSL_CLIENT_CERT_CHAIN_0\"]\n          keys = @env.keys\n          certs = keys.sort.collect{|k|\n            if /^SSL_CLIENT_CERT_CHAIN_\\d+$/ =~ k\n              if pem = @env[k]\n                OpenSSL::X509::Certificate.new(pem) unless pem.empty?\n              end\n            end\n          }\n          certs.compact\n        end\n      end\n\n      def cipher\n        return nil unless defined?(OpenSSL)\n        if cipher = @env[\"SSL_CIPHER\"]\n          ret = [ cipher ]\n          ret << @env[\"SSL_PROTOCOL\"]\n          ret << @env[\"SSL_CIPHER_USEKEYSIZE\"]\n          ret << @env[\"SSL_CIPHER_ALGKEYSIZE\"]\n          ret\n        end\n      end\n    end\n  end \nend  \n"
  },
  {
    "path": "lib/webrick/compat.rb",
    "content": "#\n# compat.rb -- cross platform compatibility\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2002 GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: compat.rb,v 1.6 2002/10/01 17:16:32 gotoyuzo Exp $\n\nmodule Errno\n  class EPROTO       < SystemCallError; end\n  class ECONNRESET   < SystemCallError; end\n  class ECONNABORTED < SystemCallError; end\nend\n"
  },
  {
    "path": "lib/webrick/config.rb",
    "content": "#\n# config.rb -- Default configurations.\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: config.rb,v 1.52 2003/07/22 19:20:42 gotoyuzo Exp $\n\nrequire 'webrick/version'\nrequire 'webrick/httpversion'\nrequire 'webrick/httputils'\nrequire 'webrick/utils'\nrequire 'webrick/log'\n\nmodule WEBrick\n  module Config\n    LIBDIR = File::dirname(__FILE__)\n\n    # for GenericServer\n    General = {\n      :ServerName     => Utils::getservername,\n      :BindAddress    => nil,   # \"0.0.0.0\" or \"::\" or nil\n      :Port           => nil,   # users MUST specifiy this!!\n      :MaxClients     => 100,   # maximum number of the concurrent connections\n      :ServerType     => nil,   # default: WEBrick::SimpleServer\n      :Logger         => nil,   # default: WEBrick::Log.new\n      :ServerSoftware => \"WEBrick/#{WEBrick::VERSION} \" +\n                         \"(Ruby/#{RUBY_VERSION}/#{RUBY_RELEASE_DATE})\",\n      :TempDir        => ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'/tmp',\n      :DoNotListen    => false,\n      :StartCallback  => nil,\n      :StopCallback   => nil,\n      :AcceptCallback => nil,\n    }\n\n    # for HTTPServer, HTTPRequest, HTTPResponse ...\n    HTTP = General.dup.update(\n      :Port           => 80,\n      :RequestTimeout => 30,\n      :HTTPVersion    => HTTPVersion.new(\"1.1\"),\n      :AccessLog      => nil,\n      :MimeTypes      => HTTPUtils::DefaultMimeTypes,\n      :DirectoryIndex => [\"index.html\",\"index.htm\",\"index.cgi\",\"index.rhtml\"],\n      :DocumentRoot   => nil,\n      :DocumentRootOptions => { :FancyIndexing => true },\n      :RequestHandler => nil,\n      :RequestCallback => nil,  # alias of :RequestHandler\n      :ServerAlias    => nil,\n\n      # for HTTPProxyServer\n      :ProxyAuthProc  => nil,\n      :ProxyContentHandler => nil,\n      :ProxyVia       => true,\n      :ProxyTimeout   => true,\n      :ProxyURI       => nil,\n\n      :CGIInterpreter => nil,\n      :CGIPathEnv     => nil,\n\n      # workaround: if Request-URIs contain 8bit chars,\n      # they should be escaped before calling of URI::parse().\n      :Escape8bitURI  => false\n    )\n\n    FileHandler = {\n      :NondisclosureName => [\".ht*\", \"*~\"],\n      :FancyIndexing     => false,\n      :HandlerTable      => {},\n      :HandlerCallback   => nil,\n      :DirectoryCallback => nil,\n      :FileCallback      => nil,\n      :UserDir           => nil,  # e.g. \"public_html\"\n      :AcceptableLanguages => []  # [\"en\", \"ja\", ... ]\n    }\n\n    BasicAuth = {\n      :AutoReloadUserDB     => true,\n    }\n\n    DigestAuth = {\n      :Algorithm            => 'MD5-sess', # or 'MD5' \n      :Domain               => nil,        # an array includes domain names.\n      :Qop                  => [ 'auth' ], # 'auth' or 'auth-int' or both.\n      :UseOpaque            => true,\n      :UseNextNonce         => false,\n      :CheckNc              => false,\n      :UseAuthenticationInfoHeader => true,\n      :AutoReloadUserDB     => true,\n      :NonceExpirePeriod    => 30*60,\n      :NonceExpireDelta     => 60,\n      :InternetExplorerHack => true,\n      :OperaHack            => true,\n    }\n  end\nend\n"
  },
  {
    "path": "lib/webrick/cookie.rb",
    "content": "#\n# cookie.rb -- Cookie class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: cookie.rb,v 1.16 2002/09/21 12:23:35 gotoyuzo Exp $\n\nrequire 'time'\nrequire 'webrick/httputils'\n\nmodule WEBrick\n  class Cookie\n\n    attr_reader :name\n    attr_accessor :value, :version\n    attr_accessor :domain, :path, :secure\n    attr_accessor :comment, :max_age\n    #attr_accessor :comment_url, :discard, :port\n\n    def initialize(name, value)\n      @name = name\n      @value = value\n      @version = 0     # Netscape Cookie\n\n      @domain = @path = @secure = @comment = @max_age =\n      @expires = @comment_url = @discard = @port = nil\n    end\n\n    def expires=(t)\n      @expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)\n    end\n\n    def expires\n      @expires && Time.parse(@expires)\n    end\n\n    def to_s\n      ret = \"\"\n      ret << @name << \"=\" << @value\n      ret << \"; \" << \"Version=\" << @version.to_s if @version > 0\n      ret << \"; \" << \"Domain=\"  << @domain  if @domain\n      ret << \"; \" << \"Expires=\" << @expires if @expires\n      ret << \"; \" << \"Max-Age=\" << @max_age.to_s if @max_age\n      ret << \"; \" << \"Comment=\" << @comment if @comment\n      ret << \"; \" << \"Path=\"    << @path if @path\n      ret << \"; \" << \"Secure\"   if @secure\n      ret\n    end\n\n    # Cookie::parse()\n    #   It parses Cookie field sent from the user agent.\n    def self.parse(str)\n      if str\n        ret = []\n        cookie = nil\n        ver = 0\n        str.split(/[;,]\\s+/).each{|x|\n          key, val = x.split(/=/,2)\n          val = val ? HTTPUtils::dequote(val) : \"\"\n          case key\n          when \"$Version\"; ver = val.to_i\n          when \"$Path\";    cookie.path = val\n          when \"$Domain\";  cookie.domain = val\n          when \"$Port\";    cookie.port = val\n          else\n            ret << cookie if cookie\n            cookie = self.new(key, val)\n            cookie.version = ver\n          end\n        }\n        ret << cookie if cookie\n        ret\n      end\n    end\n\n    def self.parse_set_cookie(str)\n      cookie_elem = str.split(/;/)\n      first_elem = cookie_elem.shift\n      first_elem.strip!\n      key, value = first_elem.split(/=/, 2)\n      cookie = new(key, HTTPUtils.dequote(value))\n      cookie_elem.each{|pair|\n        pair.strip!\n        key, value = pair.split(/=/, 2)\n        if value\n          value = HTTPUtils.dequote(value.strip)\n        end\n        case key.downcase\n        when \"domain\"  then cookie.domain  = value\n        when \"path\"    then cookie.path    = value\n        when \"expires\" then cookie.expires = value\n        when \"max-age\" then cookie.max_age = Integer(value)\n        when \"comment\" then cookie.comment = value\n        when \"version\" then cookie.version = Integer(value)\n        when \"secure\"  then cookie.secure = true\n        end\n      }\n      return cookie\n    end\n\n    def self.parse_set_cookies(str)\n      return str.split(/,(?=[^;,]*=)|,$/).collect{|c|\n        parse_set_cookie(c)\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/htmlutils.rb",
    "content": "#\n# htmlutils.rb -- HTMLUtils Module\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: htmlutils.rb,v 1.7 2002/09/21 12:23:35 gotoyuzo Exp $\n\nmodule WEBrick\n  module HTMLUtils\n\n    def escape(string)\n      str = string ? string.dup : \"\"\n      str.gsub!(/&/n, '&amp;')\n      str.gsub!(/\\\"/n, '&quot;')\n      str.gsub!(/>/n, '&gt;')\n      str.gsub!(/</n, '&lt;')\n      str\n    end\n    module_function :escape\n\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/authenticator.rb",
    "content": "#\n# httpauth/authenticator.rb -- Authenticator mix-in module.\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: authenticator.rb,v 1.3 2003/02/20 07:15:47 gotoyuzo Exp $\n\nmodule WEBrick\n  module HTTPAuth\n    module Authenticator\n      RequestField      = \"Authorization\"\n      ResponseField     = \"WWW-Authenticate\"\n      ResponseInfoField = \"Authentication-Info\"\n      AuthException     = HTTPStatus::Unauthorized\n      AuthScheme        = nil # must override by the derived class\n\n      attr_reader :realm, :userdb, :logger\n\n      private\n\n      def check_init(config)\n        [:UserDB, :Realm].each{|sym|\n          unless config[sym]\n            raise ArgumentError, \"Argument #{sym.inspect} missing.\"\n          end\n        } \n        @realm     = config[:Realm]\n        @userdb    = config[:UserDB]\n        @logger    = config[:Logger] || Log::new($stderr)\n        @reload_db = config[:AutoReloadUserDB]\n        @request_field   = self::class::RequestField\n        @response_field  = self::class::ResponseField\n        @resp_info_field = self::class::ResponseInfoField\n        @auth_exception  = self::class::AuthException\n        @auth_scheme     = self::class::AuthScheme\n      end\n\n      def check_scheme(req)\n        unless credentials = req[@request_field]\n          error(\"no credentials in the request.\")\n          return nil \n        end  \n        unless match = /^#{@auth_scheme}\\s+/.match(credentials)\n          error(\"invalid scheme in %s.\", credentials)\n          info(\"%s: %s\", @request_field, credentials) if $DEBUG\n          return nil\n        end\n        return match.post_match\n      end\n\n      def log(meth, fmt, *args)\n        msg = format(\"%s %s: \", @auth_scheme, @realm)\n        msg << fmt % args\n        @logger.send(meth, msg)\n      end\n\n      def error(fmt, *args)\n        if @logger.error?\n          log(:error, fmt, *args)\n        end\n      end                             \n\n      def info(fmt, *args)\n        if @logger.info?\n          log(:info, fmt, *args)\n        end\n      end\n    end\n\n    module ProxyAuthenticator\n      RequestField  = \"Proxy-Authorization\"\n      ResponseField = \"Proxy-Authenticate\"\n      InfoField     = \"Proxy-Authentication-Info\"\n      AuthException = HTTPStatus::ProxyAuthenticationRequired\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/basicauth.rb",
    "content": "#\n# httpauth/basicauth.rb -- HTTP basic access authentication\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: basicauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $\n\nrequire 'webrick/config'\nrequire 'webrick/httpstatus'\nrequire 'webrick/httpauth/authenticator'\n\nmodule WEBrick\n  module HTTPAuth\n    class BasicAuth\n      include Authenticator\n\n      AuthScheme = \"Basic\"\n\n      def self.make_passwd(realm, user, pass)\n        pass ||= \"\"\n        pass.crypt(Utils::random_string(2))\n      end\n\n      attr_reader :realm, :userdb, :logger\n\n      def initialize(config, default=Config::BasicAuth)\n        check_init(config)\n        @config = default.dup.update(config)\n      end\n\n      def authenticate(req, res)\n        unless basic_credentials = check_scheme(req)\n          challenge(req, res)\n        end\n        userid, password = basic_credentials.unpack(\"m*\")[0].split(\":\", 2) \n        password ||= \"\"\n        if userid.empty?\n          error(\"user id was not given.\")\n          challenge(req, res)\n        end\n        unless encpass = @userdb.get_passwd(@realm, userid, @reload_db)\n          error(\"%s: the user is not allowed.\", userid)\n          challenge(req, res)\n        end\n        if password.crypt(encpass) != encpass\n          error(\"%s: password unmatch.\", userid)\n          challenge(req, res)\n        end\n        info(\"%s: authentication succeeded.\", userid)\n        req.user = userid\n      end\n\n      def challenge(req, res)\n        res[@response_field] = \"#{@auth_scheme} realm=\\\"#{@realm}\\\"\"\n        raise @auth_exception\n      end\n    end\n\n    class ProxyBasicAuth < BasicAuth\n      include ProxyAuthenticator\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/digestauth.rb",
    "content": "#\n# httpauth/digestauth.rb -- HTTP digest access authentication\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers.\n# Copyright (c) 2003 H.M.\n#\n# The original implementation is provided by H.M.\n#   URL: http://rwiki.jin.gr.jp/cgi-bin/rw-cgi.rb?cmd=view;name=\n#        %C7%A7%BE%DA%B5%A1%C7%BD%A4%F2%B2%FE%C2%A4%A4%B7%A4%C6%A4%DF%A4%EB\n#\n# $IPR: digestauth.rb,v 1.5 2003/02/20 07:15:47 gotoyuzo Exp $\n\nrequire 'webrick/config'\nrequire 'webrick/httpstatus'\nrequire 'webrick/httpauth/authenticator'\nrequire 'digest/md5'\nrequire 'digest/sha1'\n\nmodule WEBrick\n  module HTTPAuth\n    class DigestAuth\n      include Authenticator\n\n      AuthScheme = \"Digest\"\n      OpaqueInfo = Struct.new(:time, :nonce, :nc)\n      attr_reader :algorithm, :qop\n\n      def self.make_passwd(realm, user, pass)\n        pass ||= \"\"\n        Digest::MD5::hexdigest([user, realm, pass].join(\":\"))\n      end\n\n      def initialize(config, default=Config::DigestAuth)\n        check_init(config)\n        @config                 = default.dup.update(config)\n        @algorithm              = @config[:Algorithm]\n        @domain                 = @config[:Domain]\n        @qop                    = @config[:Qop]\n        @use_opaque             = @config[:UseOpaque]\n        @use_next_nonce         = @config[:UseNextNonce]\n        @check_nc               = @config[:CheckNc]\n        @use_auth_info_header   = @config[:UseAuthenticationInfoHeader]\n        @nonce_expire_period    = @config[:NonceExpirePeriod]\n        @nonce_expire_delta     = @config[:NonceExpireDelta]\n        @internet_explorer_hack = @config[:InternetExplorerHack]\n        @opera_hack             = @config[:OperaHack]\n\n        case @algorithm\n        when 'MD5','MD5-sess'\n          @h = Digest::MD5\n        when 'SHA1','SHA1-sess'  # it is a bonus feature :-)\n          @h = Digest::SHA1\n        else\n          msg = format('Alogrithm \"%s\" is not supported.', @algorithm)\n          raise ArgumentError.new(msg)\n        end\n\n        @instance_key = hexdigest(self.__id__, Time.now.to_i, Process.pid)\n        @opaques = {}\n        @last_nonce_expire = Time.now\n        @mutex = Mutex.new\n      end\n\n      def authenticate(req, res)\n        unless result = @mutex.synchronize{ _authenticate(req, res) }\n          challenge(req, res)\n        end\n        if result == :nonce_is_stale\n          challenge(req, res, true)\n        end\n        return true\n      end\n\n      def challenge(req, res, stale=false)\n        nonce = generate_next_nonce(req)\n        if @use_opaque\n          opaque = generate_opaque(req)\n          @opaques[opaque].nonce = nonce\n        end\n\n        param = Hash.new\n        param[\"realm\"]  = HTTPUtils::quote(@realm)\n        param[\"domain\"] = HTTPUtils::quote(@domain.to_a.join(\" \")) if @domain\n        param[\"nonce\"]  = HTTPUtils::quote(nonce)\n        param[\"opaque\"] = HTTPUtils::quote(opaque) if opaque\n        param[\"stale\"]  = stale.to_s\n        param[\"algorithm\"] = @algorithm\n        param[\"qop\"]    = HTTPUtils::quote(@qop.to_a.join(\",\")) if @qop\n\n        res[@response_field] =\n          \"#{@auth_scheme} \" + param.map{|k,v| \"#{k}=#{v}\" }.join(\", \")\n        info(\"%s: %s\", @response_field, res[@response_field]) if $DEBUG\n        raise @auth_exception\n      end\n\n      private\n\n      MustParams = ['username','realm','nonce','uri','response']\n      MustParamsAuth = ['cnonce','nc']\n\n      def _authenticate(req, res)\n        unless digest_credentials = check_scheme(req)\n          return false\n        end\n\n        auth_req = split_param_value(digest_credentials)\n        if auth_req['qop'] == \"auth\" || auth_req['qop'] == \"auth-int\"\n          req_params = MustParams + MustParamsAuth\n        else\n          req_params = MustParams\n        end\n        req_params.each{|key|\n          unless auth_req.has_key?(key)\n            error('%s: parameter missing. \"%s\"', auth_req['username'], key)\n            raise HTTPStatus::BadRequest\n          end\n        }\n\n        if !check_uri(req, auth_req)\n          raise HTTPStatus::BadRequest  \n        end\n\n        if auth_req['realm'] != @realm  \n          error('%s: realm unmatch. \"%s\" for \"%s\"',\n                auth_req['username'], auth_req['realm'], @realm)\n          return false\n        end\n\n        auth_req['algorithm'] ||= 'MD5' \n        if auth_req['algorithm'] != @algorithm &&\n           (@opera_hack && auth_req['algorithm'] != @algorithm.upcase)\n          error('%s: algorithm unmatch. \"%s\" for \"%s\"',\n                auth_req['username'], auth_req['algorithm'], @algorithm)\n          return false\n        end\n\n        if (@qop.nil? && auth_req.has_key?('qop')) ||\n           (@qop && (! @qop.member?(auth_req['qop'])))\n          error('%s: the qop is not allowed. \"%s\"',\n                auth_req['username'], auth_req['qop'])\n          return false\n        end\n\n        password = @userdb.get_passwd(@realm, auth_req['username'], @reload_db)\n        unless password\n          error('%s: the user is not allowd.', auth_req['username'])\n          return false\n        end\n\n        nonce_is_invalid = false\n        if @use_opaque\n          info(\"@opaque = %s\", @opaque.inspect) if $DEBUG\n          if !(opaque = auth_req['opaque'])\n            error('%s: opaque is not given.', auth_req['username'])\n            nonce_is_invalid = true\n          elsif !(opaque_struct = @opaques[opaque])\n            error('%s: invalid opaque is given.', auth_req['username'])\n            nonce_is_invalid = true\n          elsif !check_opaque(opaque_struct, req, auth_req)\n            @opaques.delete(auth_req['opaque'])\n            nonce_is_invalid = true\n          end\n        elsif !check_nonce(req, auth_req)\n          nonce_is_invalid = true\n        end\n\n        if /-sess$/ =~ auth_req['algorithm'] ||\n           (@opera_hack && /-SESS$/ =~ auth_req['algorithm'])\n          ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])\n        else\n          ha1 = password\n        end\n\n        if auth_req['qop'] == \"auth\" || auth_req['qop'] == nil\n          ha2 = hexdigest(req.request_method, auth_req['uri'])\n          ha2_res = hexdigest(\"\", auth_req['uri'])\n        elsif auth_req['qop'] == \"auth-int\"\n          ha2 = hexdigest(req.request_method, auth_req['uri'],\n                          hexdigest(req.body))\n          ha2_res = hexdigest(\"\", auth_req['uri'], hexdigest(res.body))\n        end\n\n        if auth_req['qop'] == \"auth\" || auth_req['qop'] == \"auth-int\"\n          param2 = ['nonce', 'nc', 'cnonce', 'qop'].map{|key|\n            auth_req[key]\n          }.join(':')\n          digest     = hexdigest(ha1, param2, ha2)\n          digest_res = hexdigest(ha1, param2, ha2_res)\n        else\n          digest     = hexdigest(ha1, auth_req['nonce'], ha2)\n          digest_res = hexdigest(ha1, auth_req['nonce'], ha2_res)\n        end\n\n        if digest != auth_req['response']\n          error(\"%s: digest unmatch.\", auth_req['username'])\n          return false\n        elsif nonce_is_invalid\n          error('%s: digest is valid, but nonce is not valid.',\n                auth_req['username'])\n          return :nonce_is_stale\n        elsif @use_auth_info_header\n          auth_info = {\n            'nextnonce' => generate_next_nonce(req),\n            'rspauth'   => digest_res\n          }\n          if @use_opaque\n            opaque_struct.time  = req.request_time\n            opaque_struct.nonce = auth_info['nextnonce']\n            opaque_struct.nc    = \"%08x\" % (auth_req['nc'].hex + 1)\n          end\n          if auth_req['qop'] == \"auth\" || auth_req['qop'] == \"auth-int\"\n            ['qop','cnonce','nc'].each{|key|\n              auth_info[key] = auth_req[key]\n            }\n          end\n          res[@resp_info_field] = auth_info.keys.map{|key|\n            if key == 'nc'\n              key + '=' + auth_info[key]\n            else\n              key + \"=\" + HTTPUtils::quote(auth_info[key])\n            end\n          }.join(', ')\n        end\n        info('%s: authentication scceeded.', auth_req['username'])\n        req.user = auth_req['username']\n        return true\n      end\n\n      def split_param_value(string)\n        ret = {}\n        while string.size != 0\n          case string           \n          when /^\\s*([\\w\\-\\.\\*\\%\\!]+)=\\s*\\\"((\\\\.|[^\\\"])*)\\\"\\s*,?/\n            key = $1\n            matched = $2\n            string = $'\n            ret[key] = matched.gsub(/\\\\(.)/, \"\\\\1\")\n          when /^\\s*([\\w\\-\\.\\*\\%\\!]+)=\\s*([^,\\\"]*),?/\n            key = $1\n            matched = $2\n            string = $'\n            ret[key] = matched.clone\n          when /^s*^,/\n            string = $'\n          else\n            break\n          end\n        end\n        ret\n      end\n\n      def generate_next_nonce(req)\n        now = \"%012d\" % req.request_time.to_i\n        pk  = hexdigest(now, @instance_key)[0,32]\n        nonce = [now + \":\" + pk].pack(\"m*\").chop # it has 60 length of chars.\n        nonce\n      end\n\n      def check_nonce(req, auth_req)\n        username = auth_req['username']\n        nonce = auth_req['nonce']\n\n        pub_time, pk = nonce.unpack(\"m*\")[0].split(\":\", 2)\n        if (!pub_time || !pk)\n          error(\"%s: empty nonce is given\", username)\n          return false\n        elsif (hexdigest(pub_time, @instance_key)[0,32] != pk)\n          error(\"%s: invalid private-key: %s for %s\",\n                username, hexdigest(pub_time, @instance_key)[0,32], pk)\n          return false\n        end\n\n        diff_time = req.request_time.to_i - pub_time.to_i\n        if (diff_time < 0)\n          error(\"%s: difference of time-stamp is negative.\", username)\n          return false\n        elsif diff_time > @nonce_expire_period\n          error(\"%s: nonce is expired.\", username)\n          return false\n        end\n\n        return true\n      end\n\n      def generate_opaque(req)\n        @mutex.synchronize{\n          now = req.request_time\n          if now - @last_nonce_expire > @nonce_expire_delta\n            @opaques.delete_if{|key,val|\n              (now - val.time) > @nonce_expire_period\n            }\n            @last_nonce_expire = now\n          end\n          begin\n            opaque = Utils::random_string(16)\n          end while @opaques[opaque]\n          @opaques[opaque] = OpaqueInfo.new(now, nil, '00000001')\n          opaque\n        }\n      end\n\n      def check_opaque(opaque_struct, req, auth_req)\n        if (@use_next_nonce && auth_req['nonce'] != opaque_struct.nonce)\n          error('%s: nonce unmatched. \"%s\" for \"%s\"',\n                auth_req['username'], auth_req['nonce'], opaque_struct.nonce)\n          return false\n        elsif !check_nonce(req, auth_req)\n          return false\n        end\n        if (@check_nc && auth_req['nc'] != opaque_struct.nc)\n          error('%s: nc unmatched.\"%s\" for \"%s\"',\n                auth_req['username'], auth_req['nc'], opaque_struct.nc)\n          return false\n        end\n        true\n      end\n\n      def check_uri(req, auth_req)\n        uri = auth_req['uri']\n        if uri != req.request_uri.to_s && uri != req.unparsed_uri &&\n           (@internet_explorer_hack && uri != req.path)\n          error('%s: uri unmatch. \"%s\" for \"%s\"', auth_req['username'], \n                auth_req['uri'], req.request_uri.to_s)\n          return false\n        end\n        true\n      end\n\n      def hexdigest(*args)\n        @h.hexdigest(args.join(\":\"))\n      end\n    end\n\n    class ProxyDigestAuth < DigestAuth\n      include ProxyAuthenticator\n\n      def check_uri(req, auth_req)\n        return true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/htdigest.rb",
    "content": "#\n# httpauth/htdigest.rb -- Apache compatible htdigest file\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $\n\nrequire 'webrick/httpauth/userdb'\nrequire 'webrick/httpauth/digestauth'\nrequire 'tempfile'\n\nmodule WEBrick\n  module HTTPAuth\n    class Htdigest\n      include UserDB\n\n      def initialize(path)\n        @path = path\n        @mtime = Time.at(0)\n        @digest = Hash.new\n        @mutex = Mutex::new\n        @auth_type = DigestAuth\n        open(@path,\"a\").close unless File::exist?(@path)\n        reload\n      end\n\n      def reload\n        mtime = File::mtime(@path)\n        if mtime > @mtime\n          @digest.clear\n          open(@path){|io|\n            while line = io.gets\n              line.chomp!\n              user, realm, pass = line.split(/:/, 3)\n              unless @digest[realm]\n                @digest[realm] = Hash.new\n              end\n              @digest[realm][user] = pass\n            end\n          }\n          @mtime = mtime\n        end\n      end\n\n      def flush(output=nil)\n        output ||= @path\n        tmp = Tempfile.new(\"htpasswd\", File::dirname(output))\n        begin\n          each{|item| tmp.puts(item.join(\":\")) }\n          tmp.close\n          File::rename(tmp.path, output)\n        rescue\n          tmp.close(true)\n        end\n      end\n\n      def get_passwd(realm, user, reload_db)\n        reload() if reload_db\n        if hash = @digest[realm]\n          hash[user]\n        end\n      end\n\n      def set_passwd(realm, user, pass)\n        @mutex.synchronize{\n          unless @digest[realm]\n            @digest[realm] = Hash.new\n          end\n          @digest[realm][user] = make_passwd(realm, user, pass)\n        }\n      end\n\n      def delete_passwd(realm, user)\n        if hash = @digest[realm]\n          hash.delete(user)\n        end\n      end\n\n      def each\n        @digest.keys.sort.each{|realm|\n          hash = @digest[realm]\n          hash.keys.sort.each{|user|\n            yield([user, realm, hash[user]])\n          }\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/htgroup.rb",
    "content": "#\n# httpauth/htgroup.rb -- Apache compatible htgroup file\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: htgroup.rb,v 1.1 2003/02/16 22:22:56 gotoyuzo Exp $\n\nrequire 'tempfile'\n\nmodule WEBrick\n  module HTTPAuth\n    class Htgroup\n      def initialize(path)\n        @path = path\n        @mtime = Time.at(0)\n        @group = Hash.new\n        open(@path,\"a\").close unless File::exist?(@path)\n        reload\n      end\n\n      def reload\n        if (mtime = File::mtime(@path)) > @mtime\n          @group.clear\n          open(@path){|io|\n            while line = io.gets\n              line.chomp!\n              group, members = line.split(/:\\s*/)\n              @group[group] = members.split(/\\s+/)\n            end\n          }\n          @mtime = mtime\n        end\n      end\n\n      def flush(output=nil)\n        output ||= @path\n        tmp = Tempfile.new(\"htgroup\", File::dirname(output))\n        begin\n          @group.keys.sort.each{|group|\n            tmp.puts(format(\"%s: %s\", group, self.members(group).join(\" \")))\n          }\n          tmp.close\n          File::rename(tmp.path, output)\n        rescue\n          tmp.close(true)\n        end\n      end\n\n      def members(group)\n        reload\n        @group[group] || []\n      end\n\n      def add(group, members)\n        @group[group] = members(group) | members\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/htpasswd.rb",
    "content": "#\n# httpauth/htpasswd -- Apache compatible htpasswd file\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $\n\nrequire 'webrick/httpauth/userdb'\nrequire 'webrick/httpauth/basicauth'\nrequire 'tempfile'\n\nmodule WEBrick\n  module HTTPAuth\n    class Htpasswd\n      include UserDB\n\n      def initialize(path)\n        @path = path\n        @mtime = Time.at(0)\n        @passwd = Hash.new\n        @auth_type = BasicAuth\n        open(@path,\"a\").close unless File::exist?(@path)\n        reload\n      end\n\n      def reload\n        mtime = File::mtime(@path)\n        if mtime > @mtime\n          @passwd.clear\n          open(@path){|io|\n            while line = io.gets\n              line.chomp!\n              case line\n              when %r!\\A[^:]+:[a-zA-Z0-9./]{13}\\z!\n                user, pass = line.split(\":\")\n              when /:\\$/, /:\\{SHA\\}/\n                raise NotImplementedError,\n                      'MD5, SHA1 .htpasswd file not supported'\n              else\n                raise StandardError, 'bad .htpasswd file'\n              end\n              @passwd[user] = pass\n            end\n          }\n          @mtime = mtime\n        end\n      end\n\n      def flush(output=nil)\n        output ||= @path\n        tmp = Tempfile.new(\"htpasswd\", File::dirname(output))\n        begin\n          each{|item| tmp.puts(item.join(\":\")) }\n          tmp.close\n          File::rename(tmp.path, output)\n        rescue\n          tmp.close(true)\n        end\n      end\n\n      def get_passwd(realm, user, reload_db)\n        reload() if reload_db\n        @passwd[user]\n      end\n\n      def set_passwd(realm, user, pass)\n        @passwd[user] = make_passwd(realm, user, pass)\n      end\n\n      def delete_passwd(realm, user)\n        @passwd.delete(user)\n      end\n\n      def each\n        @passwd.keys.sort.each{|user|\n          yield([user, @passwd[user]])\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth/userdb.rb",
    "content": "#\n# httpauth/userdb.rb -- UserDB mix-in module.\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: userdb.rb,v 1.2 2003/02/20 07:15:48 gotoyuzo Exp $\n\nmodule WEBrick\n  module HTTPAuth\n    module UserDB\n      attr_accessor :auth_type # BasicAuth or DigestAuth\n\n      def make_passwd(realm, user, pass)\n        @auth_type::make_passwd(realm, user, pass)\n      end\n\n      def set_passwd(realm, user, pass)\n        self[user] = pass\n      end                             \n\n      def get_passwd(realm, user, reload_db=false)\n        # reload_db is dummy\n        make_passwd(realm, user, self[user])\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpauth.rb",
    "content": "#\n# httpauth.rb -- HTTP access authentication\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpauth.rb,v 1.14 2003/07/22 19:20:42 gotoyuzo Exp $\n\nrequire 'webrick/httpauth/basicauth'\nrequire 'webrick/httpauth/digestauth'\nrequire 'webrick/httpauth/htpasswd'\nrequire 'webrick/httpauth/htdigest'\nrequire 'webrick/httpauth/htgroup'\n\nmodule WEBrick\n  module HTTPAuth\n    module_function\n\n    def _basic_auth(req, res, realm, req_field, res_field, err_type, block)\n      user = pass = nil\n      if /^Basic\\s+(.*)/o =~ req[req_field]\n        userpass = $1\n        user, pass = userpass.unpack(\"m*\")[0].split(\":\", 2)\n      end\n      if block.call(user, pass)\n        req.user = user\n        return\n      end\n      res[res_field] = \"Basic realm=\\\"#{realm}\\\"\"\n      raise err_type\n    end\n\n    def basic_auth(req, res, realm, &block)\n      _basic_auth(req, res, realm, \"Authorization\", \"WWW-Authenticate\",\n                  HTTPStatus::Unauthorized, block)\n    end\n\n    def proxy_basic_auth(req, res, realm, &block)\n      _basic_auth(req, res, realm, \"Proxy-Authorization\", \"Proxy-Authenticate\",\n                  HTTPStatus::ProxyAuthenticationRequired, block)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpproxy.rb",
    "content": "#\n# httpproxy.rb -- HTTPProxy Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2002 GOTO Kentaro\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $\n# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $\n\nrequire \"webrick/httpserver\"\nrequire \"net/http\"\n\nNet::HTTP::version_1_2 if RUBY_VERSION < \"1.7\"\n\nmodule WEBrick\n  NullReader = Object.new\n  class << NullReader\n    def read(*args)\n      nil\n    end\n    alias gets read\n  end\n\n  class HTTPProxyServer < HTTPServer\n    def initialize(config)\n      super\n      c = @config\n      @via = \"#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}\"\n    end\n\n    def service(req, res)\n      if req.request_method == \"CONNECT\"\n        proxy_connect(req, res)\n      elsif req.unparsed_uri =~ %r!^http://!\n        proxy_service(req, res)\n      else\n        super(req, res)\n      end\n    end\n\n    def proxy_auth(req, res)\n      if proc = @config[:ProxyAuthProc]\n        proc.call(req, res)\n      end\n      req.header.delete(\"proxy-authorization\")\n    end\n\n    # Some header fields should not be transferred.\n    HopByHop = %w( connection keep-alive proxy-authenticate upgrade\n                   proxy-authorization te trailers transfer-encoding )\n    ShouldNotTransfer = %w( set-cookie proxy-connection )\n    def split_field(f) f ? f.split(/,\\s+/).collect{|i| i.downcase } : [] end\n\n    def choose_header(src, dst)\n      connections = split_field(src['connection'])\n      src.each{|key, value|\n        key = key.downcase\n        if HopByHop.member?(key)          || # RFC2616: 13.5.1\n           connections.member?(key)       || # RFC2616: 14.10\n           ShouldNotTransfer.member?(key)    # pragmatics\n          @logger.debug(\"choose_header: `#{key}: #{value}'\")\n          next\n        end\n        dst[key] = value\n      }\n    end\n\n    # Net::HTTP is stupid about the multiple header fields.\n    # Here is workaround:\n    def set_cookie(src, dst)\n      if str = src['set-cookie']\n        cookies = []\n        str.split(/,\\s*/).each{|token|\n          if /^[^=]+;/o =~ token\n            cookies[-1] << \", \" << token\n          elsif /=/o =~ token\n            cookies << token\n          else\n            cookies[-1] << \", \" << token\n          end\n        }\n        dst.cookies.replace(cookies)\n      end\n    end\n\n    def set_via(h)\n      if @config[:ProxyVia]\n        if  h['via']\n          h['via'] << \", \" << @via\n        else\n          h['via'] = @via\n        end\n      end\n    end\n\n    def proxy_uri(req, res)\n      @config[:ProxyURI]\n    end\n\n    def proxy_service(req, res)\n      # Proxy Authentication\n      proxy_auth(req, res)      \n\n      # Create Request-URI to send to the origin server\n      uri  = req.request_uri\n      path = uri.path.dup\n      path << \"?\" << uri.query if uri.query\n\n      # Choose header fields to transfer\n      header = Hash.new\n      choose_header(req, header)\n      set_via(header)\n\n      # select upstream proxy server\n      if proxy = proxy_uri(req, res)\n        proxy_host = proxy.host\n        proxy_port = proxy.port\n        if proxy.userinfo\n          credentials = \"Basic \" + [proxy.userinfo].pack(\"m*\")\n          credentials.chomp!\n          header['proxy-authorization'] = credentials\n        end\n      end\n\n      response = nil\n      begin\n        http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port)\n        http.start{\n          if @config[:ProxyTimeout]\n            ##################################   these issues are \n            http.open_timeout = 30   # secs  #   necessary (maybe bacause\n            http.read_timeout = 60   # secs  #   Ruby's bug, but why?)\n            ##################################\n          end\n          case req.request_method\n          when \"GET\"  then response = http.get(path, header)\n          when \"POST\" then response = http.post(path, req.body || \"\", header)\n          when \"HEAD\" then response = http.head(path, header)\n          else\n            raise HTTPStatus::MethodNotAllowed,\n              \"unsupported method `#{req.request_method}'.\"\n          end\n        }\n      rescue => err\n        logger.debug(\"#{err.class}: #{err.message}\")\n        raise HTTPStatus::ServiceUnavailable, err.message\n      end\n  \n      # Persistent connction requirements are mysterious for me.\n      # So I will close the connection in every response.\n      res['proxy-connection'] = \"close\"\n      res['connection'] = \"close\"\n\n      # Convert Net::HTTP::HTTPResponse to WEBrick::HTTPProxy\n      res.status = response.code.to_i\n      choose_header(response, res)\n      set_cookie(response, res)\n      set_via(res)\n      res.body = response.body\n\n      # Process contents\n      if handler = @config[:ProxyContentHandler]\n        handler.call(req, res)\n      end\n    end\n\n    def proxy_connect(req, res)\n      # Proxy Authentication\n      proxy_auth(req, res)\n\n      ua = Thread.current[:WEBrickSocket]  # User-Agent\n      raise HTTPStatus::InternalServerError,\n        \"[BUG] cannot get socket\" unless ua\n\n      host, port = req.unparsed_uri.split(\":\", 2)\n      # Proxy authentication for upstream proxy server\n      if proxy = proxy_uri(req, res)\n        proxy_request_line = \"CONNECT #{host}:#{port} HTTP/1.0\"\n        if proxy.userinfo\n          credentials = \"Basic \" + [proxy.userinfo].pack(\"m*\")\n          credentials.chomp!\n        end\n        host, port = proxy.host, proxy.port\n      end\n\n      begin\n        @logger.debug(\"CONNECT: upstream proxy is `#{host}:#{port}'.\")\n        os = TCPSocket.new(host, port)     # origin server\n\n        if proxy\n          @logger.debug(\"CONNECT: sending a Request-Line\")\n          os << proxy_request_line << CRLF\n          @logger.debug(\"CONNECT: > #{proxy_request_line}\")\n          if credentials\n            @logger.debug(\"CONNECT: sending a credentials\")\n            os << \"Proxy-Authorization: \" << credentials << CRLF\n          end\n          os << CRLF\n          proxy_status_line = os.gets(LF)\n          @logger.debug(\"CONNECT: read a Status-Line form the upstream server\")\n          @logger.debug(\"CONNECT: < #{proxy_status_line}\")\n          if %r{^HTTP/\\d+\\.\\d+\\s+200\\s*} =~ proxy_status_line\n            while line = os.gets(LF)\n              break if /\\A(#{CRLF}|#{LF})\\z/om =~ line\n            end\n          else\n            raise HTTPStatus::BadGateway\n          end\n        end\n        @logger.debug(\"CONNECT #{host}:#{port}: succeeded\")\n        res.status = HTTPStatus::RC_OK\n      rescue => ex\n        @logger.debug(\"CONNECT #{host}:#{port}: failed `#{ex.message}'\")\n        res.set_error(ex)\n        raise HTTPStatus::EOFError\n      ensure\n        if handler = @config[:ProxyContentHandler]\n          handler.call(req, res)\n        end\n        res.send_response(ua)\n        access_log(@config, req, res)\n\n        # Should clear request-line not to send the sesponse twice.\n        # see: HTTPServer#run\n        req.parse(NullReader) rescue nil\n      end\n\n      begin\n        while fds = IO::select([ua, os])\n          if fds[0].member?(ua)\n            buf = ua.sysread(1024);\n            @logger.debug(\"CONNECT: #{buf.size} byte from User-Agent\")\n            os.syswrite(buf)\n          elsif fds[0].member?(os)\n            buf = os.sysread(1024);\n            @logger.debug(\"CONNECT: #{buf.size} byte from #{host}:#{port}\")\n            ua.syswrite(buf)\n          end\n        end\n      rescue => ex\n        os.close\n        @logger.debug(\"CONNECT #{host}:#{port}: closed\")\n      end\n\n      raise HTTPStatus::EOFError\n    end\n\n    def do_OPTIONS(req, res)\n      res['allow'] = \"GET,HEAD,POST,OPTIONS,CONNECT\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httprequest.rb",
    "content": "#\n# httprequest.rb -- HTTPRequest Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $\n\nrequire 'timeout'\nrequire 'uri'\n\nrequire 'webrick/httpversion'\nrequire 'webrick/httpstatus'\nrequire 'webrick/httputils'\nrequire 'webrick/cookie'\n\nmodule WEBrick\n\n  class HTTPRequest\n    BODY_CONTAINABLE_METHODS = [ \"POST\", \"PUT\" ]\n    BUFSIZE = 1024*4\n\n    # Request line\n    attr_reader :request_line\n    attr_reader :request_method, :unparsed_uri, :http_version\n\n    # Request-URI\n    attr_reader :request_uri, :host, :port, :path\n    attr_accessor :script_name, :path_info, :query_string\n\n    # Header and entity body\n    attr_reader :raw_header, :header, :cookies\n    attr_reader :accept, :accept_charset\n    attr_reader :accept_encoding, :accept_language\n\n    # Misc\n    attr_accessor :user\n    attr_reader :addr, :peeraddr\n    attr_reader :attributes\n    attr_reader :keep_alive\n    attr_reader :request_time\n\n    def initialize(config)\n      @config = config\n      @logger = config[:Logger]\n\n      @request_line = @request_method =\n        @unparsed_uri = @http_version = nil\n\n      @request_uri = @host = @port = @path = nil\n      @script_name = @path_info = nil\n      @query_string = nil\n      @query = nil\n      @form_data = nil\n\n      @raw_header = Array.new\n      @header = nil\n      @cookies = []\n      @accept = []\n      @accept_charset = []\n      @accept_encoding = []\n      @accept_language = []\n      @body = \"\"\n\n      @addr = @peeraddr = nil\n      @attributes = {}\n      @user = nil\n      @keep_alive = false\n      @request_time = nil\n\n      @remaining_size = nil\n      @socket = nil\n    end\n\n    def parse(socket=nil)\n      @socket = socket\n      begin\n        @peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []\n        @addr = socket.respond_to?(:addr) ? socket.addr : []\n      rescue Errno::ENOTCONN\n        raise HTTPStatus::EOFError\n      end\n\n      read_request_line(socket)\n      if @http_version.major > 0\n        read_header(socket)\n        @header['cookie'].each{|cookie|\n          @cookies += Cookie::parse(cookie)\n        }\n        @accept = HTTPUtils.parse_qvalues(self['accept'])\n        @accept_charset = HTTPUtils.parse_qvalues(self['accept-charset'])\n        @accept_encoding = HTTPUtils.parse_qvalues(self['accept-encoding'])\n        @accept_language = HTTPUtils.parse_qvalues(self['accept-language'])\n      end\n      return if @request_method == \"CONNECT\"\n      return if @unparsed_uri == \"*\"\n\n      begin\n        @request_uri = parse_uri(@unparsed_uri)\n        @path = HTTPUtils::unescape(@request_uri.path)\n        @path = HTTPUtils::normalize_path(@path)\n        @host = @request_uri.host\n        @port = @request_uri.port\n        @query_string = @request_uri.query\n        @script_name = \"\"\n        @path_info = @path.dup\n      rescue\n        raise HTTPStatus::BadRequest, \"bad URI `#{@unparsed_uri}'.\"\n      end\n\n      if /close/io =~ self[\"connection\"]\n        @keep_alive = false\n      elsif /keep-alive/io =~ self[\"connection\"]\n        @keep_alive = true\n      elsif @http_version < \"1.1\"\n        @keep_alive = false\n      else\n        @keep_alive = true\n      end\n    end\n\n    def body(&block)\n      block ||= Proc.new{|chunk| @body << chunk }\n      read_body(@socket, block)\n      @body.empty? ? nil : @body\n    end\n\n    def query\n      unless @query\n        parse_query()\n      end\n      @query\n    end\n\n    def content_length\n      return Integer(self['content-length'])\n    end\n\n    def content_type\n      return self['content-type']\n    end\n\n    def [](header_name)\n      if @header\n        value = @header[header_name.downcase]\n        value.empty? ? nil : value.join(\", \")\n      end\n    end\n\n    def each\n      @header.each{|k, v|\n        value = @header[k]\n        yield(k, value.empty? ? nil : value.join(\", \"))\n      }\n    end\n\n    def keep_alive?\n      @keep_alive\n    end\n\n    def to_s\n      ret = @request_line.dup\n      @raw_header.each{|line| ret << line }\n      ret << CRLF\n      ret << body if body\n      ret\n    end\n\n    def fixup()\n      begin\n        body{|chunk| }   # read remaining body\n      rescue HTTPStatus::Error => ex\n        @logger.error(\"HTTPRequest#fixup: #{ex.class} occured.\")\n        @keep_alive = false\n      rescue => ex\n        @logger.error(ex)\n        @keep_alive = false\n      end\n    end\n\n    def meta_vars\n      # This method provides the metavariables defined by the revision 3\n      # of ``The WWW Common Gateway Interface Version 1.1''.\n      # (http://Web.Golux.Com/coar/cgi/)\n\n      meta = Hash.new\n\n      cl = self[\"Content-Length\"]\n      ct = self[\"Content-Type\"]\n      meta[\"CONTENT_LENGTH\"]    = cl if cl.to_i > 0\n      meta[\"CONTENT_TYPE\"]      = ct.dup if ct\n      meta[\"GATEWAY_INTERFACE\"] = \"CGI/1.1\"\n      meta[\"PATH_INFO\"]         = @path_info ? @path_info.dup : \"\"\n     #meta[\"PATH_TRANSLATED\"]   = nil      # no plan to be provided\n      meta[\"QUERY_STRING\"]      = @query_string ? @query_string.dup : \"\"\n      meta[\"REMOTE_ADDR\"]       = @peeraddr[3]\n      meta[\"REMOTE_HOST\"]       = @peeraddr[2]\n     #meta[\"REMOTE_IDENT\"]      = nil      # no plan to be provided\n      meta[\"REMOTE_USER\"]       = @user\n      meta[\"REQUEST_METHOD\"]    = @request_method.dup\n      meta[\"REQUEST_URI\"]       = @request_uri.to_s\n      meta[\"SCRIPT_NAME\"]       = @script_name.dup\n      meta[\"SERVER_NAME\"]       = @host\n      meta[\"SERVER_PORT\"]       = @port.to_s\n      meta[\"SERVER_PROTOCOL\"]   = \"HTTP/\" + @config[:HTTPVersion].to_s\n      meta[\"SERVER_SOFTWARE\"]   = @config[:ServerSoftware].dup\n\n      self.each{|key, val|\n        next if /^content-type$/i =~ key\n        next if /^content-length$/i =~ key\n        name = \"HTTP_\" + key\n        name.gsub!(/-/o, \"_\")\n        name.upcase!\n        meta[name] = val\n      }\n\n      meta\n    end\n\n    private\n\n    def read_request_line(socket)\n      @request_line = read_line(socket) if socket\n      @request_time = Time.now\n      raise HTTPStatus::EOFError unless @request_line\n      if /^(\\S+)\\s+(\\S+?)(?:\\s+HTTP\\/(\\d+\\.\\d+))?\\r?\\n/mo =~ @request_line\n        @request_method = $1\n        @unparsed_uri   = $2\n        @http_version   = HTTPVersion.new($3 ? $3 : \"0.9\")\n      else\n        rl = @request_line.sub(/\\x0d?\\x0a\\z/o, '')\n        raise HTTPStatus::BadRequest, \"bad Request-Line `#{rl}'.\"\n      end\n    end\n\n    def read_header(socket)\n      if socket\n        while line = read_line(socket)\n          break if /\\A(#{CRLF}|#{LF})\\z/om =~ line\n          @raw_header << line\n        end\n      end\n      @header = HTTPUtils::parse_header(@raw_header.join)\n    end\n\n    def parse_uri(str, scheme=\"http\")\n      if @config[:Escape8bitURI]\n        str = HTTPUtils::escape8bit(str)\n      end\n      uri = URI::parse(str)\n      return uri if uri.absolute?\n      if self[\"host\"]\n        pattern = /\\A(#{URI::REGEXP::PATTERN::HOST})(?::(\\d+))?\\z/n\n        host, port = *self['host'].scan(pattern)[0]\n      elsif @addr.size > 0\n        host, port = @addr[2], @addr[1]\n      else\n        host, port = @config[:ServerName], @config[:Port]\n      end\n      uri.scheme = scheme\n      uri.host = host\n      uri.port = port ? port.to_i : nil\n      return URI::parse(uri.to_s)\n    end\n\n    def read_body(socket, block)\n      return unless socket\n      if tc = self['transfer-encoding']\n        case tc\n        when /chunked/io then read_chunked(socket, block)\n        else raise HTTPStatus::NotImplemented, \"Transfer-Encoding: #{tc}.\"\n        end\n      elsif self['content-length'] || @remaining_size\n        @remaining_size ||= self['content-length'].to_i\n        while @remaining_size > 0 \n          sz = BUFSIZE < @remaining_size ? BUFSIZE : @remaining_size\n          break unless buf = read_data(socket, sz)\n          @remaining_size -= buf.size\n          block.call(buf)\n        end\n        if @remaining_size > 0 && @socket.eof?\n          raise HTTPStatus::BadRequest, \"invalid body size.\"\n        end\n      elsif BODY_CONTAINABLE_METHODS.member?(@request_method)\n        raise HTTPStatus::LengthRequired\n      end\n      return @body\n    end\n\n    def read_chunk_size(socket)\n      line = read_line(socket)\n      if /^([0-9a-fA-F]+)(?:;(\\S+))?/ =~ line\n        chunk_size = $1.hex\n        chunk_ext = $2\n        [ chunk_size, chunk_ext ]\n      else\n        raise HTTPStatus::BadRequest, \"bad chunk `#{line}'.\"\n      end\n    end\n\n    def read_chunked(socket, block)\n      chunk_size, = read_chunk_size(socket)\n      while chunk_size > 0\n        data = \"\"\n        while data.size < chunk_size\n          tmp = read_data(socket, chunk_size-data.size) # read chunk-data\n          break unless tmp\n          data << tmp\n        end\n        if data.nil? || data.size != chunk_size\n          raise BadRequest, \"bad chunk data size.\"\n        end\n        read_line(socket)                    # skip CRLF\n        block.call(data)\n        chunk_size, = read_chunk_size(socket)\n      end\n      read_header(socket)                    # trailer + CRLF\n      @header.delete(\"transfer-encoding\")\n      @remaining_size = 0\n    end\n\n    def _read_data(io, method, arg)\n      begin\n        timeout(@config[:RequestTimeout]){\n          return io.__send__(method, arg)\n        }\n      rescue Errno::ECONNRESET\n        return nil\n      rescue TimeoutError\n        raise HTTPStatus::RequestTimeout\n      end\n    end\n\n    def read_line(io)\n      _read_data(io, :gets, LF)\n    end\n\n    def read_data(io, size)\n      _read_data(io, :read, size)\n    end\n\n    def parse_query()\n      begin\n        if @request_method == \"GET\" || @request_method == \"HEAD\"\n          @query = HTTPUtils::parse_query(@query_string)\n        elsif self['content-type'] =~ /^application\\/x-www-form-urlencoded/\n          @query = HTTPUtils::parse_query(body)\n        elsif self['content-type'] =~ /^multipart\\/form-data; boundary=(.+)/\n          boundary = HTTPUtils::dequote($1)\n          @query = HTTPUtils::parse_form_data(body, boundary)\n        else\n          @query = Hash.new\n        end\n      rescue => ex\n        raise HTTPStatus::BadRequest, ex.message\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpresponse.rb",
    "content": "#\n# httpresponse.rb -- HTTPResponse Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpresponse.rb,v 1.45 2003/07/11 11:02:25 gotoyuzo Exp $\n\nrequire 'time'\nrequire 'webrick/httpversion'\nrequire 'webrick/htmlutils'\nrequire 'webrick/httputils'\nrequire 'webrick/httpstatus'\n\nmodule WEBrick\n  class HTTPResponse\n    BUFSIZE = 1024*4\n\n    attr_reader :http_version, :status, :header\n    attr_reader :cookies\n    attr_accessor :reason_phrase\n    attr_accessor :body\n\n    attr_accessor :request_method, :request_uri, :request_http_version\n    attr_accessor :filename\n    attr_accessor :keep_alive\n    attr_reader :config, :sent_size\n\n    def initialize(config)\n      @config = config\n      @logger = config[:Logger]\n      @header = Hash.new\n      @status = HTTPStatus::RC_OK\n      @reason_phrase = nil\n      @http_version = HTTPVersion::convert(@config[:HTTPVersion])\n      @body = ''\n      @keep_alive = true\n      @cookies = []\n      @request_method = nil\n      @request_uri = nil\n      @request_http_version = @http_version  # temporary\n      @chunked = false\n      @filename = nil\n      @sent_size = 0\n    end\n\n    def status_line\n      \"HTTP/#@http_version #@status #@reason_phrase #{CRLF}\"\n    end\n\n    def status=(status)\n      @status = status\n      @reason_phrase = HTTPStatus::reason_phrase(status)\n    end\n\n    def [](field)\n      @header[field.downcase]\n    end\n\n    def []=(field, value)\n      @header[field.downcase] = value.to_s\n    end\n\n    def content_length\n      if len = self['content-length']\n        return Integer(len)\n      end\n    end\n\n    def content_length=(len)\n      self['content-length'] = len.to_s\n    end\n\n    def content_type\n      self['content-type']\n    end\n\n    def content_type=(type)\n      self['content-type'] = type\n    end\n\n    def each\n      @header.each{|k, v|  yield(k, v) }\n    end\n\n    def chunked?\n      @chunked\n    end\n\n    def chunked=(val)\n      @chunked = val ? true : false\n    end\n\n    def keep_alive?\n      @keep_alive\n    end\n\n    def send_response(socket)\n      begin\n        setup_header()\n        send_header(socket)\n        send_body(socket)\n      rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN => ex\n        @logger.debug(ex)\n        @keep_alive = false\n      rescue Exception => ex\n        @logger.error(ex)\n        @keep_alive = false\n      end\n    end\n\n    def setup_header()\n      @reason_phrase    ||= HTTPStatus::reason_phrase(@status)\n      @header['server'] ||= @config[:ServerSoftware]\n      @header['date']   ||= Time.now.httpdate\n\n      # HTTP/0.9 features\n      if @request_http_version < \"1.0\"\n        @http_version = HTTPVersion.new(\"0.9\")\n        @keep_alive = false\n      end\n\n      # HTTP/1.0 features\n      if @request_http_version < \"1.1\"\n        if chunked?\n          @chunked = false\n          ver = @request_http_version.to_s\n          msg = \"chunked is set for an HTTP/#{ver} request. (ignored)\"\n          @logger.warn(msg)\n        end\n      end\n\n      # Determine the message length (RFC2616 -- 4.4 Message Length)\n      if @status == 304 || @status == 204 || HTTPStatus::info?(@status)\n        @header.delete('content-length')\n        @body = \"\"\n      elsif chunked?\n        @header[\"transfer-encoding\"] = \"chunked\"\n        @header.delete('content-length')\n      elsif %r{^multipart/byteranges} =~ @header['content-type']\n        @header.delete('content-length')\n      elsif @header['content-length'].nil?\n        unless @body.is_a?(IO)\n          @header['content-length'] = @body ? @body.size : 0\n        end\n      end\n\n      # Keep-Alive connection.\n      if @header['connection'] == \"close\"\n         @keep_alive = false\n      elsif keep_alive?\n        if chunked? || @header['content-length']\n          @header['connection'] = \"Keep-Alive\"\n        end\n      else\n        @header['connection'] = \"close\"\n      end\n\n      # Location is a single absoluteURI.\n      if location = @header['location']\n        if @request_uri\n          @header['location'] = @request_uri.merge(location)\n        end\n      end\n    end\n\n    def send_header(socket)\n      if @http_version.major > 0\n        data = status_line()\n        @header.each{|key, value|\n          tmp = key.gsub(/\\bwww|^te$|\\b\\w/){|s| s.upcase }\n          data << \"#{tmp}: #{value}\" << CRLF\n        }\n        @cookies.each{|cookie|\n          data << \"Set-Cookie: \" << cookie.to_s << CRLF\n        }\n        data << CRLF\n        _write_data(socket, data)\n      end\n    end\n\n    def send_body(socket)\n      case @body\n      when IO then send_body_io(socket)\n      else send_body_string(socket)\n      end\n    end\n\n    def to_s\n      ret = \"\"\n      send_response(ret)\n      ret\n    end\n\n    def set_redirect(status, url)\n      @body = \"<HTML><A HREF=\\\"#{url.to_s}\\\">#{url.to_s}</A>.</HTML>\\n\"\n      @header['location'] = url.to_s\n      raise status\n    end\n\n    def set_error(ex, backtrace=false)\n      case ex\n      when HTTPStatus::Status \n        @keep_alive = false if HTTPStatus::error?(ex.code)\n        self.status = ex.code\n      else \n        @keep_alive = false\n        self.status = HTTPStatus::RC_INTERNAL_SERVER_ERROR\n      end\n      @header['content-type'] = \"text/html\"\n\n      if respond_to?(:create_error_page)\n        create_error_page()\n        return\n      end\n\n      if @request_uri\n        host, port = @request_uri.host, @request_uri.port\n      else\n        host, port = @config[:ServerName], @config[:Port]\n      end\n\n      @body = ''\n      @body << <<-_end_of_html_\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\n<HTML>\n  <HEAD><TITLE>#{HTMLUtils::escape(@reason_phrase)}</TITLE></HEAD>\n  <BODY>\n    <H1>#{HTMLUtils::escape(@reason_phrase)}</H1>\n    #{HTMLUtils::escape(ex.message)}\n    <HR>\n      _end_of_html_\n\n      if backtrace && $DEBUG\n        @body << \"backtrace of `#{HTMLUtils::escape(ex.class.to_s)}' \"\n        @body << \"#{HTMLUtils::escape(ex.message)}\"\n        @body << \"<PRE>\"\n        ex.backtrace.each{|line| @body << \"\\t#{line}\\n\"}\n        @body << \"</PRE><HR>\"\n      end\n\n      @body << <<-_end_of_html_\n    <ADDRESS>\n     #{HTMLUtils::escape(@config[:ServerSoftware])} at\n     #{host}:#{port}\n    </ADDRESS>\n  </BODY>\n</HTML>\n      _end_of_html_\n    end\n\n    private\n\n    def send_body_io(socket)\n      begin\n        if @request_method == \"HEAD\"\n          # do nothing\n        elsif chunked?\n          while buf = @body.read(BUFSIZE)\n            next if buf.empty?\n            data = \"\"\n            data << format(\"%x\", buf.size) << CRLF\n            data << buf << CRLF\n            _write_data(socket, data)\n            @sent_size += buf.size\n          end\n          _write_data(socket, \"0#{CRLF}#{CRLF}\")\n        else\n          size = @header['content-length'].to_i\n          _send_file(socket, @body, 0, size)\n          @sent_size = size\n        end\n      ensure\n        @body.close\n      end\n    end\n\n    def send_body_string(socket)\n      if @request_method == \"HEAD\"\n        # do nothing\n      elsif chunked?\n        remain = body ? @body.size : 0\n        while buf = @body[@sent_size, BUFSIZE]\n          break if buf.empty?\n          data = \"\"\n          data << format(\"%x\", buf.size) << CRLF\n          data << buf << CRLF\n          _write_data(socket, data)\n          @sent_size += buf.size\n        end\n        _write_data(socket, \"0#{CRLF}#{CRLF}\")\n      else\n        if @body && @body.size > 0\n          _write_data(socket, @body)\n          @sent_size = @body.size\n        end\n      end\n    end\n\n    def _send_file(output, input, offset, size)\n      while offset > 0\n        sz = BUFSIZE < offset ? BUFSIZE : offset\n        buf = input.read(sz)\n        offset -= buf.size\n      end\n\n      if size == 0\n        while buf = input.read(BUFSIZE)\n          _write_data(output, buf)\n        end\n      else\n        while size > 0\n          sz = BUFSIZE < size ? BUFSIZE : size\n          buf = input.read(sz)\n          _write_data(output, buf)\n          size -= buf.size\n        end\n      end\n    end\n\n    def _write_data(socket, data)\n      socket << data\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/https.rb",
    "content": "#\n# https.rb -- SSL/TLS enhancement for HTTPServer\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2001 GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $\n\nrequire 'webrick/ssl'\n\nmodule WEBrick\n  module Config\n    HTTP.update(SSL)\n  end\n\n  class HTTPRequest\n    attr_reader :cipher, :server_cert, :client_cert\n\n    alias orig_parse parse\n\n    def parse(socket=nil)\n      if socket.respond_to?(:cert)\n        @server_cert = socket.cert || @config[:SSLCertificate]\n        @client_cert = socket.peer_cert\n        @client_cert_chain = socket.peer_cert_chain\n        @cipher      = socket.cipher\n      end\n      orig_parse(socket)\n    end\n\n    alias orig_parse_uri parse_uri\n\n    def parse_uri(str, scheme=\"https\")\n      if @server_cert\n        return orig_parse_uri(str, scheme)\n      end\n      return orig_parse_uri(str)\n    end\n\n    alias orig_meta_vars meta_vars\n\n    def meta_vars\n      meta = orig_meta_vars\n      if @server_cert\n        meta[\"HTTPS\"] = \"on\"\n        meta[\"SSL_SERVER_CERT\"] = @server_cert.to_pem\n        meta[\"SSL_CLIENT_CERT\"] = @client_cert ? @client_cert.to_pem : \"\"\n        if @client_cert_chain\n          @client_cert_chain.each_with_index{|cert, i|\n            meta[\"SSL_CLIENT_CERT_CHAIN_#{i}\"] = cert.to_pem\n          }\n        end\n        meta[\"SSL_CIPHER\"] = @cipher[0]\n        meta[\"SSL_PROTOCOL\"] = @cipher[1]\n        meta[\"SSL_CIPHER_USEKEYSIZE\"] = @cipher[2].to_s\n        meta[\"SSL_CIPHER_ALGKEYSIZE\"] = @cipher[3].to_s\n      end\n      meta\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpserver.rb",
    "content": "#\n# httpserver.rb -- HTTPServer Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $\n\nrequire 'webrick/server'\nrequire 'webrick/httputils'\nrequire 'webrick/httpstatus'\nrequire 'webrick/httprequest'\nrequire 'webrick/httpresponse'\nrequire 'webrick/httpservlet'\nrequire 'webrick/accesslog'\n\nmodule WEBrick\n  class HTTPServerError < ServerError; end\n\n  class HTTPServer < ::WEBrick::GenericServer\n    def initialize(config={}, default=Config::HTTP)\n      super\n      @http_version = HTTPVersion::convert(@config[:HTTPVersion])\n\n      @mount_tab = MountTable.new\n      if @config[:DocumentRoot]\n        mount(\"/\", HTTPServlet::FileHandler, @config[:DocumentRoot],\n              @config[:DocumentRootOptions])\n      end\n\n      unless @config[:AccessLog]\n        @config[:AccessLog] = [\n          [ $stderr, AccessLog::COMMON_LOG_FORMAT ],\n          [ $stderr, AccessLog::REFERER_LOG_FORMAT ]\n        ]\n      end\n \n      @virtual_hosts = Array.new\n    end\n\n    def run(sock)\n      while true \n        res = HTTPResponse.new(@config)\n        req = HTTPRequest.new(@config)\n        server = self\n        begin\n          timeout = @config[:RequestTimeout]\n          while timeout > 0\n            break if IO.select([sock], nil, nil, 0.5)\n            timeout = 0 if @status != :Running\n            timeout -= 0.5\n          end\n          raise HTTPStatus::EOFError if timeout <= 0 || sock.eof?\n          req.parse(sock)\n          res.request_method = req.request_method\n          res.request_uri = req.request_uri\n          res.request_http_version = req.http_version\n          res.keep_alive = req.keep_alive?\n          server = lookup_server(req) || self\n          if callback = server[:RequestCallback] || server[:RequestHandler]\n            callback.call(req, res)\n          end\n          server.service(req, res)\n        rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex\n          res.set_error(ex)\n        rescue HTTPStatus::Error => ex\n          @logger.error(ex.message)\n          res.set_error(ex)\n        rescue HTTPStatus::Status => ex\n          res.status = ex.code\n        rescue StandardError => ex\n          @logger.error(ex)\n          res.set_error(ex, true)\n        ensure\n          if req.request_line\n            req.fixup()\n            res.send_response(sock)\n            server.access_log(@config, req, res)\n          end\n        end\n        break if @http_version < \"1.1\"\n        break unless req.keep_alive?\n        break unless res.keep_alive?\n      end\n    end\n\n    def service(req, res)\n      if req.unparsed_uri == \"*\"\n        if req.request_method == \"OPTIONS\"\n          do_OPTIONS(req, res)\n          raise HTTPStatus::OK\n        end\n        raise HTTPStatus::NotFound, \"`#{req.unparsed_uri}' not found.\"\n      end\n\n      servlet, options, script_name, path_info = search_servlet(req.path)\n      raise HTTPStatus::NotFound, \"`#{req.path}' not found.\" unless servlet\n      req.script_name = script_name\n      req.path_info = path_info\n      si = servlet.get_instance(self, *options)\n      @logger.debug(format(\"%s is invoked.\", si.class.name))\n      si.service(req, res)\n    end\n\n    def do_OPTIONS(req, res)\n      res[\"allow\"] = \"GET,HEAD,POST,OPTIONS\"\n    end\n\n    def mount(dir, servlet, *options)\n      @logger.debug(sprintf(\"%s is mounted on %s.\", servlet.inspect, dir))\n      @mount_tab[dir] = [ servlet, options ]\n    end\n\n    def mount_proc(dir, proc=nil, &block)\n      proc ||= block\n      raise HTTPServerError, \"must pass a proc or block\" unless proc\n      mount(dir, HTTPServlet::ProcHandler.new(proc))\n    end\n\n    def unmount(dir)\n      @logger.debug(sprintf(\"unmount %s.\", dir))\n      @mount_tab.delete(dir)\n    end\n    alias umount unmount\n\n    def search_servlet(path)\n      script_name, path_info = @mount_tab.scan(path)\n      servlet, options = @mount_tab[script_name]\n      if servlet\n        [ servlet, options, script_name, path_info ]\n      end\n    end\n\n    def virtual_host(server)\n      @virtual_hosts << server\n      @virtual_hosts = @virtual_hosts.sort_by{|s|\n        num = 0\n        num -= 4 if s[:BindAddress]\n        num -= 2 if s[:Port]\n        num -= 1 if s[:ServerName]\n        num\n      }\n    end\n\n    def lookup_server(req)\n      @virtual_hosts.find{|s|\n        (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&\n        (s[:Port].nil?        || req.port == s[:Port])           &&\n        ((s[:ServerName].nil?  || req.host == s[:ServerName]) ||\n         (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))\n      }\n    end\n\n    def access_log(config, req, res)\n      param = AccessLog::setup_params(config, req, res)\n      @config[:AccessLog].each{|logger, fmt|\n        logger << AccessLog::format(fmt+\"\\n\", param)\n      }\n    end\n\n    class MountTable\n      def initialize\n        @tab = Hash.new\n        compile\n      end\n\n      def [](dir)\n        dir = normalize(dir)\n        @tab[dir]\n      end\n\n      def []=(dir, val)\n        dir = normalize(dir)\n        @tab[dir] = val\n        compile\n        val\n      end\n\n      def delete(dir)\n        dir = normalize(dir)\n        res = @tab.delete(dir)\n        compile\n        res\n      end\n\n      def scan(path)\n        @scanner =~ path\n        [ $&, $' ]\n      end\n\n      private\n\n      def compile\n        k = @tab.keys\n        k.sort!\n        k.reverse!\n        k.collect!{|path| Regexp.escape(path) }\n        @scanner = Regexp.new(\"^(\" + k.join(\"|\") +\")(?=/|$)\")\n      end\n\n      def normalize(dir)\n        ret = dir ? dir.dup : \"\"\n        ret.sub!(%r|/+$|, \"\")\n        ret\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpservlet/abstract.rb",
    "content": "#\n# httpservlet.rb -- HTTPServlet Module\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $\n\nrequire 'thread'\n\nrequire 'webrick/htmlutils'\nrequire 'webrick/httputils'\nrequire 'webrick/httpstatus'\n\nmodule WEBrick\n  module HTTPServlet\n    class HTTPServletError < StandardError; end\n\n    class AbstractServlet\n      def self.get_instance(config, *options)\n        self.new(config, *options)\n      end\n\n      def initialize(server, *options)\n        @server = @config = server\n        @logger = @server[:Logger]\n        @options = options\n      end\n\n      def service(req, res)\n        method_name = \"do_\" + req.request_method.gsub(/-/, \"_\")\n        if respond_to?(method_name)\n          __send__(method_name, req, res)\n        else\n          raise HTTPStatus::MethodNotAllowed,\n                \"unsupported method `#{req.request_method}'.\"\n        end\n      end\n\n      def do_GET(req, res)\n        raise HTTPStatus::NotFound, \"not found.\"\n      end\n\n      def do_HEAD(req, res)\n        do_GET(req, res)\n      end\n\n      def do_OPTIONS(req, res)\n        m = self.methods.grep(/^do_[A-Z]+$/)\n        m.collect!{|i| i.sub(/do_/, \"\") }\n        m.sort!\n        res[\"allow\"] = m.join(\",\")\n      end\n\n      private\n\n      def redirect_to_directory_uri(req, res)\n        if req.path[-1] != ?/\n          location = WEBrick::HTTPUtils.escape_path(req.path + \"/\")\n          if req.query_string && req.query_string.size > 0\n            location << \"?\" << req.query_string\n          end\n          res.set_redirect(HTTPStatus::MovedPermanently, location)\n        end\n      end\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpservlet/cgi_runner.rb",
    "content": "#\n# cgi_runner.rb -- CGI launcher.\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $\n\ndef sysread(io, size)\n  buf = \"\"\n  while size > 0\n    tmp = io.sysread(size)\n    buf << tmp\n    size -= tmp.size\n  end\n  return buf\nend\n\nSTDIN.binmode\n\nbuf = \"\"\nlen = sysread(STDIN, 8).to_i\nout = sysread(STDIN, len)\nSTDOUT.reopen(open(out, \"w\"))\n\nlen = sysread(STDIN, 8).to_i\nerr = sysread(STDIN, len)\nSTDERR.reopen(open(err, \"w\"))\n\nlen  = sysread(STDIN, 8).to_i\ndump = sysread(STDIN, len)\nhash = Marshal.restore(dump)\nENV.keys.each{|name| ENV.delete(name) }\nhash.each{|k, v| ENV[k] = v if v }\n\ndir = File::dirname(ENV[\"SCRIPT_FILENAME\"])\nDir::chdir dir\n\nif interpreter = ARGV[0]\n  argv = ARGV.dup\n  argv << ENV[\"SCRIPT_FILENAME\"]\n  exec(*argv)\n  # NOTREACHED\nend\nexec ENV[\"SCRIPT_FILENAME\"]\n"
  },
  {
    "path": "lib/webrick/httpservlet/cgihandler.rb",
    "content": "# \n# cgihandler.rb -- CGIHandler Class\n#       \n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#   \n# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $\n\nrequire 'rbconfig'\nrequire 'tempfile'\nrequire 'webrick/config'\nrequire 'webrick/httpservlet/abstract'\n\nmodule WEBrick\n  module HTTPServlet\n\n    class CGIHandler < AbstractServlet\n      Ruby = File::join(::Config::CONFIG['bindir'],\n                        ::Config::CONFIG['ruby_install_name'])\n      Ruby << ::Config::CONFIG['EXEEXT']\n      CGIRunner = \"\\\"#{Ruby}\\\" \\\"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\\\"\"\n\n      def initialize(server, name)\n        super\n        @script_filename = name\n        @tempdir = server[:TempDir]\n        @cgicmd = \"#{CGIRunner} #{server[:CGIInterpreter]}\"\n      end\n\n      def do_GET(req, res)\n        data = nil\n        status = -1\n\n        cgi_in = IO::popen(@cgicmd, \"wb\")\n        cgi_out = Tempfile.new(\"webrick.cgiout.\", @tempdir)\n        cgi_err = Tempfile.new(\"webrick.cgierr.\", @tempdir)\n        begin\n          cgi_in.sync = true\n          meta = req.meta_vars\n          meta[\"SCRIPT_FILENAME\"] = @script_filename\n          meta[\"PATH\"] = @config[:CGIPathEnv]\n          if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM\n            meta[\"SystemRoot\"] = ENV[\"SystemRoot\"]\n          end\n          dump = Marshal.dump(meta)\n\n          cgi_in.write(\"%8d\" % cgi_out.path.size)\n          cgi_in.write(cgi_out.path)\n          cgi_in.write(\"%8d\" % cgi_err.path.size)\n          cgi_in.write(cgi_err.path)\n          cgi_in.write(\"%8d\" % dump.size)\n          cgi_in.write(dump)\n\n          if req.body and req.body.size > 0\n            cgi_in.write(req.body)\n          end\n        ensure\n          cgi_in.close\n          status = $?.exitstatus\n          sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM\n          data = cgi_out.read\n          cgi_out.close(true)\n          if errmsg = cgi_err.read\n            if errmsg.size > 0\n              @logger.error(\"CGIHandler: #{@script_filename}:\\n\" + errmsg)\n            end\n          end \n          cgi_err.close(true)\n        end\n        \n        if status != 0\n          @logger.error(\"CGIHandler: #{@script_filename} exit with #{status}\")\n        end\n\n        data = \"\" unless data\n        raw_header, body = data.split(/^[\\xd\\xa]+/on, 2) \n        raise HTTPStatus::InternalServerError,\n          \"Premature end of script headers: #{@script_filename}\" if body.nil?\n\n        begin\n          header = HTTPUtils::parse_header(raw_header)\n          if /^(\\d+)/ =~ header['status'][0]\n            res.status = $1.to_i\n            header.delete('status')\n          end\n          if header.has_key?('location')\n            # RFC 3875 6.2.3, 6.2.4\n            res.status = 302 unless (300...400) === res.status\n          end\n          if header.has_key?('set-cookie')\n            header['set-cookie'].each{|k|\n              res.cookies << Cookie.parse_set_cookie(k)\n            }\n            header.delete('set-cookie')\n          end\n          header.each{|key, val| res[key] = val.join(\", \") }\n        rescue => ex\n          raise HTTPStatus::InternalServerError, ex.message\n        end\n        res.body = body\n      end\n      alias do_POST do_GET\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpservlet/erbhandler.rb",
    "content": "# \n# erbhandler.rb -- ERBHandler Class\n# \n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n# \n# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $\n\nrequire 'webrick/httpservlet/abstract.rb'\n\nrequire 'erb'\n\nmodule WEBrick\n  module HTTPServlet\n\n    class ERBHandler < AbstractServlet\n      def initialize(server, name)\n        super\n        @script_filename = name\n      end\n\n      def do_GET(req, res)\n        unless defined?(ERB)\n          @logger.warn \"#{self.class}: ERB not defined.\"\n          raise HTTPStatus::Forbidden, \"ERBHandler cannot work.\"\n        end\n        begin\n          data = open(@script_filename){|io| io.read }\n          res.body = evaluate(ERB.new(data), req, res)\n          res['content-type'] =\n            HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])\n        rescue StandardError => ex\n          raise\n        rescue Exception => ex\n          @logger.error(ex)\n          raise HTTPStatus::InternalServerError, ex.message\n        end\n      end\n\n      alias do_POST do_GET\n\n      private\n      def evaluate(erb, servlet_request, servlet_response)\n        Module.new.module_eval{\n          meta_vars = servlet_request.meta_vars\n          query = servlet_request.query\n          erb.result(binding)\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpservlet/filehandler.rb",
    "content": "#\n# filehandler.rb -- FileHandler Module\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $\n\nrequire 'thread'\nrequire 'time'\n\nrequire 'webrick/htmlutils'\nrequire 'webrick/httputils'\nrequire 'webrick/httpstatus'\n\nmodule WEBrick\n  module HTTPServlet\n\n    class DefaultFileHandler < AbstractServlet\n      def initialize(server, local_path)\n        super\n        @local_path = local_path\n      end\n\n      def do_GET(req, res)\n        st = File::stat(@local_path)\n        mtime = st.mtime\n        res['etag'] = sprintf(\"%x-%x-%x\", st.ino, st.size, st.mtime.to_i)\n\n        if not_modified?(req, res, mtime, res['etag'])\n          res.body = ''\n          raise HTTPStatus::NotModified\n        elsif req['range'] \n          make_partial_content(req, res, @local_path, st.size)\n          raise HTTPStatus::PartialContent\n        else\n          mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])\n          res['content-type'] = mtype\n          res['content-length'] = st.size\n          res['last-modified'] = mtime.httpdate\n          res.body = open(@local_path, \"rb\")\n        end\n      end\n\n      def not_modified?(req, res, mtime, etag)\n        if ir = req['if-range']\n          begin\n            if Time.httpdate(ir) >= mtime\n              return true\n            end\n          rescue\n            if HTTPUtils::split_header_value(ir).member?(res['etag'])\n              return true\n            end\n          end\n        end\n\n        if (ims = req['if-modified-since']) && Time.parse(ims) >= mtime\n          return true\n        end\n\n        if (inm = req['if-none-match']) &&\n           HTTPUtils::split_header_value(inm).member?(res['etag'])\n          return true\n        end\n\n        return false\n      end\n\n      def make_partial_content(req, res, filename, filesize)\n        mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])\n        unless ranges = HTTPUtils::parse_range_header(req['range'])\n          raise HTTPStatus::BadRequest,\n            \"Unrecognized range-spec: \\\"#{req['range']}\\\"\"\n        end\n        open(filename, \"rb\"){|io|\n          if ranges.size > 1\n            time = Time.now\n            boundary = \"#{time.sec}_#{time.usec}_#{Process::pid}\"\n            body = ''\n            ranges.each{|range|\n              first, last = prepare_range(range, filesize)\n              next if first < 0\n              io.pos = first\n              content = io.read(last-first+1)\n              body << \"--\" << boundary << CRLF\n              body << \"Content-Type: #{mtype}\" << CRLF\n              body << \"Content-Range: #{first}-#{last}/#{filesize}\" << CRLF\n              body << CRLF\n              body << content\n              body << CRLF\n            }\n            raise HTTPStatus::RequestRangeNotSatisfiable if body.empty?\n            body << \"--\" << boundary << \"--\" << CRLF\n            res[\"content-type\"] = \"multipart/byteranges; boundary=#{boundary}\"\n            res.body = body\n          elsif range = ranges[0]\n            first, last = prepare_range(range, filesize)\n            raise HTTPStatus::RequestRangeNotSatisfiable if first < 0\n            if last == filesize - 1\n              content = io.dup\n              content.pos = first\n            else\n              io.pos = first\n              content = io.read(last-first+1)\n            end\n            res['content-type'] = mtype\n            res['content-range'] = \"#{first}-#{last}/#{filesize}\"\n            res['content-length'] = last - first + 1\n            res.body = content\n          else\n            raise HTTPStatus::BadRequest\n          end\n        }\n      end\n\n      def prepare_range(range, filesize)\n        first = range.first < 0 ? filesize + range.first : range.first\n        return -1, -1 if first < 0 || first >= filesize\n        last = range.last < 0 ? filesize + range.last : range.last\n        last = filesize - 1 if last >= filesize\n        return first, last\n      end\n    end\n\n    class FileHandler < AbstractServlet\n      HandlerTable = Hash.new\n\n      def self.add_handler(suffix, handler)\n        HandlerTable[suffix] = handler\n      end\n\n      def self.remove_handler(suffix)\n        HandlerTable.delete(suffix)\n      end\n\n      def initialize(server, root, options={}, default=Config::FileHandler)\n        @config = server.config\n        @logger = @config[:Logger]\n        @root = File.expand_path(root)\n        if options == true || options == false\n          options = { :FancyIndexing => options }\n        end\n        @options = default.dup.update(options)\n      end\n\n      def service(req, res)\n        # if this class is mounted on \"/\" and /~username is requested.\n        # we're going to override path informations before invoking service.\n        if defined?(Etc) && @options[:UserDir] && req.script_name.empty?\n          if %r|^(/~([^/]+))| =~ req.path_info\n            script_name, user = $1, $2\n            path_info = $'\n            begin\n              passwd = Etc::getpwnam(user)\n              @root = File::join(passwd.dir, @options[:UserDir])\n              req.script_name = script_name\n              req.path_info = path_info\n            rescue\n              @logger.debug \"#{self.class}#do_GET: getpwnam(#{user}) failed\"\n            end\n          end\n        end\n        prevent_directory_traversal(req, res)\n        super(req, res)\n      end\n\n      def do_GET(req, res)\n        unless exec_handler(req, res)\n          set_dir_list(req, res)\n        end\n      end\n\n      def do_POST(req, res)\n        unless exec_handler(req, res)\n          raise HTTPStatus::NotFound, \"`#{req.path}' not found.\"\n        end\n      end\n\n      def do_OPTIONS(req, res)\n        unless exec_handler(req, res)\n          super(req, res)\n        end\n      end\n\n      # ToDo\n      # RFC2518: HTTP Extensions for Distributed Authoring -- WEBDAV\n      #\n      # PROPFIND PROPPATCH MKCOL DELETE PUT COPY MOVE\n      # LOCK UNLOCK\n\n      # RFC3253: Versioning Extensions to WebDAV\n      #          (Web Distributed Authoring and Versioning)\n      #\n      # VERSION-CONTROL REPORT CHECKOUT CHECK_IN UNCHECKOUT\n      # MKWORKSPACE UPDATE LABEL MERGE ACTIVITY\n\n      private\n\n      def trailing_pathsep?(path)\n        # check for trailing path separator:\n        #   File.dirname(\"/aaaa/bbbb/\")      #=> \"/aaaa\")\n        #   File.dirname(\"/aaaa/bbbb/x\")     #=> \"/aaaa/bbbb\")\n        #   File.dirname(\"/aaaa/bbbb\")       #=> \"/aaaa\")\n        #   File.dirname(\"/aaaa/bbbbx\")      #=> \"/aaaa\")\n        return File.dirname(path) != File.dirname(path+\"x\")\n      end\n\n      def prevent_directory_traversal(req, res)\n        # Preventing directory traversal on Windows platforms;\n        # Backslashes (0x5c) in path_info are not interpreted as special\n        # character in URI notation. So the value of path_info should be\n        # normalize before accessing to the filesystem.\n\n        if trailing_pathsep?(req.path_info)\n          # File.expand_path removes the trailing path separator.\n          # Adding a character is a workaround to save it.\n          #  File.expand_path(\"/aaa/\")        #=> \"/aaa\"\n          #  File.expand_path(\"/aaa/\" + \"x\")  #=> \"/aaa/x\"\n          expanded = File.expand_path(req.path_info + \"x\")\n          expanded.chop!  # remove trailing \"x\"\n        else\n          expanded = File.expand_path(req.path_info)\n        end\n        req.path_info = expanded\n      end\n\n      def exec_handler(req, res)\n        raise HTTPStatus::NotFound, \"`#{req.path}' not found\" unless @root\n        if set_filename(req, res)\n          handler = get_handler(req, res)\n          call_callback(:HandlerCallback, req, res)\n          h = handler.get_instance(@config, res.filename)\n          h.service(req, res)\n          return true\n        end\n        call_callback(:HandlerCallback, req, res)\n        return false\n      end\n\n      def get_handler(req, res)\n        suffix1 = (/\\.(\\w+)\\z/ =~ res.filename) && $1.downcase\n        if /\\.(\\w+)\\.([\\w\\-]+)\\z/ =~ res.filename\n          if @options[:AcceptableLanguages].include?($2.downcase)\n            suffix2 = $1.downcase\n          end\n        end\n        handler_table = @options[:HandlerTable]\n        return handler_table[suffix1] || handler_table[suffix2] ||\n               HandlerTable[suffix1] || HandlerTable[suffix2] ||\n               DefaultFileHandler\n      end\n\n      def set_filename(req, res)\n        res.filename = @root.dup\n        path_info = req.path_info.scan(%r|/[^/]*|)\n\n        path_info.unshift(\"\")  # dummy for checking @root dir\n        while base = path_info.first\n          break if base == \"/\"\n          break unless File.directory?(File.expand_path(res.filename + base))\n          shift_path_info(req, res, path_info)\n          call_callback(:DirectoryCallback, req, res)\n        end\n\n        if base = path_info.first\n          if base == \"/\"\n            if file = search_index_file(req, res)\n              shift_path_info(req, res, path_info, file)\n              call_callback(:FileCallback, req, res)\n              return true\n            end\n            shift_path_info(req, res, path_info)\n          elsif file = search_file(req, res, base)\n            shift_path_info(req, res, path_info, file)\n            call_callback(:FileCallback, req, res)\n            return true\n          else\n            raise HTTPStatus::NotFound, \"`#{req.path}' not found.\"\n          end\n        end\n\n        return false\n      end\n\n      def check_filename(req, res, name)\n        if nondisclosure_name?(name) || windows_ambiguous_name?(name)\n          @logger.warn(\"the request refers nondisclosure name `#{name}'.\")\n          raise HTTPStatus::NotFound, \"`#{req.path}' not found.\"\n        end\n      end\n\n      def shift_path_info(req, res, path_info, base=nil)\n        tmp = path_info.shift\n        base = base || tmp\n        req.path_info = path_info.join\n        req.script_name << base\n        res.filename = File.expand_path(res.filename + base)\n        check_filename(req, res, File.basename(res.filename))\n      end\n\n      def search_index_file(req, res)\n        @config[:DirectoryIndex].each{|index|\n          if file = search_file(req, res, \"/\"+index)\n            return file\n          end\n        }\n        return nil\n      end\n\n      def search_file(req, res, basename)\n        langs = @options[:AcceptableLanguages]\n        path = res.filename + basename\n        if File.file?(path)\n          return basename\n        elsif langs.size > 0\n          req.accept_language.each{|lang|\n            path_with_lang = path + \".#{lang}\"\n            if langs.member?(lang) && File.file?(path_with_lang)\n              return basename + \".#{lang}\"\n            end\n          }\n          (langs - req.accept_language).each{|lang|\n            path_with_lang = path + \".#{lang}\"\n            if File.file?(path_with_lang)\n              return basename + \".#{lang}\"\n            end\n          }\n        end\n        return nil\n      end\n\n      def call_callback(callback_name, req, res)\n        if cb = @options[callback_name]\n          cb.call(req, res)\n        end\n      end\n\n      def windows_ambiguous_name?(name)\n        return true if /[. ]+\\z/ =~ name\n        return true if /::\\$DATA\\z/ =~ name\n        return false\n      end\n\n      def nondisclosure_name?(name)\n        @options[:NondisclosureName].each{|pattern|\n          if File.fnmatch(pattern, name, File::FNM_CASEFOLD)\n            return true\n          end\n        }\n        return false\n      end\n\n      def set_dir_list(req, res)\n        redirect_to_directory_uri(req, res)\n        unless @options[:FancyIndexing]\n          raise HTTPStatus::Forbidden, \"no access permission to `#{req.path}'\"\n        end\n        local_path = res.filename\n        list = Dir::entries(local_path).collect{|name|\n          next if name == \".\" || name == \"..\"\n          next if nondisclosure_name?(name)\n          next if windows_ambiguous_name?(name)\n          st = (File::stat(File.join(local_path, name)) rescue nil)\n          if st.nil?\n            [ name, nil, -1 ]\n          elsif st.directory?\n            [ name + \"/\", st.mtime, -1 ]\n          else\n            [ name, st.mtime, st.size ]\n          end\n        }\n        list.compact!\n\n        if    d0 = req.query[\"N\"]; idx = 0\n        elsif d0 = req.query[\"M\"]; idx = 1\n        elsif d0 = req.query[\"S\"]; idx = 2\n        else  d0 = \"A\"           ; idx = 0\n        end\n        d1 = (d0 == \"A\") ? \"D\" : \"A\"\n\n        if d0 == \"A\"\n          list.sort!{|a,b| a[idx] <=> b[idx] }\n        else\n          list.sort!{|a,b| b[idx] <=> a[idx] }\n        end\n\n        res['content-type'] = \"text/html\"\n\n        res.body = <<-_end_of_html_\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n<HTML>\n  <HEAD><TITLE>Index of #{HTMLUtils::escape(req.path)}</TITLE></HEAD>\n  <BODY>\n    <H1>Index of #{HTMLUtils::escape(req.path)}</H1>\n        _end_of_html_\n\n        res.body << \"<PRE>\\n\"\n        res.body << \" <A HREF=\\\"?N=#{d1}\\\">Name</A>                          \"\n        res.body << \"<A HREF=\\\"?M=#{d1}\\\">Last modified</A>         \"\n        res.body << \"<A HREF=\\\"?S=#{d1}\\\">Size</A>\\n\"\n        res.body << \"<HR>\\n\"\n       \n        list.unshift [ \"..\", File::mtime(local_path+\"/..\"), -1 ]\n        list.each{ |name, time, size|\n          if name == \"..\"\n            dname = \"Parent Directory\"\n          elsif name.size > 25\n            dname = name.sub(/^(.{23})(.*)/){ $1 + \"..\" }\n          else\n            dname = name\n          end\n          s =  \" <A HREF=\\\"#{HTTPUtils::escape(name)}\\\">#{dname}</A>\"\n          s << \" \" * (30 - dname.size)\n          s << (time ? time.strftime(\"%Y/%m/%d %H:%M      \") : \" \" * 22)\n          s << (size >= 0 ? size.to_s : \"-\") << \"\\n\"\n          res.body << s\n        }\n        res.body << \"</PRE><HR>\"\n\n        res.body << <<-_end_of_html_    \n    <ADDRESS>\n     #{HTMLUtils::escape(@config[:ServerSoftware])}<BR>\n     at #{req.host}:#{req.port}\n    </ADDRESS>\n  </BODY>\n</HTML>\n        _end_of_html_\n      end\n\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpservlet/prochandler.rb",
    "content": "# \n# prochandler.rb -- ProcHandler Class\n#       \n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#   \n# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $\n\nrequire 'webrick/httpservlet/abstract.rb'\n\nmodule WEBrick\n  module HTTPServlet\n\n    class ProcHandler < AbstractServlet\n      def get_instance(server, *options)\n        self\n      end  \n\n      def initialize(proc)\n        @proc = proc\n      end\n\n      def do_GET(request, response)\n        @proc.call(request, response)\n      end\n\n      alias do_POST do_GET\n    end\n\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpservlet.rb",
    "content": "#\n# httpservlet.rb -- HTTPServlet Utility File\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $\n\nrequire 'webrick/httpservlet/abstract'\nrequire 'webrick/httpservlet/filehandler'\nrequire 'webrick/httpservlet/cgihandler'\nrequire 'webrick/httpservlet/erbhandler'\nrequire 'webrick/httpservlet/prochandler'\n\nmodule WEBrick\n  module HTTPServlet\n    FileHandler.add_handler(\"cgi\", CGIHandler)\n    FileHandler.add_handler(\"rhtml\", ERBHandler)\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpstatus.rb",
    "content": "#\n# httpstatus.rb -- HTTPStatus Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $\n\nmodule WEBrick\n\n  module HTTPStatus\n\n    class Status      < StandardError\n      def initialize(message=self.class, *rest)\n        super(AccessLog.escape(message), *rest)\n      end\n      class << self\n        attr_reader :code, :reason_phrase\n      end\n      def code() self::class::code end\n      def reason_phrase() self::class::reason_phrase end\n      alias to_i code\n    end\n    class Info        < Status; end\n    class Success     < Status; end\n    class Redirect    < Status; end\n    class Error       < Status; end\n    class ClientError < Error; end\n    class ServerError < Error; end\n    \n    class EOFError < StandardError; end\n\n    StatusMessage = {\n      100, 'Continue',\n      101, 'Switching Protocols',\n      200, 'OK',\n      201, 'Created',\n      202, 'Accepted',\n      203, 'Non-Authoritative Information',\n      204, 'No Content',\n      205, 'Reset Content',\n      206, 'Partial Content',\n      300, 'Multiple Choices',\n      301, 'Moved Permanently',\n      302, 'Found',\n      303, 'See Other',\n      304, 'Not Modified',\n      305, 'Use Proxy',\n      307, 'Temporary Redirect',\n      400, 'Bad Request',\n      401, 'Unauthorized',\n      402, 'Payment Required',\n      403, 'Forbidden',\n      404, 'Not Found',\n      405, 'Method Not Allowed',\n      406, 'Not Acceptable',\n      407, 'Proxy Authentication Required',\n      408, 'Request Timeout',\n      409, 'Conflict',\n      410, 'Gone',\n      411, 'Length Required',\n      412, 'Precondition Failed',\n      413, 'Request Entity Too Large',\n      414, 'Request-URI Too Large',\n      415, 'Unsupported Media Type',\n      416, 'Request Range Not Satisfiable',\n      417, 'Expectation Failed',\n      500, 'Internal Server Error',\n      501, 'Not Implemented',\n      502, 'Bad Gateway',\n      503, 'Service Unavailable',\n      504, 'Gateway Timeout',\n      505, 'HTTP Version Not Supported'\n    }\n\n    CodeToError = {}\n\n    StatusMessage.each{|code, message|\n      message.freeze\n      var_name = message.gsub(/[ \\-]/,'_').upcase\n      err_name = message.gsub(/[ \\-]/,'')\n\n      case code\n      when 100...200; parent = Info\n      when 200...300; parent = Success\n      when 300...400; parent = Redirect\n      when 400...500; parent = ClientError\n      when 500...600; parent = ServerError\n      end\n\n      const_set(\"RC_#{var_name}\", code)\n      err_class = Class.new(parent)\n      err_class.instance_variable_set(:@code, code)\n      err_class.instance_variable_set(:@reason_phrase, message)\n      const_set(err_name, err_class)\n      CodeToError[code] = err_class\n    }\n\n    def reason_phrase(code)\n      StatusMessage[code.to_i]\n    end\n    def info?(code)\n      code.to_i >= 100 and code.to_i < 200\n    end\n    def success?(code)\n      code.to_i >= 200 and code.to_i < 300\n    end\n    def redirect?(code)\n      code.to_i >= 300 and code.to_i < 400\n    end\n    def error?(code)\n      code.to_i >= 400 and code.to_i < 600\n    end\n    def client_error?(code)\n      code.to_i >= 400 and code.to_i < 500\n    end\n    def server_error?(code)\n      code.to_i >= 500 and code.to_i < 600\n    end\n\n    def self.[](code)\n      CodeToError[code]\n    end\n\n    module_function :reason_phrase\n    module_function :info?, :success?, :redirect?, :error?\n    module_function :client_error?, :server_error?\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httputils.rb",
    "content": "#\n# httputils.rb -- HTTPUtils Module\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $\n\nrequire 'socket'\nrequire 'tempfile'\n\nmodule WEBrick\n  CR   = \"\\x0d\"\n  LF   = \"\\x0a\"\n  CRLF = \"\\x0d\\x0a\"\n\n  module HTTPUtils\n\n    def normalize_path(path)\n      raise \"abnormal path `#{path}'\" if path[0] != ?/\n      ret = path.dup\n\n      ret.gsub!(%r{/+}o, '/')                    # //      => /\n      while ret.sub!(%r'/\\.(?:/|\\Z)', '/'); end  # /.      => /\n      while ret.sub!(%r'/(?!\\.\\./)[^/]+/\\.\\.(?:/|\\Z)', '/'); end # /foo/.. => /foo\n\n      raise \"abnormal path `#{path}'\" if %r{/\\.\\.(/|\\Z)} =~ ret\n      ret\n    end\n    module_function :normalize_path\n\n    #####\n\n    DefaultMimeTypes = {\n      \"ai\"    => \"application/postscript\",\n      \"asc\"   => \"text/plain\",\n      \"avi\"   => \"video/x-msvideo\",\n      \"bin\"   => \"application/octet-stream\",\n      \"bmp\"   => \"image/bmp\",\n      \"class\" => \"application/octet-stream\",\n      \"cer\"   => \"application/pkix-cert\",\n      \"crl\"   => \"application/pkix-crl\",\n      \"crt\"   => \"application/x-x509-ca-cert\",\n     #\"crl\"   => \"application/x-pkcs7-crl\",\n      \"css\"   => \"text/css\",\n      \"dms\"   => \"application/octet-stream\",\n      \"doc\"   => \"application/msword\",\n      \"dvi\"   => \"application/x-dvi\",\n      \"eps\"   => \"application/postscript\",\n      \"etx\"   => \"text/x-setext\",\n      \"exe\"   => \"application/octet-stream\",\n      \"gif\"   => \"image/gif\",\n      \"htm\"   => \"text/html\",\n      \"html\"  => \"text/html\",\n      \"jpe\"   => \"image/jpeg\",\n      \"jpeg\"  => \"image/jpeg\",\n      \"jpg\"   => \"image/jpeg\",\n      \"lha\"   => \"application/octet-stream\",\n      \"lzh\"   => \"application/octet-stream\",\n      \"mov\"   => \"video/quicktime\",\n      \"mpe\"   => \"video/mpeg\",\n      \"mpeg\"  => \"video/mpeg\",\n      \"mpg\"   => \"video/mpeg\",\n      \"pbm\"   => \"image/x-portable-bitmap\",\n      \"pdf\"   => \"application/pdf\",\n      \"pgm\"   => \"image/x-portable-graymap\",\n      \"png\"   => \"image/png\",\n      \"pnm\"   => \"image/x-portable-anymap\",\n      \"ppm\"   => \"image/x-portable-pixmap\",\n      \"ppt\"   => \"application/vnd.ms-powerpoint\",\n      \"ps\"    => \"application/postscript\",\n      \"qt\"    => \"video/quicktime\",\n      \"ras\"   => \"image/x-cmu-raster\",\n      \"rb\"    => \"text/plain\",\n      \"rd\"    => \"text/plain\",\n      \"rtf\"   => \"application/rtf\",\n      \"sgm\"   => \"text/sgml\",\n      \"sgml\"  => \"text/sgml\",\n      \"tif\"   => \"image/tiff\",\n      \"tiff\"  => \"image/tiff\",\n      \"txt\"   => \"text/plain\",\n      \"xbm\"   => \"image/x-xbitmap\",\n      \"xls\"   => \"application/vnd.ms-excel\",\n      \"xml\"   => \"text/xml\",\n      \"xpm\"   => \"image/x-xpixmap\",\n      \"xwd\"   => \"image/x-xwindowdump\",\n      \"zip\"   => \"application/zip\",\n    }\n\n    # Load Apache compatible mime.types file.\n    def load_mime_types(file)\n      open(file){ |io|\n        hash = Hash.new\n        io.each{ |line|\n          next if /^#/ =~ line\n          line.chomp!\n          mimetype, ext0 = line.split(/\\s+/, 2)\n          next unless ext0   \n          next if ext0.empty?\n          ext0.split(/\\s+/).each{ |ext| hash[ext] = mimetype }\n        }\n        hash\n      }\n    end\n    module_function :load_mime_types\n\n    def mime_type(filename, mime_tab)\n      suffix1 = (/\\.(\\w+)$/ =~ filename && $1.downcase)\n      suffix2 = (/\\.(\\w+)\\.[\\w\\-]+$/ =~ filename && $1.downcase)\n      mime_tab[suffix1] || mime_tab[suffix2] || \"application/octet-stream\"\n    end\n    module_function :mime_type\n\n    #####\n\n    def parse_header(raw)\n      header = Hash.new([].freeze)\n      field = nil\n      raw.each{|line|\n        case line\n        when /^([A-Za-z0-9!\\#$%&'*+\\-.^_`|~]+):\\s*(.*?)\\s*\\z/om\n          field, value = $1, $2\n          field.downcase!\n          header[field] = [] unless header.has_key?(field)\n          header[field] << value\n        when /^\\s+(.*?)\\s*\\z/om\n          value = $1\n          unless field\n            raise HTTPStatus::BadRequest, \"bad header '#{line}'.\"\n          end\n          header[field][-1] << \" \" << value\n        else\n          raise HTTPStatus::BadRequest, \"bad header '#{line}'.\"\n        end\n      }\n      header.each{|key, values|\n        values.each{|value|\n          value.strip!\n          value.gsub!(/\\s+/, \" \")\n        }\n      }\n      header\n    end\n    module_function :parse_header\n\n    def split_header_value(str)\n      str.scan(%r'\\G((?:\"(?:\\\\.|[^\"])+?\"|[^\",]+)+)\n                    (?:,\\s*|\\Z)'xn).flatten\n    end\n    module_function :split_header_value\n\n    def parse_range_header(ranges_specifier)\n      if /^bytes=(.*)/ =~ ranges_specifier\n        byte_range_set = split_header_value($1)\n        byte_range_set.collect{|range_spec|\n          case range_spec\n          when /^(\\d+)-(\\d+)/ then $1.to_i .. $2.to_i\n          when /^(\\d+)-/      then $1.to_i .. -1\n          when /^-(\\d+)/      then -($1.to_i) .. -1\n          else return nil\n          end\n        }\n      end\n    end\n    module_function :parse_range_header\n\n    def parse_qvalues(value)\n      tmp = []\n      if value\n        parts = value.split(/,\\s*/)\n        parts.each {|part|\n          if m = %r{^([^\\s,]+?)(?:;\\s*q=(\\d+(?:\\.\\d+)?))?$}.match(part)\n            val = m[1]\n            q = (m[2] or 1).to_f\n            tmp.push([val, q])\n          end\n        }\n        tmp = tmp.sort_by{|val, q| -q}\n        tmp.collect!{|val, q| val}\n      end\n      return tmp\n    end\n    module_function :parse_qvalues\n\n    #####\n\n    def dequote(str)\n      ret = (/\\A\"(.*)\"\\Z/ =~ str) ? $1 : str.dup\n      ret.gsub!(/\\\\(.)/, \"\\\\1\")\n      ret\n    end\n    module_function :dequote\n\n    def quote(str)\n      '\"' << str.gsub(/[\\\\\\\"]/o, \"\\\\\\1\") << '\"'\n    end\n    module_function :quote\n\n    #####\n\n    class FormData < String\n      EmptyRawHeader = [].freeze\n      EmptyHeader = {}.freeze\n\n      attr_accessor :name, :filename, :next_data\n      protected :next_data\n\n      def initialize(*args)\n        @name = @filename = @next_data = nil\n        if args.empty?\n          @raw_header = []\n          @header = nil\n          super(\"\")\n        else\n          @raw_header = EmptyRawHeader\n          @header = EmptyHeader \n          super(args.shift)\n          unless args.empty?\n            @next_data = self.class.new(*args)\n          end\n        end\n      end\n\n      def [](*key)\n        begin\n          @header[key[0].downcase].join(\", \")\n        rescue StandardError, NameError\n          super\n        end\n      end\n\n      def <<(str)\n        if @header\n          super\n        elsif str == CRLF\n          @header = HTTPUtils::parse_header(@raw_header)\n          if cd = self['content-disposition']\n            if /\\s+name=\"(.*?)\"/ =~ cd then @name = $1 end\n            if /\\s+filename=\"(.*?)\"/ =~ cd then @filename = $1 end\n          end\n        else\n          @raw_header << str\n        end\n        self\n      end\n\n      def append_data(data)\n        tmp = self\n        while tmp\n          unless tmp.next_data \n            tmp.next_data = data\n            break\n          end\n          tmp = tmp.next_data\n        end\n        self\n      end\n\n      def each_data\n        tmp = self\n        while tmp\n          next_data = tmp.next_data\n          yield(tmp)\n          tmp = next_data\n        end\n      end\n\n      def list\n        ret = []\n        each_data{|data|\n          ret << data.to_s\n        }\n        ret\n      end\n\n      alias :to_ary :list\n\n      def to_s\n        String.new(self)\n      end\n    end\n\n    def parse_query(str)\n      query = Hash.new\n      if str\n        str.split(/[&;]/).each{|x|\n          next if x.empty? \n          key, val = x.split(/=/,2)\n          key = unescape_form(key)\n          val = unescape_form(val.to_s)\n          val = FormData.new(val)\n          val.name = key\n          if query.has_key?(key)\n            query[key].append_data(val)\n            next\n          end\n          query[key] = val\n        }\n      end\n      query\n    end\n    module_function :parse_query\n\n    def parse_form_data(io, boundary)\n      boundary_regexp = /\\A--#{boundary}(--)?#{CRLF}\\z/\n      form_data = Hash.new\n      return form_data unless io\n      data = nil\n      io.each{|line|\n        if boundary_regexp =~ line\n          if data\n            data.chop!\n            key = data.name\n            if form_data.has_key?(key)\n              form_data[key].append_data(data)\n            else\n              form_data[key] = data \n            end\n          end\n          data = FormData.new\n          next\n        else\n          if data\n            data << line\n          end\n        end\n      }\n      return form_data\n    end\n    module_function :parse_form_data\n\n    #####\n\n    reserved = ';/?:@&=+$,'\n    num      = '0123456789'\n    lowalpha = 'abcdefghijklmnopqrstuvwxyz'\n    upalpha  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n    mark     = '-_.!~*\\'()'\n    unreserved = num + lowalpha + upalpha + mark\n    control  = (0x0..0x1f).collect{|c| c.chr }.join + \"\\x7f\"\n    space    = \" \"\n    delims   = '<>#%\"'\n    unwise   = '{}|\\\\^[]`'\n    nonascii = (0x80..0xff).collect{|c| c.chr }.join\n\n    module_function\n\n    def _make_regex(str) /([#{Regexp.escape(str)}])/n end\n    def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end\n    def _escape(str, regex) str.gsub(regex){ \"%%%02X\" % $1[0] } end\n    def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end\n\n    UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)\n    UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)\n    NONASCII  = _make_regex(nonascii)\n    ESCAPED   = /%([0-9a-fA-F]{2})/\n    UNESCAPED_PCHAR = _make_regex!(unreserved+\":@&=+$,\")\n\n    def escape(str)\n      _escape(str, UNESCAPED)\n    end\n\n    def unescape(str)\n      _unescape(str, ESCAPED)\n    end\n\n    def escape_form(str)\n      ret = _escape(str, UNESCAPED_FORM)\n      ret.gsub!(/ /, \"+\")\n      ret\n    end\n\n    def unescape_form(str)\n      _unescape(str.gsub(/\\+/, \" \"), ESCAPED)\n    end\n\n    def escape_path(str)\n      result = \"\"\n      str.scan(%r{/([^/]*)}).each{|i|\n        result << \"/\" << _escape(i[0], UNESCAPED_PCHAR)\n      }\n      return result\n    end\n\n    def escape8bit(str)\n      _escape(str, NONASCII)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/httpversion.rb",
    "content": "#\n# HTTPVersion.rb -- presentation of HTTP version\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: httpversion.rb,v 1.5 2002/09/21 12:23:37 gotoyuzo Exp $\n\nmodule WEBrick\n  class HTTPVersion\n    include Comparable\n\n    attr_accessor :major, :minor\n\n    def self.convert(version)\n      version.is_a?(self) ? version : new(version)\n    end\n\n    def initialize(version)\n      case version\n      when HTTPVersion\n        @major, @minor = version.major, version.minor\n      when String\n        if /^(\\d+)\\.(\\d+)$/ =~ version\n          @major, @minor = $1.to_i, $2.to_i\n        end\n      end\n      if @major.nil? || @minor.nil?\n        raise ArgumentError,\n          format(\"cannot convert %s into %s\", version.class, self.class)\n      end\n    end\n\n    def <=>(other)\n      unless other.is_a?(self.class)\n        other = self.class.new(other)\n      end\n      if (ret = @major <=> other.major) == 0\n        return @minor <=> other.minor\n      end\n      return ret\n    end\n\n    def to_s\n      format(\"%d.%d\", @major, @minor)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/log.rb",
    "content": "#\n# log.rb -- Log Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: log.rb,v 1.26 2002/10/06 17:06:10 gotoyuzo Exp $\n\nmodule WEBrick\n  class BasicLog\n    # log-level constant\n    FATAL, ERROR, WARN, INFO, DEBUG = 1, 2, 3, 4, 5\n\n    attr_accessor :level\n\n    def initialize(log_file=nil, level=nil)\n      @level = level || INFO\n      case log_file\n      when String\n        @log = open(log_file, \"a+\")\n        @log.sync = true\n        @opened = true\n      when NilClass\n        @log = $stderr\n      else\n        @log = log_file  # requires \"<<\". (see BasicLog#log)\n      end\n    end\n\n    def close\n      @log.close if @opened\n      @log = nil\n    end\n\n    def log(level, data)\n      if @log && level <= @level\n        data += \"\\n\" if /\\n\\Z/ !~ data\n        @log << data\n      end\n    end\n\n    def <<(obj)\n      log(INFO, obj.to_s)\n    end\n\n    def fatal(msg) log(FATAL, \"FATAL \" << format(msg)); end\n    def error(msg) log(ERROR, \"ERROR \" << format(msg)); end\n    def warn(msg)  log(WARN,  \"WARN  \" << format(msg)); end\n    def info(msg)  log(INFO,  \"INFO  \" << format(msg)); end\n    def debug(msg) log(DEBUG, \"DEBUG \" << format(msg)); end\n\n    def fatal?; @level >= FATAL; end\n    def error?; @level >= ERROR; end\n    def warn?;  @level >= WARN; end\n    def info?;  @level >= INFO; end\n    def debug?; @level >= DEBUG; end\n\n    private\n\n    def format(arg)\n      str = if arg.is_a?(Exception)\n        \"#{arg.class}: #{arg.message}\\n\\t\" <<\n        arg.backtrace.join(\"\\n\\t\") << \"\\n\"\n      elsif arg.respond_to?(:to_str)\n        arg.to_str\n      else\n        arg.inspect\n      end\n    end\n  end\n\n  class Log < BasicLog\n    attr_accessor :time_format \n\n    def initialize(log_file=nil, level=nil)\n      super(log_file, level)\n      @time_format = \"[%Y-%m-%d %H:%M:%S]\"\n    end\n\n    def log(level, data)\n      tmp = Time.now.strftime(@time_format)\n      tmp << \" \" << data\n      super(level, tmp)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/server.rb",
    "content": "#\n# server.rb -- GenericServer Class\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: server.rb,v 1.62 2003/07/22 19:20:43 gotoyuzo Exp $\n\nrequire 'thread'\nrequire 'socket'\nrequire 'timeout'\nrequire 'webrick/config'\nrequire 'webrick/log'\n\nmodule WEBrick\n\n  class ServerError < StandardError; end\n\n  class SimpleServer\n    def SimpleServer.start\n      yield\n    end\n  end\n\n  class Daemon\n    def Daemon.start\n      exit!(0) if fork\n      Process::setsid\n      exit!(0) if fork\n      Dir::chdir(\"/\")\n      File::umask(0)\n      STDIN.reopen(\"/dev/null\")\n      STDOUT.reopen(\"/dev/null\", \"w\")\n      STDERR.reopen(\"/dev/null\", \"w\")\n      yield if block_given?\n    end\n  end\n\n  class GenericServer\n    attr_reader :status, :config, :logger, :tokens, :listeners\n\n    def initialize(config={}, default=Config::General)\n      @config = default.dup.update(config)\n      @status = :Stop\n      @config[:Logger] ||= Log::new\n      @logger = @config[:Logger]\n\n      @tokens = SizedQueue.new(@config[:MaxClients])\n      @config[:MaxClients].times{ @tokens.push(nil) }\n\n      webrickv = WEBrick::VERSION\n      rubyv = \"#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]\"\n      @logger.info(\"WEBrick #{webrickv}\")\n      @logger.info(\"ruby #{rubyv}\")\n\n      @listeners = []\n      unless @config[:DoNotListen]\n        if @config[:Listen]\n          warn(\":Listen option is deprecated; use GenericServer#listen\")\n        end\n        listen(@config[:BindAddress], @config[:Port])\n        if @config[:Port] == 0\n          @config[:Port] = @listeners[0].addr[1]\n        end\n      end\n    end\n\n    def [](key)\n      @config[key]\n    end\n\n    def listen(address, port)\n      @listeners += Utils::create_listeners(address, port, @logger)\n    end\n\n    def start(&block)\n      raise ServerError, \"already started.\" if @status != :Stop\n      server_type = @config[:ServerType] || SimpleServer\n\n      server_type.start{\n        @logger.info \\\n          \"#{self.class}#start: pid=#{$$} port=#{@config[:Port]}\"\n        call_callback(:StartCallback)\n\n        thgroup = ThreadGroup.new\n        @status = :Running\n        while @status == :Running\n          begin\n            if svrs = IO.select(@listeners, nil, nil, 2.0)\n              svrs[0].each{|svr|\n                @tokens.pop          # blocks while no token is there.\n                if sock = accept_client(svr)\n                  th = start_thread(sock, &block)\n                  th[:WEBrickThread] = true\n                  thgroup.add(th)\n                else\n                  @tokens.push(nil)\n                end\n              }\n            end\n          rescue Errno::EBADF, IOError => ex\n            # if the listening socket was closed in GenericServer#shutdown,\n            # IO::select raise it.\n          rescue Exception => ex\n            msg = \"#{ex.class}: #{ex.message}\\n\\t#{ex.backtrace[0]}\"\n            @logger.error msg\n          end\n        end\n\n        @logger.info \"going to shutdown ...\"\n        thgroup.list.each{|th| th.join if th[:WEBrickThread] }\n        call_callback(:StopCallback)\n        @logger.info \"#{self.class}#start done.\"\n        @status = :Stop\n      }\n    end\n\n    def stop\n      if @status == :Running\n        @status = :Shutdown\n      end\n    end\n\n    def shutdown\n      stop\n      @listeners.each{|s|\n        if @logger.debug?\n          addr = s.addr\n          @logger.debug(\"close TCPSocket(#{addr[2]}, #{addr[1]})\")\n        end\n        s.close\n      }\n      @listeners.clear\n    end\n\n    def run(sock)\n      @logger.fatal \"run() must be provided by user.\"\n    end\n\n    private\n\n    def accept_client(svr)\n      sock = nil\n      begin\n        sock = svr.accept\n        sock.sync = true\n        Utils::set_non_blocking(sock)\n        Utils::set_close_on_exec(sock)\n      rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex\n        # TCP connection was established but RST segment was sent\n        # from peer before calling TCPServer#accept.\n      rescue Exception => ex\n        msg = \"#{ex.class}: #{ex.message}\\n\\t#{ex.backtrace[0]}\"\n        @logger.error msg\n      end\n      return sock\n    end\n\n    def start_thread(sock, &block)\n      Thread.start{\n        begin\n          Thread.current[:WEBrickSocket] = sock\n          begin\n            addr = sock.peeraddr\n            @logger.debug \"accept: #{addr[3]}:#{addr[1]}\"\n          rescue SocketError\n            @logger.debug \"accept: <address unknown>\"\n            raise\n          end\n          call_callback(:AcceptCallback, sock)\n          block ? block.call(sock) : run(sock)\n        rescue Errno::ENOTCONN\n          @logger.debug \"Errno::ENOTCONN raised\"\n        rescue ServerError => ex\n          msg = \"#{ex.class}: #{ex.message}\\n\\t#{ex.backtrace[0]}\"\n          @logger.error msg\n        rescue Exception => ex\n          @logger.error ex\n        ensure\n          @tokens.push(nil)\n          Thread.current[:WEBrickSocket] = nil\n          if addr\n            @logger.debug \"close: #{addr[3]}:#{addr[1]}\"\n          else\n            @logger.debug \"close: <address unknown>\"\n          end\n          sock.close\n        end\n      }\n    end\n\n    def call_callback(callback_name, *args)\n      if cb = @config[callback_name]\n        cb.call(*args)\n      end\n    end\n  end    # end of GenericServer\nend\n"
  },
  {
    "path": "lib/webrick/ssl.rb",
    "content": "#\n# ssl.rb -- SSL/TLS enhancement for GenericServer\n#\n# Copyright (c) 2003 GOTOU Yuuzou All rights reserved.\n# \n# $Id$\n\nrequire 'webrick'\nrequire 'openssl'\n\nmodule WEBrick\n  module Config\n    svrsoft = General[:ServerSoftware]\n    osslv = ::OpenSSL::OPENSSL_VERSION.split[1]\n    SSL = {\n      :ServerSoftware       => \"#{svrsoft} OpenSSL/#{osslv}\",\n      :SSLEnable            => false,\n      :SSLCertificate       => nil,\n      :SSLPrivateKey        => nil,\n      :SSLClientCA          => nil,\n      :SSLExtraChainCert    => nil,\n      :SSLCACertificateFile => nil,\n      :SSLCACertificatePath => nil,\n      :SSLCertificateStore  => nil,\n      :SSLVerifyClient      => ::OpenSSL::SSL::VERIFY_NONE,\n      :SSLVerifyDepth       => nil,\n      :SSLVerifyCallback    => nil,   # custom verification\n      :SSLTimeout           => nil,\n      :SSLOptions           => nil,\n      :SSLStartImmediately  => true,\n      # Must specify if you use auto generated certificate.\n      :SSLCertName          => nil,\n      :SSLCertComment       => \"Generated by Ruby/OpenSSL\"\n    }\n    General.update(SSL)\n  end\n\n  module Utils\n    def create_self_signed_cert(bits, cn, comment)\n      rsa = OpenSSL::PKey::RSA.new(bits){|p, n|\n        case p\n        when 0; $stderr.putc \".\"  # BN_generate_prime\n        when 1; $stderr.putc \"+\"  # BN_generate_prime\n        when 2; $stderr.putc \"*\"  # searching good prime,  \n                                  # n = #of try,\n                                  # but also data from BN_generate_prime\n        when 3; $stderr.putc \"\\n\" # found good prime, n==0 - p, n==1 - q,\n                                  # but also data from BN_generate_prime\n        else;   $stderr.putc \"*\"  # BN_generate_prime\n        end\n      }\n      cert = OpenSSL::X509::Certificate.new\n      cert.version = 3\n      cert.serial = 0\n      name = OpenSSL::X509::Name.new(cn)\n      cert.subject = name\n      cert.issuer = name\n      cert.not_before = Time.now\n      cert.not_after = Time.now + (365*24*60*60)\n      cert.public_key = rsa.public_key\n\n      ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)\n      ef.issuer_certificate = cert\n      cert.extensions = [\n        ef.create_extension(\"basicConstraints\",\"CA:FALSE\"),\n        ef.create_extension(\"keyUsage\", \"keyEncipherment\"),\n        ef.create_extension(\"subjectKeyIdentifier\", \"hash\"),\n        ef.create_extension(\"extendedKeyUsage\", \"serverAuth\"),\n        ef.create_extension(\"nsComment\", comment),\n      ]\n      aki = ef.create_extension(\"authorityKeyIdentifier\",\n                                \"keyid:always,issuer:always\")\n      cert.add_extension(aki)\n      cert.sign(rsa, OpenSSL::Digest::SHA1.new)\n\n      return [ cert, rsa ]\n    end\n    module_function :create_self_signed_cert\n  end\n\n  class GenericServer\n    def ssl_context\n      @ssl_context ||= nil\n    end\n\n    def listen(address, port)\n      listeners = Utils::create_listeners(address, port, @logger)\n      if @config[:SSLEnable]\n        unless ssl_context\n          @ssl_context = setup_ssl_context(@config)\n          @logger.info(\"\\n\" + @config[:SSLCertificate].to_text) \n        end\n        listeners.collect!{|svr|\n          ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)\n          ssvr.start_immediately = @config[:SSLStartImmediately]\n          ssvr\n        }\n      end\n      @listeners += listeners\n    end\n\n    def setup_ssl_context(config)\n      unless config[:SSLCertificate]\n        cn = config[:SSLCertName]\n        comment = config[:SSLCertComment]\n        cert, key = Utils::create_self_signed_cert(1024, cn, comment)\n        config[:SSLCertificate] = cert\n        config[:SSLPrivateKey] = key\n      end\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.key = config[:SSLPrivateKey]\n      ctx.cert = config[:SSLCertificate]\n      ctx.client_ca = config[:SSLClientCA]\n      ctx.extra_chain_cert = config[:SSLExtraChainCert]\n      ctx.ca_file = config[:SSLCACertificateFile]\n      ctx.ca_path = config[:SSLCACertificatePath]\n      ctx.cert_store = config[:SSLCertificateStore]\n      ctx.verify_mode = config[:SSLVerifyClient]\n      ctx.verify_depth = config[:SSLVerifyDepth]\n      ctx.verify_callback = config[:SSLVerifyCallback]\n      ctx.timeout = config[:SSLTimeout]\n      ctx.options = config[:SSLOptions]\n      ctx\n    end\n  end\nend\n"
  },
  {
    "path": "lib/webrick/utils.rb",
    "content": "#\n# utils.rb -- Miscellaneous utilities\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: utils.rb,v 1.10 2003/02/16 22:22:54 gotoyuzo Exp $\n\nrequire 'socket'\nrequire 'fcntl'\nbegin\n  require 'etc'\nrescue LoadError\n  nil\nend\n\nmodule WEBrick\n  module Utils\n    def set_non_blocking(io)\n      flag = File::NONBLOCK\n      if defined?(Fcntl::F_GETFL)\n        flag |= io.fcntl(Fcntl::F_GETFL)\n      end\n      io.fcntl(Fcntl::F_SETFL, flag)\n    end\n    module_function :set_non_blocking\n\n    def set_close_on_exec(io)\n      if defined?(Fcntl::FD_CLOEXEC)\n        io.fcntl(Fcntl::FD_CLOEXEC, 1)\n      end\n    end\n    module_function :set_close_on_exec\n\n    def su(user)\n      if defined?(Etc)\n        pw = Etc.getpwnam(user)\n        Process::initgroups(user, pw.gid)\n        Process::Sys::setgid(pw.gid)\n        Process::Sys::setuid(pw.uid)\n      else\n        warn(\"WEBrick::Utils::su doesn't work on this platform\")\n      end\n    end\n    module_function :su\n\n    def getservername\n      host = Socket::gethostname\n      begin\n        Socket::gethostbyname(host)[0]\n      rescue\n        host\n      end\n    end\n    module_function :getservername\n\n    def create_listeners(address, port, logger=nil)\n      unless port\n        raise ArgumentError, \"must specify port\"\n      end\n      res = Socket::getaddrinfo(address, port,\n                                Socket::AF_UNSPEC,   # address family\n                                Socket::SOCK_STREAM, # socket type\n                                0,                   # protocol\n                                Socket::AI_PASSIVE)  # flag\n      last_error = nil\n      sockets = []\n      res.each{|ai|\n        begin\n          logger.debug(\"TCPServer.new(#{ai[3]}, #{port})\") if logger\n          sock = TCPServer.new(ai[3], port)\n          port = sock.addr[1] if port == 0\n          Utils::set_close_on_exec(sock)\n          sockets << sock\n        rescue => ex\n          logger.warn(\"TCPServer Error: #{ex}\") if logger\n          last_error  = ex\n        end\n      }\n      raise last_error if sockets.empty?\n      return sockets\n    end\n    module_function :create_listeners\n\n    RAND_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" +\n                 \"0123456789\" +\n                 \"abcdefghijklmnopqrstuvwxyz\" \n\n    def random_string(len)\n      rand_max = RAND_CHARS.size\n      ret = \"\" \n      len.times{ ret << RAND_CHARS[rand(rand_max)] }\n      ret \n    end\n    module_function :random_string\n\n  end\nend\n"
  },
  {
    "path": "lib/webrick/version.rb",
    "content": "#\n# version.rb -- version and release date\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU\n# Copyright (c) 2003 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: version.rb,v 1.74 2003/07/22 19:20:43 gotoyuzo Exp $\n\nmodule WEBrick\n  VERSION      = \"1.3.1\"\nend\n"
  },
  {
    "path": "lib/webrick.rb",
    "content": "#\n# WEBrick -- WEB server toolkit.\n#\n# Author: IPR -- Internet Programming with Ruby -- writers\n# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU\n# Copyright (c) 2002 Internet Programming with Ruby writers. All rights\n# reserved.\n#\n# $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $\n\nrequire 'webrick/compat.rb'\n\nrequire 'webrick/version.rb'\nrequire 'webrick/config.rb'\nrequire 'webrick/log.rb'\nrequire 'webrick/server.rb'\nrequire 'webrick/utils.rb'\nrequire 'webrick/accesslog'\n\nrequire 'webrick/htmlutils.rb'\nrequire 'webrick/httputils.rb'\nrequire 'webrick/cookie.rb'\nrequire 'webrick/httpversion.rb'\nrequire 'webrick/httpstatus.rb'\nrequire 'webrick/httprequest.rb'\nrequire 'webrick/httpresponse.rb'\nrequire 'webrick/httpserver.rb'\nrequire 'webrick/httpservlet.rb'\nrequire 'webrick/httpauth.rb'\n"
  },
  {
    "path": "lib/wsdl/binding.rb",
    "content": "# WSDL4R - WSDL binding definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\n\n\nclass Binding < Info\n  attr_reader :name\t\t# required\n  attr_reader :type\t\t# required\n  attr_reader :operations\n  attr_reader :soapbinding\n\n  def initialize\n    super\n    @name = nil\n    @type = nil\n    @operations = XSD::NamedElements.new\n    @soapbinding = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    case element\n    when OperationName\n      o = OperationBinding.new\n      @operations << o\n      o\n    when SOAPBindingName\n      o = WSDL::SOAP::Binding.new\n      @soapbinding = o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    when TypeAttrName\n      @type = value\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/data.rb",
    "content": "# WSDL4R - WSDL data definitions.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'wsdl/documentation'\nrequire 'wsdl/definitions'\nrequire 'wsdl/types'\nrequire 'wsdl/message'\nrequire 'wsdl/part'\nrequire 'wsdl/portType'\nrequire 'wsdl/operation'\nrequire 'wsdl/param'\nrequire 'wsdl/binding'\nrequire 'wsdl/operationBinding'\nrequire 'wsdl/service'\nrequire 'wsdl/port'\nrequire 'wsdl/import'\n\n\nmodule WSDL\n\n\nArrayTypeAttrName = XSD::QName.new(Namespace, 'arrayType')\nBindingName = XSD::QName.new(Namespace, 'binding')\nDefinitionsName = XSD::QName.new(Namespace, 'definitions')\nDocumentationName = XSD::QName.new(Namespace, 'documentation')\nFaultName = XSD::QName.new(Namespace, 'fault')\nImportName = XSD::QName.new(Namespace, 'import')\nInputName = XSD::QName.new(Namespace, 'input')\nMessageName = XSD::QName.new(Namespace, 'message')\nOperationName = XSD::QName.new(Namespace, 'operation')\nOutputName = XSD::QName.new(Namespace, 'output')\nPartName = XSD::QName.new(Namespace, 'part')\nPortName = XSD::QName.new(Namespace, 'port')\nPortTypeName = XSD::QName.new(Namespace, 'portType')\nServiceName = XSD::QName.new(Namespace, 'service')\nTypesName = XSD::QName.new(Namespace, 'types')\n\nSchemaName = XSD::QName.new(XSD::Namespace, 'schema')\n\nSOAPAddressName = XSD::QName.new(SOAPBindingNamespace, 'address')\nSOAPBindingName = XSD::QName.new(SOAPBindingNamespace, 'binding')\nSOAPHeaderName = XSD::QName.new(SOAPBindingNamespace, 'header')\nSOAPBodyName = XSD::QName.new(SOAPBindingNamespace, 'body')\nSOAPFaultName = XSD::QName.new(SOAPBindingNamespace, 'fault')\nSOAPOperationName = XSD::QName.new(SOAPBindingNamespace, 'operation')\n\nBindingAttrName = XSD::QName.new(nil, 'binding')\nElementAttrName = XSD::QName.new(nil, 'element')\nLocationAttrName = XSD::QName.new(nil, 'location')\nMessageAttrName = XSD::QName.new(nil, 'message')\nNameAttrName = XSD::QName.new(nil, 'name')\nNamespaceAttrName = XSD::QName.new(nil, 'namespace')\nParameterOrderAttrName = XSD::QName.new(nil, 'parameterOrder')\nTargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace')\nTypeAttrName = XSD::QName.new(nil, 'type')\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/definitions.rb",
    "content": "# WSDL4R - WSDL definitions.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\n\n\nclass Definitions < Info\n  attr_reader :name\n  attr_reader :targetnamespace\n  attr_reader :imports\n\n  attr_accessor :location\n  attr_reader :importedschema\n\n  def initialize\n    super\n    @name = nil\n    @targetnamespace = nil\n    @location = nil\n    @importedschema = {}\n\n    @types = nil\n    @imports = []\n    @messages = XSD::NamedElements.new\n    @porttypes = XSD::NamedElements.new\n    @bindings = XSD::NamedElements.new\n    @services = XSD::NamedElements.new\n\n    @anontypes = XSD::NamedElements.new\n    @root = self\n  end\n\n  def inspect\n    sprintf(\"#<%s:0x%x %s>\", self.class.name, __id__, @name || '(unnamed)')\n  end\n\n  def targetnamespace=(targetnamespace)\n    @targetnamespace = targetnamespace\n    if @name\n      @name = XSD::QName.new(@targetnamespace, @name.name)\n    end\n  end\n\n  def collect_attributes\n    result = XSD::NamedElements.new\n    if @types\n      @types.schemas.each do |schema|\n\tresult.concat(schema.collect_attributes)\n      end\n    end\n    @imports.each do |import|\n      result.concat(import.content.collect_attributes)\n    end\n    result\n  end\n\n  def collect_elements\n    result = XSD::NamedElements.new\n    if @types\n      @types.schemas.each do |schema|\n\tresult.concat(schema.collect_elements)\n      end\n    end\n    @imports.each do |import|\n      result.concat(import.content.collect_elements)\n    end\n    result\n  end\n\n  def collect_complextypes\n    result = @anontypes.dup\n    if @types\n      @types.schemas.each do |schema|\n\tresult.concat(schema.collect_complextypes)\n      end\n    end\n    @imports.each do |import|\n      result.concat(import.content.collect_complextypes)\n    end\n    result\n  end\n\n  def collect_simpletypes\n    result = XSD::NamedElements.new\n    if @types\n      @types.schemas.each do |schema|\n\tresult.concat(schema.collect_simpletypes)\n      end\n    end\n    @imports.each do |import|\n      result.concat(import.content.collect_simpletypes)\n    end\n    result\n  end\n\n  # ToDo: simpletype must be accepted...\n  def add_type(complextype)\n    @anontypes << complextype\n  end\n\n  def messages\n    result = @messages.dup\n    @imports.each do |import|\n      result.concat(import.content.messages) if self.class === import.content\n    end\n    result\n  end\n\n  def porttypes\n    result = @porttypes.dup\n    @imports.each do |import|\n      result.concat(import.content.porttypes) if self.class === import.content\n    end\n    result\n  end\n\n  def bindings\n    result = @bindings.dup\n    @imports.each do |import|\n      result.concat(import.content.bindings) if self.class === import.content\n    end\n    result\n  end\n\n  def services\n    result = @services.dup\n    @imports.each do |import|\n      result.concat(import.content.services) if self.class === import.content\n    end\n    result\n  end\n\n  def message(name)\n    message = @messages[name]\n    return message if message\n    @imports.each do |import|\n      message = import.content.message(name) if self.class === import.content\n      return message if message\n    end\n    nil\n  end\n\n  def porttype(name)\n    porttype = @porttypes[name]\n    return porttype if porttype\n    @imports.each do |import|\n      porttype = import.content.porttype(name) if self.class === import.content\n      return porttype if porttype\n    end\n    nil\n  end\n\n  def binding(name)\n    binding = @bindings[name]\n    return binding if binding\n    @imports.each do |import|\n      binding = import.content.binding(name) if self.class === import.content\n      return binding if binding\n    end\n    nil\n  end\n\n  def service(name)\n    service = @services[name]\n    return service if service\n    @imports.each do |import|\n      service = import.content.service(name) if self.class === import.content\n      return service if service\n    end\n    nil\n  end\n\n  def porttype_binding(name)\n    binding = @bindings.find { |item| item.type == name }\n    return binding if binding\n    @imports.each do |import|\n      binding = import.content.porttype_binding(name) if self.class === import.content\n      return binding if binding\n    end\n    nil\n  end\n\n  def parse_element(element)\n    case element\n    when ImportName\n      o = Import.new\n      @imports << o\n      o\n    when TypesName\n      o = Types.new\n      @types = o\n      o\n    when MessageName\n      o = Message.new\n      @messages << o\n      o\n    when PortTypeName\n      o = PortType.new\n      @porttypes << o\n      o\n    when BindingName\n      o = Binding.new\n      @bindings << o\n      o\n    when ServiceName\n      o = Service.new\n      @services << o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    when TargetNamespaceAttrName\n      self.targetnamespace = value.source\n    else\n      nil\n    end\n  end\n\n  def self.parse_element(element)\n    if element == DefinitionsName\n      Definitions.new\n    else\n      nil\n    end\n  end\n\nprivate\n\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/documentation.rb",
    "content": "# WSDL4R - WSDL SOAP documentation element.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Documentation < Info\n  def initialize\n    super\n  end\n\n  def parse_element(element)\n    # Accepts any element.\n    self\n  end\n\n  def parse_attr(attr, value)\n    # Accepts any attribute.\n    true\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/import.rb",
    "content": "# WSDL4R - WSDL import definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/importer'\n\n\nmodule WSDL\n\n\nclass Import < Info\n  attr_reader :namespace\n  attr_reader :location\n  attr_reader :content\n\n  def initialize\n    super\n    @namespace = nil\n    @location = nil\n    @content = nil\n    @web_client = nil\n  end\n\n  def parse_element(element)\n    case element\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NamespaceAttrName\n      @namespace = value.source\n      if @content\n\t@content.targetnamespace = @namespace\n      end\n      @namespace\n    when LocationAttrName\n      @location = URI.parse(value.source)\n      if @location.relative? and !parent.location.nil? and\n          !parent.location.relative?\n        @location = parent.location + @location\n      end\n      if root.importedschema.key?(@location)\n        @content = root.importedschema[@location]\n      else\n        root.importedschema[@location] = nil      # placeholder\n        @content = import(@location)\n        if @content.is_a?(Definitions)\n          @content.root = root\n          if @namespace\n            @content.targetnamespace = @namespace\n          end\n        end\n        root.importedschema[@location] = @content\n      end\n      @location\n    else\n      nil\n    end\n  end\n\nprivate\n\n  def import(location)\n    Importer.import(location, root)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/importer.rb",
    "content": "# WSDL4R - WSDL importer library.\n# Copyright (C) 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/xmlSchema/importer'\nrequire 'wsdl/parser'\n\n\nmodule WSDL\n\n\nclass Importer < WSDL::XMLSchema::Importer\n  def self.import(location, originalroot = nil)\n    new.import(location, originalroot)\n  end\n\nprivate\n\n  def parse(content, location, originalroot)\n    opt = {\n      :location => location,\n      :originalroot => originalroot\n    }\n    begin\n      WSDL::Parser.new(opt).parse(content)\n    rescue WSDL::Parser::ParseError\n      super(content, location, originalroot)\n    end\n  end\n\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/info.rb",
    "content": "# WSDL4R - WSDL information base.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule WSDL\n\n\nclass Info\n  attr_accessor :root\n  attr_accessor :parent\n  attr_accessor :id\n\n  def initialize\n    @root = nil\n    @parent = nil\n    @id = nil\n  end\n\n  def inspect\n    if self.respond_to?(:name)\n      sprintf(\"#<%s:0x%x %s>\", self.class.name, __id__, self.name)\n    else\n      sprintf(\"#<%s:0x%x>\", self.class.name, __id__)\n    end\n  end\n\n  def parse_element(element); end\t# abstract\n  \n  def parse_attr(attr, value); end\t# abstract\n\n  def parse_epilogue; end\t\t# abstract\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/message.rb",
    "content": "# WSDL4R - WSDL message definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Message < Info\n  attr_reader :name\t# required\n  attr_reader :parts\n\n  def initialize\n    super\n    @name = nil\n    @parts = []\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    case element\n    when PartName\n      o = Part.new\n      @parts << o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(parent.targetnamespace, value.source)\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/operation.rb",
    "content": "# WSDL4R - WSDL operation definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Operation < Info\n  class NameInfo\n    attr_reader :op_name\n    attr_reader :optype_name\n    attr_reader :parts\n    def initialize(op_name, optype_name, parts)\n      @op_name = op_name\n      @optype_name = optype_name\n      @parts = parts\n    end\n  end\n\n  attr_reader :name\t\t# required\n  attr_reader :parameter_order\t# optional\n  attr_reader :input\n  attr_reader :output\n  attr_reader :fault\n  attr_reader :type\t\t# required\n\n  def initialize\n    super\n    @name = nil\n    @type = nil\n    @parameter_order = nil\n    @input = nil\n    @output = nil\n    @fault = []\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def input_info\n    typename = input.find_message.name\n    NameInfo.new(@name, typename, inputparts)\n  end\n\n  def output_info\n    typename = output.find_message.name\n    NameInfo.new(@name, typename, outputparts)\n  end\n\n  def inputparts\n    sort_parts(input.find_message.parts)\n  end\n\n  def inputname\n    XSD::QName.new(targetnamespace, input.name ? input.name.name : @name.name)\n  end\n\n  def outputparts\n    sort_parts(output.find_message.parts)\n  end\n\n  def outputname\n    XSD::QName.new(targetnamespace,\n      output.name ? output.name.name : @name.name + 'Response')\n  end\n\n  def parse_element(element)\n    case element\n    when InputName\n      o = Param.new\n      @input = o\n      o\n    when OutputName\n      o = Param.new\n      @output = o\n      o\n    when FaultName\n      o = Param.new\n      @fault << o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    when TypeAttrName\n      @type = value\n    when ParameterOrderAttrName\n      @parameter_order = value.source.split(/\\s+/)\n    else\n      nil\n    end\n  end\n\nprivate\n\n  def sort_parts(parts)\n    return parts.dup unless parameter_order\n    result = []\n    parameter_order.each do |orderitem|\n      if (ele = parts.find { |part| part.name == orderitem })\n\tresult << ele\n      end\n    end\n    if result.length == 0\n      return parts.dup\n    end\n    # result length can be shorter than parts's.\n    # return part must not be a part of the parameterOrder.\n    result\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/operationBinding.rb",
    "content": "# WSDL4R - WSDL bound operation definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass OperationBinding < Info\n  attr_reader :name\t\t# required\n  attr_reader :input\n  attr_reader :output\n  attr_reader :fault\n  attr_reader :soapoperation\n\n  def initialize\n    super\n    @name = nil\n    @input = nil\n    @output = nil\n    @fault = []\n    @soapoperation = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def porttype\n    root.porttype(parent.type)\n  end\n\n  def find_operation\n    porttype.operations[@name] or raise RuntimeError.new(\"#{@name} not found\")\n  end\n\n  def soapoperation_name\n    if @soapoperation\n      @soapoperation.input_info.op_name\n    else\n      find_operation.name\n    end\n  end\n\n  def soapoperation_style\n    style = nil\n    if @soapoperation\n      style = @soapoperation.operation_style\n    elsif parent.soapbinding\n      style = parent.soapbinding.style\n    else\n      raise TypeError.new(\"operation style definition not found\")\n    end\n    style || :document\n  end\n\n  def soapaction\n    if @soapoperation\n      @soapoperation.soapaction\n    else\n      nil\n    end\n  end\n\n  def parse_element(element)\n    case element\n    when InputName\n      o = Param.new\n      @input = o\n      o\n    when OutputName\n      o = Param.new\n      @output = o\n      o\n    when FaultName\n      o = Param.new\n      @fault << o\n      o\n    when SOAPOperationName\n      o = WSDL::SOAP::Operation.new\n      @soapoperation = o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/param.rb",
    "content": "# WSDL4R - WSDL param definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Param < Info\n  attr_reader :message\t# required\n  attr_reader :name\t# optional but required for fault.\n  attr_reader :soapbody\n  attr_reader :soapheader\n  attr_reader :soapfault\n\n  def initialize\n    super\n    @message = nil\n    @name = nil\n    @soapbody = nil\n    @soapheader = []\n    @soapfault = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def find_message\n    root.message(@message) or raise RuntimeError.new(\"#{@message} not found\")\n  end\n\n  def soapbody_use\n    if @soapbody\n      @soapbody.use || :literal\n    else\n      raise RuntimeError.new(\"soap:body not found\")\n    end\n  end\n\n  def parse_element(element)\n    case element\n    when SOAPBodyName\n      o = WSDL::SOAP::Body.new\n      @soapbody = o\n      o\n    when SOAPHeaderName\n      o = WSDL::SOAP::Header.new\n      @soapheader << o\n      o\n    when SOAPFaultName\n      o = WSDL::SOAP::Fault.new\n      @soap_fault = o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MessageAttrName\n      if value.namespace.nil?\n        value = XSD::QName.new(targetnamespace, value.source)\n      end\n      @message = value\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/parser.rb",
    "content": "# WSDL4R - WSDL XML Instance parser library.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'xsd/ns'\nrequire 'xsd/charset'\nrequire 'xsd/datatypes'\nrequire 'xsd/xmlparser'\nrequire 'wsdl/wsdl'\nrequire 'wsdl/data'\nrequire 'wsdl/xmlSchema/data'\nrequire 'wsdl/soap/data'\n\n\nmodule WSDL\n\n\nclass Parser\n  include WSDL\n\n  class ParseError < Error; end\n  class FormatDecodeError < ParseError; end\n  class UnknownElementError < FormatDecodeError; end\n  class UnknownAttributeError < FormatDecodeError; end\n  class UnexpectedElementError < FormatDecodeError; end\n  class ElementConstraintError < FormatDecodeError; end\n  class AttributeConstraintError < FormatDecodeError; end\n\nprivate\n\n  class ParseFrame\n    attr_reader :ns\n    attr_reader :name\n    attr_accessor :node\n\n  private\n\n    def initialize(ns, name, node)\n      @ns = ns\n      @name = name\n      @node = node\n    end\n  end\n\npublic\n\n  def initialize(opt = {})\n    @parser = XSD::XMLParser.create_parser(self, opt)\n    @parsestack = nil\n    @lastnode = nil\n    @ignored = {}\n    @location = opt[:location]\n    @originalroot = opt[:originalroot]\n  end\n\n  def parse(string_or_readable)\n    @parsestack = []\n    @lastnode = nil\n    @textbuf = ''\n    @parser.do_parse(string_or_readable)\n    @lastnode\n  end\n\n  def charset\n    @parser.charset\n  end\n\n  def start_element(name, attrs)\n    lastframe = @parsestack.last\n    ns = parent = nil\n    if lastframe\n      ns = lastframe.ns.clone_ns\n      parent = lastframe.node\n    else\n      ns = XSD::NS.new\n      parent = nil\n    end\n    attrs = XSD::XMLParser.filter_ns(ns, attrs)\n    node = decode_tag(ns, name, attrs, parent)\n    @parsestack << ParseFrame.new(ns, name, node)\n  end\n\n  def characters(text)\n    lastframe = @parsestack.last\n    if lastframe\n      # Need not to be cloned because character does not have attr.\n      ns = lastframe.ns\n      decode_text(ns, text)\n    else\n      p text if $DEBUG\n    end\n  end\n\n  def end_element(name)\n    lastframe = @parsestack.pop\n    unless name == lastframe.name\n      raise UnexpectedElementError.new(\"closing element name '#{name}' does not match with opening element '#{lastframe.name}'\")\n    end\n    decode_tag_end(lastframe.ns, lastframe.node)\n    @lastnode = lastframe.node\n  end\n\nprivate\n\n  def decode_tag(ns, name, attrs, parent)\n    o = nil\n    elename = ns.parse(name)\n    if !parent\n      if elename == DefinitionsName\n\to = Definitions.parse_element(elename)\n        o.location = @location\n      else\n\traise UnknownElementError.new(\"unknown element: #{elename}\")\n      end\n      o.root = @originalroot if @originalroot   # o.root = o otherwise\n    else\n      if elename == XMLSchema::AnnotationName\n        # only the first annotation element is allowed for each xsd element.\n        o = XMLSchema::Annotation.new\n      else\n        o = parent.parse_element(elename)\n      end\n      unless o\n        unless @ignored.key?(elename)\n          warn(\"ignored element: #{elename}\")\n          @ignored[elename] = elename\n        end\n\to = Documentation.new\t# which accepts any element.\n      end\n      # node could be a pseudo element.  pseudo element has its own parent.\n      o.root = parent.root\n      o.parent = parent if o.parent.nil?\n    end\n    attrs.each do |key, value|\n      attr_ele = ns.parse(key, true)\n      value_ele = ns.parse(value, true)\n      value_ele.source = value  # for recovery; value may not be a QName\n      unless o.parse_attr(attr_ele, value_ele)\n        unless @ignored.key?(attr_ele)\n          warn(\"ignored attr: #{attr_ele}\")\n          @ignored[attr_ele] = attr_ele\n        end\n      end\n    end\n    o\n  end\n\n  def decode_tag_end(ns, node)\n    node.parse_epilogue\n  end\n\n  def decode_text(ns, text)\n    @textbuf << text\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/part.rb",
    "content": "# WSDL4R - WSDL part definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Part < Info\n  attr_reader :name\t# required\n  attr_reader :element\t# optional\n  attr_reader :type\t# optional\n\n  def initialize\n    super\n    @name = nil\n    @element = nil\n    @type = nil\n  end\n\n  def parse_element(element)\n    case element\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = value.source\n    when ElementAttrName\n      @element = value\n    when TypeAttrName\n      @type = value\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/port.rb",
    "content": "# WSDL4R - WSDL port definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Port < Info\n  attr_reader :name\t\t# required\n  attr_reader :binding\t\t# required\n  attr_reader :soap_address\n\n  def initialize\n    super\n    @name = nil\n    @binding = nil\n    @soap_address = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def porttype\n    root.porttype(find_binding.type)\n  end\n\n  def find_binding\n    root.binding(@binding) or raise RuntimeError.new(\"#{@binding} not found\")\n  end\n\n  def inputoperation_map\n    result = {}\n    find_binding.operations.each do |op_bind|\n      op_info = op_bind.soapoperation.input_info\n      result[op_info.op_name] = op_info\n    end\n    result\n  end\n\n  def outputoperation_map\n    result = {}\n    find_binding.operations.each do |op_bind|\n      op_info = op_bind.soapoperation.output_info\n      result[op_info.op_name] = op_info\n    end\n    result\n  end\n\n  def parse_element(element)\n    case element\n    when SOAPAddressName\n      o = WSDL::SOAP::Address.new\n      @soap_address = o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    when BindingAttrName\n      @binding = value\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/portType.rb",
    "content": "# WSDL4R - WSDL portType definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\n\n\nclass PortType < Info\n  attr_reader :name\t\t# required\n  attr_reader :operations\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def initialize\n    super\n    @name = nil\n    @operations = XSD::NamedElements.new\n  end\n\n  def find_binding\n    root.bindings.find { |item| item.type == @name } or\n      raise RuntimeError.new(\"#{@name} not found\")\n  end\n\n  def locations\n    bind_name = find_binding.name\n    result = []\n    root.services.each do |service|\n      service.ports.each do |port|\n        if port.binding == bind_name\n          result << port.soap_address.location if port.soap_address\n        end\n      end\n    end\n    result\n  end\n\n  def parse_element(element)\n    case element\n    when OperationName\n      o = Operation.new\n      @operations << o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/service.rb",
    "content": "# WSDL4R - WSDL service definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\n\n\nclass Service < Info\n  attr_reader :name\t\t# required\n  attr_reader :ports\n  attr_reader :soap_address\n\n  def initialize\n    super\n    @name = nil\n    @ports = XSD::NamedElements.new\n    @soap_address = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    case element\n    when PortName\n      o = Port.new\n      @ports << o\n      o\n    when SOAPAddressName\n      o = WSDL::SOAP::Address.new\n      @soap_address = o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    else\n      nil\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/soap/address.rb",
    "content": "# WSDL4R - WSDL SOAP address definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass Address < Info\n  attr_reader :location\n\n  def initialize\n    super\n    @location = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when LocationAttrName\n      @location = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/binding.rb",
    "content": "# WSDL4R - WSDL SOAP binding definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass Binding < Info\n  attr_reader :style\n  attr_reader :transport\n\n  def initialize\n    super\n    @style = nil\n    @transport = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when StyleAttrName\n      if [\"document\", \"rpc\"].include?(value.source)\n\t@style = value.source.intern\n      else\n\traise Parser::AttributeConstraintError.new(\n          \"Unexpected value #{ value }.\")\n      end\n    when TransportAttrName\n      @transport = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/body.rb",
    "content": "# WSDL4R - WSDL SOAP body definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass Body < Info\n  attr_reader :parts\n  attr_reader :use\t# required\n  attr_reader :encodingstyle\n  attr_reader :namespace\n\n  def initialize\n    super\n    @parts = nil\n    @use = nil\n    @encodingstyle = nil\n    @namespace = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when PartsAttrName\n      @parts = value.source\n    when UseAttrName\n      if ['literal', 'encoded'].include?(value.source)\n        @use = value.source.intern\n      else\n        raise RuntimeError.new(\"unknown use of soap:body: #{value.source}\")\n      end\n    when EncodingStyleAttrName\n      @encodingstyle = value.source\n    when NamespaceAttrName\n      @namespace = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/cgiStubCreator.rb",
    "content": "# WSDL4R - Creating CGI stub code from WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/mappingRegistryCreator'\nrequire 'wsdl/soap/methodDefCreator'\nrequire 'wsdl/soap/classDefCreatorSupport'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass CGIStubCreator\n  include ClassDefCreatorSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n  end\n\n  def dump(service_name)\n    warn(\"CGI stub can have only 1 port.  Creating stub for the first port...  Rests are ignored.\")\n    port = @definitions.service(service_name).ports[0]\n    dump_porttype(port.porttype.name)\n  end\n\nprivate\n\n  def dump_porttype(name)\n    class_name = create_class_name(name)\n    methoddef, types = MethodDefCreator.new(@definitions).dump(name)\n    mr_creator = MappingRegistryCreator.new(@definitions)\n    c1 = XSD::CodeGen::ClassDef.new(class_name)\n    c1.def_require(\"soap/rpc/cgistub\")\n    c1.def_require(\"soap/mapping/registry\")\n    c1.def_const(\"MappingRegistry\", \"::SOAP::Mapping::Registry.new\")\n    c1.def_code(mr_creator.dump(types))\n    c1.def_code <<-EOD\nMethods = [\n#{methoddef.gsub(/^/, \"  \")}\n]\n    EOD\n    c2 = XSD::CodeGen::ClassDef.new(class_name + \"App\",\n      \"::SOAP::RPC::CGIStub\")\n    c2.def_method(\"initialize\", \"*arg\") do\n      <<-EOD\n        super(*arg)\n        servant = #{class_name}.new\n        #{class_name}::Methods.each do |definitions|\n          opt = definitions.last\n          if opt[:request_style] == :document\n            @router.add_document_operation(servant, *definitions)\n          else\n            @router.add_rpc_operation(servant, *definitions)\n          end\n        end\n        self.mapping_registry = #{class_name}::MappingRegistry\n        self.level = Logger::Severity::ERROR\n      EOD\n    end\n    c1.dump + \"\\n\" + c2.dump + format(<<-EOD)\n      #{class_name}App.new('app', nil).start\n    EOD\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/classDefCreator.rb",
    "content": "# WSDL4R - Creating class definition from WSDL\n# Copyright (C) 2002, 2003, 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/data'\nrequire 'wsdl/soap/classDefCreatorSupport'\nrequire 'xsd/codegen'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass ClassDefCreator\n  include ClassDefCreatorSupport\n\n  def initialize(definitions)\n    @elements = definitions.collect_elements\n    @simpletypes = definitions.collect_simpletypes\n    @complextypes = definitions.collect_complextypes\n    @faulttypes = nil\n    if definitions.respond_to?(:collect_faulttypes)\n      @faulttypes = definitions.collect_faulttypes\n    end\n  end\n\n  def dump(type = nil)\n    result = \"require 'xsd/qname'\\n\"\n    if type\n      result = dump_classdef(type.name, type)\n    else\n      str = dump_element\n      unless str.empty?\n        result << \"\\n\" unless result.empty?\n        result << str\n      end\n      str = dump_complextype\n      unless str.empty?\n        result << \"\\n\" unless result.empty?\n        result << str\n      end\n      str = dump_simpletype\n      unless str.empty?\n        result << \"\\n\" unless result.empty?\n        result << str\n      end\n    end\n    result\n  end\n\nprivate\n\n  def dump_element\n    @elements.collect { |ele|\n      if ele.local_complextype\n        dump_classdef(ele.name, ele.local_complextype,\n          ele.elementform == 'qualified')\n      elsif ele.local_simpletype\n        dump_simpletypedef(ele.name, ele.local_simpletype)\n      else\n        nil\n      end\n    }.compact.join(\"\\n\")\n  end\n\n  def dump_simpletype\n    @simpletypes.collect { |type|\n      dump_simpletypedef(type.name, type)\n    }.compact.join(\"\\n\")\n  end\n\n  def dump_complextype\n    @complextypes.collect { |type|\n      case type.compoundtype\n      when :TYPE_STRUCT, :TYPE_EMPTY\n        dump_classdef(type.name, type)\n      when :TYPE_ARRAY\n        dump_arraydef(type)\n      when :TYPE_SIMPLE\n        dump_simpleclassdef(type)\n      when :TYPE_MAP\n        # mapped as a general Hash\n        nil\n      else\n        raise RuntimeError.new(\n          \"unknown kind of complexContent: #{type.compoundtype}\")\n      end\n    }.compact.join(\"\\n\")\n  end\n\n  def dump_simpletypedef(qname, simpletype)\n    if !simpletype.restriction or simpletype.restriction.enumeration.empty?\n      return nil\n    end\n    c = XSD::CodeGen::ModuleDef.new(create_class_name(qname))\n    c.comment = \"#{qname}\"\n    const = {}\n    simpletype.restriction.enumeration.each do |value|\n      constname = safeconstname(value)\n      const[constname] ||= 0\n      if (const[constname] += 1) > 1\n        constname += \"_#{const[constname]}\"\n      end\n      c.def_const(constname, ndq(value))\n    end\n    c.dump\n  end\n\n  def dump_simpleclassdef(type_or_element)\n    qname = type_or_element.name\n    base = create_class_name(type_or_element.simplecontent.base)\n    c = XSD::CodeGen::ClassDef.new(create_class_name(qname), base)\n    c.comment = \"#{qname}\"\n    c.dump\n  end\n\n  def dump_classdef(qname, typedef, qualified = false)\n    if @faulttypes and @faulttypes.index(qname)\n      c = XSD::CodeGen::ClassDef.new(create_class_name(qname),\n        '::StandardError')\n    else\n      c = XSD::CodeGen::ClassDef.new(create_class_name(qname))\n    end\n    c.comment = \"#{qname}\"\n    c.def_classvar('schema_type', ndq(qname.name))\n    c.def_classvar('schema_ns', ndq(qname.namespace))\n    c.def_classvar('schema_qualified', dq('true')) if qualified\n    schema_element = []\n    init_lines = ''\n    params = []\n    typedef.each_element do |element|\n      if element.type == XSD::AnyTypeName\n        type = nil\n      elsif klass = element_basetype(element)\n        type = klass.name\n      elsif element.type\n        type = create_class_name(element.type)\n      else\n        type = nil      # means anyType.\n        # do we define a class for local complexType from it's name?\n        #   type = create_class_name(element.name)\n        # <element>\n        #   <complexType>\n        #     <seq...>\n        #   </complexType>\n        # </element>\n      end\n      name = name_element(element).name\n      attrname = safemethodname?(name) ? name : safemethodname(name)\n      varname = safevarname(name)\n      c.def_attr(attrname, true, varname)\n      init_lines << \"@#{varname} = #{varname}\\n\"\n      if element.map_as_array?\n        params << \"#{varname} = []\"\n        type << '[]' if type\n      else\n        params << \"#{varname} = nil\"\n      end\n      # nil means @@schema_ns + varname\n      eleqname =\n        (varname == name && element.name.namespace == qname.namespace) ?\n        nil : element.name\n      schema_element << [varname, eleqname, type]\n    end\n    unless typedef.attributes.empty?\n      define_attribute(c, typedef.attributes)\n      init_lines << \"@__xmlattr = {}\\n\"\n    end\n    c.def_classvar('schema_element',\n      '[' +\n        schema_element.collect { |varname, name, type|\n          '[' +\n            (\n              if name\n                varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']'\n              else\n                varname.dump + ', ' + ndq(type)\n              end\n            ) +\n          ']'\n        }.join(', ') +\n      ']'\n    )\n    c.def_method('initialize', *params) do\n      init_lines\n    end\n    c.dump\n  end\n\n  def element_basetype(ele)\n    if klass = basetype_class(ele.type)\n      klass\n    elsif ele.local_simpletype\n      basetype_class(ele.local_simpletype.base)\n    else\n      nil\n    end\n  end\n\n  def attribute_basetype(attr)\n    if klass = basetype_class(attr.type)\n      klass\n    elsif attr.local_simpletype\n      basetype_class(attr.local_simpletype.base)\n    else\n      nil\n    end\n  end\n\n  def basetype_class(type)\n    return nil if type.nil?\n    if simpletype = @simpletypes[type]\n      basetype_mapped_class(simpletype.base)\n    else\n      basetype_mapped_class(type)\n    end\n  end\n\n  def define_attribute(c, attributes)\n    schema_attribute = []\n    attributes.each do |attribute|\n      name = name_attribute(attribute)\n      if klass = attribute_basetype(attribute)\n        type = klass.name\n      else\n        type = nil\n      end\n      methodname = safemethodname('xmlattr_' + name.name)\n      c.def_method(methodname) do <<-__EOD__\n          (@__xmlattr ||= {})[#{dqname(name)}]\n        __EOD__\n      end\n      c.def_method(methodname + '=', 'value') do <<-__EOD__\n          (@__xmlattr ||= {})[#{dqname(name)}] = value\n        __EOD__\n      end\n      schema_attribute << [name, type]\n    end\n    c.def_classvar('schema_attribute',\n      '{' +\n        schema_attribute.collect { |name, type|\n          dqname(name) + ' => ' + ndq(type)\n        }.join(', ') +\n      '}'\n    )\n  end\n\n  def name_element(element)\n    return element.name if element.name \n    return element.ref if element.ref\n    raise RuntimeError.new(\"cannot define name of #{element}\")\n  end\n\n  def name_attribute(attribute)\n    return attribute.name if attribute.name \n    return attribute.ref if attribute.ref\n    raise RuntimeError.new(\"cannot define name of #{attribute}\")\n  end\n\n  DEFAULT_ITEM_NAME = XSD::QName.new(nil, 'item')\n\n  def dump_arraydef(complextype)\n    qname = complextype.name\n    c = XSD::CodeGen::ClassDef.new(create_class_name(qname), '::Array')\n    c.comment = \"#{qname}\"\n    child_type = complextype.child_type\n    c.def_classvar('schema_type', ndq(child_type.name))\n    c.def_classvar('schema_ns', ndq(child_type.namespace))\n    child_element = complextype.find_aryelement\n    schema_element = []\n    if child_type == XSD::AnyTypeName\n      type = nil\n    elsif child_element and (klass = element_basetype(child_element))\n      type = klass.name\n    elsif child_type\n      type = create_class_name(child_type)\n    else\n      type = nil\n    end\n    if child_element\n      if child_element.map_as_array?\n        type << '[]' if type\n      end\n      child_element_name = child_element.name\n    else\n      child_element_name = DEFAULT_ITEM_NAME\n    end\n    schema_element << [child_element_name.name, child_element_name, type]\n    c.def_classvar('schema_element',\n      '[' +\n        schema_element.collect { |varname, name, type|\n          '[' +\n            (\n              if name\n                varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']'\n              else\n                varname.dump + ', ' + ndq(type)\n              end\n            ) +\n          ']'\n        }.join(', ') +\n      ']'\n    )\n    c.dump\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/classDefCreatorSupport.rb",
    "content": "# WSDL4R - Creating class code support from WSDL.\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'soap/mapping'\nrequire 'soap/mapping/typeMap'\nrequire 'xsd/codegen/gensupport'\n\n\nmodule WSDL\nmodule SOAP\n\n\nmodule ClassDefCreatorSupport\n  include XSD::CodeGen::GenSupport\n\n  def create_class_name(qname)\n    if klass = basetype_mapped_class(qname)\n      ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass).name\n    else\n      safeconstname(qname.name)\n    end\n  end\n\n  def basetype_mapped_class(name)\n    ::SOAP::TypeMap[name]\n  end\n\n  def dump_method_signature(operation)\n    name = operation.name.name\n    input = operation.input\n    output = operation.output\n    fault = operation.fault\n    signature = \"#{ name }#{ dump_inputparam(input) }\"\n    str = <<__EOD__\n# SYNOPSIS\n#   #{name}#{dump_inputparam(input)}\n#\n# ARGS\n#{dump_inout_type(input).chomp}\n#\n# RETURNS\n#{dump_inout_type(output).chomp}\n#\n__EOD__\n    unless fault.empty?\n      faultstr = (fault.collect { |f| dump_inout_type(f).chomp }).join(', ')\n      str <<<<__EOD__\n# RAISES\n#   #{faultstr}\n#\n__EOD__\n    end\n    str\n  end\n\n  def dq(ele)\n    ele.dump\n  end\n\n  def ndq(ele)\n    ele.nil? ? 'nil' : dq(ele)\n  end\n\n  def sym(ele)\n    ':' + ele\n  end\n\n  def dqname(qname)\n    qname.dump\n  end\n\nprivate\n\n  def dump_inout_type(param)\n    if param\n      message = param.find_message\n      params = \"\"\n      message.parts.each do |part|\n        name = safevarname(part.name)\n        if part.type\n          typename = safeconstname(part.type.name)\n          params << add_at(\"#   #{name}\", \"#{typename} - #{part.type}\\n\", 20)\n        elsif part.element\n          typename = safeconstname(part.element.name)\n          params << add_at(\"#   #{name}\", \"#{typename} - #{part.element}\\n\", 20)\n        end\n      end\n      unless params.empty?\n        return params\n      end\n    end\n    \"#   N/A\\n\"\n  end\n\n  def dump_inputparam(input)\n    message = input.find_message\n    params = \"\"\n    message.parts.each do |part|\n      params << \", \" unless params.empty?\n      params << safevarname(part.name)\n    end\n    if params.empty?\n      \"\"\n    else\n      \"(#{ params })\"\n    end\n  end\n\n  def add_at(base, str, pos)\n    if base.size >= pos\n      base + ' ' + str\n    else\n      base + ' ' * (pos - base.size) + str\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/clientSkeltonCreator.rb",
    "content": "# WSDL4R - Creating client skelton code from WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/classDefCreatorSupport'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass ClientSkeltonCreator\n  include ClassDefCreatorSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n  end\n\n  def dump(service_name)\n    result = \"\"\n    @definitions.service(service_name).ports.each do |port|\n      result << dump_porttype(port.porttype.name)\n      result << \"\\n\"\n    end\n    result\n  end\n\nprivate\n\n  def dump_porttype(name)\n    drv_name = create_class_name(name)\n\n    result = \"\"\n    result << <<__EOD__\nendpoint_url = ARGV.shift\nobj = #{ drv_name }.new(endpoint_url)\n\n# run ruby with -d to see SOAP wiredumps.\nobj.wiredump_dev = STDERR if $DEBUG\n\n__EOD__\n    @definitions.porttype(name).operations.each do |operation|\n      result << dump_method_signature(operation)\n      result << dump_input_init(operation.input) << \"\\n\"\n      result << dump_operation(operation) << \"\\n\\n\"\n    end\n    result\n  end\n\n  def dump_operation(operation)\n    name = operation.name\n    input = operation.input\n    \"puts obj.#{ safemethodname(name.name) }#{ dump_inputparam(input) }\"\n  end\n\n  def dump_input_init(input)\n    result = input.find_message.parts.collect { |part|\n      safevarname(part.name)\n    }.join(\" = \")\n    if result.empty?\n      \"\"\n    else\n      result << \" = nil\"\n    end\n    result\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/complexType.rb",
    "content": "# WSDL4R - SOAP complexType definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/xmlSchema/complexType'\nrequire 'soap/mapping'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass ComplexType < Info\n  def compoundtype\n    @compoundtype ||= check_type\n  end\n\n  def check_type\n    if content\n      if attributes.empty? and\n          content.elements.size == 1 and content.elements[0].maxoccurs != '1'\n        if name == ::SOAP::Mapping::MapQName\n          :TYPE_MAP\n        else\n          :TYPE_ARRAY\n        end\n      else\n\t:TYPE_STRUCT\n      end\n    elsif complexcontent\n      if complexcontent.base == ::SOAP::ValueArrayName\n        :TYPE_ARRAY\n      else\n        complexcontent.basetype.check_type\n      end\n    elsif simplecontent\n      :TYPE_SIMPLE\n    elsif !attributes.empty?\n      :TYPE_STRUCT\n    else # empty complexType definition (seen in partner.wsdl of salesforce)\n      :TYPE_EMPTY\n    end\n  end\n\n  def child_type(name = nil)\n    case compoundtype\n    when :TYPE_STRUCT\n      if ele = find_element(name)\n        ele.type\n      elsif ele = find_element_by_name(name.name)\n\tele.type\n      end\n    when :TYPE_ARRAY\n      @contenttype ||= content_arytype\n    when :TYPE_MAP\n      item_ele = find_element_by_name(\"item\") or\n        raise RuntimeError.new(\"'item' element not found in Map definition.\")\n      content = item_ele.local_complextype or\n        raise RuntimeError.new(\"No complexType definition for 'item'.\")\n      if ele = content.find_element(name)\n        ele.type\n      elsif ele = content.find_element_by_name(name.name)\n        ele.type\n      end\n    else\n      raise NotImplementedError.new(\"Unknown kind of complexType.\")\n    end\n  end\n\n  def child_defined_complextype(name)\n    ele = nil\n    case compoundtype\n    when :TYPE_STRUCT, :TYPE_MAP\n      unless ele = find_element(name)\n       \tif name.namespace.nil?\n  \t  ele = find_element_by_name(name.name)\n   \tend\n      end\n    when :TYPE_ARRAY\n      if content.elements.size == 1\n\tele = content.elements[0]\n      else\n\traise RuntimeError.new(\"Assert: must not reach.\")\n      end\n    else\n      raise RuntimeError.new(\"Assert: Not implemented.\")\n    end\n    unless ele\n      raise RuntimeError.new(\"Cannot find #{name} as a children of #{@name}.\")\n    end\n    ele.local_complextype\n  end\n\n  def find_arytype\n    unless compoundtype == :TYPE_ARRAY\n      raise RuntimeError.new(\"Assert: not for array\")\n    end\n    if complexcontent\n      complexcontent.attributes.each do |attribute|\n\tif attribute.ref == ::SOAP::AttrArrayTypeName\n\t  return attribute.arytype\n\tend\n      end\n      if check_array_content(complexcontent.content)\n        return element_simpletype(complexcontent.content.elements[0])\n      end\n    elsif check_array_content(content)\n      return element_simpletype(content.elements[0])\n    end\n    raise RuntimeError.new(\"Assert: Unknown array definition.\")\n  end\n\n  def find_aryelement\n    unless compoundtype == :TYPE_ARRAY\n      raise RuntimeError.new(\"Assert: not for array\")\n    end\n    if complexcontent\n      if check_array_content(complexcontent.content)\n        return complexcontent.content.elements[0]\n      end\n    elsif check_array_content(content)\n      return content.elements[0]\n    end\n    nil # use default item name\n  end\n\nprivate\n\n  def element_simpletype(element)\n    if element.type\n      element.type \n    elsif element.local_simpletype\n      element.local_simpletype.base\n    else\n      nil\n    end\n  end\n\n  def check_array_content(content)\n    content and content.elements.size == 1 and\n      content.elements[0].maxoccurs != '1'\n  end\n\n  def content_arytype\n    if arytype = find_arytype\n      ns = arytype.namespace\n      name = arytype.name.sub(/\\[(?:,)*\\]$/, '')\n      XSD::QName.new(ns, name)\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/data.rb",
    "content": "# WSDL4R - WSDL SOAP binding data definitions.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'wsdl/soap/definitions'\nrequire 'wsdl/soap/binding'\nrequire 'wsdl/soap/operation'\nrequire 'wsdl/soap/body'\nrequire 'wsdl/soap/element'\nrequire 'wsdl/soap/header'\nrequire 'wsdl/soap/headerfault'\nrequire 'wsdl/soap/fault'\nrequire 'wsdl/soap/address'\nrequire 'wsdl/soap/complexType'\n\n\nmodule WSDL\nmodule SOAP\n\n\nHeaderFaultName = XSD::QName.new(SOAPBindingNamespace, 'headerfault')\n\nLocationAttrName = XSD::QName.new(nil, 'location')\nStyleAttrName = XSD::QName.new(nil, 'style')\nTransportAttrName = XSD::QName.new(nil, 'transport')\nUseAttrName = XSD::QName.new(nil, 'use')\nPartsAttrName = XSD::QName.new(nil, 'parts')\nPartAttrName = XSD::QName.new(nil, 'part')\nNameAttrName = XSD::QName.new(nil, 'name')\nMessageAttrName = XSD::QName.new(nil, 'message')\nEncodingStyleAttrName = XSD::QName.new(nil, 'encodingStyle')\nNamespaceAttrName = XSD::QName.new(nil, 'namespace')\nSOAPActionAttrName = XSD::QName.new(nil, 'soapAction')\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/definitions.rb",
    "content": "# WSDL4R - WSDL additional definitions for SOAP.\n# Copyright (C) 2002-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\nrequire 'soap/mapping'\n\n\nmodule WSDL\n\n\nclass Definitions < Info\n  def self.soap_rpc_complextypes\n    types = XSD::NamedElements.new\n    types << array_complextype\n    types << fault_complextype\n    types << exception_complextype\n    types\n  end\n\n  def self.array_complextype\n    type = XMLSchema::ComplexType.new(::SOAP::ValueArrayName)\n    type.complexcontent = XMLSchema::ComplexContent.new\n    type.complexcontent.base = ::SOAP::ValueArrayName\n    attr = XMLSchema::Attribute.new\n    attr.ref = ::SOAP::AttrArrayTypeName\n    anytype = XSD::AnyTypeName.dup\n    anytype.name += '[]'\n    attr.arytype = anytype\n    type.complexcontent.attributes << attr\n    type\n  end\n\n=begin\n<xs:complexType name=\"Fault\" final=\"extension\">\n  <xs:sequence>\n    <xs:element name=\"faultcode\" type=\"xs:QName\" /> \n    <xs:element name=\"faultstring\" type=\"xs:string\" /> \n    <xs:element name=\"faultactor\" type=\"xs:anyURI\" minOccurs=\"0\" /> \n    <xs:element name=\"detail\" type=\"tns:detail\" minOccurs=\"0\" /> \n  </xs:sequence>\n</xs:complexType>\n=end\n  def self.fault_complextype\n    type = XMLSchema::ComplexType.new(::SOAP::EleFaultName)\n    faultcode = XMLSchema::Element.new(::SOAP::EleFaultCodeName, XSD::XSDQName::Type)\n    faultstring = XMLSchema::Element.new(::SOAP::EleFaultStringName, XSD::XSDString::Type)\n    faultactor = XMLSchema::Element.new(::SOAP::EleFaultActorName, XSD::XSDAnyURI::Type)\n    faultactor.minoccurs = 0\n    detail = XMLSchema::Element.new(::SOAP::EleFaultDetailName, XSD::AnyTypeName)\n    detail.minoccurs = 0\n    type.all_elements = [faultcode, faultstring, faultactor, detail]\n    type.final = 'extension'\n    type\n  end\n\n  def self.exception_complextype\n    type = XMLSchema::ComplexType.new(XSD::QName.new(\n\t::SOAP::Mapping::RubyCustomTypeNamespace, 'SOAPException'))\n    excn_name = XMLSchema::Element.new(XSD::QName.new(nil, 'excn_type_name'), XSD::XSDString::Type)\n    cause = XMLSchema::Element.new(XSD::QName.new(nil, 'cause'), XSD::AnyTypeName)\n    backtrace = XMLSchema::Element.new(XSD::QName.new(nil, 'backtrace'), ::SOAP::ValueArrayName)\n    message = XMLSchema::Element.new(XSD::QName.new(nil, 'message'), XSD::XSDString::Type)\n    type.all_elements = [excn_name, cause, backtrace, message]\n    type\n  end\n\n  def soap_rpc_complextypes(binding)\n    types = rpc_operation_complextypes(binding)\n    types + self.class.soap_rpc_complextypes\n  end\n\n  def collect_faulttypes\n    result = []\n    collect_fault_messages.each do |name|\n      faultparts = message(name).parts\n      if faultparts.size != 1\n\traise RuntimeError.new(\"expecting fault message to have only 1 part\")\n      end\n      if result.index(faultparts[0].type).nil?\n\tresult << faultparts[0].type\n      end\n    end\n    result\n  end\n\nprivate\n\n  def collect_fault_messages\n    result = []\n    porttypes.each do |porttype|\n      porttype.operations.each do |operation|\n\toperation.fault.each do |fault|\n\t  if result.index(fault.message).nil?\n\t    result << fault.message\n\t  end\n\tend\n      end\n    end\n    result\n  end\n\n  def rpc_operation_complextypes(binding)\n    types = XSD::NamedElements.new\n    binding.operations.each do |op_bind|\n      if op_bind_rpc?(op_bind)\n\toperation = op_bind.find_operation\n\tif op_bind.input\n\t  type = XMLSchema::ComplexType.new(op_bind.soapoperation_name)\n\t  message = messages[operation.input.message]\n\t  type.sequence_elements = elements_from_message(message)\n\t  types << type\n\tend\n\tif op_bind.output\n\t  type = XMLSchema::ComplexType.new(operation.outputname)\n\t  message = messages[operation.output.message]\n\t  type.sequence_elements = elements_from_message(message)\n\t  types << type\n\tend\n      end\n    end\n    types\n  end\n\n  def op_bind_rpc?(op_bind)\n    op_bind.soapoperation_style == :rpc\n  end\n\n  def elements_from_message(message)\n    message.parts.collect { |part|\n      if part.element\n        collect_elements[part.element]\n      elsif part.name.nil? or part.type.nil?\n\traise RuntimeError.new(\"part of a message must be an element or typed\")\n      else\n        qname = XSD::QName.new(nil, part.name)\n        XMLSchema::Element.new(qname, part.type)\n      end\n    }\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/soap/driverCreator.rb",
    "content": "# WSDL4R - Creating driver code from WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/mappingRegistryCreator'\nrequire 'wsdl/soap/methodDefCreator'\nrequire 'wsdl/soap/classDefCreatorSupport'\nrequire 'xsd/codegen'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass DriverCreator\n  include ClassDefCreatorSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n  end\n\n  def dump(porttype = nil)\n    if porttype.nil?\n      result = \"\"\n      @definitions.porttypes.each do |type|\n\tresult << dump_porttype(type.name)\n\tresult << \"\\n\"\n      end\n    else\n      result = dump_porttype(porttype)\n    end\n    result\n  end\n\nprivate\n\n  def dump_porttype(name)\n    class_name = create_class_name(name)\n    methoddef, types = MethodDefCreator.new(@definitions).dump(name)\n    mr_creator = MappingRegistryCreator.new(@definitions)\n    binding = @definitions.bindings.find { |item| item.type == name }\n    return '' unless binding.soapbinding        # not a SOAP binding\n    address = @definitions.porttype(name).locations[0]\n\n    c = XSD::CodeGen::ClassDef.new(class_name, \"::SOAP::RPC::Driver\")\n    c.def_require(\"soap/rpc/driver\")\n    c.def_const(\"MappingRegistry\", \"::SOAP::Mapping::Registry.new\")\n    c.def_const(\"DefaultEndpointUrl\", ndq(address))\n    c.def_code(mr_creator.dump(types))\n    c.def_code <<-EOD\nMethods = [\n#{methoddef.gsub(/^/, \"  \")}\n]\n    EOD\n    c.def_method(\"initialize\", \"endpoint_url = nil\") do\n      <<-EOD\n        endpoint_url ||= DefaultEndpointUrl\n        super(endpoint_url, nil)\n        self.mapping_registry = MappingRegistry\n        init_methods\n      EOD\n    end\n    c.def_privatemethod(\"init_methods\") do\n      <<-EOD\n        Methods.each do |definitions|\n          opt = definitions.last\n          if opt[:request_style] == :document\n            add_document_operation(*definitions)\n          else\n            add_rpc_operation(*definitions)\n            qname = definitions[0]\n            name = definitions[2]\n            if qname.name != name and qname.name.capitalize == name.capitalize\n              ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|\n                __send__(name, *arg)\n              end\n            end\n          end\n        end\n      EOD\n    end\n    c.dump\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/element.rb",
    "content": "# WSDL4R - XMLSchema element definition for WSDL.\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/xmlSchema/element'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Element < Info\n  def map_as_array?\n    maxoccurs != '1'\n  end\n\n  def attributes\n    @local_complextype.attributes\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/fault.rb",
    "content": "# WSDL4R - WSDL SOAP body definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass Fault < Info\n  attr_reader :name\t# required\n  attr_reader :use\t# required\n  attr_reader :encodingstyle\n  attr_reader :namespace\n\n  def initialize\n    super\n    @name = nil\n    @use = nil\n    @encodingstyle = nil\n    @namespace = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    when UseAttrName\n      @use = value.source\n    when EncodingStyleAttrName\n      @encodingstyle = value.source\n    when NamespaceAttrName\n      @namespace = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/header.rb",
    "content": "# WSDL4R - WSDL SOAP body definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass Header < Info\n  attr_reader :headerfault\n\n  attr_reader :message\t# required\n  attr_reader :part\t# required\n  attr_reader :use\t# required\n  attr_reader :encodingstyle\n  attr_reader :namespace\n\n  def initialize\n    super\n    @message = nil\n    @part = nil\n    @use = nil\n    @encodingstyle = nil\n    @namespace = nil\n    @headerfault = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def find_message\n    root.message(@message) or raise RuntimeError.new(\"#{@message} not found\")\n  end\n\n  def find_part\n    find_message.parts.each do |part|\n      if part.name == @part\n\treturn part\n      end\n    end\n    raise RuntimeError.new(\"#{@part} not found\")\n  end\n\n  def parse_element(element)\n    case element\n    when HeaderFaultName\n      o = WSDL::SOAP::HeaderFault.new\n      @headerfault = o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MessageAttrName\n      if value.namespace.nil?\n        value = XSD::QName.new(targetnamespace, value.source)\n      end\n      @message = value\n    when PartAttrName\n      @part = value.source\n    when UseAttrName\n      @use = value.source\n    when EncodingStyleAttrName\n      @encodingstyle = value.source\n    when NamespaceAttrName\n      @namespace = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/headerfault.rb",
    "content": "# WSDL4R - WSDL SOAP body definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass HeaderFault < Info\n  attr_reader :message\t# required\n  attr_reader :part\t# required\n  attr_reader :use\t# required\n  attr_reader :encodingstyle\n  attr_reader :namespace\n\n  def initialize\n    super\n    @message = nil\n    @part = nil\n    @use = nil\n    @encodingstyle = nil\n    @namespace = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MessageAttrName\n      @message = value\n    when PartAttrName\n      @part = value.source\n    when UseAttrName\n      @use = value.source\n    when EncodingStyleAttrName\n      @encodingstyle = value.source\n    when NamespaceAttrName\n      @namespace = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/mappingRegistryCreator.rb",
    "content": "# WSDL4R - Creating MappingRegistry code from WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/classDefCreatorSupport'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass MappingRegistryCreator\n  include ClassDefCreatorSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n    @complextypes = @definitions.collect_complextypes\n    @types = nil\n  end\n\n  def dump(types)\n    @types = types\n    map_cache = []\n    map = \"\"\n    @types.each do |type|\n      if map_cache.index(type).nil?\n\tmap_cache << type\n\tif type.namespace != XSD::Namespace\n\t  if typemap = dump_typemap(type)\n            map << typemap\n          end\n\tend\n      end\n   end\n    return map\n  end\n\nprivate\n\n  def dump_typemap(type)\n    if definedtype = @complextypes[type]\n      case definedtype.compoundtype\n      when :TYPE_STRUCT\n        dump_struct_typemap(definedtype)\n      when :TYPE_ARRAY\n        dump_array_typemap(definedtype)\n      when :TYPE_MAP, :TYPE_EMPTY\n        nil\n      else\n        raise NotImplementedError.new(\"must not reach here\")\n      end\n    end\n  end\n\n  def dump_struct_typemap(definedtype)\n    ele = definedtype.name\n    return <<__EOD__\nMappingRegistry.set(\n  #{create_class_name(ele)},\n  ::SOAP::SOAPStruct,\n  ::SOAP::Mapping::Registry::TypedStructFactory,\n  { :type => #{dqname(ele)} }\n)\n__EOD__\n  end\n\n  def dump_array_typemap(definedtype)\n    ele = definedtype.name\n    arytype = definedtype.find_arytype || XSD::AnyTypeName\n    type = XSD::QName.new(arytype.namespace, arytype.name.sub(/\\[(?:,)*\\]$/, ''))\n    @types << type\n    return <<__EOD__\nMappingRegistry.set(\n  #{create_class_name(ele)},\n  ::SOAP::SOAPArray,\n  ::SOAP::Mapping::Registry::TypedArrayFactory,\n  { :type => #{dqname(type)} }\n)\n__EOD__\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/methodDefCreator.rb",
    "content": "# WSDL4R - Creating driver code from WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/classDefCreatorSupport'\nrequire 'soap/rpc/element'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass MethodDefCreator\n  include ClassDefCreatorSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n    @simpletypes = @definitions.collect_simpletypes\n    @complextypes = @definitions.collect_complextypes\n    @elements = @definitions.collect_elements\n    @types = []\n  end\n\n  def dump(porttype)\n    @types.clear\n    result = \"\"\n    operations = @definitions.porttype(porttype).operations\n    binding = @definitions.porttype_binding(porttype)\n    operations.each do |operation|\n      op_bind = binding.operations[operation.name]\n      next unless op_bind # no binding is defined\n      next unless op_bind.soapoperation # not a SOAP operation binding\n      result << \",\\n\" unless result.empty?\n      result << dump_method(operation, op_bind).chomp\n    end\n    return result, @types\n  end\n\n  def collect_rpcparameter(operation)\n    result = operation.inputparts.collect { |part|\n      collect_type(part.type)\n      param_set(::SOAP::RPC::SOAPMethod::IN, part.name, rpcdefinedtype(part))\n    }\n    outparts = operation.outputparts\n    if outparts.size > 0\n      retval = outparts[0]\n      collect_type(retval.type)\n      result << param_set(::SOAP::RPC::SOAPMethod::RETVAL, retval.name,\n        rpcdefinedtype(retval))\n      cdr(outparts).each { |part|\n\tcollect_type(part.type)\n\tresult << param_set(::SOAP::RPC::SOAPMethod::OUT, part.name,\n          rpcdefinedtype(part))\n      }\n    end\n    result\n  end\n\n  def collect_documentparameter(operation)\n    param = []\n    operation.inputparts.each do |input|\n      param << param_set(::SOAP::RPC::SOAPMethod::IN, input.name,\n        documentdefinedtype(input), elementqualified(input))\n    end\n    operation.outputparts.each do |output|\n      param << param_set(::SOAP::RPC::SOAPMethod::OUT, output.name,\n        documentdefinedtype(output), elementqualified(output))\n    end\n    param\n  end\n\nprivate\n\n  def dump_method(operation, binding)\n    name = safemethodname(operation.name.name)\n    name_as = operation.name.name\n    style = binding.soapoperation_style\n    inputuse = binding.input.soapbody_use\n    outputuse = binding.output.soapbody_use\n    namespace = binding.input.soapbody.namespace\n    if style == :rpc\n      qname = XSD::QName.new(namespace, name_as)\n      paramstr = param2str(collect_rpcparameter(operation))\n    else\n      qname = nil\n      paramstr = param2str(collect_documentparameter(operation))\n    end\n    if paramstr.empty?\n      paramstr = '[]'\n    else\n      paramstr = \"[ \" << paramstr.split(/\\r?\\n/).join(\"\\n    \") << \" ]\"\n    end\n    definitions = <<__EOD__\n#{ndq(binding.soapaction)},\n  #{dq(name)},\n  #{paramstr},\n  { :request_style =>  #{sym(style.id2name)}, :request_use =>  #{sym(inputuse.id2name)},\n    :response_style => #{sym(style.id2name)}, :response_use => #{sym(outputuse.id2name)} }\n__EOD__\n    if style == :rpc\n      return <<__EOD__\n[ #{qname.dump},\n  #{definitions}]\n__EOD__\n    else\n      return <<__EOD__\n[ #{definitions}]\n__EOD__\n    end\n  end\n\n  def rpcdefinedtype(part)\n    if mapped = basetype_mapped_class(part.type)\n      ['::' + mapped.name]\n    elsif definedtype = @simpletypes[part.type]\n      ['::' + basetype_mapped_class(definedtype.base).name]\n    elsif definedtype = @elements[part.element]\n      #['::SOAP::SOAPStruct', part.element.namespace, part.element.name]\n      ['nil', part.element.namespace, part.element.name]\n    elsif definedtype = @complextypes[part.type]\n      case definedtype.compoundtype\n      when :TYPE_STRUCT, :TYPE_EMPTY    # ToDo: empty should be treated as void.\n        type = create_class_name(part.type)\n\t[type, part.type.namespace, part.type.name]\n      when :TYPE_MAP\n\t[Hash.name, part.type.namespace, part.type.name]\n      when :TYPE_ARRAY\n\tarytype = definedtype.find_arytype || XSD::AnyTypeName\n\tns = arytype.namespace\n\tname = arytype.name.sub(/\\[(?:,)*\\]$/, '')\n        type = create_class_name(XSD::QName.new(ns, name))\n\t[type + '[]', ns, name]\n      else\n\traise NotImplementedError.new(\"must not reach here\")\n      end\n    else\n      raise RuntimeError.new(\"part: #{part.name} cannot be resolved\")\n    end\n  end\n\n  def documentdefinedtype(part)\n    if mapped = basetype_mapped_class(part.type)\n      ['::' + mapped.name, nil, part.name]\n    elsif definedtype = @simpletypes[part.type]\n      ['::' + basetype_mapped_class(definedtype.base).name, nil, part.name]\n    elsif definedtype = @elements[part.element]\n      ['::SOAP::SOAPElement', part.element.namespace, part.element.name]\n    elsif definedtype = @complextypes[part.type]\n      ['::SOAP::SOAPElement', part.type.namespace, part.type.name]\n    else\n      raise RuntimeError.new(\"part: #{part.name} cannot be resolved\")\n    end\n  end\n\n  def elementqualified(part)\n    if mapped = basetype_mapped_class(part.type)\n      false\n    elsif definedtype = @simpletypes[part.type]\n      false\n    elsif definedtype = @elements[part.element]\n      definedtype.elementform == 'qualified'\n    elsif definedtype = @complextypes[part.type]\n      false\n    else\n      raise RuntimeError.new(\"part: #{part.name} cannot be resolved\")\n    end\n  end\n\n  def param_set(io_type, name, type, ele = nil)\n    [io_type, name, type, ele]\n  end\n\n  def collect_type(type)\n    # ignore inline type definition.\n    return if type.nil?\n    return if @types.include?(type)\n    @types << type\n    return unless @complextypes[type]\n    @complextypes[type].each_element do |element|\n      collect_type(element.type)\n    end\n  end\n\n  def param2str(params)\n    params.collect { |param|\n      io, name, type, ele = param\n      unless ele.nil?\n        \"[#{dq(io)}, #{dq(name)}, #{type2str(type)}, #{ele2str(ele)}]\"\n      else\n        \"[#{dq(io)}, #{dq(name)}, #{type2str(type)}]\"\n      end\n    }.join(\",\\n\")\n  end\n\n  def type2str(type)\n    if type.size == 1\n      \"[#{dq(type[0])}]\" \n    else\n      \"[#{dq(type[0])}, #{ndq(type[1])}, #{dq(type[2])}]\" \n    end\n  end\n\n  def ele2str(ele)\n    qualified = ele\n    if qualified\n      \"true\"\n    else\n      \"false\"\n    end\n  end\n\n  def cdr(ary)\n    result = ary.dup\n    result.shift\n    result\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/operation.rb",
    "content": "# WSDL4R - WSDL SOAP operation definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass Operation < Info\n  class OperationInfo\n    attr_reader :style\n    attr_reader :op_name\n    attr_reader :optype_name\n    attr_reader :headerparts\n    attr_reader :bodyparts\n    attr_reader :faultpart\n    attr_reader :soapaction\n    \n    def initialize(style, op_name, optype_name, headerparts, bodyparts, faultpart, soapaction)\n      @style = style\n      @op_name = op_name\n      @optype_name = optype_name\n      @headerparts = headerparts\n      @bodyparts = bodyparts\n      @faultpart = faultpart\n      @soapaction = soapaction\n    end\n  end\n\n  attr_reader :soapaction\n  attr_reader :style\n\n  def initialize\n    super\n    @soapaction = nil\n    @style = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when StyleAttrName\n      if [\"document\", \"rpc\"].include?(value.source)\n\t@style = value.source.intern\n      else\n\traise Parser::AttributeConstraintError.new(\n          \"Unexpected value #{ value }.\")\n      end\n    when SOAPActionAttrName\n      @soapaction = value.source\n    else\n      nil\n    end\n  end\n\n  def input_info\n    name_info = parent.find_operation.input_info\n    param_info(name_info, parent.input)\n  end\n\n  def output_info\n    name_info = parent.find_operation.output_info\n    param_info(name_info, parent.output)\n  end\n\n  def operation_style\n    return @style if @style\n    if parent_binding.soapbinding\n      return parent_binding.soapbinding.style\n    end\n    nil\n  end\n\nprivate\n\n  def parent_binding\n    parent.parent\n  end\n\n  def param_info(name_info, param)\n    op_name = name_info.op_name\n    optype_name = name_info.optype_name\n\n    soapheader = param.soapheader\n    headerparts = soapheader.collect { |item| item.find_part }\n\n    soapbody = param.soapbody\n    if soapbody.encodingstyle and\n\tsoapbody.encodingstyle != ::SOAP::EncodingNamespace\n      raise NotImplementedError.new(\n\t\"EncodingStyle '#{ soapbody.encodingstyle }' not supported.\")\n    end\n    if soapbody.namespace\n      op_name = XSD::QName.new(soapbody.namespace, op_name.name)\n    end\n    if soapbody.parts\n      target = soapbody.parts.split(/\\s+/)\n      bodyparts = name_info.parts.find_all { |part|\n\ttarget.include?(part.name)\n      }\n    else\n      bodyparts = name_info.parts\n    end\n\n    faultpart = nil\n    OperationInfo.new(operation_style, op_name, optype_name, headerparts, bodyparts, faultpart, parent.soapaction)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/servantSkeltonCreator.rb",
    "content": "# WSDL4R - Creating servant skelton code from WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/classDefCreatorSupport'\nrequire 'xsd/codegen'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass ServantSkeltonCreator\n  include ClassDefCreatorSupport\n  include XSD::CodeGen::GenSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n  end\n\n  def dump(porttype = nil)\n    if porttype.nil?\n      result = \"\"\n      @definitions.porttypes.each do |type|\n\tresult << dump_porttype(type.name)\n\tresult << \"\\n\"\n      end\n    else\n      result = dump_porttype(porttype)\n    end\n    result\n  end\n\nprivate\n\n  def dump_porttype(name)\n    class_name = create_class_name(name)\n    c = XSD::CodeGen::ClassDef.new(class_name)\n    operations = @definitions.porttype(name).operations\n    operations.each do |operation|\n      name = safemethodname(operation.name.name)\n      input = operation.input\n      params = input.find_message.parts.collect { |part|\n        safevarname(part.name)\n      }\n      m = XSD::CodeGen::MethodDef.new(name, params) do <<-EOD\n            p [#{params.join(\", \")}]\n            raise NotImplementedError.new\n          EOD\n        end\n      m.comment = dump_method_signature(operation)\n      c.add_method(m)\n    end\n    c.dump\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/standaloneServerStubCreator.rb",
    "content": "# WSDL4R - Creating standalone server stub code from WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/soap/mappingRegistryCreator'\nrequire 'wsdl/soap/methodDefCreator'\nrequire 'wsdl/soap/classDefCreatorSupport'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass StandaloneServerStubCreator\n  include ClassDefCreatorSupport\n\n  attr_reader :definitions\n\n  def initialize(definitions)\n    @definitions = definitions\n  end\n\n  def dump(service_name)\n    warn(\"- Standalone stub can have only 1 port for now.  So creating stub for the first port and rests are ignored.\")\n    warn(\"- Standalone server stub ignores port location defined in WSDL.  Location is http://localhost:10080/ by default.  Generated client from WSDL must be configured to point this endpoint manually.\")\n    port = @definitions.service(service_name).ports[0]\n    dump_porttype(port.porttype.name)\n  end\n\nprivate\n\n  def dump_porttype(name)\n    class_name = create_class_name(name)\n    methoddef, types = MethodDefCreator.new(@definitions).dump(name)\n    mr_creator = MappingRegistryCreator.new(@definitions)\n\n    c1 = XSD::CodeGen::ClassDef.new(class_name)\n    c1.def_require(\"soap/rpc/standaloneServer\")\n    c1.def_require(\"soap/mapping/registry\")\n    c1.def_const(\"MappingRegistry\", \"::SOAP::Mapping::Registry.new\")\n    c1.def_code(mr_creator.dump(types))\n    c1.def_code <<-EOD\nMethods = [\n#{methoddef.gsub(/^/, \"  \")}\n]\n    EOD\n    c2 = XSD::CodeGen::ClassDef.new(class_name + \"App\",\n      \"::SOAP::RPC::StandaloneServer\")\n    c2.def_method(\"initialize\", \"*arg\") do\n      <<-EOD\n        super(*arg)\n        servant = #{class_name}.new\n        #{class_name}::Methods.each do |definitions|\n          opt = definitions.last\n          if opt[:request_style] == :document\n            @router.add_document_operation(servant, *definitions)\n          else\n            @router.add_rpc_operation(servant, *definitions)\n          end\n        end\n        self.mapping_registry = #{class_name}::MappingRegistry\n      EOD\n    end\n    c1.dump + \"\\n\" + c2.dump + format(<<-EOD)\n\n      if $0 == __FILE__\n        # Change listen port.\n        server = #{class_name}App.new('app', nil, '0.0.0.0', 10080)\n        trap(:INT) do\n          server.shutdown\n        end\n        server.start\n      end\n    EOD\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/soap/wsdl2ruby.rb",
    "content": "# WSDL4R - WSDL to ruby mapping library.\n# Copyright (C) 2002-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'logger'\nrequire 'xsd/qname'\nrequire 'wsdl/importer'\nrequire 'wsdl/soap/classDefCreator'\nrequire 'wsdl/soap/servantSkeltonCreator'\nrequire 'wsdl/soap/driverCreator'\nrequire 'wsdl/soap/clientSkeltonCreator'\nrequire 'wsdl/soap/standaloneServerStubCreator'\nrequire 'wsdl/soap/cgiStubCreator'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass WSDL2Ruby\n  attr_accessor :location\n  attr_reader :opt\n  attr_accessor :logger\n  attr_accessor :basedir\n\n  def run\n    unless @location\n      raise RuntimeError, \"WSDL location not given\"\n    end\n    @wsdl = import(@location)\n    @name = @wsdl.name ? @wsdl.name.name : 'default'\n    create_file\n  end\n\nprivate\n\n  def initialize\n    @location = nil\n    @opt = {}\n    @logger = Logger.new(STDERR)\n    @basedir = nil\n    @wsdl = nil\n    @name = nil\n  end\n\n  def create_file\n    create_classdef if @opt.key?('classdef')\n    create_servant_skelton(@opt['servant_skelton']) if @opt.key?('servant_skelton')\n    create_cgi_stub(@opt['cgi_stub']) if @opt.key?('cgi_stub')\n    create_standalone_server_stub(@opt['standalone_server_stub']) if @opt.key?('standalone_server_stub')\n    create_driver(@opt['driver']) if @opt.key?('driver')\n    create_client_skelton(@opt['client_skelton']) if @opt.key?('client_skelton')\n  end\n\n  def create_classdef\n    @logger.info { \"Creating class definition.\" }\n    @classdef_filename = @name + '.rb'\n    check_file(@classdef_filename) or return\n    write_file(@classdef_filename) do |f|\n      f << WSDL::SOAP::ClassDefCreator.new(@wsdl).dump\n    end\n  end\n\n  def create_client_skelton(servicename)\n    @logger.info { \"Creating client skelton.\" }\n    servicename ||= @wsdl.services[0].name.name\n    @client_skelton_filename = servicename + 'Client.rb'\n    check_file(@client_skelton_filename) or return\n    write_file(@client_skelton_filename) do |f|\n      f << shbang << \"\\n\"\n      f << \"require '#{@driver_filename}'\\n\\n\" if @driver_filename\n      f << WSDL::SOAP::ClientSkeltonCreator.new(@wsdl).dump(\n\tcreate_name(servicename))\n    end\n  end\n\n  def create_servant_skelton(porttypename)\n    @logger.info { \"Creating servant skelton.\" }\n    @servant_skelton_filename = (porttypename || @name + 'Servant') + '.rb'\n    check_file(@servant_skelton_filename) or return\n    write_file(@servant_skelton_filename) do |f|\n      f << \"require '#{@classdef_filename}'\\n\\n\" if @classdef_filename\n      f << WSDL::SOAP::ServantSkeltonCreator.new(@wsdl).dump(\n\tcreate_name(porttypename))\n    end\n  end\n\n  def create_cgi_stub(servicename)\n    @logger.info { \"Creating CGI stub.\" }\n    servicename ||= @wsdl.services[0].name.name\n    @cgi_stubFilename = servicename + '.cgi'\n    check_file(@cgi_stubFilename) or return\n    write_file(@cgi_stubFilename) do |f|\n      f << shbang << \"\\n\"\n      if @servant_skelton_filename\n\tf << \"require '#{@servant_skelton_filename}'\\n\\n\"\n      end\n      f << WSDL::SOAP::CGIStubCreator.new(@wsdl).dump(create_name(servicename))\n    end\n  end\n\n  def create_standalone_server_stub(servicename)\n    @logger.info { \"Creating standalone stub.\" }\n    servicename ||= @wsdl.services[0].name.name\n    @standalone_server_stub_filename = servicename + '.rb'\n    check_file(@standalone_server_stub_filename) or return\n    write_file(@standalone_server_stub_filename) do |f|\n      f << shbang << \"\\n\"\n      f << \"require '#{@servant_skelton_filename}'\\n\\n\" if @servant_skelton_filename\n      f << WSDL::SOAP::StandaloneServerStubCreator.new(@wsdl).dump(\n\tcreate_name(servicename))\n    end\n  end\n\n  def create_driver(porttypename)\n    @logger.info { \"Creating driver.\" }\n    @driver_filename = (porttypename || @name) + 'Driver.rb'\n    check_file(@driver_filename) or return\n    write_file(@driver_filename) do |f|\n      f << \"require '#{@classdef_filename}'\\n\\n\" if @classdef_filename\n      f << WSDL::SOAP::DriverCreator.new(@wsdl).dump(\n\tcreate_name(porttypename))\n    end\n  end\n\n  def write_file(filename)\n    if @basedir\n      filename = File.join(basedir, filename)\n    end\n    File.open(filename, \"w\") do |f|\n      yield f\n    end\n  end\n\n  def check_file(filename)\n    if @basedir\n      filename = File.join(basedir, filename)\n    end\n    if FileTest.exist?(filename)\n      if @opt.key?('force')\n\t@logger.warn {\n\t  \"File '#{filename}' exists but overrides it.\"\n\t}\n\ttrue\n      else\n\t@logger.warn {\n\t  \"File '#{filename}' exists.  #{$0} did not override it.\"\n\t}\n\tfalse\n      end\n    else\n      @logger.info { \"Creates file '#{filename}'.\" }\n      true\n    end\n  end\n\n  def shbang\n    \"#!/usr/bin/env ruby\"\n  end\n\n  def create_name(name)\n    name ? XSD::QName.new(@wsdl.targetnamespace, name) : nil\n  end\n\n  def import(location)\n    WSDL::Importer.import(location)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/types.rb",
    "content": "# WSDL4R - WSDL types definition.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\n\n\nclass Types < Info\n  attr_reader :schemas\n\n  def initialize\n    super\n    @schemas = []\n  end\n\n  def parse_element(element)\n    case element\n    when SchemaName\n      o = XMLSchema::Schema.new\n      @schemas << o\n      o\n    when DocumentationName\n      o = Documentation.new\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    nil\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/wsdl.rb",
    "content": "# WSDL4R - Base definitions.\n# Copyright (C) 2000, 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\n\n\nmodule WSDL\n\n\nVersion = '0.0.2'\n\nNamespace = 'http://schemas.xmlsoap.org/wsdl/'\nSOAPBindingNamespace ='http://schemas.xmlsoap.org/wsdl/soap/'\n\nclass Error < StandardError; end\n\n\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/all.rb",
    "content": "# WSDL4R - XMLSchema complexType definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass All < Info\n  attr_reader :minoccurs\n  attr_reader :maxoccurs\n  attr_reader :elements\n\n  def initialize\n    super()\n    @minoccurs = '1'\n    @maxoccurs = '1'\n    @elements = []\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def elementformdefault\n    parent.elementformdefault\n  end\n\n  def <<(element)\n    @elements << element\n  end\n\n  def parse_element(element)\n    case element\n    when AnyName\n      o = Any.new\n      @elements << o\n      o\n    when ElementName\n      o = Element.new\n      @elements << o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MaxOccursAttrName\n      @maxoccurs = value.source\n    when MinOccursAttrName\n      @minoccurs = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/annotation.rb",
    "content": "# WSDL4R - WSDL SOAP documentation element.\n# Copyright (C) 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Annotation < Info\n  def initialize\n    super\n  end\n\n  def parse_element(element)\n    # Accepts any element.\n    self\n  end\n\n  def parse_attr(attr, value)\n    # Accepts any attribute.\n    true\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/any.rb",
    "content": "# WSDL4R - XMLSchema any definition for WSDL.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Any < Info\n  attr_accessor :maxoccurs\n  attr_accessor :minoccurs\n  attr_accessor :namespace\n  attr_accessor :process_contents\n\n  def initialize\n    super()\n    @maxoccurs = '1'\n    @minoccurs = '1'\n    @namespace = '##any'\n    @process_contents = 'strict'\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MaxOccursAttrName\n      @maxoccurs = value.source\n    when MinOccursAttrName\n      @minoccurs = value.source\n    when NamespaceAttrName\n      @namespace = value.source\n    when ProcessContentsAttrName\n      @process_contents = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/attribute.rb",
    "content": "# WSDL4R - XMLSchema attribute definition for WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Attribute < Info\n  class << self\n    if RUBY_VERSION > \"1.7.0\"\n      def attr_reader_ref(symbol)\n        name = symbol.to_s\n        define_method(name) {\n          instance_variable_get(\"@#{name}\") ||\n            (refelement ? refelement.__send__(name) : nil)\n        }\n      end\n    else\n      def attr_reader_ref(symbol)\n        name = symbol.to_s\n        module_eval <<-EOS\n          def #{name}\n            @#{name} || (refelement ? refelement.#{name} : nil)\n          end\n        EOS\n      end\n    end\n  end\n\n  attr_writer :use\n  attr_writer :form\n  attr_writer :name\n  attr_writer :type\n  attr_writer :local_simpletype\n  attr_writer :default\n  attr_writer :fixed\n\n  attr_reader_ref :use\n  attr_reader_ref :form\n  attr_reader_ref :name\n  attr_reader_ref :type\n  attr_reader_ref :local_simpletype\n  attr_reader_ref :default\n  attr_reader_ref :fixed\n\n  attr_accessor :ref\n  attr_accessor :arytype\n\n  def initialize\n    super\n    @use = nil\n    @form = nil\n    @name = nil\n    @type = nil\n    @local_simpletype = nil\n    @default = nil\n    @fixed = nil\n    @ref = nil\n    @refelement = nil\n    @arytype = nil\n  end\n\n  def refelement\n    @refelement ||= root.collect_attributes[@ref]\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    case element\n    when SimpleTypeName\n      @local_simpletype = SimpleType.new\n      @local_simpletype\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when RefAttrName\n      @ref = value\n    when UseAttrName\n      @use = value.source\n    when FormAttrName\n      @form = value.source\n    when NameAttrName\n      if directelement?\n        @name = XSD::QName.new(targetnamespace, value.source)\n      else\n        @name = XSD::QName.new(nil, value.source)\n      end\n    when TypeAttrName\n      @type = value\n    when DefaultAttrName\n      @default = value.source\n    when FixedAttrName\n      @fixed = value.source\n    when ArrayTypeAttrName\n      @arytype = if value.namespace.nil?\n          XSD::QName.new(XSD::Namespace, value.source)\n        else\n          value\n        end\n    else\n      nil\n    end\n  end\n\nprivate\n\n  def directelement?\n    parent.is_a?(Schema)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/choice.rb",
    "content": "# WSDL4R - XMLSchema complexType definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Choice < Info\n  attr_reader :minoccurs\n  attr_reader :maxoccurs\n  attr_reader :elements\n\n  def initialize\n    super()\n    @minoccurs = '1'\n    @maxoccurs = '1'\n    @elements = []\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def elementformdefault\n    parent.elementformdefault\n  end\n\n  def <<(element)\n    @elements << element\n  end\n\n  def parse_element(element)\n    case element\n    when AnyName\n      o = Any.new\n      @elements << o\n      o\n    when ElementName\n      o = Element.new\n      @elements << o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MaxOccursAttrName\n      @maxoccurs = value.source\n    when MinOccursAttrName\n      @minoccurs = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/complexContent.rb",
    "content": "# WSDL4R - XMLSchema complexContent definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass ComplexContent < Info\n  attr_accessor :base\n  attr_reader :derivetype\n  attr_reader :content\n  attr_reader :attributes\n\n  def initialize\n    super\n    @base = nil\n    @derivetype = nil\n    @content = nil\n    @attributes = XSD::NamedElements.new\n    @basetype = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def elementformdefault\n    parent.elementformdefault\n  end\n\n  def basetype\n    @basetype ||= root.collect_complextypes[@base]\n  end\n\n  def parse_element(element)\n    case element\n    when RestrictionName, ExtensionName\n      @derivetype = element.name\n      self\n    when AllName\n      if @derivetype.nil?\n\traise Parser::ElementConstraintError.new(\"base attr not found.\")\n      end\n      @content = All.new\n      @content\n    when SequenceName\n      if @derivetype.nil?\n\traise Parser::ElementConstraintError.new(\"base attr not found.\")\n      end\n      @content = Sequence.new\n      @content\n    when ChoiceName\n      if @derivetype.nil?\n\traise Parser::ElementConstraintError.new(\"base attr not found.\")\n      end\n      @content = Choice.new\n      @content\n    when AttributeName\n      if @derivetype.nil?\n\traise Parser::ElementConstraintError.new(\"base attr not found.\")\n      end\n      o = Attribute.new\n      @attributes << o\n      o\n    end\n  end\n\n  def parse_attr(attr, value)\n    if @derivetype.nil?\n      return nil\n    end\n    case attr\n    when BaseAttrName\n      @base = value\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/complexType.rb",
    "content": "# WSDL4R - XMLSchema complexType definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/xmlSchema/content'\nrequire 'wsdl/xmlSchema/element'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass ComplexType < Info\n  attr_accessor :name\n  attr_accessor :complexcontent\n  attr_accessor :simplecontent\n  attr_reader :content\n  attr_accessor :final\n  attr_accessor :mixed\n  attr_reader :attributes\n\n  def initialize(name = nil)\n    super()\n    @name = name\n    @complexcontent = nil\n    @simplecontent = nil\n    @content = nil\n    @final = nil\n    @mixed = false\n    @attributes = XSD::NamedElements.new\n  end\n\n  def targetnamespace\n    # inner elements can be qualified\n    # parent.is_a?(WSDL::XMLSchema::Element) ? nil : parent.targetnamespace\n    parent.targetnamespace\n  end\n\n  def elementformdefault\n    parent.elementformdefault\n  end\n \n  AnyAsElement = Element.new(XSD::QName.new(nil, 'any'), XSD::AnyTypeName)\n  def each_element\n    if content\n      content.elements.each do |element|\n        if element.is_a?(Any)\n          yield(AnyAsElement)\n        else\n          yield(element)\n        end\n      end\n    end\n  end\n\n  def find_element(name)\n    if content\n      content.elements.each do |element|\n        if element.is_a?(Any)\n          return AnyAsElement if name == AnyAsElement.name\n        else\n          return element if name == element.name\n        end\n      end\n    end\n    nil\n  end\n\n  def find_element_by_name(name)\n    if content\n      content.elements.each do |element|\n        if element.is_a?(Any)\n          return AnyAsElement if name == AnyAsElement.name.name\n        else\n          return element if name == element.name.name\n        end\n      end\n    end\n    nil\n  end\n\n  def sequence_elements=(elements)\n    @content = Sequence.new\n    elements.each do |element|\n      @content << element\n    end\n  end\n\n  def all_elements=(elements)\n    @content = All.new\n    elements.each do |element|\n      @content << element\n    end\n  end\n\n  def parse_element(element)\n    case element\n    when AllName\n      @content = All.new\n    when SequenceName\n      @content = Sequence.new\n    when ChoiceName\n      @content = Choice.new\n    when ComplexContentName\n      @complexcontent = ComplexContent.new\n    when SimpleContentName\n      @simplecontent = SimpleContent.new\n    when AttributeName\n      o = Attribute.new\n      @attributes << o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when FinalAttrName\n      @final = value.source\n    when MixedAttrName\n      @mixed = (value.source == 'true')\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/content.rb",
    "content": "# WSDL4R - XMLSchema complexType definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Content < Info\n  attr_accessor :final\n  attr_accessor :mixed\n  attr_accessor :type\n  attr_reader :contents\n  attr_reader :elements\n\n  def initialize\n    super()\n    @final = nil\n    @mixed = false\n    @type = nil\n    @contents = []\n    @elements = []\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def <<(content)\n    @contents << content\n    update_elements\n  end\n\n  def each\n    @contents.each do |content|\n      yield content\n    end\n  end\n\n  def parse_element(element)\n    case element\n    when AllName, SequenceName, ChoiceName\n      o = Content.new\n      o.type = element.name\n      @contents << o\n      o\n    when AnyName\n      o = Any.new\n      @contents << o\n      o\n    when ElementName\n      o = Element.new\n      @contents << o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when FinalAttrName\n      @final = value.source\n    when MixedAttrName\n      @mixed = (value.source == 'true')\n    else\n      nil\n    end\n  end\n\n  def parse_epilogue\n    update_elements\n  end\n\nprivate\n\n  def update_elements\n    @elements = []\n    @contents.each do |content|\n      if content.is_a?(Element)\n\t@elements << [content.name, content]\n      end\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/data.rb",
    "content": "# WSDL4R - XMLSchema data definitions.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/datatypes'\nrequire 'wsdl/xmlSchema/annotation'\nrequire 'wsdl/xmlSchema/schema'\nrequire 'wsdl/xmlSchema/import'\nrequire 'wsdl/xmlSchema/include'\nrequire 'wsdl/xmlSchema/simpleType'\nrequire 'wsdl/xmlSchema/simpleRestriction'\nrequire 'wsdl/xmlSchema/simpleExtension'\nrequire 'wsdl/xmlSchema/complexType'\nrequire 'wsdl/xmlSchema/complexContent'\nrequire 'wsdl/xmlSchema/simpleContent'\nrequire 'wsdl/xmlSchema/any'\nrequire 'wsdl/xmlSchema/element'\nrequire 'wsdl/xmlSchema/all'\nrequire 'wsdl/xmlSchema/choice'\nrequire 'wsdl/xmlSchema/sequence'\nrequire 'wsdl/xmlSchema/attribute'\nrequire 'wsdl/xmlSchema/unique'\nrequire 'wsdl/xmlSchema/enumeration'\nrequire 'wsdl/xmlSchema/length'\nrequire 'wsdl/xmlSchema/pattern'\n\nmodule WSDL\nmodule XMLSchema\n\n\nAllName = XSD::QName.new(XSD::Namespace, 'all')\nAnnotationName = XSD::QName.new(XSD::Namespace, 'annotation')\nAnyName = XSD::QName.new(XSD::Namespace, 'any')\nAttributeName = XSD::QName.new(XSD::Namespace, 'attribute')\nChoiceName = XSD::QName.new(XSD::Namespace, 'choice')\nComplexContentName = XSD::QName.new(XSD::Namespace, 'complexContent')\nComplexTypeName = XSD::QName.new(XSD::Namespace, 'complexType')\nElementName = XSD::QName.new(XSD::Namespace, 'element')\nEnumerationName = XSD::QName.new(XSD::Namespace, 'enumeration')\nExtensionName = XSD::QName.new(XSD::Namespace, 'extension')\nImportName = XSD::QName.new(XSD::Namespace, 'import')\nIncludeName = XSD::QName.new(XSD::Namespace, 'include')\nLengthName = XSD::QName.new(XSD::Namespace, 'length')\nPatternName = XSD::QName.new(XSD::Namespace, 'pattern')\nRestrictionName = XSD::QName.new(XSD::Namespace, 'restriction')\nSequenceName = XSD::QName.new(XSD::Namespace, 'sequence')\nSchemaName = XSD::QName.new(XSD::Namespace, 'schema')\nSimpleContentName = XSD::QName.new(XSD::Namespace, 'simpleContent')\nSimpleTypeName = XSD::QName.new(XSD::Namespace, 'simpleType')\nUniqueName = XSD::QName.new(XSD::Namespace, 'unique')\n\nAttributeFormDefaultAttrName = XSD::QName.new(nil, 'attributeFormDefault')\nBaseAttrName = XSD::QName.new(nil, 'base')\nDefaultAttrName = XSD::QName.new(nil, 'default')\nElementFormDefaultAttrName = XSD::QName.new(nil, 'elementFormDefault')\nFinalAttrName = XSD::QName.new(nil, 'final')\nFixedAttrName = XSD::QName.new(nil, 'fixed')\nFormAttrName = XSD::QName.new(nil, 'form')\nIdAttrName = XSD::QName.new(nil, 'id')\nMaxOccursAttrName = XSD::QName.new(nil, 'maxOccurs')\nMinOccursAttrName = XSD::QName.new(nil, 'minOccurs')\nMixedAttrName = XSD::QName.new(nil, 'mixed')\nNameAttrName = XSD::QName.new(nil, 'name')\nNamespaceAttrName = XSD::QName.new(nil, 'namespace')\nNillableAttrName = XSD::QName.new(nil, 'nillable')\nProcessContentsAttrName = XSD::QName.new(nil, 'processContents')\nRefAttrName = XSD::QName.new(nil, 'ref')\nSchemaLocationAttrName = XSD::QName.new(nil, 'schemaLocation')\nTargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace')\nTypeAttrName = XSD::QName.new(nil, 'type')\nUseAttrName = XSD::QName.new(nil, 'use')\nValueAttrName = XSD::QName.new(nil, 'value')\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/element.rb",
    "content": "# WSDL4R - XMLSchema element definition for WSDL.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Element < Info\n  class << self\n    if RUBY_VERSION > \"1.7.0\"\n      def attr_reader_ref(symbol)\n        name = symbol.to_s\n        define_method(name) {\n          instance_variable_get(\"@#{name}\") ||\n            (refelement ? refelement.__send__(name) : nil)\n        }\n      end\n    else\n      def attr_reader_ref(symbol)\n        name = symbol.to_s\n        module_eval <<-EOS\n          def #{name}\n            @#{name} || (refelement ? refelement.#{name} : nil)\n          end\n        EOS\n      end\n    end\n  end\n\n  attr_writer :name\t# required\n  attr_writer :form\n  attr_writer :type\n  attr_writer :local_simpletype\n  attr_writer :local_complextype\n  attr_writer :constraint\n  attr_writer :maxoccurs\n  attr_writer :minoccurs\n  attr_writer :nillable\n\n  attr_reader_ref :name\n  attr_reader_ref :form\n  attr_reader_ref :type\n  attr_reader_ref :local_simpletype\n  attr_reader_ref :local_complextype\n  attr_reader_ref :constraint\n  attr_reader_ref :maxoccurs\n  attr_reader_ref :minoccurs\n  attr_reader_ref :nillable\n\n  attr_accessor :ref\n\n  def initialize(name = nil, type = nil)\n    super()\n    @name = name\n    @form = nil\n    @type = type\n    @local_simpletype = @local_complextype = nil\n    @constraint = nil\n    @maxoccurs = '1'\n    @minoccurs = '1'\n    @nillable = nil\n    @ref = nil\n    @refelement = nil\n  end\n\n  def refelement\n    @refelement ||= (@ref ? root.collect_elements[@ref] : nil)\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def elementformdefault\n    parent.elementformdefault\n  end\n\n  def elementform\n    self.form.nil? ? parent.elementformdefault : self.form\n  end\n\n  def parse_element(element)\n    case element\n    when SimpleTypeName\n      @local_simpletype = SimpleType.new\n      @local_simpletype\n    when ComplexTypeName\n      @type = nil\n      @local_complextype = ComplexType.new\n      @local_complextype\n    when UniqueName\n      @constraint = Unique.new\n      @constraint\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      # namespace may be nil\n      if directelement? or elementform == 'qualified'\n        @name = XSD::QName.new(targetnamespace, value.source)\n      else\n        @name = XSD::QName.new(nil, value.source)\n      end\n    when FormAttrName\n      @form = value.source\n    when TypeAttrName\n      @type = value\n    when RefAttrName\n      @ref = value\n    when MaxOccursAttrName\n      if parent.is_a?(All)\n\tif value.source != '1'\n\t  raise Parser::AttrConstraintError.new(\n            \"cannot parse #{value} for #{attr}\")\n\tend\n      end\n      @maxoccurs = value.source\n    when MinOccursAttrName\n      if parent.is_a?(All)\n\tunless ['0', '1'].include?(value.source)\n\t  raise Parser::AttrConstraintError.new(\n            \"cannot parse #{value} for #{attr}\")\n\tend\n      end\n      @minoccurs = value.source\n    when NillableAttrName\n      @nillable = (value.source == 'true')\n    else\n      nil\n    end\n  end\n\nprivate\n\n  def directelement?\n    parent.is_a?(Schema)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/enumeration.rb",
    "content": "# WSDL4R - XMLSchema enumeration definition for WSDL.\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Enumeration < Info\n  def initialize\n    super\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when ValueAttrName\n      parent.enumeration << value.source\n      value.source\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/import.rb",
    "content": "# WSDL4R - XMLSchema import definition.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/xmlSchema/importer'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Import < Info\n  attr_reader :namespace\n  attr_reader :schemalocation\n  attr_reader :content\n\n  def initialize\n    super\n    @namespace = nil\n    @schemalocation = nil\n    @content = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NamespaceAttrName\n      @namespace = value.source\n    when SchemaLocationAttrName\n      @schemalocation = URI.parse(value.source)\n      if @schemalocation.relative? and !parent.location.nil? and\n          !parent.location.relative?\n        @schemalocation = parent.location + @schemalocation\n      end\n      if root.importedschema.key?(@schemalocation)\n        @content = root.importedschema[@schemalocation]\n      else\n        root.importedschema[@schemalocation] = nil      # placeholder\n        @content = import(@schemalocation)\n        root.importedschema[@schemalocation] = @content\n      end\n      @schemalocation\n    else\n      nil\n    end\n  end\n\nprivate\n\n  def import(location)\n    Importer.import(location, root)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/importer.rb",
    "content": "# WSDL4R - XSD importer library.\n# Copyright (C) 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'soap/httpconfigloader'\nrequire 'wsdl/xmlSchema/parser'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Importer\n  def self.import(location, originalroot = nil)\n    new.import(location, originalroot)\n  end\n\n  def initialize\n    @web_client = nil\n  end\n\n  def import(location, originalroot = nil)\n    unless location.is_a?(URI)\n      location = URI.parse(location)\n    end\n    content = parse(fetch(location), location, originalroot)\n    content.location = location\n    content\n  end\n\nprivate\n\n  def parse(content, location, originalroot)\n    opt = {\n      :location => location,\n      :originalroot => originalroot\n    }\n    WSDL::XMLSchema::Parser.new(opt).parse(content)\n  end\n\n  def fetch(location)\n    warn(\"importing: #{location}\") if $DEBUG\n    content = nil\n    if location.scheme == 'file' or\n        (location.relative? and FileTest.exist?(location.path))\n      content = File.open(location.path).read\n    elsif location.scheme and location.scheme.size == 1 and\n        FileTest.exist?(location.to_s)\n      # ToDo: remove this ugly workaround for a path with drive letter\n      # (D://foo/bar)\n      content = File.open(location.to_s).read\n    else\n      client = web_client.new(nil, \"WSDL4R\")\n      client.proxy = ::SOAP::Env::HTTP_PROXY\n      client.no_proxy = ::SOAP::Env::NO_PROXY\n      if opt = ::SOAP::Property.loadproperty(::SOAP::PropertyName)\n        ::SOAP::HTTPConfigLoader.set_options(client,\n          opt[\"client.protocol.http\"])\n      end\n      content = client.get_content(location)\n    end\n    content\n  end\n\n  def web_client\n    @web_client ||= begin\n\trequire 'http-access2'\n\tif HTTPAccess2::VERSION < \"2.0\"\n\t  raise LoadError.new(\"http-access/2.0 or later is required.\")\n\tend\n\tHTTPAccess2::Client\n      rescue LoadError\n\twarn(\"Loading http-access2 failed.  Net/http is used.\") if $DEBUG\n\trequire 'soap/netHttpClient'\n\t::SOAP::NetHttpClient\n      end\n    @web_client\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/include.rb",
    "content": "# WSDL4R - XMLSchema include definition.\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'wsdl/xmlSchema/importer'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Include < Info\n  attr_reader :schemalocation\n  attr_reader :content\n\n  def initialize\n    super\n    @schemalocation = nil\n    @content = nil\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when SchemaLocationAttrName\n      @schemalocation = URI.parse(value.source)\n      if @schemalocation.relative?\n        @schemalocation = parent.location + @schemalocation\n      end\n      @content = import(@schemalocation)\n      @schemalocation\n    else\n      nil\n    end\n  end\n\nprivate\n\n  def import(location)\n    Importer.import(location)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/length.rb",
    "content": "# WSDL4R - XMLSchema length definition for WSDL.\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Length < Info\n  def initialize\n    super\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when ValueAttrName\n      value.source\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/parser.rb",
    "content": "# WSDL4R - WSDL XML Instance parser library.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'xsd/ns'\nrequire 'xsd/charset'\nrequire 'xsd/datatypes'\nrequire 'xsd/xmlparser'\nrequire 'wsdl/xmlSchema/data'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Parser\n  include XSD\n\n  class ParseError < Error; end\n  class FormatDecodeError < ParseError; end\n  class UnknownElementError < FormatDecodeError; end\n  class UnknownAttributeError < FormatDecodeError; end\n  class UnexpectedElementError < FormatDecodeError; end\n  class ElementConstraintError < FormatDecodeError; end\n  class AttributeConstraintError < FormatDecodeError; end\n\nprivate\n\n  class ParseFrame\n    attr_reader :ns\n    attr_reader :name\n    attr_accessor :node\n\n  private\n\n    def initialize(ns, name, node)\n      @ns = ns\n      @name = name\n      @node = node\n    end\n  end\n\npublic\n\n  def initialize(opt = {})\n    @parser = XSD::XMLParser.create_parser(self, opt)\n    @parsestack = nil\n    @lastnode = nil\n    @ignored = {}\n    @location = opt[:location]\n    @originalroot = opt[:originalroot]\n  end\n\n  def parse(string_or_readable)\n    @parsestack = []\n    @lastnode = nil\n    @textbuf = ''\n    @parser.do_parse(string_or_readable)\n    @lastnode\n  end\n\n  def charset\n    @parser.charset\n  end\n\n  def start_element(name, attrs)\n    lastframe = @parsestack.last\n    ns = parent = nil\n    if lastframe\n      ns = lastframe.ns.clone_ns\n      parent = lastframe.node\n    else\n      ns = XSD::NS.new\n      parent = nil\n    end\n    attrs = XSD::XMLParser.filter_ns(ns, attrs)\n    node = decode_tag(ns, name, attrs, parent)\n    @parsestack << ParseFrame.new(ns, name, node)\n  end\n\n  def characters(text)\n    lastframe = @parsestack.last\n    if lastframe\n      # Need not to be cloned because character does not have attr.\n      ns = lastframe.ns\n      decode_text(ns, text)\n    else\n      p text if $DEBUG\n    end\n  end\n\n  def end_element(name)\n    lastframe = @parsestack.pop\n    unless name == lastframe.name\n      raise UnexpectedElementError.new(\"closing element name '#{name}' does not match with opening element '#{lastframe.name}'\")\n    end\n    decode_tag_end(lastframe.ns, lastframe.node)\n    @lastnode = lastframe.node\n  end\n\nprivate\n\n  def decode_tag(ns, name, attrs, parent)\n    o = nil\n    elename = ns.parse(name)\n    if !parent\n      if elename == SchemaName\n\to = Schema.parse_element(elename)\n        o.location = @location\n      else\n\traise UnknownElementError.new(\"unknown element: #{elename}\")\n      end\n      o.root = @originalroot if @originalroot   # o.root = o otherwise\n    else\n      if elename == AnnotationName\n        # only the first annotation element is allowed for each element.\n        o = Annotation.new\n      else\n        o = parent.parse_element(elename)\n      end\n      unless o\n        unless @ignored.key?(elename)\n          warn(\"ignored element: #{elename} of #{parent.class}\")\n          @ignored[elename] = elename\n        end\n\to = Documentation.new\t# which accepts any element.\n      end\n      # node could be a pseudo element.  pseudo element has its own parent.\n      o.root = parent.root\n      o.parent = parent if o.parent.nil?\n    end\n    attrs.each do |key, value|\n      attr_ele = ns.parse(key, true)\n      value_ele = ns.parse(value, true)\n      value_ele.source = value  # for recovery; value may not be a QName\n      if attr_ele == IdAttrName\n\to.id = value_ele\n      else\n        unless o.parse_attr(attr_ele, value_ele)\n          unless @ignored.key?(attr_ele)\n            warn(\"ignored attr: #{attr_ele}\")\n            @ignored[attr_ele] = attr_ele\n          end\n        end\n      end\n    end\n    o\n  end\n\n  def decode_tag_end(ns, node)\n    node.parse_epilogue\n  end\n\n  def decode_text(ns, text)\n    @textbuf << text\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/pattern.rb",
    "content": "# WSDL4R - XMLSchema pattern definition for WSDL.\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Pattern < Info\n  def initialize\n    super\n  end\n\n  def parse_element(element)\n    nil\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when ValueAttrName\n      parent.pattern = /\\A#{value.source}\\z/n\n      value.source\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/schema.rb",
    "content": "# WSDL4R - XMLSchema schema definition for WSDL.\n# Copyright (C) 2002, 2003-2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Schema < Info\n  attr_reader :targetnamespace\t# required\n  attr_reader :complextypes\n  attr_reader :simpletypes\n  attr_reader :elements\n  attr_reader :attributes\n  attr_reader :imports\n  attr_accessor :attributeformdefault\n  attr_accessor :elementformdefault\n\n  attr_reader :importedschema\n\n  def initialize\n    super\n    @targetnamespace = nil\n    @complextypes = XSD::NamedElements.new\n    @simpletypes = XSD::NamedElements.new\n    @elements = XSD::NamedElements.new\n    @attributes = XSD::NamedElements.new\n    @imports = []\n    @attributeformdefault = \"unqualified\"\n    @elementformdefault = \"unqualified\"\n    @importedschema = {}\n    @location = nil\n    @root = self\n  end\n\n  def location\n    @location || (root.nil? ? nil : root.location)\n  end\n\n  def location=(location)\n    @location = location\n  end\n\n  def parse_element(element)\n    case element\n    when ImportName\n      o = Import.new\n      @imports << o\n      o\n    when IncludeName\n      o = Include.new\n      @imports << o\n      o\n    when ComplexTypeName\n      o = ComplexType.new\n      @complextypes << o\n      o\n    when SimpleTypeName\n      o = SimpleType.new\n      @simpletypes << o\n      o\n    when ElementName\n      o = Element.new\n      @elements << o\n      o\n    when AttributeName\n      o = Attribute.new\n      @attributes << o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when TargetNamespaceAttrName\n      @targetnamespace = value.source\n    when AttributeFormDefaultAttrName\n      @attributeformdefault = value.source\n    when ElementFormDefaultAttrName\n      @elementformdefault = value.source\n    else\n      nil\n    end\n  end\n\n  def collect_attributes\n    result = XSD::NamedElements.new\n    result.concat(@attributes)\n    @imports.each do |import|\n      result.concat(import.content.collect_attributes) if import.content\n    end\n    result\n  end\n\n  def collect_elements\n    result = XSD::NamedElements.new\n    result.concat(@elements)\n    @imports.each do |import|\n      result.concat(import.content.collect_elements) if import.content\n    end\n    result\n  end\n\n  def collect_complextypes\n    result = XSD::NamedElements.new\n    result.concat(@complextypes)\n    @imports.each do |import|\n      result.concat(import.content.collect_complextypes) if import.content\n    end\n    result\n  end\n\n  def collect_simpletypes\n    result = XSD::NamedElements.new\n    result.concat(@simpletypes)\n    @imports.each do |import|\n      result.concat(import.content.collect_simpletypes) if import.content\n    end\n    result\n  end\n\n  def self.parse_element(element)\n    if element == SchemaName\n      Schema.new\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/sequence.rb",
    "content": "# WSDL4R - XMLSchema complexType definition for WSDL.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Sequence < Info\n  attr_reader :minoccurs\n  attr_reader :maxoccurs\n  attr_reader :elements\n\n  def initialize\n    super()\n    @minoccurs = '1'\n    @maxoccurs = '1'\n    @elements = []\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def elementformdefault\n    parent.elementformdefault\n  end\n\n  def <<(element)\n    @elements << element\n  end\n\n  def parse_element(element)\n    case element\n    when AnyName\n      o = Any.new\n      @elements << o\n      o\n    when ElementName\n      o = Element.new\n      @elements << o\n      o\n    else\n      nil\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when MaxOccursAttrName\n      @maxoccurs = value.source\n    when MinOccursAttrName\n      @minoccurs = value.source\n    else\n      nil\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/simpleContent.rb",
    "content": "# WSDL4R - XMLSchema simpleContent definition for WSDL.\n# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass SimpleContent < Info\n  attr_reader :restriction\n  attr_reader :extension\n\n  def check_lexical_format(value)\n    check(value)\n  end\n\n  def initialize\n    super\n    @restriction = nil\n    @extension = nil\n  end\n\n  def base\n    content.base\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    case element\n    when RestrictionName\n      @restriction = SimpleRestriction.new\n      @restriction\n    when ExtensionName\n      @extension = SimpleExtension.new\n      @extension\n    end\n  end\n\nprivate\n\n  def content\n    @restriction || @extension\n  end\n\n  def check(value)\n    unless content.valid?(value)\n      raise XSD::ValueSpaceError.new(\"#{@name}: cannot accept '#{value}'\")\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/simpleExtension.rb",
    "content": "# WSDL4R - XMLSchema simpleType extension definition for WSDL.\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass SimpleExtension < Info\n  attr_reader :base\n  attr_reader :attributes\n\n  def initialize\n    super\n    @base = nil\n    @attributes = XSD::NamedElements.new\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n  \n  def valid?(value)\n    true\n  end\n\n  def parse_element(element)\n    case element\n    when AttributeName\n      o = Attribute.new\n      @attributes << o\n      o\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when BaseAttrName\n      @base = value\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/simpleRestriction.rb",
    "content": "# WSDL4R - XMLSchema simpleContent restriction definition for WSDL.\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass SimpleRestriction < Info\n  attr_reader :base\n  attr_reader :enumeration\n  attr_accessor :length\n  attr_accessor :pattern\n\n  def initialize\n    super\n    @base = nil\n    @enumeration = []   # NamedElements?\n    @length = nil\n    @pattern = nil\n  end\n  \n  def valid?(value)\n    return false unless check_restriction(value)\n    return false unless check_length(value)\n    return false unless check_pattern(value)\n    true\n  end\n\n  def parse_element(element)\n    case element\n    when EnumerationName\n      Enumeration.new   # just a parsing handler\n    when LengthName\n      Length.new   # just a parsing handler\n    when PatternName\n      Pattern.new   # just a parsing handler\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when BaseAttrName\n      @base = value\n    end\n  end\n\nprivate\n\n  def check_restriction(value)\n    @enumeration.empty? or @enumeration.include?(value)\n  end\n\n  def check_length(value)\n    @length.nil? or value.size == @length\n  end\n\n  def check_pattern(value)\n    @pattern.nil? or @pattern =~ value\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/simpleType.rb",
    "content": "# WSDL4R - XMLSchema simpleType definition for WSDL.\n# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\nrequire 'xsd/namedelements'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass SimpleType < Info\n  attr_accessor :name\n  attr_reader :restriction\n\n  def check_lexical_format(value)\n    if @restriction\n      check_restriction(value)\n    else\n      raise ArgumentError.new(\"incomplete simpleType\")\n    end\n  end\n\n  def base\n    if @restriction\n      @restriction.base\n    else\n      raise ArgumentError.new(\"incomplete simpleType\")\n    end\n  end\n\n  def initialize(name = nil)\n    super()\n    @name = name\n    @restriction = nil\n  end\n\n  def targetnamespace\n    parent.targetnamespace\n  end\n\n  def parse_element(element)\n    case element\n    when RestrictionName\n      @restriction = SimpleRestriction.new\n      @restriction\n    end\n  end\n\n  def parse_attr(attr, value)\n    case attr\n    when NameAttrName\n      @name = XSD::QName.new(targetnamespace, value.source)\n    end\n  end\n\nprivate\n\n  def check_restriction(value)\n    unless @restriction.valid?(value)\n      raise XSD::ValueSpaceError.new(\"#{@name}: cannot accept '#{value}'\")\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/unique.rb",
    "content": "# WSDL4R - XMLSchema unique element.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'wsdl/info'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass Unique < Info\n  def initialize\n    super\n  end\n\n  def parse_element(element)\n    # Accepts any element.\n    self\n  end\n\n  def parse_attr(attr, value)\n    # Accepts any attribute.\n    true\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/wsdl/xmlSchema/xsd2ruby.rb",
    "content": "# XSD4R - XSD to ruby mapping library.\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\nrequire 'wsdl/xmlSchema/importer'\nrequire 'wsdl/soap/classDefCreator'\n\n\nmodule WSDL\nmodule XMLSchema\n\n\nclass XSD2Ruby\n  attr_accessor :location\n  attr_reader :opt\n  attr_accessor :logger\n  attr_accessor :basedir\n\n  def run\n    unless @location\n      raise RuntimeError, \"XML Schema location not given\"\n    end\n    @xsd = import(@location)\n    @name = create_classname(@xsd)\n    create_file\n  end\n\nprivate\n\n  def initialize\n    @location = nil\n    @opt = {}\n    @logger = Logger.new(STDERR)\n    @basedir = nil\n    @xsd = nil\n    @name = nil\n  end\n\n  def create_file\n    create_classdef\n  end\n\n  def create_classdef\n    @logger.info { \"Creating class definition.\" }\n    @classdef_filename = @name + '.rb'\n    check_file(@classdef_filename) or return\n    write_file(@classdef_filename) do |f|\n      f << WSDL::SOAP::ClassDefCreator.new(@xsd).dump\n    end\n  end\n\n  def write_file(filename)\n    if @basedir\n      filename = File.join(basedir, filename)\n    end\n    File.open(filename, \"w\") do |f|\n      yield f\n    end\n  end\n\n  def check_file(filename)\n    if @basedir\n      filename = File.join(basedir, filename)\n    end\n    if FileTest.exist?(filename)\n      if @opt.key?('force')\n\t@logger.warn {\n\t  \"File '#{filename}' exists but overrides it.\"\n\t}\n\ttrue\n      else\n\t@logger.warn {\n\t  \"File '#{filename}' exists.  #{$0} did not override it.\"\n\t}\n\tfalse\n      end\n    else\n      @logger.info { \"Creates file '#{filename}'.\" }\n      true\n    end\n  end\n\n  def create_classname(xsd)\n    name = nil\n    if xsd.targetnamespace\n      name = xsd.targetnamespace.scan(/[a-zA-Z0-9]+$/)[0]\n    end\n    if name.nil?\n      'default'\n    else\n      XSD::CodeGen::GenSupport.safevarname(name)\n    end\n  end\n\n  def import(location)\n    WSDL::XMLSchema::Importer.import(location)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xmlrpc/.document",
    "content": "README.rdoc\n"
  },
  {
    "path": "lib/xmlrpc/README.txt",
    "content": "= XMLRPC for Ruby, Standard Library Documentation\n\n== Overview\n\nXMLRPC is a lightweight protocol that enables remote procedure calls over\nHTTP.  It is defined at http://www.xmlrpc.com.\n\nXMLRPC allows you to create simple distributed computing solutions that span\ncomputer languages.  Its distinctive feature is its simplicity compared to\nother approaches like SOAP and CORBA.\n\nThe Ruby standard library package 'xmlrpc' enables you to create a server that\nimplements remote procedures and a client that calls them.  Very little code\nis required to achieve either of these.\n\n== Example\n\nTry the following code.  It calls a standard demonstration remote procedure.\n\n  require 'xmlrpc/client'\n  require 'pp'\n\n  server = XMLRPC::Client.new2(\"http://xmlrpc-c.sourceforge.net/api/sample.php\")\n  result = server.call(\"sample.sumAndDifference\", 5, 3)\n  pp result\n\n== Documentation\n\nSee http://www.ntecs.de/projects/xmlrpc4r.  There is plenty of detail there to\nuse the client and implement a server.\n\n"
  },
  {
    "path": "lib/xmlrpc/base64.rb",
    "content": "=begin\n= xmlrpc/base64.rb\nCopyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n\nReleased under the same term of license as Ruby.\n\n= Classes\n* ((<XMLRPC::Base64>))\n\n= XMLRPC::Base64\n== Description\nThis class is necessary for (('xmlrpc4r')) to determine that a string should \nbe transmitted base64-encoded and not as a raw-string. \nYou can use (({XMLRPC::Base64})) on the client and server-side as a \nparameter and/or return-value.\n\n== Class Methods\n--- XMLRPC::Base64.new( str, state = :dec )\n    Creates a new (({XMLRPC::Base64})) instance with string ((|str|)) as the\n    internal string. When ((|state|)) is (({:dec})) it assumes that the \n    string ((|str|)) is not in base64 format (perhaps already decoded), \n    otherwise if ((|state|)) is (({:enc})) it decodes ((|str|)) \n    and stores it as the internal string.\n    \n--- XMLRPC::Base64.decode( str )\n    Decodes string ((|str|)) with base64 and returns that value.\n\n--- XMLRPC::Base64.encode( str )\n    Encodes string ((|str|)) with base64 and returns that value.\n\n== Instance Methods\n--- XMLRPC::Base64#decoded\n    Returns the internal string decoded.\n\n--- XMLRPC::Base64#encoded\n    Returns the internal string encoded with base64.\n\n=end\n\nmodule XMLRPC\n\nclass Base64\n  \n  def initialize(str, state = :dec)\n    case state\n    when :enc\n      @str = Base64.decode(str)\n    when :dec\n      @str = str\n    else\n      raise ArgumentError, \"wrong argument; either :enc or :dec\"\n    end\n  end\n  \n  def decoded\n    @str  \n  end\n  \n  def encoded\n    Base64.encode(@str)\n  end\n\n\n  def Base64.decode(str)\n    str.gsub(/\\s+/, \"\").unpack(\"m\")[0]\n  end\n\n  def Base64.encode(str)\n    [str].pack(\"m\")\n  end\n\nend\n\n\nend # module XMLRPC\n\n\n=begin\n= History\n    $Id$\n=end\n"
  },
  {
    "path": "lib/xmlrpc/client.rb",
    "content": "=begin\n= xmlrpc/client.rb\nCopyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n\nReleased under the same term of license as Ruby.\n\n= Classes\n* ((<XMLRPC::Client>))\n* ((<XMLRPC::Client::Proxy>))\n\n\n= XMLRPC::Client\n== Synopsis\n    require \"xmlrpc/client\"\n\n    server = XMLRPC::Client.new(\"www.ruby-lang.org\", \"/RPC2\", 80)\n    begin\n      param = server.call(\"michael.add\", 4, 5)\n      puts \"4 + 5 = #{param}\"\n    rescue XMLRPC::FaultException => e\n      puts \"Error:\"\n      puts e.faultCode\n      puts e.faultString\n    end\n\nor\n\n    require \"xmlrpc/client\"\n  \n    server = XMLRPC::Client.new(\"www.ruby-lang.org\", \"/RPC2\", 80)\n    ok, param = server.call2(\"michael.add\", 4, 5)\n    if ok then\n      puts \"4 + 5 = #{param}\"\n    else\n      puts \"Error:\"\n      puts param.faultCode\n      puts param.faultString\n    end\n\n== Description\nClass (({XMLRPC::Client})) provides remote procedure calls to a XML-RPC server.\nAfter setting the connection-parameters with ((<XMLRPC::Client.new>)) which\ncreates a new (({XMLRPC::Client})) instance, you can execute a remote procedure \nby sending the ((<call|XMLRPC::Client#call>)) or ((<call2|XMLRPC::Client#call2>))\nmessage to this new instance. The given parameters indicate which method to \ncall on the remote-side and of course the parameters for the remote procedure.\n\n== Class Methods\n--- XMLRPC::Client.new( host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, user=nil, password=nil, use_ssl=false, timeout =nil)\n    Creates an object which represents the remote XML-RPC server on the \n    given host ((|host|)). If the server is CGI-based, ((|path|)) is the\n    path to the CGI-script, which will be called, otherwise (in the\n    case of a standalone server) ((|path|)) should be (({\"/RPC2\"})).\n    ((|port|)) is the port on which the XML-RPC server listens.\n    If ((|proxy_host|)) is given, then a proxy server listening at\n    ((|proxy_host|)) is used. ((|proxy_port|)) is the port of the\n    proxy server.\n\n    Default values for ((|host|)), ((|path|)) and ((|port|)) are 'localhost', '/RPC2' and\n    '80' respectively using SSL '443'.\n\n    If ((|user|)) and ((|password|)) are given, each time a request is send, \n    a Authorization header is send. Currently only Basic Authentification is \n    implemented no Digest.\n\n    If ((|use_ssl|)) is set to (({true})), comunication over SSL is enabled.\n    Note, that you need the SSL package from RAA installed.\n\n    Parameter ((|timeout|)) is the time to wait for a XML-RPC response, defaults to 30.\n\n--- XMLRPC::Client.new2( uri, proxy=nil, timeout=nil)\n--- XMLRPC::Client.new_from_uri( uri, proxy=nil, timeout=nil)\n:   uri\n    URI specifying protocol (http or https), host, port, path, user and password.\n    Example: https://user:password@host:port/path\n\n:   proxy\n    Is of the form \"host:port\".\n \n:   timeout\n    Defaults to 30. \n\n--- XMLRPC::Client.new3( hash={} )\n--- XMLRPC::Client.new_from_hash( hash={} )\n    Parameter ((|hash|)) has following case-insensitive keys:\n    * host\n    * path\n    * port\n    * proxy_host\n    * proxy_port\n    * user\n    * password\n    * use_ssl\n    * timeout\n\n    Calls ((<XMLRPC::Client.new>)) with the corresponding values.\n\n== Instance Methods\n--- XMLRPC::Client#call( method, *args )\n    Invokes the method named ((|method|)) with the parameters given by \n    ((|args|)) on the XML-RPC server.\n    The parameter ((|method|)) is converted into a (({String})) and should \n    be a valid XML-RPC method-name.  \n    Each parameter of ((|args|)) must be of one of the following types,\n    where (({Hash})), (({Struct})) and (({Array})) can contain any of these listed ((:types:)):\n    * (({Fixnum})), (({Bignum}))\n    * (({TrueClass})), (({FalseClass})) ((({true})), (({false})))\n    * (({String})), (({Symbol}))\n    * (({Float}))\n    * (({Hash})), (({Struct}))\n    * (({Array}))\n    * (({Date})), (({Time})), (({XMLRPC::DateTime}))\n    * (({XMLRPC::Base64})) \n    * A Ruby object which class includes XMLRPC::Marshallable (only if Config::ENABLE_MARSHALLABLE is (({true}))). \n      That object is converted into a hash, with one additional key/value pair \"___class___\" which contains the class name\n      for restoring later that object.\n    \n    The method returns the return-value from the RPC \n    ((-stands for Remote Procedure Call-)). \n    The type of the return-value is one of the above shown,\n    only that a (({Bignum})) is only allowed when it fits in 32-bit and\n    that a XML-RPC (('dateTime.iso8601')) type is always returned as\n    a ((<(({XMLRPC::DateTime}))|URL:datetime.html>)) object and \n    a (({Struct})) is never returned, only a (({Hash})), the same for a (({Symbol})), where\n    always a (({String})) is returned. \n    A (({XMLRPC::Base64})) is returned as a (({String})) from xmlrpc4r version 1.6.1 on.\n    \n    If the remote procedure returned a fault-structure, then a \n    (({XMLRPC::FaultException})) exception is raised, which has two accessor-methods\n    (({faultCode})) and (({faultString})) of type (({Integer})) and (({String})).\n\n--- XMLRPC::Client#call2( method, *args )\n    The difference between this method and ((<call|XMLRPC::Client#call>)) is, that\n    this method do ((*not*)) raise a (({XMLRPC::FaultException})) exception.\n    The method returns an array of two values. The first value indicates if \n    the second value is a return-value ((({true}))) or an object of type\n    (({XMLRPC::FaultException})). \n    Both are explained in ((<call|XMLRPC::Client#call>)).\n\n    Simple to remember: The \"2\" in \"call2\" denotes the number of values it returns.\n\n--- XMLRPC::Client#multicall( *methods )\n    You can use this method to execute several methods on a XMLRPC server which supports\n    the multi-call extension.\n    Example:\n\n      s.multicall(\n        ['michael.add', 3, 4],\n        ['michael.sub', 4, 5]\n      )\n      # => [7, -1]\n\n--- XMLRPC::Client#multicall2( *methods )\n    Same as ((<XMLRPC::Client#multicall>)), but returns like ((<XMLRPC::Client#call2>)) two parameters \n    instead of raising an (({XMLRPC::FaultException})).\n\n--- XMLRPC::Client#proxy( prefix, *args )\n    Returns an object of class (({XMLRPC::Client::Proxy})), initialized with\n    ((|prefix|)) and ((|args|)). A proxy object returned by this method behaves\n    like ((<XMLRPC::Client#call>)), i.e. a call on that object will raise a\n    (({XMLRPC::FaultException})) when a fault-structure is returned by that call. \n\n--- XMLRPC::Client#proxy2( prefix, *args )\n    Almost the same like ((<XMLRPC::Client#proxy>)) only that a call on the returned\n    (({XMLRPC::Client::Proxy})) object behaves like ((<XMLRPC::Client#call2>)), i.e.\n    a call on that object will return two parameters. \n\n\n\n\n--- XMLRPC::Client#call_async(...)\n--- XMLRPC::Client#call2_async(...)\n--- XMLRPC::Client#multicall_async(...)\n--- XMLRPC::Client#multicall2_async(...)\n--- XMLRPC::Client#proxy_async(...)\n--- XMLRPC::Client#proxy2_async(...)\n    In contrast to corresponding methods without \"_async\", these can be\n    called concurrently and use for each request a new connection, where the \n    non-asynchronous counterparts use connection-alive (one connection for all requests)\n    if possible. \n\n    Note, that you have to use Threads to call these methods concurrently. \n    The following example calls two methods concurrently:\n    \n      Thread.new {\n        p client.call_async(\"michael.add\", 4, 5)\n      }\n \n      Thread.new {\n        p client.call_async(\"michael.div\", 7, 9)\n      }\n \n\n--- XMLRPC::Client#timeout\n--- XMLRPC::Client#user\n--- XMLRPC::Client#password\n    Return the corresponding attributes.\n\n--- XMLRPC::Client#timeout= (new_timeout)\n--- XMLRPC::Client#user= (new_user)\n--- XMLRPC::Client#password= (new_password)\n    Set the corresponding attributes.\n    \n\n--- XMLRPC::Client#set_writer( writer )\n    Sets the XML writer to use for generating XML output.\n    Should be an instance of a class from module (({XMLRPC::XMLWriter})).\n    If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. \n\n--- XMLRPC::Client#set_parser( parser )\n    Sets the XML parser to use for parsing XML documents.\n    Should be an instance of a class from module (({XMLRPC::XMLParser})).\n    If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used.\n\n--- XMLRPC::Client#cookie\n--- XMLRPC::Client#cookie= (cookieString)\n    Get and set the HTTP Cookie header.\n\n--- XMLRPC::Client#http_header_extra= (additionalHeaders)\n    Set extra HTTP headers that are included in the request.\n\n--- XMLRPC::Client#http_header_extra\n    Access the via ((<XMLRPC::Client#http_header_extra=>)) assigned header. \n\n--- XMLRPC::Client#http_last_response\n    Returns the (({Net::HTTPResponse})) object of the last RPC.\n\n= XMLRPC::Client::Proxy\n== Synopsis\n    require \"xmlrpc/client\"\n\n    server = XMLRPC::Client.new(\"www.ruby-lang.org\", \"/RPC2\", 80)\n\n    michael  = server.proxy(\"michael\")\n    michael2 = server.proxy(\"michael\", 4)\n\n    # both calls should return the same value '9'.\n    p michael.add(4,5)\n    p michael2.add(5)\n\n== Description\nClass (({XMLRPC::Client::Proxy})) makes XML-RPC calls look nicer!\nYou can call any method onto objects of that class - the object handles \n(({method_missing})) and will forward the method call to a XML-RPC server.\nDon't use this class directly, but use instead method ((<XMLRPC::Client#proxy>)) or\n((<XMLRPC::Client#proxy2>)).\n\n== Class Methods\n--- XMLRPC::Client::Proxy.new( server, prefix, args=[], meth=:call, delim=\".\" ) \n    Creates an object which provides (({method_missing})).\n\n    ((|server|)) must be of type (({XMLRPC::Client})), which is the XML-RPC server to be used\n    for a XML-RPC call. ((|prefix|)) and ((|delim|)) will be prepended to the methodname\n    called onto this object. \n\n    Parameter ((|meth|)) is the method (call, call2, call_async, call2_async) to use for\n    a RPC.\n\n    ((|args|)) are arguments which are automatically given\n    to every XML-RPC call before the arguments provides through (({method_missing})).\n    \n== Instance Methods\nEvery method call is forwarded to the XML-RPC server defined in ((<new|XMLRPC::Client::Proxy#new>)).\n    \nNote: Inherited methods from class (({Object})) cannot be used as XML-RPC names, because they get around\n(({method_missing})). \n          \n\n\n= History\n    $Id$\n\n=end\n\n\n\nrequire \"xmlrpc/parser\"\nrequire \"xmlrpc/create\"\nrequire \"xmlrpc/config\"\nrequire \"xmlrpc/utils\"     # ParserWriterChooseMixin\nrequire \"net/http\"\n\nmodule XMLRPC\n\n  class Client\n   \n    USER_AGENT = \"XMLRPC::Client (Ruby #{RUBY_VERSION})\"\n\n    include ParserWriterChooseMixin\n    include ParseContentType\n\n\n    # Constructors -------------------------------------------------------------------\n\n    def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, \n                   user=nil, password=nil, use_ssl=nil, timeout=nil)\n\n      @http_header_extra = nil\n      @http_last_response = nil \n      @cookie = nil\n\n      @host       = host || \"localhost\"\n      @path       = path || \"/RPC2\"\n      @proxy_host = proxy_host\n      @proxy_port = proxy_port\n      @proxy_host ||= 'localhost' if @proxy_port != nil\n      @proxy_port ||= 8080 if @proxy_host != nil\n      @use_ssl    = use_ssl || false\n      @timeout    = timeout || 30\n\n      if use_ssl\n        require \"net/https\"\n        @port = port || 443\n      else\n        @port = port || 80\n      end\n\n      @user, @password = user, password\n\n      set_auth\n\n      # convert ports to integers\n      @port = @port.to_i if @port != nil\n      @proxy_port = @proxy_port.to_i if @proxy_port != nil\n\n      # HTTP object for synchronous calls\n      Net::HTTP.version_1_2\n      @http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) \n      @http.use_ssl = @use_ssl if @use_ssl\n      @http.read_timeout = @timeout\n      @http.open_timeout = @timeout\n\n      @parser = nil\n      @create = nil\n    end\n\n\n    class << self\n\n    def new2(uri, proxy=nil, timeout=nil)\n      if match = /^([^:]+):\\/\\/(([^@]+)@)?([^\\/]+)(\\/.*)?$/.match(uri)\n        proto = match[1]\n        user, passwd = (match[3] || \"\").split(\":\")\n        host, port = match[4].split(\":\") \n        path = match[5]\n\n        if proto != \"http\" and proto != \"https\"\n          raise \"Wrong protocol specified. Only http or https allowed!\"\n        end\n\n      else\n        raise \"Wrong URI as parameter!\"\n      end\n \n      proxy_host, proxy_port = (proxy || \"\").split(\":\")\n\n      self.new(host, path, port, proxy_host, proxy_port, user, passwd, (proto == \"https\"), timeout)\n    end\n\n    alias new_from_uri new2\n\n    def new3(hash={})\n\n      # convert all keys into lowercase strings\n      h = {}\n      hash.each { |k,v| h[k.to_s.downcase] = v }\n\n      self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'], h['user'], h['password'],\n               h['use_ssl'], h['timeout'])\n    end\n\n    alias new_from_hash new3\n\n    end\n\n\n    # Attribute Accessors -------------------------------------------------------------------\n\n    # add additional HTTP headers to the request\n    attr_accessor :http_header_extra\n\n    # makes last HTTP response accessible\n    attr_reader :http_last_response\n\n    # Cookie support\n    attr_accessor :cookie\n    \n\n    attr_reader :timeout, :user, :password\n\n    def timeout=(new_timeout)\n      @timeout = new_timeout\n      @http.read_timeout = @timeout\n      @http.open_timeout = @timeout\n    end\n\n    def user=(new_user)\n      @user = new_user\n      set_auth\n    end\n\n    def password=(new_password)\n      @password = new_password\n      set_auth\n    end\n\n    # Call methods --------------------------------------------------------------\n\n    def call(method, *args)\n      ok, param = call2(method, *args) \n      if ok\n        param\n      else\n        raise param\n      end\n    end \n\n    def call2(method, *args)\n      request = create().methodCall(method, *args)\n      data = do_rpc(request, false)\n      parser().parseMethodResponse(data)\n    end\n\n    def call_async(method, *args)\n      ok, param = call2_async(method, *args) \n      if ok\n        param\n      else\n        raise param\n      end\n    end \n\n    def call2_async(method, *args)\n      request = create().methodCall(method, *args)\n      data = do_rpc(request, true)\n      parser().parseMethodResponse(data)\n    end\n\n\n    # Multicall methods --------------------------------------------------------------\n\n    def multicall(*methods)\n      ok, params = multicall2(*methods)\n      if ok\n        params\n      else\n        raise params\n      end\n    end\n\n    def multicall2(*methods)\n      gen_multicall(methods, false)\n    end\n\n    def multicall_async(*methods)\n      ok, params = multicall2_async(*methods)\n      if ok\n        params\n      else\n        raise params\n      end\n    end\n\n    def multicall2_async(*methods)\n      gen_multicall(methods, true)\n    end\n\n\n    # Proxy generating methods ------------------------------------------\n    \n    def proxy(prefix=nil, *args)\n      Proxy.new(self, prefix, args, :call)\n    end\n\n    def proxy2(prefix=nil, *args)\n      Proxy.new(self, prefix, args, :call2)\n    end\n\n    def proxy_async(prefix=nil, *args)\n      Proxy.new(self, prefix, args, :call_async)\n    end\n\n    def proxy2_async(prefix=nil, *args)\n      Proxy.new(self, prefix, args, :call2_async)\n    end\n\n\n    private # ----------------------------------------------------------\n\n    def set_auth\n      if @user.nil?\n        @auth = nil\n      else\n        a =  \"#@user\"\n        a << \":#@password\" if @password != nil\n        @auth = (\"Basic \" + [a].pack(\"m\")).chomp\n      end\n    end\n\n    def do_rpc(request, async=false)\n      header = {  \n       \"User-Agent\"     =>  USER_AGENT,\n       \"Content-Type\"   => \"text/xml; charset=utf-8\",\n       \"Content-Length\" => request.size.to_s, \n       \"Connection\"     => (async ? \"close\" : \"keep-alive\")\n      }\n\n      header[\"Cookie\"] = @cookie        if @cookie\n      header.update(@http_header_extra) if @http_header_extra\n\n      if @auth != nil\n        # add authorization header\n        header[\"Authorization\"] = @auth\n      end\n \n      resp = nil\n      @http_last_response = nil\n\n      if async\n        # use a new HTTP object for each call \n        Net::HTTP.version_1_2\n        http = Net::HTTP.new(@host, @port, @proxy_host, @proxy_port) \n        http.use_ssl = @use_ssl if @use_ssl\n        http.read_timeout = @timeout\n        http.open_timeout = @timeout\n        \n        # post request\n        http.start {\n          resp = http.post2(@path, request, header) \n        }\n      else\n        # reuse the HTTP object for each call => connection alive is possible\n        # we must start connection explicitely first time so that http.request\n        # does not assume that we don't want keepalive\n        @http.start if not @http.started?\n        \n        # post request\n        resp = @http.post2(@path, request, header) \n      end\n  \n      @http_last_response = resp\n\n      data = resp.body\n\n      if resp.code == \"401\"\n        # Authorization Required\n        raise \"Authorization failed.\\nHTTP-Error: #{resp.code} #{resp.message}\" \n      elsif resp.code[0,1] != \"2\"\n        raise \"HTTP-Error: #{resp.code} #{resp.message}\" \n      end\n\n      ct = parse_content_type(resp[\"Content-Type\"]).first\n      if ct != \"text/xml\"\n        if ct == \"text/html\"\n          raise \"Wrong content-type (received '#{ct}' but expected 'text/xml'): \\n#{data}\"\n        else\n          raise \"Wrong content-type (received '#{ct}' but expected 'text/xml')\"\n        end\n      end\n\n      expected = resp[\"Content-Length\"] || \"<unknown>\"\n      if data.nil? or data.size == 0 \n        raise \"Wrong size. Was #{data.size}, should be #{expected}\" \n      elsif expected != \"<unknown>\" and expected.to_i != data.size and resp[\"Transfer-Encoding\"].nil?\n        raise \"Wrong size. Was #{data.size}, should be #{expected}\"\n      end\n\n      set_cookies = resp.get_fields(\"Set-Cookie\")\n      if set_cookies and !set_cookies.empty?\n        require 'webrick/cookie'\n        @cookie = set_cookies.collect do |set_cookie|\n          cookie = WEBrick::Cookie.parse_set_cookie(set_cookie)\n          WEBrick::Cookie.new(cookie.name, cookie.value).to_s\n        end.join(\"; \")\n      end\n\n      return data\n    end\n\n    def gen_multicall(methods=[], async=false)\n      meth = :call2\n      meth = :call2_async if async\n\n      ok, params = self.send(meth, \"system.multicall\", \n        methods.collect {|m| {'methodName' => m[0], 'params' => m[1..-1]} }\n      )\n\n      if ok \n        params = params.collect do |param|\n          if param.is_a? Array\n            param[0]\n          elsif param.is_a? Hash\n            XMLRPC::FaultException.new(param[\"faultCode\"], param[\"faultString\"])\n          else\n            raise \"Wrong multicall return value\"\n          end \n        end\n      end\n\n      return ok, params\n    end\n\n\n\n    class Proxy\n\n      def initialize(server, prefix, args=[], meth=:call, delim=\".\")\n\t@server = server\n\t@prefix = prefix ? prefix + delim : \"\"\n\t@args   = args \n        @meth   = meth\n      end\n\n      def method_missing(mid, *args)\n\tpre = @prefix + mid.to_s\n\targ = @args + args\n\t@server.send(@meth, pre, *arg)\n      end\n\n    end # class Proxy\n\n  end # class Client\n\nend # module XMLRPC\n\n"
  },
  {
    "path": "lib/xmlrpc/config.rb",
    "content": "#\n# $Id$\n# Configuration file for XML-RPC for Ruby\n#\n\nmodule XMLRPC\n\n  module Config\n\n    DEFAULT_WRITER = XMLWriter::Simple            # or XMLWriter::XMLParser\n    \n    # available parser:\n    #   * XMLParser::NQXMLTreeParser\n    #   * XMLParser::NQXMLStreamParser\n    #   * XMLParser::XMLTreeParser\n    #   * XMLParser::XMLStreamParser (fastest)\n    #   * XMLParser::REXMLStreamParser\n    #   * XMLParser::XMLScanStreamParser\n    DEFAULT_PARSER = XMLParser::REXMLStreamParser\n\n    # enable <nil/> tag\n    ENABLE_NIL_CREATE    = false\n    ENABLE_NIL_PARSER    = false\n    \n    # allows integers greater than 32-bit if true\n    ENABLE_BIGINT        = false\n\n    # enable marshalling ruby objects which include XMLRPC::Marshallable\n    ENABLE_MARSHALLING   = true \n\n    # enable multiCall extension by default\n    ENABLE_MULTICALL     = false\n    \n    # enable Introspection extension by default\n    ENABLE_INTROSPECTION = false\n\n  end\n\nend\n\n"
  },
  {
    "path": "lib/xmlrpc/create.rb",
    "content": "#\n# Creates XML-RPC call/response documents\n# \n# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n#\n# $Id$\n#\n\nrequire \"date\"\nrequire \"xmlrpc/base64\"\n\nmodule XMLRPC\n\n  module XMLWriter\n\n    class Abstract\n      def ele(name, *children)\n\telement(name, nil, *children)\n      end\n\n      def tag(name, txt)\n\telement(name, nil, text(txt))\n      end\n    end\n\n\n    class Simple < Abstract\n\n      def document_to_str(doc)\n\tdoc\n      end\n\n      def document(*params)\n\tparams.join(\"\")\n      end\n\n      def pi(name, *params)\n\t\"<?#{name} \" + params.join(\" \") + \" ?>\"\n      end\n\n      def element(name, attrs, *children)\n\traise \"attributes not yet implemented\" unless attrs.nil?\n        if children.empty?\n          \"<#{name}/>\" \n        else\n          \"<#{name}>\" + children.join(\"\") + \"</#{name}>\"\n        end\n      end\n\n      def text(txt)\n        cleaned = txt.dup\n        cleaned.gsub!(/&/, '&amp;')\n        cleaned.gsub!(/</, '&lt;')\n        cleaned.gsub!(/>/, '&gt;')\n        cleaned\n      end\n\n    end # class Simple\n\n\n    class XMLParser < Abstract\n\n      def initialize\n\trequire \"xmltreebuilder\"\n      end\n\n      def document_to_str(doc)\n\tdoc.to_s\n      end\n\n      def document(*params)\n\tXML::SimpleTree::Document.new(*params) \n      end\n\n      def pi(name, *params)\n\tXML::SimpleTree::ProcessingInstruction.new(name, *params)\n      end\n\n      def element(name, attrs, *children)\n\tXML::SimpleTree::Element.new(name, attrs, *children)\n      end\n\n      def text(txt)\n\tXML::SimpleTree::Text.new(txt)\n      end\n\n    end # class XMLParser\n\n    Classes = [Simple, XMLParser]\n\n    # yields an instance of each installed XML writer\n    def self.each_installed_writer\n      XMLRPC::XMLWriter::Classes.each do |klass|\n        begin\n          yield klass.new\n        rescue LoadError\n        end\n      end\n    end\n\n  end # module XMLWriter\n\n  class Create\n\n    def initialize(xml_writer = nil)\n      @writer = xml_writer || Config::DEFAULT_WRITER.new\n    end\n\n\n    def methodCall(name, *params)\n      name = name.to_s\n\n      if name !~ /[a-zA-Z0-9_.:\\/]+/\n\traise ArgumentError, \"Wrong XML-RPC method-name\"\n      end\n\n      parameter = params.collect do |param|\n\t@writer.ele(\"param\", conv2value(param))\n      end\n\n      tree = @writer.document(\n\t       @writer.pi(\"xml\", 'version=\"1.0\"'),\n\t       @writer.ele(\"methodCall\",   \n\t\t @writer.tag(\"methodName\", name),\n\t\t @writer.ele(\"params\", *parameter)    \n\t       )\n\t     )\n\n      @writer.document_to_str(tree) + \"\\n\"\n    end\n\n\n\n    #\n    # generates a XML-RPC methodResponse document\n    #\n    # if is_ret == false then the params array must\n    # contain only one element, which is a structure\n    # of a fault return-value.\n    # \n    # if is_ret == true then a normal \n    # return-value of all the given params is created.\n    #\n    def methodResponse(is_ret, *params)\n\n      if is_ret \n\tresp = params.collect do |param|\n\t  @writer.ele(\"param\", conv2value(param))\n\tend\n     \n\tresp = [@writer.ele(\"params\", *resp)]\n      else\n\tif params.size != 1 or params[0] === XMLRPC::FaultException \n\t  raise ArgumentError, \"no valid fault-structure given\"\n\tend\n\tresp = @writer.ele(\"fault\", conv2value(params[0].to_h))\n      end\n\n\t\n      tree = @writer.document(\n\t       @writer.pi(\"xml\", 'version=\"1.0\"'),\n\t       @writer.ele(\"methodResponse\", resp) \n\t     )\n\n      @writer.document_to_str(tree) + \"\\n\"\n    end\n\n\n\n    #####################################\n    private\n    #####################################\n\n    #\n    # converts a Ruby object into\n    # a XML-RPC <value> tag\n    #\n    def conv2value(param)\n\n\tval = case param\n\twhen Fixnum \n\t  @writer.tag(\"i4\", param.to_s)\n\n\twhen Bignum\n          if Config::ENABLE_BIGINT\n            @writer.tag(\"i4\", param.to_s)\n          else\n            if param >= -(2**31) and param <= (2**31-1)\n              @writer.tag(\"i4\", param.to_s)\n            else\n              raise \"Bignum is too big! Must be signed 32-bit integer!\"\n            end\n          end\n\twhen TrueClass, FalseClass\n\t  @writer.tag(\"boolean\", param ? \"1\" : \"0\")\n\n\twhen String \n\t  @writer.tag(\"string\", param)\n\n\twhen Symbol \n\t  @writer.tag(\"string\", param.to_s)\n\n        when NilClass\n          if Config::ENABLE_NIL_CREATE\n            @writer.ele(\"nil\")\n          else\n            raise \"Wrong type NilClass. Not allowed!\"\n          end\n\n\twhen Float\n\t  @writer.tag(\"double\", param.to_s)\n\n\twhen Struct\n\t  h = param.members.collect do |key| \n\t    value = param[key]\n\t    @writer.ele(\"member\", \n\t      @writer.tag(\"name\", key.to_s),\n\t      conv2value(value) \n\t    )\n\t  end\n\n\t  @writer.ele(\"struct\", *h) \n\n\twhen Hash\n\t  # TODO: can a Hash be empty?\n\t  \n\t  h = param.collect do |key, value|\n\t    @writer.ele(\"member\", \n\t      @writer.tag(\"name\", key.to_s),\n\t      conv2value(value) \n\t    )\n\t  end\n\n\t  @writer.ele(\"struct\", *h) \n\n\twhen Array\n\t  # TODO: can an Array be empty?\n\t  a = param.collect {|v| conv2value(v) }\n\t  \n\t  @writer.ele(\"array\", \n\t    @writer.ele(\"data\", *a)\n\t  )\n\n\twhen Time, Date, ::DateTime\n\t  @writer.tag(\"dateTime.iso8601\", param.strftime(\"%Y%m%dT%H:%M:%S\"))  \n\n\twhen XMLRPC::DateTime\n\t  @writer.tag(\"dateTime.iso8601\", \n\t    format(\"%.4d%02d%02dT%02d:%02d:%02d\", *param.to_a))\n   \n\twhen XMLRPC::Base64\n\t  @writer.tag(\"base64\", param.encoded) \n\n\telse \n          if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable\n            # convert Ruby object into Hash\n            ret = {\"___class___\" => param.class.name}\n            param.instance_variables.each {|v| \n              name = v[1..-1]\n              val = param.instance_variable_get(v)\n\n              if val.nil?\n                ret[name] = val if Config::ENABLE_NIL_CREATE\n              else\n                ret[name] = val\n              end\n            }\n            return conv2value(ret)\n          else \n            ok, pa = wrong_type(param)\n            if ok\n              return conv2value(pa)\n            else \n              raise \"Wrong type!\"\n            end\n          end\n\tend\n\t \n\t@writer.ele(\"value\", val)\n    end\n\n    def wrong_type(value)\n      false\n    end\n\n    \n  end # class Create\n\nend # module XMLRPC\n\n"
  },
  {
    "path": "lib/xmlrpc/datetime.rb",
    "content": "=begin\n= xmlrpc/datetime.rb\nCopyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n\nReleased under the same term of license as Ruby.\n\n= Classes\n* ((<XMLRPC::DateTime>))\n\n= XMLRPC::DateTime\n== Description\nThis class is important to handle XMLRPC (('dateTime.iso8601')) values,\ncorrecly, because normal UNIX-dates (class (({Date}))) only handle dates \nfrom year 1970 on, and class (({Time})) handles dates without the time\ncomponent. (({XMLRPC::DateTime})) is able to store a XMLRPC \n(('dateTime.iso8601')) value correctly.\n\n== Class Methods\n--- XMLRPC::DateTime.new( year, month, day, hour, min, sec )\n    Creates a new (({XMLRPC::DateTime})) instance with the\n    parameters ((|year|)), ((|month|)), ((|day|)) as date and \n    ((|hour|)), ((|min|)), ((|sec|)) as time.\n    Raises (({ArgumentError})) if a parameter is out of range, or ((|year|)) is not\n    of type (({Integer})).\n    \n== Instance Methods\n--- XMLRPC::DateTime#year\n--- XMLRPC::DateTime#month\n--- XMLRPC::DateTime#day\n--- XMLRPC::DateTime#hour\n--- XMLRPC::DateTime#min\n--- XMLRPC::DateTime#sec\n    Return the value of the specified date/time component.\n\n--- XMLRPC::DateTime#mon\n    Alias for ((<XMLRPC::DateTime#month>)).\n\n--- XMLRPC::DateTime#year=( value )\n--- XMLRPC::DateTime#month=( value )\n--- XMLRPC::DateTime#day=( value )\n--- XMLRPC::DateTime#hour=( value )\n--- XMLRPC::DateTime#min=( value )\n--- XMLRPC::DateTime#sec=( value )\n    Set ((|value|)) as the new date/time component.\n    Raises (({ArgumentError})) if ((|value|)) is out of range, or in the case\n    of (({XMLRPC::DateTime#year=})) if ((|value|)) is not of type (({Integer})).\n\n--- XMLRPC::DateTime#mon=( value )\n    Alias for ((<XMLRPC::DateTime#month=>)).\n\n--- XMLRPC::DateTime#to_time\n    Return a (({Time})) object of the date/time which (({self})) represents.\n    If the (('year')) is below 1970, this method returns (({nil})), \n    because (({Time})) cannot handle years below 1970.\n    The used timezone is GMT.\n\n--- XMLRPC::DateTime#to_date\n    Return a (({Date})) object of the date which (({self})) represents.\n    The (({Date})) object do ((*not*)) contain the time component (only date).\n\n--- XMLRPC::DateTime#to_a\n    Returns all date/time components in an array.\n    Returns (({[year, month, day, hour, min, sec]})).\n=end\n\nrequire \"date\"\n\nmodule XMLRPC\n\nclass DateTime\n  \n  attr_reader :year, :month, :day, :hour, :min, :sec\n\n  def year= (value)\n    raise ArgumentError, \"date/time out of range\" unless value.is_a? Integer\n    @year = value\n  end\n\n  def month= (value)\n    raise ArgumentError, \"date/time out of range\" unless (1..12).include? value\n    @month = value\n  end\n\n  def day= (value)\n    raise ArgumentError, \"date/time out of range\" unless (1..31).include? value\n    @day = value\n  end\n\n  def hour= (value)\n    raise ArgumentError, \"date/time out of range\" unless (0..24).include? value\n    @hour = value\n  end\n\n  def min= (value)\n    raise ArgumentError, \"date/time out of range\" unless (0..59).include? value\n    @min = value\n  end\n\n  def sec= (value)\n    raise ArgumentError, \"date/time out of range\" unless (0..59).include? value\n    @sec = value\n  end\n\n  alias mon  month\n  alias mon= month= \n \n\n  def initialize(year, month, day, hour, min, sec)\n    self.year, self.month, self.day = year, month, day\n    self.hour, self.min, self.sec   = hour, min, sec\n  end\n \n  def to_time\n    if @year >= 1970\n      Time.gm(*to_a)\n    else\n      nil\n    end\n  end\n\n  def to_date\n    Date.new(*to_a[0,3])\n  end\n\n  def to_a\n    [@year, @month, @day, @hour, @min, @sec]\n  end\n\n  def ==(o)\n    Array(self) == Array(o)\n  end\n\nend\n\n\nend # module XMLRPC\n\n\n=begin\n= History\n    $Id$\n=end\n"
  },
  {
    "path": "lib/xmlrpc/httpserver.rb",
    "content": "#\n# Implements a simple HTTP-server by using John W. Small's (jsmall@laser.net) \n# ruby-generic-server.\n# \n# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n#\n# $Id$\n#\n\n\nrequire \"gserver\"\n\nclass HttpServer < GServer\n\n  ##\n  # handle_obj specifies the object, that receives calls to request_handler\n  # and ip_auth_handler \n  def initialize(handle_obj, port = 8080, host = DEFAULT_HOST, maxConnections = 4, \n                 stdlog = $stdout, audit = true, debug = true)\n    @handler = handle_obj\n    super(port, host, maxConnections, stdlog, audit, debug)\n  end\n\nprivate\n\n  # Constants -----------------------------------------------\n  \n  CRLF        = \"\\r\\n\"\n  HTTP_PROTO  = \"HTTP/1.0\"\n  SERVER_NAME = \"HttpServer (Ruby #{RUBY_VERSION})\"\n\n  DEFAULT_HEADER = {\n    \"Server\" => SERVER_NAME\n  }\n\n  ##\n  # Mapping of status code and error message\n  #\n  StatusCodeMapping = {\n    200 => \"OK\",\n    400 => \"Bad Request\",\n    403 => \"Forbidden\",\n    405 => \"Method Not Allowed\",\n    411 => \"Length Required\",\n    500 => \"Internal Server Error\"\n  }\n\n  # Classes -------------------------------------------------\n  \n  class Request\n    attr_reader :data, :header, :method, :path, :proto\n    \n    def initialize(data, method=nil, path=nil, proto=nil)\n      @header, @data = Table.new, data\n      @method, @path, @proto = method, path, proto\n    end\n    \n    def content_length\n      len = @header['Content-Length']\n      return nil if len.nil?\n      return len.to_i \n    end\n    \n  end\n  \n  class Response\n    attr_reader   :header\n    attr_accessor :body, :status, :status_message\n    \n    def initialize(status=200)\n      @status = status\n      @status_message = nil\n      @header = Table.new\n    end\n  end\n\n\n  ##\n  # a case-insensitive Hash class for HTTP header\n  #\n  class Table\n    include Enumerable\n\n    def initialize(hash={})\n      @hash = hash \n      update(hash)\n    end\n\n    def [](key)\n      @hash[key.to_s.capitalize]\n    end\n\n    def []=(key, value)\n      @hash[key.to_s.capitalize] = value\n    end\n\n    def update(hash)\n      hash.each {|k,v| self[k] = v}\n      self\n    end\n\n    def each\n      @hash.each {|k,v| yield k.capitalize, v }\n    end\n\n    def writeTo(port)\n      each { |k,v| port << \"#{k}: #{v}\" << CRLF }\n    end\n  end # class Table\n\n\n  # Helper Methods ------------------------------------------\n\n  def http_header(header=nil)\n    new_header = Table.new(DEFAULT_HEADER)\n    new_header.update(header) unless header.nil? \n\n    new_header[\"Connection\"] = \"close\"\n    new_header[\"Date\"]       = http_date(Time.now)\n\n    new_header\n  end\n\n  def http_date( aTime )\n    aTime.gmtime.strftime( \"%a, %d %b %Y %H:%M:%S GMT\" )\n  end\n\n  def http_resp(status_code, status_message=nil, header=nil, body=nil)\n    status_message ||= StatusCodeMapping[status_code]\n    \n    str = \"\"\n    str << \"#{HTTP_PROTO} #{status_code} #{status_message}\" << CRLF\n    http_header(header).writeTo(str)\n    str << CRLF\n    str << body unless body.nil?\n    str\n  end\n\n  # Main Serve Loop -----------------------------------------\n  \n  def serve(io)  \n    # perform IP authentification\n    unless @handler.ip_auth_handler(io)\n      io << http_resp(403, \"Forbidden\")\n      return\n    end\n\n    # parse first line\n    if io.gets =~ /^(\\S+)\\s+(\\S+)\\s+(\\S+)/\n      request = Request.new(io, $1, $2, $3)\n    else\n      io << http_resp(400, \"Bad Request\") \n      return\n    end\n     \n    # parse HTTP headers\n    while (line=io.gets) !~ /^(\\n|\\r)/\n      if line =~ /^([\\w-]+):\\s*(.*)$/\n\trequest.header[$1] = $2.strip\n      end\n    end\n\n    io.binmode    \n    response = Response.new\n\n    # execute request handler\n    @handler.request_handler(request, response)\n   \n    # write response back to the client\n    io << http_resp(response.status, response.status_message,\n                    response.header, response.body) \n\n  rescue Exception => e\n    io << http_resp(500, \"Internal Server Error\")\n  end\n\nend # class HttpServer\n\n"
  },
  {
    "path": "lib/xmlrpc/marshal.rb",
    "content": "#\n# Marshalling of XML-RPC methodCall and methodResponse\n# \n# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n#\n# $Id$\n#\n\nrequire \"xmlrpc/parser\"\nrequire \"xmlrpc/create\"\nrequire \"xmlrpc/config\"\nrequire \"xmlrpc/utils\"\n\nmodule XMLRPC\n\n  class Marshal\n    include ParserWriterChooseMixin\n\n    # class methods -------------------------------\n   \n    class << self\n\n      def dump_call( methodName, *params )\n        new.dump_call( methodName, *params )\n      end\n\n      def dump_response( param )\n        new.dump_response( param )\n      end\n\n      def load_call( stringOrReadable )\n        new.load_call( stringOrReadable )\n      end\n\n      def load_response( stringOrReadable )\n        new.load_response( stringOrReadable )\n      end\n\n      alias dump dump_response\n      alias load load_response\n\n    end # class self\n\n    # instance methods ----------------------------\n\n    def initialize( parser = nil, writer = nil )\n      set_parser( parser )\n      set_writer( writer )\n    end\n\n    def dump_call( methodName, *params )\n      create.methodCall( methodName, *params )\n    end\n\n    def dump_response( param ) \n      create.methodResponse( ! param.kind_of?( XMLRPC::FaultException ) , param )\n    end\n\n    ##\n    # returns [ methodname, params ]\n    #\n    def load_call( stringOrReadable )\n      parser.parseMethodCall( stringOrReadable )\n    end\n\n    ##\n    # returns paramOrFault\n    #\n    def load_response( stringOrReadable )\n      parser.parseMethodResponse( stringOrReadable )[1]\n    end\n\n  end # class Marshal\n\nend\n\n"
  },
  {
    "path": "lib/xmlrpc/parser.rb",
    "content": "#\n# Parser for XML-RPC call and response\n# \n# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n#\n# $Id$\n#\n\n\nrequire \"date\"\nrequire \"xmlrpc/base64\"\nrequire \"xmlrpc/datetime\"\n\n\n# add some methods to NQXML::Node\nmodule NQXML\n  class Node\n\n    def removeChild(node)\n      @children.delete(node)\n    end\n    def childNodes\n      @children\n    end\n    def hasChildNodes\n      not @children.empty?\n    end\n    def [] (index)\n      @children[index]\n    end\n\n    def nodeType\n      if @entity.instance_of? NQXML::Text then :TEXT\n      elsif @entity.instance_of? NQXML::Comment then :COMMENT\n      #elsif @entity.instance_of? NQXML::Element then :ELEMENT\n      elsif @entity.instance_of? NQXML::Tag then :ELEMENT\n      else :ELSE\n      end\n    end\n\n    def nodeValue\n      #TODO: error when wrong Entity-type\n      @entity.text\n    end\n    def nodeName\n      #TODO: error when wrong Entity-type\n      @entity.name\n    end\n  end # class Node\nend # module NQXML\n\nmodule XMLRPC\n\n  class FaultException < StandardError\n    attr_reader :faultCode, :faultString\n\n    alias message faultString\n\n    def initialize(faultCode, faultString)\n      @faultCode   = faultCode\n      @faultString = faultString\n    end\n    \n    # returns a hash\n    def to_h\n      {\"faultCode\" => @faultCode, \"faultString\" => @faultString}\n    end\n  end\n\n  module Convert\n    def self.int(str)\n      str.to_i\n    end\n\n    def self.boolean(str)\n      case str\n      when \"0\" then false\n      when \"1\" then true\n      else\n        raise \"RPC-value of type boolean is wrong\" \n      end\n    end\n\n    def self.double(str)\n      str.to_f\n    end\n\n    def self.dateTime(str)\n      case str\n      when /^(-?\\d\\d\\d\\d)-?(\\d\\d)-?(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(?:Z|([+-])(\\d\\d):?(\\d\\d))?$/\n        a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i}\n        if $7\n          ofs = $8.to_i*3600 + $9.to_i*60\n          ofs = -ofs if $7=='+'\n          utc = Time.utc(*a) + ofs\n          a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]\n        end\n        XMLRPC::DateTime.new(*a)\n      when /^(-?\\d\\d)-?(\\d\\d)-?(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(Z|([+-]\\d\\d):(\\d\\d))?$/\n        a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i}\n        if a[0] < 70\n          a[0] += 2000\n        else\n          a[0] += 1900\n        end\n        if $7\n          ofs = $8.to_i*3600 + $9.to_i*60\n          ofs = -ofs if $7=='+'\n          utc = Time.utc(*a) + ofs\n          a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ]\n        end\n        XMLRPC::DateTime.new(*a)\n      else\n        raise \"wrong dateTime.iso8601 format \" + str\n      end\n    end\n\n    def self.base64(str)\n      XMLRPC::Base64.decode(str)\n    end\n\n    def self.struct(hash)\n      # convert to marhalled object\n      klass = hash[\"___class___\"]\n      if klass.nil? or Config::ENABLE_MARSHALLING == false \n        hash\n      else\n        begin\n          mod = Module\n          klass.split(\"::\").each {|const| mod = mod.const_get(const.strip)}\n\n          obj = mod.allocate\n          \n          hash.delete \"___class___\"\n          hash.each {|key, value| \n            obj.instance_variable_set(\"@#{ key }\", value) if key =~ /^([\\w_][\\w_0-9]*)$/\n          }\n          obj\n        rescue\n          hash\n        end\n      end\n    end\n\n    def self.fault(hash)\n      if hash.kind_of? Hash and hash.size == 2 and \n        hash.has_key? \"faultCode\" and hash.has_key? \"faultString\" and \n        hash[\"faultCode\"].kind_of? Integer and hash[\"faultString\"].kind_of? String\n\n        XMLRPC::FaultException.new(hash[\"faultCode\"], hash[\"faultString\"]) \n      else\n        raise \"wrong fault-structure: #{hash.inspect}\"\n      end\n    end\n\n  end # module Convert\n\n  module XMLParser\n\n    class AbstractTreeParser\n\n      def parseMethodResponse(str)\n\tmethodResponse_document(createCleanedTree(str))\n      end\n\n      def parseMethodCall(str)\n\tmethodCall_document(createCleanedTree(str))\n      end\n\n      private\n\n      #\n      # remove all whitespaces but in the tags i4, int, boolean....\n      # and all comments\n      #\n      def removeWhitespacesAndComments(node)\n\tremove = []\n\tchilds = node.childNodes.to_a\n\tchilds.each do |nd|\n\t  case _nodeType(nd)\n\t  when :TEXT\n            # TODO: add nil?\n            unless %w(i4 int boolean string double dateTime.iso8601 base64).include? node.nodeName\n\n               if node.nodeName == \"value\" \n                 if not node.childNodes.to_a.detect {|n| _nodeType(n) == :ELEMENT}.nil?\n                   remove << nd if nd.nodeValue.strip == \"\" \n                 end\n               else\n                 remove << nd if nd.nodeValue.strip == \"\"\n               end\n\t    end\n\t  when :COMMENT\n\t    remove << nd\n\t  else\n\t    removeWhitespacesAndComments(nd)\n\t  end \n\tend\n\n\tremove.each { |i| node.removeChild(i) }\n      end\n\n\n      def nodeMustBe(node, name)\n\tcmp = case name\n\twhen Array \n\t  name.include?(node.nodeName)\n\twhen String\n\t  name == node.nodeName\n\telse\n\t  raise \"error\"\n\tend  \n\n\tif not cmp then\n\t  raise \"wrong xml-rpc (name)\"\n\tend\n\n\tnode\n      end\n\n      #\n      # returns, when successfully the only child-node\n      #\n      def hasOnlyOneChild(node, name=nil)\n\tif node.childNodes.to_a.size != 1\n\t  raise \"wrong xml-rpc (size)\"\n\tend\n\tif name != nil then\n\t  nodeMustBe(node.firstChild, name)\n\tend\n      end\n\n\n      def assert(b)\n\tif not b then\n\t  raise \"assert-fail\" \n\tend\n      end\n\n      # the node `node` has empty string or string\n      def text_zero_one(node)\n\tnodes = node.childNodes.to_a.size\n\n\tif nodes == 1\n\t  text(node.firstChild)\n\telsif nodes == 0\n\t  \"\"\n\telse\n\t  raise \"wrong xml-rpc (size)\"\n\tend\n      end\n     \n\n      def integer(node)\n\t#TODO: check string for float because to_i returnsa\n\t#      0 when wrong string\n\t nodeMustBe(node, %w(i4 int))    \n\thasOnlyOneChild(node)\n\t\n\tConvert.int(text(node.firstChild))\n      end\n\n      def boolean(node)\n\tnodeMustBe(node, \"boolean\")    \n\thasOnlyOneChild(node)\n\t\n        Convert.boolean(text(node.firstChild))\n      end\n\n      def v_nil(node)\n        nodeMustBe(node, \"nil\")\n\tassert( node.childNodes.to_a.size == 0 )\n        nil\n      end\n\n      def string(node)\n\tnodeMustBe(node, \"string\")    \n\ttext_zero_one(node)\n      end\n\n      def double(node)\n\t#TODO: check string for float because to_f returnsa\n\t#      0.0 when wrong string\n\tnodeMustBe(node, \"double\")    \n\thasOnlyOneChild(node)\n\t\n\tConvert.double(text(node.firstChild))\n      end\n\n      def dateTime(node)\n\tnodeMustBe(node, \"dateTime.iso8601\")\n\thasOnlyOneChild(node)\n\t\n        Convert.dateTime( text(node.firstChild) )\n      end\n\n      def base64(node)\n\tnodeMustBe(node, \"base64\")\n\t#hasOnlyOneChild(node)\n\t \n        Convert.base64(text_zero_one(node))\n      end\n\n      def member(node)\n\tnodeMustBe(node, \"member\")\n\tassert( node.childNodes.to_a.size == 2 ) \n\n\t[ name(node[0]), value(node[1]) ]\n      end\n\n      def name(node)\n\tnodeMustBe(node, \"name\")\n\t#hasOnlyOneChild(node)\n\ttext_zero_one(node) \n      end\n\n      def array(node)\n\tnodeMustBe(node, \"array\")\n\thasOnlyOneChild(node, \"data\") \n\tdata(node.firstChild)  \n      end\n\n      def data(node)\n\tnodeMustBe(node, \"data\")\n\n\tnode.childNodes.to_a.collect do |val|\n\t  value(val)\n\tend \n      end\n\n      def param(node)\n\tnodeMustBe(node, \"param\")\n\thasOnlyOneChild(node, \"value\")\n\tvalue(node.firstChild) \n      end\n \n      def methodResponse(node)\n\tnodeMustBe(node, \"methodResponse\")\n\thasOnlyOneChild(node, %w(params fault))\n\tchild = node.firstChild\n\n\tcase child.nodeName\n\twhen \"params\"\n\t  [ true, params(child,false) ] \n\twhen \"fault\"\n\t  [ false, fault(child) ]\n\telse\n\t  raise \"unexpected error\"\n\tend\n\n      end\n\n      def methodName(node)\n\tnodeMustBe(node, \"methodName\")\n\thasOnlyOneChild(node)\n\ttext(node.firstChild) \n      end\n\n      def params(node, call=true)\n\tnodeMustBe(node, \"params\")\n\n\tif call \n\t  node.childNodes.to_a.collect do |n|\n\t    param(n)\n\t  end\n\telse # response (only one param)\n\t  hasOnlyOneChild(node)\n\t  param(node.firstChild)\n\tend\n      end\n\n      def fault(node)\n\tnodeMustBe(node, \"fault\")\n\thasOnlyOneChild(node, \"value\")\n\tf = value(node.firstChild) \n        Convert.fault(f)\n      end\n\n\n\n      # _nodeType is defined in the subclass\n      def text(node)\n\tassert( _nodeType(node) == :TEXT )\n\tassert( node.hasChildNodes == false )\n\tassert( node.nodeValue != nil )\n\n\tnode.nodeValue.to_s\n      end\n\n      def struct(node)\n\tnodeMustBe(node, \"struct\")    \n\n\thash = {}\n\tnode.childNodes.to_a.each do |me|\n\t  n, v = member(me)  \n\t  hash[n] = v\n\tend \n\n        Convert.struct(hash)\n     end\n\n\n      def value(node)\n\tnodeMustBe(node, \"value\")\n\tnodes = node.childNodes.to_a.size\n        if nodes == 0 \n          return \"\"\n        elsif nodes > 1 \n\t  raise \"wrong xml-rpc (size)\"\n        end\n\n\tchild = node.firstChild\n\n\tcase _nodeType(child)\n\twhen :TEXT\n          text_zero_one(node)\n\twhen :ELEMENT\n\t  case child.nodeName\n\t  when \"i4\", \"int\"        then integer(child)\n\t  when \"boolean\"          then boolean(child)\n\t  when \"string\"           then string(child)\n\t  when \"double\"           then double(child)\n\t  when \"dateTime.iso8601\" then dateTime(child)\n\t  when \"base64\"           then base64(child)\n\t  when \"struct\"           then struct(child)\n\t  when \"array\"            then array(child) \n          when \"nil\"              \n            if Config::ENABLE_NIL_PARSER\n              v_nil(child)\n            else\n              raise \"wrong/unknown XML-RPC type 'nil'\"\n            end\n\t  else \n\t    raise \"wrong/unknown XML-RPC type\"\n\t  end\n\telse\n\t  raise \"wrong type of node\"\n\tend\n\n      end\n\n      def methodCall(node)\n\tnodeMustBe(node, \"methodCall\")\n\tassert( (1..2).include?( node.childNodes.to_a.size ) ) \n\tname = methodName(node[0])\n\n\tif node.childNodes.to_a.size == 2 then\n\t  pa = params(node[1])\n\telse # no parameters given\n\t  pa = []\n\tend\n\t[name, pa]\n      end\n\n    end # module TreeParserMixin\n\n    class AbstractStreamParser\n      def parseMethodResponse(str)\n        parser = @parser_class.new\n        parser.parse(str)\n        raise \"No valid method response!\" if parser.method_name != nil\n        if parser.fault != nil\n          # is a fault structure\n          [false, parser.fault] \n        else\n          # is a normal return value\n          raise \"Missing return value!\" if parser.params.size == 0\n          raise \"Too many return values. Only one allowed!\" if parser.params.size > 1\n          [true, parser.params[0]]\n        end\n      end\n\n      def parseMethodCall(str)\n        parser = @parser_class.new\n        parser.parse(str)\n        raise \"No valid method call - missing method name!\" if parser.method_name.nil?\n        [parser.method_name, parser.params]\n      end\n    end\n\n    module StreamParserMixin\n      attr_reader :params\n      attr_reader :method_name\n      attr_reader :fault\n\n      def initialize(*a)\n        super(*a)\n        @params = []\n        @values = []\n        @val_stack = []\n\n        @names = []\n        @name = []\n\n        @structs = []\n        @struct = {}\n\n        @method_name = nil\n        @fault = nil\n\n        @data = nil\n      end\n\n      def startElement(name, attrs=[])\n        @data = nil\n        case name\n        when \"value\"\n          @value = nil\n        when \"nil\"\n          raise \"wrong/unknown XML-RPC type 'nil'\" unless Config::ENABLE_NIL_PARSER\n          @value = :nil \n        when \"array\"\n          @val_stack << @values\n          @values = []\n        when \"struct\"\n          @names << @name\n          @name = []\n\n          @structs << @struct\n          @struct = {} \n        end\n      end\n\n      def endElement(name)\n        @data ||= \"\"\n        case name\n        when \"string\"\n          @value = @data\n        when \"i4\", \"int\"\n          @value = Convert.int(@data)\n        when \"boolean\"\n          @value = Convert.boolean(@data)\n        when \"double\"\n          @value = Convert.double(@data)\n        when \"dateTime.iso8601\"\n          @value = Convert.dateTime(@data)\n        when \"base64\"\n          @value = Convert.base64(@data)\n        when \"value\"\n          @value = @data if @value.nil?\n          @values << (@value == :nil ? nil : @value) \n        when \"array\"\n          @value = @values\n          @values = @val_stack.pop\n        when \"struct\"\n          @value = Convert.struct(@struct)\n\n          @name = @names.pop\n          @struct = @structs.pop\n        when \"name\"\n          @name[0] = @data \n        when \"member\"\n          @struct[@name[0]] = @values.pop \n\n        when \"param\"\n          @params << @values[0]\n          @values = []\n\n        when \"fault\"\n          @fault = Convert.fault(@values[0])\n\n        when \"methodName\"\n          @method_name = @data \n        end\n\n        @data = nil\n      end\n\n      def character(data)\n        if @data\n          @data << data\n        else\n          @data = data\n        end\n      end\n\n    end # module StreamParserMixin\n\n    # ---------------------------------------------------------------------------\n    class XMLStreamParser < AbstractStreamParser\n      def initialize\n        require \"xmlparser\"\n        @parser_class = Class.new(::XMLParser) {\n          include StreamParserMixin\n        }\n      end\n    end # class XMLStreamParser\n    # ---------------------------------------------------------------------------\n    class NQXMLStreamParser < AbstractStreamParser\n      def initialize\n        require \"nqxml/streamingparser\"\n        @parser_class = XMLRPCParser\n      end\n\n      class XMLRPCParser \n        include StreamParserMixin\n\n        def parse(str)\n          parser = NQXML::StreamingParser.new(str)\n          parser.each do |ele|\n            case ele\n            when NQXML::Text\n              @data = ele.text\n              #character(ele.text)\n            when NQXML::Tag\n              if ele.isTagEnd\n                endElement(ele.name)\n              else\n                startElement(ele.name, ele.attrs)\n              end\n            end\n          end # do\n        end # method parse\n      end # class XMLRPCParser\n\n    end # class NQXMLStreamParser\n    # ---------------------------------------------------------------------------\n    class XMLTreeParser < AbstractTreeParser\n\n      def initialize\n        require \"xmltreebuilder\"\n\n        # The new XMLParser library (0.6.2+) uses a slightly different DOM implementation. \n        # The following code removes the differences between both versions.\n        if defined? XML::DOM::Builder \n          return if defined? XML::DOM::Node::DOCUMENT # code below has been already executed\n          klass = XML::DOM::Node\n          klass.const_set(\"DOCUMENT\", klass::DOCUMENT_NODE)\n          klass.const_set(\"TEXT\", klass::TEXT_NODE)\n          klass.const_set(\"COMMENT\", klass::COMMENT_NODE)\n          klass.const_set(\"ELEMENT\", klass::ELEMENT_NODE)\n        end\n      end\n\n      private\n\n      def _nodeType(node)\n\ttp = node.nodeType\n\tif tp == XML::SimpleTree::Node::TEXT then :TEXT\n\telsif tp == XML::SimpleTree::Node::COMMENT then :COMMENT \n\telsif tp == XML::SimpleTree::Node::ELEMENT then :ELEMENT \n\telse :ELSE\n\tend\n      end\n\n\n      def methodResponse_document(node)\n\tassert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )\n\thasOnlyOneChild(node, \"methodResponse\")\n\t\n\tmethodResponse(node.firstChild)\n      end\n\n      def methodCall_document(node)\n\tassert( node.nodeType == XML::SimpleTree::Node::DOCUMENT )\n\thasOnlyOneChild(node, \"methodCall\")\n\t\n\tmethodCall(node.firstChild)\n      end\n\n      def createCleanedTree(str)\n\tdoc = XML::SimpleTreeBuilder.new.parse(str)\n\tdoc.documentElement.normalize\n\tremoveWhitespacesAndComments(doc)\n\tdoc\n      end\n\n    end # class XMLParser\n    # ---------------------------------------------------------------------------\n    class NQXMLTreeParser < AbstractTreeParser\n\n      def initialize\n        require \"nqxml/treeparser\"\n      end\n\n      private\n\n      def _nodeType(node)\n\tnode.nodeType\n      end\n\n      def methodResponse_document(node)\n\tmethodResponse(node)\n      end\n\n      def methodCall_document(node)\n\tmethodCall(node)\n      end\n\n      def createCleanedTree(str)\n        doc = ::NQXML::TreeParser.new(str).document.rootNode \n\tremoveWhitespacesAndComments(doc)\n\tdoc\n      end\n\n    end # class NQXMLTreeParser\n    # ---------------------------------------------------------------------------\n    class REXMLStreamParser < AbstractStreamParser\n      def initialize\n        require \"rexml/document\"\n        @parser_class = StreamListener\n      end\n\n      class StreamListener \n        include StreamParserMixin\n\n        alias :tag_start :startElement\n        alias :tag_end :endElement\n        alias :text :character\n        alias :cdata :character\n\n        def method_missing(*a)\n          # ignore\n        end\n\n        def parse(str)\n          parser = REXML::Document.parse_stream(str, self)\n       end\n      end \n\n    end\n    # ---------------------------------------------------------------------------\n    class XMLScanStreamParser < AbstractStreamParser\n      def initialize\n        require \"xmlscan/parser\"\n        @parser_class = XMLScanParser\n      end\n\n      class XMLScanParser\n        include StreamParserMixin\n\n        Entities = {\n          \"lt\"   => \"<\",\n          \"gt\"   => \">\",\n          \"amp\"  => \"&\",\n          \"quot\" => '\"',\n          \"apos\" => \"'\"\n        }\n\n        def parse(str)\n          parser  = XMLScan::XMLParser.new(self)\n          parser.parse(str)\n        end\n\n        alias :on_stag :startElement\n \talias :on_etag :endElement\n\n        def on_stag_end(name); end\n\n        def on_stag_end_empty(name)\n          startElement(name)\n          endElement(name)\n        end\n       \n        def on_chardata(str)\n          character(str)\n        end\n\n        def on_cdata(str)\n          character(str)\n        end\n\n        def on_entityref(ent)\n          str = Entities[ent]\n          if str\n            character(str)\n          else\n            raise \"unknown entity\"\n          end\n        end\n\n        def on_charref(code)\n          character(code.chr)\n        end\n\n        def on_charref_hex(code)\n          character(code.chr)\n        end\n\n        def method_missing(*a)\n        end\n\n        # TODO: call/implement?\n        # valid_name?\n        # valid_chardata?\n        # valid_char?\n        # parse_error  \n\n      end\n    end\n    # ---------------------------------------------------------------------------\n    XMLParser   = XMLTreeParser\n    NQXMLParser = NQXMLTreeParser\n\n    Classes = [XMLStreamParser, XMLTreeParser, \n               NQXMLStreamParser, NQXMLTreeParser, \n               REXMLStreamParser, XMLScanStreamParser]\n\n    # yields an instance of each installed parser\n    def self.each_installed_parser\n      XMLRPC::XMLParser::Classes.each do |klass|\n        begin\n          yield klass.new\n        rescue LoadError\n        end\n      end\n    end\n\n  end # module XMLParser\n\n\nend # module XMLRPC\n\n"
  },
  {
    "path": "lib/xmlrpc/server.rb",
    "content": "=begin\n= xmlrpc/server.rb\nCopyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de)\n\nReleased under the same term of license as Ruby.\n\n= Classes\n* ((<XMLRPC::BasicServer>))\n* ((<XMLRPC::CGIServer>))\n* ((<XMLRPC::ModRubyServer>))\n* ((<XMLRPC::Server>))\n* ((<XMLRPC::WEBrickServlet>))\n\n= XMLRPC::BasicServer\n== Description\nIs the base class for all XML-RPC server-types (CGI, standalone).\nYou can add handler and set a default handler. \nDo not use this server, as this is/should be an abstract class.\n\n=== How the method to call is found\nThe arity (number of accepted arguments) of a handler (method or (({Proc})) object) is \ncompared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)). \nA handler is only called if it accepts the number of arguments, otherwise the search \nfor another handler will go on. When at the end no handler was found, \nthe ((<default_handler|XMLRPC::BasicServer#set_default_handler>)) will be called.\nWith this technique it is possible to do overloading by number of parameters, but\nonly for (({Proc})) handler, because you cannot define two methods of the same name in\nthe same class. \n\n\n== Class Methods\n--- XMLRPC::BasicServer.new( class_delim=\".\" )\n    Creates a new (({XMLRPC::BasicServer})) instance, which should not be \n    done, because (({XMLRPC::BasicServer})) is an abstract class. This\n    method should be called from a subclass indirectly by a (({super})) call\n    in the method (({initialize})). The paramter ((|class_delim|)) is used\n    in ((<add_handler|XMLRPC::BasicServer#add_handler>)) when an object is\n    added as handler, to delimit the object-prefix and the method-name.\n\n== Instance Methods\n--- XMLRPC::BasicServer#add_handler( name, signature=nil, help=nil ) { aBlock }\n    Adds ((|aBlock|)) to the list of handlers, with ((|name|)) as the name of the method.\n    Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified, \n    where ((|signature|)) is either an Array containing strings each representing a type of it's \n    signature (the first is the return value) or an Array of Arrays if the method has multiple \n    signatures. Value type-names are \"int, boolean, double, string, dateTime.iso8601, base64, array, struct\".\n\n    Parameter ((|help|)) is a String with informations about how to call this method etc.\n\n    A handler method or code-block can return the types listed at\n    ((<XMLRPC::Client#call|URL:client.html#index:0>)). \n    When a method fails, it can tell it the client by throwing an \n    (({XMLRPC::FaultException})) like in this example:\n        s.add_handler(\"michael.div\") do |a,b|\n          if b == 0\n            raise XMLRPC::FaultException.new(1, \"division by zero\")\n          else\n            a / b \n          end\n        end \n    The client gets in the case of (({b==0})) an object back of type\n    (({XMLRPC::FaultException})) that has a ((|faultCode|)) and ((|faultString|))\n    field.\n\n--- XMLRPC::BasicServer#add_handler( prefix, obj )\n    This is the second form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).\n    To add an object write:\n        server.add_handler(\"michael\", MyHandlerClass.new)\n    All public methods of (({MyHandlerClass})) are accessible to\n    the XML-RPC clients by (('michael.\"name of method\"')). This is \n    where the ((|class_delim|)) in ((<new|XMLRPC::BasicServer.new>)) \n    has it's role, a XML-RPC method-name is defined by \n    ((|prefix|)) + ((|class_delim|)) + (('\"name of method\"')). \n\n--- XMLRPC::BasicServer#add_handler( interface, obj )\n    This is the third form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).\n\n    Use (({XMLRPC::interface})) to generate an ServiceInterface object, which\n    represents an interface (with signature and help text) for a handler class.\n\n    Parameter ((|interface|)) must be of type (({XMLRPC::ServiceInterface})).\n    Adds all methods of ((|obj|)) which are defined in ((|interface|)) to the\n    server.\n\n    This is the recommended way of adding services to a server!\n\n\n--- XMLRPC::BasicServer#get_default_handler\n    Returns the default-handler, which is called when no handler for\n    a method-name is found.\n    It is a (({Proc})) object or (({nil})).\n\n--- XMLRPC::BasicServer#set_default_handler ( &handler )\n    Sets ((|handler|)) as the default-handler, which is called when \n    no handler for a method-name is found. ((|handler|)) is a code-block.\n    The default-handler is called with the (XML-RPC) method-name as first argument, and\n    the other arguments are the parameters given by the client-call.\n  \n    If no block is specified the default of (({XMLRPC::BasicServer})) is used, which raises a\n    XMLRPC::FaultException saying \"method missing\".\n\n\n--- XMLRPC::BasicServer#set_writer( writer )\n    Sets the XML writer to use for generating XML output.\n    Should be an instance of a class from module (({XMLRPC::XMLWriter})).\n    If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. \n\n--- XMLRPC::BasicServer#set_parser( parser )\n    Sets the XML parser to use for parsing XML documents.\n    Should be an instance of a class from module (({XMLRPC::XMLParser})).\n    If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used.\n\n--- XMLRPC::BasicServer#add_introspection\n    Adds the introspection handlers \"system.listMethods\", \"system.methodSignature\" and \"system.methodHelp\", \n    where only the first one works.\n\n--- XMLRPC::BasicServer#add_multicall\n    Adds the multi-call handler \"system.multicall\".\n\n--- XMLRPC::BasicServer#get_service_hook\n    Returns the service-hook, which is called on each service request (RPC) unless it's (({nil})).\n\n--- XMLRPC::BasicServer#set_service_hook ( &handler )\n    A service-hook is called for each service request (RPC).\n    You can use a service-hook for example to wrap existing methods and catch exceptions of them or\n    convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter  \n    ((|handler|)) .\n\n    The service-hook is called with a (({Proc})) object and with the parameters for this (({Proc})).\n    An example:\n\n       server.set_service_hook {|obj, *args|\n         begin\n           ret = obj.call(*args)  # call the original service-method\n           # could convert the return value \n         resuce\n           # rescue exceptions\n         end\n       }\n\n=end\n\n\n\nrequire \"xmlrpc/parser\"\nrequire \"xmlrpc/create\"\nrequire \"xmlrpc/config\"\nrequire \"xmlrpc/utils\"         # ParserWriterChooseMixin\n\n\n\nmodule XMLRPC\n\n\nclass BasicServer\n\n  include ParserWriterChooseMixin\n  include ParseContentType\n\n  ERR_METHOD_MISSING        = 1 \n  ERR_UNCAUGHT_EXCEPTION    = 2\n  ERR_MC_WRONG_PARAM        = 3\n  ERR_MC_MISSING_PARAMS     = 4\n  ERR_MC_MISSING_METHNAME   = 5\n  ERR_MC_RECURSIVE_CALL     = 6\n  ERR_MC_WRONG_PARAM_PARAMS = 7\n  ERR_MC_EXPECTED_STRUCT    = 8\n\n\n  def initialize(class_delim=\".\")\n    @handler = []\n    @default_handler = nil \n    @service_hook = nil\n\n    @class_delim = class_delim\n    @create = nil\n    @parser = nil\n\n    add_multicall     if Config::ENABLE_MULTICALL\n    add_introspection if Config::ENABLE_INTROSPECTION\n  end\n\n  def add_handler(prefix, obj_or_signature=nil, help=nil, &block)\n    if block_given?\n      # proc-handler\n      @handler << [prefix, block, obj_or_signature, help]   \n    else\n      if prefix.kind_of? String\n        # class-handler\n        raise ArgumentError, \"Expected non-nil value\" if obj_or_signature.nil?\n        @handler << [prefix + @class_delim, obj_or_signature]\n      elsif prefix.kind_of? XMLRPC::Service::BasicInterface\n        # class-handler with interface\n        # add all methods\n        @handler += prefix.get_methods(obj_or_signature, @class_delim)\n      else\n        raise ArgumentError, \"Wrong type for parameter 'prefix'\"\n      end\n    end\n    self\n  end\n\n  def get_service_hook\n    @service_hook\n  end\n\n  def set_service_hook(&handler)\n    @service_hook = handler\n    self\n  end\n \n  def get_default_handler\n    @default_handler\n  end\n\n  def set_default_handler (&handler)\n    @default_handler = handler\n    self\n  end  \n\n  def add_multicall\n    add_handler(\"system.multicall\", %w(array array), \"Multicall Extension\") do |arrStructs|\n      unless arrStructs.is_a? Array \n        raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, \"system.multicall expects an array\")\n      end\n\n      arrStructs.collect {|call|\n        if call.is_a? Hash\n          methodName = call[\"methodName\"]\n          params     = call[\"params\"]  \n\n          if params.nil?\n            multicall_fault(ERR_MC_MISSING_PARAMS, \"Missing params\")\n          elsif methodName.nil?\n            multicall_fault(ERR_MC_MISSING_METHNAME, \"Missing methodName\")\n          else\n            if methodName == \"system.multicall\"\n              multicall_fault(ERR_MC_RECURSIVE_CALL, \"Recursive system.multicall forbidden\")\n            else\n              unless params.is_a? Array\n                multicall_fault(ERR_MC_WRONG_PARAM_PARAMS, \"Parameter params have to be an Array\")\n              else\n                ok, val = call_method(methodName, *params)\n                if ok\n                  # correct return value\n                  [val]\n                else\n                  # exception\n                  multicall_fault(val.faultCode, val.faultString) \n                end\n              end\n            end\n          end  \n           \n        else\n          multicall_fault(ERR_MC_EXPECTED_STRUCT, \"system.multicall expected struct\")\n        end\n      } \n    end # end add_handler\n    self\n  end\n\n  def add_introspection\n    add_handler(\"system.listMethods\",%w(array), \"List methods available on this XML-RPC server\") do\n      methods = []\n      @handler.each do |name, obj|\n        if obj.kind_of? Proc\n          methods << name\n        else\n          obj.class.public_instance_methods(false).each do |meth|\n            methods << \"#{name}#{meth}\"\n          end\n        end\n      end\n      methods\n    end\n\n    add_handler(\"system.methodSignature\", %w(array string), \"Returns method signature\") do |meth|\n      sigs = []\n      @handler.each do |name, obj, sig|\n        if obj.kind_of? Proc and sig != nil and name == meth\n          if sig[0].kind_of? Array\n            # sig contains multiple signatures, e.g. [[\"array\"], [\"array\", \"string\"]]\n            sig.each {|s| sigs << s}\n          else\n            # sig is a single signature, e.g. [\"array\"]\n            sigs << sig \n          end\n        end\n      end\n      sigs.uniq! || sigs  # remove eventually duplicated signatures\n    end\n\n    add_handler(\"system.methodHelp\", %w(string string), \"Returns help on using this method\") do |meth|\n      help = nil \n      @handler.each do |name, obj, sig, hlp|\n        if obj.kind_of? Proc and name == meth \n          help = hlp\n          break      \n        end\n      end\n      help || \"\"\n    end\n\n    self\n  end\n\n\n  \n  def process(data)\n    method, params = parser().parseMethodCall(data) \n    handle(method, *params)\n  end\n \n  private # --------------------------------------------------------------\n\n  def multicall_fault(nr, str)\n    {\"faultCode\" => nr, \"faultString\" => str}\n  end\n \n  #\n  # method dispatch\n  #\n  def dispatch(methodname, *args)\n    for name, obj in @handler\n      if obj.kind_of? Proc\n        next unless methodname == name\n      else\n        next unless methodname =~ /^#{name}(.+)$/\n        next unless obj.respond_to? $1\n        obj = obj.method($1)\n      end\n\n      if check_arity(obj, args.size)\n        if @service_hook.nil?\n          return obj.call(*args) \n        else\n          return @service_hook.call(obj, *args)\n        end\n      end\n    end \n \n    if @default_handler.nil?\n      raise XMLRPC::FaultException.new(ERR_METHOD_MISSING, \"Method #{methodname} missing or wrong number of parameters!\")\n    else\n      @default_handler.call(methodname, *args) \n    end\n  end\n\n\n  #\n  # returns true, if the arity of \"obj\" matches\n  #\n  def check_arity(obj, n_args)\n    ary = obj.arity\n\n    if ary >= 0\n      n_args == ary\n    else\n      n_args >= (ary+1).abs \n    end\n  end\n\n\n\n  def call_method(methodname, *args)\n    begin\n      [true, dispatch(methodname, *args)]\n    rescue XMLRPC::FaultException => e  \n      [false, e]  \n    rescue Exception => e\n      [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, \"Uncaught exception #{e.message} in method #{methodname}\")]\n    end\n  end\n\n  #\n  #\n  #\n  def handle(methodname, *args)\n    create().methodResponse(*call_method(methodname, *args))\n  end\n\n\nend\n\n\n=begin\n= XMLRPC::CGIServer\n== Synopsis\n    require \"xmlrpc/server\"\n \n    s = XMLRPC::CGIServer.new     \n\n    s.add_handler(\"michael.add\") do |a,b|\n      a + b\n    end\n\n    s.add_handler(\"michael.div\") do |a,b|\n      if b == 0\n        raise XMLRPC::FaultException.new(1, \"division by zero\")\n      else\n        a / b \n      end\n    end \n\n    s.set_default_handler do |name, *args|\n      raise XMLRPC::FaultException.new(-99, \"Method #{name} missing\" +\n                                       \" or wrong number of parameters!\")\n    end\n  \n    s.serve\n\n== Description\nImplements a CGI-based XML-RPC server.\n\n== Superclass\n((<XMLRPC::BasicServer>))\n\n== Class Methods\n--- XMLRPC::CGIServer.new( *a )\n    Creates a new (({XMLRPC::CGIServer})) instance. All parameters given\n    are by-passed to ((<XMLRPC::BasicServer.new>)). You can only create \n    ((*one*)) (({XMLRPC::CGIServer})) instance, because more than one makes\n    no sense.\n\n== Instance Methods\n--- XMLRPC::CGIServer#serve\n    Call this after you have added all you handlers to the server.\n    This method processes a XML-RPC methodCall and sends the answer\n    back to the client. \n    Make sure that you don't write to standard-output in a handler, or in\n    any other part of your program, this would case a CGI-based server to fail!\n=end\n\nclass CGIServer < BasicServer\n  @@obj = nil\n\n  def CGIServer.new(*a)\n    @@obj = super(*a) if @@obj.nil?\n    @@obj\n  end\n\n  def initialize(*a)\n    super(*a)\n  end\n  \n  def serve\n    catch(:exit_serve) {\n      length = ENV['CONTENT_LENGTH'].to_i\n\n      http_error(405, \"Method Not Allowed\") unless ENV['REQUEST_METHOD'] == \"POST\" \n      http_error(400, \"Bad Request\")        unless parse_content_type(ENV['CONTENT_TYPE']).first == \"text/xml\"\n      http_error(411, \"Length Required\")    unless length > 0 \n\n      # TODO: do we need a call to binmode?\n      $stdin.binmode if $stdin.respond_to? :binmode\n      data = $stdin.read(length)\n\n      http_error(400, \"Bad Request\")        if data.nil? or data.size != length\n\n      http_write(process(data), \"Content-type\" => \"text/xml; charset=utf-8\")\n    }\n  end\n\n\n  private\n\n  def http_error(status, message)\n    err = \"#{status} #{message}\"\n    msg = <<-\"MSGEND\" \n      <html>\n        <head>\n          <title>#{err}</title>\n        </head>\n        <body>\n          <h1>#{err}</h1>\n          <p>Unexpected error occured while processing XML-RPC request!</p>\n        </body>\n      </html>\n    MSGEND\n\n    http_write(msg, \"Status\" => err, \"Content-type\" => \"text/html\")\n    throw :exit_serve # exit from the #serve method\n  end\n\n  def http_write(body, header)\n    h = {}\n    header.each {|key, value| h[key.to_s.capitalize] = value}\n    h['Status']         ||= \"200 OK\"\n    h['Content-length'] ||= body.size.to_s \n\n    str = \"\"\n    h.each {|key, value| str << \"#{key}: #{value}\\r\\n\"}\n    str << \"\\r\\n#{body}\"\n\n    print str\n  end\n\nend\n\n=begin\n= XMLRPC::ModRubyServer\n== Description\nImplements a XML-RPC server, which works with Apache mod_ruby.\n\nUse it in the same way as CGIServer!\n\n== Superclass\n((<XMLRPC::BasicServer>))\n=end \n\nclass ModRubyServer < BasicServer\n\n  def initialize(*a)\n    @ap = Apache::request\n    super(*a)\n  end\n\n  def serve\n    catch(:exit_serve) {\n      header = {}\n      @ap.headers_in.each {|key, value| header[key.capitalize] = value}\n\n      length = header['Content-length'].to_i\n\n      http_error(405, \"Method Not Allowed\") unless @ap.request_method  == \"POST\" \n      http_error(400, \"Bad Request\")        unless parse_content_type(header['Content-type']).first == \"text/xml\"\n      http_error(411, \"Length Required\")    unless length > 0 \n\n      # TODO: do we need a call to binmode?\n      @ap.binmode\n      data = @ap.read(length)\n\n      http_error(400, \"Bad Request\")        if data.nil? or data.size != length\n\n      http_write(process(data), 200, \"Content-type\" => \"text/xml; charset=utf-8\")\n    }\n  end\n\n\n  private\n\n  def http_error(status, message)\n    err = \"#{status} #{message}\"\n    msg = <<-\"MSGEND\" \n      <html>\n        <head>\n          <title>#{err}</title>\n        </head>\n        <body>\n          <h1>#{err}</h1>\n          <p>Unexpected error occured while processing XML-RPC request!</p>\n        </body>\n      </html>\n    MSGEND\n\n    http_write(msg, status, \"Status\" => err, \"Content-type\" => \"text/html\")\n    throw :exit_serve # exit from the #serve method\n  end\n\n  def http_write(body, status, header)\n    h = {}\n    header.each {|key, value| h[key.to_s.capitalize] = value}\n    h['Status']         ||= \"200 OK\"\n    h['Content-length'] ||= body.size.to_s \n\n    h.each {|key, value| @ap.headers_out[key] = value }\n    @ap.content_type = h[\"Content-type\"] \n    @ap.status = status.to_i \n    @ap.send_http_header \n\n    @ap.print body\n  end\n\nend\n\n=begin\n= XMLRPC::Server\n== Synopsis\n    require \"xmlrpc/server\"\n \n    s = XMLRPC::Server.new(8080) \n\n    s.add_handler(\"michael.add\") do |a,b|\n      a + b\n    end\n\n    s.add_handler(\"michael.div\") do |a,b|\n      if b == 0\n        raise XMLRPC::FaultException.new(1, \"division by zero\")\n      else\n        a / b \n      end\n    end \n\n    s.set_default_handler do |name, *args|\n      raise XMLRPC::FaultException.new(-99, \"Method #{name} missing\" +\n                                       \" or wrong number of parameters!\")\n    end\n \n    s.serve\n\n== Description\nImplements a standalone XML-RPC server. The method (({serve}))) is left if a SIGHUP is sent to the\nprogram.\n\n== Superclass\n((<XMLRPC::WEBrickServlet>))\n\n== Class Methods\n--- XMLRPC::Server.new( port=8080, host=\"127.0.0.1\", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a )\n    Creates a new (({XMLRPC::Server})) instance, which is a XML-RPC server listening on\n    port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost. \n    The server is not started, to start it you have to call ((<serve|XMLRPC::Server#serve>)).\n\n    Parameters ((|audit|)) and ((|debug|)) are obsolete!\n\n    All additionally given parameters in ((|*a|)) are by-passed to ((<XMLRPC::BasicServer.new>)). \n    \n== Instance Methods\n--- XMLRPC::Server#serve\n    Call this after you have added all you handlers to the server.\n    This method starts the server to listen for XML-RPC requests and answer them.\n\n--- XMLRPC::Server#shutdown\n    Stops and shuts the server down.\n    \n=end\n\nclass WEBrickServlet < BasicServer; end # forward declaration\n\nclass Server < WEBrickServlet\n\n  def initialize(port=8080, host=\"127.0.0.1\", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a)\n    super(*a)\n    require 'webrick'\n    @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections, \n                                      :Logger => WEBrick::Log.new(stdlog))\n    @server.mount(\"/\", self)\n  end\n  \n  def serve\n    if RUBY_PLATFORM =~ /mingw|mswin32/\n      signals = [1]\n    else\n      signals = %w[INT TERM HUP]\n    end\n    signals.each { |signal| trap(signal) { @server.shutdown } }\n\n    @server.start\n  end\n  \n  def shutdown\n    @server.shutdown\n  end\n \nend\n\n=begin\n= XMLRPC::WEBrickServlet\n== Synopsis\n\n    require \"webrick\"\n    require \"xmlrpc/server\"\n\n    s = XMLRPC::WEBrickServlet.new\n    s.add_handler(\"michael.add\") do |a,b|\n      a + b\n    end\n\n    s.add_handler(\"michael.div\") do |a,b|\n      if b == 0\n        raise XMLRPC::FaultException.new(1, \"division by zero\")\n      else\n        a / b \n      end\n    end \n\n    s.set_default_handler do |name, *args|\n      raise XMLRPC::FaultException.new(-99, \"Method #{name} missing\" +\n                                       \" or wrong number of parameters!\")\n    end\n\n    httpserver = WEBrick::HTTPServer.new(:Port => 8080)    \n    httpserver.mount(\"/RPC2\", s)\n    trap(\"HUP\") { httpserver.shutdown }   # use 1 instead of \"HUP\" on Windows\n    httpserver.start\n\n== Instance Methods\n\n--- XMLRPC::WEBrickServlet#set_valid_ip( *ip_addr )\n    Specifies the valid IP addresses that are allowed to connect to the server.\n    Each IP is either a (({String})) or a (({Regexp})).\n\n--- XMLRPC::WEBrickServlet#get_valid_ip\n    Return the via method ((<set_valid_ip|XMLRPC::Server#set_valid_ip>)) specified\n    valid IP addresses.\n \n== Description\nImplements a servlet for use with WEBrick, a pure Ruby (HTTP-) server framework.\n\n== Superclass\n((<XMLRPC::BasicServer>))\n\n=end\n\nclass WEBrickServlet < BasicServer\n  def initialize(*a)\n    super\n    require \"webrick/httpstatus\"\n    @valid_ip = nil\n  end\n\n  # deprecated from WEBrick/1.2.2. \n  # but does not break anything.\n  def require_path_info?\n    false \n  end\n\n  def get_instance(config, *options)\n    # TODO: set config & options\n    self\n  end\n\n  def set_valid_ip(*ip_addr)\n    if ip_addr.size == 1 and ip_addr[0].nil?\n      @valid_ip = nil\n    else\n      @valid_ip = ip_addr\n    end\n  end\n\n  def get_valid_ip\n    @valid_ip\n  end\n\n  def service(request, response)\n\n    if @valid_ip \n      raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }\n    end\n\n    if request.request_method != \"POST\"\n      raise WEBrick::HTTPStatus::MethodNotAllowed,\n            \"unsupported method `#{request.request_method}'.\"\n    end\n\n    if parse_content_type(request['Content-type']).first != \"text/xml\" \n      raise WEBrick::HTTPStatus::BadRequest\n    end \n\n    length = (request['Content-length'] || 0).to_i\n\n    raise WEBrick::HTTPStatus::LengthRequired unless length > 0\n\n    data = request.body\n\n    if data.nil? or data.size != length\n      raise WEBrick::HTTPStatus::BadRequest\n    end\n\n    resp = process(data)\n    if resp.nil? or resp.size <= 0  \n      raise WEBrick::HTTPStatus::InternalServerError\n    end\n\n    response.status = 200\n    response['Content-Length'] = resp.size\n    response['Content-Type']   = \"text/xml; charset=utf-8\"\n    response.body = resp \n  end\nend\n\n\nend # module XMLRPC\n\n\n=begin\n= History\n    $Id$    \n=end\n\n"
  },
  {
    "path": "lib/xmlrpc/utils.rb",
    "content": "#\n# Defines ParserWriterChooseMixin, which makes it possible to choose a\n# different XML writer and/or XML parser then the default one.\n# The Mixin is used in client.rb (class Client) and server.rb (class \n# BasicServer)\n# \n# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)\n#\n# $Id$ \n#\n\nmodule XMLRPC\n\n  #\n  # This module enables a user-class to be marshalled\n  # by XML-RPC for Ruby into a Hash, with one additional\n  # key/value pair \"___class___\" => ClassName\n  # \n  module Marshallable\n  end\n\n\n  module ParserWriterChooseMixin\n\n    def set_writer(writer)\n      @create = Create.new(writer)\n      self\n    end\n\n    def set_parser(parser)\n      @parser = parser\n      self\n    end\n\n    private\n\n    def create\n      # if set_writer was not already called then call it now\n      if @create.nil? then\n\tset_writer(Config::DEFAULT_WRITER.new)\n      end\n      @create\n    end\n\n    def parser\n      # if set_parser was not already called then call it now\n      if @parser.nil? then\n\tset_parser(Config::DEFAULT_PARSER.new)\n      end\n      @parser\n    end\n\n  end # module ParserWriterChooseMixin\n\n\n  module Service\n\n  #\n  # base class for Service Interface definitions, used\n  # by BasicServer#add_handler\n  #\n\n  class BasicInterface\n    attr_reader :prefix, :methods\n\n    def initialize(prefix)\n      @prefix = prefix\n      @methods = []\n    end\n\n    def add_method(sig, help=nil, meth_name=nil)\n      mname = nil\n      sig = [sig] if sig.kind_of? String\n\n      sig = sig.collect do |s| \n        name, si = parse_sig(s)\n        raise \"Wrong signatures!\" if mname != nil and name != mname \n        mname = name\n        si\n      end\n\n      @methods << [mname, meth_name || mname, sig, help]\n    end\n\n    private # ---------------------------------\n  \n    def parse_sig(sig)\n      # sig is a String\n      if sig =~ /^\\s*(\\w+)\\s+([^(]+)(\\(([^)]*)\\))?\\s*$/\n        params = [$1]\n        name   = $2.strip \n        $4.split(\",\").each {|i| params << i.strip} if $4 != nil\n        return name, params\n      else\n        raise \"Syntax error in signature\"\n      end\n    end\n\n  end # class BasicInterface\n\n  #\n  # class which wraps a Service Interface definition, used\n  # by BasicServer#add_handler\n  #\n  class Interface < BasicInterface\n    def initialize(prefix, &p)\n      raise \"No interface specified\" if p.nil?\n      super(prefix)\n      instance_eval(&p)\n    end\n\n    def get_methods(obj, delim=\".\") \n      prefix = @prefix + delim\n      @methods.collect { |name, meth, sig, help| \n        [prefix + name, obj.method(meth).to_proc, sig, help] \n      }\n    end\n\n    private # ---------------------------------\n\n    def meth(*a)\n      add_method(*a)\n    end\n\n  end # class Interface\n\n  class PublicInstanceMethodsInterface < BasicInterface\n    def initialize(prefix)\n      super(prefix)\n    end\n\n    def get_methods(obj, delim=\".\")\n      prefix = @prefix + delim\n      obj.class.public_instance_methods(false).collect { |name|\n        [prefix + name, obj.method(name).to_proc, nil, nil] \n      }\n    end\n  end\n\n\n  end # module Service\n\n\n  # \n  # short-form to create a Service::Interface\n  #\n  def self.interface(prefix, &p)\n    Service::Interface.new(prefix, &p)  \n  end\n\n  # short-cut for creating a PublicInstanceMethodsInterface\n  def self.iPIMethods(prefix)\n    Service::PublicInstanceMethodsInterface.new(prefix) \n  end\n\n\n  module ParseContentType\n    def parse_content_type(str)\n      a, *b = str.split(\";\")\n      return a.strip.downcase, *b\n    end\n  end\n\nend # module XMLRPC\n\n"
  },
  {
    "path": "lib/xsd/charset.rb",
    "content": "# XSD4R - Charset handling library.\n# Copyright (C) 2001, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule XSD\n\n\nmodule Charset\n  @internal_encoding = $KCODE\n\n  class XSDError < StandardError; end\n  class CharsetError < XSDError; end\n  class UnknownCharsetError < CharsetError; end\n  class CharsetConversionError < CharsetError; end\n\npublic\n\n  ###\n  ## Maps\n  #\n  EncodingConvertMap = {}\n  def Charset.init\n    EncodingConvertMap[['UTF8', 'X_ISO8859_1']] =\n      Proc.new { |str| str.unpack('U*').pack('C*') }\n    EncodingConvertMap[['X_ISO8859_1', 'UTF8']] =\n      Proc.new { |str| str.unpack('C*').pack('U*') }\n    begin\n      require 'xsd/iconvcharset'\n      @internal_encoding = 'UTF8'\n      sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' :\n        'shift_jis'\n      EncodingConvertMap[['UTF8', 'EUC' ]] =\n        Proc.new { |str| IconvCharset.safe_iconv(\"euc-jp\", \"utf-8\", str) }\n      EncodingConvertMap[['EUC' , 'UTF8']] =\n        Proc.new { |str| IconvCharset.safe_iconv(\"utf-8\", \"euc-jp\", str) }\n      EncodingConvertMap[['EUC' , 'SJIS']] =\n        Proc.new { |str| IconvCharset.safe_iconv(sjtag, \"euc-jp\", str) }\n      EncodingConvertMap[['UTF8', 'SJIS']] =\n        Proc.new { |str| IconvCharset.safe_iconv(sjtag, \"utf-8\", str) }\n      EncodingConvertMap[['SJIS', 'UTF8']] =\n        Proc.new { |str| IconvCharset.safe_iconv(\"utf-8\", sjtag, str) }\n      EncodingConvertMap[['SJIS', 'EUC' ]] =\n        Proc.new { |str| IconvCharset.safe_iconv(\"euc-jp\", sjtag, str) }\n    rescue LoadError\n      begin\n       \trequire 'nkf'\n\tEncodingConvertMap[['EUC' , 'SJIS']] =\n          Proc.new { |str| NKF.nkf('-sXm0', str) }\n\tEncodingConvertMap[['SJIS', 'EUC' ]] =\n          Proc.new { |str| NKF.nkf('-eXm0', str) }\n      rescue LoadError\n      end\n  \n      begin\n\trequire 'uconv'\n\t@internal_encoding = 'UTF8'\n\tEncodingConvertMap[['UTF8', 'EUC' ]] = Uconv.method(:u8toeuc)\n\tEncodingConvertMap[['UTF8', 'SJIS']] = Uconv.method(:u8tosjis)\n\tEncodingConvertMap[['EUC' , 'UTF8']] = Uconv.method(:euctou8)\n\tEncodingConvertMap[['SJIS', 'UTF8']] = Uconv.method(:sjistou8)\n      rescue LoadError\n      end\n    end\n  end\n  self.init\n\n  CharsetMap = {\n    'NONE' => 'us-ascii',\n    'EUC' => 'euc-jp',\n    'SJIS' => 'shift_jis',\n    'UTF8' => 'utf-8',\n    'X_ISO_8859_1' => 'iso-8859-1',\n    'X_UNKNOWN' => nil,\n  }\n\n\n  ###\n  ## handlers\n  #\n  def Charset.encoding\n    @internal_encoding\n  end\n\n  def Charset.encoding=(encoding)\n    warn(\"xsd charset is set to #{encoding}\") if $DEBUG\n    @internal_encoding = encoding\n  end\n\n  def Charset.xml_encoding_label\n    charset_label(@internal_encoding)\n  end\n\n  def Charset.encoding_to_xml(str, charset)\n    encoding_conv(str, @internal_encoding, charset_str(charset))\n  end\n\n  def Charset.encoding_from_xml(str, charset)\n    encoding_conv(str, charset_str(charset), @internal_encoding)\n  end\n\n  def Charset.encoding_conv(str, enc_from, enc_to)\n    if enc_from == enc_to or enc_from == 'NONE' or enc_to == 'NONE'\n      str\n    elsif converter = EncodingConvertMap[[enc_from, enc_to]]\n      converter.call(str)\n    else\n      raise CharsetConversionError.new(\n\t\"Converter not found: #{enc_from} -> #{enc_to}\")\n    end\n  end\n\n  def Charset.charset_label(encoding)\n    CharsetMap[encoding.upcase]\n  end\n\n  def Charset.charset_str(label)\n    if CharsetMap.respond_to?(:key)\n      CharsetMap.key(label.downcase) || 'X_UNKNOWN'\n    else\n      CharsetMap.index(label.downcase) || 'X_UNKNOWN'\n    end\n  end\n\n  # us_ascii = '[\\x00-\\x7F]'\n  us_ascii = '[\\x9\\xa\\xd\\x20-\\x7F]'\t# XML 1.0 restricted.\n  USASCIIRegexp = Regexp.new(\"\\\\A#{us_ascii}*\\\\z\", nil, \"NONE\")\n\n  twobytes_euc = '(?:[\\x8E\\xA1-\\xFE][\\xA1-\\xFE])'\n  threebytes_euc = '(?:\\x8F[\\xA1-\\xFE][\\xA1-\\xFE])'\n  character_euc = \"(?:#{us_ascii}|#{twobytes_euc}|#{threebytes_euc})\"\n  EUCRegexp = Regexp.new(\"\\\\A#{character_euc}*\\\\z\", nil, \"NONE\")\n\n  # onebyte_sjis = '[\\x00-\\x7F\\xA1-\\xDF]'\n  onebyte_sjis = '[\\x9\\xa\\xd\\x20-\\x7F\\xA1-\\xDF]'\t# XML 1.0 restricted.\n  twobytes_sjis = '(?:[\\x81-\\x9F\\xE0-\\xFC][\\x40-\\x7E\\x80-\\xFC])'\n  character_sjis = \"(?:#{onebyte_sjis}|#{twobytes_sjis})\"\n  SJISRegexp = Regexp.new(\"\\\\A#{character_sjis}*\\\\z\", nil, \"NONE\")\n\n  # 0xxxxxxx\n  # 110yyyyy 10xxxxxx\n  twobytes_utf8 = '(?:[\\xC0-\\xDF][\\x80-\\xBF])'\n  # 1110zzzz 10yyyyyy 10xxxxxx\n  threebytes_utf8 = '(?:[\\xE0-\\xEF][\\x80-\\xBF][\\x80-\\xBF])'\n  # 11110uuu 10uuuzzz 10yyyyyy 10xxxxxx\n  fourbytes_utf8 = '(?:[\\xF0-\\xF7][\\x80-\\xBF][\\x80-\\xBF][\\x80-\\xBF])'\n  character_utf8 =\n    \"(?:#{us_ascii}|#{twobytes_utf8}|#{threebytes_utf8}|#{fourbytes_utf8})\"\n  UTF8Regexp = Regexp.new(\"\\\\A#{character_utf8}*\\\\z\", nil, \"NONE\")\n\n  def Charset.is_us_ascii(str)\n    USASCIIRegexp =~ str\n  end\n\n  def Charset.is_utf8(str)\n    UTF8Regexp =~ str\n  end\n\n  def Charset.is_euc(str)\n    EUCRegexp =~ str\n  end\n\n  def Charset.is_sjis(str)\n    SJISRegexp =~ str\n  end\n\n  def Charset.is_ces(str, code = $KCODE)\n    case code\n    when 'NONE'\n      is_us_ascii(str)\n    when 'UTF8'\n      is_utf8(str)\n    when 'EUC'\n      is_euc(str)\n    when 'SJIS'\n      is_sjis(str)\n    else\n      raise UnknownCharsetError.new(\"Unknown charset: #{code}\")\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/xsd/codegen/classdef.rb",
    "content": "# XSD4R - Generating class definition code\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\nrequire 'xsd/codegen/moduledef'\nrequire 'xsd/codegen/methoddef'\n\n\nmodule XSD\nmodule CodeGen\n\n\nclass ClassDef < ModuleDef\n  include GenSupport\n\n  def initialize(name, baseclass = nil)\n    super(name)\n    @baseclass = baseclass\n    @classvar = []\n    @attrdef = []\n  end\n\n  def def_classvar(var, value)\n    var = var.sub(/\\A@@/, \"\")\n    unless safevarname?(var)\n      raise ArgumentError.new(\"#{var} seems to be unsafe\")\n    end\n    @classvar << [var, value]\n  end\n\n  def def_attr(attrname, writable = true, varname = nil)\n    unless safevarname?(varname || attrname)\n      raise ArgumentError.new(\"#{varname || attrname} seems to be unsafe\")\n    end\n    @attrdef << [attrname, writable, varname]\n  end\n\n  def dump\n    buf = \"\"\n    unless @requirepath.empty?\n      buf << dump_requirepath \n    end\n    buf << dump_emptyline unless buf.empty?\n    package = @name.split(/::/)[0..-2]\n    buf << dump_package_def(package) unless package.empty?\n    buf << dump_comment if @comment\n    buf << dump_class_def\n    spacer = false\n    unless @classvar.empty?\n      spacer = true\n      buf << dump_classvar\n    end\n    unless @const.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_const\n    end\n    unless @code.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_code\n    end\n    unless @attrdef.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_attributes\n    end\n    unless @methoddef.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_methods\n    end\n    buf << dump_class_def_end\n    buf << dump_package_def_end(package) unless package.empty?\n    buf.gsub(/^\\s+$/, '')\n  end\n\nprivate\n\n  def dump_class_def\n    name = @name.to_s.split(/::/)\n    if @baseclass\n      format(\"class #{name.last} < #{@baseclass}\")\n    else\n      format(\"class #{name.last}\")\n    end\n  end\n\n  def dump_class_def_end\n    str = format(\"end\")\n  end\n\n  def dump_classvar\n    dump_static(\n      @classvar.collect { |var, value|\n        %Q(@@#{var.sub(/^@@/, \"\")} = #{dump_value(value)})\n      }.join(\"\\n\")\n    )\n  end\n\n  def dump_attributes\n    str = \"\"\n    @attrdef.each do |attrname, writable, varname|\n      varname ||= attrname\n      if attrname == varname\n        str << format(dump_accessor(attrname, writable), 2)\n      end\n    end\n    @attrdef.each do |attrname, writable, varname|\n      varname ||= attrname\n      if attrname != varname\n        str << \"\\n\" unless str.empty?\n        str << format(dump_attribute(attrname, writable, varname), 2)\n      end\n    end\n    str\n  end\n\n  def dump_accessor(attrname, writable)\n    if writable\n      \"attr_accessor :#{attrname}\"\n    else\n      \"attr_reader :#{attrname}\"\n    end\n  end\n\n  def dump_attribute(attrname, writable, varname)\n    str = nil\n    mr = MethodDef.new(attrname)\n    mr.definition = \"@#{varname}\"\n    str = mr.dump\n    if writable\n      mw = MethodDef.new(attrname + \"=\", 'value')\n      mw.definition = \"@#{varname} = value\"\n      str << \"\\n\" + mw.dump\n    end\n    str\n  end\nend\n\n\nend\nend\n\n\nif __FILE__ == $0\n  require 'xsd/codegen/classdef'\n  include XSD::CodeGen\n  c = ClassDef.new(\"Foo::Bar::HobbitName\", String)\n  c.def_require(\"foo/bar\")\n  c.comment = <<-EOD\n      foo\n    bar\n      baz\n  EOD\n  c.def_const(\"FOO\", 1)\n  c.def_classvar(\"@@foo\", \"var\".dump)\n  c.def_classvar(\"baz\", \"1\".dump)\n  c.def_attr(\"Foo\", true, \"foo\")\n  c.def_attr(\"bar\")\n  c.def_attr(\"baz\", true)\n  c.def_attr(\"Foo2\", true, \"foo2\")\n  c.def_attr(\"foo3\", false, \"foo3\")\n  c.def_method(\"foo\") do\n    <<-EOD\n        foo.bar = 1\n\\tbaz.each do |ele|\n\\t  ele\n        end\n    EOD\n  end\n  c.def_method(\"baz\", \"qux\") do\n    <<-EOD\n      [1, 2, 3].each do |i|\n        p i\n      end\n    EOD\n  end\n\n  m = MethodDef.new(\"qux\", \"quxx\", \"quxxx\") do\n    <<-EOD\n    p quxx + quxxx\n    EOD\n  end\n  m.comment = \"hello world\\n123\"\n  c.add_method(m)\n  c.def_code <<-EOD\n    Foo.new\n    Bar.z\n  EOD\n  c.def_code <<-EOD\n    Foo.new\n    Bar.z\n  EOD\n  c.def_privatemethod(\"foo\", \"baz\", \"*arg\", \"&block\")\n\n  puts c.dump\nend\n"
  },
  {
    "path": "lib/xsd/codegen/commentdef.rb",
    "content": "# XSD4R - Generating comment definition code\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\n\n\nmodule XSD\nmodule CodeGen\n\n\nmodule CommentDef\n  include GenSupport\n\n  attr_accessor :comment\n\nprivate\n\n  def dump_comment\n    if /\\A#/ =~ @comment\n      format(@comment)\n    else\n      format(@comment).gsub(/^/, '# ')\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/codegen/gensupport.rb",
    "content": "# XSD4R - Code generation support\n# Copyright (C) 2004, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule XSD\nmodule CodeGen\n\n# from the file 'keywords' in 1.9.\nKEYWORD = {}\n%w(\n__LINE__\n__FILE__\nBEGIN\nEND\nalias\nand\nbegin\nbreak\ncase\nclass\ndef\ndefined?\ndo\nelse\nelsif\nend\nensure\nfalse\nfor\nif\nin\nmodule\nnext\nnil\nnot\nor\nredo\nrescue\nretry\nreturn\nself\nsuper\nthen\ntrue\nundef\nunless\nuntil\nwhen\nwhile\nyield\n).each { |k| KEYWORD[k] = nil }\n\nmodule GenSupport\n  def capitalize(target)\n    target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') }\n  end\n  module_function :capitalize\n\n  def uncapitalize(target)\n    target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') }\n  end\n  module_function :uncapitalize\n\n  def safeconstname(name)\n    safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele|\n      GenSupport.capitalize(ele)\n    }.join\n    if /^[A-Z]/ !~ safename or keyword?(safename)\n      safename = \"C_#{safename}\"\n    end\n    safename\n  end\n  module_function :safeconstname\n\n  def safeconstname?(name)\n    /\\A[A-Z][a-zA-Z0-9_]*\\z/ =~ name and !keyword?(name)\n  end\n  module_function :safeconstname?\n\n  def safemethodname(name)\n    safename = name.scan(/[a-zA-Z0-9_]+/).join('_')\n    safename = uncapitalize(safename)\n    if /^[a-z]/ !~ safename\n      safename = \"m_#{safename}\"\n    end\n    safename\n  end\n  module_function :safemethodname\n\n  def safemethodname?(name)\n    /\\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\\z/ =~ name\n  end\n  module_function :safemethodname?\n\n  def safevarname(name)\n    safename = uncapitalize(name.scan(/[a-zA-Z0-9_]+/).join('_'))\n    if /^[a-z]/ !~ safename or keyword?(safename)\n      \"v_#{safename}\"\n    else\n      safename\n    end\n  end\n  module_function :safevarname\n\n  def safevarname?(name)\n    /\\A[a-z_][a-zA-Z0-9_]*\\z/ =~ name and !keyword?(name)\n  end\n  module_function :safevarname?\n\n  def keyword?(word)\n    KEYWORD.key?(word)\n  end\n  module_function :keyword?\n\n  def format(str, indent = nil)\n    str = trim_eol(str)\n    str = trim_indent(str)\n    if indent\n      str.gsub(/^/, \" \" * indent)\n    else\n      str\n    end\n  end\n\nprivate\n\n  def trim_eol(str)\n    str.collect { |line|\n      line.sub(/\\r?\\n\\z/, \"\") + \"\\n\"\n    }.join\n  end\n\n  def trim_indent(str)\n    indent = nil\n    str = str.collect { |line| untab(line) }.join\n    str.each do |line|\n      head = line.index(/\\S/)\n      if !head.nil? and (indent.nil? or head < indent)\n        indent = head\n      end\n    end\n    return str unless indent\n    str.collect { |line|\n      line.sub(/^ {0,#{indent}}/, \"\")\n    }.join\n  end\n\n  def untab(line, ts = 8)\n    while pos = line.index(/\\t/)\n      line = line.sub(/\\t/, \" \" * (ts - (pos % ts)))\n    end\n    line\n  end\n\n  def dump_emptyline\n    \"\\n\"\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/codegen/methoddef.rb",
    "content": "# XSD4R - Generating method definition code\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\nrequire 'xsd/codegen/commentdef'\n\n\nmodule XSD\nmodule CodeGen\n\n\nclass MethodDef\n  include GenSupport\n  include CommentDef\n\n  attr_accessor :definition\n\n  def initialize(name, *params)\n    unless safemethodname?(name)\n      raise ArgumentError.new(\"name '#{name}' seems to be unsafe\")\n    end\n    @name = name\n    @params = params\n    @comment = nil\n    @definition = yield if block_given?\n  end\n\n  def dump\n    buf = \"\"\n    buf << dump_comment if @comment\n    buf << dump_method_def\n    buf << dump_definition if @definition and !@definition.empty?\n    buf << dump_method_def_end\n    buf\n  end\n\nprivate\n\n  def dump_method_def\n    if @params.empty?\n      format(\"def #{@name}\")\n    else\n      format(\"def #{@name}(#{@params.join(\", \")})\")\n    end\n  end\n\n  def dump_method_def_end\n    format(\"end\")\n  end\n\n  def dump_definition\n    format(@definition, 2)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/codegen/moduledef.rb",
    "content": "# XSD4R - Generating module definition code\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\nrequire 'xsd/codegen/methoddef'\nrequire 'xsd/codegen/commentdef'\n\n\nmodule XSD\nmodule CodeGen\n\n\nclass ModuleDef\n  include GenSupport\n  include CommentDef\n\n  def initialize(name)\n    @name = name\n    @comment = nil\n    @const = []\n    @code = []\n    @requirepath = []\n    @methoddef = []\n  end\n\n  def def_require(path)\n    @requirepath << path\n  end\n\n  def def_const(const, value)\n    unless safeconstname?(const)\n      raise ArgumentError.new(\"#{const} seems to be unsafe\")\n    end\n    @const << [const, value]\n  end\n\n  def def_code(code)\n    @code << code\n  end\n\n  def def_method(name, *params)\n    add_method(MethodDef.new(name, *params) { yield if block_given? }, :public)\n  end\n  alias def_publicmethod def_method\n\n  def def_protectedmethod(name, *params)\n    add_method(MethodDef.new(name, *params) { yield if block_given? },\n      :protected)\n  end\n\n  def def_privatemethod(name, *params)\n    add_method(MethodDef.new(name, *params) { yield if block_given? }, :private)\n  end\n\n  def add_method(m, visibility = :public)\n    @methoddef << [visibility, m]\n  end\n\n  def dump\n    buf = \"\"\n    unless @requirepath.empty?\n      buf << dump_requirepath \n    end\n    buf << dump_emptyline unless buf.empty?\n    package = @name.split(/::/)[0..-2]\n    buf << dump_package_def(package) unless package.empty?\n    buf << dump_comment if @comment\n    buf << dump_module_def\n    spacer = false\n    unless @const.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_const\n    end\n    unless @code.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_code\n    end\n    unless @methoddef.empty?\n      buf << dump_emptyline if spacer\n      spacer = true\n      buf << dump_methods\n    end\n    buf << dump_module_def_end\n    buf << dump_package_def_end(package) unless package.empty?\n    buf.gsub(/^\\s+$/, '')\n  end\n\nprivate\n\n  def dump_requirepath\n    format(\n      @requirepath.collect { |path|\n        %Q(require '#{path}')\n      }.join(\"\\n\")\n    )\n  end\n\n  def dump_const\n    dump_static(\n      @const.sort.collect { |var, value|\n        %Q(#{var} = #{dump_value(value)})\n      }.join(\"\\n\")\n    )\n  end\n\n  def dump_code\n    dump_static(@code.join(\"\\n\"))\n  end\n\n  def dump_static(str)\n    format(str, 2)\n  end\n\n  def dump_methods\n    methods = {}\n    @methoddef.each do |visibility, method|\n      (methods[visibility] ||= []) << method\n    end\n    str = \"\"\n    [:public, :protected, :private].each do |visibility|\n      if methods[visibility]\n        str << \"\\n\" unless str.empty?\n        str << visibility.to_s << \"\\n\\n\" unless visibility == :public\n        str << methods[visibility].collect { |m| format(m.dump, 2) }.join(\"\\n\")\n      end\n    end\n    str\n  end\n\n  def dump_value(value)\n    if value.respond_to?(:to_src)\n      value.to_src\n    else\n      value\n    end\n  end\n\n  def dump_package_def(package)\n    format(package.collect { |ele| \"module #{ele}\" }.join(\"; \")) + \"\\n\\n\"\n  end\n\n  def dump_package_def_end(package)\n    \"\\n\\n\" + format(package.collect { |ele| \"end\" }.join(\"; \"))\n  end\n\n  def dump_module_def\n    name = @name.to_s.split(/::/)\n    format(\"module #{name.last}\")\n  end\n\n  def dump_module_def_end\n    format(\"end\")\n  end\nend\n\n\nend\nend\n\n\nif __FILE__ == $0\n  require 'xsd/codegen/moduledef'\n  include XSD::CodeGen\n  m = ModuleDef.new(\"Foo::Bar::HobbitName\")\n  m.def_require(\"foo/bar\")\n  m.def_require(\"baz\")\n  m.comment = <<-EOD\n    foo\n    bar\n    baz\n  EOD\n  m.def_method(\"foo\") do\n    <<-EOD\n      foo.bar = 1\n      baz.each do |ele|\n        ele + 1\n      end\n    EOD\n  end\n  m.def_method(\"baz\", \"qux\")\n  #m.def_protectedmethod(\"aaa\")\n  m.def_privatemethod(\"bbb\")\n  puts m.dump\nend\n"
  },
  {
    "path": "lib/xsd/codegen.rb",
    "content": "# XSD4R - Generating code library\n# Copyright (C) 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/codegen/gensupport'\nrequire 'xsd/codegen/moduledef'\nrequire 'xsd/codegen/classdef'\nrequire 'xsd/codegen/methoddef'\n"
  },
  {
    "path": "lib/xsd/datatypes.rb",
    "content": "# XSD4R - XML Schema Datatype implementation.\n# Copyright (C) 2000, 2001, 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'xsd/charset'\nrequire 'uri'\n\n\n###\n## XMLSchamaDatatypes general definitions.\n#\nmodule XSD\n\n\nNamespace = 'http://www.w3.org/2001/XMLSchema'\nInstanceNamespace = 'http://www.w3.org/2001/XMLSchema-instance'\n\nAttrType = 'type'\nNilValue = 'true'\n\nAnyTypeLiteral = 'anyType'\nAnySimpleTypeLiteral = 'anySimpleType'\nNilLiteral = 'nil'\nStringLiteral = 'string'\nBooleanLiteral = 'boolean'\nDecimalLiteral = 'decimal'\nFloatLiteral = 'float'\nDoubleLiteral = 'double'\nDurationLiteral = 'duration'\nDateTimeLiteral = 'dateTime'\nTimeLiteral = 'time'\nDateLiteral = 'date'\nGYearMonthLiteral = 'gYearMonth'\nGYearLiteral = 'gYear'\nGMonthDayLiteral = 'gMonthDay'\nGDayLiteral = 'gDay'\nGMonthLiteral = 'gMonth'\nHexBinaryLiteral = 'hexBinary'\nBase64BinaryLiteral = 'base64Binary'\nAnyURILiteral = 'anyURI'\nQNameLiteral = 'QName'\n\nNormalizedStringLiteral = 'normalizedString'\n#3.3.2 token\n#3.3.3 language\n#3.3.4 NMTOKEN\n#3.3.5 NMTOKENS\n#3.3.6 Name\n#3.3.7 NCName\n#3.3.8 ID\n#3.3.9 IDREF\n#3.3.10 IDREFS\n#3.3.11 ENTITY\n#3.3.12 ENTITIES\nIntegerLiteral = 'integer'\nNonPositiveIntegerLiteral = 'nonPositiveInteger'\nNegativeIntegerLiteral = 'negativeInteger'\nLongLiteral = 'long'\nIntLiteral = 'int'\nShortLiteral = 'short'\nByteLiteral = 'byte'\nNonNegativeIntegerLiteral = 'nonNegativeInteger'\nUnsignedLongLiteral = 'unsignedLong'\nUnsignedIntLiteral = 'unsignedInt'\nUnsignedShortLiteral = 'unsignedShort'\nUnsignedByteLiteral = 'unsignedByte'\nPositiveIntegerLiteral = 'positiveInteger'\n\nAttrTypeName = QName.new(InstanceNamespace, AttrType)\nAttrNilName = QName.new(InstanceNamespace, NilLiteral)\n\nAnyTypeName = QName.new(Namespace, AnyTypeLiteral)\nAnySimpleTypeName = QName.new(Namespace, AnySimpleTypeLiteral)\n\nclass Error < StandardError; end\nclass ValueSpaceError < Error; end\n\n\n###\n## The base class of all datatypes with Namespace.\n#\nclass NSDBase\n  @@types = []\n\n  attr_accessor :type\n\n  def self.inherited(klass)\n    @@types << klass\n  end\n\n  def self.types\n    @@types\n  end\n\n  def initialize\n  end\n\n  def init(type)\n    @type = type\n  end\nend\n\n\n###\n## The base class of XSD datatypes.\n#\nclass XSDAnySimpleType < NSDBase\n  include XSD\n  Type = QName.new(Namespace, AnySimpleTypeLiteral)\n\n  # @data represents canonical space (ex. Integer: 123).\n  attr_reader :data\n  # @is_nil represents this data is nil or not.\n  attr_accessor :is_nil\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\n  # true or raise\n  def check_lexical_format(value)\n    screen_data(value)\n    true\n  end\n\n  # set accepts a string which follows lexical space (ex. String: \"+123\"), or\n  # an object which follows canonical space (ex. Integer: 123).\n  def set(value)\n    if value.nil?\n      @is_nil = true\n      @data = nil\n      _set(nil)\n    else\n      @is_nil = false\n      _set(screen_data(value))\n    end\n  end\n\n  # to_s creates a string which follows lexical space (ex. String: \"123\").\n  def to_s()\n    if @is_nil\n      \"\"\n    else\n      _to_s\n    end\n  end\n\nprivate\n\n  def init(type, value)\n    super(type)\n    set(value)\n  end\n\n  # raises ValueSpaceError if check failed\n  def screen_data(value)\n    value\n  end\n\n  def _set(value)\n    @data = value\n  end\n\n  def _to_s\n    @data.to_s\n  end\nend\n\nclass XSDNil < XSDAnySimpleType\n  Type = QName.new(Namespace, NilLiteral)\n  Value = 'true'\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\nend\n\n\n###\n## Primitive datatypes.\n#\nclass XSDString < XSDAnySimpleType\n  Type = QName.new(Namespace, StringLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    unless XSD::Charset.is_ces(value, XSD::Charset.encoding)\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    value\n  end\nend\n\nclass XSDBoolean < XSDAnySimpleType\n  Type = QName.new(Namespace, BooleanLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    if value.is_a?(String)\n      str = value.strip\n      if str == 'true' || str == '1'\n\ttrue\n      elsif str == 'false' || str == '0'\n\tfalse\n      else\n\traise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n      end\n    else\n      value ? true : false\n    end\n  end\nend\n\nclass XSDDecimal < XSDAnySimpleType\n  Type = QName.new(Namespace, DecimalLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\n  def nonzero?\n    (@number != '0')\n  end\n\nprivate\n\n  def screen_data(d)\n    if d.is_a?(String)\n      # Integer(\"00012\") => 10 in Ruby.\n      d.sub!(/^([+\\-]?)0*(?=\\d)/, \"\\\\1\")\n    end\n    screen_data_str(d)\n  end\n\n  def screen_data_str(str)\n    /^([+\\-]?)(\\d*)(?:\\.(\\d*)?)?$/ =~ str.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n    end\n    sign = $1 || '+'\n    int_part = $2\n    frac_part = $3\n    int_part = '0' if int_part.empty?\n    frac_part = frac_part ? frac_part.sub(/0+$/, '') : ''\n    point = - frac_part.size\n    number = int_part + frac_part\n    # normalize\n    if sign == '+'\n      sign = ''\n    elsif sign == '-'\n      if number == '0'\n\tsign = ''\n      end\n    end\n    [sign, point, number]\n  end\n\n  def _set(data)\n    if data.nil?\n      @sign = @point = @number = @data = nil\n      return\n    end\n    @sign, @point, @number = data\n    @data = _to_s\n    @data.freeze\n  end\n\n  # 0.0 -> 0; right?\n  def _to_s\n    str = @number.dup\n    if @point.nonzero?\n      str[@number.size + @point, 0] = '.'\n    end\n    @sign + str\n  end\nend\n\nmodule FloatConstants\n  NaN = 0.0/0.0\n  POSITIVE_INF = +1.0/0.0\n  NEGATIVE_INF = -1.0/0.0\n  POSITIVE_ZERO = +1.0/POSITIVE_INF\n  NEGATIVE_ZERO = -1.0/POSITIVE_INF\n  MIN_POSITIVE_SINGLE = 2.0 ** -149\nend\n\nclass XSDFloat < XSDAnySimpleType\n  include FloatConstants\n  Type = QName.new(Namespace, FloatLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    # \"NaN\".to_f => 0 in some environment.  libc?\n    if value.is_a?(Float)\n      return narrow32bit(value)\n    end\n    str = value.to_s.strip\n    if str == 'NaN'\n      NaN\n    elsif str == 'INF'\n      POSITIVE_INF\n    elsif str == '-INF'\n      NEGATIVE_INF\n    else\n      if /^[+\\-\\.\\deE]+$/ !~ str\n\traise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n      end\n      # Float(\"-1.4E\") might fail on some system.\n      str << '0' if /e$/i =~ str\n      begin\n  \treturn narrow32bit(Float(str))\n      rescue ArgumentError\n  \traise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n      end\n    end\n  end\n\n  def _to_s\n    if @data.nan?\n      'NaN'\n    elsif @data.infinite? == 1\n      'INF'\n    elsif @data.infinite? == -1\n      '-INF'\n    else\n      sign = XSDFloat.positive?(@data) ? '+' : '-'\n      sign + sprintf(\"%.10g\", @data.abs).sub(/[eE]([+-])?0+/) { 'e' + $1 }\n    end\n  end\n\n  # Convert to single-precision 32-bit floating point value.\n  def narrow32bit(f)\n    if f.nan? || f.infinite?\n      f\n    elsif f.abs < MIN_POSITIVE_SINGLE\n      XSDFloat.positive?(f) ? POSITIVE_ZERO : NEGATIVE_ZERO\n    else\n      f\n    end\n  end\n\n  def self.positive?(value)\n    (1 / value) > 0.0\n  end\nend\n\n# Ruby's Float is double-precision 64-bit floating point value.\nclass XSDDouble < XSDAnySimpleType\n  include FloatConstants\n  Type = QName.new(Namespace, DoubleLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    # \"NaN\".to_f => 0 in some environment.  libc?\n    if value.is_a?(Float)\n      return value\n    end\n    str = value.to_s.strip\n    if str == 'NaN'\n      NaN\n    elsif str == 'INF'\n      POSITIVE_INF\n    elsif str == '-INF'\n      NEGATIVE_INF\n    else\n      begin\n\treturn Float(str)\n      rescue ArgumentError\n\t# '1.4e' cannot be parsed on some architecture.\n\tif /e\\z/i =~ str\n\t  begin\n\t    return Float(str + '0')\n\t  rescue ArgumentError\n\t    raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n\t  end\n\telse\n\t  raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n\tend\n      end\n    end\n  end\n\n  def _to_s\n    if @data.nan?\n      'NaN'\n    elsif @data.infinite? == 1\n      'INF'\n    elsif @data.infinite? == -1\n      '-INF'\n    else\n      sign = (1 / @data > 0.0) ? '+' : '-'\n      sign + sprintf(\"%.16g\", @data.abs).sub(/[eE]([+-])?0+/) { 'e' + $1 }\n    end\n  end\nend\n\nclass XSDDuration < XSDAnySimpleType\n  Type = QName.new(Namespace, DurationLiteral)\n\n  attr_accessor :sign\n  attr_accessor :year\n  attr_accessor :month\n  attr_accessor :day\n  attr_accessor :hour\n  attr_accessor :min\n  attr_accessor :sec\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    /^([+\\-]?)P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/ =~ value.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8)))\n      # Should we allow 'PT5S' here?\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    sign = $1\n    year = $2.to_i\n    month = $3.to_i\n    day = $4.to_i\n    hour = $6.to_i\n    min = $7.to_i\n    sec = $8 ? XSDDecimal.new($8) : 0\n    [sign, year, month, day, hour, min, sec]\n  end\n\n  def _set(data)\n    if data.nil?\n      @sign = @year = @month = @day = @hour = @min = @sec = @data = nil\n      return\n    end\n    @sign, @year, @month, @day, @hour, @min, @sec = data\n    @data = _to_s\n    @data.freeze\n  end\n\n  def _to_s\n    str = ''\n    str << @sign if @sign\n    str << 'P'\n    l = ''\n    l << \"#{ @year }Y\" if @year.nonzero?\n    l << \"#{ @month }M\" if @month.nonzero?\n    l << \"#{ @day }D\" if @day.nonzero?\n    r = ''\n    r << \"#{ @hour }H\" if @hour.nonzero?\n    r << \"#{ @min }M\" if @min.nonzero?\n    r << \"#{ @sec }S\" if @sec.nonzero?\n    str << l\n    if l.empty?\n      str << \"0D\"\n    end\n    unless r.empty?\n      str << \"T\" << r\n    end\n    str\n  end\nend\n\n\nrequire 'rational'\nrequire 'date'\n\nmodule XSDDateTimeImpl\n  SecInDay = 86400\t# 24 * 60 * 60\n\n  def to_obj(klass)\n    if klass == Time\n      to_time\n    elsif klass == Date\n      to_date\n    elsif klass == DateTime\n      to_datetime\n    else\n      nil\n    end\n  end\n\n  def to_time\n    begin\n      if @data.offset * SecInDay == Time.now.utc_offset\n        d = @data\n\tusec = (d.sec_fraction * SecInDay * 1000000).round\n        Time.local(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec)\n      else\n        d = @data.newof\n\tusec = (d.sec_fraction * SecInDay * 1000000).round\n        Time.gm(d.year, d.month, d.mday, d.hour, d.min, d.sec, usec)\n      end\n    rescue ArgumentError\n      nil\n    end\n  end\n\n  def to_date\n    Date.new0(@data.class.jd_to_ajd(@data.jd, 0, 0), 0, @data.start)\n  end\n\n  def to_datetime\n    data\n  end\n\n  def tz2of(str)\n    /^(?:Z|(?:([+\\-])(\\d\\d):(\\d\\d))?)$/ =~ str\n    sign = $1\n    hour = $2.to_i\n    min = $3.to_i\n\n    of = case sign\n      when '+'\n\tof = +(hour.to_r * 60 + min) / 1440\t# 24 * 60\n      when '-'\n\tof = -(hour.to_r * 60 + min) / 1440\t# 24 * 60\n      else\n\t0\n      end\n    of\n  end\n\n  def of2tz(offset)\n    diffmin = offset * 24 * 60\n    if diffmin.zero?\n      'Z'\n    else\n      ((diffmin < 0) ? '-' : '+') << format('%02d:%02d',\n    \t(diffmin.abs / 60.0).to_i, (diffmin.abs % 60.0).to_i)\n    end\n  end\n\n  def screen_data(t)\n    # convert t to a DateTime as an internal representation.\n    if t.respond_to?(:to_datetime)      # 1.9 or later\n      t.to_datetime\n    elsif t.is_a?(DateTime)\n      t\n    elsif t.is_a?(Date)\n      t = screen_data_str(t)\n      t <<= 12 if t.year < 0\n      t\n    elsif t.is_a?(Time)\n      jd = DateTime.civil_to_jd(t.year, t.mon, t.mday, DateTime::ITALY)\n      fr = DateTime.time_to_day_fraction(t.hour, t.min, [t.sec, 59].min) +\n        t.usec.to_r / 1000000 / SecInDay\n      of = t.utc_offset.to_r / SecInDay\n      DateTime.new0(DateTime.jd_to_ajd(jd, fr, of), of, DateTime::ITALY)\n    else\n      screen_data_str(t)\n    end\n  end\n\n  def add_tz(s)\n    s + of2tz(@data.offset)\n  end\nend\n\nclass XSDDateTime < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, DateTimeLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^([+\\-]?\\d{4,})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d(?:\\.(\\d*))?)(Z|(?:[+\\-]\\d\\d:\\d\\d)?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    if $1 == '0000'\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    year = $1.to_i\n    if year < 0\n      year += 1\n    end\n    mon = $2.to_i\n    mday = $3.to_i\n    hour = $4.to_i\n    min = $5.to_i\n    sec = $6.to_i\n    secfrac = $7\n    zonestr = $8\n    data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr))\n    if secfrac\n      diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay\n      data += diffday\n      # FYI: new0 and jd_to_rjd are not necessary to use if you don't have\n      # exceptional reason.\n    end\n    [data, secfrac]\n  end\n\n  def _set(data)\n    if data.nil?\n      @data = @secfrac = nil\n      return\n    end\n    @data, @secfrac = data\n  end\n\n  def _to_s\n    year = (@data.year > 0) ? @data.year : @data.year - 1\n    s = format('%.4d-%02d-%02dT%02d:%02d:%02d',\n      year, @data.mon, @data.mday, @data.hour, @data.min, @data.sec)\n    if @data.sec_fraction.nonzero?\n      if @secfrac\n  \ts << \".#{ @secfrac }\"\n      else\n\ts << sprintf(\"%.16f\",\n          (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')\n      end\n    end\n    add_tz(s)\n  end\nend\n\nclass XSDTime < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, TimeLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^(\\d\\d):(\\d\\d):(\\d\\d(?:\\.(\\d*))?)(Z|(?:([+\\-])(\\d\\d):(\\d\\d))?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    hour = $1.to_i\n    min = $2.to_i\n    sec = $3.to_i\n    secfrac = $4\n    zonestr = $5\n    data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr))\n    if secfrac\n      diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay\n      data += diffday\n    end\n    [data, secfrac]\n  end\n\n  def _set(data)\n    if data.nil?\n      @data = @secfrac = nil\n      return\n    end\n    @data, @secfrac = data\n  end\n\n  def _to_s\n    s = format('%02d:%02d:%02d', @data.hour, @data.min, @data.sec)\n    if @data.sec_fraction.nonzero?\n      if @secfrac\n  \ts << \".#{ @secfrac }\"\n      else\n\ts << sprintf(\"%.16f\",\n          (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')\n      end\n    end\n    add_tz(s)\n  end\nend\n\nclass XSDDate < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, DateLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^([+\\-]?\\d{4,})-(\\d\\d)-(\\d\\d)(Z|(?:([+\\-])(\\d\\d):(\\d\\d))?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    year = $1.to_i\n    if year < 0\n      year += 1\n    end\n    mon = $2.to_i\n    mday = $3.to_i\n    zonestr = $4\n    DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr))\n  end\n\n  def _to_s\n    year = (@data.year > 0) ? @data.year : @data.year - 1\n    s = format('%.4d-%02d-%02d', year, @data.mon, @data.mday)\n    add_tz(s)\n  end\nend\n\nclass XSDGYearMonth < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, GYearMonthLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^([+\\-]?\\d{4,})-(\\d\\d)(Z|(?:([+\\-])(\\d\\d):(\\d\\d))?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    year = $1.to_i\n    if year < 0\n      year += 1\n    end\n    mon = $2.to_i\n    zonestr = $3\n    DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr))\n  end\n\n  def _to_s\n    year = (@data.year > 0) ? @data.year : @data.year - 1\n    s = format('%.4d-%02d', year, @data.mon)\n    add_tz(s)\n  end\nend\n\nclass XSDGYear < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, GYearLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^([+\\-]?\\d{4,})(Z|(?:([+\\-])(\\d\\d):(\\d\\d))?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    year = $1.to_i\n    if year < 0\n      year += 1\n    end\n    zonestr = $2\n    DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr))\n  end\n\n  def _to_s\n    year = (@data.year > 0) ? @data.year : @data.year - 1\n    s = format('%.4d', year)\n    add_tz(s)\n  end\nend\n\nclass XSDGMonthDay < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, GMonthDayLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^(\\d\\d)-(\\d\\d)(Z|(?:[+\\-]\\d\\d:\\d\\d)?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    mon = $1.to_i\n    mday = $2.to_i\n    zonestr = $3\n    DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr))\n  end\n\n  def _to_s\n    s = format('%02d-%02d', @data.mon, @data.mday)\n    add_tz(s)\n  end\nend\n\nclass XSDGDay < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, GDayLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^(\\d\\d)(Z|(?:[+\\-]\\d\\d:\\d\\d)?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    mday = $1.to_i\n    zonestr = $2\n    DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr))\n  end\n\n  def _to_s\n    s = format('%02d', @data.mday)\n    add_tz(s)\n  end\nend\n\nclass XSDGMonth < XSDAnySimpleType\n  include XSDDateTimeImpl\n  Type = QName.new(Namespace, GMonthLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(t)\n    /^(\\d\\d)(Z|(?:[+\\-]\\d\\d:\\d\\d)?)?$/ =~ t.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ t }'.\")\n    end\n    mon = $1.to_i\n    zonestr = $2\n    DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr))\n  end\n\n  def _to_s\n    s = format('%02d', @data.mon)\n    add_tz(s)\n  end\nend\n\nclass XSDHexBinary < XSDAnySimpleType\n  Type = QName.new(Namespace, HexBinaryLiteral)\n\n  # String in Ruby could be a binary.\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\n  def set_encoded(value)\n    if /^[0-9a-fA-F]*$/ !~ value\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    @data = String.new(value).strip\n    @is_nil = false\n  end\n\n  def string\n    [@data].pack(\"H*\")\n  end\n\nprivate\n\n  def screen_data(value)\n    value.unpack(\"H*\")[0].tr('a-f', 'A-F')\n  end\nend\n\nclass XSDBase64Binary < XSDAnySimpleType\n  Type = QName.new(Namespace, Base64BinaryLiteral)\n\n  # String in Ruby could be a binary.\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\n  def set_encoded(value)\n    if /^[A-Za-z0-9+\\/=]*$/ !~ value\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    @data = String.new(value).strip\n    @is_nil = false\n  end\n\n  def string\n    @data.unpack(\"m\")[0]\n  end\n\nprivate\n\n  def screen_data(value)\n    [value].pack(\"m\").strip\n  end\nend\n\nclass XSDAnyURI < XSDAnySimpleType\n  Type = QName.new(Namespace, AnyURILiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    begin\n      URI.parse(value.to_s.strip)\n    rescue URI::InvalidURIError\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n  end\nend\n\nclass XSDQName < XSDAnySimpleType\n  Type = QName.new(Namespace, QNameLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    /^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip\n    unless Regexp.last_match\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    prefix = $1\n    localpart = $2\n    [prefix, localpart]\n  end\n\n  def _set(data)\n    if data.nil?\n      @prefix = @localpart = @data = nil\n      return\n    end\n    @prefix, @localpart = data\n    @data = _to_s\n    @data.freeze\n  end\n\n  def _to_s\n    if @prefix\n      \"#{ @prefix }:#{ @localpart }\"\n    else\n      \"#{ @localpart }\"\n    end\n  end\nend\n\n\n###\n## Derived types\n#\nclass XSDNormalizedString < XSDString\n  Type = QName.new(Namespace, NormalizedStringLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data(value)\n    if /[\\t\\r\\n]/ =~ value\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ value }'.\")\n    end\n    super\n  end\nend\n\nclass XSDInteger < XSDDecimal\n  Type = QName.new(Namespace, IntegerLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def screen_data_str(str)\n    begin\n      data = Integer(str)\n    rescue ArgumentError\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n    end\n    unless validate(data)\n      raise ValueSpaceError.new(\"#{ type }: cannot accept '#{ str }'.\")\n    end\n    data\n  end\n\n  def _set(value)\n    @data = value\n  end\n\n  def _to_s()\n    @data.to_s\n  end\n\n  def validate(v)\n    max = maxinclusive\n    min = mininclusive\n    (max.nil? or v <= max) and (min.nil? or v >= min)\n  end\n\n  def maxinclusive\n    nil\n  end\n\n  def mininclusive\n    nil\n  end\n\n  PositiveMinInclusive = 1\n  def positive(v)\n    PositiveMinInclusive <= v\n  end\nend\n\nclass XSDNonPositiveInteger < XSDInteger\n  Type = QName.new(Namespace, NonPositiveIntegerLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    0\n  end\n\n  def mininclusive\n    nil\n  end\nend\n\nclass XSDNegativeInteger < XSDNonPositiveInteger\n  Type = QName.new(Namespace, NegativeIntegerLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    -1\n  end\n\n  def mininclusive\n    nil\n  end\nend\n\nclass XSDLong < XSDInteger\n  Type = QName.new(Namespace, LongLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +9223372036854775807\n  end\n\n  def mininclusive\n    -9223372036854775808\n  end\nend\n\nclass XSDInt < XSDLong\n  Type = QName.new(Namespace, IntLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +2147483647\n  end\n\n  def mininclusive\n    -2147483648\n  end\nend\n\nclass XSDShort < XSDInt\n  Type = QName.new(Namespace, ShortLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +32767\n  end\n\n  def mininclusive\n    -32768\n  end\nend\n\nclass XSDByte < XSDShort\n  Type = QName.new(Namespace, ByteLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +127\n  end\n\n  def mininclusive\n    -128\n  end\nend\n\nclass XSDNonNegativeInteger < XSDInteger\n  Type = QName.new(Namespace, NonNegativeIntegerLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    nil\n  end\n\n  def mininclusive\n    0\n  end\nend\n\nclass XSDUnsignedLong < XSDNonNegativeInteger\n  Type = QName.new(Namespace, UnsignedLongLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +18446744073709551615\n  end\n\n  def mininclusive\n    0\n  end\nend\n\nclass XSDUnsignedInt < XSDUnsignedLong\n  Type = QName.new(Namespace, UnsignedIntLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +4294967295\n  end\n\n  def mininclusive\n    0\n  end\nend\n\nclass XSDUnsignedShort < XSDUnsignedInt\n  Type = QName.new(Namespace, UnsignedShortLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +65535\n  end\n\n  def mininclusive\n    0\n  end\nend\n\nclass XSDUnsignedByte < XSDUnsignedShort\n  Type = QName.new(Namespace, UnsignedByteLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    +255\n  end\n\n  def mininclusive\n    0\n  end\nend\n\nclass XSDPositiveInteger < XSDNonNegativeInteger\n  Type = QName.new(Namespace, PositiveIntegerLiteral)\n\n  def initialize(value = nil)\n    init(Type, value)\n  end\n\nprivate\n\n  def maxinclusive\n    nil\n  end\n\n  def mininclusive\n    1\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/xsd/datatypes1999.rb",
    "content": "# XSD4R - XML Schema Datatype 1999 support\n# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/datatypes'\n\n\nmodule XSD\n  Namespace.replace('http://www.w3.org/1999/XMLSchema')\n  InstanceNamespace.replace('http://www.w3.org/1999/XMLSchema-instance')\n  AnyTypeLiteral.replace('ur-type')\n  AnySimpleTypeLiteral.replace('ur-type')\n  NilLiteral.replace('null')\n  NilValue.replace('1')\n  DateTimeLiteral.replace('timeInstant')\nend\n"
  },
  {
    "path": "lib/xsd/iconvcharset.rb",
    "content": "# XSD4R - Charset handling with iconv.\n# Copyright (C) 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'iconv'\n\n\nmodule XSD\n\n\nclass IconvCharset\n  def self.safe_iconv(to, from, str)\n    iconv = Iconv.new(to, from)\n    out = \"\"\n    begin\n      out << iconv.iconv(str)\n    rescue Iconv::IllegalSequence => e\n      out << e.success\n      ch, str = e.failed.split(//, 2)\n      out << '?'\n      warn(\"Failed to convert #{ch}\")\n      retry\n    end\n    return out\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/xsd/mapping.rb",
    "content": "# XSD4R - XML Mapping for Ruby\n# Copyright (C) 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire \"soap/parser\"\nrequire 'soap/encodingstyle/literalHandler'\nrequire \"soap/generator\"\nrequire \"soap/mapping\"\nrequire \"soap/mapping/wsdlliteralregistry\"\n\n\nmodule XSD\n\n\nmodule Mapping\n  MappingRegistry = SOAP::Mapping::WSDLLiteralRegistry.new\n  MappingOpt = {:default_encodingstyle => SOAP::LiteralNamespace}\n\n  def self.obj2xml(obj, elename = nil, io = nil)\n    if !elename.nil? and !elename.is_a?(XSD::QName)\n      elename = XSD::QName.new(nil, elename)\n    end\n    elename ||= XSD::QName.new(nil, SOAP::Mapping.name2elename(obj.class.to_s))\n    soap = SOAP::Mapping.obj2soap(obj, MappingRegistry)\n    soap.elename = elename\n    generator = SOAP::SOAPGenerator.new(MappingOpt)\n    generator.generate(soap, io)\n  end\n\n  def self.xml2obj(stream)\n    parser = SOAP::Parser.new(MappingOpt)\n    soap = parser.parse(stream)\n    SOAP::Mapping.soap2obj(soap, MappingRegistry)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/xsd/namedelements.rb",
    "content": "# XSD4R - WSDL named element collection.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule XSD\n\n\nclass NamedElements\n  include Enumerable\n\n  def initialize\n    @elements = []\n    @cache = {}\n  end\n\n  def dup\n    o = NamedElements.new\n    o.elements = @elements.dup\n    o\n  end\n\n  def freeze\n    super\n    @elements.freeze\n    self\n  end\n\n  def empty?\n    size == 0\n  end\n\n  def size\n    @elements.size\n  end\n\n  def [](idx)\n    if idx.is_a?(Numeric)\n      @elements[idx]\n    else\n      @cache[idx] ||= @elements.find { |item| item.name == idx }\n    end\n  end\n\n  def find_name(name)\n    @elements.find { |item| item.name.name == name }\n  end\n\n  def keys\n    collect { |element| element.name }\n  end\n\n  def each\n    @elements.each do |element|\n      yield(element)\n    end\n  end\n\n  def <<(rhs)\n    @elements << rhs\n    self\n  end\n  \n  def delete(rhs)\n    @elements.delete(rhs)\n  end\n\n  def +(rhs)\n    o = NamedElements.new\n    o.elements = @elements + rhs.elements\n    o\n  end\n\n  def concat(rhs)\n    @elements.concat(rhs.elements)\n    self\n  end\n\n  Empty = NamedElements.new.freeze\n\nprotected\n\n  def elements=(rhs)\n    @elements = rhs\n  end\n\n  def elements\n    @elements\n  end\nend\n\nend\n"
  },
  {
    "path": "lib/xsd/ns.rb",
    "content": "# XSD4R - XML Schema Namespace library\n# Copyright (C) 2000-2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/datatypes'\n\n\nmodule XSD\n\n\nclass NS\n  class Assigner\n    def initialize\n      @count = 0\n    end\n\n    def assign(ns)\n      @count += 1\n      \"n#{@count}\"\n    end\n  end\n\n  attr_reader :default_namespace\n\n  class FormatError < Error; end\n\npublic\n\n  def initialize(tag2ns = {})\n    @tag2ns = tag2ns\n    @assigner = nil\n    @ns2tag = {}\n    @tag2ns.each do |tag, ns|\n      @ns2tag[ns] = tag\n    end\n    @default_namespace = nil\n  end\n\n  def assign(ns, tag = nil)\n    if (tag == '')\n      @default_namespace = ns\n      tag\n    else\n      @assigner ||= Assigner.new\n      tag ||= @assigner.assign(ns)\n      @ns2tag[ns] = tag\n      @tag2ns[tag] = ns\n      tag\n    end\n  end\n\n  def assigned?(ns)\n    @default_namespace == ns or @ns2tag.key?(ns)\n  end\n\n  def assigned_tag?(tag)\n    @tag2ns.key?(tag)\n  end\n\n  def clone_ns\n    cloned = NS.new(@tag2ns.dup)\n    cloned.assigner = @assigner\n    cloned.assign(@default_namespace, '') if @default_namespace\n    cloned\n  end\n\n  def name(name)\n    if (name.namespace == @default_namespace)\n      name.name\n    elsif @ns2tag.key?(name.namespace)\n      \"#{@ns2tag[name.namespace]}:#{name.name}\"\n    else\n      raise FormatError.new(\"namespace: #{name.namespace} not defined yet\")\n    end\n  end\n\n  def compare(ns, name, rhs)\n    if (ns == @default_namespace)\n      return true if (name == rhs)\n    end\n    @tag2ns.each do |assigned_tag, assigned_ns|\n      if assigned_ns == ns && \"#{assigned_tag}:#{name}\" == rhs\n\treturn true\n      end\n    end\n    false\n  end\n\n  # $1 and $2 are necessary.\n  ParseRegexp = Regexp.new('^([^:]+)(?::(.+))?$')\n\n  def parse(str, local = false)\n    if ParseRegexp =~ str\n      if (name = $2) and (ns = @tag2ns[$1])\n        return XSD::QName.new(ns, name)\n      end\n    end\n    XSD::QName.new(local ? nil : @default_namespace, str)\n  end\n\n  # For local attribute key parsing\n  #   <foo xmlns=\"urn:a\" xmlns:n1=\"urn:a\" bar=\"1\" n1:baz=\"2\" />\n  #     =>\n  #   {}bar, {urn:a}baz\n  def parse_local(elem)\n    ParseRegexp =~ elem\n    if $2\n      ns = @tag2ns[$1]\n      name = $2\n      if !ns\n\traise FormatError.new(\"unknown namespace qualifier: #{$1}\")\n      end\n    elsif $1\n      ns = nil\n      name = $1\n    else\n      raise FormatError.new(\"illegal element format: #{elem}\")\n    end\n    XSD::QName.new(ns, name)\n  end\n\n  def each_ns\n    @ns2tag.each do |ns, tag|\n      yield(ns, tag)\n    end\n  end\n\nprotected\n\n  def assigner=(assigner)\n    @assigner = assigner\n  end\nend\n\n\nend\n"
  },
  {
    "path": "lib/xsd/qname.rb",
    "content": "# XSD4R - XML QName definition.\n# Copyright (C) 2002, 2003, 2004  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nmodule XSD\n\n\nclass QName\n  attr_accessor :namespace\n  attr_accessor :name\n  attr_accessor :source\n\n  def initialize(namespace = nil, name = nil)\n    @namespace = namespace\n    @name = name\n    @source = nil\n  end\n\n  def dup_name(name)\n    XSD::QName.new(@namespace, name)\n  end\n\n  def dump\n    ns = @namespace.nil? ? 'nil' : @namespace.dump\n    name = @name.nil? ? 'nil' : @name.dump\n    \"XSD::QName.new(#{ns}, #{name})\"\n  end\n\n  def match(rhs)\n    if rhs.namespace and (rhs.namespace != @namespace)\n      return false\n    end\n    if rhs.name and (rhs.name != @name)\n      return false\n    end\n    true\n  end\n\n  def ==(rhs)\n    !rhs.nil? and @namespace == rhs.namespace and @name == rhs.name\n  end\n\n  def ===(rhs)\n    (self == rhs)\n  end\n\n  def eql?(rhs)\n    (self == rhs)\n  end\n\n  def hash\n    @namespace.hash ^ @name.hash\n  end\n  \n  def to_s\n    \"{#{ namespace }}#{ name }\"\n  end\n\n  def inspect\n    sprintf(\"#<%s:0x%x %s>\", self.class.name, __id__,\n      \"{#{ namespace }}#{ name }\")\n  end\n\n  NormalizedNameRegexp = /^\\{([^}]*)\\}(.*)$/\n  def parse(str)\n    NormalizedNameRegexp =~ str\n    self.new($1, $2)\n  end\n\n  EMPTY = QName.new.freeze\nend\n\n\nend\n"
  },
  {
    "path": "lib/xsd/xmlparser/parser.rb",
    "content": "# XSD4R - XML Instance parser library.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/qname'\nrequire 'xsd/ns'\nrequire 'xsd/charset'\n\n\nmodule XSD\nmodule XMLParser\n\n\nclass Parser\n  class ParseError < Error; end\n  class FormatDecodeError < ParseError; end\n  class UnknownElementError < FormatDecodeError; end\n  class UnknownAttributeError < FormatDecodeError; end\n  class UnexpectedElementError < FormatDecodeError; end\n  class ElementConstraintError < FormatDecodeError; end\n\n  @@parser_factory = nil\n\n  def self.factory\n    @@parser_factory\n  end\n\n  def self.create_parser(host, opt = {})\n    @@parser_factory.new(host, opt)\n  end\n\n  def self.add_factory(factory)\n    if $DEBUG\n      puts \"Set #{ factory } as XML processor.\"\n    end\n    @@parser_factory = factory\n  end\n\npublic\n\n  attr_accessor :charset\n\n  def initialize(host, opt = {})\n    @host = host\n    @charset = opt[:charset] || nil\n  end\n\n  def parse(string_or_readable)\n    @textbuf = ''\n    prologue\n    do_parse(string_or_readable)\n    epilogue\n  end\n\nprivate\n\n  def do_parse(string_or_readable)\n    raise NotImplementError.new(\n      'Method do_parse must be defined in derived class.')\n  end\n\n  def start_element(name, attrs)\n    @host.start_element(name, attrs)\n  end\n\n  def characters(text)\n    @host.characters(text)\n  end\n\n  def end_element(name)\n    @host.end_element(name)\n  end\n\n  def prologue\n  end\n\n  def epilogue\n  end\n\n  def xmldecl_encoding=(charset)\n    if @charset.nil?\n      @charset = charset\n    else\n      # Definition in a stream (like HTTP) has a priority.\n      p \"encoding definition: #{ charset } is ignored.\" if $DEBUG\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/xmlparser/rexmlparser.rb",
    "content": "# XSD4R - REXMLParser XML parser library.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/xmlparser'\nrequire 'rexml/streamlistener'\nrequire 'rexml/document'\n\n\nmodule XSD\nmodule XMLParser\n\n\nclass REXMLParser < XSD::XMLParser::Parser\n  include REXML::StreamListener\n\n  def do_parse(string_or_readable)\n    source = nil\n    source = REXML::SourceFactory.create_from(string_or_readable)\n    source.encoding = charset if charset\n    # Listener passes a String in utf-8.\n    @charset = 'utf-8'\n    REXML::Document.parse_stream(source, self)\n  end\n\n  def epilogue\n  end\n\n  def tag_start(name, attrs)\n    start_element(name, attrs)\n  end\n\n  def tag_end(name)\n    end_element(name)\n  end\n\n  def text(text)\n    characters(text)\n  end\n\n  def xmldecl(version, encoding, standalone)\n    # Version should be checked.\n  end\n\n  add_factory(self)\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/xmlparser/xmlparser.rb",
    "content": "# XSD4R - XMLParser XML parser library.\n# Copyright (C) 2001, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/xmlparser'\nrequire 'xml/parser'\n\n\nmodule XSD\nmodule XMLParser\n\n\nclass XMLParser < XSD::XMLParser::Parser\n  class Listener < XML::Parser\n    begin\n      require 'xml/encoding-ja'\n      include XML::Encoding_ja\n    rescue LoadError\n      # uconv may not be installed.\n    end\n  end\n\n  def do_parse(string_or_readable)\n    # XMLParser passes a String in utf-8.\n    @charset = 'utf-8'\n    @parser = Listener.new\n    @parser.parse(string_or_readable) do |type, name, data|\n      case type\n      when XML::Parser::START_ELEM\n\tstart_element(name, data)\n      when XML::Parser::END_ELEM\n\tend_element(name)\n      when XML::Parser::CDATA\n\tcharacters(data)\n      else\n\traise FormatDecodeError.new(\"Unexpected XML: #{ type }/#{ name }/#{ data }.\")\n      end\n    end\n  end\n\n  add_factory(self)\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/xmlparser/xmlscanner.rb",
    "content": "# XSD4R - XMLScan XML parser library.\n# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/xmlparser'\nrequire 'xmlscan/scanner'\n\n\nmodule XSD\nmodule XMLParser\n\n\nclass XMLScanner < XSD::XMLParser::Parser\n  include XMLScan::Visitor\n\n  def do_parse(string_or_readable)\n    @attrs = {}\n    @curattr = nil\n    @scanner = XMLScan::XMLScanner.new(self)\n    @scanner.kcode = XSD::Charset.charset_str(charset) if charset\n    @scanner.parse(string_or_readable)\n  end\n\n  def scanner_kcode=(charset)\n    @scanner.kcode = XSD::Charset.charset_str(charset) if charset\n    self.xmldecl_encoding = charset\n  end\n\n  ENTITY_REF_MAP = {\n    'lt' => '<',\n    'gt' => '>',\n    'amp' => '&',\n    'quot' => '\"',\n    'apos' => '\\''\n  }\n\n  def parse_error(msg)\n    raise ParseError.new(msg)\n  end\n\n  def wellformed_error(msg)\n    raise NotWellFormedError.new(msg)\n  end\n\n  def valid_error(msg)\n    raise NotValidError.new(msg)\n  end\n\n  def warning(msg)\n    p msg if $DEBUG\n  end\n\n  # def on_xmldecl; end\n\n  def on_xmldecl_version(str)\n    # 1.0 expected.\n  end\n\n  def on_xmldecl_encoding(str)\n    self.scanner_kcode = str\n  end\n\n  # def on_xmldecl_standalone(str); end\n\n  # def on_xmldecl_other(name, value); end\n\n  # def on_xmldecl_end; end\n\n  # def on_doctype(root, pubid, sysid); end\n\n  # def on_prolog_space(str); end\n\n  # def on_comment(str); end\n\n  # def on_pi(target, pi); end\n\n  def on_chardata(str)\n    characters(str)\n  end\n\n  # def on_cdata(str); end\n\n  def on_etag(name)\n    end_element(name)\n  end\n\n  def on_entityref(ref)\n    characters(ENTITY_REF_MAP[ref])\n  end\n\n  def on_charref(code)\n    characters([code].pack('U'))\n  end\n\n  def on_charref_hex(code)\n    on_charref(code)\n  end\n\n  # def on_start_document; end\n\n  # def on_end_document; end\n\n  def on_stag(name)\n    @attrs = {}\n  end\n\n  def on_attribute(name)\n    @attrs[name] = @curattr = ''\n  end\n\n  def on_attr_value(str)\n    @curattr << str\n  end\n\n  def on_attr_entityref(ref)\n    @curattr << ENTITY_REF_MAP[ref]\n  end\n\n  def on_attr_charref(code)\n    @curattr << [code].pack('U')\n  end\n\n  def on_attr_charref_hex(code)\n    on_attr_charref(code)\n  end\n\n  # def on_attribute_end(name); end\n\n  def on_stag_end_empty(name)\n    on_stag_end(name)\n    on_etag(name)\n  end\n\n  def on_stag_end(name)\n    start_element(name, @attrs)\n  end\n\n  add_factory(self)\nend\n\n\nend\nend\n"
  },
  {
    "path": "lib/xsd/xmlparser.rb",
    "content": "# XSD4R - XML Instance parser library.\n# Copyright (C) 2002, 2003  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.\n\n# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can\n# redistribute it and/or modify it under the same terms of Ruby's license;\n# either the dual license version in 2003, or any later version.\n\n\nrequire 'xsd/xmlparser/parser'\n\n\nmodule XSD\n\n\nmodule XMLParser\n  def create_parser(host, opt)\n    XSD::XMLParser::Parser.create_parser(host, opt)\n  end\n  module_function :create_parser\n\n  # $1 is necessary.\n  NSParseRegexp = Regexp.new('^xmlns:?(.*)$')\n\n  def filter_ns(ns, attrs)\n    return attrs if attrs.nil? or attrs.empty?\n    newattrs = {}\n    attrs.each do |key, value|\n      if (NSParseRegexp =~ key)\n\t# '' means 'default namespace'.\n\ttag = $1 || ''\n\tns.assign(value, tag)\n      else\n\tnewattrs[key] = value\n      end\n    end\n    newattrs\n  end\n  module_function :filter_ns\nend\n\n\nend\n\n\n# Try to load XML processor.\nloaded = false\n[\n  'xsd/xmlparser/xmlparser',\n  'xsd/xmlparser/xmlscanner',\n  'xsd/xmlparser/rexmlparser',\n].each do |lib|\n  begin\n    require lib\n    loaded = true\n    break\n  rescue LoadError\n  end\nend\nunless loaded\n  raise RuntimeError.new(\"XML processor module not found.\")\nend\n"
  },
  {
    "path": "lib/yaml/baseemitter.rb",
    "content": "#\n# BaseEmitter\n#\n\nrequire 'yaml/constants'\nrequire 'yaml/encoding'\nrequire 'yaml/error'\n\nmodule YAML\n\n    module BaseEmitter\n\n        def options( opt = nil )\n            if opt\n                @options[opt] || YAML::DEFAULTS[opt]\n            else\n                @options\n            end\n        end\n\n        def options=( opt )\n            @options = opt\n        end\n\n        #\n        # Emit binary data\n        #\n        def binary_base64( value )\n            self << \"!binary \"\n            self.node_text( [value].pack(\"m\"), '|' )\n        end\n\n\t\t#\n\t\t# Emit plain, normal flowing text\n\t\t#\n\t\tdef node_text( value, block = nil )\n            @seq_map = false\n\t\t\tvalx = value.dup\n            unless block\n            block =\n                if options(:UseBlock)\n                    '|'\n                elsif not options(:UseFold) and valx =~ /\\n[ \\t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/\n                    '|'\n                else\n                    '>'\n                end \n\n                indt = $&.to_i if block =~ /\\d+/\n                if valx =~ /(\\A\\n*[ \\t#]|^---\\s+)/\n                    indt = options(:Indent) unless indt.to_i > 0\n                    block += indt.to_s\n                end\n\n            block +=\n                if valx =~ /\\n\\Z\\n/\n                    \"+\"\n                elsif valx =~ /\\Z\\n/\n                    \"\"\n                else\n                    \"-\"\n                end\n            end\n            block += \"\\n\"\n            if block[0] == ?\"\n                esc_skip = ( \"\\t\\n\" unless valx =~ /^[ \\t]/ ) || \"\"\n                valx = fold( YAML::escape( valx, esc_skip ) + \"\\\"\" ).chomp\n                self << '\"' + indent_text( valx, indt, false )\n            else\n                if block[0] == ?> \n                    valx = fold( valx ) \n                end\n                #p [block, indt]\n                self << block + indent_text( valx, indt )\n            end\n\t\tend\n\n\t\t#\n\t\t# Emit a simple, unqouted string\n\t\t#\n\t\tdef simple( value )\n            @seq_map = false\n            self << value.to_s\n\t\tend\n\n\t\t#\n\t\t# Emit double-quoted string\n\t\t#\n\t\tdef double( value )\n\t\t\t\"\\\"#{YAML.escape( value )}\\\"\" \n\t\tend\n\n\t\t#\n\t\t# Emit single-quoted string\n\t\t#\n\t\tdef single( value )\n\t\t\t\"'#{value}'\"\n\t\tend\n\n\t\t#\n\t\t# Write a text block with the current indent\n\t\t#\n\t\tdef indent_text( text, mod, first_line = true )\n\t\t\treturn \"\" if text.to_s.empty?\n            spacing = indent( mod )\n            text = text.gsub( /\\A([^\\n])/, \"#{ spacing }\\\\1\" ) if first_line\n\t\t\treturn text.gsub( /\\n^([^\\n])/, \"\\n#{spacing}\\\\1\" )\n\t\tend\n\n\t\t#\n\t\t# Write a current indent\n\t\t#\n        def indent( mod = nil )\n            #p [ self.id, level, mod, :INDENT ]\n            if level <= 0\n                mod ||= 0\n            else\n                mod ||= options(:Indent)\n                mod += ( level - 1 ) * options(:Indent)\n            end\n            return \" \" * mod\n\t\tend\n\n\t\t#\n\t\t# Add indent to the buffer\n\t\t#\n\t\tdef indent!\n\t\t\tself << indent\n\t\tend\n\n\t\t#\n\t\t# Folding paragraphs within a column\n\t\t#\n\t\tdef fold( value )\n            value.gsub( /(^[ \\t]+.*$)|(\\S.{0,#{options(:BestWidth) - 1}})(?:[ \\t]+|(\\n+(?=[ \\t]|\\Z))|$)/ ) do\n                $1 || $2 + ( $3 || \"\\n\" )\n            end\n\t\tend\n\n        #\n        # Quick mapping\n        #\n        def map( type, &e )\n            val = Mapping.new\n            e.call( val )\n\t\t\tself << \"#{type} \" if type.length.nonzero?\n\n\t\t\t#\n\t\t\t# Empty hashes\n\t\t\t#\n\t\t\tif val.length.zero?\n\t\t\t\tself << \"{}\"\n                @seq_map = false\n\t\t\telse\n                # FIXME\n                # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? \n\t\t\t    #     @headless = 1 \n                # end\n\n                defkey = @options.delete( :DefaultKey )\n                if defkey\n                    seq_map_shortcut\n                    self << \"= : \"\n                    defkey.to_yaml( :Emitter => self )\n                end\n\n\t\t\t\t#\n\t\t\t\t# Emit the key and value\n\t\t\t\t#\n                val.each { |v|\n                    seq_map_shortcut\n                    if v[0].is_complex_yaml?\n                        self << \"? \"\n                    end\n                    v[0].to_yaml( :Emitter => self )\n                    if v[0].is_complex_yaml?\n                        self << \"\\n\"\n                        indent!\n                    end\n                    self << \": \" \n                    v[1].to_yaml( :Emitter => self )\n                }\n\t\t\tend\n        end\n\n        def seq_map_shortcut\n            # FIXME: seq_map needs to work with the new anchoring system\n            # if @seq_map\n            #     @anchor_extras[@buffer.length - 1] = \"\\n\" + indent\n            #     @seq_map = false\n            # else\n                self << \"\\n\"\n                indent! \n            # end\n        end\n\n        #\n        # Quick sequence\n        #\n        def seq( type, &e )\n            @seq_map = false\n            val = Sequence.new\n            e.call( val )\n\t\t\tself << \"#{type} \" if type.length.nonzero?\n\n\t\t\t#\n\t\t\t# Empty arrays\n\t\t\t#\n\t\t\tif val.length.zero?\n\t\t\t\tself << \"[]\"\n\t\t\telse\n                # FIXME\n                # if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero? \n\t\t\t    #     @headless = 1 \n                # end\n\n\t\t\t\t#\n\t\t\t\t# Emit the key and value\n\t\t\t\t#\n                val.each { |v|\n                    self << \"\\n\"\n                    indent!\n                    self << \"- \"\n                    @seq_map = true if v.class == Hash\n                    v.to_yaml( :Emitter => self )\n                }\n\t\t\tend\n        end\n\n    end\n\n    #\n    # Emitter helper classes\n    #\n    class Mapping < Array\n        def add( k, v )\n            push [k, v]\n        end\n    end\n\n    class Sequence < Array\n        def add( v )\n            push v\n        end\n    end\n\nend\n"
  },
  {
    "path": "lib/yaml/basenode.rb",
    "content": "#\n# YAML::BaseNode class\n#\nrequire 'yaml/ypath'\n\nmodule YAML\n\n    #\n    # YAML Generic Model container\n    #\n    module BaseNode\n\n        #\n        # Search for YPath entry and return\n        # qualified nodes.\n        #\n        def select( ypath_str )\n            matches = match_path( ypath_str )\n\n            #\n            # Create a new generic view of the elements selected\n            #\n            if matches\n                result = []\n                matches.each { |m|\n                    result.push m.last\n                }\n                YAML.transfer( 'seq', result )\n            end\n        end\n\n        #\n        # Search for YPath entry and return\n        # transformed nodes.\n        #\n        def select!( ypath_str )\n            matches = match_path( ypath_str )\n\n            #\n            # Create a new generic view of the elements selected\n            #\n            if matches\n                result = []\n                matches.each { |m|\n                    result.push m.last.transform\n                }\n                result\n            end\n        end\n\n        #\n        # Search for YPath entry and return a list of\n        # qualified paths.\n        #\n        def search( ypath_str )\n            matches = match_path( ypath_str )\n\n            if matches\n                matches.collect { |m|\n                    path = []\n                    m.each_index { |i|\n                        path.push m[i] if ( i % 2 ).zero?\n                    }\n                    \"/\" + path.compact.join( \"/\" )\n                }\n            end\n        end\n\n        def at( seg )\n            if Hash === @value\n                self[seg]\n            elsif Array === @value and seg =~ /\\A\\d+\\Z/ and @value[seg.to_i]\n                @value[seg.to_i]\n            end\n        end\n\n        #\n        # YPath search returning a complete depth array\n        #\n        def match_path( ypath_str )\n            depth = 0\n            matches = []\n            YPath.each_path( ypath_str ) do |ypath|\n                seg = match_segment( ypath, 0 )\n                matches += seg if seg\n            end\n            matches.uniq\n        end\n\n        #\n        # Search a node for a single YPath segment\n        #\n        def match_segment( ypath, depth )\n            deep_nodes = []\n            seg = ypath.segments[ depth ]\n            if seg == \"/\"\n                unless String === @value\n                    idx = -1\n                    @value.collect { |v|\n                        idx += 1\n                        if Hash === @value\n                            match_init = [v[0].transform, v[1]]\n                            match_deep = v[1].match_segment( ypath, depth )\n                        else\n                            match_init = [idx, v]\n                            match_deep = v.match_segment( ypath, depth )\n                        end\n                        if match_deep\n                            match_deep.each { |m|\n                                deep_nodes.push( match_init + m )\n                            }\n                        end\n                    }\n                end\n                depth += 1\n                seg = ypath.segments[ depth ]\n            end\n            match_nodes =\n                case seg\n                when \".\"\n                    [[nil, self]]\n                when \"..\"\n                    [[\"..\", nil]]\n                when \"*\"\n                    if @value.is_a? Enumerable\n                        idx = -1\n                        @value.collect { |h|\n                            idx += 1\n                            if Hash === @value\n                                [h[0].transform, h[1]]\n                            else\n                                [idx, h]\n                            end\n                        }\n                    end\n                else\n                    if seg =~ /^\"(.*)\"$/\n                        seg = $1\n                    elsif seg =~ /^'(.*)'$/\n                        seg = $1\n                    end\n                    if ( v = at( seg ) )\n                        [[ seg, v ]]\n                    end\n                end\n            return deep_nodes unless match_nodes\n            pred = ypath.predicates[ depth ]\n            if pred\n                case pred\n                when /^\\.=/\n                    pred = $'   # '\n                    match_nodes.reject! { |n|\n                        n.last.value != pred\n                    }\n                else\n                    match_nodes.reject! { |n|\n                        n.last.at( pred ).nil?\n                    }\n                end\n            end\n            return match_nodes + deep_nodes unless ypath.segments.length > depth + 1\n\n            #puts \"DEPTH: #{depth + 1}\"\n            deep_nodes = []\n            match_nodes.each { |n|\n                if n[1].is_a? BaseNode\n                    match_deep = n[1].match_segment( ypath, depth + 1 )\n                    if match_deep\n                        match_deep.each { |m|\n                            deep_nodes.push( n + m )\n                        }\n                    end\n                else\n                    deep_nodes = []\n                end\n            }\n            deep_nodes = nil if deep_nodes.length == 0\n            deep_nodes\n        end\n\n        #\n        # We want the node to act like as Hash\n        # if it is.\n        #\n        def []( *key )\n            if Hash === @value\n                v = @value.detect { |k,| k.transform == key.first }\n                v[1] if v\n            elsif Array === @value\n                @value.[]( *key )\n            end\n        end\n\n        def children\n            if Hash === @value\n                @value.values.collect { |c| c[1] }\n            elsif Array === @value\n                @value\n            end\n        end\n\n        def children_with_index\n            if Hash === @value\n                @value.keys.collect { |i| [self[i], i] }\n            elsif Array === @value\n                i = -1; @value.collect { |v| i += 1; [v, i] }\n            end\n        end\n\n        def emit\n            transform.to_yaml\n        end\n    end\n\nend\n\n"
  },
  {
    "path": "lib/yaml/constants.rb",
    "content": "#\n# Constants used throughout the library\n#\nmodule YAML\n\n\t#\n\t# Constants\n\t#\n\tVERSION = '0.60'\n\tSUPPORTED_YAML_VERSIONS = ['1.0']\n\n\t#\n\t# Parser tokens\n\t#\n\tWORD_CHAR = 'A-Za-z0-9'\n\tPRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\\'\". ' \n\tNOT_PLAIN_CHAR = '\\x7f\\x0-\\x1f\\x80-\\x9f'\n\tESCAPE_CHAR = '[\\\\x00-\\\\x09\\\\x0b-\\\\x1f]'\n\tINDICATOR_CHAR = '*&!|\\\\\\\\^@%{}[]='\n\tSPACE_INDICATORS = '-#:,?'\n\tRESTRICTED_INDICATORS = '#:,}]'\n\tDNS_COMP_RE = \"\\\\w(?:[-\\\\w]*\\\\w)?\"\n\tDNS_NAME_RE = \"(?:(?:#{DNS_COMP_RE}\\\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})\"\n\tESCAPES = %w{\\x00   \\x01\t\\x02\t\\x03\t\\x04\t\\x05\t\\x06\t\\a\n\t\t\t     \\x08\t\\t\t\t\\n\t\t\\v\t\t\\f\t\t\\r\t\t\\x0e\t\\x0f\n\t\t\t\t \\x10\t\\x11\t\\x12\t\\x13\t\\x14\t\\x15\t\\x16\t\\x17\n\t\t\t\t \\x18\t\\x19\t\\x1a\t\\e\t\t\\x1c\t\\x1d\t\\x1e\t\\x1f\n\t\t\t    }\n\tUNESCAPES = {\n\t\t\t\t'a' => \"\\x07\", 'b' => \"\\x08\", 't' => \"\\x09\", \n\t\t\t\t'n' => \"\\x0a\", 'v' => \"\\x0b\", 'f' => \"\\x0c\",\n\t\t\t\t'r' => \"\\x0d\", 'e' => \"\\x1b\", '\\\\' => '\\\\',\n\t\t\t    }\n\n\t#\n\t# Default settings\n\t#\n\tDEFAULTS = {\n\t\t:Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',\n\t\t:SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,\n\t\t:WidthType => 'absolute', :BestWidth => 80,\n\t\t:UseBlock => false, :UseFold => false, :Encoding => :None\n\t}\n\nend\n"
  },
  {
    "path": "lib/yaml/dbm.rb",
    "content": "require 'yaml'\nrequire 'dbm'\n#\n# YAML + DBM = YDBM\n# - Same interface as DBM class\n#\nmodule YAML\n\nclass DBM < ::DBM\n    VERSION = \"0.1\"\n    def []( key )\n        fetch( key )\n    end\n    def []=( key, val )\n        store( key, val )\n    end\n    def fetch( keystr, ifnone = nil )\n        begin\n            val = super( keystr )\n            return YAML::load( val ) if String === val\n        rescue IndexError\n        end\n        if block_given?\n            yield keystr\n        else\n            ifnone\n        end\n    end\n    def index( keystr )\n        super( keystr.to_yaml )\n    end\n    def values_at( *keys )\n        keys.collect { |k| fetch( k ) }\n    end\n    def delete( key )\n        v = super( key )\n        if String === v\n            v = YAML::load( v ) \n        end\n        v\n    end\n    def delete_if\n        del_keys = keys.dup\n        del_keys.delete_if { |k| yield( k, fetch( k ) ) == false }\n        del_keys.each { |k| delete( k ) } \n        self\n    end\n    def reject\n        hsh = self.to_hash\n        hsh.reject { |k,v| yield k, v }\n    end\n    def each_pair\n        keys.each { |k| yield k, fetch( k ) }\n        self\n    end\n    def each_value\n        super { |v| yield YAML::load( v ) }\n        self\n    end\n    def values\n        super.collect { |v| YAML::load( v ) }\n    end\n    def has_value?( val )\n        each_value { |v| return true if v == val }\n        return false\n    end\n    def invert\n        h = {}\n        keys.each { |k| h[ self.fetch( k ) ] = k }\n        h\n    end\n    def replace( hsh )\n        clear\n        update( hsh )\n    end\n    def shift\n        a = super\n        a[1] = YAML::load( a[1] ) if a\n        a\n    end\n    def select( *keys )\n        if block_given?\n            self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact\n        else\n            values_at( *keys )\n        end\n    end\n    def store( key, val )\n        super( key, val.to_yaml )\n        val\n    end\n    def update( hsh )\n        hsh.keys.each do |k|\n            self.store( k, hsh.fetch( k ) )\n        end\n        self\n    end\n    def to_a\n        a = []\n        keys.each { |k| a.push [ k, self.fetch( k ) ] }\n        a\n    end\n    def to_hash\n        h = {}\n        keys.each { |k| h[ k ] = self.fetch( k ) }\n        h\n    end\n    alias :each :each_pair\nend\n\nend\n"
  },
  {
    "path": "lib/yaml/encoding.rb",
    "content": "#\n# Handle Unicode-to-Internal conversion\n#\n\nmodule YAML\n\n\t#\n\t# Escape the string, condensing common escapes\n\t#\n\tdef YAML.escape( value, skip = \"\" )\n\t\tvalue.gsub( /\\\\/, \"\\\\\\\\\\\\\" ).\n              gsub( /\"/, \"\\\\\\\"\" ).\n              gsub( /([\\x00-\\x1f])/ ) do\n                 skip[$&] || ESCAPES[ $&.unpack(\"C\")[0] ]\n             end\n\tend\n\n\t#\n\t# Unescape the condenses escapes\n\t#\n\tdef YAML.unescape( value )\n\t\tvalue.gsub( /\\\\(?:([nevfbart\\\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {\n\t\t\tif $3\n\t\t\t\t[\"#$3\".hex ].pack('U*')\n\t\t\telsif $2\n\t\t\t\t[$2].pack( \"H2\" ) \n\t\t\telse\n\t\t\t\tUNESCAPES[$1] \n\t\t\tend\n\t\t}\n\tend\n\nend\n"
  },
  {
    "path": "lib/yaml/error.rb",
    "content": "#\n# Error messages and exception class\n#\n\nmodule YAML\n\n\t#\n\t# Error messages\n\t#\n\n\tERROR_NO_HEADER_NODE = \"With UseHeader=false, the node Array or Hash must have elements\"\n\tERROR_NEED_HEADER = \"With UseHeader=false, the node must be an Array or Hash\"\n\tERROR_BAD_EXPLICIT = \"Unsupported explicit transfer: '%s'\"\n    ERROR_MANY_EXPLICIT = \"More than one explicit transfer\"\n\tERROR_MANY_IMPLICIT = \"More than one implicit request\"\n\tERROR_NO_ANCHOR = \"No anchor for alias '%s'\"\n\tERROR_BAD_ANCHOR = \"Invalid anchor: %s\"\n\tERROR_MANY_ANCHOR = \"More than one anchor\"\n\tERROR_ANCHOR_ALIAS = \"Can't define both an anchor and an alias\"\n\tERROR_BAD_ALIAS = \"Invalid alias: %s\"\n\tERROR_MANY_ALIAS = \"More than one alias\"\n\tERROR_ZERO_INDENT = \"Can't use zero as an indentation width\"\n\tERROR_UNSUPPORTED_VERSION = \"This release of YAML.rb does not support YAML version %s\"\n\tERROR_UNSUPPORTED_ENCODING = \"Attempt to use unsupported encoding: %s\"\n\n\t#\n\t# YAML Error classes\n\t#\n    \n\tclass Error < StandardError; end\n\tclass ParseError < Error; end\n    class TypeError < StandardError; end\n\nend\n"
  },
  {
    "path": "lib/yaml/loader.rb",
    "content": "#\n# YAML::Loader class\n# .. type handling ..\n#\nmodule YAML\n    class Loader\n        TRANSFER_DOMAINS = {\n            'yaml.org,2002' => {},\n            'ruby.yaml.org,2002' => {}\n        }\n        PRIVATE_TYPES = {}\n        IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]\n    end\nend\n"
  },
  {
    "path": "lib/yaml/rubytypes.rb",
    "content": "# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4\nrequire 'date'\n\nclass Class\n\tdef to_yaml( opts = {} )\n\t\traise TypeError, \"can't dump anonymous class %s\" % self.class\n\tend\nend\n\nclass Object\n    yaml_as \"tag:ruby.yaml.org,2002:object\"\n    def to_yaml_style; end\n    def to_yaml_properties; instance_variables.sort; end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            out.map( taguri, to_yaml_style ) do |map|\n\t\t\t\tto_yaml_properties.each do |m|\n                    map.add( m[1..-1], instance_variable_get( m ) )\n                end\n            end\n        end\n\tend\nend\n\nclass Hash\n    yaml_as \"tag:ruby.yaml.org,2002:hash\"\n    yaml_as \"tag:yaml.org,2002:map\"\n    def yaml_initialize( tag, val )\n        if Array === val\n            update Hash.[]( *val )\t\t# Convert the map to a sequence\n        elsif Hash === val\n            update val\n        else\n            raise YAML::TypeError, \"Invalid map explicitly tagged #{ tag }: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            out.map( taguri, to_yaml_style ) do |map|\n                each do |k, v|\n                    map.add( k, v )\n                end\n            end\n        end\n\tend\nend\n\nclass Struct\n    yaml_as \"tag:ruby.yaml.org,2002:struct\"\n    def self.yaml_tag_class_name; self.name.gsub( \"Struct::\", \"\" ); end\n    def self.yaml_tag_read_class( name ); \"Struct::#{ name }\"; end\n    def self.yaml_new( klass, tag, val )\n        if Hash === val\n            struct_type = nil\n\n            #\n            # Use existing Struct if it exists\n            #\n            props = {}\n            val.delete_if { |k,v| props[k] = v if k =~ /^@/ }\n            begin\n                struct_name, struct_type = YAML.read_type_class( tag, Struct )\n            rescue NameError\n            end\n            if not struct_type\n                struct_def = [ tag.split( ':', 4 ).last ]\n                struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) ) \n            end\n\n            #\n            # Set the Struct properties\n            #\n            st = YAML::object_maker( struct_type, {} )\n            st.members.each do |m|\n                st.send( \"#{m}=\", val[m] )\n            end\n            props.each do |k,v|\n                st.instance_variable_set(k, v)\n            end\n            st\n        else\n            raise YAML::TypeError, \"Invalid Ruby Struct: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n\t\t\t#\n\t\t\t# Basic struct is passed as a YAML map\n\t\t\t#\n            out.map( taguri, to_yaml_style ) do |map|\n\t\t\t\tself.members.each do |m|\n                    map.add( m, self[m] )\n                end\n\t\t\t\tself.to_yaml_properties.each do |m|\n                    map.add( m, instance_variable_get( m ) )\n                end\n            end\n        end\n\tend\nend\n\nclass Array\n    yaml_as \"tag:ruby.yaml.org,2002:array\"\n    yaml_as \"tag:yaml.org,2002:seq\"\n    def yaml_initialize( tag, val ); concat( val.to_a ); end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            out.seq( taguri, to_yaml_style ) do |seq|\n                each do |x|\n                    seq.add( x )\n                end\n            end\n        end\n\tend\nend\n\nclass Exception\n    yaml_as \"tag:ruby.yaml.org,2002:exception\"\n    def Exception.yaml_new( klass, tag, val )\n        o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } )\n        val.each_pair do |k,v|\n            o.instance_variable_set(\"@#{k}\", v)\n        end\n        o\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            out.map( taguri, to_yaml_style ) do |map|\n                map.add( 'message', message )\n\t\t\t\tto_yaml_properties.each do |m|\n                    map.add( m[1..-1], instance_variable_get( m ) )\n                end\n            end\n        end\n\tend\nend\n\nclass String\n    yaml_as \"tag:ruby.yaml.org,2002:string\"\n    yaml_as \"tag:yaml.org,2002:binary\"\n    yaml_as \"tag:yaml.org,2002:str\"\n    def is_complex_yaml?\n        to_yaml_style or not to_yaml_properties.empty? or self =~ /\\n.+/\n    end\n    def is_binary_data?\n        ( self.count( \"^ -~\", \"^\\r\\n\" ).fdiv(self.size) > 0.3 || self.index( \"\\x00\" ) ) unless empty?\n    end\n    def String.yaml_new( klass, tag, val )\n        val = val.unpack(\"m\")[0] if tag == \"tag:yaml.org,2002:binary\"\n        val = { 'str' => val } if String === val\n        if Hash === val\n            s = klass.allocate\n            # Thank you, NaHi\n            String.instance_method(:initialize).\n                  bind(s).\n                  call( val.delete( 'str' ) )\n            val.each { |k,v| s.instance_variable_set( k, v ) }\n            s\n        else\n            raise YAML::TypeError, \"Invalid String: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|\n            if is_binary_data?\n                out.scalar( \"tag:yaml.org,2002:binary\", [self].pack(\"m\"), :literal )\n            elsif to_yaml_properties.empty?\n                out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )\n            else\n                out.map( taguri, to_yaml_style ) do |map|\n                    map.add( 'str', \"#{self}\" )\n                    to_yaml_properties.each do |m|\n                        map.add( m, instance_variable_get( m ) )\n                    end\n                end\n            end\n        end\n\tend\nend\n\nclass Symbol\n    yaml_as \"tag:ruby.yaml.org,2002:symbol\"\n    yaml_as \"tag:ruby.yaml.org,2002:sym\"\n    def Symbol.yaml_new( klass, tag, val )\n        if String === val\n            val = YAML::load( val ) if val =~ /\\A([\"']).*\\1\\z/\n            val.intern\n        else\n            raise YAML::TypeError, \"Invalid Symbol: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            out.scalar( \"tag:yaml.org,2002:str\", self.inspect, :plain )\n        end\n\tend\nend\n\nclass Range\n    yaml_as \"tag:ruby.yaml.org,2002:range\"\n    def Range.yaml_new( klass, tag, val )\n        inr = %r'(\\w+|[+-]?\\d+(?:\\.\\d+)?(?:e[+-]\\d+)?|\"(?:[^\\\\\"]|\\\\.)*\")'\n        opts = {}\n        if String === val and val =~ /^#{inr}(\\.{2,3})#{inr}$/o\n            r1, rdots, r2 = $1, $2, $3\n            opts = {\n                'begin' => YAML.load( \"--- #{r1}\" ),\n                'end' => YAML.load( \"--- #{r2}\" ),\n                'excl' => rdots.length == 3\n            }\n            val = {}\n        elsif Hash === val\n            opts['begin'] = val.delete('begin')\n            opts['end'] = val.delete('end')\n            opts['excl'] = val.delete('excl')\n        end\n        if Hash === opts\n            r = YAML::object_maker( klass, {} )\n            # Thank you, NaHi\n            Range.instance_method(:initialize).\n                  bind(r).\n                  call( opts['begin'], opts['end'], opts['excl'] )\n            val.each { |k,v| r.instance_variable_set( k, v ) }\n            r\n        else\n            raise YAML::TypeError, \"Invalid Range: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or\n            #   self.end.is_complex_yaml? or self.end.respond_to? :to_str or\n            #   not to_yaml_properties.empty?\n                out.map( taguri, to_yaml_style ) do |map|\n                    map.add( 'begin', self.begin )\n                    map.add( 'end', self.end )\n                    map.add( 'excl', self.exclude_end? )\n                    to_yaml_properties.each do |m|\n                        map.add( m, instance_variable_get( m ) )\n                    end\n                end\n            # else\n            #     out.scalar( taguri ) do |sc|\n            #         sc.embed( self.begin )\n            #         sc.concat( self.exclude_end? ? \"...\" : \"..\" )\n            #         sc.embed( self.end )\n            #     end\n            # end\n        end\n\tend\nend\n\nclass Regexp\n    yaml_as \"tag:ruby.yaml.org,2002:regexp\"\n    def Regexp.yaml_new( klass, tag, val )\n        if String === val and val =~ /^\\/(.*)\\/([mix]*)$/\n            val = { 'regexp' => $1, 'mods' => $2 }\n        end\n        if Hash === val\n            mods = nil\n            unless val['mods'].to_s.empty?\n                mods = 0x00\n                mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )\n                mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )\n                mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )\n            end\n            val.delete( 'mods' )\n            r = YAML::object_maker( klass, {} )\n            Regexp.instance_method(:initialize).\n                  bind(r).\n                  call( val.delete( 'regexp' ), mods )\n            val.each { |k,v| r.instance_variable_set( k, v ) }\n            r\n        else\n            raise YAML::TypeError, \"Invalid Regular expression: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            if to_yaml_properties.empty?\n                out.scalar( taguri, self.inspect, :plain )\n            else\n                out.map( taguri, to_yaml_style ) do |map|\n                    src = self.inspect\n                    if src =~ /\\A\\/(.*)\\/([a-z]*)\\Z/\n                        map.add( 'regexp', $1 )\n                        map.add( 'mods', $2 )\n                    else\n\t\t                raise YAML::TypeError, \"Invalid Regular expression: \" + src\n                    end\n                    to_yaml_properties.each do |m|\n                        map.add( m, instance_variable_get( m ) )\n                    end\n                end\n            end\n        end\n\tend\nend\n\nclass Time\n    yaml_as \"tag:ruby.yaml.org,2002:time\"\n    yaml_as \"tag:yaml.org,2002:timestamp\"\n    def Time.yaml_new( klass, tag, val )\n        if Hash === val\n            t = val.delete( 'at' )\n            val.each { |k,v| t.instance_variable_set( k, v ) }\n            t\n        else\n            raise YAML::TypeError, \"Invalid Time: \" + val.inspect\n        end\n    end\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            tz = \"Z\"\n            # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!\n            unless self.utc?\n                utc_same_instant = self.dup.utc\n                utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)\n                difference_to_utc = utc_same_writing - utc_same_instant\n                if (difference_to_utc < 0) \n                    difference_sign = '-'\n                    absolute_difference = -difference_to_utc\n                else\n                    difference_sign = '+'\n                    absolute_difference = difference_to_utc\n                end\n                difference_minutes = (absolute_difference/60).round\n                tz = \"%s%02d:%02d\" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]\n            end\n            standard = self.strftime( \"%Y-%m-%d %H:%M:%S\" )\n            standard += \".%06d\" % [usec] if usec.nonzero?\n            standard += \" %s\" % [tz]\n            if to_yaml_properties.empty?\n                out.scalar( taguri, standard, :plain )\n            else\n                out.map( taguri, to_yaml_style ) do |map|\n                    map.add( 'at', standard )\n                    to_yaml_properties.each do |m|\n                        map.add( m, instance_variable_get( m ) )\n                    end\n                end\n            end\n        end\n\tend\nend\n\nclass Date\n    yaml_as \"tag:yaml.org,2002:timestamp#ymd\"\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( self, opts ) do |out|\n            out.scalar( \"tag:yaml.org,2002:timestamp\", self.to_s, :plain )\n        end\n\tend\nend\n\nclass Integer\n    yaml_as \"tag:yaml.org,2002:int\"\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            out.scalar( \"tag:yaml.org,2002:int\", self.to_s, :plain )\n        end\n\tend\nend\n\nclass Float\n    yaml_as \"tag:yaml.org,2002:float\"\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            str = self.to_s\n            if str == \"Infinity\"\n                str = \".Inf\"\n            elsif str == \"-Infinity\"\n                str = \"-.Inf\"\n            elsif str == \"NaN\"\n                str = \".NaN\"\n            end\n            out.scalar( \"tag:yaml.org,2002:float\", str, :plain )\n        end\n\tend\nend\n\nclass TrueClass\n    yaml_as \"tag:yaml.org,2002:bool#yes\"\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            out.scalar( taguri, \"true\", :plain )\n        end\n\tend\nend\n\nclass FalseClass\n    yaml_as \"tag:yaml.org,2002:bool#no\"\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            out.scalar( taguri, \"false\", :plain )\n        end\n\tend\nend\n\nclass NilClass \n    yaml_as \"tag:yaml.org,2002:null\"\n\tdef to_yaml( opts = {} )\n\t\tYAML::quick_emit( nil, opts ) do |out|\n            out.scalar( taguri, \"\", :plain )\n        end\n\tend\nend\n\n"
  },
  {
    "path": "lib/yaml/store.rb",
    "content": "#\n# YAML::Store\n#\nrequire 'yaml'\nrequire 'pstore'\n\nclass YAML::Store < PStore\n  def initialize( *o )\n    @opt = YAML::DEFAULTS.dup\n    if String === o.first\n      super(o.shift)\n    end\n    if o.last.is_a? Hash\n      @opt.update(o.pop)\n    end\n  end\n\n  def dump(table)\n    @table.to_yaml(@opt)\n  end\n\n  def load(content)\n    table = YAML::load(content)\n    if table == false\n      {}\n    else\n      table\n    end\n  end\n\n  def marshal_dump_supports_canonical_option?\n    false\n  end\n\n  EMPTY_MARSHAL_DATA = {}.to_yaml\n  EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA)\n  def empty_marshal_data\n    EMPTY_MARSHAL_DATA\n  end\n  def empty_marshal_checksum\n    EMPTY_MARSHAL_CHECKSUM\n  end\nend\n"
  },
  {
    "path": "lib/yaml/stream.rb",
    "content": "module YAML\n\n\t#\n\t# YAML::Stream -- for emitting many documents\n\t#\n\tclass Stream\n\n\t\tattr_accessor :documents, :options\n\n\t\tdef initialize( opts = {} )\n\t\t\t@options = opts\n\t\t\t@documents = []\n\t\tend\n\t\t\n        def []( i )\n            @documents[ i ]\n        end\n\n\t\tdef add( doc )\n\t\t\t@documents << doc\n\t\tend\n\n\t\tdef edit( doc_num, doc )\n\t\t\t@documents[ doc_num ] = doc\n\t\tend\n\n\t\tdef emit( io = nil )\n            # opts = @options.dup\n\t\t\t# opts[:UseHeader] = true if @documents.length > 1\n            out = YAML.emitter\n            out.reset( io || io2 = StringIO.new )\n            @documents.each { |v|\n                v.to_yaml( out )\n            }\n            io || ( io2.rewind; io2.read )\n\t\tend\n\n\tend\n\nend\n"
  },
  {
    "path": "lib/yaml/stringio.rb",
    "content": "#\n# Limited StringIO if no core lib is available\n#\nbegin\nrequire 'stringio'\nrescue LoadError\n    # StringIO based on code by MoonWolf\n    class StringIO\n        def initialize(string=\"\")\n            @string=string\n            @pos=0\n            @eof=(string.size==0)\n        end\n        def pos\n            @pos\n        end    \n        def eof\n            @eof\n        end\n        alias eof? eof\n        def readline(rs=$/)\n            if @eof\n                raise EOFError\n            else\n                if p = @string[@pos..-1]=~rs\n                    line = @string[@pos,p+1]\n                else\n                    line = @string[@pos..-1]\n                end\n                @pos+=line.size\n                @eof =true if @pos==@string.size\n                $_ = line\n            end\n        end\n        def rewind\n            seek(0,0)\n        end\n        def seek(offset,whence)\n            case whence\n            when 0\n                @pos=offset\n            when 1\n                @pos+=offset\n            when 2\n                @pos=@string.size+offset\n            end\n            @eof=(@pos>=@string.size)\n            0\n        end\n    end\n\n\t#\n\t# Class method for creating streams\n\t#\n\tdef YAML.make_stream( io )\n        if String === io\n            io = StringIO.new( io )\n        elsif not IO === io\n            raise YAML::Error, \"YAML stream must be an IO or String object.\"\n        end\n        if YAML::unicode\n            def io.readline\n                YAML.utf_to_internal( readline( @ln_sep ), @utf_encoding )\n            end\n            def io.check_unicode\n                @utf_encoding = YAML.sniff_encoding( read( 4 ) )\n                @ln_sep = YAML.enc_separator( @utf_encoding )\n                seek( -4, IO::SEEK_CUR )\n            end\n\t\t    def io.utf_encoding\n\t\t    \t@utf_encoding\n\t\t    end\n            io.check_unicode\n        else\n            def io.utf_encoding\n                :None\n            end\n        end\n        io\n\tend\n\nend\n\n"
  },
  {
    "path": "lib/yaml/syck.rb",
    "content": "#\n# YAML::Syck module\n# .. glues syck and yaml.rb together ..\n#\nrequire 'syck'\nrequire 'yaml/basenode'\n\nmodule YAML\n    module Syck\n\n        #\n        # Mixin BaseNode functionality\n        #\n        class Node\n            include YAML::BaseNode\n        end\n\n    end\nend\n"
  },
  {
    "path": "lib/yaml/tag.rb",
    "content": "# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4\n# $Id$\n#\n# = yaml/tag.rb: methods for associating a taguri to a class.\n#\n# Author:: why the lucky stiff\n# \nmodule YAML\n    # A dictionary of taguris which map to\n    # Ruby classes.\n    @@tagged_classes = {}\n    \n    # \n    # Associates a taguri _tag_ with a Ruby class _cls_.  The taguri is used to give types\n    # to classes when loading YAML.  Taguris are of the form:\n    #\n    #   tag:authorityName,date:specific\n    #\n    # The +authorityName+ is a domain name or email address.  The +date+ is the date the type\n    # was issued in YYYY or YYYY-MM or YYYY-MM-DD format.  The +specific+ is a name for\n    # the type being added.\n    # \n    # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the\n    # +date+.  The +specific+ is simply the name of the type:\n    #\n    #  tag:yaml.org,2002:int\n    #  tag:yaml.org,2002:float\n    #  tag:yaml.org,2002:timestamp\n    #\n    # The domain must be owned by you on the +date+ declared.  If you don't own any domains on the\n    # date you declare the type, you can simply use an e-mail address.\n    #\n    #  tag:why@ruby-lang.org,2004:notes/personal\n    #\n    def YAML.tag_class( tag, cls )\n        if @@tagged_classes.has_key? tag\n            warn \"class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag\"\n        end\n        @@tagged_classes[tag] = cls\n    end\n\n    # Returns the complete dictionary of taguris, paired with classes.  The key for\n    # the dictionary is the full taguri.  The value for each key is the class constant\n    # associated to that taguri.\n    #\n    #  YAML.tagged_classes[\"tag:yaml.org,2002:int\"] => Integer\n    #\n    def YAML.tagged_classes\n        @@tagged_classes\n    end\nend\n\nclass Module\n    # :stopdoc:\n\n    # Adds a taguri _tag_ to a class, used when dumping or loading the class\n    # in YAML.  See YAML::tag_class for detailed information on typing and\n    # taguris.\n    def yaml_as( tag, sc = true )\n        verbose, $VERBOSE = $VERBOSE, nil\n        class_eval <<-\"end;\", __FILE__, __LINE__+1\n            attr_writer :taguri\n            def taguri\n                if respond_to? :to_yaml_type\n                    YAML::tagurize( to_yaml_type[1..-1] )\n                else\n                    return @taguri if defined?(@taguri) and @taguri\n                    tag = #{ tag.dump }\n                    if self.class.yaml_tag_subclasses? and self.class != YAML::tagged_classes[tag]\n                        tag = \"\\#{ tag }:\\#{ self.class.yaml_tag_class_name }\"\n                    end\n                    tag\n                end\n            end\n            def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end\n        end;\n        YAML::tag_class tag, self\n    ensure\n        $VERBOSE = verbose\n    end\n    # Transforms the subclass name into a name suitable for display\n    # in a subclassed tag.\n    def yaml_tag_class_name\n        self.name\n    end\n    # Transforms the subclass name found in the tag into a Ruby\n    # constant name.\n    def yaml_tag_read_class( name )\n        name\n    end\nend\n"
  },
  {
    "path": "lib/yaml/types.rb",
    "content": "# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4\n#\n# Classes required by the full core typeset\n#\n\nmodule YAML\n\n    #\n    # Default private type\n    #\n    class PrivateType\n        def self.tag_subclasses?; false; end\n        verbose, $VERBOSE = $VERBOSE, nil\n        def initialize( type, val )\n            @type_id = type; @value = val\n            @value.taguri = \"x-private:#{ @type_id }\"\n        end\n        def to_yaml( opts = {} )\n            @value.to_yaml( opts )\n        end\n    ensure\n        $VERBOSE = verbose\n    end\n\n    #\n    # Default domain type\n    #\n    class DomainType\n        def self.tag_subclasses?; false; end\n        verbose, $VERBOSE = $VERBOSE, nil\n        def initialize( domain, type, val )\n            @domain = domain; @type_id = type; @value = val\n            @value.taguri = \"tag:#{ @domain }:#{ @type_id }\"\n        end\n        def to_yaml( opts = {} )\n            @value.to_yaml( opts )\n        end\n    ensure\n        $VERBOSE = verbose\n    end\n\n    #\n    # Unresolved objects\n    #\n    class Object\n        def self.tag_subclasses?; false; end\n        def to_yaml( opts = {} )\n            YAML::quick_emit( self, opts ) do |out|\n                out.map( \"tag:ruby.yaml.org,2002:object:#{ @class }\", to_yaml_style ) do |map|\n                    @ivars.each do |k,v|\n                        map.add( k, v )\n                    end\n                end\n            end\n        end\n    end\n\n    #\n    # YAML Hash class to support comments and defaults\n    #\n    class SpecialHash < ::Hash \n        attr_accessor :default\n        def inspect\n            self.default.to_s\n        end\n        def to_s\n            self.default.to_s\n        end\n        def update( h )\n            if YAML::SpecialHash === h\n                @default = h.default if h.default\n            end\n            super( h )\n        end\n        def to_yaml( opts = {} )\n            opts[:DefaultKey] = self.default\n            super( opts )\n        end\n    end\n\n    #\n    # Builtin collection: !omap\n    #\n    class Omap < ::Array\n        yaml_as \"tag:yaml.org,2002:omap\"\n        def yaml_initialize( tag, val )\n            if Array === val\n                val.each do |v|\n                    if Hash === v\n                        concat( v.to_a )\t\t# Convert the map to a sequence\n                    else\n                        raise YAML::Error, \"Invalid !omap entry: \" + val.inspect\n                    end\n                end\n            else\n                raise YAML::Error, \"Invalid !omap: \" + val.inspect\n            end\n            self\n        end\n        def self.[]( *vals )\n            o = Omap.new\n            0.step( vals.length - 1, 2 ) do |i|\n                o[vals[i]] = vals[i+1]\n            end\n            o\n        end\n        def []( k )\n            self.assoc( k ).to_a[1]\n        end\n        def []=( k, *rest )\n            val, set = rest.reverse\n            if ( tmp = self.assoc( k ) ) and not set\n                tmp[1] = val\n            else\n                self << [ k, val ] \n            end\n            val\n        end\n        def has_key?( k )\n            self.assoc( k ) ? true : false\n        end\n        def is_complex_yaml?\n            true\n        end\n        def to_yaml( opts = {} )\n            YAML::quick_emit( self, opts ) do |out|\n                out.seq( taguri, to_yaml_style ) do |seq|\n                    self.each do |v|\n                        seq.add( Hash[ *v ] )\n                    end\n                end\n            end\n        end\n    end\n\n    #\n    # Builtin collection: !pairs\n    #\n    class Pairs < ::Array\n        yaml_as \"tag:yaml.org,2002:pairs\"\n        def yaml_initialize( tag, val )\n            if Array === val\n                val.each do |v|\n                    if Hash === v\n                        concat( v.to_a )\t\t# Convert the map to a sequence\n                    else\n                        raise YAML::Error, \"Invalid !pairs entry: \" + val.inspect\n                    end\n                end\n            else\n                raise YAML::Error, \"Invalid !pairs: \" + val.inspect\n            end\n            self\n        end\n        def self.[]( *vals )\n            p = Pairs.new\n            0.step( vals.length - 1, 2 ) { |i|\n                p[vals[i]] = vals[i+1]\n            }\n            p\n        end\n        def []( k )\n            self.assoc( k ).to_a\n        end\n        def []=( k, val )\n            self << [ k, val ] \n            val\n        end\n        def has_key?( k )\n            self.assoc( k ) ? true : false\n        end\n        def is_complex_yaml?\n            true\n        end\n        def to_yaml( opts = {} )\n            YAML::quick_emit( self, opts ) do |out|\n                out.seq( taguri, to_yaml_style ) do |seq|\n                    self.each do |v|\n                        seq.add( Hash[ *v ] )\n                    end\n                end\n            end\n        end\n    end\n\n    #\n    # Builtin collection: !set\n    #\n    class Set < ::Hash\n        yaml_as \"tag:yaml.org,2002:set\"\n    end\nend\n"
  },
  {
    "path": "lib/yaml/yamlnode.rb",
    "content": "#\n# YAML::YamlNode class\n#\nrequire 'yaml/basenode'\n\nmodule YAML\n\n    #\n    # YAML Generic Model container\n    #\n    class YamlNode\n        include BaseNode\n        attr_accessor :kind, :type_id, :value, :anchor\n        def initialize( t, v )\n            @type_id = t\n            if Hash === v\n                @kind = 'map'\n                @value = {}\n                v.each { |k,v|\n                    @value[ k.transform ] = [ k, v ]\n                }\n            elsif Array === v\n                @kind = 'seq'\n                @value = v\n            elsif String === v\n                @kind = 'scalar'\n                @value = v\n            end\n        end\n\n        #\n        # Transform this node fully into a native type\n        #\n        def transform\n            t = nil\n            if @value.is_a? Hash\n                t = {}\n                @value.each { |k,v|\n                    t[ k ] = v[1].transform\n                }\n            elsif @value.is_a? Array\n                t = []\n                @value.each { |v|\n                    t.push v.transform\n                }\n            else\n                t = @value\n            end\n            YAML.transfer_method( @type_id, t )\n        end\n\n    end\n\nend\n"
  },
  {
    "path": "lib/yaml/ypath.rb",
    "content": "#\n# YAML::YPath\n#\n\nmodule YAML\n\n    class YPath\n        attr_accessor :segments, :predicates, :flags\n        def initialize( str )\n            @segments = []\n            @predicates = []\n            @flags = nil\n            while str =~ /^\\/?(\\/|[^\\/\\[]+)(?:\\[([^\\]]+)\\])?/\n                @segments.push $1\n                @predicates.push $2\n                str = $'\n            end\n            unless str.to_s.empty?\n                @segments += str.split( \"/\" )\n            end\n            if @segments.length == 0\n                @segments.push \".\"\n            end\n        end\n        def YPath.each_path( str )\n            #\n            # Find choices\n            #\n            paths = []\n            str = \"(#{ str })\"\n            while str.sub!( /\\(([^()]+)\\)/, \"\\n#{ paths.length }\\n\" )\n                paths.push $1.split( '|' )\n            end\n\n            #\n            # Construct all possible paths\n            #\n            all = [ str ]\n            ( paths.length - 1 ).downto( 0 ) do |i|\n                all = all.collect do |a|\n                    paths[i].collect do |p|\n                        a.gsub( /\\n#{ i }\\n/, p )\n                    end\n                end.flatten.uniq\n            end\n            all.collect do |path|\n                yield YPath.new( path )\n            end\n        end\n    end\n\nend\n"
  },
  {
    "path": "lib/yaml.rb",
    "content": "# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4\n# $Id$\n#\n# = yaml.rb: top-level module with methods for loading and parsing YAML documents\n#\n# Author:: why the lucky stiff\n# \n\nrequire 'stringio'\nrequire 'yaml/error'\nrequire 'yaml/syck'\nrequire 'yaml/tag'\nrequire 'yaml/stream'\nrequire 'yaml/constants'\n\n# == YAML\n#\n# YAML(tm) (rhymes with 'camel') is a\n# straightforward machine parsable data serialization format designed for\n# human readability and interaction with scripting languages such as Perl\n# and Python. YAML is optimized for data serialization, formatted\n# dumping, configuration files, log files, Internet messaging and\n# filtering. This specification describes the YAML information model and\n# serialization format. Together with the Unicode standard for characters, it\n# provides all the information necessary to understand YAML Version 1.0\n# and construct computer programs to process it.\n#                         \n# See http://yaml.org/ for more information.  For a quick tutorial, please\n# visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes).\n#                              \n# == About This Library\n#                         \n# The YAML 1.0 specification outlines four stages of YAML loading and dumping.\n# This library honors all four of those stages, although data is really only\n# available to you in three stages.\n#     \n# The four stages are: native, representation, serialization, and presentation.\n#     \n# The native stage refers to data which has been loaded completely into Ruby's\n# own types. (See +YAML::load+.)\n#\n# The representation stage means data which has been composed into\n# +YAML::BaseNode+ objects.  In this stage, the document is available as a\n# tree of node objects.  You can perform YPath queries and transformations\n# at this level.  (See +YAML::parse+.)\n#   \n# The serialization stage happens inside the parser.  The YAML parser used in\n# Ruby is called Syck.  Serialized nodes are available in the extension as\n# SyckNode structs.\n#       \n# The presentation stage is the YAML document itself.  This is accessible\n# to you as a string.  (See +YAML::dump+.)\n#   \n# For more information about the various information models, see Chapter\n# 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269).\n#\n# The YAML module provides quick access to the most common loading (YAML::load)\n# and dumping (YAML::dump) tasks.  This module also provides an API for registering\n# global types (YAML::add_domain_type).\n#\n# == Example\n#\n# A simple round-trip (load and dump) of an object.\n#\n#     require \"yaml\"\n#\n#     test_obj = [\"dogs\", \"cats\", \"badgers\"]\n#\n#     yaml_obj = YAML::dump( test_obj )\n#                         # -> ---\n#                              - dogs\n#                              - cats\n#                              - badgers\n#     ruby_obj = YAML::load( yaml_obj )\n#                         # => [\"dogs\", \"cats\", \"badgers\"]\n#     ruby_obj == test_obj\n#                         # => true\n#\n# To register your custom types with the global resolver, use +add_domain_type+.\n#\n#     YAML::add_domain_type( \"your-site.com,2004\", \"widget\" ) do |type, val|\n#         Widget.new( val )\n#     end\n#\nmodule YAML\n\n    Resolver = YAML::Syck::Resolver\n    DefaultResolver = YAML::Syck::DefaultResolver\n    DefaultResolver.use_types_at( @@tagged_classes )\n    GenericResolver = YAML::Syck::GenericResolver\n    Parser = YAML::Syck::Parser\n    Emitter = YAML::Syck::Emitter\n\n    # Returns a new default parser\n    def YAML.parser; Parser.new.set_resolver( YAML.resolver ); end\n    # Returns a new generic parser\n    def YAML.generic_parser; Parser.new.set_resolver( GenericResolver ); end\n    # Returns the default resolver\n    def YAML.resolver; DefaultResolver; end\n    # Returns a new default emitter\n    def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end\n\n\t#\n\t# Converts _obj_ to YAML and writes the YAML result to _io_.\n    #     \n    #   File.open( 'animals.yaml', 'w' ) do |out|\n    #     YAML.dump( ['badger', 'elephant', 'tiger'], out )\n    #   end\n    #\n    # If no _io_ is provided, a string containing the dumped YAML\n    # is returned.\n\t#\n    #   YAML.dump( :locked )\n    #      #=> \"--- :locked\"\n    #\n\tdef YAML.dump( obj, io = nil )\n        obj.to_yaml( io || io2 = StringIO.new )\n        io || ( io2.rewind; io2.read )\n\tend\n\n\t#\n\t# Load a document from the current _io_ stream.\n\t#\n    #   File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }\n    #      #=> ['badger', 'elephant', 'tiger']\n    #\n    # Can also load from a string.\n    #\n    #   YAML.load( \"--- :locked\" )\n    #      #=> :locked\n    #\n\tdef YAML.load( io )\n\t\typ = parser.load( io )\n\tend\n\n    #\n    # Load a document from the file located at _filepath_.\n    #\n    #   YAML.load_file( 'animals.yaml' )\n    #      #=> ['badger', 'elephant', 'tiger']\n    #\n    def YAML.load_file( filepath )\n        File.open( filepath ) do |f|\n            load( f )\n        end\n    end\n\n\t#\n\t# Parse the first document from the current _io_ stream\n\t#\n    #   File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }\n    #      #=> #<YAML::Syck::Node:0x82ccce0\n    #           @kind=:seq,\n    #           @value=\n    #            [#<YAML::Syck::Node:0x82ccd94\n    #              @kind=:scalar,\n    #              @type_id=\"str\",\n    #              @value=\"badger\">,\n    #             #<YAML::Syck::Node:0x82ccd58\n    #              @kind=:scalar,\n    #              @type_id=\"str\",\n    #              @value=\"elephant\">,\n    #             #<YAML::Syck::Node:0x82ccd1c\n    #              @kind=:scalar,\n    #              @type_id=\"str\",\n    #              @value=\"tiger\">]>\n    #\n    # Can also load from a string.\n    #\n    #   YAML.parse( \"--- :locked\" )\n    #      #=> #<YAML::Syck::Node:0x82edddc \n    #            @type_id=\"tag:ruby.yaml.org,2002:sym\", \n    #            @value=\":locked\", @kind=:scalar>\n    #\n\tdef YAML.parse( io )\n\t\typ = generic_parser.load( io )\n\tend\n\n    #\n    # Parse a document from the file located at _filepath_.\n    #\n    #   YAML.parse_file( 'animals.yaml' )\n    #      #=> #<YAML::Syck::Node:0x82ccce0\n    #           @kind=:seq,\n    #           @value=\n    #            [#<YAML::Syck::Node:0x82ccd94\n    #              @kind=:scalar,\n    #              @type_id=\"str\",\n    #              @value=\"badger\">,\n    #             #<YAML::Syck::Node:0x82ccd58\n    #              @kind=:scalar,\n    #              @type_id=\"str\",\n    #              @value=\"elephant\">,\n    #             #<YAML::Syck::Node:0x82ccd1c\n    #              @kind=:scalar,\n    #              @type_id=\"str\",\n    #              @value=\"tiger\">]>\n    #\n    def YAML.parse_file( filepath )\n        File.open( filepath ) do |f|\n            parse( f )\n        end\n    end\n\n\t#\n\t# Calls _block_ with each consecutive document in the YAML\n    # stream contained in _io_.\n    #\n    #   File.open( 'many-docs.yaml' ) do |yf|\n    #     YAML.each_document( yf ) do |ydoc|\n    #       ## ydoc contains the single object\n    #       ## from the YAML document\n    #     end\n    #   end\n\t#\n\tdef YAML.each_document( io, &block )\n\t\typ = parser.load_documents( io, &block )\n    end\n\n\t#\n\t# Calls _block_ with each consecutive document in the YAML\n    # stream contained in _io_.\n    #\n    #   File.open( 'many-docs.yaml' ) do |yf|\n    #     YAML.load_documents( yf ) do |ydoc|\n    #       ## ydoc contains the single object\n    #       ## from the YAML document\n    #     end\n    #   end\n\t#\n\tdef YAML.load_documents( io, &doc_proc )\n\t\tYAML.each_document( io, &doc_proc )\n    end\n\n\t#\n\t# Calls _block_ with a tree of +YAML::BaseNodes+, one tree for\n    # each consecutive document in the YAML stream contained in _io_.\n    #\n    #   File.open( 'many-docs.yaml' ) do |yf|\n    #     YAML.each_node( yf ) do |ydoc|\n    #       ## ydoc contains a tree of nodes\n    #       ## from the YAML document\n    #     end\n    #   end\n\t#\n\tdef YAML.each_node( io, &doc_proc )\n\t\typ = generic_parser.load_documents( io, &doc_proc )\n    end\n\n\t#\n\t# Calls _block_ with a tree of +YAML::BaseNodes+, one tree for\n    # each consecutive document in the YAML stream contained in _io_.\n    #\n    #   File.open( 'many-docs.yaml' ) do |yf|\n    #     YAML.parse_documents( yf ) do |ydoc|\n    #       ## ydoc contains a tree of nodes\n    #       ## from the YAML document\n    #     end\n    #   end\n\t#\n\tdef YAML.parse_documents( io, &doc_proc )\n\t\tYAML.each_node( io, &doc_proc )\n    end\n\n\t#\n\t# Loads all documents from the current _io_ stream, \n    # returning a +YAML::Stream+ object containing all\n    # loaded documents.\n\t#\n\tdef YAML.load_stream( io )\n\t\td = nil\n\t\tparser.load_documents( io ) do |doc|\n\t\t\td = YAML::Stream.new if not d\n\t\t\td.add( doc ) \n        end\n\t\treturn d\n\tend\n\n\t#\n    # Returns a YAML stream containing each of the items in +objs+,\n    # each having their own document.\n    #\n    #   YAML.dump_stream( 0, [], {} )\n    #     #=> --- 0\n    #         --- []\n    #         --- {}\n    #\n\tdef YAML.dump_stream( *objs )\n\t\td = YAML::Stream.new\n        objs.each do |doc|\n\t\t\td.add( doc ) \n        end\n        d.emit\n\tend\n\n\t#\n\t# Add a global handler for a YAML domain type.\n\t#\n\tdef YAML.add_domain_type( domain, type_tag, &transfer_proc )\n        resolver.add_type( \"tag:#{ domain }:#{ type_tag }\", transfer_proc )\n\tend\n\n\t#\n\t# Add a transfer method for a builtin type\n\t#\n\tdef YAML.add_builtin_type( type_tag, &transfer_proc )\n\t    resolver.add_type( \"tag:yaml.org,2002:#{ type_tag }\", transfer_proc )\n\tend\n\n\t#\n\t# Add a transfer method for a builtin type\n\t#\n\tdef YAML.add_ruby_type( type_tag, &transfer_proc )\n\t    resolver.add_type( \"tag:ruby.yaml.org,2002:#{ type_tag }\", transfer_proc )\n\tend\n\n\t#\n\t# Add a private document type\n\t#\n\tdef YAML.add_private_type( type_re, &transfer_proc )\n\t    resolver.add_type( \"x-private:\" + type_re, transfer_proc )\n\tend\n\n    #\n    # Detect typing of a string\n    #\n    def YAML.detect_implicit( val )\n        resolver.detect_implicit( val )\n    end\n\n    #\n    # Convert a type_id to a taguri\n    #\n    def YAML.tagurize( val )\n        resolver.tagurize( val )\n    end\n\n    #\n    # Apply a transfer method to a Ruby object\n    #\n    def YAML.transfer( type_id, obj )\n        resolver.transfer( YAML.tagurize( type_id ), obj )\n    end\n\n\t#\n\t# Apply any implicit a node may qualify for\n\t#\n\tdef YAML.try_implicit( obj )\n\t\tYAML.transfer( YAML.detect_implicit( obj ), obj )\n\tend\n\n    #\n    # Method to extract colon-seperated type and class, returning\n    # the type and the constant of the class\n    #\n    def YAML.read_type_class( type, obj_class )\n        scheme, domain, type, tclass = type.split( ':', 4 )\n        tclass.split( \"::\" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass\n        return [ type, obj_class ]\n    end\n\n    #\n    # Allocate blank object\n    #\n    def YAML.object_maker( obj_class, val )\n        if Hash === val\n            o = obj_class.allocate\n            val.each_pair { |k,v|\n                o.instance_variable_set(\"@#{k}\", v)\n            }\n            o\n        else\n            raise YAML::Error, \"Invalid object explicitly tagged !ruby/Object: \" + val.inspect\n        end\n    end\n\n\t#\n\t# Allocate an Emitter if needed\n\t#\n\tdef YAML.quick_emit( oid, opts = {}, &e )\n        out = \n            if opts.is_a? YAML::Emitter\n                opts\n            else\n                emitter.reset( opts )\n            end\n        oid =\n            case oid when Fixnum, NilClass; oid\n            else oid = \"#{oid.object_id}-#{oid.hash}\"\n            end\n        out.emit( oid, &e )\n\tend\n\t\nend\n\nrequire 'yaml/rubytypes'\nrequire 'yaml/types'\n\nmodule Kernel\n    #\n    # ryan:: You know how Kernel.p is a really convenient way to dump ruby\n    #        structures?  The only downside is that it's not as legible as\n    #        YAML.\n    #\n    # _why:: (listening)\n    #\n    # ryan:: I know you don't want to urinate all over your users' namespaces.\n    #        But, on the other hand, convenience of dumping for debugging is,\n    #        IMO, a big YAML use case.\n    #\n    # _why:: Go nuts!  Have a pony parade!\n    #\n    # ryan:: Either way, I certainly will have a pony parade.\n    #\n\n    # Prints any supplied _objects_ out in YAML.  Intended as\n    # a variation on +Kernel::p+.\n    #\n    #   S = Struct.new(:name, :state)\n    #   s = S['dave', 'TX']\n    #   y s\n    #\n    # _produces:_\n    #\n    #   --- !ruby/struct:S \n    #   name: dave\n    #   state: TX\n    #\n    def y( object, *objects )\n        objects.unshift object\n        puts( if objects.length == 1\n                  YAML::dump( *objects )\n              else\n                  YAML::dump_stream( *objects )\n              end )\n    end\n    private :y\nend\n\n\n"
  },
  {
    "path": "main.c",
    "content": "/**********************************************************************\n\n  main.c -\n\n  $Author$\n  $Date$\n  created at: Fri Aug 19 13:19:58 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\n#ifdef __human68k__\nint _stacksize = 262144;\n#endif\n\n#if defined __MINGW32__\nint _CRT_glob = 0;\n#endif\n\n#if defined(__MACOS__) && defined(__MWERKS__)\n#include <console.h>\n#endif\n\n/* to link startup code with ObjC support */\n#if (defined(__APPLE__) || defined(__NeXT__)) && defined(__MACH__)\nstatic void objcdummyfunction( void ) { objc_msgSend(); }\n#endif\n\nint\nmain(argc, argv, envp)\n    int argc;\n    char **argv, **envp;\n{\n#ifdef _WIN32\n    NtInitialize(&argc, &argv);\n#endif\n#if defined(__MACOS__) && defined(__MWERKS__)\n    argc = ccommand(&argv);\n#endif\n\n    {\n        RUBY_INIT_STACK\n        ruby_init();\n        ruby_options(argc, argv);\n        ruby_run();\n    }\n    return 0;\n}\n"
  },
  {
    "path": "marktable.c",
    "content": "/**\n * A mark table, used during a mark-and-sweep garbage collection cycle.\n *\n * This implementation is somewhat slower than default MRI, but is\n * copy-on-write friendly. It stores mark information for objects in a bit\n * field located at the beginning of the heap. Mark information for filenames\n * are stored in a pointer set.\n */\n#ifndef _MARK_TABLE_C_\n#define _MARK_TABLE_C_\n\n#include \"pointerset.h\"\n\n/* A mark table for filenames and objects that are not on the heap. */\nstatic PointerSet *mark_table = NULL;\nstatic struct heaps_slot *last_heap = NULL;\n\nstatic inline struct heaps_slot *\nfind_heap_slot_for_object(RVALUE *object)\n{\n    register int i;\n\n    /* Look in the cache first. */\n    if (last_heap != NULL && object >= last_heap->slot\n     && object < last_heap->slotlimit) {\n        return last_heap;\n    }\n    for (i = 0; i < heaps_used; i++) {\n        struct heaps_slot *heap = &heaps[i];\n        if (object >= heap->slot\n         && object < heap->slotlimit) {\n            /* Cache this result. According to empirical evidence, the chance is\n             * high that the next lookup will be for the same heap slot.\n             */\n            last_heap = heap;\n            return heap;\n        }\n    }\n    return NULL;\n}\n\nstatic inline void\nfind_position_in_bitfield(struct heaps_slot *hs, RVALUE *object,\n                          unsigned int *bitfield_index, unsigned int *bitfield_offset)\n{\n    unsigned int index;\n    index = object - hs->slot;\n\n    /*\n     * We use bit operators to calculate the position in the bit field, whenever possible.\n     * This only works if sizeof(int) is a multiple of 2, but I don't know of any platform\n     * on which that is not true.\n     */\n    if (sizeof(int) == 4 || sizeof(int) == 8 || sizeof(int) == 16) {\n        int int_bits_log; /* Must be equal to the base 2 logarithm of sizeof(int) * 8 */\n\n        switch (sizeof(int)) {\n        case 4:\n            int_bits_log = 5;\n            break;\n        case 8:\n            int_bits_log = 6;\n            break;\n        case 16:\n            int_bits_log = 7;\n            break;\n        default:\n            int_bits_log = 0; /* Shut up compiler warning. */\n            abort();\n        }\n        *bitfield_index = index >> int_bits_log;\n        *bitfield_offset = index & ((sizeof(int) * 8) - 1);\n    } else {\n        *bitfield_index = index / (sizeof(int) * 8);\n        *bitfield_offset = index % (sizeof(int) * 8);\n    }\n}\n\n\nstatic void\nrb_mark_table_init()\n{\n    if (mark_table == NULL) {\n        mark_table = pointer_set_new();\n    }\n}\n\nstatic void\nrb_mark_table_prepare()\n{\n    last_heap = NULL;\n}\n\nstatic void\nrb_mark_table_reset(lifetime_t lifetime)\n{\n    int i;\n    for (i = 0; i < heaps_used; i++) {\n        if (heaps[i].lifetime == lifetime) {\n            MEMZERO(heaps[i].marks, int, heaps[i].marks_size);\n        }\n    }\n}\n\nstatic inline void\nrb_mark_table_add(RVALUE *object)\n{\n    struct heaps_slot *hs;\n    unsigned int bitfield_index, bitfield_offset;\n\n    hs = find_heap_slot_for_object(object);\n    if (hs != NULL) {\n        find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);\n        hs->marks[bitfield_index] |= (1 << bitfield_offset);\n    } else {\n        pointer_set_insert(mark_table, (void *) object);\n    }\n}\n\nstatic inline void\nrb_mark_table_heap_add(struct heaps_slot *hs, RVALUE *object)\n{\n    unsigned int bitfield_index, bitfield_offset;\n    find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);\n    hs->marks[bitfield_index] |= (1 << bitfield_offset);\n}\n\nstatic inline int\nrb_mark_table_contains(RVALUE *object)\n{\n    struct heaps_slot *hs;\n    unsigned int bitfield_index, bitfield_offset;\n\n    hs = find_heap_slot_for_object(object);\n    if (hs != NULL) {\n        find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);\n        return hs->marks[bitfield_index] & (1 << bitfield_offset);\n    } else {\n        return pointer_set_contains(mark_table, (void *) object);\n    }\n}\n\nstatic inline int\nrb_mark_table_heap_contains(struct heaps_slot *hs, RVALUE *object)\n{\n    unsigned int bitfield_index, bitfield_offset;\n    find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);\n    last_heap = hs;\n    return hs->marks[bitfield_index] & (1 << bitfield_offset);\n}\n\nstatic inline void\nrb_mark_table_remove(RVALUE *object)\n{\n    struct heaps_slot *hs;\n    unsigned int bitfield_index, bitfield_offset;\n\n    hs = find_heap_slot_for_object(object);\n    if (hs != NULL) {\n        find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);\n        hs->marks[bitfield_index] &= ~(1 << bitfield_offset);\n    } else {\n        pointer_set_delete(mark_table, (void *) object);\n    }\n}\n\nstatic inline void\nrb_mark_table_heap_remove(struct heaps_slot *hs, RVALUE *object)\n{\n    unsigned int bitfield_index, bitfield_offset;\n    find_position_in_bitfield(hs, object, &bitfield_index, &bitfield_offset);\n    hs->marks[bitfield_index] &= ~(1 << bitfield_offset);\n}\n\nstatic inline void\nrb_mark_table_add_filename(char *filename)\n{\n    pointer_set_insert(mark_table, (void *) filename);\n}\n\nstatic inline int\nrb_mark_table_contains_filename(const char *filename)\n{\n    return pointer_set_contains(mark_table, (void *) filename);\n}\n\nstatic inline void\nrb_mark_table_remove_filename(char *filename)\n{\n    pointer_set_delete(mark_table, (void *) filename);\n}\n\n#ifdef GC_DEBUG\nstatic inline void\nrb_mark_table_add_source_pos(source_position_t *source_pos)\n{\n    pointer_set_insert(mark_table, (void *) source_pos);\n}\n\nstatic inline int\nrb_mark_table_contains_source_pos(const source_position_t *source_pos)\n{\n    return pointer_set_contains(mark_table, (void *) source_pos);\n}\n\nstatic inline void\nrb_mark_table_remove_source_pos(source_position_t *source_pos)\n{\n    pointer_set_delete(mark_table, (void *) source_pos);\n}\n#endif\n\n#endif /* _MARK_TABLE_C_ */\n"
  },
  {
    "path": "marktable.h",
    "content": "#ifndef _MARK_TABLE_H_\n#define _MARK_TABLE_H_\n\nstatic void rb_mark_table_init();\nstatic void rb_mark_table_prepare();\nstatic void rb_mark_table_reset(lifetime_t lifetime);\nstatic void rb_mark_table_add(RVALUE *object);\nstatic void rb_mark_table_heap_add(struct heaps_slot *hs, RVALUE *object);\nstatic int  rb_mark_table_contains(RVALUE *object);\nstatic int  rb_mark_table_heap_contains(struct heaps_slot *hs, RVALUE *object);\nstatic void rb_mark_table_remove(RVALUE *object);\nstatic void rb_mark_table_heap_remove(struct heaps_slot *hs, RVALUE *object);\nstatic void rb_mark_table_add_filename(char *filename);\nstatic int  rb_mark_table_contains_filename(const char *filename);\nstatic void rb_mark_table_remove_filename(char *filename);\n\n#ifdef GC_DEBUG\nstatic void rb_mark_table_add_source_pos(source_position_t *source_pos);\nstatic int  rb_mark_table_contains_source_pos(const source_position_t *source_pos);\nstatic void rb_mark_table_remove_source_pos(source_position_t *source_pos);\n#endif\n\n#endif /* _MARK_TABLE_H_ */\n"
  },
  {
    "path": "marshal.c",
    "content": "/**********************************************************************\n\n  marshal.c -\n\n  $Author$\n  $Date$\n  created at: Thu Apr 27 16:30:01 JST 1995\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubyio.h\"\n#include \"st.h\"\n#include \"util.h\"\n\n#include <math.h>\n#ifdef HAVE_FLOAT_H\n#include <float.h>\n#endif\n#ifdef HAVE_IEEEFP_H\n#include <ieeefp.h>\n#endif\n\n#define BITSPERSHORT (2*CHAR_BIT)\n#define SHORTMASK ((1<<BITSPERSHORT)-1)\n#define SHORTDN(x) RSHIFT(x,BITSPERSHORT)\n\n#if SIZEOF_SHORT == SIZEOF_BDIGITS\n#define SHORTLEN(x) (x)\n#else\nstatic int\nshortlen(len, ds)\n    long len;\n    BDIGIT *ds;\n{\n    BDIGIT num;\n    int offset = 0;\n\n    num = ds[len-1];\n    while (num) {\n\tnum = SHORTDN(num);\n\toffset++;\n    }\n    return (len - 1)*sizeof(BDIGIT)/2 + offset;\n}\n#define SHORTLEN(x) shortlen((x),d)\n#endif\n\n#define MARSHAL_MAJOR   4\n#define MARSHAL_MINOR   8\n\n#define TYPE_NIL\t'0'\n#define TYPE_TRUE\t'T'\n#define TYPE_FALSE\t'F'\n#define TYPE_FIXNUM\t'i'\n\n#define TYPE_EXTENDED\t'e'\n#define TYPE_UCLASS\t'C'\n#define TYPE_OBJECT\t'o'\n#define TYPE_DATA       'd'\n#define TYPE_USERDEF\t'u'\n#define TYPE_USRMARSHAL\t'U'\n#define TYPE_FLOAT\t'f'\n#define TYPE_BIGNUM\t'l'\n#define TYPE_STRING\t'\"'\n#define TYPE_REGEXP\t'/'\n#define TYPE_ARRAY\t'['\n#define TYPE_HASH\t'{'\n#define TYPE_HASH_DEF\t'}'\n#define TYPE_STRUCT\t'S'\n#define TYPE_MODULE_OLD\t'M'\n#define TYPE_CLASS\t'c'\n#define TYPE_MODULE\t'm'\n\n#define TYPE_SYMBOL\t':'\n#define TYPE_SYMLINK\t';'\n\n#define TYPE_IVAR\t'I'\n#define TYPE_LINK\t'@'\n\nstatic ID s_dump, s_load, s_mdump, s_mload;\nstatic ID s_dump_data, s_load_data, s_alloc, s_call;\nstatic ID s_getc, s_read, s_write, s_binmode;\n\nstruct dump_arg {\n    VALUE str, dest;\n    st_table *symbols;\n    st_table *data;\n    int taint;\n};\n\nstruct dump_call_arg {\n    VALUE obj;\n    struct dump_arg *arg;\n    int limit;\n};\n\nstatic void\ncheck_dump_arg(arg, sym)\n    struct dump_arg *arg;\n    ID sym;\n{\n    if (!arg->symbols) {\n        rb_raise(rb_eRuntimeError, \"Marshal.dump reentered at %s\",\n\t\t rb_id2name(sym));\n    }\n}\n\nstatic void clear_dump_arg _((struct dump_arg *arg));\n\nstatic void\nmark_dump_arg(ptr)\n    void *ptr;\n{\n    struct dump_arg *p = ptr;\n    if (!p->symbols)\n        return;\n    rb_mark_set(p->data);\n}\n\nstatic void\nfree_dump_arg(ptr)\n    void *ptr;\n{\n    clear_dump_arg(ptr);\n    xfree(ptr);\n}\n\nstatic VALUE\nclass2path(klass)\n    VALUE klass;\n{\n    VALUE path = rb_class_path(klass);\n    char *n = RSTRING(path)->ptr;\n\n    if (n[0] == '#') {\n\trb_raise(rb_eTypeError, \"can't dump anonymous %s %s\",\n\t\t (TYPE(klass) == T_CLASS ? \"class\" : \"module\"),\n\t\t n);\n    }\n    if (rb_path2class(n) != rb_class_real(klass)) {\n\trb_raise(rb_eTypeError, \"%s can't be referred\", n);\n    }\n    return path;\n}\n\nstatic void w_long _((long, struct dump_arg*));\n\nstatic void\nw_nbyte(s, n, arg)\n    const char *s;\n    int n;\n    struct dump_arg *arg;\n{\n    VALUE buf = arg->str;\n    rb_str_buf_cat(buf, s, n);\n    if (arg->dest && RSTRING(buf)->len >= BUFSIZ) {\n\tif (arg->taint) OBJ_TAINT(buf);\n\trb_io_write(arg->dest, buf);\n\trb_str_resize(buf, 0);\n    }\n}\n\nstatic void\nw_byte(c, arg)\n    char c;\n    struct dump_arg *arg;\n{\n    w_nbyte(&c, 1, arg);\n}\n\nstatic void\nw_bytes(s, n, arg)\n    const char *s;\n    int n;\n    struct dump_arg *arg;\n{\n    w_long(n, arg);\n    w_nbyte(s, n, arg);\n}\n\nstatic void\nw_short(x, arg)\n    int x;\n    struct dump_arg *arg;\n{\n    w_byte((x >> 0) & 0xff, arg);\n    w_byte((x >> 8) & 0xff, arg);\n}\n\nstatic void\nw_long(x, arg)\n    long x;\n    struct dump_arg *arg;\n{\n    char buf[sizeof(long)+1];\n    int i, len = 0;\n\n#if SIZEOF_LONG > 4\n    if (!(RSHIFT(x, 31) == 0 || RSHIFT(x, 31) == -1)) {\n\t/* big long does not fit in 4 bytes */\n\trb_raise(rb_eTypeError, \"long too big to dump\");\n    }\n#endif\n\n    if (x == 0) {\n\tw_byte(0, arg);\n\treturn;\n    }\n    if (0 < x && x < 123) {\n\tw_byte(x + 5, arg);\n\treturn;\n    }\n    if (-124 < x && x < 0) {\n\tw_byte((x - 5)&0xff, arg);\n\treturn;\n    }\n    for (i=1;i<sizeof(long)+1;i++) {\n\tbuf[i] = x & 0xff;\n\tx = RSHIFT(x,8);\n\tif (x == 0) {\n\t    buf[0] = i;\n\t    break;\n\t}\n\tif (x == -1) {\n\t    buf[0] = -i;\n\t    break;\n\t}\n    }\n    len = i;\n    for (i=0;i<=len;i++) {\n\tw_byte(buf[i], arg);\n    }\n}\n\n#ifdef DBL_MANT_DIG\n#define DECIMAL_MANT (53-16)\t/* from IEEE754 double precision */\n\n#if DBL_MANT_DIG > 32\n#define MANT_BITS 32\n#elif DBL_MANT_DIG > 24\n#define MANT_BITS 24\n#elif DBL_MANT_DIG > 16\n#define MANT_BITS 16\n#else\n#define MANT_BITS 8\n#endif\n\nstatic int\nsave_mantissa(d, buf)\n    double d;\n    char *buf;\n{\n    int e, i = 0;\n    unsigned long m;\n    double n;\n\n    d = modf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);\n    if (d > 0) {\n\tbuf[i++] = 0;\n\tdo {\n\t    d = modf(ldexp(d, MANT_BITS), &n);\n\t    m = (unsigned long)n;\n#if MANT_BITS > 24\n\t    buf[i++] = m >> 24;\n#endif\n#if MANT_BITS > 16\n\t    buf[i++] = m >> 16;\n#endif\n#if MANT_BITS > 8\n\t    buf[i++] = m >> 8;\n#endif\n\t    buf[i++] = m;\n\t} while (d > 0);\n\twhile (!buf[i - 1]) --i;\n    }\n    return i;\n}\n\nstatic double\nload_mantissa(d, buf, len)\n    double d;\n    const char *buf;\n    int len;\n{\n    if (--len > 0 && !*buf++) {\t/* binary mantissa mark */\n\tint e, s = d < 0, dig = 0;\n\tunsigned long m;\n\n\tmodf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);\n\tdo {\n\t    m = 0;\n\t    switch (len) {\n\t      default: m = *buf++ & 0xff;\n#if MANT_BITS > 24\n\t      case 3: m = (m << 8) | (*buf++ & 0xff);\n#endif\n#if MANT_BITS > 16\n\t      case 2: m = (m << 8) | (*buf++ & 0xff);\n#endif\n#if MANT_BITS > 8\n\t      case 1: m = (m << 8) | (*buf++ & 0xff);\n#endif\n\t    }\n\t    dig -= len < MANT_BITS / 8 ? 8 * (unsigned)len : MANT_BITS;\n\t    d += ldexp((double)m, dig);\n\t} while ((len -= MANT_BITS / 8) > 0);\n\td = ldexp(d, e - DECIMAL_MANT);\n\tif (s) d = -d;\n    }\n    return d;\n}\n#else\n#define load_mantissa(d, buf, len) (d)\n#define save_mantissa(d, buf) 0\n#endif\n\n#ifdef DBL_DIG\n#define FLOAT_DIG (DBL_DIG+2)\n#else\n#define FLOAT_DIG 17\n#endif\n\nstatic void\nw_float(d, arg)\n    double d;\n    struct dump_arg *arg;\n{\n    char buf[100];\n\n    if (isinf(d)) {\n\tif (d < 0) strcpy(buf, \"-inf\");\n\telse       strcpy(buf, \"inf\");\n    }\n    else if (isnan(d)) {\n\tstrcpy(buf, \"nan\");\n    }\n    else if (d == 0.0) {\n\tif (1.0/d < 0) strcpy(buf, \"-0\");\n\telse           strcpy(buf, \"0\");\n    }\n    else {\n\tint len;\n\n\t/* xxx: should not use system's sprintf(3) */\n\tsprintf(buf, \"%.*g\", FLOAT_DIG, d);\n\tlen = strlen(buf);\n\tw_bytes(buf, len + save_mantissa(d, buf + len), arg);\n\treturn;\n    }\n    w_bytes(buf, strlen(buf), arg);\n}\n\nstatic void\nw_symbol(id, arg)\n    ID id;\n    struct dump_arg *arg;\n{\n    const char *sym = rb_id2name(id);\n    st_data_t num;\n\n    if (st_lookup(arg->symbols, id, &num)) {\n\tw_byte(TYPE_SYMLINK, arg);\n\tw_long((long)num, arg);\n    }\n    else {\n\tw_byte(TYPE_SYMBOL, arg);\n\tw_bytes(sym, strlen(sym), arg);\n\tst_add_direct(arg->symbols, id, arg->symbols->num_entries);\n    }\n}\n\nstatic void\nw_unique(s, arg)\n    const char *s;\n    struct dump_arg *arg;\n{\n    if (s[0] == '#') {\n\trb_raise(rb_eTypeError, \"can't dump anonymous class %s\", s);\n    }\n    w_symbol(rb_intern(s), arg);\n}\n\nstatic void w_object _((VALUE,struct dump_arg*,int));\n\nstatic int\nhash_each(key, value, arg)\n    VALUE key, value;\n    struct dump_call_arg *arg;\n{\n    w_object(key, arg->arg, arg->limit);\n    w_object(value, arg->arg, arg->limit);\n    return ST_CONTINUE;\n}\n\nstatic void\nw_extended(klass, arg, check)\n    VALUE klass;\n    struct dump_arg *arg;\n    int check;\n{\n    const char *path;\n\n    if (check && FL_TEST(klass, FL_SINGLETON)) {\n\tif (RCLASS(klass)->m_tbl->num_entries ||\n\t    (RCLASS(klass)->iv_tbl && RCLASS(klass)->iv_tbl->num_entries > 1)) {\n\t    rb_raise(rb_eTypeError, \"singleton can't be dumped\");\n\t}\n\tklass = RCLASS(klass)->super;\n    }\n    while (BUILTIN_TYPE(klass) == T_ICLASS) {\n\tpath = rb_class2name(RBASIC(klass)->klass);\n\tw_byte(TYPE_EXTENDED, arg);\n\tw_unique(path, arg);\n\tklass = RCLASS(klass)->super;\n    }\n}\n\nstatic void\nw_class(type, obj, arg, check)\n    int type;\n    VALUE obj;\n    struct dump_arg *arg;\n    int check;\n{\n    char *path;\n\n    VALUE klass = CLASS_OF(obj);\n    w_extended(klass, arg, check);\n    w_byte(type, arg);\n    path = RSTRING(class2path(rb_class_real(klass)))->ptr;\n    w_unique(path, arg);\n}\n\nstatic void\nw_uclass(obj, base_klass, arg)\n    VALUE obj, base_klass;\n    struct dump_arg *arg;\n{\n    VALUE klass = CLASS_OF(obj);\n\n    w_extended(klass, arg, Qtrue);\n    klass = rb_class_real(klass);\n    if (klass != base_klass) {\n\tw_byte(TYPE_UCLASS, arg);\n\tw_unique(RSTRING(class2path(klass))->ptr, arg);\n    }\n}\n\nstatic int\nw_obj_each(id, value, arg)\n    ID id;\n    VALUE value;\n    struct dump_call_arg *arg;\n{\n    w_symbol(id, arg->arg);\n    w_object(value, arg->arg, arg->limit);\n    return ST_CONTINUE;\n}\n\nstatic void\nw_ivar(tbl, arg)\n    st_table *tbl;\n    struct dump_call_arg *arg;\n{\n    if (tbl) {\n\tw_long(tbl->num_entries, arg->arg);\n\tst_foreach_safe(tbl, w_obj_each, (st_data_t)arg);\n    }\n    else {\n\tw_long(0, arg->arg);\n    }\n}\n\nstatic void\nw_object(obj, arg, limit)\n    VALUE obj;\n    struct dump_arg *arg;\n    int limit;\n{\n    struct dump_call_arg c_arg;\n    st_table *ivtbl = 0;\n    st_data_t num;\n\n    if (limit == 0) {\n\trb_raise(rb_eArgError, \"exceed depth limit\");\n    }\n\n    limit--;\n    c_arg.limit = limit;\n    c_arg.arg = arg;\n\n    if (st_lookup(arg->data, obj, &num)) {\n\tw_byte(TYPE_LINK, arg);\n\tw_long((long)num, arg);\n\treturn;\n    }\n\n    if ((ivtbl = rb_generic_ivar_table(obj)) != 0) {\n\tw_byte(TYPE_IVAR, arg);\n    }\n    if (obj == Qnil) {\n\tw_byte(TYPE_NIL, arg);\n    }\n    else if (obj == Qtrue) {\n\tw_byte(TYPE_TRUE, arg);\n    }\n    else if (obj == Qfalse) {\n\tw_byte(TYPE_FALSE, arg);\n    }\n    else if (FIXNUM_P(obj)) {\n#if SIZEOF_LONG <= 4\n\tw_byte(TYPE_FIXNUM, arg);\n\tw_long(FIX2INT(obj), arg);\n#else\n\tif (RSHIFT((long)obj, 31) == 0 || RSHIFT((long)obj, 31) == -1) {\n\t    w_byte(TYPE_FIXNUM, arg);\n\t    w_long(FIX2LONG(obj), arg);\n\t}\n\telse {\n\t    w_object(rb_int2big(FIX2LONG(obj)), arg, limit);\n\t}\n#endif\n    }\n    else if (SYMBOL_P(obj)) {\n\tw_symbol(SYM2ID(obj), arg);\n    }\n    else {\n\tif (OBJ_TAINTED(obj)) arg->taint = Qtrue;\n\n\tst_add_direct(arg->data, obj, arg->data->num_entries);\n\tif (rb_respond_to(obj, s_mdump)) {\n\t    volatile VALUE v;\n\n\t    v = rb_funcall(obj, s_mdump, 0, 0);\n\t    check_dump_arg(arg, s_mdump);\n\t    w_class(TYPE_USRMARSHAL, obj, arg, Qfalse);\n\t    w_object(v, arg, limit);\n\t    if (ivtbl) w_ivar(0, &c_arg);\n\t    return;\n\t}\n\tif (rb_respond_to(obj, s_dump)) {\n\t    VALUE v;\n\n\t    v = rb_funcall(obj, s_dump, 1, INT2NUM(limit));\n\t    check_dump_arg(arg, s_dump);\n\t    if (TYPE(v) != T_STRING) {\n\t\trb_raise(rb_eTypeError, \"_dump() must return string\");\n\t    }\n\t    if (!ivtbl && (ivtbl = rb_generic_ivar_table(v))) {\n\t\tw_byte(TYPE_IVAR, arg);\n\t    }\n\t    w_class(TYPE_USERDEF, obj, arg, Qfalse);\n\t    w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg);\n\t    if (ivtbl) {\n\t\tw_ivar(ivtbl, &c_arg);\n\t    }\n\t    return;\n\t}\n\n\tswitch (BUILTIN_TYPE(obj)) {\n\t  case T_CLASS:\n\t    if (FL_TEST(obj, FL_SINGLETON)) {\n\t\trb_raise(rb_eTypeError, \"singleton class can't be dumped\");\n\t    }\n\t    w_byte(TYPE_CLASS, arg);\n\t    {\n\t\tVALUE path = class2path(obj);\n\t\tw_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);\n\t    }\n\t    break;\n\n\t  case T_MODULE:\n\t    w_byte(TYPE_MODULE, arg);\n\t    {\n\t\tVALUE path = class2path(obj);\n\t\tw_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);\n\t    }\n\t    break;\n\n\t  case T_FLOAT:\n\t    w_byte(TYPE_FLOAT, arg);\n\t    w_float(RFLOAT(obj)->value, arg);\n\t    break;\n\n\t  case T_BIGNUM:\n\t    w_byte(TYPE_BIGNUM, arg);\n\t    {\n\t\tchar sign = RBIGNUM(obj)->sign ? '+' : '-';\n\t\tlong len = RBIGNUM(obj)->len;\n\t\tBDIGIT *d = RBIGNUM(obj)->digits;\n\n\t\tw_byte(sign, arg);\n\t\tw_long(SHORTLEN(len), arg); /* w_short? */\n\t\twhile (len--) {\n#if SIZEOF_BDIGITS > SIZEOF_SHORT\n\t\t    BDIGIT num = *d;\n\t\t    int i;\n\n\t\t    for (i=0; i<SIZEOF_BDIGITS; i+=SIZEOF_SHORT) {\n\t\t\tw_short(num & SHORTMASK, arg);\n\t\t\tnum = SHORTDN(num);\n\t\t\tif (len == 0 && num == 0) break;\n\t\t    }\n#else\n\t\t    w_short(*d, arg);\n#endif\n\t\t    d++;\n\t\t}\n\t    }\n\t    break;\n\n\t  case T_STRING:\n\t    w_uclass(obj, rb_cString, arg);\n\t    w_byte(TYPE_STRING, arg);\n\t    w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg);\n\t    break;\n\n\t  case T_REGEXP:\n\t    w_uclass(obj, rb_cRegexp, arg);\n\t    w_byte(TYPE_REGEXP, arg);\n\t    w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg);\n\t    w_byte(rb_reg_options(obj), arg);\n\t    break;\n\n\t  case T_ARRAY:\n\t    w_uclass(obj, rb_cArray, arg);\n\t    w_byte(TYPE_ARRAY, arg);\n\t    {\n\t\tlong len = RARRAY(obj)->len;\n\t\tVALUE *ptr = RARRAY(obj)->ptr;\n\n\t\tw_long(len, arg);\n\t\twhile (len--) {\n\t\t    w_object(*ptr, arg, limit);\n\t\t    ptr++;\n\t\t}\n\t    }\n\t    break;\n\n\t  case T_HASH:\n\t    w_uclass(obj, rb_cHash, arg);\n\t    if (NIL_P(RHASH(obj)->ifnone)) {\n\t\tw_byte(TYPE_HASH, arg);\n\t    }\n\t    else if (FL_TEST(obj, FL_USER2)) {\n\t\t/* FL_USER2 means HASH_PROC_DEFAULT (see hash.c) */\n\t\trb_raise(rb_eTypeError, \"can't dump hash with default proc\");\n\t    }\n\t    else {\n\t\tw_byte(TYPE_HASH_DEF, arg);\n\t    }\n\t    w_long(RHASH(obj)->tbl->num_entries, arg);\n\t    rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg);\n\t    if (!NIL_P(RHASH(obj)->ifnone)) {\n\t\tw_object(RHASH(obj)->ifnone, arg, limit);\n\t    }\n\t    break;\n\n\t  case T_STRUCT:\n\t    w_class(TYPE_STRUCT, obj, arg, Qtrue);\n\t    {\n\t\tlong len = RSTRUCT(obj)->len;\n\t\tVALUE mem;\n\t\tlong i;\n\n\t\tw_long(len, arg);\n\t\tmem = rb_struct_members(obj);\n\t\tfor (i=0; i<len; i++) {\n\t\t    w_symbol(SYM2ID(RARRAY(mem)->ptr[i]), arg);\n\t\t    w_object(RSTRUCT(obj)->ptr[i], arg, limit);\n\t\t}\n\t    }\n\t    break;\n\n\t  case T_OBJECT:\n\t    w_class(TYPE_OBJECT, obj, arg, Qtrue);\n\t    w_ivar(ROBJECT(obj)->iv_tbl, &c_arg);\n\t    break;\n\n\t  case T_DATA:\n\t    {\n\t\tVALUE v;\n\n\t\tif (!rb_respond_to(obj, s_dump_data)) {\n\t\t    rb_raise(rb_eTypeError,\n\t\t\t     \"no marshal_dump is defined for class %s\",\n\t\t\t     rb_obj_classname(obj));\n\t\t}\n\t\tv = rb_funcall(obj, s_dump_data, 0);\n\t\tcheck_dump_arg(arg, s_dump_data);\n\t\tw_class(TYPE_DATA, obj, arg, Qtrue);\n\t\tw_object(v, arg, limit);\n\t    }\n\t    break;\n\n\t  default:\n\t    rb_raise(rb_eTypeError, \"can't dump %s\",\n\t\t     rb_obj_classname(obj));\n\t    break;\n\t}\n    }\n    if (ivtbl) {\n\tw_ivar(ivtbl, &c_arg);\n    }\n}\n\nstatic void\nclear_dump_arg(arg)\n    struct dump_arg *arg;\n{\n    if (!arg->symbols) return;\n    st_free_table(arg->symbols);\n    arg->symbols = 0;\n    st_free_table(arg->data);\n    if (arg->taint) {\n\tOBJ_TAINT(arg->str);\n    }\n}\n\n/*\n * call-seq:\n *      dump( obj [, anIO] , limit=--1 ) => anIO\n *\n * Serializes obj and all descendent objects. If anIO is\n * specified, the serialized data will be written to it, otherwise the\n * data will be returned as a String. If limit is specified, the\n * traversal of subobjects will be limited to that depth. If limit is\n * negative, no checking of depth will be performed.\n *\n *     class Klass\n *       def initialize(str)\n *         @str = str\n *       end\n *       def sayHello\n *         @str\n *       end\n *     end\n *\n * (produces no output)\n *\n *     o = Klass.new(\"hello\\n\")\n *     data = Marshal.dump(o)\n *     obj = Marshal.load(data)\n *     obj.sayHello   #=> \"hello\\n\"\n */\nstatic VALUE\nmarshal_dump(argc, argv)\n    int argc;\n    VALUE* argv;\n{\n    VALUE obj, port, a1, a2;\n    int limit = -1;\n    struct dump_arg *arg;\n    VALUE wrapper;\n\n    port = Qnil;\n    rb_scan_args(argc, argv, \"12\", &obj, &a1, &a2);\n    if (argc == 3) {\n\tif (!NIL_P(a2)) limit = NUM2INT(a2);\n\tif (NIL_P(a1)) goto type_error;\n\tport = a1;\n    }\n    else if (argc == 2) {\n\tif (FIXNUM_P(a1)) limit = FIX2INT(a1);\n\telse if (NIL_P(a1)) goto type_error;\n\telse port = a1;\n    }\n    wrapper = Data_Make_Struct(rb_cData, struct dump_arg, mark_dump_arg, free_dump_arg, arg);\n    arg->dest = 0;\n    arg->symbols = st_init_numtable();\n    arg->data    = st_init_numtable();\n    arg->taint   = Qfalse;\n    arg->str = rb_str_buf_new(0);\n    RBASIC(arg->str)->klass = 0;\n    if (!NIL_P(port)) {\n\tif (!rb_respond_to(port, s_write)) {\n\t  type_error:\n\t    rb_raise(rb_eTypeError, \"instance of IO needed\");\n\t}\n\targ->dest = port;\n\tif (rb_respond_to(port, s_binmode)) {\n\t    rb_funcall2(port, s_binmode, 0, 0);\n\t    check_dump_arg(arg, s_binmode);\n\t}\n    }\n    else {\n\tport = arg->str;\n    }\n\n    w_byte(MARSHAL_MAJOR, arg);\n    w_byte(MARSHAL_MINOR, arg);\n\n    w_object(obj, arg, limit);\n    if (arg->dest) {\n\trb_io_write(arg->dest, arg->str);\n\trb_str_resize(arg->str, 0);\n    }\n\n    RBASIC(arg->str)->klass = rb_cString;\n    clear_dump_arg(arg);\n    RB_GC_GUARD(wrapper);\n\n    return port;\n}\n\nstruct load_arg {\n    VALUE src;\n    long offset;\n    st_table *symbols;\n    st_table *data;\n    VALUE proc;\n    int taint;\n};\n\nstatic void\ncheck_load_arg(arg, sym)\n    struct load_arg *arg;\n    ID sym;\n{\n    if (!arg->symbols) {\n        rb_raise(rb_eRuntimeError, \"Marshal.load reentered at %s\",\n\t\t rb_id2name(sym));\n    }\n}\n\nstatic void clear_load_arg _((struct load_arg *arg));\n\nstatic void\nmark_load_arg(ptr)\n    void *ptr;\n{\n    struct load_arg *p = ptr;\n    if (!p->symbols)\n        return;\n    rb_mark_tbl(p->data);\n}\n\nstatic void\nfree_load_arg(void *ptr)\n{\n    clear_load_arg(ptr);\n    xfree(ptr);\n}\n\nstatic VALUE r_object _((struct load_arg *arg));\n\nstatic int\nr_byte(arg)\n    struct load_arg *arg;\n{\n    int c;\n\n    if (TYPE(arg->src) == T_STRING) {\n\tif (RSTRING(arg->src)->len > arg->offset) {\n\t    c = (unsigned char)RSTRING(arg->src)->ptr[arg->offset++];\n\t}\n\telse {\n\t    rb_raise(rb_eArgError, \"marshal data too short\");\n\t}\n    }\n    else {\n\tVALUE src = arg->src;\n\tVALUE v = rb_funcall2(src, s_getc, 0, 0);\n\tcheck_load_arg(arg, s_getc);\n\tif (NIL_P(v)) rb_eof_error();\n\tc = (unsigned char)FIX2INT(v);\n    }\n    return c;\n}\n\nstatic void\nlong_toobig(size)\n    int size;\n{\n    rb_raise(rb_eTypeError, \"long too big for this architecture (size %d, given %d)\",\n\t     sizeof(long), size);\n}\n\n#undef SIGN_EXTEND_CHAR\n#if __STDC__\n# define SIGN_EXTEND_CHAR(c) ((signed char)(c))\n#else  /* not __STDC__ */\n/* As in Harbison and Steele.  */\n# define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)\n#endif\n\nstatic long\nr_long(arg)\n    struct load_arg *arg;\n{\n    register long x;\n    int c = SIGN_EXTEND_CHAR(r_byte(arg));\n    long i;\n\n    if (c == 0) return 0;\n    if (c > 0) {\n\tif (4 < c && c < 128) {\n\t    return c - 5;\n\t}\n\tif (c > sizeof(long)) long_toobig(c);\n\tx = 0;\n\tfor (i=0;i<c;i++) {\n\t    x |= (long)r_byte(arg) << (8*i);\n\t}\n    }\n    else {\n\tif (-129 < c && c < -4) {\n\t    return c + 5;\n\t}\n\tc = -c;\n\tif (c > sizeof(long)) long_toobig(c);\n\tx = -1;\n\tfor (i=0;i<c;i++) {\n\t    x &= ~((long)0xff << (8*i));\n\t    x |= (long)r_byte(arg) << (8*i);\n\t}\n    }\n    return x;\n}\n\n#define r_bytes(arg) r_bytes0(r_long(arg), (arg))\n\nstatic VALUE\nr_bytes0(len, arg)\n    long len;\n    struct load_arg *arg;\n{\n    VALUE str;\n\n    if (len == 0) return rb_str_new(0, 0);\n    if (TYPE(arg->src) == T_STRING) {\n\tif (RSTRING(arg->src)->len - arg->offset >= len) {\n\t    str = rb_str_new(RSTRING(arg->src)->ptr+arg->offset, len);\n\t    arg->offset += len;\n\t}\n\telse {\n\t  too_short:\n\t    rb_raise(rb_eArgError, \"marshal data too short\");\n\t}\n    }\n    else {\n\tVALUE src = arg->src;\n\tVALUE n = LONG2NUM(len);\n\tstr = rb_funcall2(src, s_read, 1, &n);\n\tcheck_load_arg(arg, s_read);\n\tif (NIL_P(str)) goto too_short;\n\tStringValue(str);\n\tif (RSTRING(str)->len != len) goto too_short;\n\tif (OBJ_TAINTED(str)) arg->taint = Qtrue;\n    }\n    return str;\n}\n\nstatic ID\nr_symlink(arg)\n    struct load_arg *arg;\n{\n    ID id;\n    long num = r_long(arg);\n\n    if (st_lookup(arg->symbols, num, &id)) {\n\treturn id;\n    }\n    rb_raise(rb_eArgError, \"bad symbol\");\n}\n\nstatic ID\nr_symreal(arg)\n    struct load_arg *arg;\n{\n    ID id;\n\n    id = rb_intern(RSTRING(r_bytes(arg))->ptr);\n    st_insert(arg->symbols, arg->symbols->num_entries, id);\n\n    return id;\n}\n\nstatic ID\nr_symbol(arg)\n    struct load_arg *arg;\n{\n    if (r_byte(arg) == TYPE_SYMLINK) {\n\treturn r_symlink(arg);\n    }\n    return r_symreal(arg);\n}\n\nstatic const char*\nr_unique(arg)\n    struct load_arg *arg;\n{\n    return rb_id2name(r_symbol(arg));\n}\n\nstatic VALUE\nr_string(arg)\n    struct load_arg *arg;\n{\n    return r_bytes(arg);\n}\n\nstatic VALUE\nr_entry(v, arg)\n    VALUE v;\n    struct load_arg *arg;\n{\n    st_insert(arg->data, arg->data->num_entries, (st_data_t)v);\n    if (arg->taint) OBJ_TAINT(v);\n    return v;\n}\n\nstatic void\nr_ivar(obj, arg)\n    VALUE obj;\n    struct load_arg *arg;\n{\n    long len;\n\n    len = r_long(arg);\n    if (len > 0) {\n\twhile (len--) {\n\t    ID id = r_symbol(arg);\n\t    VALUE val = r_object(arg);\n\t    rb_ivar_set(obj, id, val);\n\t}\n    }\n}\n\nstatic VALUE\npath2class(path)\n    const char *path;\n{\n    VALUE v = rb_path2class(path);\n\n    if (TYPE(v) != T_CLASS) {\n\trb_raise(rb_eArgError, \"%s does not refer class\", path);\n    }\n    return v;\n}\n\nstatic VALUE\npath2module(path)\n    const char *path;\n{\n    VALUE v = rb_path2class(path);\n\n    if (TYPE(v) != T_MODULE) {\n\trb_raise(rb_eArgError, \"%s does not refer module\", path);\n    }\n    return v;\n}\n\nstatic VALUE\nr_object0(arg, proc, ivp, extmod)\n    struct load_arg *arg;\n    VALUE proc;\n    int *ivp;\n    VALUE extmod;\n{\n    VALUE v = Qnil;\n    int type = r_byte(arg);\n    long id;\n    st_data_t link;\n\n    switch (type) {\n      case TYPE_LINK:\n\tid = r_long(arg);\n \tif (!st_lookup(arg->data, (st_data_t)id, &link)) {\n\t    rb_raise(rb_eArgError, \"dump format error (unlinked)\");\n\t}\n\tv = (st_data_t)link;\n\treturn v;\n\n      case TYPE_IVAR:\n        {\n\t    int ivar = Qtrue;\n\n\t    v = r_object0(arg, 0, &ivar, extmod);\n\t    if (ivar) r_ivar(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_EXTENDED:\n\t{\n\t    VALUE m = path2module(r_unique(arg));\n\n            if (NIL_P(extmod)) extmod = rb_ary_new2(0);\n            rb_ary_push(extmod, m);\n\n\t    v = r_object0(arg, 0, 0, extmod);\n            while (RARRAY(extmod)->len > 0) {\n                m = rb_ary_pop(extmod);\n                rb_extend_object(v, m);\n            }\n\t}\n\tbreak;\n\n      case TYPE_UCLASS:\n\t{\n\t    VALUE c = path2class(r_unique(arg));\n\n\t    if (FL_TEST(c, FL_SINGLETON)) {\n\t\trb_raise(rb_eTypeError, \"singleton can't be loaded\");\n\t    }\n\t    v = r_object0(arg, 0, 0, extmod);\n\t    if (rb_special_const_p(v) || TYPE(v) == T_OBJECT || TYPE(v) == T_CLASS) {\n\t      format_error:\n\t\trb_raise(rb_eArgError, \"dump format error (user class)\");\n\t    }\n\t    if (TYPE(v) == T_MODULE || !RTEST(rb_class_inherited_p(c, RBASIC(v)->klass))) {\n\t\tVALUE tmp = rb_obj_alloc(c);\n\n\t\tif (TYPE(v) != TYPE(tmp)) goto format_error;\n\t    }\n\t    RBASIC(v)->klass = c;\n\t}\n\tbreak;\n\n      case TYPE_NIL:\n\tv = Qnil;\n\tbreak;\n\n      case TYPE_TRUE:\n\tv = Qtrue;\n\tbreak;\n\n      case TYPE_FALSE:\n\tv = Qfalse;\n\tbreak;\n\n      case TYPE_FIXNUM:\n\t{\n\t    long i = r_long(arg);\n\t    v = LONG2FIX(i);\n\t}\n\tbreak;\n\n      case TYPE_FLOAT:\n\t{\n\t    double d, t = 0.0;\n\t    VALUE str = r_bytes(arg);\n\t    const char *ptr = RSTRING(str)->ptr;\n\n\t    if (strcmp(ptr, \"nan\") == 0) {\n\t\td = t / t;\n\t    }\n\t    else if (strcmp(ptr, \"inf\") == 0) {\n\t\td = 1.0 / t;\n\t    }\n\t    else if (strcmp(ptr, \"-inf\") == 0) {\n\t\td = -1.0 / t;\n\t    }\n\t    else {\n\t\tchar *e;\n\t\td = strtod(ptr, &e);\n\t\td = load_mantissa(d, e, RSTRING(str)->len - (e - ptr));\n\t    }\n\t    v = rb_float_new(d);\n\t    r_entry(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_BIGNUM:\n\t{\n\t    long len;\n\t    BDIGIT *digits;\n\t    volatile VALUE data;\n\n\t    NEWOBJ(big, struct RBignum);\n\t    OBJSETUP(big, rb_cBignum, T_BIGNUM);\n\t    big->sign = (r_byte(arg) == '+');\n\t    len = r_long(arg);\n\t    data = r_bytes0(len * 2, arg);\n#if SIZEOF_BDIGITS == SIZEOF_SHORT\n\t    big->len = len;\n#else\n\t    big->len = (len + 1) * 2 / sizeof(BDIGIT);\n#endif\n\t    big->digits = digits = ALLOC_N(BDIGIT, big->len);\n\t    MEMCPY(digits, RSTRING(data)->ptr, char, len * 2);\n#if SIZEOF_BDIGITS > SIZEOF_SHORT\n\t    MEMZERO((char *)digits + len * 2, char,\n\t\t    big->len * sizeof(BDIGIT) - len * 2);\n#endif\n\t    len = big->len;\n\t    while (len > 0) {\n\t\tunsigned char *p = (unsigned char *)digits;\n\t\tBDIGIT num = 0;\n#if SIZEOF_BDIGITS > SIZEOF_SHORT\n\t\tint shift = 0;\n\t\tint i;\n\n\t\tfor (i=0; i<SIZEOF_BDIGITS; i++) {\n\t\t    num |= (int)p[i] << shift;\n\t\t    shift += 8;\n\t\t}\n#else\n\t\tnum = p[0] | (p[1] << 8);\n#endif\n\t\t*digits++ = num;\n\t\tlen--;\n\t    }\n\t    v = rb_big_norm((VALUE)big);\n\t    r_entry(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_STRING:\n\tv = r_entry(r_string(arg), arg);\n\tbreak;\n\n      case TYPE_REGEXP:\n\t{\n\t    volatile VALUE str = r_bytes(arg);\n\t    int options = r_byte(arg);\n\t    v = r_entry(rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, options), arg);\n\t}\n\tbreak;\n\n      case TYPE_ARRAY:\n\t{\n\t    volatile long len = r_long(arg); /* gcc 2.7.2.3 -O2 bug?? */\n\n\t    v = rb_ary_new2(len);\n\t    r_entry(v, arg);\n\t    while (len--) {\n\t\trb_ary_push(v, r_object(arg));\n\t    }\n\t}\n\tbreak;\n\n      case TYPE_HASH:\n      case TYPE_HASH_DEF:\n\t{\n\t    long len = r_long(arg);\n\n\t    v = rb_hash_new();\n\t    r_entry(v, arg);\n\t    while (len--) {\n\t\tVALUE key = r_object(arg);\n\t\tVALUE value = r_object(arg);\n\t\trb_hash_aset(v, key, value);\n\t    }\n\t    if (type == TYPE_HASH_DEF) {\n\t\tRHASH(v)->ifnone = r_object(arg);\n\t    }\n\t}\n\tbreak;\n\n      case TYPE_STRUCT:\n\t{\n\t    VALUE klass, mem, values;\n\t    volatile long i;\t/* gcc 2.7.2.3 -O2 bug?? */\n\t    long len;\n\t    ID slot;\n\n\t    klass = path2class(r_unique(arg));\n\t    mem = rb_struct_s_members(klass);\n\t    len = r_long(arg);\n\n\t    values = rb_ary_new2(len);\n\t    for (i=0; i<len; i++) {\n\t\trb_ary_push(values, Qnil);\n\t    }\n\t    v = rb_struct_alloc(klass, values);\n\t    r_entry(v, arg);\n\t    for (i=0; i<len; i++) {\n\t\tslot = r_symbol(arg);\n\n\t\tif (RARRAY(mem)->ptr[i] != ID2SYM(slot)) {\n\t\t    rb_raise(rb_eTypeError, \"struct %s not compatible (:%s for :%s)\",\n\t\t\t     rb_class2name(klass),\n\t\t\t     rb_id2name(slot),\n\t\t\t     rb_id2name(SYM2ID(RARRAY(mem)->ptr[i])));\n\t\t}\n\t\trb_struct_aset(v, LONG2FIX(i), r_object(arg));\n\t    }\n\t}\n\tbreak;\n\n      case TYPE_USERDEF:\n        {\n\t    VALUE klass = path2class(r_unique(arg));\n\t    VALUE data;\n\n\t    if (!rb_respond_to(klass, s_load)) {\n\t\trb_raise(rb_eTypeError, \"class %s needs to have method `_load'\",\n\t\t\t rb_class2name(klass));\n\t    }\n\t    data = r_string(arg);\n\t    if (ivp) {\n\t\tr_ivar(data, arg);\n\t\t*ivp = Qfalse;\n\t    }\n\t    v = rb_funcall(klass, s_load, 1, data);\n\t    check_load_arg(arg, s_load);\n\t    r_entry(v, arg);\n\t}\n        break;\n\n      case TYPE_USRMARSHAL:\n        {\n\t    VALUE klass = path2class(r_unique(arg));\n\t    VALUE data;\n\n\t    v = rb_obj_alloc(klass);\n            if (! NIL_P(extmod)) {\n                while (RARRAY(extmod)->len > 0) {\n                    VALUE m = rb_ary_pop(extmod);\n                    rb_extend_object(v, m);\n                }\n            }\n\t    if (!rb_respond_to(v, s_mload)) {\n\t\trb_raise(rb_eTypeError, \"instance of %s needs to have method `marshal_load'\",\n\t\t\t rb_class2name(klass));\n\t    }\n\t    r_entry(v, arg);\n\t    data = r_object(arg);\n\t    rb_funcall(v, s_mload, 1, data);\n\t    check_load_arg(arg, s_mload);\n\t}\n        break;\n\n      case TYPE_OBJECT:\n\t{\n\t    VALUE klass = path2class(r_unique(arg));\n\n\t    v = rb_obj_alloc(klass);\n\t    if (TYPE(v) != T_OBJECT) {\n\t\trb_raise(rb_eArgError, \"dump format error\");\n\t    }\n\t    r_entry(v, arg);\n\t    r_ivar(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_DATA:\n       {\n           VALUE klass = path2class(r_unique(arg));\n           if (rb_respond_to(klass, s_alloc)) {\n\t       static int warn = Qtrue;\n\t       if (warn) {\n\t\t   rb_warn(\"define `allocate' instead of `_alloc'\");\n\t\t   warn = Qfalse;\n\t       }\n\t       v = rb_funcall(klass, s_alloc, 0);\n\t       check_load_arg(arg, s_alloc);\n           }\n\t   else {\n\t       v = rb_obj_alloc(klass);\n\t   }\n           if (TYPE(v) != T_DATA) {\n               rb_raise(rb_eArgError, \"dump format error\");\n           }\n           r_entry(v, arg);\n           if (!rb_respond_to(v, s_load_data)) {\n               rb_raise(rb_eTypeError,\n                        \"class %s needs to have instance method `_load_data'\",\n                        rb_class2name(klass));\n           }\n           rb_funcall(v, s_load_data, 1, r_object0(arg, 0, 0, extmod));\n\t   check_load_arg(arg, s_load_data);\n       }\n       break;\n\n      case TYPE_MODULE_OLD:\n        {\n\t    volatile VALUE str = r_bytes(arg);\n\n\t    v = rb_path2class(RSTRING(str)->ptr);\n\t    r_entry(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_CLASS:\n        {\n\t    volatile VALUE str = r_bytes(arg);\n\n\t    v = path2class(RSTRING(str)->ptr);\n\t    r_entry(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_MODULE:\n        {\n\t    volatile VALUE str = r_bytes(arg);\n\n\t    v = path2module(RSTRING(str)->ptr);\n\t    r_entry(v, arg);\n\t}\n\tbreak;\n\n      case TYPE_SYMBOL:\n\tv = ID2SYM(r_symreal(arg));\n\tbreak;\n\n      case TYPE_SYMLINK:\n\treturn ID2SYM(r_symlink(arg));\n\n      default:\n\trb_raise(rb_eArgError, \"dump format error(0x%x)\", type);\n\tbreak;\n    }\n    if (proc) {\n\trb_funcall(proc, s_call, 1, v);\n\tcheck_load_arg(arg, s_call);\n    }\n    return v;\n}\n\nstatic VALUE\nr_object(arg)\n    struct load_arg *arg;\n{\n    return r_object0(arg, arg->proc, 0, Qnil);\n}\n\nstatic void\nclear_load_arg(arg)\n    struct load_arg *arg;\n{\n    if (!arg->symbols) return;\n    st_free_table(arg->symbols);\n    arg->symbols = 0;\n    st_free_table(arg->data);\n}\n\n/*\n * call-seq:\n *     load( source [, proc] ) => obj\n *     restore( source [, proc] ) => obj\n * \n * Returns the result of converting the serialized data in source into a\n * Ruby object (possibly with associated subordinate objects). source\n * may be either an instance of IO or an object that responds to\n * to_str. If proc is specified, it will be passed each object as it\n * is deserialized.\n */\nstatic VALUE\nmarshal_load(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE port, proc;\n    int major, minor, taint = Qfalse;\n    VALUE v, wrapper;\n    struct load_arg *arg;\n\n    rb_scan_args(argc, argv, \"11\", &port, &proc);\n    v = rb_check_string_type(port);\n    if (!NIL_P(v)) {\n\ttaint = OBJ_TAINTED(port); /* original taintedness */\n\tport = v;\n    }\n    else if (rb_respond_to(port, s_getc) && rb_respond_to(port, s_read)) {\n\tif (rb_respond_to(port, s_binmode)) {\n\t    rb_funcall2(port, s_binmode, 0, 0);\n\t}\n\ttaint = Qtrue;\n    }\n    else {\n\trb_raise(rb_eTypeError, \"instance of IO needed\");\n    }\n    wrapper = Data_Make_Struct(rb_cData, struct load_arg, mark_load_arg, free_load_arg, arg);\n    arg->src = port;\n    arg->offset = 0;\n    arg->symbols = st_init_numtable();\n    arg->data    = st_init_numtable();\n    arg->proc = 0;\n    arg->taint = taint;\n\n    major = r_byte(arg);\n    minor = r_byte(arg);\n    if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {\n\tclear_load_arg(arg);\n\trb_raise(rb_eTypeError, \"incompatible marshal file format (can't be read)\\n\\\n\\tformat version %d.%d required; %d.%d given\",\n\t\t MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);\n    }\n    if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {\n\trb_warn(\"incompatible marshal file format (can be read)\\n\\\n\\tformat version %d.%d required; %d.%d given\",\n\t\tMARSHAL_MAJOR, MARSHAL_MINOR, major, minor);\n    }\n\n    if (!NIL_P(proc)) arg->proc = proc;\n    v = r_object(arg);\n    clear_load_arg(arg);\n    RB_GC_GUARD(wrapper);\n\n    return v;\n}\n\n/*\n * The marshaling library converts collections of Ruby objects into a\n * byte stream, allowing them to be stored outside the currently\n * active script. This data may subsequently be read and the original\n * objects reconstituted.\n * Marshaled data has major and minor version numbers stored along\n * with the object information. In normal use, marshaling can only\n * load data written with the same major version number and an equal\n * or lower minor version number. If Ruby's ``verbose'' flag is set\n * (normally using -d, -v, -w, or --verbose) the major and minor\n * numbers must match exactly. Marshal versioning is independent of\n * Ruby's version numbers. You can extract the version by reading the\n * first two bytes of marshaled data.\n *\n *     str = Marshal.dump(\"thing\")\n *     RUBY_VERSION   #=> \"1.8.0\"\n *     str[0]         #=> 4\n *     str[1]         #=> 8\n *\n * Some objects cannot be dumped: if the objects to be dumped include\n * bindings, procedure or method objects, instances of class IO, or\n * singleton objects, a TypeError will be raised.\n * If your class has special serialization needs (for example, if you\n * want to serialize in some specific format), or if it contains\n * objects that would otherwise not be serializable, you can implement\n * your own serialization strategy by defining two methods, _dump and\n * _load:\n * The instance method _dump should return a String object containing\n * all the information necessary to reconstitute objects of this class\n * and all referenced objects up to a maximum depth given as an integer\n * parameter (a value of -1 implies that you should disable depth checking).\n * The class method _load should take a String and return an object of this class.\n */\nvoid\nInit_marshal()\n{\n    VALUE rb_mMarshal = rb_define_module(\"Marshal\");\n\n    s_dump = rb_intern(\"_dump\");\n    s_load = rb_intern(\"_load\");\n    s_mdump = rb_intern(\"marshal_dump\");\n    s_mload = rb_intern(\"marshal_load\");\n    s_dump_data = rb_intern(\"_dump_data\");\n    s_load_data = rb_intern(\"_load_data\");\n    s_alloc = rb_intern(\"_alloc\");\n    s_call = rb_intern(\"call\");\n    s_getc = rb_intern(\"getc\");\n    s_read = rb_intern(\"read\");\n    s_write = rb_intern(\"write\");\n    s_binmode = rb_intern(\"binmode\");\n\n    rb_define_module_function(rb_mMarshal, \"dump\", marshal_dump, -1);\n    rb_define_module_function(rb_mMarshal, \"load\", marshal_load, -1);\n    rb_define_module_function(rb_mMarshal, \"restore\", marshal_load, -1);\n\n    rb_define_const(rb_mMarshal, \"MAJOR_VERSION\", INT2FIX(MARSHAL_MAJOR));\n    rb_define_const(rb_mMarshal, \"MINOR_VERSION\", INT2FIX(MARSHAL_MINOR));\n}\n\nVALUE\nrb_marshal_dump(obj, port)\n    VALUE obj, port;\n{\n    int argc = 1;\n    VALUE argv[2];\n\n    argv[0] = obj;\n    argv[1] = port;\n    if (!NIL_P(port)) argc = 2;\n    return marshal_dump(argc, argv);\n}\n\nVALUE\nrb_marshal_load(port)\n    VALUE port;\n{\n    return marshal_load(1, &port);\n}\n"
  },
  {
    "path": "math.c",
    "content": "/**********************************************************************\n\n  math.c -\n\n  $Author$\n  $Date$\n  created at: Tue Jan 25 14:12:56 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include <math.h>\n#include <errno.h>\n\nVALUE rb_mMath;\n\n#define Need_Float(x) (x) = rb_Float(x)\n#define Need_Float2(x,y) do {\\\n    Need_Float(x);\\\n    Need_Float(y);\\\n} while (0)\n\nstatic void\ndomain_check(x, msg)\n    double x;\n    char *msg;\n{\n    while(1) {\n\tif (errno) {\n\t    rb_sys_fail(msg);\n\t}\n\tif (isnan(x)) {\n#if defined(EDOM)\n\t    errno = EDOM;\n#elif defined(ERANGE)\n\t    errno = ERANGE;\n#endif\n\t    continue;\n\t}\n\tbreak;\n    }\n}\n\n\n/*\n *  call-seq:\n *     Math.atan2(y, x)  => float\n *  \n *  Computes the arc tangent given <i>y</i> and <i>x</i>. Returns\n *  -PI..PI.\n *     \n */\n\nstatic VALUE\nmath_atan2(obj, y, x)\n    VALUE obj, x, y;\n{\n    Need_Float2(y, x);\n    return rb_float_new(atan2(RFLOAT(y)->value, RFLOAT(x)->value));\n}\n\n\n/*\n *  call-seq:\n *     Math.cos(x)    => float\n *  \n *  Computes the cosine of <i>x</i> (expressed in radians). Returns\n *  -1..1.\n */\n\nstatic VALUE\nmath_cos(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(cos(RFLOAT(x)->value));\n}\n\n/*\n *  call-seq:\n *     Math.sin(x)    => float\n *  \n *  Computes the sine of <i>x</i> (expressed in radians). Returns\n *  -1..1.\n */\n\nstatic VALUE\nmath_sin(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n\n    return rb_float_new(sin(RFLOAT(x)->value));\n}\n\n\n/*\n *  call-seq:\n *     Math.tan(x)    => float\n *  \n *  Returns the tangent of <i>x</i> (expressed in radians).\n */\n\nstatic VALUE\nmath_tan(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n\n    return rb_float_new(tan(RFLOAT(x)->value));\n}\n\n/*\n *  call-seq:\n *     Math.acos(x)    => float\n *  \n *  Computes the arc cosine of <i>x</i>. Returns 0..PI.\n */\n\nstatic VALUE\nmath_acos(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = acos(RFLOAT(x)->value);\n    domain_check(d, \"acos\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.asin(x)    => float\n *  \n *  Computes the arc sine of <i>x</i>. Returns -{PI/2} .. {PI/2}.\n */\n\nstatic VALUE\nmath_asin(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = asin(RFLOAT(x)->value);\n    domain_check(d, \"asin\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.atan(x)    => float\n *  \n *  Computes the arc tangent of <i>x</i>. Returns -{PI/2} .. {PI/2}.\n */\n\nstatic VALUE\nmath_atan(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(atan(RFLOAT(x)->value));\n}\n\n#ifndef HAVE_COSH\ndouble\ncosh(x)\n    double x;\n{\n    return (exp(x) + exp(-x)) / 2;\n}\n#endif\n\n/*\n *  call-seq:\n *     Math.cosh(x)    => float\n *  \n *  Computes the hyperbolic cosine of <i>x</i> (expressed in radians).\n */\n\nstatic VALUE\nmath_cosh(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    \n    return rb_float_new(cosh(RFLOAT(x)->value));\n}\n\n#ifndef HAVE_SINH\ndouble\nsinh(x)\n    double x;\n{\n    return (exp(x) - exp(-x)) / 2;\n}\n#endif\n\n/*\n *  call-seq:\n *     Math.sinh(x)    => float\n *  \n *  Computes the hyperbolic sine of <i>x</i> (expressed in\n *  radians).\n */\n\nstatic VALUE\nmath_sinh(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(sinh(RFLOAT(x)->value));\n}\n\n#ifndef HAVE_TANH\ndouble\ntanh(x)\n    double x;\n{\n    return sinh(x) / cosh(x);\n}\n#endif\n\n/*\n *  call-seq:\n *     Math.tanh()    => float\n *  \n *  Computes the hyperbolic tangent of <i>x</i> (expressed in\n *  radians).\n */\n\nstatic VALUE\nmath_tanh(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(tanh(RFLOAT(x)->value));\n}\n\n/*\n *  call-seq:\n *     Math.acosh(x)    => float\n *  \n *  Computes the inverse hyperbolic cosine of <i>x</i>.\n */\n\nstatic VALUE\nmath_acosh(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = acosh(RFLOAT(x)->value);\n    domain_check(d, \"acosh\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.asinh(x)    => float\n *  \n *  Computes the inverse hyperbolic sine of <i>x</i>.\n */\n\nstatic VALUE\nmath_asinh(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(asinh(RFLOAT(x)->value));\n}\n\n/*\n *  call-seq:\n *     Math.atanh(x)    => float\n *  \n *  Computes the inverse hyperbolic tangent of <i>x</i>.\n */\n\nstatic VALUE\nmath_atanh(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = atanh(RFLOAT(x)->value);\n    domain_check(d, \"atanh\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.exp(x)    => float\n *  \n *  Returns e**x.\n */\n\nstatic VALUE\nmath_exp(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(exp(RFLOAT(x)->value));\n}\n\n#if defined __CYGWIN__\n# include <cygwin/version.h>\n# if CYGWIN_VERSION_DLL_MAJOR < 1005\n#  define nan(x) nan()\n# endif\n# define log(x) ((x) < 0.0 ? nan(\"\") : log(x))\n# define log10(x) ((x) < 0.0 ? nan(\"\") : log10(x))\n#endif\n\n/*\n *  call-seq:\n *     Math.log(numeric)    => float\n *  \n *  Returns the natural logarithm of <i>numeric</i>.\n */\n\nstatic VALUE\nmath_log(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = log(RFLOAT(x)->value);\n    domain_check(d, \"log\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.log10(numeric)    => float\n *  \n *  Returns the base 10 logarithm of <i>numeric</i>.\n */\n\nstatic VALUE\nmath_log10(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = log10(RFLOAT(x)->value);\n    domain_check(d, \"log10\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.sqrt(numeric)    => float\n *  \n *  Returns the non-negative square root of <i>numeric</i>.\n */\n\nstatic VALUE\nmath_sqrt(obj, x)\n    VALUE obj, x;\n{\n    double d;\n\n    Need_Float(x);\n    errno = 0;\n    d = sqrt(RFLOAT(x)->value);\n    domain_check(d, \"sqrt\");\n    return rb_float_new(d);\n}\n\n/*\n *  call-seq:\n *     Math.frexp(numeric)    => [ fraction, exponent ]\n *  \n *  Returns a two-element array containing the normalized fraction (a\n *  <code>Float</code>) and exponent (a <code>Fixnum</code>) of\n *  <i>numeric</i>.\n *     \n *     fraction, exponent = Math.frexp(1234)   #=> [0.6025390625, 11]\n *     fraction * 2**exponent                  #=> 1234.0\n */\n\nstatic VALUE\nmath_frexp(obj, x)\n    VALUE obj, x;\n{\n    double d;\n    int exp;\n\n    Need_Float(x);\n    \n    d = frexp(RFLOAT(x)->value, &exp);\n    return rb_assoc_new(rb_float_new(d), INT2NUM(exp));\n}\n\n/*\n *  call-seq:\n *     Math.ldexp(flt, int) -> float\n *  \n *  Returns the value of <i>flt</i>*(2**<i>int</i>).\n *     \n *     fraction, exponent = Math.frexp(1234)\n *     Math.ldexp(fraction, exponent)   #=> 1234.0\n */\n\nstatic VALUE\nmath_ldexp(obj, x, n)\n    VALUE obj, x, n;\n{\n    Need_Float(x);\n    return rb_float_new(ldexp(RFLOAT(x)->value, NUM2INT(n)));\n}\n\n/*\n *  call-seq:\n *     Math.hypot(x, y)    => float\n *  \n *  Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle\n *  with sides <i>x</i> and <i>y</i>.\n *     \n *     Math.hypot(3, 4)   #=> 5.0\n */\n\nstatic VALUE\nmath_hypot(obj, x, y)\n    VALUE obj, x, y;\n{\n    Need_Float2(x, y);\n    return rb_float_new(hypot(RFLOAT(x)->value, RFLOAT(y)->value));\n}\n\n/*\n * call-seq:\n *    Math.erf(x)  => float\n *\n *  Calculates the error function of x.\n */\n\nstatic VALUE\nmath_erf(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(erf(RFLOAT(x)->value));\n}\n\n/*\n * call-seq:\n *    Math.erfc(x)  => float\n *\n *  Calculates the complementary error function of x.\n */\n\nstatic VALUE\nmath_erfc(obj, x)\n    VALUE obj, x;\n{\n    Need_Float(x);\n    return rb_float_new(erfc(RFLOAT(x)->value));\n}\n\n/*\n *  The <code>Math</code> module contains module functions for basic\n *  trigonometric and transcendental functions. See class\n *  <code>Float</code> for a list of constants that\n *  define Ruby's floating point accuracy.\n */     \n\n\nvoid\nInit_Math()\n{\n    rb_mMath = rb_define_module(\"Math\");\n\n#ifdef M_PI\n    rb_define_const(rb_mMath, \"PI\", rb_float_new(M_PI));\n#else\n    rb_define_const(rb_mMath, \"PI\", rb_float_new(atan(1.0)*4.0));\n#endif\n\n#ifdef M_E\n    rb_define_const(rb_mMath, \"E\", rb_float_new(M_E));\n#else\n    rb_define_const(rb_mMath, \"E\", rb_float_new(exp(1.0)));\n#endif\n\n    rb_define_module_function(rb_mMath, \"atan2\", math_atan2, 2);\n    rb_define_module_function(rb_mMath, \"cos\", math_cos, 1);\n    rb_define_module_function(rb_mMath, \"sin\", math_sin, 1);\n    rb_define_module_function(rb_mMath, \"tan\", math_tan, 1);\n\n    rb_define_module_function(rb_mMath, \"acos\", math_acos, 1);\n    rb_define_module_function(rb_mMath, \"asin\", math_asin, 1);\n    rb_define_module_function(rb_mMath, \"atan\", math_atan, 1);\n\n    rb_define_module_function(rb_mMath, \"cosh\", math_cosh, 1);\n    rb_define_module_function(rb_mMath, \"sinh\", math_sinh, 1);\n    rb_define_module_function(rb_mMath, \"tanh\", math_tanh, 1);\n\n    rb_define_module_function(rb_mMath, \"acosh\", math_acosh, 1);\n    rb_define_module_function(rb_mMath, \"asinh\", math_asinh, 1);\n    rb_define_module_function(rb_mMath, \"atanh\", math_atanh, 1);\n\n    rb_define_module_function(rb_mMath, \"exp\", math_exp, 1);\n    rb_define_module_function(rb_mMath, \"log\", math_log, 1);\n    rb_define_module_function(rb_mMath, \"log10\", math_log10, 1);\n    rb_define_module_function(rb_mMath, \"sqrt\", math_sqrt, 1);\n\n    rb_define_module_function(rb_mMath, \"frexp\", math_frexp, 1);\n    rb_define_module_function(rb_mMath, \"ldexp\", math_ldexp, 2);\n\n    rb_define_module_function(rb_mMath, \"hypot\", math_hypot, 2);\n\n    rb_define_module_function(rb_mMath, \"erf\",  math_erf,  1);\n    rb_define_module_function(rb_mMath, \"erfc\", math_erfc, 1);\n}\n"
  },
  {
    "path": "mdoc2man.rb",
    "content": "#!/usr/bin/env ruby\n###\n### mdoc2man - mdoc to man converter\n###\n### Quick usage:  mdoc2man.rb < mdoc_manpage.8 > man_manpage.8\n###\n### Ported from Perl by Akinori MUSHA.\n###\n###  Copyright (c) 2001 University of Illinois Board of Trustees\n###  Copyright (c) 2001 Mark D. Roth\n###  Copyright (c) 2002, 2003 Akinori MUSHA\n###  All rights reserved.\n### \n###  Redistribution and use in source and binary forms, with or without\n###  modification, are permitted provided that the following conditions\n###  are met:\n###  1. Redistributions of source code must retain the above copyright\n###     notice, this list of conditions and the following disclaimer.\n###  2. Redistributions in binary form must reproduce the above copyright\n###     notice, this list of conditions and the following disclaimer in the\n###     documentation and/or other materials provided with the distribution.\n###  3. All advertising materials mentioning features or use of this software\n###     must display the following acknowledgement:\n###     This product includes software developed by the University of\n###     Illinois at Urbana, and their contributors.\n###  4. The University nor the names of their\n###     contributors may be used to endorse or promote products derived from\n###     this software without specific prior written permission.\n### \n###  THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND\n###  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n###  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n###  ARE DISCLAIMED.  IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE\n###  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n###  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n###  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n###  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n###  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n###  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n###  SUCH DAMAGE.\n###\n### $Id$\n###\n\nclass Mdoc2Man\n  ANGLE = 1\n  OPTION = 2\n  PAREN = 3\n\n  RE_PUNCT = /^[!\"'),\\.\\/:;>\\?\\]`]$/\n\n  def initialize\n    @name = @date = @id = nil\n    @refauthors = @reftitle = @refissue = @refdate = @refopt = nil\n\n    @optlist = 0\t\t### 1 = bullet, 2 = enum, 3 = tag, 4 = item\n    @oldoptlist = 0\n    @nospace = 0\t\t### 0, 1, 2\n    @enum = 0\n    @synopsis = true\n    @reference = false\n    @ext = false\n    @extopt = false\n    @literal = false\n  end\n\n  def mdoc2man(i, o)\n    i.each { |line|\n      if /^\\./ !~ line\n\to.print line\n\to.print \".br\\n\" if @literal\n\tnext\n      end\n\n      line.slice!(0, 1)\n\n      next if /\\\\\"/ =~ line\n\n      line = parse_macro(line) and o.print line\n    }\n\n    initialize\n  end\n\n  def parse_macro(line)\n    words = line.split\n    retval = ''\n\n    quote = []\n    dl = false\n\n    while word = words.shift\n      case word\n      when RE_PUNCT\n\twhile q = quote.pop\n\t  case q\n\t  when OPTION\n\t    retval << ']'\n\t  when PAREN\n\t    retval << ')'\n\t  when ANGLE\n\t    retval << '>'\n\t  end\n\tend\n\tretval << word\n\tnext\n      when 'Li', 'Pf'\n\t@nospace = 1\n\tnext\n      when 'Xo'\n\t@ext = true\n\tretval << ' ' unless retval.empty? || /[\\n ]\\z/ =~ retval\n\tnext\n      when 'Xc'\n\t@ext = false\n\tretval << \"\\n\" unless @extopt\n\tbreak\n      when 'Bd'\n\t@literal = true if words[0] == '-literal'\n\tretval << \"\\n\"\n\tbreak\n      when 'Ed'\n\t@literal = false\n\tbreak\n      when 'Ns'\n\t@nospace = 1 if @nospace == 0\n\tretval.chomp!(' ')\n\tnext\n      when 'No'\n\tretval.chomp!(' ')\n\tretval << words.shift\n\tnext\n      when 'Dq'\n\tretval << '``'\n\tbegin\n\t  retval << words.shift << ' '\n\tend until words.empty? || RE_PUNCT =~ words[0]\n\tretval.chomp!(' ')\n\tretval << '\\'\\''\n\t@nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]\n\tnext\n      when 'Sq', 'Ql'\n\tretval << '`' << words.shift << '\\''\n\t@nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]\n\tnext\n\t# when  'Ic'\n\t#   retval << '\\\\fB' << words.shift << '\\\\fP'\n\t#   next\n      when 'Oo'\n\t#retval << \"[\\\\c\\n\"\n\t@extopt = true\n\t@nospace = 1 if @nospace == 0\n\tretval << '['\n\tnext\n      when 'Oc'\n\t@extopt = false\n\tretval << ']'\n\tnext\n      when 'Ao'\n\t@nospace = 1 if @nospace == 0\n\tretval << '<'\n\tnext\n      when 'Ac'\n\tretval << '>'\n\tnext\n      end\n\n      retval << ' ' if @nospace == 0 && !(retval.empty? || /[\\n ]\\z/ =~ retval)\n      @nospace = 0 if @nospace == 1\n\n      case word\n      when 'Dd'\n\t@date = words.join(' ')\n\treturn nil\n      when 'Dt'\n\tif words.size >= 2 && words[1] == '\"\"' &&\n\t    /^(.*)\\(([0-9])\\)$/ =~ words[0]\n\t  words[0] = $1\n\t  words[1] = $2\n\tend\n\t@id = words.join(' ')\n\treturn nil\n      when 'Os'\n\tretval << '.TH ' << @id << ' \"' << @date << '\" \"' <<\n\t  words.join(' ') << '\"'\n\tbreak\n      when 'Sh'\n\tretval << '.SH'\n\t@synopsis = (words[0] == 'SYNOPSIS')\n\tnext\n      when 'Xr'\n\tretval << '\\\\fB' << words.shift <<\n\t  '\\\\fP(' << words.shift << ')' << words.shift\n\tbreak\n      when 'Rs'\n\t@refauthors = []\n\t@reftitle = ''\n\t@refissue = ''\n\t@refdate = ''\n\t@refopt = ''\n\t@reference = true\n\tbreak\n      when 'Re'\n\tretval << \"\\n\"\n\n\t# authors\n\twhile @refauthors.size > 1\n\t  retval << @refauthors.shift << ', '\n\tend\n\tretval << 'and ' unless retval.empty?\n\tretval << @refauthors.shift\n\n\t# title \n\tretval << ', \\\\fI' << @reftitle << '\\\\fP'\n\n\t# issue\n\tretval << ', ' << @refissue unless @refissue.empty?\n\n\t# date\n\tretval << ', ' << @refdate unless @refdate.empty?\n\n\t# optional info\n\tretval << ', ' << @refopt unless @refopt.empty?\n\n\tretval << \".\\n\"\n\n\t@reference = false\n\tbreak\n      when 'An'\n\tnext\n      when 'Dl'\n\tretval << \".nf\\n\" << '\\\\&  '\n\tdl = true\n\tnext\n      when 'Ux'\n\tretval << \"UNIX\"\n\tnext\n      end\n\n      if @reference\n\tcase word\n\twhen '%A'\n\t  @refauthors.unshift(words.join(' '))\n\t  break\n\twhen '%T'\n\t  @reftitle = words.join(' ')\n\t  @reftitle.sub!(/^\"/, '')\n\t  @reftitle.sub!(/\"$/, '')\n\t  break\n\twhen '%N'\n\t  @refissue = words.join(' ')\n\t  break\n\twhen '%D'\n\t  @refdate = words.join(' ')\n\t  break\n\twhen '%O'\n\t  @refopt = words.join(' ')\n\t  break\n\tend\n      end\n\n      case word\n      when 'Nm'\n\tname = words.empty? ? @name : words.shift\n\t@name ||= name\n\tretval << \".br\\n\" if @synopsis\n\tretval << \"\\\\fB\" << name << \"\\\\fP\"\n\t@nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]\n\tnext\n      when 'Nd'\n\tretval << '\\\\-'\n\tnext\n      when 'Fl'\n\tretval << '\\\\fB\\\\-' << words.shift << '\\\\fP'\n\t@nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]\n\tnext\n      when 'Ar'\n\tretval << '\\\\fI'\n\tif words.empty?\n\t  retval << 'file ...\\\\fP'\n\telse\n\t  retval << words.shift << '\\\\fP'\n\t  while words[0] == '|'\n\t    retval << ' ' << words.shift << ' \\\\fI' << words.shift << '\\\\fP'\n\t  end\n\t  @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]\n\t  next\n\tend\n      when 'Cm'\n\tretval << '\\\\fB' << words.shift << '\\\\fP'\n\twhile RE_PUNCT =~ words[0]\n\t  retval << words.shift\n\tend\n\tnext\n      when 'Op'\n\tquote << OPTION\n\t@nospace = 1 if @nospace == 0\n\tretval << '['\n\t# words.push(words.pop + ']')\n\tnext\n      when 'Aq'\n\tquote << ANGLE\n\t@nospace = 1 if @nospace == 0\n\tretval << '<'\n\t# words.push(words.pop + '>')\n\tnext\n      when 'Pp'\n\tretval << \"\\n\"\n\tnext\n      when 'Ss'\n\tretval << '.SS'\n\tnext\n      end\n\n      if word == 'Pa' && !quote.include?(OPTION)\n\tretval << '\\\\fI'\n\tretval << '\\\\&' if /^\\./ =~ words[0]\n\tretval << words.shift << '\\\\fP'\n\twhile RE_PUNCT =~ words[0]\n\t  retval << words.shift\n\tend\n\t# @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]\n\tnext\n      end\n\n      case word\n      when 'Dv'\n\tretval << '.BR'\n\tnext\n      when 'Em', 'Ev'\n\tretval << '.IR'\n\tnext\n      when 'Pq'\n\tretval << '('\n\t@nospace = 1\n\tquote << PAREN\n\tnext\n      when 'Sx', 'Sy'\n\tretval << '.B ' << words.join(' ')\n\tbreak\n      when 'Ic'\n\tretval << '\\\\fB'\n\tuntil words.empty? || RE_PUNCT =~ words[0]\n\t  case words[0]\n\t  when 'Op'\n\t    words.shift\n\t    retval << '['\n\t    words.push(words.pop + ']')\n\t    next\n\t  when 'Aq'\n\t    words.shift\n\t    retval << '<'\n\t    words.push(words.pop + '>')\n\t    next\n\t  when 'Ar'\n\t    words.shift\n\t    retval << '\\\\fI' << words.shift << '\\\\fP'\n\t  else\n\t    retval << words.shift\n\t  end\n\n\t  retval << ' ' if @nospace == 0\n\tend\n\n\tretval.chomp!(' ')\n\tretval << '\\\\fP'\n\tretval << words.shift unless words.empty?\n\tbreak\n      when 'Bl'\n\t@oldoptlist = @optlist\n\n\tcase words[0]\n\twhen '-bullet'\n\t  @optlist = 1\n\twhen '-enum'\n\t  @optlist = 2\n\t  @enum = 0\n\twhen '-tag'\n\t  @optlist = 3\n\twhen '-item'\n\t  @optlist = 4\n\tend\n\n\tbreak\n      when 'El'\n\t@optlist = @oldoptlist\n\tnext\n      end\n\n      if @optlist != 0 && word == 'It'\n\tcase @optlist\n\twhen 1\n\t  # bullets\n\t  retval << '.IP \\\\(bu'\n\twhen 2\n\t  # enum\n\t  @enum += 1\n\t  retval << '.IP ' << @enum << '.'\n\twhen 3\n\t  # tags\n\t  retval << \".TP\\n\"\n\t  case words[0]\n\t  when 'Pa', 'Ev'\n\t    words.shift\n\t    retval << '.B'\n\t  end\n\twhen 4\n\t  # item\n\t  retval << \".IP\\n\"\n\tend\n\n\tnext\n      end\n\n      case word\n      when 'Sm'\n\tcase words[0]\n\twhen 'off'\n\t  @nospace = 2\n\twhen 'on'\n\t  # retval << \"\\n\"\n\t  @nospace = 0\n\tend\n\twords.shift\n\tnext\n      end\n\n      retval << word\n    end\n\n    return nil if retval == '.'\n\n    retval.sub!(/\\A\\.([^a-zA-Z])/, \"\\\\1\")\n    # retval.chomp!(' ')\n\n    while q = quote.pop\n      case q\n      when OPTION\n\tretval << ']'\n      when PAREN\n\tretval << ')'\n      when ANGLE\n\tretval << '>'\n      end\n    end\n\n    # retval << ' ' unless @nospace == 0 || retval.empty? || /\\n\\z/ =~ retval\n\n    retval << ' ' unless !@ext || @extopt || / $/ =~ retval\n\n    retval << \"\\n\" unless @ext || @extopt || retval.empty? || /\\n\\z/ =~ retval\n\n    retval << \".fi\\n\" if dl\n\n    return retval\n  end\n\n  def self.mdoc2man(i, o)\n    new.mdoc2man(i, o)\n  end\nend\n\nif $0 == __FILE__\n  Mdoc2Man.mdoc2man(ARGF, STDOUT)\nend\n"
  },
  {
    "path": "misc/README",
    "content": "README            this file\ninf-ruby.el       program to run ruby under emacs\nruby-mode.el      ruby mode for emacs\nrubydb2x.el       ruby debugger support for emacs 19.2x or before\nrubydb3x.el       ruby debugger support for emacs 19.3x or later\nruby-electric.el  emacs minor mode providing electric commands\n\nCheck out http://rubyforge.org/projects/ruby-debug/ also.\n"
  },
  {
    "path": "misc/inf-ruby.el",
    "content": ";;; -*-Emacs-Lisp-*-\n;;;\n;;;  $Id$\n;;;  $Author$\n;;;  $Date$\n;;;\n;;; Inferior Ruby Mode - ruby process in a buffer.\n;;;                      adapted from cmuscheme.el\n;;;\n;;; Usage:\n;;;\n;;; (0) check ruby-program-name variable that can run your environment.\n;;;\n;;; (1) modify .emacs to use ruby-mode \n;;;     for example :\n;;;\n;;;    (autoload 'ruby-mode \"ruby-mode\"\n;;;      \"Mode for editing ruby source files\" t)\n;;;    (setq auto-mode-alist\n;;;          (append '((\"\\\\.rb$\" . ruby-mode)) auto-mode-alist))\n;;;    (setq interpreter-mode-alist (append '((\"ruby\" . ruby-mode))\n;;;    \t\t\t\t     interpreter-mode-alist))\n;;;    \n;;; (2) set to load inf-ruby and set inf-ruby key definition in ruby-mode.\n;;;\n;;;    (autoload 'run-ruby \"inf-ruby\"\n;;;      \"Run an inferior Ruby process\")\n;;;    (autoload 'inf-ruby-keys \"inf-ruby\"\n;;;      \"Set local key defs for inf-ruby in ruby-mode\")\n;;;    (add-hook 'ruby-mode-hook\n;;;          '(lambda ()\n;;;             (inf-ruby-keys)\n;;;    ))\n;;;\n;;; HISTORY\n;;; senda -  8 Apr 1998: Created.\n;;;\t $Log$\n;;;\t Revision 1.7  2004/07/27 08:11:36  matz\n;;;\t * eval.c (rb_eval): copy on write for argument local variable\n;;;\t   assignment.\n;;;\n;;;\t * eval.c (assign): ditto.\n;;;\n;;;\t * eval.c (rb_call0): update ruby_frame->argv with the default\n;;;\t   value used for the optional arguments.\n;;;\n;;;\t * object.c (Init_Object): \"===\" calls rb_obj_equal() directly.\n;;;\t   [ruby-list:39937]\n;;;\n;;;\t Revision 1.6  2002/09/07 14:35:46  nobu\n;;;\t * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp\n;;;\t   alist for error message from ruby.\n;;;\t\n;;;\t * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs.\n;;;\t\n;;;\t * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors\n;;;\t   doesn't parse first line, so insert separators before each\n;;;\t   evaluations.\n;;;\t\n;;;\t Revision 1.5  2002/08/19 10:05:47  nobu\n;;;\t * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition\n;;;\t   conflicted with ruby-insert-end.\n;;;\t\n;;;\t * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode.\n;;;\t\n;;;\t * misc/inf-ruby.el (ruby-send-region): send as here document to\n;;;\t   adjust source file/line.  [ruby-talk:47113], [ruby-dev:17965]\n;;;\t\n;;;\t * misc/inf-ruby.el (ruby-send-terminator): added to make unique\n;;;\t   terminator.\n;;;\t\n;;;\t Revision 1.4  2002/01/29 07:16:09  matz\n;;;\t * file.c (rb_stat_rdev_major): added. [new]\n;;;\t\n;;;\t * file.c (rb_stat_rdev_minor): added. [new]\n;;;\t\n;;;\t * file.c (rb_stat_inspect): print mode in octal.\n;;;\t\n;;;\t Revision 1.3  1999/12/01 09:24:18  matz\n;;;\t 19991201\n;;;\t\n;;;\t Revision 1.2  1999/08/13 05:45:18  matz\n;;;\t 1.4.0\n;;;\t\n;;;\t Revision 1.1.1.1.2.1  1999/07/15 07:59:59  matz\n;;;\t 990715\n;;;\t\n;;;\t Revision 1.1.1.1  1999/01/20 04:59:36  matz\n;;;\t ruby 1.3 cycle\n;;;\t\n;;;\t Revision 1.1.2.1  1998/12/16 07:30:36  matz\n;;;\t first public release of 1.1d (pre1.2) series\n;;;\t\n;;;\t Revision 1.4  1998/05/20 02:45:58  senda\n;;;\t default program to irb\n;;;\n;;;\t Revision 1.3  1998/04/10 04:11:30  senda\n;;;\t modification by Matsumoto san (1.1b9_09)\n;;;\t remove-in-string defined\n;;;\t global variable :\n;;;\t \t inferior-ruby-first-prompt-pattern\n;;;\t       inferior-ruby-prompt-pattern\n;;;\t defined\n;;;\n;;;\t Revision 1.2  1998/04/09 07:53:42  senda\n;;;\t remove M-C-x in inferior-ruby-mode\n;;;\n;;;\t Revision 1.1  1998/04/09 07:28:36  senda\n;;;\t Initial revision\n;;;\n;;;\n\n(require 'comint)\n(require 'compile)\n(require 'ruby-mode)\n\n;;\n;; you may change these variables\n;;\n;(defvar ruby-program-name \"rbc --noreadline\"\n;  \"*Program invoked by the run-ruby command\")\n;\n;(defvar inferior-ruby-first-prompt-pattern \"^rbc0> *\"\n;  \"first prompt regex pattern of ruby interpreter.\")\n;\n;(defvar inferior-ruby-prompt-pattern \"^\\\\(rbc.[>*\\\"'] *\\\\)+\"\n;  \"prompt regex pattern of ruby interpreter.\")\n\n;;;; for irb\n(defvar ruby-program-name \"irb --inf-ruby-mode\"\n  \"*Program invoked by the run-ruby command\")\n\n(defvar inferior-ruby-first-prompt-pattern \"^irb(.*)[0-9:]+0> *\"\n  \"first prompt regex pattern of ruby interpreter.\")\n\n(defvar inferior-ruby-prompt-pattern \"^\\\\(irb(.*)[0-9:]+[>*\\\"'] *\\\\)+\"\n  \"prompt regex pattern of ruby interpreter.\")\n\n;;\n;; mode variables\n;;\n(defvar inferior-ruby-mode-hook nil\n  \"*Hook for customising inferior-ruby mode.\")\n(defvar inferior-ruby-mode-map nil\n  \"*Mode map for inferior-ruby-mode\")\n\n(defconst inferior-ruby-error-regexp-alist\n       '((\"SyntaxError: compile error\\n^\\\\([^\\(].*\\\\):\\\\([1-9][0-9]*\\\\):\" 1 2)\n\t (\"^\\tfrom \\\\([^\\(].*\\\\):\\\\([1-9][0-9]*\\\\)\\\\(:in `.*'\\\\)?$\" 1 2)))\n\n(cond ((not inferior-ruby-mode-map)\n       (setq inferior-ruby-mode-map\n\t     (copy-keymap comint-mode-map))\n;       (define-key inferior-ruby-mode-map \"\\M-\\C-x\" ;gnu convention\n;\t           'ruby-send-definition)\n;       (define-key inferior-ruby-mode-map \"\\C-x\\C-e\" 'ruby-send-last-sexp)\n       (define-key inferior-ruby-mode-map \"\\C-c\\C-l\" 'ruby-load-file)\n))\n\n(defun inf-ruby-keys ()\n  \"Set local key defs for inf-ruby in ruby-mode\"\n  (define-key ruby-mode-map \"\\M-\\C-x\" 'ruby-send-definition)\n;  (define-key ruby-mode-map \"\\C-x\\C-e\" 'ruby-send-last-sexp)\n  (define-key ruby-mode-map \"\\C-c\\C-b\" 'ruby-send-block)\n  (define-key ruby-mode-map \"\\C-c\\M-b\" 'ruby-send-block-and-go)\n  (define-key ruby-mode-map \"\\C-c\\C-x\" 'ruby-send-definition)\n  (define-key ruby-mode-map \"\\C-c\\M-x\" 'ruby-send-definition-and-go)\n  (define-key ruby-mode-map \"\\C-c\\C-r\" 'ruby-send-region)\n  (define-key ruby-mode-map \"\\C-c\\M-r\" 'ruby-send-region-and-go)\n  (define-key ruby-mode-map \"\\C-c\\C-z\" 'switch-to-ruby)\n  (define-key ruby-mode-map \"\\C-c\\C-l\" 'ruby-load-file)\n  (define-key ruby-mode-map \"\\C-c\\C-s\" 'run-ruby)\n)\n\n(defvar ruby-buffer nil \"current ruby (actually irb) process buffer.\")\n\n(defun inferior-ruby-mode ()\n  \"Major mode for interacting with an inferior ruby (irb) process.\n\nThe following commands are available:\n\\\\{inferior-ruby-mode-map}\n\nA ruby process can be fired up with M-x run-ruby.\n\nCustomisation: Entry to this mode runs the hooks on comint-mode-hook and\ninferior-ruby-mode-hook (in that order).\n\nYou can send text to the inferior ruby process from other buffers containing\nRuby source.\n    switch-to-ruby switches the current buffer to the ruby process buffer.\n    ruby-send-definition sends the current definition to the ruby process.\n    ruby-send-region sends the current region to the ruby process.\n\n    ruby-send-definition-and-go, ruby-send-region-and-go,\n        switch to the ruby process buffer after sending their text.\nFor information on running multiple processes in multiple buffers, see\ndocumentation for variable ruby-buffer.\n\nCommands:\nReturn after the end of the process' output sends the text from the \n    end of process to point.\nReturn before the end of the process' output copies the sexp ending at point\n    to the end of the process' output, and sends it.\nDelete converts tabs to spaces as it moves back.\nTab indents for ruby; with argument, shifts rest\n    of expression rigidly with the current line.\nC-M-q does Tab on each line starting within following expression.\nParagraphs are separated only by blank lines.  # start comments.\nIf you accidentally suspend your process, use \\\\[comint-continue-subjob]\nto continue it.\"\n  (interactive)\n  (comint-mode)\n  ;; Customise in inferior-ruby-mode-hook\n  ;(setq comint-prompt-regexp \"^[^>\\n]*>+ *\")\n  (setq comint-prompt-regexp inferior-ruby-prompt-pattern)\n  ;;(scheme-mode-variables)\n  (ruby-mode-variables)\n  (setq major-mode 'inferior-ruby-mode)\n  (setq mode-name \"Inferior Ruby\")\n  (setq mode-line-process '(\":%s\"))\n  (use-local-map inferior-ruby-mode-map)\n  (setq comint-input-filter (function ruby-input-filter))\n  (setq comint-get-old-input (function ruby-get-old-input))\n  (compilation-shell-minor-mode t)\n  (make-local-variable 'compilation-error-regexp-alist)\n  (setq compilation-error-regexp-alist inferior-ruby-error-regexp-alist)\n  (run-hooks 'inferior-ruby-mode-hook))\n\n(defvar inferior-ruby-filter-regexp \"\\\\`\\\\s *\\\\S ?\\\\S ?\\\\s *\\\\'\"\n  \"*Input matching this regexp are not saved on the history list.\nDefaults to a regexp ignoring all inputs of 0, 1, or 2 letters.\")\n\n(defun ruby-input-filter (str)\n  \"Don't save anything matching inferior-ruby-filter-regexp\"\n  (not (string-match inferior-ruby-filter-regexp str)))\n\n;; adapted from replace-in-string in XEmacs (subr.el)\n(defun remove-in-string (str regexp)\n  \"Remove all matches in STR for REGEXP and returns the new string.\"\n  (let ((rtn-str \"\") (start 0) match prev-start)\n    (while (setq match (string-match regexp str start))\n      (setq prev-start start\n\t    start (match-end 0)\n\t    rtn-str (concat rtn-str (substring str prev-start match))))\n    (concat rtn-str (substring str start))))\n\n(defun ruby-get-old-input ()\n  \"Snarf the sexp ending at point\"\n  (save-excursion\n    (let ((end (point)))\n      (re-search-backward inferior-ruby-first-prompt-pattern)\n      (remove-in-string (buffer-substring (point) end)\n\t\t\tinferior-ruby-prompt-pattern)\n      )))\n\n(defun ruby-args-to-list (string)\n  (let ((where (string-match \"[ \\t]\" string)))\n    (cond ((null where) (list string))\n\t  ((not (= where 0))\n\t   (cons (substring string 0 where)\n\t\t (ruby-args-to-list (substring string (+ 1 where)\n\t\t\t\t\t\t (length string)))))\n\t  (t (let ((pos (string-match \"[^ \\t]\" string)))\n\t       (if (null pos)\n\t\t   nil\n\t\t (ruby-args-to-list (substring string pos\n\t\t\t\t\t\t (length string)))))))))\n\n(defun run-ruby (cmd)\n  \"Run an inferior Ruby process, input and output via buffer *ruby*.\nIf there is a process already running in `*ruby*', switch to that buffer.\nWith argument, allows you to edit the command line (default is value\nof `ruby-program-name').  Runs the hooks `inferior-ruby-mode-hook'\n\\(after the `comint-mode-hook' is run).\n\\(Type \\\\[describe-mode] in the process buffer for a list of commands.)\"\n\n  (interactive (list (if current-prefix-arg\n\t\t\t (read-string \"Run Ruby: \" ruby-program-name)\n\t\t\t ruby-program-name)))\n  (if (not (comint-check-proc \"*ruby*\"))\n      (let ((cmdlist (ruby-args-to-list cmd)))\n\t(set-buffer (apply 'make-comint \"ruby\" (car cmdlist)\n\t\t\t   nil (cdr cmdlist)))\n\t(inferior-ruby-mode)))\n  (setq ruby-program-name cmd)\n  (setq ruby-buffer \"*ruby*\")\n  (pop-to-buffer \"*ruby*\"))\n\n(defconst ruby-send-terminator \"--inf-ruby-%x-%d-%d-%d--\"\n  \"Template for irb here document terminator.\nMust not contain ruby meta characters.\")\n\n(defconst ruby-eval-separator \"\")\n\n(defun ruby-send-region (start end)\n  \"Send the current region to the inferior Ruby process.\"\n  (interactive \"r\")\n  (let (term (file (buffer-file-name)) line)\n    (save-excursion\n      (save-restriction\n\t(widen)\n\t(goto-char start)\n\t(setq line (+ start (forward-line (- start)) 1))\n\t(goto-char start)\n\t(while (progn\n\t\t (setq term (apply 'format ruby-send-terminator (random) (current-time)))\n\t\t (re-search-forward (concat \"^\" (regexp-quote term) \"$\") end t)))))\n    ;; compilation-parse-errors parses from second line.\n    (save-excursion\n      (let ((m (process-mark (ruby-proc))))\n\t(set-buffer (marker-buffer m))\n\t(goto-char m)\n\t(insert ruby-eval-separator \"\\n\")\n\t(set-marker m (point))))\n    (comint-send-string (ruby-proc) (format \"eval <<'%s', nil, %S, %d\\n\" term file line))\n    (comint-send-region (ruby-proc) start end)\n    (comint-send-string (ruby-proc) (concat \"\\n\" term \"\\n\"))))\n\n(defun ruby-send-definition ()\n  \"Send the current definition to the inferior Ruby process.\"\n  (interactive)\n  (save-excursion\n    (ruby-end-of-defun)\n    (let ((end (point)))\n      (ruby-beginning-of-defun)\n      (ruby-send-region (point) end))))\n\n;(defun ruby-send-last-sexp ()\n;  \"Send the previous sexp to the inferior Ruby process.\"\n;  (interactive)\n;  (ruby-send-region (save-excursion (backward-sexp) (point)) (point)))\n\n(defun ruby-send-block ()\n  \"Send the current block to the inferior Ruby process.\"\n  (interactive)\n  (save-excursion\n    (ruby-end-of-block)\n    (end-of-line)\n    (let ((end (point)))\n      (ruby-beginning-of-block)\n      (ruby-send-region (point) end))))\n\n(defun switch-to-ruby (eob-p)\n  \"Switch to the ruby process buffer.\nWith argument, positions cursor at end of buffer.\"\n  (interactive \"P\")\n  (if (get-buffer ruby-buffer)\n      (pop-to-buffer ruby-buffer)\n      (error \"No current process buffer. See variable ruby-buffer.\"))\n  (cond (eob-p\n\t (push-mark)\n\t (goto-char (point-max)))))\n\n(defun ruby-send-region-and-go (start end)\n  \"Send the current region to the inferior Ruby process.\nThen switch to the process buffer.\"\n  (interactive \"r\")\n  (ruby-send-region start end)\n  (switch-to-ruby t))\n\n(defun ruby-send-definition-and-go ()\n  \"Send the current definition to the inferior Ruby. \nThen switch to the process buffer.\"\n  (interactive)\n  (ruby-send-definition)\n  (switch-to-ruby t))\n\n(defun ruby-send-block-and-go ()\n  \"Send the current block to the inferior Ruby. \nThen switch to the process buffer.\"\n  (interactive)\n  (ruby-send-block)\n  (switch-to-ruby t))\n\n(defvar ruby-source-modes '(ruby-mode)\n  \"*Used to determine if a buffer contains Ruby source code.\nIf it's loaded into a buffer that is in one of these major modes, it's\nconsidered a ruby source file by ruby-load-file.\nUsed by these commands to determine defaults.\")\n\n(defvar ruby-prev-l/c-dir/file nil\n  \"Caches the last (directory . file) pair.\nCaches the last pair used in the last ruby-load-file command.\nUsed for determining the default in the \nnext one.\")\n\n(defun ruby-load-file (file-name)\n  \"Load a Ruby file into the inferior Ruby process.\"\n  (interactive (comint-get-source \"Load Ruby file: \" ruby-prev-l/c-dir/file\n\t\t\t\t  ruby-source-modes t)) ; T because LOAD \n                                                          ; needs an exact name\n  (comint-check-source file-name) ; Check to see if buffer needs saved.\n  (setq ruby-prev-l/c-dir/file (cons (file-name-directory    file-name)\n\t\t\t\t       (file-name-nondirectory file-name)))\n  (comint-send-string (ruby-proc) (concat \"(load \\\"\"\n\t\t\t\t\t    file-name\n\t\t\t\t\t    \"\\\"\\)\\n\")))\n\n(defun ruby-proc ()\n  \"Returns the current ruby process. See variable ruby-buffer.\"\n  (let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode)\n\t\t\t\t      (current-buffer)\n\t\t\t\t    ruby-buffer))))\n    (or proc\n\t(error \"No current process. See variable ruby-buffer\"))))\n\n;;; Do the user's customisation...\n\n(defvar inf-ruby-load-hook nil\n  \"This hook is run when inf-ruby is loaded in.\nThis is a good place to put keybindings.\")\n\t\n(run-hooks 'inf-ruby-load-hook)\n\n(provide 'inf-ruby)\n\n;;; inf-ruby.el ends here\n"
  },
  {
    "path": "misc/ruby-electric.el",
    "content": ";; -*-Emacs-Lisp-*-\n;;\n;; ruby-electric.el --- electric editing commands for ruby files\n;;\n;; Copyright (C) 2005 by Dee Zsombor <dee dot zsombor at gmail dot com>.\n;; Released under same license terms as Ruby.\n;;\n;; Due credit: this work was inspired by a code snippet posted by\n;; Frederick Ros at http://rubygarden.org/ruby?EmacsExtensions.\n;;\n;; Following improvements where added:\n;;\n;;       - handling of strings of type 'here document'\n;;       - more keywords, with special handling for 'do'\n;;       - packaged into a minor mode\n;;\n;; Usage:\n;;\n;;    0) copy ruby-electric.el into directory where emacs can find it.\n;;\n;;    1) modify your startup file (.emacs or whatever) by adding\n;;       following line:\n;;\n;;            (require 'ruby-electric)\n;;\n;;       note that you need to have font lock enabled beforehand.\n;;\n;;    2) toggle Ruby Electric Mode on/off with ruby-electric-mode.\n;;\n;; Changelog:\n;;\n;;  2005/Jan/14: inserts matching pair delimiters like {, [, (, ', \",\n;;  ' and | .\n;;\n;;  2005/Jan/14: added basic Custom support for configuring keywords\n;;  with electric closing.\n;;\n;;  2005/Jan/18: more Custom support for configuring characters for\n;;  which matching expansion should occur.\n;;\n;;  2005/Jan/18: no longer uses 'looking-back' or regexp character\n;;  classes like [:space:] since they are not implemented on XEmacs.\n;;\n;;  2005/Feb/01: explicitly provide default argument of 1 to\n;;  'backward-word' as it requires it on Emacs 21.3\n;;\n;;  2005/Mar/06: now stored inside ruby CVS; customize pages now have\n;;  ruby as parent; cosmetic fixes.\n\n\n(require 'ruby-mode)\n\n(defgroup ruby-electric nil\n  \"Minor mode providing electric editing commands for ruby files\"\n  :group 'ruby) \n\n(defconst ruby-electric-expandable-do-re\n  \"do\\\\s-$\")\n\n(defconst ruby-electric-expandable-bar\n  \"\\\\s-\\\\(do\\\\|{\\\\)\\\\s-+|\")\n\n(defvar ruby-electric-matching-delimeter-alist\n  '((?\\[ . ?\\])\n    (?\\( . ?\\))\n    (?\\' . ?\\')\n    (?\\` . ?\\`)\n    (?\\\" . ?\\\")))\n\n(defcustom ruby-electric-simple-keywords-re \n  \"\\\\(def\\\\|if\\\\|class\\\\|module\\\\|unless\\\\|case\\\\|while\\\\|do\\\\|until\\\\|for\\\\|begin\\\\)\"\n  \"*Regular expresion matching keywords for which closing 'end'\nis to be inserted.\"\n  :type 'regexp :group 'ruby-electric)\n\n(defcustom ruby-electric-expand-delimiters-list '(all)\n  \"*List of contexts where matching delimiter should be\ninserted. The word 'all' will do all insertions.\"\n  :type '(set :extra-offset 8\n\t      (const :tag \"Everything\" all )\n\t      (const :tag \"Curly brace\" ?\\{ )\n\t      (const :tag \"Square brace\" ?\\[ )\n\t      (const :tag \"Round brace\" ?\\( )\n\t      (const :tag \"Quote\" ?\\' )\n\t      (const :tag \"Double quote\" ?\\\" )\n\t      (const :tag \"Back quote\" ?\\` )\n\t      (const :tag \"Vertical bar\" ?\\| ))\n  :group 'ruby-electric) \n\n(defcustom ruby-electric-newline-before-closing-bracket nil\n  \"*Controls whether a newline should be inserted before the\nclosing bracket or not.\"\n  :type 'boolean :group 'ruby-electric)\n\n(define-minor-mode ruby-electric-mode\n  \"Toggle Ruby Electric minor mode.\nWith no argument, this command toggles the mode.  Non-null prefix\nargument turns on the mode.  Null prefix argument turns off the\nmode.\n\nWhen Ruby Electric mode is enabled, an indented 'end' is\nheuristicaly inserted whenever typing a word like 'module',\n'class', 'def', 'if', 'unless', 'case', 'until', 'for', 'begin',\n'do'. Simple, double and back quotes as well as braces are paired\nauto-magically. Expansion does not occur inside comments and\nstrings. Note that you must have Font Lock enabled.\"\n  ;; initial value.\n  nil\n  ;;indicator for the mode line.\n  \" REl\"\n  ;;keymap\n  ruby-mode-map\n  (ruby-electric-setup-keymap))\n\n(defun ruby-electric-setup-keymap()\n  (define-key ruby-mode-map \" \" 'ruby-electric-space)\n  (define-key ruby-mode-map \"{\" 'ruby-electric-curlies)\n  (define-key ruby-mode-map \"(\" 'ruby-electric-matching-char)\n  (define-key ruby-mode-map \"[\" 'ruby-electric-matching-char)\n  (define-key ruby-mode-map \"\\\"\" 'ruby-electric-matching-char)\n  (define-key ruby-mode-map \"\\'\" 'ruby-electric-matching-char)\n  (define-key ruby-mode-map \"|\" 'ruby-electric-bar))\n\n(defun ruby-electric-space (arg)\n  (interactive \"P\")\n  (self-insert-command (prefix-numeric-value arg))\n  (if (ruby-electric-space-can-be-expanded-p)\n      (save-excursion\n\t(ruby-indent-line t)\n\t(newline)\n\t(ruby-insert-end))))\n\n(defun ruby-electric-code-at-point-p()\n  (and ruby-electric-mode\n       (let* ((properties (text-properties-at (point))))\n\t (and (null (memq 'font-lock-string-face properties))\n\t      (null (memq 'font-lock-comment-face properties))))))\n\n(defun ruby-electric-string-at-point-p()\n  (and ruby-electric-mode\n       (consp (memq 'font-lock-string-face (text-properties-at (point))))))\n\n(defun ruby-electric-is-last-command-char-expandable-punct-p()\n  (or (memq 'all ruby-electric-expand-delimiters-list)\n      (memq last-command-char ruby-electric-expand-delimiters-list))) \n\n(defun ruby-electric-space-can-be-expanded-p()\n  (if (ruby-electric-code-at-point-p)\n      (let* ((ruby-electric-keywords-re \n\t      (concat ruby-electric-simple-keywords-re \"\\\\s-$\"))\n\t     (ruby-electric-single-keyword-in-line-re \n\t      (concat \"\\\\s-*\" ruby-electric-keywords-re)))\n\t(save-excursion\n\t  (backward-word 1)\n\t  (or (looking-at ruby-electric-expandable-do-re)\n\t      (and (looking-at ruby-electric-keywords-re)\n\t\t   (not (string= \"do\" (match-string 1)))\n\t\t   (progn\n\t\t     (beginning-of-line)\n\t\t     (looking-at ruby-electric-single-keyword-in-line-re))))))))\n\n\n(defun ruby-electric-curlies(arg)\n  (interactive \"P\")\n  (self-insert-command (prefix-numeric-value arg))\n  (if (ruby-electric-is-last-command-char-expandable-punct-p)\n      (cond ((ruby-electric-code-at-point-p)\n\t     (insert \" \")\n\t     (save-excursion\n\t       (if ruby-electric-newline-before-closing-bracket\n\t\t   (newline))\n\t       (insert \"}\")))\n\t    ((ruby-electric-string-at-point-p)\n\t     (save-excursion\n\t       (backward-char 1)\n\t       (when (char-equal ?\\# (preceding-char))\n\t\t (forward-char 1)\n\t\t (insert \"}\")))))))\n\n(defun ruby-electric-matching-char(arg)\n  (interactive \"P\")\n  (self-insert-command (prefix-numeric-value arg))\n  (and (ruby-electric-is-last-command-char-expandable-punct-p)\n       (ruby-electric-code-at-point-p)\n       (save-excursion\n\t (insert (cdr (assoc last-command-char \n\t\t\t     ruby-electric-matching-delimeter-alist))))))\n\n(defun ruby-electric-bar(arg)\n  (interactive \"P\")\n  (self-insert-command (prefix-numeric-value arg))\n  (and (ruby-electric-is-last-command-char-expandable-punct-p)\n       (ruby-electric-code-at-point-p)\n       (and (save-excursion (re-search-backward ruby-electric-expandable-bar nil t))\n\t    (= (point) (match-end 0))) ;looking-back is missing on XEmacs\n       (save-excursion \n\t (insert \"|\"))))\n\n\n(provide 'ruby-electric)\n"
  },
  {
    "path": "misc/ruby-mode.el",
    "content": ";;;\n;;;  ruby-mode.el -\n;;;\n;;;  $Author$\n;;;  $Date$\n;;;  created at: Fri Feb  4 14:49:13 JST 1994\n;;;\n\n(defconst ruby-mode-revision \"$Revision$\")\n\n(defconst ruby-mode-version\n  (progn\n   (string-match \"[0-9.]+\" ruby-mode-revision)\n   (substring ruby-mode-revision (match-beginning 0) (match-end 0))))\n\n(defconst ruby-block-beg-re\n  \"class\\\\|module\\\\|def\\\\|if\\\\|unless\\\\|case\\\\|while\\\\|until\\\\|for\\\\|begin\\\\|do\"\n  )\n\n(defconst ruby-non-block-do-re\n  \"\\\\(while\\\\|until\\\\|for\\\\|rescue\\\\)\\\\>[^_]\"\n  )\n\n(defconst ruby-indent-beg-re\n  \"\\\\(\\\\s *\\\\(class\\\\|module\\\\|def\\\\)\\\\)\\\\|if\\\\|unless\\\\|case\\\\|while\\\\|until\\\\|for\\\\|begin\"\n    )\n\n(defconst ruby-modifier-beg-re\n  \"if\\\\|unless\\\\|while\\\\|until\"\n  )\n\n(defconst ruby-modifier-re\n  (concat ruby-modifier-beg-re \"\\\\|rescue\")\n  )\n\n(defconst ruby-block-mid-re\n  \"then\\\\|else\\\\|elsif\\\\|when\\\\|rescue\\\\|ensure\"\n  )\n\n(defconst ruby-block-op-re\n  \"and\\\\|or\\\\|not\"\n  )\n\n(defconst ruby-block-hanging-re\n  (concat ruby-modifier-beg-re \"\\\\|\" ruby-block-op-re)\n  )\n\n(defconst ruby-block-end-re \"\\\\<end\\\\>\")\n\n(defconst ruby-here-doc-beg-re\n  \"<<\\\\(-\\\\)?\\\\(\\\\([a-zA-Z0-9_]+\\\\)\\\\|[\\\"]\\\\([^\\\"]+\\\\)[\\\"]\\\\|[']\\\\([^']+\\\\)[']\\\\)\")\n\n(defun ruby-here-doc-end-match ()\n  (concat \"^\"\n\t  (if (match-string 1) \"[ \\t]*\" nil)\n\t  (regexp-quote\n\t   (or (match-string 3)\n\t       (match-string 4)\n\t       (match-string 5)))))\n\n(defconst ruby-delimiter\n  (concat \"[?$/%(){}#\\\"'`.:]\\\\|<<\\\\|\\\\[\\\\|\\\\]\\\\|\\\\<\\\\(\"\n\t  ruby-block-beg-re\n\t  \"\\\\)\\\\>\\\\|\" ruby-block-end-re\n\t  \"\\\\|^=begin\\\\|\" ruby-here-doc-beg-re)\n  )\n\n(defconst ruby-negative\n  (concat \"^[ \\t]*\\\\(\\\\(\" ruby-block-mid-re \"\\\\)\\\\>\\\\|\"\n\t    ruby-block-end-re \"\\\\|}\\\\|\\\\]\\\\)\")\n  )\n\n(defconst ruby-operator-chars \"-,.+*/%&|^~=<>:\")\n(defconst ruby-operator-re (concat \"[\" ruby-operator-chars \"]\"))\n\n(defconst ruby-symbol-chars \"a-zA-Z0-9_\")\n(defconst ruby-symbol-re (concat \"[\" ruby-symbol-chars \"]\"))\n\n(defvar ruby-mode-abbrev-table nil\n  \"Abbrev table in use in ruby-mode buffers.\")\n\n(define-abbrev-table 'ruby-mode-abbrev-table ())\n\n(defvar ruby-mode-map nil \"Keymap used in ruby mode.\")\n\n(if ruby-mode-map\n    nil\n  (setq ruby-mode-map (make-sparse-keymap))\n  (define-key ruby-mode-map \"{\" 'ruby-electric-brace)\n  (define-key ruby-mode-map \"}\" 'ruby-electric-brace)\n  (define-key ruby-mode-map \"\\e\\C-a\" 'ruby-beginning-of-defun)\n  (define-key ruby-mode-map \"\\e\\C-e\" 'ruby-end-of-defun)\n  (define-key ruby-mode-map \"\\e\\C-b\" 'ruby-backward-sexp)\n  (define-key ruby-mode-map \"\\e\\C-f\" 'ruby-forward-sexp)\n  (define-key ruby-mode-map \"\\e\\C-p\" 'ruby-beginning-of-block)\n  (define-key ruby-mode-map \"\\e\\C-n\" 'ruby-end-of-block)\n  (define-key ruby-mode-map \"\\e\\C-h\" 'ruby-mark-defun)\n  (define-key ruby-mode-map \"\\e\\C-q\" 'ruby-indent-exp)\n  (define-key ruby-mode-map \"\\t\" 'ruby-indent-command)\n  (define-key ruby-mode-map \"\\C-c\\C-e\" 'ruby-insert-end)\n  (define-key ruby-mode-map \"\\C-j\" 'ruby-reindent-then-newline-and-indent)\n  (define-key ruby-mode-map \"\\C-m\" 'newline))\n\n(defvar ruby-mode-syntax-table nil\n  \"Syntax table in use in ruby-mode buffers.\")\n\n(if ruby-mode-syntax-table\n    ()\n  (setq ruby-mode-syntax-table (make-syntax-table))\n  (modify-syntax-entry ?\\' \"\\\"\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\\" \"\\\"\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\` \"\\\"\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?# \"<\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\n \">\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\\\ \"\\\\\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?$ \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?? \"_\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?_ \"_\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?< \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?> \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?& \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?| \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?% \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?= \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?/ \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?+ \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?* \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?- \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\; \".\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\( \"()\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\) \")(\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\{ \"(}\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\} \"){\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\[ \"(]\" ruby-mode-syntax-table)\n  (modify-syntax-entry ?\\] \")[\" ruby-mode-syntax-table)\n  )\n\n(defcustom ruby-indent-tabs-mode nil\n  \"*Indentation can insert tabs in ruby mode if this is non-nil.\"\n  :type 'boolean :group 'ruby)\n\n(defcustom ruby-indent-level 2\n  \"*Indentation of ruby statements.\"\n  :type 'integer :group 'ruby)\n\n(defcustom ruby-comment-column 32\n  \"*Indentation column of comments.\"\n  :type 'integer :group 'ruby)\n\n(defcustom ruby-deep-arglist t\n  \"*Deep indent lists in parenthesis when non-nil.\nAlso ignores spaces after parenthesis when 'space.\"\n  :group 'ruby)\n\n(defcustom ruby-deep-indent-paren '(?\\( ?\\[ ?\\] t)\n  \"*Deep indent lists in parenthesis when non-nil. t means continuous line.\nAlso ignores spaces after parenthesis when 'space.\"\n  :group 'ruby)\n\n(defcustom ruby-deep-indent-paren-style 'space\n  \"Default deep indent style.\"\n  :options '(t nil space) :group 'ruby)\n\n(eval-when-compile (require 'cl))\n(defun ruby-imenu-create-index-in-block (prefix beg end)\n  (let ((index-alist '()) (case-fold-search nil)\n\tname next pos decl sing)\n    (goto-char beg)\n    (while (re-search-forward \"^\\\\s *\\\\(\\\\(class\\\\>\\\\(\\\\s *<<\\\\)?\\\\|module\\\\>\\\\)\\\\s *\\\\([^\\(<\\n ]+\\\\)\\\\|\\\\(def\\\\|alias\\\\)\\\\>\\\\s *\\\\([^\\(\\n ]+\\\\)\\\\)\" end t)\n      (setq sing (match-beginning 3))\n      (setq decl (match-string 5))\n      (setq next (match-end 0))\n      (setq name (or (match-string 4) (match-string 6)))\n      (setq pos (match-beginning 0))\n      (cond\n       ((string= \"alias\" decl)\n\t(if prefix (setq name (concat prefix name)))\n\t(push (cons name pos) index-alist))\n       ((string= \"def\" decl)\n\t(if prefix\n\t    (setq name\n\t\t  (cond\n\t\t   ((string-match \"^self\\.\" name)\n\t\t    (concat (substring prefix 0 -1) (substring name 4)))\n\t\t  (t (concat prefix name)))))\n\t(push (cons name pos) index-alist)\n\t(ruby-accurate-end-of-block end))\n       (t\n\t(if (string= \"self\" name)\n\t    (if prefix (setq name (substring prefix 0 -1)))\n\t  (if prefix (setq name (concat (substring prefix 0 -1) \"::\" name)))\n\t  (push (cons name pos) index-alist))\n\t(ruby-accurate-end-of-block end)\n\t(setq beg (point))\n\t(setq index-alist\n\t      (nconc (ruby-imenu-create-index-in-block\n\t\t      (concat name (if sing \".\" \"#\"))\n\t\t      next beg) index-alist))\n\t(goto-char beg))))\n    index-alist))\n\n(defun ruby-imenu-create-index ()\n  (nreverse (ruby-imenu-create-index-in-block nil (point-min) nil)))\n\n(defun ruby-accurate-end-of-block (&optional end)\n  (let (state)\n    (or end (setq end (point-max)))\n    (while (and (setq state (apply 'ruby-parse-partial end state))\n\t\t(>= (nth 2 state) 0) (< (point) end)))))\n\n(defun ruby-mode-variables ()\n  (set-syntax-table ruby-mode-syntax-table)\n  (setq local-abbrev-table ruby-mode-abbrev-table)\n  (make-local-variable 'indent-line-function)\n  (setq indent-line-function 'ruby-indent-line)\n  (make-local-variable 'require-final-newline)\n  (setq require-final-newline t)\n  (make-variable-buffer-local 'comment-start)\n  (setq comment-start \"# \")\n  (make-variable-buffer-local 'comment-end)\n  (setq comment-end \"\")\n  (make-variable-buffer-local 'comment-column)\n  (setq comment-column ruby-comment-column)\n  (make-variable-buffer-local 'comment-start-skip)\n  (setq comment-start-skip \"#+ *\")\n  (setq indent-tabs-mode ruby-indent-tabs-mode)\n  (make-local-variable 'parse-sexp-ignore-comments)\n  (setq parse-sexp-ignore-comments t)\n  (make-local-variable 'paragraph-start)\n  (setq paragraph-start (concat \"$\\\\|\" page-delimiter))\n  (make-local-variable 'paragraph-separate)\n  (setq paragraph-separate paragraph-start)\n  (make-local-variable 'paragraph-ignore-fill-prefix)\n  (setq paragraph-ignore-fill-prefix t))\n\n;;;###autoload\n(defun ruby-mode ()\n  \"Major mode for editing ruby scripts.\n\\\\[ruby-indent-command] properly indents subexpressions of multi-line\nclass, module, def, if, while, for, do, and case statements, taking\nnesting into account.\n\nThe variable ruby-indent-level controls the amount of indentation.\n\\\\{ruby-mode-map}\"\n  (interactive)\n  (kill-all-local-variables)\n  (use-local-map ruby-mode-map)\n  (setq mode-name \"Ruby\")\n  (setq major-mode 'ruby-mode)\n  (ruby-mode-variables)\n\n  (make-local-variable 'imenu-create-index-function)\n  (setq imenu-create-index-function 'ruby-imenu-create-index)\n\n  (make-local-variable 'add-log-current-defun-function)\n  (setq add-log-current-defun-function 'ruby-add-log-current-method)\n\n  (set (make-local-variable 'font-lock-defaults) '((ruby-font-lock-keywords) nil nil))\n  (set (make-local-variable 'font-lock-keywords) ruby-font-lock-keywords)\n  (set (make-local-variable 'font-lock-syntax-table) ruby-font-lock-syntax-table)\n  (set (make-local-variable 'font-lock-syntactic-keywords) ruby-font-lock-syntactic-keywords)\n\n  (run-mode-hooks 'ruby-mode-hook))\n\n(defun ruby-current-indentation ()\n  (save-excursion\n    (beginning-of-line)\n    (back-to-indentation)\n    (current-column)))\n\n(defun ruby-indent-line (&optional flag)\n  \"Correct indentation of the current ruby line.\"\n  (ruby-indent-to (ruby-calculate-indent)))\n\n(defun ruby-indent-command ()\n  (interactive)\n  (ruby-indent-line t))\n\n(defun ruby-indent-to (x)\n  (if x\n      (let (shift top beg)\n\t(and (< x 0) (error \"invalid nest\"))\n\t(setq shift (current-column))\n\t(beginning-of-line)\n\t(setq beg (point))\n\t(back-to-indentation)\n\t(setq top (current-column))\n\t(skip-chars-backward \" \\t\")\n\t(if (>= shift top) (setq shift (- shift top))\n\t  (setq shift 0))\n\t(if (and (bolp)\n\t\t (= x top))\n\t    (move-to-column (+ x shift))\n\t  (move-to-column top)\n\t  (delete-region beg (point))\n\t  (beginning-of-line)\n\t  (indent-to x)\n\t  (move-to-column (+ x shift))))))\n\n(defun ruby-special-char-p (&optional pnt)\n  (setq pnt (or pnt (point)))\n  (let ((c (char-before pnt)) (b (and (< (point-min) pnt) (char-before (1- pnt)))))\n    (cond ((or (eq c ??) (eq c ?$)))\n\t  ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? ))))\n\t  ((eq c ?\\\\) (eq b ??)))))\n\n(defun ruby-expr-beg (&optional option)\n  (save-excursion\n    (store-match-data nil)\n    (let ((space (skip-chars-backward \" \\t\"))\n\t  (start (point)))\n      (cond\n       ((bolp) t)\n       ((progn\n\t  (forward-char -1)\n\t  (and (looking-at \"\\\\?\")\n\t       (or (eq (char-syntax (char-before (point))) ?w)\n\t\t   (ruby-special-char-p))))\n\tnil)\n       ((and (eq option 'heredoc) (< space 0)) t)\n       ((or (looking-at ruby-operator-re)\n\t    (looking-at \"[\\\\[({,;]\")\n\t    (and (looking-at \"[!?]\")\n\t\t (or (not (eq option 'modifier))\n\t\t     (bolp)\n\t\t     (save-excursion (forward-char -1) (looking-at \"\\\\Sw$\"))))\n\t    (and (looking-at ruby-symbol-re)\n\t\t (skip-chars-backward ruby-symbol-chars)\n\t\t (cond\n\t\t  ((or (looking-at (concat \"\\\\<\\\\(\" ruby-block-beg-re\n\t\t\t\t\t   \"|\" ruby-block-op-re\n\t\t\t\t\t   \"|\" ruby-block-mid-re \"\\\\)\\\\>\")))\n\t\t   (goto-char (match-end 0))\n\t\t   (not (looking-at \"\\\\s_\")))\n\t\t  ((eq option 'expr-qstr)\n\t\t   (looking-at \"[a-zA-Z][a-zA-z0-9_]* +%[^ \\t]\"))\n\t\t  ((eq option 'expr-re)\n\t\t   (looking-at \"[a-zA-Z][a-zA-z0-9_]* +/[^ \\t]\"))\n\t\t  (t nil)))))))))\n\n(defun ruby-forward-string (term &optional end no-error expand)\n  (let ((n 1) (c (string-to-char term))\n\t(re (if expand\n\t\t(concat \"[^\\\\]\\\\(\\\\\\\\\\\\\\\\\\\\)*\\\\([\" term \"]\\\\|\\\\(#{\\\\)\\\\)\")\n\t      (concat \"[^\\\\]\\\\(\\\\\\\\\\\\\\\\\\\\)*[\" term \"]\"))))\n    (while (and (re-search-forward re end no-error)\n\t\t(if (match-beginning 3)\n\t\t    (ruby-forward-string \"}{\" end no-error nil)\n\t\t  (> (setq n (if (eq (char-before (point)) c)\n\t\t\t\t     (1- n) (1+ n))) 0)))\n      (forward-char -1))\n    (cond ((zerop n))\n\t  (no-error nil)\n\t  ((error \"unterminated string\")))))\n\n(defun ruby-deep-indent-paren-p (c)\n  (cond ((listp ruby-deep-indent-paren)\n\t (let ((deep (assoc c ruby-deep-indent-paren)))\n\t   (cond (deep\n\t\t  (or (cdr deep) ruby-deep-indent-paren-style))\n\t\t ((memq c ruby-deep-indent-paren)\n\t\t  ruby-deep-indent-paren-style))))\n\t((eq c ruby-deep-indent-paren) ruby-deep-indent-paren-style)\n\t((eq c ?\\( ) ruby-deep-arglist)))\n\n(defun ruby-parse-partial (&optional end in-string nest depth pcol indent)\n  (or depth (setq depth 0))\n  (or indent (setq indent 0))\n  (when (re-search-forward ruby-delimiter end 'move)\n    (let ((pnt (point)) w re expand)\n      (goto-char (match-beginning 0))\n      (cond\n       ((and (memq (char-before) '(?@ ?$)) (looking-at \"\\\\sw\"))\n\t(goto-char pnt))\n       ((looking-at \"[\\\"`]\")\t\t;skip string\n\t(cond\n\t ((and (not (eobp))\n\t       (ruby-forward-string (buffer-substring (point) (1+ (point))) end t t))\n\t  nil)\n\t (t\n\t  (setq in-string (point))\n\t  (goto-char end))))\n       ((looking-at \"'\")\n\t(cond\n\t ((and (not (eobp))\n\t       (re-search-forward \"[^\\\\]\\\\(\\\\\\\\\\\\\\\\\\\\)*'\" end t))\n\t  nil)\n\t (t\n\t  (setq in-string (point))\n\t  (goto-char end))))\n       ((looking-at \"/=\") \n\t(goto-char pnt))\n       ((looking-at \"/\")\n\t(cond\n\t ((and (not (eobp)) (ruby-expr-beg 'expr-re))\n\t  (if (ruby-forward-string \"/\" end t t)\n\t      nil\n\t    (setq in-string (point))\n\t    (goto-char end)))\n\t (t\n\t  (goto-char pnt))))\n       ((looking-at \"%\")\n\t(cond\n\t ((and (not (eobp))\n\t       (ruby-expr-beg 'expr-qstr)\n\t       (not (looking-at \"%=\"))\n\t       (looking-at \"%[QqrxWw]?\\\\([^a-zA-Z0-9 \\t\\n]\\\\)\"))\n\t  (goto-char (match-beginning 1))\n\t  (setq expand (not (memq (char-before) '(?q ?w))))\n\t  (setq w (match-string 1))\n\t  (cond\n\t   ((string= w \"[\") (setq re \"][\"))\n\t   ((string= w \"{\") (setq re \"}{\"))\n\t   ((string= w \"(\") (setq re \")(\"))\n\t   ((string= w \"<\") (setq re \"><\"))\n\t   ((and expand (string= w \"\\\\\"))\n\t    (setq w (concat \"\\\\\" w))))\n\t  (unless (cond (re (ruby-forward-string re end t expand))\n\t\t\t(expand (ruby-forward-string w end t t))\n\t\t\t(t (re-search-forward\n\t\t\t    (if (string= w \"\\\\\")\n\t\t\t\t\"\\\\\\\\[^\\\\]*\\\\\\\\\"\n\t\t\t      (concat \"[^\\\\]\\\\(\\\\\\\\\\\\\\\\\\\\)*\" w))\n\t\t\t    end t)))\n\t    (setq in-string (point))\n\t    (goto-char end)))\n\t (t\n\t  (goto-char pnt))))\n       ((looking-at \"\\\\?\")\t\t;skip ?char\n\t(cond\n\t ((and (ruby-expr-beg)\n\t       (looking-at \"?\\\\(\\\\\\\\C-\\\\|\\\\\\\\M-\\\\)*\\\\\\\\?.\"))\n\t  (goto-char (match-end 0)))\n\t (t\n\t  (goto-char pnt))))\n       ((looking-at \"\\\\$\")\t\t;skip $char\n\t(goto-char pnt)\n\t(forward-char 1))\n       ((looking-at \"#\")\t\t;skip comment\n\t(forward-line 1)\n\t(goto-char (point))\n\t)\n       ((looking-at \"[\\\\[{(]\")\n\t(let ((deep (ruby-deep-indent-paren-p (char-after))))\n\t  (if (and deep (or (not (eq (char-after) ?\\{)) (ruby-expr-beg)))\n\t      (progn\n\t\t(and (eq deep 'space) (looking-at \".\\\\s +[^# \\t\\n]\")\n\t\t     (setq pnt (1- (match-end 0))))\n\t\t(setq nest (cons (cons (char-after (point)) pnt) nest))\n\t\t(setq pcol (cons (cons pnt depth) pcol))\n\t\t(setq depth 0))\n\t    (setq nest (cons (cons (char-after (point)) pnt) nest))\n\t    (setq depth (1+ depth))))\n\t(goto-char pnt)\n\t)\n       ((looking-at \"[])}]\")\n\t(if (ruby-deep-indent-paren-p (matching-paren (char-after)))\n\t    (setq depth (cdr (car pcol)) pcol (cdr pcol))\n\t  (setq depth (1- depth)))\n\t(setq nest (cdr nest))\n\t(goto-char pnt))\n       ((looking-at ruby-block-end-re)\n\t(if (or (and (not (bolp))\n\t\t     (progn\n\t\t       (forward-char -1)\n\t\t       (setq w (char-after (point)))\n\t\t       (or (eq ?_ w)\n\t\t\t   (eq ?. w))))\n\t\t(progn\n\t\t  (goto-char pnt)\n\t\t  (setq w (char-after (point)))\n\t\t  (or (eq ?_ w)\n\t\t      (eq ?! w)\n\t\t      (eq ?? w))))\n\t    nil\n\t  (setq nest (cdr nest))\n\t  (setq depth (1- depth)))\n\t(goto-char pnt))\n       ((looking-at \"def\\\\s +[^(\\n;]*\")\n\t(if (or (bolp)\n\t\t(progn\n\t\t  (forward-char -1)\n\t\t  (not (eq ?_ (char-after (point))))))\n\t    (progn\n\t      (setq nest (cons (cons nil pnt) nest))\n\t      (setq depth (1+ depth))))\n\t(goto-char (match-end 0)))\n       ((looking-at (concat \"\\\\<\\\\(\" ruby-block-beg-re \"\\\\)\\\\>\"))\n\t(and\n\t (save-match-data\n\t   (or (not (looking-at \"do\\\\>[^_]\"))\n\t       (save-excursion\n\t\t (back-to-indentation)\n\t\t (not (looking-at ruby-non-block-do-re)))))\n\t (or (bolp)\n\t     (progn\n\t       (forward-char -1)\n\t       (setq w (char-after (point)))\n\t       (not (or (eq ?_ w)\n\t\t\t(eq ?. w)))))\n\t (goto-char pnt)\n\t (setq w (char-after (point)))\n\t (not (eq ?_ w))\n\t (not (eq ?! w))\n\t (not (eq ?? w))\n\t (skip-chars-forward \" \\t\")\n\t (goto-char (match-beginning 0))\n\t (or (not (looking-at ruby-modifier-re))\n\t     (ruby-expr-beg 'modifier))\n\t (goto-char pnt)\n\t (setq nest (cons (cons nil pnt) nest))\n\t (setq depth (1+ depth)))\n\t(goto-char pnt))\n       ((looking-at \":\\\\(['\\\"]\\\\)\")\n\t(goto-char (match-beginning 1))\n\t(ruby-forward-string (buffer-substring (match-beginning 1) (match-end 1)) end))\n       ((looking-at \":\\\\([-,.+*/%&|^~<>]=?\\\\|===?\\\\|<=>\\\\)\")\n\t(goto-char (match-end 0)))\n       ((looking-at \":\\\\([a-zA-Z_][a-zA-Z_0-9]*[!?=]?\\\\)?\")\n\t(goto-char (match-end 0)))\n       ((or (looking-at \"\\\\.\\\\.\\\\.?\")\n\t    (looking-at \"\\\\.[0-9]+\")\n\t    (looking-at \"\\\\.[a-zA-Z_0-9]+\")\n\t    (looking-at \"\\\\.\"))\n\t(goto-char (match-end 0)))\n       ((looking-at \"^=begin\")\n\t(if (re-search-forward \"^=end\" end t)\n\t    (forward-line 1)\n\t  (setq in-string (match-end 0))\n\t  (goto-char end)))\n       ((looking-at \"<<\")\n\t(cond\n\t ((and (ruby-expr-beg 'heredoc)\n\t       (looking-at \"<<\\\\(-\\\\)?\\\\(\\\\([\\\"'`]\\\\)\\\\([^\\n]+?\\\\)\\\\3\\\\|\\\\(?:\\\\sw\\\\|\\\\s_\\\\)+\\\\)\"))\n\t  (setq re (regexp-quote (or (match-string 4) (match-string 2))))\n\t  (if (match-beginning 1) (setq re (concat \"\\\\s *\" re)))\n\t  (let* ((id-end (goto-char (match-end 0)))\n\t\t (line-end-position (save-excursion (end-of-line) (point)))\n\t\t (state (list in-string nest depth pcol indent)))\n\t    ;; parse the rest of the line\n\t    (while (and (> line-end-position (point))\n\t\t\t(setq state (apply 'ruby-parse-partial\n\t\t\t\t\t   line-end-position state))))\n\t    (setq in-string (car state)\n\t\t  nest (nth 1 state)\n\t\t  depth (nth 2 state)\n\t\t  pcol (nth 3 state)\n\t\t  indent (nth 4 state))\n\t    ;; skip heredoc section\n\t    (if (re-search-forward (concat \"^\" re \"$\") end 'move)\n\t\t(forward-line 1)\n\t      (setq in-string id-end)\n\t      (goto-char end))))\n\t (t\n\t  (goto-char pnt))))\n       ((looking-at \"^__END__$\")\n\t(goto-char pnt))\n       ((looking-at ruby-here-doc-beg-re)\n\t(if (re-search-forward (ruby-here-doc-end-match)\n\t\t\t       indent-point t)\n\t    (forward-line 1)\n\t  (setq in-string (match-end 0))\n\t  (goto-char indent-point)))\n       (t\n\t(error (format \"bad string %s\"\n\t\t       (buffer-substring (point) pnt)\n\t\t       ))))))\n  (list in-string nest depth pcol))\n\n(defun ruby-parse-region (start end)\n  (let (state)\n    (save-excursion\n      (if start\n\t  (goto-char start)\n\t(ruby-beginning-of-indent))\n      (save-restriction\n\t(narrow-to-region (point) end)\n\t(while (and (> end (point))\n\t\t    (setq state (apply 'ruby-parse-partial end state))))))\n    (list (nth 0 state)\t\t\t; in-string\n\t  (car (nth 1 state))\t\t; nest\n\t  (nth 2 state)\t\t\t; depth\n\t  (car (car (nth 3 state)))\t; pcol\n\t  ;(car (nth 5 state))\t\t; indent\n\t  )))\n\n(defun ruby-indent-size (pos nest)\n  (+ pos (* (or nest 1) ruby-indent-level)))\n\n(defun ruby-calculate-indent (&optional parse-start)\n  (save-excursion\n    (beginning-of-line)\n    (let ((indent-point (point))\n\t  (case-fold-search nil)\n\t  state bol eol begin op-end\n\t  (paren (progn (skip-syntax-forward \" \")\n\t\t\t(and (char-after) (matching-paren (char-after)))))\n\t  (indent 0))\n      (if parse-start\n\t  (goto-char parse-start)\n\t(ruby-beginning-of-indent)\n\t(setq parse-start (point)))\n      (back-to-indentation)\n      (setq indent (current-column))\n      (setq state (ruby-parse-region parse-start indent-point))\n      (cond\n       ((nth 0 state)\t\t\t; within string\n\t(setq indent nil))\t\t;  do nothing\n       ((car (nth 1 state))\t\t; in paren\n\t(goto-char (setq begin (cdr (nth 1 state))))\n\t(let ((deep (ruby-deep-indent-paren-p (car (nth 1 state)))))\n\t  (if deep\n\t      (cond ((and (eq deep t) (eq (car (nth 1 state)) paren))\n\t\t     (skip-syntax-backward \" \")\n\t\t     (setq indent (1- (current-column))))\n\t\t    ((let ((s (ruby-parse-region (point) indent-point)))\n\t\t       (and (nth 2 s) (> (nth 2 s) 0)\n\t\t\t    (or (goto-char (cdr (nth 1 s))) t)))\n\t\t     (forward-word -1)\n\t\t     (setq indent (ruby-indent-size (current-column) (nth 2 state))))\n\t\t    (t\n\t\t     (setq indent (current-column))\n\t\t     (cond ((eq deep 'space))\n\t\t\t   (paren (setq indent (1- indent)))\n\t\t\t   (t (setq indent (ruby-indent-size (1- indent) 1))))))\n\t    (if (nth 3 state) (goto-char (nth 3 state))\n\t      (goto-char parse-start) (back-to-indentation))\n\t    (setq indent (ruby-indent-size (current-column) (nth 2 state))))\n\t  (and (eq (car (nth 1 state)) paren)\n\t       (ruby-deep-indent-paren-p (matching-paren paren))\n\t       (search-backward (char-to-string paren))\n\t       (setq indent (current-column)))))\n       ((and (nth 2 state) (> (nth 2 state) 0)) ; in nest\n\t(if (null (cdr (nth 1 state)))\n\t    (error \"invalid nest\"))\n\t(goto-char (cdr (nth 1 state)))\n\t(forward-word -1)\t\t; skip back a keyword\n\t(setq begin (point))\n\t(cond\n\t ((looking-at \"do\\\\>[^_]\")\t; iter block is a special case\n\t  (if (nth 3 state) (goto-char (nth 3 state))\n\t    (goto-char parse-start) (back-to-indentation))\n\t  (setq indent (ruby-indent-size (current-column) (nth 2 state))))\n\t (t\n\t  (setq indent (+ (current-column) ruby-indent-level)))))\n       \n       ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest\n\t(setq indent (ruby-indent-size (current-column) (nth 2 state)))))\n      (when indent\n\t(goto-char indent-point)\n\t(end-of-line)\n\t(setq eol (point))\n\t(beginning-of-line)\n\t(cond\n\t ((and (not (ruby-deep-indent-paren-p paren))\n\t       (re-search-forward ruby-negative eol t))\n\t  (and (not (eq ?_ (char-after (match-end 0))))\n\t       (setq indent (- indent ruby-indent-level))))\n\t ((and\n\t   (save-excursion\n\t     (beginning-of-line)\n\t     (not (bobp)))\n\t   (or (ruby-deep-indent-paren-p t)\n\t       (null (car (nth 1 state)))))\n\t  ;; goto beginning of non-empty no-comment line\n\t  (let (end done)\n\t    (while (not done)\n\t      (skip-chars-backward \" \\t\\n\")\n\t      (setq end (point))\n\t      (beginning-of-line)\n\t      (if (re-search-forward \"^\\\\s *#\" end t)\n\t\t  (beginning-of-line)\n\t\t(setq done t))))\n\t  (setq bol (point))\n\t  (end-of-line)\n\t  ;; skip the comment at the end\n\t  (skip-chars-backward \" \\t\")\n\t  (let (end (pos (point)))\n\t    (beginning-of-line)\n\t    (while (and (re-search-forward \"#\" pos t)\n\t\t\t(setq end (1- (point)))\n\t\t\t(or (ruby-special-char-p end)\n\t\t\t    (and (setq state (ruby-parse-region parse-start end))\n\t\t\t\t (nth 0 state))))\n\t      (setq end nil))\n\t    (goto-char (or end pos))\n\t    (skip-chars-backward \" \\t\")\n\t    (setq begin (if (nth 0 state) pos (cdr (nth 1 state))))\n\t    (setq state (ruby-parse-region parse-start (point))))\n\t  (or (bobp) (forward-char -1))\n\t  (and\n\t   (or (and (looking-at ruby-symbol-re)\n\t\t    (skip-chars-backward ruby-symbol-chars)\n\t\t    (looking-at (concat \"\\\\<\\\\(\" ruby-block-hanging-re \"\\\\)\\\\>\"))\n\t\t    (not (eq (point) (nth 3 state)))\n\t\t    (save-excursion\n\t\t      (goto-char (match-end 0))\n\t\t      (not (looking-at \"[a-z_]\"))))\n\t       (and (looking-at ruby-operator-re)\n\t\t    (not (ruby-special-char-p))\n\t\t    ;; operator at the end of line\n\t\t    (let ((c (char-after (point))))\n\t\t      (and\n;; \t\t       (or (null begin)\n;; \t\t\t   (save-excursion\n;; \t\t\t     (goto-char begin)\n;; \t\t\t     (skip-chars-forward \" \\t\")\n;; \t\t\t     (not (or (eolp) (looking-at \"#\")\n;; \t\t\t\t      (and (eq (car (nth 1 state)) ?{)\n;; \t\t\t\t\t   (looking-at \"|\"))))))\n\t\t       (or (not (eq ?/ c))\n\t\t\t   (null (nth 0 (ruby-parse-region (or begin parse-start) (point)))))\n\t\t       (or (not (eq ?| (char-after (point))))\n\t\t\t   (save-excursion\n\t\t\t     (or (eolp) (forward-char -1))\n\t\t\t     (cond\n\t\t\t      ((search-backward \"|\" nil t)\n\t\t\t       (skip-chars-backward \" \\t\\n\")\n\t\t\t       (and (not (eolp))\n\t\t\t\t    (progn\n\t\t\t\t      (forward-char -1)\n\t\t\t\t      (not (looking-at \"{\")))\n\t\t\t\t    (progn\n\t\t\t\t      (forward-word -1)\n\t\t\t\t      (not (looking-at \"do\\\\>[^_]\")))))\n\t\t\t      (t t))))\n\t\t       (not (eq ?, c))\n\t\t       (setq op-end t)))))\n\t   (setq indent\n\t\t (cond\n\t\t  ((and\n\t\t    (null op-end)\n\t\t    (not (looking-at (concat \"\\\\<\\\\(\" ruby-block-hanging-re \"\\\\)\\\\>\")))\n\t\t    (eq (ruby-deep-indent-paren-p t) 'space)\n\t\t    (not (bobp)))\n\t\t   (save-excursion\n\t\t     (widen)\n\t\t     (goto-char (or begin parse-start))\n\t\t     (skip-syntax-forward \" \")\n\t\t     (current-column)))\n\t\t  ((car (nth 1 state)) indent)\n\t\t  (t\n\t\t   (+ indent ruby-indent-level))))))))\n      indent)))\n\n(defun ruby-electric-brace (arg)\n  (interactive \"P\")\n  (insert-char last-command-char 1)\n  (ruby-indent-line t)\n  (delete-char -1)\n  (self-insert-command (prefix-numeric-value arg)))\n\n(eval-when-compile\n  (defmacro defun-region-command (func args &rest body)\n    (let ((intr (car body)))\n      (when (featurep 'xemacs)\n\t(if (stringp intr) (setq intr (cadr body)))\n\t(and (eq (car intr) 'interactive)\n\t     (setq intr (cdr intr))\n\t     (setcar intr (concat \"_\" (car intr)))))\n      (cons 'defun (cons func (cons args body))))))\n\n(defun-region-command ruby-beginning-of-defun (&optional arg)\n  \"Move backward to next beginning-of-defun.\nWith argument, do this that many times.\nReturns t unless search stops due to end of buffer.\"\n  (interactive \"p\")\n  (and (re-search-backward (concat \"^\\\\(\" ruby-block-beg-re \"\\\\)\\\\b\")\n\t\t\t   nil 'move (or arg 1))\n       (progn (beginning-of-line) t)))\n\n(defun ruby-beginning-of-indent ()\n  (and (re-search-backward (concat \"^\\\\(\" ruby-indent-beg-re \"\\\\)\\\\b\")\n\t\t\t   nil 'move)\n       (progn\n\t (beginning-of-line)\n\t t)))\n\n(defun-region-command ruby-end-of-defun (&optional arg)\n  \"Move forward to next end of defun.\nAn end of a defun is found by moving forward from the beginning of one.\"\n  (interactive \"p\")\n  (and (re-search-forward (concat \"^\\\\(\" ruby-block-end-re \"\\\\)\\\\($\\\\|\\\\b[^_]\\\\)\")\n\t\t\t  nil 'move (or arg 1))\n       (progn (beginning-of-line) t))\n  (forward-line 1))\n\n(defun ruby-move-to-block (n)\n  (let (start pos done down)\n    (setq start (ruby-calculate-indent))\n    (setq down (looking-at (if (< n 0) ruby-block-end-re\n\t\t\t     (concat \"\\\\<\\\\(\" ruby-block-beg-re \"\\\\)\\\\>\"))))\n    (while (and (not done) (not (if (< n 0) (bobp) (eobp))))\n      (forward-line n)\n      (cond\n       ((looking-at \"^\\\\s *$\"))\n       ((looking-at \"^\\\\s *#\"))\n       ((and (> n 0) (looking-at \"^=begin\\\\>\"))\n\t(re-search-forward \"^=end\\\\>\"))\n       ((and (< n 0) (looking-at \"^=end\\\\>\"))\n\t(re-search-backward \"^=begin\\\\>\"))\n       (t\n\t(setq pos (current-indentation))\n\t(cond\n\t ((< start pos)\n\t  (setq down t))\n\t ((and down (= pos start))\n\t  (setq done t))\n\t ((> start pos)\n\t  (setq done t)))))\n      (if done\n\t  (save-excursion\n\t    (back-to-indentation)\n\t    (if (looking-at (concat \"\\\\<\\\\(\" ruby-block-mid-re \"\\\\)\\\\>\"))\n\t\t(setq done nil))))))\n  (back-to-indentation))\n\n(defun-region-command ruby-beginning-of-block (&optional arg)\n  \"Move backward to next beginning-of-block\"\n  (interactive \"p\")\n  (ruby-move-to-block (- (or arg 1))))\n\n(defun-region-command ruby-end-of-block (&optional arg)\n  \"Move forward to next beginning-of-block\"\n  (interactive \"p\")\n  (ruby-move-to-block (or arg 1)))\n\n(defun-region-command ruby-forward-sexp (&optional cnt)\n  (interactive \"p\")\n  (if (and (numberp cnt) (< cnt 0))\n      (ruby-backward-sexp (- cnt))\n    (let ((i (or cnt 1)))\n      (condition-case nil\n\t  (while (> i 0)\n\t    (skip-syntax-forward \" \")\n\t    (cond ((looking-at \"\\\\?\\\\(\\\\\\\\[CM]-\\\\)*\\\\\\\\?\\\\S \")\n\t\t   (goto-char (match-end 0)))\n\t\t  ((progn\n\t\t     (skip-chars-forward \",.:;|&^~=!?\\\\+\\\\-\\\\*\")\n\t\t     (looking-at \"\\\\s(\"))\n\t\t   (goto-char (scan-sexps (point) 1)))\n\t\t  ((and (looking-at (concat \"\\\\<\\\\(\" ruby-block-beg-re \"\\\\)\\\\>\"))\n\t\t\t(not (eq (char-before (point)) ?.))\n\t\t\t(not (eq (char-before (point)) ?:)))\n\t\t   (ruby-end-of-block)\n\t\t   (forward-word 1))\n\t\t  ((looking-at \"\\\\(\\\\$\\\\|@@?\\\\)?\\\\sw\")\n\t\t   (while (progn\n\t\t\t    (while (progn (forward-word 1) (looking-at \"_\")))\n\t\t\t    (cond ((looking-at \"::\") (forward-char 2) t)\n\t\t\t\t  ((> (skip-chars-forward \".\") 0))\n\t\t\t\t  ((looking-at \"\\\\?\\\\|!\\\\(=[~=>]\\\\|[^~=]\\\\)\")\n\t\t\t\t   (forward-char 1) nil)))))\n\t\t  ((let (state expr)\n\t\t     (while\n\t\t\t (progn\n\t\t\t   (setq expr (or expr (ruby-expr-beg)\n\t\t\t\t\t  (looking-at \"%\\\\sw?\\\\Sw\\\\|[\\\"'`/]\")))\n\t\t\t   (nth 1 (setq state (apply 'ruby-parse-partial nil state))))\n\t\t       (setq expr t)\n\t\t       (skip-chars-forward \"<\"))\n\t\t     (not expr))))\n\t    (setq i (1- i)))\n\t((error) (forward-word 1)))\n      i)))\n\n(defun-region-command ruby-backward-sexp (&optional cnt)\n  (interactive \"p\")\n  (if (and (numberp cnt) (< cnt 0))\n      (ruby-forward-sexp (- cnt))\n    (let ((i (or cnt 1)))\n      (condition-case nil\n\t  (while (> i 0)\n\t    (skip-chars-backward \" \\t\\n,.:;|&^~=!?\\\\+\\\\-\\\\*\")\n\t    (forward-char -1)\n\t    (cond ((looking-at \"\\\\s)\")\n\t\t   (goto-char (scan-sexps (1+ (point)) -1))\n\t\t   (case (char-before)\n\t\t     (?% (forward-char -1))\n\t\t     ('(?q ?Q ?w ?W ?r ?x)\n\t\t      (if (eq (char-before (1- (point))) ?%) (forward-char -2))))\n\t\t   nil)\n\t\t  ((looking-at \"\\\\s\\\"\\\\|\\\\\\\\\\\\S_\")\n\t\t   (let ((c (char-to-string (char-before (match-end 0)))))\n\t\t     (while (and (search-backward c)\n\t\t\t\t (oddp (skip-chars-backward \"\\\\\")))))\n\t\t   nil)\n\t\t  ((looking-at \"\\\\s.\\\\|\\\\s\\\\\")\n\t\t   (if (ruby-special-char-p) (forward-char -1)))\n\t\t  ((looking-at \"\\\\s(\") nil)\n\t\t  (t\n\t\t   (forward-char 1)\n\t\t   (while (progn (forward-word -1)\n\t\t\t\t (case (char-before)\n\t\t\t\t   (?_ t)\n\t\t\t\t   (?. (forward-char -1) t)\n\t\t\t\t   ((?$ ?@)\n\t\t\t\t    (forward-char -1)\n\t\t\t\t    (and (eq (char-before) (char-after)) (forward-char -1)))\n\t\t\t\t   (?:\n\t\t\t\t    (forward-char -1)\n\t\t\t\t    (eq (char-before) :)))))\n\t\t   (if (looking-at ruby-block-end-re)\n\t\t       (ruby-beginning-of-block))\n\t\t   nil))\n\t    (setq i (1- i)))\n\t((error)))\n      i)))\n\n(defun ruby-reindent-then-newline-and-indent ()\n  (interactive \"*\")\n  (newline)\n  (save-excursion\n    (end-of-line 0)\n    (indent-according-to-mode)\n    (delete-region (point) (progn (skip-chars-backward \" \\t\") (point))))\n  (indent-according-to-mode))\n\n(fset 'ruby-encomment-region (symbol-function 'comment-region))\n\n(defun ruby-decomment-region (beg end)\n  (interactive \"r\")\n  (save-excursion\n    (goto-char beg)\n    (while (re-search-forward \"^\\\\([ \\t]*\\\\)#\" end t)\n      (replace-match \"\\\\1\" nil nil)\n      (save-excursion\n\t(ruby-indent-line)))))\n\n(defun ruby-insert-end ()\n  (interactive)\n  (insert \"end\")\n  (ruby-indent-line t)\n  (end-of-line))\n\n(defun ruby-mark-defun ()\n  \"Put mark at end of this Ruby function, point at beginning.\"\n  (interactive)\n  (push-mark (point))\n  (ruby-end-of-defun)\n  (push-mark (point) nil t)\n  (ruby-beginning-of-defun)\n  (re-search-backward \"^\\n\" (- (point) 1) t))\n\n(defun ruby-indent-exp (&optional shutup-p)\n  \"Indent each line in the balanced expression following point syntactically.\nIf optional SHUTUP-P is non-nil, no errors are signalled if no\nbalanced expression is found.\"\n  (interactive \"*P\")\n  (let ((here (point-marker)) start top column (nest t))\n    (set-marker-insertion-type here t)\n    (unwind-protect\n\t(progn\n\t  (beginning-of-line)\n\t  (setq start (point) top (current-indentation))\n\t  (while (and (not (eobp))\n\t\t      (progn\n\t\t\t(setq column (ruby-calculate-indent start))\n\t\t\t(cond ((> column top)\n\t\t\t       (setq nest t))\n\t\t\t      ((and (= column top) nest)\n\t\t\t       (setq nest nil) t))))\n\t    (ruby-indent-to column)\n\t    (beginning-of-line 2)))\n      (goto-char here)\n      (set-marker here nil))))\n\n(defun ruby-add-log-current-method ()\n  \"Return current method string.\"\n  (condition-case nil\n      (save-excursion\n\t(let ((mlist nil) (indent 0))\n\t  ;; get current method (or class/module)\n\t  (if (re-search-backward\n\t       (concat \"^[ \\t]*\\\\(def\\\\|class\\\\|module\\\\)[ \\t]+\"\n\t\t       \"\\\\(\" \n\t\t       ;; \\\\. for class method\n\t\t\t\"\\\\(\" ruby-symbol-re \"\\\\|\\\\.\" \"\\\\)\" \n\t\t\t\"+\\\\)\")\n\t       nil t)\n\t      (progn\n\t\t(setq mlist (list (match-string 2)))\n\t\t(goto-char (match-beginning 1))\n\t\t(setq indent (current-column))\n\t\t(beginning-of-line)))\n\t  ;; nest class/module\n\t  (while (and (> indent 0)\n\t\t      (re-search-backward\n\t\t       (concat\n\t\t\t\"^[ \\t]*\\\\(class\\\\|module\\\\)[ \\t]+\"\n\t\t\t\"\\\\([A-Z]\" ruby-symbol-re \"+\\\\)\")\n\t\t       nil t))\n\t    (goto-char (match-beginning 1))\n\t    (if (< (current-column) indent)\n\t\t(progn\n\t\t  (setq mlist (cons (match-string 2) mlist))\n\t\t  (setq indent (current-column))\n\t\t  (beginning-of-line))))\n\t  ;; generate string\n\t  (if (consp mlist)\n\t      (mapconcat (function identity) mlist \"::\")\n\t    nil)))))\n\n(cond\n ((featurep 'font-lock)\n  (or (boundp 'font-lock-variable-name-face)\n      (setq font-lock-variable-name-face font-lock-type-face))\n\n  (setq ruby-font-lock-syntactic-keywords\n\t'(\n\t  ;; #{ }, #$hoge, #@foo are not comments\n\t  (\"\\\\(#\\\\)[{$@]\" 1 (1 . nil))\n\t  ;; the last $', $\", $` in the respective string is not variable\n\t  ;; the last ?', ?\", ?` in the respective string is not ascii code\n\t  (\"\\\\(^\\\\|[\\[ \\t\\n<+\\(,=]\\\\)\\\\(['\\\"`]\\\\)\\\\(\\\\\\\\.\\\\|\\\\2\\\\|[^'\\\"`\\n\\\\\\\\]\\\\)*?\\\\\\\\?[?$]\\\\(\\\\2\\\\)\"\n\t   (2 (7 . nil))\n\t   (4 (7 . nil)))\n\t  ;; $' $\" $` .... are variables\n\t  ;; ?' ?\" ?` are ascii codes\n\t  (\"\\\\(^\\\\|[^\\\\\\\\]\\\\)\\\\(\\\\\\\\\\\\\\\\\\\\)*[?$]\\\\([#\\\"'`]\\\\)\" 3 (1 . nil))\n\t  ;; regexps\n\t  (\"\\\\(^\\\\|[=(,~?:;<>]\\\\|\\\\(^\\\\|\\\\s \\\\)\\\\(if\\\\|elsif\\\\|unless\\\\|while\\\\|until\\\\|when\\\\|and\\\\|or\\\\|&&\\\\|||\\\\)\\\\|g?sub!?\\\\|scan\\\\|split!?\\\\)\\\\s *\\\\(/\\\\)[^/\\n\\\\\\\\]*\\\\(\\\\\\\\.[^/\\n\\\\\\\\]*\\\\)*\\\\(/\\\\)\"\n\t   (4 (7 . ?/))\n\t   (6 (7 . ?/)))\n\t  (\"^\\\\(=\\\\)begin\\\\(\\\\s \\\\|$\\\\)\" 1 (7 . nil))\n\t  (\"^\\\\(=\\\\)end\\\\(\\\\s \\\\|$\\\\)\" 1 (7 . nil))))\n\n  (if (featurep 'xemacs)\n      (put 'ruby-mode 'font-lock-defaults\n\t   '((ruby-font-lock-keywords)\n\t     nil nil nil\n\t     beginning-of-line\n\t     (font-lock-syntactic-keywords\n\t      . ruby-font-lock-syntactic-keywords))))\n\n  (defun ruby-font-lock-docs (limit)\n    (if (re-search-forward \"^=begin\\\\(\\\\s \\\\|$\\\\)\" limit t)\n\t(let (beg)\n\t  (beginning-of-line)\n\t  (setq beg (point))\n\t  (forward-line 1)\n\t  (if (re-search-forward \"^=end\\\\(\\\\s \\\\|$\\\\)\" limit t)\n\t      (progn\n\t\t(set-match-data (list beg (point)))\n\t\tt)))))\n\n  (defun ruby-font-lock-maybe-docs (limit)\n    (let (beg)\n      (save-excursion\n\t(if (and (re-search-backward \"^=\\\\(begin\\\\|end\\\\)\\\\(\\\\s \\\\|$\\\\)\" nil t)\n\t\t (string= (match-string 1) \"begin\"))\n\t    (progn\n\t      (beginning-of-line)\n\t      (setq beg (point)))))\n      (if (and beg (and (re-search-forward \"^=\\\\(begin\\\\|end\\\\)\\\\(\\\\s \\\\|$\\\\)\" nil t)\n\t\t\t(string= (match-string 1) \"end\")))\n\t  (progn\n\t    (set-match-data (list beg (point)))\n\t    t)\n\tnil)))\n\n  (defvar ruby-font-lock-syntax-table\n    (let* ((tbl (copy-syntax-table ruby-mode-syntax-table)))\n      (modify-syntax-entry ?_ \"w\" tbl)\n      tbl))\n\n  (defun ruby-font-lock-here-docs (limit)\n    (if (re-search-forward ruby-here-doc-beg-re limit t)\n\t(let (beg)\n\t  (beginning-of-line)\n          (forward-line)\n\t  (setq beg (point))\n\t  (if (re-search-forward (ruby-here-doc-end-match) nil t)\n\t      (progn\n\t\t(set-match-data (list beg (point)))\n\t\tt)))))\n\n  (defun ruby-font-lock-maybe-here-docs (limit)\n    (let (beg)\n      (save-excursion\n\t(if (re-search-backward ruby-here-doc-beg-re nil t)\n\t    (progn\n\t      (beginning-of-line)\n              (forward-line)\n\t      (setq beg (point)))))\n      (if (and beg\n\t       (let ((end-match (ruby-here-doc-end-match)))\n                 (and (not (re-search-backward end-match beg t))\n\t\t      (re-search-forward end-match nil t))))\n\t  (progn\n\t    (set-match-data (list beg (point)))\n\t    t)\n          nil)))\n\n  (defvar ruby-font-lock-keywords\n    (list\n     ;; functions\n     '(\"^\\\\s *def\\\\s +\\\\([^( \\t\\n]+\\\\)\"\n       1 font-lock-function-name-face)\n     ;; keywords\n     (cons (concat\n\t    \"\\\\(^\\\\|[^_:.@$]\\\\|\\\\.\\\\.\\\\)\\\\b\\\\(defined\\\\?\\\\|\\\\(\"\n\t    (mapconcat\n\t     'identity\n\t     '(\"alias\"\n\t       \"and\"\n\t       \"begin\"\n\t       \"break\"\n\t       \"case\"\n\t       \"catch\"\n\t       \"class\"\n\t       \"def\"\n\t       \"do\"\n\t       \"elsif\"\n\t       \"else\"\n\t       \"fail\"\n\t       \"ensure\"\n\t       \"for\"\n\t       \"end\"\n\t       \"if\"\n\t       \"in\"\n\t       \"module\"\n\t       \"next\"\n\t       \"not\"\n\t       \"or\"\n\t       \"raise\"\n\t       \"redo\"\n\t       \"rescue\"\n\t       \"retry\"\n\t       \"return\"\n\t       \"then\"\n\t       \"throw\"\n\t       \"super\"\n\t       \"unless\"\n\t       \"undef\"\n\t       \"until\"\n\t       \"when\"\n\t       \"while\"\n\t       \"yield\"\n\t       )\n\t     \"\\\\|\")\n\t    \"\\\\)\\\\>\\\\)\")\n\t   2)\n     ;; variables\n     '(\"\\\\(^\\\\|[^_:.@$]\\\\|\\\\.\\\\.\\\\)\\\\b\\\\(nil\\\\|self\\\\|true\\\\|false\\\\)\\\\>\"\n       2 font-lock-variable-name-face)\n     ;; variables\n     '(\"\\\\(\\\\$\\\\([^a-zA-Z0-9 \\n]\\\\|[0-9]\\\\)\\\\)\\\\W\"\n       1 font-lock-variable-name-face)\n     '(\"\\\\(\\\\$\\\\|@\\\\|@@\\\\)\\\\(\\\\w\\\\|_\\\\)+\"\n       0 font-lock-variable-name-face)\n     ;; embedded document\n     '(ruby-font-lock-docs\n       0 font-lock-comment-face t)\n     '(ruby-font-lock-maybe-docs\n       0 font-lock-comment-face t)\n     ;; \"here\" document\n     '(ruby-font-lock-here-docs\n       0 font-lock-string-face t)\n     '(ruby-font-lock-maybe-here-docs\n       0 font-lock-string-face t)\n     `(,ruby-here-doc-beg-re\n       0 font-lock-string-face t)\n     ;; general delimited string\n     '(\"\\\\(^\\\\|[[ \\t\\n<+(,=]\\\\)\\\\(%[xrqQwW]?\\\\([^<[{(a-zA-Z0-9 \\n]\\\\)[^\\n\\\\\\\\]*\\\\(\\\\\\\\.[^\\n\\\\\\\\]*\\\\)*\\\\(\\\\3\\\\)\\\\)\"\n       (2 font-lock-string-face))\n     ;; constants\n     '(\"\\\\(^\\\\|[^_]\\\\)\\\\b\\\\([A-Z]+\\\\(\\\\w\\\\|_\\\\)*\\\\)\"\n       2 font-lock-type-face)\n     ;; symbols\n     '(\"\\\\(^\\\\|[^:]\\\\)\\\\(:\\\\([-+~]@?\\\\|[/%&|^`]\\\\|\\\\*\\\\*?\\\\|<\\\\(<\\\\|=>?\\\\)?\\\\|>[>=]?\\\\|===?\\\\|=~\\\\|\\\\[\\\\]=?\\\\|\\\\(\\\\w\\\\|_\\\\)+\\\\([!?=]\\\\|\\\\b_*\\\\)\\\\|#{[^}\\n\\\\\\\\]*\\\\(\\\\\\\\.[^}\\n\\\\\\\\]*\\\\)*}\\\\)\\\\)\"\n       2 font-lock-reference-face)\n     ;; expression expansion\n     '(\"#\\\\({[^}\\n\\\\\\\\]*\\\\(\\\\\\\\.[^}\\n\\\\\\\\]*\\\\)*}\\\\|\\\\(\\\\$\\\\|@\\\\|@@\\\\)\\\\(\\\\w\\\\|_\\\\)+\\\\)\"\n       0 font-lock-variable-name-face t)\n     ;; warn lower camel case\n     ;'(\"\\\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\\\([!?]?\\\\|\\\\>\\\\)\"\n     ;  0 font-lock-warning-face)\n     )\n    \"*Additional expressions to highlight in ruby mode.\"))\n\n ((featurep 'hilit19)\n  (hilit-set-mode-patterns\n   'ruby-mode\n   '((\"[^$\\\\?]\\\\(\\\"[^\\\\\\\"]*\\\\(\\\\\\\\\\\\(.\\\\|\\n\\\\)[^\\\\\\\"]*\\\\)*\\\"\\\\)\" 1 string)\n     (\"[^$\\\\?]\\\\('[^\\\\']*\\\\(\\\\\\\\\\\\(.\\\\|\\n\\\\)[^\\\\']*\\\\)*'\\\\)\" 1 string)\n     (\"[^$\\\\?]\\\\(`[^\\\\`]*\\\\(\\\\\\\\\\\\(.\\\\|\\n\\\\)[^\\\\`]*\\\\)*`\\\\)\" 1 string)\n     (\"^\\\\s *#.*$\" nil comment)\n     (\"[^$@?\\\\]\\\\(#[^$@{\\n].*$\\\\)\" 1 comment)\n     (\"[^a-zA-Z_]\\\\(\\\\?\\\\(\\\\\\\\[CM]-\\\\)*.\\\\)\" 1 string)\n     (\"^\\\\s *\\\\(require\\\\|load\\\\).*$\" nil include)\n     (\"^\\\\s *\\\\(include\\\\|alias\\\\|undef\\\\).*$\" nil decl)\n     (\"^\\\\s *\\\\<\\\\(class\\\\|def\\\\|module\\\\)\\\\>\" \"[)\\n;]\" defun)\n     (\"[^_]\\\\<\\\\(begin\\\\|case\\\\|else\\\\|elsif\\\\|end\\\\|ensure\\\\|for\\\\|if\\\\|unless\\\\|rescue\\\\|then\\\\|when\\\\|while\\\\|until\\\\|do\\\\|yield\\\\)\\\\>\\\\([^_]\\\\|$\\\\)\" 1 defun)\n     (\"[^_]\\\\<\\\\(and\\\\|break\\\\|next\\\\|raise\\\\|fail\\\\|in\\\\|not\\\\|or\\\\|redo\\\\|retry\\\\|return\\\\|super\\\\|yield\\\\|catch\\\\|throw\\\\|self\\\\|nil\\\\)\\\\>\\\\([^_]\\\\|$\\\\)\" 1 keyword)\n     (\"\\\\$\\\\(.\\\\|\\\\sw+\\\\)\" nil type)\n     (\"[$@].[a-zA-Z_0-9]*\" nil struct)\n     (\"^__END__\" nil label))))\n )\n\n\n(provide 'ruby-mode)\n"
  },
  {
    "path": "misc/ruby-style.el",
    "content": ";;; -*- emacs-lisp -*-\n;;;\n;;; ruby-style.el -\n;;;\n;;; C/C++ mode style for Ruby.\n;;;\n;;;  $Author: nobu $\n;;;  created at: Thu Apr 26 13:54:01 JST 2007\n;;;\n\n(defconst ruby-style-revision \"$Revision: 15588 $\"\n  \"Ruby style revision string.\")\n\n(defconst ruby-style-version\n  (progn\n   (string-match \"[0-9.]+\" ruby-style-revision)\n   (substring ruby-style-revision (match-beginning 0) (match-end 0)))\n  \"Ruby style version number.\")\n\n(defun ruby-style-case-indent (x)\n  (save-excursion\n    (unless (progn (backward-up-list) (back-to-indentation)\n\t\t   (> (point) (cdr x)))\n      (goto-char (cdr x))\n      (if (looking-at \"\\\\<case\\\\|default\\\\>\") '*))))\n\n(defun ruby-style-label-indent (x)\n  (save-excursion\n    (unless (progn (backward-up-list) (back-to-indentation)\n\t\t   (>= (point) (cdr x)))\n      (goto-char (cdr x))\n      (condition-case ()\n\t  (progn\n\t    (backward-up-list)\n\t    (backward-sexp 2)\n\t    (if (looking-at \"\\\\<switch\\\\>\") '/))\n\t(error)))))\n\n(require 'cc-styles)\n(c-add-style\n \"ruby\"\n '(\"bsd\"\n   (c-basic-offset . 4)\n   (tab-width . 8)\n   (indent-tabs-mode . t)\n   (c-offsets-alist\n    (case-label . *)\n    (label . (ruby-style-label-indent *))\n    (statement-case-intro . *)\n    (statement-case-open . *)\n    (statement-block-intro . (ruby-style-case-indent +))\n    (access-label /)\n    )))\n\n(defun ruby-style-c-mode ()\n  (interactive)\n  (if (or (string-match \"/ruby\\\\>\" (buffer-file-name))\n          (save-excursion\n            (goto-char (point-min))\n            (let ((head (progn (forward-line 100) (point)))\n                  (case-fold-search nil))\n              (goto-char (point-min))\n              (re-search-forward \"Copyright (C) .* Yukihiro Matsumoto\" head t))))\n      (setq c-file-style \"ruby\")))\n\n(provide 'ruby-style)\n"
  },
  {
    "path": "misc/rubydb2x.el",
    "content": "(require 'gud)\n(provide 'rubydb)\n\n;; ======================================================================\n;; rubydb functions\n\n;;; History of argument lists passed to rubydb.\n(defvar gud-rubydb-history nil)\n\n(defun gud-rubydb-massage-args (file args)\n  (cons \"-I\" (cons \".\" (cons \"-r\" (cons \"debug\" (cons file args))))))\n\n;; There's no guarantee that Emacs will hand the filter the entire\n;; marker at once; it could be broken up across several strings.  We\n;; might even receive a big chunk with several markers in it.  If we\n;; receive a chunk of text which looks like it might contain the\n;; beginning of a marker, we save it here between calls to the\n;; filter.\n(defvar gud-rubydb-marker-acc \"\")\n\n(defun gud-rubydb-marker-filter (string)\n  (save-match-data\n    (setq gud-marker-acc (concat gud-marker-acc string))\n    (let ((output \"\"))\n      \n      ;; Process all the complete markers in this chunk.\n      (while (string-match \"\\032\\032\\\\([^:\\n]*\\\\):\\\\([0-9]*\\\\):.*\\n\"\n                           gud-marker-acc)\n        (setq\n         \n         ;; Extract the frame position from the marker.\n         gud-last-frame\n         (cons (substring gud-marker-acc (match-beginning 1) (match-end 1))\n               (string-to-int (substring gud-marker-acc\n                                         (match-beginning 2)\n                                         (match-end 2))))\n         \n         ;; Append any text before the marker to the output we're going\n         ;; to return - we don't include the marker in this text.\n         output (concat output\n                        (substring gud-marker-acc 0 (match-beginning 0)))\n         \n         ;; Set the accumulator to the remaining text.\n         gud-marker-acc (substring gud-marker-acc (match-end 0))))\n      \n      ;; Does the remaining text look like it might end with the\n      ;; beginning of another marker?  If it does, then keep it in\n      ;; gud-marker-acc until we receive the rest of it.  Since we\n      ;; know the full marker regexp above failed, it's pretty simple to\n      ;; test for marker starts.\n      (if (string-match \"\\032.*\\\\'\" gud-marker-acc)\n          (progn\n            ;; Everything before the potential marker start can be output.\n            (setq output (concat output (substring gud-marker-acc\n                                                   0 (match-beginning 0))))\n            \n            ;; Everything after, we save, to combine with later input.\n            (setq gud-marker-acc\n                  (substring gud-marker-acc (match-beginning 0))))\n        \n        (setq output (concat output gud-marker-acc)\n              gud-marker-acc \"\"))\n      \n      output)))\n  \n(defun gud-rubydb-find-file (f)\n  (find-file-noselect f))\n\n(defvar rubydb-command-name \"ruby\"\n  \"File name for executing ruby.\")\n\n;;;###autoload\n(defun rubydb (command-line)\n  \"Run rubydb on program FILE in buffer *gud-FILE*.\nThe directory containing FILE becomes the initial working directory\nand source-file directory for your debugger.\"\n  (interactive\n   (list (read-from-minibuffer \"Run rubydb (like this): \"\n                               (if (consp gud-rubydb-history)\n                                   (car gud-rubydb-history)\n                                 (concat rubydb-command-name \" \"))\n                               nil nil\n                               '(gud-rubydb-history . 1))))\n\n  (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args)\n                            (gud-marker-filter . gud-rubydb-marker-filter)\n                            (gud-find-file . gud-rubydb-find-file)\n                            ))\n  (gud-common-init command-line)\n\n  (gud-def gud-break  \"b %l\"         \"\\C-b\" \"Set breakpoint at current line.\")\n;  (gud-def gud-remove \"clear %l\"     \"\\C-d\" \"Remove breakpoint at current line\")\n  (gud-def gud-step   \"s\"            \"\\C-s\" \"Step one source line with display.\")\n  (gud-def gud-next   \"n\"            \"\\C-n\" \"Step one line (skip functions).\")\n  (gud-def gud-cont   \"c\"            \"\\C-r\" \"Continue with display.\")\n  (gud-def gud-finish \"finish\"       \"\\C-f\" \"Finish executing current function.\")\n  (gud-def gud-up     \"up %p\"        \"<\" \"Up N stack frames (numeric arg).\")\n  (gud-def gud-down   \"down %p\"      \">\" \"Down N stack frames (numeric arg).\")\n  (gud-def gud-print  \"p %e\"         \"\\C-p\" \"Evaluate ruby expression at point.\")\n\n  (setq comint-prompt-regexp \"^(rdb:-) \")\n  (setq paragraph-start comint-prompt-regexp)\n  (run-hooks 'rubydb-mode-hook)\n  )\n"
  },
  {
    "path": "misc/rubydb3x.el",
    "content": "(require 'gud)\n(provide 'rubydb)\n\n;; ======================================================================\n;; rubydb functions\n\n;;; History of argument lists passed to rubydb.\n(defvar gud-rubydb-history nil)\n\n(if (fboundp 'gud-overload-functions)\n    (defun gud-rubydb-massage-args (file args)\n      (cons \"-r\" (cons \"debug\" (cons file args))))\n  (defun gud-rubydb-massage-args (file args)\n      (cons \"-r\" (cons \"debug\" args))))\n\n;; There's no guarantee that Emacs will hand the filter the entire\n;; marker at once; it could be broken up across several strings.  We\n;; might even receive a big chunk with several markers in it.  If we\n;; receive a chunk of text which looks like it might contain the\n;; beginning of a marker, we save it here between calls to the\n;; filter.\n(defvar gud-rubydb-marker-acc \"\")\n(make-variable-buffer-local 'gud-rubydb-marker-acc)\n\n(defun gud-rubydb-marker-filter (string)\n  (setq gud-rubydb-marker-acc (concat gud-rubydb-marker-acc string))\n  (let ((output \"\"))\n\n    ;; Process all the complete markers in this chunk.\n    (while (string-match \"\\032\\032\\\\([^:\\n]*\\\\):\\\\([0-9]*\\\\):.*\\n\"\n\t\t\t gud-rubydb-marker-acc)\n      (setq\n\n       ;; Extract the frame position from the marker.\n       gud-last-frame\n       (cons (substring gud-rubydb-marker-acc (match-beginning 1) (match-end 1))\n\t     (string-to-int (substring gud-rubydb-marker-acc\n\t\t\t\t       (match-beginning 2)\n\t\t\t\t       (match-end 2))))\n\n       ;; Append any text before the marker to the output we're going\n       ;; to return - we don't include the marker in this text.\n       output (concat output\n\t\t      (substring gud-rubydb-marker-acc 0 (match-beginning 0)))\n\n       ;; Set the accumulator to the remaining text.\n       gud-rubydb-marker-acc (substring gud-rubydb-marker-acc (match-end 0))))\n\n    ;; Does the remaining text look like it might end with the\n    ;; beginning of another marker?  If it does, then keep it in\n    ;; gud-rubydb-marker-acc until we receive the rest of it.  Since we\n    ;; know the full marker regexp above failed, it's pretty simple to\n    ;; test for marker starts.\n    (if (string-match \"\\032.*\\\\'\" gud-rubydb-marker-acc)\n\t(progn\n\t  ;; Everything before the potential marker start can be output.\n\t  (setq output (concat output (substring gud-rubydb-marker-acc\n\t\t\t\t\t\t 0 (match-beginning 0))))\n\n\t  ;; Everything after, we save, to combine with later input.\n\t  (setq gud-rubydb-marker-acc\n\t\t(substring gud-rubydb-marker-acc (match-beginning 0))))\n\n      (setq output (concat output gud-rubydb-marker-acc)\n\t    gud-rubydb-marker-acc \"\"))\n\n    output))\n\n(defun gud-rubydb-find-file (f)\n  (save-excursion\n    (let ((buf (find-file-noselect f)))\n      (set-buffer buf)\n;;      (gud-make-debug-menu)\n      buf)))\n\n(defvar rubydb-command-name \"ruby\"\n  \"File name for executing ruby.\")\n\n;;;###autoload\n(defun rubydb (command-line)\n  \"Run rubydb on program FILE in buffer *gud-FILE*.\nThe directory containing FILE becomes the initial working directory\nand source-file directory for your debugger.\"\n  (interactive\n   (list (read-from-minibuffer \"Run rubydb (like this): \"\n\t\t\t       (if (consp gud-rubydb-history)\n\t\t\t\t   (car gud-rubydb-history)\n\t\t\t\t (concat rubydb-command-name \" \"))\n\t\t\t       nil nil\n\t\t\t       '(gud-rubydb-history . 1))))\n\n  (if (not (fboundp 'gud-overload-functions))\n      (gud-common-init command-line 'gud-rubydb-massage-args\n\t\t       'gud-rubydb-marker-filter 'gud-rubydb-find-file)\n    (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args)\n\t\t\t      (gud-marker-filter . gud-rubydb-marker-filter)\n\t\t\t      (gud-find-file . gud-rubydb-find-file)))\n    (gud-common-init command-line rubydb-command-name))\n\n  (gud-def gud-break  \"b %l\"         \"\\C-b\" \"Set breakpoint at current line.\")\n;  (gud-def gud-remove \"clear %l\"     \"\\C-d\" \"Remove breakpoint at current line\")\n  (gud-def gud-step   \"s\"            \"\\C-s\" \"Step one source line with display.\")\n  (gud-def gud-next   \"n\"            \"\\C-n\" \"Step one line (skip functions).\")\n  (gud-def gud-cont   \"c\"            \"\\C-r\" \"Continue with display.\")\n  (gud-def gud-finish \"finish\"       \"\\C-f\" \"Finish executing current function.\")\n  (gud-def gud-up     \"up %p\"        \"<\" \"Up N stack frames (numeric arg).\")\n  (gud-def gud-down   \"down %p\"      \">\" \"Down N stack frames (numeric arg).\")\n  (gud-def gud-print  \"p %e\"         \"\\C-p\" \"Evaluate ruby expression at point.\")\n\n  (setq comint-prompt-regexp \"^(rdb:-) \")\n  (if (boundp 'comint-last-output-start)\n      (set-marker comint-last-output-start (point)))\n  (set (make-local-variable 'paragraph-start) comint-prompt-regexp)\n  (run-hooks 'rubydb-mode-hook)\n  )\n"
  },
  {
    "path": "missing/acosh.c",
    "content": "/**********************************************************************\n\n  acosh.c -\n\n  $Author$\n  $Date$\n  created at: Fri Apr 12 00:34:17 JST 2002\n\n  public domain rewrite of acosh(3), asinh(3) and atanh(3)\n\n**********************************************************************/\n\n#include <errno.h>\n#include <float.h>\n#include <math.h>\n\n/* DBL_MANT_DIG must be less than 4 times of bits of int */\n#ifndef DBL_MANT_DIG\n#define DBL_MANT_DIG 53\t\t/* in this case, at least 12 digit precision */\n#endif\n#define BIG_CRITERIA_BIT (1<<DBL_MANT_DIG/2)\n#if BIG_CRITERIA_BIT > 0\n#define BIG_CRITERIA (1.0*BIG_CRITERIA_BIT)\n#else\n#define BIG_CRITERIA (1.0*(1<<DBL_MANT_DIG/4)*(1<<(DBL_MANT_DIG/2+1-DBL_MANT_DIG/4)))\n#endif\n#define SMALL_CRITERIA_BIT (1<<(DBL_MANT_DIG/3))\n#if SMALL_CRITERIA_BIT > 0\n#define SMALL_CRITERIA (1.0/SMALL_CRITERIA_BIT)\n#else\n#define SMALL_CRITERIA (1.0*(1<<DBL_MANT_DIG/4)*(1<<(DBL_MANT_DIG/3+1-DBL_MANT_DIG/4)))\n#endif\n\n#ifndef HAVE_ACOSH\ndouble\nacosh(x)\n    double x;\n{\n    if (x < 1)\n\tx = -1;\t\t\t/* NaN */\n    else if (x == 1)\n\treturn 0;\n    else if (x > BIG_CRITERIA)\n\tx += x;\n    else\n\tx += sqrt((x + 1) * (x - 1));\n    return log(x);\n}\n#endif\n\n#ifndef HAVE_ASINH\ndouble\nasinh(x)\n    double x;\n{\n    int neg = x < 0;\n    double z = fabs(x);\n\n    if (z < SMALL_CRITERIA) return x;\n    if (z < (1.0/(1<<DBL_MANT_DIG/5))) {\n\tdouble x2 = z * z;\n\tz *= 1 + x2 * (-1.0/6.0 + x2 * 3.0/40.0);\n    }\n    else if (z > BIG_CRITERIA) {\n\tz = log(z + z);\n    }\n    else {\n\tz = log(z + sqrt(z * z + 1));\n    }\n    if (neg) z = -z;\n    return z;\n}\n#endif\n\n#ifndef HAVE_ATANH\ndouble\natanh(x)\n    double x;\n{\n    int neg = x < 0;\n    double z = fabs(x);\n\n    if (z < SMALL_CRITERIA) return x;\n    z = log(z > 1 ? -1 : (1 + z) / (1 - z)) / 2;\n    if (neg) z = -z;\n    return z;\n}\n#endif\n"
  },
  {
    "path": "missing/alloca.c",
    "content": "/* alloca -- (mostly) portable public-domain implementation -- D A Gwyn\n\n   last edit:\t86/05/30\trms\n   include config.h, since on VMS it renames some symbols.\n   Use xmalloc instead of malloc.\n\n   This implementation of the PWB library alloca() function,\n   which is used to allocate space off the run-time stack so\n   that it is automatically reclaimed upon procedure exit, \n   was inspired by discussions with J. Q. Johnson of Cornell.\n\n   It should work under any C implementation that uses an\n   actual procedure stack (as opposed to a linked list of\n   frames).  There are some preprocessor constants that can\n   be defined when compiling for your specific system, for\n   improved efficiency; however, the defaults should be okay.\n\n   The general concept of this implementation is to keep\n   track of all alloca()-allocated blocks, and reclaim any\n   that are found to be deeper in the stack than the current\n   invocation.  This heuristic does not reclaim storage as\n   soon as it becomes invalid, but it will do so eventually.\n\n   As a special case, alloca(0) reclaims storage without\n   allocating any.  It is a good idea to use alloca(0) in\n   your main control loop, etc. to force garbage collection.\n*/\n#ifndef lint\nstatic char\tSCCSid[] = \"@(#)alloca.c\t1.1\";\t/* for the \"what\" utility */\n#endif\n\n#include <sys/types.h>\n#include \"config.h\"\n#ifdef emacs\n#ifdef static\n/* actually, only want this if static is defined as \"\"\n   -- this is for usg, in which emacs must undefine static\n   in order to make unexec workable\n   */\n#ifndef STACK_DIRECTION\nyou\nlose\n-- must know STACK_DIRECTION at compile-time\n#endif /* STACK_DIRECTION undefined */\n#endif /* static */\n#endif /* emacs */\n\ntypedef void\t*pointer;\t\t/* generic pointer type */\n\n#define\tNULL\t0\t\t\t/* null pointer constant */\n\n#ifdef RUBY_LIB\n#define xmalloc ruby_xmalloc\n#define xfree ruby_xfree\n#endif\n\nextern void\txfree();\nextern pointer\txmalloc();\n\n/*\n\tDefine STACK_DIRECTION if you know the direction of stack\n\tgrowth for your system; otherwise it will be automatically\n\tdeduced at run-time.\n\n\tSTACK_DIRECTION > 0 => grows toward higher addresses\n\tSTACK_DIRECTION < 0 => grows toward lower addresses\n\tSTACK_DIRECTION = 0 => direction of growth unknown\n*/\n\n#ifndef STACK_DIRECTION\n#define\tSTACK_DIRECTION\t0\t\t/* direction unknown */\n#endif\n\n#if STACK_DIRECTION != 0\n\n#define\tSTACK_DIR\tSTACK_DIRECTION\t/* known at compile-time */\n\n#else\t/* STACK_DIRECTION == 0; need run-time code */\n\nstatic int\tstack_dir;\t\t/* 1 or -1 once known */\n#define\tSTACK_DIR\tstack_dir\n\nstatic void\nfind_stack_direction (/* void */)\n{\n  static char\t*addr = NULL;\t/* address of first\n\t\t\t\t   `dummy', once known */\n  auto char\tdummy;\t\t/* to get stack address */\n\n  if (addr == NULL)\n    {\t\t\t\t/* initial entry */\n      addr = &dummy;\n\n      find_stack_direction ();\t/* recurse once */\n    }\n  else\t\t\t\t/* second entry */\n    if (&dummy > addr)\n      stack_dir = 1;\t\t/* stack grew upward */\n    else\n      stack_dir = -1;\t\t/* stack grew downward */\n}\n\n#endif\t/* STACK_DIRECTION == 0 */\n\n/*\n\tAn \"alloca header\" is used to:\n\t(a) chain together all alloca()ed blocks;\n\t(b) keep track of stack depth.\n\n\tIt is very important that sizeof(header) agree with malloc()\n\talignment chunk size.  The following default should work okay.\n*/\n\n#ifndef\tALIGN_SIZE\n#define\tALIGN_SIZE\tsizeof(double)\n#endif\n\ntypedef union hdr\n{\n  char\talign[ALIGN_SIZE];\t/* to force sizeof(header) */\n  struct\n    {\n      union hdr *next;\t\t/* for chaining headers */\n      char *deep;\t\t/* for stack depth measure */\n    } h;\n} header;\n\n/*\n\talloca( size ) returns a pointer to at least `size' bytes of\n\tstorage which will be automatically reclaimed upon exit from\n\tthe procedure that called alloca().  Originally, this space\n\twas supposed to be taken from the current stack frame of the\n\tcaller, but that method cannot be made to work for some\n\timplementations of C, for example under Gould's UTX/32.\n*/\n\nstatic header *last_alloca_header = NULL; /* -> last alloca header */\n\npointer\nalloca (size_t size)\t\t/* returns pointer to storage */\n{\n  auto char\tprobe;\t\t/* probes stack depth: */\n  register char\t*depth = &probe;\n\n#if STACK_DIRECTION == 0\n  if (STACK_DIR == 0)\t\t/* unknown growth direction */\n    find_stack_direction ();\n#endif\n\n  /* Reclaim garbage, defined as all alloca()ed storage that\n     was allocated from deeper in the stack than currently. */\n  {\n    register header\t*hp;\t/* traverses linked list */\n\n    for (hp = last_alloca_header; hp != NULL;)\n      if (STACK_DIR > 0 && hp->h.deep > depth\n\t  || STACK_DIR < 0 && hp->h.deep < depth)\n\t{\n\t  register header\t*np = hp->h.next;\n\n\t  xfree ((pointer) hp);\t/* collect garbage */\n\n\t  hp = np;\t\t/* -> next header */\n\t}\n      else\n\tbreak;\t\t\t/* rest are not deeper */\n\n    last_alloca_header = hp;\t/* -> last valid storage */\n  }\n\n  if (size == 0)\n    return NULL;\t\t/* no allocation required */\n\n  /* Allocate combined header + user data storage. */\n\n  {\n    register pointer\tnew = xmalloc (sizeof (header) + size);\n    /* address of header */\n\n    ((header *)new)->h.next = last_alloca_header;\n    ((header *)new)->h.deep = depth;\n\n    last_alloca_header = (header *)new;\n\n    /* User storage begins just after header. */\n\n    return (pointer)((char *)new + sizeof(header));\n  }\n}\n\n"
  },
  {
    "path": "missing/crypt.c",
    "content": "/*\n * Copyright (c) 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * This code is derived from software contributed to Berkeley by\n * Tom Truscott.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(LIBC_SCCS) && !defined(lint)\nstatic char sccsid[] = \"@(#)crypt.c\t8.1 (Berkeley) 6/4/93\";\n#endif /* LIBC_SCCS and not lint */\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#include <limits.h>\n#ifdef HAVE_PWD_H\n#include <pwd.h>\n#endif\n#include <stdio.h>\n#ifndef _PASSWORD_EFMT1\n#define _PASSWORD_EFMT1 '_'\n#endif\n\n/*\n * UNIX password, and DES, encryption.\n * By Tom Truscott, trt@rti.rti.org,\n * from algorithms by Robert W. Baldwin and James Gillogly.\n *\n * References:\n * \"Mathematical Cryptology for Computer Scientists and Mathematicians,\"\n * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.\n *\n * \"Password Security: A Case History,\" R. Morris and Ken Thompson,\n * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.\n *\n * \"DES will be Totally Insecure within Ten Years,\" M.E. Hellman,\n * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.\n */\n\n/* =====  Configuration ==================== */\n\n/*\n * define \"MUST_ALIGN\" if your compiler cannot load/store\n * long integers at arbitrary (e.g. odd) memory locations.\n * (Either that or never pass unaligned addresses to des_cipher!)\n */\n#if !defined(vax)\n#define\tMUST_ALIGN\n#endif\n\n#ifdef CHAR_BITS\n#if CHAR_BITS != 8\n\t#error C_block structure assumes 8 bit characters\n#endif\n#endif\n\n/*\n * define \"LONG_IS_32_BITS\" only if sizeof(long)==4.\n * This avoids use of bit fields (your compiler may be sloppy with them).\n */\n#if !defined(cray)\n#define\tLONG_IS_32_BITS\n#endif\n\n/*\n * define \"B64\" to be the declaration for a 64 bit integer.\n * XXX this feature is currently unused, see \"endian\" comment below.\n */\n#if defined(cray)\n#define\tB64\tlong\n#endif\n#if defined(convex)\n#define\tB64\tlong long\n#endif\n\n/*\n * define \"LARGEDATA\" to get faster permutations, by using about 72 kilobytes\n * of lookup tables.  This speeds up des_setkey() and des_cipher(), but has\n * little effect on crypt().\n */\n#if defined(notdef)\n#define\tLARGEDATA\n#endif\n\nint des_setkey(), des_cipher();\n\n/* compile with \"-DSTATIC=int\" when profiling */\n#ifndef STATIC\n#define\tSTATIC\tstatic\n#endif\nSTATIC void init_des(), init_perm(), permute();\n#ifdef DEBUG\nSTATIC void prtab();\n#endif\n\n/* ==================================== */\n\n/*\n * Cipher-block representation (Bob Baldwin):\n *\n * DES operates on groups of 64 bits, numbered 1..64 (sigh).  One\n * representation is to store one bit per byte in an array of bytes.  Bit N of\n * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.\n * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the\n * first byte, 9..16 in the second, and so on.  The DES spec apparently has\n * bit 1 in the MSB of the first byte, but that is particularly noxious so we\n * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is\n * the MSB of the first byte.  Specifically, the 64-bit input data and key are\n * converted to LSB format, and the output 64-bit block is converted back into\n * MSB format.\n *\n * DES operates internally on groups of 32 bits which are expanded to 48 bits\n * by permutation E and shrunk back to 32 bits by the S boxes.  To speed up\n * the computation, the expansion is applied only once, the expanded\n * representation is maintained during the encryption, and a compression\n * permutation is applied only at the end.  To speed up the S-box lookups,\n * the 48 bits are maintained as eight 6 bit groups, one per byte, which\n * directly feed the eight S-boxes.  Within each byte, the 6 bits are the\n * most significant ones.  The low two bits of each byte are zero.  (Thus,\n * bit 1 of the 48 bit E expansion is stored as the \"4\"-valued bit of the\n * first byte in the eight byte representation, bit 2 of the 48 bit value is\n * the \"8\"-valued bit, and so on.)  In fact, a combined \"SPE\"-box lookup is\n * used, in which the output is the 64 bit result of an S-box lookup which\n * has been permuted by P and expanded by E, and is ready for use in the next\n * iteration.  Two 32-bit wide tables, SPE[0] and SPE[1], are used for this\n * lookup.  Since each byte in the 48 bit path is a multiple of four, indexed\n * lookup of SPE[0] and SPE[1] is simple and fast.  The key schedule and\n * \"salt\" are also converted to this 8*(6+2) format.  The SPE table size is\n * 8*64*8 = 4K bytes.\n *\n * To speed up bit-parallel operations (such as XOR), the 8 byte\n * representation is \"union\"ed with 32 bit values \"i0\" and \"i1\", and, on\n * machines which support it, a 64 bit value \"b64\".  This data structure,\n * \"C_block\", has two problems.  First, alignment restrictions must be\n * honored.  Second, the byte-order (e.g. little-endian or big-endian) of\n * the architecture becomes visible.\n *\n * The byte-order problem is unfortunate, since on the one hand it is good\n * to have a machine-independent C_block representation (bits 1..8 in the\n * first byte, etc.), and on the other hand it is good for the LSB of the\n * first byte to be the LSB of i0.  We cannot have both these things, so we\n * currently use the \"little-endian\" representation and avoid any multi-byte\n * operations that depend on byte order.  This largely precludes use of the\n * 64-bit datatype since the relative order of i0 and i1 are unknown.  It\n * also inhibits grouping the SPE table to look up 12 bits at a time.  (The\n * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1\n * high-order zero, providing fast indexing into a 64-bit wide SPE.)  On the\n * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup\n * requires a 128 kilobyte table, so perhaps this is not a big loss.\n *\n * Permutation representation (Jim Gillogly):\n *\n * A transformation is defined by its effect on each of the 8 bytes of the\n * 64-bit input.  For each byte we give a 64-bit output that has the bits in\n * the input distributed appropriately.  The transformation is then the OR\n * of the 8 sets of 64-bits.  This uses 8*256*8 = 16K bytes of storage for\n * each transformation.  Unless LARGEDATA is defined, however, a more compact\n * table is used which looks up 16 4-bit \"chunks\" rather than 8 8-bit chunks.\n * The smaller table uses 16*16*8 = 2K bytes for each transformation.  This\n * is slower but tolerable, particularly for password encryption in which\n * the SPE transformation is iterated many times.  The small tables total 9K\n * bytes, the large tables total 72K bytes.\n *\n * The transformations used are:\n * IE3264: MSB->LSB conversion, initial permutation, and expansion.\n *\tThis is done by collecting the 32 even-numbered bits and applying\n *\ta 32->64 bit transformation, and then collecting the 32 odd-numbered\n *\tbits and applying the same transformation.  Since there are only\n *\t32 input bits, the IE3264 transformation table is half the size of\n *\tthe usual table.\n * CF6464: Compression, final permutation, and LSB->MSB conversion.\n *\tThis is done by two trivial 48->32 bit compressions to obtain\n *\ta 64-bit block (the bit numbering is given in the \"CIFP\" table)\n *\tfollowed by a 64->64 bit \"cleanup\" transformation.  (It would\n *\tbe possible to group the bits in the 64-bit block so that 2\n *\tidentical 32->32 bit transformations could be used instead,\n *\tsaving a factor of 4 in space and possibly 2 in time, but\n *\tbyte-ordering and other complications rear their ugly head.\n *\tSimilar opportunities/problems arise in the key schedule\n *\ttransforms.)\n * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.\n *\tThis admittedly baroque 64->64 bit transformation is used to\n *\tproduce the first code (in 8*(6+2) format) of the key schedule.\n * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.\n *\tIt would be possible to define 15 more transformations, each\n *\twith a different rotation, to generate the entire key schedule.\n *\tTo save space, however, we instead permute each code into the\n *\tnext by using a transformation that \"undoes\" the PC2 permutation,\n *\trotates the code, and then applies PC2.  Unfortunately, PC2\n *\ttransforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not\n *\tinvertible.  We get around that problem by using a modified PC2\n *\twhich retains the 8 otherwise-lost bits in the unused low-order\n *\tbits of each byte.  The low-order bits are cleared when the\n *\tcodes are stored into the key schedule.\n * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.\n *\tThis is faster than applying PC2ROT[0] twice,\n *\n * The Bell Labs \"salt\" (Bob Baldwin):\n *\n * The salting is a simple permutation applied to the 48-bit result of E.\n * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and\n * i+24 of the result are swapped.  The salt is thus a 24 bit number, with\n * 16777216 possible values.  (The original salt was 12 bits and could not\n * swap bits 13..24 with 36..48.)\n *\n * It is possible, but ugly, to warp the SPE table to account for the salt\n * permutation.  Fortunately, the conditional bit swapping requires only\n * about four machine instructions and can be done on-the-fly with about an\n * 8% performance penalty.\n */\n\ntypedef union {\n\tunsigned char b[8];\n\tstruct {\n#if defined(LONG_IS_32_BITS)\n\t\t/* long is often faster than a 32-bit bit field */\n\t\tlong\ti0;\n\t\tlong\ti1;\n#else\n\t\tlong\ti0: 32;\n\t\tlong\ti1: 32;\n#endif\n\t} b32;\n#if defined(B64)\n\tB64\tb64;\n#endif\n} C_block;\n\n/*\n * Convert twenty-four-bit long in host-order\n * to six bits (and 2 low-order zeroes) per char little-endian format.\n */\n#define\tTO_SIX_BIT(rslt, src) {\t\t\t\t\\\n\t\tC_block cvt;\t\t\t\t\\\n\t\tcvt.b[0] = src; src >>= 6;\t\t\\\n\t\tcvt.b[1] = src; src >>= 6;\t\t\\\n\t\tcvt.b[2] = src; src >>= 6;\t\t\\\n\t\tcvt.b[3] = src;\t\t\t\t\\\n\t\trslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2;\t\\\n\t}\n\n/*\n * These macros may someday permit efficient use of 64-bit integers.\n */\n#define\tZERO(d,d0,d1)\t\t\td0 = 0, d1 = 0\n#define\tLOAD(d,d0,d1,bl)\t\td0 = (bl).b32.i0, d1 = (bl).b32.i1\n#define\tLOADREG(d,d0,d1,s,s0,s1)\td0 = s0, d1 = s1\n#define\tOR(d,d0,d1,bl)\t\t\td0 |= (bl).b32.i0, d1 |= (bl).b32.i1\n#define\tSTORE(s,s0,s1,bl)\t\t(bl).b32.i0 = s0, (bl).b32.i1 = s1\n#define\tDCL_BLOCK(d,d0,d1)\t\tlong d0, d1\n\n#if defined(LARGEDATA)\n\t/* Waste memory like crazy.  Also, do permutations in line */\n#define\tLGCHUNKBITS\t3\n#define\tCHUNKBITS\t(1<<LGCHUNKBITS)\n#define\tPERM6464(d,d0,d1,cpp,p)\t\t\t\t\\\n\tLOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);\t\t\\\n\tOR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);\t\t\\\n\tOR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);\t\t\\\n\tOR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);\t\t\\\n\tOR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]);\t\t\\\n\tOR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]);\t\t\\\n\tOR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]);\t\t\\\n\tOR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);\n#define\tPERM3264(d,d0,d1,cpp,p)\t\t\t\t\\\n\tLOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]);\t\t\\\n\tOR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]);\t\t\\\n\tOR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]);\t\t\\\n\tOR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);\n#else\n\t/* \"small data\" */\n#define\tLGCHUNKBITS\t2\n#define\tCHUNKBITS\t(1<<LGCHUNKBITS)\n#define\tPERM6464(d,d0,d1,cpp,p)\t\t\t\t\\\n\t{ C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }\n#define\tPERM3264(d,d0,d1,cpp,p)\t\t\t\t\\\n\t{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }\n\nSTATIC void\npermute(cp, out, p, chars_in)\n\tunsigned char *cp;\n\tC_block *out;\n\tregister C_block *p;\n\tint chars_in;\n{\n\tregister DCL_BLOCK(D,D0,D1);\n\tregister C_block *tp;\n\tregister int t;\n\n\tZERO(D,D0,D1);\n\tdo {\n\t\tt = *cp++;\n\t\ttp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);\n\t\ttp = &p[t>>4];  OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);\n\t} while (--chars_in > 0);\n\tSTORE(D,D0,D1,*out);\n}\n#endif /* LARGEDATA */\n\n\n/* =====  (mostly) Standard DES Tables ==================== */\n\nstatic unsigned char IP[] = {\t\t/* initial permutation */\n\t58, 50, 42, 34, 26, 18, 10,  2,\n\t60, 52, 44, 36, 28, 20, 12,  4,\n\t62, 54, 46, 38, 30, 22, 14,  6,\n\t64, 56, 48, 40, 32, 24, 16,  8,\n\t57, 49, 41, 33, 25, 17,  9,  1,\n\t59, 51, 43, 35, 27, 19, 11,  3,\n\t61, 53, 45, 37, 29, 21, 13,  5,\n\t63, 55, 47, 39, 31, 23, 15,  7,\n};\n\n/* The final permutation is the inverse of IP - no table is necessary */\n\nstatic unsigned char ExpandTr[] = {\t/* expansion operation */\n\t32,  1,  2,  3,  4,  5,\n\t 4,  5,  6,  7,  8,  9,\n\t 8,  9, 10, 11, 12, 13,\n\t12, 13, 14, 15, 16, 17,\n\t16, 17, 18, 19, 20, 21,\n\t20, 21, 22, 23, 24, 25,\n\t24, 25, 26, 27, 28, 29,\n\t28, 29, 30, 31, 32,  1,\n};\n\nstatic unsigned char PC1[] = {\t\t/* permuted choice table 1 */\n\t57, 49, 41, 33, 25, 17,  9,\n\t 1, 58, 50, 42, 34, 26, 18,\n\t10,  2, 59, 51, 43, 35, 27,\n\t19, 11,  3, 60, 52, 44, 36,\n\n\t63, 55, 47, 39, 31, 23, 15,\n\t 7, 62, 54, 46, 38, 30, 22,\n\t14,  6, 61, 53, 45, 37, 29,\n\t21, 13,  5, 28, 20, 12,  4,\n};\n\nstatic unsigned char Rotates[] = {\t/* PC1 rotation schedule */\n\t1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,\n};\n\n/* note: each \"row\" of PC2 is left-padded with bits that make it invertible */\nstatic unsigned char PC2[] = {\t\t/* permuted choice table 2 */\n\t 9, 18,    14, 17, 11, 24,  1,  5,\n\t22, 25,     3, 28, 15,  6, 21, 10,\n\t35, 38,    23, 19, 12,  4, 26,  8,\n\t43, 54,    16,  7, 27, 20, 13,  2,\n\n\t 0,  0,    41, 52, 31, 37, 47, 55,\n\t 0,  0,    30, 40, 51, 45, 33, 48,\n\t 0,  0,    44, 49, 39, 56, 34, 53,\n\t 0,  0,    46, 42, 50, 36, 29, 32,\n};\n\nstatic unsigned char S[8][64] = {\t/* 48->32 bit substitution tables */\n    {\n\t\t\t\t\t/* S[1]\t\t\t*/\n\t14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,\n\t 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,\n\t 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,\n\t15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,\n    },\n    {\n\t\t\t\t\t/* S[2]\t\t\t*/\n\t15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,\n\t 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,\n\t 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,\n\t13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,\n    },\n    {\n\t\t\t\t\t/* S[3]\t\t\t*/\n\t10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,\n\t13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,\n\t13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,\n\t 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,\n    },\n    {\n\t\t\t\t\t/* S[4]\t\t\t*/\n\t 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,\n\t13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,\n\t10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,\n\t 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,\n    },\n    {\n\t\t\t\t\t/* S[5]\t\t\t*/\n\t 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,\n\t14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,\n\t 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,\n\t11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,\n    },\n    {\n\t\t\t\t\t/* S[6]\t\t\t*/\n\t12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,\n\t10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,\n\t 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,\n\t 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,\n    },\n    {\n\t\t\t\t\t/* S[7]\t\t\t*/\n\t 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,\n\t13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,\n\t 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,\n\t 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,\n    },\n    {\n\t\t\t\t\t/* S[8]\t\t\t*/\n\t13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,\n\t 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,\n\t 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,\n\t 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11,\n    },\n};\n\nstatic unsigned char P32Tr[] = {\t/* 32-bit permutation function */\n\t16,  7, 20, 21,\n\t29, 12, 28, 17,\n\t 1, 15, 23, 26,\n\t 5, 18, 31, 10,\n\t 2,  8, 24, 14,\n\t32, 27,  3,  9,\n\t19, 13, 30,  6,\n\t22, 11,  4, 25,\n};\n\nstatic unsigned char CIFP[] = {\t\t/* compressed/interleaved permutation */\n\t 1,  2,  3,  4,   17, 18, 19, 20,\n\t 5,  6,  7,  8,   21, 22, 23, 24,\n\t 9, 10, 11, 12,   25, 26, 27, 28,\n\t13, 14, 15, 16,   29, 30, 31, 32,\n\n\t33, 34, 35, 36,   49, 50, 51, 52,\n\t37, 38, 39, 40,   53, 54, 55, 56,\n\t41, 42, 43, 44,   57, 58, 59, 60,\n\t45, 46, 47, 48,   61, 62, 63, 64,\n};\n\nstatic unsigned char itoa64[] =\t\t/* 0..63 => ascii-64 */\n\t\"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\n\n/* =====  Tables that are initialized at run time  ==================== */\n\n\nstatic unsigned char a64toi[128];\t/* ascii-64 => 0..63 */\n\n/* Initial key schedule permutation */\nstatic C_block\tPC1ROT[64/CHUNKBITS][1<<CHUNKBITS];\n\n/* Subsequent key schedule rotation permutations */\nstatic C_block\tPC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];\n\n/* Initial permutation/expansion table */\nstatic C_block\tIE3264[32/CHUNKBITS][1<<CHUNKBITS];\n\n/* Table that combines the S, P, and E operations.  */\nstatic long SPE[2][8][64];\n\n/* compressed/interleaved => final permutation table */\nstatic C_block\tCF6464[64/CHUNKBITS][1<<CHUNKBITS];\n\n\n/* ==================================== */\n\n\nstatic C_block\tconstdatablock;\t\t\t/* encryption constant */\nstatic char\tcryptresult[1+4+4+11+1];\t/* encrypted result */\n\n/*\n * Return a pointer to static data consisting of the \"setting\"\n * followed by an encryption produced by the \"key\" and \"setting\".\n */\nchar *\ncrypt(key, setting)\n\tregister const char *key;\n\tregister const char *setting;\n{\n\tregister char *encp;\n\tregister long i;\n\tregister int t;\n\tlong salt;\n\tint num_iter, salt_size;\n\tC_block keyblock, rsltblock;\n\n\tfor (i = 0; i < 8; i++) {\n\t\tif ((t = 2*(unsigned char)(*key)) != 0)\n\t\t\tkey++;\n\t\tkeyblock.b[i] = t;\n\t}\n\tif (des_setkey((char *)keyblock.b))\t/* also initializes \"a64toi\" */\n\t\treturn (NULL);\n\n\tencp = &cryptresult[0];\n\tswitch (*setting) {\n\tcase _PASSWORD_EFMT1:\n\t\t/*\n\t\t * Involve the rest of the password 8 characters at a time.\n\t\t */\n\t\twhile (*key) {\n\t\t\tif (des_cipher((char *)&keyblock,\n\t\t\t    (char *)&keyblock, 0L, 1))\n\t\t\t\treturn (NULL);\n\t\t\tfor (i = 0; i < 8; i++) {\n\t\t\t\tif ((t = 2*(unsigned char)(*key)) != 0)\n\t\t\t\t\tkey++;\n\t\t\t\tkeyblock.b[i] ^= t;\n\t\t\t}\n\t\t\tif (des_setkey((char *)keyblock.b))\n\t\t\t\treturn (NULL);\n\t\t}\n\n\t\t*encp++ = *setting++;\n\n\t\t/* get iteration count */\n\t\tnum_iter = 0;\n\t\tfor (i = 4; --i >= 0; ) {\n\t\t\tif ((t = (unsigned char)setting[i]) == '\\0')\n\t\t\t\tt = '.';\n\t\t\tencp[i] = t;\n\t\t\tnum_iter = (num_iter<<6) | a64toi[t];\n\t\t}\n\t\tsetting += 4;\n\t\tencp += 4;\n\t\tsalt_size = 4;\n\t\tbreak;\n\tdefault:\n\t\tnum_iter = 25;\n\t\tsalt_size = 2;\n\t}\n\n\tsalt = 0;\n\tfor (i = salt_size; --i >= 0; ) {\n\t\tif ((t = (unsigned char)setting[i]) == '\\0')\n\t\t\tt = '.';\n\t\tencp[i] = t;\n\t\tsalt = (salt<<6) | a64toi[t];\n\t}\n\tencp += salt_size;\n\tif (des_cipher((char *)&constdatablock, (char *)&rsltblock,\n\t    salt, num_iter))\n\t\treturn (NULL);\n\n\t/*\n\t * Encode the 64 cipher bits as 11 ascii characters.\n\t */\n\ti = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];\n\tencp[3] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[2] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[1] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[0] = itoa64[i];\t\tencp += 4;\n\ti = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];\n\tencp[3] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[2] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[1] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[0] = itoa64[i];\t\tencp += 4;\n\ti = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;\n\tencp[2] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[1] = itoa64[i&0x3f];\ti >>= 6;\n\tencp[0] = itoa64[i];\n\n\tencp[3] = 0;\n\n\treturn (cryptresult);\n}\n\n\n/*\n * The Key Schedule, filled in by des_setkey() or setkey().\n */\n#define\tKS_SIZE\t16\nstatic C_block\tKS[KS_SIZE];\n\n/*\n * Set up the key schedule from the key.\n */\nint\ndes_setkey(key)\n\tregister const char *key;\n{\n\tregister DCL_BLOCK(K, K0, K1);\n\tregister C_block *ptabp;\n\tregister int i;\n\tstatic int des_ready = 0;\n\n\tif (!des_ready) {\n\t\tinit_des();\n\t\tdes_ready = 1;\n\t}\n\n\tPERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);\n\tkey = (char *)&KS[0];\n\tSTORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);\n\tfor (i = 1; i < 16; i++) {\n\t\tkey += sizeof(C_block);\n\t\tSTORE(K,K0,K1,*(C_block *)key);\n\t\tptabp = (C_block *)PC2ROT[Rotates[i]-1];\n\t\tPERM6464(K,K0,K1,(unsigned char *)key,ptabp);\n\t\tSTORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);\n\t}\n\treturn (0);\n}\n\n/*\n * Encrypt (or decrypt if num_iter < 0) the 8 chars at \"in\" with abs(num_iter)\n * iterations of DES, using the the given 24-bit salt and the pre-computed key\n * schedule, and store the resulting 8 chars at \"out\" (in == out is permitted).\n *\n * NOTE: the performance of this routine is critically dependent on your\n * compiler and machine architecture.\n */\nint\ndes_cipher(in, out, salt, num_iter)\n\tconst char *in;\n\tchar *out;\n\tlong salt;\n\tint num_iter;\n{\n\t/* variables that we want in registers, most important first */\n#if defined(pdp11)\n\tregister int j;\n#endif\n\tregister long L0, L1, R0, R1, k;\n\tregister C_block *kp;\n\tregister int ks_inc, loop_count;\n\tC_block B;\n\n\tL0 = salt;\n\tTO_SIX_BIT(salt, L0);\t/* convert to 4*(6+2) format */\n\n#if defined(vax) || defined(pdp11)\n\tsalt = ~salt;\t/* \"x &~ y\" is faster than \"x & y\". */\n#define\tSALT (~salt)\n#else\n#define\tSALT salt\n#endif\n\n#if defined(MUST_ALIGN)\n\tB.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];\n\tB.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];\n\tLOAD(L,L0,L1,B);\n#else\n\tLOAD(L,L0,L1,*(C_block *)in);\n#endif\n\tLOADREG(R,R0,R1,L,L0,L1);\n\tL0 &= 0x55555555L;\n\tL1 &= 0x55555555L;\n\tL0 = (L0 << 1) | L1;\t/* L0 is the even-numbered input bits */\n\tR0 &= 0xaaaaaaaaL;\n\tR1 = (R1 >> 1) & 0x55555555L;\n\tL1 = R0 | R1;\t\t/* L1 is the odd-numbered input bits */\n\tSTORE(L,L0,L1,B);\n\tPERM3264(L,L0,L1,B.b,  (C_block *)IE3264);\t/* even bits */\n\tPERM3264(R,R0,R1,B.b+4,(C_block *)IE3264);\t/* odd bits */\n\n\tif (num_iter >= 0)\n\t{\t\t/* encryption */\n\t\tkp = &KS[0];\n\t\tks_inc  = sizeof(*kp);\n\t}\n\telse\n\t{\t\t/* decryption */\n\t\tnum_iter = -num_iter;\n\t\tkp = &KS[KS_SIZE-1];\n\t\tks_inc  = -sizeof(*kp);\n\t}\n\n\twhile (--num_iter >= 0) {\n\t\tloop_count = 8;\n\t\tdo {\n\n#define\tSPTAB(t, i)\t(*(long *)((unsigned char *)t + i*(sizeof(long)/4)))\n#if defined(gould)\n\t\t\t/* use this if B.b[i] is evaluated just once ... */\n#define\tDOXOR(x,y,i)\tx^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);\n#else\n#if defined(pdp11)\n\t\t\t/* use this if your \"long\" int indexing is slow */\n#define\tDOXOR(x,y,i)\tj=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);\n#else\n\t\t\t/* use this if \"k\" is allocated to a register ... */\n#define\tDOXOR(x,y,i)\tk=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);\n#endif\n#endif\n\n#define\tCRUNCH(p0, p1, q0, q1)\t\\\n\t\t\tk = (q0 ^ q1) & SALT;\t\\\n\t\t\tB.b32.i0 = k ^ q0 ^ kp->b32.i0;\t\t\\\n\t\t\tB.b32.i1 = k ^ q1 ^ kp->b32.i1;\t\t\\\n\t\t\tkp = (C_block *)((char *)kp+ks_inc);\t\\\n\t\t\t\t\t\t\t\\\n\t\t\tDOXOR(p0, p1, 0);\t\t\\\n\t\t\tDOXOR(p0, p1, 1);\t\t\\\n\t\t\tDOXOR(p0, p1, 2);\t\t\\\n\t\t\tDOXOR(p0, p1, 3);\t\t\\\n\t\t\tDOXOR(p0, p1, 4);\t\t\\\n\t\t\tDOXOR(p0, p1, 5);\t\t\\\n\t\t\tDOXOR(p0, p1, 6);\t\t\\\n\t\t\tDOXOR(p0, p1, 7);\n\n\t\t\tCRUNCH(L0, L1, R0, R1);\n\t\t\tCRUNCH(R0, R1, L0, L1);\n\t\t} while (--loop_count != 0);\n\t\tkp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));\n\n\n\t\t/* swap L and R */\n\t\tL0 ^= R0;  L1 ^= R1;\n\t\tR0 ^= L0;  R1 ^= L1;\n\t\tL0 ^= R0;  L1 ^= R1;\n\t}\n\n\t/* store the encrypted (or decrypted) result */\n\tL0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);\n\tL1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);\n\tSTORE(L,L0,L1,B);\n\tPERM6464(L,L0,L1,B.b, (C_block *)CF6464);\n#if defined(MUST_ALIGN)\n\tSTORE(L,L0,L1,B);\n\tout[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];\n\tout[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];\n#else\n\tSTORE(L,L0,L1,*(C_block *)out);\n#endif\n\treturn (0);\n}\n\n\n/*\n * Initialize various tables.  This need only be done once.  It could even be\n * done at compile time, if the compiler were capable of that sort of thing.\n */\nSTATIC void\ninit_des()\n{\n\tregister int i, j;\n\tregister long k;\n\tregister int tableno;\n\tstatic unsigned char perm[64], tmp32[32];\t/* \"static\" for speed */\n\n\t/*\n\t * table that converts chars \"./0-9A-Za-z\"to integers 0-63.\n\t */\n\tfor (i = 0; i < 64; i++)\n\t\ta64toi[itoa64[i]] = i;\n\n\t/*\n\t * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.\n\t */\n\tfor (i = 0; i < 64; i++)\n\t\tperm[i] = 0;\n\tfor (i = 0; i < 64; i++) {\n\t\tif ((k = PC2[i]) == 0)\n\t\t\tcontinue;\n\t\tk += Rotates[0]-1;\n\t\tif ((k%28) < Rotates[0]) k -= 28;\n\t\tk = PC1[k];\n\t\tif (k > 0) {\n\t\t\tk--;\n\t\t\tk = (k|07) - (k&07);\n\t\t\tk++;\n\t\t}\n\t\tperm[i] = k;\n\t}\n#ifdef DEBUG\n\tprtab(\"pc1tab\", perm, 8);\n#endif\n\tinit_perm(PC1ROT, perm, 8, 8);\n\n\t/*\n\t * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.\n\t */\n\tfor (j = 0; j < 2; j++) {\n\t\tunsigned char pc2inv[64];\n\t\tfor (i = 0; i < 64; i++)\n\t\t\tperm[i] = pc2inv[i] = 0;\n\t\tfor (i = 0; i < 64; i++) {\n\t\t\tif ((k = PC2[i]) == 0)\n\t\t\t\tcontinue;\n\t\t\tpc2inv[k-1] = i+1;\n\t\t}\n\t\tfor (i = 0; i < 64; i++) {\n\t\t\tif ((k = PC2[i]) == 0)\n\t\t\t\tcontinue;\n\t\t\tk += j;\n\t\t\tif ((k%28) <= j) k -= 28;\n\t\t\tperm[i] = pc2inv[k];\n\t\t}\n#ifdef DEBUG\n\t\tprtab(\"pc2tab\", perm, 8);\n#endif\n\t\tinit_perm(PC2ROT[j], perm, 8, 8);\n\t}\n\n\t/*\n\t * Bit reverse, then initial permutation, then expansion.\n\t */\n\tfor (i = 0; i < 8; i++) {\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tk = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];\n\t\t\tif (k > 32)\n\t\t\t\tk -= 32;\n\t\t\telse if (k > 0)\n\t\t\t\tk--;\n\t\t\tif (k > 0) {\n\t\t\t\tk--;\n\t\t\t\tk = (k|07) - (k&07);\n\t\t\t\tk++;\n\t\t\t}\n\t\t\tperm[i*8+j] = k;\n\t\t}\n\t}\n#ifdef DEBUG\n\tprtab(\"ietab\", perm, 8);\n#endif\n\tinit_perm(IE3264, perm, 4, 8);\n\n\t/*\n\t * Compression, then final permutation, then bit reverse.\n\t */\n\tfor (i = 0; i < 64; i++) {\n\t\tk = IP[CIFP[i]-1];\n\t\tif (k > 0) {\n\t\t\tk--;\n\t\t\tk = (k|07) - (k&07);\n\t\t\tk++;\n\t\t}\n\t\tperm[k-1] = i+1;\n\t}\n#ifdef DEBUG\n\tprtab(\"cftab\", perm, 8);\n#endif\n\tinit_perm(CF6464, perm, 8, 8);\n\n\t/*\n\t * SPE table\n\t */\n\tfor (i = 0; i < 48; i++)\n\t\tperm[i] = P32Tr[ExpandTr[i]-1];\n\tfor (tableno = 0; tableno < 8; tableno++) {\n\t\tfor (j = 0; j < 64; j++)  {\n\t\t\tk = (((j >> 0) &01) << 5)|\n\t\t\t    (((j >> 1) &01) << 3)|\n\t\t\t    (((j >> 2) &01) << 2)|\n\t\t\t    (((j >> 3) &01) << 1)|\n\t\t\t    (((j >> 4) &01) << 0)|\n\t\t\t    (((j >> 5) &01) << 4);\n\t\t\tk = S[tableno][k];\n\t\t\tk = (((k >> 3)&01) << 0)|\n\t\t\t    (((k >> 2)&01) << 1)|\n\t\t\t    (((k >> 1)&01) << 2)|\n\t\t\t    (((k >> 0)&01) << 3);\n\t\t\tfor (i = 0; i < 32; i++)\n\t\t\t\ttmp32[i] = 0;\n\t\t\tfor (i = 0; i < 4; i++)\n\t\t\t\ttmp32[4 * tableno + i] = (k >> i) & 01;\n\t\t\tk = 0;\n\t\t\tfor (i = 24; --i >= 0; )\n\t\t\t\tk = (k<<1) | tmp32[perm[i]-1];\n\t\t\tTO_SIX_BIT(SPE[0][tableno][j], k);\n\t\t\tk = 0;\n\t\t\tfor (i = 24; --i >= 0; )\n\t\t\t\tk = (k<<1) | tmp32[perm[i+24]-1];\n\t\t\tTO_SIX_BIT(SPE[1][tableno][j], k);\n\t\t}\n\t}\n}\n\n/*\n * Initialize \"perm\" to represent transformation \"p\", which rearranges\n * (perhaps with expansion and/or contraction) one packed array of bits\n * (of size \"chars_in\" characters) into another array (of size \"chars_out\"\n * characters).\n *\n * \"perm\" must be all-zeroes on entry to this routine.\n */\nSTATIC void\ninit_perm(perm, p, chars_in, chars_out)\n\tC_block perm[64/CHUNKBITS][1<<CHUNKBITS];\n\tunsigned char p[64];\n\tint chars_in, chars_out;\n{\n\tregister int i, j, k, l;\n\n\tfor (k = 0; k < chars_out*8; k++) {\t/* each output bit position */\n\t\tl = p[k] - 1;\t\t/* where this bit comes from */\n\t\tif (l < 0)\n\t\t\tcontinue;\t/* output bit is always 0 */\n\t\ti = l>>LGCHUNKBITS;\t/* which chunk this bit comes from */\n\t\tl = 1<<(l&(CHUNKBITS-1));\t/* mask for this bit */\n\t\tfor (j = 0; j < (1<<CHUNKBITS); j++) {\t/* each chunk value */\n\t\t\tif ((j & l) != 0)\n\t\t\t\tperm[i][j].b[k>>3] |= 1<<(k&07);\n\t\t}\n\t}\n}\n\n/*\n * \"setkey\" routine (for backwards compatibility)\n */\nint\nsetkey(key)\n\tregister const char *key;\n{\n\tregister int i, j, k;\n\tC_block keyblock;\n\n\tfor (i = 0; i < 8; i++) {\n\t\tk = 0;\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tk <<= 1;\n\t\t\tk |= (unsigned char)*key++;\n\t\t}\n\t\tkeyblock.b[i] = k;\n\t}\n\treturn (des_setkey((char *)keyblock.b));\n}\n\n/*\n * \"encrypt\" routine (for backwards compatibility)\n */\nint\nencrypt(block, flag)\n\tregister char *block;\n\tint flag;\n{\n\tregister int i, j, k;\n\tC_block cblock;\n\n\tfor (i = 0; i < 8; i++) {\n\t\tk = 0;\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tk <<= 1;\n\t\t\tk |= (unsigned char)*block++;\n\t\t}\n\t\tcblock.b[i] = k;\n\t}\n\tif (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))\n\t\treturn (1);\n\tfor (i = 7; i >= 0; i--) {\n\t\tk = cblock.b[i];\n\t\tfor (j = 7; j >= 0; j--) {\n\t\t\t*--block = k&01;\n\t\t\tk >>= 1;\n\t\t}\n\t}\n\treturn (0);\n}\n\n#ifdef DEBUG\nSTATIC void\nprtab(s, t, num_rows)\n\tchar *s;\n\tunsigned char *t;\n\tint num_rows;\n{\n\tregister int i, j;\n\n\t(void)printf(\"%s:\\n\", s);\n\tfor (i = 0; i < num_rows; i++) {\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\t (void)printf(\"%3d\", t[i*8+j]);\n\t\t}\n\t\t(void)printf(\"\\n\");\n\t}\n\t(void)printf(\"\\n\");\n}\n#endif\n"
  },
  {
    "path": "missing/dup2.c",
    "content": "/*\n * Public domain dup2() lookalike\n * by Curtis Jackson @ AT&T Technologies, Burlington, NC\n * electronic address:  burl!rcj\n *\n * dup2 performs the following functions:\n *\n * Check to make sure that fd1 is a valid open file descriptor.\n * Check to see if fd2 is already open; if so, close it.\n * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd.\n * Return fd2 if all went well; return BADEXIT otherwise.\n */\n\n#include \"config.h\"\n\n#if defined(HAVE_FCNTL)\n# include <fcntl.h>\n#endif\n\n#if !defined(HAVE_FCNTL) || !defined(F_DUPFD)\n# include <errno.h>\n#endif\n\n#define BADEXIT -1\n\nint\ndup2(fd1, fd2)\nint fd1, fd2;\n{\n#if defined(HAVE_FCNTL) && defined(F_DUPFD)\n\tif (fd1 != fd2) {\n#ifdef F_GETFL\n\t\tif (fcntl(fd1, F_GETFL) < 0)\n\t\t\treturn BADEXIT;\n\t\tif (fcntl(fd2, F_GETFL) >= 0)\n\t\t\tclose(fd2);\n#else\n\t\tclose(fd2);\n#endif\n\t\tif (fcntl(fd1, F_DUPFD, fd2) < 0)\n\t\t\treturn BADEXIT;\n\t}\n\treturn fd2;\n#else\n\textern int errno;\n\tint i, fd, fds[256];\n\n\tif (fd1 == fd2) return 0;\n\tclose(fd2);\n\tfor (i=0; i<256; i++) {\n\t\tfd = fds[i] = dup(fd1);\n\t\tif (fd == fd2) break;\n\t}\n\twhile (i) {\n\t    \tclose(fds[i--]);\n\t}\n\tif (fd == fd2) return 0;\n\terrno = EMFILE;\n\treturn BADEXIT;\n#endif\n}\n"
  },
  {
    "path": "missing/erf.c",
    "content": "/* erf.c  - public domain implementation of error function erf(3m)\n\nreference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten\n            (New Algorithm handbook in C language) (Gijyutsu hyouron\n            sha, Tokyo, 1991) p.227 [in Japanese]                 */\n#include <stdio.h>\n#include <math.h>\n\n#ifdef _WIN32\n# include <float.h>\n# if !defined __MINGW32__ || defined __NO_ISOCEXT\n#  ifndef isnan\n#   define isnan(x) _isnan(x)\n#  endif\n#  ifndef isinf\n#   define isinf(x) (!_finite(x) && !_isnan(x))\n#  endif\n#  ifndef finite\n#   define finite(x) _finite(x)\n#  endif\n# endif\n#endif\n\nstatic double q_gamma(double, double, double);\n\n/* Incomplete gamma function\n   1 / Gamma(a) * Int_0^x exp(-t) t^(a-1) dt  */\nstatic double p_gamma(a, x, loggamma_a)\n    double a, x, loggamma_a;\n{\n    int k;\n    double result, term, previous;\n\n    if (x >= 1 + a) return 1 - q_gamma(a, x, loggamma_a);\n    if (x == 0)     return 0;\n    result = term = exp(a * log(x) - x - loggamma_a) / a;\n    for (k = 1; k < 1000; k++) {\n        term *= x / (a + k);\n        previous = result;  result += term;\n        if (result == previous) return result;\n    }\n    fprintf(stderr, \"erf.c:%d:p_gamma() could not converge.\", __LINE__);\n    return result;\n}\n\n/* Incomplete gamma function\n   1 / Gamma(a) * Int_x^inf exp(-t) t^(a-1) dt  */\nstatic double q_gamma(a, x, loggamma_a)\n    double a, x, loggamma_a;\n{\n    int k;\n    double result, w, temp, previous;\n    double la = 1, lb = 1 + x - a;  /* Laguerre polynomial */\n\n    if (x < 1 + a) return 1 - p_gamma(a, x, loggamma_a);\n    w = exp(a * log(x) - x - loggamma_a);\n    result = w / lb;\n    for (k = 2; k < 1000; k++) {\n        temp = ((k - 1 - a) * (lb - la) + (k + x) * lb) / k;\n        la = lb;  lb = temp;\n        w *= (k - 1 - a) / k;\n        temp = w / (la * lb);\n        previous = result;  result += temp;\n        if (result == previous) return result;\n    }\n    fprintf(stderr, \"erf.c:%d:q_gamma() could not converge.\", __LINE__);\n    return result;\n}\n\n#define LOG_PI_OVER_2 0.572364942924700087071713675675 /* log_e(PI)/2 */\n\ndouble erf(x)\n    double x;\n{\n    if (!finite(x)) {\n        if (isnan(x)) return x;      /* erf(NaN)   = NaN   */\n        return (x>0 ? 1.0 : -1.0);   /* erf(+-inf) = +-1.0 */\n    }\n    if (x >= 0) return   p_gamma(0.5, x * x, LOG_PI_OVER_2);\n    else        return - p_gamma(0.5, x * x, LOG_PI_OVER_2);\n}\n\ndouble erfc(x)\n    double x;\n{\n    if (!finite(x)) {\n        if (isnan(x)) return x;      /* erfc(NaN)   = NaN      */\n        return (x>0 ? 0.0 : 2.0);    /* erfc(+-inf) = 0.0, 2.0 */\n    }\n    if (x >= 0) return  q_gamma(0.5, x * x, LOG_PI_OVER_2);\n    else        return  1 + p_gamma(0.5, x * x, LOG_PI_OVER_2);\n}\n"
  },
  {
    "path": "missing/file.h",
    "content": "/* This is file FILE.H */\n\n#ifndef _FILE_H_\n#define _FILE_H_\n\n#include <fcntl.h>\n\n#ifndef L_SET\n# define L_SET  0       /* seek from beginning.  */\n# define L_CURR\t1       /* seek from current position.  */\n# define L_INCR\t1       /* ditto.  */\n# define L_XTND 2       /* seek from end.  */\n#endif\n\n#ifndef R_OK\n# define R_OK  4        /* test whether readable.  */\n# define W_OK  2        /* test whether writable.  */\n# define X_OK  1        /* test whether execubale. */\n# define F_OK  0        /* test whether exist.  */\n#endif\n\n#endif\n"
  },
  {
    "path": "missing/fileblocks.c",
    "content": "/* dummy for autoconf */\n"
  },
  {
    "path": "missing/finite.c",
    "content": "/* public domain rewrite of finite(3) */\n\nint\nfinite(n)\n    double n;\n{\n    return !isnan(n) && !isinf(n);\n}\n"
  },
  {
    "path": "missing/flock.c",
    "content": "#include \"config.h\"\n\n#if defined _WIN32\n#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H\n\n/* These are the flock() constants.  Since this sytems doesn't have\n   flock(), the values of the constants are probably not available.\n*/\n# ifndef LOCK_SH\n#  define LOCK_SH 1\n# endif\n# ifndef LOCK_EX\n#  define LOCK_EX 2\n# endif\n# ifndef LOCK_NB\n#  define LOCK_NB 4\n# endif\n# ifndef LOCK_UN\n#  define LOCK_UN 8\n# endif\n\n#include <fcntl.h>\n#include <unistd.h>\n#include <errno.h>\n\nint\nflock(fd, operation)\n    int fd;\n    int operation;\n{\n    struct flock lock;\n \n    switch (operation & ~LOCK_NB) {\n    case LOCK_SH:\n\tlock.l_type = F_RDLCK;\n\tbreak;\n    case LOCK_EX:\n\tlock.l_type = F_WRLCK;\n\tbreak;\n    case LOCK_UN:\n\tlock.l_type = F_UNLCK;\n\tbreak;\n    default:\n\terrno = EINVAL;\n\treturn -1;\n    }\n    lock.l_whence = SEEK_SET;\n    lock.l_start = lock.l_len = 0L;\n \n    return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);\n}\n\n#elif defined(HAVE_LOCKF)\n\n#include <unistd.h>\n#include <errno.h>\n\n/*  Emulate flock() with lockf() or fcntl().  This is just to increase\n    portability of scripts.  The calls might not be completely\n    interchangeable.  What's really needed is a good file\n    locking module.\n*/\n\n# ifndef F_ULOCK\n#  define F_ULOCK\t0\t/* Unlock a previously locked region */\n# endif\n# ifndef F_LOCK\n#  define F_LOCK\t1\t/* Lock a region for exclusive use */\n# endif\n# ifndef F_TLOCK\n#  define F_TLOCK\t2\t/* Test and lock a region for exclusive use */\n# endif\n# ifndef F_TEST\n#  define F_TEST\t3\t/* Test a region for other processes locks */\n# endif\n\n/* These are the flock() constants.  Since this sytems doesn't have\n   flock(), the values of the constants are probably not available.\n*/\n# ifndef LOCK_SH\n#  define LOCK_SH 1\n# endif\n# ifndef LOCK_EX\n#  define LOCK_EX 2\n# endif\n# ifndef LOCK_NB\n#  define LOCK_NB 4\n# endif\n# ifndef LOCK_UN\n#  define LOCK_UN 8\n# endif\n\nint\nflock(fd, operation)\n    int fd;\n    int operation;\n{\n    switch (operation) {\n\n\t/* LOCK_SH - get a shared lock */\n      case LOCK_SH:\n        rb_notimplement();\n        return -1;\n\t/* LOCK_EX - get an exclusive lock */\n      case LOCK_EX:\n\treturn lockf (fd, F_LOCK, 0);\n\n\t/* LOCK_SH|LOCK_NB - get a non-blocking shared lock */\n      case LOCK_SH|LOCK_NB:\n        rb_notimplement();\n        return -1;\n\t/* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */\n      case LOCK_EX|LOCK_NB:\n\treturn lockf (fd, F_TLOCK, 0);\n\n\t/* LOCK_UN - unlock */\n      case LOCK_UN:\n\treturn lockf (fd, F_ULOCK, 0);\n\n\t/* Default - can't decipher operation */\n      default:\n\terrno = EINVAL;\n        return -1;\n    }\n}\n#else\nint\nflock(fd, operation)\n    int fd;\n    int operation;\n{\n    rb_notimplement();\n    return -1;\n}\n#endif\n"
  },
  {
    "path": "missing/hypot.c",
    "content": "/* public domain rewrite of hypot */\n\n#include <math.h>\n\ndouble hypot(x,y)\n    double x, y;\n{\n    if (x < 0) x = -x;\n    if (y < 0) y = -y;\n    if (x < y) {\n\tdouble tmp = x;\n\tx = y; y = tmp;\n    }\n    if (y == 0.0) return x;\n    y /= x;\n    return x * sqrt(1.0+y*y);\n}\n"
  },
  {
    "path": "missing/isinf.c",
    "content": "/* public domain rewrite of isinf(3) */\n\n#ifdef __osf__\n\n#define _IEEE 1\n#include <nan.h>\n\nint\nisinf(n)\n    double n;\n{\n    if (IsNANorINF(n) && IsINF(n)) {\n\treturn 1;\n    }\n    else {\n\treturn 0;\n    }\n}\n\n#else\n\n#include \"config.h\"\n\n#if defined(HAVE_FINITE) && defined(HAVE_ISNAN)\n\n#include <math.h>\n#ifdef HAVE_IEEEFP_H\n#include <ieeefp.h>\n#endif\n\n/* \n * isinf may be provided only as a macro.\n * ex. HP-UX, Solaris 10\n * http://www.gnu.org/software/automake/manual/autoconf/Function-Portability.html\n */\n#ifndef isinf\nint\nisinf(n)\n    double n;\n{\n    return (!finite(n) && !isnan(n));\n}\n#endif\n\n#else\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#else\n# include <strings.h>\n#endif\n\nstatic double zero()\t{ return 0.0; }\nstatic double one()\t{ return 1.0; }\nstatic double inf()\t{ return one() / zero(); }\n\nint\nisinf(n)\n    double n;\n{\n    static double pinf = 0.0;\n    static double ninf = 0.0;\n\n    if (pinf == 0.0) {\n\tpinf = inf();\n\tninf = -pinf;\n    }\n    return memcmp(&n, &pinf, sizeof n) == 0\n\t|| memcmp(&n, &ninf, sizeof n) == 0;\n}\n#endif\n#endif\n"
  },
  {
    "path": "missing/isnan.c",
    "content": "/* public domain rewrite of isnan(3) */\n\nstatic int double_ne();\n\nint\nisnan(n)\n    double n;\n{\n    return double_ne(n, n);\n}\n\nstatic int\ndouble_ne(n1, n2)\n    double n1, n2;\n{\n    return n1 != n2;\n}\n"
  },
  {
    "path": "missing/memcmp.c",
    "content": "/* public domain rewrite of memcmp(3) */\n\nint\nmemcmp(s1,s2,len)\n    char *s1;\n    char *s2;\n    register int len;\n{\n    register unsigned char *a = (unsigned char*)s1;\n    register unsigned char *b = (unsigned char*)s2;\n    register int tmp;\n\n    while (len--) {\n\tif (tmp = *a++ - *b++)\n\t    return tmp;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "missing/memmove.c",
    "content": "/* public domain rewrite of memcmp(3) */\n\nvoid *\nmemmove (d, s, n)\n    void *d, *s;\n    int n;\n{\n    char *dst = d;\n    char *src = s;\n    void *ret = dst;\n\n    if (src < dst) {\n\tsrc += n;\n\tdst += n;\n\twhile (n--)\n\t    *--dst = *--src;\n    }\n    else if (dst < src)\n\twhile (n--)\n\t    *dst++ = *src++;\n    return ret;\n}\n"
  },
  {
    "path": "missing/os2.c",
    "content": "/* os/2 compatibility functions -- follows Ruby's license */\n\n#include \"ruby.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <fcntl.h>\n#include <process.h>\n#include <limits.h>\n#include <errno.h>\n\n#define INCL_DOS\n#include <os2.h>\n\nint\nchown(char *path, int owner, int group)\n{\n\treturn 0;\n}\n\nint\nlink(char *from, char *to)\n{\n\treturn -1;\n}\n\ntypedef char* CHARP;\n\nint\ndo_spawn(cmd)\nchar *cmd;\n{\n    register char **a;\n    register char *s;\n    char **argv;\n    char *shell, *sw, *cmd2;\n    int status;\n\n    if ((shell = getenv(\"RUBYSHELL\")) != NULL && *shell != '\\0') {\n\ts = shell;\n\tdo\n\t    *s = isupper(*s) ? tolower(*s) : *s;\n\twhile (*++s);\n\tif (strstr(shell, \"cmd\") || strstr(shell, \"4os2\"))\n\t    sw = \"/c\";\n\telse\n\t    sw = \"-c\";\n    } else if ((shell = getenv(\"SHELL\")) != NULL && *shell != '\\0') {\n\ts = shell;\n\tdo\n\t    *s = isupper(*s) ? tolower(*s) : *s;\n\twhile (*++s);\n\tif (strstr(shell, \"cmd\") || strstr(shell, \"4os2\"))\n\t    sw = \"/c\";\n\telse\n\t    sw = \"-c\";\n    } else if ((shell = getenv(\"COMSPEC\")) != NULL && *shell != '\\0') {\n\ts = shell;\n\tdo\n\t    *s = isupper(*s) ? tolower(*s) : *s;\n\twhile (*++s);\n\tif (strstr(shell, \"cmd\") || strstr(shell, \"4os2\"))\n\t    sw = \"/c\";\n\telse\n\t    sw = \"-c\";\n    }\n    /* see if there are shell metacharacters in it */\n    /*SUPPRESS 530*/\n    /*    for (s = cmd; *s && isalpha(*s); s++) ;\n    if (*s == '=')\n    goto doshell; */\n    for (s = cmd; *s; s++) {\n\tif (*sw == '-' && *s != ' ' && \n\t    !isalpha(*s) && index(\"$&*(){}[]'\\\";\\\\|?<>~`\\n\",*s)) {\n\t    if (*s == '\\n' && !s[1]) {\n\t\t*s = '\\0';\n\t\tbreak;\n\t    }\n\t    goto doshell;\n\t} else if (*sw == '/' && *s != ' ' && \n\t    !isalpha(*s) && index(\"^()<>|&\\n\",*s)) {\n\t    if (*s == '\\n' && !s[1]) {\n\t\t*s = '\\0';\n\t\tbreak;\n\t    }\n\t  doshell:\n\t    status = spawnlp(P_WAIT,shell,shell,sw,cmd,(char*)NULL);\n\t    return status;\n\t}\n    }\n    argv = ALLOC_N(CHARP,(strlen(cmd) / 2 + 2));\n    cmd2 = ALLOC_N(char, (strlen(cmd) + 1));\n    strcpy(cmd2, cmd);\n    a = argv;\n    for (s = cmd2; *s;) {\n\twhile (*s && isspace(*s)) s++;\n\tif (*s)\n\t    *(a++) = s;\n\twhile (*s && !isspace(*s)) s++;\n\tif (*s)\n\t    *s++ = '\\0';\n    }\n    *a = NULL;\n    if (argv[0]) {\n\tif ((status = spawnvp(P_WAIT, argv[0], argv)) == -1) {\n\t    free(argv);\n\t    free(cmd2);\n\t    return -1;\n\t}\n    }\n    free(cmd2);\n    free(argv);\n    return status;\n}\n"
  },
  {
    "path": "missing/strcasecmp.c",
    "content": "/* public domain rewrite of strcasecmp(3) */\n\n#include <ctype.h>\n\nint\nstrcasecmp(p1, p2)\n    char *p1, *p2;\n{\n    while (*p1 && *p2) {\n\tif (toupper(*p1) != toupper(*p2))\n\t    return toupper(*p1) - toupper(*p2);\n\tp1++;\n\tp2++;\n    }\n    return strlen(p1) - strlen(p2);\n}\n"
  },
  {
    "path": "missing/strchr.c",
    "content": "/* public domain rewrite of strchr(3) and strrchr(3) */\n\nchar *\nstrchr(s, c)\n    char *s;\n    int c;\n{\n    if (c == 0) return s + strlen(s);\n    while (*s) {\n\tif (*s == c)\n\t    return s;\n\ts++;\n    }\n    return 0;\n}\n\nchar *\nstrrchr(s, c)\n    char *s;\n    int c;\n{\n    char *save;\n\n    if (c == 0) return s + strlen(s);\n    save = 0;\n    while (*s) {\n\tif (*s == c)\n\t    save = s;\n\ts++;\n    }\n    return save;\n}\n"
  },
  {
    "path": "missing/strerror.c",
    "content": "/* public domain rewrite of strerror(3) */\n\nextern int sys_nerr;\nextern char *sys_errlist[];\n\nstatic char msg[50];\n\nchar *\nstrerror(error)\n    int error;\n{\n    if (error <= sys_nerr && error > 0) {\n\treturn sys_errlist[error];\n    }\n    sprintf(msg, \"Unknown error (%d)\", error);\n    return msg;\n}\n"
  },
  {
    "path": "missing/strftime.c",
    "content": "/*\n * strftime.c\n *\n * Public-domain implementation of ANSI C library routine.\n *\n * It's written in old-style C for maximal portability.\n * However, since I'm used to prototypes, I've included them too.\n *\n * If you want stuff in the System V ascftime routine, add the SYSV_EXT define.\n * For extensions from SunOS, add SUNOS_EXT.\n * For stuff needed to implement the P1003.2 date command, add POSIX2_DATE.\n * For VMS dates, add VMS_EXT.\n * For a an RFC822 time format, add MAILHEADER_EXT.\n * For ISO week years, add ISO_DATE_EXT.\n * For complete POSIX semantics, add POSIX_SEMANTICS.\n *\n * The code for %c, %x, and %X now follows the 1003.2 specification for\n * the POSIX locale.\n * This version ignores LOCALE information.\n * It also doesn't worry about multi-byte characters.\n * So there.\n *\n * This file is also shipped with GAWK (GNU Awk), gawk specific bits of\n * code are included if GAWK is defined.\n *\n * Arnold Robbins\n * January, February, March, 1991\n * Updated March, April 1992\n * Updated April, 1993\n * Updated February, 1994\n * Updated May, 1994\n * Updated January, 1995\n * Updated September, 1995\n * Updated January, 1996\n *\n * Fixes from ado@elsie.nci.nih.gov\n * February 1991, May 1992\n * Fixes from Tor Lillqvist tml@tik.vtt.fi\n * May, 1993\n * Further fixes from ado@elsie.nci.nih.gov\n * February 1994\n * %z code from chip@chinacat.unicom.com\n * Applied September 1995\n * %V code fixed (again) and %G, %g added,\n * January 1996\n */\n\n#include \"config.h\"\n\n#ifndef GAWK\n#include <stdio.h>\n#include <ctype.h>\n#include <string.h>\n#include <time.h>\n#endif\n#if defined(TM_IN_SYS_TIME) || !defined(GAWK) && !defined(_WIN32_WCE)\n#include <sys/types.h>\n#include <sys/time.h>\n#endif\n\n/* defaults: season to taste */\n#define SYSV_EXT\t1\t/* stuff in System V ascftime routine */\n#define SUNOS_EXT\t1\t/* stuff in SunOS strftime routine */\n#define POSIX2_DATE\t1\t/* stuff in Posix 1003.2 date command */\n#define VMS_EXT\t\t1\t/* include %v for VMS date format */\n#define MAILHEADER_EXT\t1\t/* add %z for HHMM format */\n#define ISO_DATE_EXT\t1\t/* %G and %g for year of ISO week */\n#ifndef GAWK\n#define POSIX_SEMANTICS\t1\t/* call tzset() if TZ changes */\n#endif\n\n#if defined(ISO_DATE_EXT)\n#if ! defined(POSIX2_DATE)\n#define POSIX2_DATE\t1\n#endif\n#endif\n\n#if defined(POSIX2_DATE)\n#if ! defined(SYSV_EXT)\n#define SYSV_EXT\t1\n#endif\n#if ! defined(SUNOS_EXT)\n#define SUNOS_EXT\t1\n#endif\n#endif\n\n#if defined(POSIX2_DATE)\n#define adddecl(stuff)\tstuff\n#else\n#define adddecl(stuff)\n#endif\n\n#undef strchr\t/* avoid AIX weirdness */\n\n#ifndef __STDC__\n#define const\t/**/\nextern void tzset();\nstatic int weeknumber();\nadddecl(static int iso8601wknum();)\n#else\nextern void tzset(void);\nstatic int weeknumber(const struct tm *timeptr, int firstweekday);\nadddecl(static int iso8601wknum(const struct tm *timeptr);)\n#endif\n\n#ifdef STDC_HEADERS\n#include <stdlib.h>\n#include <string.h>\n#else\nextern void *malloc();\nextern void *realloc();\nextern char *getenv();\nextern char *strchr();\n#endif\n\n#define range(low, item, hi)\tmax(low, min(item, hi))\n\n#ifdef __CYGWIN__\n#define DLL_IMPORT __declspec(dllimport)\n#endif\n#ifdef __WIN32__\n#define DLL_IMPORT __declspec(dllimport)\n#endif\n#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)\nextern DLL_IMPORT char *tzname[2];\n#ifdef HAVE_DAYLIGHT\nextern DLL_IMPORT int daylight;\n#endif\n#ifdef HAVE_VAR_TIMEZONE\nextern DLL_IMPORT TYPEOF_VAR_TIMEZONE timezone;\n#endif\n#ifdef HAVE_VAR_ALTZONE\nextern DLL_IMPORT TYPEOF_VAR_ALTZONE altzone;\n#endif\n#endif\n\n#undef min\t/* just in case */\n\n/* min --- return minimum of two numbers */\n\n#ifndef __STDC__\nstatic inline int\nmin(a, b)\nint a, b;\n#else\nstatic inline int\nmin(int a, int b)\n#endif\n{\n\treturn (a < b ? a : b);\n}\n\n#undef max\t/* also, just in case */\n\n/* max --- return maximum of two numbers */\n\n#ifndef __STDC__\nstatic inline int\nmax(a, b)\nint a, b;\n#else\nstatic inline int\nmax(int a, int b)\n#endif\n{\n\treturn (a > b ? a : b);\n}\n\n/* strftime --- produce formatted time */\n\n#ifndef __STDC__\nsize_t\nstrftime(s, maxsize, format, timeptr)\nchar *s;\nsize_t maxsize;\nconst char *format;\nconst struct tm *timeptr;\n#else\nsize_t\nstrftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)\n#endif\n{\n\tchar *endp = s + maxsize;\n\tchar *start = s;\n\tauto char tbuf[100];\n\tlong off;\n\tint i, w;\n\tlong y;\n\tstatic short first = 1;\n#ifdef POSIX_SEMANTICS\n\tstatic char *savetz = NULL;\n\tstatic int savetzlen = 0;\n\tchar *tz;\n#endif /* POSIX_SEMANTICS */\n#ifndef HAVE_TM_ZONE\n#ifndef HAVE_TM_NAME\n\tstruct timeval tv;\n\tstruct timezone zone;\n#endif /* HAVE_TM_NAME */\n#endif /* HAVE_TM_ZONE */\n\n\t/* various tables, useful in North America */\n\tstatic const char *days_a[] = {\n\t\t\"Sun\", \"Mon\", \"Tue\", \"Wed\",\n\t\t\"Thu\", \"Fri\", \"Sat\",\n\t};\n\tstatic const char *days_l[] = {\n\t\t\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\",\n\t\t\"Thursday\", \"Friday\", \"Saturday\",\n\t};\n\tstatic const char *months_a[] = {\n\t\t\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n\t\t\"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\",\n\t};\n\tstatic const char *months_l[] = {\n\t\t\"January\", \"February\", \"March\", \"April\",\n\t\t\"May\", \"June\", \"July\", \"August\", \"September\",\n\t\t\"October\", \"November\", \"December\",\n\t};\n\tstatic const char *ampm[] = { \"AM\", \"PM\", };\n\n\tif (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)\n\t\treturn 0;\n\n\t/* quick check if we even need to bother */\n\tif (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)\n\t\treturn 0;\n\n#ifndef POSIX_SEMANTICS\n\tif (first) {\n\t\ttzset();\n\t\tfirst = 0;\n\t}\n#else\t/* POSIX_SEMANTICS */\n\ttz = getenv(\"TZ\");\n\tif (first) {\n\t\tif (tz != NULL) {\n\t\t\tint tzlen = strlen(tz);\n\n\t\t\tsavetz = (char *) malloc(tzlen + 1);\n\t\t\tif (savetz != NULL) {\n\t\t\t\tsavetzlen = tzlen + 1;\n\t\t\t\tstrcpy(savetz, tz);\n\t\t\t}\n\t\t}\n\t\ttzset();\n\t\tfirst = 0;\n\t}\n\t/* if we have a saved TZ, and it is different, recapture and reset */\n\tif (tz && savetz && (tz[0] != savetz[0] || strcmp(tz, savetz) != 0)) {\n\t\ti = strlen(tz) + 1;\n\t\tif (i > savetzlen) {\n\t\t\tsavetz = (char *) realloc(savetz, i);\n\t\t\tif (savetz) {\n\t\t\t\tsavetzlen = i;\n\t\t\t\tstrcpy(savetz, tz);\n\t\t\t}\n\t\t} else\n\t\t\tstrcpy(savetz, tz);\n\t\ttzset();\n\t}\n#endif\t/* POSIX_SEMANTICS */\n\n\tfor (; *format && s < endp - 1; format++) {\n\t\ttbuf[0] = '\\0';\n\t\tif (*format != '%') {\n\t\t\t*s++ = *format;\n\t\t\tcontinue;\n\t\t}\n\tagain:\n\t\tswitch (*++format) {\n\t\tcase '\\0':\n\t\t\t*s++ = '%';\n\t\t\tgoto out;\n\n\t\tcase '%':\n\t\t\t*s++ = '%';\n\t\t\tcontinue;\n\n\t\tcase 'a':\t/* abbreviated weekday name */\n\t\t\tif (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)\n\t\t\t\tstrcpy(tbuf, \"?\");\n\t\t\telse\n\t\t\t\tstrcpy(tbuf, days_a[timeptr->tm_wday]);\n\t\t\tbreak;\n\n\t\tcase 'A':\t/* full weekday name */\n\t\t\tif (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)\n\t\t\t\tstrcpy(tbuf, \"?\");\n\t\t\telse\n\t\t\t\tstrcpy(tbuf, days_l[timeptr->tm_wday]);\n\t\t\tbreak;\n\n#ifdef SYSV_EXT\n\t\tcase 'h':\t/* abbreviated month name */\n#endif\n\t\tcase 'b':\t/* abbreviated month name */\n\t\t\tif (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)\n\t\t\t\tstrcpy(tbuf, \"?\");\n\t\t\telse\n\t\t\t\tstrcpy(tbuf, months_a[timeptr->tm_mon]);\n\t\t\tbreak;\n\n\t\tcase 'B':\t/* full month name */\n\t\t\tif (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)\n\t\t\t\tstrcpy(tbuf, \"?\");\n\t\t\telse\n\t\t\t\tstrcpy(tbuf, months_l[timeptr->tm_mon]);\n\t\t\tbreak;\n\n\t\tcase 'c':\t/* appropriate date and time representation */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%a %b %e %H:%M:%S %Y\", timeptr);\n\t\t\tbreak;\n\n\t\tcase 'd':\t/* day of the month, 01 - 31 */\n\t\t\ti = range(1, timeptr->tm_mday, 31);\n\t\t\tsprintf(tbuf, \"%02d\", i);\n\t\t\tbreak;\n\n\t\tcase 'H':\t/* hour, 24-hour clock, 00 - 23 */\n\t\t\ti = range(0, timeptr->tm_hour, 23);\n\t\t\tsprintf(tbuf, \"%02d\", i);\n\t\t\tbreak;\n\n\t\tcase 'I':\t/* hour, 12-hour clock, 01 - 12 */\n\t\t\ti = range(0, timeptr->tm_hour, 23);\n\t\t\tif (i == 0)\n\t\t\t\ti = 12;\n\t\t\telse if (i > 12)\n\t\t\t\ti -= 12;\n\t\t\tsprintf(tbuf, \"%02d\", i);\n\t\t\tbreak;\n\n\t\tcase 'j':\t/* day of the year, 001 - 366 */\n\t\t\tsprintf(tbuf, \"%03d\", timeptr->tm_yday + 1);\n\t\t\tbreak;\n\n\t\tcase 'm':\t/* month, 01 - 12 */\n\t\t\ti = range(0, timeptr->tm_mon, 11);\n\t\t\tsprintf(tbuf, \"%02d\", i + 1);\n\t\t\tbreak;\n\n\t\tcase 'M':\t/* minute, 00 - 59 */\n\t\t\ti = range(0, timeptr->tm_min, 59);\n\t\t\tsprintf(tbuf, \"%02d\", i);\n\t\t\tbreak;\n\n\t\tcase 'p':\t/* am or pm based on 12-hour clock */\n\t\t\ti = range(0, timeptr->tm_hour, 23);\n\t\t\tif (i < 12)\n\t\t\t\tstrcpy(tbuf, ampm[0]);\n\t\t\telse\n\t\t\t\tstrcpy(tbuf, ampm[1]);\n\t\t\tbreak;\n\n\t\tcase 'S':\t/* second, 00 - 60 */\n\t\t\ti = range(0, timeptr->tm_sec, 60);\n\t\t\tsprintf(tbuf, \"%02d\", i);\n\t\t\tbreak;\n\n\t\tcase 'U':\t/* week of year, Sunday is first day of week */\n\t\t\tsprintf(tbuf, \"%02d\", weeknumber(timeptr, 0));\n\t\t\tbreak;\n\n\t\tcase 'w':\t/* weekday, Sunday == 0, 0 - 6 */\n\t\t\ti = range(0, timeptr->tm_wday, 6);\n\t\t\tsprintf(tbuf, \"%d\", i);\n\t\t\tbreak;\n\n\t\tcase 'W':\t/* week of year, Monday is first day of week */\n\t\t\tsprintf(tbuf, \"%02d\", weeknumber(timeptr, 1));\n\t\t\tbreak;\n\n\t\tcase 'x':\t/* appropriate date representation */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%m/%d/%y\", timeptr);\n\t\t\tbreak;\n\n\t\tcase 'X':\t/* appropriate time representation */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%H:%M:%S\", timeptr);\n\t\t\tbreak;\n\n\t\tcase 'y':\t/* year without a century, 00 - 99 */\n\t\t\ti = timeptr->tm_year % 100;\n\t\t\tsprintf(tbuf, \"%02d\", i);\n\t\t\tbreak;\n\n\t\tcase 'Y':\t/* year with century */\n\t\t\tsprintf(tbuf, \"%ld\", 1900L + timeptr->tm_year);\n\t\t\tbreak;\n\n#ifdef MAILHEADER_EXT\n\t\t/*\n\t\t * From: Chip Rosenthal <chip@chinacat.unicom.com>\n\t\t * Date: Sun, 19 Mar 1995 00:33:29 -0600 (CST)\n\t\t * \n\t\t * Warning: the %z [code] is implemented by inspecting the\n\t\t * timezone name conditional compile settings, and\n\t\t * inferring a method to get timezone offsets. I've tried\n\t\t * this code on a couple of machines, but I don't doubt\n\t\t * there is some system out there that won't like it.\n\t\t * Maybe the easiest thing to do would be to bracket this\n\t\t * with an #ifdef that can turn it off. The %z feature\n\t\t * would be an admittedly obscure one that most folks can\n\t\t * live without, but it would be a great help to those of\n\t\t * us that muck around with various message processors.\n\t\t */\n \t\tcase 'z':\t/* time zone offset east of GMT e.g. -0600 */\n#ifdef HAVE_TM_NAME\n\t\t\t/*\n\t\t\t * Systems with tm_name probably have tm_tzadj as\n\t\t\t * secs west of GMT.  Convert to mins east of GMT.\n\t\t\t */\n\t\t\toff = -timeptr->tm_tzadj / 60;\n#else /* !HAVE_TM_NAME */\n#ifdef HAVE_TM_ZONE\n\t\t\t/*\n\t\t\t * Systems with tm_zone probably have tm_gmtoff as\n\t\t\t * secs east of GMT.  Convert to mins east of GMT.\n\t\t\t */\n\t\t\toff = timeptr->tm_gmtoff / 60;\n#else /* !HAVE_TM_ZONE */\n#ifdef HAVE_GETTIMEOFDAY\n\t\t\tgettimeofday(&tv, &zone);\n\t\t\toff = -zone.tz_minuteswest;\n#else\n#if HAVE_VAR_TIMEZONE\n#if HAVE_VAR_ALTZONE\n\t\t\toff = -(daylight ? timezone : altzone) / 60;\n#else\n\t\t\toff = -timezone / 60;\n#endif\n#endif\n#endif\n#endif /* !HAVE_TM_ZONE */\n#endif /* !HAVE_TM_NAME */\n\t\t\tif (off < 0) {\n\t\t\t\ttbuf[0] = '-';\n\t\t\t\toff = -off;\n\t\t\t} else {\n\t\t\t\ttbuf[0] = '+';\n\t\t\t}\n\t\t\tsprintf(tbuf+1, \"%02u%02u\", (unsigned)off/60, (unsigned)off%60);\n\t\t\tbreak;\n#endif /* MAILHEADER_EXT */\n\n\t\tcase 'Z':\t/* time zone name or abbrevation */\n#ifdef HAVE_TZNAME\n\t\t\ti = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */\n\t\t\tstrcpy(tbuf, tzname[i]);\n#else\n#ifdef HAVE_TM_ZONE\n\t\t\tstrcpy(tbuf, timeptr->tm_zone);\n#else\n#ifdef HAVE_TM_NAME\n\t\t\tstrcpy(tbuf, timeptr->tm_name);\n#else\n#ifdef HAVE_TIMEZONE\n\t\t\tgettimeofday(& tv, & zone);\n#ifdef TIMEZONE_VOID\n\t\t\tstrcpy(tbuf, timezone());\n#else\n\t\t\tstrcpy(tbuf, timezone(zone.tz_minuteswest,\n\t\t\t\t\t\ttimeptr->tm_isdst > 0));\n#endif /* TIMEZONE_VOID */\n#endif /* HAVE_TIMEZONE */\n#endif /* HAVE_TM_NAME */\n#endif /* HAVE_TM_ZONE */\n#endif /* HAVE_TZNAME */\n\t\t\tbreak;\n\n#ifdef SYSV_EXT\n\t\tcase 'n':\t/* same as \\n */\n\t\t\ttbuf[0] = '\\n';\n\t\t\ttbuf[1] = '\\0';\n\t\t\tbreak;\n\n\t\tcase 't':\t/* same as \\t */\n\t\t\ttbuf[0] = '\\t';\n\t\t\ttbuf[1] = '\\0';\n\t\t\tbreak;\n\n\t\tcase 'D':\t/* date as %m/%d/%y */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%m/%d/%y\", timeptr);\n\t\t\tbreak;\n\n\t\tcase 'e':\t/* day of month, blank padded */\n\t\t\tsprintf(tbuf, \"%2d\", range(1, timeptr->tm_mday, 31));\n\t\t\tbreak;\n\n\t\tcase 'r':\t/* time as %I:%M:%S %p */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%I:%M:%S %p\", timeptr);\n\t\t\tbreak;\n\n\t\tcase 'R':\t/* time as %H:%M */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%H:%M\", timeptr);\n\t\t\tbreak;\n\n\t\tcase 'T':\t/* time as %H:%M:%S */\n\t\t\tstrftime(tbuf, sizeof tbuf, \"%H:%M:%S\", timeptr);\n\t\t\tbreak;\n#endif\n\n#ifdef SUNOS_EXT\n\t\tcase 'k':\t/* hour, 24-hour clock, blank pad */\n\t\t\tsprintf(tbuf, \"%2d\", range(0, timeptr->tm_hour, 23));\n\t\t\tbreak;\n\n\t\tcase 'l':\t/* hour, 12-hour clock, 1 - 12, blank pad */\n\t\t\ti = range(0, timeptr->tm_hour, 23);\n\t\t\tif (i == 0)\n\t\t\t\ti = 12;\n\t\t\telse if (i > 12)\n\t\t\t\ti -= 12;\n\t\t\tsprintf(tbuf, \"%2d\", i);\n\t\t\tbreak;\n#endif\n\n\n#ifdef VMS_EXT\n\t\tcase 'v':\t/* date as dd-bbb-YYYY */\n\t\t\tsprintf(tbuf, \"%2d-%3.3s-%4ld\",\n\t\t\t\trange(1, timeptr->tm_mday, 31),\n\t\t\t\tmonths_a[range(0, timeptr->tm_mon, 11)],\n\t\t\t\ttimeptr->tm_year + 1900L);\n\t\t\tfor (i = 3; i < 6; i++)\n\t\t\t\tif (islower(tbuf[i]))\n\t\t\t\t\ttbuf[i] = toupper(tbuf[i]);\n\t\t\tbreak;\n#endif\n\n\n#ifdef POSIX2_DATE\n\t\tcase 'C':\n\t\t\tsprintf(tbuf, \"%02ld\", (timeptr->tm_year + 1900L) / 100);\n\t\t\tbreak;\n\n\n\t\tcase 'E':\n\t\tcase 'O':\n\t\t\t/* POSIX locale extensions, ignored for now */\n\t\t\tgoto again;\n\n\t\tcase 'V':\t/* week of year according ISO 8601 */\n\t\t\tsprintf(tbuf, \"%02d\", iso8601wknum(timeptr));\n\t\t\tbreak;\n\n\t\tcase 'u':\n\t\t/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */\n\t\t\tsprintf(tbuf, \"%d\", timeptr->tm_wday == 0 ? 7 :\n\t\t\t\t\ttimeptr->tm_wday);\n\t\t\tbreak;\n#endif\t/* POSIX2_DATE */\n\n#ifdef ISO_DATE_EXT\n\t\tcase 'G':\n\t\tcase 'g':\n\t\t\t/*\n\t\t\t * Year of ISO week.\n\t\t\t *\n\t\t\t * If it's December but the ISO week number is one,\n\t\t\t * that week is in next year.\n\t\t\t * If it's January but the ISO week number is 52 or\n\t\t\t * 53, that week is in last year.\n\t\t\t * Otherwise, it's this year.\n\t\t\t */\n\t\t\tw = iso8601wknum(timeptr);\n\t\t\tif (timeptr->tm_mon == 11 && w == 1)\n\t\t\t\ty = 1900L + timeptr->tm_year + 1;\n\t\t\telse if (timeptr->tm_mon == 0 && w >= 52)\n\t\t\t\ty = 1900L + timeptr->tm_year - 1;\n\t\t\telse\n\t\t\t\ty = 1900L + timeptr->tm_year;\n\n\t\t\tif (*format == 'G')\n\t\t\t\tsprintf(tbuf, \"%ld\", y);\n\t\t\telse\n\t\t\t\tsprintf(tbuf, \"%02ld\", y % 100);\n\t\t\tbreak;\n#endif /* ISO_DATE_EXT */\n\t\tdefault:\n\t\t\ttbuf[0] = '%';\n\t\t\ttbuf[1] = *format;\n\t\t\ttbuf[2] = '\\0';\n\t\t\tbreak;\n\t\t}\n\t\ti = strlen(tbuf);\n\t\tif (i) {\n\t\t\tif (s + i < endp - 1) {\n\t\t\t\tstrcpy(s, tbuf);\n\t\t\t\ts += i;\n\t\t\t} else\n\t\t\t\treturn 0;\n\t\t}\n\t}\nout:\n\tif (s < endp && *format == '\\0') {\n\t\t*s = '\\0';\n\t\treturn (s - start);\n\t} else\n\t\treturn 0;\n}\n\n/* isleap --- is a year a leap year? */\n\n#ifndef __STDC__\nstatic int\nisleap(year)\nlong year;\n#else\nstatic int\nisleap(long year)\n#endif\n{\n\treturn ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);\n}\n\n\n#ifdef POSIX2_DATE\n/* iso8601wknum --- compute week number according to ISO 8601 */\n\n#ifndef __STDC__\nstatic int\niso8601wknum(timeptr)\nconst struct tm *timeptr;\n#else\nstatic int\niso8601wknum(const struct tm *timeptr)\n#endif\n{\n\t/*\n\t * From 1003.2:\n\t *\tIf the week (Monday to Sunday) containing January 1\n\t *\thas four or more days in the new year, then it is week 1;\n\t *\totherwise it is the highest numbered week of the previous\n\t *\tyear (52 or 53), and the next week is week 1.\n\t *\n\t * ADR: This means if Jan 1 was Monday through Thursday,\n\t *\tit was week 1, otherwise week 52 or 53.\n\t *\n\t * XPG4 erroneously included POSIX.2 rationale text in the\n\t * main body of the standard. Thus it requires week 53.\n\t */\n\n\tint weeknum, jan1day;\n\n\t/* get week number, Monday as first day of the week */\n\tweeknum = weeknumber(timeptr, 1);\n\n\t/*\n\t * With thanks and tip of the hatlo to tml@tik.vtt.fi\n\t *\n\t * What day of the week does January 1 fall on?\n\t * We know that\n\t *\t(timeptr->tm_yday - jan1.tm_yday) MOD 7 ==\n\t *\t\t(timeptr->tm_wday - jan1.tm_wday) MOD 7\n\t * and that\n\t * \tjan1.tm_yday == 0\n\t * and that\n\t * \ttimeptr->tm_wday MOD 7 == timeptr->tm_wday\n\t * from which it follows that. . .\n \t */\n\tjan1day = timeptr->tm_wday - (timeptr->tm_yday % 7);\n\tif (jan1day < 0)\n\t\tjan1day += 7;\n\n\t/*\n\t * If Jan 1 was a Monday through Thursday, it was in\n\t * week 1.  Otherwise it was last year's highest week, which is\n\t * this year's week 0.\n\t *\n\t * What does that mean?\n\t * If Jan 1 was Monday, the week number is exactly right, it can\n\t *\tnever be 0.\n\t * If it was Tuesday through Thursday, the weeknumber is one\n\t *\tless than it should be, so we add one.\n\t * Otherwise, Friday, Saturday or Sunday, the week number is\n\t * OK, but if it is 0, it needs to be 52 or 53.\n\t */\n\tswitch (jan1day) {\n\tcase 1:\t\t/* Monday */\n\t\tbreak;\n\tcase 2:\t\t/* Tuesday */\n\tcase 3:\t\t/* Wednesday */\n\tcase 4:\t\t/* Thursday */\n\t\tweeknum++;\n\t\tbreak;\n\tcase 5:\t\t/* Friday */\n\tcase 6:\t\t/* Saturday */\n\tcase 0:\t\t/* Sunday */\n\t\tif (weeknum == 0) {\n#ifdef USE_BROKEN_XPG4\n\t\t\t/* XPG4 (as of March 1994) says 53 unconditionally */\n\t\t\tweeknum = 53;\n#else\n\t\t\t/* get week number of last week of last year */\n\t\t\tstruct tm dec31ly;\t/* 12/31 last year */\n\t\t\tdec31ly = *timeptr;\n\t\t\tdec31ly.tm_year--;\n\t\t\tdec31ly.tm_mon = 11;\n\t\t\tdec31ly.tm_mday = 31;\n\t\t\tdec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;\n\t\t\tdec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900L);\n\t\t\tweeknum = iso8601wknum(& dec31ly);\n#endif\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (timeptr->tm_mon == 11) {\n\t\t/*\n\t\t * The last week of the year\n\t\t * can be in week 1 of next year.\n\t\t * Sigh.\n\t\t *\n\t\t * This can only happen if\n\t\t *\tM   T  W\n\t\t *\t29  30 31\n\t\t *\t30  31\n\t\t *\t31\n\t\t */\n\t\tint wday, mday;\n\n\t\twday = timeptr->tm_wday;\n\t\tmday = timeptr->tm_mday;\n\t\tif (   (wday == 1 && (mday >= 29 && mday <= 31))\n\t\t    || (wday == 2 && (mday == 30 || mday == 31))\n\t\t    || (wday == 3 &&  mday == 31))\n\t\t\tweeknum = 1;\n\t}\n\n\treturn weeknum;\n}\n#endif\n\n/* weeknumber --- figure how many weeks into the year */\n\n/* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */\n\n#ifndef __STDC__\nstatic int\nweeknumber(timeptr, firstweekday)\nconst struct tm *timeptr;\nint firstweekday;\n#else\nstatic int\nweeknumber(const struct tm *timeptr, int firstweekday)\n#endif\n{\n\tint wday = timeptr->tm_wday;\n\tint ret;\n\n\tif (firstweekday == 1) {\n\t\tif (wday == 0)\t/* sunday */\n\t\t\twday = 6;\n\t\telse\n\t\t\twday--;\n\t}\n\tret = ((timeptr->tm_yday + 7 - wday) / 7);\n\tif (ret < 0)\n\t\tret = 0;\n\treturn ret;\n}\n\n#if 0\n/* ADR --- I'm loathe to mess with ado's code ... */\n\nDate:         Wed, 24 Apr 91 20:54:08 MDT\nFrom: Michal Jaegermann <audfax!emory!vm.ucs.UAlberta.CA!NTOMCZAK>\nTo: arnold@audiofax.com\n\nHi Arnold,\nin a process of fixing of strftime() in libraries on Atari ST I grabbed\nsome pieces of code from your own strftime.  When doing that it came\nto mind that your weeknumber() function compiles a little bit nicer\nin the following form:\n/*\n * firstweekday is 0 if starting in Sunday, non-zero if in Monday\n */\n{\n    return (timeptr->tm_yday - timeptr->tm_wday +\n\t    (firstweekday ? (timeptr->tm_wday ? 8 : 1) : 7)) / 7;\n}\nHow nicer it depends on a compiler, of course, but always a tiny bit.\n\n   Cheers,\n   Michal\n   ntomczak@vm.ucs.ualberta.ca\n#endif\n\n#ifdef\tTEST_STRFTIME\n\n/*\n * NAME:\n *\ttst\n *\n * SYNOPSIS:\n *\ttst\n *\n * DESCRIPTION:\n *\t\"tst\" is a test driver for the function \"strftime\".\n *\n * OPTIONS:\n *\tNone.\n *\n * AUTHOR:\n *\tKarl Vogel\n *\tControl Data Systems, Inc.\n *\tvogelke@c-17igp.wpafb.af.mil\n *\n * BUGS:\n *\tNone noticed yet.\n *\n * COMPILE:\n *\tcc -o tst -DTEST_STRFTIME strftime.c\n */\n\n/* ADR: I reformatted this to my liking, and deleted some unneeded code. */\n\n#ifndef NULL\n#include\t<stdio.h>\n#endif\n#include\t<sys/time.h>\n#include\t<string.h>\n\n#define\t\tMAXTIME\t\t132\n\n/*\n * Array of time formats.\n */\n\nstatic char *array[] =\n{\n\t\"(%%A)      full weekday name, var length (Sunday..Saturday)  %A\",\n\t\"(%%B)       full month name, var length (January..December)  %B\",\n\t\"(%%C)                                               Century  %C\",\n\t\"(%%D)                                       date (%%m/%%d/%%y)  %D\",\n\t\"(%%E)                           Locale extensions (ignored)  %E\",\n\t\"(%%H)                          hour (24-hour clock, 00..23)  %H\",\n\t\"(%%I)                          hour (12-hour clock, 01..12)  %I\",\n\t\"(%%M)                                       minute (00..59)  %M\",\n\t\"(%%O)                           Locale extensions (ignored)  %O\",\n\t\"(%%R)                                 time, 24-hour (%%H:%%M)  %R\",\n\t\"(%%S)                                       second (00..60)  %S\",\n\t\"(%%T)                              time, 24-hour (%%H:%%M:%%S)  %T\",\n\t\"(%%U)    week of year, Sunday as first day of week (00..53)  %U\",\n\t\"(%%V)                    week of year according to ISO 8601  %V\",\n\t\"(%%W)    week of year, Monday as first day of week (00..53)  %W\",\n\t\"(%%X)     appropriate locale time representation (%H:%M:%S)  %X\",\n\t\"(%%Y)                           year with century (1970...)  %Y\",\n\t\"(%%Z) timezone (EDT), or blank if timezone not determinable  %Z\",\n\t\"(%%a)          locale's abbreviated weekday name (Sun..Sat)  %a\",\n\t\"(%%b)            locale's abbreviated month name (Jan..Dec)  %b\",\n\t\"(%%c)           full date (Sat Nov  4 12:02:33 1989)%n%t%t%t  %c\",\n\t\"(%%d)                             day of the month (01..31)  %d\",\n\t\"(%%e)               day of the month, blank-padded ( 1..31)  %e\",\n\t\"(%%h)                                should be same as (%%b)  %h\",\n\t\"(%%j)                            day of the year (001..366)  %j\",\n\t\"(%%k)               hour, 24-hour clock, blank pad ( 0..23)  %k\",\n\t\"(%%l)               hour, 12-hour clock, blank pad ( 0..12)  %l\",\n\t\"(%%m)                                        month (01..12)  %m\",\n\t\"(%%p)              locale's AM or PM based on 12-hour clock  %p\",\n\t\"(%%r)                   time, 12-hour (same as %%I:%%M:%%S %%p)  %r\",\n\t\"(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7]   %u\",\n\t\"(%%v)                                VMS date (dd-bbb-YYYY)  %v\",\n\t\"(%%w)                       day of week (0..6, Sunday == 0)  %w\",\n\t\"(%%x)                appropriate locale date representation  %x\",\n\t\"(%%y)                      last two digits of year (00..99)  %y\",\n\t\"(%%z)      timezone offset east of GMT as HHMM (e.g. -0500)  %z\",\n\t(char *) NULL\n};\n\n/* main routine. */\n\nint\nmain(argc, argv)\nint argc;\nchar **argv;\n{\n\tlong time();\n\n\tchar *next;\n\tchar string[MAXTIME];\n\n\tint k;\n\tint length;\n\n\tstruct tm *tm;\n\n\tlong clock;\n\n\t/* Call the function. */\n\n\tclock = time((long *) 0);\n\ttm = localtime(&clock);\n\n\tfor (k = 0; next = array[k]; k++) {\n\t\tlength = strftime(string, MAXTIME, next, tm);\n\t\tprintf(\"%s\\n\", string);\n\t}\n\n\texit(0);\n}\n#endif\t/* TEST_STRFTIME */\n"
  },
  {
    "path": "missing/strncasecmp.c",
    "content": "/* public domain rewrite of strncasecmp(3) */\n\n#include <ctype.h>\n\nint\nstrncasecmp(p1, p2, len)\n    char *p1;\n    char *p2;\n    int len;\n{\n    while (len != 0) {\n\tif (toupper(*p1) != toupper(*p2)) {\n\t    return toupper(*p1) - toupper(*p2);\n\t}\n\tif (*p1 == '\\0') {\n\t    return 0;\n\t}\n\tlen--; p1++; p2++;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "missing/strstr.c",
    "content": "/* public domain rewrite of strstr(3) */\n\nchar *\nstrstr(haystack, needle)\n    char *haystack, *needle;\n{\n    char *hend;\n    char *a, *b;\n\n    if (*needle == 0) return haystack;\n    hend = haystack + strlen(haystack) - strlen(needle) + 1;\n    while (haystack < hend) {\n\tif (*haystack == *needle) {\n\t    a = haystack;\n\t    b = needle;\n\t    for (;;) {\n\t\tif (*b == 0) return haystack;\n\t\tif (*a++ != *b++) {\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\thaystack++;\n    }\n    return 0;\n}\n"
  },
  {
    "path": "missing/strtod.c",
    "content": "/* \n * strtod.c --\n *\n *\tSource code for the \"strtod\" library procedure.\n *\n * Copyright (c) 1988-1993 The Regents of the University of California.\n * Copyright (c) 1994 Sun Microsystems, Inc.\n *\n * Permission to use, copy, modify, and distribute this\n * software and its documentation for any purpose and without\n * fee is hereby granted, provided that the above copyright\n * notice appear in all copies.  The University of California\n * makes no representations about the suitability of this\n * software for any purpose.  It is provided \"as is\" without\n * express or implied warranty.\n *\n * RCS: @(#) $Id$\n */\n\n#include \"config.h\"\n#ifdef HAVE_STDLIB_H\n#   include <stdlib.h>\n#endif\n#include <ctype.h>\n#include <errno.h>\nextern  int     errno;\n\n#ifndef __STDC__\n# ifdef __GNUC__\n#  define const __const__\n# else\n#  define const\n# endif\n#endif\n\n#ifndef TRUE\n#define TRUE 1\n#define FALSE 0\n#endif\n#ifndef NULL\n#define NULL 0\n#endif\n\nstatic int maxExponent = 511;\t/* Largest possible base 10 exponent.  Any\n\t\t\t\t * exponent larger than this will already\n\t\t\t\t * produce underflow or overflow, so there's\n\t\t\t\t * no need to worry about additional digits.\n\t\t\t\t */\nstatic double powersOf10[] = {\t/* Table giving binary powers of 10.  Entry */\n    10.,\t\t\t/* is 10^2^i.  Used to convert decimal */\n    100.,\t\t\t/* exponents into floating-point numbers. */\n    1.0e4,\n    1.0e8,\n    1.0e16,\n    1.0e32,\n    1.0e64,\n    1.0e128,\n    1.0e256\n};\n\f\n/*\n *----------------------------------------------------------------------\n *\n * strtod --\n *\n *\tThis procedure converts a floating-point number from an ASCII\n *\tdecimal representation to internal double-precision format.\n *\n * Results:\n *\tThe return value is the double-precision floating-point\n *\trepresentation of the characters in string.  If endPtr isn't\n *\tNULL, then *endPtr is filled in with the address of the\n *\tnext character after the last one that was part of the\n *\tfloating-point number.\n *\n * Side effects:\n *\tNone.\n *\n *----------------------------------------------------------------------\n */\n\ndouble\nstrtod(string, endPtr)\n    const char *string;\t\t/* A decimal ASCII floating-point number,\n\t\t\t\t * optionally preceded by white space.\n\t\t\t\t * Must have form \"-I.FE-X\", where I is the\n\t\t\t\t * integer part of the mantissa, F is the\n\t\t\t\t * fractional part of the mantissa, and X\n\t\t\t\t * is the exponent.  Either of the signs\n\t\t\t\t * may be \"+\", \"-\", or omitted.  Either I\n\t\t\t\t * or F may be omitted, or both.  The decimal\n\t\t\t\t * point isn't necessary unless F is present.\n\t\t\t\t * The \"E\" may actually be an \"e\".  E and X\n\t\t\t\t * may both be omitted (but not just one).\n\t\t\t\t */\n    char **endPtr;\t\t/* If non-NULL, store terminating character's\n\t\t\t\t * address here. */\n{\n    int sign, expSign = FALSE;\n    double fraction, dblExp, *d;\n    register const char *p;\n    register int c;\n    int exp = 0;\t\t/* Exponent read from \"EX\" field. */\n    int fracExp = 0;\t\t/* Exponent that derives from the fractional\n\t\t\t\t * part.  Under normal circumstatnces, it is\n\t\t\t\t * the negative of the number of digits in F.\n\t\t\t\t * However, if I is very long, the last digits\n\t\t\t\t * of I get dropped (otherwise a long I with a\n\t\t\t\t * large negative exponent could cause an\n\t\t\t\t * unnecessary overflow on I alone).  In this\n\t\t\t\t * case, fracExp is incremented one for each\n\t\t\t\t * dropped digit. */\n    int mantSize;\t\t/* Number of digits in mantissa. */\n    int decPt;\t\t\t/* Number of mantissa digits BEFORE decimal\n\t\t\t\t * point. */\n    const char *pExp;\t\t/* Temporarily holds location of exponent\n\t\t\t\t * in string. */\n\n    /*\n     * Strip off leading blanks and check for a sign.\n     */\n\n    p = string;\n    while (isspace(*p)) {\n\tp += 1;\n    }\n    if (*p == '-') {\n\tsign = TRUE;\n\tp += 1;\n    } else {\n\tif (*p == '+') {\n\t    p += 1;\n\t}\n\tsign = FALSE;\n    }\n\n    /*\n     * Count the number of digits in the mantissa (including the decimal\n     * point), and also locate the decimal point.\n     */\n\n    decPt = -1;\n    for (mantSize = 0; ; mantSize += 1)\n    {\n\tc = *p;\n\tif (!isdigit(c)) {\n\t    if ((c != '.') || (decPt >= 0)) {\n\t\tbreak;\n\t    }\n\t    decPt = mantSize;\n\t}\n\tp += 1;\n    }\n\n    /*\n     * Now suck up the digits in the mantissa.  Use two integers to\n     * collect 9 digits each (this is faster than using floating-point).\n     * If the mantissa has more than 18 digits, ignore the extras, since\n     * they can't affect the value anyway.\n     */\n    \n    pExp  = p;\n    p -= mantSize;\n    if (decPt < 0) {\n\tdecPt = mantSize;\n    } else {\n\tmantSize -= 1;\t\t\t/* One of the digits was the point. */\n    }\n    if (mantSize > 18) {\n\tfracExp = decPt - 18;\n\tmantSize = 18;\n    } else {\n\tfracExp = decPt - mantSize;\n    }\n    if (mantSize == 0) {\n\tfraction = 0.0;\n\tp = string;\n\tgoto done;\n    } else {\n\tint frac1, frac2;\n\tfrac1 = 0;\n\tfor ( ; mantSize > 9; mantSize -= 1)\n\t{\n\t    c = *p;\n\t    p += 1;\n\t    if (c == '.') {\n\t\tc = *p;\n\t\tp += 1;\n\t    }\n\t    frac1 = 10*frac1 + (c - '0');\n\t}\n\tfrac2 = 0;\n\tfor (; mantSize > 0; mantSize -= 1)\n\t{\n\t    c = *p;\n\t    p += 1;\n\t    if (c == '.') {\n\t\tc = *p;\n\t\tp += 1;\n\t    }\n\t    frac2 = 10*frac2 + (c - '0');\n\t}\n\tfraction = (1.0e9 * frac1) + frac2;\n    }\n\n    /*\n     * Skim off the exponent.\n     */\n\n    p = pExp;\n    if ((*p == 'E') || (*p == 'e')) {\n\tp += 1;\n\tif (*p == '-') {\n\t    expSign = TRUE;\n\t    p += 1;\n\t} else {\n\t    if (*p == '+') {\n\t\tp += 1;\n\t    }\n\t    expSign = FALSE;\n\t}\n\twhile (isdigit(*p)) {\n\t    exp = exp * 10 + (*p - '0');\n\t    p += 1;\n\t}\n    }\n    if (expSign) {\n\texp = fracExp - exp;\n    } else {\n\texp = fracExp + exp;\n    }\n\n    /*\n     * Generate a floating-point number that represents the exponent.\n     * Do this by processing the exponent one bit at a time to combine\n     * many powers of 2 of 10. Then combine the exponent with the\n     * fraction.\n     */\n    \n    if (exp < 0) {\n\texpSign = TRUE;\n\texp = -exp;\n    } else {\n\texpSign = FALSE;\n    }\n    if (exp > maxExponent) {\n\texp = maxExponent;\n\terrno = ERANGE;\n    }\n    dblExp = 1.0;\n    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {\n\tif (exp & 01) {\n\t    dblExp *= *d;\n\t}\n    }\n    if (expSign) {\n\tfraction /= dblExp;\n    } else {\n\tfraction *= dblExp;\n    }\n\ndone:\n    if (endPtr != NULL) {\n\t*endPtr = (char *) p;\n    }\n\n    if (sign) {\n\treturn -fraction;\n    }\n    return fraction;\n}\n"
  },
  {
    "path": "missing/strtol.c",
    "content": "/* public domain rewrite of strtol(3) */\n\n#include <ctype.h>\n\nlong\nstrtol(nptr, endptr, base)\n    char *nptr;\n    char **endptr;\n    int base;\n{\n    long result;\n    char *p = nptr;\n\n    while (isspace(*p)) {\n\tp++;\n    }\n    if (*p == '-') {\n\tp++;\n\tresult = -strtoul(p, endptr, base);\n    }\n    else {\n\tif (*p == '+') p++;\n\tresult = strtoul(p, endptr, base);\n    }\n    if (endptr != 0 && *endptr == p) {\n\t*endptr = nptr;\n    }\n    return result;\n}\n"
  },
  {
    "path": "missing/strtoul.c",
    "content": "/* \n * strtoul.c --\n *\n *\tSource code for the \"strtoul\" library procedure.\n *\n * Copyright 1988 Regents of the University of California\n * Permission to use, copy, modify, and distribute this\n * software and its documentation for any purpose and without\n * fee is hereby granted, provided that the above copyright\n * notice appear in all copies.  The University of California\n * makes no representations about the suitability of this\n * software for any purpose.  It is provided \"as is\" without\n * express or implied warranty.\n */\n\n#include <ctype.h>\n\n/*\n * The table below is used to convert from ASCII digits to a\n * numerical equivalent.  It maps from '0' through 'z' to integers\n * (100 for non-digit characters).\n */\n\nstatic char cvtIn[] = {\n    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\t\t/* '0' - '9' */\n    100, 100, 100, 100, 100, 100, 100,\t\t/* punctuation */\n    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\t/* 'A' - 'Z' */\n    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n    30, 31, 32, 33, 34, 35,\n    100, 100, 100, 100, 100, 100,\t\t/* punctuation */\n    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\t/* 'a' - 'z' */\n    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n    30, 31, 32, 33, 34, 35};\n\f\n/*\n *----------------------------------------------------------------------\n *\n * strtoul --\n *\n *\tConvert an ASCII string into an integer.\n *\n * Results:\n *\tThe return value is the integer equivalent of string.  If endPtr\n *\tis non-NULL, then *endPtr is filled in with the character\n *\tafter the last one that was part of the integer.  If string\n *\tdoesn't contain a valid integer value, then zero is returned\n *\tand *endPtr is set to string.\n *\n * Side effects:\n *\tNone.\n *\n *----------------------------------------------------------------------\n */\n\nunsigned long int\nstrtoul(string, endPtr, base)\n    char *string;\t\t/* String of ASCII digits, possibly\n\t\t\t\t * preceded by white space.  For bases\n\t\t\t\t * greater than 10, either lower- or\n\t\t\t\t * upper-case digits may be used.\n\t\t\t\t */\n    char **endPtr;\t\t/* Where to store address of terminating\n\t\t\t\t * character, or NULL. */\n    int base;\t\t\t/* Base for conversion.  Must be less\n\t\t\t\t * than 37.  If 0, then the base is chosen\n\t\t\t\t * from the leading characters of string:\n\t\t\t\t * \"0x\" means hex, \"0\" means octal, anything\n\t\t\t\t * else means decimal.\n\t\t\t\t */\n{\n    register char *p;\n    register unsigned long int result = 0;\n    register unsigned digit;\n    int anyDigits = 0;\n\n    /*\n     * Skip any leading blanks.\n     */\n\n    p = string;\n    while (isspace(*p)) {\n\tp += 1;\n    }\n\n    /*\n     * If no base was provided, pick one from the leading characters\n     * of the string.\n     */\n    \n    if (base == 0)\n    {\n\tif (*p == '0') {\n\t    p += 1;\n\t    if (*p == 'x') {\n\t\tp += 1;\n\t\tbase = 16;\n\t    } else {\n\n\t\t/*\n\t\t * Must set anyDigits here, otherwise \"0\" produces a\n\t\t * \"no digits\" error.\n\t\t */\n\n\t\tanyDigits = 1;\n\t\tbase = 8;\n\t    }\n\t}\n\telse base = 10;\n    } else if (base == 16) {\n\n\t/*\n\t * Skip a leading \"0x\" from hex numbers.\n\t */\n\n\tif ((p[0] == '0') && (p[1] == 'x')) {\n\t    p += 2;\n\t}\n    }\n\n    /*\n     * Sorry this code is so messy, but speed seems important.  Do\n     * different things for base 8, 10, 16, and other.\n     */\n\n    if (base == 8) {\n\tfor ( ; ; p += 1) {\n\t    digit = *p - '0';\n\t    if (digit > 7) {\n\t\tbreak;\n\t    }\n\t    result = (result << 3) + digit;\n\t    anyDigits = 1;\n\t}\n    } else if (base == 10) {\n\tfor ( ; ; p += 1) {\n\t    digit = *p - '0';\n\t    if (digit > 9) {\n\t\tbreak;\n\t    }\n\t    result = (10*result) + digit;\n\t    anyDigits = 1;\n\t}\n    } else if (base == 16) {\n\tfor ( ; ; p += 1) {\n\t    digit = *p - '0';\n\t    if (digit > ('z' - '0')) {\n\t\tbreak;\n\t    }\n\t    digit = cvtIn[digit];\n\t    if (digit > 15) {\n\t\tbreak;\n\t    }\n\t    result = (result << 4) + digit;\n\t    anyDigits = 1;\n\t}\n    } else {\n\tfor ( ; ; p += 1) {\n\t    digit = *p - '0';\n\t    if (digit > ('z' - '0')) {\n\t\tbreak;\n\t    }\n\t    digit = cvtIn[digit];\n\t    if (digit >= base) {\n\t\tbreak;\n\t    }\n\t    result = result*base + digit;\n\t    anyDigits = 1;\n\t}\n    }\n\n    /*\n     * See if there were any digits at all.\n     */\n\n    if (!anyDigits) {\n\tp = string;\n    }\n\n    if (endPtr != 0) {\n\t*endPtr = p;\n    }\n\n    return result;\n}\n"
  },
  {
    "path": "missing/vsnprintf.c",
    "content": "/*-\n * Copyright (c) 1990, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * This code is derived from software contributed to Berkeley by\n * Chris Torek.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * IMPORTANT NOTE:\n * --------------\n * From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change\n * paragraph 3 above is now null and void.\n */\n\n/* SNPRINTF.C  \n * fjc 7-31-97 Modified by Mib Software to be a standalone snprintf.c module.\n *      http://www.mibsoftware.com\n * Mib Software does not warrant this software any differently than the\n * University of California, Berkeley as described above.  All warranties\n * are disclaimed.  Use this software at your own risk.\n *\n *      All code referencing FILE * functions was eliminated, since it could\n *      never be called.  All header files and necessary files are collapsed\n *      into one file, internal functions are declared static.  This should\n *      allow inclusion into libraries with less chance of namespace collisions.\n *\n *      snprintf should be the only externally visible item.\n *     \n *      As of 7-31-97 FLOATING_POINT is NOT provided.  The code is somewhat\n *        non-portable, so it is disabled.\n */\n\n/* Define FLOATING_POINT to get floating point. */\n/*\n#define\tFLOATING_POINT\n*/\n\n#include <sys/types.h>\n#define u_long unsigned long\n#define u_short unsigned short\n#define u_int unsigned int\n\n#undef __P\n#if defined(__STDC__)\n# include <stdarg.h>\n# if !defined(__P)\n#  define __P(x) x\n# endif\n#else\n# define __P(x) ()\n# if !defined(const)\n#  define const\n# endif\n# include <varargs.h>\n#endif\n#ifndef _BSD_VA_LIST_ \n#define\t_BSD_VA_LIST_ va_list\n#endif\n\n#ifdef __STDC__\n# include <limits.h>\n#else\n# ifndef LONG_MAX\n#  ifdef HAVE_LIMITS_H\n#   include <limits.h>\n#  else\n    /* assuming 32bit(2's compliment) long */\n#   define LONG_MAX 2147483647\n#  endif\n# endif\n#endif\n\n#if defined(__hpux) && !defined(__GNUC__) && !defined(__STDC__)\n#define const\n#endif\n\n#if defined(sgi)\n#undef __const\n#define __const\n#endif /* People who don't like const sys_error */\n\n#include <stddef.h>\n\n#ifndef NULL\n#define\tNULL\t0\n#endif\n\n/*\n * NB: to fit things in six character monocase externals, the stdio\n * code uses the prefix `__s' for stdio objects, typically followed\n * by a three-character attempt at a mnemonic.\n */\n\n/* stdio buffers */\nstruct __sbuf {\n\tunsigned char *_base;\n\tint\t_size;\n};\n\n\n/*\n * stdio state variables.\n *\n * The following always hold:\n *\n *\tif (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),\n *\t\t_lbfsize is -_bf._size, else _lbfsize is 0\n *\tif _flags&__SRD, _w is 0\n *\tif _flags&__SWR, _r is 0\n *\n * This ensures that the getc and putc macros (or inline functions) never\n * try to write or read from a file that is in `read' or `write' mode.\n * (Moreover, they can, and do, automatically switch from read mode to\n * write mode, and back, on \"r+\" and \"w+\" files.)\n *\n * _lbfsize is used only to make the inline line-buffered output stream\n * code as compact as possible.\n *\n * _ub, _up, and _ur are used when ungetc() pushes back more characters\n * than fit in the current _bf, or when ungetc() pushes back a character\n * that does not match the previous one in _bf.  When this happens,\n * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff\n * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.\n *\n * NB: see WARNING above before changing the layout of this structure!\n */\ntypedef\tstruct __sFILE {\n\tunsigned char *_p;\t/* current position in (some) buffer */\n\tint\t_r;\t\t/* read space left for getc() */\n\tint\t_w;\t\t/* write space left for putc() */\n\tshort\t_flags;\t\t/* flags, below; this FILE is free if 0 */\n\tshort\t_file;\t\t/* fileno, if Unix descriptor, else -1 */\n\tstruct\t__sbuf _bf;\t/* the buffer (at least 1 byte, if !NULL) */\n\tint\t_lbfsize;\t/* 0 or -_bf._size, for inline putc */\n} FILE;\n\n\n#define\t__SLBF\t0x0001\t\t/* line buffered */\n#define\t__SNBF\t0x0002\t\t/* unbuffered */\n#define\t__SRD\t0x0004\t\t/* OK to read */\n#define\t__SWR\t0x0008\t\t/* OK to write */\n\t/* RD and WR are never simultaneously asserted */\n#define\t__SRW\t0x0010\t\t/* open for reading & writing */\n#define\t__SEOF\t0x0020\t\t/* found EOF */\n#define\t__SERR\t0x0040\t\t/* found error */\n#define\t__SMBF\t0x0080\t\t/* _buf is from malloc */\n#define\t__SAPP\t0x0100\t\t/* fdopen()ed in append mode */\n#define\t__SSTR\t0x0200\t\t/* this is an sprintf/snprintf string */\n#define\t__SOPT\t0x0400\t\t/* do fseek() optimisation */\n#define\t__SNPT\t0x0800\t\t/* do not do fseek() optimisation */\n#define\t__SOFF\t0x1000\t\t/* set iff _offset is in fact correct */\n#define\t__SMOD\t0x2000\t\t/* true => fgetln modified _p text */\n\n\n#define\tEOF\t(-1)\n\n\n#define\t__sfeof(p)\t(((p)->_flags & __SEOF) != 0)\n#define\t__sferror(p)\t(((p)->_flags & __SERR) != 0)\n#define\t__sclearerr(p)\t((void)((p)->_flags &= ~(__SERR|__SEOF)))\n#define\t__sfileno(p)\t((p)->_file)\n\n#define\tfeof(p)\t\t__sfeof(p)\n#define\tferror(p)\t__sferror(p)\n#define\tclearerr(p)\t__sclearerr(p)\n\n#ifndef _ANSI_SOURCE\n#define\tfileno(p)\t__sfileno(p)\n#endif\n\n\n#if defined(__hpux) && !defined(__GNUC__) || defined(__DECC)\n#include <string.h>\n#endif\n\n/*\n * I/O descriptors for __sfvwrite().\n */\nstruct __siov {\n\tvoid\t*iov_base;\n\tsize_t\tiov_len;\n};\nstruct __suio {\n\tstruct\t__siov *uio_iov;\n\tint\tuio_iovcnt;\n\tint\tuio_resid;\n};\n\n/*\n * Write some memory regions.  Return zero on success, EOF on error.\n *\n * This routine is large and unsightly, but most of the ugliness due\n * to the three different kinds of output buffering is handled here.\n */\nstatic BSD__sfvwrite(fp, uio)\n\tregister FILE *fp;\n\tregister struct __suio *uio;\n{\n\tregister size_t len;\n\tregister char *p;\n\tregister struct __siov *iov;\n\tregister int w;\n\n\tif ((len = uio->uio_resid) == 0)\n\t\treturn (0);\n#ifndef __hpux\n#define\tMIN(a, b) ((a) < (b) ? (a) : (b))\n#endif\n#define\tCOPY(n)\t  (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))\n\n\tiov = uio->uio_iov;\n\tp = iov->iov_base;\n\tlen = iov->iov_len;\n\tiov++;\n#define GETIOV(extra_work) \\\n\twhile (len == 0) { \\\n\t\textra_work; \\\n\t\tp = iov->iov_base; \\\n\t\tlen = iov->iov_len; \\\n\t\tiov++; \\\n\t}\n\tif (fp->_flags & __SNBF) {\n\t/* fjc 7-31-97 Will never happen.  We are working with\n\t\t\t\t\t   strings only\n\t*/\n\t} else if ((fp->_flags & __SLBF) == 0) {\n\t/*\n\t\t * Fully buffered: fill partially full buffer, if any,\n\t\t * and then flush.  If there is no partial buffer, write\n\t\t * one _bf._size byte chunk directly (without copying).\n\t\t *\n\t\t * String output is a special case: write as many bytes\n\t\t * as fit, but pretend we wrote everything.  This makes\n\t\t * snprintf() return the number of bytes needed, rather\n\t\t * than the number used, and avoids its write function\n\t\t * (so that the write function can be invalid).\n\t\t */\n\t\tdo {\n\t\t\tGETIOV(;);\n\t\t\tw = fp->_w;\n\t\t\tif (fp->_flags & __SSTR) {\n\t\t\t\tif (len < w)\n\t\t\t\t\tw = len;\n\t\t\t\tCOPY(w);\t/* copy MIN(fp->_w,len), */\n\t\t\t\tfp->_w -= w;\n\t\t\t\tfp->_p += w;\n\t\t\t\tw = len;\t/* but pretend copied all */\n\t\t\t} else {\n\t\t\t\t/* fjc 7-31-97 Will never happen.  We are working with\n\t\t\t\t\t\t\t\t   strings only\n\t\t\t\t*/\n\t\t\t}\n\t\t\tp += w;\n\t\t\tlen -= w;\n\t\t} while ((uio->uio_resid -= w) != 0);\n\t} else {\n\t\t/* fjc 7-31-97 Will never happen.  We are working with\n\t\t\t\t\t\t   strings only\n\t\t*/\n\t}\n\treturn (0);\n\nerr:\n\tfp->_flags |= __SERR;\n\treturn (EOF);\n}\n\n/*\n * Actual printf innards.\n *\n * This code is large and complicated...\n */\n\n#if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__)\n#include <stdlib.h>\n#endif\n\n/*\n * Flush out all the vectors defined by the given uio,\n * then reset it so that it can be reused.\n */\nstatic int\nBSD__sprint(fp, uio)\n\tFILE *fp;\n\tregister struct __suio *uio;\n{\n\tregister int err;\n\n\tif (uio->uio_resid == 0) {\n\t\tuio->uio_iovcnt = 0;\n\t\treturn (0);\n\t}\n\terr = BSD__sfvwrite(fp, uio);\n\tuio->uio_resid = 0;\n\tuio->uio_iovcnt = 0;\n\treturn (err);\n}\n\n\n/*\n * Helper function for `fprintf to unbuffered unix file': creates a\n * temporary buffer.  We only work on write-only files; this avoids\n * worries about ungetc buffers and so forth.\n */\nstatic int\nBSD__sbprintf(fp, fmt, ap)\n\tregister FILE *fp;\n\tconst char *fmt;\n\tva_list ap;\n{\n/* We don't support files. */\n\treturn 0;\n}\n\n\n/*\n * Macros for converting digits to letters and vice versa\n */\n#define\tto_digit(c)\t((c) - '0')\n#define is_digit(c)\t((unsigned)to_digit(c) <= 9)\n#define\tto_char(n)\t((n) + '0')\n\n/*\n * Convert an unsigned long to ASCII for printf purposes, returning\n * a pointer to the first character of the string representation.\n * Octal numbers can be forced to have a leading zero; hex numbers\n * use the given digits.\n */\nstatic char *\nBSD__ultoa(val, endp, base, octzero, xdigs)\n\tregister u_long val;\n\tchar *endp;\n\tint base, octzero;\n\tchar *xdigs;\n{\n\tregister char *cp = endp;\n\tregister long sval;\n\n\t/*\n\t * Handle the three cases separately, in the hope of getting\n\t * better/faster code.\n\t */\n\tswitch (base) {\n\tcase 10:\n\t\tif (val < 10) {\t/* many numbers are 1 digit */\n\t\t\t*--cp = to_char(val);\n\t\t\treturn (cp);\n\t\t}\n\t\t/*\n\t\t * On many machines, unsigned arithmetic is harder than\n\t\t * signed arithmetic, so we do at most one unsigned mod and\n\t\t * divide; this is sufficient to reduce the range of\n\t\t * the incoming value to where signed arithmetic works.\n\t\t */\n\t\tif (val > LONG_MAX) {\n\t\t\t*--cp = to_char(val % 10);\n\t\t\tsval = val / 10;\n\t\t} else\n\t\t\tsval = val;\n\t\tdo {\n\t\t\t*--cp = to_char(sval % 10);\n\t\t\tsval /= 10;\n\t\t} while (sval != 0);\n\t\tbreak;\n\n\tcase 8:\n\t\tdo {\n\t\t\t*--cp = to_char(val & 7);\n\t\t\tval >>= 3;\n\t\t} while (val);\n\t\tif (octzero && *cp != '0')\n\t\t\t*--cp = '0';\n\t\tbreak;\n\n\tcase 16:\n\t\tdo {\n\t\t\t*--cp = xdigs[val & 15];\n\t\t\tval >>= 4;\n\t\t} while (val);\n\t\tbreak;\n\n\tdefault:\t\t\t/* oops */\n\t\t/* \n\t\tabort();\n\t\t*/\n\t\tbreak;\t/* fjc 7-31-97.  Don't reference abort() here */\n\t}\n\treturn (cp);\n}\n\n#ifdef FLOATING_POINT\n#include <math.h>\n/* #include \"floatio.h\" */\n\n#ifndef MAXEXP\n# define MAXEXP 1024\n#endif\n\n#ifndef MAXFRACT\n# define MAXFRACT 64\n#endif\n\n#define\tBUF\t\t(MAXEXP+MAXFRACT+1)\t/* + decimal point */\n#define\tDEFPREC\t\t6\n\nstatic char *cvt __P((double, int, int, char *, int *, int, int *));\nstatic int exponent __P((char *, int, int));\n\n#else /* no FLOATING_POINT */\n\n#define\tBUF\t\t68\n\n#endif /* FLOATING_POINT */\n\n\n/*\n * Flags used during conversion.\n */\n#define\tALT\t\t0x001\t\t/* alternate form */\n#define\tHEXPREFIX\t0x002\t\t/* add 0x or 0X prefix */\n#define\tLADJUST\t\t0x004\t\t/* left adjustment */\n#define\tLONGDBL\t\t0x008\t\t/* long double; unimplemented */\n#define\tLONGINT\t\t0x010\t\t/* long integer */\n\n#ifdef _HAVE_SANE_QUAD_\n#define\tQUADINT\t\t0x020\t\t/* quad integer */\n#endif /* _HAVE_SANE_QUAD_ */\n\n#define\tSHORTINT\t0x040\t\t/* short integer */\n#define\tZEROPAD\t\t0x080\t\t/* zero (as opposed to blank) pad */\n#define FPT\t\t0x100\t\t/* Floating point number */\nstatic int\nBSD_vfprintf(fp, fmt0, ap)\n\tFILE *fp;\n\tconst char *fmt0;\n\tva_list ap;\n{\n\tregister char *fmt;\t/* format string */\n\tregister int ch;\t/* character from fmt */\n\tregister int n;\t\t/* handy integer (short term usage) */\n\tregister char *cp;\t/* handy char pointer (short term usage) */\n\tregister struct __siov *iovp;/* for PRINT macro */\n\tregister int flags;\t/* flags as above */\n\tint ret;\t\t/* return value accumulator */\n\tint width;\t\t/* width from format (%8d), or 0 */\n\tint prec;\t\t/* precision from format (%.3d), or -1 */\n\tchar sign;\t\t/* sign prefix (' ', '+', '-', or \\0) */\n#ifdef FLOATING_POINT\n\tchar softsign;\t\t/* temporary negative sign for floats */\n\tdouble _double;\t\t/* double precision arguments %[eEfgG] */\n\tint expt;\t\t/* integer value of exponent */\n\tint expsize;\t\t/* character count for expstr */\n\tint ndig;\t\t/* actual number of digits returned by cvt */\n\tchar expstr[7];\t\t/* buffer for exponent string */\n#endif\n\tu_long\tulval;\t\t/* integer arguments %[diouxX] */\n#ifdef _HAVE_SANE_QUAD_\n\tu_quad_t uqval;\t\t/* %q integers */\n#endif /* _HAVE_SANE_QUAD_ */\n\tint base;\t\t/* base for [diouxX] conversion */\n\tint dprec;\t\t/* a copy of prec if [diouxX], 0 otherwise */\n\tint fieldsz;\t\t/* field size expanded by sign, etc */\n\tint realsz;\t\t/* field size expanded by dprec */\n\tint size;\t\t/* size of converted field or string */\n\tchar *xdigs;\t\t/* digits for [xX] conversion */\n#define NIOV 8\n\tstruct __suio uio;\t/* output information: summary */\n\tstruct __siov iov[NIOV];/* ... and individual io vectors */\n\tchar buf[BUF];\t\t/* space for %c, %[diouxX], %[eEfgG] */\n\tchar ox[2];\t\t/* space for 0x hex-prefix */\n\n\t/*\n\t * Choose PADSIZE to trade efficiency vs. size.  If larger printf\n\t * fields occur frequently, increase PADSIZE and make the initializers\n\t * below longer.\n\t */\n#define\tPADSIZE\t16\t\t/* pad chunk size */\n\tstatic char blanks[PADSIZE] =\n\t {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};\n\tstatic char zeroes[PADSIZE] =\n\t {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};\n\n\t/*\n\t * BEWARE, these `goto error' on error, and PAD uses `n'.\n\t */\n#define\tPRINT(ptr, len) { \\\n\tiovp->iov_base = (ptr); \\\n\tiovp->iov_len = (len); \\\n\tuio.uio_resid += (len); \\\n\tiovp++; \\\n\tif (++uio.uio_iovcnt >= NIOV) { \\\n\t\tif (BSD__sprint(fp, &uio)) \\\n\t\t\tgoto error; \\\n\t\tiovp = iov; \\\n\t} \\\n}\n#define\tPAD(howmany, with) { \\\n\tif ((n = (howmany)) > 0) { \\\n\t\twhile (n > PADSIZE) { \\\n\t\t\tPRINT(with, PADSIZE); \\\n\t\t\tn -= PADSIZE; \\\n\t\t} \\\n\t\tPRINT(with, n); \\\n\t} \\\n}\n#define\tFLUSH() { \\\n\tif (uio.uio_resid && BSD__sprint(fp, &uio)) \\\n\t\tgoto error; \\\n\tuio.uio_iovcnt = 0; \\\n\tiovp = iov; \\\n}\n\n\t/*\n\t * To extend shorts properly, we need both signed and unsigned\n\t * argument extraction methods.\n\t */\n#define\tSARG() \\\n\t(flags&LONGINT ? va_arg(ap, long) : \\\n\t    flags&SHORTINT ? (long)(short)va_arg(ap, int) : \\\n\t    (long)va_arg(ap, int))\n#define\tUARG() \\\n\t(flags&LONGINT ? va_arg(ap, u_long) : \\\n\t    flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \\\n\t    (u_long)va_arg(ap, u_int))\n\n\t/* optimise fprintf(stderr) (and other unbuffered Unix files) */\n\tif ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&\n\t    fp->_file >= 0)\n\t\treturn (BSD__sbprintf(fp, fmt0, ap));\n\n\tfmt = (char *)fmt0;\n\tuio.uio_iov = iovp = iov;\n\tuio.uio_resid = 0;\n\tuio.uio_iovcnt = 0;\n\tret = 0;\n\n\t/*\n\t * Scan the format for conversions (`%' character).\n\t */\n\tfor (;;) {\n\t\tfor (cp = fmt; (ch = *fmt) != '\\0' && ch != '%'; fmt++)\n\t\t\t/* void */;\n\t\tif ((n = fmt - cp) != 0) {\n\t\t\tPRINT(cp, n);\n\t\t\tret += n;\n\t\t}\n\t\tif (ch == '\\0')\n\t\t\tgoto done;\n\t\tfmt++;\t\t/* skip over '%' */\n\n\t\tflags = 0;\n\t\tdprec = 0;\n\t\twidth = 0;\n\t\tprec = -1;\n\t\tsign = '\\0';\n\nrflag:\t\tch = *fmt++;\nreswitch:\tswitch (ch) {\n\t\tcase ' ':\n\t\t\t/*\n\t\t\t * ``If the space and + flags both appear, the space\n\t\t\t * flag will be ignored.''\n\t\t\t *\t-- ANSI X3J11\n\t\t\t */\n\t\t\tif (!sign)\n\t\t\t\tsign = ' ';\n\t\t\tgoto rflag;\n\t\tcase '#':\n\t\t\tflags |= ALT;\n\t\t\tgoto rflag;\n\t\tcase '*':\n\t\t\t/*\n\t\t\t * ``A negative field width argument is taken as a\n\t\t\t * - flag followed by a positive field width.''\n\t\t\t *\t-- ANSI X3J11\n\t\t\t * They don't exclude field widths read from args.\n\t\t\t */\n\t\t\tif ((width = va_arg(ap, int)) >= 0)\n\t\t\t\tgoto rflag;\n\t\t\twidth = -width;\n\t\t\t/* FALLTHROUGH */\n\t\tcase '-':\n\t\t\tflags |= LADJUST;\n\t\t\tgoto rflag;\n\t\tcase '+':\n\t\t\tsign = '+';\n\t\t\tgoto rflag;\n\t\tcase '.':\n\t\t\tif ((ch = *fmt++) == '*') {\n\t\t\t\tn = va_arg(ap, int);\n\t\t\t\tprec = n < 0 ? -1 : n;\n\t\t\t\tgoto rflag;\n\t\t\t}\n\t\t\tn = 0;\n\t\t\twhile (is_digit(ch)) {\n\t\t\t\tn = 10 * n + to_digit(ch);\n\t\t\t\tch = *fmt++;\n\t\t\t}\n\t\t\tprec = n < 0 ? -1 : n;\n\t\t\tgoto reswitch;\n\t\tcase '0':\n\t\t\t/*\n\t\t\t * ``Note that 0 is taken as a flag, not as the\n\t\t\t * beginning of a field width.''\n\t\t\t *\t-- ANSI X3J11\n\t\t\t */\n\t\t\tflags |= ZEROPAD;\n\t\t\tgoto rflag;\n\t\tcase '1': case '2': case '3': case '4':\n\t\tcase '5': case '6': case '7': case '8': case '9':\n\t\t\tn = 0;\n\t\t\tdo {\n\t\t\t\tn = 10 * n + to_digit(ch);\n\t\t\t\tch = *fmt++;\n\t\t\t} while (is_digit(ch));\n\t\t\twidth = n;\n\t\t\tgoto reswitch;\n#ifdef FLOATING_POINT\n\t\tcase 'L':\n\t\t\tflags |= LONGDBL;\n\t\t\tgoto rflag;\n#endif\n\t\tcase 'h':\n\t\t\tflags |= SHORTINT;\n\t\t\tgoto rflag;\n\t\tcase 'l':\n\t\t\tflags |= LONGINT;\n\t\t\tgoto rflag;\n#ifdef _HAVE_SANE_QUAD_\n\t\tcase 'q':\n\t\t\tflags |= QUADINT;\n\t\t\tgoto rflag;\n#endif /* _HAVE_SANE_QUAD_ */\n\t\tcase 'c':\n\t\t\t*(cp = buf) = va_arg(ap, int);\n\t\t\tsize = 1;\n\t\t\tsign = '\\0';\n\t\t\tbreak;\n\t\tcase 'D':\n\t\t\tflags |= LONGINT;\n\t\t\t/*FALLTHROUGH*/\n\t\tcase 'd':\n\t\tcase 'i':\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tif (flags & QUADINT) {\n\t\t\t\tuqval = va_arg(ap, quad_t);\n\t\t\t\tif ((quad_t)uqval < 0) {\n\t\t\t\t\tuqval = -uqval;\n\t\t\t\t\tsign = '-';\n\t\t\t\t}\n\t\t\t} else {\n#else /* _HAVE_SANE_QUAD_ */\n\t\t\t{\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\tulval = SARG();\n\t\t\t\tif ((long)ulval < 0) {\n\t\t\t\t\tulval = -ulval;\n\t\t\t\t\tsign = '-';\n\t\t\t\t}\n\t\t\t}\n\t\t\tbase = 10;\n\t\t\tgoto number;\n#ifdef FLOATING_POINT\n\t\tcase 'e':\t\t/* anomalous precision */\n\t\tcase 'E':\n\t\t\tprec = (prec == -1) ?\n\t\t\t\tDEFPREC + 1 : prec + 1;\n\t\t\t/* FALLTHROUGH */\n\t\t\tgoto fp_begin;\n\t\tcase 'f':\t\t/* always print trailing zeroes */\n\t\t\tif (prec != 0)\n\t\t\t\tflags |= ALT;\n\t\tcase 'g':\n\t\tcase 'G':\n\t\t\tif (prec == -1)\n\t\t\t\tprec = DEFPREC;\nfp_begin:\t\t_double = va_arg(ap, double);\n\t\t\t/* do this before tricky precision changes */\n\t\t\tif (isinf(_double)) {\n\t\t\t\tif (_double < 0)\n\t\t\t\t\tsign = '-';\n\t\t\t\tcp = \"Inf\";\n\t\t\t\tsize = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (isnan(_double)) {\n\t\t\t\tcp = \"NaN\";\n\t\t\t\tsize = 3;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tflags |= FPT;\n\t\t\tcp = cvt(_double, prec, flags, &softsign,\n\t\t\t\t&expt, ch, &ndig);\n\t\t\tif (ch == 'g' || ch == 'G') {\n\t\t\t\tif (expt <= -4 || expt > prec)\n\t\t\t\t\tch = (ch == 'g') ? 'e' : 'E';\n\t\t\t\telse\n\t\t\t\t\tch = 'g';\n\t\t\t} \n\t\t\tif (ch <= 'e') {\t/* 'e' or 'E' fmt */\n\t\t\t\t--expt;\n\t\t\t\texpsize = exponent(expstr, expt, ch);\n\t\t\t\tsize = expsize + ndig;\n\t\t\t\tif (ndig > 1 || flags & ALT)\n\t\t\t\t\t++size;\n\t\t\t} else if (ch == 'f') {\t\t/* f fmt */\n\t\t\t\tif (expt > 0) {\n\t\t\t\t\tsize = expt;\n\t\t\t\t\tif (prec || flags & ALT)\n\t\t\t\t\t\tsize += prec + 1;\n\t\t\t\t} else\t/* \"0.X\" */\n\t\t\t\t\tsize = prec + 2;\n\t\t\t} else if (expt >= ndig) {\t/* fixed g fmt */\n\t\t\t\tsize = expt;\n\t\t\t\tif (flags & ALT)\n\t\t\t\t\t++size;\n\t\t\t} else\n\t\t\t\tsize = ndig + (expt > 0 ?\n\t\t\t\t\t1 : 2 - expt);\n\n\t\t\tif (softsign)\n\t\t\t\tsign = '-';\n\t\t\tbreak;\n#endif /* FLOATING_POINT */\n\t\tcase 'n':\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tif (flags & QUADINT)\n\t\t\t\t*va_arg(ap, quad_t *) = ret;\n\t\t\telse if (flags & LONGINT)\n#else /* _HAVE_SANE_QUAD_ */\n\t\t\tif (flags & LONGINT)\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\t*va_arg(ap, long *) = ret;\n\t\t\telse if (flags & SHORTINT)\n\t\t\t\t*va_arg(ap, short *) = ret;\n\t\t\telse\n\t\t\t\t*va_arg(ap, int *) = ret;\n\t\t\tcontinue;\t/* no output */\n\t\tcase 'O':\n\t\t\tflags |= LONGINT;\n\t\t\t/*FALLTHROUGH*/\n\t\tcase 'o':\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tif (flags & QUADINT)\n\t\t\t\tuqval = va_arg(ap, u_quad_t);\n\t\t\telse\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\tulval = UARG();\n\t\t\tbase = 8;\n\t\t\tgoto nosign;\n\t\tcase 'p':\n\t\t\t/*\n\t\t\t * ``The argument shall be a pointer to void.  The\n\t\t\t * value of the pointer is converted to a sequence\n\t\t\t * of printable characters, in an implementation-\n\t\t\t * defined manner.''\n\t\t\t *\t-- ANSI X3J11\n\t\t\t */\n#ifdef _HAVE_LLP64_\n\t\t\tuqval = (u_long)va_arg(ap, void *);\n\t\t\tflags = (flags) | QUADINT | HEXPREFIX;\n#else\n\t\t\tulval = (u_long)va_arg(ap, void *);\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tflags = (flags & ~QUADINT) | HEXPREFIX;\n#else /* _HAVE_SANE_QUAD_ */\n\t\t\tflags = (flags) | HEXPREFIX;\n#endif /* _HAVE_SANE_QUAD_ */\n#endif\n\t\t\tbase = 16;\n\t\t\txdigs = \"0123456789abcdef\";\n\t\t\tch = 'x';\n\t\t\tgoto nosign;\n\t\tcase 's':\n\t\t\tif ((cp = va_arg(ap, char *)) == NULL)\n\t\t\t\tcp = \"(null)\";\n\t\t\tif (prec >= 0) {\n\t\t\t\t/*\n\t\t\t\t * can't use strlen; can only look for the\n\t\t\t\t * NUL in the first `prec' characters, and\n\t\t\t\t * strlen() will go further.\n\t\t\t\t */\n\t\t\t\tchar *p = (char *)memchr(cp, 0, prec);\n\n\t\t\t\tif (p != NULL) {\n\t\t\t\t\tsize = p - cp;\n\t\t\t\t\tif (size > prec)\n\t\t\t\t\t\tsize = prec;\n\t\t\t\t} else\n\t\t\t\t\tsize = prec;\n\t\t\t} else\n\t\t\t\tsize = strlen(cp);\n\t\t\tsign = '\\0';\n\t\t\tbreak;\n\t\tcase 'U':\n\t\t\tflags |= LONGINT;\n\t\t\t/*FALLTHROUGH*/\n\t\tcase 'u':\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tif (flags & QUADINT)\n\t\t\t\tuqval = va_arg(ap, u_quad_t);\n\t\t\telse\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\tulval = UARG();\n\t\t\tbase = 10;\n\t\t\tgoto nosign;\n\t\tcase 'X':\n\t\t\txdigs = \"0123456789ABCDEF\";\n\t\t\tgoto hex;\n\t\tcase 'x':\n\t\t\txdigs = \"0123456789abcdef\";\nhex:\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tif (flags & QUADINT)\n\t\t\t\tuqval = va_arg(ap, u_quad_t);\n\t\t\telse\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\tulval = UARG();\n\t\t\tbase = 16;\n\t\t\t/* leading 0x/X only if non-zero */\n\t\t\tif (flags & ALT &&\n#ifdef _HAVE_SANE_QUAD_\n\t\t\t    (flags & QUADINT ? uqval != 0 : ulval != 0))\n#else /* _HAVE_SANE_QUAD_ */\n\t\t\t    ulval != 0)\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\tflags |= HEXPREFIX;\n\n\t\t\t/* unsigned conversions */\nnosign:\t\t\tsign = '\\0';\n\t\t\t/*\n\t\t\t * ``... diouXx conversions ... if a precision is\n\t\t\t * specified, the 0 flag will be ignored.''\n\t\t\t *\t-- ANSI X3J11\n\t\t\t */\nnumber:\t\t\tif ((dprec = prec) >= 0)\n\t\t\t\tflags &= ~ZEROPAD;\n\n\t\t\t/*\n\t\t\t * ``The result of converting a zero value with an\n\t\t\t * explicit precision of zero is no characters.''\n\t\t\t *\t-- ANSI X3J11\n\t\t\t */\n\t\t\tcp = buf + BUF;\n#ifdef _HAVE_SANE_QUAD_\n\t\t\tif (flags & QUADINT) {\n\t\t\t\tif (uqval != 0 || prec != 0)\n\t\t\t\t\tcp = __uqtoa(uqval, cp, base,\n\t\t\t\t\t    flags & ALT, xdigs);\n\t\t\t} else {\n#else /* _HAVE_SANE_QUAD_ */\n\t\t\t{\n#endif /* _HAVE_SANE_QUAD_ */\n\t\t\t\tif (ulval != 0 || prec != 0)\n\t\t\t\t\tcp = BSD__ultoa(ulval, cp, base,\n\t\t\t\t\t    flags & ALT, xdigs);\n\t\t\t}\n\t\t\tsize = buf + BUF - cp;\n\t\t\tbreak;\n\t\tdefault:\t/* \"%?\" prints ?, unless ? is NUL */\n\t\t\tif (ch == '\\0')\n\t\t\t\tgoto done;\n\t\t\t/* pretend it was %c with argument ch */\n\t\t\tcp = buf;\n\t\t\t*cp = ch;\n\t\t\tsize = 1;\n\t\t\tsign = '\\0';\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t * All reasonable formats wind up here.  At this point, `cp'\n\t\t * points to a string which (if not flags&LADJUST) should be\n\t\t * padded out to `width' places.  If flags&ZEROPAD, it should\n\t\t * first be prefixed by any sign or other prefix; otherwise,\n\t\t * it should be blank padded before the prefix is emitted.\n\t\t * After any left-hand padding and prefixing, emit zeroes\n\t\t * required by a decimal [diouxX] precision, then print the\n\t\t * string proper, then emit zeroes required by any leftover\n\t\t * floating precision; finally, if LADJUST, pad with blanks.\n\t\t *\n\t\t * Compute actual size, so we know how much to pad.\n\t\t * fieldsz excludes decimal prec; realsz includes it.\n\t\t */\n\t\tfieldsz = size;\n\t\tif (sign)\n\t\t\tfieldsz++;\n\t\telse if (flags & HEXPREFIX)\n\t\t\tfieldsz += 2;\n\t\trealsz = dprec > fieldsz ? dprec : fieldsz;\n\n\t\t/* right-adjusting blank padding */\n\t\tif ((flags & (LADJUST|ZEROPAD)) == 0)\n\t\t\tPAD(width - realsz, blanks);\n\n\t\t/* prefix */\n\t\tif (sign) {\n\t\t\tPRINT(&sign, 1);\n\t\t} else if (flags & HEXPREFIX) {\n\t\t\tox[0] = '0';\n\t\t\tox[1] = ch;\n\t\t\tPRINT(ox, 2);\n\t\t}\n\n\t\t/* right-adjusting zero padding */\n\t\tif ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)\n\t\t\tPAD(width - realsz, zeroes);\n\n\t\t/* leading zeroes from decimal precision */\n\t\tPAD(dprec - fieldsz, zeroes);\n\n\t\t/* the string or number proper */\n#ifdef FLOATING_POINT\n\t\tif ((flags & FPT) == 0) {\n\t\t\tPRINT(cp, size);\n\t\t} else {\t/* glue together f_p fragments */\n\t\t\tif (ch >= 'f') {\t/* 'f' or 'g' */\n\t\t\t\tif (_double == 0) {\n\t\t\t\t/* kludge for __dtoa irregularity */\n\t\t\t\t\tif (prec == 0 ||\n\t\t\t\t\t    (flags & ALT) == 0) {\n\t\t\t\t\t\tPRINT(\"0\", 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tPRINT(\"0.\", 2);\n\t\t\t\t\t\tPAD(ndig - 1, zeroes);\n\t\t\t\t\t}\n\t\t\t\t} else if (expt <= 0) {\n\t\t\t\t\tPRINT(\"0.\", 2);\n\t\t\t\t\tPAD(-expt, zeroes);\n\t\t\t\t\tPRINT(cp, ndig);\n\t\t\t\t} else if (expt >= ndig) {\n\t\t\t\t\tPRINT(cp, ndig);\n\t\t\t\t\tPAD(expt - ndig, zeroes);\n\t\t\t\t\tif (flags & ALT)\n\t\t\t\t\t\tPRINT(\".\", 1);\n\t\t\t\t} else {\n\t\t\t\t\tPRINT(cp, expt);\n\t\t\t\t\tcp += expt;\n\t\t\t\t\tPRINT(\".\", 1);\n\t\t\t\t\tPRINT(cp, ndig-expt);\n\t\t\t\t}\n\t\t\t} else {\t/* 'e' or 'E' */\n\t\t\t\tif (ndig > 1 || flags & ALT) {\n\t\t\t\t\tox[0] = *cp++;\n\t\t\t\t\tox[1] = '.';\n\t\t\t\t\tPRINT(ox, 2);\n\t\t\t\t\tif (_double || flags & ALT == 0) {\n\t\t\t\t\t\tPRINT(cp, ndig-1);\n\t\t\t\t\t} else\t/* 0.[0..] */\n\t\t\t\t\t\t/* __dtoa irregularity */\n\t\t\t\t\t\tPAD(ndig - 1, zeroes);\n\t\t\t\t} else\t/* XeYYY */\n\t\t\t\t\tPRINT(cp, 1);\n\t\t\t\tPRINT(expstr, expsize);\n\t\t\t}\n\t\t}\n#else\n\t\tPRINT(cp, size);\n#endif\n\t\t/* left-adjusting padding (always blank) */\n\t\tif (flags & LADJUST)\n\t\t\tPAD(width - realsz, blanks);\n\n\t\t/* finally, adjust ret */\n\t\tret += width > realsz ? width : realsz;\n\n\t\tFLUSH();\t/* copy out the I/O vectors */\n\t}\ndone:\n\tFLUSH();\nerror:\n\treturn (__sferror(fp) ? EOF : ret);\n\t/* NOTREACHED */\n}\n\n#ifdef FLOATING_POINT\n\nextern char *BSD__dtoa __P((double, int, int, int *, int *, char **));\n\nstatic char *\ncvt(value, ndigits, flags, sign, decpt, ch, length)\n\tdouble value;\n\tint ndigits, flags, *decpt, ch, *length;\n\tchar *sign;\n{\n\tint mode, dsgn;\n\tchar *digits, *bp, *rve;\n\n\tif (ch == 'f')\n\t\tmode = 3;\n\telse {\n\t\tmode = 2;\n\t}\n\tif (value < 0) {\n\t\tvalue = -value;\n\t\t*sign = '-';\n\t} else if (value == 0.0 && 1.0/value < 0) {\n\t    *sign = '-';\n\t} else {\n\t    *sign = '\\000';\n\t}\n\tdigits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);\n\tif (flags & ALT) {\t/* Print trailing zeros */\n\t\tbp = digits + ndigits;\n\t\tif (ch == 'f') {\n\t\t\tif (*digits == '0' && value)\n\t\t\t\t*decpt = -ndigits + 1;\n\t\t\tbp += *decpt;\n\t\t}\n\t\tif (value == 0)\t/* kludge for __dtoa irregularity */\n\t\t\trve = bp;\n\t\twhile (rve < bp)\n\t\t\t*rve++ = '0';\n\t}\n\t*length = rve - digits;\n\treturn (digits);\n}\n\nstatic int\nexponent(p0, exp, fmtch)\n\tchar *p0;\n\tint exp, fmtch;\n{\n\tregister char *p, *t;\n\tchar expbuf[MAXEXP];\n\n\tp = p0;\n\t*p++ = fmtch;\n\tif (exp < 0) {\n\t\texp = -exp;\n\t\t*p++ = '-';\n\t}\n\telse\n\t\t*p++ = '+';\n\tt = expbuf + MAXEXP;\n\tif (exp > 9) {\n\t\tdo {\n\t\t\t*--t = to_char(exp % 10);\n\t\t} while ((exp /= 10) > 9);\n\t\t*--t = to_char(exp);\n\t\tfor (; t < expbuf + MAXEXP; *p++ = *t++);\n\t}\n\telse {\n\t\t*p++ = '0';\n\t\t*p++ = to_char(exp);\n\t}\n\treturn (p - p0);\n}\n#endif /* FLOATING_POINT */\n\nint\nvsnprintf(str, n, fmt, ap)\n\tchar *str;\n\tsize_t n;\n\tconst char *fmt;\n\t_BSD_VA_LIST_ ap;\n{\n\tint ret;\n\tFILE f;\n\n\tif ((int)n < 1)\n\t\treturn (EOF);\n\tf._flags = __SWR | __SSTR;\n\tf._bf._base = f._p = (unsigned char *)str;\n\tf._bf._size = f._w = n - 1;\n\tret = BSD_vfprintf(&f, fmt, ap);\n\t*f._p = 0;\n\treturn (ret);\n}\n\n#if defined(LIBC_SCCS) && !defined(lint)\nstatic char sccsid[] = \"@(#)snprintf.c\t8.1 (Berkeley) 6/4/93\";\n#endif /* LIBC_SCCS and not lint */\n\n#if defined(__STDC__)\n# include <stdarg.h>\n#else\n# include <varargs.h>\n#endif\n\nint\n#if defined(__STDC__)\nsnprintf(char *str, size_t n, char const *fmt, ...)\n#else\nsnprintf(str, n, fmt, va_alist)\nchar *str, *fmt;\nsize_t n;\nva_dcl\n#endif\n{\n\tint ret;\n\tva_list ap;\n\tFILE f;\n\n\tif ((int)n < 1)\n\t\treturn (EOF);\n\n#if defined(__STDC__)\n\tva_start(ap, fmt);\n#else\n\tva_start(ap);\n#endif\n\tf._flags = __SWR | __SSTR;\n\tf._bf._base = f._p = (unsigned char *)str;\n\tf._bf._size = f._w = n - 1;\n\tret = BSD_vfprintf(&f, fmt, ap);\n\t*f._p = 0;\n\tva_end(ap);\n\treturn (ret);\n}\n"
  },
  {
    "path": "missing/x68.c",
    "content": "/* x68 compatibility functions -- follows Ruby's license */\n\n#include \"config.h\"\n\n#if !HAVE_SELECT\n#include \"x68/select.c\"\n#endif\n#if MISSING__DTOS18\n#include \"x68/_dtos18.c\"\n#endif\n#if MISSING_FCONVERT\n#include \"x68/_round.c\"\n#include \"x68/fconvert.c\"\n#endif\n\n/* missing some basic syscalls */\nint\nlink(const char *src, const char *dst)\n{\n    return symlink(src, dst);\n}\n\n#ifndef HAVE_GETTIMEOFDAY\n#include <time.h>\n#include <sys/time.h>\n\nstruct timezone {\n    int tz_minuteswest;\n    int tz_dsttime;\n};\n\nint\ngettimeofday(struct timeval *tv, struct timezone *tz)\n{\n    tv->tv_sec = (long)time((time_t*)0);\n    tv->tv_usec = 0;\n\n    return 0;\n}\n#endif\n"
  },
  {
    "path": "missing.h",
    "content": "/************************************************\n\n  missing.h - prototype for *.c in ./missing, and\n  \t      for missing timeval struct\n\n  $Author$\n  $Date$\n  created at: Sat May 11 23:46:03 JST 2002\n\n************************************************/\n\n#ifndef MISSING_H\n#define MISSING_H\n\n#if defined(HAVE_SYS_TIME_H)\n#  include <sys/time.h>\n#elif !defined(_WIN32)\n#  define time_t long\nstruct timeval {\n    time_t tv_sec;\t/* seconds */\n    time_t tv_usec;\t/* microseconds */\n};\n#endif\n#if defined(HAVE_SYS_TYPES_H)\n#  include <sys/types.h>\n#endif\n\n#ifndef HAVE_ACOSH\nextern double acosh _((double));\nextern double asinh _((double));\nextern double atanh _((double));\n#endif\n\n#ifndef HAVE_CRYPT\nextern char *crypt _((const char *, const char *));\n#endif\n\n#ifndef HAVE_DUP2\nextern int dup2 _((int, int));\n#endif\n\n#ifndef HAVE_EACCESS\nextern int eaccess _((const char*, int));\n#endif\n\n#ifndef HAVE_FINITE\nextern int finite _((double));\n#endif\n\n#ifndef HAVE_FLOCK\nextern int flock _((int, int));\n#endif\n\n/*\n#ifndef HAVE_FREXP\nextern double frexp _((double, int *));\n#endif\n*/\n\n#ifndef HAVE_HYPOT\nextern double hypot _((double, double));\n#endif\n\n#ifndef HAVE_ERF\nextern double erf _((double));\nextern double erfc _((double));\n#endif\n\n#ifndef HAVE_ISINF\n# if defined(HAVE_FINITE) && defined(HAVE_ISNAN)\n# define isinf(x) (!finite(x) && !isnan(x))\n# else\nextern int isinf _((double));\n# endif\n#endif\n\n#ifndef HAVE_ISNAN\nextern int isnan _((double));\n#endif\n\n/*\n#ifndef HAVE_MEMCMP\nextern int memcmp _((char *, char *, int));\n#endif\n*/\n\n#ifndef HAVE_MEMMOVE\nextern void *memmove _((void *, void *, int));\n#endif\n\n/*\n#ifndef HAVE_MODF\nextern double modf _((double, double *));\n#endif\n*/\n\n#ifndef HAVE_STRCASECMP\nextern int strcasecmp _((char *, char *));\n#endif\n\n#ifndef HAVE_STRNCASECMP\nextern int strncasecmp _((char *, char *, int));\n#endif\n\n#ifndef HAVE_STRCHR\nextern char *strchr _((char *, int));\nextern char *strrchr _((char *, int));\n#endif\n\n#ifndef HAVE_STRERROR\nextern char *strerror _((int));\n#endif\n\n#ifndef HAVE_STRFTIME\nextern size_t strftime _((char *, size_t, const char *, const struct tm *));\n#endif\n\n#ifndef HAVE_STRSTR\nextern char *strstr _((char *, char *));\n#endif\n\n/*\n#ifndef HAVE_STRTOL\nextern long strtol _((char *, char **, int));\n#endif\n*/\n\n#ifndef HAVE_STRTOUL\nextern unsigned long strtoul _((char *, char **, int));\n#endif\n\n#ifndef HAVE_VSNPRINTF\n# ifdef HAVE_STDARG_PROTOTYPES\n#  include <stdarg.h>\n# else\n#  include <varargs.h>\n# endif\nextern int snprintf __((char *, size_t n, char const *, ...));\nextern int vsnprintf _((char *, size_t n, char const *, va_list));\n#endif\n\n#endif /* MISSING_H */\n"
  },
  {
    "path": "mkconfig.rb",
    "content": "#!./miniruby -s\n\n# avoid warnings with -d.\n$install_name ||= nil\n$so_name ||= nil\n\nsrcdir = File.dirname(__FILE__)\n$:.replace [srcdir+\"/lib\"] unless defined?(CROSS_COMPILING)\n$:.unshift(\".\")\n\nrequire \"fileutils\"\nmkconfig = File.basename($0)\n\nrbconfig_rb = ARGV[0] || 'rbconfig.rb'\nunless File.directory?(dir = File.dirname(rbconfig_rb))\n  FileUtils.makedirs(dir, :verbose => true)\nend\n\nversion = RUBY_VERSION\ndef (config = \"\").write(arg)\n  concat(arg.to_s)\nend\n$stdout = config\n\nfast = {'prefix'=>TRUE, 'ruby_install_name'=>TRUE, 'INSTALL'=>TRUE, 'EXEEXT'=>TRUE}\nprint %[\n# This file was created by #{mkconfig} when ruby was built.  Any\n# changes made to this file will be lost the next time ruby is built.\n\nmodule Config\n  RUBY_VERSION == \"#{version}\" or\n    raise \"ruby lib version (#{version}) doesn't match executable version (\\#{RUBY_VERSION})\"\n\n]\n\nv_fast = []\nv_others = []\nvars = {}\nhas_version = false\ncontinued_name = nil\ncontinued_line = nil\nFile.foreach \"config.status\" do |line|\n  next if /^#/ =~ line\n  name = nil\n  case line\n  when /^s([%,])@(\\w+)@\\1(?:\\|\\#_!!_\\#\\|)?(.*)\\1/\n    name = $2\n    val = $3.gsub(/\\\\(?=,)/, '')\n  when /^S\\[\"(\\w+)\"\\]\\s*=\\s*\"(.*)\"\\s*(\\\\)?$/\n    name = $1\n    val = $2\n    if $3\n      continued_line = []\n      continued_line << val\n      continued_name = name\n      next\n    end\n  when /^\"(.+)\"\\s*(\\\\)?$/\n    if continued_line\n      continued_line <<  $1\n      unless $2\n\tval = continued_line.join(\"\")\n\tname = continued_name\n\tcontinued_line = nil\n      end\n    end\n  when /^(?:ac_given_)?INSTALL=(.*)/\n    v_fast << \"  CONFIG[\\\"INSTALL\\\"] = \" + $1 + \"\\n\"\n  end\n\n  if name\n    next if /^(?:ac_.*|configure_input|(?:top_)?srcdir|\\w+OBJS)$/ =~ name\n    next if /^\\$\\(ac_\\w+\\)$/ =~ val\n    next if /^\\$\\{ac_\\w+\\}$/ =~ val\n    next if /^\\$ac_\\w+$/ =~ val\n    next if $install_name and /^RUBY_INSTALL_NAME$/ =~ name\n    next if $so_name and /^RUBY_SO_NAME$/ =~  name\n    next if /^(?:X|(?:MINI|RUN)RUBY$)/ =~ name\n    if /^program_transform_name$/ =~ name and /^s(\\\\?.)(.*)\\1$/ =~ val\n      next if $install_name\n      sep = %r\"#{Regexp.quote($1)}\"\n      ptn = $2.sub(/\\$\\$/, '$').split(sep, 2)\n      name = \"ruby_install_name\"\n      val = \"ruby\".sub(/#{ptn[0]}/, ptn[1])\n    end\n    val.gsub!(/ +(?!-)/, \"=\") if name == \"configure_args\" && /mswin32/ =~ RUBY_PLATFORM\n    val = val.gsub(/\\$(?:\\$|\\{?(\\w+)\\}?)/) {$1 ? \"$(#{$1})\" : $&}.dump\n    if /^prefix$/ =~ name\n      val = \"(TOPDIR || DESTDIR + #{val})\"\n    end\n    v = \"  CONFIG[\\\"#{name}\\\"] #{vars[name] ? '<< \"\\n\"' : '='} #{val}\\n\"\n    vars[name] = true\n    if fast[name]\n      v_fast << v\n    else\n      v_others << v\n    end\n    has_version = true if name == \"MAJOR\"\n  end\n#  break if /^CEOF/\nend\n\ndrive = File::PATH_SEPARATOR == ';'\n\nprefix = '/lib/ruby/' + RUBY_VERSION.sub(/\\.\\d+$/, '') + '/' + RUBY_PLATFORM\nprint \"  TOPDIR = File.dirname(__FILE__).chomp!(#{prefix.dump})\\n\"\nprint \"  DESTDIR = \", (drive ? \"TOPDIR && TOPDIR[/\\\\A[a-z]:/i] || \" : \"\"), \"'' unless defined? DESTDIR\\n\"\nprint \"  CONFIG = {}\\n\"\nprint \"  CONFIG[\\\"DESTDIR\\\"] = DESTDIR\\n\"\n\nunless has_version\n  RUBY_VERSION.scan(/(\\d+)\\.(\\d+)\\.(\\d+)/) {\n    print \"  CONFIG[\\\"MAJOR\\\"] = \\\"\" + $1 + \"\\\"\\n\"\n    print \"  CONFIG[\\\"MINOR\\\"] = \\\"\" + $2 + \"\\\"\\n\"\n    print \"  CONFIG[\\\"TEENY\\\"] = \\\"\" + $3 + \"\\\"\\n\"\n  }\n  patchlevel = IO.foreach(File.join(srcdir, \"version.h\")) {|l|\n    m = /^\\s*#\\s*define\\s+RUBY_PATCHLEVEL\\s+(\\d+)/.match(l) and break m[1]\n  }\n  print \"  CONFIG[\\\"PATCHLEVEL\\\"] = \\\"#{patchlevel}\\\"\\n\"\nend\n\ndest = drive ? /= \\\"(?!\\$[\\(\\{])(?:[a-z]:)?/i : /= \\\"(?!\\$[\\(\\{])/\nv_others.collect! do |x|\n  if /^\\s*CONFIG\\[\"(?!abs_|old)[a-z]+(?:_prefix|dir)\"\\]/ === x\n    x.sub(dest, '= \"$(DESTDIR)')\n  else\n    x\n  end\nend\n\nif $install_name\n  v_fast << \"  CONFIG[\\\"ruby_install_name\\\"] = \\\"\" + $install_name + \"\\\"\\n\"\n  v_fast << \"  CONFIG[\\\"RUBY_INSTALL_NAME\\\"] = \\\"\" + $install_name + \"\\\"\\n\"\nend\nif $so_name\n  v_fast << \"  CONFIG[\\\"RUBY_SO_NAME\\\"] = \\\"\" + $so_name + \"\\\"\\n\"\nend\n\nprint(*v_fast)\nprint(*v_others)\nprint <<EOS\n  CONFIG[\"ruby_version\"] = \"$(MAJOR).$(MINOR)\"\n  CONFIG[\"rubylibdir\"] = \"$(libdir)/ruby/$(ruby_version)\"\n  CONFIG[\"archdir\"] = \"$(rubylibdir)/$(arch)\"\n  CONFIG[\"sitelibdir\"] = \"$(sitedir)/$(ruby_version)\"\n  CONFIG[\"sitearchdir\"] = \"$(sitelibdir)/$(sitearch)\"\n  CONFIG[\"vendorlibdir\"] = \"$(vendordir)/$(ruby_version)\"\n  CONFIG[\"vendorarchdir\"] = \"$(vendorlibdir)/$(sitearch)\"\n  CONFIG[\"topdir\"] = File.dirname(__FILE__)\n  MAKEFILE_CONFIG = {}\n  CONFIG.each{|k,v| MAKEFILE_CONFIG[k] = v.dup}\n  def Config::expand(val, config = CONFIG)\n    val.gsub!(/\\\\$\\\\$|\\\\$\\\\(([^()]+)\\\\)|\\\\$\\\\{([^{}]+)\\\\}/) do |var|\n      if !(v = $1 || $2)\n\t'$'\n      elsif key = config[v = v[/\\\\A[^:]+(?=(?::(.*?)=(.*))?\\\\z)/]]\n\tpat, sub = $1, $2\n\tconfig[v] = false\n\tConfig::expand(key, config)\n\tconfig[v] = key\n\tkey = key.gsub(/\\#{Regexp.quote(pat)}(?=\\\\s|\\\\z)/n) {sub} if pat\n\tkey\n      else\n\tvar\n      end\n    end\n    val\n  end\n  CONFIG.each_value do |val|\n    Config::expand(val)\n  end\nend\nRbConfig = Config # compatibility for ruby-1.9\nCROSS_COMPILING = nil unless defined? CROSS_COMPILING\nEOS\n\n$stdout = STDOUT\nmode = IO::RDWR|IO::CREAT\nmode |= IO::BINARY if defined?(IO::BINARY)\nopen(rbconfig_rb, mode) do |f|\n  if $timestamp and f.stat.size == config.size and f.read == config\n    puts \"#{rbconfig_rb} unchanged\"\n  else\n    puts \"#{rbconfig_rb} updated\"\n    f.rewind\n    f.truncate(0)\n    f.print(config)\n  end\nend\nif String === $timestamp\n  FileUtils.touch($timestamp)\nend\n\n# vi:set sw=2:\n"
  },
  {
    "path": "node.h",
    "content": "/**********************************************************************\n\n  node.h -\n\n  $Author$\n  $Date$\n  created at: Fri May 28 15:14:02 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef NODE_H\n#define NODE_H\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\nenum node_type {\n    NODE_METHOD,\n    NODE_FBODY,\n    NODE_CFUNC,\n    NODE_SCOPE,\n    NODE_BLOCK,\n    NODE_IF,\n    NODE_CASE,\n    NODE_WHEN,\n    NODE_OPT_N,\n    NODE_WHILE,\n    NODE_UNTIL,\n    NODE_ITER,\n    NODE_FOR,\n    NODE_BREAK,\n    NODE_NEXT,\n    NODE_REDO,\n    NODE_RETRY,\n    NODE_BEGIN,\n    NODE_RESCUE,\n    NODE_RESBODY,\n    NODE_ENSURE,\n    NODE_AND,\n    NODE_OR,\n    NODE_NOT,\n    NODE_MASGN,\n    NODE_LASGN,\n    NODE_DASGN,\n    NODE_DASGN_CURR,\n    NODE_GASGN,\n    NODE_IASGN,\n    NODE_CDECL,\n    NODE_CVASGN,\n    NODE_CVDECL,\n    NODE_OP_ASGN1,\n    NODE_OP_ASGN2,\n    NODE_OP_ASGN_AND,\n    NODE_OP_ASGN_OR,\n    NODE_CALL,\n    NODE_FCALL,\n    NODE_VCALL,\n    NODE_SUPER,\n    NODE_ZSUPER,\n    NODE_ARRAY,\n    NODE_ZARRAY,\n    NODE_HASH,\n    NODE_RETURN,\n    NODE_YIELD,\n    NODE_LVAR,\n    NODE_DVAR,\n    NODE_GVAR,\n    NODE_IVAR,\n    NODE_CONST,\n    NODE_CVAR,\n    NODE_NTH_REF,\n    NODE_BACK_REF,\n    NODE_MATCH,\n    NODE_MATCH2,\n    NODE_MATCH3,\n    NODE_LIT,\n    NODE_STR,\n    NODE_DSTR,\n    NODE_XSTR,\n    NODE_DXSTR,\n    NODE_EVSTR,\n    NODE_DREGX,\n    NODE_DREGX_ONCE,\n    NODE_ARGS,\n    NODE_ARGSCAT,\n    NODE_ARGSPUSH,\n    NODE_SPLAT,\n    NODE_TO_ARY,\n    NODE_SVALUE,\n    NODE_BLOCK_ARG,\n    NODE_BLOCK_PASS,\n    NODE_DEFN,\n    NODE_DEFS,\n    NODE_ALIAS,\n    NODE_VALIAS,\n    NODE_UNDEF,\n    NODE_CLASS,\n    NODE_MODULE,\n    NODE_SCLASS,\n    NODE_COLON2,\n    NODE_COLON3,\n    NODE_CREF,\n    NODE_DOT2,\n    NODE_DOT3,\n    NODE_FLIP2,\n    NODE_FLIP3,\n    NODE_ATTRSET,\n    NODE_SELF,\n    NODE_NIL,\n    NODE_TRUE,\n    NODE_FALSE,\n    NODE_DEFINED,\n    NODE_NEWLINE,\n    NODE_POSTEXE,\n    NODE_ALLOCA,\n    NODE_DMETHOD,\n    NODE_BMETHOD,\n    NODE_MEMO,\n    NODE_IFUNC,\n    NODE_DSYM,\n    NODE_ATTRASGN,\n    NODE_LAST\n};\n\ntypedef struct RNode {\n    unsigned long flags;\n    char *nd_file;\n    union {\n\tstruct RNode *node;\n\tID id;\n\tVALUE value;\n\tVALUE (*cfunc)(ANYARGS);\n\tID *tbl;\n    } u1;\n    union {\n\tstruct RNode *node;\n\tID id;\n\tlong argc;\n\tVALUE value;\n    } u2;\n    union {\n\tstruct RNode *node;\n\tID id;\n\tlong state;\n\tstruct global_entry *entry;\n\tlong cnt;\n\tVALUE value;\n    } u3;\n} NODE;\n\nextern NODE *ruby_cref;\nextern NODE *ruby_top_cref;\n\n#define RNODE(obj)  (R_CAST(RNode)(obj))\n\n#define nd_type(n) ((int)(((RNODE(n))->flags>>FL_USHIFT)&0xff))\n#define nd_set_type(n,t) \\\n    RNODE(n)->flags=((RNODE(n)->flags&~FL_UMASK)|(((t)<<FL_USHIFT)&FL_UMASK))\n\n#define NODE_LSHIFT (FL_USHIFT+8)\n#define NODE_LMASK  (((long)1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)\n#define nd_line(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))\n#define nd_set_line(n,l) \\\n    RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))\n\n#define nd_head  u1.node\n#define nd_alen  u2.argc\n#define nd_next  u3.node\n\n#define nd_cond  u1.node\n#define nd_body  u2.node\n#define nd_else  u3.node\n\n#define nd_orig  u3.value\n\n#define nd_resq  u2.node\n#define nd_ensr  u3.node\n\n#define nd_1st   u1.node\n#define nd_2nd   u2.node\n\n#define nd_stts  u1.node\n\n#define nd_entry u3.entry\n#define nd_vid   u1.id\n#define nd_cflag u2.id\n#define nd_cval  u3.value\n\n#define nd_cnt   u3.cnt\n#define nd_tbl   u1.tbl\n\n#define nd_var   u1.node\n#define nd_ibdy  u2.node\n#define nd_iter  u3.node\n\n#define nd_value u2.node\n#define nd_aid   u3.id\n\n#define nd_lit   u1.value\n\n#define nd_frml  u1.node\n#define nd_rest  u2.node\n#define nd_opt   u1.node\n\n#define nd_recv  u1.node\n#define nd_mid   u2.id\n#define nd_args  u3.node\n\n#define nd_noex  u1.id\n#define nd_defn  u3.node\n\n#define nd_cfnc  u1.cfunc\n#define nd_argc  u2.argc\n\n#define nd_cpath u1.node\n#define nd_super u3.node\n\n#define nd_modl  u1.id\n#define nd_clss  u1.value\n\n#define nd_beg   u1.node\n#define nd_end   u2.node\n#define nd_state u3.state\n#define nd_rval  u2.value\n\n#define nd_nth   u2.argc\n\n#define nd_tag   u1.id\n#define nd_tval  u2.value\n\n// Default node allocator\n#define NEW_NODE(t,a0,a1,a2) rb_node_newnode_longlife((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))\n\n// Specific node allocators\n#define NEW_NODE_EDEN(t,a0,a1,a2) rb_node_newnode_eden((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))\n#define NEW_NODE_LONGLIFE(t,a0,a1,a2) rb_node_newnode_longlife((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))\n\n/* IFUNC nodes are created whenever an enumeration runs; see rb_iterate(). For\n   this reason, they're allocated in ordinary heap. */\n#define NEW_IFUNC(f,c) NEW_NODE_EDEN(NODE_IFUNC,f,c,0)\n\n#define NEW_METHOD(n,x) NEW_NODE(NODE_METHOD,x,n,0)\n#define NEW_FBODY(n,i,o) NEW_NODE(NODE_FBODY,n,i,o)\n#define NEW_DEFN(i,a,d,p) NEW_NODE(NODE_DEFN,p,i,NEW_RFUNC(a,d))\n#define NEW_DEFS(r,i,a,d) NEW_NODE(NODE_DEFS,r,i,NEW_RFUNC(a,d))\n#define NEW_CFUNC(f,c) NEW_NODE(NODE_CFUNC,f,c,0)\n#define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))\n#define NEW_SCOPE(b) NEW_NODE(NODE_SCOPE,local_tbl(),0,(b))\n#define NEW_BLOCK(a) NEW_NODE(NODE_BLOCK,a,0,0)\n#define NEW_IF(c,t,e) NEW_NODE(NODE_IF,c,t,e)\n#define NEW_UNLESS(c,t,e) NEW_IF(c,e,t)\n#define NEW_CASE(h,b) NEW_NODE(NODE_CASE,h,b,0)\n#define NEW_WHEN(c,t,e) NEW_NODE(NODE_WHEN,c,t,e)\n#define NEW_OPT_N(b) NEW_NODE(NODE_OPT_N,0,b,0)\n#define NEW_WHILE(c,b,n) NEW_NODE(NODE_WHILE,c,b,n)\n#define NEW_UNTIL(c,b,n) NEW_NODE(NODE_UNTIL,c,b,n)\n#define NEW_FOR(v,i,b) NEW_NODE(NODE_FOR,v,b,i)\n#define NEW_ITER(v,i,b) NEW_NODE(NODE_ITER,v,b,i)\n#define NEW_BREAK(s) NEW_NODE(NODE_BREAK,s,0,0)\n#define NEW_NEXT(s) NEW_NODE(NODE_NEXT,s,0,0)\n#define NEW_REDO() NEW_NODE(NODE_REDO,0,0,0)\n#define NEW_RETRY() NEW_NODE(NODE_RETRY,0,0,0)\n#define NEW_BEGIN(b) NEW_NODE(NODE_BEGIN,0,b,0)\n#define NEW_RESCUE(b,res,e) NEW_NODE(NODE_RESCUE,b,res,e)\n#define NEW_RESBODY(a,ex,n) NEW_NODE(NODE_RESBODY,n,ex,a)\n#define NEW_ENSURE(b,en) NEW_NODE(NODE_ENSURE,b,0,en)\n#define NEW_RETURN(s) NEW_NODE(NODE_RETURN,s,0,0)\n#define NEW_YIELD(a,s) NEW_NODE(NODE_YIELD,a,0,s)\n#define NEW_LIST(a)  NEW_ARRAY(a)\n#define NEW_ARRAY(a) NEW_NODE(NODE_ARRAY,a,1,0)\n#define NEW_ZARRAY() NEW_NODE(NODE_ZARRAY,0,0,0)\n#define NEW_HASH(a)  NEW_NODE(NODE_HASH,a,0,0)\n#define NEW_NOT(a)   NEW_NODE(NODE_NOT,0,a,0)\n#define NEW_MASGN(l,r)   NEW_NODE(NODE_MASGN,l,0,r)\n#define NEW_GASGN(v,val) NEW_NODE(NODE_GASGN,v,val,rb_global_entry(v))\n#define NEW_LASGN(v,val) NEW_NODE(NODE_LASGN,v,val,local_cnt(v))\n#define NEW_DASGN(v,val) NEW_NODE(NODE_DASGN,v,val,0)\n#define NEW_DASGN_CURR(v,val) NEW_NODE(NODE_DASGN_CURR,v,val,0)\n#define NEW_IASGN(v,val) NEW_NODE(NODE_IASGN,v,val,0)\n#define NEW_CDECL(v,val,path) NEW_NODE(NODE_CDECL,v,val,path)\n#define NEW_CVASGN(v,val) NEW_NODE(NODE_CVASGN,v,val,0)\n#define NEW_CVDECL(v,val) NEW_NODE(NODE_CVDECL,v,val,0)\n#define NEW_OP_ASGN1(p,id,a) NEW_NODE(NODE_OP_ASGN1,p,id,a)\n#define NEW_OP_ASGN2(r,i,o,val) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o))\n#define NEW_OP_ASGN22(i,o) NEW_NODE(NODE_OP_ASGN2,i,o,rb_id_attrset(i))\n#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)\n#define NEW_OP_ASGN_AND(i,val) NEW_NODE(NODE_OP_ASGN_AND,i,val,0)\n#define NEW_GVAR(v) NEW_NODE(NODE_GVAR,v,0,rb_global_entry(v))\n#define NEW_LVAR(v) NEW_NODE(NODE_LVAR,v,0,local_cnt(v))\n#define NEW_DVAR(v) NEW_NODE(NODE_DVAR,v,0,0)\n#define NEW_IVAR(v) NEW_NODE(NODE_IVAR,v,0,0)\n#define NEW_CONST(v) NEW_NODE(NODE_CONST,v,0,0)\n#define NEW_CVAR(v) NEW_NODE(NODE_CVAR,v,0,0)\n#define NEW_NTH_REF(n)  NEW_NODE(NODE_NTH_REF,0,n,local_cnt('~'))\n#define NEW_BACK_REF(n) NEW_NODE(NODE_BACK_REF,0,n,local_cnt('~'))\n#define NEW_MATCH(c) NEW_NODE(NODE_MATCH,c,0,0)\n#define NEW_MATCH2(n1,n2) NEW_NODE(NODE_MATCH2,n1,n2,0)\n#define NEW_MATCH3(r,n2) NEW_NODE(NODE_MATCH3,r,n2,0)\n#define NEW_LIT(l) NEW_NODE(NODE_LIT,l,0,0)\n#define NEW_STR(s) NEW_NODE(NODE_STR,s,0,0)\n#define NEW_DSTR(s) NEW_NODE(NODE_DSTR,s,1,0)\n#define NEW_XSTR(s) NEW_NODE(NODE_XSTR,s,0,0)\n#define NEW_DXSTR(s) NEW_NODE(NODE_DXSTR,s,0,0)\n#define NEW_DSYM(s,l) NEW_NODE(NODE_DSYM,s,1,l)\n#define NEW_EVSTR(n) NEW_NODE(NODE_EVSTR,0,(n),0)\n#define NEW_CALL(r,m,a) NEW_NODE(NODE_CALL,r,m,a)\n#define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)\n#define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)\n#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)\n#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)\n#define NEW_ARGS(f,o,r) NEW_NODE(NODE_ARGS,o,r,f)\n#define NEW_ARGSCAT(a,b) NEW_NODE(NODE_ARGSCAT,a,b,0)\n#define NEW_ARGSPUSH(a,b) NEW_NODE(NODE_ARGSPUSH,a,b,0)\n#define NEW_SPLAT(a) NEW_NODE(NODE_SPLAT,a,0,0)\n#define NEW_TO_ARY(a) NEW_NODE(NODE_TO_ARY,a,0,0)\n#define NEW_SVALUE(a) NEW_NODE(NODE_SVALUE,a,0,0)\n#define NEW_BLOCK_ARG(v) NEW_NODE(NODE_BLOCK_ARG,v,0,local_cnt(v))\n#define NEW_BLOCK_PASS(b) NEW_NODE(NODE_BLOCK_PASS,0,b,0)\n#define NEW_ALIAS(n,o) NEW_NODE(NODE_ALIAS,n,o,0)\n#define NEW_VALIAS(n,o) NEW_NODE(NODE_VALIAS,n,o,0)\n#define NEW_UNDEF(i) NEW_NODE(NODE_UNDEF,0,i,0)\n#define NEW_CLASS(n,b,s) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(b),(s))\n#define NEW_SCLASS(r,b) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(b),0)\n#define NEW_MODULE(n,b) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(b),0)\n#define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0)\n#define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0)\n#define NEW_CREF(c,n) NEW_NODE(NODE_CREF,c,0,n)\n#define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0)\n#define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0)\n#define NEW_ATTRSET(a) NEW_NODE(NODE_ATTRSET,a,0,0)\n#define NEW_SELF() NEW_NODE(NODE_SELF,0,0,0)\n#define NEW_NIL() NEW_NODE(NODE_NIL,0,0,0)\n#define NEW_TRUE() NEW_NODE(NODE_TRUE,0,0,0)\n#define NEW_FALSE() NEW_NODE(NODE_FALSE,0,0,0)\n#define NEW_DEFINED(e) NEW_NODE(NODE_DEFINED,e,0,0)\n#define NEW_NEWLINE(n) NEW_NODE(NODE_NEWLINE,0,0,n)\n#define NEW_PREEXE(b) NEW_SCOPE(b)\n#define NEW_POSTEXE() NEW_NODE(NODE_POSTEXE,0,0,0)\n#define NEW_DMETHOD(b) NEW_NODE(NODE_DMETHOD,0,0,b)\n#define NEW_BMETHOD(b) NEW_NODE(NODE_BMETHOD,0,0,b)\n#define NEW_ATTRASGN(r,m,a) NEW_NODE(NODE_ATTRASGN,r,m,a)\n\n#define NOEX_PUBLIC    0\n#define NOEX_NOSUPER   1\n#define NOEX_PRIVATE   2\n#define NOEX_PROTECTED 4\n#define NOEX_MASK      6\n\n#define NOEX_UNDEF     NOEX_NOSUPER\n\nNODE *rb_compile_cstr _((const char*, const char*, int, int));\nNODE *rb_compile_string _((const char*, VALUE, int));\nNODE *rb_compile_file _((const char*, VALUE, int));\n\nvoid rb_add_method _((VALUE, ID, NODE *, int));\nNODE *rb_node_newnode_eden _((enum node_type,VALUE,VALUE,VALUE));\nNODE *rb_node_newnode_longlife _((enum node_type,VALUE,VALUE,VALUE));\n\nNODE* rb_method_node _((VALUE klass, ID id));\n\nstruct global_entry *rb_global_entry _((ID));\nVALUE rb_gvar_get _((struct global_entry *));\nVALUE rb_gvar_set _((struct global_entry *, VALUE));\nVALUE rb_gvar_defined _((struct global_entry *));\n\ntypedef unsigned int rb_event_t;\n\n#define RUBY_EVENT_NONE     0x00\n#define RUBY_EVENT_LINE     0x01\n#define RUBY_EVENT_CLASS    0x02\n#define RUBY_EVENT_END      0x04\n#define RUBY_EVENT_CALL     0x08\n#define RUBY_EVENT_RETURN   0x10\n#define RUBY_EVENT_C_CALL   0x20\n#define RUBY_EVENT_C_RETURN 0x40\n#define RUBY_EVENT_RAISE    0x80\n#define RUBY_EVENT_ALL      0xff\n\ntypedef void (*rb_event_hook_func_t) _((rb_event_t,NODE*,VALUE,ID,VALUE));\nNODE *rb_copy_node_scope _((NODE *, NODE *));\nvoid rb_add_event_hook _((rb_event_hook_func_t,rb_event_t));\nint rb_remove_event_hook _((rb_event_hook_func_t));\n\n#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)\n#include <ucontext.h>\n#define USE_CONTEXT\n#endif\n#include <setjmp.h>\n#include \"st.h\"\n\n#ifdef USE_CONTEXT\ntypedef struct {\n    ucontext_t context;\n    volatile int status;\n} rb_jmpbuf_t[1];\n#else\ntypedef RUBY_JMP_BUF rb_jmpbuf_t;\n#endif\n\nenum rb_thread_status {\n    THREAD_TO_KILL,\n    THREAD_RUNNABLE,\n    THREAD_STOPPED,\n    THREAD_KILLED,\n};\n\ntypedef struct rb_thread *rb_thread_t;\n\nstruct rb_thread {\n    rb_thread_t next, prev;\n    rb_jmpbuf_t context;\n#if (defined _WIN32 && !defined _WIN32_WCE) || defined __CYGWIN__\n    unsigned long win32_exception_list;\n#endif\n\n    VALUE result;\n\n    size_t stk_len;\n    size_t stk_max;\n    size_t stk_size;\n    VALUE *stk_ptr;\n    VALUE *stk_pos;\n    VALUE *stk_base;\n    VALUE *guard;\n    VALUE *gc_stack_end;\n#ifdef __ia64\n    size_t bstr_len;\n    size_t bstr_max;\n    VALUE *bstr_ptr;\n    VALUE *bstr_pos;\n#endif\n\n    struct FRAME *frame;\n    struct SCOPE *scope;\n    struct RVarmap *dyna_vars;\n    struct BLOCK *block;\n    struct iter *iter;\n    struct tag *tag;\n    VALUE klass;\n    VALUE wrapper;\n    NODE *cref;\n\n    int flags;\t\t/* misc. states (vmode/rb_trap_immediate/raised) */\n\n    NODE *node;\n\n    int tracing;\n    VALUE errinfo;\n    VALUE last_status;\n    VALUE last_line;\n    VALUE last_match;\n\n    int safe;\n\n    enum rb_thread_status status;\n    int wait_for;\n    int fd;\n    fd_set readfds;\n    fd_set writefds;\n    fd_set exceptfds;\n\n    /* The following scratch structs are exclusively used in\n       eval.c:rb_thread_schedule() to remove pressure from\n       the stack. */\n    fd_set scratch_readfds;\n    fd_set scratch_writefds;\n    fd_set scratch_exceptfds;\n    struct timeval scratch_delay_tv;\n\n    int select_value;\n    double delay;\n    rb_thread_t join;\n\n    int abort;\n    int priority;\n    VALUE thgroup;\n\n    struct st_table *locals;\n\n    VALUE thread;\n\n    VALUE sandbox;\n};\n\nextern VALUE (*ruby_sandbox_save)_((rb_thread_t));\nextern VALUE (*ruby_sandbox_restore)_((rb_thread_t));\nextern rb_thread_t rb_curr_thread;\nextern rb_thread_t rb_main_thread;\n\nenum {\n    RAISED_EXCEPTION     = 0x1000,\n    RAISED_STACKOVERFLOW = 0x2000,\n    RAISED_NOMEMORY      = 0x4000,\n    RAISED_MASK          = 0xf000\n};\nint rb_thread_set_raised(rb_thread_t th);\nint rb_thread_reset_raised(rb_thread_t th);\n#define rb_thread_raised_set(th, f)   ((th)->flags |= (f))\n#define rb_thread_raised_reset(th, f) ((th)->flags &= ~(f))\n#define rb_thread_raised_p(th, f)     (((th)->flags & (f)) != 0)\n#define rb_thread_raised_clear(th)    (rb_thread_raised_reset(th, RAISED_MASK))\n\n#if defined(__cplusplus)\n}  /* extern \"C\" { */\n#endif\n\n#endif\n"
  },
  {
    "path": "numeric.c",
    "content": "/**********************************************************************\n\n  numeric.c -\n\n  $Author$\n  $Date$\n  created at: Fri Aug 13 18:33:09 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"env.h\"\n#include <ctype.h>\n#include <math.h>\n#include <stdio.h>\n\n#if defined(__FreeBSD__) && __FreeBSD__ < 4\n#include <floatingpoint.h>\n#endif\n\n#ifdef HAVE_FLOAT_H\n#include <float.h>\n#endif\n\n#ifdef HAVE_IEEEFP_H\n#include <ieeefp.h>\n#endif\n\n/* use IEEE 64bit values if not defined */\n#ifndef FLT_RADIX\n#define FLT_RADIX 2\n#endif\n#ifndef FLT_ROUNDS\n#define FLT_ROUNDS 1\n#endif\n#ifndef DBL_MIN\n#define DBL_MIN 2.2250738585072014e-308\n#endif\n#ifndef DBL_MAX\n#define DBL_MAX 1.7976931348623157e+308\n#endif\n#ifndef DBL_MIN_EXP\n#define DBL_MIN_EXP (-1021)\n#endif\n#ifndef DBL_MAX_EXP\n#define DBL_MAX_EXP 1024\n#endif\n#ifndef DBL_MIN_10_EXP\n#define DBL_MIN_10_EXP (-307)\n#endif\n#ifndef DBL_MAX_10_EXP\n#define DBL_MAX_10_EXP 308\n#endif\n#ifndef DBL_DIG\n#define DBL_DIG 15\n#endif\n#ifndef DBL_MANT_DIG\n#define DBL_MANT_DIG 53\n#endif\n#ifndef DBL_EPSILON\n#define DBL_EPSILON 2.2204460492503131e-16\n#endif\n\nextern double round _((double));\n\n#ifndef HAVE_ROUND\ndouble\nround(x)\n    double x;\n{\n    double f;\n\n    if (x > 0.0) {\n\tf = floor(x);\n\tx = f + (x - f >= 0.5);\n    }\n    else if (x < 0.0) {\n\tf = ceil(x);\n\tx = f - (f - x >= 0.5);\n    }\n    return x;\n}\n#endif\n\nstatic ID id_coerce, id_to_i, id_eq;\n\nVALUE rb_cNumeric;\nVALUE rb_cFloat;\nVALUE rb_cInteger;\nVALUE rb_cFixnum;\n\nVALUE rb_eZeroDivError;\nVALUE rb_eFloatDomainError;\n\nvoid\nrb_num_zerodiv()\n{\n    rb_raise(rb_eZeroDivError, \"divided by 0\");\n}\n\n\n/*\n *  call-seq:\n *     num.coerce(numeric)   => array\n *\n *  If <i>aNumeric</i> is the same type as <i>num</i>, returns an array\n *  containing <i>aNumeric</i> and <i>num</i>. Otherwise, returns an\n *  array with both <i>aNumeric</i> and <i>num</i> represented as\n *  <code>Float</code> objects. This coercion mechanism is used by\n *  Ruby to handle mixed-type numeric operations: it is intended to\n *  find a compatible common type between the two operands of the operator.\n *\n *     1.coerce(2.5)   #=> [2.5, 1.0]\n *     1.2.coerce(3)   #=> [3.0, 1.2]\n *     1.coerce(2)     #=> [2, 1]\n */\n\nstatic VALUE\nnum_coerce(x, y)\n    VALUE x, y;\n{\n    if (CLASS_OF(x) == CLASS_OF(y))\n\treturn rb_assoc_new(y, x);\n    x = rb_Float(x);\n    y = rb_Float(y);\n    return rb_assoc_new(y, x);\n}\n\nstatic VALUE\ncoerce_body(x)\n    VALUE *x;\n{\n    return rb_funcall(x[1], id_coerce, 1, x[0]);\n}\n\nstatic VALUE\ncoerce_rescue(x)\n    VALUE *x;\n{\n    volatile VALUE v = rb_inspect(x[1]);\n\n    rb_raise(rb_eTypeError, \"%s can't be coerced into %s\",\n\t     rb_special_const_p(x[1])?\n\t     RSTRING(v)->ptr:\n\t     rb_obj_classname(x[1]),\n\t     rb_obj_classname(x[0]));\n    return Qnil;\t\t/* dummy */\n}\n\nstatic int\ndo_coerce(x, y, err)\n    VALUE *x, *y;\n    int err;\n{\n    VALUE ary;\n    VALUE a[2];\n\n    a[0] = *x; a[1] = *y;\n\n    ary = rb_rescue(coerce_body, (VALUE)a, err?coerce_rescue:0, (VALUE)a);\n    if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {\n\tif (err) {\n\t    rb_raise(rb_eTypeError, \"coerce must return [x, y]\");\n\t}\n\treturn Qfalse;\n    }\n\n    *x = RARRAY(ary)->ptr[0];\n    *y = RARRAY(ary)->ptr[1];\n    return Qtrue;\n}\n\nVALUE\nrb_num_coerce_bin(x, y)\n    VALUE x, y;\n{\n    do_coerce(&x, &y, Qtrue);\n    return rb_funcall(x, ruby_frame->orig_func, 1, y);\n}\n\nVALUE\nrb_num_coerce_cmp(x, y)\n    VALUE x, y;\n{\n    if (do_coerce(&x, &y, Qfalse))\n\treturn rb_funcall(x, ruby_frame->orig_func, 1, y);\n    return Qnil;\n}\n\nVALUE\nrb_num_coerce_relop(x, y)\n    VALUE x, y;\n{\n    VALUE c, x0 = x, y0 = y;\n\n    if (!do_coerce(&x, &y, Qfalse) ||\n\tNIL_P(c = rb_funcall(x, ruby_frame->orig_func, 1, y))) {\n\trb_cmperr(x0, y0);\n\treturn Qnil;\t\t/* not reached */\n    }\n    return c;\n}\n\n/*\n * Trap attempts to add methods to <code>Numeric</code> objects. Always\n * raises a <code>TypeError</code>\n */\n\nstatic VALUE\nnum_sadded(x, name)\n    VALUE x, name;\n{\n    ruby_frame = ruby_frame->prev; /* pop frame for \"singleton_method_added\" */\n    /* Numerics should be values; singleton_methods should not be added to them */\n    rb_raise(rb_eTypeError,\n\t     \"can't define singleton method \\\"%s\\\" for %s\",\n\t     rb_id2name(rb_to_id(name)),\n\t     rb_obj_classname(x));\n    return Qnil;\t\t/* not reached */\n}\n\n/* :nodoc: */\nstatic VALUE\nnum_init_copy(x, y)\n    VALUE x, y;\n{\n    /* Numerics are immutable values, which should not be copied */\n    rb_raise(rb_eTypeError, \"can't copy %s\", rb_obj_classname(x));\n    return Qnil;\t\t/* not reached */\n}\n\n/*\n *  call-seq:\n *     +num    => num\n *\n *  Unary Plus---Returns the receiver's value.\n */\n\nstatic VALUE\nnum_uplus(num)\n    VALUE num;\n{\n    return num;\n}\n\n/*\n *  call-seq:\n *     -num    => numeric\n *\n *  Unary Minus---Returns the receiver's value, negated.\n */\n\nstatic VALUE\nnum_uminus(num)\n    VALUE num;\n{\n    VALUE zero;\n\n    zero = INT2FIX(0);\n    do_coerce(&zero, &num, Qtrue);\n\n    return rb_funcall(zero, '-', 1, num);\n}\n\n/*\n *  call-seq:\n *     num.quo(numeric)    =>   result\n *     num.fdiv(numeric)   =>   result\n *\n *  Equivalent to <code>Numeric#/</code>, but overridden in subclasses.\n */\n\nstatic VALUE\nnum_quo(x, y)\n    VALUE x, y;\n{\n    return rb_funcall(x, '/', 1, y);\n}\n\n\nstatic VALUE num_floor(VALUE num);\n\n/*\n *  call-seq:\n *     num.div(numeric)    => integer\n *\n *  Uses <code>/</code> to perform division, then converts the result to\n *  an integer. <code>Numeric</code> does not define the <code>/</code>\n *  operator; this is left to subclasses.\n */\n\nstatic VALUE\nnum_div(x, y)\n    VALUE x, y;\n{\n    return num_floor(rb_funcall(x, '/', 1, y));\n}\n\n\n\n/*\n *  call-seq:\n *     num.divmod( aNumeric ) -> anArray\n *\n *  Returns an array containing the quotient and modulus obtained by\n *  dividing <i>num</i> by <i>aNumeric</i>. If <code>q, r =\n *  x.divmod(y)</code>, then\n *\n *      q = floor(float(x)/float(y))\n *      x = q*y + r\n *\n *  The quotient is rounded toward -infinity, as shown in the following table:\n *\n *     a    |  b  |  a.divmod(b)  |   a/b   | a.modulo(b) | a.remainder(b)\n *    ------+-----+---------------+---------+-------------+---------------\n *     13   |  4  |   3,    1     |   3     |    1        |     1\n *    ------+-----+---------------+---------+-------------+---------------\n *     13   | -4  |  -4,   -3     |  -3     |   -3        |     1\n *    ------+-----+---------------+---------+-------------+---------------\n *    -13   |  4  |  -4,    3     |  -4     |    3        |    -1\n *    ------+-----+---------------+---------+-------------+---------------\n *    -13   | -4  |   3,   -1     |   3     |   -1        |    -1\n *    ------+-----+---------------+---------+-------------+---------------\n *     11.5 |  4  |   2,    3.5   |   2.875 |    3.5      |     3.5\n *    ------+-----+---------------+---------+-------------+---------------\n *     11.5 | -4  |  -3,   -0.5   |  -2.875 |   -0.5      |     3.5\n *    ------+-----+---------------+---------+-------------+---------------\n *    -11.5 |  4  |  -3,    0.5   |  -2.875 |    0.5      |    -3.5\n *    ------+-----+---------------+---------+-------------+---------------\n *    -11.5 | -4  |   2    -3.5   |   2.875 |   -3.5      |    -3.5\n *\n *\n *  Examples\n *     11.divmod(3)         #=> [3, 2]\n *     11.divmod(-3)        #=> [-4, -1]\n *     11.divmod(3.5)       #=> [3, 0.5]\n *     (-11).divmod(3.5)    #=> [-4, 3.0]\n *     (11.5).divmod(3.5)   #=> [3, 1.0]\n */\n\nstatic VALUE\nnum_divmod(x, y)\n    VALUE x, y;\n{\n    return rb_assoc_new(num_div(x, y), rb_funcall(x, '%', 1, y));\n}\n\n/*\n *  call-seq:\n *     num.modulo(numeric)    => result\n *\n *  Equivalent to\n *  <i>num</i>.<code>divmod(</code><i>aNumeric</i><code>)[1]</code>.\n */\n\nstatic VALUE\nnum_modulo(x, y)\n    VALUE x, y;\n{\n    return rb_funcall(x, '%', 1, y);\n}\n\n/*\n *  call-seq:\n *     num.remainder(numeric)    => result\n *\n *  If <i>num</i> and <i>numeric</i> have different signs, returns\n *  <em>mod</em>-<i>numeric</i>; otherwise, returns <em>mod</em>. In\n *  both cases <em>mod</em> is the value\n *  <i>num</i>.<code>modulo(</code><i>numeric</i><code>)</code>. The\n *  differences between <code>remainder</code> and modulo\n *  (<code>%</code>) are shown in the table under <code>Numeric#divmod</code>.\n */\n\nstatic VALUE\nnum_remainder(x, y)\n    VALUE x, y;\n{\n    VALUE z = rb_funcall(x, '%', 1, y);\n\n    if ((!rb_equal(z, INT2FIX(0))) &&\n\t((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&\n\t  RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||\n\t (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&\n\t  RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) {\n\treturn rb_funcall(z, '-', 1, y);\n    }\n    return z;\n}\n\n/*\n *  call-seq:\n *     num.integer? -> true or false\n *\n *  Returns <code>true</code> if <i>num</i> is an <code>Integer</code>\n *  (including <code>Fixnum</code> and <code>Bignum</code>).\n */\n\nstatic VALUE\nnum_int_p(num)\n    VALUE num;\n{\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     num.abs   => num or numeric\n *\n *  Returns the absolute value of <i>num</i>.\n *\n *     12.abs         #=> 12\n *     (-34.56).abs   #=> 34.56\n *     -34.56.abs     #=> 34.56\n */\n\nstatic VALUE\nnum_abs(num)\n    VALUE num;\n{\n    if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) {\n\treturn rb_funcall(num, rb_intern(\"-@\"), 0);\n    }\n    return num;\n}\n\n\n/*\n *  call-seq:\n *     num.zero?    => true or false\n *\n *  Returns <code>true</code> if <i>num</i> has a zero value.\n */\n\nstatic VALUE\nnum_zero_p(num)\n    VALUE num;\n{\n    if (rb_equal(num, INT2FIX(0))) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     num.nonzero?    => num or nil\n *\n *  Returns <i>num</i> if <i>num</i> is not zero, <code>nil</code>\n *  otherwise. This behavior is useful when chaining comparisons:\n *\n *     a = %w( z Bb bB bb BB a aA Aa AA A )\n *     b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }\n *     b   #=> [\"A\", \"a\", \"AA\", \"Aa\", \"aA\", \"BB\", \"Bb\", \"bB\", \"bb\", \"z\"]\n */\n\nstatic VALUE\nnum_nonzero_p(num)\n    VALUE num;\n{\n    if (RTEST(rb_funcall(num, rb_intern(\"zero?\"), 0, 0))) {\n\treturn Qnil;\n    }\n    return num;\n}\n\n/*\n *  call-seq:\n *     num.to_int    => integer\n *\n *  Invokes the child class's <code>to_i</code> method to convert\n *  <i>num</i> to an integer.\n */\n\nstatic VALUE\nnum_to_int(num)\n    VALUE num;\n{\n    return rb_funcall(num, id_to_i, 0, 0);\n}\n\n\n/********************************************************************\n *\n * Document-class: Float\n *\n *  <code>Float</code> objects represent real numbers using the native\n *  architecture's double-precision floating point representation.\n */\n\nVALUE\nrb_float_new(d)\n    double d;\n{\n    NEWOBJ(flt, struct RFloat);\n    OBJSETUP(flt, rb_cFloat, T_FLOAT);\n\n    flt->value = d;\n    return (VALUE)flt;\n}\n\n/*\n *  call-seq:\n *     flt.to_s    => string\n *\n *  Returns a string containing a representation of self. As well as a\n *  fixed or exponential form of the number, the call may return\n *  ``<code>NaN</code>'', ``<code>Infinity</code>'', and\n *  ``<code>-Infinity</code>''.\n */\n\nstatic VALUE\nflo_to_s(flt)\n    VALUE flt;\n{\n    char buf[32];\n    double value = RFLOAT(flt)->value;\n    char *p, *e;\n\n    if (isinf(value))\n\treturn rb_str_new2(value < 0 ? \"-Infinity\" : \"Infinity\");\n    else if(isnan(value))\n\treturn rb_str_new2(\"NaN\");\n\n    sprintf(buf, \"%#.15g\", value); /* ensure to print decimal point */\n    if (!(e = strchr(buf, 'e'))) {\n\te = buf + strlen(buf);\n    }\n    if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */\n\tsprintf(buf, \"%#.14e\", value);\n\tif (!(e = strchr(buf, 'e'))) {\n\t    e = buf + strlen(buf);\n\t}\n    }\n    p = e;\n    while (p[-1]=='0' && ISDIGIT(p[-2]))\n\tp--;\n    memmove(p, e, strlen(e)+1);\n    return rb_str_new2(buf);\n}\n\n/*\n * MISSING: documentation\n */\n\nstatic VALUE\nflo_coerce(x, y)\n    VALUE x, y;\n{\n    return rb_assoc_new(rb_Float(y), x);\n}\n\n/*\n * call-seq:\n *    -float   => float\n *\n * Returns float, negated.\n */\n\nstatic VALUE\nflo_uminus(flt)\n    VALUE flt;\n{\n    return rb_float_new(-RFLOAT(flt)->value);\n}\n\n/*\n * call-seq:\n *   float + other   => float\n *\n * Returns a new float which is the sum of <code>float</code>\n * and <code>other</code>.\n */\n\nstatic VALUE\nflo_plus(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\treturn rb_float_new(RFLOAT(x)->value + (double)FIX2LONG(y));\n      case T_BIGNUM:\n\treturn rb_float_new(RFLOAT(x)->value + rb_big2dbl(y));\n      case T_FLOAT:\n\treturn rb_float_new(RFLOAT(x)->value + RFLOAT(y)->value);\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   float + other   => float\n *\n * Returns a new float which is the difference of <code>float</code>\n * and <code>other</code>.\n */\n\nstatic VALUE\nflo_minus(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\treturn rb_float_new(RFLOAT(x)->value - (double)FIX2LONG(y));\n      case T_BIGNUM:\n\treturn rb_float_new(RFLOAT(x)->value - rb_big2dbl(y));\n      case T_FLOAT:\n\treturn rb_float_new(RFLOAT(x)->value - RFLOAT(y)->value);\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   float * other   => float\n *\n * Returns a new float which is the product of <code>float</code>\n * and <code>other</code>.\n */\n\nstatic VALUE\nflo_mul(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\treturn rb_float_new(RFLOAT(x)->value * (double)FIX2LONG(y));\n      case T_BIGNUM:\n\treturn rb_float_new(RFLOAT(x)->value * rb_big2dbl(y));\n      case T_FLOAT:\n\treturn rb_float_new(RFLOAT(x)->value * RFLOAT(y)->value);\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   float / other   => float\n *\n * Returns a new float which is the result of dividing\n * <code>float</code> by <code>other</code>.\n */\n\nstatic VALUE\nflo_div(x, y)\n    VALUE x, y;\n{\n    long f_y;\n    double d;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tf_y = FIX2LONG(y);\n\treturn rb_float_new(RFLOAT(x)->value / (double)f_y);\n      case T_BIGNUM:\n\td = rb_big2dbl(y);\n\treturn rb_float_new(RFLOAT(x)->value / d);\n      case T_FLOAT:\n\treturn rb_float_new(RFLOAT(x)->value / RFLOAT(y)->value);\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\n\nstatic void\nflodivmod(x, y, divp, modp)\n    double x, y;\n    double *divp, *modp;\n{\n    double div, mod;\n\n#ifdef HAVE_FMOD\n    mod = fmod(x, y);\n#else\n    {\n\tdouble z;\n\n\tmodf(x/y, &z);\n\tmod = x - z * y;\n    }\n#endif\n    if (isinf(x) && !isinf(y) && !isnan(y))\n\tdiv = x;\n    else\n\tdiv = (x - mod) / y;\n    if (y*mod < 0) {\n\tmod += y;\n\tdiv -= 1.0;\n    }\n    if (modp) *modp = mod;\n    if (divp) *divp = div;\n}\n\n\n/*\n *  call-seq:\n *     flt % other         => float\n *     flt.modulo(other)   => float\n *\n *  Return the modulo after division of <code>flt</code> by <code>other</code>.\n *\n *     6543.21.modulo(137)      #=> 104.21\n *     6543.21.modulo(137.24)   #=> 92.9299999999996\n */\n\nstatic VALUE\nflo_mod(x, y)\n    VALUE x, y;\n{\n    double fy, mod;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tfy = (double)FIX2LONG(y);\n\tbreak;\n      case T_BIGNUM:\n\tfy = rb_big2dbl(y);\n\tbreak;\n      case T_FLOAT:\n\tfy = RFLOAT(y)->value;\n\tbreak;\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    flodivmod(RFLOAT(x)->value, fy, 0, &mod);\n    return rb_float_new(mod);\n}\n\n/*\n *  call-seq:\n *     flt.divmod(numeric)    => array\n *\n *  See <code>Numeric#divmod</code>.\n */\n\nstatic VALUE\nflo_divmod(x, y)\n    VALUE x, y;\n{\n    double fy, div, mod, val;\n    volatile VALUE a, b;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tfy = (double)FIX2LONG(y);\n\tbreak;\n      case T_BIGNUM:\n\tfy = rb_big2dbl(y);\n\tbreak;\n      case T_FLOAT:\n\tfy = RFLOAT(y)->value;\n\tbreak;\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n    flodivmod(RFLOAT(x)->value, fy, &div, &mod);\n    if (FIXABLE(div)) {\n        val = round(div);\n\ta = LONG2FIX(val);\n    }\n    else {\n\ta = rb_dbl2big(div);\n    }\n    b = rb_float_new(mod);\n    return rb_assoc_new(a, b);\n}\n\n/*\n * call-seq:\n *\n *  flt ** other   => float\n *\n * Raises <code>float</code> the <code>other</code> power.\n */\n\nstatic VALUE\nflo_pow(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n        return rb_float_new(pow(RFLOAT(x)->value, (double)FIX2LONG(y)));\n      case T_BIGNUM:\n\treturn rb_float_new(pow(RFLOAT(x)->value, rb_big2dbl(y)));\n      case T_FLOAT:\n        return rb_float_new(pow(RFLOAT(x)->value, RFLOAT(y)->value));\n      default:\n        return rb_num_coerce_bin(x, y);\n    }\n}\n\n/*\n *  call-seq:\n *     num.eql?(numeric)    => true or false\n *\n *  Returns <code>true</code> if <i>num</i> and <i>numeric</i> are the\n *  same type and have equal values.\n *\n *     1 == 1.0          #=> true\n *     1.eql?(1.0)       #=> false\n *     (1.0).eql?(1.0)   #=> true\n */\n\nstatic VALUE\nnum_eql(x, y)\n    VALUE x, y;\n{\n    if (TYPE(x) != TYPE(y)) return Qfalse;\n\n    return rb_equal(x, y);\n}\n\n/*\n *  call-seq:\n *     num <=> other -> 0 or nil\n *\n *  Returns zero if <i>num</i> equals <i>other</i>, <code>nil</code>\n *  otherwise.\n */\n\nstatic VALUE\nnum_cmp(x, y)\n    VALUE x, y;\n{\n    if (x == y) return INT2FIX(0);\n    return Qnil;\n}\n\nstatic VALUE\nnum_equal(x, y)\n    VALUE x, y;\n{\n    if (x == y) return Qtrue;\n    return rb_funcall(y, id_eq, 1, x);\n}\n\n/*\n *  call-seq:\n *     flt == obj   => true or false\n *\n *  Returns <code>true</code> only if <i>obj</i> has the same value\n *  as <i>flt</i>. Contrast this with <code>Float#eql?</code>, which\n *  requires <i>obj</i> to be a <code>Float</code>.\n *\n *     1.0 == 1   #=> true\n *\n */\n\nstatic VALUE\nflo_eq(x, y)\n    VALUE x, y;\n{\n    volatile double a, b;\n\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tb = FIX2LONG(y);\n\tbreak;\n      case T_BIGNUM:\n\tb = rb_big2dbl(y);\n\tbreak;\n      case T_FLOAT:\n\tb = RFLOAT(y)->value;\n\tif (isnan(b)) return Qfalse;\n\tbreak;\n      default:\n\treturn num_equal(x, y);\n    }\n    a = RFLOAT(x)->value;\n    if (isnan(a)) return Qfalse;\n    return (a == b)?Qtrue:Qfalse;\n}\n\n/*\n * call-seq:\n *   flt.hash   => integer\n *\n * Returns a hash code for this float.\n */\n\nstatic VALUE\nflo_hash(num)\n    VALUE num;\n{\n    double d;\n    char *c;\n    int i, hash;\n\n    d = RFLOAT(num)->value;\n    if (d == 0) d = fabs(d);\n    c = (char*)&d;\n    for (hash=0, i=0; i<sizeof(double);i++) {\n\thash = (hash * 971) ^ (unsigned char)c[i];\n    }\n    if (hash < 0) hash = -hash;\n    return INT2FIX(hash);\n}\n\nVALUE\nrb_dbl_cmp(a, b)\n    double a, b;\n{\n    if (isnan(a) || isnan(b)) return Qnil;\n    if (a == b) return INT2FIX(0);\n    if (a > b) return INT2FIX(1);\n    if (a < b) return INT2FIX(-1);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     flt <=> numeric   => -1, 0, +1\n *\n *  Returns -1, 0, or +1 depending on whether <i>flt</i> is less than,\n *  equal to, or greater than <i>numeric</i>. This is the basis for the\n *  tests in <code>Comparable</code>.\n */\n\nstatic VALUE\nflo_cmp(x, y)\n    VALUE x, y;\n{\n    double a, b;\n\n    a = RFLOAT(x)->value;\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tb = (double)FIX2LONG(y);\n\tbreak;\n\n      case T_BIGNUM:\n\tb = rb_big2dbl(y);\n\tbreak;\n\n      case T_FLOAT:\n\tb = RFLOAT(y)->value;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_cmp(x, y);\n    }\n    return rb_dbl_cmp(a, b);\n}\n\n/*\n * call-seq:\n *   flt > other    =>  true or false\n *\n * <code>true</code> if <code>flt</code> is greater than <code>other</code>.\n */\n\nstatic VALUE\nflo_gt(x, y)\n    VALUE x, y;\n{\n    double a, b;\n\n    a = RFLOAT(x)->value;\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tb = (double)FIX2LONG(y);\n\tbreak;\n\n      case T_BIGNUM:\n\tb = rb_big2dbl(y);\n\tbreak;\n\n      case T_FLOAT:\n\tb = RFLOAT(y)->value;\n\tif (isnan(b)) return Qfalse;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_relop(x, y);\n    }\n    if (isnan(a)) return Qfalse;\n    return (a > b)?Qtrue:Qfalse;\n}\n\n/*\n * call-seq:\n *   flt >= other    =>  true or false\n *\n * <code>true</code> if <code>flt</code> is greater than\n * or equal to <code>other</code>.\n */\n\nstatic VALUE\nflo_ge(x, y)\n    VALUE x, y;\n{\n    double a, b;\n\n    a = RFLOAT(x)->value;\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tb = (double)FIX2LONG(y);\n\tbreak;\n\n      case T_BIGNUM:\n\tb = rb_big2dbl(y);\n\tbreak;\n\n      case T_FLOAT:\n\tb = RFLOAT(y)->value;\n\tif (isnan(b)) return Qfalse;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_relop(x, y);\n    }\n    if (isnan(a)) return Qfalse;\n    return (a >= b)?Qtrue:Qfalse;\n}\n\n/*\n * call-seq:\n *   flt < other    =>  true or false\n *\n * <code>true</code> if <code>flt</code> is less than <code>other</code>.\n */\n\nstatic VALUE\nflo_lt(x, y)\n    VALUE x, y;\n{\n    double a, b;\n\n    a = RFLOAT(x)->value;\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tb = (double)FIX2LONG(y);\n\tbreak;\n\n      case T_BIGNUM:\n\tb = rb_big2dbl(y);\n\tbreak;\n\n      case T_FLOAT:\n\tb = RFLOAT(y)->value;\n\tif (isnan(b)) return Qfalse;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_relop(x, y);\n    }\n    if (isnan(a)) return Qfalse;\n    return (a < b)?Qtrue:Qfalse;\n}\n\n/*\n * call-seq:\n *   flt <= other    =>  true or false\n *\n * <code>true</code> if <code>flt</code> is less than\n * or equal to <code>other</code>.\n */\n\nstatic VALUE\nflo_le(x, y)\n    VALUE x, y;\n{\n    double a, b;\n\n    a = RFLOAT(x)->value;\n    switch (TYPE(y)) {\n      case T_FIXNUM:\n\tb = (double)FIX2LONG(y);\n\tbreak;\n\n      case T_BIGNUM:\n\tb = rb_big2dbl(y);\n\tbreak;\n\n      case T_FLOAT:\n\tb = RFLOAT(y)->value;\n\tif (isnan(b)) return Qfalse;\n\tbreak;\n\n      default:\n\treturn rb_num_coerce_relop(x, y);\n    }\n    if (isnan(a)) return Qfalse;\n    return (a <= b)?Qtrue:Qfalse;\n}\n\n/*\n *  call-seq:\n *     flt.eql?(obj)   => true or false\n *\n *  Returns <code>true</code> only if <i>obj</i> is a\n *  <code>Float</code> with the same value as <i>flt</i>. Contrast this\n *  with <code>Float#==</code>, which performs type conversions.\n *\n *     1.0.eql?(1)   #=> false\n */\n\nstatic VALUE\nflo_eql(x, y)\n    VALUE x, y;\n{\n    if (TYPE(y) == T_FLOAT) {\n\tdouble a = RFLOAT(x)->value;\n\tdouble b = RFLOAT(y)->value;\n\n\tif (isnan(a) || isnan(b)) return Qfalse;\n\tif (a == b) return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   flt.to_f   => flt\n *\n * As <code>flt</code> is already a float, returns <i>self</i>.\n */\n\nstatic VALUE\nflo_to_f(num)\n    VALUE num;\n{\n    return num;\n}\n\n/*\n *  call-seq:\n *     flt.abs    => float\n *\n *  Returns the absolute value of <i>flt</i>.\n *\n *     (-34.56).abs   #=> 34.56\n *     -34.56.abs     #=> 34.56\n *\n */\n\nstatic VALUE\nflo_abs(flt)\n    VALUE flt;\n{\n    double val = fabs(RFLOAT(flt)->value);\n    return rb_float_new(val);\n}\n\n/*\n *  call-seq:\n *     flt.zero? -> true or false\n *\n *  Returns <code>true</code> if <i>flt</i> is 0.0.\n *\n */\n\nstatic VALUE\nflo_zero_p(num)\n    VALUE num;\n{\n    if (RFLOAT(num)->value == 0.0) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     flt.nan? -> true or false\n *\n *  Returns <code>true</code> if <i>flt</i> is an invalid IEEE floating\n *  point number.\n *\n *     a = -1.0      #=> -1.0\n *     a.nan?        #=> false\n *     a = 0.0/0.0   #=> NaN\n *     a.nan?        #=> true\n */\n\nstatic VALUE\nflo_is_nan_p(num)\n     VALUE num;\n{\n    double value = RFLOAT(num)->value;\n\n    return isnan(value) ? Qtrue : Qfalse;\n}\n\n/*\n *  call-seq:\n *     flt.infinite? -> nil, -1, +1\n *\n *  Returns <code>nil</code>, -1, or +1 depending on whether <i>flt</i>\n *  is finite, -infinity, or +infinity.\n *\n *     (0.0).infinite?        #=> nil\n *     (-1.0/0.0).infinite?   #=> -1\n *     (+1.0/0.0).infinite?   #=> 1\n */\n\nstatic VALUE\nflo_is_infinite_p(num)\n     VALUE num;\n{\n    double value = RFLOAT(num)->value;\n\n    if (isinf(value)) {\n\treturn INT2FIX( value < 0 ? -1 : 1 );\n    }\n\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     flt.finite? -> true or false\n *\n *  Returns <code>true</code> if <i>flt</i> is a valid IEEE floating\n *  point number (it is not infinite, and <code>nan?</code> is\n *  <code>false</code>).\n *\n */\n\nstatic VALUE\nflo_is_finite_p(num)\n     VALUE num;\n{\n    double value = RFLOAT(num)->value;\n\n#if HAVE_FINITE\n    if (!finite(value))\n\treturn Qfalse;\n#else\n    if (isinf(value) || isnan(value))\n\treturn Qfalse;\n#endif\n\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     flt.floor   => integer\n *\n *  Returns the largest integer less than or equal to <i>flt</i>.\n *\n *     1.2.floor      #=> 1\n *     2.0.floor      #=> 2\n *     (-1.2).floor   #=> -2\n *     (-2.0).floor   #=> -2\n */\n\nstatic VALUE\nflo_floor(num)\n    VALUE num;\n{\n    double f = floor(RFLOAT(num)->value);\n    long val;\n\n    if (!FIXABLE(f)) {\n\treturn rb_dbl2big(f);\n    }\n    val = f;\n    return LONG2FIX(val);\n}\n\n/*\n *  call-seq:\n *     flt.ceil    => integer\n *\n *  Returns the smallest <code>Integer</code> greater than or equal to\n *  <i>flt</i>.\n *\n *     1.2.ceil      #=> 2\n *     2.0.ceil      #=> 2\n *     (-1.2).ceil   #=> -1\n *     (-2.0).ceil   #=> -2\n */\n\nstatic VALUE\nflo_ceil(num)\n    VALUE num;\n{\n    double f = ceil(RFLOAT(num)->value);\n    long val;\n\n    if (!FIXABLE(f)) {\n\treturn rb_dbl2big(f);\n    }\n    val = f;\n    return LONG2FIX(val);\n}\n\n/*\n *  call-seq:\n *     flt.round   => integer\n *\n *  Rounds <i>flt</i> to the nearest integer. Equivalent to:\n *\n *     def round\n *       return (self+0.5).floor if self > 0.0\n *       return (self-0.5).ceil  if self < 0.0\n *       return 0\n *     end\n *\n *     1.5.round      #=> 2\n *     (-1.5).round   #=> -2\n *\n */\n\nstatic VALUE\nflo_round(num)\n    VALUE num;\n{\n    double f = RFLOAT(num)->value;\n    long val;\n\n    f = round(f);\n\n    if (!FIXABLE(f)) {\n\treturn rb_dbl2big(f);\n    }\n    val = f;\n    return LONG2FIX(val);\n}\n\n/*\n *  call-seq:\n *     flt.to_i       => integer\n *     flt.to_int     => integer\n *     flt.truncate   => integer\n *\n *  Returns <i>flt</i> truncated to an <code>Integer</code>.\n */\n\nstatic VALUE\nflo_truncate(num)\n    VALUE num;\n{\n    double f = RFLOAT(num)->value;\n    long val;\n\n    if (f > 0.0) f = floor(f);\n    if (f < 0.0) f = ceil(f);\n\n    if (!FIXABLE(f)) {\n\treturn rb_dbl2big(f);\n    }\n    val = f;\n    return LONG2FIX(val);\n}\n\n\n/*\n *  call-seq:\n *     num.floor    => integer\n *\n *  Returns the largest integer less than or equal to <i>num</i>.\n *  <code>Numeric</code> implements this by converting <i>anInteger</i>\n *  to a <code>Float</code> and invoking <code>Float#floor</code>.\n *\n *     1.floor      #=> 1\n *     (-1).floor   #=> -1\n */\n\nstatic VALUE\nnum_floor(num)\n    VALUE num;\n{\n    return flo_floor(rb_Float(num));\n}\n\n\n/*\n *  call-seq:\n *     num.ceil    => integer\n *\n *  Returns the smallest <code>Integer</code> greater than or equal to\n *  <i>num</i>. Class <code>Numeric</code> achieves this by converting\n *  itself to a <code>Float</code> then invoking\n *  <code>Float#ceil</code>.\n *\n *     1.ceil        #=> 1\n *     1.2.ceil      #=> 2\n *     (-1.2).ceil   #=> -1\n *     (-1.0).ceil   #=> -1\n */\n\nstatic VALUE\nnum_ceil(num)\n    VALUE num;\n{\n    return flo_ceil(rb_Float(num));\n}\n\n/*\n *  call-seq:\n *     num.round    => integer\n *\n *  Rounds <i>num</i> to the nearest integer. <code>Numeric</code>\n *  implements this by converting itself to a\n *  <code>Float</code> and invoking <code>Float#round</code>.\n */\n\nstatic VALUE\nnum_round(num)\n    VALUE num;\n{\n    return flo_round(rb_Float(num));\n}\n\n/*\n *  call-seq:\n *     num.truncate    => integer\n *\n *  Returns <i>num</i> truncated to an integer. <code>Numeric</code>\n *  implements this by converting its value to a float and invoking\n *  <code>Float#truncate</code>.\n */\n\nstatic VALUE\nnum_truncate(num)\n    VALUE num;\n{\n    return flo_truncate(rb_Float(num));\n}\n\n\nint ruby_float_step _((VALUE from, VALUE to, VALUE step, int excl));\n\nint\nruby_float_step(from, to, step, excl)\n    VALUE from, to, step;\n    int excl;\n{\n    if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step) == T_FLOAT) {\n\tconst double epsilon = DBL_EPSILON;\n\tdouble beg = NUM2DBL(from);\n\tdouble end = NUM2DBL(to);\n\tdouble unit = NUM2DBL(step);\n\tdouble n = (end - beg)/unit;\n\tdouble err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;\n\tlong i;\n\n\tif (err>0.5) err=0.5;\n\tn = floor(n + err);\n\tif (!excl) n++;\n\tfor (i=0; i<n; i++) {\n\t    rb_yield(rb_float_new(i*unit+beg));\n\t}\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     num.step(limit, step ) {|i| block }     => num\n *\n *  Invokes <em>block</em> with the sequence of numbers starting at\n *  <i>num</i>, incremented by <i>step</i> on each call. The loop\n *  finishes when the value to be passed to the block is greater than\n *  <i>limit</i> (if <i>step</i> is positive) or less than\n *  <i>limit</i> (if <i>step</i> is negative). If all the arguments are\n *  integers, the loop operates using an integer counter. If any of the\n *  arguments are floating point numbers, all are converted to floats,\n *  and the loop is executed <i>floor(n + n*epsilon)+ 1</i> times,\n *  where <i>n = (limit - num)/step</i>. Otherwise, the loop\n *  starts at <i>num</i>, uses either the <code><</code> or\n *  <code>></code> operator to compare the counter against\n *  <i>limit</i>, and increments itself using the <code>+</code>\n *  operator.\n *\n *     1.step(10, 2) { |i| print i, \" \" }\n *     Math::E.step(Math::PI, 0.2) { |f| print f, \" \" }\n *\n *  <em>produces:</em>\n *\n *     1 3 5 7 9\n *     2.71828182845905 2.91828182845905 3.11828182845905\n */\n\nstatic VALUE\nnum_step(argc, argv, from)\n    int argc;\n    VALUE *argv;\n    VALUE from;\n{\n    VALUE to, step;\n\n    RETURN_ENUMERATOR(from, argc, argv);\n\n    if (argc == 1) {\n\tto = argv[0];\n\tstep = INT2FIX(1);\n    }\n    else {\n\tif (argc == 2) {\n\t    to = argv[0];\n\t    step = argv[1];\n\t}\n\telse {\n\t    rb_raise(rb_eArgError, \"wrong number of arguments\");\n\t}\n\tif (rb_equal(step, INT2FIX(0))) {\n\t    rb_raise(rb_eArgError, \"step can't be 0\");\n\t}\n    }\n\n    if (FIXNUM_P(from) && FIXNUM_P(to) && FIXNUM_P(step)) {\n\tlong i, end, diff;\n\n\ti = FIX2LONG(from);\n\tend = FIX2LONG(to);\n\tdiff = FIX2LONG(step);\n\n\tif (diff > 0) {\n\t    while (i <= end) {\n\t\trb_yield(LONG2FIX(i));\n\t\ti += diff;\n\t    }\n\t}\n\telse {\n\t    while (i >= end) {\n\t\trb_yield(LONG2FIX(i));\n\t\ti += diff;\n\t    }\n\t}\n    }\n    else if (!ruby_float_step(from, to, step, Qfalse)) {\n\tVALUE i = from;\n\tID cmp;\n\n\tif (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {\n\t    cmp = '>';\n\t}\n\telse {\n\t    cmp = '<';\n\t}\n\tfor (;;) {\n\t    if (RTEST(rb_funcall(i, cmp, 1, to))) break;\n\t    rb_yield(i);\n\t    i = rb_funcall(i, '+', 1, step);\n\t}\n    }\n    return from;\n}\n\nlong\nrb_num2long(val)\n    VALUE val;\n{\n  again:\n    if (NIL_P(val)) {\n\trb_raise(rb_eTypeError, \"no implicit conversion from nil to integer\");\n    }\n\n    if (FIXNUM_P(val)) return FIX2LONG(val);\n\n    switch (TYPE(val)) {\n      case T_FLOAT:\n\tif (RFLOAT(val)->value <= (double)LONG_MAX\n\t    && RFLOAT(val)->value >= (double)LONG_MIN) {\n\t    return (long)(RFLOAT(val)->value);\n\t}\n\telse {\n\t    char buf[24];\n\t    char *s;\n\n\t    sprintf(buf, \"%-.10g\", RFLOAT(val)->value);\n\t    if ((s = strchr(buf, ' ')) != 0) *s = '\\0';\n\t    rb_raise(rb_eRangeError, \"float %s out of range of integer\", buf);\n\t}\n\n      case T_BIGNUM:\n\treturn rb_big2long(val);\n\n      default:\n\tval = rb_to_int(val);\n\tgoto again;\n    }\n}\n\nunsigned long\nrb_num2ulong(val)\n    VALUE val;\n{\n    if (TYPE(val) == T_BIGNUM) {\n\treturn rb_big2ulong(val);\n    }\n    return (unsigned long)rb_num2long(val);\n}\n\n#if SIZEOF_INT < SIZEOF_LONG\nstatic void\ncheck_int(num)\n    long num;\n{\n    const char *s;\n\n    if (num < INT_MIN) {\n\ts = \"small\";\n    }\n    else if (num > INT_MAX) {\n\ts = \"big\";\n    }\n    else {\n\treturn;\n    }\n    rb_raise(rb_eRangeError, \"integer %ld too %s to convert to `int'\", num, s);\n}\n\nstatic void\ncheck_uint(num, sign)\n    unsigned long num;\n    VALUE sign;\n{\n    static const unsigned long mask = ~(unsigned long)UINT_MAX;\n\n    if (RTEST(sign)) {\n\t/* minus */\n\tif ((num & mask) != mask || (num & ~mask) <= INT_MAX + 1UL)\n\t    rb_raise(rb_eRangeError, \"integer %ld too small to convert to `unsigned int'\", num);\n    }\n    else {\n\t/* plus */\n\tif ((num & mask) != 0)\n\t    rb_raise(rb_eRangeError, \"integer %lu too big to convert to `unsigned int'\", num);\n    }\n}\n\nlong\nrb_num2int(val)\n    VALUE val;\n{\n    long num = rb_num2long(val);\n\n    check_int(num);\n    return num;\n}\n\nlong\nrb_fix2int(val)\n    VALUE val;\n{\n    long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val);\n\n    check_int(num);\n    return num;\n}\n\nunsigned long\nrb_num2uint(val)\n    VALUE val;\n{\n    unsigned long num = rb_num2ulong(val);\n\n    check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));\n    return num;\n}\n\nunsigned long\nrb_fix2uint(val)\n    VALUE val;\n{\n    unsigned long num;\n\n    if (!FIXNUM_P(val)) {\n        return rb_num2uint(val);\n    }\n    num = FIX2ULONG(val);\n\n    check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));\n    return num;\n}\n#else\nlong\nrb_num2int(val)\n    VALUE val;\n{\n    return rb_num2long(val);\n}\n\nlong\nrb_fix2int(val)\n    VALUE val;\n{\n    return FIX2INT(val);\n}\n#endif\n\nVALUE\nrb_num2fix(val)\n    VALUE val;\n{\n    long v;\n\n    if (FIXNUM_P(val)) return val;\n\n    v = rb_num2long(val);\n    if (!FIXABLE(v))\n\trb_raise(rb_eRangeError, \"integer %ld out of range of fixnum\", v);\n    return LONG2FIX(v);\n}\n\n#if HAVE_LONG_LONG\n\nLONG_LONG\nrb_num2ll(val)\n    VALUE val;\n{\n    if (NIL_P(val)) {\n\trb_raise(rb_eTypeError, \"no implicit conversion from nil\");\n    }\n\n    if (FIXNUM_P(val)) return (LONG_LONG)FIX2LONG(val);\n\n    switch (TYPE(val)) {\n    case T_FLOAT:\n\tif (RFLOAT(val)->value <= (double)LLONG_MAX\n\t    && RFLOAT(val)->value >= (double)LLONG_MIN) {\n\t    return (LONG_LONG)(RFLOAT(val)->value);\n\t}\n\telse {\n\t    char buf[24];\n\t    char *s;\n\n\t    sprintf(buf, \"%-.10g\", RFLOAT(val)->value);\n\t    if ((s = strchr(buf, ' ')) != 0) *s = '\\0';\n\t    rb_raise(rb_eRangeError, \"float %s out of range of long long\", buf);\n\t}\n\n    case T_BIGNUM:\n\treturn rb_big2ll(val);\n\n    case T_STRING:\n\trb_raise(rb_eTypeError, \"no implicit conversion from string\");\n\treturn Qnil;            /* not reached */\n\n    case T_TRUE:\n    case T_FALSE:\n\trb_raise(rb_eTypeError, \"no implicit conversion from boolean\");\n\treturn Qnil;\t\t/* not reached */\n\n      default:\n\t  val = rb_to_int(val);\n\t  return NUM2LL(val);\n    }\n}\n\nunsigned LONG_LONG\nrb_num2ull(val)\n    VALUE val;\n{\n    if (TYPE(val) == T_BIGNUM) {\n\treturn rb_big2ull(val);\n    }\n    return (unsigned LONG_LONG)rb_num2ll(val);\n}\n\n#endif  /* HAVE_LONG_LONG */\n\n\n/*\n * Document-class: Integer\n *\n *  <code>Integer</code> is the basis for the two concrete classes that\n *  hold whole numbers, <code>Bignum</code> and <code>Fixnum</code>.\n *\n */\n\n\n/*\n *  call-seq:\n *     int.to_i      => int\n *     int.to_int    => int\n *     int.floor     => int\n *     int.ceil      => int\n *     int.round     => int\n *     int.truncate  => int\n *\n *  As <i>int</i> is already an <code>Integer</code>, all these\n *  methods simply return the receiver.\n */\n\nstatic VALUE\nint_to_i(num)\n    VALUE num;\n{\n    return num;\n}\n\n/*\n *  call-seq:\n *     int.integer? -> true\n *\n *  Always returns <code>true</code>.\n */\n\nstatic VALUE\nint_int_p(num)\n    VALUE num;\n{\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     int.odd? -> true or false\n *\n *  Returns <code>true</code> if <i>int</i> is an odd number.\n */\n\nstatic VALUE\nint_odd_p(VALUE num)\n{\n    if (rb_funcall(num, '%', 1, INT2FIX(2)) != INT2FIX(0)) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     int.even? -> true or false\n *\n *  Returns <code>true</code> if <i>int</i> is an even number.\n */\n\nstatic VALUE\nint_even_p(VALUE num)\n{\n    if (rb_funcall(num, '%', 1, INT2FIX(2)) == INT2FIX(0)) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     int.next    => integer\n *     int.succ    => integer\n *\n *  Returns the <code>Integer</code> equal to <i>int</i> + 1.\n *\n *     1.next      #=> 2\n *     (-1).next   #=> 0\n */\n\nstatic VALUE\nint_succ(num)\n    VALUE num;\n{\n    if (FIXNUM_P(num)) {\n\tlong i = FIX2LONG(num) + 1;\n\treturn LONG2NUM(i);\n    }\n    return rb_funcall(num, '+', 1, INT2FIX(1));\n}\n\n/*\n *  call-seq:\n *     int.pred    => integer\n *\n *  Returns the <code>Integer</code> equal to <i>int</i> - 1.\n *\n *     1.pred      #=> 0\n *     (-1).pred   #=> -2\n */\n\nstatic VALUE\nint_pred(VALUE num)\n{\n    if (FIXNUM_P(num)) {\n        long i = FIX2LONG(num) - 1;\n        return LONG2NUM(i);\n    }\n    return rb_funcall(num, '-', 1, INT2FIX(1));\n}\n\n/*\n *  call-seq:\n *     int.chr    => string\n *\n *  Returns a string containing the ASCII character represented by the\n *  receiver's value.\n *\n *     65.chr    #=> \"A\"\n *     ?a.chr    #=> \"a\"\n *     230.chr   #=> \"\\346\"\n */\n\nstatic VALUE\nint_chr(num)\n    VALUE num;\n{\n    char c;\n    long i = NUM2LONG(num);\n\n    if (i < 0 || 0xff < i)\n\trb_raise(rb_eRangeError, \"%ld out of char range\", i);\n    c = i;\n    return rb_str_new(&c, 1);\n}\n\n/*\n *  call-seq:\n *     int.ord    => int\n *\n *  Returns the int itself.\n *\n *     ?a.ord    #=> 97\n *\n *  This method is intended for compatibility to\n *  character constant in Ruby 1.9.\n *  For example, ?a.ord returns 97 both in 1.8 and 1.9.\n */\n\nstatic VALUE\nint_ord(num)\n    VALUE num;\n{\n    return num;\n}\n\n/********************************************************************\n *\n * Document-class: Fixnum\n *\n *  A <code>Fixnum</code> holds <code>Integer</code> values that can be\n *  represented in a native machine word (minus 1 bit). If any operation\n *  on a <code>Fixnum</code> exceeds this range, the value is\n *  automatically converted to a <code>Bignum</code>.\n *\n *  <code>Fixnum</code> objects have immediate value. This means that\n *  when they are assigned or passed as parameters, the actual object is\n *  passed, rather than a reference to that object. Assignment does not\n *  alias <code>Fixnum</code> objects. There is effectively only one\n *  <code>Fixnum</code> object instance for any given integer value, so,\n *  for example, you cannot add a singleton method to a\n *  <code>Fixnum</code>.\n */\n\n\n/*\n * call-seq:\n *   Fixnum.induced_from(obj)    =>  fixnum\n *\n * Convert <code>obj</code> to a Fixnum. Works with numeric parameters.\n * Also works with Symbols, but this is deprecated.\n */\n\nstatic VALUE\nrb_fix_induced_from(klass, x)\n    VALUE klass, x;\n{\n    return rb_num2fix(x);\n}\n\n/*\n * call-seq:\n *   Integer.induced_from(obj)    =>  fixnum, bignum\n *\n * Convert <code>obj</code> to an Integer.\n */\n\nstatic VALUE\nrb_int_induced_from(klass, x)\n    VALUE klass, x;\n{\n    switch (TYPE(x)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n       return x;\n    case T_FLOAT:\n       return rb_funcall(x, id_to_i, 0);\n    default:\n       rb_raise(rb_eTypeError, \"failed to convert %s into Integer\",\n                rb_obj_classname(x));\n    }\n}\n\n/*\n * call-seq:\n *   Float.induced_from(obj)    =>  float\n *\n * Convert <code>obj</code> to a float.\n */\n\nstatic VALUE\nrb_flo_induced_from(klass, x)\n    VALUE klass, x;\n{\n    switch (TYPE(x)) {\n    case T_FIXNUM:\n    case T_BIGNUM:\n       return rb_funcall(x, rb_intern(\"to_f\"), 0);\n    case T_FLOAT:\n       return x;\n    default:\n       rb_raise(rb_eTypeError, \"failed to convert %s into Float\",\n                rb_obj_classname(x));\n    }\n}\n\n/*\n * call-seq:\n *   -fix   =>  integer\n *\n * Negates <code>fix</code> (which might return a Bignum).\n */\n\nstatic VALUE\nfix_uminus(num)\n    VALUE num;\n{\n    return LONG2NUM(-FIX2LONG(num));\n}\n\nVALUE\nrb_fix2str(x, base)\n    VALUE x;\n    int base;\n{\n    extern const char ruby_digitmap[];\n    char buf[SIZEOF_LONG*CHAR_BIT + 2], *b = buf + sizeof buf;\n    long val = FIX2LONG(x);\n    int neg = 0;\n\n    if (base < 2 || 36 < base) {\n\trb_raise(rb_eArgError, \"illegal radix %d\", base);\n    }\n    if (val == 0) {\n\treturn rb_str_new2(\"0\");\n    }\n    if (val < 0) {\n\tval = -val;\n\tneg = 1;\n    }\n    *--b = '\\0';\n    do {\n\t*--b = ruby_digitmap[(int)(val % base)];\n    } while (val /= base);\n    if (neg) {\n\t*--b = '-';\n    }\n\n    return rb_str_new2(b);\n}\n\n/*\n *  call-seq:\n *     fix.to_s( base=10 ) -> aString\n *\n *  Returns a string containing the representation of <i>fix</i> radix\n *  <i>base</i> (between 2 and 36).\n *\n *     12345.to_s       #=> \"12345\"\n *     12345.to_s(2)    #=> \"11000000111001\"\n *     12345.to_s(8)    #=> \"30071\"\n *     12345.to_s(10)   #=> \"12345\"\n *     12345.to_s(16)   #=> \"3039\"\n *     12345.to_s(36)   #=> \"9ix\"\n *\n */\nstatic VALUE\nfix_to_s(argc, argv, x)\n    int argc;\n    VALUE *argv;\n    VALUE x;\n{\n    VALUE b;\n    int base;\n\n    rb_scan_args(argc, argv, \"01\", &b);\n    if (argc == 0) base = 10;\n    else base = NUM2INT(b);\n\n    return rb_fix2str(x, base);\n}\n\n/*\n * call-seq:\n *   fix + numeric   =>  numeric_result\n *\n * Performs addition: the class of the resulting object depends on\n * the class of <code>numeric</code> and on the magnitude of the\n * result.\n */\n\nstatic VALUE\nfix_plus(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong a, b, c;\n\tVALUE r;\n\n\ta = FIX2LONG(x);\n\tb = FIX2LONG(y);\n\tc = a + b;\n\tr = LONG2NUM(c);\n\n\treturn r;\n    }\n    if (TYPE(y) == T_FLOAT) {\n\treturn rb_float_new((double)FIX2LONG(x) + RFLOAT(y)->value);\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\n/*\n * call-seq:\n *   fix - numeric   =>  numeric_result\n *\n * Performs subtraction: the class of the resulting object depends on\n * the class of <code>numeric</code> and on the magnitude of the\n * result.\n */\n\nstatic VALUE\nfix_minus(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong a, b, c;\n\tVALUE r;\n\n\ta = FIX2LONG(x);\n\tb = FIX2LONG(y);\n\tc = a - b;\n\tr = LONG2NUM(c);\n\n\treturn r;\n    }\n    if (TYPE(y) == T_FLOAT) {\n\treturn rb_float_new((double)FIX2LONG(x) - RFLOAT(y)->value);\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\n/*\n * call-seq:\n *   fix * numeric   =>  numeric_result\n *\n * Performs multiplication: the class of the resulting object depends on\n * the class of <code>numeric</code> and on the magnitude of the\n * result.\n */\n\nstatic VALUE\nfix_mul(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n#ifdef __HP_cc\n        /* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */\n        volatile\n#endif\n\tlong a, b, c;\n\tVALUE r;\n\n\ta = FIX2LONG(x);\n\tif (a == 0) return x;\n\n\tb = FIX2LONG(y);\n\tc = a * b;\n\tr = LONG2FIX(c);\n\n\tif (FIX2LONG(r) != c || c/a != b) {\n\t    r = rb_big_mul(rb_int2big(a), rb_int2big(b));\n\t}\n\treturn r;\n    }\n    if (TYPE(y) == T_FLOAT) {\n\treturn rb_float_new((double)FIX2LONG(x) * RFLOAT(y)->value);\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\nstatic void\nfixdivmod(x, y, divp, modp)\n    long x, y;\n    long *divp, *modp;\n{\n    long div, mod;\n\n    if (y == 0) rb_num_zerodiv();\n    if (y < 0) {\n\tif (x < 0)\n\t    div = -x / -y;\n\telse\n\t    div = - (x / -y);\n    }\n    else {\n\tif (x < 0)\n\t    div = - (-x / y);\n\telse\n\t    div = x / y;\n    }\n    mod = x - div*y;\n    if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {\n\tmod += y;\n\tdiv -= 1;\n    }\n    if (divp) *divp = div;\n    if (modp) *modp = mod;\n}\n\n/*\n *  call-seq:\n *     fix.quo(numeric)    => float\n *     fix.fdiv(numeric)   => float\n *\n *  Returns the floating point result of dividing <i>fix</i> by\n *  <i>numeric</i>.\n *\n *     654321.quo(13731)      #=> 47.6528293642124\n *     654321.quo(13731.24)   #=> 47.6519964693647\n *\n */\n\nstatic VALUE\nfix_quo(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\treturn rb_float_new((double)FIX2LONG(x) / (double)FIX2LONG(y));\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\n/*\n * call-seq:\n *   fix / numeric      =>  numeric_result\n *   fix.div(numeric)   =>  numeric_result\n *\n * Performs division: the class of the resulting object depends on\n * the class of <code>numeric</code> and on the magnitude of the\n * result.\n */\n\nstatic VALUE\nfix_div(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong div;\n\n\tfixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0);\n\treturn LONG2NUM(div);\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\n/*\n *  call-seq:\n *    fix % other         => Numeric\n *    fix.modulo(other)   => Numeric\n *\n *  Returns <code>fix</code> modulo <code>other</code>.\n *  See <code>Numeric.divmod</code> for more information.\n */\n\nstatic VALUE\nfix_mod(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong mod;\n\n\tfixdivmod(FIX2LONG(x), FIX2LONG(y), 0, &mod);\n\treturn LONG2NUM(mod);\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\n/*\n *  call-seq:\n *     fix.divmod(numeric)    => array\n *\n *  See <code>Numeric#divmod</code>.\n */\nstatic VALUE\nfix_divmod(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong div, mod;\n\n\tfixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod);\n\n\treturn rb_assoc_new(LONG2NUM(div), LONG2NUM(mod));\n    }\n    return rb_num_coerce_bin(x, y);\n}\n\nstatic VALUE\nint_pow(x, y)\n    long x;\n    unsigned long y;\n{\n    int neg = x < 0;\n    long z = 1;\n\n    if (neg) x = -x;\n    if (y & 1)\n\tz = x;\n    else\n\tneg = 0;\n    y &= ~1;\n    do {\n\twhile (y % 2 == 0) {\n\t    long x2 = x * x;\n\t    if (x2/x != x || !POSFIXABLE(x2)) {\n\t\tVALUE v;\n\t      bignum:\n\t\tv = rb_big_pow(rb_int2big(x), LONG2NUM(y));\n\t\tif (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);\n\t\treturn v;\n\t    }\n\t    x = x2;\n\t    y >>= 1;\n\t}\n\t{\n\t    long xz = x * z;\n\t    if (!POSFIXABLE(xz) || xz / x != z) {\n\t\tgoto bignum;\n\t    }\n\t    z = xz;\n\t}\n    } while (--y);\n    if (neg) z = -z;\n    return LONG2NUM(z);\n}\n\n/*\n *  call-seq:\n *    fix ** other         => Numeric\n *\n *  Raises <code>fix</code> to the <code>other</code> power, which may\n *  be negative or fractional.\n *\n *    2 ** 3      #=> 8\n *    2 ** -1     #=> 0.5\n *    2 ** 0.5    #=> 1.4142135623731\n */\n\nstatic VALUE\nfix_pow(x, y)\n    VALUE x, y;\n{\n    static const double zero = 0.0;\n    long a = FIX2LONG(x);\n\n    if (FIXNUM_P(y)) {\n\tlong b = FIX2LONG(y);\n\n\tif (b == 0) return INT2FIX(1);\n\tif (b == 1) return x;\n\tif (a == 0) {\n\t    if (b > 0) return INT2FIX(0);\n\t    return rb_float_new(1.0 / zero);\n\t}\n\tif (a == 1) return INT2FIX(1);\n\tif (a == -1) {\n\t    if (b % 2 == 0)\n\t\treturn INT2FIX(1);\n\t    else \n\t\treturn INT2FIX(-1);\n\t}\n\tif (b > 0) {\n\t    return int_pow(a, b);\n\t}\n\treturn rb_float_new(pow((double)a, (double)b));\n    }\n    switch (TYPE(y)) {\n      case T_BIGNUM:\n\tif (a == 0) return INT2FIX(0);\n\tif (a == 1) return INT2FIX(1);\n\tif (a == -1) {\n\t    if (int_even_p(y)) return INT2FIX(1);\n\t    else return INT2FIX(-1);\n\t}\n\tx = rb_int2big(FIX2LONG(x));\n\treturn rb_big_pow(x, y);\n      case T_FLOAT:\n\tif (RFLOAT(y)->value == 0.0) return rb_float_new(1.0);\n\tif (a == 0) {\n\t    return rb_float_new(RFLOAT(y)->value < 0 ? (1.0 / zero) : 0.0);\n\t}\n\tif (a == 1) return rb_float_new(1.0);\n\treturn rb_float_new(pow((double)a, RFLOAT(y)->value));\n      default:\n\treturn rb_num_coerce_bin(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   fix == other\n *\n * Return <code>true</code> if <code>fix</code> equals <code>other</code>\n * numerically.\n *\n *   1 == 2      #=> false\n *   1 == 1.0    #=> true\n */\n\nstatic VALUE\nfix_equal(x, y)\n    VALUE x, y;\n{\n    if (x == y) return Qtrue;\n    if (FIXNUM_P(y)) return Qfalse;\n    return num_equal(x, y);\n}\n\n/*\n *  call-seq:\n *     fix <=> numeric    => -1, 0, +1\n *\n *  Comparison---Returns -1, 0, or +1 depending on whether <i>fix</i> is\n *  less than, equal to, or greater than <i>numeric</i>. This is the\n *  basis for the tests in <code>Comparable</code>.\n */\n\nstatic VALUE\nfix_cmp(x, y)\n    VALUE x, y;\n{\n    if (x == y) return INT2FIX(0);\n    if (FIXNUM_P(y)) {\n\tlong a = FIX2LONG(x), b = FIX2LONG(y);\n\n\tif (a > b) return INT2FIX(1);\n\treturn INT2FIX(-1);\n    }\n    else {\n\treturn rb_num_coerce_cmp(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   fix > other     => true or false\n *\n * Returns <code>true</code> if the value of <code>fix</code> is\n * greater than that of <code>other</code>.\n */\n\nstatic VALUE\nfix_gt(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong a = FIX2LONG(x), b = FIX2LONG(y);\n\n\tif (a > b) return Qtrue;\n\treturn Qfalse;\n    }\n    else {\n\treturn rb_num_coerce_relop(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   fix >= other     => true or false\n *\n * Returns <code>true</code> if the value of <code>fix</code> is\n * greater than or equal to that of <code>other</code>.\n */\n\nstatic VALUE\nfix_ge(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong a = FIX2LONG(x), b = FIX2LONG(y);\n\n\tif (a >= b) return Qtrue;\n\treturn Qfalse;\n    }\n    else {\n\treturn rb_num_coerce_relop(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   fix < other     => true or false\n *\n * Returns <code>true</code> if the value of <code>fix</code> is\n * less than that of <code>other</code>.\n */\n\nstatic VALUE\nfix_lt(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong a = FIX2LONG(x), b = FIX2LONG(y);\n\n\tif (a < b) return Qtrue;\n\treturn Qfalse;\n    }\n    else {\n\treturn rb_num_coerce_relop(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   fix <= other     => true or false\n *\n * Returns <code>true</code> if the value of <code>fix</code> is\n * less thanor equal to that of <code>other</code>.\n */\n\nstatic VALUE\nfix_le(x, y)\n    VALUE x, y;\n{\n    if (FIXNUM_P(y)) {\n\tlong a = FIX2LONG(x), b = FIX2LONG(y);\n\n\tif (a <= b) return Qtrue;\n\treturn Qfalse;\n    }\n    else {\n\treturn rb_num_coerce_relop(x, y);\n    }\n}\n\n/*\n * call-seq:\n *   ~fix     => integer\n *\n * One's complement: returns a number where each bit is flipped.\n */\n\nstatic VALUE\nfix_rev(num)\n    VALUE num;\n{\n    long val = FIX2LONG(num);\n\n    val = ~val;\n    return LONG2NUM(val);\n}\n\nstatic VALUE\nfix_coerce(x)\n    VALUE x;\n{\n    while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) {\n\tx = rb_to_int(x);\n    }\n    return x;\n}\n\n/*\n * call-seq:\n *   fix & other     => integer\n *\n * Bitwise AND.\n */\n\nstatic VALUE\nfix_and(x, y)\n    VALUE x, y;\n{\n    long val;\n\n    if (!FIXNUM_P(y = fix_coerce(y))) {\n\treturn rb_big_and(y, x);\n    }\n    val = FIX2LONG(x) & FIX2LONG(y);\n    return LONG2NUM(val);\n}\n\n/*\n * call-seq:\n *   fix | other     => integer\n *\n * Bitwise OR.\n */\n\nstatic VALUE\nfix_or(x, y)\n    VALUE x, y;\n{\n    long val;\n\n    if (!FIXNUM_P(y = fix_coerce(y))) {\n\treturn rb_big_or(y, x);\n    }\n    val = FIX2LONG(x) | FIX2LONG(y);\n    return LONG2NUM(val);\n}\n\n/*\n * call-seq:\n *   fix ^ other     => integer\n *\n * Bitwise EXCLUSIVE OR.\n */\n\nstatic VALUE\nfix_xor(x, y)\n    VALUE x, y;\n{\n    long val;\n\n    if (!FIXNUM_P(y = fix_coerce(y))) {\n\treturn rb_big_xor(y, x);\n    }\n    val = FIX2LONG(x) ^ FIX2LONG(y);\n    return LONG2NUM(val);\n}\n\nstatic VALUE fix_lshift _((long, unsigned long));\nstatic VALUE fix_rshift _((long, unsigned long));\n\n/*\n * call-seq:\n *   fix << count     => integer\n *\n * Shifts _fix_ left _count_ positions (right if _count_ is negative).\n */\n\nstatic VALUE\nrb_fix_lshift(x, y)\n    VALUE x, y;\n{\n    long val, width;\n\n    val = NUM2LONG(x);\n    if (!FIXNUM_P(y))\n\treturn rb_big_lshift(rb_int2big(val), y);\n    width = FIX2LONG(y);\n    if (width < 0)\n\treturn fix_rshift(val, (unsigned long)-width);\n    return fix_lshift(val, width);\n}\n\nstatic VALUE\nfix_lshift(val, width)\n    long val;\n    unsigned long width;\n{\n    if (width > (sizeof(VALUE)*CHAR_BIT-1)\n\t|| ((unsigned long)val)>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) {\n\treturn rb_big_lshift(rb_int2big(val), ULONG2NUM(width));\n    }\n    val = val << width;\n    return LONG2NUM(val);\n}\n\n/*\n * call-seq:\n *   fix >> count     => integer\n *\n * Shifts _fix_ right _count_ positions (left if _count_ is negative).\n */\n\nstatic VALUE\nrb_fix_rshift(x, y)\n    VALUE x, y;\n{\n    long i, val;\n\n    val = FIX2LONG(x);\n    if (!FIXNUM_P(y))\n\treturn rb_big_rshift(rb_int2big(val), y);\n    i = FIX2LONG(y);\n    if (i == 0) return x;\n    if (i < 0)\n\treturn fix_lshift(val, (unsigned long)-i);\n    return fix_rshift(val, i);\n}\n\nstatic VALUE\nfix_rshift(long val, unsigned long i)\n{\n    if (i >= sizeof(long)*CHAR_BIT-1) {\n\tif (val < 0) return INT2FIX(-1);\n\treturn INT2FIX(0);\n    }\n    val = RSHIFT(val, i);\n    return LONG2FIX(val);\n}\n\n/*\n *  call-seq:\n *     fix[n]     => 0, 1\n *\n *  Bit Reference---Returns the <em>n</em>th bit in the binary\n *  representation of <i>fix</i>, where <i>fix</i>[0] is the least\n *  significant bit.\n *\n *     a = 0b11001100101010\n *     30.downto(0) do |n| print a[n] end\n *\n *  <em>produces:</em>\n *\n *     0000000000000000011001100101010\n */\n\nstatic VALUE\nfix_aref(fix, idx)\n    VALUE fix, idx;\n{\n    long val = FIX2LONG(fix);\n    long i;\n\n    if (!FIXNUM_P(idx = fix_coerce(idx))) {\n\tidx = rb_big_norm(idx);\n\tif (!FIXNUM_P(idx)) {\n\t    if (!RBIGNUM(idx)->sign || val >= 0)\n\t\treturn INT2FIX(0);\n\t    return INT2FIX(1);\n\t}\n    }\n    i = FIX2LONG(idx);\n\n    if (i < 0) return INT2FIX(0);\n    if (sizeof(VALUE)*CHAR_BIT-1 < i) {\n\tif (val < 0) return INT2FIX(1);\n\treturn INT2FIX(0);\n    }\n    if (val & (1L<<i))\n\treturn INT2FIX(1);\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     fix.to_f -> float\n *\n *  Converts <i>fix</i> to a <code>Float</code>.\n *\n */\n\nstatic VALUE\nfix_to_f(num)\n    VALUE num;\n{\n    double val;\n\n    val = (double)FIX2LONG(num);\n\n    return rb_float_new(val);\n}\n\n/*\n *  call-seq:\n *     fix.abs -> aFixnum\n *\n *  Returns the absolute value of <i>fix</i>.\n *\n *     -12345.abs   #=> 12345\n *     12345.abs    #=> 12345\n *\n */\n\nstatic VALUE\nfix_abs(fix)\n    VALUE fix;\n{\n    long i = FIX2LONG(fix);\n\n    if (i < 0) i = -i;\n\n    return LONG2NUM(i);\n}\n\n/*\n *  call-seq:\n *     fix.id2name -> string or nil\n *\n *  Returns the name of the object whose symbol id is <i>fix</i>. If\n *  there is no symbol in the symbol table with this value, returns\n *  <code>nil</code>. <code>id2name</code> has nothing to do with the\n *  <code>Object.id</code> method. See also <code>Fixnum#to_sym</code>,\n *  <code>String#intern</code>, and class <code>Symbol</code>.\n *\n *     symbol = :@inst_var    #=> :@inst_var\n *     id     = symbol.to_i   #=> 9818\n *     id.id2name             #=> \"@inst_var\"\n */\n\nstatic VALUE\nfix_id2name(fix)\n    VALUE fix;\n{\n    const char *name = rb_id2name(FIX2UINT(fix));\n    if (name) return rb_str_new2(name);\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     fix.to_sym -> aSymbol\n *\n *  Returns the symbol whose integer value is <i>fix</i>. See also\n *  <code>Fixnum#id2name</code>.\n *\n *     fred = :fred.to_i\n *     fred.id2name   #=> \"fred\"\n *     fred.to_sym    #=> :fred\n */\n\nstatic VALUE\nfix_to_sym(fix)\n    VALUE fix;\n{\n    ID id = FIX2UINT(fix);\n\n    if (rb_id2name(id)) {\n\treturn ID2SYM(id);\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     fix.size -> fixnum\n *\n *  Returns the number of <em>bytes</em> in the machine representation\n *  of a <code>Fixnum</code>.\n *\n *     1.size            #=> 4\n *     -1.size           #=> 4\n *     2147483647.size   #=> 4\n */\n\nstatic VALUE\nfix_size(fix)\n    VALUE fix;\n{\n    return INT2FIX(sizeof(long));\n}\n\n/*\n *  call-seq:\n *     int.upto(limit) {|i| block }     => int\n *\n *  Iterates <em>block</em>, passing in integer values from <i>int</i>\n *  up to and including <i>limit</i>.\n *\n *     5.upto(10) { |i| print i, \" \" }\n *\n *  <em>produces:</em>\n *\n *     5 6 7 8 9 10\n */\n\nstatic VALUE\nint_upto(from, to)\n    VALUE from, to;\n{\n    RETURN_ENUMERATOR(from, 1, &to);\n\n    if (FIXNUM_P(from) && FIXNUM_P(to)) {\n\tlong i, end;\n\n\tend = FIX2LONG(to);\n\tfor (i = FIX2LONG(from); i <= end; i++) {\n\t    rb_yield(LONG2FIX(i));\n\t}\n    }\n    else {\n\tVALUE i = from, c;\n\n\twhile (!(c = rb_funcall(i, '>', 1, to))) {\n\t    rb_yield(i);\n\t    i = rb_funcall(i, '+', 1, INT2FIX(1));\n\t}\n\tif (NIL_P(c)) rb_cmperr(i, to);\n    }\n    return from;\n}\n\n/*\n *  call-seq:\n *     int.downto(limit) {|i| block }     => int\n *\n *  Iterates <em>block</em>, passing decreasing values from <i>int</i>\n *  down to and including <i>limit</i>.\n *\n *     5.downto(1) { |n| print n, \".. \" }\n *     print \"  Liftoff!\\n\"\n *\n *  <em>produces:</em>\n *\n *     5.. 4.. 3.. 2.. 1..   Liftoff!\n */\n\nstatic VALUE\nint_downto(from, to)\n    VALUE from, to;\n{\n    RETURN_ENUMERATOR(from, 1, &to);\n\n    if (FIXNUM_P(from) && FIXNUM_P(to)) {\n\tlong i, end;\n\n\tend = FIX2LONG(to);\n\tfor (i=FIX2LONG(from); i >= end; i--) {\n\t    rb_yield(LONG2FIX(i));\n\t}\n    }\n    else {\n\tVALUE i = from, c;\n\n\twhile (!(c = rb_funcall(i, '<', 1, to))) {\n\t    rb_yield(i);\n\t    i = rb_funcall(i, '-', 1, INT2FIX(1));\n\t}\n\tif (NIL_P(c)) rb_cmperr(i, to);\n    }\n    return from;\n}\n\n/*\n *  call-seq:\n *     int.times {|i| block }     => int\n *\n *  Iterates block <i>int</i> times, passing in values from zero to\n *  <i>int</i> - 1.\n *\n *     5.times do |i|\n *       print i, \" \"\n *     end\n *\n *  <em>produces:</em>\n *\n *     0 1 2 3 4\n */\n\nstatic VALUE\nint_dotimes(num)\n    VALUE num;\n{\n    RETURN_ENUMERATOR(num, 0, 0);\n\n    if (FIXNUM_P(num)) {\n\tlong i, end;\n\n\tend = FIX2LONG(num);\n\tfor (i=0; i<end; i++) {\n\t    rb_yield(LONG2FIX(i));\n\t}\n    }\n    else {\n\tVALUE i = INT2FIX(0);\n\n\tfor (;;) {\n\t    if (!RTEST(rb_funcall(i, '<', 1, num))) break;\n\t    rb_yield(i);\n\t    i = rb_funcall(i, '+', 1, INT2FIX(1));\n\t}\n    }\n    return num;\n}\n\n/*\n *  call-seq:\n *     fix.zero?    => true or false\n *\n *  Returns <code>true</code> if <i>fix</i> is zero.\n *\n */\n\nstatic VALUE\nfix_zero_p(num)\n    VALUE num;\n{\n    if (FIX2LONG(num) == 0) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     fix.odd? -> true or false\n *\n *  Returns <code>true</code> if <i>fix</i> is an odd number.\n */\n\nstatic VALUE\nfix_odd_p(VALUE num)\n{\n    if (num & 2) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     fix.even? -> true or false\n *\n *  Returns <code>true</code> if <i>fix</i> is an even number.\n */\n\nstatic VALUE\nfix_even_p(VALUE num)\n{\n    if (num & 2) {\n        return Qfalse;\n    }\n    return Qtrue;\n}\n\nvoid\nInit_Numeric()\n{\n#if defined(__FreeBSD__) && __FreeBSD__ < 4\n    /* allow divide by zero -- Inf */\n    fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL));\n#elif defined(_UNICOSMP)\n    /* Turn off floating point exceptions for divide by zero, etc. */\n    _set_Creg(0, 0);\n#elif defined(__BORLANDC__)\n    /* Turn off floating point exceptions for overflow, etc. */\n    _control87(MCW_EM, MCW_EM);\n#endif\n    id_coerce = rb_intern(\"coerce\");\n    id_to_i = rb_intern(\"to_i\");\n    id_eq = rb_intern(\"==\");\n\n    rb_eZeroDivError = rb_define_class(\"ZeroDivisionError\", rb_eStandardError);\n    rb_eFloatDomainError = rb_define_class(\"FloatDomainError\", rb_eRangeError);\n    rb_cNumeric = rb_define_class(\"Numeric\", rb_cObject);\n\n    rb_define_method(rb_cNumeric, \"singleton_method_added\", num_sadded, 1);\n    rb_include_module(rb_cNumeric, rb_mComparable);\n    rb_define_method(rb_cNumeric, \"initialize_copy\", num_init_copy, 1);\n    rb_define_method(rb_cNumeric, \"coerce\", num_coerce, 1);\n\n    rb_define_method(rb_cNumeric, \"+@\", num_uplus, 0);\n    rb_define_method(rb_cNumeric, \"-@\", num_uminus, 0);\n    rb_define_method(rb_cNumeric, \"<=>\", num_cmp, 1);\n    rb_define_method(rb_cNumeric, \"eql?\", num_eql, 1);\n    rb_define_method(rb_cNumeric, \"quo\", num_quo, 1);\n    rb_define_method(rb_cNumeric, \"fdiv\", num_quo, 1);\n    rb_define_method(rb_cNumeric, \"div\", num_div, 1);\n    rb_define_method(rb_cNumeric, \"divmod\", num_divmod, 1);\n    rb_define_method(rb_cNumeric, \"modulo\", num_modulo, 1);\n    rb_define_method(rb_cNumeric, \"remainder\", num_remainder, 1);\n    rb_define_method(rb_cNumeric, \"abs\", num_abs, 0);\n    rb_define_method(rb_cNumeric, \"to_int\", num_to_int, 0);\n\n    rb_define_method(rb_cNumeric, \"integer?\", num_int_p, 0);\n    rb_define_method(rb_cNumeric, \"zero?\", num_zero_p, 0);\n    rb_define_method(rb_cNumeric, \"nonzero?\", num_nonzero_p, 0);\n\n    rb_define_method(rb_cNumeric, \"floor\", num_floor, 0);\n    rb_define_method(rb_cNumeric, \"ceil\", num_ceil, 0);\n    rb_define_method(rb_cNumeric, \"round\", num_round, 0);\n    rb_define_method(rb_cNumeric, \"truncate\", num_truncate, 0);\n    rb_define_method(rb_cNumeric, \"step\", num_step, -1);\n\n    rb_cInteger = rb_define_class(\"Integer\", rb_cNumeric);\n    rb_undef_alloc_func(rb_cInteger);\n    rb_undef_method(CLASS_OF(rb_cInteger), \"new\");\n\n    rb_define_method(rb_cInteger, \"integer?\", int_int_p, 0);\n    rb_define_method(rb_cInteger, \"odd?\", int_odd_p, 0);\n    rb_define_method(rb_cInteger, \"even?\", int_even_p, 0);\n    rb_define_method(rb_cInteger, \"upto\", int_upto, 1);\n    rb_define_method(rb_cInteger, \"downto\", int_downto, 1);\n    rb_define_method(rb_cInteger, \"times\", int_dotimes, 0);\n    rb_include_module(rb_cInteger, rb_mPrecision);\n    rb_define_method(rb_cInteger, \"succ\", int_succ, 0);\n    rb_define_method(rb_cInteger, \"next\", int_succ, 0);\n    rb_define_method(rb_cInteger, \"pred\", int_pred, 0);\n    rb_define_method(rb_cInteger, \"chr\", int_chr, 0);\n    rb_define_method(rb_cInteger, \"ord\", int_ord, 0);\n    rb_define_method(rb_cInteger, \"to_i\", int_to_i, 0);\n    rb_define_method(rb_cInteger, \"to_int\", int_to_i, 0);\n    rb_define_method(rb_cInteger, \"floor\", int_to_i, 0);\n    rb_define_method(rb_cInteger, \"ceil\", int_to_i, 0);\n    rb_define_method(rb_cInteger, \"round\", int_to_i, 0);\n    rb_define_method(rb_cInteger, \"truncate\", int_to_i, 0);\n\n    rb_cFixnum = rb_define_class(\"Fixnum\", rb_cInteger);\n    rb_include_module(rb_cFixnum, rb_mPrecision);\n    rb_define_singleton_method(rb_cFixnum, \"induced_from\", rb_fix_induced_from, 1);\n    rb_define_singleton_method(rb_cInteger, \"induced_from\", rb_int_induced_from, 1);\n\n    rb_define_method(rb_cFixnum, \"to_s\", fix_to_s, -1);\n\n    rb_define_method(rb_cFixnum, \"id2name\", fix_id2name, 0);\n    rb_define_method(rb_cFixnum, \"to_sym\", fix_to_sym, 0);\n\n    rb_define_method(rb_cFixnum, \"-@\", fix_uminus, 0);\n    rb_define_method(rb_cFixnum, \"+\", fix_plus, 1);\n    rb_define_method(rb_cFixnum, \"-\", fix_minus, 1);\n    rb_define_method(rb_cFixnum, \"*\", fix_mul, 1);\n    rb_define_method(rb_cFixnum, \"/\", fix_div, 1);\n    rb_define_method(rb_cFixnum, \"div\", fix_div, 1);\n    rb_define_method(rb_cFixnum, \"%\", fix_mod, 1);\n    rb_define_method(rb_cFixnum, \"modulo\", fix_mod, 1);\n    rb_define_method(rb_cFixnum, \"divmod\", fix_divmod, 1);\n    rb_define_method(rb_cFixnum, \"quo\", fix_quo, 1);\n    rb_define_method(rb_cFixnum, \"fdiv\", fix_quo, 1);\n    rb_define_method(rb_cFixnum, \"**\", fix_pow, 1);\n\n    rb_define_method(rb_cFixnum, \"abs\", fix_abs, 0);\n\n    rb_define_method(rb_cFixnum, \"==\", fix_equal, 1);\n    rb_define_method(rb_cFixnum, \"<=>\", fix_cmp, 1);\n    rb_define_method(rb_cFixnum, \">\",  fix_gt, 1);\n    rb_define_method(rb_cFixnum, \">=\", fix_ge, 1);\n    rb_define_method(rb_cFixnum, \"<\",  fix_lt, 1);\n    rb_define_method(rb_cFixnum, \"<=\", fix_le, 1);\n\n    rb_define_method(rb_cFixnum, \"~\", fix_rev, 0);\n    rb_define_method(rb_cFixnum, \"&\", fix_and, 1);\n    rb_define_method(rb_cFixnum, \"|\", fix_or,  1);\n    rb_define_method(rb_cFixnum, \"^\", fix_xor, 1);\n    rb_define_method(rb_cFixnum, \"[]\", fix_aref, 1);\n\n    rb_define_method(rb_cFixnum, \"<<\", rb_fix_lshift, 1);\n    rb_define_method(rb_cFixnum, \">>\", rb_fix_rshift, 1);\n\n    rb_define_method(rb_cFixnum, \"to_f\", fix_to_f, 0);\n    rb_define_method(rb_cFixnum, \"size\", fix_size, 0);\n    rb_define_method(rb_cFixnum, \"zero?\", fix_zero_p, 0);\n    rb_define_method(rb_cFixnum, \"odd?\", fix_odd_p, 0);\n    rb_define_method(rb_cFixnum, \"even?\", fix_even_p, 0);\n\n    rb_cFloat  = rb_define_class(\"Float\", rb_cNumeric);\n\n    rb_undef_alloc_func(rb_cFloat);\n    rb_undef_method(CLASS_OF(rb_cFloat), \"new\");\n\n    rb_define_singleton_method(rb_cFloat, \"induced_from\", rb_flo_induced_from, 1);\n    rb_include_module(rb_cFloat, rb_mPrecision);\n\n    rb_define_const(rb_cFloat, \"ROUNDS\", INT2FIX(FLT_ROUNDS));\n    rb_define_const(rb_cFloat, \"RADIX\", INT2FIX(FLT_RADIX));\n    rb_define_const(rb_cFloat, \"MANT_DIG\", INT2FIX(DBL_MANT_DIG));\n    rb_define_const(rb_cFloat, \"DIG\", INT2FIX(DBL_DIG));\n    rb_define_const(rb_cFloat, \"MIN_EXP\", INT2FIX(DBL_MIN_EXP));\n    rb_define_const(rb_cFloat, \"MAX_EXP\", INT2FIX(DBL_MAX_EXP));\n    rb_define_const(rb_cFloat, \"MIN_10_EXP\", INT2FIX(DBL_MIN_10_EXP));\n    rb_define_const(rb_cFloat, \"MAX_10_EXP\", INT2FIX(DBL_MAX_10_EXP));\n    rb_define_const(rb_cFloat, \"MIN\", rb_float_new(DBL_MIN));\n    rb_define_const(rb_cFloat, \"MAX\", rb_float_new(DBL_MAX));\n    rb_define_const(rb_cFloat, \"EPSILON\", rb_float_new(DBL_EPSILON));\n\n    rb_define_method(rb_cFloat, \"to_s\", flo_to_s, 0);\n    rb_define_method(rb_cFloat, \"coerce\", flo_coerce, 1);\n    rb_define_method(rb_cFloat, \"-@\", flo_uminus, 0);\n    rb_define_method(rb_cFloat, \"+\", flo_plus, 1);\n    rb_define_method(rb_cFloat, \"-\", flo_minus, 1);\n    rb_define_method(rb_cFloat, \"*\", flo_mul, 1);\n    rb_define_method(rb_cFloat, \"/\", flo_div, 1);\n    rb_define_method(rb_cFloat, \"%\", flo_mod, 1);\n    rb_define_method(rb_cFloat, \"modulo\", flo_mod, 1);\n    rb_define_method(rb_cFloat, \"divmod\", flo_divmod, 1);\n    rb_define_method(rb_cFloat, \"**\", flo_pow, 1);\n    rb_define_method(rb_cFloat, \"==\", flo_eq, 1);\n    rb_define_method(rb_cFloat, \"<=>\", flo_cmp, 1);\n    rb_define_method(rb_cFloat, \">\",  flo_gt, 1);\n    rb_define_method(rb_cFloat, \">=\", flo_ge, 1);\n    rb_define_method(rb_cFloat, \"<\",  flo_lt, 1);\n    rb_define_method(rb_cFloat, \"<=\", flo_le, 1);\n    rb_define_method(rb_cFloat, \"eql?\", flo_eql, 1);\n    rb_define_method(rb_cFloat, \"hash\", flo_hash, 0);\n    rb_define_method(rb_cFloat, \"to_f\", flo_to_f, 0);\n    rb_define_method(rb_cFloat, \"abs\", flo_abs, 0);\n    rb_define_method(rb_cFloat, \"zero?\", flo_zero_p, 0);\n\n    rb_define_method(rb_cFloat, \"to_i\", flo_truncate, 0);\n    rb_define_method(rb_cFloat, \"to_int\", flo_truncate, 0);\n    rb_define_method(rb_cFloat, \"floor\", flo_floor, 0);\n    rb_define_method(rb_cFloat, \"ceil\", flo_ceil, 0);\n    rb_define_method(rb_cFloat, \"round\", flo_round, 0);\n    rb_define_method(rb_cFloat, \"truncate\", flo_truncate, 0);\n\n    rb_define_method(rb_cFloat, \"nan?\",      flo_is_nan_p, 0);\n    rb_define_method(rb_cFloat, \"infinite?\", flo_is_infinite_p, 0);\n    rb_define_method(rb_cFloat, \"finite?\",   flo_is_finite_p, 0);\n}\n"
  },
  {
    "path": "object.c",
    "content": "/**********************************************************************\n\n  object.c -\n\n  $Author$\n  $Date$\n  created at: Thu Jul 15 12:01:24 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"st.h\"\n#include \"util.h\"\n#include <stdio.h>\n#include <errno.h>\n#include <ctype.h>\n#include <math.h>\n\nVALUE rb_mKernel;\nVALUE rb_cObject;\nVALUE rb_cModule;\nVALUE rb_cClass;\nVALUE rb_cData;\n\nVALUE rb_cNilClass;\nVALUE rb_cTrueClass;\nVALUE rb_cFalseClass;\nVALUE rb_cSymbol;\n\n#ifdef GC_DEBUG\nint longlife_moved_objs_count = 0;\n#endif\n\nstatic ID id_eq, id_eql, id_inspect, id_init_copy;\n\n/*\n *  call-seq:\n *     obj === other   => true or false\n *\n *  Case Equality---For class <code>Object</code>, effectively the same\n *  as calling  <code>#==</code>, but typically overridden by descendents\n *  to provide meaningful semantics in <code>case</code> statements.\n */\n\nVALUE\nrb_equal(obj1, obj2)\n    VALUE obj1, obj2;\n{\n    VALUE result;\n\n    if (obj1 == obj2) return Qtrue;\n    result = rb_funcall(obj1, id_eq, 1, obj2);\n    if (RTEST(result)) return Qtrue;\n    return Qfalse;\n}\n\nint\nrb_eql(obj1, obj2)\n    VALUE obj1, obj2;\n{\n    return RTEST(rb_funcall(obj1, id_eql, 1, obj2));\n}\n\n/*\n *  call-seq:\n *     obj == other        => true or false\n *     obj.equal?(other)   => true or false\n *     obj.eql?(other)     => true or false\n *\n *  Equality---At the <code>Object</code> level, <code>==</code> returns\n *  <code>true</code> only if <i>obj</i> and <i>other</i> are the\n *  same object. Typically, this method is overridden in descendent\n *  classes to provide class-specific meaning.\n *\n *  Unlike <code>==</code>, the <code>equal?</code> method should never be\n *  overridden by subclasses: it is used to determine object identity\n *  (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same\n *  object as <code>b</code>).\n *\n *  The <code>eql?</code> method returns <code>true</code> if\n    <i>obj</i> and <i>anObject</i> have the\n *  same value. Used by <code>Hash</code> to test members for equality.\n *  For objects of class <code>Object</code>, <code>eql?</code> is\n *  synonymous with <code>==</code>. Subclasses normally continue this\n *  tradition, but there are exceptions. <code>Numeric</code> types, for\n *  example, perform type conversion across <code>==</code>, but not\n *  across <code>eql?</code>, so:\n *\n *     1 == 1.0     #=> true\n *     1.eql? 1.0   #=> false\n */\n\nstatic VALUE\nrb_obj_equal(obj1, obj2)\n    VALUE obj1, obj2;\n{\n    if (obj1 == obj2) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj.id    => fixnum\n *\n *  Soon-to-be deprecated version of <code>Object#object_id</code>.\n */\n\nVALUE\nrb_obj_id_obsolete(obj)\n    VALUE obj;\n{\n    rb_warn(\"Object#id will be deprecated; use Object#object_id\");\n    return rb_obj_id(obj);\n}\n\nVALUE\nrb_class_real(cl)\n    VALUE cl;\n{\n    while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) {\n        cl = RCLASS(cl)->super;\n    }\n    return cl;\n}\n\n/*\n *  call-seq:\n *     obj.type   => class\n *\n *  Deprecated synonym for <code>Object#class</code>.\n */\n\nVALUE\nrb_obj_type(obj)\n    VALUE obj;\n{\n    rb_warn(\"Object#type is deprecated; use Object#class\");\n    return rb_class_real(CLASS_OF(obj));\n}\n\n\n/*\n *  call-seq:\n *     obj.class    => class\n *\n *  Returns the class of <i>obj</i>, now preferred over\n *  <code>Object#type</code>, as an object's type in Ruby is only\n *  loosely tied to that object's class. This method must always be\n *  called with an explicit receiver, as <code>class</code> is also a\n *  reserved word in Ruby.\n *\n *     1.class      #=> Fixnum\n *     self.class   #=> Object\n */\n\nVALUE\nrb_obj_class(obj)\n    VALUE obj;\n{\n    return rb_class_real(CLASS_OF(obj));\n}\n\nstatic void\ninit_copy(dest, obj)\n    VALUE dest, obj;\n{\n    if (OBJ_FROZEN(dest)) {\n        rb_raise(rb_eTypeError, \"[bug] frozen object (%s) allocated\", rb_obj_classname(dest));\n    }\n    RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);\n    RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT);\n    if (FL_TEST(obj, FL_EXIVAR)) {\n        rb_copy_generic_ivar(dest, obj);\n    }\n    rb_gc_copy_finalizer(dest, obj);\n    switch (TYPE(obj)) {\n      case T_OBJECT:\n      case T_CLASS:\n      case T_MODULE:\n        if (ROBJECT(dest)->iv_tbl) {\n            st_free_table(ROBJECT(dest)->iv_tbl);\n            ROBJECT(dest)->iv_tbl = 0;\n        }\n        if (ROBJECT(obj)->iv_tbl) {\n            ROBJECT(dest)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl);\n        }\n    }\n    rb_funcall(dest, id_init_copy, 1, obj);\n}\n\n/*\n *  call-seq:\n *     obj.clone -> an_object\n *\n *  Produces a shallow copy of <i>obj</i>---the instance variables of\n *  <i>obj</i> are copied, but not the objects they reference. Copies\n *  the frozen and tainted state of <i>obj</i>. See also the discussion\n *  under <code>Object#dup</code>.\n *\n *     class Klass\n *        attr_accessor :str\n *     end\n *     s1 = Klass.new      #=> #<Klass:0x401b3a38>\n *     s1.str = \"Hello\"    #=> \"Hello\"\n *     s2 = s1.clone       #=> #<Klass:0x401b3998 @str=\"Hello\">\n *     s2.str[1,4] = \"i\"   #=> \"i\"\n *     s1.inspect          #=> \"#<Klass:0x401b3a38 @str=\\\"Hi\\\">\"\n *     s2.inspect          #=> \"#<Klass:0x401b3998 @str=\\\"Hi\\\">\"\n *\n *  This method may have class-specific behavior.  If so, that\n *  behavior will be documented under the #+initialize_copy+ method of\n *  the class.\n */\n\nVALUE\nrb_obj_clone(obj)\n    VALUE obj;\n{\n    VALUE clone;\n\n    if (rb_special_const_p(obj)) {\n        rb_raise(rb_eTypeError, \"can't clone %s\", rb_obj_classname(obj));\n    }\n    clone = rb_obj_alloc(rb_obj_class(obj));\n    RBASIC(clone)->klass = rb_singleton_class_clone(obj);\n    RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE);\n    init_copy(clone, obj);\n    RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;\n\n    return clone;\n}\n\n/* :nodoc: */\nVALUE\nrb_obj_freeze(VALUE obj)\n{\n    int i;\n    if (!OBJ_MOVED(obj)) {\n        obj = rb_obj_move(obj);\n        switch (TYPE(obj)) {\n          case T_HASH:\n            st_foreach_map(RHASH(obj)->tbl, rb_obj_freeze, rb_obj_freeze);\n            break;\n          case T_ARRAY:\n            for (i = 0; i < RARRAY(obj)->len; i++) {\n                rb_ary_store(obj, i, rb_obj_freeze(rb_ary_entry(obj, i)));\n            }\n            break;\n        }\n    }\n    if (!OBJ_FROZEN(obj) && TYPE(obj) != T_CLASS && TYPE(obj) != T_MODULE) {\n        if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj)) {\n            rb_raise(rb_eSecurityError, \"Insecure: can't freeze object\");\n        }\n        OBJ_FREEZE(obj);\n    }\n    return obj;\n}\n\n/*\n *  call-seq:\n *     obj.dup -> an_object\n *\n *  Produces a shallow copy of <i>obj</i>---the instance variables of\n *  <i>obj</i> are copied, but not the objects they reference.\n *  <code>dup</code> copies the tainted state of <i>obj</i>. See also\n *  the discussion under <code>Object#clone</code>. In general,\n *  <code>clone</code> and <code>dup</code> may have different semantics\n *  in descendent classes. While <code>clone</code> is used to duplicate\n *  an object, including its internal state, <code>dup</code> typically\n *  uses the class of the descendent object to create the new instance.\n *\n *  This method may have class-specific behavior.  If so, that\n *  behavior will be documented under the #+initialize_copy+ method of\n *  the class.\n */\n\nVALUE\nrb_obj_dup(obj)\n    VALUE obj;\n{\n    VALUE dup;\n\n    if (rb_special_const_p(obj)) {\n        rb_raise(rb_eTypeError, \"can't dup %s\", rb_obj_classname(obj));\n    }\n    dup = rb_obj_alloc(rb_obj_class(obj));\n    init_copy(dup, obj);\n\n    return dup;\n}\n\n/* :nodoc: */\nVALUE\nrb_obj_init_copy(obj, orig)\n    VALUE obj, orig;\n{\n    if (obj == orig) return obj;\n    rb_check_frozen(obj);\n    if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {\n        rb_raise(rb_eTypeError, \"initialize_copy should take same class object\");\n    }\n    return obj;\n}\n\n/*\n *  call-seq:\n *     obj.to_a -> anArray\n *\n *  Returns an array representation of <i>obj</i>. For objects of class\n *  <code>Object</code> and others that don't explicitly override the\n *  method, the return value is an array containing <code>self</code>.\n *  However, this latter behavior will soon be obsolete.\n *\n *     self.to_a       #=> -:1: warning: default `to_a' will be obsolete\n *     \"hello\".to_a    #=> [\"hello\"]\n *     Time.new.to_a   #=> [39, 54, 8, 9, 4, 2003, 3, 99, true, \"CDT\"]\n */\n\n\nstatic VALUE\nrb_any_to_a(obj)\n    VALUE obj;\n{\n    rb_warn(\"default `to_a' will be obsolete\");\n    return rb_ary_new3(1, obj);\n}\n\n\n/*\n *  call-seq:\n *     obj.to_s    => string\n *\n *  Returns a string representing <i>obj</i>. The default\n *  <code>to_s</code> prints the object's class and an encoding of the\n *  object id. As a special case, the top-level object that is the\n *  initial execution context of Ruby programs returns ``main.''\n */\n\nVALUE\nrb_any_to_s(obj)\n    VALUE obj;\n{\n    const char *cname = rb_obj_classname(obj);\n    size_t len;\n    VALUE str;\n\n    len = strlen(cname)+6+16;\n    str = rb_str_new(0, len); /* 6:tags 16:addr */\n    snprintf(RSTRING(str)->ptr, len+1, \"#<%s:0x%lx>\", cname, obj);\n    RSTRING(str)->len = strlen(RSTRING(str)->ptr);\n    if (OBJ_TAINTED(obj)) OBJ_TAINT(str);\n\n    return str;\n}\n\nVALUE\nrb_inspect(obj)\n    VALUE obj;\n{\n    return rb_obj_as_string(rb_funcall(obj, id_inspect, 0, 0));\n}\n\nstatic int\ninspect_i(id, value, str)\n    ID id;\n    VALUE value;\n    VALUE str;\n{\n    VALUE str2;\n    const char *ivname;\n\n    /* need not to show internal data */\n    if (CLASS_OF(value) == 0) return ST_CONTINUE;\n    if (!rb_is_instance_id(id)) return ST_CONTINUE;\n    if (RSTRING(str)->ptr[0] == '-') { /* first element */\n        RSTRING(str)->ptr[0] = '#';\n        rb_str_cat2(str, \" \");\n    }\n    else {\n        rb_str_cat2(str, \", \");\n    }\n    ivname = rb_id2name(id);\n    rb_str_cat2(str, ivname);\n    rb_str_cat2(str, \"=\");\n    str2 = rb_inspect(value);\n    rb_str_append(str, str2);\n    OBJ_INFECT(str, str2);\n\n    return ST_CONTINUE;\n}\n\nstatic VALUE\ninspect_obj(obj, str)\n    VALUE obj, str;\n{\n    st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str);\n    rb_str_cat2(str, \">\");\n    RSTRING(str)->ptr[0] = '#';\n    OBJ_INFECT(str, obj);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     obj.inspect   => string\n *\n *  Returns a string containing a human-readable representation of\n *  <i>obj</i>. If not overridden, uses the <code>to_s</code> method to\n *  generate the string.\n *\n *     [ 1, 2, 3..4, 'five' ].inspect   #=> \"[1, 2, 3..4, \\\"five\\\"]\"\n *     Time.new.inspect                 #=> \"Wed Apr 09 08:54:39 CDT 2003\"\n */\n\n\nstatic VALUE\nrb_obj_inspect(obj)\n    VALUE obj;\n{\n    if (TYPE(obj) == T_OBJECT\n        && ROBJECT(obj)->iv_tbl\n        && ROBJECT(obj)->iv_tbl->num_entries > 0) {\n        VALUE str;\n        size_t len;\n        const char *c = rb_obj_classname(obj);\n\n        if (rb_inspecting_p(obj)) {\n            len = strlen(c)+10+16+1;\n            str = rb_str_new(0, len); /* 10:tags 16:addr 1:nul */\n            snprintf(RSTRING(str)->ptr, len, \"#<%s:0x%lx ...>\", c, obj);\n            RSTRING(str)->len = strlen(RSTRING(str)->ptr);\n            return str;\n        }\n        len = strlen(c)+6+16+1;\n        str = rb_str_new(0, len);     /* 6:tags 16:addr 1:nul */\n        snprintf(RSTRING(str)->ptr, len, \"-<%s:0x%lx\", c, obj);\n        RSTRING(str)->len = strlen(RSTRING(str)->ptr);\n        return rb_protect_inspect(inspect_obj, obj, str);\n    }\n    return rb_funcall(obj, rb_intern(\"to_s\"), 0, 0);\n}\n\n\n/*\n *  call-seq:\n *     obj.instance_of?(class)    => true or false\n *\n *  Returns <code>true</code> if <i>obj</i> is an instance of the given\n *  class. See also <code>Object#kind_of?</code>.\n */\n\nVALUE\nrb_obj_is_instance_of(obj, c)\n    VALUE obj, c;\n{\n    switch (TYPE(c)) {\n      case T_MODULE:\n      case T_CLASS:\n      case T_ICLASS:\n        break;\n      default:\n        rb_raise(rb_eTypeError, \"class or module required\");\n    }\n\n    if (rb_obj_class(obj) == c) return Qtrue;\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     obj.is_a?(class)       => true or false\n *     obj.kind_of?(class)    => true or false\n *\n *  Returns <code>true</code> if <i>class</i> is the class of\n *  <i>obj</i>, or if <i>class</i> is one of the superclasses of\n *  <i>obj</i> or modules included in <i>obj</i>.\n *\n *     module M;    end\n *     class A\n *       include M\n *     end\n *     class B < A; end\n *     class C < B; end\n *     b = B.new\n *     b.instance_of? A   #=> false\n *     b.instance_of? B   #=> true\n *     b.instance_of? C   #=> false\n *     b.instance_of? M   #=> false\n *     b.kind_of? A       #=> true\n *     b.kind_of? B       #=> true\n *     b.kind_of? C       #=> false\n *     b.kind_of? M       #=> true\n */\n\nVALUE\nrb_obj_is_kind_of(obj, c)\n    VALUE obj, c;\n{\n    VALUE cl = CLASS_OF(obj);\n\n    switch (TYPE(c)) {\n      case T_MODULE:\n      case T_CLASS:\n      case T_ICLASS:\n        break;\n\n      default:\n        rb_raise(rb_eTypeError, \"class or module required\");\n    }\n\n    while (cl) {\n        if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl)\n            return Qtrue;\n        cl = RCLASS(cl)->super;\n    }\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     obj.tap{|x|...}    => obj\n *\n *  Yields <code>x</code> to the block, and then returns <code>x</code>.\n *  The primary purpose of this method is to \"tap into\" a method chain,\n *  in order to perform operations on intermediate results within the chain.\n *\n *      (1..10).tap {\n *        |x| puts \"original: #{x.inspect}\"\n *      }.to_a.tap {\n *        |x| puts \"array: #{x.inspect}\"\n *      }.select {|x| x%2==0}.tap {\n *        |x| puts \"evens: #{x.inspect}\"\n *      }.map {|x| x*x}.tap {\n *        |x| puts \"squares: #{x.inspect}\"\n *      }\n *\n */\n\nVALUE\nrb_obj_tap(obj)\n    VALUE obj;\n{\n    rb_yield(obj);\n    return obj;\n}\n\n\n/*\n * Document-method: inherited\n *\n * call-seq:\n *    inherited(subclass)\n *\n * Callback invoked whenever a subclass of the current class is created.\n *\n * Example:\n *\n *    class Foo\n *       def self.inherited(subclass)\n *          puts \"New subclass: #{subclass}\"\n *       end\n *    end\n *\n *    class Bar < Foo\n *    end\n *\n *    class Baz < Bar\n *    end\n *\n * produces:\n *\n *    New subclass: Bar\n *    New subclass: Baz\n */\n\n/*\n * Document-method: singleton_method_added\n *\n *  call-seq:\n *     singleton_method_added(symbol)\n *\n *  Invoked as a callback whenever a singleton method is added to the\n *  receiver.\n *\n *     module Chatty\n *       def Chatty.singleton_method_added(id)\n *         puts \"Adding #{id.id2name}\"\n *       end\n *       def self.one()     end\n *       def two()          end\n *       def Chatty.three() end\n *     end\n *\n *  <em>produces:</em>\n *\n *     Adding singleton_method_added\n *     Adding one\n *     Adding three\n *\n */\n\n/*\n * Document-method: singleton_method_removed\n *\n *  call-seq:\n *     singleton_method_removed(symbol)\n *\n *  Invoked as a callback whenever a singleton method is removed from\n *  the receiver.\n *\n *     module Chatty\n *       def Chatty.singleton_method_removed(id)\n *         puts \"Removing #{id.id2name}\"\n *       end\n *       def self.one()     end\n *       def two()          end\n *       def Chatty.three() end\n *       class <<self\n *         remove_method :three\n *         remove_method :one\n *       end\n *     end\n *\n *  <em>produces:</em>\n *\n *     Removing three\n *     Removing one\n */\n\n/*\n * Document-method: singleton_method_undefined\n *\n *  call-seq:\n *     singleton_method_undefined(symbol)\n *\n *  Invoked as a callback whenever a singleton method is undefined in\n *  the receiver.\n *\n *     module Chatty\n *       def Chatty.singleton_method_undefined(id)\n *         puts \"Undefining #{id.id2name}\"\n *       end\n *       def Chatty.one()   end\n *       class << self\n *          undef_method(:one)\n *       end\n *     end\n *\n *  <em>produces:</em>\n *\n *     Undefining one\n */\n\n\n/*\n * Document-method: included\n *\n * call-seq:\n *    included( othermod )\n *\n * Callback invoked whenever the receiver is included in another\n * module or class. This should be used in preference to\n * <tt>Module.append_features</tt> if your code wants to perform some\n * action when a module is included in another.\n *\n *        module A\n *          def A.included(mod)\n *            puts \"#{self} included in #{mod}\"\n *          end\n *        end\n *        module Enumerable\n *          include A\n *        end\n */\n\n\n/*\n * Not documented\n */\n\nstatic VALUE\nrb_obj_dummy()\n{\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     obj.tainted?    => true or false\n *\n *  Returns <code>true</code> if the object is tainted.\n */\n\nVALUE\nrb_obj_tainted(obj)\n    VALUE obj;\n{\n    if (OBJ_TAINTED(obj))\n        return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj.taint -> obj\n *\n *  Marks <i>obj</i> as tainted---if the <code>$SAFE</code> level is\n *  set appropriately, many method calls which might alter the running\n *  programs environment will refuse to accept tainted strings.\n */\n\nVALUE\nrb_obj_taint(obj)\n    VALUE obj;\n{\n    rb_secure(4);\n    if (!OBJ_TAINTED(obj)) {\n        if (OBJ_FROZEN(obj)) {\n            rb_error_frozen(\"object\");\n        }\n        OBJ_TAINT(obj);\n    }\n    return obj;\n}\n\n\n/*\n *  call-seq:\n *     obj.untaint    => obj\n *\n *  Removes the taint from <i>obj</i>.\n */\n\nVALUE\nrb_obj_untaint(obj)\n    VALUE obj;\n{\n    rb_secure(3);\n    if (OBJ_TAINTED(obj)) {\n        if (OBJ_FROZEN(obj)) {\n            rb_error_frozen(\"object\");\n        }\n        FL_UNSET(obj, FL_TAINT);\n    }\n    return obj;\n}\n\nvoid\nrb_obj_infect(obj1, obj2)\n    VALUE obj1, obj2;\n{\n    OBJ_INFECT(obj1, obj2);\n}\n\n\n/*\n *  call-seq:\n *     obj.freeze    => obj\n *\n *  Prevents further modifications to <i>obj</i>. A\n *  <code>TypeError</code> will be raised if modification is attempted.\n *  There is no way to unfreeze a frozen object. See also\n *  <code>Object#frozen?</code>.\n *\n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.freeze\n *     a << \"z\"\n *\n *  <em>produces:</em>\n *\n *     prog.rb:3:in `<<': can't modify frozen array (TypeError)\n *      from prog.rb:3\n */\n\nVALUE\nrb_obj_move(obj)\n    VALUE obj;\n{\n    if (!OBJ_MOVED(obj)) {\n        if (TYPE(obj) == T_STRING) {\n            obj = rb_str_move(obj);\n        } else {\n            /* Currently has no real effect */\n            OBJ_MOVE(obj);\n        }\n    }\n    return obj;\n}\n\n/*\n *  call-seq:\n *     obj.frozen?    => true or false\n *\n *  Returns the freeze status of <i>obj</i>.\n *\n *     a = [ \"a\", \"b\", \"c\" ]\n *     a.freeze    #=> [\"a\", \"b\", \"c\"]\n *     a.frozen?   #=> true\n */\n\nstatic VALUE\nrb_obj_frozen_p(obj)\n    VALUE obj;\n{\n    if (OBJ_FROZEN(obj)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj.moved?    => true or false\n *\n *  Returns the moved status of <i>obj</i>.\n *\n */\n\nstatic VALUE\nrb_obj_moved_p(obj)\n    VALUE obj;\n{\n    if (OBJ_MOVED(obj)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     obj.longlived?    => true or false\n *\n *  Returns whether <i>obj</i> is on the longlife heap.\n *\n */\n\nstatic VALUE\nrb_obj_longlived_p(obj)\n    VALUE obj;\n{\n    if (OBJ_LONGLIVED(obj)) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * Document-class: NilClass\n *\n *  The class of the singleton object <code>nil</code>.\n */\n\n/*\n *  call-seq:\n *     nil.to_i => 0\n *\n *  Always returns zero.\n *\n *     nil.to_i   #=> 0\n */\n\n\nstatic VALUE\nnil_to_i(obj)\n    VALUE obj;\n{\n    return INT2FIX(0);\n}\n\n/*\n *  call-seq:\n *     nil.to_f    => 0.0\n *\n *  Always returns zero.\n *\n *     nil.to_f   #=> 0.0\n */\n\nstatic VALUE\nnil_to_f(obj)\n    VALUE obj;\n{\n    return rb_float_new(0.0);\n}\n\n/*\n *  call-seq:\n *     nil.to_s    => \"\"\n *\n *  Always returns the empty string.\n *\n *     nil.to_s   #=> \"\"\n */\n\nstatic VALUE\nnil_to_s(obj)\n    VALUE obj;\n{\n    return rb_str_new2(\"\");\n}\n\n/*\n *  call-seq:\n *     nil.to_a    => []\n *\n *  Always returns an empty array.\n *\n *     nil.to_a   #=> []\n */\n\nstatic VALUE\nnil_to_a(obj)\n    VALUE obj;\n{\n    return rb_ary_new2(0);\n}\n\n/*\n *  call-seq:\n *    nil.inspect  => \"nil\"\n *\n *  Always returns the string \"nil\".\n */\n\nstatic VALUE\nnil_inspect(obj)\n    VALUE obj;\n{\n    return rb_str_new2(\"nil\");\n}\n\nstatic VALUE\nmain_to_s(obj)\n    VALUE obj;\n{\n    return rb_str_new2(\"main\");\n}\n\n\n/***********************************************************************\n *  Document-class: TrueClass\n *\n *  The global value <code>true</code> is the only instance of class\n *  <code>TrueClass</code> and represents a logically true value in\n *  boolean expressions. The class provides operators allowing\n *  <code>true</code> to be used in logical expressions.\n */\n\n\n/*\n * call-seq:\n *   true.to_s   =>  \"true\"\n *\n * The string representation of <code>true</code> is \"true\".\n */\n\nstatic VALUE\ntrue_to_s(obj)\n    VALUE obj;\n{\n    return rb_str_new2(\"true\");\n}\n\n\n/*\n *  call-seq:\n *     true & obj    => true or false\n *\n *  And---Returns <code>false</code> if <i>obj</i> is\n *  <code>nil</code> or <code>false</code>, <code>true</code> otherwise.\n */\n\nstatic VALUE\ntrue_and(obj, obj2)\n    VALUE obj, obj2;\n{\n    return RTEST(obj2)?Qtrue:Qfalse;\n}\n\n/*\n *  call-seq:\n *     true | obj   => true\n *\n *  Or---Returns <code>true</code>. As <i>anObject</i> is an argument to\n *  a method call, it is always evaluated; there is no short-circuit\n *  evaluation in this case.\n *\n *     true |  puts(\"or\")\n *     true || puts(\"logical or\")\n *\n *  <em>produces:</em>\n *\n *     or\n */\n\nstatic VALUE\ntrue_or(obj, obj2)\n    VALUE obj, obj2;\n{\n    return Qtrue;\n}\n\n\n/*\n *  call-seq:\n *     true ^ obj   => !obj\n *\n *  Exclusive Or---Returns <code>true</code> if <i>obj</i> is\n *  <code>nil</code> or <code>false</code>, <code>false</code>\n *  otherwise.\n */\n\nstatic VALUE\ntrue_xor(obj, obj2)\n    VALUE obj, obj2;\n{\n    return RTEST(obj2)?Qfalse:Qtrue;\n}\n\n\n/*\n *  Document-class: FalseClass\n *\n *  The global value <code>false</code> is the only instance of class\n *  <code>FalseClass</code> and represents a logically false value in\n *  boolean expressions. The class provides operators allowing\n *  <code>false</code> to participate correctly in logical expressions.\n *\n */\n\n/*\n * call-seq:\n *   false.to_s   =>  \"false\"\n *\n * 'nuf said...\n */\n\nstatic VALUE\nfalse_to_s(obj)\n    VALUE obj;\n{\n    return rb_str_new2(\"false\");\n}\n\n/*\n *  call-seq:\n *     false & obj   => false\n *     nil & obj     => false\n *\n *  And---Returns <code>false</code>. <i>obj</i> is always\n *  evaluated as it is the argument to a method call---there is no\n *  short-circuit evaluation in this case.\n */\n\nstatic VALUE\nfalse_and(obj, obj2)\n    VALUE obj, obj2;\n{\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     false | obj   =>   true or false\n *     nil   | obj   =>   true or false\n *\n *  Or---Returns <code>false</code> if <i>obj</i> is\n *  <code>nil</code> or <code>false</code>; <code>true</code> otherwise.\n */\n\nstatic VALUE\nfalse_or(obj, obj2)\n    VALUE obj, obj2;\n{\n    return RTEST(obj2)?Qtrue:Qfalse;\n}\n\n\n\n/*\n *  call-seq:\n *     false ^ obj    => true or false\n *     nil   ^ obj    => true or false\n *\n *  Exclusive Or---If <i>obj</i> is <code>nil</code> or\n *  <code>false</code>, returns <code>false</code>; otherwise, returns\n *  <code>true</code>.\n *\n */\n\nstatic VALUE\nfalse_xor(obj, obj2)\n    VALUE obj, obj2;\n{\n    return RTEST(obj2)?Qtrue:Qfalse;\n}\n\n/*\n * call_seq:\n *   nil.nil?               => true\n *\n * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.\n */\n\nstatic VALUE\nrb_true(obj)\n    VALUE obj;\n{\n    return Qtrue;\n}\n\n/*\n * call_seq:\n *   nil.nil?               => true\n *   <anything_else>.nil?   => false\n *\n * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.\n */\n\n\nstatic VALUE\nrb_false(obj)\n    VALUE obj;\n{\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     obj =~ other  => false\n *\n *  Pattern Match---Overridden by descendents (notably\n *  <code>Regexp</code> and <code>String</code>) to provide meaningful\n *  pattern-match semantics.\n */\n\nstatic VALUE\nrb_obj_pattern_match(obj1, obj2)\n    VALUE obj1, obj2;\n{\n    return Qfalse;\n}\n\n/**********************************************************************\n * Document-class: Symbol\n *\n *  <code>Symbol</code> objects represent names and some strings\n *  inside the Ruby\n *  interpreter. They are generated using the <code>:name</code> and\n *  <code>:\"string\"</code> literals\n *  syntax, and by the various <code>to_sym</code> methods. The same\n *  <code>Symbol</code> object will be created for a given name or string\n *  for the duration of a program's execution, regardless of the context\n *  or meaning of that name. Thus if <code>Fred</code> is a constant in\n *  one context, a method in another, and a class in a third, the\n *  <code>Symbol</code> <code>:Fred</code> will be the same object in\n *  all three contexts.\n *\n *     module One\n *       class Fred\n *       end\n *       $f1 = :Fred\n *     end\n *     module Two\n *       Fred = 1\n *       $f2 = :Fred\n *     end\n *     def Fred()\n *     end\n *     $f3 = :Fred\n *     $f1.id   #=> 2514190\n *     $f2.id   #=> 2514190\n *     $f3.id   #=> 2514190\n *\n */\n\n/*\n *  call-seq:\n *     sym.to_i      => fixnum\n *\n *  Returns an integer that is unique for each symbol within a\n *  particular execution of a program.\n *\n *     :fred.to_i           #=> 9809\n *     \"fred\".to_sym.to_i   #=> 9809\n */\n\nstatic VALUE\nsym_to_i(sym)\n    VALUE sym;\n{\n    ID id = SYM2ID(sym);\n\n    return LONG2FIX(id);\n}\n\n\n/* :nodoc: */\n\nstatic VALUE\nsym_to_int(sym)\n    VALUE sym;\n{\n    rb_warning(\"treating Symbol as an integer\");\n    return sym_to_i(sym);\n}\n\n\n/*\n *  call-seq:\n *     sym.inspect    => string\n *\n *  Returns the representation of <i>sym</i> as a symbol literal.\n *\n *     :fred.inspect   #=> \":fred\"\n */\n\nstatic VALUE\nsym_inspect(sym)\n    VALUE sym;\n{\n    VALUE str;\n    const char *name;\n    ID id = SYM2ID(sym);\n\n    name = rb_id2name(id);\n    str = rb_str_new(0, strlen(name)+1);\n    RSTRING(str)->ptr[0] = ':';\n    strcpy(RSTRING(str)->ptr+1, name);\n    if (!rb_symname_p(name)) {\n        str = rb_str_dump(str);\n        strncpy(RSTRING(str)->ptr, \":\\\"\", 2);\n    }\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     sym.id2name   => string\n *     sym.to_s      => string\n *\n *  Returns the name or string corresponding to <i>sym</i>.\n *\n *     :fred.id2name   #=> \"fred\"\n */\n\n\nstatic VALUE\nsym_to_s(sym)\n    VALUE sym;\n{\n    return rb_str_new2(rb_id2name(SYM2ID(sym)));\n}\n\n\n/*\n * call-seq:\n *   sym.to_sym   => sym\n *\n * In general, <code>to_sym</code> returns the <code>Symbol</code> corresponding\n * to an object. As <i>sym</i> is already a symbol, <code>self</code> is returned\n * in this case.\n */\n\nstatic VALUE\nsym_to_sym(sym)\n    VALUE sym;\n{\n    return sym;\n}\n\n\nstatic VALUE\nsym_call(args, mid)\n    VALUE args, mid;\n{\n    VALUE obj;\n\n    if (RARRAY(args)->len < 1) {\n        rb_raise(rb_eArgError, \"no receiver given\");\n    }\n    obj = rb_ary_shift(args);\n    return rb_apply(obj, (ID)mid, args);\n}\n\nVALUE rb_proc_new _((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));\n\n/*\n * call-seq:\n *   sym.to_proc\n *\n * Returns a _Proc_ object which respond to the given method by _sym_.\n *\n *   (1..3).collect(&:to_s)  #=> [\"1\", \"2\", \"3\"]\n */\n\nstatic VALUE\nsym_to_proc(VALUE sym)\n{\n    return rb_proc_new(sym_call, (VALUE)SYM2ID(sym));\n}\n\n\n/***********************************************************************\n *\n * Document-class: Module\n *\n *  A <code>Module</code> is a collection of methods and constants. The\n *  methods in a module may be instance methods or module methods.\n *  Instance methods appear as methods in a class when the module is\n *  included, module methods do not. Conversely, module methods may be\n *  called without creating an encapsulating object, while instance\n *  methods may not. (See <code>Module#module_function</code>)\n *\n *  In the descriptions that follow, the parameter <i>syml</i> refers\n *  to a symbol, which is either a quoted string or a\n *  <code>Symbol</code> (such as <code>:name</code>).\n *\n *     module Mod\n *       include Math\n *       CONST = 1\n *       def meth\n *         #  ...\n *       end\n *     end\n *     Mod.class              #=> Module\n *     Mod.constants          #=> [\"E\", \"PI\", \"CONST\"]\n *     Mod.instance_methods   #=> [\"meth\"]\n *\n */\n\n/*\n * call-seq:\n *   mod.to_s   => string\n *\n * Return a string representing this module or class. For basic\n * classes and modules, this is the name. For singletons, we\n * show information on the thing we're attached to as well.\n */\n\nstatic VALUE\nrb_mod_to_s(klass)\n    VALUE klass;\n\n{\n    if (FL_TEST(klass, FL_SINGLETON)) {\n        VALUE s = rb_str_new2(\"#<\");\n        VALUE v = rb_iv_get(klass, \"__attached__\");\n\n        rb_str_cat2(s, \"Class:\");\n        switch (TYPE(v)) {\n          case T_CLASS: case T_MODULE:\n            rb_str_append(s, rb_inspect(v));\n            break;\n          default:\n            rb_str_append(s, rb_any_to_s(v));\n            break;\n        }\n        rb_str_cat2(s, \">\");\n\n        return s;\n    }\n    return rb_str_dup(rb_class_name(klass));\n}\n\n/*\n *  call-seq:\n *     mod.freeze\n *\n *  Prevents further modifications to <i>mod</i>.\n */\n\nstatic VALUE\nrb_mod_freeze(mod)\n    VALUE mod;\n{\n    rb_mod_to_s(mod);\n    return rb_obj_freeze(mod);\n}\n\n/*\n *  call-seq:\n *     mod === obj    => true or false\n *\n *  Case Equality---Returns <code>true</code> if <i>anObject</i> is an\n *  instance of <i>mod</i> or one of <i>mod</i>'s descendents. Of\n *  limited use for modules, but can be used in <code>case</code>\n *  statements to classify objects by class.\n */\n\nstatic VALUE\nrb_mod_eqq(mod, arg)\n    VALUE mod, arg;\n{\n    return rb_obj_is_kind_of(arg, mod);\n}\n\n/*\n * call-seq:\n *   mod <= other   =>  true, false, or nil\n *\n * Returns true if <i>mod</i> is a subclass of <i>other</i> or\n * is the same as <i>other</i>. Returns\n * <code>nil</code> if there's no relationship between the two.\n * (Think of the relationship in terms of the class definition:\n * \"class A<B\" implies \"A<B\").\n *\n */\n\nVALUE\nrb_class_inherited_p(mod, arg)\n    VALUE mod, arg;\n{\n    VALUE start = mod;\n\n    if (mod == arg) return Qtrue;\n    switch (TYPE(arg)) {\n      case T_MODULE:\n      case T_CLASS:\n        break;\n      default:\n        rb_raise(rb_eTypeError, \"compared with non class/module\");\n    }\n\n    if (FL_TEST(mod, FL_SINGLETON)) {\n        if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)\n            return Qtrue;\n        mod = RBASIC(mod)->klass;\n    }\n    while (mod) {\n        if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)\n            return Qtrue;\n        mod = RCLASS(mod)->super;\n    }\n    /* not mod < arg; check if mod > arg */\n    while (arg) {\n        if (RCLASS(arg)->m_tbl == RCLASS(start)->m_tbl)\n            return Qfalse;\n        arg = RCLASS(arg)->super;\n    }\n    return Qnil;\n}\n\n/*\n * call-seq:\n *   mod < other   =>  true, false, or nil\n *\n * Returns true if <i>mod</i> is a subclass of <i>other</i>. Returns\n * <code>nil</code> if there's no relationship between the two.\n * (Think of the relationship in terms of the class definition:\n * \"class A<B\" implies \"A<B\").\n *\n */\n\nstatic VALUE\nrb_mod_lt(mod, arg)\n    VALUE mod, arg;\n{\n    if (mod == arg) return Qfalse;\n    return rb_class_inherited_p(mod, arg);\n}\n\n\n/*\n * call-seq:\n *   mod >= other   =>  true, false, or nil\n *\n * Returns true if <i>mod</i> is an ancestor of <i>other</i>, or the\n * two modules are the same. Returns\n * <code>nil</code> if there's no relationship between the two.\n * (Think of the relationship in terms of the class definition:\n * \"class A<B\" implies \"B>A\").\n *\n */\n\nstatic VALUE\nrb_mod_ge(mod, arg)\n    VALUE mod, arg;\n{\n    switch (TYPE(arg)) {\n      case T_MODULE:\n      case T_CLASS:\n        break;\n      default:\n        rb_raise(rb_eTypeError, \"compared with non class/module\");\n    }\n\n    return rb_class_inherited_p(arg, mod);\n}\n\n/*\n * call-seq:\n *   mod > other   =>  true, false, or nil\n *\n * Returns true if <i>mod</i> is an ancestor of <i>other</i>. Returns\n * <code>nil</code> if there's no relationship between the two.\n * (Think of the relationship in terms of the class definition:\n * \"class A<B\" implies \"B>A\").\n *\n */\n\nstatic VALUE\nrb_mod_gt(mod, arg)\n    VALUE mod, arg;\n{\n    if (mod == arg) return Qfalse;\n    return rb_mod_ge(mod, arg);\n}\n\n/*\n *  call-seq:\n *     mod <=> other_mod   => -1, 0, +1, or nil\n *\n *  Comparison---Returns -1 if <i>mod</i> includes <i>other_mod</i>, 0 if\n *  <i>mod</i> is the same as <i>other_mod</i>, and +1 if <i>mod</i> is\n *  included by <i>other_mod</i> or if <i>mod</i> has no relationship with\n *  <i>other_mod</i>. Returns <code>nil</code> if <i>other_mod</i> is\n *  not a module.\n */\n\nstatic VALUE\nrb_mod_cmp(mod, arg)\n    VALUE mod, arg;\n{\n    VALUE cmp;\n\n    if (mod == arg) return INT2FIX(0);\n    switch (TYPE(arg)) {\n      case T_MODULE:\n      case T_CLASS:\n        break;\n      default:\n        return Qnil;\n    }\n\n    cmp = rb_class_inherited_p(mod, arg);\n    if (NIL_P(cmp)) return Qnil;\n    if (cmp) {\n        return INT2FIX(-1);\n    }\n    return INT2FIX(1);\n}\n\nstatic VALUE rb_module_s_alloc _((VALUE));\nstatic VALUE\nrb_module_s_alloc(klass)\n    VALUE klass;\n{\n    VALUE mod = rb_module_new();\n\n    RBASIC(mod)->klass = klass;\n    return mod;\n}\n\nstatic VALUE rb_class_s_alloc _((VALUE));\nstatic VALUE\nrb_class_s_alloc(klass)\n    VALUE klass;\n{\n    return rb_class_boot(0);\n}\n\n/*\n *  call-seq:\n *    Module.new                  => mod\n *    Module.new {|mod| block }   => mod\n *\n *  Creates a new anonymous module. If a block is given, it is passed\n *  the module object, and the block is evaluated in the context of this\n *  module using <code>module_eval</code>.\n *\n *     Fred = Module.new do\n *       def meth1\n *         \"hello\"\n *       end\n *       def meth2\n *         \"bye\"\n *       end\n *     end\n *     a = \"my string\"\n *     a.extend(Fred)   #=> \"my string\"\n *     a.meth1          #=> \"hello\"\n *     a.meth2          #=> \"bye\"\n */\n\nstatic VALUE\nrb_mod_initialize(module)\n    VALUE module;\n{\n    if (rb_block_given_p()) {\n        rb_mod_module_eval(0, 0, module);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     Class.new(super_class=Object)   =>    a_class\n *\n *  Creates a new anonymous (unnamed) class with the given superclass\n *  (or <code>Object</code> if no parameter is given). You can give a\n *  class a name by assigning the class object to a constant.\n *\n */\n\nstatic VALUE\nrb_class_initialize(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE super;\n\n    if (RCLASS(klass)->super != 0) {\n        rb_raise(rb_eTypeError, \"already initialized class\");\n    }\n    if (rb_scan_args(argc, argv, \"01\", &super) == 0) {\n        super = rb_cObject;\n    }\n    else {\n        rb_check_inheritable(super);\n    }\n    RCLASS(klass)->super = super;\n    rb_make_metaclass(klass, RBASIC(super)->klass);\n    rb_mod_initialize(klass);\n    rb_class_inherited(super, klass);\n\n    return klass;\n}\n\n/*\n *  call-seq:\n *     class.allocate()   =>   obj\n *\n *  Allocates space for a new object of <i>class</i>'s class and does not\n *  call initialize on the new instance. The returned object must be an\n *  instance of <i>class</i>.\n *\n *      klass = Class.new do\n *        def initialize(*args)\n *          @initialized = true\n *        end\n *\n *        def initialized?\n *          @initialized || false\n *        end\n *      end\n *\n *      klass.allocate.initialized? #=> false\n *\n */\n\nVALUE\nrb_obj_alloc(klass)\n    VALUE klass;\n{\n    VALUE obj;\n\n    if (RCLASS(klass)->super == 0) {\n        rb_raise(rb_eTypeError, \"can't instantiate uninitialized class\");\n    }\n    if (FL_TEST(klass, FL_SINGLETON)) {\n        rb_raise(rb_eTypeError, \"can't create instance of virtual class\");\n    }\n    obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0);\n    if (rb_obj_class(obj) != rb_class_real(klass)) {\n        rb_raise(rb_eTypeError, \"wrong instance allocation\");\n    }\n    return obj;\n}\n\nstatic VALUE rb_class_allocate_instance _((VALUE));\nstatic VALUE\nrb_class_allocate_instance(klass)\n    VALUE klass;\n{\n    NEWOBJ(obj, struct RObject);\n    OBJSETUP(obj, klass, T_OBJECT);\n    return (VALUE)obj;\n}\n\n/*\n *  call-seq:\n *     class.new(args, ...)    =>  obj\n *\n *  Calls <code>allocate</code> to create a new object of\n *  <i>class</i>'s class, then invokes that object's\n *  <code>initialize</code> method, passing it <i>args</i>.\n *  This is the method that ends up getting called whenever\n *  an object is constructed using .new.\n *\n */\n\nVALUE\nrb_class_new_instance(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE obj;\n\n    obj = rb_obj_alloc(klass);\n    rb_obj_call_init(obj, argc, argv);\n\n    return obj;\n}\n\n/*\n *  call-seq:\n *     class.superclass -> a_super_class or nil\n *\n *  Returns the superclass of <i>class</i>, or <code>nil</code>.\n *\n *     File.superclass     #=> IO\n *     IO.superclass       #=> Object\n *     Object.superclass   #=> nil\n *\n */\n\nstatic VALUE\nrb_class_superclass(klass)\n    VALUE klass;\n{\n    VALUE super = RCLASS(klass)->super;\n\n    if (!super) {\n        rb_raise(rb_eTypeError, \"uninitialized class\");\n    }\n    if (FL_TEST(klass, FL_SINGLETON)) {\n        super = RBASIC(klass)->klass;\n    }\n    while (TYPE(super) == T_ICLASS) {\n        super = RCLASS(super)->super;\n    }\n    if (!super) {\n        return Qnil;\n    }\n    return super;\n}\n\nstatic ID\nstr_to_id(str)\n    VALUE str;\n{\n    VALUE sym = rb_str_intern(str);\n\n    return SYM2ID(sym);\n}\n\nID\nrb_to_id(name)\n    VALUE name;\n{\n    VALUE tmp;\n    ID id;\n\n    switch (TYPE(name)) {\n      case T_STRING:\n        return str_to_id(name);\n      case T_FIXNUM:\n        rb_warn(\"do not use Fixnums as Symbols\");\n        id = FIX2LONG(name);\n        if (!rb_id2name(id)) {\n            rb_raise(rb_eArgError, \"%ld is not a symbol\", id);\n        }\n        break;\n      case T_SYMBOL:\n        id = SYM2ID(name);\n        break;\n      default:\n        tmp = rb_check_string_type(name);\n        if (!NIL_P(tmp)) {\n            return str_to_id(tmp);\n        }\n        rb_raise(rb_eTypeError, \"%s is not a symbol\", RSTRING(rb_inspect(name))->ptr);\n    }\n    return id;\n}\n\n/*\n *  call-seq:\n *     attr(symbol, writable=false)    => nil\n *\n *  Defines a named attribute for this module, where the name is\n *  <i>symbol.</i><code>id2name</code>, creating an instance variable\n *  (<code>@name</code>) and a corresponding access method to read it.\n *  If the optional <i>writable</i> argument is <code>true</code>, also\n *  creates a method called <code>name=</code> to set the attribute.\n *\n *     module Mod\n *       attr  :size, true\n *     end\n *\n *  <em>is equivalent to:</em>\n *\n *     module Mod\n *       def size\n *         @size\n *       end\n *       def size=(val)\n *         @size = val\n *       end\n *     end\n */\n\nstatic VALUE\nrb_mod_attr(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE name, pub;\n\n    rb_scan_args(argc, argv, \"11\", &name, &pub);\n    rb_attr(klass, rb_to_id(name), 1, RTEST(pub), Qtrue);\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     attr_reader(symbol, ...)    => nil\n *\n *  Creates instance variables and corresponding methods that return the\n *  value of each instance variable. Equivalent to calling\n *  ``<code>attr</code><i>:name</i>'' on each name in turn.\n */\n\nstatic VALUE\nrb_mod_attr_reader(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_attr(klass, rb_to_id(argv[i]), 1, 0, Qtrue);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *      attr_writer(symbol, ...)    => nil\n *\n *  Creates an accessor method to allow assignment to the attribute\n *  <i>aSymbol</i><code>.id2name</code>.\n */\n\nstatic VALUE\nrb_mod_attr_writer(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_attr(klass, rb_to_id(argv[i]), 0, 1, Qtrue);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     attr_accessor(symbol, ...)    => nil\n *\n *  Equivalent to calling ``<code>attr</code><i>symbol</i><code>,\n *  true</code>'' on each <i>symbol</i> in turn.\n *\n *     module Mod\n *       attr_accessor(:one, :two)\n *     end\n *     Mod.instance_methods.sort   #=> [\"one\", \"one=\", \"two\", \"two=\"]\n */\n\nstatic VALUE\nrb_mod_attr_accessor(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    int i;\n\n    for (i=0; i<argc; i++) {\n        rb_attr(klass, rb_to_id(argv[i]), 1, 1, Qtrue);\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     mod.const_get(sym)    => obj\n *\n *  Returns the value of the named constant in <i>mod</i>.\n *\n *     Math.const_get(:PI)   #=> 3.14159265358979\n */\n\nstatic VALUE\nrb_mod_const_get(mod, name)\n    VALUE mod, name;\n{\n    ID id = rb_to_id(name);\n\n    if (!rb_is_const_id(id)) {\n        rb_name_error(id, \"wrong constant name %s\", rb_id2name(id));\n    }\n    return rb_const_get(mod, id);\n}\n\n/*\n *  call-seq:\n *     mod.const_set(sym, obj)    => obj\n *\n *  Sets the named constant to the given object, returning that object.\n *  Creates a new constant if no constant with the given name previously\n *  existed.\n *\n *     Math.const_set(\"HIGH_SCHOOL_PI\", 22.0/7.0)   #=> 3.14285714285714\n *     Math::HIGH_SCHOOL_PI - Math::PI              #=> 0.00126448926734968\n */\n\nstatic VALUE\nrb_mod_const_set(mod, name, value)\n    VALUE mod, name, value;\n{\n    ID id = rb_to_id(name);\n\n    if (!rb_is_const_id(id)) {\n        rb_name_error(id, \"wrong constant name %s\", rb_id2name(id));\n    }\n    rb_const_set(mod, id, value);\n    return value;\n}\n\n/*\n *  call-seq:\n *     mod.const_defined?(sym)   => true or false\n *\n *  Returns <code>true</code> if a constant with the given name is\n *  defined by <i>mod</i>.\n *\n *     Math.const_defined? \"PI\"   #=> true\n */\n\nstatic VALUE\nrb_mod_const_defined(mod, name)\n    VALUE mod, name;\n{\n    ID id = rb_to_id(name);\n\n    if (!rb_is_const_id(id)) {\n        rb_name_error(id, \"wrong constant name %s\", rb_id2name(id));\n    }\n    return rb_const_defined_at(mod, id);\n}\n\n/*\n *  call-seq:\n *     obj.methods    => array\n *\n *  Returns a list of the names of methods publicly accessible in\n *  <i>obj</i>. This will include all the methods accessible in\n *  <i>obj</i>'s ancestors.\n *\n *     class Klass\n *       def kMethod()\n *       end\n *     end\n *     k = Klass.new\n *     k.methods[0..9]    #=> [\"kMethod\", \"freeze\", \"nil?\", \"is_a?\",\n *                             \"class\", \"instance_variable_set\",\n *                              \"methods\", \"extend\", \"__send__\", \"instance_eval\"]\n *     k.methods.length   #=> 42\n */\n\nstatic VALUE\nrb_obj_methods(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n  retry:\n    if (argc == 0) {\n        VALUE args[1];\n\n        args[0] = Qtrue;\n        return rb_class_instance_methods(1, args, CLASS_OF(obj));\n    }\n    else {\n        VALUE recur;\n\n        rb_scan_args(argc, argv, \"1\", &recur);\n        if (RTEST(recur)) {\n            argc = 0;\n            goto retry;\n        }\n        return rb_obj_singleton_methods(argc, argv, obj);\n    }\n}\n\n/*\n *  call-seq:\n *     obj.protected_methods(all=true)   => array\n *\n *  Returns the list of protected methods accessible to <i>obj</i>. If\n *  the <i>all</i> parameter is set to <code>false</code>, only those methods\n *  in the receiver will be listed.\n */\n\nstatic VALUE\nrb_obj_protected_methods(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    if (argc == 0) {            /* hack to stop warning */\n        VALUE args[1];\n\n        args[0] = Qtrue;\n        return rb_class_protected_instance_methods(1, args, CLASS_OF(obj));\n    }\n    return rb_class_protected_instance_methods(argc, argv, CLASS_OF(obj));\n}\n\n/*\n *  call-seq:\n *     obj.private_methods(all=true)   => array\n *\n *  Returns the list of private methods accessible to <i>obj</i>. If\n *  the <i>all</i> parameter is set to <code>false</code>, only those methods\n *  in the receiver will be listed.\n */\n\nstatic VALUE\nrb_obj_private_methods(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    if (argc == 0) {            /* hack to stop warning */\n        VALUE args[1];\n\n        args[0] = Qtrue;\n        return rb_class_private_instance_methods(1, args, CLASS_OF(obj));\n    }\n    return rb_class_private_instance_methods(argc, argv, CLASS_OF(obj));\n}\n\n/*\n *  call-seq:\n *     obj.public_methods(all=true)   => array\n *\n *  Returns the list of public methods accessible to <i>obj</i>. If\n *  the <i>all</i> parameter is set to <code>false</code>, only those methods\n *  in the receiver will be listed.\n */\n\nstatic VALUE\nrb_obj_public_methods(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    if (argc == 0) {            /* hack to stop warning */\n        VALUE args[1];\n\n        args[0] = Qtrue;\n        return rb_class_public_instance_methods(1, args, CLASS_OF(obj));\n    }\n    return rb_class_public_instance_methods(argc, argv, CLASS_OF(obj));\n}\n\n/*\n *  call-seq:\n *     obj.instance_variable_get(symbol)    => obj\n *\n *  Returns the value of the given instance variable, or nil if the\n *  instance variable is not set. The <code>@</code> part of the\n *  variable name should be included for regular instance\n *  variables. Throws a <code>NameError</code> exception if the\n *  supplied symbol is not valid as an instance variable name.\n *\n *     class Fred\n *       def initialize(p1, p2)\n *         @a, @b = p1, p2\n *       end\n *     end\n *     fred = Fred.new('cat', 99)\n *     fred.instance_variable_get(:@a)    #=> \"cat\"\n *     fred.instance_variable_get(\"@b\")   #=> 99\n */\n\nstatic VALUE\nrb_obj_ivar_get(obj, iv)\n    VALUE obj, iv;\n{\n    ID id = rb_to_id(iv);\n\n    if (!rb_is_instance_id(id)) {\n        rb_name_error(id, \"`%s' is not allowed as an instance variable name\", rb_id2name(id));\n    }\n    return rb_ivar_get(obj, id);\n}\n\n/*\n *  call-seq:\n *     obj.instance_variable_set(symbol, obj)    => obj\n *\n *  Sets the instance variable names by <i>symbol</i> to\n *  <i>object</i>, thereby frustrating the efforts of the class's\n *  author to attempt to provide proper encapsulation. The variable\n *  did not have to exist prior to this call.\n *\n *     class Fred\n *       def initialize(p1, p2)\n *         @a, @b = p1, p2\n *       end\n *     end\n *     fred = Fred.new('cat', 99)\n *     fred.instance_variable_set(:@a, 'dog')   #=> \"dog\"\n *     fred.instance_variable_set(:@c, 'cat')   #=> \"cat\"\n *     fred.inspect                             #=> \"#<Fred:0x401b3da8 @a=\\\"dog\\\", @b=99, @c=\\\"cat\\\">\"\n */\n\nstatic VALUE\nrb_obj_ivar_set(obj, iv, val)\n    VALUE obj, iv, val;\n{\n    ID id = rb_to_id(iv);\n\n    if (!rb_is_instance_id(id)) {\n        rb_name_error(id, \"`%s' is not allowed as an instance variable name\", rb_id2name(id));\n    }\n    return rb_ivar_set(obj, id, val);\n}\n\n/*\n *  call-seq:\n *     obj.instance_variable_defined?(symbol)    => true or false\n *\n *  Returns <code>true</code> if the given instance variable is\n *  defined in <i>obj</i>.\n *\n *     class Fred\n *       def initialize(p1, p2)\n *         @a, @b = p1, p2\n *       end\n *     end\n *     fred = Fred.new('cat', 99)\n *     fred.instance_variable_defined?(:@a)    #=> true\n *     fred.instance_variable_defined?(\"@b\")   #=> true\n *     fred.instance_variable_defined?(\"@c\")   #=> false\n */\n\nstatic VALUE\nrb_obj_ivar_defined(obj, iv)\n    VALUE obj, iv;\n{\n    ID id = rb_to_id(iv);\n\n    if (!rb_is_instance_id(id)) {\n        rb_name_error(id, \"`%s' is not allowed as an instance variable name\", rb_id2name(id));\n    }\n    return rb_ivar_defined(obj, id);\n}\n\n/*\n *  call-seq:\n *     mod.class_variable_get(symbol)    => obj\n *\n *  Returns the value of the given class variable (or throws a\n *  <code>NameError</code> exception). The <code>@@</code> part of the\n *  variable name should be included for regular class variables\n *\n *     class Fred\n *       @@foo = 99\n *     end\n *\n *     def Fred.foo\n *       class_variable_get(:@@foo)     #=> 99\n *     end\n */\n\nstatic VALUE\nrb_mod_cvar_get(obj, iv)\n    VALUE obj, iv;\n{\n    ID id = rb_to_id(iv);\n\n    if (!rb_is_class_id(id)) {\n        rb_name_error(id, \"`%s' is not allowed as a class variable name\", rb_id2name(id));\n    }\n    return rb_cvar_get(obj, id);\n}\n\n/*\n *  call-seq:\n *     obj.class_variable_set(symbol, obj)    => obj\n *\n *  Sets the class variable names by <i>symbol</i> to\n *  <i>object</i>.\n *\n *     class Fred\n *       @@foo = 99\n *       def foo\n *         @@foo\n *       end\n *     end\n *\n *     def Fred.foo\n *       class_variable_set(:@@foo, 101)      #=> 101\n *     end\n *     Fred.foo\n *     Fred.new.foo                             #=> 101\n */\n\nstatic VALUE\nrb_mod_cvar_set(obj, iv, val)\n    VALUE obj, iv, val;\n{\n    ID id = rb_to_id(iv);\n\n    if (!rb_is_class_id(id)) {\n        rb_name_error(id, \"`%s' is not allowed as a class variable name\", rb_id2name(id));\n    }\n    rb_cvar_set(obj, id, val, Qfalse);\n    return val;\n}\n\n/*\n *  call-seq:\n *     obj.class_variable_defined?(symbol)    => true or false\n *\n *  Returns <code>true</code> if the given class variable is defined\n *  in <i>obj</i>.\n *\n *     class Fred\n *       @@foo = 99\n *     end\n *     Fred.class_variable_defined?(:@@foo)    #=> true\n *     Fred.class_variable_defined?(:@@bar)    #=> false\n */\n\nstatic VALUE\nrb_mod_cvar_defined(obj, iv)\n    VALUE obj, iv;\n{\n    ID id = rb_to_id(iv);\n\n    if (!rb_is_class_id(id)) {\n        rb_name_error(id, \"`%s' is not allowed as a class variable name\", rb_id2name(id));\n    }\n    return rb_cvar_defined(obj, id);\n}\n\nstatic VALUE\nconvert_type(val, tname, method, raise)\n    VALUE val;\n    const char *tname, *method;\n    int raise;\n{\n    ID m;\n\n    m = rb_intern(method);\n    if (!rb_respond_to(val, m)) {\n        if (raise) {\n            rb_raise(rb_eTypeError, \"can't convert %s into %s\",\n                     NIL_P(val) ? \"nil\" :\n                     val == Qtrue ? \"true\" :\n                     val == Qfalse ? \"false\" :\n                     rb_obj_classname(val),\n                     tname);\n        }\n        else {\n            return Qnil;\n        }\n    }\n    return rb_funcall(val, m, 0);\n}\n\nVALUE\nrb_convert_type(val, type, tname, method)\n    VALUE val;\n    int type;\n    const char *tname, *method;\n{\n    VALUE v;\n\n    if (TYPE(val) == type) return val;\n    v = convert_type(val, tname, method, Qtrue);\n    if (TYPE(v) != type) {\n        rb_raise(rb_eTypeError, \"%s#%s should return %s\",\n                 rb_obj_classname(val), method, tname);\n    }\n    return v;\n}\n\nVALUE\nrb_check_convert_type(val, type, tname, method)\n    VALUE val;\n    int type;\n    const char *tname, *method;\n{\n    VALUE v;\n\n    /* always convert T_DATA */\n    if (TYPE(val) == type && type != T_DATA) return val;\n    v = convert_type(val, tname, method, Qfalse);\n    if (NIL_P(v)) return Qnil;\n    if (TYPE(v) != type) {\n        rb_raise(rb_eTypeError, \"%s#%s should return %s\",\n                 rb_obj_classname(val), method, tname);\n    }\n    return v;\n}\n\n\nstatic VALUE\nrb_to_integer(val, method)\n    VALUE val;\n    const char *method;\n{\n    VALUE v = convert_type(val, \"Integer\", method, Qtrue);\n    if (!rb_obj_is_kind_of(v, rb_cInteger)) {\n        rb_raise(rb_eTypeError, \"%s#%s should return Integer\",\n                 rb_obj_classname(val), method);\n    }\n    return v;\n}\n\nVALUE\nrb_check_to_integer(VALUE val, const char *method)\n{\n    VALUE v;\n\n    if (FIXNUM_P(val)) return val;\n    v = convert_type(val, \"Integer\", method, Qfalse);\n    if (!rb_obj_is_kind_of(v, rb_cInteger)) {\n        return Qnil;\n    }\n    return v;\n}\n\nVALUE\nrb_to_int(val)\n    VALUE val;\n{\n    return rb_to_integer(val, \"to_int\");\n}\n\nVALUE\nrb_Integer(val)\n    VALUE val;\n{\n    VALUE tmp;\n\n    switch (TYPE(val)) {\n      case T_FLOAT:\n        if (RFLOAT(val)->value <= (double)FIXNUM_MAX\n            && RFLOAT(val)->value >= (double)FIXNUM_MIN) {\n            break;\n        }\n        return rb_dbl2big(RFLOAT(val)->value);\n\n      case T_FIXNUM:\n      case T_BIGNUM:\n        return val;\n\n      case T_STRING:\n        return rb_str_to_inum(val, 0, Qtrue);\n\n      default:\n        break;\n    }\n    tmp = convert_type(val, \"Integer\", \"to_int\", Qfalse);\n    if (NIL_P(tmp)) {\n        return rb_to_integer(val, \"to_i\");\n    }\n    return tmp;\n}\n\n/*\n *  call-seq:\n *     Integer(arg)    => integer\n *\n *  Converts <i>arg</i> to a <code>Fixnum</code> or <code>Bignum</code>.\n *  Numeric types are converted directly (with floating point numbers\n *  being truncated). If <i>arg</i> is a <code>String</code>, leading\n *  radix indicators (<code>0</code>, <code>0b</code>, and\n *  <code>0x</code>) are honored. Others are converted using\n *  <code>to_int</code> and <code>to_i</code>. This behavior is\n *  different from that of <code>String#to_i</code>.\n *\n *     Integer(123.999)    #=> 123\n *     Integer(\"0x1a\")     #=> 26\n *     Integer(Time.new)   #=> 1049896590\n */\n\nstatic VALUE\nrb_f_integer(obj, arg)\n    VALUE obj, arg;\n{\n    return rb_Integer(arg);\n}\n\ndouble\nrb_cstr_to_dbl(p, badcheck)\n    const char *p;\n    int badcheck;\n{\n    const char *q;\n    char *end;\n    double d;\n    const char *ellipsis = \"\";\n    int w;\n#define OutOfRange() (((w = end - p) > 20) ? (w = 20, ellipsis = \"...\") : (ellipsis = \"\"))\n\n    if (!p) return 0.0;\n    q = p;\n    if (badcheck) {\n        while (ISSPACE(*p)) p++;\n    }\n    else {\n        while (ISSPACE(*p) || *p == '_') p++;\n    }\n    errno = 0;\n    d = strtod(p, &end);\n    if (errno == ERANGE) {\n        OutOfRange();\n        rb_warn(\"Float %.*s%s out of range\", w, p, ellipsis);\n        errno = 0;\n    }\n    if (p == end) {\n        if (badcheck) {\n          bad:\n            rb_invalid_str(q, \"Float()\");\n        }\n        return d;\n    }\n    if (*end) {\n        char *buf = ALLOCA_N(char, strlen(p)+1);\n        char *n = buf;\n\n        while (p < end) *n++ = *p++;\n        while (*p) {\n            if (*p == '_') {\n                /* remove underscores between digits */\n                if (badcheck) {\n                    if (n == buf || !ISDIGIT(n[-1])) goto bad;\n                    ++p;\n                    if (!ISDIGIT(*p)) goto bad;\n                }\n                else {\n                    while (*++p == '_');\n                    continue;\n                }\n            }\n            *n++ = *p++;\n        }\n        *n = '\\0';\n        p = buf;\n        d = strtod(p, &end);\n        if (errno == ERANGE) {\n            OutOfRange();\n            rb_warn(\"Float %.*s%s out of range\", w, p, ellipsis);\n            errno = 0;\n        }\n        if (badcheck) {\n            if (!end || p == end) goto bad;\n            while (*end && ISSPACE(*end)) end++;\n            if (*end) goto bad;\n        }\n    }\n    if (errno == ERANGE) {\n        errno = 0;\n        OutOfRange();\n        rb_raise(rb_eArgError, \"Float %.*s%s out of range\", w, q, ellipsis);\n    }\n    return d;\n}\n\ndouble\nrb_str_to_dbl(str, badcheck)\n    VALUE str;\n    int badcheck;\n{\n    char *s;\n    long len;\n\n    StringValue(str);\n    s = RSTRING(str)->ptr;\n    len = RSTRING(str)->len;\n    if (s) {\n        if (s[len]) {           /* no sentinel somehow */\n            char *p = ALLOCA_N(char, len+1);\n\n            MEMCPY(p, s, char, len);\n            p[len] = '\\0';\n            s = p;\n        }\n        if (badcheck && len != strlen(s)) {\n            rb_raise(rb_eArgError, \"string for Float contains null byte\");\n        }\n    }\n    return rb_cstr_to_dbl(s, badcheck);\n}\n\nVALUE\nrb_Float(val)\n    VALUE val;\n{\n    switch (TYPE(val)) {\n      case T_FIXNUM:\n        return rb_float_new((double)FIX2LONG(val));\n\n      case T_FLOAT:\n        return val;\n\n      case T_BIGNUM:\n        return rb_float_new(rb_big2dbl(val));\n\n      case T_STRING:\n        return rb_float_new(rb_str_to_dbl(val, Qtrue));\n\n      case T_NIL:\n        rb_raise(rb_eTypeError, \"can't convert nil into Float\");\n        break;\n\n      default:\n        return rb_convert_type(val, T_FLOAT, \"Float\", \"to_f\");\n\n    }\n}\n\n/*\n *  call-seq:\n *     Float(arg)    => float\n *\n *  Returns <i>arg</i> converted to a float. Numeric types are converted\n *  directly, the rest are converted using <i>arg</i>.to_f. As of Ruby\n *  1.8, converting <code>nil</code> generates a <code>TypeError</code>.\n *\n *     Float(1)           #=> 1.0\n *     Float(\"123.456\")   #=> 123.456\n */\n\nstatic VALUE\nrb_f_float(obj, arg)\n    VALUE obj, arg;\n{\n    return rb_Float(arg);\n}\n\ndouble\nrb_num2dbl(val)\n    VALUE val;\n{\n    switch (TYPE(val)) {\n      case T_FLOAT:\n        return RFLOAT(val)->value;\n\n      case T_STRING:\n        rb_raise(rb_eTypeError, \"no implicit conversion to float from string\");\n        break;\n\n      case T_NIL:\n        rb_raise(rb_eTypeError, \"no implicit conversion to float from nil\");\n        break;\n\n      default:\n        break;\n    }\n\n    return RFLOAT(rb_Float(val))->value;\n}\n\nchar*\nrb_str2cstr(str, len)\n    VALUE str;\n    long *len;\n{\n    StringValue(str);\n    if (len) *len = RSTRING(str)->len;\n    else if (RTEST(ruby_verbose) && RSTRING(str)->len != strlen(RSTRING(str)->ptr)) {\n        rb_warn(\"string contains \\\\0 character\");\n    }\n    return RSTRING(str)->ptr;\n}\n\nVALUE\nrb_String(val)\n    VALUE val;\n{\n    return rb_convert_type(val, T_STRING, \"String\", \"to_s\");\n}\n\n\n/*\n *  call-seq:\n *     String(arg)   => string\n *\n *  Converts <i>arg</i> to a <code>String</code> by calling its\n *  <code>to_s</code> method.\n *\n *     String(self)        #=> \"main\"\n *     String(self.class   #=> \"Object\"\n *     String(123456)      #=> \"123456\"\n */\n\nstatic VALUE\nrb_f_string(obj, arg)\n    VALUE obj, arg;\n{\n    return rb_String(arg);\n}\n\n#if 0\nVALUE\nrb_Array(val)\n    VALUE val;\n{\n    VALUE tmp = rb_check_array_type(val);\n\n    if (NIL_P(tmp)) {\n        tmp = rb_check_convert_type(val, T_ARRAY, \"Array\", \"to_a\");\n        if (NIL_P(tmp)) {\n            return rb_ary_new3(1, val);\n        }\n    }\n    return tmp;\n}\n#endif\n\n/*\n *  call-seq:\n *     Array(arg)    => array\n *\n *  Returns <i>arg</i> as an <code>Array</code>. First tries to call\n *  <i>arg</i><code>.to_ary</code>, then <i>arg</i><code>.to_a</code>.\n *  If both fail, creates a single element array containing <i>arg</i>\n *  (unless <i>arg</i> is <code>nil</code>).\n *\n *     Array(1..5)   #=> [1, 2, 3, 4, 5]\n */\n\nstatic VALUE\nrb_f_array(obj, arg)\n    VALUE obj, arg;\n{\n    return rb_Array(arg);\n}\n\nstatic VALUE\nboot_defclass(name, super)\n    char *name;\n    VALUE super;\n{\n    extern st_table *rb_class_tbl;\n    VALUE obj = rb_class_boot(super);\n    ID id = rb_intern(name);\n\n    rb_name_class(obj, id);\n    st_add_direct(rb_class_tbl, id, obj);\n    rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);\n    return obj;\n}\n\nVALUE ruby_top_self;\n\n/*\n *  Document-class: Class\n *\n *  Classes in Ruby are first-class objects---each is an instance of\n *  class <code>Class</code>.\n *\n *  When a new class is created (typically using <code>class Name ...\n *  end</code>), an object of type <code>Class</code> is created and\n *  assigned to a global constant (<code>Name</code> in this case). When\n *  <code>Name.new</code> is called to create a new object, the\n *  <code>new</code> method in <code>Class</code> is run by default.\n *  This can be demonstrated by overriding <code>new</code> in\n *  <code>Class</code>:\n *\n *     class Class\n *        alias oldNew  new\n *        def new(*args)\n *          print \"Creating a new \", self.name, \"\\n\"\n *          oldNew(*args)\n *        end\n *      end\n *\n *\n *      class Name\n *      end\n *\n *\n *      n = Name.new\n *\n *  <em>produces:</em>\n *\n *     Creating a new Name\n *\n *  Classes, modules, and objects are interrelated. In the diagram\n *  that follows, the vertical arrows represent inheritance, and the\n *  parentheses meta-classes. All metaclasses are instances\n *  of the class `Class'.\n *\n *                            +------------------+\n *                            |                  |\n *              Object---->(Object)              |\n *               ^  ^        ^  ^                |\n *               |  |        |  |                |\n *               |  |  +-----+  +---------+      |\n *               |  |  |                  |      |\n *               |  +-----------+         |      |\n *               |     |        |         |      |\n *        +------+     |     Module--->(Module)  |\n *        |            |        ^         ^      |\n *   OtherClass-->(OtherClass)  |         |      |\n *                              |         |      |\n *                            Class---->(Class)  |\n *                              ^                |\n *                              |                |\n *                              +----------------+\n */\n\n\n/*\n *  <code>Object</code> is the parent class of all classes in Ruby. Its\n *  methods are therefore available to all objects unless explicitly\n *  overridden.\n *\n *  <code>Object</code> mixes in the <code>Kernel</code> module, making\n *  the built-in kernel functions globally accessible. Although the\n *  instance methods of <code>Object</code> are defined by the\n *  <code>Kernel</code> module, we have chosen to document them here for\n *  clarity.\n *\n *  In the descriptions of Object's methods, the parameter <i>symbol</i> refers\n *  to a symbol, which is either a quoted string or a\n *  <code>Symbol</code> (such as <code>:name</code>).\n */\n\nvoid\nInit_Object()\n{\n    VALUE metaclass;\n\n    rb_cObject = boot_defclass(\"Object\", 0);\n    rb_cModule = boot_defclass(\"Module\", rb_cObject);\n    rb_cClass =  boot_defclass(\"Class\",  rb_cModule);\n\n    metaclass = rb_make_metaclass(rb_cObject, rb_cClass);\n    metaclass = rb_make_metaclass(rb_cModule, metaclass);\n    metaclass = rb_make_metaclass(rb_cClass, metaclass);\n\n    rb_mKernel = rb_define_module(\"Kernel\");\n    rb_include_module(rb_cObject, rb_mKernel);\n    rb_define_alloc_func(rb_cObject, rb_class_allocate_instance);\n    rb_define_private_method(rb_cObject, \"initialize\", rb_obj_dummy, 0);\n    rb_define_private_method(rb_cClass, \"inherited\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_cModule, \"included\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_cModule, \"extended\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_cModule, \"method_added\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_cModule, \"method_removed\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_cModule, \"method_undefined\", rb_obj_dummy, 1);\n\n\n    rb_define_method(rb_mKernel, \"nil?\", rb_false, 0);\n    rb_define_method(rb_mKernel, \"==\", rb_obj_equal, 1);\n    rb_define_method(rb_mKernel, \"equal?\", rb_obj_equal, 1);\n    rb_define_method(rb_mKernel, \"===\", rb_equal, 1);\n    rb_define_method(rb_mKernel, \"=~\", rb_obj_pattern_match, 1);\n\n    rb_define_method(rb_mKernel, \"eql?\", rb_obj_equal, 1);\n\n    rb_define_method(rb_mKernel, \"id\", rb_obj_id_obsolete, 0);\n    rb_define_method(rb_mKernel, \"type\", rb_obj_type, 0);\n    rb_define_method(rb_mKernel, \"class\", rb_obj_class, 0);\n\n    rb_define_method(rb_mKernel, \"clone\", rb_obj_clone, 0);\n    rb_define_method(rb_mKernel, \"dup\", rb_obj_dup, 0);\n    rb_define_method(rb_mKernel, \"initialize_copy\", rb_obj_init_copy, 1);\n\n    rb_define_method(rb_mKernel, \"taint\", rb_obj_taint, 0);\n    rb_define_method(rb_mKernel, \"tainted?\", rb_obj_tainted, 0);\n    rb_define_method(rb_mKernel, \"untaint\", rb_obj_untaint, 0);\n    rb_define_method(rb_mKernel, \"freeze\", rb_obj_freeze, 0);\n    rb_define_method(rb_mKernel, \"frozen?\", rb_obj_frozen_p, 0);\n    rb_define_method(rb_mKernel, \"moved?\", rb_obj_moved_p, 0);\n    rb_define_method(rb_mKernel, \"longlived?\", rb_obj_longlived_p, 0);\n\n    rb_define_method(rb_mKernel, \"to_a\", rb_any_to_a, 0); /* to be removed */\n    rb_define_method(rb_mKernel, \"to_s\", rb_any_to_s, 0);\n    rb_define_method(rb_mKernel, \"inspect\", rb_obj_inspect, 0);\n    rb_define_method(rb_mKernel, \"methods\", rb_obj_methods, -1);\n    rb_define_method(rb_mKernel, \"singleton_methods\",\n                     rb_obj_singleton_methods, -1); /* in class.c */\n    rb_define_method(rb_mKernel, \"protected_methods\",\n                     rb_obj_protected_methods, -1);\n    rb_define_method(rb_mKernel, \"private_methods\", rb_obj_private_methods, -1);\n    rb_define_method(rb_mKernel, \"public_methods\", rb_obj_public_methods, -1);\n    rb_define_method(rb_mKernel, \"instance_variables\",\n                     rb_obj_instance_variables, 0); /* in variable.c */\n    rb_define_method(rb_mKernel, \"instance_variable_get\", rb_obj_ivar_get, 1);\n    rb_define_method(rb_mKernel, \"instance_variable_set\", rb_obj_ivar_set, 2);\n    rb_define_method(rb_mKernel, \"instance_variable_defined?\", rb_obj_ivar_defined, 1);\n    rb_define_private_method(rb_mKernel, \"remove_instance_variable\",\n                             rb_obj_remove_instance_variable, 1); /* in variable.c */\n\n    rb_define_method(rb_mKernel, \"instance_of?\", rb_obj_is_instance_of, 1);\n    rb_define_method(rb_mKernel, \"kind_of?\", rb_obj_is_kind_of, 1);\n    rb_define_method(rb_mKernel, \"is_a?\", rb_obj_is_kind_of, 1);\n    rb_define_method(rb_mKernel, \"tap\", rb_obj_tap, 0);\n\n    rb_define_private_method(rb_mKernel, \"singleton_method_added\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_mKernel, \"singleton_method_removed\", rb_obj_dummy, 1);\n    rb_define_private_method(rb_mKernel, \"singleton_method_undefined\", rb_obj_dummy, 1);\n\n    rb_define_global_function(\"sprintf\", rb_f_sprintf, -1); /* in sprintf.c */\n    rb_define_global_function(\"format\", rb_f_sprintf, -1);  /* in sprintf.c  */\n\n    rb_define_global_function(\"Integer\", rb_f_integer, 1);\n    rb_define_global_function(\"Float\", rb_f_float, 1);\n\n    rb_define_global_function(\"String\", rb_f_string, 1);\n    rb_define_global_function(\"Array\", rb_f_array, 1);\n\n    rb_cNilClass = rb_define_class(\"NilClass\", rb_cObject);\n    rb_define_method(rb_cNilClass, \"to_i\", nil_to_i, 0);\n    rb_define_method(rb_cNilClass, \"to_f\", nil_to_f, 0);\n    rb_define_method(rb_cNilClass, \"to_s\", nil_to_s, 0);\n    rb_define_method(rb_cNilClass, \"to_a\", nil_to_a, 0);\n    rb_define_method(rb_cNilClass, \"inspect\", nil_inspect, 0);\n    rb_define_method(rb_cNilClass, \"&\", false_and, 1);\n    rb_define_method(rb_cNilClass, \"|\", false_or, 1);\n    rb_define_method(rb_cNilClass, \"^\", false_xor, 1);\n\n    rb_define_method(rb_cNilClass, \"nil?\", rb_true, 0);\n    rb_undef_alloc_func(rb_cNilClass);\n    rb_undef_method(CLASS_OF(rb_cNilClass), \"new\");\n    rb_define_global_const(\"NIL\", Qnil);\n\n    rb_cSymbol = rb_define_class(\"Symbol\", rb_cObject);\n    rb_define_singleton_method(rb_cSymbol, \"all_symbols\",\n                               rb_sym_all_symbols, 0); /* in parse.y */\n    rb_undef_alloc_func(rb_cSymbol);\n    rb_undef_method(CLASS_OF(rb_cSymbol), \"new\");\n\n    rb_define_method(rb_cSymbol, \"to_i\", sym_to_i, 0);\n    rb_define_method(rb_cSymbol, \"to_int\", sym_to_int, 0);\n    rb_define_method(rb_cSymbol, \"inspect\", sym_inspect, 0);\n    rb_define_method(rb_cSymbol, \"to_s\", sym_to_s, 0);\n    rb_define_method(rb_cSymbol, \"id2name\", sym_to_s, 0);\n    rb_define_method(rb_cSymbol, \"to_sym\", sym_to_sym, 0);\n    rb_define_method(rb_cSymbol, \"to_proc\", sym_to_proc, 0);\n    rb_define_method(rb_cSymbol, \"===\", rb_obj_equal, 1);\n\n    rb_define_method(rb_cModule, \"freeze\", rb_mod_freeze, 0);\n    rb_define_method(rb_cModule, \"===\", rb_mod_eqq, 1);\n    rb_define_method(rb_cModule, \"==\", rb_obj_equal, 1);\n    rb_define_method(rb_cModule, \"<=>\",  rb_mod_cmp, 1);\n    rb_define_method(rb_cModule, \"<\",  rb_mod_lt, 1);\n    rb_define_method(rb_cModule, \"<=\", rb_class_inherited_p, 1);\n    rb_define_method(rb_cModule, \">\",  rb_mod_gt, 1);\n    rb_define_method(rb_cModule, \">=\", rb_mod_ge, 1);\n    rb_define_method(rb_cModule, \"initialize_copy\", rb_mod_init_copy, 1); /* in class.c */\n    rb_define_method(rb_cModule, \"to_s\", rb_mod_to_s, 0);\n    rb_define_method(rb_cModule, \"included_modules\",\n                     rb_mod_included_modules, 0); /* in class.c */\n    rb_define_method(rb_cModule, \"include?\", rb_mod_include_p, 1); /* in class.c */\n    rb_define_method(rb_cModule, \"name\", rb_mod_name, 0);  /* in variable.c */\n    rb_define_method(rb_cModule, \"ancestors\", rb_mod_ancestors, 0); /* in class.c */\n\n    rb_define_private_method(rb_cModule, \"attr\", rb_mod_attr, -1);\n    rb_define_private_method(rb_cModule, \"attr_reader\", rb_mod_attr_reader, -1);\n    rb_define_private_method(rb_cModule, \"attr_writer\", rb_mod_attr_writer, -1);\n    rb_define_private_method(rb_cModule, \"attr_accessor\", rb_mod_attr_accessor, -1);\n\n    rb_define_alloc_func(rb_cModule, rb_module_s_alloc);\n    rb_define_method(rb_cModule, \"initialize\", rb_mod_initialize, 0);\n    rb_define_method(rb_cModule, \"instance_methods\",\n                     rb_class_instance_methods, -1);           /* in class.c */\n    rb_define_method(rb_cModule, \"public_instance_methods\",\n                     rb_class_public_instance_methods, -1);    /* in class.c */\n    rb_define_method(rb_cModule, \"protected_instance_methods\",\n                     rb_class_protected_instance_methods, -1); /* in class.c */\n    rb_define_method(rb_cModule, \"private_instance_methods\",\n                     rb_class_private_instance_methods, -1);   /* in class.c */\n\n    rb_define_method(rb_cModule, \"class_variable_defined?\", rb_mod_cvar_defined, 1);\n    rb_define_method(rb_cModule, \"constants\", rb_mod_constants, 0); /* in variable.c */\n    rb_define_method(rb_cModule, \"const_get\", rb_mod_const_get, 1);\n    rb_define_method(rb_cModule, \"const_set\", rb_mod_const_set, 2);\n    rb_define_method(rb_cModule, \"const_defined?\", rb_mod_const_defined, 1);\n    rb_define_private_method(rb_cModule, \"remove_const\",\n                             rb_mod_remove_const, 1); /* in variable.c */\n    rb_define_method(rb_cModule, \"const_missing\",\n                     rb_mod_const_missing, 1); /* in variable.c */\n    rb_define_method(rb_cModule, \"class_variables\",\n                     rb_mod_class_variables, 0); /* in variable.c */\n    rb_define_private_method(rb_cModule, \"remove_class_variable\",\n                             rb_mod_remove_cvar, 1); /* in variable.c */\n    rb_define_private_method(rb_cModule, \"class_variable_get\", rb_mod_cvar_get, 1);\n    rb_define_private_method(rb_cModule, \"class_variable_set\", rb_mod_cvar_set, 2);\n\n    rb_define_method(rb_cClass, \"allocate\", rb_obj_alloc, 0);\n    rb_define_method(rb_cClass, \"new\", rb_class_new_instance, -1);\n    rb_define_method(rb_cClass, \"initialize\", rb_class_initialize, -1);\n    rb_define_method(rb_cClass, \"initialize_copy\", rb_class_init_copy, 1); /* in class.c */\n    rb_define_method(rb_cClass, \"superclass\", rb_class_superclass, 0);\n    rb_define_alloc_func(rb_cClass, rb_class_s_alloc);\n    rb_undef_method(rb_cClass, \"extend_object\");\n    rb_undef_method(rb_cClass, \"append_features\");\n\n    rb_cData = rb_define_class(\"Data\", rb_cObject);\n    rb_undef_alloc_func(rb_cData);\n\n    rb_global_variable(&ruby_top_self);\n    ruby_top_self = rb_obj_alloc(rb_cObject);\n    rb_define_singleton_method(ruby_top_self, \"to_s\", main_to_s, 0);\n\n    rb_cTrueClass = rb_define_class(\"TrueClass\", rb_cObject);\n    rb_define_method(rb_cTrueClass, \"to_s\", true_to_s, 0);\n    rb_define_method(rb_cTrueClass, \"&\", true_and, 1);\n    rb_define_method(rb_cTrueClass, \"|\", true_or, 1);\n    rb_define_method(rb_cTrueClass, \"^\", true_xor, 1);\n    rb_undef_alloc_func(rb_cTrueClass);\n    rb_undef_method(CLASS_OF(rb_cTrueClass), \"new\");\n    rb_define_global_const(\"TRUE\", Qtrue);\n\n    rb_cFalseClass = rb_define_class(\"FalseClass\", rb_cObject);\n    rb_define_method(rb_cFalseClass, \"to_s\", false_to_s, 0);\n    rb_define_method(rb_cFalseClass, \"&\", false_and, 1);\n    rb_define_method(rb_cFalseClass, \"|\", false_or, 1);\n    rb_define_method(rb_cFalseClass, \"^\", false_xor, 1);\n    rb_undef_alloc_func(rb_cFalseClass);\n    rb_undef_method(CLASS_OF(rb_cFalseClass), \"new\");\n    rb_define_global_const(\"FALSE\", Qfalse);\n\n    id_eq = rb_intern(\"==\");\n    id_eql = rb_intern(\"eql?\");\n    id_inspect = rb_intern(\"inspect\");\n    id_init_copy = rb_intern(\"initialize_copy\");\n}\n"
  },
  {
    "path": "pack.c",
    "content": "/**********************************************************************\n\n  pack.c -\n\n  $Author$\n  $Date$\n  created at: Thu Feb 10 15:17:05 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include <sys/types.h>\n#include <ctype.h>\n\n#define SIZE16 2\n#define SIZE32 4\n\n#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4\n# define NATINT_PACK\n#endif\n\n#ifdef NATINT_PACK\n# define OFF16B(p) ((char*)(p) + (natint?0:(sizeof(short) - SIZE16)))\n# define OFF32B(p) ((char*)(p) + (natint?0:(sizeof(long) - SIZE32)))\n# define NATINT_LEN(type,len) (natint?sizeof(type):(len))\n# ifdef WORDS_BIGENDIAN\n#   define OFF16(p) OFF16B(p)\n#   define OFF32(p) OFF32B(p)\n# endif\n# define NATINT_HTOVS(x) (natint?htovs(x):htov16(x))\n# define NATINT_HTOVL(x) (natint?htovl(x):htov32(x))\n# define NATINT_HTONS(x) (natint?htons(x):hton16(x))\n# define NATINT_HTONL(x) (natint?htonl(x):hton32(x))\n#else\n# define NATINT_LEN(type,len) sizeof(type)\n# define NATINT_HTOVS(x) htovs(x)\n# define NATINT_HTOVL(x) htovl(x)\n# define NATINT_HTONS(x) htons(x)\n# define NATINT_HTONL(x) htonl(x)\n#endif\n\n#ifndef OFF16\n# define OFF16(p) (char*)(p)\n# define OFF32(p) (char*)(p)\n#endif\n#ifndef OFF16B\n# define OFF16B(p) (char*)(p)\n# define OFF32B(p) (char*)(p)\n#endif\n\n#define define_swapx(x, xtype)\t\t\\\nstatic xtype\t\t\t\t\\\nTOKEN_PASTE(swap,x)(z)\t\t\t\\\n    xtype z;\t\t\t\t\\\n{\t\t\t\t\t\\\n    xtype r;\t\t\t\t\\\n    xtype *zp;\t\t\t\t\\\n    unsigned char *s, *t;\t\t\\\n    int i;\t\t\t\t\\\n\t\t\t\t\t\\\n    zp = xmalloc(sizeof(xtype));\t\\\n    *zp = z;\t\t\t\t\\\n    s = (unsigned char*)zp;\t\t\\\n    t = xmalloc(sizeof(xtype));\t\t\\\n    for (i=0; i<sizeof(xtype); i++) {\t\\\n\tt[sizeof(xtype)-i-1] = s[i];\t\\\n    }\t\t\t\t\t\\\n    r = *(xtype *)t;\t\t\t\\\n    free(t);\t\t\t\t\\\n    free(zp);\t\t\t\t\\\n    return r;\t\t\t\t\\\n}\n\n#ifndef swap16\n#define swap16(x)\t((((x)&0xFF)<<8) | (((x)>>8)&0xFF))\n#endif\n#if SIZEOF_SHORT == 2\n#define swaps(x)\tswap16(x)\n#else\n#if SIZEOF_SHORT == 4\n#define swaps(x)\t((((x)&0xFF)<<24)\t\\\n\t\t\t|(((x)>>24)&0xFF)\t\\\n\t\t\t|(((x)&0x0000FF00)<<8)\t\\\n\t\t\t|(((x)&0x00FF0000)>>8)\t)\n#else\ndefine_swapx(s,short)\n#endif\n#endif\n\n#ifndef swap32\n#define swap32(x)\t((((x)&0xFF)<<24)\t\\\n\t\t\t|(((x)>>24)&0xFF)\t\\\n\t\t\t|(((x)&0x0000FF00)<<8)\t\\\n\t\t\t|(((x)&0x00FF0000)>>8)\t)\n#endif\n#if SIZEOF_LONG == 4\n#define swapl(x)\tswap32(x)\n#else\n#if SIZEOF_LONG == 8\n#define swapl(x)        ((((x)&0x00000000000000FF)<<56)\t\\\n\t\t\t|(((x)&0xFF00000000000000)>>56)\t\\\n\t\t\t|(((x)&0x000000000000FF00)<<40)\t\\\n\t\t\t|(((x)&0x00FF000000000000)>>40)\t\\\n\t\t\t|(((x)&0x0000000000FF0000)<<24)\t\\\n\t\t\t|(((x)&0x0000FF0000000000)>>24)\t\\\n\t\t\t|(((x)&0x00000000FF000000)<<8)\t\\\n\t\t\t|(((x)&0x000000FF00000000)>>8))\n#else\ndefine_swapx(l,long)\n#endif\n#endif\n\n#if SIZEOF_FLOAT == 4\n#if SIZEOF_LONG == 4\t/* SIZEOF_FLOAT == 4 == SIZEOF_LONG */\n#define swapf(x)\tswapl(x)\n#define FLOAT_SWAPPER\tunsigned long\n#else\n#if SIZEOF_SHORT == 4\t/* SIZEOF_FLOAT == 4 == SIZEOF_SHORT */\n#define swapf(x)\tswaps(x)\n#define FLOAT_SWAPPER\tunsigned short\n#else\t/* SIZEOF_FLOAT == 4 but undivide by known size of int */\ndefine_swapx(f,float)\n#endif\t/* #if SIZEOF_SHORT == 4 */\n#endif\t/* #if SIZEOF_LONG == 4 */\n#else\t/* SIZEOF_FLOAT != 4 */\ndefine_swapx(f,float)\n#endif\t/* #if SIZEOF_FLOAT == 4 */\n\n#if SIZEOF_DOUBLE == 8\n#if SIZEOF_LONG == 8\t/* SIZEOF_DOUBLE == 8 == SIZEOF_LONG */\n#define swapd(x)\tswapl(x)\n#define DOUBLE_SWAPPER\tunsigned long\n#else\n#if SIZEOF_LONG == 4\t/* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_LONG */\nstatic double\nswapd(d)\n    const double d;\n{\n    double dtmp = d;\n    unsigned long utmp[2];\n    unsigned long utmp0;\n\n    utmp[0] = 0; utmp[1] = 0;\n    memcpy(utmp,&dtmp,sizeof(double));\n    utmp0 = utmp[0];\n    utmp[0] = swapl(utmp[1]);\n    utmp[1] = swapl(utmp0);\n    memcpy(&dtmp,utmp,sizeof(double));\n    return dtmp;\n}\n#else\n#if SIZEOF_SHORT == 4\t/* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_SHORT */\nstatic double\nswapd(d)\n    const double d;\n{\n    double dtmp = d;\n    unsigned short utmp[2];\n    unsigned short utmp0;\n\n    utmp[0] = 0; utmp[1] = 0;\n    memcpy(utmp,&dtmp,sizeof(double));\n    utmp0 = utmp[0];\n    utmp[0] = swaps(utmp[1]);\n    utmp[1] = swaps(utmp0);\n    memcpy(&dtmp,utmp,sizeof(double));\n    return dtmp;\n}\n#else\t/* SIZEOF_DOUBLE == 8 but undivied by known size of int */\ndefine_swapx(d, double)\n#endif\t/* #if SIZEOF_SHORT == 4 */\n#endif\t/* #if SIZEOF_LONG == 4 */\n#endif\t/* #if SIZEOF_LONG == 8 */\n#else\t/* SIZEOF_DOUBLE != 8 */\ndefine_swapx(d, double)\n#endif\t/* #if SIZEOF_DOUBLE == 8 */\n\n#undef define_swapx\n\n#ifdef DYNAMIC_ENDIAN\n#ifdef ntohs\n#undef ntohs\n#undef ntohl\n#undef htons\n#undef htonl\n#endif\nstatic int\nendian()\n{\n    static int init = 0;\n    static int endian_value;\n    char *p;\n\n    if (init) return endian_value;\n    init = 1;\n    p = (char*)&init;\n    return endian_value = p[0]?0:1;\n}\n\n#define ntohs(x) (endian()?(x):swaps(x))\n#define ntohl(x) (endian()?(x):swapl(x))\n#define ntohf(x) (endian()?(x):swapf(x))\n#define ntohd(x) (endian()?(x):swapd(x))\n#define htons(x) (endian()?(x):swaps(x))\n#define htonl(x) (endian()?(x):swapl(x))\n#define htonf(x) (endian()?(x):swapf(x))\n#define htond(x) (endian()?(x):swapd(x))\n#define htovs(x) (endian()?swaps(x):(x))\n#define htovl(x) (endian()?swapl(x):(x))\n#define htovf(x) (endian()?swapf(x):(x))\n#define htovd(x) (endian()?swapd(x):(x))\n#define vtohs(x) (endian()?swaps(x):(x))\n#define vtohl(x) (endian()?swapl(x):(x))\n#define vtohf(x) (endian()?swapf(x):(x))\n#define vtohd(x) (endian()?swapd(x):(x))\n# ifdef NATINT_PACK\n#define htov16(x) (endian()?swap16(x):(x))\n#define htov32(x) (endian()?swap32(x):(x))\n#define hton16(x) (endian()?(x):swap16(x))\n#define hton32(x) (endian()?(x):swap32(x))\n# endif\n#else\n#ifdef WORDS_BIGENDIAN\n#ifndef ntohs\n#define ntohs(x) (x)\n#define ntohl(x) (x)\n#define htons(x) (x)\n#define htonl(x) (x)\n#endif\n#define ntohf(x) (x)\n#define ntohd(x) (x)\n#define htonf(x) (x)\n#define htond(x) (x)\n#define htovs(x) swaps(x)\n#define htovl(x) swapl(x)\n#define htovf(x) swapf(x)\n#define htovd(x) swapd(x)\n#define vtohs(x) swaps(x)\n#define vtohl(x) swapl(x)\n#define vtohf(x) swapf(x)\n#define vtohd(x) swapd(x)\n# ifdef NATINT_PACK\n#define htov16(x) swap16(x)\n#define htov32(x) swap32(x)\n#define hton16(x) (x)\n#define hton32(x) (x)\n# endif\n#else /* LITTLE ENDIAN */\n#ifdef ntohs\n#undef ntohs\n#undef ntohl\n#undef htons\n#undef htonl\n#endif\n#define ntohs(x) swaps(x)\n#define ntohl(x) swapl(x)\n#define htons(x) swaps(x)\n#define htonl(x) swapl(x)\n#define ntohf(x) swapf(x)\n#define ntohd(x) swapd(x)\n#define htonf(x) swapf(x)\n#define htond(x) swapd(x)\n#define htovs(x) (x)\n#define htovl(x) (x)\n#define htovf(x) (x)\n#define htovd(x) (x)\n#define vtohs(x) (x)\n#define vtohl(x) (x)\n#define vtohf(x) (x)\n#define vtohd(x) (x)\n# ifdef NATINT_PACK\n#define htov16(x) (x)\n#define htov32(x) (x)\n#define hton16(x) swap16(x)\n#define hton32(x) swap32(x)\n# endif\n#endif\n#endif\n\n#ifdef FLOAT_SWAPPER\n#define FLOAT_CONVWITH(y)\tFLOAT_SWAPPER y;\n#define HTONF(x,y)\t(memcpy(&y,&x,sizeof(float)),\t\\\n\t\t\t y = htonf((FLOAT_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(float)),\t\\\n\t\t\t x)\n#define HTOVF(x,y)\t(memcpy(&y,&x,sizeof(float)),\t\\\n\t\t\t y = htovf((FLOAT_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(float)),\t\\\n\t\t\t x)\n#define NTOHF(x,y)\t(memcpy(&y,&x,sizeof(float)),\t\\\n\t\t\t y = ntohf((FLOAT_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(float)),\t\\\n\t\t\t x)\n#define VTOHF(x,y)\t(memcpy(&y,&x,sizeof(float)),\t\\\n\t\t\t y = vtohf((FLOAT_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(float)),\t\\\n\t\t\t x)\n#else\n#define FLOAT_CONVWITH(y)\n#define HTONF(x,y)\thtonf(x)\n#define HTOVF(x,y)\thtovf(x)\n#define NTOHF(x,y)\tntohf(x)\n#define VTOHF(x,y)\tvtohf(x)\n#endif\n\n#ifdef DOUBLE_SWAPPER\n#define DOUBLE_CONVWITH(y)\tDOUBLE_SWAPPER y;\n#define HTOND(x,y)\t(memcpy(&y,&x,sizeof(double)),\t\\\n\t\t\t y = htond((DOUBLE_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(double)),\t\\\n\t\t\t x)\n#define HTOVD(x,y)\t(memcpy(&y,&x,sizeof(double)),\t\\\n\t\t\t y = htovd((DOUBLE_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(double)),\t\\\n\t\t\t x)\n#define NTOHD(x,y)\t(memcpy(&y,&x,sizeof(double)),\t\\\n\t\t\t y = ntohd((DOUBLE_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(double)),\t\\\n\t\t\t x)\n#define VTOHD(x,y)\t(memcpy(&y,&x,sizeof(double)),\t\\\n\t\t\t y = vtohd((DOUBLE_SWAPPER)y),\t\\\n\t\t\t memcpy(&x,&y,sizeof(double)),\t\\\n\t\t\t x)\n#else\n#define DOUBLE_CONVWITH(y)\n#define HTOND(x,y)\thtond(x)\n#define HTOVD(x,y)\thtovd(x)\n#define NTOHD(x,y)\tntohd(x)\n#define VTOHD(x,y)\tvtohd(x)\n#endif\n\nunsigned long rb_big2ulong_pack _((VALUE x));\n\nstatic unsigned long\nnum2i32(x)\n    VALUE x;\n{\n    x = rb_to_int(x); /* is nil OK? (should not) */\n\n    if (FIXNUM_P(x)) return FIX2LONG(x);\n    if (TYPE(x) == T_BIGNUM) {\n\treturn rb_big2ulong_pack(x);\n    }\n    rb_raise(rb_eTypeError, \"can't convert %s to `integer'\", rb_obj_classname(x));\n    return 0;\t\t\t/* not reached */\n}\n\n#if SIZEOF_LONG == SIZE32\n# define EXTEND32(x) \n#else\n/* invariant in modulo 1<<31 */\n# define EXTEND32(x) do { if (!natint) {(x) = (((1L<<31)-1-(x))^~(~0L<<31));}} while(0)\n#endif\n#if SIZEOF_SHORT == SIZE16\n# define EXTEND16(x) \n#else\n# define EXTEND16(x) do { if (!natint) {(x) = (short)(((1<<15)-1-(x))^~(~0<<15));}} while(0)\n#endif\n\n#ifdef HAVE_LONG_LONG\n# define QUAD_SIZE sizeof(LONG_LONG)\n#else\n# define QUAD_SIZE 8\n#endif\nstatic const char toofew[] = \"too few arguments\";\n\nstatic void encodes _((VALUE,const char*,long,int));\nstatic void qpencode _((VALUE,VALUE,long));\n\nstatic int uv_to_utf8 _((char*,unsigned long));\nstatic unsigned long utf8_to_uv _((char*,long*));\n\n/*\n *  call-seq:\n *     arr.pack ( aTemplateString ) -> aBinaryString\n *  \n *  Packs the contents of <i>arr</i> into a binary sequence according to\n *  the directives in <i>aTemplateString</i> (see the table below)\n *  Directives ``A,'' ``a,'' and ``Z'' may be followed by a count,\n *  which gives the width of the resulting field. The remaining\n *  directives also may take a count, indicating the number of array\n *  elements to convert. If the count is an asterisk\n *  (``<code>*</code>''), all remaining array elements will be\n *  converted. Any of the directives ``<code>sSiIlL</code>'' may be\n *  followed by an underscore (``<code>_</code>'') to use the underlying\n *  platform's native size for the specified type; otherwise, they use a\n *  platform-independent size. Spaces are ignored in the template\n *  string. See also <code>String#unpack</code>.\n *     \n *     a = [ \"a\", \"b\", \"c\" ]\n *     n = [ 65, 66, 67 ]\n *     a.pack(\"A3A3A3\")   #=> \"a  b  c  \"\n *     a.pack(\"a3a3a3\")   #=> \"a\\000\\000b\\000\\000c\\000\\000\"\n *     n.pack(\"ccc\")      #=> \"ABC\"\n *     \n *  Directives for +pack+.\n *\n *   Directive    Meaning\n *   ---------------------------------------------------------------\n *       @     |  Moves to absolute position\n *       A     |  ASCII string (space padded, count is width)\n *       a     |  ASCII string (null padded, count is width)\n *       B     |  Bit string (descending bit order)\n *       b     |  Bit string (ascending bit order)\n *       C     |  Unsigned char\n *       c     |  Char\n *       D, d  |  Double-precision float, native format\n *       E     |  Double-precision float, little-endian byte order\n *       e     |  Single-precision float, little-endian byte order\n *       F, f  |  Single-precision float, native format\n *       G     |  Double-precision float, network (big-endian) byte order\n *       g     |  Single-precision float, network (big-endian) byte order\n *       H     |  Hex string (high nibble first)\n *       h     |  Hex string (low nibble first)\n *       I     |  Unsigned integer\n *       i     |  Integer\n *       L     |  Unsigned long\n *       l     |  Long\n *       M     |  Quoted printable, MIME encoding (see RFC2045)\n *       m     |  Base64 encoded string\n *       N     |  Long, network (big-endian) byte order\n *       n     |  Short, network (big-endian) byte-order\n *       P     |  Pointer to a structure (fixed-length string)\n *       p     |  Pointer to a null-terminated string\n *       Q, q  |  64-bit number\n *       S     |  Unsigned short\n *       s     |  Short\n *       U     |  UTF-8\n *       u     |  UU-encoded string\n *       V     |  Long, little-endian byte order\n *       v     |  Short, little-endian byte order\n *       w     |  BER-compressed integer\\fnm\n *       X     |  Back up a byte\n *       x     |  Null byte\n *       Z     |  Same as ``a'', except that null is added with *\n */\n\nstatic VALUE\npack_pack(ary, fmt)\n    VALUE ary, fmt;\n{\n    static const char nul10[] = \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n    static const char spc10[] = \"          \";\n    char *p, *pend;\n    VALUE res, from, associates = 0;\n    char type;\n    long items, len, idx, plen;\n    const char *ptr;\n#ifdef NATINT_PACK\n    int natint;\t\t/* native integer */\n#endif\n\n    StringValue(fmt);\n    p = RSTRING(fmt)->ptr;\n    pend = p + RSTRING(fmt)->len;\n    res = rb_str_buf_new(0);\n\n    items = RARRAY(ary)->len;\n    idx = 0;\n\n#define TOO_FEW (rb_raise(rb_eArgError, toofew), 0)\n#define THISFROM (items > 0 ? RARRAY(ary)->ptr[idx] : TOO_FEW)\n#define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : TOO_FEW)\n\n    while (p < pend) {\n\tif (RSTRING(fmt)->ptr + RSTRING(fmt)->len != pend) {\n\t    rb_raise(rb_eRuntimeError, \"format string modified\");\n\t}\n\ttype = *p++;\t\t/* get data type */\n#ifdef NATINT_PACK\n\tnatint = 0;\n#endif\n\n\tif (ISSPACE(type)) continue;\n\tif (type == '#') {\n\t    while ((p < pend) && (*p != '\\n')) {\n\t\tp++;\n\t    }\n\t    continue;\n\t}\n        if (*p == '_' || *p == '!') {\n\t    const char *natstr = \"sSiIlL\";\n\n\t    if (strchr(natstr, type)) {\n#ifdef NATINT_PACK\n\t\tnatint = 1;\n#endif\n\t\tp++;\n\t    }\n\t    else {\n\t\trb_raise(rb_eArgError, \"'%c' allowed only after types %s\", *p, natstr);\n\t    }\n\t}\n\tif (*p == '*') {\t/* set data length */\n\t    len = strchr(\"@Xxu\", type) ? 0\n                : strchr(\"PMm\", type) ? 1\n                : items;\n\t    p++;\n\t}\n\telse if (ISDIGIT(*p)) {\n\t    len = strtoul(p, (char**)&p, 10);\n\t}\n\telse {\n\t    len = 1;\n\t}\n\n\tswitch (type) {\n\t  case 'A': case 'a': case 'Z':\n\t  case 'B': case 'b':\n\t  case 'H': case 'h':\n\t    from = NEXTFROM;\n\t    if (NIL_P(from)) {\n\t\tptr = \"\";\n\t\tplen = 0;\n\t    }\n\t    else {\n\t\tStringValue(from);\n\t\tptr = RSTRING(from)->ptr;\n\t\tplen = RSTRING(from)->len;\n\t\tOBJ_INFECT(res, from);\n\t    }\n\n\t    if (p[-1] == '*')\n\t\tlen = plen;\n\n\t    switch (type) {\n\t      case 'a':\t\t/* arbitrary binary string (null padded)  */\n\t      case 'A':\t\t/* ASCII string (space padded) */\n\t      case 'Z':\t\t/* null terminated ASCII string  */\n\t\tif (plen >= len) {\n\t\t    rb_str_buf_cat(res, ptr, len);\n\t\t    if (p[-1] == '*' && type == 'Z')\n\t\t\trb_str_buf_cat(res, nul10, 1);\n\t\t}\n\t\telse {\n\t\t    rb_str_buf_cat(res, ptr, plen);\n\t\t    len -= plen;\n\t\t    while (len >= 10) {\n\t\t\trb_str_buf_cat(res, (type == 'A')?spc10:nul10, 10);\n\t\t\tlen -= 10;\n\t\t    }\n\t\t    rb_str_buf_cat(res, (type == 'A')?spc10:nul10, len);\n\t\t}\n\t\tbreak;\n\n\t      case 'b':\t\t/* bit string (ascending) */\n\t\t{\n\t\t    int byte = 0;\n\t\t    long i, j = 0;\n\n\t\t    if (len > plen) {\n\t\t\tj = (len - plen + 1)/2;\n\t\t\tlen = plen;\n\t\t    }\n\t\t    for (i=0; i++ < len; ptr++) {\n\t\t\tif (*ptr & 1)\n\t\t\t    byte |= 128;\n\t\t\tif (i & 7)\n\t\t\t    byte >>= 1;\n\t\t\telse {\n\t\t\t    char c = byte & 0xff;\n\t\t\t    rb_str_buf_cat(res, &c, 1);\n\t\t\t    byte = 0;\n\t\t\t}\n\t\t    }\n\t\t    if (len & 7) {\n\t\t\tchar c;\n\t\t\tbyte >>= 7 - (len & 7);\n\t\t\tc = byte & 0xff;\n\t\t\trb_str_buf_cat(res, &c, 1);\n\t\t    }\n\t\t    len = j;\n\t\t    goto grow;\n\t\t}\n\t\tbreak;\n\n\t      case 'B':\t\t/* bit string (descending) */\n\t\t{\n\t\t    int byte = 0;\n\t\t    long i, j = 0;\n\n\t\t    if (len > plen) {\n\t\t\tj = (len - plen + 1)/2;\n\t\t\tlen = plen;\n\t\t    }\n\t\t    for (i=0; i++ < len; ptr++) {\n\t\t\tbyte |= *ptr & 1;\n\t\t\tif (i & 7)\n\t\t\t    byte <<= 1;\n\t\t\telse {\n\t\t\t    char c = byte & 0xff;\n\t\t\t    rb_str_buf_cat(res, &c, 1);\n\t\t\t    byte = 0;\n\t\t\t}\n\t\t    }\n\t\t    if (len & 7) {\n\t\t\tchar c;\n\t\t\tbyte <<= 7 - (len & 7);\n\t\t\tc = byte & 0xff;\n\t\t\trb_str_buf_cat(res, &c, 1);\n\t\t    }\n\t\t    len = j;\n\t\t    goto grow;\n\t\t}\n\t\tbreak;\n\n\t      case 'h':\t\t/* hex string (low nibble first) */\n\t\t{\n\t\t    int byte = 0;\n\t\t    long i, j = 0;\n\n\t\t    if (len > plen) {\n\t\t\tj = (len + 1) / 2 - (plen + 1) / 2;\n\t\t\tlen = plen;\n\t\t    }\n\t\t    for (i=0; i++ < len; ptr++) {\n\t\t\tif (ISALPHA(*ptr))\n\t\t\t    byte |= (((*ptr & 15) + 9) & 15) << 4;\n\t\t\telse\n\t\t\t    byte |= (*ptr & 15) << 4;\n\t\t\tif (i & 1)\n\t\t\t    byte >>= 4;\n\t\t\telse {\n\t\t\t    char c = byte & 0xff;\n\t\t\t    rb_str_buf_cat(res, &c, 1);\n\t\t\t    byte = 0;\n\t\t\t}\n\t\t    }\n\t\t    if (len & 1) {\n\t\t\tchar c = byte & 0xff;\n\t\t\trb_str_buf_cat(res, &c, 1);\n\t\t    }\n\t\t    len = j;\n\t\t    goto grow;\n\t\t}\n\t\tbreak;\n\n\t      case 'H':\t\t/* hex string (high nibble first) */\n\t\t{\n\t\t    int byte = 0;\n\t\t    long i, j = 0;\n\n\t\t    if (len > plen) {\n\t\t\tj = (len + 1) / 2 - (plen + 1) / 2;\n\t\t\tlen = plen;\n\t\t    }\n\t\t    for (i=0; i++ < len; ptr++) {\n\t\t\tif (ISALPHA(*ptr))\n\t\t\t    byte |= ((*ptr & 15) + 9) & 15;\n\t\t\telse\n\t\t\t    byte |= *ptr & 15;\n\t\t\tif (i & 1)\n\t\t\t    byte <<= 4;\n\t\t\telse {\n\t\t\t    char c = byte & 0xff;\n\t\t\t    rb_str_buf_cat(res, &c, 1);\n\t\t\t    byte = 0;\n\t\t\t}\n\t\t    }\n\t\t    if (len & 1) {\n\t\t\tchar c = byte & 0xff;\n\t\t\trb_str_buf_cat(res, &c, 1);\n\t\t    }\n\t\t    len = j;\n\t\t    goto grow;\n\t\t}\n\t\tbreak;\n\t    }\n\t    break;\n\n\t  case 'c':\t\t/* signed char */\n\t  case 'C':\t\t/* unsigned char */\n\t    while (len-- > 0) {\n\t\tchar c;\n\n\t\tfrom = NEXTFROM;\n\t\tc = num2i32(from);\n\t\trb_str_buf_cat(res, &c, sizeof(char));\n\t    }\n\t    break;\n\n\t  case 's':\t\t/* signed short */\n\t  case 'S':\t\t/* unsigned short */\n\t    while (len-- > 0) {\n\t\tshort s;\n\n\t\tfrom = NEXTFROM;\n\t\ts = num2i32(from);\n\t\trb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));\n\t    }\n\t    break;\n\n\t  case 'i':\t\t/* signed int */\n\t  case 'I':\t\t/* unsigned int */\n\t    while (len-- > 0) {\n\t\tlong i;\n\n\t\tfrom = NEXTFROM;\n\t\ti = num2i32(from);\n\t\trb_str_buf_cat(res, OFF32(&i), NATINT_LEN(int,4));\n\t    }\n\t    break;\n\n\t  case 'l':\t\t/* signed long */\n\t  case 'L':\t\t/* unsigned long */\n\t    while (len-- > 0) {\n\t\tlong l;\n\n\t\tfrom = NEXTFROM;\n\t\tl = num2i32(from);\n\t\trb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));\n\t    }\n\t    break;\n\n\t  case 'q':\t\t/* signed quad (64bit) int */\n\t  case 'Q':\t\t/* unsigned quad (64bit) int */\n\t    while (len-- > 0) {\n\t\tchar tmp[QUAD_SIZE];\n\n\t\tfrom = NEXTFROM;\n\t\trb_quad_pack(tmp, from);\n\t\trb_str_buf_cat(res, (char*)&tmp, QUAD_SIZE);\n\t    }\n\t    break;\n\n\t  case 'n':\t\t/* unsigned short (network byte-order)  */\n\t    while (len-- > 0) {\n\t\tunsigned short s;\n\n\t\tfrom = NEXTFROM;\n\t\ts = num2i32(from);\n\t\ts = NATINT_HTONS(s);\n\t\trb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));\n\t    }\n\t    break;\n\n\t  case 'N':\t\t/* unsigned long (network byte-order) */\n\t    while (len-- > 0) {\n\t\tunsigned long l;\n\n\t\tfrom = NEXTFROM;\n\t\tl = num2i32(from);\n\t\tl = NATINT_HTONL(l);\n\t\trb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));\n\t    }\n\t    break;\n\n\t  case 'v':\t\t/* unsigned short (VAX byte-order) */\n\t    while (len-- > 0) {\n\t\tunsigned short s;\n\n\t\tfrom = NEXTFROM;\n\t\ts = num2i32(from);\n\t\ts = NATINT_HTOVS(s);\n\t\trb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));\n\t    }\n\t    break;\n\n\t  case 'V':\t\t/* unsigned long (VAX byte-order) */\n\t    while (len-- > 0) {\n\t\tunsigned long l;\n\n\t\tfrom = NEXTFROM;\n\t\tl = num2i32(from);\n\t\tl = NATINT_HTOVL(l);\n\t\trb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));\n\t    }\n\t    break;\n\n\t  case 'f':\t\t/* single precision float in native format */\n\t  case 'F':\t\t/* ditto */\n\t    while (len-- > 0) {\n\t\tfloat f;\n\n\t\tfrom = NEXTFROM;\n\t\tf = RFLOAT(rb_Float(from))->value;\n\t\trb_str_buf_cat(res, (char*)&f, sizeof(float));\n\t    }\n\t    break;\n\n\t  case 'e':\t\t/* single precision float in VAX byte-order */\n\t    while (len-- > 0) {\n\t\tfloat f;\n\t\tFLOAT_CONVWITH(ftmp);\n\n\t\tfrom = NEXTFROM;\n\t\tf = RFLOAT(rb_Float(from))->value;\n\t\tf = HTOVF(f,ftmp);\n\t\trb_str_buf_cat(res, (char*)&f, sizeof(float));\n\t    }\n\t    break;\n\n\t  case 'E':\t\t/* double precision float in VAX byte-order */\n\t    while (len-- > 0) {\n\t\tdouble d;\n\t\tDOUBLE_CONVWITH(dtmp);\n\n\t\tfrom = NEXTFROM;\n\t\td = RFLOAT(rb_Float(from))->value;\n\t\td = HTOVD(d,dtmp);\n\t\trb_str_buf_cat(res, (char*)&d, sizeof(double));\n\t    }\n\t    break;\n\n\t  case 'd':\t\t/* double precision float in native format */\n\t  case 'D':\t\t/* ditto */\n\t    while (len-- > 0) {\n\t\tdouble d;\n\n\t\tfrom = NEXTFROM;\n\t\td = RFLOAT(rb_Float(from))->value;\n\t\trb_str_buf_cat(res, (char*)&d, sizeof(double));\n\t    }\n\t    break;\n\n\t  case 'g':\t\t/* single precision float in network byte-order */\n\t    while (len-- > 0) {\n\t\tfloat f;\n\t\tFLOAT_CONVWITH(ftmp);\n\n\t\tfrom = NEXTFROM;\n\t\tf = RFLOAT(rb_Float(from))->value;\n\t\tf = HTONF(f,ftmp);\n\t\trb_str_buf_cat(res, (char*)&f, sizeof(float));\n\t    }\n\t    break;\n\n\t  case 'G':\t\t/* double precision float in network byte-order */\n\t    while (len-- > 0) {\n\t\tdouble d;\n\t\tDOUBLE_CONVWITH(dtmp);\n\n\t\tfrom = NEXTFROM;\n\t\td = RFLOAT(rb_Float(from))->value;\n\t\td = HTOND(d,dtmp);\n\t\trb_str_buf_cat(res, (char*)&d, sizeof(double));\n\t    }\n\t    break;\n\n\t  case 'x':\t\t/* null byte */\n\t  grow:\n\t    while (len >= 10) {\n\t\trb_str_buf_cat(res, nul10, 10);\n\t\tlen -= 10;\n\t    }\n\t    rb_str_buf_cat(res, nul10, len);\n\t    break;\n\n\t  case 'X':\t\t/* back up byte */\n\t  shrink:\n\t    plen = RSTRING(res)->len;\n\t    if (plen < len)\n\t\trb_raise(rb_eArgError, \"X outside of string\");\n\t    RSTRING(res)->len = plen - len;\n\t    RSTRING(res)->ptr[plen - len] = '\\0';\n\t    break;\n\n\t  case '@':\t\t/* null fill to absolute position */\n\t    len -= RSTRING(res)->len;\n\t    if (len > 0) goto grow;\n\t    len = -len;\n\t    if (len > 0) goto shrink;\n\t    break;\n\n\t  case '%':\n\t    rb_raise(rb_eArgError, \"%% is not supported\");\n\t    break;\n\n\t  case 'U':\t\t/* Unicode character */\n\t    while (len-- > 0) {\n\t\tlong l;\n\t\tchar buf[8];\n\t\tint le;\n\n\t\tfrom = NEXTFROM;\n\t\tfrom = rb_to_int(from);\n\t\tl = NUM2INT(from);\n\t\tif (l < 0) {\n\t\t    rb_raise(rb_eRangeError, \"pack(U): value out of range\");\n\t\t}\n\t\tle = uv_to_utf8(buf, l);\n\t\trb_str_buf_cat(res, (char*)buf, le);\n\t    }\n\t    break;\n\n\t  case 'u':\t\t/* uuencoded string */\n\t  case 'm':\t\t/* base64 encoded string */\n\t    from = NEXTFROM;\n\t    StringValue(from);\n\t    ptr = RSTRING(from)->ptr;\n\t    plen = RSTRING(from)->len;\n\n\t    if (len <= 2)\n\t\tlen = 45;\n\t    else\n\t\tlen = len / 3 * 3;\n\t    while (plen > 0) {\n\t\tlong todo;\n\n\t\tif (plen > len)\n\t\t    todo = len;\n\t\telse\n\t\t    todo = plen;\n\t\tencodes(res, ptr, todo, type);\n\t\tplen -= todo;\n\t\tptr += todo;\n\t    }\n\t    break;\n\n\t  case 'M':\t\t/* quoted-printable encoded string */\n\t    from = rb_obj_as_string(NEXTFROM);\n\t    if (len <= 1)\n\t\tlen = 72;\n\t    qpencode(res, from, len);\n\t    break;\n\n\t  case 'P':\t\t/* pointer to packed byte string */\n\t    from = THISFROM;\n\t    if (!NIL_P(from)) {\n\t\tStringValue(from);\n\t\tif (RSTRING(from)->len < len) {\n\t\t    rb_raise(rb_eArgError, \"too short buffer for P(%ld for %ld)\",\n\t\t\t     RSTRING(from)->len, len);\n\t\t}\n\t    }\n\t    len = 1;\n\t    /* FALL THROUGH */\n\t  case 'p':\t\t/* pointer to string */\n\t    while (len-- > 0) {\n\t\tchar *t;\n\t\tfrom = NEXTFROM;\n\t\tif (NIL_P(from)) {\n\t\t    t = 0;\n\t\t}\n\t\telse {\n\t\t    t = StringValuePtr(from);\n\t\t}\n\t\tif (!associates) {\n\t\t    associates = rb_ary_new();\n\t\t}\n\t\trb_ary_push(associates, from);\n\t\trb_obj_taint(from);\n\t\trb_str_buf_cat(res, (char*)&t, sizeof(char*));\n\t    }\n\t    break;\n\n\t  case 'w':\t\t/* BER compressed integer  */\n\t    while (len-- > 0) {\n\t\tunsigned long ul;\n\t\tVALUE buf = rb_str_new(0, 0);\n\t\tchar c, *bufs, *bufe;\n\n\t\tfrom = NEXTFROM;\n\t\tif (TYPE(from) == T_BIGNUM) {\n\t\t    VALUE big128 = rb_uint2big(128);\n\t\t    while (TYPE(from) == T_BIGNUM) {\n\t\t\tfrom = rb_big_divmod(from, big128);\n\t\t\tc = NUM2INT(RARRAY(from)->ptr[1]) | 0x80; /* mod */\n\t\t\trb_str_buf_cat(buf, &c, sizeof(char));\n\t\t\tfrom = RARRAY(from)->ptr[0]; /* div */\n\t\t    }\n\t\t}\n\n\t\t{\n\t\t    long l = NUM2LONG(from);\n\t\t    if (l < 0) {\n\t\t\trb_raise(rb_eArgError, \"can't compress negative numbers\");\n\t\t    }\n\t\t    ul = l;\n\t\t}\n\n\t\twhile (ul) {\n\t\t    c = ((ul & 0x7f) | 0x80);\n\t\t    rb_str_buf_cat(buf, &c, sizeof(char));\n\t\t    ul >>=  7;\n\t\t}\n\n\t\tif (RSTRING(buf)->len) {\n\t\t    bufs = RSTRING(buf)->ptr;\n\t\t    bufe = bufs + RSTRING(buf)->len - 1;\n\t\t    *bufs &= 0x7f; /* clear continue bit */\n\t\t    while (bufs < bufe) { /* reverse */\n\t\t\tc = *bufs;\n\t\t\t*bufs++ = *bufe;\n\t\t\t*bufe-- = c;\n\t\t    }\n\t\t    rb_str_buf_cat(res, RSTRING(buf)->ptr, RSTRING(buf)->len);\n\t\t}\n\t\telse {\n\t\t    c = 0;\n\t\t    rb_str_buf_cat(res, &c, sizeof(char));\n\t\t}\n\t    }\n\t    break;\n\n\t  default:\n\t    break;\n\t}\n    }\n\n    if (associates) {\n\trb_str_associate(res, associates);\n    }\n    OBJ_INFECT(res, fmt);\n    return res;\n}\n\nstatic const char uu_table[] =\n\"`!\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\";\nstatic const char b64_table[] =\n\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nstatic void\nencodes(str, s, len, type)\n    VALUE str;\n    const char *s;\n    long len;\n    int type;\n{\n    char *buff = ALLOCA_N(char, len * 4 / 3 + 6);\n    long i = 0;\n    const char *trans = type == 'u' ? uu_table : b64_table;\n    int padding;\n\n    if (type == 'u') {\n\tbuff[i++] = len + ' ';\n\tpadding = '`';\n    }\n    else {\n\tpadding = '=';\n    }\n    while (len >= 3) {\n\tbuff[i++] = trans[077 & (*s >> 2)];\n\tbuff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];\n\tbuff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];\n\tbuff[i++] = trans[077 & s[2]];\n\ts += 3;\n\tlen -= 3;\n    }\n    if (len == 2) {\n\tbuff[i++] = trans[077 & (*s >> 2)];\n\tbuff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];\n\tbuff[i++] = trans[077 & (((s[1] << 2) & 074) | (('\\0' >> 6) & 03))];\n\tbuff[i++] = padding;\n    }\n    else if (len == 1) {\n\tbuff[i++] = trans[077 & (*s >> 2)];\n\tbuff[i++] = trans[077 & (((*s << 4) & 060) | (('\\0' >> 4) & 017))];\n\tbuff[i++] = padding;\n\tbuff[i++] = padding;\n    }\n    buff[i++] = '\\n';\n    rb_str_buf_cat(str, buff, i);\n}\n\nstatic char hex_table[] = \"0123456789ABCDEF\";\n\nstatic void\nqpencode(str, from, len)\n    VALUE str, from;\n    long len;\n{\n    char buff[1024];\n    long i = 0, n = 0, prev = EOF;\n    unsigned char *s = (unsigned char*)RSTRING(from)->ptr;\n    unsigned char *send = s + RSTRING(from)->len;\n\n    while (s < send) {\n        if ((*s > 126) ||\n\t    (*s < 32 && *s != '\\n' && *s != '\\t') ||\n\t    (*s == '=')) {\n\t    buff[i++] = '=';\n\t    buff[i++] = hex_table[*s >> 4];\n\t    buff[i++] = hex_table[*s & 0x0f];\n            n += 3;\n            prev = EOF;\n        }\n\telse if (*s == '\\n') {\n            if (prev == ' ' || prev == '\\t') {\n\t\tbuff[i++] = '=';\n\t\tbuff[i++] = *s;\n            }\n\t    buff[i++] = *s;\n            n = 0;\n            prev = *s;\n        }\n\telse {\n\t    buff[i++] = *s;\n            n++;\n            prev = *s;\n        }\n        if (n > len) {\n\t    buff[i++] = '=';\n\t    buff[i++] = '\\n';\n            n = 0;\n            prev = '\\n';\n        }\n\tif (i > 1024 - 5) {\n\t    rb_str_buf_cat(str, buff, i);\n\t    i = 0;\n\t}\n\ts++;\n    }\n    if (n > 0) {\n\tbuff[i++] = '=';\n\tbuff[i++] = '\\n';\n    }\n    if (i > 0) {\n\trb_str_buf_cat(str, buff, i);\n    }\n}\n\nstatic inline int\nhex2num(c)\n    char c;\n{\n    switch (c) {\n    case '0': case '1': case '2': case '3': case '4':\n    case '5': case '6': case '7': case '8': case '9':\n        return c - '0';\n    case 'a': case 'b': case 'c':\n    case 'd': case 'e': case 'f':\n\treturn c - 'a' + 10;\n    case 'A': case 'B': case 'C':\n    case 'D': case 'E': case 'F':\n\treturn c - 'A' + 10;\n    default:\n\treturn -1;\n    }\n}\n\n#define PACK_LENGTH_ADJUST_SIZE(sz) do {\t\\\n    tmp = 0;\t\t\t\t\t\\\n    if (len > (send-s)/sz) {\t\t\t\\\n        if (!star) {\t\t\t\t\\\n\t    tmp = len-(send-s)/sz;\t\t\\\n        }\t\t\t\t\t\\\n\tlen = (send-s)/sz;\t\t\t\\\n    }\t\t\t\t\t\t\\\n} while (0)\n\n#ifdef NATINT_PACK\n#define PACK_LENGTH_ADJUST(type,sz) do {\t\\\n    int t__len = NATINT_LEN(type,(sz));\t\t\\\n    PACK_LENGTH_ADJUST_SIZE(t__len);\t\t\\\n} while (0)\n#else\n#define PACK_LENGTH_ADJUST(type,sz) \t\t\\\n    PACK_LENGTH_ADJUST_SIZE(sizeof(type))\n#endif\n\n#define PACK_ITEM_ADJUST() while (tmp--) rb_ary_push(ary, Qnil)\n\nstatic VALUE\ninfected_str_new(ptr, len, str)\n    const char *ptr;\n    long len;\n    VALUE str;\n{\n    VALUE s = rb_str_new(ptr, len);\n\n    OBJ_INFECT(s, str);\n    return s;\n}\n    \n/*\n *  call-seq:\n *     str.unpack(format)   => anArray\n *  \n *  Decodes <i>str</i> (which may contain binary data) according to the\n *  format string, returning an array of each value extracted. The\n *  format string consists of a sequence of single-character directives,\n *  summarized in the table at the end of this entry.\n *  Each directive may be followed\n *  by a number, indicating the number of times to repeat with this\n *  directive. An asterisk (``<code>*</code>'') will use up all\n *  remaining elements. The directives <code>sSiIlL</code> may each be\n *  followed by an underscore (``<code>_</code>'') to use the underlying\n *  platform's native size for the specified type; otherwise, it uses a\n *  platform-independent consistent size. Spaces are ignored in the\n *  format string. See also <code>Array#pack</code>.\n *     \n *     \"abc \\0\\0abc \\0\\0\".unpack('A6Z6')   #=> [\"abc\", \"abc \"]\n *     \"abc \\0\\0\".unpack('a3a3')           #=> [\"abc\", \" \\000\\000\"]\n *     \"abc \\0abc \\0\".unpack('Z*Z*')       #=> [\"abc \", \"abc \"]\n *     \"aa\".unpack('b8B8')                 #=> [\"10000110\", \"01100001\"]\n *     \"aaa\".unpack('h2H2c')               #=> [\"16\", \"61\", 97]\n *     \"\\xfe\\xff\\xfe\\xff\".unpack('sS')     #=> [-2, 65534]\n *     \"now=20is\".unpack('M*')             #=> [\"now is\"]\n *     \"whole\".unpack('xax2aX2aX1aX2a')    #=> [\"h\", \"e\", \"l\", \"l\", \"o\"]\n *\n *  This table summarizes the various formats and the Ruby classes\n *  returned by each.\n *     \n *     Format | Returns | Function\n *     -------+---------+-----------------------------------------\n *       A    | String  | with trailing nulls and spaces removed\n *     -------+---------+-----------------------------------------\n *       a    | String  | string\n *     -------+---------+-----------------------------------------\n *       B    | String  | extract bits from each character (msb first)\n *     -------+---------+-----------------------------------------\n *       b    | String  | extract bits from each character (lsb first)\n *     -------+---------+-----------------------------------------\n *       C    | Fixnum  | extract a character as an unsigned integer\n *     -------+---------+-----------------------------------------\n *       c    | Fixnum  | extract a character as an integer\n *     -------+---------+-----------------------------------------\n *       d,D  | Float   | treat sizeof(double) characters as\n *            |         | a native double\n *     -------+---------+-----------------------------------------\n *       E    | Float   | treat sizeof(double) characters as\n *            |         | a double in little-endian byte order\n *     -------+---------+-----------------------------------------\n *       e    | Float   | treat sizeof(float) characters as\n *            |         | a float in little-endian byte order\n *     -------+---------+-----------------------------------------\n *       f,F  | Float   | treat sizeof(float) characters as\n *            |         | a native float\n *     -------+---------+-----------------------------------------\n *       G    | Float   | treat sizeof(double) characters as\n *            |         | a double in network byte order\n *     -------+---------+-----------------------------------------\n *       g    | Float   | treat sizeof(float) characters as a\n *            |         | float in network byte order\n *     -------+---------+-----------------------------------------\n *       H    | String  | extract hex nibbles from each character\n *            |         | (most significant first)\n *     -------+---------+-----------------------------------------\n *       h    | String  | extract hex nibbles from each character\n *            |         | (least significant first)\n *     -------+---------+-----------------------------------------\n *       I    | Integer | treat sizeof(int) (modified by _)\n *            |         | successive characters as an unsigned\n *            |         | native integer\n *     -------+---------+-----------------------------------------\n *       i    | Integer | treat sizeof(int) (modified by _)\n *            |         | successive characters as a signed\n *            |         | native integer\n *     -------+---------+-----------------------------------------\n *       L    | Integer | treat four (modified by _) successive\n *            |         | characters as an unsigned native\n *            |         | long integer\n *     -------+---------+-----------------------------------------\n *       l    | Integer | treat four (modified by _) successive\n *            |         | characters as a signed native\n *            |         | long integer\n *     -------+---------+-----------------------------------------\n *       M    | String  | quoted-printable\n *     -------+---------+-----------------------------------------\n *       m    | String  | base64-encoded\n *     -------+---------+-----------------------------------------\n *       N    | Integer | treat four characters as an unsigned\n *            |         | long in network byte order\n *     -------+---------+-----------------------------------------\n *       n    | Fixnum  | treat two characters as an unsigned\n *            |         | short in network byte order\n *     -------+---------+-----------------------------------------\n *       P    | String  | treat sizeof(char *) characters as a\n *            |         | pointer, and  return \\emph{len} characters\n *            |         | from the referenced location\n *     -------+---------+-----------------------------------------\n *       p    | String  | treat sizeof(char *) characters as a\n *            |         | pointer to a  null-terminated string\n *     -------+---------+-----------------------------------------\n *       Q    | Integer | treat 8 characters as an unsigned \n *            |         | quad word (64 bits)\n *     -------+---------+-----------------------------------------\n *       q    | Integer | treat 8 characters as a signed \n *            |         | quad word (64 bits)\n *     -------+---------+-----------------------------------------\n *       S    | Fixnum  | treat two (different if _ used)\n *            |         | successive characters as an unsigned\n *            |         | short in native byte order\n *     -------+---------+-----------------------------------------\n *       s    | Fixnum  | Treat two (different if _ used) \n *            |         | successive characters as a signed short\n *            |         | in native byte order\n *     -------+---------+-----------------------------------------\n *       U    | Integer | UTF-8 characters as unsigned integers\n *     -------+---------+-----------------------------------------\n *       u    | String  | UU-encoded\n *     -------+---------+-----------------------------------------\n *       V    | Fixnum  | treat four characters as an unsigned\n *            |         | long in little-endian byte order\n *     -------+---------+-----------------------------------------\n *       v    | Fixnum  | treat two characters as an unsigned\n *            |         | short in little-endian byte order\n *     -------+---------+-----------------------------------------\n *       w    | Integer | BER-compressed integer (see Array.pack)\n *     -------+---------+-----------------------------------------\n *       X    | ---     | skip backward one character\n *     -------+---------+-----------------------------------------\n *       x    | ---     | skip forward one character\n *     -------+---------+-----------------------------------------\n *       Z    | String  | with trailing nulls removed\n *            |         | upto first null with *\n *     -------+---------+-----------------------------------------\n *       @    | ---     | skip to the offset given by the \n *            |         | length argument\n *     -------+---------+-----------------------------------------\n */\n\nstatic VALUE\npack_unpack(str, fmt)\n    VALUE str, fmt;\n{\n    static const char hexdigits[] = \"0123456789abcdef0123456789ABCDEFx\";\n    char *s, *send;\n    char *p, *pend;\n    VALUE ary;\n    char type;\n    long len;\n    int tmp, star;\n#ifdef NATINT_PACK\n    int natint;\t\t\t/* native integer */\n#endif\n\n    StringValue(str);\n    StringValue(fmt);\n    s = RSTRING(str)->ptr;\n    send = s + RSTRING(str)->len;\n    p = RSTRING(fmt)->ptr;\n    pend = p + RSTRING(fmt)->len;\n\n    ary = rb_ary_new();\n    while (p < pend) {\n\ttype = *p++;\n#ifdef NATINT_PACK\n\tnatint = 0;\n#endif\n\n\tif (ISSPACE(type)) continue;\n\tif (type == '#') {\n\t    while ((p < pend) && (*p != '\\n')) {\n\t\tp++;\n\t    }\n\t    continue;\n\t}\n\tstar = 0;\n\tif (*p == '_' || *p == '!') {\n\t    static const char natstr[] = \"sSiIlL\";\n\n\t    if (strchr(natstr, type)) {\n#ifdef NATINT_PACK\n\t\tnatint = 1;\n#endif\n\t\tp++;\n\t    }\n\t    else {\n\t\trb_raise(rb_eArgError, \"'%c' allowed only after types %s\", *p, natstr);\n\t    }\n\t}\n\tif (p >= pend)\n\t    len = 1;\n\telse if (*p == '*') {\n\t    star = 1;\n\t    len = send - s;\n\t    p++;\n\t}\n\telse if (ISDIGIT(*p)) {\n\t    len = strtoul(p, (char**)&p, 10);\n\t}\n\telse {\n\t    len = (type != '@');\n\t}\n\n\tswitch (type) {\n\t  case '%':\n\t    rb_raise(rb_eArgError, \"%% is not supported\");\n\t    break;\n\n\t  case 'A':\n\t    if (len > send - s) len = send - s;\n\t    {\n\t\tlong end = len;\n\t\tchar *t = s + len - 1;\n\n\t\twhile (t >= s) {\n\t\t    if (*t != ' ' && *t != '\\0') break;\n\t\t    t--; len--;\n\t\t}\n\t\trb_ary_push(ary, infected_str_new(s, len, str));\n\t\ts += end;\n\t    }\n\t    break;\n\n\t  case 'Z':\n\t    {\n\t\tchar *t = s;\n\n\t\tif (len > send-s) len = send-s;\n\t\twhile (t < s+len && *t) t++;\n\t\trb_ary_push(ary, infected_str_new(s, t-s, str));\n\t\tif (t < send) t++;\n\t\ts = star ? t : s+len;\n\t    }\n\t    break;\n\n\t  case 'a':\n\t    if (len > send - s) len = send - s;\n\t    rb_ary_push(ary, infected_str_new(s, len, str));\n\t    s += len;\n\t    break;\n\n\t  case 'b':\n\t    {\n\t\tVALUE bitstr;\n\t\tchar *t;\n\t\tint bits;\n\t\tlong i;\n\n\t\tif (p[-1] == '*' || len > (send - s) * 8)\n\t\t    len = (send - s) * 8;\n\t\tbits = 0;\n\t\trb_ary_push(ary, bitstr = rb_str_new(0, len));\n\t\tt = RSTRING(bitstr)->ptr;\n\t\tfor (i=0; i<len; i++) {\n\t\t    if (i & 7) bits >>= 1;\n\t\t    else bits = *s++;\n\t\t    *t++ = (bits & 1) ? '1' : '0';\n\t\t}\n\t    }\n\t    break;\n\n\t  case 'B':\n\t    {\n\t\tVALUE bitstr;\n\t\tchar *t;\n\t\tint bits;\n\t\tlong i;\n\n\t\tif (p[-1] == '*' || len > (send - s) * 8)\n\t\t    len = (send - s) * 8;\n\t\tbits = 0;\n\t\trb_ary_push(ary, bitstr = rb_str_new(0, len));\n\t\tt = RSTRING(bitstr)->ptr;\n\t\tfor (i=0; i<len; i++) {\n\t\t    if (i & 7) bits <<= 1;\n\t\t    else bits = *s++;\n\t\t    *t++ = (bits & 128) ? '1' : '0';\n\t\t}\n\t    }\n\t    break;\n\n\t  case 'h':\n\t    {\n\t\tVALUE bitstr;\n\t\tchar *t;\n\t\tint bits;\n\t\tlong i;\n\n\t\tif (p[-1] == '*' || len > (send - s) * 2)\n\t\t    len = (send - s) * 2;\n\t\tbits = 0;\n\t\trb_ary_push(ary, bitstr = rb_str_new(0, len));\n\t\tt = RSTRING(bitstr)->ptr;\n\t\tfor (i=0; i<len; i++) {\n\t\t    if (i & 1)\n\t\t\tbits >>= 4;\n\t\t    else\n\t\t\tbits = *s++;\n\t\t    *t++ = hexdigits[bits & 15];\n\t\t}\n\t    }\n\t    break;\n\n\t  case 'H':\n\t    {\n\t\tVALUE bitstr;\n\t\tchar *t;\n\t\tint bits;\n\t\tlong i;\n\n\t\tif (p[-1] == '*' || len > (send - s) * 2)\n\t\t    len = (send - s) * 2;\n\t\tbits = 0;\n\t\trb_ary_push(ary, bitstr = rb_str_new(0, len));\n\t\tt = RSTRING(bitstr)->ptr;\n\t\tfor (i=0; i<len; i++) {\n\t\t    if (i & 1)\n\t\t\tbits <<= 4;\n\t\t    else\n\t\t\tbits = *s++;\n\t\t    *t++ = hexdigits[(bits >> 4) & 15];\n\t\t}\n\t    }\n\t    break;\n\n\t  case 'c':\n\t    PACK_LENGTH_ADJUST(char,sizeof(char));\n\t    while (len-- > 0) {\n                int c = *s++;\n                if (c > (char)127) c-=256;\n\t\trb_ary_push(ary, INT2FIX(c));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'C':\n\t    PACK_LENGTH_ADJUST(unsigned char,sizeof(unsigned char));\n\t    while (len-- > 0) {\n\t\tunsigned char c = *s++;\n\t\trb_ary_push(ary, INT2FIX(c));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 's':\n\t    PACK_LENGTH_ADJUST(short,2);\n\t    while (len-- > 0) {\n\t\tshort tmp = 0;\n\t\tmemcpy(OFF16(&tmp), s, NATINT_LEN(short,2));\n\t\tEXTEND16(tmp);\n\t\ts += NATINT_LEN(short,2);\n\t\trb_ary_push(ary, INT2FIX(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'S':\n\t    PACK_LENGTH_ADJUST(unsigned short,2);\n\t    while (len-- > 0) {\n\t\tunsigned short tmp = 0;\n\t\tmemcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2));\n\t\ts += NATINT_LEN(unsigned short,2);\n\t\trb_ary_push(ary, INT2FIX(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'i':\n\t    PACK_LENGTH_ADJUST(int,sizeof(int));\n\t    while (len-- > 0) {\n\t\tint tmp;\n\t\tmemcpy(&tmp, s, sizeof(int));\n\t\ts += sizeof(int);\n\t\trb_ary_push(ary, INT2NUM(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'I':\n\t    PACK_LENGTH_ADJUST(unsigned int,sizeof(unsigned int));\n\t    while (len-- > 0) {\n\t\tunsigned int tmp;\n\t\tmemcpy(&tmp, s, sizeof(unsigned int));\n\t\ts += sizeof(unsigned int);\n\t\trb_ary_push(ary, UINT2NUM(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'l':\n\t    PACK_LENGTH_ADJUST(long,4);\n\t    while (len-- > 0) {\n\t\tlong tmp = 0;\n\t\tmemcpy(OFF32(&tmp), s, NATINT_LEN(long,4));\n\t\tEXTEND32(tmp);\n\t\ts += NATINT_LEN(long,4);\n\t\trb_ary_push(ary, LONG2NUM(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'L':\n\t    PACK_LENGTH_ADJUST(unsigned long,4);\n\t    while (len-- > 0) {\n\t\tunsigned long tmp = 0;\n\t\tmemcpy(OFF32(&tmp), s, NATINT_LEN(unsigned long,4));\n\t\ts += NATINT_LEN(unsigned long,4);\n\t\trb_ary_push(ary, ULONG2NUM(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'q':\n\t    PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);\n\t    while (len-- > 0) {\n\t\tchar *tmp = (char*)s;\n\t\ts += QUAD_SIZE;\n\t\trb_ary_push(ary, rb_quad_unpack(tmp, 1));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'Q':\n\t    PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);\n\t    while (len-- > 0) {\n\t\tchar *tmp = (char*)s;\n\t\ts += QUAD_SIZE;\n\t\trb_ary_push(ary, rb_quad_unpack(tmp, 0));\n\t    }\n\t    break;\n\n\t  case 'n':\n\t    PACK_LENGTH_ADJUST(unsigned short,2);\n\t    while (len-- > 0) {\n\t\tunsigned short tmp = 0;\n\t\tmemcpy(OFF16B(&tmp), s, NATINT_LEN(unsigned short,2));\n\t\ts += NATINT_LEN(unsigned short,2);\n\t\trb_ary_push(ary, UINT2NUM(ntohs(tmp)));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'N':\n\t    PACK_LENGTH_ADJUST(unsigned long,4);\n\t    while (len-- > 0) {\n\t\tunsigned long tmp = 0;\n\t\tmemcpy(OFF32B(&tmp), s, NATINT_LEN(unsigned long,4));\n\t\ts += NATINT_LEN(unsigned long,4);\n\t\trb_ary_push(ary, ULONG2NUM(ntohl(tmp)));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'v':\n\t    PACK_LENGTH_ADJUST(unsigned short,2);\n\t    while (len-- > 0) {\n\t\tunsigned short tmp = 0;\n\t\tmemcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2));\n\t\ts += NATINT_LEN(unsigned short,2);\n\t\trb_ary_push(ary, UINT2NUM(vtohs(tmp)));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'V':\n\t    PACK_LENGTH_ADJUST(unsigned long,4);\n\t    while (len-- > 0) {\n\t\tunsigned long tmp = 0;\n\t\tmemcpy(OFF32(&tmp), s, NATINT_LEN(long,4));\n\t\ts += NATINT_LEN(long,4);\n\t\trb_ary_push(ary, ULONG2NUM(vtohl(tmp)));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'f':\n\t  case 'F':\n\t    PACK_LENGTH_ADJUST(float,sizeof(float));\n\t    while (len-- > 0) {\n\t\tfloat tmp;\n\t\tmemcpy(&tmp, s, sizeof(float));\n\t\ts += sizeof(float);\n\t\trb_ary_push(ary, rb_float_new((double)tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'e':\n\t    PACK_LENGTH_ADJUST(float,sizeof(float));\n\t    while (len-- > 0) {\n\t        float tmp;\n\t\tFLOAT_CONVWITH(ftmp);\n\n\t\tmemcpy(&tmp, s, sizeof(float));\n\t\ts += sizeof(float);\n\t\ttmp = VTOHF(tmp,ftmp);\n\t\trb_ary_push(ary, rb_float_new((double)tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\t    \n\t  case 'E':\n\t    PACK_LENGTH_ADJUST(double,sizeof(double));\n\t    while (len-- > 0) {\n\t\tdouble tmp;\n\t\tDOUBLE_CONVWITH(dtmp);\n\n\t\tmemcpy(&tmp, s, sizeof(double));\n\t\ts += sizeof(double);\n\t\ttmp = VTOHD(tmp,dtmp);\n\t\trb_ary_push(ary, rb_float_new(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\t    \n\t  case 'D':\n\t  case 'd':\n\t    PACK_LENGTH_ADJUST(double,sizeof(double));\n\t    while (len-- > 0) {\n\t\tdouble tmp;\n\t\tmemcpy(&tmp, s, sizeof(double));\n\t\ts += sizeof(double);\n\t\trb_ary_push(ary, rb_float_new(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\n\t  case 'g':\n\t    PACK_LENGTH_ADJUST(float,sizeof(float));\n\t    while (len-- > 0) {\n\t        float tmp;\n\t\tFLOAT_CONVWITH(ftmp;)\n\n\t\tmemcpy(&tmp, s, sizeof(float));\n\t\ts += sizeof(float);\n\t\ttmp = NTOHF(tmp,ftmp);\n\t\trb_ary_push(ary, rb_float_new((double)tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\t    \n\t  case 'G':\n\t    PACK_LENGTH_ADJUST(double,sizeof(double));\n\t    while (len-- > 0) {\n\t\tdouble tmp;\n\t\tDOUBLE_CONVWITH(dtmp);\n\n\t\tmemcpy(&tmp, s, sizeof(double));\n\t\ts += sizeof(double);\n\t\ttmp = NTOHD(tmp,dtmp);\n\t\trb_ary_push(ary, rb_float_new(tmp));\n\t    }\n\t    PACK_ITEM_ADJUST();\n\t    break;\n\t    \n\t  case 'U':\n\t    if (len > send - s) len = send - s;\n\t    while (len > 0 && s < send) {\n\t\tlong alen = send - s;\n\t\tunsigned long l;\n\n\t\tl = utf8_to_uv(s, &alen);\n\t\ts += alen; len--;\n\t\trb_ary_push(ary, ULONG2NUM(l));\n\t    }\n\t    break;\n\n\t  case 'u':\n\t    {\n\t\tVALUE buf = infected_str_new(0, (send - s)*3/4, str);\n\t\tchar *ptr = RSTRING(buf)->ptr;\n\t\tlong total = 0;\n\n\t\twhile (s < send && *s > ' ' && *s < 'a') {\n\t\t    long a,b,c,d;\n\t\t    char hunk[4];\n\n\t\t    hunk[3] = '\\0';\n\t\t    len = (*s++ - ' ') & 077;\n\t\t    total += len;\n\t\t    if (total > RSTRING(buf)->len) {\n\t\t\tlen -= total - RSTRING(buf)->len;\n\t\t\ttotal = RSTRING(buf)->len;\n\t\t    }\n\n\t\t    while (len > 0) {\n\t\t\tlong mlen = len > 3 ? 3 : len;\n\n\t\t\tif (s < send && *s >= ' ')\n\t\t\t    a = (*s++ - ' ') & 077;\n\t\t\telse\n\t\t\t    a = 0;\n\t\t\tif (s < send && *s >= ' ')\n\t\t\t    b = (*s++ - ' ') & 077;\n\t\t\telse\n\t\t\t    b = 0;\n\t\t\tif (s < send && *s >= ' ')\n\t\t\t    c = (*s++ - ' ') & 077;\n\t\t\telse\n\t\t\t    c = 0;\n\t\t\tif (s < send && *s >= ' ')\n\t\t\t    d = (*s++ - ' ') & 077;\n\t\t\telse\n\t\t\t    d = 0;\n\t\t\thunk[0] = a << 2 | b >> 4;\n\t\t\thunk[1] = b << 4 | c >> 2;\n\t\t\thunk[2] = c << 6 | d;\n\t\t\tmemcpy(ptr, hunk, mlen);\n\t\t\tptr += mlen;\n\t\t\tlen -= mlen;\n\t\t    }\n\t\t    if (*s == '\\r') s++;\n\t\t    if (*s == '\\n') s++;\n\t\t    else if (s < send && (s+1 == send || s[1] == '\\n'))\n\t\t\ts += 2;\t/* possible checksum byte */\n\t\t}\n\t\t\n\t\tRSTRING(buf)->ptr[total] = '\\0';\n\t\tRSTRING(buf)->len = total;\n\t\trb_ary_push(ary, buf);\n\t    }\n\t    break;\n\n\t  case 'm':\n\t    {\n\t\tVALUE buf = infected_str_new(0, (send - s)*3/4, str);\n\t\tchar *ptr = RSTRING(buf)->ptr;\n\t\tint a = -1,b = -1,c = 0,d;\n\t\tstatic int first = 1;\n\t\tstatic int b64_xtable[256];\n\n\t\tif (first) {\n\t\t    int i;\n\t\t    first = 0;\n\n\t\t    for (i = 0; i < 256; i++) {\n\t\t\tb64_xtable[i] = -1;\n\t\t    }\n\t\t    for (i = 0; i < 64; i++) {\n\t\t\tb64_xtable[(int)b64_table[i]] = i;\n\t\t    }\n\t\t}\n\t\twhile (s < send) {\n\t\t    a = b = c = d = -1;\n\t\t    while((a = b64_xtable[(int)(*(unsigned char*)s)]) == -1 && s < send) { s++; }\n\t\t    if( s >= send ) break;\n\t\t    s++;\n\t\t    while((b = b64_xtable[(int)(*(unsigned char*)s)]) == -1 && s < send) { s++; }\n\t\t    if( s >= send ) break;\n\t\t    s++;\n\t\t    while((c = b64_xtable[(int)(*(unsigned char*)s)]) == -1 && s < send) { if( *s == '=' ) break; s++; }\n\t\t    if( *s == '=' || s >= send ) break;\n\t\t    s++;\n\t\t    while((d = b64_xtable[(int)(*(unsigned char*)s)]) == -1 && s < send) { if( *s == '=' ) break; s++; }\n\t\t    if( *s == '=' || s >= send ) break;\n\t\t    s++;\n\t\t    *ptr++ = a << 2 | b >> 4;\n\t\t    *ptr++ = b << 4 | c >> 2;\n\t\t    *ptr++ = c << 6 | d;\n\t\t}\n\t\tif (a != -1 && b != -1) {\n\t\t    if (c == -1 && *s == '=')\n\t\t\t*ptr++ = a << 2 | b >> 4;\n\t\t    else if (c != -1 && *s == '=') {\n\t\t\t*ptr++ = a << 2 | b >> 4;\n\t\t\t*ptr++ = b << 4 | c >> 2;\n\t\t    }\n\t\t}\n\t\t*ptr = '\\0';\n\t\tRSTRING(buf)->len = ptr - RSTRING(buf)->ptr;\n\t\trb_ary_push(ary, buf);\n\t    }\n\t    break;\n\n\t  case 'M':\n\t    {\n\t\tVALUE buf = infected_str_new(0, send - s, str);\n\t\tchar *ptr = RSTRING(buf)->ptr;\n\t\tint c1, c2;\n\n\t\twhile (s < send) {\n\t\t    if (*s == '=') {\n\t\t\tif (++s == send) break;\n                       if (s+1 < send && *s == '\\r' && *(s+1) == '\\n')\n                         s++;\n\t\t\tif (*s != '\\n') {\n\t\t\t    if ((c1 = hex2num(*s)) == -1) break;\n\t\t\t    if (++s == send) break;\n\t\t\t    if ((c2 = hex2num(*s)) == -1) break;\n\t\t\t    *ptr++ = c1 << 4 | c2;\n\t\t\t}\n\t\t    }\n\t\t    else {\n\t\t\t*ptr++ = *s;\n\t\t    }\n\t\t    s++;\n\t\t}\n\t\t*ptr = '\\0';\n\t\tRSTRING(buf)->len = ptr - RSTRING(buf)->ptr;\n\t\trb_ary_push(ary, buf);\n\t    }\n\t    break;\n\n\t  case '@':\n\t    if (len > RSTRING(str)->len)\n\t\trb_raise(rb_eArgError, \"@ outside of string\");\n\t    s = RSTRING(str)->ptr + len;\n\t    break;\n\n\t  case 'X':\n\t    if (len > s - RSTRING(str)->ptr)\n\t\trb_raise(rb_eArgError, \"X outside of string\");\n\t    s -= len;\n\t    break;\n\n\t  case 'x':\n\t    if (len > send - s)\n\t\trb_raise(rb_eArgError, \"x outside of string\");\n\t    s += len;\n\t    break;\n\n\t  case 'P':\n\t    if (sizeof(char *) <= send - s) {\n\t\tVALUE tmp = Qnil;\n\t\tchar *t;\n\n\t\tmemcpy(&t, s, sizeof(char *));\n\t\ts += sizeof(char *);\n\n\t\tif (t) {\n\t\t    VALUE a, *p, *pend;\n\n\t\t    if (!(a = rb_str_associated(str))) {\n\t\t\trb_raise(rb_eArgError, \"no associated pointer\");\n\t\t    }\n\t\t    p = RARRAY(a)->ptr;\n\t\t    pend = p + RARRAY(a)->len;\n\t\t    while (p < pend) {\n\t\t\tif (TYPE(*p) == T_STRING && RSTRING(*p)->ptr == t) {\n\t\t\t    if (len < RSTRING(*p)->len) {\n\t\t\t\ttmp = rb_tainted_str_new(t, len);\n\t\t\t\trb_str_associate(tmp, a);\n\t\t\t    }\n\t\t\t    else {\n\t\t\t\ttmp = *p;\n\t\t\t    }\n\t\t\t    break;\n\t\t\t}\n\t\t\tp++;\n\t\t    }\n\t\t    if (p == pend) {\n\t\t\trb_raise(rb_eArgError, \"non associated pointer\");\n\t\t    }\n\t\t}\n\t\trb_ary_push(ary, tmp);\n\t    }\n\t    break;\n\n\t  case 'p':\n\t    if (len > (send - s) / sizeof(char *))\n\t\tlen = (send - s) / sizeof(char *);\n\t    while (len-- > 0) {\n\t\tif (send - s < sizeof(char *))\n\t\t    break;\n\t\telse {\n\t\t    VALUE tmp = Qnil;\n\t\t    char *t;\n\n\t\t    memcpy(&t, s, sizeof(char *));\n\t\t    s += sizeof(char *);\n\n\t\t    if (t) {\n\t\t\tVALUE a, *p, *pend;\n\n\t\t\tif (!(a = rb_str_associated(str))) {\n\t\t\t    rb_raise(rb_eArgError, \"no associated pointer\");\n\t\t\t}\n\t\t\tp = RARRAY(a)->ptr;\n\t\t\tpend = p + RARRAY(a)->len;\n\t\t\twhile (p < pend) {\n\t\t\t    if (TYPE(*p) == T_STRING && RSTRING(*p)->ptr == t) {\n\t\t\t\ttmp = *p;\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t    p++;\n\t\t\t}\n\t\t\tif (p == pend) {\n\t\t\t    rb_raise(rb_eArgError, \"non associated pointer\");\n\t\t\t}\n\t\t    }\n\t\t    rb_ary_push(ary, tmp);\n\t\t}\n\t    }\n\t    break;\n\n\t  case 'w':\n\t    {\n\t\tunsigned long ul = 0;\n\t\tunsigned long ulmask = 0xfeUL << ((sizeof(unsigned long) - 1) * 8);\n\n\t\twhile (len > 0 && s < send) {\n\t\t    ul <<= 7;\n\t\t    ul |= (*s & 0x7f);\n\t\t    if (!(*s++ & 0x80)) {\n\t\t\trb_ary_push(ary, ULONG2NUM(ul));\n\t\t\tlen--;\n\t\t\tul = 0;\n\t\t    }\n\t\t    else if (ul & ulmask) {\n\t\t\tVALUE big = rb_uint2big(ul);\n\t\t\tVALUE big128 = rb_uint2big(128);\n\t\t\twhile (s < send) {\n\t\t\t    big = rb_big_mul(big, big128);\n\t\t\t    big = rb_big_plus(big, rb_uint2big(*s & 0x7f));\n\t\t\t    if (!(*s++ & 0x80)) {\n\t\t\t\trb_ary_push(ary, big);\n\t\t\t\tlen--;\n\t\t\t\tul = 0;\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    break;\n\n\t  default:\n\t    break;\n\t}\n    }\n\n    return ary;\n}\n\n#define BYTEWIDTH 8\n\nstatic int\nuv_to_utf8(buf, uv)\n    char *buf;\n    unsigned long uv;\n{\n    if (uv <= 0x7f) {\n\tbuf[0] = (char)uv;\n\treturn 1;\n    }\n    if (uv <= 0x7ff) {\n\tbuf[0] = ((uv>>6)&0xff)|0xc0;\n\tbuf[1] = (uv&0x3f)|0x80;\n\treturn 2;\n    }\n    if (uv <= 0xffff) {\n\tbuf[0] = ((uv>>12)&0xff)|0xe0;\n\tbuf[1] = ((uv>>6)&0x3f)|0x80;\n\tbuf[2] = (uv&0x3f)|0x80;\n\treturn 3;\n    }\n    if (uv <= 0x1fffff) {\n\tbuf[0] = ((uv>>18)&0xff)|0xf0;\n\tbuf[1] = ((uv>>12)&0x3f)|0x80;\n\tbuf[2] = ((uv>>6)&0x3f)|0x80;\n\tbuf[3] = (uv&0x3f)|0x80;\n\treturn 4;\n    }\n    if (uv <= 0x3ffffff) {\n\tbuf[0] = ((uv>>24)&0xff)|0xf8;\n\tbuf[1] = ((uv>>18)&0x3f)|0x80;\n\tbuf[2] = ((uv>>12)&0x3f)|0x80;\n\tbuf[3] = ((uv>>6)&0x3f)|0x80;\n\tbuf[4] = (uv&0x3f)|0x80;\n\treturn 5;\n    }\n    if (uv <= 0x7fffffff) {\n\tbuf[0] = ((uv>>30)&0xff)|0xfc;\n\tbuf[1] = ((uv>>24)&0x3f)|0x80;\n\tbuf[2] = ((uv>>18)&0x3f)|0x80;\n\tbuf[3] = ((uv>>12)&0x3f)|0x80;\n\tbuf[4] = ((uv>>6)&0x3f)|0x80;\n\tbuf[5] = (uv&0x3f)|0x80;\n\treturn 6;\n    }\n    rb_raise(rb_eRangeError, \"pack(U): value out of range\");\n}\n\nstatic const unsigned long utf8_limits[] = {\n    0x0,\t\t\t/* 1 */\n    0x80,\t\t\t/* 2 */\n    0x800,\t\t\t/* 3 */\n    0x10000,\t\t\t/* 4 */\n    0x200000,\t\t\t/* 5 */\n    0x4000000,\t\t\t/* 6 */\n    0x80000000,\t\t\t/* 7 */\n};\n\nstatic unsigned long\nutf8_to_uv(p, lenp)\n    char *p;\n    long *lenp;\n{\n    int c = *p++ & 0xff;\n    unsigned long uv = c;\n    long n;\n\n    if (!(uv & 0x80)) {\n\t*lenp = 1;\n        return uv;\n    }\n    if (!(uv & 0x40)) {\n\t*lenp = 1;\n\trb_raise(rb_eArgError, \"malformed UTF-8 character\");\n    }\n\n    if      (!(uv & 0x20)) { n = 2; uv &= 0x1f; }\n    else if (!(uv & 0x10)) { n = 3; uv &= 0x0f; }\n    else if (!(uv & 0x08)) { n = 4; uv &= 0x07; }\n    else if (!(uv & 0x04)) { n = 5; uv &= 0x03; }\n    else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }\n    else {\n\t*lenp = 1;\n\trb_raise(rb_eArgError, \"malformed UTF-8 character\");\n    }\n    if (n > *lenp) {\n\trb_raise(rb_eArgError, \"malformed UTF-8 character (expected %d bytes, given %d bytes)\",\n\t\t n, *lenp);\n    }\n    *lenp = n--;\n    if (n != 0) {\n\twhile (n--) {\n\t    c = *p++ & 0xff;\n\t    if ((c & 0xc0) != 0x80) {\n\t\t*lenp -= n + 1;\n\t\trb_raise(rb_eArgError, \"malformed UTF-8 character\");\n\t    }\n\t    else {\n\t\tc &= 0x3f;\n\t\tuv = uv << 6 | c;\n\t    }\n\t}\n    }\n    n = *lenp - 1;\n    if (uv < utf8_limits[n]) {\n\trb_raise(rb_eArgError, \"redundant UTF-8 sequence\");\n    }\n    return uv;\n}\n\nvoid\nInit_pack()\n{\n    rb_define_method(rb_cArray, \"pack\", pack_pack, 1);\n    rb_define_method(rb_cString, \"unpack\", pack_unpack, 1);\n}\n"
  },
  {
    "path": "parse.y",
    "content": "/**********************************************************************\n\n  parse.y -\n\n  $Author$\n  $Date$\n  created at: Fri May 28 18:02:42 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n%{\n\n#define YYDEBUG 1\n#define YYERROR_VERBOSE 1\n#ifndef YYSTACK_USE_ALLOCA\n#define YYSTACK_USE_ALLOCA 0\n#endif\n\n#include \"ruby.h\"\n#include \"env.h\"\n#include \"intern.h\"\n#include \"node.h\"\n#include \"st.h\"\n#include <stdio.h>\n#include <errno.h>\n#include <ctype.h>\n\n#define YYMALLOC\trb_parser_malloc\n#define YYREALLOC\trb_parser_realloc\n#define YYCALLOC\trb_parser_calloc\n#define YYFREE \trb_parser_free\n#define malloc\tYYMALLOC\n#define realloc\tYYREALLOC\n#define calloc\tYYCALLOC\n#define free\tYYFREE\nstatic void *rb_parser_malloc _((size_t));\nstatic void *rb_parser_realloc _((void *, size_t));\nstatic void *rb_parser_calloc _((size_t, size_t));\nstatic void rb_parser_free _((void *));\n\n#define yyparse ruby_yyparse\n#define yylex ruby_yylex\n#define yyerror ruby_yyerror\n#define yylval ruby_yylval\n#define yychar ruby_yychar\n#define yydebug ruby_yydebug\n\n#define ID_SCOPE_SHIFT 3\n#define ID_SCOPE_MASK 0x07\n#define ID_LOCAL    0x01\n#define ID_INSTANCE 0x02\n#define ID_GLOBAL   0x03\n#define ID_ATTRSET  0x04\n#define ID_CONST    0x05\n#define ID_CLASS    0x06\n#define ID_JUNK     0x07\n#define ID_INTERNAL ID_JUNK\n\n#define is_notop_id(id) ((id)>tLAST_TOKEN)\n#define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)\n#define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)\n#define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)\n#define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)\n#define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)\n#define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)\n#define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)\n\n#define is_asgn_or_id(id) ((is_notop_id(id)) && \\\n\t(((id)&ID_SCOPE_MASK) == ID_GLOBAL || \\\n\t ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \\\n\t ((id)&ID_SCOPE_MASK) == ID_CLASS))\n\nNODE *ruby_eval_tree_begin = 0;\nNODE *ruby_eval_tree = 0;\n\nchar *ruby_sourcefile;\t\t/* current source file */\nint   ruby_sourceline;\t\t/* current line no. */\n#ifdef GC_DEBUG\nID ruby_sourcefunc;  /* current func if no other context */\nVALUE ruby_sourcefunc_line;  /* current func if no other context */\nchar* ruby_sourcefunc_file;  /* current func if no other context */\n#endif\n\nstatic int yylex();\nstatic int yyerror();\n\nstatic enum lex_state {\n    EXPR_BEG,\t\t\t/* ignore newline, +/- is a sign. */\n    EXPR_END,\t\t\t/* newline significant, +/- is an operator. */\n    EXPR_ARG,\t\t\t/* newline significant, +/- is an operator. */\n    EXPR_CMDARG,\t\t/* newline significant, +/- is an operator. */\n    EXPR_ENDARG,\t\t/* newline significant, +/- is an operator. */\n    EXPR_MID,\t\t\t/* newline significant, +/- is an operator. */\n    EXPR_FNAME,\t\t\t/* ignore newline, no reserved words. */\n    EXPR_DOT,\t\t\t/* right after `.' or `::', no reserved words. */\n    EXPR_CLASS,\t\t\t/* immediate after `class', no here document. */\n} lex_state;\nstatic NODE *lex_strterm;\n\n#ifdef HAVE_LONG_LONG\ntypedef unsigned LONG_LONG stack_type;\n#else\ntypedef unsigned long stack_type;\n#endif\n\n#define BITSTACK_PUSH(stack, n)\t(stack = (stack<<1)|((n)&1))\n#define BITSTACK_POP(stack)\t(stack >>= 1)\n#define BITSTACK_LEXPOP(stack)\t(stack = (stack >> 1) | (stack & 1))\n#define BITSTACK_SET_P(stack)\t(stack&1)\n\nstatic stack_type cond_stack = 0;\n#define COND_PUSH(n)\tBITSTACK_PUSH(cond_stack, n)\n#define COND_POP()\tBITSTACK_POP(cond_stack)\n#define COND_LEXPOP()\tBITSTACK_LEXPOP(cond_stack)\n#define COND_P()\tBITSTACK_SET_P(cond_stack)\n\nstatic stack_type cmdarg_stack = 0;\n#define CMDARG_PUSH(n)\tBITSTACK_PUSH(cmdarg_stack, n)\n#define CMDARG_POP()\tBITSTACK_POP(cmdarg_stack)\n#define CMDARG_LEXPOP()\tBITSTACK_LEXPOP(cmdarg_stack)\n#define CMDARG_P()\tBITSTACK_SET_P(cmdarg_stack)\n\nstatic int class_nest = 0;\nstatic int in_single = 0;\nstatic int in_def = 0;\nstatic int compile_for_eval = 0;\nstatic ID cur_mid = 0;\nstatic int command_start = Qtrue;\n\nstatic NODE *deferred_nodes;\n\nstatic NODE *cond();\nstatic NODE *logop();\nstatic int cond_negative();\n\nstatic NODE *newline_node();\nstatic void fixpos();\n\nstatic int value_expr0();\nstatic void void_expr0();\nstatic void void_stmts();\nstatic NODE *remove_begin();\n#define value_expr(node) value_expr0((node) = remove_begin(node))\n#define void_expr(node) void_expr0((node) = remove_begin(node))\n\nstatic NODE *block_append();\nstatic NODE *list_append();\nstatic NODE *list_concat();\nstatic NODE *arg_concat();\nstatic NODE *arg_prepend();\nstatic NODE *literal_concat();\nstatic NODE *new_evstr();\nstatic NODE *evstr2dstr();\nstatic NODE *call_op();\nstatic int in_defined = 0;\n\nstatic NODE *negate_lit();\nstatic NODE *ret_args();\nstatic NODE *arg_blk_pass();\nstatic NODE *new_call();\nstatic NODE *new_fcall();\nstatic NODE *new_super();\nstatic NODE *new_yield();\n\nstatic NODE *gettable();\nstatic NODE *assignable();\nstatic NODE *aryset();\nstatic NODE *attrset();\nstatic void rb_backref_error();\nstatic NODE *node_assign();\n\nstatic NODE *match_gen();\nstatic void local_push();\nstatic void local_pop();\nstatic int  local_append();\nstatic int  local_cnt();\nstatic int  local_id();\nstatic ID  *local_tbl();\nstatic ID   internal_id();\n\nstatic struct RVarmap *dyna_push();\nstatic void dyna_pop();\nstatic int dyna_in_block();\nstatic NODE *dyna_init();\n\nstatic void top_local_init();\nstatic void top_local_setup();\n\nstatic void fixup_nodes();\n\n#define RE_OPTION_ONCE 0x80\n\n#define NODE_STRTERM NODE_ZARRAY\t/* nothing to gc */\n#define NODE_HEREDOC NODE_ARRAY \t/* 1, 3 to gc */\n#define SIGN_EXTEND(x,n) (((1<<(n)-1)^((x)&~(~0<<(n))))-(1<<(n)-1))\n#define nd_func u1.id\n#if SIZEOF_SHORT == 2\n#define nd_term(node) ((signed short)(node)->u2.id)\n#else\n#define nd_term(node) SIGN_EXTEND((node)->u2.id, CHAR_BIT*2)\n#endif\n#define nd_paren(node) (char)((node)->u2.id >> CHAR_BIT*2)\n#define nd_nest u3.id\n\n#define NEW_BLOCK_VAR(b, v) NEW_NODE(NODE_BLOCK_PASS, 0, b, v)\n\n/* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150,\n   for instance).  This is too low for Ruby to parse some files, such as\n   date/format.rb, therefore bump the value up to at least Bison's default. */\n#ifdef OLD_YACC\n#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 10000\n#endif\n#endif\n\n%}\n\n%union {\n    NODE *node;\n    ID id;\n    int num;\n    struct RVarmap *vars;\n}\n\n%token  kCLASS\n\tkMODULE\n\tkDEF\n\tkUNDEF\n\tkBEGIN\n\tkRESCUE\n\tkENSURE\n\tkEND\n\tkIF\n\tkUNLESS\n\tkTHEN\n\tkELSIF\n\tkELSE\n\tkCASE\n\tkWHEN\n\tkWHILE\n\tkUNTIL\n\tkFOR\n\tkBREAK\n\tkNEXT\n\tkREDO\n\tkRETRY\n\tkIN\n\tkDO\n\tkDO_COND\n\tkDO_BLOCK\n\tkRETURN\n\tkYIELD\n\tkSUPER\n\tkSELF\n\tkNIL\n\tkTRUE\n\tkFALSE\n\tkAND\n\tkOR\n\tkNOT\n\tkIF_MOD\n\tkUNLESS_MOD\n\tkWHILE_MOD\n\tkUNTIL_MOD\n\tkRESCUE_MOD\n\tkALIAS\n\tkDEFINED\n\tklBEGIN\n\tklEND\n\tk__LINE__\n\tk__FILE__\n\n%token <id>   tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR\n%token <node> tINTEGER tFLOAT tSTRING_CONTENT\n%token <node> tNTH_REF tBACK_REF\n%token <num>  tREGEXP_END\n\n%type <node> singleton strings string string1 xstring regexp\n%type <node> string_contents xstring_contents string_content\n%type <node> words qwords word_list qword_list word\n%type <node> literal numeric dsym cpath\n%type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call\n%type <node> expr_value arg_value primary_value\n%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure\n%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args\n%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs\n%type <node> mrhs superclass block_call block_command\n%type <node> f_arglist f_args f_optarg f_opt f_rest_arg f_block_arg opt_f_block_arg\n%type <node> assoc_list assocs assoc undef_list backref string_dvar\n%type <node> for_var block_var opt_block_var block_par\n%type <node> brace_block cmd_brace_block do_block lhs none fitem\n%type <node> mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node\n%type <id>   fsym variable sym symbol operation operation2 operation3\n%type <id>   cname fname op\n%type <num>  f_norm_arg f_arg\n%token tUPLUS \t\t/* unary+ */\n%token tUMINUS \t\t/* unary- */\n%token tPOW\t\t/* ** */\n%token tCMP  \t\t/* <=> */\n%token tEQ  \t\t/* == */\n%token tEQQ  \t\t/* === */\n%token tNEQ  \t\t/* != */\n%token tGEQ  \t\t/* >= */\n%token tLEQ  \t\t/* <= */\n%token tANDOP tOROP\t/* && and || */\n%token tMATCH tNMATCH\t/* =~ and !~ */\n%token tDOT2 tDOT3\t/* .. and ... */\n%token tAREF tASET\t/* [] and []= */\n%token tLSHFT tRSHFT\t/* << and >> */\n%token tCOLON2\t\t/* :: */\n%token tCOLON3\t\t/* :: at EXPR_BEG */\n%token <id> tOP_ASGN\t/* +=, -=  etc. */\n%token tASSOC\t\t/* => */\n%token tLPAREN\t\t/* ( */\n%token tLPAREN_ARG\t/* ( */\n%token tRPAREN\t\t/* ) */\n%token tLBRACK\t\t/* [ */\n%token tLBRACE\t\t/* { */\n%token tLBRACE_ARG\t/* { */\n%token tSTAR\t\t/* * */\n%token tAMPER\t\t/* & */\n%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG\n%token tSTRING_DBEG tSTRING_DVAR tSTRING_END\n\n/*\n *\tprecedence table\n */\n\n%nonassoc tLOWEST\n%nonassoc tLBRACE_ARG\n\n%nonassoc  kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD\n%left  kOR kAND\n%right kNOT\n%nonassoc kDEFINED\n%right '=' tOP_ASGN\n%left kRESCUE_MOD\n%right '?' ':'\n%nonassoc tDOT2 tDOT3\n%left  tOROP\n%left  tANDOP\n%nonassoc  tCMP tEQ tEQQ tNEQ tMATCH tNMATCH\n%left  '>' tGEQ '<' tLEQ\n%left  '|' '^'\n%left  '&'\n%left  tLSHFT tRSHFT\n%left  '+' '-'\n%left  '*' '/' '%'\n%right tUMINUS_NUM tUMINUS\n%right tPOW\n%right '!' '~' tUPLUS\n\n%token tLAST_TOKEN\n\n%%\nprogram\t\t:  {\n\t\t\tlex_state = EXPR_BEG;\n                        top_local_init();\n\t\t\tif (ruby_class == rb_cObject) class_nest = 0;\n\t\t\telse class_nest = 1;\n\t\t    }\n\t\t  compstmt\n\t\t    {\n\t\t\tif ($2 && !compile_for_eval) {\n                            /* last expression should not be void */\n\t\t\t    if (nd_type($2) != NODE_BLOCK) void_expr($2);\n\t\t\t    else {\n\t\t\t\tNODE *node = $2;\n\t\t\t\twhile (node->nd_next) {\n\t\t\t\t    node = node->nd_next;\n\t\t\t\t}\n\t\t\t\tvoid_expr(node->nd_head);\n\t\t\t    }\n\t\t\t}\n\t\t\truby_eval_tree = block_append(ruby_eval_tree, $2);\n                        top_local_setup();\n\t\t\tclass_nest = 0;\n\t\t    }\n\t\t;\n\nbodystmt\t: compstmt\n\t\t  opt_rescue\n\t\t  opt_else\n\t\t  opt_ensure\n\t\t    {\n\t\t        $$ = $1;\n\t\t\tif ($2) {\n\t\t\t    $$ = NEW_RESCUE($1, $2, $3);\n\t\t\t}\n\t\t\telse if ($3) {\n\t\t\t    rb_warn(\"else without rescue is useless\");\n\t\t\t    $$ = block_append($$, $3);\n\t\t\t}\n\t\t\tif ($4) {\n\t\t\t    $$ = NEW_ENSURE($$, $4);\n\t\t\t}\n\t\t\tfixpos($$, $1);\n\t\t    }\n\t\t;\n\ncompstmt\t: stmts opt_terms\n\t\t    {\n\t\t\tvoid_stmts($1);\n\t\t\tfixup_nodes(&deferred_nodes);\n\t\t        $$ = $1;\n\t\t    }\n\t\t;\n\nstmts\t\t: none\n\t\t| stmt\n\t\t    {\n\t\t\t$$ = newline_node($1);\n\t\t    }\n\t\t| stmts terms stmt\n\t\t    {\n\t\t\t$$ = block_append($1, newline_node($3));\n\t\t    }\n\t\t| error stmt\n\t\t    {\n\t\t\t$$ = remove_begin($2);\n\t\t    }\n\t\t;\n\nstmt\t\t: kALIAS fitem {lex_state = EXPR_FNAME;} fitem\n\t\t    {\n\t\t        $$ = NEW_ALIAS($2, $4);\n\t\t    }\n\t\t| kALIAS tGVAR tGVAR\n\t\t    {\n\t\t        $$ = NEW_VALIAS($2, $3);\n\t\t    }\n\t\t| kALIAS tGVAR tBACK_REF\n\t\t    {\n\t\t\tchar buf[3];\n\n\t\t\tsprintf(buf, \"$%c\", (char)$3->nd_nth);\n\t\t        $$ = NEW_VALIAS($2, rb_intern(buf));\n\t\t    }\n\t\t| kALIAS tGVAR tNTH_REF\n\t\t    {\n\t\t        yyerror(\"can't make alias for the number variables\");\n\t\t        $$ = 0;\n\t\t    }\n\t\t| kUNDEF undef_list\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| stmt kIF_MOD expr_value\n\t\t    {\n\t\t\t$$ = NEW_IF(cond($3), remove_begin($1), 0);\n\t\t        fixpos($$, $3);\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t            $$->nd_else = $$->nd_body;\n\t\t            $$->nd_body = 0;\n\t\t\t}\n\t\t    }\n\t\t| stmt kUNLESS_MOD expr_value\n\t\t    {\n\t\t\t$$ = NEW_UNLESS(cond($3), remove_begin($1), 0);\n\t\t        fixpos($$, $3);\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t            $$->nd_body = $$->nd_else;\n\t\t            $$->nd_else = 0;\n\t\t\t}\n\t\t    }\n\t\t| stmt kWHILE_MOD expr_value\n\t\t    {\n\t\t\tif ($1 && nd_type($1) == NODE_BEGIN) {\n\t\t\t    $$ = NEW_WHILE(cond($3), $1->nd_body, 0);\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = NEW_WHILE(cond($3), $1, 1);\n\t\t\t}\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t\t    nd_set_type($$, NODE_UNTIL);\n\t\t\t}\n\t\t    }\n\t\t| stmt kUNTIL_MOD expr_value\n\t\t    {\n\t\t\tif ($1 && nd_type($1) == NODE_BEGIN) {\n\t\t\t    $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = NEW_UNTIL(cond($3), $1, 1);\n\t\t\t}\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t\t    nd_set_type($$, NODE_WHILE);\n\t\t\t}\n\t\t    }\n\t\t| stmt kRESCUE_MOD stmt\n\t\t    {\n\t\t\tNODE *resq = NEW_RESBODY(0, remove_begin($3), 0);\n\t\t\t$$ = NEW_RESCUE(remove_begin($1), resq, 0);\n\t\t    }\n\t\t| klBEGIN\n\t\t    {\n\t\t\tif (in_def || in_single) {\n\t\t\t    yyerror(\"BEGIN in method\");\n\t\t\t}\n\t\t\tlocal_push(0);\n\t\t    }\n\t\t  '{' compstmt '}'\n\t\t    {\n\t\t\truby_eval_tree_begin = block_append(ruby_eval_tree_begin,\n\t\t\t\t\t\t            NEW_PREEXE($4));\n\t\t        local_pop();\n\t\t        $$ = 0;\n\t\t    }\n\t\t| klEND '{' compstmt '}'\n\t\t    {\n\t\t\tif (in_def || in_single) {\n\t\t\t    rb_warn(\"END in method; use at_exit\");\n\t\t\t}\n\n\t\t\t$$ = NEW_ITER(0, NEW_POSTEXE(), $3);\n\t\t    }\n\t\t| lhs '=' command_call\n\t\t    {\n\t\t\t$$ = node_assign($1, $3);\n\t\t    }\n\t\t| mlhs '=' command_call\n\t\t    {\n\t\t\tvalue_expr($3);\n\t\t\t$1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);\n\t\t\t$$ = $1;\n\t\t    }\n\t\t| var_lhs tOP_ASGN command_call\n\t\t    {\n\t\t\tvalue_expr($3);\n\t\t\tif ($1) {\n\t\t\t    ID vid = $1->nd_vid;\n\t\t\t    if ($2 == tOROP) {\n\t\t\t\t$1->nd_value = $3;\n\t\t\t\t$$ = NEW_OP_ASGN_OR(gettable(vid), $1);\n\t\t\t\tif (is_asgn_or_id(vid)) {\n\t\t\t\t    $$->nd_aid = vid;\n\t\t\t\t}\n\t\t\t    }\n\t\t\t    else if ($2 == tANDOP) {\n\t\t\t\t$1->nd_value = $3;\n\t\t\t\t$$ = NEW_OP_ASGN_AND(gettable(vid), $1);\n\t\t\t    }\n\t\t\t    else {\n\t\t\t\t$$ = $1;\n\t\t\t\t$$->nd_value = call_op(gettable(vid),$2,1,$3);\n\t\t\t    }\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = 0;\n\t\t\t}\n\t\t    }\n\t\t| primary_value '[' aref_args ']' tOP_ASGN command_call\n\t\t    {\n                        NODE *args;\n\n\t\t\tvalue_expr($6);\n\t\t\tif (!$3) $3 = NEW_ZARRAY();\n\t\t\targs = arg_concat($6, $3);\n\t\t\tif ($5 == tOROP) {\n\t\t\t    $5 = 0;\n\t\t\t}\n\t\t\telse if ($5 == tANDOP) {\n\t\t\t    $5 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN1($1, $5, args);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value '.' tIDENTIFIER tOP_ASGN command_call\n\t\t    {\n\t\t\tvalue_expr($5);\n\t\t\tif ($4 == tOROP) {\n\t\t\t    $4 = 0;\n\t\t\t}\n\t\t\telse if ($4 == tANDOP) {\n\t\t\t    $4 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN2($1, $3, $4, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value '.' tCONSTANT tOP_ASGN command_call\n\t\t    {\n\t\t\tvalue_expr($5);\n\t\t\tif ($4 == tOROP) {\n\t\t\t    $4 = 0;\n\t\t\t}\n\t\t\telse if ($4 == tANDOP) {\n\t\t\t    $4 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN2($1, $3, $4, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call\n\t\t    {\n\t\t\tvalue_expr($5);\n\t\t\tif ($4 == tOROP) {\n\t\t\t    $4 = 0;\n\t\t\t}\n\t\t\telse if ($4 == tANDOP) {\n\t\t\t    $4 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN2($1, $3, $4, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| backref tOP_ASGN command_call\n\t\t    {\n\t\t        rb_backref_error($1);\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| lhs '=' mrhs\n\t\t    {\n\t\t\t$$ = node_assign($1, NEW_SVALUE($3));\n\t\t    }\n\t\t| mlhs '=' arg_value\n\t\t    {\n\t\t\t$1->nd_value = ($1->nd_head) ? NEW_TO_ARY($3) : NEW_ARRAY($3);\n\t\t\t$$ = $1;\n\t\t    }\n\t\t| mlhs '=' mrhs\n\t\t    {\n\t\t\t$1->nd_value = $3;\n\t\t\t$$ = $1;\n\t\t    }\n\t\t| expr\n\t\t;\n\nexpr\t\t: command_call\n\t\t| expr kAND expr\n\t\t    {\n\t\t\t$$ = logop(NODE_AND, $1, $3);\n\t\t    }\n\t\t| expr kOR expr\n\t\t    {\n\t\t\t$$ = logop(NODE_OR, $1, $3);\n\t\t    }\n\t\t| kNOT expr\n\t\t    {\n\t\t\t$$ = NEW_NOT(cond($2));\n\t\t    }\n\t\t| '!' command_call\n\t\t    {\n\t\t\t$$ = NEW_NOT(cond($2));\n\t\t    }\n\t\t| arg\n\t\t;\n\nexpr_value\t: expr\n\t\t    {\n\t\t\tvalue_expr($$);\n\t\t\t$$ = $1;\n\t\t    }\n\t\t;\n\ncommand_call\t: command\n\t\t| block_command\n\t\t| kRETURN call_args\n\t\t    {\n\t\t\t$$ = NEW_RETURN(ret_args($2));\n\t\t    }\n\t\t| kBREAK call_args\n\t\t    {\n\t\t\t$$ = NEW_BREAK(ret_args($2));\n\t\t    }\n\t\t| kNEXT call_args\n\t\t    {\n\t\t\t$$ = NEW_NEXT(ret_args($2));\n\t\t    }\n\t\t;\n\nblock_command\t: block_call\n\t\t| block_call '.' operation2 command_args\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t    }\n\t\t| block_call tCOLON2 operation2 command_args\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t    }\n\t\t;\n\ncmd_brace_block\t: tLBRACE_ARG\n\t\t    {\n\t\t\t$<vars>$ = dyna_push();\n\t\t\t$<num>1 = ruby_sourceline;\n\t\t    }\n\t\t  opt_block_var {$<vars>$ = ruby_dyna_vars;}\n\t\t  compstmt\n\t\t  '}'\n\t\t    {\n\t\t\t$$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4));\n\t\t\tnd_set_line($$, $<num>1);\n\t\t\tdyna_pop($<vars>2);\n\t\t    }\n\t\t;\n\ncommand\t\t: operation command_args       %prec tLOWEST\n\t\t    {\n\t\t\t$$ = new_fcall($1, $2);\n\t\t        fixpos($$, $2);\n\t\t   }\n\t\t| operation command_args cmd_brace_block\n\t\t    {\n\t\t\t$$ = new_fcall($1, $2);\n\t\t\tif ($3) {\n\t\t\t    if (nd_type($$) == NODE_BLOCK_PASS) {\n\t\t\t\trb_compile_error(\"both block arg and actual block given\");\n\t\t\t    }\n\t\t\t    $3->nd_iter = $$;\n\t\t\t    $$ = $3;\n\t\t\t}\n\t\t        fixpos($$, $2);\n\t\t   }\n\t\t| primary_value '.' operation2 command_args\t%prec tLOWEST\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value '.' operation2 command_args cmd_brace_block\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t\tif ($5) {\n\t\t\t    if (nd_type($$) == NODE_BLOCK_PASS) {\n\t\t\t\trb_compile_error(\"both block arg and actual block given\");\n\t\t\t    }\n\t\t\t    $5->nd_iter = $$;\n\t\t\t    $$ = $5;\n\t\t\t}\n\t\t        fixpos($$, $1);\n\t\t   }\n\t\t| primary_value tCOLON2 operation2 command_args\t%prec tLOWEST\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value tCOLON2 operation2 command_args cmd_brace_block\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t\tif ($5) {\n\t\t\t    if (nd_type($$) == NODE_BLOCK_PASS) {\n\t\t\t\trb_compile_error(\"both block arg and actual block given\");\n\t\t\t    }\n\t\t\t    $5->nd_iter = $$;\n\t\t\t    $$ = $5;\n\t\t\t}\n\t\t        fixpos($$, $1);\n\t\t   }\n\t\t| kSUPER command_args\n\t\t    {\n\t\t\t$$ = new_super($2);\n\t\t        fixpos($$, $2);\n\t\t    }\n\t\t| kYIELD command_args\n\t\t    {\n\t\t\t$$ = new_yield($2);\n\t\t        fixpos($$, $2);\n\t\t    }\n\t\t;\n\nmlhs\t\t: mlhs_basic\n\t\t| tLPAREN mlhs_entry ')'\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nmlhs_entry\t: mlhs_basic\n\t\t| tLPAREN mlhs_entry ')'\n\t\t    {\n\t\t\t$$ = NEW_MASGN(NEW_LIST($2), 0);\n\t\t    }\n\t\t;\n\nmlhs_basic\t: mlhs_head\n\t\t    {\n\t\t\t$$ = NEW_MASGN($1, 0);\n\t\t    }\n\t\t| mlhs_head mlhs_item\n\t\t    {\n\t\t\t$$ = NEW_MASGN(list_append($1,$2), 0);\n\t\t    }\n\t\t| mlhs_head tSTAR mlhs_node\n\t\t    {\n\t\t\t$$ = NEW_MASGN($1, $3);\n\t\t    }\n\t\t| mlhs_head tSTAR\n\t\t    {\n\t\t\t$$ = NEW_MASGN($1, -1);\n\t\t    }\n\t\t| tSTAR mlhs_node\n\t\t    {\n\t\t\t$$ = NEW_MASGN(0, $2);\n\t\t    }\n\t\t| tSTAR\n\t\t    {\n\t\t\t$$ = NEW_MASGN(0, -1);\n\t\t    }\n\t\t;\n\nmlhs_item\t: mlhs_node\n\t\t| tLPAREN mlhs_entry ')'\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nmlhs_head\t: mlhs_item ','\n\t\t    {\n\t\t\t$$ = NEW_LIST($1);\n\t\t    }\n\t\t| mlhs_head mlhs_item ','\n\t\t    {\n\t\t\t$$ = list_append($1, $2);\n\t\t    }\n\t\t;\n\nmlhs_node\t: variable\n\t\t    {\n\t\t\t$$ = assignable($1, 0);\n\t\t    }\n\t\t| primary_value '[' aref_args ']'\n\t\t    {\n\t\t\t$$ = aryset($1, $3);\n\t\t    }\n\t\t| primary_value '.' tIDENTIFIER\n\t\t    {\n\t\t\t$$ = attrset($1, $3);\n\t\t    }\n\t\t| primary_value tCOLON2 tIDENTIFIER\n\t\t    {\n\t\t\t$$ = attrset($1, $3);\n\t\t    }\n\t\t| primary_value '.' tCONSTANT\n\t\t    {\n\t\t\t$$ = attrset($1, $3);\n\t\t    }\n\t\t| primary_value tCOLON2 tCONSTANT\n\t\t    {\n\t\t\tif (in_def || in_single)\n\t\t\t    yyerror(\"dynamic constant assignment\");\n\t\t\t$$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));\n\t\t    }\n\t\t| tCOLON3 tCONSTANT\n\t\t    {\n\t\t\tif (in_def || in_single)\n\t\t\t    yyerror(\"dynamic constant assignment\");\n\t\t\t$$ = NEW_CDECL(0, 0, NEW_COLON3($2));\n\t\t    }\n\t\t| backref\n\t\t    {\n\t\t        rb_backref_error($1);\n\t\t\t$$ = 0;\n\t\t    }\n\t\t;\n\nlhs\t\t: variable\n\t\t    {\n\t\t\t$$ = assignable($1, 0);\n\t\t    }\n\t\t| primary_value '[' aref_args ']'\n\t\t    {\n\t\t\t$$ = aryset($1, $3);\n\t\t    }\n\t\t| primary_value '.' tIDENTIFIER\n\t\t    {\n\t\t\t$$ = attrset($1, $3);\n\t\t    }\n\t\t| primary_value tCOLON2 tIDENTIFIER\n\t\t    {\n\t\t\t$$ = attrset($1, $3);\n\t\t    }\n\t\t| primary_value '.' tCONSTANT\n\t\t    {\n\t\t\t$$ = attrset($1, $3);\n\t\t    }\n\t\t| primary_value tCOLON2 tCONSTANT\n\t\t    {\n\t\t\tif (in_def || in_single)\n\t\t\t    yyerror(\"dynamic constant assignment\");\n\t\t\t$$ = NEW_CDECL(0, 0, NEW_COLON2($1, $3));\n\t\t    }\n\t\t| tCOLON3 tCONSTANT\n\t\t    {\n\t\t\tif (in_def || in_single)\n\t\t\t    yyerror(\"dynamic constant assignment\");\n\t\t\t$$ = NEW_CDECL(0, 0, NEW_COLON3($2));\n\t\t    }\n\t\t| backref\n\t\t    {\n\t\t        rb_backref_error($1);\n\t\t\t$$ = 0;\n\t\t    }\n\t\t;\n\ncname\t\t: tIDENTIFIER\n\t\t    {\n\t\t\tyyerror(\"class/module name must be CONSTANT\");\n\t\t    }\n\t\t| tCONSTANT\n\t\t;\n\ncpath\t\t: tCOLON3 cname\n\t\t    {\n\t\t\t$$ = NEW_COLON3($2);\n\t\t    }\n\t\t| cname\n\t\t    {\n\t\t\t$$ = NEW_COLON2(0, $$);\n\t\t    }\n\t\t| primary_value tCOLON2 cname\n\t\t    {\n\t\t\t$$ = NEW_COLON2($1, $3);\n\t\t    }\n\t\t;\n\nfname\t\t: tIDENTIFIER\n\t\t| tCONSTANT\n\t\t| tFID\n\t\t| op\n\t\t    {\n\t\t\tlex_state = EXPR_END;\n\t\t\t$$ = $1;\n\t\t    }\n\t\t| reswords\n\t\t    {\n\t\t\tlex_state = EXPR_END;\n\t\t\t$$ = $<id>1;\n\t\t    }\n\t\t;\n\nfsym\t\t: fname\n\t\t| symbol\n\t\t;\n\nfitem\t\t: fsym\n\t\t    {\n\t\t\t$$ = NEW_LIT(ID2SYM($1));\n\t\t    }\n\t\t| dsym\n\t\t;\n\nundef_list\t: fitem\n\t\t    {\n\t\t\t$$ = NEW_UNDEF($1);\n\t\t    }\n\t\t| undef_list ',' {lex_state = EXPR_FNAME;} fitem\n\t\t    {\n\t\t\t$$ = block_append($1, NEW_UNDEF($4));\n\t\t    }\n\t\t;\n\nop\t\t: '|'\t\t{ $$ = '|'; }\n\t\t| '^'\t\t{ $$ = '^'; }\n\t\t| '&'\t\t{ $$ = '&'; }\n\t\t| tCMP\t\t{ $$ = tCMP; }\n\t\t| tEQ\t\t{ $$ = tEQ; }\n\t\t| tEQQ\t\t{ $$ = tEQQ; }\n\t\t| tMATCH\t{ $$ = tMATCH; }\n\t\t| '>'\t\t{ $$ = '>'; }\n\t\t| tGEQ\t\t{ $$ = tGEQ; }\n\t\t| '<'\t\t{ $$ = '<'; }\n\t\t| tLEQ\t\t{ $$ = tLEQ; }\n\t\t| tLSHFT\t{ $$ = tLSHFT; }\n\t\t| tRSHFT\t{ $$ = tRSHFT; }\n\t\t| '+'\t\t{ $$ = '+'; }\n\t\t| '-'\t\t{ $$ = '-'; }\n\t\t| '*'\t\t{ $$ = '*'; }\n\t\t| tSTAR\t\t{ $$ = '*'; }\n\t\t| '/'\t\t{ $$ = '/'; }\n\t\t| '%'\t\t{ $$ = '%'; }\n\t\t| tPOW\t\t{ $$ = tPOW; }\n\t\t| '~'\t\t{ $$ = '~'; }\n\t\t| tUPLUS\t{ $$ = tUPLUS; }\n\t\t| tUMINUS\t{ $$ = tUMINUS; }\n\t\t| tAREF\t\t{ $$ = tAREF; }\n\t\t| tASET\t\t{ $$ = tASET; }\n\t\t| '`'\t\t{ $$ = '`'; }\n\t\t;\n\nreswords\t: k__LINE__ | k__FILE__  | klBEGIN | klEND\n\t\t| kALIAS | kAND | kBEGIN | kBREAK | kCASE | kCLASS | kDEF\n\t\t| kDEFINED | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE\n\t\t| kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT\n\t\t| kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF | kSUPER\n\t\t| kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD\n\t\t| kIF | kUNLESS | kWHILE | kUNTIL\n\t\t;\n\narg\t\t: lhs '=' arg\n\t\t    {\n\t\t\t$$ = node_assign($1, $3);\n\t\t    }\n\t\t| lhs '=' arg kRESCUE_MOD arg\n\t\t    {\n\t\t\t$$ = node_assign($1, NEW_RESCUE($3, NEW_RESBODY(0,$5,0), 0));\n\t\t    }\n\t\t| var_lhs tOP_ASGN arg\n\t\t    {\n\t\t\tvalue_expr($3);\n\t\t\tif ($1) {\n\t\t\t    ID vid = $1->nd_vid;\n\t\t\t    if ($2 == tOROP) {\n\t\t\t\t$1->nd_value = $3;\n\t\t\t\t$$ = NEW_OP_ASGN_OR(gettable(vid), $1);\n\t\t\t\tif (is_asgn_or_id(vid)) {\n\t\t\t\t    $$->nd_aid = vid;\n\t\t\t\t}\n\t\t\t    }\n\t\t\t    else if ($2 == tANDOP) {\n\t\t\t\t$1->nd_value = $3;\n\t\t\t\t$$ = NEW_OP_ASGN_AND(gettable(vid), $1);\n\t\t\t    }\n\t\t\t    else {\n\t\t\t\t$$ = $1;\n\t\t\t\t$$->nd_value = call_op(gettable(vid),$2,1,$3);\n\t\t\t    }\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = 0;\n\t\t\t}\n\t\t    }\n\t\t| primary_value '[' aref_args ']' tOP_ASGN arg\n\t\t    {\n                        NODE *args;\n\n\t\t\tvalue_expr($6);\n\t\t\tif (!$3) $3 = NEW_ZARRAY();\n\t\t\targs = arg_concat($6, $3);\n\t\t\tif ($5 == tOROP) {\n\t\t\t    $5 = 0;\n\t\t\t}\n\t\t\telse if ($5 == tANDOP) {\n\t\t\t    $5 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN1($1, $5, args);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value '.' tIDENTIFIER tOP_ASGN arg\n\t\t    {\n\t\t\tvalue_expr($5);\n\t\t\tif ($4 == tOROP) {\n\t\t\t    $4 = 0;\n\t\t\t}\n\t\t\telse if ($4 == tANDOP) {\n\t\t\t    $4 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN2($1, $3, $4, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value '.' tCONSTANT tOP_ASGN arg\n\t\t    {\n\t\t\tvalue_expr($5);\n\t\t\tif ($4 == tOROP) {\n\t\t\t    $4 = 0;\n\t\t\t}\n\t\t\telse if ($4 == tANDOP) {\n\t\t\t    $4 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN2($1, $3, $4, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg\n\t\t    {\n\t\t\tvalue_expr($5);\n\t\t\tif ($4 == tOROP) {\n\t\t\t    $4 = 0;\n\t\t\t}\n\t\t\telse if ($4 == tANDOP) {\n\t\t\t    $4 = 1;\n\t\t\t}\n\t\t\t$$ = NEW_OP_ASGN2($1, $3, $4, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value tCOLON2 tCONSTANT tOP_ASGN arg\n\t\t    {\n\t\t\tyyerror(\"constant re-assignment\");\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| tCOLON3 tCONSTANT tOP_ASGN arg\n\t\t    {\n\t\t\tyyerror(\"constant re-assignment\");\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| backref tOP_ASGN arg\n\t\t    {\n\t\t        rb_backref_error($1);\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| arg tDOT2 arg\n\t\t    {\n\t\t\tvalue_expr($1);\n\t\t\tvalue_expr($3);\n\t\t\t$$ = NEW_DOT2($1, $3);\n\t\t\tif (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&\n\t\t\t    nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {\n\t\t\t    deferred_nodes = list_append(deferred_nodes, $$);\n\t\t\t}\n\t\t    }\n\t\t| arg tDOT3 arg\n\t\t    {\n\t\t\tvalue_expr($1);\n\t\t\tvalue_expr($3);\n\t\t\t$$ = NEW_DOT3($1, $3);\n\t\t\tif (nd_type($1) == NODE_LIT && FIXNUM_P($1->nd_lit) &&\n\t\t\t    nd_type($3) == NODE_LIT && FIXNUM_P($3->nd_lit)) {\n\t\t\t    deferred_nodes = list_append(deferred_nodes, $$);\n\t\t\t}\n\t\t    }\n\t\t| arg '+' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '+', 1, $3);\n\t\t    }\n\t\t| arg '-' arg\n\t\t    {\n\t\t        $$ = call_op($1, '-', 1, $3);\n\t\t    }\n\t\t| arg '*' arg\n\t\t    {\n\t\t        $$ = call_op($1, '*', 1, $3);\n\t\t    }\n\t\t| arg '/' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '/', 1, $3);\n\t\t    }\n\t\t| arg '%' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '%', 1, $3);\n\t\t    }\n\t\t| arg tPOW arg\n\t\t    {\n\t\t\t$$ = call_op($1, tPOW, 1, $3);\n\t\t    }\n\t\t| tUMINUS_NUM tINTEGER tPOW arg\n\t\t    {\n\t\t\t$$ = call_op(call_op($2, tPOW, 1, $4), tUMINUS, 0, 0);\n\t\t    }\n\t\t| tUMINUS_NUM tFLOAT tPOW arg\n\t\t    {\n\t\t\t$$ = call_op(call_op($2, tPOW, 1, $4), tUMINUS, 0, 0);\n\t\t    }\n\t\t| tUPLUS arg\n\t\t    {\n\t\t\tif ($2 && nd_type($2) == NODE_LIT) {\n\t\t\t    $$ = $2;\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = call_op($2, tUPLUS, 0, 0);\n\t\t\t}\n\t\t    }\n\t\t| tUMINUS arg\n\t\t    {\n\t\t\t$$ = call_op($2, tUMINUS, 0, 0);\n\t\t    }\n\t\t| arg '|' arg\n\t\t    {\n\t\t        $$ = call_op($1, '|', 1, $3);\n\t\t    }\n\t\t| arg '^' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '^', 1, $3);\n\t\t    }\n\t\t| arg '&' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '&', 1, $3);\n\t\t    }\n\t\t| arg tCMP arg\n\t\t    {\n\t\t\t$$ = call_op($1, tCMP, 1, $3);\n\t\t    }\n\t\t| arg '>' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '>', 1, $3);\n\t\t    }\n\t\t| arg tGEQ arg\n\t\t    {\n\t\t\t$$ = call_op($1, tGEQ, 1, $3);\n\t\t    }\n\t\t| arg '<' arg\n\t\t    {\n\t\t\t$$ = call_op($1, '<', 1, $3);\n\t\t    }\n\t\t| arg tLEQ arg\n\t\t    {\n\t\t\t$$ = call_op($1, tLEQ, 1, $3);\n\t\t    }\n\t\t| arg tEQ arg\n\t\t    {\n\t\t\t$$ = call_op($1, tEQ, 1, $3);\n\t\t    }\n\t\t| arg tEQQ arg\n\t\t    {\n\t\t\t$$ = call_op($1, tEQQ, 1, $3);\n\t\t    }\n\t\t| arg tNEQ arg\n\t\t    {\n\t\t\t$$ = NEW_NOT(call_op($1, tEQ, 1, $3));\n\t\t    }\n\t\t| arg tMATCH arg\n\t\t    {\n\t\t\t$$ = match_gen($1, $3);\n\t\t    }\n\t\t| arg tNMATCH arg\n\t\t    {\n\t\t\t$$ = NEW_NOT(match_gen($1, $3));\n\t\t    }\n\t\t| '!' arg\n\t\t    {\n\t\t\t$$ = NEW_NOT(cond($2));\n\t\t    }\n\t\t| '~' arg\n\t\t    {\n\t\t\t$$ = call_op($2, '~', 0, 0);\n\t\t    }\n\t\t| arg tLSHFT arg\n\t\t    {\n\t\t\t$$ = call_op($1, tLSHFT, 1, $3);\n\t\t    }\n\t\t| arg tRSHFT arg\n\t\t    {\n\t\t\t$$ = call_op($1, tRSHFT, 1, $3);\n\t\t    }\n\t\t| arg tANDOP arg\n\t\t    {\n\t\t\t$$ = logop(NODE_AND, $1, $3);\n\t\t    }\n\t\t| arg tOROP arg\n\t\t    {\n\t\t\t$$ = logop(NODE_OR, $1, $3);\n\t\t    }\n\t\t| kDEFINED opt_nl {in_defined = 1;} arg\n\t\t    {\n\t\t        in_defined = 0;\n\t\t\t$$ = NEW_DEFINED($4);\n\t\t    }\n\t\t| arg '?' arg ':' arg\n\t\t    {\n\t\t\t$$ = NEW_IF(cond($1), $3, $5);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary\n\t\t    {\n\t\t\t$$ = $1;\n\t\t    }\n\t\t;\n\narg_value\t: arg\n\t\t    {\n\t\t\tvalue_expr($1);\n\t\t\t$$ = $1;\n\t\t    }\n\t\t;\n\naref_args\t: none\n\t\t| command opt_nl\n\t\t    {\n\t\t\t$$ = NEW_LIST($1);\n\t\t    }\n\t\t| args trailer\n\t\t    {\n\t\t\t$$ = $1;\n\t\t    }\n\t\t| args ',' tSTAR arg opt_nl\n\t\t    {\n\t\t\tvalue_expr($4);\n\t\t\t$$ = arg_concat($1, $4);\n\t\t    }\n\t\t| assocs trailer\n\t\t    {\n\t\t\t$$ = NEW_LIST(NEW_HASH($1));\n\t\t    }\n\t\t| tSTAR arg opt_nl\n\t\t    {\n\t\t\tvalue_expr($2);\n\t\t\t$$ = NEW_NEWLINE(NEW_SPLAT($2));\n\t\t    }\n\t\t;\n\nparen_args\t: '(' none ')'\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| '(' call_args opt_nl ')'\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| '(' block_call opt_nl ')'\n\t\t    {\n\t\t\t$$ = NEW_LIST($2);\n\t\t    }\n\t\t| '(' args ',' block_call opt_nl ')'\n\t\t    {\n\t\t\t$$ = list_append($2, $4);\n\t\t    }\n\t\t;\n\nopt_paren_args\t: none\n\t\t| paren_args\n\t\t;\n\ncall_args\t: command\n\t\t    {\n\t\t\t$$ = NEW_LIST($1);\n\t\t    }\n\t\t| args opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_blk_pass($1, $2);\n\t\t    }\n\t\t| args ',' tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_concat($1, $4);\n\t\t\t$$ = arg_blk_pass($$, $5);\n\t\t    }\n\t\t| assocs opt_block_arg\n\t\t    {\n\t\t\t$$ = NEW_LIST(NEW_HASH($1));\n\t\t\t$$ = arg_blk_pass($$, $2);\n\t\t    }\n\t\t| assocs ',' tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_concat(NEW_LIST(NEW_HASH($1)), $4);\n\t\t\t$$ = arg_blk_pass($$, $5);\n\t\t    }\n\t\t| args ',' assocs opt_block_arg\n\t\t    {\n\t\t\t$$ = list_append($1, NEW_HASH($3));\n\t\t\t$$ = arg_blk_pass($$, $4);\n\t\t    }\n\t\t| args ',' assocs ',' tSTAR arg opt_block_arg\n\t\t    {\n\t\t\tvalue_expr($6);\n\t\t\t$$ = arg_concat(list_append($1, NEW_HASH($3)), $6);\n\t\t\t$$ = arg_blk_pass($$, $7);\n\t\t    }\n\t\t| tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_blk_pass(NEW_SPLAT($2), $3);\n\t\t    }\n\t\t| block_arg\n\t\t;\n\ncall_args2\t: arg_value ',' args opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_blk_pass(list_concat(NEW_LIST($1),$3), $4);\n\t\t    }\n\t\t| arg_value ',' block_arg\n\t\t    {\n                        $$ = arg_blk_pass($1, $3);\n                    }\n\t\t| arg_value ',' tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_concat(NEW_LIST($1), $4);\n\t\t\t$$ = arg_blk_pass($$, $5);\n\t\t    }\n\t\t| arg_value ',' args ',' tSTAR arg_value opt_block_arg\n\t\t    {\n                       $$ = arg_concat(list_concat(NEW_LIST($1),$3), $6);\n\t\t\t$$ = arg_blk_pass($$, $7);\n\t\t    }\n\t\t| assocs opt_block_arg\n\t\t    {\n\t\t\t$$ = NEW_LIST(NEW_HASH($1));\n\t\t\t$$ = arg_blk_pass($$, $2);\n\t\t    }\n\t\t| assocs ',' tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_concat(NEW_LIST(NEW_HASH($1)), $4);\n\t\t\t$$ = arg_blk_pass($$, $5);\n\t\t    }\n\t\t| arg_value ',' assocs opt_block_arg\n\t\t    {\n\t\t\t$$ = list_append(NEW_LIST($1), NEW_HASH($3));\n\t\t\t$$ = arg_blk_pass($$, $4);\n\t\t    }\n\t\t| arg_value ',' args ',' assocs opt_block_arg\n\t\t    {\n\t\t\t$$ = list_append(list_concat(NEW_LIST($1),$3), NEW_HASH($5));\n\t\t\t$$ = arg_blk_pass($$, $6);\n\t\t    }\n\t\t| arg_value ',' assocs ',' tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_concat(list_append(NEW_LIST($1), NEW_HASH($3)), $6);\n\t\t\t$$ = arg_blk_pass($$, $7);\n\t\t    }\n\t\t| arg_value ',' args ',' assocs ',' tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_concat(list_append(list_concat(NEW_LIST($1), $3), NEW_HASH($5)), $8);\n\t\t\t$$ = arg_blk_pass($$, $9);\n\t\t    }\n\t\t| tSTAR arg_value opt_block_arg\n\t\t    {\n\t\t\t$$ = arg_blk_pass(NEW_SPLAT($2), $3);\n\t\t    }\n\t\t| block_arg\n\t\t;\n\ncommand_args\t:  {\n\t\t\t$<num>$ = cmdarg_stack;\n\t\t\tCMDARG_PUSH(1);\n\t\t    }\n\t\t  open_args\n\t\t    {\n\t\t\t/* CMDARG_POP() */\n\t\t        cmdarg_stack = $<num>1;\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nopen_args\t: call_args\n\t\t| tLPAREN_ARG  {lex_state = EXPR_ENDARG;} ')'\n\t\t    {\n\t\t        rb_warn(\"don't put space before argument parentheses\");\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| tLPAREN_ARG call_args2 {lex_state = EXPR_ENDARG;} ')'\n\t\t    {\n\t\t        rb_warn(\"don't put space before argument parentheses\");\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nblock_arg\t: tAMPER arg_value\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_PASS($2);\n\t\t    }\n\t\t;\n\nopt_block_arg\t: ',' block_arg\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| none\n\t\t;\n\nargs \t\t: arg_value\n\t\t    {\n\t\t\t$$ = NEW_LIST($1);\n\t\t    }\n\t\t| args ',' arg_value\n\t\t    {\n\t\t\t$$ = list_append($1, $3);\n\t\t    }\n\t\t;\n\nmrhs\t\t: args ',' arg_value\n\t\t    {\n\t\t\t$$ = list_append($1, $3);\n\t\t    }\n\t\t| args ',' tSTAR arg_value\n\t\t    {\n\t\t\t$$ = arg_concat($1, $4);\n\t\t    }\n\t\t| tSTAR arg_value\n\t\t    {\n\t\t\t$$ = NEW_SPLAT($2);\n\t\t    }\n\t\t;\n\nprimary\t\t: literal\n\t\t| strings\n\t\t| xstring\n\t\t| regexp\n\t\t| words\n\t\t| qwords\n\t\t| var_ref\n\t\t| backref\n\t\t| tFID\n\t\t    {\n\t\t\t$$ = NEW_FCALL($1, 0);\n\t\t    }\n\t\t| kBEGIN\n\t\t    {\n\t\t\t$<num>1 = ruby_sourceline;\n\t\t    }\n\t\t  bodystmt\n\t\t  kEND\n\t\t    {\n\t\t\tif ($3 == NULL)\n\t\t\t    $$ = NEW_NIL();\n\t\t\telse\n\t\t\t    $$ = NEW_BEGIN($3);\n\t\t\tnd_set_line($$, $<num>1);\n\t\t    }\n\t\t| tLPAREN_ARG expr {lex_state = EXPR_ENDARG;} opt_nl ')'\n\t\t    {\n\t\t        rb_warning(\"(...) interpreted as grouped expression\");\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| tLPAREN compstmt ')'\n\t\t    {\n\t\t\tif (!$2) $$ = NEW_NIL();\n\t\t\telse $$ = $2;\n\t\t    }\n\t\t| primary_value tCOLON2 tCONSTANT\n\t\t    {\n\t\t\t$$ = NEW_COLON2($1, $3);\n\t\t    }\n\t\t| tCOLON3 tCONSTANT\n\t\t    {\n\t\t\t$$ = NEW_COLON3($2);\n\t\t    }\n\t\t| primary_value '[' aref_args ']'\n\t\t    {\n\t\t\tif ($1 && nd_type($1) == NODE_SELF)\n\t\t\t    $$ = NEW_FCALL(tAREF, $3);\n\t\t\telse\n\t\t\t    $$ = NEW_CALL($1, tAREF, $3);\n\t\t\tfixpos($$, $1);\n\t\t    }\n\t\t| tLBRACK aref_args ']'\n\t\t    {\n\t\t        if ($2 == 0) {\n\t\t\t    $$ = NEW_ZARRAY(); /* zero length array*/\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = $2;\n\t\t\t}\n\t\t    }\n\t\t| tLBRACE assoc_list '}'\n\t\t    {\n\t\t\t$$ = NEW_HASH($2);\n\t\t    }\n\t\t| kRETURN\n\t\t    {\n\t\t\t$$ = NEW_RETURN(0);\n\t\t    }\n\t\t| kYIELD '(' call_args ')'\n\t\t    {\n\t\t\t$$ = new_yield($3);\n\t\t    }\n\t\t| kYIELD '(' ')'\n\t\t    {\n\t\t\t$$ = NEW_YIELD(0, Qfalse);\n\t\t    }\n\t\t| kYIELD\n\t\t    {\n\t\t\t$$ = NEW_YIELD(0, Qfalse);\n\t\t    }\n\t\t| kDEFINED opt_nl '(' {in_defined = 1;} expr ')'\n\t\t    {\n\t\t        in_defined = 0;\n\t\t\t$$ = NEW_DEFINED($5);\n\t\t    }\n\t\t| operation brace_block\n\t\t    {\n\t\t\t$2->nd_iter = NEW_FCALL($1, 0);\n\t\t\t$$ = $2;\n\t\t\tfixpos($2->nd_iter, $2);\n\t\t    }\n\t\t| method_call\n\t\t| method_call brace_block\n\t\t    {\n\t\t\tif ($1 && nd_type($1) == NODE_BLOCK_PASS) {\n\t\t\t    rb_compile_error(\"both block arg and actual block given\");\n\t\t\t}\n\t\t\t$2->nd_iter = $1;\n\t\t\t$$ = $2;\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| kIF expr_value then\n\t\t  compstmt\n\t\t  if_tail\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_IF(cond($2), $4, $5);\n\t\t        fixpos($$, $2);\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t            NODE *tmp = $$->nd_body;\n\t\t            $$->nd_body = $$->nd_else;\n\t\t            $$->nd_else = tmp;\n\t\t\t}\n\t\t    }\n\t\t| kUNLESS expr_value then\n\t\t  compstmt\n\t\t  opt_else\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_UNLESS(cond($2), $4, $5);\n\t\t        fixpos($$, $2);\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t            NODE *tmp = $$->nd_body;\n\t\t            $$->nd_body = $$->nd_else;\n\t\t            $$->nd_else = tmp;\n\t\t\t}\n\t\t    }\n\t\t| kWHILE {COND_PUSH(1);} expr_value do {COND_POP();}\n\t\t  compstmt\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_WHILE(cond($3), $6, 1);\n\t\t        fixpos($$, $3);\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t\t    nd_set_type($$, NODE_UNTIL);\n\t\t\t}\n\t\t    }\n\t\t| kUNTIL {COND_PUSH(1);} expr_value do {COND_POP();}\n\t\t  compstmt\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_UNTIL(cond($3), $6, 1);\n\t\t        fixpos($$, $3);\n\t\t\tif (cond_negative(&$$->nd_cond)) {\n\t\t\t    nd_set_type($$, NODE_WHILE);\n\t\t\t}\n\t\t    }\n\t\t| kCASE expr_value opt_terms\n\t\t  case_body\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_CASE($2, $4);\n\t\t        fixpos($$, $2);\n\t\t    }\n\t\t| kCASE opt_terms case_body kEND\n\t\t    {\n\t\t\t$$ = $3;\n\t\t    }\n\t\t| kCASE opt_terms kELSE compstmt kEND\n\t\t    {\n\t\t\t$$ = $4;\n\t\t    }\n\t\t| kFOR for_var kIN {COND_PUSH(1);} expr_value do {COND_POP();}\n\t\t  compstmt\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_FOR($2, $5, $8);\n\t\t        fixpos($$, $2);\n\t\t    }\n\t\t| kCLASS cpath superclass\n\t\t    {\n\t\t\tif (in_def || in_single)\n\t\t\t    yyerror(\"class definition in method body\");\n\t\t\tclass_nest++;\n\t\t\tlocal_push(0);\n\t\t        $<num>$ = ruby_sourceline;\n\t\t    }\n\t\t  bodystmt\n\t\t  kEND\n\t\t    {\n\t\t        $$ = NEW_CLASS($2, $5, $3);\n\t\t        nd_set_line($$, $<num>4);\n\t\t        local_pop();\n\t\t\tclass_nest--;\n\t\t    }\n\t\t| kCLASS tLSHFT expr\n\t\t    {\n\t\t\t$<num>$ = in_def;\n\t\t        in_def = 0;\n\t\t    }\n\t\t  term\n\t\t    {\n\t\t        $<num>$ = in_single;\n\t\t        in_single = 0;\n\t\t\tclass_nest++;\n\t\t\tlocal_push(0);\n\t\t    }\n\t\t  bodystmt\n\t\t  kEND\n\t\t    {\n\t\t        $$ = NEW_SCLASS($3, $7);\n\t\t        fixpos($$, $3);\n\t\t        local_pop();\n\t\t\tclass_nest--;\n\t\t        in_def = $<num>4;\n\t\t        in_single = $<num>6;\n\t\t    }\n\t\t| kMODULE cpath\n\t\t    {\n\t\t\tif (in_def || in_single)\n\t\t\t    yyerror(\"module definition in method body\");\n\t\t\tclass_nest++;\n\t\t\tlocal_push(0);\n\t\t        $<num>$ = ruby_sourceline;\n\t\t    }\n\t\t  bodystmt\n\t\t  kEND\n\t\t    {\n\t\t        $$ = NEW_MODULE($2, $4);\n\t\t        nd_set_line($$, $<num>3);\n\t\t        local_pop();\n\t\t\tclass_nest--;\n\t\t    }\n\t\t| kDEF fname\n\t\t    {\n\t\t\t$<id>$ = cur_mid;\n\t\t\tcur_mid = $2;\n\t\t\tin_def++;\n\t\t\tlocal_push(0);\n\t\t    }\n\t\t  f_arglist\n\t\t  bodystmt\n\t\t  kEND\n\t\t    {\n\t\t\tif (!$5) $5 = NEW_NIL();\n\t\t\t$$ = NEW_DEFN($2, $4, $5, NOEX_PRIVATE);\n\t\t        fixpos($$, $4);\n\t\t        local_pop();\n\t\t\tin_def--;\n\t\t\tcur_mid = $<id>3;\n\t\t    }\n\t\t| kDEF singleton dot_or_colon {lex_state = EXPR_FNAME;} fname\n\t\t    {\n\t\t\tin_single++;\n\t\t\tlocal_push(0);\n\t\t        lex_state = EXPR_END; /* force for args */\n\t\t    }\n\t\t  f_arglist\n\t\t  bodystmt\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_DEFS($2, $5, $7, $8);\n\t\t        fixpos($$, $2);\n\t\t        local_pop();\n\t\t\tin_single--;\n\t\t    }\n\t\t| kBREAK\n\t\t    {\n\t\t\t$$ = NEW_BREAK(0);\n\t\t    }\n\t\t| kNEXT\n\t\t    {\n\t\t\t$$ = NEW_NEXT(0);\n\t\t    }\n\t\t| kREDO\n\t\t    {\n\t\t\t$$ = NEW_REDO();\n\t\t    }\n\t\t| kRETRY\n\t\t    {\n\t\t\t$$ = NEW_RETRY();\n\t\t    }\n\t\t;\n\nprimary_value \t: primary\n\t\t    {\n\t\t\tvalue_expr($1);\n\t\t\t$$ = $1;\n\t\t    }\n\t\t;\n\nthen\t\t: term\n\t\t| ':'\n\t\t| kTHEN\n\t\t| term kTHEN\n\t\t;\n\ndo\t\t: term\n\t\t| ':'\n\t\t| kDO_COND\n\t\t;\n\nif_tail\t\t: opt_else\n\t\t| kELSIF expr_value then\n\t\t  compstmt\n\t\t  if_tail\n\t\t    {\n\t\t\t$$ = NEW_IF(cond($2), $4, $5);\n\t\t        fixpos($$, $2);\n\t\t    }\n\t\t;\n\nopt_else\t: none\n\t\t| kELSE compstmt\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nfor_var \t: lhs\n\t\t| mlhs\n\t\t;\n\nblock_par\t: mlhs_item\n\t\t    {\n\t\t\t$$ = NEW_LIST($1);\n\t\t    }\n\t\t| block_par ',' mlhs_item\n\t\t    {\n\t\t\t$$ = list_append($1, $3);\n\t\t    }\n\t\t;\n\nblock_var\t: block_par\n\t\t    {\n\t\t\tif ($1->nd_alen == 1) {\n\t\t\t    $$ = $1->nd_head;\n\t\t\t    rb_gc_force_recycle((VALUE)$1);\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = NEW_MASGN($1, 0);\n\t\t\t}\n\t\t    }\n\t\t| block_par ','\n\t\t    {\n\t\t\t$$ = NEW_MASGN($1, 0);\n\t\t    }\n\t\t| block_par ',' tAMPER lhs\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_VAR($4, NEW_MASGN($1, 0));\n\t\t    }\n\t\t| block_par ',' tSTAR lhs ',' tAMPER lhs\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_VAR($7, NEW_MASGN($1, $4));\n\t\t    }\n\t\t| block_par ',' tSTAR ',' tAMPER lhs\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_VAR($6, NEW_MASGN($1, -1));\n\t\t    }\n\t\t| block_par ',' tSTAR lhs\n\t\t    {\n\t\t\t$$ = NEW_MASGN($1, $4);\n\t\t    }\n\t\t| block_par ',' tSTAR\n\t\t    {\n\t\t\t$$ = NEW_MASGN($1, -1);\n\t\t    }\n\t\t| tSTAR lhs ',' tAMPER lhs\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_VAR($5, NEW_MASGN(0, $2));\n\t\t    }\n\t\t| tSTAR ',' tAMPER lhs\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_VAR($4, NEW_MASGN(0, -1));\n\t\t    }\n\t\t| tSTAR lhs\n\t\t    {\n\t\t\t$$ = NEW_MASGN(0, $2);\n\t\t    }\n\t\t| tSTAR\n\t\t    {\n\t\t\t$$ = NEW_MASGN(0, -1);\n\t\t    }\n\t\t| tAMPER lhs\n\t\t    {\n\t\t\t$$ = NEW_BLOCK_VAR($2, (NODE*)1);\n\t\t    }\n\t\t;\n\nopt_block_var\t: none\n\t\t| '|' /* none */ '|'\n\t\t    {\n\t\t\t$$ = (NODE*)1;\n\t\t\tcommand_start = Qtrue;\n\t\t    }\n\t\t| tOROP\n\t\t    {\n\t\t\t$$ = (NODE*)1;\n\t\t\tcommand_start = Qtrue;\n\t\t    }\n\t\t| '|' block_var '|'\n\t\t    {\n\t\t\t$$ = $2;\n\t\t\tcommand_start = Qtrue;\n\t\t    }\n\t\t;\n\ndo_block\t: kDO_BLOCK\n\t\t    {\n\t\t        $<vars>$ = dyna_push();\n\t\t\t$<num>1 = ruby_sourceline;\n\t\t    }\n\t\t  opt_block_var {$<vars>$ = ruby_dyna_vars;}\n\t\t  compstmt\n\t\t  kEND\n\t\t    {\n\t\t\t$$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4));\n\t\t\tnd_set_line($$, $<num>1);\n\t\t\tdyna_pop($<vars>2);\n\t\t    }\n\t\t;\n\nblock_call\t: command do_block\n\t\t    {\n\t\t\tif ($1 && nd_type($1) == NODE_BLOCK_PASS) {\n\t\t\t    rb_compile_error(\"both block arg and actual block given\");\n\t\t\t}\n\t\t\t$2->nd_iter = $1;\n\t\t\t$$ = $2;\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| block_call '.' operation2 opt_paren_args\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t    }\n\t\t| block_call tCOLON2 operation2 opt_paren_args\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t    }\n\t\t;\n\nmethod_call\t: operation paren_args\n\t\t    {\n\t\t\t$$ = new_fcall($1, $2);\n\t\t        fixpos($$, $2);\n\t\t    }\n\t\t| primary_value '.' operation2 opt_paren_args\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value tCOLON2 operation2 paren_args\n\t\t    {\n\t\t\t$$ = new_call($1, $3, $4);\n\t\t        fixpos($$, $1);\n\t\t    }\n\t\t| primary_value tCOLON2 operation3\n\t\t    {\n\t\t\t$$ = new_call($1, $3, 0);\n\t\t    }\n\t\t| kSUPER paren_args\n\t\t    {\n\t\t\t$$ = new_super($2);\n\t\t    }\n\t\t| kSUPER\n\t\t    {\n\t\t\t$$ = NEW_ZSUPER();\n\t\t    }\n\t\t;\n\nbrace_block\t: '{'\n\t\t    {\n\t\t        $<vars>$ = dyna_push();\n\t\t\t$<num>1 = ruby_sourceline;\n\t\t    }\n\t\t  opt_block_var {$<vars>$ = ruby_dyna_vars;}\n\t\t  compstmt '}'\n\t\t    {\n\t\t\t$$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4));\n\t\t\tnd_set_line($$, $<num>1);\n\t\t\tdyna_pop($<vars>2);\n\t\t    }\n\t\t| kDO\n\t\t    {\n\t\t        $<vars>$ = dyna_push();\n\t\t\t$<num>1 = ruby_sourceline;\n\t\t    }\n\t\t  opt_block_var {$<vars>$ = ruby_dyna_vars;}\n\t\t  compstmt kEND\n\t\t    {\n\t\t\t$$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4));\n\t\t\tnd_set_line($$, $<num>1);\n\t\t\tdyna_pop($<vars>2);\n\t\t    }\n\t\t;\n\ncase_body\t: kWHEN when_args then\n\t\t  compstmt\n\t\t  cases\n\t\t    {\n\t\t\t$$ = NEW_WHEN($2, $4, $5);\n\t\t    }\n\t\t;\nwhen_args\t: args\n\t\t| args ',' tSTAR arg_value\n\t\t    {\n\t\t\t$$ = list_append($1, NEW_WHEN($4, 0, 0));\n\t\t    }\n\t\t| tSTAR arg_value\n\t\t    {\n\t\t\t$$ = NEW_LIST(NEW_WHEN($2, 0, 0));\n\t\t    }\n\t\t;\n\ncases\t\t: opt_else\n\t\t| case_body\n\t\t;\n\nopt_rescue\t: kRESCUE exc_list exc_var then\n\t\t  compstmt\n\t\t  opt_rescue\n\t\t    {\n\t\t        if ($3) {\n\t\t            $3 = node_assign($3, NEW_GVAR(rb_intern(\"$!\")));\n\t\t\t    $5 = block_append($3, $5);\n\t\t\t}\n\t\t\t$$ = NEW_RESBODY($2, $5, $6);\n\t\t        fixpos($$, $2?$2:$5);\n\t\t    }\n\t\t| none\n\t\t;\n\nexc_list\t: arg_value\n\t\t    {\n\t\t\t$$ = NEW_LIST($1);\n\t\t    }\n\t\t| mrhs\n\t\t| none\n\t\t;\n\nexc_var\t\t: tASSOC lhs\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| none\n\t\t;\n\nopt_ensure\t: kENSURE compstmt\n\t\t    {\n\t\t\tif ($2)\n\t\t\t    $$ = $2;\n\t\t\telse\n\t\t\t    /* place holder */\n\t\t\t    $$ = NEW_NIL();\n\t\t    }\n\t\t| none\n\t\t;\n\nliteral\t\t: numeric\n\t\t| symbol\n\t\t    {\n\t\t\t$$ = NEW_LIT(ID2SYM($1));\n\t\t    }\n\t\t| dsym\n\t\t;\n\nstrings\t\t: string\n\t\t    {\n\t\t\tNODE *node = $1;\n\t\t\tif (!node) {\n\t\t\t    node = NEW_STR(rb_str_new(0, 0));\n\t\t\t}\n\t\t\telse {\n\t\t\t    node = evstr2dstr(node);\n\t\t\t}\n\t\t\t$$ = node;\n\t\t    }\n\t\t;\n\nstring\t\t: string1\n\t\t| string string1\n\t\t    {\n\t\t\t$$ = literal_concat($1, $2);\n\t\t    }\n\t\t;\n\nstring1\t\t: tSTRING_BEG string_contents tSTRING_END\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nxstring\t\t: tXSTRING_BEG xstring_contents tSTRING_END\n\t\t    {\n\t\t\tNODE *node = $2;\n\t\t\tif (!node) {\n\t\t\t    node = NEW_XSTR(rb_str_new(0, 0));\n\t\t\t}\n\t\t\telse {\n\t\t\t    switch (nd_type(node)) {\n\t\t\t      case NODE_STR:\n\t\t\t\tnd_set_type(node, NODE_XSTR);\n\t\t\t\tbreak;\n\t\t\t      case NODE_DSTR:\n\t\t\t\tnd_set_type(node, NODE_DXSTR);\n\t\t\t\tbreak;\n\t\t\t      default:\n\t\t\t\tnode = NEW_NODE(NODE_DXSTR, rb_str_new(0, 0), 1, NEW_LIST(node));\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t\t$$ = node;\n\t\t    }\n\t\t;\n\nregexp\t\t: tREGEXP_BEG xstring_contents tREGEXP_END\n\t\t    {\n\t\t\tint options = $3;\n\t\t\tNODE *node = $2;\n\t\t\tif (!node) {\n\t\t\t    node = NEW_LIT(rb_reg_new(\"\", 0, options & ~RE_OPTION_ONCE));\n\t\t\t}\n\t\t\telse switch (nd_type(node)) {\n\t\t\t  case NODE_STR:\n\t\t\t    {\n\t\t\t\tVALUE src = node->nd_lit;\n\t\t\t\tnd_set_type(node, NODE_LIT);\n\t\t\t\tnode->nd_lit = rb_reg_new(RSTRING(src)->ptr,\n\t\t\t\t\t\t\t  RSTRING(src)->len,\n\t\t\t\t\t\t\t  options & ~RE_OPTION_ONCE);\n\t\t\t    }\n\t\t\t    break;\n\t\t\t  default:\n\t\t\t    node = NEW_NODE(NODE_DSTR, rb_str_new(0, 0), 1, NEW_LIST(node));\n\t\t\t  case NODE_DSTR:\n\t\t\t    if (options & RE_OPTION_ONCE) {\n\t\t\t\tnd_set_type(node, NODE_DREGX_ONCE);\n\t\t\t    }\n\t\t\t    else {\n\t\t\t\tnd_set_type(node, NODE_DREGX);\n\t\t\t    }\n\t\t\t    node->nd_cflag = options & ~RE_OPTION_ONCE;\n\t\t\t    break;\n\t\t\t}\n\t\t\t$$ = node;\n\t\t    }\n\t\t;\n\nwords\t\t: tWORDS_BEG ' ' tSTRING_END\n\t\t    {\n\t\t\t$$ = NEW_ZARRAY();\n\t\t    }\n\t\t| tWORDS_BEG word_list tSTRING_END\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nword_list\t: /* none */\n\t\t    {\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| word_list word ' '\n\t\t    {\n\t\t\t$$ = list_append($1, evstr2dstr($2));\n\t\t    }\n\t\t;\n\nword\t\t: string_content\n\t\t| word string_content\n\t\t    {\n\t\t\t$$ = literal_concat($1, $2);\n\t\t    }\n\t\t;\n\nqwords\t\t: tQWORDS_BEG ' ' tSTRING_END\n\t\t    {\n\t\t\t$$ = NEW_ZARRAY();\n\t\t    }\n\t\t| tQWORDS_BEG qword_list tSTRING_END\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nqword_list\t: /* none */\n\t\t    {\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| qword_list tSTRING_CONTENT ' '\n\t\t    {\n\t\t\t$$ = list_append($1, $2);\n\t\t    }\n\t\t;\n\nstring_contents : /* none */\n\t\t    {\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| string_contents string_content\n\t\t    {\n\t\t\t$$ = literal_concat($1, $2);\n\t\t    }\n\t\t;\n\nxstring_contents: /* none */\n\t\t    {\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| xstring_contents string_content\n\t\t    {\n\t\t\t$$ = literal_concat($1, $2);\n\t\t    }\n\t\t;\n\nstring_content\t: tSTRING_CONTENT\n\t\t| tSTRING_DVAR\n\t\t    {\n\t\t\t$<node>$ = lex_strterm;\n\t\t\tlex_strterm = 0;\n\t\t\tlex_state = EXPR_BEG;\n\t\t    }\n\t\t  string_dvar\n\t\t    {\n\t\t\tlex_strterm = $<node>2;\n\t\t        $$ = NEW_EVSTR($3);\n\t\t    }\n\t\t| tSTRING_DBEG\n\t\t    {\n\t\t\t$<node>$ = lex_strterm;\n\t\t\tlex_strterm = 0;\n\t\t\tlex_state = EXPR_BEG;\n\t\t\tCOND_PUSH(0);\n\t\t\tCMDARG_PUSH(0);\n\t\t    }\n\t\t  compstmt '}'\n\t\t    {\n\t\t\tlex_strterm = $<node>2;\n\t\t\tCOND_LEXPOP();\n\t\t\tCMDARG_LEXPOP();\n\t\t\tif (($$ = $3) && nd_type($$) == NODE_NEWLINE) {\n\t\t\t    $$ = $$->nd_next;\n\t\t\t    rb_gc_force_recycle((VALUE)$3);\n\t\t\t}\n\t\t\t$$ = new_evstr($$);\n\t\t    }\n\t\t;\n\nstring_dvar\t: tGVAR {$$ = NEW_GVAR($1);}\n\t\t| tIVAR {$$ = NEW_IVAR($1);}\n\t\t| tCVAR {$$ = NEW_CVAR($1);}\n\t\t| backref\n\t\t;\n\nsymbol\t\t: tSYMBEG sym\n\t\t    {\n\t\t        lex_state = EXPR_END;\n\t\t\t$$ = $2;\n\t\t    }\n\t\t;\n\nsym\t\t: fname\n\t\t| tIVAR\n\t\t| tGVAR\n\t\t| tCVAR\n\t\t;\n\ndsym\t\t: tSYMBEG xstring_contents tSTRING_END\n\t\t    {\n\t\t        lex_state = EXPR_END;\n\t\t\tif (!($$ = $2)) {\n\t\t\t    $$ = NEW_NIL();\n\t\t\t    yyerror(\"empty symbol literal\");\n\t\t\t}\n\t\t\telse {\n\t\t\t    VALUE lit;\n\n\t\t\t    switch (nd_type($$)) {\n\t\t\t      case NODE_DSTR:\n\t\t\t\tnd_set_type($$, NODE_DSYM);\n\t\t\t\tbreak;\n\t\t\t      case NODE_STR:\n\t\t\t\tlit = $$->nd_lit;\n\t\t\t\tif (RSTRING(lit)->len == 0) {\n\t\t\t\t    yyerror(\"empty symbol literal\");\n\t\t\t\t    break;\n\t\t\t\t}\n\t\t\t\tif (strlen(RSTRING(lit)->ptr) == RSTRING(lit)->len) {\n\t\t\t\t    $$->nd_lit = ID2SYM(rb_intern(RSTRING($$->nd_lit)->ptr));\n\t\t\t\t    nd_set_type($$, NODE_LIT);\n\t\t\t\t    break;\n\t\t\t\t}\n\t\t\t\t/* fall through */\n\t\t\t      default:\n\t\t\t\t$$ = NEW_DSYM(rb_str_new(0, 0), NEW_LIST($$));\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t;\n\nnumeric\t\t: tINTEGER\n\t\t| tFLOAT\n\t\t| tUMINUS_NUM tINTEGER\t       %prec tLOWEST\n\t\t    {\n\t\t\t$$ = negate_lit($2);\n\t\t    }\n\t\t| tUMINUS_NUM tFLOAT\t       %prec tLOWEST\n\t\t    {\n\t\t\t$$ = negate_lit($2);\n\t\t    }\n\t\t;\n\nvariable\t: tIDENTIFIER\n\t\t| tIVAR\n\t\t| tGVAR\n\t\t| tCONSTANT\n\t\t| tCVAR\n\t\t| kNIL {$$ = kNIL;}\n\t\t| kSELF {$$ = kSELF;}\n\t\t| kTRUE {$$ = kTRUE;}\n\t\t| kFALSE {$$ = kFALSE;}\n\t\t| k__FILE__ {$$ = k__FILE__;}\n\t\t| k__LINE__ {$$ = k__LINE__;}\n\t\t;\n\nvar_ref\t\t: variable\n\t\t    {\n\t\t\t$$ = gettable($1);\n\t\t    }\n\t\t;\n\nvar_lhs\t\t: variable\n\t\t    {\n\t\t\t$$ = assignable($1, 0);\n\t\t    }\n\t\t;\n\nbackref\t\t: tNTH_REF\n\t\t| tBACK_REF\n\t\t;\n\nsuperclass\t: term\n\t\t    {\n\t\t\t$$ = 0;\n\t\t    }\n\t\t| '<'\n\t\t    {\n\t\t\tlex_state = EXPR_BEG;\n\t\t    }\n\t\t  expr_value term\n\t\t    {\n\t\t\t$$ = $3;\n\t\t    }\n\t\t| error term {yyerrok; $$ = 0;}\n\t\t;\n\nf_arglist\t: '(' f_args opt_nl ')'\n\t\t    {\n\t\t\t$$ = $2;\n\t\t\tlex_state = EXPR_BEG;\n\t\t        command_start = Qtrue;\n\t\t    }\n\t\t| f_args term\n\t\t    {\n\t\t\t$$ = $1;\n\t\t    }\n\t\t;\n\nf_args\t\t: f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS($1, $3, $5), $6);\n\t\t    }\n\t\t| f_arg ',' f_optarg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS($1, $3, 0), $4);\n\t\t    }\n\t\t| f_arg ',' f_rest_arg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS($1, 0, $3), $4);\n\t\t    }\n\t\t| f_arg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS($1, 0, 0), $2);\n\t\t    }\n\t\t| f_optarg ',' f_rest_arg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS(0, $1, $3), $4);\n\t\t    }\n\t\t| f_optarg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS(0, $1, 0), $2);\n\t\t    }\n\t\t| f_rest_arg opt_f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS(0, 0, $1), $2);\n\t\t    }\n\t\t| f_block_arg\n\t\t    {\n\t\t\t$$ = block_append(NEW_ARGS(0, 0, 0), $1);\n\t\t    }\n\t\t| /* none */\n\t\t    {\n\t\t\t$$ = NEW_ARGS(0, 0, 0);\n\t\t    }\n\t\t;\n\nf_norm_arg\t: tCONSTANT\n\t\t    {\n\t\t\tyyerror(\"formal argument cannot be a constant\");\n\t\t    }\n                | tIVAR\n\t\t    {\n                        yyerror(\"formal argument cannot be an instance variable\");\n\t\t    }\n                | tGVAR\n\t\t    {\n                        yyerror(\"formal argument cannot be a global variable\");\n\t\t    }\n                | tCVAR\n\t\t    {\n                        yyerror(\"formal argument cannot be a class variable\");\n\t\t    }\n\t\t| tIDENTIFIER\n\t\t    {\n\t\t\tif (!is_local_id($1))\n\t\t\t    yyerror(\"formal argument must be local variable\");\n\t\t\telse if (local_id($1))\n\t\t\t    yyerror(\"duplicate argument name\");\n\t\t\tlocal_cnt($1);\n\t\t\t$$ = 1;\n\t\t    }\n\t\t;\n\nf_arg\t\t: f_norm_arg\n\t\t| f_arg ',' f_norm_arg\n\t\t    {\n\t\t\t$$ += 1;\n\t\t    }\n\t\t;\n\nf_opt\t\t: tIDENTIFIER '=' arg_value\n\t\t    {\n\t\t\tif (!is_local_id($1))\n\t\t\t    yyerror(\"formal argument must be local variable\");\n\t\t\telse if (local_id($1))\n\t\t\t    yyerror(\"duplicate optional argument name\");\n\t\t\t$$ = assignable($1, $3);\n\t\t    }\n\t\t;\n\nf_optarg\t: f_opt\n\t\t    {\n\t\t\t$$ = NEW_BLOCK($1);\n\t\t\t$$->nd_end = $$;\n\t\t    }\n\t\t| f_optarg ',' f_opt\n\t\t    {\n\t\t\t$$ = block_append($1, $3);\n\t\t    }\n\t\t;\n\nrestarg_mark\t: '*'\n\t\t| tSTAR\n\t\t;\n\nf_rest_arg\t: restarg_mark tIDENTIFIER\n\t\t    {\n\t\t\tif (!is_local_id($2))\n\t\t\t    yyerror(\"rest argument must be local variable\");\n\t\t\telse if (local_id($2))\n\t\t\t    yyerror(\"duplicate rest argument name\");\n\t\t\tif (dyna_in_block()) {\n\t\t\t    rb_dvar_push($2, Qnil);\n\t\t\t}\n\t\t\t$$ = assignable($2, 0);\n\t\t    }\n\t\t| restarg_mark\n\t\t    {\n\t\t\tif (dyna_in_block()) {\n\t\t\t    $$ = NEW_DASGN_CURR(internal_id(), 0);\n\t\t\t}\n\t\t\telse {\n\t\t\t    $$ = NEW_NODE(NODE_LASGN,0,0,local_append(0));\n\t\t\t}\n\t\t    }\n\t\t;\n\nblkarg_mark\t: '&'\n\t\t| tAMPER\n\t\t;\n\nf_block_arg\t: blkarg_mark tIDENTIFIER\n\t\t    {\n\t\t\tif (!is_local_id($2))\n\t\t\t    yyerror(\"block argument must be local variable\");\n\t\t\telse if (local_id($2))\n\t\t\t    yyerror(\"duplicate block argument name\");\n\t\t\t$$ = NEW_BLOCK_ARG($2);\n\t\t    }\n\t\t;\n\nopt_f_block_arg\t: ',' f_block_arg\n\t\t    {\n\t\t\t$$ = $2;\n\t\t    }\n\t\t| none\n\t\t;\n\nsingleton\t: var_ref\n\t\t    {\n\t\t\t$$ = $1;\n\t\t\tvalue_expr($$);\n\t\t    }\n\t\t| '(' {lex_state = EXPR_BEG;} expr opt_nl ')'\n\t\t    {\n\t\t\tif ($3 == 0) {\n\t\t\t    yyerror(\"can't define singleton method for ().\");\n\t\t\t}\n\t\t\telse {\n\t\t\t    switch (nd_type($3)) {\n\t\t\t      case NODE_STR:\n\t\t\t      case NODE_DSTR:\n\t\t\t      case NODE_XSTR:\n\t\t\t      case NODE_DXSTR:\n\t\t\t      case NODE_DREGX:\n\t\t\t      case NODE_LIT:\n\t\t\t      case NODE_ARRAY:\n\t\t\t      case NODE_ZARRAY:\n\t\t\t\tyyerror(\"can't define singleton method for literals\");\n\t\t\t      default:\n\t\t\t\tvalue_expr($3);\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t\t$$ = $3;\n\t\t    }\n\t\t;\n\nassoc_list\t: none\n\t\t| assocs trailer\n\t\t    {\n\t\t\t$$ = $1;\n\t\t    }\n\t\t| args trailer\n\t\t    {\n\t\t\tif ($1->nd_alen%2 != 0) {\n\t\t\t    yyerror(\"odd number list for Hash\");\n\t\t\t}\n\t\t\t$$ = $1;\n\t\t    }\n\t\t;\n\nassocs\t\t: assoc\n\t\t| assocs ',' assoc\n\t\t    {\n\t\t\t$$ = list_concat($1, $3);\n\t\t    }\n\t\t;\n\nassoc\t\t: arg_value tASSOC arg_value\n\t\t    {\n\t\t\t$$ = list_append(NEW_LIST($1), $3);\n\t\t    }\n\t\t;\n\noperation\t: tIDENTIFIER\n\t\t| tCONSTANT\n\t\t| tFID\n\t\t;\n\noperation2\t: tIDENTIFIER\n\t\t| tCONSTANT\n\t\t| tFID\n\t\t| op\n\t\t;\n\noperation3\t: tIDENTIFIER\n\t\t| tFID\n\t\t| op\n\t\t;\n\ndot_or_colon\t: '.'\n\t\t| tCOLON2\n\t\t;\n\nopt_terms\t: /* none */\n\t\t| terms\n\t\t;\n\nopt_nl\t\t: /* none */\n\t\t| '\\n'\n\t\t;\n\ntrailer\t\t: /* none */\n\t\t| '\\n'\n\t\t| ','\n\t\t;\n\nterm\t\t: ';' {yyerrok;}\n\t\t| '\\n'\n\t\t;\n\nterms\t\t: term\n\t\t| terms ';' {yyerrok;}\n\t\t;\n\nnone\t\t: /* none */ {$$ = 0;}\n\t\t;\n%%\n#ifdef yystacksize\n#undef YYMALLOC\n#endif\n\n#include \"regex.h\"\n#include \"util.h\"\n\n/* We remove any previous definition of `SIGN_EXTEND_CHAR',\n   since ours (we hope) works properly with all combinations of\n   machines, compilers, `char' and `unsigned char' argument types.\n   (Per Bothner suggested the basic approach.)  */\n#undef SIGN_EXTEND_CHAR\n#if __STDC__\n# define SIGN_EXTEND_CHAR(c) ((signed char)(c))\n#else  /* not __STDC__ */\n/* As in Harbison and Steele.  */\n# define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)\n#endif\n#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_' || ismbchar(c)))\n\nstatic char *tokenbuf = NULL;\nstatic int   tokidx, toksiz = 0;\n\n#define LEAVE_BS 1\n\nstatic VALUE (*lex_gets)();\t/* gets function */\nstatic VALUE lex_input;\t\t/* non-nil if File */\nstatic VALUE lex_lastline;\t/* gc protect */\nstatic char *lex_pbeg;\nstatic char *lex_p;\nstatic char *lex_pend;\n\nstatic int\nyyerror(msg)\n    const char *msg;\n{\n    const int max_line_margin = 30;\n    const char *p, *pe;\n    char *buf;\n    int len, i;\n\n    rb_compile_error(\"%s\", msg);\n    p = lex_p;\n    while (lex_pbeg <= p) {\n\tif (*p == '\\n') break;\n\tp--;\n    }\n    p++;\n\n    pe = lex_p;\n    while (pe < lex_pend) {\n\tif (*pe == '\\n') break;\n\tpe++;\n    }\n\n    len = pe - p;\n    if (len > 4) {\n\tchar *p2;\n\tconst char *pre = \"\", *post = \"\";\n\n\tif (len > max_line_margin * 2 + 10) {\n\t    int re_mbc_startpos _((const char *, int, int, int));\n\t    if ((len = lex_p - p) > max_line_margin) {\n\t\tp = p + re_mbc_startpos(p, len, len - max_line_margin, 0);\n\t\tpre = \"...\";\n\t    }\n\t    if ((len = pe - lex_p) > max_line_margin) {\n\t\tpe = lex_p + re_mbc_startpos(lex_p, len, max_line_margin, 1);\n\t\tpost = \"...\";\n\t    }\n\t    len = pe - p;\n\t}\n\tbuf = ALLOCA_N(char, len+2);\n\tMEMCPY(buf, p, char, len);\n\tbuf[len] = '\\0';\n\trb_compile_error_append(\"%s%s%s\", pre, buf, post);\n\n\ti = lex_p - p;\n\tp2 = buf; pe = buf + len;\n\n\twhile (p2 < pe) {\n\t    if (*p2 != '\\t') *p2 = ' ';\n\t    p2++;\n\t}\n\tbuf[i] = '^';\n\tbuf[i+1] = '\\0';\n\trb_compile_error_append(\"%s\", buf);\n    }\n\n    return 0;\n}\n\nstatic int heredoc_end;\n\nint ruby_in_compile = 0;\nint ruby__end__seen;\n\nstatic VALUE ruby_debug_lines;\n#ifdef YYMALLOC\nstatic NODE *parser_heap;\n#endif\n\nstatic NODE*\nyycompile(f, line)\n    char *f;\n    int line;\n{\n    int n;\n    NODE *node = 0;\n    struct RVarmap *vp, *vars = ruby_dyna_vars;\n\n    ruby_in_compile = 1;\n    ruby_in_longlife_context++;\n    if (!compile_for_eval && rb_safe_level() == 0 &&\n\trb_const_defined(rb_cObject, rb_intern(\"SCRIPT_LINES__\"))) {\n\tVALUE hash, fname;\n\n\thash = rb_const_get(rb_cObject, rb_intern(\"SCRIPT_LINES__\"));\n\tif (TYPE(hash) == T_HASH) {\n\t    fname = rb_str_new2(f);\n\t    ruby_debug_lines = rb_ary_new();\n\t    rb_hash_aset(hash, fname, ruby_debug_lines);\n\t}\n\tif (line > 1) {\n\t    VALUE str = rb_str_new(0,0);\n\t    while (line > 1) {\n\t\trb_ary_push(ruby_debug_lines, str);\n\t\tline--;\n\t    }\n\t}\n    }\n\n    ruby__end__seen = 0;\n    ruby_eval_tree = 0;\n    ruby_eval_tree_begin = 0;\n    heredoc_end = 0;\n    lex_strterm = 0;\n    ruby_current_node = 0;\n    ruby_sourcefile = rb_source_filename(f);\n    deferred_nodes = 0;\n    n = yyparse();\n    ruby_debug_lines = 0;\n    compile_for_eval = 0;\n    ruby_in_compile = 0;\n    ruby_in_longlife_context--;\n    cond_stack = 0;\n    cmdarg_stack = 0;\n    command_start = 1;\n    class_nest = 0;\n    in_single = 0;\n    in_def = 0;\n    cur_mid = 0;\n    deferred_nodes = 0;\n\n    vp = ruby_dyna_vars;\n    ruby_dyna_vars = vars;\n    lex_strterm = 0;\n    while (vp && vp != vars) {\n\tstruct RVarmap *tmp = vp;\n\tvp = vp->next;\n\trb_gc_force_recycle((VALUE)tmp);\n    }\n    if (n == 0) node = ruby_eval_tree;\n    if (ruby_nerrs) ruby_eval_tree_begin = 0;\n    return node;\n}\n\nstatic int lex_gets_ptr;\n\nstatic VALUE\nlex_get_str(s)\n    VALUE s;\n{\n    char *beg, *end, *pend;\n\n    beg = RSTRING(s)->ptr;\n    if (lex_gets_ptr) {\n\tif (RSTRING(s)->len == lex_gets_ptr) return Qnil;\n\tbeg += lex_gets_ptr;\n    }\n    pend = RSTRING(s)->ptr + RSTRING(s)->len;\n    end = beg;\n    while (end < pend) {\n\tif (*end++ == '\\n') break;\n    }\n    lex_gets_ptr = end - RSTRING(s)->ptr;\n    return rb_str_new(beg, end - beg);\n}\n\nstatic VALUE\nlex_getline()\n{\n    VALUE line = (*lex_gets)(lex_input);\n    if (ruby_debug_lines && !NIL_P(line)) {\n\trb_ary_push(ruby_debug_lines, line);\n    }\n    return line;\n}\n\nNODE*\nrb_compile_string(f, s, line)\n    const char *f;\n    VALUE s;\n    int line;\n{\n    lex_gets = lex_get_str;\n    lex_gets_ptr = 0;\n    lex_input = s;\n    lex_pbeg = lex_p = lex_pend = 0;\n    ruby_sourceline = line - 1;\n    compile_for_eval = ruby_in_eval;\n\n    return yycompile(f, line);\n}\n\nNODE*\nrb_compile_cstr(f, s, len, line)\n    const char *f, *s;\n    int len, line;\n{\n    return rb_compile_string(f, rb_str_new(s, len), line);\n}\n\nNODE*\nrb_compile_file(f, file, start)\n    const char *f;\n    VALUE file;\n    int start;\n{\n    lex_gets = rb_io_gets;\n    lex_input = file;\n    lex_pbeg = lex_p = lex_pend = 0;\n    ruby_sourceline = start - 1;\n\n    return yycompile(f, start);\n}\n\nstatic inline int\nnextc()\n{\n    int c;\n\n    if (lex_p == lex_pend) {\n\tif (lex_input) {\n\t    VALUE v = lex_getline();\n\n\t    if (NIL_P(v)) return -1;\n\t    if (heredoc_end > 0) {\n\t\truby_sourceline = heredoc_end;\n\t\theredoc_end = 0;\n\t    }\n\t    ruby_sourceline++;\n\t    lex_pbeg = lex_p = RSTRING(v)->ptr;\n\t    lex_pend = lex_p + RSTRING(v)->len;\n\t    lex_lastline = v;\n\t}\n\telse {\n\t    lex_lastline = 0;\n\t    return -1;\n\t}\n    }\n    c = (unsigned char)*lex_p++;\n    if (c == '\\r' && lex_p < lex_pend && *lex_p == '\\n') {\n\tlex_p++;\n\tc = '\\n';\n    }\n\n    return c;\n}\n\nstatic void\npushback(c)\n    int c;\n{\n    if (c == -1) return;\n    lex_p--;\n}\n\n#define was_bol() (lex_p == lex_pbeg + 1)\n#define peek(c) (lex_p != lex_pend && (c) == *lex_p)\n\n#define tokfix() (tokenbuf[tokidx]='\\0')\n#define tok() tokenbuf\n#define toklen() tokidx\n#define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)\n\nstatic char*\nnewtok()\n{\n    tokidx = 0;\n    if (!tokenbuf) {\n\ttoksiz = 60;\n\ttokenbuf = ALLOC_N(char, 60);\n    }\n    if (toksiz > 4096) {\n\ttoksiz = 60;\n\tREALLOC_N(tokenbuf, char, 60);\n    }\n    return tokenbuf;\n}\n\nstatic void\ntokadd(c)\n    char c;\n{\n    tokenbuf[tokidx++] = c;\n    if (tokidx >= toksiz) {\n\ttoksiz *= 2;\n\tREALLOC_N(tokenbuf, char, toksiz);\n    }\n}\n\nstatic int\nread_escape()\n{\n    int c;\n\n    switch (c = nextc()) {\n      case '\\\\':\t/* Backslash */\n\treturn c;\n\n      case 'n':\t/* newline */\n\treturn '\\n';\n\n      case 't':\t/* horizontal tab */\n\treturn '\\t';\n\n      case 'r':\t/* carriage-return */\n\treturn '\\r';\n\n      case 'f':\t/* form-feed */\n\treturn '\\f';\n\n      case 'v':\t/* vertical tab */\n\treturn '\\13';\n\n      case 'a':\t/* alarm(bell) */\n\treturn '\\007';\n\n      case 'e':\t/* escape */\n\treturn 033;\n\n      case '0': case '1': case '2': case '3': /* octal constant */\n      case '4': case '5': case '6': case '7':\n\t{\n\t    int numlen;\n\n\t    pushback(c);\n\t    c = scan_oct(lex_p, 3, &numlen);\n\t    lex_p += numlen;\n\t}\n\treturn c;\n\n      case 'x':\t/* hex constant */\n\t{\n\t    int numlen;\n\n\t    c = scan_hex(lex_p, 2, &numlen);\n\t    if (numlen == 0) {\n\t\tyyerror(\"Invalid escape character syntax\");\n\t\treturn 0;\n\t    }\n\t    lex_p += numlen;\n\t}\n\treturn c;\n\n      case 'b':\t/* backspace */\n\treturn '\\010';\n\n      case 's':\t/* space */\n\treturn ' ';\n\n      case 'M':\n\tif ((c = nextc()) != '-') {\n\t    yyerror(\"Invalid escape character syntax\");\n\t    pushback(c);\n\t    return '\\0';\n\t}\n\tif ((c = nextc()) == '\\\\') {\n\t    return read_escape() | 0x80;\n\t}\n\telse if (c == -1) goto eof;\n\telse {\n\t    return ((c & 0xff) | 0x80);\n\t}\n\n      case 'C':\n\tif ((c = nextc()) != '-') {\n\t    yyerror(\"Invalid escape character syntax\");\n\t    pushback(c);\n\t    return '\\0';\n\t}\n      case 'c':\n\tif ((c = nextc())== '\\\\') {\n\t    c = read_escape();\n\t}\n\telse if (c == '?')\n\t    return 0177;\n\telse if (c == -1) goto eof;\n\treturn c & 0x9f;\n\n      eof:\n      case -1:\n        yyerror(\"Invalid escape character syntax\");\n\treturn '\\0';\n\n      default:\n\treturn c;\n    }\n}\n\nstatic int\ntokadd_escape()\n{\n    int c;\n\n    switch (c = nextc()) {\n      case '\\n':\n\treturn 0;\t\t/* just ignore */\n\n      case '0': case '1': case '2': case '3': /* octal constant */\n      case '4': case '5': case '6': case '7':\n\t{\n\t    int i;\n\n\t    tokadd('\\\\');\n\t    tokadd(c);\n\t    for (i=0; i<2; i++) {\n\t\tc = nextc();\n\t\tif (c == -1) goto eof;\n\t\tif (c < '0' || '7' < c) {\n\t\t    pushback(c);\n\t\t    break;\n\t\t}\n\t\ttokadd(c);\n\t    }\n\t}\n\treturn 0;\n\n      case 'x':\t/* hex constant */\n\t{\n\t    int numlen;\n\n\t    tokadd('\\\\');\n\t    tokadd(c);\n\t    scan_hex(lex_p, 2, &numlen);\n\t    if (numlen == 0) {\n\t\tyyerror(\"Invalid escape character syntax\");\n\t\treturn -1;\n\t    }\n\t    while (numlen--)\n\t\ttokadd(nextc());\n\t}\n\treturn 0;\n\n      case 'M':\n\tif ((c = nextc()) != '-') {\n\t    yyerror(\"Invalid escape character syntax\");\n\t    pushback(c);\n\t    return 0;\n\t}\n\ttokadd('\\\\'); tokadd('M'); tokadd('-');\n\tgoto escaped;\n\n      case 'C':\n\tif ((c = nextc()) != '-') {\n\t    yyerror(\"Invalid escape character syntax\");\n\t    pushback(c);\n\t    return 0;\n\t}\n\ttokadd('\\\\'); tokadd('C'); tokadd('-');\n\tgoto escaped;\n\n      case 'c':\n\ttokadd('\\\\'); tokadd('c');\n      escaped:\n\tif ((c = nextc()) == '\\\\') {\n\t    return tokadd_escape();\n\t}\n\telse if (c == -1) goto eof;\n\ttokadd(c);\n\treturn 0;\n\n      eof:\n      case -1:\n        yyerror(\"Invalid escape character syntax\");\n\treturn -1;\n\n      default:\n        tokadd('\\\\');\n\ttokadd(c);\n    }\n    return 0;\n}\n\nstatic int\nregx_options()\n{\n    char kcode = 0;\n    int options = 0;\n    int c;\n\n    newtok();\n    while (c = nextc(), ISALPHA(c)) {\n\tswitch (c) {\n\t  case 'i':\n\t    options |= RE_OPTION_IGNORECASE;\n\t    break;\n\t  case 'x':\n\t    options |= RE_OPTION_EXTENDED;\n\t    break;\n\t  case 'm':\n\t    options |= RE_OPTION_MULTILINE;\n\t    break;\n\t  case 'o':\n\t    options |= RE_OPTION_ONCE;\n\t    break;\n\t  case 'n':\n\t    kcode = 16;\n\t    break;\n\t  case 'e':\n\t    kcode = 32;\n\t    break;\n\t  case 's':\n\t    kcode = 48;\n\t    break;\n\t  case 'u':\n\t    kcode = 64;\n\t    break;\n\t  default:\n\t    tokadd(c);\n\t    break;\n\t}\n    }\n    pushback(c);\n    if (toklen()) {\n\ttokfix();\n\trb_compile_error(\"unknown regexp option%s - %s\",\n\t\t\t toklen() > 1 ? \"s\" : \"\", tok());\n    }\n    return options | kcode;\n}\n\n#define STR_FUNC_ESCAPE 0x01\n#define STR_FUNC_EXPAND 0x02\n#define STR_FUNC_REGEXP 0x04\n#define STR_FUNC_QWORDS 0x08\n#define STR_FUNC_SYMBOL 0x10\n#define STR_FUNC_INDENT 0x20\n\nenum string_type {\n    str_squote = (0),\n    str_dquote = (STR_FUNC_EXPAND),\n    str_xquote = (STR_FUNC_EXPAND),\n    str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),\n    str_sword  = (STR_FUNC_QWORDS),\n    str_dword  = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),\n    str_ssym   = (STR_FUNC_SYMBOL),\n    str_dsym   = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND),\n};\n\nstatic void\ndispose_string(str)\n    VALUE str;\n{\n    xfree(RSTRING(str)->ptr);\n    rb_gc_force_recycle(str);\n}\n\nstatic int\ntokadd_string(func, term, paren, nest)\n    int func, term, paren, *nest;\n{\n    int c;\n\n    while ((c = nextc()) != -1) {\n\tif (paren && c == paren) {\n\t    ++*nest;\n\t}\n\telse if (c == term) {\n\t    if (!nest || !*nest) {\n\t\tpushback(c);\n\t\tbreak;\n\t    }\n\t    --*nest;\n\t}\n\telse if ((func & STR_FUNC_EXPAND) && c == '#' && lex_p < lex_pend) {\n\t    int c2 = *lex_p;\n\t    if (c2 == '$' || c2 == '@' || c2 == '{') {\n\t\tpushback(c);\n\t\tbreak;\n\t    }\n\t}\n\telse if (c == '\\\\') {\n\t    c = nextc();\n\t    switch (c) {\n\t      case '\\n':\n\t\tif (func & STR_FUNC_QWORDS) break;\n\t\tif (func & STR_FUNC_EXPAND) continue;\n\t\ttokadd('\\\\');\n\t\tbreak;\n\n\t      case '\\\\':\n\t\tif (func & STR_FUNC_ESCAPE) tokadd(c);\n\t\tbreak;\n\n\t      default:\n\t\tif (func & STR_FUNC_REGEXP) {\n\t\t    pushback(c);\n\t\t    if (tokadd_escape() < 0)\n\t\t\treturn -1;\n\t\t    continue;\n\t\t}\n\t\telse if (func & STR_FUNC_EXPAND) {\n\t\t    pushback(c);\n\t\t    if (func & STR_FUNC_ESCAPE) tokadd('\\\\');\n\t\t    c = read_escape();\n\t\t}\n\t\telse if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {\n\t\t    /* ignore backslashed spaces in %w */\n\t\t}\n\t\telse if (c != term && !(paren && c == paren)) {\n\t\t    tokadd('\\\\');\n\t\t}\n\t    }\n\t}\n\telse if (ismbchar(c)) {\n\t    int i, len = mbclen(c)-1;\n\n\t    for (i = 0; i < len; i++) {\n\t\ttokadd(c);\n\t\tc = nextc();\n\t    }\n\t}\n\telse if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {\n\t    pushback(c);\n\t    break;\n\t}\n\tif (!c && (func & STR_FUNC_SYMBOL)) {\n\t    func &= ~STR_FUNC_SYMBOL;\n\t    rb_compile_error(\"symbol cannot contain '\\\\0'\");\n\t    continue;\n\t}\n\ttokadd(c);\n    }\n    return c;\n}\n\n#define NEW_STRTERM(func, term, paren) \\\n\tNEW_NODE(NODE_STRTERM, (func), (term) | ((paren) << (CHAR_BIT * 2)), 0)\n\nstatic int\nparse_string(quote)\n    NODE *quote;\n{\n    int func = quote->nd_func;\n    int term = nd_term(quote);\n    int paren = nd_paren(quote);\n    int c, space = 0;\n\n    if (func == -1) return tSTRING_END;\n    c = nextc();\n    if ((func & STR_FUNC_QWORDS) && ISSPACE(c)) {\n\tdo {c = nextc();} while (ISSPACE(c));\n\tspace = 1;\n    }\n    if (c == term && !quote->nd_nest) {\n\tif (func & STR_FUNC_QWORDS) {\n\t    quote->nd_func = -1;\n\t    return ' ';\n\t}\n\tif (!(func & STR_FUNC_REGEXP)) return tSTRING_END;\n\tyylval.num = regx_options();\n\treturn tREGEXP_END;\n    }\n    if (space) {\n\tpushback(c);\n\treturn ' ';\n    }\n    newtok();\n    if ((func & STR_FUNC_EXPAND) && c == '#') {\n\tswitch (c = nextc()) {\n\t  case '$':\n\t  case '@':\n\t    pushback(c);\n\t    return tSTRING_DVAR;\n\t  case '{':\n\t    return tSTRING_DBEG;\n\t}\n\ttokadd('#');\n    }\n    pushback(c);\n    if (tokadd_string(func, term, paren, &quote->nd_nest) == -1) {\n\truby_sourceline = nd_line(quote);\n\trb_compile_error(\"unterminated string meets end of file\");\n\treturn tSTRING_END;\n    }\n\n    tokfix();\n    yylval.node = NEW_STR(rb_str_new(tok(), toklen()));\n    return tSTRING_CONTENT;\n}\n\nstatic int\nheredoc_identifier()\n{\n    int c = nextc(), term, func = 0, len;\n\n    if (c == '-') {\n\tc = nextc();\n\tfunc = STR_FUNC_INDENT;\n    }\n    switch (c) {\n      case '\\'':\n\tfunc |= str_squote; goto quoted;\n      case '\"':\n\tfunc |= str_dquote; goto quoted;\n      case '`':\n\tfunc |= str_xquote;\n      quoted:\n\tnewtok();\n\ttokadd(func);\n\tterm = c;\n\twhile ((c = nextc()) != -1 && c != term) {\n\t    len = mbclen(c);\n\t    do {tokadd(c);} while (--len > 0 && (c = nextc()) != -1);\n\t}\n\tif (c == -1) {\n\t    rb_compile_error(\"unterminated here document identifier\");\n\t    return 0;\n\t}\n\tbreak;\n\n      default:\n\tif (!is_identchar(c)) {\n\t    pushback(c);\n\t    if (func & STR_FUNC_INDENT) {\n\t\tpushback('-');\n\t    }\n\t    return 0;\n\t}\n\tnewtok();\n\tterm = '\"';\n\ttokadd(func |= str_dquote);\n\tdo {\n\t    len = mbclen(c);\n\t    do {tokadd(c);} while (--len > 0 && (c = nextc()) != -1);\n\t} while ((c = nextc()) != -1 && is_identchar(c));\n\tpushback(c);\n\tbreak;\n    }\n\n    tokfix();\n    len = lex_p - lex_pbeg;\n    lex_p = lex_pend;\n    lex_strterm = NEW_NODE(NODE_HEREDOC,\n\t\t\t\t  rb_str_new(tok(), toklen()),\t/* nd_lit */\n\t\t\t\t  len,\t\t\t\t/* nd_nth */\n\t\t\t\t  lex_lastline);\t\t/* nd_orig */\n    return term == '`' ? tXSTRING_BEG : tSTRING_BEG;\n}\n\nstatic void\nheredoc_restore(here)\n    NODE *here;\n{\n    VALUE line = here->nd_orig;\n    lex_lastline = line;\n    lex_pbeg = RSTRING(line)->ptr;\n    lex_pend = lex_pbeg + RSTRING(line)->len;\n    lex_p = lex_pbeg + here->nd_nth;\n    heredoc_end = ruby_sourceline;\n    ruby_sourceline = nd_line(here);\n    dispose_string(here->nd_lit);\n    rb_gc_force_recycle((VALUE)here);\n}\n\nstatic int\nwhole_match_p(eos, len, indent)\n    char *eos;\n    int len, indent;\n{\n    char *p = lex_pbeg;\n    int n;\n\n    if (indent) {\n\twhile (*p && ISSPACE(*p)) p++;\n    }\n    n= lex_pend - (p + len);\n    if (n < 0 || (n > 0 && p[len] != '\\n' && p[len] != '\\r')) return Qfalse;\n    if (strncmp(eos, p, len) == 0) return Qtrue;\n    return Qfalse;\n}\n\nstatic int\nhere_document(here)\n    NODE *here;\n{\n    int c, func, indent = 0;\n    char *eos, *p, *pend;\n    long len;\n    VALUE str = 0;\n\n    eos = RSTRING(here->nd_lit)->ptr;\n    len = RSTRING(here->nd_lit)->len - 1;\n    indent = (func = *eos++) & STR_FUNC_INDENT;\n\n    if ((c = nextc()) == -1) {\n      error:\n\trb_compile_error(\"can't find string \\\"%s\\\" anywhere before EOF\", eos);\n\theredoc_restore(lex_strterm);\n\tlex_strterm = 0;\n\treturn 0;\n    }\n    if (was_bol() && whole_match_p(eos, len, indent)) {\n\theredoc_restore(lex_strterm);\n\treturn tSTRING_END;\n    }\n\n    if (!(func & STR_FUNC_EXPAND)) {\n\tdo {\n\t    p = RSTRING(lex_lastline)->ptr;\n\t    pend = lex_pend;\n\t    if (pend > p) {\n\t\tswitch (pend[-1]) {\n\t\t  case '\\n':\n\t\t    if (--pend == p || pend[-1] != '\\r') {\n\t\t\tpend++;\n\t\t\tbreak;\n\t\t    }\n\t\t  case '\\r':\n\t\t    --pend;\n\t\t}\n\t    }\n\t    if (str)\n\t\trb_str_cat(str, p, pend - p);\n\t    else\n\t\tstr = rb_str_new(p, pend - p);\n\t    if (pend < lex_pend) rb_str_cat(str, \"\\n\", 1);\n\t    lex_p = lex_pend;\n\t    if (nextc() == -1) {\n\t\tif (str) dispose_string(str);\n\t\tgoto error;\n\t    }\n\t} while (!whole_match_p(eos, len, indent));\n    }\n    else {\n\tnewtok();\n\tif (c == '#') {\n\t    switch (c = nextc()) {\n\t      case '$':\n\t      case '@':\n\t\tpushback(c);\n\t\treturn tSTRING_DVAR;\n\t      case '{':\n\t\treturn tSTRING_DBEG;\n\t    }\n\t    tokadd('#');\n\t}\n\tdo {\n\t    pushback(c);\n\t    if ((c = tokadd_string(func, '\\n', 0, NULL)) == -1) goto error;\n\t    if (c != '\\n') {\n\t\tyylval.node = NEW_STR(rb_str_new(tok(), toklen()));\n\t\treturn tSTRING_CONTENT;\n\t    }\n\t    tokadd(nextc());\n\t    if ((c = nextc()) == -1) goto error;\n\t} while (!whole_match_p(eos, len, indent));\n\tstr = rb_str_new(tok(), toklen());\n    }\n    heredoc_restore(lex_strterm);\n    lex_strterm = NEW_STRTERM(-1, 0, 0);\n    yylval.node = NEW_STR(str);\n    return tSTRING_CONTENT;\n}\n\n#include \"lex.c\"\n\nstatic void\narg_ambiguous()\n{\n    rb_warning(\"ambiguous first argument; put parentheses or even spaces\");\n}\n\n#define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)\n#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_CLASS)\n\nstatic int\nyylex()\n{\n    register int c;\n    int space_seen = 0;\n    int cmd_state;\n    enum lex_state last_state;\n\n    if (lex_strterm) {\n\tint token;\n\tif (nd_type(lex_strterm) == NODE_HEREDOC) {\n\t    token = here_document(lex_strterm);\n\t    if (token == tSTRING_END) {\n\t\tlex_strterm = 0;\n\t\tlex_state = EXPR_END;\n\t    }\n\t}\n\telse {\n\t    token = parse_string(lex_strterm);\n\t    if (token == tSTRING_END || token == tREGEXP_END) {\n\t\trb_gc_force_recycle((VALUE)lex_strterm);\n\t\tlex_strterm = 0;\n\t\tlex_state = EXPR_END;\n\t    }\n\t}\n\treturn token;\n    }\n    cmd_state = command_start;\n    command_start = Qfalse;\n  retry:\n    switch (c = nextc()) {\n      case '\\0':\t\t/* NUL */\n      case '\\004':\t\t/* ^D */\n      case '\\032':\t\t/* ^Z */\n      case -1:\t\t\t/* end of script. */\n\treturn 0;\n\n\t/* white spaces */\n      case ' ': case '\\t': case '\\f': case '\\r':\n      case '\\13': /* '\\v' */\n\tspace_seen++;\n\tgoto retry;\n\n      case '#':\t\t/* it's a comment */\n\twhile ((c = nextc()) != '\\n') {\n\t    if (c == -1)\n\t\treturn 0;\n\t}\n\t/* fall through */\n      case '\\n':\n\tswitch (lex_state) {\n\t  case EXPR_BEG:\n\t  case EXPR_FNAME:\n\t  case EXPR_DOT:\n\t  case EXPR_CLASS:\n\t    goto retry;\n\t  default:\n\t    break;\n\t}\n\tcommand_start = Qtrue;\n\tlex_state = EXPR_BEG;\n\treturn '\\n';\n\n      case '*':\n\tif ((c = nextc()) == '*') {\n\t    if ((c = nextc()) == '=') {\n\t\tyylval.id = tPOW;\n\t\tlex_state = EXPR_BEG;\n\t\treturn tOP_ASGN;\n\t    }\n\t    pushback(c);\n\t    c = tPOW;\n\t}\n\telse {\n\t    if (c == '=') {\n\t\tyylval.id = '*';\n\t\tlex_state = EXPR_BEG;\n\t\treturn tOP_ASGN;\n\t    }\n\t    pushback(c);\n\t    if (IS_ARG() && space_seen && !ISSPACE(c)){\n\t\trb_warning(\"`*' interpreted as argument prefix\");\n\t\tc = tSTAR;\n\t    }\n\t    else if (IS_BEG()) {\n\t\tc = tSTAR;\n\t    }\n\t    else {\n\t\tc = '*';\n\t    }\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\treturn c;\n\n      case '!':\n\tlex_state = EXPR_BEG;\n\tif ((c = nextc()) == '=') {\n\t    return tNEQ;\n\t}\n\tif (c == '~') {\n\t    return tNMATCH;\n\t}\n\tpushback(c);\n\treturn '!';\n\n      case '=':\n\tif (was_bol()) {\n\t    /* skip embedded rd document */\n\t    if (strncmp(lex_p, \"begin\", 5) == 0 && ISSPACE(lex_p[5])) {\n\t\tfor (;;) {\n\t\t    lex_p = lex_pend;\n\t\t    c = nextc();\n\t\t    if (c == -1) {\n\t\t\trb_compile_error(\"embedded document meets end of file\");\n\t\t\treturn 0;\n\t\t    }\n\t\t    if (c != '=') continue;\n\t\t    if (strncmp(lex_p, \"end\", 3) == 0 &&\n\t\t\t(lex_p + 3 == lex_pend || ISSPACE(lex_p[3]))) {\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\t\tlex_p = lex_pend;\n\t\tgoto retry;\n\t    }\n\t}\n\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\tif ((c = nextc()) == '=') {\n\t    if ((c = nextc()) == '=') {\n\t\treturn tEQQ;\n\t    }\n\t    pushback(c);\n\t    return tEQ;\n\t}\n\tif (c == '~') {\n\t    return tMATCH;\n\t}\n\telse if (c == '>') {\n\t    return tASSOC;\n\t}\n\tpushback(c);\n\treturn '=';\n\n      case '<':\n\tc = nextc();\n\tif (c == '<' &&\n\t    lex_state != EXPR_END &&\n\t    lex_state != EXPR_DOT &&\n\t    lex_state != EXPR_ENDARG &&\n\t    lex_state != EXPR_CLASS &&\n\t    (!IS_ARG() || space_seen)) {\n\t    int token = heredoc_identifier();\n\t    if (token) return token;\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\tif (c == '=') {\n\t    if ((c = nextc()) == '>') {\n\t\treturn tCMP;\n\t    }\n\t    pushback(c);\n\t    return tLEQ;\n\t}\n\tif (c == '<') {\n\t    if ((c = nextc()) == '=') {\n\t\tyylval.id = tLSHFT;\n\t\tlex_state = EXPR_BEG;\n\t\treturn tOP_ASGN;\n\t    }\n\t    pushback(c);\n\t    return tLSHFT;\n\t}\n\tpushback(c);\n\treturn '<';\n\n      case '>':\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\tif ((c = nextc()) == '=') {\n\t    return tGEQ;\n\t}\n\tif (c == '>') {\n\t    if ((c = nextc()) == '=') {\n\t\tyylval.id = tRSHFT;\n\t\tlex_state = EXPR_BEG;\n\t\treturn tOP_ASGN;\n\t    }\n\t    pushback(c);\n\t    return tRSHFT;\n\t}\n\tpushback(c);\n\treturn '>';\n\n      case '\"':\n\tlex_strterm = NEW_STRTERM(str_dquote, '\"', 0);\n\treturn tSTRING_BEG;\n\n      case '`':\n\tif (lex_state == EXPR_FNAME) {\n\t    lex_state = EXPR_END;\n\t    return c;\n\t}\n\tif (lex_state == EXPR_DOT) {\n\t    if (cmd_state)\n\t\tlex_state = EXPR_CMDARG;\n\t    else\n\t\tlex_state = EXPR_ARG;\n\t    return c;\n\t}\n\tlex_strterm = NEW_STRTERM(str_xquote, '`', 0);\n\treturn tXSTRING_BEG;\n\n      case '\\'':\n\tlex_strterm = NEW_STRTERM(str_squote, '\\'', 0);\n\treturn tSTRING_BEG;\n\n      case '?':\n\tif (lex_state == EXPR_END || lex_state == EXPR_ENDARG) {\n\t    lex_state = EXPR_BEG;\n\t    return '?';\n\t}\n\tc = nextc();\n\tif (c == -1) {\n\t    rb_compile_error(\"incomplete character syntax\");\n\t    return 0;\n\t}\n\tif (ISSPACE(c)){\n\t    if (!IS_ARG()){\n\t\tint c2 = 0;\n\t\tswitch (c) {\n\t\t  case ' ':\n\t\t    c2 = 's';\n\t\t    break;\n\t\t  case '\\n':\n\t\t    c2 = 'n';\n\t\t    break;\n\t\t  case '\\t':\n\t\t    c2 = 't';\n\t\t    break;\n\t\t  case '\\v':\n\t\t    c2 = 'v';\n\t\t    break;\n\t\t  case '\\r':\n\t\t    c2 = 'r';\n\t\t    break;\n\t\t  case '\\f':\n\t\t    c2 = 'f';\n\t\t    break;\n\t\t}\n\t\tif (c2) {\n\t\t    rb_warn(\"invalid character syntax; use ?\\\\%c\", c2);\n\t\t}\n\t    }\n\t  ternary:\n\t    pushback(c);\n\t    lex_state = EXPR_BEG;\n\t    return '?';\n\t}\n\telse if (ismbchar(c)) {\n\t    rb_warn(\"multibyte character literal not supported yet; use ?\\\\%.3o\", c);\n\t    goto ternary;\n\t}\n\telse if ((ISALNUM(c) || c == '_') && lex_p < lex_pend && is_identchar(*lex_p)) {\n\t    goto ternary;\n\t}\n\telse if (c == '\\\\') {\n\t    c = read_escape();\n\t}\n\tc &= 0xff;\n\tlex_state = EXPR_END;\n\tyylval.node = NEW_LIT(INT2FIX(c));\n\treturn tINTEGER;\n\n      case '&':\n\tif ((c = nextc()) == '&') {\n\t    lex_state = EXPR_BEG;\n\t    if ((c = nextc()) == '=') {\n\t\tyylval.id = tANDOP;\n\t\tlex_state = EXPR_BEG;\n\t\treturn tOP_ASGN;\n\t    }\n\t    pushback(c);\n\t    return tANDOP;\n\t}\n\telse if (c == '=') {\n\t    yylval.id = '&';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tpushback(c);\n\tif (IS_ARG() && space_seen && !ISSPACE(c)){\n\t    rb_warning(\"`&' interpreted as argument prefix\");\n\t    c = tAMPER;\n\t}\n\telse if (IS_BEG()) {\n\t    c = tAMPER;\n\t}\n\telse {\n\t    c = '&';\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG;\n\t}\n\treturn c;\n\n      case '|':\n\tif ((c = nextc()) == '|') {\n\t    lex_state = EXPR_BEG;\n\t    if ((c = nextc()) == '=') {\n\t\tyylval.id = tOROP;\n\t\tlex_state = EXPR_BEG;\n\t\treturn tOP_ASGN;\n\t    }\n\t    pushback(c);\n\t    return tOROP;\n\t}\n\tif (c == '=') {\n\t    yylval.id = '|';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tif (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {\n\t    lex_state = EXPR_ARG;\n\t}\n\telse {\n\t    lex_state = EXPR_BEG;\n\t}\n\tpushback(c);\n\treturn '|';\n\n      case '+':\n\tc = nextc();\n\tif (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {\n\t    lex_state = EXPR_ARG;\n\t    if (c == '@') {\n\t\treturn tUPLUS;\n\t    }\n\t    pushback(c);\n\t    return '+';\n\t}\n\tif (c == '=') {\n\t    yylval.id = '+';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tif (IS_BEG() ||\n\t    (IS_ARG() && space_seen && !ISSPACE(c))) {\n\t    if (IS_ARG()) arg_ambiguous();\n\t    lex_state = EXPR_BEG;\n\t    pushback(c);\n\t    if (ISDIGIT(c)) {\n\t\tc = '+';\n\t\tgoto start_num;\n\t    }\n\t    return tUPLUS;\n\t}\n\tlex_state = EXPR_BEG;\n\tpushback(c);\n\treturn '+';\n\n      case '-':\n\tc = nextc();\n\tif (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {\n\t    lex_state = EXPR_ARG;\n\t    if (c == '@') {\n\t\treturn tUMINUS;\n\t    }\n\t    pushback(c);\n\t    return '-';\n\t}\n\tif (c == '=') {\n\t    yylval.id = '-';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tif (IS_BEG() ||\n\t    (IS_ARG() && space_seen && !ISSPACE(c))) {\n\t    if (IS_ARG()) arg_ambiguous();\n\t    lex_state = EXPR_BEG;\n\t    pushback(c);\n\t    if (ISDIGIT(c)) {\n\t\treturn tUMINUS_NUM;\n\t    }\n\t    return tUMINUS;\n\t}\n\tlex_state = EXPR_BEG;\n\tpushback(c);\n\treturn '-';\n\n      case '.':\n\tlex_state = EXPR_BEG;\n\tif ((c = nextc()) == '.') {\n\t    if ((c = nextc()) == '.') {\n\t\treturn tDOT3;\n\t    }\n\t    pushback(c);\n\t    return tDOT2;\n\t}\n\tpushback(c);\n\tif (ISDIGIT(c)) {\n\t    yyerror(\"no .<digit> floating literal anymore; put 0 before dot\");\n\t}\n\tlex_state = EXPR_DOT;\n\treturn '.';\n\n      start_num:\n      case '0': case '1': case '2': case '3': case '4':\n      case '5': case '6': case '7': case '8': case '9':\n\t{\n\t    int is_float, seen_point, seen_e, nondigit;\n\n\t    is_float = seen_point = seen_e = nondigit = 0;\n\t    lex_state = EXPR_END;\n\t    newtok();\n\t    if (c == '-' || c == '+') {\n\t\ttokadd(c);\n\t\tc = nextc();\n\t    }\n\t    if (c == '0') {\n\t\tint start = toklen();\n\t\tc = nextc();\n\t\tif (c == 'x' || c == 'X') {\n\t\t    /* hexadecimal */\n\t\t    c = nextc();\n\t\t    if (ISXDIGIT(c)) {\n\t\t\tdo {\n\t\t\t    if (c == '_') {\n\t\t\t\tif (nondigit) break;\n\t\t\t\tnondigit = c;\n\t\t\t\tcontinue;\n\t\t\t    }\n\t\t\t    if (!ISXDIGIT(c)) break;\n\t\t\t    nondigit = 0;\n\t\t\t    tokadd(c);\n\t\t\t} while ((c = nextc()) != -1);\n\t\t    }\n\t\t    pushback(c);\n\t\t    tokfix();\n\t\t    if (toklen() == start) {\n\t\t\tyyerror(\"numeric literal without digits\");\n\t\t    }\n\t\t    else if (nondigit) goto trailing_uc;\n\t\t    yylval.node = NEW_LIT(rb_cstr_to_inum(tok(), 16, Qfalse));\n\t\t    return tINTEGER;\n\t\t}\n\t\tif (c == 'b' || c == 'B') {\n\t\t    /* binary */\n\t\t    c = nextc();\n\t\t    if (c == '0' || c == '1') {\n\t\t\tdo {\n\t\t\t    if (c == '_') {\n\t\t\t\tif (nondigit) break;\n\t\t\t\tnondigit = c;\n\t\t\t\tcontinue;\n\t\t\t    }\n\t\t\t    if (c != '0' && c != '1') break;\n\t\t\t    nondigit = 0;\n\t\t\t    tokadd(c);\n\t\t\t} while ((c = nextc()) != -1);\n\t\t    }\n\t\t    pushback(c);\n\t\t    tokfix();\n\t\t    if (toklen() == start) {\n\t\t\tyyerror(\"numeric literal without digits\");\n\t\t    }\n\t\t    else if (nondigit) goto trailing_uc;\n\t\t    yylval.node = NEW_LIT(rb_cstr_to_inum(tok(), 2, Qfalse));\n\t\t    return tINTEGER;\n\t\t}\n\t\tif (c == 'd' || c == 'D') {\n\t\t    /* decimal */\n\t\t    c = nextc();\n\t\t    if (ISDIGIT(c)) {\n\t\t\tdo {\n\t\t\t    if (c == '_') {\n\t\t\t\tif (nondigit) break;\n\t\t\t\tnondigit = c;\n\t\t\t\tcontinue;\n\t\t\t    }\n\t\t\t    if (!ISDIGIT(c)) break;\n\t\t\t    nondigit = 0;\n\t\t\t    tokadd(c);\n\t\t\t} while ((c = nextc()) != -1);\n\t\t    }\n\t\t    pushback(c);\n\t\t    tokfix();\n\t\t    if (toklen() == start) {\n\t\t\tyyerror(\"numeric literal without digits\");\n\t\t    }\n\t\t    else if (nondigit) goto trailing_uc;\n\t\t    yylval.node = NEW_LIT(rb_cstr_to_inum(tok(), 10, Qfalse));\n\t\t    return tINTEGER;\n\t\t}\n\t\tif (c == '_') {\n\t\t    /* 0_0 */\n\t\t    goto octal_number;\n\t\t}\n\t\tif (c == 'o' || c == 'O') {\n\t\t    /* prefixed octal */\n\t\t    c = nextc();\n\t\t    if (c == '_') {\n\t\t\tyyerror(\"numeric literal without digits\");\n\t\t    }\n\t\t}\n\t\tif (c >= '0' && c <= '7') {\n\t\t    /* octal */\n\t\t  octal_number:\n\t            do {\n\t\t\tif (c == '_') {\n\t\t\t    if (nondigit) break;\n\t\t\t    nondigit = c;\n\t\t\t    continue;\n\t\t\t}\n\t\t\tif (c < '0' || c > '9') break;\n\t\t\tif (c > '7') goto invalid_octal;\n\t\t\tnondigit = 0;\n\t\t\ttokadd(c);\n\t\t    } while ((c = nextc()) != -1);\n\t\t    if (toklen() > start) {\n\t\t\tpushback(c);\n\t\t\ttokfix();\n\t\t\tif (nondigit) goto trailing_uc;\n\t\t\tyylval.node = NEW_LIT(rb_cstr_to_inum(tok(), 8, Qfalse));\n\t\t\treturn tINTEGER;\n\t\t    }\n\t\t    if (nondigit) {\n\t\t\tpushback(c);\n\t\t\tgoto trailing_uc;\n\t\t    }\n\t\t}\n\t\tif (c > '7' && c <= '9') {\n\t\t  invalid_octal:\n\t\t    yyerror(\"Illegal octal digit\");\n\t\t}\n\t\telse if (c == '.' || c == 'e' || c == 'E') {\n\t\t    tokadd('0');\n\t\t}\n\t\telse {\n\t\t    pushback(c);\n\t\t    yylval.node = NEW_LIT(INT2FIX(0));\n\t\t    return tINTEGER;\n\t\t}\n\t    }\n\n\t    for (;;) {\n\t\tswitch (c) {\n\t\t  case '0': case '1': case '2': case '3': case '4':\n\t\t  case '5': case '6': case '7': case '8': case '9':\n\t\t    nondigit = 0;\n\t\t    tokadd(c);\n\t\t    break;\n\n\t\t  case '.':\n\t\t    if (nondigit) goto trailing_uc;\n\t\t    if (seen_point || seen_e) {\n\t\t\tgoto decode_num;\n\t\t    }\n\t\t    else {\n\t\t\tint c0 = nextc();\n\t\t\tif (!ISDIGIT(c0)) {\n\t\t\t    pushback(c0);\n\t\t\t    goto decode_num;\n\t\t\t}\n\t\t\tc = c0;\n\t\t    }\n\t\t    tokadd('.');\n\t\t    tokadd(c);\n\t\t    is_float++;\n\t\t    seen_point++;\n\t\t    nondigit = 0;\n\t\t    break;\n\n\t\t  case 'e':\n\t\t  case 'E':\n\t\t    if (nondigit) {\n\t\t\tpushback(c);\n\t\t\tc = nondigit;\n\t\t\tgoto decode_num;\n\t\t    }\n\t\t    if (seen_e) {\n\t\t\tgoto decode_num;\n\t\t    }\n\t\t    tokadd(c);\n\t\t    seen_e++;\n\t\t    is_float++;\n\t\t    nondigit = c;\n\t\t    c = nextc();\n\t\t    if (c != '-' && c != '+') continue;\n\t\t    tokadd(c);\n\t\t    nondigit = c;\n\t\t    break;\n\n\t\t  case '_':\t/* `_' in number just ignored */\n\t\t    if (nondigit) goto decode_num;\n\t\t    nondigit = c;\n\t\t    break;\n\n\t\t  default:\n\t\t    goto decode_num;\n\t\t}\n\t\tc = nextc();\n\t    }\n\n\t  decode_num:\n\t    pushback(c);\n\t    tokfix();\n\t    if (nondigit) {\n\t\tchar tmp[30];\n\t      trailing_uc:\n\t\tsprintf(tmp, \"trailing `%c' in number\", nondigit);\n\t\tyyerror(tmp);\n\t    }\n\t    if (is_float) {\n\t\tdouble d = strtod(tok(), 0);\n\t\tif (errno == ERANGE) {\n\t\t    rb_warn(\"Float %s out of range\", tok());\n\t\t    errno = 0;\n\t\t}\n\t\tyylval.node = NEW_LIT(rb_float_new(d));\n\t\treturn tFLOAT;\n\t    }\n\t    yylval.node = NEW_LIT(rb_cstr_to_inum(tok(), 10, Qfalse));\n\t    return tINTEGER;\n\t}\n\n      case ']':\n      case '}':\n      case ')':\n\tCOND_LEXPOP();\n\tCMDARG_LEXPOP();\n\tlex_state = EXPR_END;\n\treturn c;\n\n      case ':':\n\tc = nextc();\n\tif (c == ':') {\n\t    if (IS_BEG() || (IS_ARG() && space_seen)) {\n\t\tlex_state = EXPR_BEG;\n\t\treturn tCOLON3;\n\t    }\n\t    lex_state = EXPR_DOT;\n\t    return tCOLON2;\n\t}\n\tif (lex_state == EXPR_END || lex_state == EXPR_ENDARG || ISSPACE(c)) {\n\t    pushback(c);\n\t    lex_state = EXPR_BEG;\n\t    return ':';\n\t}\n\tswitch (c) {\n\t  case '\\'':\n\t    lex_strterm = NEW_STRTERM(str_ssym, c, 0);\n\t    break;\n\t  case '\"':\n\t    lex_strterm = NEW_STRTERM(str_dsym, c, 0);\n\t    break;\n\t  default:\n\t    pushback(c);\n\t    break;\n\t}\n\tlex_state = EXPR_FNAME;\n\treturn tSYMBEG;\n\n      case '/':\n\tif (IS_BEG()) {\n\t    lex_strterm = NEW_STRTERM(str_regexp, '/', 0);\n\t    return tREGEXP_BEG;\n\t}\n\tif ((c = nextc()) == '=') {\n\t    yylval.id = '/';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tpushback(c);\n\tif (IS_ARG() && space_seen) {\n\t    if (!ISSPACE(c)) {\n\t\targ_ambiguous();\n\t\tlex_strterm = NEW_STRTERM(str_regexp, '/', 0);\n\t\treturn tREGEXP_BEG;\n\t    }\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\treturn '/';\n\n      case '^':\n\tif ((c = nextc()) == '=') {\n\t    yylval.id = '^';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\tpushback(c);\n\treturn '^';\n\n      case ';':\n\tcommand_start = Qtrue;\n      case ',':\n\tlex_state = EXPR_BEG;\n\treturn c;\n\n      case '~':\n\tif (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {\n\t    if ((c = nextc()) != '@') {\n\t\tpushback(c);\n\t    }\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\treturn '~';\n\n      case '(':\n\tcommand_start = Qtrue;\n\tif (IS_BEG()) {\n\t    c = tLPAREN;\n\t}\n\telse if (space_seen) {\n\t    if (lex_state == EXPR_CMDARG) {\n\t\tc = tLPAREN_ARG;\n\t    }\n\t    else if (lex_state == EXPR_ARG) {\n\t\trb_warn(\"don't put space before argument parentheses\");\n\t\tc = '(';\n\t    }\n\t}\n\tCOND_PUSH(0);\n\tCMDARG_PUSH(0);\n\tlex_state = EXPR_BEG;\n\treturn c;\n\n      case '[':\n\tif (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {\n\t    lex_state = EXPR_ARG;\n\t    if ((c = nextc()) == ']') {\n\t\tif ((c = nextc()) == '=') {\n\t\t    return tASET;\n\t\t}\n\t\tpushback(c);\n\t\treturn tAREF;\n\t    }\n\t    pushback(c);\n\t    return '[';\n\t}\n\telse if (IS_BEG()) {\n\t    c = tLBRACK;\n\t}\n\telse if (IS_ARG() && space_seen) {\n\t    c = tLBRACK;\n\t}\n\tlex_state = EXPR_BEG;\n\tCOND_PUSH(0);\n\tCMDARG_PUSH(0);\n\treturn c;\n\n      case '{':\n\tif (IS_ARG() || lex_state == EXPR_END)\n\t    c = '{';          /* block (primary) */\n\telse if (lex_state == EXPR_ENDARG)\n\t    c = tLBRACE_ARG;  /* block (expr) */\n\telse\n\t    c = tLBRACE;      /* hash */\n\tCOND_PUSH(0);\n\tCMDARG_PUSH(0);\n\tlex_state = EXPR_BEG;\n\tif (c != tLBRACE) command_start = Qtrue;\n\treturn c;\n\n      case '\\\\':\n\tc = nextc();\n\tif (c == '\\n') {\n\t    space_seen = 1;\n\t    goto retry; /* skip \\\\n */\n\t}\n\tpushback(c);\n\treturn '\\\\';\n\n      case '%':\n\tif (IS_BEG()) {\n\t    int term;\n\t    int paren;\n\n\t    c = nextc();\n\t  quotation:\n\t    if (!ISALNUM(c)) {\n\t\tterm = c;\n\t\tc = 'Q';\n\t    }\n\t    else {\n\t\tterm = nextc();\n\t\tif (ISALNUM(term) || ismbchar(term)) {\n\t\t    yyerror(\"unknown type of %string\");\n\t\t    return 0;\n\t\t}\n\t    }\n\t    if (c == -1 || term == -1) {\n\t\trb_compile_error(\"unterminated quoted string meets end of file\");\n\t\treturn 0;\n\t    }\n\t    paren = term;\n\t    if (term == '(') term = ')';\n\t    else if (term == '[') term = ']';\n\t    else if (term == '{') term = '}';\n\t    else if (term == '<') term = '>';\n\t    else paren = 0;\n\n\t    switch (c) {\n\t      case 'Q':\n\t\tlex_strterm = NEW_STRTERM(str_dquote, term, paren);\n\t\treturn tSTRING_BEG;\n\n\t      case 'q':\n\t\tlex_strterm = NEW_STRTERM(str_squote, term, paren);\n\t\treturn tSTRING_BEG;\n\n\t      case 'W':\n\t\tlex_strterm = NEW_STRTERM(str_dword, term, paren);\n\t\tdo {c = nextc();} while (ISSPACE(c));\n\t\tpushback(c);\n\t\treturn tWORDS_BEG;\n\n\t      case 'w':\n\t\tlex_strterm = NEW_STRTERM(str_sword, term, paren);\n\t\tdo {c = nextc();} while (ISSPACE(c));\n\t\tpushback(c);\n\t\treturn tQWORDS_BEG;\n\n\t      case 'x':\n\t\tlex_strterm = NEW_STRTERM(str_xquote, term, paren);\n\t\treturn tXSTRING_BEG;\n\n\t      case 'r':\n\t\tlex_strterm = NEW_STRTERM(str_regexp, term, paren);\n\t\treturn tREGEXP_BEG;\n\n\t      case 's':\n\t\tlex_strterm = NEW_STRTERM(str_ssym, term, paren);\n\t\tlex_state = EXPR_FNAME;\n\t\treturn tSYMBEG;\n\n\t      default:\n\t\tyyerror(\"unknown type of %string\");\n\t\treturn 0;\n\t    }\n\t}\n\tif ((c = nextc()) == '=') {\n\t    yylval.id = '%';\n\t    lex_state = EXPR_BEG;\n\t    return tOP_ASGN;\n\t}\n\tif (IS_ARG() && space_seen && !ISSPACE(c)) {\n\t    goto quotation;\n\t}\n\tswitch (lex_state) {\n\t  case EXPR_FNAME: case EXPR_DOT:\n\t    lex_state = EXPR_ARG; break;\n\t  default:\n\t    lex_state = EXPR_BEG; break;\n\t}\n\tpushback(c);\n\treturn '%';\n\n      case '$':\n\tlast_state = lex_state;\n\tlex_state = EXPR_END;\n\tnewtok();\n\tc = nextc();\n\tswitch (c) {\n\t  case '_':\t\t/* $_: last read line string */\n\t    c = nextc();\n\t    if (is_identchar(c)) {\n\t\ttokadd('$');\n\t\ttokadd('_');\n\t\tbreak;\n\t    }\n\t    pushback(c);\n\t    c = '_';\n\t    /* fall through */\n\t  case '~':\t\t/* $~: match-data */\n\t    local_cnt(c);\n\t    /* fall through */\n\t  case '*':\t\t/* $*: argv */\n\t  case '$':\t\t/* $$: pid */\n\t  case '?':\t\t/* $?: last status */\n\t  case '!':\t\t/* $!: error string */\n\t  case '@':\t\t/* $@: error position */\n\t  case '/':\t\t/* $/: input record separator */\n\t  case '\\\\':\t\t/* $\\: output record separator */\n\t  case ';':\t\t/* $;: field separator */\n\t  case ',':\t\t/* $,: output field separator */\n\t  case '.':\t\t/* $.: last read line number */\n\t  case '=':\t\t/* $=: ignorecase */\n\t  case ':':\t\t/* $:: load path */\n\t  case '<':\t\t/* $<: reading filename */\n\t  case '>':\t\t/* $>: default output handle */\n\t  case '\\\"':\t\t/* $\": already loaded files */\n\t    tokadd('$');\n\t    tokadd(c);\n\t    tokfix();\n\t    yylval.id = rb_intern(tok());\n\t    return tGVAR;\n\n\t  case '-':\n\t    tokadd('$');\n\t    tokadd(c);\n\t    c = nextc();\n\t    if (is_identchar(c)) {\n\t\ttokadd(c);\n\t    }\n\t    else {\n\t\tpushback(c);\n\t    }\n\t  gvar:\n\t    tokfix();\n\t    yylval.id = rb_intern(tok());\n\t    /* xxx shouldn't check if valid option variable */\n\t    return tGVAR;\n\n\t  case '&':\t\t/* $&: last match */\n\t  case '`':\t\t/* $`: string before last match */\n\t  case '\\'':\t\t/* $': string after last match */\n\t  case '+':\t\t/* $+: string matches last paren. */\n\t    if (last_state == EXPR_FNAME) {\n\t\ttokadd('$');\n\t\ttokadd(c);\n\t\tgoto gvar;\n\t    }\n\t    yylval.node = NEW_BACK_REF(c);\n\t    return tBACK_REF;\n\n\t  case '1': case '2': case '3':\n\t  case '4': case '5': case '6':\n\t  case '7': case '8': case '9':\n\t    tokadd('$');\n\t    do {\n\t\ttokadd(c);\n\t\tc = nextc();\n\t    } while (ISDIGIT(c));\n\t    pushback(c);\n\t    if (last_state == EXPR_FNAME) goto gvar;\n\t    tokfix();\n\t    yylval.node = NEW_NTH_REF(atoi(tok()+1));\n\t    return tNTH_REF;\n\n\t  default:\n\t    if (!is_identchar(c)) {\n\t\tpushback(c);\n\t\treturn '$';\n\t    }\n\t  case '0':\n\t    tokadd('$');\n\t}\n\tbreak;\n\n      case '@':\n\tc = nextc();\n\tnewtok();\n\ttokadd('@');\n\tif (c == '@') {\n\t    tokadd('@');\n\t    c = nextc();\n\t}\n\tif (ISDIGIT(c)) {\n\t    if (tokidx == 1) {\n\t\trb_compile_error(\"`@%c' is not allowed as an instance variable name\", c);\n\t    }\n\t    else {\n\t\trb_compile_error(\"`@@%c' is not allowed as a class variable name\", c);\n\t    }\n\t    return 0;\n\t}\n\tif (!is_identchar(c)) {\n\t    pushback(c);\n\t    return '@';\n\t}\n\tbreak;\n\n      case '_':\n\tif (was_bol() && whole_match_p(\"__END__\", 7, 0)) {\n\t    ruby__end__seen = 1;\n\t    lex_lastline = 0;\n\t    return -1;\n\t}\n\tnewtok();\n\tbreak;\n\n      default:\n\tif (!is_identchar(c)) {\n\t    rb_compile_error(\"Invalid char `\\\\%03o' in expression\", c);\n\t    goto retry;\n\t}\n\n\tnewtok();\n\tbreak;\n    }\n\n    do {\n\ttokadd(c);\n\tif (ismbchar(c)) {\n\t    int i, len = mbclen(c)-1;\n\n\t    for (i = 0; i < len; i++) {\n\t\tc = nextc();\n\t\ttokadd(c);\n\t    }\n\t}\n\tc = nextc();\n    } while (is_identchar(c));\n    if ((c == '!' || c == '?') && is_identchar(tok()[0]) && !peek('=')) {\n\ttokadd(c);\n    }\n    else {\n\tpushback(c);\n    }\n    tokfix();\n\n    {\n\tint result = 0;\n\n\tlast_state = lex_state;\n\tswitch (tok()[0]) {\n\t  case '$':\n\t    lex_state = EXPR_END;\n\t    result = tGVAR;\n\t    break;\n\t  case '@':\n\t    lex_state = EXPR_END;\n\t    if (tok()[1] == '@')\n\t\tresult = tCVAR;\n\t    else\n\t\tresult = tIVAR;\n\t    break;\n\n\t  default:\n\t    if (toklast() == '!' || toklast() == '?') {\n\t\tresult = tFID;\n\t    }\n\t    else {\n\t\tif (lex_state == EXPR_FNAME) {\n\t\t    if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&\n\t\t\t(!peek('=') || (lex_p + 1 < lex_pend && lex_p[1] == '>'))) {\n\t\t\tresult = tIDENTIFIER;\n\t\t\ttokadd(c);\n\t\t\ttokfix();\n\t\t    }\n\t\t    else {\n\t\t\tpushback(c);\n\t\t    }\n\t\t}\n\t\tif (result == 0 && ISUPPER(tok()[0])) {\n\t\t    result = tCONSTANT;\n\t\t}\n\t\telse {\n\t\t    result = tIDENTIFIER;\n\t\t}\n\t    }\n\n\t    if (lex_state != EXPR_DOT) {\n\t\tconst struct kwtable *kw;\n\n\t\t/* See if it is a reserved word.  */\n\t\tkw = rb_reserved_word(tok(), toklen());\n\t\tif (kw) {\n\t\t    enum lex_state state = lex_state;\n\t\t    lex_state = kw->state;\n\t\t    if (state == EXPR_FNAME) {\n\t\t\tyylval.id = rb_intern(kw->name);\n\t\t\treturn kw->id[0];\n\t\t    }\n\t\t    if (kw->id[0] == kDO) {\n\t\t\tcommand_start = Qtrue;\n\t\t\tif (COND_P()) return kDO_COND;\n\t\t\tif (CMDARG_P() && state != EXPR_CMDARG)\n\t\t\t    return kDO_BLOCK;\n\t\t\tif (state == EXPR_ENDARG)\n\t\t\t    return kDO_BLOCK;\n\t\t\treturn kDO;\n\t\t    }\n\t\t    if (state == EXPR_BEG)\n\t\t\treturn kw->id[0];\n\t\t    else {\n\t\t\tif (kw->id[0] != kw->id[1])\n\t\t\t    lex_state = EXPR_BEG;\n\t\t\treturn kw->id[1];\n\t\t    }\n\t\t}\n\t    }\n\n\t    if (lex_state == EXPR_BEG ||\n\t\tlex_state == EXPR_MID ||\n\t\tlex_state == EXPR_DOT ||\n\t\tlex_state == EXPR_ARG ||\n\t\tlex_state == EXPR_CLASS ||\n\t\tlex_state == EXPR_CMDARG) {\n\t\tif (cmd_state) {\n\t\t    lex_state = EXPR_CMDARG;\n\t\t}\n\t\telse {\n\t\t    lex_state = EXPR_ARG;\n\t\t}\n\t    }\n\t    else {\n\t\tlex_state = EXPR_END;\n\t    }\n\t}\n\tyylval.id = rb_intern(tok());\n\tif (is_local_id(yylval.id) &&\n\t    last_state != EXPR_DOT &&\n\t    ((dyna_in_block() && rb_dvar_defined(yylval.id)) || local_id(yylval.id))) {\n\t    lex_state = EXPR_END;\n\t}\n\treturn result;\n    }\n}\n\nNODE*\nrb_node_newnode_eden(type, a0, a1, a2)\n    enum node_type type;\n    VALUE a0, a1, a2;\n{\n    NODE *n = (NODE*)rb_newobj_eden(type);\n\n    n->flags |= T_NODE;\n    nd_set_type(n, type);\n    nd_set_line(n, ruby_sourceline);\n    n->nd_file = ruby_sourcefile;\n\n    n->u1.value = a0;\n    n->u2.value = a1;\n    n->u3.value = a2;\n\n    return n;\n}\n\nNODE*\nrb_node_newnode_longlife(type, a0, a1, a2)\n    enum node_type type;\n    VALUE a0, a1, a2;\n{\n    NODE *n = (NODE*) rb_newobj_longlife((int)type);\n\n    n->flags |= T_NODE;\n    nd_set_type(n, type);\n    nd_set_line(n, ruby_sourceline);\n    n->nd_file = ruby_sourcefile;\n\n    n->u1.value = a0;\n    n->u2.value = a1;\n    n->u3.value = a2;\n\n    return n;\n}\n\nstatic enum node_type\nnodetype(node)\t\t\t/* for debug */\n    NODE *node;\n{\n    return (enum node_type)nd_type(node);\n}\n\nstatic int\nnodeline(node)\n    NODE *node;\n{\n    return nd_line(node);\n}\n\nstatic NODE*\nnewline_node(node)\n    NODE *node;\n{\n    NODE *nl = 0;\n    if (node) {\n\tint line;\n\tif (nd_type(node) == NODE_NEWLINE) return node;\n\tline = nd_line(node);\n\tnode = remove_begin(node);\n\tnl = NEW_NEWLINE(node);\n\tnd_set_line(nl, line);\n\tnl->nd_nth = line;\n    }\n    return nl;\n}\n\nstatic void\nfixpos(node, orig)\n    NODE *node, *orig;\n{\n    if (!node) return;\n    if (!orig) return;\n    if (orig == (NODE*)1) return;\n    node->nd_file = orig->nd_file;\n    nd_set_line(node, nd_line(orig));\n}\n\nstatic void\nparser_warning(node, mesg)\n    NODE *node;\n    const char *mesg;\n{\n    int line = ruby_sourceline;\n    ruby_sourceline = nd_line(node);\n    rb_warning(\"%s\", mesg);\n    ruby_sourceline = line;\n}\n\nstatic void\nparser_warn(node, mesg)\n    NODE *node;\n    const char *mesg;\n{\n    int line = ruby_sourceline;\n    ruby_sourceline = nd_line(node);\n    rb_warn(\"%s\", mesg);\n    ruby_sourceline = line;\n}\n\nstatic NODE*\nblock_append(head, tail)\n    NODE *head, *tail;\n{\n    NODE *end, *h = head;\n\n    if (tail == 0) return head;\n\n  again:\n    if (h == 0) return tail;\n    switch (nd_type(h)) {\n      case NODE_NEWLINE:\n\th = h->nd_next;\n\tgoto again;\n      case NODE_LIT:\n      case NODE_STR:\n\tparser_warning(h, \"unused literal ignored\");\n\treturn tail;\n      default:\n\th = end = NEW_BLOCK(head);\n\tend->nd_end = end;\n\tfixpos(end, head);\n\thead = end;\n\tbreak;\n      case NODE_BLOCK:\n\tend = h->nd_end;\n\tbreak;\n    }\n\n    if (RTEST(ruby_verbose)) {\n\tNODE *nd = end->nd_head;\n      newline:\n\tswitch (nd_type(nd)) {\n\t  case NODE_RETURN:\n\t  case NODE_BREAK:\n\t  case NODE_NEXT:\n\t  case NODE_REDO:\n\t  case NODE_RETRY:\n\t    parser_warning(nd, \"statement not reached\");\n\t    break;\n\n\tcase NODE_NEWLINE:\n\t    nd = nd->nd_next;\n\t    goto newline;\n\n\t  default:\n\t    break;\n\t}\n    }\n\n    if (nd_type(tail) != NODE_BLOCK) {\n\ttail = NEW_BLOCK(tail);\n\ttail->nd_end = tail;\n    }\n    end->nd_next = tail;\n    h->nd_end = tail->nd_end;\n    return head;\n}\n\n/* append item to the list */\nstatic NODE*\nlist_append(list, item)\n    NODE *list, *item;\n{\n    NODE *last;\n\n    if (list == 0) return NEW_LIST(item);\n    if (list->nd_next) {\n\tlast = list->nd_next->nd_end;\n    }\n    else {\n\tlast = list;\n    }\n\n    list->nd_alen += 1;\n    last->nd_next = NEW_LIST(item);\n    list->nd_next->nd_end = last->nd_next;\n    return list;\n}\n\n/* concat two lists */\nstatic NODE*\nlist_concat(head, tail)\n    NODE *head, *tail;\n{\n    NODE *last;\n\n    if (head->nd_next) {\n\tlast = head->nd_next->nd_end;\n    }\n    else {\n\tlast = head;\n    }\n\n    head->nd_alen += tail->nd_alen;\n    last->nd_next = tail;\n    if (tail->nd_next) {\n\thead->nd_next->nd_end = tail->nd_next->nd_end;\n    }\n    else {\n\thead->nd_next->nd_end = tail;\n    }\n\n    return head;\n}\n\n/* concat two string literals */\nstatic NODE *\nliteral_concat(head, tail)\n    NODE *head, *tail;\n{\n    enum node_type htype;\n\n    if (!head) return tail;\n    if (!tail) return head;\n\n    htype = nd_type(head);\n    if (htype == NODE_EVSTR) {\n\tNODE *node = NEW_DSTR(rb_str_new(0, 0));\n\thead = list_append(node, head);\n    }\n    switch (nd_type(tail)) {\n      case NODE_STR:\n\tif (htype == NODE_STR) {\n\t    rb_str_concat(head->nd_lit, tail->nd_lit);\n\t    rb_gc_force_recycle((VALUE)tail);\n\t}\n\telse {\n\t    list_append(head, tail);\n\t}\n\tbreak;\n\n      case NODE_DSTR:\n\tif (htype == NODE_STR) {\n\t    rb_str_concat(head->nd_lit, tail->nd_lit);\n\t    tail->nd_lit = head->nd_lit;\n\t    rb_gc_force_recycle((VALUE)head);\n\t    head = tail;\n\t}\n\telse {\n\t    nd_set_type(tail, NODE_ARRAY);\n\t    tail->nd_head = NEW_STR(tail->nd_lit);\n\t    list_concat(head, tail);\n\t}\n\tbreak;\n\n      case NODE_EVSTR:\n\tif (htype == NODE_STR) {\n\t    nd_set_type(head, NODE_DSTR);\n\t    head->nd_alen = 1;\n\t}\n\tlist_append(head, tail);\n\tbreak;\n    }\n    return head;\n}\n\nstatic NODE *\nevstr2dstr(node)\n    NODE *node;\n{\n    if (nd_type(node) == NODE_EVSTR) {\n\tnode = list_append(NEW_DSTR(rb_str_new(0, 0)), node);\n    }\n    return node;\n}\n\nstatic NODE *\nnew_evstr(node)\n    NODE *node;\n{\n    NODE *head = node;\n\n  again:\n    if (node) {\n\tswitch (nd_type(node)) {\n\t  case NODE_STR: case NODE_DSTR: case NODE_EVSTR:\n\t    return node;\n\t  case NODE_NEWLINE:\n\t    node = node->nd_next;\n\t    goto again;\n\t}\n    }\n    return NEW_EVSTR(head);\n}\n\nstatic NODE *\ncall_op(recv, id, narg, arg1)\n    NODE *recv;\n    ID id;\n    int narg;\n    NODE *arg1;\n{\n    value_expr(recv);\n    if (narg == 1) {\n\tvalue_expr(arg1);\n\targ1 = NEW_LIST(arg1);\n    }\n    else {\n\targ1 = 0;\n    }\n    return NEW_CALL(recv, id, arg1);\n}\n\nstatic NODE*\nmatch_gen(node1, node2)\n    NODE *node1;\n    NODE *node2;\n{\n    local_cnt('~');\n\n    value_expr(node1);\n    value_expr(node2);\n    if (node1) {\n\tswitch (nd_type(node1)) {\n\t  case NODE_DREGX:\n\t  case NODE_DREGX_ONCE:\n\t    return NEW_MATCH2(node1, node2);\n\n\t  case NODE_LIT:\n\t    if (TYPE(node1->nd_lit) == T_REGEXP) {\n\t\treturn NEW_MATCH2(node1, node2);\n\t    }\n\t}\n    }\n\n    if (node2) {\n\tswitch (nd_type(node2)) {\n\t  case NODE_DREGX:\n\t  case NODE_DREGX_ONCE:\n\t    return NEW_MATCH3(node2, node1);\n\n\t  case NODE_LIT:\n\t    if (TYPE(node2->nd_lit) == T_REGEXP) {\n\t\treturn NEW_MATCH3(node2, node1);\n\t    }\n\t}\n    }\n\n    return NEW_CALL(node1, tMATCH, NEW_LIST(node2));\n}\n\nstatic NODE*\ngettable(id)\n    ID id;\n{\n    if (id == kSELF) {\n\treturn NEW_SELF();\n    }\n    else if (id == kNIL) {\n\treturn NEW_NIL();\n    }\n    else if (id == kTRUE) {\n\treturn NEW_TRUE();\n    }\n    else if (id == kFALSE) {\n\treturn NEW_FALSE();\n    }\n    else if (id == k__FILE__) {\n\treturn NEW_STR(rb_str_new2(ruby_sourcefile));\n    }\n    else if (id == k__LINE__) {\n\treturn NEW_LIT(INT2FIX(ruby_sourceline));\n    }\n    else if (is_local_id(id)) {\n\tif (dyna_in_block() && rb_dvar_defined(id)) return NEW_DVAR(id);\n\tif (local_id(id)) return NEW_LVAR(id);\n\t/* method call without arguments */\n#if 0\n\t/* Rite will warn this */\n\trb_warn(\"ambiguous identifier; %s() or self.%s is better for method call\",\n\t\trb_id2name(id), rb_id2name(id));\n#endif\n\treturn NEW_VCALL(id);\n    }\n    else if (is_global_id(id)) {\n\treturn NEW_GVAR(id);\n    }\n    else if (is_instance_id(id)) {\n\treturn NEW_IVAR(id);\n    }\n    else if (is_const_id(id)) {\n\treturn NEW_CONST(id);\n    }\n    else if (is_class_id(id)) {\n\treturn NEW_CVAR(id);\n    }\n    rb_compile_error(\"identifier %s is not valid\", rb_id2name(id));\n    return 0;\n}\n\nstatic VALUE dyna_var_lookup _((ID id));\n\nstatic NODE*\nassignable(id, val)\n    ID id;\n    NODE *val;\n{\n    value_expr(val);\n    if (id == kSELF) {\n\tyyerror(\"Can't change the value of self\");\n    }\n    else if (id == kNIL) {\n\tyyerror(\"Can't assign to nil\");\n    }\n    else if (id == kTRUE) {\n\tyyerror(\"Can't assign to true\");\n    }\n    else if (id == kFALSE) {\n\tyyerror(\"Can't assign to false\");\n    }\n    else if (id == k__FILE__) {\n\tyyerror(\"Can't assign to __FILE__\");\n    }\n    else if (id == k__LINE__) {\n\tyyerror(\"Can't assign to __LINE__\");\n    }\n    else if (is_local_id(id)) {\n\tif (rb_dvar_curr(id)) {\n\t    return NEW_DASGN_CURR(id, val);\n\t}\n\telse if (dyna_var_lookup(id)) {\n\t    return NEW_DASGN(id, val);\n\t}\n\telse if (local_id(id) || !dyna_in_block()) {\n\t    return NEW_LASGN(id, val);\n\t}\n\telse{\n\t    rb_dvar_push(id, Qnil);\n\t    return NEW_DASGN_CURR(id, val);\n\t}\n    }\n    else if (is_global_id(id)) {\n\treturn NEW_GASGN(id, val);\n    }\n    else if (is_instance_id(id)) {\n\treturn NEW_IASGN(id, val);\n    }\n    else if (is_const_id(id)) {\n\tif (in_def || in_single)\n\t    yyerror(\"dynamic constant assignment\");\n\treturn NEW_CDECL(id, val, 0);\n    }\n    else if (is_class_id(id)) {\n\tif (in_def || in_single) return NEW_CVASGN(id, val);\n\treturn NEW_CVDECL(id, val);\n    }\n    else {\n\trb_compile_error(\"identifier %s is not valid\", rb_id2name(id));\n    }\n    return 0;\n}\n\nstatic NODE *\naryset(recv, idx)\n    NODE *recv, *idx;\n{\n    if (recv && nd_type(recv) == NODE_SELF)\n\trecv = (NODE *)1;\n    else\n\tvalue_expr(recv);\n    return NEW_ATTRASGN(recv, tASET, idx);\n}\n\nID\nrb_id_attrset(id)\n    ID id;\n{\n    id &= ~ID_SCOPE_MASK;\n    id |= ID_ATTRSET;\n    return id;\n}\n\nstatic NODE *\nattrset(recv, id)\n    NODE *recv;\n    ID id;\n{\n    if (recv && nd_type(recv) == NODE_SELF)\n\trecv = (NODE *)1;\n    else\n\tvalue_expr(recv);\n    return NEW_ATTRASGN(recv, rb_id_attrset(id), 0);\n}\n\nstatic void\nrb_backref_error(node)\n    NODE *node;\n{\n    switch (nd_type(node)) {\n      case NODE_NTH_REF:\n\trb_compile_error(\"Can't set variable $%d\", node->nd_nth);\n\tbreak;\n      case NODE_BACK_REF:\n\trb_compile_error(\"Can't set variable $%c\", (int)node->nd_nth);\n\tbreak;\n    }\n}\n\nstatic NODE *\narg_concat(node1, node2)\n    NODE *node1;\n    NODE *node2;\n{\n    if (!node2) return node1;\n    return NEW_ARGSCAT(node1, node2);\n}\n\nstatic NODE *\narg_add(node1, node2)\n    NODE *node1;\n    NODE *node2;\n{\n    if (!node1) return NEW_LIST(node2);\n    if (nd_type(node1) == NODE_ARRAY) {\n\treturn list_append(node1, node2);\n    }\n    else {\n\treturn NEW_ARGSPUSH(node1, node2);\n    }\n}\n\nstatic NODE*\nnode_assign(lhs, rhs)\n    NODE *lhs, *rhs;\n{\n    if (!lhs) return 0;\n\n    value_expr(rhs);\n    switch (nd_type(lhs)) {\n      case NODE_GASGN:\n      case NODE_IASGN:\n      case NODE_LASGN:\n      case NODE_DASGN:\n      case NODE_DASGN_CURR:\n      case NODE_MASGN:\n      case NODE_CDECL:\n      case NODE_CVDECL:\n      case NODE_CVASGN:\n\tlhs->nd_value = rhs;\n\tbreak;\n\n      case NODE_ATTRASGN:\n      case NODE_CALL:\n\tlhs->nd_args = arg_add(lhs->nd_args, rhs);\n\tbreak;\n\n      default:\n\t/* should not happen */\n\tbreak;\n    }\n\n    return lhs;\n}\n\nstatic int\nvalue_expr0(node)\n    NODE *node;\n{\n    int cond = 0;\n\n    while (node) {\n\tswitch (nd_type(node)) {\n\t  case NODE_DEFN:\n\t  case NODE_DEFS:\n\t    parser_warning(node, \"void value expression\");\n\t    return Qfalse;\n\n\t  case NODE_RETURN:\n\t  case NODE_BREAK:\n\t  case NODE_NEXT:\n\t  case NODE_REDO:\n\t  case NODE_RETRY:\n\t    if (!cond) yyerror(\"void value expression\");\n\t    /* or \"control never reach\"? */\n\t    return Qfalse;\n\n\t  case NODE_BLOCK:\n\t    while (node->nd_next) {\n\t\tnode = node->nd_next;\n\t    }\n\t    node = node->nd_head;\n\t    break;\n\n\t  case NODE_BEGIN:\n\t    node = node->nd_body;\n\t    break;\n\n\t  case NODE_IF:\n\t    if (!value_expr(node->nd_body)) return Qfalse;\n\t    node = node->nd_else;\n\t    break;\n\n\t  case NODE_AND:\n\t  case NODE_OR:\n\t    cond = 1;\n\t    node = node->nd_2nd;\n\t    break;\n\n\t  case NODE_NEWLINE:\n\t    node = node->nd_next;\n\t    break;\n\n\t  default:\n\t    return Qtrue;\n\t}\n    }\n\n    return Qtrue;\n}\n\nstatic void\nvoid_expr0(node)\n    NODE *node;\n{\n    const char *useless = 0;\n\n    if (!RTEST(ruby_verbose)) return;\n\n  again:\n    if (!node) return;\n    switch (nd_type(node)) {\n      case NODE_NEWLINE:\n\tnode = node->nd_next;\n\tgoto again;\n\n      case NODE_CALL:\n\tswitch (node->nd_mid) {\n\t  case '+':\n\t  case '-':\n\t  case '*':\n\t  case '/':\n\t  case '%':\n\t  case tPOW:\n\t  case tUPLUS:\n\t  case tUMINUS:\n\t  case '|':\n\t  case '^':\n\t  case '&':\n\t  case tCMP:\n\t  case '>':\n\t  case tGEQ:\n\t  case '<':\n\t  case tLEQ:\n\t  case tEQ:\n\t  case tNEQ:\n\t    useless = rb_id2name(node->nd_mid);\n\t    break;\n\t}\n\tbreak;\n\n      case NODE_LVAR:\n      case NODE_DVAR:\n      case NODE_GVAR:\n      case NODE_IVAR:\n      case NODE_CVAR:\n      case NODE_NTH_REF:\n      case NODE_BACK_REF:\n\tuseless = \"a variable\";\n\tbreak;\n      case NODE_CONST:\n      case NODE_CREF:\n\tuseless = \"a constant\";\n\tbreak;\n      case NODE_LIT:\n      case NODE_STR:\n      case NODE_DSTR:\n      case NODE_DREGX:\n      case NODE_DREGX_ONCE:\n\tuseless = \"a literal\";\n\tbreak;\n      case NODE_COLON2:\n      case NODE_COLON3:\n\tuseless = \"::\";\n\tbreak;\n      case NODE_DOT2:\n\tuseless = \"..\";\n\tbreak;\n      case NODE_DOT3:\n\tuseless = \"...\";\n\tbreak;\n      case NODE_SELF:\n\tuseless = \"self\";\n\tbreak;\n      case NODE_NIL:\n\tuseless = \"nil\";\n\tbreak;\n      case NODE_TRUE:\n\tuseless = \"true\";\n\tbreak;\n      case NODE_FALSE:\n\tuseless = \"false\";\n\tbreak;\n      case NODE_DEFINED:\n\tuseless = \"defined?\";\n\tbreak;\n    }\n\n    if (useless) {\n\tint line = ruby_sourceline;\n\n\truby_sourceline = nd_line(node);\n\trb_warn(\"useless use of %s in void context\", useless);\n\truby_sourceline = line;\n    }\n}\n\nstatic void\nvoid_stmts(node)\n    NODE *node;\n{\n    if (!RTEST(ruby_verbose)) return;\n    if (!node) return;\n    if (nd_type(node) != NODE_BLOCK) return;\n\n    for (;;) {\n\tif (!node->nd_next) return;\n\tvoid_expr0(node->nd_head);\n\tnode = node->nd_next;\n    }\n}\n\nstatic NODE *\nremove_begin(node)\n    NODE *node;\n{\n    NODE **n = &node;\n    while (*n) {\n\tswitch (nd_type(*n)) {\n\t  case NODE_NEWLINE:\n\t    n = &(*n)->nd_next;\n\t    continue;\n\t  case NODE_BEGIN:\n\t    *n = (*n)->nd_body;\n\t  default:\n\t    return node;\n\t}\n    }\n    return node;\n}\n\nstatic int\nassign_in_cond(node)\n    NODE *node;\n{\n    switch (nd_type(node)) {\n      case NODE_MASGN:\n\tyyerror(\"multiple assignment in conditional\");\n\treturn 1;\n\n      case NODE_LASGN:\n      case NODE_DASGN:\n      case NODE_GASGN:\n      case NODE_IASGN:\n\tbreak;\n\n      case NODE_NEWLINE:\n      default:\n\treturn 0;\n    }\n\n    switch (nd_type(node->nd_value)) {\n      case NODE_LIT:\n      case NODE_STR:\n      case NODE_NIL:\n      case NODE_TRUE:\n      case NODE_FALSE:\n\t/* reports always */\n\tparser_warn(node->nd_value, \"found = in conditional, should be ==\");\n\treturn 1;\n\n      case NODE_DSTR:\n      case NODE_XSTR:\n      case NODE_DXSTR:\n      case NODE_EVSTR:\n      case NODE_DREGX:\n      default:\n\tbreak;\n    }\n#if 0\n    if (assign_in_cond(node->nd_value) == 0) {\n\tparser_warning(node->nd_value, \"assignment in condition\");\n    }\n#endif\n    return 1;\n}\n\nstatic int\ne_option_supplied()\n{\n    if (strcmp(ruby_sourcefile, \"-e\") == 0)\n\treturn Qtrue;\n    return Qfalse;\n}\n\nstatic void\nwarn_unless_e_option(node, str)\n    NODE *node;\n    const char *str;\n{\n    if (!e_option_supplied()) parser_warn(node, str);\n}\n\nstatic void\nwarning_unless_e_option(node, str)\n    NODE *node;\n    const char *str;\n{\n    if (!e_option_supplied()) parser_warning(node, str);\n}\n\nstatic void\nfixup_nodes(rootnode)\n    NODE **rootnode;\n{\n    NODE *node, *next, *head;\n\n    for (node = *rootnode; node; node = next) {\n\tenum node_type type;\n\tVALUE val;\n\n\tnext = node->nd_next;\n\thead = node->nd_head;\n\trb_gc_force_recycle((VALUE)node);\n\t*rootnode = next;\n\tswitch (type = nd_type(head)) {\n\t  case NODE_DOT2:\n\t  case NODE_DOT3:\n\t    val = rb_range_new(head->nd_beg->nd_lit, head->nd_end->nd_lit,\n\t\t\t       type == NODE_DOT3 ? Qtrue : Qfalse);\n\t    rb_gc_force_recycle((VALUE)head->nd_beg);\n\t    rb_gc_force_recycle((VALUE)head->nd_end);\n\t    nd_set_type(head, NODE_LIT);\n\t    head->nd_lit = val;\n\t    break;\n\t  default:\n\t    break;\n\t}\n    }\n}\n\nstatic NODE *cond0();\n\nstatic NODE*\nrange_op(node)\n    NODE *node;\n{\n    enum node_type type;\n\n    if (node == 0) return 0;\n\n    type = nd_type(node);\n    if (type == NODE_NEWLINE) {\n\tnode = node->nd_next;\n\ttype = nd_type(node);\n    }\n    value_expr(node);\n    if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) {\n\twarn_unless_e_option(node, \"integer literal in conditional range\");\n\treturn call_op(node,tEQ,1,NEW_GVAR(rb_intern(\"$.\")));\n    }\n    return cond0(node);\n}\n\nstatic int\nliteral_node(node)\n    NODE *node;\n{\n    if (!node) return 1;\t/* same as NODE_NIL */\n    switch (nd_type(node)) {\n      case NODE_LIT:\n      case NODE_STR:\n      case NODE_DSTR:\n      case NODE_EVSTR:\n      case NODE_DREGX:\n      case NODE_DREGX_ONCE:\n      case NODE_DSYM:\n\treturn 2;\n      case NODE_TRUE:\n      case NODE_FALSE:\n      case NODE_NIL:\n\treturn 1;\n    }\n    return 0;\n}\n\nstatic NODE*\ncond0(node)\n    NODE *node;\n{\n    if (node == 0) return 0;\n    assign_in_cond(node);\n\n    switch (nd_type(node)) {\n      case NODE_DSTR:\n      case NODE_EVSTR:\n      case NODE_STR:\n\trb_warn(\"string literal in condition\");\n\tbreak;\n\n      case NODE_DREGX:\n      case NODE_DREGX_ONCE:\n\twarning_unless_e_option(node, \"regex literal in condition\");\n\tlocal_cnt('_');\n\tlocal_cnt('~');\n\treturn NEW_MATCH2(node, NEW_GVAR(rb_intern(\"$_\")));\n\n      case NODE_AND:\n      case NODE_OR:\n\tnode->nd_1st = cond0(node->nd_1st);\n\tnode->nd_2nd = cond0(node->nd_2nd);\n\tbreak;\n\n      case NODE_DOT2:\n      case NODE_DOT3:\n\tnode->nd_beg = range_op(node->nd_beg);\n\tnode->nd_end = range_op(node->nd_end);\n\tif (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2);\n\telse if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3);\n\tnode->nd_cnt = local_append(internal_id());\n\tif (!e_option_supplied()) {\n\t    int b = literal_node(node->nd_beg);\n\t    int e = literal_node(node->nd_end);\n\t    if ((b == 1 && e == 1) || (b + e >= 2 && RTEST(ruby_verbose))) {\n\t\tparser_warn(node, \"range literal in condition\");\n\t    }\n\t}\n\tbreak;\n\n      case NODE_DSYM:\n\tparser_warning(node, \"literal in condition\");\n\tbreak;\n\n      case NODE_LIT:\n\tif (TYPE(node->nd_lit) == T_REGEXP) {\n\t    warn_unless_e_option(node, \"regex literal in condition\");\n\t    nd_set_type(node, NODE_MATCH);\n\t    local_cnt('_');\n\t    local_cnt('~');\n\t}\n\telse {\n\t    parser_warning(node, \"literal in condition\");\n\t}\n      default:\n\tbreak;\n    }\n    return node;\n}\n\nstatic NODE*\ncond(node)\n    NODE *node;\n{\n    if (node == 0) return 0;\n    value_expr(node);\n    if (nd_type(node) == NODE_NEWLINE){\n\tnode->nd_next = cond0(node->nd_next);\n\treturn node;\n    }\n    return cond0(node);\n}\n\nstatic NODE*\nlogop(type, left, right)\n    enum node_type type;\n    NODE *left, *right;\n{\n    value_expr(left);\n    if (left && nd_type(left) == type) {\n\tNODE *node = left, *second;\n\twhile ((second = node->nd_2nd) != 0 && nd_type(second) == type) {\n\t    node = second;\n\t}\n\tnode->nd_2nd = NEW_NODE(type, second, right, 0);\n\treturn left;\n    }\n    return NEW_NODE(type, left, right, 0);\n}\n\nstatic int\ncond_negative(nodep)\n    NODE **nodep;\n{\n    NODE *c = *nodep;\n\n    if (!c) return 0;\n    switch (nd_type(c)) {\n      case NODE_NOT:\n\t*nodep = c->nd_body;\n\treturn 1;\n      case NODE_NEWLINE:\n\tif (c->nd_next && nd_type(c->nd_next) == NODE_NOT) {\n\t    c->nd_next = c->nd_next->nd_body;\n\t    return 1;\n\t}\n    }\n    return 0;\n}\n\nstatic void\nno_blockarg(node)\n    NODE *node;\n{\n    if (node && nd_type(node) == NODE_BLOCK_PASS) {\n\trb_compile_error(\"block argument should not be given\");\n    }\n}\n\nstatic NODE *\nret_args(node)\n    NODE *node;\n{\n    if (node) {\n\tno_blockarg(node);\n\tif (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {\n\t    node = node->nd_head;\n\t}\n\tif (node && nd_type(node) == NODE_SPLAT) {\n\t    node = NEW_SVALUE(node);\n\t}\n    }\n    return node;\n}\n\nstatic NODE *\nnew_yield(node)\n    NODE *node;\n{\n    long state = Qtrue;\n\n    if (node) {\n        no_blockarg(node);\n        if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {\n            node = node->nd_head;\n            state = Qfalse;\n        }\n        if (node && nd_type(node) == NODE_SPLAT) {\n            state = Qtrue;\n        }\n    }\n    else {\n        state = Qfalse;\n    }\n    return NEW_YIELD(node, state);\n}\n\nstatic NODE*\nnegate_lit(node)\n    NODE *node;\n{\n    switch (TYPE(node->nd_lit)) {\n      case T_FIXNUM:\n\tnode->nd_lit = LONG2FIX(-FIX2LONG(node->nd_lit));\n\tbreak;\n      case T_BIGNUM:\n\tnode->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);\n\tbreak;\n      case T_FLOAT:\n\tRFLOAT(node->nd_lit)->value = -RFLOAT(node->nd_lit)->value;\n\tbreak;\n      default:\n\tbreak;\n    }\n    return node;\n}\n\nstatic NODE *\narg_blk_pass(node1, node2)\n    NODE *node1;\n    NODE *node2;\n{\n    if (node2) {\n\tnode2->nd_head = node1;\n\treturn node2;\n    }\n    return node1;\n}\n\nstatic NODE*\narg_prepend(node1, node2)\n    NODE *node1, *node2;\n{\n    switch (nd_type(node2)) {\n      case NODE_ARRAY:\n\treturn list_concat(NEW_LIST(node1), node2);\n\n      case NODE_SPLAT:\n\treturn arg_concat(node1, node2->nd_head);\n\n      case NODE_BLOCK_PASS:\n\tnode2->nd_body = arg_prepend(node1, node2->nd_body);\n\treturn node2;\n\n      default:\n\trb_bug(\"unknown nodetype(%d) for arg_prepend\", nd_type(node2));\n    }\n    return 0;\t\t\t/* not reached */\n}\n\nstatic NODE*\nnew_call(r,m,a)\n    NODE *r;\n    ID m;\n    NODE *a;\n{\n    if (a && nd_type(a) == NODE_BLOCK_PASS) {\n\ta->nd_iter = NEW_CALL(r,m,a->nd_head);\n\treturn a;\n    }\n    return NEW_CALL(r,m,a);\n}\n\nstatic NODE*\nnew_fcall(m,a)\n    ID m;\n    NODE *a;\n{\n    if (a && nd_type(a) == NODE_BLOCK_PASS) {\n\ta->nd_iter = NEW_FCALL(m,a->nd_head);\n\treturn a;\n    }\n    return NEW_FCALL(m,a);\n}\n\nstatic NODE*\nnew_super(a)\n    NODE *a;\n{\n    if (a && nd_type(a) == NODE_BLOCK_PASS) {\n\ta->nd_iter = NEW_SUPER(a->nd_head);\n\treturn a;\n    }\n    return NEW_SUPER(a);\n}\n\nstatic struct local_vars {\n    ID *tbl;\n    int nofree;\n    int cnt;\n    int dlev;\n    struct RVarmap* dyna_vars;\n    struct local_vars *prev;\n} *lvtbl;\n\nstatic void\nlocal_push(top)\n    int top;\n{\n    struct local_vars *local;\n\n    local = ALLOC(struct local_vars);\n    local->prev = lvtbl;\n    local->nofree = 0;\n    local->cnt = 0;\n    local->tbl = 0;\n    local->dlev = 0;\n    local->dyna_vars = ruby_dyna_vars;\n    lvtbl = local;\n    if (!top) {\n\t/* preserve reference for GC, but link should be cut. */\n\trb_dvar_push(0, (VALUE)ruby_dyna_vars);\n\truby_dyna_vars->next = 0;\n    }\n}\n\nstatic void\nlocal_pop()\n{\n    struct local_vars *local = lvtbl->prev;\n\n    if (lvtbl->tbl) {\n\tif (!lvtbl->nofree) xfree(lvtbl->tbl);\n\telse lvtbl->tbl[0] = lvtbl->cnt;\n    }\n    ruby_dyna_vars = lvtbl->dyna_vars;\n    xfree(lvtbl);\n    lvtbl = local;\n}\n\nstatic ID*\nlocal_tbl()\n{\n    lvtbl->nofree = 1;\n    return lvtbl->tbl;\n}\n\nstatic int\nlocal_append(id)\n    ID id;\n{\n    if (lvtbl->tbl == 0) {\n\tlvtbl->tbl = ALLOC_N(ID, 4);\n\tlvtbl->tbl[0] = 0;\n\tlvtbl->tbl[1] = '_';\n\tlvtbl->tbl[2] = '~';\n\tlvtbl->cnt = 2;\n\tif (id == '_') return 0;\n\tif (id == '~') return 1;\n    }\n    else {\n\tREALLOC_N(lvtbl->tbl, ID, lvtbl->cnt+2);\n    }\n\n    lvtbl->tbl[lvtbl->cnt+1] = id;\n    return lvtbl->cnt++;\n}\n\nstatic int\nlocal_cnt(id)\n    ID id;\n{\n    int cnt, max;\n\n    if (id == 0) return lvtbl->cnt;\n\n    for (cnt=1, max=lvtbl->cnt+1; cnt<max;cnt++) {\n\tif (lvtbl->tbl[cnt] == id) return cnt-1;\n    }\n    return local_append(id);\n}\n\nstatic int\nlocal_id(id)\n    ID id;\n{\n    int i, max;\n\n    if (lvtbl == 0) return Qfalse;\n    for (i=3, max=lvtbl->cnt+1; i<max; i++) {\n\tif (lvtbl->tbl[i] == id) return Qtrue;\n    }\n    return Qfalse;\n}\n\nstatic void\ntop_local_init()\n{\n    local_push(1);\n    lvtbl->cnt = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;\n    if (lvtbl->cnt > 0) {\n\tlvtbl->tbl = ALLOC_N(ID, lvtbl->cnt+3);\n\tMEMCPY(lvtbl->tbl, ruby_scope->local_tbl, ID, lvtbl->cnt+1);\n    }\n    else {\n\tlvtbl->tbl = 0;\n    }\n    if (ruby_dyna_vars)\n\tlvtbl->dlev = 1;\n    else\n\tlvtbl->dlev = 0;\n}\n\nstatic void\ntop_local_setup()\n{\n    int len = lvtbl->cnt;\n    int i;\n\n    if (len > 0) {\n\ti = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;\n\n\tif (i < len) {\n\t    if (i == 0 || (ruby_scope->flags & SCOPE_MALLOC) == 0) {\n\t\tVALUE *vars = ALLOC_N(VALUE, len+1);\n\t\tif (ruby_scope->local_vars) {\n\t\t    *vars++ = ruby_scope->local_vars[-1];\n\t\t    MEMCPY(vars, ruby_scope->local_vars, VALUE, i);\n\t\t    rb_mem_clear(vars+i, len-i);\n\t\t}\n\t\telse {\n\t\t    *vars++ = 0;\n\t\t    rb_mem_clear(vars, len);\n\t\t}\n\t\truby_scope->local_vars = vars;\n\t\truby_scope->flags |= SCOPE_MALLOC;\n\t    }\n\t    else {\n\t\tVALUE *vars = ruby_scope->local_vars-1;\n\t\tREALLOC_N(vars, VALUE, len+1);\n\t\truby_scope->local_vars = vars+1;\n\t\trb_mem_clear(ruby_scope->local_vars+i, len-i);\n\t    }\n\t    if (ruby_scope->local_tbl && ruby_scope->local_vars[-1] == 0) {\n               if (!(ruby_scope->flags & SCOPE_CLONE))\n                   xfree(ruby_scope->local_tbl);\n\t    }\n            ruby_scope->local_vars[-1] = 0; /* no reference needed */\n\t    ruby_scope->local_tbl = local_tbl();\n\t}\n    }\n    local_pop();\n}\n\n#define DVAR_USED FL_USER6\n\nstatic VALUE\ndyna_var_lookup(id)\n    ID id;\n{\n    struct RVarmap *vars = ruby_dyna_vars;\n\n    while (vars) {\n\tif (vars->id == id) {\n\t    FL_SET(vars, DVAR_USED);\n\t    return Qtrue;\n\t}\n\tvars = vars->next;\n    }\n    return Qfalse;\n}\n\nstatic struct RVarmap*\ndyna_push()\n{\n    struct RVarmap* vars = ruby_dyna_vars;\n\n    rb_dvar_push(0, 0);\n    lvtbl->dlev++;\n    return vars;\n}\n\nstatic void\ndyna_pop(vars)\n    struct RVarmap* vars;\n{\n    lvtbl->dlev--;\n    ruby_dyna_vars = vars;\n}\n\nstatic int\ndyna_in_block()\n{\n    return (lvtbl->dlev > 0);\n}\n\nstatic NODE *\ndyna_init(node, pre)\n    NODE *node;\n    struct RVarmap *pre;\n{\n    struct RVarmap *post = ruby_dyna_vars;\n    NODE *var;\n\n    if (!node || !post || pre == post) return node;\n    for (var = 0; post != pre && post->id; post = post->next) {\n\tif (FL_TEST(post, DVAR_USED)) {\n\t    var = NEW_DASGN_CURR(post->id, var);\n\t}\n    }\n    return block_append(var, node);\n}\n\nint\nruby_parser_stack_on_heap()\n{\n#if defined(YYMALLOC)\n    (void)rb_parser_realloc;\n    (void)rb_parser_calloc;\n    (void)nodetype;\n    (void)nodeline;\n    return Qfalse;\n#else\n    return Qtrue;\n#endif\n}\n\nvoid\nrb_gc_mark_parser()\n{\n#if defined YYMALLOC\n    rb_gc_mark((VALUE)parser_heap);\n#elif defined yystacksize\n    if (yyvsp) rb_gc_mark_locations((VALUE *)yyvs, (VALUE *)yyvsp);\n#endif\n}\n\nvoid\nrb_parser_append_print()\n{\n    ruby_eval_tree =\n\tblock_append(ruby_eval_tree,\n\t\t     NEW_FCALL(rb_intern(\"print\"),\n\t\t\t       NEW_ARRAY(NEW_GVAR(rb_intern(\"$_\")))));\n}\n\nvoid\nrb_parser_while_loop(chop, split)\n    int chop, split;\n{\n    if (split) {\n\truby_eval_tree =\n\t    block_append(NEW_GASGN(rb_intern(\"$F\"),\n\t\t\t\t   NEW_CALL(NEW_GVAR(rb_intern(\"$_\")),\n\t\t\t\t\t    rb_intern(\"split\"), 0)),\n\t\t\t\t   ruby_eval_tree);\n    }\n    if (chop) {\n\truby_eval_tree =\n\t    block_append(NEW_CALL(NEW_GVAR(rb_intern(\"$_\")),\n\t\t\t\t  rb_intern(\"chop!\"), 0), ruby_eval_tree);\n    }\n    ruby_eval_tree = NEW_OPT_N(ruby_eval_tree);\n}\n\nstatic struct {\n    ID token;\n    const char *name;\n} op_tbl[] = {\n    {tDOT2,\t\"..\"},\n    {tDOT3,\t\"...\"},\n    {'+',\t\"+\"},\n    {'-',\t\"-\"},\n    {'+',\t\"+(binary)\"},\n    {'-',\t\"-(binary)\"},\n    {'*',\t\"*\"},\n    {'/',\t\"/\"},\n    {'%',\t\"%\"},\n    {tPOW,\t\"**\"},\n    {tUPLUS,\t\"+@\"},\n    {tUMINUS,\t\"-@\"},\n    {tUPLUS,\t\"+(unary)\"},\n    {tUMINUS,\t\"-(unary)\"},\n    {'|',\t\"|\"},\n    {'^',\t\"^\"},\n    {'&',\t\"&\"},\n    {tCMP,\t\"<=>\"},\n    {'>',\t\">\"},\n    {tGEQ,\t\">=\"},\n    {'<',\t\"<\"},\n    {tLEQ,\t\"<=\"},\n    {tEQ,\t\"==\"},\n    {tEQQ,\t\"===\"},\n    {tNEQ,\t\"!=\"},\n    {tMATCH,\t\"=~\"},\n    {tNMATCH,\t\"!~\"},\n    {'!',\t\"!\"},\n    {'~',\t\"~\"},\n    {'!',\t\"!(unary)\"},\n    {'~',\t\"~(unary)\"},\n    {'!',\t\"!@\"},\n    {'~',\t\"~@\"},\n    {tAREF,\t\"[]\"},\n    {tASET,\t\"[]=\"},\n    {tLSHFT,\t\"<<\"},\n    {tRSHFT,\t\">>\"},\n    {tCOLON2,\t\"::\"},\n    {'`',\t\"`\"},\n    {0,\t0}\n};\n\nstatic st_table *sym_tbl;\nstatic st_table *sym_rev_tbl;\n\nvoid\nInit_sym()\n{\n    sym_tbl = st_init_strtable_with_size(200);\n    sym_rev_tbl = st_init_numtable_with_size(200);\n}\n\nstatic ID last_id = tLAST_TOKEN;\n\nstatic ID\ninternal_id()\n{\n    return ID_INTERNAL | (++last_id << ID_SCOPE_SHIFT);\n}\n\nstatic int\nis_special_global_name(m)\n    const char *m;\n{\n    switch (*m) {\n      case '~': case '*': case '$': case '?': case '!': case '@':\n      case '/': case '\\\\': case ';': case ',': case '.': case '=':\n      case ':': case '<': case '>': case '\\\"':\n      case '&': case '`': case '\\'': case '+':\n      case '0':\n\t++m;\n\tbreak;\n      case '-':\n\t++m;\n\tif (is_identchar(*m)) m += mbclen(*m);\n\tbreak;\n      default:\n\tif (!ISDIGIT(*m)) return 0;\n\tdo ++m; while (ISDIGIT(*m));\n    }\n    return !*m;\n}\n\nint\nrb_symname_p(name)\n    const char *name;\n{\n    const char *m = name;\n    int localid = Qfalse;\n\n    if (!m) return Qfalse;\n    switch (*m) {\n      case '\\0':\n\treturn Qfalse;\n\n      case '$':\n\tif (is_special_global_name(++m)) return Qtrue;\n\tgoto id;\n\n      case '@':\n\tif (*++m == '@') ++m;\n\tgoto id;\n\n      case '<':\n\tswitch (*++m) {\n\t  case '<': ++m; break;\n\t  case '=': if (*++m == '>') ++m; break;\n\t  default: break;\n\t}\n\tbreak;\n\n      case '>':\n\tswitch (*++m) {\n\t  case '>': case '=': ++m; break;\n\t}\n\tbreak;\n\n      case '=':\n\tswitch (*++m) {\n\t  case '~': ++m; break;\n\t  case '=': if (*++m == '=') ++m; break;\n\t  default: return Qfalse;\n\t}\n\tbreak;\n\n      case '*':\n\tif (*++m == '*') ++m;\n\tbreak;\n\n      case '+': case '-':\n\tif (*++m == '@') ++m;\n\tbreak;\n\n      case '|': case '^': case '&': case '/': case '%': case '~': case '`':\n\t++m;\n\tbreak;\n\n      case '[':\n\tif (*++m != ']') return Qfalse;\n\tif (*++m == '=') ++m;\n\tbreak;\n\n      default:\n\tlocalid = !ISUPPER(*m);\n      id:\n\tif (*m != '_' && !ISALPHA(*m) && !ismbchar(*m)) return Qfalse;\n\twhile (is_identchar(*m)) m += mbclen(*m);\n\tif (localid) {\n\t    switch (*m) {\n\t      case '!': case '?': case '=': ++m;\n\t    }\n\t}\n\tbreak;\n    }\n    return *m ? Qfalse : Qtrue;\n}\n\nint\nrb_sym_interned_p(str)\n    VALUE str;\n{\n    ID id;\n\n    if (st_lookup(sym_tbl, (st_data_t)RSTRING(str)->ptr, (st_data_t *)&id))\n\treturn Qtrue;\n    return Qfalse;\n}\n\nID\nrb_intern(name)\n    const char *name;\n{\n    const char *m = name;\n    ID id;\n    int last;\n\n    if (st_lookup(sym_tbl, (st_data_t)name, (st_data_t *)&id))\n\treturn id;\n\n    last = strlen(name)-1;\n    id = 0;\n    switch (*name) {\n      case '$':\n\tid |= ID_GLOBAL;\n\tif (is_special_global_name(++m)) goto new_id;\n\tbreak;\n      case '@':\n\tif (name[1] == '@') {\n\t    m++;\n\t    id |= ID_CLASS;\n\t}\n\telse {\n\t    id |= ID_INSTANCE;\n\t}\n\tm++;\n\tbreak;\n      default:\n\tif (name[0] != '_' && ISASCII(name[0]) && !ISALNUM(name[0])) {\n\t    /* operators */\n\t    int i;\n\n\t    for (i=0; op_tbl[i].token; i++) {\n\t\tif (*op_tbl[i].name == *name &&\n\t\t    strcmp(op_tbl[i].name, name) == 0) {\n\t\t    id = op_tbl[i].token;\n\t\t    goto id_regist;\n\t\t}\n\t    }\n\t}\n\n\tif (name[last] == '=') {\n\t    /* attribute assignment */\n\t    char *buf = ALLOCA_N(char,last+1);\n\n\t    strncpy(buf, name, last);\n\t    buf[last] = '\\0';\n\t    id = rb_intern(buf);\n\t    if (id > tLAST_TOKEN && !is_attrset_id(id)) {\n\t\tid = rb_id_attrset(id);\n\t\tgoto id_regist;\n\t    }\n\t    id = ID_ATTRSET;\n\t}\n\telse if (ISUPPER(name[0])) {\n\t    id = ID_CONST;\n        }\n\telse {\n\t    id = ID_LOCAL;\n\t}\n\tbreak;\n    }\n    if (!ISDIGIT(*m)) {\n\twhile (m <= name + last && is_identchar(*m)) {\n\t    m += mbclen(*m);\n\t}\n    }\n    if (*m) id = ID_JUNK;\n  new_id:\n    id |= ++last_id << ID_SCOPE_SHIFT;\n  id_regist:\n    name = strdup(name);\n    st_add_direct(sym_tbl, (st_data_t)name, id);\n    st_add_direct(sym_rev_tbl, id, (st_data_t)name);\n    return id;\n}\n\nconst char *\nrb_id2name(id)\n    ID id;\n{\n    const char *name;\n    st_data_t data;\n\n    if (id < tLAST_TOKEN) {\n\tint i;\n\n\tfor (i=0; op_tbl[i].token; i++) {\n\t    if (op_tbl[i].token == id)\n\t\treturn op_tbl[i].name;\n\t}\n    }\n\n    if (st_lookup(sym_rev_tbl, id, &data))\n\treturn (char *)data;\n\n    if (is_attrset_id(id)) {\n\tID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;\n\n      again:\n\tname = rb_id2name(id2);\n\tif (name) {\n\t    char *buf = ALLOCA_N(char, strlen(name)+2);\n\n\t    strcpy(buf, name);\n\t    strcat(buf, \"=\");\n\t    rb_intern(buf);\n\t    return rb_id2name(id);\n\t}\n\tif (is_local_id(id2)) {\n\t    id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;\n\t    goto again;\n\t}\n    }\n    return 0;\n}\n\nstatic int\nsymbols_i(key, value, ary)\n    char *key;\n    ID value;\n    VALUE ary;\n{\n    rb_ary_push(ary, ID2SYM(value));\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     Symbol.all_symbols    => array\n *\n *  Returns an array of all the symbols currently in Ruby's symbol\n *  table.\n *\n *     Symbol.all_symbols.size    #=> 903\n *     Symbol.all_symbols[1,20]   #=> [:floor, :ARGV, :Binding, :symlink,\n *                                     :chown, :EOFError, :$;, :String,\n *                                     :LOCK_SH, :\"setuid?\", :$<,\n *                                     :default_proc, :compact, :extend,\n *                                     :Tms, :getwd, :$=, :ThreadGroup,\n *                                     :wait2, :$>]\n */\n\nVALUE\nrb_sym_all_symbols()\n{\n    VALUE ary = rb_ary_new2(sym_tbl->num_entries);\n\n    st_foreach(sym_tbl, symbols_i, ary);\n    return ary;\n}\n\nint\nrb_is_const_id(id)\n    ID id;\n{\n    if (is_const_id(id)) return Qtrue;\n    return Qfalse;\n}\n\nint\nrb_is_class_id(id)\n    ID id;\n{\n    if (is_class_id(id)) return Qtrue;\n    return Qfalse;\n}\n\nint\nrb_is_instance_id(id)\n    ID id;\n{\n    if (is_instance_id(id)) return Qtrue;\n    return Qfalse;\n}\n\nint\nrb_is_local_id(id)\n    ID id;\n{\n    if (is_local_id(id)) return Qtrue;\n    return Qfalse;\n}\n\nint\nrb_is_junk_id(id)\n    ID id;\n{\n    if (is_junk_id(id)) return Qtrue;\n    return Qfalse;\n}\n\nstatic void\nspecial_local_set(c, val)\n    char c;\n    VALUE val;\n{\n    int cnt;\n\n    top_local_init();\n    cnt = local_cnt(c);\n    top_local_setup();\n    ruby_scope->local_vars[cnt] = val;\n}\n\nVALUE\nrb_backref_get()\n{\n    VALUE *var = rb_svar(1);\n    if (var) {\n\treturn *var;\n    }\n    return Qnil;\n}\n\nvoid\nrb_backref_set(val)\n    VALUE val;\n{\n    VALUE *var = rb_svar(1);\n    if (var) {\n\t*var = val;\n    }\n    else {\n\tspecial_local_set('~', val);\n    }\n}\n\nVALUE\nrb_lastline_get()\n{\n    VALUE *var = rb_svar(0);\n    if (var) {\n\treturn *var;\n    }\n    return Qnil;\n}\n\nvoid\nrb_lastline_set(val)\n    VALUE val;\n{\n    VALUE *var = rb_svar(0);\n    if (var) {\n\t*var = val;\n    }\n    else {\n\tspecial_local_set('_', val);\n    }\n}\n\n#ifdef YYMALLOC\n#define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))\n#define NEWHEAP() NEW_NODE_EDEN(NODE_ALLOCA, 0, (VALUE)parser_heap, 0)\n#define ADD2HEAP(n, c, p) ((parser_heap = (n))->u1.node = (p), \\\n\t\t\t   (n)->u3.cnt = (c), (p))\n\nstatic void *\nrb_parser_malloc(size)\n    size_t size;\n{\n    size_t cnt = HEAPCNT(1, size);\n    NODE *n = NEWHEAP();\n    void *ptr = xmalloc(size);\n\n    return ADD2HEAP(n, cnt, ptr);\n}\n\nstatic void *\nrb_parser_calloc(nelem, size)\n    size_t nelem, size;\n{\n    size_t cnt = HEAPCNT(nelem, size);\n    NODE *n = NEWHEAP();\n    void *ptr = xcalloc(nelem, size);\n\n    return ADD2HEAP(n, cnt, ptr);\n}\n\nstatic void *\nrb_parser_realloc(ptr, size)\n    void *ptr;\n    size_t size;\n{\n    NODE *n;\n    size_t cnt = HEAPCNT(1, size);\n\n    if (ptr && (n = parser_heap) != NULL) {\n\tdo {\n\t    if (n->u1.node == ptr) {\n\t\tn->u1.node = ptr = xrealloc(ptr, size);\n\t\tif (n->u3.cnt) n->u3.cnt = cnt;\n\t\treturn ptr;\n\t    }\n\t} while ((n = n->u2.node) != NULL);\n    }\n    n = NEWHEAP();\n    ptr = xrealloc(ptr, size);\n    return ADD2HEAP(n, cnt, ptr);\n}\n\nstatic void\nrb_parser_free(ptr)\n    void *ptr;\n{\n    NODE **prev = &parser_heap, *n;\n\n    while ((n = *prev) != 0) {\n\tif (n->u1.node == ptr) {\n\t    *prev = n->u2.node;\n\t    rb_gc_force_recycle((VALUE)n);\n\t    break;\n\t}\n\tprev = &n->u2.node;\n    }\n    xfree(ptr);\n}\n#endif\n"
  },
  {
    "path": "pointerset.c",
    "content": "#include \"config.h\"\n#include \"defines.h\"\n#ifdef HAVE_STDLIB_H\n\t#include <stdlib.h>\n#endif\n#include <string.h>\n#include \"pointerset.h\"\n\n\ntypedef struct _PointerSetEntry PointerSetEntry;\n\nstruct _PointerSet {\n\tunsigned int num_bins;\n\tunsigned int num_entries;\n\tPointerSetEntry **bins;\n};\n\nstruct _PointerSetEntry {\n\tPointerSetElement element;\n\tPointerSetEntry *next;\n};\n\n/* Table of prime numbers 2^n+a, 2<=n<=30. */\nstatic const long primes[] = {\n\t8 + 3,\n\t16 + 3,\n\t32 + 5,\n\t64 + 3,\n\t128 + 3,\n\t256 + 27,\n\t512 + 9,\n\t1024 + 9,\n\t2048 + 5,\n\t4096 + 3,\n\t8192 + 27,\n\t16384 + 43,\n\t32768 + 3,\n\t65536 + 45,\n\t131072 + 29,\n\t262144 + 3,\n\t524288 + 21,\n\t1048576 + 7,\n\t2097152 + 17,\n\t4194304 + 15,\n\t8388608 + 9,\n\t16777216 + 43,\n\t33554432 + 35,\n\t67108864 + 15,\n\t134217728 + 29,\n\t268435456 + 3,\n\t536870912 + 11,\n\t1073741824 + 85,\n\t0\n};\n\n\n/* The percentage of nonempty buckets, before increasing the number of bins. 1.0 == 100%\n * A value larger than 1.0 means that it's very likely that some buckets contain more than\n * 1 entry.\n */\n#define MAX_LOAD_FACTOR 2.0\n/* The default for the number of bins allocated initially. Must be a prime number. */\n#define DEFAULT_TABLE_SIZE 11\n/* MINSIZE is the minimum size of a dictionary. */\n#define MINSIZE 8\n\n#if SIZEOF_LONG == SIZEOF_VOIDP\n\ttypedef unsigned long PointerInt;\n#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP\n\ttypedef unsigned LONG_LONG PointerInt;\n#else\n\t#error ---->> pointerset.c requires sizeof(void*) == sizeof(long) to be compiled. <<---\n\t-\n#endif\n\n#define alloc(type) (type*)malloc((unsigned)sizeof(type))\n#define Calloc(n,s) (char*)calloc((n),(s))\n\n#define HASH(element, num_bins) ((PointerInt) element) % num_bins\n#define FIND_ENTRY(set, entry, element) \\\n\tdo { \\\n\t\tunsigned int bin_pos = HASH(element, set->num_bins); \\\n\t\tentry = (set)->bins[bin_pos]; \\\n\t\twhile (entry != NULL && entry->element != element) { \\\n\t\t\tentry = entry->next; \\\n\t\t} \\\n\t} while (0)\n\n\nstatic int\nnew_size(int size)\n{\n\tint i;\n\tint newsize;\n\n\tfor (i = 0, newsize = MINSIZE;\n\t     i < sizeof(primes)/sizeof(primes[0]);\n\t     i++, newsize <<= 1)\n\t{\n\t\tif (newsize > size)\n\t\t\treturn primes[i];\n\t}\n\t/* Ran out of polynomials */\n\treturn -1;\t/* should raise exception */\n}\n\nPointerSet *\npointer_set_new()\n{\n\tPointerSet *set;\n\n\tset = alloc(PointerSet);\n\tif (set != NULL) {\n\t\tset->num_entries = 0;\n\t\tset->num_bins = DEFAULT_TABLE_SIZE;\n\t\tset->bins = (PointerSetEntry **) Calloc(DEFAULT_TABLE_SIZE, sizeof(PointerSetEntry *));\n\t}\n\treturn set;\n}\n\nstatic void\nfree_bin_contents(PointerSet *set)\n{\n\tPointerSetEntry *entry, *next;\n\tint i;\n\n\tfor(i = 0; i < set->num_bins; i++) {\n\t\tentry = set->bins[i];\n\t\twhile (entry != NULL) {\n\t\t\tnext = entry->next;\n\t\t\tfree(entry);\n\t\t\tentry = next;\n\t\t}\n\t\tset->bins[i] = NULL;\n\t}\n\tset->num_entries = 0;\n}\n\nvoid\npointer_set_free(PointerSet *set)\n{\n\tfree_bin_contents(set);\n\tfree(set->bins);\n\tfree(set);\n}\n\nint\npointer_set_contains(PointerSet *set, PointerSetElement element)\n{\n\tPointerSetEntry *entry;\n\tFIND_ENTRY(set, entry, element);\n\treturn entry != NULL;\n}\n\nstatic void\nrehash(PointerSet *set, int new_num_bins)\n{\n\tPointerSetEntry *entry, **new_bins;\n\tint i;\n\n\tnew_bins = (PointerSetEntry **) Calloc(new_num_bins, sizeof(PointerSetEntry *));\n\tfor (i = 0; i < set->num_bins; i++) {\n\t\tentry = set->bins[i];\n\t\twhile (entry != NULL) {\n\t\t\tunsigned int new_bin_pos;\n\t\t\tPointerSetEntry *next;\n\n\t\t\tnew_bin_pos = HASH(entry->element, new_num_bins);\n\t\t\tnext = entry->next;\n\t\t\tentry->next = new_bins[new_bin_pos];\n\t\t\tnew_bins[new_bin_pos] = entry;\n\t\t\tentry = next;\n\t\t}\n\t}\n\tfree(set->bins);\n\tset->num_bins = new_num_bins;\n\tset->bins = new_bins;\n}\n\nvoid\npointer_set_insert(PointerSet *set, PointerSetElement element)\n{\n\tPointerSetEntry *entry;\n\n\tFIND_ENTRY(set, entry, element);\n\tif (entry == NULL) {\n\t\tunsigned int bin_pos;\n\n\t\tif (set->num_entries / (double) set->num_bins > MAX_LOAD_FACTOR) {\n\t\t\t/* Increase number of bins to the next prime number. */\n\t\t\trehash(set, new_size(set->num_bins + 1));\n\t\t}\n\n\t\tbin_pos = HASH(element, set->num_bins);\n\t\tentry = malloc(sizeof(PointerSetEntry));\n\t\tentry->element = element;\n\t\tentry->next = set->bins[bin_pos];\n\t\tset->bins[bin_pos] = entry;\n\t\tset->num_entries++;\n\t}\n}\n\nvoid\npointer_set_delete(PointerSet *set, PointerSetElement element)\n{\n\tunsigned int bin_pos;\n\tPointerSetEntry *entry, *prev;\n\n\tbin_pos = HASH(element, set->num_bins);\n\tentry = set->bins[bin_pos];\n\tprev = NULL;\n\twhile (entry != NULL && entry->element != element) {\n\t\tprev = entry;\n\t\tentry = entry->next;\n\t}\n\tif (entry != NULL) {\n\t\tif (prev != NULL) {\n\t\t\tprev->next = entry->next;\n\t\t} else {\n\t\t\tset->bins[bin_pos] = entry->next;\n\t\t}\n\t\tfree(entry);\n\t\tset->num_entries--;\n\t\t/* TODO: is it a good idea to reduce the number of bins? */\n\t}\n}\n\nvoid\npointer_set_reset(PointerSet *set)\n{\n\tfree_bin_contents(set);\n\tset->bins = realloc(set->bins, sizeof(PointerSetEntry *) * DEFAULT_TABLE_SIZE);\n\tset->num_bins = DEFAULT_TABLE_SIZE;\n\tmemset(set->bins, 0, sizeof(PointerSetEntry *) * DEFAULT_TABLE_SIZE);\n}\n\nunsigned int\npointer_set_get_size(PointerSet *set)\n{\n\treturn set->num_entries;\n}\n\nunsigned int\npointer_set_get_capacity(PointerSet *set)\n{\n\treturn set->num_bins;\n}\n"
  },
  {
    "path": "pointerset.h",
    "content": "/**\n * A specialized set data structure, designed to only contain pointers.\n * It will grow and shrink dynamically.\n */\n#ifndef _POINTER_SET_H_\n#define _POINTER_SET_H_\n\ntypedef void * PointerSetElement;\ntypedef struct _PointerSet PointerSet;\n\n/**\n * Create a new, empty pointer set.\n */\nPointerSet   *pointer_set_new();\n\n/**\n * Free the given pointer set.\n */\nvoid         pointer_set_free(PointerSet *set);\n\n/**\n * Insert the given pointer into the pointer set. The data that the\n * pointer pointers to is not touched, so <tt>element</tt> may even be\n * an invalid pointer.\n */\nvoid         pointer_set_insert(PointerSet *set, PointerSetElement element);\n\n/**\n * Remove the given pointer from the pointer set. Nothing will happen\n * if the pointer isn't already in the set.\n */\nvoid         pointer_set_delete(PointerSet *set, PointerSetElement element);\n\n/**\n * Check whether the given pointer is in the pointer set.\n */\nint          pointer_set_contains(PointerSet *set, PointerSetElement element);\n\n/**\n * Clear the pointer set.\n */\nvoid         pointer_set_reset(PointerSet *set);\n\n/**\n * Return the number of pointers in the pointer set.\n */\nunsigned int pointer_set_get_size(PointerSet *set);\n\n/**\n * Return the amount of space that is used to store the pointers in the set.\n *\n * @invariant pointer_set_get_capacity(set) >= pointer_set_get_size(set)\n */\nunsigned int pointer_set_get_capacity(PointerSet *set);\n\n#endif /* _POINTER_SET_H_ */\n"
  },
  {
    "path": "prec.c",
    "content": "/**********************************************************************\n\n  prec.c -\n\n  $Author$\n  $Date$\n  created at: Tue Jan 26 02:40:41 2000\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\nVALUE rb_mPrecision;\n\nstatic ID prc_pr, prc_if;\n\n\n/*\n *  call-seq:\n *   num.prec(klass)   => a_klass\n *\n *  Converts _self_ into an instance of _klass_. By default,\n *  +prec+ invokes \n *\n *     klass.induced_from(num)\n *\n *  and returns its value. So, if <code>klass.induced_from</code>\n *  doesn't return an instance of _klass_, it will be necessary\n *  to reimplement +prec+.\n */\n\nstatic VALUE\nprec_prec(x, klass)\n    VALUE x, klass;\n{\n    return rb_funcall(klass, prc_if, 1, x);\n}\n\n/*\n *  call-seq:\n *    num.prec_i  =>  Integer\n *\n *  Returns an +Integer+ converted from _num_. It is equivalent \n *  to <code>prec(Integer)</code>.\n */\n\nstatic VALUE\nprec_prec_i(x)\n    VALUE x;\n{\n    VALUE klass = rb_cInteger;\n\n    return rb_funcall(x, prc_pr, 1, klass);\n}\n\n/*\n *  call-seq:\n *    num.prec_f  =>  Float\n *\n *  Returns a +Float+ converted from _num_. It is equivalent \n *  to <code>prec(Float)</code>.\n */\n\nstatic VALUE\nprec_prec_f(x)\n    VALUE x;\n{\n    VALUE klass = rb_cFloat;\n\n    return rb_funcall(x, prc_pr, 1, klass);\n}\n\n/*\n * call-seq:\n *   Mod.induced_from(number)  =>  a_mod\n * \n * Creates an instance of mod from. This method is overridden\n * by concrete +Numeric+ classes, so that (for example)\n *\n *   Fixnum.induced_from(9.9)   #=>  9\n *\n * Note that a use of +prec+ in a redefinition may cause\n * an infinite loop.\n */\n\nstatic VALUE\nprec_induced_from(module, x)\n    VALUE module, x;\n{\n    rb_raise(rb_eTypeError, \"undefined conversion from %s into %s\",\n            rb_obj_classname(x), rb_class2name(module));\n    return Qnil;\t\t/* not reached */\n}\n\n/*\n * call_seq:\n *   included\n *\n * When the +Precision+ module is mixed-in to a class, this +included+\n * method is used to add our default +induced_from+ implementation\n * to the host class.\n */\n\nstatic VALUE\nprec_included(module, include)\n    VALUE module, include;\n{\n    switch (TYPE(include)) {\n      case T_CLASS:\n      case T_MODULE:\n       break;\n      default:\n       Check_Type(include, T_CLASS);\n       break;\n    }\n    rb_define_singleton_method(include, \"induced_from\", prec_induced_from, 1);\n    return module;\n}\n\n/*\n * Precision is a mixin for concrete numeric classes with\n * precision.  Here, `precision' means the fineness of approximation\n * of a real number, so, this module should not be included into\n * anything which is not a subset of Real (so it should not be\n * included in classes such as +Complex+ or +Matrix+).\n*/\n\nvoid\nInit_Precision()\n{\n    rb_mPrecision = rb_define_module(\"Precision\");\n    rb_define_singleton_method(rb_mPrecision, \"included\", prec_included, 1);\n    rb_define_method(rb_mPrecision, \"prec\", prec_prec, 1);\n    rb_define_method(rb_mPrecision, \"prec_i\", prec_prec_i, 0);\n    rb_define_method(rb_mPrecision, \"prec_f\", prec_prec_f, 0);\n\n    prc_pr = rb_intern(\"prec\");\n    prc_if = rb_intern(\"induced_from\");\n}\n"
  },
  {
    "path": "process.c",
    "content": "/**********************************************************************\n\n  process.c -\n\n  $Author$\n  $Date$\n  created at: Tue Aug 10 14:30:50 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n#include <stdio.h>\n#include <errno.h>\n#include <signal.h>\n#ifdef HAVE_STDLIB_H\n#include <stdlib.h>\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef __DJGPP__\n#include <process.h>\n#endif\n\n#include <time.h>\n#include <ctype.h>\n\n#ifndef EXIT_SUCCESS\n#define EXIT_SUCCESS 0\n#endif\n#ifndef EXIT_FAILURE\n#define EXIT_FAILURE 1\n#endif\n\nstruct timeval rb_time_interval _((VALUE));\n\n#ifdef HAVE_SYS_WAIT_H\n# include <sys/wait.h>\n#endif\n#ifdef HAVE_SYS_RESOURCE_H\n# include <sys/resource.h>\n#endif\n#include \"st.h\"\n\n#ifdef __EMX__\n#undef HAVE_GETPGRP\n#endif\n\n#ifdef HAVE_SYS_TIMES_H\n#include <sys/times.h>\n#endif\n\n#ifdef HAVE_GRP_H\n#include <grp.h>\n#endif\n\n#if defined(HAVE_TIMES) || defined(_WIN32)\nstatic VALUE S_Tms;\n#endif\n\n#ifndef WIFEXITED\n#define WIFEXITED(w)    (((w) & 0xff) == 0)\n#endif\n#ifndef WIFSIGNALED\n#define WIFSIGNALED(w)  (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))\n#endif\n#ifndef WIFSTOPPED\n#define WIFSTOPPED(w)   (((w) & 0xff) == 0x7f)\n#endif\n#ifndef WEXITSTATUS\n#define WEXITSTATUS(w)  (((w) >> 8) & 0xff)\n#endif\n#ifndef WTERMSIG\n#define WTERMSIG(w)     ((w) & 0x7f)\n#endif\n#ifndef WSTOPSIG\n#define WSTOPSIG        WEXITSTATUS\n#endif\n\n#if defined(__APPLE__) && ( defined(__MACH__) || defined(__DARWIN__) ) && !defined(__MacOS_X__)\n#define __MacOS_X__ 1\n#endif\n\n#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)\n#define HAVE_44BSD_SETUID 1\n#define HAVE_44BSD_SETGID 1\n#endif\n\n#ifdef __NetBSD__\n#undef HAVE_SETRUID\n#undef HAVE_SETRGID\n#endif\n\n#ifdef BROKEN_SETREUID\n#define setreuid ruby_setreuid\n#endif\n#ifdef BROKEN_SETREGID\n#define setregid ruby_setregid\n#endif\n\n#if defined(HAVE_44BSD_SETUID) || defined(__MacOS_X__)\n#if !defined(USE_SETREUID) && !defined(BROKEN_SETREUID)\n#define OBSOLETE_SETREUID 1\n#endif\n#if !defined(USE_SETREGID) && !defined(BROKEN_SETREGID)\n#define OBSOLETE_SETREGID 1\n#endif\n#endif\n\n#define preserving_errno(stmts) \\\n\tdo {int saved_errno = errno; stmts; errno = saved_errno;} while (0)\n\n\n/*\n *  call-seq:\n *     Process.pid   => fixnum\n *\n *  Returns the process id of this process. Not available on all\n *  platforms.\n *\n *     Process.pid   #=> 27415\n */\n\nstatic VALUE\nget_pid()\n{\n    rb_secure(2);\n    return INT2FIX(getpid());\n}\n\n\n/*\n *  call-seq:\n *     Process.ppid   => fixnum\n *\n *  Returns the process id of the parent of this process. Always\n *  returns 0 on NT. Not available on all platforms.\n *\n *     puts \"I am #{Process.pid}\"\n *     Process.fork { puts \"Dad is #{Process.ppid}\" }\n *\n *  <em>produces:</em>\n *\n *     I am 27417\n *     Dad is 27417\n */\n\nstatic VALUE\nget_ppid()\n{\n    rb_secure(2);\n#ifdef _WIN32\n    return INT2FIX(0);\n#else\n    return INT2FIX(getppid());\n#endif\n}\n\n\n/*********************************************************************\n *\n * Document-class: Process::Status\n *\n *  <code>Process::Status</code> encapsulates the information on the\n *  status of a running or terminated system process. The built-in\n *  variable <code>$?</code> is either +nil+ or a\n *  <code>Process::Status</code> object.\n *\n *     fork { exit 99 }   #=> 26557\n *     Process.wait       #=> 26557\n *     $?.class           #=> Process::Status\n *     $?.to_i            #=> 25344\n *     $? >> 8            #=> 99\n *     $?.stopped?        #=> false\n *     $?.exited?         #=> true\n *     $?.exitstatus      #=> 99\n *\n *  Posix systems record information on processes using a 16-bit\n *  integer.  The lower bits record the process status (stopped,\n *  exited, signaled) and the upper bits possibly contain additional\n *  information (for example the program's return code in the case of\n *  exited processes). Pre Ruby 1.8, these bits were exposed directly\n *  to the Ruby program. Ruby now encapsulates these in a\n *  <code>Process::Status</code> object. To maximize compatibility,\n *  however, these objects retain a bit-oriented interface. In the\n *  descriptions that follow, when we talk about the integer value of\n *  _stat_, we're referring to this 16 bit value.\n */\n\nstatic VALUE rb_cProcStatus;\nVALUE rb_last_status = Qnil;\n\nstatic void\nlast_status_set(status, pid)\n    int status, pid;\n{\n    rb_last_status = rb_obj_alloc(rb_cProcStatus);\n    rb_iv_set(rb_last_status, \"status\", INT2FIX(status));\n    rb_iv_set(rb_last_status, \"pid\", INT2FIX(pid));\n}\n\n\n/*\n *  call-seq:\n *     stat.to_i     => fixnum\n *     stat.to_int   => fixnum\n *\n *  Returns the bits in _stat_ as a <code>Fixnum</code>. Poking\n *  around in these bits is platform dependent.\n *\n *     fork { exit 0xab }         #=> 26566\n *     Process.wait               #=> 26566\n *     sprintf('%04x', $?.to_i)   #=> \"ab00\"\n */\n\nstatic VALUE\npst_to_i(st)\n    VALUE st;\n{\n    return rb_iv_get(st, \"status\");\n}\n\n\n/*\n *  call-seq:\n *     stat.to_s   => string\n *\n *  Equivalent to _stat_<code>.to_i.to_s</code>.\n */\n\nstatic VALUE\npst_to_s(st)\n    VALUE st;\n{\n    return rb_fix2str(pst_to_i(st), 10);\n}\n\n\n/*\n *  call-seq:\n *     stat.pid   => fixnum\n *\n *  Returns the process ID that this status object represents.\n *\n *     fork { exit }   #=> 26569\n *     Process.wait    #=> 26569\n *     $?.pid          #=> 26569\n */\n\nstatic VALUE\npst_pid(st)\n    VALUE st;\n{\n    return rb_iv_get(st, \"pid\");\n}\n\n\n/*\n *  call-seq:\n *     stat.inspect   => string\n *\n *  Override the inspection method.\n */\n\nstatic VALUE\npst_inspect(st)\n    VALUE st;\n{\n    VALUE pid;\n    int status;\n    VALUE str;\n    char buf[256];\n\n    pid = pst_pid(st);\n    status = NUM2INT(st);\n\n    snprintf(buf, sizeof(buf), \"#<%s: pid=%ld\", rb_class2name(CLASS_OF(st)), NUM2LONG(pid));\n    str = rb_str_new2(buf);\n    if (WIFSTOPPED(status)) {\n\tint stopsig = WSTOPSIG(status);\n\tconst char *signame = ruby_signal_name(stopsig);\n\tif (signame) {\n\t    snprintf(buf, sizeof(buf), \",stopped(SIG%s=%d)\", signame, stopsig);\n\t}\n\telse {\n\t    snprintf(buf, sizeof(buf), \",stopped(%d)\", stopsig);\n\t}\n\trb_str_cat2(str, buf);\n    }\n    if (WIFSIGNALED(status)) {\n\tint termsig = WTERMSIG(status);\n\tconst char *signame = ruby_signal_name(termsig);\n\tif (signame) {\n\t    snprintf(buf, sizeof(buf), \",signaled(SIG%s=%d)\", signame, termsig);\n\t}\n\telse {\n\t    snprintf(buf, sizeof(buf), \",signaled(%d)\", termsig);\n\t}\n\trb_str_cat2(str, buf);\n    }\n    if (WIFEXITED(status)) {\n\tsnprintf(buf, sizeof(buf), \",exited(%d)\", WEXITSTATUS(status));\n\trb_str_cat2(str, buf);\n    }\n#ifdef WCOREDUMP\n    if (WCOREDUMP(status)) {\n\trb_str_cat2(str, \",coredumped\");\n    }\n#endif\n    rb_str_cat2(str, \">\");\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     stat == other   => true or false\n *\n *  Returns +true+ if the integer value of _stat_\n *  equals <em>other</em>.\n */\n\nstatic VALUE\npst_equal(st1, st2)\n    VALUE st1, st2;\n{\n    if (st1 == st2) return Qtrue;\n    return rb_equal(pst_to_i(st1), st2);\n}\n\n\n/*\n *  call-seq:\n *     stat & num   => fixnum\n *\n *  Logical AND of the bits in _stat_ with <em>num</em>.\n *\n *     fork { exit 0x37 }\n *     Process.wait\n *     sprintf('%04x', $?.to_i)       #=> \"3700\"\n *     sprintf('%04x', $? & 0x1e00)   #=> \"1600\"\n */\n\nstatic VALUE\npst_bitand(st1, st2)\n    VALUE st1, st2;\n{\n    int status = NUM2INT(st1) & NUM2INT(st2);\n\n    return INT2NUM(status);\n}\n\n\n/*\n *  call-seq:\n *     stat >> num   => fixnum\n *\n *  Shift the bits in _stat_ right <em>num</em> places.\n *\n *     fork { exit 99 }   #=> 26563\n *     Process.wait       #=> 26563\n *     $?.to_i            #=> 25344\n *     $? >> 8            #=> 99\n */\n\nstatic VALUE\npst_rshift(st1, st2)\n    VALUE st1, st2;\n{\n    int status = NUM2INT(st1) >> NUM2INT(st2);\n\n    return INT2NUM(status);\n}\n\n\n/*\n *  call-seq:\n *     stat.stopped?   => true or false\n *\n *  Returns +true+ if this process is stopped. This is only\n *  returned if the corresponding <code>wait</code> call had the\n *  <code>WUNTRACED</code> flag set.\n */\n\nstatic VALUE\npst_wifstopped(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (WIFSTOPPED(status))\n\treturn Qtrue;\n    else\n\treturn Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     stat.stopsig   => fixnum or nil\n *\n *  Returns the number of the signal that caused _stat_ to stop\n *  (or +nil+ if self is not stopped).\n */\n\nstatic VALUE\npst_wstopsig(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (WIFSTOPPED(status))\n\treturn INT2NUM(WSTOPSIG(status));\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     stat.signaled?   => true or false\n *\n *  Returns +true+ if _stat_ terminated because of\n *  an uncaught signal.\n */\n\nstatic VALUE\npst_wifsignaled(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (WIFSIGNALED(status))\n\treturn Qtrue;\n    else\n\treturn Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     stat.termsig   => fixnum or nil\n *\n *  Returns the number of the signal that caused _stat_ to\n *  terminate (or +nil+ if self was not terminated by an\n *  uncaught signal).\n */\n\nstatic VALUE\npst_wtermsig(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (WIFSIGNALED(status))\n\treturn INT2NUM(WTERMSIG(status));\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     stat.exited?   => true or false\n *\n *  Returns +true+ if _stat_ exited normally (for\n *  example using an <code>exit()</code> call or finishing the\n *  program).\n */\n\nstatic VALUE\npst_wifexited(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (WIFEXITED(status))\n\treturn Qtrue;\n    else\n\treturn Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     stat.exitstatus   => fixnum or nil\n *\n *  Returns the least significant eight bits of the return code of\n *  _stat_. Only available if <code>exited?</code> is\n *  +true+.\n *\n *     fork { }           #=> 26572\n *     Process.wait       #=> 26572\n *     $?.exited?         #=> true\n *     $?.exitstatus      #=> 0\n *\n *     fork { exit 99 }   #=> 26573\n *     Process.wait       #=> 26573\n *     $?.exited?         #=> true\n *     $?.exitstatus      #=> 99\n */\n\nstatic VALUE\npst_wexitstatus(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (WIFEXITED(status))\n\treturn INT2NUM(WEXITSTATUS(status));\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     stat.success?   => true, false or nil\n *\n *  Returns +true+ if _stat_ is successful, +false+ if not.\n *  Returns +nil+ if <code>exited?</code> is not +true+.\n */\n\nstatic VALUE\npst_success_p(st)\n    VALUE st;\n{\n    int status = NUM2INT(st);\n\n    if (!WIFEXITED(status))\n\treturn Qnil;\n    return WEXITSTATUS(status) == EXIT_SUCCESS ? Qtrue : Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     stat.coredump?   => true or false\n *\n *  Returns +true+ if _stat_ generated a coredump\n *  when it terminated. Not available on all platforms.\n */\n\nstatic VALUE\npst_wcoredump(st)\n    VALUE st;\n{\n#ifdef WCOREDUMP\n    int status = NUM2INT(st);\n\n    if (WCOREDUMP(status))\n\treturn Qtrue;\n    else\n\treturn Qfalse;\n#else\n    return Qfalse;\n#endif\n}\n\n#if !defined(HAVE_WAITPID) && !defined(HAVE_WAIT4)\n#define NO_WAITPID\nstatic st_table *pid_tbl;\n#endif\n\nint\nrb_waitpid(pid, st, flags)\n    int pid;\n    int *st;\n    int flags;\n{\n    int result;\n#ifndef NO_WAITPID\n    int oflags = flags;\n    if (!rb_thread_alone()) {\t/* there're other threads to run */\n\tflags |= WNOHANG;\n    }\n\n  retry:\n    TRAP_BEG;\n#ifdef HAVE_WAITPID\n    result = waitpid(pid, st, flags);\n#else  /* HAVE_WAIT4 */\n    result = wait4(pid, st, flags, NULL);\n#endif\n    TRAP_END;\n    if (result < 0) {\n\tif (errno == EINTR) {\n\t    rb_thread_polling();\n\t    goto retry;\n\t}\n\treturn -1;\n    }\n    if (result == 0) {\n\tif (oflags & WNOHANG) return 0;\n\trb_thread_polling();\n\tif (rb_thread_alone()) flags = oflags;\n\tgoto retry;\n    }\n#else  /* NO_WAITPID */\n    if (pid_tbl && st_lookup(pid_tbl, pid, st)) {\n\tlast_status_set(*st, pid);\n\tst_delete(pid_tbl, (st_data_t*)&pid, NULL);\n\treturn pid;\n    }\n\n    if (flags) {\n\trb_raise(rb_eArgError, \"can't do waitpid with flags\");\n    }\n\n    for (;;) {\n\tTRAP_BEG;\n\tresult = wait(st);\n\tTRAP_END;\n\tif (result < 0) {\n\t    if (errno == EINTR) {\n\t\trb_thread_schedule();\n\t\tcontinue;\n\t    }\n\t    return -1;\n\t}\n\tif (result == pid) {\n\t    break;\n\t}\n\tif (!pid_tbl)\n\t    pid_tbl = st_init_numtable();\n\tst_insert(pid_tbl, pid, st);\n\tif (!rb_thread_alone()) rb_thread_schedule();\n    }\n#endif\n    if (result > 0) {\n\tlast_status_set(*st, result);\n    }\n    return result;\n}\n\n#ifdef NO_WAITPID\nstruct wait_data {\n    int pid;\n    int status;\n};\n\nstatic int\nwait_each(pid, status, data)\n    int pid, status;\n    struct wait_data *data;\n{\n    if (data->status != -1) return ST_STOP;\n\n    data->pid = pid;\n    data->status = status;\n    return ST_DELETE;\n}\n\nstatic int\nwaitall_each(pid, status, ary)\n    int pid, status;\n    VALUE ary;\n{\n    last_status_set(status, pid);\n    rb_ary_push(ary, rb_assoc_new(INT2NUM(pid), rb_last_status));\n    return ST_DELETE;\n}\n#endif\n\n\n/* [MG]:FIXME: I wasn't sure how this should be done, since ::wait()\n   has historically been documented as if it didn't take any arguments\n   despite the fact that it's just an alias for ::waitpid(). The way I\n   have it below is more truthful, but a little confusing.\n\n   I also took the liberty of putting in the pid values, as they're\n   pretty useful, and it looked as if the original 'ri' output was\n   supposed to contain them after \"[...]depending on the value of\n   aPid:\".\n\n   The 'ansi' and 'bs' formats of the ri output don't display the\n   definition list for some reason, but the plain text one does.\n */\n\n/*\n *  call-seq:\n *     Process.wait()                     => fixnum\n *     Process.wait(pid=-1, flags=0)      => fixnum\n *     Process.waitpid(pid=-1, flags=0)   => fixnum\n *\n *  Waits for a child process to exit, returns its process id, and\n *  sets <code>$?</code> to a <code>Process::Status</code> object\n *  containing information on that process. Which child it waits on\n *  depends on the value of _pid_:\n *\n *  > 0::   Waits for the child whose process ID equals _pid_.\n *\n *  0::     Waits for any child whose process group ID equals that of the\n *          calling process.\n *\n *  -1::    Waits for any child process (the default if no _pid_ is\n *          given).\n *\n *  < -1::  Waits for any child whose process group ID equals the absolute\n *          value of _pid_.\n *\n *  The _flags_ argument may be a logical or of the flag values\n *  <code>Process::WNOHANG</code> (do not block if no child available)\n *  or <code>Process::WUNTRACED</code> (return stopped children that\n *  haven't been reported). Not all flags are available on all\n *  platforms, but a flag value of zero will work on all platforms.\n *\n *  Calling this method raises a <code>SystemError</code> if there are\n *  no child processes. Not available on all platforms.\n *\n *     include Process\n *     fork { exit 99 }                 #=> 27429\n *     wait                             #=> 27429\n *     $?.exitstatus                    #=> 99\n *\n *     pid = fork { sleep 3 }           #=> 27440\n *     Time.now                         #=> Wed Apr 09 08:57:09 CDT 2003\n *     waitpid(pid, Process::WNOHANG)   #=> nil\n *     Time.now                         #=> Wed Apr 09 08:57:09 CDT 2003\n *     waitpid(pid, 0)                  #=> 27440\n *     Time.now                         #=> Wed Apr 09 08:57:12 CDT 2003\n */\n\nstatic VALUE\nproc_wait(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE vpid, vflags;\n    int pid, flags, status;\n\n    rb_secure(2);\n    flags = 0;\n    rb_scan_args(argc, argv, \"02\", &vpid, &vflags);\n    if (argc == 0) {\n\tpid = -1;\n    }\n    else {\n\tpid = NUM2INT(vpid);\n\tif (argc == 2 && !NIL_P(vflags)) {\n\t    flags = NUM2UINT(vflags);\n\t}\n    }\n    if ((pid = rb_waitpid(pid, &status, flags)) < 0)\n\trb_sys_fail(0);\n    if (pid == 0) {\n\treturn rb_last_status = Qnil;\n    }\n    return INT2FIX(pid);\n}\n\n\n/*\n *  call-seq:\n *     Process.wait2(pid=-1, flags=0)      => [pid, status]\n *     Process.waitpid2(pid=-1, flags=0)   => [pid, status]\n *\n *  Waits for a child process to exit (see Process::waitpid for exact\n *  semantics) and returns an array containing the process id and the\n *  exit status (a <code>Process::Status</code> object) of that\n *  child. Raises a <code>SystemError</code> if there are no child\n *  processes.\n *\n *     Process.fork { exit 99 }   #=> 27437\n *     pid, status = Process.wait2\n *     pid                        #=> 27437\n *     status.exitstatus          #=> 99\n */\n\nstatic VALUE\nproc_wait2(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE pid = proc_wait(argc, argv);\n    if (NIL_P(pid)) return Qnil;\n    return rb_assoc_new(pid, rb_last_status);\n}\n\n\n/*\n *  call-seq:\n *     Process.waitall   => [ [pid1,status1], ...]\n *\n *  Waits for all children, returning an array of\n *  _pid_/_status_ pairs (where _status_ is a\n *  <code>Process::Status</code> object).\n *\n *     fork { sleep 0.2; exit 2 }   #=> 27432\n *     fork { sleep 0.1; exit 1 }   #=> 27433\n *     fork {            exit 0 }   #=> 27434\n *     p Process.waitall\n *\n *  <em>produces</em>:\n *\n *     [[27434, #<Process::Status: pid=27434,exited(0)>],\n *      [27433, #<Process::Status: pid=27433,exited(1)>],\n *      [27432, #<Process::Status: pid=27432,exited(2)>]]\n */\n\nstatic VALUE\nproc_waitall()\n{\n    VALUE result;\n    int pid, status;\n\n    rb_secure(2);\n    result = rb_ary_new();\n#ifdef NO_WAITPID\n    if (pid_tbl) {\n\tst_foreach(pid_tbl, waitall_each, result);\n    }\n\n    for (pid = -1;;) {\n\tpid = wait(&status);\n\tif (pid == -1) {\n\t    if (errno == ECHILD)\n\t\tbreak;\n\t    if (errno == EINTR) {\n\t\trb_thread_schedule();\n\t\tcontinue;\n\t    }\n\t    rb_sys_fail(0);\n\t}\n\tlast_status_set(status, pid);\n\trb_ary_push(result, rb_assoc_new(INT2NUM(pid), rb_last_status));\n    }\n#else\n    rb_last_status = Qnil;\n    for (pid = -1;;) {\n\tpid = rb_waitpid(-1, &status, 0);\n\tif (pid == -1) {\n\t    if (errno == ECHILD)\n\t\tbreak;\n\t    rb_sys_fail(0);\n\t}\n\trb_ary_push(result, rb_assoc_new(INT2NUM(pid), rb_last_status));\n    }\n#endif\n    return result;\n}\n\nstatic VALUE\ndetach_process_watcher(arg)\n    void *arg;\n{\n    int pid = (int)(VALUE)arg, status;\n\n    while (rb_waitpid(pid, &status, WNOHANG) == 0) {\n\trb_thread_sleep(1);\n    }\n    return rb_last_status;\n}\n\nVALUE\nrb_detach_process(pid)\n    int pid;\n{\n    return rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);\n}\n\n\n/*\n *  call-seq:\n *     Process.detach(pid)   => thread\n *\n *  Some operating systems retain the status of terminated child\n *  processes until the parent collects that status (normally using\n *  some variant of <code>wait()</code>. If the parent never collects\n *  this status, the child stays around as a <em>zombie</em> process.\n *  <code>Process::detach</code> prevents this by setting up a\n *  separate Ruby thread whose sole job is to reap the status of the\n *  process _pid_ when it terminates. Use <code>detach</code>\n *  only when you do not intent to explicitly wait for the child to\n *  terminate.  <code>detach</code> only checks the status\n *  periodically (currently once each second).\n *\n *  The waiting thread returns the exit status of the detached process\n *  when it terminates, so you can use <code>Thread#join</code> to\n *  know the result.  If specified _pid_ is not a valid child process\n *  ID, the thread returns +nil+ immediately.\n *\n *  In this first example, we don't reap the first child process, so\n *  it appears as a zombie in the process status display.\n *\n *     p1 = fork { sleep 0.1 }\n *     p2 = fork { sleep 0.2 }\n *     Process.waitpid(p2)\n *     sleep 2\n *     system(\"ps -ho pid,state -p #{p1}\")\n *\n *  <em>produces:</em>\n *\n *     27389 Z\n *\n *  In the next example, <code>Process::detach</code> is used to reap\n *  the child automatically.\n *\n *     p1 = fork { sleep 0.1 }\n *     p2 = fork { sleep 0.2 }\n *     Process.detach(p1)\n *     Process.waitpid(p2)\n *     sleep 2\n *     system(\"ps -ho pid,state -p #{p1}\")\n *\n *  <em>(produces no output)</em>\n */\n\nstatic VALUE\nproc_detach(VALUE obj, VALUE pid)\n{\n    rb_secure(2);\n    return rb_detach_process(NUM2INT(pid));\n}\n\n#ifndef HAVE_STRING_H\nchar *strtok();\n#endif\n\n#ifdef HAVE_SETITIMER\n#define before_exec() rb_thread_stop_timer()\n#define after_exec() rb_thread_start_timer()\n#else\n#define before_exec()\n#define after_exec()\n#endif\n\nextern char *dln_find_exe();\n\nstatic void\nsecurity(str)\n    char *str;\n{\n    if (rb_env_path_tainted()) {\n\tif (rb_safe_level() > 0) {\n\t    rb_raise(rb_eSecurityError, \"Insecure PATH - %s\", str);\n\t}\n    }\n}\n\nstatic int\nproc_exec_v(argv, prog)\n    char **argv;\n    char *prog;\n{\n    if (!prog)\n\tprog = argv[0];\n    security(prog);\n    prog = dln_find_exe(prog, 0);\n    if (!prog)\n\treturn -1;\n\n#if (defined(MSDOS) && !defined(DJGPP)) || defined(__human68k__) || defined(__EMX__) || defined(OS2)\n    {\n#if defined(__human68k__)\n#define COMMAND \"command.x\"\n#endif\n#if defined(__EMX__) || defined(OS2) /* OS/2 emx */\n#define COMMAND \"cmd.exe\"\n#endif\n#if (defined(MSDOS) && !defined(DJGPP))\n#define COMMAND \"command.com\"\n#endif\n\tchar *extension;\n\n\tif ((extension = strrchr(prog, '.')) != NULL && strcasecmp(extension, \".bat\") == 0) {\n\t    char **new_argv;\n\t    char *p;\n\t    int n;\n\n\t    for (n = 0; argv[n]; n++)\n\t\t/* no-op */;\n\t    new_argv = ALLOCA_N(char*, n + 2);\n\t    for (; n > 0; n--)\n\t\tnew_argv[n + 1] = argv[n];\n\t    new_argv[1] = strcpy(ALLOCA_N(char, strlen(argv[0]) + 1), argv[0]);\n\t    for (p = new_argv[1]; *p != '\\0'; p++)\n\t\tif (*p == '/')\n\t\t    *p = '\\\\';\n\t    new_argv[0] = COMMAND;\n\t    argv = new_argv;\n\t    prog = dln_find_exe(argv[0], 0);\n\t    if (!prog) {\n\t\terrno = ENOENT;\n\t\treturn -1;\n\t    }\n\t}\n    }\n#endif /* MSDOS or __human68k__ or __EMX__ */\n    before_exec();\n    execv(prog, argv);\n    preserving_errno(after_exec());\n    return -1;\n}\n\nstatic int\nproc_exec_n(argc, argv, progv)\n    int argc;\n    VALUE *argv;\n    VALUE progv;\n{\n    char *prog = 0;\n    char **args;\n    int i;\n\n    if (progv) {\n\tprog = RSTRING(progv)->ptr;\n    }\n    args = ALLOCA_N(char*, argc+1);\n    for (i=0; i<argc; i++) {\n\tSafeStringValue(argv[i]);\n\targs[i] = RSTRING(argv[i])->ptr;\n    }\n    args[i] = 0;\n    if (args[0]) {\n\treturn proc_exec_v(args, prog);\n    }\n    return -1;\n}\n\nint\nrb_proc_exec(str)\n    const char *str;\n{\n#ifndef _WIN32\n    const char *s = str;\n    char *ss, *t;\n    char **argv, **a;\n#endif\n\n    while (*str && ISSPACE(*str))\n\tstr++;\n\n#ifdef _WIN32\n    before_exec();\n    do_spawn(P_OVERLAY, (char *)str);\n    after_exec();\n#else\n    for (s=str; *s; s++) {\n\tif (*s != ' ' && !ISALPHA(*s) && strchr(\"*?{}[]<>()~&|\\\\$;'`\\\"\\n\",*s)) {\n#if defined(MSDOS)\n\t    int status;\n\t    before_exec();\n\t    status = system(str);\n\t    after_exec();\n\t    if (status != -1)\n\t\texit(status);\n#else\n#if defined(__human68k__) || defined(__CYGWIN32__) || defined(__EMX__)\n\t    char *shell = dln_find_exe(\"sh\", 0);\n\t    int status = -1;\n\t    before_exec();\n\t    if (shell)\n\t\texecl(shell, \"sh\", \"-c\", str, (char *) NULL);\n\t    else\n\t\tstatus = system(str);\n\t    after_exec();\n\t    if (status != -1)\n\t\texit(status);\n#else\n\t    before_exec();\n\t    execl(\"/bin/sh\", \"sh\", \"-c\", str, (char *)NULL);\n\t    preserving_errno(after_exec());\n#endif\n#endif\n\t    return -1;\n\t}\n    }\n    a = argv = ALLOCA_N(char*, (s-str)/2+2);\n    ss = ALLOCA_N(char, s-str+1);\n    strcpy(ss, str);\n    if ((*a++ = strtok(ss, \" \\t\")) != 0) {\n\twhile ((t = strtok(NULL, \" \\t\")) != 0) {\n\t    *a++ = t;\n\t}\n\t*a = NULL;\n    }\n    if (argv[0]) {\n\treturn proc_exec_v(argv, 0);\n    }\n    errno = ENOENT;\n#endif\t/* _WIN32 */\n    return -1;\n}\n\n#if defined(__human68k__) || defined(__DJGPP__) || defined(_WIN32)\nstatic int\nproc_spawn_v(argv, prog)\n    char **argv;\n    char *prog;\n{\n#if defined(__human68k__)\n    char *extension;\n#endif\n    int status;\n\n    if (!prog)\n\tprog = argv[0];\n    security(prog);\n    prog = dln_find_exe(prog, 0);\n    if (!prog)\n\treturn -1;\n\n#if defined(__human68k__)\n    if ((extension = strrchr(prog, '.')) != NULL && strcasecmp(extension, \".bat\") == 0) {\n\tchar **new_argv;\n\tchar *p;\n\tint n;\n\n\tfor (n = 0; argv[n]; n++)\n\t    /* no-op */;\n\tnew_argv = ALLOCA_N(char*, n + 2);\n\tfor (; n > 0; n--)\n\t    new_argv[n + 1] = argv[n];\n\tnew_argv[1] = strcpy(ALLOCA_N(char, strlen(argv[0]) + 1), argv[0]);\n\tfor (p = new_argv[1]; *p != '\\0'; p++)\n\t    if (*p == '/')\n\t\t*p = '\\\\';\n\tnew_argv[0] = COMMAND;\n\targv = new_argv;\n\tprog = dln_find_exe(argv[0], 0);\n\tif (!prog) {\n\t    errno = ENOENT;\n\t    return -1;\n\t}\n    }\n#endif\n    before_exec();\n#if defined(_WIN32)\n    status = do_aspawn(P_WAIT, prog, argv);\n#else\n    status = spawnv(P_WAIT, prog, argv);\n#endif\n    after_exec();\n    return status;\n}\n\nstatic int\nproc_spawn_n(argc, argv, prog)\n    int argc;\n    VALUE *argv;\n    VALUE prog;\n{\n    char **args;\n    int i;\n\n    args = ALLOCA_N(char*, argc + 1);\n    for (i = 0; i < argc; i++) {\n\tSafeStringValue(argv[i]);\n\targs[i] = StringValueCStr(argv[i]);\n    }\n    if (prog)\n\tSafeStringValue(prog);\n    args[i] = (char*) 0;\n    if (args[0])\n\treturn proc_spawn_v(args, prog ? StringValueCStr(prog) : 0);\n    return -1;\n}\n\n#if !defined(_WIN32)\nstatic int\nproc_spawn(sv)\n    VALUE sv;\n{\n    char *str;\n    char *s, *t;\n    char **argv, **a;\n    int status;\n\n    SafeStringValue(sv);\n    str = s = StringValueCStr(sv);\n    for (s = str; *s; s++) {\n\tif (*s != ' ' && !ISALPHA(*s) && strchr(\"*?{}[]<>()~&|\\\\$;'`\\\"\\n\",*s)) {\n\t    char *shell = dln_find_exe(\"sh\", 0);\n\t    before_exec();\n\t    status = shell?spawnl(P_WAIT,shell,\"sh\",\"-c\",str,(char*)NULL):system(str);\n\t    after_exec();\n\t    return status;\n\t}\n    }\n    a = argv = ALLOCA_N(char*, (s - str) / 2 + 2);\n    s = ALLOCA_N(char, s - str + 1);\n    strcpy(s, str);\n    if (*a++ = strtok(s, \" \\t\")) {\n\twhile (t = strtok(NULL, \" \\t\"))\n\t    *a++ = t;\n\t*a = NULL;\n    }\n    return argv[0] ? proc_spawn_v(argv, 0) : -1;\n}\n#endif\n#endif\n\nstruct rb_exec_arg {\n    int argc;\n    VALUE *argv;\n    VALUE prog;\n};\n\nstatic void\nproc_prepare_args(e, argc, argv, prog)\n    struct rb_exec_arg *e;\n    int argc;\n    VALUE *argv;\n    VALUE prog;\n{\n    int i;\n\n    MEMZERO(e, struct rb_exec_arg, 1);\n    if (prog) {\n\tSafeStringValue(prog);\n\tStringValueCStr(prog);\n    }\n    for (i = 0; i < argc; i++) {\n\tSafeStringValue(argv[i]);\n\tStringValueCStr(argv[i]);\n    }\n    security(RSTRING(prog ? prog : argv[0])->ptr);\n    e->prog = prog;\n    e->argc = argc;\n    e->argv = argv;\n}\n\nstatic VALUE\nproc_exec_args(earg)\n    VALUE earg;\n{\n    struct rb_exec_arg *e = (struct rb_exec_arg *)earg;\n    int argc = e->argc;\n    VALUE *argv = e->argv;\n    VALUE prog = e->prog;\n\n    if (argc == 1 && prog == 0) {\n\treturn (VALUE)rb_proc_exec(RSTRING(argv[0])->ptr);\n    }\n    else {\n\treturn (VALUE)proc_exec_n(argc, argv, prog);\n    }\n}\n\n/*\n *  call-seq:\n *     exec(command [, arg, ...])\n *\n *  Replaces the current process by running the given external _command_.\n *  If +exec+ is given a single argument, that argument is\n *  taken as a line that is subject to shell expansion before being\n *  executed. If multiple arguments are given, the second and subsequent\n *  arguments are passed as parameters to _command_ with no shell\n *  expansion. If the first argument is a two-element array, the first\n *  element is the command to be executed, and the second argument is\n *  used as the <code>argv[0]</code> value, which may show up in process\n *  listings. In MSDOS environments, the command is executed in a\n *  subshell; otherwise, one of the <code>exec(2)</code> system calls is\n *  used, so the running command may inherit some of the environment of\n *  the original program (including open file descriptors).\n *\n *     exec \"echo *\"       # echoes list of files in current directory\n *     # never get here\n *\n *\n *     exec \"echo\", \"*\"    # echoes an asterisk\n *     # never get here\n */\n\nVALUE\nrb_f_exec(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE prog = 0;\n    VALUE tmp;\n    struct rb_exec_arg earg;\n\n    if (argc == 0) {\n\trb_last_status = Qnil;\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    tmp = rb_check_array_type(argv[0]);\n    if (!NIL_P(tmp)) {\n\tif (RARRAY(tmp)->len != 2) {\n\t    rb_raise(rb_eArgError, \"wrong first argument\");\n\t}\n\tprog = RARRAY(tmp)->ptr[0];\n\targv[0] = RARRAY(tmp)->ptr[1];\n\tSafeStringValue(prog);\n    }\n    proc_prepare_args(&earg, argc, argv, prog);\n    proc_exec_args((VALUE)&earg);\n    rb_sys_fail(RSTRING(argv[0])->ptr);\n    return Qnil;\t\t/* dummy */\n}\n\n\n/*\n *  call-seq:\n *     Kernel.fork  [{ block }]   => fixnum or nil\n *     Process.fork [{ block }]   => fixnum or nil\n *\n *  Creates a subprocess. If a block is specified, that block is run\n *  in the subprocess, and the subprocess terminates with a status of\n *  zero. Otherwise, the +fork+ call returns twice, once in\n *  the parent, returning the process ID of the child, and once in\n *  the child, returning _nil_. The child process can exit using\n *  <code>Kernel.exit!</code> to avoid running any\n *  <code>at_exit</code> functions. The parent process should\n *  use <code>Process.wait</code> to collect the termination statuses\n *  of its children or use <code>Process.detach</code> to register\n *  disinterest in their status; otherwise, the operating system\n *  may accumulate zombie processes.\n *\n *  The thread calling fork is the only thread in the created child process.\n *  fork doesn't copy other threads.\n */\n\nstatic VALUE\nrb_f_fork(obj)\n    VALUE obj;\n{\n#if !defined(__human68k__) && !defined(_WIN32) && !defined(__MACOS__) && !defined(__EMX__) && !defined(__VMS)\n    int pid;\n\n    rb_secure(2);\n\n#ifndef __VMS\n    fflush(stdout);\n    fflush(stderr);\n#endif\n\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n    before_exec();\n#endif\n    pid = fork();\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n    after_exec();\n#endif\n    switch (pid) {\n      case 0:\n#ifdef linux\n\tafter_exec();\n#endif\n\trb_thread_atfork();\n\tif (rb_block_given_p()) {\n\t    int status;\n\n\t    rb_protect(rb_yield, Qundef, &status);\n\t    ruby_stop(status);\n\t}\n\treturn Qnil;\n\n      case -1:\n\trb_sys_fail(\"fork(2)\");\n\treturn Qnil;\n\n      default:\n\treturn INT2FIX(pid);\n    }\n#else\n    rb_notimplement();\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.exit!(fixnum=-1)\n *\n *  Exits the process immediately. No exit handlers are\n *  run. <em>fixnum</em> is returned to the underlying system as the\n *  exit status.\n *\n *     Process.exit!(0)\n */\n\nstatic VALUE\nrb_f_exit_bang(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE status;\n    int istatus;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"01\", &status) == 1) {\n\tswitch (status) {\n\t  case Qtrue:\n\t    istatus = EXIT_SUCCESS;\n\t    break;\n\t  case Qfalse:\n\t    istatus = EXIT_FAILURE;\n\t    break;\n\t  default:\n\t    istatus = NUM2INT(status);\n\t    break;\n\t}\n    }\n    else {\n\tistatus = EXIT_FAILURE;\n    }\n    _exit(istatus);\n\n    return Qnil;\t\t/* not reached */\n}\n\n#if defined(sun)\n#define signal(a,b) sigset(a,b)\n#endif\n\nvoid\nrb_syswait(pid)\n    int pid;\n{\n    static int overriding;\n#ifdef SIGHUP\n    RETSIGTYPE (*hfunc)_((int)) = 0;\n#endif\n#ifdef SIGQUIT\n    RETSIGTYPE (*qfunc)_((int)) = 0;\n#endif\n    RETSIGTYPE (*ifunc)_((int)) = 0;\n    int status;\n    int i, hooked = Qfalse;\n\n    if (!overriding) {\n#ifdef SIGHUP\n\thfunc = signal(SIGHUP, SIG_IGN);\n#endif\n#ifdef SIGQUIT\n\tqfunc = signal(SIGQUIT, SIG_IGN);\n#endif\n\tifunc = signal(SIGINT, SIG_IGN);\n\toverriding = Qtrue;\n\thooked = Qtrue;\n    }\n\n    do {\n\ti = rb_waitpid(pid, &status, 0);\n    } while (i == -1 && errno == EINTR);\n\n    if (hooked) {\n#ifdef SIGHUP\n\tsignal(SIGHUP, hfunc);\n#endif\n#ifdef SIGQUIT\n\tsignal(SIGQUIT, qfunc);\n#endif\n\tsignal(SIGINT, ifunc);\n\toverriding = Qfalse;\n    }\n}\n\n/*\n *  call-seq:\n *     system(cmd [, arg, ...])    => true or false\n *\n *  Executes _cmd_ in a subshell, returning +true+ if\n *  the command was found and ran successfully, +false+\n *  otherwise. An error status is available in <code>$?</code>. The\n *  arguments are processed in the same way as for\n *  <code>Kernel::exec</code>.\n *\n *     system(\"echo *\")\n *     system(\"echo\", \"*\")\n *\n *  <em>produces:</em>\n *\n *     config.h main.rb\n *     *\n */\n\nstatic VALUE\nrb_f_system(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int status;\n#if defined(__EMX__)\n    VALUE cmd;\n\n    fflush(stdout);\n    fflush(stderr);\n    if (argc == 0) {\n\trb_last_status = Qnil;\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    if (TYPE(argv[0]) == T_ARRAY) {\n\tif (RARRAY(argv[0])->len != 2) {\n\t    rb_raise(rb_eArgError, \"wrong first argument\");\n\t}\n\targv[0] = RARRAY(argv[0])->ptr[0];\n    }\n    cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(\" \"));\n\n    SafeStringValue(cmd);\n    status = do_spawn(RSTRING(cmd)->ptr);\n    last_status_set(status, 0);\n#elif defined(__human68k__) || defined(__DJGPP__) || defined(_WIN32)\n    volatile VALUE prog = 0;\n\n    fflush(stdout);\n    fflush(stderr);\n    if (argc == 0) {\n\trb_last_status = Qnil;\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    if (TYPE(argv[0]) == T_ARRAY) {\n\tif (RARRAY(argv[0])->len != 2) {\n\t    rb_raise(rb_eArgError, \"wrong first argument\");\n\t}\n\tprog = RARRAY(argv[0])->ptr[0];\n\targv[0] = RARRAY(argv[0])->ptr[1];\n    }\n\n    if (argc == 1 && prog == 0) {\n#if defined(_WIN32)\n\tSafeStringValue(argv[0]);\n\tstatus = do_spawn(P_WAIT, StringValueCStr(argv[0]));\n#else\n\tstatus = proc_spawn(argv[0]);\n#endif\n    }\n    else {\n\tstatus = proc_spawn_n(argc, argv, prog);\n    }\n#if !defined(_WIN32)\n    last_status_set(status == -1 ? 127 : status, 0);\n#else\n    if (status == -1)\n\tlast_status_set(0x7f << 8, 0);\n#endif\n#elif defined(__VMS)\n    VALUE cmd;\n\n    if (argc == 0) {\n\trb_last_status = Qnil;\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    if (TYPE(argv[0]) == T_ARRAY) {\n\tif (RARRAY(argv[0])->len != 2) {\n\t    rb_raise(rb_eArgError, \"wrong first argument\");\n\t}\n\targv[0] = RARRAY(argv[0])->ptr[0];\n    }\n    cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(\" \"));\n\n    SafeStringValue(cmd);\n    status = system(StringValueCStr(cmd));\n    last_status_set((status & 0xff) << 8, 0);\n#else\n    volatile VALUE prog = 0;\n    int pid;\n    struct rb_exec_arg earg;\n    RETSIGTYPE (*chfunc)(int);\n\n    fflush(stdout);\n    fflush(stderr);\n    if (argc == 0) {\n\trb_last_status = Qnil;\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    if (TYPE(argv[0]) == T_ARRAY) {\n\tif (RARRAY(argv[0])->len != 2) {\n\t    rb_raise(rb_eArgError, \"wrong first argument\");\n\t}\n\tprog = RARRAY(argv[0])->ptr[0];\n\targv[0] = RARRAY(argv[0])->ptr[1];\n    }\n    proc_prepare_args(&earg, argc, argv, prog);\n\n    chfunc = signal(SIGCHLD, SIG_DFL);\n  retry:\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n    before_exec();\n#endif\n    pid = fork();\n    if (pid == 0) {\n\t/* child process */\n\trb_thread_atfork();\n\trb_protect(proc_exec_args, (VALUE)&earg, NULL);\n\t_exit(127);\n    }\n#if defined(__NetBSD__) || defined(__APPLE__) || defined(linux)\n    after_exec();\n#endif\n    if (pid < 0) {\n\tif (errno == EAGAIN) {\n\t    rb_thread_sleep(1);\n\t    goto retry;\n\t}\n    }\n    else {\n\trb_syswait(pid);\n    }\n    signal(SIGCHLD, chfunc);\n    if (pid < 0) rb_sys_fail(0);\n    status = NUM2INT(rb_last_status);\n#endif\n\n    if (status == EXIT_SUCCESS) return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     sleep([duration])    => fixnum\n *\n *  Suspends the current thread for _duration_ seconds (which may be any number,\n *  including a +Float+ with fractional seconds). Returns the actual number of\n *  seconds slept (rounded), which may be less than that asked for if another\n *  thread calls <code>Thread#run</code>. Zero arguments causes +sleep+ to sleep\n *  forever.\n *\n *     Time.new    #=> Wed Apr 09 08:56:32 CDT 2003\n *     sleep 1.2   #=> 1\n *     Time.new    #=> Wed Apr 09 08:56:33 CDT 2003\n *     sleep 1.9   #=> 2\n *     Time.new    #=> Wed Apr 09 08:56:35 CDT 2003\n */\n\nstatic VALUE\nrb_f_sleep(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int beg, end;\n\n    beg = time(0);\n    if (argc == 0) {\n\trb_thread_sleep_forever();\n    }\n    else if (argc == 1) {\n\trb_thread_wait_for(rb_time_interval(argv[0]));\n    }\n    else {\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n\n    end = time(0) - beg;\n\n    return INT2FIX(end);\n}\n\n\n#if defined(SIGCLD) && !defined(SIGCHLD)\n# define SIGCHLD SIGCLD\n#endif\n\n/*\n *  call-seq:\n *     Process.getpgrp   => integer\n *\n *  Returns the process group ID for this process. Not available on\n *  all platforms.\n *\n *     Process.getpgid(0)   #=> 25527\n *     Process.getpgrp      #=> 25527\n */\n\nstatic VALUE\nproc_getpgrp()\n{\n#if defined(HAVE_GETPGRP) && defined(GETPGRP_VOID)\n    int pgrp;\n#endif\n\n    rb_secure(2);\n#if defined(HAVE_GETPGRP) && defined(GETPGRP_VOID)\n    pgrp = getpgrp();\n    if (pgrp < 0) rb_sys_fail(0);\n    return INT2FIX(pgrp);\n#else\n# ifdef HAVE_GETPGID\n    pgrp = getpgid(0);\n    if (pgrp < 0) rb_sys_fail(0);\n    return INT2FIX(pgrp);\n# else\n    rb_notimplement();\n# endif\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.setpgrp   => 0\n *\n *  Equivalent to <code>setpgid(0,0)</code>. Not available on all\n *  platforms.\n */\n\nstatic VALUE\nproc_setpgrp()\n{\n    rb_secure(2);\n  /* check for posix setpgid() first; this matches the posix */\n  /* getpgrp() above.  It appears that configure will set SETPGRP_VOID */\n  /* even though setpgrp(0,0) would be prefered. The posix call avoids */\n  /* this confusion. */\n#ifdef HAVE_SETPGID\n    if (setpgid(0,0) < 0) rb_sys_fail(0);\n#elif defined(HAVE_SETPGRP) && defined(SETPGRP_VOID)\n    if (setpgrp() < 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(0);\n}\n\n\n/*\n *  call-seq:\n *     Process.getpgid(pid)   => integer\n *\n *  Returns the process group ID for the given process id. Not\n *  available on all platforms.\n *\n *     Process.getpgid(Process.ppid())   #=> 25527\n */\n\nstatic VALUE\nproc_getpgid(obj, pid)\n    VALUE obj, pid;\n{\n#if defined(HAVE_GETPGID) && !defined(__CHECKER__)\n    int i;\n\n    rb_secure(2);\n    i = getpgid(NUM2INT(pid));\n    if (i < 0) rb_sys_fail(0);\n    return INT2NUM(i);\n#else\n    rb_notimplement();\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.setpgid(pid, integer)   => 0\n *\n *  Sets the process group ID of _pid_ (0 indicates this\n *  process) to <em>integer</em>. Not available on all platforms.\n */\n\nstatic VALUE\nproc_setpgid(obj, pid, pgrp)\n    VALUE obj, pid, pgrp;\n{\n#ifdef HAVE_SETPGID\n    int ipid, ipgrp;\n\n    rb_secure(2);\n    ipid = NUM2INT(pid);\n    ipgrp = NUM2INT(pgrp);\n\n    if (setpgid(ipid, ipgrp) < 0) rb_sys_fail(0);\n    return INT2FIX(0);\n#else\n    rb_notimplement();\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.setsid   => fixnum\n *\n *  Establishes this process as a new session and process group\n *  leader, with no controlling tty. Returns the session id. Not\n *  available on all platforms.\n *\n *     Process.setsid   #=> 27422\n */\n\nstatic VALUE\nproc_setsid()\n{\n#if defined(HAVE_SETSID)\n    int pid;\n\n    rb_secure(2);\n    pid = setsid();\n    if (pid < 0) rb_sys_fail(0);\n    return INT2FIX(pid);\n#elif defined(HAVE_SETPGRP) && defined(TIOCNOTTY)\n  rb_pid_t pid;\n  int ret;\n\n  rb_secure(2);\n  pid = getpid();\n#if defined(SETPGRP_VOID)\n  ret = setpgrp();\n  /* If `pid_t setpgrp(void)' is equivalent to setsid(),\n     `ret' will be the same value as `pid', and following open() will fail.\n     In Linux, `int setpgrp(void)' is equivalent to setpgid(0, 0). */\n#else\n  ret = setpgrp(0, pid);\n#endif\n  if (ret == -1) rb_sys_fail(0);\n\n  if ((fd = open(\"/dev/tty\", O_RDWR)) >= 0) {\n    ioctl(fd, TIOCNOTTY, NULL);\n    close(fd);\n  }\n  return INT2FIX(pid);\n#else\n    rb_notimplement();\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.getpriority(kind, integer)   => fixnum\n *\n *  Gets the scheduling priority for specified process, process group,\n *  or user. <em>kind</em> indicates the kind of entity to find: one\n *  of <code>Process::PRIO_PGRP</code>,\n *  <code>Process::PRIO_USER</code>, or\n *  <code>Process::PRIO_PROCESS</code>. _integer_ is an id\n *  indicating the particular process, process group, or user (an id\n *  of 0 means _current_). Lower priorities are more favorable\n *  for scheduling. Not available on all platforms.\n *\n *     Process.getpriority(Process::PRIO_USER, 0)      #=> 19\n *     Process.getpriority(Process::PRIO_PROCESS, 0)   #=> 19\n */\n\nstatic VALUE\nproc_getpriority(obj, which, who)\n    VALUE obj, which, who;\n{\n#ifdef HAVE_GETPRIORITY\n    int prio, iwhich, iwho;\n\n    rb_secure(2);\n    iwhich = NUM2INT(which);\n    iwho   = NUM2INT(who);\n\n    errno = 0;\n    prio = getpriority(iwhich, iwho);\n    if (errno) rb_sys_fail(0);\n    return INT2FIX(prio);\n#else\n    rb_notimplement();\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.setpriority(kind, integer, priority)   => 0\n *\n *  See <code>Process#getpriority</code>.\n *\n *     Process.setpriority(Process::PRIO_USER, 0, 19)      #=> 0\n *     Process.setpriority(Process::PRIO_PROCESS, 0, 19)   #=> 0\n *     Process.getpriority(Process::PRIO_USER, 0)          #=> 19\n *     Process.getpriority(Process::PRIO_PROCESS, 0)       #=> 19\n */\n\nstatic VALUE\nproc_setpriority(obj, which, who, prio)\n    VALUE obj, which, who, prio;\n{\n#ifdef HAVE_GETPRIORITY\n    int iwhich, iwho, iprio;\n\n    rb_secure(2);\n    iwhich = NUM2INT(which);\n    iwho   = NUM2INT(who);\n    iprio  = NUM2INT(prio);\n\n    if (setpriority(iwhich, iwho, iprio) < 0)\n\trb_sys_fail(0);\n    return INT2FIX(0);\n#else\n    rb_notimplement();\n#endif\n}\n\n#if SIZEOF_RLIM_T == SIZEOF_INT\n# define RLIM2NUM(v) UINT2NUM(v)\n# define NUM2RLIM(v) NUM2UINT(v)\n#elif SIZEOF_RLIM_T == SIZEOF_LONG\n# define RLIM2NUM(v) ULONG2NUM(v)\n# define NUM2RLIM(v) NUM2ULONG(v)\n#elif SIZEOF_RLIM_T == SIZEOF_LONG_LONG\n# define RLIM2NUM(v) ULL2NUM(v)\n# define NUM2RLIM(v) NUM2ULL(v)\n#endif\n\n/*\n *  call-seq:\n *     Process.getrlimit(resource)   => [cur_limit, max_limit]\n *\n *  Gets the resource limit of the process.\n *  _cur_limit_ means current (soft) limit and\n *  _max_limit_ means maximum (hard) limit.\n *\n *  _resource_ indicates the kind of resource to limit:\n *  such as <code>Process::RLIMIT_CORE</code>,\n *  <code>Process::RLIMIT_CPU</code>, etc.\n *  See Process.setrlimit for details.\n *\n *  _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>,\n *  <code>Process::RLIM_SAVED_MAX</code> or\n *  <code>Process::RLIM_SAVED_CUR</code>.\n *  See Process.setrlimit and the system getrlimit(2) manual for details.\n */\n\nstatic VALUE\nproc_getrlimit(VALUE obj, VALUE resource)\n{\n#if defined(HAVE_GETRLIMIT) && defined(RLIM2NUM)\n    struct rlimit rlim;\n\n    rb_secure(2);\n\n    if (getrlimit(NUM2INT(resource), &rlim) < 0) {\n        rb_sys_fail(\"getrlimit\");\n    }\n    return rb_assoc_new(RLIM2NUM(rlim.rlim_cur), RLIM2NUM(rlim.rlim_max));\n#else\n    rb_notimplement();\n#endif\n}\n\n/*\n *  call-seq:\n *     Process.setrlimit(resource, cur_limit, max_limit)        => nil\n *     Process.setrlimit(resource, cur_limit)                   => nil\n *\n *  Sets the resource limit of the process.\n *  _cur_limit_ means current (soft) limit and\n *  _max_limit_ means maximum (hard) limit.\n *\n *  If _max_limit_ is not given, _cur_limit_ is used.\n *\n *  _resource_ indicates the kind of resource to limit.\n *  The list of resources are OS dependent.\n *  Ruby may support following resources.\n *\n *  [Process::RLIMIT_CORE] core size (bytes) (SUSv3)\n *  [Process::RLIMIT_CPU] CPU time (seconds) (SUSv3)\n *  [Process::RLIMIT_DATA] data segment (bytes) (SUSv3)\n *  [Process::RLIMIT_FSIZE] file size (bytes) (SUSv3)\n *  [Process::RLIMIT_NOFILE] file descriptors (number) (SUSv3)\n *  [Process::RLIMIT_STACK] stack size (bytes) (SUSv3)\n *  [Process::RLIMIT_AS] total available memory (bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD but 4.4BSD-Lite)\n *  [Process::RLIMIT_MEMLOCK] total size for mlock(2) (bytes) (4.4BSD, GNU/Linux)\n *  [Process::RLIMIT_NPROC] number of processes for the user (number) (4.4BSD, GNU/Linux)\n *  [Process::RLIMIT_RSS] resident memory size (bytes) (4.2BSD, GNU/Linux)\n *  [Process::RLIMIT_SBSIZE] all socket buffers (bytes) (NetBSD, FreeBSD)\n *\n *  Other <code>Process::RLIMIT_???</code> constants may be defined.\n *\n *  _cur_limit_ and _max_limit_ may be <code>Process::RLIM_INFINITY</code>,\n *  which means that the resource is not limited.\n *  They may be <code>Process::RLIM_SAVED_MAX</code> or\n *  <code>Process::RLIM_SAVED_CUR</code> too.\n *  See system setrlimit(2) manual for details.\n *\n */\n\nstatic VALUE\nproc_setrlimit(int argc, VALUE *argv, VALUE obj)\n{\n#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)\n    VALUE resource, rlim_cur, rlim_max;\n    struct rlimit rlim;\n\n    rb_secure(2);\n\n    rb_scan_args(argc, argv, \"21\", &resource, &rlim_cur, &rlim_max);\n    if (rlim_max == Qnil)\n        rlim_max = rlim_cur;\n\n    rlim.rlim_cur = NUM2RLIM(rlim_cur);\n    rlim.rlim_max = NUM2RLIM(rlim_max);\n\n    if (setrlimit(NUM2INT(resource), &rlim) < 0) {\n        rb_sys_fail(\"setrlimit\");\n    }\n    return Qnil;\n#else\n    rb_notimplement();\n#endif\n}\n\nstatic int under_uid_switch = 0;\nstatic void\ncheck_uid_switch()\n{\n    rb_secure(2);\n    if (under_uid_switch) {\n\trb_raise(rb_eRuntimeError, \"can't handle UID while evaluating block given to Process::UID.switch method\");\n    }\n}\n\nstatic int under_gid_switch = 0;\nstatic void\ncheck_gid_switch()\n{\n    rb_secure(2);\n    if (under_gid_switch) {\n\trb_raise(rb_eRuntimeError, \"can't handle GID while evaluating block given to Process::UID.switch method\");\n    }\n}\n\n\n/*********************************************************************\n * Document-class: Process::Sys\n *\n *  The <code>Process::Sys</code> module contains UID and GID\n *  functions which provide direct bindings to the system calls of the\n *  same names instead of the more-portable versions of the same\n *  functionality found in the <code>Process</code>,\n *  <code>Process::UID</code>, and <code>Process::GID</code> modules.\n */\n\n\n/*\n *  call-seq:\n *     Process::Sys.setuid(integer)   => nil\n *\n *  Set the user ID of the current process to _integer_. Not\n *  available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setuid(obj, id)\n    VALUE obj, id;\n{\n#if defined HAVE_SETUID\n    check_uid_switch();\n    if (setuid(NUM2INT(id)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n\n/*\n *  call-seq:\n *     Process::Sys.setruid(integer)   => nil\n *\n *  Set the real user ID of the calling process to _integer_.\n *  Not available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setruid(obj, id)\n    VALUE obj, id;\n{\n#if defined HAVE_SETRUID\n    check_uid_switch();\n    if (setruid(NUM2INT(id)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process::Sys.seteuid(integer)   => nil\n *\n *  Set the effective user ID of the calling process to\n *  _integer_.  Not available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_seteuid(obj, id)\n    VALUE obj, id;\n{\n#if defined HAVE_SETEUID\n    check_uid_switch();\n    if (seteuid(NUM2INT(id)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process::Sys.setreuid(rid, eid)   => nil\n *\n *  Sets the (integer) real and/or effective user IDs of the current\n *  process to _rid_ and _eid_, respectively. A value of\n *  <code>-1</code> for either means to leave that ID unchanged. Not\n *  available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setreuid(obj, rid, eid)\n    VALUE obj, rid, eid;\n{\n#if defined HAVE_SETREUID\n    check_uid_switch();\n    if (setreuid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process::Sys.setresuid(rid, eid, sid)   => nil\n *\n *  Sets the (integer) real, effective, and saved user IDs of the\n *  current process to _rid_, _eid_, and _sid_ respectively. A\n *  value of <code>-1</code> for any value means to\n *  leave that ID unchanged. Not available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setresuid(obj, rid, eid, sid)\n    VALUE obj, rid, eid, sid;\n{\n#if defined HAVE_SETRESUID\n    check_uid_switch();\n    if (setresuid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process.uid           => fixnum\n *     Process::UID.rid      => fixnum\n *     Process::Sys.getuid   => fixnum\n *\n *  Returns the (real) user ID of this process.\n *\n *     Process.uid   #=> 501\n */\n\nstatic VALUE\nproc_getuid(obj)\n    VALUE obj;\n{\n    int uid = getuid();\n    return INT2FIX(uid);\n}\n\n\n/*\n *  call-seq:\n *     Process.uid= integer   => numeric\n *\n *  Sets the (integer) user ID for this process. Not available on all\n *  platforms.\n */\n\nstatic VALUE\nproc_setuid(obj, id)\n    VALUE obj, id;\n{\n    int uid = NUM2INT(id);\n\n    check_uid_switch();\n#if defined(HAVE_SETRESUID) &&  !defined(__CHECKER__)\n    if (setresuid(uid, -1, -1) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETREUID\n    if (setreuid(uid, -1) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETRUID\n    if (setruid(uid) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETUID\n    {\n\tif (geteuid() == uid) {\n\t    if (setuid(uid) < 0) rb_sys_fail(0);\n\t}\n\telse {\n\t    rb_notimplement();\n\t}\n    }\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(uid);\n}\n\n\n/********************************************************************\n *\n * Document-class: Process::UID\n *\n *  The <code>Process::UID</code> module contains a collection of\n *  module functions which can be used to portably get, set, and\n *  switch the current process's real, effective, and saved user IDs.\n *\n */\n\nstatic int SAVED_USER_ID = -1;\n\n#ifdef BROKEN_SETREUID\nint\nsetreuid(ruid, euid)\n    rb_uid_t ruid, euid;\n{\n    if (ruid != -1 && ruid != getuid()) {\n\tif (euid == -1) euid = geteuid();\n\tif (setuid(ruid) < 0) return -1;\n    }\n    if (euid != -1 && euid != geteuid()) {\n\tif (seteuid(euid) < 0) return -1;\n    }\n    return 0;\n}\n#endif\n\n/*\n *  call-seq:\n *     Process::UID.change_privilege(integer)   => fixnum\n *\n *  Change the current process's real and effective user ID to that\n *  specified by _integer_. Returns the new user ID. Not\n *  available on all platforms.\n *\n *     [Process.uid, Process.euid]          #=> [0, 0]\n *     Process::UID.change_privilege(31)    #=> 31\n *     [Process.uid, Process.euid]          #=> [31, 31]\n */\n\nstatic VALUE\np_uid_change_privilege(obj, id)\n    VALUE obj, id;\n{\n    int uid;\n\n    check_uid_switch();\n\n    uid = NUM2INT(id);\n\n    if (geteuid() == 0) { /* root-user */\n#if defined(HAVE_SETRESUID)\n\tif (setresuid(uid, uid, uid) < 0) rb_sys_fail(0);\n\tSAVED_USER_ID = uid;\n#elif defined(HAVE_SETUID)\n\tif (setuid(uid) < 0) rb_sys_fail(0);\n\tSAVED_USER_ID = uid;\n#elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)\n\tif (getuid() == uid) {\n\t    if (SAVED_USER_ID == uid) {\n\t\tif (setreuid(-1, uid) < 0) rb_sys_fail(0);\n\t    } else {\n\t\tif (uid == 0) { /* (r,e,s) == (root, root, x) */\n\t\t    if (setreuid(-1, SAVED_USER_ID) < 0) rb_sys_fail(0);\n\t\t    if (setreuid(SAVED_USER_ID, 0) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = 0; /* (r,e,s) == (x, root, root) */\n\t\t    if (setreuid(uid, uid) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = uid;\n\t\t} else {\n\t\t    if (setreuid(0, -1) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = 0;\n\t\t    if (setreuid(uid, uid) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = uid;\n\t\t}\n\t    }\n\t} else {\n\t    if (setreuid(uid, uid) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t}\n#elif defined(HAVE_SETRUID) && defined(HAVE_SETEUID)\n\tif (getuid() == uid) {\n\t    if (SAVED_USER_ID == uid) {\n\t\tif (seteuid(uid) < 0) rb_sys_fail(0);\n\t    } else {\n\t\tif (uid == 0) {\n\t\t    if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = 0;\n\t\t    if (setruid(0) < 0) rb_sys_fail(0);\n\t\t} else {\n\t\t    if (setruid(0) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = 0;\n\t\t    if (seteuid(uid) < 0) rb_sys_fail(0);\n\t\t    if (setruid(uid) < 0) rb_sys_fail(0);\n\t\t    SAVED_USER_ID = uid;\n\t\t}\n\t    }\n\t} else {\n\t    if (seteuid(uid) < 0) rb_sys_fail(0);\n\t    if (setruid(uid) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t}\n#else\n\trb_notimplement();\n#endif\n    } else { /* unprivileged user */\n#if defined(HAVE_SETRESUID)\n\tif (setresuid((getuid() == uid)? -1: uid,\n\t\t      (geteuid() == uid)? -1: uid,\n\t\t      (SAVED_USER_ID == uid)? -1: uid) < 0) rb_sys_fail(0);\n\tSAVED_USER_ID = uid;\n#elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)\n\tif (SAVED_USER_ID == uid) {\n\t    if (setreuid((getuid() == uid)? -1: uid,\n\t\t\t (geteuid() == uid)? -1: uid) < 0) rb_sys_fail(0);\n\t} else if (getuid() != uid) {\n\t    if (setreuid(uid, (geteuid() == uid)? -1: uid) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t} else if (/* getuid() == uid && */ geteuid() != uid) {\n\t    if (setreuid(geteuid(), uid) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t    if (setreuid(uid, -1) < 0) rb_sys_fail(0);\n\t} else { /* getuid() == uid && geteuid() == uid */\n\t    if (setreuid(-1, SAVED_USER_ID) < 0) rb_sys_fail(0);\n\t    if (setreuid(SAVED_USER_ID, uid) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t    if (setreuid(uid, -1) < 0) rb_sys_fail(0);\n\t}\n#elif defined(HAVE_SETRUID) && defined(HAVE_SETEUID)\n\tif (SAVED_USER_ID == uid) {\n\t    if (geteuid() != uid && seteuid(uid) < 0) rb_sys_fail(0);\n\t    if (getuid() != uid && setruid(uid) < 0) rb_sys_fail(0);\n\t} else if (/* SAVED_USER_ID != uid && */ geteuid() == uid) {\n\t    if (getuid() != uid) {\n\t\tif (setruid(uid) < 0) rb_sys_fail(0);\n\t\tSAVED_USER_ID = uid;\n\t    } else {\n\t\tif (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);\n\t\tSAVED_USER_ID = uid;\n\t\tif (setruid(uid) < 0) rb_sys_fail(0);\n\t    }\n\t} else if (/* geteuid() != uid && */ getuid() == uid) {\n\t    if (seteuid(uid) < 0) rb_sys_fail(0);\n\t    if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t    if (setruid(uid) < 0) rb_sys_fail(0);\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#elif defined HAVE_44BSD_SETUID\n\tif (getuid() == uid) {\n\t    /* (r,e,s)==(uid,?,?) ==> (uid,uid,uid) */\n\t    if (setuid(uid) < 0) rb_sys_fail(0);\n\t    SAVED_USER_ID = uid;\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#elif defined HAVE_SETEUID\n\tif (getuid() == uid && SAVED_USER_ID == uid) {\n\t    if (seteuid(uid) < 0) rb_sys_fail(0);\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#elif defined HAVE_SETUID\n\tif (getuid() == uid && SAVED_USER_ID == uid) {\n\t    if (setuid(uid) < 0) rb_sys_fail(0);\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#else\n\trb_notimplement();\n#endif\n    }\n    return INT2FIX(uid);\n}\n\n\n\n/*\n *  call-seq:\n *     Process::Sys.setgid(integer)   => nil\n *\n *  Set the group ID of the current process to _integer_. Not\n *  available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setgid(obj, id)\n    VALUE obj, id;\n{\n#if defined HAVE_SETGID\n    check_gid_switch();\n    if (setgid(NUM2INT(id)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process::Sys.setrgid(integer)   => nil\n *\n *  Set the real group ID of the calling process to _integer_.\n *  Not available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setrgid(obj, id)\n    VALUE obj, id;\n{\n#if defined HAVE_SETRGID\n    check_gid_switch();\n    if (setrgid(NUM2INT(id)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n\n/*\n *  call-seq:\n *     Process::Sys.setegid(integer)   => nil\n *\n *  Set the effective group ID of the calling process to\n *  _integer_.  Not available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setegid(obj, id)\n    VALUE obj, id;\n{\n#if defined HAVE_SETEGID\n    check_gid_switch();\n    if (setegid(NUM2INT(id)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process::Sys.setregid(rid, eid)   => nil\n *\n *  Sets the (integer) real and/or effective group IDs of the current\n *  process to <em>rid</em> and <em>eid</em>, respectively. A value of\n *  <code>-1</code> for either means to leave that ID unchanged. Not\n *  available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setregid(obj, rid, eid)\n    VALUE obj, rid, eid;\n{\n#if defined HAVE_SETREGID\n    check_gid_switch();\n    if (setregid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     Process::Sys.setresgid(rid, eid, sid)   => nil\n *\n *  Sets the (integer) real, effective, and saved user IDs of the\n *  current process to <em>rid</em>, <em>eid</em>, and <em>sid</em>\n *  respectively. A value of <code>-1</code> for any value means to\n *  leave that ID unchanged. Not available on all platforms.\n *\n */\n\nstatic VALUE\np_sys_setresgid(obj, rid, eid, sid)\n    VALUE obj, rid, eid, sid;\n{\n#if defined HAVE_SETRESGID\n    check_gid_switch();\n    if (setresgid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     Process::Sys.issetugid   => true or false\n *\n *  Returns +true+ if the process was created as a result\n *  of an execve(2) system call which had either of the setuid or\n *  setgid bits set (and extra privileges were given as a result) or\n *  if it has changed any of its real, effective or saved user or\n *  group IDs since it began execution.\n *\n */\n\nstatic VALUE\np_sys_issetugid(obj)\n    VALUE obj;\n{\n#if defined HAVE_ISSETUGID\n    rb_secure(2);\n    if (issetugid()) {\n\treturn Qtrue;\n    } else {\n\treturn Qfalse;\n    }\n#else\n    rb_notimplement();\n    return Qnil;\t\t/* not reached */\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.gid           => fixnum\n *     Process::GID.rid      => fixnum\n *     Process::Sys.getgid   => fixnum\n *\n *  Returns the (real) group ID for this process.\n *\n *     Process.gid   #=> 500\n */\n\nstatic VALUE\nproc_getgid(obj)\n    VALUE obj;\n{\n    int gid = getgid();\n    return INT2FIX(gid);\n}\n\n\n/*\n *  call-seq:\n *     Process.gid= fixnum   => fixnum\n *\n *  Sets the group ID for this process.\n */\n\nstatic VALUE\nproc_setgid(obj, id)\n    VALUE obj, id;\n{\n    int gid = NUM2INT(id);\n\n    check_gid_switch();\n#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)\n    if (setresgid(gid, -1, -1) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETREGID\n    if (setregid(gid, -1) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETRGID\n    if (setrgid(gid) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETGID\n    {\n\tif (getegid() == gid) {\n\t    if (setgid(gid) < 0) rb_sys_fail(0);\n\t}\n\telse {\n\t    rb_notimplement();\n\t}\n    }\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(gid);\n}\n\n\nstatic size_t maxgroups = 32;\n\n\n/*\n *  call-seq:\n *     Process.groups   => array\n *\n *  Get an <code>Array</code> of the gids of groups in the\n *  supplemental group access list for this process.\n *\n *     Process.groups   #=> [27, 6, 10, 11]\n *\n */\n\nstatic VALUE\nproc_getgroups(VALUE obj)\n{\n#ifdef HAVE_GETGROUPS\n    VALUE ary;\n    size_t ngroups;\n    rb_gid_t *groups;\n    int i;\n\n    groups = ALLOCA_N(rb_gid_t, maxgroups);\n\n    ngroups = getgroups(maxgroups, groups);\n    if (ngroups == -1)\n\trb_sys_fail(0);\n\n    ary = rb_ary_new();\n    for (i = 0; i < ngroups; i++)\n\trb_ary_push(ary, INT2NUM(groups[i]));\n\n    return ary;\n#else\n    rb_notimplement();\n    return Qnil;\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.groups= array   => array\n *\n *  Set the supplemental group access list to the given\n *  <code>Array</code> of group IDs.\n *\n *     Process.groups   #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]\n *     Process.groups = [27, 6, 10, 11]   #=> [27, 6, 10, 11]\n *     Process.groups   #=> [27, 6, 10, 11]\n *\n */\n\nstatic VALUE\nproc_setgroups(VALUE obj, VALUE ary)\n{\n#ifdef HAVE_SETGROUPS\n    size_t ngroups;\n    rb_gid_t *groups;\n    int i;\n    struct group *gr;\n\n    Check_Type(ary, T_ARRAY);\n\n    ngroups = RARRAY(ary)->len;\n    if (ngroups > maxgroups)\n\trb_raise(rb_eArgError, \"too many groups, %d max\", maxgroups);\n\n    groups = ALLOCA_N(rb_gid_t, ngroups);\n\n    for (i = 0; i < ngroups && i < RARRAY(ary)->len; i++) {\n\tVALUE g = RARRAY(ary)->ptr[i];\n\n\tif (FIXNUM_P(g)) {\n\t    groups[i] = FIX2INT(g);\n\t}\n\telse {\n\t    VALUE tmp = rb_check_string_type(g);\n\n\t    if (NIL_P(tmp)) {\n\t\tgroups[i] = NUM2INT(g);\n\t    }\n\t    else {\n\t\tgr = getgrnam(RSTRING(tmp)->ptr);\n\t\tif (gr == NULL)\n\t\t    rb_raise(rb_eArgError,\n\t\t\t     \"can't find group for %s\", RSTRING(tmp)->ptr);\n\t\tgroups[i] = gr->gr_gid;\n\t    }\n\t}\n    }\n\n    i = setgroups(ngroups, groups);\n    if (i == -1)\n\trb_sys_fail(0);\n\n    return proc_getgroups(obj);\n#else\n    rb_notimplement();\n    return Qnil;\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.initgroups(username, gid)   => array\n *\n *  Initializes the supplemental group access list by reading the\n *  system group database and using all groups of which the given user\n *  is a member. The group with the specified <em>gid</em> is also\n *  added to the list. Returns the resulting <code>Array</code> of the\n *  gids of all the groups in the supplementary group access list. Not\n *  available on all platforms.\n *\n *     Process.groups   #=> [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27]\n *     Process.initgroups( \"mgranger\", 30 )   #=> [30, 6, 10, 11]\n *     Process.groups   #=> [30, 6, 10, 11]\n *\n */\n\nstatic VALUE\nproc_initgroups(obj, uname, base_grp)\n    VALUE obj, uname, base_grp;\n{\n#ifdef HAVE_INITGROUPS\n    if (initgroups(StringValuePtr(uname), (rb_gid_t)NUM2INT(base_grp)) != 0) {\n\trb_sys_fail(0);\n    }\n    return proc_getgroups(obj);\n#else\n    rb_notimplement();\n    return Qnil;\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.maxgroups   => fixnum\n *\n *  Returns the maximum number of gids allowed in the supplemental\n *  group access list.\n *\n *     Process.maxgroups   #=> 32\n */\n\nstatic VALUE\nproc_getmaxgroups(obj)\n    VALUE obj;\n{\n    return INT2FIX(maxgroups);\n}\n\n\n/*\n *  call-seq:\n *     Process.maxgroups= fixnum   => fixnum\n *\n *  Sets the maximum number of gids allowed in the supplemental group\n *  access list.\n */\n\nstatic VALUE\nproc_setmaxgroups(VALUE obj, VALUE val)\n{\n    size_t  ngroups = FIX2INT(val);\n\n    if (ngroups > 4096)\n\tngroups = 4096;\n\n    maxgroups = ngroups;\n\n    return INT2FIX(maxgroups);\n}\n\n\n/********************************************************************\n *\n * Document-class: Process::GID\n *\n *  The <code>Process::GID</code> module contains a collection of\n *  module functions which can be used to portably get, set, and\n *  switch the current process's real, effective, and saved group IDs.\n *\n */\n\nstatic int SAVED_GROUP_ID = -1;\n\n#ifdef BROKEN_SETREGID\nint\nsetregid(rgid, egid)\n    rb_gid_t rgid, egid;\n{\n    if (rgid != -1 && rgid != getgid()) {\n\tif (egid == -1) egid = getegid();\n\tif (setgid(rgid) < 0) return -1;\n    }\n    if (egid != -1 && egid != getegid()) {\n\tif (setegid(egid) < 0) return -1;\n    }\n    return 0;\n}\n#endif\n\n/*\n *  call-seq:\n *     Process::GID.change_privilege(integer)   => fixnum\n *\n *  Change the current process's real and effective group ID to that\n *  specified by _integer_. Returns the new group ID. Not\n *  available on all platforms.\n *\n *     [Process.gid, Process.egid]          #=> [0, 0]\n *     Process::GID.change_privilege(33)    #=> 33\n *     [Process.gid, Process.egid]          #=> [33, 33]\n */\n\nstatic VALUE\np_gid_change_privilege(obj, id)\n    VALUE obj, id;\n{\n    int gid;\n\n    check_gid_switch();\n\n    gid = NUM2INT(id);\n\n    if (geteuid() == 0) { /* root-user */\n#if defined(HAVE_SETRESGID)\n\tif (setresgid(gid, gid, gid) < 0) rb_sys_fail(0);\n\tSAVED_GROUP_ID = gid;\n#elif defined HAVE_SETGID\n\tif (setgid(gid) < 0) rb_sys_fail(0);\n\tSAVED_GROUP_ID = gid;\n#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)\n\tif (getgid() == gid) {\n\t    if (SAVED_GROUP_ID == gid) {\n\t\tif (setregid(-1, gid) < 0) rb_sys_fail(0);\n\t    } else {\n\t\tif (gid == 0) { /* (r,e,s) == (root, y, x) */\n\t\t    if (setregid(-1, SAVED_GROUP_ID) < 0) rb_sys_fail(0);\n\t\t    if (setregid(SAVED_GROUP_ID, 0) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = 0; /* (r,e,s) == (x, root, root) */\n\t\t    if (setregid(gid, gid) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = gid;\n\t\t} else { /* (r,e,s) == (z, y, x) */\n\t\t    if (setregid(0, 0) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = 0;\n\t\t    if (setregid(gid, gid) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = gid;\n\t\t}\n\t    }\n\t} else {\n\t    if (setregid(gid, gid) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t}\n#elif defined(HAVE_SETRGID) && defined (HAVE_SETEGID)\n\tif (getgid() == gid) {\n\t    if (SAVED_GROUP_ID == gid) {\n\t\tif (setegid(gid) < 0) rb_sys_fail(0);\n\t    } else {\n\t\tif (gid == 0) {\n\t\t    if (setegid(gid) < 0) rb_sys_fail(0);\n\t\t    if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = 0;\n\t\t    if (setrgid(0) < 0) rb_sys_fail(0);\n\t\t} else {\n\t\t    if (setrgid(0) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = 0;\n\t\t    if (setegid(gid) < 0) rb_sys_fail(0);\n\t\t    if (setrgid(gid) < 0) rb_sys_fail(0);\n\t\t    SAVED_GROUP_ID = gid;\n\t\t}\n\t    }\n\t} else {\n\t    if (setegid(gid) < 0) rb_sys_fail(0);\n\t    if (setrgid(gid) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t}\n#else\n\trb_notimplement();\n#endif\n    } else { /* unprivileged user */\n#if defined(HAVE_SETRESGID)\n\tif (setresgid((getgid() == gid)? -1: gid,\n\t\t      (getegid() == gid)? -1: gid,\n\t\t      (SAVED_GROUP_ID == gid)? -1: gid) < 0) rb_sys_fail(0);\n\tSAVED_GROUP_ID = gid;\n#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)\n\tif (SAVED_GROUP_ID == gid) {\n\t    if (setregid((getgid() == gid)? -1: gid,\n\t\t\t (getegid() == gid)? -1: gid) < 0) rb_sys_fail(0);\n\t} else if (getgid() != gid) {\n\t    if (setregid(gid, (getegid() == gid)? -1: gid) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t} else if (/* getgid() == gid && */ getegid() != gid) {\n\t    if (setregid(getegid(), gid) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t    if (setregid(gid, -1) < 0) rb_sys_fail(0);\n\t} else { /* getgid() == gid && getegid() == gid */\n\t    if (setregid(-1, SAVED_GROUP_ID) < 0) rb_sys_fail(0);\n\t    if (setregid(SAVED_GROUP_ID, gid) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t    if (setregid(gid, -1) < 0) rb_sys_fail(0);\n\t}\n#elif defined(HAVE_SETRGID) && defined(HAVE_SETEGID)\n\tif (SAVED_GROUP_ID == gid) {\n\t    if (getegid() != gid && setegid(gid) < 0) rb_sys_fail(0);\n\t    if (getgid() != gid && setrgid(gid) < 0) rb_sys_fail(0);\n\t} else if (/* SAVED_GROUP_ID != gid && */ getegid() == gid) {\n\t    if (getgid() != gid) {\n\t\tif (setrgid(gid) < 0) rb_sys_fail(0);\n\t\tSAVED_GROUP_ID = gid;\n\t    } else {\n\t\tif (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);\n\t\tSAVED_GROUP_ID = gid;\n\t\tif (setrgid(gid) < 0) rb_sys_fail(0);\n\t    }\n\t} else if (/* getegid() != gid && */ getgid() == gid) {\n\t    if (setegid(gid) < 0) rb_sys_fail(0);\n\t    if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t    if (setrgid(gid) < 0) rb_sys_fail(0);\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#elif defined HAVE_44BSD_SETGID\n\tif (getgid() == gid) {\n\t    /* (r,e,s)==(gid,?,?) ==> (gid,gid,gid) */\n\t    if (setgid(gid) < 0) rb_sys_fail(0);\n\t    SAVED_GROUP_ID = gid;\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#elif defined HAVE_SETEGID\n\tif (getgid() == gid && SAVED_GROUP_ID == gid) {\n\t    if (setegid(gid) < 0) rb_sys_fail(0);\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#elif defined HAVE_SETGID\n\tif (getgid() == gid && SAVED_GROUP_ID == gid) {\n\t    if (setgid(gid) < 0) rb_sys_fail(0);\n\t} else {\n\t    errno = EPERM;\n\t    rb_sys_fail(0);\n\t}\n#else\n\trb_notimplement();\n#endif\n    }\n    return INT2FIX(gid);\n}\n\n\n/*\n *  call-seq:\n *     Process.euid           => fixnum\n *     Process::UID.eid       => fixnum\n *     Process::Sys.geteuid   => fixnum\n *\n *  Returns the effective user ID for this process.\n *\n *     Process.euid   #=> 501\n */\n\nstatic VALUE\nproc_geteuid(obj)\n    VALUE obj;\n{\n    int euid = geteuid();\n    return INT2FIX(euid);\n}\n\n\n/*\n *  call-seq:\n *     Process.euid= integer\n *\n *  Sets the effective user ID for this process. Not available on all\n *  platforms.\n */\n\nstatic VALUE\nproc_seteuid(obj, euid)\n    VALUE obj, euid;\n{\n    check_uid_switch();\n#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)\n    if (setresuid(-1, NUM2INT(euid), -1) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETREUID\n    if (setreuid(-1, NUM2INT(euid)) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETEUID\n    if (seteuid(NUM2INT(euid)) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETUID\n    euid = NUM2INT(euid);\n    if (euid == getuid()) {\n\tif (setuid(euid) < 0) rb_sys_fail(0);\n    }\n    else {\n\trb_notimplement();\n    }\n#else\n    rb_notimplement();\n#endif\n    return euid;\n}\n\nstatic VALUE\nrb_seteuid_core(euid)\n    int euid;\n{\n    int uid;\n\n    check_uid_switch();\n\n    uid = getuid();\n\n#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)\n    if (uid != euid) {\n\tif (setresuid(-1,euid,euid) < 0) rb_sys_fail(0);\n\tSAVED_USER_ID = euid;\n    } else {\n\tif (setresuid(-1,euid,-1) < 0) rb_sys_fail(0);\n    }\n#elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)\n    if (setreuid(-1, euid) < 0) rb_sys_fail(0);\n    if (uid != euid) {\n\tif (setreuid(euid,uid) < 0) rb_sys_fail(0);\n\tif (setreuid(uid,euid) < 0) rb_sys_fail(0);\n\tSAVED_USER_ID = euid;\n    }\n#elif defined HAVE_SETEUID\n    if (seteuid(euid) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETUID\n    if (geteuid() == 0) rb_sys_fail(0);\n    if (setuid(euid) < 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(euid);\n}\n\n\n/*\n *  call-seq:\n *     Process::UID.grant_privilege(integer)   => fixnum\n *     Process::UID.eid= integer               => fixnum\n *\n *  Set the effective user ID, and if possible, the saved user ID of\n *  the process to the given _integer_. Returns the new\n *  effective user ID. Not available on all platforms.\n *\n *     [Process.uid, Process.euid]          #=> [0, 0]\n *     Process::UID.grant_privilege(31)     #=> 31\n *     [Process.uid, Process.euid]          #=> [0, 31]\n */\n\nstatic VALUE\np_uid_grant_privilege(obj, id)\n    VALUE obj, id;\n{\n    return rb_seteuid_core(NUM2INT(id));\n}\n\n\n/*\n *  call-seq:\n *     Process.egid          => fixnum\n *     Process::GID.eid      => fixnum\n *     Process::Sys.geteid   => fixnum\n *\n *  Returns the effective group ID for this process. Not available on\n *  all platforms.\n *\n *     Process.egid   #=> 500\n */\n\nstatic VALUE\nproc_getegid(obj)\n    VALUE obj;\n{\n    int egid = getegid();\n\n    return INT2FIX(egid);\n}\n\n\n/*\n *  call-seq:\n *     Process.egid = fixnum   => fixnum\n *\n *  Sets the effective group ID for this process. Not available on all\n *  platforms.\n */\n\nstatic VALUE\nproc_setegid(obj, egid)\n    VALUE obj, egid;\n{\n    check_gid_switch();\n\n#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)\n    if (setresgid(-1, NUM2INT(egid), -1) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETREGID\n    if (setregid(-1, NUM2INT(egid)) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETEGID\n    if (setegid(NUM2INT(egid)) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETGID\n    egid = NUM2INT(egid);\n    if (egid == getgid()) {\n\tif (setgid(egid) < 0) rb_sys_fail(0);\n    }\n    else {\n\trb_notimplement();\n    }\n#else\n    rb_notimplement();\n#endif\n    return egid;\n}\n\nstatic VALUE\nrb_setegid_core(egid)\n    int egid;\n{\n    int gid;\n\n    check_gid_switch();\n\n    gid = getgid();\n\n#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)\n    if (gid != egid) {\n\tif (setresgid(-1,egid,egid) < 0) rb_sys_fail(0);\n\tSAVED_GROUP_ID = egid;\n    } else {\n\tif (setresgid(-1,egid,-1) < 0) rb_sys_fail(0);\n    }\n#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)\n    if (setregid(-1, egid) < 0) rb_sys_fail(0);\n    if (gid != egid) {\n\tif (setregid(egid,gid) < 0) rb_sys_fail(0);\n\tif (setregid(gid,egid) < 0) rb_sys_fail(0);\n\tSAVED_GROUP_ID = egid;\n    }\n#elif defined HAVE_SETEGID\n    if (setegid(egid) < 0) rb_sys_fail(0);\n#elif defined HAVE_SETGID\n    if (geteuid() == 0 /* root user */) rb_sys_fail(0);\n    if (setgid(egid) < 0) rb_sys_fail(0);\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(egid);\n}\n\n\n/*\n *  call-seq:\n *     Process::GID.grant_privilege(integer)    => fixnum\n *     Process::GID.eid = integer               => fixnum\n *\n *  Set the effective group ID, and if possible, the saved group ID of\n *  the process to the given _integer_. Returns the new\n *  effective group ID. Not available on all platforms.\n *\n *     [Process.gid, Process.egid]          #=> [0, 0]\n *     Process::GID.grant_privilege(31)     #=> 33\n *     [Process.gid, Process.egid]          #=> [0, 33]\n */\n\nstatic VALUE\np_gid_grant_privilege(obj, id)\n    VALUE obj, id;\n{\n    return rb_setegid_core(NUM2INT(id));\n}\n\n\n/*\n *  call-seq:\n *     Process::UID.re_exchangeable?   => true or false\n *\n *  Returns +true+ if the real and effective user IDs of a\n *  process may be exchanged on the current platform.\n *\n */\n\nstatic VALUE\np_uid_exchangeable()\n{\n#if defined(HAVE_SETRESUID) &&  !defined(__CHECKER__)\n    return Qtrue;\n#elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)\n    return Qtrue;\n#else\n    return Qfalse;\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process::UID.re_exchange   => fixnum\n *\n *  Exchange real and effective user IDs and return the new effective\n *  user ID. Not available on all platforms.\n *\n *     [Process.uid, Process.euid]   #=> [0, 31]\n *     Process::UID.re_exchange      #=> 0\n *     [Process.uid, Process.euid]   #=> [31, 0]\n */\n\nstatic VALUE\np_uid_exchange(obj)\n    VALUE obj;\n{\n    int uid, euid;\n\n    check_uid_switch();\n\n    uid = getuid();\n    euid = geteuid();\n\n#if defined(HAVE_SETRESUID) &&  !defined(__CHECKER__)\n    if (setresuid(euid, uid, uid) < 0) rb_sys_fail(0);\n    SAVED_USER_ID = uid;\n#elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)\n    if (setreuid(euid,uid) < 0) rb_sys_fail(0);\n    SAVED_USER_ID = uid;\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(uid);\n}\n\n\n/*\n *  call-seq:\n *     Process::GID.re_exchangeable?   => true or false\n *\n *  Returns +true+ if the real and effective group IDs of a\n *  process may be exchanged on the current platform.\n *\n */\n\nstatic VALUE\np_gid_exchangeable()\n{\n#if defined(HAVE_SETRESGID) &&  !defined(__CHECKER__)\n    return Qtrue;\n#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)\n    return Qtrue;\n#else\n    return Qfalse;\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process::GID.re_exchange   => fixnum\n *\n *  Exchange real and effective group IDs and return the new effective\n *  group ID. Not available on all platforms.\n *\n *     [Process.gid, Process.egid]   #=> [0, 33]\n *     Process::GID.re_exchange      #=> 0\n *     [Process.gid, Process.egid]   #=> [33, 0]\n */\n\nstatic VALUE\np_gid_exchange(obj)\n    VALUE obj;\n{\n    int gid, egid;\n\n    check_gid_switch();\n\n    gid = getgid();\n    egid = getegid();\n\n#if defined(HAVE_SETRESGID) &&  !defined(__CHECKER__)\n    if (setresgid(egid, gid, gid) < 0) rb_sys_fail(0);\n    SAVED_GROUP_ID = gid;\n#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)\n    if (setregid(egid,gid) < 0) rb_sys_fail(0);\n    SAVED_GROUP_ID = gid;\n#else\n    rb_notimplement();\n#endif\n    return INT2FIX(gid);\n}\n\n/* [MG] :FIXME: Is this correct? I'm not sure how to phrase this. */\n\n/*\n *  call-seq:\n *     Process::UID.sid_available?   => true or false\n *\n *  Returns +true+ if the current platform has saved user\n *  ID functionality.\n *\n */\n\nstatic VALUE\np_uid_have_saved_id()\n{\n#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)\n    return Qtrue;\n#else\n    return Qfalse;\n#endif\n}\n\n\n#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)\nstatic VALUE\np_uid_sw_ensure(id)\n    int id;\n{\n    under_uid_switch = 0;\n    return rb_seteuid_core(id);\n}\n\n\n/*\n *  call-seq:\n *     Process::UID.switch              => fixnum\n *     Process::UID.switch {|| block}   => object\n *\n *  Switch the effective and real user IDs of the current process. If\n *  a <em>block</em> is given, the user IDs will be switched back\n *  after the block is executed. Returns the new effective user ID if\n *  called without a block, and the return value of the block if one\n *  is given.\n *\n */\n\nstatic VALUE\np_uid_switch(obj)\n    VALUE obj;\n{\n    int uid, euid;\n\n    check_uid_switch();\n\n    uid = getuid();\n    euid = geteuid();\n\n    if (uid != euid) {\n\tproc_seteuid(obj, INT2FIX(uid));\n\tif (rb_block_given_p()) {\n\t    under_uid_switch = 1;\n\t    return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, SAVED_USER_ID);\n\t} else {\n\t    return INT2FIX(euid);\n\t}\n    } else if (euid != SAVED_USER_ID) {\n\tproc_seteuid(obj, INT2FIX(SAVED_USER_ID));\n\tif (rb_block_given_p()) {\n\t    under_uid_switch = 1;\n\t    return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, euid);\n\t} else {\n\t    return INT2FIX(uid);\n\t}\n    } else {\n\terrno = EPERM;\n\trb_sys_fail(0);\n    }\n\n#else\nstatic VALUE\np_uid_sw_ensure(obj)\n    VALUE obj;\n{\n    under_uid_switch = 0;\n    return p_uid_exchange(obj);\n}\n\nstatic VALUE\np_uid_switch(obj)\n    VALUE obj;\n{\n    int uid, euid;\n\n    check_uid_switch();\n\n    uid = getuid();\n    euid = geteuid();\n\n    if (uid == euid) {\n\terrno = EPERM;\n\trb_sys_fail(0);\n    }\n    p_uid_exchange(obj);\n    if (rb_block_given_p()) {\n\tunder_uid_switch = 1;\n\treturn rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, obj);\n    } else {\n\treturn INT2FIX(euid);\n    }\n#endif\n}\n\n\n/* [MG] :FIXME: Is this correct? I'm not sure how to phrase this. */\n\n/*\n *  call-seq:\n *     Process::GID.sid_available?   => true or false\n *\n *  Returns +true+ if the current platform has saved group\n *  ID functionality.\n *\n */\n\nstatic VALUE\np_gid_have_saved_id()\n{\n#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)\n    return Qtrue;\n#else\n    return Qfalse;\n#endif\n}\n\n#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)\nstatic VALUE\np_gid_sw_ensure(id)\n    int id;\n{\n    under_gid_switch = 0;\n    return rb_setegid_core(id);\n}\n\n\n/*\n *  call-seq:\n *     Process::GID.switch              => fixnum\n *     Process::GID.switch {|| block}   => object\n *\n *  Switch the effective and real group IDs of the current process. If\n *  a <em>block</em> is given, the group IDs will be switched back\n *  after the block is executed. Returns the new effective group ID if\n *  called without a block, and the return value of the block if one\n *  is given.\n *\n */\n\nstatic VALUE\np_gid_switch(obj)\n    VALUE obj;\n{\n    int gid, egid;\n\n    check_gid_switch();\n\n    gid = getgid();\n    egid = getegid();\n\n    if (gid != egid) {\n\tproc_setegid(obj, INT2FIX(gid));\n\tif (rb_block_given_p()) {\n\t    under_gid_switch = 1;\n\t    return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, SAVED_GROUP_ID);\n\t} else {\n\t    return INT2FIX(egid);\n\t}\n    } else if (egid != SAVED_GROUP_ID) {\n\tproc_setegid(obj, INT2FIX(SAVED_GROUP_ID));\n\tif (rb_block_given_p()) {\n\t    under_gid_switch = 1;\n\t    return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, egid);\n\t} else {\n\t    return INT2FIX(gid);\n\t}\n    } else {\n\terrno = EPERM;\n\trb_sys_fail(0);\n    }\n#else\nstatic VALUE\np_gid_sw_ensure(obj)\n    VALUE obj;\n{\n    under_gid_switch = 0;\n    return p_gid_exchange(obj);\n}\n\nstatic VALUE\np_gid_switch(obj)\n    VALUE obj;\n{\n    int gid, egid;\n\n    check_gid_switch();\n\n    gid = getgid();\n    egid = getegid();\n\n    if (gid == egid) {\n\terrno = EPERM;\n\trb_sys_fail(0);\n    }\n    p_gid_exchange(obj);\n    if (rb_block_given_p()) {\n\tunder_gid_switch = 1;\n\treturn rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, obj);\n    } else {\n\treturn INT2FIX(egid);\n    }\n#endif\n}\n\n\n/*\n *  call-seq:\n *     Process.times   => aStructTms\n *\n *  Returns a <code>Tms</code> structure (see <code>Struct::Tms</code>\n *  on page 388) that contains user and system CPU times for this\n *  process.\n *\n *     t = Process.times\n *     [ t.utime, t.stime ]   #=> [0.0, 0.02]\n */\n\nVALUE\nrb_proc_times(obj)\n    VALUE obj;\n{\n#if defined(HAVE_TIMES) && !defined(__CHECKER__)\n    const double hertz =\n#ifdef HAVE__SC_CLK_TCK\n\t(double)sysconf(_SC_CLK_TCK);\n#else\n#ifndef HZ\n# ifdef CLK_TCK\n#   define HZ CLK_TCK\n# else\n#   define HZ 60\n# endif\n#endif /* HZ */\n\tHZ;\n#endif\n    struct tms buf;\n    volatile VALUE utime, stime, cutime, sctime;\n\n    times(&buf);\n    return rb_struct_new(S_Tms,\n\t\t\t utime = rb_float_new(buf.tms_utime / hertz),\n\t\t\t stime = rb_float_new(buf.tms_stime / hertz),\n\t\t\t cutime = rb_float_new(buf.tms_cutime / hertz),\n\t\t\t sctime = rb_float_new(buf.tms_cstime / hertz));\n#else\n    rb_notimplement();\n#endif\n}\n\nVALUE rb_mProcess;\nVALUE rb_mProcUID;\nVALUE rb_mProcGID;\nVALUE rb_mProcID_Syscall;\n\n\n/*\n *  The <code>Process</code> module is a collection of methods used to\n *  manipulate processes.\n */\n\nvoid\nInit_process()\n{\n    rb_define_virtual_variable(\"$$\", get_pid, 0);\n    rb_define_readonly_variable(\"$?\", &rb_last_status);\n    rb_define_global_function(\"exec\", rb_f_exec, -1);\n    rb_define_global_function(\"fork\", rb_f_fork, 0);\n    rb_define_global_function(\"exit!\", rb_f_exit_bang, -1);\n    rb_define_global_function(\"system\", rb_f_system, -1);\n    rb_define_global_function(\"sleep\", rb_f_sleep, -1);\n\n    rb_mProcess = rb_define_module(\"Process\");\n\n#if !defined(_WIN32) && !defined(DJGPP)\n#ifdef WNOHANG\n    rb_define_const(rb_mProcess, \"WNOHANG\", INT2FIX(WNOHANG));\n#else\n    rb_define_const(rb_mProcess, \"WNOHANG\", INT2FIX(0));\n#endif\n#ifdef WUNTRACED\n    rb_define_const(rb_mProcess, \"WUNTRACED\", INT2FIX(WUNTRACED));\n#else\n    rb_define_const(rb_mProcess, \"WUNTRACED\", INT2FIX(0));\n#endif\n#endif\n\n    rb_define_singleton_method(rb_mProcess, \"exec\", rb_f_exec, -1);\n    rb_define_singleton_method(rb_mProcess, \"fork\", rb_f_fork, 0);\n    rb_define_singleton_method(rb_mProcess, \"exit!\", rb_f_exit_bang, -1);\n    rb_define_singleton_method(rb_mProcess, \"exit\", rb_f_exit, -1);   /* in eval.c */\n    rb_define_singleton_method(rb_mProcess, \"abort\", rb_f_abort, -1); /* in eval.c */\n\n    rb_define_module_function(rb_mProcess, \"kill\", rb_f_kill, -1); /* in signal.c */\n    rb_define_module_function(rb_mProcess, \"wait\", proc_wait, -1);\n    rb_define_module_function(rb_mProcess, \"wait2\", proc_wait2, -1);\n    rb_define_module_function(rb_mProcess, \"waitpid\", proc_wait, -1);\n    rb_define_module_function(rb_mProcess, \"waitpid2\", proc_wait2, -1);\n    rb_define_module_function(rb_mProcess, \"waitall\", proc_waitall, 0);\n    rb_define_module_function(rb_mProcess, \"detach\", proc_detach, 1);\n\n    rb_cProcStatus = rb_define_class_under(rb_mProcess, \"Status\", rb_cObject);\n    rb_undef_method(CLASS_OF(rb_cProcStatus), \"new\");\n\n    rb_define_method(rb_cProcStatus, \"==\", pst_equal, 1);\n    rb_define_method(rb_cProcStatus, \"&\", pst_bitand, 1);\n    rb_define_method(rb_cProcStatus, \">>\", pst_rshift, 1);\n    rb_define_method(rb_cProcStatus, \"to_i\", pst_to_i, 0);\n    rb_define_method(rb_cProcStatus, \"to_int\", pst_to_i, 0);\n    rb_define_method(rb_cProcStatus, \"to_s\", pst_to_s, 0);\n    rb_define_method(rb_cProcStatus, \"inspect\", pst_inspect, 0);\n\n    rb_define_method(rb_cProcStatus, \"pid\", pst_pid, 0);\n\n    rb_define_method(rb_cProcStatus, \"stopped?\", pst_wifstopped, 0);\n    rb_define_method(rb_cProcStatus, \"stopsig\", pst_wstopsig, 0);\n    rb_define_method(rb_cProcStatus, \"signaled?\", pst_wifsignaled, 0);\n    rb_define_method(rb_cProcStatus, \"termsig\", pst_wtermsig, 0);\n    rb_define_method(rb_cProcStatus, \"exited?\", pst_wifexited, 0);\n    rb_define_method(rb_cProcStatus, \"exitstatus\", pst_wexitstatus, 0);\n    rb_define_method(rb_cProcStatus, \"success?\", pst_success_p, 0);\n    rb_define_method(rb_cProcStatus, \"coredump?\", pst_wcoredump, 0);\n\n    rb_define_module_function(rb_mProcess, \"pid\", get_pid, 0);\n    rb_define_module_function(rb_mProcess, \"ppid\", get_ppid, 0);\n\n    rb_define_module_function(rb_mProcess, \"getpgrp\", proc_getpgrp, 0);\n    rb_define_module_function(rb_mProcess, \"setpgrp\", proc_setpgrp, 0);\n    rb_define_module_function(rb_mProcess, \"getpgid\", proc_getpgid, 1);\n    rb_define_module_function(rb_mProcess, \"setpgid\", proc_setpgid, 2);\n\n    rb_define_module_function(rb_mProcess, \"setsid\", proc_setsid, 0);\n\n    rb_define_module_function(rb_mProcess, \"getpriority\", proc_getpriority, 2);\n    rb_define_module_function(rb_mProcess, \"setpriority\", proc_setpriority, 3);\n\n#ifdef HAVE_GETPRIORITY\n    rb_define_const(rb_mProcess, \"PRIO_PROCESS\", INT2FIX(PRIO_PROCESS));\n    rb_define_const(rb_mProcess, \"PRIO_PGRP\", INT2FIX(PRIO_PGRP));\n    rb_define_const(rb_mProcess, \"PRIO_USER\", INT2FIX(PRIO_USER));\n#endif\n\n    rb_define_module_function(rb_mProcess, \"getrlimit\", proc_getrlimit, 1);\n    rb_define_module_function(rb_mProcess, \"setrlimit\", proc_setrlimit, -1);\n#ifdef RLIM2NUM\n    {\n        VALUE inf = RLIM2NUM(RLIM_INFINITY), v;\n        rb_define_const(rb_mProcess, \"RLIM_INFINITY\", inf);\n#ifdef RLIM_SAVED_MAX\n        v = RLIM_INFINITY == RLIM_SAVED_MAX ? inf : RLIM2NUM(RLIM_SAVED_MAX);\n        rb_define_const(rb_mProcess, \"RLIM_SAVED_MAX\", v);\n#endif\n#ifdef RLIM_SAVED_CUR\n        v = RLIM_INFINITY == RLIM_SAVED_CUR ? inf : RLIM2NUM(RLIM_SAVED_CUR);\n        rb_define_const(rb_mProcess, \"RLIM_SAVED_CUR\", v);\n#endif\n    }\n#ifdef RLIMIT_CORE\n    rb_define_const(rb_mProcess, \"RLIMIT_CORE\", INT2FIX(RLIMIT_CORE));\n#endif\n#ifdef RLIMIT_CPU\n    rb_define_const(rb_mProcess, \"RLIMIT_CPU\", INT2FIX(RLIMIT_CPU));\n#endif\n#ifdef RLIMIT_DATA\n    rb_define_const(rb_mProcess, \"RLIMIT_DATA\", INT2FIX(RLIMIT_DATA));\n#endif\n#ifdef RLIMIT_FSIZE\n    rb_define_const(rb_mProcess, \"RLIMIT_FSIZE\", INT2FIX(RLIMIT_FSIZE));\n#endif\n#ifdef RLIMIT_NOFILE\n    rb_define_const(rb_mProcess, \"RLIMIT_NOFILE\", INT2FIX(RLIMIT_NOFILE));\n#endif\n#ifdef RLIMIT_STACK\n    rb_define_const(rb_mProcess, \"RLIMIT_STACK\", INT2FIX(RLIMIT_STACK));\n#endif\n#ifdef RLIMIT_AS\n    rb_define_const(rb_mProcess, \"RLIMIT_AS\", INT2FIX(RLIMIT_AS));\n#endif\n#ifdef RLIMIT_MEMLOCK\n    rb_define_const(rb_mProcess, \"RLIMIT_MEMLOCK\", INT2FIX(RLIMIT_MEMLOCK));\n#endif\n#ifdef RLIMIT_NPROC\n    rb_define_const(rb_mProcess, \"RLIMIT_NPROC\", INT2FIX(RLIMIT_NPROC));\n#endif\n#ifdef RLIMIT_RSS\n    rb_define_const(rb_mProcess, \"RLIMIT_RSS\", INT2FIX(RLIMIT_RSS));\n#endif\n#ifdef RLIMIT_SBSIZE\n    rb_define_const(rb_mProcess, \"RLIMIT_SBSIZE\", INT2FIX(RLIMIT_SBSIZE));\n#endif\n#endif\n\n    rb_define_module_function(rb_mProcess, \"uid\", proc_getuid, 0);\n    rb_define_module_function(rb_mProcess, \"uid=\", proc_setuid, 1);\n    rb_define_module_function(rb_mProcess, \"gid\", proc_getgid, 0);\n    rb_define_module_function(rb_mProcess, \"gid=\", proc_setgid, 1);\n    rb_define_module_function(rb_mProcess, \"euid\", proc_geteuid, 0);\n    rb_define_module_function(rb_mProcess, \"euid=\", proc_seteuid, 1);\n    rb_define_module_function(rb_mProcess, \"egid\", proc_getegid, 0);\n    rb_define_module_function(rb_mProcess, \"egid=\", proc_setegid, 1);\n    rb_define_module_function(rb_mProcess, \"initgroups\", proc_initgroups, 2);\n    rb_define_module_function(rb_mProcess, \"groups\", proc_getgroups, 0);\n    rb_define_module_function(rb_mProcess, \"groups=\", proc_setgroups, 1);\n    rb_define_module_function(rb_mProcess, \"maxgroups\", proc_getmaxgroups, 0);\n    rb_define_module_function(rb_mProcess, \"maxgroups=\", proc_setmaxgroups, 1);\n\n    rb_define_module_function(rb_mProcess, \"times\", rb_proc_times, 0);\n\n#if defined(HAVE_TIMES) || defined(_WIN32)\n    S_Tms = rb_struct_define(\"Tms\", \"utime\", \"stime\", \"cutime\", \"cstime\", NULL);\n#endif\n\n    SAVED_USER_ID = geteuid();\n    SAVED_GROUP_ID = getegid();\n\n    rb_mProcUID = rb_define_module_under(rb_mProcess, \"UID\");\n    rb_mProcGID = rb_define_module_under(rb_mProcess, \"GID\");\n\n    rb_define_module_function(rb_mProcUID, \"rid\", proc_getuid, 0);\n    rb_define_module_function(rb_mProcGID, \"rid\", proc_getgid, 0);\n    rb_define_module_function(rb_mProcUID, \"eid\", proc_geteuid, 0);\n    rb_define_module_function(rb_mProcGID, \"eid\", proc_getegid, 0);\n    rb_define_module_function(rb_mProcUID, \"change_privilege\", p_uid_change_privilege, 1);\n    rb_define_module_function(rb_mProcGID, \"change_privilege\", p_gid_change_privilege, 1);\n    rb_define_module_function(rb_mProcUID, \"grant_privilege\", p_uid_grant_privilege, 1);\n    rb_define_module_function(rb_mProcGID, \"grant_privilege\", p_gid_grant_privilege, 1);\n    rb_define_alias(rb_singleton_class(rb_mProcUID), \"eid=\", \"grant_privilege\");\n    rb_define_alias(rb_singleton_class(rb_mProcGID), \"eid=\", \"grant_privilege\");\n    rb_define_module_function(rb_mProcUID, \"re_exchange\", p_uid_exchange, 0);\n    rb_define_module_function(rb_mProcGID, \"re_exchange\", p_gid_exchange, 0);\n    rb_define_module_function(rb_mProcUID, \"re_exchangeable?\", p_uid_exchangeable, 0);\n    rb_define_module_function(rb_mProcGID, \"re_exchangeable?\", p_gid_exchangeable, 0);\n    rb_define_module_function(rb_mProcUID, \"sid_available?\", p_uid_have_saved_id, 0);\n    rb_define_module_function(rb_mProcGID, \"sid_available?\", p_gid_have_saved_id, 0);\n    rb_define_module_function(rb_mProcUID, \"switch\", p_uid_switch, 0);\n    rb_define_module_function(rb_mProcGID, \"switch\", p_gid_switch, 0);\n\n    rb_mProcID_Syscall = rb_define_module_under(rb_mProcess, \"Sys\");\n\n    rb_define_module_function(rb_mProcID_Syscall, \"getuid\", proc_getuid, 0);\n    rb_define_module_function(rb_mProcID_Syscall, \"geteuid\", proc_geteuid, 0);\n    rb_define_module_function(rb_mProcID_Syscall, \"getgid\", proc_getgid, 0);\n    rb_define_module_function(rb_mProcID_Syscall, \"getegid\", proc_getegid, 0);\n\n    rb_define_module_function(rb_mProcID_Syscall, \"setuid\", p_sys_setuid, 1);\n    rb_define_module_function(rb_mProcID_Syscall, \"setgid\", p_sys_setgid, 1);\n\n    rb_define_module_function(rb_mProcID_Syscall, \"setruid\", p_sys_setruid, 1);\n    rb_define_module_function(rb_mProcID_Syscall, \"setrgid\", p_sys_setrgid, 1);\n\n    rb_define_module_function(rb_mProcID_Syscall, \"seteuid\", p_sys_seteuid, 1);\n    rb_define_module_function(rb_mProcID_Syscall, \"setegid\", p_sys_setegid, 1);\n\n    rb_define_module_function(rb_mProcID_Syscall, \"setreuid\", p_sys_setreuid, 2);\n    rb_define_module_function(rb_mProcID_Syscall, \"setregid\", p_sys_setregid, 2);\n\n    rb_define_module_function(rb_mProcID_Syscall, \"setresuid\", p_sys_setresuid, 3);\n    rb_define_module_function(rb_mProcID_Syscall, \"setresgid\", p_sys_setresgid, 3);\n    rb_define_module_function(rb_mProcID_Syscall, \"issetugid\", p_sys_issetugid, 0);\n}\n"
  },
  {
    "path": "random.c",
    "content": "/**********************************************************************\n\n  random.c -\n\n  $Author$\n  $Date$\n  created at: Fri Dec 24 16:39:21 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n/* \nThis is based on trimmed version of MT19937.  To get the original version,\ncontact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.\n\nThe original copyright notice follows.\n\n   A C-program for MT19937, with initialization improved 2002/2/10.\n   Coded by Takuji Nishimura and Makoto Matsumoto.\n   This is a faster version by taking Shawn Cokus's optimization,\n   Matthe Bellew's simplification, Isaku Wada's real version.\n\n   Before using, initialize the state by using init_genrand(seed) \n   or init_by_array(init_key, key_length).\n\n   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n   All rights reserved.                          \n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions\n   are met:\n\n     1. Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n\n     2. Redistributions in binary form must reproduce the above copyright\n        notice, this list of conditions and the following disclaimer in the\n        documentation and/or other materials provided with the distribution.\n\n     3. The names of its contributors may not be used to endorse or promote \n        products derived from this software without specific prior written \n        permission.\n\n   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n   Any feedback is very welcome.\n   http://www.math.keio.ac.jp/matumoto/emt.html\n   email: matumoto@math.keio.ac.jp\n*/\n\n/* Period parameters */  \n#define N 624\n#define M 397\n#define MATRIX_A 0x9908b0dfUL   /* constant vector a */\n#define UMASK 0x80000000UL /* most significant w-r bits */\n#define LMASK 0x7fffffffUL /* least significant r bits */\n#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )\n#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))\n\nstatic unsigned long state[N]; /* the array for the state vector  */\nstatic int left = 1;\nstatic int initf = 0;\nstatic unsigned long *next;\n\n/* initializes state[N] with a seed */\nstatic void\ninit_genrand(s)\n    unsigned long s;\n{\n    int j;\n    state[0]= s & 0xffffffffUL;\n    for (j=1; j<N; j++) {\n        state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j); \n        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */\n        /* In the previous versions, MSBs of the seed affect   */\n        /* only MSBs of the array state[].                        */\n        /* 2002/01/09 modified by Makoto Matsumoto             */\n        state[j] &= 0xffffffffUL;  /* for >32 bit machines */\n    }\n    left = 1; initf = 1;\n}\n\n/* initialize by an array with array-length */\n/* init_key is the array for initializing keys */\n/* key_length is its length */\n/* slight change for C++, 2004/2/26 */\nstatic void\ninit_by_array(unsigned long init_key[], int key_length)\n{\n    int i, j, k;\n    init_genrand(19650218UL);\n    i=1; j=0;\n    k = (N>key_length ? N : key_length);\n    for (; k; k--) {\n        state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))\n          + init_key[j] + j; /* non linear */\n        state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */\n        i++; j++;\n        if (i>=N) { state[0] = state[N-1]; i=1; }\n        if (j>=key_length) j=0;\n    }\n    for (k=N-1; k; k--) {\n        state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))\n          - i; /* non linear */\n        state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */\n        i++;\n        if (i>=N) { state[0] = state[N-1]; i=1; }\n    }\n\n    state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ \n    left = 1; initf = 1;\n}\n\nstatic void\nnext_state()\n{\n    unsigned long *p=state;\n    int j;\n\n    /* if init_genrand() has not been called, */\n    /* a default initial seed is used         */\n    if (initf==0) init_genrand(5489UL);\n\n    left = N;\n    next = state;\n    \n    for (j=N-M+1; --j; p++) \n        *p = p[M] ^ TWIST(p[0], p[1]);\n\n    for (j=M; --j; p++) \n        *p = p[M-N] ^ TWIST(p[0], p[1]);\n\n    *p = p[M-N] ^ TWIST(p[0], state[0]);\n}\n\n/* generates a random number on [0,0xffffffff]-interval */\nunsigned long\nrb_genrand_int32(void)\n{\n    unsigned long y;\n\n    if (--left == 0) next_state();\n    y = *next++;\n\n    /* Tempering */\n    y ^= (y >> 11);\n    y ^= (y << 7) & 0x9d2c5680UL;\n    y ^= (y << 15) & 0xefc60000UL;\n    y ^= (y >> 18);\n\n    return y;\n}\n\n/* generates a random number on [0,1) with 53-bit resolution*/\ndouble\nrb_genrand_real(void) \n{ \n    unsigned long a=rb_genrand_int32()>>5, b=rb_genrand_int32()>>6; \n    return(a*67108864.0+b)*(1.0/9007199254740992.0); \n} \n/* These real versions are due to Isaku Wada, 2002/01/09 added */\n\n#undef N\n#undef M\n\n/* These real versions are due to Isaku Wada, 2002/01/09 added */\n\n#include \"ruby.h\"\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#include <time.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>\n#endif\n\nstatic VALUE saved_seed = INT2FIX(0);\n\nstatic VALUE\nrand_init(vseed)\n    VALUE vseed;\n{\n    volatile VALUE seed;\n    VALUE old;\n    long len;\n    unsigned long *buf;\n\n    seed = rb_to_int(vseed);\n    switch (TYPE(seed)) {\n      case T_FIXNUM:\n          len = sizeof(VALUE);\n          break;\n      case T_BIGNUM:\n          len = RBIGNUM(seed)->len * SIZEOF_BDIGITS;\n          if (len == 0)\n              len = 4;\n          break;\n      default:\n          rb_raise(rb_eTypeError, \"failed to convert %s into Integer\",\n                   rb_obj_classname(vseed));\n    }\n    len = (len + 3) / 4; /* number of 32bit words */\n    buf = ALLOC_N(unsigned long, len); /* allocate longs for init_by_array */\n    memset(buf, 0, len * sizeof(long));\n    if (FIXNUM_P(seed)) {\n        buf[0] = FIX2ULONG(seed) & 0xffffffff;\n#if SIZEOF_LONG > 4\n        buf[1] = FIX2ULONG(seed) >> 32;\n#endif\n    }\n    else {\n        int i, j;\n        for (i = RBIGNUM(seed)->len-1; 0 <= i; i--) {\n            j = i * SIZEOF_BDIGITS / 4;\n#if SIZEOF_BDIGITS < 4\n            buf[j] <<= SIZEOF_BDIGITS * 8;\n#endif\n            buf[j] |= ((BDIGIT *)RBIGNUM(seed)->digits)[i];\n        }\n    }\n    while (1 < len && buf[len-1] == 0) {\n        len--;\n    }\n    if (len <= 1) {\n        init_genrand(buf[0]);\n    }\n    else {\n        if (buf[len-1] == 1) /* remove leading-zero-guard */\n            len--;\n        init_by_array(buf, len);\n    }\n    old = saved_seed;\n    saved_seed = seed;\n    free(buf);\n    return old;\n}\n\nstatic VALUE\nrandom_seed()\n{\n    static int n = 0;\n    struct timeval tv;\n    int fd;\n    struct stat statbuf;\n\n    int seed_len;\n    BDIGIT *digits;\n    unsigned long *seed;\n    NEWOBJ(big, struct RBignum);\n    OBJSETUP(big, rb_cBignum, T_BIGNUM);\n\n    seed_len = 4 * sizeof(long);\n    big->sign = 1;\n    big->len = seed_len / SIZEOF_BDIGITS + 1;\n    digits = big->digits = ALLOC_N(BDIGIT, big->len);\n    seed = (unsigned long *)big->digits;\n\n    memset(digits, 0, big->len * SIZEOF_BDIGITS);\n\n#ifdef S_ISCHR\n    if ((fd = open(\"/dev/urandom\", O_RDONLY\n#ifdef O_NONBLOCK\n            |O_NONBLOCK\n#endif\n#ifdef O_NOCTTY\n            |O_NOCTTY\n#endif\n#ifdef O_NOFOLLOW\n            |O_NOFOLLOW\n#endif\n            )) >= 0) {\n        if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {\n            read(fd, seed, seed_len);\n        }\n        close(fd);\n    }\n#endif\n\n    gettimeofday(&tv, 0);\n    seed[0] ^= tv.tv_usec;\n    seed[1] ^= tv.tv_sec;\n    seed[2] ^= getpid() ^ (n++ << 16);\n    seed[3] ^= (unsigned long)&seed;\n\n    /* set leading-zero-guard if need. */\n    digits[big->len-1] = digits[big->len-2] <= 1 ? 1 : 0;\n\n    return rb_big_norm((VALUE)big);\n}\n\n/*\n *  call-seq:\n *     srand(number=0)    => old_seed\n *  \n *  Seeds the pseudorandom number generator to the value of\n *  <i>number</i>.<code>to_i.abs</code>. If <i>number</i> is omitted,\n *  seeds the generator using a combination of the time, the\n *  process id, and a sequence number. (This is also the behavior if\n *  <code>Kernel::rand</code> is called without previously calling\n *  <code>srand</code>, but without the sequence.) By setting the seed\n *  to a known value, scripts can be made deterministic during testing.\n *  The previous seed value is returned. Also see <code>Kernel::rand</code>.\n */\n\nstatic VALUE\nrb_f_srand(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE seed, old;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"01\", &seed) == 0) {\n\tseed = random_seed();\n    }\n    old = rand_init(seed);\n\n    return old;\n}\n\nstatic unsigned long \nmake_mask(unsigned long x)\n{\n    x = x | x >> 1;\n    x = x | x >> 2;\n    x = x | x >> 4;\n    x = x | x >> 8;\n    x = x | x >> 16;\n#if 4 < SIZEOF_LONG\n    x = x | x >> 32;\n#endif\n    return x;\n}\n\nstatic unsigned long\nlimited_rand(unsigned long limit)\n{\n    unsigned long mask = make_mask(limit);\n    int i;\n    unsigned long val;\n\n  retry:\n    val = 0;\n    for (i = SIZEOF_LONG/4-1; 0 <= i; i--) {\n        if (mask >> (i * 32)) {\n            val |= rb_genrand_int32() << (i * 32);\n            val &= mask;\n            if (limit < val)\n                goto retry;\n        }\n    }\n    return val;\n}\n\nstatic VALUE\nlimited_big_rand(struct RBignum *limit)\n{\n    unsigned long mask, lim, rnd;\n    struct RBignum *val;\n    int i, len, boundary;\n\n    len = (limit->len * SIZEOF_BDIGITS + 3) / 4;\n    val = (struct RBignum *)rb_big_clone((VALUE)limit);\n    val->sign = 1;\n#if SIZEOF_BDIGITS == 2\n# define BIG_GET32(big,i) (((BDIGIT *)(big)->digits)[(i)*2] | \\\n                           ((i)*2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)*2+1] << 16) \\\n                                                 : 0))\n# define BIG_SET32(big,i,d) ((((BDIGIT *)(big)->digits)[(i)*2] = (d) & 0xffff), \\\n                             ((i)*2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)*2+1] = (d) >> 16) \\\n                                                   : 0))\n#else\n    /* SIZEOF_BDIGITS == 4 */\n# define BIG_GET32(big,i) (((BDIGIT *)(big)->digits)[i])\n# define BIG_SET32(big,i,d) (((BDIGIT *)(big)->digits)[i] = (d))\n#endif\n  retry:\n    mask = 0;\n    boundary = 1;\n    for (i = len-1; 0 <= i; i--) {\n        lim = BIG_GET32(limit, i);\n        mask = mask ? 0xffffffff : make_mask(lim);\n        if (mask) {\n            rnd = rb_genrand_int32() & mask;\n            if (boundary) {\n                if (lim < rnd)\n                    goto retry;\n                if (rnd < lim)\n                    boundary = 0;\n            }\n        }\n        else {\n            rnd = 0;\n        }\n        BIG_SET32(val, i, rnd);\n    }\n    return rb_big_norm((VALUE)val);\n}\n\n/*\n *  call-seq:\n *     rand(max=0)    => number\n *  \n *  Converts <i>max</i> to an integer using max1 =\n *  max<code>.to_i.abs</code>. If the result is zero, returns a\n *  pseudorandom floating point number greater than or equal to 0.0 and\n *  less than 1.0. Otherwise, returns a pseudorandom integer greater\n *  than or equal to zero and less than max1. <code>Kernel::srand</code>\n *  may be used to ensure repeatable sequences of random numbers between\n *  different runs of the program. Ruby currently uses a modified\n *  Mersenne Twister with a period of 2**19937-1.\n *     \n *     srand 1234                 #=> 0\n *     [ rand,  rand ]            #=> [0.191519450163469, 0.49766366626136]\n *     [ rand(10), rand(1000) ]   #=> [6, 817]\n *     srand 1234                 #=> 1234\n *     [ rand,  rand ]            #=> [0.191519450163469, 0.49766366626136]\n */\n\nstatic VALUE\nrb_f_rand(argc, argv, obj)\n    int argc;\n    VALUE *argv;\n    VALUE obj;\n{\n    VALUE vmax;\n    long val, max;\n\n    rb_scan_args(argc, argv, \"01\", &vmax);\n    switch (TYPE(vmax)) {\n      case T_FLOAT:\n\tif (RFLOAT(vmax)->value <= LONG_MAX && RFLOAT(vmax)->value >= LONG_MIN) {\n\t    max = (long)RFLOAT(vmax)->value;\n\t    break;\n\t}\n        if (RFLOAT(vmax)->value < 0)\n            vmax = rb_dbl2big(-RFLOAT(vmax)->value);\n        else\n            vmax = rb_dbl2big(RFLOAT(vmax)->value);\n\t/* fall through */\n      case T_BIGNUM:\n      bignum:\n        {\n            struct RBignum *limit = (struct RBignum *)vmax;\n            if (!limit->sign) {\n                limit = (struct RBignum *)rb_big_clone(vmax);\n                limit->sign = 1;\n            }\n            limit = (struct RBignum *)rb_big_minus((VALUE)limit, INT2FIX(1));\n            if (FIXNUM_P((VALUE)limit)) {\n                if (FIX2LONG((VALUE)limit) == -1)\n                    return rb_float_new(rb_genrand_real());\n                return LONG2NUM(limited_rand(FIX2LONG((VALUE)limit)));\n            }\n            return limited_big_rand(limit);\n\t}\n      case T_NIL:\n\tmax = 0;\n\tbreak;\n      default:\n\tvmax = rb_Integer(vmax);\n\tif (TYPE(vmax) == T_BIGNUM) goto bignum;\n\t/* fall through */\n      case T_FIXNUM:\n\tmax = FIX2LONG(vmax);\n\tbreak;\n    }\n\n    if (max == 0) {\n\treturn rb_float_new(rb_genrand_real());\n    }\n    if (max < 0) max = -max;\n    val = limited_rand(max-1);\n    return LONG2NUM(val);\n}\n\nvoid\nInit_Random()\n{\n    rand_init(random_seed());\n    rb_define_global_function(\"srand\", rb_f_srand, -1);\n    rb_define_global_function(\"rand\", rb_f_rand, -1);\n    rb_global_variable(&saved_seed);\n}\n"
  },
  {
    "path": "range.c",
    "content": "/**********************************************************************\n\n  range.c -\n\n  $Author$\n  $Date$\n  created at: Thu Aug 19 17:46:47 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\nVALUE rb_cRange;\nstatic ID id_cmp, id_succ, id_beg, id_end, id_excl;\n\n#define EXCL(r) RTEST(rb_ivar_get((r), id_excl))\n#define SET_EXCL(r,v) rb_ivar_set((r), id_excl, (v) ? Qtrue : Qfalse)\n\nstatic VALUE\nrange_failed()\n{\n    rb_raise(rb_eArgError, \"bad value for range\");\n    return Qnil;\t\t/* dummy */\n}\n\nstatic VALUE\nrange_check(args)\n    VALUE *args;\n{\n    return rb_funcall(args[0], id_cmp, 1, args[1]);\n}\n\nstatic void\nrange_init(range, beg, end, exclude_end)\n    VALUE range, beg, end;\n    int exclude_end;\n{\n    VALUE args[2];\n\n    args[0] = beg;\n    args[1] = end;\n    \n    if (!FIXNUM_P(beg) || !FIXNUM_P(end)) {\n\tVALUE v;\n\n\tv = rb_rescue(range_check, (VALUE)args, range_failed, 0);\n\tif (NIL_P(v)) range_failed();\n    }\n\n    SET_EXCL(range, exclude_end);\n    rb_ivar_set(range, id_beg, beg);\n    rb_ivar_set(range, id_end, end);\n}\n\nVALUE\nrb_range_new(beg, end, exclude_end)\n    VALUE beg, end;\n    int exclude_end;\n{\n    VALUE range = rb_obj_alloc(rb_cRange);\n\n    range_init(range, beg, end, exclude_end);\n    return range;\n}\n\n/*\n *  call-seq:\n *     Range.new(start, end, exclusive=false)    => range\n *  \n *  Constructs a range using the given <i>start</i> and <i>end</i>. If the third\n *  parameter is omitted or is <code>false</code>, the <i>range</i> will include\n *  the end object; otherwise, it will be excluded.\n */\n\nstatic VALUE\nrange_initialize(argc, argv, range)\n    int argc;\n    VALUE *argv;\n    VALUE range;\n{\n    VALUE beg, end, flags;\n    \n    rb_scan_args(argc, argv, \"21\", &beg, &end, &flags);\n    /* Ranges are immutable, so that they should be initialized only once. */\n    if (rb_ivar_defined(range, id_beg)) {\n\trb_name_error(rb_intern(\"initialize\"), \"`initialize' called twice\");\n    }\n    range_init(range, beg, end, RTEST(flags));\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     rng.exclude_end?    => true or false\n *  \n *  Returns <code>true</code> if <i>rng</i> excludes its end value.\n */\n\nstatic VALUE\nrange_exclude_end_p(range)\n    VALUE range;\n{\n    return EXCL(range) ? Qtrue : Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     rng == obj    => true or false\n *  \n *  Returns <code>true</code> only if <i>obj</i> is a Range, has equivalent\n *  beginning and end items (by comparing them with <code>==</code>), and has\n *  the same #exclude_end? setting as <i>rng</t>.\n *     \n *    (0..2) == (0..2)            #=> true\n *    (0..2) == Range.new(0,2)    #=> true\n *    (0..2) == (0...2)           #=> false\n *     \n */\n\nstatic VALUE\nrange_eq(range, obj)\n    VALUE range, obj;\n{\n    if (range == obj) return Qtrue;\n    if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))\n\treturn Qfalse;\n\n    if (!rb_equal(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg)))\n\treturn Qfalse;\n    if (!rb_equal(rb_ivar_get(range, id_end), rb_ivar_get(obj, id_end)))\n\treturn Qfalse;\n\n    if (EXCL(range) != EXCL(obj)) return Qfalse;\n\n    return Qtrue;\n}\n\nstatic int\nr_lt(a, b)\n    VALUE a, b;\n{\n    VALUE r = rb_funcall(a, id_cmp, 1, b);\n\n    if (NIL_P(r)) return Qfalse;\n    if (rb_cmpint(r, a, b) < 0) return Qtrue;\n    return Qfalse;\n}\n\nstatic int\nr_le(a, b)\n    VALUE a, b;\n{\n    int c;\n    VALUE r = rb_funcall(a, id_cmp, 1, b);\n\n    if (NIL_P(r)) return Qfalse;\n    c = rb_cmpint(r, a, b);\n    if (c == 0) return INT2FIX(0);\n    if (c < 0) return Qtrue;\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     rng.eql?(obj)    => true or false\n *  \n *  Returns <code>true</code> only if <i>obj</i> is a Range, has equivalent\n *  beginning and end items (by comparing them with #eql?), and has the same\n *  #exclude_end? setting as <i>rng</i>.\n *     \n *    (0..2) == (0..2)            #=> true\n *    (0..2) == Range.new(0,2)    #=> true\n *    (0..2) == (0...2)           #=> false\n *     \n */\n\nstatic VALUE\nrange_eql(range, obj)\n    VALUE range, obj;\n{\n    if (range == obj) return Qtrue;\n    if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))\n\treturn Qfalse;\n\n    if (!rb_eql(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg)))\n\treturn Qfalse;\n    if (!rb_eql(rb_ivar_get(range, id_end), rb_ivar_get(obj, id_end)))\n\treturn Qfalse;\n\n    if (EXCL(range) != EXCL(obj)) return Qfalse;\n\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *   rng.hash    => fixnum\n *\n * Generate a hash value such that two ranges with the same start and\n * end points, and the same value for the \"exclude end\" flag, generate\n * the same hash value.\n */\n\nstatic VALUE\nrange_hash(range)\n    VALUE range;\n{\n    long hash = EXCL(range);\n    VALUE v;\n\n    v = rb_hash(rb_ivar_get(range, id_beg));\n    hash ^= v << 1;\n    v = rb_hash(rb_ivar_get(range, id_end));\n    hash ^= v << 9;\n    hash ^= EXCL(range) << 24;\n\n    return LONG2FIX(hash);\n}\n\nstatic VALUE\nstr_step(args)\n    VALUE *args;\n{\n    return rb_str_upto(args[0], args[1], EXCL(args[2]));\n}\n\nstatic void\nrange_each_func(range, func, v, e, arg)\n    VALUE range;\n    void (*func) _((VALUE, void*));\n    VALUE v, e;\n    void *arg;\n{\n    int c;\n\n    if (EXCL(range)) {\n\twhile (r_lt(v, e)) {\n\t    (*func)(v, arg);\n\t    v = rb_funcall(v, id_succ, 0, 0);\n\t}\n    }\n    else {\n\twhile (RTEST(c = r_le(v, e))) {\n\t    (*func)(v, arg);\n\t    if (c == INT2FIX(0)) break;\n\t    v = rb_funcall(v, id_succ, 0, 0);\n\t}\n    }\n}\n\nstatic VALUE\nstep_i(i, arg)\n    VALUE i;\n    VALUE arg;\n{\n    VALUE *iter = (VALUE *)arg;\n\n    if (FIXNUM_P(iter[0])) {\n\titer[0] -= INT2FIX(1) & ~FIXNUM_FLAG;\n    }\n    else {\n\titer[0] = rb_funcall(iter[0], '-', 1, INT2FIX(1));\n    }\n    if (iter[0] == INT2FIX(0)) {\n\trb_yield(i);\n\titer[0] = iter[1];\n    }\n    return Qnil;\n}\n\nextern int ruby_float_step _((VALUE from, VALUE to, VALUE step, int excl));\n\n/*\n *  call-seq:\n *     rng.step(n=1) {| obj | block }    => rng\n *  \n *  Iterates over <i>rng</i>, passing each <i>n</i>th element to the block. If\n *  the range contains numbers, <i>n</i> is added for each iteration.  Otherwise\n *  <code>step</code> invokes <code>succ</code> to iterate through range\n *  elements. The following code uses class <code>Xs</code>, which is defined\n *  in the class-level documentation.\n *     \n *     range = Xs.new(1)..Xs.new(10)\n *     range.step(2) {|x| puts x}\n *     range.step(3) {|x| puts x}\n *     \n *  <em>produces:</em>\n *     \n *      1 x\n *      3 xxx\n *      5 xxxxx\n *      7 xxxxxxx\n *      9 xxxxxxxxx\n *      1 x\n *      4 xxxx\n *      7 xxxxxxx\n *     10 xxxxxxxxxx\n */\n\n\nstatic VALUE\nrange_step(argc, argv, range)\n    int argc;\n    VALUE *argv;\n    VALUE range;\n{\n    VALUE b, e, step, tmp;\n\n    RETURN_ENUMERATOR(range, argc, argv);\n\n    b = rb_ivar_get(range, id_beg);\n    e = rb_ivar_get(range, id_end);\n    if (argc == 0) {\n\tstep = INT2FIX(1);\n    }\n    else {\n\trb_scan_args(argc, argv, \"01\", &step);\n\tif (!rb_obj_is_kind_of(step, rb_cNumeric)) {\n\t    step = rb_to_int(step);\n\t}\n\tif (rb_funcall(step, '<', 1, INT2FIX(0))) {\n\t    rb_raise(rb_eArgError, \"step can't be negative\");\n\t}\n\telse if (!rb_funcall(step, '>', 1, INT2FIX(0))) {\n\t    rb_raise(rb_eArgError, \"step can't be 0\");\n\t}\n    }\n\n    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */\n\tlong end = FIX2LONG(e);\n\tlong i, unit = FIX2LONG(step);\n\n\tif (!EXCL(range))\n\t    end += 1;\n\ti = FIX2LONG(b);\t\n\twhile (i < end) {\n\t    rb_yield(LONG2NUM(i));\n\t    if (i + unit < i) break;\n\t    i += unit;\n\t}\n\n    }\n    else if (ruby_float_step(b, e, step, EXCL(range))) {\n\t/* done */\n    }\n    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||\n\t     !NIL_P(rb_check_to_integer(b, \"to_int\")) ||\n\t     !NIL_P(rb_check_to_integer(e, \"to_int\"))) {\n\tID op = EXCL(range) ? '<' : rb_intern(\"<=\");\n\n\twhile (RTEST(rb_funcall(b, op, 1, e))) {\n\t    rb_yield(b);\n\t    b = rb_funcall(b, '+', 1, step);\n\t}\n    }\n    else {\n\ttmp = rb_check_string_type(b);\n\n\tif (!NIL_P(tmp)) {\n\t    VALUE args[5], iter[2];\n\n\t    b = tmp;\n\t    args[0] = e;\n\t    args[1] = EXCL(range) ? Qtrue : Qfalse;\n\t    iter[0] = INT2FIX(1);\n\t    iter[1] = step;\n\t    rb_block_call(b, rb_intern(\"upto\"), 2, args, step_i, (VALUE)iter);\n\t}\n\telse if (rb_obj_is_kind_of(b, rb_cNumeric) ||\n\t\t !NIL_P(rb_check_to_integer(b, \"to_int\")) ||\n\t\t !NIL_P(rb_check_to_integer(e, \"to_int\"))) {\n\t    ID c = EXCL(range) ? '<' : rb_intern(\"<=\");\n\n\t    while (RTEST(rb_funcall(b, c, 1, e))) {\n\t\trb_yield(b);\n\t\tb = rb_funcall(b, '+', 1, step);\n\t    }\n\t}\n\telse {\n\t    VALUE args[2];\n\n\t    if (!rb_respond_to(b, id_succ)) {\n\t\trb_raise(rb_eTypeError, \"can't iterate from %s\",\n\t\t\t rb_obj_classname(b));\n\t    }\n\t    args[0] = INT2FIX(1);\n\t    args[1] = step;\n\t    range_each_func(range, step_i, b, e, args);\n\t}\n    }\n    return range;\n}\n\nstatic void\neach_i(v, arg)\n    VALUE v;\n    void *arg;\n{\n    rb_yield(v);\n}\n\n/*\n *  call-seq:\n *     rng.each {| i | block } => rng\n *  \n *  Iterates over the elements <i>rng</i>, passing each in turn to the\n *  block. You can only iterate if the start object of the range\n *  supports the +succ+ method (which means that you can't iterate over\n *  ranges of +Float+ objects).\n *     \n *     (10..15).each do |n|\n *        print n, ' '\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     10 11 12 13 14 15\n */\n\nstatic VALUE\nrange_each(range)\n    VALUE range;\n{\n    VALUE beg, end;\n\n    RETURN_ENUMERATOR(range, 0, 0);\n\n    beg = rb_ivar_get(range, id_beg);\n    end = rb_ivar_get(range, id_end);\n\n    if (!rb_respond_to(beg, id_succ)) {\n\trb_raise(rb_eTypeError, \"can't iterate from %s\",\n\t\t rb_obj_classname(beg));\n    }\n    if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */\n\tlong lim = FIX2LONG(end);\n\tlong i;\n\n\tif (!EXCL(range)) lim += 1;\n\tfor (i=FIX2LONG(beg); i<lim; i++) {\n\t    rb_yield(LONG2NUM(i));\n\t}\n    }\n    else if (TYPE(beg) == T_STRING) {\n\tVALUE args[5], iter[2];\n\n\targs[0] = beg; args[1] = end; args[2] = range;\n\titer[0] = INT2FIX(1); iter[1] = INT2FIX(1);\n\trb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i,\n\t\t   (VALUE)iter);\n    }\n    else {\n\trange_each_func(range, each_i, beg, end, NULL);\n    }\n    return range;\n}\n\n/*\n *  call-seq:\n *     rng.first    => obj\n *     rng.begin    => obj\n *  \n *  Returns the first object in <i>rng</i>.\n */\n\nstatic VALUE\nrange_first(range)\n    VALUE range;\n{\n    return rb_ivar_get(range, id_beg);\n}\n\n\n/*\n *  call-seq:\n *     rng.end    => obj\n *     rng.last   => obj\n *  \n *  Returns the object that defines the end of <i>rng</i>.\n *     \n *     (1..10).end    #=> 10\n *     (1...10).end   #=> 10\n */\n\n\nstatic VALUE\nrange_last(range)\n    VALUE range;\n{\n    return rb_ivar_get(range, id_end);\n}\n\nVALUE\nrb_range_beg_len(range, begp, lenp, len, err)\n    VALUE range;\n    long *begp, *lenp;\n    long len;\n    int err;\n{\n    long beg, end, b, e;\n\n    if (!rb_obj_is_kind_of(range, rb_cRange)) return Qfalse;\n\n    beg = b = NUM2LONG(rb_ivar_get(range, id_beg));\n    end = e = NUM2LONG(rb_ivar_get(range, id_end));\n\n    if (beg < 0) {\n\tbeg += len;\n\tif (beg < 0) goto out_of_range;\n    }\n    if (err == 0 || err == 2) {\n\tif (beg > len) goto out_of_range;\n\tif (end > len) end = len;\n    }\n    if (end < 0) end += len;\n    if (!EXCL(range)) end++;\t/* include end point */\n    len = end - beg;\n    if (len < 0) len = 0;\n\n    *begp = beg;\n    *lenp = len;\n    return Qtrue;\n\n  out_of_range:\n    if (err) {\n\trb_raise(rb_eRangeError, \"%ld..%s%ld out of range\",\n\t\t b, EXCL(range)? \".\" : \"\", e);\n    }\n    return Qnil;\n}\n\n/*\n * call-seq:\n *   rng.to_s   => string\n *\n * Convert this range object to a printable form.\n */\n\nstatic VALUE\nrange_to_s(range)\n    VALUE range;\n{\n    VALUE str, str2;\n\n    str = rb_obj_as_string(rb_ivar_get(range, id_beg));\n    str2 = rb_obj_as_string(rb_ivar_get(range, id_end));\n    str = rb_str_dup(str);\n    rb_str_cat(str, \"...\", EXCL(range)?3:2);\n    rb_str_append(str, str2);\n    OBJ_INFECT(str, str2);\n\n    return str;\n}\n\n/*\n * call-seq:\n *   rng.inspect  => string\n *\n * Convert this range object to a printable form (using \n * <code>inspect</code> to convert the start and end\n * objects).\n */\n\n\nstatic VALUE\nrange_inspect(range)\n    VALUE range;\n{\n    VALUE str, str2;\n\n    str = rb_inspect(rb_ivar_get(range, id_beg));\n    str2 = rb_inspect(rb_ivar_get(range, id_end));\n    str = rb_str_dup(str);\n    rb_str_cat(str, \"...\", EXCL(range)?3:2);\n    rb_str_append(str, str2);\n    OBJ_INFECT(str, str2);\n\n    return str;\n}\n\n/*\n *  call-seq:\n *     rng === obj       =>  true or false\n *     rng.member?(val)  =>  true or false\n *     rng.include?(val) =>  true or false\n *  \n *  Returns <code>true</code> if <i>obj</i> is an element of\n *  <i>rng</i>, <code>false</code> otherwise. Conveniently,\n *  <code>===</code> is the comparison operator used by\n *  <code>case</code> statements.\n *     \n *     case 79\n *     when 1..50   then   print \"low\\n\"\n *     when 51..75  then   print \"medium\\n\"\n *     when 76..100 then   print \"high\\n\"\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     high\n */\n\nstatic VALUE\nrange_include(range, val)\n    VALUE range, val;\n{\n    VALUE beg, end;\n\n    beg = rb_ivar_get(range, id_beg);\n    end = rb_ivar_get(range, id_end);\n    if (r_le(beg, val)) {\n\tif (EXCL(range)) {\n\t    if (r_lt(val, end)) return Qtrue;\n\t}\n\telse {\n\t    if (r_le(val, end)) return Qtrue;\n\t}\n    }\n    return Qfalse;\n}\n\n\n/*  A <code>Range</code> represents an interval---a set of values with a\n *  start and an end. Ranges may be constructed using the\n *  <em>s</em><code>..</code><em>e</em> and\n *  <em>s</em><code>...</code><em>e</em> literals, or with\n *  <code>Range::new</code>. Ranges constructed using <code>..</code>\n *  run from the start to the end inclusively. Those created using\n *  <code>...</code> exclude the end value. When used as an iterator,\n *  ranges return each value in the sequence.\n *     \n *     (-1..-5).to_a      #=> []\n *     (-5..-1).to_a      #=> [-5, -4, -3, -2, -1]\n *     ('a'..'e').to_a    #=> [\"a\", \"b\", \"c\", \"d\", \"e\"]\n *     ('a'...'e').to_a   #=> [\"a\", \"b\", \"c\", \"d\"]\n *     \n *  Ranges can be constructed using objects of any type, as long as the\n *  objects can be compared using their <code><=></code> operator and\n *  they support the <code>succ</code> method to return the next object\n *  in sequence.\n *     \n *     class Xs                # represent a string of 'x's\n *       include Comparable\n *       attr :length\n *       def initialize(n)\n *         @length = n\n *       end\n *       def succ\n *         Xs.new(@length + 1)\n *       end\n *       def <=>(other)\n *         @length <=> other.length\n *       end\n *       def to_s\n *         sprintf \"%2d #{inspect}\", @length\n *       end\n *       def inspect\n *         'x' * @length\n *       end\n *     end\n *     \n *     r = Xs.new(3)..Xs.new(6)   #=> xxx..xxxxxx\n *     r.to_a                     #=> [xxx, xxxx, xxxxx, xxxxxx]\n *     r.member?(Xs.new(5))       #=> true\n *     \n *  In the previous code example, class <code>Xs</code> includes the\n *  <code>Comparable</code> module. This is because\n *  <code>Enumerable#member?</code> checks for equality using\n *  <code>==</code>. Including <code>Comparable</code> ensures that the\n *  <code>==</code> method is defined in terms of the <code><=></code>\n *  method implemented in <code>Xs</code>.\n *     \n */\n\nvoid\nInit_Range()\n{\n    rb_cRange = rb_define_class(\"Range\", rb_cObject);\n    rb_include_module(rb_cRange, rb_mEnumerable);\n    rb_define_method(rb_cRange, \"initialize\", range_initialize, -1);\n    rb_define_method(rb_cRange, \"==\", range_eq, 1);\n    rb_define_method(rb_cRange, \"===\", range_include, 1);\n    rb_define_method(rb_cRange, \"eql?\", range_eql, 1);\n    rb_define_method(rb_cRange, \"hash\", range_hash, 0);\n    rb_define_method(rb_cRange, \"each\", range_each, 0);\n    rb_define_method(rb_cRange, \"step\", range_step, -1);\n    rb_define_method(rb_cRange, \"first\", range_first, 0);\n    rb_define_method(rb_cRange, \"last\", range_last, 0);\n    rb_define_method(rb_cRange, \"begin\", range_first, 0);\n    rb_define_method(rb_cRange, \"end\", range_last, 0);\n    rb_define_method(rb_cRange, \"to_s\", range_to_s, 0);\n    rb_define_method(rb_cRange, \"inspect\", range_inspect, 0);\n\n    rb_define_method(rb_cRange, \"exclude_end?\", range_exclude_end_p, 0);\n\n    rb_define_method(rb_cRange, \"member?\", range_include, 1);\n    rb_define_method(rb_cRange, \"include?\", range_include, 1);\n\n    id_cmp = rb_intern(\"<=>\");\n    id_succ = rb_intern(\"succ\");\n    id_beg = rb_intern(\"begin\");\n    id_end = rb_intern(\"end\");\n    id_excl = rb_intern(\"excl\");\n}\n"
  },
  {
    "path": "re.c",
    "content": "/**********************************************************************\n\n  re.c -\n\n  $Author$\n  created at: Mon Aug  9 18:24:49 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"re.h\"\n#include <ctype.h>\n\nVALUE rb_eRegexpError;\n\n#define BEG(no) regs->beg[no]\n#define END(no) regs->end[no]\n\n#if 'a' == 97   /* it's ascii */\nstatic const char casetable[] = {\n        '\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\007',\n        '\\010', '\\011', '\\012', '\\013', '\\014', '\\015', '\\016', '\\017',\n        '\\020', '\\021', '\\022', '\\023', '\\024', '\\025', '\\026', '\\027',\n        '\\030', '\\031', '\\032', '\\033', '\\034', '\\035', '\\036', '\\037',\n        /* ' '     '!'     '\"'     '#'     '$'     '%'     '&'     ''' */\n        '\\040', '\\041', '\\042', '\\043', '\\044', '\\045', '\\046', '\\047',\n        /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */\n        '\\050', '\\051', '\\052', '\\053', '\\054', '\\055', '\\056', '\\057',\n        /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */\n        '\\060', '\\061', '\\062', '\\063', '\\064', '\\065', '\\066', '\\067',\n        /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */\n        '\\070', '\\071', '\\072', '\\073', '\\074', '\\075', '\\076', '\\077',\n        /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */\n        '\\100', '\\141', '\\142', '\\143', '\\144', '\\145', '\\146', '\\147',\n        /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */\n        '\\150', '\\151', '\\152', '\\153', '\\154', '\\155', '\\156', '\\157',\n        /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */\n        '\\160', '\\161', '\\162', '\\163', '\\164', '\\165', '\\166', '\\167',\n        /* 'X'     'Y'     'Z'     '['     '\\'     ']'     '^'     '_' */\n        '\\170', '\\171', '\\172', '\\133', '\\134', '\\135', '\\136', '\\137',\n        /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */\n        '\\140', '\\141', '\\142', '\\143', '\\144', '\\145', '\\146', '\\147',\n        /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */\n        '\\150', '\\151', '\\152', '\\153', '\\154', '\\155', '\\156', '\\157',\n        /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */\n        '\\160', '\\161', '\\162', '\\163', '\\164', '\\165', '\\166', '\\167',\n        /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */\n        '\\170', '\\171', '\\172', '\\173', '\\174', '\\175', '\\176', '\\177',\n        '\\200', '\\201', '\\202', '\\203', '\\204', '\\205', '\\206', '\\207',\n        '\\210', '\\211', '\\212', '\\213', '\\214', '\\215', '\\216', '\\217',\n        '\\220', '\\221', '\\222', '\\223', '\\224', '\\225', '\\226', '\\227',\n        '\\230', '\\231', '\\232', '\\233', '\\234', '\\235', '\\236', '\\237',\n        '\\240', '\\241', '\\242', '\\243', '\\244', '\\245', '\\246', '\\247',\n        '\\250', '\\251', '\\252', '\\253', '\\254', '\\255', '\\256', '\\257',\n        '\\260', '\\261', '\\262', '\\263', '\\264', '\\265', '\\266', '\\267',\n        '\\270', '\\271', '\\272', '\\273', '\\274', '\\275', '\\276', '\\277',\n        '\\300', '\\301', '\\302', '\\303', '\\304', '\\305', '\\306', '\\307',\n        '\\310', '\\311', '\\312', '\\313', '\\314', '\\315', '\\316', '\\317',\n        '\\320', '\\321', '\\322', '\\323', '\\324', '\\325', '\\326', '\\327',\n        '\\330', '\\331', '\\332', '\\333', '\\334', '\\335', '\\336', '\\337',\n        '\\340', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347',\n        '\\350', '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357',\n        '\\360', '\\361', '\\362', '\\363', '\\364', '\\365', '\\366', '\\367',\n        '\\370', '\\371', '\\372', '\\373', '\\374', '\\375', '\\376', '\\377',\n};\n#else\n# error >>> \"You lose. You will need a translation table for your character set.\" <<<\n#endif\n\nint\nrb_memcicmp(x, y, len)\n    const void *x, *y;\n    long len;\n{\n    const unsigned char *p1 = x, *p2 = y;\n    int tmp;\n\n    while (len--) {\n\tif ((tmp = casetable[(unsigned)*p1++] - casetable[(unsigned)*p2++]) != 0)\n\t    return tmp;\n    }\n    return 0;\n}\n\nint\nrb_memcmp(p1, p2, len)\n    const void *p1, *p2;\n    long len;\n{\n    if (!ruby_ignorecase) {\n\treturn memcmp(p1, p2, len);\n    }\n    return rb_memcicmp(p1, p2, len);\n}\n\nlong\nrb_memsearch(x0, m, y0, n)\n    const void *x0, *y0;\n    long m, n;\n{\n    const unsigned char *x = (unsigned char *)x0, *y = (unsigned char *)y0;\n    const unsigned char *s, *e;\n    long i;\n    int d;\n    unsigned long hx, hy;\n\n#define KR_REHASH(a, b, h) (((h) << 1) - (((unsigned long)(a))<<d) + (b))\n\n    if (m > n) return -1;\n    s = y; e = s + n - m;\n\n    /* Preprocessing */\n    /* computes d = 2^(m-1) with\n       the left-shift operator */\n    d = sizeof(hx) * CHAR_BIT - 1;\n    if (d > m) d = m;\n\n    if (ruby_ignorecase) {\n\tif (n == m) {\n\t    return rb_memcicmp(x, s, m) == 0 ? 0 : -1;\n\t}\n\t/* Prepare hash value */\n\tfor (hy = hx = i = 0; i < d; ++i) {\n\t    hx = KR_REHASH(0, casetable[x[i]], hx);\n\t    hy = KR_REHASH(0, casetable[s[i]], hy);\n\t}\n\t/* Searching */\n\twhile (hx != hy || rb_memcicmp(x, s, m)) {\n\t    if (s >= e) return -1;\n\t    hy = KR_REHASH(casetable[*s], casetable[*(s+d)], hy);\n\t    s++;\n\t}\n    }\n    else {\n\tif (n == m) {\n\t    return memcmp(x, s, m) == 0 ? 0 : -1;\n\t}\n\t/* Prepare hash value */\n\tfor (hy = hx = i = 0; i < d; ++i) {\n\t    hx = KR_REHASH(0, x[i], hx);\n\t    hy = KR_REHASH(0, s[i], hy);\n\t}\n\t/* Searching */\n\twhile (hx != hy || memcmp(x, s, m)) {\n\t    if (s >= e) return -1;\n\t    hy = KR_REHASH(*s, *(s+d), hy);\n\t    s++;\n\t}\n    }\n    return s-y;\n}\n\n#define REG_LITERAL FL_USER5\n#define REG_CASESTATE  FL_USER0\n#define KCODE_NONE  0\n#define KCODE_EUC   FL_USER1\n#define KCODE_SJIS  FL_USER2\n#define KCODE_UTF8  FL_USER3\n#define KCODE_FIXED FL_USER4\n#define KCODE_MASK (KCODE_EUC|KCODE_SJIS|KCODE_UTF8)\n\nstatic int reg_kcode = DEFAULT_KCODE;\n\nstatic void\nkcode_euc(re)\n    struct RRegexp *re;\n{\n    FL_UNSET(re, KCODE_MASK);\n    FL_SET(re, KCODE_EUC);\n    FL_SET(re, KCODE_FIXED);\n}\n\nstatic void\nkcode_sjis(re)\n    struct RRegexp *re;\n{\n    FL_UNSET(re, KCODE_MASK);\n    FL_SET(re, KCODE_SJIS);\n    FL_SET(re, KCODE_FIXED);\n}\n\nstatic void\nkcode_utf8(re)\n    struct RRegexp *re;\n{\n    FL_UNSET(re, KCODE_MASK);\n    FL_SET(re, KCODE_UTF8);\n    FL_SET(re, KCODE_FIXED);\n}\n\nstatic void\nkcode_none(re)\n    struct RRegexp *re;\n{\n    FL_UNSET(re, KCODE_MASK);\n    FL_SET(re, KCODE_FIXED);\n}\n\nstatic int curr_kcode;\n\nvoid\nrb_kcode_set_option(re)\n    VALUE re;\n{\n    if (!FL_TEST(re, KCODE_FIXED)) return;\n\n    curr_kcode = RBASIC(re)->flags & KCODE_MASK;\n    if (reg_kcode == curr_kcode) return;\n    switch (curr_kcode) {\n      case KCODE_NONE:\n\tre_mbcinit(MBCTYPE_ASCII);\n\tbreak;\n      case KCODE_EUC:\n\tre_mbcinit(MBCTYPE_EUC);\n\tbreak;\n      case KCODE_SJIS:\n\tre_mbcinit(MBCTYPE_SJIS);\n\tbreak;\n      case KCODE_UTF8:\n\tre_mbcinit(MBCTYPE_UTF8);\n\tbreak;\n    }\n}\n\nvoid\nrb_kcode_reset_option()\n{\n    if (reg_kcode == curr_kcode) return;\n    switch (reg_kcode) {\n      case KCODE_NONE:\n\tre_mbcinit(MBCTYPE_ASCII);\n\tbreak;\n      case KCODE_EUC:\n\tre_mbcinit(MBCTYPE_EUC);\n\tbreak;\n      case KCODE_SJIS:\n\tre_mbcinit(MBCTYPE_SJIS);\n\tbreak;\n      case KCODE_UTF8:\n\tre_mbcinit(MBCTYPE_UTF8);\n\tbreak;\n    }\n}\n\nint\nrb_reg_mbclen2(c, re)\n    unsigned int c;\n    VALUE re;\n{\n    int len;\n\n    if (!FL_TEST(re, KCODE_FIXED))\n\treturn mbclen(c);\n    rb_kcode_set_option(re);\n    len = mbclen(c);\n    rb_kcode_reset_option();\n    return len;\n}\n\nstatic void\nrb_reg_check(re)\n    VALUE re;\n{\n    if (!RREGEXP(re)->ptr || !RREGEXP(re)->str) {\n\trb_raise(rb_eTypeError, \"uninitialized Regexp\");\n    }\n}\n\nstatic void\nrb_reg_expr_str(str, s, len)\n    VALUE str;\n    const char *s;\n    long len;\n{\n    const char *p, *pend;\n    int need_escape = 0;\n\n    p = s; pend = p + len;\n    while (p<pend) {\n\tif (*p == '/' || (!ISPRINT(*p) && !ismbchar(*p))) {\n\t    need_escape = 1;\n\t    break;\n\t}\n\tp += mbclen(*p);\n    }\n    if (!need_escape) {\n\trb_str_buf_cat(str, s, len);\n    }\n    else {\n\tp = s;\n\twhile (p<pend) {\n\t    if (*p == '\\\\') {\n\t\tint n = mbclen(p[1]) + 1;\n\t\trb_str_buf_cat(str, p, n);\n\t\tp += n;\n\t\tcontinue;\n\t    }\n\t    else if (*p == '/') {\n\t\tchar c = '\\\\';\n\t\trb_str_buf_cat(str, &c, 1);\n\t\trb_str_buf_cat(str, p, 1);\n\t    }\n\t    else if (ismbchar(*p)) {\n\t    \trb_str_buf_cat(str, p, mbclen(*p));\n\t\tp += mbclen(*p);\n\t\tcontinue;\n\t    }\n\t    else if (ISPRINT(*p)) {\n\t\trb_str_buf_cat(str, p, 1);\n\t    }\n\t    else if (!ISSPACE(*p)) {\n\t\tchar b[8];\n\n\t\tsprintf(b, \"\\\\%03o\", *p & 0377);\n\t\trb_str_buf_cat(str, b, 4);\n\t    }\n\t    else {\n\t\trb_str_buf_cat(str, p, 1);\n\t    }\n\t    p++;\n\t}\n    }\n}\n\nstatic VALUE\nrb_reg_desc(s, len, re)\n    const char *s;\n    long len;\n    VALUE re;\n{\n    VALUE str = rb_str_buf_new2(\"/\");\n\n    rb_reg_expr_str(str, s, len);\n    rb_str_buf_cat2(str, \"/\");\n    if (re) {\n\trb_reg_check(re);\n\tif (RREGEXP(re)->ptr->options & RE_OPTION_MULTILINE)\n\t    rb_str_buf_cat2(str, \"m\");\n\tif (RREGEXP(re)->ptr->options & RE_OPTION_IGNORECASE)\n\t    rb_str_buf_cat2(str, \"i\");\n\tif (RREGEXP(re)->ptr->options & RE_OPTION_EXTENDED)\n\t    rb_str_buf_cat2(str, \"x\");\n\n\tif (FL_TEST(re, KCODE_FIXED)) {\n\t    switch ((RBASIC(re)->flags & KCODE_MASK)) {\n\t      case KCODE_NONE:\n\t\trb_str_buf_cat2(str, \"n\");\n\t\tbreak;\n\t      case KCODE_EUC:\n\t\trb_str_buf_cat2(str, \"e\");\n\t\tbreak;\n\t      case KCODE_SJIS:\n\t\trb_str_buf_cat2(str, \"s\");\n\t\tbreak;\n\t      case KCODE_UTF8:\n\t\trb_str_buf_cat2(str, \"u\");\n\t\tbreak;\n\t    }\n\t}\n    }\n    OBJ_INFECT(str, re);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     rxp.source   => str\n *\n *  Returns the original string of the pattern.\n *\n *     /ab+c/ix.source   #=> \"ab+c\"\n */\n\nstatic VALUE\nrb_reg_source(re)\n    VALUE re;\n{\n    VALUE str;\n\n    rb_reg_check(re);\n    str = rb_str_new(RREGEXP(re)->str,RREGEXP(re)->len);\n    if (OBJ_TAINTED(re)) OBJ_TAINT(str);\n    return str;\n}\n\n/*\n * call-seq:\n *    rxp.inspect   => string\n *\n * Produce a nicely formatted string-version of _rxp_. Perhaps surprisingly,\n * <code>#inspect</code> actually produces the more natural version of\n * the string than <code>#to_s</code>.\n *\n *     /ab+c/ix.to_s         #=> /ab+c/ix\n*/\n\nstatic VALUE\nrb_reg_inspect(re)\n    VALUE re;\n{\n    rb_reg_check(re);\n    return rb_reg_desc(RREGEXP(re)->str, RREGEXP(re)->len, re);\n}\n\n\n/*\n *  call-seq:\n *     rxp.to_s   => str\n *\n *  Returns a string containing the regular expression and its options (using the\n *  <code>(?xxx:yyy)</code> notation. This string can be fed back in to\n *  <code>Regexp::new</code> to a regular expression with the same semantics as\n *  the original. (However, <code>Regexp#==</code> may not return true when\n *  comparing the two, as the source of the regular expression itself may\n *  differ, as the example shows).  <code>Regexp#inspect</code> produces a\n *  generally more readable version of <i>rxp</i>.\n *\n *     r1 = /ab+c/ix         #=> /ab+c/ix\n *     s1 = r1.to_s          #=> \"(?ix-m:ab+c)\"\n *     r2 = Regexp.new(s1)   #=> /(?ix-m:ab+c)/\n *     r1 == r2              #=> false\n *     r1.source             #=> \"ab+c\"\n *     r2.source             #=> \"(?ix-m:ab+c)\"\n */\n\nstatic VALUE\nrb_reg_to_s(re)\n    VALUE re;\n{\n    int options;\n    const int embeddable = RE_OPTION_MULTILINE|RE_OPTION_IGNORECASE|RE_OPTION_EXTENDED;\n    long len;\n    const char* ptr;\n    VALUE str = rb_str_buf_new2(\"(?\");\n\n    rb_reg_check(re);\n\n    options = RREGEXP(re)->ptr->options;\n    ptr = RREGEXP(re)->str;\n    len = RREGEXP(re)->len;\n  again:\n    if (len >= 4 && ptr[0] == '(' && ptr[1] == '?') {\n\tint err = 1;\n\tptr += 2;\n\tif ((len -= 2) > 0) {\n\t    do {\n\t\tif (*ptr == 'm') {\n\t\t    options |= RE_OPTION_MULTILINE;\n\t\t}\n\t\telse if (*ptr == 'i') {\n\t\t    options |= RE_OPTION_IGNORECASE;\n\t\t}\n\t\telse if (*ptr == 'x') {\n\t\t    options |= RE_OPTION_EXTENDED;\n\t\t}\n\t\telse break;\n\t\t++ptr;\n\t    } while (--len > 0);\n\t}\n\tif (len > 1 && *ptr == '-') {\n\t    ++ptr;\n\t    --len;\n\t    do {\n\t\tif (*ptr == 'm') {\n\t\t    options &= ~RE_OPTION_MULTILINE;\n\t\t}\n\t\telse if (*ptr == 'i') {\n\t\t    options &= ~RE_OPTION_IGNORECASE;\n\t\t}\n\t\telse if (*ptr == 'x') {\n\t\t    options &= ~RE_OPTION_EXTENDED;\n\t\t}\n\t\telse break;\n\t\t++ptr;\n\t    } while (--len > 0);\n\t}\n\tif (*ptr == ')') {\n\t    --len;\n\t    ++ptr;\n\t    goto again;\n\t}\n\tif (*ptr == ':' && ptr[len-1] == ')') {\n\t    Regexp *rp;\n\t    rb_kcode_set_option(re);\n\t    rp = ALLOC(Regexp);\n\t    MEMZERO((char *)rp, Regexp, 1);\n\t    err = re_compile_pattern(++ptr, len -= 2, rp) != 0;\n\t    rb_kcode_reset_option();\n\t    re_free_pattern(rp);\n\t}\n\tif (err) {\n\t    options = RREGEXP(re)->ptr->options;\n\t    ptr = RREGEXP(re)->str;\n\t    len = RREGEXP(re)->len;\n\t}\n    }\n\n    if (options & RE_OPTION_MULTILINE) rb_str_buf_cat2(str, \"m\");\n    if (options & RE_OPTION_IGNORECASE) rb_str_buf_cat2(str, \"i\");\n    if (options & RE_OPTION_EXTENDED) rb_str_buf_cat2(str, \"x\");\n\n    if ((options & embeddable) != embeddable) {\n\trb_str_buf_cat2(str, \"-\");\n\tif (!(options & RE_OPTION_MULTILINE)) rb_str_buf_cat2(str, \"m\");\n\tif (!(options & RE_OPTION_IGNORECASE)) rb_str_buf_cat2(str, \"i\");\n\tif (!(options & RE_OPTION_EXTENDED)) rb_str_buf_cat2(str, \"x\");\n    }\n\n    rb_str_buf_cat2(str, \":\");\n    rb_reg_expr_str(str, ptr, len);\n    rb_str_buf_cat2(str, \")\");\n\n    OBJ_INFECT(str, re);\n    return str;\n}\n\nstatic void\nrb_reg_raise(s, len, err, re)\n    const char *s;\n    long len;\n    const char *err;\n    VALUE re;\n{\n    VALUE desc = rb_reg_desc(s, len, re);\n\n    if (ruby_in_compile)\n\trb_compile_error(\"%s: %s\", err, RSTRING(desc)->ptr);\n    else\n\trb_raise(rb_eRegexpError, \"%s: %s\", err, RSTRING(desc)->ptr);\n}\n\n\n/*\n *  call-seq:\n *     rxp.casefold?   => true or false\n *\n *  Returns the value of the case-insensitive flag.\n */\n\nstatic VALUE\nrb_reg_casefold_p(re)\n    VALUE re;\n{\n    rb_reg_check(re);\n    if (RREGEXP(re)->ptr->options & RE_OPTION_IGNORECASE) return Qtrue;\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     rxp.options   => fixnum\n *\n *  Returns the set of bits corresponding to the options used when creating this\n *  Regexp (see <code>Regexp::new</code> for details. Note that additional bits\n *  may be set in the returned options: these are used internally by the regular\n *  expression code. These extra bits are ignored if the options are passed to\n *  <code>Regexp::new</code>.\n *\n *     Regexp::IGNORECASE                  #=> 1\n *     Regexp::EXTENDED                    #=> 2\n *     Regexp::MULTILINE                   #=> 4\n *\n *     /cat/.options                       #=> 128\n *     /cat/ix.options                     #=> 131\n *     Regexp.new('cat', true).options     #=> 129\n *     Regexp.new('cat', 0, 's').options   #=> 384\n *\n *     r = /cat/ix\n *     Regexp.new(r.source, r.options)     #=> /cat/ix\n */\n\nstatic VALUE\nrb_reg_options_m(re)\n    VALUE re;\n{\n    int options = rb_reg_options(re);\n    return INT2NUM(options);\n}\n\n\n/*\n *  call-seq:\n *     rxp.kcode   => str\n *\n *  Returns the character set code for the regexp.\n */\n\nstatic VALUE\nrb_reg_kcode_m(re)\n    VALUE re;\n{\n    const char *kcode;\n\n    if (FL_TEST(re, KCODE_FIXED)) {\n\tswitch (RBASIC(re)->flags & KCODE_MASK) {\n\t  case KCODE_NONE:\n\t    kcode = \"none\"; break;\n\t  case KCODE_EUC:\n\t    kcode = \"euc\"; break;\n\t  case KCODE_SJIS:\n\t    kcode = \"sjis\"; break;\n\t  case KCODE_UTF8:\n\t    kcode = \"utf8\"; break;\n\t  default:\n\t    rb_bug(\"unknown kcode - should not happen\");\n\t    break;\n\t}\n\treturn rb_str_new2(kcode);\n    }\n    return Qnil;\n}\n\nstatic Regexp*\nmake_regexp(s, len, flags)\n    const char *s;\n    long len;\n    int flags;\n{\n    Regexp *rp;\n    const char *err;\n\n    /* Handle escaped characters first. */\n\n    /* Build a copy of the string (in dest) with the\n       escaped characters translated,  and generate the regex\n       from that.\n    */\n\n    rp = ALLOC(Regexp);\n    MEMZERO((char *)rp, Regexp, 1);\n    rp->buffer = ALLOC_N(char, 16);\n    rp->allocated = 16;\n    rp->fastmap = ALLOC_N(char, 256);\n    if (flags) {\n\trp->options = flags;\n    }\n    err = re_compile_pattern(s, len, rp);\n\n    if (err != NULL) {\n\tre_free_pattern(rp);\n\trb_reg_raise(s, len, err, 0);\n\treturn 0;\n    }\n    return rp;\n}\n\n\n/*\n *  Document-class: MatchData\n *\n *  <code>MatchData</code> is the type of the special variable <code>$~</code>,\n *  and is the type of the object returned by <code>Regexp#match</code> and\n *  <code>Regexp#last_match</code>. It encapsulates all the results of a pattern\n *  match, results normally accessed through the special variables\n *  <code>$&</code>, <code>$'</code>, <code>$`</code>, <code>$1</code>,\n *  <code>$2</code>, and so on. <code>Matchdata</code> is also known as\n *  <code>MatchingData</code>.\n *\n */\n\nVALUE rb_cMatch;\n\nstatic VALUE match_alloc _((VALUE));\nstatic VALUE\nmatch_alloc(klass)\n    VALUE klass;\n{\n    NEWOBJ(match, struct RMatch);\n    OBJSETUP(match, klass, T_MATCH);\n\n    match->str = 0;\n    match->regs = 0;\n    match->regs = ALLOC(struct re_registers);\n    MEMZERO(match->regs, struct re_registers, 1);\n\n    return (VALUE)match;\n}\n\nstatic void\nmatch_check(VALUE match)\n{\n    if (!RMATCH(match)->str) {\n\trb_raise(rb_eTypeError, \"uninitialized Match\");\n    }\n}\n\n/* :nodoc: */\nstatic VALUE\nmatch_init_copy(obj, orig)\n    VALUE obj, orig;\n{\n    if (obj == orig) return obj;\n\n    if (!rb_obj_is_instance_of(orig, rb_obj_class(obj))) {\n\trb_raise(rb_eTypeError, \"wrong argument class\");\n    }\n    RMATCH(obj)->str = RMATCH(orig)->str;\n    re_free_registers(RMATCH(obj)->regs);\n    RMATCH(obj)->regs->allocated = 0;\n    re_copy_registers(RMATCH(obj)->regs, RMATCH(orig)->regs);\n\n    return obj;\n}\n\n\n/*\n *  call-seq:\n *     mtch.length   => integer\n *     mtch.size     => integer\n *\n *  Returns the number of elements in the match array.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.length   #=> 5\n *     m.size     #=> 5\n */\n\nstatic VALUE\nmatch_size(match)\n    VALUE match;\n{\n    match_check(match);\n    return INT2FIX(RMATCH(match)->regs->num_regs);\n}\n\n\n/*\n *  call-seq:\n *     mtch.offset(n)   => array\n *\n *  Returns a two-element array containing the beginning and ending offsets of\n *  the <em>n</em>th match.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.offset(0)   #=> [1, 7]\n *     m.offset(4)   #=> [6, 7]\n */\n\nstatic VALUE\nmatch_offset(match, n)\n    VALUE match, n;\n{\n    int i = NUM2INT(n);\n\n    match_check(match);\n    if (i < 0 || RMATCH(match)->regs->num_regs <= i)\n\trb_raise(rb_eIndexError, \"index %d out of matches\", i);\n\n    if (RMATCH(match)->regs->beg[i] < 0)\n\treturn rb_assoc_new(Qnil, Qnil);\n\n    return rb_assoc_new(INT2FIX(RMATCH(match)->regs->beg[i]),\n\t\t\tINT2FIX(RMATCH(match)->regs->end[i]));\n}\n\n\n/*\n *  call-seq:\n *     mtch.begin(n)   => integer\n *\n *  Returns the offset of the start of the <em>n</em>th element of the match\n *  array in the string.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.begin(0)   #=> 1\n *     m.begin(2)   #=> 2\n */\n\nstatic VALUE\nmatch_begin(match, n)\n    VALUE match, n;\n{\n    int i = NUM2INT(n);\n\n    match_check(match);\n    if (i < 0 || RMATCH(match)->regs->num_regs <= i)\n\trb_raise(rb_eIndexError, \"index %d out of matches\", i);\n\n    if (RMATCH(match)->regs->beg[i] < 0)\n\treturn Qnil;\n\n    return INT2FIX(RMATCH(match)->regs->beg[i]);\n}\n\n\n/*\n *  call-seq:\n *     mtch.end(n)   => integer\n *\n *  Returns the offset of the character immediately following the end of the\n *  <em>n</em>th element of the match array in the string.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.end(0)   #=> 7\n *     m.end(2)   #=> 3\n */\n\nstatic VALUE\nmatch_end(match, n)\n    VALUE match, n;\n{\n    int i = NUM2INT(n);\n\n    match_check(match);\n    if (i < 0 || RMATCH(match)->regs->num_regs <= i)\n\trb_raise(rb_eIndexError, \"index %d out of matches\", i);\n\n    if (RMATCH(match)->regs->beg[i] < 0)\n\treturn Qnil;\n\n    return INT2FIX(RMATCH(match)->regs->end[i]);\n}\n\n#define MATCH_BUSY FL_USER2\n\nvoid\nrb_match_busy(match)\n    VALUE match;\n{\n    FL_SET(match, MATCH_BUSY);\n}\n\nint ruby_ignorecase;\nstatic int may_need_recompile;\n\nstatic void\nrb_reg_prepare_re(re)\n    VALUE re;\n{\n    int need_recompile = 0;\n    int state;\n\n    rb_reg_check(re);\n    state = FL_TEST(re, REG_CASESTATE);\n    /* ignorecase status */\n    if (ruby_ignorecase && !state) {\n\tFL_SET(re, REG_CASESTATE);\n\tRREGEXP(re)->ptr->options |= RE_OPTION_IGNORECASE;\n\tneed_recompile = 1;\n    }\n    if (!ruby_ignorecase && state) {\n\tFL_UNSET(re, REG_CASESTATE);\n\tRREGEXP(re)->ptr->options &= ~RE_OPTION_IGNORECASE;\n\tneed_recompile = 1;\n    }\n\n    if (!FL_TEST(re, KCODE_FIXED) &&\n\t(RBASIC(re)->flags & KCODE_MASK) != reg_kcode) {\n\tneed_recompile = 1;\n\tRBASIC(re)->flags &= ~KCODE_MASK;\n\tRBASIC(re)->flags |= reg_kcode;\n    }\n\n    if (need_recompile) {\n\tconst char *err;\n\n\tif (FL_TEST(re, KCODE_FIXED))\n\t    rb_kcode_set_option(re);\n\trb_reg_check(re);\n\tRREGEXP(re)->ptr->fastmap_accurate = 0;\n\terr = re_compile_pattern(RREGEXP(re)->str, RREGEXP(re)->len, RREGEXP(re)->ptr);\n\tif (err != NULL) {\n\t    rb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len, err, re);\n\t}\n    }\n}\n\nlong\nrb_reg_adjust_startpos(re, str, pos, reverse)\n    VALUE re, str;\n    long pos, reverse;\n{\n    long range;\n\n    rb_reg_check(re);\n    if (may_need_recompile) rb_reg_prepare_re(re);\n\n    if (FL_TEST(re, KCODE_FIXED))\n\trb_kcode_set_option(re);\n    else if (reg_kcode != curr_kcode)\n\trb_kcode_reset_option();\n\n    if (reverse) {\n\trange = -pos;\n    }\n    else {\n\trange = RSTRING(str)->len - pos;\n    }\n    return re_adjust_startpos(RREGEXP(re)->ptr,\n\t\t\t      RSTRING(str)->ptr, RSTRING(str)->len,\n\t\t\t      pos, range);\n}\n\nlong\nrb_reg_search(re, str, pos, reverse)\n    VALUE re, str;\n    long pos, reverse;\n{\n    long result;\n    VALUE match;\n    struct re_registers regs;\n    long range;\n\n    if (pos > RSTRING(str)->len || pos < 0) {\n\trb_backref_set(Qnil);\n\treturn -1;\n    }\n\n    rb_reg_check(re);\n    if (may_need_recompile) rb_reg_prepare_re(re);\n\n    if (FL_TEST(re, KCODE_FIXED))\n\trb_kcode_set_option(re);\n    else if (reg_kcode != curr_kcode)\n\trb_kcode_reset_option();\n\n    if (reverse) {\n\trange = -pos;\n    }\n    else {\n\trange = RSTRING(str)->len - pos;\n    }\n    MEMZERO(&regs, struct re_registers, 1);\n    result = re_search(RREGEXP(re)->ptr,RSTRING(str)->ptr,RSTRING(str)->len,\n\t\t       pos, range, &regs);\n\n    if (FL_TEST(re, KCODE_FIXED))\n\trb_kcode_reset_option();\n\n    if (result == -2) {\n\trb_reg_raise(RREGEXP(re)->str, RREGEXP(re)->len,\n\t\t     \"Stack overflow in regexp matcher\", re);\n    }\n\n    if (result < 0) {\n\tre_free_registers(&regs);\n\trb_backref_set(Qnil);\n\treturn result;\n    }\n\n    match = rb_backref_get();\n    if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) {\n\tmatch = match_alloc(rb_cMatch);\n    }\n    else {\n\tif (rb_safe_level() >= 3)\n\t    OBJ_TAINT(match);\n\telse\n\t    FL_UNSET(match, FL_TAINT);\n    }\n\n    re_copy_registers(RMATCH(match)->regs, &regs);\n    re_free_registers(&regs);\n    RMATCH(match)->str = rb_str_new4(str);\n    rb_backref_set(match);\n\n    OBJ_INFECT(match, re);\n    OBJ_INFECT(match, str);\n    return result;\n}\n\nVALUE\nrb_reg_nth_defined(nth, match)\n    int nth;\n    VALUE match;\n{\n    if (NIL_P(match)) return Qnil;\n    match_check(match);\n    if (nth >= RMATCH(match)->regs->num_regs) {\n\treturn Qnil;\n    }\n    if (nth < 0) {\n\tnth += RMATCH(match)->regs->num_regs;\n\tif (nth <= 0) return Qnil;\n    }\n    if (RMATCH(match)->BEG(nth) == -1) return Qfalse;\n    return Qtrue;\n}\n\nVALUE\nrb_reg_nth_match(nth, match)\n    int nth;\n    VALUE match;\n{\n    VALUE str;\n    long start, end, len;\n\n    if (NIL_P(match)) return Qnil;\n    match_check(match);\n    if (nth >= RMATCH(match)->regs->num_regs) {\n\treturn Qnil;\n    }\n    if (nth < 0) {\n\tnth += RMATCH(match)->regs->num_regs;\n\tif (nth <= 0) return Qnil;\n    }\n    start = RMATCH(match)->BEG(nth);\n    if (start == -1) return Qnil;\n    end = RMATCH(match)->END(nth);\n    len = end - start;\n    str = rb_str_substr(RMATCH(match)->str, start, len);\n    OBJ_INFECT(str, match);\n    return str;\n}\n\nVALUE\nrb_reg_last_match(match)\n    VALUE match;\n{\n    return rb_reg_nth_match(0, match);\n}\n\n\n/*\n *  call-seq:\n *     mtch.pre_match   => str\n *\n *  Returns the portion of the original string before the current match.\n *  Equivalent to the special variable <code>$`</code>.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.pre_match   #=> \"T\"\n */\n\nVALUE\nrb_reg_match_pre(match)\n    VALUE match;\n{\n    VALUE str;\n\n    if (NIL_P(match)) return Qnil;\n    match_check(match);\n    if (RMATCH(match)->BEG(0) == -1) return Qnil;\n    str = rb_str_substr(RMATCH(match)->str, 0, RMATCH(match)->BEG(0));\n    if (OBJ_TAINTED(match)) OBJ_TAINT(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     mtch.post_match   => str\n *\n *  Returns the portion of the original string after the current match.\n *  Equivalent to the special variable <code>$'</code>.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138: The Movie\")\n *     m.post_match   #=> \": The Movie\"\n */\n\nVALUE\nrb_reg_match_post(match)\n    VALUE match;\n{\n    VALUE str;\n    long pos;\n\n    if (NIL_P(match)) return Qnil;\n    match_check(match);\n    if (RMATCH(match)->BEG(0) == -1) return Qnil;\n    str = RMATCH(match)->str;\n    pos = RMATCH(match)->END(0);\n    str = rb_str_substr(str, pos, RSTRING(str)->len - pos);\n    if (OBJ_TAINTED(match)) OBJ_TAINT(str);\n    return str;\n}\n\nVALUE\nrb_reg_match_last(match)\n    VALUE match;\n{\n    int i;\n\n    if (NIL_P(match)) return Qnil;\n    match_check(match);\n    if (RMATCH(match)->BEG(0) == -1) return Qnil;\n\n    for (i=RMATCH(match)->regs->num_regs-1; RMATCH(match)->BEG(i) == -1 && i > 0; i--)\n\t;\n    if (i == 0) return Qnil;\n    return rb_reg_nth_match(i, match);\n}\n\nstatic VALUE\nlast_match_getter()\n{\n    return rb_reg_last_match(rb_backref_get());\n}\n\nstatic VALUE\nprematch_getter()\n{\n    return rb_reg_match_pre(rb_backref_get());\n}\n\nstatic VALUE\npostmatch_getter()\n{\n    return rb_reg_match_post(rb_backref_get());\n}\n\nstatic VALUE\nlast_paren_match_getter()\n{\n    return rb_reg_match_last(rb_backref_get());\n}\n\nstatic VALUE\nmatch_array(match, start)\n    VALUE match;\n    int start;\n{\n    struct re_registers *regs;\n    VALUE ary;\n    VALUE target;\n    int i;\n    int taint = OBJ_TAINTED(match);\n\n    match_check(match);\n    regs = RMATCH(match)->regs;\n    ary = rb_ary_new2(regs->num_regs);\n    target = RMATCH(match)->str;\n\n    for (i=start; i<regs->num_regs; i++) {\n\tif (regs->beg[i] == -1) {\n\t    rb_ary_push(ary, Qnil);\n\t}\n\telse {\n\t    VALUE str = rb_str_substr(target, regs->beg[i], regs->end[i]-regs->beg[i]);\n\t    if (taint) OBJ_TAINT(str);\n\t    rb_ary_push(ary, str);\n\t}\n    }\n    return ary;\n}\n\n\n/* [MG]:FIXME: I put parens around the /.../.match() in the first line of the\n   second example to prevent the '*' followed by a '/' from ending the\n   comment. */\n\n/*\n *  call-seq:\n *     mtch.to_a   => anArray\n *\n *  Returns the array of matches.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.to_a   #=> [\"HX1138\", \"H\", \"X\", \"113\", \"8\"]\n *\n *  Because <code>to_a</code> is called when expanding\n *  <code>*</code><em>variable</em>, there's a useful assignment\n *  shortcut for extracting matched fields. This is slightly slower than\n *  accessing the fields directly (as an intermediate array is\n *  generated).\n *\n *     all,f1,f2,f3 = *(/(.)(.)(\\d+)(\\d)/.match(\"THX1138.\"))\n *     all   #=> \"HX1138\"\n *     f1    #=> \"H\"\n *     f2    #=> \"X\"\n *     f3    #=> \"113\"\n */\n\nstatic VALUE\nmatch_to_a(match)\n    VALUE match;\n{\n    return match_array(match, 0);\n}\n\n\n/*\n *  call-seq:\n *     mtch.captures   => array\n *\n *  Returns the array of captures; equivalent to <code>mtch.to_a[1..-1]</code>.\n *\n *     f1,f2,f3,f4 = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\").captures\n *     f1    #=> \"H\"\n *     f2    #=> \"X\"\n *     f3    #=> \"113\"\n *     f4    #=> \"8\"\n */\nstatic VALUE\nmatch_captures(match)\n    VALUE match;\n{\n    return match_array(match, 1);\n}\n\n\n/*\n *  call-seq:\n *     mtch[i]               => obj\n *     mtch[start, length]   => array\n *     mtch[range]           => array\n *\n *  Match Reference---<code>MatchData</code> acts as an array, and may be\n *  accessed using the normal array indexing techniques.  <i>mtch</i>[0] is\n *  equivalent to the special variable <code>$&</code>, and returns the entire\n *  matched string.  <i>mtch</i>[1], <i>mtch</i>[2], and so on return the values\n *  of the matched backreferences (portions of the pattern between parentheses).\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m[0]       #=> \"HX1138\"\n *     m[1, 2]    #=> [\"H\", \"X\"]\n *     m[1..3]    #=> [\"H\", \"X\", \"113\"]\n *     m[-3, 2]   #=> [\"X\", \"113\"]\n */\n\nstatic VALUE\nmatch_aref(argc, argv, match)\n    int argc;\n    VALUE *argv;\n    VALUE match;\n{\n    VALUE idx, rest;\n\n    rb_scan_args(argc, argv, \"11\", &idx, &rest);\n\n    if (!NIL_P(rest) || !FIXNUM_P(idx) || FIX2INT(idx) < 0) {\n\treturn rb_ary_aref(argc, argv, match_to_a(match));\n    }\n    return rb_reg_nth_match(FIX2INT(idx), match);\n}\n\nstatic VALUE match_entry _((VALUE, long));\nstatic VALUE\nmatch_entry(match, n)\n    VALUE match;\n    long n;\n{\n    return rb_reg_nth_match(n, match);\n}\n\n\n/*\n *  call-seq:\n *     mtch.values_at([index]*)   => array\n *\n *  Uses each <i>index</i> to access the matching values, returning an array of\n *  the corresponding matches.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138: The Movie\")\n *     m.to_a               #=> [\"HX1138\", \"H\", \"X\", \"113\", \"8\"]\n *     m.values_at(0, 2, -2)   #=> [\"HX1138\", \"X\", \"113\"]\n */\n\nstatic VALUE\nmatch_values_at(argc, argv, match)\n    int argc;\n    VALUE *argv;\n    VALUE match;\n{\n    match_check(match);\n    return rb_values_at(match, RMATCH(match)->regs->num_regs, argc, argv, match_entry);\n}\n\n\n/*\n *  call-seq:\n *     mtch.select{|obj| block}   => array\n *\n *  Returns an array containing match strings for which <em>block</em>\n *  gives <code>true</code>.  MatchData#select will be removed from Ruby 1.9.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138: The Movie\")\n *     p m.select{|x| /X/ =~ x}   #=> [\"HX1138\", \"X\"]\n */\n\nstatic VALUE\nmatch_select(argc, argv, match)\n    int argc;\n    VALUE *argv;\n    VALUE match;\n{\n    if (argc > 0) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for 0)\", argc);\n    }\n    else {\n\tstruct re_registers *regs;\n\tVALUE target;\n\tVALUE result = rb_ary_new();\n\tint i;\n\tint taint = OBJ_TAINTED(match);\n\n\tmatch_check(match);\n\tregs = RMATCH(match)->regs;\n\ttarget = RMATCH(match)->str;\n\n\tfor (i=0; i<regs->num_regs; i++) {\n\t    VALUE str = rb_str_substr(target, regs->beg[i], regs->end[i]-regs->beg[i]);\n\t    if (taint) OBJ_TAINT(str);\n\t    if (RTEST(rb_yield(str))) {\n\t\trb_ary_push(result, str);\n\t    }\n\t}\n\treturn result;\n    }\n}\n\n\n\n/*\n *  call-seq:\n *     mtch.to_s   => str\n *\n *  Returns the entire matched string.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.to_s   #=> \"HX1138\"\n */\n\nstatic VALUE\nmatch_to_s(match)\n    VALUE match;\n{\n    VALUE str = rb_reg_last_match(match);\n\n    if (NIL_P(str)) str = rb_str_new(0,0);\n    if (OBJ_TAINTED(match)) OBJ_TAINT(str);\n    if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     mtch.string   => str\n *\n *  Returns a frozen copy of the string passed in to <code>match</code>.\n *\n *     m = /(.)(.)(\\d+)(\\d)/.match(\"THX1138.\")\n *     m.string   #=> \"THX1138.\"\n */\n\nstatic VALUE\nmatch_string(match)\n    VALUE match;\n{\n    match_check(match);\n    return RMATCH(match)->str;\t/* str is frozen */\n}\n\n/*\n * call-seq:\n *    mtch.inspect   => str\n *\n * Returns a printable version of <i>mtch</i>.\n *\n *     puts /.$/.match(\"foo\").inspect\n *     #=> #<MatchData \"o\">\n *\n *     puts /(.)(.)(.)/.match(\"foo\").inspect\n *     #=> #<MatchData \"foo\" 1:\"f\" 2:\"o\" 3:\"o\">\n *\n *     puts /(.)(.)?(.)/.match(\"fo\").inspect\n *     #=> #<MatchData \"fo\" 1:\"f\" 2:nil 3:\"o\">\n *\n */\n\nstatic VALUE\nmatch_inspect(VALUE match)\n{\n    const char *cname = rb_obj_classname(match);\n    VALUE str;\n    int i;\n    struct re_registers *regs = RMATCH(match)->regs;\n    int num_regs = regs->num_regs;\n\n    str = rb_str_buf_new2(\"#<\");\n    rb_str_buf_cat2(str, cname);\n\n    for (i = 0; i < num_regs; i++) {\n        VALUE v;\n        rb_str_buf_cat2(str, \" \");\n        if (0 < i) {\n            char buf[sizeof(i)*3+1];\n            snprintf(buf, sizeof(buf), \"%d\", i);\n            rb_str_buf_cat2(str, buf);\n            rb_str_buf_cat2(str, \":\");\n        }\n        v = rb_reg_nth_match(i, match);\n        if (v == Qnil)\n            rb_str_buf_cat2(str, \"nil\");\n        else\n            rb_str_buf_append(str, rb_str_inspect(v));\n    }\n    rb_str_buf_cat2(str, \">\");\n\n    return str;\n}\n\nVALUE rb_cRegexp;\n\nstatic void\nrb_reg_initialize(obj, s, len, options)\n    VALUE obj;\n    const char *s;\n    long len;\n    int options;\t\t/* CASEFOLD  = 1 */\n\t\t\t\t/* EXTENDED  = 2 */\n\t\t\t\t/* MULTILINE = 4 */\n\t\t\t\t/* CODE_NONE = 16 */\n\t\t\t\t/* CODE_EUC  = 32 */\n\t\t\t\t/* CODE_SJIS = 48 */\n\t\t\t\t/* CODE_UTF8 = 64 */\n{\n    struct RRegexp *re = RREGEXP(obj);\n\n    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify regexp\");\n    rb_check_frozen(obj);\n    if (FL_TEST(obj, REG_LITERAL))\n\trb_raise(rb_eSecurityError, \"can't modify literal regexp\");\n    if (re->ptr) re_free_pattern(re->ptr);\n    if (re->str) free(re->str);\n    re->ptr = 0;\n    re->str = 0;\n\n    switch (options & ~0xf) {\n      case 0:\n      default:\n\tFL_SET(re, reg_kcode);\n\tbreak;\n      case 16:\n\tkcode_none(re);\n\tbreak;\n      case 32:\n\tkcode_euc(re);\n\tbreak;\n      case 48:\n\tkcode_sjis(re);\n\tbreak;\n      case 64:\n\tkcode_utf8(re);\n\tbreak;\n    }\n\n    if (options & ~0xf) {\n\trb_kcode_set_option((VALUE)re);\n    }\n    if (ruby_ignorecase) {\n\toptions |= RE_OPTION_IGNORECASE;\n\tFL_SET(re, REG_CASESTATE);\n    }\n    re->ptr = make_regexp(s, len, options & 0xf);\n    re->str = ALLOC_N(char, len+1);\n    memcpy(re->str, s, len);\n    re->str[len] = '\\0';\n    re->len = len;\n    if (options & ~0xf) {\n\trb_kcode_reset_option();\n    }\n    if (ruby_in_compile) FL_SET(obj, REG_LITERAL);\n}\n\nstatic VALUE rb_reg_s_alloc _((VALUE));\nstatic VALUE\nrb_reg_s_alloc(klass)\n    VALUE klass;\n{\n    NEWOBJ(re, struct RRegexp);\n    OBJSETUP(re, klass, T_REGEXP);\n\n    re->ptr = 0;\n    re->len = 0;\n    re->str = 0;\n\n    return (VALUE)re;\n}\n\nVALUE\nrb_reg_new(s, len, options)\n    const char *s;\n    long len;\n    int options;\n{\n    VALUE re = rb_reg_s_alloc(rb_cRegexp);\n\n    rb_reg_initialize(re, s, len, options);\n    return (VALUE)re;\n}\n\nstatic int case_cache;\nstatic int kcode_cache;\nstatic VALUE reg_cache;\n\nVALUE\nrb_reg_regcomp(str)\n    VALUE str;\n{\n    volatile VALUE save_str = str;\n    if (reg_cache && RREGEXP(reg_cache)->len == RSTRING(str)->len\n\t&& case_cache == ruby_ignorecase\n\t&& kcode_cache == reg_kcode\n\t&& memcmp(RREGEXP(reg_cache)->str, RSTRING(str)->ptr, RSTRING(str)->len) == 0)\n\treturn reg_cache;\n\n    case_cache = ruby_ignorecase;\n    kcode_cache = reg_kcode;\n    reg_cache = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, ruby_ignorecase);\n    RB_GC_GUARD(save_str);\n    return reg_cache;\n}\n\nstatic int\nrb_reg_cur_kcode(re)\n    VALUE re;\n{\n    if (FL_TEST(re, KCODE_FIXED)) {\n\treturn RBASIC(re)->flags & KCODE_MASK;\n    }\n    return 0;\n}\n\n/*\n * call-seq:\n *   rxp.hash   => fixnum\n *\n * Produce a hash based on the text and options of this regular expression.\n */\n\nstatic VALUE\nrb_reg_hash(re)\n    VALUE re;\n{\n    int hashval, len;\n    char *p;\n\n    rb_reg_check(re);\n    hashval = RREGEXP(re)->ptr->options;\n    len = RREGEXP(re)->len;\n    p  = RREGEXP(re)->str;\n    while (len--) {\n\thashval = hashval * 33 + *p++;\n    }\n    hashval = hashval + (hashval>>5);\n\n    return INT2FIX(hashval);\n}\n\n\n/*\n *  call-seq:\n *     rxp == other_rxp      => true or false\n *     rxp.eql?(other_rxp)   => true or false\n *\n *  Equality---Two regexps are equal if their patterns are identical, they have\n *  the same character set code, and their <code>casefold?</code> values are the\n *  same.\n *\n *     /abc/  == /abc/x   #=> false\n *     /abc/  == /abc/i   #=> false\n *     /abc/u == /abc/n   #=> false\n */\n\nstatic VALUE\nrb_reg_equal(re1, re2)\n    VALUE re1, re2;\n{\n    if (re1 == re2) return Qtrue;\n    if (TYPE(re2) != T_REGEXP) return Qfalse;\n    rb_reg_check(re1); rb_reg_check(re2);\n    if (RREGEXP(re1)->len != RREGEXP(re2)->len) return Qfalse;\n    if (memcmp(RREGEXP(re1)->str, RREGEXP(re2)->str, RREGEXP(re1)->len) == 0 &&\n\trb_reg_cur_kcode(re1) == rb_reg_cur_kcode(re2) &&\n\tRREGEXP(re1)->ptr->options == RREGEXP(re2)->ptr->options) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\n\n/*\n *  call-seq:\n *     rxp.match(str)   => matchdata or nil\n *\n *  Returns a <code>MatchData</code> object describing the match, or\n *  <code>nil</code> if there was no match. This is equivalent to retrieving the\n *  value of the special variable <code>$~</code> following a normal match.\n *\n *     /(.)(.)(.)/.match(\"abc\")[2]   #=> \"b\"\n */\n\nVALUE\nrb_reg_match(re, str)\n    VALUE re, str;\n{\n    long start;\n\n    if (NIL_P(str)) {\n\trb_backref_set(Qnil);\n\treturn Qnil;\n    }\n    StringValue(str);\n    start = rb_reg_search(re, str, 0, 0);\n    if (start < 0) {\n\treturn Qnil;\n    }\n    return LONG2FIX(start);\n}\n\n\n/*\n *  call-seq:\n *     rxp === str   => true or false\n *\n *  Case Equality---Synonym for <code>Regexp#=~</code> used in case statements.\n *\n *     a = \"HELLO\"\n *     case a\n *     when /^[a-z]*$/; print \"Lower case\\n\"\n *     when /^[A-Z]*$/; print \"Upper case\\n\"\n *     else;            print \"Mixed case\\n\"\n *     end\n *\n *  <em>produces:</em>\n *\n *     Upper case\n */\n\nVALUE\nrb_reg_eqq(re, str)\n    VALUE re, str;\n{\n    long start;\n\n    if (TYPE(str) != T_STRING) {\n\tstr = rb_check_string_type(str);\n\tif (NIL_P(str)) {\n\t    rb_backref_set(Qnil);\n\t    return Qfalse;\n\t}\n    }\n    StringValue(str);\n    start = rb_reg_search(re, str, 0, 0);\n    if (start < 0) {\n\treturn Qfalse;\n    }\n    return Qtrue;\n}\n\n\n/*\n *  call-seq:\n *     ~ rxp   => integer or nil\n *\n *  Match---Matches <i>rxp</i> against the contents of <code>$_</code>.\n *  Equivalent to <code><i>rxp</i> =~ $_</code>.\n *\n *     $_ = \"input data\"\n *     ~ /at/   #=> 7\n */\n\nVALUE\nrb_reg_match2(re)\n    VALUE re;\n{\n    long start;\n    VALUE line = rb_lastline_get();\n\n    if (TYPE(line) != T_STRING) {\n\trb_backref_set(Qnil);\n\treturn Qnil;\n    }\n\n    start = rb_reg_search(re, line, 0, 0);\n    if (start < 0) {\n\treturn Qnil;\n    }\n    return LONG2FIX(start);\n}\n\n\n/*\n *  call-seq:\n *     rxp.match(str)   => matchdata or nil\n *\n *  Returns a <code>MatchData</code> object describing the match, or\n *  <code>nil</code> if there was no match. This is equivalent to retrieving the\n *  value of the special variable <code>$~</code> following a normal match.\n *\n *     /(.)(.)(.)/.match(\"abc\")[2]   #=> \"b\"\n */\n\nstatic VALUE\nrb_reg_match_m(re, str)\n    VALUE re, str;\n{\n    VALUE result = rb_reg_match(re, str);\n\n    if (NIL_P(result)) return Qnil;\n    result = rb_backref_get();\n    rb_match_busy(result);\n    return result;\n}\n\n/*\n * Document-method: compile\n *\n * Synonym for <code>Regexp.new</code>\n */\n\n/*\n *  call-seq:\n *     Regexp.new(string [, options [, lang]])       => regexp\n *     Regexp.new(regexp)                            => regexp\n *     Regexp.compile(string [, options [, lang]])   => regexp\n *     Regexp.compile(regexp)                        => regexp\n *\n *  Constructs a new regular expression from <i>pattern</i>, which can be either\n *  a <code>String</code> or a <code>Regexp</code> (in which case that regexp's\n *  options are propagated, and new options may not be specified (a change as of\n *  Ruby 1.8). If <i>options</i> is a <code>Fixnum</code>, it should be one or\n *  more of the constants <code>Regexp::EXTENDED</code>,\n *  <code>Regexp::IGNORECASE</code>, and <code>Regexp::MULTILINE</code>,\n *  <em>or</em>-ed together. Otherwise, if <i>options</i> is not\n *  <code>nil</code>, the regexp will be case insensitive. The <i>lang</i>\n *  parameter enables multibyte support for the regexp: `n', `N' = none, `e',\n *  `E' = EUC, `s', `S' = SJIS, `u', `U' = UTF-8.\n *\n *     r1 = Regexp.new('^a-z+:\\\\s+\\w+')           #=> /^a-z+:\\s+\\w+/\n *     r2 = Regexp.new('cat', true)               #=> /cat/i\n *     r3 = Regexp.new('dog', Regexp::EXTENDED)   #=> /dog/x\n *     r4 = Regexp.new(r2)                        #=> /cat/i\n */\n\nstatic VALUE\nrb_reg_initialize_m(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    const char *s;\n    long len;\n    int flags = 0;\n\n    if (argc == 0 || argc > 3) {\n\trb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n    if (TYPE(argv[0]) == T_REGEXP) {\n\tif (argc > 1) {\n\t    rb_warn(\"flags%s ignored\", (argc == 3) ? \" and encoding\": \"\");\n\t}\n\trb_reg_check(argv[0]);\n\tflags = RREGEXP(argv[0])->ptr->options & 0xf;\n\tif (FL_TEST(argv[0], KCODE_FIXED)) {\n\t    switch (RBASIC(argv[0])->flags & KCODE_MASK) {\n\t      case KCODE_NONE:\n\t\tflags |= 16;\n\t\tbreak;\n\t      case KCODE_EUC:\n\t\tflags |= 32;\n\t\tbreak;\n\t      case KCODE_SJIS:\n\t\tflags |= 48;\n\t\tbreak;\n\t      case KCODE_UTF8:\n\t\tflags |= 64;\n\t\tbreak;\n\t      default:\n\t\tbreak;\n\t    }\n\t}\n\ts = RREGEXP(argv[0])->str;\n\tlen = RREGEXP(argv[0])->len;\n    }\n    else {\n\tif (argc >= 2) {\n\t    if (FIXNUM_P(argv[1])) flags = FIX2INT(argv[1]);\n\t    else if (RTEST(argv[1])) flags = RE_OPTION_IGNORECASE;\n\t}\n\tif (argc == 3 && !NIL_P(argv[2])) {\n\t    char *kcode = StringValuePtr(argv[2]);\n\n\t    flags &= ~0x70;\n\t    switch (kcode[0]) {\n\t      case 'n': case 'N':\n\t\tflags |= 16;\n\t\tbreak;\n\t      case 'e': case 'E':\n\t\tflags |= 32;\n\t\tbreak;\n\t      case 's': case 'S':\n\t\tflags |= 48;\n\t\tbreak;\n\t      case 'u': case 'U':\n\t\tflags |= 64;\n\t\tbreak;\n\t      default:\n\t\tbreak;\n\t    }\n\t}\n\ts = StringValuePtr(argv[0]);\n\tlen = RSTRING(argv[0])->len;\n    }\n    rb_reg_initialize(self, s, len, flags);\n    return self;\n}\n\nVALUE\nrb_reg_quote(str)\n    VALUE str;\n{\n    char *s, *send, *t;\n    VALUE tmp;\n    int c;\n\n    s = RSTRING(str)->ptr;\n    send = s + RSTRING(str)->len;\n    for (; s < send; s++) {\n\tc = *s;\n\tif (ismbchar(c)) {\n\t    int n = mbclen(c);\n\n\t    while (n-- && s < send)\n\t\ts++;\n\t    s--;\n\t    continue;\n\t}\n\tswitch (c) {\n\t  case '[': case ']': case '{': case '}':\n\t  case '(': case ')': case '|': case '-':\n\t  case '*': case '.': case '\\\\':\n\t  case '?': case '+': case '^': case '$':\n\t  case ' ': case '#':\n\t  case '\\t': case '\\f': case '\\n': case '\\r':\n\t    goto meta_found;\n\t}\n    }\n    return rb_str_new3(str);\n\n  meta_found:\n    tmp = rb_str_new(0, RSTRING(str)->len*2);\n    t = RSTRING(tmp)->ptr;\n    /* copy upto metacharacter */\n    memcpy(t, RSTRING(str)->ptr, s - RSTRING(str)->ptr);\n    t += s - RSTRING(str)->ptr;\n\n    for (; s < send; s++) {\n\tc = *s;\n\tif (ismbchar(c)) {\n\t    int n = mbclen(c);\n\n\t    while (n-- && s < send)\n\t\t*t++ = *s++;\n\t    s--;\n\t    continue;\n\t}\n\tswitch (c) {\n\t  case '[': case ']': case '{': case '}':\n\t  case '(': case ')': case '|': case '-':\n\t  case '*': case '.': case '\\\\':\n\t  case '?': case '+': case '^': case '$':\n\t  case '#':\n\t    *t++ = '\\\\';\n\t    break;\n\t  case ' ':\n\t    *t++ = '\\\\';\n\t    *t++ = ' ';\n\t    continue;\n\t  case '\\t':\n\t    *t++ = '\\\\';\n\t    *t++ = 't';\n\t    continue;\n\t  case '\\n':\n\t    *t++ = '\\\\';\n\t    *t++ = 'n';\n\t    continue;\n\t  case '\\r':\n\t    *t++ = '\\\\';\n\t    *t++ = 'r';\n\t    continue;\n\t  case '\\f':\n\t    *t++ = '\\\\';\n\t    *t++ = 'f';\n\t    continue;\n\t}\n\t*t++ = c;\n    }\n    rb_str_resize(tmp, t - RSTRING(tmp)->ptr);\n    OBJ_INFECT(tmp, str);\n    return tmp;\n}\n\n\n/*\n *  call-seq:\n *     Regexp.escape(str)   => a_str\n *     Regexp.quote(str)    => a_str\n *\n *  Escapes any characters that would have special meaning in a regular\n *  expression. Returns a new escaped string, or self if no characters are\n *  escaped.  For any string,\n *  <code>Regexp.escape(<i>str</i>)=~<i>str</i></code> will be true.\n *\n *     Regexp.escape('\\\\*?{}.')   #=> \\\\\\\\\\*\\?\\{\\}\\.\n */\n\nstatic VALUE\nrb_reg_s_quote(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE str, kcode;\n    int kcode_saved = reg_kcode;\n\n    rb_scan_args(argc, argv, \"11\", &str, &kcode);\n    if (!NIL_P(kcode)) {\n\trb_set_kcode(StringValuePtr(kcode));\n\tcurr_kcode = reg_kcode;\n\treg_kcode = kcode_saved;\n    }\n    StringValue(str);\n    str = rb_reg_quote(str);\n    rb_kcode_reset_option();\n    return str;\n}\n\nint\nrb_kcode()\n{\n    switch (reg_kcode) {\n      case KCODE_EUC:\n\treturn MBCTYPE_EUC;\n      case KCODE_SJIS:\n\treturn MBCTYPE_SJIS;\n      case KCODE_UTF8:\n\treturn MBCTYPE_UTF8;\n      case KCODE_NONE:\n\treturn MBCTYPE_ASCII;\n    }\n    rb_bug(\"wrong reg_kcode value (0x%x)\", reg_kcode);\n}\n\nstatic int\nrb_reg_get_kcode(re)\n    VALUE re;\n{\n    switch (RBASIC(re)->flags & KCODE_MASK) {\n      case KCODE_NONE:\n\treturn 16;\n      case KCODE_EUC:\n\treturn 32;\n      case KCODE_SJIS:\n\treturn 48;\n      case KCODE_UTF8:\n\treturn 64;\n      default:\n\treturn 0;\n    }\n}\n\nint\nrb_reg_options(re)\n    VALUE re;\n{\n    int options;\n\n    rb_reg_check(re);\n    options = RREGEXP(re)->ptr->options &\n\t(RE_OPTION_IGNORECASE|RE_OPTION_MULTILINE|RE_OPTION_EXTENDED);\n    if (FL_TEST(re, KCODE_FIXED)) {\n\toptions |= rb_reg_get_kcode(re);\n    }\n    return options;\n}\n\nstatic VALUE\nrb_reg_s_union(self, args0)\n    VALUE self;\n    VALUE args0;\n{\n    long argc = RARRAY_LEN(args0);\n    if (argc == 0) {\n        VALUE args[1];\n        args[0] = rb_str_new2(\"(?!)\");\n        return rb_class_new_instance(1, args, rb_cRegexp);\n    }\n    else if (argc == 1) {\n        VALUE v;\n        v = rb_check_convert_type(rb_ary_entry(args0, 0), T_REGEXP, \"Regexp\", \"to_regexp\");\n        if (!NIL_P(v))\n            return v;\n        else {\n            VALUE args[1];\n            args[0] = rb_reg_s_quote(RARRAY_LEN(args0), RARRAY_PTR(args0));\n            return rb_class_new_instance(1, args, rb_cRegexp);\n        }\n    }\n    else {\n        int i, kcode = -1;\n        VALUE kcode_re = Qnil;\n        VALUE source = rb_str_buf_new(0);\n        VALUE args[3];\n        for (i = 0; i < argc; i++) {\n            volatile VALUE v;\n            if (0 < i)\n                rb_str_buf_cat2(source, \"|\");\n            v = rb_check_convert_type(rb_ary_entry(args0, i), T_REGEXP, \"Regexp\", \"to_regexp\");\n            if (!NIL_P(v)) {\n                if (FL_TEST(v, KCODE_FIXED)) {\n                    if (kcode == -1) {\n                        kcode_re = v;\n                        kcode = RBASIC(v)->flags & KCODE_MASK;\n                    }\n                    else if ((RBASIC(v)->flags & KCODE_MASK) != kcode) {\n                        volatile VALUE str1, str2;\n                        str1 = rb_inspect(kcode_re);\n                        str2 = rb_inspect(v);\n                        rb_raise(rb_eArgError, \"mixed kcode: %s and %s\",\n                            RSTRING(str1)->ptr, RSTRING(str2)->ptr);\n                    }\n                }\n                v = rb_reg_to_s(v);\n            }\n            else {\n                args[0] = rb_ary_entry(args0, i);\n                v = rb_reg_s_quote(1, args);\n            }\n            rb_str_buf_append(source, v);\n        }\n        args[0] = source;\n        args[1] = Qnil;\n        switch (kcode) {\n          case -1:\n            args[2] = Qnil;\n            break;\n          case KCODE_NONE:\n            args[2] = rb_str_new2(\"n\");\n            break;\n          case KCODE_EUC:\n            args[2] = rb_str_new2(\"e\");\n            break;\n          case KCODE_SJIS:\n            args[2] = rb_str_new2(\"s\");\n            break;\n          case KCODE_UTF8:\n            args[2] = rb_str_new2(\"u\");\n            break;\n        }\n        return rb_class_new_instance(3, args, rb_cRegexp);\n    }\n}\n\n/*\n *  call-seq:\n *     Regexp.union(pat1, pat2, ...)            => new_regexp\n *     Regexp.union(pats_ary)                   => new_regexp\n *\n *  Return a <code>Regexp</code> object that is the union of the given\n *  <em>pattern</em>s, i.e., will match any of its parts. The <em>pattern</em>s\n *  can be Regexp objects, in which case their options will be preserved, or\n *  Strings. If no patterns are given, returns <code>/(?!)/</code>.\n *\n *     Regexp.union                         #=> /(?!)/\n *     Regexp.union(\"penzance\")             #=> /penzance/\n *     Regexp.union(\"a+b*c\")                #=> /a\\+b\\*c/\n *     Regexp.union(\"skiing\", \"sledding\")   #=> /skiing|sledding/\n *     Regexp.union([\"skiing\", \"sledding\"]) #=> /skiing|sledding/\n *     Regexp.union(/dogs/, /cats/i)        #=> /(?-mix:dogs)|(?i-mx:cats)/\n */\nstatic VALUE\nrb_reg_s_union_m(VALUE self, VALUE args)\n{\n    VALUE v;\n    if (RARRAY_LEN(args) == 1 &&\n        !NIL_P(v = rb_check_array_type(rb_ary_entry(args, 0)))) {\n        return rb_reg_s_union(self, v);\n    }\n    return rb_reg_s_union(self, args);\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_reg_init_copy(copy, re)\n    VALUE copy, re;\n{\n    if (copy == re) return copy;\n    rb_check_frozen(copy);\n    /* need better argument type check */\n    if (!rb_obj_is_instance_of(re, rb_obj_class(copy))) {\n\trb_raise(rb_eTypeError, \"wrong argument type\");\n    }\n    rb_reg_check(re);\n    rb_reg_initialize(copy, RREGEXP(re)->str, RREGEXP(re)->len,\n\t\t      rb_reg_options(re));\n    return copy;\n}\n\nVALUE\nrb_reg_regsub(str, src, regs)\n    VALUE str, src;\n    struct re_registers *regs;\n{\n    VALUE val = 0;\n    char *p, *s, *e, c;\n    int no;\n\n    p = s = RSTRING(str)->ptr;\n    e = s + RSTRING(str)->len;\n\n    while (s < e) {\n\tchar *ss = s;\n\n\tc = *s++;\n\tif (ismbchar(c)) {\n\t    s += mbclen(c) - 1;\n\t    continue;\n\t}\n\tif (c != '\\\\' || s == e) continue;\n\n\tif (!val) {\n\t    val = rb_str_buf_new(ss-p);\n\t    rb_str_buf_cat(val, p, ss-p);\n\t}\n\telse {\n\t    rb_str_buf_cat(val, p, ss-p);\n\t}\n\n\tc = *s++;\n\tp = s;\n\tswitch (c) {\n\t  case '0': case '1': case '2': case '3': case '4':\n\t  case '5': case '6': case '7': case '8': case '9':\n\t    no = c - '0';\n\t    break;\n\t  case '&':\n\t    no = 0;\n\t    break;\n\n\t  case '`':\n\t    rb_str_buf_cat(val, RSTRING(src)->ptr, BEG(0));\n\t    continue;\n\n\t  case '\\'':\n\t    rb_str_buf_cat(val, RSTRING(src)->ptr+END(0), RSTRING(src)->len-END(0));\n\t    continue;\n\n\t  case '+':\n\t    no = regs->num_regs-1;\n\t    while (BEG(no) == -1 && no > 0) no--;\n\t    if (no == 0) continue;\n\t    break;\n\n\t  case '\\\\':\n\t    rb_str_buf_cat(val, s-1, 1);\n\t    continue;\n\n\t  default:\n\t    rb_str_buf_cat(val, s-2, 2);\n\t    continue;\n\t}\n\n\tif (no >= 0) {\n\t    if (no >= regs->num_regs) continue;\n\t    if (BEG(no) == -1) continue;\n\t    rb_str_buf_cat(val, RSTRING(src)->ptr+BEG(no), END(no)-BEG(no));\n\t}\n    }\n\n    if (p < e) {\n\tif (!val) {\n\t    val = rb_str_buf_new(e-p);\n\t    rb_str_buf_cat(val, p, e-p);\n\t}\n\telse {\n\t    rb_str_buf_cat(val, p, e-p);\n\t}\n    }\n    if (!val) return str;\n\n    return val;\n}\n\nconst char*\nrb_get_kcode()\n{\n    switch (reg_kcode) {\n      case KCODE_SJIS:\n\treturn \"SJIS\";\n      case KCODE_EUC:\n\treturn \"EUC\";\n      case KCODE_UTF8:\n\treturn \"UTF8\";\n      default:\n\treturn \"NONE\";\n    }\n}\n\nstatic VALUE\nkcode_getter()\n{\n    return rb_str_new2(rb_get_kcode());\n}\n\nvoid\nrb_set_kcode(code)\n    const char *code;\n{\n    if (code == 0) goto set_no_conversion;\n\n    switch (code[0]) {\n      case 'E':\n      case 'e':\n\treg_kcode = KCODE_EUC;\n\tre_mbcinit(MBCTYPE_EUC);\n\tbreak;\n      case 'S':\n      case 's':\n\treg_kcode = KCODE_SJIS;\n\tre_mbcinit(MBCTYPE_SJIS);\n\tbreak;\n      case 'U':\n      case 'u':\n\treg_kcode = KCODE_UTF8;\n\tre_mbcinit(MBCTYPE_UTF8);\n\tbreak;\n      default:\n      case 'N':\n      case 'n':\n      case 'A':\n      case 'a':\n      set_no_conversion:\n\treg_kcode = KCODE_NONE;\n\tre_mbcinit(MBCTYPE_ASCII);\n\tbreak;\n    }\n}\n\nstatic void\nkcode_setter(val)\n    VALUE val;\n{\n    may_need_recompile = 1;\n    rb_set_kcode(StringValuePtr(val));\n}\n\nstatic VALUE\nignorecase_getter()\n{\n    return ruby_ignorecase?Qtrue:Qfalse;\n}\n\nstatic void\nignorecase_setter(val, id)\n    VALUE val;\n    ID id;\n{\n    rb_warn(\"modifying %s is deprecated\", rb_id2name(id));\n    may_need_recompile = 1;\n    ruby_ignorecase = RTEST(val);\n}\n\nstatic VALUE\nmatch_getter()\n{\n    VALUE match = rb_backref_get();\n\n    if (NIL_P(match)) return Qnil;\n    rb_match_busy(match);\n    return match;\n}\n\nstatic void\nmatch_setter(val)\n    VALUE val;\n{\n    if (!NIL_P(val)) {\n\tCheck_Type(val, T_MATCH);\n    }\n    rb_backref_set(val);\n}\n\n/*\n *  call-seq:\n *     Regexp.last_match           => matchdata\n *     Regexp.last_match(fixnum)   => str\n *\n *  The first form returns the <code>MatchData</code> object generated by the\n *  last successful pattern match. Equivalent to reading the global variable\n *  <code>$~</code>. The second form returns the nth field in this\n *  <code>MatchData</code> object.\n *\n *     /c(.)t/ =~ 'cat'       #=> 0\n *     Regexp.last_match      #=> #<MatchData:0x401b3d30>\n *     Regexp.last_match(0)   #=> \"cat\"\n *     Regexp.last_match(1)   #=> \"a\"\n *     Regexp.last_match(2)   #=> nil\n */\n\nstatic VALUE\nrb_reg_s_last_match(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE nth;\n\n    if (rb_scan_args(argc, argv, \"01\", &nth) == 1) {\n\treturn rb_reg_nth_match(NUM2INT(nth), rb_backref_get());\n    }\n    return match_getter();\n}\n\n\n/*\n *  Document-class: Regexp\n *\n *  A <code>Regexp</code> holds a regular expression, used to match a pattern\n *  against strings. Regexps are created using the <code>/.../</code> and\n *  <code>%r{...}</code> literals, and by the <code>Regexp::new</code>\n *  constructor.\n *\n */\n\nvoid\nInit_Regexp()\n{\n    rb_eRegexpError = rb_define_class(\"RegexpError\", rb_eStandardError);\n\n    re_set_casetable(casetable);\n#if DEFAULT_KCODE == KCODE_EUC\n    re_mbcinit(MBCTYPE_EUC);\n#else\n#if DEFAULT_KCODE == KCODE_SJIS\n    re_mbcinit(MBCTYPE_SJIS);\n#else\n#if DEFAULT_KCODE == KCODE_UTF8\n    re_mbcinit(MBCTYPE_UTF8);\n#else\n    re_mbcinit(MBCTYPE_ASCII);\n#endif\n#endif\n#endif\n\n    rb_define_virtual_variable(\"$~\", match_getter, match_setter);\n    rb_define_virtual_variable(\"$&\", last_match_getter, 0);\n    rb_define_virtual_variable(\"$`\", prematch_getter, 0);\n    rb_define_virtual_variable(\"$'\", postmatch_getter, 0);\n    rb_define_virtual_variable(\"$+\", last_paren_match_getter, 0);\n\n    rb_define_virtual_variable(\"$=\", ignorecase_getter, ignorecase_setter);\n    rb_define_virtual_variable(\"$KCODE\", kcode_getter, kcode_setter);\n    rb_define_virtual_variable(\"$-K\", kcode_getter, kcode_setter);\n\n    rb_cRegexp = rb_define_class(\"Regexp\", rb_cObject);\n    rb_define_alloc_func(rb_cRegexp, rb_reg_s_alloc);\n    rb_define_singleton_method(rb_cRegexp, \"compile\", rb_class_new_instance, -1);\n    rb_define_singleton_method(rb_cRegexp, \"quote\", rb_reg_s_quote, -1);\n    rb_define_singleton_method(rb_cRegexp, \"escape\", rb_reg_s_quote, -1);\n    rb_define_singleton_method(rb_cRegexp, \"union\", rb_reg_s_union_m, -2);\n    rb_define_singleton_method(rb_cRegexp, \"last_match\", rb_reg_s_last_match, -1);\n\n    rb_define_method(rb_cRegexp, \"initialize\", rb_reg_initialize_m, -1);\n    rb_define_method(rb_cRegexp, \"initialize_copy\", rb_reg_init_copy, 1);\n    rb_define_method(rb_cRegexp, \"hash\", rb_reg_hash, 0);\n    rb_define_method(rb_cRegexp, \"eql?\", rb_reg_equal, 1);\n    rb_define_method(rb_cRegexp, \"==\", rb_reg_equal, 1);\n    rb_define_method(rb_cRegexp, \"=~\", rb_reg_match, 1);\n    rb_define_method(rb_cRegexp, \"===\", rb_reg_eqq, 1);\n    rb_define_method(rb_cRegexp, \"~\", rb_reg_match2, 0);\n    rb_define_method(rb_cRegexp, \"match\", rb_reg_match_m, 1);\n    rb_define_method(rb_cRegexp, \"to_s\", rb_reg_to_s, 0);\n    rb_define_method(rb_cRegexp, \"inspect\", rb_reg_inspect, 0);\n    rb_define_method(rb_cRegexp, \"source\", rb_reg_source, 0);\n    rb_define_method(rb_cRegexp, \"casefold?\", rb_reg_casefold_p, 0);\n    rb_define_method(rb_cRegexp, \"options\", rb_reg_options_m, 0);\n    rb_define_method(rb_cRegexp, \"kcode\", rb_reg_kcode_m, 0);\n\n    rb_define_const(rb_cRegexp, \"IGNORECASE\", INT2FIX(RE_OPTION_IGNORECASE));\n    rb_define_const(rb_cRegexp, \"EXTENDED\", INT2FIX(RE_OPTION_EXTENDED));\n    rb_define_const(rb_cRegexp, \"MULTILINE\", INT2FIX(RE_OPTION_MULTILINE));\n\n    rb_global_variable(&reg_cache);\n\n    rb_cMatch  = rb_define_class(\"MatchData\", rb_cObject);\n    rb_define_global_const(\"MatchingData\", rb_cMatch);\n    rb_define_alloc_func(rb_cMatch, match_alloc);\n    rb_undef_method(CLASS_OF(rb_cMatch), \"new\");\n\n    rb_define_method(rb_cMatch, \"initialize_copy\", match_init_copy, 1);\n    rb_define_method(rb_cMatch, \"size\", match_size, 0);\n    rb_define_method(rb_cMatch, \"length\", match_size, 0);\n    rb_define_method(rb_cMatch, \"offset\", match_offset, 1);\n    rb_define_method(rb_cMatch, \"begin\", match_begin, 1);\n    rb_define_method(rb_cMatch, \"end\", match_end, 1);\n    rb_define_method(rb_cMatch, \"to_a\", match_to_a, 0);\n    rb_define_method(rb_cMatch, \"[]\", match_aref, -1);\n    rb_define_method(rb_cMatch, \"captures\", match_captures, 0);\n    rb_define_method(rb_cMatch, \"values_at\", match_values_at, -1);\n    rb_define_method(rb_cMatch, \"select\", match_select, -1);\n    rb_define_method(rb_cMatch, \"pre_match\", rb_reg_match_pre, 0);\n    rb_define_method(rb_cMatch, \"post_match\", rb_reg_match_post, 0);\n    rb_define_method(rb_cMatch, \"to_s\", match_to_s, 0);\n    rb_define_method(rb_cMatch, \"inspect\", match_inspect, 0);\n    rb_define_method(rb_cMatch, \"string\", match_string, 0);\n}\n"
  },
  {
    "path": "re.h",
    "content": "/**********************************************************************\n\n  re.h -\n\n  $Author$\n  $Date$\n  created at: Thu Sep 30 14:18:32 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef RE_H\n#define RE_H\n\n#include <sys/types.h>\n#include <stdio.h>\n\n#include \"regex.h\"\n\ntypedef struct re_pattern_buffer Regexp;\n\nstruct RMatch {\n    struct RBasic basic;\n    VALUE str;\n    struct re_registers *regs;\n};\n\n#define RMATCH(obj)  (R_CAST(RMatch)(obj))\n#define RMATCH_REGS(obj)  (R_CAST(RMatch)(obj)->regs)\n\nVALUE rb_reg_regcomp _((VALUE));\nlong rb_reg_search _((VALUE, VALUE, long, long));\nVALUE rb_reg_regsub _((VALUE, VALUE, struct re_registers *));\nlong rb_reg_adjust_startpos _((VALUE, VALUE, long, long));\nvoid rb_match_busy _((VALUE));\nVALUE rb_reg_quote _((VALUE));\n\nRUBY_EXTERN int ruby_ignorecase;\n\nint rb_reg_mbclen2 _((unsigned int, VALUE));\n#define mbclen2(c,re) rb_reg_mbclen2((c),(re))\n#endif\n"
  },
  {
    "path": "regex.c",
    "content": "/* Extended regular expression matching and search library.\n   Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Library General Public License as\n   published by the Free Software Foundation; either version 2 of the\n   License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Library General Public License for more details.\n\n   You should have received a copy of the GNU Library General Public\n   License along with the GNU C Library; see the file LGPL.  If not,\n   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)\n   Last change: May 21, 1993 by t^2  */\n/* removed gapped buffer support, multiple syntax support by matz <matz@nts.co.jp> */\n/* Perl5 extension added by matz <matz@caelum.co.jp> */\n/* UTF-8 extension added Jan 16 1999 by Yoshida Masato  <yoshidam@tau.bekkoame.ne.jp> */\n\n#include \"config.h\"\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#else\n# include <strings.h>\n#endif\n\n/* We write fatal error messages on standard error.  */\n#include <stdio.h>\n\n/* isalpha(3) etc. are used for the character classes.  */\n#include <ctype.h>\n#include <sys/types.h>\n\n#ifndef PARAMS\n# if defined __GNUC__ || (defined __STDC__ && __STDC__)\n#  define PARAMS(args) args\n# else\n#  define PARAMS(args) ()\n# endif  /* GCC.  */\n#endif  /* Not PARAMS.  */\n\n#if defined(STDC_HEADERS)\n# include <stddef.h>\n#else\n/* We need this for `regex.h', and perhaps for the Emacs include files.  */\n# include <sys/types.h>\n#endif\n#ifdef HAVE_STDLIB_H\n# include <stdlib.h>\n#endif\n\n#if !defined(__STDC__) && !defined(_MSC_VER)\n# define volatile\n#endif\n\n#ifdef HAVE_PROTOTYPES\n# define _(args) args\n#else\n# define _(args) ()\n#endif\n\n#ifdef RUBY_PLATFORM\n#include \"defines.h\"\n#undef xmalloc\n#undef xrealloc\n#undef xcalloc\n#undef xfree\n\n# define RUBY\nextern int rb_prohibit_interrupt;\nextern int rb_trap_pending;\nvoid rb_trap_exec _((void));\n\n# define CHECK_INTS do {\\\n    if (!rb_prohibit_interrupt) {\\\n\tif (rb_trap_pending) rb_trap_exec();\\\n    }\\\n} while (0)\n#endif\n\n/* Make alloca work the best possible way.  */\n#ifdef __GNUC__\n# ifndef atarist\n#  ifndef alloca\n#   define alloca __builtin_alloca\n#  endif\n# endif /* atarist */\n#else\n# ifdef HAVE_ALLOCA_H\n#  include <alloca.h>\n# else\n#  ifdef _AIX\n #pragma alloca\n#  else\n#   ifndef alloca /* predefined by HP cc +Olibcalls */\nvoid *alloca ();\n#   endif\n#  endif /* AIX */\n# endif /* HAVE_ALLOCA_H */\n\n#endif /* __GNUC__ */\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#else\n# include <strings.h>\n#endif\n\n#define xmalloc     malloc\n#define xrealloc    realloc\n#define xcalloc     calloc\n#define xfree       free\n\n#ifdef C_ALLOCA\n#define FREE_VARIABLES() alloca(0)\n#else\n#define FREE_VARIABLES()\n#endif\n\n#define FREE_AND_RETURN_VOID(stackb)   do {\t\t\t\t\\\n  FREE_VARIABLES();\t\t\t\t\t\t\t\\\n  if (stackb != stacka) xfree(stackb);\t\t\t\t\t\\\n  return;\t\t\t\t\t\t\t\t\\\n} while(0)\n\n#define FREE_AND_RETURN(stackb,val)    do {\t\t\t\t\\\n  FREE_VARIABLES();\t\t\t\t\t\t\t\\\n  if (stackb != stacka) xfree(stackb);\t\t\t\t\t\\\n  return(val);\t\t\t\t\t\t\t\t\\\n} while(0)\n\n#define DOUBLE_STACK(type) do {\t\t\t\t\t\t\\\n  type *stackx;\t\t\t\t\t\t\t\t\\\n  unsigned int xlen = stacke - stackb; \t\t\t\t\t\\\n  if (stackb == stacka) {\t\t\t\t\t\t\\\n    stackx = (type*)xmalloc(2 * xlen * sizeof(type));\t\t\t\\\n    if (!stackx) goto memory_exhausted;\t\t\t\t\t\\\n    memcpy(stackx, stackb, xlen * sizeof (type));\t\t\t\\\n  }\t\t\t\t\t\t\t\t\t\\\n  else {\t\t\t\t\t\t\t\t\\\n    stackx = (type*)xrealloc(stackb, 2 * xlen * sizeof(type));\t\t\\\n    if (!stackx) goto memory_exhausted;\t\t\t\t\t\\\n  }\t\t\t\t\t\t\t\t\t\\\n  /* Rearrange the pointers. */\t\t\t\t\t\t\\\n  stackp = stackx + (stackp - stackb);\t\t\t\t\t\\\n  stackb = stackx;\t\t\t\t\t\t\t\\\n  stacke = stackb + 2 * xlen;\t\t\t\t\t\t\\\n} while (0)\n\n#define RE_TALLOC(n,t)  ((t*)alloca((n)*sizeof(t)))\n#define TMALLOC(n,t)    ((t*)xmalloc((n)*sizeof(t)))\n#define TREALLOC(s,n,t) (s=((t*)xrealloc(s,(n)*sizeof(t))))\n\n#define EXPAND_FAIL_STACK() DOUBLE_STACK(unsigned char*)\n#define ENSURE_FAIL_STACK(n)\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    if (stacke - stackp <= (n)) {\t\t\t\t\t\\\n\t/* if (len > re_max_failures * MAX_NUM_FAILURE_ITEMS)\t\t\\\n\t   {\t\t\t\t\t\t\t\t\\\n\t   FREE_AND_RETURN(stackb,(-2));\t\t\t\t\\\n\t   }*/\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n        /* Roughly double the size of the stack.  */\t\t\t\\\n        EXPAND_FAIL_STACK();\t\t\t\t\t\t\\\n      }\t\t\t\t\t\t\t\t\t\\\n  } while (0)\n\n/* Get the interface, including the syntax bits.  */\n#include \"regex.h\"\n\n/* Subroutines for re_compile_pattern.  */\nstatic void store_jump _((char*, int, char*));\nstatic void insert_jump _((int, char*, char*, char*));\nstatic void store_jump_n _((char*, int, char*, unsigned));\nstatic void insert_jump_n _((int, char*, char*, char*, unsigned));\n/*static void insert_op _((int, char*, char*));*/\nstatic void insert_op_2 _((int, char*, char*, int, int));\nstatic int memcmp_translate _((unsigned char*, unsigned char*, int));\n\n/* Define the syntax stuff, so we can do the \\<, \\>, etc.  */\n\n/* This must be nonzero for the wordchar and notwordchar pattern\n   commands in re_match.  */\n#define Sword  1\n#define Sword2 2\n\n#define SYNTAX(c) re_syntax_table[c]\n\nstatic char re_syntax_table[256];\nstatic void init_syntax_once _((void));\nstatic const unsigned char *translate = 0;\nstatic void init_regs _((struct re_registers*, unsigned int));\nstatic void bm_init_skip _((int *, unsigned char*, int, const unsigned char*));\nstatic int current_mbctype = MBCTYPE_ASCII;\n\n#undef P\n\n#ifdef RUBY\n#include \"util.h\"\nvoid rb_warn _((const char*, ...));\n# define re_warning(x) rb_warn(x)\n#endif\n\n#ifndef re_warning\n# define re_warning(x)\n#endif\n\nstatic void\ninit_syntax_once()\n{\n   register int c;\n   static int done = 0;\n\n   if (done)\n     return;\n\n   memset(re_syntax_table, 0, sizeof re_syntax_table);\n\n   for (c=0; c<=0x7f; c++)\n     if (isalnum(c)) \n       re_syntax_table[c] = Sword;\n   re_syntax_table['_'] = Sword;\n\n   for (c=0x80; c<=0xff; c++)\n     if (isalnum(c)) \n       re_syntax_table[c] = Sword2;\n   done = 1;\n}\n\nvoid\nre_set_casetable(table)\n     const char *table;\n{\n  translate = (const unsigned char*)table;\n}\n\n/* Jim Meyering writes:\n\n   \"... Some ctype macros are valid only for character codes that\n   isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when\n   using /bin/cc or gcc but without giving an ansi option).  So, all\n   ctype uses should be through macros like ISPRINT...  If\n   STDC_HEADERS is defined, then autoconf has verified that the ctype\n   macros don't need to be guarded with references to isascii. ...\n   Defining isascii to 1 should let any compiler worth its salt\n   eliminate the && through constant folding.\"\n   Solaris defines some of these symbols so we must undefine them first.  */\n\n#undef ISASCII\n#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)\n# define ISASCII(c) 1\n#else\n# define ISASCII(c) isascii(c)\n#endif\n\n#ifdef isblank\n# define ISBLANK(c) (ISASCII(c) && isblank(c))\n#else\n# define ISBLANK(c) ((c) == ' ' || (c) == '\\t')\n#endif\n#ifdef isgraph\n# define ISGRAPH(c) (ISASCII(c) && isgraph(c))\n#else\n# define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))\n#endif\n\n#undef ISPRINT\n#define ISPRINT(c) (ISASCII(c) && isprint(c))\n#define ISDIGIT(c) (ISASCII(c) && isdigit(c))\n#define ISALNUM(c) (ISASCII(c) && isalnum(c))\n#define ISALPHA(c) (ISASCII(c) && isalpha(c))\n#define ISCNTRL(c) (ISASCII(c) && iscntrl(c))\n#define ISLOWER(c) (ISASCII(c) && islower(c))\n#define ISPUNCT(c) (ISASCII(c) && ispunct(c))\n#define ISSPACE(c) (ISASCII(c) && isspace(c))\n#define ISUPPER(c) (ISASCII(c) && isupper(c))\n#define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))\n\n#ifndef NULL\n# define NULL (void *)0\n#endif\n\n/* We remove any previous definition of `SIGN_EXTEND_CHAR',\n   since ours (we hope) works properly with all combinations of\n   machines, compilers, `char' and `unsigned char' argument types.\n   (Per Bothner suggested the basic approach.)  */\n#undef SIGN_EXTEND_CHAR\n#if __STDC__\n# define SIGN_EXTEND_CHAR(c) ((signed char)(c))\n#else  /* not __STDC__ */\n/* As in Harbison and Steele.  */\n# define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)\n#endif\n\n/* These are the command codes that appear in compiled regular\n   expressions, one per byte.  Some command codes are followed by\n   argument bytes.  A command code can specify any interpretation\n   whatsoever for its arguments.  Zero-bytes may appear in the compiled\n   regular expression.\n\n   The value of `exactn' is needed in search.c (search_buffer) in emacs.\n   So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of\n   `exactn' we use here must also be 1.  */\n\nenum regexpcode\n  {\n    unused=0,\n    exactn=1, /* Followed by one byte giving n, then by n literal bytes.  */\n    begline,  /* Fail unless at beginning of line.  */\n    endline,  /* Fail unless at end of line.  */\n    begbuf,   /* Succeeds if at beginning of buffer (if emacs) or at beginning\n                 of string to be matched (if not).  */\n    endbuf,   /* Analogously, for end of buffer/string.  */\n    endbuf2,  /* End of buffer/string, or newline just before it.  */\n    begpos,   /* Matches where last scan//gsub left off.  */\n    jump,     /* Followed by two bytes giving relative address to jump to.  */\n    jump_past_alt,/* Same as jump, but marks the end of an alternative.  */\n    on_failure_jump,\t /* Followed by two bytes giving relative address of \n\t\t\t    place to resume at in case of failure.  */\n    finalize_jump,\t /* Throw away latest failure point and then jump to \n\t\t\t    address.  */\n    maybe_finalize_jump, /* Like jump but finalize if safe to do so.\n\t\t\t    This is used to jump back to the beginning\n\t\t\t    of a repeat.  If the command that follows\n\t\t\t    this jump is clearly incompatible with the\n\t\t\t    one at the beginning of the repeat, such that\n\t\t\t    we can be sure that there is no use backtracking\n\t\t\t    out of repetitions already completed,\n\t\t\t    then we finalize.  */\n    dummy_failure_jump,  /* Jump, and push a dummy failure point. This \n\t\t\t    failure point will be thrown away if an attempt \n                            is made to use it for a failure. A + construct \n                            makes this before the first repeat.  Also\n                            use it as an intermediary kind of jump when\n                            compiling an or construct.  */\n    push_dummy_failure, /* Push a dummy failure point and continue.  Used at the end of\n\t\t\t   alternatives.  */\n    succeed_n,\t /* Used like on_failure_jump except has to succeed n times;\n\t\t    then gets turned into an on_failure_jump. The relative\n                    address following it is useless until then.  The\n                    address is followed by two bytes containing n.  */\n    jump_n,\t /* Similar to jump, but jump n times only; also the relative\n\t\t    address following is in turn followed by yet two more bytes\n                    containing n.  */\n    try_next,    /* Jump to next pattern for the first time,\n\t\t    leaving this pattern on the failure stack. */\n    finalize_push,\t/* Finalize stack and push the beginning of the pattern\n\t\t\t   on the stack to retry (used for non-greedy match) */\n    finalize_push_n,\t/* Similar to finalize_push, buf finalize n time only */\n    set_number_at,\t/* Set the following relative location to the\n\t\t\t   subsequent number.  */\n    anychar,\t /* Matches any (more or less) one character excluding newlines.  */\n    anychar_repeat,\t /* Matches sequence of characters excluding newlines.  */\n    charset,     /* Matches any one char belonging to specified set.\n\t\t    First following byte is number of bitmap bytes.\n\t\t    Then come bytes for a bitmap saying which chars are in.\n\t\t    Bits in each byte are ordered low-bit-first.\n\t\t    A character is in the set if its bit is 1.\n\t\t    A character too large to have a bit in the map\n\t\t    is automatically not in the set.  */\n    charset_not, /* Same parameters as charset, but match any character\n                    that is not one of those specified.  */\n    start_memory, /* Start remembering the text that is matched, for\n\t\t    storing in a memory register.  Followed by one\n                    byte containing the register number.  Register numbers\n                    must be in the range 0 through RE_NREGS.  */\n    stop_memory, /* Stop remembering the text that is matched\n\t\t    and store it in a memory register.  Followed by\n                    one byte containing the register number. Register\n                    numbers must be in the range 0 through RE_NREGS.  */\n    start_paren,    /* Place holder at the start of (?:..). */\n    stop_paren,    /* Place holder at the end of (?:..). */\n    casefold_on,   /* Turn on casefold flag. */\n    casefold_off,  /* Turn off casefold flag. */\n    option_set,\t   /* Turn on multi line match (match with newlines). */\n    start_nowidth, /* Save string point to the stack. */\n    stop_nowidth,  /* Restore string place at the point start_nowidth. */\n    pop_and_fail,  /* Fail after popping nowidth entry from stack. */\n    stop_backtrack,  /* Restore backtrack stack at the point start_nowidth. */\n    duplicate,   /* Match a duplicate of something remembered.\n\t\t    Followed by one byte containing the index of the memory \n                    register.  */\n    wordchar,    /* Matches any word-constituent character.  */\n    notwordchar, /* Matches any char that is not a word-constituent.  */\n    wordbeg,\t /* Succeeds if at word beginning.  */\n    wordend,\t /* Succeeds if at word end.  */\n    wordbound,   /* Succeeds if at a word boundary.  */\n    notwordbound /* Succeeds if not at a word boundary.  */\n  };\n\n\n/* Number of failure points to allocate space for initially,\n   when matching.  If this number is exceeded, more space is allocated,\n   so it is not a hard limit.  */\n\n#ifndef NFAILURES\n#define NFAILURES 160\n#endif\n\n/* Store NUMBER in two contiguous bytes starting at DESTINATION.  */\n#define STORE_NUMBER(destination, number)\t\t\t\t\\\n  do { (destination)[0] = (number) & 0377;\t\t\t\t\\\n    (destination)[1] = (number) >> 8; } while (0)\n\n/* Same as STORE_NUMBER, except increment the destination pointer to\n   the byte after where the number is stored.  Watch out that values for\n   DESTINATION such as p + 1 won't work, whereas p will.  */\n#define STORE_NUMBER_AND_INCR(destination, number)\t\t\t\\\n  do { STORE_NUMBER(destination, number);\t\t\t\t\\\n    (destination) += 2; } while (0)\n\n\n/* Put into DESTINATION a number stored in two contingous bytes starting\n   at SOURCE.  */\n#define EXTRACT_NUMBER(destination, source)\t\t\t\t\\\n  do { (destination) = *(source) & 0377;\t\t\t\t\\\n    (destination) += SIGN_EXTEND_CHAR(*(char*)((source) + 1)) << 8; } while (0)\n\n/* Same as EXTRACT_NUMBER, except increment the pointer for source to\n   point to second byte of SOURCE.  Note that SOURCE has to be a value\n   such as p, not, e.g., p + 1. */\n#define EXTRACT_NUMBER_AND_INCR(destination, source)\t\t\t\\\n  do { EXTRACT_NUMBER(destination, source);\t\t\t\t\\\n       (source) += 2; } while (0)\n\n\n/* Specify the precise syntax of regexps for compilation.  This provides\n   for compatibility for various utilities which historically have\n   different, incompatible syntaxes.\n\n   The argument SYNTAX is a bit-mask comprised of the various bits\n   defined in regex.h.  */\n\nlong\nre_set_syntax(syntax)\n  long syntax;\n{\n    /* obsolete */\n    return 0;\n}\n\n/* Macros for re_compile_pattern, which is found below these definitions.  */\n\n#define TRANSLATE_P() ((options&RE_OPTION_IGNORECASE) && translate)\n#define MAY_TRANSLATE() ((bufp->options&(RE_OPTION_IGNORECASE|RE_MAY_IGNORECASE)) && translate)\n/* Fetch the next character in the uncompiled pattern---translating it \n   if necessary.  Also cast from a signed character in the constant\n   string passed to us by the user to an unsigned char that we can use\n   as an array index (in, e.g., `translate').  */\n#define PATFETCH(c)\t\t\t\t\t\t\t\\\n  do {if (p == pend) goto end_of_pattern;\t\t\t\t\\\n    c = (unsigned char) *p++; \t\t\t\t\t\t\\\n    if (TRANSLATE_P()) c = (unsigned char)translate[c];\t\\\n  } while (0)\n\n/* Fetch the next character in the uncompiled pattern, with no\n   translation.  */\n#define PATFETCH_RAW(c)\t\t\t\t\t\t\t\\\n  do {if (p == pend) goto end_of_pattern;\t\t\t\t\\\n    c = (unsigned char)*p++; \t\t\t\t\t\t\\\n  } while (0)\n\n/* Go backwards one character in the pattern.  */\n#define PATUNFETCH p--\n\n#define MBC2WC(c, p)\t\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    if (current_mbctype == MBCTYPE_UTF8) {\t\t\t\t\\\n      int n = mbclen(c) - 1;\t\t\t\t\t\t\\\n      c &= (1<<(BYTEWIDTH-2-n)) - 1;\t\t\t\t\t\\\n      while (n--) {\t\t\t\t\t\t\t\\\n\tc = c << 6 | (*p++ & ((1<<6)-1));\t\t\t\t\\\n      }\t\t\t\t\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    else {\t\t\t\t\t\t\t\t\\\n      c <<= 8;\t\t\t\t\t\t\t\t\\\n      c |= (unsigned char)*(p)++;\t\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n  } while (0)\n\n#define PATFETCH_MBC(c)\t\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    if (p + mbclen(c) - 1 >= pend) goto end_of_pattern;\t\t\t\\\n    MBC2WC(c, p);\t\t\t\t\t\t\t\\\n  } while(0)\n\n#define WC2MBC1ST(c)\t\t\t\t\t\t\t\\\n ((current_mbctype != MBCTYPE_UTF8) ? ((c<0x100) ? (c) : (((c)>>8)&0xff)) : utf8_firstbyte(c))\n\ntypedef unsigned int (*mbc_startpos_func_t) _((const char *string, unsigned int pos));\n\nstatic unsigned int asc_startpos _((const char *string, unsigned int pos));\nstatic unsigned int euc_startpos _((const char *string, unsigned int pos));\nstatic unsigned int sjis_startpos _((const char *string, unsigned int pos));\nstatic unsigned int utf8_startpos _((const char *string, unsigned int pos));\n\nstatic const mbc_startpos_func_t mbc_startpos_func[4] = {\n  asc_startpos, euc_startpos, sjis_startpos, utf8_startpos\n};\n\n#define mbc_startpos(start, pos) (*mbc_startpos_func[current_mbctype])((start), (pos))\n\nstatic unsigned int\nutf8_firstbyte(c)\n     unsigned long c;\n{\n  if (c < 0x80) return c;\n  if (c <= 0x7ff) return ((c>>6)&0xff)|0xc0;\n  if (c <= 0xffff) return ((c>>12)&0xff)|0xe0;\n  if (c <= 0x1fffff) return ((c>>18)&0xff)|0xf0;\n  if (c <= 0x3ffffff) return ((c>>24)&0xff)|0xf8;\n  if (c <= 0x7fffffff) return ((c>>30)&0xff)|0xfc;\n#if SIZEOF_INT > 4\n  if (c <= 0xfffffffff) return 0xfe;\n#else\n  return 0xfe;\n#endif\n}\n\n#if 0\nstatic void\nprint_mbc(c)\n     unsigned int c;\n{\n  if (current_mbctype == MBCTYPE_UTF8) {\n    if (c < 0x80)\n      printf(\"%c\", (int)c);\n    else if (c <= 0x7ff)\n      printf(\"%c%c\", (int)utf8_firstbyte(c), (int)(c & 0x3f));\n    else if (c <= 0xffff)\n      printf(\"%c%c%c\", (int)utf8_firstbyte(c), (int)((c >> 6) & 0x3f),\n\t     (int)(c & 0x3f));\n    else if (c <= 0x1fffff) \n      printf(\"%c%c%c%c\", (int)utf8_firstbyte(c), (int)((c >> 12) & 0x3f),\n\t     (int)((c >> 6) & 0x3f), (int)(c & 0x3f));\n    else if (c <= 0x3ffffff)\n      printf(\"%c%c%c%c%c\", (int)utf8_firstbyte(c), (int)((c >> 18) & 0x3f),\n\t     (int)((c >> 12) & 0x3f), (int)((c >> 6) & 0x3f), (int)(c & 0x3f));\n    else if (c <= 0x7fffffff)\n      printf(\"%c%c%c%c%c%c\", (int)utf8_firstbyte(c), (int)((c >> 24) & 0x3f),\n\t     (int)((c >> 18) & 0x3f), (int)((c >> 12) & 0x3f),\n\t     (int)((c >> 6) & 0x3f), (int)(c & 0x3f));\n  }\n  else if (c < 0xff) {\n    printf(\"\\\\%o\", (int)c);\n  }\n  else {\n    printf(\"%c%c\", (int)(c >> BYTEWIDTH), (int)(c &0xff));\n  }\n}\n#endif\n\n/* If the buffer isn't allocated when it comes in, use this.  */\n#define INIT_BUF_SIZE  28\n\n/* Make sure we have at least N more bytes of space in buffer.  */\n#define GET_BUFFER_SPACE(n)\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t        \\\n    while (b - bufp->buffer + (n) >= bufp->allocated)\t\t\t\\\n      EXTEND_BUFFER;\t\t\t\t\t\t\t\\\n  } while (0)\n\n/* Make sure we have one more byte of buffer space and then add CH to it.  */\n#define BUFPUSH(ch)\t\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    GET_BUFFER_SPACE(1);\t\t\t\t\t\t\\\n    *b++ = (char)(ch);\t\t\t\t\t\t\t\\\n  } while (0)\n\n/* Extend the buffer by twice its current size via reallociation and\n   reset the pointers that pointed into the old allocation to point to\n   the correct places in the new allocation.  If extending the buffer\n   results in it being larger than 1 << 16, then flag memory exhausted.  */\n#define EXTEND_BUFFER\t\t\t\t\t\t\\\n  do { char *old_buffer = bufp->buffer;\t\t\t\t\t\\\n    if (bufp->allocated == (1L<<16)) goto too_big;\t\t\t\\\n    bufp->allocated *= 2;\t\t\t\t\t\t\\\n    if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16);\t\t\\\n    bufp->buffer = (char*)xrealloc(bufp->buffer, bufp->allocated);\t\\\n    if (bufp->buffer == 0)\t\t\t\t\t\t\\\n      goto memory_exhausted;\t\t\t\t\t\t\\\n    b = (b - old_buffer) + bufp->buffer;\t\t\t\t\\\n    if (fixup_alt_jump)\t\t\t\t\t\t\t\\\n      fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\t\\\n    if (laststart)\t\t\t\t\t\t\t\\\n      laststart = (laststart - old_buffer) + bufp->buffer;\t\t\\\n    begalt = (begalt - old_buffer) + bufp->buffer;\t\t\t\\\n    if (pending_exact)\t\t\t\t\t\t\t\\\n      pending_exact = (pending_exact - old_buffer) + bufp->buffer;\t\\\n  } while (0)\n\n\n/* Set the bit for character C in a character set list.  */\n#define SET_LIST_BIT(c)\t\t\t\t\t\t\t\\\n  (b[(unsigned char)(c) / BYTEWIDTH]\t\t\t\t\t\\\n   |= 1 << ((unsigned char)(c) % BYTEWIDTH))\n\n/* Get the next unsigned number in the uncompiled pattern.  */\n#define GET_UNSIGNED_NUMBER(num) \t\t\t\t\t\\\n  do { if (p != pend) { \t\t\t\t\t\t\\\n        PATFETCH(c); \t\t\t\t\t\t\t\\\n\twhile (ISDIGIT(c)) { \t\t\t\t\t\t\\\n\t  if (num < 0) \t\t\t\t\t\t\t\\\n\t     num = 0; \t\t\t\t\t\t\t\\\n\t  num = num * 10 + c - '0'; \t\t\t\t\t\\\n\t  if (p == pend) \t\t\t\t\t\t\\\n\t     break; \t\t\t\t\t\t\t\\\n\t  PATFETCH(c); \t\t\t\t\t\t\t\\\n\t} \t\t\t\t\t\t\t\t\\\n     } \t\t\t\t\t\t\t\t\t\\\n  } while (0)\n\n#define STREQ(s1, s2) ((strcmp(s1, s2) == 0))\n\n#define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */\n\n#define IS_CHAR_CLASS(string)\t\t\t\t\t\t\\\n   (STREQ(string, \"alpha\") || STREQ(string, \"upper\")\t\t\t\\\n    || STREQ(string, \"lower\") || STREQ(string, \"digit\")\t\t\t\\\n    || STREQ(string, \"alnum\") || STREQ(string, \"xdigit\")\t\t\\\n    || STREQ(string, \"space\") || STREQ(string, \"print\")\t\t\t\\\n    || STREQ(string, \"punct\") || STREQ(string, \"graph\")\t\t\t\\\n    || STREQ(string, \"cntrl\") || STREQ(string, \"blank\"))\n\f\n#define STORE_MBC(p, c)\t\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    (p)[0] = (unsigned char)(((c) >>24) & 0xff);\t\t\t\\\n    (p)[1] = (unsigned char)(((c) >>16) & 0xff);\t\t\t\\\n    (p)[2] = (unsigned char)(((c) >> 8) & 0xff);\t\t\t\\\n    (p)[3] = (unsigned char)(((c) >> 0) & 0xff);\t\t\t\\\n  } while (0)\n\n#define STORE_MBC_AND_INCR(p, c) \t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    *(p)++ = (unsigned char)(((c) >>24) & 0xff);\t\t\t\\\n    *(p)++ = (unsigned char)(((c) >>16) & 0xff);\t\t\t\\\n    *(p)++ = (unsigned char)(((c) >> 8) & 0xff);\t\t\t\\\n    *(p)++ = (unsigned char)(((c) >> 0) & 0xff);\t\t\t\\\n  } while (0)\n\n#define EXTRACT_MBC(p) \t\t\t\t\t\t\t\\\n  ((unsigned int)((unsigned char)(p)[0] << 24 |\t\t\t\t\\\n\t\t    (unsigned char)(p)[1] << 16 |\t\t\t\\\n                    (unsigned char)(p)[2] <<  8 |\t\t\t\\\n\t\t    (unsigned char)(p)[3]))\n\n#define EXTRACT_MBC_AND_INCR(p) \t\t\t\t\t\\\n  ((unsigned int)((p) += 4, \t\t\t\t\t\t\\\n\t\t    (unsigned char)(p)[-4] << 24 |\t\t\t\\\n\t\t    (unsigned char)(p)[-3] << 16 |\t\t\t\\\n                    (unsigned char)(p)[-2] <<  8 |\t\t\t\\\n\t\t    (unsigned char)(p)[-1]))\n\n#define EXTRACT_UNSIGNED(p) \\\n  ((unsigned char)(p)[0] | (unsigned char)(p)[1] << 8)\n#define EXTRACT_UNSIGNED_AND_INCR(p) \\\n  ((p) += 2, (unsigned char)(p)[-2] | (unsigned char)(p)[-1] << 8)\n\n/* Handle (mb)?charset(_not)?.\n\n   Structure of mbcharset(_not)? in compiled pattern.\n\n     struct {\n       unsinged char id;\t\tmbcharset(_not)?\n       unsigned char sbc_size;\n       unsigned char sbc_map[sbc_size];\tsame as charset(_not)? up to here.\n       unsigned short mbc_size;\t\tnumber of intervals.\n       struct {\n\t unsigned long beg;\t\tbeginning of interval.\n\t unsigned long end;\t\tend of interval.\n       } intervals[mbc_size];\n     }; */\n\nstatic void\nset_list_bits(c1, c2, b)\n    unsigned long c1, c2;\n    unsigned char *b;\n{\n  unsigned char sbc_size = b[-1];\n  unsigned short mbc_size = EXTRACT_UNSIGNED(&b[sbc_size]);\n  unsigned short beg, end, upb;\n\n  if (c1 > c2)\n    return;\n  b = &b[sbc_size + 2];\n\n  for (beg = 0, upb = mbc_size; beg < upb; ) {\n    unsigned short mid = (unsigned short)(beg + upb) >> 1;\n\n    if ((int)c1 - 1 > (int)EXTRACT_MBC(&b[mid*8+4]))\n      beg = mid + 1;\n    else\n      upb = mid;\n  }\n\n  for (end = beg, upb = mbc_size; end < upb; ) {\n    unsigned short mid = (unsigned short)(end + upb) >> 1;\n\n    if ((int)c2 >= (int)EXTRACT_MBC(&b[mid*8]) - 1)\n      end = mid + 1;\n    else\n      upb = mid;\n  }\n\n  if (beg != end) {\n    if (c1 > EXTRACT_MBC(&b[beg*8]))\n      c1 = EXTRACT_MBC(&b[beg*8]);\n    if (c2 < EXTRACT_MBC(&b[(end - 1)*8+4]))\n      c2 = EXTRACT_MBC(&b[(end - 1)*8+4]);\n  }\n  if (end < mbc_size && end != beg + 1)\n    /* NOTE: memcpy() would not work here.  */\n    memmove(&b[(beg + 1)*8], &b[end*8], (mbc_size - end)*8);\n  STORE_MBC(&b[beg*8 + 0], c1);\n  STORE_MBC(&b[beg*8 + 4], c2);\n  mbc_size += beg - end + 1;\n  STORE_NUMBER(&b[-2], mbc_size);\n}\n\nstatic int\nis_in_list_sbc(c, b)\n    unsigned long c;\n    const unsigned char *b;\n{\n  unsigned short size;\n\n  size = *b++;\n  return ((int)c / BYTEWIDTH < (int)size && b[c / BYTEWIDTH] & 1 << c % BYTEWIDTH);\n}\n  \nstatic int\nis_in_list_mbc(c, b)\n    unsigned long c;\n    const unsigned char *b;\n{\n  unsigned short size;\n  unsigned short i, j;\n\n  size = *b++;\n  b += size + 2;\n  size = EXTRACT_UNSIGNED(&b[-2]);\n  if (size == 0) return 0;\n\n  for (i = 0, j = size; i < j; ) {\n    unsigned short k = (unsigned short)(i + j) >> 1;\n\n    if (c > EXTRACT_MBC(&b[k*8+4]))\n      i = k + 1;\n    else\n      j = k;\n  }\n  if (i < size && EXTRACT_MBC(&b[i*8]) <= c)\n    return 1;\n\n  return 0;\n}\n\nstatic int\nis_in_list(c, b)\n    unsigned long c;\n    const unsigned char *b;\n{\n  return is_in_list_sbc(c, b) || (current_mbctype ? is_in_list_mbc(c, b) : 0);\n}\n\n#if 0\nstatic void\nprint_partial_compiled_pattern(start, end)\n    unsigned char *start;\n    unsigned char *end;\n{\n  int mcnt, mcnt2;\n  unsigned char *p = start;\n  unsigned char *pend = end;\n\n  if (start == NULL) {\n    printf(\"(null)\\n\");\n    return;\n  }\n\n  /* Loop over pattern commands.  */\n  while (p < pend) {\n    switch ((enum regexpcode)*p++) {\n    case unused:\n      printf(\"/unused\");\n      break;\n\n    case exactn:\n      mcnt = *p++;\n      printf(\"/exactn/%d\", mcnt);\n      do {\n\tputchar('/');\n\tprintf(\"%c\", *p++);\n      }\n      while (--mcnt);\n      break;\n\n    case start_memory:\n      mcnt = *p++;\n      printf(\"/start_memory/%d/%d\", mcnt, *p++);\n      break;\n\n    case stop_memory:\n      mcnt = *p++;\n      printf(\"/stop_memory/%d/%d\", mcnt, *p++);\n      break;\n\n    case start_paren:\n      printf(\"/start_paren\");\n      break;\n\n    case stop_paren:\n      printf(\"/stop_paren\");\n      break;\n\n    case casefold_on:\n      printf(\"/casefold_on\");\n      break;\n\n    case casefold_off:\n      printf(\"/casefold_off\");\n      break;\n\n    case option_set:\n      printf(\"/option_set/%d\", *p++);\n      break;\n\n    case start_nowidth:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/start_nowidth//%d\", mcnt);\n      break;\n\n    case stop_nowidth:\n      printf(\"/stop_nowidth//\");\n      p += 2;\n      break;\n\n    case pop_and_fail:\n      printf(\"/pop_and_fail\");\n      break;\n\n    case stop_backtrack:\n      printf(\"/stop_backtrack//\");\n      p += 2;\n      break;\n\n    case duplicate:\n      printf(\"/duplicate/%d\", *p++);\n      break;\n\n    case anychar:\n      printf(\"/anychar\");\n      break;\n\n    case anychar_repeat:\n      printf(\"/anychar_repeat\");\n      break;\n\n    case charset:\n    case charset_not:\n      {\n\tregister int c;\n\n\tprintf(\"/charset%s\",\n\t       (enum regexpcode)*(p - 1) == charset_not ? \"_not\" : \"\");\n\n\tmcnt = *p++;\n\tprintf(\"/%d\", mcnt);\n\tfor (c = 0; c < mcnt; c++) {\n\t  unsigned bit;\n\t  unsigned char map_byte = p[c];\n\n\t  putchar('/');\n\n\t  for (bit = 0; bit < BYTEWIDTH; bit++)\n\t    if (map_byte & (1 << bit))\n\t      printf(\"%c\", c * BYTEWIDTH + bit);\n\t}\n\tp += mcnt;\n\tmcnt = EXTRACT_UNSIGNED_AND_INCR(p);\n\tputchar('/');\n\twhile (mcnt--) {\n\t  print_mbc(EXTRACT_MBC_AND_INCR(p));\n\t  putchar('-');\n\t  print_mbc(EXTRACT_MBC_AND_INCR(p));\n\t}\n\tbreak;\n      }\n\n    case begline:\n      printf(\"/begline\");\n      break;\n\n    case endline:\n      printf(\"/endline\");\n      break;\n\n    case on_failure_jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/on_failure_jump//%d\", mcnt);\n      break;\n\n    case dummy_failure_jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/dummy_failure_jump//%d\", mcnt);\n      break;\n\n    case push_dummy_failure:\n      printf(\"/push_dummy_failure\");\n      break;\n\n    case finalize_jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/finalize_jump//%d\", mcnt);\n      break;\n\n    case maybe_finalize_jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/maybe_finalize_jump//%d\", mcnt);\n      break;\n\n    case jump_past_alt:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/jump_past_alt//%d\", mcnt);\n      break;\n\n    case jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/jump//%d\", mcnt);\n      break;\n\n    case succeed_n: \n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      EXTRACT_NUMBER_AND_INCR(mcnt2, p);\n      printf(\"/succeed_n//%d//%d\", mcnt, mcnt2);\n      break;\n\n    case jump_n: \n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      EXTRACT_NUMBER_AND_INCR(mcnt2, p);\n      printf(\"/jump_n//%d//%d\", mcnt, mcnt2);\n      break;\n\n    case set_number_at: \n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      EXTRACT_NUMBER_AND_INCR(mcnt2, p);\n      printf(\"/set_number_at//%d//%d\", mcnt, mcnt2);\n      break;\n\n    case try_next:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/try_next//%d\", mcnt);\n      break;\n\n    case finalize_push:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      printf(\"/finalize_push//%d\", mcnt);\n      break;\n\n    case finalize_push_n:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      EXTRACT_NUMBER_AND_INCR(mcnt2, p);\n      printf(\"/finalize_push_n//%d//%d\", mcnt, mcnt2);\n      break;\n\n    case wordbound:\n      printf(\"/wordbound\");\n      break;\n\n    case notwordbound:\n      printf(\"/notwordbound\");\n      break;\n\n    case wordbeg:\n      printf(\"/wordbeg\");\n      break;\n\n    case wordend:\n      printf(\"/wordend\");\n\n    case wordchar:\n      printf(\"/wordchar\");\n      break;\n\t  \n    case notwordchar:\n      printf(\"/notwordchar\");\n      break;\n\n    case begbuf:\n      printf(\"/begbuf\");\n      break;\n\n    case endbuf:\n      printf(\"/endbuf\");\n      break;\n\n    case endbuf2:\n      printf(\"/endbuf2\");\n      break;\n\n    case begpos:\n      printf(\"/begpos\");\n      break;\n\n    default:\n      printf(\"?%d\", *(p-1));\n    }\n  }\n  printf(\"/\\n\");\n}\n\n\nstatic void\nprint_compiled_pattern(bufp)\n     struct re_pattern_buffer *bufp;\n{\n  unsigned char *buffer = (unsigned char*)bufp->buffer;\n\n  print_partial_compiled_pattern(buffer, buffer + bufp->used);\n}\n#endif\n\nstatic char*\ncalculate_must_string(start, end)\n     char *start;\n     char *end;\n{\n  int mcnt;\n  int max = 0;\n  unsigned char *p = (unsigned char *)start;\n  unsigned char *pend = (unsigned char *)end;\n  char *must = 0;\n\n  if (start == NULL) return 0;\n\n  /* Loop over pattern commands.  */\n  while (p < pend) {\n    switch ((enum regexpcode)*p++) {\n    case unused:\n      break;\n\n    case exactn:\n      mcnt = *p;\n      if (mcnt > max) {\n\tmust = (char *)p;\n\tmax = mcnt;\n      }\n      p += mcnt+1;\n      break;\n\n    case start_memory:\n    case stop_memory:\n      p += 2;\n      break;\n\n    case duplicate:\n    case option_set:\n      p++;\n      break;\n\n    case casefold_on:\n    case casefold_off:\n      return 0;\t\t/* should not check must_string */\n\n    case pop_and_fail:\n    case anychar:\n    case anychar_repeat:\n    case begline:\n    case endline:\n    case wordbound:\n    case notwordbound:\n    case wordbeg:\n    case wordend:\n    case wordchar:\n    case notwordchar:\n    case begbuf:\n    case endbuf:\n    case endbuf2:\n    case begpos:\n    case push_dummy_failure:\n    case start_paren:\n    case stop_paren:\n      break;\n\n    case charset:\n    case charset_not:\n      mcnt = *p++;\n      p += mcnt;\n      mcnt = EXTRACT_UNSIGNED_AND_INCR(p);\n      while (mcnt--) {\n\tp += 8;\n      }\n      break;\n\n    case on_failure_jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      if (mcnt > 0) p += mcnt;\n      if ((enum regexpcode)p[-3] == jump) {\n\tp -= 2;\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tif (mcnt > 0) p += mcnt;\n      }\n      break;\n\n    case dummy_failure_jump:\n    case succeed_n: \n    case try_next:\n    case jump:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      if (mcnt > 0) p += mcnt;\n      break;\n\n    case start_nowidth:\n    case stop_nowidth:\n    case stop_backtrack:\n    case finalize_jump:\n    case maybe_finalize_jump:\n    case finalize_push:\n      p += 2;\n      break;\n\n    case jump_n: \n    case set_number_at: \n    case finalize_push_n:\n      p += 4;\n      break;\n\n    default:\n      break;\n    }\n  }\n  return must;\n}\n\nstatic unsigned int\nread_backslash(c)\n     int c;\n{\n  switch (c) {\n  case 'n':\n    return '\\n';\n\n  case 't':\n    return '\\t';\n\n  case 'r':\n    return '\\r';\n\n  case 'f':\n    return '\\f';\n\n  case 'v':\n    return '\\v';\n\n  case 'a':\n    return '\\007';\n\n  case 'b':\n    return '\\010';\n\n  case 'e':\n    return '\\033';\n  }\n  return c;\n}\n\nstatic unsigned int\nread_special(p, pend, pp)\n     const char *p, *pend, **pp;\n{\n  int c;\n\n  PATFETCH_RAW(c);\n  switch (c) {\n  case 'M':\n    PATFETCH_RAW(c);\n    if (c != '-') return -1;\n    PATFETCH_RAW(c);\n    *pp = p;\n    if (c == '\\\\') {\n      return read_special(--p, pend, pp) | 0x80;\n    }\n    else if (c == -1) return ~0;\n    else {\n      return ((c & 0xff) | 0x80);\n    }\n\n  case 'C':\n    PATFETCH_RAW(c);\n    if (c != '-') return ~0;\n  case 'c':\n    PATFETCH_RAW(c);\n    *pp = p;\n    if (c == '\\\\') {\n      c = read_special(--p, pend, pp);\n    }\n    else if (c == '?') return 0177;\n    else if (c == -1) return ~0;\n    return c & 0x9f;\n  default:\n    *pp = p + 1;\n    return read_backslash(c);\n  }\n\n end_of_pattern:\n  return ~0;\n}\n\n/* re_compile_pattern takes a regular-expression string\n   and converts it into a buffer full of byte commands for matching.\n\n   PATTERN   is the address of the pattern string\n   SIZE      is the length of it.\n   BUFP\t    is a  struct re_pattern_buffer *  which points to the info\n\t     on where to store the byte commands.\n\t     This structure contains a  char *  which points to the\n\t     actual space, which should have been obtained with malloc.\n\t     re_compile_pattern may use realloc to grow the buffer space.\n\n   The number of bytes of commands can be found out by looking in\n   the `struct re_pattern_buffer' that bufp pointed to, after\n   re_compile_pattern returns. */\n\nconst char *\nre_compile_pattern(pattern, size, bufp)\n     const char *pattern;\n     int size;\n     struct re_pattern_buffer *bufp;\n{\n  register char *b = bufp->buffer;\n  register const char *p = pattern;\n  const char *nextp;\n  const char *pend = pattern + size;\n  register unsigned int c, c1 = 0;\n  const char *p0;\n  int numlen;\n#define ERROR_MSG_MAX_SIZE 200\n  static char error_msg[ERROR_MSG_MAX_SIZE+1];\n\n  /* Address of the count-byte of the most recently inserted `exactn'\n     command.  This makes it possible to tell whether a new exact-match\n     character can be added to that command or requires a new `exactn'\n     command.  */\n\n  char *pending_exact = 0;\n\n  /* Address of the place where a forward-jump should go to the end of\n     the containing expression.  Each alternative of an `or', except the\n     last, ends with a forward-jump of this sort.  */\n\n  char *fixup_alt_jump = 0;\n\n  /* Address of start of the most recently finished expression.\n     This tells postfix * where to find the start of its operand.  */\n\n  char *laststart = 0;\n\n  /* In processing a repeat, 1 means zero matches is allowed.  */\n\n  char zero_times_ok;\n\n  /* In processing a repeat, 1 means many matches is allowed.  */\n\n  char many_times_ok;\n\n  /* In processing a repeat, 1 means non-greedy matches.  */\n\n  char greedy;\n\n  /* Address of beginning of regexp, or inside of last (.  */\n\n  char *begalt = b;\n\n  /* Place in the uncompiled pattern (i.e., the {) to\n     which to go back if the interval is invalid.  */\n  const char *beg_interval;\n\n  /* In processing an interval, at least this many matches must be made.  */\n  int lower_bound;\n\n  /* In processing an interval, at most this many matches can be made.  */\n  int upper_bound;\n\n  /* Stack of information saved by ( and restored by ).\n     Five stack elements are pushed by each (:\n     First, the value of b.\n     Second, the value of fixup_alt_jump.\n     Third, the value of begalt.\n     Fourth, the value of regnum.\n     Fifth, the type of the paren. */\n\n  int stacka[40];\n  int *stackb = stacka;\n  int *stackp = stackb;\n  int *stacke = stackb + 40;\n\n  /* Counts ('s as they are encountered.  Remembered for the matching ),\n     where it becomes the register number to put in the stop_memory\n     command.  */\n\n  int regnum = 1;\n\n  int range = 0;\n  int had_mbchar = 0;\n  int had_num_literal = 0;\n  int had_char_class = 0;\n\n  int options = bufp->options;\n\n  bufp->fastmap_accurate = 0;\n  bufp->must = 0;\n  bufp->must_skip = 0;\n\n  /* Initialize the syntax table.  */\n  init_syntax_once();\n\n  if (bufp->allocated == 0) {\n    bufp->allocated = INIT_BUF_SIZE;\n    /* EXTEND_BUFFER loses when bufp->allocated is 0.  */\n    bufp->buffer = (char*)xrealloc(bufp->buffer, INIT_BUF_SIZE);\n    if (!bufp->buffer) goto memory_exhausted; /* this not happen */\n    begalt = b = bufp->buffer;\n  }\n\n  while (p != pend) {\n    PATFETCH(c);\n\n    switch (c) {\n    case '$':\n      if (bufp->options & RE_OPTION_SINGLELINE) {\n\tBUFPUSH(endbuf);\n      }\n      else {\n\tp0 = p;\n\t/* When testing what follows the $,\n\t   look past the \\-constructs that don't consume anything.  */\n\n\twhile (p0 != pend) {\n\t  if (*p0 == '\\\\' && p0 + 1 != pend\n\t      && (p0[1] == 'b' || p0[1] == 'B'))\n\t    p0 += 2;\n\t  else\n\t    break;\n\t}\n\tBUFPUSH(endline);\n      }\n      break;\n\n    case '^':\n      if (bufp->options & RE_OPTION_SINGLELINE)\n\tBUFPUSH(begbuf);\n      else\n\tBUFPUSH(begline);\n      break;\n\n    case '+':\n    case '?':\n    case '*':\n      /* If there is no previous pattern, char not special. */\n      if (!laststart) {\n\tsnprintf(error_msg, ERROR_MSG_MAX_SIZE, \n\t\t \"invalid regular expression; there's no previous pattern, to which '%c' would define cardinality at %d\", \n\t\t c, p-pattern);\n\tFREE_AND_RETURN(stackb, error_msg);\n      }\n      /* If there is a sequence of repetition chars,\n\t collapse it down to just one.  */\n      zero_times_ok = c != '+';\n      many_times_ok = c != '?';\n      greedy = 1;\n      if (p != pend) {\n\tPATFETCH(c);\n\tswitch (c) {\n\tcase '?':\n\t  greedy = 0;\n\t  break;\n\tcase '*':\n\tcase '+':\n\t  goto nested_meta;\n\tdefault:\n\t  PATUNFETCH;\n\t  break;\n\t}\n      }\n\n    repeat:\n      /* Star, etc. applied to an empty pattern is equivalent\n\t to an empty pattern.  */\n      if (!laststart)  \n\tbreak;\n\n      if (greedy && many_times_ok && *laststart == anychar && b - laststart <= 2) {\n\tif (b[-1] == stop_paren)\n\t  b--;\n\tif (zero_times_ok)\n\t  *laststart = anychar_repeat;\n\telse {\n\t  BUFPUSH(anychar_repeat);\n\t}\n\tbreak;\n      }\n      /* Now we know whether or not zero matches is allowed\n\t and also whether or not two or more matches is allowed.  */\n      if (many_times_ok) {\n\t/* If more than one repetition is allowed, put in at the\n\t   end a backward relative jump from b to before the next\n\t   jump we're going to put in below (which jumps from\n\t   laststart to after this jump).  */\n\tGET_BUFFER_SPACE(3);\n\tstore_jump(b,greedy?maybe_finalize_jump:finalize_push,laststart-3);\n\tb += 3;  \t/* Because store_jump put stuff here.  */\n      }\n\n      /* On failure, jump from laststart to next pattern, which will be the\n\t end of the buffer after this jump is inserted.  */\n      GET_BUFFER_SPACE(3);\n      insert_jump(on_failure_jump, laststart, b + 3, b);\n      b += 3;\n\n      if (zero_times_ok) {\n\tif (greedy == 0) {\n\t  GET_BUFFER_SPACE(3);\n\t  insert_jump(try_next, laststart, b + 3, b);\n\t  b += 3;\n\t}\n      }\n      else {\n\t/* At least one repetition is required, so insert a\n\t   `dummy_failure_jump' before the initial\n\t   `on_failure_jump' instruction of the loop. This\n\t   effects a skip over that instruction the first time\n\t   we hit that loop.  */\n\tGET_BUFFER_SPACE(3);\n\tinsert_jump(dummy_failure_jump, laststart, laststart + 6, b);\n\tb += 3;\n      }\n      break;\n\n    case '.':\n      laststart = b;\n      BUFPUSH(anychar);\n      break;\n\n    case '[':\n      if (p == pend)\n\tFREE_AND_RETURN(stackb, \"invalid regular expression; '[' can't be the last character ie. can't start range at the end of pattern\");\n      while ((b - bufp->buffer + 9 + (1 << BYTEWIDTH) / BYTEWIDTH)\n\t     > bufp->allocated)\n\tEXTEND_BUFFER;\n\n      laststart = b;\n      if (*p == '^') {\n\tBUFPUSH(charset_not); \n\tp++;\n      }\n      else\n\tBUFPUSH(charset);\n      p0 = p;\n\n      BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH);\n      /* Clear the whole map */\n      memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2);\n\n      had_mbchar = 0;\n      had_num_literal = 0;\n      had_char_class = 0;\n\n      /* Read in characters and ranges, setting map bits.  */\n      for (;;) {\n\tint size;\n\tunsigned last = (unsigned)-1;\n\n\tif ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])) || current_mbctype) {\n\t  /* Ensure the space is enough to hold another interval\n\t     of multi-byte chars in charset(_not)?.  */\n\t  size = (1 << BYTEWIDTH) / BYTEWIDTH + 2 + size*8 + 8;\n\t  while (b + size + 1 > bufp->buffer + bufp->allocated)\n\t    EXTEND_BUFFER;\n\t}\n      range_retry:\n\tif (range && had_char_class) {\n\t  FREE_AND_RETURN(stackb, \"invalid regular expression; can't use character class as an end value of range\");\n\t}\n\tPATFETCH_RAW(c);\n\n\tif (c == ']') {\n\t  if (p == p0 + 1) {\n\t    if (p == pend)\n\t      FREE_AND_RETURN(stackb, \"invalid regular expression; empty character class\");\n            re_warning(\"character class has `]' without escape\");\n\t  }\n\t  else \n\t    /* Stop if this isn't merely a ] inside a bracket\n\t       expression, but rather the end of a bracket\n\t       expression.  */\n\t    break;\n\t}\n\t/* Look ahead to see if it's a range when the last thing\n\t   was a character class.  */\n\tif (had_char_class && c == '-' && *p != ']')\n\t  FREE_AND_RETURN(stackb, \"invalid regular expression; can't use character class as a start value of range\");\n\tif (ismbchar(c)) {\n\t  PATFETCH_MBC(c);\n\t  had_mbchar++;\n\t}\n\thad_char_class = 0;\n\n\tif (c == '-' && ((p != p0 + 1 && *p != ']') ||\n                         (p[0] == '-' && p[1] != ']') ||\n                         range))\n          re_warning(\"character class has `-' without escape\");\n        if (c == '[' && *p != ':')\n          re_warning(\"character class has `[' without escape\");\n\n\t/* \\ escapes characters when inside [...].  */\n\tif (c == '\\\\') {\n\t  PATFETCH_RAW(c);\n\t  switch (c) {\n\t  case 'w':\n\t    for (c = 0; c < (1 << BYTEWIDTH); c++) {\n\t      if (SYNTAX(c) == Sword ||\n\t\t  (!current_mbctype && SYNTAX(c) == Sword2))\n\t\tSET_LIST_BIT(c);\n\t    }\n\t    if (current_mbctype) {\n\t      set_list_bits(0x80, 0xffffffff, b);\n\t    }\n\t    had_char_class = 1;\n\t    last = -1;\n\t    continue;\n\n\t  case 'W':\n\t    for (c = 0; c < (1 << BYTEWIDTH); c++) {\n\t      if (SYNTAX(c) != Sword &&\n\t\t  ((current_mbctype && !re_mbctab[c]) ||\n\t\t  (!current_mbctype && SYNTAX(c) != Sword2)))\n\t\tSET_LIST_BIT(c);\n\t    }\n\t    had_char_class = 1;\n\t    last = -1;\n\t    continue;\n\n\t  case 's':\n\t    for (c = 0; c < 256; c++)\n\t      if (ISSPACE(c))\n\t\tSET_LIST_BIT(c);\n\t    had_char_class = 1;\n\t    last = -1;\n\t    continue;\n\n\t  case 'S':\n\t    for (c = 0; c < 256; c++)\n\t      if (!ISSPACE(c))\n\t\tSET_LIST_BIT(c);\n\t    if (current_mbctype)\n\t      set_list_bits(0x80, 0xffffffff, b);\n\t    had_char_class = 1;\n\t    last = -1;\n\t    continue;\n\n\t  case 'd':\n\t    for (c = '0'; c <= '9'; c++)\n\t      SET_LIST_BIT(c);\n\t    had_char_class = 1;\n\t    last = -1;\n\t    continue;\n\n\t  case 'D':\n\t    for (c = 0; c < 256; c++)\n\t      if (!ISDIGIT(c))\n\t\tSET_LIST_BIT(c);\n\t    if (current_mbctype)\n\t      set_list_bits(0x80, 0xffffffff, b);\n\t    had_char_class = 1;\n\t    last = -1;\n\t    continue;\n\n\t  case 'x':\n\t    c = scan_hex(p, 2, &numlen);\n\t    if (numlen == 0) goto invalid_escape;\n\t    p += numlen;\n\t    had_num_literal = 1;\n\t    break;\n\n\t  case '0': case '1': case '2': case '3': case '4':\n\t  case '5': case '6': case '7': case '8': case '9':\n\t    PATUNFETCH;\n\t    c = scan_oct(p, 3, &numlen);\n\t    p += numlen;\n\t    had_num_literal = 1;\n\t    break;\n\n\t  case 'M':\n\t  case 'C':\n\t  case 'c':\n\t    {\n\t      const char *pp;\n\n\t      --p;\n\t      c = read_special(p, pend, &pp);\n\t      if (c > 255) goto invalid_escape;\n\t      p = pp;\n\t      had_num_literal = 1;\n\t    }\n\t    break;\n\n\t  default:\n\t    c = read_backslash(c);\n\t    if (ismbchar(c)) {\n\t      PATFETCH_MBC(c);\n\t      had_mbchar++;\n\t    }\n\t    break;\n\t  }\n\t}\n        else if (c == '[' && *p == ':') { /* [:...:] */\n\t  /* Leave room for the null.  */\n\t  char str[CHAR_CLASS_MAX_LENGTH + 1];\n\n\t  PATFETCH_RAW(c);\n\t  c1 = 0;\n\n\t  /* If pattern is `[[:'.  */\n\t  if (p == pend) \n\t    FREE_AND_RETURN(stackb, \"invalid regular expression; re can't end '[[:'\");\n\n\t  for (;;) {\n\t    PATFETCH_RAW(c);\n\t    if (c == ':' || c == ']' || p == pend\n\t\t|| c1 == CHAR_CLASS_MAX_LENGTH)\n\t      break;\n\t    str[c1++] = c;\n\t  }\n\t  str[c1] = '\\0';\n\n\t  /* If isn't a word bracketed by `[:' and `:]':\n\t     undo the ending character, the letters, and\n\t     the leading `:' and `['.  */\n\t  if (c == ':' && *p == ']') {\n\t    int ch;\n\t    char is_alnum = STREQ(str, \"alnum\");\n\t    char is_alpha = STREQ(str, \"alpha\");\n\t    char is_blank = STREQ(str, \"blank\");\n\t    char is_cntrl = STREQ(str, \"cntrl\");\n\t    char is_digit = STREQ(str, \"digit\");\n\t    char is_graph = STREQ(str, \"graph\");\n\t    char is_lower = STREQ(str, \"lower\");\n\t    char is_print = STREQ(str, \"print\");\n\t    char is_punct = STREQ(str, \"punct\");\n\t    char is_space = STREQ(str, \"space\");\n\t    char is_upper = STREQ(str, \"upper\");\n\t    char is_xdigit = STREQ(str, \"xdigit\");\n\n\t    if (!IS_CHAR_CLASS(str)){\n\t      snprintf(error_msg, ERROR_MSG_MAX_SIZE, \n\t\t       \"invalid regular expression; [:%s:] is not a character class\", str);\n\t      FREE_AND_RETURN(stackb, error_msg);\n\t    }\n\n\t    /* Throw away the ] at the end of the character class.  */\n\t    PATFETCH(c);\n\n\t    if (p == pend) \n\t      FREE_AND_RETURN(stackb, \"invalid regular expression; range doesn't have ending ']' after a character class\");\n\n\t    for (ch = 0; ch < 1 << BYTEWIDTH; ch++) {\n\t      if (   (is_alnum  && ISALNUM(ch))\n\t\t  || (is_alpha  && ISALPHA(ch))\n\t\t  || (is_blank  && ISBLANK(ch))\n\t\t  || (is_cntrl  && ISCNTRL(ch))\n\t\t  || (is_digit  && ISDIGIT(ch))\n\t\t  || (is_graph  && ISGRAPH(ch))\n\t\t  || (is_lower  && ISLOWER(ch))\n\t\t  || (is_print  && ISPRINT(ch))\n\t\t  || (is_punct  && ISPUNCT(ch))\n\t\t  || (is_space  && ISSPACE(ch))\n\t\t  || (is_upper  && ISUPPER(ch))\n\t\t  || (is_xdigit && ISXDIGIT(ch)))\n\t\tSET_LIST_BIT(ch);\n\t    }\n\t    had_char_class = 1;\n            continue;\n\t  }\n\t  else {\n\t    c1 += 2;\n\t    while (c1--)    \n\t      PATUNFETCH;\n            re_warning(\"character class has `[' without escape\");\n            c = '[';\n\t  }\n\t}\n\n\t/* Get a range.  */\n\tif (range) {\n\t  if (last > c)\n\t    goto invalid_pattern;\n\n\t  range = 0;\n\t  if (had_mbchar == 0) {\n\t    if (TRANSLATE_P()) {\n\t      for (;last<=c;last++) \n\t\tSET_LIST_BIT(translate[last]);\n\t    }\n\t    else {\n\t      for (;last<=c;last++) \n\t\tSET_LIST_BIT(last);\n\t    }\n\t  }\n\t  else if (had_mbchar == 2) {\n\t    set_list_bits(last, c, b);\n\t  }\n\t  else {\n\t    /* restriction: range between sbc and mbc */\n\t    goto invalid_pattern;\n\t  }\n\t}\n\telse if (p[0] == '-' && p[1] != ']') {\n\t  last = c;\n\t  PATFETCH_RAW(c1);\n\t  range = 1;\n\t  goto range_retry;\n\t}\n\telse {\n\t  if (TRANSLATE_P() && c < 0x100) c = (unsigned char)translate[c];\n\t  if (had_mbchar == 0 && (!current_mbctype || !had_num_literal)) {\n\t    SET_LIST_BIT(c);\n\t    had_num_literal = 0;\n\t  }\n\t  else {\n\t    set_list_bits(c, c, b);\n\t  }\n\t}\n\thad_mbchar = 0;\n      }\n\n      /* Discard any character set/class bitmap bytes that are all\n\t 0 at the end of the map. Decrement the map-length byte too.  */\n      while ((int)b[-1] > 0 && b[b[-1] - 1] == 0) \n\tb[-1]--; \n      if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH)\n\tmemmove(&b[(unsigned char)b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH],\n\t\t2 + EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])*8);\n      b += b[-1] + 2 + EXTRACT_UNSIGNED(&b[(unsigned char)b[-1]])*8;\n      had_num_literal = 0;\n      break;\n\n    case '(':\n      {\n\tint old_options = options;\n\tint push_option = 0;\n\tint casefold = 0;\n\n\tPATFETCH(c);\n\tif (c == '?') {\n\t  int negative = 0;\n\n\t  PATFETCH_RAW(c);\n\t  switch (c) {\n\t  case 'x': case 'm': case 'i': case '-':\n\t    for (;;) {\n\t      switch (c) {\n\t      case '-':\n\t\tnegative = 1;\n\t\tbreak;\n\n\t      case ':':\n\t      case ')':\n\t\tbreak;\n\n\t      case 'x':\n\t\tif (negative)\n\t\t  options &= ~RE_OPTION_EXTENDED;\n\t\telse\n\t\t  options |= RE_OPTION_EXTENDED;\n\t\tbreak;\n\n\t      case 'm':\n\t\tif (negative) {\n\t\t  if (options&RE_OPTION_MULTILINE) {\n\t\t    options &= ~RE_OPTION_MULTILINE;\n\t\t  }\n\t\t}\n\t\telse if (!(options&RE_OPTION_MULTILINE)) {\n\t\t  options |= RE_OPTION_MULTILINE;\n\t\t}\n\t\tpush_option = 1;\n\t\tbreak;\n\n\t      case 'i':\n\t\tif (negative) {\n\t\t  if (options&RE_OPTION_IGNORECASE) {\n\t\t    options &= ~RE_OPTION_IGNORECASE;\n\t\t  }\n\t\t}\n\t\telse if (!(options&RE_OPTION_IGNORECASE)) {\n\t\t  options |= RE_OPTION_IGNORECASE;\n\t\t}\n\t\tcasefold = 1;\n\t\tbreak;\n\n\t      default:\n\t\tFREE_AND_RETURN(stackb, \"undefined (?...) inline option\");\n\t      }\n\t      if (c == ')') {\n\t\tc = '#';\t/* read whole in-line options */\n\t\tbreak;\n\t      }\n\t      if (c == ':') break;\n\t      PATFETCH_RAW(c);\n\t    }\n\t    break;\n\n\t  case '#':\n\t    for (;;) {\n\t      PATFETCH(c);\n\t      if (c == ')') break;\n\t    }\n\t    c = '#';\n\t    break;\n\n\t  case ':':\n\t  case '=':\n\t  case '!':\n\t  case '>':\n\t    break;\n\n\t  default:\n\t    FREE_AND_RETURN(stackb, \"undefined (?...) sequence\");\n\t  }\n\t}\n\telse {\n\t  PATUNFETCH;\n\t  c = '(';\n\t}\n\tif (c == '#') {\n\t  if (push_option) {\n\t    BUFPUSH(option_set);\n\t    BUFPUSH(options);\n\t  }\n\t  if (casefold) {\n\t    if (options & RE_OPTION_IGNORECASE)\n\t      BUFPUSH(casefold_on);\n\t    else\n\t      BUFPUSH(casefold_off);\n\t  }\n\t  break;\n\t}\n\tif (stackp+8 >= stacke) {\n\t  DOUBLE_STACK(int);\n\t}\n\n\t/* Laststart should point to the start_memory that we are about\n\t   to push (unless the pattern has RE_NREGS or more ('s).  */\n\t/* obsolete: now RE_NREGS is just a default register size. */\n\t*stackp++ = b - bufp->buffer;    \n\t*stackp++ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;\n\t*stackp++ = begalt - bufp->buffer;\n\tswitch (c) {\n\tcase '(':\n\t  BUFPUSH(start_memory);\n\t  BUFPUSH(regnum);\n\t  *stackp++ = regnum++;\n\t  *stackp++ = b - bufp->buffer;\n\t  BUFPUSH(0);\n\t  /* too many ()'s to fit in a byte. (max 254) */\n\t  if (regnum >= RE_REG_MAX) goto too_big;\n\t  break;\n\n\tcase '=':\n\tcase '!':\n\tcase '>':\n\t  BUFPUSH(start_nowidth);\n\t  *stackp++ = b - bufp->buffer;\n\t  BUFPUSH(0);\t/* temporary value */\n\t  BUFPUSH(0);\n\t  if (c != '!') break;\n\n\t  BUFPUSH(on_failure_jump);\n\t  *stackp++ = b - bufp->buffer;\n\t  BUFPUSH(0);\t/* temporary value */\n\t  BUFPUSH(0);\n\t  break;\n\n\tcase ':':\n\t  BUFPUSH(start_paren);\n\t  pending_exact = 0;\n\tdefault:\n\t  break;\n\t}\n\tif (push_option) {\n\t  BUFPUSH(option_set);\n\t  BUFPUSH(options);\n\t}\n\tif (casefold) {\n\t  if (options & RE_OPTION_IGNORECASE)\n\t    BUFPUSH(casefold_on);\n\t  else\n\t    BUFPUSH(casefold_off);\n\t}\n\t*stackp++ = c;\n\t*stackp++ = old_options;\n\tfixup_alt_jump = 0;\n\tlaststart = 0;\n\tbegalt = b;\n      }\n      break;\n\n    case ')':\n      if (stackp == stackb) \n\tFREE_AND_RETURN(stackb, \"unmatched )\");\n\n      pending_exact = 0;\n      if (fixup_alt_jump) {\n\t/* Push a dummy failure point at the end of the\n\t   alternative for a possible future\n\t   `finalize_jump' to pop.  See comments at\n\t   `push_dummy_failure' in `re_match'.  */\n\tBUFPUSH(push_dummy_failure);\n\n\t/* We allocated space for this jump when we assigned\n\t   to `fixup_alt_jump', in the `handle_alt' case below.  */\n\tstore_jump(fixup_alt_jump, jump, b);\n      }\n      if (options != stackp[-1]) {\n\tif ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {\n\t  BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);\n\t}\n\tif ((options ^ stackp[-1]) != RE_OPTION_IGNORECASE) {\n\t  BUFPUSH(option_set);\n\t  BUFPUSH(stackp[-1]);\n\t}\n      }\n      p0 = b;\n      options = *--stackp;\n      switch (c = *--stackp) {\n      case '(':\n\t{\n\t  char *loc = bufp->buffer + *--stackp;\n\t  *loc = regnum - stackp[-1];\n\t  BUFPUSH(stop_memory);\n\t  BUFPUSH(stackp[-1]);\n\t  BUFPUSH(regnum - stackp[-1]);\n\t  stackp--;\n\t}\n\tbreak;\n\n      case '!':\n\tBUFPUSH(pop_and_fail);\n\t/* back patch */\n\tSTORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2);\n\tstackp--;\n\t/* fall through */\n      case '=':\n\tBUFPUSH(stop_nowidth);\n\t/* tell stack-pos place to start_nowidth */\n\tSTORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2);\n\tBUFPUSH(0);\t/* space to hold stack pos */\n\tBUFPUSH(0);\n\tstackp--;\n\tbreak;\n\n      case '>':\n\tBUFPUSH(stop_backtrack);\n\t/* tell stack-pos place to start_nowidth */\n\tSTORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2);\n\tBUFPUSH(0);\t/* space to hold stack pos */\n\tBUFPUSH(0);\n\tstackp--;\n\tbreak;\n\n      case ':':\n\tBUFPUSH(stop_paren);\n\tbreak;\n\n      default:\n\tbreak;\n      }\n      begalt = *--stackp + bufp->buffer;\n      stackp--;\n      fixup_alt_jump = *stackp ? *stackp + bufp->buffer - 1 : 0;\n      laststart = *--stackp + bufp->buffer;\n      if (c == '!' || c == '=') laststart = b;\n      break;\n\n    case '|':\n      /* Insert before the previous alternative a jump which\n\t jumps to this alternative if the former fails.  */\n      GET_BUFFER_SPACE(3);\n      insert_jump(on_failure_jump, begalt, b + 6, b);\n      pending_exact = 0;\n      b += 3;\n      /* The alternative before this one has a jump after it\n\t which gets executed if it gets matched.  Adjust that\n\t jump so it will jump to this alternative's analogous\n\t jump (put in below, which in turn will jump to the next\n\t (if any) alternative's such jump, etc.).  The last such\n\t jump jumps to the correct final destination.  A picture:\n\t _____ _____ \n\t |   | |   |   \n\t |   v |   v \n\t a | b   | c   \n\n\t If we are at `b', then fixup_alt_jump right now points to a\n\t three-byte space after `a'.  We'll put in the jump, set\n\t fixup_alt_jump to right after `b', and leave behind three\n\t bytes which we'll fill in when we get to after `c'.  */\n\n      if (fixup_alt_jump)\n\tstore_jump(fixup_alt_jump, jump_past_alt, b);\n\n      /* Mark and leave space for a jump after this alternative,\n\t to be filled in later either by next alternative or\n\t when know we're at the end of a series of alternatives.  */\n      fixup_alt_jump = b;\n      GET_BUFFER_SPACE(3);\n      b += 3;\n\n      laststart = 0;\n      begalt = b;\n      break;\n\n    case '{':\n      /* If there is no previous pattern, this is an invalid pattern.  */\n      if (!laststart) {\n\tsnprintf(error_msg, ERROR_MSG_MAX_SIZE, \n\t\t \"invalid regular expression; there's no previous pattern, to which '{' would define cardinality at %d\", \n\t\t p-pattern);\n\tFREE_AND_RETURN(stackb, error_msg);\n      }\n      if( p == pend)\n\tFREE_AND_RETURN(stackb, \"invalid regular expression; '{' can't be last character\" );\n\n      beg_interval = p - 1;\n\n      lower_bound = -1;\t\t\t/* So can see if are set.  */\n      upper_bound = -1;\n      GET_UNSIGNED_NUMBER(lower_bound);\n      if (c == ',') {\n\tGET_UNSIGNED_NUMBER(upper_bound);\n      }\n      else\n\t/* Interval such as `{1}' => match exactly once. */\n\tupper_bound = lower_bound;\n\n      if (lower_bound < 0 || c != '}')\n\tgoto unfetch_interval;\n\n      if (lower_bound >= RE_DUP_MAX || upper_bound >= RE_DUP_MAX)\n\tFREE_AND_RETURN(stackb, \"too big quantifier in {,}\");\n      if (upper_bound < 0) upper_bound = RE_DUP_MAX;\n      if (lower_bound > upper_bound)\n\tFREE_AND_RETURN(stackb, \"can't do {n,m} with n > m\");\n\n      beg_interval = 0;\n      pending_exact = 0;\n\n      greedy = 1;\n      if (p != pend) {\n\tPATFETCH(c);\n\tif (c == '?') greedy = 0;\n\telse PATUNFETCH;\n      }\n\n      if (lower_bound == 0) {\n\tzero_times_ok = 1;\n\tif (upper_bound == RE_DUP_MAX) {\n\t  many_times_ok = 1;\n\t  goto repeat;\n\t}\n\tif (upper_bound == 1) {\n\t  many_times_ok = 0;\n\t  goto repeat;\n\t}\n      }\n      if (lower_bound == 1) {\n\tif (upper_bound == 1) {\n\t  /* No need to repeat */\n\t  break;\n\t}\n\tif (upper_bound == RE_DUP_MAX) {\n\t  many_times_ok = 1;\n\t  zero_times_ok = 0;\n\t  goto repeat;\n\t}\n      }\n\n      /* If upper_bound is zero, don't want to succeed at all; \n\t jump from laststart to b + 3, which will be the end of\n\t the buffer after this jump is inserted.  */\n\n      if (upper_bound == 0) {\n\tGET_BUFFER_SPACE(3);\n\tinsert_jump(jump, laststart, b + 3, b);\n\tb += 3;\n\tbreak;\n      }\n\n      /* If lower_bound == upper_bound, repeat count can be removed */\n      if (lower_bound == upper_bound) {\n\tint mcnt;\n\tint skip_stop_paren = 0;\n\n\tif (b[-1] == stop_paren) {\n\t  skip_stop_paren = 1;\n\t  b--;\n\t}\n\n\tif (*laststart == exactn && laststart[1]+2 == b - laststart\n\t    && laststart[1]*lower_bound < 256) {\n\t  mcnt = laststart[1];\n\t  GET_BUFFER_SPACE((lower_bound-1)*mcnt);\n\t  laststart[1] = lower_bound*mcnt;\n\t  while (--lower_bound) {\n\t    memcpy(b, laststart+2, mcnt);\n\t    b += mcnt;\n\t  }\n\t  if (skip_stop_paren) BUFPUSH(stop_paren);\n\t  break;\n\t}\n\n\tif (lower_bound < 5 && b - laststart < 10) {\n\t  /* 5 and 10 are the magic numbers */\n\n\t  mcnt = b - laststart;\n\t  GET_BUFFER_SPACE((lower_bound-1)*mcnt);\n\t  while (--lower_bound) {\n\t    memcpy(b, laststart, mcnt);\n\t    b += mcnt;\n\t  }\n\t  if (skip_stop_paren) BUFPUSH(stop_paren);\n\t  break;\n\t}\n\tif (skip_stop_paren) b++; /* push back stop_paren */\n      }\n\n      /* Otherwise, we have a nontrivial interval.  When\n\t we're all done, the pattern will look like:\n\t set_number_at <jump count> <upper bound>\n\t set_number_at <succeed_n count> <lower bound>\n\t succeed_n <after jump addr> <succed_n count>\n\t <body of loop>\n\t jump_n <succeed_n addr> <jump count>\n\t (The upper bound and `jump_n' are omitted if\n\t `upper_bound' is 1, though.)  */\n      { /* If the upper bound is > 1, we need to insert\n\t   more at the end of the loop.  */\n\tunsigned nbytes = upper_bound == 1 ? 10 : 20;\n\n\tGET_BUFFER_SPACE(nbytes);\n\t/* Initialize lower bound of the `succeed_n', even\n\t   though it will be set during matching by its\n\t   attendant `set_number_at' (inserted next),\n\t   because `re_compile_fastmap' needs to know.\n\t   Jump to the `jump_n' we might insert below.  */\n\tinsert_jump_n(succeed_n, laststart, b + (nbytes/2), \n\t\t      b, lower_bound);\n\tb += 5; \t/* Just increment for the succeed_n here.  */\n\n\t/* Code to initialize the lower bound.  Insert \n\t   before the `succeed_n'.  The `5' is the last two\n\t   bytes of this `set_number_at', plus 3 bytes of\n\t   the following `succeed_n'.  */\n\tinsert_op_2(set_number_at, laststart, b, 5, lower_bound);\n\tb += 5;\n\n\tif (upper_bound > 1) {\n\t  /* More than one repetition is allowed, so\n\t     append a backward jump to the `succeed_n'\n\t     that starts this interval.\n\n\t     When we've reached this during matching,\n\t     we'll have matched the interval once, so\n\t     jump back only `upper_bound - 1' times.  */\n\t  GET_BUFFER_SPACE(5);\n\t  store_jump_n(b, greedy?jump_n:finalize_push_n, laststart + 5,\n\t\t       upper_bound - 1);\n\t  b += 5;\n\n\t  /* The location we want to set is the second\n\t     parameter of the `jump_n'; that is `b-2' as\n\t     an absolute address.  `laststart' will be\n\t     the `set_number_at' we're about to insert;\n\t     `laststart+3' the number to set, the source\n\t     for the relative address.  But we are\n\t     inserting into the middle of the pattern --\n\t     so everything is getting moved up by 5.\n\t     Conclusion: (b - 2) - (laststart + 3) + 5,\n\t     i.e., b - laststart.\n\n\t     We insert this at the beginning of the loop\n\t     so that if we fail during matching, we'll\n\t     reinitialize the bounds.  */\n\t  insert_op_2(set_number_at, laststart, b, b - laststart,\n\t\t      upper_bound - 1);\n\t  b += 5;\n\t}\n      }\n      break;\n\n    unfetch_interval:\n      /* If an invalid interval, match the characters as literals.  */\n      re_warning(\"regexp has invalid interval\");\n      p = beg_interval;\n      beg_interval = 0;\n\n      /* normal_char and normal_backslash need `c'.  */\n      PATFETCH(c);\t\n      goto normal_char;\n\n    case '\\\\':\n      if (p == pend)\n\tFREE_AND_RETURN(stackb, \"invalid regular expression; '\\\\' can't be last character\");\n      /* Do not translate the character after the \\, so that we can\n\t distinguish, e.g., \\B from \\b, even if we normally would\n\t translate, e.g., B to b.  */\n      PATFETCH_RAW(c);\n      switch (c) {\n      case 's':\n      case 'S':\n      case 'd':\n      case 'D':\n\twhile (b - bufp->buffer + 9 + (1 << BYTEWIDTH) / BYTEWIDTH\n\t       > bufp->allocated)\n\t  EXTEND_BUFFER;\n\n\tlaststart = b;\n\tif (c == 's' || c == 'd') {\n\t  BUFPUSH(charset);\n\t}\n\telse {\n\t  BUFPUSH(charset_not);\n\t}\n\n\tBUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH);\n\tmemset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2);\n\tif (c == 's' || c == 'S') {\n\t  SET_LIST_BIT(' ');\n\t  SET_LIST_BIT('\\t');\n\t  SET_LIST_BIT('\\n');\n\t  SET_LIST_BIT('\\r');\n\t  SET_LIST_BIT('\\f');\n\t}\n\telse {\n\t  char cc;\n\n\t  for (cc = '0'; cc <= '9'; cc++) {\n\t    SET_LIST_BIT(cc);\n\t  }\n\t}\n\n\twhile ((int)b[-1] > 0 && b[b[-1] - 1] == 0) \n\t  b[-1]--; \n\tif (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH)\n\t  memmove(&b[(unsigned char)b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH],\n\t\t  2 + EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])*8);\n\tb += b[-1] + 2 + EXTRACT_UNSIGNED(&b[(unsigned char)b[-1]])*8;\n\tbreak;\n\n      case 'w':\n\tlaststart = b;\n\tBUFPUSH(wordchar);\n\tbreak;\n\n      case 'W':\n\tlaststart = b;\n\tBUFPUSH(notwordchar);\n\tbreak;\n\n#ifndef RUBY\n      case '<':\n\tBUFPUSH(wordbeg);\n\tbreak;\n\n      case '>':\n\tBUFPUSH(wordend);\n\tbreak;\n#endif\n\n      case 'b':\n\tBUFPUSH(wordbound);\n\tbreak;\n\n      case 'B':\n\tBUFPUSH(notwordbound);\n\tbreak;\n\n      case 'A':\n\tBUFPUSH(begbuf);\n\tbreak;\n\n      case 'Z':\n\tif ((bufp->options & RE_OPTION_SINGLELINE) == 0) {\n\t  BUFPUSH(endbuf2);\n\t  break;\n\t}\n\t/* fall through */\n      case 'z':\n\tBUFPUSH(endbuf);\n\tbreak;\n\n      case 'G':\n\tBUFPUSH(begpos);\n\tbreak;\n\n\t/* hex */\n      case 'x':\n\thad_mbchar = 0;\n\tc = scan_hex(p, 2, &numlen);\n\tif (numlen == 0) goto invalid_escape;\n\tp += numlen;\n\thad_num_literal = 1;\n\tgoto numeric_char;\n\n\t/* octal */\n      case '0':\n\thad_mbchar = 0;\n\tc = scan_oct(p, 2, &numlen);\n\tp += numlen;\n\thad_num_literal = 1;\n\tgoto numeric_char;\n\n\t/* back-ref or octal */\n      case '1': case '2': case '3':\n      case '4': case '5': case '6':\n      case '7': case '8': case '9':\n\tPATUNFETCH;\n\tp0 = p;\n\n\thad_mbchar = 0;\n\tc1 = 0;\n\tGET_UNSIGNED_NUMBER(c1);\n\tif (!ISDIGIT(c)) PATUNFETCH;\n\n\tif (9 < c1 && c1 >= regnum) {\n\t  /* need to get octal */\n\t  c = scan_oct(p0, 3, &numlen) & 0xff;\n\t  p = p0 + numlen;\n\t  c1 = 0;\n\t  had_num_literal = 1;\n\t  goto numeric_char;\n\t}\n\n\tlaststart = b;\n\tBUFPUSH(duplicate);\n\tBUFPUSH(c1);\n\tbreak;\n\n      case 'M':\n      case 'C':\n      case 'c':\n\tp0 = --p;\n\tc = read_special(p, pend, &p0);\n\tif (c > 255) goto invalid_escape;\n\tp = p0;\n\thad_num_literal = 1;\n\tgoto numeric_char;\n\n      default:\n\tc = read_backslash(c);\n\tgoto normal_char;\n      }\n      break;\n\n    case '#':\n      if (options & RE_OPTION_EXTENDED) {\n\twhile (p != pend) {\n\t  PATFETCH(c);\n\t  if (c == '\\n') break;\n\t}\n\tbreak;\n      }\n      goto normal_char;\n\n    case ' ':\n    case '\\t':\n    case '\\f':\n    case '\\r':\n    case '\\n':\n      if (options & RE_OPTION_EXTENDED)\n\tbreak;\n\n    default:\n      if (c == ']')\n        re_warning(\"regexp has `]' without escape\");\n      else if (c == '}')\n        re_warning(\"regexp has `}' without escape\");\n    normal_char:\t\t/* Expects the character in `c'.  */\n      had_mbchar = 0;\n      if (ismbchar(c)) {\n\thad_mbchar = 1;\n\tc1 = p - pattern;\n      }\n    numeric_char:\n      nextp = p + mbclen(c) - 1;\n      if (!pending_exact || pending_exact + *pending_exact + 1 != b\n\t  || *pending_exact >= (c1 ? 0176 : 0177)\n\t  || (nextp < pend &&\n\t      (   *nextp == '+' || *nextp == '?'\n\t       || *nextp == '*' || *nextp == '^'\n\t       || *nextp == '{'))) {\n\tlaststart = b;\n\tBUFPUSH(exactn);\n\tpending_exact = b;\n\tBUFPUSH(0);\n      }\n      if (had_num_literal || c == 0xff) {\n\tBUFPUSH(0xff);\n\t(*pending_exact)++;\n\thad_num_literal = 0;\n      }\n      BUFPUSH(c);\n      (*pending_exact)++;\n      if (had_mbchar) {\n\tint len = mbclen(c) - 1;\n\twhile (len--) {\n\t  PATFETCH_RAW(c);\n\t  BUFPUSH(c);\n\t  (*pending_exact)++;\n\t}\n      }\n    }\n  }\n\n  if (fixup_alt_jump)\n    store_jump(fixup_alt_jump, jump, b);\n\n  if (stackp != stackb)\n    FREE_AND_RETURN(stackb, \"unmatched (\");\n\n  /* set optimize flags */\n  laststart = bufp->buffer;\n  if (laststart != b) {\n    if (*laststart == dummy_failure_jump) laststart += 3;\n    else if (*laststart == try_next) laststart += 3;\n    if (*laststart == anychar_repeat) {\n      bufp->options |= RE_OPTIMIZE_ANCHOR;\n    }\n  }\n\n  bufp->used = b - bufp->buffer;\n  bufp->re_nsub = regnum;\n  laststart = bufp->buffer;\n  if (laststart != b) {\n    if (*laststart == start_memory) laststart += 3;\n    if (*laststart == exactn) {\n      bufp->options |= RE_OPTIMIZE_EXACTN;\n      bufp->must = laststart+1;\n    }\n  }\n  if (!bufp->must) {\n    bufp->must = calculate_must_string(bufp->buffer, b);\n  }\n  if (current_mbctype == MBCTYPE_SJIS) bufp->options |= RE_OPTIMIZE_NO_BM;\n  else if (bufp->must) {\n    int i;\n    int len = (unsigned char)bufp->must[0];\n\n    for (i=1; i<len; i++) {\n      if ((unsigned char)bufp->must[i] == 0xff ||\n\t  (current_mbctype && ismbchar(bufp->must[i]))) {\n\tbufp->options |= RE_OPTIMIZE_NO_BM;\n\tbreak;\n      }\n    }\n    if (!(bufp->options & RE_OPTIMIZE_NO_BM)) {\n      bufp->must_skip = (int *) xmalloc((1 << BYTEWIDTH)*sizeof(int));\n      bm_init_skip(bufp->must_skip, (unsigned char*)bufp->must+1,\n\t\t   (unsigned char)bufp->must[0],\n\t\t   (unsigned char*)(MAY_TRANSLATE()?translate:0));\n    }\n  }\n\n  bufp->regstart = TMALLOC(regnum, unsigned char*);\n  bufp->regend = TMALLOC(regnum, unsigned char*);\n  bufp->old_regstart = TMALLOC(regnum, unsigned char*);\n  bufp->old_regend = TMALLOC(regnum, unsigned char*);\n  bufp->reg_info = TMALLOC(regnum, register_info_type);\n  bufp->best_regstart = TMALLOC(regnum, unsigned char*);\n  bufp->best_regend = TMALLOC(regnum, unsigned char*);\n  FREE_AND_RETURN(stackb, 0);\n\n invalid_pattern:\n  FREE_AND_RETURN(stackb, \"invalid regular expression\");\n\n end_of_pattern:\n  FREE_AND_RETURN(stackb, \"premature end of regular expression\");\n\n too_big:\n  FREE_AND_RETURN(stackb, \"regular expression too big\");\n\n memory_exhausted:\n  FREE_AND_RETURN(stackb, \"memory exhausted\");\n\n nested_meta:\n  FREE_AND_RETURN(stackb, \"nested *?+ in regexp\");\n\n invalid_escape:\n  FREE_AND_RETURN(stackb, \"Invalid escape character syntax\");\n}\n\nvoid\nre_free_pattern(bufp)\n     struct re_pattern_buffer *bufp;\n{\n  xfree(bufp->buffer);\n  xfree(bufp->fastmap);\n  if (bufp->must_skip) xfree(bufp->must_skip);\n\n  xfree(bufp->regstart);\n  xfree(bufp->regend);\n  xfree(bufp->old_regstart);\n  xfree(bufp->old_regend);\n  xfree(bufp->best_regstart);\n  xfree(bufp->best_regend);\n  xfree(bufp->reg_info);\n  xfree(bufp);\n}\n\n/* Store a jump of the form <OPCODE> <relative address>.\n   Store in the location FROM a jump operation to jump to relative\n   address FROM - TO.  OPCODE is the opcode to store.  */\n\nstatic void\nstore_jump(from, opcode, to)\n     char *from, *to;\n     int opcode;\n{\n  from[0] = (char)opcode;\n  STORE_NUMBER(from + 1, to - (from + 3));\n}\n\n\n/* Open up space before char FROM, and insert there a jump to TO.\n   CURRENT_END gives the end of the storage not in use, so we know \n   how much data to copy up. OP is the opcode of the jump to insert.\n\n   If you call this function, you must zero out pending_exact.  */\n\nstatic void\ninsert_jump(op, from, to, current_end)\n     int op;\n     char *from, *to, *current_end;\n{\n  register char *pfrom = current_end;\t\t/* Copy from here...  */\n  register char *pto = current_end + 3;\t\t/* ...to here.  */\n\n  while (pfrom != from)\t\t\t       \n    *--pto = *--pfrom;\n  store_jump(from, op, to);\n}\n\n\n/* Store a jump of the form <opcode> <relative address> <n> .\n\n   Store in the location FROM a jump operation to jump to relative\n   address FROM - TO.  OPCODE is the opcode to store, N is a number the\n   jump uses, say, to decide how many times to jump.\n\n   If you call this function, you must zero out pending_exact.  */\n\nstatic void\nstore_jump_n(from, opcode, to, n)\n     char *from, *to;\n     int opcode;\n     unsigned n;\n{\n  from[0] = (char)opcode;\n  STORE_NUMBER(from + 1, to - (from + 3));\n  STORE_NUMBER(from + 3, n);\n}\n\n\n/* Similar to insert_jump, but handles a jump which needs an extra\n   number to handle minimum and maximum cases.  Open up space at\n   location FROM, and insert there a jump to TO.  CURRENT_END gives the\n   end of the storage in use, so we know how much data to copy up. OP is\n   the opcode of the jump to insert.\n\n   If you call this function, you must zero out pending_exact.  */\n\nstatic void\ninsert_jump_n(op, from, to, current_end, n)\n     int op;\n     char *from, *to, *current_end;\n     unsigned n;\n{\n  register char *pfrom = current_end;\t\t/* Copy from here...  */\n  register char *pto = current_end + 5;\t\t/* ...to here.  */\n\n  while (pfrom != from)\t\t\t       \n    *--pto = *--pfrom;\n  store_jump_n(from, op, to, n);\n}\n\n\n#if 0\n/* Open up space at location THERE, and insert operation OP.\n   CURRENT_END gives the end of the storage in use, so\n   we know how much data to copy up.\n\n   If you call this function, you must zero out pending_exact.  */\n\nstatic void\ninsert_op(op, there, current_end)\n     int op;\n     char *there, *current_end;\n{\n  register char *pfrom = current_end;\t\t/* Copy from here...  */\n  register char *pto = current_end + 1;\t\t/* ...to here.  */\n\n  while (pfrom != there)\t\t\t       \n    *--pto = *--pfrom;\n\n  there[0] = (char)op;\n}\n#endif\n\n\n/* Open up space at location THERE, and insert operation OP followed by\n   NUM_1 and NUM_2.  CURRENT_END gives the end of the storage in use, so\n   we know how much data to copy up.\n\n   If you call this function, you must zero out pending_exact.  */\n\nstatic void\ninsert_op_2(op, there, current_end, num_1, num_2)\n     int op;\n     char *there, *current_end;\n     int num_1, num_2;\n{\n  register char *pfrom = current_end;\t\t/* Copy from here...  */\n  register char *pto = current_end + 5;\t\t/* ...to here.  */\n\n  while (pfrom != there)\t\t\t       \n    *--pto = *--pfrom;\n\n  there[0] = (char)op;\n  STORE_NUMBER(there + 1, num_1);\n  STORE_NUMBER(there + 3, num_2);\n}\n\n\f\n#define trans_eq(c1, c2, translate) (translate?(translate[c1]==translate[c2]):((c1)==(c2)))\nstatic int\nslow_match(little, lend, big, bend, translate)\n     const unsigned char *little, *lend;\n     const unsigned char *big, *bend;\n     const unsigned char *translate;\n{\n  int c;\n\n  while (little < lend && big < bend) {\n    c = *little++;\n    if (c == 0xff)\n      c = *little++;\n    if (!trans_eq(*big++, c, translate)) break;\n  }\n  if (little == lend) return 1;\n  return 0;\n}\n\nstatic int\nslow_search(little, llen, big, blen, translate)\n     const unsigned char *little;\n     int llen;\n     const unsigned char *big;\n     int blen;\n     const char *translate;\n{\n  const unsigned char *bsave = big;\n  const unsigned char *bend = big + blen;\n  register int c;\n  int fescape = 0;\n\n  c = *little;\n  if (c == 0xff) {\n    c = little[1];\n    fescape = 1;\n  }\n  else if (translate && !ismbchar(c)) {\n    c = translate[c];\n  }\n\n  while (big < bend) {\n    /* look for first character */\n    if (fescape) {\n      while (big < bend) {\n\tif (*big == c) break;\n\tbig++;\n      }\n    }\n    else if (translate && !ismbchar(c)) {\n      while (big < bend) {\n\tif (ismbchar(*big)) big+=mbclen(*big)-1;\n\telse if (translate[*big] == c) break;\n\tbig++;\n      }\n    }\n    else {\n      while (big < bend) {\n\tif (*big == c) break;\n\tif (ismbchar(*big)) big+=mbclen(*big)-1;\n\tbig++;\n      }\n    }\n\n    if (slow_match(little, little+llen, big, bend, (unsigned char *)translate))\n      return big - bsave;\n\n    big+=mbclen(*big);\n  }\n  return -1;\n}\n\nstatic void\nbm_init_skip(skip, pat, m, translate)\n     int *skip;\n     unsigned char *pat;\n     int m;\n     const unsigned char *translate;\n{\n  int j, c;\n\n  for (c=0; c<256; c++) {\n    skip[c] = m;\n  }\n  if (translate) {\n    for (j=0; j<m-1; j++) {\n      skip[translate[pat[j]]] = m-1-j;\n    }\n  }\n  else {\n    for (j=0; j<m-1; j++) {\n      skip[pat[j]] = m-1-j;\n    }\n  }\n}\n\nstatic int\nbm_search(little, llen, big, blen, skip, translate)\n     const unsigned char *little;\n     int llen;\n     const unsigned char *big;\n     int blen;\n     int *skip;\n     const unsigned char *translate;\n{\n  int i, j, k;\n\n  i = llen-1;\n  if (translate) {\n    while (i < blen) {\n      k = i;\n      j = llen-1;\n      while (j >= 0 && translate[big[k]] == translate[little[j]]) {\n\tk--;\n\tj--;\n      }\n      if (j < 0) return k+1;\n\n      i += skip[translate[big[i]]];\n    }\n    return -1;\n  }\n  while (i < blen) {\n    k = i;\n    j = llen-1;\n    while (j >= 0 && big[k] == little[j]) {\n      k--;\n      j--;\n    }\n    if (j < 0) return k+1;\n\n    i += skip[big[i]];\n  }\n  return -1;\n}\n\f\n/* Given a pattern, compute a fastmap from it.  The fastmap records\n   which of the (1 << BYTEWIDTH) possible characters can start a string\n   that matches the pattern.  This fastmap is used by re_search to skip\n   quickly over totally implausible text.\n\n   The caller must supply the address of a (1 << BYTEWIDTH)-byte data \n   area as bufp->fastmap.\n   The other components of bufp describe the pattern to be used.  */\nstatic int\nre_compile_fastmap0(bufp)\n     struct re_pattern_buffer *bufp;\n{\n  unsigned char *pattern = (unsigned char*)bufp->buffer;\n  int size = bufp->used;\n  register char *fastmap = bufp->fastmap;\n  register unsigned char *p = pattern;\n  register unsigned char *pend = pattern + size;\n  register int j, k;\n  unsigned is_a_succeed_n;\n\n  \n  unsigned char *stacka[NFAILURES];\n  unsigned char **stackb = stacka;\n  unsigned char **stackp = stackb;\n  unsigned char **stacke = stackb + NFAILURES;\n  int options = bufp->options;\n\n  memset(fastmap, 0, (1 << BYTEWIDTH));\n  bufp->fastmap_accurate = 1;\n  bufp->can_be_null = 0;\n\n  while (p) {\n    is_a_succeed_n = 0;\n    if (p == pend) {\n      bufp->can_be_null = 1;\n      break;\n    }\n#ifdef SWITCH_ENUM_BUG\n    switch ((int)((enum regexpcode)*p++))\n#else\n    switch ((enum regexpcode)*p++)\n#endif\n      {\n      case exactn:\n\tif (p[1] == 0xff) {\n\t  if (TRANSLATE_P())\n\t    fastmap[translate[p[2]]] = 2;\n\t  else\n\t    fastmap[p[2]] = 2;\n\t  bufp->options |= RE_OPTIMIZE_BMATCH;\n\t}\n\telse if (TRANSLATE_P())\n\t  fastmap[translate[p[1]]] = 1;\n\telse\n\t  fastmap[p[1]] = 1;\n\tbreak;\n\n      case begline:\n      case begbuf:\n      case begpos:\n      case endbuf:\n      case endbuf2:\n      case wordbound:\n      case notwordbound:\n      case wordbeg:\n      case wordend:\n      case pop_and_fail:\n      case push_dummy_failure:\n      case start_paren:\n      case stop_paren:\n\tcontinue;\n\n      case casefold_on:\n\tbufp->options |= RE_MAY_IGNORECASE;\n\toptions |= RE_OPTION_IGNORECASE;\n\tcontinue;\n\n      case casefold_off:\n\toptions &= ~RE_OPTION_IGNORECASE;\n\tcontinue;\n\n      case option_set:\n\toptions = *p++;\n\tcontinue;\n\n      case endline:\n\tif (TRANSLATE_P())\n\t  fastmap[translate['\\n']] = 1;\n\telse\n\t  fastmap['\\n'] = 1;\n\tif ((options & RE_OPTION_SINGLELINE) == 0 && bufp->can_be_null == 0)\n\t  bufp->can_be_null = 2;\n\tbreak;\n\n      case jump_n:\n      case finalize_jump:\n      case maybe_finalize_jump:\n      case jump:\n      case jump_past_alt:\n      case dummy_failure_jump:\n      case finalize_push:\n      case finalize_push_n:\n\tEXTRACT_NUMBER_AND_INCR(j, p);\n\tp += j;\t\n\tif (j > 0)\n\t  continue;\n\t/* Jump backward reached implies we just went through\n\t   the body of a loop and matched nothing.\n\t   Opcode jumped to should be an on_failure_jump.\n\t   Just treat it like an ordinary jump.\n\t   For a * loop, it has pushed its failure point already;\n\t   If so, discard that as redundant.  */\n\n\tif ((enum regexpcode)*p != on_failure_jump\n\t    && (enum regexpcode)*p != try_next\n\t    && (enum regexpcode)*p != succeed_n)\n\t  continue;\n\tp++;\n\tEXTRACT_NUMBER_AND_INCR(j, p);\n\tp += j;\t\n\tif (stackp != stackb && *stackp == p)\n\t  stackp--;\t\t/* pop */\n\tcontinue;\n\n      case try_next:\n      case start_nowidth:\n      case stop_nowidth:\n      case stop_backtrack:\n\tp += 2;\n\tcontinue;\n\n      case succeed_n:\n\tis_a_succeed_n = 1;\n\t/* Get to the number of times to succeed.  */\n\tEXTRACT_NUMBER(k, p + 2);\n\t/* Increment p past the n for when k != 0.  */\n\tif (k != 0) {\n\t  p += 4;\n\t  continue;\n\t}\n\t/* fall through */\n\n      case on_failure_jump:\n      EXTRACT_NUMBER_AND_INCR(j, p);\n      if (p + j < pend) {\n\tif (stackp == stacke) {\n\t  EXPAND_FAIL_STACK();\n\t}\n\t*++stackp = p + j;\t/* push */\n      }\n      else {\n\tbufp->can_be_null = 1;\n      }\n      if (is_a_succeed_n)\n\tEXTRACT_NUMBER_AND_INCR(k, p);\t/* Skip the n.  */\n      continue;\n\n      case set_number_at:\n\tp += 4;\n\tcontinue;\n\n      case start_memory:\n      case stop_memory:\n\tp += 2;\n\tcontinue;\n\n      case duplicate:\n\tbufp->can_be_null = 1;\n\tif (*p >= bufp->re_nsub) break;\n\tfastmap['\\n'] = 1;\n      case anychar_repeat:\n      case anychar:\n\tfor (j = 0; j < (1 << BYTEWIDTH); j++) {\n\t  if (j != '\\n' || (options & RE_OPTION_MULTILINE))\n\t    fastmap[j] = 1;\n\t}\n\tif (bufp->can_be_null) {\n\t  FREE_AND_RETURN(stackb, 0);\n\t}\n\t/* Don't return; check the alternative paths\n\t   so we can set can_be_null if appropriate.  */\n\tif ((enum regexpcode)p[-1] == anychar_repeat) {\n\t    continue;\n\t}\n\tbreak;\n\n      case wordchar:\n\tfor (j = 0; j < 0x80; j++) {\n\t  if (SYNTAX(j) == Sword)\n\t    fastmap[j] = 1;\n\t}\n\tswitch (current_mbctype) {\n\tcase MBCTYPE_ASCII:\n\t  for (j = 0x80; j < (1 << BYTEWIDTH); j++) {\n\t    if (SYNTAX(j) == Sword2)\n\t      fastmap[j] = 1;\n\t  }\n\t  break;\n\tcase MBCTYPE_EUC:\n\tcase MBCTYPE_SJIS:\n\tcase MBCTYPE_UTF8:\n\t  for (j = 0x80; j < (1 << BYTEWIDTH); j++) {\n\t    if (re_mbctab[j])\n\t      fastmap[j] = 1;\n\t  }\n\t  break;\n\t}\n\tbreak;\n\n      case notwordchar:\n\tfor (j = 0; j < 0x80; j++)\n\t  if (SYNTAX(j) != Sword)\n\t    fastmap[j] = 1;\n\tswitch (current_mbctype) {\n\tcase MBCTYPE_ASCII:\n\t  for (j = 0x80; j < (1 << BYTEWIDTH); j++) {\n\t    if (SYNTAX(j) != Sword2)\n\t      fastmap[j] = 1;\n\t  }\n\t  break;\n\tcase MBCTYPE_EUC:\n\tcase MBCTYPE_SJIS:\n\tcase MBCTYPE_UTF8:\n\t  for (j = 0x80; j < (1 << BYTEWIDTH); j++) {\n\t    if (!re_mbctab[j])\n\t      fastmap[j] = 1;\n\t  }\n\t  break;\n\t}\n\tbreak;\n\n      case charset:\n\t/* NOTE: Charset for single-byte chars never contain\n\t   multi-byte char.  See set_list_bits().  */\n\tfor (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)\n\t  if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) {\n\t    int tmp = TRANSLATE_P()?translate[j]:j;\n\t    fastmap[tmp] = 1;\n\t  }\n\t{\n\t  unsigned short size;\n\t  unsigned long c, beg, end;\n\n\t  p += p[-1] + 2;\n\t  size = EXTRACT_UNSIGNED(&p[-2]);\n\t  for (j = 0; j < (int)size; j++) {\n\t    c = EXTRACT_MBC(&p[j*8]);\n\t    beg = WC2MBC1ST(c);\n\t    c = EXTRACT_MBC(&p[j*8+4]);\n\t    end = WC2MBC1ST(c);\n\t    /* set bits for 1st bytes of multi-byte chars.  */\n\t    while (beg <= end) {\n\t      /* NOTE: Charset for multi-byte chars might contain\n\t\t single-byte chars.  We must reject them. */\n\t      if (c < 0x100) {\n\t\tfastmap[beg] = 2;\n\t\tbufp->options |= RE_OPTIMIZE_BMATCH;\n\t      }\n\t      else if (ismbchar(beg))\n\t\tfastmap[beg] = 1;\n\t      beg++;\n\t    }\n\t  }\n\t}\n\tbreak;\n\n      case charset_not:\n\t/* S: set of all single-byte chars.\n\t   M: set of all first bytes that can start multi-byte chars.\n\t   s: any set of single-byte chars.\n\t   m: any set of first bytes that can start multi-byte chars.\n\n\t   We assume S+M = U.\n\t   ___      _   _\n\t   s+m = (S*s+M*m).  */\n\t/* Chars beyond end of map must be allowed */\n\t/* NOTE: Charset_not for single-byte chars might contain\n\t   multi-byte chars.  See set_list_bits(). */\n\tfor (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)\n\t  if (!ismbchar(j))\n\t    fastmap[j] = 1;\n\n\tfor (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)\n\t  if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) {\n\t    if (!ismbchar(j))\n\t      fastmap[j] = 1;\n\t  }\n\t{\n\t  unsigned short size;\n\t  unsigned long c, beg;\n\t  int num_literal = 0;\n\n\t  p += p[-1] + 2;\n\t  size = EXTRACT_UNSIGNED(&p[-2]);\n\t  if (size == 0) {\n\t    for (j = 0x80; j < (1 << BYTEWIDTH); j++)\n\t      if (ismbchar(j))\n\t\tfastmap[j] = 1;\n\t    break;\n\t  }\n\t  for (j = 0,c = 0;j < (int)size; j++) {\n\t    unsigned int cc = EXTRACT_MBC(&p[j*8]);\n\t    beg = WC2MBC1ST(cc);\n\t    while (c <= beg) {\n\t      if (ismbchar(c))\n\t\tfastmap[c] = 1;\n\t      c++;\n\t    }\n\n\t    cc = EXTRACT_MBC(&p[j*8+4]);\n\t    if (cc < 0xff) {\n\t      num_literal = 1;\n\t      while (c <= cc) {\n\t\tif (ismbchar(c))\n\t\t  fastmap[c] = 1;\n\t\tc++;\n\t      }\n\t    }\n\t    c = WC2MBC1ST(cc);\n\t  }\n\n\t  for (j = c; j < (1 << BYTEWIDTH); j++) {\n\t    if (num_literal)\n\t      fastmap[j] = 1;\n\t    if (ismbchar(j))\n\t      fastmap[j] = 1;\n\t  }\n\t}\n\tbreak;\n\n      case unused:\t/* pacify gcc -Wall */\n\tbreak;\n      }\n\n    /* Get here means we have successfully found the possible starting\n       characters of one path of the pattern.  We need not follow this\n       path any farther.  Instead, look at the next alternative\n       remembered in the stack.  */\n    if (stackp != stackb)\n      p = *stackp--;\t\t/* pop */\n    else\n      break;\n  }\n  FREE_AND_RETURN(stackb, 0);\n memory_exhausted:\n  FREE_AND_RETURN(stackb, -2);\n}\n\nvoid\nre_compile_fastmap(bufp)\n     struct re_pattern_buffer *bufp;\n{\n  (void)re_compile_fastmap0(bufp);\n}\n\f\n/* adjust startpos value to the position between characters. */\nint\nre_mbc_startpos(string, size, startpos, range)\n     const char *string;\n     int size, startpos, range;\n{\n  int i = mbc_startpos(string, startpos);\n\n  if (i < startpos) {\n    if (range > 0) {\n      startpos = i + mbclen(string[i]);\n    }\n    else {\n      int len = mbclen(string[i]);\n      if (i + len <= startpos)\n\tstartpos = i + len;\n      else\n\tstartpos = i;\n    }\n  }\n  return startpos;\n}\n\nint\nre_adjust_startpos(bufp, string, size, startpos, range)\n     struct re_pattern_buffer *bufp;\n     const char *string;\n     int size, startpos, range;\n{\n  /* Update the fastmap now if not correct already.  */\n  if (!bufp->fastmap_accurate) {\n    int ret = re_compile_fastmap0(bufp);\n    if (ret) return ret;\n  }\n\n  /* Adjust startpos for mbc string */\n  if (current_mbctype && startpos>0 && !(bufp->options&RE_OPTIMIZE_BMATCH)) {\n    startpos = re_mbc_startpos(string, size, startpos, range);\n  }\n  return startpos;\n}\n\f\n\nstatic int re_match_exec _((struct re_pattern_buffer *, const char *, int, int, int,\n\t\t\t    struct re_registers *));\n\n/* Using the compiled pattern in BUFP->buffer, first tries to match\n   STRING, starting first at index STARTPOS, then at STARTPOS + 1, and\n   so on.  RANGE is the number of places to try before giving up.  If\n   RANGE is negative, it searches backwards, i.e., the starting\n   positions tried are STARTPOS, STARTPOS - 1, etc.  STRING is of SIZE.\n   In REGS, return the indices of STRING that matched the entire\n   BUFP->buffer and its contained subexpressions.\n\n   The value returned is the position in the strings at which the match\n   was found, or -1 if no match was found, or -2 if error (such as\n   failure stack overflow).  */\n\nint\nre_search(bufp, string, size, startpos, range, regs)\n     struct re_pattern_buffer *bufp;\n     const char *string;\n     int size, startpos, range;\n     struct re_registers *regs;\n{\n  register char *fastmap = bufp->fastmap;\n  int val, anchor = 0, initpos = startpos;\n\n  /* Check for out-of-range starting position.  */\n  if (startpos < 0  ||  startpos > size)\n    return -1;\n  if (!string) {\n    if (size == 0) string = \"\";\n    else return -1;\n  }\n\n  /* Update the fastmap now if not correct already.  */\n  if (fastmap && !bufp->fastmap_accurate) {\n    int ret = re_compile_fastmap0(bufp);\n    if (ret) return ret;\n  }\n\n\n  /* If the search isn't to be a backwards one, don't waste time in a\n     search for a pattern that must be anchored.  */\n  if (bufp->used > 0) {\n    switch ((enum regexpcode)bufp->buffer[0]) {\n    case begbuf:\n    begbuf_match:\n      if (range > 0) {\n\tif (startpos > 0) return -1;\n\telse {\n\t  val = re_match(bufp, string, size, 0, regs);\n\t  if (val >= 0) return 0;\n\t  return val;\n\t}\n      }\n      break;\n\n    case begline:\n      anchor = 1;\n      break;\n\n    case begpos:\n      val = re_match(bufp, string, size, startpos, regs);\n      if (val >= 0) return startpos;\n      return val;\n\n    default:\n      break;\n    }\n  }\n  if (bufp->options & RE_OPTIMIZE_ANCHOR) {\n    if (bufp->options&RE_OPTION_MULTILINE && range > 0) {\n      goto begbuf_match;\n    }\n    anchor = 1;\n  }\n\n  if (bufp->must) {\n    int len = ((unsigned char*)bufp->must)[0];\n    int pos, pbeg, pend;\n\n    pbeg = startpos;\n    pend = startpos + range;\n    if (pbeg > pend) {\t\t/* swap pbeg,pend */\n      pos = pend; pend = pbeg; pbeg = pos;\n    }\n    pend = size;\n    if (bufp->options & RE_OPTIMIZE_NO_BM) {\n      pos = slow_search((unsigned char *)(bufp->must+1), len,\n\t\t\t(unsigned char*)(string+pbeg), pend-pbeg,\n\t\t\t(char *)(MAY_TRANSLATE()?translate:0));\n    }\n    else {\n      pos = bm_search((unsigned char *)(bufp->must+1), len,\n\t\t      (unsigned char *)(string+pbeg), pend-pbeg,\n\t\t      bufp->must_skip,\n\t\t      MAY_TRANSLATE()?translate:0);\n    }\n    if (pos == -1) return -1;\n    if (range > 0 && (bufp->options & RE_OPTIMIZE_EXACTN)) {\n      startpos += pos;\n      range -= pos;\n      if (range < 0) return -1;\n    }\n  }\n\n  for (;;) {\n    /* If a fastmap is supplied, skip quickly over characters that\n       cannot possibly be the start of a match.  Note, however, that\n       if the pattern can possibly match the null string, we must\n       test it at each starting point so that we take the first null\n       string we get.  */\n\n    if (fastmap && startpos < size\n\t&& bufp->can_be_null != 1 && !(anchor && startpos == 0)) {\n      if (range > 0) {\t/* Searching forwards.  */\n\tregister unsigned char *p, c;\n\tint irange = range;\n\n\tp = (unsigned char*)string+startpos;\n\n\twhile (range > 0) {\n\t  c = *p++;\n\t  if (ismbchar(c)) {\n\t    int len;\n\n\t    if (fastmap[c])\n\t      break;\n\t    len = mbclen(c) - 1;\n\t    while (len--) {\n\t      c = *p++;\n\t      range--;\n\t      if (fastmap[c] == 2)\n\t\tgoto startpos_adjust;\n\t    }\n\t  }\n\t  else {\n\t    if (fastmap[MAY_TRANSLATE() ? translate[c] : c])\n\t      break;\n\t  }\n\t  range--;\n\t}\n      startpos_adjust:\n\tstartpos += irange - range;\n      }\n      else {\t\t\t/* Searching backwards.  */\n\tregister unsigned char c;\n\n\tc = string[startpos];\n\tc &= 0xff;\n\tif (MAY_TRANSLATE() ? !fastmap[translate[c]] : !fastmap[c])\n\t  goto advance;\n      }\n    }\n\n    if (startpos > size) return -1;\n    if ((anchor || !bufp->can_be_null) && range > 0 && size > 0 && startpos == size)\n      return -1;\n    val = re_match_exec(bufp, string, size, startpos, initpos, regs);\n    if (val >= 0) return startpos;\n    if (val == -2) return -2;\n\n#ifndef NO_ALLOCA\n#ifdef C_ALLOCA\n    alloca(0);\n#endif /* C_ALLOCA */\n#endif /* NO_ALLOCA */\n\n    if (range > 0) {\n      if (anchor && startpos < size &&\n\t  (startpos < 1 || string[startpos-1] != '\\n')) {\n\twhile (range > 0 && string[startpos] != '\\n') {\n\t  range--;\n\t  startpos++;\n\t}\n      }\n    }\n\n  advance:\n    if (!range) \n      break;\n    else if (range > 0) {\n      const char *d = string + startpos;\n\n      if (ismbchar(*d)) {\n\tint len = mbclen(*d) - 1;\n\trange-=len, startpos+=len;\n\tif (!range)\n\t  break;\n      }\n      range--, startpos++;\n    }\n    else {\n      range++, startpos--;\n      {\n\tconst char *s, *d, *p;\n\n\ts = string; d = string + startpos;\n\tfor (p = d; p-- > s && ismbchar(*p); )\n\t  /* --p >= s would not work on 80[12]?86. \n\t     (when the offset of s equals 0 other than huge model.)  */\n\t  ;\n\tif (!((d - p) & 1)) {\n\t  if (!range)\n\t    break;\n\t  range++, startpos--;\n\t}\n      }\n    }\n  }\n  return -1;\n}\n\n\n\f\n\n/* The following are used for re_match, defined below:  */\n\n/* Accessing macros used in re_match: */\n\n#define IS_ACTIVE(R)  ((R).bits.is_active)\n#define MATCHED_SOMETHING(R)  ((R).bits.matched_something)\n\n\n/* Macros used by re_match:  */\n\n/* I.e., regstart, regend, and reg_info.  */\n#define NUM_REG_ITEMS  3\n\n/* I.e., ptr and count.  */\n#define NUM_COUNT_ITEMS 2\n\n/* Individual items aside from the registers.  */\n#define NUM_NONREG_ITEMS 4\n\n/* We push at most this many things on the stack whenever we\n   fail.  The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are\n   arguments to the PUSH_FAILURE_POINT macro.  */\n#define MAX_NUM_FAILURE_ITEMS   (num_regs * NUM_REG_ITEMS + NUM_NONREG_ITEMS)\n\n/* We push this many things on the stack whenever we fail.  */\n#define NUM_FAILURE_ITEMS  (last_used_reg * NUM_REG_ITEMS + NUM_NONREG_ITEMS + 1)\n\n/* This pushes counter information for succeed_n and jump_n */\n#define PUSH_FAILURE_COUNT(ptr)\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    int c;\t\t\t\t\t\t\t\t\\\n    EXTRACT_NUMBER(c, ptr);\t\t\t\t\t\t\\\n    ENSURE_FAIL_STACK(NUM_COUNT_ITEMS);\t\t\t\t\t\\\n    *stackp++ = (unsigned char*)(long)c;\t\t\t\t\\\n    *stackp++ = (ptr);\t\t\t\t\t\t\t\\\n    num_failure_counts++;\t\t\t\t\t\t\\\n  } while (0)\n\n/* This pushes most of the information about the current state we will want\n   if we ever fail back to it.  */\n\n#define PUSH_FAILURE_POINT(pattern_place, string_place)\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    long last_used_reg, this_reg;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n    /* Find out how many registers are active or have been matched.\t\\\n       (Aside from register zero, which is only set at the end.) */\t\\\n    for (last_used_reg = num_regs-1; last_used_reg > 0; last_used_reg--)\\\n      if (!REG_UNSET(regstart[last_used_reg]))\t\t\t\t\\\n        break;\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n    ENSURE_FAIL_STACK(NUM_FAILURE_ITEMS);\t\t\t\t\\\n    *stackp++ = (unsigned char*)(long)num_failure_counts;\t\t\\\n    num_failure_counts = 0;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n    /* Now push the info for each of those registers.  */\t\t\\\n    for (this_reg = 1; this_reg <= last_used_reg; this_reg++) {\t\t\\\n      *stackp++ = regstart[this_reg];\t\t\t\t\t\\\n      *stackp++ = regend[this_reg];\t\t\t\t\t\\\n      *stackp++ = reg_info[this_reg].word;\t\t\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n    /* Push how many registers we saved.  */\t\t\t\t\\\n    *stackp++ = (unsigned char*)last_used_reg;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n    *stackp++ = pattern_place;                                          \\\n    *stackp++ = string_place;                                           \\\n    *stackp++ = (unsigned char*)(long)options; /* current option status */\t\\\n    *stackp++ = (unsigned char*)0; /* non-greedy flag */\t\t\\\n  } while(0)\n\n#define NON_GREEDY ((unsigned char*)1)\n\n#define POP_FAILURE_COUNT()\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    unsigned char *ptr = *--stackp;\t\t\t\t\t\\\n    int count = (long)*--stackp;\t\t\t\t\t\\\n    STORE_NUMBER(ptr, count);\t\t\t\t\t\t\\\n  } while (0)\n\n/* This pops what PUSH_FAILURE_POINT pushes.  */\n\n#define POP_FAILURE_POINT()\t\t\t\t\t\t\\\n  do {\t\t\t\t\t\t\t\t\t\\\n    long temp;\t\t\t\t\t\t\t\t\\\n    stackp -= NUM_NONREG_ITEMS;\t/* Remove failure points (and flag). */\t\\\n    temp = (long)*--stackp;\t/* How many regs pushed.  */\t        \\\n    temp *= NUM_REG_ITEMS;\t/* How much to take off the stack.  */\t\\\n    stackp -= temp; \t\t/* Remove the register info.  */\t\\\n    temp = (long)*--stackp;\t/* How many counters pushed.  */\t\\\n    while (temp--) {\t\t\t\t\t\t\t\\\n      POP_FAILURE_COUNT();      /* Remove the counter info.  */\t\t\\\n    }\t\t\t\t\t\t\t\t\t\\\n    num_failure_counts = 0;\t/* Reset num_failure_counts.  */\t\\\n  } while(0)\n\n     /* Registers are set to a sentinel when they haven't yet matched.  */\n#define REG_UNSET_VALUE ((unsigned char*)-1)\n#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)\n\n#define PREFETCH if (d == dend) goto fail\n\n     /* Call this when have matched something; it sets `matched' flags for the\n   registers corresponding to the subexpressions of which we currently\n   are inside.  */\n#define SET_REGS_MATCHED \t\t\t\t\t\t\\\n  do { unsigned this_reg;\t\t\t\t\t\t\\\n    for (this_reg = 0; this_reg < num_regs; this_reg++) { \t\t\\\n        if (IS_ACTIVE(reg_info[this_reg]))\t\t\t\t\\\n          MATCHED_SOMETHING(reg_info[this_reg]) = 1;\t\t\t\\\n        else\t\t\t\t\t\t\t\t\\\n          MATCHED_SOMETHING(reg_info[this_reg]) = 0;\t\t\t\\\n      } \t\t\t\t\t\t\t\t\\\n  } while(0)\n\n#define AT_STRINGS_BEG(d)  ((d) == string)\n#define AT_STRINGS_END(d)  ((d) == dend)\n\n#define IS_A_LETTER(d) (SYNTAX(*(d)) == Sword ||\t\t\t\\\n\t\t\t(current_mbctype ?\t\t\t\t\\\n\t\t\t (re_mbctab[*(d)] && ((d)+mbclen(*(d)))<=dend):\t\\\n\t\t\t SYNTAX(*(d)) == Sword2))\n\n#define PREV_IS_A_LETTER(d) ((current_mbctype == MBCTYPE_SJIS)?\t\t\\\n\t\t\t     IS_A_LETTER((d)-(!AT_STRINGS_BEG((d)-1)&&\t\\\n\t\t\t\t\t      ismbchar((d)[-2])?2:1)):\t\\\n                             ((current_mbctype && ((d)[-1] >= 0x80)) ||\t\\\n\t\t\t      IS_A_LETTER((d)-1)))\n\nstatic void\ninit_regs(regs, num_regs)\n     struct re_registers *regs;\n     unsigned int num_regs;\n{\n  int i;\n\n  regs->num_regs = num_regs;\n  if (num_regs < RE_NREGS)\n    num_regs = RE_NREGS;\n\n  if (regs->allocated == 0) {\n    regs->beg = TMALLOC(num_regs, int);\n    regs->end = TMALLOC(num_regs, int);\n    regs->allocated = num_regs;\n  }\n  else if (regs->allocated < num_regs) {\n    TREALLOC(regs->beg, num_regs, int);\n    TREALLOC(regs->end, num_regs, int);\n    regs->allocated = num_regs;\n  }\n  for (i=0; i<num_regs; i++) {\n    regs->beg[i] = regs->end[i] = -1;\n  }\n}\n\n/* Match the pattern described by BUFP against STRING, which is of\n   SIZE.  Start the match at index POS in STRING.  In REGS, return the\n   indices of STRING that matched the entire BUFP->buffer and its\n   contained subexpressions.\n\n   If bufp->fastmap is nonzero, then it had better be up to date.\n\n   The reason that the data to match are specified as two components\n   which are to be regarded as concatenated is so this function can be\n   used directly on the contents of an Emacs buffer.\n\n   -1 is returned if there is no match.  -2 is returned if there is an\n   error (such as match stack overflow).  Otherwise the value is the\n   length of the substring which was matched.  */\n\nint\nre_match(bufp, string_arg, size, pos, regs)\n     struct re_pattern_buffer *bufp;\n     const char *string_arg;\n     int size, pos;\n     struct re_registers *regs;\n{\n  return re_match_exec(bufp, string_arg, size, pos, pos, regs);\n}\n\nstatic int\nre_match_exec(bufp, string_arg, size, pos, beg, regs)\n     struct re_pattern_buffer *bufp;\n     const char *string_arg;\n     int size, pos, beg;\n     struct re_registers *regs;\n{\n  register unsigned char *p = (unsigned char*)bufp->buffer;\n  unsigned char *p1;\n\n  /* Pointer to beyond end of buffer.  */\n  register unsigned char *pend = p + bufp->used;\n\n  unsigned num_regs = bufp->re_nsub;\n\n  unsigned char *string = (unsigned char*)string_arg;\n\n  register unsigned char *d, *dend;\n  register int mcnt;\t\t\t/* Multipurpose.  */\n  int options = bufp->options;\n\n  /* Failure point stack.  Each place that can handle a failure further\n     down the line pushes a failure point on this stack.  It consists of\n     restart, regend, and reg_info for all registers corresponding to the\n     subexpressions we're currently inside, plus the number of such\n     registers, and, finally, two char *'s.  The first char * is where to\n     resume scanning the pattern; the second one is where to resume\n     scanning the strings.  If the latter is zero, the failure point is a\n     ``dummy''; if a failure happens and the failure point is a dummy, it\n     gets discarded and the next next one is tried.  */\n\n  unsigned char **const stacka = 0;\n  unsigned char **stackb;\n  unsigned char **stackp;\n  unsigned char **stacke;\n\n  /* Information on the contents of registers. These are pointers into\n     the input strings; they record just what was matched (on this\n     attempt) by a subexpression part of the pattern, that is, the\n     regnum-th regstart pointer points to where in the pattern we began\n     matching and the regnum-th regend points to right after where we\n     stopped matching the regnum-th subexpression.  (The zeroth register\n     keeps track of what the whole pattern matches.)  */\n\n  unsigned char **regstart = bufp->regstart;\n  unsigned char **regend = bufp->regend;\n\n  /* If a group that's operated upon by a repetition operator fails to\n     match anything, then the register for its start will need to be\n     restored because it will have been set to wherever in the string we\n     are when we last see its open-group operator.  Similarly for a\n     register's end.  */\n  unsigned char **old_regstart = bufp->old_regstart;\n  unsigned char **old_regend = bufp->old_regend;\n\n  /* The is_active field of reg_info helps us keep track of which (possibly\n     nested) subexpressions we are currently in. The matched_something\n     field of reg_info[reg_num] helps us tell whether or not we have\n     matched any of the pattern so far this time through the reg_num-th\n     subexpression.  These two fields get reset each time through any\n     loop their register is in.  */\n\n  register_info_type *reg_info = bufp->reg_info;\n\n  /* The following record the register info as found in the above\n     variables when we find a match better than any we've seen before. \n     This happens as we backtrack through the failure points, which in\n     turn happens only if we have not yet matched the entire string.  */\n\n  unsigned best_regs_set = 0;\n  unsigned char **best_regstart = bufp->best_regstart;\n  unsigned char **best_regend = bufp->best_regend;\n\n  int num_failure_counts = 0;\n\n  if (regs) {\n    init_regs(regs, num_regs);\n  }\n\n  /* Initialize the stack. */\n  stackb = TMALLOC(MAX_NUM_FAILURE_ITEMS * NFAILURES, unsigned char*);\n  stackp = stackb;\n  stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES];\n\n#ifdef DEBUG_REGEX\n  fprintf(stderr, \"Entering re_match(%s)\\n\", string_arg);\n#endif\n\n  /* Initialize subexpression text positions to -1 to mark ones that no\n     ( or ( and ) or ) has been seen for. Also set all registers to\n     inactive and mark them as not having matched anything or ever\n     failed. */\n  for (mcnt = 0; mcnt < num_regs; mcnt++) {\n    regstart[mcnt] = regend[mcnt]\n      = old_regstart[mcnt] = old_regend[mcnt]\n      = best_regstart[mcnt] = best_regend[mcnt] = REG_UNSET_VALUE;\n#ifdef __CHECKER__\n    reg_info[mcnt].word = 0;\n#endif\n    IS_ACTIVE (reg_info[mcnt]) = 0;\n    MATCHED_SOMETHING (reg_info[mcnt]) = 0;\n  }\n\n  /* Set up pointers to ends of strings.\n     Don't allow the second string to be empty unless both are empty.  */\n\n\n  /* `p' scans through the pattern as `d' scans through the data. `dend'\n     is the end of the input string that `d' points within. `d' is\n     advanced into the following input string whenever necessary, but\n     this happens before fetching; therefore, at the beginning of the\n     loop, `d' can be pointing at the end of a string, but it cannot\n     equal string2.  */\n\n  d = string + pos, dend = string + size;\n\n  /* This loops over pattern commands.  It exits by returning from the\n     function if match is complete, or it drops through if match fails\n     at this starting point in the input data.  */\n\n  for (;;) {\n#ifdef DEBUG_REGEX\n    fprintf(stderr,\n\t    \"regex loop(%d):  matching 0x%02d\\n\",\n\t    p - (unsigned char*)bufp->buffer,\n\t    *p);\n#endif\n    /* End of pattern means we might have succeeded.  */\n    if (p == pend) {\n      /* If not end of string, try backtracking.  Otherwise done.  */\n      if ((bufp->options & RE_OPTION_LONGEST) && d != dend) {\n\tif (best_regs_set) /* non-greedy, no need to backtrack */\n\t  goto restore_best_regs;\n\twhile (stackp != stackb && stackp[-1] == NON_GREEDY) {\n\t  if (best_regs_set) /* non-greedy, no need to backtrack */\n\t    goto restore_best_regs;\n\t  POP_FAILURE_POINT();\n\t}\n\tif (stackp != stackb) {\n\t  /* More failure points to try.  */\n\n\t  /* If exceeds best match so far, save it.  */\n\t  if (! best_regs_set || (d > best_regend[0])) {\n\t    best_regs_set = 1;\n\t    best_regend[0] = d;\t/* Never use regstart[0].  */\n\n\t    for (mcnt = 1; mcnt < num_regs; mcnt++) {\n\t      best_regstart[mcnt] = regstart[mcnt];\n\t      best_regend[mcnt] = regend[mcnt];\n\t    }\n\t  }\n\t  goto fail;\t       \n\t}\n\t/* If no failure points, don't restore garbage.  */\n\telse if (best_regs_set) {\n\trestore_best_regs:\n\t  /* Restore best match.  */\n\t  d = best_regend[0];\n\n\t  for (mcnt = 0; mcnt < num_regs; mcnt++) {\n\t    regstart[mcnt] = best_regstart[mcnt];\n\t    regend[mcnt] = best_regend[mcnt];\n\t  }\n\t}\n      }\n\n      /* If caller wants register contents data back, convert it \n\t to indices.  */\n      if (regs) {\n\tregs->beg[0] = pos;\n\tregs->end[0] = d - string;\n\tfor (mcnt = 1; mcnt < num_regs; mcnt++) {\n\t  if (REG_UNSET(regend[mcnt])) {\n\t    regs->beg[mcnt] = -1;\n\t    regs->end[mcnt] = -1;\n\t    continue;\n\t  }\n\t  regs->beg[mcnt] = regstart[mcnt] - string;\n\t  regs->end[mcnt] = regend[mcnt] - string;\n\t}\n      }\n      FREE_AND_RETURN(stackb, (d - pos - string));\n    }\n\n    /* Otherwise match next pattern command.  */\n#ifdef SWITCH_ENUM_BUG\n    switch ((int)((enum regexpcode)*p++))\n#else\n    switch ((enum regexpcode)*p++)\n#endif\n      {\n\t/* ( [or `(', as appropriate] is represented by start_memory,\n\t   ) by stop_memory.  Both of those commands are followed by\n\t   a register number in the next byte.  The text matched\n\t   within the ( and ) is recorded under that number.  */\n      case start_memory:\n\told_regstart[*p] = regstart[*p];\n\tregstart[*p] = d;\n\tIS_ACTIVE(reg_info[*p]) = 1;\n\tMATCHED_SOMETHING(reg_info[*p]) = 0;\n\tp += 2;\n\tcontinue;\n\n      case stop_memory:\n\told_regend[*p] = regend[*p];\n\tregend[*p] = d;\n\tIS_ACTIVE(reg_info[*p]) = 0;\n\tp += 2;\n\tcontinue;\n\n      case start_paren:\n      case stop_paren:\n\tbreak;\n\n\t/* \\<digit> has been turned into a `duplicate' command which is\n\t   followed by the numeric value of <digit> as the register number.  */\n      case duplicate:\n\t{\n\t  int regno = *p++;   /* Get which register to match against */\n\t  register unsigned char *d2, *dend2;\n\n\t  /* Check if there's corresponding group */\n\t  if (regno >= num_regs) goto fail;\n\t  /* Check if corresponding group is still open */\n\t  if (IS_ACTIVE(reg_info[regno])) goto fail;\n\n\t  /* Where in input to try to start matching.  */\n\t  d2 = regstart[regno];\n\t  if (REG_UNSET(d2)) goto fail;\n\n\t  /* Where to stop matching; if both the place to start and\n\t     the place to stop matching are in the same string, then\n\t     set to the place to stop, otherwise, for now have to use\n\t     the end of the first string.  */\n\n\t  dend2 = regend[regno];\n\t  if (REG_UNSET(dend2)) goto fail;\n\t  for (;;) {\n\t    /* At end of register contents => success */\n\t    if (d2 == dend2) break;\n\n\t    /* If necessary, advance to next segment in data.  */\n\t    PREFETCH;\n\n\t    /* How many characters left in this segment to match.  */\n\t    mcnt = dend - d;\n\n\t    /* Want how many consecutive characters we can match in\n\t       one shot, so, if necessary, adjust the count.  */\n\t    if (mcnt > dend2 - d2)\n\t      mcnt = dend2 - d2;\n\n\t    /* Compare that many; failure if mismatch, else move\n\t       past them.  */\n\t    if ((options & RE_OPTION_IGNORECASE) \n\t\t? memcmp_translate(d, d2, mcnt) \n\t\t: memcmp((char*)d, (char*)d2, mcnt))\n\t      goto fail;\n\t    d += mcnt, d2 += mcnt;\n\t  }\n\t}\n\tbreak;\n\n      case start_nowidth:\n\tPUSH_FAILURE_POINT(0, d);\n\tif (stackp - stackb > RE_DUP_MAX) {\n\t   FREE_AND_RETURN(stackb,(-2));\n\t}\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tSTORE_NUMBER(p+mcnt, stackp - stackb);\n\tcontinue;\n\n      case stop_nowidth:\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tstackp = stackb + mcnt;\n\td = stackp[-3];\n\tPOP_FAILURE_POINT();\n\tcontinue;\n\n      case stop_backtrack:\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tstackp = stackb + mcnt;\n\tPOP_FAILURE_POINT();\n\tcontinue;\n\n      case pop_and_fail:\n\tEXTRACT_NUMBER(mcnt, p+1);\n\tstackp = stackb + mcnt;\n\tPOP_FAILURE_POINT();\n\tgoto fail;\n\n      case anychar:\n\tPREFETCH;\n\tif (ismbchar(*d)) {\n\t  if (d + mbclen(*d) > dend)\n\t    goto fail;\n\t  SET_REGS_MATCHED;\n\t  d += mbclen(*d);\n\t  break;\n\t}\n\tif (!(options&RE_OPTION_MULTILINE)\n\t    && (TRANSLATE_P() ? translate[*d] : *d) == '\\n')\n\t  goto fail;\n\tSET_REGS_MATCHED;\n\td++;\n\tbreak;\n\n      case anychar_repeat:\n\tfor (;;) {\n\t  PUSH_FAILURE_POINT(p, d);\n\t  PREFETCH;\n\t  if (ismbchar(*d)) {\n\t    if (d + mbclen(*d) > dend)\n\t      goto fail;\n\t    SET_REGS_MATCHED;\n\t    d += mbclen(*d);\n\t    continue;\n\t  }\n\t  if (!(options&RE_OPTION_MULTILINE) &&\n\t      (TRANSLATE_P() ? translate[*d] : *d) == '\\n')\n\t    goto fail;\n\t  SET_REGS_MATCHED;\n\t  d++;\n\t}\n\tbreak;\n\n      case charset:\n      case charset_not:\n\t{\n\t  int not;\t    /* Nonzero for charset_not.  */\n\t  int part = 0;\t    /* true if matched part of mbc */\n\t  unsigned char *dsave = d + 1;\n\t  int cc, c;\n\n\t  PREFETCH;\n\t  c = (unsigned char)*d++;\n\t  if (ismbchar(c)) {\n\t    if (d + mbclen(c) - 1 <= dend) {\n\t      cc = c;\n\t      MBC2WC(c, d);\n\t      not = is_in_list_mbc(c, p);\n\t      if (!not) {\n\t\tpart = not = is_in_list_sbc(cc, p);\n\t      }\n\t    } else {\n\t      not = is_in_list(c, p);\n\t    }\n\t  }\n\t  else {\n\t    if (TRANSLATE_P())\n\t      c = (unsigned char)translate[c];\n\t    not = is_in_list(c, p);\n\t  }\n\n\t  if (*(p - 1) == (unsigned char)charset_not) {\n\t    not = !not;\n\t  }\n\t  if (!not) goto fail;\n\n\t  p += 1 + *p + 2 + EXTRACT_UNSIGNED(&p[1 + *p])*8;\n\t  SET_REGS_MATCHED;\n\n\t  if (part) d = dsave;\n\t  break;\n\t}\n\n      case begline:\n\tif (size == 0 || AT_STRINGS_BEG(d))\n\t  break;\n\tif (d[-1] == '\\n' && !AT_STRINGS_END(d))\n\t  break;\n\tgoto fail;\n\n      case endline:\n\tif (AT_STRINGS_END(d)) {\n\t  break;\n\t}\n\telse if (*d == '\\n')\n\t  break;\n\tgoto fail;\n\n\t/* Match at the very beginning of the string. */\n      case begbuf:\n\tif (AT_STRINGS_BEG(d))\n\t  break;\n\tgoto fail;\n\n\t/* Match at the very end of the data. */\n      case endbuf:\n\tif (AT_STRINGS_END(d))\n\t  break;\n\tgoto fail;\n\n\t/* Match at the very end of the data. */\n      case endbuf2:\n\tif (AT_STRINGS_END(d)) {\n\t  break;\n\t}\n\t/* .. or newline just before the end of the data. */\n\tif (*d == '\\n' && AT_STRINGS_END(d+1))\n\t  break;\n\tgoto fail;\n\n\t/* `or' constructs are handled by starting each alternative with\n\t   an on_failure_jump that points to the start of the next\n\t   alternative.  Each alternative except the last ends with a\n\t   jump to the joining point.  (Actually, each jump except for\n\t   the last one really jumps to the following jump, because\n\t   tensioning the jumps is a hassle.)  */\n\n\t/* The start of a stupid repeat has an on_failure_jump that points\n\t   past the end of the repeat text. This makes a failure point so \n\t   that on failure to match a repetition, matching restarts past\n\t   as many repetitions have been found with no way to fail and\n\t   look for another one.  */\n\n\t/* A smart repeat is similar but loops back to the on_failure_jump\n\t   so that each repetition makes another failure point.  */\n\n\t/* Match at the starting position. */\n      case begpos:\n\tif (d - string == beg)\n\t  break;\n\tgoto fail;\n\n      case on_failure_jump:\n      on_failure:\n      EXTRACT_NUMBER_AND_INCR(mcnt, p);\n      PUSH_FAILURE_POINT(p + mcnt, d);\n      continue;\n\n      /* The end of a smart repeat has a maybe_finalize_jump back.\n\t Change it either to a finalize_jump or an ordinary jump.  */\n      case maybe_finalize_jump:\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tp1 = p;\n\n\t/* Compare the beginning of the repeat with what in the\n\t   pattern follows its end. If we can establish that there\n\t   is nothing that they would both match, i.e., that we\n\t   would have to backtrack because of (as in, e.g., `a*a')\n\t   then we can change to finalize_jump, because we'll\n\t   never have to backtrack.\n\n\t   This is not true in the case of alternatives: in\n\t   `(a|ab)*' we do need to backtrack to the `ab' alternative\n\t   (e.g., if the string was `ab').  But instead of trying to\n\t   detect that here, the alternative has put on a dummy\n\t   failure point which is what we will end up popping.  */\n\n\t/* Skip over open/close-group commands.  */\n\twhile (p1 + 2 < pend) {\n\t  if ((enum regexpcode)*p1 == stop_memory ||\n\t      (enum regexpcode)*p1 == start_memory)\n\t    p1 += 3;\t/* Skip over args, too.  */\n\t  else if (/*(enum regexpcode)*p1 == start_paren ||*/\n\t\t   (enum regexpcode)*p1 == stop_paren)\n\t      p1 += 1;\n\t  else\n\t    break;\n\t}\n\n\tif (p1 == pend)\n\t  p[-3] = (unsigned char)finalize_jump;\n\telse if (*p1 == (unsigned char)exactn ||\n\t\t *p1 == (unsigned char)endline) {\n\t  register int c = *p1 == (unsigned char)endline ? '\\n' : p1[2];\n\t  register unsigned char *p2 = p + mcnt;\n\t    /* p2[0] ... p2[2] are an on_failure_jump.\n\t       Examine what follows that.  */\n\t  if (p2[3] == (unsigned char)exactn && p2[5] != c)\n\t    p[-3] = (unsigned char)finalize_jump;\n\t  else if (p2[3] == (unsigned char)charset ||\n\t\t   p2[3] == (unsigned char)charset_not) {\n\t    int not;\n\t    if (ismbchar(c)) {\n\t      unsigned char *pp = p1+3;\n\t      MBC2WC(c, pp);\n\t    }\n\t    /* `is_in_list()' is TRUE if c would match */\n\t    /* That means it is not safe to finalize.  */\n\t    not = is_in_list(c, p2 + 4);\n\t    if (p2[3] == (unsigned char)charset_not)\n\t      not = !not;\n\t    if (!not)\n\t      p[-3] = (unsigned char)finalize_jump;\n\t  }\n\t}\n\tp -= 2;\t\t/* Point at relative address again.  */\n\tif (p[-1] != (unsigned char)finalize_jump) {\n\t  p[-1] = (unsigned char)jump;\t\n\t  goto nofinalize;\n\t}\n\t/* Note fall through.  */\n\n\t/* The end of a stupid repeat has a finalize_jump back to the\n\t   start, where another failure point will be made which will\n\t   point to after all the repetitions found so far.  */\n\n\t/* Take off failure points put on by matching on_failure_jump \n\t   because didn't fail.  Also remove the register information\n\t   put on by the on_failure_jump.  */\n      case finalize_jump:\n\tif (stackp > stackb && stackp[-3] == d) {\n\t  p = stackp[-4];\n\t  POP_FAILURE_POINT();\n\t  continue;\n\t}\n\tPOP_FAILURE_POINT(); \n\t/* Note fall through.  */\n\n      /* We need this opcode so we can detect where alternatives end\n\t in `group_match_null_string_p' et al.  */\n      case jump_past_alt:\n\t/* fall through */\n\n\t/* Jump without taking off any failure points.  */\n      case jump:\n      nofinalize:\n        EXTRACT_NUMBER_AND_INCR(mcnt, p);\n        if (mcnt < 0 && stackp > stackb && stackp[-3] == d) /* avoid infinite loop */\n\t   goto fail;\n        p += mcnt;\n        continue;\n\n      case dummy_failure_jump:\n\t/* Normally, the on_failure_jump pushes a failure point, which\n\t   then gets popped at finalize_jump.  We will end up at\n\t   finalize_jump, also, and with a pattern of, say, `a+', we\n\t   are skipping over the on_failure_jump, so we have to push\n\t   something meaningless for finalize_jump to pop.  */\n\tPUSH_FAILURE_POINT(0, 0);\n\tgoto nofinalize;\n\n\t/* At the end of an alternative, we need to push a dummy failure\n\t   point in case we are followed by a `finalize_jump', because\n\t   we don't want the failure point for the alternative to be\n\t   popped.  For example, matching `(a|ab)*' against `aab'\n\t   requires that we match the `ab' alternative.  */\n      case push_dummy_failure:\n\t/* See comments just above at `dummy_failure_jump' about the\n\t   two zeroes.  */\n\tp1 = p;\n\t/* Skip over open/close-group commands.  */\n\twhile (p1 + 2 < pend) {\n\t  if ((enum regexpcode)*p1 == stop_memory ||\n\t      (enum regexpcode)*p1 == start_memory)\n\t    p1 += 3;\t/* Skip over args, too.  */\n\t  else if (/*(enum regexpcode)*p1 == start_paren ||*/\n\t\t   (enum regexpcode)*p1 == stop_paren)\n\t      p1 += 1;\n\t  else\n\t    break;\n\t}\n\tif (p1 < pend && (enum regexpcode)*p1 == jump)\n\t  p[-1] = unused;\n\telse\n\t  PUSH_FAILURE_POINT(0, 0);\n\tbreak;\n\n\t/* Have to succeed matching what follows at least n times.  Then\n\t   just handle like an on_failure_jump.  */\n      case succeed_n: \n\tEXTRACT_NUMBER(mcnt, p + 2);\n\t/* Originally, this is how many times we HAVE to succeed.  */\n\tif (mcnt != 0) {\n\t  mcnt--;\n\t  p += 2;\n\t  PUSH_FAILURE_COUNT(p);\n\t  STORE_NUMBER_AND_INCR(p, mcnt);\n\t  PUSH_FAILURE_POINT(0, 0);\n\t}\n\telse  {\n\t  goto on_failure;\n\t}\n\tcontinue;\n\n      case jump_n:\n\tEXTRACT_NUMBER(mcnt, p + 2);\n\t/* Originally, this is how many times we CAN jump.  */\n\tif (mcnt) {\n\t  mcnt--;\n\t  PUSH_FAILURE_COUNT(p + 2);\n\t  STORE_NUMBER(p + 2, mcnt);\n\t  goto nofinalize;\t     /* Do the jump without taking off\n\t\t\t\t\tany failure points.  */\n\t}\n\t/* If don't have to jump any more, skip over the rest of command.  */\n\telse      \n\t  p += 4;\t\t     \n\tcontinue;\n\n      case set_number_at:\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tp1 = p + mcnt;\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tSTORE_NUMBER(p1, mcnt);\n\tcontinue;\n\n      case try_next:\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n\tif (p + mcnt < pend) {\n\t  PUSH_FAILURE_POINT(p, d);\n\t  stackp[-1] = NON_GREEDY;\n\t}\n\tp += mcnt;\n\tcontinue;\n\n      case finalize_push:\n\tPOP_FAILURE_POINT();\n\tEXTRACT_NUMBER_AND_INCR(mcnt, p);\n        if (mcnt < 0 && stackp > stackb  && stackp[-3] == d) /* avoid infinite loop */\n\t   goto fail;\n\tPUSH_FAILURE_POINT(p + mcnt, d);\n\tstackp[-1] = NON_GREEDY;\n\tcontinue;\n\n      case finalize_push_n:\n\tEXTRACT_NUMBER(mcnt, p + 2); \n\t/* Originally, this is how many times we CAN jump.  */\n\tif (mcnt) {\n\t  int pos, i;\n\n\t  mcnt--;\n\t  STORE_NUMBER(p + 2, mcnt);\n\t  EXTRACT_NUMBER(pos, p);\n\t  EXTRACT_NUMBER(i, p+pos+5);\n\t  if (i > 0) goto nofinalize;\n\t  POP_FAILURE_POINT();\n\t  EXTRACT_NUMBER_AND_INCR(mcnt, p);\n\t  PUSH_FAILURE_POINT(p + mcnt, d);\n\t  stackp[-1] = NON_GREEDY;\n\t  p += 2;\t\t/* skip n */\n\t}\n\t/* If don't have to push any more, skip over the rest of command.  */\n\telse \n\t  p += 4;   \n\tcontinue;\n\n\t/* Ignore these.  Used to ignore the n of succeed_n's which\n\t   currently have n == 0.  */\n      case unused:\n\tcontinue;\n\n      case casefold_on:\n\toptions |= RE_OPTION_IGNORECASE;\n\tcontinue;\n\n      case casefold_off:\n\toptions &= ~RE_OPTION_IGNORECASE;\n\tcontinue;\n\n      case option_set:\n\toptions = *p++;\n\tcontinue;\n\n      case wordbound:\n\tif (AT_STRINGS_BEG(d)) {\n\t  if (AT_STRINGS_END(d)) goto fail;\n\t  if (IS_A_LETTER(d)) break;\n\t  else goto fail;\n\t}\n\tif (AT_STRINGS_END(d)) {\n\t  if (PREV_IS_A_LETTER(d)) break;\n\t  else goto fail;\n\t}\n\tif (PREV_IS_A_LETTER(d) != IS_A_LETTER(d))\n\t  break;\n\tgoto fail;\n\n      case notwordbound:\n\tif (AT_STRINGS_BEG(d)) {\n\t  if (IS_A_LETTER(d)) goto fail;\n\t  else break;\n\t}\n\tif (AT_STRINGS_END(d)) {\n\t  if (PREV_IS_A_LETTER(d)) goto fail;\n\t  else break;\n\t}\n\tif (PREV_IS_A_LETTER(d) != IS_A_LETTER(d))\n\t  goto fail;\n\tbreak;\n\n      case wordbeg:\n\tif (IS_A_LETTER(d) && (AT_STRINGS_BEG(d) || !PREV_IS_A_LETTER(d)))\n\t  break;\n\tgoto fail;\n\n      case wordend:\n\tif (!AT_STRINGS_BEG(d) && PREV_IS_A_LETTER(d)\n\t    && (!IS_A_LETTER(d) || AT_STRINGS_END(d)))\n\t  break;\n\tgoto fail;\n\n      case wordchar:\n\tPREFETCH;\n\tif (!IS_A_LETTER(d))\n\t  goto fail;\n\tif (ismbchar(*d) && d + mbclen(*d) - 1 < dend)\n\t  d += mbclen(*d) - 1;\n\td++;\n\tSET_REGS_MATCHED;\n\tbreak;\n\n      case notwordchar:\n\tPREFETCH;\n\tif (IS_A_LETTER(d))\n\t  goto fail;\n\tif (ismbchar(*d) && d + mbclen(*d) - 1 < dend)\n\t  d += mbclen(*d) - 1;\n\td++;\n\tSET_REGS_MATCHED;\n\tbreak;\n\n      case exactn:\n\t/* Match the next few pattern characters exactly.\n\t   mcnt is how many characters to match.  */\n\tmcnt = *p++;\n\t/* This is written out as an if-else so we don't waste time\n\t   testing `translate' inside the loop.  */\n\tif (TRANSLATE_P()) {\n\t  do {\n\t    unsigned char c;\n\n\t    PREFETCH;\n\t    if (*p == 0xff) {\n\t      p++;  \n\t      if (!--mcnt\n\t\t  || AT_STRINGS_END(d)\n\t\t  || (unsigned char)*d++ != (unsigned char)*p++)\n\t\tgoto fail;\n\t      continue;\n\t    }\n\t    c = *d++;\n\t    if (ismbchar(c)) {\n\t      int n;\n\n\t      if (c != (unsigned char)*p++)\n\t\tgoto fail;\n\t      for (n = mbclen(c) - 1; n > 0; n--)\n\t\tif (!--mcnt\t/* redundant check if pattern was\n\t\t\t\t   compiled properly. */\n\t\t    || AT_STRINGS_END(d)\n\t\t    || (unsigned char)*d++ != (unsigned char)*p++)\n\t\t  goto fail;\n\t      continue;\n\t    }\n\t    /* compiled code translation needed for ruby */\n\t    if ((unsigned char)translate[c] != (unsigned char)translate[*p++])\n\t      goto fail;\n\t  }\n\t  while (--mcnt);\n\t}\n\telse {\n\t  do {\n\t    PREFETCH;\n\t    if (*p == 0xff) {p++; mcnt--;}\n\t    if (*d++ != *p++) goto fail;\n\t  }\n\t  while (--mcnt);\n\t}\n\tSET_REGS_MATCHED;\n\tbreak;\n      }\n#ifdef RUBY\n    CHECK_INTS;\n#endif\n    continue;  /* Successfully executed one pattern command; keep going.  */\n\n    /* Jump here if any matching operation fails. */\n  fail:\n    if (stackp != stackb) {\n      /* A restart point is known.  Restart there and pop it. */\n      short last_used_reg, this_reg;\n\n      /* If this failure point is from a dummy_failure_point, just\n\t skip it.  */\n      if (stackp[-4] == 0 || (best_regs_set && stackp[-1] == NON_GREEDY)) {\n\tPOP_FAILURE_POINT();\n\tgoto fail;\n      }\n      stackp--;\t\t/* discard greedy flag */\n      options = (long)*--stackp;\n      d = *--stackp;\n      p = *--stackp;\n      /* Restore register info.  */\n      last_used_reg = (long)*--stackp;\n\n      /* Make the ones that weren't saved -1 or 0 again. */\n      for (this_reg = num_regs - 1; this_reg > last_used_reg; this_reg--) {\n\tregend[this_reg] = REG_UNSET_VALUE;\n\tregstart[this_reg] = REG_UNSET_VALUE;\n\tIS_ACTIVE(reg_info[this_reg]) = 0;\n\tMATCHED_SOMETHING(reg_info[this_reg]) = 0;\n      }\n\n      /* And restore the rest from the stack.  */\n      for ( ; this_reg > 0; this_reg--) {\n\treg_info[this_reg].word = *--stackp;\n\tregend[this_reg] = *--stackp;\n\tregstart[this_reg] = *--stackp;\n      }\n      mcnt = (long)*--stackp;\n      while (mcnt--) {\n\tPOP_FAILURE_COUNT();\n      }\n      if (p < pend) {\n\tint is_a_jump_n = 0;\n\tint failed_paren = 0;\n\n\tp1 = p;\n\t/* If failed to a backwards jump that's part of a repetition\n\t   loop, need to pop this failure point and use the next one.  */\n\tswitch ((enum regexpcode)*p1) {\n\tcase jump_n:\n\tcase finalize_push_n:\n\t  is_a_jump_n = 1;\n\tcase maybe_finalize_jump:\n\tcase finalize_jump:\n\tcase finalize_push:\n\tcase jump:\n\t  p1++;\n\t  EXTRACT_NUMBER_AND_INCR(mcnt, p1);\n\n\t  if (mcnt >= 0) break;\t/* should be backward jump */\n\t  p1 += mcnt;\n\n\t  if (( is_a_jump_n && (enum regexpcode)*p1 == succeed_n) ||\n\t      (!is_a_jump_n && (enum regexpcode)*p1 == on_failure_jump)) {\n\t    if (failed_paren) {\n\t      p1++;\n\t      EXTRACT_NUMBER_AND_INCR(mcnt, p1);\n\t      PUSH_FAILURE_POINT(p1 + mcnt, d);\n\t    }\n\t    goto fail;\n\t  }\n\t  break;\n\tdefault:\n\t  /* do nothing */;\n\t}\n      }\n    }\n    else\n      break;   /* Matching at this starting point really fails.  */\n  }\n\n  if (best_regs_set)\n    goto restore_best_regs;\n\n  FREE_AND_RETURN(stackb,(-1)); \t/* Failure to match.  */\n memory_exhausted:\n  FREE_AND_RETURN(stackb,(-2));\n}\n\n\nstatic int\nmemcmp_translate(s1, s2, len)\n     unsigned char *s1, *s2;\n     register int len;\n{\n  register unsigned char *p1 = s1, *p2 = s2, c;\n  while (len) {\n    c = *p1++;\n    if (ismbchar(c)) {\n      int n;\n\n      if (c != *p2++) return 1;\n      for (n = mbclen(c) - 1; n > 0; n--)\n\tif (!--len || *p1++ != *p2++)\n\t  return 1;\n    }\n    else\n      if (translate[c] != translate[*p2++])\n\treturn 1;\n    len--;\n  }\n  return 0;\n}\n\nvoid\nre_copy_registers(regs1, regs2)\n     struct re_registers *regs1, *regs2;\n{\n  int i;\n\n  if (regs1 == regs2) return;\n  if (regs1->allocated == 0) {\n    regs1->beg = TMALLOC(regs2->num_regs, int);\n    regs1->end = TMALLOC(regs2->num_regs, int);\n    regs1->allocated = regs2->num_regs;\n  }\n  else if (regs1->allocated < regs2->num_regs) {\n    TREALLOC(regs1->beg, regs2->num_regs, int);\n    TREALLOC(regs1->end, regs2->num_regs, int);\n    regs1->allocated = regs2->num_regs;\n  }\n  for (i=0; i<regs2->num_regs; i++) {\n    regs1->beg[i] = regs2->beg[i];\n    regs1->end[i] = regs2->end[i];\n  }\n  regs1->num_regs = regs2->num_regs;\n}\n\nvoid\nre_free_registers(regs)\n     struct re_registers *regs;\n{\n  if (regs->allocated == 0) return;\n  if (regs->beg) xfree(regs->beg);\n  if (regs->end) xfree(regs->end);\n}\n\n/* Functions for multi-byte support.\n   Created for grep multi-byte extension Jul., 1993 by t^2 (Takahiro Tanimoto)\n   Last change: Jul. 9, 1993 by t^2  */\nstatic const unsigned char mbctab_ascii[] = {\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nstatic const unsigned char mbctab_euc[] = { /* 0xA1-0xFE */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,\n};\n\nstatic const unsigned char mbctab_sjis[] = { /* 0x81-0x9F,0xE0-0xFC */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0\n};\n\nstatic const unsigned char mbctab_sjis_trail[] = { /* 0x40-0x7E,0x80-0xFC */\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0\n};\n\nstatic const unsigned char mbctab_utf8[] = {\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n  3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 0, 0,\n};\n\nconst unsigned char *re_mbctab = mbctab_ascii;\n\nvoid\nre_mbcinit(mbctype)\n     int mbctype;\n{\n  switch (mbctype) {\n  case MBCTYPE_ASCII:\n    re_mbctab = mbctab_ascii;\n    current_mbctype = MBCTYPE_ASCII;\n    break;\n  case MBCTYPE_EUC:\n    re_mbctab = mbctab_euc;\n    current_mbctype = MBCTYPE_EUC;\n    break;\n  case MBCTYPE_SJIS:\n    re_mbctab = mbctab_sjis;\n    current_mbctype = MBCTYPE_SJIS;\n    break;\n  case MBCTYPE_UTF8:\n    re_mbctab = mbctab_utf8;\n    current_mbctype = MBCTYPE_UTF8;\n    break;\n  }\n}\n\n#define mbc_isfirst(t, c) (t)[(unsigned char)(c)]\n#define mbc_len(t, c)     ((t)[(unsigned char)(c)]+1)\n\nstatic unsigned int\nasc_startpos(string, pos)\n     const char *string;\n     unsigned int pos;\n{\n  return pos;\n}\n\n#define euc_islead(c)  ((unsigned char)((c) - 0xa1) > 0xfe - 0xa1)\n#define euc_mbclen(c)  mbc_len(mbctab_euc, (c))\nstatic unsigned int\neuc_startpos(string, pos)\n     const char *string;\n     unsigned int pos;\n{\n  unsigned int i = pos, w;\n\n  while (i > 0 && !euc_islead(string[i])) {\n    --i;\n  }\n  if (i == pos || i + (w = euc_mbclen(string[i])) > pos) {\n    return i;\n  }\n  i += w;\n  return i + ((pos - i) & ~1);\n}\n\n#define sjis_isfirst(c) mbc_isfirst(mbctab_sjis, (c))\n#define sjis_istrail(c) mbctab_sjis_trail[(unsigned char)(c)]\n#define sjis_mbclen(c)  mbc_len(mbctab_sjis, (c))\nstatic unsigned int\nsjis_startpos(string, pos)\n     const char *string;\n     unsigned int pos;\n{\n  unsigned int i = pos, w;\n\n  if (i > 0 && sjis_istrail(string[i])) {\n    do {\n      if (!sjis_isfirst(string[--i])) {\n\t++i;\n\tbreak;\n      }\n    } while (i > 0);\n  }\n  if (i == pos || i + (w = sjis_mbclen(string[i])) > pos) {\n    return i;\n  }\n  i += w;\n  return i + ((pos - i) & ~1);\n}\n\n#define utf8_islead(c)  ((unsigned char)((c) & 0xc0) != 0x80)\n#define utf8_mbclen(c)  mbc_len(mbctab_utf8, (c))\nstatic unsigned int\nutf8_startpos(string, pos)\n     const char *string;\n     unsigned int pos;\n{\n  unsigned int i = pos, w;\n\n  while (i > 0 && !utf8_islead(string[i])) {\n    --i;\n  }\n  if (i == pos || i + (w = utf8_mbclen(string[i])) > pos) {\n    return i;\n  }\n  return i + w;\n}\n\n/*\n  vi: sw=2 ts=8\n  Local variables:\n  mode\t\t : C\n  c-file-style\t : \"gnu\"\n  tab-width\t : 8\n  End\n*/\n"
  },
  {
    "path": "regex.h",
    "content": "/* Definitions for data structures and routines for the regular\n   expression library, version 0.12.\n   Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc.\n\n   This file is part of the GNU C Library.  Its master source is NOT part of\n   the C library, however.  The master source lives in /gd/gnu/lib.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Library General Public License as\n   published by the Free Software Foundation; either version 2 of the\n   License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Library General Public License for more details.\n\n   You should have received a copy of the GNU Library General Public\n   License along with the GNU C Library; see the file LGPL.  If not,\n   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n   Boston, MA 02111-1307, USA.  */\n/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)\n   Last change: May 21, 1993 by t^2  */\n/* modified for Ruby by matz@netlab.co.jp */\n\n#ifndef REGEX_H\n#define REGEX_H\n\n/* symbol mangling for ruby */\n#ifdef RUBY\n# define re_adjust_startpos ruby_re_adjust_startpos\n# define re_compile_fastmap ruby_re_compile_fastmap\n# define re_compile_pattern ruby_re_compile_pattern\n# define re_copy_registers ruby_re_copy_registers\n# define re_free_pattern ruby_re_free_pattern\n# define re_free_registers ruby_re_free_registers\n# define re_match ruby_re_match\n# define re_mbcinit ruby_re_mbcinit\n# define re_search ruby_re_search\n# define re_set_casetable ruby_re_set_casetable\n# define register_info_type ruby_register_info_type\n#endif\n\n#include <stddef.h>\n\n/* Define number of parens for which we record the beginnings and ends.\n   This affects how much space the `struct re_registers' type takes up.  */\n#ifndef RE_NREGS\n#define RE_NREGS 10\n#endif\n\n#define BYTEWIDTH 8\n\n#define RE_REG_MAX ((1<<BYTEWIDTH)-1)\n\n/* Maximum number of duplicates an interval can allow.  */\n#ifndef RE_DUP_MAX\n#define RE_DUP_MAX  ((1 << 15) - 1) \n#endif\n\n\n/* If this bit is set, then character classes are supported; they are:\n     [:alpha:],\t[:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],\n     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].\n   If not set, then character classes are not supported.  */\n#define RE_CHAR_CLASSES (1L << 9)\n\n/* match will be done case insensetively */\n#define RE_OPTION_IGNORECASE (1L)\n/* perl-style extended pattern available */\n#define RE_OPTION_EXTENDED   (RE_OPTION_IGNORECASE<<1)\n/* newline will be included for . */\n#define RE_OPTION_MULTILINE  (RE_OPTION_EXTENDED<<1)\n/* ^ and $ ignore newline */\n#define RE_OPTION_SINGLELINE (RE_OPTION_MULTILINE<<1)\n/* search for longest match, in accord with POSIX regexp */\n#define RE_OPTION_LONGEST    (RE_OPTION_SINGLELINE<<1)\n\n#define RE_MAY_IGNORECASE    (RE_OPTION_LONGEST<<1)\n#define RE_OPTIMIZE_ANCHOR   (RE_MAY_IGNORECASE<<1)\n#define RE_OPTIMIZE_EXACTN   (RE_OPTIMIZE_ANCHOR<<1)\n#define RE_OPTIMIZE_NO_BM    (RE_OPTIMIZE_EXACTN<<1)\n#define RE_OPTIMIZE_BMATCH   (RE_OPTIMIZE_NO_BM<<1)\n\n/* For multi-byte char support */\n#define MBCTYPE_ASCII 0\n#define MBCTYPE_EUC 1\n#define MBCTYPE_SJIS 2\n#define MBCTYPE_UTF8 3\n\nextern\n#if defined _WIN32 && !defined __GNUC__ && !defined RUBY_EXPORT\n__declspec(dllimport)\n# endif\nconst unsigned char *re_mbctab;\n#if defined(__STDC__)\nvoid re_mbcinit (int);\n#else\nvoid re_mbcinit ();\n#endif\n\n#undef ismbchar\n#define ismbchar(c) re_mbctab[(unsigned char)(c)]\n#define mbclen(c)   (re_mbctab[(unsigned char)(c)]+1)\n\n/* Structure used in re_match() */\n\ntypedef union\n{\n  unsigned char *word;\n  struct {\n    unsigned is_active : 1;\n    unsigned matched_something : 1;\n  } bits;\n} register_info_type;\n\n/* This data structure is used to represent a compiled pattern.  */\n\nstruct re_pattern_buffer\n  {\n    char *buffer;\t/* Space holding the compiled pattern commands.  */\n    int allocated;\t/* Size of space that `buffer' points to. */\n    int used;\t\t/* Length of portion of buffer actually occupied  */\n    char *fastmap;\t/* Pointer to fastmap, if any, or zero if none.  */\n\t\t\t/* re_search uses the fastmap, if there is one,\n\t\t\t   to skip over totally implausible characters.  */\n    char *must;\t        /* Pointer to exact pattern which strings should have\n\t\t\t   to be matched.  */\n    int *must_skip;     /* Pointer to exact pattern skip table for bm_search */\n    long options;\t/* Flags for options such as extended_pattern. */\n    long re_nsub;\t/* Number of subexpressions found by the compiler. */\n    char fastmap_accurate;\n\t\t\t/* Set to zero when a new pattern is stored,\n\t\t\t   set to one when the fastmap is updated from it.  */\n    char can_be_null;   /* Set to one by compiling fastmap\n\t\t\t   if this pattern might match the null string.\n\t\t\t   It does not necessarily match the null string\n\t\t\t   in that case, but if this is zero, it cannot.\n\t\t\t   2 as value means can match null string\n\t\t\t   but at end of range or before a character\n\t\t\t   listed in the fastmap.  */\n\n    /* stack & working area for re_match() */\n    unsigned char **regstart;\n    unsigned char **regend;\n    unsigned char **old_regstart;\n    unsigned char **old_regend;\n    register_info_type *reg_info;\n    unsigned char **best_regstart;\n    unsigned char **best_regend;\n  };\n\ntypedef struct re_pattern_buffer regex_t;\n\n/* Structure to store register contents data in.\n\n   Pass the address of such a structure as an argument to re_match, etc.,\n   if you want this information back.\n\n   For i from 1 to RE_NREGS - 1, start[i] records the starting index in\n   the string of where the ith subexpression matched, and end[i] records\n   one after the ending index.  start[0] and end[0] are analogous, for\n   the entire pattern.  */\n\nstruct re_registers\n  {\n    int allocated;\n    int num_regs;\n    int *beg;\n    int *end;\n  };\n\n/* Type for byte offsets within the string.  POSIX mandates this.  */\ntypedef size_t regoff_t;\n\n/* POSIX specification for registers.  Aside from the different names than\n   `re_registers', POSIX uses an array of structures, instead of a\n   structure of arrays.  */\ntypedef struct\n{\n  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */\n  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */\n} regmatch_t;\n\n#ifdef __STDC__\n\nextern const char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);\nvoid re_free_pattern (struct re_pattern_buffer *);\n/* Is this really advertised?  */\nextern int re_adjust_startpos (struct re_pattern_buffer *, const char*, int, int, int);\nextern void re_compile_fastmap (struct re_pattern_buffer *);\nextern int re_search (struct re_pattern_buffer *, const char*, int, int, int,\n\t\t      struct re_registers *);\nextern int re_match (struct re_pattern_buffer *, const char *, int, int,\n\t\t     struct re_registers *);\nextern void re_set_casetable (const char *table);\nextern void re_copy_registers (struct re_registers*, struct re_registers*);\nextern void re_free_registers (struct re_registers*);\n\n#ifndef RUBY\n/* 4.2 bsd compatibility.  */\nextern char *re_comp (const char *);\nextern int re_exec (const char *);\n#endif\n\n#else /* !__STDC__ */\n\nextern const char *re_compile_pattern ();\nvoid re_free_regexp ();\n/* Is this really advertised? */\nextern int re_adjust_startpos ();\nextern void re_compile_fastmap ();\nextern int re_search ();\nextern int re_match ();\nextern void re_set_casetable ();\nextern void re_copy_registers ();\nextern void re_free_registers ();\n\n#endif /* __STDC__ */\n\n#endif /* !REGEX_H */\n"
  },
  {
    "path": "ruby.1",
    "content": ".\\\"Ruby is copyrighted by Yukihiro Matsumoto <matz@netlab.jp>.\n.Dd December 31, 2002\n.Dt RUBY(1) \"\" \"Ruby Programmers Reference Guide\"\n.\\\".Dt RUBY 1\n.Os UNIX\n.Sh NAME\n.Nm ruby\n.Nd Interpreted object-oriented scripting language\n.Sh SYNOPSIS\n.Nm\n.Op Fl -copyright\n.Op Fl -version\n.Op Fl Sacdlnpswvy\n.Op Fl 0 Ns Op Ar octal\n.Op Fl C Ar directory\n.Op Fl F Ar pattern\n.Op Fl I Ar directory\n.Op Fl K Ar c\n.Op Fl T Ns Op Ar level\n.Op Fl e Ar command\n.Op Fl i Ns Op Ar extension\n.Op Fl r Ar library\n.Op Fl x Ns Op Ar directory\n.Op Fl -\n.Op Ar program_file\n.Op Ar argument ...\n.Sh DESCRIPTION\nRuby is an interpreted scripting language for quick and easy\nobject-oriented programming.  It has many features to process text\nfiles and to do system management tasks (as in Perl).  It is simple,\nstraight-forward, and extensible.\n.Pp\nIf you want a language for easy object-oriented programming, or you\ndon't like the Perl ugliness, or you do like the concept of LISP, but\ndon't like too much parentheses, Ruby may be the language of your\nchoice.\n.Sh FEATURES\nRuby's features are as follows:\n.Bl -tag -width 6n\n.It Sy \"Interpretive\"\nRuby is an interpreted language, so you don't have to recompile\nprograms written in Ruby to execute them.\n.Pp\n.It Sy \"Variables have no type (dynamic typing)\"\nVariables in Ruby can contain data of any type.  You don't have to\nworry about variable typing.  Consequently, it has a weaker compile\ntime check.\n.Pp\n.It Sy \"No declaration needed\"\nYou can use variables in your Ruby programs without any declarations.\nVariable names denote their scope, local, global, instance, etc.\n.Pp\n.It Sy \"Simple syntax\"\nRuby has a simple syntax influenced slightly from Eiffel.\n.Pp\n.It Sy \"No user-level memory management\"\nRuby has automatic memory management.  Objects no longer referenced\nfrom anywhere are automatically collected by the garbage collector\nbuilt into the interpreter.\n.Pp\n.It Sy \"Everything is an object\"\nRuby is the purely object-oriented language, and was so since its\ncreation.  Even such basic data as integers are seen as objects.\n.Pp\n.It Sy \"Class, inheritance, and methods\"\nOf course, as an object-oriented language, Ruby has such basic\nfeatures like classes, inheritance, and methods.\n.Pp\n.It Sy \"Singleton methods\"\nRuby has the ability to define methods for certain objects.  For\nexample, you can define a press-button action for certain widget by\ndefining a singleton method for the button.  Or, you can make up your\nown prototype based object system using singleton methods, if you want\nto.\n.Pp\n.It Sy \"Mix-in by modules\"\nRuby intentionally does not have the multiple inheritance as it is a\nsource of confusion.  Instead, Ruby has the ability to share\nimplementations across the inheritance tree.  This is often called\n.Sq Mix-in .\n.Pp\n.It Sy \"Iterators\"\nRuby has iterators for loop abstraction.\n.Pp\n.It Sy \"Closures\"\nIn Ruby, you can objectify the procedure.\n.Pp\n.It Sy \"Text processing and regular expression\"\nRuby has a bunch of text processing features like in Perl.\n.Pp\n.It Sy \"Bignums\"\nWith built-in bignums, you can for example calculate factorial(400).\n.Pp\n.It Sy \"Exception handling\"\nAs in Java(tm).\n.Pp\n.It Sy \"Direct access to the OS\"\nRuby can use most\n.Ux\nsystem calls, often used in system programming.\n.Pp\n.It Sy \"Dynamic loading\"\nOn most\n.Ux\nsystems, you can load object files into the Ruby interpreter\non-the-fly.\n.El\n.Pp\n.Sh OPTIONS\nRuby interpreter accepts following command-line options (switches).\nThey are quite similar to those of\n.Xr perl 1 .\n.Bl -tag -width \"1234567890123\" -compact\n.Pp\n.It Fl -copyright\nPrints the copyright notice.\n.Pp\n.It Fl -version\nPrints the version of Ruby interpreter.\n.Pp\n.It Fl 0 Ns Op Ar octal\n(The digit\n.Dq zero . )\nSpecifies the input record separator\n.Pf ( Li \"$/\" )\nas an octal number. If no digit is given, the null character is taken\nas the separator.  Other switches may follow the digits.\n.Fl 00\nturns Ruby into paragraph mode.\n.Fl 0777\nmakes Ruby read whole file at once as a single string since there is\nno legal character with that value.\n.Pp\n.It Fl C Ar directory\nCauses Ruby to switch to the directory.\n.Pp\n.It Fl F Ar pattern\nSpecifies input field separator\n.Pf ( Li \"$;\" ) .\n.Pp\n.It Fl I Ar directory\nUsed to tell Ruby where to load the library scripts.  Directory path\nwill be added to the load-path variable\n.Pf ( Li \"$:\" ) .\n.Pp\n.It Fl K Ar kcode\nSpecifies KANJI (Japanese) encoding.\n.Pp\n.It Fl S\nMakes Ruby use the\n.Ev PATH\nenvironment variable to search for script, unless if its name begins\nwith a slash.  This is used to emulate\n.Li #!\non machines that don't support it, in the following manner:\n.Bd -literal -offset indent\n#! /usr/local/bin/ruby\n# This line makes the next one a comment in Ruby \\e\n  exec /usr/local/bin/ruby -S $0 $*\n.Ed\n.Pp\n.It Fl T Ns Op Ar level\nTurns on taint checks at the specified level (default 1).\n.Pp\n.It Fl a\nTurns on auto-split mode when used with\n.Fl n\nor\n.Fl p .\nIn auto-split mode, Ruby executes\n.Dl $F = $_.split\nat beginning of each loop.\n.Pp\n.It Fl c\nCauses Ruby to check the syntax of the script and exit without\nexecuting. If there are no syntax errors, Ruby will print\n.Dq Syntax OK\nto the standard output.\n.Pp\n.It Fl d\n.It Fl -debug\nTurns on debug mode.\n.Li \"$DEBUG\"\nwill be set to true.\n.Pp\n.It Fl e Ar command\nSpecifies script from command-line while telling Ruby not to search\nthe rest of arguments for a script file name.\n.Pp\n.It Fl h\n.It Fl -help\nPrints a summary of the options.\n.Pp\n.It Fl i Ar extension\nSpecifies in-place-edit mode.  The extension, if specified, is added\nto old file name to make a backup copy.  For example:\n.Bd -literal -offset indent\n% echo matz > /tmp/junk\n% cat /tmp/junk\nmatz\n% ruby -p -i.bak -e '$_.upcase!' /tmp/junk\n% cat /tmp/junk\nMATZ\n% cat /tmp/junk.bak\nmatz\n.Ed\n.Pp\n.It Fl l\n(The lowercase letter\n.Dq ell . )\nEnables automatic line-ending processing, which means to firstly set\n.Li \"$\\e\"\nto the value of\n.Li \"$/\" ,\nand secondly chops every line read using\n.Li chop! .\n.Pp\n.It Fl n\nCauses Ruby to assume the following loop around your script, which\nmakes it iterate over file name arguments somewhat like\n.Nm sed\n.Fl n\nor\n.Nm awk .\n.Bd -literal -offset indent\nwhile gets\n  ...\nend\n.Ed\n.Pp\n.It Fl p\nActs mostly same as -n switch, but print the value of variable\n.Li \"$_\"\nat the each end of the loop.  For example:\n.Bd -literal -offset indent\n% echo matz | ruby -p -e '$_.tr! \"a-z\", \"A-Z\"'\nMATZ\n.Ed\n.Pp\n.It Fl r Ar library\nCauses Ruby to load the library using require.  It is useful when using\n.Fl n\nor\n.Fl p .\n.Pp\n.It Fl s\nEnables some switch parsing for switches after script name but before\nany file name arguments (or before a\n.Fl - ) .\nAny switches found there are removed from\n.Li ARGV\nand set the corresponding variable in the script.  For example:\n.Bd -literal -offset indent\n#! /usr/local/bin/ruby -s\n# prints \"true\" if invoked with `-xyz' switch.\nprint \"true\\en\" if $xyz\n.Ed\n.Pp\nOn some systems\n.Li \"$0\"\ndoes not always contain the full pathname, so you need the\n.Fl S\nswitch to tell Ruby to search for the script if necessary.  To handle\nembedded spaces or such.  A better construct than\n.Li \"$*\"\nwould be\n.Li ${1+\"$@\"} ,\nbut it does not work if the script is being interpreted by\n.Xr csh 1 .\n.Pp\n.It Fl v\n.It Fl -verbose\nEnables verbose mode.  Ruby will print its version at the beginning,\nand set the variable\n.Li \"$VERBOSE\"\nto true.  Some methods print extra messages if this variable is true.\nIf this switch is given, and no other switches are present, Ruby quits\nafter printing its version.\n.Pp\n.It Fl w\nEnables verbose mode without printing version message at the\nbeginning.  It sets the\n.Li \"$VERBOSE\"\nvariable to true.\n.Pp\n.It Fl x Ns Op Ar directory\nTells Ruby that the script is embedded in a message.  Leading garbage\nwill be discarded until the first that starts with\n.Dq #!\nand contains the string,\n.Dq ruby .\nAny meaningful switches on that line will applied.  The end of script\nmust be specified with either\n.Li EOF ,\n.Li \"^D\" ( Li \"control-D\" ) ,\n.Li \"^Z\" ( Li \"control-Z\" ) ,\nor reserved word\n.Li __END__ .\nIf the directory name is specified, Ruby will switch to that directory\nbefore executing script.\n.Pp\n.It Fl y\n.It Fl -yydebug\nTurns on compiler debug mode.  Ruby will print a bunch of internal\nstate messages during compiling scripts.  You don't have to specify\nthis switch, unless you are going to debug the Ruby interpreter.\n.El\n.Pp\n.Sh ENVIRONMENT\n.Bl -tag -width \"RUBYLIB_PREFIX\" -compact\n.It Ev RUBYLIB\nA colon-separated list of directories that are added to Ruby's\nlibrary load path\n.Pf ( Li \"$:\" ) . Directories from this environment variable are searched\nbefore the standard load path is searched.\n.Pp\ne.g.:\n.Dl RUBYLIB=\"$HOME/lib/ruby:$HOME/lib/rubyext\"\n.Pp\n.It Ev RUBYOPT\nAdditional Ruby options.\n.Pp\ne.g.\n.Dl RUBYOPT=\"-w -Ke\"\n.Pp\n.It Ev RUBYPATH\nA colon-separated list of directories that Ruby searches for\nRuby programs when the\n.Fl S\nflag is specified.  This variable precedes the\n.Ev PATH\nenvironment variable.\n.Pp\n.It Ev RUBYSHELL\nThe path to the system shell command.  This environment variable is\nenabled for only mswin32, mingw32, and OS/2 platforms.  If this\nvariable is not defined, Ruby refers to\n.Ev COMSPEC .\n.Pp\n.It Ev PATH\nRuby refers to the\n.Ev PATH\nenvironment variable on calling Kernel#system.\n.Pp\n.It Ev RUBYLIB_PREFIX\nThis variable is obsolete.\n.El\n.Pp\n.Sh AUTHORS\nRuby is designed and implemented by\n.An Yukihiro Matsumoto Aq matz@netlab.jp .\n"
  },
  {
    "path": "ruby.c",
    "content": "/**********************************************************************\n\n  ruby.c -\n\n  $Author$\n  $Date$\n  created at: Tue Aug 10 12:47:31 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#if defined _WIN32 || defined __CYGWIN__\n#include <windows.h>\n#endif\n#if defined __CYGWIN__\n#include <sys/cygwin.h>\n#endif\n#ifdef _WIN32_WCE\n#include <winsock.h>\n#include \"wince.h\"\n#endif\n#include \"ruby.h\"\n#include \"dln.h\"\n#include \"node.h\"\n#include <stdio.h>\n#include <sys/types.h>\n#include <ctype.h>\n\n#ifdef __hpux\n#include <sys/pstat.h>\n#endif\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#ifndef HAVE_STRING_H\nchar *strchr _((const char*,const char));\nchar *strrchr _((const char*,const char));\nchar *strstr _((const char*,const char*));\n#endif\n\n#include \"util.h\"\n\n#ifndef HAVE_STDLIB_H\nchar *getenv();\n#endif\n\n#define RUBY_BINARY_NAME \"ruby\"\n#define KIJI_BINARY_NAME \"kiji\"\n\nVALUE ruby_debug = Qfalse;\nVALUE ruby_verbose = Qfalse;\nstatic int sflag = 0;\nstatic int xflag = 0;\nextern int ruby_yydebug;\n\nchar *ruby_inplace_mode = Qfalse;\n\nstatic void load_stdin _((void));\nstatic void load_file _((const char *, int));\nstatic void forbid_setid _((const char *));\n\nstatic VALUE do_loop = Qfalse, do_print = Qfalse;\nstatic VALUE do_check = Qfalse, do_line = Qfalse;\nstatic VALUE do_split = Qfalse;\n\nstatic const char *script;\n\nstatic int origargc;\nstatic char **origargv;\n\nstatic void\nusage(name)\n    const char *name;\n{\n    /* This message really ought to be max 23 lines.\n     * Removed -h because the user already knows that option. Others? */\n\n    static const char *const usage_msg[] = {\n\"-0[octal]       specify record separator (\\\\0, if no argument)\",\n\"-a              autosplit mode with -n or -p (splits $_ into $F)\",\n\"-c              check syntax only\",\n\"-Cdirectory     cd to directory, before executing your script\",\n\"-d              set debugging flags (set $DEBUG to true)\",\n\"-e 'command'    one line of script. Several -e's allowed. Omit [programfile]\",\n\"-Fpattern       split() pattern for autosplit (-a)\",\n\"-i[extension]   edit ARGV files in place (make backup if extension supplied)\",\n\"-Idirectory     specify $LOAD_PATH directory (may be used more than once)\",\n\"-Kkcode         specifies KANJI (Japanese) code-set\",\n\"-l              enable line ending processing\",\n\"-n              assume 'while gets(); ... end' loop around your script\",\n\"-p              assume loop like -n but print line also like sed\",\n\"-rlibrary       require the library, before executing your script\",\n\"-s              enable some switch parsing for switches after script name\",\n\"-S              look for the script using PATH environment variable\",\n\"-T[level]       turn on tainting checks\",\n\"-v              print version number, then turn on verbose mode\",\n\"-w              turn warnings on for your script\",\n\"-W[level]       set warning level; 0=silence, 1=medium, 2=verbose (default)\",\n\"-x[directory]   strip off text before #!ruby line and perhaps cd to directory\",\n\"--copyright     print the copyright\",\n\"--version       print the version\",\nNULL\n};\n    const char *const *p = usage_msg;\n\n    printf(\"Usage: %s [switches] [--] [programfile] [arguments]\\n\", name);\n    while (*p)\n\tprintf(\"  %s\\n\", *p++);\n}\n\nextern VALUE rb_load_path;\n\n#ifndef CharNext\t\t/* defined as CharNext[AW] on Windows. */\n#define CharNext(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE))\n#endif\n\n#if defined DOSISH || defined __CYGWIN__\nstatic inline void\ntranslate_char(char *p, int from, int to)\n{\n    while (*p) {\n\tif ((unsigned char)*p == from)\n\t    *p = to;\n\tp = CharNext(p);\n    }\n}\n#endif\n\n#if defined _WIN32 || defined __CYGWIN__ || defined __DJGPP__\nstatic VALUE\nrubylib_mangled_path(const char *s, unsigned int l)\n{\n    static char *newp, *oldp;\n    static int newl, oldl, notfound;\n    char *ptr;\n    VALUE ret;\n\n    if (!newp && !notfound) {\n\tnewp = getenv(\"RUBYLIB_PREFIX\");\n\tif (newp) {\n\t    oldp = newp = strdup(newp);\n\t    while (*newp && !ISSPACE(*newp) && *newp != ';') {\n\t\tnewp = CharNext(newp);\t/* Skip digits. */\n\t    }\n\t    oldl = newp - oldp;\n\t    while (*newp && (ISSPACE(*newp) || *newp == ';')) {\n\t\tnewp = CharNext(newp);\t/* Skip whitespace. */\n\t    }\n\t    newl = strlen(newp);\n\t    if (newl == 0 || oldl == 0) {\n\t\trb_fatal(\"malformed RUBYLIB_PREFIX\");\n\t    }\n\t    translate_char(newp, '\\\\', '/');\n\t}\n\telse {\n\t    notfound = 1;\n\t}\n    }\n    if (!newp || l < oldl || strncasecmp(oldp, s, oldl) != 0) {\n\treturn rb_str_new(s, l);\n    }\n    ret = rb_str_new(0, l + newl - oldl);\n    ptr = RSTRING_PTR(ret);\n    memcpy(ptr, newp, newl);\n    memcpy(ptr + newl, s + oldl, l - oldl);\n    ptr[l + newl - oldl] = 0;\n    return ret;\n}\n\nstatic VALUE\nrubylib_mangled_path2(const char *s)\n{\n    return rubylib_mangled_path(s, strlen(s));\n}\n#else\n#define rubylib_mangled_path rb_str_new\n#define rubylib_mangled_path2 rb_str_new2\n#endif\n\nstatic void push_include _((const char *path));\n\nstatic void\npush_include(path)\n    const char *path;\n{\n    const char sep = PATH_SEP_CHAR;\n    const char *p, *s;\n\n    p = path;\n    while (*p) {\n\twhile (*p == sep)\n\t    p++;\n\tif (!*p) break;\n\tfor (s = p; *s && *s != sep; s = CharNext(s));\n\trb_ary_push(rb_load_path, rubylib_mangled_path(p, s - p));\n\tp = s;\n    }\n}\n\n#ifdef __CYGWIN__\nstatic void\npush_include_cygwin(const char *path)\n{\n    const char *p, *s;\n    char rubylib[FILENAME_MAX];\n    VALUE buf = 0;\n\n    p = path;\n    while (*p) {\n\tunsigned int len;\n\twhile (*p == ';')\n\t    p++;\n\tif (!*p) break;\n\tfor (s = p; *s && *s != ';'; s = CharNext(s));\n\tlen = s - p;\n\tif (*s) {\n\t    if (!buf) {\n\t\tbuf = rb_str_new(p, len);\n\t\tp = RSTRING_PTR(buf);\n\t    }\n\t    else {\n\t\trb_str_resize(buf, len);\n\t\tp = strncpy(RSTRING_PTR(buf), p, len);\n\t    }\n\t}\n\tif (cygwin_conv_to_posix_path(p, rubylib) == 0)\n\t    p = rubylib;\n\tpush_include(p);\n\tif (!*s) break;\n\tp = s + 1;\n    }\n}\n\n#define push_include push_include_cygwin\n#endif\n\nvoid\nruby_incpush(path)\n    const char *path;\n{\n    if (path == 0)\n\treturn;\n    push_include(path);\n}\n\n#if defined DOSISH || defined __CYGWIN__\n#define LOAD_RELATIVE 1\n#endif\n\nvoid\nruby_init_loadpath()\n{\n#if defined LOAD_RELATIVE\n    char libpath[FILENAME_MAX+1];\n    char *p;\n    int rest;\n#if defined _WIN32 || defined __CYGWIN__\n    HMODULE libruby = NULL;\n    MEMORY_BASIC_INFORMATION m;\n\n#ifndef _WIN32_WCE\n    memset(&m, 0, sizeof(m));\n    if (VirtualQuery(ruby_init_loadpath, &m, sizeof(m)) && m.State == MEM_COMMIT)\n\tlibruby = (HMODULE)m.AllocationBase;\n#endif\n    GetModuleFileName(libruby, libpath, sizeof libpath);\n#elif defined(DJGPP)\n    extern char *__dos_argv0;\n    strncpy(libpath, __dos_argv0, FILENAME_MAX);\n#elif defined(__human68k__)\n    extern char **_argv;\n    strncpy(libpath, _argv[0], FILENAME_MAX);\n#elif defined(__EMX__)\n    _execname(libpath, FILENAME_MAX);\n#endif\n\n    libpath[FILENAME_MAX] = '\\0';\n#if defined DOSISH\n    translate_char(libpath, '\\\\', '/');\n#elif defined __CYGWIN__\n    {\n\tchar rubylib[FILENAME_MAX];\n\tcygwin_conv_to_posix_path(libpath, rubylib);\n\tstrncpy(libpath, rubylib, sizeof(libpath));\n    }\n#endif\n    p = strrchr(libpath, '/');\n    if (p) {\n\t*p = 0;\n\tif (p - libpath > 3 && !strcasecmp(p - 4, \"/bin\")) {\n\t    p -= 4;\n\t    *p = 0;\n\t}\n    }\n    else {\n\tstrcpy(libpath, \".\");\n\tp = libpath + 1;\n    }\n\n    rest = FILENAME_MAX - (p - libpath);\n\n#define RUBY_RELATIVE(path) (strncpy(p, (path), rest), libpath)\n#else\n#define RUBY_RELATIVE(path) (path)\n#endif\n#define incpush(path) rb_ary_push(rb_load_path, rubylib_mangled_path2(path))\n\n    if (rb_safe_level() == 0) {\n\truby_incpush(getenv(\"RUBYLIB\"));\n    }\n\n#ifdef RUBY_SEARCH_PATH\n    incpush(RUBY_RELATIVE(RUBY_SEARCH_PATH));\n#endif\n\n    incpush(RUBY_RELATIVE(RUBY_SITE_LIB2));\n#ifdef RUBY_SITE_THIN_ARCHLIB\n    incpush(RUBY_RELATIVE(RUBY_SITE_THIN_ARCHLIB));\n#endif\n    incpush(RUBY_RELATIVE(RUBY_SITE_ARCHLIB));\n    incpush(RUBY_RELATIVE(RUBY_SITE_LIB));\n\n    incpush(RUBY_RELATIVE(RUBY_VENDOR_LIB2));\n#ifdef RUBY_VENDOR_THIN_ARCHLIB\n    incpush(RUBY_RELATIVE(RUBY_VENDOR_THIN_ARCHLIB));\n#endif\n    incpush(RUBY_RELATIVE(RUBY_VENDOR_ARCHLIB));\n    incpush(RUBY_RELATIVE(RUBY_VENDOR_LIB));\n\n    incpush(RUBY_RELATIVE(RUBY_LIB));\n#ifdef RUBY_THIN_ARCHLIB\n    incpush(RUBY_RELATIVE(RUBY_THIN_ARCHLIB));\n#endif\n    incpush(RUBY_RELATIVE(RUBY_ARCHLIB));\n\n    if (rb_safe_level() == 0) {\n\tincpush(\".\");\n    }\n}\n\nstruct req_list {\n    char *name;\n    struct req_list *next;\n};\nstatic struct req_list req_list_head, *req_list_last = &req_list_head;\n\nstatic void\nadd_modules(mod)\n    const char *mod;\n{\n    struct req_list *list;\n\n    list = ALLOC(struct req_list);\n    list->name = ALLOC_N(char, strlen(mod)+1);\n    strcpy(list->name, mod);\n    list->next = 0;\n    req_list_last->next = list;\n    req_list_last = list;\n}\n\nextern void Init_ext _((void));\n\nstatic void\nrequire_libraries()\n{\n    extern NODE *ruby_eval_tree;\n    extern NODE *ruby_eval_tree_begin;\n    NODE *save[3];\n    struct req_list *list = req_list_head.next;\n    struct req_list *tmp;\n\n    save[0] = ruby_eval_tree;\n    save[1] = ruby_eval_tree_begin;\n    save[2] = NEW_NEWLINE(0);\n    ruby_eval_tree = ruby_eval_tree_begin = 0;\n    ruby_current_node = 0;\n    Init_ext();\t\t/* should be called here for some reason :-( */\n    ruby_current_node = save[2];\n    ruby_set_current_source();\n    req_list_last = 0;\n    while (list) {\n\tint state;\n\n\truby_current_node = 0;\n\trb_protect((VALUE (*)(VALUE))rb_require, (VALUE)list->name, &state);\n\tif (state) rb_jump_tag(state);\n\ttmp = list->next;\n\tfree(list->name);\n\tfree(list);\n\tlist = tmp;\n\truby_current_node = save[2];\n\truby_set_current_source();\n    }\n    req_list_head.next = 0;\n    ruby_eval_tree = save[0];\n    ruby_eval_tree_begin = save[1];\n    rb_gc_force_recycle((VALUE)save[2]);\n    ruby_current_node = 0;\n}\n\nstatic void\nprocess_sflag()\n{\n    if (sflag) {\n\tlong n;\n\tVALUE *args;\n\n\tn = RARRAY(rb_argv)->len;\n\targs = RARRAY(rb_argv)->ptr;\n\twhile (n > 0) {\n\t    VALUE v = *args++;\n\t    char *s = StringValuePtr(v);\n\t    char *p;\n\t    int hyphen = Qfalse;\n\n\t    if (s[0] != '-') break;\n\t    n--;\n\t    if (s[1] == '-' && s[2] == '\\0') break;\n\n\t    v = Qtrue;\n\t    /* check if valid name before replacing - with _ */\n\t    for (p = s + 1; *p; p++) {\n\t\tif (*p == '=') {\n\t\t    *p++ = '\\0';\n\t\t    v = rb_str_new2(p);\n\t\t    break;\n\t\t}\n\t\tif (*p == '-') {\n\t\t    hyphen = Qtrue;\n\t\t}\n\t\telse if (*p != '_' && !ISALNUM(*p)) {\n\t\t    VALUE name_error[2];\n\t\t    name_error[0] = rb_str_new2(\"invalid name for global variable - \");\n\t\t    if (!(p = strchr(p, '='))) {\n\t\t\trb_str_cat2(name_error[0], s);\n\t\t    }\n\t\t    else {\n\t\t\trb_str_cat(name_error[0], s, p - s);\n\t\t    }\n\t\t    name_error[1] = args[-1];\n\t\t    rb_exc_raise(rb_class_new_instance(2, name_error, rb_eNameError));\n\t\t}\n\t    }\n\t    s[0] = '$';\n\t    if (hyphen) {\n\t\tfor (p = s + 1; *p; ++p) {\n\t\t    if (*p == '-') *p = '_';\n\t\t}\n\t    }\n\t    rb_gv_set(s, v);\n\t}\n\tn = RARRAY(rb_argv)->len - n;\n\twhile (n--) {\n\t    rb_ary_shift(rb_argv);\n\t}\n    }\n    sflag = 0;\n}\n\nstatic void proc_options _((int argc, char **argv));\n\nstatic char*\nmoreswitches(s)\n    char *s;\n{\n    int argc; char *argv[3];\n    char *p = s;\n\n    argc = 2; argv[0] = argv[2] = 0;\n    while (*s && !ISSPACE(*s))\n\ts++;\n    argv[1] = ALLOCA_N(char, s-p+2);\n    argv[1][0] = '-';\n    strncpy(argv[1]+1, p, s-p);\n    argv[1][s-p+1] = '\\0';\n    proc_options(argc, argv);\n    while (*s && ISSPACE(*s))\n\ts++;\n    return s;\n}\n\nstatic void\nproc_options(argc, argv)\n    int argc;\n    char **argv;\n{\n    char *argv0 = argv[0];\n    int do_search;\n    char *s;\n    NODE *volatile script_node = 0;\n\n    int version = 0;\n    int copyright = 0;\n    int verbose = 0;\n    VALUE e_script = Qfalse;\n\n    if (argc == 0) return;\n\n    do_search = Qfalse;\n\n    for (argc--,argv++; argc > 0; argc--,argv++) {\n\tif (argv[0][0] != '-' || !argv[0][1]) break;\n\n\ts = argv[0]+1;\n      reswitch:\n\tswitch (*s) {\n\t  case 'a':\n\t    do_split = Qtrue;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'p':\n\t    do_print = Qtrue;\n\t    /* through */\n\t  case 'n':\n\t    do_loop = Qtrue;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'd':\n\t    ruby_debug = Qtrue;\n\t    ruby_verbose = Qtrue;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'y':\n\t    ruby_yydebug = 1;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'v':\n\t    if (argv0 == 0 || verbose) {\n\t\ts++;\n\t\tgoto reswitch;\n\t    }\n\t    ruby_show_version();\n\t    verbose = 1;\n\t  case 'w':\n\t    ruby_verbose = Qtrue;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'W':\n\t    {\n\t\tint numlen;\n\t\tint v = 2;\t/* -W as -W2 */\n\n\t\tif (*++s) {\n\t\t    v = scan_oct(s, 1, &numlen);\n\t\t    if (numlen == 0) v = 1;\n\t\t    s += numlen;\n\t\t}\n\t\tswitch (v) {\n\t\t  case 0:\n\t\t    ruby_verbose = Qnil; break;\n\t\t  case 1:\n\t\t    ruby_verbose = Qfalse; break;\n\t\t  default:\n\t\t    ruby_verbose = Qtrue; break;\n\t\t}\n\t    }\n\t    goto reswitch;\n\n\t  case 'c':\n\t    do_check = Qtrue;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 's':\n\t    forbid_setid(\"-s\");\n\t    sflag = 1;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'h':\n\t    usage(origargv[0]);\n\t    exit(0);\n\n\t  case 'l':\n\t    do_line = Qtrue;\n\t    rb_output_rs = rb_rs;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'S':\n\t    forbid_setid(\"-S\");\n\t    do_search = Qtrue;\n\t    s++;\n\t    goto reswitch;\n\n\t  case 'e':\n\t    forbid_setid(\"-e\");\n\t    if (!*++s) {\n\t\ts = argv[1];\n\t\targc--,argv++;\n\t    }\n\t    if (!s) {\n\t\tfprintf(stderr, \"%s: no code specified for -e\\n\", origargv[0]);\n\t\texit(2);\n\t    }\n\t    if (!e_script) {\n\t\te_script = rb_str_new(0,0);\n\t\tif (script == 0) script = \"-e\";\n\t    }\n\t    rb_str_cat2(e_script, s);\n\t    rb_str_cat2(e_script, \"\\n\");\n\t    break;\n\n\t  case 'r':\n\t    forbid_setid(\"-r\");\n\t    if (*++s) {\n\t\tadd_modules(s);\n\t    }\n\t    else if (argv[1]) {\n\t\tadd_modules(argv[1]);\n\t\targc--,argv++;\n\t    }\n\t    break;\n\n\t  case 'i':\n\t    forbid_setid(\"-i\");\n\t    if (ruby_inplace_mode) free(ruby_inplace_mode);\n\t    ruby_inplace_mode = strdup(s+1);\n\t    break;\n\n\t  case 'x':\n\t    xflag = Qtrue;\n\t    s++;\n\t    if (*s && chdir(s) < 0) {\n\t\trb_fatal(\"Can't chdir to %s\", s);\n\t    }\n\t    break;\n\n\t  case 'C':\n\t  case 'X':\n\t    s++;\n\t    if (!*s) {\n\t\ts = argv[1];\n\t\targc--,argv++;\n\t    }\n\t    if (!s || !*s) {\n\t\trb_fatal(\"Can't chdir\");\n\t    }\n\t    if (chdir(s) < 0) {\n\t\trb_fatal(\"Can't chdir to %s\", s);\n\t    }\n\t    break;\n\n\t  case 'F':\n\t    if (*++s) {\n\t\trb_fs = rb_reg_new(s, strlen(s), 0);\n\t    }\n\t    break;\n\n\t  case 'K':\n\t    if (*++s) {\n\t\trb_set_kcode(s);\n\t\ts++;\n\t    }\n\t    goto reswitch;\n\n\t  case 'T':\n\t    {\n\t\tint numlen;\n\t\tint v = 1;\n\n\t\tif (*++s) {\n\t\t    v = scan_oct(s, 2, &numlen);\n\t\t    if (numlen == 0) v = 1;\n\t\t    s += numlen;\n\t\t}\n\t\trb_set_safe_level(v);\n\t    }\n\t    goto reswitch;\n\n\t  case 'I':\n\t    forbid_setid(\"-I\");\n\t    if (*++s)\n\t\truby_incpush(s);\n\t    else if (argv[1]) {\n\t\truby_incpush(argv[1]);\n\t\targc--,argv++;\n\t    }\n\t    break;\n\n\t  case '0':\n\t    {\n\t\tint numlen;\n\t\tint v;\n\t\tchar c;\n\n\t\tv = scan_oct(s, 4, &numlen);\n\t\ts += numlen;\n\t\tif (v > 0377) rb_rs = Qnil;\n\t\telse if (v == 0 && numlen >= 2) {\n\t\t    rb_rs = rb_str_new2(\"\\n\\n\");\n\t\t}\n\t\telse {\n\t\t    c = v & 0xff;\n\t\t    rb_rs = rb_str_new(&c, 1);\n\t\t}\n\t    }\n\t    goto reswitch;\n\n\t  case '-':\n\t    if (!s[1] || (s[1] == '\\r' && !s[2])) {\n\t\targc--,argv++;\n\t\tgoto switch_end;\n\t    }\n\t    s++;\n\t    if (strcmp(\"copyright\", s) == 0)\n\t\tcopyright = 1;\n\t    else if (strcmp(\"debug\", s) == 0) {\n\t\truby_debug = Qtrue;\n                ruby_verbose = Qtrue;\n            }\n\t    else if (strcmp(\"version\", s) == 0)\n\t\tversion = 1;\n\t    else if (strcmp(\"verbose\", s) == 0) {\n\t\tverbose = 1;\n\t\truby_verbose = Qtrue;\n\t    }\n\t    else if (strcmp(\"yydebug\", s) == 0)\n\t\truby_yydebug = 1;\n\t    else if (strcmp(\"help\", s) == 0) {\n\t\tusage(origargv[0]);\n\t\texit(0);\n\t    }\n\t    else {\n\t\tfprintf(stderr, \"%s: invalid option --%s  (-h will show valid options)\\n\",\n\t\t\torigargv[0], s);\n\t\texit(2);\n\t    }\n\t    break;\n\n\t  case '\\r':\n\t    if (!s[1]) break;\n\n\t  default:\n\t    {\n\t\tconst char *format;\n\t\tif (ISPRINT(*s)) {\n\t\t    format = \"%s: invalid option -%c  (-h will show valid options)\\n\";\n\t\t}\n\t\telse {\n\t\t    format = \"%s: invalid option -\\\\%03o  (-h will show valid options)\\n\";\n\t\t}\n\t\tfprintf(stderr, format, origargv[0], (int)(unsigned char)*s);\n\t    }\n\t    exit(2);\n\n\t  case 0:\n\t    break;\n\t}\n    }\n\n  switch_end:\n    if (argv0 == 0) return;\n\n    if (rb_safe_level() == 0 && (s = getenv(\"RUBYOPT\"))) {\n\twhile (ISSPACE(*s)) s++;\n\tif (*s == 'T' || (*s == '-' && *(s+1) == 'T')) {\n\t    int numlen;\n\t    int v = 1;\n\n\t    if (*s != 'T') ++s;\n\t    if (*++s) {\n\t\tv = scan_oct(s, 2, &numlen);\n\t\tif (numlen == 0) v = 1;\n\t    }\n\t    rb_set_safe_level(v);\n\t}\n\telse {\n\t    while (s && *s) {\n\t\tif (*s == '-') {\n\t\t    s++;\n\t\t    if (ISSPACE(*s)) {\n\t\t\tdo {s++;} while (ISSPACE(*s));\n\t\t\tcontinue;\n\t\t    }\n\t\t}\n\t\tif (!*s) break;\n\t\tif (!strchr(\"IdvwWrK\", *s))\n\t\t    rb_raise(rb_eRuntimeError, \"illegal switch in RUBYOPT: -%c\", *s);\n\t\ts = moreswitches(s);\n\t    }\n\t}\n    }\n\n    if (version) {\n\truby_show_version();\n\texit(0);\n    }\n    if (copyright) {\n\truby_show_copyright();\n    }\n\n    if (rb_safe_level() >= 4) {\n\tOBJ_TAINT(rb_argv);\n\tOBJ_TAINT(rb_load_path);\n    }\n\n    if (!e_script) {\n\tif (argc == 0) {\t/* no more args */\n\t    if (verbose) exit(0);\n\t    script = \"-\";\n\t}\n\telse {\n\t    script = argv[0];\n#if defined DOSISH || defined __CYGWIN__\n\t    translate_char(argv[0], '\\\\', '/');\n#endif\n\t    if (script[0] == '\\0') {\n\t\tscript = \"-\";\n\t    }\n\t    else if (do_search) {\n\t\tchar *path = getenv(\"RUBYPATH\");\n\n\t\tscript = 0;\n\t\tif (path) {\n\t\t    script = dln_find_file(argv[0], path);\n\t\t}\n\t\tif (!script) {\n\t\t    script = dln_find_file(argv[0], getenv(PATH_ENV));\n\t\t}\n\t\tif (!script) script = argv[0];\n\t\tscript = ruby_sourcefile = rb_source_filename(script);\n\t\tscript_node = NEW_NEWLINE(0);\n#if defined DOSISH || defined __CYGWIN__\n\t\ttranslate_char(ruby_sourcefile, '\\\\', '/');\n#endif\n\t    }\n\t    argc--; argv++;\n\t}\n    }\n\n    ruby_script(script);\n    ruby_set_argv(argc, argv);\n    process_sflag();\n\n    ruby_init_loadpath();\n    ruby_sourcefile = rb_source_filename(argv0);\n    if (e_script) {\n\trequire_libraries();\n\trb_compile_string(script, e_script, 1);\n    }\n    else if (strlen(script) == 1 && script[0] == '-') {\n\tload_stdin();\n    }\n    else {\n\tload_file(script, 1);\n    }\n\n    process_sflag();\n    xflag = 0;\n\n    if (rb_safe_level() >= 4) {\n\tFL_UNSET(rb_argv, FL_TAINT);\n\tFL_UNSET(rb_load_path, FL_TAINT);\n    }\n}\n\nextern int ruby__end__seen;\n\nstatic void\nload_file(fname, script)\n    const char *fname;\n    int script;\n{\n    extern VALUE rb_stdin;\n    VALUE f;\n    int line_start = 1;\n\n    if (!fname) rb_load_fail(fname);\n    if (strcmp(fname, \"-\") == 0) {\n\tf = rb_stdin;\n    }\n    else {\n\tFILE *fp = fopen(fname, \"r\");\n\n\tif (fp == NULL) {\n\t    rb_load_fail(fname);\n\t}\n\tfclose(fp);\n\n\tf = rb_file_open(fname, \"r\");\n#if defined DOSISH || defined __CYGWIN__\n\t{\n\t    char *ext = strrchr(fname, '.');\n\t    if (ext && strcasecmp(ext, \".exe\") == 0)\n\t\trb_io_binmode(f);\n\t}\n#endif\n    }\n\n    if (script) {\n\tVALUE c = 1;\t\t/* something not nil */\n\tVALUE line;\n\tchar *p;\n\n\tif (xflag) {\n\t    forbid_setid(\"-x\");\n\t    xflag = Qfalse;\n\t    while (!NIL_P(line = rb_io_gets(f))) {\n\t\tline_start++;\n\t\tif (RSTRING(line)->len > 2\n\t\t    && RSTRING(line)->ptr[0] == '#'\n\t\t    && RSTRING(line)->ptr[1] == '!') {\n                   if (((p = strstr(RSTRING(line)->ptr, RUBY_BINARY_NAME)) != NULL) ||\n                       ((p = strstr(RSTRING(line)->ptr, KIJI_BINARY_NAME)) != NULL)) {\n\t\t\tgoto start_read;\n\t\t    }\n\t\t}\n\t    }\n\t    rb_raise(rb_eLoadError, \"no Ruby script found in input\");\n\t}\n\n\tc = rb_io_getc(f);\n\tif (c == INT2FIX('#')) {\n\t    line = rb_io_gets(f);\n\t    if (NIL_P(line)) return;\n\t    line_start++;\n\n\t    if (RSTRING(line)->len > 2 && RSTRING(line)->ptr[0] == '!') {\n\t\tif (((p = strstr(RSTRING(line)->ptr, RUBY_BINARY_NAME)) == NULL) &&\n\t\t    ((p = strstr(RSTRING(line)->ptr, KIJI_BINARY_NAME)) == NULL)) {\n\t\t    /* not ruby script, kick the program */\n\t\t    char **argv;\n\t\t    char *path;\n\t\t    char *pend = RSTRING(line)->ptr + RSTRING(line)->len;\n\n\t\t    p = RSTRING(line)->ptr + 1;\t/* skip `#!' */\n\t\t    if (pend[-1] == '\\n') pend--; /* chomp line */\n\t\t    if (pend[-1] == '\\r') pend--;\n\t\t    *pend = '\\0';\n\t\t    while (p < pend && ISSPACE(*p))\n\t\t\tp++;\n\t\t    path = p;\t/* interpreter path */\n\t\t    while (p < pend && !ISSPACE(*p))\n\t\t\tp++;\n\t\t    *p++ = '\\0';\n\t\t    if (p < pend) {\n\t\t\targv = ALLOCA_N(char*, origargc+3);\n\t\t\targv[1] = p;\n\t\t\tMEMCPY(argv+2, origargv+1, char*, origargc);\n\t\t    }\n\t\t    else {\n\t\t\targv = origargv;\n\t\t    }\n\t\t    argv[0] = path;\n\t\t    execv(path, argv);\n\n\t\t    ruby_sourcefile = rb_source_filename(fname);\n\t\t    ruby_sourceline = 1;\n\t\t    rb_fatal(\"Can't exec %s\", path);\n\t\t}\n\n\t      start_read:\n\t\tp += 4;\n\t\tRSTRING(line)->ptr[RSTRING(line)->len-1] = '\\0';\n\t\tif (RSTRING(line)->ptr[RSTRING(line)->len-2] == '\\r')\n\t\t    RSTRING(line)->ptr[RSTRING(line)->len-2] = '\\0';\n\t\tif ((p = strstr(p, \" -\")) != 0) {\n\t\t    p++;\t/* skip space before `-' */\n\t\t    while (*p == '-') {\n\t\t\tp = moreswitches(p+1);\n\t\t    }\n\t\t}\n\t    }\n\t}\n\telse if (!NIL_P(c)) {\n\t    rb_io_ungetc(f, c);\n\t}\n\trequire_libraries();\t/* Why here? unnatural */\n\tif (NIL_P(c)) return;\n    }\n    rb_compile_file(fname, f, line_start);\n    if (script && ruby__end__seen) {\n\trb_define_global_const(\"DATA\", f);\n    }\n    else if (f != rb_stdin) {\n\trb_io_close(f);\n    }\n}\n\nvoid\nrb_load_file(fname)\n    const char *fname;\n{\n    load_file(fname, 0);\n}\n\nstatic void\nload_stdin()\n{\n    forbid_setid(\"program input from stdin\");\n    load_file(\"-\", 1);\n}\n\nVALUE rb_progname;\nVALUE rb_argv;\nVALUE rb_argv0;\n\n#if defined(PSTAT_SETCMD) || defined(HAVE_SETPROCTITLE)\n#elif defined(_WIN32)\n#elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)\n#else\n#define USE_ENVSPACE_FOR_ARG0\n#endif\n\n#ifdef USE_ENVSPACE_FOR_ARG0\nstatic struct {\n    char *begin, *end;\n} envspace;\nextern char **environ;\n\nstatic void\nset_arg0space()\n{\n    char *s;\n    int i;\n\n    if (!environ || (s = environ[0]) == NULL) return;\n    envspace.begin = s;\n    s += strlen(s);\n    for (i = 1; environ[i]; i++) {\n\tif (environ[i] == s + 1) {\n\t    s++;\n\t    s += strlen(s);\t/* this one is ok too */\n\t}\n    }\n    envspace.end = s;\n}\n#else\n#define set_arg0space() ((void)0)\n#endif\n\nstatic int\nget_arglen(int argc, char **argv)\n{\n    char *s = argv[0];\n    int i;\n\n    if (!argc) return 0;\n    s += strlen(s);\n    /* See if all the arguments are contiguous in memory */\n    for (i = 1; i < argc; i++) {\n\tif (argv[i] == s + 1) {\n\t    s++;\n\t    s += strlen(s);\t/* this one is ok too */\n\t}\n\telse {\n\t    break;\n\t}\n    }\n#if defined(USE_ENVSPACE_FOR_ARG0)\n    if (environ && (s == environ[0])) {\n\ts += strlen(s);\n\tfor (i = 1; environ[i]; i++) {\n\t    if (environ[i] == s + 1) {\n\t\ts++;\n\t\ts += strlen(s);\t/* this one is ok too */\n\t    }\n\t}\n\truby_setenv(\"\", NULL); /* duplicate environ vars */\n    }\n#endif\n    return s - argv[0];\n}\n\nstatic void\nset_arg0(val, id)\n    VALUE val;\n    ID id;\n{\n    VALUE progname;\n    char *s;\n    long i;\n    int j;\n#if !defined(PSTAT_SETCMD) && !defined(HAVE_SETPROCTITLE)\n    static int len = 0;\n#endif\n\n    if (origargv == 0) rb_raise(rb_eRuntimeError, \"$0 not initialized\");\n    StringValue(val);\n    s = RSTRING(val)->ptr;\n    i = RSTRING(val)->len;\n#if defined(PSTAT_SETCMD)\n    if (i >= PST_CLEN) {\n\tunion pstun j;\n\tj.pst_command = s;\n\ti = PST_CLEN;\n\tRSTRING(val)->len = i;\n\t*(s + i) = '\\0';\n\tpstat(PSTAT_SETCMD, j, PST_CLEN, 0, 0);\n    }\n    else {\n\tunion pstun j;\n\tj.pst_command = s;\n\tpstat(PSTAT_SETCMD, j, i, 0, 0);\n    }\n    progname = rb_tainted_str_new(s, i);\n#elif defined(HAVE_SETPROCTITLE)\n    setproctitle(\"%.*s\", (int)i, s);\n    progname = rb_tainted_str_new(s, i);\n#else\n    if (len == 0) {\n\tlen = get_arglen(origargc, origargv);\n    }\n\n    if (i >= len) {\n\ti = len;\n    }\n    memcpy(origargv[0], s, i);\n    s = origargv[0] + i;\n    *s = '\\0';\n    if (++i < len) memset(s + 1, ' ', len - i);\n    for (i = len-1, j = origargc-1; j > 0 && i >= 0; --i, --j) {\n\torigargv[j] = origargv[0] + i;\n\t*origargv[j] = '\\0';\n    }\n    progname = rb_tainted_str_new2(origargv[0]);\n#endif\n    rb_progname = rb_obj_freeze(progname);\n}\n\nvoid\nruby_script(name)\n    const char *name;\n{\n    if (name) {\n\trb_progname = rb_obj_freeze(rb_tainted_str_new2(name));\n\truby_sourcefile = rb_source_filename(name);\n    }\n}\n\nstatic int uid, euid, gid, egid;\n\nstatic void\ninit_ids()\n{\n    uid = (int)getuid();\n    euid = (int)geteuid();\n    gid = (int)getgid();\n    egid = (int)getegid();\n#ifdef VMS\n    uid |= gid << 16;\n    euid |= egid << 16;\n#endif\n    if (uid && (euid != uid || egid != gid)) {\n\trb_set_safe_level(1);\n    }\n}\n\nstatic void\nforbid_setid(s)\n    const char *s;\n{\n    if (euid != uid)\n        rb_raise(rb_eSecurityError, \"no %s allowed while running setuid\", s);\n    if (egid != gid)\n        rb_raise(rb_eSecurityError, \"no %s allowed while running setgid\", s);\n    if (rb_safe_level() > 0)\n        rb_raise(rb_eSecurityError, \"no %s allowed in tainted mode\", s);\n}\n\nstatic void\nverbose_setter(val, id, variable)\n    VALUE val;\n    ID id;\n    VALUE *variable;\n{\n    ruby_verbose = RTEST(val) ? Qtrue : val;\n}\n\nvoid\nruby_prog_init()\n{\n    init_ids();\n\n    ruby_sourcefile = rb_source_filename(\"ruby\");\n    rb_define_hooked_variable(\"$VERBOSE\", &ruby_verbose, 0, verbose_setter);\n    rb_define_hooked_variable(\"$-v\", &ruby_verbose, 0, verbose_setter);\n    rb_define_hooked_variable(\"$-w\", &ruby_verbose, 0, verbose_setter);\n    rb_define_variable(\"$DEBUG\", &ruby_debug);\n    rb_define_variable(\"$-d\", &ruby_debug);\n    rb_define_readonly_variable(\"$-p\", &do_print);\n    rb_define_readonly_variable(\"$-l\", &do_line);\n\n    rb_define_hooked_variable(\"$0\", &rb_progname, 0, set_arg0);\n    rb_define_hooked_variable(\"$PROGRAM_NAME\", &rb_progname, 0, set_arg0);\n\n    rb_define_readonly_variable(\"$*\", &rb_argv);\n    rb_argv = rb_ary_new();\n    rb_define_global_const(\"ARGV\", rb_argv);\n    rb_define_readonly_variable(\"$-a\", &do_split);\n    rb_global_variable(&rb_argv0);\n\n#ifdef MSDOS\n    /*\n     * There is no way we can refer to them from ruby, so close them to save\n     * space.\n     */\n    (void)fclose(stdaux);\n    (void)fclose(stdprn);\n#endif\n}\n\nvoid\nruby_set_argv(argc, argv)\n    int argc;\n    char **argv;\n{\n    int i;\n\n#if defined(USE_DLN_A_OUT)\n    if (origargv) dln_argv0 = origargv[0];\n    else          dln_argv0 = argv[0];\n#endif\n    rb_ary_clear(rb_argv);\n    for (i=0; i < argc; i++) {\n\tVALUE arg = rb_tainted_str_new2(argv[i]);\n\n\tOBJ_FREEZE(arg);\n\trb_ary_push(rb_argv, arg);\n    }\n}\n\nvoid\nruby_process_options(argc, argv)\n    int argc;\n    char **argv;\n{\n    origargc = argc; origargv = argv;\n\n    ruby_script(argv[0]);\t/* for the time being */\n    rb_argv0 = rb_progname;\n#if defined(USE_DLN_A_OUT)\n    dln_argv0 = argv[0];\n#endif\n    set_arg0space();\n    proc_options(argc, argv);\n\n    if (do_check && ruby_nerrs == 0) {\n\tprintf(\"Syntax OK\\n\");\n\texit(0);\n    }\n    if (do_print) {\n\trb_parser_append_print();\n    }\n    if (do_loop) {\n\trb_parser_while_loop(do_line, do_split);\n    }\n}\n"
  },
  {
    "path": "ruby.h",
    "content": "/**********************************************************************\n\n  ruby.h -\n\n  $Author$\n  created at: Thu Jun 10 14:26:32 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#ifndef RUBY_H\n#define RUBY_H\n\n#if defined(__cplusplus)\nextern \"C\" {\n#if 0\n} /* satisfy cc-mode */\n#endif\n#endif\n\n#include \"config.h\"\n#ifdef RUBY_EXTCONF_H\n#include RUBY_EXTCONF_H\n#endif\n\n#define NORETURN_STYLE_NEW 1\n#ifndef NORETURN\n# define NORETURN(x) x\n#endif\n#ifndef NOINLINE\n# define NOINLINE(x) x\n#endif\n\n#include \"defines.h\"\n\n#ifdef HAVE_STDLIB_H\n# include <stdlib.h>\n#endif\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#else\n# include <strings.h>\n#endif\n\n#ifdef HAVE_INTRINSICS_H\n# include <intrinsics.h>\n#endif\n\n#include <stddef.h>\n#include <stdio.h>\n\n/* need to include <ctype.h> to use these macros */\n#ifndef ISPRINT\n#define ISASCII(c) isascii((int)(unsigned char)(c))\n#undef ISPRINT\n#define ISPRINT(c) (ISASCII(c) && isprint((int)(unsigned char)(c)))\n#define ISSPACE(c) (ISASCII(c) && isspace((int)(unsigned char)(c)))\n#define ISUPPER(c) (ISASCII(c) && isupper((int)(unsigned char)(c)))\n#define ISLOWER(c) (ISASCII(c) && islower((int)(unsigned char)(c)))\n#define ISALNUM(c) (ISASCII(c) && isalnum((int)(unsigned char)(c)))\n#define ISALPHA(c) (ISASCII(c) && isalpha((int)(unsigned char)(c)))\n#define ISDIGIT(c) (ISASCII(c) && isdigit((int)(unsigned char)(c)))\n#define ISXDIGIT(c) (ISASCII(c) && isxdigit((int)(unsigned char)(c)))\n#endif\n\n#if defined(HAVE_ALLOCA_H)\n#include <alloca.h>\n#else\n#  ifdef _AIX\n#pragma alloca\n#  endif\n#endif\n\n#if defined(__VMS)\n# pragma builtins\n# define alloca __alloca\n#endif\n\n#if SIZEOF_LONG != SIZEOF_VOIDP\n# error ---->> ruby requires sizeof(void*) == sizeof(long) to be compiled. <<----\n#else\ntypedef unsigned long VALUE;\ntypedef unsigned long ID;\n#endif\n\n#ifdef __STDC__\n# include <limits.h>\n#else\n# ifndef LONG_MAX\n#  ifdef HAVE_LIMITS_H\n#   include <limits.h>\n#  else\n    /* assuming 32bit(2's compliment) long */\n#   define LONG_MAX 2147483647\n#  endif\n# endif\n# ifndef LONG_MIN\n#  define LONG_MIN (-LONG_MAX-1)\n# endif\n# ifndef CHAR_BIT\n#  define CHAR_BIT 8\n# endif\n#endif\n\n#ifdef HAVE_LONG_LONG\n# ifndef LLONG_MAX\n#  ifdef LONG_LONG_MAX\n#   define LLONG_MAX  LONG_LONG_MAX\n#  else\n#   ifdef _I64_MAX\n#    define LLONG_MAX _I64_MAX\n#   else\n    /* assuming 64bit(2's complement) long long */\n#    define LLONG_MAX 9223372036854775807LL\n#   endif\n#  endif\n# endif\n# ifndef LLONG_MIN\n#  ifdef LONG_LONG_MIN\n#   define LLONG_MIN  LONG_LONG_MIN\n#  else\n#   ifdef _I64_MIN\n#    define LLONG_MIN _I64_MIN\n#   else\n#    define LLONG_MIN (-LLONG_MAX-1)\n#   endif\n#  endif\n# endif\n#endif\n\n#define FIXNUM_MAX (LONG_MAX>>1)\n#define FIXNUM_MIN RSHIFT((long)LONG_MIN,1)\n\n#define FIXNUM_FLAG 0x01\n#define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))\n#define LONG2FIX(i) INT2FIX(i)\n#define rb_fix_new(v) INT2FIX(v)\nVALUE rb_int2inum _((long));\n#define INT2NUM(v) rb_int2inum(v)\n#define LONG2NUM(v) INT2NUM(v)\n#define rb_int_new(v) rb_int2inum(v)\nVALUE rb_uint2inum _((unsigned long));\n#define UINT2NUM(v) rb_uint2inum(v)\n#define ULONG2NUM(v) UINT2NUM(v)\n#define rb_uint_new(v) rb_uint2inum(v)\n\n#ifdef HAVE_LONG_LONG\nVALUE rb_ll2inum _((LONG_LONG));\n#define LL2NUM(v) rb_ll2inum(v)\nVALUE rb_ull2inum _((unsigned LONG_LONG));\n#define ULL2NUM(v) rb_ull2inum(v)\n#endif\n\n#if SIZEOF_OFF_T > SIZEOF_LONG && defined(HAVE_LONG_LONG)\n# define OFFT2NUM(v) LL2NUM(v)\n#elif SIZEOF_OFF_T == SIZEOF_LONG\n# define OFFT2NUM(v) LONG2NUM(v)\n#else\n# define OFFT2NUM(v) INT2NUM(v)\n#endif\n\n#define FIX2LONG(x) RSHIFT((long)x,1)\n#define FIX2ULONG(x) (((unsigned long)(x))>>1)\n#define FIXNUM_P(f) (((long)(f))&FIXNUM_FLAG)\n#define POSFIXABLE(f) ((f) < FIXNUM_MAX+1)\n#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)\n#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))\n\n#define IMMEDIATE_MASK 0x03\n#define IMMEDIATE_P(x) ((VALUE)(x) & IMMEDIATE_MASK)\n\n#define SYMBOL_FLAG 0x0e\n#define SYMBOL_P(x) (((VALUE)(x)&0xff)==SYMBOL_FLAG)\n#define ID2SYM(x) ((VALUE)(((long)(x))<<8|SYMBOL_FLAG))\n#define SYM2ID(x) RSHIFT((unsigned long)x,8)\n\n/* special contants - i.e. non-zero and non-fixnum constants */\n#define Qfalse ((VALUE)0)\n#define Qtrue  ((VALUE)2)\n#define Qnil   ((VALUE)4)\n#define Qundef ((VALUE)6)\t/* undefined value for placeholder */\n\n#define RTEST(v) (((VALUE)(v) & ~Qnil) != 0)\n#define NIL_P(v) ((VALUE)(v) == Qnil)\n\n#define CLASS_OF(v) rb_class_of((VALUE)(v))\n\n#define T_NONE   0x00\n\n#define T_NIL    0x01\n#define T_OBJECT 0x02\n#define T_CLASS  0x03\n#define T_ICLASS 0x04\n#define T_MODULE 0x05\n#define T_FLOAT  0x06\n#define T_STRING 0x07\n#define T_REGEXP 0x08\n#define T_ARRAY  0x09\n#define T_FIXNUM 0x0a\n#define T_HASH   0x0b\n#define T_STRUCT 0x0c\n#define T_BIGNUM 0x0d\n#define T_FILE   0x0e\n\n#define T_TRUE   0x20\n#define T_FALSE  0x21\n#define T_DATA   0x22\n#define T_MATCH  0x23\n#define T_SYMBOL 0x24\n\n#define T_BLKTAG 0x3b\n#define T_UNDEF  0x3c\n#define T_VARMAP 0x3d\n#define T_SCOPE  0x3e\n#define T_NODE   0x3f\n\n#define T_MASK   0x3f\n\n// Used by the tracer for types which aren't available statically\n#define T_UNKNOWN (T_MASK+1)\n\n#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)\n\n#define TYPE(x) rb_type((VALUE)(x))\n\n#ifdef __GNUC__\n#define RB_GC_GUARD_PTR(ptr) \\\n    __extension__ ({volatile VALUE *rb_gc_guarded_ptr = (ptr); rb_gc_guarded_ptr;})\n#else\n#define RB_GC_GUARD_PTR(ptr) (volatile VALUE *)(ptr)\n#endif\n#define RB_GC_GUARD(v) (*RB_GC_GUARD_PTR(&(v)))\n\nvoid rb_check_type _((VALUE,int));\n#define Check_Type(v,t) rb_check_type((VALUE)(v),t)\n\nVALUE rb_str_to_str _((VALUE));\nVALUE rb_string_value _((volatile VALUE*));\nchar *rb_string_value_ptr _((volatile VALUE*));\nchar *rb_string_value_cstr _((volatile VALUE*));\n\n#define StringValue(v) rb_string_value(&(v))\n#define StringValuePtr(v) rb_string_value_ptr(&(v))\n#define StringValueCStr(v) rb_string_value_cstr(&(v))\n\nvoid rb_check_safe_obj _((VALUE));\nvoid rb_check_safe_str _((VALUE));\n#define SafeStringValue(v) do {\\\n    StringValue(v);\\\n    rb_check_safe_obj(v);\\\n} while (0)\n/* obsolete macro - use SafeStringValue(v) */\n#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))\n\nvoid rb_secure _((int));\nRUBY_EXTERN int ruby_safe_level;\n#define rb_safe_level() (ruby_safe_level)\nvoid rb_set_safe_level _((int));\nvoid rb_secure_update _((VALUE));\n\nlong rb_num2long _((VALUE));\nunsigned long rb_num2ulong _((VALUE));\n#define NUM2LONG(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2long((VALUE)x))\n#define NUM2ULONG(x) rb_num2ulong((VALUE)x)\n#if SIZEOF_INT < SIZEOF_LONG\nlong rb_num2int _((VALUE));\n#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):rb_num2int((VALUE)x))\nlong rb_fix2int _((VALUE));\n#define FIX2INT(x) rb_fix2int((VALUE)x)\nunsigned long rb_num2uint _((VALUE));\n#define NUM2UINT(x) rb_num2uint(x)\nunsigned long rb_fix2uint _((VALUE));\n#define FIX2UINT(x) rb_fix2uint(x)\n#else\n#define NUM2INT(x) ((int)NUM2LONG(x))\n#define NUM2UINT(x) ((unsigned int)NUM2ULONG(x))\n#define FIX2INT(x) ((int)FIX2LONG(x))\n#define FIX2UINT(x) ((unsigned int)FIX2ULONG(x))\n#endif\n\n#ifdef HAVE_LONG_LONG\nLONG_LONG rb_num2ll _((VALUE));\nunsigned LONG_LONG rb_num2ull _((VALUE));\n# define NUM2LL(x) (FIXNUM_P(x)?FIX2LONG(x):rb_num2ll((VALUE)x))\n# define NUM2ULL(x) rb_num2ull((VALUE)x)\n#endif\n\n#if defined(HAVE_LONG_LONG) && SIZEOF_OFF_T > SIZEOF_LONG\n# define NUM2OFFT(x) ((off_t)NUM2LL(x))\n#else\n# define NUM2OFFT(x) NUM2LONG(x)\n#endif\n\ndouble rb_num2dbl _((VALUE));\n#define NUM2DBL(x) rb_num2dbl((VALUE)(x))\n\n/* obsolete API - use StringValue() */\nchar *rb_str2cstr _((VALUE,long*));\n/* obsolete API - use StringValuePtr() */\n#define STR2CSTR(x) rb_str2cstr((VALUE)(x),0)\n\n#define NUM2CHR(x) (((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\\\n                     RSTRING(x)->ptr[0]:(char)(NUM2INT(x)&0xff))\n#define CHR2FIX(x) INT2FIX((long)((x)&0xff))\n\nRUBY_EXTERN int ruby_in_longlife_context;\n\n#ifdef GC_DEBUG\nRUBY_EXTERN int gc_debug_on;\n\nstruct source_position_list;\n\ntypedef struct source_position {\n    char *file;\n    int line;\n    ID func;\n    VALUE frames_hash;\n    struct source_position *parent;\n} source_position_t;\n\nchar *gc_debug_get_backtrace(source_position_t *source_pos);\n\n#define GC_DEBUG_ON (unlikely(gc_debug_on))\n#define GC_DEBUG_PRINTF(str,...) if (GC_DEBUG_ON) fprintf(gc_data_file, str, __VA_ARGS__);\n#define GC_DEBUG_PRINT(str) if (GC_DEBUG_ON) fprintf(gc_data_file, str);\n#define GC_DEBUG_SET_SOURCE if (GC_DEBUG_ON) ruby_set_current_source();\n#else\n#define GC_DEBUG_PRINTF(str,...) ;\n#define GC_DEBUG_PRINT(str) ;\n#define GC_DEBUG_ON (0)\n#define GC_DEBUG_SET_SOURCE\n#endif /* GC_DEBUG */\n\nVALUE rb_newobj_eden();\nVALUE rb_newobj_longlife();\n\n/* Legacy gem compatibility only. Do not use. */\nVALUE rb_newobj();\n\n// Default allocator\n#define NEWOBJ(obj,type) type *obj = (type*)rb_newobj_eden()\n\n// Specific allocators\n#define NEWOBJ_LONGLIFE(obj,type) type *obj = (type*)rb_newobj_longlife()\n#define NEWOBJ_EDEN(obj,type) type *obj = (type*)rb_newobj_eden()\n\n#define OBJSETUP(obj,c,t) do {\\\n    RBASIC(obj)->flags = (t | (RBASIC(obj)->flags & (FL_MOVE|FL_LONGLIFE)));\\\n    RBASIC(obj)->klass = (c);\\\n    if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\\\n} while (0)\n\n#define CLONESETUP(clone,obj) do {\\\n    OBJSETUP(clone,rb_singleton_class_clone((VALUE)obj),RBASIC(obj)->flags);\\\n    rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\\\n    if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)clone,(VALUE)obj);\\\n} while (0)\n#define DUPSETUP(dup,obj) do {\\\n    OBJSETUP(dup,rb_obj_class(obj),(RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT));\\\n    if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)dup,(VALUE)obj);\\\n} while (0)\n\nstruct RBasic {\n    unsigned long flags;\n    VALUE klass;\n};\n\nstruct RObject {\n    struct RBasic basic;\n    struct st_table *iv_tbl;\n};\n\nstruct RClass {\n    struct RBasic basic;\n    struct st_table *iv_tbl;\n    struct st_table *m_tbl;\n    VALUE super;\n};\n#define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)\n#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)\n#define RCLASS_SUPER(c) (RCLASS(c)->super)\n#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)\n#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)\n#define RMODULE_SUPER(m) RCLASS_SUPER(m)\n\nstruct RFloat {\n    struct RBasic basic;\n    double value;\n};\n#define RFLOAT_VALUE(v) (RFLOAT(v)->value)\n\n#define ELTS_SHARED FL_USER2\n\nstruct RString {\n    struct RBasic basic;\n    long len;\n    char *ptr;\n    union {\n\tlong capa;\n\tVALUE shared;\n    } aux;\n};\n#define RSTRING_PTR(s) (RSTRING(s)->ptr)\n#define RSTRING_LEN(s) (RSTRING(s)->len)\n#define RSTRING_END(s) (RSTRING_PTR(s)+RSTRING_LEN(s))\n\nstruct RArray {\n    struct RBasic basic;\n    long len;\n    union {\n\tlong capa;\n\tVALUE shared;\n    } aux;\n    VALUE *ptr;\n};\n#define RARRAY_PTR(s) (RARRAY(s)->ptr)\n#define RARRAY_LEN(s) (RARRAY(s)->len)\n\nstruct RRegexp {\n    struct RBasic basic;\n    struct re_pattern_buffer *ptr;\n    long len;\n    char *str;\n};\n#define RREGEXP_SRC_PTR(r) (RREGEXP(r)->src)\n#define RREGEXP_SRC_LEN(r) (RREGEXP(r)->len)\n\nstruct RHash {\n    struct RBasic basic;\n    struct st_table *tbl;\n    int iter_lev;\n    VALUE ifnone;\n};\n#define RHASH_TBL(h) (RHASH(h)->tbl)\n#define RHASH_ITER_LEV(h) (RHASH(h)->iter_lev)\n#define RHASH_IFNONE(h) (RHASH(h)->ifnone)\n#define RHASH_SIZE(h) (RHASH(h)->tbl->num_entries)\n#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)\n\nstruct RFile {\n    struct RBasic basic;\n    struct rb_io_t *fptr;\n};\n\nstruct RData {\n    struct RBasic basic;\n    void (*dmark) _((void*));\n    void (*dfree) _((void*));\n    void *data;\n};\n\n#define DATA_PTR(dta) (RDATA(dta)->data)\n\n/*\n#define RUBY_DATA_FUNC(func) ((void (*)_((void*)))func)\n*/\ntypedef void (*RUBY_DATA_FUNC) _((void*));\n\nVALUE rb_data_object_alloc _((VALUE,void*,RUBY_DATA_FUNC,RUBY_DATA_FUNC));\n\n#define Data_Wrap_Struct(klass,mark,free,sval)\\\n    rb_data_object_alloc(klass,sval,(RUBY_DATA_FUNC)mark,(RUBY_DATA_FUNC)free)\n\n#define Data_Make_Struct(klass,type,mark,free,sval) (\\\n    sval = ALLOC(type),\\\n    memset(sval, 0, sizeof(type)),\\\n    Data_Wrap_Struct(klass,mark,free,sval)\\\n)\n\n#define Data_Get_Struct(obj,type,sval) do {\\\n    Check_Type(obj, T_DATA); \\\n    sval = (type*)DATA_PTR(obj);\\\n} while (0)\n\nstruct RStruct {\n    struct RBasic basic;\n    long len;\n    VALUE *ptr;\n};\n#define RSTRUCT_LEN(st) (RSTRUCT(st)->len)\n#define RSTRUCT_PTR(st) (RSTRUCT(st)->ptr)\n\nstruct RBignum {\n    struct RBasic basic;\n    char sign;\n    long len;\n    void *digits;\n};\n#define RBIGNUM_SIGN(b)       (RBIGNUM(b)->sign)\n#define RBIGNUM_SET_SIGN(b,s) (RBIGNUM(b)->sign = (s))\n#define RBIGNUM_POSITIVE_P(b) RBIGNUM_SIGN(b)\n#define RBIGNUM_NEGATIVE_P(b) (!RBIGNUM_SIGN(b))\n#define RBIGNUM_LEN(b)        (RBIGNUM(b)->len)\n#define RBIGNUM_DIGITS(b)     (RBIGNUM(b)->digits)\n\n#define R_CAST(st)   (struct st*)\n#define RBASIC(obj)  (R_CAST(RBasic)(obj))\n#define ROBJECT(obj) (R_CAST(RObject)(obj))\n#define RCLASS(obj)  (R_CAST(RClass)(obj))\n#define RMODULE(obj) RCLASS(obj)\n#define RFLOAT(obj)  (R_CAST(RFloat)(obj))\n#define RSTRING(obj) (R_CAST(RString)(obj))\n#define RREGEXP(obj) (R_CAST(RRegexp)(obj))\n#define RARRAY(obj)  (R_CAST(RArray)(obj))\n#define RHASH(obj)   (R_CAST(RHash)(obj))\n#define RDATA(obj)   (R_CAST(RData)(obj))\n#define RSTRUCT(obj) (R_CAST(RStruct)(obj))\n#define RBIGNUM(obj) (R_CAST(RBignum)(obj))\n#define RFILE(obj)   (R_CAST(RFile)(obj))\n\n#define FL_SINGLETON FL_USER0\n#define FL_LONGLIFE       (1<<6)\n#define FL_FINALIZE       (1<<7)\n#define FL_TAINT          (1<<8)\n#define FL_EXIVAR         (1<<9)\n#define FL_FREEZE         (1<<10)\n#define FL_REMEMBERED_SET (1<<11)\n#define FL_MOVE           (1<<12)\n\n#define FL_USHIFT    13\n\n#define FL_USER0     (1<<(FL_USHIFT+0))\n#define FL_USER1     (1<<(FL_USHIFT+1))\n#define FL_USER2     (1<<(FL_USHIFT+2))\n#define FL_USER3     (1<<(FL_USHIFT+3))\n#define FL_USER4     (1<<(FL_USHIFT+4))\n#define FL_USER5     (1<<(FL_USHIFT+5))\n#define FL_USER6     (1<<(FL_USHIFT+6))\n\n#define FL_UMASK  (0xff<<FL_USHIFT)\n\n#define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x))\n\n#define FL_ABLE(x) (!SPECIAL_CONST_P(x))\n#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)\n#define FL_SET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags |= (f);} while (0)\n#define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0)\n#define FL_REVERSE(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags ^= (f);} while (0)\n\n#define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT)\n#define OBJ_TAINT(x) FL_SET((x), FL_TAINT)\n#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT;} while (0)\n\n#define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE)\n#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)\n#define OBJ_UNFREEZE(x) FL_UNSET((x), FL_FREEZE)\n\n#define OBJ_LONGLIVED(x) FL_TEST((x), FL_LONGLIFE)\n#define OBJ_LONGLIFE(x) FL_SET((x), FL_LONGLIFE)\n\n#define OBJ_MOVED(x) FL_TEST((x), FL_MOVE)\n#define OBJ_MOVE(x) FL_SET((x), FL_MOVE)\n\n#define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n))\n#define ALLOC(type) (type*)xmalloc(sizeof(type))\n#define REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n))\n\n#define ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n))\n\n#define MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))\n#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))\n#define MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))\n#define MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))\n\nvoid rb_obj_infect _((VALUE,VALUE));\n\ntypedef int ruby_glob_func(const char*,VALUE);\nvoid rb_glob _((const char*,void(*)(const char*,VALUE),VALUE));\nvoid rb_globi _((const char*,void(*)(const char*,VALUE),VALUE));\nint ruby_brace_expand _((const char*,int,ruby_glob_func*,VALUE));\nint ruby_brace_glob _((const char*,int,ruby_glob_func*,VALUE));\n\nVALUE rb_define_class _((const char*,VALUE));\nVALUE rb_define_module _((const char*));\nVALUE rb_define_class_under _((VALUE, const char*, VALUE));\nVALUE rb_define_module_under _((VALUE, const char*));\n\nvoid rb_include_module _((VALUE,VALUE));\nvoid rb_extend_object _((VALUE,VALUE));\n\nvoid rb_define_variable _((const char*,VALUE*));\nvoid rb_define_virtual_variable _((const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));\nvoid rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS)));\nint ruby_glob _((const char*,int,int(*)(const char*,VALUE),VALUE));\nint ruby_globi _((const char*,int,int(*)(const char*,VALUE),VALUE));\nvoid rb_define_readonly_variable _((const char*,VALUE*));\nvoid rb_define_const _((VALUE,const char*,VALUE));\nvoid rb_define_global_const _((const char*,VALUE));\n\n#define RUBY_METHOD_FUNC(func) ((VALUE (*)(ANYARGS))func)\nvoid rb_define_method _((VALUE,const char*,VALUE(*)(ANYARGS),int));\nvoid rb_define_module_function _((VALUE,const char*,VALUE(*)(ANYARGS),int));\nvoid rb_define_global_function _((const char*,VALUE(*)(ANYARGS),int));\n\nvoid rb_undef_method _((VALUE,const char*));\nvoid rb_define_alias _((VALUE,const char*,const char*));\nvoid rb_define_attr _((VALUE,const char*,int,int));\n\nvoid rb_global_variable _((VALUE*));\nvoid rb_gc_register_address _((VALUE*));\nvoid rb_gc_unregister_address _((VALUE*));\n\nVALUE rb_temp_enable_longlife();\nVALUE rb_temp_disable_longlife();\n\nint rb_gc_is_thread_marked _((VALUE));\n\nID rb_intern _((const char*));\nconst char *rb_id2name _((ID));\nID rb_to_id _((VALUE));\n\nconst char *rb_class2name _((VALUE));\nconst char *rb_obj_classname _((VALUE));\n\nvoid rb_p _((VALUE));\n\nVALUE rb_eval_string _((const char*));\nVALUE rb_eval_string_protect _((const char*, int*));\nVALUE rb_eval_string_wrap _((const char*, int*));\nVALUE rb_funcall __((VALUE, ID, int, ...));\nVALUE rb_funcall2 _((VALUE, ID, int, const VALUE*));\nVALUE rb_funcall3 _((VALUE, ID, int, const VALUE*));\nint rb_scan_args __((int, const VALUE*, const char*, ...));\nVALUE rb_call_super _((int, const VALUE*));\n\nVALUE rb_gv_set _((const char*, VALUE));\nVALUE rb_gv_get _((const char*));\nVALUE rb_iv_get _((VALUE, const char*));\nVALUE rb_iv_set _((VALUE, const char*, VALUE));\n\nVALUE rb_equal _((VALUE,VALUE));\n\nRUBY_EXTERN VALUE ruby_verbose, ruby_debug;\n\nNORETURN(void rb_raise __((VALUE, const char*, ...)));\nNORETURN(void rb_fatal __((const char*, ...)));\nNORETURN(void rb_bug __((const char*, ...)));\nNORETURN(void rb_sys_fail _((const char*)));\nNORETURN(void rb_iter_break _((void)));\nNORETURN(void rb_exit _((int)));\nNORETURN(void rb_notimplement _((void)));\n\nvoid rb_warning __((const char*, ...));\t\t/* reports if `-w' specified */\nvoid rb_sys_warning __((const char*, ...));\t/* reports if `-w' specified */\nvoid rb_warn __((const char*, ...));\t\t/* reports always */\n\ntypedef VALUE rb_block_call_func _((VALUE, VALUE));\n\nVALUE rb_each _((VALUE));\nVALUE rb_yield _((VALUE));\nVALUE rb_yield_values __((int n, ...));\nVALUE rb_yield_splat _((VALUE));\nint rb_block_given_p _((void));\nvoid rb_need_block _((void));\nVALUE rb_iterate _((VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE));\nVALUE rb_rescue _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));\nVALUE rb_rescue2 __((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...));\nVALUE rb_ensure _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));\nVALUE rb_catch _((const char*,VALUE(*)(ANYARGS),VALUE));\nNORETURN(void rb_throw _((const char*,VALUE)));\n\nVALUE rb_require _((const char*));\n\n#ifdef __ia64\nvoid ruby_init_stack(VALUE*, void*);\n#define RUBY_INIT_STACK \\\n    VALUE variable_in_this_stack_frame; \\\n    ruby_init_stack(&variable_in_this_stack_frame, rb_ia64_bsp());\n#else\nvoid ruby_init_stack(VALUE*);\n#define RUBY_INIT_STACK \\\n    VALUE variable_in_this_stack_frame; \\\n    ruby_init_stack(&variable_in_this_stack_frame);\n#endif\nvoid ruby_init _((void));\nvoid ruby_options _((int, char**));\nNORETURN(void ruby_run _((void)));\n\nRUBY_EXTERN VALUE rb_mKernel;\nRUBY_EXTERN VALUE rb_mComparable;\nRUBY_EXTERN VALUE rb_mEnumerable;\nRUBY_EXTERN VALUE rb_mPrecision;\nRUBY_EXTERN VALUE rb_mErrno;\nRUBY_EXTERN VALUE rb_mFileTest;\nRUBY_EXTERN VALUE rb_mGC;\nRUBY_EXTERN VALUE rb_mMath;\nRUBY_EXTERN VALUE rb_mProcess;\n\nRUBY_EXTERN VALUE rb_cObject;\nRUBY_EXTERN VALUE rb_cArray;\nRUBY_EXTERN VALUE rb_cBignum;\nRUBY_EXTERN VALUE rb_cBinding;\nRUBY_EXTERN VALUE rb_cClass;\nRUBY_EXTERN VALUE rb_cCont;\nRUBY_EXTERN VALUE rb_cDir;\nRUBY_EXTERN VALUE rb_cData;\nRUBY_EXTERN VALUE rb_cEnumerator;\nRUBY_EXTERN VALUE rb_cFalseClass;\nRUBY_EXTERN VALUE rb_cFile;\nRUBY_EXTERN VALUE rb_cFixnum;\nRUBY_EXTERN VALUE rb_cFloat;\nRUBY_EXTERN VALUE rb_cHash;\nRUBY_EXTERN VALUE rb_cInteger;\nRUBY_EXTERN VALUE rb_cIO;\nRUBY_EXTERN VALUE rb_cMatch;\nRUBY_EXTERN VALUE rb_cMethod;\nRUBY_EXTERN VALUE rb_cModule;\nRUBY_EXTERN VALUE rb_cNameErrorMesg;\nRUBY_EXTERN VALUE rb_cNilClass;\nRUBY_EXTERN VALUE rb_cNumeric;\nRUBY_EXTERN VALUE rb_cProc;\nRUBY_EXTERN VALUE rb_cRange;\nRUBY_EXTERN VALUE rb_cRegexp;\nRUBY_EXTERN VALUE rb_cStat;\nRUBY_EXTERN VALUE rb_cString;\nRUBY_EXTERN VALUE rb_cStruct;\nRUBY_EXTERN VALUE rb_cSymbol;\nRUBY_EXTERN VALUE rb_cThread;\nRUBY_EXTERN VALUE rb_cTime;\nRUBY_EXTERN VALUE rb_cTrueClass;\nRUBY_EXTERN VALUE rb_cUnboundMethod;\n\nRUBY_EXTERN VALUE rb_eException;\nRUBY_EXTERN VALUE rb_eStandardError;\nRUBY_EXTERN VALUE rb_eSystemExit;\nRUBY_EXTERN VALUE rb_eInterrupt;\nRUBY_EXTERN VALUE rb_eSignal;\nRUBY_EXTERN VALUE rb_eFatal;\nRUBY_EXTERN VALUE rb_eArgError;\nRUBY_EXTERN VALUE rb_eEOFError;\nRUBY_EXTERN VALUE rb_eIndexError;\nRUBY_EXTERN VALUE rb_eStopIteration;\nRUBY_EXTERN VALUE rb_eRangeError;\nRUBY_EXTERN VALUE rb_eIOError;\nRUBY_EXTERN VALUE rb_eRuntimeError;\nRUBY_EXTERN VALUE rb_eSecurityError;\nRUBY_EXTERN VALUE rb_eSystemCallError;\nRUBY_EXTERN VALUE rb_eThreadError;\nRUBY_EXTERN VALUE rb_eTypeError;\nRUBY_EXTERN VALUE rb_eZeroDivError;\nRUBY_EXTERN VALUE rb_eNotImpError;\nRUBY_EXTERN VALUE rb_eNoMemError;\nRUBY_EXTERN VALUE rb_eNoMethodError;\nRUBY_EXTERN VALUE rb_eFloatDomainError;\nRUBY_EXTERN VALUE rb_eLocalJumpError;\nRUBY_EXTERN VALUE rb_eSysStackError;\nRUBY_EXTERN VALUE rb_eRegexpError;\n\nRUBY_EXTERN VALUE rb_eScriptError;\nRUBY_EXTERN VALUE rb_eNameError;\nRUBY_EXTERN VALUE rb_eSyntaxError;\nRUBY_EXTERN VALUE rb_eLoadError;\n\nRUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;\nRUBY_EXTERN VALUE ruby_errinfo;\n\nstatic inline VALUE\n#if defined(HAVE_PROTOTYPES)\nrb_class_of(VALUE obj)\n#else\nrb_class_of(obj)\n    VALUE obj;\n#endif\n{\n    if (FIXNUM_P(obj)) return rb_cFixnum;\n    if (obj == Qnil) return rb_cNilClass;\n    if (obj == Qfalse) return rb_cFalseClass;\n    if (obj == Qtrue) return rb_cTrueClass;\n    if (SYMBOL_P(obj)) return rb_cSymbol;\n\n    return RBASIC(obj)->klass;\n}\n\nstatic inline int\n#if defined(HAVE_PROTOTYPES)\nrb_type(VALUE obj)\n#else\nrb_type(obj)\n   VALUE obj;\n#endif\n{\n    if (FIXNUM_P(obj)) return T_FIXNUM;\n    if (obj == Qnil) return T_NIL;\n    if (obj == Qfalse) return T_FALSE;\n    if (obj == Qtrue) return T_TRUE;\n    if (obj == Qundef) return T_UNDEF;\n    if (SYMBOL_P(obj)) return T_SYMBOL;\n    return BUILTIN_TYPE(obj);\n}\n\nstatic inline int\n#if defined(HAVE_PROTOTYPES)\nrb_special_const_p(VALUE obj)\n#else\nrb_special_const_p(obj)\n    VALUE obj;\n#endif\n{\n    if (SPECIAL_CONST_P(obj)) return Qtrue;\n    return Qfalse;\n}\n\n#include \"missing.h\"\n#include \"intern.h\"\n\n#if defined(EXTLIB) && defined(USE_DLN_A_OUT)\n/* hook for external modules */\nstatic char *dln_libs_to_be_linked[] = { EXTLIB, 0 };\n#endif\n\n#if defined(HAVE_LIBPTHREAD)\n#ifdef HAVE_PTHREAD_H\n#include <pthread.h>\n#endif\ntypedef pthread_t rb_nativethread_t;\n# define NATIVETHREAD_CURRENT() pthread_self()\n# define NATIVETHREAD_EQUAL(t1,t2) pthread_equal((t1),(t2))\n# define HAVE_NATIVETHREAD\n\n# define NATIVETHREAD_KILL(th,sig) pthread_kill((th),(sig))\n# define HAVE_NATIVETHREAD_KILL\n#elif defined(_WIN32) || defined(_WIN32_WCE)\ntypedef DWORD rb_nativethread_t;\n# define NATIVETHREAD_CURRENT() GetCurrentThreadId()\n# define NATIVETHREAD_EQUAL(t1,t2) ((t1) == (t2))\n# define HAVE_NATIVETHREAD\n#endif\n#ifdef HAVE_NATIVETHREAD\nint is_ruby_native_thread _((void));\n#else\n#define is_ruby_native_thread() (1)\n#endif\n#ifdef HAVE_NATIVETHREAD_KILL\nvoid ruby_native_thread_kill _((int));\n#endif\n\n#if defined(__cplusplus)\n#if 0\n{ /* satisfy cc-mode */\n#endif\n}  /* extern \"C\" { */\n#endif\n\n#endif /* ifndef RUBY_H */\n"
  },
  {
    "path": "rubyio.h",
    "content": "/**********************************************************************\n\n  rubyio.h -\n\n  $Author$\n  $Date$\n  created at: Fri Nov 12 16:47:09 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef RUBYIO_H\n#define RUBYIO_H\n\n#include <stdio.h>\n#include <errno.h>\n\n#if defined(HAVE_STDIO_EXT_H)\n#include <stdio_ext.h>\n#endif\n\ntypedef struct rb_io_t {\n    FILE *f;\t\t\t/* stdio ptr for read/write */\n    FILE *f2;\t\t\t/* additional ptr for rw pipes */\n    int mode;\t\t\t/* mode flags */\n    int pid;\t\t\t/* child's pid (for pipes) */\n    int lineno;\t\t\t/* number of lines read */\n    char *path;\t\t\t/* pathname for file */\n    void (*finalize) _((struct rb_io_t*,int)); /* finalize proc */\n} rb_io_t;\n\n#define HAVE_RB_IO_T 1\n#define OpenFile rb_io_t\t/* for backward compatibility */\n\n#define FMODE_READABLE  1\n#define FMODE_WRITABLE  2\n#define FMODE_READWRITE 3\n#define FMODE_APPEND   64\n#define FMODE_CREATE  128\n#define FMODE_BINMODE   4\n#define FMODE_SYNC      8\n#define FMODE_WBUF     16\n#define FMODE_RBUF     32\n#define FMODE_WSPLIT  0x200\n#define FMODE_WSPLIT_INITIALIZED  0x400\n\n#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)\n\n#define MakeOpenFile(obj, fp) do {\\\n    if (RFILE(obj)->fptr) {\\\n\trb_io_close(obj);\\\n\tfree(RFILE(obj)->fptr);\\\n\tRFILE(obj)->fptr = 0;\\\n    }\\\n    fp = 0;\\\n    fp = RFILE(obj)->fptr = ALLOC(rb_io_t);\\\n    fp->f = fp->f2 = NULL;\\\n    fp->mode = 0;\\\n    fp->pid = 0;\\\n    fp->lineno = 0;\\\n    fp->path = NULL;\\\n    fp->finalize = 0;\\\n} while (0)\n\n#define GetReadFile(fptr) ((fptr)->f)\n#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f)\n\nFILE *rb_fopen _((const char*, const char*));\nFILE *rb_fdopen _((int, const char*));\nint rb_getc _((FILE*));\nlong rb_io_fread _((char *, long, FILE *));\nlong rb_io_fwrite _((const char *, long, FILE *));\nint  rb_io_mode_flags _((const char*));\nint  rb_io_modenum_flags _((int));\nvoid rb_io_check_writable _((rb_io_t*));\nvoid rb_io_check_readable _((rb_io_t*));\nvoid rb_io_fptr_finalize _((rb_io_t*));\nvoid rb_io_synchronized _((rb_io_t*));\nvoid rb_io_check_initialized _((rb_io_t*));\nvoid rb_io_check_closed _((rb_io_t*));\nint rb_io_wait_readable _((int));\nint rb_io_wait_writable _((int));\nvoid rb_io_set_nonblock(rb_io_t *fptr);\n\nVALUE rb_io_taint_check _((VALUE));\nNORETURN(void rb_eof_error _((void)));\n\nvoid rb_read_check _((FILE*));\nint rb_read_pending _((FILE*));\n#endif\n"
  },
  {
    "path": "rubysig.h",
    "content": "/**********************************************************************\n\n  rubysig.h -\n\n  $Author$\n  $Date$\n  created at: Wed Aug 16 01:15:38 JST 1995\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef SIG_H\n#define SIG_H\n\n#include <errno.h>\n\n#if defined __ppc__ || defined __powerpc__ || \\\n    defined __ppc64__ || defined __powerpc64__\n#define __anyPowerPC__ 1  /* for compatibility with older gcc versions */\n#endif\n\n/* STACK_WIPE_SITES determines where attempts are made to exorcise\n   \"ghost object refereces\" from the stack and how the stack is cleared:\n   \n   0x*001 -->  wipe stack just after every thread_switch\n   0x*002 -->  wipe stack just after every EXEC_TAG()\n   0x*004 -->  wipe stack in CHECK_INTS\n   0x*010 -->  wipe stack in while & until loops\n   0x*020 -->  wipe stack before yield() in iterators and outside eval.c\n   0x*040 -->  wipe stack on catch and thread save context\n   0x*100 -->  update stack extent on each object allocation\n   0x*200 -->  update stack extent on each object reallocation\n   0x*400 -->  update stack extent during GC marking passes\n   0x*800 -->  update stack extent on each throw (use with 0x040)\n   0x1000 -->  use inline assembly code for x86, PowerPC, or ARM CPUs\n\n   0x0*** -->  do not even call rb_wipe_stack()\n   0x2*** -->  call dummy rb_wipe_stack() (for debugging and profiling)\n   0x4*** -->  safe, portable stack clearing in memory allocated with alloca\n   0x6*** -->  use faster, but less safe stack clearing in unallocated stack\n   0x8*** -->  use faster, but less safe stack clearing (with inline code)\n   \n   for most effective gc use 0x*707\n   for fastest micro-benchmarking use 0x0000\n   0x*770 prevents almost all memory leaks caused by ghost references\n   without adding much overhead for stack clearing.\n   Other good trade offs are 0x*270, 0x*703, 0x*303 or even 0x*03\n   \n   In general, you may lessen the default -mpreferred-stack-boundary\n   only if using less safe stack clearing (0x6***).  Lessening the\n   stack alignment with portable stack clearing (0x4***) may fail to clear \n   all ghost references off the stack.\n   \n   When using 0x6*** or 0x8***, the compiler could insert \n   stack push(s) between reading the stack pointer and clearing \n   the ghost references.  The register(s) pushed will be\n   cleared by the rb_gc_stack_wipe(), typically resulting in a segfault\n   or an interpreter hang.\n   \n   STACK_WIPE_SITES of 0x8770 works well compiled with gcc on most machines\n   using the recommended CFLAGS=\"-O2 -fno-stack-protector\".  However...\n   If it hangs or crashes for you, try changing STACK_WIPE_SITES to 0x4770\n   and please report your details.  i.e. CFLAGS, compiler, version, CPU\n   \n   Note that it is redundant to wipe_stack in looping constructs if \n   also doing so in CHECK_INTS.  It is also redundant to wipe_stack on\n   each thread_switch if wiping after every thread save context.\n*/\n#ifndef STACK_WIPE_SITES\n# ifdef __x86_64__     /* deal with \"red zone\" by not inlining stack clearing */\n#  define STACK_WIPE_SITES  0x6770\n# elif defined __anyPowerPC__   /* On any PowerPC, deal with... */\n#  define STACK_WIPE_SITES  0x7764   /* red zone & alloc(0) doesn't return sp */\n# else\n#  define STACK_WIPE_SITES  0x8770 /*normal case, use 0x4770 if problems arise*/\n# endif\n#endif\n\n#if (STACK_WIPE_SITES & 0x14) == 0x14\n#warning  wiping stack in CHECK_INTS makes wiping in loops redundant\n#endif\n#if (STACK_WIPE_SITES & 0x41) == 0x41\n#warning  wiping stack after thread save makes wiping on thread_switch redundant\n#endif\n\n#define STACK_WIPE_METHOD (STACK_WIPE_SITES>>13)\n\n#ifdef _WIN32\ntypedef LONG rb_atomic_t;\n\n# define ATOMIC_TEST(var) InterlockedExchange(&(var), 0)\n# define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))\n# define ATOMIC_INC(var) InterlockedIncrement(&(var))\n# define ATOMIC_DEC(var) InterlockedDecrement(&(var))\n\n/* Windows doesn't allow interrupt while system calls */\n# define TRAP_BEG do {\\\n    int saved_errno = 0;\\\n    rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1)\n# define TRAP_END\\\n    ATOMIC_SET(rb_trap_immediate, trap_immediate);\\\n    saved_errno = errno;\\\n    CHECK_INTS;\\\n    errno = saved_errno;\\\n} while (0)\n# define RUBY_CRITICAL(statements) do {\\\n    rb_w32_enter_critical();\\\n    statements;\\\n    rb_w32_leave_critical();\\\n} while (0)\n#else\ntypedef int rb_atomic_t;\n\n# define ATOMIC_TEST(var) ((var) ? ((var) = 0, 1) : 0)\n# define ATOMIC_SET(var, val) ((var) = (val))\n# define ATOMIC_INC(var) (++(var))\n# define ATOMIC_DEC(var) (--(var))\n\n# define TRAP_BEG do {\\\n    int saved_errno = 0;\\\n    int trap_immediate = rb_trap_immediate;\\\n    rb_trap_immediate = 1\n# define TRAP_END rb_trap_immediate = trap_immediate;\\\n    saved_errno = errno;\\\n    CHECK_INTS;\\\n    errno = saved_errno;\\\n} while (0)\n\n# define RUBY_CRITICAL(statements) do {\\\n    int trap_immediate = rb_trap_immediate;\\\n    rb_trap_immediate = 0;\\\n    statements;\\\n    rb_trap_immediate = trap_immediate;\\\n} while (0)\n#endif\nRUBY_EXTERN rb_atomic_t rb_trap_immediate;\n\nRUBY_EXTERN int rb_prohibit_interrupt;\n#define DEFER_INTS (rb_prohibit_interrupt++)\n#define ALLOW_INTS do {\\\n    rb_prohibit_interrupt--;\\\n    CHECK_INTS;\\\n} while (0)\n#define ENABLE_INTS (rb_prohibit_interrupt--)\n\nVALUE rb_with_disable_interrupt _((VALUE(*)(ANYARGS),VALUE));\n\nRUBY_EXTERN rb_atomic_t rb_trap_pending;\nvoid rb_trap_restore_mask _((void));\n\nRUBY_EXTERN int rb_thread_critical;\nvoid rb_thread_schedule _((void));\n\nRUBY_EXTERN int rb_gc_stack_grow_direction;  /* -1 for down or 1 for up */\n\n#if STACK_GROW_DIRECTION > 0\n\n/* clear stack space between end and sp (not including *sp) */\n#define __stack_zero(end,sp)  __stack_zero_up(end,sp)\n\n/* true if top has grown past limit, i.e. top deeper than limit */\n#define __stack_past(limit,top)  __stack_past_up(limit,top)\n\n/* depth of mid below stack top */\n#define __stack_depth(top,mid)   __stack_depth_up(top,mid)\n\n/* stack pointer top adjusted to include depth more items */\n#define __stack_grow(top,depth)  __stack_grow_up(top,depth)\n\n\n#elif STACK_GROW_DIRECTION < 0\n#define __stack_zero(end,sp)  __stack_zero_down(end,sp)\n#define __stack_past(limit,top)  __stack_past_down(limit,top)\n#define __stack_depth(top,mid)   __stack_depth_down(top,mid)\n#define __stack_grow(top,depth)  __stack_grow_down(top,depth)\n\n#else  /* limp along if stack direction can't be determined at compile time */\n#define __stack_zero(end,sp) if (rb_gc_stack_grow_direction<0) \\\n        __stack_zero_down(end,sp); else __stack_zero_up(end,sp);\n#define __stack_past(limit,top)  (rb_gc_stack_grow_direction<0 ? \\\n                      __stack_past_down(limit,top) : __stack_past_up(limit,top))\n#define __stack_depth(top,mid) (rb_gc_stack_grow_direction<0 ? \\\n                       __stack_depth_down(top,mid) : __stack_depth_up(top,mid))\n#define __stack_grow(top,depth) (rb_gc_stack_grow_direction<0 ? \\\n                      __stack_grow_down(top,depth) : __stack_grow_up(top,depth))\n#endif\n \n#define __stack_zero_up(end,sp)  while (end >= ++sp) *sp=0\n#define __stack_past_up(limit,top)  ((limit) < (top))\n#define __stack_depth_up(top,mid) ((top) - (mid))\n#define __stack_grow_up(top,depth) ((top)+(depth))\n\n#define __stack_zero_down(end,sp)  while (end <= --sp) *sp=0\n#define __stack_past_down(limit,top)  ((limit) > (top))\n#define __stack_depth_down(top,mid) ((mid) - (top))\n#define __stack_grow_down(top,depth) ((top)-(depth))\n\n/* Make alloca work the best possible way.  */\n#ifdef __GNUC__\n# ifndef atarist\n#  ifndef alloca\n#   define alloca __builtin_alloca\n#  endif\n# endif /* atarist */\n\n# define nativeAllocA __builtin_alloca\n\n/* use assembly to get stack pointer quickly */\n# if STACK_WIPE_SITES & 0x1000\n#  define __defspfn(asmb)  \\\nstatic inline VALUE *__sp(void) __attribute__((always_inline)); \\\nstatic inline VALUE *__sp(void) \\\n{ \\\n  VALUE *sp; asm(asmb); \\\n  return sp; \\\n}\n#  ifdef __anyPowerPC__\n__defspfn(\"addi %0, r1, 0\": \"=r\"(sp))\n#  elif defined  __i386__\n__defspfn(\"movl %%esp, %0\": \"=r\"(sp))\n#  elif defined __x86_64__\n#warn ===> x86_64 inline assembler is known to crash -- change STACK_WIPE_SITES\n__defspfn(\"movq %%rsp, %0\": \"=r\"(sp))\n#  elif __arm__\n__defspfn(\"mov %0, sp\": \"=r\"(sp))\n#  else\n#   define __sp()  ((VALUE *)__builtin_alloca(0))\n#   warning No assembly version of __sp() defined for this CPU.\n#  endif\n# else\n#  define __sp()  ((VALUE *)__builtin_alloca(0))\n# endif\n\n#else  // not GNUC\n\n# ifdef HAVE_ALLOCA_H\n#  include <alloca.h>\n# else\n#  ifndef _AIX\n#   ifndef alloca /* predefined by HP cc +Olibcalls */\nvoid *alloca ();\n#   endif\n#  endif /* AIX */\n# endif /* HAVE_ALLOCA_H */\n\n# if STACK_WIPE_SITES & 0x1000\n#  warning No assembly versions of __sp() defined for this compiler.\n# endif\n# if HAVE_ALLOCA\n#  define __sp()  ((VALUE *)alloca(0))\n#  define nativeAllocA alloca\n# else\nRUBY_EXTERN VALUE *__sp(void);\n#  if STACK_WIPE_SITES\n#   define STACK_WIPE_SITES 0\n#   warning Disabled Stack Wiping because there is no native alloca()\n#  endif\n# endif\n#endif /* __GNUC__ */\n\n\n/*\n  Zero memory that was (recently) part of the stack, but is no longer.\n  Invoke when stack is deep to mark its extent and when it's shallow to wipe it.\n*/\n#if STACK_WIPE_METHOD == 0\n#define rb_gc_wipe_stack() ((void)0)\n#elif STACK_WIPE_METHOD == 4\n#define rb_gc_wipe_stack() do { \\\n  if (rb_curr_thread) {     \\\n    VALUE *end = rb_curr_thread->gc_stack_end;  \\\n    VALUE *sp = __sp();            \\\n    rb_curr_thread->gc_stack_end = sp;          \\\n    __stack_zero(end, sp);   \\\n  } \\\n} while (0)\n#else\nRUBY_EXTERN void rb_gc_wipe_stack(void);\n#endif\n\n/*\n  Update our record of maximum stack extent without zeroing unused stack\n*/\n#define rb_gc_update_stack_extent() do { \\\n    VALUE *sp = __sp(); \\\n    if (rb_curr_thread && __stack_past(rb_curr_thread->gc_stack_end, sp)) rb_curr_thread->gc_stack_end = sp; \\\n} while(0)\n\n\n#if STACK_WIPE_SITES & 4\n# define CHECK_INTS_wipe_stack()  rb_gc_wipe_stack()\n#else\n# define CHECK_INTS_wipe_stack()  (void)0\n#endif\n\n#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE)\nRUBY_EXTERN int rb_thread_pending;\n# define CHECK_INTS do {\\\n    CHECK_INTS_wipe_stack(); \\\n    if (!(rb_prohibit_interrupt || rb_thread_critical)) {\\\n        if (rb_thread_pending) rb_thread_schedule();\\\n\tif (rb_trap_pending) rb_trap_exec();\\\n    }\\\n} while (0)\n#else\n/* pseudo preemptive thread switching */\nRUBY_EXTERN int rb_thread_tick;\n#define THREAD_TICK 500\n#define CHECK_INTS do {\\\n    CHECK_INTS_wipe_stack(); \\\n    if (!(rb_prohibit_interrupt || rb_thread_critical)) {\\\n\tif (rb_thread_tick-- <= 0) {\\\n\t    rb_thread_tick = THREAD_TICK;\\\n            rb_thread_schedule();\\\n\t}\\\n        if (rb_trap_pending) rb_trap_exec();\\\n    }\\\n} while (0)\n#endif\n\n#endif\n"
  },
  {
    "path": "rubytest.rb",
    "content": "#! ./miniruby\n\nexit if defined?(CROSS_COMPILING)\nload './rbconfig.rb'\ninclude Config\n\nruby = \"./#{CONFIG['ruby_install_name']}#{CONFIG['EXEEXT']}\"\nunless File.exist? ruby\n  print \"#{ruby} is not found.\\n\"\n  print \"Try `make' first, then `make test', please.\\n\"\n  exit false\nend\n\nif File.exist? CONFIG['LIBRUBY_SO']\n  case RUBY_PLATFORM\n  when /-hpux/\n    dldpath = \"SHLIB_PATH\"\n  when /-aix/\n    dldpath = \"LIBPATH\"\n  when /-beos/\n    dldpath = \"LIBRARY_PATH\"\n  when /-darwin/\n    dldpath = \"DYLD_LIBRARY_PATH\"\n  else\n    dldpath = \"LD_LIBRARY_PATH\"\n  end\n  x = ENV[dldpath]\n  x = x ? \".:\"+x : \".\"\n  ENV[dldpath] = x\nend\n\nif /linux/ =~ RUBY_PLATFORM and File.exist? CONFIG['LIBRUBY_SO']\n  ENV[\"LD_PRELOAD\"] = \"./#{CONFIG['LIBRUBY_SO']}\"\nend\n\n$stderr.reopen($stdout)\nerror = ''\n\nsrcdir = File.dirname(__FILE__)\n`#{ruby} -I#{srcdir}/lib #{srcdir}/sample/test.rb`.each do |line|\n  if line =~ /^end of test/\n    print \"test succeeded\\n\"\n    exit 0\n  end\n  error << line if line =~ %r:^(sample/test.rb|not):\nend\nprint error\nprint \"test failed\\n\"\nexit 1\n"
  },
  {
    "path": "runruby.rb",
    "content": "#!./miniruby\n\npure = true\nwhile arg = ARGV[0]\n  break ARGV.shift if arg == '--'\n  /\\A--([-\\w]+)(?:=(.*))?\\z/ =~ arg or break\n  arg, value = $1, $2\n  re = Regexp.new('\\A'+arg.gsub(/\\w+\\b/, '\\&\\\\w*')+'\\z', \"i\")\n  case\n  when re =~ \"srcdir\"\n    srcdir = value\n  when re =~ \"archdir\"\n    archdir = value\n  when re =~ \"extout\"\n    extout = value\n  when re =~ \"pure\"\n    pure = (value != \"no\")\n  when re =~ \"debugger\"\n    debugger = value ? (value.split unless value == \"no\") : %w\"gdb --args\"\n  else\n    break\n  end\n  ARGV.shift\nend\n\nsrcdir ||= File.dirname(__FILE__)\narchdir ||= '.'\n\nabs_archdir = File.expand_path(archdir)\n$:.unshift(abs_archdir)\n\nrequire 'rbconfig'\nconfig = RbConfig::CONFIG\n\nruby = File.join(archdir, config[\"RUBY_INSTALL_NAME\"]+config['EXEEXT'])\nunless File.exist?(ruby)\n  abort \"#{ruby} is not found.\\nTry `make' first, then `make test', please.\\n\"\nend\n\nlibs = [abs_archdir]\nif extout\n  abs_extout = File.expand_path(extout)\n  libs << File.expand_path(\"common\", abs_extout) << File.expand_path(RUBY_PLATFORM, abs_extout)\nend\nlibs << File.expand_path(\"lib\", srcdir)\nconfig[\"bindir\"] = abs_archdir\nENV[\"RUBY\"] = File.expand_path(ruby)\nENV[\"PATH\"] = [abs_archdir, ENV[\"PATH\"]].compact.join(File::PATH_SEPARATOR)\n\nif pure\n  libs << File.expand_path(\"ext\", srcdir) << \"-\"\nelsif e = ENV[\"RUBYLIB\"]\n  libs |= e.split(File::PATH_SEPARATOR)\nend\nENV[\"RUBYLIB\"] = $:.replace(libs).join(File::PATH_SEPARATOR)\n\nlibruby_so = File.join(abs_archdir, config['LIBRUBY_SO'])\nif File.file?(libruby_so)\n  if e = config['LIBPATHENV'] and !e.empty?\n    ENV[e] = [abs_archdir, ENV[e]].compact.join(File::PATH_SEPARATOR)\n  end\n  if /linux/ =~ RUBY_PLATFORM\n    ENV[\"LD_PRELOAD\"] = [libruby_so, ENV[\"LD_PRELOAD\"]].compact.join(' ')\n  end\nend\n\ncmd = [ruby]\ncmd << \"-rpurelib.rb\" if pure\ncmd.concat(ARGV)\ncmd.unshift(*debugger) if debugger\nexec(*cmd)\n"
  },
  {
    "path": "sample/README",
    "content": "README\t\tthis file\nbiorhythm.rb\tbiorhythm calculator\ncal.rb\t\tcal(1) clone\ncbreak.rb\tno echo done by ioctl\nclnt.rb\t\tsocket client\ndbmtest.rb\ttest for dbm\ndir.rb\t\tdirectory access\ndualstack-fetch.rb\tIPv6 demo\ndualstack-httpd.rb\tIPv6 demo\ndstore.rb\tobject database on dbm\neval.rb\t\tsimple evaluator\nexport.rb\tmethod access example\nexyacc.rb\textrace BNF from yacc file\nfact.rb\t\tfactorial calculator\nfib.awk\t\tFibonacci number (AWK)\nfib.pl\t\tFibonacci number (Perl)\nfib.py\t\tFibonacci number (Python)\nfib.rb\t\tFibonacci number (Ruby)\nfib.scm\t\tFibonacci number (Scheme)\nfreq.rb\t\tcount word occurrence\nfrom.rb\t\tscan mail spool\nfullpath.rb\tconvert ls -lR to fullpath format\ngetopts.test\ttest fot getopt.rb\nio.rb\t\tio test\nirb.rb\t\tinteractive ruby\nless.rb\t\tfront end for less\nlist.rb\t\tstupid object sample\nlist2.rb\tstupid object sample\nlist3.rb\tstupid object sample\nmine.rb\t\tsimple mine sweeper\t\nmkproto.rb\textract prototype from C\nmpart.rb\tsplit file int multi part\nmrshtest.rb\ttest marshal\nobserv.rb\tobserver design pattern sample\noccur.pl\tcount word occurrence (Perl)\noccur.rb\tcount word occurrence (Ruby)\noccur2.rb\tcount word occurrence - another style\nphilos.rb\tfamous dining philosophers\npi.rb\t\tcalculate PI\nrcs.awk\t\trandom character stereogram (AWK)\nrcs.rb\t\trandom character stereogram (Ruby)\nrcs.dat\t\tdata for random character stereogram\nrd2html.rb\trd (Ruby Document) to HTML translator\nregx.rb\t\tregular expression tester\nsieve.rb\tsieve of Eratosthenes\nsvr.rb\t\tsocket server\ntest.rb\t\ttest suite used by `make test'\ntime.rb\t\t/usr/bin/time clone\ntrojan.rb\tsimple tool to find file that may be trojan horse.\ntsvr.rb\t\tsocket server using thread\nuumerge.rb\tmerge files and uudecode them\n"
  },
  {
    "path": "sample/biorhythm.rb",
    "content": "#!/usr/local/bin/ruby\n#\n#               biorhythm.rb - \n#                       $Release Version: $\n#                       $Revision$\n#                       $Date$\n#                       by Yasuo OHBA(STAFS Development Room)\n#\n# --\n#\n#       \n#\n\n# probably based on:\n#\n# Newsgroups: comp.sources.misc,de.comp.sources.os9\n# From: fkk@stasys.sta.sub.org (Frank Kaefer)\n# Subject: v41i126:  br - Biorhythm v3.0, Part01/01\n# Message-ID: <1994Feb1.070616.15982@sparky.sterling.com>\n# Sender: kent@sparky.sterling.com (Kent Landfield)\n# Organization: Sterling Software\n# Date: Tue, 1 Feb 1994 07:06:16 GMT\n#\n# Posting-number: Volume 41, Issue 126\n# Archive-name: br/part01\n# Environment: basic, dos, os9\n\ninclude Math\nrequire \"date.rb\"\nrequire \"parsearg.rb\"\nrequire \"parsedate.rb\"\n\ndef usage()\n  print \"Usage:\\n\"\n  print \"biorhythm.rb [options]\\n\"\n  print \"  options...\\n\"\n  print \"    -D YYYYMMDD(birthday)     : use default values.\\n\"\n  print \"    --sdate | --date YYYYMMDD : use system date; use specified date.\\n\"\n  print \"    --birthday YYYYMMDD       : specifies your birthday.\\n\"\n  print \"    -v | -g                   : show values or graph.\\n\"\n  print \"    --days DAYS               : graph range (only in effect for graphs).\\n\"\n  print \"    --help                    : help\\n\"\nend\n$USAGE = 'usage'\n\ndef printHeader(y, m, d, p, w)\n  print \"\\n>>> Biorhythm <<<\\n\"\n  printf \"The birthday %04d.%02d.%02d is a %s\\n\", y, m, d, w\n  printf \"Age in days: [%d]\\n\\n\", p\nend\n\ndef getPosition(z)\n  pi = Math::PI\n  z = Integer(z)\n  phys = (50.0 * (1.0 + sin((z / 23.0 - (z / 23)) * 360.0 * pi / 180.0))).to_i\n  emot = (50.0 * (1.0 + sin((z / 28.0 - (z / 28)) * 360.0 * pi / 180.0))).to_i\n  geist =(50.0 * (1.0 + sin((z / 33.0 - (z / 33)) * 360.0 * pi / 180.0))).to_i\n  return phys, emot, geist\nend\n\ndef parsedate(s)\n  ParseDate::parsedate(s).values_at(0, 1, 2)\nend\n\ndef name_of_week(date)\n  Date::DAYNAMES[date.wday]\nend\n\n#\n# main program\n#\nparseArgs(0, nil, \"vg\", \"D:\", \"sdate\", \"date:\", \"birthday:\", \"days:\")\n\nif $OPT_D\n  dd = Date.today\n  bd = Date.new(*parsedate($OPT_D))\n  ausgabeart = \"g\"\nelse\n  if $OPT_birthday\n    bd = Date.new(*parsedate($OPT_birthday))\n  else\n    STDERR.print(\"Birthday                      (YYYYMMDD) : \")\n    unless (si = STDIN.gets.chop).empty?\n      bd = Date.new(*parsedate(si))\n    end\n  end\n  if !bd\n    STDERR.print \"BAD Input Birthday!!\\n\"\n    exit()\n  end\n\n  if $OPT_sdate\n    dd = Date.today\n  elsif $OPT_date\n    dd = Date.new(*parsedate($OPT_date))\n  else\n    STDERR.print(\"Date        [<RETURN> for Systemdate] (YYYYMMDD) : \")\n    unless (si = STDIN.gets.chop).empty?\n      dd = Date.new(*parsedate(si))\n    end\n  end\n  dd ||= Date.today\n\n  if $OPT_v\n    ausgabeart = \"v\"\n  elsif $OPT_g\n    ausgabeart = \"g\"\n  else\n    STDERR.print(\"Values for today or Graph  (v/g) [default g] : \")\n    ausgabeart = STDIN.gets.chop\n  end\nend\nif ausgabeart == \"v\"\n  printHeader(bd.year, bd.month, bd.day, dd - bd, name_of_week(bd))\n  print \"\\n\"\n  \n  phys, emot, geist = getPosition(dd - bd)\n  printf \"Biorhythm:   %04d.%02d.%02d\\n\", dd.year, dd.month, dd.day\n  printf \"Physical:    %d%%\\n\", phys\n  printf \"Emotional:   %d%%\\n\", emot\n  printf \"Mental:      %d%%\\n\", geist\n  print \"\\n\"\nelse\n  if $OPT_days\n    display_period = $OPT_days.to_i\n  elsif $OPT_D\n    display_period = 9\n  else\n    STDERR.printf(\"Graph for how many days     [default 10] : \")\n    display_period = STDIN.gets.chop\n    if display_period.empty?\n      display_period = 9\n    else\n      display_period = display_period.to_i - 1\n    end\n  end\n\n  printHeader(bd.year, bd.month, bd.day, dd - bd, name_of_week(bd))\n  print \"                     P=physical, E=emotional, M=mental\\n\"\n  print \"             -------------------------+-------------------------\\n\"\n  print \"                     Bad Condition    |    Good Condition\\n\"\n  print \"             -------------------------+-------------------------\\n\"\n  \n  (dd - bd).step(dd - bd + display_period) do |z|\n    phys, emot, geist = getPosition(z)\n    \n    printf \"%04d.%02d.%02d : \", dd.year, dd.month, dd.day\n    p = (phys / 2.0 + 0.5).to_i\n    e = (emot / 2.0 + 0.5).to_i\n    g = (geist / 2.0 + 0.5).to_i\n    graph = \".\" * 51\n    graph[25] = ?|\n    graph[p] = ?P\n    graph[e] = ?E\n    graph[g] = ?M\n    print graph, \"\\n\"\n    dd = dd + 1\n  end\n  print \"             -------------------------+-------------------------\\n\\n\"\nend\n"
  },
  {
    "path": "sample/cal.rb",
    "content": "#! /usr/bin/env ruby\n\n# cal.rb: Written by Tadayoshi Funaba 1998-2004,2006,2008\n# $Id: cal.rb,v 2.11 2008-01-06 08:42:17+09 tadf Exp $\n\nrequire 'date'\n\nclass Cal\n\n  START =\n    {\n    'cn' => Date::GREGORIAN, # China\n    'de' => 2342032,         # Germany (protestant states)\n    'dk' => 2342032,         # Denmark\n    'es' => 2299161,         # Spain\n    'fi' => 2361390,         # Finland\n    'fr' => 2299227,         # France\n    'gb' => 2361222,         # United Kingdom\n    'gr' => 2423868,         # Greece\n    'hu' => 2301004,         # Hungary\n    'it' => 2299161,         # Italy\n    'jp' => Date::GREGORIAN, # Japan\n    'no' => 2342032,         # Norway\n    'pl' => 2299161,         # Poland\n    'pt' => 2299161,         # Portugal\n    'ru' => 2421639,         # Russia\n    'se' => 2361390,         # Sweden\n    'us' => 2361222,         # United States\n    'os' => Date::JULIAN,    # (old style)\n    'ns' => Date::GREGORIAN  # (new style)\n  }\n\n  DEFAULT_START = 'gb'\n\n  def initialize\n    opt_j; opt_m; opt_t; opt_y; opt_c\n  end\n\n  def opt_j(flag=false) @opt_j = flag end\n  def opt_m(flag=false) @opt_m = flag end\n  def opt_t(flag=false) @opt_t = flag end\n  def opt_y(flag=false) @opt_y = flag end\n\n  def opt_c(arg=DEFAULT_START) @start = START[arg] end\n\n  def set_params\n    @dw = if @opt_j then 3 else 2 end\n    @mw = (@dw + 1) * 7 - 1\n    @mn = if @opt_j then 2 else 3 end\n    @tw = (@mw + 2) * @mn - 2\n    @k  = if @opt_m then 1 else 0 end\n    @da = if @opt_j then :yday else :mday end\n  end\n\n  def pict(y, m)\n    d = (1..31).detect{|x| Date.valid_date?(y, m, x, @start)}\n    fi = Date.new(y, m, d, @start)\n    fi -= (fi.jd - @k + 1) % 7\n\n    ve  = (fi..fi +  6).collect{|cu|\n      %w(S M Tu W Th F S)[cu.wday]\n    }\n    ve += (fi..fi + 41).collect{|cu|\n      if cu.mon == m then cu.send(@da) end.to_s\n    }\n\n    ve = ve.collect{|e| e.rjust(@dw)}\n\n    gr = group(ve, 7)\n    gr = trans(gr) if @opt_t\n    ta = gr.collect{|xs| xs.join(' ')}\n\n    ca = %w(January February March April May June July\n\t    August September October November December)[m - 1]\n    ca = ca + ' ' + y.to_s if !@opt_y\n    ca = ca.center(@mw)\n\n    ta.unshift(ca)\n  end\n\n  def group(xs, n)\n    (0..xs.size / n - 1).collect{|i| xs[i * n, n]}\n  end\n\n  def trans(xs)\n    (0..xs[0].size - 1).collect{|i| xs.collect{|x| x[i]}}\n  end\n\n  def stack(xs)\n    if xs.empty? then [] else xs[0] + stack(xs[1..-1]) end\n  end\n\n  def block(xs, n)\n    stack(group(xs, n).collect{|ys| trans(ys).collect{|zs| zs.join('  ')}})\n  end\n\n  def unlines(xs)\n    xs.collect{|x| x + \"\\n\"}.join\n  end\n\n  def monthly(y, m)\n    unlines(pict(y, m))\n  end\n\n  def addmon(y, m, n)\n    y, m = (y * 12 + (m - 1) + n).divmod(12)\n    return y, m + 1\n  end\n\n  def yearly(y)\n    y.to_s.center(@tw) + \"\\n\\n\" +\n      unlines(block((0..11).collect{|n| pict(*addmon(y, 1, n))}, @mn)) + \"\\n\"\n  end\n\n  def print(y, m)\n    set_params\n    if @opt_y then yearly(y) else monthly(y, m) end\n  end\n\nend\n\nif __FILE__ == $0\n\n  require 'getoptlong'\n\n  def usage\n    warn 'usage: cal [-c iso3166] [-jmty] [[month] year]'\n    exit 1\n  end\n\n  cal = Cal.new\n\n  begin\n    GetoptLong.new(['-c', GetoptLong::REQUIRED_ARGUMENT],\n\t\t   ['-j', GetoptLong::NO_ARGUMENT],\n\t\t   ['-m', GetoptLong::NO_ARGUMENT],\n\t\t   ['-t', GetoptLong::NO_ARGUMENT],\n\t\t   ['-y', GetoptLong::NO_ARGUMENT]).\n    each do |opt, arg|\n      case opt\n      when '-c'; cal.opt_c(arg) || raise\n      when '-j'; cal.opt_j(true)\n      when '-m'; cal.opt_m(true)\n      when '-t'; cal.opt_t(true)\n      when '-y'; cal.opt_y(true)\n      end\n    end\n  rescue\n    usage\n  end\n\n  y, m = ARGV.values_at(1, 0).compact.collect{|x| x.to_i}\n  cal.opt_y(true) if y && !m\n\n  to = Date.today\n  y ||= to.year\n  m ||= to.mon\n\n  usage unless m >= 1 && m <= 12\n  usage unless y >= -4712\n\n  print cal.print(y, m)\n\nend\n\n# See Bird & Wadler's Introduction to functional programming 4.5.\n"
  },
  {
    "path": "sample/cbreak.rb",
    "content": "# ioctl example works on Sun\n\nCBREAK = 0x00000002\nECHO = 0x00000008\nTIOCGETP = 0x40067408\nTIOCSETP = 0x80067409\n\ndef cbreak ()\n  set_cbreak(true)\nend\n\ndef cooked ()\n  set_cbreak(false)\nend\n\ndef set_cbreak (on)\n  tty = \"\\0\" * 256\n  STDIN.ioctl(TIOCGETP, tty)\n  ttys = tty.unpack(\"C4 S\")\n  if on\n    ttys[4] |= CBREAK\n    ttys[4] &= ~ECHO\n  else\n    ttys[4] &= ~CBREAK\n    ttys[4] |= ECHO\n  end\n  tty = ttys.pack(\"C4 S\")\n  STDIN.ioctl(TIOCSETP, tty)\nend\ncbreak();\n\nprint(\"this is no-echo line: \");\nreadline().print\ncooked();\nprint(\"this is echo line: \");\nreadline()\n"
  },
  {
    "path": "sample/clnt.rb",
    "content": "# socket example - client side\n# usage: ruby clnt.rb [host] port\n\nrequire \"socket\"\n\nif ARGV.length >= 2\n  host = ARGV.shift\nelse\n  host = \"localhost\"\nend\nprint(\"Trying \", host, \" ...\")\nSTDOUT.flush\ns = TCPSocket.open(host, ARGV.shift)\nprint(\" done\\n\")\nprint(\"addr: \", s.addr.join(\":\"), \"\\n\")\nprint(\"peer: \", s.peeraddr.join(\":\"), \"\\n\")\nwhile line = gets()\n  s.write(line)\n  print(s.readline)\nend\ns.close\n"
  },
  {
    "path": "sample/dbmtest.rb",
    "content": "# ruby dbm acess\nrequire \"dbm\"\n\nd = DBM.open(\"test\")\nkeys = d.keys\nif keys.length > 0 then\n  for k in keys; print k, \"\\n\"; end\n  for v in d.values; print v, \"\\n\"; end\nelse\n  d['foobar'] = 'FB'\n  d['baz'] = 'BZ'\n  d['quux'] = 'QX'\nend\n\n"
  },
  {
    "path": "sample/dir.rb",
    "content": "# directory access\n# list all files but .*/*~/*.o\ndirp = Dir.open(\".\")\nfor f in dirp\n  case f\n  when /^\\./, /~$/, /\\.o/\n    # do not print\n  else\n    print f, \"\\n\"\n  end\nend\ndirp.close\n"
  },
  {
    "path": "sample/drb/README.rd",
    "content": "= Sample scripts\n\n* array and iteretor\n  * darray.rb --- server\n  * darrayc.rb --- client\n\n* simple chat\n  * dchats.rb --- server\n  * dchatc.rb --- client\n\n* distributed chasen (for Japanese)\n  * dhasen.rb --- server\n  * dhasenc.rb --- client\n\n* simple log server\n  * dlogd.rb --- server\n  * dlogc.rb --- client\n\n* Queue server, and DRbUnknown demo\n  * dqueue.rb --- server\n  * dqin.rb --- client. push DQEntry objects.\n  * dqout.rb --- client. pop DQEntry objects.\n  * dqlib.rb --- define DQEntry\n\n* IdConv customize demo: reference by name \n  * name.rb --- server\n  * namec.rb --- client\n\n* extserv\n  * extserv_test.rb\n\n* IdConv customize demo 2: using TimerIdConv\n  * holders.rb --- server\n  * holderc.rb --- client\n\n* rinda, remote tuplespace\n  * rinda_ts.rb --- TupleSpace server.\n  * rindas.rb --- provide simple service via TupleSpace.\n  * rindac.rb --- service user\n\n* observer\n  cdbiff - ((<URI:http://namazu.org/~satoru/cdbiff/>))\n  * dbiff.rb --- dcdbiff server\n  * dcdbiff.rb --- dcdbiff client\n\n* drbssl\n  * drbssl_s.rb\n  * drbssl_c.rb\n  \n* add DRbProtocl\n  * http0.rb\n  * http0serv.rb\n\n* Rinda::Ring\n  * ring_place.rb\n  * ring_echo.rb\n"
  },
  {
    "path": "sample/drb/README.rd.ja",
    "content": "= ץ륹ץ\n\n* Array⡼ȤѤƥƥ졼\n  * darray.rb --- server\n  * darrayc.rb --- client\n\n* ʰץå\n  * dchats.rb --- server\n  * dchatc.rb --- client\n\n* ʬchasen\n  * dhasen.rb --- server\n  * dhasenc.rb --- client\n\n* ʰץ\n  * dlogd.rb --- server\n  * dlogc.rb --- client\n\n* QueueС\n  饤dqin.rbQueueФΤʤ֥(DQEntry)\n  push뤬DRbUnknownˤꥯ饤dqout.rbpopǤ롣\n  * dqueue.rb --- server\n  * dqin.rb --- clientDQEntry֥Ȥpush\n  * dqout.rb --- clientDQEntry֥Ȥpop\n  * dqlib.rb --- DQEntry饤֥\n\n* ̾ˤ뻲\n  IdConv򥫥ޥidǤʤ̾ǻȤ\n  * name.rb --- server\n  * namec.rb --- client\n\n* extservΥץ\n  * extserv_test.rb\n\n* TimerIdConvλ\n  * holders.rb --- serverruby -d hodlers.rbȤTimerIdConvѤ롣\n  * holderc.rb --- client\n\n* rinda.rbλ\n  * rinda_ts.rb --- TupleSpaceС\n  * rindac.rb --- TupleSpaceclientǥץꥱclient\n  * rindas.rb --- TupleSpaceclientǥץꥱserver\n\n* observerλ\n  cdbiff - ((<URI:http://namazu.org/~satoru/cdbiff/>))\n  * dbiff.rb --- dcdbiff server\n  * dcdbiff.rb --- dcdbiff client\n\n* drbsslλ\n  * drbssl_s.rb\n  * drbssl_c.rb\n\n* DRbProtoclɲ\n  * http0.rb\n  * http0serv.rb\n\n* ringλ\n  * ring_place.rb\n  * ring_echo.rb\n"
  },
  {
    "path": "sample/drb/darray.rb",
    "content": "=begin\n distributed Ruby --- Array\n \tCopyright (c) 1999-2001 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nhere = ARGV.shift\nDRb.start_service(here, [1, 2, \"III\", 4, \"five\", 6])\nputs DRb.uri\nDRb.thread.join\n\n"
  },
  {
    "path": "sample/drb/darrayc.rb",
    "content": "=begin\n distributed Ruby --- Array client\n \tCopyright (c) 1999-2001 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nthere = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\n\nDRb.start_service(nil, nil)\nro = DRbObject.new(nil, there)\np ro.size\n\nputs \"# collect\"\na = ro.collect { |x|\n  x + x\n}\np a\n\nputs \"# find\"\np ro.find { |x| x.kind_of? String }\n  \nputs \"# each, break\"\nro.each do |x|\n  next if x == \"five\"\n  puts x\nend\n\nputs \"# each, break\"\nro.each do |x|\n  break if x == \"five\"\n  puts x\nend\n\nputs \"# each, next\"\nro.each do |x|\n  next if x == \"five\"\n  puts x\nend\n\nputs \"# each, redo\"\ncount = 0\nro.each do |x|\n  count += 1\n  puts count\n  redo if count == 3\nend\n\nputs \"# each, retry\"\nretried = false\nro.each do |x|\n  puts x\n  if x == 4 && !retried\n    puts 'retry'\n    retried = true\n    retry\n  end\nend\n\n"
  },
  {
    "path": "sample/drb/dbiff.rb",
    "content": "#\n# dbiff.rb - distributed cdbiff (server)\n#  * original: cdbiff by Satoru Takabayashi <http://namazu.org/~satoru/cdbiff>\n\nrequire 'drb/drb'\nrequire 'drb/eq'\nrequire 'drb/observer'\n\nclass Biff\n  include DRb::DRbObservable\n\n  def initialize(filename, interval)\n    super()\n    @filename = filename\n    @interval = interval\n  end\n\n  def run\n    last = Time.now\n    while true\n      begin \n\tsleep(@interval)\n\tcurrent = File::mtime(@filename)\n\tif current > last\n\t  changed\n\t  begin\n\t    notify_observers(@filename, current) \n\t  rescue Error\n\t  end\n\t  last = current\n\tend\n      rescue\n\tnext\n      end\n    end\n  end\nend\n\ndef main\n  filename = \"/var/mail/#{ENV['USER']}\"\n  interval = 15\n  uri = 'druby://:19903'\n\n  biff = Biff.new(filename, interval)\n\n  DRb.start_service(uri, biff)\n  biff.run\nend\n\nmain\n\n"
  },
  {
    "path": "sample/drb/dcdbiff.rb",
    "content": "#\n# dcdbiff.rb - distributed cdbiff (client)\n#  * original: cdbiff by Satoru Takabayashi <http://namazu.org/~satoru/cdbiff>\n\nrequire 'drb/drb'\nrequire 'drb/eq'\n\nclass Notify\n  include DRbUndumped\n\n  def initialize(biff, command)\n    @biff = biff\n    @command = command\n\n    @biff.add_observer(self)\n  end\n\n  def update(filename, time)\n    p [filename, time] if $DEBUG\n    system(@command)\n  end\n\n  def done\n    begin\n      @biff.delete_observer(self)\n    rescue\n    end\n  end\nend\n\ndef main\n  command = 'eject'\n  uri = 'druby://localhost:19903'\n\n  DRb.start_service\n  biff = DRbObject.new(nil, uri)\n  notify = Notify.new(biff, command)\n\n  trap(\"INT\"){ notify.done }\n  DRb.thread.join\nend\n\nmain\n"
  },
  {
    "path": "sample/drb/dchatc.rb",
    "content": "=begin\n distributed Ruby --- chat client\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nclass ChatClient\n  include DRbUndumped  \n\n  def initialize(name)\n    @name = name\n    @key = nil\n  end\n  attr_reader(:name)\n  attr_accessor(:key)\n\n  def message(there, str)\n    raise 'invalid key' unless @key == there\n    puts str\n  end\nend\n\nif __FILE__ == $0\n  begin\n    there = ARGV.shift\n    name = ARGV.shift\n    raise \"usage\" unless (there and name)\n  rescue\n    $stderr.puts(\"usage: #{$0} <server_uri> <your_name>\")\n    exit 1\n  end\n  DRb.start_service\n  ro = DRbObject.new(nil, there)\n\n  chat = ChatClient.new(name)\n  entry = ro.add_member(chat)\n  while gets\n    entry.say($_)\n  end\nend\n"
  },
  {
    "path": "sample/drb/dchats.rb",
    "content": "=begin\n distributed Ruby --- chat server\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\nrequire 'thread'\nrequire 'drb/drb'\n\nclass ChatEntry\n  include DRbUndumped\n\n  def initialize(server, there)\n    @server = server\n    @there = there\n    @name = there.name\n    @key = there.key = Time.now\n  end\n  attr :name, true\n  attr :there\n\n  def say(str)\n    @server.distribute(@there, str)\n  end\n\n  def listen(str)\n    @there.message(@key, str)\n  end\nend\n\n\nclass ChatServer\n  def initialize\n    @mutex = Mutex.new\n    @members = {}\n  end\n\n  def add_member(there)\n    client = ChatEntry.new(self, there)\n    @mutex.synchronize do\n      @members[there] = client\n    end\n    client\n  end\n\n  def distribute(there, str)\n    name = @members[there].name\n    msg = \"<#{name}> #{str}\"\n    msg2 = \">#{name}< #{str}\"\n    @mutex.synchronize do\n      for m in @members.keys\n\tbegin\n\t  if m == there\n\t    @members[m].listen(msg2)\n\t   else\n\t    @members[m].listen(msg)\n\t  end\n\trescue\n\t  p $!\n\t  @members.delete(m)\n\tend\n      end\n    end\n  end\nend\n\nif __FILE__ == $0\n  here = ARGV.shift\n  DRb.start_service(here, ChatServer.new)\n  puts DRb.uri\n  DRb.thread.join\nend\n"
  },
  {
    "path": "sample/drb/dhasen.rb",
    "content": "=begin\n distributed Ruby --- dRuby Sample Server --- chasen server\n \tCopyright (c) 1999-2001 Masatoshi SEKI \n=end\n\n=begin\n How to play.\n\n Terminal 1\n | % ruby dhasen.rb \n | druby://yourhost:7640\n\n Terminal 2\n | % ruby dhasenc.rb druby://yourhost:7640\n\n=end\n\nrequire 'drb/drb'\nrequire 'chasen'\nrequire 'thread'\n\nclass Dhasen\n  include DRbUndumped\n\n  def initialize\n    @mutex = Mutex.new\n  end\n\n  def sparse(str, *arg)\n    @mutex.synchronize do\n      Chasen.getopt(*arg)\n      Chasen.sparse(str)\n    end\n  end\nend\n\nif __FILE__ == $0\n  DRb.start_service(nil, Dhasen.new)\n  puts DRb.uri\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "sample/drb/dhasenc.rb",
    "content": "=begin\n distributed Ruby --- dRuby Sample Client -- chasen client\n \tCopyright (c) 1999-2001 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nthere = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\nDRb.start_service\ndhasen = DRbObject.new(nil, there)\n\nprint dhasen.sparse(\"ϡŷʤꡣ\", \"-F\", '(%BB %m %M)\\n', \"-j\")\nprint dhasen.sparse(\"ϡŷʤꡣ\", \"-F\", '(%m %M)\\n')\n"
  },
  {
    "path": "sample/drb/dlogc.rb",
    "content": "=begin\n distributed Ruby --- Log test\n \tCopyright (c) 1999-2001 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nthere = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\n\nDRb.start_service\nro = DRbObject.new(nil, there)\nro.log(123)\nro.log(\"hello\")\nsleep 2\nro.log(\"wakeup\")\n\n"
  },
  {
    "path": "sample/drb/dlogd.rb",
    "content": "=begin\n distributed Ruby --- Log server\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\nrequire 'thread'\n\nclass Logger\n  def initialize(fname)\n    @fname = fname.to_s\n    @fp = File.open(@fname, \"a+\")\n    @queue = Queue.new\n    @th = Thread.new { self.flush }\n  end\n\n  def log(str)\n    @queue.push(\"#{Time.now}\\t\" + str.to_s)\n  end\n\n  def flush\n    begin\n      while(1)\n\t@fp.puts(@queue.pop)\n\t@fp.flush\n      end\n    ensure\n      @fp.close\n    end\n  end\nend\n\nif __FILE__ == $0\n  here = ARGV.shift\n  DRb.start_service(here, Logger.new('/usr/tmp/dlogd.log'))\n  puts DRb.uri\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "sample/drb/dqin.rb",
    "content": "=begin\n distributed Ruby --- store\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\nrequire 'dqlib'\n\nthere = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\n\nDRb.start_service\nqueue = DRbObject.new(nil, there)\nqueue.push(DQEntry.new(DRb.uri))\n"
  },
  {
    "path": "sample/drb/dqlib.rb",
    "content": "class DQEntry\n  def initialize(name)\n    @name = name\n  end\n\n  def greeting\n    \"Hello, This is #{@name}.\"\n  end\n  alias to_s greeting\nend\n\nif __FILE__ == $0\n  puts DQEntry.new('DQEntry')\nend\n"
  },
  {
    "path": "sample/drb/dqout.rb",
    "content": "=begin\n distributed Ruby --- fetch\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\nrequire 'dqlib'\n\nthere = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\n\nDRb.start_service\nqueue = DRbObject.new(nil, there)\nentry = queue.pop\nputs entry.greeting\n"
  },
  {
    "path": "sample/drb/dqueue.rb",
    "content": "=begin\n distributed Ruby --- Queue\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'thread'\nrequire 'drb/drb'\n\nDRb.start_service(nil, Queue.new)\nputs DRb.uri\nDRb.thread.join\n\n"
  },
  {
    "path": "sample/drb/drbc.rb",
    "content": "=begin\n distributed Ruby --- dRuby Sample Client\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nclass DRbEx2\n  include DRbUndumped\n\n  def initialize(n)\n    @n = n\n  end\n\n  def to_i\n    @n.to_i\n  end\nend\n\nif __FILE__ == $0\n  there = ARGV.shift\n  unless there\n    $stderr.puts(\"usage: #{$0} <server_uri>\")\n    exit 1\n  end\n\n  DRb.start_service()\n  ro = DRbObject.new_with_uri(there)\n\n  puts ro\n  p ro.to_a\n  puts ro.hello\n  p ro.hello\n  puts ro.sample(DRbEx2.new(1), 2, 3)\n  puts ro.sample(1, ro.sample(DRbEx2.new(1), 2, 3), DRbEx2.new(3))\n\n  begin\n    ro.err\n  rescue DRb::DRbUnknownError\n    p $!\n    p $!.unknown\n  rescue RuntimeError\n    p $!\n  end\nend\n"
  },
  {
    "path": "sample/drb/drbch.rb",
    "content": "=begin\n distributed Ruby --- dRuby Sample Client\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\nrequire 'drb/http'\n\nclass DRbEx2\n  include DRbUndumped\n\n  def initialize(n)\n    @n = n\n  end\n\n  def to_i\n    @n.to_i\n  end\nend\n\nif __FILE__ == $0\n  there = ARGV.shift\n  unless there\n    $stderr.puts(\"usage: #{$0} <server_uri>\")\n    exit 1\n  end\n\n  DRb::DRbConn.proxy_map['x68k'] = 'http://x68k/~mas/http_cgi.rb'\n\n  DRb.start_service()\n  ro = DRbObject.new(nil, there)\n\n  puts ro\n  p ro.to_a\n  puts ro.hello\n  p ro.hello\n  puts ro.sample(DRbEx2.new(1), 2, 3)\n  puts ro.sample(1, ro.sample(DRbEx2.new(1), 2, 3), DRbEx2.new(3))\n\n  begin\n    ro.err\n  rescue DRb::DRbUnknownError\n    p $!\n    p $!.unknown\n  rescue RuntimeError\n    p $!\n  end\nend\n"
  },
  {
    "path": "sample/drb/drbm.rb",
    "content": "=begin\n multiple DRbServer\n \tCopyright (c) 1999-2002 Masatoshi SEKI \n=end\n\n=begin\n How to play.\n\n Terminal 1\n | % ruby drbm.rb \n | druby://yourhost:7640 druby://yourhost:7641\n\n Terminal 2\n | % ruby drbmc.rb druby://yourhost:7640 druby://yourhost:7641\n | [#<DRb::DRbObject .... @uri=\"druby://yourhost:7640\">, \"FOO\"]\n | [#<DRb::DRbObject .... @uri=\"druby://yourhost:7641\">, \"FOO\"]\n\n=end\n\nrequire 'drb/drb'\n\nclass Hoge\n  include DRbUndumped\n  def initialize(s)\n    @str = s\n  end\n  \n  def to_s\n    @str\n  end\nend\n\nclass Foo\n  def initialize(s='FOO')\n    @hoge = Hoge.new(s)\n  end\n\n  def hello\n    @hoge\n  end\nend\n\nclass Bar < Foo\n  def initialize(foo)\n    @hoge = foo.hello\n  end\nend\n\n\nif __FILE__ == $0\n  foo = Foo.new\n  s1 = DRb::DRbServer.new('druby://:7640', foo)\n  s2 = DRb::DRbServer.new('druby://:7641', Bar.new(foo))\n\n  puts \"#{s1.uri} #{s2.uri}\"\n\n  s1.thread.join\n  s2.thread.join\nend\n\n"
  },
  {
    "path": "sample/drb/drbmc.rb",
    "content": "=begin\n  multiple DRbServer client\n \tCopyright (c) 1999-2002 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nif __FILE__ == $0\n  s1 = ARGV.shift\n  s2 = ARGV.shift\n  unless s1 && s2\n    $stderr.puts(\"usage: #{$0} <server_uri1> <server_uri2>\")\n    exit 1\n  end\n\n  DRb.start_service()\n  r1 = DRbObject.new(nil, s1)\n  r2 = DRbObject.new(nil, s2)\n\n  p [r1.hello, r1.hello.to_s]\n  p [r2.hello, r2.hello.to_s]\nend\n"
  },
  {
    "path": "sample/drb/drbs-acl.rb",
    "content": "=begin\n distributed Ruby --- dRuby Sample Server\n \tCopyright (c) 1999-2000 Masatoshi SEKI \n=end\n\n=begin\n How to play.\n\n Terminal 1\n | % ruby drbs.rb \n | druby://yourhost:7640\n\n Terminal 2\n | % ruby drbc.rb druby://yourhost:7640\n | \"hello\"\n | 6\n | 10\n\n=end\n\nrequire 'drb/drb'\nrequire 'acl'\n\nclass DRbEx\n  def initialize\n    @hello = 'hello'\n  end\n\n  def hello\n    info = Thread.current['DRb']\n    p info['socket'].peeraddr if info\n    @hello\n  end\n\n  def sample(a, b, c)\n    a.to_i + b.to_i + c.to_i\n  end\nend\n\nif __FILE__ == $0\n  acl = ACL.new(%w(deny all\n                   allow 192.168.1.*\n                   allow localhost))\n  \n  DRb.install_acl(acl)\n\n  DRb.start_service(nil, DRbEx.new)\n  puts DRb.uri\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "sample/drb/drbs.rb",
    "content": "=begin\n distributed Ruby --- dRuby Sample Server\n \tCopyright (c) 1999-2000,2002 Masatoshi SEKI \n=end\n\n=begin\n How to play.\n\n Terminal 1\n | % ruby drbs.rb \n | druby://yourhost:7640\n\n Terminal 2\n | % ruby drbc.rb druby://yourhost:7640\n | \"hello\"\n | ....\n\n=end\n\nrequire 'drb/drb'\n\nclass DRbEx\n  include DRbUndumped\n\n  def initialize\n    @hello = 'hello'\n  end\n\n  def hello\n    cntxt = Thread.current['DRb']\n    if cntxt\n      p cntxt['server'].uri\n      p cntxt['client'].peeraddr\n    end\n    Foo::Unknown.new\n  end\n\n  def err\n    raise FooError\n  end\n\n  def sample(a, b, c)\n    a.to_i + b.to_i + c.to_i\n  end\nend\n\nclass Foo\n  class Unknown\n  end\nend\n\nclass FooError < RuntimeError\nend\n\nif __FILE__ == $0\n  DRb.start_service(ARGV.shift || 'druby://:7640', DRbEx.new)\n  puts DRb.uri\n  Thread.new do\n    sleep 10\n    DRb.stop_service\n  end\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "sample/drb/drbssl_c.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'drb'\nrequire 'drb/ssl'\n\nthere = ARGV.shift || \"drbssl://localhost:3456\"\n\nconfig = Hash.new\nconfig[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER\nconfig[:SSLVerifyCallback] = lambda{|ok,x509_store|\n  p [ok, x509_store.error_string]\n  true\n}\n\nDRb.start_service(nil,nil,config)\nh = DRbObject.new(nil, there)\nwhile line = gets\n  p h.hello(line.chomp)\nend\n"
  },
  {
    "path": "sample/drb/drbssl_s.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'drb'\nrequire 'drb/ssl'\n\nhere = ARGV.shift || \"drbssl://localhost:3456\"\n\nclass HelloWorld\n  include DRbUndumped\n\n  def hello(name)\n    \"Hello, #{name}.\"\n  end\nend\n\nconfig = Hash.new\nconfig[:verbose] = true\nbegin\n  data = open(\"sample.key\"){|io| io.read }\n  config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)\n  data = open(\"sample.crt\"){|io| io.read }\n  config[:SSLCertificate] = OpenSSL::X509::Certificate.new(data)\nrescue\n  $stderr.puts \"Switching to use self-signed certificate\"\n  config[:SSLCertName] =\n    [ [\"C\",\"JP\"], [\"O\",\"Foo.DRuby.Org\"], [\"CN\", \"Sample\"] ]\nend\n\nDRb.start_service(here, HelloWorld.new, config)\nputs DRb.uri\nDRb.thread.join\n"
  },
  {
    "path": "sample/drb/extserv_test.rb",
    "content": "=begin\n dRuby sample\n \tCopyright (c) 2000 Masatoshi SEKI \n\n= How to play\n\n* Terminal 1\n  \n  % ruby -I. extserv_test.rb server\n  druby://yourhost:12345\n\n* Terminal 2\n\n  % ruby -I. extserv_test.rb druby://yourhost:12345\n  ...\n\n=end\n\nrequire 'drb/drb'\n\ndef ARGV.shift\n  it = super()\n  raise \"usage:\\nserver: #{$0} server [<uri>]\\nclient: #{$0} [quit] <uri>\" unless it\n  it\nend\n\nclass Foo\n  include DRbUndumped\n  \n  def initialize(str)\n    @str = str\n  end\n  \n  def hello(it)\n    \"#{it}: #{self}\"\n  end\n\n  def to_s\n    @str\n  end\nend\n\ncmd = ARGV.shift\ncase cmd\nwhen 'itest1', 'itest2'\n  require 'drb/extserv'\n\n  front = Foo.new(cmd)\n  server = DRb::DRbServer.new(nil, front)\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift, server)\n  server.thread.join\n\nwhen 'server'\n  require 'drb/extservm'\n\n  DRb::ExtServManager.command['itest1'] = \"ruby -I. #{$0} itest1\"\n  DRb::ExtServManager.command['itest2'] = \"ruby -I. #{$0} itest2\"\n  \n  s = DRb::ExtServManager.new\n  DRb.start_service(ARGV.shift, s)\n  puts DRb.uri\n  DRb.thread.join\n\n\nelse\n  uri = (cmd == 'quit') ? ARGV.shift : cmd\n\n  DRb.start_service\n  s = DRbObject.new(nil, uri)\n  t1 = s.service('itest1').front\n  puts t1\n  t2 = s.service('itest2').front\n  puts t2\n  puts t1.hello(t2)\n  if (cmd == 'quit') \n    s.service('itest1').stop_service\n    s.service('itest2').stop_service\n  end\nend\n\n"
  },
  {
    "path": "sample/drb/gw_ct.rb",
    "content": "require 'drb/drb'\n\nclass Foo\n  include DRbUndumped\n\n  def foo(n)\n    n + n\n  end\n\n  def bar(n)\n    yield(n) + yield(n)\n  end\nend\n\nDRb.start_service(nil)\nputs DRb.uri\n\nro = DRbObject.new(nil, ARGV.shift)\nro[:tcp] = Foo.new\ngets\n\nit = ro[:unix]\np [it, it.foo(1)]\ngets\n\np it.bar('2') {|n| n * 3}\ngets\n\n\n"
  },
  {
    "path": "sample/drb/gw_cu.rb",
    "content": "require 'drb/drb'\nrequire 'drb/unix'\n\nclass Foo\n  include DRbUndumped\n\n  def foo(n)\n    n + n\n  end\n\n  def bar(n)\n    yield(n) + yield(n)\n  end\nend\n\nDRb.start_service('drubyunix:', nil)\nputs DRb.uri\n\nro = DRbObject.new(nil, ARGV.shift)\nro[:unix] = Foo.new\ngets\n\nit = ro[:tcp]\np [it, it.foo(1)]\ngets\n\np it.bar('2') {|n| n * 3}\ngets\n"
  },
  {
    "path": "sample/drb/gw_s.rb",
    "content": "require 'drb/drb'\nrequire 'drb/unix'\nrequire 'drb/gw'\n\nDRb.install_id_conv(DRb::GWIdConv.new)\ngw = DRb::GW.new\ns1 = DRb::DRbServer.new(ARGV.shift, gw)\ns2 = DRb::DRbServer.new(ARGV.shift, gw)\ns1.thread.join\ns2.thread.join\n"
  },
  {
    "path": "sample/drb/holderc.rb",
    "content": "require 'drb/drb'\n\nbegin\n  there = ARGV.shift || raise\nrescue\n  $stderr.puts(\"usage: #{$0} <server_uri>\")\n  exit 1\nend\n\nDRb.start_service()\nro = DRbObject.new(nil, there)\n\nary = []\n10.times do \n  ary.push(ro.gen)\nend\n\nsleep 5 if $DEBUG\n\nary.each do |e|\n  p e.sample([1])\nend\n"
  },
  {
    "path": "sample/drb/holders.rb",
    "content": "=begin\n= How to play.\n\n==  with timeridconv:\n  % ruby -d holders.rb\n  druby://yourhost:1234\n\n  % ruby holderc.rb druby://yourhost:1234\n\n\n==  without timeridconv:\n  % ruby holders.rb\n  druby://yourhost:1234\n\n  % ruby holderc.rb druby://yourhost:1234\n=end\n  \n\nrequire 'drb/drb'\n\nclass DRbEx3\n  include DRbUndumped\n\n  def initialize(n)\n    @v = n\n  end\n\n  def sample(list)\n    sum = 0\n    list.each do |e|\n      sum += e.to_i\n    end\n    @v * sum\n  end\nend\n\nclass DRbEx4\n  include DRbUndumped\n  \n  def initialize\n    @curr = 1\n  end\n  \n  def gen\n    begin\n      @curr += 1\n      DRbEx3.new(@curr)\n    ensure\n      GC.start\n    end\n  end\nend\n\nif __FILE__ == $0\n  if $DEBUG\n    require 'drb/timeridconv'\n    DRb.install_id_conv(DRb::TimerIdConv.new(2))\n  end\n\n  DRb.start_service(nil, DRbEx4.new)\n  puts DRb.uri\n  DRb.thread.join\nend\n"
  },
  {
    "path": "sample/drb/http0.rb",
    "content": "require 'drb/drb'\nrequire 'net/http'\nrequire 'uri'\n\nmodule DRb\n  module HTTP0\n    class StrStream\n      def initialize(str='')\n\t@buf = str\n      end\n      attr_reader :buf\n\n      def read(n)\n\tbegin\n\t  return @buf[0,n]\n\tensure\n\t  @buf[0,n] = ''\n\tend\n      end\n\n      def write(s)\n\t@buf.concat s\n      end\n    end\n\n    def self.uri_option(uri, config)\n      return uri, nil\n    end\n\n    def self.open(uri, config)\n      unless /^http:/ =~ uri\n\traise(DRbBadScheme, uri) unless uri =~ /^http:/\n\traise(DRbBadURI, 'can\\'t parse uri:' + uri)\n      end\n      ClientSide.new(uri, config)\n    end\n\n    class ClientSide\n      def initialize(uri, config)\n\t@uri = uri\n\t@res = nil\n\t@config = config\n\t@msg = DRbMessage.new(config)\n\t@proxy = ENV['HTTP_PROXY']\n      end\n\n      def close; end\n      def alive?; false; end\n      \n      def send_request(ref, msg_id, *arg, &b)\n\tstream = StrStream.new\n\t@msg.send_request(stream, ref, msg_id, *arg, &b)\n\t@reply_stream = StrStream.new\n\tpost(@uri, stream.buf)\n      end\n      \n      def recv_reply\n\t@msg.recv_reply(@reply_stream)\n      end\n\n      def post(url, data)\n\tit = URI.parse(url)\n\tpath = [(it.path=='' ? '/' : it.path), it.query].compact.join('?')\n\thttp = Net::HTTP.new(it.host, it.port)\n\tsio = StrStream.new\n\thttp.post(path, data, {'Content-Type'=>'application/octetstream;'}) do |str|\n\t  sio.write(str)\n\t  if @config[:load_limit] < sio.buf.size\n\t    raise TypeError, 'too large packet' \n\t  end\n\tend\n\t@reply_stream = sio\n      end\n    end\n  end\n  DRbProtocol.add_protocol(HTTP0)\nend\n"
  },
  {
    "path": "sample/drb/http0serv.rb",
    "content": "require 'webrick'\nrequire 'drb/drb'\nrequire 'drb/http0'\nrequire 'thread'\n\nmodule DRb\n  module HTTP0\n    \n    def self.open_server(uri, config)\n      unless /^http:/ =~ uri\n\traise(DRbBadScheme, uri) unless uri =~ /^http:/\n\traise(DRbBadURI, 'can\\'t parse uri:' + uri)\n      end\n      Server.new(uri, config)\n    end\n\n    class Callback < WEBrick::HTTPServlet::AbstractServlet\n      def initialize(config, drb)\n\t@config = config\n\t@drb = drb\n\t@queue = Queue.new\n      end\n      \n      def do_POST(req, res)\n\t@req = req\n\t@res = res\n\t@drb.push(self)\n\t@res.body = @queue.pop\n\t@res['content-type'] = 'application/octet-stream;'\n      end\n      \n      def req_body\n\t@req.body\n      end\n\n      def reply(body)\n\t@queue.push(body)\n      end\n      \n      def close\n\t@queue.push('')\n      end\n    end\n\n    class Server\n      def initialize(uri, config)\n\t@uri = uri\n\t@config = config\n\t@queue = Queue.new\n\tsetup_webrick(uri)\n      end\n      attr_reader :uri\n\n      def close\n\t@server.shutdown if @server\n\t@server = nil\n      end\n\n      def push(callback)\n\t@queue.push(callback)\n      end\n\n      def accept\n\tclient = @queue.pop\n\tServerSide.new(client, @config)\n      end\n\n      def setup_webrick(uri)\n\tlogger = WEBrick::Log::new($stderr, WEBrick::Log::FATAL)\n\tu = URI.parse(uri)\n\ts = WEBrick::HTTPServer.new(:Port => u.port,\n\t\t\t\t    :AddressFamily => Socket::AF_INET,\n\t\t\t\t    :BindAddress => u.host,\n\t\t\t\t    :Logger => logger,\n\t\t\t\t    :ServerType => Thread)\n\ts.mount(u.path, Callback, self)\n\t@server = s\n\ts.start\n      end\n    end\n    \n    class ServerSide\n      def initialize(callback, config)\n\t@callback = callback\n\t@config = config\n\t@msg = DRbMessage.new(@config)\n\t@req_stream = StrStream.new(@callback.req_body)\n      end\n      \n      def close\n\t@callback.close if @callback\n\t@callback = nil\n      end\n\n      def alive?; false; end\n\n      def recv_request\n\tbegin\n\t  @msg.recv_request(@req_stream)\n\trescue\n\t  close\n\t  raise $!\n\tend\n      end\n\n      def send_reply(succ, result)\n\tbegin\n\t  return unless @callback\n\t  stream = StrStream.new\n\t  @msg.send_reply(stream, succ, result)\n\t  @callback.reply(stream.buf)\n\trescue\n\t  close\n\t  raise $!\n\tend\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "sample/drb/name.rb",
    "content": "=begin\n distributed Ruby --- NamedObject Sample\n \tCopyright (c) 2000-2001 Masatoshi SEKI \n=end\n\n=begin\nHow to play.\n\n* start server \n Terminal 1\n | % ruby name.rb druby://yourhost:7640\n | druby://yourhost:7640\n | [return] to exit\n\n* start client\n Terminal 2\n | % ruby namec.rb druby://yourhost:7640\n | #<DRb::DRbObject:0x40164174 @uri=\"druby://yourhost:7640\", @ref=\"seq\">\n | #<DRb::DRbObject:0x40163c9c @uri=\"druby://yourhost:7640\", @ref=\"mutex\">\n | 1\n | 2\n | [return] to continue\n\n* restart server\n Terminal 1\n type [return]\n | % ruby name.rb druby://yourhost:7640\n | druby://yourhost:7640\n | [return] to exit\n\n* continue client \n Terminal 2\n type [return] \n | 1\n | 2\n=end\n\nrequire 'thread.rb'\nrequire 'drb/drb'\n\nmodule DRbNamedObject\n  DRbNAMEDICT = {}\n  attr_reader(:drb_name)\n\n  def drb_name=(name)\n    @drb_name = name\n    Thread.exclusive do \n      raise(IndexError, name) if DRbNAMEDICT[name]\n      DRbNAMEDICT[name] = self\n    end\n  end\nend\n\nclass DRbNamedIdConv < DRb::DRbIdConv\n  def initialize\n    @dict = DRbNamedObject::DRbNAMEDICT\n  end\n\n  def to_obj(ref)\n    @dict.fetch(ref) do super end\n  end\n\n  def to_id(obj)\n    if obj.kind_of? DRbNamedObject\n      return obj.drb_name \n    else\n      return super\n    end\n  end\nend\n\nclass Seq\n  include DRbUndumped\n  include DRbNamedObject\n\n  def initialize(v, name)\n    @counter = v\n    @mutex = Mutex.new\n    self.drb_name = name\n  end\n\n  def next_value\n    @mutex.synchronize do\n      @counter += 1\n      return @counter\n    end\n  end\nend\n\nclass Front\n  def initialize\n    seq = Seq.new(0, 'seq')\n    mutex = Mutex.new\n    mutex.extend(DRbUndumped)\n    mutex.extend(DRbNamedObject)\n    mutex.drb_name = 'mutex'\n    @name = {}\n    @name['seq'] = seq\n    @name['mutex'] = mutex\n  end\n    \n  def [](k)\n    @name[k]\n  end\nend\n\nif __FILE__ == $0\n  uri = ARGV.shift\n\n  name_conv = DRbNamedIdConv.new\n  \n  DRb.install_id_conv(name_conv)\n  DRb.start_service(uri, Front.new)\n  puts DRb.uri\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "sample/drb/namec.rb",
    "content": "=begin\n distributed Ruby --- NamedObject Sample Client\n \tCopyright (c) 2000-2001 Masatoshi SEKI \n=end\n\nrequire 'drb/drb'\n\nbegin\n  there = ARGV.shift || raise\nrescue\n  puts \"usage: #{$0} <server_uri>\"\n  exit 1\nend\n\nDRb.start_service()\nro = DRbObject.new(nil, there)\n\nseq = ro[\"seq\"]\nmutex = ro[\"mutex\"]\n\np seq\np mutex\n\nmutex.synchronize do\n  p seq.next_value\n  p seq.next_value\nend\n\nputs '[return] to continue'\ngets\n\nmutex.synchronize do\n  p seq.next_value\n  p seq.next_value\nend\n\n"
  },
  {
    "path": "sample/drb/old_tuplespace.rb",
    "content": "#!/usr/local/bin/ruby\n# TupleSpace\n# Copyright (c) 1999-2000 Masatoshi SEKI\n# You can redistribute it and/or modify it under the same terms as Ruby.\n\nrequire 'thread'\n\nclass TupleSpace\n  class Template\n    def initialize(list)\n      @list = list\n      @check_idx = []\n      @list.each_with_index do |x, i|\n\t@check_idx.push i if x\n      end\n      @size = @list.size\n    end\n\n    attr :size\n    alias length size\n\n    def match(tuple)\n      return nil if tuple.size != self.size\n      @check_idx.each do |i|\n\tunless @list[i] === tuple[i]\n\t  return false\n\tend\n      end\n      return true\n    end\n  end\n\n  def initialize\n    @que = {}\n    @waiting = {}\n    @que.taint\t\t# enable tainted comunication\n    @waiting.taint\n    self.taint\n  end\n\n  def wakeup_waiting(tuple)\n    sz = tuple.length\n    return nil unless @waiting[sz]\n\n    x = nil\n    i = -1\n    found = false\n    @waiting[sz] = @waiting[sz].find_all { |x|\n      if x[0].match(tuple)\n\tbegin\n\t  x[1].wakeup\n\trescue ThreadError\n\tend\n\tfalse\n      else\n\ttrue\n      end\n    }\n  end\n\n  def put_waiting(template, thread)\n    sz = template.length\n    @waiting[sz] = [] unless @waiting[sz]\n    @waiting[sz].push([Template.new(template), thread])\n  end\n  private :wakeup_waiting\n  private :put_waiting\n\n  def get_que(template)\n    sz = template.length\n    return nil unless @que[sz]\n\n    template = Template.new(template)\n\n    x = nil\n    i = -1\n    found = false\n    @que[sz].each_with_index do |x, i|\n      if template.match(x)\n\tfound = true\n\tbreak\n      end\n    end\n    return nil unless found\n    \n    @que[sz].delete_at(i)\n\n    return x\n  end\n\n  def put_que(tuple)\n    sz = tuple.length\n    @que[sz] = [] unless @que[sz]\n    @que[sz].push tuple\n  end\n  private :get_que\n  private :put_que\n\n  def out(*tuples)\n    tuples.each do |tuple|\n      Thread.critical = true\n      put_que(tuple)\n      wakeup_waiting(tuple)\n      Thread.critical = false\n    end\n  end\n  alias put out\n  alias write out\n\n  def in(template, non_block=false)\n    begin\n      loop do\n\tThread.critical = true\n\ttuple = get_que(template)\n\tunless tuple\n\t  if non_block\n\t    raise ThreadError, \"queue empty\"\n\t  end\n\t  put_waiting(template, Thread.current)\n\t  Thread.stop\n\telse\n\t  return tuple\n\tend\n      end\n    ensure\n      Thread.critical = false\n    end\n  end\n  alias get in\n  alias take in\n\n  def rd(template, non_block=false)\n    tuple = self.in(template, non_block)\n    out(tuple)\n    tuple\n  end\n  alias read rd\n\n  def mv(dest, template, non_block=false)\n    tuple = self.in(template, non_block)\n    begin\n      dest.out(tuple)\n    rescue\n      self.out(tuple)\n    end\n  end\n  alias move mv\nend\n\nif __FILE__ == $0\n  ts = TupleSpace.new\n  clients = []\n  servers = []\n\n  def server(ts, id)\n    Thread.start {\n      loop do\n\treq = ts.in(['req', nil, nil])\n\tac = req[1]\n\tnum = req[2]\n\tsleep id\n\tts.out([ac, id, num, num * num])\n      end\n    }\n  end\n\n  def client(ts, n)\n    Thread.start {\n      ac = Object.new\n      tuples = (1..10).collect { |i| \n\t['req', ac, i * 10 + n]\n      }\n      ts.out(*tuples)\n      ts.out(tuples[0])\n      puts \"out: #{n}\"\n      11.times do |i|\n\tans = ts.in([ac, nil, nil, nil])\n\tputs \"client(#{n}) server(#{ans[1]}) #{ans[2]} #{ans[3]}\"\n      end\n    }\n  end\n\n  def watcher(ts)\n    Thread.start {\n      loop do\n\tbegin\n\t  sleep 1\n\t  p ts.rd(['req', nil, nil], true)\n\trescue ThreadError\n\t  puts \"'req' not found.\"\n\tend\n      end\n    }\n  end\n\n  (0..3).each do |n|\n    servers.push(server(ts, n))\n  end\n\n  (1..6).each do |n|\n    clients.push(client(ts, n))\n  end\n\n  (1..3).each do \n    watcher(ts)\n  end\n\n  clients.each do |t|\n    t.join\n  end\nend\n\n\n\n"
  },
  {
    "path": "sample/drb/rinda_ts.rb",
    "content": "require 'drb/drb'\nrequire 'rinda/tuplespace'\n\nuri = ARGV.shift\nDRb.start_service(uri, Rinda::TupleSpace.new)\nputs DRb.uri\nDRb.thread.join\n"
  },
  {
    "path": "sample/drb/rindac.rb",
    "content": "require 'drb/drb'\nrequire 'rinda/rinda'\n\nuri = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\n\nDRb.start_service\nts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, uri))\n\n(1..10).each do |n|\n  ts.write(['sum', DRb.uri, n])\nend\n\n(1..10).each do |n|\n  ans = ts.take(['ans', DRb.uri, n, nil])\n  p [ans[2], ans[3]]\nend\n\n"
  },
  {
    "path": "sample/drb/rindas.rb",
    "content": "require 'drb/drb'\nrequire 'rinda/rinda'\n\ndef do_it(v)\n  puts \"do_it(#{v})\"\n  v + v\nend\n\nuri = ARGV.shift || raise(\"usage: #{$0} <server_uri>\")\n\nDRb.start_service\nts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, uri))\n\nwhile true\n  r = ts.take(['sum', nil, nil])\n  v = do_it(r[2])\n  ts.write(['ans', r[1], r[2], v])\nend\n"
  },
  {
    "path": "sample/drb/ring_echo.rb",
    "content": "require 'drb/drb'\nrequire 'drb/eq'\nrequire 'rinda/ring'\nrequire 'thread'\n\nclass RingEcho\n  include DRbUndumped\n  def initialize(name)\n    @name = name\n  end\n  \n  def echo(str)\n    \"#{@name}: #{str}\"\n  end\nend\n\nDRb.start_service\n\nrenewer = Rinda::SimpleRenewer.new\n\nfinder = Rinda::RingFinger.new\nts = finder.lookup_ring_any\nts.read_all([:name, :RingEcho, nil, nil]).each do |tuple|\n  p tuple[2]\n  puts tuple[2].echo('Hello, World') rescue nil\nend\nts.write([:name, :RingEcho, RingEcho.new(DRb.uri), ''], renewer)\n\nDRb.thread.join\n\n"
  },
  {
    "path": "sample/drb/ring_inspect.rb",
    "content": "require 'rinda/ring'\nrequire 'drb/drb'\n\nclass Inspector\n  def initialize\n  end\n\n  def primary\n    Rinda::RingFinger.primary\n  end\n\n  def list_place\n    Rinda::RingFinger.to_a\n  end\n\n  def list(idx = -1)\n    if idx < 0\n      ts = primary\n    else\n      ts = list_place[idx]\n      raise \"RingNotFound\" unless ts\n    end\n    ts.read_all([:name, nil, nil, nil])\n  end\nend\n\ndef main\n  DRb.start_service\n  r = Inspector.new\nend\n"
  },
  {
    "path": "sample/drb/ring_place.rb",
    "content": "require 'drb/drb'\nrequire 'rinda/ring'\nrequire 'rinda/tuplespace'\n\nunless $DEBUG\n  # Run as a daemon...\n  exit!( 0 ) if fork\n  Process.setsid\n  exit!( 0 ) if fork\nend\n\nDRb.start_service(ARGV.shift)\n\nts = Rinda::TupleSpace.new\nplace = Rinda::RingServer.new(ts)\n\nif $DEBUG\n  puts DRb.uri\n  DRb.thread.join\nelse\n  STDIN.reopen('/dev/null')\n  STDOUT.reopen('/dev/null', 'w')\n  STDERR.reopen('/dev/null', 'w')\n  DRb.thread.join\nend\n"
  },
  {
    "path": "sample/drb/simpletuple.rb",
    "content": "#!/usr/local/bin/ruby\n# SimpleTupleSpace\n# Copyright (c) 1999-2000 Masatoshi SEKI\n# You can redistribute it and/or modify it under the same terms as Ruby.\n\nrequire 'thread'\n\nclass SimpleTupleSpace\n  def initialize\n    @hash = {}\n    @waiting = {}\n    @hash.taint\n    @waiting.taint\n    self.taint\n  end\n   \n  def out(key, obj)\n    Thread.critical = true\n    @hash[key] ||= []\n    @waiting[key] ||= []\n    @hash[key].push obj\n    begin\n      t = @waiting[key].shift\n      @waiting.delete(key) if @waiting[key].length == 0\n      t.wakeup if t\n    rescue ThreadError\n      retry\n    ensure\n      Thread.critical = false\n    end\n  end\n\n  def in(key)\n    Thread.critical = true\n    @hash[key] ||= []\n    @waiting[key] ||= []\n    begin\n      loop do\n        if @hash[key].length == 0\n          @waiting[key].push Thread.current\n          Thread.stop\n        else\n          return @hash[key].shift\n        end\n      end\n    ensure\n      @hash.delete(key) if @hash[key].length == 0\n      Thread.critical = false\n    end\n  end\nend  \n\nif __FILE__ == $0\n  ts = SimpleTupleSpace.new\n  clients = []\n  servers = []\n\n  def server(ts)\n    Thread.start {\n      loop do\n\treq = ts.in('req')\n\tac = req[0]\n\tnum = req[1]\n\tts.out(ac, num * num)\n      end\n    }\n  end\n\n  def client(ts, n)\n    Thread.start {\n      ac = Object.new\n      ts.out('req', [ac, n])\n      ans = ts.in(ac)\n      puts \"#{n}: #{ans}\"\n    }\n  end\n\n  3.times do \n    servers.push(server(ts))\n  end\n\n  (1..6).each do |n|\n    clients.push(client(ts, n))\n  end\n\n  clients.each do |t|\n    t.join\n  end\nend\n\n\n"
  },
  {
    "path": "sample/drb/speedc.rb",
    "content": "#!/usr/local/bin/ruby\n\nuri = ARGV.shift || raise(\"usage: #{$0} URI\")\nN = (ARGV.shift || 100).to_i\n\ncase uri\nwhen /^tcpromp:/, /^unixromp:/\n  require 'romp'\n\n  client = ROMP::Client.new(uri, false)\n  foo = client.resolve(\"foo\")\nwhen /^druby:/\n  require 'drb/drb'\n  \n  DRb.start_service\n  foo = DRbObject.new(nil, uri)\nend\n\nN.times do |n|\n  foo.foo(n)\nend\n"
  },
  {
    "path": "sample/drb/speeds.rb",
    "content": "class Foo\n  attr_reader :i\n  def initialize\n    @i = 0\n  end\n  \n  def foo(i)\n    @i = i\n    i + i\n  end\nend\n\n# server = ROMP::Server.new('tcpromp://localhost:4242', nil, true)\n\nuri = ARGV.shift || raise(\"usage: #{$0} URI\")\nfoo = Foo.new\n\ncase uri\nwhen /^tcpromp:/, /^unixromp:/\n  require 'romp'\n\n  server = ROMP::Server.new(uri, nil, true)\n  server.bind(foo, \"foo\")\n\nwhen /^druby:/\n  require 'drb/drb'\n  \n  DRb.start_service(uri, Foo.new)\nend\n\nDRb.thread.join\n"
  },
  {
    "path": "sample/dualstack-fetch.rb",
    "content": "# simple webpage fetcher\n\n# The code demonstrates how a multi-protocol client should be written.\n# TCPSocket is using getaddrinfo() internally, so there should be no problem.\n\nrequire \"socket\"\n\nif ARGV.size != 1\n  STDERR.print \"requires URL\\n\"\n  exit\nend\n\nurl = ARGV[0]\nif url !~ /^http:\\/\\/([^\\/]+)(\\/.*)$/\n  STDERR.print \"only http with full hostname is supported\\n\"\n  exit\nend\n\n# split URL into host, port and path\nhostport = $1\npath = $2\nif (hostport =~ /^(.*):([0-9]+)$/)\n  host = $1\n  port = $2\nelse\n  host = hostport\n  port = 80\nend\nif host =~ /^\\[(.*)\\]$/\n  host = $1\nend\n\n#STDERR.print \"url=<#{ARGV[0]}>\\n\"\n#STDERR.print \"host=<#{host}>\\n\"\n#STDERR.print \"port=<#{port}>\\n\"\n#STDERR.print \"path=<#{path}>\\n\"\n\nSTDERR.print \"conntecting to #{host} port #{port}\\n\"\nc = TCPSocket.new(host, port)\ndest = Socket.getnameinfo(c.getpeername,\n\t\tSocket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)\nSTDERR.print \"conntected to #{dest[0]} port #{dest[1]}\\n\"\nc.print \"GET #{path} HTTP/1.0\\n\"\nc.print \"Host: #{host}\\n\"\nc.print \"\\n\"\nwhile c.gets\n  print\nend\n"
  },
  {
    "path": "sample/dualstack-httpd.rb",
    "content": "# simple httpd\n\n# The code demonstrates how a multi-protocol daemon should be written.\n\nrequire \"socket\"\nrequire \"thread\"\n\nport = 8888\nres = Socket.getaddrinfo(nil, port, nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE)\nsockpool = []\nnames = []\nthreads = []\n\nres.each do |i|\n  s = TCPserver.new(i[3], i[1])\n  n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(\" port \")\n  sockpool.push s\n  names.push n\nend\n\n(0 .. sockpool.size - 1).each do |i|\n  mysock = sockpool[i]\n  myname = names[i]\n  STDERR.print \"socket #{mysock} started, address #{myname}\\n\"\n  threads[i] = Thread.start do\t\t# Thread.start cannot be used here!\n    ls = mysock\t# copy to dynamic variable\n    t = Thread.current\n    STDERR.print \"socket #{myname} listener started, pid #{$$} thread #{t}\\n\"\n    while true\n      as = ls.accept\n      Thread.start do\n\tSTDERR.print \"socket #{myname} accepted, thread \", Thread.current, \"\\n\"\n\ts = as\t# copy to dynamic variable\n\tstr = ''\n\twhile line = s.gets\n\t  break if line == \"\\r\\n\" or line == \"\\n\"\n\t  str << line\n\tend\n\tSTDERR.print \"socket #{myname} got string\\n\"\n\ts.write(\"HTTP/1.0 200 OK\\n\")\n\ts.write(\"Content-type: text/plain\\n\\n\")\n\ts.write(\"this is test: my name is #{myname}, you sent:\\n\")\n\ts.write(\"---start\\n\")\n\ts.write(str)\n\ts.write(\"---end\\n\")\n\ts.close\n\tSTDERR.print \"socket #{myname} processed, thread \", Thread.current, \" terminating\\n\"\n      end\n    end\n  end\nend\n\nfor t in threads\n  t.join\nend\n"
  },
  {
    "path": "sample/erb/erb4html.rb",
    "content": "require 'erb'\n\nclass ERB\n  class ERBString < String\n    def to_s; self; end\n\n    def erb_concat(s)\n      if self.class === s\n        concat(s)\n      else\n        concat(erb_quote(s))\n      end\n    end\n\n    def erb_quote(s); s; end\n  end\nend\n\nclass ERB4Html < ERB\n  def self.quoted(s)\n    HtmlString.new(s)\n  end\n\n  class HtmlString < ERB::ERBString\n    def erb_quote(s)\n      ERB::Util::html_escape(s)\n    end\n  end\n\n  def set_eoutvar(compiler, eoutvar = '_erbout')\n    compiler.put_cmd = \"#{eoutvar}.concat\"\n    compiler.insert_cmd = \"#{eoutvar}.erb_concat\"\n\n    cmd = []\n    cmd.push \"#{eoutvar} = ERB4Html.quoted('')\"\n\n    compiler.pre_cmd = cmd\n\n    cmd = []\n    cmd.push(eoutvar)\n\n    compiler.post_cmd = cmd\n  end\nend\n\nif __FILE__ == $0\n  page = <<EOP\n<title><%=title%></title>\n<p><%=para%></p>\nEOP\n  erb = ERB4Html.new(page)\n\n  title = \"<auto-quote>\"\n  para = \"&lt;quoted&gt;\"\n  puts erb.result\n\n  title = \"<auto-quote>\"\n  para = ERB4Html.quoted(\"&lt;quoted&gt;\")\n  puts erb.result\nend\n"
  },
  {
    "path": "sample/eval.rb",
    "content": "line = ''\nindent = 0\n$stdout.sync = true\nprint \"ruby> \"\nloop do\n  l = gets\n  if l.nil?\n    break if line.empty?\n  else\n    line += l\n    if l =~ /,\\s*$/\n      print \"ruby| \"\n      next\n    end\n    if l =~ /^\\s*(class|module|def|if|unless|case|while|until|for|begin)\\b[^_]/\n      indent += 1\n    end\n    if l =~ /^\\s*end\\b[^_]/\n      indent -= 1\n    end\n    if l =~ /\\{\\s*(\\|.*\\|)?\\s*$/\n      indent += 1\n    end\n    if l =~ /^\\s*\\}/\n      indent -= 1\n    end\n    if indent > 0\n      print \"ruby| \"\n      next\n    end\n  end\n  begin\n    print eval(line).inspect, \"\\n\"\n  rescue ScriptError, StandardError\n    printf \"ERR: %s\\n\", $! || 'exception raised'\n  end\n  break if l.nil?\n  line = ''\n  print \"ruby> \"\nend\nprint \"\\n\"\n"
  },
  {
    "path": "sample/export.rb",
    "content": "# method access permission\n# output:\n#\tfoobar\n#\tFoo\n\nclass Foo\n  public :printf\n  def baz\n    print \"baz\\n\"\n  end\n  private :baz\n\n  def quux\n    print \"in QUUX \"\n    baz()\n  end\nend\n\ndef foobar\n  print \"foobar\\n\"\nend\n\nf = Foo.new\n#Foo.private :printf\nclass Foo\t\t\t# redefines foobar's scope\n  public :foobar\nend\nf.foobar\nf.printf \"%s\\n\", Foo\n\nf.quux\n\nclass Bar<Foo\n  def quux\n    super\n    baz()\n  end\nend\n\nBar.new.quux\n"
  },
  {
    "path": "sample/exyacc.rb",
    "content": "#! /usr/local/bin/ruby -Kn\n# usage: exyacc.rb [yaccfiles]\n# this is coverted from exyacc.pl in the camel book\n\n$/ = nil\n\nwhile gets()\n  sbeg = $_.index(\"\\n%%\") + 1\n  send = $_.rindex(\"\\n%%\") + 1\n  $_ = $_[sbeg, send-sbeg]\n  sub!(/.*\\n/, \"\")\n  gsub!(/'\\{'/, \"'\\001'\")\n  gsub!(/'\\}'/, \"'\\002'\")\n  gsub!(%r{\\*/}, \"\\003\\003\")\n  gsub!(%r{/\\*[^\\003]*\\003\\003}, '')\n  while gsub!(/\\{[^{}]*\\}/, ''); end\n  gsub!(/'\\001'/, \"'{'\")\n  gsub!(/'\\002'/, \"'}'\")\n  while gsub!(/^[ \\t]*\\n(\\s)/, '\\1'); end\n  gsub!(/([:|])[ \\t\\n]+(\\w)/, '\\1 \\2')\n  print $_\nend\n"
  },
  {
    "path": "sample/fact.rb",
    "content": "def fact(n)\n  return 1 if n == 0\n  f = 1\n  n.downto(1) do |i|\n    f *= i\n  end\n  return f\nend\nprint fact(ARGV[0].to_i), \"\\n\"\n"
  },
  {
    "path": "sample/fib.awk",
    "content": "   function fib(n) {\n       if ( n<2 ) return n; else return fib(n-2) + fib(n-1)\n   }\n\n   BEGIN { print fib(20); }\n"
  },
  {
    "path": "sample/fib.pl",
    "content": "sub fib {\n    my($n)=@_;\n    if ($n<2) {\n\treturn $n;\n    }\n    else {\n\treturn fib($n-2)+fib($n-1);\n    }\n}\n\nprint fib(20), \"\\n\";\n"
  },
  {
    "path": "sample/fib.py",
    "content": "# calculate Fibonacci(20)\n# for benchmark\ndef fib(n):\n  if n<2:\n    return n\n  else:\n    return fib(n-2)+fib(n-1)\n\nprint fib(20)\n\n"
  },
  {
    "path": "sample/fib.rb",
    "content": "# calculate Fibonacci(20)\n# for benchmark\ndef fib(n)\n  if n<2\n    n\n  else\n    fib(n-2)+fib(n-1)\n  end\nend\nprint(fib(20), \"\\n\");\n"
  },
  {
    "path": "sample/fib.scm",
    "content": "(define (fib n)\n  (if (< n 2)\n      n\n      (+ (fib (- n 2)) (fib (- n 1)))))\n\n(display (fib 20))\n(newline)\n(quit)\n"
  },
  {
    "path": "sample/freq.rb",
    "content": "# word occurrence listing\n# usege: ruby freq.rb file..\nfreq = Hash.new(0)\nwhile line = gets()\n  line.scan(/\\w+/) do |word|\n    freq[word] += 1\n  end\nend\n\nfor word in freq.keys.sort!\n  print word, \" -- \", freq[word], \"\\n\"\nend\n"
  },
  {
    "path": "sample/from.rb",
    "content": "#! /usr/local/bin/ruby\n\nrequire \"parsedate\"\nrequire \"kconv\"\nrequire \"mailread\"\n\ninclude ParseDate\ninclude Kconv\n\nclass String\n\n  def kconv(code = Kconv::EUC)\n    Kconv.kconv(self, code, Kconv::AUTO)\n  end\n\n  def kjust(len)\n    len += 1\n    me = self[0, len].ljust(len)\n    if me =~ /.$/ and $&.size == 2\n      me[-2..-1] = '  '\n      me[-2, 2] = '  '\n    end\n    me.chop!\n  end\n\nend\n\nif ARGV[0] == '-w'\n  wait = true\n  ARGV.shift\nend\n\nif ARGV.length == 0\n  file = ENV['MAIL']\n  user = ENV['USER'] || ENV['USERNAME'] || ENV['LOGNAME'] \nelse\n  file = user = ARGV[0]\n  ARGV.clear\nend\n\nif file == nil or !File.exist? file\n  [ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|\n    if File.exist? f = \"#{m}/mail/#{user}\"\n      file = f\n      break \n    end\n  end\nend\n\n$outcount = 0;\ndef fromout(date, from, subj)\n  return if !date\n  y, m, d = parsedate(date) if date\n  y ||= 0; m ||= 0; d ||= 0\n  if from\n    from.gsub! /\\n/, \"\"\n  else\n    from = \"sombody@somewhere\"\n  end\n  if subj\n    subj.gsub! /\\n/, \"\"\n  else\n    subj = \"(nil)\"\n  end\n  if ENV['LANG'] =~ /sjis/i\n    lang = Kconv::SJIS\n  else\n    lang = Kconv::EUC\n  end\n  from = from.kconv(lang).kjust(28)\n  subj = subj.kconv(lang).kjust(40)\n  printf \"%02d/%02d/%02d [%s] %s\\n\",y%100,m,d,from,subj\n  $outcount += 1\nend\n\nif File.exist?(file)\n  atime = File.atime(file)\n  mtime = File.mtime(file)\n  f = open(file, \"r\")\n  begin\n    until f.eof?\n      mail = Mail.new(f)\n      fromout mail.header['Date'],mail.header['From'],mail.header['Subject']\n    end\n  ensure\n    f.close\n    File.utime(atime, mtime, file)\n  end\nend\n\nif $outcount == 0\n  print \"You have no mail.\\n\"\n  sleep 2 if wait\nelsif wait\n  system \"stty cbreak -echo\"\n  getc()\n  system \"stty cooked echo\"\nend\n"
  },
  {
    "path": "sample/fullpath.rb",
    "content": "#! /usr/local/bin/ruby\n# convert ls-lR filename into fullpath.\n\nif ARGV[0] =~ /-p/\n  ARGV.shift\n  path = ARGV.shift \nend\n\nif path == nil\n  path = \"\"\nelsif path !~ %r|/$|\n  path += \"/\"\nend\n\nwhile line = gets()\n  case line\n  when /:$/\n    path = line.chop.chop + \"/\"\n  when /^total/, /^d/\n  when /^(.*\\d )(.+)$/\n    print($1, path, $2, \"\\n\")\n  end\nend\n"
  },
  {
    "path": "sample/getopts.test",
    "content": "#! /usr/local/bin/ruby\n\nload(\"parsearg.rb\")\n\ndef usage()\n  printf \"Usage:\\n\"\n  printf \"%s -d [-x x] [-y y] [--geometry geom] [--version] [string ...]\\n\", $0\nend\n\n$USAGE = 'usage'\nparseArgs(0, \"d&(x|y)\", \"dfg\", \"x:\", \"y:\", \"geometry:800x600\", \"version\")\nif ($OPT_d)\n  if $OPT_version\n    printf \"version 1.0\\n\"\n  end\n  if ($OPT_x)\n    printf(\"x = %d\\n\", $OPT_x.to_i)\n  end\n  if ($OPT_y)\n    printf(\"y = %d\\n\", $OPT_y.to_i)\n  end\n  if ($OPT_geometry)\n    printf(\"geometry = %s\\n\", $OPT_geometry)\n  end\n  if $OPT_f\n    printf \"f = TRUE\\n\"\n  end\n  if $OPT_g\n    printf \"g = TRUE\\n\"\n  end\nend\n\nwhile (ARGV.length != 0)\n  print \"other = \", ARGV[0], \"\\n\"\n  ARGV.shift\nend\n"
  },
  {
    "path": "sample/less.rb",
    "content": "#! /usr/local/bin/ruby\n\nZCAT = \"/usr/local/bin/zcat\"\nLESS = \"/usr/local/bin/less\"\n\nFILE = ARGV.pop\nOPTION = (if ARGV.length == 0; \"\" else ARGV.join(\" \"); end)\n\nif FILE =~ /\\.(Z|gz)$/\n  exec(format(\"%s %s | %s %s\", ZCAT, FILE, LESS, OPTION))\nelsif FILE == nil\n  exec(format(\"%s %s\", LESS, OPTION))\nelse\n  print(format(\"%s %s %s\", LESS, OPTION, FILE), \"\\n\")\n  exec(format(\"%s %s %s\", LESS, OPTION, FILE))\nend\nexit()\n"
  },
  {
    "path": "sample/list.rb",
    "content": "# Linked list example\nclass MyElem\n  # object initializer called from Class#new\n  def initialize(item)\n    # @variables are instance variable, no declaration needed\n    @data = item\n    @succ = nil\n  end\n\n  def data\n    @data\n  end\n\n  def succ\n    @succ\n  end\n\n  # the method invoked by ``obj.data = val''\n  def succ=(new)\n    @succ = new\n  end\nend\n\nclass MyList\n  def add_to_list(obj)\n    elt = MyElem.new(obj)\n    if @head\n      @tail.succ = elt\n    else\n      @head = elt\n    end\n    @tail = elt\n  end\n\n  def each\n    elt = @head\n    while elt\n      yield elt\n      elt = elt.succ\n    end\n  end\n\n  # the method to convert object into string.\n  # redefining this will affect print.\n  def to_s\n    str = \"<MyList:\\n\";\n    for elt in self\n      # short form of ``str = str + elt.data.to_s + \"\\n\"''\n      str += elt.data.to_s + \"\\n\"\n    end\n    str += \">\"\n    str\n  end\nend\n\nclass Point\n  def initialize(x, y)\n    @x = x; @y = y\n    self\n  end\n\n  def to_s\n    sprintf(\"%d@%d\", @x, @y)\n  end\nend\n\n# global variable name starts with `$'.\n$list1 = MyList.new\n$list1.add_to_list(10)\n$list1.add_to_list(20)\n$list1.add_to_list(Point.new(2, 3))\n$list1.add_to_list(Point.new(4, 5))\n$list2 = MyList.new\n$list2.add_to_list(20)\n$list2.add_to_list(Point.new(4, 5))\n$list2.add_to_list($list1)\n\n# parenthesises around method arguments can be ommitted unless ambiguous.\nprint \"list1:\\n\", $list1, \"\\n\"\nprint \"list2:\\n\", $list2, \"\\n\"\n"
  },
  {
    "path": "sample/list2.rb",
    "content": "# Linked list example -- short version\nclass Point\n  def initialize(x, y)\n    @x = x; @y = y\n    self\n  end\n\n  def to_s\n    sprintf(\"%d@%d\", @x, @y)\n  end\nend\n    \nlist1 = [10, 20, Point.new(2, 3), Point.new(4, 5)]\nlist2 = [20, Point.new(4, 5), list1]\nprint(\"list1:\\n\", list1.join(\"\\n\"), \"\\n\")\nprint(\"list2:\\n\", list2.join(\"\\n\"), \"\\n\")\n"
  },
  {
    "path": "sample/list3.rb",
    "content": "# Linked list example -- short version\n# using inspect\n\nclass Point\n  def initialize(x, y)\n    @x = x; @y = y\n    self\n  end\n\n  def to_s\n    sprintf(\"%d@%d\", @x, @y)\n  end\nend\n    \nlist1 = [10, 20, Point.new(2, 3), Point.new(4, 5)]\nlist2 = [20, Point.new(4, 5), list1]\nprint(\"list1: \", list1.inspect, \"\\n\")\nprint(\"list2: \", list2.inspect, \"\\n\")\n"
  },
  {
    "path": "sample/logger/app.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'logger'\n\nclass MyApp < Logger::Application\n  def initialize(a, b, c)\n    super('MyApp')\n\n    # Set logDevice here.\n    logfile = 'app.log'\n    self.log = logfile\n    self.level = INFO\n\n    # Initialize your application...\n    @a = a\n    @b = b\n    @c = c\n  end\n\n  def run\n    @log.info  { 'Started.' }\n\n    @log.info  { \"This block isn't evaled because 'debug' is not severe here.\" }\n    @log.debug { \"Result = \" << foo(0) }\n    @log.info  { \"So nothing is dumped.\" }\n\n    @log.info  { \"This block is evaled because 'info' is enough severe here.\" }\n    @log.info  { \"Result = \" << foo(0) }\n    @log.info  { \"Above causes exception, so not reached here.\" }\n\n    @log.info  { 'Finished.' }\n  end\n\nprivate\n\n  def foo(var)\n    1 / var\n  end\nend\n\nstatus = MyApp.new(1, 2, 3).start\n\nif status != 0\n  puts 'Some error(s) occured.'\n  puts 'See \"app.log\".'\nend\n"
  },
  {
    "path": "sample/logger/log.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'logger'\n\nlog = Logger.new(STDERR)\n\ndef do_log(log)\n  log.debug('do_log1') { \"debug\" }\n  log.info('do_log2') { \"info\" }\n  log.warn('do_log3') { \"warn\" }\n  log.error('do_log4') { \"error\" }\n  log.fatal('do_log6') { \"fatal\" }\n  log.unknown('do_log7') { \"unknown\" }\nend\n\nlog.level = Logger::DEBUG\t# Default.\ndo_log(log)\n\nputs \"Set severity threshold 'WARN'.\"\n\nlog.level = Logger::WARN\ndo_log(log)\n\nputs \"Change datetime format.  Thanks to Daniel Berger.\"\n\nlog.datetime_format = \"%d-%b-%Y@%H:%M:%S\"\ndo_log(log)\n"
  },
  {
    "path": "sample/logger/shifting.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'logger'\n\nlogfile = 'shifting.log'\n# Max 3 age ... logShifting.log, logShifting.log.0, and logShifting.log.1\nshift_age = 3\n# Shift log file about for each 1024 bytes.\nshift_size = 1024\n\nlog = Logger.new(logfile, shift_age, shift_size)\n\ndef do_log(log)\n  log.debug('do_log1') { 'd' * rand(100) }\n  log.info('do_log2') { 'i' * rand(100) }\n  log.warn('do_log3') { 'w' * rand(100) }\n  log.error('do_log4') { 'e' * rand(100) }\n  log.fatal('do_log5') { 'f' * rand(100) }\n  log.unknown('do_log6') { 'u' * rand(100) }\nend\n\n(1..10).each do\n  do_log(log)\nend\n\nputs 'See shifting.log and shifting.log.[01].'\n"
  },
  {
    "path": "sample/mine.rb",
    "content": "#! /usr/bin/ruby -Ke\n\nclass Board\n  def clr\n    print \"\\e[2J\"\n  end\n  def pos(x,y)\n    printf \"\\e[%d;%dH\", y+1, x*2+1\n  end\n  def colorstr(id,s)\n    printf \"\\e[%dm%s\\e[0m\", id, s\n  end\n  def put(x, y, col, str)\n    pos(x,y); colorstr(43,str)\n    pos(0,@hi); print \"Ĥ:\",@mc,\"/\",@total,\"   \"\n    pos(x,y)\n  end\n  private :clr, :pos, :colorstr, :put\n  CHR=[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"@@\"]\n  COL=[46,43,45] # default,opened,over\n  def initialize(h,w,m)\n    # פ(h:ġw:m:Ƥο)\n    @hi=h; @wi=w; @m=m\n    reset\n  end\n  def reset\n    # פ()\n    srand()\n    @cx=0; @cy=0; @mc=@m\n    @over=false\n    @data=Array.new(@hi*@wi)\n    @state=Array.new(@hi*@wi)\n    @total=@hi*@wi\n    @total.times {|i| @data[i]=0}\n    @m.times do\n       loop do\n         j=rand(@total-1)\n         if @data[j] == 0 then\n           @data[j]=1\n           break\n         end\n       end\n    end\n    clr; pos(0,0)\n    @hi.times{|y| pos(0,y); colorstr(COL[0],CHR[0]*@wi)}\n    pos(@cx,@cy)\n  end\n  def mark\n    # ߤΥ֤˥ޡĤ\n    if @state[@wi*@cy+@cx] != nil then return end\n    @state[@wi*@cy+@cx] = \"MARK\"\n    @mc=@mc-1;\n    @total=@total-1;\n    put(@cx, @cy, COL[1], CHR[9])\n  end\n  def open(x=@cx,y=@cy)\n    # ߤΥ֤򥪡ץˤ\n    # ƤХ४С\n    if @state[@wi*y+x] ==\"OPEN\"  then return 0 end\n    if @state[@wi*y+x] == nil then @total=@total-1 end\n    if @state[@wi*y+x] ==\"MARK\" then @mc=@mc+1 end\n    @state[@wi*y+x]=\"OPEN\"\n    if fetch(x,y) == 1 then @over = 1; return end\n    c = count(x,y)\n    put(x, y, COL[1], CHR[c])\n    return 0 if c != 0\n    if x > 0 && y > 0         then open(x-1,y-1) end\n    if y > 0                  then open(x,  y-1) end\n    if x < @wi-1 && y > 0     then open(x+1,y-1) end\n    if x > 0                  then open(x-1,y) end\n    if x < @wi-1              then open(x+1,y) end\n    if x > 0 && y < @hi-1     then open(x-1,y+1) end\n    if y < @hi -1             then open(x,y+1) end\n    if x < @wi-1 && y < @hi-1 then open(x+1,y+1) end\n    pos(@cx,@cy)\n  end\n  def fetch(x,y)\n    # (x,y)ΰ֤Ƥο(0 or 1)֤\n    if x < 0 then 0\n    elsif x >= @wi then 0\n    elsif y < 0 then 0\n    elsif y >= @hi then 0\n    else\n      @data[y*@wi+x]\n    end\n  end\n  def count(x,y)\n    # (x,y)ܤƤο֤\n    fetch(x-1,y-1)+fetch(x,y-1)+fetch(x+1,y-1)+\n    fetch(x-1,y)  +             fetch(x+1,y)+\n    fetch(x-1,y+1)+fetch(x,y+1)+fetch(x+1,y+1)\n  end\n  def over(win)\n    # νλ\n    quit\n    unless win\n      pos(@cx,@cy); print CHR[11]\n    end\n    pos(0,@hi)\n    if win then print \"*** YOU WIN !! ***\"\n    else print \"*** GAME OVER ***\"\n    end\n  end\n  def over?\n    # νλå\n    # λƤӽФ\n    remain = (@mc+@total == 0)\n    if @over || remain\n      over(remain)\n      true\n    else\n      false\n    end\n  end\n  def quit\n    # (ޤϽλ)\n    # ̤Ƹ\n    @hi.times do|y|\n      pos(0,y)\n      @wi.times do|x|\n\tcolorstr(if @state[y*@wi+x] == \"MARK\" then COL[1] else COL[2] end,\n\t\t if fetch(x,y)==1 then CHR[10] else CHR[count(x,y)] end)\n      end\n    end\n  end\n  def down\n    # 򲼤\n    if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end\n  end\n  def up\n    # \n    if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end\n  end\n  def left\n    # 򺸤\n    if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end\n  end\n  def right\n    # 򱦤\n    if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end\n  end\nend\n\nbd=Board.new(10,10,10)\nsystem(\"stty raw -echo\")\nbegin\n  loop do\n    case STDIN.getc\n    when ?n  # new game\n      bd.reset\n    when ?m  # mark\n      bd.mark\n    when ?j\n      bd.down\n    when ?k\n      bd.up\n    when ?h\n      bd.left\n    when ?l\n      bd.right\n    when ?\\s\n      bd.open\n    when ?q,?\\C-c  # quit game\n      bd.quit\n      break\n    end\n    if bd.over?\n      if STDIN.getc == ?q then break end\n      bd.reset\n    end\n  end\nensure\n  system(\"stty -raw echo\")\nend\nprint \"\\n\"\n"
  },
  {
    "path": "sample/mkproto.rb",
    "content": "$/ = nil\nwhile line = gets()\n  if /^((void|VALUE|int|char *\\*|ID|struct [\\w_]+ *\\*|st_table *\\*) *)?\\n([\\w\\d_]+)\\(.*\\)\\n\\s*((.+;\\n)*)\\{/ =~ line\n    line = $'\n    printf \"%s %s(\", $2, $3\n    args = []\n    for arg in $4.split(/;\\n\\s*/)\n      arg.gsub!(/ +/, ' ')\n      if arg =~ /,/\n\tif arg =~ /(([^*]+) *\\** *[\\w\\d_]+),/\n\t  type = $2.strip\n\t  args.push $1.strip\n\t  arg = $'\n\telse\n\t  type = \"\"\n\tend\n\twhile arg.sub!(/(\\** *[\\w\\d_]+)(,|$)/, \"\") && $~\n\t  args.push type + \" \" + $1.strip\n\tend\n      else\n\targs.push arg.strip\n      end\n    end\n    printf \"%s);\\n\", args.join(', ')\n    redo\n  end\nend\n"
  },
  {
    "path": "sample/mpart.rb",
    "content": "#! ./ruby\n# split into multi part\n# usage: mpart.rb [-nnn] file..\n\nlines = 1000\n\nif (ARGV[0] =~ /^-(\\d+)$/ )\n  lines = $1.to_i;\n  ARGV.shift;\nend\n\nbasename = ARGV[0]\nextname = \"part\"\n\npart = 1\nline = 0\n\nfline = 0\nfor i in ifp = open(basename)\n  fline = fline + 1\nend\nifp.close\n\nparts = fline / lines + 1\n\nfor i in ifp = open(basename)\n  if line == 0\n    ofp = open(sprintf(\"%s.%s%02d\", basename, extname, part), \"w\")\n    printf(ofp, \"%s part%02d/%02d\\n\", basename, part, parts)\n    ofp.write(\"BEGIN--cut here--cut here\\n\")\n  end\n  ofp.write(i)\n  line = line + 1\n  if line >= lines and !ifp.eof?\n    ofp.write(\"END--cut here--cut here\\n\")\n    ofp.close\n    part = part + 1\n    line = 0\n  end\nend\nofp.write(\"END--cut here--cut here\\n\")\nofp.close\n\nifp.close\n"
  },
  {
    "path": "sample/mrshtest.rb",
    "content": "include Marshal\na = 25.6;\npt = Struct.new('Point', :x,:y);\nx = pt.new(10, 10)\ny = pt.new(20, 20)\nrt = Struct.new('Rectangle', :origin,:corner);\nz = rt.new(x, y)\nc = Object.new\ns = [a, x, z, c, c, \"fff\"];\np s\nd = dump(s);\np d\np load(d)\n"
  },
  {
    "path": "sample/observ.rb",
    "content": "#! /usr/local/bin/ruby\n\nrequire \"thread\"\nrequire \"observer\"\n\nclass Tick\n  include Observable\n  def initialize\n    Thread.start do\n      loop do\n\tsleep 0.999\n\tnow = Time.now\n\tchanged\n\tnotify_observers(now.hour, now.min, now.sec)\n      end\n    end\n  end\nend\n\nclass Clock\n  def initialize(tick)\n    @tick = tick\n    @tick.add_observer(self)\n  end\n  def update(h, m, s)\n    printf \"\\e[8D%02d:%02d:%02d\", h, m, s\n    STDOUT.flush\n  end\nend\n\nclock = Clock.new(Tick.new)\nsleep\n"
  },
  {
    "path": "sample/occur.pl",
    "content": "while (<>) {\n    for (split(/\\W+/)) {\n\t$freq{$_}++;\n    }\n}\n\nfor (sort keys %freq) {\n    print \"$_ -- $freq{$_}\\n\";\n}\n"
  },
  {
    "path": "sample/occur.rb",
    "content": "# word occurrence listing\n# usege: ruby occur.rb file..\nfreq = Hash.new(0)\nwhile gets()\n  for word in split(/\\W+/)\n    freq[word] += 1\n  end\nend\n\nfor word in freq.keys.sort!\n  print word, \" -- \", freq[word], \"\\n\"\nend\n"
  },
  {
    "path": "sample/occur2.rb",
    "content": "# word occurrence listing\n# usege: ruby occur2.rb file..\nfreq = {}\nwhile gets()\n  for word in split(/\\W+/)\n    begin\n      freq[word] += 1\n    rescue NameError\n      freq[word] = 1\n    end\n  end\nend\n\nfor word in freq.keys.sort\n  printf(\"%s -- %d\\n\", word, freq[word])\nend\n"
  },
  {
    "path": "sample/openssl/c_rehash.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'openssl'\nrequire 'digest/md5'\n\nclass CHashDir\n  include Enumerable\n\n  def initialize(dirpath)\n    @dirpath = dirpath\n    @fingerprint_cache = @cert_cache = @crl_cache = nil\n  end\n\n  def hash_dir(silent = false)\n    # ToDo: Should lock the directory...\n    @silent = silent\n    @fingerprint_cache = Hash.new\n    @cert_cache = Hash.new\n    @crl_cache = Hash.new\n    do_hash_dir\n  end\n\n  def get_certs(name = nil)\n    if name\n      @cert_cache[hash_name(name)]\n    else\n      @cert_cache.values.flatten\n    end\n  end\n\n  def get_crls(name = nil)\n    if name\n      @crl_cache[hash_name(name)]\n    else\n      @crl_cache.values.flatten\n    end\n  end\n\n  def delete_crl(crl)\n    File.unlink(crl_filename(crl))\n    hash_dir(true)\n  end\n\n  def add_crl(crl)\n    File.open(crl_filename(crl), \"w\") do |f|\n      f << crl.to_pem\n    end\n    hash_dir(true)\n  end\n\n  def load_pem_file(filepath)\n    str = File.read(filepath)\n    begin\n      OpenSSL::X509::Certificate.new(str)\n    rescue\n      begin\n\tOpenSSL::X509::CRL.new(str)\n      rescue\n\tbegin\n\t  OpenSSL::X509::Request.new(str)\n\trescue\n\t  nil\n\tend\n      end\n    end\n  end\n\nprivate\n\n  def crl_filename(crl)\n    path(hash_name(crl.issuer)) + '.pem'\n  end\n\n  def do_hash_dir\n    Dir.chdir(@dirpath) do\n      delete_symlink\n      Dir.glob('*.pem') do |pemfile|\n\tcert = load_pem_file(pemfile)\n\tcase cert\n\twhen OpenSSL::X509::Certificate\n\t  link_hash_cert(pemfile, cert)\n\twhen OpenSSL::X509::CRL\n\t  link_hash_crl(pemfile, cert)\n\telse\n\t  STDERR.puts(\"WARNING: #{pemfile} does not contain a certificate or CRL: skipping\") unless @silent\n\tend\n      end\n    end\n  end\n\n  def delete_symlink\n    Dir.entries(\".\").each do |entry|\n      next unless /^[\\da-f]+\\.r{0,1}\\d+$/ =~ entry\n      File.unlink(entry) if FileTest.symlink?(entry)\n    end\n  end\n\n  def link_hash_cert(org_filename, cert)\n    name_hash = hash_name(cert.subject)\n    fingerprint = fingerprint(cert.to_der)\n    filepath = link_hash(org_filename, name_hash, fingerprint) { |idx|\n      \"#{name_hash}.#{idx}\"\n    }\n    unless filepath\n      unless @silent\n\tSTDERR.puts(\"WARNING: Skipping duplicate certificate #{org_filename}\")\n      end\n    else\n      (@cert_cache[name_hash] ||= []) << path(filepath)\n    end\n  end\n\n  def link_hash_crl(org_filename, crl)\n    name_hash = hash_name(crl.issuer)\n    fingerprint = fingerprint(crl.to_der)\n    filepath = link_hash(org_filename, name_hash, fingerprint) { |idx|\n      \"#{name_hash}.r#{idx}\"\n    }\n    unless filepath\n      unless @silent\n\tSTDERR.puts(\"WARNING: Skipping duplicate CRL #{org_filename}\")\n      end\n    else\n      (@crl_cache[name_hash] ||= []) << path(filepath)\n    end\n  end\n\n  def link_hash(org_filename, name, fingerprint)\n    idx = 0\n    filepath = nil\n    while true\n      filepath = yield(idx)\n      break unless FileTest.symlink?(filepath) or FileTest.exist?(filepath)\n      if @fingerprint_cache[filepath] == fingerprint\n\treturn false\n      end\n      idx += 1\n    end\n    STDOUT.puts(\"#{org_filename} => #{filepath}\") unless @silent\n    symlink(org_filename, filepath)\n    @fingerprint_cache[filepath] = fingerprint\n    filepath\n  end\n\n  def symlink(from, to)\n    begin\n      File.symlink(from, to)\n    rescue\n      File.open(to, \"w\") do |f|\n\tf << File.read(from)\n      end\n    end\n  end\n\n  def path(filename)\n    File.join(@dirpath, filename)\n  end\n\n  def hash_name(name)\n    sprintf(\"%x\", name.hash)\n  end\n\n  def fingerprint(der)\n    Digest::MD5.hexdigest(der).upcase\n  end\nend\n\nif $0 == __FILE__\n  dirlist = ARGV\n  dirlist << '/usr/ssl/certs' if dirlist.empty?\n  dirlist.each do |dir|\n    CHashDir.new(dir).hash_dir\n  end\nend\n"
  },
  {
    "path": "sample/openssl/cert2text.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'openssl'\ninclude OpenSSL::X509\n\ndef cert2text(cert_str)\n  [Certificate, CRL, Request].each do |klass|\n    begin\n      puts klass.new(cert_str).to_text\n      return\n    rescue\n    end\n  end\n  raise ArgumentError.new('Unknown format.')\nend\n\nif ARGV.empty?\n  cert2text(STDIN.read)\nelse\n  ARGV.each do |file|\n    cert2text(File.read(file))\n  end\nend\n"
  },
  {
    "path": "sample/openssl/cert_store_view.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'fox'\nrequire 'openssl'\nrequire 'time'\nrequire 'certstore'\nrequire 'getopts'\n\ninclude Fox\n\nmodule CertDumpSupport\n  def cert_label(cert)\n    subject_alt_name =\n      cert.extensions.find { |ext| ext.oid == 'subjectAltName' }\n    if subject_alt_name\n      subject_alt_name.value.split(/\\s*,\\s/).each do |alt_name_pair|\n\talt_tag, alt_name = alt_name_pair.split(/:/)\n\treturn alt_name\n      end\n    end\n    name_label(cert.subject)\n  end\n\n  def name_label(name)\n    ary = name.to_a\n    if (cn = ary.find { |rdn| rdn[0] == 'CN' })\n      return cn[1]\n    end\n    if ary.last[0] == 'OU'\n      return ary.last[1]\n    end\n    name.to_s\n  end\n\n  def name_text(name)\n    name.to_a.collect { |tag, value|\n      \"#{tag} = #{value}\"\n    }.reverse.join(\"\\n\")\n  end\n\n  def bn_label(bn)\n    (\"0\" << sprintf(\"%X\", bn)).scan(/../).join(\" \")\n  end\nend\n\nclass CertDump\n  include CertDumpSupport\n\n  def initialize(cert)\n    @cert = cert\n  end\n\n  def get_dump(tag)\n    case tag\n    when 'Version'\n      version\n    when 'Serial'\n      serial\n    when 'Signature Algorithm'\n      signature_algorithm\n    when 'Issuer'\n      issuer\n    when 'Validity'\n      validity\n    when 'Not before'\n      not_before\n    when 'Not after'\n      not_after\n    when 'Subject'\n      subject\n    when 'Public key'\n      public_key\n    else\n      ext(tag)\n    end\n  end\n\n  def get_dump_line(tag)\n    case tag\n    when 'Version'\n      version_line\n    when 'Serial'\n      serial_line\n    when 'Signature Algorithm'\n      signature_algorithm_line\n    when 'Subject'\n      subject_line\n    when 'Issuer'\n      issuer_line\n    when 'Validity'\n      validity_line\n    when 'Not before'\n      not_before_line\n    when 'Not after'\n      not_after_line\n    when 'Public key'\n      public_key_line\n    else\n      ext_line(tag)\n    end\n  end\n\nprivate\n\n  def version\n    \"Version: #{@cert.version + 1}\"\n  end\n\n  def version_line\n    version\n  end\n\n  def serial\n    bn_label(@cert.serial)\n  end\n\n  def serial_line\n    serial\n  end\n\n  def signature_algorithm\n    @cert.signature_algorithm\n  end\n\n  def signature_algorithm_line\n    signature_algorithm\n  end\n\n  def subject\n    name_text(@cert.subject)\n  end\n\n  def subject_line\n    @cert.subject.to_s\n  end\n\n  def issuer\n    name_text(@cert.issuer)\n  end\n\n  def issuer_line\n    @cert.issuer.to_s\n  end\n\n  def validity\n    <<EOS\nNot before: #{not_before}\nNot after: #{not_after}\nEOS\n  end\n\n  def validity_line\n    \"from #{@cert.not_before.iso8601} to #{@cert.not_after.iso8601}\"\n  end\n\n  def not_before\n    @cert.not_before.to_s\n  end\n\n  def not_before_line\n    not_before\n  end\n\n  def not_after\n    @cert.not_after.to_s\n  end\n\n  def not_after_line\n    not_after\n  end\n\n  def public_key\n    @cert.public_key.to_text\n  end\n\n  def public_key_line\n    \"#{@cert.public_key.class} -- \" << public_key.scan(/\\A[^\\n]*/)[0] << '...'\n  end\n\n  def ext(tag)\n    @cert.extensions.each do |ext|\n      if ext.oid == tag\n\treturn ext_detail(tag, ext.value)\n      end\n    end\n    \"(unknown)\"\n  end\n\n  def ext_line(tag)\n    ext(tag).tr(\"\\r\\n\", '')\n  end\n\n  def ext_detail(tag, value)\n    value\n  end\nend\n\nclass CrlDump\n  include CertDumpSupport\n\n  def initialize(crl)\n    @crl = crl\n  end\n\n  def get_dump(tag)\n    case tag\n    when 'Version'\n      version\n    when 'Signature Algorithm'\n      signature_algorithm\n    when 'Issuer'\n      issuer\n    when 'Last update'\n      last_update\n    when 'Next update'\n      next_update\n    else\n      ext(tag)\n    end\n  end\n\n  def get_dump_line(tag)\n    case tag\n    when 'Version'\n      version_line\n    when 'Signature Algorithm'\n      signature_algorithm_line\n    when 'Issuer'\n      issuer_line\n    when 'Last update'\n      last_update_line\n    when 'Next update'\n      next_update_line\n    else\n      ext_line(tag)\n    end\n  end\n\nprivate\n\n  def version\n    \"Version: #{@crl.version + 1}\"\n  end\n\n  def version_line\n    version\n  end\n\n  def signature_algorithm\n    @crl.signature_algorithm\n  end\n\n  def signature_algorithm_line\n    signature_algorithm\n  end\n\n  def issuer\n    name_text(@crl.issuer)\n  end\n\n  def issuer_line\n    @crl.issuer.to_s\n  end\n\n  def last_update\n    @crl.last_update.to_s\n  end\n\n  def last_update_line\n    last_update\n  end\n\n  def next_update\n    @crl.next_update.to_s\n  end\n\n  def next_update_line\n    next_update\n  end\n\n  def ext(tag)\n    @crl.extensions.each do |ext|\n      if ext.oid == tag\n\treturn ext_detail(tag, ext.value)\n      end\n    end\n    \"(unknown)\"\n  end\n\n  def ext_line(tag)\n    ext(tag).tr(\"\\r\\n\", '')\n  end\n\n  def ext_detail(tag, value)\n    value\n  end\nend\n\nclass RevokedDump\n  include CertDumpSupport\n\n  def initialize(revoked)\n    @revoked = revoked\n  end\n\n  def get_dump(tag)\n    case tag\n    when 'Serial'\n      serial\n    when 'Time'\n      time\n    else\n      ext(tag)\n    end\n  end\n\n  def get_dump_line(tag)\n    case tag\n    when 'Serial'\n      serial_line\n    when 'Time'\n      time_line\n    else\n      ext_line(tag)\n    end\n  end\n\nprivate\n\n  def serial\n    bn_label(@revoked.serial)\n  end\n\n  def serial_line\n    serial\n  end\n\n  def time\n    @revoked.time.to_s\n  end\n\n  def time_line\n    time\n  end\n\n  def ext(tag)\n    @revoked.extensions.each do |ext|\n      if ext.oid == tag\n\treturn ext_detail(tag, ext.value)\n      end\n    end\n    \"(unknown)\"\n  end\n\n  def ext_line(tag)\n    ext(tag).tr(\"\\r\\n\", '')\n  end\n\n  def ext_detail(tag, value)\n    value\n  end\nend\n\nclass RequestDump\n  include CertDumpSupport\n\n  def initialize(req)\n    @req = req\n  end\n\n  def get_dump(tag)\n    case tag\n    when 'Version'\n      version\n    when 'Signature Algorithm'\n      signature_algorithm\n    when 'Subject'\n      subject\n    when 'Public key'\n      public_key\n    else\n      attributes(tag)\n    end\n  end\n\n  def get_dump_line(tag)\n    case tag\n    when 'Version'\n      version_line\n    when 'Signature Algorithm'\n      signature_algorithm_line\n    when 'Subject'\n      subject_line\n    when 'Public key'\n      public_key_line\n    else\n      attributes_line(tag)\n    end\n  end\n\nprivate\n\n  def version\n    \"Version: #{@req.version + 1}\"\n  end\n\n  def version_line\n    version\n  end\n\n  def signature_algorithm\n    @req.signature_algorithm\n  end\n\n  def signature_algorithm_line\n    signature_algorithm\n  end\n\n  def subject\n    name_text(@req.subject)\n  end\n\n  def subject_line\n    @req.subject.to_s\n  end\n\n  def public_key\n    @req.public_key.to_text\n  end\n\n  def public_key_line\n    \"#{@req.public_key.class} -- \" << public_key.scan(/\\A[^\\n]*/)[0] << '...'\n  end\n\n  def attributes(tag)\n    \"(unknown)\"\n  end\n\n  def attributes_line(tag)\n    attributes(tag).tr(\"\\r\\n\", '')\n  end\nend\n\nclass CertStoreView < FXMainWindow\n  class CertTree\n    include CertDumpSupport\n\n    def initialize(observer, tree)\n      @observer = observer\n      @tree = tree\n      @tree.connect(SEL_COMMAND) do |sender, sel, item|\n       \tif item.data\n  \t  @observer.getApp().beginWaitCursor do\n  \t    @observer.show_item(item.data)\n  \t  end\n\telse\n\t  @observer.show_item(nil)\n  \tend\n      end\n    end\n\n    def show(cert_store)\n      @tree.clearItems\n      @self_signed_ca_node = add_item_last(nil, \"Trusted root CA\")\n      @other_ca_node = add_item_last(nil, \"Intermediate CA\")\n      @ee_node = add_item_last(nil, \"Personal\")\n      @crl_node = add_item_last(nil, \"CRL\")\n      @request_node = add_item_last(nil, \"Request\")\n      @verify_path_node = add_item_last(nil, \"Certification path\")\n      show_certs(cert_store)\n    end\n\n    def show_certs(cert_store)\n      remove_items(@self_signed_ca_node)\n      remove_items(@other_ca_node)\n      remove_items(@ee_node)\n      remove_items(@crl_node)\n      remove_items(@request_node)\n      import_certs(cert_store)\n    end\n\n    def show_request(req)\n      node = add_item_last(@request_node, name_label(req.subject), req)\n      @tree.selectItem(node)\n      @observer.show_item(req)\n    end\n\n    def show_verify_path(verify_path)\n      add_verify_path(verify_path)\n    end\n\n  private\n\n    def open_node(node)\n      node.expanded = node.opened = true\n    end\n\n    def close_node(node)\n      node.expanded = node.opened = false\n    end\n\n    def import_certs(cert_store)\n      cert_store.self_signed_ca.each do |cert|\n\tadd_item_last(@self_signed_ca_node, cert_label(cert), cert)\n      end\n      cert_store.other_ca.each do |cert|\n\tadd_item_last(@other_ca_node, cert_label(cert), cert)\n      end\n      cert_store.ee.each do |cert|\n\tadd_item_last(@ee_node, cert_label(cert), cert)\n      end\n      cert_store.crl.each do |crl|\n\tnode = add_item_last(@crl_node, name_label(crl.issuer), crl)\n\tclose_node(node)\n\tcrl.revoked.each do |revoked|\n\t  add_item_last(node, bn_label(revoked.serial), revoked)\n\tend\n      end\n      cert_store.request.each do |req|\n\tadd_item_last(@requestnode, name_label(req.subject), req)\n      end\n    end\n\n    def add_verify_path(verify_path)\n      node = @verify_path_node\n      last_cert = nil\n      verify_path.reverse_each do |ok, cert, crl_check, error_string|\n\twarn = []\n\tif @observer.cert_store.is_ca?(cert)\n\t  warn << 'NO ARL' unless crl_check\n\telse\n\t  warn << 'NO CRL' unless crl_check\n\tend\n\twarn_str = '(' << warn.join(\", \") << ')'\n\twarn_mark = warn.empty? ? '' : '!'\n\tlabel = if ok\n\t    \"OK#{warn_mark}...\" + cert_label(cert)\n\t  else\n\t    \"NG(#{error_string})...\" + cert_label(cert)\n\t  end\n\tlabel << warn_str unless warn.empty?\n\tnode = add_item_last(node, label, cert)\n\tnode.expanded = true\n\tlast_cert = cert\n      end\n      if last_cert\n\t@tree.selectItem(node)\n\t@observer.show_item(last_cert)\n      end\n    end\n\n    def add_item_last(parent, label, obj = nil)\n      node = @tree.addItemLast(parent, FXTreeItem.new(label))\n      node.data = obj if obj\n      open_node(node)\n      node\n    end\n\n    def remove_items(node)\n      while node.getNumChildren > 0\n\t@tree.removeItem(node.getFirst)\n      end\n    end\n  end\n\n  class CertInfo\n    def initialize(observer, table)\n      @observer = observer\n      @table = table\n      @table.leadingRows = 0\n      @table.leadingCols = 0\n      @table.trailingRows = 0\n      @table.trailingCols = 0\n      @table.showVertGrid(false)\n      @table.showHorzGrid(false)\n      @table.setTableSize(1, 2)\n      @table.setColumnWidth(0, 125)\n      @table.setColumnWidth(1, 350)\n    end\n\n    def show(item)\n      @observer.show_detail(nil, nil)\n      if item.nil?\n\tset_column_size(1)\n\treturn\n      end\n      case item\n      when OpenSSL::X509::Certificate\n\tshow_cert(item)\n      when OpenSSL::X509::CRL\n\tshow_crl(item)\n      when OpenSSL::X509::Revoked\n\tshow_revoked(item)\n      when OpenSSL::X509::Request\n\tshow_request(item)\n      else\n\traise NotImplementedError.new(\"Unknown item type #{item.class}.\")\n      end\n    end\n\n  private\n\n    def show_cert(cert)\n      wrap = CertDump.new(cert)\n      items = []\n      items << ['Version', wrap.get_dump_line('Version')]\n      items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]\n      items << ['Issuer', wrap.get_dump_line('Issuer')]\n      items << ['Serial', wrap.get_dump_line('Serial')]\n      #items << ['Not before', wrap.get_dump_line('Not before')]\n      #items << ['Not after', wrap.get_dump_line('Not after')]\n      items << ['Subject', wrap.get_dump_line('Subject')]\n      items << ['Public key', wrap.get_dump_line('Public key')]\n      items << ['Validity', wrap.get_dump_line('Validity')]\n      (cert.extensions.sort { |a, b| a.oid <=> b.oid }).each do |ext|\n\titems << [ext.oid, wrap.get_dump_line(ext.oid)]\n      end\n      show_items(cert, items)\n    end\n\n    def show_crl(crl)\n      wrap = CrlDump.new(crl)\n      items = []\n      items << ['Version', wrap.get_dump_line('Version')]\n      items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]\n      items << ['Issuer', wrap.get_dump_line('Issuer')]\n      items << ['Last update', wrap.get_dump_line('Last update')]\n      items << ['Next update', wrap.get_dump_line('Next update')]\n      crl.extensions.each do |ext|\n\titems << [ext.oid, wrap.get_dump_line(ext.oid)]\n      end\n      show_items(crl, items)\n    end\n\n    def show_revoked(revoked)\n      wrap = RevokedDump.new(revoked)\n      items = []\n      items << ['Serial', wrap.get_dump_line('Serial')]\n      items << ['Time', wrap.get_dump_line('Time')]\n      revoked.extensions.each do |ext|\n\titems << [ext.oid, wrap.get_dump_line(ext.oid)]\n      end\n      show_items(revoked, items)\n    end\n\n    def show_request(req)\n      wrap = RequestDump.new(req)\n      items = []\n      items << ['Version', wrap.get_dump_line('Version')]\n      items << ['Signature Algorithm', wrap.get_dump_line('Signature Algorithm')]\n      items << ['Subject', wrap.get_dump_line('Subject')]\n      items << ['Public key', wrap.get_dump_line('Public key')]\n      req.attributes.each do |attr|\n\titems << [attr.attr, wrap.get_dump_line(attr.oid)]\n      end\n      show_items(req, items)\n    end\n\n    def show_items(obj, items)\n      set_column_size(items.size)\n      items.each_with_index do |ele, idx|\n\ttag, value = ele\n\t@table.setItemText(idx, 0, tag)\n\t@table.getItem(idx, 0).data = tag\n\t@table.setItemText(idx, 1, value.to_s)\n\t@table.getItem(idx, 1).data = tag\n      end\n      @table.connect(SEL_COMMAND) do |sender, sel, loc|\n\titem = @table.getItem(loc.row, loc.col)\n\t@observer.show_detail(obj, item.data)\n      end\n      justify_table\n    end\n\n    def set_column_size(size)\n      col0_width = @table.getColumnWidth(0)\n      col1_width = @table.getColumnWidth(1)\n      @table.setTableSize(size, 2)\n      @table.setColumnWidth(0, col0_width)\n      @table.setColumnWidth(1, col1_width)\n    end\n\n    def justify_table\n      for col in 0..@table.numCols-1\n      \tfor row in 0..@table.numRows-1\n  \t  @table.getItem(row, col).justify = FXTableItem::LEFT\n   \tend\n      end\n    end\n  end\n\n  class CertDetail\n    def initialize(observer, detail)\n      @observer = observer\n      @detail = detail\n    end\n\n    def show(item, tag)\n      if item.nil?\n\t@detail.text = ''\n\treturn\n      end\n      case item\n      when OpenSSL::X509::Certificate\n\tshow_cert(item, tag)\n      when OpenSSL::X509::CRL\n\tshow_crl(item, tag)\n      when OpenSSL::X509::Revoked\n\tshow_revoked(item, tag)\n      when OpenSSL::X509::Request\n\tshow_request(item, tag)\n      else\n\traise NotImplementedError.new(\"Unknown item type #{item.class}.\")\n      end\n    end\n\n  private\n\n    def show_cert(cert, tag)\n      wrap = CertDump.new(cert)\n      @detail.text = wrap.get_dump(tag)\n    end\n\n    def show_crl(crl, tag)\n      wrap = CrlDump.new(crl)\n      @detail.text = wrap.get_dump(tag)\n    end\n\n    def show_revoked(revoked, tag)\n      wrap = RevokedDump.new(revoked)\n      @detail.text = wrap.get_dump(tag)\n    end\n\n    def show_request(request, tag)\n      wrap = RequestDump.new(request)\n      @detail.text = wrap.get_dump(tag)\n    end\n  end\n\n  attr_reader :cert_store\n\n  def initialize(app, cert_store)\n    @cert_store = cert_store\n    @verify_filter = 0\n    @verify_filename = nil\n    full_width = 800\n    full_height = 500\n    horz_pos = 300\n\n    super(app, \"Certificate store\", nil, nil, DECOR_ALL, 0, 0, full_width,\n      full_height)\n\n    FXTooltip.new(self.getApp())\n\n    menubar = FXMenubar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)\n    file_menu = FXMenuPane.new(self)\n    FXMenuTitle.new(menubar, \"&File\", nil, file_menu)\n    file_open_menu = FXMenuPane.new(self)\n    FXMenuCommand.new(file_open_menu, \"&Directory\\tCtl-O\").connect(SEL_COMMAND,\n      method(:on_cmd_file_open_dir))\n    FXMenuCascade.new(file_menu, \"&Open\\tCtl-O\", nil, file_open_menu)\n    FXMenuCommand.new(file_menu, \"&Quit\\tCtl-Q\", nil, getApp(), FXApp::ID_QUIT)\n\n    tool_menu = FXMenuPane.new(self)\n    FXMenuTitle.new(menubar, \"&Tool\", nil, tool_menu)\n    FXMenuCommand.new(tool_menu, \"&Verify\\tCtl-N\").connect(SEL_COMMAND,\n      method(:on_cmd_tool_verify))\n    FXMenuCommand.new(tool_menu, \"&Show Request\\tCtl-R\").connect(SEL_COMMAND,\n      method(:on_cmd_tool_request))\n\n    base_frame = FXHorizontalFrame.new(self, LAYOUT_FILL_X | LAYOUT_FILL_Y)\n    splitter_horz = FXSplitter.new(base_frame, LAYOUT_SIDE_TOP | LAYOUT_FILL_X |\n    LAYOUT_FILL_Y | SPLITTER_TRACKING | SPLITTER_HORIZONTAL)\n\n    # Cert tree\n    cert_tree_frame = FXHorizontalFrame.new(splitter_horz, LAYOUT_FILL_X |\n      LAYOUT_FILL_Y | FRAME_SUNKEN | FRAME_THICK)\n    cert_tree_frame.setWidth(horz_pos)\n    cert_tree = FXTreeList.new(cert_tree_frame, 0, nil, 0,\n      TREELIST_BROWSESELECT | TREELIST_SHOWS_LINES | TREELIST_SHOWS_BOXES |\n      TREELIST_ROOT_BOXES | LAYOUT_FILL_X | LAYOUT_FILL_Y)\n    @cert_tree = CertTree.new(self, cert_tree)\n\n    # Cert info\n    splitter_vert = FXSplitter.new(splitter_horz, LAYOUT_SIDE_TOP |\n      LAYOUT_FILL_X | LAYOUT_FILL_Y | SPLITTER_TRACKING | SPLITTER_VERTICAL |\n      SPLITTER_REVERSED)\n    cert_list_base = FXVerticalFrame.new(splitter_vert, LAYOUT_FILL_X |\n      LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)\n    cert_list_frame = FXHorizontalFrame.new(cert_list_base, FRAME_SUNKEN |\n      FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y)\n    cert_info = FXTable.new(cert_list_frame, 2, 10, nil, 0, FRAME_SUNKEN |\n      TABLE_COL_SIZABLE | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 2, 2, 2, 2)\n    @cert_info = CertInfo.new(self, cert_info)\n\n    cert_detail_base = FXVerticalFrame.new(splitter_vert, LAYOUT_FILL_X |\n      LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0)\n    cert_detail_frame = FXHorizontalFrame.new(cert_detail_base, FRAME_SUNKEN |\n      FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y)\n    cert_detail = FXText.new(cert_detail_frame, nil, 0, TEXT_READONLY |\n      LAYOUT_FILL_X | LAYOUT_FILL_Y)\n    @cert_detail = CertDetail.new(self, cert_detail)\n\n    show_init\n  end\n\n  def create\n    super\n    show(PLACEMENT_SCREEN)\n  end\n\n  def show_init\n    @cert_tree.show(@cert_store)\n    show_item(nil)\n  end\n\n  def show_certs\n    @cert_tree.show_certs(@cert_store)\n  end\n\n  def show_request(req)\n    @cert_tree.show_request(req)\n  end\n\n  def show_verify_path(verify_path)\n    @cert_tree.show_verify_path(verify_path)\n  end\n\n  def show_item(item)\n    @cert_info.show(item) if @cert_info\n  end\n\n  def show_detail(item, tag)\n    @cert_detail.show(item, tag) if @cert_detail\n  end\n\n  def verify(certfile)\n    path = verify_certfile(certfile)\n    show_certs\t# CRL could be change.\n    show_verify_path(path)\n  end\n\nprivate\n\n  def on_cmd_file_open_dir(sender, sel, ptr)\n    dir = FXFileDialog.getOpenDirectory(self, \"Open certificate directory\", \".\")\n    unless dir.empty?\n      begin\n\t@cert_store = CertStore.new(dir)\n      rescue\n\tshow_error($!)\n      end\n      show_init\n    end\n    1\n  end\n\n  def on_cmd_tool_verify(sender, sel, ptr)\n    dialog = FXFileDialog.new(self, \"Verify certificate\")\n    dialog.filename = ''\n    dialog.patternList = [\"All Files (*)\", \"PEM formatted certificate (*.pem)\"]\n    dialog.currentPattern = @verify_filter\n    if dialog.execute != 0\n      @verify_filename = dialog.filename\n      verify(@verify_filename)\n    end\n    @verify_filter = dialog.currentPattern\n    1\n  end\n\n  def on_cmd_tool_request(sender, sel, ptr)\n    dialog = FXFileDialog.new(self, \"Show request\")\n    dialog.filename = ''\n    dialog.patternList = [\"All Files (*)\", \"PEM formatted certificate (*.pem)\"]\n    if dialog.execute != 0\n      req = @cert_store.generate_cert(dialog.filename)\n      show_request(req)\n    end\n    1\n  end\n\n  def verify_certfile(filename)\n    begin\n      cert = @cert_store.generate_cert(filename)\n      result = @cert_store.verify(cert)\n      @cert_store.scan_certs\n      result\n    rescue\n      show_error($!)\n      []\n    end\n  end\n\n  def show_error(e)\n    msg = e.inspect + \"\\n\" + e.backtrace.join(\"\\n\")\n    FXMessageBox.error(self, MBOX_OK, \"Error\", msg)\n  end\nend\n\ngetopts nil, \"cert:\"\n\ncerts_dir = ARGV.shift or raise \"#{$0} cert_dir\"\ncertfile = $OPT_cert\napp = FXApp.new(\"CertStore\", \"FoxTest\")\ncert_store = CertStore.new(certs_dir)\nw = CertStoreView.new(app, cert_store)\napp.create\nif certfile\n  w.verify(certfile)\nend\napp.run\n"
  },
  {
    "path": "sample/openssl/certstore.rb",
    "content": "require 'c_rehash'\nrequire 'crlstore'\n\n\nclass CertStore\n  include OpenSSL\n  include X509\n\n  attr_reader :self_signed_ca\n  attr_reader :other_ca\n  attr_reader :ee\n  attr_reader :crl\n  attr_reader :request\n\n  def initialize(certs_dir)\n    @certs_dir = certs_dir\n    @c_store = CHashDir.new(@certs_dir)\n    @c_store.hash_dir(true)\n    @crl_store = CrlStore.new(@c_store)\n    @x509store = Store.new\n    @self_signed_ca = @other_ca = @ee = @crl = nil\n\n    # Uncomment this line to let OpenSSL to check CRL for each certs.\n    # @x509store.flags = V_FLAG_CRL_CHECK | V_FLAG_CRL_CHECK_ALL\n\n    add_path\n    scan_certs\n  end\n\n  def generate_cert(filename)\n    @c_store.load_pem_file(filename)\n  end\n\n  def verify(cert)\n    error, crl_map = do_verify(cert)\n    if error\n      [[false, cert, crl_map[cert.subject], error]]\n    else\n      @x509store.chain.collect { |c| [true, c, crl_map[c.subject], nil] }\n    end\n  end\n\n  def match_cert(cert1, cert2)\n    (cert1.issuer.cmp(cert2.issuer) == 0) and cert1.serial == cert2.serial\n  end\n\n  def is_ca?(cert)\n    case guess_cert_type(cert)\n    when CERT_TYPE_SELF_SIGNED\n      true\n    when CERT_TYPE_OTHER \n      true\n    else\n      false\n    end\n  end\n\n  def scan_certs\n    @self_signed_ca = []\n    @other_ca = []\n    @ee = []\n    @crl = []\n    @request = []\n    load_certs\n  end\n\nprivate\n\n  def add_path\n    @x509store.add_path(@certs_dir)\n  end\n\n  def do_verify(cert)\n    error_map = {}\n    crl_map = {}\n    result = @x509store.verify(cert) do |ok, ctx|\n      cert = ctx.current_cert\n      if ctx.current_crl\n\tcrl_map[cert.subject] = true\n      end\n      if ok\n\tif !ctx.current_crl\n\t  if crl = @crl_store.find_crl(cert)\n\t    crl_map[cert.subject] = true\n\t    if crl.revoked.find { |revoked| revoked.serial == cert.serial }\n\t      ok = false\n\t      error_string = 'certification revoked'\n\t    end\n\t  end\n\tend\n      end\n      error_map[cert.subject] = error_string if error_string\n      ok\n    end\n    error = if result\n\tnil\n      else\n\terror_map[cert.subject] || @x509store.error_string\n      end\n    return error, crl_map\n  end\n\n  def load_certs\n    @c_store.get_certs.each do |certfile|\n      cert = generate_cert(certfile)\n      case guess_cert_type(cert)\n      when CERT_TYPE_SELF_SIGNED\n\t@self_signed_ca << cert\n      when CERT_TYPE_OTHER\n\t@other_ca << cert\n      when CERT_TYPE_EE\n\t@ee << cert\n      else\n\traise \"Unknown cert type.\"\n      end\n    end\n    @c_store.get_crls.each do |crlfile|\n      @crl << generate_cert(crlfile)\n    end\n  end\n\n  CERT_TYPE_SELF_SIGNED = 0\n  CERT_TYPE_OTHER = 1\n  CERT_TYPE_EE = 2\n  def guess_cert_type(cert)\n    ca = self_signed = is_cert_self_signed(cert)\n    cert.extensions.each do |ext|\n      # Ignores criticality of extensions.  It's 'guess'ing.\n      case ext.oid\n      when 'basicConstraints'\n\t/CA:(TRUE|FALSE), pathlen:(\\d+)/ =~ ext.value\n\tca = ($1 == 'TRUE') unless ca\n      when 'keyUsage'\n\tusage = ext.value.split(/\\s*,\\s*/)\n\tca = usage.include?('Certificate Sign') unless ca\n      when 'nsCertType'\n\tusage = ext.value.split(/\\s*,\\s*/)\n\tca = usage.include?('SSL CA') unless ca\n      end\n    end\n    if ca\n      if self_signed\n\tCERT_TYPE_SELF_SIGNED\n      else\n\tCERT_TYPE_OTHER\n      end\n    else\n      CERT_TYPE_EE\n    end\n  end\n\n  def is_cert_self_signed(cert)\n    # cert.subject.cmp(cert.issuer) == 0\n    cert.subject.to_s == cert.issuer.to_s\n  end\nend\n\n\nif $0 == __FILE__\n  c = CertStore.new(\"trust_certs\")\nend\n"
  },
  {
    "path": "sample/openssl/cipher.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'openssl'\n\ntext = \"abcdefghijklmnopqrstuvwxyz\"\npass = \"secret password\"\nsalt = \"8 octets\"        # or nil\nalg = \"DES-EDE3-CBC\"\n#alg = \"AES-128-CBC\"\n\nputs \"--Setup--\"\nputs %(clear text:    \"#{text}\")\nputs %(password:      \"#{pass}\")\nputs %(salt:          \"#{salt}\")\nputs %(cipher alg:    \"#{alg}\")\nputs\n\nputs \"--Encrypting--\"\ndes = OpenSSL::Cipher::Cipher.new(alg)\ndes.pkcs5_keyivgen(pass, salt)\ndes.encrypt\ncipher =  des.update(text)\ncipher << des.final\nputs %(encrypted text: #{cipher.inspect})\nputs\n\nputs \"--Decrypting--\"\ndes = OpenSSL::Cipher::Cipher.new(alg)\ndes.pkcs5_keyivgen(pass, salt)\ndes.decrypt\nout =  des.update(cipher)\nout << des.final\nputs %(decrypted text: \"#{out}\")\nputs\n"
  },
  {
    "path": "sample/openssl/crlstore.rb",
    "content": "begin\n  require 'http-access2'\nrescue LoadError\n  STDERR.puts(\"Cannot load http-access2.  CRL might not be fetched.\")\nend\nrequire 'c_rehash'\n\n\nclass CrlStore\n  def initialize(c_store)\n    @c_store = c_store\n    @c_store.hash_dir(true)\n  end\n\n  def find_crl(cert)\n    do_find_crl(cert)\n  end\n\nprivate\n\n  def do_find_crl(cert)\n    unless ca = find_ca(cert)\n      return nil\n    end\n    unless crlfiles = @c_store.get_crls(ca.subject)\n      if crl = renew_crl(cert, ca)\n\t@c_store.add_crl(crl)\n\treturn crl\n      end\n      return nil\n    end\n    crlfiles.each do |crlfile|\n      next unless crl = load_crl(crlfile)\n      if crl.next_update < Time.now\n\tif new_crl = renew_crl(cert, ca)\n\t  @c_store.delete_crl(crl)\n\t  @c_store.add_crl(new_crl)\n\t  crl = new_crl\n\tend\n      end\n      if check_valid(crl, ca)\n\treturn crl\n      end\n    end\n    nil\n  end\n\n  def find_ca(cert)\n    @c_store.get_certs(cert.issuer).each do |cafile|\n      ca = load_cert(cafile)\n      if cert.verify(ca.public_key)\n\treturn ca\n      end\n    end\n    nil\n  end\n\n  def fetch(location)\n    if /\\AURI:(.*)\\z/ =~ location\n      begin\n\tc = HTTPAccess2::Client.new(ENV['http_proxy'] || ENV['HTTP_PROXY'])\n\tc.get_content($1)\n      rescue NameError, StandardError\n\tnil\n      end\n    else\n      nil\n    end\n  end\n\n  def load_cert(certfile)\n    load_cert_str(File.read(certfile))\n  end\n\n  def load_crl(crlfile)\n    load_crl_str(File.read(crlfile))\n  end\n\n  def load_cert_str(cert_str)\n    OpenSSL::X509::Certificate.new(cert_str)\n  end\n\n  def load_crl_str(crl_str)\n    OpenSSL::X509::CRL.new(crl_str)\n  end\n\n  def check_valid(crl, ca)\n    unless crl.verify(ca.public_key)\n      return false\n    end\n    crl.last_update <= Time.now\n  end\n\n  RE_CDP = /\\AcrlDistributionPoints\\z/\n  def get_cdp(cert)\n    if cdp_ext = cert.extensions.find { |ext| RE_CDP =~ ext.oid }\n      cdp_ext.value.chomp\n    else\n      false\n    end\n  end\n\n  def renew_crl(cert, ca)\n    if cdp = get_cdp(cert)\n      if new_crl_str = fetch(cdp)\n\tnew_crl = load_crl_str(new_crl_str)\n\tif check_valid(new_crl, ca)\n\t  return new_crl\n\tend\n      end\n    end\n    false\n  end\nend\n\nif $0 == __FILE__\n  dir = \"trust_certs\"\n  c_store = CHashDir.new(dir)\n  s = CrlStore.new(c_store)\n  c = OpenSSL::X509::Certificate.new(File.read(\"cert_store/google_codesign.pem\"))\n  p s.find_crl(c)\nend\n"
  },
  {
    "path": "sample/openssl/echo_cli.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'socket'\nrequire 'openssl'\nrequire 'getopts'\n\ngetopts nil, \"p:2000\", \"c:\", \"k:\", \"C:\"\n\nhost      = ARGV[0] || \"localhost\"\nport      = $OPT_p\ncert_file = $OPT_c\nkey_file  = $OPT_k\nca_path   = $OPT_C\n\nctx = OpenSSL::SSL::SSLContext.new()\nif cert_file && key_file\n  ctx.cert = OpenSSL::X509::Certificate.new(File::read(cert_file))\n  ctx.key  = OpenSSL::PKey::RSA.new(File::read(key_file))\nend\nif ca_path\n  ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER\n  ctx.ca_path = ca_path\nelse\n  $stderr.puts \"!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!\"\nend\n\ns = TCPSocket.new(host, port)\nssl = OpenSSL::SSL::SSLSocket.new(s, ctx)\nssl.connect # start SSL session\nssl.sync_close = true  # if true the underlying socket will be\n                       # closed in SSLSocket#close. (default: false)\nwhile line = $stdin.gets\n  ssl.write line\n  print ssl.gets\nend\n\nssl.close\n"
  },
  {
    "path": "sample/openssl/echo_svr.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'socket'\nrequire 'openssl'\nrequire 'getopts'\n\ngetopts nil, \"p:2000\", \"c:\", \"k:\", \"C:\"\n\nport      = $OPT_p\ncert_file = $OPT_c\nkey_file  = $OPT_k\nca_path   = $OPT_C\n\nif cert_file && key_file\n  cert = OpenSSL::X509::Certificate.new(File::read(cert_file))\n  key  = OpenSSL::PKey::RSA.new(File::read(key_file))\nelse\n  key = OpenSSL::PKey::RSA.new(512){ print \".\" }\n  puts\n  cert = OpenSSL::X509::Certificate.new\n  cert.version = 2\n  cert.serial = 0\n  name = OpenSSL::X509::Name.new([[\"C\",\"JP\"],[\"O\",\"TEST\"],[\"CN\",\"localhost\"]])\n  cert.subject = name\n  cert.issuer = name\n  cert.not_before = Time.now\n  cert.not_after = Time.now + 3600\n  cert.public_key = key.public_key\n  ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)\n  cert.extensions = [\n    ef.create_extension(\"basicConstraints\",\"CA:FALSE\"),\n    ef.create_extension(\"subjectKeyIdentifier\",\"hash\"),\n    ef.create_extension(\"extendedKeyUsage\",\"serverAuth\"),\n    ef.create_extension(\"keyUsage\",\n                        \"keyEncipherment,dataEncipherment,digitalSignature\")\n  ]\n  ef.issuer_certificate = cert\n  cert.add_extension ef.create_extension(\"authorityKeyIdentifier\",\n                                         \"keyid:always,issuer:always\")\n  cert.sign(key, OpenSSL::Digest::SHA1.new)\nend\n\nctx = OpenSSL::SSL::SSLContext.new()\nctx.key = key\nctx.cert = cert\nif ca_path\n  ctx.verify_mode =\n    OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT\n  ctx.ca_path = ca_path\nelse\n  $stderr.puts \"!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!\"\nend\n\ntcps = TCPServer.new(port)\nssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)\nloop do\n  ns = ssls.accept\n  while line = ns.gets\n    ns.write line\n  end\n  ns.close\nend\n"
  },
  {
    "path": "sample/openssl/gen_csr.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'getopts'\nrequire 'openssl'\n\ninclude OpenSSL\n\ndef usage\n  myname = File::basename($0)\n  $stderr.puts <<EOS\nUsage: #{myname} [--key keypair_file] name\n  name ... ex. /C=JP/O=RRR/OU=CA/CN=NaHi/emailAddress=nahi@example.org\nEOS\n  exit\nend\n\ngetopts nil, \"key:\", \"csrout:\", \"keyout:\"\nkeypair_file = $OPT_key\ncsrout = $OPT_csrout || \"csr.pem\"\nkeyout = $OPT_keyout || \"keypair.pem\"\n\n$stdout.sync = true\nname_str = ARGV.shift or usage()\np name_str\nname = X509::Name.parse(name_str)\n\nkeypair = nil\nif keypair_file\n  keypair = PKey::RSA.new(File.open(keypair_file).read)\nelse\n  keypair = PKey::RSA.new(1024) { putc \".\" }\n  puts\n  puts \"Writing #{keyout}...\"\n  File.open(keyout, \"w\", 0400) do |f|\n    f << keypair.to_pem\n  end\nend\n\nputs \"Generating CSR for #{name_str}\"\n\nreq = X509::Request.new\nreq.version = 0\nreq.subject = name\nreq.public_key = keypair.public_key\nreq.sign(keypair, Digest::MD5.new)\n\nputs \"Writing #{csrout}...\"\nFile.open(csrout, \"w\") do |f|\n  f << req.to_pem\nend\n"
  },
  {
    "path": "sample/openssl/smime_read.rb",
    "content": "require 'getopts'\nrequire 'openssl'\ninclude OpenSSL\n\ngetopts nil, \"c:\", \"k:\", \"C:\"\n\ncert_file = $OPT_c\nkey_file  = $OPT_k\nca_path   = $OPT_C\n\ndata = $stdin.read\n\ncert = X509::Certificate.new(File::read(cert_file))\nkey = PKey::RSA.new(File::read(key_file))\np7enc = PKCS7::read_smime(data)\ndata = p7enc.decrypt(key, cert)\n\nstore = X509::Store.new\nstore.add_path(ca_path)\np7sig = PKCS7::read_smime(data)\nif p7sig.verify([], store)\n  puts p7sig.data\nend\n"
  },
  {
    "path": "sample/openssl/smime_write.rb",
    "content": "require 'openssl'\nrequire 'getopts'\ninclude OpenSSL\n\ngetopts nil, \"c:\", \"k:\", \"r:\"\n\ncert_file = $OPT_c\nkey_file  = $OPT_k\nrcpt_file = $OPT_r\n\ncert = X509::Certificate.new(File::read(cert_file))\nkey = PKey::RSA.new(File::read(key_file))\n\ndata  = \"Content-Type: text/plain\\r\\n\"\ndata << \"\\r\\n\"\ndata << \"This is a clear-signed message.\\r\\n\"\n\np7sig  = PKCS7::sign(cert, key, data, [], PKCS7::DETACHED)\nsmime0 = PKCS7::write_smime(p7sig)\n\nrcpt  = X509::Certificate.new(File::read(rcpt_file))\np7enc = PKCS7::encrypt([rcpt], smime0)\nprint PKCS7::write_smime(p7enc)   \n"
  },
  {
    "path": "sample/openssl/wget.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'net/https'\nrequire 'getopts'\n\ngetopts nil, 'C:'\n\nca_path = $OPT_C\n\nuri = URI.parse(ARGV[0])\nif proxy = ENV['HTTP_PROXY']\n  prx_uri = URI.parse(proxy)\n  prx_host = prx_uri.host\n  prx_port = prx_uri.port\nend\n\nh = Net::HTTP.new(uri.host, uri.port, prx_host, prx_port)\nh.set_debug_output($stderr) if $DEBUG\nif uri.scheme == \"https\"\n  h.use_ssl = true\n  if ca_path\n    h.verify_mode = OpenSSL::SSL::VERIFY_PEER\n    h.ca_path = ca_path\n  else\n    $stderr.puts \"!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!\"\n  end\nend\n\npath = uri.path.empty? ? \"/\" : uri.path\nh.get2(path){|resp|\n  STDERR.puts h.peer_cert.inspect if h.peer_cert\n  print resp.body\n}\n"
  },
  {
    "path": "sample/optparse/opttest.rb",
    "content": "#!/usr/bin/ruby -I.\n\nrequire 'optparse'\nrequire 'optparse/time'\nrequire 'pp'\n\n# keywords\nCODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]\nCODE_ALIASES = {\"jis\" => \"iso-2022-jp\", \"sjis\" => \"shift_jis\"}\nPOSSIBLE_CODES = \"(#{(CODES+CODE_ALIASES.keys).join(',')})\"\n\nARGV.options do\n  |opts|\n  opts.banner << \" argv...\"\n\n  # separater\n  opts.on_tail\n  opts.on_tail(\"common options:\")\n\n  # no argument, shows at tail\n  opts.on_tail(\"--help\", \"show this message\") {puts opts; exit}\n\n  # mandatory argument\n  opts.on(\"-r\", \"--require=LIBRARY\", String,\n\t  \"require the LIBRARY, before\",\n\t  \"executing your script\") {|@library|}\n\n  # optional argument\n  opts.on(\"-i\", \"--inplace=[EXTENSION]\",\n\t  \"edit ARGV files in place\", # multiline description\n\t  \"(make backup if EXTENSION supplied)\") {|@inplace| @inplace ||= ''}\n\n  opts.on(\"-N=[NUM]\", Integer) {|@number|}\n\n  # additional class\n  opts.on(\"-t\", \"--[no-]time[=TIME]\", Time, \"it's the time\") {|@time|}\n\n  # limit argument syntax\n  opts.on(\"-[0-7]\", \"-F\", \"--irs=[OCTAL]\", OptionParser::OctalInteger,\n\t  \"specify record separator\", \"(\\\\0, if no argument)\") {|@irs|}\n\n  # boolean switch(default true)\n  @exec = true\n  opts.on(\"-n\", \"--no-exec[=FLAG]\", TrueClass, \"not really execute\") {|@exec|}\n\n  # array\n  opts.on(\"-a\", \"--list[=LIST,LIST]\", Array, \"list\") {|@list|}\n\n  # fixed size array\n  opts.on(\"--pair[=car,cdr]\", Array, \"pair\") {|@x, @y|}\n\n  # keyword completion\n  opts.on(\"--code=CODE\", CODES, CODE_ALIASES, \"select coding system\",\n\t  \"(\"+CODES.join(\",\")+\",\", \" \"+CODE_ALIASES.keys.join(\",\")+\")\") {|@code|}\n\n  # optional argument with keyword completion\n  opts.on(\"--type[=TYPE]\", [:text, :binary], \"select type(text, binary)\") {|@type|}\n\n  # boolean switch with optional argument(default false)\n  opts.on(\"-v\", \"--[no-]verbose=[FLAG]\", \"run verbosely\") {|@verbose|}\n\n  # easy way, set local variable\n  opts.on(\"-q\", \"--quit\", \"quit when ARGV is empty\") {|@quit|}\n\n  # adding on the fly\n  opts.on(\"--add=SWITCH=[ARG]\", \"add option on the fly\", /\\A(\\w+)(?:=.+)?\\Z/) do\n    |opt, var|\n    opts.on(\"--#{opt}\", \"added in runtime\", &eval(\"proc {|@#{var}|}\"))\n  end\n\n  opts.on_head(\"specific options:\")\n\n  # no argument\n  opts.on_tail(\"--version\", \"show version\") do\n    puts OptionParser::Version.join('.')\n    exit\n  end\n  opts.parse!\nend\n\npp self\n(print ARGV.options; exit) if @quit\nARGV.options = nil\t\t# no more parse\nputs \"ARGV = #{ARGV.join(' ')}\" if !ARGV.empty?\n#opts.variable.each {|sym| puts \"#{sym} = #{opts.send(sym).inspect}\"}\n"
  },
  {
    "path": "sample/optparse/subcommand.rb",
    "content": "#! /usr/bin/ruby\n# contributed by Minero Aoki.\n\nrequire 'optparse'\n\nparser = OptionParser.new\nparser.on('-i') { puts \"-i\" }\nparser.on('-o') { puts '-o' }\n\nsubparsers = Hash.new {|h,k|\n  $stderr.puts \"no such subcommand: #{k}\"\n  exit 1\n}\nsubparsers['add'] = OptionParser.new.on('-i') { puts \"add -i\" }\nsubparsers['del'] = OptionParser.new.on('-i') { puts \"del -i\" }\nsubparsers['list'] = OptionParser.new.on('-i') { puts \"list -i\" }\n\nparser.order!(ARGV)\nsubparsers[ARGV.shift].parse!(ARGV) unless ARGV.empty?\n"
  },
  {
    "path": "sample/philos.rb",
    "content": "#\n# The Dining Philosophers - thread example\n#\nrequire \"thread\"\n\nsrand\n#srand\nN=9\t\t\t\t# number of philosophers\n$forks = []\nfor i in 0..N-1\n  $forks[i] = Mutex.new\nend\n$state = \"-o\"*N\n\ndef wait\n  sleep rand(20)/10.0\nend\n\ndef think(n)\n  wait\nend\n\ndef eat(n)\n  wait\nend\n\ndef philosopher(n)\n  while true\n    think n\n    $forks[n].lock\n    if not $forks[(n+1)%N].try_lock\n      $forks[n].unlock\t\t# avoid deadlock\n      next\n    end\n    $state[n*2] = ?|;\n    $state[(n+1)%N*2] = ?|;\n    $state[n*2+1] = ?*;\n    print $state, \"\\n\"\n    eat(n)\n    $state[n*2] = ?-;\n    $state[(n+1)%N*2] = ?-;\n    $state[n*2+1] = ?o;\n    print $state, \"\\n\"\n    $forks[n].unlock\n    $forks[(n+1)%N].unlock\n  end\nend\n\nfor n in 0..N-1\n  Thread.start(n){|i| philosopher(i)}\n  sleep 0.1\nend\n\nsleep\n"
  },
  {
    "path": "sample/pi.rb",
    "content": "#!/usr/local/bin/ruby\n\nk, a, b, a1, b1 = 2, 4, 1, 12, 4\n\nloop do\n  # Next approximation\n  p, q, k = k*k, 2*k+1, k+1\n  a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1\n  # Print common digits\n  d = a / b\n  d1 = a1 / b1\n  while d == d1\n    print d\n    $stdout.flush\n    a, a1 = 10*(a%b), 10*(a1%b1)\n    d, d1 = a/b, a1/b1\n  end\nend\n"
  },
  {
    "path": "sample/rcs.awk",
    "content": "BEGIN {\n    sw = 40.0;\n    dw = 78.0;\n    hdw = dw / 2.0;\n    w = 20.0;\n    h =1.0;\n    d = 0.2;\n    ss=\"abcdefghijklmnopqrstuvwxyz0123456789!#$%^&*()-=\\\\[];'`,./\";\n    rnd = srand();\n}\n\n{\n    xr = -hdw; y = h * 1.0; maxxl = -999;\n    s = \"\";\n    while (xr < hdw) {\n\tx = xr * (1 + y) - y * w / 2;\n\ti = (x / (1 + h) + sw /2);\n\tc = (0 < i && i < length($0)) ? substr($0, i, 1) : \"0\";\n\ty = h - d * c;\n\txl = xr - w * y / (1 + y);\n\tif (xl < -hdw || xl >= hdw || xl <= maxxl) {\n\t    t = rand() * length(ss);\n\t    c = substr(ss, t, 1);\n\t}\n\telse {\n\t    c = substr(s, xl + hdw, 1);\n\t    maxxl = xl;\n\t}\n\ts = s c;\n\txr = xr + 1;\n    }\n    print s;\n}\n"
  },
  {
    "path": "sample/rcs.rb",
    "content": "# random dot steraogram\n# usage: rcs.rb rcs.dat\n\nsw = 40.0\t# width of original pattern\ndw = 78.0\t# width of generating Random Character Streogram\nhdw = dw / 2.0\nw = 20.0\t# distance between eyes\nh =1.0\t\t# distance from screen and base plane\nd = 0.2\t\t# z value unit\nss=\"abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\\\[];'`,./\"\nrnd = srand()\t# You don't actually need this in ruby - srand() is called\n\t\t# on the first call of rand().\n\nwhile gets()\n#  print($_)\n  xr = -hdw; y = h * 1.0; maxxl = -999\n  s = \"\"\n  while xr < hdw\n    x = xr * (1 + y) - y * w / 2\n    i = (x / (1 + h) + sw / 2)\n    if (1 < i && i < $_.length)\n      c = $_[i, 1].to_i\n    else\n      c = 0\n    end\n    y = h - d * c\n    xl = xr - w * y / (1 + y)\n    if xl < -hdw || xl >= hdw || xl <= maxxl\n      tt = rand(ss.length)\n      c = ss[tt, 1]\n    else\n      c = s[xl + hdw, 1]\n      maxxl = xl\n    end\n    s += c\n    xr += 1\n  end\n  print(s, \"\\n\")\nend\n"
  },
  {
    "path": "sample/regx.rb",
    "content": "st = \"\\033[7m\"\nen = \"\\033[m\"\n#st = \"<<\"\n#en = \">>\"\n\nwhile true\n  print \"str> \"\n  STDOUT.flush\n  input = gets\n  break if not input\n  if input != \"\"\n    str = input\n    str.chop!\n  end\n  print \"pat> \"\n  STDOUT.flush\n  re = gets\n  break if not re\n  re.chop!\n  str.gsub! re, \"#{st}\\\\&#{en}\"\n  print str, \"\\n\"\nend\nprint \"\\n\"\n"
  },
  {
    "path": "sample/rss/blend.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"rss\"\n\nfeeds = []\nverbose = false\nencoding = \"UTF-8\"\n\ndef error(exception)\n  mark = \"=\" * 20\n  mark = \"#{mark} error #{mark}\"\n  STDERR.puts mark\n  STDERR.puts exception.class\n  STDERR.puts exception.message\n  STDERR.puts exception.backtrace\n  STDERR.puts mark\nend\n\nbefore_time = Time.now\nARGV.each do |fname|\n  if fname == '-v'\n    verbose = true\n    next\n  end\n  rss = nil\n  f = File.new(fname).read\n  begin\n    ## do validate parse\n    rss = RSS::Parser.parse(f)\n  rescue RSS::InvalidRSSError\n    error($!) if verbose\n    ## do non validate parse for invalid RSS 1.0\n    begin\n      rss = RSS::Parser.parse(f, false)\n    rescue RSS::Error\n      ## invalid RSS.\n      error($!) if verbose\n    end\n  rescue RSS::Error\n    error($!) if verbose\n  end\n  if rss.nil?\n    STDERR.puts \"#{fname} does not include RSS 1.0 or 0.9x/2.0\"\n  else\n    begin\n      rss.output_encoding = encoding\n    rescue RSS::UnknownConversionMethodError\n      error($!) if verbose\n    end\n    feeds << rss\n  end\nend\nprocessing_time = Time.now - before_time\n\nrss = RSS::Maker.make(\"1.0\") do |maker|\n  maker.encoding = encoding\n  maker.channel.about = \"http://example.com/blend.rdf\"\n  maker.channel.title = \"blended feeds\"\n  maker.channel.link = \"http://example.com/\"\n  maker.channel.description = \"blended feeds generated by RSS Parser\"\n\n  feeds.each do |feed|\n    feed.items.each do |item|\n      item.setup_maker(maker.items)\n    end\n  end\n\n  maker.items.each do |item|\n    item.title ||= \"UNKNOWN\"\n    item.link ||= \"UNKNOWN\"\n  end\n\n  maker.items.do_sort = true\n  maker.items.max_size = 15\nend\nputs rss\n\nSTDERR.puts \"Used XML parser: #{RSS::Parser.default_parser}\"\nSTDERR.puts \"Processing time: #{processing_time}s\"\n"
  },
  {
    "path": "sample/rss/convert.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"rss\"\n\nfeeds = []\nverbose = false\nencoding = \"UTF-8\"\nto_version = \"1.0\"\n\ndef error(exception)\n  mark = \"=\" * 20\n  mark = \"#{mark} error #{mark}\"\n  STDERR.puts mark\n  STDERR.puts exception.class\n  STDERR.puts exception.message\n  STDERR.puts exception.backtrace\n  STDERR.puts mark\nend\n\nbefore_time = Time.now\nARGV.each do |fname|\n  case fname\n  when '-v'\n    verbose = true\n    next\n  when /^-t(0\\.91|1\\.0|2\\.0|atom)$/\n    to_version = $1\n    next\n  end\n  rss = nil\n  f = File.read(fname)\n  begin\n    ## do validate parse\n    rss = RSS::Parser.parse(f)\n  rescue RSS::InvalidRSSError\n    error($!) if verbose\n    ## do non validate parse for invalid RSS 1.0\n    begin\n      rss = RSS::Parser.parse(f, false)\n    rescue RSS::Error\n      ## invalid RSS.\n      error($!) if verbose\n    end\n  rescue RSS::Error\n    error($!) if verbose\n  end\n  if rss.nil?\n    STDERR.puts \"#{fname} does not include RSS 1.0 or 0.9x/2.0\"\n  else\n    begin\n      rss.output_encoding = encoding\n    rescue RSS::UnknownConversionMethodError\n      error($!) if verbose\n    end\n    feeds << [fname, rss]\n  end\nend\nprocessing_time = Time.now - before_time\n\nfeeds.each do |fname, rss|\n  converted_rss = rss.to_xml(to_version)\n  output_name = fname.sub(/(\\.[^\\.]+)$/, \"-#{to_version}\\\\1\")\n  File.open(output_name, \"w\") do |output|\n    output.print(converted_rss)\n  end\nend\n\nSTDERR.puts \"Used XML parser: #{RSS::Parser.default_parser}\"\nSTDERR.puts \"Processing time: #{processing_time}s\"\n"
  },
  {
    "path": "sample/rss/list_description.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"nkf\"\nclass String\n  # From tdiary.rb\n  def shorten( len = 120 )\n    lines = NKF::nkf( \"-e -m0 -f#{len}\", self.gsub( /\\n/, ' ' ) ).split( /\\n/ )\n    lines[0].concat( '...' ) if lines[0] and lines[1]\n    lines[0]\n  end\nend\n\nrequire \"rss\"\n\nchannels = {}\nverbose = false\n\ndef error(exception)\n  mark = \"=\" * 20\n  mark = \"#{mark} error #{mark}\"\n  puts mark\n  puts exception.class\n  puts exception.message\n  puts exception.backtrace\n  puts mark\nend\n\nbefore_time = Time.now\nARGV.each do |fname|\n  if fname == '-v'\n    verbose = true\n    next\n  end\n  rss = nil\n  f = File.new(fname).read\n  begin\n    ## do validate parse\n    rss = RSS::Parser.parse(f)\n  rescue RSS::InvalidRSSError\n    error($!) if verbose\n    ## do non validate parse for invalid RSS 1.0\n    begin\n      rss = RSS::Parser.parse(f, false)\n    rescue RSS::Error\n      ## invalid RSS.\n      error($!) if verbose\n    end\n  rescue RSS::Error\n    error($!) if verbose\n  end\n  if rss.nil?\n    puts \"#{fname} does not include RSS 1.0 or 0.9x/2.0\"\n  else\n    begin\n      rss.output_encoding = \"euc-jp\"\n    rescue RSS::UnknownConversionMethodError\n      error($!) if verbose\n    end\n\n    rss = rss.to_rss(\"1.0\") do |maker|\n      maker.channel.about ||= maker.channel.link\n      maker.channel.description ||= \"No description\"\n      maker.items.each do |item|\n        item.title ||= \"No title\"\n        item.link ||= \"UNKNOWN\"\n      end\n    end\n    next if rss.nil?\n\n    rss.items.each do |item|\n      channels[rss.channel.title] ||= []\n      channels[rss.channel.title] << item if item.description\n    end\n  end\nend\nprocessing_time = Time.now - before_time\n\nchannels.sort do |x, y|\n  x[0] <=> y[0]\nend[0..20].each do |title, items|\n  puts \"Channel: #{title}\" unless items.empty?\n  items.sort do |x, y|\n    x.title <=> y.title\n  end[0..10].each do |item|\n    puts \"  Item: #{item.title.shorten(50)}\"\n    puts \"    Description: #{item.description.shorten(50)}\"\n  end\nend\n\nputs \"Used XML parser: #{RSS::Parser.default_parser}\"\nputs \"Processing time: #{processing_time}s\"\n"
  },
  {
    "path": "sample/rss/re_read.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"rss\"\n\ndef error(exception)\n  mark = \"=\" * 20\n  mark = \"#{mark} error #{mark}\"\n  puts mark\n  puts exception.class\n  puts exception.message\n  puts exception.backtrace\n  puts mark\nend\n\nverbose = false\nbefore_time = Time.now\n\nARGV.each do |fname|\n  if fname == '-v'\n    verbose = true\n    next\n  end\n  source = nil\n  File.open(fname) do |f|\n    source = f.read\n  end\n  \n  rss = nil\n  read = false\n  begin\n    rss = RSS::Parser.parse(source)\n    puts \"Re-read valid feed: #{fname}\"\n    RSS::Parser.parse(rss.to_s)\n    read = true\n  rescue RSS::InvalidRSSError\n    error($!) if verbose\n    ## do non validate parse for invalid feed\n    begin\n      rss = RSS::Parser.parse(source, false)\n    rescue RSS::Error\n      ## invalid feed\n      error($!) if verbose\n    end\n  rescue RSS::Error\n    error($!) if verbose\n  end\n  \n  if rss.nil?\n    puts \"Invalid feed: #{fname}\"\n  elsif !read\n    puts \"Re-read invalid feed: #{fname}\"\n    begin\n      RSS::Parser.parse(rss.to_s)\n    rescue RSS::Error\n      puts \"  Error occurred: #{fname}\"\n      error($!) if verbose\n    end\n  end\nend\n\nprocessing_time = Time.now - before_time\n\nputs \"Used XML parser: #{RSS::Parser.default_parser}\"\nputs \"Processing time: #{processing_time}s\"\n"
  },
  {
    "path": "sample/rss/rss_recent.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire \"nkf\"\nclass String\n  # From tdiary.rb\n  def shorten( len = 120 )\n    lines = NKF::nkf( \"-e -m0 -f#{len}\", self.gsub( /\\n/, ' ' ) ).split( /\\n/ )\n    lines[0].concat( '...' ) if lines[0] and lines[1]\n    lines[0]\n  end\nend\n\nrequire \"rss\"\n\nitems = []\nverbose = false\n\ndef error(exception)\n  mark = \"=\" * 20\n  mark = \"#{mark} error #{mark}\"\n  puts mark\n  puts exception.class\n  puts exception.message\n  puts exception.backtrace\n  puts mark\nend\nbefore_time = Time.now\nARGV.each do |fname|\n  if fname == '-v'\n    verbose = true\n    next\n  end\n  rss = nil\n  f = File.new(fname).read\n  begin\n    ## do validate parse\n    rss = RSS::Parser.parse(f)\n  rescue RSS::InvalidRSSError\n    error($!) if verbose\n    ## do non validate parse for invalid RSS 1.0\n    begin\n      rss = RSS::Parser.parse(f, false)\n    rescue RSS::Error\n      ## invalid RSS.\n      error($!) if verbose\n    end\n  rescue RSS::Error\n    error($!) if verbose\n  end\n  if rss.nil?\n    puts \"#{fname} does not include RSS 1.0 or 0.9x/2.0\"\n  else\n    begin\n      rss.output_encoding = \"euc-jp\"\n    rescue RSS::UnknownConversionMethodError\n      error($!) if verbose\n    end\n\n    rss = rss.to_rss(\"1.0\") do |maker|\n      maker.channel.about ||= maker.channel.link\n      maker.channel.description ||= \"No description\"\n      maker.items.each do |item|\n        item.title ||= \"UNKNOWN\"\n        item.link ||= \"UNKNOWN\"\n      end\n    end\n    next if rss.nil?\n\n    rss.items.each do |item|\n      items << [rss.channel, item] if item.dc_date\n    end\n  end\nend\nprocessing_time = Time.now - before_time\n\nitems.sort do |x, y|\n  y[1].dc_date <=> x[1].dc_date\nend[0..20].each do |channel, item|\n  puts \"#{item.dc_date.localtime.iso8601}: \" <<\n    \"#{channel.title}: #{item.title}\"\n  puts \" Description: #{item.description.shorten(50)}\" if item.description\nend\n\nputs \"Used XML parser: #{RSS::Parser.default_parser}\"\nputs \"Processing time: #{processing_time}s\"\n"
  },
  {
    "path": "sample/sieve.rb",
    "content": "# sieve of Eratosthenes\nmax = Integer(ARGV.shift || 100)\nsieve = []\nfor i in 2 .. max\n  sieve[i] = i\nend\n\nfor i in 2 .. Math.sqrt(max)\n  next unless sieve[i]\n  (i*i).step(max, i) do |j|\n    sieve[j] = nil\n  end\nend\nputs sieve.compact.join(\", \")\n"
  },
  {
    "path": "sample/svr.rb",
    "content": "# socket example - server side\n# usage: ruby svr.rb\n\n# this server might be blocked by an ill-behaved client.\n# see tsvr.rb which is safe from client blocking.\n\nrequire \"socket\"\n\ngs = TCPserver.open(0)\naddr = gs.addr\naddr.shift\nprintf(\"server is on %s\\n\", addr.join(\":\"))\nsocks = [gs]\n\nloop do\n  nsock = select(socks);\n  next if nsock == nil\n  for s in nsock[0]\n    if s == gs\n      ns = s.accept\n      socks.push(ns)\n      print(s, \" is accepted\\n\")\n    else\n      if s.eof?\n\tprint(s, \" is gone\\n\")\n\ts.close\n\tsocks.delete(s)\n      # single thread gets may block whole service\n      elsif str = s.gets   \n\t  s.write(str)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "sample/test.rb",
    "content": "#! /usr/bin/env ruby\n\n$KCODE = \"none\"\n$testnum=0\n$ntest=0\n$failed = 0\n\ndef test_check(what)\n  printf \"%s\\n\", what\n  $what = what\n  $testnum = 0\nend\n\ndef test_ok(cond,n=1)\n  $testnum+=1\n  $ntest+=1\n  if cond\n    printf \"ok %d\\n\", $testnum\n  else\n    where = caller(n)[0]\n    printf \"not ok %s %d -- %s\\n\", $what, $testnum, where\n    $failed+=1 \n  end\nend\n\n# make sure conditional operators work\n\ntest_check \"assignment\"\n\na=[]; a[0] ||= \"bar\";\ntest_ok(a[0] == \"bar\")\nh={}; h[\"foo\"] ||= \"bar\";\ntest_ok(h[\"foo\"] == \"bar\")\n\naa = 5\naa ||= 25\ntest_ok(aa == 5)\nbb ||= 25\ntest_ok(bb == 25)\ncc &&=33\ntest_ok(cc == nil)\ncc = 5\ncc &&=44\ntest_ok(cc == 44)\n\na = nil; test_ok(a == nil)\na = 1; test_ok(a == 1)\na = []; test_ok(a == [])\na = [1]; test_ok(a == [1])\na = [nil]; test_ok(a == [nil])\na = [[]]; test_ok(a == [[]])\na = [1,2]; test_ok(a == [1,2])\na = [*[]]; test_ok(a == [])\na = [*[1]]; test_ok(a == [1])\na = [*[1,2]]; test_ok(a == [1,2])\n\na = *nil; test_ok(a == nil)\na = *1; test_ok(a == 1)\na = *[]; test_ok(a == nil)\na = *[1]; test_ok(a == 1)\na = *[nil]; test_ok(a == nil)\na = *[[]]; test_ok(a == [])\na = *[1,2]; test_ok(a == [1,2])\na = *[*[]]; test_ok(a == nil)\na = *[*[1]]; test_ok(a == 1)\na = *[*[1,2]]; test_ok(a == [1,2])\n\na, = nil; test_ok(a == nil)\na, = 1; test_ok(a == 1)\na, = []; test_ok(a == nil)\na, = [1]; test_ok(a == 1)\na, = [nil]; test_ok(a == nil)\na, = [[]]; test_ok(a == [])\na, = 1,2; test_ok(a == 1)\na, = [1,2]; test_ok(a == 1)\na, = [*[]]; test_ok(a == nil)\na, = [*[1]]; test_ok(a == 1)\na, = *[1,2]; test_ok(a == 1)\na, = [*[1,2]]; test_ok(a == 1)\n\na, = *nil; test_ok(a == nil)\na, = *1; test_ok(a == 1)\na, = *[]; test_ok(a == nil)\na, = *[1]; test_ok(a == 1)\na, = *[nil]; test_ok(a == nil)\na, = *[[]]; test_ok(a == [])\na, = *[1,2]; test_ok(a == 1)\na, = *[*[]]; test_ok(a == nil)\na, = *[*[1]]; test_ok(a == 1)\na, = *[*[1,2]]; test_ok(a == 1)\n\n*a = nil; test_ok(a == [nil])\n*a = 1; test_ok(a == [1])\n*a = []; test_ok(a == [[]])\n*a = [1]; test_ok(a == [[1]])\n*a = [nil]; test_ok(a == [[nil]])\n*a = [[]]; test_ok(a == [[[]]])\n*a = [1,2]; test_ok(a == [[1,2]])\n*a = [*[]]; test_ok(a == [[]])\n*a = [*[1]]; test_ok(a == [[1]])\n*a = [*[1,2]]; test_ok(a == [[1,2]])\n\n*a = *nil; test_ok(a == [nil])\n*a = *1; test_ok(a == [1])\n*a = *[]; test_ok(a == [])\n*a = *[1]; test_ok(a == [1])\n*a = *[nil]; test_ok(a == [nil])\n*a = *[[]]; test_ok(a == [[]])\n*a = *[1,2]; test_ok(a == [1,2])\n*a = *[*[]]; test_ok(a == [])\n*a = *[*[1]]; test_ok(a == [1])\n*a = *[*[1,2]]; test_ok(a == [1,2])\n\na,b,*c = nil; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = 1; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = []; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = [1]; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = [nil]; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = [[]]; test_ok([a,b,c] == [[],nil,[]])\na,b,*c = [1,2]; test_ok([a,b,c] == [1,2,[]])\na,b,*c = [*[]]; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = [*[1]]; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = [*[1,2]]; test_ok([a,b,c] == [1,2,[]])\n\na,b,*c = *nil; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = *1; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = *[]; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = *[1]; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = *[nil]; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = *[[]]; test_ok([a,b,c] == [[],nil,[]])\na,b,*c = *[1,2]; test_ok([a,b,c] == [1,2,[]])\na,b,*c = *[*[]]; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = *[*[1]]; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = *[*[1,2]]; test_ok([a,b,c] == [1,2,[]])\n\ndef f; yield nil; end; f {|a| test_ok(a == nil)}\ndef f; yield 1; end; f {|a| test_ok(a == 1)}\ndef f; yield []; end; f {|a| test_ok(a == [])}\ndef f; yield [1]; end; f {|a| test_ok(a == [1])}\ndef f; yield [nil]; end; f {|a| test_ok(a == [nil])}\ndef f; yield [[]]; end; f {|a| test_ok(a == [[]])}\ndef f; yield [*[]]; end; f {|a| test_ok(a == [])}\ndef f; yield [*[1]]; end; f {|a| test_ok(a == [1])}\ndef f; yield [*[1,2]]; end; f {|a| test_ok(a == [1,2])}\n\ndef f; yield *nil; end; f {|a| test_ok(a == nil)}\ndef f; yield *1; end; f {|a| test_ok(a == 1)}\ndef f; yield *[1]; end; f {|a| test_ok(a == 1)}\ndef f; yield *[nil]; end; f {|a| test_ok(a == nil)}\ndef f; yield *[[]]; end; f {|a| test_ok(a == [])}\ndef f; yield *[*[1]]; end; f {|a| test_ok(a == 1)}\n\ndef f; yield; end; f {|a,| test_ok(a == nil)}\ndef f; yield nil; end; f {|a,| test_ok(a == nil)}\ndef f; yield 1; end; f {|a,| test_ok(a == 1)}\ndef f; yield []; end; f {|a,| test_ok(a == nil)}\ndef f; yield [1]; end; f {|a,| test_ok(a == 1)}\ndef f; yield [nil]; end; f {|a,| test_ok(a == nil)}\ndef f; yield [[]]; end; f {|a,| test_ok(a == [])}\ndef f; yield [*[]]; end; f {|a,| test_ok(a == nil)}\ndef f; yield [*[1]]; end; f {|a,| test_ok(a == 1)}\ndef f; yield [*[1,2]]; end; f {|a,| test_ok(a == 1)}\n\ndef f; yield *nil; end; f {|a,| test_ok(a == nil)}\ndef f; yield *1; end; f {|a,| test_ok(a == 1)}\ndef f; yield *[]; end; f {|a,| test_ok(a == nil)}\ndef f; yield *[1]; end; f {|a,| test_ok(a == 1)}\ndef f; yield *[nil]; end; f {|a,| test_ok(a == nil)}\ndef f; yield *[[]]; end; f {|a,| test_ok(a == [])}\ndef f; yield *[*[]]; end; f {|a,| test_ok(a == nil)}\ndef f; yield *[*[1]]; end; f {|a,| test_ok(a == 1)}\ndef f; yield *[*[1,2]]; end; f {|a,| test_ok(a == 1)}\n\ndef f; yield; end; f {|*a| test_ok(a == [])}\ndef f; yield nil; end; f {|*a| test_ok(a == [nil])}\ndef f; yield 1; end; f {|*a| test_ok(a == [1])}\ndef f; yield []; end; f {|*a| test_ok(a == [[]])}\ndef f; yield [1]; end; f {|*a| test_ok(a == [[1]])}\ndef f; yield [nil]; end; f {|*a| test_ok(a == [[nil]])}\ndef f; yield [[]]; end; f {|*a| test_ok(a == [[[]]])}\ndef f; yield [1,2]; end; f {|*a| test_ok(a == [[1,2]])}\ndef f; yield [*[]]; end; f {|*a| test_ok(a == [[]])}\ndef f; yield [*[1]]; end; f {|*a| test_ok(a == [[1]])}\ndef f; yield [*[1,2]]; end; f {|*a| test_ok(a == [[1,2]])}\n\ndef f; yield *nil; end; f {|*a| test_ok(a == [nil])}\ndef f; yield *1; end; f {|*a| test_ok(a == [1])}\ndef f; yield *[]; end; f {|*a| test_ok(a == [])}\ndef f; yield *[1]; end; f {|*a| test_ok(a == [1])}\ndef f; yield *[nil]; end; f {|*a| test_ok(a == [nil])}\ndef f; yield *[[]]; end; f {|*a| test_ok(a == [[]])}\ndef f; yield *[*[]]; end; f {|*a| test_ok(a == [])}\ndef f; yield *[*[1]]; end; f {|*a| test_ok(a == [1])}\ndef f; yield *[*[1,2]]; end; f {|*a| test_ok(a == [1,2])}\n\ndef f; yield; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield 1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}\ndef f; yield []; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield [1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}\ndef f; yield [nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}\ndef f; yield [*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield [*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}\ndef f; yield [*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}\n\ndef f; yield *nil; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield *1; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}\ndef f; yield *[]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield *[1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}\ndef f; yield *[nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield *[[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}\ndef f; yield *[*[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}\ndef f; yield *[*[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}\ndef f; yield *[*[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}\n\ndef r; return; end; a = r(); test_ok(a == nil)\ndef r; return nil; end; a = r(); test_ok(a == nil)\ndef r; return 1; end; a = r(); test_ok(a == 1)\ndef r; return []; end; a = r(); test_ok(a == [])\ndef r; return [1]; end; a = r(); test_ok(a == [1])\ndef r; return [nil]; end; a = r(); test_ok(a == [nil])\ndef r; return [[]]; end; a = r(); test_ok(a == [[]])\ndef r; return [*[]]; end; a = r(); test_ok(a == [])\ndef r; return [*[1]]; end; a = r(); test_ok(a == [1])\ndef r; return [*[1,2]]; end; a = r(); test_ok(a == [1,2])\n\ndef r; return *nil; end; a = r(); test_ok(a == nil)\ndef r; return *1; end; a = r(); test_ok(a == 1)\ndef r; return *[]; end; a = r(); test_ok(a == nil)\ndef r; return *[1]; end; a = r(); test_ok(a == 1)\ndef r; return *[nil]; end; a = r(); test_ok(a == nil)\ndef r; return *[[]]; end; a = r(); test_ok(a == [])\ndef r; return *[*[]]; end; a = r(); test_ok(a == nil)\ndef r; return *[*[1]]; end; a = r(); test_ok(a == 1)\ndef r; return *[*[1,2]]; end; a = r(); test_ok(a == [1,2])\n\ndef r; return *nil; end; a = *r(); test_ok(a == nil)\ndef r; return *1; end; a = *r(); test_ok(a == 1)\ndef r; return *[]; end; a = *r(); test_ok(a == nil)\ndef r; return *[1]; end; a = *r(); test_ok(a == 1)\ndef r; return *[nil]; end; a = *r(); test_ok(a == nil)\ndef r; return *[[]]; end; a = *r(); test_ok(a == nil)\ndef r; return *[*[]]; end; a = *r(); test_ok(a == nil)\ndef r; return *[*[1]]; end; a = *r(); test_ok(a == 1)\ndef r; return *[*[1,2]]; end; a = *r(); test_ok(a == [1,2])\n\ndef r; return; end; *a = r(); test_ok(a == [nil])\ndef r; return nil; end; *a = r(); test_ok(a == [nil])\ndef r; return 1; end; *a = r(); test_ok(a == [1])\ndef r; return []; end; *a = r(); test_ok(a == [[]])\ndef r; return [1]; end; *a = r(); test_ok(a == [[1]])\ndef r; return [nil]; end; *a = r(); test_ok(a == [[nil]])\ndef r; return [[]]; end; *a = r(); test_ok(a == [[[]]])\ndef r; return [1,2]; end; *a = r(); test_ok(a == [[1,2]])\ndef r; return [*[]]; end; *a = r(); test_ok(a == [[]])\ndef r; return [*[1]]; end; *a = r(); test_ok(a == [[1]])\ndef r; return [*[1,2]]; end; *a = r(); test_ok(a == [[1,2]])\n\ndef r; return *nil; end; *a = r(); test_ok(a == [nil])\ndef r; return *1; end; *a = r(); test_ok(a == [1])\ndef r; return *[]; end; *a = r(); test_ok(a == [nil])\ndef r; return *[1]; end; *a = r(); test_ok(a == [1])\ndef r; return *[nil]; end; *a = r(); test_ok(a == [nil])\ndef r; return *[[]]; end; *a = r(); test_ok(a == [[]])\ndef r; return *[1,2]; end; *a = r(); test_ok(a == [[1,2]])\ndef r; return *[*[]]; end; *a = r(); test_ok(a == [nil])\ndef r; return *[*[1]]; end; *a = r(); test_ok(a == [1])\ndef r; return *[*[1,2]]; end; *a = r(); test_ok(a == [[1,2]])\n\ndef r; return *nil; end; *a = *r(); test_ok(a == [nil])\ndef r; return *1; end; *a = *r(); test_ok(a == [1])\ndef r; return *[]; end; *a = *r(); test_ok(a == [nil])\ndef r; return *[1]; end; *a = *r(); test_ok(a == [1])\ndef r; return *[nil]; end; *a = *r(); test_ok(a == [nil])\ndef r; return *[[]]; end; *a = *r(); test_ok(a == [])\ndef r; return *[1,2]; end; *a = *r(); test_ok(a == [1,2])\ndef r; return *[*[]]; end; *a = *r(); test_ok(a == [nil])\ndef r; return *[*[1]]; end; *a = *r(); test_ok(a == [1])\ndef r; return *[*[1,2]]; end; *a = *r(); test_ok(a == [1,2])\n\ndef r; return; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return nil; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return 1; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])\ndef r; return []; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return [1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])\ndef r; return [nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return [[]]; end; a,b,*c = r(); test_ok([a,b,c] == [[],nil,[]])\ndef r; return [1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])\ndef r; return [*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return [*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])\ndef r; return [*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])\n\ndef r; return *nil; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return *1; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])\ndef r; return *[]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return *[1]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])\ndef r; return *[nil]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return *[[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return *[1,2]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])\ndef r; return *[*[]]; end; a,b,*c = r(); test_ok([a,b,c] == [nil,nil,[]])\ndef r; return *[*[1]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,nil,[]])\ndef r; return *[*[1,2]]; end; a,b,*c = r(); test_ok([a,b,c] == [1,2,[]])\n\nf = lambda {|r,| test_ok([] == r)}\nf.call([], *[])\n\nf = lambda {|r,*l| test_ok([] == r); test_ok([1] == l)}\nf.call([], *[1])\n\nf = lambda{|x| x}\ntest_ok(f.call(42) == 42)\ntest_ok(f.call([42]) == [42])\ntest_ok(f.call([[42]]) == [[42]])\ntest_ok(f.call([42,55]) == [42,55])\n\nf = lambda{|x,| x}\ntest_ok(f.call(42) == 42)\ntest_ok(f.call([42]) == [42])\ntest_ok(f.call([[42]]) == [[42]])\ntest_ok(f.call([42,55]) == [42,55])\n\nf = lambda{|*x| x}\ntest_ok(f.call(42) == [42])\ntest_ok(f.call([42]) == [[42]])\ntest_ok(f.call([[42]]) == [[[42]]])\ntest_ok(f.call([42,55]) == [[42,55]])\ntest_ok(f.call(42,55) == [42,55])\n\na,=*[1]\ntest_ok(a == 1)\na,=*[[1]]\ntest_ok(a == [1])\na,=*[[[1]]]\ntest_ok(a == [[1]])\n\nx, (y, z) = 1, 2, 3\ntest_ok([1,2,nil] == [x,y,z])\nx, (y, z) = 1, [2,3]\ntest_ok([1,2,3] == [x,y,z])\nx, (y, z) = 1, [2]\ntest_ok([1,2,nil] == [x,y,z])\n\na = loop do break; end; test_ok(a == nil)\na = loop do break nil; end; test_ok(a == nil)\na = loop do break 1; end; test_ok(a == 1)\na = loop do break []; end; test_ok(a == [])\na = loop do break [1]; end; test_ok(a == [1])\na = loop do break [nil]; end; test_ok(a == [nil])\na = loop do break [[]]; end; test_ok(a == [[]])\na = loop do break [*[]]; end; test_ok(a == [])\na = loop do break [*[1]]; end; test_ok(a == [1])\na = loop do break [*[1,2]]; end; test_ok(a == [1,2])\n\na = loop do break *nil; end; test_ok(a == nil)\na = loop do break *1; end; test_ok(a == 1)\na = loop do break *[]; end; test_ok(a == nil)\na = loop do break *[1]; end; test_ok(a == 1)\na = loop do break *[nil]; end; test_ok(a == nil)\na = loop do break *[[]]; end; test_ok(a == [])\na = loop do break *[*[]]; end; test_ok(a == nil)\na = loop do break *[*[1]]; end; test_ok(a == 1)\na = loop do break *[*[1,2]]; end; test_ok(a == [1,2])\n\n*a = loop do break; end; test_ok(a == [nil])\n*a = loop do break nil; end; test_ok(a == [nil])\n*a = loop do break 1; end; test_ok(a == [1])\n*a = loop do break []; end; test_ok(a == [[]])\n*a = loop do break [1]; end; test_ok(a == [[1]])\n*a = loop do break [nil]; end; test_ok(a == [[nil]])\n*a = loop do break [[]]; end; test_ok(a == [[[]]])\n*a = loop do break [1,2]; end; test_ok(a == [[1,2]])\n*a = loop do break [*[]]; end; test_ok(a == [[]])\n*a = loop do break [*[1]]; end; test_ok(a == [[1]])\n*a = loop do break [*[1,2]]; end; test_ok(a == [[1,2]])\n\n*a = loop do break *nil; end; test_ok(a == [nil])\n*a = loop do break *1; end; test_ok(a == [1])\n*a = loop do break *[]; end; test_ok(a == [nil])\n*a = loop do break *[1]; end; test_ok(a == [1])\n*a = loop do break *[nil]; end; test_ok(a == [nil])\n*a = loop do break *[[]]; end; test_ok(a == [[]])\n*a = loop do break *[1,2]; end; test_ok(a == [[1,2]])\n*a = loop do break *[*[]]; end; test_ok(a == [nil])\n*a = loop do break *[*[1]]; end; test_ok(a == [1])\n*a = loop do break *[*[1,2]]; end; test_ok(a == [[1,2]])\n\n*a = *loop do break *nil; end; test_ok(a == [nil])\n*a = *loop do break *1; end; test_ok(a == [1])\n*a = *loop do break *[]; end; test_ok(a == [nil])\n*a = *loop do break *[1]; end; test_ok(a == [1])\n*a = *loop do break *[nil]; end; test_ok(a == [nil])\n*a = *loop do break *[[]]; end; test_ok(a == [])\n*a = *loop do break *[1,2]; end; test_ok(a == [1,2])\n*a = *loop do break *[*[]]; end; test_ok(a == [nil])\n*a = *loop do break *[*[1]]; end; test_ok(a == [1])\n*a = *loop do break *[*[1,2]]; end; test_ok(a == [1,2])\n\na,b,*c = loop do break; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break nil; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break 1; end; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = loop do break []; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break [1]; end; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = loop do break [nil]; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break [[]]; end; test_ok([a,b,c] == [[],nil,[]])\na,b,*c = loop do break [1,2]; end; test_ok([a,b,c] == [1,2,[]])\na,b,*c = loop do break [*[]]; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break [*[1]]; end; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = loop do break [*[1,2]]; end; test_ok([a,b,c] == [1,2,[]])\n\na,b,*c = loop do break *nil; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break *1; end; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = loop do break *[]; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break *[1]; end; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = loop do break *[nil]; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break *[[]]; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break *[1,2]; end; test_ok([a,b,c] == [1,2,[]])\na,b,*c = loop do break *[*[]]; end; test_ok([a,b,c] == [nil,nil,[]])\na,b,*c = loop do break *[*[1]]; end; test_ok([a,b,c] == [1,nil,[]])\na,b,*c = loop do break *[*[1,2]]; end; test_ok([a,b,c] == [1,2,[]])\n\ndef r(val); a = yield(); test_ok(a == val, 2); end\nr(nil){next}\nr(nil){next nil}\nr(1){next 1}\nr([]){next []}\nr([1]){next [1]}\nr([nil]){next [nil]}\nr([[]]){next [[]]}\nr([]){next [*[]]}\nr([1]){next [*[1]]}\nr([1,2]){next [*[1,2]]}\n\nr(nil){next *nil}\nr(1){next *1}\nr(nil){next *[]}\nr(1){next *[1]}\nr(nil){next *[nil]}\nr([]){next *[[]]}\nr(nil){next *[*[]]}\nr(1){next *[*[1]]}\nr([1,2]){next *[*[1,2]]}\n\ndef r(val); *a = yield(); test_ok(a == val, 2); end\nr([nil]){next}\nr([nil]){next nil}\nr([1]){next 1}\nr([[]]){next []}\nr([[1]]){next [1]}\nr([[nil]]){next [nil]}\nr([[[]]]){next [[]]}\nr([[1,2]]){next [1,2]}\nr([[]]){next [*[]]}\nr([[1]]){next [*[1]]}\nr([[1,2]]){next [*[1,2]]}\n\ndef r(val); *a = *yield(); test_ok(a == val, 2); end\nr([nil]){next *nil}\nr([1]){next *1}\nr([nil]){next *[]}\nr([1]){next *[1]}\nr([nil]){next *[nil]}\nr([]){next *[[]]}\nr([1,2]){next *[1,2]}\nr([nil]){next *[*[]]}\nr([1]){next *[*[1]]}\nr([1,2]){next *[*[1,2]]}\n\ndef r(val); a,b,*c = yield(); test_ok([a,b,c] == val, 2); end\nr([nil,nil,[]]){next}\nr([nil,nil,[]]){next nil}\nr([1,nil,[]]){next 1}\nr([nil,nil,[]]){next []}\nr([1,nil,[]]){next [1]}\nr([nil,nil,[]]){next [nil]}\nr([[],nil,[]]){next [[]]}\nr([1,2,[]]){next [1,2]}\nr([nil,nil,[]]){next [*[]]}\nr([1,nil,[]]){next [*[1]]}\nr([1,2,[]]){next [*[1,2]]}\n\ndef r(val); a,b,*c = *yield(); test_ok([a,b,c] == val, 2); end\nr([nil,nil,[]]){next *nil}\nr([1,nil,[]]){next *1}\nr([nil,nil,[]]){next *[]}\nr([1,nil,[]]){next *[1]}\nr([nil,nil,[]]){next *[nil]}\nr([nil,nil,[]]){next *[[]]}\nr([1,2,[]]){next *[1,2]}\nr([nil,nil,[]]){next *[*[]]}\nr([1,nil,[]]){next *[*[1]]}\nr([1,2,[]]){next *[*[1,2]]}\n\ntest_check \"condition\"\n\n$x = '0';\n\n$x == $x && test_ok(true)\n$x != $x && test_ok(false)\n$x == $x || test_ok(false)\n$x != $x || test_ok(true)\n\n# first test to see if we can run the tests.\n\ntest_check \"if/unless\";\n\n$x = 'test';\ntest_ok(if $x == $x then true else false end)\n$bad = false\nunless $x == $x\n  $bad = true\nend\ntest_ok(!$bad)\ntest_ok(unless $x != $x then true else false end)\n\ntest_check \"case\"\n\ncase 5\nwhen 1, 2, 3, 4, 6, 7, 8\n  test_ok(false)\nwhen 5\n  test_ok(true)\nend\n\ncase 5\nwhen 5\n  test_ok(true)\nwhen 1..10\n  test_ok(false)\nend\n\ncase 5\nwhen 1..10\n  test_ok(true)\nelse\n  test_ok(false)\nend\n\ncase 5\nwhen 5\n  test_ok(true)\nelse\n  test_ok(false)\nend\n\ncase \"foobar\"\nwhen /^f.*r$/\n  test_ok(true)\nelse\n  test_ok(false)\nend\n\ntest_check \"while/until\";\n\ntmp = open(\"while_tmp\", \"w\")\ntmp.print \"tvi925\\n\";\ntmp.print \"tvi920\\n\";\ntmp.print \"vt100\\n\";\ntmp.print \"Amiga\\n\";\ntmp.print \"paper\\n\";\ntmp.close\n\n# test break\n\ntmp = open(\"while_tmp\", \"r\")\ntest_ok(tmp.kind_of?(File))\n\nwhile line = tmp.gets()\n  break if /vt100/ =~ line\nend\n\ntest_ok(!tmp.eof? && /vt100/ =~ line)\ntmp.close\n\n# test next\n$bad = false\ntmp = open(\"while_tmp\", \"r\")\nwhile line = tmp.gets()\n  next if /vt100/ =~ line\n  $bad = 1 if /vt100/ =~ line\nend\ntest_ok(!(!tmp.eof? || /vt100/ =~ line || $bad))\ntmp.close\n\n# test redo\n$bad = false\ntmp = open(\"while_tmp\", \"r\")\nwhile tmp.gets()\n  line = $_\n  gsub(/vt100/, 'VT100')\n  if $_ != line\n    $_.gsub!('VT100', 'Vt100')\n    redo\n  end\n  $bad = 1 if /vt100/ =~ $_\n  $bad = 1 if /VT100/ =~ $_\nend\ntest_ok(tmp.eof? && !$bad)\ntmp.close\n\nsum=0\nfor i in 1..10\n  sum += i\n  i -= 1\n  if i > 0\n    redo\n  end\nend\ntest_ok(sum == 220)\n\n# test interval\n$bad = false\ntmp = open(\"while_tmp\", \"r\")\nwhile line = tmp.gets()\n  break if 3\n  case line\n  when /vt100/, /Amiga/, /paper/\n    $bad = true\n  end\nend\ntest_ok(!$bad)\ntmp.close\n\nFile.unlink \"while_tmp\" or `/bin/rm -f \"while_tmp\"`\ntest_ok(!File.exist?(\"while_tmp\"))\n\ni = 0\nuntil i>4\n  i+=1\nend\ntest_ok(i>4)\n\n\n# exception handling\ntest_check \"exception\";\n\nbegin\n  raise \"this must be handled\"\n  test_ok(false)\nrescue\n  test_ok(true)\nend\n\n$bad = true\nbegin\n  raise \"this must be handled no.2\"\nrescue\n  if $bad\n    $bad = false\n    retry\n    test_ok(false)\n  end\nend\ntest_ok(true)\n\n# exception in rescue clause\n$string = \"this must be handled no.3\"\nbegin\n  begin\n    raise \"exception in rescue clause\"\n  rescue \n    raise $string\n  end\n  test_ok(false)\nrescue\n  test_ok(true) if $! == $string\nend\n  \n# exception in ensure clause\nbegin\n  begin\n    raise \"this must be handled no.4\"\n  ensure \n    raise \"exception in ensure clause\"\n  end\n  test_ok(false)\nrescue\n  test_ok(true)\nend\n\n$bad = true\nbegin\n  begin\n    raise \"this must be handled no.5\"\n  ensure\n    $bad = false\n  end\nrescue\nend\ntest_ok(!$bad)\n\n$bad = true\nbegin\n  begin\n    raise \"this must be handled no.6\"\n  ensure\n    $bad = false\n  end\nrescue\nend\ntest_ok(!$bad)\n\n$bad = true\nwhile true\n  begin\n    break\n  ensure\n    $bad = false\n  end\nend\ntest_ok(!$bad)\n\ntest_ok(catch(:foo) {\n     loop do\n       loop do\n\t throw :foo, true\n\t break\n       end\n       break\n       test_ok(false)\t\t\t# should no reach here\n     end\n     false\n   })\n\ntest_check \"array\"\ntest_ok([1, 2] + [3, 4] == [1, 2, 3, 4])\ntest_ok([1, 2] * 2 == [1, 2, 1, 2])\ntest_ok([1, 2] * \":\" == \"1:2\")\n\ntest_ok([1, 2].hash == [1, 2].hash)\n\ntest_ok([1,2,3] & [2,3,4] == [2,3])\ntest_ok([1,2,3] | [2,3,4] == [1,2,3,4])\ntest_ok([1,2,3] - [2,3] == [1])\n\n$x = [0, 1, 2, 3, 4, 5]\ntest_ok($x[2] == 2)\ntest_ok($x[1..3] == [1, 2, 3])\ntest_ok($x[1,3] == [1, 2, 3])\n\n$x[0, 2] = 10\ntest_ok($x[0] == 10 && $x[1] == 2)\n  \n$x[0, 0] = -1\ntest_ok($x[0] == -1 && $x[1] == 10)\n\n$x[-1, 1] = 20\ntest_ok($x[-1] == 20 && $x.pop == 20)\n\n# array and/or\ntest_ok(([1,2,3]&[2,4,6]) == [2])\ntest_ok(([1,2,3]|[2,4,6]) == [1,2,3,4,6])\n\n# compact\n$x = [nil, 1, nil, nil, 5, nil, nil]\n$x.compact!\ntest_ok($x == [1, 5])\n\n# uniq\n$x = [1, 1, 4, 2, 5, 4, 5, 1, 2]\n$x.uniq!\ntest_ok($x == [1, 4, 2, 5])\n\n# empty?\ntest_ok(!$x.empty?)\n$x = []\ntest_ok($x.empty?)\n\n# sort\n$x = [\"it\", \"came\", \"to\", \"pass\", \"that\", \"...\"]\n$x = $x.sort.join(\" \")\ntest_ok($x == \"... came it pass that to\")\n$x = [2,5,3,1,7]\n$x.sort!{|a,b| a<=>b}\t\t# sort with condition\ntest_ok($x == [1,2,3,5,7])\n$x.sort!{|a,b| b-a}\t\t# reverse sort\ntest_ok($x == [7,5,3,2,1])\n\n# split test\n$x = \"The Book of Mormon\"\ntest_ok($x.split(//).reverse!.join == $x.reverse)\ntest_ok($x.reverse == $x.reverse!)\ntest_ok(\"1 byte string\".split(//).reverse.join(\":\") == \"g:n:i:r:t:s: :e:t:y:b: :1\")\n$x = \"a b c  d\"\ntest_ok($x.split == ['a', 'b', 'c', 'd'])\ntest_ok($x.split(' ') == ['a', 'b', 'c', 'd'])\ntest_ok(defined? \"a\".chomp)\ntest_ok(\"abc\".scan(/./) == [\"a\", \"b\", \"c\"])\ntest_ok(\"1a2b3c\".scan(/(\\d.)/) == [[\"1a\"], [\"2b\"], [\"3c\"]])\n# non-greedy match\ntest_ok(\"a=12;b=22\".scan(/(.*?)=(\\d*);?/) == [[\"a\", \"12\"], [\"b\", \"22\"]])\n\n$x = [1]\ntest_ok(($x * 5).join(\":\") == '1:1:1:1:1')\ntest_ok(($x * 1).join(\":\") == '1')\ntest_ok(($x * 0).join(\":\") == '')\n\n*$x = *(1..7).to_a\ntest_ok($x.size == 7)\ntest_ok($x == [1, 2, 3, 4, 5, 6, 7])\n\n$x = [1,2,3]\n$x[1,0] = $x\ntest_ok($x == [1,1,2,3,2,3])\n\n$x = [1,2,3]\n$x[-1,0] = $x\ntest_ok($x == [1,2,1,2,3,3])\n\n$x = [1,2,3]\n$x.concat($x)\ntest_ok($x == [1,2,3,1,2,3])\n\ntest_check \"hash\"\n$x = {1=>2, 2=>4, 3=>6}\n$y = {1, 2, 2, 4, 3, 6}\n\ntest_ok($x[1] == 2)\n\ntest_ok(begin   \n     for k,v in $y\n       raise if k*2 != v\n     end\n     true\n   rescue\n     false\n   end)\n\ntest_ok($x.length == 3)\ntest_ok($x.has_key?(1))\ntest_ok($x.has_value?(4))\ntest_ok($x.values_at(2,3) == [4,6])\ntest_ok($x == {1=>2, 2=>4, 3=>6})\n\n$z = $y.keys.sort.join(\":\")\ntest_ok($z == \"1:2:3\")\n\n$z = $y.values.sort.join(\":\")\ntest_ok($z == \"2:4:6\")\ntest_ok($x == $y)\n\n$y.shift\ntest_ok($y.length == 2)\n\n$z = [1,2]\n$y[$z] = 256\ntest_ok($y[$z] == 256)\n\n$x = Hash.new(0)\n$x[1] = 1\ntest_ok($x[1] == 1)\ntest_ok($x[2] == 0)\n\n$x = Hash.new([])\ntest_ok($x[22] == [])\ntest_ok($x[22].equal?($x[22]))\n\n$x = Hash.new{[]}\ntest_ok($x[22] == [])\ntest_ok(!$x[22].equal?($x[22]))\n\n$x = Hash.new{|h,k| $z = k; h[k] = k*2}\n$z = 0\ntest_ok($x[22] == 44)\ntest_ok($z == 22)\n$z = 0\ntest_ok($x[22] == 44)\ntest_ok($z == 0)\n$x.default = 5\ntest_ok($x[23] == 5)\n\n$x = Hash.new\ndef $x.default(k)\n  $z = k\n  self[k] = k*2\nend\n$z = 0\ntest_ok($x[22] == 44)\ntest_ok($z == 22)\n$z = 0\ntest_ok($x[22] == 44)\ntest_ok($z == 0)\n\ntest_check \"iterator\"\n\ntest_ok(!iterator?)\n\ndef ttt\n  test_ok(iterator?)\nend\nttt{}\n\n# yield at top level\ntest_ok(!defined?(yield))\n\n$x = [1, 2, 3, 4]\n$y = []\n\n# iterator over array\nfor i in $x\n  $y.push i\nend\ntest_ok($x == $y)\n\n# nested iterator\ndef tt\n  1.upto(10) {|i|\n    yield i\n  }\nend\n\ntt{|i| break if i == 5}\ntest_ok(i == 5)\n\ndef tt2(dummy)\n  yield 1\nend\n\ndef tt3(&block)\n  tt2(raise(ArgumentError,\"\"),&block)\nend\n\n$x = false\nbegin\n  tt3{}\nrescue ArgumentError\n  $x = true\nrescue Exception\nend\ntest_ok($x)\n\ndef tt4 &block\n  tt2(raise(ArgumentError,\"\"),&block)\nend\n$x = false\nbegin\n  tt4{}\nrescue ArgumentError\n  $x = true\nrescue Exception\nend\ntest_ok($x)\n\n# iterator break/redo/next/retry\ndone = true\nloop{\n  break\n  done = false\t\t\t# should not reach here\n}\ntest_ok(done)\n\ndone = false\n$bad = false\nloop {\n  break if done\n  done = true\n  next\n  $bad = true\t\t\t# should not reach here\n}\ntest_ok(!$bad)\n\ndone = false\n$bad = false\nloop {\n  break if done\n  done = true\n  redo\n  $bad = true\t\t\t# should not reach here\n}\ntest_ok(!$bad)\n\n$x = []\nfor i in 1 .. 7\n  $x.push i\nend\ntest_ok($x.size == 7)\ntest_ok($x == [1, 2, 3, 4, 5, 6, 7])\n\n$done = false\n$x = []\nfor i in 1 .. 7\t\t\t# see how retry works in iterator loop\n  if i == 4 and not $done\n    $done = true\n    retry\n  end\n  $x.push(i)\nend\ntest_ok($x.size == 10)\ntest_ok($x == [1, 2, 3, 1, 2, 3, 4, 5, 6, 7])\n\n# append method to built-in class\nclass Array\n  def iter_test1\n    collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}\n  end\n  def iter_test2\n    a = collect{|e| [e, yield(e)]}\n    a.sort{|a,b|a[1]<=>b[1]}\n  end\nend\n$x = [[1,2],[3,4],[5,6]]\ntest_ok($x.iter_test1{|x|x} == $x.iter_test2{|x|x})\n\nclass IterTest\n  def initialize(e); @body = e; end\n\n  def each0(&block); @body.each(&block); end\n  def each1(&block); @body.each {|*x| block.call(*x) } end\n  def each2(&block); @body.each {|*x| block.call(x) } end\n  def each3(&block); @body.each {|x| block.call(*x) } end\n  def each4(&block); @body.each {|x| block.call(x) } end\n  def each5; @body.each {|*x| yield(*x) } end\n  def each6; @body.each {|*x| yield(x) } end\n  def each7; @body.each {|x| yield(*x) } end\n  def each8; @body.each {|x| yield(x) } end\n\n  def f(a)\n    a\n  end\nend\ntest_ok(IterTest.new(nil).method(:f).to_proc.call([1]) == [1])\nm = /\\w+/.match(\"abc\")\ntest_ok(IterTest.new(nil).method(:f).to_proc.call([m]) == [m])\n\nIterTest.new([0]).each0 {|x| test_ok(x == 0)}\nIterTest.new([1]).each1 {|x| test_ok(x == 1)}\nIterTest.new([2]).each2 {|x| test_ok(x == [2])}\nIterTest.new([3]).each3 {|x| test_ok(x == 3)}\nIterTest.new([4]).each4 {|x| test_ok(x == 4)}\nIterTest.new([5]).each5 {|x| test_ok(x == 5)}\nIterTest.new([6]).each6 {|x| test_ok(x == [6])}\nIterTest.new([7]).each7 {|x| test_ok(x == 7)}\nIterTest.new([8]).each8 {|x| test_ok(x == 8)}\n\nIterTest.new([[0]]).each0 {|x| test_ok(x == [0])}\nIterTest.new([[1]]).each1 {|x| test_ok(x == [1])}\nIterTest.new([[2]]).each2 {|x| test_ok(x == [[2]])}\nIterTest.new([[3]]).each3 {|x| test_ok(x == 3)}\nIterTest.new([[4]]).each4 {|x| test_ok(x == [4])}\nIterTest.new([[5]]).each5 {|x| test_ok(x == [5])}\nIterTest.new([[6]]).each6 {|x| test_ok(x == [[6]])}\nIterTest.new([[7]]).each7 {|x| test_ok(x == 7)}\nIterTest.new([[8]]).each8 {|x| test_ok(x == [8])}\n\nIterTest.new([[0,0]]).each0 {|x| test_ok(x == [0,0])}\nIterTest.new([[8,8]]).each8 {|x| test_ok(x == [8,8])}\n\ndef m0(v)\n  v\nend\n\ndef m1\n  m0(block_given?)\nend\ntest_ok(m1{p 'test'})\ntest_ok(!m1)\n\ndef m\n  m0(block_given?,&proc{})\nend\ntest_ok(m1{p 'test'})\ntest_ok(!m1)\n\nclass C\n  include Enumerable\n  def initialize\n    @a = [1,2,3]\n  end\n  def each(&block)\n    @a.each(&block)\n  end\nend\n\ntest_ok(C.new.collect{|n| n} == [1,2,3])\n\ntest_ok(Proc == lambda{}.class)\ntest_ok(Proc == Proc.new{}.class)\nlambda{|a|test_ok(a==1)}.call(1)\ndef block_test(klass, &block)\n  test_ok(klass === block)\nend\n\nblock_test(NilClass)\nblock_test(Proc){}\n\ndef argument_test(state, proc, *args)\n  x = state\n  begin\n    proc.call(*args)\n  rescue ArgumentError\n    x = !x\n  end\n  test_ok(x,2)\nend\n\nargument_test(true, lambda{||})\nargument_test(false, lambda{||}, 1)\nargument_test(true, lambda{|a,|}, 1)\nargument_test(false, lambda{|a,|})\nargument_test(false, lambda{|a,|}, 1,2)\n\ndef get_block(&block)\n  block\nend\n\ntest_ok(Proc == get_block{}.class)\nargument_test(true, get_block{||})\nargument_test(true, get_block{||}, 1)\nargument_test(true, get_block{|a,|}, 1)\nargument_test(true, get_block{|a,|})\nargument_test(true, get_block{|a,|}, 1,2)\n\nargument_test(true, get_block(&lambda{||}))\nargument_test(false, get_block(&lambda{||}),1)\nargument_test(true, get_block(&lambda{|a,|}),1)\nargument_test(false, get_block(&lambda{|a,|}),1,2)\n\nblock = get_block{11}\ntest_ok(block.class == Proc)\ntest_ok(block.to_proc.class == Proc)\ntest_ok(block.clone.call == 11)\ntest_ok(get_block(&block).class == Proc)\n\nlambda = lambda{44}\ntest_ok(lambda.class == Proc)\ntest_ok(lambda.to_proc.class == Proc)\ntest_ok(lambda.clone.call == 44)\ntest_ok(get_block(&lambda).class == Proc)\n\ntest_ok(Proc.new{|a,| a}.call(1,2,3) == 1)\nargument_test(true, Proc.new{|a,|}, 1,2)\n\ntest_ok(Proc.new{|&b| b.call(10)}.call {|x| x} == 10)\ntest_ok(Proc.new{|a,&b| b.call(a)}.call(12) {|x| x} == 12)\n\ndef test_return1\n  Proc.new {\n    return 55\n  }.call + 5\nend\ntest_ok(test_return1() == 55)\ndef test_return2\n  lambda {\n    return 55\n  }.call + 5\nend\ntest_ok(test_return2() == 60)\n\ndef proc_call(&b)\n  b.call\nend\ndef proc_yield()\n  yield\nend\ndef proc_return1\n  proc_call{return 42}+1\nend\ntest_ok(proc_return1() == 42)\ndef proc_return2\n  proc_yield{return 42}+1\nend\ntest_ok(proc_return2() == 42)\n\ndef ljump_test(state, proc, *args)\n  x = state\n  begin\n    proc.call(*args)\n  rescue LocalJumpError\n    x = !x\n  end\n  test_ok(x,2)\nend\n\nljump_test(false, get_block{break})\nljump_test(true, lambda{break})\n\ntest_ok(block.arity == -1)\ntest_ok(lambda.arity == -1)\ntest_ok(lambda{||}.arity == 0)\ntest_ok(lambda{|a|}.arity == 1)\ntest_ok(lambda{|a,|}.arity == 1)\ntest_ok(lambda{|a,b|}.arity == 2)\n\ndef marity_test(m)\n  method = method(m)\n  test_ok(method.arity == method.to_proc.arity)\nend\nmarity_test(:test_ok)\nmarity_test(:marity_test)\nmarity_test(:p)\n\nlambda(&method(:test_ok)).call(true)\nlambda(&get_block{|a,n| test_ok(a,n)}).call(true, 2)\n\nclass ITER_TEST1\n   def a\n     block_given?\n   end\nend\n\nclass ITER_TEST2 < ITER_TEST1\n   def a\n     test_ok(super)\n     super\n   end\nend\ntest_ok(ITER_TEST2.new.a {})\n\nclass ITER_TEST3\n  def foo x\n    return yield if block_given?\n    x\n  end\nend\n\nclass ITER_TEST4 < ITER_TEST3\n  def foo x\n    test_ok(super == yield)\n    test_ok(super(x, &nil) == x)\n  end\nend\n\nITER_TEST4.new.foo(44){55}   \n\ntest_check \"float\"\ntest_ok(2.6.floor == 2)\ntest_ok((-2.6).floor == -3)\ntest_ok(2.6.ceil == 3)\ntest_ok((-2.6).ceil == -2)\ntest_ok(2.6.truncate == 2)\ntest_ok((-2.6).truncate == -2)\ntest_ok(2.6.round == 3)\ntest_ok((-2.4).truncate == -2)\ntest_ok((13.4 % 1 - 0.4).abs < 0.0001)\nnan = 0.0/0\ndef nan_test(x,y)\n  test_ok(x != y)\n  test_ok((x < y) == false)\n  test_ok((x > y) == false)\n  test_ok((x <= y) == false)\n  test_ok((x >= y) == false)\nend\nnan_test(nan, nan)\nnan_test(nan, 0)\nnan_test(nan, 1)\nnan_test(nan, -1)\nnan_test(nan, 1000)\nnan_test(nan, -1000)\nnan_test(nan, 1_000_000_000_000)\nnan_test(nan, -1_000_000_000_000)\nnan_test(nan, 100.0);\nnan_test(nan, -100.0);\nnan_test(nan, 0.001);\nnan_test(nan, -0.001);\nnan_test(nan, 1.0/0);\nnan_test(nan, -1.0/0);\n\n#s = \"3.7517675036461267e+17\"\n#test_ok(s == sprintf(\"%.16e\", s.to_f))\nf = 3.7517675036461267e+17\ntest_ok(f == sprintf(\"%.16e\", f).to_f)\n\n\ntest_check \"bignum\"\ndef fact(n)\n  return 1 if n == 0\n  f = 1\n  while n>0\n    f *= n\n    n -= 1\n  end\n  return f\nend\n$x = fact(40)\ntest_ok($x == $x)\ntest_ok($x == fact(40))\ntest_ok($x < $x+2)\ntest_ok($x > $x-2)\ntest_ok($x == 815915283247897734345611269596115894272000000000)\ntest_ok($x != 815915283247897734345611269596115894272000000001)\ntest_ok($x+1 == 815915283247897734345611269596115894272000000001)\ntest_ok($x/fact(20) == 335367096786357081410764800000)\n$x = -$x\ntest_ok($x == -815915283247897734345611269596115894272000000000)\ntest_ok(2-(2**32) == -(2**32-2))\ntest_ok(2**32 - 5 == (2**32-3)-2)\n\n$good = true;\nfor i in 1000..1014\n  $good = false if ((1 << i) != (2**i))\nend\ntest_ok($good)\n\n$good = true;\nn1= 1 << 1000\nfor i in 1000..1014\n  $good = false if ((1 << i) != n1)\n  n1 *= 2\nend\ntest_ok($good)\n\n$good = true;\nn2=n1\nfor i in 1..10\n  n1 = n1 / 2\n  n2 = n2 >> 1\n  $good = false if (n1 != n2)\nend\ntest_ok($good)\n\n$good = true;\nfor i in 4000..4096\n  n1 = 1 << i;\n  if (n1**2-1) / (n1+1) != (n1-1)\n    p i\n    $good = false\n  end\nend\ntest_ok($good)\n\nb = 10**80\na = b * 9 + 7\ntest_ok(7 == a.modulo(b))\ntest_ok(-b + 7 == a.modulo(-b))\ntest_ok(b + -7 == (-a).modulo(b))\ntest_ok(-7 == (-a).modulo(-b))\ntest_ok(7 == a.remainder(b))\ntest_ok(7 == a.remainder(-b))\ntest_ok(-7 == (-a).remainder(b))\ntest_ok(-7 == (-a).remainder(-b))\n\ntest_ok(10**40+10**20 == 10000000000000000000100000000000000000000)\ntest_ok(10**40/10**20 == 100000000000000000000)\n\na = 677330545177305025495135714080\nb = 14269972710765292560\ntest_ok(a % b == 0)\ntest_ok(-a % b == 0)\n\ndef shift_test(a)\n  b = a / (2 ** 32)\n  c = a >> 32\n  test_ok(b == c)\n\n  b = a * (2 ** 32)\n  c = a << 32\n  test_ok(b == c)\nend\n\nshift_test(-4518325415524767873)\nshift_test(-0xfffffffffffffffff)\n\ntest_check \"string & char\"\n\ntest_ok(\"abcd\" == \"abcd\")\ntest_ok(\"abcd\" =~ /abcd/)\ntest_ok(\"abcd\" === \"abcd\")\n# compile time string concatenation\ntest_ok(\"ab\" \"cd\" == \"abcd\")\ntest_ok(\"#{22}aa\" \"cd#{44}\" == \"22aacd44\")\ntest_ok(\"#{22}aa\" \"cd#{44}\" \"55\" \"#{66}\" == \"22aacd445566\")\ntest_ok(\"abc\" !~ /^$/)\ntest_ok(\"abc\\n\" !~ /^$/)\ntest_ok(\"abc\" !~ /^d*$/)\ntest_ok((\"abc\" =~ /d*$/) == 3)\ntest_ok(\"\" =~ /^$/)\ntest_ok(\"\\n\" =~ /^$/)\ntest_ok(\"a\\n\\n\" =~ /^$/)\ntest_ok(\"abcabc\" =~ /.*a/ && $& == \"abca\")\ntest_ok(\"abcabc\" =~ /.*c/ && $& == \"abcabc\")\ntest_ok(\"abcabc\" =~ /.*?a/ && $& == \"a\")\ntest_ok(\"abcabc\" =~ /.*?c/ && $& == \"abc\")\ntest_ok(/(.|\\n)*?\\n(b|\\n)/ =~ \"a\\nb\\n\\n\" && $& == \"a\\nb\")\n\ntest_ok(/^(ab+)+b/ =~ \"ababb\" && $& == \"ababb\")\ntest_ok(/^(?:ab+)+b/ =~ \"ababb\" && $& == \"ababb\")\ntest_ok(/^(ab+)+/ =~ \"ababb\" && $& == \"ababb\")\ntest_ok(/^(?:ab+)+/ =~ \"ababb\" && $& == \"ababb\")\n\ntest_ok(/(\\s+\\d+){2}/ =~ \" 1 2\" && $& == \" 1 2\")\ntest_ok(/(?:\\s+\\d+){2}/ =~ \" 1 2\" && $& == \" 1 2\")\n\n$x = <<END;\nABCD\nABCD\nEND\n$x.gsub!(/((.|\\n)*?)B((.|\\n)*?)D/){$1+$3}\ntest_ok($x == \"AC\\nAC\\n\")\n\ntest_ok(\"foobar\" =~ /foo(?=(bar)|(baz))/)\ntest_ok(\"foobaz\" =~ /foo(?=(bar)|(baz))/)\n\n$foo = \"abc\"\ntest_ok(\"#$foo = abc\" == \"abc = abc\")\ntest_ok(\"#{$foo} = abc\" == \"abc = abc\")\n\nfoo = \"abc\"\ntest_ok(\"#{foo} = abc\" == \"abc = abc\")\n\ntest_ok('-' * 5 == '-----')\ntest_ok('-' * 1 == '-')\ntest_ok('-' * 0 == '')\n\nfoo = '-'\ntest_ok(foo * 5 == '-----')\ntest_ok(foo * 1 == '-')\ntest_ok(foo * 0 == '')\n\n$x = \"a.gif\"\ntest_ok($x.sub(/.*\\.([^\\.]+)$/, '\\1') == \"gif\")\ntest_ok($x.sub(/.*\\.([^\\.]+)$/, 'b.\\1') == \"b.gif\")\ntest_ok($x.sub(/.*\\.([^\\.]+)$/, '\\2') == \"\")\ntest_ok($x.sub(/.*\\.([^\\.]+)$/, 'a\\2b') == \"ab\")\ntest_ok($x.sub(/.*\\.([^\\.]+)$/, '<\\&>') == \"<a.gif>\")\n\n# character constants(assumes ASCII)\ntest_ok(\"a\"[0] == ?a)\ntest_ok(?a == ?a)\ntest_ok(?\\C-a == 1)\ntest_ok(?\\M-a == 225)\ntest_ok(?\\M-\\C-a == 129)\ntest_ok(\"a\".upcase![0] == ?A)\ntest_ok(\"A\".downcase![0] == ?a)\ntest_ok(\"abc\".tr!(\"a-z\", \"A-Z\") == \"ABC\")\ntest_ok(\"aabbcccc\".tr_s!(\"a-z\", \"A-Z\") == \"ABC\")\ntest_ok(\"abcc\".squeeze!(\"a-z\") == \"abc\")\ntest_ok(\"abcd\".delete!(\"bc\") == \"ad\")\n\n$x = \"abcdef\"\n$y = [ ?a, ?b, ?c, ?d, ?e, ?f ]\n$bad = false\n$x.each_byte {|i|\n  if i != $y.shift\n    $bad = true\n    break\n  end\n}\ntest_ok(!$bad)\n\ns = \"a string\"\ns[0..s.size]=\"another string\"\ntest_ok(s == \"another string\")\n\ns = <<EOS\n#{\n[1,2,3].join(\",\")\n}\nEOS\ntest_ok(s == \"1,2,3\\n\")\ntest_ok(\"Just\".to_i(36) == 926381)\ntest_ok(\"-another\".to_i(36) == -23200231779)\ntest_ok(1299022.to_s(36) == \"ruby\")\ntest_ok(-1045307475.to_s(36) == \"-hacker\")\ntest_ok(\"Just_another_Ruby_hacker\".to_i(36) == 265419172580680477752431643787347)\ntest_ok(-265419172580680477752431643787347.to_s(36) == \"-justanotherrubyhacker\")\n\na = []\n(0..255).each {|n|\n  ch = [n].pack(\"C\")                     \n  a.push ch if /a#{Regexp.quote ch}b/x =~ \"ab\" \n}\ntest_ok(a.size == 0)\n\ntest_check \"assignment\"\na = nil\ntest_ok(defined?(a))\ntest_ok(a == nil)\n\n# multiple asignment\na, b = 1, 2\ntest_ok(a == 1 && b == 2)\n\na, b = b, a\ntest_ok(a == 2 && b == 1)\n\na, = 1,2\ntest_ok(a == 1)\n\na, *b = 1, 2, 3\ntest_ok(a == 1 && b == [2, 3])\n\na, (b, c), d = 1, [2, 3], 4\ntest_ok(a == 1 && b == 2 && c == 3 && d == 4)\n\n*a = 1, 2, 3\ntest_ok(a == [1, 2, 3])\n\n*a = 4\ntest_ok(a == [4])\n\n*a = nil\ntest_ok(a == [nil])\n\ntest_check \"call\"\ndef aaa(a, b=100, *rest)\n  res = [a, b]\n  res += rest if rest\n  return res\nend\n\n# not enough argument\nbegin\n  aaa()\t\t\t\t# need at least 1 arg\n  test_ok(false)\nrescue\n  test_ok(true)\nend\n\nbegin\n  aaa\t\t\t\t# no arg given (exception raised)\n  test_ok(false)\nrescue\n  test_ok(true)\nend\n\ntest_ok(aaa(1) == [1, 100])\ntest_ok(aaa(1, 2) == [1, 2])\ntest_ok(aaa(1, 2, 3, 4) == [1, 2, 3, 4])\ntest_ok(aaa(1, *[2, 3, 4]) == [1, 2, 3, 4])\n\ntest_check \"proc\"\n$proc = proc{|i| i}\ntest_ok($proc.call(2) == 2)\ntest_ok($proc.call(3) == 3)\n\n$proc = proc{|i| i*2}\ntest_ok($proc.call(2) == 4)\ntest_ok($proc.call(3) == 6)\n\nproc{\n  iii=5\t\t\t\t# nested local variable\n  $proc = proc{|i|\n    iii = i\n  }\n  $proc2 = proc {\n    $x = iii\t\t\t# nested variables shared by procs\n  }\n  # scope of nested variables\n  test_ok(defined?(iii))\n}.call\ntest_ok(!defined?(iii))\t\t# out of scope\n\nloop{iii=5; test_ok(eval(\"defined? iii\")); break}\nloop {\n  iii = 10\n  def dyna_var_check\n    loop {\n      test_ok(!defined?(iii))\n      break\n    }\n  end\n  dyna_var_check\n  break\n}\n$x=0\n$proc.call(5)\n$proc2.call\ntest_ok($x == 5)\n\nif defined? Process.kill\n  test_check \"signal\"\n\n  $x = 0\n  trap \"SIGINT\", proc{|sig| $x = 2}\n  Process.kill \"SIGINT\", $$\n  sleep 0.1\n  test_ok($x == 2)\n\n  trap \"SIGINT\", proc{raise \"Interrupt\"}\n\n  x = false\n  begin\n    Process.kill \"SIGINT\", $$\n    sleep 0.1\n  rescue\n    x = $!\n  end\n  test_ok(x && /Interrupt/ =~ x.message)\nend\n\ntest_check \"eval\"\ntest_ok(eval(\"\") == nil)\n$bad=false\neval 'while false; $bad = true; print \"foo\\n\" end'\ntest_ok(!$bad)\n\ntest_ok(eval('TRUE'))\ntest_ok(eval('true'))\ntest_ok(!eval('NIL'))\ntest_ok(!eval('nil'))\ntest_ok(!eval('FALSE'))\ntest_ok(!eval('false'))\n\n$foo = 'test_ok(true)'\nbegin\n  eval $foo\nrescue\n  test_ok(false)\nend\n\ntest_ok(eval(\"$foo\") == 'test_ok(true)')\ntest_ok(eval(\"true\") == true)\ni = 5\ntest_ok(eval(\"i == 5\"))\ntest_ok(eval(\"i\") == 5)\ntest_ok(eval(\"defined? i\"))\n\n# eval with binding\ndef test_ev\n  local1 = \"local1\"\n  lambda {\n    local2 = \"local2\"\n    return binding\n  }.call\nend\n\n$x = test_ev\ntest_ok(eval(\"local1\", $x) == \"local1\") # normal local var\ntest_ok(eval(\"local2\", $x) == \"local2\") # nested local var\n$bad = true\nbegin\n  p eval(\"local1\")\nrescue NameError\t\t# must raise error\n  $bad = false\nend\ntest_ok(!$bad)\n\nmodule EvTest\n  EVTEST1 = 25\n  evtest2 = 125\n  $x = binding\nend\ntest_ok(eval(\"EVTEST1\", $x) == 25)\t# constant in module\ntest_ok(eval(\"evtest2\", $x) == 125)\t# local var in module\n$bad = true\nbegin\n  eval(\"EVTEST1\")\nrescue NameError\t\t# must raise error\n  $bad = false\nend\ntest_ok(!$bad)\n\nx = proc{}\neval \"i4 = 1\", x\ntest_ok(eval(\"i4\", x) == 1)\nx = proc{proc{}}.call\neval \"i4 = 22\", x\ntest_ok(eval(\"i4\", x) == 22)\n$x = []\nx = proc{proc{}}.call\neval \"(0..9).each{|i5| $x[i5] = proc{i5*2}}\", x\ntest_ok($x[4].call == 8)\n\nx = binding\neval \"i = 1\", x\ntest_ok(eval(\"i\", x) == 1)\nx = proc{binding}.call\neval \"i = 22\", x\ntest_ok(eval(\"i\", x) == 22)\n$x = []\nx = proc{binding}.call\neval \"(0..9).each{|i5| $x[i5] = proc{i5*2}}\", x\ntest_ok($x[4].call == 8)\nx = proc{binding}.call\neval \"for i6 in 1..1; j6=i6; end\", x\ntest_ok(eval(\"defined? i6\", x))\ntest_ok(eval(\"defined? j6\", x))\n\nproc {\n  p = binding\n  eval \"foo11 = 1\", p\n  foo22 = 5\n  proc{foo11=22}.call\n  proc{foo22=55}.call\n  test_ok(eval(\"foo11\", p) == eval(\"foo11\"))\n  test_ok(eval(\"foo11\") == 1)\n  test_ok(eval(\"foo22\", p) == eval(\"foo22\"))\n  test_ok(eval(\"foo22\") == 55)\n}.call\n\np1 = proc{i7 = 0; proc{i7}}.call\ntest_ok(p1.call == 0)\neval \"i7=5\", p1\ntest_ok(p1.call == 5)\ntest_ok(!defined?(i7))\n\np1 = proc{i7 = 0; proc{i7}}.call\ni7 = nil\ntest_ok(p1.call == 0)\neval \"i7=1\", p1\ntest_ok(p1.call == 1)\neval \"i7=5\", p1\ntest_ok(p1.call == 5)\ntest_ok(i7 == nil)\n\ntest_check \"system\"\ntest_ok(`echo foobar` == \"foobar\\n\")\ntest_ok(`./miniruby -e 'print \"foobar\"'` == 'foobar')\n\ntmp = open(\"script_tmp\", \"w\")\ntmp.print \"print $zzz\\n\";\ntmp.close\n\ntest_ok(`./miniruby -s script_tmp -zzz` == 'true')\ntest_ok(`./miniruby -s script_tmp -zzz=555` == '555')\n\ntmp = open(\"script_tmp\", \"w\")\ntmp.print \"#! /usr/local/bin/ruby -s\\n\";\ntmp.print \"print $zzz\\n\";\ntmp.close\n\ntest_ok(`./miniruby script_tmp -zzz=678` == '678')\n\ntmp = open(\"script_tmp\", \"w\")\ntmp.print \"this is a leading junk\\n\";\ntmp.print \"#! /usr/local/bin/ruby -s\\n\";\ntmp.print \"print $zzz\\n\";\ntmp.print \"__END__\\n\";\ntmp.print \"this is a trailing junk\\n\";\ntmp.close\n\ntest_ok(`./miniruby -x script_tmp` == 'nil')\ntest_ok(`./miniruby -x script_tmp -zzz=555` == '555')\n\ntmp = open(\"script_tmp\", \"w\")\nfor i in 1..5\n  tmp.print i, \"\\n\"\nend\ntmp.close\n\n`./miniruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp`\ndone = true\ntmp = open(\"script_tmp\", \"r\")\nwhile tmp.gets\n  if $_.to_i % 5 != 0\n    done = false\n    break\n  end\nend\ntmp.close\ntest_ok(done)\n  \nFile.unlink \"script_tmp\" or `/bin/rm -f \"script_tmp\"`\nFile.unlink \"script_tmp.bak\" or `/bin/rm -f \"script_tmp.bak\"`\n\n$bad = false\nif (dir = File.dirname(File.dirname($0))) == '.'\n  dir = \"\"\nelse\n  dir << \"/\"\nend\n\ndef valid_syntax?(code, fname)\n  code = code.sub(/\\A(?:\\s*\\#.*$)*(\\n)?/n) {\n    \"#$&#{\"\\n\" if $1 && !$2}BEGIN{return true}\\n\"\n  }\n  eval(code, nil, fname, 0)\nrescue Exception\n  puts $!.message\n  false\nend\n\nfor script in Dir[\"#{dir}{lib,sample,ext}/**/*.rb\"]\n  unless valid_syntax? IO::read(script), script\n    $bad = true\n  end\nend\ntest_ok(!$bad)\n\ntest_check \"const\"\nTEST1 = 1\nTEST2 = 2\n\nmodule Const\n  TEST3 = 3\n  TEST4 = 4\nend\n\nmodule Const2\n  TEST3 = 6\n  TEST4 = 8\nend\n\ninclude Const\n\ntest_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,3,4])\n\ninclude Const2\nSTDERR.print \"intentionally redefines TEST3, TEST4\\n\" if $VERBOSE\ntest_ok([TEST1,TEST2,TEST3,TEST4] == [1,2,6,8])\n\n\ntest_ok((String <=> Object) == -1)\ntest_ok((Object <=> String) == 1)\ntest_ok((Array <=> String) == nil)\n\ntest_check \"clone\"\nfoo = Object.new\ndef foo.test\n  \"test\"\nend\nbar = foo.clone\ndef bar.test2\n  \"test2\"\nend\n\ntest_ok(bar.test2 == \"test2\")\ntest_ok(bar.test == \"test\")\ntest_ok(foo.test == \"test\")  \n\nbegin\n  foo.test2\n  test_ok false\nrescue NoMethodError\n  test_ok true\nend\n\nmodule M001; end\nmodule M002; end\nmodule M003; include M002; end\nmodule M002; include M001; end\nmodule M003; include M002; end\n\ntest_ok(M003.ancestors == [M003, M002, M001])\n\ntest_check \"marshal\"\n$x = [1,2,3,[4,5,\"foo\"],{1=>\"bar\"},2.5,fact(30)]\n$y = Marshal.dump($x)\ntest_ok($x == Marshal.load($y))\n\nStrClone=String.clone;\ntest_ok(Marshal.load(Marshal.dump(StrClone.new(\"abc\"))).class == StrClone)\n\n[[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|\n  a = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))\n  ma = Marshal.dump(a)\n  b = Marshal.load(ma)\n  test_ok(a == b)\n}\n\ntest_check \"pack\"\n\n$format = \"c2x5CCxsdils_l_a6\";\n# Need the expression in here to force ary[5] to be numeric.  This avoids\n# test2 failing because ary2 goes str->numeric->str and ary does not.\nary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,\"abcdef\"]\n$x = ary.pack($format)\nary2 = $x.unpack($format)\n\ntest_ok(ary.length == ary2.length)\ntest_ok(ary.join(':') == ary2.join(':'))\ntest_ok($x =~ /def/)\n\n$x = [-1073741825]\ntest_ok($x.pack(\"q\").unpack(\"q\") == $x)\n\ntest_check \"math\"\ntest_ok(Math.sqrt(4) == 2)\n\ninclude Math\ntest_ok(sqrt(4) == 2)\n\ntest_check \"struct\"\nstruct_test = Struct.new(\"Test\", :foo, :bar)\ntest_ok(struct_test == Struct::Test)\n\ntest = struct_test.new(1, 2)\ntest_ok(test.foo == 1 && test.bar == 2)\ntest_ok(test[0] == 1 && test[1] == 2)\n\na, b = test.to_a\ntest_ok(a == 1 && b == 2)\n\ntest[0] = 22\ntest_ok(test.foo == 22)\n\ntest.bar = 47\ntest_ok(test.bar == 47)\n\ntest_check \"variable\"\ntest_ok($$.instance_of?(Fixnum))\n\n# read-only variable\nbegin\n  $$ = 5\n  test_ok false\nrescue NameError\n  test_ok true\nend\n\nfoobar = \"foobar\"\n$_ = foobar\ntest_ok($_ == foobar)\n\nclass Gods\n  @@rule = \"Uranus\"\n  def ruler0\n    @@rule\n  end\n\n  def self.ruler1\t\t# <= per method definition style\n    @@rule\n  end\t\t   \n  class << self\t\t\t# <= multiple method definition style\n    def ruler2\n      @@rule\n    end\n  end\nend\n\nmodule Olympians\n @@rule =\"Zeus\"\n def ruler3\n    @@rule\n  end\nend\n\nclass Titans < Gods\n  @@rule = \"Cronus\"\n  include Olympians           \t# OK to cause warning (intentional)\nend\n\ntest_ok(Gods.new.ruler0 == \"Cronus\")\ntest_ok(Gods.ruler1 == \"Cronus\")\ntest_ok(Gods.ruler2 == \"Cronus\")\ntest_ok(Titans.ruler1 == \"Cronus\")\ntest_ok(Titans.ruler2 == \"Cronus\")\natlas = Titans.new\ntest_ok(atlas.ruler0 == \"Cronus\")\ntest_ok(atlas.ruler3 == \"Zeus\")\n\ntest_check \"trace\"\n$x = 1234\n$y = 0\ntrace_var :$x, proc{$y = $x}\n$x = 40414\ntest_ok($y == $x)\n\nuntrace_var :$x\n$x = 19660208\ntest_ok($y != $x)\n\ntrace_var :$x, proc{$x *= 2}\n$x = 5\ntest_ok($x == 10)\n\nuntrace_var :$x\n\ntest_check \"defined?\"\n\ntest_ok(defined?($x))\t\t# global variable\ntest_ok(defined?($x) == 'global-variable')# returns description\n\nfoo=5\ntest_ok(defined?(foo))\t\t# local variable\n\ntest_ok(defined?(Array))\t# constant\ntest_ok(defined?(Object.new))\t# method\ntest_ok(!defined?(Object.print))# private method\ntest_ok(defined?(1 == 2))\t# operator expression\n\nclass Foo\n  def foo\n    p :foo\n  end\n  protected :foo\n  def bar(f)\n    test_ok(defined?(self.foo))\n    test_ok(defined?(f.foo))\n  end\nend\nf = Foo.new\ntest_ok(defined?(f.foo) == nil)\nf.bar(f)\n\ndef defined_test\n  return !defined?(yield)\nend\n\ntest_ok(defined_test)\t\t# not iterator\ntest_ok(!defined_test{})\t# called as iterator\n\ntest_check \"alias\"\nclass Alias0\n  def foo; \"foo\" end\nend\nclass Alias1<Alias0\n  alias bar foo\n  def foo; \"foo+\" + super end\nend\nclass Alias2<Alias1\n  alias baz foo\n  undef foo\nend\n\nx = Alias2.new\ntest_ok(x.bar == \"foo\")\ntest_ok(x.baz == \"foo+foo\")\n\n# test_check for cache\ntest_ok(x.baz == \"foo+foo\")\n\nclass Alias3<Alias2\n  def foo\n    defined? super\n  end\n  def bar\n    defined? super\n  end\n  def quux\n    defined? super\n  end\nend\nx = Alias3.new\ntest_ok(!x.foo)\ntest_ok(x.bar)\ntest_ok(!x.quux)\n\ntest_check \"path\"\ntest_ok(File.basename(\"a\") == \"a\")\ntest_ok(File.basename(\"a/b\") == \"b\")\ntest_ok(File.basename(\"a/b/\") == \"b\")\ntest_ok(File.basename(\"/\") == \"/\")\ntest_ok(File.basename(\"//\") == \"/\")\ntest_ok(File.basename(\"///\") == \"/\")\ntest_ok(File.basename(\"a/b////\") == \"b\")\ntest_ok(File.basename(\"a.rb\", \".rb\") == \"a\")\ntest_ok(File.basename(\"a.rb///\", \".rb\") == \"a\")\ntest_ok(File.basename(\"a.rb///\", \".*\") == \"a\")\ntest_ok(File.basename(\"a.rb///\", \".c\") == \"a.rb\")\ntest_ok(File.dirname(\"a\") == \".\")\ntest_ok(File.dirname(\"/\") == \"/\")\ntest_ok(File.dirname(\"/a\") == \"/\")\ntest_ok(File.dirname(\"a/b\") == \"a\")\ntest_ok(File.dirname(\"a/b/c\") == \"a/b\")\ntest_ok(File.dirname(\"/a/b/c\") == \"/a/b\")\ntest_ok(File.dirname(\"/a/b/\") == \"/a\")\ntest_ok(File.dirname(\"/a/b///\") == \"/a\")\ncase Dir.pwd\nwhen %r'\\A\\w:'\n  test_ok(/\\A\\w:\\/\\z/ =~ File.expand_path(\".\", \"/\"))\n  test_ok(/\\A\\w:\\/a\\z/ =~ File.expand_path(\"a\", \"/\"))\n  dosish = true\nwhen %r'\\A//'\n  test_ok(%r'\\A//[^/]+/[^/]+\\z' =~ File.expand_path(\".\", \"/\"))\n  test_ok(%r'\\A//[^/]+/[^/]+/a\\z' =~ File.expand_path(\".\", \"/\"))\n  dosish = true\nelse\n  test_ok(File.expand_path(\".\", \"/\") == \"/\")\n  test_ok(File.expand_path(\"sub\", \"/\") == \"/sub\")\nend\nif dosish\n  test_ok(File.expand_path(\"/\", \"//machine/share/sub\") == \"//machine/share\")\n  test_ok(File.expand_path(\"/dir\", \"//machine/share/sub\") == \"//machine/share/dir\")\n  test_ok(File.expand_path(\"/\", \"z:/sub\") == \"z:/\")\n  test_ok(File.expand_path(\"/dir\", \"z:/sub\") == \"z:/dir\")\nend\ntest_ok(File.expand_path(\".\", \"//\") == \"//\")\ntest_ok(File.expand_path(\"sub\", \"//\") == \"//sub\")\n\ntest_check \"gc\"\nbegin\n  1.upto(10000) {\n    tmp = [0,1,2,3,4,5,6,7,8,9]\n  }\n  tmp = nil\n  test_ok true\nrescue\n  test_ok false\nend\nclass S\n  def initialize(a)\n    @a = a\n  end\nend\nl=nil\n100000.times {\n  l = S.new(l)\n}\nGC.start\ntest_ok true   # reach here or dumps core\nl = []\n100000.times {\n  l.push([l])\n}\nGC.start\ntest_ok true   # reach here or dumps core\n\nif $failed > 0\n  printf \"test: %d failed %d\\n\", $ntest, $failed\nelse\n  printf \"end of test(test: %d)\\n\", $ntest\nend\n"
  },
  {
    "path": "sample/testunit/adder.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nclass Adder\n  def initialize(number)\n    @number = number\n  end\n  def add(number)\n    return @number + number\n  end\nend\n\n"
  },
  {
    "path": "sample/testunit/subtracter.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nclass Subtracter\n  def initialize(number)\n    @number = number\n  end\n  def subtract(number)\n    return @number - number\n  end\nend\n"
  },
  {
    "path": "sample/testunit/tc_adder.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'adder'\n\nclass TC_Adder < Test::Unit::TestCase\n  def setup\n    @adder = Adder.new(5)\n  end\n  def test_add\n    assert_equal(7, @adder.add(2), \"Should have added correctly\")\n  end\n  def teardown\n    @adder = nil\n  end\nend\n"
  },
  {
    "path": "sample/testunit/tc_subtracter.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'subtracter'\n\nclass TC_Subtracter < Test::Unit::TestCase\n  def setup\n    @subtracter = Subtracter.new(5)\n  end\n  def test_subtract\n    assert_equal(3, @subtracter.subtract(2), \"Should have subtracted correctly\")\n  end\n  def teardown\n    @subtracter = nil\n  end\nend\n"
  },
  {
    "path": "sample/testunit/ts_examples.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'tc_adder'\nrequire 'tc_subtracter'\n"
  },
  {
    "path": "sample/time.rb",
    "content": "#! /usr/bin/env ruby\n\nb = Time.now\nsystem(*ARGV)\ne = Time.now\n\ntms = Process.times\nreal = e - b\nuser = tms.cutime\nsys = tms.cstime\n\nSTDERR.printf(\"%11.1f real %11.1f user %11.1f sys\\n\", real, user, sys)\n"
  },
  {
    "path": "sample/trojan.rb",
    "content": "#! /usr/local/bin/ruby\n\npath = ENV['PATH'].split(File::PATH_SEPARATOR)\n\nfor dir in path\n  if File.directory?(dir)\n    for f in d = Dir.open(dir)\n      fpath = File.join(dir, f)  \n      if File.file?(fpath) && (File.stat(fpath).mode & 022) != 0\n\tprintf(\"file %s is writable from other users\\n\", fpath)\n      end\n    end\n    d.close\n  end\nend\n"
  },
  {
    "path": "sample/tsvr.rb",
    "content": "# socket example - server side using thread\n# usage: ruby tsvr.rb\n\nrequire \"socket\"\n\ngs = TCPserver.open(0)\naddr = gs.addr\naddr.shift\nprintf(\"server is on %s\\n\", addr.join(\":\"))\n\nloop do\n  Thread.start(gs.accept) do |s|\n    print(s, \" is accepted\\n\")\n    while line = s.gets\n      s.write(line)\n    end\n    print(s, \" is gone\\n\")\n    s.close\n  end\nend\n"
  },
  {
    "path": "sample/uumerge.rb",
    "content": "#!/usr/bin/env ruby\n\nif ARGV[0] == \"-c\"\n  out_stdout = 1\n  ARGV.shift\nend\n\n$sawbegin = 0\n$sawend = 0\n\nwhile line = gets()\n  if /^begin\\s*(\\d*)\\s*(\\S*)/ =~ line\n    $mode, $file = $1, $2\n    $sawbegin+=1\n    if out_stdout\n      out = STDOUT\n    else\n      out = open($file, \"w\") if $file != \"\"\n    end\n    out.binmode\n    break\n  end\nend\n\nraise \"missing begin\" unless $sawbegin\n\nout.binmode\nwhile line = gets()\n  if /^end/ =~ line\n    $sawend+=1\n    out.close unless out_stdout\n    File.chmod $mode.oct, $file unless out_stdout\n    next\n  end\n  line.sub!(/[a-z]+$/, \"\")\t# handle stupid trailing lowercase letters\n  next if /[a-z]/ =~ line\n  next if !(((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4)\n  out << $_.unpack(\"u\") if $sawbegin > $sawend\nend\n\nraise \"missing end\" if $sawbegin > $sawend\nraise \"missing begin\" if ! $sawbegin\nexit 0\n"
  },
  {
    "path": "sample/webrick/demo-app.rb",
    "content": "require \"pp\"\n\nmodule DemoApplication\n  def initialize(config, enctype)\n    super\n    @enctype = enctype\n  end\n\n  def do_GET(req, res)\n    if req.path_info != \"/\"\n      res.set_redirect(WEBrick::HTTPStatus::Found, req.script_name + \"/\")\n    end\n    res.body =<<-_end_of_html_\n      <HTML>\n       <FORM method=\"POST\" enctype=#{@enctype}>\n        text: <INPUT type=\"text\" name=\"text\"><BR>\n        file: <INPUT type=\"file\" name=\"file\"><BR>\n        check:\n        <INPUT type=\"checkbox\" name=\"check\" value=\"a\">a,\n        <INPUT type=\"checkbox\" name=\"check\" value=\"b\">b,\n        <INPUT type=\"checkbox\" name=\"check\" value=\"c\">c,\n        <BR>\n        <INPUT type=\"submit\">\n       </FORM>\n      </HTML>\n    _end_of_html_\n    res['content-type'] = 'text/html; charset=iso-8859-1'\n  end\n\n  def do_POST(req, res)\n    if req[\"content-length\"].to_i > 1024*10\n      raise WEBrick::HTTPStatus::Forbidden, \"file size too large\"\n    end\n    res.body =<<-_end_of_html_\n      <HTML>\n       <H2>Query Parameters</H2>\n       #{display_query(req.query)}\n       <A href=\"#{req.path}\">return</A>\n       <H2>Request</H2>\n       <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(req, \"\", 80))}</PRE>\n       <H2>Response</H2>\n       <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(res, \"\", 80))}</PRE>\n      </HTML>\n    _end_of_html_\n    res['content-type'] = 'text/html; charset=iso-8859-1'\n  end\n\n  private\n\n  def display_query(q)\n    ret = \"\"\n    q.each{|key, val|\n      ret << \"<H3>#{WEBrick::HTMLUtils::escape(key)}</H3>\"\n      ret << \"<TABLE border=1>\"\n      ret << make_tr(\"val\", val.inspect)\n      ret << make_tr(\"val.to_a\", val.to_a.inspect)\n      ret << make_tr(\"val.to_ary\", val.to_ary.inspect)\n      ret << \"</TABLE>\"\n    }\n    ret\n  end\n\n  def make_tr(arg0, arg1)\n    \"<TR><TD>#{arg0}</TD><TD>#{WEBrick::HTMLUtils::escape(arg1)}</TD></TR>\"\n  end\nend\n"
  },
  {
    "path": "sample/webrick/demo-multipart.cgi",
    "content": "#!/usr/bin/env ruby\nrequire \"webrick/cgi\"\nrequire \"webrick/https\" # should load if it runs on HTTPS server\nrequire \"./demo-app\"\n\nclass DemoCGI < WEBrick::CGI\n  include DemoApplication\nend\n\nconfig = { :NPH => false }\ncgi = DemoCGI.new(config, \"multipart/form-data\")\ncgi.start\n"
  },
  {
    "path": "sample/webrick/demo-servlet.rb",
    "content": "require \"webrick\"\nrequire \"./demo-app\"\n\nclass DemoServlet < WEBrick::HTTPServlet::AbstractServlet\n  include DemoApplication\nend\n"
  },
  {
    "path": "sample/webrick/demo-urlencoded.cgi",
    "content": "#!/usr/bin/env ruby\nrequire \"webrick/cgi\"\nrequire \"webrick/https\"  # should load if it runs on HTTPS server \nrequire \"./demo-app\"\n\nclass DemoCGI < WEBrick::CGI\n  include DemoApplication\nend\n\nconfig = { :NPH => false } \ncgi = DemoCGI.new(config, \"application/x-www-form-urlencoded\")\ncgi.start\n"
  },
  {
    "path": "sample/webrick/hello.cgi",
    "content": "#!/usr/bin/env ruby\nrequire \"webrick/cgi\"\n\nclass HelloCGI < WEBrick::CGI\n  def do_GET(req, res)\n    res[\"content-type\"] = \"text/plain\"\n    res.body = \"Hello, world.\\n\"\n  end\nend\n\nHelloCGI.new.start\n"
  },
  {
    "path": "sample/webrick/hello.rb",
    "content": "require \"webrick\"\n\nclass HelloServlet < WEBrick::HTTPServlet::AbstractServlet\n  def do_GET(req, res)\n    res[\"content-type\"] = \"text/plain\"\n    res.body = \"Hello, world.\\n\"\n  end\nend\n"
  },
  {
    "path": "sample/webrick/httpd.rb",
    "content": "require \"webrick\"\n\nhttpd = WEBrick::HTTPServer.new(\n  :DocumentRoot => File::dirname(__FILE__),\n  :Port         => 10080,\n  :Logger       => WEBrick::Log.new($stderr, WEBrick::Log::DEBUG),\n  :AccessLog    => [\n    [ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT  ],\n    [ $stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT ],\n    [ $stderr, WEBrick::AccessLog::AGENT_LOG_FORMAT   ],\n  ],\n  :CGIPathEnv   => ENV[\"PATH\"]   # PATH environment variable for CGI.\n)\n\nrequire \"./hello\"\nhttpd.mount(\"/hello\", HelloServlet)\n\nrequire \"./demo-servlet\"\nhttpd.mount(\"/urlencoded\", DemoServlet, \"application/x-www-form-urlencoded\")\nhttpd.mount(\"/multipart\", DemoServlet, \"multipart/form-data\")\n\ntrap(:INT){ httpd.shutdown }\nhttpd.start\n"
  },
  {
    "path": "sample/webrick/httpproxy.rb",
    "content": "require \"webrick\"\nrequire \"webrick/httpproxy\"\n\n# :ProxyContentHandler will be invoked before sending\n# response to User-Agenge. You can inspect the pair of\n# request and response messages (or can edit the response\n# message if necessary).\n\npch = Proc.new{|req, res|\n  p [ req.request_line, res.status_line ]\n}\n\ndef upstream_proxy\n  if prx = ENV[\"http_proxy\"]\n    return URI.parse(prx)\n  end\n  return nil\nend\n\nhttpd = WEBrick::HTTPProxyServer.new(\n  :Port     => 10080,\n  :ProxyContentHandler => pch,\n  :ProxyURI => upstream_proxy\n)\nSignal.trap(:INT){ httpd.shutdown }\nhttpd.start\n"
  },
  {
    "path": "sample/webrick/httpsd.rb",
    "content": "require \"webrick\"\nrequire \"webrick/https\"\n\nhostname = WEBrick::Utils::getservername\nsubject = [[\"O\", \"ruby-lang.org\"], [\"OU\", \"sample\"], [\"CN\", hostname]]\ncomment = \"Comment for self-signed certificate\"\n\nhttpd = WEBrick::HTTPServer.new(\n  :DocumentRoot   => File::dirname(__FILE__),\n  :Port           => 10443,\n  :SSLEnable      => true,\n\n  # Specify key pair and server certificate.\n  # :SSLPrivateKey  => OpenSSL::PKey::RSA.new(File.read(\"server.key\")),\n  # :SSLCertificate => OpenSSL::X509::Certificate.new(File.read(\"server.crt\")),\n\n  # specify the following SSL options if you want to use auto\n  # generated self-signed certificate.\n  :SSLCertName    => subject,\n  :SSLComment     => comment,\n\n  :CGIPathEnv     => ENV[\"PATH\"]  # PATH environment variable for CGI.\n)\n\nrequire \"./hello\"\nhttpd.mount(\"/hello\", HelloServlet)\n\nrequire \"./demo-servlet\"\nhttpd.mount(\"/urlencoded\", DemoServlet, \"application/x-www-form-urlencoded\")\nhttpd.mount(\"/multipart\", DemoServlet, \"multipart/form-data\")\n\ntrap(:INT){ httpd.shutdown }\nhttpd.start\n"
  },
  {
    "path": "signal.c",
    "content": "/**********************************************************************\n\n  signal.c -\n\n  $Author$\n  $Date$\n  created at: Tue Dec 20 10:13:44 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n#include \"node.h\"\n#include <signal.h>\n#include <stdio.h>\n#include <ucontext.h>\n\n#ifdef HAVE_SYS_PARAM_H\n#include <sys/param.h>\n#endif\n\n#ifdef __BEOS__\n#undef SIGBUS\n#endif\n\n#if defined HAVE_SIGPROCMASK || defined HAVE_SIGSETMASK\n#define USE_TRAP_MASK 1\n#else\n#define USE_TRAP_MASK 0\n#endif\n\n#ifndef NSIG\n# ifdef DJGPP\n#  define NSIG SIGMAX\n# else\n#  define NSIG (_SIGMAX + 1)      /* For QNX */\n# endif\n#endif\n\nstatic struct signals {\n    const char *signm;\n    int  signo;\n} siglist [] = {\n    {\"EXIT\", 0},\n#ifdef SIGHUP\n    {\"HUP\", SIGHUP},\n#endif\n    {\"INT\", SIGINT},\n#ifdef SIGQUIT\n    {\"QUIT\", SIGQUIT},\n#endif\n#ifdef SIGILL\n    {\"ILL\", SIGILL},\n#endif\n#ifdef SIGTRAP\n    {\"TRAP\", SIGTRAP},\n#endif\n#ifdef SIGIOT\n    {\"IOT\", SIGIOT},\n#endif\n#ifdef SIGABRT\n    {\"ABRT\", SIGABRT},\n#endif\n#ifdef SIGEMT\n    {\"EMT\", SIGEMT},\n#endif\n#ifdef SIGFPE\n    {\"FPE\", SIGFPE},\n#endif\n#ifdef SIGKILL\n    {\"KILL\", SIGKILL},\n#endif\n#ifdef SIGBUS\n    {\"BUS\", SIGBUS},\n#endif\n#ifdef SIGSEGV\n    {\"SEGV\", SIGSEGV},\n#endif\n#ifdef SIGSYS\n    {\"SYS\", SIGSYS},\n#endif\n#ifdef SIGPIPE\n    {\"PIPE\", SIGPIPE},\n#endif\n#ifdef SIGALRM\n    {\"ALRM\", SIGALRM},\n#endif\n#ifdef SIGTERM\n    {\"TERM\", SIGTERM},\n#endif\n#ifdef SIGURG\n    {\"URG\", SIGURG},\n#endif\n#ifdef SIGSTOP\n    {\"STOP\", SIGSTOP},\n#endif\n#ifdef SIGTSTP\n    {\"TSTP\", SIGTSTP},\n#endif\n#ifdef SIGCONT\n    {\"CONT\", SIGCONT},\n#endif\n#ifdef SIGCHLD\n    {\"CHLD\", SIGCHLD},\n#endif\n#ifdef SIGCLD\n    {\"CLD\", SIGCLD},\n#else\n# ifdef SIGCHLD\n    {\"CLD\", SIGCHLD},\n# endif\n#endif\n#ifdef SIGTTIN\n    {\"TTIN\", SIGTTIN},\n#endif\n#ifdef SIGTTOU\n    {\"TTOU\", SIGTTOU},\n#endif\n#ifdef SIGIO\n    {\"IO\", SIGIO},\n#endif\n#ifdef SIGXCPU\n    {\"XCPU\", SIGXCPU},\n#endif\n#ifdef SIGXFSZ\n    {\"XFSZ\", SIGXFSZ},\n#endif\n#ifdef SIGVTALRM\n    {\"VTALRM\", SIGVTALRM},\n#endif\n#ifdef SIGPROF\n    {\"PROF\", SIGPROF},\n#endif\n#ifdef SIGWINCH\n    {\"WINCH\", SIGWINCH},\n#endif\n#ifdef SIGUSR1\n    {\"USR1\", SIGUSR1},\n#endif\n#ifdef SIGUSR2\n    {\"USR2\", SIGUSR2},\n#endif\n#ifdef SIGLOST\n    {\"LOST\", SIGLOST},\n#endif\n#ifdef SIGMSG\n    {\"MSG\", SIGMSG},\n#endif\n#ifdef SIGPWR\n    {\"PWR\", SIGPWR},\n#endif\n#ifdef SIGPOLL\n    {\"POLL\", SIGPOLL},\n#endif\n#ifdef SIGDANGER\n    {\"DANGER\", SIGDANGER},\n#endif\n#ifdef SIGMIGRATE\n    {\"MIGRATE\", SIGMIGRATE},\n#endif\n#ifdef SIGPRE\n    {\"PRE\", SIGPRE},\n#endif\n#ifdef SIGGRANT\n    {\"GRANT\", SIGGRANT},\n#endif\n#ifdef SIGRETRACT\n    {\"RETRACT\", SIGRETRACT},\n#endif\n#ifdef SIGSOUND\n    {\"SOUND\", SIGSOUND},\n#endif\n#ifdef SIGINFO\n    {\"INFO\", SIGINFO},\n#endif\n    {NULL, 0}\n};\n\nstatic int\nsignm2signo(nm)\n    const char *nm;\n{\n    struct signals *sigs;\n\n    for (sigs = siglist; sigs->signm; sigs++)\n\tif (strcmp(sigs->signm, nm) == 0)\n\t    return sigs->signo;\n    return 0;\n}\n\nstatic const char*\nsigno2signm(no)\n    int no;\n{\n    struct signals *sigs;\n\n    for (sigs = siglist; sigs->signm; sigs++)\n\tif (sigs->signo == no)\n\t    return sigs->signm;\n    return 0;\n}\n\nconst char *\nruby_signal_name(no)\n    int no;\n{\n    return signo2signm(no);\n}\n\n/*\n * call-seq:\n *    SignalException.new(sig)   =>  signal_exception\n *\n *  Construct a new SignalException object.  +sig+ should be a known\n *  signal name, or a signal number.\n */\n\nstatic VALUE\nesignal_init(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    int argnum = 1;\n    VALUE sig = Qnil;\n    int signo;\n    const char *signm;\n    char tmpnm[(sizeof(int)*CHAR_BIT)/3+4];\n\n    if (argc > 0) {\n\tsig = argv[0];\n\tif (FIXNUM_P(sig)) argnum = 2;\n    }\n    if (argc < 1 || argnum < argc) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for %d)\",\n\t\t argc, argnum);\n    }\n    if (argnum == 2) {\n\tsigno = FIX2INT(sig);\n\tif (signo < 0 || signo > NSIG) {\n\t    rb_raise(rb_eArgError, \"invalid signal number (%d)\", signo);\n\t}\n\tif (argc > 1) {\n\t    sig = argv[1];\n\t}\n\telse {\n\t    signm = signo2signm(signo);\n\t    if (signm) {\n\t\tsnprintf(tmpnm, sizeof(tmpnm), \"SIG%s\", signm);\n\t    }\n\t    else {\n\t\tsnprintf(tmpnm, sizeof(tmpnm), \"SIG%u\", signo);\n\t    }\n\t    sig = rb_str_new2(signm = tmpnm);\n\t}\n    }\n    else {\n\tsignm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig);\n\tif (strncmp(signm, \"SIG\", 3) == 0) signm += 3;\n\tsigno = signm2signo(signm);\n\tif (!signo) {\n\t    rb_raise(rb_eArgError, \"unsupported name `SIG%s'\", signm);\n\t}\n\tif (SYMBOL_P(sig)) {\n\t    sig = rb_str_new2(signm);\n\t}\n    }\n    rb_call_super(1, &sig);\n    rb_iv_set(self, \"signo\", INT2NUM(signo));\n\n    return self;\n}\n\nstatic VALUE\ninterrupt_init(argc, argv, self)\n    int argc;\n    VALUE *argv;\n    VALUE self;\n{\n    VALUE args[2];\n\n    args[0] = INT2FIX(SIGINT);\n    rb_scan_args(argc, argv, \"01\", &args[1]);\n\n    return rb_call_super(2, args);\n}\n\nvoid\nruby_default_signal(sig)\n    int sig;\n{\n#ifndef MACOS_UNUSE_SIGNAL\n    extern rb_pid_t getpid _((void));\n\n    signal(sig, SIG_DFL);\n    kill(getpid(), sig);\n#endif\n}\n\n/*\n *  call-seq:\n *     Process.kill(signal, pid, ...)    => fixnum\n *  \n *  Sends the given signal to the specified process id(s), or to the\n *  current process if _pid_ is zero. _signal_ may be an\n *  integer signal number or a POSIX signal name (either with or without\n *  a +SIG+ prefix). If _signal_ is negative (or starts\n *  with a minus sign), kills process groups instead of\n *  processes. Not all signals are available on all platforms.\n *     \n *     pid = fork do\n *        Signal.trap(\"HUP\") { puts \"Ouch!\"; exit }\n *        # ... do some work ...\n *     end\n *     # ...\n *     Process.kill(\"HUP\", pid)\n *     Process.wait\n *     \n *  <em>produces:</em>\n *     \n *     Ouch!\n */\n\nVALUE\nrb_f_kill(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    int negative = 0;\n    int sig;\n    int i;\n    const char *s;\n\n    rb_secure(2);\n    if (argc < 2)\n\trb_raise(rb_eArgError, \"wrong number of arguments -- kill(sig, pid...)\");\n    switch (TYPE(argv[0])) {\n      case T_FIXNUM:\n\tsig = FIX2INT(argv[0]);\n\tbreak;\n\n      case T_SYMBOL:\n\ts = rb_id2name(SYM2ID(argv[0]));\n\tif (!s) rb_raise(rb_eArgError, \"bad signal\");\n\tgoto str_signal;\n\n      case T_STRING:\n\ts = RSTRING(argv[0])->ptr;\n\tif (s[0] == '-') {\n\t    negative++;\n\t    s++;\n\t}\n      str_signal:\n\tif (strncmp(\"SIG\", s, 3) == 0)\n\t    s += 3;\n\tif((sig = signm2signo(s)) == 0)\n\t    rb_raise(rb_eArgError, \"unsupported name `SIG%s'\", s);\n\n\tif (negative)\n\t    sig = -sig;\n\tbreak;\n\n      default:\n        {\n\t    VALUE str;\n\n\t    str = rb_check_string_type(argv[0]);\n\t    if (!NIL_P(str)) {\n\t\ts = RSTRING(str)->ptr;\n\t\tgoto str_signal;\n\t    }\n\t    rb_raise(rb_eArgError, \"bad signal type %s\",\n\t\t     rb_obj_classname(argv[0]));\n\t}\n\tbreak;\n    }\n\n    if (sig < 0) {\n\tsig = -sig;\n\tfor (i=1; i<argc; i++) {\n\t    int pid = NUM2INT(argv[i]);\n#ifdef HAS_KILLPG\n\t    if (killpg(pid, sig) < 0)\n#else\n\t    if (kill(-pid, sig) < 0)\n#endif\n\t\trb_sys_fail(0);\n\t}\n    }\n    else {\n\tfor (i=1; i<argc; i++) {\n\t    Check_Type(argv[i], T_FIXNUM);\n\t    if (kill(FIX2INT(argv[i]), sig) < 0)\n\t\trb_sys_fail(0);\n\t}\n    }\n    return INT2FIX(i-1);\n}\n\nstatic struct {\n    VALUE cmd;\n    int safe;\n} trap_list[NSIG];\nstatic rb_atomic_t trap_pending_list[NSIG];\nstatic char rb_trap_accept_nativethreads[NSIG];\nrb_atomic_t rb_trap_pending;\nrb_atomic_t rb_trap_immediate;\nint rb_prohibit_interrupt = 1;\n\nvoid\nrb_gc_mark_trap_list()\n{\n#ifndef MACOS_UNUSE_SIGNAL\n    int i;\n\n    for (i=0; i<NSIG; i++) {\n\tif (trap_list[i].cmd)\n\t    rb_gc_mark(trap_list[i].cmd);\n    }\n#endif /* MACOS_UNUSE_SIGNAL */\n}\n\n#ifdef __dietlibc__\n#define sighandler_t sh_t\n#endif\n\ntypedef RETSIGTYPE (*sighandler_t)_((int));\n\n#ifdef POSIX_SIGNAL\nstatic sighandler_t\nruby_signal(signum, handler)\n    int signum;\n    void *handler;\n{\n    struct sigaction sigact, old;\n\n    rb_trap_accept_nativethreads[signum] = 0;\n\n    if (signum == SIGSEGV || signum == SIGBUS) {\n      sigact.sa_sigaction = handler;\n      sigact.sa_flags = (SA_ONSTACK | SA_RESETHAND | SA_SIGINFO);\n    } else {\n      sigact.sa_handler = handler;\n      sigact.sa_flags = 0;\n    }\n\n    sigemptyset(&sigact.sa_mask);\n\n# ifdef SA_NOCLDWAIT\n    if (signum == SIGCHLD && handler == SIG_IGN)\n\tsigact.sa_flags |= SA_NOCLDWAIT;\n# endif\n    sigaction(signum, &sigact, &old);\n    return old.sa_handler;\n}\n\nvoid\nposix_signal(signum, handler)\n    int signum;\n    sighandler_t handler;\n{\n    ruby_signal(signum, handler);\n}\n\n# ifdef HAVE_NATIVETHREAD\nstatic sighandler_t\nruby_nativethread_signal(signum, handler)\n    int signum;\n    sighandler_t handler;\n{\n    sighandler_t old;\n\n    old = ruby_signal(signum, handler);\n    rb_trap_accept_nativethreads[signum] = 1;\n    return old;\n}\n\nvoid\nposix_nativethread_signal(signum, handler)\n    int signum;\n    sighandler_t handler;\n{\n    ruby_nativethread_signal(signum, handler);\n}\n# endif\n\n#else /* !POSIX_SIGNAL */\n#define ruby_signal(sig,handler) (rb_trap_accept_nativethreads[sig] = 0, signal((sig),(handler)))\n\n# ifdef HAVE_NATIVETHREAD\nstatic sighandler_t\nruby_nativethread_signal(signum, handler)\n    int signum;\n    sighandler_t handler;\n{\n    sighandler_t old;\n\n    old = signal(signum, handler);\n    rb_trap_accept_nativethreads[signum] = 1;\n    return old;\n}\n# endif\n#endif /* POSIX_SIGNAL */\n\nstatic void signal_exec _((int sig));\nstatic void\nsignal_exec(sig)\n    int sig;\n{\n    if (trap_list[sig].cmd == 0) {\n\tswitch (sig) {\n\t  case SIGINT:\n\t    rb_thread_interrupt();\n\t    break;\n#ifdef SIGHUP\n\t  case SIGHUP:\n#endif\n#ifdef SIGQUIT\n\t  case SIGQUIT:\n#endif\n#ifdef SIGTERM\n\t  case SIGTERM:\n#endif\n#ifdef SIGALRM\n\t  case SIGALRM:\n#endif\n#ifdef SIGUSR1\n\t  case SIGUSR1:\n#endif\n#ifdef SIGUSR2\n\t  case SIGUSR2:\n#endif\n\t    rb_thread_signal_raise(sig);\n\t    break;\n\t}\n    }\n    else if (trap_list[sig].cmd == Qundef) {\n\trb_thread_signal_exit();\n    }\n    else {\n\trb_thread_trap_eval(trap_list[sig].cmd, sig, trap_list[sig].safe);\n    }\n}\n\n#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)\nstatic void\nsigsend_to_ruby_thread(int sig)\n{\n# ifdef HAVE_SIGPROCMASK\n    sigset_t mask, old_mask;\n# else\n    int mask, old_mask;\n# endif\n\n# ifdef HAVE_SIGPROCMASK\n    sigfillset(&mask);\n    sigprocmask(SIG_BLOCK, &mask, &old_mask);\n# else\n    mask = sigblock(~0);\n    sigsetmask(mask);\n# endif\n\n    ruby_native_thread_kill(sig);\n}\n#endif\n\nstatic RETSIGTYPE sighandler _((int));\nstatic RETSIGTYPE\nsighandler(sig)\n    int sig;\n{\n#ifdef _WIN32\n#define IN_MAIN_CONTEXT(f, a) (rb_w32_main_context(a, f) ? (void)0 : f(a))\n#else\n#define IN_MAIN_CONTEXT(f, a) f(a)\n#endif\n\n    if (sig >= NSIG) {\n\trb_bug(\"trap_handler: Bad signal %d\", sig);\n    }\n\n#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)\n    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {\n\tsigsend_to_ruby_thread(sig);\n\treturn;\n    }\n#endif\n\n#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)\n    if (rb_trap_accept_nativethreads[sig]) {\n\truby_nativethread_signal(sig, sighandler);\n    }\n    else {\n\truby_signal(sig, sighandler);\n    }\n#endif\n\n    if (trap_list[sig].cmd == 0 && ATOMIC_TEST(rb_trap_immediate)) {\n\tIN_MAIN_CONTEXT(signal_exec, sig);\n\tATOMIC_SET(rb_trap_immediate, 1);\n    }\n    else {\n\tATOMIC_INC(rb_trap_pending);\n\tATOMIC_INC(trap_pending_list[sig]);\n#ifdef _WIN32\n\trb_w32_interrupted();\n#endif\n    }\n}\n\n#include <stdio.h>\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n\nvoid\n#ifdef HAVE_STDARG_PROTOTYPES\nsig_printf(const char *fmt, ...)\n#else\n  sig_printf(fmt, va_alist)\n     const char *fmt;\n    va_dcl\n#endif\n{\n  char buf[BUFSIZ];\n  va_list args;\n  FILE *out = stderr;\n\n  va_init_list(args, fmt);\n  vfprintf(out, fmt, args);\n  va_end(args);\n  fprintf(out, \"\\n\");\n}\n\nstatic void\ndump_machine_state(uc)\n     ucontext_t *uc;\n{\n  const char *dump64 =\n    \" ----------------- Register state dump ----------------------\\n\"\n    \"rax = 0x%.16x  rbx    = 0x%.16x  rcx = 0x%.16x  rdx = 0x%.16x\\n\"\n    \"rdi = 0x%.16x  rsi    = 0x%.16x  rbp = 0x%.16x  rsp = 0x%.16x\\n\"\n    \"r8  = 0x%.16x  r9     = 0x%.16x  r10 = 0x%.16x  r11 = 0x%.16x\\n\"\n    \"r12 = 0x%.16x  r13    = 0x%.16x  r14 = 0x%.16x  r15 = 0x%.16x\\n\"\n    \"rip = 0x%.16x  rflags = 0x%.16x  cs  = 0x%.16x  fs  = 0x%.16x\\n\"\n    \"gs  = 0x%.16x\";\n\n  const char *dump32 =\n    \" ----------------- Register state dump -------------------\\n\"\n    \"eax = 0x%.8x  ebx    = 0x%.8x  ecx = 0x%.8x  edx = 0x%.8x\\n\"\n    \"edi = 0x%.8x  esi    = 0x%.8x  ebp = 0x%.8x  esp = 0x%.8x\\n\"\n    \"ss  = 0x%.8x  eflags = 0x%.8x  eip = 0x%.8x  cs  = 0x%.8x\\n\"\n    \"ds  = 0x%.8x  es     = 0x%.8x  fs  = 0x%.8x  gs  = 0x%.8x\\n\";\n\n#if defined(__LP64__) && defined(__APPLE__)\n  sig_printf(dump64, uc->uc_mcontext->__ss.__rax, uc->uc_mcontext->__ss.__rbx,\n\t     uc->uc_mcontext->__ss.__rcx, uc->uc_mcontext->__ss.__rdx, uc->uc_mcontext->__ss.__rdi,\n\t     uc->uc_mcontext->__ss.__rsi, uc->uc_mcontext->__ss.__rbp, uc->uc_mcontext->__ss.__rsp,\n\t     uc->uc_mcontext->__ss.__r8, uc->uc_mcontext->__ss.__r9, uc->uc_mcontext->__ss.__r10,\n\t     uc->uc_mcontext->__ss.__r11, uc->uc_mcontext->__ss.__r12, uc->uc_mcontext->__ss.__r13,\n\t     uc->uc_mcontext->__ss.__r14, uc->uc_mcontext->__ss.__r15, uc->uc_mcontext->__ss.__rip,\n\t     uc->uc_mcontext->__ss.__rflags, uc->uc_mcontext->__ss.__cs, uc->uc_mcontext->__ss.__fs,\n\t     uc->uc_mcontext->__ss.__gs);\n#elif !defined(__LP64__) && defined(__APPLE__)\n  sig_printf(dump32, uc->uc_mcontext->__ss.__eax, uc->uc_mcontext->__ss.__ebx,\n\t     uc->uc_mcontext->__ss.__ecx, uc->uc_mcontext->__ss.__edx,\n\t     uc->uc_mcontext->__ss.__edi, uc->uc_mcontext->__ss.__esi,\n\t     uc->uc_mcontext->__ss.__ebp, uc->uc_mcontext->__ss.__esp,\n\t     uc->uc_mcontext->__ss.__ss, uc->uc_mcontext->__ss.__eflags,\n\t     uc->uc_mcontext->__ss.__eip, uc->uc_mcontext->__ss.__cs,\n\t     uc->uc_mcontext->__ss.__ds, uc->uc_mcontext->__ss.__es,\n\t     uc->uc_mcontext->__ss.__fs, uc->uc_mcontext->__ss.__gs);\n#elif defined(__x86_64__) && defined(BSD)\n  sig_printf(dump64, uc->uc_mcontext.mc_rax, uc->uc_mcontext.mc_rbx,\n\t     uc->uc_mcontext.mc_rcx, uc->uc_mcontext.mc_rdx, uc->uc_mcontext.mc_rdi,\n\t     uc->uc_mcontext.mc_rsi, uc->uc_mcontext.mc_rbp, uc->uc_mcontext.mc_rsp,\n\t     uc->uc_mcontext.mc_r8, uc->uc_mcontext.mc_r9, uc->uc_mcontext.mc_r10,\n\t     uc->uc_mcontext.mc_r11, uc->uc_mcontext.mc_r12, uc->uc_mcontext.mc_r13,\n\t     uc->uc_mcontext.mc_r14, uc->uc_mcontext.mc_r15, uc->uc_mcontext.mc_rip,\n\t     uc->uc_mcontext.mc_rflags, uc->uc_mcontext.mc_cs, uc->uc_mcontext.mc_fs,\n\t     uc->uc_mcontext.mc_gs);\n#elif defined(__i386__)\n  sig_printf(dump32, uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX],\n\t     uc->uc_mcontext.gregs[REG_ECX], uc->uc_mcontext.gregs[REG_EDX],\n\t     uc->uc_mcontext.gregs[REG_EDI], uc->uc_mcontext.gregs[REG_ESI],\n\t     uc->uc_mcontext.gregs[REG_EBP], uc->uc_mcontext.gregs[REG_ESP],\n\t     uc->uc_mcontext.gregs[REG_SS], uc->uc_mcontext.gregs[REG_EFL],\n\t     uc->uc_mcontext.gregs[REG_EIP], uc->uc_mcontext.gregs[REG_EIP],\n\t     uc->uc_mcontext.gregs[REG_DS], uc->uc_mcontext.gregs[REG_ES],\n\t     uc->uc_mcontext.gregs[REG_FS], uc->uc_mcontext.gregs[REG_FS]);\n#elif defined(__x86_64__)\n  sig_printf(dump64, uc->uc_mcontext.gregs[REG_RAX], uc->uc_mcontext.gregs[REG_RBX],\n\t     uc->uc_mcontext.gregs[REG_RCX], uc->uc_mcontext.gregs[REG_RDX],\n\t     uc->uc_mcontext.gregs[REG_RDI], uc->uc_mcontext.gregs[REG_RSI],\n\t     uc->uc_mcontext.gregs[REG_RBP], uc->uc_mcontext.gregs[REG_RSP],\n\t     uc->uc_mcontext.gregs[REG_R8], uc->uc_mcontext.gregs[REG_R9],\n\t     uc->uc_mcontext.gregs[REG_R10], uc->uc_mcontext.gregs[REG_R11],\n\t     uc->uc_mcontext.gregs[REG_R12], uc->uc_mcontext.gregs[REG_R13],\n\t     uc->uc_mcontext.gregs[REG_R14], uc->uc_mcontext.gregs[REG_R15],\n\t     uc->uc_mcontext.gregs[REG_RIP], uc->uc_mcontext.gregs[REG_EFL],\n\t     uc->uc_mcontext.gregs[REG_CSGSFS]);\n#else\n#endif\n}\n\nstatic int\ncheck_guard(caddr_t fault_addr, rb_thread_t th) {\n  if(fault_addr <= (caddr_t)rb_curr_thread->guard &&\n     fault_addr >= (caddr_t)rb_curr_thread->stk_ptr) {\n    return 1;\n  }\n  return 0;\n}\n\n#ifdef SIGBUS\n#ifdef POSIX_SIGNAL\nstatic void sigbus _((int, siginfo_t*, void*));\nstatic void\nsigbus(sig, ip, context)\n     int sig;\n     siginfo_t *ip;\n     void *context;\n{\n#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)\n  if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {\n    sigsend_to_ruby_thread(sig);\n    return;\n  }\n#endif\n\n  dump_machine_state(context);\n  if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) {\n    /* we hit the guard page, print out a warning to help app developers */\n    rb_bug(\"Thread stack overflow! Try increasing it!\");\n  } else {\n    rb_bug(\"Bus Error\");\n  }\n}\n\n#else /* !defined(POSIX_SIGNAL) */\n\nstatic RETSIGTYPE sigbus _((int));\nstatic RETSIGTYPE\nsigbus(sig)\n    int sig;\n{\n#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)\n    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {\n        sigsend_to_ruby_thread(sig);\n        return;\n    }\n#endif\n\n    rb_bug(\"Bus Error\");\n}\n#endif\n#endif\n\n\n#ifdef SIGSEGV\n#ifdef POSIX_SIGNAL\nstatic void sigsegv _((int, siginfo_t*, void*));\nstatic void\nsigsegv(sig, ip, context)\n     int sig;\n     siginfo_t *ip;\n     void *context;\n{\n#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)\n  if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {\n    sigsend_to_ruby_thread(sig);\n    return;\n  }\n#endif\n\n  dump_machine_state(context);\n  if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) {\n    /* we hit the guard page, print out a warning to help app developers */\n    rb_bug(\"Thread stack overflow! Try increasing it!\");\n  } else {\n    rb_bug(\"Segmentation fault\");\n  }\n}\n\n#else /* !defined(POSIX_SIGNAL) */\n\nstatic RETSIGTYPE sigsegv _((int));\nstatic RETSIGTYPE\nsigsegv(sig)\n    int sig;\n{\n#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL)\n    if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) {\n        sigsend_to_ruby_thread(sig);\n        return;\n    }\n#endif\n\n    rb_gc_unstress();\n    rb_bug(\"Segmentation fault\");\n}\n#endif\n#endif\n\n#ifdef SIGPIPE\nstatic RETSIGTYPE sigpipe _((int));\nstatic RETSIGTYPE\nsigpipe(sig)\n    int sig;\n{\n    /* do nothing */\n}\n#endif\n\nvoid\nrb_trap_exit()\n{\n#ifndef MACOS_UNUSE_SIGNAL\n    if (trap_list[0].cmd) {\n\tVALUE trap_exit = trap_list[0].cmd;\n\n\ttrap_list[0].cmd = 0;\n\trb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)), trap_list[0].safe);\n    }\n#endif\n}\n\nvoid\nrb_trap_exec()\n{\n#ifndef MACOS_UNUSE_SIGNAL\n    int i;\n\n    for (i=0; i<NSIG; i++) {\n\tif (trap_pending_list[i]) {\n\t    trap_pending_list[i] = 0;\n\t    signal_exec(i);\n\t}\n    }\n#endif /* MACOS_UNUSE_SIGNAL */\n    rb_trap_pending = 0;\n}\n\nstruct trap_arg {\n#if USE_TRAP_MASK\n# ifdef HAVE_SIGPROCMASK\n    sigset_t mask;\n# else\n    int mask;\n# endif\n#endif\n    VALUE sig, cmd;\n};\n\n#if USE_TRAP_MASK\n# ifdef HAVE_SIGPROCMASK\nstatic sigset_t trap_last_mask;\n# else\nstatic int trap_last_mask;\n# endif\n#endif\n\nstatic RETSIGTYPE sigexit _((int));\nstatic RETSIGTYPE\nsigexit(sig)\n    int sig;\n{\n    rb_thread_signal_exit();\n}\n\nstatic VALUE\ntrap(arg)\n    struct trap_arg *arg;\n{\n    sighandler_t oldfunc;\n    void *func;\n    VALUE command, oldcmd;\n    int sig = -1;\n    const char *s;\n\n    func = sighandler;\n    command = arg->cmd;\n    if (NIL_P(command)) {\n\tfunc = SIG_IGN;\n    }\n    else if (TYPE(command) == T_STRING) {\n\tSafeStringValue(command);\t/* taint check */\n\tif (RSTRING(command)->len == 0) {\n\t    func = SIG_IGN;\n\t}\n\telse if (RSTRING(command)->len == 7) {\n\t    if (strncmp(RSTRING(command)->ptr, \"SIG_IGN\", 7) == 0) {\n\t\tfunc = SIG_IGN;\n\t    }\n\t    else if (strncmp(RSTRING(command)->ptr, \"SIG_DFL\", 7) == 0) {\n\t\tfunc = SIG_DFL;\n\t    }\n\t    else if (strncmp(RSTRING(command)->ptr, \"DEFAULT\", 7) == 0) {\n\t\tfunc = SIG_DFL;\n\t    }\n\t}\n\telse if (RSTRING(command)->len == 6) {\n\t    if (strncmp(RSTRING(command)->ptr, \"IGNORE\", 6) == 0) {\n\t\tfunc = SIG_IGN;\n\t    }\n\t}\n\telse if (RSTRING(command)->len == 4) {\n\t    if (strncmp(RSTRING(command)->ptr, \"EXIT\", 4) == 0) {\n\t\tfunc = sigexit;\n\t    }\n\t}\n    }\n    if (func == SIG_IGN || func == SIG_DFL) {\n\tcommand = 0;\n    }\n\n    switch (TYPE(arg->sig)) {\n      case T_FIXNUM:\n\tsig = FIX2INT(arg->sig);\n\tbreak;\n\n      case T_SYMBOL:\n\ts = rb_id2name(SYM2ID(arg->sig));\n\tif (!s) rb_raise(rb_eArgError, \"bad signal\");\n\tgoto str_signal;\n\n      case T_STRING:\n\ts = RSTRING(arg->sig)->ptr;\n\n      str_signal:\n\tif (strncmp(\"SIG\", s, 3) == 0)\n\t    s += 3;\n\tsig = signm2signo(s);\n\tif (sig == 0 && strcmp(s, \"EXIT\") != 0)\n\t    rb_raise(rb_eArgError, \"unsupported signal SIG%s\", s);\n    }\n\n    if (sig < 0 || sig >= NSIG) {\n\trb_raise(rb_eArgError, \"invalid signal number (%d)\", sig);\n    }\n#if defined(HAVE_SETITIMER)\n    if (sig == SIGVTALRM) {\n\trb_raise(rb_eArgError, \"SIGVTALRM reserved for Thread; can't set handler\");\n    }\n#endif\n    if (func == SIG_DFL) {\n\tswitch (sig) {\n\t  case SIGINT:\n#ifdef SIGHUP\n\t  case SIGHUP:\n#endif\n#ifdef SIGQUIT\n\t  case SIGQUIT:\n#endif\n#ifdef SIGTERM\n\t  case SIGTERM:\n#endif\n#ifdef SIGALRM\n\t  case SIGALRM:\n#endif\n#ifdef SIGUSR1\n\t  case SIGUSR1:\n#endif\n#ifdef SIGUSR2\n\t  case SIGUSR2:\n#endif\n\t    func = sighandler;\n\t    break;\n#ifdef SIGBUS\n\t  case SIGBUS:\n\t    func = sigbus;\n\t    break;\n#endif\n#ifdef SIGSEGV\n\t  case SIGSEGV:\n\t    func = sigsegv;\n\t    break;\n#endif\n#ifdef SIGPIPE\n\t  case SIGPIPE:\n\t    func = sigpipe;\n\t    break;\n#endif\n\t}\n    }\n    oldfunc = ruby_signal(sig, func);\n    oldcmd = trap_list[sig].cmd;\n    if (!oldcmd) {\n\tif (oldfunc == SIG_IGN) oldcmd = rb_str_new2(\"IGNORE\");\n\telse if (oldfunc == sighandler) oldcmd = rb_str_new2(\"DEFAULT\");\n\telse oldcmd = Qnil;\n    }\n\n    trap_list[sig].cmd = command;\n    trap_list[sig].safe = ruby_safe_level;\n    /* enable at least specified signal. */\n#if USE_TRAP_MASK\n#ifdef HAVE_SIGPROCMASK\n    sigdelset(&arg->mask, sig);\n#else\n    arg->mask &= ~sigmask(sig);\n#endif\n#endif\n    return oldcmd;\n}\n\n#if USE_TRAP_MASK\nstatic VALUE\ntrap_ensure(arg)\n    struct trap_arg *arg;\n{\n    /* enable interrupt */\n#ifdef HAVE_SIGPROCMASK\n    sigprocmask(SIG_SETMASK, &arg->mask, NULL);\n#else\n    sigsetmask(arg->mask);\n#endif\n    trap_last_mask = arg->mask;\n    return 0;\n}\n#endif\n\nvoid\nrb_trap_restore_mask()\n{\n#if USE_TRAP_MASK\n# ifdef HAVE_SIGPROCMASK\n    sigprocmask(SIG_SETMASK, &trap_last_mask, NULL);\n# else\n    sigsetmask(trap_last_mask);\n# endif\n#endif\n}\n\n/*\n * call-seq:\n *   Signal.trap( signal, proc ) => obj\n *   Signal.trap( signal ) {| | block } => obj\n *\n * Specifies the handling of signals. The first parameter is a signal\n * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a\n * signal number. The characters ``SIG'' may be omitted from the\n * signal name. The command or block specifies code to be run when the\n * signal is raised. If the command is the string ``IGNORE'' or\n * ``SIG_IGN'', the signal will be ignored. If the command is\n * ``DEFAULT'' or ``SIG_DFL'', the operating system's default handler\n * will be invoked. If the command is ``EXIT'', the script will be\n * terminated by the signal. Otherwise, the given command or block\n * will be run.\n * The special signal name ``EXIT'' or signal number zero will be\n * invoked just prior to program termination.\n * trap returns the previous handler for the given signal.\n *\n *     Signal.trap(0, proc { puts \"Terminating: #{$$}\" })\n *     Signal.trap(\"CLD\")  { puts \"Child died\" }\n *     fork && Process.wait\n *\n * produces:\n *     Terminating: 27461\n *     Child died\n *     Terminating: 27460\n */\nstatic VALUE\nsig_trap(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    struct trap_arg arg;\n\n    rb_secure(2);\n    if (argc == 0 || argc > 2) {\n\trb_raise(rb_eArgError, \"wrong number of arguments -- trap(sig, cmd)/trap(sig){...}\");\n    }\n\n    arg.sig = argv[0];\n    if (argc == 1) {\n\targ.cmd = rb_block_proc();\n    }\n    else if (argc == 2) {\n\targ.cmd = argv[1];\n    }\n\n    if (OBJ_TAINTED(arg.cmd)) {\n\trb_raise(rb_eSecurityError, \"Insecure: tainted signal trap\");\n    }\n#if USE_TRAP_MASK\n    /* disable interrupt */\n# ifdef HAVE_SIGPROCMASK\n    sigfillset(&arg.mask);\n    sigprocmask(SIG_BLOCK, &arg.mask, &arg.mask);\n# else\n    arg.mask = sigblock(~0);\n# endif\n\n    return rb_ensure(trap, (VALUE)&arg, trap_ensure, (VALUE)&arg);\n#else\n    return trap(&arg);\n#endif\n}\n\n/*\n * call-seq:\n *   Signal.list => a_hash\n *\n * Returns a list of signal names mapped to the corresponding\n * underlying signal numbers.\n *\n * Signal.list   #=> {\"ABRT\"=>6, \"ALRM\"=>14, \"BUS\"=>7, \"CHLD\"=>17, \"CLD\"=>17, \"CONT\"=>18, \"FPE\"=>8, \"HUP\"=>1, \"ILL\"=>4, \"INT\"=>2, \"IO\"=>29, \"IOT\"=>6, \"KILL\"=>9, \"PIPE\"=>13, \"POLL\"=>29, \"PROF\"=>27, \"PWR\"=>30, \"QUIT\"=>3, \"SEGV\"=>11, \"STOP\"=>19, \"SYS\"=>31, \"TERM\"=>15, \"TRAP\"=>5, \"TSTP\"=>20, \"TTIN\"=>21, \"TTOU\"=>22, \"URG\"=>23, \"USR1\"=>10, \"USR2\"=>12, \"VTALRM\"=>26, \"WINCH\"=>28, \"XCPU\"=>24, \"XFSZ\"=>25}\n */\nstatic VALUE\nsig_list()\n{\n    VALUE h = rb_hash_new();\n    struct signals *sigs;\n\n    for (sigs = siglist; sigs->signm; sigs++) {\n\trb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));\n    }\n    return h;\n}\n\nstatic void\ncreate_sigstack()\n{\n  stack_t ss;\n  ss.ss_size = SIGSTKSZ;\n  ss.ss_sp = malloc(ss.ss_size);\n  ss.ss_flags = 0;\n  if (sigaltstack(&ss, NULL) < 0) {\n    free(ss.ss_sp);\n    fprintf(stderr, \"Couldn't create signal stack! Error %d: %s\\n\", errno, strerror(errno));\n    exit(1);\n  }\n}\n\nstatic void\ninstall_sighandler(signum, handler)\n    int signum;\n    sighandler_t handler;\n{\n    sighandler_t old;\n\n    old = ruby_signal(signum, handler);\n    if (old != SIG_DFL) {\n       ruby_signal(signum, old);\n    }\n}\n\n#if 0\n/* \n *   If you write a handler which works on any native thread\n *   (even if the thread is NOT a ruby's one), please enable\n *   this function and use it to install the handler, instead\n *   of `install_sighandler()'.\n */\n#ifdef HAVE_NATIVETHREAD\nstatic void\ninstall_nativethread_sighandler(signum, handler)\n    int signum;\n    sighandler_t handler;\n{\n    sighandler_t old;\n    int old_st;\n\n    old_st = rb_trap_accept_nativethreads[signum];\n    old = ruby_nativethread_signal(signum, handler);\n    if (old != SIG_DFL) {\n        if (old_st) {\n            ruby_nativethread_signal(signum, old);\n        } else {\n            ruby_signal(signum, old);\n        }\n    }\n}\n#endif\n#endif\n\n#if defined(SIGCLD) || defined(SIGCHLD)\nstatic void\ninit_sigchld(sig)\n    int sig;\n{\n    sighandler_t oldfunc;\n#if USE_TRAP_MASK\n# ifdef HAVE_SIGPROCMASK\n    sigset_t mask;\n# else\n    int mask;\n# endif\n#endif\n\n#if USE_TRAP_MASK\n    /* disable interrupt */\n# ifdef HAVE_SIGPROCMASK\n    sigfillset(&mask);\n    sigprocmask(SIG_BLOCK, &mask, &mask);\n# else\n    mask = sigblock(~0);\n# endif\n#endif\n\n    oldfunc = ruby_signal(sig, SIG_DFL);\n    if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {\n\truby_signal(sig, oldfunc);\n    } else {\n\ttrap_list[sig].cmd = 0;\n    }\n\n#if USE_TRAP_MASK\n#ifdef HAVE_SIGPROCMASK\n    sigdelset(&mask, sig);\n    sigprocmask(SIG_SETMASK, &mask, NULL);\n#else\n    mask &= ~sigmask(sig);\n    sigsetmask(mask);\n#endif\n    trap_last_mask = mask;\n#endif\n}\n#endif\n\n/*\n * Many operating systems allow signals to be sent to running\n * processes. Some signals have a defined effect on the process, while\n * others may be trapped at the code level and acted upon. For\n * example, your process may trap the USR1 signal and use it to toggle\n * debugging, and may use TERM to initiate a controlled shutdown.\n *\n *     pid = fork do\n *       Signal.trap(\"USR1\") do\n *         $debug = !$debug\n *         puts \"Debug now: #$debug\"\n *       end\n *       Signal.trap(\"TERM\") do\n *         puts \"Terminating...\"\n *         shutdown()\n *       end\n *       # . . . do some work . . .\n *     end\n *\n *     Process.detach(pid)\n *\n *     # Controlling program:\n *     Process.kill(\"USR1\", pid)\n *     # ...\n *     Process.kill(\"USR1\", pid)\n *     # ...\n *     Process.kill(\"TERM\", pid)\n *\n * produces:\n *     Debug now: true\n *     Debug now: false\n *    Terminating...\n *\n * The list of available signal names and their interpretation is\n * system dependent. Signal delivery semantics may also vary between\n * systems; in particular signal delivery may not always be reliable.\n */\nvoid\nInit_signal()\n{\n#ifndef MACOS_UNUSE_SIGNAL\n    VALUE mSignal = rb_define_module(\"Signal\");\n\n    rb_define_global_function(\"trap\", sig_trap, -1);\n    rb_define_module_function(mSignal, \"trap\", sig_trap, -1);\n    rb_define_module_function(mSignal, \"list\", sig_list, 0);\n\n    rb_define_method(rb_eSignal, \"initialize\", esignal_init, -1);\n    rb_attr(rb_eSignal, rb_intern(\"signo\"), 1, 0, 0);\n    rb_alias(rb_eSignal, rb_intern(\"signm\"), rb_intern(\"message\"));\n    rb_define_method(rb_eInterrupt, \"initialize\", interrupt_init, -1);\n\n    create_sigstack();\n\n    install_sighandler(SIGINT, sighandler);\n#ifdef SIGHUP\n    install_sighandler(SIGHUP, sighandler);\n#endif\n#ifdef SIGQUIT\n    install_sighandler(SIGQUIT, sighandler);\n#endif\n#ifdef SIGTERM\n    install_sighandler(SIGTERM, sighandler);\n#endif\n#ifdef SIGALRM\n    install_sighandler(SIGALRM, sighandler);\n#endif\n#ifdef SIGUSR1\n    install_sighandler(SIGUSR1, sighandler);\n#endif\n#ifdef SIGUSR2\n    install_sighandler(SIGUSR2, sighandler);\n#endif\n\n#ifdef SIGBUS\n    install_sighandler(SIGBUS, sigbus);\n#endif\n#ifdef SIGSEGV\n    install_sighandler(SIGSEGV, sigsegv);\n#endif\n#ifdef SIGPIPE\n    install_sighandler(SIGPIPE, sigpipe);\n#endif\n\n#if defined(SIGCLD)\n    init_sigchld(SIGCLD);\n#elif defined(SIGCHLD)\n    init_sigchld(SIGCHLD);\n#endif\n\n#endif /* MACOS_UNUSE_SIGNAL */\n}\n"
  },
  {
    "path": "sprintf.c",
    "content": "/**********************************************************************\n\n  sprintf.c -\n\n  $Author$\n  $Date$\n  created at: Fri Oct 15 10:39:26 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"re.h\"\n#include <ctype.h>\n#include <math.h>\n\n#define BIT_DIGITS(N)   (((N)*146)/485 + 1)  /* log2(10) =~ 146/485 */\n#define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)\n#define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n)))\n\nstatic void fmt_setup _((char*,int,int,int,int));\n\nstatic char*\nremove_sign_bits(str, base)\n    char *str;\n    int base;\n{\n    char *s, *t;\n    \n    s = t = str;\n\n    if (base == 16) {\n\twhile (*t == 'f') {\n\t    t++;\n\t}\n    }\n    else if (base == 8) {\n\t*t |= EXTENDSIGN(3, strlen(t));\n\twhile (*t == '7') {\n\t    t++;\n\t}\n    }\n    else if (base == 2) {\n\twhile (*t == '1') {\n\t    t++;\n\t}\n    }\n    if (t > s) {\n\twhile (*t) *s++ = *t++;\n\t*s = '\\0';\n    }\n\n    return str;\n}\n\nstatic char\nsign_bits(base, p)\n    int base;\n    const char *p;\n{\n    char c = '.';\n\n    switch (base) {\n      case 16:\n\tif (*p == 'X') c = 'F';\n\telse c = 'f';\n\tbreak;\n      case 8:\n\tc = '7'; break;\n      case 2:\n\tc = '1'; break;\n    }\n    return c;\n}\n\n#define FNONE  0\n#define FSHARP 1\n#define FMINUS 2\n#define FPLUS  4\n#define FZERO  8\n#define FSPACE 16\n#define FWIDTH 32\n#define FPREC  64\n#define FPREC0 128\n\n#define CHECK(l) do {\\\n    while (blen + (l) >= bsiz) {\\\n\tbsiz*=2;\\\n    }\\\n    rb_str_resize(result, bsiz);\\\n    buf = RSTRING(result)->ptr;\\\n} while (0)\n\n#define PUSH(s, l) do { \\\n    CHECK(l);\\\n    memcpy(&buf[blen], s, l);\\\n    blen += (l);\\\n} while (0)\n\n#define GETARG() (nextvalue != Qundef ? nextvalue : \\\n    posarg < 0 ? \\\n    (rb_raise(rb_eArgError, \"unnumbered(%d) mixed with numbered\", nextarg), 0) : \\\n    (posarg = nextarg++, GETNTHARG(posarg)))\n\n#define GETPOSARG(n) (posarg > 0 ? \\\n    (rb_raise(rb_eArgError, \"numbered(%d) after unnumbered(%d)\", n, posarg), 0) : \\\n    ((n < 1) ? (rb_raise(rb_eArgError, \"invalid index - %d$\", n), 0) : \\\n\t       (posarg = -1, GETNTHARG(n))))\n\n#define GETNTHARG(nth) \\\n    ((nth >= argc) ? (rb_raise(rb_eArgError, \"too few arguments\"), 0) : argv[nth])\n\n#define GETNUM(n, val) \\\n    for (; p < end && ISDIGIT(*p); p++) { \\\n\tint next_n = 10 * n + (*p - '0'); \\\n        if (next_n / 10 != n) {\\\n\t    rb_raise(rb_eArgError, #val \" too big\"); \\\n\t} \\\n\tn = next_n; \\\n    } \\\n    if (p >= end) { \\\n\trb_raise(rb_eArgError, \"malformed format string - %%*[0-9]\"); \\\n    }\n\n#define GETASTER(val) do { \\\n    t = p++; \\\n    n = 0; \\\n    GETNUM(n, val); \\\n    if (*p == '$') { \\\n\ttmp = GETPOSARG(n); \\\n    } \\\n    else { \\\n\ttmp = GETARG(); \\\n\tp = t; \\\n    } \\\n    val = NUM2INT(tmp); \\\n} while (0)\n\n\n/*\n *  call-seq:\n *     format(format_string [, arguments...] )   => string\n *     sprintf(format_string [, arguments...] )  => string\n *  \n *  Returns the string resulting from applying <i>format_string</i> to\n *  any additional arguments. Within the format string, any characters\n *  other than format sequences are copied to the result. A format\n *  sequence consists of a percent sign, followed by optional flags,\n *  width, and precision indicators, then terminated with a field type\n *  character. The field type controls how the corresponding\n *  <code>sprintf</code> argument is to be interpreted, while the flags\n *  modify that interpretation. The field type characters are listed\n *  in the table at the end of this section. The flag characters are:\n *\n *    Flag     | Applies to   | Meaning\n *    ---------+--------------+-----------------------------------------\n *    space    | bdeEfgGiouxX | Leave a space at the start of \n *             |              | positive numbers.\n *    ---------+--------------+-----------------------------------------\n *    (digit)$ | all          | Specifies the absolute argument number\n *             |              | for this field. Absolute and relative\n *             |              | argument numbers cannot be mixed in a\n *             |              | sprintf string.\n *    ---------+--------------+-----------------------------------------\n *     #       | beEfgGoxX    | Use an alternative format. For the\n *             |              | conversions `o', `x', `X', and `b', \n *             |              | prefix the result with ``0'', ``0x'', ``0X'',\n *             |              |  and ``0b'', respectively. For `e',\n *             |              | `E', `f', `g', and 'G', force a decimal\n *             |              | point to be added, even if no digits follow.\n *             |              | For `g' and 'G', do not remove trailing zeros.\n *    ---------+--------------+-----------------------------------------\n *    +        | bdeEfgGiouxX | Add a leading plus sign to positive numbers.\n *    ---------+--------------+-----------------------------------------\n *    -        | all          | Left-justify the result of this conversion.\n *    ---------+--------------+-----------------------------------------\n *    0 (zero) | bdeEfgGiouxX | Pad with zeros, not spaces.\n *    ---------+--------------+-----------------------------------------\n *    *        | all          | Use the next argument as the field width. \n *             |              | If negative, left-justify the result. If the\n *             |              | asterisk is followed by a number and a dollar \n *             |              | sign, use the indicated argument as the width.\n *\n *     \n *  The field width is an optional integer, followed optionally by a\n *  period and a precision. The width specifies the minimum number of\n *  characters that will be written to the result for this field. For\n *  numeric fields, the precision controls the number of decimal places\n *  displayed. For string fields, the precision determines the maximum\n *  number of characters to be copied from the string. (Thus, the format\n *  sequence <code>%10.10s</code> will always contribute exactly ten\n *  characters to the result.)\n *\n *  The field types are:\n *\n *      Field |  Conversion\n *      ------+--------------------------------------------------------------\n *        b   | Convert argument as a binary number.\n *        c   | Argument is the numeric code for a single character.\n *        d   | Convert argument as a decimal number.\n *        E   | Equivalent to `e', but uses an uppercase E to indicate\n *            | the exponent.\n *        e   | Convert floating point argument into exponential notation \n *            | with one digit before the decimal point. The precision\n *            | determines the number of fractional digits (defaulting to six).\n *        f   | Convert floating point argument as [-]ddd.ddd, \n *            |  where the precision determines the number of digits after\n *            | the decimal point.\n *        G   | Equivalent to `g', but use an uppercase `E' in exponent form.\n *        g   | Convert a floating point number using exponential form\n *            | if the exponent is less than -4 or greater than or\n *            | equal to the precision, or in d.dddd form otherwise.\n *        i   | Identical to `d'.\n *        o   | Convert argument as an octal number.\n *        p   | The valuing of argument.inspect.\n *        s   | Argument is a string to be substituted. If the format\n *            | sequence contains a precision, at most that many characters\n *            | will be copied.\n *        u   | Treat argument as an unsigned decimal number. Negative integers\n *            | are displayed as a 32 bit two's complement plus one for the\n *            | underlying architecture; that is, 2 ** 32 + n.  However, since\n *            | Ruby has no inherent limit on bits used to represent the\n *            | integer, this value is preceded by two dots (..) in order to\n *            | indicate a infinite number of leading sign bits.\n *        X   | Convert argument as a hexadecimal number using uppercase\n *            | letters. Negative numbers will be displayed with two\n *            | leading periods (representing an infinite string of\n *            | leading 'FF's.\n *        x   | Convert argument as a hexadecimal number.\n *            | Negative numbers will be displayed with two\n *            | leading periods (representing an infinite string of\n *            | leading 'ff's.\n *     \n *  Examples:\n *\n *     sprintf(\"%d %04x\", 123, 123)               #=> \"123 007b\"\n *     sprintf(\"%08b '%4s'\", 123, 123)            #=> \"01111011 ' 123'\"\n *     sprintf(\"%1$*2$s %2$d %1$s\", \"hello\", 8)   #=> \"   hello 8 hello\"\n *     sprintf(\"%1$*2$s %2$d\", \"hello\", -8)       #=> \"hello    -8\"\n *     sprintf(\"%+g:% g:%-g\", 1.23, 1.23, 1.23)   #=> \"+1.23: 1.23:1.23\"\n *     sprintf(\"%u\", -123)                        #=> \"..4294967173\"\n */\n\nVALUE\nrb_f_sprintf(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));\n}\n\nVALUE\nrb_str_format(argc, argv, fmt)\n    int argc;\n    VALUE *argv;\n    VALUE fmt;\n{\n    const char *p, *end;\n    char *buf;\n    int blen, bsiz;\n    VALUE result;\n\n    int width, prec, flags = FNONE;\n    int nextarg = 1;\n    int posarg = 0;\n    int tainted = 0;\n    VALUE nextvalue;\n    VALUE tmp;\n    VALUE str;\n\n#define CHECK_FOR_WIDTH(f)\t\t\t\t \\\n    if ((f) & FWIDTH) {\t\t\t\t\t \\\n\trb_raise(rb_eArgError, \"width given twice\");\t \\\n    }\t\t\t\t\t\t\t \\\n    if ((f) & FPREC0) {\t\t\t\t\t \\\n\trb_raise(rb_eArgError, \"width after precision\"); \\\n    }\n#define CHECK_FOR_FLAGS(f)\t\t\t\t \\\n    if ((f) & FWIDTH) {\t\t\t\t\t \\\n\trb_raise(rb_eArgError, \"flag after width\");\t \\\n    }\t\t\t\t\t\t\t \\\n    if ((f) & FPREC0) {\t\t\t\t\t \\\n\trb_raise(rb_eArgError, \"flag after precision\"); \\\n    }\n\n    ++argc;\n    --argv;\n    if (OBJ_TAINTED(fmt)) tainted = 1;\n    StringValue(fmt);\n    fmt = rb_str_new4(fmt);\n    p = RSTRING(fmt)->ptr;\n    end = p + RSTRING(fmt)->len;\n    blen = 0;\n    bsiz = 120;\n    result = rb_str_buf_new(bsiz);\n    buf = RSTRING(result)->ptr;\n\n    for (; p < end; p++) {\n\tconst char *t;\n\tint n;\n\n\tfor (t = p; t < end && *t != '%'; t++) ;\n\tPUSH(p, t - p);\n\tif (t >= end) {\n\t    /* end of fmt string */\n\t    goto sprint_exit;\n\t}\n\tp = t + 1;\t\t/* skip `%' */\n\n\twidth = prec = -1;\n\tnextvalue = Qundef;\n      retry:\n\tswitch (*p) {\n\t  default:\n\t    if (ISPRINT(*p))\n\t\trb_raise(rb_eArgError, \"malformed format string - %%%c\", *p);\n\t    else\n\t\trb_raise(rb_eArgError, \"malformed format string\");\n\t    break;\n\n\t  case ' ':\n\t    CHECK_FOR_FLAGS(flags);\n\t    flags |= FSPACE;\n\t    p++;\n\t    goto retry;\n\n\t  case '#':\n\t    CHECK_FOR_FLAGS(flags);\n\t    flags |= FSHARP;\n\t    p++;\n\t    goto retry;\n\n\t  case '+':\n\t    CHECK_FOR_FLAGS(flags);\n\t    flags |= FPLUS;\n\t    p++;\n\t    goto retry;\n\n\t  case '-':\n\t    CHECK_FOR_FLAGS(flags);\n\t    flags |= FMINUS;\n\t    p++;\n\t    goto retry;\n\n\t  case '0':\n\t    CHECK_FOR_FLAGS(flags);\n\t    flags |= FZERO;\n\t    p++;\n\t    goto retry;\n\n\t  case '1': case '2': case '3': case '4':\n\t  case '5': case '6': case '7': case '8': case '9':\n\t    n = 0;\n\t    GETNUM(n, width);\n\t    if (*p == '$') {\n\t\tif (nextvalue != Qundef) {\n\t\t    rb_raise(rb_eArgError, \"value given twice - %d$\", n);\n\t\t}\n\t\tnextvalue = GETPOSARG(n);\n\t\tp++;\n\t\tgoto retry;\n\t    }\n\t    CHECK_FOR_WIDTH(flags);\n\t    width = n;\n\t    flags |= FWIDTH;\n\t    goto retry;\n\n\t  case '*':\n\t    CHECK_FOR_WIDTH(flags);\n\t    flags |= FWIDTH;\n\t    GETASTER(width);\n\t    if (width < 0) {\n\t\tflags |= FMINUS;\n\t\twidth = -width;\n\t    }\n\t    p++;\n\t    goto retry;\n\n\t  case '.':\n\t    if (flags & FPREC0) {\n\t\trb_raise(rb_eArgError, \"precision given twice\");\n\t    }\n\t    flags |= FPREC|FPREC0;\n\n\t    prec = 0;\n\t    p++;\n\t    if (*p == '*') {\n\t\tGETASTER(prec);\n\t\tif (prec < 0) {\t/* ignore negative precision */\n\t\t    flags &= ~FPREC;\n\t\t}\n\t\tp++;\n\t\tgoto retry;\n\t    }\n\n\t    GETNUM(prec, precision);\n\t    goto retry;\n\n\t  case '\\n':\n\t  case '\\0':\n\t    p--;\n\t  case '%':\n\t    if (flags != FNONE) {\n\t\trb_raise(rb_eArgError, \"illegal format character - %%\");\n\t    }\n\t    PUSH(\"%\", 1);\n\t    break;\n\n\t  case 'c':\n\t    {\n\t\tVALUE val = GETARG();\n\t\tchar c;\n\n\t\tif (!(flags & FMINUS))\n\t\t    while (--width > 0)\n\t\t\tPUSH(\" \", 1);\n\t\tc = NUM2INT(val) & 0xff;\n\t\tPUSH(&c, 1);\n\t\twhile (--width > 0)\n\t\t    PUSH(\" \", 1);\n\t    }\n\t    break;\n\n\t  case 's':\n\t  case 'p':\n\t    {\n\t\tVALUE arg = GETARG();\n\t\tlong len;\n\n\t\tif (*p == 'p') arg = rb_inspect(arg);\n\t\tstr = rb_obj_as_string(arg);\n\t\tif (OBJ_TAINTED(str)) tainted = 1;\n\t\tlen = RSTRING(str)->len;\n\t\tif (flags&FPREC) {\n\t\t    if (prec < len) {\n\t\t\tlen = prec;\n\t\t    }\n\t\t}\n\t\t/* need to adjust multi-byte string pos */\n\t\tif (flags&FWIDTH) {\n\t\t    if (width > len) {\n\t\t\tCHECK(width);\n\t\t\twidth -= len;\n\t\t\tif (!(flags&FMINUS)) {\n\t\t\t    while (width--) {\n\t\t\t\tbuf[blen++] = ' ';\n\t\t\t    }\n\t\t\t}\n\t\t\tmemcpy(&buf[blen], RSTRING_PTR(str), len);\n\t\t\tblen += len;\n\t\t\tif (flags&FMINUS) {\n\t\t\t    while (width--) {\n\t\t\t\tbuf[blen++] = ' ';\n\t\t\t    }\n\t\t\t}\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\t\tPUSH(RSTRING(str)->ptr, len);\n\t    }\n\t    break;\n\n\t  case 'd':\n\t  case 'i':\n\t  case 'o':\n\t  case 'x':\n\t  case 'X':\n\t  case 'b':\n\t  case 'B':\n\t  case 'u':\n\t    {\n\t\tvolatile VALUE val = GETARG();\n\t\tchar fbuf[32], nbuf[64], *s, *t;\n\t\tconst char *prefix = 0;\n\t\tint sign = 0;\n\t\tchar sc = 0;\n\t\tlong v = 0;\n\t\tint base, bignum = 0;\n\t\tint len, pos;\n\t\tvolatile VALUE tmp;\n                volatile VALUE tmp1;\n\n\t\tswitch (*p) {\n\t\t  case 'd':\n\t\t  case 'i':\n\t\t    sign = 1; break;\n\t\t  case 'o':\n\t\t  case 'x':\n\t\t  case 'X':\n\t\t  case 'b':\n\t\t  case 'B':\n\t\t  case 'u':\n\t\t  default:\n\t\t    if (flags&(FPLUS|FSPACE)) sign = 1;\n\t\t    break;\n\t\t}\n\t\tif (flags & FSHARP) {\n\t\t    switch (*p) {\n\t\t      case 'o':\n\t\t\tprefix = \"0\"; break;\n\t\t      case 'x':\n\t\t\tprefix = \"0x\"; break;\n\t\t      case 'X':\n\t\t\tprefix = \"0X\"; break;\n\t\t      case 'b':\n\t\t\tprefix = \"0b\"; break;\n\t\t      case 'B':\n\t\t\tprefix = \"0B\"; break;\n\t\t    }\n\t\t    if (prefix) {\n\t\t\twidth -= strlen(prefix);\n\t\t    }\n\t\t}\n\n\t      bin_retry:\n\t\tswitch (TYPE(val)) {\n\t\t  case T_FLOAT:\n\t\t    val = rb_dbl2big(RFLOAT(val)->value);\n\t\t    if (FIXNUM_P(val)) goto bin_retry;\n\t\t    bignum = 1;\n\t\t    break;\n\t\t  case T_STRING:\n\t\t    val = rb_str_to_inum(val, 0, Qtrue);\n\t\t    goto bin_retry;\n\t\t  case T_BIGNUM:\n\t\t    bignum = 1;\n\t\t    break;\n\t\t  case T_FIXNUM:\n\t\t    v = FIX2LONG(val);\n\t\t    break;\n\t\t  default:\n\t\t    val = rb_Integer(val);\n\t\t    goto bin_retry;\n\t\t}\n\n\t\tswitch (*p) {\n\t\t  case 'o':\n\t\t    base = 8; break;\n\t\t  case 'x':\n\t\t  case 'X':\n\t\t    base = 16; break;\n\t\t  case 'b':\n\t\t  case 'B':\n\t\t    base = 2; break;\n\t\t  case 'u':\n\t\t  case 'd':\n\t\t  case 'i':\n\t\t  default:\n\t\t    base = 10; break;\n\t\t}\n\n\t\tif (!bignum) {\n\t\t    if (base == 2) {\n\t\t\tval = rb_int2big(v);\n\t\t\tgoto bin_retry;\n\t\t    }\n\t\t    if (sign) {\n\t\t\tchar c = *p;\n\t\t\tif (c == 'i') c = 'd'; /* %d and %i are identical */\n\t\t\tif (v < 0) {\n\t\t\t    v = -v;\n\t\t\t    sc = '-';\n\t\t\t    width--;\n\t\t\t}\n\t\t\telse if (flags & FPLUS) {\n\t\t\t    sc = '+';\n\t\t\t    width--;\n\t\t\t}\n\t\t\telse if (flags & FSPACE) {\n\t\t\t    sc = ' ';\n\t\t\t    width--;\n\t\t\t}\n\t\t\tsprintf(fbuf, \"%%l%c\", c);\n\t\t\tsprintf(nbuf, fbuf, v);\n\t\t\ts = nbuf;\n\t\t\tgoto format_integer;\n\t\t    }\n\t\t    s = nbuf;\n\t\t    if (v < 0) {\n\t\t\tif (base == 10) {\n\t\t\t    rb_warning(\"negative number for %%u specifier\");\n\t\t\t}\n\t\t\tif (!(flags&(FPREC|FZERO))) {\n\t\t\t    strcpy(s, \"..\");\n\t\t\t    s += 2;\n\t\t\t}\n\t\t    }\n\t\t    sprintf(fbuf, \"%%l%c\", *p == 'X' ? 'x' : *p);\n\t\t    sprintf(s, fbuf, v);\n\t\t    if (v < 0) {\n\t\t\tchar d = 0;\n\n\t\t\tremove_sign_bits(s, base);\n\t\t\tswitch (base) {\n\t\t\t  case 16:\n\t\t\t    d = 'f'; break;\n\t\t\t  case 8:\n\t\t\t    d = '7'; break;\n\t\t\t}\n\t\t\tif (d && *s != d) {\n\t\t\t    memmove(s+1, s, strlen(s)+1);\n\t\t\t    *s = d;\n\t\t\t}\n\t\t    }\n\t\t    s = nbuf;\n\t\t    goto format_integer;\n\t\t}\n\n\t\tif (sign) {\n\t\t    tmp = rb_big2str(val, base);\n\t\t    s = RSTRING(tmp)->ptr;\n\t\t    if (s[0] == '-') {\n\t\t\ts++;\n\t\t\tsc = '-';\n                        width--;\n\t\t    }\n\t\t    else if (flags & FPLUS) {\n\t\t\tsc = '+';\n                        width--;\n\t\t    }\n\t\t    else if (flags & FSPACE) {\n\t\t\tsc = ' ';\n                        width--;\n\t\t    }\n\t\t    goto format_integer;\n\t\t}\n\t\tif (!RBIGNUM(val)->sign) {\n\t\t    val = rb_big_clone(val);\n\t\t    rb_big_2comp(val);\n\t\t}\n\t\ttmp1 = tmp = rb_big2str0(val, base, RBIGNUM(val)->sign);\n\t\ts = RSTRING(tmp)->ptr;\n\t\tif (*s == '-') {\n\t\t    if (base == 10) {\n\t\t\trb_warning(\"negative number for %%u specifier\");\n\t\t    }\n\t\t    remove_sign_bits(++s, base);\n\t\t    tmp = rb_str_new(0, 3+strlen(s));\n\t\t    t = RSTRING(tmp)->ptr;\n\t\t    if (!(flags&(FPREC|FZERO))) {\n\t\t\tstrcpy(t, \"..\");\n\t\t\tt += 2;\n\t\t    }\n\t\t    switch (base) {\n\t\t      case 16:\n\t\t\tif (s[0] != 'f') strcpy(t++, \"f\"); break;\n\t\t      case 8:\n\t\t\tif (s[0] != '7') strcpy(t++, \"7\"); break;\n\t\t      case 2:\n\t\t\tif (s[0] != '1') strcpy(t++, \"1\"); break;\n\t\t    }\n\t\t    strcpy(t, s);\n\t\t    bignum = 2;\n\t\t}\n\t\ts = RSTRING(tmp)->ptr;\n\n\t      format_integer:\n\t\tpos = -1;\n\t\tlen = strlen(s);\n\n\t\tif (*p == 'X') {\n\t\t    char *pp = s;\n\t\t    while (*pp) {\n\t\t\t*pp = toupper(*pp);\n\t\t\tpp++;\n\t\t    }\n\t\t}\n\t\tif ((flags&(FZERO|FPREC)) == FZERO) {\n\t\t    prec = width;\n\t\t    width = 0;\n\t\t}\n\t\telse {\n\t\t    if (prec < len) prec = len;\n\t\t    width -= prec;\n\t\t}\n\t\tif (!(flags&FMINUS)) {\n\t\t    CHECK(width);\n\t\t    while (width-- > 0) {\n\t\t\tbuf[blen++] = ' ';\n\t\t    }\n\t\t}\n\t\tif (sc) PUSH(&sc, 1);\n\t\tif (prefix) {\n\t\t    int plen = strlen(prefix);\n\t\t    PUSH(prefix, plen);\n\t\t}\n\t\tCHECK(prec - len);\n\t\tif (!bignum && v < 0) {\n\t\t    char c = sign_bits(base, p);\n\t\t    while (len < prec--) {\n\t\t\tbuf[blen++] = c;\n\t\t    }\n\t\t}\n\t\telse {\n\t\t    char c;\n\n\t\t    if (!sign && bignum && !RBIGNUM(val)->sign)\n\t\t\tc = sign_bits(base, p);\n\t\t    else\n\t\t\tc = '0';\n\t\t    while (len < prec--) {\n\t\t\tbuf[blen++] = c;\n\t\t    }\n\t\t}\n\t\tPUSH(s, len);\n\t\tCHECK(width);\n\t\twhile (width-- > 0) {\n\t\t    buf[blen++] = ' ';\n\t\t}\n\t    }\n\t    break;\n\n\t  case 'f':\n\t  case 'g':\n\t  case 'G':\n\t  case 'e':\n\t  case 'E':\n\t    {\n\t\tVALUE val = GETARG();\n\t\tdouble fval;\n\t\tint i, need = 6;\n\t\tchar fbuf[32];\n\n\t\tfval = RFLOAT(rb_Float(val))->value;\n#if defined(_WIN32) && !defined(__BORLANDC__)\n\t\tif (isnan(fval) || isinf(fval)) {\n\t\t    const char *expr;\n\n\t\t    if  (isnan(fval)) {\n\t\t\texpr = \"NaN\";\n\t\t    }\n\t\t    else {\n\t\t\texpr = \"Inf\";\n\t\t    }\n\t\t    need = strlen(expr);\n\t\t    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))\n\t\t\tneed++;\n\t\t    else if (flags & FSPACE)\n\t\t\tneed++;\n\t\t    if ((flags & FWIDTH) && need < width)\n\t\t\tneed = width;\n\n\t\t    CHECK(need);\n\t\t    sprintf(&buf[blen], \"%*s\", need, \"\");\n\t\t    if (flags & FMINUS) {\n\t\t\tif (!isnan(fval) && fval < 0.0)\n\t\t\t    buf[blen++] = '-';\n\t\t\telse if (flags & FPLUS)\n\t\t\t    buf[blen++] = '+';\n\t\t\telse if (flags & FSPACE)\n\t\t\t    blen++;\n\t\t\tstrncpy(&buf[blen], expr, strlen(expr));\n\t\t    }\n\t\t    else if (flags & FZERO) {\n\t\t\tif (!isnan(fval) && fval < 0.0) {\n\t\t\t    buf[blen++] = '-';\n\t\t\t    need--;\n\t\t\t}\n\t\t\telse if (flags & FPLUS) {\n\t\t\t    buf[blen++] = '+';\n\t\t\t    need--;\n\t\t\t}\n\t\t\telse if (flags & FSPACE) {\n\t\t\t    blen++;\n\t\t\t    need--;\n\t\t\t}\n\t\t\twhile (need-- - strlen(expr) > 0) {\n\t\t\t    buf[blen++] = '0';\n\t\t\t}\n\t\t\tstrncpy(&buf[blen], expr, strlen(expr));\n\t\t    }\n\t\t    else {\n\t\t\tif (!isnan(fval) && fval < 0.0)\n\t\t\t    buf[blen + need - strlen(expr) - 1] = '-';\n\t\t\telse if (flags & FPLUS)\n\t\t\t    buf[blen + need - strlen(expr) - 1] = '+';\n\t\t\tstrncpy(&buf[blen + need - strlen(expr)], expr,\n\t\t\t\tstrlen(expr));\n\t\t    }\n\t\t    blen += strlen(&buf[blen]);\n\t\t    break;\n\t\t}\n#endif\t/* defined(_WIN32) && !defined(__BORLANDC__) */\n\t\tfmt_setup(fbuf, *p, flags, width, prec);\n\t\tneed = 0;\n\t\tif (*p != 'e' && *p != 'E') {\n\t\t    i = INT_MIN;\n\t\t    frexp(fval, &i);\n\t\t    if (i > 0)\n\t\t\tneed = BIT_DIGITS(i);\n\t\t}\n\t\tneed += (flags&FPREC) ? prec : 6;\n\t\tif ((flags&FWIDTH) && need < width)\n\t\t    need = width;\n\t\tneed += 20;\n\n\t\tCHECK(need);\n\t\tsprintf(&buf[blen], fbuf, fval);\n\t\tblen += strlen(&buf[blen]);\n\t    }\n\t    break;\n\t}\n\tflags = FNONE;\n    }\n\n  sprint_exit:\n    /* XXX - We cannot validiate the number of arguments if (digit)$ style used.\n     */\n    if (posarg >= 0 && nextarg < argc) {\n\tconst char *mesg = \"too many arguments for format string\";\n\tif (RTEST(ruby_debug)) rb_raise(rb_eArgError, mesg);\n\tif (RTEST(ruby_verbose)) rb_warn(mesg);\n    }\n    rb_str_resize(result, blen);\n\n    if (tainted) OBJ_TAINT(result);\n    return result;\n}\n\nstatic void\nfmt_setup(buf, c, flags, width, prec)\n    char *buf;\n    int c;\n    int flags, width, prec;\n{\n    *buf++ = '%';\n    if (flags & FSHARP) *buf++ = '#';\n    if (flags & FPLUS)  *buf++ = '+';\n    if (flags & FMINUS) *buf++ = '-';\n    if (flags & FZERO)  *buf++ = '0';\n    if (flags & FSPACE) *buf++ = ' ';\n\n    if (flags & FWIDTH) {\n\tsprintf(buf, \"%d\", width);\n\tbuf += strlen(buf);\n    }\n\n    if (flags & FPREC) {\n\tsprintf(buf, \".%d\", prec);\n\tbuf += strlen(buf);\n    }\n\n    *buf++ = c;\n    *buf = '\\0';\n}\n"
  },
  {
    "path": "st.c",
    "content": "/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */\n\n/* static       char    sccsid[] = \"@(#) st.c 5.1 89/12/14 Crucible\"; */\n\n#include \"config.h\"\n#include \"defines.h\"\n#include <stdio.h>\n#ifdef HAVE_STDLIB_H\n#include <stdlib.h>\n#endif\n#include <string.h>\n#include \"st.h\"\n\ntypedef struct st_table_entry st_table_entry;\n\nstruct st_table_entry {\n    unsigned int hash;\n    st_data_t key;\n    st_data_t record;\n    st_table_entry *next;\n};\n\n#define ST_DEFAULT_MAX_DENSITY 5\n#define ST_DEFAULT_INIT_TABLE_SIZE 11\n\n    /*\n     * DEFAULT_MAX_DENSITY is the default for the largest we allow the\n     * average number of items per bin before increasing the number of\n     * bins\n     *\n     * DEFAULT_INIT_TABLE_SIZE is the default for the number of bins\n     * allocated initially\n     *\n     */\nstatic int numcmp(long, long);\nstatic int numhash(long);\nstatic struct st_hash_type type_numhash = {\n    numcmp,\n    numhash,\n};\n\n/* extern int strcmp(const char *, const char *); */\nstatic struct st_hash_type type_strhash = {\n    strcmp,\n    strhash,\n};\n\nstatic void rehash(st_table *);\n\n#ifdef RUBY\n#define malloc xmalloc\n#define calloc xcalloc\n#endif\n\n#define alloc(type) (type*)malloc((unsigned)sizeof(type))\n#define Calloc(n,s) (char*)calloc((n),(s))\n\n#define EQUAL(table,x,y) ((x)==(y) || (*table->type->compare)((x),(y)) == 0)\n\n#define do_hash(key,table) (unsigned int)(*(table)->type->hash)((key))\n#define do_hash_bin(key,table) (do_hash(key, table)%(table)->num_bins)\n\n/*\n * MINSIZE is the minimum size of a dictionary.\n */\n\n#define MINSIZE 8\n\n/*\nTable of prime numbers 2^n+a, 2<=n<=30.\n*/\nstatic long primes[] = {\n        8 + 3,\n        16 + 3,\n        32 + 5,\n        64 + 3,\n        128 + 3,\n        256 + 27,\n        512 + 9,\n        1024 + 9,\n        2048 + 5,\n        4096 + 3,\n        8192 + 27,\n        16384 + 43,\n        32768 + 3,\n        65536 + 45,\n        131072 + 29,\n        262144 + 3,\n        524288 + 21,\n        1048576 + 7,\n        2097152 + 17,\n        4194304 + 15,\n        8388608 + 9,\n        16777216 + 43,\n        33554432 + 35,\n        67108864 + 15,\n        134217728 + 29,\n        268435456 + 3,\n        536870912 + 11,\n        1073741824 + 85,\n        0\n};\n\nstatic int\nnew_size(size)\n    int size;\n{\n    int i;\n\n#if 0\n    for (i=3; i<31; i++) {\n        if ((1<<i) > size) return 1<<i;\n    }\n    return -1;\n#else\n    int newsize;\n\n    for (i = 0, newsize = MINSIZE;\n         i < sizeof(primes)/sizeof(primes[0]);\n         i++, newsize <<= 1)\n    {\n        if (newsize > size) return primes[i];\n    }\n    /* Ran out of polynomials */\n    return -1;                  /* should raise exception */\n#endif\n}\n\n#ifdef HASH_LOG\nstatic int collision = 0;\nstatic int init_st = 0;\n\nstatic void\nstat_col()\n{\n    FILE *f = fopen(\"/tmp/col\", \"w\");\n    fprintf(f, \"collision: %d\\n\", collision);\n    fclose(f);\n}\n#endif\n\nst_table*\nst_init_table_with_size(type, size)\n    struct st_hash_type *type;\n    int size;\n{\n    st_table *tbl;\n\n#ifdef HASH_LOG\n    if (init_st == 0) {\n        init_st = 1;\n        atexit(stat_col);\n    }\n#endif\n\n    size = new_size(size);      /* round up to prime number */\n\n    tbl = alloc(st_table);\n    tbl->type = type;\n    tbl->num_entries = 0;\n    tbl->num_bins = size;\n    tbl->bins = (st_table_entry **)Calloc(size, sizeof(st_table_entry*));\n\n    return tbl;\n}\n\nst_table*\nst_init_table(type)\n    struct st_hash_type *type;\n{\n    return st_init_table_with_size(type, 0);\n}\n\nst_table*\nst_init_numtable(void)\n{\n    return st_init_table(&type_numhash);\n}\n\nst_table*\nst_init_numtable_with_size(size)\n    int size;\n{\n    return st_init_table_with_size(&type_numhash, size);\n}\n\nst_table*\nst_init_strtable(void)\n{\n    return st_init_table(&type_strhash);\n}\n\nst_table*\nst_init_strtable_with_size(size)\n    int size;\n{\n    return st_init_table_with_size(&type_strhash, size);\n}\n\nvoid\nst_free_table(table)\n    st_table *table;\n{\n    register st_table_entry *ptr, *next;\n    int i;\n\n    for(i = 0; i < table->num_bins; i++) {\n        ptr = table->bins[i];\n        while (ptr != 0) {\n            next = ptr->next;\n            free(ptr);\n            ptr = next;\n        }\n    }\n    free(table->bins);\n    free(table);\n}\n\n#define PTR_NOT_EQUAL(table, ptr, hash_val, key) \\\n((ptr) != 0 && (ptr->hash != (hash_val) || !EQUAL((table), (key), (ptr)->key)))\n\n#ifdef HASH_LOG\n#define COLLISION collision++\n#else\n#define COLLISION\n#endif\n\n#define FIND_ENTRY(table, ptr, hash_val, bin_pos) do {\\\n    bin_pos = hash_val%(table)->num_bins;\\\n    ptr = (table)->bins[bin_pos];\\\n    if (PTR_NOT_EQUAL(table, ptr, hash_val, key)) {\\\n        COLLISION;\\\n        while (PTR_NOT_EQUAL(table, ptr->next, hash_val, key)) {\\\n            ptr = ptr->next;\\\n        }\\\n        ptr = ptr->next;\\\n    }\\\n} while (0)\n\nint\nst_lookup(table, key, value)\n    st_table *table;\n    register st_data_t key;\n    st_data_t *value;\n{\n    unsigned int hash_val, bin_pos;\n    register st_table_entry *ptr;\n\n    hash_val = do_hash(key, table);\n    FIND_ENTRY(table, ptr, hash_val, bin_pos);\n\n    if (ptr == 0) {\n        return 0;\n    }\n    else {\n        if (value != 0)  *value = ptr->record;\n        return 1;\n    }\n}\n\n#define ADD_DIRECT(table, key, value, hash_val, bin_pos)\\\ndo {\\\n    st_table_entry *entry;\\\n    if (table->num_entries/(table->num_bins) > ST_DEFAULT_MAX_DENSITY) {\\\n        rehash(table);\\\n        bin_pos = hash_val % table->num_bins;\\\n    }\\\n    \\\n    entry = alloc(st_table_entry);\\\n    \\\n    entry->hash = hash_val;\\\n    entry->key = key;\\\n    entry->record = value;\\\n    entry->next = table->bins[bin_pos];\\\n    table->bins[bin_pos] = entry;\\\n    table->num_entries++;\\\n} while (0)\n\nint\nst_insert(table, key, value)\n    register st_table *table;\n    register st_data_t key;\n    st_data_t value;\n{\n    unsigned int hash_val, bin_pos;\n    register st_table_entry *ptr;\n\n    hash_val = do_hash(key, table);\n    FIND_ENTRY(table, ptr, hash_val, bin_pos);\n\n    if (ptr == 0) {\n        ADD_DIRECT(table, key, value, hash_val, bin_pos);\n        return 0;\n    }\n    else {\n        ptr->record = value;\n        return 1;\n    }\n}\n\nvoid\nst_add_direct(table, key, value)\n    st_table *table;\n    st_data_t key;\n    st_data_t value;\n{\n    unsigned int hash_val, bin_pos;\n\n    hash_val = do_hash(key, table);\n    bin_pos = hash_val % table->num_bins;\n    ADD_DIRECT(table, key, value, hash_val, bin_pos);\n}\n\nstatic void\nrehash(table)\n    register st_table *table;\n{\n    register st_table_entry *ptr, *next, **new_bins;\n    int i, old_num_bins = table->num_bins, new_num_bins;\n    unsigned int hash_val;\n\n    new_num_bins = new_size(old_num_bins+1);\n    new_bins = (st_table_entry**)Calloc(new_num_bins, sizeof(st_table_entry*));\n\n    for(i = 0; i < old_num_bins; i++) {\n        ptr = table->bins[i];\n        while (ptr != 0) {\n            next = ptr->next;\n            hash_val = ptr->hash % new_num_bins;\n            ptr->next = new_bins[hash_val];\n            new_bins[hash_val] = ptr;\n            ptr = next;\n        }\n    }\n    free(table->bins);\n    table->num_bins = new_num_bins;\n    table->bins = new_bins;\n}\n\nst_table*\nst_copy(old_table)\n    st_table *old_table;\n{\n    st_table *new_table;\n    st_table_entry *ptr, *entry;\n    int i, num_bins = old_table->num_bins;\n\n    new_table = alloc(st_table);\n    if (new_table == 0) {\n        return 0;\n    }\n\n    *new_table = *old_table;\n    new_table->bins = (st_table_entry**)\n        Calloc((unsigned)num_bins, sizeof(st_table_entry*));\n\n    if (new_table->bins == 0) {\n        free(new_table);\n        return 0;\n    }\n\n    for(i = 0; i < num_bins; i++) {\n        new_table->bins[i] = 0;\n        ptr = old_table->bins[i];\n        while (ptr != 0) {\n            entry = alloc(st_table_entry);\n            if (entry == 0) {\n                free(new_table->bins);\n                free(new_table);\n                return 0;\n            }\n            *entry = *ptr;\n            entry->next = new_table->bins[i];\n            new_table->bins[i] = entry;\n            ptr = ptr->next;\n        }\n    }\n    return new_table;\n}\n\nint\nst_delete(table, key, value)\n    register st_table *table;\n    register st_data_t *key;\n    st_data_t *value;\n{\n    unsigned int hash_val;\n    st_table_entry *tmp;\n    register st_table_entry *ptr;\n\n    hash_val = do_hash_bin(*key, table);\n    ptr = table->bins[hash_val];\n\n    if (ptr == 0) {\n        if (value != 0) *value = 0;\n        return 0;\n    }\n\n    if (EQUAL(table, *key, ptr->key)) {\n        table->bins[hash_val] = ptr->next;\n        table->num_entries--;\n        if (value != 0) *value = ptr->record;\n        *key = ptr->key;\n        free(ptr);\n        return 1;\n    }\n\n    for(; ptr->next != 0; ptr = ptr->next) {\n        if (EQUAL(table, ptr->next->key, *key)) {\n            tmp = ptr->next;\n            ptr->next = ptr->next->next;\n            table->num_entries--;\n            if (value != 0) *value = tmp->record;\n            *key = tmp->key;\n            free(tmp);\n            return 1;\n        }\n    }\n\n    return 0;\n}\n\nint\nst_delete_safe(table, key, value, never)\n    register st_table *table;\n    register st_data_t *key;\n    st_data_t *value;\n    st_data_t never;\n{\n    unsigned int hash_val;\n    register st_table_entry *ptr;\n\n    hash_val = do_hash_bin(*key, table);\n    ptr = table->bins[hash_val];\n\n    if (ptr == 0) {\n        if (value != 0) *value = 0;\n        return 0;\n    }\n\n    for(; ptr != 0; ptr = ptr->next) {\n        if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) {\n            table->num_entries--;\n            *key = ptr->key;\n            if (value != 0) *value = ptr->record;\n            ptr->key = ptr->record = never;\n            return 1;\n        }\n    }\n\n    return 0;\n}\n\nstatic int\ndelete_never(key, value, never)\n    st_data_t key, value, never;\n{\n    if (value == never) return ST_DELETE;\n    return ST_CONTINUE;\n}\n\nvoid\nst_cleanup_safe(table, never)\n    st_table *table;\n    st_data_t never;\n{\n    int num_entries = table->num_entries;\n\n    st_foreach(table, delete_never, never);\n    table->num_entries = num_entries;\n}\n\nvoid\nst_foreach_map(table, map_key_func, map_value_func)\n    st_table *table;\n    st_data_t (*map_key_func)();\n    st_data_t (*map_value_func)();\n{\n    st_table_entry *ptr;\n    st_data_t new_key;\n    int i;\n\n    for(i = 0; i < table->num_bins; i++) {\n        for(ptr = table->bins[i]; ptr != 0; ptr = ptr->next) {\n            new_key = (*map_key_func)(ptr->key);\n            if(new_key != ptr->key && table->type->compare(new_key, ptr->key)) {\n                rb_bug(\"Key replaced with non-equal key\");\n            }\n            ptr->key = new_key;\n            ptr->record = (*map_value_func)(ptr->record);\n        }\n    }\n}\n\nint\nst_foreach(table, func, arg)\n    st_table *table;\n    int (*func)();\n    st_data_t arg;\n{\n    st_table_entry *ptr, *last, *tmp;\n    enum st_retval retval;\n    int i;\n\n    for(i = 0; i < table->num_bins; i++) {\n        last = 0;\n        for(ptr = table->bins[i]; ptr != 0;) {\n            retval = (*func)(ptr->key, ptr->record, arg);\n            switch (retval) {\n            case ST_CHECK:      /* check if hash is modified during iteration */\n                tmp = 0;\n                if (i < table->num_bins) {\n                    for (tmp = table->bins[i]; tmp; tmp=tmp->next) {\n                        if (tmp == ptr) break;\n                    }\n                }\n                if (!tmp) {\n                    /* call func with error notice */\n                    return 1;\n                }\n                /* fall through */\n            case ST_CONTINUE:\n                last = ptr;\n                ptr = ptr->next;\n                break;\n            case ST_STOP:\n                return 0;\n            case ST_DELETE:\n                tmp = ptr;\n                if (last == 0) {\n                    table->bins[i] = ptr->next;\n                }\n                else {\n                    last->next = ptr->next;\n                }\n                ptr = ptr->next;\n                free(tmp);\n                table->num_entries--;\n            }\n        }\n    }\n    return 0;\n}\n\nint\nstrhash(string)\n    register const char *string;\n{\n    register int c;\n\n#ifdef HASH_ELFHASH\n    register unsigned int h = 0, g;\n\n    while ((c = *string++) != '\\0') {\n        h = ( h << 4 ) + c;\n        if ( g = h & 0xF0000000 )\n            h ^= g >> 24;\n        h &= ~g;\n    }\n    return h;\n#elif defined(HASH_PERL)\n    register int val = 0;\n\n    while ((c = *string++) != '\\0') {\n        val += c;\n        val += (val << 10);\n        val ^= (val >> 6);\n    }\n    val += (val << 3);\n    val ^= (val >> 11);\n\n    return val + (val << 15);\n#else\n    register int val = 0;\n\n    while ((c = *string++) != '\\0') {\n        val = val*997 + c;\n    }\n\n    return val + (val>>5);\n#endif\n}\n\nstatic int\nnumcmp(x, y)\n    long x, y;\n{\n    return x != y;\n}\n\nstatic int\nnumhash(n)\n    long n;\n{\n    return n;\n}\n"
  },
  {
    "path": "st.h",
    "content": "/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */\n\n/* @(#) st.h 5.1 89/12/14 */\n\n#ifndef ST_INCLUDED\n\n#define ST_INCLUDED\n\n#if SIZEOF_LONG == SIZEOF_VOIDP\ntypedef unsigned long st_data_t;\n#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP\ntypedef unsigned LONG_LONG st_data_t;\n#else\n# error ---->> st.c requires sizeof(void*) == sizeof(long) to be compiled. <<---\n-\n#endif\n#define ST_DATA_T_DEFINED\n\ntypedef struct st_table st_table;\n\nstruct st_hash_type {\n    int (*compare)();\n    int (*hash)();\n};\n\nstruct st_table {\n    struct st_hash_type *type;\n    int num_bins;\n    int num_entries;\n    struct st_table_entry **bins;\n};\n\n#define st_is_member(table,key) st_lookup(table,key,(st_data_t *)0)\n\nenum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};\n\n#ifndef _\n# define _(args) args\n#endif\n#ifndef ANYARGS\n# ifdef __cplusplus\n#   define ANYARGS ...\n# else\n#   define ANYARGS\n# endif\n#endif\n\nst_table *st_init_table _((struct st_hash_type *));\nst_table *st_init_table_with_size _((struct st_hash_type *, int));\nst_table *st_init_numtable _((void));\nst_table *st_init_numtable_with_size _((int));\nst_table *st_init_strtable _((void));\nst_table *st_init_strtable_with_size _((int));\nint st_delete _((st_table *, st_data_t *, st_data_t *));\nint st_delete_safe _((st_table *, st_data_t *, st_data_t *, st_data_t));\nint st_insert _((st_table *, st_data_t, st_data_t));\nint st_lookup _((st_table *, st_data_t, st_data_t *));\nint st_foreach _((st_table *, int (*)(ANYARGS), st_data_t));\nvoid st_foreach_map _((st_table*, st_data_t (*)(ANYARGS), st_data_t (*)(ANYARGS)));\nvoid st_add_direct _((st_table *, st_data_t, st_data_t));\nvoid st_free_table _((st_table *));\nvoid st_cleanup_safe _((st_table *, st_data_t));\nst_table *st_copy _((st_table *));\n\n#define ST_NUMCMP\t((int (*)()) 0)\n#define ST_NUMHASH\t((int (*)()) -2)\n\n#define st_numcmp\tST_NUMCMP\n#define st_numhash\tST_NUMHASH\n\nint st_strhash();\nint strhash(const char *);\n#endif /* ST_INCLUDED */\n"
  },
  {
    "path": "string.c",
    "content": "/**********************************************************************\n\n  string.c -\n\n  $Author$\n  $Date$\n  created at: Mon Aug  9 17:12:58 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"re.h\"\n\n#define BEG(no) regs->beg[no]\n#define END(no) regs->end[no]\n\n#include <math.h>\n#include <ctype.h>\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\nVALUE rb_cString;\n\n#define STR_TMPLOCK FL_USER1\n#define STR_ASSOC   FL_USER3\n#define STR_NOCAPA  (ELTS_SHARED|STR_ASSOC)\n\n#define RESIZE_CAPA(str,capacity) do {\\\n    REALLOC_N(RSTRING(str)->ptr, char, (capacity)+1);\\\n    if (!FL_TEST(str, STR_NOCAPA))\\\n        RSTRING(str)->aux.capa = (capacity);\\\n} while (0)\n\nVALUE rb_fs;\n\nstatic inline void\nstr_mod_check(s, p, len)\n    VALUE s;\n    char *p;\n    long len;\n{\n    if (RSTRING(s)->ptr != p || RSTRING(s)->len != len) {\n        rb_raise(rb_eRuntimeError, \"string modified\");\n    }\n}\n\nstatic inline void\nstr_frozen_check(s)\n    VALUE s;\n{\n    if (OBJ_FROZEN(s)) {\n        rb_raise(rb_eRuntimeError, \"string frozen\");\n    }\n}\n\nstatic VALUE\nstr_alloc_eden(klass)\n    VALUE klass;\n{\n    NEWOBJ_EDEN(str, struct RString);\n    OBJSETUP(str, klass, T_STRING);\n\n    str->ptr = 0;\n    str->len = 0;\n    str->aux.capa = 0;\n\n    return (VALUE)str;\n}\n\nstatic VALUE\nstr_alloc_longlife(klass)\n    VALUE klass;\n{\n    NEWOBJ_LONGLIFE(str, struct RString);\n    OBJSETUP(str, klass, T_STRING);\n\n    str->ptr = 0;\n    str->len = 0;\n    str->aux.capa = 0;\n\n    return (VALUE)str;\n}\n\nstatic VALUE\nstr_alloc(klass)\n    VALUE klass;\n{\n    if (ruby_in_longlife_context) {\n        return str_alloc_longlife(klass);\n    } else {\n        return str_alloc_eden(klass);\n    }\n}\n\nstatic VALUE\nstr_new(klass, ptr, len)\n    VALUE klass;\n    const char *ptr;\n    long len;\n{\n    VALUE str;\n\n    if (len < 0) {\n        rb_raise(rb_eArgError, \"negative string size (or size too big)\");\n    }\n\n    str = str_alloc(klass);\n    RSTRING(str)->len = len;\n    RSTRING(str)->aux.capa = len;\n    RSTRING(str)->ptr = ALLOC_N(char,len+1);\n    if (ptr) {\n        memcpy(RSTRING(str)->ptr, ptr, len);\n    }\n    RSTRING(str)->ptr[len] = '\\0';\n    return str;\n}\n\nVALUE\nrb_str_new(ptr, len)\n    const char *ptr;\n    long len;\n{\n    return str_new(rb_cString, ptr, len);\n}\n\nVALUE\nrb_str_new2(ptr)\n    const char *ptr;\n{\n    if (!ptr) {\n        rb_raise(rb_eArgError, \"NULL pointer given\");\n    }\n    return rb_str_new(ptr, strlen(ptr));\n}\n\nVALUE\nrb_tainted_str_new(ptr, len)\n    const char *ptr;\n    long len;\n{\n    VALUE str = rb_str_new(ptr, len);\n\n    OBJ_TAINT(str);\n    return str;\n}\n\nVALUE\nrb_tainted_str_new2(ptr)\n    const char *ptr;\n{\n    VALUE str = rb_str_new2(ptr);\n\n    OBJ_TAINT(str);\n    return str;\n}\n\nstatic VALUE\nstr_new3(klass, str)\n    VALUE klass, str;\n{\n    VALUE str2 = str_alloc(klass);\n\n    RSTRING(str2)->len = RSTRING(str)->len;\n    RSTRING(str2)->ptr = RSTRING(str)->ptr;\n    RSTRING(str2)->aux.shared = str;\n    FL_SET(str2, ELTS_SHARED);\n\n    return str2;\n}\n\nVALUE\nrb_str_new3(str)\n    VALUE str;\n{\n    VALUE str2 = str_new3(rb_obj_class(str), str);\n\n    OBJ_INFECT(str2, str);\n    return str2;\n}\n\nstatic VALUE\nstr_new4(klass, str)\n    VALUE klass, str;\n{\n    VALUE str2 = str_alloc(klass);\n\n    RSTRING(str2)->len = RSTRING(str)->len;\n    RSTRING(str2)->ptr = RSTRING(str)->ptr;\n    if (FL_TEST(str, ELTS_SHARED)) {\n        FL_SET(str2, ELTS_SHARED);\n        RSTRING(str2)->aux.shared = RSTRING(str)->aux.shared;\n    }\n    else {\n        FL_SET(str, ELTS_SHARED);\n        RSTRING(str)->aux.shared = str2;\n        maybe_add_to_longlife_recent_allocations(str);\n    }\n\n    return str2;\n}\n\nVALUE\nrb_str_new4(orig)\n    VALUE orig;\n{\n    VALUE klass, str;\n\n    if (OBJ_FROZEN(orig)) return orig;\n    klass = rb_obj_class(orig);\n    if (FL_TEST(orig, ELTS_SHARED) && (str = RSTRING(orig)->aux.shared) && klass == RBASIC(str)->klass) {\n        long ofs;\n        ofs = RSTRING(str)->len - RSTRING(orig)->len;\n        if ((ofs > 0) || (!OBJ_TAINTED(str) && OBJ_TAINTED(orig))) {\n            str = str_new3(klass, str);\n            RSTRING(str)->ptr += ofs;\n            RSTRING(str)->len -= ofs;\n        }\n    }\n    else if (FL_TEST(orig, STR_ASSOC)) {\n        str = str_new(klass, RSTRING(orig)->ptr, RSTRING(orig)->len);\n    }\n    else {\n        str = str_new4(klass, orig);\n    }\n    OBJ_INFECT(str, orig);\n    OBJ_FREEZE(str);\n    return str;\n}\n\nVALUE\nrb_str_new5(obj, ptr, len)\n    VALUE obj;\n    const char *ptr;\n    long len;\n{\n    return str_new(rb_obj_class(obj), ptr, len);\n}\n\n#define STR_BUF_MIN_SIZE 128\n\nVALUE\nrb_str_buf_new(capa)\n    long capa;\n{\n    VALUE str = str_alloc(rb_cString);\n\n    if (capa < STR_BUF_MIN_SIZE) {\n        capa = STR_BUF_MIN_SIZE;\n    }\n    RSTRING(str)->ptr = 0;\n    RSTRING(str)->len = 0;\n    RSTRING(str)->aux.capa = capa;\n    RSTRING(str)->ptr = ALLOC_N(char, capa+1);\n    RSTRING(str)->ptr[0] = '\\0';\n\n    return str;\n}\n\nVALUE\nrb_str_buf_new2(ptr)\n    const char *ptr;\n{\n    VALUE str;\n    long len = strlen(ptr);\n\n    str = rb_str_buf_new(len);\n    rb_str_buf_cat(str, ptr, len);\n\n    return str;\n}\n\nVALUE\nrb_str_tmp_new(len)\n    long len;\n{\n    return str_new(0, 0, len);\n}\n\nVALUE\nrb_str_to_str(str)\n    VALUE str;\n{\n    return rb_convert_type(str, T_STRING, \"String\", \"to_str\");\n}\n\nstatic void\nrb_str_shared_replace(str, str2)\n    VALUE str, str2;\n{\n    if (str == str2) return;\n    rb_str_modify(str);\n    if (!FL_TEST(str, ELTS_SHARED)) free(RSTRING(str)->ptr);\n    if (NIL_P(str2)) {\n        RSTRING(str)->ptr = 0;\n        RSTRING(str)->len = 0;\n        RSTRING(str)->aux.capa = 0;\n        FL_UNSET(str, STR_NOCAPA);\n        return;\n    }\n    RSTRING(str)->ptr = RSTRING(str2)->ptr;\n    RSTRING(str)->len = RSTRING(str2)->len;\n    FL_UNSET(str, STR_NOCAPA);\n    if (FL_TEST(str2, STR_NOCAPA)) {\n        FL_SET(str, RBASIC(str2)->flags & STR_NOCAPA);\n        RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;\n    }\n    else {\n        RSTRING(str)->aux.capa = RSTRING(str2)->aux.capa;\n    }\n    RSTRING(str2)->ptr = 0;     /* abandon str2 */\n    RSTRING(str2)->len = 0;\n    RSTRING(str2)->aux.capa = 0;\n    FL_UNSET(str2, STR_NOCAPA);\n    if (OBJ_TAINTED(str2)) OBJ_TAINT(str);\n    maybe_add_to_longlife_recent_allocations(str);\n}\n\nstatic ID id_to_s;\n\nVALUE\nrb_obj_as_string(obj)\n    VALUE obj;\n{\n    VALUE str;\n\n    if (TYPE(obj) == T_STRING) {\n        return obj;\n    }\n    str = rb_funcall(obj, id_to_s, 0);\n    if (TYPE(str) != T_STRING)\n        return rb_any_to_s(obj);\n    if (OBJ_TAINTED(obj)) OBJ_TAINT(str);\n    return str;\n}\n\nstatic VALUE rb_str_s_alloc _((VALUE));\nstatic VALUE rb_str_replace _((VALUE, VALUE));\n\nVALUE\nrb_str_dup(str)\n    VALUE str;\n{\n    VALUE dup = str_alloc(rb_obj_class(str));\n    rb_str_replace(dup, str);\n    return dup;\n}\n\n/*\n *  call-seq:\n *     String.new(str=\"\")   => new_str\n *\n *  Returns a new string object containing a copy of <i>str</i>.\n */\n\nstatic VALUE\nrb_str_init(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE orig;\n\n    if (rb_scan_args(argc, argv, \"01\", &orig) == 1)\n        rb_str_replace(str, orig);\n    return str;\n}\n\n/*\n *  call-seq:\n *     str.length   => integer\n *\n *  Returns the length of <i>str</i>.\n */\n\nstatic VALUE\nrb_str_length(str)\n    VALUE str;\n{\n    return LONG2NUM(RSTRING(str)->len);\n}\n\n/*\n *  call-seq:\n *     str.empty?   => true or false\n *\n *  Returns <code>true</code> if <i>str</i> has a length of zero.\n *\n *     \"hello\".empty?   #=> false\n *     \"\".empty?        #=> true\n */\n\nstatic VALUE\nrb_str_empty(str)\n    VALUE str;\n{\n    if (RSTRING(str)->len == 0)\n        return Qtrue;\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     str + other_str   => new_str\n *\n *  Concatenation---Returns a new <code>String</code> containing\n *  <i>other_str</i> concatenated to <i>str</i>.\n *\n *     \"Hello from \" + self.to_s   #=> \"Hello from main\"\n */\n\nVALUE\nrb_str_plus(str1, str2)\n    VALUE str1, str2;\n{\n    VALUE str3;\n\n    StringValue(str2);\n    str3 = rb_str_new(0, RSTRING(str1)->len+RSTRING(str2)->len);\n    memcpy(RSTRING(str3)->ptr, RSTRING(str1)->ptr, RSTRING(str1)->len);\n    memcpy(RSTRING(str3)->ptr + RSTRING(str1)->len,\n           RSTRING(str2)->ptr, RSTRING(str2)->len);\n    RSTRING(str3)->ptr[RSTRING(str3)->len] = '\\0';\n\n    if (OBJ_TAINTED(str1) || OBJ_TAINTED(str2))\n        OBJ_TAINT(str3);\n    return str3;\n}\n\n/*\n *  call-seq:\n *     str * integer   => new_str\n *\n *  Copy---Returns a new <code>String</code> containing <i>integer</i> copies of\n *  the receiver.\n *\n *     \"Ho! \" * 3   #=> \"Ho! Ho! Ho! \"\n */\n\nVALUE\nrb_str_times(str, times)\n    VALUE str;\n    VALUE times;\n{\n    VALUE str2;\n    long i, len;\n\n    len = NUM2LONG(times);\n    if (len < 0) {\n        rb_raise(rb_eArgError, \"negative argument\");\n    }\n    if (len && LONG_MAX/len <  RSTRING(str)->len) {\n        rb_raise(rb_eArgError, \"argument too big\");\n    }\n\n    str2 = rb_str_new5(str,0, len *= RSTRING(str)->len);\n    for (i = 0; i < len; i += RSTRING(str)->len) {\n        memcpy(RSTRING(str2)->ptr + i,\n               RSTRING(str)->ptr, RSTRING(str)->len);\n    }\n    RSTRING(str2)->ptr[RSTRING(str2)->len] = '\\0';\n\n    OBJ_INFECT(str2, str);\n\n    return str2;\n}\n\n/*\n *  call-seq:\n *     str % arg   => new_str\n *\n *  Format---Uses <i>str</i> as a format specification, and returns the result\n *  of applying it to <i>arg</i>. If the format specification contains more than\n *  one substitution, then <i>arg</i> must be an <code>Array</code> containing\n *  the values to be substituted. See <code>Kernel::sprintf</code> for details\n *  of the format string.\n *\n *     \"%05d\" % 123                       #=> \"00123\"\n *     \"%-5s: %08x\" % [ \"ID\", self.id ]   #=> \"ID   : 200e14d6\"\n */\n\nstatic VALUE\nrb_str_format_m(str, arg)\n    VALUE str, arg;\n{\n    volatile VALUE tmp = rb_check_array_type(arg);\n\n    if (!NIL_P(tmp)) {\n        return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);\n    }\n    return rb_str_format(1, &arg, str);\n}\n\nstatic const char null_str[] = \"\";\n\nstatic int\nstr_independent(str)\n    VALUE str;\n{\n    if (FL_TEST(str, STR_TMPLOCK)) {\n        rb_raise(rb_eRuntimeError, \"can't modify string; temporarily locked\");\n    }\n    if (OBJ_FROZEN(str)) rb_error_frozen(\"string\");\n    if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)\n        rb_raise(rb_eSecurityError, \"Insecure: can't modify string\");\n    if (RSTRING(str)->ptr == null_str) return 0;\n    if (!FL_TEST(str, ELTS_SHARED)) return 1;\n    return 0;\n}\n\nstatic void\nstr_make_independent(str)\n    VALUE str;\n{\n    char *ptr;\n\n    ptr = ALLOC_N(char, RSTRING(str)->len+1);\n    if (RSTRING(str)->ptr) {\n        memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len);\n    }\n    ptr[RSTRING(str)->len] = 0;\n    RSTRING(str)->ptr = ptr;\n    RSTRING(str)->aux.capa = RSTRING(str)->len;\n    FL_UNSET(str, STR_NOCAPA);\n}\n\nvoid\nrb_str_modify(str)\n    VALUE str;\n{\n    if (!str_independent(str))\n        str_make_independent(str);\n}\n\nvoid\nrb_str_associate(str, add)\n    VALUE str, add;\n{\n    if (FL_TEST(str, STR_ASSOC)) {\n        /* already associated */\n        rb_ary_concat(RSTRING(str)->aux.shared, add);\n    }\n    else {\n        if (FL_TEST(str, ELTS_SHARED)) {\n            str_make_independent(str);\n        }\n        else if (RSTRING(str)->aux.capa != RSTRING(str)->len) {\n            RESIZE_CAPA(str, RSTRING(str)->len);\n        }\n        RSTRING(str)->aux.shared = add;\n        FL_SET(str, STR_ASSOC);\n        maybe_add_to_longlife_recent_allocations(str);\n    }\n}\n\nVALUE\nrb_str_associated(str)\n    VALUE str;\n{\n    if (FL_TEST(str, STR_ASSOC)) {\n        return RSTRING(str)->aux.shared;\n    }\n    return Qfalse;\n}\n\n#define make_null_str(s) do { \\\n        FL_SET(s, ELTS_SHARED); \\\n        RSTRING(s)->ptr = (char *)null_str; \\\n        RSTRING(s)->aux.shared = 0; \\\n    } while (0)\n\nstatic VALUE\nrb_str_s_alloc(klass)\n    VALUE klass;\n{\n    VALUE str = str_alloc(klass);\n    make_null_str(str);\n    return str;\n}\n\nVALUE\nrb_string_value(ptr)\n    volatile VALUE *ptr;\n{\n    VALUE s = *ptr;\n    if (TYPE(s) != T_STRING) {\n        s = rb_str_to_str(s);\n        *ptr = s;\n    }\n    if (!RSTRING(s)->ptr) {\n        make_null_str(s);\n    }\n    return s;\n}\n\nchar *\nrb_string_value_ptr(ptr)\n    volatile VALUE *ptr;\n{\n    return RSTRING(rb_string_value(ptr))->ptr;\n}\n\nchar *\nrb_string_value_cstr(ptr)\n    volatile VALUE *ptr;\n{\n    VALUE str = rb_string_value(ptr);\n    char *s = RSTRING(str)->ptr;\n\n    if (!s || RSTRING(str)->len != strlen(s)) {\n        rb_raise(rb_eArgError, \"string contains null byte\");\n    }\n    return s;\n}\n\nVALUE\nrb_check_string_type(str)\n    VALUE str;\n{\n    str = rb_check_convert_type(str, T_STRING, \"String\", \"to_str\");\n    if (!NIL_P(str) && !RSTRING(str)->ptr) {\n        make_null_str(str);\n    }\n    return str;\n}\n\nVALUE\nrb_str_substr(str, beg, len)\n    VALUE str;\n    long beg, len;\n{\n    VALUE str2;\n\n    if (len < 0) return Qnil;\n    if (beg > RSTRING(str)->len) return Qnil;\n    if (beg < 0) {\n        beg += RSTRING(str)->len;\n        if (beg < 0) return Qnil;\n    }\n    if (beg + len > RSTRING(str)->len) {\n        len = RSTRING(str)->len - beg;\n    }\n    if (len < 0) {\n        len = 0;\n    }\n    if (len == 0) {\n        str2 = rb_str_new5(str,0,0);\n    }\n    else if (len > sizeof(struct RString)/2 &&\n        beg + len == RSTRING(str)->len && !FL_TEST(str, STR_ASSOC)) {\n        str2 = rb_str_new4(str);\n        str2 = str_new3(rb_obj_class(str2), str2);\n        RSTRING(str2)->ptr += RSTRING(str2)->len - len;\n        RSTRING(str2)->len = len;\n    }\n    else {\n        str2 = rb_str_new5(str, RSTRING(str)->ptr+beg, len);\n    }\n    OBJ_INFECT(str2, str);\n\n    return str2;\n}\n\n#ifdef GC_DEBUG\nVALUE\nrb_str_char_ptr(VALUE str)\n{\n    return LONG2FIX(RSTRING(str)->ptr);\n}\n#endif\n\nVALUE\nrb_str_move(str2)\n    VALUE str2;\n{\n    VALUE str;\n\n    int len = RSTRING(str2)->len;\n    char *ptr = RSTRING(str2)->ptr;\n\n    str = str_alloc_longlife(rb_obj_class(str2));\n    RSTRING(str)->len = len;\n    RSTRING(str)->aux.capa = len;\n    RSTRING(str)->ptr = ALLOC_N(char,len+1);\n    if (ptr) {\n        memcpy(RSTRING(str)->ptr, ptr, len);\n    }\n    RSTRING(str)->ptr[len] = '\\0';\n\n    OBJ_FREEZE(str2);\n    OBJ_INFECT(str, str2);\n#ifdef GC_DEBUG\n    longlife_moved_objs_count++;\n#endif\n    return str;\n}\n\nVALUE\nrb_str_dup_frozen(str)\n    VALUE str;\n{\n    if (FL_TEST(str, ELTS_SHARED) && RSTRING(str)->aux.shared) {\n        VALUE shared = RSTRING(str)->aux.shared;\n        if (RSTRING(shared)->len == RSTRING(str)->len) {\n            OBJ_FREEZE(shared);\n            return shared;\n        }\n    }\n    if (OBJ_FROZEN(str)) return str;\n    str = rb_str_dup(str);\n    OBJ_FREEZE(str);\n    return str;\n}\n\nVALUE\nrb_str_locktmp(str)\n    VALUE str;\n{\n    if (FL_TEST(str, STR_TMPLOCK)) {\n        rb_raise(rb_eRuntimeError, \"temporal locking already locked string\");\n    }\n    FL_SET(str, STR_TMPLOCK);\n    return str;\n}\n\nVALUE\nrb_str_unlocktmp(str)\n    VALUE str;\n{\n    if (!FL_TEST(str, STR_TMPLOCK)) {\n        rb_raise(rb_eRuntimeError, \"temporal unlocking already unlocked string\");\n    }\n    FL_UNSET(str, STR_TMPLOCK);\n    return str;\n}\n\nvoid\nrb_str_set_len(VALUE str, long len)\n{\n    RSTRING(str)->len = len;\n    RSTRING(str)->ptr[len] = '\\0';\n}\n\nVALUE\nrb_str_resize(str, len)\n    VALUE str;\n    long len;\n{\n    if (len < 0) {\n        rb_raise(rb_eArgError, \"negative string size (or size too big)\");\n    }\n\n    rb_str_modify(str);\n    if (len != RSTRING(str)->len) {\n        if (RSTRING(str)->len < len || RSTRING(str)->len - len > 1024) {\n            REALLOC_N(RSTRING(str)->ptr, char, len+1);\n            if (!FL_TEST(str, STR_NOCAPA)) {\n                RSTRING(str)->aux.capa = len;\n            }\n        }\n        RSTRING(str)->len = len;\n        RSTRING(str)->ptr[len] = '\\0';  /* sentinel */\n    }\n    return str;\n}\n\nstatic VALUE\nstr_buf_cat(str, ptr, len)\n    VALUE str;\n    const char *ptr;\n    long len;\n{\n    long capa, total, off = -1;;\n\n    rb_str_modify(str);\n    if (ptr >= RSTRING(str)->ptr && ptr <= RSTRING(str)->ptr + RSTRING(str)->len) {\n        off = ptr - RSTRING(str)->ptr;\n    }\n    if (len == 0) return 0;\n    if (FL_TEST(str, STR_ASSOC)) {\n        FL_UNSET(str, STR_ASSOC);\n        capa = RSTRING(str)->aux.capa = RSTRING(str)->len;\n    }\n    else {\n        capa = RSTRING(str)->aux.capa;\n    }\n    if (RSTRING(str)->len >= LONG_MAX - len) {\n        rb_raise(rb_eArgError, \"string sizes too big\");\n    }\n    total = RSTRING(str)->len+len;\n    if (capa <= total) {\n        while (total > capa) {\n            if (capa + 1 >= LONG_MAX / 2) {\n                capa = total;\n                break;\n            }\n            capa = (capa + 1) * 2;\n        }\n        RESIZE_CAPA(str, capa);\n    }\n    if (off != -1) {\n        ptr = RSTRING(str)->ptr + off;\n    }\n    memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);\n    RSTRING(str)->len = total;\n    RSTRING(str)->ptr[total] = '\\0'; /* sentinel */\n\n    return str;\n}\n\nVALUE\nrb_str_buf_cat(str, ptr, len)\n    VALUE str;\n    const char *ptr;\n    long len;\n{\n    if (len == 0) return str;\n    if (len < 0) {\n        rb_raise(rb_eArgError, \"negative string size (or size too big)\");\n    }\n    return str_buf_cat(str, ptr, len);\n}\n\nVALUE\nrb_str_buf_cat2(str, ptr)\n    VALUE str;\n    const char *ptr;\n{\n    return rb_str_buf_cat(str, ptr, strlen(ptr));\n}\n\nVALUE\nrb_str_cat(str, ptr, len)\n    VALUE str;\n    const char *ptr;\n    long len;\n{\n    if (len < 0) {\n        rb_raise(rb_eArgError, \"negative string size (or size too big)\");\n    }\n    if (FL_TEST(str, STR_ASSOC)) {\n        rb_str_modify(str);\n        REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len+1);\n        memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);\n        RSTRING(str)->len += len;\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0'; /* sentinel */\n        return str;\n    }\n\n    return rb_str_buf_cat(str, ptr, len);\n}\n\nVALUE\nrb_str_cat2(str, ptr)\n    VALUE str;\n    const char *ptr;\n{\n    return rb_str_cat(str, ptr, strlen(ptr));\n}\n\nVALUE\nrb_str_buf_append(str, str2)\n    VALUE str, str2;\n{\n    str_buf_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);\n    OBJ_INFECT(str, str2);\n    return str;\n}\n\nVALUE\nrb_str_append(str, str2)\n    VALUE str, str2;\n{\n    StringValue(str2);\n    rb_str_modify(str);\n    if (RSTRING(str2)->len > 0) {\n        if (FL_TEST(str, STR_ASSOC)) {\n            long len = RSTRING(str)->len+RSTRING(str2)->len;\n            REALLOC_N(RSTRING(str)->ptr, char, len+1);\n            memcpy(RSTRING(str)->ptr + RSTRING(str)->len,\n                   RSTRING(str2)->ptr, RSTRING(str2)->len);\n            RSTRING(str)->ptr[len] = '\\0'; /* sentinel */\n            RSTRING(str)->len = len;\n        }\n        else {\n            return rb_str_buf_append(str, str2);\n        }\n    }\n    OBJ_INFECT(str, str2);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str << fixnum        => str\n *     str.concat(fixnum)   => str\n *     str << obj           => str\n *     str.concat(obj)      => str\n *\n *  Append---Concatenates the given object to <i>str</i>. If the object is a\n *  <code>Fixnum</code> between 0 and 255, it is converted to a character before\n *  concatenation.\n *\n *     a = \"hello \"\n *     a << \"world\"   #=> \"hello world\"\n *     a.concat(33)   #=> \"hello world!\"\n */\n\nVALUE\nrb_str_concat(str1, str2)\n    VALUE str1, str2;\n{\n    if (FIXNUM_P(str2)) {\n        int i = FIX2INT(str2);\n        if (0 <= i && i <= 0xff) { /* byte */\n            char c = i;\n            return rb_str_cat(str1, &c, 1);\n        }\n    }\n    str1 = rb_str_append(str1, str2);\n\n    return str1;\n}\n\nint\nrb_str_hash(str)\n    VALUE str;\n{\n    register long len = RSTRING(str)->len;\n    register char *p = RSTRING(str)->ptr;\n    register int key = 0;\n\n#if defined(HASH_ELFHASH)\n    register unsigned int g;\n\n    while (len--) {\n        key = (key << 4) + *p++;\n        if (g = key & 0xF0000000)\n            key ^= g >> 24;\n        key &= ~g;\n    }\n#elif defined(HASH_PERL)\n    while (len--) {\n        key += *p++;\n        key += (key << 10);\n        key ^= (key >> 6);\n    }\n    key += (key << 3);\n    key ^= (key >> 11);\n    key += (key << 15);\n#else\n    while (len--) {\n        key = key*65599 + *p;\n        p++;\n    }\n    key = key + (key>>5);\n#endif\n    return key;\n}\n\n/*\n * call-seq:\n *    str.hash   => fixnum\n *\n * Return a hash based on the string's length and content.\n */\n\nstatic VALUE\nrb_str_hash_m(str)\n    VALUE str;\n{\n    int key = rb_str_hash(str);\n    return INT2FIX(key);\n}\n\n#define lesser(a,b) (((a)>(b))?(b):(a))\n\nint\nrb_str_cmp(str1, str2)\n    VALUE str1, str2;\n{\n    long len;\n    int retval;\n\n    len = lesser(RSTRING(str1)->len, RSTRING(str2)->len);\n    retval = rb_memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr, len);\n    if (retval == 0) {\n        if (RSTRING(str1)->len == RSTRING(str2)->len) return 0;\n        if (RSTRING(str1)->len > RSTRING(str2)->len) return 1;\n        return -1;\n    }\n    if (retval > 0) return 1;\n    return -1;\n}\n\n\n/*\n *  call-seq:\n *     str == obj   => true or false\n *\n *  Equality---If <i>obj</i> is not a <code>String</code>, returns\n *  <code>false</code>. Otherwise, returns <code>true</code> if <i>str</i>\n *  <code><=></code> <i>obj</i> returns zero.\n */\n\nstatic VALUE\nrb_str_equal(str1, str2)\n    VALUE str1, str2;\n{\n    if (str1 == str2) return Qtrue;\n    if (TYPE(str2) != T_STRING) {\n        if (!rb_respond_to(str2, rb_intern(\"to_str\"))) {\n            return Qfalse;\n        }\n        return rb_equal(str2, str1);\n    }\n    if (RSTRING(str1)->len == RSTRING(str2)->len &&\n        rb_str_cmp(str1, str2) == 0) {\n        return Qtrue;\n    }\n    return Qfalse;\n}\n\n#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))\n\n/*\n * call-seq:\n *   str.eql?(other)   => true or false\n *\n * Two strings are equal if the have the same length and content.\n */\n\nstatic VALUE\nrb_str_eql(str1, str2)\n    VALUE str1, str2;\n{\n    if (TYPE(str2) != T_STRING || RSTRING(str1)->len != RSTRING(str2)->len)\n        return Qfalse;\n\n    if (memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr,\n               lesser(RSTRING(str1)->len, RSTRING(str2)->len)) == 0)\n        return Qtrue;\n\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     str <=> other_str   => -1, 0, +1\n *\n *  Comparison---Returns -1 if <i>other_str</i> is less than, 0 if\n *  <i>other_str</i> is equal to, and +1 if <i>other_str</i> is greater than\n *  <i>str</i>. If the strings are of different lengths, and the strings are\n *  equal when compared up to the shortest length, then the longer string is\n *  considered greater than the shorter one. If the variable <code>$=</code> is\n *  <code>false</code>, the comparison is based on comparing the binary values\n *  of each character in the string. In older versions of Ruby, setting\n *  <code>$=</code> allowed case-insensitive comparisons; this is now deprecated\n *  in favor of using <code>String#casecmp</code>.\n *\n *  <code><=></code> is the basis for the methods <code><</code>,\n *  <code><=</code>, <code>></code>, <code>>=</code>, and <code>between?</code>,\n *  included from module <code>Comparable</code>.  The method\n *  <code>String#==</code> does not use <code>Comparable#==</code>.\n *\n *     \"abcdef\" <=> \"abcde\"     #=> 1\n *     \"abcdef\" <=> \"abcdef\"    #=> 0\n *     \"abcdef\" <=> \"abcdefg\"   #=> -1\n *     \"abcdef\" <=> \"ABCDEF\"    #=> 1\n */\n\nstatic VALUE\nrb_str_cmp_m(str1, str2)\n    VALUE str1, str2;\n{\n    long result;\n\n    if (TYPE(str2) != T_STRING) {\n        if (!rb_respond_to(str2, rb_intern(\"to_str\"))) {\n            return Qnil;\n        }\n        else if (!rb_respond_to(str2, rb_intern(\"<=>\"))) {\n            return Qnil;\n        }\n        else {\n            VALUE tmp = rb_funcall(str2, rb_intern(\"<=>\"), 1, str1);\n\n            if (NIL_P(tmp)) return Qnil;\n            if (!FIXNUM_P(tmp)) {\n                return rb_funcall(LONG2FIX(0), '-', 1, tmp);\n            }\n            result = -FIX2LONG(tmp);\n        }\n    }\n    else {\n        result = rb_str_cmp(str1, str2);\n    }\n    return LONG2NUM(result);\n}\n\n/*\n *  call-seq:\n *     str.casecmp(other_str)   => -1, 0, +1\n *\n *  Case-insensitive version of <code>String#<=></code>.\n *\n *     \"abcdef\".casecmp(\"abcde\")     #=> 1\n *     \"aBcDeF\".casecmp(\"abcdef\")    #=> 0\n *     \"abcdef\".casecmp(\"abcdefg\")   #=> -1\n *     \"abcdef\".casecmp(\"ABCDEF\")    #=> 0\n */\n\nstatic VALUE\nrb_str_casecmp(str1, str2)\n    VALUE str1, str2;\n{\n    long len;\n    int retval;\n\n    StringValue(str2);\n    len = lesser(RSTRING(str1)->len, RSTRING(str2)->len);\n    retval = rb_memcicmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr, len);\n    if (retval == 0) {\n        if (RSTRING(str1)->len == RSTRING(str2)->len) return INT2FIX(0);\n        if (RSTRING(str1)->len > RSTRING(str2)->len) return INT2FIX(1);\n        return INT2FIX(-1);\n    }\n    if (retval == 0) return INT2FIX(0);\n    if (retval > 0) return INT2FIX(1);\n    return INT2FIX(-1);\n}\n\nstatic long\nrb_str_index(str, sub, offset)\n    VALUE str, sub;\n    long offset;\n{\n    long pos;\n\n    if (offset < 0) {\n        offset += RSTRING(str)->len;\n        if (offset < 0) return -1;\n    }\n    if (RSTRING(str)->len - offset < RSTRING(sub)->len) return -1;\n    if (RSTRING(sub)->len == 0) return offset;\n    pos = rb_memsearch(RSTRING(sub)->ptr, RSTRING(sub)->len,\n                       RSTRING(str)->ptr+offset, RSTRING(str)->len-offset);\n    if (pos < 0) return pos;\n    return pos + offset;\n}\n\n\n/*\n *  call-seq:\n *     str.index(substring [, offset])   => fixnum or nil\n *     str.index(fixnum [, offset])      => fixnum or nil\n *     str.index(regexp [, offset])      => fixnum or nil\n *\n *  Returns the index of the first occurrence of the given <i>substring</i>,\n *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns\n *  <code>nil</code> if not found. If the second parameter is present, it\n *  specifies the position in the string to begin the search.\n *\n *     \"hello\".index('e')             #=> 1\n *     \"hello\".index('lo')            #=> 3\n *     \"hello\".index('a')             #=> nil\n *     \"hello\".index(101)             #=> 1\n *     \"hello\".index(/[aeiou]/, -3)   #=> 4\n */\n\nstatic VALUE\nrb_str_index_m(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE sub;\n    VALUE initpos;\n    long pos;\n\n    if (rb_scan_args(argc, argv, \"11\", &sub, &initpos) == 2) {\n        pos = NUM2LONG(initpos);\n    }\n    else {\n        pos = 0;\n    }\n    if (pos < 0) {\n        pos += RSTRING(str)->len;\n        if (pos < 0) {\n            if (TYPE(sub) == T_REGEXP) {\n                rb_backref_set(Qnil);\n            }\n            return Qnil;\n        }\n    }\n\n    switch (TYPE(sub)) {\n      case T_REGEXP:\n        pos = rb_reg_adjust_startpos(sub, str, pos, 0);\n        pos = rb_reg_search(sub, str, pos, 0);\n        break;\n\n      case T_FIXNUM: {\n        int c = FIX2INT(sub);\n        long len = RSTRING(str)->len;\n        unsigned char *p = (unsigned char*)RSTRING(str)->ptr;\n\n        for (;pos<len;pos++) {\n            if (p[pos] == c) return LONG2NUM(pos);\n        }\n        return Qnil;\n      }\n\n      default: {\n        VALUE tmp;\n\n        tmp = rb_check_string_type(sub);\n        if (NIL_P(tmp)) {\n            rb_raise(rb_eTypeError, \"type mismatch: %s given\",\n                     rb_obj_classname(sub));\n        }\n        sub = tmp;\n      }\n        /* fall through */\n      case T_STRING:\n        pos = rb_str_index(str, sub, pos);\n        break;\n    }\n\n    if (pos == -1) return Qnil;\n    return LONG2NUM(pos);\n}\n\nstatic long\nrb_str_rindex(str, sub, pos)\n    VALUE str, sub;\n    long pos;\n{\n    long len = RSTRING(sub)->len;\n    char *s, *sbeg, *t;\n\n    /* substring longer than string */\n    if (RSTRING(str)->len < len) return -1;\n    if (RSTRING(str)->len - pos < len) {\n        pos = RSTRING(str)->len - len;\n    }\n    sbeg = RSTRING(str)->ptr;\n    s = RSTRING(str)->ptr + pos;\n    t = RSTRING(sub)->ptr;\n    if (len) {\n        while (sbeg <= s) {\n            if (rb_memcmp(s, t, len) == 0) {\n                return s - RSTRING(str)->ptr;\n            }\n            s--;\n        }\n        return -1;\n    }\n    else {\n        return pos;\n    }\n}\n\n\n/*\n *  call-seq:\n *     str.rindex(substring [, fixnum])   => fixnum or nil\n *     str.rindex(fixnum [, fixnum])   => fixnum or nil\n *     str.rindex(regexp [, fixnum])   => fixnum or nil\n *\n *  Returns the index of the last occurrence of the given <i>substring</i>,\n *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns\n *  <code>nil</code> if not found. If the second parameter is present, it\n *  specifies the position in the string to end the search---characters beyond\n *  this point will not be considered.\n *\n *     \"hello\".rindex('e')             #=> 1\n *     \"hello\".rindex('l')             #=> 3\n *     \"hello\".rindex('a')             #=> nil\n *     \"hello\".rindex(101)             #=> 1\n *     \"hello\".rindex(/[aeiou]/, -2)   #=> 1\n */\n\nstatic VALUE\nrb_str_rindex_m(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE sub;\n    VALUE position;\n    long pos;\n\n    if (rb_scan_args(argc, argv, \"11\", &sub, &position) == 2) {\n        pos = NUM2LONG(position);\n        if (pos < 0) {\n            pos += RSTRING(str)->len;\n            if (pos < 0) {\n                if (TYPE(sub) == T_REGEXP) {\n                    rb_backref_set(Qnil);\n                }\n                return Qnil;\n            }\n        }\n        if (pos > RSTRING(str)->len) pos = RSTRING(str)->len;\n    }\n    else {\n        pos = RSTRING(str)->len;\n    }\n\n    switch (TYPE(sub)) {\n      case T_REGEXP:\n        if (RREGEXP(sub)->len) {\n            pos = rb_reg_adjust_startpos(sub, str, pos, 1);\n            pos = rb_reg_search(sub, str, pos, 1);\n        }\n        if (pos >= 0) return LONG2NUM(pos);\n        break;\n\n      default: {\n        VALUE tmp;\n\n        tmp = rb_check_string_type(sub);\n        if (NIL_P(tmp)) {\n            rb_raise(rb_eTypeError, \"type mismatch: %s given\",\n                     rb_obj_classname(sub));\n        }\n        sub = tmp;\n      }\n        /* fall through */\n      case T_STRING:\n        pos = rb_str_rindex(str, sub, pos);\n        if (pos >= 0) return LONG2NUM(pos);\n        break;\n\n      case T_FIXNUM: {\n        int c = FIX2INT(sub);\n        unsigned char *p = (unsigned char*)RSTRING(str)->ptr + pos;\n        unsigned char *pbeg = (unsigned char*)RSTRING(str)->ptr;\n\n        if (pos == RSTRING(str)->len) {\n            if (pos == 0) return Qnil;\n            --p;\n        }\n        while (pbeg <= p) {\n            if (*p == c) return LONG2NUM((char*)p - RSTRING(str)->ptr);\n            p--;\n        }\n        return Qnil;\n      }\n    }\n    return Qnil;\n}\n\n/*\n *  call-seq:\n *     str =~ obj   => fixnum or nil\n *\n *  Match---If <i>obj</i> is a <code>Regexp</code>, use it as a pattern to match\n *  against <i>str</i>,and returns the position the match starts, or\n *  <code>nil</code> if there is no match. Otherwise, invokes\n *  <i>obj.=~</i>, passing <i>str</i> as an argument. The default\n *  <code>=~</code> in <code>Object</code> returns <code>false</code>.\n *\n *     \"cat o' 9 tails\" =~ /\\d/   #=> 7\n *     \"cat o' 9 tails\" =~ 9      #=> false\n */\n\nstatic VALUE\nrb_str_match(x, y)\n    VALUE x, y;\n{\n    switch (TYPE(y)) {\n      case T_STRING:\n        rb_raise(rb_eTypeError, \"type mismatch: String given\");\n\n      case T_REGEXP:\n        return rb_reg_match(y, x);\n\n      default:\n        return rb_funcall(y, rb_intern(\"=~\"), 1, x);\n    }\n}\n\n\nstatic VALUE get_pat _((VALUE, int));\n\n\n/*\n *  call-seq:\n *     str.match(pattern)   => matchdata or nil\n *\n *  Converts <i>pattern</i> to a <code>Regexp</code> (if it isn't already one),\n *  then invokes its <code>match</code> method on <i>str</i>.\n *\n *     'hello'.match('(.)\\1')      #=> #<MatchData:0x401b3d30>\n *     'hello'.match('(.)\\1')[0]   #=> \"ll\"\n *     'hello'.match(/(.)\\1/)[0]   #=> \"ll\"\n *     'hello'.match('xx')         #=> nil\n */\n\nstatic VALUE\nrb_str_match_m(str, re)\n    VALUE str, re;\n{\n    return rb_funcall(get_pat(re, 0), rb_intern(\"match\"), 1, str);\n}\n\nstatic char\nsucc_char(s)\n    char *s;\n{\n    char c = *s;\n\n    /* numerics */\n    if ('0' <= c && c < '9') (*s)++;\n    else if (c == '9') {\n        *s = '0';\n        return '1';\n    }\n    /* small alphabets */\n    else if ('a' <= c && c < 'z') (*s)++;\n    else if (c == 'z') {\n        return *s = 'a';\n    }\n    /* capital alphabets */\n    else if ('A' <= c && c < 'Z') (*s)++;\n    else if (c == 'Z') {\n        return *s = 'A';\n    }\n    return 0;\n}\n\n\n/*\n *  call-seq:\n *     str.succ   => new_str\n *     str.next   => new_str\n *\n *  Returns the successor to <i>str</i>. The successor is calculated by\n *  incrementing characters starting from the rightmost alphanumeric (or\n *  the rightmost character if there are no alphanumerics) in the\n *  string. Incrementing a digit always results in another digit, and\n *  incrementing a letter results in another letter of the same case.\n *  Incrementing nonalphanumerics uses the underlying character set's\n *  collating sequence.\n *\n *  If the increment generates a ``carry,'' the character to the left of\n *  it is incremented. This process repeats until there is no carry,\n *  adding an additional character if necessary.\n *\n *     \"abcd\".succ        #=> \"abce\"\n *     \"THX1138\".succ     #=> \"THX1139\"\n *     \"<<koala>>\".succ   #=> \"<<koalb>>\"\n *     \"1999zzz\".succ     #=> \"2000aaa\"\n *     \"ZZZ9999\".succ     #=> \"AAAA0000\"\n *     \"***\".succ         #=> \"**+\"\n */\n\nstatic VALUE\nrb_str_succ(orig)\n    VALUE orig;\n{\n    VALUE str;\n    char *sbeg, *s;\n    int c = -1;\n    long n = 0;\n\n    str = rb_str_new5(orig, RSTRING(orig)->ptr, RSTRING(orig)->len);\n    OBJ_INFECT(str, orig);\n    if (RSTRING(str)->len == 0) return str;\n\n    sbeg = RSTRING(str)->ptr; s = sbeg + RSTRING(str)->len - 1;\n\n    while (sbeg <= s) {\n        if (ISALNUM(*s)) {\n            if ((c = succ_char(s)) == 0) break;\n            n = s - sbeg;\n        }\n        s--;\n    }\n    if (c == -1) {              /* str contains no alnum */\n        sbeg = RSTRING(str)->ptr; s = sbeg + RSTRING(str)->len - 1;\n        c = '\\001';\n        while (sbeg <= s) {\n            if ((*s += 1) != 0) break;\n            s--;\n        }\n    }\n    if (s < sbeg) {\n        RESIZE_CAPA(str, RSTRING(str)->len + 1);\n        s = RSTRING(str)->ptr + n;\n        memmove(s+1, s, RSTRING(str)->len - n);\n        *s = c;\n        RSTRING(str)->len += 1;\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n    }\n\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.succ!   => str\n *     str.next!   => str\n *\n *  Equivalent to <code>String#succ</code>, but modifies the receiver in\n *  place.\n */\n\nstatic VALUE\nrb_str_succ_bang(str)\n    VALUE str;\n{\n    rb_str_shared_replace(str, rb_str_succ(str));\n\n    return str;\n}\n\nVALUE\nrb_str_upto(beg, end, excl)\n    VALUE beg, end;\n    int excl;\n{\n    VALUE current, after_end;\n    ID succ = rb_intern(\"succ\");\n    int n;\n\n    StringValue(end);\n    n = rb_str_cmp(beg, end);\n    if (n > 0 || (excl && n == 0)) return beg;\n    after_end = rb_funcall(end, succ, 0, 0);\n    current = beg;\n    while (!rb_str_equal(current, after_end)) {\n        rb_yield(current);\n        if (!excl && rb_str_equal(current, end)) break;\n        current = rb_funcall(current, succ, 0, 0);\n        StringValue(current);\n        if (excl && rb_str_equal(current, end)) break;\n        StringValue(current);\n        if (RSTRING(current)->len > RSTRING(end)->len || RSTRING(current)->len == 0)\n            break;\n    }\n\n    return beg;\n}\n\n\n/*\n *  call-seq:\n *     str.upto(other_str, exclusive=false) {|s| block }   => str\n *\n *  Iterates through successive values, starting at <i>str</i> and\n *  ending at <i>other_str</i> inclusive, passing each value in turn to\n *  the block. The <code>String#succ</code> method is used to generate\n *  each value.  If optional second argument exclusive is omitted or is <code>false</code>,\n *  the last value will be included; otherwise it will be excluded.\n *\n *     \"a8\".upto(\"b6\") {|s| print s, ' ' }\n *     for s in \"a8\"..\"b6\"\n *       print s, ' '\n *     end\n *\n *  <em>produces:</em>\n *\n *     a8 a9 b0 b1 b2 b3 b4 b5 b6\n *     a8 a9 b0 b1 b2 b3 b4 b5 b6\n */\n\nstatic VALUE\nrb_str_upto_m(argc, argv, beg)\n    int argc;\n    VALUE *argv;\n    VALUE beg;\n{\n    VALUE end, exclusive;\n\n    rb_scan_args(argc, argv, \"11\", &end, &exclusive);\n\n    return rb_str_upto(beg, end, RTEST(exclusive));\n}\n\nstatic VALUE\nrb_str_subpat(str, re, nth)\n    VALUE str, re;\n    int nth;\n{\n    if (rb_reg_search(re, str, 0, 0) >= 0) {\n        return rb_reg_nth_match(nth, rb_backref_get());\n    }\n    return Qnil;\n}\n\nstatic VALUE\nrb_str_aref(str, indx)\n    VALUE str;\n    VALUE indx;\n{\n    long idx;\n\n    switch (TYPE(indx)) {\n      case T_FIXNUM:\n        idx = FIX2LONG(indx);\n\n      num_index:\n        if (idx < 0) {\n            idx = RSTRING(str)->len + idx;\n        }\n        if (idx < 0 || RSTRING(str)->len <= idx) {\n            return Qnil;\n        }\n        return INT2FIX(RSTRING(str)->ptr[idx] & 0xff);\n\n      case T_REGEXP:\n        return rb_str_subpat(str, indx, 0);\n\n      case T_STRING:\n        if (rb_str_index(str, indx, 0) != -1)\n            return rb_str_dup(indx);\n        return Qnil;\n\n      default:\n        /* check if indx is Range */\n        {\n            long beg, len;\n            VALUE tmp;\n\n            switch (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 0)) {\n              case Qfalse:\n                break;\n              case Qnil:\n                return Qnil;\n              default:\n                tmp = rb_str_substr(str, beg, len);\n                OBJ_INFECT(tmp, indx);\n                return tmp;\n            }\n        }\n        idx = NUM2LONG(indx);\n        goto num_index;\n    }\n    return Qnil;                /* not reached */\n}\n\n\n/*\n *  call-seq:\n *     str[fixnum]                 => fixnum or nil\n *     str[fixnum, fixnum]         => new_str or nil\n *     str[range]                  => new_str or nil\n *     str[regexp]                 => new_str or nil\n *     str[regexp, fixnum]         => new_str or nil\n *     str[other_str]              => new_str or nil\n *     str.slice(fixnum)           => fixnum or nil\n *     str.slice(fixnum, fixnum)   => new_str or nil\n *     str.slice(range)            => new_str or nil\n *     str.slice(regexp)           => new_str or nil\n *     str.slice(regexp, fixnum)   => new_str or nil\n *     str.slice(other_str)        => new_str or nil\n *\n *  Element Reference---If passed a single <code>Fixnum</code>, returns the code\n *  of the character at that position. If passed two <code>Fixnum</code>\n *  objects, returns a substring starting at the offset given by the first, and\n *  a length given by the second. If given a range, a substring containing\n *  characters at offsets given by the range is returned. In all three cases, if\n *  an offset is negative, it is counted from the end of <i>str</i>. Returns\n *  <code>nil</code> if the initial offset falls outside the string, the length\n *  is negative, or the beginning of the range is greater than the end.\n *\n *  If a <code>Regexp</code> is supplied, the matching portion of <i>str</i> is\n *  returned. If a numeric parameter follows the regular expression, that\n *  component of the <code>MatchData</code> is returned instead. If a\n *  <code>String</code> is given, that string is returned if it occurs in\n *  <i>str</i>. In both cases, <code>nil</code> is returned if there is no\n *  match.\n *\n *     a = \"hello there\"\n *     a[1]                   #=> 101\n *     a[1,3]                 #=> \"ell\"\n *     a[1..3]                #=> \"ell\"\n *     a[-3,2]                #=> \"er\"\n *     a[-4..-2]              #=> \"her\"\n *     a[12..-1]              #=> nil\n *     a[-2..-4]              #=> \"\"\n *     a[/[aeiou](.)\\1/]      #=> \"ell\"\n *     a[/[aeiou](.)\\1/, 0]   #=> \"ell\"\n *     a[/[aeiou](.)\\1/, 1]   #=> \"l\"\n *     a[/[aeiou](.)\\1/, 2]   #=> nil\n *     a[\"lo\"]                #=> \"lo\"\n *     a[\"bye\"]               #=> nil\n */\n\nstatic VALUE\nrb_str_aref_m(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    if (argc == 2) {\n        if (TYPE(argv[0]) == T_REGEXP) {\n            return rb_str_subpat(str, argv[0], NUM2INT(argv[1]));\n        }\n        return rb_str_substr(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]));\n    }\n    if (argc != 1) {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 1)\", argc);\n    }\n    return rb_str_aref(str, argv[0]);\n}\n\nstatic void\nrb_str_splice(str, beg, len, val)\n    VALUE str;\n    long beg, len;\n    VALUE val;\n{\n    if (len < 0) rb_raise(rb_eIndexError, \"negative length %ld\", len);\n\n    StringValue(val);\n    rb_str_modify(str);\n\n    if (RSTRING(str)->len < beg) {\n      out_of_range:\n        rb_raise(rb_eIndexError, \"index %ld out of string\", beg);\n    }\n    if (beg < 0) {\n        if (-beg > RSTRING(str)->len) {\n            goto out_of_range;\n        }\n        beg += RSTRING(str)->len;\n    }\n    if (RSTRING(str)->len < len || RSTRING(str)->len < beg + len) {\n        len = RSTRING(str)->len - beg;\n    }\n\n    if (len < RSTRING(val)->len) {\n        /* expand string */\n        RESIZE_CAPA(str, RSTRING(str)->len + RSTRING(val)->len - len + 1);\n    }\n\n    if (RSTRING(val)->len != len) {\n        memmove(RSTRING(str)->ptr + beg + RSTRING(val)->len,\n                RSTRING(str)->ptr + beg + len,\n                RSTRING(str)->len - (beg + len));\n    }\n    if (RSTRING(str)->len < beg && len < 0) {\n        MEMZERO(RSTRING(str)->ptr + RSTRING(str)->len, char, -len);\n    }\n    if (RSTRING(val)->len > 0) {\n        memmove(RSTRING(str)->ptr+beg, RSTRING(val)->ptr, RSTRING(val)->len);\n    }\n    RSTRING(str)->len += RSTRING(val)->len - len;\n    if (RSTRING(str)->ptr) {\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n    }\n    OBJ_INFECT(str, val);\n}\n\nvoid\nrb_str_update(str, beg, len, val)\n    VALUE str;\n    long beg, len;\n    VALUE val;\n{\n    rb_str_splice(str, beg, len, val);\n}\n\nstatic void\nrb_str_subpat_set(str, re, nth, val)\n    VALUE str, re;\n    int nth;\n    VALUE val;\n{\n    VALUE match;\n    long start, end, len;\n\n    if (rb_reg_search(re, str, 0, 0) < 0) {\n        rb_raise(rb_eIndexError, \"regexp not matched\");\n    }\n    match = rb_backref_get();\n    if (nth >= RMATCH(match)->regs->num_regs) {\n      out_of_range:\n        rb_raise(rb_eIndexError, \"index %d out of regexp\", nth);\n    }\n    if (nth < 0) {\n        if (-nth >= RMATCH(match)->regs->num_regs) {\n            goto out_of_range;\n        }\n        nth += RMATCH(match)->regs->num_regs;\n    }\n\n    start = RMATCH(match)->BEG(nth);\n    if (start == -1) {\n        rb_raise(rb_eIndexError, \"regexp group %d not matched\", nth);\n    }\n    end = RMATCH(match)->END(nth);\n    len = end - start;\n    rb_str_splice(str, start, len, val);\n}\n\nstatic VALUE\nrb_str_aset(str, indx, val)\n    VALUE str;\n    VALUE indx, val;\n{\n    long idx, beg;\n\n    switch (TYPE(indx)) {\n      case T_FIXNUM:\n        idx = FIX2LONG(indx);\n      num_index:\n        if (RSTRING(str)->len <= idx) {\n          out_of_range:\n            rb_raise(rb_eIndexError, \"index %ld out of string\", idx);\n        }\n        if (idx < 0) {\n            if (-idx > RSTRING(str)->len)\n                goto out_of_range;\n            idx += RSTRING(str)->len;\n        }\n        if (FIXNUM_P(val)) {\n            rb_str_modify(str);\n            if (RSTRING(str)->len == idx) {\n                RSTRING(str)->len += 1;\n                RESIZE_CAPA(str, RSTRING(str)->len);\n            }\n            RSTRING(str)->ptr[idx] = FIX2INT(val) & 0xff;\n        }\n        else {\n            rb_str_splice(str, idx, 1, val);\n        }\n        return val;\n\n      case T_REGEXP:\n        rb_str_subpat_set(str, indx, 0, val);\n        return val;\n\n      case T_STRING:\n        beg = rb_str_index(str, indx, 0);\n        if (beg < 0) {\n            rb_raise(rb_eIndexError, \"string not matched\");\n        }\n        rb_str_splice(str, beg, RSTRING(indx)->len, val);\n        return val;\n\n      default:\n        /* check if indx is Range */\n        {\n            long beg, len;\n            if (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 2)) {\n                rb_str_splice(str, beg, len, val);\n                return val;\n            }\n        }\n        idx = NUM2LONG(indx);\n        goto num_index;\n    }\n}\n\n/*\n *  call-seq:\n *     str[fixnum] = fixnum\n *     str[fixnum] = new_str\n *     str[fixnum, fixnum] = new_str\n *     str[range] = aString\n *     str[regexp] = new_str\n *     str[regexp, fixnum] = new_str\n *     str[other_str] = new_str\n *\n *  Element Assignment---Replaces some or all of the content of <i>str</i>. The\n *  portion of the string affected is determined using the same criteria as\n *  <code>String#[]</code>. If the replacement string is not the same length as\n *  the text it is replacing, the string will be adjusted accordingly. If the\n *  regular expression or string is used as the index doesn't match a position\n *  in the string, <code>IndexError</code> is raised. If the regular expression\n *  form is used, the optional second <code>Fixnum</code> allows you to specify\n *  which portion of the match to replace (effectively using the\n *  <code>MatchData</code> indexing rules. The forms that take a\n *  <code>Fixnum</code> will raise an <code>IndexError</code> if the value is\n *  out of range; the <code>Range</code> form will raise a\n *  <code>RangeError</code>, and the <code>Regexp</code> and <code>String</code>\n *  forms will silently ignore the assignment.\n */\n\nstatic VALUE\nrb_str_aset_m(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    if (argc == 3) {\n        if (TYPE(argv[0]) == T_REGEXP) {\n            rb_str_subpat_set(str, argv[0], NUM2INT(argv[1]), argv[2]);\n        }\n        else {\n            rb_str_splice(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);\n        }\n        return argv[2];\n    }\n    if (argc != 2) {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 2)\", argc);\n    }\n    return rb_str_aset(str, argv[0], argv[1]);\n}\n\n/*\n *  call-seq:\n *     str.insert(index, other_str)   => str\n *\n *  Inserts <i>other_str</i> before the character at the given\n *  <i>index</i>, modifying <i>str</i>. Negative indices count from the\n *  end of the string, and insert <em>after</em> the given character.\n *  The intent is insert <i>aString</i> so that it starts at the given\n *  <i>index</i>.\n *\n *     \"abcd\".insert(0, 'X')    #=> \"Xabcd\"\n *     \"abcd\".insert(3, 'X')    #=> \"abcXd\"\n *     \"abcd\".insert(4, 'X')    #=> \"abcdX\"\n *     \"abcd\".insert(-3, 'X')   #=> \"abXcd\"\n *     \"abcd\".insert(-1, 'X')   #=> \"abcdX\"\n */\n\nstatic VALUE\nrb_str_insert(str, idx, str2)\n    VALUE str, idx, str2;\n{\n    long pos = NUM2LONG(idx);\n\n    if (pos == -1) {\n        pos = RSTRING(str)->len;\n    }\n    else if (pos < 0) {\n        pos++;\n    }\n    rb_str_splice(str, pos, 0, str2);\n    return str;\n}\n\n/*\n *  call-seq:\n *     str.slice!(fixnum)           => fixnum or nil\n *     str.slice!(fixnum, fixnum)   => new_str or nil\n *     str.slice!(range)            => new_str or nil\n *     str.slice!(regexp)           => new_str or nil\n *     str.slice!(other_str)        => new_str or nil\n *\n *  Deletes the specified portion from <i>str</i>, and returns the portion\n *  deleted. The forms that take a <code>Fixnum</code> will raise an\n *  <code>IndexError</code> if the value is out of range; the <code>Range</code>\n *  form will raise a <code>RangeError</code>, and the <code>Regexp</code> and\n *  <code>String</code> forms will silently ignore the assignment.\n *\n *     string = \"this is a string\"\n *     string.slice!(2)        #=> 105\n *     string.slice!(3..6)     #=> \" is \"\n *     string.slice!(/s.*t/)   #=> \"sa st\"\n *     string.slice!(\"r\")      #=> \"r\"\n *     string                  #=> \"thing\"\n */\n\nstatic VALUE\nrb_str_slice_bang(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE result;\n    VALUE buf[3];\n    int i;\n\n    if (argc < 1 || 2 < argc) {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 1)\", argc);\n    }\n    for (i=0; i<argc; i++) {\n        buf[i] = argv[i];\n    }\n    buf[i] = rb_str_new(0,0);\n    result = rb_str_aref_m(argc, buf, str);\n    if (!NIL_P(result)) {\n        rb_str_aset_m(argc+1, buf, str);\n    }\n    return result;\n}\n\nstatic VALUE\nget_pat(pat, quote)\n    VALUE pat;\n    int quote;\n{\n    VALUE val;\n\n    switch (TYPE(pat)) {\n      case T_REGEXP:\n        return pat;\n\n      case T_STRING:\n        break;\n\n      default:\n        val = rb_check_string_type(pat);\n        if (NIL_P(val)) {\n            Check_Type(pat, T_REGEXP);\n        }\n        pat = val;\n    }\n\n    if (quote) {\n        pat = rb_reg_quote(pat);\n    }\n\n    return rb_reg_regcomp(pat);\n}\n\nstatic VALUE\nget_pat_quoted(pat)\n     VALUE pat;\n{\n    return get_pat(pat, 1);\n}\n\nstatic VALUE\nregcomp_failed(str)\n    VALUE str;\n{\n    rb_raise(rb_eArgError, \"invalid byte sequence\");\n    /*NOTREACHED*/\n    return Qundef;\n}\n\nstatic VALUE\nget_arg_pat(pat, quote)\n     VALUE pat;\n{\n    return rb_rescue2(get_pat_quoted, pat,\n                      regcomp_failed, pat,\n                      rb_eRegexpError, (VALUE)0);\n}\n\n/*\n *  call-seq:\n *     str.sub!(pattern, replacement)          => str or nil\n *     str.sub!(pattern) {|match| block }      => str or nil\n *\n *  Performs the substitutions of <code>String#sub</code> in place,\n *  returning <i>str</i>, or <code>nil</code> if no substitutions were\n *  performed.\n */\n\nstatic VALUE\nrb_str_sub_bang(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE pat, repl, match;\n    struct re_registers *regs;\n    int iter = 0;\n    int tainted = 0;\n    long plen;\n\n    if (argc == 1 && rb_block_given_p()) {\n        iter = 1;\n    }\n    else if (argc == 2) {\n        repl = argv[1];\n        StringValue(repl);\n        if (OBJ_TAINTED(repl)) tainted = 1;\n    }\n    else {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 2)\", argc);\n    }\n\n    pat = get_pat(argv[0], 1);\n    if (rb_reg_search(pat, str, 0, 0) >= 0) {\n        match = rb_backref_get();\n        regs = RMATCH(match)->regs;\n\n        if (iter) {\n            char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len;\n\n            rb_match_busy(match);\n            repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));\n            str_mod_check(str, p, len);\n            str_frozen_check(str);\n            rb_backref_set(match);\n        }\n        else {\n            repl = rb_reg_regsub(repl, str, regs);\n        }\n        rb_str_modify(str);\n        if (OBJ_TAINTED(repl)) tainted = 1;\n        plen = END(0) - BEG(0);\n        if (RSTRING(repl)->len > plen) {\n            RESIZE_CAPA(str, RSTRING(str)->len + RSTRING(repl)->len - plen);\n        }\n        if (RSTRING(repl)->len != plen) {\n            memmove(RSTRING(str)->ptr + BEG(0) + RSTRING(repl)->len,\n                    RSTRING(str)->ptr + BEG(0) + plen,\n                    RSTRING(str)->len - BEG(0) - plen);\n        }\n        memcpy(RSTRING(str)->ptr + BEG(0),\n               RSTRING(repl)->ptr, RSTRING(repl)->len);\n        RSTRING(str)->len += RSTRING(repl)->len - plen;\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n        if (tainted) OBJ_TAINT(str);\n        return str;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.sub(pattern, replacement)         => new_str\n *     str.sub(pattern) {|match| block }     => new_str\n *\n *  Returns a copy of <i>str</i> with the <em>first</em> occurrence of\n *  <i>pattern</i> replaced with either <i>replacement</i> or the value of the\n *  block. The <i>pattern</i> will typically be a <code>Regexp</code>; if it is\n *  a <code>String</code> then no regular expression metacharacters will be\n *  interpreted (that is <code>/\\d/</code> will match a digit, but\n *  <code>'\\d'</code> will match a backslash followed by a 'd').\n *\n *  If the method call specifies <i>replacement</i>, special variables such as\n *  <code>$&</code> will not be useful, as substitution into the string occurs\n *  before the pattern match starts. However, the sequences <code>\\1</code>,\n *  <code>\\2</code>, etc., may be used.\n *\n *  In the block form, the current match string is passed in as a parameter, and\n *  variables such as <code>$1</code>, <code>$2</code>, <code>$`</code>,\n *  <code>$&</code>, and <code>$'</code> will be set appropriately. The value\n *  returned by the block will be substituted for the match on each call.\n *\n *  The result inherits any tainting in the original string or any supplied\n *  replacement string.\n *\n *     \"hello\".sub(/[aeiou]/, '*')               #=> \"h*llo\"\n *     \"hello\".sub(/([aeiou])/, '<\\1>')          #=> \"h<e>llo\"\n *     \"hello\".sub(/./) {|s| s[0].to_s + ' ' }   #=> \"104 ello\"\n */\n\nstatic VALUE\nrb_str_sub(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_sub_bang(argc, argv, str);\n    return str;\n}\n\nstatic VALUE\nstr_gsub(argc, argv, str, bang)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n    int bang;\n{\n    VALUE pat, val, repl, match, dest;\n    struct re_registers *regs;\n    long beg, n;\n    long offset, blen, slen, len;\n    int iter = 0;\n    char *buf, *bp, *sp, *cp;\n    int tainted = 0;\n\n    if (argc == 1) {\n        RETURN_ENUMERATOR(str, argc, argv);\n        iter = 1;\n    }\n    else if (argc == 2) {\n        repl = argv[1];\n        StringValue(repl);\n        if (OBJ_TAINTED(repl)) tainted = 1;\n    }\n    else {\n        rb_raise(rb_eArgError, \"wrong number of arguments (%d for 2)\", argc);\n    }\n\n    pat = get_pat(argv[0], 1);\n    offset=0; n=0;\n    beg = rb_reg_search(pat, str, 0, 0);\n    if (beg < 0) {\n        if (bang) return Qnil;  /* no match, no substitution */\n        return rb_str_dup(str);\n    }\n\n    blen = RSTRING(str)->len + 30; /* len + margin */\n    dest = str_new(0, 0, blen);\n    buf = RSTRING(dest)->ptr;\n    bp = buf;\n    sp = cp = RSTRING(str)->ptr;\n    slen = RSTRING(str)->len;\n\n    rb_str_locktmp(dest);\n    while (beg >= 0) {\n        n++;\n        match = rb_backref_get();\n        regs = RMATCH(match)->regs;\n        if (iter) {\n            rb_match_busy(match);\n            val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));\n            str_mod_check(str, sp, slen);\n            if (bang) str_frozen_check(str);\n            if (val == dest) {  /* paranoid chack [ruby-dev:24827] */\n                rb_raise(rb_eRuntimeError, \"block should not cheat\");\n            }\n            rb_backref_set(match);\n        }\n        else {\n            val = rb_reg_regsub(repl, str, regs);\n        }\n        if (OBJ_TAINTED(val)) tainted = 1;\n        len = (bp - buf) + (beg - offset) + RSTRING(val)->len + 3;\n        if (blen < len) {\n            while (blen < len) blen *= 2;\n            len = bp - buf;\n            RESIZE_CAPA(dest, blen);\n            RSTRING(dest)->len = blen;\n            buf = RSTRING(dest)->ptr;\n            bp = buf + len;\n        }\n        len = beg - offset;     /* copy pre-match substr */\n        memcpy(bp, cp, len);\n        bp += len;\n        memcpy(bp, RSTRING(val)->ptr, RSTRING(val)->len);\n        bp += RSTRING(val)->len;\n        offset = END(0);\n        if (BEG(0) == END(0)) {\n            /*\n             * Always consume at least one character of the input string\n             * in order to prevent infinite loops.\n             */\n            if (RSTRING(str)->len <= END(0)) break;\n            len = mbclen2(RSTRING(str)->ptr[END(0)], pat);\n            memcpy(bp, RSTRING(str)->ptr+END(0), len);\n            bp += len;\n            offset = END(0) + len;\n        }\n        cp = RSTRING(str)->ptr + offset;\n        if (offset > RSTRING(str)->len) break;\n        beg = rb_reg_search(pat, str, offset, 0);\n    }\n    if (RSTRING(str)->len > offset) {\n        len = bp - buf;\n        if (blen - len < RSTRING(str)->len - offset) {\n            blen = len + RSTRING(str)->len - offset;\n            RESIZE_CAPA(dest, blen);\n            buf = RSTRING(dest)->ptr;\n            bp = buf + len;\n        }\n        memcpy(bp, cp, RSTRING(str)->len - offset);\n        bp += RSTRING(str)->len - offset;\n    }\n    rb_backref_set(match);\n    *bp = '\\0';\n    rb_str_unlocktmp(dest);\n    if (bang) {\n        if (str_independent(str)) {\n            free(RSTRING(str)->ptr);\n        }\n        FL_UNSET(str, STR_NOCAPA);\n        RSTRING(str)->ptr = buf;\n        RSTRING(str)->aux.capa = blen;\n        RSTRING(dest)->ptr = 0;\n        RSTRING(dest)->len = 0;\n    }\n    else {\n        RBASIC(dest)->klass = rb_obj_class(str);\n        OBJ_INFECT(dest, str);\n        str = dest;\n    }\n    RSTRING(str)->len = bp - buf;\n\n    if (tainted) OBJ_TAINT(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.gsub!(pattern, replacement)        => str or nil\n *     str.gsub!(pattern) {|match| block }    => str or nil\n *\n *  Performs the substitutions of <code>String#gsub</code> in place, returning\n *  <i>str</i>, or <code>nil</code> if no substitutions were performed.\n */\n\nstatic VALUE\nrb_str_gsub_bang(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    return str_gsub(argc, argv, str, 1);\n}\n\n\n/*\n *  call-seq:\n *     str.gsub(pattern, replacement)       => new_str\n *     str.gsub(pattern) {|match| block }   => new_str\n *\n *  Returns a copy of <i>str</i> with <em>all</em> occurrences of <i>pattern</i>\n *  replaced with either <i>replacement</i> or the value of the block. The\n *  <i>pattern</i> will typically be a <code>Regexp</code>; if it is a\n *  <code>String</code> then no regular expression metacharacters will be\n *  interpreted (that is <code>/\\d/</code> will match a digit, but\n *  <code>'\\d'</code> will match a backslash followed by a 'd').\n *\n *  If a string is used as the replacement, special variables from the match\n *  (such as <code>$&</code> and <code>$1</code>) cannot be substituted into it,\n *  as substitution into the string occurs before the pattern match\n *  starts. However, the sequences <code>\\1</code>, <code>\\2</code>, and so on\n *  may be used to interpolate successive groups in the match.\n *\n *  In the block form, the current match string is passed in as a parameter, and\n *  variables such as <code>$1</code>, <code>$2</code>, <code>$`</code>,\n *  <code>$&</code>, and <code>$'</code> will be set appropriately. The value\n *  returned by the block will be substituted for the match on each call.\n *\n *  The result inherits any tainting in the original string or any supplied\n *  replacement string.\n *\n *     \"hello\".gsub(/[aeiou]/, '*')              #=> \"h*ll*\"\n *     \"hello\".gsub(/([aeiou])/, '<\\1>')         #=> \"h<e>ll<o>\"\n *     \"hello\".gsub(/./) {|s| s[0].to_s + ' '}   #=> \"104 101 108 108 111 \"\n */\n\nstatic VALUE\nrb_str_gsub(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    return str_gsub(argc, argv, str, 0);\n}\n\n\n/*\n *  call-seq:\n *     str.replace(other_str)   => str\n *\n *  Replaces the contents and taintedness of <i>str</i> with the corresponding\n *  values in <i>other_str</i>.\n *\n *     s = \"hello\"         #=> \"hello\"\n *     s.replace \"world\"   #=> \"world\"\n */\n\nstatic VALUE\nrb_str_replace(str, str2)\n    VALUE str, str2;\n{\n    if (str == str2) return str;\n\n    StringValue(str2);\n    if (FL_TEST(str2, ELTS_SHARED)) {\n        if (str_independent(str)) {\n            free(RSTRING(str)->ptr);\n        }\n        RSTRING(str)->len = RSTRING(str2)->len;\n        RSTRING(str)->ptr = RSTRING(str2)->ptr;\n        FL_SET(str, ELTS_SHARED);\n        FL_UNSET(str, STR_ASSOC);\n        RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;\n    }\n    else {\n        if (str_independent(str)) {\n            rb_str_resize(str, RSTRING(str2)->len);\n            memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len);\n            if (!RSTRING(str)->ptr) {\n                make_null_str(str);\n            }\n        }\n        else {\n            RSTRING(str)->ptr = RSTRING(str2)->ptr;\n            RSTRING(str)->len = RSTRING(str2)->len;\n            str_make_independent(str);\n        }\n        if (FL_TEST(str2, STR_ASSOC)) {\n            FL_SET(str, STR_ASSOC);\n            RSTRING(str)->aux.shared = RSTRING(str2)->aux.shared;\n        }\n    }\n\n    OBJ_INFECT(str, str2);\n    maybe_add_to_longlife_recent_allocations(str);\n    return str;\n}\n\nstatic VALUE\nuscore_get()\n{\n    VALUE line;\n\n    line = rb_lastline_get();\n    if (TYPE(line) != T_STRING) {\n        rb_raise(rb_eTypeError, \"$_ value need to be String (%s given)\",\n                 NIL_P(line) ? \"nil\" : rb_obj_classname(line));\n    }\n    return line;\n}\n\n/*\n *  call-seq:\n *     sub!(pattern, replacement)    => $_ or nil\n *     sub!(pattern) {|...| block }  => $_ or nil\n *\n *  Equivalent to <code>$_.sub!(<i>args</i>)</code>.\n */\n\nstatic VALUE\nrb_f_sub_bang(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_str_sub_bang(argc, argv, uscore_get());\n}\n\n/*\n *  call-seq:\n *     sub(pattern, replacement)   => $_\n *     sub(pattern) { block }      => $_\n *\n *  Equivalent to <code>$_.sub(<i>args</i>)</code>, except that\n *  <code>$_</code> will be updated if substitution occurs.\n */\n\nstatic VALUE\nrb_f_sub(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE str = rb_str_dup(uscore_get());\n\n    if (NIL_P(rb_str_sub_bang(argc, argv, str)))\n        return str;\n    rb_lastline_set(str);\n    return str;\n}\n\n/*\n *  call-seq:\n *     gsub!(pattern, replacement)    => string or nil\n *     gsub!(pattern) {|...| block }  => string or nil\n *\n *  Equivalent to <code>Kernel::gsub</code>, except <code>nil</code> is\n *  returned if <code>$_</code> is not modified.\n *\n *     $_ = \"quick brown fox\"\n *     gsub! /cat/, '*'   #=> nil\n *     $_                 #=> \"quick brown fox\"\n */\n\nstatic VALUE\nrb_f_gsub_bang(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_str_gsub_bang(argc, argv, uscore_get());\n}\n\n/*\n *  call-seq:\n *     gsub(pattern, replacement)    => string\n *     gsub(pattern) {|...| block }  => string\n *\n *  Equivalent to <code>$_.gsub...</code>, except that <code>$_</code>\n *  receives the modified result.\n *\n *     $_ = \"quick brown fox\"\n *     gsub /[aeiou]/, '*'   #=> \"q**ck br*wn f*x\"\n *     $_                    #=> \"q**ck br*wn f*x\"\n */\n\nstatic VALUE\nrb_f_gsub(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE str = rb_str_dup(uscore_get());\n\n    if (NIL_P(rb_str_gsub_bang(argc, argv, str)))\n        return str;\n    rb_lastline_set(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.reverse!   => str\n *\n *  Reverses <i>str</i> in place.\n */\n\nstatic VALUE\nrb_str_reverse_bang(str)\n    VALUE str;\n{\n    char *s, *e;\n    char c;\n\n    if (RSTRING(str)->len > 1) {\n        rb_str_modify(str);\n        s = RSTRING(str)->ptr;\n        e = s + RSTRING(str)->len - 1;\n        while (s < e) {\n            c = *s;\n            *s++ = *e;\n            *e-- = c;\n        }\n    }\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.reverse   => new_str\n *\n *  Returns a new string with the characters from <i>str</i> in reverse order.\n *\n *     \"stressed\".reverse   #=> \"desserts\"\n */\n\nstatic VALUE\nrb_str_reverse(str)\n    VALUE str;\n{\n    VALUE obj;\n    char *s, *e, *p;\n\n    if (RSTRING(str)->len <= 1) return rb_str_dup(str);\n\n    obj = rb_str_new5(str, 0, RSTRING(str)->len);\n    s = RSTRING(str)->ptr; e = s + RSTRING(str)->len - 1;\n    p = RSTRING(obj)->ptr;\n\n    while (e >= s) {\n        *p++ = *e--;\n    }\n    OBJ_INFECT(obj, str);\n\n    return obj;\n}\n\n\n/*\n *  call-seq:\n *     str.include? other_str   => true or false\n *     str.include? fixnum      => true or false\n *\n *  Returns <code>true</code> if <i>str</i> contains the given string or\n *  character.\n *\n *     \"hello\".include? \"lo\"   #=> true\n *     \"hello\".include? \"ol\"   #=> false\n *     \"hello\".include? ?h     #=> true\n */\n\nstatic VALUE\nrb_str_include(str, arg)\n    VALUE str, arg;\n{\n    long i;\n\n    if (FIXNUM_P(arg)) {\n        if (memchr(RSTRING(str)->ptr, FIX2INT(arg), RSTRING(str)->len))\n            return Qtrue;\n        return Qfalse;\n    }\n\n    StringValue(arg);\n    i = rb_str_index(str, arg, 0);\n\n    if (i == -1) return Qfalse;\n    return Qtrue;\n}\n\n\n/*\n *  call-seq:\n *     str.to_i(base=10)   => integer\n *\n *  Returns the result of interpreting leading characters in <i>str</i> as an\n *  integer base <i>base</i> (between 2 and 36). Extraneous characters past the\n *  end of a valid number are ignored. If there is not a valid number at the\n *  start of <i>str</i>, <code>0</code> is returned. This method never raises an\n *  exception.\n *\n *     \"12345\".to_i             #=> 12345\n *     \"99 red balloons\".to_i   #=> 99\n *     \"0a\".to_i                #=> 0\n *     \"0a\".to_i(16)            #=> 10\n *     \"hello\".to_i             #=> 0\n *     \"1100101\".to_i(2)        #=> 101\n *     \"1100101\".to_i(8)        #=> 294977\n *     \"1100101\".to_i(10)       #=> 1100101\n *     \"1100101\".to_i(16)       #=> 17826049\n */\n\nstatic VALUE\nrb_str_to_i(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE b;\n    int base;\n\n    rb_scan_args(argc, argv, \"01\", &b);\n    if (argc == 0) base = 10;\n    else base = NUM2INT(b);\n\n    if (base < 0) {\n        rb_raise(rb_eArgError, \"illegal radix %d\", base);\n    }\n    return rb_str_to_inum(str, base, Qfalse);\n}\n\n\n/*\n *  call-seq:\n *     str.to_f   => float\n *\n *  Returns the result of interpreting leading characters in <i>str</i> as a\n *  floating point number. Extraneous characters past the end of a valid number\n *  are ignored. If there is not a valid number at the start of <i>str</i>,\n *  <code>0.0</code> is returned. This method never raises an exception.\n *\n *     \"123.45e1\".to_f        #=> 1234.5\n *     \"45.67 degrees\".to_f   #=> 45.67\n *     \"thx1138\".to_f         #=> 0.0\n */\n\nstatic VALUE\nrb_str_to_f(str)\n    VALUE str;\n{\n    return rb_float_new(rb_str_to_dbl(str, Qfalse));\n}\n\n\n/*\n *  call-seq:\n *     str.to_s     => str\n *     str.to_str   => str\n *\n *  Returns the receiver.\n */\n\nstatic VALUE\nrb_str_to_s(str)\n    VALUE str;\n{\n    if (rb_obj_class(str) != rb_cString) {\n        VALUE dup = str_alloc(rb_cString);\n        rb_str_replace(dup, str);\n        return dup;\n    }\n    return str;\n}\n\n/*\n * call-seq:\n *   str.inspect   => string\n *\n * Returns a printable version of _str_, with special characters\n * escaped.\n *\n *    str = \"hello\"\n *    str[3] = 8\n *    str.inspect       #=> \"hel\\010o\"\n */\n\nVALUE\nrb_str_inspect(str)\n    VALUE str;\n{\n    char *p, *pend;\n    VALUE result = rb_str_buf_new2(\"\\\"\");\n    char s[5];\n\n    p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;\n    while (p < pend) {\n        char c = *p++;\n        int len;\n        if (ismbchar(c) && p + (len = mbclen(c)) <= pend) {\n            rb_str_buf_cat(result, p - 1, len);\n            p += len - 1;\n        }\n        else if (c == '\"'|| c == '\\\\' || (c == '#' && IS_EVSTR(p, pend))) {\n            s[0] = '\\\\'; s[1] = c;\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (ISPRINT(c)) {\n            s[0] = c;\n            rb_str_buf_cat(result, s, 1);\n        }\n        else if (c == '\\n') {\n            s[0] = '\\\\'; s[1] = 'n';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == '\\r') {\n            s[0] = '\\\\'; s[1] = 'r';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == '\\t') {\n            s[0] = '\\\\'; s[1] = 't';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == '\\f') {\n            s[0] = '\\\\'; s[1] = 'f';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == '\\013') {\n            s[0] = '\\\\'; s[1] = 'v';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == '\\010') {\n            s[0] = '\\\\'; s[1] = 'b';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == '\\007') {\n            s[0] = '\\\\'; s[1] = 'a';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else if (c == 033) {\n            s[0] = '\\\\'; s[1] = 'e';\n            rb_str_buf_cat(result, s, 2);\n        }\n        else {\n            sprintf(s, \"\\\\%03o\", c & 0377);\n            rb_str_buf_cat2(result, s);\n        }\n    }\n    rb_str_buf_cat2(result, \"\\\"\");\n\n    OBJ_INFECT(result, str);\n    return result;\n}\n\n\n/*\n *  call-seq:\n *     str.dump   => new_str\n *\n *  Produces a version of <i>str</i> with all nonprinting characters replaced by\n *  <code>\\nnn</code> notation and all special characters escaped.\n */\n\nVALUE\nrb_str_dump(str)\n    VALUE str;\n{\n    long len;\n    char *p, *pend;\n    char *q, *qend;\n    VALUE result;\n\n    len = 2;                    /* \"\" */\n    p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;\n    while (p < pend) {\n        char c = *p++;\n        switch (c) {\n          case '\"':  case '\\\\':\n          case '\\n': case '\\r':\n          case '\\t': case '\\f':\n          case '\\013': case '\\010': case '\\007': case '\\033':\n            len += 2;\n            break;\n\n          case '#':\n            len += IS_EVSTR(p, pend) ? 2 : 1;\n            break;\n\n          default:\n            if (ISPRINT(c)) {\n                len++;\n            }\n            else {\n                len += 4;               /* \\nnn */\n            }\n            break;\n        }\n    }\n\n    result = rb_str_new5(str, 0, len);\n    p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;\n    q = RSTRING(result)->ptr; qend = q + len;\n\n    *q++ = '\"';\n    while (p < pend) {\n        char c = *p++;\n\n        if (c == '\"' || c == '\\\\') {\n            *q++ = '\\\\';\n            *q++ = c;\n        }\n        else if (c == '#') {\n            if (IS_EVSTR(p, pend)) *q++ = '\\\\';\n            *q++ = '#';\n        }\n        else if (ISPRINT(c)) {\n            *q++ = c;\n        }\n        else if (c == '\\n') {\n            *q++ = '\\\\';\n            *q++ = 'n';\n        }\n        else if (c == '\\r') {\n            *q++ = '\\\\';\n            *q++ = 'r';\n        }\n        else if (c == '\\t') {\n            *q++ = '\\\\';\n            *q++ = 't';\n        }\n        else if (c == '\\f') {\n            *q++ = '\\\\';\n            *q++ = 'f';\n        }\n        else if (c == '\\013') {\n            *q++ = '\\\\';\n            *q++ = 'v';\n        }\n        else if (c == '\\010') {\n            *q++ = '\\\\';\n            *q++ = 'b';\n        }\n        else if (c == '\\007') {\n            *q++ = '\\\\';\n            *q++ = 'a';\n        }\n        else if (c == '\\033') {\n            *q++ = '\\\\';\n            *q++ = 'e';\n        }\n        else {\n            *q++ = '\\\\';\n            sprintf(q, \"%03o\", c&0xff);\n            q += 3;\n        }\n    }\n    *q++ = '\"';\n\n    OBJ_INFECT(result, str);\n    return result;\n}\n\n\n/*\n *  call-seq:\n *     str.upcase!   => str or nil\n *\n *  Upcases the contents of <i>str</i>, returning <code>nil</code> if no changes\n *  were made.\n */\n\nstatic VALUE\nrb_str_upcase_bang(str)\n    VALUE str;\n{\n    char *s, *send;\n    int modify = 0;\n\n    rb_str_modify(str);\n    s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;\n    while (s < send) {\n        if (ismbchar(*s)) {\n            s+=mbclen(*s) - 1;\n        }\n        else if (ISLOWER(*s)) {\n            *s = toupper(*s);\n            modify = 1;\n        }\n        s++;\n    }\n\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.upcase   => new_str\n *\n *  Returns a copy of <i>str</i> with all lowercase letters replaced with their\n *  uppercase counterparts. The operation is locale insensitive---only\n *  characters ``a'' to ``z'' are affected.\n *\n *     \"hEllO\".upcase   #=> \"HELLO\"\n */\n\nstatic VALUE\nrb_str_upcase(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_upcase_bang(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.downcase!   => str or nil\n *\n *  Downcases the contents of <i>str</i>, returning <code>nil</code> if no\n *  changes were made.\n */\n\nstatic VALUE\nrb_str_downcase_bang(str)\n    VALUE str;\n{\n    char *s, *send;\n    int modify = 0;\n\n    rb_str_modify(str);\n    s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;\n    while (s < send) {\n        if (ismbchar(*s)) {\n            s+=mbclen(*s) - 1;\n        }\n        else if (ISUPPER(*s)) {\n            *s = tolower(*s);\n            modify = 1;\n        }\n        s++;\n    }\n\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.downcase   => new_str\n *\n *  Returns a copy of <i>str</i> with all uppercase letters replaced with their\n *  lowercase counterparts. The operation is locale insensitive---only\n *  characters ``A'' to ``Z'' are affected.\n *\n *     \"hEllO\".downcase   #=> \"hello\"\n */\n\nstatic VALUE\nrb_str_downcase(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_downcase_bang(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.capitalize!   => str or nil\n *\n *  Modifies <i>str</i> by converting the first character to uppercase and the\n *  remainder to lowercase. Returns <code>nil</code> if no changes are made.\n *\n *     a = \"hello\"\n *     a.capitalize!   #=> \"Hello\"\n *     a               #=> \"Hello\"\n *     a.capitalize!   #=> nil\n */\n\nstatic VALUE\nrb_str_capitalize_bang(str)\n    VALUE str;\n{\n    char *s, *send;\n    int modify = 0;\n\n    rb_str_modify(str);\n    if (RSTRING(str)->len == 0 || !RSTRING(str)->ptr) return Qnil;\n    s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;\n    if (ISLOWER(*s)) {\n        *s = toupper(*s);\n        modify = 1;\n    }\n    while (++s < send) {\n        if (ismbchar(*s)) {\n            s+=mbclen(*s) - 1;\n        }\n        else if (ISUPPER(*s)) {\n            *s = tolower(*s);\n            modify = 1;\n        }\n    }\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.capitalize   => new_str\n *\n *  Returns a copy of <i>str</i> with the first character converted to uppercase\n *  and the remainder to lowercase.\n *\n *     \"hello\".capitalize    #=> \"Hello\"\n *     \"HELLO\".capitalize    #=> \"Hello\"\n *     \"123ABC\".capitalize   #=> \"123abc\"\n */\n\nstatic VALUE\nrb_str_capitalize(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_capitalize_bang(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.swapcase!   => str or nil\n *\n *  Equivalent to <code>String#swapcase</code>, but modifies the receiver in\n *  place, returning <i>str</i>, or <code>nil</code> if no changes were made.\n */\n\nstatic VALUE\nrb_str_swapcase_bang(str)\n    VALUE str;\n{\n    char *s, *send;\n    int modify = 0;\n\n    rb_str_modify(str);\n    s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;\n    while (s < send) {\n        if (ismbchar(*s)) {\n            s+=mbclen(*s) - 1;\n        }\n        else if (ISUPPER(*s)) {\n            *s = tolower(*s);\n            modify = 1;\n        }\n        else if (ISLOWER(*s)) {\n            *s = toupper(*s);\n            modify = 1;\n        }\n        s++;\n    }\n\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.swapcase   => new_str\n *\n *  Returns a copy of <i>str</i> with uppercase alphabetic characters converted\n *  to lowercase and lowercase characters converted to uppercase.\n *\n *     \"Hello\".swapcase          #=> \"hELLO\"\n *     \"cYbEr_PuNk11\".swapcase   #=> \"CyBeR_pUnK11\"\n */\n\nstatic VALUE\nrb_str_swapcase(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_swapcase_bang(str);\n    return str;\n}\n\ntypedef unsigned char *USTR;\n\nstruct tr {\n    int gen, now, max;\n    char *p, *pend;\n};\n\nstatic int\ntrnext(t)\n    struct tr *t;\n{\n    for (;;) {\n        if (!t->gen) {\n            if (t->p == t->pend) return -1;\n            if (t->p < t->pend - 1 && *t->p == '\\\\') {\n                t->p++;\n            }\n            t->now = *(USTR)t->p++;\n            if (t->p < t->pend - 1 && *t->p == '-') {\n                t->p++;\n                if (t->p < t->pend) {\n                    if (t->now > *(USTR)t->p) {\n                        t->p++;\n                        continue;\n                    }\n                    t->gen = 1;\n                    t->max = *(USTR)t->p++;\n                }\n            }\n            return t->now;\n        }\n        else if (++t->now < t->max) {\n            return t->now;\n        }\n        else {\n            t->gen = 0;\n            return t->max;\n        }\n    }\n}\n\nstatic VALUE rb_str_delete_bang _((int,VALUE*,VALUE));\n\nstatic VALUE\ntr_trans(str, src, repl, sflag)\n    VALUE str, src, repl;\n    int sflag;\n{\n    struct tr trsrc, trrepl;\n    int cflag = 0;\n    int trans[256];\n    int i, c, modify = 0;\n    char *s, *send;\n\n    StringValue(src);\n    StringValue(repl);\n    if (RSTRING(str)->len == 0 || !RSTRING(str)->ptr) return Qnil;\n    trsrc.p = RSTRING(src)->ptr; trsrc.pend = trsrc.p + RSTRING(src)->len;\n    if (RSTRING(src)->len >= 2 && RSTRING(src)->ptr[0] == '^') {\n        cflag++;\n        trsrc.p++;\n    }\n    if (RSTRING(repl)->len == 0) {\n        return rb_str_delete_bang(1, &src, str);\n    }\n    trrepl.p = RSTRING(repl)->ptr;\n    trrepl.pend = trrepl.p + RSTRING(repl)->len;\n    trsrc.gen = trrepl.gen = 0;\n    trsrc.now = trrepl.now = 0;\n    trsrc.max = trrepl.max = 0;\n\n    if (cflag) {\n        for (i=0; i<256; i++) {\n            trans[i] = 1;\n        }\n        while ((c = trnext(&trsrc)) >= 0) {\n            trans[c & 0xff] = -1;\n        }\n        while ((c = trnext(&trrepl)) >= 0)\n            /* retrieve last replacer */;\n        for (i=0; i<256; i++) {\n            if (trans[i] >= 0) {\n                trans[i] = trrepl.now;\n            }\n        }\n    }\n    else {\n        int r;\n\n        for (i=0; i<256; i++) {\n            trans[i] = -1;\n        }\n        while ((c = trnext(&trsrc)) >= 0) {\n            r = trnext(&trrepl);\n            if (r == -1) r = trrepl.now;\n            trans[c & 0xff] = r;\n        }\n    }\n\n    rb_str_modify(str);\n    s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;\n    if (sflag) {\n        char *t = s;\n        int c0, last = -1;\n\n        while (s < send) {\n            c0 = *s++;\n            if ((c = trans[c0 & 0xff]) >= 0) {\n                if (last == c) continue;\n                last = c;\n                *t++ = c & 0xff;\n                modify = 1;\n            }\n            else {\n                last = -1;\n                *t++ = c0;\n            }\n        }\n        if (RSTRING(str)->len > (t - RSTRING(str)->ptr)) {\n            RSTRING(str)->len = (t - RSTRING(str)->ptr);\n            modify = 1;\n            *t = '\\0';\n        }\n    }\n    else {\n        while (s < send) {\n            if ((c = trans[*s & 0xff]) >= 0) {\n                *s = c & 0xff;\n                modify = 1;\n            }\n            s++;\n        }\n    }\n\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.tr!(from_str, to_str)   => str or nil\n *\n *  Translates <i>str</i> in place, using the same rules as\n *  <code>String#tr</code>. Returns <i>str</i>, or <code>nil</code> if no\n *  changes were made.\n */\n\nstatic VALUE\nrb_str_tr_bang(str, src, repl)\n    VALUE str, src, repl;\n{\n    return tr_trans(str, src, repl, 0);\n}\n\n\n/*\n *  call-seq:\n *     str.tr(from_str, to_str)   => new_str\n *\n *  Returns a copy of <i>str</i> with the characters in <i>from_str</i> replaced\n *  by the corresponding characters in <i>to_str</i>. If <i>to_str</i> is\n *  shorter than <i>from_str</i>, it is padded with its last character. Both\n *  strings may use the c1--c2 notation to denote ranges of characters, and\n *  <i>from_str</i> may start with a <code>^</code>, which denotes all\n *  characters except those listed.\n *\n *     \"hello\".tr('aeiou', '*')    #=> \"h*ll*\"\n *     \"hello\".tr('^aeiou', '*')   #=> \"*e**o\"\n *     \"hello\".tr('el', 'ip')      #=> \"hippo\"\n *     \"hello\".tr('a-y', 'b-z')    #=> \"ifmmp\"\n */\n\nstatic VALUE\nrb_str_tr(str, src, repl)\n    VALUE str, src, repl;\n{\n    str = rb_str_dup(str);\n    tr_trans(str, src, repl, 0);\n    return str;\n}\n\nstatic void\ntr_setup_table(str, table, init)\n    VALUE str;\n    char table[256];\n    int init;\n{\n    char buf[256];\n    struct tr tr;\n    int i, c;\n    int cflag = 0;\n\n    tr.p = RSTRING(str)->ptr; tr.pend = tr.p + RSTRING(str)->len;\n    tr.gen = tr.now = tr.max = 0;\n    if (RSTRING(str)->len > 1 && RSTRING(str)->ptr[0] == '^') {\n        cflag = 1;\n        tr.p++;\n    }\n\n    if (init) {\n        for (i=0; i<256; i++) {\n            table[i] = 1;\n        }\n    }\n    for (i=0; i<256; i++) {\n        buf[i] = cflag;\n    }\n    while ((c = trnext(&tr)) >= 0) {\n        buf[c & 0xff] = !cflag;\n    }\n    for (i=0; i<256; i++) {\n        table[i] = table[i] && buf[i];\n    }\n}\n\n\n/*\n *  call-seq:\n *     str.delete!([other_str]+>)   => str or nil\n *\n *  Performs a <code>delete</code> operation in place, returning <i>str</i>, or\n *  <code>nil</code> if <i>str</i> was not modified.\n */\n\nstatic VALUE\nrb_str_delete_bang(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    char *s, *send, *t;\n    char squeez[256];\n    int modify = 0;\n    int init = 1;\n    int i;\n\n    if (argc < 1) {\n        rb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n    for (i=0; i<argc; i++) {\n        VALUE s = argv[i];\n\n        StringValue(s);\n        tr_setup_table(s, squeez, init);\n        init = 0;\n    }\n\n    rb_str_modify(str);\n    s = t = RSTRING(str)->ptr;\n    if (!s || RSTRING(str)->len == 0) return Qnil;\n    send = s + RSTRING(str)->len;\n    while (s < send) {\n        if (squeez[*s & 0xff])\n            modify = 1;\n        else\n            *t++ = *s;\n        s++;\n    }\n    *t = '\\0';\n    RSTRING(str)->len = t - RSTRING(str)->ptr;\n\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.delete([other_str]+)   => new_str\n *\n *  Returns a copy of <i>str</i> with all characters in the intersection of its\n *  arguments deleted. Uses the same rules for building the set of characters as\n *  <code>String#count</code>.\n *\n *     \"hello\".delete \"l\",\"lo\"        #=> \"heo\"\n *     \"hello\".delete \"lo\"            #=> \"he\"\n *     \"hello\".delete \"aeiou\", \"^e\"   #=> \"hell\"\n *     \"hello\".delete \"ej-m\"          #=> \"ho\"\n */\n\nstatic VALUE\nrb_str_delete(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_delete_bang(argc, argv, str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.squeeze!([other_str]*)   => str or nil\n *\n *  Squeezes <i>str</i> in place, returning either <i>str</i>, or\n *  <code>nil</code> if no changes were made.\n */\n\nstatic VALUE\nrb_str_squeeze_bang(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    char squeez[256];\n    char *s, *send, *t;\n    int c, save, modify = 0;\n    int init = 1;\n    int i;\n\n    if (argc == 0) {\n        for (i=0; i<256; i++) {\n            squeez[i] = 1;\n        }\n    }\n    else {\n        for (i=0; i<argc; i++) {\n            VALUE s = argv[i];\n\n            StringValue(s);\n            tr_setup_table(s, squeez, init);\n            init = 0;\n        }\n    }\n\n    rb_str_modify(str);\n    s = t = RSTRING(str)->ptr;\n    if (!s || RSTRING(str)->len == 0) return Qnil;\n    send = s + RSTRING(str)->len;\n    save = -1;\n    while (s < send) {\n        c = *s++ & 0xff;\n        if (c != save || !squeez[c]) {\n            *t++ = save = c;\n        }\n    }\n    *t = '\\0';\n    if (t - RSTRING(str)->ptr != RSTRING(str)->len) {\n        RSTRING(str)->len = t - RSTRING(str)->ptr;\n        modify = 1;\n    }\n\n    if (modify) return str;\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.squeeze([other_str]*)    => new_str\n *\n *  Builds a set of characters from the <i>other_str</i> parameter(s) using the\n *  procedure described for <code>String#count</code>. Returns a new string\n *  where runs of the same character that occur in this set are replaced by a\n *  single character. If no arguments are given, all runs of identical\n *  characters are replaced by a single character.\n *\n *     \"yellow moon\".squeeze                  #=> \"yelow mon\"\n *     \"  now   is  the\".squeeze(\" \")         #=> \" now is the\"\n *     \"putters shoot balls\".squeeze(\"m-z\")   #=> \"puters shot balls\"\n */\n\nstatic VALUE\nrb_str_squeeze(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_squeeze_bang(argc, argv, str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.tr_s!(from_str, to_str)   => str or nil\n *\n *  Performs <code>String#tr_s</code> processing on <i>str</i> in place,\n *  returning <i>str</i>, or <code>nil</code> if no changes were made.\n */\n\nstatic VALUE\nrb_str_tr_s_bang(str, src, repl)\n    VALUE str, src, repl;\n{\n    return tr_trans(str, src, repl, 1);\n}\n\n\n/*\n *  call-seq:\n *     str.tr_s(from_str, to_str)   => new_str\n *\n *  Processes a copy of <i>str</i> as described under <code>String#tr</code>,\n *  then removes duplicate characters in regions that were affected by the\n *  translation.\n *\n *     \"hello\".tr_s('l', 'r')     #=> \"hero\"\n *     \"hello\".tr_s('el', '*')    #=> \"h*o\"\n *     \"hello\".tr_s('el', 'hx')   #=> \"hhxo\"\n */\n\nstatic VALUE\nrb_str_tr_s(str, src, repl)\n    VALUE str, src, repl;\n{\n    str = rb_str_dup(str);\n    tr_trans(str, src, repl, 1);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.count([other_str]+)   => fixnum\n *\n *  Each <i>other_str</i> parameter defines a set of characters to count.  The\n *  intersection of these sets defines the characters to count in\n *  <i>str</i>. Any <i>other_str</i> that starts with a caret (^) is\n *  negated. The sequence c1--c2 means all characters between c1 and c2.\n *\n *     a = \"hello world\"\n *     a.count \"lo\"            #=> 5\n *     a.count \"lo\", \"o\"       #=> 2\n *     a.count \"hello\", \"^l\"   #=> 4\n *     a.count \"ej-m\"          #=> 4\n */\n\nstatic VALUE\nrb_str_count(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    char table[256];\n    char *s, *send;\n    int init = 1;\n    int i;\n\n    if (argc < 1) {\n        rb_raise(rb_eArgError, \"wrong number of arguments\");\n    }\n    for (i=0; i<argc; i++) {\n        VALUE s = argv[i];\n\n        StringValue(s);\n        tr_setup_table(s, table, init);\n        init = 0;\n    }\n\n    s = RSTRING(str)->ptr;\n    if (!s || RSTRING(str)->len == 0) return INT2FIX(0);\n    send = s + RSTRING(str)->len;\n    i = 0;\n    while (s < send) {\n        if (table[*s++ & 0xff]) {\n            i++;\n        }\n    }\n    return INT2NUM(i);\n}\n\n\n/*\n *  call-seq:\n *     str.split(pattern=$;, [limit])   => anArray\n *\n *  Divides <i>str</i> into substrings based on a delimiter, returning an array\n *  of these substrings.\n *\n *  If <i>pattern</i> is a <code>String</code>, then its contents are used as\n *  the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single\n *  space, <i>str</i> is split on whitespace, with leading whitespace and runs\n *  of contiguous whitespace characters ignored.\n *\n *  If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the\n *  pattern matches. Whenever the pattern matches a zero-length string,\n *  <i>str</i> is split into individual characters.\n *\n *  If <i>pattern</i> is omitted, the value of <code>$;</code> is used.  If\n *  <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is\n *  split on whitespace as if ` ' were specified.\n *\n *  If the <i>limit</i> parameter is omitted, trailing null fields are\n *  suppressed. If <i>limit</i> is a positive number, at most that number of\n *  fields will be returned (if <i>limit</i> is <code>1</code>, the entire\n *  string is returned as the only entry in an array). If negative, there is no\n *  limit to the number of fields returned, and trailing null fields are not\n *  suppressed.\n *\n *     \" now's  the time\".split        #=> [\"now's\", \"the\", \"time\"]\n *     \" now's  the time\".split(' ')   #=> [\"now's\", \"the\", \"time\"]\n *     \" now's  the time\".split(/ /)   #=> [\"\", \"now's\", \"\", \"the\", \"time\"]\n *     \"1, 2.34,56, 7\".split(%r{,\\s*}) #=> [\"1\", \"2.34\", \"56\", \"7\"]\n *     \"hello\".split(//)               #=> [\"h\", \"e\", \"l\", \"l\", \"o\"]\n *     \"hello\".split(//, 3)            #=> [\"h\", \"e\", \"llo\"]\n *     \"hi mom\".split(%r{\\s*})         #=> [\"h\", \"i\", \"m\", \"o\", \"m\"]\n *\n *     \"mellow yellow\".split(\"ello\")   #=> [\"m\", \"w y\", \"w\"]\n *     \"1,2,,3,4,,\".split(',')         #=> [\"1\", \"2\", \"\", \"3\", \"4\"]\n *     \"1,2,,3,4,,\".split(',', 4)      #=> [\"1\", \"2\", \"\", \"3,4,,\"]\n *     \"1,2,,3,4,,\".split(',', -4)     #=> [\"1\", \"2\", \"\", \"3\", \"4\", \"\", \"\"]\n */\n\nstatic VALUE\nrb_str_split_m(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE spat;\n    VALUE limit;\n    int awk_split = Qfalse;\n    long beg, end, i = 0;\n    int lim = 0;\n    VALUE result, tmp;\n\n    if (rb_scan_args(argc, argv, \"02\", &spat, &limit) == 2) {\n        lim = NUM2INT(limit);\n        if (lim <= 0) limit = Qnil;\n        else if (lim == 1) {\n            if (RSTRING(str)->len == 0)\n                return rb_ary_new2(0);\n            return rb_ary_new3(1, str);\n        }\n        i = 1;\n    }\n\n    if (NIL_P(spat)) {\n        if (!NIL_P(rb_fs)) {\n            spat = rb_fs;\n            goto fs_set;\n        }\n        awk_split = Qtrue;\n    }\n    else {\n      fs_set:\n        if (TYPE(spat) == T_STRING && RSTRING(spat)->len == 1) {\n            if (RSTRING(spat)->ptr[0] == ' ') {\n                awk_split = Qtrue;\n            }\n            else {\n                spat = rb_reg_regcomp(rb_reg_quote(spat));\n            }\n        }\n        else {\n            spat = get_pat(spat, 1);\n        }\n    }\n\n    result = rb_ary_new();\n    beg = 0;\n    if (awk_split) {\n        char *ptr = RSTRING(str)->ptr;\n        long len = RSTRING(str)->len;\n        char *eptr = ptr + len;\n        int skip = 1;\n\n        for (end = beg = 0; ptr<eptr; ptr++) {\n            if (skip) {\n                if (ISSPACE(*ptr)) {\n                    beg++;\n                }\n                else {\n                    end = beg+1;\n                    skip = 0;\n                    if (!NIL_P(limit) && lim <= i) break;\n                }\n            }\n            else {\n                if (ISSPACE(*ptr)) {\n                    rb_ary_push(result, rb_str_substr(str, beg, end-beg));\n                    skip = 1;\n                    beg = end + 1;\n                    if (!NIL_P(limit)) ++i;\n                }\n                else {\n                    end++;\n                }\n            }\n        }\n    }\n    else {\n        long start = beg;\n        long idx;\n        int last_null = 0;\n        struct re_registers *regs;\n\n        while ((end = rb_reg_search(spat, str, start, 0)) >= 0) {\n            regs = RMATCH(rb_backref_get())->regs;\n            if (start == end && BEG(0) == END(0)) {\n                if (!RSTRING(str)->ptr) {\n                    rb_ary_push(result, rb_str_new(\"\", 0));\n                    break;\n                }\n                else if (last_null == 1) {\n                    rb_ary_push(result, rb_str_substr(str, beg, mbclen2(RSTRING(str)->ptr[beg],spat)));\n                    beg = start;\n                }\n                else {\n                    start += mbclen2(RSTRING(str)->ptr[start],spat);\n                    last_null = 1;\n                    continue;\n                }\n            }\n            else {\n                rb_ary_push(result, rb_str_substr(str, beg, end-beg));\n                beg = start = END(0);\n            }\n            last_null = 0;\n\n            for (idx=1; idx < regs->num_regs; idx++) {\n                if (BEG(idx) == -1) continue;\n                if (BEG(idx) == END(idx))\n                    tmp = rb_str_new5(str, 0, 0);\n                else\n                    tmp = rb_str_substr(str, BEG(idx), END(idx)-BEG(idx));\n                rb_ary_push(result, tmp);\n            }\n            if (!NIL_P(limit) && lim <= ++i) break;\n        }\n    }\n    if (RSTRING(str)->len > 0 && (!NIL_P(limit) || RSTRING(str)->len > beg || lim < 0)) {\n        if (RSTRING(str)->len == beg)\n            tmp = rb_str_new5(str, 0, 0);\n        else\n            tmp = rb_str_substr(str, beg, RSTRING(str)->len-beg);\n        rb_ary_push(result, tmp);\n    }\n    if (NIL_P(limit) && lim == 0) {\n        while (RARRAY(result)->len > 0 &&\n               RSTRING(RARRAY(result)->ptr[RARRAY(result)->len-1])->len == 0)\n            rb_ary_pop(result);\n    }\n\n    return result;\n}\n\nVALUE\nrb_str_split(str, sep0)\n    VALUE str;\n    const char *sep0;\n{\n    VALUE sep;\n\n    StringValue(str);\n    sep = rb_str_new2(sep0);\n    return rb_str_split_m(1, &sep, str);\n}\n\n/*\n *  call-seq:\n *     split([pattern [, limit]])    => array\n *\n *  Equivalent to <code>$_.split(<i>pattern</i>, <i>limit</i>)</code>.\n *  See <code>String#split</code>.\n */\n\nstatic VALUE\nrb_f_split(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_str_split_m(argc, argv, uscore_get());\n}\n\n/*\n *  Document-method: lines\n *  call-seq:\n *     str.lines(separator=$/)   => anEnumerator\n *     str.lines(separator=$/) {|substr| block }        => str\n *\n *  Returns an enumerator that gives each line in the string.  If a block is\n *  given, it iterates over each line in the string.\n *\n *     \"foo\\nbar\\n\".lines.to_a   #=> [\"foo\\n\", \"bar\\n\"]\n *     \"foo\\nb ar\".lines.sort    #=> [\"b ar\", \"foo\\n\"]\n */\n\n/*\n *  call-seq:\n *     str.each(separator=$/) {|substr| block }        => str\n *     str.each_line(separator=$/) {|substr| block }   => str\n *\n *  Splits <i>str</i> using the supplied parameter as the record separator\n *  (<code>$/</code> by default), passing each substring in turn to the supplied\n *  block. If a zero-length record separator is supplied, the string is split\n *  into paragraphs delimited by multiple successive newlines.\n *\n *     print \"Example one\\n\"\n *     \"hello\\nworld\".each {|s| p s}\n *     print \"Example two\\n\"\n *     \"hello\\nworld\".each('l') {|s| p s}\n *     print \"Example three\\n\"\n *     \"hello\\n\\n\\nworld\".each('') {|s| p s}\n *\n *  <em>produces:</em>\n *\n *     Example one\n *     \"hello\\n\"\n *     \"world\"\n *     Example two\n *     \"hel\"\n *     \"l\"\n *     \"o\\nworl\"\n *     \"d\"\n *     Example three\n *     \"hello\\n\\n\\n\"\n *     \"world\"\n */\n\nstatic VALUE\nrb_str_each_line(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE rs;\n    int newline;\n    char *p = RSTRING(str)->ptr, *pend = p + RSTRING(str)->len, *s;\n    char *ptr = p;\n    long len = RSTRING(str)->len, rslen;\n    VALUE line;\n\n    if (rb_scan_args(argc, argv, \"01\", &rs) == 0) {\n        rs = rb_rs;\n    }\n    RETURN_ENUMERATOR(str, argc, argv);\n    if (NIL_P(rs)) {\n        rb_yield(str);\n        return str;\n    }\n    StringValue(rs);\n    rslen = RSTRING(rs)->len;\n    if (rslen == 0) {\n        newline = '\\n';\n    }\n    else {\n        newline = RSTRING(rs)->ptr[rslen-1];\n    }\n\n    for (s = p, p += rslen; p < pend; p++) {\n        if (rslen == 0 && *p == '\\n') {\n            if (*++p != '\\n') continue;\n            while (*p == '\\n') p++;\n        }\n        if (RSTRING(str)->ptr < p && p[-1] == newline &&\n            (rslen <= 1 ||\n             rb_memcmp(RSTRING(rs)->ptr, p-rslen, rslen) == 0)) {\n            line = rb_str_new5(str, s, p - s);\n            OBJ_INFECT(line, str);\n            rb_yield(line);\n            str_mod_check(str, ptr, len);\n            s = p;\n        }\n    }\n\n    if (s != pend) {\n        if (p > pend) p = pend;\n        line = rb_str_new5(str, s, p - s);\n        OBJ_INFECT(line, str);\n        rb_yield(line);\n    }\n\n    return str;\n}\n\n\n/*\n *  Document-method: bytes\n *  call-seq:\n *     str.bytes   => anEnumerator\n *     str.bytes {|fixnum| block }    => str\n *\n *  Returns an enumerator that gives each byte in the string.  If a block is\n *  given, it iterates over each byte in the string.\n *\n *     \"hello\".bytes.to_a        #=> [104, 101, 108, 108, 111]\n */\n\n/*\n *  call-seq:\n *     str.each_byte {|fixnum| block }    => str\n *\n *  Passes each byte in <i>str</i> to the given block.\n *\n *     \"hello\".each_byte {|c| print c, ' ' }\n *\n *  <em>produces:</em>\n *\n *     104 101 108 108 111\n */\n\nstatic VALUE\nrb_str_each_byte(str)\n    VALUE str;\n{\n    long i;\n\n    RETURN_ENUMERATOR(str, 0, 0);\n    for (i=0; i<RSTRING(str)->len; i++) {\n        rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff));\n    }\n    return str;\n}\n\n\n/*\n *  Document-method: chars\n *  call-seq:\n *     str.chars                   => anEnumerator\n *     str.chars {|substr| block } => str\n *\n *  Returns an enumerator that gives each character in the string.\n *  If a block is given, it iterates over each character in the string.\n *\n *     \"foo\".chars.to_a   #=> [\"f\",\"o\",\"o\"]\n */\n\n/*\n *  Document-method: each_char\n *  call-seq:\n *     str.each_char {|cstr| block }    => str\n *\n *  Passes each character in <i>str</i> to the given block.\n *\n *     \"hello\".each_char {|c| print c, ' ' }\n *\n *  <em>produces:</em>\n *\n *     h e l l o\n */\n\nstatic VALUE\nrb_str_each_char(VALUE str)\n{\n    int i, len, n;\n    const char *ptr;\n\n    RETURN_ENUMERATOR(str, 0, 0);\n    str = rb_str_new4(str);\n    ptr = RSTRING(str)->ptr;\n    len = RSTRING(str)->len;\n    for (i = 0; i < len; i += n) {\n        n = mbclen(ptr[i]);\n        rb_yield(rb_str_substr(str, i, n));\n    }\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.chop!   => str or nil\n *\n *  Processes <i>str</i> as for <code>String#chop</code>, returning <i>str</i>,\n *  or <code>nil</code> if <i>str</i> is the empty string.  See also\n *  <code>String#chomp!</code>.\n */\n\nstatic VALUE\nrb_str_chop_bang(str)\n    VALUE str;\n{\n    if (RSTRING(str)->len > 0) {\n        rb_str_modify(str);\n        RSTRING(str)->len--;\n        if (RSTRING(str)->ptr[RSTRING(str)->len] == '\\n') {\n            if (RSTRING(str)->len > 0 &&\n                RSTRING(str)->ptr[RSTRING(str)->len-1] == '\\r') {\n                RSTRING(str)->len--;\n            }\n        }\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n        return str;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.chop   => new_str\n *\n *  Returns a new <code>String</code> with the last character removed.  If the\n *  string ends with <code>\\r\\n</code>, both characters are removed. Applying\n *  <code>chop</code> to an empty string returns an empty\n *  string. <code>String#chomp</code> is often a safer alternative, as it leaves\n *  the string unchanged if it doesn't end in a record separator.\n *\n *     \"string\\r\\n\".chop   #=> \"string\"\n *     \"string\\n\\r\".chop   #=> \"string\\n\"\n *     \"string\\n\".chop     #=> \"string\"\n *     \"string\".chop       #=> \"strin\"\n *     \"x\".chop.chop       #=> \"\"\n */\n\nstatic VALUE\nrb_str_chop(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_chop_bang(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     chop!    => $_ or nil\n *\n *  Equivalent to <code>$_.chop!</code>.\n *\n *     a  = \"now\\r\\n\"\n *     $_ = a\n *     chop!   #=> \"now\"\n *     chop!   #=> \"no\"\n *     chop!   #=> \"n\"\n *     chop!   #=> \"\"\n *     chop!   #=> nil\n *     $_      #=> \"\"\n *     a       #=> \"\"\n */\n\nstatic VALUE\nrb_f_chop_bang(str)\n    VALUE str;\n{\n    return rb_str_chop_bang(uscore_get());\n}\n\n/*\n *  call-seq:\n *     chop   => string\n *\n *  Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>\n *  is never returned. See <code>String#chop!</code>.\n *\n *     a  =  \"now\\r\\n\"\n *     $_ = a\n *     chop   #=> \"now\"\n *     $_     #=> \"now\"\n *     chop   #=> \"no\"\n *     chop   #=> \"n\"\n *     chop   #=> \"\"\n *     chop   #=> \"\"\n *     a      #=> \"now\\r\\n\"\n */\n\nstatic VALUE\nrb_f_chop()\n{\n    VALUE str = uscore_get();\n\n    if (RSTRING(str)->len > 0) {\n        str = rb_str_dup(str);\n        rb_str_chop_bang(str);\n        rb_lastline_set(str);\n    }\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.chomp!(separator=$/)   => str or nil\n *\n *  Modifies <i>str</i> in place as described for <code>String#chomp</code>,\n *  returning <i>str</i>, or <code>nil</code> if no modifications were made.\n */\n\nstatic VALUE\nrb_str_chomp_bang(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE rs;\n    int newline;\n    char *p;\n    long len, rslen;\n\n    if (rb_scan_args(argc, argv, \"01\", &rs) == 0) {\n        len = RSTRING(str)->len;\n        if (len == 0) return Qnil;\n        p = RSTRING(str)->ptr;\n        rs = rb_rs;\n        if (rs == rb_default_rs) {\n          smart_chomp:\n            rb_str_modify(str);\n            if (RSTRING(str)->ptr[len-1] == '\\n') {\n                RSTRING(str)->len--;\n                if (RSTRING(str)->len > 0 &&\n                    RSTRING(str)->ptr[RSTRING(str)->len-1] == '\\r') {\n                    RSTRING(str)->len--;\n                }\n            }\n            else if (RSTRING(str)->ptr[len-1] == '\\r') {\n                RSTRING(str)->len--;\n            }\n            else {\n                return Qnil;\n            }\n            RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n            return str;\n        }\n    }\n    if (NIL_P(rs)) return Qnil;\n    StringValue(rs);\n    len = RSTRING(str)->len;\n    if (len == 0) return Qnil;\n    p = RSTRING(str)->ptr;\n    rslen = RSTRING(rs)->len;\n    if (rslen == 0) {\n        while (len>0 && p[len-1] == '\\n') {\n            len--;\n            if (len>0 && p[len-1] == '\\r')\n                len--;\n        }\n        if (len < RSTRING(str)->len) {\n            rb_str_modify(str);\n            RSTRING(str)->len = len;\n            RSTRING(str)->ptr[len] = '\\0';\n            return str;\n        }\n        return Qnil;\n    }\n    if (rslen > len) return Qnil;\n    newline = RSTRING(rs)->ptr[rslen-1];\n    if (rslen == 1 && newline == '\\n')\n        goto smart_chomp;\n\n    if (p[len-1] == newline &&\n        (rslen <= 1 ||\n         rb_memcmp(RSTRING(rs)->ptr, p+len-rslen, rslen) == 0)) {\n        rb_str_modify(str);\n        RSTRING(str)->len -= rslen;\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n        return str;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.chomp(separator=$/)   => new_str\n *\n *  Returns a new <code>String</code> with the given record separator removed\n *  from the end of <i>str</i> (if present). If <code>$/</code> has not been\n *  changed from the default Ruby record separator, then <code>chomp</code> also\n *  removes carriage return characters (that is it will remove <code>\\n</code>,\n *  <code>\\r</code>, and <code>\\r\\n</code>).\n *\n *     \"hello\".chomp            #=> \"hello\"\n *     \"hello\\n\".chomp          #=> \"hello\"\n *     \"hello\\r\\n\".chomp        #=> \"hello\"\n *     \"hello\\n\\r\".chomp        #=> \"hello\\n\"\n *     \"hello\\r\".chomp          #=> \"hello\"\n *     \"hello \\n there\".chomp   #=> \"hello \\n there\"\n *     \"hello\".chomp(\"llo\")     #=> \"he\"\n */\n\nstatic VALUE\nrb_str_chomp(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_chomp_bang(argc, argv, str);\n    return str;\n}\n\n/*\n *  call-seq:\n *     chomp!             => $_ or nil\n *     chomp!(string)     => $_ or nil\n *\n *  Equivalent to <code>$_.chomp!(<em>string</em>)</code>. See\n *  <code>String#chomp!</code>\n *\n *     $_ = \"now\\n\"\n *     chomp!       #=> \"now\"\n *     $_           #=> \"now\"\n *     chomp! \"x\"   #=> nil\n *     $_           #=> \"now\"\n */\n\nstatic VALUE\nrb_f_chomp_bang(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    return rb_str_chomp_bang(argc, argv, uscore_get());\n}\n\n/*\n *  call-seq:\n *     chomp            => $_\n *     chomp(string)    => $_\n *\n *  Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See\n *  <code>String#chomp</code>.\n *\n *     $_ = \"now\\n\"\n *     chomp         #=> \"now\"\n *     $_            #=> \"now\"\n *     chomp \"ow\"    #=> \"n\"\n *     $_            #=> \"n\"\n *     chomp \"xxx\"   #=> \"n\"\n *     $_            #=> \"n\"\n */\n\nstatic VALUE\nrb_f_chomp(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE str = uscore_get();\n    VALUE dup = rb_str_dup(str);\n\n    if (NIL_P(rb_str_chomp_bang(argc, argv, dup)))\n        return str;\n    rb_lastline_set(dup);\n    return dup;\n}\n\n\n/*\n *  call-seq:\n *     str.lstrip!   => self or nil\n *\n *  Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no\n *  change was made. See also <code>String#rstrip!</code> and\n *  <code>String#strip!</code>.\n *\n *     \"  hello  \".lstrip   #=> \"hello  \"\n *     \"hello\".lstrip!      #=> nil\n */\n\nstatic VALUE\nrb_str_lstrip_bang(str)\n    VALUE str;\n{\n    char *s, *t, *e;\n\n    s = RSTRING(str)->ptr;\n    if (!s || RSTRING(str)->len == 0) return Qnil;\n    e = t = s + RSTRING(str)->len;\n    /* remove spaces at head */\n    while (s < t && ISSPACE(*s)) s++;\n\n    if (s > RSTRING(str)->ptr) {\n        rb_str_modify(str);\n        RSTRING(str)->len = t-s;\n        memmove(RSTRING(str)->ptr, s, RSTRING(str)->len);\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n        return str;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.lstrip   => new_str\n *\n *  Returns a copy of <i>str</i> with leading whitespace removed. See also\n *  <code>String#rstrip</code> and <code>String#strip</code>.\n *\n *     \"  hello  \".lstrip   #=> \"hello  \"\n *     \"hello\".lstrip       #=> \"hello\"\n */\n\nstatic VALUE\nrb_str_lstrip(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_lstrip_bang(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.rstrip!   => self or nil\n *\n *  Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if\n *  no change was made. See also <code>String#lstrip!</code> and\n *  <code>String#strip!</code>.\n *\n *     \"  hello  \".rstrip   #=> \"  hello\"\n *     \"hello\".rstrip!      #=> nil\n */\n\nstatic VALUE\nrb_str_rstrip_bang(str)\n    VALUE str;\n{\n    char *s, *t, *e;\n\n    s = RSTRING(str)->ptr;\n    if (!s || RSTRING(str)->len == 0) return Qnil;\n    e = t = s + RSTRING(str)->len;\n\n    /* remove trailing '\\0's */\n    while (s < t && t[-1] == '\\0') t--;\n\n    /* remove trailing spaces */\n    while (s < t && ISSPACE(*(t-1))) t--;\n\n    if (t < e) {\n        rb_str_modify(str);\n        RSTRING(str)->len = t-s;\n        RSTRING(str)->ptr[RSTRING(str)->len] = '\\0';\n        return str;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.rstrip   => new_str\n *\n *  Returns a copy of <i>str</i> with trailing whitespace removed. See also\n *  <code>String#lstrip</code> and <code>String#strip</code>.\n *\n *     \"  hello  \".rstrip   #=> \"  hello\"\n *     \"hello\".rstrip       #=> \"hello\"\n */\n\nstatic VALUE\nrb_str_rstrip(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_rstrip_bang(str);\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.strip!   => str or nil\n *\n *  Removes leading and trailing whitespace from <i>str</i>. Returns\n *  <code>nil</code> if <i>str</i> was not altered.\n */\n\nstatic VALUE\nrb_str_strip_bang(str)\n    VALUE str;\n{\n    VALUE l = rb_str_lstrip_bang(str);\n    VALUE r = rb_str_rstrip_bang(str);\n\n    if (NIL_P(l) && NIL_P(r)) return Qnil;\n    return str;\n}\n\n\n/*\n *  call-seq:\n *     str.strip   => new_str\n *\n *  Returns a copy of <i>str</i> with leading and trailing whitespace removed.\n *\n *     \"    hello    \".strip   #=> \"hello\"\n *     \"\\tgoodbye\\r\\n\".strip   #=> \"goodbye\"\n */\n\nstatic VALUE\nrb_str_strip(str)\n    VALUE str;\n{\n    str = rb_str_dup(str);\n    rb_str_strip_bang(str);\n    return str;\n}\n\nstatic VALUE\nscan_once(str, pat, start)\n    VALUE str, pat;\n    long *start;\n{\n    VALUE result, match;\n    struct re_registers *regs;\n    long i;\n\n    if (rb_reg_search(pat, str, *start, 0) >= 0) {\n        match = rb_backref_get();\n        regs = RMATCH(match)->regs;\n        if (BEG(0) == END(0)) {\n            /*\n             * Always consume at least one character of the input string\n             */\n            if (RSTRING(str)->len > END(0))\n                *start = END(0)+mbclen2(RSTRING(str)->ptr[END(0)],pat);\n            else\n                *start = END(0)+1;\n        }\n        else {\n            *start = END(0);\n        }\n        if (regs->num_regs == 1) {\n            return rb_reg_nth_match(0, match);\n        }\n        result = rb_ary_new2(regs->num_regs);\n        for (i=1; i < regs->num_regs; i++) {\n            rb_ary_push(result, rb_reg_nth_match(i, match));\n        }\n\n        return result;\n    }\n    return Qnil;\n}\n\n\n/*\n *  call-seq:\n *     str.scan(pattern)                         => array\n *     str.scan(pattern) {|match, ...| block }   => str\n *\n *  Both forms iterate through <i>str</i>, matching the pattern (which may be a\n *  <code>Regexp</code> or a <code>String</code>). For each match, a result is\n *  generated and either added to the result array or passed to the block. If\n *  the pattern contains no groups, each individual result consists of the\n *  matched string, <code>$&</code>.  If the pattern contains groups, each\n *  individual result is itself an array containing one entry per group.\n *\n *     a = \"cruel world\"\n *     a.scan(/\\w+/)        #=> [\"cruel\", \"world\"]\n *     a.scan(/.../)        #=> [\"cru\", \"el \", \"wor\"]\n *     a.scan(/(...)/)      #=> [[\"cru\"], [\"el \"], [\"wor\"]]\n *     a.scan(/(..)(..)/)   #=> [[\"cr\", \"ue\"], [\"l \", \"wo\"]]\n *\n *  And the block form:\n *\n *     a.scan(/\\w+/) {|w| print \"<<#{w}>> \" }\n *     print \"\\n\"\n *     a.scan(/(.)(.)/) {|x,y| print y, x }\n *     print \"\\n\"\n *\n *  <em>produces:</em>\n *\n *     <<cruel>> <<world>>\n *     rceu lowlr\n */\n\nstatic VALUE\nrb_str_scan(str, pat)\n    VALUE str, pat;\n{\n    VALUE result;\n    long start = 0;\n    VALUE match = Qnil;\n    char *p = RSTRING(str)->ptr; long len = RSTRING(str)->len;\n\n    pat = get_pat(pat, 1);\n    if (!rb_block_given_p()) {\n        VALUE ary = rb_ary_new();\n\n        while (!NIL_P(result = scan_once(str, pat, &start))) {\n            match = rb_backref_get();\n            rb_ary_push(ary, result);\n        }\n        rb_backref_set(match);\n        return ary;\n    }\n\n    while (!NIL_P(result = scan_once(str, pat, &start))) {\n        match = rb_backref_get();\n        rb_match_busy(match);\n        rb_yield(result);\n        str_mod_check(str, p, len);\n        rb_backref_set(match);  /* restore $~ value */\n    }\n    rb_backref_set(match);\n    return str;\n}\n\n/*\n *  call-seq:\n *     scan(pattern)                   => array\n *     scan(pattern) {|///| block }    => $_\n *\n *  Equivalent to calling <code>$_.scan</code>. See\n *  <code>String#scan</code>.\n */\n\nstatic VALUE\nrb_f_scan(self, pat)\n    VALUE self, pat;\n{\n    return rb_str_scan(uscore_get(), pat);\n}\n\n\n/*\n *  call-seq:\n *     str.hex   => integer\n *\n *  Treats leading characters from <i>str</i> as a string of hexadecimal digits\n *  (with an optional sign and an optional <code>0x</code>) and returns the\n *  corresponding number. Zero is returned on error.\n *\n *     \"0x0a\".hex     #=> 10\n *     \"-1234\".hex    #=> -4660\n *     \"0\".hex        #=> 0\n *     \"wombat\".hex   #=> 0\n */\n\nstatic VALUE\nrb_str_hex(str)\n    VALUE str;\n{\n    return rb_str_to_inum(str, 16, Qfalse);\n}\n\n\n/*\n *  call-seq:\n *     str.oct   => integer\n *\n *  Treats leading characters of <i>str</i> as a string of octal digits (with an\n *  optional sign) and returns the corresponding number.  Returns 0 if the\n *  conversion fails.\n *\n *     \"123\".oct       #=> 83\n *     \"-377\".oct      #=> -255\n *     \"bad\".oct       #=> 0\n *     \"0377bad\".oct   #=> 255\n */\n\nstatic VALUE\nrb_str_oct(str)\n    VALUE str;\n{\n    return rb_str_to_inum(str, -8, Qfalse);\n}\n\n\n/*\n *  call-seq:\n *     str.crypt(other_str)   => new_str\n *\n *  Applies a one-way cryptographic hash to <i>str</i> by invoking the standard\n *  library function <code>crypt</code>. The argument is the salt string, which\n *  should be two characters long, each character drawn from\n *  <code>[a-zA-Z0-9./]</code>.\n */\n\nstatic VALUE\nrb_str_crypt(str, salt)\n    VALUE str, salt;\n{\n    extern char *crypt _((const char *, const char*));\n    VALUE result;\n    const char *s;\n\n    StringValue(salt);\n    if (RSTRING(salt)->len < 2)\n        rb_raise(rb_eArgError, \"salt too short(need >=2 bytes)\");\n\n    if (RSTRING(str)->ptr) s = RSTRING(str)->ptr;\n    else s = \"\";\n    result = rb_str_new2(crypt(s, RSTRING(salt)->ptr));\n    OBJ_INFECT(result, str);\n    OBJ_INFECT(result, salt);\n    return result;\n}\n\n\n/*\n *  call-seq:\n *     str.intern   => symbol\n *     str.to_sym   => symbol\n *\n *  Returns the <code>Symbol</code> corresponding to <i>str</i>, creating the\n *  symbol if it did not previously exist. See <code>Symbol#id2name</code>.\n *\n *     \"Koala\".intern         #=> :Koala\n *     s = 'cat'.to_sym       #=> :cat\n *     s == :cat              #=> true\n *     s = '@cat'.to_sym      #=> :@cat\n *     s == :@cat             #=> true\n *\n *  This can also be used to create symbols that cannot be represented using the\n *  <code>:xxx</code> notation.\n *\n *     'cat and dog'.to_sym   #=> :\"cat and dog\"\n */\n\nVALUE\nrb_str_intern(s)\n    VALUE s;\n{\n    volatile VALUE str = s;\n    ID id;\n\n    if (!RSTRING(str)->ptr || RSTRING(str)->len == 0) {\n        rb_raise(rb_eArgError, \"interning empty string\");\n    }\n    if (strlen(RSTRING(str)->ptr) != RSTRING(str)->len)\n        rb_raise(rb_eArgError, \"symbol string may not contain `\\\\0'\");\n    if (OBJ_TAINTED(str) && rb_safe_level() >= 1 && !rb_sym_interned_p(str)) {\n        rb_raise(rb_eSecurityError, \"Insecure: can't intern tainted string\");\n    }\n    id = rb_intern(RSTRING(str)->ptr);\n    return ID2SYM(id);\n}\n\n\n/*\n *  call-seq:\n *     str.sum(n=16)   => integer\n *\n *  Returns a basic <em>n</em>-bit checksum of the characters in <i>str</i>,\n *  where <em>n</em> is the optional <code>Fixnum</code> parameter, defaulting\n *  to 16. The result is simply the sum of the binary value of each character in\n *  <i>str</i> modulo <code>2n - 1</code>. This is not a particularly good\n *  checksum.\n */\n\nstatic VALUE\nrb_str_sum(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE vbits;\n    int bits;\n    char *ptr, *p, *pend;\n    long len;\n\n    if (rb_scan_args(argc, argv, \"01\", &vbits) == 0) {\n        bits = 16;\n    }\n    else bits = NUM2INT(vbits);\n\n    ptr = p = RSTRING(str)->ptr;\n    len = RSTRING(str)->len;\n    pend = p + len;\n    if (bits >= sizeof(long)*CHAR_BIT) {\n        VALUE sum = INT2FIX(0);\n\n        while (p < pend) {\n            str_mod_check(str, ptr, len);\n            sum = rb_funcall(sum, '+', 1, INT2FIX((unsigned char)*p));\n            p++;\n        }\n        if (bits != 0) {\n            VALUE mod;\n\n            mod = rb_funcall(INT2FIX(1), rb_intern(\"<<\"), 1, INT2FIX(bits));\n            mod = rb_funcall(mod, '-', 1, INT2FIX(1));\n            sum = rb_funcall(sum, '&', 1, mod);\n        }\n        return sum;\n    }\n    else {\n       unsigned long sum = 0;\n\n        while (p < pend) {\n            str_mod_check(str, ptr, len);\n            sum += (unsigned char)*p;\n            p++;\n        }\n        if (bits != 0) {\n           sum &= (((unsigned long)1)<<bits)-1;\n        }\n        return rb_int2inum(sum);\n    }\n}\n\nstatic VALUE\nrb_str_justify(argc, argv, str, jflag)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n    char jflag;\n{\n    VALUE w;\n    long width, flen = 0;\n    VALUE res;\n    char *p, *pend;\n    const char *f = \" \";\n    long n;\n    VALUE pad;\n\n    rb_scan_args(argc, argv, \"11\", &w, &pad);\n    width = NUM2LONG(w);\n    if (argc == 2) {\n        StringValue(pad);\n        f = RSTRING(pad)->ptr;\n        flen = RSTRING(pad)->len;\n        if (flen == 0) {\n            rb_raise(rb_eArgError, \"zero width padding\");\n        }\n    }\n    if (width < 0 || RSTRING(str)->len >= width) return rb_str_dup(str);\n    res = rb_str_new5(str, 0, width);\n    p = RSTRING(res)->ptr;\n    if (jflag != 'l') {\n        n = width - RSTRING(str)->len;\n        pend = p + ((jflag == 'r') ? n : n/2);\n        if (flen <= 1) {\n            while (p < pend) {\n                *p++ = *f;\n            }\n        }\n        else {\n            const char *q = f;\n            while (p + flen <= pend) {\n                memcpy(p,f,flen);\n                p += flen;\n            }\n            while (p < pend) {\n                *p++ = *q++;\n            }\n        }\n    }\n    memcpy(p, RSTRING(str)->ptr, RSTRING(str)->len);\n    if (jflag != 'r') {\n        p += RSTRING(str)->len; pend = RSTRING(res)->ptr + width;\n        if (flen <= 1) {\n            while (p < pend) {\n                *p++ = *f;\n            }\n        }\n        else {\n            while (p + flen <= pend) {\n                memcpy(p,f,flen);\n                p += flen;\n            }\n            while (p < pend) {\n                *p++ = *f++;\n            }\n        }\n    }\n    OBJ_INFECT(res, str);\n    if (flen > 0) OBJ_INFECT(res, pad);\n    return res;\n}\n\n\n/*\n *  call-seq:\n *     str.ljust(integer, padstr=' ')   => new_str\n *\n *  If <i>integer</i> is greater than the length of <i>str</i>, returns a new\n *  <code>String</code> of length <i>integer</i> with <i>str</i> left justified\n *  and padded with <i>padstr</i>; otherwise, returns <i>str</i>.\n *\n *     \"hello\".ljust(4)            #=> \"hello\"\n *     \"hello\".ljust(20)           #=> \"hello               \"\n *     \"hello\".ljust(20, '1234')   #=> \"hello123412341234123\"\n */\n\nstatic VALUE\nrb_str_ljust(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    return rb_str_justify(argc, argv, str, 'l');\n}\n\n\n/*\n *  call-seq:\n *     str.rjust(integer, padstr=' ')   => new_str\n *\n *  If <i>integer</i> is greater than the length of <i>str</i>, returns a new\n *  <code>String</code> of length <i>integer</i> with <i>str</i> right justified\n *  and padded with <i>padstr</i>; otherwise, returns <i>str</i>.\n *\n *     \"hello\".rjust(4)            #=> \"hello\"\n *     \"hello\".rjust(20)           #=> \"               hello\"\n *     \"hello\".rjust(20, '1234')   #=> \"123412341234123hello\"\n */\n\nstatic VALUE\nrb_str_rjust(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    return rb_str_justify(argc, argv, str, 'r');\n}\n\n\n/*\n *  call-seq:\n *     str.center(integer, padstr)   => new_str\n *\n *  If <i>integer</i> is greater than the length of <i>str</i>, returns a new\n *  <code>String</code> of length <i>integer</i> with <i>str</i> centered and\n *  padded with <i>padstr</i>; otherwise, returns <i>str</i>.\n *\n *     \"hello\".center(4)         #=> \"hello\"\n *     \"hello\".center(20)        #=> \"       hello        \"\n *     \"hello\".center(20, '123') #=> \"1231231hello12312312\"\n */\n\nstatic VALUE\nrb_str_center(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    return rb_str_justify(argc, argv, str, 'c');\n}\n\n/*\n *  call-seq:\n *     str.partition(sep)              => [head, sep, tail]\n *\n *  Searches the string for <i>sep</i> and returns the part before it,\n *  the <i>sep</i>, and the part after it.  If <i>sep</i> is not\n *  found, returns <i>str</i> and two empty strings.  If no argument\n *  is given, Enumerable#partition is called.\n *\n *     \"hello\".partition(\"l\")         #=> [\"he\", \"l\", \"lo\"]\n *     \"hello\".partition(\"x\")         #=> [\"hello\", \"\", \"\"]\n */\n\nstatic VALUE\nrb_str_partition(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    VALUE sep;\n    long pos;\n\n    if (argc == 0) return rb_call_super(argc, argv);\n    rb_scan_args(argc, argv, \"1\", &sep);\n    if (TYPE(sep) != T_REGEXP) {\n        VALUE tmp;\n\n        tmp = rb_check_string_type(sep);\n        if (NIL_P(tmp)) {\n            rb_raise(rb_eTypeError, \"type mismatch: %s given\",\n                     rb_obj_classname(sep));\n        }\n        sep = get_arg_pat(tmp);\n    }\n    pos = rb_reg_search(sep, str, 0, 0);\n    if (pos < 0) {\n      failed:\n        return rb_ary_new3(3, str, rb_str_new(0,0),rb_str_new(0,0));\n    }\n    sep = rb_str_subpat(str, sep, 0);\n    if (pos == 0 && RSTRING(sep)->len == 0) goto failed;\n    return rb_ary_new3(3, rb_str_substr(str, 0, pos),\n                          sep,\n                          rb_str_substr(str, pos+RSTRING(sep)->len,\n                                             RSTRING(str)->len-pos-RSTRING(sep)->len));\n}\n\n/*\n *  call-seq:\n *     str.rpartition(sep)            => [head, sep, tail]\n *\n *  Searches <i>sep</i> in the string from the end of the string, and\n *  returns the part before it, the <i>sep</i>, and the part after it.\n *  If <i>sep</i> is not found, returns two empty strings and\n *  <i>str</i>.\n *\n *     \"hello\".rpartition(\"l\")         #=> [\"hel\", \"l\", \"o\"]\n *     \"hello\".rpartition(\"x\")         #=> [\"\", \"\", \"hello\"]\n */\n\nstatic VALUE\nrb_str_rpartition(str, sep)\n    VALUE str;\n    VALUE sep;\n{\n    long pos = RSTRING(str)->len;\n\n    if (TYPE(sep) != T_REGEXP) {\n        VALUE tmp;\n\n        tmp = rb_check_string_type(sep);\n        if (NIL_P(tmp)) {\n            rb_raise(rb_eTypeError, \"type mismatch: %s given\",\n                     rb_obj_classname(sep));\n        }\n        sep = get_arg_pat(tmp);\n    }\n    pos = rb_reg_search(sep, str, pos, 1);\n    if (pos < 0) {\n        return rb_ary_new3(3, rb_str_new(0,0),rb_str_new(0,0), str);\n    }\n    sep = rb_reg_nth_match(0, rb_backref_get());\n    return rb_ary_new3(3, rb_str_substr(str, 0, pos),\n                          sep,\n                          rb_str_substr(str, pos+RSTRING(sep)->len,\n                                             RSTRING(str)->len-pos-RSTRING(sep)->len));\n}\n\n/*\n *  call-seq:\n *     str.start_with?([prefix]+)   => true or false\n *\n *  Returns true if <i>str</i> starts with the prefix given.\n */\n\nstatic VALUE\nrb_str_start_with(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    int i;\n    VALUE pat;\n\n    for (i=0; i<argc; i++) {\n        VALUE prefix = rb_check_string_type(argv[i]);\n        if (NIL_P(prefix)) continue;\n        if (RSTRING(str)->len < RSTRING(prefix)->len) continue;\n        pat = get_arg_pat(prefix);\n        if (rb_reg_search(pat, str, 0, 1) >= 0)\n            return Qtrue;\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     str.end_with?([suffix]+)   => true or false\n *\n *  Returns true if <i>str</i> ends with the suffix given.\n */\n\nstatic VALUE\nrb_str_end_with(argc, argv, str)\n    int argc;\n    VALUE *argv;\n    VALUE str;\n{\n    int i;\n    long pos;\n    VALUE pat;\n\n    for (i=0; i<argc; i++) {\n        VALUE suffix = rb_check_string_type(argv[i]);\n        if (NIL_P(suffix)) continue;\n        if (RSTRING(str)->len < RSTRING(suffix)->len) continue;\n        pat = get_arg_pat(suffix);\n        pos = rb_reg_adjust_startpos(pat, str, RSTRING(str)->len - RSTRING(suffix)->len, 0);\n        if (rb_reg_search(pat, str, pos, 0) >= 0)\n            return Qtrue;\n    }\n    return Qfalse;\n}\n\nvoid\nrb_str_setter(val, id, var)\n    VALUE val;\n    ID id;\n    VALUE *var;\n{\n    if (!NIL_P(val) && TYPE(val) != T_STRING) {\n        rb_raise(rb_eTypeError, \"value of %s must be String\", rb_id2name(id));\n    }\n    *var = val;\n}\n\n\n/*\n *  A <code>String</code> object holds and manipulates an arbitrary sequence of\n *  bytes, typically representing characters. String objects may be created\n *  using <code>String::new</code> or as literals.\n *\n *  Because of aliasing issues, users of strings should be aware of the methods\n *  that modify the contents of a <code>String</code> object.  Typically,\n *  methods with names ending in ``!'' modify their receiver, while those\n *  without a ``!'' return a new <code>String</code>.  However, there are\n *  exceptions, such as <code>String#[]=</code>.\n *\n */\n\nvoid\nInit_String()\n{\n    rb_cString  = rb_define_class(\"String\", rb_cObject);\n    rb_include_module(rb_cString, rb_mComparable);\n    rb_include_module(rb_cString, rb_mEnumerable);\n    rb_define_alloc_func(rb_cString, rb_str_s_alloc);\n    rb_define_method(rb_cString, \"initialize\", rb_str_init, -1);\n    rb_define_method(rb_cString, \"initialize_copy\", rb_str_replace, 1);\n    rb_define_method(rb_cString, \"<=>\", rb_str_cmp_m, 1);\n    rb_define_method(rb_cString, \"==\", rb_str_equal, 1);\n    rb_define_method(rb_cString, \"eql?\", rb_str_eql, 1);\n    rb_define_method(rb_cString, \"hash\", rb_str_hash_m, 0);\n    rb_define_method(rb_cString, \"casecmp\", rb_str_casecmp, 1);\n    rb_define_method(rb_cString, \"+\", rb_str_plus, 1);\n    rb_define_method(rb_cString, \"*\", rb_str_times, 1);\n    rb_define_method(rb_cString, \"%\", rb_str_format_m, 1);\n    rb_define_method(rb_cString, \"[]\", rb_str_aref_m, -1);\n    rb_define_method(rb_cString, \"[]=\", rb_str_aset_m, -1);\n    rb_define_method(rb_cString, \"insert\", rb_str_insert, 2);\n    rb_define_method(rb_cString, \"length\", rb_str_length, 0);\n    rb_define_method(rb_cString, \"size\", rb_str_length, 0);\n    rb_define_method(rb_cString, \"bytesize\", rb_str_length, 0);\n    rb_define_method(rb_cString, \"empty?\", rb_str_empty, 0);\n    rb_define_method(rb_cString, \"=~\", rb_str_match, 1);\n    rb_define_method(rb_cString, \"match\", rb_str_match_m, 1);\n    rb_define_method(rb_cString, \"succ\", rb_str_succ, 0);\n    rb_define_method(rb_cString, \"succ!\", rb_str_succ_bang, 0);\n    rb_define_method(rb_cString, \"next\", rb_str_succ, 0);\n    rb_define_method(rb_cString, \"next!\", rb_str_succ_bang, 0);\n    rb_define_method(rb_cString, \"upto\", rb_str_upto_m, -1);\n    rb_define_method(rb_cString, \"index\", rb_str_index_m, -1);\n    rb_define_method(rb_cString, \"rindex\", rb_str_rindex_m, -1);\n    rb_define_method(rb_cString, \"replace\", rb_str_replace, 1);\n\n    rb_define_method(rb_cString, \"to_i\", rb_str_to_i, -1);\n    rb_define_method(rb_cString, \"to_f\", rb_str_to_f, 0);\n    rb_define_method(rb_cString, \"to_s\", rb_str_to_s, 0);\n    rb_define_method(rb_cString, \"to_str\", rb_str_to_s, 0);\n    rb_define_method(rb_cString, \"inspect\", rb_str_inspect, 0);\n    rb_define_method(rb_cString, \"dump\", rb_str_dump, 0);\n\n    rb_define_method(rb_cString, \"upcase\", rb_str_upcase, 0);\n    rb_define_method(rb_cString, \"downcase\", rb_str_downcase, 0);\n    rb_define_method(rb_cString, \"capitalize\", rb_str_capitalize, 0);\n    rb_define_method(rb_cString, \"swapcase\", rb_str_swapcase, 0);\n\n    rb_define_method(rb_cString, \"upcase!\", rb_str_upcase_bang, 0);\n    rb_define_method(rb_cString, \"downcase!\", rb_str_downcase_bang, 0);\n    rb_define_method(rb_cString, \"capitalize!\", rb_str_capitalize_bang, 0);\n    rb_define_method(rb_cString, \"swapcase!\", rb_str_swapcase_bang, 0);\n\n    rb_define_method(rb_cString, \"hex\", rb_str_hex, 0);\n    rb_define_method(rb_cString, \"oct\", rb_str_oct, 0);\n    rb_define_method(rb_cString, \"split\", rb_str_split_m, -1);\n    rb_define_method(rb_cString, \"reverse\", rb_str_reverse, 0);\n    rb_define_method(rb_cString, \"reverse!\", rb_str_reverse_bang, 0);\n    rb_define_method(rb_cString, \"concat\", rb_str_concat, 1);\n    rb_define_method(rb_cString, \"<<\", rb_str_concat, 1);\n    rb_define_method(rb_cString, \"crypt\", rb_str_crypt, 1);\n    rb_define_method(rb_cString, \"intern\", rb_str_intern, 0);\n    rb_define_method(rb_cString, \"to_sym\", rb_str_intern, 0);\n\n    rb_define_method(rb_cString, \"include?\", rb_str_include, 1);\n    rb_define_method(rb_cString, \"start_with?\", rb_str_start_with, -1);\n    rb_define_method(rb_cString, \"end_with?\", rb_str_end_with, -1);\n\n    rb_define_method(rb_cString, \"scan\", rb_str_scan, 1);\n\n    rb_define_method(rb_cString, \"ljust\", rb_str_ljust, -1);\n    rb_define_method(rb_cString, \"rjust\", rb_str_rjust, -1);\n    rb_define_method(rb_cString, \"center\", rb_str_center, -1);\n\n    rb_define_method(rb_cString, \"sub\", rb_str_sub, -1);\n    rb_define_method(rb_cString, \"gsub\", rb_str_gsub, -1);\n    rb_define_method(rb_cString, \"chop\", rb_str_chop, 0);\n    rb_define_method(rb_cString, \"chomp\", rb_str_chomp, -1);\n    rb_define_method(rb_cString, \"strip\", rb_str_strip, 0);\n    rb_define_method(rb_cString, \"lstrip\", rb_str_lstrip, 0);\n    rb_define_method(rb_cString, \"rstrip\", rb_str_rstrip, 0);\n\n    rb_define_method(rb_cString, \"sub!\", rb_str_sub_bang, -1);\n    rb_define_method(rb_cString, \"gsub!\", rb_str_gsub_bang, -1);\n    rb_define_method(rb_cString, \"chop!\", rb_str_chop_bang, 0);\n    rb_define_method(rb_cString, \"chomp!\", rb_str_chomp_bang, -1);\n    rb_define_method(rb_cString, \"strip!\", rb_str_strip_bang, 0);\n    rb_define_method(rb_cString, \"lstrip!\", rb_str_lstrip_bang, 0);\n    rb_define_method(rb_cString, \"rstrip!\", rb_str_rstrip_bang, 0);\n\n    rb_define_method(rb_cString, \"tr\", rb_str_tr, 2);\n    rb_define_method(rb_cString, \"tr_s\", rb_str_tr_s, 2);\n    rb_define_method(rb_cString, \"delete\", rb_str_delete, -1);\n    rb_define_method(rb_cString, \"squeeze\", rb_str_squeeze, -1);\n    rb_define_method(rb_cString, \"count\", rb_str_count, -1);\n\n    rb_define_method(rb_cString, \"tr!\", rb_str_tr_bang, 2);\n    rb_define_method(rb_cString, \"tr_s!\", rb_str_tr_s_bang, 2);\n    rb_define_method(rb_cString, \"delete!\", rb_str_delete_bang, -1);\n    rb_define_method(rb_cString, \"squeeze!\", rb_str_squeeze_bang, -1);\n\n    rb_define_method(rb_cString, \"each_line\", rb_str_each_line, -1);\n    rb_define_method(rb_cString, \"each\",      rb_str_each_line, -1);\n    rb_define_method(rb_cString, \"each_byte\", rb_str_each_byte, 0);\n    rb_define_method(rb_cString, \"each_char\", rb_str_each_char, 0);\n\n    rb_define_method(rb_cString, \"lines\", rb_str_each_line, -1);\n    rb_define_method(rb_cString, \"bytes\", rb_str_each_byte, 0);\n    rb_define_method(rb_cString, \"chars\", rb_str_each_char, 0);\n\n    rb_define_method(rb_cString, \"sum\", rb_str_sum, -1);\n\n    rb_define_global_function(\"sub\", rb_f_sub, -1);\n    rb_define_global_function(\"gsub\", rb_f_gsub, -1);\n\n    rb_define_global_function(\"sub!\", rb_f_sub_bang, -1);\n    rb_define_global_function(\"gsub!\", rb_f_gsub_bang, -1);\n\n    rb_define_global_function(\"chop\", rb_f_chop, 0);\n    rb_define_global_function(\"chop!\", rb_f_chop_bang, 0);\n\n    rb_define_global_function(\"chomp\", rb_f_chomp, -1);\n    rb_define_global_function(\"chomp!\", rb_f_chomp_bang, -1);\n\n    rb_define_global_function(\"split\", rb_f_split, -1);\n    rb_define_global_function(\"scan\", rb_f_scan, 1);\n\n    rb_define_method(rb_cString, \"slice\", rb_str_aref_m, -1);\n    rb_define_method(rb_cString, \"slice!\", rb_str_slice_bang, -1);\n\n    rb_define_method(rb_cString, \"partition\", rb_str_partition, -1);\n    rb_define_method(rb_cString, \"rpartition\", rb_str_rpartition, 1);\n\n#ifdef GC_DEBUG\n    rb_define_method(rb_cString, \"__char_ptr__\", rb_str_char_ptr, 0);\n#endif\n\n    id_to_s = rb_intern(\"to_s\");\n\n    rb_fs = Qnil;\n    rb_define_variable(\"$;\", &rb_fs);\n    rb_define_variable(\"$-F\", &rb_fs);\n}\n"
  },
  {
    "path": "struct.c",
    "content": "/**********************************************************************\n\n  struct.c -\n\n  $Author$\n  $Date$\n  created at: Tue Mar 22 18:44:30 JST 1995\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"env.h\"\n\nVALUE rb_cStruct;\n\nstatic VALUE struct_alloc _((VALUE));\n\nVALUE\nrb_struct_iv_get(c, name)\n    VALUE c;\n    const char *name;\n{\n    ID id;\n\n    id = rb_intern(name);\n    for (;;) {\n\tif (rb_ivar_defined(c, id))\n\t    return rb_ivar_get(c, id);\n\tc = RCLASS(c)->super;\n\tif (c == 0 || c == rb_cStruct)\n\t    return Qnil;\n    }\n}\n\nVALUE\nrb_struct_s_members(klass)\n    VALUE klass;\n{\n    VALUE members = rb_struct_iv_get(klass, \"__members__\");\n\n    if (NIL_P(members)) {\n\trb_raise(rb_eTypeError, \"uninitialized struct\");\n    }\n    if (TYPE(members) != T_ARRAY) {\n\trb_raise(rb_eTypeError, \"corrupted struct\");\n    }\n    return members;\n}\n\nVALUE\nrb_struct_members(s)\n    VALUE s;\n{\n    VALUE members = rb_struct_s_members(rb_obj_class(s));\n\n    if (RSTRUCT(s)->len != RARRAY(members)->len) {\n\trb_raise(rb_eTypeError, \"struct size differs (%d required %d given)\",\n\t\t RARRAY(members)->len, RSTRUCT(s)->len);\n    }\n    return members;\n}\n\nstatic VALUE\nrb_struct_s_members_m(klass)\n    VALUE klass;\n{\n    VALUE members, ary;\n    VALUE *p, *pend;\n\n    members = rb_struct_s_members(klass);\n    ary = rb_ary_new2(RARRAY(members)->len);\n    p = RARRAY(members)->ptr; pend = p + RARRAY(members)->len;\n    while (p < pend) {\n\trb_ary_push(ary, rb_str_new2(rb_id2name(SYM2ID(*p))));\n\tp++;\n    }\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     struct.members    => array\n *  \n *  Returns an array of strings representing the names of the instance\n *  variables.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     joe.members   #=> [\"name\", \"address\", \"zip\"]\n */\n\nstatic VALUE\nrb_struct_members_m(obj)\n    VALUE obj;\n{\n    return rb_struct_s_members_m(rb_obj_class(obj));\n}\n\nVALUE\nrb_struct_getmember(obj, id)\n    VALUE obj;\n    ID id;\n{\n    VALUE members, slot;\n    long i;\n\n    members = rb_struct_members(obj);\n    slot = ID2SYM(id);\n    for (i=0; i<RARRAY(members)->len; i++) {\n\tif (RARRAY(members)->ptr[i] == slot) {\n\t    return RSTRUCT(obj)->ptr[i];\n\t}\n    }\n    rb_name_error(id, \"%s is not struct member\", rb_id2name(id));\n    return Qnil;\t\t/* not reached */\n}\n\nstatic VALUE\nrb_struct_ref(obj)\n    VALUE obj;\n{\n    return rb_struct_getmember(obj, ruby_frame->orig_func);\n}\n\nstatic VALUE rb_struct_ref0(obj) VALUE obj; {return RSTRUCT(obj)->ptr[0];}\nstatic VALUE rb_struct_ref1(obj) VALUE obj; {return RSTRUCT(obj)->ptr[1];}\nstatic VALUE rb_struct_ref2(obj) VALUE obj; {return RSTRUCT(obj)->ptr[2];}\nstatic VALUE rb_struct_ref3(obj) VALUE obj; {return RSTRUCT(obj)->ptr[3];}\nstatic VALUE rb_struct_ref4(obj) VALUE obj; {return RSTRUCT(obj)->ptr[4];}\nstatic VALUE rb_struct_ref5(obj) VALUE obj; {return RSTRUCT(obj)->ptr[5];}\nstatic VALUE rb_struct_ref6(obj) VALUE obj; {return RSTRUCT(obj)->ptr[6];}\nstatic VALUE rb_struct_ref7(obj) VALUE obj; {return RSTRUCT(obj)->ptr[7];}\nstatic VALUE rb_struct_ref8(obj) VALUE obj; {return RSTRUCT(obj)->ptr[8];}\nstatic VALUE rb_struct_ref9(obj) VALUE obj; {return RSTRUCT(obj)->ptr[9];}\n\nstatic VALUE (*ref_func[10])() = {\n    rb_struct_ref0,\n    rb_struct_ref1,\n    rb_struct_ref2,\n    rb_struct_ref3,\n    rb_struct_ref4,\n    rb_struct_ref5,\n    rb_struct_ref6,\n    rb_struct_ref7,\n    rb_struct_ref8,\n    rb_struct_ref9,\n};\n\nstatic void\nrb_struct_modify(s)\n    VALUE s;\n{\n    if (OBJ_FROZEN(s)) rb_error_frozen(\"Struct\");\n    if (!OBJ_TAINTED(s) && rb_safe_level() >= 4)\n       rb_raise(rb_eSecurityError, \"Insecure: can't modify Struct\");\n}\n\nstatic VALUE\nrb_struct_set(obj, val)\n    VALUE obj, val;\n{\n    VALUE members, slot;\n    ID id;\n    long i;\n\n    members = rb_struct_members(obj);\n    rb_struct_modify(obj);\n    id = ruby_frame->orig_func;\n    for (i=0; i<RARRAY(members)->len; i++) {\n\tslot = RARRAY(members)->ptr[i];\n\tif (rb_id_attrset(SYM2ID(slot)) == id) {\n\t    return RSTRUCT(obj)->ptr[i] = val;\n\t}\n    }\n    rb_name_error(ruby_frame->last_func, \"`%s' is not a struct member\",\n\t\t  rb_id2name(id));\n    return Qnil;\t\t/* not reached */\n}\n\nstatic VALUE\nmake_struct(name, members, klass)\n    VALUE name, members, klass;\n{\n    VALUE nstr;\n    ID id;\n    long i;\n\n    OBJ_FREEZE(members);\n    if (NIL_P(name)) {\n\tnstr = rb_class_new(klass);\n\trb_make_metaclass(nstr, RBASIC(klass)->klass);\n\trb_class_inherited(klass, nstr);\n    }\n    else {\n\tchar *cname = StringValuePtr(name);\n\tid = rb_intern(cname);\n\tif (!rb_is_const_id(id)) {\n\t    rb_name_error(id, \"identifier %s needs to be constant\", cname);\n\t}\n\tif (rb_const_defined_at(klass, id)) {\n\t    rb_warn(\"redefining constant Struct::%s\", cname);\n\t    rb_mod_remove_const(klass, ID2SYM(id));\n\t}\n\tnstr = rb_define_class_under(klass, rb_id2name(id), klass);\n    }\n    rb_iv_set(nstr, \"__size__\", LONG2NUM(RARRAY(members)->len));\n    rb_iv_set(nstr, \"__members__\", members);\n\n    rb_define_alloc_func(nstr, struct_alloc);\n    rb_define_singleton_method(nstr, \"new\", rb_class_new_instance, -1);\n    rb_define_singleton_method(nstr, \"[]\", rb_class_new_instance, -1);\n    rb_define_singleton_method(nstr, \"members\", rb_struct_s_members_m, 0);\n    for (i=0; i< RARRAY(members)->len; i++) {\n\tID id = SYM2ID(RARRAY(members)->ptr[i]);\n\tif (rb_is_local_id(id) || rb_is_const_id(id)) {\n\t    if (i<10) {\n\t\trb_define_method_id(nstr, id, ref_func[i], 0);\n\t    }\n\t    else {\n\t\trb_define_method_id(nstr, id, rb_struct_ref, 0);\n\t    }\n\t    rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1);\n\t}\n    }\n\n    return nstr;\n}\n\n#ifdef HAVE_STDARG_PROTOTYPES\n#include <stdarg.h>\n#define va_init_list(a,b) va_start(a,b)\n#else\n#include <varargs.h>\n#define va_init_list(a,b) va_start(a)\n#endif\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_struct_define(const char *name, ...)\n#else\nrb_struct_define(name, va_alist)\n    const char *name;\n    va_dcl\n#endif\n{\n    va_list ar;\n    VALUE nm, ary;\n    char *mem;\n\n    if (!name) nm = Qnil;\n    else nm = rb_str_new2(name);\n    ary = rb_ary_new();\n\n    va_init_list(ar, name);\n    while ((mem = va_arg(ar, char*)) != 0) {\n\tID slot = rb_intern(mem);\n\trb_ary_push(ary, ID2SYM(slot));\n    }\n    va_end(ar);\n\n    return make_struct(nm, ary, rb_cStruct);\n}\n\n/*\n *  call-seq:\n *     Struct.new( [aString] [, aSym]+> )    => StructClass\n *     StructClass.new(arg, ...)             => obj\n *     StructClass[arg, ...]                 => obj\n *\n *  Creates a new class, named by <i>aString</i>, containing accessor\n *  methods for the given symbols. If the name <i>aString</i> is\n *  omitted, an anonymous structure class will be created. Otherwise,\n *  the name of this struct will appear as a constant in class\n *  <code>Struct</code>, so it must be unique for all\n *  <code>Struct</code>s in the system and should start with a capital\n *  letter. Assigning a structure class to a constant effectively gives\n *  the class the name of the constant.\n *     \n *  <code>Struct::new</code> returns a new <code>Class</code> object,\n *  which can then be used to create specific instances of the new\n *  structure. The number of actual parameters must be\n *  less than or equal to the number of attributes defined for this\n *  class; unset parameters default to \\nil{}.  Passing too many\n *  parameters will raise an \\E{ArgumentError}.\n *\n *  The remaining methods listed in this section (class and instance)\n *  are defined for this generated class. \n *     \n *     # Create a structure with a name in Struct\n *     Struct.new(\"Customer\", :name, :address)    #=> Struct::Customer\n *     Struct::Customer.new(\"Dave\", \"123 Main\")   #=> #<Struct::Customer name=\"Dave\", address=\"123 Main\">\n *     \n *     # Create a structure named by its constant\n *     Customer = Struct.new(:name, :address)     #=> Customer\n *     Customer.new(\"Dave\", \"123 Main\")           #=> #<Customer name=\"Dave\", address=\"123 Main\">\n */\n\nstatic VALUE\nrb_struct_s_def(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    VALUE name, rest;\n    long i;\n    VALUE st;\n    ID id;\n\n    rb_scan_args(argc, argv, \"1*\", &name, &rest);\n    if (!NIL_P(name) && SYMBOL_P(name)) {\n\trb_ary_unshift(rest, name);\n\tname = Qnil;\n    }\n    for (i=0; i<RARRAY(rest)->len; i++) {\n\tid = rb_to_id(RARRAY(rest)->ptr[i]);\n\tRARRAY(rest)->ptr[i] = ID2SYM(id);\n    }\n    st = make_struct(name, rest, klass);\n    if (rb_block_given_p()) {\n\trb_mod_module_eval(0, 0, st);\n    }\n\n    return st;\n}\n\n/*\n */\n\nstatic VALUE\nrb_struct_initialize(self, values)\n    VALUE self, values;\n{\n    VALUE klass = rb_obj_class(self);\n    VALUE size;\n    long n;\n\n    rb_struct_modify(self);\n    size = rb_struct_iv_get(klass, \"__size__\");\n    n = FIX2LONG(size);\n    if (n < RARRAY(values)->len) {\n\trb_raise(rb_eArgError, \"struct size differs\");\n    }\n    MEMCPY(RSTRUCT(self)->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);\n    if (n > RARRAY(values)->len) {\n\trb_mem_clear(RSTRUCT(self)->ptr+RARRAY(values)->len,\n\t\t     n-RARRAY(values)->len);\n    }\n    return Qnil;\n}\n\nstatic VALUE\nstruct_alloc(klass)\n    VALUE klass;\n{\n    VALUE size;\n    long n;\n    NEWOBJ(st, struct RStruct);\n    OBJSETUP(st, klass, T_STRUCT);\n\n    size = rb_struct_iv_get(klass, \"__size__\");\n    n = FIX2LONG(size);\n\n    st->ptr = ALLOC_N(VALUE, n);\n    rb_mem_clear(st->ptr, n);\n    st->len = n;\n\n    return (VALUE)st;\n}\n\nVALUE\nrb_struct_alloc(klass, values)\n    VALUE klass, values;\n{\n    return rb_class_new_instance(RARRAY(values)->len, RARRAY(values)->ptr, klass);\n}\n\nVALUE\n#ifdef HAVE_STDARG_PROTOTYPES\nrb_struct_new(VALUE klass, ...)\n#else\nrb_struct_new(klass, va_alist)\n    VALUE klass;\n    va_dcl\n#endif\n{\n    VALUE sz, *mem;\n    long size, i;\n    va_list args;\n\n    sz = rb_struct_iv_get(klass, \"__size__\");\n    size = FIX2LONG(sz); \n    mem = ALLOCA_N(VALUE, size);\n    va_init_list(args, klass);\n    for (i=0; i<size; i++) {\n\tmem[i] = va_arg(args, VALUE);\n    }\n    va_end(args);\n\n    return rb_class_new_instance(size, mem, klass);\n}\n\n/*\n *  call-seq:\n *     struct.each {|obj| block }  => struct\n *  \n *  Calls <i>block</i> once for each instance variable, passing the\n *  value as a parameter.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     joe.each {|x| puts(x) }\n *     \n *  <em>produces:</em>\n *     \n *     Joe Smith\n *     123 Maple, Anytown NC\n *     12345\n */\n\nstatic VALUE\nrb_struct_each(s)\n    VALUE s;\n{\n    long i;\n\n    RETURN_ENUMERATOR(s, 0, 0);\n    for (i=0; i<RSTRUCT(s)->len; i++) {\n\trb_yield(RSTRUCT(s)->ptr[i]);\n    }\n    return s;\n}\n\n/*\n *  call-seq:\n *     struct.each_pair {|sym, obj| block }     => struct\n *  \n *  Calls <i>block</i> once for each instance variable, passing the name\n *  (as a symbol) and the value as parameters.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     joe.each_pair {|name, value| puts(\"#{name} => #{value}\") }\n *     \n *  <em>produces:</em>\n *     \n *     name => Joe Smith\n *     address => 123 Maple, Anytown NC\n *     zip => 12345\n */\n\nstatic VALUE\nrb_struct_each_pair(s)\n    VALUE s;\n{\n    VALUE members;\n    long i;\n\n    RETURN_ENUMERATOR(s, 0, 0);\n    members = rb_struct_members(s);\n    for (i=0; i<RSTRUCT(s)->len; i++) {\n\trb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]);\n    }\n    return s;\n}\n\nstatic VALUE\ninspect_struct(s)\n    VALUE s;\n{\n    const char *cname = rb_class2name(rb_obj_class(s));\n    VALUE str, members;\n    long i;\n\n    members = rb_struct_members(s);\n    str = rb_str_buf_new2(\"#<struct \");\n    rb_str_cat2(str, cname);\n    rb_str_cat2(str, \" \");\n    for (i=0; i<RSTRUCT(s)->len; i++) {\n\tVALUE slot;\n\tID id;\n\tconst char *p;\n\n\tif (i > 0) {\n\t    rb_str_cat2(str, \", \");\n\t}\n\tslot = RARRAY(members)->ptr[i];\n\tid = SYM2ID(slot);\n\tif (rb_is_local_id(id) || rb_is_const_id(id)) {\n\t    p = rb_id2name(id);\n\t    rb_str_cat2(str, p);\n\t}\n\telse {\n\t    rb_str_append(str, rb_inspect(slot));\n\t}\n\trb_str_cat2(str, \"=\");\n\trb_str_append(str, rb_inspect(RSTRUCT(s)->ptr[i]));\n    }\n    rb_str_cat2(str, \">\");\n    OBJ_INFECT(str, s);\n\n    return str;\n}\n\n/*\n * call-seq:\n *   struct.to_s      => string\n *   struct.inspect   => string\n *\n * Describe the contents of this struct in a string.\n */\n\nstatic VALUE\nrb_struct_inspect(s)\n    VALUE s;\n{\n    if (rb_inspecting_p(s)) {\n\tconst char *cname = rb_class2name(rb_obj_class(s));\n\tsize_t len = strlen(cname) + 14;\n\tVALUE str = rb_str_new(0, len);\n\n\tsnprintf(RSTRING(str)->ptr, len+1, \"#<struct %s:...>\", cname);\n\tRSTRING(str)->len = strlen(RSTRING(str)->ptr);\n\treturn str;\n    }\n    return rb_protect_inspect(inspect_struct, s, 0);\n}\n\n/*\n *  call-seq:\n *     struct.to_a     => array\n *     struct.values   => array\n *  \n *  Returns the values for this instance as an array.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     joe.to_a[1]   #=> \"123 Maple, Anytown NC\"\n */\n\nstatic VALUE\nrb_struct_to_a(s)\n    VALUE s;\n{\n    return rb_ary_new4(RSTRUCT(s)->len, RSTRUCT(s)->ptr);\n}\n\n/* :nodoc: */\nstatic VALUE\nrb_struct_init_copy(copy, s)\n    VALUE copy, s;\n{\n    if (copy == s) return copy;\n    rb_check_frozen(copy);\n    if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {\n\trb_raise(rb_eTypeError, \"wrong argument class\");\n    }\n    if (RSTRUCT(copy)->len != RSTRUCT(s)->len) {\n\trb_raise(rb_eTypeError, \"struct size mismatch\");\n    }\n    MEMCPY(RSTRUCT(copy)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(copy)->len);\n\n    return copy;\n}\n\nstatic VALUE\nrb_struct_aref_id(s, id)\n    VALUE s;\n    ID id;\n{\n    VALUE members;\n    long i, len;\n\n    members = rb_struct_members(s);\n    len = RARRAY(members)->len;\n    for (i=0; i<len; i++) {\n\tif (SYM2ID(RARRAY(members)->ptr[i]) == id) {\n\t    return RSTRUCT(s)->ptr[i];\n\t}\n    }\n    rb_name_error(id, \"no member '%s' in struct\", rb_id2name(id));\n    return Qnil;\t\t/* not reached */\n}\n\n/*\n *  call-seq:\n *     struct[symbol]    => anObject\n *     struct[fixnum]    => anObject \n *  \n *  Attribute Reference---Returns the value of the instance variable\n *  named by <i>symbol</i>, or indexed (0..length-1) by\n *  <i>fixnum</i>. Will raise <code>NameError</code> if the named\n *  variable does not exist, or <code>IndexError</code> if the index is\n *  out of range.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     \n *     joe[\"name\"]   #=> \"Joe Smith\"\n *     joe[:name]    #=> \"Joe Smith\"\n *     joe[0]        #=> \"Joe Smith\"\n */\n\nVALUE\nrb_struct_aref(s, idx)\n    VALUE s, idx;\n{\n    long i;\n\n    if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {\n\treturn rb_struct_aref_id(s, rb_to_id(idx));\n    }\n\n    i = NUM2LONG(idx);\n    if (i < 0) i = RSTRUCT(s)->len + i;\n    if (i < 0)\n        rb_raise(rb_eIndexError, \"offset %ld too small for struct(size:%ld)\",\n\t\t i, RSTRUCT(s)->len);\n    if (RSTRUCT(s)->len <= i)\n        rb_raise(rb_eIndexError, \"offset %ld too large for struct(size:%ld)\",\n\t\t i, RSTRUCT(s)->len);\n    return RSTRUCT(s)->ptr[i];\n}\n\nstatic VALUE\nrb_struct_aset_id(s, id, val)\n    VALUE s, val;\n    ID id;\n{\n    VALUE members;\n    long i, len;\n\n    members = rb_struct_members(s);\n    rb_struct_modify(s);\n    len = RARRAY(members)->len;\n    if (RSTRUCT(s)->len != RARRAY(members)->len) {\n\trb_raise(rb_eTypeError, \"struct size differs (%d required %d given)\",\n\t\t RARRAY(members)->len, RSTRUCT(s)->len);\n    }\n    for (i=0; i<len; i++) {\n\tif (SYM2ID(RARRAY(members)->ptr[i]) == id) {\n\t    RSTRUCT(s)->ptr[i] = val;\n\t    return val;\n\t}\n    }\n    rb_name_error(id, \"no member '%s' in struct\", rb_id2name(id));\n}\n\n/*\n *  call-seq:\n *     struct[symbol] = obj    => obj\n *     struct[fixnum] = obj    => obj\n *  \n *  Attribute Assignment---Assigns to the instance variable named by\n *  <i>symbol</i> or <i>fixnum</i> the value <i>obj</i> and\n *  returns it. Will raise a <code>NameError</code> if the named\n *  variable does not exist, or an <code>IndexError</code> if the index\n *  is out of range.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     \n *     joe[\"name\"] = \"Luke\"\n *     joe[:zip]   = \"90210\"\n *     \n *     joe.name   #=> \"Luke\"\n *     joe.zip    #=> \"90210\"\n */\n\nVALUE\nrb_struct_aset(s, idx, val)\n    VALUE s, idx, val;\n{\n    long i;\n\n    if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {\n\treturn rb_struct_aset_id(s, rb_to_id(idx), val);\n    }\n\n    i = NUM2LONG(idx);\n    if (i < 0) i = RSTRUCT(s)->len + i;\n    if (i < 0) {\n        rb_raise(rb_eIndexError, \"offset %ld too small for struct(size:%ld)\",\n\t\t i, RSTRUCT(s)->len);\n    }\n    if (RSTRUCT(s)->len <= i) {\n        rb_raise(rb_eIndexError, \"offset %ld too large for struct(size:%ld)\",\n\t\t i, RSTRUCT(s)->len);\n    }\n    rb_struct_modify(s);\n    return RSTRUCT(s)->ptr[i] = val;\n}\n\nstatic VALUE struct_entry _((VALUE, long));\nstatic VALUE\nstruct_entry(s, n)\n    VALUE s;\n    long n;\n{\n    return rb_struct_aref(s, LONG2NUM(n));\n}\n\n/* \n * call-seq:\n *   struct.values_at(selector,... )  => an_array\n *\n *   Returns an array containing the elements in\n *   _self_ corresponding to the given selector(s). The selectors\n *   may be either integer indices or ranges. \n *   See also </code>.select<code>.\n * \n *      a = %w{ a b c d e f }\n *      a.values_at(1, 3, 5)\n *      a.values_at(1, 3, 5, 7)\n *      a.values_at(-1, -3, -5, -7)\n *      a.values_at(1..3, 2...5)\n */\n\nstatic VALUE\nrb_struct_values_at(argc, argv, s)\n    int argc;\n    VALUE *argv;\n    VALUE s;\n{\n    return rb_values_at(s, RSTRUCT(s)->len, argc, argv, struct_entry);\n}\n\n/*\n *  call-seq:\n *     struct.select {|i| block }    => array\n *  \n *  Invokes the block passing in successive elements from\n *  <i>struct</i>, returning an array containing those elements\n *  for which the block returns a true value (equivalent to\n *  <code>Enumerable#select</code>).\n *     \n *     Lots = Struct.new(:a, :b, :c, :d, :e, :f)\n *     l = Lots.new(11, 22, 33, 44, 55, 66)\n *     l.select {|v| (v % 2).zero? }   #=> [22, 44, 66]\n */\n\nstatic VALUE\nrb_struct_select(argc, argv, s)\n    int argc;\n    VALUE *argv;\n    VALUE s;\n{\n    VALUE result;\n    long i;\n\n    if (argc > 0) {\n\trb_raise(rb_eArgError, \"wrong number of arguments (%d for 0)\", argc);\n    }\n    result = rb_ary_new();\n    for (i = 0; i < RSTRUCT(s)->len; i++) {\n\tif (RTEST(rb_yield(RSTRUCT(s)->ptr[i]))) {\n\t    rb_ary_push(result, RSTRUCT(s)->ptr[i]);\n\t}\n    }\n\n    return result;\n}\n\n/*\n *  call-seq:\n *     struct == other_struct     => true or false\n *  \n *  Equality---Returns <code>true</code> if <i>other_struct</i> is\n *  equal to this one: they must be of the same class as generated by\n *  <code>Struct::new</code>, and the values of all instance variables\n *  must be equal (according to <code>Object#==</code>).\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe   = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     joejr = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     jane  = Customer.new(\"Jane Doe\", \"456 Elm, Anytown NC\", 12345)\n *     joe == joejr   #=> true\n *     joe == jane    #=> false\n */\n\nstatic VALUE\nrb_struct_equal(s, s2)\n    VALUE s, s2;\n{\n    long i;\n\n    if (s == s2) return Qtrue;\n    if (TYPE(s2) != T_STRUCT) return Qfalse;\n    if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;\n    if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {\n\trb_bug(\"inconsistent struct\"); /* should never happen */\n    }\n\n    for (i=0; i<RSTRUCT(s)->len; i++) {\n\tif (!rb_equal(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;\n    }\n    return Qtrue;\n}\n\n/*\n * call-seq:\n *   struct.hash   => fixnum\n *\n * Return a hash value based on this struct's contents.\n */\n\nstatic VALUE\nrb_struct_hash(s)\n    VALUE s;\n{\n    long i, h;\n    VALUE n;\n\n    h = rb_hash(rb_obj_class(s));\n    for (i = 0; i < RSTRUCT(s)->len; i++) {\n\th = (h << 1) | (h<0 ? 1 : 0);\n\tn = rb_hash(RSTRUCT(s)->ptr[i]);\n\th ^= NUM2LONG(n);\n    }\n    return LONG2FIX(h);\n}\n\n/*\n * code-seq:\n *   struct.eql?(other)   => true or false\n *\n * Two structures are equal if they are the same object, or if all their\n * fields are equal (using <code>eql?</code>).\n */\n\nstatic VALUE\nrb_struct_eql(s, s2)\n    VALUE s, s2;\n{\n    long i;\n\n    if (s == s2) return Qtrue;\n    if (TYPE(s2) != T_STRUCT) return Qfalse;\n    if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;\n    if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {\n\trb_bug(\"inconsistent struct\"); /* should never happen */\n    }\n\n    for (i=0; i<RSTRUCT(s)->len; i++) {\n\tif (!rb_eql(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;\n    }\n    return Qtrue;\n}\n\n/*\n *  call-seq:\n *     struct.length    => fixnum\n *     struct.size      => fixnum\n *  \n *  Returns the number of instance variables.\n *     \n *     Customer = Struct.new(:name, :address, :zip)\n *     joe = Customer.new(\"Joe Smith\", \"123 Maple, Anytown NC\", 12345)\n *     joe.length   #=> 3\n */\n\nstatic VALUE\nrb_struct_size(s)\n    VALUE s;\n{\n    return LONG2FIX(RSTRUCT(s)->len);\n}\n\n/*\n *  A <code>Struct</code> is a convenient way to bundle a number of\n *  attributes together, using accessor methods, without having to write\n *  an explicit class.\n *     \n *  The <code>Struct</code> class is a generator of specific classes,\n *  each one of which is defined to hold a set of variables and their\n *  accessors. In these examples, we'll call the generated class\n *  ``<i>Customer</i>Class,'' and we'll show an example instance of that\n *  class as ``<i>Customer</i>Inst.''\n *     \n *  In the descriptions that follow, the parameter <i>symbol</i> refers\n *  to a symbol, which is either a quoted string or a\n *  <code>Symbol</code> (such as <code>:name</code>).\n */\nvoid\nInit_Struct()\n{\n    rb_cStruct = rb_define_class(\"Struct\", rb_cObject);\n    rb_include_module(rb_cStruct, rb_mEnumerable);\n\n    rb_undef_alloc_func(rb_cStruct);\n    rb_define_singleton_method(rb_cStruct, \"new\", rb_struct_s_def, -1);\n\n    rb_define_method(rb_cStruct, \"initialize\", rb_struct_initialize, -2);\n    rb_define_method(rb_cStruct, \"initialize_copy\", rb_struct_init_copy, 1);\n\n    rb_define_method(rb_cStruct, \"==\", rb_struct_equal, 1);\n    rb_define_method(rb_cStruct, \"eql?\", rb_struct_eql, 1);\n    rb_define_method(rb_cStruct, \"hash\", rb_struct_hash, 0);\n\n    rb_define_method(rb_cStruct, \"to_s\", rb_struct_inspect, 0);\n    rb_define_method(rb_cStruct, \"inspect\", rb_struct_inspect, 0);\n    rb_define_method(rb_cStruct, \"to_a\", rb_struct_to_a, 0);\n    rb_define_method(rb_cStruct, \"values\", rb_struct_to_a, 0);\n    rb_define_method(rb_cStruct, \"size\", rb_struct_size, 0);\n    rb_define_method(rb_cStruct, \"length\", rb_struct_size, 0);\n\n    rb_define_method(rb_cStruct, \"each\", rb_struct_each, 0);\n    rb_define_method(rb_cStruct, \"each_pair\", rb_struct_each_pair, 0);\n    rb_define_method(rb_cStruct, \"[]\", rb_struct_aref, 1);\n    rb_define_method(rb_cStruct, \"[]=\", rb_struct_aset, 2);\n    rb_define_method(rb_cStruct, \"select\", rb_struct_select, -1);\n    rb_define_method(rb_cStruct, \"values_at\", rb_struct_values_at, -1);\n\n    rb_define_method(rb_cStruct, \"members\", rb_struct_members_m, 0);\n}\n"
  },
  {
    "path": "system_allocator.c",
    "content": "/*\n * The problem\n * -----------\n * On platforms that use a two-level symbol namespace for dynamic libraries\n * (most notably MacOS X), integrating tcmalloc requires special modifications.\n *\n * Most Unix platforms use a flat namespace for symbol lookup, which is why\n * linking to tcmalloc causes it override malloc() and free() for the entire\n * process. This is not the case on OS X: if Ruby calls a function from library\n * that's not compiled with -flat_namespace, then that library will use the\n * system's memory allocator instead of tcmalloc.\n *\n * The Ruby readline extension is a good example of how things can go wrong.\n * The readline extension calls the readline() function in the readline library.\n * This library is not compiled with -flat_namespace; readline() returns a string\n * that's allocated by the system memory allocator. The Ruby readline extension\n * then frees this string by passing it to tcmalloc's free() function. This\n * results in a crash.\n * Note that setting DYLD_FORCE_FLAT_NAMESPACE on OS X does not work: the\n * resulting Ruby interpreter will crash immediately.\n *\n *\n * The solution\n * ------------\n * This can be fixed by making it possible for Ruby extensions to call the\n * system's memory allocator functions, instead of tcmalloc's, if it knows\n * that a piece of memory is allocated by the system's memory allocator.\n *\n * This library, libsystem_allocator provides wrapper functions for the system\n * memory allocator. libsystem_allocator will be compiled without -flat_namespace\n * on OS X, and so it will always use the system's memory allocator instead of\n * tcmalloc.\n *\n * libsystem_allocator will not be compiled on systems that only support flat\n * namespaces (e.g. Linux). On those platforms, system_malloc() and\n * system_free() have no special effect.\n */\n#include <stdlib.h>\n\nvoid *\nsystem_malloc(long size)\n{\n    return malloc(size);\n}\n\nvoid\nsystem_free(void *ptr)\n{\n    free(ptr);\n}\n"
  },
  {
    "path": "test/callerforallthreads/test_caller_for_each_thread.rb",
    "content": "# -*- ruby-indent-level: 4 -*-\nrequire 'thread'\nrequire 'test/unit'\n\nclass AClassWithNestedmethods\n  \n  def an_ultra_nested_method(skip)\n    caller_for_all_threads skip\n  end\n\n  def a_nested_method(skip)\n    an_ultra_nested_method skip\n  end\n\n  def a_method(skip=0)\n    a_nested_method skip\n  end\n  \nend\n\nclass CallerForEachThreadTest < Test::Unit::TestCase\n  \n  def testCollectMeaningfulBacktraceForASingleThread\n    backtraces = AClassWithNestedmethods.new.a_method\n    backtrace = backtraces[Thread.current]\n    assert_not_nil backtrace\n    assert_equal __FILE__ + \":8:in `an_ultra_nested_method'\", backtrace[0]\n    assert_equal __FILE__ + \":12:in `a_nested_method'\", backtrace[1]\n    assert_equal __FILE__ + \":16:in `a_method'\", backtrace[2]\n    assert_equal __FILE__ + \":24:in `testCollectMeaningfulBacktraceForASingleThread'\", \n                 backtrace[3]\n  end\n\n  def testCanSkipFirstStackEntries\n    backtraces = AClassWithNestedmethods.new.a_method 2\n    backtrace = backtraces[Thread.current]\n    assert_not_nil backtrace\n    assert_equal __FILE__ + \":16:in `a_method'\", backtrace[0]\n    assert_equal __FILE__ + \":35:in `testCanSkipFirstStackEntries'\", \n                 backtrace[1]\n  end\n\n  def testCollectMeaningfulBacktraceForMultipleThreads\n    first_thread = Thread.new do\n      loop do\n        Thread.pass\n        sleep 1\n      end\n    end\n\n    second_thread = Thread.new do\n      loop do\n        Thread.pass\n        sleep 1\n      end\n    end\n\n    backtraces = AClassWithNestedmethods.new.a_method\n    \n    backtrace = backtraces[Thread.current]\n    assert_not_nil backtrace\n    assert_match __FILE__ + \":8:in `an_ultra_nested_method'\", backtrace[0]\n    assert_match __FILE__ + \":12:in `a_nested_method'\", backtrace[1]\n    assert_equal __FILE__ + \":16:in `a_method'\", backtrace[2]\n    assert_equal __FILE__ + \":58:in `testCollectMeaningfulBacktraceForMultipleThreads'\", \n                 backtrace[3]\n                 \n    backtrace = backtraces[first_thread]\n    assert_not_nil backtrace\n    assert_equal __FILE__ + \":47:in `testCollectMeaningfulBacktraceForMultipleThreads'\", \n                 backtrace[0]\n    assert_equal __FILE__ + \":45:in `loop'\", \n                 backtrace[1]\n    assert_equal __FILE__ + \":45:in `testCollectMeaningfulBacktraceForMultipleThreads'\",\n                 backtrace[2]\n    assert_equal __FILE__ + \":44:in `initialize'\",backtrace[3]\n    assert_equal __FILE__ + \":44:in `new'\", backtrace[4]\n    assert_equal __FILE__ + \":44:in `testCollectMeaningfulBacktraceForMultipleThreads'\",\n                 backtrace[5]\n\n    backtrace = backtraces[second_thread]\n    assert_not_nil backtrace\n    assert_equal __FILE__ + \":53:in `testCollectMeaningfulBacktraceForMultipleThreads'\", \n                 backtrace[0]\n    assert_equal __FILE__ + \":52:in `loop'\", backtrace[1]\n    assert_equal __FILE__ + \":52:in `testCollectMeaningfulBacktraceForMultipleThreads'\",\n                 backtrace[2]\n    assert_equal __FILE__ + \":51:in `initialize'\",backtrace[3]\n    assert_equal __FILE__ + \":51:in `new'\", backtrace[4]\n    assert_equal __FILE__ + \":51:in `testCollectMeaningfulBacktraceForMultipleThreads'\",\n                 backtrace[5]\n  end\n  \nend\n\n"
  },
  {
    "path": "test/csv/test_csv.rb",
    "content": "require 'test/unit'\nrequire 'tempfile'\nrequire 'fileutils'\n\nrequire 'csv'\n\nclass CSV\n  class StreamBuf\n    # Let buffer work hard.\n    remove_const(\"BufSize\")\n    BufSize = 2\n  end\nend\n\n\nmodule CSVTestSupport\n  def d(data)\n    data\n  end\nend\n\n\nclass TestCSV < Test::Unit::TestCase\n  file = Tempfile.new(\"crlf\")\n  file << \"\\n\"\n  file.open\n  file.binmode\n  RSEP = file.read\n  file.close\n\n  include CSVTestSupport\n\n  class << self\n    include CSVTestSupport\n  end\n\n  @@simpleCSVData = {\n    [nil] => '',\n    [''] => '\"\"',\n    [nil, nil] => ',',\n    [nil, nil, nil] => ',,',\n    ['foo'] => 'foo',\n    [','] => '\",\"',\n    [',', ','] => '\",\",\",\"',\n    [';'] => ';',\n    [';', ';'] => ';,;',\n    [\"\\\"\\r\", \"\\\"\\r\"] => \"\\\"\\\"\\\"\\r\\\",\\\"\\\"\\\"\\r\\\"\",\n    [\"\\\"\\n\", \"\\\"\\n\"] => \"\\\"\\\"\\\"\\n\\\",\\\"\\\"\\\"\\n\\\"\",\n    [\"\\t\"] => \"\\t\",\n    [\"\\t\", \"\\t\"] => \"\\t,\\t\",\n    ['foo', 'bar'] => 'foo,bar',\n    ['foo', '\"bar\"', 'baz'] => 'foo,\"\"\"bar\"\"\",baz',\n    ['foo', 'foo,bar', 'baz'] => 'foo,\"foo,bar\",baz',\n    ['foo', '\"\"', 'baz'] => 'foo,\"\"\"\"\"\",baz',\n    ['foo', '', 'baz'] => 'foo,\"\",baz',\n    ['foo', nil, 'baz'] => 'foo,,baz',\n    [nil, 'foo', 'bar'] => ',foo,bar',\n    ['foo', 'bar', nil] => 'foo,bar,',\n    ['foo', \"\\r\", 'baz'] => \"foo,\\\"\\r\\\",baz\",\n    ['foo', \"\\n\", 'baz'] => \"foo,\\\"\\n\\\",baz\",\n    ['foo', \"\\r\\n\\r\", 'baz'] => \"foo,\\\"\\r\\n\\r\\\",baz\",\n    ['foo', \"\\r\\n\", 'baz'] => \"foo,\\\"\\r\\n\\\",baz\",\n    ['foo', \"\\r.\\n\", 'baz'] => \"foo,\\\"\\r.\\n\\\",baz\",\n    ['foo', \"\\r\\n\\n\", 'baz'] => \"foo,\\\"\\r\\n\\n\\\",baz\",\n    ['foo', '\"', 'baz'] => 'foo,\"\"\"\",baz',\n  }\n\n  @@fullCSVData = {\n    [d(nil)] => '',\n    [d('')] => '\"\"',\n    [d(nil), d(nil)] => ',',\n    [d(nil), d(nil), d(nil)] => ',,',\n    [d('foo')] => 'foo',\n    [d('foo'), d('bar')] => 'foo,bar',\n    [d('foo'), d('\"bar\"'), d('baz')] => 'foo,\"\"\"bar\"\"\",baz',\n    [d('foo'), d('foo,bar'), d('baz')] => 'foo,\"foo,bar\",baz',\n    [d('foo'), d('\"\"'), d('baz')] => 'foo,\"\"\"\"\"\",baz',\n    [d('foo'), d(''), d('baz')] => 'foo,\"\",baz',\n    [d('foo'), d(nil), d('baz')] => 'foo,,baz',\n    [d('foo'), d(\"\\r\"), d('baz')] => \"foo,\\\"\\r\\\",baz\",\n    [d('foo'), d(\"\\n\"), d('baz')] => \"foo,\\\"\\n\\\",baz\",\n    [d('foo'), d(\"\\r\\n\"), d('baz')] => \"foo,\\\"\\r\\n\\\",baz\",\n    [d('foo'), d(\"\\r.\\n\"), d('baz')] => \"foo,\\\"\\r.\\n\\\",baz\",\n    [d('foo'), d(\"\\r\\n\\n\"), d('baz')] => \"foo,\\\"\\r\\n\\n\\\",baz\",\n    [d('foo'), d('\"'), d('baz')] => 'foo,\"\"\"\",baz',\n  }\n\n  @@fullCSVDataArray = @@fullCSVData.collect { |key, value| key }\n\n  def ssv2csv(ssvStr, row_sep = nil)\n    sepConv(ssvStr, ?;, ?,, row_sep)\n  end\n\n  def csv2ssv(csvStr, row_sep = nil)\n    sepConv(csvStr, ?,, ?;, row_sep)\n  end\n\n  def tsv2csv(tsvStr, row_sep = nil)\n    sepConv(tsvStr, ?\\t, ?,, row_sep)\n  end\n\n  def csv2tsv(csvStr, row_sep = nil)\n    sepConv(csvStr, ?,, ?\\t, row_sep)\n  end\n\n  def sepConv(srcStr, srcSep, destSep, row_sep = nil)\n    rows = []\n    cols, idx = CSV.parse_row(srcStr, 0, rows, srcSep, row_sep)\n    destStr = ''\n    cols = CSV.generate_row(rows, rows.size, destStr, destSep, row_sep)\n    destStr\n  end\n\npublic\n\n  def setup\n    @tmpdir = File.join(Dir.tmpdir, \"ruby_test_csv_tmp_#{$$}\")\n    Dir.mkdir(@tmpdir)\n    @infile = File.join(@tmpdir, 'in.csv')\n    @infiletsv = File.join(@tmpdir, 'in.tsv')\n    @emptyfile = File.join(@tmpdir, 'empty.csv')\n    @outfile = File.join(@tmpdir, 'out.csv')\n    @bomfile = File.join(@tmpdir, \"bom.csv\")\n    @macfile = File.join(@tmpdir, \"mac.csv\")\n\n    CSV.open(@infile, \"wb\") do |writer|\n      @@fullCSVDataArray.each do |row|\n\twriter.add_row(row)\n      end\n    end\n\n    CSV.open(@infiletsv, \"wb\", ?\\t) do |writer|\n      @@fullCSVDataArray.each do |row|\n\twriter.add_row(row)\n      end\n    end\n\n    CSV.generate(@emptyfile) do |writer|\n      # Create empty file.\n    end\n\n    File.open(@bomfile, \"wb\") do |f|\n      f.write(\"\\357\\273\\277\\\"foo\\\"\\r\\n\\\"bar\\\"\\r\\n\")\n    end\n\n    File.open(@macfile, \"wb\") do |f|\n      f.write(\"\\\"Avenches\\\",\\\"aus Umgebung\\\"\\r\\\"Bad Hersfeld\\\",\\\"Ausgrabung\\\"\")\n    end\n  end\n\n  def teardown\n    FileUtils.rm_rf(@tmpdir)\n  end\n\n  #### CSV::Reader unit test\n  \n  def test_Reader_each\n    file = File.open(@infile, \"rb\")\n    begin\n      reader = CSV::Reader.create(file)\n      expectedArray = @@fullCSVDataArray.dup\n      first = true\n      ret = reader.each { |row|\n\tif first\n\t  assert_instance_of(Array, row)\n\t  first = false\n\tend\n\texpected = expectedArray.shift\n\tassert_equal(expected, row)\n      }\n      assert_nil(ret, \"Return is nil\")\n      assert(expectedArray.empty?)\n    ensure\n      file.close\n    end\n\n    # Illegal format.\n    reader = CSV::Reader.create(\"a,b\\r\\na,b,\\\"c\\\"\\ra\")\n    assert_raises(CSV::IllegalFormatError) do\n      reader.each do |row|\n      end\n    end\n\n    reader = CSV::Reader.create(\"a,b\\r\\n\\\"\")\n    assert_raises(CSV::IllegalFormatError) do\n      reader.each do |row|\n      end\n    end\n  end\n\n  def test_Reader_shift\n    file = File.open(@infile, \"rb\")\n    begin\n      reader = CSV::Reader.create(file)\n      first = true\n      checked = 0\n      @@fullCSVDataArray.each do |expected|\n\tactual = reader.shift\n\tif first\n\t  assert_instance_of(Array, actual)\n\t  first = false\n\tend\n\tassert_equal(expected, actual)\n\tchecked += 1\n      end\n      assert(checked == @@fullCSVDataArray.size)\n    ensure\n      file.close\n    end\n\n    # Illegal format.\n    reader = CSV::Reader.create(\"a,b\\r\\na,b,\\\"c\\\"\\ra\")\n    assert_raises(CSV::IllegalFormatError) do\n      reader.shift\n      reader.shift\n    end\n\n    reader = CSV::Reader.create(\"a,b\\r\\na,b,\\\"c\\\"\\ra\")\n    assert_raises(CSV::IllegalFormatError) do\n      reader.shift\n      reader.shift\n    end\n  end\n\n  def test_Reader_getRow\n    if CSV::Reader.respond_to?(:allocate)\n      obj = CSV::Reader.allocate\n      assert_raises(NotImplementedError) do\n\trow = []\n\tobj.shift\n      end\n    end\n  end\n\n  def test_IOReader_close_on_terminate\n    f = File.open(@infile, \"r\")\n    reader = CSV::IOReader.create(f)\n    reader.close\n    assert(!f.closed?)\n    f.close\n\n    f = File.open(@infile, \"r\")\n    writer = CSV::IOReader.create(f)\n    writer.close_on_terminate\n    writer.close\n    assert(f.closed?)\n  end\n\n  def test_Reader_close\n    f = File.open(@infile, \"r\")\n    reader = CSV::IOReader.create(f)\n    reader.close_on_terminate\n    reader.close\n    assert(f.closed?)\n  end\n\n  def test_Reader_s_new\n    assert_raises(RuntimeError) do\n      CSV::Reader.new(nil)\n    end\n  end\n\n  def test_Reader_s_create\n    reader = CSV::Reader.create(\"abc\")\n    assert_instance_of(CSV::StringReader, reader, \"With a String\")\n\n    file = File.open(@infile, \"rb\")\n    reader = CSV::Reader.create(file)\n    assert_instance_of(CSV::IOReader, reader, 'With an IO')\n\n    obj = Object.new\n    def obj.sysread(size)\n      \"abc\"\n    end\n    def obj.read(size)\n      \"abc\"\n    end\n    reader = CSV::Reader.create(obj)\n    assert_instance_of(CSV::IOReader, reader, \"With not an IO or String\")\n\n    # No need to test Tempfile because it's a pseudo IO.  I test this here\n    # fors other tests.\n    reader = CSV::Reader.create(Tempfile.new(\"in.csv\"))\n    assert_instance_of(CSV::IOReader, reader, \"With an pseudo IO.\")\n    file.close\n  end\n\n  def test_IOReader_s_create_binmode\n    file = File.open(@outfile, \"wb\")\n    file << \"\\\"\\r\\n\\\",\\\"\\r\\\",\\\"\\n\\\"\\r1,2,3\"\n    file.close\n\n    file = File.open(@outfile, \"rb\")\n    begin\n      reader = CSV::IOReader.new(file, ?,, ?\\r)\n      assert_equal([\"\\r\\n\", \"\\r\", \"\\n\"], reader.shift.to_a)\n      assert_equal([\"1\", \"2\", \"3\"], reader.shift.to_a)\n      reader.close\n    ensure\n      file.close\n    end\n\n    file = File.open(@outfile, \"r\")\t# not \"rb\"\n    begin\n      lfincell = (RSEP == \"\\n\" ? \"\\r\\n\" : \"\\n\")\n      reader = CSV::IOReader.new(file, ?,, ?\\r)\n      assert_equal([lfincell, \"\\r\", \"\\n\"], reader.shift.to_a)\n      assert_equal([\"1\", \"2\", \"3\"], reader.shift.to_a)\n      reader.close\n    ensure\n      file.close\n    end\n  end\n\n  def test_Reader_s_parse\n    ret = CSV::Reader.parse(\"a,b,c\") { |row|\n      assert_instance_of(Array, row, \"Block parameter\")\n    }\n    assert_nil(ret, \"Return is nil\")\n\n    ret = CSV::Reader.parse(\"a;b;c\", ?;) { |row|\n      assert_instance_of(Array, row, \"Block parameter\")\n    }\n\n    file = Tempfile.new(\"in.csv\")\n    file << \"a,b,c\"\n    file.open\n    ret = CSV::Reader.parse(file) { |row|\n      assert_instance_of(Array, row, \"Block parameter\")\n    }\n    assert_nil(ret, \"Return is nil\")\n\n    file = Tempfile.new(\"in.csv\")\n    file << \"a,b,c\"\n    file.open\n    ret = CSV::Reader.parse(file, ?,) { |row|\n      assert_instance_of(Array, row, \"Block parameter\")\n    }\n\n    # Illegal format.\n    assert_raises(CSV::IllegalFormatError) do\n      CSV::Reader.parse(\"a,b\\r\\na,b,\\\"c\\\"\\ra\") do |row|\n      end\n    end\n\n    assert_raises(CSV::IllegalFormatError) do\n      CSV::Reader.parse(\"a,b\\r\\na,b\\\"\") do |row|\n      end\n    end\n  end\n\n\n  #### CSV::Writer unit test\n  \n  def test_Writer_s_new\n    assert_raises(RuntimeError) do\n      CSV::Writer.new(nil)\n    end\n  end\n\n  def test_Writer_s_generate\n    ret = CSV::Writer.generate(STDOUT) { |writer|\n      assert_instance_of(CSV::BasicWriter, writer, \"Block parameter\")\n    }\n\n    ret = CSV::Writer.generate(STDOUT, ?;) { |writer|\n      assert_instance_of(CSV::BasicWriter, writer, \"Block parameter\")\n    }\n\n    assert_nil(ret, \"Return is nil\")\n  end\n\n  def test_Writer_s_create\n    writer = CSV::Writer.create(STDERR)\n    assert_instance_of(CSV::BasicWriter, writer, \"String\")\n\n    writer = CSV::Writer.create(STDERR, ?;)\n    assert_instance_of(CSV::BasicWriter, writer, \"String\")\n\n    writer = CSV::Writer.create(Tempfile.new(\"out.csv\"))\n    assert_instance_of(CSV::BasicWriter, writer, \"IO\")\n  end\n\n  def test_Writer_LSHIFT # '<<'\n    file = Tempfile.new(\"out.csv\")\n    CSV::Writer.generate(file) do |writer|\n      ret = writer << ['a', 'b', 'c']\n      assert_instance_of(CSV::BasicWriter, ret, 'Return is self')\n\n      writer << [nil, 'e', 'f'] << [nil, nil, '']\n    end\n    file.open\n    file.binmode\n    str = file.read\n    assert_equal(\"a,b,c#{RSEP},e,f#{RSEP},,\\\"\\\"#{RSEP}\", str, 'Normal')\n\n    file = Tempfile.new(\"out2.csv\")\n    CSV::Writer.generate(file) do |writer|\n      ret = writer << [d('a'), d('b'), d('c')]\n      assert_instance_of(CSV::BasicWriter, ret, 'Return is self')\n\n      writer << [d(nil), d('e'), d('f')] << [d(nil), d(nil), d('')]\n    end\n    file.open\n    file.binmode\n    str = file.read\n    assert_equal(\"a,b,c#{RSEP},e,f#{RSEP},,\\\"\\\"#{RSEP}\", str, 'Normal')\n  end\n\n  def test_Writer_add_row\n    file = Tempfile.new(\"out.csv\")\n    CSV::Writer.generate(file) do |writer|\n      ret = writer.add_row(\n\t[d('a'), d('b'), d('c')])\n      assert_instance_of(CSV::BasicWriter, ret, 'Return is self')\n\n      writer.add_row(\n\t[d(nil), d('e'), d('f')]\n     ).add_row(\n\t[d(nil), d(nil), d('')]\n     )\n    end\n    file.open\n    file.binmode\n    str = file.read\n    assert_equal(\"a,b,c#{RSEP},e,f#{RSEP},,\\\"\\\"#{RSEP}\", str, 'Normal')\n  end\n\n  def test_Writer_close\n    f = File.open(@outfile, \"w\")\n    writer = CSV::BasicWriter.create(f)\n    writer.close_on_terminate\n    writer.close\n    assert(f.closed?)\n  end\n\n  def test_BasicWriter_close_on_terminate\n    f = File.open(@outfile, \"w\")\n    writer = CSV::BasicWriter.create(f)\n    writer.close\n    assert(!f.closed?)\n    f.close\n\n    f = File.open(@outfile, \"w\")\n    writer = CSV::BasicWriter.new(f)\n    writer.close_on_terminate\n    writer.close\n    assert(f.closed?)\n  end\n\n  def test_BasicWriter_s_create_binmode\n    file = File.open(@outfile, \"w\")\t# not \"wb\"\n    begin\n      writer = CSV::BasicWriter.new(file, ?,, ?\\r)\n      writer << [\"\\r\\n\", \"\\r\", \"\\n\"]\n      writer << [\"1\", \"2\", \"3\"]\n      writer.close\n    ensure\n      file.close\n    end\n\n    file = File.open(@outfile, \"rb\")\n    str = file.read\n    file.close\n    assert_equal(\"\\\"\\r#{RSEP}\\\",\\\"\\r\\\",\\\"#{RSEP}\\\"\\r1,2,3\\r\", str)\n  end\n\n  #### CSV unit test\n\n  def test_s_open_reader\n    assert_raises(ArgumentError, 'Illegal mode') do\n      CSV.open(\"temp\", \"a\")\n    end\n\n    assert_raises(ArgumentError, 'Illegal mode') do\n      CSV.open(\"temp\", \"a\", ?;)\n    end\n\n    reader = CSV.open(@infile, \"r\")\n    assert_instance_of(CSV::IOReader, reader)\n    reader.close\n\n    reader = CSV.open(@infile, \"rb\")\n    assert_instance_of(CSV::IOReader, reader)\n    reader.close\n\n    reader = CSV.open(@infile, \"r\", ?;)\n    assert_instance_of(CSV::IOReader, reader)\n    reader.close\n\n    CSV.open(@infile, \"r\") do |row|\n      assert_instance_of(Array, row)\n      break\n    end\n\n    CSV.open(@infiletsv, \"r\", ?\\t) do |row|\n      assert_instance_of(Array, row)\n      break\n    end\n\n    assert_raises(Errno::ENOENT) do\n      CSV.open(\"NoSuchFileOrDirectory\", \"r\")\n    end\n\n    assert_raises(Errno::ENOENT) do\n      CSV.open(\"NoSuchFileOrDirectory\", \"r\", ?;)\n    end\n\n    # Illegal format.\n    File.open(@outfile, \"wb\") do |f|\n      f << \"a,b\\r\\na,b,\\\"c\\\"\\ra\"\n    end\n    assert_raises(CSV::IllegalFormatError) do\n      CSV.open(@outfile, \"r\") do |row|\n      end\n    end\n\n    File.open(@outfile, \"wb\") do |f|\n      f << \"a,b\\r\\na,b\\\"\"\n    end\n    assert_raises(CSV::IllegalFormatError) do\n      CSV.open(@outfile, \"r\") do |row|\n      end\n    end\n\n    CSV.open(@emptyfile, \"r\") do |row|\n      assert_fail(\"Must not reach here\")\n    end\n  end\n\n  def test_s_parse\n    result = CSV.parse(File.read(@infile))\n    assert_instance_of(Array, result)\n    assert_instance_of(Array, result[0])\n\n    result = CSV.parse(File.read(@infile))\n    assert_instance_of(Array, result)\n    assert_instance_of(Array, result[0])\n\n    assert_equal([], CSV.parse(\"\"))\n    assert_equal([[nil]], CSV.parse(\"\\n\"))\n\n    CSV.parse(File.read(@infile)) do |row|\n      assert_instance_of(Array, row)\n      break\n    end\n\n    CSV.parse(File.read(@infiletsv), ?\\t) do |row|\n      assert_instance_of(Array, row)\n      break\n    end\n\n    CSV.parse(\"\") do |row|\n      assert(false)\n    end\n\n    count = 0\n    CSV.parse(\"\\n\") do |row|\n      assert_equal([nil], row)\n      count += 1\n    end\n    assert_equal(1, count)\n\n    assert_equal([[\"a|b-c|d\"]], CSV.parse(\"a|b-c|d\"))\n    assert_equal([[\"a\", \"b\"], [\"c\", \"d\"]], CSV.parse(\"a|b-c|d\", \"|\", \"-\"))\n  end\n\n  def test_s_open_writer\n    writer = CSV.open(@outfile, \"w\")\n    assert_instance_of(CSV::BasicWriter, writer)\n    writer.close\n\n    writer = CSV.open(@outfile, \"wb\")\n    assert_instance_of(CSV::BasicWriter, writer)\n    writer.close\n\n    writer = CSV.open(@outfile, \"wb\", ?;)\n    assert_instance_of(CSV::BasicWriter, writer)\n    writer.close\n\n    CSV.open(@outfile, \"w\") do |writer|\n      assert_instance_of(CSV::BasicWriter, writer)\n    end\n\n    CSV.open(@outfile, \"w\", ?;) do |writer|\n      assert_instance_of(CSV::BasicWriter, writer)\n    end\n\n    begin\n      CSV.open(@tmpdir, \"w\")\n      assert(false)\n    rescue Exception => ex\n      assert(ex.is_a?(Errno::EEXIST) || ex.is_a?(Errno::EISDIR) || ex.is_a?(Errno::EACCES))\n    end\n  end\n\n  def test_s_generate\n    writer = CSV.generate(@outfile)\n    assert_instance_of(CSV::BasicWriter, writer)\n    writer.close\n\n    writer = CSV.generate(@outfile, ?;)\n    assert_instance_of(CSV::BasicWriter, writer)\n    writer.close\n\n    CSV.generate(@outfile) do |writer|\n      assert_instance_of(CSV::BasicWriter, writer)\n    end\n\n    CSV.generate(@outfile, ?;) do |writer|\n      assert_instance_of(CSV::BasicWriter, writer)\n    end\n\n    begin\n      CSV.generate(@tmpdir)\n      assert(false)\n    rescue Exception => ex\n      assert(ex.is_a?(Errno::EEXIST) || ex.is_a?(Errno::EISDIR) || ex.is_a?(Errno::EACCES))\n    end\n  end\n\n  def test_s_generate_line\n    str = CSV.generate_line([])\n    assert_equal('', str, \"Extra boundary check.\")\n\n    str = CSV.generate_line([], ?;)\n    assert_equal('', str, \"Extra boundary check.\")\n\n    @@simpleCSVData.each do |col, str|\n      buf = CSV.generate_line(col)\n      assert_equal(str, buf)\n    end\n\n    @@simpleCSVData.each do |col, str|\n      buf = CSV.generate_line(col, ?;)\n      assert_equal(str + \"\\n\", ssv2csv(buf))\n    end\n\n    @@simpleCSVData.each do |col, str|\n      buf = CSV.generate_line(col, ?\\t)\n      assert_equal(str + \"\\n\", tsv2csv(buf))\n    end\n\n    str = CSV.generate_line(['a', 'b'], nil, ?|)\n    assert_equal('a,b', str)\n\n    str = CSV.generate_line(['a', 'b'], nil, \"a\")\n    assert_equal('\"a\",b', str)\n  end\n\n  def test_s_generate_row\n    buf = ''\n    cols = CSV.generate_row([], 0, buf)\n    assert_equal(0, cols)\n    assert_equal(\"\\n\", buf, \"Extra boundary check.\")\n\n    buf = ''\n    cols = CSV.generate_row([], 0, buf, ?;)\n    assert_equal(0, cols)\n    assert_equal(\"\\n\", buf, \"Extra boundary check.\")\n\n    buf = ''\n    cols = CSV.generate_row([], 0, buf, ?\\t)\n    assert_equal(0, cols)\n    assert_equal(\"\\n\", buf, \"Extra boundary check.\")\n\n    buf = ''\n    cols = CSV.generate_row([], 0, buf, ?\\t, ?|)\n    assert_equal(0, cols)\n    assert_equal(\"|\", buf, \"Extra boundary check.\")\n\n    buf = ''\n    cols = CSV.generate_row([d('1')], 2, buf)\n    assert_equal('1,', buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1')], 2, buf, ?;)\n    assert_equal('1;', buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1')], 2, buf, ?\\t)\n    assert_equal(\"1\\t\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1')], 2, buf, ?\\t, ?|)\n    assert_equal(\"1\\t\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1'), d('2')], 1, buf)\n    assert_equal(\"1\\n\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?;)\n    assert_equal(\"1\\n\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\\t)\n    assert_equal(\"1\\n\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\\t, ?\\n)\n    assert_equal(\"1\\n\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\\t, ?\\r)\n    assert_equal(\"1\\r\", buf)\n\n    buf = ''\n    cols = CSV.generate_row([d('1'), d('2')], 1, buf, ?\\t, ?|)\n    assert_equal(\"1|\", buf)\n\n    @@fullCSVData.each do |col, str|\n      buf = ''\n      cols = CSV.generate_row(col, col.size, buf)\n      assert_equal(col.size, cols)\n      assert_equal(str + \"\\n\", buf)\n    end\n\n    @@fullCSVData.each do |col, str|\n      buf = ''\n      cols = CSV.generate_row(col, col.size, buf, ?;)\n      assert_equal(col.size, cols)\n      assert_equal(str + \"\\n\", ssv2csv(buf))\n    end\n\n    @@fullCSVData.each do |col, str|\n      buf = ''\n      cols = CSV.generate_row(col, col.size, buf, ?\\t)\n      assert_equal(col.size, cols)\n      assert_equal(str + \"\\n\", tsv2csv(buf))\n    end\n\n    # row separator\n    @@fullCSVData.each do |col, str|\n      buf = ''\n      cols = CSV.generate_row(col, col.size, buf, ?,, ?|)\n      assert_equal(col.size, cols)\n      assert_equal(str + \"|\", buf)\n    end\n\n    # col and row separator\n    @@fullCSVData.each do |col, str|\n      buf = ''\n      cols = CSV.generate_row(col, col.size, buf, ?\\t, ?|)\n      assert_equal(col.size, cols)\n      assert_equal(str + \"|\", tsv2csv(buf, ?|))\n    end\n\n    buf = ''\n    toBe = ''\n    cols = 0\n    colsToBe = 0\n    @@fullCSVData.each do |col, str|\n      cols += CSV.generate_row(col, col.size, buf)\n      toBe << str << \"\\n\"\n      colsToBe += col.size\n    end\n    assert_equal(colsToBe, cols)\n    assert_equal(toBe, buf)\n\n    buf = ''\n    toBe = ''\n    cols = 0\n    colsToBe = 0\n    @@fullCSVData.each do |col, str|\n      lineBuf = ''\n      cols += CSV.generate_row(col, col.size, lineBuf, ?;)\n      buf << ssv2csv(lineBuf) << \"\\n\"\n      toBe << ssv2csv(lineBuf) << \"\\n\"\n      colsToBe += col.size\n    end\n    assert_equal(colsToBe, cols)\n    assert_equal(toBe, buf)\n\n    buf = ''\n    toBe = ''\n    cols = 0\n    colsToBe = 0\n    @@fullCSVData.each do |col, str|\n      lineBuf = ''\n      cols += CSV.generate_row(col, col.size, lineBuf, ?\\t)\n      buf << tsv2csv(lineBuf) << \"\\n\"\n      toBe << tsv2csv(lineBuf) << \"\\n\"\n      colsToBe += col.size\n    end\n    assert_equal(colsToBe, cols)\n    assert_equal(toBe, buf)\n\n    buf = ''\n    toBe = ''\n    cols = 0\n    colsToBe = 0\n    @@fullCSVData.each do |col, str|\n      lineBuf = ''\n      cols += CSV.generate_row(col, col.size, lineBuf, ?|)\n      buf << tsv2csv(lineBuf, ?|)\n      toBe << tsv2csv(lineBuf, ?|)\n      colsToBe += col.size\n    end\n    assert_equal(colsToBe, cols)\n    assert_equal(toBe, buf)\n  end\n\n  def test_s_parse_line\n    @@simpleCSVData.each do |col, str|\n      row = CSV.parse_line(str)\n      assert_instance_of(Array, row)\n      assert_equal(col.size, row.size)\n      assert_equal(col, row)\n    end\n\n    @@simpleCSVData.each do |col, str|\n      str = csv2ssv(str)\n      row = CSV.parse_line(str, ?;)\n      assert_instance_of(Array, row)\n      assert_equal(col.size, row.size, str.inspect)\n      assert_equal(col, row, str.inspect)\n    end\n\n    @@simpleCSVData.each do |col, str|\n      str = csv2tsv(str)\n      row = CSV.parse_line(str, ?\\t)\n      assert_instance_of(Array, row)\n      assert_equal(col.size, row.size)\n      assert_equal(col, row)\n    end\n\n    assert_equal(['a', 'b', 'c'], CSV.parse_line(\"a,b,c\", nil, nil))\n    assert_equal(['a', nil], CSV.parse_line(\"a,b,c\", nil, ?b))\n    assert_equal(['a', 'b', nil], CSV.parse_line(\"a,b,c\", nil, \"c\"))\n    assert_equal([nil], CSV.parse_line(\"\"))\n    assert_equal([nil], CSV.parse_line(\"\\n\"))\n    assert_equal([\"\"], CSV.parse_line(\"\\\"\\\"\\n\"))\n    \n    # Illegal format.\n    buf = []\n    row = CSV.parse_line(\"a,b,\\\"c\\\"\\ra\")\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    buf = Array.new\n    row = CSV.parse_line(\"a;b;\\\"c\\\"\\ra\", ?;)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    buf = Array.new\n    row = CSV.parse_line(\"a\\tb\\t\\\"c\\\"\\ra\", ?\\t)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"a,b\\\"\")\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"a;b\\\"\", ?;)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"a\\tb\\\"\", ?\\t)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"\\\"a,b\\\"\\r,\")\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"\\\"a;b\\\"\\r;\", ?;)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"\\\"a\\tb\\\"\\r\\t\", ?\\t)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"\\\"a,b\\\"\\r\\\"\")\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"\\\"a;b\\\"\\r\\\"\", ?;)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n\n    row = CSV.parse_line(\"\\\"a\\tb\\\"\\r\\\"\", ?\\t)\n    assert_instance_of(Array, row)\n    assert_equal(0, row.size)\n  end\n\n  def test_s_parse_row\n    @@fullCSVData.each do |col, str|\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"\\r\\n\", 0, buf)\n      assert_equal(cols, buf.size, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf, str.inspect)\n\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"\\n\", 0, buf, ?,, ?\\n)\n      assert_equal(cols, buf.size, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf, str.inspect)\n\n      # separator: |\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"|\", 0, buf, ?,)\n      assert_not_equal(col, buf)\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"|\", 0, buf, ?,, ?|)\n      assert_equal(cols, buf.size, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf, str.inspect)\n    end\n\n    @@fullCSVData.each do |col, str|\n      str = csv2ssv(str)\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"\\r\\n\", 0, buf, ?;)\n      assert_equal(cols, buf.size, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf, str)\n    end\n\n    @@fullCSVData.each do |col, str|\n      str = csv2tsv(str)\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"\\r\\n\", 0, buf, ?\\t)\n      assert_equal(cols, buf.size, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf, str)\n    end\n\n    @@fullCSVData.each do |col, str|\n      str = csv2tsv(str, ?|)\n      buf = Array.new\n      cols, idx = CSV.parse_row(str + \"|\", 0, buf, ?\\t, ?|)\n      assert_equal(cols, buf.size, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf, str)\n    end\n\n    buf = []\n    CSV.parse_row(\"a,b,c\", 0, buf, nil, nil)\n    assert_equal(['a', 'b', 'c'], buf)\n\n    buf = []\n    CSV.parse_row(\"a,b,c\", 0, buf, nil, ?b)\n    assert_equal(['a', nil], buf)\n\n    buf = []\n    CSV.parse_row(\"a,b,c\", 0, buf, nil, \"c\")\n    assert_equal(['a', 'b', nil], buf)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a,b,\\\"c\\r\\\"\", 0, buf)\n    assert_equal([\"a\", \"b\", \"c\\r\"], buf.to_a)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a;b;\\\"c\\r\\\"\", 0, buf, ?;)\n    assert_equal([\"a\", \"b\", \"c\\r\"], buf.to_a)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\tb\\t\\\"c\\r\\\"\", 0, buf, ?\\t)\n    assert_equal([\"a\", \"b\", \"c\\r\"], buf.to_a)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a,b,c\\n\", 0, buf, ?,, ?\\n)\n    assert_equal([\"a\", \"b\", \"c\"], buf.to_a)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\tb\\tc\\n\", 0, buf, ?\\t, ?\\n)\n    assert_equal([\"a\", \"b\", \"c\"], buf.to_a)\n\n    # Illegal format.\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a,b,c\\\"\", 0, buf)\n    assert_equal(0, cols, \"Illegal format; unbalanced double-quote.\")\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a;b;c\\\"\", 0, buf, ?;)\n    assert_equal(0, cols, \"Illegal format; unbalanced double-quote.\")\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a,b,\\\"c\\\"\\ra\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a,b,\\\"c\\\"\\ra\", 0, buf, ?;)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a,b\\\"\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a;b\\\"\", 0, buf, ?;)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"\\\"a,b\\\"\\r,\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\r,\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\r\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\rbc\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\r\\\"\\\"\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"a\\r\\rabc,\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"\\\"a;b\\\"\\r;\", 0, buf, ?;)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"\\\"a,b\\\"\\r\\\"\", 0, buf)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n\n    buf = Array.new\n    cols, idx = CSV.parse_row(\"\\\"a;b\\\"\\r\\\"\", 0, buf, ?;)\n    assert_equal(0, cols)\n    assert_equal(0, idx)\n  end\n\n  def test_s_parse_rowEOF\n    @@fullCSVData.each do |col, str|\n      if str == ''\n\t# String \"\" is not allowed.\n\tnext\n      end\n      buf = Array.new\n      cols, idx = CSV.parse_row(str, 0, buf)\n      assert_equal(col.size, cols, \"Reported size.\")\n      assert_equal(col.size, buf.size, \"Size.\")\n      assert_equal(col, buf)\n    end\n  end\n\n  def test_s_parse_rowConcat\n    buf = ''\n    toBe = []\n    @@fullCSVData.each do |col, str|\n      buf  << str << \"\\r\\n\"\n      toBe.concat(col)\n    end\n    idx = 0\n    cols = 0\n    parsed = Array.new\n    parsedCols = 0\n    begin\n      cols, idx = CSV.parse_row(buf, idx, parsed)\n      parsedCols += cols\n    end while cols > 0\n    assert_equal(toBe.size, parsedCols)\n    assert_equal(toBe.size, parsed.size)\n    assert_equal(toBe, parsed)\n\n    buf = ''\n    toBe = []\n    @@fullCSVData.each do |col, str|\n      buf  << str << \"\\n\"\n      toBe.concat(col)\n    end\n    idx = 0\n    cols = 0\n    parsed = Array.new\n    parsedCols = 0\n    begin\n      cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?\\n)\n      parsedCols += cols\n    end while cols > 0\n    assert_equal(toBe.size, parsedCols)\n    assert_equal(toBe.size, parsed.size)\n    assert_equal(toBe, parsed)\n\n    buf = ''\n    toBe = []\n    @@fullCSVData.sort { |a, b|\n      a[0].length <=> b[0].length\n    }.each do |col, str|\n      buf  << str << \"\\n\"\n      toBe.concat(col)\n    end\n    idx = 0\n    cols = 0\n    parsed = Array.new\n    parsedCols = 0\n    begin\n      cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?\\n)\n      parsedCols += cols\n    end while cols > 0\n    assert_equal(toBe.size, parsedCols)\n    assert_equal(toBe.size, parsed.size)\n    assert_equal(toBe, parsed)\n\n    buf = ''\n    toBe = []\n    @@fullCSVData.each do |col, str|\n      buf  << str << \"|\"\n      toBe.concat(col)\n    end\n    idx = 0\n    cols = 0\n    parsed = []\n    parsedCols = 0\n    begin\n      cols, idx = CSV.parse_row(buf, idx, parsed, ?,, ?|)\n      parsedCols += cols\n    end while cols > 0\n    assert_equal(toBe.size, parsedCols)\n    assert_equal(toBe.size, parsed.size)\n    assert_equal(toBe, parsed)\n  end\n\n  def test_utf8\n    rows = []\n    CSV.open(@bomfile, \"r\") do |row|\n      rows << row.to_a\n    end\n    assert_equal([[\"foo\"], [\"bar\"]], rows)\n\n    rows = []\n    file = File.open(@bomfile)\n    CSV::Reader.parse(file) do |row|\n      rows << row.to_a\n    end\n    assert_equal([[\"foo\"], [\"bar\"]], rows)\n    file.close\n  end\n\n  def test_macCR\n    rows = []\n    CSV.open(@macfile, \"r\", ?,, ?\\r) do |row|\n      rows << row.to_a\n    end\n    assert_equal([[\"Avenches\", \"aus Umgebung\"], [\"Bad Hersfeld\", \"Ausgrabung\"]], rows)\n\n    rows = []\n    assert_raises(CSV::IllegalFormatError) do\n      CSV.open(@macfile, \"r\") do |row|\n        rows << row.to_a\n      end\n      assert_equal([[\"Avenches\", \"aus Umgebung\\r\\\"Bad Hersfeld\", \"Ausgrabung\"]], rows)\n    end\n\n    rows = []\n    file = File.open(@macfile)\n    begin\n      CSV::Reader.parse(file, ?,, ?\\r) do |row|\n        rows << row.to_a\n      end\n      assert_equal([[\"Avenches\", \"aus Umgebung\"], [\"Bad Hersfeld\", \"Ausgrabung\"]], rows)\n    ensure\n      file.close\n    end\n\n    rows = []\n    file = File.open(@macfile)\n    begin\n      assert_raises(CSV::IllegalFormatError) do\n        CSV::Reader.parse(file, ?,) do |row|\n          rows << row.to_a\n        end\n        assert_equal([[\"Avenches\", \"aus Umgebung\\r\\\"Bad Hersfeld\", \"Ausgrabung\"]], rows)\n      end\n    ensure\n      file.close\n    end\n  end\n\n\n  #### CSV unit test\n\n  InputStreamPattern = '0123456789'\n  InputStreamPatternSize = InputStreamPattern.size\n  def expChar(idx)\n    InputStreamPattern[idx % InputStreamPatternSize]\n  end\n\n  def expStr(idx, n)\n    if n > InputStreamPatternSize\n      InputStreamPattern + expStr(0, n - InputStreamPatternSize)\n    else\n      InputStreamPattern[idx % InputStreamPatternSize, n]\n    end\n  end\n\n  def setupInputStream(size, bufSize = nil)\n    setBufSize(bufSize) if bufSize\n    m = ((size / InputStreamPatternSize) + 1).to_i\n    File.open(@outfile, \"wb\") do |f|\n      f << (InputStreamPattern * m)[0, size]\n    end\n    file = File.open(@outfile, \"rb\")\n    buf = CSV::IOBuf.new(file)\n    if block_given?\n      yield(buf)\n      file.close\n      nil\n    else\n      buf\n    end\n  end\n\n  def setBufSize(size)\n    CSV::StreamBuf.module_eval('remove_const(\"BufSize\")')\n    CSV::StreamBuf.module_eval(\"BufSize = #{ size }\")\n  end\n\n  class StrBuf < CSV::StreamBuf\n  private\n    def initialize(string)\n      @str = string\n      @idx = 0\n      super()\n    end\n\n    def read(size)\n      str = @str[@idx, size]\n      if str.empty?\n        nil\n      else\n        @idx += str.size\n        str\n      end\n    end\n  end\n\n  class ErrBuf < CSV::StreamBuf\n    class Error < RuntimeError; end\n  private\n    def initialize\n      @first = true\n      super()\n    end\n\n    def read(size)\n      if @first\n\t@first = false\n\t\"a\" * size\n      else\n\traise ErrBuf::Error.new\n      end\n    end\n  end\n\n  def test_StreamBuf_MyBuf\n    # At first, check ruby's behaviour.\n    s = \"abc\"\n    assert_equal(?a, s[0])\n    assert_equal(?b, s[1])\n    assert_equal(?c, s[2])\n    assert_equal(nil, s[3])\n    assert_equal(\"a\", s[0, 1])\n    assert_equal(\"b\", s[1, 1])\n    assert_equal(\"c\", s[2, 1])\n    assert_equal(\"\", s[3, 1])\n    assert_equal(nil, s[4, 1])\n\n    s = StrBuf.new(\"abc\")\n    assert_equal(?a, s[0])\n    assert_equal(?b, s.get(1))\n    assert_equal(?c, s[2])\n    assert_equal(nil, s.get(3))\n    assert_equal(\"a\", s[0, 1])\n    assert_equal(\"b\", s.get(1, 1))\n    assert_equal(\"c\", s[2, 1])\n    assert_equal(\"\", s.get(3, 1))\n    assert_equal(nil, s[4, 1])\n\n    dropped = s.drop(1)\n    assert_equal(1, dropped)\n    assert_equal(?b, s[0])\n    assert(!s.is_eos?)\n    dropped = s.drop(1)\n    assert_equal(1, dropped)\n    assert_equal(?c, s[0])\n    assert(!s.is_eos?)\n    dropped = s.drop(1)\n    assert_equal(1, dropped)\n    assert_equal(nil, s[0])\n    assert(s.is_eos?)\n    dropped = s.drop(1)\n    assert_equal(0, dropped)\n    assert_equal(nil, s[0])\n    assert(s.is_eos?)\n\n    s = StrBuf.new(\"\")\n    assert_equal(nil, s[0])\n\n    s = StrBuf.new(\"\")\n    dropped = s.drop(1)\n    assert_equal(0, dropped)\n\n    assert_raises(TestCSV::ErrBuf::Error) do\n      s = ErrBuf.new\n      s[1024]\n    end\n\n    assert_raises(TestCSV::ErrBuf::Error) do\n      s = ErrBuf.new\n      s.drop(1024)\n    end\n  end\n\n  def test_StreamBuf_AREF # '[idx]'\n    setupInputStream(22, 1024) do |s|\n      [0, 1, 9, 10, 19, 20, 21].each do |idx|\n\tassert_equal(expChar(idx), s[idx], idx.to_s)\n      end\n      [22, 23].each do |idx|\n\tassert_equal(nil, s[idx], idx.to_s)\n      end\n      assert_equal(nil, s[-1])\n    end\n\n    setupInputStream(22, 1) do |s|\n      [0, 1, 9, 10, 19, 20, 21].each do |idx|\n\tassert_equal(expChar(idx), s[idx], idx.to_s)\n      end\n      [22, 23].each do |idx|\n\tassert_equal(nil, s[idx], idx.to_s)\n      end\n    end\n\n    setupInputStream(1024, 1) do |s|\n      [1023, 0].each do |idx|\n\tassert_equal(expChar(idx), s[idx], idx.to_s)\n      end\n      [1024, 1025].each do |idx|\n\tassert_equal(nil, s[idx], idx.to_s)\n      end\n    end\n\n    setupInputStream(1, 1) do |s|\n      [0].each do |idx|\n\tassert_equal(expChar(idx), s[idx], idx.to_s)\n      end\n      [1, 2].each do |idx|\n\tassert_equal(nil, s[idx], idx.to_s)\n      end\n    end\n  end\n\n  def test_StreamBuf_AREF_n # '[idx, n]'\n    # At first, check ruby's behaviour.\n    assert_equal(\"\", \"abc\"[3, 1])\n    assert_equal(nil, \"abc\"[4, 1])\n    \n    setupInputStream(22, 1024) do |s|\n      [0, 1, 9, 10, 19, 20, 21].each do |idx|\n\tassert_equal(expStr(idx, 1), s[idx, 1], idx.to_s)\n      end\n      assert_equal(\"\", s[22, 1])\n      assert_equal(nil, s[23, 1])\n    end\n\n    setupInputStream(22, 1) do |s|\n      [0, 1, 9, 10, 19, 20, 21].each do |idx|\n\tassert_equal(expStr(idx, 1), s[idx, 1], idx.to_s)\n      end\n      assert_equal(\"\", s[22, 1])\n      assert_equal(nil, s[23, 1])\n    end\n\n    setupInputStream(1024, 1) do |s|\n      [1023, 0].each do |idx|\n\tassert_equal(expStr(idx, 1), s[idx, 1], idx.to_s)\n      end\n      assert_equal(\"\", s[1024, 1])\n      assert_equal(nil, s[1025, 1])\n    end\n\n    setupInputStream(1, 1) do |s|\n      [0].each do |idx|\n\tassert_equal(expStr(idx, 1), s[idx, 1], idx.to_s)\n      end\n      assert_equal(\"\", s[1, 1])\n      assert_equal(nil, s[2, 1])\n    end\n\n    setupInputStream(22, 11) do |s|\n      [0, 1, 10, 11, 20].each do  |idx|\n\tassert_equal(expStr(idx, 2), s[idx, 2], idx.to_s)\n      end\n      assert_equal(expStr(21, 1), s[21, 2])\n\n      assert_equal(expStr(0, 12), s[0, 12])\n      assert_equal(expStr(10, 12), s[10, 12])\n      assert_equal(expStr(10, 12), s[10, 13])\n      assert_equal(expStr(10, 12), s[10, 14])\n      assert_equal(expStr(10, 12), s[10, 1024])\n\n      assert_equal(nil, s[0, -1])\n      assert_equal(nil, s[21, -1])\n\n      assert_equal(nil, s[-1, 10])\n      assert_equal(nil, s[-1, -1])\n    end\n  end\n\n  def test_StreamBuf_get\n    setupInputStream(22, 1024) do |s|\n      [0, 1, 9, 10, 19, 20, 21].each do |idx|\n\tassert_equal(expChar(idx), s.get(idx), idx.to_s)\n      end\n      [22, 23].each do |idx|\n\tassert_equal(nil, s.get(idx), idx.to_s)\n      end\n      assert_equal(nil, s.get(-1))\n    end\n  end\n  \n  def test_StreamBuf_get_n\n    setupInputStream(22, 1024) do |s|\n      [0, 1, 9, 10, 19, 20, 21].each do |idx|\n\tassert_equal(expStr(idx, 1), s.get(idx, 1), idx.to_s)\n      end\n      assert_equal(\"\", s.get(22, 1))\n      assert_equal(nil, s.get(23, 1))\n\n      assert_equal(nil, s.get(-1, 1))\n      assert_equal(nil, s.get(-1, -1))\n    end\n  end\n\n  def test_StreamBuf_drop\n    setupInputStream(22, 1024) do |s|\n      assert_equal(expChar(0), s[0])\n      assert_equal(expChar(21), s[21])\n      assert_equal(nil, s[22])\n\n      dropped = s.drop(-1)\n      assert_equal(0, dropped)\n      assert_equal(expChar(0), s[0])\n\n      dropped = s.drop(0)\n      assert_equal(0, dropped)\n      assert_equal(expChar(0), s[0])\n\n      dropped = s.drop(1)\n      assert_equal(1, dropped)\n      assert_equal(expChar(1), s[0])\n      assert_equal(expChar(2), s[1])\n\n      dropped = s.drop(1)\n      assert_equal(1, dropped)\n      assert_equal(expChar(2), s[0])\n      assert_equal(expChar(3), s[1])\n    end\n\n    setupInputStream(4, 2) do |s|\n      dropped = s.drop(2)\n      assert_equal(2, dropped)\n      assert_equal(expChar(2), s[0])\n      assert_equal(expChar(3), s[1])\n      dropped = s.drop(1)\n      assert_equal(1, dropped)\n      assert_equal(expChar(3), s[0])\n      assert_equal(nil, s[1])\n      dropped = s.drop(1)\n      assert_equal(1, dropped)\n      assert_equal(nil, s[0])\n      assert_equal(nil, s[1])\n      dropped = s.drop(0)\n      assert_equal(0, dropped)\n      assert_equal(nil, s[0])\n      assert_equal(nil, s[1])\n    end\n\n    setupInputStream(6, 3) do |s|\n      dropped = s.drop(2)\n      assert_equal(2, dropped)\n      dropped = s.drop(2)\n      assert_equal(2, dropped)\n      assert_equal(expChar(4), s[0])\n      assert_equal(expChar(5), s[1])\n      dropped = s.drop(3)\n      assert_equal(2, dropped)\n      assert_equal(nil, s[0])\n      assert_equal(nil, s[1])\n    end\n  end\n\n  def test_StreamBuf_is_eos?\n    setupInputStream(3, 1024) do |s|\n      assert(!s.is_eos?)\n      s.drop(1)\n      assert(!s.is_eos?)\n      s.drop(1)\n      assert(!s.is_eos?)\n      s.drop(1)\n      assert(s.is_eos?)\n      s.drop(1)\n      assert(s.is_eos?)\n    end\n\n    setupInputStream(3, 2) do |s|\n      assert(!s.is_eos?)\n      s.drop(1)\n      assert(!s.is_eos?)\n      s.drop(1)\n      assert(!s.is_eos?)\n      s.drop(1)\n      assert(s.is_eos?)\n      s.drop(1)\n      assert(s.is_eos?)\n    end\n  end\n\n  def test_StreamBuf_s_new\n    # NotImplementedError should be raised from StreamBuf#read.\n    assert_raises(NotImplementedError) do\n      CSV::StreamBuf.new\n    end\n  end\n\n  def test_IOBuf_close\n    f = File.open(@outfile, \"wb\")\n    f << \"tst\"\n    f.close\n\n    f = File.open(@outfile, \"rb\")\n    iobuf = CSV::IOBuf.new(f)\n    iobuf.close\n    assert(true)\t# iobuf.close does not raise any exception.\n    f.close\n  end\n\n  def test_IOBuf_s_new\n    iobuf = CSV::IOBuf.new(Tempfile.new(\"in.csv\"))\n    assert_instance_of(CSV::IOBuf, iobuf)\n  end\n\n\n  #### CSV functional test\n\n  # sample data\n  #\n  #  1      2       3         4       5        6      7    8\n  # +------+-------+---------+-------+--------+------+----+------+\n  # | foo  | \"foo\" | foo,bar | \"\"    |(empty) |(null)| \\r | \\r\\n |\n  # +------+-------+---------+-------+--------+------+----+------+\n  # | NaHi | \"Na\"  | Na,Hi   | \\r.\\n | \\r\\n\\n | \"    | \\n | \\r\\n |\n  # +------+-------+---------+-------+--------+------+----+------+\n  #\n  def test_s_parseAndCreate\n    colSize = 8\n    csvStr = \"foo,!!!foo!!!,!foo,bar!,!!!!!!,!!,,!\\r!,!\\r\\n!\\nNaHi,!!!Na!!!,!Na,Hi!,!\\r.\\n!,!\\r\\n\\n!,!!!!,!\\n!,!\\r\\n!\".gsub!('!', '\"')\n    csvStrTerminated = csvStr + \"\\n\"\n\n    myStr = csvStr.dup\n    res1 = []; res2 = []\n    idx = 0\n    col, idx = CSV::parse_row(myStr, 0, res1)\n    col, idx = CSV::parse_row(myStr, idx, res2)\n\n    buf = ''\n    col = CSV::generate_row(res1, colSize, buf)\n    col = CSV::generate_row(res2, colSize, buf)\n    assert_equal(csvStrTerminated, buf)\n\n    parsed = []\n    CSV::Reader.parse(csvStrTerminated) do |row|\n      parsed << row\n    end\n\n    buf = ''\n    CSV::Writer.generate(buf) do |writer|\n      parsed.each do |row|\n\twriter.add_row(row)\n      end\n    end\n    assert_equal(csvStrTerminated, buf)\n\n    buf = ''\n    CSV::Writer.generate(buf) do |writer|\n      parsed.each do |row|\n\twriter << row\n      end\n    end\n    assert_equal(csvStrTerminated, buf)\n  end\n\n  def test_writer_fs_rs_generate\n    buf = ''\n    CSV::Writer.generate(buf, \",,\") do |writer|\n      writer << []\n    end\n    assert_equal(\"\\n\", buf)\n\n    buf = ''\n    CSV::Writer.generate(buf, \",,\") do |writer|\n      writer << [] << []\n    end\n    assert_equal(\"\\n\\n\", buf)\n\n    buf = ''\n    CSV::Writer.generate(buf, \",,\") do |writer|\n      writer << [1]\n    end\n    assert_equal(\"1\\n\", buf)\n\n    buf = ''\n    CSV::Writer.generate(buf, \",,\") do |writer|\n      writer << [1, 2, 3]\n      writer << [4, \",,\", 5]\n    end\n    assert_equal(\"1,,2,,3\\n4,,\\\",,\\\",,5\\n\", buf)\n\n    buf = ''\n    CSV::Writer.generate(buf, \",,:\", \",,;\") do |writer|\n      writer << [nil, nil, nil]\n      writer << [nil, \",,\", nil]\n    end\n    assert_equal(\",,:,,:,,;,,:,,,,:,,;\", buf)\n\n    buf = ''\n    CSV::Writer.generate(buf, \"---\") do |writer|\n      writer << [1, 2, 3]\n      writer << [4, \"---\\\"---\", 5]\n    end\n    assert_equal(\"1---2---3\\n4---\\\"---\\\"\\\"---\\\"---5\\n\", buf)\n\n    buf = ''\n    CSV::Writer.generate(buf, nil) do |writer|\n      writer << [1, 2, 3]\n      writer << [4, \",\\\",\", 5]\n    end\n    assert_equal(\"1,2,3\\n4,\\\",\\\"\\\",\\\",5\\n\", buf)\n  end\n\n  def test_writer_fs_rs_parse\n    reader = CSV::Reader.create('a||b--c||d', '||', '--')\n    assert_equal(['a', 'b'], reader.shift)\n    assert_equal(['c', 'd'], reader.shift)\n\n    reader = CSV::Reader.create(\"a@|b@-c@|d\", \"@|\", \"@-\")\n    assert_equal(['a', 'b'], reader.shift)\n    assert_equal(['c', 'd'], reader.shift)\n\n    reader = CSV::Reader.create(\"ababfsababrs\", \"abfs\", \"abrs\")\n    assert_equal(['ab', 'ab'], reader.shift)\n\n    reader = CSV::Reader.create('\"ab\"abfsababrs', \"abfs\", \"abrs\")\n    assert_equal(['ab', 'ab'], reader.shift)\n\n    reader = CSV::Reader.create('\"ab\"aabfsababrs', \"abfs\", \"abrs\")\n    assert_raises(CSV::IllegalFormatError) do\n      reader.shift\n    end\n\n    # fs match while matching rs progress\n    reader = CSV::Reader.create(\"ab,ababrs\", nil, \"abrs\")\n    assert_equal(['ab', 'ab'], reader.shift)\n\n    reader = CSV::Reader.create(',ababrs', nil, \"abrs\")\n    assert_equal([nil, 'ab'], reader.shift)\n\n    reader = CSV::Reader.create('\"\",ababrs', nil, \"abrs\")\n    assert_equal(['', 'ab'], reader.shift)\n\n    reader = CSV::Reader.create('ab,\"ab\"abrs', nil, \"abrs\")\n    assert_equal(['ab', 'ab'], reader.shift)\n\n    reader = CSV::Reader.create('ab,\"ab\"aabrs', nil, \"abrs\")\n    assert_raises(CSV::IllegalFormatError) do\n      reader.shift\n    end\n\n    # rs match while matching fs progress\n    reader = CSV::Reader.create(\"ab|abc\", 'ab-', \"ab|\")\n    assert_equal([nil], reader.shift)\n    assert_equal(['abc'], reader.shift)\n\n    reader = CSV::Reader.create(\"ab\\ncdabcef\", \"abc\", \"\\n\")\n    assert_equal(['ab'], reader.shift)\n    assert_equal(['cd', \"ef\"], reader.shift)\n\n    # EOF while fs/rs matching\n    reader = CSV::Reader.create(\"ab\", 'ab-', \"xyz\")\n    assert_equal(['ab'], reader.shift)\n\n    reader = CSV::Reader.create(\"ab\", 'xyz', \"ab|\")\n    assert_equal(['ab'], reader.shift)\n\n    reader = CSV::Reader.create(\"ab\", 'ab-', \"ab|\")\n    assert_equal(['ab'], reader.shift)\n\n    reader = CSV::Reader.create(\",,:,,:,,;,,:,,,,:,,;\", \",,:\", \",,;\")\n    assert_equal([nil, nil, nil], reader.shift)\n    assert_equal([nil, \",,\", nil], reader.shift)\n  end\n\n  def test_s_foreach\n    File.open(@outfile, \"w\") do |f|\n      f << \"1,2,3\\n4,5,6\"\n    end\n    row = []\n    CSV.foreach(@outfile) { |line|\n      row << line\n    }\n    assert_equal([['1', '2', '3'], ['4', '5', '6']], row)\n\n    File.open(@outfile, \"w\") do |f|\n      f << \"1,2,3\\r4,5,6\"\n    end\n    row = []\n    CSV.foreach(@outfile, \"\\r\") { |line|\n      row << line\n    }\n    assert_equal([['1', '2', '3'], ['4', '5', '6']], row)\n  end\n\n  def test_s_readlines\n    File.open(@outfile, \"w\") do |f|\n      f << \"1,2,3\\n4,5,6\"\n    end\n    assert_equal([[\"1\", \"2\", \"3\"], [\"4\", \"5\", \"6\"]], CSV.readlines(@outfile))\n    assert_equal([[\"1\", \"2\", nil], [nil, \"5\", \"6\"]], CSV.readlines(@outfile, \"3\\n4\"))\n  end\n\n  def test_s_read\n    File.open(@outfile, \"w\") do |f|\n      f << \"1,2,3\\n4,5,6\"\n    end\n    assert_equal([[\"1\", \"2\", \"3\"], [\"4\", \"5\", \"6\"]], CSV.read(@outfile))\n    assert_equal([[\"1\", \"2\"]], CSV.read(@outfile, 3))\n    assert_equal([[nil], [\"4\", nil]], CSV.read(@outfile, 3, 5))\n  end\nend\n"
  },
  {
    "path": "test/dbm/test_dbm.rb",
    "content": "require 'test/unit'\n\nbegin\n  require 'dbm'\nrescue LoadError\nend\n\nif defined? DBM\n  require 'tmpdir'\n  require 'fileutils'\n\n  class TestDBM < Test::Unit::TestCase\n    def TestDBM.uname_s\n      require 'rbconfig'\n      case Config::CONFIG['target_os']\n      when 'cygwin'\n        require 'Win32API'\n        uname = Win32API.new('cygwin1', 'uname', 'P', 'I')\n        utsname = ' ' * 100\n        raise 'cannot get system name' if uname.call(utsname) == -1\n\n        utsname.unpack('A20' * 5)[0]\n      else\n        Config::CONFIG['target_os']\n      end\n    end\n    SYSTEM = uname_s\n\n    def setup\n      @path = \"tmptest_dbm_\"\n      assert_instance_of(DBM, @dbm = DBM.new(@path))\n\n      # prepare to make readonly DBM file\n      DBM.open(\"tmptest_dbm_rdonly\") {|dbm|\n        dbm['foo'] = 'FOO'\n      }\n      \n      File.chmod(0400, *Dir.glob(\"tmptest_dbm_rdonly.*\"))\n\n      assert_instance_of(DBM, @dbm_rdonly = DBM.new(\"tmptest_dbm_rdonly\", nil))\n    end\n    def teardown\n      assert_nil(@dbm.close)\n      assert_nil(@dbm_rdonly.close)\n      ObjectSpace.each_object(DBM) do |obj|\n        obj.close unless obj.closed?\n      end\n      File.delete *Dir.glob(\"tmptest_dbm*\").to_a\n      p Dir.glob(\"tmptest_dbm*\") if $DEBUG\n    end\n\n    def check_size(expect, dbm=@dbm)\n      assert_equal(expect, dbm.size)\n      n = 0\n      dbm.each { n+=1 }\n      assert_equal(expect, n)\n      if expect == 0\n        assert_equal(true, dbm.empty?)\n      else\n        assert_equal(false, dbm.empty?)\n      end\n    end\n\n    def have_fork?\n      begin\n        fork{}\n        true\n      rescue NotImplementedError\n        false\n      end\n    end\n\n    def test_s_new_has_no_block\n      # DBM.new ignore the block\n      foo = true\n      assert_instance_of(DBM, dbm = DBM.new(\"tmptest_dbm\") { foo = false })\n      assert_equal(foo, true)\n      assert_nil(dbm.close)\n    end\n    def test_s_open_no_create\n      assert_nil(dbm = DBM.open(\"tmptest_dbm\", nil))\n    ensure\n      dbm.close if dbm\n    end\n    def test_s_open_with_block\n      assert_equal(DBM.open(\"tmptest_dbm\") { :foo }, :foo)\n    end\n\n    def test_close\n      assert_instance_of(DBM, dbm = DBM.open(\"tmptest_dbm\"))\n      assert_nil(dbm.close)\n\n      # closed DBM file\n      assert_raise(DBMError) { dbm.close }\n    end\n\n    def test_aref\n      assert_equal('bar', @dbm['foo'] = 'bar')\n      assert_equal('bar', @dbm['foo'])\n\n      assert_nil(@dbm['bar'])\n    end\n\n    def test_fetch\n      assert_equal('bar', @dbm['foo']='bar')\n      assert_equal('bar', @dbm.fetch('foo'))\n\n      # key not found\n      assert_raise(IndexError) {\n        @dbm.fetch('bar')\n      }\n\n      # test for `ifnone' arg\n      assert_equal('baz', @dbm.fetch('bar', 'baz'))\n\n      # test for `ifnone' block\n      assert_equal('foobar', @dbm.fetch('bar') {|key| 'foo' + key })\n    end\n\n    def test_aset\n      num = 0\n      2.times {|i|\n        assert_equal('foo', @dbm['foo'] = 'foo')\n        assert_equal('foo', @dbm['foo'])\n        assert_equal('bar', @dbm['foo'] = 'bar')\n        assert_equal('bar', @dbm['foo'])\n\n        num += 1 if i == 0\n        assert_equal(num, @dbm.size)\n\n        # assign nil\n        assert_equal('', @dbm['bar'] = '')\n        assert_equal('', @dbm['bar'])\n\n        num += 1 if i == 0\n        assert_equal(num, @dbm.size)\n\n        # empty string\n        assert_equal('', @dbm[''] = '')\n        assert_equal('', @dbm[''])\n\n        num += 1 if i == 0\n        assert_equal(num, @dbm.size)\n\n        # Fixnum\n        assert_equal('200', @dbm['100'] = '200')\n        assert_equal('200', @dbm['100'])\n\n        num += 1 if i == 0\n        assert_equal(num, @dbm.size)\n\n        # Big key and value\n        assert_equal('y' * 100, @dbm['x' * 100] = 'y' * 100)\n        assert_equal('y' * 100, @dbm['x' * 100])\n\n        num += 1 if i == 0\n        assert_equal(num, @dbm.size)\n      }\n    end\n\n    def test_index\n      assert_equal('bar', @dbm['foo'] = 'bar')\n      assert_equal('foo', @dbm.index('bar'))\n      assert_nil(@dbm['bar'])\n    end\n\n    def test_indexes\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n      assert_equal(values.reverse, @dbm.indexes(*keys.reverse))\n    end\n\n    def test_values_at\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n      assert_equal(values.reverse, @dbm.values_at(*keys.reverse))\n    end\n\n    def test_select_with_block\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n      ret = @dbm.select {|k,v|\n        assert_equal(k.upcase, v)\n        k != \"bar\"\n      }\n      assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],\n                    ret.sort)\n    end\n\n    def test_length\n      num = 10\n      assert_equal(0, @dbm.size)\n      num.times {|i|\n        i = i.to_s\n        @dbm[i] = i\n      }\n      assert_equal(num, @dbm.size)\n\n      @dbm.shift\n\n      assert_equal(num - 1, @dbm.size)\n    end\n\n    def test_empty?\n      assert_equal(true, @dbm.empty?)\n      @dbm['foo'] = 'FOO'\n      assert_equal(false, @dbm.empty?)\n    end\n\n    def test_each_pair\n      n = 0\n      @dbm.each_pair { n += 1 }\n      assert_equal(0, n)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n\n      n = 0\n      ret = @dbm.each_pair {|key, val|\n        assert_not_nil(i = keys.index(key))\n        assert_equal(val, values[i])\n\n        n += 1\n      }\n      assert_equal(keys.size, n)\n      assert_equal(@dbm, ret)\n    end\n\n    def test_each_value\n      n = 0\n      @dbm.each_value { n += 1 }\n      assert_equal(0, n)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n\n      n = 0\n      ret = @dbm.each_value {|val|\n        assert_not_nil(key = @dbm.index(val))\n        assert_not_nil(i = keys.index(key))\n        assert_equal(val, values[i])\n\n        n += 1\n      }\n      assert_equal(keys.size, n)\n      assert_equal(@dbm, ret)\n    end\n\n    def test_each_key\n      n = 0\n      @dbm.each_key { n += 1 }\n      assert_equal(0, n)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n\n      n = 0\n      ret = @dbm.each_key {|key|\n        assert_not_nil(i = keys.index(key))\n        assert_equal(@dbm[key], values[i])\n\n        n += 1\n      }\n      assert_equal(keys.size, n)\n      assert_equal(@dbm, ret)\n    end\n\n    def test_keys\n      assert_equal([], @dbm.keys)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n\n      assert_equal(keys.sort, @dbm.keys.sort)\n      assert_equal(values.sort, @dbm.values.sort)\n    end\n\n    def test_values\n      test_keys\n    end\n\n    def test_shift\n      assert_nil(@dbm.shift)\n      assert_equal(0, @dbm.size)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n\n      ret_keys = []\n      ret_values = []\n      while ret = @dbm.shift\n        ret_keys.push ret[0]\n        ret_values.push ret[1]\n\n        assert_equal(keys.size - ret_keys.size, @dbm.size)\n      end\n\n      assert_equal(keys.sort, ret_keys.sort)\n      assert_equal(values.sort, ret_values.sort)\n    end\n\n    def test_delete\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      key = keys[1]\n\n      assert_nil(@dbm.delete(key))\n      assert_equal(0, @dbm.size)\n\n      @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values\n\n      assert_equal('BAR', @dbm.delete(key))\n      assert_nil(@dbm[key])\n      assert_equal(2, @dbm.size)\n\n      assert_nil(@dbm.delete(key))\n\n      if /^CYGWIN_9/ !~ SYSTEM\n        assert_raise(DBMError) {\n          @dbm_rdonly.delete(\"foo\")\n        }\n\n        assert_nil(@dbm_rdonly.delete(\"bar\"))\n      end\n    end\n    def test_delete_with_block\n      key = 'no called block'\n      @dbm[key] = 'foo'\n      assert_equal('foo', @dbm.delete(key) {|k| k.replace 'called block'})\n      assert_equal('no called block', key)\n      assert_equal(0, @dbm.size)\n\n      key = 'no called block'\n      assert_equal(:blockval,\n                    @dbm.delete(key) {|k| k.replace 'called block'; :blockval})\n      assert_equal('called block', key)\n      assert_equal(0, @dbm.size)\n    end\n\n    def test_delete_if\n      v = \"0\"\n      100.times {@dbm[v] = v; v = v.next}\n\n      ret = @dbm.delete_if {|key, val| key.to_i < 50}\n      assert_equal(@dbm, ret)\n      check_size(50, @dbm)\n\n      ret = @dbm.delete_if {|key, val| key.to_i >= 50}\n      assert_equal(@dbm, ret)\n      check_size(0, @dbm)\n\n      # break\n      v = \"0\"\n      100.times {@dbm[v] = v; v = v.next}\n      check_size(100, @dbm)\n      n = 0;\n      @dbm.delete_if {|key, val|\n        break if n > 50\n        n+=1\n        true\n      }\n      assert_equal(51, n)\n      check_size(49, @dbm)\n\n      @dbm.clear\n\n      # raise\n      v = \"0\"\n      100.times {@dbm[v] = v; v = v.next}\n      check_size(100, @dbm)\n      n = 0;\n      begin\n        @dbm.delete_if {|key, val|\n          raise \"runtime error\" if n > 50\n          n+=1\n          true\n        }\n      rescue\n      end\n      assert_equal(51, n)\n      check_size(49, @dbm)\n    end\n\n    def test_reject\n      v = \"0\"\n      100.times {@dbm[v] = v; v = v.next}\n\n      hash = @dbm.reject {|key, val| key.to_i < 50}\n      assert_instance_of(Hash, hash)\n      assert_equal(100, @dbm.size)\n\n      assert_equal(50, hash.size)\n      hash.each_pair {|key,val|\n        assert_equal(false, key.to_i < 50)\n        assert_equal(key, val)\n      }\n\n      hash = @dbm.reject {|key, val| key.to_i < 100}\n      assert_instance_of(Hash, hash)\n      assert_equal(true, hash.empty?)\n    end\n\n    def test_clear\n      v = \"1\"\n      100.times {v = v.next; @dbm[v] = v}\n\n      assert_equal(@dbm, @dbm.clear)\n\n      # validate DBM#size\n      i = 0\n      @dbm.each { i += 1 }\n      assert_equal(@dbm.size, i)\n      assert_equal(0, i)\n    end\n\n    def test_invert\n      v = \"0\"\n      100.times {@dbm[v] = v; v = v.next}\n\n      hash = @dbm.invert\n      assert_instance_of(Hash, hash)\n      assert_equal(100, hash.size)\n      hash.each_pair {|key, val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_update\n      hash = {}\n      v = \"0\"\n      100.times {v = v.next; hash[v] = v}\n\n      @dbm[\"101\"] = \"101\"\n      @dbm.update hash\n      assert_equal(101, @dbm.size)\n      @dbm.each_pair {|key, val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_replace\n      hash = {}\n      v = \"0\"\n      100.times {v = v.next; hash[v] = v}\n\n      @dbm[\"101\"] = \"101\"\n      @dbm.replace hash\n      assert_equal(100, @dbm.size)\n      @dbm.each_pair {|key, val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_haskey?\n      assert_equal('bar', @dbm['foo']='bar')\n      assert_equal(true,  @dbm.has_key?('foo'))\n      assert_equal(false, @dbm.has_key?('bar'))\n    end\n\n    def test_has_value?\n      assert_equal('bar', @dbm['foo']='bar')\n      assert_equal(true,  @dbm.has_value?('bar'))\n      assert_equal(false, @dbm.has_value?('foo'))\n    end\n\n    def test_to_a\n      v = \"0\"\n      100.times {v = v.next; @dbm[v] = v}\n\n      ary = @dbm.to_a\n      assert_instance_of(Array, ary)\n      assert_equal(100, ary.size)\n      ary.each {|key,val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_to_hash\n      v = \"0\"\n      100.times {v = v.next; @dbm[v] = v}\n\n      hash = @dbm.to_hash\n      assert_instance_of(Hash, hash)\n      assert_equal(100, hash.size)\n      hash.each {|key,val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n  end\n\n  class TestDBM2 < Test::Unit::TestCase\n    TMPROOT = \"#{Dir.tmpdir}/ruby-dbm.#{$$}\"\n\n    def setup\n      Dir.mkdir TMPROOT\n    end\n\n    def teardown\n      FileUtils.rm_rf TMPROOT if File.directory?(TMPROOT)\n    end\n\n    def test_reader_open\n      DBM.open(\"#{TMPROOT}/a\") {}\n      v = DBM.open(\"#{TMPROOT}/a\", nil, DBM::READER) {|d|\n        # Errno::EPERM is raised on Solaris which use ndbm.\n        # DBMError is raised on Debian which use gdbm. \n        assert_raises(Errno::EPERM, DBMError) { d[\"k\"] = \"v\" }\n        true\n      }\n      assert(v)\n    end\n\n    def test_newdb_open\n      DBM.open(\"#{TMPROOT}/a\") {|dbm|\n        dbm[\"k\"] = \"v\"\n      }\n      v = DBM.open(\"#{TMPROOT}/a\", nil, DBM::NEWDB) {|d|\n        assert_equal(0, d.length)\n        assert_nil(d[\"k\"])\n        true\n      }\n      assert(v)\n    end\n\n    def test_freeze\n      DBM.open(\"#{TMPROOT}/a\") {|d|\n        d.freeze\n        assert_raises(TypeError) { d[\"k\"] = \"v\" }\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "test/digest/test_digest.rb",
    "content": "#!/usr/bin/env ruby\n#\n# $RoughId: test.rb,v 1.4 2001/07/13 15:38:27 knu Exp $\n# $Id$\n\nrequire 'test/unit'\n\nrequire 'digest'\n%w[digest/md5 digest/rmd160 digest/sha1 digest/sha2].each do |lib|\n  begin\n    require lib\n  rescue LoadError\n  end\nend\n\nmodule TestDigest\n  Data1 = \"abc\"\n  Data2 = \"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\n\n  def test_s_hexdigest\n    self.class::DATA.each do |str, digest|\n      assert_equal(digest, self.class::ALGO.hexdigest(str))\n    end\n  end\n\n  def test_s_digest\n    self.class::DATA.each do |str, digest|\n      assert_equal([digest].pack(\"H*\"), self.class::ALGO.digest(str))\n    end\n  end\n\n  def test_update\n    # This test is also for digest() and hexdigest()\n\n    str = \"ABC\"\n\n    md = self.class::ALGO.new\n    md.update str\n    assert_equal(self.class::ALGO.hexdigest(str), md.hexdigest)\n    assert_equal(self.class::ALGO.digest(str), md.digest)\n  end\n\n  def test_eq\n    # This test is also for clone()\n\n    md1 = self.class::ALGO.new\n    md1 << \"ABC\"\n\n    assert_equal(md1, md1.clone, self.class::ALGO)\n\n    md2 = self.class::ALGO.new\n    md2 << \"A\"\n\n    assert(md1 != md2, self.class::ALGO)\n\n    md2 << \"BC\"\n\n    assert_equal(md1, md2, self.class::ALGO)\n  end\n\n  def test_instance_eval\n    assert_nothing_raised {\n      self.class::ALGO.new.instance_eval { update \"a\" }\n    }\n  end\n\n  class TestMD5 < Test::Unit::TestCase\n    include TestDigest\n    ALGO = Digest::MD5\n    DATA = {\n      Data1 => \"900150983cd24fb0d6963f7d28e17f72\",\n      Data2 => \"8215ef0796a20bcaaae116d3876c664a\",\n    }\n  end if defined?(Digest::MD5)\n\n  class TestSHA1 < Test::Unit::TestCase\n    include TestDigest\n    ALGO = Digest::SHA1\n    DATA = {\n      Data1 => \"a9993e364706816aba3e25717850c26c9cd0d89d\",\n      Data2 => \"84983e441c3bd26ebaae4aa1f95129e5e54670f1\",\n    }\n  end if defined?(Digest::SHA1)\n\n  class TestSHA256 < Test::Unit::TestCase\n    include TestDigest\n    ALGO = Digest::SHA256\n    DATA = {\n      Data1 => \"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\",\n      Data2 => \"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1\",\n    }\n  end if defined?(Digest::SHA256)\n\n  class TestSHA384 < Test::Unit::TestCase\n    include TestDigest\n    ALGO = Digest::SHA384\n    DATA = {\n      Data1 => \"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7\",\n      Data2 => \"3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b\",\n    }\n  end if defined?(Digest::SHA384)\n\n  class TestSHA512 < Test::Unit::TestCase\n    include TestDigest\n    ALGO = Digest::SHA512\n    DATA = {\n      Data1 => \"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\",\n      Data2 => \"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445\",\n    }\n  end if defined?(Digest::SHA512)\n\n  class TestRMD160 < Test::Unit::TestCase\n    include TestDigest\n    ALGO = Digest::RMD160\n    DATA = {\n      Data1 => \"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc\",\n      Data2 => \"12a053384a9c0c88e405a06c27dcf49ada62eb2b\",\n    }\n  end if defined?(Digest::RMD160)\nend\n"
  },
  {
    "path": "test/drb/drbtest.rb",
    "content": "require 'test/unit'\nrequire 'drb/drb'\nrequire 'drb/extservm'\nrequire 'timeout'\nbegin\n  loadpath = $:.dup\n  $:.replace($: | [File.expand_path(\"../ruby\", File.dirname(__FILE__))])\n  require 'envutil'\nensure\n  $:.replace(loadpath)\nend\n\nclass DRbService\n  @@manager = DRb::ExtServManager.new\n  @@ruby = EnvUtil.rubybin\n  @@ruby += \" -d\" if $DEBUG\n  def self.add_service_command(nm)\n    dir = File.dirname(File.expand_path(__FILE__))\n    DRb::ExtServManager.command[nm] = \"\\\"#{@@ruby}\\\" \\\"#{dir}/#{nm}\\\"\"\n  end\n\n  %w(ut_drb.rb ut_array.rb ut_port.rb ut_large.rb ut_safe1.rb ut_eval.rb).each do |nm|\n    add_service_command(nm)\n  end\n  @server = @@server = DRb::DRbServer.new('druby://localhost:0', @@manager, {})\n  @@manager.uri = @@server.uri\n  def self.manager\n    @@manager\n  end\n  def self.server\n    @server || @@server\n  end\n  def self.ext_service(name)\n    timeout(100, RuntimeError) do\n      manager.service(name)\n    end\n  end\nend\n\nclass Onecky\n  include DRbUndumped\n  def initialize(n)\n    @num = n\n  end\n\n  def to_i\n    @num.to_i\n  end\n\n  def sleep(n)\n    Kernel.sleep(n)\n    to_i\n  end\nend\n\nclass FailOnecky < Onecky\n  class OneckyError < RuntimeError; end\n  def to_i\n    raise(OneckyError, @num.to_s)\n  end\nend\n\nclass XArray < Array\n  def initialize(ary)\n    ary.each do |x|\n      self.push(x)\n    end\n  end\nend\n\nmodule DRbCore\n  def setup\n    @ext = DRbService.ext_service('ut_drb.rb')\n    @there = @ext.front\n  end\n\n  def teardown\n    @ext.stop_service if @ext\n  end\n\n  def test_00_DRbObject\n    ro = DRbObject.new(nil, 'druby://localhost:12345')\n    assert_equal('druby://localhost:12345', ro.__drburi)\n    assert_equal(nil, ro.__drbref)\n\n    ro = DRbObject.new_with_uri('druby://localhost:12345')\n    assert_equal('druby://localhost:12345', ro.__drburi)\n    assert_equal(nil, ro.__drbref)\n\n    ro = DRbObject.new_with_uri('druby://localhost:12345?foobar')\n    assert_equal('druby://localhost:12345', ro.__drburi)\n    assert_equal(DRb::DRbURIOption.new('foobar'), ro.__drbref)\n  end\n\n  def test_01\n    assert_equal(\"hello\", @there.hello)\n    onecky = Onecky.new('3')\n    assert_equal(6, @there.sample(onecky, 1, 2))\n    ary = @there.to_a\n    assert_kind_of(DRb::DRbObject, ary)\n    \n    assert(@there.respond_to?(:to_a, true))\n    assert(@there.respond_to?(:eval, true))\n    assert(! @there.respond_to?(:eval, false))\n    assert(! @there.respond_to?(:eval))\n  end\n\n  def test_01_02_loop\n    onecky = Onecky.new('3')\n    50.times do\n      assert_equal(6, @there.sample(onecky, 1, 2))\n      ary = @there.to_a\n      assert_kind_of(DRb::DRbObject, ary)\n    end\n  end\n\n  def test_02_unknown\n    obj = @there.unknown_class\n    assert_kind_of(DRb::DRbUnknown, obj)\n    assert_equal('Unknown2', obj.name)\n\n    obj = @there.unknown_module\n    assert_kind_of(DRb::DRbUnknown, obj)\n    if RUBY_VERSION >= '1.8'\n      assert_equal('DRbEx::', obj.name)\n    else\n      assert_equal('DRbEx', obj.name)\n    end\n\n    assert_raises(DRb::DRbUnknownError) do\n      @there.unknown_error\n    end\n\n    onecky = FailOnecky.new('3')\n\n    assert_raises(FailOnecky::OneckyError) do\n      @there.sample(onecky, 1, 2)\n    end\n  end\n\n  def test_03\n    assert_equal(8, @there.sum(1, 1, 1, 1, 1, 1, 1, 1))\n    assert_raises(ArgumentError) do\n      @there.sum(1, 1, 1, 1, 1, 1, 1, 1, 1)\n    end\n    assert_raises(DRb::DRbConnError) do\n      @there.sum('1' * 4096)\n    end\n  end\n\n  def test_04\n    assert_respond_to(@there, 'sum')\n    assert(!(@there.respond_to? \"foobar\"))\n  end\n\n  def test_05_eq\n    a = @there.to_a[0]\n    b = @there.to_a[0]\n    assert(a.object_id != b.object_id)\n    assert(a == b)\n    assert_equal(a, b)\n    assert(a == @there)\n    assert_equal(a.hash, b.hash)\n    assert_equal(a.hash, @there.hash)\n    assert(a.eql?(b))\n    assert(a.eql?(@there))\n  end\n\n  def test_06_timeout\n    ten = Onecky.new(10)\n    assert_raises(TimeoutError) do\n      @there.do_timeout(ten)\n    end\n    assert_raises(TimeoutError) do\n      @there.do_timeout(ten)\n    end\n  end\n\n  def test_07_public_private_protected_missing\n    assert_nothing_raised() {\n      begin\n\t@there.method_missing(:eval)\n      rescue NoMethodError\n\tassert_match(/^private method \\`eval\\'/, $!.message)\n      end\n    }\n    assert_nothing_raised() {\n      begin\n        @there.call_private_method\n      rescue NoMethodError\n        assert_equal(NoMethodError, $!.class)\n\tassert_match(/^private method \\`call_private_method\\'/, $!.message)\n      end\n    }\n    assert_nothing_raised() {\n      begin\n        @there.call_protected_method\n      rescue NoMethodError\n        assert_equal(NoMethodError, $!.class)\n\tassert_match(/^protected method \\`call_protected_method\\'/, $!.message)\n      end\n    }\n    assert_nothing_raised() {\n      begin\n\t@there.method_missing(:undefined_method_test)\n      rescue NoMethodError\n        assert_equal(NoMethodError, $!.class)\n\tassert_match(/^undefined method \\`undefined_method_test\\'/, $!.message)\n      end\n    }\n    assert_raises(SecurityError) do\n      @there.method_missing(:__send__, :to_s)\n    end\n    assert_equal(true, @there.missing)\n  end\n\n  def test_08_here\n    ro = DRbObject.new(nil, DRb.uri)\n    assert_kind_of(String, ro.to_s)\n\n    ro = DRbObject.new_with_uri(DRb.uri)\n    assert_kind_of(String, ro.to_s)\n  end\n\n  def uri_concat_option(uri, opt)\n    \"#{uri}?#{opt}\"\n  end\n\n  def test_09_option\n    uri = uri_concat_option(@there.__drburi, \"foo\")\n    ro = DRbObject.new_with_uri(uri)\n    assert_equal(ro.__drburi, @there.__drburi)\n    assert_equal(3, ro.size)\n\n    uri = uri_concat_option(@there.__drburi, \"\")\n    ro = DRbObject.new_with_uri(uri)\n    assert_equal(ro.__drburi, @there.__drburi)\n    assert_equal(DRb::DRbURIOption.new(''), ro.__drbref)\n\n    uri = uri_concat_option(@there.__drburi, \"hello?world\")\n    ro = DRbObject.new_with_uri(uri)\n    assert_equal(DRb::DRbURIOption.new('hello?world'), ro.__drbref)\n\n    uri = uri_concat_option(@there.__drburi, \"?hello?world\")\n    ro = DRbObject.new_with_uri(uri)\n    assert_equal(DRb::DRbURIOption.new('?hello?world'), ro.__drbref)\n  end\n\n  def test_10_yield\n    @there.simple_hash.each do |k, v|\n      assert_kind_of(String, k)\n      assert_kind_of(Symbol, v)\n    end\n  end\n\n  def test_10_yield_undumped\n    @there.xarray2_hash.each do |k, v|\n      assert_kind_of(String, k)\n      assert_kind_of(DRbObject, v)\n    end\n  end\n\n  def test_11_remote_no_method_error\n    assert_raises(DRb::DRbRemoteError) do\n      @there.remote_no_method_error\n    end\n    begin\n      @there.remote_no_method_error\n    rescue\n      error = $!\n      assert_match(/^undefined method .*\\(NoMethodError\\)/, error.message)\n      assert_equal('NoMethodError', error.reason)\n    end\n  end\nend\n\nmodule DRbAry\n  def setup\n    @ext = DRbService.ext_service('ut_array.rb')\n    @there = @ext.front\n  end\n\n  def teardown\n    @ext.stop_service if @ext\n  end\n\n  def test_01\n    assert_kind_of(DRb::DRbObject, @there)\n  end\n\n  def test_02_collect\n    ary = @there.collect do |x| x + x end\n    assert_kind_of(Array, ary)\n    assert_equal([2, 4, 'IIIIII', 8, 'fivefive', 12], ary)\n  end\n\n  def test_03_redo\n    ary = []\n    count = 0\n    @there.each do |x|\n      count += 1\n      ary.push x\n      redo if count == 3\n    end\n    assert_equal([1, 2, 'III', 'III', 4, 'five', 6], ary)\n  end\n\n  def test_04_retry\n    retried = false\n    ary = []\n    @there.each do |x|\n      ary.push x\n      if x == 4 && !retried\n\tretried = true\n\tretry\n      end\n    end\n    assert_equal([1, 2, 'III', 4, 1, 2, 'III', 4, 'five', 6], ary)\n  end\n\n  def test_05_break\n    ary = []\n    @there.each do |x|\n      ary.push x\n      break if x == 4\n    end\n    assert_equal([1, 2, 'III', 4], ary)\n  end\n\n  def test_06_next\n    ary = []\n    @there.each do |x|\n      next if String === x\n      ary.push x\n    end\n    assert_equal([1, 2, 4, 6], ary)\n  end\n\n  class_eval <<EOS\n  def test_07_break_18\n    ary = []\n    result = @there.each do |x|\n      ary.push x\n      break(:done) if x == 4\n    end\n    assert_equal([1, 2, 'III', 4], ary)\n    assert_equal(:done, result)\n  end\nEOS\n\nend\n"
  },
  {
    "path": "test/drb/ignore_test_drb.rb",
    "content": "require 'drbtest'\n\nclass TestDRbReusePort < Test::Unit::TestCase\n  include DRbAry\n\n  def setup\n    @ext = DRbService.ext_service('ut_port.rb')\n    @there = @ext.front\n  end\n\n  def teardown\n    return unless @ext\n    @ext.stop_service\n    while true\n      sleep 0.1\n      begin\n        @ext.alive?\n      rescue DRb::DRbConnError\n        break\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "test/drb/test_acl.rb",
    "content": "# acltest.rb - ACL unit test\n# Copyright (c) 2000 Masatoshi SEKI\n#\n# acltest.rb is copyrighted free software by Masatoshi SEKI.\n# You can redistribute it and/or modify it under the same terms as Ruby.\n\nrequire 'test/unit'\nrequire 'drb/acl'\n\nclass SampleHosts\n  def initialize\n    list = %w(127.0.0.1 localhost\n              192.168.1.1 x68k.linux.or.jp\n              192.168.1.2 lc630.macos.or.jp\n              192.168.1.3 lib30.win32.or.jp\n              192.168.1.4 ns00.linux.or.jp\n              192.168.1.5 yum.macos.or.jp\n              ::ffff:192.168.1.5 ipv6.macos.or.jp\n              ::192.168.1.5 too.yumipv6.macos.or.jp\n              192.168.1.254 comstarz.foo.or.jp)\n\n    @hostlist = Array.new(list.size / 2)\n    @hostlist.each_index do |idx|\n      @hostlist[idx] = [\"AF_INET\", 10000, list[idx * 2 + 1], list[idx * 2]]\n    end\n\n    @hosts = Hash.new\n    @hostlist.each do |h|\n      @hosts[h[2].split('.')[0]] = h\n    end\n  end\n  attr_reader(:hostlist, :hosts)\nend\n\n\nclass ACLEntryTest < Test::Unit::TestCase\n  HOSTS = SampleHosts.new\n\n  def setup\n    @hostlist = HOSTS.hostlist\n    @hosts = HOSTS.hosts\n  end\n\n  def test_all\n    a = ACL::ACLEntry.new(\"*\")\n    b = ACL::ACLEntry.new(\"all\")\n    @hostlist.each do |h|\n      assert(a.match(h))\n      assert(b.match(h))\n    end\n  end\n\n  def test_ip_v6\n    a = ACL::ACLEntry.new('::ffff:192.0.0.0/104')\n    assert(! a.match(@hosts['localhost']))\n    assert(a.match(@hosts['yum']))\n    assert(a.match(@hosts['ipv6']))\n    assert(! a.match(@hosts['too']))\n  end\n\n  def test_ip\n    a = ACL::ACLEntry.new('192.0.0.0/8')\n    assert(! a.match(@hosts['localhost']))\n    assert(a.match(@hosts['yum']))\n\n    a = ACL::ACLEntry.new('192.168.0.1/255.255.0.255')\n    assert(! a.match(@hosts['localhost']))\n    assert(! a.match(@hosts['yum']))\n    assert(a.match(@hosts['x68k']))\n\n    a = ACL::ACLEntry.new('192.168.1.0/24')\n    assert(! a.match(@hosts['localhost']))\n    assert(a.match(@hosts['yum']))\n    assert(a.match(@hosts['x68k']))\n\n    a = ACL::ACLEntry.new('92.0.0.0/8')\n    assert(! a.match(@hosts['localhost']))\n    assert(! a.match(@hosts['yum']))\n    assert(! a.match(@hosts['x68k']))\n\n    a = ACL::ACLEntry.new('127.0.0.1/255.0.0.255')\n    assert(a.match(@hosts['localhost']))\n    assert(! a.match(@hosts['yum']))\n    assert(! a.match(@hosts['x68k']))\n  end\n\n  def test_name\n    a = ACL::ACLEntry.new('*.jp')\n    assert(! a.match(@hosts['localhost']))\n    assert(a.match(@hosts['yum']))\n\n    a = ACL::ACLEntry.new('yum.*.jp')\n    assert(a.match(@hosts['yum']))\n    assert(! a.match(@hosts['lc630']))\n\n    a = ACL::ACLEntry.new('*.macos.or.jp')\n    assert(a.match(@hosts['yum']))\n    assert(a.match(@hosts['lc630']))\n    assert(! a.match(@hosts['lib30']))\n  end\nend\n\nclass ACLListTest < Test::Unit::TestCase\n  HOSTS = SampleHosts.new\n\n  def setup\n    @hostlist = HOSTS.hostlist\n    @hosts = HOSTS.hosts\n  end\n\n  private\n  def build(list)\n    acl= ACL::ACLList.new\n    list.each do |s|\n      acl.add s\n    end\n    acl\n  end\n\n  public\n  def test_all_1\n    a = build(%w(all))\n    @hostlist.each do |h|\n      assert(a.match(h))\n    end\n  end\n\n  def test_all_2\n    a = build(%w(localhost 127.0.0.0/8 yum.* *))\n    @hostlist.each do |h|\n      assert(a.match(h))\n    end\n  end\n\n  def test_1\n    a = build(%w(192.0.0.1/255.0.0.255 yum.*.jp))\n    assert(a.match(@hosts['yum']))\n    assert(a.match(@hosts['x68k']))\n    assert(! a.match(@hosts['lc630']))\n  end\n\n  def test_2\n    a = build(%w(*.linux.or.jp))\n    assert(!a.match(@hosts['yum']))\n    assert(a.match(@hosts['x68k']))\n    assert(!a.match(@hosts['lc630']))\n  end\nend\n\nclass ACLTest < Test::Unit::TestCase\n  HOSTS = SampleHosts.new\n\n  def setup\n    @hostlist = HOSTS.hostlist\n    @hosts = HOSTS.hosts\n  end\n\n  def test_0\n    a = ACL.new\n    @hostlist.each do |h|\n      assert(a.allow_addr?(h))\n    end\n  end\n\n  def test_not_0\n    a = ACL.new([], ACL::ALLOW_DENY)\n    @hostlist.each do |h|\n      assert(! a.allow_addr?(h))\n    end\n  end\n\n  def test_1\n    data = %w(deny all\n              allow localhost\n              allow x68k.*)\n\n    a = ACL.new(data)\n    assert(a.allow_addr?(@hosts['x68k']))\n    assert(a.allow_addr?(@hosts['localhost']))\n    assert(! a.allow_addr?(@hosts['lc630']))\n  end\n\n  def test_not_1\n    data = %w(deny 192.0.0.0/8\n              allow localhost\n              allow x68k.*)\n\n    a = ACL.new(data, ACL::ALLOW_DENY)\n    assert(!a.allow_addr?(@hosts['x68k']))\n    assert(a.allow_addr?(@hosts['localhost']))\n    assert(! a.allow_addr?(@hosts['lc630']))\n  end\nend\n\n  \n"
  },
  {
    "path": "test/drb/test_drb.rb",
    "content": "require 'drbtest'\n\nclass TestDRbCore < Test::Unit::TestCase\n  include DRbCore\nend\n\nclass TestDRbYield < Test::Unit::TestCase\n  def setup\n    @ext = DRbService.ext_service('ut_drb.rb')\n    @there = @ext.front\n  end\n\n  def teardown\n    @ext.stop_service if @ext\n  end\n\n  def test_01_one\n    @there.echo_yield_1([]) {|one|\n      assert_equal([], one)\n    }\n    \n    @there.echo_yield_1(1) {|one|\n      assert_equal(1, one)\n    }\n    \n    @there.echo_yield_1(nil) {|one|\n      assert_equal(nil, one)\n    }\n  end\n\n  def test_02_two\n    @there.echo_yield_2([], []) {|one, two|\n      assert_equal([], one)\n      assert_equal([], two)\n    }\n\n    @there.echo_yield_2(1, 2) {|one, two|\n      assert_equal(1, one)\n      assert_equal(2, two)\n    }\n\n    @there.echo_yield_2(3, nil) {|one, two|\n      assert_equal(3, one)\n      assert_equal(nil, two)\n    }\n\n    @there.echo_yield_1([:key, :value]) {|one, two|\n      assert_equal(:key, one)\n      assert_equal(:value, two)\n    }\n  end\n\n  def test_03_many\n    @there.echo_yield_0 {|*s|\n      assert_equal([], s)\n    }\n    @there.echo_yield(nil) {|*s|\n      assert_equal([nil], s)\n    }\n    @there.echo_yield(1) {|*s|\n      assert_equal([1], s)\n    }\n    @there.echo_yield(1, 2) {|*s|\n      assert_equal([1, 2], s)\n    }\n    @there.echo_yield(1, 2, 3) {|*s|\n      assert_equal([1, 2, 3], s)\n    }\n    @there.echo_yield([], []) {|*s|\n      assert_equal([[], []], s)\n    }\n    @there.echo_yield([]) {|*s|\n      assert_equal([[]], s) # !\n    }\n  end\n\n  def test_04_many_to_one\n    @there.echo_yield_0 {|*s|\n      assert_equal([], s)\n    }\n    @there.echo_yield(nil) {|*s|\n      assert_equal([nil], s)\n    }\n    @there.echo_yield(1) {|*s|\n      assert_equal([1], s)\n    }\n    @there.echo_yield(1, 2) {|*s|\n      assert_equal([1, 2], s)\n    }\n    @there.echo_yield(1, 2, 3) {|*s|\n      assert_equal([1, 2, 3], s)\n    }\n    @there.echo_yield([], []) {|*s|\n      assert_equal([[], []], s)\n    }\n    @there.echo_yield([]) {|*s|\n      assert_equal([[]], s)\n    }\n  end\n\n  def test_05_array_subclass\n    @there.xarray_each {|x| assert_kind_of(XArray, x)}\n    @there.xarray_each {|*x| assert_kind_of(XArray, x[0])}\n  end\n\n  def test_06_taint\n    x = proc {}\n    assert(! x.tainted?)\n    @there.echo_yield(x) {|o|\n      assert_equal(x, o)\n      assert(! x.tainted?)\n    }\n  end\nend\n\nclass TestRubyYield < TestDRbYield\n  def echo_yield(*arg)\n    yield(*arg)\n  end\n\n  def echo_yield_0\n    yield\n  end\n\n  def echo_yield_1(a)\n    yield(a)\n  end\n\n  def echo_yield_2(a, b)\n    yield(a, b)\n  end\n\n  def xarray_each\n    xary = [XArray.new([0])]\n    xary.each do |x|\n      yield(x)\n    end\n  end\n\n  def setup\n    @there = self\n  end\n  \n  def teardown\n  end\nend\n\nclass TestRuby18Yield < TestRubyYield\n  class YieldTest18\n    def echo_yield(*arg, &proc)\n      proc.call(*arg)\n    end\n    \n    def echo_yield_0(&proc)\n      proc.call\n    end\n    \n    def echo_yield_1(a, &proc)\n      proc.call(a)\n    end\n    \n    def echo_yield_2(a, b, &proc)\n      proc.call(a, b)\n    end\n\n    def xarray_each(&proc)\n      xary = [XArray.new([0])]\n      xary.each(&proc)\n    end\n\n  end\n\n  def setup\n    @there = YieldTest18.new\n  end\nend\n\nclass TestDRbAry < Test::Unit::TestCase\n  include DRbAry\nend\n\nclass TestDRbMServer < Test::Unit::TestCase\n  def setup\n    @ext = DRbService.ext_service('ut_drb.rb')\n    @there = @ext.front\n    @server = (1..3).collect do |n|\n      DRb::DRbServer.new(nil, Onecky.new(n.to_s))\n    end\n  end\n\n  def teardown\n    @server.each do |s|\n      s.stop_service\n    end\n    @ext.stop_service if @ext\n  end\n\n  def test_01\n    assert_equal(6, @there.sample(@server[0].front, @server[1].front, @server[2].front))\n  end\nend\n\nclass TestDRbSafe1 < TestDRbAry\n  def setup\n    @ext = DRbService.ext_service('ut_safe1.rb')\n    @there = @ext.front\n  end\nend\n\nclass TestDRbEval < Test::Unit::TestCase\n  def setup\n    super\n    @ext = DRbService.ext_service('ut_eval.rb')\n    @there = @ext.front\n  end\n\n  def teardown\n    @ext.stop_service if @ext\n  end\n  \n  def test_01_safe1_safe4_eval\n    assert_raises(SecurityError) do\n      @there.method_missing(:instance_eval, 'ENV.inspect')\n    end\n\n    assert_raises(SecurityError) do\n      @there.method_missing(:send, :eval, 'ENV.inspect')\n    end\n\n    remote_class = @there.remote_class\n\n    assert_raises(SecurityError) do\n      remote_class.class_eval('ENV.inspect')\n    end\n\n    assert_raises(SecurityError) do\n      remote_class.module_eval('ENV.inspect')\n    end\n\n    four = @there.four\n    assert_equal(1, four.method_missing(:send, :eval, '1'))\n    \n    remote_class = four.remote_class\n\n    assert_equal(1, remote_class.class_eval('1'))\n\n    assert_equal(1, remote_class.module_eval('1'))\n\n    assert_raises(SecurityError) do\n      remote_class.class_eval('ENV = {}')\n    end\n\n    assert_raises(SecurityError) do\n      remote_class.module_eval('ENV = {}')\n    end\n  end\nend\n\nclass TestDRbLarge < Test::Unit::TestCase\n  def setup\n    @ext = DRbService.ext_service('ut_large.rb')\n    @there = @ext.front\n  end\n\n  def teardown\n    @ext.stop_service if @ext\n  end\n\n  def test_01_large_ary\n    ary = [2] * 10240\n    assert_equal(10240, @there.size(ary))\n    assert_equal(20480, @there.sum(ary))\n  end\n\n  def test_02_large_ary\n    ary = [\"Hello, World\"] * 10240\n    assert_equal(10240, @there.size(ary))\n  end\n\n  def test_03_large_ary\n    ary = [Thread.current] * 10240\n    assert_equal(10240, @there.size(ary))\n  end\n\n  def test_04_many_arg\n    assert_raises(ArgumentError) {\n      @there.arg_test(1, 2, 3, 4, 5, 6, 7, 8, 9, 0)\n    }\n  end\n\n  def test_05_too_large_ary\n    ary = [\"Hello, World\"] * 102400\n    exception = nil\n    begin\n      @there.size(ary)      \n    rescue StandardError\n      exception = $!\n    end\n    assert_kind_of(StandardError, exception)\n  end\nend\n"
  },
  {
    "path": "test/drb/test_drbssl.rb",
    "content": "require 'drbtest'\n\nbegin\n  require 'drb/ssl'\nrescue LoadError\nend\n\nif Object.const_defined?(\"OpenSSL\")\n\n\nclass DRbSSLService < DRbService\n  %w(ut_drb_drbssl.rb ut_array_drbssl.rb).each do |nm|\n    add_service_command(nm)\n  end\n  config = Hash.new\n\n  config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER\n  config[:SSLVerifyCallback] = lambda{ |ok,x509_store|\n    true\n  }\n  begin\n    data = open(\"sample.key\"){|io| io.read }\n    config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)\n    data = open(\"sample.crt\"){|io| io.read }\n    config[:SSLCertificate] = OpenSSL::X509::Certificate.new(data)\n  rescue\n    # $stderr.puts \"Switching to use self-signed certificate\"\n    config[:SSLCertName] =\n      [ [\"C\",\"JP\"], [\"O\",\"Foo.DRuby.Org\"], [\"CN\", \"Sample\"] ]\n  end\n\n  uri = ARGV.shift if $0 == __FILE__\n  @server = DRb::DRbServer.new(uri || 'drbssl://:0', self.manager, config)\nend\n\nclass TestDRbSSLCore < Test::Unit::TestCase\n  include DRbCore\n  def setup\n    @ext = DRbSSLService.ext_service('ut_drb_drbssl.rb')\n    @there = @ext.front\n  end\n\n  def test_02_unknown\n  end\n\n  def test_01_02_loop\n  end\n\n  def test_05_eq\n  end\nend\n\nclass TestDRbSSLAry < Test::Unit::TestCase\n  include DRbAry\n  def setup\n    @ext = DRbSSLService.ext_service('ut_array_drbssl.rb')\n    @there = @ext.front\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/drb/test_drbunix.rb",
    "content": "require 'drbtest'\n\nbegin\n  require 'drb/unix'\nrescue LoadError\nend\n\nif Object.const_defined?(\"UNIXServer\")\n\n\nclass DRbUNIXService < DRbService\n  %w(ut_drb_drbunix.rb ut_array_drbunix.rb).each do |nm|\n    add_service_command(nm)\n  end\n\n  uri = ARGV.shift if $0 == __FILE__\n  @server = DRb::DRbServer.new(uri || 'drbunix:', self.manager, {})\nend\n\nclass TestDRbUNIXCore < Test::Unit::TestCase\n  include DRbCore\n  def setup\n    @ext = DRbUNIXService.ext_service('ut_drb_drbunix.rb')\n    @there = @ext.front\n  end\n\n  def test_02_unknown\n  end\n\n  def test_01_02_loop\n  end\n\n  def test_05_eq\n  end\nend\n\nclass TestDRbUNIXAry < Test::Unit::TestCase\n  include DRbAry\n  def setup\n    @ext = DRbUNIXService.ext_service('ut_array_drbunix.rb')\n    @there = @ext.front\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/drb/ut_array.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <uri> <name>\" unless it\n    it\n  end\n\n  DRb.start_service(nil, [1, 2, 'III', 4, \"five\", 6])\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "test/drb/ut_array_drbssl.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\nrequire 'drb/ssl'\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <uri> <name>\" unless it\n    it\n  end\n\n  config = Hash.new\n  config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER\n  config[:SSLVerifyCallback] = lambda{|ok,x509_store|\n    true\n  }\n  config[:SSLCertName] =\n    [ [\"C\",\"JP\"], [\"O\",\"Foo.DRuby.Org\"], [\"CN\", \"Sample\"] ]\n\n  DRb.start_service('drbssl://:0', [1, 2, 'III', 4, \"five\", 6], config)\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "test/drb/ut_array_drbunix.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <uri> <name>\" unless it\n    it\n  end\n\n  DRb.start_service('drbunix:', [1, 2, 'III', 4, \"five\", 6])\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "test/drb/ut_drb.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\nrequire 'timeout'\n\nclass XArray < Array\n  def initialize(ary)\n    ary.each do |x|\n      self.push(x)\n    end\n  end\nend\n\nclass XArray2 < XArray\n  include DRbUndumped\nend\n\nclass Unknown2\n  def initialize\n    @foo = 'unknown2'\n  end\nend\n\nclass DRbEx\n  include DRbUndumped\n\n  class FooBar\n    def initialize\n      @foo = 'bar'\n    end\n  end\n\n  class UError < RuntimeError; end\n\n  def initialize\n    @hello = 'hello'\n  end\n  attr_reader :hello\n\n  def sample(a, b, c)\n    a.to_i + b.to_i + c.to_i\n  end\n\n  def sum(*a)\n    s = 0\n    a.each do |e|\n      s += e.to_i\n    end\n    s\n  end\n\n  def do_timeout(n)\n    timeout(0.1) do\n      n.sleep(2)\n    end\n  end\n\n  def unknown_module\n    FooBar.new\n  end\n\n  def unknown_class\n    Unknown2.new\n  end\n\n  def unknown_error\n    raise UError\n  end\n\n  def remote_no_method_error\n    invoke_no_method(self)\n  end\n\n  def test_yield\n    yield\n    yield([])\n    yield(*[])\n  end\n\n  def echo_yield(*arg)\n    yield(*arg)\n    nil\n  end\n\n  def echo_yield_0\n    yield\n    nil\n  end\n\n  def echo_yield_1(one)\n    yield(one)\n    nil\n  end\n\n  def echo_yield_2(one, two)\n    yield(one, two)\n    nil\n  end\n\n  def xarray_each\n    xary = [XArray.new([0])]\n    xary.each do |x|\n      yield(x)\n    end\n    nil\n  end\n\n  def xarray2_hash\n    unless @xary2_hash\n      @xary2_hash = { \"a\" => XArray2.new([0]), \"b\" => XArray2.new([1]) }\n    end\n    DRbObject.new(@xary2_hash)\n  end\n\n  def simple_hash\n    unless @hash\n      @hash = { 'a'=>:a, 'b'=>:b }\n    end\n    DRbObject.new(@hash)\n  end\n\n  def [](key)\n    key.to_s\n  end\n\n  def to_a\n    [self]\n  end\n\n  def method_missing(msg, *a, &b)\n    if msg == :missing\n      return true\n    else\n      super(msg, *a, &b)\n    end\n  end\n\n  private\n  def call_private_method\n    true\n  end\n\n  protected\n  def call_protected_method\n    true\n  end\nend\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <manager-uri> <name>\" unless it\n    it\n  end\n\n  DRb::DRbServer.default_argc_limit(8)\n  DRb::DRbServer.default_load_limit(4096)\n  DRb.start_service('druby://localhost:0', DRbEx.new)\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n"
  },
  {
    "path": "test/drb/ut_drb_drbssl.rb",
    "content": "require \"#{File.dirname(File.expand_path(__FILE__))}/ut_drb\"\nrequire 'drb/ssl'\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <manager-uri> <name>\" unless it\n    it\n  end\n\n  config = Hash.new\n  config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER\n  config[:SSLVerifyCallback] = lambda{|ok,x509_store|\n    true\n  }\n  config[:SSLCertName] =\n    [ [\"C\",\"JP\"], [\"O\",\"Foo.DRuby.Org\"], [\"CN\", \"Sample\"] ]\n\n  DRb::DRbServer.default_argc_limit(8)\n  DRb::DRbServer.default_load_limit(4096)\n  DRb.start_service('drbssl://localhost:0', DRbEx.new, config)\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "test/drb/ut_drb_drbunix.rb",
    "content": "require \"#{File.dirname(File.expand_path(__FILE__))}/ut_drb\"\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <manager-uri> <name>\" unless it\n    it\n  end\n\n  DRb::DRbServer.default_argc_limit(8)\n  DRb::DRbServer.default_load_limit(4096)\n  DRb.start_service('drbunix:', DRbEx.new)\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "test/drb/ut_eval.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\n\nclass EvalAttack\n  def initialize\n    @four = DRb::DRbServer.new('druby://localhost:0', self, {:safe_level => 4})\n  end\n\n  def four\n    DRbObject.new_with_uri(@four.uri)\n  end\n\n  def remote_class\n    DRbObject.new(self.class)\n  end\nend\n\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <uri> <name>\" unless it\n    it\n  end\n\n  $SAFE = 1\n\n  DRb.start_service('druby://localhost:0', EvalAttack.new, {:safe_level => 2})\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n"
  },
  {
    "path": "test/drb/ut_large.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\nrequire 'timeout'\n\nclass DRbLarge\n  include DRbUndumped\n\n  def size(ary)\n    ary.size \n  end\n\n  def sum(ary)\n    sum = 0\n    ary.each do |e|\n      sum += e.to_i\n    end\n    sum\n  end\n\n  def arg_test(*arg)\n    # nop\n  end\nend\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <manager-uri> <name>\" unless it\n    it\n  end\n\n  DRb::DRbServer.default_argc_limit(3)\n  DRb::DRbServer.default_load_limit(100000)\n  DRb.start_service('druby://localhost:0', DRbLarge.new)\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n\n"
  },
  {
    "path": "test/drb/ut_port.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <uri> <name>\" unless it\n    it\n  end\n\n  DRb.start_service('druby://:8473', [1, 2, 'III', 4, \"five\", 6])\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n"
  },
  {
    "path": "test/drb/ut_safe1.rb",
    "content": "require 'drb/drb'\nrequire 'drb/extserv'\n\nif __FILE__ == $0\n  def ARGV.shift\n    it = super()\n    raise \"usage: #{$0} <uri> <name>\" unless it\n    it\n  end\n\n  DRb.start_service('druby://localhost:0', [1, 2, 'III', 4, \"five\", 6], \n                    {:safe_level => 1})\n  es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)\n  DRb.thread.join\nend\n"
  },
  {
    "path": "test/drb/ut_timerholder.rb",
    "content": "require 'runit/testcase'\nrequire 'runit/cui/testrunner'\nrequire 'timerholder'\n\nclass TimerHolderTest < RUNIT::TestCase\n  def do_test(timeout, keeper_sleep = nil)\n    holder = TimerHolder.new(timeout)\n    holder.keeper_sleep = keeper_sleep if keeper_sleep\n    key = holder.add(self)\n    sleep(timeout * 0.5)\n    assert_equal(holder.peek(key), self)\n    holder.delete(key)\n    assert(!holder.include?(key))\n    key = holder.add(self)\n    sleep(timeout+0.5)\n    assert_equal(holder.fetch(key), nil)\n    key = holder.add(self)\n    assert_equal(holder.fetch(key), self)\n    holder.store(key, true)\n    assert_equal(holder.fetch(key), true)\n    assert_equal(holder.include?(key), true)\n    sleep(timeout+0.5)\n    assert_exception(TimerHolder::InvalidIndexError) do\n      holder.store(key, 1)\n    end\n    assert_equal(holder.include?(key), false)\n    key = holder.add(self)\n    sleep(timeout * 0.5)\n    assert(holder.include?(key))\n    holder.extend(key, timeout)\n    sleep(timeout * 0.5)\n    assert(holder.include?(key))\n    sleep(timeout * 0.6)\n    assert(!holder.include?(key))\n    holder.delete(key)\n  end\n  \n  def test_00\n    do_test(0.5)\n  end\n\n  def test_01\n    do_test(1, 0.5)\n  end\nend\n\nif __FILE__ == $0\n  RUNIT::CUI::TestRunner.run(TimerHolderTest.suite)\nend\n"
  },
  {
    "path": "test/erb/hello.erb",
    "content": "= hello\n<% 3.times do |n| %>\n* <%= n %>\n<% end %>\n"
  },
  {
    "path": "test/erb/test_erb.rb",
    "content": "require 'test/unit'\nrequire 'erb'\n\nclass TestERB < Test::Unit::TestCase\n  class MyError < RuntimeError ; end\n\n  def test_without_filename\n    erb = ERB.new(\"<% raise ::TestERB::MyError %>\")\n    e = assert_raise(MyError) {\n      erb.result\n    }\n    assert_equal(\"(erb):1\", e.backtrace[0])\n  end\n\n  def test_with_filename\n    erb = ERB.new(\"<% raise ::TestERB::MyError %>\")\n    erb.filename = \"test filename\"\n    e = assert_raise(MyError) {\n      erb.result\n    }\n    assert_equal(\"test filename:1\", e.backtrace[0])\n  end\n\n  def test_without_filename_with_safe_level\n    erb = ERB.new(\"<% raise ::TestERB::MyError %>\", 1)\n    e = assert_raise(MyError) {\n      erb.result\n    }\n    assert_equal(\"(erb):1\", e.backtrace[0])\n  end\n\n  def test_with_filename_and_safe_level\n    erb = ERB.new(\"<% raise ::TestERB::MyError %>\", 1)\n    erb.filename = \"test filename\"\n    e = assert_raise(MyError) {\n      erb.result\n    }\n    assert_equal(\"test filename:1\", e.backtrace[0])\n  end\nend\n\nclass TestERBCore < Test::Unit::TestCase\n  def setup\n    @erb = ERB\n  end\n\n  def test_core\n    _test_core(nil)\n    _test_core(0)\n    _test_core(1)\n    _test_core(2)\n    _test_core(3)\n  end\n\n  def _test_core(safe)\n    erb = @erb.new(\"hello\")\n    assert_equal(\"hello\", erb.result)\n\n    erb = @erb.new(\"hello\", safe, 0)\n    assert_equal(\"hello\", erb.result)\n\n    erb = @erb.new(\"hello\", safe, 1)\n    assert_equal(\"hello\", erb.result)\n\n    erb = @erb.new(\"hello\", safe, 2)\n    assert_equal(\"hello\", erb.result)\n\n    src = <<EOS\n%% hi\n= hello\n<% 3.times do |n| %>\n% n=0\n* <%= n %>\n<% end %>\nEOS\n      \n    ans = <<EOS\n%% hi\n= hello\n\n% n=0\n* 0\n\n% n=0\n* 1\n\n% n=0\n* 2\n\nEOS\n    erb = @erb.new(src)\n    assert_equal(ans, erb.result)\n    erb = @erb.new(src, safe, 0)\n    assert_equal(ans, erb.result)\n    erb = @erb.new(src, safe, '')\n    assert_equal(ans, erb.result)\n\n    ans = <<EOS\n%% hi\n= hello\n% n=0\n* 0% n=0\n* 1% n=0\n* 2\nEOS\n    erb = @erb.new(src, safe, 1)\n    assert_equal(ans.chomp, erb.result)\n    erb = @erb.new(src, safe, '>')\n    assert_equal(ans.chomp, erb.result)\n\n    ans  = <<EOS\n%% hi\n= hello\n% n=0\n* 0\n% n=0\n* 1\n% n=0\n* 2\nEOS\n      \n    erb = @erb.new(src, safe, 2)\n    assert_equal(ans, erb.result)\n    erb = @erb.new(src, safe, '<>')\n    assert_equal(ans, erb.result)\n\n    ans = <<EOS\n% hi\n= hello\n\n* 0\n\n* 0\n\n* 0\n\nEOS\n    erb = @erb.new(src, safe, '%')\n    assert_equal(ans, erb.result)\n\n    ans = <<EOS\n% hi\n= hello\n* 0* 0* 0\nEOS\n    erb = @erb.new(src, safe, '%>')\n    assert_equal(ans.chomp, erb.result)\n\n    ans = <<EOS\n% hi\n= hello\n* 0\n* 0\n* 0\nEOS\n    erb = @erb.new(src, safe, '%<>')\n    assert_equal(ans, erb.result)\n  end\n\n  def test_safe_04\n    erb = @erb.new('<%=$SAFE%>', 4)\n    assert_equal('4', erb.result(TOPLEVEL_BINDING.taint))\n  end\n\n  class Foo; end\n\n  def test_def_class\n    erb = @erb.new('hello')\n    cls = erb.def_class\n    assert_equal(Object, cls.superclass)\n    assert(cls.new.respond_to?('result'))\n    cls = erb.def_class(Foo)\n    assert_equal(Foo, cls.superclass)\n    assert(cls.new.respond_to?('result'))\n    cls = erb.def_class(Object, 'erb')\n    assert_equal(Object, cls.superclass)\n    assert(cls.new.respond_to?('erb'))\n  end\n\n  def test_percent\n    src = <<EOS\n%n = 1\n<%= n%>\nEOS\n    assert_equal(\"1\\n\", ERB.new(src, nil, '%').result)\n\n    src = <<EOS\n<%\n%>\nEOS\n    ans = \"\\n\"\n    assert_equal(ans, ERB.new(src, nil, '%').result)\n\n    src = \"<%\\n%>\"\n    # ans = \"\\n\"\n    ans = \"\"\n    assert_equal(ans, ERB.new(src, nil, '%').result)\n\n    src = <<EOS\n<%\nn = 1\n%><%= n%>\nEOS\n    assert_equal(\"1\\n\", ERB.new(src, nil, '%').result)\n\n    src = <<EOS\n%n = 1\n%% <% n = 2\nn.times do |i|%>\n%% %%><%%<%= i%><%\nend%>\n%%%\nEOS\n    ans = <<EOS\n% \n% %%><%0\n% %%><%1\n%%\nEOS\n    assert_equal(ans, ERB.new(src, nil, '%').result)\n  end\n\n  def test_def_method\n    klass = Class.new\n    klass.module_eval do\n      extend ERB::DefMethod\n      fname = File.join(File.dirname(File.expand_path(__FILE__)), 'hello.erb')\n      def_erb_method('hello', fname)\n    end\n    assert(klass.new.respond_to?('hello'))\n\n    assert(! klass.new.respond_to?('hello_world'))\n    erb = @erb.new('hello, world')\n    klass.module_eval do\n      def_erb_method('hello_world', erb)\n    end\n    assert(klass.new.respond_to?('hello_world'))    \n  end\n\n  def test_escape\n    src = <<EOS\n1.<%% : <%=\"<%%\"%>\n2.%%> : <%=\"%%>\"%>\n3.\n% x = \"foo\"\n<%=x%>\n4.\n%% print \"foo\"\n5.\n%% <%=\"foo\"%>\n6.<%=\"\n% print 'foo'\n\"%>\n7.<%=\"\n%% print 'foo'\n\"%>\nEOS\n    ans = <<EOS\n1.<% : <%%\n2.%%> : %>\n3.\nfoo\n4.\n% print \"foo\"\n5.\n% foo\n6.\n% print 'foo'\n\n7.\n%% print 'foo'\n\nEOS\n    assert_equal(ans, ERB.new(src, nil, '%').result)\n  end\n\n  def test_keep_lineno\n    src = <<EOS\nHello, \n% x = \"World\"\n<%= x%>\n% raise(\"lineno\")\nEOS\n\n    erb = ERB.new(src, nil, '%')\n    begin\n      erb.result\n      assert(false)\n    rescue\n      assert_equal(\"(erb):4\", $@[0].to_s)\n    end\n\n    src = <<EOS\n%>\nHello, \n<% x = \"World%%>\n\"%>\n<%= x%>\nEOS\n\n    ans = <<EOS\n%>Hello, \nWorld%>\nEOS\n    assert_equal(ans, ERB.new(src, nil, '>').result)\n\n    ans = <<EOS\n%>\nHello, \n\nWorld%>\nEOS\n    assert_equal(ans, ERB.new(src, nil, '<>').result)\n\n    ans = <<EOS\n%>\nHello, \n\nWorld%>\n\nEOS\n    assert_equal(ans, ERB.new(src).result)\n\n    src = <<EOS\nHello, \n<% x = \"World%%>\n\"%>\n<%= x%>\n<% raise(\"lineno\") %>\nEOS\n\n    erb = ERB.new(src)\n    begin\n      erb.result\n      assert(false)\n    rescue\n      assert_equal(\"(erb):5\", $@[0].to_s)\n    end\n\n    erb = ERB.new(src, nil, '>')\n    begin\n      erb.result\n      assert(false)\n    rescue\n      assert_equal(\"(erb):5\", $@[0].to_s)\n    end\n\n    erb = ERB.new(src, nil, '<>')\n    begin\n      erb.result\n      assert(false)\n    rescue\n      assert_equal(\"(erb):5\", $@[0].to_s)\n    end\n\n    src = <<EOS\n% y = 'Hello'\n<%- x = \"World%%>\n\"-%>\n<%= x %><%- x = nil -%> \n<% raise(\"lineno\") %>\nEOS\n\n    erb = ERB.new(src, nil, '-')\n    begin\n      erb.result\n      assert(false)\n    rescue\n      assert_equal(\"(erb):5\", $@[0].to_s)\n    end\n\n    erb = ERB.new(src, nil, '%-')\n    begin\n      erb.result\n      assert(false)\n    rescue\n      assert_equal(\"(erb):5\", $@[0].to_s)\n    end\n  end\n\n  def test_explicit\n    src = <<EOS\n<% x = %w(hello world) -%>\nNotSkip <%- y = x -%> NotSkip\n<% x.each do |w| -%>\n  <%- up = w.upcase -%>\n  * <%= up %>\n<% end -%>\n <%- z = nil -%> NotSkip <%- z = x %>\n <%- z.each do |w| -%>\n   <%- down = w.downcase -%>\n   * <%= down %>\n   <%- up = w.upcase -%>\n   * <%= up %>\n <%- end -%>\nKeepNewLine <%- z = nil -%> \nEOS\n\n   ans = <<EOS\nNotSkip  NotSkip\n  * HELLO\n  * WORLD\n NotSkip \n   * hello\n   * HELLO\n   * world\n   * WORLD\nKeepNewLine  \nEOS\n   assert_equal(ans, ERB.new(src, nil, '-').result)\n   assert_equal(ans, ERB.new(src, nil, '-%').result)\n  end\n\n  def test_percent_after_etag\n    assert_equal(\"1%\", @erb.new(\"<%= 1 %>%\", nil, \"%\").result)\n  end\nend\n\nclass TestERBCoreWOStrScan < TestERBCore\n  def setup\n    @save_map = ERB::Compiler::Scanner.instance_variable_get('@scanner_map')\n    map = {[nil, false]=>ERB::Compiler::SimpleScanner}\n    ERB::Compiler::Scanner.instance_variable_set('@scanner_map', map)\n    super\n  end\n\n  def teardown\n    ERB::Compiler::Scanner.instance_variable_set('@scanner_map', @save_map)\n  end\nend\n"
  },
  {
    "path": "test/fileutils/fileasserts.rb",
    "content": "# $Id$\n\nmodule Test\n  module Unit\n    module Assertions   # redefine\n\n      def assert_same_file(from, to)\n        _wrap_assertion {\n          assert_block(\"file #{from} != #{to}\") {\n            File.read(from) == File.read(to)\n          }\n        }\n      end\n\n      def assert_same_entry(from, to)\n        a = File.stat(from)\n        b = File.stat(to)\n        assert_equal a.mode, b.mode, \"mode #{a.mode} != #{b.mode}\"\n        #assert_equal a.atime, b.atime\n        assert_equal a.mtime, b.mtime, \"mtime #{a.mtime} != #{b.mtime}\"\n        assert_equal a.uid, b.uid, \"uid #{a.uid} != #{b.uid}\"\n        assert_equal a.gid, b.gid, \"gid #{a.gid} != #{b.gid}\"\n      end\n\n      def assert_file_exist(path)\n        _wrap_assertion {\n          assert_block(\"file not exist: #{path}\") {\n            File.exist?(path)\n          }\n        }\n      end\n\n      def assert_file_not_exist(path)\n        _wrap_assertion {\n          assert_block(\"file not exist: #{path}\") {\n            not File.exist?(path)\n          }\n        }\n      end\n\n      def assert_directory(path)\n        _wrap_assertion {\n          assert_block(\"is not directory: #{path}\") {\n            File.directory?(path)\n          }\n        }\n      end\n\n      def assert_symlink(path)\n        _wrap_assertion {\n          assert_block(\"is not a symlink: #{path}\") {\n            File.symlink?(path)\n          }\n        }\n      end\n\n      def assert_not_symlink(path)\n        _wrap_assertion {\n          assert_block(\"is a symlink: #{path}\") {\n            not File.symlink?(path)\n          }\n        }\n      end\n\n    end\n  end\nend\n"
  },
  {
    "path": "test/fileutils/test_dryrun.rb",
    "content": "# $Id$\n\nrequire 'test/unit'\nrequire 'fileutils'\n\nclass TestFileUtilsDryRun < Test::Unit::TestCase\n\n  include FileUtils::DryRun\n\n  def test_visibility\n    FileUtils::METHODS.each do |m|\n      assert_equal true, FileUtils::DryRun.respond_to?(m, true),\n                   \"FileUtils::DryRun.#{m} not defined\"\n      assert_equal true, FileUtils::DryRun.respond_to?(m, false),\n                   \"FileUtils::DryRun.#{m} not public\"\n    end\n    FileUtils::METHODS.each do |m|\n      assert_equal true, respond_to?(m, true)\n                   \"FileUtils::DryRun\\##{m} is not defined\"\n      assert_equal true, FileUtils::DryRun.private_method_defined?(m),\n                   \"FileUtils::DryRun\\##{m} is not private\"\n    end\n  end\n\nend\n"
  },
  {
    "path": "test/fileutils/test_fileutils.rb",
    "content": "# $Id$\n\nrequire 'fileutils'\nrequire 'fileasserts'\nrequire 'pathname'\nrequire 'tmpdir'\nrequire 'test/unit'\n\nclass TestFileUtils < Test::Unit::TestCase\n  TMPROOT = \"#{Dir.tmpdir}/fileutils.rb.#{$$}\"\nend\n\nprevdir = Dir.pwd\ntmproot = TestFileUtils::TMPROOT\nDir.mkdir tmproot unless File.directory?(tmproot)\nDir.chdir tmproot\n\ndef have_drive_letter?\n  /djgpp|mswin(?!ce)|mingw|bcc|emx/ =~ RUBY_PLATFORM\nend\n\ndef have_file_perm?\n  /djgpp|mswin|mingw|bcc|wince|emx/ !~ RUBY_PLATFORM\nend\n\n$fileutils_rb_have_symlink = nil\n\ndef have_symlink?\n  if $fileutils_rb_have_symlink == nil\n    $fileutils_rb_have_symlink = check_have_symlink?\n  end\n  $fileutils_rb_have_symlink\nend\n\ndef check_have_symlink?\n  File.symlink nil, nil\nrescue NotImplementedError\n  return false\nrescue\n  return true\nend\n\n$fileutils_rb_have_hardlink = nil\n\ndef have_hardlink?\n  if $fileutils_rb_have_hardlink == nil\n    $fileutils_rb_have_hardlink = check_have_hardlink?\n  end\n  $fileutils_rb_have_hardlink\nend\n\ndef check_have_hardlink?\n  File.link nil, nil\nrescue NotImplementedError\n  return false\nrescue\n  return true\nend\n\nbegin\n  Dir.mkdir(\"\\n\")\n  Dir.rmdir(\"\\n\")\n  def lf_in_path_allowed?\n    true\n  end\nrescue\n  def lf_in_path_allowed?\n    false\n  end\nend\n\nDir.chdir prevdir\nDir.rmdir tmproot\n\nclass TestFileUtils\n\n  include FileUtils\n\n  def check_singleton(name)\n    assert_equal true, ::FileUtils.public_methods.include?(name.to_s)\n  end\n\n  def my_rm_rf(path)\n    if File.exist?('/bin/rm')\n      system %Q[/bin/rm -rf \"#{path}\"]\n    else\n      FileUtils.rm_rf path\n    end\n  end\n\n  def mymkdir(path)\n    Dir.mkdir path\n    File.chown nil, Process.gid, path if have_file_perm?\n  end\n\n  def setup\n    @prevdir = Dir.pwd\n    tmproot = TMPROOT\n    mymkdir tmproot unless File.directory?(tmproot)\n    Dir.chdir tmproot\n    my_rm_rf 'data'; mymkdir 'data'\n    my_rm_rf 'tmp';  mymkdir 'tmp'\n    prepare_data_file\n  end\n\n  def teardown\n    tmproot = Dir.pwd\n    Dir.chdir @prevdir\n    my_rm_rf tmproot\n  end\n\n\n  TARGETS = %w( data/a data/all data/random data/zero )\n\n  def prepare_data_file\n    File.open('data/a', 'w') {|f|\n      32.times do\n        f.puts 'a' * 50\n      end\n    }\n\n    all_chars = (0..255).map {|n| n.chr }.join('')\n    File.open('data/all', 'w') {|f|\n      32.times do\n        f.puts all_chars\n      end\n    }\n\n    random_chars = (0...50).map { rand(256).chr }.join('')\n    File.open('data/random', 'w') {|f|\n      32.times do\n        f.puts random_chars\n      end\n    }\n\n    File.open('data/zero', 'w') {|f|\n      ;\n    }\n  end\n\n  BIGFILE = 'data/big'\n\n  def prepare_big_file\n    File.open('data/big', 'w') {|f|\n      (4 * 1024 * 1024 / 256).times do   # 4MB\n        f.print \"aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa\\n\"\n      end\n    }\n  end\n\n  def prepare_time_data\n    File.open('data/old',    'w') {|f| f.puts 'dummy' }\n    File.open('data/newer',  'w') {|f| f.puts 'dummy' }\n    File.open('data/newest', 'w') {|f| f.puts 'dummy' }\n    t = Time.now\n    File.utime t-8, t-8, 'data/old'\n    File.utime t-4, t-4, 'data/newer'\n  end\n\n  def each_srcdest\n    TARGETS.each do |path|\n      yield path, \"tmp/#{File.basename(path)}\"\n    end\n  end\n\n  #\n  # Test Cases\n  #\n\n  def test_pwd\n    check_singleton :pwd\n\n    assert_equal Dir.pwd, pwd()\n\n    cwd = Dir.pwd\nif have_drive_letter?\n    cd('C:/') {\n      assert_equal 'C:/', pwd()\n    }\n    assert_equal cwd, pwd()\nelse\n    cd('/') {\n      assert_equal '/', pwd()\n    }\n    assert_equal cwd, pwd()\nend\n  end\n\n  def test_cmp\n    check_singleton :cmp\n\n    TARGETS.each do |fname|\n      assert cmp(fname, fname), 'not same?'\n    end\n    assert_raises(ArgumentError) {\n      cmp TARGETS[0], TARGETS[0], :undefinedoption => true\n    }\n\n    # pathname\n    touch 'tmp/cmptmp'\n    assert_nothing_raised {\n      cmp Pathname.new('tmp/cmptmp'), 'tmp/cmptmp'\n      cmp 'tmp/cmptmp', Pathname.new('tmp/cmptmp')\n      cmp Pathname.new('tmp/cmptmp'), Pathname.new('tmp/cmptmp')\n    }\n  end\n\n  def test_cp\n    check_singleton :cp\n\n    each_srcdest do |srcpath, destpath|\n      cp srcpath, destpath\n      assert_same_file srcpath, destpath\n\n      cp srcpath, File.dirname(destpath)\n      assert_same_file srcpath, destpath\n\n      cp srcpath, File.dirname(destpath) + '/'\n      assert_same_file srcpath, destpath\n\n      cp srcpath, destpath, :preserve => true\n      assert_same_file srcpath, destpath\n      assert_same_entry srcpath, destpath\n    end\n\n    # src==dest (1) same path\n    touch 'tmp/cptmp'\n    assert_raises(ArgumentError) {\n      cp 'tmp/cptmp', 'tmp/cptmp'\n    }\nif have_symlink?\n    # src==dest (2) symlink and its target\n    File.symlink 'cptmp', 'tmp/cptmp_symlink'\n    assert_raises(ArgumentError) {\n      cp 'tmp/cptmp', 'tmp/cptmp_symlink'\n    }\n    assert_raises(ArgumentError) {\n      cp 'tmp/cptmp_symlink', 'tmp/cptmp'\n    }\n    # src==dest (3) looped symlink\n    File.symlink 'symlink', 'tmp/symlink'\n    assert_raises(Errno::ELOOP) {\n      cp 'tmp/symlink', 'tmp/symlink'\n    }\nend\n\n    # pathname\n    assert_nothing_raised {\n      cp 'tmp/cptmp', Pathname.new('tmp/tmpdest')\n      cp Pathname.new('tmp/cptmp'), 'tmp/tmpdest'\n      cp Pathname.new('tmp/cptmp'), Pathname.new('tmp/tmpdest')\n      mkdir 'tmp/tmpdir'\n      cp ['tmp/cptmp', 'tmp/tmpdest'], Pathname.new('tmp/tmpdir')\n    }\n  end\n\n  def test_cp_r\n    check_singleton :cp_r\n\n    cp_r 'data', 'tmp'\n    TARGETS.each do |fname|\n      assert_same_file fname, \"tmp/#{fname}\"\n    end\n\n    cp_r 'data', 'tmp2', :preserve => true\n    TARGETS.each do |fname|\n      assert_same_entry fname, \"tmp2/#{File.basename(fname)}\"\n      assert_same_file fname, \"tmp2/#{File.basename(fname)}\"\n    end\n\n    # a/* -> b/*\n    mkdir 'tmp/cpr_src'\n    mkdir 'tmp/cpr_dest'\n    File.open('tmp/cpr_src/a', 'w') {|f| f.puts 'a' }\n    File.open('tmp/cpr_src/b', 'w') {|f| f.puts 'b' }\n    File.open('tmp/cpr_src/c', 'w') {|f| f.puts 'c' }\n    mkdir 'tmp/cpr_src/d'\n    cp_r 'tmp/cpr_src/.', 'tmp/cpr_dest'\n    assert_same_file 'tmp/cpr_src/a', 'tmp/cpr_dest/a'\n    assert_same_file 'tmp/cpr_src/b', 'tmp/cpr_dest/b'\n    assert_same_file 'tmp/cpr_src/c', 'tmp/cpr_dest/c'\n    assert_directory 'tmp/cpr_dest/d'\n    my_rm_rf 'tmp/cpr_src'\n    my_rm_rf 'tmp/cpr_dest'\n\nif have_symlink?\n    # symlink in a directory\n    mkdir 'tmp/cpr_src'\n    ln_s 'SLdest', 'tmp/cpr_src/symlink'\n    cp_r 'tmp/cpr_src', 'tmp/cpr_dest'\n    assert_symlink 'tmp/cpr_dest/symlink'\n    assert_equal 'SLdest', File.readlink('tmp/cpr_dest/symlink')\n\n    # root is a symlink\n    ln_s 'cpr_src', 'tmp/cpr_src2'\n    cp_r 'tmp/cpr_src2', 'tmp/cpr_dest2'\n    assert_directory 'tmp/cpr_dest2'\n    #assert_not_symlink 'tmp/cpr_dest2'\n    # * 2005-05-26: feature change on trunk\n    #assert_symlink 'tmp/cpr_dest2'\n    # * 2005-09-19: revert for 1.8 (:dereference_root => true by default)\n    assert_not_symlink 'tmp/cpr_dest2'\n    assert_symlink 'tmp/cpr_dest2/symlink'\n    assert_equal 'SLdest', File.readlink('tmp/cpr_dest2/symlink')\nend\n\n    # pathname\n    touch 'tmp/cprtmp'\n    assert_nothing_raised {\n      cp_r Pathname.new('tmp/cprtmp'), 'tmp/tmpdest'\n      cp_r 'tmp/cprtmp', Pathname.new('tmp/tmpdest')\n      cp_r Pathname.new('tmp/cprtmp'), Pathname.new('tmp/tmpdest')\n    }\n  end\n\n  def test_mv\n    check_singleton :mv\n\n    mkdir 'tmp/dest'\n    TARGETS.each do |fname|\n      cp fname, 'tmp/mvsrc'\n      mv 'tmp/mvsrc', 'tmp/mvdest'\n      assert_same_file fname, 'tmp/mvdest'\n\n      mv 'tmp/mvdest', 'tmp/dest/'\n      assert_same_file fname, 'tmp/dest/mvdest'\n\n      mv 'tmp/dest/mvdest', 'tmp'\n      assert_same_file fname, 'tmp/mvdest'\n    end\n\n    # [ruby-talk:124368]\n    mkdir 'tmp/tmpdir'\n    mkdir_p 'tmp/dest2/tmpdir'\n    assert_raises(Errno::EEXIST) {\n      mv 'tmp/tmpdir', 'tmp/dest2'\n    }\n    mkdir 'tmp/dest2/tmpdir/junk'\n    assert_raises(Errno::EEXIST) {\n      mv 'tmp/tmpdir', 'tmp/dest2'\n    }\n\n    # src==dest (1) same path\n    touch 'tmp/cptmp'\n    assert_raises(ArgumentError) {\n      mv 'tmp/cptmp', 'tmp/cptmp'\n    }\nif have_symlink?\n    # src==dest (2) symlink and its target\n    File.symlink 'cptmp', 'tmp/cptmp_symlink'\n    assert_raises(ArgumentError) {\n      mv 'tmp/cptmp', 'tmp/cptmp_symlink'\n    }\n    assert_raises(ArgumentError) {\n      mv 'tmp/cptmp_symlink', 'tmp/cptmp'\n    }\n    # src==dest (3) looped symlink\n    File.symlink 'symlink', 'tmp/symlink'\n    assert_raises(Errno::ELOOP) {\n      mv 'tmp/symlink', 'tmp/symlink'\n    }\nend\n\n    # pathname\n    assert_nothing_raised {\n      touch 'tmp/mvtmpsrc'\n      mv Pathname.new('tmp/mvtmpsrc'), 'tmp/mvtmpdest'\n      touch 'tmp/mvtmpsrc'\n      mv 'tmp/mvtmpsrc', Pathname.new('tmp/mvtmpdest')\n      touch 'tmp/mvtmpsrc'\n      mv Pathname.new('tmp/mvtmpsrc'), Pathname.new('tmp/mvtmpdest')\n    }\n  end\n\n  def test_rm\n    check_singleton :rm\n\n    TARGETS.each do |fname|\n      cp fname, 'tmp/rmsrc'\n      rm 'tmp/rmsrc'\n      assert_file_not_exist 'tmp/rmsrc'\n    end\n\n    # pathname\n    touch 'tmp/rmtmp1'\n    touch 'tmp/rmtmp2'\n    touch 'tmp/rmtmp3'\n    assert_nothing_raised {\n      rm Pathname.new('tmp/rmtmp1')\n      rm [Pathname.new('tmp/rmtmp2'), Pathname.new('tmp/rmtmp3')]\n    }\n    assert_file_not_exist 'tmp/rmtmp1'\n    assert_file_not_exist 'tmp/rmtmp2'\n    assert_file_not_exist 'tmp/rmtmp3'\n  end\n\n  def test_rm_f\n    check_singleton :rm_f\n\n    TARGETS.each do |fname|\n      cp fname, 'tmp/rmsrc'\n      rm_f 'tmp/rmsrc'\n      assert_file_not_exist 'tmp/rmsrc'\n    end\n\nif have_symlink?\n    File.open('tmp/lnf_symlink_src', 'w') {|f| f.puts 'dummy' }\n    File.symlink 'tmp/lnf_symlink_src', 'tmp/lnf_symlink_dest'\n    rm_f 'tmp/lnf_symlink_dest'\n    assert_file_not_exist 'tmp/lnf_symlink_dest'\n    assert_file_exist     'tmp/lnf_symlink_src'\nend\n\n    rm_f 'notexistdatafile'\n    rm_f 'tmp/notexistdatafile'\n    my_rm_rf 'tmpdatadir'\n    Dir.mkdir 'tmpdatadir'\n    # rm_f 'tmpdatadir'\n    Dir.rmdir 'tmpdatadir'\n\n    Dir.mkdir 'tmp/tmpdir'\n    File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }\n    rm_f ['tmp/tmpdir/a', 'tmp/tmpdir/b', 'tmp/tmpdir/c']\n    assert_file_not_exist 'tmp/tmpdir/a'\n    assert_file_not_exist 'tmp/tmpdir/c'\n    Dir.rmdir 'tmp/tmpdir'\n\n    # pathname\n    touch 'tmp/rmtmp1'\n    touch 'tmp/rmtmp2'\n    touch 'tmp/rmtmp3'\n    touch 'tmp/rmtmp4'\n    assert_nothing_raised {\n      rm_f Pathname.new('tmp/rmtmp1')\n      rm_f [Pathname.new('tmp/rmtmp2'), Pathname.new('tmp/rmtmp3')]\n    }\n    assert_file_not_exist 'tmp/rmtmp1'\n    assert_file_not_exist 'tmp/rmtmp2'\n    assert_file_not_exist 'tmp/rmtmp3'\n    assert_file_exist 'tmp/rmtmp4'\n  end\n\n  def test_rm_r\n    check_singleton :rm_r\n\n    my_rm_rf 'tmpdatadir'\n\n    Dir.mkdir 'tmpdatadir'\n    rm_r 'tmpdatadir'\n    assert_file_not_exist 'tmpdatadir'\n\n    Dir.mkdir 'tmpdatadir'\n    rm_r 'tmpdatadir/'\n    assert_file_not_exist 'tmpdatadir'\n\n    Dir.mkdir 'tmp/tmpdir'\n    rm_r 'tmp/tmpdir/'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\n\n    Dir.mkdir 'tmp/tmpdir'\n    rm_r 'tmp/tmpdir'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\n\n    Dir.mkdir 'tmp/tmpdir'\n    File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/b', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }\n    rm_r 'tmp/tmpdir'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\n\n    Dir.mkdir 'tmp/tmpdir'\n    File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }\n    rm_r ['tmp/tmpdir/a', 'tmp/tmpdir/b', 'tmp/tmpdir/c'], :force => true\n    assert_file_not_exist 'tmp/tmpdir/a'\n    assert_file_not_exist 'tmp/tmpdir/c'\n    Dir.rmdir 'tmp/tmpdir'\n\nif have_symlink?\n    # [ruby-talk:94635] a symlink to the directory\n    Dir.mkdir 'tmp/tmpdir'\n    File.symlink '..', 'tmp/tmpdir/symlink_to_dir'\n    rm_r 'tmp/tmpdir'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\nend\n\n    # pathname\n    Dir.mkdir 'tmp/tmpdir1'; touch 'tmp/tmpdir1/tmp'\n    Dir.mkdir 'tmp/tmpdir2'; touch 'tmp/tmpdir2/tmp'\n    Dir.mkdir 'tmp/tmpdir3'; touch 'tmp/tmpdir3/tmp'\n    assert_nothing_raised {\n      rm_r Pathname.new('tmp/tmpdir1')\n      rm_r [Pathname.new('tmp/tmpdir2'), Pathname.new('tmp/tmpdir3')]\n    }\n    assert_file_not_exist 'tmp/tmpdir1'\n    assert_file_not_exist 'tmp/tmpdir2'\n    assert_file_not_exist 'tmp/tmpdir3'\n  end\n\n  def test_remove_entry_secure\n    check_singleton :remove_entry_secure\n\n    my_rm_rf 'tmpdatadir'\n\n    Dir.mkdir 'tmpdatadir'\n    remove_entry_secure 'tmpdatadir'\n    assert_file_not_exist 'tmpdatadir'\n\n    Dir.mkdir 'tmpdatadir'\n    remove_entry_secure 'tmpdatadir/'\n    assert_file_not_exist 'tmpdatadir'\n\n    Dir.mkdir 'tmp/tmpdir'\n    remove_entry_secure 'tmp/tmpdir/'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\n\n    Dir.mkdir 'tmp/tmpdir'\n    remove_entry_secure 'tmp/tmpdir'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\n\n    Dir.mkdir 'tmp/tmpdir'\n    File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/b', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }\n    remove_entry_secure 'tmp/tmpdir'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\n\n    Dir.mkdir 'tmp/tmpdir'\n    File.open('tmp/tmpdir/a', 'w') {|f| f.puts 'dummy' }\n    File.open('tmp/tmpdir/c', 'w') {|f| f.puts 'dummy' }\n    remove_entry_secure 'tmp/tmpdir/a', true\n    remove_entry_secure 'tmp/tmpdir/b', true\n    remove_entry_secure 'tmp/tmpdir/c', true\n    assert_file_not_exist 'tmp/tmpdir/a'\n    assert_file_not_exist 'tmp/tmpdir/c'\n    Dir.rmdir 'tmp/tmpdir'\n\nif have_symlink?\n    # [ruby-talk:94635] a symlink to the directory\n    Dir.mkdir 'tmp/tmpdir'\n    File.symlink '..', 'tmp/tmpdir/symlink_to_dir'\n    remove_entry_secure 'tmp/tmpdir'\n    assert_file_not_exist 'tmp/tmpdir'\n    assert_file_exist     'tmp'\nend\n\n    # pathname\n    Dir.mkdir 'tmp/tmpdir1'; touch 'tmp/tmpdir1/tmp'\n    assert_nothing_raised {\n      remove_entry_secure Pathname.new('tmp/tmpdir1')\n    }\n    assert_file_not_exist 'tmp/tmpdir1'\n  end\n\n  def test_with_big_file\n    prepare_big_file\n\n    cp BIGFILE, 'tmp/cpdest'\n    assert_same_file BIGFILE, 'tmp/cpdest'\n    assert cmp(BIGFILE, 'tmp/cpdest'), 'orig != copied'\n\n    mv 'tmp/cpdest', 'tmp/mvdest'\n    assert_same_file BIGFILE, 'tmp/mvdest'\n    assert_file_not_exist 'tmp/cpdest'\n\n    rm 'tmp/mvdest'\n    assert_file_not_exist 'tmp/mvdest'\n  end\n\nif have_hardlink?\n  def test_ln\n    TARGETS.each do |fname|\n      ln fname, 'tmp/lndest'\n      assert_same_file fname, 'tmp/lndest'\n      File.unlink 'tmp/lndest'\n    end\n\n    ln TARGETS, 'tmp'\n    TARGETS.each do |fname|\n      assert_same_file fname, 'tmp/' + File.basename(fname)\n    end\n    TARGETS.each do |fname|\n      File.unlink 'tmp/' + File.basename(fname)\n    end\n\n    # src==dest (1) same path\n    touch 'tmp/cptmp'\n    assert_raises(Errno::EEXIST) {\n      ln 'tmp/cptmp', 'tmp/cptmp'\n    }\nif have_symlink?\n    # src==dest (2) symlink and its target\n    File.symlink 'cptmp', 'tmp/symlink'\n    assert_raises(Errno::EEXIST) {\n      ln 'tmp/cptmp', 'tmp/symlink'   # normal file -> symlink\n    }\n    assert_raises(Errno::EEXIST) {\n      ln 'tmp/symlink', 'tmp/cptmp'   # symlink -> normal file\n    }\n    # src==dest (3) looped symlink\n    File.symlink 'cptmp_symlink', 'tmp/cptmp_symlink'\n    begin\n      ln 'tmp/cptmp_symlink', 'tmp/cptmp_symlink'\n    rescue => err\n      assert_kind_of SystemCallError, err\n    end\nend\n\n    # pathname\n    touch 'tmp/lntmp'\n    assert_nothing_raised {\n      ln Pathname.new('tmp/lntmp'), 'tmp/lndesttmp1'\n      ln 'tmp/lntmp', Pathname.new('tmp/lndesttmp2')\n      ln Pathname.new('tmp/lntmp'), Pathname.new('tmp/lndesttmp3')\n    }\n  end\nend\n\nif have_symlink?\n  def test_ln_s\n    check_singleton :ln_s\n\n    TARGETS.each do |fname|\n      ln_s fname, 'tmp/lnsdest'\n      assert FileTest.symlink?('tmp/lnsdest'), 'not symlink'\n      assert_equal fname, File.readlink('tmp/lnsdest')\n      rm_f 'tmp/lnsdest'\n    end\n    assert_nothing_raised {\n      ln_s 'symlink', 'tmp/symlink'\n    }\n    assert_symlink 'tmp/symlink'\n\n    # pathname\n    touch 'tmp/lnsdest'\n    assert_nothing_raised {\n      ln_s Pathname.new('lnsdest'), 'tmp/symlink_tmp1'\n      ln_s 'lnsdest', Pathname.new('tmp/symlink_tmp2')\n      ln_s Pathname.new('lnsdest'), Pathname.new('tmp/symlink_tmp3')\n    }\n  end\nend\n\nif have_symlink?\n  def test_ln_sf\n    check_singleton :ln_sf\n\n    TARGETS.each do |fname|\n      ln_sf fname, 'tmp/lnsdest'\n      assert FileTest.symlink?('tmp/lnsdest'), 'not symlink'\n      assert_equal fname, File.readlink('tmp/lnsdest')\n      ln_sf fname, 'tmp/lnsdest'\n      ln_sf fname, 'tmp/lnsdest'\n    end\n    assert_nothing_raised {\n      ln_sf 'symlink', 'tmp/symlink'\n    }\n\n    # pathname\n    touch 'tmp/lns_dest'\n    assert_nothing_raised {\n      ln_sf Pathname.new('lns_dest'), 'tmp/symlink_tmp1'\n      ln_sf 'lns_dest', Pathname.new('tmp/symlink_tmp2')\n      ln_sf Pathname.new('lns_dest'), Pathname.new('tmp/symlink_tmp3')\n    }\n  end\nend\n\n  def test_mkdir\n    check_singleton :mkdir\n\n    my_rm_rf 'tmpdatadir'\n    mkdir 'tmpdatadir'\n    assert_directory 'tmpdatadir'\n    Dir.rmdir 'tmpdatadir'\n\n    mkdir 'tmpdatadir/'\n    assert_directory 'tmpdatadir'\n    Dir.rmdir 'tmpdatadir'\n\n    mkdir 'tmp/mkdirdest'\n    assert_directory 'tmp/mkdirdest'\n    Dir.rmdir 'tmp/mkdirdest'\n\n    mkdir 'tmp/tmp', :mode => 0700\n    assert_directory 'tmp/tmp'\n    assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm?\n    Dir.rmdir 'tmp/tmp'\n\nif have_file_perm?\n    mkdir 'tmp/tmp', :mode => 07777\n    assert_directory 'tmp/tmp'\n    assert_equal 07777, (File.stat('tmp/tmp').mode & 07777)\n    Dir.rmdir 'tmp/tmp'\nend\n\nif lf_in_path_allowed?\n    mkdir \"tmp-first-line\\ntmp-second-line\"\n    assert_directory \"tmp-first-line\\ntmp-second-line\"\n    Dir.rmdir \"tmp-first-line\\ntmp-second-line\"\nend\n\n    # pathname\n    assert_nothing_raised {\n      mkdir Pathname.new('tmp/tmpdirtmp')\n      mkdir [Pathname.new('tmp/tmpdirtmp2'), Pathname.new('tmp/tmpdirtmp3')]\n    }\n  end\n\n  def test_mkdir_p\n    check_singleton :mkdir_p\n\n    dirs = %w(\n      tmpdir/dir/\n      tmpdir/dir/./\n      tmpdir/dir/./.././dir/\n      tmpdir/a\n      tmpdir/a/\n      tmpdir/a/b\n      tmpdir/a/b/\n      tmpdir/a/b/c/\n      tmpdir/a/b/c\n      tmpdir/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a\n      tmpdir/a/a\n    )\n    my_rm_rf 'tmpdir'\n    dirs.each do |d|\n      mkdir_p d\n      assert_directory d\n      assert_file_not_exist \"#{d}/a\"\n      assert_file_not_exist \"#{d}/b\"\n      assert_file_not_exist \"#{d}/c\"\n      my_rm_rf 'tmpdir'\n    end\n    dirs.each do |d|\n      mkdir_p d\n      assert_directory d\n    end\n    rm_rf 'tmpdir'\n    dirs.each do |d|\n      mkdir_p \"#{Dir.pwd}/#{d}\"\n      assert_directory d\n    end\n    rm_rf 'tmpdir'\n\n    mkdir_p 'tmp/tmp/tmp', :mode => 0700\n    assert_directory 'tmp/tmp'\n    assert_directory 'tmp/tmp/tmp'\n    assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm?\n    assert_equal 0700, (File.stat('tmp/tmp/tmp').mode & 0777) if have_file_perm?\n    rm_rf 'tmp/tmp'\n\n    mkdir_p 'tmp/tmp', :mode => 0\n    assert_directory 'tmp/tmp'\n    assert_equal 0, (File.stat('tmp/tmp').mode & 0777) if have_file_perm?\n    # DO NOT USE rm_rf here.\n    # (rm(1) try to chdir to parent directory, it fails to remove directory.)\n    Dir.rmdir 'tmp/tmp'\n    Dir.rmdir 'tmp'\n\nif have_file_perm?\n    mkdir_p 'tmp/tmp/tmp', :mode => 07777\n    assert_directory 'tmp/tmp/tmp'\n    assert_equal 07777, (File.stat('tmp/tmp/tmp').mode & 07777)\n    Dir.rmdir 'tmp/tmp/tmp'\n    Dir.rmdir 'tmp/tmp'\nend\n\n    # pathname\n    assert_nothing_raised {\n      mkdir_p Pathname.new('tmp/tmp/tmp')\n    }\n  end\n\n  def test_install\n    check_singleton :install\n\n    File.open('tmp/aaa', 'w') {|f| f.puts 'aaa' }\n    File.open('tmp/bbb', 'w') {|f| f.puts 'bbb' }\n    install 'tmp/aaa', 'tmp/bbb', :mode => 0600\n    assert_equal \"aaa\\n\", File.read('tmp/bbb')\n    assert_equal 0600, (File.stat('tmp/bbb').mode & 0777) if have_file_perm?\n\n    t = File.mtime('tmp/bbb')\n    install 'tmp/aaa', 'tmp/bbb'\n    assert_equal \"aaa\\n\", File.read('tmp/bbb')\n    assert_equal 0600, (File.stat('tmp/bbb').mode & 0777) if have_file_perm?\n    assert_equal t, File.mtime('tmp/bbb')\n\n    File.unlink 'tmp/aaa'\n    File.unlink 'tmp/bbb'\n\n    # src==dest (1) same path\n    touch 'tmp/cptmp'\n    assert_raises(ArgumentError) {\n      install 'tmp/cptmp', 'tmp/cptmp'\n    }\nif have_symlink?\n    # src==dest (2) symlink and its target\n    File.symlink 'cptmp', 'tmp/cptmp_symlink'\n    assert_raises(ArgumentError) {\n      install 'tmp/cptmp', 'tmp/cptmp_symlink'\n    }\n    assert_raises(ArgumentError) {\n      install 'tmp/cptmp_symlink', 'tmp/cptmp'\n    }\n    # src==dest (3) looped symlink\n    File.symlink 'symlink', 'tmp/symlink'\n    assert_raises(Errno::ELOOP) {\n      # File#install invokes open(2), always ELOOP must be raised\n      install 'tmp/symlink', 'tmp/symlink'\n    }\nend\n\n    # pathname\n    assert_nothing_raised {\n      rm_f 'tmp/a'; touch 'tmp/a'\n      install 'tmp/a', Pathname.new('tmp/b')\n      rm_f 'tmp/a'; touch 'tmp/a'\n      install Pathname.new('tmp/a'), 'tmp/b'\n      rm_f 'tmp/a'; touch 'tmp/a'\n      install Pathname.new('tmp/a'), Pathname.new('tmp/b')\n      rm_f 'tmp/a'\n      touch 'tmp/a'\n      touch 'tmp/b'\n      mkdir 'tmp/dest'\n      install [Pathname.new('tmp/a'), Pathname.new('tmp/b')], 'tmp/dest'\n      my_rm_rf 'tmp/dest'\n      mkdir 'tmp/dest'\n      install [Pathname.new('tmp/a'), Pathname.new('tmp/b')], Pathname.new('tmp/dest')\n    }\n  end\n\nif have_file_perm?\n  def test_chmod\n    check_singleton :chmod\n\n    touch 'tmp/a'\n    chmod 0700, 'tmp/a'\n    assert_equal 0700, File.stat('tmp/a').mode & 0777\n    chmod 0500, 'tmp/a'\n    assert_equal 0500, File.stat('tmp/a').mode & 0777\n  end\n\n  def test_chmod_R\n    check_singleton :chmod_R\n\n    mkdir_p 'tmp/dir/dir'\n    touch %w( tmp/dir/file tmp/dir/dir/file )\n    chmod_R 0700, 'tmp/dir'\n    assert_equal 0700, File.stat('tmp/dir').mode & 0777\n    assert_equal 0700, File.stat('tmp/dir/file').mode & 0777\n    assert_equal 0700, File.stat('tmp/dir/dir').mode & 0777\n    assert_equal 0700, File.stat('tmp/dir/dir/file').mode & 0777\n    chmod_R 0500, 'tmp/dir'\n    assert_equal 0500, File.stat('tmp/dir').mode & 0777\n    assert_equal 0500, File.stat('tmp/dir/file').mode & 0777\n    assert_equal 0500, File.stat('tmp/dir/dir').mode & 0777\n    assert_equal 0500, File.stat('tmp/dir/dir/file').mode & 0777\n    chmod_R 0700, 'tmp/dir'   # to remove\n  end\n\n  # FIXME: How can I test this method?\n  def test_chown\n    check_singleton :chown\n  end\n\n  # FIXME: How can I test this method?\n  def test_chown_R\n    check_singleton :chown_R\n  end\nend\n\n  def test_copy_entry\n    check_singleton :copy_entry\n\n    each_srcdest do |srcpath, destpath|\n      copy_entry srcpath, destpath\n      assert_same_file srcpath, destpath\n      assert_equal File.stat(srcpath).ftype, File.stat(destpath).ftype\n    end\nif have_symlink?\n    # root is a symlink\n    File.symlink 'somewhere', 'tmp/symsrc'\n    copy_entry 'tmp/symsrc', 'tmp/symdest'\n    assert_symlink 'tmp/symdest'\n    assert_equal 'somewhere', File.readlink('tmp/symdest')\n\n    # content is a symlink\n    mkdir 'tmp/dir'\n    File.symlink 'somewhere', 'tmp/dir/sym'\n    copy_entry 'tmp/dir', 'tmp/dirdest'\n    assert_directory 'tmp/dirdest'\n    assert_not_symlink 'tmp/dirdest'\n    assert_symlink 'tmp/dirdest/sym'\n    assert_equal 'somewhere', File.readlink('tmp/dirdest/sym')\nend\n  end\n\n  def test_copy_file\n    check_singleton :copy_file\n\n    each_srcdest do |srcpath, destpath|\n      copy_file srcpath, destpath\n      assert_same_file srcpath, destpath\n    end\n  end\n\n  def test_copy_stream\n    check_singleton :copy_stream\n    # IO\n    each_srcdest do |srcpath, destpath|\n      File.open(srcpath) {|src|\n        File.open(destpath, 'w') {|dest|\n          copy_stream src, dest\n        }\n      }\n      assert_same_file srcpath, destpath\n    end\n\n    # duck typing test  [ruby-dev:25369]\n    my_rm_rf 'tmp'\n    Dir.mkdir 'tmp'\n    each_srcdest do |srcpath, destpath|\n      File.open(srcpath) {|src|\n        File.open(destpath, 'w') {|dest|\n          copy_stream Stream.new(src), Stream.new(dest)\n        }\n      }\n      assert_same_file srcpath, destpath\n    end\n  end\n\n  def test_remove_file\n    check_singleton :remove_file\n    File.open('data/tmp', 'w') {|f| f.puts 'dummy' }\n    remove_file 'data/tmp'\n    assert_file_not_exist 'data/tmp'\nif have_file_perm?\n    File.open('data/tmp', 'w') {|f| f.puts 'dummy' }\n    File.chmod 0, 'data/tmp'\n    remove_file 'data/tmp'\n    assert_file_not_exist 'data/tmp'\nend\n  end\n\n  def test_remove_dir\n    check_singleton :remove_dir\n    Dir.mkdir 'data/tmpdir'\n    File.open('data/tmpdir/a', 'w') {|f| f.puts 'dummy' }\n    remove_dir 'data/tmpdir'\n    assert_file_not_exist 'data/tmpdir'\nif have_file_perm?\n    Dir.mkdir 'data/tmpdir'\n    File.chmod 0555, 'data/tmpdir'\n    remove_dir 'data/tmpdir'\n    assert_file_not_exist 'data/tmpdir'\nend\n  end\n\n  def test_compare_file\n    check_singleton :compare_file\n    # FIXME\n  end\n\n  def test_compare_stream\n    check_singleton :compare_stream\n    # FIXME\n  end\n\n  class Stream\n    def initialize(f)\n      @f = f\n    end\n\n    def read(n)\n      @f.read(n)\n    end\n\n    def write(str)\n      @f.write str\n    end\n  end\n\n  def test_uptodate?\n    check_singleton :uptodate?\n    prepare_time_data\n    Dir.chdir('data') {\n      assert(   uptodate?('newest', %w(old newer notexist)) )\n      assert( ! uptodate?('newer', %w(old newest notexist)) )\n      assert( ! uptodate?('notexist', %w(old newest newer)) )\n    }\n\n    # pathname\n    touch 'tmp/a'\n    touch 'tmp/b'\n    touch 'tmp/c'\n    assert_nothing_raised {\n      uptodate? Pathname.new('tmp/a'), ['tmp/b', 'tmp/c']\n      uptodate? 'tmp/a', [Pathname.new('tmp/b'), 'tmp/c']\n      uptodate? 'tmp/a', ['tmp/b', Pathname.new('tmp/c')]\n      uptodate? Pathname.new('tmp/a'), [Pathname.new('tmp/b'), Pathname.new('tmp/c')]\n    }\n  end\n\n  def test_cd\n    check_singleton :cd\n  end\n\n  def test_chdir\n    check_singleton :chdir\n  end\n\n  def test_getwd\n    check_singleton :getwd\n  end\n\n  def test_identical?\n    check_singleton :identical?\n  end\n\n  def test_link\n    check_singleton :link\n  end\n\n  def test_makedirs\n    check_singleton :makedirs\n  end\n\n  def test_mkpath\n    check_singleton :mkpath\n  end\n\n  def test_move\n    check_singleton :move\n  end\n\n  def test_rm_rf\n    check_singleton :rm_rf\n  end\n\n  def test_rmdir\n    check_singleton :rmdir\n  end\n\n  def test_rmtree\n    check_singleton :rmtree\n  end\n\n  def test_safe_unlink\n    check_singleton :safe_unlink\n  end\n\n  def test_symlink\n    check_singleton :symlink\n  end\n\n  def test_touch\n    check_singleton :touch\n  end\n\n  def test_collect_methods\n  end\n\n  def test_commands\n  end\n\n  def test_have_option?\n  end\n\n  def test_options\n  end\n\n  def test_options_of\n  end\n\nend\n"
  },
  {
    "path": "test/fileutils/test_nowrite.rb",
    "content": "# $Id$\n\nrequire 'fileutils'\nrequire 'fileasserts'\nrequire 'tmpdir'\nrequire 'test/unit'\n\nclass TestFileUtilsNoWrite < Test::Unit::TestCase\n\n  include FileUtils::NoWrite\n\n  def test_visibility\n    FileUtils::METHODS.each do |m|\n      assert_equal true, FileUtils::NoWrite.respond_to?(m, true),\n                   \"FileUtils::NoWrite.#{m} is not defined\"\n      assert_equal true, FileUtils::NoWrite.respond_to?(m, false),\n                   \"FileUtils::NoWrite.#{m} is not public\"\n    end\n    FileUtils::METHODS.each do |m|\n      assert_equal true, respond_to?(m, true),\n                   \"FileUtils::NoWrite\\##{m} is not defined\"\n      assert_equal true, FileUtils::NoWrite.private_method_defined?(m),\n                   \"FileUtils::NoWrite\\##{m} is not private\"\n    end\n  end\n\n  def my_rm_rf(path)\n    if File.exist?('/bin/rm')\n      system %Q[/bin/rm -rf \"#{path}\"]\n    else\n      FileUtils.rm_rf path\n    end\n  end\n\n  SRC  = 'data/src'\n  COPY = 'data/copy'\n\n  def setup\n    @prevdir = Dir.pwd\n    tmproot = \"#{Dir.tmpdir}/fileutils.rb.#{$$}\"\n    Dir.mkdir tmproot unless File.directory?(tmproot)\n    Dir.chdir tmproot\n    my_rm_rf 'data'; Dir.mkdir 'data'\n    my_rm_rf 'tmp'; Dir.mkdir 'tmp'\n    File.open(SRC,  'w') {|f| f.puts 'dummy' }\n    File.open(COPY, 'w') {|f| f.puts 'dummy' }\n  end\n\n  def teardown\n    tmproot = Dir.pwd\n    Dir.chdir @prevdir\n    my_rm_rf tmproot\n  end\n\n  def test_cp\n    cp SRC, 'tmp/cp'\n    check 'tmp/cp'\n  end\n\n  def test_mv\n    mv SRC, 'tmp/mv'\n    check 'tmp/mv'\n  end\n\n  def check(dest)\n    assert_file_not_exist dest\n    assert_file_exist SRC\n    assert_same_file SRC, COPY\n  end\n\n  def test_rm\n    rm SRC\n    assert_file_exist SRC\n    assert_same_file SRC, COPY\n  end\n\n  def test_rm_f\n    rm_f SRC\n    assert_file_exist SRC\n    assert_same_file SRC, COPY\n  end\n\n  def test_rm_rf\n    rm_rf SRC\n    assert_file_exist SRC\n    assert_same_file SRC, COPY\n  end\n\n  def test_mkdir\n    mkdir 'dir'\n    assert_file_not_exist 'dir'\n  end\n\n  def test_mkdir_p\n    mkdir 'dir/dir/dir'\n    assert_file_not_exist 'dir'\n  end\n\nend\n"
  },
  {
    "path": "test/fileutils/test_verbose.rb",
    "content": "# $Id$\n\nrequire 'test/unit'\nrequire 'fileutils'\n\nclass TestFileUtilsVerbose < Test::Unit::TestCase\n\n  include FileUtils::Verbose\n\n  def test_visibility\n    FileUtils::METHODS.each do |m|\n      assert_equal true, FileUtils::Verbose.respond_to?(m, true),\n                   \"FileUtils::Verbose.#{m} is not defined\"\n      assert_equal true, FileUtils::Verbose.respond_to?(m, false),\n                   \"FileUtils::Verbose.#{m} is not public\"\n    end\n    FileUtils::METHODS.each do |m|\n      assert_equal true, respond_to?(m, true),\n                   \"FileUtils::Verbose.#{m} is not defined\"\n      assert_equal true, FileUtils::Verbose.private_method_defined?(m),\n                   \"FileUtils::Verbose.#{m} is not private\"\n    end\n  end\n\nend\n"
  },
  {
    "path": "test/gdbm/test_gdbm.rb",
    "content": "require 'test/unit'\n\nbegin\n  require 'gdbm'\nrescue LoadError\nend\n\nif defined? GDBM\n  require 'tmpdir'\n  require 'fileutils'\n\n  class TestGDBM < Test::Unit::TestCase\n    def TestGDBM.uname_s\n      require 'rbconfig'\n      case Config::CONFIG['target_os']\n      when 'cygwin'\n        require 'Win32API'\n        uname = Win32API.new('cygwin1', 'uname', 'P', 'I')\n        utsname = ' ' * 100\n        raise 'cannot get system name' if uname.call(utsname) == -1\n\n        utsname.unpack('A20' * 5)[0]\n      else\n        Config::CONFIG['target_os']\n      end\n    end\n    SYSTEM = uname_s\n\n    def setup\n      @path = \"tmptest_gdbm_\"\n      assert_instance_of(GDBM, @gdbm = GDBM.new(@path))\n\n      # prepare to make readonly GDBM file\n      GDBM.open(\"tmptest_gdbm_rdonly\", 0400) {|gdbm|\n        gdbm['foo'] = 'FOO'\n      }\n      assert_instance_of(GDBM, @gdbm_rdonly = GDBM.new(\"tmptest_gdbm_rdonly\", nil))\n    end\n    def teardown\n      assert_nil(@gdbm.close)\n      assert_nil(@gdbm_rdonly.close)\n      ObjectSpace.each_object(GDBM) do |obj|\n        obj.close unless obj.closed?\n      end\n      File.delete *Dir.glob(\"*tmptest_gdbm*\").to_a\n      p Dir.glob(\"*tmptest_gdbm*\") if $DEBUG\n    end\n\n    def check_size(expect, gdbm=@gdbm)\n      assert_equal(expect, gdbm.size)\n      n = 0\n      gdbm.each { n+=1 }\n      assert_equal(expect, n)\n      if expect == 0\n        assert_equal(true, gdbm.empty?)\n      else\n        assert_equal(false, gdbm.empty?)\n      end\n    end\n\n    def have_fork?\n      begin\n        fork{}\n        true\n      rescue NotImplementedError\n        false\n      end\n    end\n\n    def test_s_new_has_no_block\n      # GDBM.new ignore the block\n      foo = true\n      assert_instance_of(GDBM, gdbm = GDBM.new(\"tmptest_gdbm\") { foo = false })\n      assert_equal(foo, true)\n      assert_nil(gdbm.close)\n    end\n    def test_s_open_create_new\n      return if /^CYGWIN_9/ =~ SYSTEM\n\n      save_mask = File.umask(0)\n      begin\n        assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm\"))\n        gdbm.close\n        assert_equal(File.stat(\"tmptest_gdbm\").mode & 0777, 0666)\n        assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm2\", 0644))\n        gdbm.close\n        assert_equal(File.stat(\"tmptest_gdbm2\").mode & 0777, 0644)\n      ensure\n        File.umask save_mask\n      end\n    end\n    def test_s_open_no_create\n      assert_nil(gdbm = GDBM.open(\"tmptest_gdbm\", nil),\n                 \"this test is failed on libgdbm 1.8.0\")\n    ensure\n      gdbm.close if gdbm\n    end\n    def test_s_open_3rd_arg\n      assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm\", 0644,\n                                                GDBM::FAST))\n      gdbm.close\n\n      # gdbm 1.8.0 specific\n      if defined? GDBM::SYNC\n        assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm\", 0644,\n                                                  GDBM::SYNC))\n        gdbm.close\n      end\n      # gdbm 1.8.0 specific\n      if defined? GDBM::NOLOCK\n        assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm\", 0644,\n                                                  GDBM::NOLOCK))\n        gdbm.close\n      end\n    end\n    def test_s_open_with_block\n      assert_equal(GDBM.open(\"tmptest_gdbm\") { :foo }, :foo)\n    end\n    def test_s_open_lock\n      return unless have_fork?\t# snip this test\n      pid = fork() {\n        assert_instance_of(GDBM, gdbm  = GDBM.open(\"tmptest_gdbm\", 0644))\n        sleep 2\n      }\n      begin\n        sleep 1\n        assert_raise(Errno::EWOULDBLOCK) {\n          begin\n            assert_instance_of(GDBM, gdbm2 = GDBM.open(\"tmptest_gdbm\", 0644))\n          rescue Errno::EAGAIN, Errno::EACCES\n            raise Errno::EWOULDBLOCK\n          end\n        }\n      ensure\n        Process.wait pid\n      end\n    end\n\n=begin\n    # Is it guaranteed on many OS?\n    def test_s_open_lock_one_process\n      # locking on one process\n      assert_instance_of(GDBM, gdbm  = GDBM.open(\"tmptest_gdbm\", 0644))\n      assert_raise(Errno::EWOULDBLOCK) {\n        begin\n          GDBM.open(\"tmptest_gdbm\", 0644)\n        rescue Errno::EAGAIN\n          raise Errno::EWOULDBLOCK\n        end\n      }\n    end\n=end\n\n    def test_s_open_nolock\n      # gdbm 1.8.0 specific\n      if not defined? GDBM::NOLOCK\n        return\n      end\n      return unless have_fork?\t# snip this test\n\n      pid = fork() {\n        assert_instance_of(GDBM, gdbm  = GDBM.open(\"tmptest_gdbm\", 0644,\n                                                  GDBM::NOLOCK))\n        sleep 2\n      }\n      sleep 1\n      begin\n        gdbm2 = nil\n        assert_nothing_raised(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {\n          assert_instance_of(GDBM, gdbm2 = GDBM.open(\"tmptest_gdbm\", 0644))\n        }\n      ensure\n        Process.wait pid\n        gdbm2.close if gdbm2\n      end\n\n      p Dir.glob(\"tmptest_gdbm*\") if $DEBUG\n\n      pid = Process.fork() {\n        assert_instance_of(GDBM, gdbm  = GDBM.open(\"tmptest_gdbm\", 0644))\n        sleep 2\n      }\n      begin\n        sleep 1\n        gdbm2 = nil\n        assert_nothing_raised(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {\n          # this test is failed on Cygwin98 (???)\n          assert_instance_of(GDBM, gdbm2 = GDBM.open(\"tmptest_gdbm\", 0644,\n                                                     GDBM::NOLOCK))\n        }\n      ensure\n        Process.wait pid\n        gdbm2.close if gdbm2\n      end\n    end\n\n    def test_s_open_error\n      return if /(ms|bcc)win|mingw|djgpp/ =~ RUBY_PLATFORM\n      assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm\", 0))\n      assert_raise(Errno::EACCES) {\n        GDBM.open(\"tmptest_gdbm\", 0)\n      }\n      gdbm.close\n    end\n\n    def test_close\n      assert_instance_of(GDBM, gdbm = GDBM.open(\"tmptest_gdbm\"))\n      assert_nil(gdbm.close)\n\n      # closed GDBM file\n      assert_raise(RuntimeError) { gdbm.close }\n    end\n\n    def test_aref\n      assert_equal('bar', @gdbm['foo'] = 'bar')\n      assert_equal('bar', @gdbm['foo'])\n\n      assert_nil(@gdbm['bar'])\n    end\n\n    def test_fetch\n      assert_equal('bar', @gdbm['foo']='bar')\n      assert_equal('bar', @gdbm.fetch('foo'))\n\n      # key not found\n      assert_raise(IndexError) {\n        @gdbm.fetch('bar')\n      }\n\n      # test for `ifnone' arg\n      assert_equal('baz', @gdbm.fetch('bar', 'baz'))\n\n      # test for `ifnone' block\n      assert_equal('foobar', @gdbm.fetch('bar') {|key| 'foo' + key })\n    end\n\n    def test_aset\n      num = 0\n      2.times {|i|\n        assert_equal('foo', @gdbm['foo'] = 'foo')\n        assert_equal('foo', @gdbm['foo'])\n        assert_equal('bar', @gdbm['foo'] = 'bar')\n        assert_equal('bar', @gdbm['foo'])\n\n        num += 1 if i == 0\n        assert_equal(num, @gdbm.size)\n\n        # assign nil\n        assert_equal('', @gdbm['bar'] = '')\n        assert_equal('', @gdbm['bar'])\n\n        num += 1 if i == 0\n        assert_equal(num, @gdbm.size)\n\n        # empty string\n        assert_equal('', @gdbm[''] = '')\n        assert_equal('', @gdbm[''])\n\n        num += 1 if i == 0\n        assert_equal(num, @gdbm.size)\n\n        # Fixnum\n        assert_equal('200', @gdbm['100'] = '200')\n        assert_equal('200', @gdbm['100'])\n\n        num += 1 if i == 0\n        assert_equal(num, @gdbm.size)\n\n        # Big key and value\n        assert_equal('y' * 100, @gdbm['x' * 100] = 'y' * 100)\n        assert_equal('y' * 100, @gdbm['x' * 100])\n\n        num += 1 if i == 0\n        assert_equal(num, @gdbm.size)\n      }\n    end\n\n    def test_index\n      assert_equal('bar', @gdbm['foo'] = 'bar')\n      assert_equal('foo', @gdbm.index('bar'))\n      assert_nil(@gdbm['bar'])\n    end\n\n    def test_values_at\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n      assert_equal(values.reverse, @gdbm.values_at(*keys.reverse))\n    end\n\n    def test_select_with_block\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n      ret = @gdbm.select {|k,v|\n        assert_equal(k.upcase, v)\n        k != \"bar\"\n      }\n      assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],\n                    ret.sort)\n    end\n\n    def test_length\n      num = 10\n      assert_equal(0, @gdbm.size)\n      num.times {|i|\n        i = i.to_s\n        @gdbm[i] = i\n      }\n      assert_equal(num, @gdbm.size)\n\n      @gdbm.shift\n\n      assert_equal(num - 1, @gdbm.size)\n    end\n\n    def test_empty?\n      assert_equal(true, @gdbm.empty?)\n      @gdbm['foo'] = 'FOO'\n      assert_equal(false, @gdbm.empty?)\n    end\n\n    def test_each_pair\n      n = 0\n      @gdbm.each_pair { n += 1 }\n      assert_equal(0, n)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n\n      n = 0\n      ret = @gdbm.each_pair {|key, val|\n        assert_not_nil(i = keys.index(key))\n        assert_equal(val, values[i])\n\n        n += 1\n      }\n      assert_equal(keys.size, n)\n      assert_equal(@gdbm, ret)\n    end\n\n    def test_each_value\n      n = 0\n      @gdbm.each_value { n += 1 }\n      assert_equal(0, n)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n\n      n = 0\n      ret = @gdbm.each_value {|val|\n        assert_not_nil(key = @gdbm.index(val))\n        assert_not_nil(i = keys.index(key))\n        assert_equal(val, values[i])\n\n        n += 1\n      }\n      assert_equal(keys.size, n)\n      assert_equal(@gdbm, ret)\n    end\n\n    def test_each_key\n      n = 0\n      @gdbm.each_key { n += 1 }\n      assert_equal(0, n)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n\n      n = 0\n      ret = @gdbm.each_key {|key|\n        assert_not_nil(i = keys.index(key))\n        assert_equal(@gdbm[key], values[i])\n\n        n += 1\n      }\n      assert_equal(keys.size, n)\n      assert_equal(@gdbm, ret)\n    end\n\n    def test_keys\n      assert_equal([], @gdbm.keys)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n\n      assert_equal(keys.sort, @gdbm.keys.sort)\n      assert_equal(values.sort, @gdbm.values.sort)\n    end\n\n    def test_values\n      test_keys\n    end\n\n    def test_shift\n      assert_nil(@gdbm.shift)\n      assert_equal(0, @gdbm.size)\n\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n\n      ret_keys = []\n      ret_values = []\n      while ret = @gdbm.shift\n        ret_keys.push ret[0]\n        ret_values.push ret[1]\n\n        assert_equal(keys.size - ret_keys.size, @gdbm.size)\n      end\n\n      assert_equal(keys.sort, ret_keys.sort)\n      assert_equal(values.sort, ret_values.sort)\n    end\n\n    def test_delete\n      keys = %w(foo bar baz)\n      values = %w(FOO BAR BAZ)\n      key = keys[1]\n\n      assert_nil(@gdbm.delete(key))\n      assert_equal(0, @gdbm.size)\n\n      @gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values\n\n      assert_equal('BAR', @gdbm.delete(key))\n      assert_nil(@gdbm[key])\n      assert_equal(2, @gdbm.size)\n\n      assert_nil(@gdbm.delete(key))\n\n      if /^CYGWIN_9/ !~ SYSTEM\n        assert_raise(GDBMError) {\n          @gdbm_rdonly.delete(\"foo\")\n        }\n\n        assert_nil(@gdbm_rdonly.delete(\"bar\"))\n      end\n    end\n    def test_delete_with_block\n      key = 'no called block'\n      @gdbm[key] = 'foo'\n      assert_equal('foo', @gdbm.delete(key) {|k| k.replace 'called block'})\n      assert_equal('no called block', key)\n      assert_equal(0, @gdbm.size)\n\n      key = 'no called block'\n      assert_equal(:blockval,\n                    @gdbm.delete(key) {|k| k.replace 'called block'; :blockval})\n      assert_equal('called block', key)\n      assert_equal(0, @gdbm.size)\n    end\n\n    def test_delete_if\n      v = \"0\"\n      100.times {@gdbm[v] = v; v = v.next}\n\n      ret = @gdbm.delete_if {|key, val| key.to_i < 50}\n      assert_equal(@gdbm, ret)\n      check_size(50, @gdbm)\n\n      ret = @gdbm.delete_if {|key, val| key.to_i >= 50}\n      assert_equal(@gdbm, ret)\n      check_size(0, @gdbm)\n\n      # break\n      v = \"0\"\n      100.times {@gdbm[v] = v; v = v.next}\n      check_size(100, @gdbm)\n      n = 0;\n      @gdbm.delete_if {|key, val|\n        break if n > 50\n        n+=1\n        true\n      }\n      assert_equal(51, n)\n      check_size(49, @gdbm)\n\n      @gdbm.clear\n\n      # raise\n      v = \"0\"\n      100.times {@gdbm[v] = v; v = v.next}\n      check_size(100, @gdbm)\n      n = 0;\n      begin\n        @gdbm.delete_if {|key, val|\n          raise \"runtime error\" if n > 50\n          n+=1\n          true\n        }\n      rescue\n      end\n      assert_equal(51, n)\n      check_size(49, @gdbm)\n    end\n\n    def test_reject\n      v = \"0\"\n      100.times {@gdbm[v] = v; v = v.next}\n\n      hash = @gdbm.reject {|key, val| key.to_i < 50}\n      assert_instance_of(Hash, hash)\n      assert_equal(100, @gdbm.size)\n\n      assert_equal(50, hash.size)\n      hash.each_pair {|key,val|\n        assert_equal(false, key.to_i < 50)\n        assert_equal(key, val)\n      }\n\n      hash = @gdbm.reject {|key, val| key.to_i < 100}\n      assert_instance_of(Hash, hash)\n      assert_equal(true, hash.empty?)\n    end\n\n    def test_clear\n      v = \"1\"\n      100.times {v = v.next; @gdbm[v] = v}\n\n      assert_equal(@gdbm, @gdbm.clear)\n\n      # validate GDBM#size\n      i = 0\n      @gdbm.each { i += 1 }\n      assert_equal(@gdbm.size, i)\n      assert_equal(0, i)\n    end\n\n    def test_invert\n      v = \"0\"\n      100.times {@gdbm[v] = v; v = v.next}\n\n      hash = @gdbm.invert\n      assert_instance_of(Hash, hash)\n      assert_equal(100, hash.size)\n      hash.each_pair {|key, val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_update\n      hash = {}\n      v = \"0\"\n      100.times {v = v.next; hash[v] = v}\n\n      @gdbm[\"101\"] = \"101\"\n      @gdbm.update hash\n      assert_equal(101, @gdbm.size)\n      @gdbm.each_pair {|key, val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_replace\n      hash = {}\n      v = \"0\"\n      100.times {v = v.next; hash[v] = v}\n\n      @gdbm[\"101\"] = \"101\"\n      @gdbm.replace hash\n      assert_equal(100, @gdbm.size)\n      @gdbm.each_pair {|key, val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_reorganize\n      size1 = File.size(@path)\n      i = \"1\"\n      1000.times {i = i.next; @gdbm[i] = i}\n      @gdbm.clear\n      @gdbm.sync\n\n      size2 = File.size(@path)\n      @gdbm.reorganize\n      size3 = File.size(@path)\n\n      # p [size1, size2, size3]\n      assert_equal(true, size1 < size2)\n      # this test is failed on Cygwin98. `GDBM version 1.8.0, as of May 19, 1999'\n      assert_equal(true, size3 < size2)\n      assert_equal(size1, size3)\n    end\n\n    def test_sync\n      assert_instance_of(GDBM, gdbm = GDBM.open('tmptest_gdbm', 0666, GDBM::FAST))\n      assert_equal(gdbm.sync, gdbm)\n      gdbm.close\n      assert_instance_of(GDBM, gdbm = GDBM.open('tmptest_gdbm', 0666))\n      assert_equal(gdbm.sync, gdbm)\n      gdbm.close\n    end\n\n    def test_cachesize=\n        assert_equal(@gdbm.cachesize = 1024, 1024)\n    end\n\n    def test_fastmode=\n        assert_equal(@gdbm.fastmode = true, true)\n    end\n\n    def test_syncmode=\n        assert_equal(@gdbm.syncmode = true, true)\n    end\n\n    def test_haskey?\n      assert_equal('bar', @gdbm['foo']='bar')\n      assert_equal(true,  @gdbm.has_key?('foo'))\n      assert_equal(false, @gdbm.has_key?('bar'))\n    end\n\n    def test_has_value?\n      assert_equal('bar', @gdbm['foo']='bar')\n      assert_equal(true,  @gdbm.has_value?('bar'))\n      assert_equal(false, @gdbm.has_value?('foo'))\n    end\n\n    def test_to_a\n      v = \"0\"\n      100.times {v = v.next; @gdbm[v] = v}\n\n      ary = @gdbm.to_a\n      assert_instance_of(Array, ary)\n      assert_equal(100, ary.size)\n      ary.each {|key,val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n\n    def test_to_hash\n      v = \"0\"\n      100.times {v = v.next; @gdbm[v] = v}\n\n      hash = @gdbm.to_hash\n      assert_instance_of(Hash, hash)\n      assert_equal(100, hash.size)\n      hash.each {|key,val|\n        assert_equal(key.to_i, val.to_i)\n      }\n    end\n  end\n\n  class TestGDBM2 < Test::Unit::TestCase\n    TMPROOT = \"#{Dir.tmpdir}/ruby-gdbm.#{$$}\"\n\n    def setup\n      Dir.mkdir TMPROOT\n    end\n\n    def teardown\n      FileUtils.rm_rf TMPROOT if File.directory?(TMPROOT)\n    end\n\n    def test_reader_open\n      GDBM.open(\"#{TMPROOT}/a.dbm\") {}\n      v = GDBM.open(\"#{TMPROOT}/a.dbm\", nil, GDBM::READER) {|d|\n        assert_raises(GDBMError) { d[\"k\"] = \"v\" }\n        true\n      }\n      assert(v)\n    end\n\n    def test_newdb_open\n      GDBM.open(\"#{TMPROOT}/a.dbm\") {|dbm|\n        dbm[\"k\"] = \"v\"\n      } \n      v = GDBM.open(\"#{TMPROOT}/a.dbm\", nil, GDBM::NEWDB) {|d|\n        assert_equal(0, d.length)\n        assert_nil(d[\"k\"])\n        true\n      }\n      assert(v)\n    end\n\n    def test_freeze\n      GDBM.open(\"#{TMPROOT}/a.dbm\") {|d|\n        d.freeze\n        assert_raises(TypeError) { d[\"k\"] = \"v\" }\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "test/iconv/test_basic.rb",
    "content": "require File.expand_path(\"../utils.rb\", __FILE__)\n\nclass TestIconv::Basic < TestIconv\n  def test_euc2sjis\n    iconv = Iconv.open('SHIFT_JIS', 'EUC-JP')\n    str = iconv.iconv(EUCJ_STR)\n    str << iconv.iconv(nil)\n    assert_equal(SJIS_STR, str)\n    iconv.close\n  end\n\n  def test_close\n    iconv = Iconv.new('Shift_JIS', 'EUC-JP')\n    output = \"\"\n    begin\n      output += iconv.iconv(EUCJ_STR)\n      output += iconv.iconv(nil)\n    ensure\n      assert_respond_to(iconv, :close)\n      assert_equal(\"\", iconv.close)\n      assert_equal(SJIS_STR, output)\n    end\n  end\n\n  def test_open_without_block\n    assert_respond_to(Iconv, :open)\n    iconv = Iconv.open('SHIFT_JIS', 'EUC-JP')\n    str = iconv.iconv(EUCJ_STR)\n    str << iconv.iconv(nil)\n    assert_equal(SJIS_STR, str )\n    iconv.close\n  end\n\n  def test_open_with_block\n    input = \"#{EUCJ_STR}\\n\"*2\n    output = \"\"\n    Iconv.open(\"Shift_JIS\", \"EUC-JP\") do |cd|\n      input.each_line do |s|\n        output << cd.iconv(s)\n      end\n      output << cd.iconv(nil)\n    end\n    assert_equal(\"#{SJIS_STR}\\n\"*2, output)\n  end\n\n  def test_unknown_encoding\n    assert_raise(Iconv::InvalidEncoding) { Iconv.iconv(\"utf-8\", \"X-UKNOWN\", \"heh\") }\n    assert_raise(Iconv::InvalidEncoding, '[ruby-dev:39487]') {\n      Iconv.iconv(\"X-UNKNOWN-1\", \"X-UNKNOWN-2\") {break}\n    }\n  end\nend if defined?(TestIconv)\n"
  },
  {
    "path": "test/iconv/test_option.rb",
    "content": "require File.expand_path(\"../utils.rb\", __FILE__)\n\nclass TestIconv::Option < TestIconv\n  def test_ignore_option\n    iconv = Iconv.new('SHIFT_JIS', 'EUC-JP//ignore')\n    str = iconv.iconv(EUCJ_STR)\n    str << iconv.iconv(nil)\n    assert_equal(SJIS_STR, str)\n    iconv.close\n\n    iconv = Iconv.new('SHIFT_JIS//IGNORE', 'EUC-JP//ignore')\n    str = iconv.iconv(EUCJ_STR)\n    str << iconv.iconv(nil)\n    assert_equal(SJIS_STR, str)\n    iconv.close\n  end\n\n  def test_translit_option\n    iconv = Iconv.new('SHIFT_JIS', 'EUC-JP//ignore')\n    str = iconv.iconv(EUCJ_STR)\n    str << iconv.iconv(nil)\n    assert_equal(SJIS_STR, str)\n    iconv.close\n\n    iconv = Iconv.new('SHIFT_JIS//TRANSLIT', 'EUC-JP//translit//ignore')\n    str = iconv.iconv(EUCJ_STR)\n    str << iconv.iconv(nil)\n    assert_equal(SJIS_STR, str)\n    iconv.close\n  end\nend if defined?(TestIconv)\n"
  },
  {
    "path": "test/iconv/test_partial.rb",
    "content": "require File.expand_path(\"../utils.rb\", __FILE__)\n\nclass TestIconv::Partial < TestIconv\n  def test_partial_ascii\n    c = Iconv.open(ASCII, ASCII)\n    ref = '[ruby-core:17092]'\n  rescue\n    return\n  else\n    assert_equal(\"abc\", c.iconv(\"abc\"))\n    assert_equal(\"c\",   c.iconv(\"abc\", 2),     \"#{ref}: with start\")\n    assert_equal(\"c\",   c.iconv(\"abc\", 2, 1),  \"#{ref}: with start, length\")\n    assert_equal(\"c\",   c.iconv(\"abc\", 2, 5),  \"#{ref}: with start, longer length\")\n    assert_equal(\"bc\",  c.iconv(\"abc\", -2),    \"#{ref}: with nagative start\")\n    assert_equal(\"b\",   c.iconv(\"abc\", -2, 1), \"#{ref}: with nagative start, length\")\n    assert_equal(\"bc\",  c.iconv(\"abc\", -2, 5), \"#{ref}: with nagative start, longer length\")\n    assert_equal(\"\",    c.iconv(\"abc\", 5),     \"#{ref}: with OOB\")\n    assert_equal(\"\",    c.iconv(\"abc\", 5, 2),  \"#{ref}: with OOB, length\")\n  ensure\n    c.close if c\n  end\n\n  def test_partial_euc2sjis\n    c = Iconv.open('SHIFT_JIS', 'EUC-JP')\n  rescue\n    return\n  else\n    assert_equal(SJIS_STR[0, 2],   c.iconv(EUCJ_STR, 0, 2))\n    assert_equal(SJIS_STR,         c.iconv(EUCJ_STR, 0, 20))\n    assert_equal(SJIS_STR[2..-1],  c.iconv(EUCJ_STR, 2))\n    assert_equal(SJIS_STR[2, 2],   c.iconv(EUCJ_STR, 2, 2))\n    assert_equal(SJIS_STR[2..-1],  c.iconv(EUCJ_STR, 2, 20))\n    assert_equal(SJIS_STR[-4..-1], c.iconv(EUCJ_STR, -4))\n    assert_equal(SJIS_STR[-4, 2],  c.iconv(EUCJ_STR, -4, 2))\n    assert_equal(SJIS_STR[-4..-1], c.iconv(EUCJ_STR, -4, 20))\n    assert_equal(\"\",               c.iconv(EUCJ_STR, 20))\n    assert_equal(\"\",               c.iconv(EUCJ_STR, 20, 2))\n  ensure\n    c.close\n  end\nend if defined?(TestIconv)\n"
  },
  {
    "path": "test/iconv/utils.rb",
    "content": "begin\n  require 'iconv'\nrescue LoadError\nelse\n  require 'test/unit'\nend\n\nclass TestIconv < ::Test::Unit::TestCase\n  if defined?(::Encoding) and String.method_defined?(:force_encoding)\n    def self.encode(str, enc)\n      str.force_encoding(enc)\n    end\n  else\n    def self.encode(str, enc)\n      str\n    end\n  end\n\n  def default_test\n    self.class == TestIconv or super\n  end\n\n  ASCII = \"ascii\"\n  EUCJ_STR = encode(\"\\xa4\\xa2\\xa4\\xa4\\xa4\\xa6\\xa4\\xa8\\xa4\\xaa\", \"EUC-JP\").freeze\n  SJIS_STR = encode(\"\\x82\\xa0\\x82\\xa2\\x82\\xa4\\x82\\xa6\\x82\\xa8\", \"Shift_JIS\").freeze\nend if defined?(::Iconv)\n"
  },
  {
    "path": "test/io/nonblock/test_flush.rb",
    "content": "require 'test/unit'\nbegin\n  require 'io/nonblock'\nrescue LoadError\nend\n\nclass TestIONonblock < Test::Unit::TestCase\n  def test_flush                # [ruby-dev:24985]\n    r,w = IO.pipe\n    w.nonblock = true\n    w.sync = false\n    w << \"b\"\n    w.flush\n    w << \"a\" * 4096\n    Thread.new {\n      Thread.pass\n      w.close\n    }\n    result = \"\"\n    t = Thread.new {\n      while (Thread.pass; s = r.read(4096))\n        result << s\n      end\n    }\n    assert_raise(IOError) {w.flush}\n    assert_nothing_raised {t.join}\n  end\nend if IO.method_defined?(:nonblock)\n"
  },
  {
    "path": "test/logger/test_logger.rb",
    "content": "require 'test/unit'\nrequire 'logger'\nrequire 'tempfile'\n\n\nclass TestLoggerSeverity < Test::Unit::TestCase\n  def test_enum\n    logger_levels = Logger.constants\n    levels = [\"WARN\", \"UNKNOWN\", \"INFO\", \"FATAL\", \"DEBUG\", \"ERROR\"]\n    Logger::Severity.constants.each do |level|\n      assert(levels.include?(level))\n      assert(logger_levels.include?(level))\n    end\n    assert_equal(levels.size, Logger::Severity.constants.size)\n  end\nend\n\n\nclass TestLogger < Test::Unit::TestCase\n  include Logger::Severity\n\n  def setup\n    @logger = Logger.new(nil)\n  end\n\n  def test_const_progname\n    assert %r!\\Alogger\\.rb/\\S+\\z! === Logger::ProgName\n  end\n\n  class Log\n    attr_reader :label, :datetime, :pid, :severity, :progname, :msg\n    def initialize(line)\n      /\\A(\\w+), \\[([^#]*)#(\\d+)\\]\\s+(\\w+) -- (\\w*): ([\\x0-\\xff]*)/ =~ line\n      @label, @datetime, @pid, @severity, @progname, @msg = $1, $2, $3, $4, $5, $6\n    end\n  end\n\n  def log_add(logger, severity, msg, progname = nil, &block)\n    log(logger, :add, severity, msg, progname, &block)\n  end\n\n  def log(logger, msg_id, *arg, &block)\n    Log.new(log_raw(logger, msg_id, *arg, &block))\n  end\n\n  def log_raw(logger, msg_id, *arg, &block)\n    logdev = Tempfile.new(File.basename(__FILE__) + '.log')\n    logger.instance_eval { @logdev = Logger::LogDevice.new(logdev) }\n    logger.__send__(msg_id, *arg, &block)\n    logdev.open\n    msg = logdev.read\n    logdev.close\n    msg\n  end\n\n  def test_level\n    @logger.level = UNKNOWN\n    assert_equal(UNKNOWN, @logger.level)\n    @logger.level = INFO\n    assert_equal(INFO, @logger.level)\n    @logger.sev_threshold = ERROR\n    assert_equal(ERROR, @logger.sev_threshold)\n    @logger.sev_threshold = WARN\n    assert_equal(WARN, @logger.sev_threshold)\n    assert_equal(WARN, @logger.level)\n\n    @logger.level = DEBUG\n    assert(@logger.debug?)\n    assert(@logger.info?)\n    @logger.level = INFO\n    assert(!@logger.debug?)\n    assert(@logger.info?)\n    assert(@logger.warn?)\n    @logger.level = WARN\n    assert(!@logger.info?)\n    assert(@logger.warn?)\n    assert(@logger.error?)\n    @logger.level = ERROR\n    assert(!@logger.warn?)\n    assert(@logger.error?)\n    assert(@logger.fatal?)\n    @logger.level = FATAL\n    assert(!@logger.error?)\n    assert(@logger.fatal?)\n    @logger.level = UNKNOWN\n    assert(!@logger.error?)\n    assert(!@logger.fatal?)\n  end\n\n  def test_progname\n    assert_nil(@logger.progname)\n    @logger.progname = \"name\"\n    assert_equal(\"name\", @logger.progname)\n  end\n\n  def test_datetime_format\n    dummy = STDERR\n    logger = Logger.new(dummy)\n    log = log_add(logger, INFO, \"foo\")\n    assert_match(/^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d.\\s*\\d+ $/, log.datetime)\n    logger.datetime_format = \"%d%b%Y@%H:%M:%S\"\n    log = log_add(logger, INFO, \"foo\")\n    assert_match(/^\\d\\d\\w\\w\\w\\d\\d\\d\\d@\\d\\d:\\d\\d:\\d\\d$/, log.datetime)\n    logger.datetime_format = \"\"\n    log = log_add(logger, INFO, \"foo\")\n    assert_match(/^$/, log.datetime)\n  end\n\n  def test_formatter\n    dummy = STDERR\n    logger = Logger.new(dummy)\n    # default\n    log = log(logger, :info, \"foo\")\n    assert_equal(\"foo\\n\", log.msg)\n    # config\n    logger.formatter = proc { |severity, timestamp, progname, msg|\n      \"#{severity}:#{msg}\\n\\n\"\n    }\n    line = log_raw(logger, :info, \"foo\")\n    assert_equal(\"INFO:foo\\n\\n\", line)\n    # recover\n    logger.formatter = nil\n    log = log(logger, :info, \"foo\")\n    assert_equal(\"foo\\n\", log.msg)\n    # again\n    o = Object.new\n    def o.call(severity, timestamp, progname, msg)\n      \"<<#{severity}-#{msg}>>\\n\"\n    end\n    logger.formatter = o\n    line = log_raw(logger, :info, \"foo\")\n    assert_equal(\"<<INFO-foo>>\\n\", line)\n  end\n\n  def test_initialize\n    logger = Logger.new(STDERR)\n    assert_nil(logger.progname)\n    assert_equal(DEBUG, logger.level)\n    assert_nil(logger.datetime_format)\n  end\n\n  def test_add\n    logger = Logger.new(nil)\n    logger.progname = \"my_progname\"\n    assert(logger.add(INFO))\n    log = log_add(logger, nil, \"msg\")\n    assert_equal(\"ANY\", log.severity)\n    assert_equal(\"my_progname\", log.progname)\n    logger.level = WARN\n    assert(logger.log(INFO))\n    assert_nil(log_add(logger, INFO, \"msg\").msg)\n    log = log_add(logger, WARN, nil) { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    log = log_add(logger, WARN, \"\") { \"msg\" }\n    assert_equal(\"\\n\", log.msg)\n    assert_equal(\"my_progname\", log.progname)\n    log = log_add(logger, WARN, nil, \"progname?\")\n    assert_equal(\"progname?\\n\", log.msg)\n    assert_equal(\"my_progname\", log.progname)\n  end\n\n  def test_level_log\n    logger = Logger.new(nil)\n    logger.progname = \"my_progname\"\n    log = log(logger, :debug, \"custom_progname\") { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    assert_equal(\"custom_progname\", log.progname)\n    assert_equal(\"DEBUG\", log.severity)\n    assert_equal(\"D\", log.label)\n    #\n    log = log(logger, :debug) { \"msg_block\" }\n    assert_equal(\"msg_block\\n\", log.msg)\n    assert_equal(\"my_progname\", log.progname)\n    log = log(logger, :debug, \"msg_inline\")\n    assert_equal(\"msg_inline\\n\", log.msg)\n    assert_equal(\"my_progname\", log.progname)\n    #\n    log = log(logger, :info, \"custom_progname\") { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    assert_equal(\"custom_progname\", log.progname)\n    assert_equal(\"INFO\", log.severity)\n    assert_equal(\"I\", log.label)\n    #\n    log = log(logger, :warn, \"custom_progname\") { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    assert_equal(\"custom_progname\", log.progname)\n    assert_equal(\"WARN\", log.severity)\n    assert_equal(\"W\", log.label)\n    #\n    log = log(logger, :error, \"custom_progname\") { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    assert_equal(\"custom_progname\", log.progname)\n    assert_equal(\"ERROR\", log.severity)\n    assert_equal(\"E\", log.label)\n    #\n    log = log(logger, :fatal, \"custom_progname\") { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    assert_equal(\"custom_progname\", log.progname)\n    assert_equal(\"FATAL\", log.severity)\n    assert_equal(\"F\", log.label)\n    #\n    log = log(logger, :unknown, \"custom_progname\") { \"msg\" }\n    assert_equal(\"msg\\n\", log.msg)\n    assert_equal(\"custom_progname\", log.progname)\n    assert_equal(\"ANY\", log.severity)\n    assert_equal(\"A\", log.label)\n  end\n\n  def test_close\n    r, w = IO.pipe\n    assert(!w.closed?)\n    logger = Logger.new(w)\n    logger.close\n    assert(w.closed?)\n    r.close\n  end\n\n  class MyError < StandardError\n  end\n\n  class MyMsg\n    def inspect\n      \"my_msg\"\n    end\n  end\n\n  def test_format\n    logger = Logger.new(nil)\n    log = log_add(logger, INFO, \"msg\\n\")\n    assert_equal(\"msg\\n\\n\", log.msg)\n    begin\n      raise MyError.new(\"excn\")\n    rescue MyError => e\n      log = log_add(logger, INFO, e)\n      assert_match(/^excn \\(TestLogger::MyError\\)/, log.msg)\n      # expects backtrace is dumped across multi lines.  10 might be changed.\n      assert(log.msg.split(/\\n/).size >= 10)\n    end\n    log = log_add(logger, INFO, MyMsg.new)\n    assert_equal(\"my_msg\\n\", log.msg)\n  end\n\n  def test_lshift\n    r, w = IO.pipe\n    logger = Logger.new(w)\n    logger << \"msg\"\n    read_ready, = IO.select([r], nil, nil, 0.1)\n    w.close\n    msg = r.read\n    r.close\n    assert_equal(\"msg\", msg)\n    #\n    r, w = IO.pipe\n    logger = Logger.new(w)\n    logger << \"msg2\\n\\n\"\n    read_ready, = IO.select([r], nil, nil, 0.1)\n    w.close\n    msg = r.read\n    r.close\n    assert_equal(\"msg2\\n\\n\", msg)\n  end\nend\n\nclass TestLogDevice < Test::Unit::TestCase\n  def d(log)\n    Logger::LogDevice.new(log)\n  end\n\n  def test_initialize\n    logdev = d(STDERR)\n    assert_equal(STDERR, logdev.dev)\n    assert_nil(logdev.filename)\n    assert_raises(TypeError) do\n      d(nil)\n    end\n    #\n    filename = __FILE__ + \".#{$$}\"\n    begin\n      logdev = d(filename)\n      assert(File.exist?(filename))\n      assert(logdev.dev.sync)\n      assert_equal(filename, logdev.filename)\n    ensure\n      logdev.close\n      File.unlink(filename)\n    end\n  end\n\n  def test_write\n    r, w = IO.pipe\n    logdev = d(w)\n    logdev.write(\"msg2\\n\\n\")\n    read_ready, = IO.select([r], nil, nil, 0.1)\n    w.close\n    msg = r.read\n    r.close\n    assert_equal(\"msg2\\n\\n\", msg)\n  end\n\n  def test_close\n    r, w = IO.pipe\n    logdev = d(w)\n    logdev.write(\"msg2\\n\\n\")\n    read_ready, = IO.select([r], nil, nil, 0.1)\n    assert(!w.closed?)\n    logdev.close\n    assert(w.closed?)\n    r.close\n  end\n\n  def test_shifting_size\n    logfile = File.basename(__FILE__) + '_1.log'\n    logfile0 = logfile + '.0'\n    logfile1 = logfile + '.1'\n    logfile2 = logfile + '.2'\n    logfile3 = logfile + '.3'\n    File.unlink(logfile) if File.exist?(logfile)\n    File.unlink(logfile0) if File.exist?(logfile0)\n    File.unlink(logfile1) if File.exist?(logfile1)\n    File.unlink(logfile2) if File.exist?(logfile2)\n    logger = Logger.new(logfile, 4, 100)\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile))\n    assert(!File.exist?(logfile0))\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile0))\n    assert(!File.exist?(logfile1))\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile1))\n    assert(!File.exist?(logfile2))\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile2))\n    assert(!File.exist?(logfile3))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile3))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile3))\n    logger.close\n    File.unlink(logfile)\n    File.unlink(logfile0)\n    File.unlink(logfile1)\n    File.unlink(logfile2)\n\n    logfile = File.basename(__FILE__) + '_2.log'\n    logfile0 = logfile + '.0'\n    logfile1 = logfile + '.1'\n    logfile2 = logfile + '.2'\n    logfile3 = logfile + '.3'\n    logger = Logger.new(logfile, 4, 150)\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile))\n    assert(!File.exist?(logfile0))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile0))\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile0))\n    assert(!File.exist?(logfile1))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile1))\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile1))\n    assert(!File.exist?(logfile2))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile2))\n    logger.error(\"0\" * 15)\n    assert(File.exist?(logfile2))\n    assert(!File.exist?(logfile3))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile3))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile3))\n    logger.error(\"0\" * 15)\n    assert(!File.exist?(logfile3))\n    logger.close\n    File.unlink(logfile)\n    File.unlink(logfile0)\n    File.unlink(logfile1)\n    File.unlink(logfile2)\n  end\nend\n"
  },
  {
    "path": "test/matrix/test_matrix.rb",
    "content": "require 'test/unit'\nrequire 'matrix'\n\nclass TestMatrix < Test::Unit::TestCase\n  def setup\n    @m1 = Matrix[[1,2,3], [4,5,6]]\n    @m2 = Matrix[[1,2,3], [4,5,6]]\n    @m3 = @m1.clone\n    @m4 = Matrix[[1,0, 2.0, 3.0], [4.0, 5.0, 6.0]]\n    @n1 = Matrix[[2,3,4], [5,6,7]]\n  end\n\n  def test_identity\n    assert_same @m1, @m1\n    assert_not_same @m1, @m2\n    assert_not_same @m1, @m3\n    assert_not_same @m1, @m4\n    assert_not_same @m1, @n1\n  end\n\n  def test_equality\n    assert_equal @m1, @m1\n    assert_equal @m1, @m2\n    assert_equal @m1, @m3\n    assert_not_equal @m1, @m4\n    assert_not_equal @m1, @n1\n  end\n\n  def test_hash_equality\n    assert @m1.eql?(@m1)\n    assert @m1.eql?(@m2)\n    assert @m1.eql?(@m3)\n    assert !@m1.eql?(@m4)\n    assert !@m1.eql?(@n1)\n\n    hash = { @m1 => :value }\n    assert hash.key?(@m1)\n    assert hash.key?(@m2)\n    assert hash.key?(@m3)\n    assert !hash.key?(@m4)\n    assert !hash.key?(@n1)\n  end\nend\n"
  },
  {
    "path": "test/matrix/test_vector.rb",
    "content": "require 'test/unit'\nrequire 'matrix'\n\nclass TestVector < Test::Unit::TestCase\n  def setup\n    @v1 = Vector[1,2,3]\n    @v2 = Vector[1,2,3]\n    @v3 = @v1.clone\n    @v4 = Vector[1,0, 2.0, 3.0]\n    @w1 = Vector[2,3,4]\n  end\n\n  def test_identity\n    assert_same @v1, @v1\n    assert_not_same @v1, @v2\n    assert_not_same @v1, @v3\n    assert_not_same @v1, @v4\n    assert_not_same @v1, @w1\n  end\n\n  def test_equality\n    assert_equal @v1, @v1\n    assert_equal @v1, @v2\n    assert_equal @v1, @v3\n    assert_not_equal @v1, @v4\n    assert_not_equal @v1, @w1\n  end\n\n  def test_hash_equality\n    assert @v1.eql?(@v1)\n    assert @v1.eql?(@v2)\n    assert @v1.eql?(@v3)\n    assert !@v1.eql?(@v4)\n    assert !@v1.eql?(@w1)\n\n    hash = { @v1 => :value }\n    assert hash.key?(@v1)\n    assert hash.key?(@v2)\n    assert hash.key?(@v3)\n    assert !hash.key?(@v4)\n    assert !hash.key?(@w1)\n  end\nend\n"
  },
  {
    "path": "test/monitor/test_monitor.rb",
    "content": "require \"monitor\"\nrequire \"thread\"\n\nrequire \"test/unit\"\n\nclass TestMonitor < Test::Unit::TestCase\n  def setup\n    @monitor = Monitor.new\n  end\n\n  def test_enter\n    ary = []\n    queue = Queue.new\n    th = Thread.start {\n      queue.pop\n      @monitor.enter\n      for i in 6 .. 10\n        ary.push(i)\n        Thread.pass\n      end\n      @monitor.exit\n    }\n    @monitor.enter\n    queue.enq(nil)\n    for i in 1 .. 5\n      ary.push(i)\n      Thread.pass\n    end\n    @monitor.exit\n    th.join\n    assert_equal((1..10).to_a, ary)\n  end\n\n  def test_synchronize\n    ary = []\n    queue = Queue.new\n    th = Thread.start {\n      queue.pop\n      @monitor.synchronize do\n        for i in 6 .. 10\n          ary.push(i)\n          Thread.pass\n        end\n      end\n    }\n    @monitor.synchronize do\n      queue.enq(nil)\n      for i in 1 .. 5\n        ary.push(i)\n        Thread.pass\n      end\n    end\n    th.join\n    assert_equal((1..10).to_a, ary)\n  end\n\n  def test_killed_thread_in_synchronize\n    ary = []\n    queue = Queue.new\n    t1 = Thread.start {\n      queue.pop\n      @monitor.synchronize {\n        ary << :t1\n      }\n    }\n    t2 = Thread.start {\n      queue.pop\n      @monitor.synchronize {\n        ary << :t2\n      }\n    }\n    @monitor.synchronize do\n      queue.enq(nil)\n      queue.enq(nil)\n      assert_equal([], ary)\n      t1.kill\n      t2.kill\n      ary << :main\n    end\n    assert_equal([:main], ary)\n  end\n\n  def test_try_enter\n    queue1 = Queue.new\n    queue2 = Queue.new\n    th = Thread.start {\n      queue1.deq\n      @monitor.enter\n      queue2.enq(nil)\n      queue1.deq\n      @monitor.exit\n      queue2.enq(nil)\n    }\n    assert_equal(true, @monitor.try_enter)\n    @monitor.exit\n    queue1.enq(nil)\n    queue2.deq\n    assert_equal(false, @monitor.try_enter)\n    queue1.enq(nil)\n    queue2.deq\n    assert_equal(true, @monitor.try_enter)\n  end\n\n  def test_cond\n    cond = @monitor.new_cond\n\n    a = \"foo\"\n    queue1 = Queue.new\n    Thread.start do\n      queue1.deq\n      @monitor.synchronize do\n        a = \"bar\"\n        cond.signal\n      end\n    end\n    @monitor.synchronize do\n      queue1.enq(nil)\n      assert_equal(\"foo\", a)\n      result1 = cond.wait\n      assert_equal(true, result1)\n      assert_equal(\"bar\", a)\n    end\n  end\n\n  def test_timedwait\n    cond = @monitor.new_cond\n    b = \"foo\"\n    queue2 = Queue.new\n    Thread.start do\n      queue2.deq\n      @monitor.synchronize do\n        b = \"bar\"\n        cond.signal\n      end\n    end\n    @monitor.synchronize do\n      queue2.enq(nil)\n      assert_equal(\"foo\", b)\n      result2 = cond.wait(0.1)\n      assert_equal(true, result2)\n      assert_equal(\"bar\", b)\n    end\n\n    c = \"foo\"\n    queue3 = Queue.new\n    Thread.start do\n      queue3.deq\n      @monitor.synchronize do\n        c = \"bar\"\n        cond.signal\n      end\n    end\n    @monitor.synchronize do\n      assert_equal(\"foo\", c)\n      result3 = cond.wait(0.1)\n      assert_equal(false, result3)\n      assert_equal(\"foo\", c)\n      queue3.enq(nil)\n      result4 = cond.wait\n      assert_equal(true, result4)\n      assert_equal(\"bar\", c)\n    end\n\n#     d = \"foo\"\n#     cumber_thread = Thread.start {\n#       loop do\n#         @monitor.synchronize do\n#           d = \"foo\"\n#         end\n#       end\n#     }\n#     queue3 = Queue.new\n#     Thread.start do\n#       queue3.pop\n#       @monitor.synchronize do\n#         d = \"bar\"\n#         cond.signal\n#       end\n#     end\n#     @monitor.synchronize do\n#       queue3.enq(nil)\n#       assert_equal(\"foo\", d)\n#       result5 = cond.wait\n#       assert_equal(true, result5)\n#       # this thread has priority over cumber_thread\n#       assert_equal(\"bar\", d)\n#     end\n#     cumber_thread.kill\n  end\nend\n"
  },
  {
    "path": "test/net/http/test_connection.rb",
    "content": "require 'net/http'\nrequire 'test/unit'\n\nmodule TestHTTP\n  class HTTPConnectionTest < Test::Unit::TestCase\n    def test_connection_refused_in_request\n      bug2708 = '[ruby-core:28028]'\n      port = nil\n      localhost = \"127.0.0.1\"\n      t = Thread.new {\n        TCPServer.open(localhost, 0) do |serv|\n          _, port, _, _ = serv.addr\n          if clt = serv.accept\n            clt.close\n          end\n        end\n      }\n      begin\n        sleep 0.1 until port\n        assert_raise(Errno::ECONNRESET, bug2708) {\n          n = Net::HTTP.new(localhost, port)\n          n.request_get('/')\n        }\n      ensure\n        t.join if t\n      end\n      assert_raise(Errno::ECONNREFUSED, bug2708) {\n        n = Net::HTTP.new(localhost, port)\n        n.request_get('/')\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "test/net/http/test_httpheader.rb",
    "content": "require 'net/http'\nrequire 'test/unit'\n\nclass HTTPHeaderTest < Test::Unit::TestCase\n\n  class C\n    include Net::HTTPHeader\n    def initialize\n      initialize_http_header({})\n    end\n    attr_accessor :body\n  end\n\n  def setup\n    @c = C.new\n  end\n\n  def test_size\n    assert_equal 0, @c.size\n    @c['a'] = 'a'\n    assert_equal 1, @c.size\n    @c['b'] = 'b'\n    assert_equal 2, @c.size\n    @c['b'] = 'b'\n    assert_equal 2, @c.size\n    @c['c'] = 'c'\n    assert_equal 3, @c.size\n  end\n\n  def test_ASET\n    @c['My-Header'] = 'test string'\n    @c['my-Header'] = 'test string'\n    @c['My-header'] = 'test string'\n    @c['my-header'] = 'test string'\n    @c['MY-HEADER'] = 'test string'\n    assert_equal 1, @c.size\n\n    @c['AaA'] = 'aaa'\n    @c['aaA'] = 'aaa'\n    @c['AAa'] = 'aaa'\n    assert_equal 2, @c.length\n  end\n\n  def test_AREF\n    @c['My-Header'] = 'test string'\n    assert_equal 'test string', @c['my-header']\n    assert_equal 'test string', @c['MY-header']\n    assert_equal 'test string', @c['my-HEADER']\n\n    @c['Next-Header'] = 'next string'\n    assert_equal 'next string', @c['next-header']\n  end\n\n  def test_add_field\n    @c.add_field 'My-Header', 'a'\n    assert_equal 'a', @c['My-Header']\n    assert_equal ['a'], @c.get_fields('My-Header')\n    @c.add_field 'My-Header', 'b'\n    assert_equal 'a, b', @c['My-Header']\n    assert_equal ['a', 'b'], @c.get_fields('My-Header')\n    @c.add_field 'My-Header', 'c'\n    assert_equal 'a, b, c', @c['My-Header']\n    assert_equal ['a', 'b', 'c'], @c.get_fields('My-Header')\n    @c.add_field 'My-Header', 'd, d'\n    assert_equal 'a, b, c, d, d', @c['My-Header']\n    assert_equal ['a', 'b', 'c', 'd, d'], @c.get_fields('My-Header')\n  end\n\n  def test_get_fields\n    @c['My-Header'] = 'test string'\n    assert_equal ['test string'], @c.get_fields('my-header')\n    assert_equal ['test string'], @c.get_fields('My-header')\n    assert_equal ['test string'], @c.get_fields('my-Header')\n\n    assert_nil @c.get_fields('not-found')\n    assert_nil @c.get_fields('Not-Found')\n\n    @c.get_fields('my-header').push 'junk'\n    assert_equal ['test string'], @c.get_fields('my-header')\n    @c.get_fields('my-header').clear\n    assert_equal ['test string'], @c.get_fields('my-header')\n  end\n\n  def test_delete\n    @c['My-Header'] = 'test'\n    assert_equal 'test', @c['My-Header']\n    assert_nil @c['not-found']\n    @c.delete 'My-Header'\n    assert_nil @c['My-Header']\n    assert_nil @c['not-found']\n    @c.delete 'My-Header'\n    @c.delete 'My-Header'\n    assert_nil @c['My-Header']\n    assert_nil @c['not-found']\n  end\n\n  def test_each\n    @c['My-Header'] = 'test'\n    @c.each do |k, v|\n      assert_equal 'my-header', k\n      assert_equal 'test', v\n    end\n    @c.each do |k, v|\n      assert_equal 'my-header', k\n      assert_equal 'test', v\n    end\n  end\n\n  def test_each_key\n    @c['My-Header'] = 'test'\n    @c.each_key do |k|\n      assert_equal 'my-header', k\n    end\n    @c.each_key do |k|\n      assert_equal 'my-header', k\n    end\n  end\n\n  def test_each_value\n    @c['My-Header'] = 'test'\n    @c.each_value do |v|\n      assert_equal 'test', v\n    end\n    @c.each_value do |v|\n      assert_equal 'test', v\n    end\n  end\n\n  def test_canonical_each\n    @c['my-header'] = ['a', 'b']\n    @c.canonical_each do |k,v|\n      assert_equal 'My-Header', k\n      assert_equal 'a, b', v\n    end\n  end\n\n  def test_each_capitalized\n    @c['my-header'] = ['a', 'b']\n    @c.each_capitalized do |k,v|\n      assert_equal 'My-Header', k\n      assert_equal 'a, b', v\n    end\n  end\n\n  def test_key?\n    @c['My-Header'] = 'test'\n    assert_equal true, @c.key?('My-Header')\n    assert_equal true, @c.key?('my-header')\n    assert_equal false, @c.key?('Not-Found')\n    assert_equal false, @c.key?('not-found')\n    assert_equal false, @c.key?('')\n    assert_equal false, @c.key?('x' * 1024)\n  end\n\n  def test_to_hash\n  end\n\n  def test_range\n    try_range(1..5,     '1-5')\n    try_range(234..567, '234-567')\n    try_range(-5..-1,   '-5')\n    try_range(1..-1,    '1-')\n  end\n\n  def try_range(r, s)\n    @c['range'] = \"bytes=#{s}\"\n    assert_equal r, Array(@c.range)[0]\n  end\n\n  def test_range=\n    @c.range = 0..499\n    assert_equal 'bytes=0-499', @c['range']\n    @c.range = 0...500\n    assert_equal 'bytes=0-499', @c['range']\n    @c.range = 300\n    assert_equal 'bytes=0-299', @c['range']\n    @c.range = -400\n    assert_equal 'bytes=-400', @c['range']\n    @c.set_range 0, 500\n    assert_equal 'bytes=0-499', @c['range']\n  end\n\n  def test_content_range\n  end\n\n  def test_range_length\n    @c['Content-Range'] = \"bytes 0-499/1000\"\n    assert_equal 500, @c.range_length\n    @c['Content-Range'] = \"bytes 1-500/1000\"\n    assert_equal 500, @c.range_length\n    @c['Content-Range'] = \"bytes 1-1/1000\"\n    assert_equal 1, @c.range_length\n  end\n\n  def test_chunked?\n    try_chunked true, 'chunked'\n    try_chunked true, '  chunked  '\n    try_chunked true, '(OK)chunked'\n\n    try_chunked false, 'not-chunked'\n    try_chunked false, 'chunked-but-not-chunked'\n  end\n\n  def try_chunked(bool, str)\n    @c['transfer-encoding'] = str\n    assert_equal bool, @c.chunked?\n  end\n\n  def test_content_length\n    @c.delete('content-length')\n    assert_nil @c['content-length']\n\n    try_content_length 500, '500'\n    try_content_length 10000_0000_0000, '1000000000000'\n    try_content_length 123, '  123'\n    try_content_length 1,   '1 23'\n    try_content_length 500, '(OK)500'\n    assert_raises(Net::HTTPHeaderSyntaxError, 'here is no digit, but') {\n      @c['content-length'] = 'no digit'\n      @c.content_length\n    }\n  end\n\n  def try_content_length(len, str)\n    @c['content-length'] = str\n    assert_equal len, @c.content_length\n  end\n\n  def test_content_length=\n    @c.content_length = 0\n    assert_equal 0, @c.content_length\n    @c.content_length = 1\n    assert_equal 1, @c.content_length\n    @c.content_length = 999\n    assert_equal 999, @c.content_length\n    @c.content_length = 10000000000000\n    assert_equal 10000000000000, @c.content_length\n  end\n\n  def test_content_type\n    assert_nil @c.content_type\n    @c.content_type = 'text/html'\n    assert_equal 'text/html', @c.content_type\n    @c.content_type = 'application/pdf'\n    assert_equal 'application/pdf', @c.content_type\n    @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}\n    assert_equal 'text/html', @c.content_type\n    @c.content_type = 'text'\n    assert_equal 'text', @c.content_type\n  end\n\n  def test_main_type\n    assert_nil @c.main_type\n    @c.content_type = 'text/html'\n    assert_equal 'text', @c.main_type\n    @c.content_type = 'application/pdf'\n    assert_equal 'application', @c.main_type\n    @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}\n    assert_equal 'text', @c.main_type\n    @c.content_type = 'text'\n    assert_equal 'text', @c.main_type\n  end\n\n  def test_sub_type\n    assert_nil @c.sub_type\n    @c.content_type = 'text/html'\n    assert_equal 'html', @c.sub_type\n    @c.content_type = 'application/pdf'\n    assert_equal 'pdf', @c.sub_type\n    @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}\n    assert_equal 'html', @c.sub_type\n    @c.content_type = 'text'\n    assert_nil @c.sub_type\n  end\n\n  def test_type_params\n    assert_equal({}, @c.type_params)\n    @c.content_type = 'text/html'\n    assert_equal({}, @c.type_params)\n    @c.content_type = 'application/pdf'\n    assert_equal({}, @c.type_params)\n    @c.set_content_type 'text/html', {'charset' => 'iso-2022-jp'}\n    assert_equal({'charset' => 'iso-2022-jp'}, @c.type_params)\n    @c.content_type = 'text'\n    assert_equal({}, @c.type_params)\n  end\n\n  def test_set_content_type\n  end\n\n  def test_form_data=\n    @c.form_data = {\"cmd\"=>\"search\", \"q\"=>\"ruby\", \"max\"=>\"50\"}\n    assert_equal 'application/x-www-form-urlencoded', @c.content_type\n    assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split('&').sort\n  end\n\n  def test_set_form_data\n    @c.set_form_data \"cmd\"=>\"search\", \"q\"=>\"ruby\", \"max\"=>\"50\"\n    assert_equal 'application/x-www-form-urlencoded', @c.content_type\n    assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split('&').sort\n\n    @c.set_form_data \"cmd\"=>\"search\", \"q\"=>\"ruby\", \"max\"=>50\n    assert_equal 'application/x-www-form-urlencoded', @c.content_type\n    assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split('&').sort\n\n    @c.set_form_data({\"cmd\"=>\"search\", \"q\"=>\"ruby\", \"max\"=>\"50\"}, ';')\n    assert_equal 'application/x-www-form-urlencoded', @c.content_type\n    assert_equal %w( cmd=search max=50 q=ruby ), @c.body.split(';').sort\n  end\n\n  def test_basic_auth\n  end\n\n  def test_proxy_basic_auth\n  end\n\nend\n"
  },
  {
    "path": "test/net/http/test_https_proxy.rb",
    "content": "begin\n  require 'net/https'\nrescue LoadError\nend\nrequire 'test/unit'\n\nclass HTTPSProxyTest < Test::Unit::TestCase\n  def test_https_proxy_authentication\n    t = nil\n    TCPServer.open(\"127.0.0.1\", 0) {|serv|\n      _, port, _, _ = serv.addr\n      t = Thread.new {\n        proxy = Net::HTTP.Proxy(\"127.0.0.1\", port, 'user', 'password')\n        http = proxy.new(\"foo.example.org\", 8000)\n        http.use_ssl = true\n        http.verify_mode = OpenSSL::SSL::VERIFY_NONE\n        begin\n          http.start\n        rescue EOFError\n        end\n      }\n      sock = serv.accept\n      proxy_request = sock.gets(\"\\r\\n\\r\\n\")\n      assert_equal(\n        \"CONNECT foo.example.org:8000 HTTP/1.1\\r\\n\" +\n        \"Host: foo.example.org:8000\\r\\n\" +\n        \"Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==\\r\\n\" +\n        \"\\r\\n\",\n        proxy_request,\n        \"[ruby-dev:25673]\")\n      sock.close\n    }\n  ensure\n    t.join if t\n  end\nend if defined?(OpenSSL)\n \n"
  },
  {
    "path": "test/net/imap/test_imap.rb",
    "content": "require \"net/imap\"\nrequire \"test/unit\"\n\nclass IMAPTest < Test::Unit::TestCase\n  def test_parse_nomodesq\n    parser = Net::IMAP::ResponseParser.new\n    r = parser.parse(%Q'* OK [NOMODSEQ] Sorry, modsequences have not been enabled on this mailbox\\r\\n')\n    assert_equal(\"OK\", r.name)\n    assert_equal(\"NOMODSEQ\", r.data.code.name)\n  end\nend\n"
  },
  {
    "path": "test/net/pop/test_pop.rb",
    "content": "require 'net/pop'\nrequire 'test/unit'\nrequire 'digest/md5'\n\nclass TestPOP < Test::Unit::TestCase\n  def setup\n    @users = {'user' => 'pass' }\n    @ok_user = 'user'\n    @stamp_base = \"#{$$}.#{Time.now.to_i}@localhost\"\n  end\n\n  def test_pop_auth_ok\n    pop_test(false) do |pop|\n      assert_instance_of Net::POP3, pop\n      assert_nothing_raised do\n        pop.start(@ok_user, @users[@ok_user])\n      end\n    end\n  end\n\n  def test_pop_auth_ng\n    pop_test(false) do |pop|\n      assert_instance_of Net::POP3, pop\n      assert_raise Net::POPAuthenticationError do\n        pop.start(@ok_user, 'bad password')\n      end\n    end\n  end\n\n  def test_apop_ok\n    pop_test(@stamp_base) do |pop|\n      assert_instance_of Net::APOP, pop\n      assert_nothing_raised do\n        pop.start(@ok_user, @users[@ok_user])\n      end\n    end\n  end\n\n  def test_apop_ng\n    pop_test(@stamp_base) do |pop|\n      assert_instance_of Net::APOP, pop\n      assert_raise Net::POPAuthenticationError do\n        pop.start(@ok_user, 'bad password')\n      end\n    end\n  end\n\n  def test_apop_invalid\n    pop_test(\"\\x80\"+@stamp_base) do |pop|\n      assert_instance_of Net::APOP, pop\n      assert_raise Net::POPAuthenticationError do\n        pop.start(@ok_user, @users[@ok_user])\n      end\n    end\n  end\n\n  def test_apop_invalid_at\n    pop_test(@stamp_base.sub('@', '.')) do |pop|\n      assert_instance_of Net::APOP, pop\n      e = assert_raise Net::POPAuthenticationError do\n        pop.start(@ok_user, @users[@ok_user])\n      end\n    end\n  end\n\n  def pop_test(apop=false)\n    host = 'localhost'\n    server = TCPServer.new(host, 0)\n    port = server.addr[1]\n    thread = Thread.start do\n      sock = server.accept\n      begin\n        pop_server_loop(sock, apop)\n      ensure\n        sock.close\n      end\n    end\n    begin\n      pop = Net::POP3::APOP(apop).new(host, port)\n      #pop.set_debug_output $stderr\n      yield pop\n    ensure\n      begin\n        pop.finish\n      rescue IOError\n        raise unless $!.message == \"POP session not yet started\"\n      end\n    end\n  ensure\n    server.close\n    thread.value\n  end\n\n  def pop_server_loop(sock, apop)\n    if apop\n      sock.print \"+OK ready <#{apop}>\\r\\n\"\n    else\n      sock.print \"+OK ready\\r\\n\"\n    end\n    user = nil\n    while line = sock.gets\n      case line\n      when /^USER (.+)\\r\\n/\n        user = $1\n        if @users.key?(user)\n          sock.print \"+OK\\r\\n\"\n        else\n          sock.print \"-ERR unknown user\\r\\n\"\n        end\n      when /^PASS (.+)\\r\\n/\n        if @users[user] == $1\n          sock.print \"+OK\\r\\n\"\n        else\n          sock.print \"-ERR invalid password\\r\\n\"\n        end\n      when /^APOP (.+) (.+)\\r\\n/\n        user = $1\n        if apop && Digest::MD5.hexdigest(\"<#{apop}>#{@users[user]}\") == $2\n          sock.print \"+OK\\r\\n\"\n        else\n          sock.print \"-ERR authentication failed\\r\\n\"\n        end\n      when /^QUIT/\n        sock.print \"+OK bye\\r\\n\"\n        return\n      else\n        sock.print \"-ERR command not recognized\\r\\n\"\n        return\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/nkf/test_kconv.rb",
    "content": "require 'test/unit'\nrequire 'kconv'\n\nclass TestKconv < Test::Unit::TestCase\n  EUC_STR = \"\\\n\\xa5\\xaa\\xa5\\xd6\\xa5\\xb8\\xa5\\xa7\\xa5\\xaf\\xa5\\xc8\\xbb\\xd8\\xb8\\xfe\\\n\\xa5\\xd7\\xa5\\xed\\xa5\\xb0\\xa5\\xe9\\xa5\\xdf\\xa5\\xf3\\xa5\\xb0\\xb8\\xc0\\xb8\\xec\n\\x52\\x75\\x62\\x79\"\n  UTF8_STR = \"\\\n\\xe3\\x82\\xaa\\xe3\\x83\\x96\\xe3\\x82\\xb8\\xe3\\x82\\xa7\\\n\\xe3\\x82\\xaf\\xe3\\x83\\x88\\xe6\\x8c\\x87\\xe5\\x90\\x91\\\n\\xe3\\x83\\x97\\xe3\\x83\\xad\\xe3\\x82\\xb0\\xe3\\x83\\xa9\\xe3\\x83\\x9f\\\n\\xe3\\x83\\xb3\\xe3\\x82\\xb0\\xe8\\xa8\\x80\\xe8\\xaa\\x9e\n\\x52\\x75\\x62\\x79\"\n  SJIS_STR = \"\\\n\\x83\\x49\\x83\\x75\\x83\\x57\\x83\\x46\\x83\\x4e\\x83\\x67\\x8e\\x77\\x8c\\xfc\\\n\\x83\\x76\\x83\\x8d\\x83\\x4f\\x83\\x89\\x83\\x7e\\x83\\x93\\x83\\x4f\\x8c\\xbe\\x8c\\xea\n\\x52\\x75\\x62\\x79\"\n  JIS_STR = \"\\\n\\x1b\\x24\\x42\\x25\\x2a\\x25\\x56\\x25\\x38\\x25\\x27\\x25\\x2f\\x25\\x48\\x3b\\x58\\x38\\x7e\\\n\\x25\\x57\\x25\\x6d\\x25\\x30\\x25\\x69\\x25\\x5f\\x25\\x73\\x25\\x30\\x38\\x40\\x38\\x6c\\x1b\\x28\\x42\n\\x52\\x75\\x62\\x79\"\n\n  def test_eucjp\n    assert(EUC_STR.iseuc)\n    assert_equal(::Kconv::EUC, Kconv.guess(EUC_STR))\n    assert_equal(EUC_STR, EUC_STR.toeuc)\n    assert_equal(EUC_STR, SJIS_STR.toeuc)\n    assert_equal(EUC_STR, UTF8_STR.toeuc)\n    assert_equal(EUC_STR, JIS_STR.toeuc)\n    assert_equal(EUC_STR, EUC_STR.kconv(::NKF::EUC))\n    assert_equal(EUC_STR, SJIS_STR.kconv(::NKF::EUC))\n    assert_equal(EUC_STR, UTF8_STR.kconv(::NKF::EUC))\n    assert_equal(EUC_STR, JIS_STR.kconv(::NKF::EUC))\n  end\n  def test_shiftjis\n    assert(SJIS_STR.issjis)\n    assert_equal(::Kconv::SJIS, Kconv.guess(SJIS_STR))\n    assert_equal(SJIS_STR, EUC_STR.tosjis)\n    assert_equal(SJIS_STR, SJIS_STR.tosjis)\n    assert_equal(SJIS_STR, UTF8_STR.tosjis)\n    assert_equal(SJIS_STR, JIS_STR.tosjis)\n    assert_equal(SJIS_STR, EUC_STR.kconv(::NKF::SJIS))\n    assert_equal(SJIS_STR, SJIS_STR.kconv(::NKF::SJIS))\n    assert_equal(SJIS_STR, UTF8_STR.kconv(::NKF::SJIS))\n    assert_equal(SJIS_STR, JIS_STR.kconv(::NKF::SJIS))\n  end\n  def test_utf8\n    assert(UTF8_STR.isutf8)\n    assert_equal(::Kconv::UTF8, Kconv.guess(UTF8_STR))\n    assert_equal(UTF8_STR, EUC_STR.toutf8)\n    assert_equal(UTF8_STR, SJIS_STR.toutf8)\n    assert_equal(UTF8_STR, UTF8_STR.toutf8)\n    assert_equal(UTF8_STR, JIS_STR.toutf8)\n    assert_equal(UTF8_STR, EUC_STR.kconv(::NKF::UTF8))\n    assert_equal(UTF8_STR, SJIS_STR.kconv(::NKF::UTF8))\n    assert_equal(UTF8_STR, UTF8_STR.kconv(::NKF::UTF8))\n    assert_equal(UTF8_STR, JIS_STR.kconv(::NKF::UTF8))\n  end\n  def test_jis\n    assert_equal(::Kconv::JIS, Kconv.guess(JIS_STR))\n    assert_equal(JIS_STR, EUC_STR.tojis)\n    assert_equal(JIS_STR, SJIS_STR.tojis)\n    assert_equal(JIS_STR, UTF8_STR.tojis)\n    assert_equal(JIS_STR, JIS_STR.tojis)\n    assert_equal(JIS_STR, EUC_STR.kconv(::NKF::JIS))\n    assert_equal(JIS_STR, SJIS_STR.kconv(::NKF::JIS))\n    assert_equal(JIS_STR, UTF8_STR.kconv(::NKF::JIS))\n    assert_equal(JIS_STR, JIS_STR.kconv(::NKF::JIS))\n  end\nend\n"
  },
  {
    "path": "test/nkf/test_nkf.rb",
    "content": "require 'test/unit'\nrequire 'nkf'\n\nclass TestNKF < Test::Unit::TestCase\n  EUC_STR = \"\\xa5\\xaa\\xa5\\xd6\\xa5\\xb8\\xa5\\xa7\\xa5\\xaf\\xa5\\xc8\\xbb\\xd8\\xb8\\xfe\\\n\\xa5\\xb9\\xa5\\xaf\\xa5\\xea\\xa5\\xd7\\xa5\\xc8\\xb8\\xc0\\xb8\\xec\\\nRuby\"\n\n  def test_guess\n    str_euc = EUC_STR\n    str_jis = NKF.nkf('-j', str_euc)\n    assert_equal(::NKF::JIS, NKF.guess(str_jis))\n    assert_equal(::NKF::EUC, NKF.guess(str_euc))\n  end\n\nend\n"
  },
  {
    "path": "test/openssl/ssl_server.rb",
    "content": "require \"socket\"\nrequire \"thread\"\nrequire \"openssl\"\nrequire File.join(File.dirname(__FILE__), \"utils.rb\")\n\ndef get_pem(io=$stdin)\n  buf = \"\"\n  while line = io.gets\n    if /^-----BEGIN / =~ line\n      buf << line\n      break\n    end\n  end\n  while line = io.gets\n    buf << line\n    if /^-----END / =~ line\n      break\n    end\n  end\n  return buf\nend\n\ndef make_key(pem)\n  begin\n    return OpenSSL::PKey::RSA.new(pem)\n  rescue\n    return OpenSSL::PKey::DSA.new(pem)\n  end\nend\n\nca_cert  = OpenSSL::X509::Certificate.new(get_pem)\nssl_cert = OpenSSL::X509::Certificate.new(get_pem)\nssl_key  = make_key(get_pem)\nport = Integer(ARGV.shift)\nverify_mode = Integer(ARGV.shift)\nstart_immediately = (/yes/ =~ ARGV.shift)\n\nstore = OpenSSL::X509::Store.new\nstore.add_cert(ca_cert)\nstore.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT\nctx = OpenSSL::SSL::SSLContext.new\nctx.cert_store = store\n#ctx.extra_chain_cert = [ ca_cert ]\nctx.cert = ssl_cert\nctx.key = ssl_key\nctx.verify_mode = verify_mode\n\nSocket.do_not_reverse_lookup = true\ntcps = nil\n100.times{|i|\n  begin\n    tcps = TCPServer.new(\"0.0.0.0\", port+i)\n    port = port + i\n    break\n  rescue Errno::EADDRINUSE\n    next \n  end\n}\nssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)\nssls.start_immediately = start_immediately\n\n$stdout.sync = true\n$stdout.puts Process.pid\n$stdout.puts port\n\nloop do\n  ssl = ssls.accept rescue next\n  Thread.start{\n    q = Queue.new\n    th = Thread.start{ ssl.write(q.shift) while true }\n    while line = ssl.gets\n      if line =~ /^STARTTLS$/\n        ssl.accept\n        next\n      end\n      q.push(line)\n    end\n    th.kill if q.empty?\n    ssl.close\n  }\nend\n"
  },
  {
    "path": "test/openssl/test_asn1.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire 'test/unit'\n\nclass  OpenSSL::TestASN1 < Test::Unit::TestCase\n  def test_decode\n    subj = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=TestCA\")\n    key = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    now = Time.at(Time.now.to_i) # suppress usec\n    s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf\n    exts = [\n      [\"basicConstraints\",\"CA:TRUE,pathlen:1\",true],\n      [\"keyUsage\",\"keyCertSign, cRLSign\",true],\n      [\"subjectKeyIdentifier\",\"hash\",false],\n    ]\n    dgst = OpenSSL::Digest::SHA1.new\n    cert = OpenSSL::TestUtils.issue_cert(\n      subj, key, s, now, now+3600, exts, nil, nil, dgst)\n\n\n    asn1 = OpenSSL::ASN1.decode(cert)\n    assert_equal(OpenSSL::ASN1::Sequence, asn1.class)\n    assert_equal(3, asn1.value.size)\n    tbs_cert, sig_alg, sig_val = *asn1.value\n\n    assert_equal(OpenSSL::ASN1::Sequence, tbs_cert.class)\n    assert_equal(8, tbs_cert.value.size)\n\n    version = tbs_cert.value[0]\n    assert_equal(:CONTEXT_SPECIFIC, version.tag_class)\n    assert_equal(0, version.tag)\n    assert_equal(1, version.value.size)\n    assert_equal(OpenSSL::ASN1::Integer, version.value[0].class)\n    assert_equal(2, version.value[0].value)\n\n    serial = tbs_cert.value[1]\n    assert_equal(OpenSSL::ASN1::Integer, serial.class)\n    assert_equal(0xdeadbeafdeadbeafdeadbeafdeadbeaf, serial.value)\n\n    sig = tbs_cert.value[2]\n    assert_equal(OpenSSL::ASN1::Sequence, sig.class)\n    assert_equal(2, sig.value.size)\n    assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class)\n    assert_equal(\"1.2.840.113549.1.1.5\", sig.value[0].oid)\n    assert_equal(OpenSSL::ASN1::Null, sig.value[1].class)\n\n    dn = tbs_cert.value[3] # issuer\n    assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.class)\n    assert_equal(3, dn.value.size)\n    assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)\n    assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)\n    assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)\n    assert_equal(1, dn.value[0].value.size)\n    assert_equal(1, dn.value[1].value.size)\n    assert_equal(1, dn.value[2].value.size)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)\n    assert_equal(2, dn.value[0].value[0].value.size)\n    assert_equal(2, dn.value[1].value[0].value.size)\n    assert_equal(2, dn.value[2].value[0].value.size)\n    oid, value = *dn.value[0].value[0].value\n    assert_equal(OpenSSL::ASN1::ObjectId, oid.class)\n    assert_equal(\"0.9.2342.19200300.100.1.25\", oid.oid)\n    assert_equal(OpenSSL::ASN1::IA5String, value.class)\n    assert_equal(\"org\", value.value)\n    oid, value = *dn.value[1].value[0].value\n    assert_equal(OpenSSL::ASN1::ObjectId, oid.class)\n    assert_equal(\"0.9.2342.19200300.100.1.25\", oid.oid)\n    assert_equal(OpenSSL::ASN1::IA5String, value.class)\n    assert_equal(\"ruby-lang\", value.value)\n    oid, value = *dn.value[2].value[0].value\n    assert_equal(OpenSSL::ASN1::ObjectId, oid.class)\n    assert_equal(\"2.5.4.3\", oid.oid)\n    assert_equal(OpenSSL::ASN1::UTF8String, value.class)\n    assert_equal(\"TestCA\", value.value)\n\n    validity = tbs_cert.value[4]\n    assert_equal(OpenSSL::ASN1::Sequence, validity.class)\n    assert_equal(2, validity.value.size)\n    assert_equal(OpenSSL::ASN1::UTCTime, validity.value[0].class)\n    assert_equal(now, validity.value[0].value)\n    assert_equal(OpenSSL::ASN1::UTCTime, validity.value[1].class)\n    assert_equal(now+3600, validity.value[1].value)\n\n    dn = tbs_cert.value[5] # subject\n    assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.class)\n    assert_equal(3, dn.value.size)\n    assert_equal(OpenSSL::ASN1::Set, dn.value[0].class)\n    assert_equal(OpenSSL::ASN1::Set, dn.value[1].class)\n    assert_equal(OpenSSL::ASN1::Set, dn.value[2].class)\n    assert_equal(1, dn.value[0].value.size)\n    assert_equal(1, dn.value[1].value.size)\n    assert_equal(1, dn.value[2].value.size)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class)\n    assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class)\n    assert_equal(2, dn.value[0].value[0].value.size)\n    assert_equal(2, dn.value[1].value[0].value.size)\n    assert_equal(2, dn.value[2].value[0].value.size)\n    oid, value = *dn.value[0].value[0].value\n    assert_equal(OpenSSL::ASN1::ObjectId, oid.class)\n    assert_equal(\"0.9.2342.19200300.100.1.25\", oid.oid)\n    assert_equal(OpenSSL::ASN1::IA5String, value.class)\n    assert_equal(\"org\", value.value)\n    oid, value = *dn.value[1].value[0].value\n    assert_equal(OpenSSL::ASN1::ObjectId, oid.class)\n    assert_equal(\"0.9.2342.19200300.100.1.25\", oid.oid)\n    assert_equal(OpenSSL::ASN1::IA5String, value.class)\n    assert_equal(\"ruby-lang\", value.value)\n    oid, value = *dn.value[2].value[0].value\n    assert_equal(OpenSSL::ASN1::ObjectId, oid.class)\n    assert_equal(\"2.5.4.3\", oid.oid)\n    assert_equal(OpenSSL::ASN1::UTF8String, value.class)\n    assert_equal(\"TestCA\", value.value)\n\n    pkey = tbs_cert.value[6]\n    assert_equal(OpenSSL::ASN1::Sequence, pkey.class)\n    assert_equal(2, pkey.value.size)\n    assert_equal(OpenSSL::ASN1::Sequence, pkey.value[0].class)\n    assert_equal(2, pkey.value[0].value.size)\n    assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)\n    assert_equal(\"1.2.840.113549.1.1.1\", pkey.value[0].value[0].oid)\n    assert_equal(OpenSSL::ASN1::BitString, pkey.value[1].class)\n    assert_equal(0, pkey.value[1].unused_bits)\n    spkey = OpenSSL::ASN1.decode(pkey.value[1].value)\n    assert_equal(OpenSSL::ASN1::Sequence, spkey.class)\n    assert_equal(2, spkey.value.size)\n    assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class)\n    assert_equal(143085709396403084580358323862163416700436550432664688288860593156058579474547937626086626045206357324274536445865308750491138538454154232826011964045825759324933943290377903384882276841880081931690695505836279972214003660451338124170055999155993192881685495391496854691199517389593073052473319331505702779271, spkey.value[0].value)\n    assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class)\n    assert_equal(65537, spkey.value[1].value)\n\n    extensions = tbs_cert.value[7]\n    assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class)\n    assert_equal(3, extensions.tag)\n    assert_equal(1, extensions.value.size)\n    assert_equal(OpenSSL::ASN1::Sequence, extensions.value[0].class)\n    assert_equal(3, extensions.value[0].value.size)\n\n    ext = extensions.value[0].value[0]  # basicConstraints\n    assert_equal(OpenSSL::ASN1::Sequence, ext.class)\n    assert_equal(3, ext.value.size)\n    assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)\n    assert_equal(\"2.5.29.19\",  ext.value[0].oid)\n    assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)\n    assert_equal(true, ext.value[1].value)\n    assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)\n    extv = OpenSSL::ASN1.decode(ext.value[2].value)\n    assert_equal(OpenSSL::ASN1::Sequence, extv.class)\n    assert_equal(2, extv.value.size)\n    assert_equal(OpenSSL::ASN1::Boolean, extv.value[0].class)\n    assert_equal(true, extv.value[0].value)\n    assert_equal(OpenSSL::ASN1::Integer, extv.value[1].class)\n    assert_equal(1, extv.value[1].value)\n\n    ext = extensions.value[0].value[1]  # keyUsage\n    assert_equal(OpenSSL::ASN1::Sequence, ext.class)\n    assert_equal(3, ext.value.size)\n    assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)\n    assert_equal(\"2.5.29.15\",  ext.value[0].oid)\n    assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class)\n    assert_equal(true, ext.value[1].value)\n    assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class)\n    extv = OpenSSL::ASN1.decode(ext.value[2].value)\n    assert_equal(OpenSSL::ASN1::BitString, extv.class)\n    str = \"\\000\"; str[0] = 0b00000110\n    assert_equal(str, extv.value)\n\n    ext = extensions.value[0].value[2]  # subjetKeyIdentifier\n    assert_equal(OpenSSL::ASN1::Sequence, ext.class)\n    assert_equal(2, ext.value.size)\n    assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class)\n    assert_equal(\"2.5.29.14\",  ext.value[0].oid)\n    assert_equal(OpenSSL::ASN1::OctetString, ext.value[1].class)\n    extv = OpenSSL::ASN1.decode(ext.value[1].value)\n    assert_equal(OpenSSL::ASN1::OctetString, extv.class)\n    sha1 = OpenSSL::Digest::SHA1.new\n    sha1.update(pkey.value[1].value)\n    assert_equal(sha1.digest, extv.value)\n\n    assert_equal(OpenSSL::ASN1::Sequence, sig_alg.class)\n    assert_equal(2, sig_alg.value.size)\n    assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class)\n    assert_equal(\"1.2.840.113549.1.1.1\", pkey.value[0].value[0].oid)\n    assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class)\n\n    assert_equal(OpenSSL::ASN1::BitString, sig_val.class)\n    cululated_sig = key.sign(OpenSSL::Digest::SHA1.new, tbs_cert.to_der)\n    assert_equal(cululated_sig, sig_val.value)\n  end\nend if defined?(OpenSSL)\n"
  },
  {
    "path": "test/openssl/test_cipher.rb",
    "content": "begin\n  require \"openssl\"\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestCipher < Test::Unit::TestCase\n  def setup\n    @c1 = OpenSSL::Cipher::Cipher.new(\"DES-EDE3-CBC\")\n    @c2 = OpenSSL::Cipher::DES.new(:EDE3, \"CBC\")\n    @key = \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n    @iv = \"\\0\\0\\0\\0\\0\\0\\0\\0\"\n    @hexkey = \"0000000000000000000000000000000000000000000000\"\n    @hexiv = \"0000000000000000\"\n    @data = \"DATA\"\n  end\n\n  def teardown\n    @c1 = @c2 = nil\n  end\n\n  def test_crypt\n    @c1.encrypt.pkcs5_keyivgen(@key, @iv)\n    @c2.encrypt.pkcs5_keyivgen(@key, @iv)\n    s1 = @c1.update(@data) + @c1.final\n    s2 = @c2.update(@data) + @c2.final\n    assert_equal(s1, s2, \"encrypt\")\n\n    @c1.decrypt.pkcs5_keyivgen(@key, @iv)\n    @c2.decrypt.pkcs5_keyivgen(@key, @iv)\n    assert_equal(@data, @c1.update(s1)+@c1.final, \"decrypt\")\n    assert_equal(@data, @c2.update(s2)+@c2.final, \"decrypt\")\n  end\n\n  def test_info\n    assert_equal(\"DES-EDE3-CBC\", @c1.name, \"name\")\n    assert_equal(\"DES-EDE3-CBC\", @c2.name, \"name\")\n    assert_kind_of(Fixnum, @c1.key_len, \"key_len\")\n    assert_kind_of(Fixnum, @c1.iv_len, \"iv_len\")\n  end\n\n  def test_dup\n    assert_equal(@c1.name, @c1.dup.name, \"dup\")\n    assert_equal(@c1.name, @c1.clone.name, \"clone\")\n    @c1.encrypt\n    @c1.key = @key\n    @c1.iv = @iv\n    tmpc = @c1.dup\n    s1 = @c1.update(@data) + @c1.final\n    s2 = tmpc.update(@data) + tmpc.final\n    assert_equal(s1, s2, \"encrypt dup\")\n  end\n\n  def test_reset\n    @c1.encrypt\n    @c1.key = @key\n    @c1.iv = @iv\n    s1 = @c1.update(@data) + @c1.final\n    @c1.reset\n    s2 = @c1.update(@data) + @c1.final\n    assert_equal(s1, s2, \"encrypt reset\")\n  end\n\n  def test_empty_data\n    @c1.encrypt\n    assert_raises(ArgumentError){ @c1.update(\"\") }\n  end\n\n  if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00907000\n    def test_ciphers\n      OpenSSL::Cipher.ciphers.each{|name|\n        assert(OpenSSL::Cipher::Cipher.new(name).is_a?(OpenSSL::Cipher::Cipher))\n      }\n    end\n\n    def test_AES\n      pt = File.read(__FILE__)\n      %w(ECB CBC CFB OFB).each{|mode|\n        c1 = OpenSSL::Cipher::AES256.new(mode)\n        c1.encrypt\n        c1.pkcs5_keyivgen(\"passwd\")\n        ct = c1.update(pt) + c1.final\n\n        c2 = OpenSSL::Cipher::AES256.new(mode)\n        c2.decrypt\n        c2.pkcs5_keyivgen(\"passwd\")\n        assert_equal(pt, c2.update(ct) + c2.final)\n      }\n    end\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_digest.rb",
    "content": "begin\n  require \"openssl\"\nrescue LoadError\nend\nrequire \"digest/md5\"\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestDigest < Test::Unit::TestCase\n  def setup\n    @d1 = OpenSSL::Digest::Digest::new(\"MD5\")\n    @d2 = OpenSSL::Digest::MD5.new\n    @md = Digest::MD5.new\n    @data = \"DATA\"\n  end\n\n  def teardown\n    @d1 = @d2 = @md = nil\n  end\n\n  def test_digest\n    assert_equal(@md.digest, @d1.digest)\n    assert_equal(@md.hexdigest, @d1.hexdigest)\n    @d1 << @data\n    @d2 << @data\n    @md << @data\n    assert_equal(@md.digest, @d1.digest)\n    assert_equal(@md.hexdigest, @d1.hexdigest)\n    assert_equal(@d1.digest, @d2.digest)\n    assert_equal(@d1.hexdigest, @d2.hexdigest)\n    assert_equal(@md.digest, OpenSSL::Digest::MD5.digest(@data))\n    assert_equal(@md.hexdigest, OpenSSL::Digest::MD5.hexdigest(@data))\n  end\n\n  def test_eql\n    assert(@d1 == @d2, \"==\")\n    d = @d1.clone\n    assert(d == @d1, \"clone\")\n  end\n\n  def test_info\n    assert_equal(\"MD5\", @d1.name, \"name\")\n    assert_equal(\"MD5\", @d2.name, \"name\")\n    assert_equal(16, @d1.size, \"size\")\n  end\n\n  def test_dup\n    @d1.update(@data)\n    assert_equal(@d1.name, @d1.dup.name, \"dup\")\n    assert_equal(@d1.name, @d1.clone.name, \"clone\")\n    assert_equal(@d1.digest, @d1.clone.digest, \"clone .digest\")\n  end\n\n  def test_reset\n    @d1.update(@data)\n    dig1 = @d1.digest\n    @d1.reset\n    @d1.update(@data)\n    dig2 = @d1.digest\n    assert_equal(dig1, dig2, \"reset\")\n  end\n\n  if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000\n    def encode16(str)\n      str.unpack(\"H*\").first\n    end\n\n    def test_098_features\n      sha224_a = \"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5\"\n      sha256_a = \"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb\"\n      sha384_a = \"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31\"\n      sha512_a = \"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75\"\n\n      assert_equal(sha224_a, OpenSSL::Digest::SHA224.hexdigest(\"a\"))\n      assert_equal(sha256_a, OpenSSL::Digest::SHA256.hexdigest(\"a\"))\n      assert_equal(sha384_a, OpenSSL::Digest::SHA384.hexdigest(\"a\"))\n      assert_equal(sha512_a, OpenSSL::Digest::SHA512.hexdigest(\"a\"))\n\n      assert_equal(sha224_a, encode16(OpenSSL::Digest::SHA224.digest(\"a\")))\n      assert_equal(sha256_a, encode16(OpenSSL::Digest::SHA256.digest(\"a\")))\n      assert_equal(sha384_a, encode16(OpenSSL::Digest::SHA384.digest(\"a\")))\n      assert_equal(sha512_a, encode16(OpenSSL::Digest::SHA512.digest(\"a\")))\n    end\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_ec.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL::PKey::EC)\n\nclass OpenSSL::TestEC < Test::Unit::TestCase\n  def setup\n    @data1 = 'foo'\n    @data2 = 'bar' * 1000 # data too long for DSA sig\n\n    @group1 = OpenSSL::PKey::EC::Group.new('secp112r1')\n    @group2 = OpenSSL::PKey::EC::Group.new('sect163k1')\n\n    @key1 = OpenSSL::PKey::EC.new\n    @key1.group = @group1\n    @key1.generate_key\n\n    @key2 = OpenSSL::PKey::EC.new(@group2.curve_name)\n    @key2.generate_key\n\n    @groups = [@group1, @group2]\n    @keys = [@key1, @key2]\n  end\n\n  def compare_keys(k1, k2)\n    assert_equal(k1.to_pem, k2.to_pem)\n  end\n\n  def test_curve_names\n    @groups.each_with_index do |group, idx|\n      key = @keys[idx]\n      assert_equal(group.curve_name, key.group.curve_name)\n    end\n  end\n\n  def test_check_key\n    for key in @keys\n      assert_equal(key.check_key, true)\n      assert_equal(key.private_key?, true)\n      assert_equal(key.public_key?, true)\n    end\n  end\n\n  def test_encoding\n    for group in @groups\n      for meth in [:to_der, :to_pem]\n        txt = group.send(meth)\n        gr = OpenSSL::PKey::EC::Group.new(txt)\n        assert_equal(txt, gr.send(meth))\n\n        assert_equal(group.generator.to_bn, gr.generator.to_bn)\n        assert_equal(group.cofactor, gr.cofactor)\n        assert_equal(group.order, gr.order)\n        assert_equal(group.seed, gr.seed)\n        assert_equal(group.degree, gr.degree)\n      end\n    end\n\n    for key in @keys\n      group = key.group\n\n      for meth in [:to_der, :to_pem]\n        txt = key.send(meth)\n        assert_equal(txt, OpenSSL::PKey::EC.new(txt).send(meth))\n      end\n\n      bn = key.public_key.to_bn\n      assert_equal(bn, OpenSSL::PKey::EC::Point.new(group, bn).to_bn)\n    end\n  end\n\n  def test_set_keys\n    for key in @keys\n      k = OpenSSL::PKey::EC.new\n      k.group = key.group\n      k.private_key = key.private_key\n      k.public_key = key.public_key\n\n      compare_keys(key, k)\n    end\n  end\n\n  def test_dsa_sign_verify\n    for key in @keys\n      sig = key.dsa_sign_asn1(@data1)\n      assert_equal(key.dsa_verify_asn1(@data1, sig), true)\n        \n      assert_raises(OpenSSL::PKey::ECError) { key.dsa_sign_asn1(@data2) }\n    end\n  end\n\n  def test_dh_compute_key\n    for key in @keys\n      k = OpenSSL::PKey::EC.new(key.group)\n      k.generate_key\n\n      puba = key.public_key\n      pubb = k.public_key\n      a = key.dh_compute_key(pubb)\n      b = k.dh_compute_key(puba)\n      assert_equal(a, b)\n    end\n  end\n\n# test Group: asn1_flag, point_conversion\n\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_hmac.rb",
    "content": "begin\n  require \"openssl\"\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestHMAC < Test::Unit::TestCase\n  def setup\n    @digest = OpenSSL::Digest::MD5.new\n    @key = \"KEY\"\n    @data = \"DATA\"\n    @h1 = OpenSSL::HMAC.new(@key, @digest)\n    @h2 = OpenSSL::HMAC.new(@key, @digest)\n  end\n\n  def teardown\n  end\n\n  def test_hmac\n    @h1.update(@data)\n    assert_equal(OpenSSL::HMAC.digest(@digest, @key, @data), @h1.digest, \"digest\")\n    assert_equal(OpenSSL::HMAC.hexdigest(@digest, @key, @data), @h1.hexdigest, \"hexdigest\")\n  end\n\n  def test_dup\n    @h1.update(@data)\n    h = @h1.dup\n    assert_equal(@h1.digest, h.digest, \"dup digest\")\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_ns_spki.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\n\nclass OpenSSL::TestNSSPI < Test::Unit::TestCase\n  def setup\n    # This request data is adopt from the specification of\n    # \"Netscape Extensions for User Key Generation\".\n    # -- http://wp.netscape.com/eng/security/comm4-keygen.html\n    @b64  = \"MIHFMHEwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAnX0TILJrOMUue+PtwBRE6XfV\"\n    @b64 << \"WtKQbsshxk5ZhcUwcwyvcnIq9b82QhJdoACdD34rqfCAIND46fXKQUnb0mvKzQID\"\n    @b64 << \"AQABFhFNb3ppbGxhSXNNeUZyaWVuZDANBgkqhkiG9w0BAQQFAANBAAKv2Eex2n/S\"\n    @b64 << \"r/7iJNroWlSzSMtTiQTEB+ADWHGj9u1xrUrOilq/o2cuQxIfZcNZkYAkWP4DubqW\"\n    @b64 << \"i0//rgBvmco=\"\n  end\n\n  def teardown\n  end\n\n  def test_build_data\n    key1 = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    key2 = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    spki = OpenSSL::Netscape::SPKI.new\n    spki.challenge = \"RandomString\"\n    spki.public_key = key1.public_key\n    spki.sign(key1, OpenSSL::Digest::SHA1.new)\n    assert(spki.verify(spki.public_key))\n    assert(spki.verify(key1.public_key))\n    assert(!spki.verify(key2.public_key))\n\n    der = spki.to_der\n    spki = OpenSSL::Netscape::SPKI.new(der)\n    assert_equal(\"RandomString\", spki.challenge)\n    assert_equal(key1.public_key.to_der, spki.public_key.to_der)\n    assert(spki.verify(spki.public_key))\n  end\n\n  def test_decode_data\n    spki = OpenSSL::Netscape::SPKI.new(@b64)\n    assert_equal(@b64, spki.to_pem)\n    assert_equal(@b64.unpack(\"m\").first, spki.to_der)\n    assert_equal(\"MozillaIsMyFriend\", spki.challenge)\n    assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)\n\n    spki = OpenSSL::Netscape::SPKI.new(@b64.unpack(\"m\").first)\n    assert_equal(@b64, spki.to_pem)\n    assert_equal(@b64.unpack(\"m\").first, spki.to_der)\n    assert_equal(\"MozillaIsMyFriend\", spki.challenge)\n    assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_pair.rb",
    "content": "begin\n  require \"openssl\"\nrescue LoadError\nend\nrequire 'test/unit'\n\nif defined?(OpenSSL)\n\nrequire 'socket'\ndir = File.expand_path(__FILE__)\n2.times {dir = File.dirname(dir)}\n$:.replace([File.join(dir, \"ruby\")] | $:)\nrequire 'ut_eof'\n\nmodule SSLPair\n  def server\n    host = \"127.0.0.1\"\n    port = 0\n    ctx = OpenSSL::SSL::SSLContext.new()\n    ctx.ciphers = \"ADH\"\n    tcps = TCPServer.new(host, port)\n    ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)\n    return ssls\n  end\n\n  def client(port)\n    host = \"127.0.0.1\"\n    ctx = OpenSSL::SSL::SSLContext.new()\n    ctx.ciphers = \"ADH\"\n    s = TCPSocket.new(host, port)\n    ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)\n    ssl.connect\n    ssl.sync_close = true\n    ssl\n  end\n\n  def ssl_pair\n    ssls = server\n    th = Thread.new {\n      ns = ssls.accept\n      ssls.close\n      ns\n    }\n    port = ssls.to_io.addr[1]\n    c = client(port)\n    s = th.value\n    if block_given?\n      begin\n        yield c, s\n      ensure\n        c.close unless c.closed?\n        s.close unless s.closed?\n      end\n    else\n      return c, s\n    end\n  end\nend\n\nclass OpenSSL::TestEOF1 < Test::Unit::TestCase\n  include TestEOF\n  include SSLPair\n\n  def open_file(content)\n    s1, s2 = ssl_pair\n    Thread.new { s2 << content; s2.close }\n    yield s1\n  end\nend\n\nclass OpenSSL::TestEOF2 < Test::Unit::TestCase\n  include TestEOF\n  include SSLPair\n\n  def open_file(content)\n    s1, s2 = ssl_pair\n    Thread.new { s1 << content; s1.close }\n    yield s2\n  end\nend\n\nclass OpenSSL::TestPair < Test::Unit::TestCase\n  include SSLPair\n\n  def test_getc\n    ssl_pair {|s1, s2|\n      s1 << \"a\"\n      assert_equal(?a, s2.getc)\n    }\n  end\n\n  def test_readpartial\n    ssl_pair {|s1, s2|\n      s2.write \"a\\nbcd\"\n      assert_equal(\"a\\n\", s1.gets)\n      assert_equal(\"bcd\", s1.readpartial(10))\n      s2.write \"efg\"\n      assert_equal(\"efg\", s1.readpartial(10))\n      s2.close\n      assert_raise(EOFError) { s1.readpartial(10) }\n      assert_raise(EOFError) { s1.readpartial(10) }\n      assert_equal(\"\", s1.readpartial(0))\n    }\n  end\n\n  def test_readall\n    ssl_pair {|s1, s2|\n      s2.close\n      assert_equal(\"\", s1.read)\n    }\n  end\n\n  def test_readline\n    ssl_pair {|s1, s2|\n      s2.close\n      assert_raise(EOFError) { s1.readline }\n    }\n  end\n\n  def test_puts_meta\n    ssl_pair {|s1, s2|\n      begin\n        old = $/\n        $/ = '*'\n        s1.puts 'a'\n      ensure\n        $/ = old\n      end\n      s1.close\n      assert_equal(\"a\\n\", s2.read)\n    }\n  end\n\n  def test_puts_empty\n    ssl_pair {|s1, s2|\n      s1.puts\n      s1.close\n      assert_equal(\"\\n\", s2.read)\n    }\n  end\n\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_pkcs7.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestPKCS7 < Test::Unit::TestCase\n  def setup\n    @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    ca = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=CA\")\n    ee1 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE1\")\n    ee2 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE2\")\n\n    now = Time.now\n    ca_exts = [\n      [\"basicConstraints\",\"CA:TRUE\",true],\n      [\"keyUsage\",\"keyCertSign, cRLSign\",true],\n      [\"subjectKeyIdentifier\",\"hash\",false],\n      [\"authorityKeyIdentifier\",\"keyid:always\",false],\n    ]\n    @ca_cert = issue_cert(ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,\n                           nil, nil, OpenSSL::Digest::SHA1.new)\n    ee_exts = [\n      [\"keyUsage\",\"Non Repudiation, Digital Signature, Key Encipherment\",true],\n      [\"authorityKeyIdentifier\",\"keyid:always\",false],\n      [\"extendedKeyUsage\",\"clientAuth, emailProtection, codeSigning\",false],\n    ]\n    @ee1_cert = issue_cert(ee1, @rsa1024, 2, Time.now, Time.now+1800, ee_exts,\n                           @ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    @ee2_cert = issue_cert(ee2, @rsa1024, 3, Time.now, Time.now+1800, ee_exts,\n                           @ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n  end\n\n  def issue_cert(*args)             \n    OpenSSL::TestUtils.issue_cert(*args)\n  end\n\n  def test_signed\n    store = OpenSSL::X509::Store.new\n    store.add_cert(@ca_cert)\n    ca_certs = [@ca_cert]\n\n    data = \"aaaaa\\r\\nbbbbb\\r\\nccccc\\r\\n\"\n    tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs)\n    p7 = OpenSSL::PKCS7::PKCS7.new(tmp.to_der)\n    certs = p7.certificates\n    signers = p7.signers\n    assert(p7.verify([], store))\n    assert_equal(data, p7.data)\n    assert_equal(2, certs.size)\n    assert_equal(@ee1_cert.subject.to_s, certs[0].subject.to_s)\n    assert_equal(@ca_cert.subject.to_s, certs[1].subject.to_s)\n    assert_equal(1, signers.size)\n    assert_equal(@ee1_cert.serial, signers[0].serial)\n    assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)\n\n    # Normaly OpenSSL tries to translate the supplied content into canonical\n    # MIME format (e.g. a newline character is converted into CR+LF).\n    # If the content is a binary, PKCS7::BINARY flag should be used.\n\n    data = \"aaaaa\\nbbbbb\\nccccc\\n\"\n    flag = OpenSSL::PKCS7::BINARY\n    tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs, flag)\n    p7 = OpenSSL::PKCS7::PKCS7.new(tmp.to_der)\n    certs = p7.certificates\n    signers = p7.signers\n    assert(p7.verify([], store))\n    assert_equal(data, p7.data)\n    assert_equal(2, certs.size)\n    assert_equal(@ee1_cert.subject.to_s, certs[0].subject.to_s)\n    assert_equal(@ca_cert.subject.to_s, certs[1].subject.to_s)\n    assert_equal(1, signers.size)\n    assert_equal(@ee1_cert.serial, signers[0].serial)\n    assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)\n\n    # A signed-data which have multiple signatures can be created \n    # through the following steps.\n    #   1. create two signed-data\n    #   2. copy signerInfo and certificate from one to another\n\n    tmp1 = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, [], flag)\n    tmp2 = OpenSSL::PKCS7.sign(@ee2_cert, @rsa1024, data, [], flag)\n    tmp1.add_signer(tmp2.signers[0])\n    tmp1.add_certificate(@ee2_cert)  \n\n    p7 = OpenSSL::PKCS7::PKCS7.new(tmp1.to_der)\n    certs = p7.certificates\n    signers = p7.signers\n    assert(p7.verify([], store))\n    assert_equal(data, p7.data)\n    assert_equal(2, certs.size)\n    assert_equal(2, signers.size)\n    assert_equal(@ee1_cert.serial, signers[0].serial)\n    assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)\n    assert_equal(@ee2_cert.serial, signers[1].serial)\n    assert_equal(@ee2_cert.issuer.to_s, signers[1].issuer.to_s)\n  end\n\n  def test_detached_sign\n    store = OpenSSL::X509::Store.new\n    store.add_cert(@ca_cert)\n    ca_certs = [@ca_cert]\n\n    data = \"aaaaa\\nbbbbb\\nccccc\\n\"\n    flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED\n    tmp = OpenSSL::PKCS7.sign(@ee1_cert, @rsa1024, data, ca_certs, flag)\n    p7 = OpenSSL::PKCS7::PKCS7.new(tmp.to_der)\n    a1 = OpenSSL::ASN1.decode(p7)\n\n    certs = p7.certificates\n    signers = p7.signers\n    assert(!p7.verify([], store))\n    assert(p7.verify([], store, data))\n    assert_equal(data, p7.data)\n    assert_equal(2, certs.size)\n    assert_equal(@ee1_cert.subject.to_s, certs[0].subject.to_s)\n    assert_equal(@ca_cert.subject.to_s, certs[1].subject.to_s)\n    assert_equal(1, signers.size)\n    assert_equal(@ee1_cert.serial, signers[0].serial)\n    assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s)\n  end\n\n  def test_enveloped\n    if OpenSSL::OPENSSL_VERSION_NUMBER <= 0x0090704f\n      # PKCS7_encrypt() of OpenSSL-0.9.7d goes to SEGV.\n      # http://www.mail-archive.com/openssl-dev@openssl.org/msg17376.html\n      return\n    end\n\n    certs = [@ee1_cert, @ee2_cert]\n    cipher = OpenSSL::Cipher::AES.new(\"128-CBC\")\n    data = \"aaaaa\\nbbbbb\\nccccc\\n\"\n\n    tmp = OpenSSL::PKCS7.encrypt(certs, data, cipher, OpenSSL::PKCS7::BINARY)\n    p7 = OpenSSL::PKCS7::PKCS7.new(tmp.to_der)\n    recip = p7.recipients\n    assert_equal(:enveloped, p7.type)\n    assert_equal(2, recip.size)\n\n    assert_equal(@ca_cert.subject.to_s, recip[0].issuer.to_s)\n    assert_equal(2, recip[0].serial)\n    assert_equal(data, p7.decrypt(@rsa1024, @ee1_cert))\n\n    assert_equal(@ca_cert.subject.to_s, recip[1].issuer.to_s)\n    assert_equal(3, recip[1].serial)\n    assert_equal(data, p7.decrypt(@rsa1024, @ee2_cert))\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_pkey_rsa.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire 'test/unit'\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestPKeyRSA < Test::Unit::TestCase\n  def test_padding\n    key = OpenSSL::PKey::RSA.new(512, 3)\n\n    # Need right size for raw mode\n    plain0 = \"x\" * (512/8)\n    cipher = key.private_encrypt(plain0, OpenSSL::PKey::RSA::NO_PADDING)\n    plain1 = key.public_decrypt(cipher, OpenSSL::PKey::RSA::NO_PADDING)\n    assert_equal(plain0, plain1)\n\n    # Need smaller size for pkcs1 mode\n    plain0 = \"x\" * (512/8 - 11)\n    cipher1 = key.private_encrypt(plain0, OpenSSL::PKey::RSA::PKCS1_PADDING)\n    plain1 = key.public_decrypt(cipher1, OpenSSL::PKey::RSA::PKCS1_PADDING)\n    assert_equal(plain0, plain1)\n\n    cipherdef = key.private_encrypt(plain0) # PKCS1_PADDING is default\n    plain1 = key.public_decrypt(cipherdef)\n    assert_equal(plain0, plain1)\n    assert_equal(cipher1, cipherdef)\n\n    # Failure cases\n    assert_raise(ArgumentError){ key.private_encrypt() }\n    assert_raise(ArgumentError){ key.private_encrypt(\"hi\", 1, nil) }\n    assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt(plain0, 666) }\n  end\n\n  def test_private\n    key = OpenSSL::PKey::RSA.new(512, 3)\n    assert(key.private?)\n    key2 = OpenSSL::PKey::RSA.new(key.to_der)\n    assert(key2.private?)\n    key3 = key.public_key\n    assert(!key3.private?)\n    key4 = OpenSSL::PKey::RSA.new(key3.to_der)\n    assert(!key4.private?)\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_ssl.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"rbconfig\"\nrequire \"socket\"\nrequire \"test/unit\"\nbegin\n  loadpath = $:.dup\n  $:.replace($: | [File.expand_path(\"../ruby\", File.dirname(__FILE__))])\n  require 'envutil'\nensure\n  $:.replace(loadpath)\nend\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestSSL < Test::Unit::TestCase\n  RUBY = EnvUtil.rubybin\n  SSL_SERVER = File.join(File.dirname(__FILE__), \"ssl_server.rb\")\n  PORT = 20443\n  ITERATIONS = ($0 == __FILE__) ? 100 : 10\n\n  def setup\n    @ca_key  = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256\n    @ca  = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=CA\")\n    @svr = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=localhost\")\n    @cli = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=localhost\")\n\n    now = Time.at(Time.now.to_i)\n    ca_exts = [\n      [\"basicConstraints\",\"CA:TRUE\",true],\n      [\"keyUsage\",\"cRLSign,keyCertSign\",true],\n    ]\n    ee_exts = [\n      [\"keyUsage\",\"keyEncipherment,digitalSignature\",true],\n    ]\n    @ca_cert  = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts,\n                           nil, nil, OpenSSL::Digest::SHA1.new)\n    @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts,\n                           @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)\n    @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts,\n                           @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)\n    @server = nil\n  end\n\n  def teardown\n  end\n\n  def issue_cert(*arg)\n    OpenSSL::TestUtils.issue_cert(*arg)\n  end\n\n  def issue_crl(*arg)\n    OpenSSL::TestUtils.issue_crl(*arg)\n  end\n\n  def readwrite_loop(ctx, ssl)\n    while line = ssl.gets\n      if line =~ /^STARTTLS$/\n        ssl.accept\n        next\n      end\n      ssl.write(line)\n    end\n  rescue OpenSSL::SSL::SSLError\n  rescue IOError\n  ensure\n    ssl.close rescue nil\n  end\n\n  def server_loop(ctx, ssls, server_proc)\n    loop do\n      ssl = nil\n      begin\n        ssl = ssls.accept\n      rescue OpenSSL::SSL::SSLError\n      \tretry\n      end\n\n      Thread.start do\n        Thread.current.abort_on_exception = true  \n        server_proc.call(ctx, ssl)\n      end\n    end\n  rescue Errno::EBADF, IOError\n  end\n\n  def start_server(port0, verify_mode, start_immediately, args = {}, &block)\n    ctx_proc = args[:ctx_proc]\n    server_proc = args[:server_proc]\n    server_proc ||= method(:readwrite_loop)\n  \n    store = OpenSSL::X509::Store.new\n    store.add_cert(@ca_cert)\n    store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT\n    ctx = OpenSSL::SSL::SSLContext.new\n    ctx.cert_store = store\n    #ctx.extra_chain_cert = [ ca_cert ]\n    ctx.cert = @svr_cert\n    ctx.key = @svr_key\n    ctx.verify_mode = verify_mode\n    ctx_proc.call(ctx) if ctx_proc\n\n    Socket.do_not_reverse_lookup = true\n    tcps = nil\n    port = port0\n    begin\n      tcps = TCPServer.new(\"127.0.0.1\", port)\n    rescue Errno::EADDRINUSE\n      port += 1\n      retry\n    end\n\n    ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)\n    ssls.start_immediately = start_immediately\n\n    begin\n      server = Thread.new do\n        Thread.current.abort_on_exception = true  \n        server_loop(ctx, ssls, server_proc)\n      end\n\n      $stderr.printf(\"%s started: pid=%d port=%d\\n\", SSL_SERVER, pid, port) if $DEBUG\n\n      block.call(server, port.to_i)\n    ensure\n      tcps.close if (tcps)\n      if (server)\n        server.join(5)\n        if server.alive?\n          server.kill\n          server.join\n          flunk(\"TCPServer was closed and SSLServer is still alive\") unless $!\n        end\n      end\n    end\n  end\n\n  def starttls(ssl)\n    ssl.puts(\"STARTTLS\")\n\n    sleep 1   # When this line is eliminated, process on Cygwin blocks\n              # forever at ssl.connect. But I don't know why it does.\n\n    ssl.connect\n  end\n\n  def test_ctx_setup\n    ctx = OpenSSL::SSL::SSLContext.new\n    assert_equal(ctx.setup, true)\n    assert_equal(ctx.setup, nil)\n  end\n\n  def test_connect_and_close\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      assert(ssl.connect)\n      ssl.close\n      assert(!sock.closed?)\n      sock.close\n\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      ssl.sync_close = true  # !!\n      assert(ssl.connect)\n      ssl.close\n      assert(sock.closed?)\n    }\n  end\n\n  def test_read_and_write\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      ssl.sync_close = true\n      ssl.connect\n\n      # syswrite and sysread\n      ITERATIONS.times{|i|\n        str = \"x\" * 100 + \"\\n\"\n        ssl.syswrite(str)\n        assert_equal(str, ssl.sysread(str.size))\n\n        str = \"x\" * i * 100 + \"\\n\"\n        buf = \"\"\n        ssl.syswrite(str)\n        assert_equal(buf.object_id, ssl.sysread(str.size, buf).object_id)\n        assert_equal(str, buf)\n      }\n\n      # read and write\n      ITERATIONS.times{|i|\n        str = \"x\" * 100 + \"\\n\"\n        ssl.write(str)\n        assert_equal(str, ssl.read(str.size))\n\n        str = \"x\" * i * 100 + \"\\n\"\n        buf = \"\"\n        ssl.write(str)\n        assert_equal(buf.object_id, ssl.read(str.size, buf).object_id)\n        assert_equal(str, buf)\n      }\n\n      ssl.close\n    }\n  end\n\n  def test_client_auth\n    vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT\n    start_server(PORT, vflag, true){|server, port|\n      assert_raises(OpenSSL::SSL::SSLError){\n        sock = TCPSocket.new(\"127.0.0.1\", port)\n        ssl = OpenSSL::SSL::SSLSocket.new(sock)\n        ssl.connect\n      }\n\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.key = @cli_key\n      ctx.cert = @cli_cert\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n      ssl.sync_close = true\n      ssl.connect\n      ssl.puts(\"foo\")\n      assert_equal(\"foo\\n\", ssl.gets)\n      ssl.close\n\n      called = nil\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.client_cert_cb = Proc.new{ |sslconn|\n        called = true\n        [@cli_cert, @cli_key]\n      }\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n      ssl.sync_close = true\n      ssl.connect\n      assert(called)\n      ssl.puts(\"foo\")\n      assert_equal(\"foo\\n\", ssl.gets)\n      ssl.close\n    }\n  end\n\n  def test_starttls\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      ssl.sync_close = true\n      str = \"x\" * 1000 + \"\\n\"\n\n      ITERATIONS.times{\n        ssl.puts(str)\n        assert_equal(str, ssl.gets)\n      }\n\n      starttls(ssl)\n\n      ITERATIONS.times{\n        ssl.puts(str)\n        assert_equal(str, ssl.gets)\n      }\n\n      ssl.close\n    }\n  end\n\n  def test_parallel\n    GC.start\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      ssls = []\n      10.times{\n        sock = TCPSocket.new(\"127.0.0.1\", port)\n        ssl = OpenSSL::SSL::SSLSocket.new(sock)\n        ssl.connect\n        ssl.sync_close = true\n        ssls << ssl\n      }\n      str = \"x\" * 1000 + \"\\n\"\n      ITERATIONS.times{\n        ssls.each{|ssl|\n          ssl.puts(str)\n          assert_equal(str, ssl.gets)\n        }\n      }\n      ssls.each{|ssl| ssl.close }\n    }\n  end\n\n  def test_verify_result\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.set_params\n      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n      assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }\n      assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)\n\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.set_params(\n        :verify_callback => Proc.new do |preverify_ok, store_ctx|\n          store_ctx.error = OpenSSL::X509::V_OK\n          true\n        end\n      )\n      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n      ssl.connect\n      assert_equal(OpenSSL::X509::V_OK, ssl.verify_result)\n\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.set_params(\n        :verify_callback => Proc.new do |preverify_ok, store_ctx|\n          store_ctx.error = OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION\n          false\n        end\n      )\n      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n      assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }\n      assert_equal(OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION, ssl.verify_result)\n    }\n  end\n\n  def test_sslctx_set_params\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ctx = OpenSSL::SSL::SSLContext.new\n      ctx.set_params\n      assert_equal(OpenSSL::SSL::VERIFY_PEER, ctx.verify_mode)\n      assert_equal(OpenSSL::SSL::OP_ALL, ctx.options)\n      ciphers = ctx.ciphers\n      ciphers_versions = ciphers.collect{|_, v, _, _| v }\n      ciphers_names = ciphers.collect{|v, _, _, _| v }\n      assert(ciphers_names.all?{|v| /ADH/ !~ v })\n      assert(ciphers_versions.all?{|v| /SSLv2/ !~ v })\n      ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n      assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }\n      assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)\n    }\n  end\n\n  def test_post_connection_check\n    sslerr = OpenSSL::SSL::SSLError\n\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      ssl.connect\n      assert_raises(sslerr){ssl.post_connection_check(\"localhost.localdomain\")}\n      assert_raises(sslerr){ssl.post_connection_check(\"127.0.0.1\")}\n      assert(ssl.post_connection_check(\"localhost\"))\n      assert_raises(sslerr){ssl.post_connection_check(\"foo.example.com\")}\n\n      cert = ssl.peer_cert\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"localhost.localdomain\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"127.0.0.1\"))\n      assert(OpenSSL::SSL.verify_certificate_identity(cert, \"localhost\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"foo.example.com\"))\n    }\n\n    now = Time.now\n    exts = [\n      [\"keyUsage\",\"keyEncipherment,digitalSignature\",true],\n      [\"subjectAltName\",\"DNS:localhost.localdomain\",false],\n      [\"subjectAltName\",\"IP:127.0.0.1\",false],\n    ]\n    @svr_cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,\n                           @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      ssl.connect\n      assert(ssl.post_connection_check(\"localhost.localdomain\"))\n      assert(ssl.post_connection_check(\"127.0.0.1\"))\n      assert_raises(sslerr){ssl.post_connection_check(\"localhost\")}\n      assert_raises(sslerr){ssl.post_connection_check(\"foo.example.com\")}\n\n      cert = ssl.peer_cert\n      assert(OpenSSL::SSL.verify_certificate_identity(cert, \"localhost.localdomain\"))\n      assert(OpenSSL::SSL.verify_certificate_identity(cert, \"127.0.0.1\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"localhost\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"foo.example.com\"))\n    }\n\n    now = Time.now\n    exts = [\n      [\"keyUsage\",\"keyEncipherment,digitalSignature\",true],\n      [\"subjectAltName\",\"DNS:*.localdomain\",false],\n    ]\n    @svr_cert = issue_cert(@svr, @svr_key, 5, now, now+1800, exts,\n                           @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|\n      sock = TCPSocket.new(\"127.0.0.1\", port)\n      ssl = OpenSSL::SSL::SSLSocket.new(sock)\n      ssl.connect\n      assert(ssl.post_connection_check(\"localhost.localdomain\"))\n      assert_raises(sslerr){ssl.post_connection_check(\"127.0.0.1\")}\n      assert_raises(sslerr){ssl.post_connection_check(\"localhost\")}\n      assert_raises(sslerr){ssl.post_connection_check(\"foo.example.com\")}\n      cert = ssl.peer_cert\n      assert(OpenSSL::SSL.verify_certificate_identity(cert, \"localhost.localdomain\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"127.0.0.1\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"localhost\"))\n      assert(!OpenSSL::SSL.verify_certificate_identity(cert, \"foo.example.com\"))\n    }\n  end\n\n  def test_client_session\n    last_session = nil\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|\n      2.times do\n        sock = TCPSocket.new(\"127.0.0.1\", port)\n        # Debian's openssl 0.9.8g-13 failed at assert(ssl.session_reused?),\n        # when use default SSLContext. [ruby-dev:36167]\n        ctx = OpenSSL::SSL::SSLContext.new(\"TLSv1\")\n        ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n        ssl.sync_close = true\n        ssl.session = last_session if last_session\n        ssl.connect\n\n        session = ssl.session\n        if last_session\n          assert(ssl.session_reused?)\n\n          if session.respond_to?(:id)\n            assert_equal(session.id, last_session.id)\n          end\n          assert_equal(session.to_pem, last_session.to_pem)\n          assert_equal(session.to_der, last_session.to_der)\n          # Older version of OpenSSL may not be consistent.  Look up which versions later.\n          assert_equal(session.to_text, last_session.to_text)\n        else\n          assert(!ssl.session_reused?)\n        end\n        last_session = session\n\n        str = \"x\" * 100 + \"\\n\"\n        ssl.puts(str)\n        assert_equal(str, ssl.gets)\n\n        ssl.close\n      end\n    end\n  end\n\n  def test_server_session\n    connections = 0\n    saved_session = nil\n\n    ctx_proc = Proc.new do |ctx, ssl|\n# add test for session callbacks here\n    end\n\n    server_proc = Proc.new do |ctx, ssl|\n      session = ssl.session\n      stats = ctx.session_cache_stats\n\n      case connections\n      when 0\n        assert_equal(stats[:cache_num], 1)\n        assert_equal(stats[:cache_hits], 0)\n        assert_equal(stats[:cache_misses], 0)\n        assert(!ssl.session_reused?)\n      when 1\n        assert_equal(stats[:cache_num], 1)\n        assert_equal(stats[:cache_hits], 1)\n        assert_equal(stats[:cache_misses], 0)\n        assert(ssl.session_reused?)\n        ctx.session_remove(session)\n        saved_session = session\n      when 2\n        assert_equal(stats[:cache_num], 1)\n        assert_equal(stats[:cache_hits], 1)\n        assert_equal(stats[:cache_misses], 1)\n        assert(!ssl.session_reused?)\n        ctx.session_add(saved_session)\n      when 3\n        assert_equal(stats[:cache_num], 2)\n        assert_equal(stats[:cache_hits], 2)\n        assert_equal(stats[:cache_misses], 1)\n        assert(ssl.session_reused?)\n        ctx.flush_sessions(Time.now + 5000)\n      when 4\n        assert_equal(stats[:cache_num], 1)\n        assert_equal(stats[:cache_hits], 2)\n        assert_equal(stats[:cache_misses], 2)\n        assert(!ssl.session_reused?)\n        ctx.session_add(saved_session)\n      end\n      connections += 1\n      \n      readwrite_loop(ctx, ssl)\n    end\n\n    first_session = nil\n    start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|\n      10.times do |i|\n        sock = TCPSocket.new(\"127.0.0.1\", port)\n        ctx = OpenSSL::SSL::SSLContext.new\n        if defined?(OpenSSL::SSL::OP_NO_TICKET)\n          # disable RFC4507 support\n          ctx.options = OpenSSL::SSL::OP_NO_TICKET\n        end\n        ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)\n        ssl.sync_close = true\n        ssl.session = first_session if first_session\n        ssl.connect\n\n        session = ssl.session\n        if first_session\n          case i\n          when 1; assert(ssl.session_reused?)\n          when 2; assert(!ssl.session_reused?)\n          when 3; assert(ssl.session_reused?)\n          when 4; assert(!ssl.session_reused?)\n          when 5..10; assert(ssl.session_reused?)\n          end\n        end\n        first_session ||= session\n\n        str = \"x\" * 100 + \"\\n\"\n        ssl.puts(str)\n        assert_equal(str, ssl.gets)\n\n        ssl.close\n      end\n    end\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_x509cert.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Certificate < Test::Unit::TestCase\n  def setup\n    @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    @dsa256  = OpenSSL::TestUtils::TEST_KEY_DSA256\n    @dsa512  = OpenSSL::TestUtils::TEST_KEY_DSA512\n    @ca = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=CA\")\n    @ee1 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE1\")\n    @ee2 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE2\")\n  end\n\n  def teardown\n  end\n\n  def issue_cert(*args)\n    OpenSSL::TestUtils.issue_cert(*args)\n  end\n\n  def test_serial\n    [1, 2**32, 2**100].each{|s|\n      cert = issue_cert(@ca, @rsa2048, s, Time.now, Time.now+3600, [],\n                        nil, nil, OpenSSL::Digest::SHA1.new) \n      assert_equal(s, cert.serial)\n      cert = OpenSSL::X509::Certificate.new(cert.to_der)\n      assert_equal(s, cert.serial)\n    }\n  end\n\n  def test_public_key\n    exts = [\n      [\"basicConstraints\",\"CA:TRUE\",true],\n      [\"subjectKeyIdentifier\",\"hash\",false],\n      [\"authorityKeyIdentifier\",\"keyid:always\",false],\n    ]\n\n    sha1 = OpenSSL::Digest::SHA1.new\n    dss1 = OpenSSL::Digest::DSS1.new\n    [\n      [@rsa1024, sha1], [@rsa2048, sha1], [@dsa256, dss1], [@dsa512, dss1],\n    ].each{|pk, digest|\n      cert = issue_cert(@ca, pk, 1, Time.now, Time.now+3600, exts,\n                        nil, nil, digest)\n      assert_equal(cert.extensions[1].value,\n                   OpenSSL::TestUtils.get_subject_key_id(cert))\n      cert = OpenSSL::X509::Certificate.new(cert.to_der)\n      assert_equal(cert.extensions[1].value,\n                   OpenSSL::TestUtils.get_subject_key_id(cert))\n    }\n  end\n\n  def test_validity\n    now = Time.now until now && now.usec != 0\n    cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new) \n    assert_not_equal(now, cert.not_before)\n    assert_not_equal(now+3600, cert.not_after)\n\n    now = Time.at(now.to_i)\n    cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new) \n    assert_equal(now.getutc, cert.not_before)\n    assert_equal((now+3600).getutc, cert.not_after)\n\n    now = Time.at(0)\n    cert = issue_cert(@ca, @rsa2048, 1, now, now, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new) \n    assert_equal(now.getutc, cert.not_before)\n    assert_equal(now.getutc, cert.not_after)\n\n    now = Time.at(0x7fffffff)\n    cert = issue_cert(@ca, @rsa2048, 1, now, now, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new) \n    assert_equal(now.getutc, cert.not_before)\n    assert_equal(now.getutc, cert.not_after)\n  end\n\n  def test_extension\n    ca_exts = [\n      [\"basicConstraints\",\"CA:TRUE\",true],\n      [\"keyUsage\",\"keyCertSign, cRLSign\",true],\n      [\"subjectKeyIdentifier\",\"hash\",false],\n      [\"authorityKeyIdentifier\",\"keyid:always\",false],\n    ]\n    ca_cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,\n                         nil, nil, OpenSSL::Digest::SHA1.new) \n    ca_cert.extensions.each_with_index{|ext, i|\n      assert_equal(ca_exts[i].first, ext.oid)\n      assert_equal(ca_exts[i].last, ext.critical?)\n    }\n\n    ee1_exts = [\n      [\"keyUsage\",\"Non Repudiation, Digital Signature, Key Encipherment\",true],\n      [\"subjectKeyIdentifier\",\"hash\",false],\n      [\"authorityKeyIdentifier\",\"keyid:always\",false],\n      [\"extendedKeyUsage\",\"clientAuth, emailProtection, codeSigning\",false],\n      [\"subjectAltName\",\"email:ee1@ruby-lang.org\",false],\n    ]\n    ee1_cert = issue_cert(@ee1, @rsa1024, 2, Time.now, Time.now+1800, ee1_exts,\n                          ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new) \n    assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)\n    ee1_cert.extensions.each_with_index{|ext, i|\n      assert_equal(ee1_exts[i].first, ext.oid)\n      assert_equal(ee1_exts[i].last, ext.critical?)\n    }\n\n    ee2_exts = [\n      [\"keyUsage\",\"Non Repudiation, Digital Signature, Key Encipherment\",true],\n      [\"subjectKeyIdentifier\",\"hash\",false],\n      [\"authorityKeyIdentifier\",\"issuer:always\",false],\n      [\"extendedKeyUsage\",\"clientAuth, emailProtection, codeSigning\",false],\n      [\"subjectAltName\",\"email:ee2@ruby-lang.org\",false],\n    ]\n    ee2_cert = issue_cert(@ee2, @rsa1024, 3, Time.now, Time.now+1800, ee2_exts,\n                          ca_cert, @rsa2048, OpenSSL::Digest::MD5.new) \n    assert_equal(ca_cert.subject.to_der, ee2_cert.issuer.to_der)\n    ee2_cert.extensions.each_with_index{|ext, i|\n      assert_equal(ee2_exts[i].first, ext.oid)\n      assert_equal(ee2_exts[i].last, ext.critical?)\n    }\n\n  end\n\n  def test_sign_and_verify\n    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new) \n    assert_equal(false, cert.verify(@rsa1024))\n    assert_equal(true,  cert.verify(@rsa2048))\n    assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })\n    assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })\n    cert.serial = 2\n    assert_equal(false, cert.verify(@rsa2048))\n\n    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::MD5.new) \n    assert_equal(false, cert.verify(@rsa1024))\n    assert_equal(true,  cert.verify(@rsa2048))\n    assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })\n    assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })\n    cert.subject = @ee1\n    assert_equal(false, cert.verify(@rsa2048))\n\n    cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::DSS1.new) \n    assert_equal(false, certificate_error_returns_false { cert.verify(@rsa1024) })\n    assert_equal(false, certificate_error_returns_false { cert.verify(@rsa2048) })\n    assert_equal(false, cert.verify(@dsa256))\n    assert_equal(true,  cert.verify(@dsa512))\n    cert.not_after = Time.now \n    assert_equal(false, cert.verify(@dsa512))\n\n    assert_raises(OpenSSL::X509::CertificateError){\n      cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],\n                        nil, nil, OpenSSL::Digest::DSS1.new) \n    }\n    assert_raises(OpenSSL::X509::CertificateError){\n      cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],\n                        nil, nil, OpenSSL::Digest::MD5.new) \n    }\n    assert_raises(OpenSSL::X509::CertificateError){\n      cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],\n                        nil, nil, OpenSSL::Digest::SHA1.new) \n    }\n  end\n  \n  private\n  \n  def certificate_error_returns_false\n    yield\n  rescue OpenSSL::X509::CertificateError\n    false\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_x509crl.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509CRL < Test::Unit::TestCase\n  def setup\n    @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    @dsa256  = OpenSSL::TestUtils::TEST_KEY_DSA256\n    @dsa512  = OpenSSL::TestUtils::TEST_KEY_DSA512\n    @ca = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=CA\")\n    @ee1 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE1\")\n    @ee2 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE2\")\n  end\n\n  def teardown\n  end\n\n  def issue_crl(*args)\n    OpenSSL::TestUtils.issue_crl(*args)\n  end\n\n  def issue_cert(*args)\n    OpenSSL::TestUtils.issue_cert(*args)\n  end\n\n  def test_basic\n    now = Time.at(Time.now.to_i)\n\n    cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new)\n    crl = issue_crl([], 1, now, now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    assert_equal(1, crl.version)\n    assert_equal(cert.issuer.to_der, crl.issuer.to_der)\n    assert_equal(now, crl.last_update)\n    assert_equal(now+1600, crl.next_update)\n\n    crl = OpenSSL::X509::CRL.new(crl.to_der)\n    assert_equal(1, crl.version)\n    assert_equal(cert.issuer.to_der, crl.issuer.to_der)\n    assert_equal(now, crl.last_update)\n    assert_equal(now+1600, crl.next_update)\n  end\n\n  def test_revoked\n\n    # CRLReason ::= ENUMERATED {\n    #      unspecified             (0),\n    #      keyCompromise           (1),\n    #      cACompromise            (2),\n    #      affiliationChanged      (3),\n    #      superseded              (4),\n    #      cessationOfOperation    (5),\n    #      certificateHold         (6),\n    #      removeFromCRL           (8),\n    #      privilegeWithdrawn      (9),\n    #      aACompromise           (10) }\n\n    now = Time.at(Time.now.to_i)\n    revoke_info = [\n      [1, Time.at(0),          1],\n      [2, Time.at(0x7fffffff), 2],\n      [3, now,                 3],\n      [4, now,                 4],\n      [5, now,                 5],\n    ]\n    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new)\n    crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    revoked = crl.revoked\n    assert_equal(5, revoked.size)\n    assert_equal(1, revoked[0].serial)\n    assert_equal(2, revoked[1].serial)\n    assert_equal(3, revoked[2].serial)\n    assert_equal(4, revoked[3].serial)\n    assert_equal(5, revoked[4].serial)\n\n    assert_equal(Time.at(0), revoked[0].time)\n    assert_equal(Time.at(0x7fffffff), revoked[1].time)\n    assert_equal(now, revoked[2].time)\n    assert_equal(now, revoked[3].time)\n    assert_equal(now, revoked[4].time)\n\n    assert_equal(\"CRLReason\", revoked[0].extensions[0].oid)\n    assert_equal(\"CRLReason\", revoked[1].extensions[0].oid)\n    assert_equal(\"CRLReason\", revoked[2].extensions[0].oid)\n    assert_equal(\"CRLReason\", revoked[3].extensions[0].oid)\n    assert_equal(\"CRLReason\", revoked[4].extensions[0].oid)\n\n    assert_equal(\"Key Compromise\", revoked[0].extensions[0].value)\n    assert_equal(\"CA Compromise\", revoked[1].extensions[0].value)\n    assert_equal(\"Affiliation Changed\", revoked[2].extensions[0].value)\n    assert_equal(\"Superseded\", revoked[3].extensions[0].value)\n    assert_equal(\"Cessation Of Operation\", revoked[4].extensions[0].value)\n\n    assert_equal(false, revoked[0].extensions[0].critical?)\n    assert_equal(false, revoked[1].extensions[0].critical?)\n    assert_equal(false, revoked[2].extensions[0].critical?)\n    assert_equal(false, revoked[3].extensions[0].critical?)\n    assert_equal(false, revoked[4].extensions[0].critical?)\n\n    crl = OpenSSL::X509::CRL.new(crl.to_der)\n    assert_equal(\"Key Compromise\", revoked[0].extensions[0].value)\n    assert_equal(\"CA Compromise\", revoked[1].extensions[0].value)\n    assert_equal(\"Affiliation Changed\", revoked[2].extensions[0].value)\n    assert_equal(\"Superseded\", revoked[3].extensions[0].value)\n    assert_equal(\"Cessation Of Operation\", revoked[4].extensions[0].value)\n\n    revoke_info = (1..1000).collect{|i| [i, now, 0] }\n    crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    revoked = crl.revoked\n    assert_equal(1000, revoked.size)\n    assert_equal(1, revoked[0].serial)\n    assert_equal(1000, revoked[999].serial)\n  end\n\n  def test_extension\n    cert_exts = [\n      [\"basicConstraints\", \"CA:TRUE\", true],\n      [\"subjectKeyIdentifier\", \"hash\", false], \n      [\"authorityKeyIdentifier\", \"keyid:always\", false], \n      [\"subjectAltName\", \"email:xyzzy@ruby-lang.org\", false],\n      [\"keyUsage\", \"cRLSign, keyCertSign\", true],\n    ]\n    crl_exts = [\n      [\"authorityKeyIdentifier\", \"keyid:always\", false], \n      [\"issuerAltName\", \"issuer:copy\", false],\n    ]\n\n    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, cert_exts,\n                      nil, nil, OpenSSL::Digest::SHA1.new)\n    crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts,\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    exts = crl.extensions\n    assert_equal(3, exts.size)\n    assert_equal(\"1\", exts[0].value)\n    assert_equal(\"crlNumber\", exts[0].oid)\n    assert_equal(false, exts[0].critical?)\n\n    assert_equal(\"authorityKeyIdentifier\", exts[1].oid)\n    keyid = OpenSSL::TestUtils.get_subject_key_id(cert)\n    assert_match(/^keyid:#{keyid}/, exts[1].value)\n    assert_equal(false, exts[1].critical?)\n\n    assert_equal(\"issuerAltName\", exts[2].oid)\n    assert_equal(\"email:xyzzy@ruby-lang.org\", exts[2].value)\n    assert_equal(false, exts[2].critical?)\n\n    crl = OpenSSL::X509::CRL.new(crl.to_der)\n    exts = crl.extensions\n    assert_equal(3, exts.size)\n    assert_equal(\"1\", exts[0].value)\n    assert_equal(\"crlNumber\", exts[0].oid)\n    assert_equal(false, exts[0].critical?)\n\n    assert_equal(\"authorityKeyIdentifier\", exts[1].oid)\n    keyid = OpenSSL::TestUtils.get_subject_key_id(cert)\n    assert_match(/^keyid:#{keyid}/, exts[1].value)\n    assert_equal(false, exts[1].critical?)\n\n    assert_equal(\"issuerAltName\", exts[2].oid)\n    assert_equal(\"email:xyzzy@ruby-lang.org\", exts[2].value)\n    assert_equal(false, exts[2].critical?)\n  end\n\n  def test_crlnumber\n    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new)\n    crl = issue_crl([], 1, Time.now, Time.now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    assert_match(1.to_s, crl.extensions[0].value)\n    assert_match(/X509v3 CRL Number:\\s+#{1}/m, crl.to_text)\n\n    crl = issue_crl([], 2**32, Time.now, Time.now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    assert_match((2**32).to_s, crl.extensions[0].value)\n    assert_match(/X509v3 CRL Number:\\s+#{2**32}/m, crl.to_text)\n\n    crl = issue_crl([], 2**100, Time.now, Time.now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    assert_match(/X509v3 CRL Number:\\s+#{2**100}/m, crl.to_text)\n    assert_match((2**100).to_s, crl.extensions[0].value)\n  end\n\n  def test_sign_and_verify\n    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::SHA1.new)\n    crl = issue_crl([], 1, Time.now, Time.now+1600, [],\n                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    assert_equal(false, crl.verify(@rsa1024))\n    assert_equal(true,  crl.verify(@rsa2048))\n    assert_equal(false, crl_error_returns_false { crl.verify(@dsa256) })\n    assert_equal(false, crl_error_returns_false { crl.verify(@dsa512) })\n    crl.version = 0\n    assert_equal(false, crl.verify(@rsa2048))\n\n    cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],\n                      nil, nil, OpenSSL::Digest::DSS1.new)\n    crl = issue_crl([], 1, Time.now, Time.now+1600, [],\n                    cert, @dsa512, OpenSSL::Digest::DSS1.new)\n    assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })\n    assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })\n    assert_equal(false, crl.verify(@dsa256))\n    assert_equal(true,  crl.verify(@dsa512))\n    crl.version = 0\n    assert_equal(false, crl.verify(@dsa512))\n  end\n  \n  private\n  \n  def crl_error_returns_false\n    yield\n  rescue OpenSSL::X509::CRLError\n    false\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_x509ext.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Extension < Test::Unit::TestCase\n  def setup\n    @basic_constraints_value = OpenSSL::ASN1::Sequence([\n      OpenSSL::ASN1::Boolean(true),   # CA\n      OpenSSL::ASN1::Integer(2)       # pathlen\n    ])\n    @basic_constraints = OpenSSL::ASN1::Sequence([\n      OpenSSL::ASN1::ObjectId(\"basicConstraints\"),\n      OpenSSL::ASN1::Boolean(true),\n      OpenSSL::ASN1::OctetString(@basic_constraints_value.to_der),\n    ])\n  end\n\n  def teardown\n  end\n\n  def test_new\n    ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der)\n    assert_equal(\"basicConstraints\", ext.oid)\n    assert_equal(true, ext.critical?)\n    assert_equal(\"CA:TRUE, pathlen:2\", ext.value)\n\n    ext = OpenSSL::X509::Extension.new(\"2.5.29.19\",\n                                       @basic_constraints_value.to_der, true)\n    assert_equal(@basic_constraints.to_der, ext.to_der)\n  end\n\n  def test_create_by_factory\n    ef = OpenSSL::X509::ExtensionFactory.new\n\n    bc = ef.create_extension(\"basicConstraints\", \"critical, CA:TRUE, pathlen:2\")\n    assert_equal(@basic_constraints.to_der, bc.to_der)\n\n    bc = ef.create_extension(\"basicConstraints\", \"CA:TRUE, pathlen:2\", true)\n    assert_equal(@basic_constraints.to_der, bc.to_der)\n\n    begin\n      ef.config = OpenSSL::Config.parse(<<-_end_of_cnf_)\n      [crlDistPts]\n      URI.1 = http://www.example.com/crl\n      URI.2 = ldap://ldap.example.com/cn=ca?certificateRevocationList;binary\n      _end_of_cnf_\n    rescue NotImplementedError\n      return\n    end\n\n    cdp = ef.create_extension(\"crlDistributionPoints\", \"@crlDistPts\")\n    assert_equal(false, cdp.critical?)\n    assert_equal(\"crlDistributionPoints\", cdp.oid)\n    assert_match(%{URI:http://www\\.example\\.com/crl}, cdp.value)\n    assert_match(\n      %r{URI:ldap://ldap\\.example\\.com/cn=ca\\?certificateRevocationList;binary},\n      cdp.value)\n\n    cdp = ef.create_extension(\"crlDistributionPoints\", \"critical, @crlDistPts\")\n    assert_equal(true, cdp.critical?)\n    assert_equal(\"crlDistributionPoints\", cdp.oid)\n    assert_match(%{URI:http://www.example.com/crl}, cdp.value)\n    assert_match(\n      %r{URI:ldap://ldap.example.com/cn=ca\\?certificateRevocationList;binary},\n      cdp.value)\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_x509name.rb",
    "content": "begin\n  require \"openssl\"\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Name < Test::Unit::TestCase\n  OpenSSL::ASN1::ObjectId.register(\n    \"1.2.840.113549.1.9.1\", \"emailAddress\", \"emailAddress\")\n  OpenSSL::ASN1::ObjectId.register(\n    \"2.5.4.5\", \"serialNumber\", \"serialNumber\")\n\n  def setup\n    @obj_type_tmpl = Hash.new(OpenSSL::ASN1::PRINTABLESTRING)\n    @obj_type_tmpl.update(OpenSSL::X509::Name::OBJECT_TYPE_TEMPLATE)\n  end\n\n  def teardown\n  end\n\n  def test_s_new\n    dn = [ [\"C\", \"JP\"], [\"O\", \"example\"], [\"CN\", \"www.example.jp\"] ]\n    name = OpenSSL::X509::Name.new(dn)\n    ary = name.to_a\n    assert_equal(\"/C=JP/O=example/CN=www.example.jp\", name.to_s)\n    assert_equal(\"C\", ary[0][0])\n    assert_equal(\"O\", ary[1][0])\n    assert_equal(\"CN\", ary[2][0])\n    assert_equal(\"JP\", ary[0][1])\n    assert_equal(\"example\", ary[1][1])\n    assert_equal(\"www.example.jp\", ary[2][1])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])\n\n    dn = [\n      [\"countryName\", \"JP\"],\n      [\"organizationName\", \"example\"],\n      [\"commonName\", \"www.example.jp\"]\n    ]\n    name = OpenSSL::X509::Name.new(dn)\n    ary = name.to_a\n    assert_equal(\"/C=JP/O=example/CN=www.example.jp\", name.to_s)\n    assert_equal(\"C\", ary[0][0])\n    assert_equal(\"O\", ary[1][0])\n    assert_equal(\"CN\", ary[2][0])\n    assert_equal(\"JP\", ary[0][1])\n    assert_equal(\"example\", ary[1][1])\n    assert_equal(\"www.example.jp\", ary[2][1])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])\n\n    name = OpenSSL::X509::Name.new(dn, @obj_type_tmpl)\n    ary = name.to_a\n    assert_equal(\"/C=JP/O=example/CN=www.example.jp\", name.to_s)\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])\n\n    dn = [\n      [\"countryName\", \"JP\", OpenSSL::ASN1::PRINTABLESTRING],\n      [\"organizationName\", \"example\", OpenSSL::ASN1::PRINTABLESTRING],\n      [\"commonName\", \"www.example.jp\", OpenSSL::ASN1::PRINTABLESTRING]\n    ]\n    name = OpenSSL::X509::Name.new(dn)\n    ary = name.to_a\n    assert_equal(\"/C=JP/O=example/CN=www.example.jp\", name.to_s)\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])\n\n    dn = [\n      [\"DC\", \"org\"],\n      [\"DC\", \"ruby-lang\"],\n      [\"CN\", \"GOTOU Yuuzou\"],\n      [\"emailAddress\", \"gotoyuzo@ruby-lang.org\"],\n      [\"serialNumber\", \"123\"],\n    ]\n    name = OpenSSL::X509::Name.new(dn)\n    ary = name.to_a\n    assert_equal(\"/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123\", name.to_s)\n    assert_equal(\"DC\", ary[0][0])\n    assert_equal(\"DC\", ary[1][0])\n    assert_equal(\"CN\", ary[2][0])\n    assert_equal(\"emailAddress\", ary[3][0])\n    assert_equal(\"serialNumber\", ary[4][0])\n    assert_equal(\"org\", ary[0][1])\n    assert_equal(\"ruby-lang\", ary[1][1])\n    assert_equal(\"GOTOU Yuuzou\", ary[2][1])\n    assert_equal(\"gotoyuzo@ruby-lang.org\", ary[3][1])\n    assert_equal(\"123\", ary[4][1])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2])\n\n    name_from_der = OpenSSL::X509::Name.new(name.to_der)\n    assert_equal(name_from_der.to_s, name.to_s)\n    assert_equal(name_from_der.to_a, name.to_a)\n    assert_equal(name_from_der.to_der, name.to_der)\n  end\n\n  def test_s_parse\n    dn = \"/DC=org/DC=ruby-lang/CN=www.ruby-lang.org\"\n    name = OpenSSL::X509::Name.parse(dn)\n    assert_equal(dn, name.to_s)\n    ary = name.to_a\n    assert_equal(\"DC\", ary[0][0])\n    assert_equal(\"DC\", ary[1][0])\n    assert_equal(\"CN\", ary[2][0])\n    assert_equal(\"org\", ary[0][1])\n    assert_equal(\"ruby-lang\", ary[1][1])\n    assert_equal(\"www.ruby-lang.org\", ary[2][1])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])\n\n    dn2 = \"DC=org, DC=ruby-lang, CN=www.ruby-lang.org\"\n    name = OpenSSL::X509::Name.parse(dn)\n    ary = name.to_a\n    assert_equal(dn, name.to_s)\n    assert_equal(\"org\", ary[0][1])\n    assert_equal(\"ruby-lang\", ary[1][1])\n    assert_equal(\"www.ruby-lang.org\", ary[2][1])\n\n    name = OpenSSL::X509::Name.parse(dn, @obj_type_tmpl)\n    ary = name.to_a\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])\n  end\n\n  def test_s_parse_rfc2253\n    scanner = OpenSSL::X509::Name::RFC2253DN.method(:scan)\n\n    assert_equal([[\"C\", \"JP\"]], scanner.call(\"C=JP\"))\n    assert_equal([\n        [\"DC\", \"org\"],\n        [\"DC\", \"ruby-lang\"],\n        [\"CN\", \"GOTOU Yuuzou\"],\n        [\"emailAddress\", \"gotoyuzo@ruby-lang.org\"],\n      ],\n      scanner.call(\n        \"emailAddress=gotoyuzo@ruby-lang.org,CN=GOTOU Yuuzou,\"+\n        \"DC=ruby-lang,DC=org\")\n    )\n\n    u8 = OpenSSL::ASN1::UTF8STRING\n    assert_equal([\n        [\"DC\", \"org\"],\n        [\"DC\", \"ruby-lang\"],\n        [\"O\", \",=+<>#;\"],\n        [\"O\", \",=+<>#;\"],\n        [\"OU\", \"\"],\n        [\"OU\", \"\"],\n        [\"L\", \"aaa=\\\"bbb, ccc\\\"\"],\n        [\"L\", \"aaa=\\\"bbb, ccc\\\"\"],\n        [\"CN\", \"\\345\\276\\214\\350\\227\\244\\350\\243\\225\\350\\224\\265\"],\n        [\"CN\", \"\\345\\276\\214\\350\\227\\244\\350\\243\\225\\350\\224\\265\"],\n        [\"CN\", \"\\345\\276\\214\\350\\227\\244\\350\\243\\225\\350\\224\\265\"],\n        [\"CN\", \"\\345\\276\\214\\350\\227\\244\\350\\243\\225\\350\\224\\265\", u8],\n        [\"2.5.4.3\", \"GOTOU, Yuuzou\"],\n        [\"2.5.4.3\", \"GOTOU, Yuuzou\"],\n        [\"2.5.4.3\", \"GOTOU, Yuuzou\"],\n        [\"2.5.4.3\", \"GOTOU, Yuuzou\"],\n        [\"CN\", \"GOTOU \\\"gotoyuzo\\\" Yuuzou\"],\n        [\"CN\", \"GOTOU \\\"gotoyuzo\\\" Yuuzou\"],\n        [\"1.2.840.113549.1.9.1\", \"gotoyuzo@ruby-lang.org\"],\n        [\"emailAddress\", \"gotoyuzo@ruby-lang.org\"],\n      ],\n      scanner.call(\n        \"emailAddress=gotoyuzo@ruby-lang.org,\" +\n        \"1.2.840.113549.1.9.1=gotoyuzo@ruby-lang.org,\" +\n        'CN=GOTOU \\\"gotoyuzo\\\" Yuuzou,' +\n        'CN=\"GOTOU \\\"gotoyuzo\\\" Yuuzou\",' +\n        '2.5.4.3=GOTOU\\,\\20Yuuzou,' +\n        '2.5.4.3=GOTOU\\, Yuuzou,' +\n        '2.5.4.3=\"GOTOU, Yuuzou\",' +\n        '2.5.4.3=\"GOTOU\\, Yuuzou\",' +\n        \"CN=#0C0CE5BE8CE897A4E8A395E894B5,\" +\n        'CN=\\E5\\BE\\8C\\E8\\97\\A4\\E8\\A3\\95\\E8\\94\\B5,' +\n        \"CN=\\\"\\xE5\\xBE\\x8C\\xE8\\x97\\xA4\\xE8\\xA3\\x95\\xE8\\x94\\xB5\\\",\" +\n        \"CN=\\xE5\\xBE\\x8C\\xE8\\x97\\xA4\\xE8\\xA3\\x95\\xE8\\x94\\xB5,\" +\n        'L=aaa\\=\\\"bbb\\, ccc\\\",' +\n        'L=\"aaa=\\\"bbb, ccc\\\"\",' +\n        'OU=,' +\n        'OU=\"\",' +\n        'O=\\,\\=\\+\\<\\>\\#\\;,' +\n        'O=\",=+<>#;\",' +\n        \"DC=ruby-lang,\" +\n        \"DC=org\")\n    )\n\n    [\n      \"DC=org+DC=jp\",\n      \"DC=org,DC=ruby-lang+DC=rubyist,DC=www\"\n    ].each{|dn|\n      ex = scanner.call(dn) rescue $!\n      dn_r = Regexp.escape(dn)\n      assert_match(/^multi-valued RDN is not supported: #{dn_r}/, ex.message)\n    }\n\n    [\n      [\"DC=org,DC=exapmle,CN\", \"CN\"],\n      [\"DC=org,DC=example,\", \"\"],\n      [\"DC=org,DC=exapmle,CN=www.example.org;\", \"CN=www.example.org;\"],\n      [\"DC=org,DC=exapmle,CN=#www.example.org\", \"CN=#www.example.org\"],\n      [\"DC=org,DC=exapmle,CN=#777777.example.org\", \"CN=#777777.example.org\"],\n      [\"DC=org,DC=exapmle,CN=\\\"www.example\\\".org\", \"CN=\\\"www.example\\\".org\"],\n      [\"DC=org,DC=exapmle,CN=www.\\\"example.org\\\"\", \"CN=www.\\\"example.org\\\"\"],\n      [\"DC=org,DC=exapmle,CN=www.\\\"example\\\".org\", \"CN=www.\\\"example\\\".org\"],\n    ].each{|dn, msg|\n      ex = scanner.call(dn) rescue $!\n      assert_match(/^malformed RDN: .*=>#{Regexp.escape(msg)}/, ex.message)\n    }\n\n    dn = \"CN=www.ruby-lang.org,DC=ruby-lang,DC=org\"\n    name = OpenSSL::X509::Name.parse_rfc2253(dn)\n    assert_equal(dn, name.to_s(OpenSSL::X509::Name::RFC2253))\n    ary = name.to_a\n    assert_equal(\"DC\", ary[0][0])\n    assert_equal(\"DC\", ary[1][0])\n    assert_equal(\"CN\", ary[2][0])\n    assert_equal(\"org\", ary[0][1])\n    assert_equal(\"ruby-lang\", ary[1][1])\n    assert_equal(\"www.ruby-lang.org\", ary[2][1])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])\n  end\n\n  def test_add_entry\n    dn = [\n      [\"DC\", \"org\"],\n      [\"DC\", \"ruby-lang\"],\n      [\"CN\", \"GOTOU Yuuzou\"],\n      [\"emailAddress\", \"gotoyuzo@ruby-lang.org\"],\n      [\"serialNumber\", \"123\"],\n    ]\n    name = OpenSSL::X509::Name.new\n    dn.each{|attr| name.add_entry(*attr) }\n    ary = name.to_a\n    assert_equal(\"/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123\", name.to_s)\n    assert_equal(\"DC\", ary[0][0])\n    assert_equal(\"DC\", ary[1][0])\n    assert_equal(\"CN\", ary[2][0])\n    assert_equal(\"emailAddress\", ary[3][0])\n    assert_equal(\"serialNumber\", ary[4][0])\n    assert_equal(\"org\", ary[0][1])\n    assert_equal(\"ruby-lang\", ary[1][1])\n    assert_equal(\"GOTOU Yuuzou\", ary[2][1])\n    assert_equal(\"gotoyuzo@ruby-lang.org\", ary[3][1])\n    assert_equal(\"123\", ary[4][1])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])\n    assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])\n    assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2])\n    assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2])\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_x509req.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Request < Test::Unit::TestCase\n  def setup\n    @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    @dsa256  = OpenSSL::TestUtils::TEST_KEY_DSA256\n    @dsa512  = OpenSSL::TestUtils::TEST_KEY_DSA512\n    @dn = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou\")\n  end\n\n  def issue_csr(ver, dn, key, digest)\n    req = OpenSSL::X509::Request.new\n    req.version = ver\n    req.subject = dn\n    req.public_key = key.public_key\n    req.sign(key, digest)\n    req\n  end\n\n  def test_public_key\n    req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)\n    req = OpenSSL::X509::Request.new(req.to_der)\n    assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)\n\n    req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)\n    assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)\n    req = OpenSSL::X509::Request.new(req.to_der)\n    assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)\n  end\n\n  def test_version\n    req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    assert_equal(0, req.version)\n    req = OpenSSL::X509::Request.new(req.to_der)\n    assert_equal(0, req.version)\n\n    req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    assert_equal(1, req.version)\n    req = OpenSSL::X509::Request.new(req.to_der)\n    assert_equal(1, req.version)\n  end\n\n  def test_subject\n    req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    assert_equal(@dn.to_der, req.subject.to_der)\n    req = OpenSSL::X509::Request.new(req.to_der)\n    assert_equal(@dn.to_der, req.subject.to_der)\n  end\n\n  def create_ext_req(exts)\n    ef = OpenSSL::X509::ExtensionFactory.new\n    exts = exts.collect{|e| ef.create_extension(*e) }\n    return OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence(exts)])\n  end\n\n  def get_ext_req(ext_req_value)\n    set = OpenSSL::ASN1.decode(ext_req_value)\n    seq = set.value[0]\n    seq.value.collect{|asn1ext|\n      OpenSSL::X509::Extension.new(asn1ext).to_a\n    }\n  end\n\n  def test_attr\n    exts = [\n      [\"keyUsage\", \"Digital Signature, Key Encipherment\", true],\n      [\"subjectAltName\", \"email:gotoyuzo@ruby-lang.org\", false],\n    ]\n    attrval = create_ext_req(exts)\n    attrs = [\n      OpenSSL::X509::Attribute.new(\"extReq\", attrval),\n      OpenSSL::X509::Attribute.new(\"msExtReq\", attrval),\n    ]\n\n    req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    attrs.each{|attr| req0.add_attribute(attr) }\n    req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    req1.attributes = attrs\n    assert_equal(req0.to_der, req1.to_der)\n\n    attrs = req0.attributes\n    assert_equal(2, attrs.size)\n    assert_equal(\"extReq\", attrs[0].oid)\n    assert_equal(\"msExtReq\", attrs[1].oid)\n    assert_equal(exts, get_ext_req(attrs[0].value))\n    assert_equal(exts, get_ext_req(attrs[1].value))\n\n    req = OpenSSL::X509::Request.new(req0.to_der)\n    attrs = req.attributes\n    assert_equal(2, attrs.size)\n    assert_equal(\"extReq\", attrs[0].oid)\n    assert_equal(\"msExtReq\", attrs[1].oid)\n    assert_equal(exts, get_ext_req(attrs[0].value))\n    assert_equal(exts, get_ext_req(attrs[1].value))\n  end\n\n  def test_sign_and_verify\n    req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)\n    assert_equal(true,  req.verify(@rsa1024))\n    assert_equal(false, req.verify(@rsa2048))\n    assert_equal(false, request_error_returns_false { req.verify(@dsa256) })\n    assert_equal(false, request_error_returns_false { req.verify(@dsa512) })\n    req.version = 1\n    assert_equal(false, req.verify(@rsa1024))\n\n    req = issue_csr(0, @dn, @rsa2048, OpenSSL::Digest::MD5.new)\n    assert_equal(false, req.verify(@rsa1024))\n    assert_equal(true,  req.verify(@rsa2048))\n    assert_equal(false, request_error_returns_false { req.verify(@dsa256) })\n    assert_equal(false, request_error_returns_false { req.verify(@dsa512) })\n    req.subject = OpenSSL::X509::Name.parse(\"/C=JP/CN=FooBar\")\n    assert_equal(false, req.verify(@rsa2048))\n\n    req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)\n    assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })\n    assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })\n    assert_equal(false, req.verify(@dsa256))\n    assert_equal(true,  req.verify(@dsa512))\n    req.public_key = @rsa1024.public_key\n    assert_equal(false, req.verify(@dsa512))\n\n    assert_raise(OpenSSL::X509::RequestError){\n      issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::DSS1.new) }\n    assert_raise(OpenSSL::X509::RequestError){\n      issue_csr(0, @dn, @dsa512, OpenSSL::Digest::SHA1.new) }\n    assert_raise(OpenSSL::X509::RequestError){\n      issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) }\n  end\n  \n  private\n  \n  def request_error_returns_false\n    yield\n  rescue OpenSSL::X509::RequestError\n    false\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/test_x509store.rb",
    "content": "begin\n  require \"openssl\"\n  require File.join(File.dirname(__FILE__), \"utils.rb\")\nrescue LoadError\nend\nrequire \"test/unit\"\n\nif defined?(OpenSSL)\n\nclass OpenSSL::TestX509Store < Test::Unit::TestCase\n  def setup\n    @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024\n    @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048\n    @dsa256  = OpenSSL::TestUtils::TEST_KEY_DSA256\n    @dsa512  = OpenSSL::TestUtils::TEST_KEY_DSA512\n    @ca1 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=CA1\")\n    @ca2 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=CA2\")\n    @ee1 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE1\")\n    @ee2 = OpenSSL::X509::Name.parse(\"/DC=org/DC=ruby-lang/CN=EE2\")\n  end\n\n  def teardown\n  end\n\n  def issue_cert(*args)\n    OpenSSL::TestUtils.issue_cert(*args)\n  end\n\n  def issue_crl(*args)\n    OpenSSL::TestUtils.issue_crl(*args)\n  end\n\n  def test_verify\n    now = Time.at(Time.now.to_i)\n    ca_exts = [\n      [\"basicConstraints\",\"CA:TRUE\",true],\n      [\"keyUsage\",\"cRLSign,keyCertSign\",true],\n    ]\n    ee_exts = [\n      [\"keyUsage\",\"keyEncipherment,digitalSignature\",true],\n    ]\n    ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, ca_exts,\n                          nil, nil, OpenSSL::Digest::SHA1.new)\n    ca2_cert = issue_cert(@ca2, @rsa1024, 2, now, now+1800, ca_exts,\n                          ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    ee1_cert = issue_cert(@ee1, @dsa256, 10, now, now+1800, ee_exts,\n                          ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)\n    ee2_cert = issue_cert(@ee2, @dsa512, 20, now, now+1800, ee_exts,\n                          ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)\n    ee3_cert = issue_cert(@ee2, @dsa512, 30, now-100, now-1, ee_exts,\n                          ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)\n    ee4_cert = issue_cert(@ee2, @dsa512, 40, now+1000, now+2000, ee_exts,\n                          ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)\n\n    revoke_info = []\n    crl1   = issue_crl(revoke_info, 1, now, now+1800, [],\n                       ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    revoke_info = [ [2, now, 1], ]\n    crl1_2 = issue_crl(revoke_info, 2, now, now+1800, [],\n                       ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    revoke_info = [ [20, now, 1], ]\n    crl2   = issue_crl(revoke_info, 1, now, now+1800, [],\n                       ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)\n    revoke_info = []\n    crl2_2 = issue_crl(revoke_info, 2, now-100, now-1, [],\n                       ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)\n\n    assert(true, ca1_cert.verify(ca1_cert.public_key))   # self signed\n    assert(true, ca2_cert.verify(ca1_cert.public_key))   # issued by ca1\n    assert(true, ee1_cert.verify(ca2_cert.public_key))   # issued by ca2\n    assert(true, ee2_cert.verify(ca2_cert.public_key))   # issued by ca2\n    assert(true, ee3_cert.verify(ca2_cert.public_key))   # issued by ca2\n    assert(true, crl1.verify(ca1_cert.public_key))       # issued by ca1\n    assert(true, crl1_2.verify(ca1_cert.public_key))     # issued by ca1\n    assert(true, crl2.verify(ca2_cert.public_key))       # issued by ca2\n    assert(true, crl2_2.verify(ca2_cert.public_key))     # issued by ca2\n\n    store = OpenSSL::X509::Store.new\n    assert_equal(false, store.verify(ca1_cert))\n    assert_not_equal(OpenSSL::X509::V_OK, store.error)\n\n    assert_equal(false, store.verify(ca2_cert))\n    assert_not_equal(OpenSSL::X509::V_OK, store.error)\n\n    store.add_cert(ca1_cert)\n    assert_equal(true, store.verify(ca2_cert))\n    assert_equal(OpenSSL::X509::V_OK, store.error)\n    assert_equal(\"ok\", store.error_string)\n    chain = store.chain\n    assert_equal(2, chain.size)\n    assert_equal(@ca2.to_der, chain[0].subject.to_der)\n    assert_equal(@ca1.to_der, chain[1].subject.to_der)\n\n    store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT\n    assert_equal(false, store.verify(ca2_cert))\n    assert_not_equal(OpenSSL::X509::V_OK, store.error)\n\n    store.purpose = OpenSSL::X509::PURPOSE_CRL_SIGN\n    assert_equal(true, store.verify(ca2_cert))\n    assert_equal(OpenSSL::X509::V_OK, store.error)\n\n    store.add_cert(ca2_cert)\n    store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT\n    assert_equal(true, store.verify(ee1_cert))\n    assert_equal(true, store.verify(ee2_cert))\n    assert_equal(OpenSSL::X509::V_OK, store.error)\n    assert_equal(\"ok\", store.error_string)\n    chain = store.chain\n    assert_equal(3, chain.size)\n    assert_equal(@ee2.to_der, chain[0].subject.to_der)\n    assert_equal(@ca2.to_der, chain[1].subject.to_der)\n    assert_equal(@ca1.to_der, chain[2].subject.to_der)\n    assert_equal(false, store.verify(ee3_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)\n    assert_match(/expire/i, store.error_string)\n    assert_equal(false, store.verify(ee4_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)\n    assert_match(/not yet valid/i, store.error_string)\n\n    store = OpenSSL::X509::Store.new\n    store.add_cert(ca1_cert)\n    store.add_cert(ca2_cert)\n    store.time = now + 1500\n    assert_equal(true, store.verify(ca1_cert))\n    assert_equal(true, store.verify(ca2_cert))\n    assert_equal(true, store.verify(ee4_cert))\n    store.time = now + 1900\n    assert_equal(true, store.verify(ca1_cert))\n    assert_equal(false, store.verify(ca2_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)\n    assert_equal(false, store.verify(ee4_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)\n    store.time = now + 4000\n    assert_equal(false, store.verify(ee1_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)\n    assert_equal(false, store.verify(ee4_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)\n\n    # the underlying X509 struct caches the result of the last\n    # verification for signature and not-before. so the following code\n    # rebuilds new objects to avoid site effect.\n    store.time = Time.now - 4000\n    assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ca2_cert)))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)\n    assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ee1_cert)))\n    assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)\n\n    return unless defined?(OpenSSL::X509::V_FLAG_CRL_CHECK)\n\n    store = OpenSSL::X509::Store.new\n    store.purpose = OpenSSL::X509::PURPOSE_ANY\n    store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK\n    store.add_cert(ca1_cert)\n    store.add_crl(crl1)   # revoke no cert\n    store.add_crl(crl2)   # revoke ee2_cert\n    assert_equal(true,  store.verify(ca1_cert))\n    assert_equal(true,  store.verify(ca2_cert))\n    assert_equal(true,  store.verify(ee1_cert, [ca2_cert]))\n    assert_equal(false, store.verify(ee2_cert, [ca2_cert]))\n\n    store = OpenSSL::X509::Store.new\n    store.purpose = OpenSSL::X509::PURPOSE_ANY\n    store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK\n    store.add_cert(ca1_cert)\n    store.add_crl(crl1_2) # revoke ca2_cert\n    store.add_crl(crl2)   # revoke ee2_cert\n    assert_equal(true,  store.verify(ca1_cert))\n    assert_equal(false, store.verify(ca2_cert))\n    assert_equal(true,  store.verify(ee1_cert, [ca2_cert]),\n      \"This test is expected to be success with OpenSSL 0.9.7c or later.\")\n    assert_equal(false, store.verify(ee2_cert, [ca2_cert]))\n\n    store.flags =\n      OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL\n    assert_equal(true,  store.verify(ca1_cert))\n    assert_equal(false, store.verify(ca2_cert))\n    assert_equal(false, store.verify(ee1_cert, [ca2_cert]))\n    assert_equal(false, store.verify(ee2_cert, [ca2_cert]))\n\n    store = OpenSSL::X509::Store.new\n    store.purpose = OpenSSL::X509::PURPOSE_ANY\n    store.flags =\n      OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL\n    store.add_cert(ca1_cert)\n    store.add_cert(ca2_cert)\n    store.add_crl(crl1)\n    store.add_crl(crl2_2) # issued by ca2 but expired.\n    assert_equal(true, store.verify(ca1_cert))\n    assert_equal(true, store.verify(ca2_cert))\n    assert_equal(false, store.verify(ee1_cert))\n    assert_equal(OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED, store.error)\n    assert_equal(false, store.verify(ee2_cert))\n  end\n\n  def test_set_errors\n    now = Time.now\n    ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, [],\n                          nil, nil, OpenSSL::Digest::SHA1.new)\n    store = OpenSSL::X509::Store.new\n    store.add_cert(ca1_cert)\n    assert_raises(OpenSSL::X509::StoreError){\n      store.add_cert(ca1_cert)  # add same certificate twice\n    }\n\n    revoke_info = []\n    crl1 = issue_crl(revoke_info, 1, now, now+1800, [],\n                     ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    revoke_info = [ [2, now, 1], ]\n    crl2 = issue_crl(revoke_info, 2, now+1800, now+3600, [],\n                     ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)\n    store.add_crl(crl1)\n    assert_raises(OpenSSL::X509::StoreError){\n      store.add_crl(crl2) # add CRL issued by same CA twice.\n    }\n  end\nend\n\nend\n"
  },
  {
    "path": "test/openssl/utils.rb",
    "content": "require \"openssl\"\nrequire \"test/unit\"\n\nmodule OpenSSL::TestUtils\n  TEST_KEY_RSA1024 = OpenSSL::PKey::RSA.new <<-_end_of_pem_\n-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx\naKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/\nQ3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB\nAoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0\nmaDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T\ngnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572\n74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE\nJiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX\nsOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII\n8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA\nwa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi\nqRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD\ndPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA==\n-----END RSA PRIVATE KEY-----\n  _end_of_pem_\n\n  TEST_KEY_RSA2048 = OpenSSL::PKey::RSA.new <<-_end_of_pem_\n-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN\ns9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign\n4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D\nkYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl\nNwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J\nDRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb\nI0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq\nPIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V\nseSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0\nXc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc\nVsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW\nwORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G\n0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj\nXGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb\naqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n\nh2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw\nIvnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k\nIQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb\nv4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId\nU0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr\nvd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS\nCc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC\n9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41\ngBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG\n4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw==\n-----END RSA PRIVATE KEY-----\n  _end_of_pem_\n\n  TEST_KEY_DSA256 = OpenSSL::PKey::DSA.new <<-_end_of_pem_\n-----BEGIN DSA PRIVATE KEY-----\nMIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE\n9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed\nAkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM\n3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT\nb4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn\nISNX5cMzFHRW3Q==\n-----END DSA PRIVATE KEY-----\n  _end_of_pem_\n\n  TEST_KEY_DSA512 = OpenSSL::PKey::DSA.new <<-_end_of_pem_\n-----BEGIN DSA PRIVATE KEY-----\nMIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok\nRZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D\nAkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR\nS/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++\nQ1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S\n55jreJD3Se3slps=\n-----END DSA PRIVATE KEY-----\n  _end_of_pem_\n\n  module_function\n\n  def issue_cert(dn, key, serial, not_before, not_after, extensions,\n                 issuer, issuer_key, digest)\n    cert = OpenSSL::X509::Certificate.new\n    issuer = cert unless issuer\n    issuer_key = key unless issuer_key\n    cert.version = 2\n    cert.serial = serial\n    cert.subject = dn\n    cert.issuer = issuer.subject\n    cert.public_key = key.public_key\n    cert.not_before = not_before\n    cert.not_after = not_after\n    ef = OpenSSL::X509::ExtensionFactory.new\n    ef.subject_certificate = cert\n    ef.issuer_certificate = issuer\n    extensions.each{|oid, value, critical|\n      cert.add_extension(ef.create_extension(oid, value, critical))\n    }\n    cert.sign(issuer_key, digest)\n    cert\n  end\n\n  def issue_crl(revoke_info, serial, lastup, nextup, extensions, \n                issuer, issuer_key, digest)\n    crl = OpenSSL::X509::CRL.new\n    crl.issuer = issuer.subject\n    crl.version = 1\n    crl.last_update = lastup\n    crl.next_update = nextup\n    revoke_info.each{|serial, time, reason_code|\n      revoked = OpenSSL::X509::Revoked.new\n      revoked.serial = serial\n      revoked.time = time\n      enum = OpenSSL::ASN1::Enumerated(reason_code)\n      ext = OpenSSL::X509::Extension.new(\"CRLReason\", enum)\n      revoked.add_extension(ext)\n      crl.add_revoked(revoked)\n    }\n    ef = OpenSSL::X509::ExtensionFactory.new\n    ef.issuer_certificate = issuer\n    ef.crl = crl\n    crlnum = OpenSSL::ASN1::Integer(serial)\n    crl.add_extension(OpenSSL::X509::Extension.new(\"crlNumber\", crlnum))\n    extensions.each{|oid, value, critical|\n      crl.add_extension(ef.create_extension(oid, value, critical))\n    }\n    crl.sign(issuer_key, digest)\n    crl\n  end\n\n  def get_subject_key_id(cert)\n    asn1_cert = OpenSSL::ASN1.decode(cert)\n    tbscert   = asn1_cert.value[0]\n    pkinfo    = tbscert.value[6]\n    publickey = pkinfo.value[1]\n    pkvalue   = publickey.value\n    OpenSSL::Digest::SHA1.hexdigest(pkvalue).scan(/../).join(\":\").upcase\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_getopts.rb",
    "content": "require 'test/unit'\n\nclass TestOptionParserGetopts < Test::Unit::TestCase\n  def setup\n    @opt = OptionParser.new\n  end\n\n  def test_short_noarg\n    o = @opt.getopts(%w[-a], \"ab\")\n    assert_equal(true, o['a'])\n    assert_equal(false, o['b'])\n  end\n\n  def test_short_arg\n    o = @opt.getopts(%w[-a1], \"a:b:\")\n    assert_equal(\"1\", o['a'])\n    assert_equal(nil, o['b'])\n  end\n\n  def test_long_noarg\n    o = @opt.getopts(%w[--foo], \"\", \"foo\", \"bar\")\n    assert_equal(true, o['foo'])\n    assert_equal(false, o['bar'])\n  end\n\n  def test_long_arg\n    o = @opt.getopts(%w[--bar ZOT], \"\", \"foo:FOO\", \"bar:BAR\")\n    assert_equal(\"FOO\", o['foo'])\n    assert_equal(\"ZOT\", o['bar'])\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_noarg.rb",
    "content": "require 'test_optparse'\n\nmodule TestOptionParser::NoArg\n  class Def1 < TestOptionParser\n    include NoArg\n    def setup\n      super\n      @opt.def_option(\"-x\") {|x| @flag = x}\n      @opt.def_option(\"--option\") {|x| @flag = x}\n    end\n  end\n  class Def2 < TestOptionParser\n    include NoArg\n    def setup\n      super\n      @opt.def_option(\"-x\", \"--option\") {|x| @flag = x}\n    end\n  end\n\n  def test_short\n    assert_raises(OptionParser::InvalidOption) {@opt.parse!(%w\"-xq\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x\")})\n    assert_equal(true, @flag)\n    @flag = nil\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"-x foo\")})\n    assert_equal(true, @flag)\n  end\n\n  def test_abbrev\n    assert_raises(OptionParser::InvalidOption) {@opt.parse!(%w\"-oq\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o\")})\n    assert_equal(true, @flag)\n    @flag = nil\n    assert_raises(OptionParser::InvalidOption) {@opt.parse!(%w\"-O\")}\n    assert_nil(@flag)\n    @flag = nil\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"-o foo\")})\n    assert_equal(true, @flag)\n  end\n\n  def test_long\n    assert_raises(OptionParser::NeedlessArgument) {@opt.parse!(%w\"--option=x\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt\")})\n    assert_equal(true, @flag)\n    @flag = nil\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"--opt foo\")})\n    assert_equal(true, @flag)\n  end\n\n  def test_ambiguous\n    @opt.def_option(\"--open\") {|x|}\n    assert_raises(OptionParser::AmbiguousOption) {@opt.parse!(%w\"--op\")}\n    assert_raises(OptionParser::AmbiguousOption) {@opt.parse!(%w\"-o\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt\")})\n    assert_equal(true, @flag)\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_optarg.rb",
    "content": "require 'test_optparse'\n\nclass TestOptionParser::OptArg < TestOptionParser\n  def setup\n    super\n    @opt.def_option(\"-x[VAL]\") {|x| @flag = x}\n    @opt.def_option(\"--option[=VAL]\") {|x| @flag = x}\n  end\n\n  def test_short\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x\")})\n    assert_equal(nil, @flag)\n    @flag = false\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"-x foo\")})\n    assert_equal(nil, @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-xfoo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x=\")})\n    assert_equal(\"=\", @flag)\n  end\n\n  def test_abbrev\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o\")})\n    assert_equal(nil, @flag)\n    @flag = false\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"-o foo\")})\n    assert_equal(nil, @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-ofoo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o=\")})\n    assert_equal(\"=\", @flag)\n  end\n\n  def test_long\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt\")})\n    assert_equal(nil, @flag)\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"--opt= foo\")})\n    assert_equal(\"\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt=foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"--opt foo\")})\n    assert_equal(nil, @flag)\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_optparse.rb",
    "content": "require 'test/unit'\nrequire 'optparse'\n\nclass TestOptionParser < Test::Unit::TestCase\n  def setup\n    @opt = OptionParser.new\n    @flag = self.class\t\t# cannot set by option\n  end\n  def no_error(*args)\n    assert_nothing_raised(*args) {return yield}\n  end\n\n  def test_permute\n    assert_equal(%w\"\", no_error {@opt.permute!(%w\"\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo bar\", no_error {@opt.permute!(%w\"foo bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"- foo bar\", no_error {@opt.permute!(%w\"- foo bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo bar\", no_error {@opt.permute!(%w\"-- foo bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo - bar\", no_error {@opt.permute!(%w\"foo - bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo bar\", no_error {@opt.permute!(%w\"foo -- bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo --help bar\", no_error {@opt.permute!(%w\"foo -- --help bar\")})\n    assert_equal(self.class, @flag)\n  end\n\n  def test_order\n    assert_equal(%w\"\", no_error {@opt.order!(%w\"\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo bar\", no_error {@opt.order!(%w\"foo bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"- foo bar\", no_error {@opt.order!(%w\"- foo bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo bar\", no_error {@opt.permute!(%w\"-- foo bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo - bar\", no_error {@opt.order!(%w\"foo - bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo -- bar\", no_error {@opt.order!(%w\"foo -- bar\")})\n    assert_equal(self.class, @flag)\n    assert_equal(%w\"foo -- --help bar\", no_error {@opt.order!(%w\"foo -- --help bar\")})\n    assert_equal(self.class, @flag)\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_placearg.rb",
    "content": "require 'test_optparse'\n\nclass TestOptionParser::PlaceArg < TestOptionParser\n  def setup\n    super\n    @opt.def_option(\"-x [VAL]\") {|x| @flag = x}\n    @opt.def_option(\"--option [VAL]\") {|x| @flag = x}\n    @opt.def_option(\"-n\") {}\n  end\n\n  def test_short\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x -n\")})\n    assert_equal(nil, @flag)\n    @flag = false\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-xbar\")})\n    assert_equal(\"bar\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x=\")})\n    assert_equal(\"=\", @flag)\n  end\n\n  def test_abbrev\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o -n\")})\n    assert_equal(nil, @flag)\n    @flag = false\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-obar\")})\n    assert_equal(\"bar\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o=\")})\n    assert_equal(\"=\", @flag)\n  end\n\n  def test_long\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt -n\")})\n    assert_equal(nil, @flag)\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"--opt= foo\")})\n    assert_equal(\"\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt=foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt bar\")})\n    assert_equal(\"bar\", @flag)\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_reqarg.rb",
    "content": "require 'test_optparse'\n\nmodule TestOptionParser::ReqArg\n  class Def1 < TestOptionParser\n    include ReqArg\n    def setup\n      super\n      @opt.def_option(\"-xVAL\") {|x| @flag = x}\n      @opt.def_option(\"--option=VAL\") {|x| @flag = x}\n    end\n  end\n  class Def2 < TestOptionParser\n    include ReqArg\n    def setup\n      super\n      @opt.def_option(\"-x\", \"--option=VAL\") {|x| @flag = x}\n    end\n  end\n  class Def3 < TestOptionParser\n    include ReqArg\n    def setup\n      super\n      @opt.def_option(\"--option=VAL\", \"-x\") {|x| @flag = x}\n    end\n  end\n  class Def4 < TestOptionParser\n    include ReqArg\n    def setup\n      super\n      @opt.def_option(\"-xVAL\", \"--option=VAL\") {|x| @flag = x}\n    end\n  end\n\n  def test_short\n    assert_raises(OptionParser::MissingArgument) {@opt.parse!(%w\"-x\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-xbar\")})\n    assert_equal(\"bar\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-x=\")})\n    assert_equal(\"=\", @flag)\n  end\n\n  def test_abbrev\n    assert_raises(OptionParser::MissingArgument) {@opt.parse!(%w\"-o\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-obar\")})\n    assert_equal(\"bar\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"-o=\")})\n    assert_equal(\"=\", @flag)\n  end\n\n  def test_long\n    assert_raises(OptionParser::MissingArgument) {@opt.parse!(%w\"--opt\")}\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt foo\")})\n    assert_equal(\"foo\", @flag)\n    assert_equal(%w\"foo\", no_error {@opt.parse!(%w\"--opt= foo\")})\n    assert_equal(\"\", @flag)\n    assert_equal(%w\"\", no_error {@opt.parse!(%w\"--opt=foo\")})\n    assert_equal(\"foo\", @flag)\n  end\nend\n"
  },
  {
    "path": "test/optparse/test_summary.rb",
    "content": "require 'test/unit'\nrequire 'optparse'\n\nclass TestOptionParser < Test::Unit::TestCase; end\nclass TestOptionParser::SummaryTest < Test::Unit::TestCase\n  def test_short_clash\n    r = nil\n    o = OptionParser.new do |opts|\n      opts.on(\"-f\", \"--first-option\", \"description 1\", \"description 2\"){r = \"first-option\"}\n      opts.on(\"-t\", \"--test-option\"){r = \"test-option\"}\n      opts.on(\"-t\", \"--another-test-option\"){r = \"another-test-option\"}\n      opts.separator \"this is\\nseparator\"\n      opts.on(\"-l\", \"--last-option\"){r = \"last-option\"}\n    end\n    s = o.summarize\n    o.parse(\"-t\")\n    assert_match(/--#{r}/, s.grep(/^\\s*-t,/)[0])\n    assert_match(/first-option/, s[0])\n    assert_match(/description 1/, s[0])\n    assert_match(/description 2/, s[1])\n    assert_match(/last-option/, s[-1])\n  end\nend\n"
  },
  {
    "path": "test/ostruct/test_ostruct.rb",
    "content": "require 'test/unit'\nrequire 'ostruct'\n\nclass TC_OpenStruct < Test::Unit::TestCase\n  def assert_not_respond_to(object, method, message=\"\")\n    _wrap_assertion do\n      full_message = build_message(message, <<EOT, object, object.class, method)\n<?>\nof type <?>\nexpected not to respond_to\\\\?<?>.\nEOT\n      _wrap_assertion do\n        if object.respond_to?(method)\n          raise Test::Unit::AssertionFailedError, full_message, caller(5)\n        end\n      end\n    end\n  end\n\n  def test_equality\n    o1 = OpenStruct.new\n    o2 = OpenStruct.new\n    assert_equal(o1, o2)\n\n    o1.a = 'a'\n    assert_not_equal(o1, o2)\n\n    o2.a = 'a'\n    assert_equal(o1, o2)\n\n    o1.a = 'b'\n    assert_not_equal(o1, o2)\n\n    o2 = Object.new\n    o2.instance_eval{@table = {:a => 'b'}}\n    assert_not_equal(o1, o2)\n  end\n  \n  def test_inspect\n    foo = OpenStruct.new\n    assert_equal(\"#<OpenStruct>\", foo.inspect)\n    foo.bar = 1\n    foo.baz = 2\n    foo.foo = 0\n    assert_match(/\\A#<OpenStruct (?:(?:foo=0|bar=1|baz=2)(?:, (?!>))?)+>\\z/, foo.inspect)\n    assert_match(/ foo=0(?:, |>\\z)/, foo.inspect)\n    assert_match(/ bar=1(?:, |>\\z)/, foo.inspect)\n    assert_match(/ baz=2(?:, |>\\z)/, foo.inspect)\n\n    foo = OpenStruct.new\n    foo.bar = OpenStruct.new\n    assert_equal('#<OpenStruct bar=#<OpenStruct>>', foo.inspect)\n    foo.bar.foo = foo\n    assert_equal('#<OpenStruct bar=#<OpenStruct foo=#<OpenStruct ...>>>', foo.inspect)\n  end\n\n  def test_frozen\n    o = OpenStruct.new\n    o.a = 'a'\n    o.freeze\n    assert_raise(TypeError) {o.b = 'b'}\n    assert_not_respond_to(o, :b)\n    assert_raise(TypeError) {o.a = 'z'}\n    assert_equal('a', o.a)\n  end\nend\n"
  },
  {
    "path": "test/pathname/test_pathname.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'test/unit'\nrequire 'pathname'\n\nrequire 'fileutils'\nrequire 'tmpdir'\nrequire 'enumerator'\n\nclass TestPathname < Test::Unit::TestCase\n  def self.define_assertion(name, &block)\n    @defassert_num ||= {}\n    @defassert_num[name] ||= 0\n    @defassert_num[name] += 1\n    define_method(\"test_#{name}_#{@defassert_num[name]}\", &block)\n  end\n\n  def self.defassert(name, result, *args)\n    define_assertion(name) {\n      assert_equal(result, self.send(name, *args), \"#{name}(#{args.map {|a| a.inspect }.join(', ')})\")\n    }\n  end\n\n  DOSISH = File::ALT_SEPARATOR != nil\n  DOSISH_DRIVE_LETTER = File.dirname(\"A:\") == \"A:.\"\n  DOSISH_UNC = File.dirname(\"//\") == \"//\"\n\n  def cleanpath_aggressive(path)\n    Pathname.new(path).cleanpath.to_s\n  end\n\n  defassert(:cleanpath_aggressive, '/',       '/')\n  defassert(:cleanpath_aggressive, '.',       '')\n  defassert(:cleanpath_aggressive, '.',       '.')\n  defassert(:cleanpath_aggressive, '..',      '..')\n  defassert(:cleanpath_aggressive, 'a',       'a')\n  defassert(:cleanpath_aggressive, '/',       '/.')\n  defassert(:cleanpath_aggressive, '/',       '/..')\n  defassert(:cleanpath_aggressive, '/a',      '/a')\n  defassert(:cleanpath_aggressive, '.',       './')\n  defassert(:cleanpath_aggressive, '..',      '../')\n  defassert(:cleanpath_aggressive, 'a',       'a/')\n  defassert(:cleanpath_aggressive, 'a/b',     'a//b')\n  defassert(:cleanpath_aggressive, 'a',       'a/.')\n  defassert(:cleanpath_aggressive, 'a',       'a/./')\n  defassert(:cleanpath_aggressive, '.',       'a/..')\n  defassert(:cleanpath_aggressive, '.',       'a/../')\n  defassert(:cleanpath_aggressive, '/a',      '/a/.')\n  defassert(:cleanpath_aggressive, '..',      './..')\n  defassert(:cleanpath_aggressive, '..',      '../.')\n  defassert(:cleanpath_aggressive, '..',      './../')\n  defassert(:cleanpath_aggressive, '..',      '.././')\n  defassert(:cleanpath_aggressive, '/',       '/./..')\n  defassert(:cleanpath_aggressive, '/',       '/../.')\n  defassert(:cleanpath_aggressive, '/',       '/./../')\n  defassert(:cleanpath_aggressive, '/',       '/.././')\n  defassert(:cleanpath_aggressive, 'a/b/c',   'a/b/c')\n  defassert(:cleanpath_aggressive, 'b/c',     './b/c')\n  defassert(:cleanpath_aggressive, 'a/c',     'a/./c')\n  defassert(:cleanpath_aggressive, 'a/b',     'a/b/.')\n  defassert(:cleanpath_aggressive, '.',       'a/../.')\n  defassert(:cleanpath_aggressive, '/a',      '/../.././../a')\n  defassert(:cleanpath_aggressive, '../../d', 'a/b/../../../../c/../d')\n\n  if DOSISH_UNC\n    defassert(:cleanpath_aggressive, '//a/b/c', '//a/b/c/')\n  else\n    defassert(:cleanpath_aggressive, '/',       '///')\n    defassert(:cleanpath_aggressive, '/a',      '///a')\n    defassert(:cleanpath_aggressive, '/',       '///..')\n    defassert(:cleanpath_aggressive, '/',       '///.')\n    defassert(:cleanpath_aggressive, '/',       '///a/../..')\n  end\n\n  def cleanpath_conservative(path)\n    Pathname.new(path).cleanpath(true).to_s\n  end\n\n  defassert(:cleanpath_conservative, '/',      '/')\n  defassert(:cleanpath_conservative, '.',      '')\n  defassert(:cleanpath_conservative, '.',      '.')\n  defassert(:cleanpath_conservative, '..',     '..')\n  defassert(:cleanpath_conservative, 'a',      'a')\n  defassert(:cleanpath_conservative, '/',      '/.')\n  defassert(:cleanpath_conservative, '/',      '/..')\n  defassert(:cleanpath_conservative, '/a',     '/a')\n  defassert(:cleanpath_conservative, '.',      './')\n  defassert(:cleanpath_conservative, '..',     '../')\n  defassert(:cleanpath_conservative, 'a/',     'a/')\n  defassert(:cleanpath_conservative, 'a/b',    'a//b')\n  defassert(:cleanpath_conservative, 'a/.',    'a/.')\n  defassert(:cleanpath_conservative, 'a/.',    'a/./')\n  defassert(:cleanpath_conservative, 'a/..',   'a/../')\n  defassert(:cleanpath_conservative, '/a/.',   '/a/.')\n  defassert(:cleanpath_conservative, '..',     './..')\n  defassert(:cleanpath_conservative, '..',     '../.')\n  defassert(:cleanpath_conservative, '..',     './../')\n  defassert(:cleanpath_conservative, '..',     '.././')\n  defassert(:cleanpath_conservative, '/',      '/./..')\n  defassert(:cleanpath_conservative, '/',      '/../.')\n  defassert(:cleanpath_conservative, '/',      '/./../')\n  defassert(:cleanpath_conservative, '/',      '/.././')\n  defassert(:cleanpath_conservative, 'a/b/c',  'a/b/c')\n  defassert(:cleanpath_conservative, 'b/c',    './b/c')\n  defassert(:cleanpath_conservative, 'a/c',    'a/./c')\n  defassert(:cleanpath_conservative, 'a/b/.',  'a/b/.')\n  defassert(:cleanpath_conservative, 'a/..',   'a/../.')\n  defassert(:cleanpath_conservative, '/a',     '/../.././../a')\n  defassert(:cleanpath_conservative, 'a/b/../../../../c/../d', 'a/b/../../../../c/../d')\n\n  if DOSISH_UNC\n    defassert(:cleanpath_conservative, '//',     '//')\n  else\n    defassert(:cleanpath_conservative, '/',      '//')\n  end\n\n  # has_trailing_separator?(path) -> bool\n  def has_trailing_separator?(path)\n    Pathname.allocate.__send__(:has_trailing_separator?, path)\n  end\n\n  defassert(:has_trailing_separator?, false, \"/\")\n  defassert(:has_trailing_separator?, false, \"///\")\n  defassert(:has_trailing_separator?, false, \"a\")\n  defassert(:has_trailing_separator?, true, \"a/\")\n\n  def add_trailing_separator(path)\n    Pathname.allocate.__send__(:add_trailing_separator, path)\n  end\n\n  def del_trailing_separator(path)\n    Pathname.allocate.__send__(:del_trailing_separator, path)\n  end\n\n  defassert(:del_trailing_separator, \"/\", \"/\")\n  defassert(:del_trailing_separator, \"/a\", \"/a\")\n  defassert(:del_trailing_separator, \"/a\", \"/a/\")\n  defassert(:del_trailing_separator, \"/a\", \"/a//\")\n  defassert(:del_trailing_separator, \".\", \".\")\n  defassert(:del_trailing_separator, \".\", \"./\")\n  defassert(:del_trailing_separator, \".\", \".//\")\n\n  if DOSISH_DRIVE_LETTER\n    defassert(:del_trailing_separator, \"A:\", \"A:\")\n    defassert(:del_trailing_separator, \"A:/\", \"A:/\")\n    defassert(:del_trailing_separator, \"A:/\", \"A://\")\n    defassert(:del_trailing_separator, \"A:.\", \"A:.\")\n    defassert(:del_trailing_separator, \"A:.\", \"A:./\")\n    defassert(:del_trailing_separator, \"A:.\", \"A:.//\")\n  end\n\n  if DOSISH_UNC\n    defassert(:del_trailing_separator, \"//\", \"//\")\n    defassert(:del_trailing_separator, \"//a\", \"//a\")\n    defassert(:del_trailing_separator, \"//a\", \"//a/\")\n    defassert(:del_trailing_separator, \"//a\", \"//a//\")\n    defassert(:del_trailing_separator, \"//a/b\", \"//a/b\")\n    defassert(:del_trailing_separator, \"//a/b\", \"//a/b/\")\n    defassert(:del_trailing_separator, \"//a/b\", \"//a/b//\")\n    defassert(:del_trailing_separator, \"//a/b/c\", \"//a/b/c\")\n    defassert(:del_trailing_separator, \"//a/b/c\", \"//a/b/c/\")\n    defassert(:del_trailing_separator, \"//a/b/c\", \"//a/b/c//\")\n  else\n    defassert(:del_trailing_separator, \"/\", \"///\")\n    defassert(:del_trailing_separator, \"///a\", \"///a/\")\n  end\n\n  if DOSISH\n    defassert(:del_trailing_separator, \"a\", \"a\\\\\")\n    require 'Win32API'\n    if Win32API.new('kernel32', 'GetACP', nil, 'L').call == 932\n      defassert(:del_trailing_separator, \"\\225\\\\\", \"\\225\\\\\\\\\") # SJIS\n    end\n  end\n\n  def plus(path1, path2) # -> path\n    (Pathname.new(path1) + Pathname.new(path2)).to_s\n  end\n\n  defassert(:plus, '/', '/', '/')\n  defassert(:plus, 'a/b', 'a', 'b')\n  defassert(:plus, 'a', 'a', '.')\n  defassert(:plus, 'b', '.', 'b')\n  defassert(:plus, '.', '.', '.')\n  defassert(:plus, '/b', 'a', '/b')\n\n  defassert(:plus, '/', '/', '..')\n  defassert(:plus, '.', 'a', '..')\n  defassert(:plus, 'a', 'a/b', '..')\n  defassert(:plus, '../..', '..', '..')\n  defassert(:plus, '/c', '/', '../c')\n  defassert(:plus, 'c', 'a', '../c')\n  defassert(:plus, 'a/c', 'a/b', '../c')\n  defassert(:plus, '../../c', '..', '../c')\n\n  defassert(:plus, 'a//b/d//e', 'a//b/c', '../d//e')\n\n  def relative?(path)\n    Pathname.new(path).relative?\n  end\n\n  defassert(:relative?, false, '/')\n  defassert(:relative?, false, '/a')\n  defassert(:relative?, false, '/..')\n  defassert(:relative?, true, 'a')\n  defassert(:relative?, true, 'a/b')\n\n  if DOSISH_DRIVE_LETTER\n    defassert(:relative?, false, 'A:')\n    defassert(:relative?, false, 'A:/')\n    defassert(:relative?, false, 'A:/a')\n  end\n\n  if File.dirname('//') == '//'\n    defassert(:relative?, false, '//')\n    defassert(:relative?, false, '//a')\n    defassert(:relative?, false, '//a/')\n    defassert(:relative?, false, '//a/b')\n    defassert(:relative?, false, '//a/b/')\n    defassert(:relative?, false, '//a/b/c')\n  end\n\n  def relative_path_from(dest_directory, base_directory)\n    Pathname.new(dest_directory).relative_path_from(Pathname.new(base_directory)).to_s\n  end\n\n  defassert(:relative_path_from, \"../a\", \"a\", \"b\")\n  defassert(:relative_path_from, \"../a\", \"a\", \"b/\")\n  defassert(:relative_path_from, \"../a\", \"a/\", \"b\")\n  defassert(:relative_path_from, \"../a\", \"a/\", \"b/\")\n  defassert(:relative_path_from, \"../a\", \"/a\", \"/b\")\n  defassert(:relative_path_from, \"../a\", \"/a\", \"/b/\")\n  defassert(:relative_path_from, \"../a\", \"/a/\", \"/b\")\n  defassert(:relative_path_from, \"../a\", \"/a/\", \"/b/\")\n\n  defassert(:relative_path_from, \"../b\", \"a/b\", \"a/c\")\n  defassert(:relative_path_from, \"../a\", \"../a\", \"../b\")\n\n  defassert(:relative_path_from, \"a\", \"a\", \".\")\n  defassert(:relative_path_from, \"..\", \".\", \"a\")\n\n  defassert(:relative_path_from, \".\", \".\", \".\")\n  defassert(:relative_path_from, \".\", \"..\", \"..\")\n  defassert(:relative_path_from, \"..\", \"..\", \".\")\n\n  defassert(:relative_path_from, \"c/d\", \"/a/b/c/d\", \"/a/b\")\n  defassert(:relative_path_from, \"../..\", \"/a/b\", \"/a/b/c/d\")\n  defassert(:relative_path_from, \"../../../../e\", \"/e\", \"/a/b/c/d\")\n  defassert(:relative_path_from, \"../b/c\", \"a/b/c\", \"a/d\")\n\n  defassert(:relative_path_from, \"../a\", \"/../a\", \"/b\")\n  defassert(:relative_path_from, \"../../a\", \"../a\", \"b\")\n  defassert(:relative_path_from, \".\", \"/a/../../b\", \"/b\")\n  defassert(:relative_path_from, \"..\", \"a/..\", \"a\")\n  defassert(:relative_path_from, \".\", \"a/../b\", \"b\")\n\n  defassert(:relative_path_from, \"a\", \"a\", \"b/..\")\n  defassert(:relative_path_from, \"b/c\", \"b/c\", \"b/..\")\n\n  def self.defassert_raise(name, exc, *args)\n    define_assertion(name) {\n      message = \"#{name}(#{args.map {|a| a.inspect }.join(', ')})\"\n      assert_raise(exc, message) { self.send(name, *args) }\n    }\n  end\n\n  defassert_raise(:relative_path_from, ArgumentError, \"/\", \".\")\n  defassert_raise(:relative_path_from, ArgumentError, \".\", \"/\")\n  defassert_raise(:relative_path_from, ArgumentError, \"a\", \"..\")\n  defassert_raise(:relative_path_from, ArgumentError, \".\", \"..\")\n\n  def realpath(path)\n    Pathname.new(path).realpath.to_s\n  end\n\n  def test_realpath\n    begin\n      File.symlink(nil, nil)\n    rescue NotImplementedError\n      return\n    rescue TypeError\n    end\n    Dir.mktmpdir('rubytest-pathname') {|dir|\n      File.symlink(\"not-exist-target\", \"#{dir}/not-exist\")\n      assert_raise(Errno::ENOENT) { realpath(\"#{dir}/not-exist\") }\n      File.symlink(\"loop\", \"#{dir}/loop\")\n      assert_raise(Errno::ELOOP) { realpath(\"#{dir}/loop\") }\n    }\n  end\n\n  def descend(path)\n    Pathname.new(path).enum_for(:descend).map {|v| v.to_s }\n  end\n\n  defassert(:descend, %w[/ /a /a/b /a/b/c], \"/a/b/c\")\n  defassert(:descend, %w[a a/b a/b/c], \"a/b/c\")\n  defassert(:descend, %w[. ./a ./a/b ./a/b/c], \"./a/b/c\")\n  defassert(:descend, %w[a/], \"a/\")\n\n  def ascend(path)\n    Pathname.new(path).enum_for(:ascend).map {|v| v.to_s }\n  end\n\n  defassert(:ascend, %w[/a/b/c /a/b /a /], \"/a/b/c\")\n  defassert(:ascend, %w[a/b/c a/b a], \"a/b/c\")\n  defassert(:ascend, %w[./a/b/c ./a/b ./a .], \"./a/b/c\")\n  defassert(:ascend, %w[a/], \"a/\")\n\n  def test_initialize\n    p1 = Pathname.new('a')\n    assert_equal('a', p1.to_s)\n    p2 = Pathname.new(p1)\n    assert_equal(p1, p2)\n  end\n\n  def test_initialize_nul\n    assert_raise(ArgumentError) { Pathname.new(\"a\\0\") }\n  end\n\n  class AnotherStringLike # :nodoc:\n    def initialize(s) @s = s end\n    def to_str() @s end\n    def ==(other) @s == other end\n  end\n\n  def test_equality\n    obj = Pathname.new(\"a\")\n    str = \"a\"\n    sym = :a\n    ano = AnotherStringLike.new(\"a\")\n    assert_equal(false, obj == str)\n    assert_equal(false, str == obj)\n    assert_equal(false, obj == ano)\n    assert_equal(false, ano == obj)\n    assert_equal(false, obj == sym)\n    assert_equal(false, sym == obj)\n\n    obj2 = Pathname.new(\"a\")\n    assert_equal(true, obj == obj2)\n    assert_equal(true, obj === obj2)\n    assert_equal(true, obj.eql?(obj2))\n  end\n\n  def test_hashkey\n    h = {}\n    h[Pathname.new(\"a\")] = 1\n    h[Pathname.new(\"a\")] = 2\n    assert_equal(1, h.size)\n  end\n\n  def assert_pathname_cmp(e, s1, s2)\n    p1 = Pathname.new(s1)\n    p2 = Pathname.new(s2)\n    r = p1 <=> p2\n    assert(e == r,\n      \"#{p1.inspect} <=> #{p2.inspect}: <#{e}> expected but was <#{r}>\")\n  end\n  def test_comparison\n    assert_pathname_cmp( 0, \"a\", \"a\")\n    assert_pathname_cmp( 1, \"b\", \"a\")\n    assert_pathname_cmp(-1, \"a\", \"b\")\n    ss = %w(\n      a\n      a/\n      a/b\n      a.\n      a0\n    )\n    s1 = ss.shift\n    ss.each {|s2|\n      assert_pathname_cmp(-1, s1, s2)\n      s1 = s2\n    }\n  end\n\n  def test_comparison_string\n    assert_equal(nil, Pathname.new(\"a\") <=> \"a\")\n    assert_equal(nil, \"a\" <=> Pathname.new(\"a\"))\n  end\n\n  def pathsub(path, pat, repl) Pathname.new(path).sub(pat, repl).to_s end\n  defassert(:pathsub, \"a.o\", \"a.c\", /\\.c\\z/, \".o\")\n\n  def test_sub_matchdata\n    result = Pathname(\"abc.gif\").sub(/\\..*/) {\n      assert_not_nil($~)\n      assert_equal(\".gif\", $~[0])\n      \".png\"\n    }\n    assert_equal(\"abc.png\", result.to_s)\n  end\n\n  def root?(path)\n    Pathname.new(path).root?\n  end\n\n  defassert(:root?, true, \"/\")\n  defassert(:root?, true, \"//\")\n  defassert(:root?, true, \"///\")\n  defassert(:root?, false, \"\")\n  defassert(:root?, false, \"a\")\n\n  def test_destructive_update\n    path = Pathname.new(\"a\")\n    path.to_s.replace \"b\"\n    assert_equal(Pathname.new(\"a\"), path)\n  end\n\n  def test_null_character\n    assert_raise(ArgumentError) { Pathname.new(\"\\0\") }\n  end\n\n  def test_taint\n    obj = Pathname.new(\"a\"); assert_same(obj, obj.taint)\n    obj = Pathname.new(\"a\"); assert_same(obj, obj.untaint)\n\n    assert_equal(false, Pathname.new(\"a\"      )           .tainted?)\n    assert_equal(false, Pathname.new(\"a\"      )      .to_s.tainted?)\n    assert_equal(true,  Pathname.new(\"a\"      ).taint     .tainted?)\n    assert_equal(true,  Pathname.new(\"a\"      ).taint.to_s.tainted?)\n    assert_equal(true,  Pathname.new(\"a\".taint)           .tainted?)\n    assert_equal(true,  Pathname.new(\"a\".taint)      .to_s.tainted?)\n    assert_equal(true,  Pathname.new(\"a\".taint).taint     .tainted?)\n    assert_equal(true,  Pathname.new(\"a\".taint).taint.to_s.tainted?)\n\n    str = \"a\"\n    path = Pathname.new(str)\n    str.taint\n    assert_equal(false, path     .tainted?)\n    assert_equal(false, path.to_s.tainted?)\n  end\n\n  def test_untaint\n    obj = Pathname.new(\"a\"); assert_same(obj, obj.untaint)\n\n    assert_equal(false, Pathname.new(\"a\").taint.untaint     .tainted?)\n    assert_equal(false, Pathname.new(\"a\").taint.untaint.to_s.tainted?)\n\n    str = \"a\".taint\n    path = Pathname.new(str)\n    str.untaint\n    assert_equal(true, path     .tainted?)\n    assert_equal(true, path.to_s.tainted?)\n  end\n\n  def test_freeze\n    obj = Pathname.new(\"a\"); assert_same(obj, obj.freeze)\n\n    assert_equal(false, Pathname.new(\"a\"       )            .frozen?)\n    assert_equal(false, Pathname.new(\"a\".freeze)            .frozen?)\n    assert_equal(true,  Pathname.new(\"a\"       ).freeze     .frozen?)\n    assert_equal(true,  Pathname.new(\"a\".freeze).freeze     .frozen?)\n    assert_equal(false, Pathname.new(\"a\"       )       .to_s.frozen?)\n    assert_equal(false, Pathname.new(\"a\".freeze)       .to_s.frozen?)\n    assert_equal(false, Pathname.new(\"a\"       ).freeze.to_s.frozen?)\n    assert_equal(false, Pathname.new(\"a\".freeze).freeze.to_s.frozen?)\n  end\n\n  def test_to_s\n    str = \"a\"\n    obj = Pathname.new(str)\n    assert_equal(str, obj.to_s)\n    assert_not_same(str, obj.to_s)\n    assert_not_same(obj.to_s, obj.to_s)\n  end\n\n  def test_kernel_open\n    count = 0\n    result = Kernel.open(Pathname.new(__FILE__)) {|f|\n      assert(File.identical?(__FILE__, f))\n      count += 1\n      2\n    }\n    assert_equal(1, count)\n    assert_equal(2, result)\n  end\n\n  def test_each_filename\n    result = []\n    Pathname.new(\"/usr/bin/ruby\").each_filename {|f| result << f }\n    assert_equal(%w[usr bin ruby], result)\n  end\n\n  def test_kernel_pathname\n    assert_equal(Pathname.new(\"a\"), Pathname(\"a\"))\n  end\nend\n"
  },
  {
    "path": "test/rational/test_fixnum_gcd.rb",
    "content": "require 'rational'\nrequire 'pp'\n\nrequire 'test/unit'\nrequire 'rbconfig'\n\nclass GcdTest < Test::Unit::TestCase\n\n  @@biggest_positive_fixnum = 1\n  until (x = ((@@biggest_positive_fixnum << 1) + 1)).class == Bignum\n    @@biggest_positive_fixnum = x\n  end\n  @@biggest_positive_fixnum = (@@biggest_positive_fixnum - 10)\n  until (x = (@@biggest_positive_fixnum + 1)).class == Bignum\n    @@biggest_positive_fixnum = x\n  end\n  @@smallest_positive_bignum = x\n  \n  @@biggest_negative_fixnum = -1\n  until (x = (@@biggest_negative_fixnum << 1)).class == Bignum\n    @@biggest_negative_fixnum = x\n  end\n  until (x = (@@biggest_negative_fixnum - 1)).class == Bignum\n    @@biggest_negative_fixnum = x\n  end\n  @@smallest_negative_bignum = x\n  \n  def xc x\n    [ x.class, x ].inspect\n  end\n\ncase RbConfig::CONFIG['build_cpu']\nwhen 'amd64', 'x86_64'\n  # values generated by ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]\n@@expected = \n[[\"[Fixnum, 1] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -4611686018427387903] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Bignum, 4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -4611686018427387904] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Bignum, -4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Bignum, 4611686018427387905] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 4611686018427387903]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 4611686018427387903]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Bignum, -4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, 4611686018427387903] gcd [Bignum, 4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 4611686018427387903]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 4611686018427387903]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Bignum, -4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387903] gcd [Bignum, 4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, -4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, 4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, -4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, 4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, -4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387904] gcd [Bignum, 4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, 4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Bignum, 4611686018427387904]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, -4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Fixnum, -4611686018427387904] gcd [Bignum, 4611686018427387905] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, 25] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -25] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, -4611686018427387905] gcd [Bignum, -4611686018427387905] => \",\n  \"[Bignum, 4611686018427387905]\"],\n [\"[Bignum, -4611686018427387905] gcd [Bignum, 4611686018427387905] => \",\n  \"[Bignum, 4611686018427387905]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, 25] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -25] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, 4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -4611686018427387903] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Bignum, 4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Fixnum, -4611686018427387904] => \",\n  \"[Fixnum, 1]\"],\n [\"[Bignum, 4611686018427387905] gcd [Bignum, -4611686018427387905] => \",\n  \"[Bignum, 4611686018427387905]\"],\n [\"[Bignum, 4611686018427387905] gcd [Bignum, 4611686018427387905] => \",\n  \"[Bignum, 4611686018427387905]\"]]\nwhen 'i686', 'i386'\n  # values generated by ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux]\n@@expected = \n[[\"[Fixnum, 1] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Bignum, 1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Bignum, 1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 2] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 2] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Bignum, 1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Bignum, 1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, 4] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 4] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 5] gcd [Bignum, -1073741825] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 5] gcd [Bignum, 1073741825] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, 25] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 25] gcd [Bignum, -1073741825] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, 25] gcd [Bignum, 1073741825] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -4] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Bignum, 1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Bignum, 1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -2] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -2] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Bignum, 1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Bignum, 1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -4] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -4] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -25] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -5] gcd [Bignum, -1073741825] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -5] gcd [Bignum, 1073741825] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -25] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, -25] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -25] gcd [Bignum, -1073741825] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, -25] gcd [Bignum, 1073741825] => \", \"[Fixnum, 25]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1073741823]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -1073741823] => \",\n  \"[Fixnum, 1073741823]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, 1073741823] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, 1073741823] => \",\n  \"[Fixnum, 1073741823]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -1073741823] => \",\n  \"[Fixnum, 1073741823]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741823] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, 1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, 1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, 1073741824] => \", \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, 1073741824] => \", \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, 1073741824] => \", \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, 1073741824] => \", \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741824] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -2] => \", \"[Fixnum, 2]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -4] => \", \"[Fixnum, 4]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -5] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -25] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, 1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, 1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Fixnum, -1073741824] => \",\n  \"[Bignum, 1073741824]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, -1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Fixnum, -1073741824] gcd [Bignum, 1073741825] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, 25] => \", \"[Fixnum, 25]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -25] => \", \"[Fixnum, 25]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, -1073741825] gcd [Bignum, -1073741825] => \",\n  \"[Bignum, 1073741825]\"],\n [\"[Bignum, -1073741825] gcd [Bignum, 1073741825] => \",\n  \"[Bignum, 1073741825]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, 1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, 2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, 4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, 5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, 25] => \", \"[Fixnum, 25]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -1] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -2] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -4] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -5] => \", \"[Fixnum, 5]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -25] => \", \"[Fixnum, 25]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, 1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -1073741823] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Bignum, 1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Fixnum, -1073741824] => \", \"[Fixnum, 1]\"],\n [\"[Bignum, 1073741825] gcd [Bignum, -1073741825] => \",\n  \"[Bignum, 1073741825]\"],\n [\"[Bignum, 1073741825] gcd [Bignum, 1073741825] => \", \"[Bignum, 1073741825]\"]]\nelse\n  pp RbConfig::CONFIG\n  @@expected = nil\nend\n\n  def test_results\n    values = \n      [\n       1, 2, 4, 5, 25,\n       -1, -2, -4, -5, -25,\n       @@biggest_positive_fixnum, - @@biggest_positive_fixnum,\n       @@biggest_negative_fixnum, - @@biggest_negative_fixnum,\n       @@smallest_positive_bignum, - @@smallest_positive_bignum,\n       @@smallest_negative_bignum, - @@smallest_negative_bignum,\n      ]\n\n    result = [ ]\n    values.each do | x |\n      values.each do | y |\n        result <<\n          [ \"#{xc(x)} gcd #{xc(y)} => \", \n            begin\n              xc(x.gcd(y))\n            rescue => err\n              err\n            end\n          ]\n      end\n    end\n    \n    if @@expected \n      if result != @@expected\n        @@expected.each_with_index do | x, i |\n          y = result[i]\n          assert_equal x, y\n        end\n      end\n    else\n      puts \"@@expected = \"\n      pp result\n    end\n  end\nend\n"
  },
  {
    "path": "test/rational/test_rational.rb",
    "content": "require 'test/unit'\nrequire 'rational'\n\nclass RationalSub < Rational; end\n\nclass Rational_Test < Test::Unit::TestCase\n\n  def setup\n    @complex = defined?(Complex)\n    if @complex\n      @keiju = Complex.instance_variables.include?(:@RCS_ID)\n    end\n    seps = [File::SEPARATOR, File::ALT_SEPARATOR].compact.map{|x| Regexp.escape(x)}.join(\"|\")\n    @unify = $\".grep(/(?:^|#{seps})mathn(?:\\.(?:rb|so))?/).size != 0\n  end\n\n  ## [1.8] Rational#convert is missing\n=begin\n  def test_ratsub\n    c = RationalSub.__send__(:convert, 1)\n\n    assert_kind_of(Numeric, c)\n\n    if @unify\n      assert_instance_of(Fixnum, c)\n    else\n      assert_instance_of(RationalSub, c)\n\n      c2 = c + 1\n      assert_instance_of(RationalSub, c2)\n      c2 = c - 1\n      assert_instance_of(RationalSub, c2)\n\n      c3 = c - c2\n      assert_instance_of(RationalSub, c3)\n\n      s = Marshal.dump(c)\n      c5 = Marshal.load(s)\n      assert_equal(c, c5)\n      assert_instance_of(RationalSub, c5)\n    end\n\n    c1 = Rational(1)\n    assert_equal(c1.hash, c.hash, '[ruby-dev:38850]')\n    assert_equal([true, true], [c.eql?(c1), c1.eql?(c)])\n  end\n=end\n\n  def test_eql_p\n    c = Rational(0)\n    c2 = Rational(0)\n    c3 = Rational(1)\n\n    assert_equal(true, c.eql?(c2))\n    assert_equal(false, c.eql?(c3))\n\n    if @unify\n      assert_equal(true, c.eql?(0))\n    else\n      assert_equal(false, c.eql?(0))\n    end\n  end\n\n  def test_hash\n    assert_instance_of(Fixnum, Rational(1,2).hash)\n\n    h = {}\n    h[Rational(0)] = 0\n    h[Rational(1,1)] = 1\n    h[Rational(2,1)] = 2\n    h[Rational(3,1)] = 3\n\n    assert_equal(4, h.size)\n    assert_equal(2, h[Rational(2,1)])\n\n    h[Rational(0,1)] = 9\n    assert_equal(4, h.size)\n  end\n\n  def test_freeze\n    c = Rational(1)\n    c.freeze\n    unless @unify\n      assert_equal(true, c.frozen?)\n    end\n    assert_instance_of(String, c.to_s)\n  end\n\n  def test_conv\n    c = Rational(0,1)\n    assert_equal(Rational(0,1), c)\n\n    c = Rational(2**32, 2**32)\n    assert_equal(Rational(2**32,2**32), c)\n    assert_equal([1,1], [c.numerator,c.denominator])\n\n    c = Rational(-2**32, 2**32)\n    assert_equal(Rational(-2**32,2**32), c)\n    assert_equal([-1,1], [c.numerator,c.denominator])\n\n    c = Rational(2**32, -2**32)\n    assert_equal(Rational(2**32,-2**32), c)\n    assert_equal([-1,1], [c.numerator,c.denominator])\n\n    c = Rational(-2**32, -2**32)\n    assert_equal(Rational(-2**32,-2**32), c)\n    assert_equal([1,1], [c.numerator,c.denominator])\n\n    ## [1.8] Rational() blindly expects arguments to be integers\n=begin\n    c = Rational(Rational(1,2),2)\n    assert_equal(Rational(1,4), c)\n\n    c = Rational(2,Rational(1,2))\n    assert_equal(Rational(4), c)\n\n    c = Rational(Rational(1,2),Rational(1,2))\n    assert_equal(Rational(1), c)\n=end\n\n    if @complex && !@keiju\n      c = Rational(Complex(1,2),2)\n      assert_equal(Complex(Rational(1,2),1), c)\n\n      c = Rational(2,Complex(1,2))\n      assert_equal(Complex(Rational(2,5),Rational(-4,5)), c)\n\n      c = Rational(Complex(1,2),Complex(1,2))\n      assert_equal(Rational(1), c)\n    end\n\n    assert_equal(Rational(3),Rational(3))\n    assert_equal(Rational(1),Rational(3,3))\n    ## [1.8] Float#to_r is missing\n=begin\n    assert_equal(3.3.to_r,Rational(3.3))\n=end\n    ## [1.8] Rational() blindly expects arguments to be integers\n=begin\n    assert_equal(1,Rational(3.3,3.3))\n    assert_equal(Rational(3),Rational('3'))\n    assert_equal(Rational(1),Rational('3.0','3.0'))\n    assert_equal(Rational(1),Rational('3/3','3/3'))\n    assert_raise(TypeError){Rational(nil)}\n    assert_raise(ArgumentError){Rational('')}\n    assert_raise(TypeError){Rational(Object.new)}\n=end\n    assert_raise(ArgumentError){Rational()}\n    assert_raise(ArgumentError){Rational(1,2,3)}\n\n    ## [1.8] Rational() blindly expects arguments to be integers\n=begin\n    if (0.0/0).nan?\n      assert_raise(FloatDomainError){Rational(0.0/0)}\n    end\n    if (1.0/0).infinite?\n      assert_raise(FloatDomainError){Rational(1.0/0)}\n    end\n=end\n  end\n\n  def test_attr\n    c = Rational(4)\n\n    assert_equal(4, c.numerator)\n    assert_equal(1, c.denominator)\n\n    c = Rational(4,5)\n\n    assert_equal(4, c.numerator)\n    assert_equal(5, c.denominator)\n\n    c = Rational(4)\n\n    assert_equal(4, c.numerator)\n    assert_equal(1, c.denominator)\n\n    c = Rational(4,5)\n\n    assert_equal(4, c.numerator)\n    assert_equal(5, c.denominator)\n\n    c = Rational(4)\n\n    assert_equal(4, c.numerator)\n    assert_equal(1, c.denominator)\n\n    c = Rational(4,5)\n\n    assert_equal(4, c.numerator)\n    assert_equal(5, c.denominator)\n  end\n\n  def test_attr2\n    c = Rational(1)\n\n    if @unify\n=begin\n      assert_equal(true, c.finite?)\n      assert_equal(false, c.infinite?)\n      assert_equal(false, c.nan?)\n      assert_equal(true, c.integer?)\n      assert_equal(false, c.float?)\n      assert_equal(true, c.rational?)\n=end\n      ## [1.8] Numeric#real? is missing\n=begin\n      assert_equal(true, c.real?)\n=end\n=begin\n      assert_equal(false, c.complex?)\n      assert_equal(true, c.exact?)\n      assert_equal(false, c.inexact?)\n=end\n    else\n=begin\n      assert_equal(true, c.finite?)\n      assert_equal(false, c.infinite?)\n      assert_equal(false, c.nan?)\n      assert_equal(false, c.integer?)\n      assert_equal(false, c.float?)\n      assert_equal(true, c.rational?)\n=end\n      ## [1.8] Numeric#real? is missing\n=begin\n      assert_equal(true, c.real?)\n=end\n=begin\n      assert_equal(false, c.complex?)\n      assert_equal(true, c.exact?)\n      assert_equal(false, c.inexact?)\n=end\n    end\n\n=begin\n    assert_equal(true, Rational(0).positive?)\n    assert_equal(true, Rational(1).positive?)\n    assert_equal(false, Rational(-1).positive?)\n    assert_equal(false, Rational(0).negative?)\n    assert_equal(false, Rational(1).negative?)\n    assert_equal(true, Rational(-1).negative?)\n\n    assert_equal(0, Rational(0).sign)\n    assert_equal(1, Rational(2).sign)\n    assert_equal(-1, Rational(-2).sign)\n=end\n\n    assert_equal(true, Rational(0).zero?)\n    assert_equal(true, Rational(0,1).zero?)\n    assert_equal(false, Rational(1,1).zero?)\n\n    assert_equal(nil, Rational(0).nonzero?)\n    assert_equal(nil, Rational(0,1).nonzero?)\n    assert_equal(Rational(1,1), Rational(1,1).nonzero?)\n  end\n\n  def test_uplus\n    assert_equal(Rational(1), +Rational(1))\n    assert_equal(Rational(-1), +Rational(-1))\n    assert_equal(Rational(1,1), +Rational(1,1))\n    assert_equal(Rational(-1,1), +Rational(-1,1))\n    assert_equal(Rational(-1,1), +Rational(1,-1))\n    assert_equal(Rational(1,1), +Rational(-1,-1))\n  end\n\n  def test_negate\n    assert_equal(Rational(-1), -Rational(1))\n    assert_equal(Rational(1), -Rational(-1))\n    assert_equal(Rational(-1,1), -Rational(1,1))\n    assert_equal(Rational(1,1), -Rational(-1,1))\n    assert_equal(Rational(1,1), -Rational(1,-1))\n    assert_equal(Rational(-1,1), -Rational(-1,-1))\n\n=begin\n    assert_equal(0, Rational(0).negate)\n    assert_equal(-2, Rational(2).negate)\n    assert_equal(2, Rational(-2).negate)\n=end\n  end\n\n  def test_add\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_equal(Rational(7,6), c + c2)\n\n    assert_equal(Rational(5,2), c + 2)\n    assert_equal(2.5, c + 2.0)\n  end\n\n  def test_sub\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_equal(Rational(-1,6), c - c2)\n\n    assert_equal(Rational(-3,2), c - 2)\n    assert_equal(-1.5, c - 2.0)\n  end\n\n  def test_mul\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_equal(Rational(1,3), c * c2)\n\n    assert_equal(Rational(1,1), c * 2)\n    assert_equal(1.0, c * 2.0)\n  end\n\n  def test_div\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_equal(Rational(3,4), c / c2)\n\n    assert_equal(Rational(1,4), c / 2)\n    assert_equal(0.25, c / 2.0)\n\n    assert_raise(ZeroDivisionError){Rational(1, 3) / 0}\n    assert_raise(ZeroDivisionError){Rational(1, 3) / Rational(0)}\n  end\n\n  def assert_eql(exp, act, *args)\n    unless Array === exp\n      exp = [exp]\n    end\n    unless Array === act\n      act = [act]\n    end\n    exp.zip(act).each do |e, a|\n      na = [e, a] + args\n      assert_equal(*na)\n      na = [e.class, a] + args\n      assert_instance_of(*na)\n    end\n  end\n\n  def test_idiv\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_eql(0, c.div(c2))\n    assert_eql(0, c.div(2))\n    assert_eql(0, c.div(2.0))\n\n    c = Rational(301,100)\n    c2 = Rational(7,5)\n\n    assert_equal(2, c.div(c2))\n    assert_equal(-3, c.div(-c2))\n    assert_equal(-3, (-c).div(c2))\n    assert_equal(2, (-c).div(-c2))\n\n    c = Rational(301,100)\n    c2 = Rational(2)\n\n    assert_equal(1, c.div(c2))\n    assert_equal(-2, c.div(-c2))\n    assert_equal(-2, (-c).div(c2))\n    assert_equal(1, (-c).div(-c2))\n\n    unless @unify\n      c = Rational(11)\n      c2 = Rational(3)\n\n      assert_equal(3, c.div(c2))\n      assert_equal(-4, c.div(-c2))\n      assert_equal(-4, (-c).div(c2))\n      assert_equal(3, (-c).div(-c2))\n    end\n  end\n\n  def test_modulo\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_eql(Rational(1,2), c.modulo(c2))\n    assert_eql(Rational(1,2), c.modulo(2))\n    assert_eql(0.5, c.modulo(2.0))\n\n    c = Rational(301,100)\n    c2 = Rational(7,5)\n\n    assert_equal(Rational(21,100), c.modulo(c2))\n    assert_equal(Rational(-119,100), c.modulo(-c2))\n    assert_equal(Rational(119,100), (-c).modulo(c2))\n    assert_equal(Rational(-21,100), (-c).modulo(-c2))\n\n    c = Rational(301,100)\n    c2 = Rational(2)\n\n    assert_equal(Rational(101,100), c.modulo(c2))\n    assert_equal(Rational(-99,100), c.modulo(-c2))\n    assert_equal(Rational(99,100), (-c).modulo(c2))\n    assert_equal(Rational(-101,100), (-c).modulo(-c2))\n\n    unless @unify\n      c = Rational(11)\n      c2 = Rational(3)\n\n      assert_equal(2, c.modulo(c2))\n      assert_equal(-1, c.modulo(-c2))\n      assert_equal(1, (-c).modulo(c2))\n      assert_equal(-2, (-c).modulo(-c2))\n    end\n  end\n\n  def test_divmod\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_eql([0, Rational(1,2)], c.divmod(c2))\n    assert_eql([0, Rational(1,2)], c.divmod(2))\n    assert_eql([0, 0.5], c.divmod(2.0))\n\n    c = Rational(301,100)\n    c2 = Rational(7,5)\n\n    assert_equal([2, Rational(21,100)], c.divmod(c2))\n    assert_equal([-3, Rational(-119,100)], c.divmod(-c2))\n    assert_equal([-3, Rational(119,100)], (-c).divmod(c2))\n    assert_equal([2, Rational(-21,100)], (-c).divmod(-c2))\n\n    c = Rational(301,100)\n    c2 = Rational(2)\n\n    assert_equal([1, Rational(101,100)], c.divmod(c2))\n    assert_equal([-2, Rational(-99,100)], c.divmod(-c2))\n    assert_equal([-2, Rational(99,100)], (-c).divmod(c2))\n    assert_equal([1, Rational(-101,100)], (-c).divmod(-c2))\n\n    unless @unify\n      c = Rational(11)\n      c2 = Rational(3)\n\n      assert_equal([3,2], c.divmod(c2))\n      assert_equal([-4,-1], c.divmod(-c2))\n      assert_equal([-4,1], (-c).divmod(c2))\n      assert_equal([3,-2], (-c).divmod(-c2))\n    end\n  end\n\n=begin\n  def test_quot\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_eql(0, c.quot(c2))\n    assert_eql(0, c.quot(2))\n    assert_eql(0, c.quot(2.0))\n\n    c = Rational(301,100)\n    c2 = Rational(7,5)\n\n    assert_equal(2, c.quot(c2))\n    assert_equal(-2, c.quot(-c2))\n    assert_equal(-2, (-c).quot(c2))\n    assert_equal(2, (-c).quot(-c2))\n\n    c = Rational(301,100)\n    c2 = Rational(2)\n\n    assert_equal(1, c.quot(c2))\n    assert_equal(-1, c.quot(-c2))\n    assert_equal(-1, (-c).quot(c2))\n    assert_equal(1, (-c).quot(-c2))\n\n    unless @unify\n      c = Rational(11)\n      c2 = Rational(3)\n\n      assert_equal(3, c.quot(c2))\n      assert_equal(-3, c.quot(-c2))\n      assert_equal(-3, (-c).quot(c2))\n      assert_equal(3, (-c).quot(-c2))\n    end\n  end\n=end\n\n  def test_remainder\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_eql(Rational(1,2), c.remainder(c2))\n    assert_eql(Rational(1,2), c.remainder(2))\n    assert_eql(0.5, c.remainder(2.0))\n\n    c = Rational(301,100)\n    c2 = Rational(7,5)\n\n    assert_equal(Rational(21,100), c.remainder(c2))\n    assert_equal(Rational(21,100), c.remainder(-c2))\n    assert_equal(Rational(-21,100), (-c).remainder(c2))\n    assert_equal(Rational(-21,100), (-c).remainder(-c2))\n\n    c = Rational(301,100)\n    c2 = Rational(2)\n\n    assert_equal(Rational(101,100), c.remainder(c2))\n    assert_equal(Rational(101,100), c.remainder(-c2))\n    assert_equal(Rational(-101,100), (-c).remainder(c2))\n    assert_equal(Rational(-101,100), (-c).remainder(-c2))\n\n    unless @unify\n      c = Rational(11)\n      c2 = Rational(3)\n\n      assert_equal(2, c.remainder(c2))\n      assert_equal(2, c.remainder(-c2))\n      assert_equal(-2, (-c).remainder(c2))\n      assert_equal(-2, (-c).remainder(-c2))\n    end\n  end\n\n=begin\n  def test_quotrem\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_eql([0, Rational(1,2)], c.quotrem(c2))\n    assert_eql([0, Rational(1,2)], c.quotrem(2))\n    assert_eql([0, 0.5], c.quotrem(2.0))\n\n    c = Rational(301,100)\n    c2 = Rational(7,5)\n\n    assert_equal([2, Rational(21,100)], c.quotrem(c2))\n    assert_equal([-2, Rational(21,100)], c.quotrem(-c2))\n    assert_equal([-2, Rational(-21,100)], (-c).quotrem(c2))\n    assert_equal([2, Rational(-21,100)], (-c).quotrem(-c2))\n\n    c = Rational(301,100)\n    c2 = Rational(2)\n\n    assert_equal([1, Rational(101,100)], c.quotrem(c2))\n    assert_equal([-1, Rational(101,100)], c.quotrem(-c2))\n    assert_equal([-1, Rational(-101,100)], (-c).quotrem(c2))\n    assert_equal([1, Rational(-101,100)], (-c).quotrem(-c2))\n\n    unless @unify\n      c = Rational(11)\n      c2 = Rational(3)\n\n      assert_equal([3,2], c.quotrem(c2))\n      assert_equal([-3,2], c.quotrem(-c2))\n      assert_equal([-3,-2], (-c).quotrem(c2))\n      assert_equal([3,-2], (-c).quotrem(-c2))\n    end\n  end\n=end\n\n  def test_quo\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_equal(Rational(3,4), c.quo(c2))\n\n    assert_equal(Rational(1,4), c.quo(2))\n    assert_equal(0.25, c.quo(2.0))\n  end\n\n  def test_fdiv\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    assert_equal(0.75, c.fdiv(c2))\n\n    assert_equal(0.25, c.fdiv(2))\n    assert_equal(0.25, c.fdiv(2.0))\n  end\n\n  def test_expt\n    c = Rational(1,2)\n    c2 = Rational(2,3)\n\n    r = c ** c2\n    assert_in_delta(0.6299, r, 0.001)\n\n    assert_equal(Rational(1,4), c ** 2)\n    assert_equal(Rational(4), c ** -2)\n    assert_equal(Rational(1,4), (-c) ** 2)\n    assert_equal(Rational(4), (-c) ** -2)\n\n    assert_equal(0.25, c ** 2.0)\n    assert_equal(4.0, c ** -2.0)\n\n    assert_equal(Rational(1,4), c ** Rational(2))\n    assert_equal(Rational(4), c ** Rational(-2))\n\n    assert_equal(Rational(1), 0 ** Rational(0))\n    assert_equal(Rational(1), Rational(0) ** 0)\n    assert_equal(Rational(1), Rational(0) ** Rational(0))\n\n    # p ** p\n    x = 2 ** Rational(2)\n    ## [1.8] Fixnum#coerce tries to convert the other operand to Float.\n=begin\n    assert_equal(Rational(4), x)\n    unless @unify\n      assert_instance_of(Rational, x)\n    end\n    assert_equal(4, x.numerator)\n    assert_equal(1, x.denominator)\n=end\n    assert_equal(4.0, x)\n    unless @unify\n      assert_instance_of(Float, x)\n    end\n\n    x = Rational(2) ** 2\n    assert_equal(Rational(4), x)\n    unless @unify\n      assert_instance_of(Rational, x)\n    end\n    assert_equal(4, x.numerator)\n    assert_equal(1, x.denominator)\n\n    x = Rational(2) ** Rational(2)\n    ## [1.8] Rational#** calculates Rational**Rational in Float.\n=begin\n    assert_equal(Rational(4), x)\n    unless @unify\n      assert_instance_of(Rational, x)\n    end\n    assert_equal(4, x.numerator)\n    assert_equal(1, x.denominator)\n=end\n    assert_equal(4.0, x)\n    unless @unify\n      assert_instance_of(Float, x)\n    end\n\n    # -p ** p\n    x = (-2) ** Rational(2)\n    ## [1.8] Fixnum#coerce tries to convert the other operand to Float.\n=begin\n    assert_equal(Rational(4), x)\n    unless @unify\n      assert_instance_of(Rational, x)\n    end\n    assert_equal(4, x.numerator)\n    assert_equal(1, x.denominator)\n=end\n    assert_equal(4.0, x)\n    unless @unify\n      assert_instance_of(Float, x)\n    end\n\n    x = Rational(-2) ** 2\n    assert_equal(Rational(4), x)\n    unless @unify\n      assert_instance_of(Rational, x)\n    end\n    assert_equal(4, x.numerator)\n    assert_equal(1, x.denominator)\n\n    x = Rational(-2) ** Rational(2)\n    ## [1.8] Rational#** calculates Rational**Rational in Float.\n=begin\n    assert_equal(Rational(4), x)\n    unless @unify\n      assert_instance_of(Rational, x)\n    end\n    assert_equal(4, x.numerator)\n    assert_equal(1, x.denominator)\n=end\n    assert_equal(4.0, x)\n    unless @unify\n      assert_instance_of(Float, x)\n    end\n\n    # p ** -p\n    x = 2 ** Rational(-2)\n    ## [1.8] Fixnum#coerce tries to convert the other operand to Float.\n=begin\n    assert_equal(Rational(1,4), x)\n    assert_instance_of(Rational, x)\n    assert_equal(1, x.numerator)\n    assert_equal(4, x.denominator)\n=end\n    assert_equal(0.25, x)\n    assert_instance_of(Float, x)\n\n    x = Rational(2) ** -2\n    assert_equal(Rational(1,4), x)\n    assert_instance_of(Rational, x)\n    assert_equal(1, x.numerator)\n    assert_equal(4, x.denominator)\n\n    x = Rational(2) ** Rational(-2)\n    ## [1.8] Rational#** calculates Rational**Rational in Float.\n=begin\n    assert_equal(Rational(1,4), x)\n    assert_instance_of(Rational, x)\n    assert_equal(1, x.numerator)\n    assert_equal(4, x.denominator)\n=end\n    assert_equal(0.25, x)\n    assert_instance_of(Float, x)\n\n    # -p ** -p\n    x = (-2) ** Rational(-2)\n    ## [1.8] Fixnum#coerce tries to convert the other operand to Float.\n=begin\n    assert_equal(Rational(1,4), x)\n    assert_instance_of(Rational, x)\n    assert_equal(1, x.numerator)\n    assert_equal(4, x.denominator)\n=end\n    assert_equal(0.25, x)\n    assert_instance_of(Float, x)\n\n    x = Rational(-2) ** -2\n    assert_equal(Rational(1,4), x)\n    assert_instance_of(Rational, x)\n    assert_equal(1, x.numerator)\n    assert_equal(4, x.denominator)\n\n    x = Rational(-2) ** Rational(-2)\n    ## [1.8] Rational#** calculates Rational**Rational in Float.\n=begin\n    assert_equal(Rational(1,4), x)\n    assert_instance_of(Rational, x)\n    assert_equal(1, x.numerator)\n    assert_equal(4, x.denominator)\n=end\n    assert_equal(0.25, x)\n    assert_instance_of(Float, x)\n\n    unless @unify # maybe bug mathn\n      ## [1.8] returns Infinity\n=begin\n      assert_raise(ZeroDivisionError){0 ** -1}\n=end\n    end\n  end\n\n  def test_cmp\n    assert_equal(-1, Rational(-1) <=> Rational(0))\n    assert_equal(0, Rational(0) <=> Rational(0))\n    assert_equal(+1, Rational(+1) <=> Rational(0))\n\n    assert_equal(-1, Rational(-1) <=> 0)\n    assert_equal(0, Rational(0) <=> 0)\n    assert_equal(+1, Rational(+1) <=> 0)\n\n    assert_equal(-1, Rational(-1) <=> 0.0)\n    assert_equal(0, Rational(0) <=> 0.0)\n    assert_equal(+1, Rational(+1) <=> 0.0)\n\n    assert_equal(-1, Rational(1,2) <=> Rational(2,3))\n    assert_equal(0, Rational(2,3) <=> Rational(2,3))\n    assert_equal(+1, Rational(2,3) <=> Rational(1,2))\n\n    f = 2**30-1\n    b = 2**30\n\n    assert_equal(0, Rational(f) <=> Rational(f))\n    assert_equal(-1, Rational(f) <=> Rational(b))\n    assert_equal(+1, Rational(b) <=> Rational(f))\n    assert_equal(0, Rational(b) <=> Rational(b))\n\n    assert_equal(-1, Rational(f-1) <=> Rational(f))\n    assert_equal(+1, Rational(f) <=> Rational(f-1))\n    assert_equal(-1, Rational(b-1) <=> Rational(b))\n    assert_equal(+1, Rational(b) <=> Rational(b-1))\n\n    assert_equal(false, Rational(0) < Rational(0))\n    assert_equal(true, Rational(0) <= Rational(0))\n    assert_equal(true, Rational(0) >= Rational(0))\n    assert_equal(false, Rational(0) > Rational(0))\n\n    assert_equal(nil, Rational(0) <=> nil)\n    assert_equal(nil, Rational(0) <=> 'foo')\n  end\n\n  def test_eqeq\n    assert(Rational(1,1) == Rational(1))\n    assert(Rational(-1,1) == Rational(-1))\n\n    assert_equal(false, Rational(2,1) == Rational(1))\n    assert_equal(true, Rational(2,1) != Rational(1))\n    assert_equal(false, Rational(1) == nil)\n    assert_equal(false, Rational(1) == '')\n  end\n\n  def test_coerce\n    assert_equal([Rational(2),Rational(1)], Rational(1).coerce(2))\n    ## [1.8] Rational coerces itself to Float\n=begin\n    assert_equal([Rational(2.2),Rational(1)], Rational(1).coerce(2.2))\n=end\n    assert_equal([2.2,1.0], Rational(1).coerce(2.2))\n    assert_equal([Rational(2),Rational(1)], Rational(1).coerce(Rational(2)))\n  end\n\n  def test_unify\n    if @unify\n      assert_instance_of(Fixnum, Rational(1,2) + Rational(1,2))\n      assert_instance_of(Fixnum, Rational(1,2) - Rational(1,2))\n      assert_instance_of(Fixnum, Rational(1,2) * 2)\n      assert_instance_of(Fixnum, Rational(1,2) / Rational(1,2))\n      assert_instance_of(Fixnum, Rational(1,2).div(Rational(1,2)))\n      assert_instance_of(Fixnum, Rational(1,2).quo(Rational(1,2)))\n      assert_instance_of(Fixnum, Rational(1,2) ** -2)\n    end\n  end\n\n  def test_math\n    assert_equal(Rational(1,2), Rational(1,2).abs)\n    assert_equal(Rational(1,2), Rational(-1,2).abs)\n    if @complex && !@keiju\n      assert_equal(Rational(1,2), Rational(1,2).magnitude)\n      assert_equal(Rational(1,2), Rational(-1,2).magnitude)\n    end\n\n    assert_equal(1, Rational(1,2).numerator)\n    assert_equal(2, Rational(1,2).denominator)\n  end\n\n  def test_trunc\n    [[Rational(13, 5),  [ 2,  3,  2,  3]], #  2.6\n     [Rational(5, 2),   [ 2,  3,  2,  3]], #  2.5\n     [Rational(12, 5),  [ 2,  3,  2,  2]], #  2.4\n     [Rational(-12,5),  [-3, -2, -2, -2]], # -2.4\n     [Rational(-5, 2),  [-3, -2, -2, -3]], # -2.5\n     [Rational(-13, 5), [-3, -2, -2, -3]], # -2.6\n    ].each do |i, a|\n      assert_equal(a[0], i.floor)\n      assert_equal(a[1], i.ceil)\n      assert_equal(a[2], i.truncate)\n      assert_equal(a[3], i.round)\n    end\n  end\n\n  def test_to_s\n    c = Rational(1,2)\n\n    assert_instance_of(String, c.to_s)\n    assert_equal('1/2', c.to_s)\n\n    if @unify\n      assert_equal('0', Rational(0,2).to_s)\n      assert_equal('0', Rational(0,-2).to_s)\n    else\n      ## [1.8] Float#to_r is missing\n=begin\n      assert_equal('0/1', Rational(0,2).to_s)\n      assert_equal('0/1', Rational(0,-2).to_s)\n=end\n      assert_equal('0', Rational(0,2).to_s)\n      assert_equal('0', Rational(0,-2).to_s)\n    end\n    assert_equal('1/2', Rational(1,2).to_s)\n    assert_equal('-1/2', Rational(-1,2).to_s)\n    assert_equal('1/2', Rational(-1,-2).to_s)\n    assert_equal('-1/2', Rational(1,-2).to_s)\n    assert_equal('1/2', Rational(-1,-2).to_s)\n  end\n\n  def test_inspect\n    c = Rational(1,2)\n\n    assert_instance_of(String, c.inspect)\n    ## [1.8] Format changed in 1.9\n=begin\n    assert_equal('(1/2)', c.inspect)\n=end\n    assert_equal('Rational(1, 2)', c.inspect)\n  end\n\n  def test_marshal\n    c = Rational(1,2)\n    c.instance_eval{@ivar = 9}\n\n    s = Marshal.dump(c)\n    c2 = Marshal.load(s)\n    assert_equal(c, c2)\n    assert_equal(9, c2.instance_variable_get(:@ivar))\n    assert_instance_of(Rational, c2)\n\n    ## [1.8] No support (yet) for the marshal format of Rational in 1.9\n=begin\n    assert_raise(ZeroDivisionError){\n      Marshal.load(\"\\x04\\bU:\\rRational[\\ai\\x06i\\x05\")\n    }\n=end\n  end\n\n  ## [1.8] String#to_r is missing\n=begin\n  def test_parse\n    assert_equal(Rational(5), '5'.to_r)\n    assert_equal(Rational(-5), '-5'.to_r)\n    assert_equal(Rational(5,3), '5/3'.to_r)\n    assert_equal(Rational(-5,3), '-5/3'.to_r)\n#    assert_equal(Rational(5,-3), '5/-3'.to_r)\n#    assert_equal(Rational(-5,-3), '-5/-3'.to_r)\n\n    assert_equal(Rational(5), '5.0'.to_r)\n    assert_equal(Rational(-5), '-5.0'.to_r)\n    assert_equal(Rational(5,3), '5.0/3'.to_r)\n    assert_equal(Rational(-5,3), '-5.0/3'.to_r)\n#    assert_equal(Rational(5,-3), '5.0/-3'.to_r)\n#    assert_equal(Rational(-5,-3), '-5.0/-3'.to_r)\n\n    assert_equal(Rational(5), '5e0'.to_r)\n    assert_equal(Rational(-5), '-5e0'.to_r)\n    assert_equal(Rational(5,3), '5e0/3'.to_r)\n    assert_equal(Rational(-5,3), '-5e0/3'.to_r)\n#    assert_equal(Rational(5,-3), '5e0/-3'.to_r)\n#    assert_equal(Rational(-5,-3), '-5e0/-3'.to_r)\n\n    assert_equal(Rational(33,100), '.33'.to_r)\n    assert_equal(Rational(33,100), '0.33'.to_r)\n    assert_equal(Rational(-33,100), '-.33'.to_r)\n    assert_equal(Rational(-33,100), '-0.33'.to_r)\n    assert_equal(Rational(-33,100), '-0.3_3'.to_r)\n\n    assert_equal(Rational(1,2), '5e-1'.to_r)\n    assert_equal(Rational(50), '5e+1'.to_r)\n    assert_equal(Rational(1,2), '5.0e-1'.to_r)\n    assert_equal(Rational(50), '5.0e+1'.to_r)\n    assert_equal(Rational(50), '5e1'.to_r)\n    assert_equal(Rational(50), '5E1'.to_r)\n    assert_equal(Rational(500), '5e2'.to_r)\n    assert_equal(Rational(5000), '5e3'.to_r)\n    assert_equal(Rational(500000000000), '5e1_1'.to_r)\n\n    assert_equal(Rational(5), Rational('5'))\n    assert_equal(Rational(-5), Rational('-5'))\n    assert_equal(Rational(5,3), Rational('5/3'))\n    assert_equal(Rational(-5,3), Rational('-5/3'))\n#    assert_equal(Rational(5,-3), Rational('5/-3'))\n#    assert_equal(Rational(-5,-3), Rational('-5/-3'))\n\n    assert_equal(Rational(5), Rational('5.0'))\n    assert_equal(Rational(-5), Rational('-5.0'))\n    assert_equal(Rational(5,3), Rational('5.0/3'))\n    assert_equal(Rational(-5,3), Rational('-5.0/3'))\n#    assert_equal(Rational(5,-3), Rational('5.0/-3'))\n#    assert_equal(Rational(-5,-3), Rational('-5.0/-3'))\n\n    assert_equal(Rational(5), Rational('5e0'))\n    assert_equal(Rational(-5), Rational('-5e0'))\n    assert_equal(Rational(5,3), Rational('5e0/3'))\n    assert_equal(Rational(-5,3), Rational('-5e0/3'))\n#    assert_equal(Rational(5,-3), Rational('5e0/-3'))\n#    assert_equal(Rational(-5,-3), Rational('-5e0/-3'))\n\n    assert_equal(Rational(33,100), Rational('.33'))\n    assert_equal(Rational(33,100), Rational('0.33'))\n    assert_equal(Rational(-33,100), Rational('-.33'))\n    assert_equal(Rational(-33,100), Rational('-0.33'))\n    assert_equal(Rational(-33,100), Rational('-0.3_3'))\n\n    assert_equal(Rational(1,2), Rational('5e-1'))\n    assert_equal(Rational(50), Rational('5e+1'))\n    assert_equal(Rational(1,2), Rational('5.0e-1'))\n    assert_equal(Rational(50), Rational('5.0e+1'))\n    assert_equal(Rational(50), Rational('5e1'))\n    assert_equal(Rational(50), Rational('5E1'))\n    assert_equal(Rational(500), Rational('5e2'))\n    assert_equal(Rational(5000), Rational('5e3'))\n    assert_equal(Rational(500000000000), Rational('5e1_1'))\n\n    assert_equal(Rational(0), ''.to_r)\n    assert_equal(Rational(0), ' '.to_r)\n    assert_equal(Rational(5), \"\\f\\n\\r\\t\\v5\\0\".to_r)\n    assert_equal(Rational(0), '_'.to_r)\n    assert_equal(Rational(0), '_5'.to_r)\n    assert_equal(Rational(5), '5_'.to_r)\n    assert_equal(Rational(5), '5x'.to_r)\n    assert_equal(Rational(5), '5/_3'.to_r)\n    assert_equal(Rational(5,3), '5/3_'.to_r)\n    assert_equal(Rational(5,3), '5/3.3'.to_r)\n    assert_equal(Rational(5,3), '5/3x'.to_r)\n    assert_raise(ArgumentError){ Rational('')}\n    assert_raise(ArgumentError){ Rational('_')}\n    assert_raise(ArgumentError){ Rational(\"\\f\\n\\r\\t\\v5\\0\")}\n    assert_raise(ArgumentError){ Rational('_5')}\n    assert_raise(ArgumentError){ Rational('5_')}\n    assert_raise(ArgumentError){ Rational('5x')}\n    assert_raise(ArgumentError){ Rational('5/_3')}\n    assert_raise(ArgumentError){ Rational('5/3_')}\n    assert_raise(ArgumentError){ Rational('5/3.3')}\n    assert_raise(ArgumentError){ Rational('5/3x')}\n  end\n=end\n\n=begin\n  def test_reciprocal\n    assert_equal(Rational(1,9), Rational(9,1).reciprocal)\n    assert_equal(Rational(9,1), Rational(1,9).reciprocal)\n    assert_equal(Rational(-1,9), Rational(-9,1).reciprocal)\n    assert_equal(Rational(-9,1), Rational(-1,9).reciprocal)\n    assert_equal(Rational(1,9), Rational(9,1).inverse)\n    assert_equal(Rational(9,1), Rational(1,9).inverse)\n    assert_equal(Rational(-1,9), Rational(-9,1).inverse)\n    assert_equal(Rational(-9,1), Rational(-1,9).inverse)\n  end\n=end\n\n  def test_to_i\n    assert_equal(1, Rational(3,2).to_i)\n    assert_equal(1, Integer(Rational(3,2)))\n  end\n\n  def test_to_f\n    assert_equal(1.5, Rational(3,2).to_f)\n    assert_equal(1.5, Float(Rational(3,2)))\n  end\n\n  def test_to_c\n    if @complex && !@keiju\n      if @unify\n\tassert_equal(Rational(3,2), Rational(3,2).to_c)\n\tassert_equal(Rational(3,2), Complex(Rational(3,2)))\n      else\n\tassert_equal(Complex(Rational(3,2)), Rational(3,2).to_c)\n\tassert_equal(Complex(Rational(3,2)), Complex(Rational(3,2)))\n      end\n    end\n  end\n\n  def test_to_r\n    ## [1.8] Float#to_r is missing\n=begin\n    c = nil.to_r\n    assert_equal([0,1], [c.numerator, c.denominator])\n=end\n\n    c = 0.to_r\n    assert_equal([0,1], [c.numerator, c.denominator])\n\n    c = 1.to_r\n    assert_equal([1,1], [c.numerator, c.denominator])\n\n    ## [1.8] Float#to_r is missing\n=begin\n    c = 1.1.to_r\n    assert_equal([2476979795053773, 2251799813685248],\n\t\t [c.numerator, c.denominator])\n=end\n\n    c = Rational(1,2).to_r\n    assert_equal([1,2], [c.numerator, c.denominator])\n\n    if @complex\n      if @keiju\n\tassert_raise(NoMethodError){Complex(1,2).to_r}\n      else\n\tassert_raise(RangeError){Complex(1,2).to_r}\n      end\n    end\n\n    ## [1.8] Float#to_r is missing\n=begin\n    if (0.0/0).nan?\n      assert_raise(FloatDomainError){(0.0/0).to_r}\n    end\n    if (1.0/0).infinite?\n      assert_raise(FloatDomainError){(1.0/0).to_r}\n    end\n=end\n  end\n\n  ## [1.8] #rationalize is missing\n=begin\n  def test_rationalize\n    c = nil.rationalize\n    assert_equal([0,1], [c.numerator, c.denominator])\n\n    c = 0.rationalize\n    assert_equal([0,1], [c.numerator, c.denominator])\n\n    c = 1.rationalize\n    assert_equal([1,1], [c.numerator, c.denominator])\n\n    c = 1.1.rationalize\n    assert_equal([11, 10], [c.numerator, c.denominator])\n\n    c = Rational(1,2).rationalize\n    assert_equal([1,2], [c.numerator, c.denominator])\n\n    assert_equal(nil.rationalize(Rational(1,10)), Rational(0))\n    assert_equal(0.rationalize(Rational(1,10)), Rational(0))\n    assert_equal(10.rationalize(Rational(1,10)), Rational(10))\n\n    r = 0.3333\n    assert_equal(r.rationalize, Rational(3333, 10000))\n    assert_equal(r.rationalize(Rational(1,10)), Rational(1,3))\n    assert_equal(r.rationalize(Rational(-1,10)), Rational(1,3))\n\n    r = Rational(5404319552844595,18014398509481984)\n    assert_equal(r.rationalize, r)\n    assert_equal(r.rationalize(Rational(1,10)), Rational(1,3))\n    assert_equal(r.rationalize(Rational(-1,10)), Rational(1,3))\n\n    r = -0.3333\n    assert_equal(r.rationalize, Rational(-3333, 10000))\n    assert_equal(r.rationalize(Rational(1,10)), Rational(-1,3))\n    assert_equal(r.rationalize(Rational(-1,10)), Rational(-1,3))\n\n    r = Rational(-5404319552844595,18014398509481984)\n    assert_equal(r.rationalize, r)\n    assert_equal(r.rationalize(Rational(1,10)), Rational(-1,3))\n    assert_equal(r.rationalize(Rational(-1,10)), Rational(-1,3))\n\n    if @complex\n      if @keiju\n      else\n\tassert_raise(RangeError){Complex(1,2).rationalize}\n      end\n    end\n\n    if (0.0/0).nan?\n      assert_raise(FloatDomainError){(0.0/0).rationalize}\n    end\n    if (1.0/0).infinite?\n      assert_raise(FloatDomainError){(1.0/0).rationalize}\n    end\n  end\n=end\n\n  def test_gcdlcm\n    assert_equal(7, 91.gcd(-49))\n    assert_equal(5, 5.gcd(0))\n    assert_equal(5, 0.gcd(5))\n    assert_equal(70, 14.lcm(35))\n    assert_equal(0, 5.lcm(0))\n    assert_equal(0, 0.lcm(5))\n    assert_equal([5,0], 0.gcdlcm(5))\n    assert_equal([5,0], 5.gcdlcm(0))\n\n    assert_equal(1, 1073741827.gcd(1073741789))\n    assert_equal(1152921470247108503, 1073741827.lcm(1073741789))\n\n    assert_equal(1, 1073741789.gcd(1073741827))\n    assert_equal(1152921470247108503, 1073741789.lcm(1073741827))\n  end\n\n  def test_supp\n    ## [1.8] Numeric#real? is missing\n=begin\n    assert_equal(true, 1.real?)\n    assert_equal(true, 1.1.real?)\n=end\n\n    assert_equal(1, 1.numerator)\n    assert_equal(9, 9.numerator)\n    assert_equal(1, 1.denominator)\n    assert_equal(1, 9.denominator)\n\n    ## [1.8] Float#to_r is missing\n=begin\n    assert_equal(1.0, 1.0.numerator)\n    assert_equal(9.0, 9.0.numerator)\n    assert_equal(1.0, 1.0.denominator)\n    assert_equal(1.0, 9.0.denominator)\n=end\n\n=begin\n    assert_equal(Rational(1,9), 9.reciprocal)\n    assert_in_delta(0.1111, 9.0.reciprocal, 0.001)\n    assert_equal(Rational(1,9), 9.inverse)\n    assert_in_delta(0.1111, 9.0.inverse, 0.001)\n=end\n\n    assert_equal(Rational(1,2), 1.quo(2))\n    assert_equal(Rational(5000000000), 10000000000.quo(2))\n    assert_equal(0.5, 1.0.quo(2))\n    assert_equal(Rational(1,4), Rational(1,2).quo(2))\n\n    assert_equal(0.5, 1.fdiv(2))\n    assert_equal(5000000000.0, 10000000000.fdiv(2))\n    assert_equal(0.5, 1.0.fdiv(2))\n    assert_equal(0.25, Rational(1,2).fdiv(2))\n  end\n\n  ## [1.8] Not for me\n=begin\n  def test_ruby19\n    assert_raise(NoMethodError){ Rational.new(1) }\n    assert_raise(NoMethodError){ Rational.new!(1) }\n  end\n=end\n\n  def test_fixed_bug\n    if @unify\n      assert_instance_of(Fixnum, Rational(1,2) ** 0) # mathn's bug\n    end\n\n    n = Float::MAX.to_i * 2\n    ## [1.8] Bug still exists (or is left as \"a feature\")\n=begin\n    assert_equal(1.0, Rational(n + 2, n + 1).to_f, '[ruby-dev:33852]')\n=end\n  end\n\n  def test_known_bug\n  end\n\nend\n"
  },
  {
    "path": "test/rational/test_rational2.rb",
    "content": "require 'test/unit'\nrequire 'rational'\n\nclass Rational_Test2 < Test::Unit::TestCase\n\n  def test_kumi\n    assert_equal(Rational(1, 1), +Rational(1, 1))\n    assert_equal(Rational(-1, 1), -Rational(1, 1))\n    assert_equal(Rational(2, 1),\n                 Rational(1, 1) + Rational(1, 1))\n    assert_equal(Rational(0, 1),\n                 Rational(1, 1) - Rational(1, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(1, 1) * Rational(1, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(1, 1) / Rational(1, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(1, 1) + Rational(2, 1))\n    assert_equal(Rational(-1, 1),\n                 Rational(1, 1) - Rational(2, 1))\n    assert_equal(Rational(2, 1),\n                 Rational(1, 1) * Rational(2, 1))\n    assert_equal(Rational(1, 2),\n                 Rational(1, 1) / Rational(2, 1))\n    assert_equal(Rational(4, 1),\n                 Rational(1, 1) + Rational(3, 1))\n    assert_equal(Rational(-2, 1),\n                 Rational(1, 1) - Rational(3, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(1, 1) * Rational(3, 1))\n    assert_equal(Rational(1, 3),\n                 Rational(1, 1) / Rational(3, 1))\n    assert_equal(Rational(1073741790, 1),\n                 Rational(1, 1) + Rational(1073741789, 1))\n    assert_equal(Rational(-1073741788, 1),\n                 Rational(1, 1) - Rational(1073741789, 1))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1, 1) * Rational(1073741789, 1))\n    assert_equal(Rational(1, 1073741789),\n                 Rational(1, 1) / Rational(1073741789, 1))\n    assert_equal(Rational(1073741828, 1),\n                 Rational(1, 1) + Rational(1073741827, 1))\n    assert_equal(Rational(-1073741826, 1),\n                 Rational(1, 1) - Rational(1073741827, 1))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1, 1) * Rational(1073741827, 1))\n    assert_equal(Rational(1, 1073741827),\n                 Rational(1, 1) / Rational(1073741827, 1))\n    assert_equal(Rational(5, 3),\n                 Rational(1, 1) + Rational(2, 3))\n    assert_equal(Rational(1, 3),\n                 Rational(1, 1) - Rational(2, 3))\n    assert_equal(Rational(2, 3),\n                 Rational(1, 1) * Rational(2, 3))\n    assert_equal(Rational(3, 2),\n                 Rational(1, 1) / Rational(2, 3))\n    assert_equal(Rational(5, 2),\n                 Rational(1, 1) + Rational(3, 2))\n    assert_equal(Rational(-1, 2),\n                 Rational(1, 1) - Rational(3, 2))\n    assert_equal(Rational(3, 2),\n                 Rational(1, 1) * Rational(3, 2))\n    assert_equal(Rational(2, 3),\n                 Rational(1, 1) / Rational(3, 2))\n    assert_equal(Rational(1073741792, 1073741789),\n                 Rational(1, 1) + Rational(3, 1073741789))\n    assert_equal(Rational(1073741786, 1073741789),\n                 Rational(1, 1) - Rational(3, 1073741789))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(1, 1) * Rational(3, 1073741789))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1, 1) / Rational(3, 1073741789))\n    assert_equal(Rational(1073741792, 3),\n                 Rational(1, 1) + Rational(1073741789, 3))\n    assert_equal(Rational(-1073741786, 3),\n                 Rational(1, 1) - Rational(1073741789, 3))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1, 1) * Rational(1073741789, 3))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(1, 1) / Rational(1073741789, 3))\n    assert_equal(Rational(1073741830, 1073741827),\n                 Rational(1, 1) + Rational(3, 1073741827))\n    assert_equal(Rational(1073741824, 1073741827),\n                 Rational(1, 1) - Rational(3, 1073741827))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(1, 1) * Rational(3, 1073741827))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1, 1) / Rational(3, 1073741827))\n    assert_equal(Rational(1073741830, 3),\n                 Rational(1, 1) + Rational(1073741827, 3))\n    assert_equal(Rational(-1073741824, 3),\n                 Rational(1, 1) - Rational(1073741827, 3))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1, 1) * Rational(1073741827, 3))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(1, 1) / Rational(1073741827, 3))\n    assert_equal(Rational(2147483616, 1073741827),\n                 Rational(1, 1) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(38, 1073741827),\n                 Rational(1, 1) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1, 1) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1, 1) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483616, 1073741789),\n                 Rational(1, 1) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(-38, 1073741789),\n                 Rational(1, 1) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1, 1) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1, 1) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(2, 1), +Rational(2, 1))\n    assert_equal(Rational(-2, 1), -Rational(2, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(2, 1) + Rational(1, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(2, 1) - Rational(1, 1))\n    assert_equal(Rational(2, 1),\n                 Rational(2, 1) * Rational(1, 1))\n    assert_equal(Rational(2, 1),\n                 Rational(2, 1) / Rational(1, 1))\n    assert_equal(Rational(4, 1),\n                 Rational(2, 1) + Rational(2, 1))\n    assert_equal(Rational(0, 1),\n                 Rational(2, 1) - Rational(2, 1))\n    assert_equal(Rational(4, 1),\n                 Rational(2, 1) * Rational(2, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(2, 1) / Rational(2, 1))\n    assert_equal(Rational(5, 1),\n                 Rational(2, 1) + Rational(3, 1))\n    assert_equal(Rational(-1, 1),\n                 Rational(2, 1) - Rational(3, 1))\n    assert_equal(Rational(6, 1),\n                 Rational(2, 1) * Rational(3, 1))\n    assert_equal(Rational(2, 3),\n                 Rational(2, 1) / Rational(3, 1))\n    assert_equal(Rational(1073741791, 1),\n                 Rational(2, 1) + Rational(1073741789, 1))\n    assert_equal(Rational(-1073741787, 1),\n                 Rational(2, 1) - Rational(1073741789, 1))\n    assert_equal(Rational(2147483578, 1),\n                 Rational(2, 1) * Rational(1073741789, 1))\n    assert_equal(Rational(2, 1073741789),\n                 Rational(2, 1) / Rational(1073741789, 1))\n    assert_equal(Rational(1073741829, 1),\n                 Rational(2, 1) + Rational(1073741827, 1))\n    assert_equal(Rational(-1073741825, 1),\n                 Rational(2, 1) - Rational(1073741827, 1))\n    assert_equal(Rational(2147483654, 1),\n                 Rational(2, 1) * Rational(1073741827, 1))\n    assert_equal(Rational(2, 1073741827),\n                 Rational(2, 1) / Rational(1073741827, 1))\n    assert_equal(Rational(8, 3),\n                 Rational(2, 1) + Rational(2, 3))\n    assert_equal(Rational(4, 3),\n                 Rational(2, 1) - Rational(2, 3))\n    assert_equal(Rational(4, 3),\n                 Rational(2, 1) * Rational(2, 3))\n    assert_equal(Rational(3, 1),\n                 Rational(2, 1) / Rational(2, 3))\n    assert_equal(Rational(7, 2),\n                 Rational(2, 1) + Rational(3, 2))\n    assert_equal(Rational(1, 2),\n                 Rational(2, 1) - Rational(3, 2))\n    assert_equal(Rational(3, 1),\n                 Rational(2, 1) * Rational(3, 2))\n    assert_equal(Rational(4, 3),\n                 Rational(2, 1) / Rational(3, 2))\n    assert_equal(Rational(2147483581, 1073741789),\n                 Rational(2, 1) + Rational(3, 1073741789))\n    assert_equal(Rational(2147483575, 1073741789),\n                 Rational(2, 1) - Rational(3, 1073741789))\n    assert_equal(Rational(6, 1073741789),\n                 Rational(2, 1) * Rational(3, 1073741789))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(2, 1) / Rational(3, 1073741789))\n    assert_equal(Rational(1073741795, 3),\n                 Rational(2, 1) + Rational(1073741789, 3))\n    assert_equal(Rational(-1073741783, 3),\n                 Rational(2, 1) - Rational(1073741789, 3))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(2, 1) * Rational(1073741789, 3))\n    assert_equal(Rational(6, 1073741789),\n                 Rational(2, 1) / Rational(1073741789, 3))\n    assert_equal(Rational(2147483657, 1073741827),\n                 Rational(2, 1) + Rational(3, 1073741827))\n    assert_equal(Rational(2147483651, 1073741827),\n                 Rational(2, 1) - Rational(3, 1073741827))\n    assert_equal(Rational(6, 1073741827),\n                 Rational(2, 1) * Rational(3, 1073741827))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(2, 1) / Rational(3, 1073741827))\n    assert_equal(Rational(1073741833, 3),\n                 Rational(2, 1) + Rational(1073741827, 3))\n    assert_equal(Rational(-1073741821, 3),\n                 Rational(2, 1) - Rational(1073741827, 3))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(2, 1) * Rational(1073741827, 3))\n    assert_equal(Rational(6, 1073741827),\n                 Rational(2, 1) / Rational(1073741827, 3))\n    assert_equal(Rational(3221225443, 1073741827),\n                 Rational(2, 1) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741865, 1073741827),\n                 Rational(2, 1) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483578, 1073741827),\n                 Rational(2, 1) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483654, 1073741789),\n                 Rational(2, 1) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225405, 1073741789),\n                 Rational(2, 1) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741751, 1073741789),\n                 Rational(2, 1) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(2147483654, 1073741789),\n                 Rational(2, 1) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(2147483578, 1073741827),\n                 Rational(2, 1) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(3, 1), +Rational(3, 1))\n    assert_equal(Rational(-3, 1), -Rational(3, 1))\n    assert_equal(Rational(4, 1),\n                 Rational(3, 1) + Rational(1, 1))\n    assert_equal(Rational(2, 1),\n                 Rational(3, 1) - Rational(1, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(3, 1) * Rational(1, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(3, 1) / Rational(1, 1))\n    assert_equal(Rational(5, 1),\n                 Rational(3, 1) + Rational(2, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 1) - Rational(2, 1))\n    assert_equal(Rational(6, 1),\n                 Rational(3, 1) * Rational(2, 1))\n    assert_equal(Rational(3, 2),\n                 Rational(3, 1) / Rational(2, 1))\n    assert_equal(Rational(6, 1),\n                 Rational(3, 1) + Rational(3, 1))\n    assert_equal(Rational(0, 1),\n                 Rational(3, 1) - Rational(3, 1))\n    assert_equal(Rational(9, 1),\n                 Rational(3, 1) * Rational(3, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 1) / Rational(3, 1))\n    assert_equal(Rational(1073741792, 1),\n                 Rational(3, 1) + Rational(1073741789, 1))\n    assert_equal(Rational(-1073741786, 1),\n                 Rational(3, 1) - Rational(1073741789, 1))\n    assert_equal(Rational(3221225367, 1),\n                 Rational(3, 1) * Rational(1073741789, 1))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(3, 1) / Rational(1073741789, 1))\n    assert_equal(Rational(1073741830, 1),\n                 Rational(3, 1) + Rational(1073741827, 1))\n    assert_equal(Rational(-1073741824, 1),\n                 Rational(3, 1) - Rational(1073741827, 1))\n    assert_equal(Rational(3221225481, 1),\n                 Rational(3, 1) * Rational(1073741827, 1))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(3, 1) / Rational(1073741827, 1))\n    assert_equal(Rational(11, 3),\n                 Rational(3, 1) + Rational(2, 3))\n    assert_equal(Rational(7, 3),\n                 Rational(3, 1) - Rational(2, 3))\n    assert_equal(Rational(2, 1),\n                 Rational(3, 1) * Rational(2, 3))\n    assert_equal(Rational(9, 2),\n                 Rational(3, 1) / Rational(2, 3))\n    assert_equal(Rational(9, 2),\n                 Rational(3, 1) + Rational(3, 2))\n    assert_equal(Rational(3, 2),\n                 Rational(3, 1) - Rational(3, 2))\n    assert_equal(Rational(9, 2),\n                 Rational(3, 1) * Rational(3, 2))\n    assert_equal(Rational(2, 1),\n                 Rational(3, 1) / Rational(3, 2))\n    assert_equal(Rational(3221225370, 1073741789),\n                 Rational(3, 1) + Rational(3, 1073741789))\n    assert_equal(Rational(3221225364, 1073741789),\n                 Rational(3, 1) - Rational(3, 1073741789))\n    assert_equal(Rational(9, 1073741789),\n                 Rational(3, 1) * Rational(3, 1073741789))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(3, 1) / Rational(3, 1073741789))\n    assert_equal(Rational(1073741798, 3),\n                 Rational(3, 1) + Rational(1073741789, 3))\n    assert_equal(Rational(-1073741780, 3),\n                 Rational(3, 1) - Rational(1073741789, 3))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(3, 1) * Rational(1073741789, 3))\n    assert_equal(Rational(9, 1073741789),\n                 Rational(3, 1) / Rational(1073741789, 3))\n    assert_equal(Rational(3221225484, 1073741827),\n                 Rational(3, 1) + Rational(3, 1073741827))\n    assert_equal(Rational(3221225478, 1073741827),\n                 Rational(3, 1) - Rational(3, 1073741827))\n    assert_equal(Rational(9, 1073741827),\n                 Rational(3, 1) * Rational(3, 1073741827))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(3, 1) / Rational(3, 1073741827))\n    assert_equal(Rational(1073741836, 3),\n                 Rational(3, 1) + Rational(1073741827, 3))\n    assert_equal(Rational(-1073741818, 3),\n                 Rational(3, 1) - Rational(1073741827, 3))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(3, 1) * Rational(1073741827, 3))\n    assert_equal(Rational(9, 1073741827),\n                 Rational(3, 1) / Rational(1073741827, 3))\n    assert_equal(Rational(4294967270, 1073741827),\n                 Rational(3, 1) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483692, 1073741827),\n                 Rational(3, 1) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225367, 1073741827),\n                 Rational(3, 1) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225481, 1073741789),\n                 Rational(3, 1) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(4294967194, 1073741789),\n                 Rational(3, 1) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(2147483540, 1073741789),\n                 Rational(3, 1) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(3221225481, 1073741789),\n                 Rational(3, 1) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(3221225367, 1073741827),\n                 Rational(3, 1) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741789, 1), +Rational(1073741789, 1))\n    assert_equal(Rational(-1073741789, 1), -Rational(1073741789, 1))\n    assert_equal(Rational(1073741790, 1),\n                 Rational(1073741789, 1) + Rational(1, 1))\n    assert_equal(Rational(1073741788, 1),\n                 Rational(1073741789, 1) - Rational(1, 1))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1073741789, 1) * Rational(1, 1))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1073741789, 1) / Rational(1, 1))\n    assert_equal(Rational(1073741791, 1),\n                 Rational(1073741789, 1) + Rational(2, 1))\n    assert_equal(Rational(1073741787, 1),\n                 Rational(1073741789, 1) - Rational(2, 1))\n    assert_equal(Rational(2147483578, 1),\n                 Rational(1073741789, 1) * Rational(2, 1))\n    assert_equal(Rational(1073741789, 2),\n                 Rational(1073741789, 1) / Rational(2, 1))\n    assert_equal(Rational(1073741792, 1),\n                 Rational(1073741789, 1) + Rational(3, 1))\n    assert_equal(Rational(1073741786, 1),\n                 Rational(1073741789, 1) - Rational(3, 1))\n    assert_equal(Rational(3221225367, 1),\n                 Rational(1073741789, 1) * Rational(3, 1))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741789, 1) / Rational(3, 1))\n    assert_equal(Rational(2147483578, 1),\n                 Rational(1073741789, 1) + Rational(1073741789, 1))\n    assert_equal(Rational(0, 1),\n                 Rational(1073741789, 1) - Rational(1073741789, 1))\n    assert_equal(Rational(1152921429444920521, 1),\n                 Rational(1073741789, 1) * Rational(1073741789, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741789, 1) / Rational(1073741789, 1))\n    assert_equal(Rational(2147483616, 1),\n                 Rational(1073741789, 1) + Rational(1073741827, 1))\n    assert_equal(Rational(-38, 1),\n                 Rational(1073741789, 1) - Rational(1073741827, 1))\n    assert_equal(Rational(1152921470247108503, 1),\n                 Rational(1073741789, 1) * Rational(1073741827, 1))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1073741789, 1) / Rational(1073741827, 1))\n    assert_equal(Rational(3221225369, 3),\n                 Rational(1073741789, 1) + Rational(2, 3))\n    assert_equal(Rational(3221225365, 3),\n                 Rational(1073741789, 1) - Rational(2, 3))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(1073741789, 1) * Rational(2, 3))\n    assert_equal(Rational(3221225367, 2),\n                 Rational(1073741789, 1) / Rational(2, 3))\n    assert_equal(Rational(2147483581, 2),\n                 Rational(1073741789, 1) + Rational(3, 2))\n    assert_equal(Rational(2147483575, 2),\n                 Rational(1073741789, 1) - Rational(3, 2))\n    assert_equal(Rational(3221225367, 2),\n                 Rational(1073741789, 1) * Rational(3, 2))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(1073741789, 1) / Rational(3, 2))\n    assert_equal(Rational(1152921429444920524, 1073741789),\n                 Rational(1073741789, 1) + Rational(3, 1073741789))\n    assert_equal(Rational(1152921429444920518, 1073741789),\n                 Rational(1073741789, 1) - Rational(3, 1073741789))\n    assert_equal(Rational(3, 1),\n                 Rational(1073741789, 1) * Rational(3, 1073741789))\n    assert_equal(Rational(1152921429444920521, 3),\n                 Rational(1073741789, 1) / Rational(3, 1073741789))\n    assert_equal(Rational(4294967156, 3),\n                 Rational(1073741789, 1) + Rational(1073741789, 3))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(1073741789, 1) - Rational(1073741789, 3))\n    assert_equal(Rational(1152921429444920521, 3),\n                 Rational(1073741789, 1) * Rational(1073741789, 3))\n    assert_equal(Rational(3, 1),\n                 Rational(1073741789, 1) / Rational(1073741789, 3))\n    assert_equal(Rational(1152921470247108506, 1073741827),\n                 Rational(1073741789, 1) + Rational(3, 1073741827))\n    assert_equal(Rational(1152921470247108500, 1073741827),\n                 Rational(1073741789, 1) - Rational(3, 1073741827))\n    assert_equal(Rational(3221225367, 1073741827),\n                 Rational(1073741789, 1) * Rational(3, 1073741827))\n    assert_equal(Rational(1152921470247108503, 3),\n                 Rational(1073741789, 1) / Rational(3, 1073741827))\n    assert_equal(Rational(4294967194, 3),\n                 Rational(1073741789, 1) + Rational(1073741827, 3))\n    assert_equal(Rational(2147483540, 3),\n                 Rational(1073741789, 1) - Rational(1073741827, 3))\n    assert_equal(Rational(1152921470247108503, 3),\n                 Rational(1073741789, 1) * Rational(1073741827, 3))\n    assert_equal(Rational(3221225367, 1073741827),\n                 Rational(1073741789, 1) / Rational(1073741827, 3))\n    assert_equal(Rational(1152921471320850292, 1073741827),\n                 Rational(1073741789, 1) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921469173366714, 1073741827),\n                 Rational(1073741789, 1) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921429444920521, 1073741827),\n                 Rational(1073741789, 1) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1073741789, 1) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921430518662348, 1073741789),\n                 Rational(1073741789, 1) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921428371178694, 1073741789),\n                 Rational(1073741789, 1) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1073741789, 1) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921429444920521, 1073741827),\n                 Rational(1073741789, 1) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741827, 1), +Rational(1073741827, 1))\n    assert_equal(Rational(-1073741827, 1), -Rational(1073741827, 1))\n    assert_equal(Rational(1073741828, 1),\n                 Rational(1073741827, 1) + Rational(1, 1))\n    assert_equal(Rational(1073741826, 1),\n                 Rational(1073741827, 1) - Rational(1, 1))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1073741827, 1) * Rational(1, 1))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1073741827, 1) / Rational(1, 1))\n    assert_equal(Rational(1073741829, 1),\n                 Rational(1073741827, 1) + Rational(2, 1))\n    assert_equal(Rational(1073741825, 1),\n                 Rational(1073741827, 1) - Rational(2, 1))\n    assert_equal(Rational(2147483654, 1),\n                 Rational(1073741827, 1) * Rational(2, 1))\n    assert_equal(Rational(1073741827, 2),\n                 Rational(1073741827, 1) / Rational(2, 1))\n    assert_equal(Rational(1073741830, 1),\n                 Rational(1073741827, 1) + Rational(3, 1))\n    assert_equal(Rational(1073741824, 1),\n                 Rational(1073741827, 1) - Rational(3, 1))\n    assert_equal(Rational(3221225481, 1),\n                 Rational(1073741827, 1) * Rational(3, 1))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741827, 1) / Rational(3, 1))\n    assert_equal(Rational(2147483616, 1),\n                 Rational(1073741827, 1) + Rational(1073741789, 1))\n    assert_equal(Rational(38, 1),\n                 Rational(1073741827, 1) - Rational(1073741789, 1))\n    assert_equal(Rational(1152921470247108503, 1),\n                 Rational(1073741827, 1) * Rational(1073741789, 1))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1073741827, 1) / Rational(1073741789, 1))\n    assert_equal(Rational(2147483654, 1),\n                 Rational(1073741827, 1) + Rational(1073741827, 1))\n    assert_equal(Rational(0, 1),\n                 Rational(1073741827, 1) - Rational(1073741827, 1))\n    assert_equal(Rational(1152921511049297929, 1),\n                 Rational(1073741827, 1) * Rational(1073741827, 1))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741827, 1) / Rational(1073741827, 1))\n    assert_equal(Rational(3221225483, 3),\n                 Rational(1073741827, 1) + Rational(2, 3))\n    assert_equal(Rational(3221225479, 3),\n                 Rational(1073741827, 1) - Rational(2, 3))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(1073741827, 1) * Rational(2, 3))\n    assert_equal(Rational(3221225481, 2),\n                 Rational(1073741827, 1) / Rational(2, 3))\n    assert_equal(Rational(2147483657, 2),\n                 Rational(1073741827, 1) + Rational(3, 2))\n    assert_equal(Rational(2147483651, 2),\n                 Rational(1073741827, 1) - Rational(3, 2))\n    assert_equal(Rational(3221225481, 2),\n                 Rational(1073741827, 1) * Rational(3, 2))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(1073741827, 1) / Rational(3, 2))\n    assert_equal(Rational(1152921470247108506, 1073741789),\n                 Rational(1073741827, 1) + Rational(3, 1073741789))\n    assert_equal(Rational(1152921470247108500, 1073741789),\n                 Rational(1073741827, 1) - Rational(3, 1073741789))\n    assert_equal(Rational(3221225481, 1073741789),\n                 Rational(1073741827, 1) * Rational(3, 1073741789))\n    assert_equal(Rational(1152921470247108503, 3),\n                 Rational(1073741827, 1) / Rational(3, 1073741789))\n    assert_equal(Rational(4294967270, 3),\n                 Rational(1073741827, 1) + Rational(1073741789, 3))\n    assert_equal(Rational(2147483692, 3),\n                 Rational(1073741827, 1) - Rational(1073741789, 3))\n    assert_equal(Rational(1152921470247108503, 3),\n                 Rational(1073741827, 1) * Rational(1073741789, 3))\n    assert_equal(Rational(3221225481, 1073741789),\n                 Rational(1073741827, 1) / Rational(1073741789, 3))\n    assert_equal(Rational(1152921511049297932, 1073741827),\n                 Rational(1073741827, 1) + Rational(3, 1073741827))\n    assert_equal(Rational(1152921511049297926, 1073741827),\n                 Rational(1073741827, 1) - Rational(3, 1073741827))\n    assert_equal(Rational(3, 1),\n                 Rational(1073741827, 1) * Rational(3, 1073741827))\n    assert_equal(Rational(1152921511049297929, 3),\n                 Rational(1073741827, 1) / Rational(3, 1073741827))\n    assert_equal(Rational(4294967308, 3),\n                 Rational(1073741827, 1) + Rational(1073741827, 3))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(1073741827, 1) - Rational(1073741827, 3))\n    assert_equal(Rational(1152921511049297929, 3),\n                 Rational(1073741827, 1) * Rational(1073741827, 3))\n    assert_equal(Rational(3, 1),\n                 Rational(1073741827, 1) / Rational(1073741827, 3))\n    assert_equal(Rational(1152921512123039718, 1073741827),\n                 Rational(1073741827, 1) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921509975556140, 1073741827),\n                 Rational(1073741827, 1) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1073741827, 1) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921511049297929, 1073741789),\n                 Rational(1073741827, 1) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921471320850330, 1073741789),\n                 Rational(1073741827, 1) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921469173366676, 1073741789),\n                 Rational(1073741827, 1) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921511049297929, 1073741789),\n                 Rational(1073741827, 1) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1073741827, 1) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(2, 3), +Rational(2, 3))\n    assert_equal(Rational(-2, 3), -Rational(2, 3))\n    assert_equal(Rational(5, 3),\n                 Rational(2, 3) + Rational(1, 1))\n    assert_equal(Rational(-1, 3),\n                 Rational(2, 3) - Rational(1, 1))\n    assert_equal(Rational(2, 3),\n                 Rational(2, 3) * Rational(1, 1))\n    assert_equal(Rational(2, 3),\n                 Rational(2, 3) / Rational(1, 1))\n    assert_equal(Rational(8, 3),\n                 Rational(2, 3) + Rational(2, 1))\n    assert_equal(Rational(-4, 3),\n                 Rational(2, 3) - Rational(2, 1))\n    assert_equal(Rational(4, 3),\n                 Rational(2, 3) * Rational(2, 1))\n    assert_equal(Rational(1, 3),\n                 Rational(2, 3) / Rational(2, 1))\n    assert_equal(Rational(11, 3),\n                 Rational(2, 3) + Rational(3, 1))\n    assert_equal(Rational(-7, 3),\n                 Rational(2, 3) - Rational(3, 1))\n    assert_equal(Rational(2, 1),\n                 Rational(2, 3) * Rational(3, 1))\n    assert_equal(Rational(2, 9),\n                 Rational(2, 3) / Rational(3, 1))\n    assert_equal(Rational(3221225369, 3),\n                 Rational(2, 3) + Rational(1073741789, 1))\n    assert_equal(Rational(-3221225365, 3),\n                 Rational(2, 3) - Rational(1073741789, 1))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(2, 3) * Rational(1073741789, 1))\n    assert_equal(Rational(2, 3221225367),\n                 Rational(2, 3) / Rational(1073741789, 1))\n    assert_equal(Rational(3221225483, 3),\n                 Rational(2, 3) + Rational(1073741827, 1))\n    assert_equal(Rational(-3221225479, 3),\n                 Rational(2, 3) - Rational(1073741827, 1))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(2, 3) * Rational(1073741827, 1))\n    assert_equal(Rational(2, 3221225481),\n                 Rational(2, 3) / Rational(1073741827, 1))\n    assert_equal(Rational(4, 3),\n                 Rational(2, 3) + Rational(2, 3))\n    assert_equal(Rational(0, 1),\n                 Rational(2, 3) - Rational(2, 3))\n    assert_equal(Rational(4, 9),\n                 Rational(2, 3) * Rational(2, 3))\n    assert_equal(Rational(1, 1),\n                 Rational(2, 3) / Rational(2, 3))\n    assert_equal(Rational(13, 6),\n                 Rational(2, 3) + Rational(3, 2))\n    assert_equal(Rational(-5, 6),\n                 Rational(2, 3) - Rational(3, 2))\n    assert_equal(Rational(1, 1),\n                 Rational(2, 3) * Rational(3, 2))\n    assert_equal(Rational(4, 9),\n                 Rational(2, 3) / Rational(3, 2))\n    assert_equal(Rational(2147483587, 3221225367),\n                 Rational(2, 3) + Rational(3, 1073741789))\n    assert_equal(Rational(2147483569, 3221225367),\n                 Rational(2, 3) - Rational(3, 1073741789))\n    assert_equal(Rational(2, 1073741789),\n                 Rational(2, 3) * Rational(3, 1073741789))\n    assert_equal(Rational(2147483578, 9),\n                 Rational(2, 3) / Rational(3, 1073741789))\n    assert_equal(Rational(1073741791, 3),\n                 Rational(2, 3) + Rational(1073741789, 3))\n    assert_equal(Rational(-357913929, 1),\n                 Rational(2, 3) - Rational(1073741789, 3))\n    assert_equal(Rational(2147483578, 9),\n                 Rational(2, 3) * Rational(1073741789, 3))\n    assert_equal(Rational(2, 1073741789),\n                 Rational(2, 3) / Rational(1073741789, 3))\n    assert_equal(Rational(2147483663, 3221225481),\n                 Rational(2, 3) + Rational(3, 1073741827))\n    assert_equal(Rational(2147483645, 3221225481),\n                 Rational(2, 3) - Rational(3, 1073741827))\n    assert_equal(Rational(2, 1073741827),\n                 Rational(2, 3) * Rational(3, 1073741827))\n    assert_equal(Rational(2147483654, 9),\n                 Rational(2, 3) / Rational(3, 1073741827))\n    assert_equal(Rational(357913943, 1),\n                 Rational(2, 3) + Rational(1073741827, 3))\n    assert_equal(Rational(-1073741825, 3),\n                 Rational(2, 3) - Rational(1073741827, 3))\n    assert_equal(Rational(2147483654, 9),\n                 Rational(2, 3) * Rational(1073741827, 3))\n    assert_equal(Rational(2, 1073741827),\n                 Rational(2, 3) / Rational(1073741827, 3))\n    assert_equal(Rational(5368709021, 3221225481),\n                 Rational(2, 3) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(-1073741713, 3221225481),\n                 Rational(2, 3) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483578, 3221225481),\n                 Rational(2, 3) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483654, 3221225367),\n                 Rational(2, 3) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(5368709059, 3221225367),\n                 Rational(2, 3) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(-1073741903, 3221225367),\n                 Rational(2, 3) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(2147483654, 3221225367),\n                 Rational(2, 3) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(2147483578, 3221225481),\n                 Rational(2, 3) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(3, 2), +Rational(3, 2))\n    assert_equal(Rational(-3, 2), -Rational(3, 2))\n    assert_equal(Rational(5, 2),\n                 Rational(3, 2) + Rational(1, 1))\n    assert_equal(Rational(1, 2),\n                 Rational(3, 2) - Rational(1, 1))\n    assert_equal(Rational(3, 2),\n                 Rational(3, 2) * Rational(1, 1))\n    assert_equal(Rational(3, 2),\n                 Rational(3, 2) / Rational(1, 1))\n    assert_equal(Rational(7, 2),\n                 Rational(3, 2) + Rational(2, 1))\n    assert_equal(Rational(-1, 2),\n                 Rational(3, 2) - Rational(2, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(3, 2) * Rational(2, 1))\n    assert_equal(Rational(3, 4),\n                 Rational(3, 2) / Rational(2, 1))\n    assert_equal(Rational(9, 2),\n                 Rational(3, 2) + Rational(3, 1))\n    assert_equal(Rational(-3, 2),\n                 Rational(3, 2) - Rational(3, 1))\n    assert_equal(Rational(9, 2),\n                 Rational(3, 2) * Rational(3, 1))\n    assert_equal(Rational(1, 2),\n                 Rational(3, 2) / Rational(3, 1))\n    assert_equal(Rational(2147483581, 2),\n                 Rational(3, 2) + Rational(1073741789, 1))\n    assert_equal(Rational(-2147483575, 2),\n                 Rational(3, 2) - Rational(1073741789, 1))\n    assert_equal(Rational(3221225367, 2),\n                 Rational(3, 2) * Rational(1073741789, 1))\n    assert_equal(Rational(3, 2147483578),\n                 Rational(3, 2) / Rational(1073741789, 1))\n    assert_equal(Rational(2147483657, 2),\n                 Rational(3, 2) + Rational(1073741827, 1))\n    assert_equal(Rational(-2147483651, 2),\n                 Rational(3, 2) - Rational(1073741827, 1))\n    assert_equal(Rational(3221225481, 2),\n                 Rational(3, 2) * Rational(1073741827, 1))\n    assert_equal(Rational(3, 2147483654),\n                 Rational(3, 2) / Rational(1073741827, 1))\n    assert_equal(Rational(13, 6),\n                 Rational(3, 2) + Rational(2, 3))\n    assert_equal(Rational(5, 6),\n                 Rational(3, 2) - Rational(2, 3))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 2) * Rational(2, 3))\n    assert_equal(Rational(9, 4),\n                 Rational(3, 2) / Rational(2, 3))\n    assert_equal(Rational(3, 1),\n                 Rational(3, 2) + Rational(3, 2))\n    assert_equal(Rational(0, 1),\n                 Rational(3, 2) - Rational(3, 2))\n    assert_equal(Rational(9, 4),\n                 Rational(3, 2) * Rational(3, 2))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 2) / Rational(3, 2))\n    assert_equal(Rational(3221225373, 2147483578),\n                 Rational(3, 2) + Rational(3, 1073741789))\n    assert_equal(Rational(3221225361, 2147483578),\n                 Rational(3, 2) - Rational(3, 1073741789))\n    assert_equal(Rational(9, 2147483578),\n                 Rational(3, 2) * Rational(3, 1073741789))\n    assert_equal(Rational(1073741789, 2),\n                 Rational(3, 2) / Rational(3, 1073741789))\n    assert_equal(Rational(2147483587, 6),\n                 Rational(3, 2) + Rational(1073741789, 3))\n    assert_equal(Rational(-2147483569, 6),\n                 Rational(3, 2) - Rational(1073741789, 3))\n    assert_equal(Rational(1073741789, 2),\n                 Rational(3, 2) * Rational(1073741789, 3))\n    assert_equal(Rational(9, 2147483578),\n                 Rational(3, 2) / Rational(1073741789, 3))\n    assert_equal(Rational(3221225487, 2147483654),\n                 Rational(3, 2) + Rational(3, 1073741827))\n    assert_equal(Rational(3221225475, 2147483654),\n                 Rational(3, 2) - Rational(3, 1073741827))\n    assert_equal(Rational(9, 2147483654),\n                 Rational(3, 2) * Rational(3, 1073741827))\n    assert_equal(Rational(1073741827, 2),\n                 Rational(3, 2) / Rational(3, 1073741827))\n    assert_equal(Rational(2147483663, 6),\n                 Rational(3, 2) + Rational(1073741827, 3))\n    assert_equal(Rational(-2147483645, 6),\n                 Rational(3, 2) - Rational(1073741827, 3))\n    assert_equal(Rational(1073741827, 2),\n                 Rational(3, 2) * Rational(1073741827, 3))\n    assert_equal(Rational(9, 2147483654),\n                 Rational(3, 2) / Rational(1073741827, 3))\n    assert_equal(Rational(5368709059, 2147483654),\n                 Rational(3, 2) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741903, 2147483654),\n                 Rational(3, 2) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225367, 2147483654),\n                 Rational(3, 2) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225481, 2147483578),\n                 Rational(3, 2) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(5368709021, 2147483578),\n                 Rational(3, 2) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741713, 2147483578),\n                 Rational(3, 2) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(3221225481, 2147483578),\n                 Rational(3, 2) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(3221225367, 2147483654),\n                 Rational(3, 2) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(3, 1073741789), +Rational(3, 1073741789))\n    assert_equal(Rational(-3, 1073741789), -Rational(3, 1073741789))\n    assert_equal(Rational(1073741792, 1073741789),\n                 Rational(3, 1073741789) + Rational(1, 1))\n    assert_equal(Rational(-1073741786, 1073741789),\n                 Rational(3, 1073741789) - Rational(1, 1))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(3, 1073741789) * Rational(1, 1))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(3, 1073741789) / Rational(1, 1))\n    assert_equal(Rational(2147483581, 1073741789),\n                 Rational(3, 1073741789) + Rational(2, 1))\n    assert_equal(Rational(-2147483575, 1073741789),\n                 Rational(3, 1073741789) - Rational(2, 1))\n    assert_equal(Rational(6, 1073741789),\n                 Rational(3, 1073741789) * Rational(2, 1))\n    assert_equal(Rational(3, 2147483578),\n                 Rational(3, 1073741789) / Rational(2, 1))\n    assert_equal(Rational(3221225370, 1073741789),\n                 Rational(3, 1073741789) + Rational(3, 1))\n    assert_equal(Rational(-3221225364, 1073741789),\n                 Rational(3, 1073741789) - Rational(3, 1))\n    assert_equal(Rational(9, 1073741789),\n                 Rational(3, 1073741789) * Rational(3, 1))\n    assert_equal(Rational(1, 1073741789),\n                 Rational(3, 1073741789) / Rational(3, 1))\n    assert_equal(Rational(1152921429444920524, 1073741789),\n                 Rational(3, 1073741789) + Rational(1073741789, 1))\n    assert_equal(Rational(-1152921429444920518, 1073741789),\n                 Rational(3, 1073741789) - Rational(1073741789, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(3, 1073741789) * Rational(1073741789, 1))\n    assert_equal(Rational(3, 1152921429444920521),\n                 Rational(3, 1073741789) / Rational(1073741789, 1))\n    assert_equal(Rational(1152921470247108506, 1073741789),\n                 Rational(3, 1073741789) + Rational(1073741827, 1))\n    assert_equal(Rational(-1152921470247108500, 1073741789),\n                 Rational(3, 1073741789) - Rational(1073741827, 1))\n    assert_equal(Rational(3221225481, 1073741789),\n                 Rational(3, 1073741789) * Rational(1073741827, 1))\n    assert_equal(Rational(3, 1152921470247108503),\n                 Rational(3, 1073741789) / Rational(1073741827, 1))\n    assert_equal(Rational(2147483587, 3221225367),\n                 Rational(3, 1073741789) + Rational(2, 3))\n    assert_equal(Rational(-2147483569, 3221225367),\n                 Rational(3, 1073741789) - Rational(2, 3))\n    assert_equal(Rational(2, 1073741789),\n                 Rational(3, 1073741789) * Rational(2, 3))\n    assert_equal(Rational(9, 2147483578),\n                 Rational(3, 1073741789) / Rational(2, 3))\n    assert_equal(Rational(3221225373, 2147483578),\n                 Rational(3, 1073741789) + Rational(3, 2))\n    assert_equal(Rational(-3221225361, 2147483578),\n                 Rational(3, 1073741789) - Rational(3, 2))\n    assert_equal(Rational(9, 2147483578),\n                 Rational(3, 1073741789) * Rational(3, 2))\n    assert_equal(Rational(2, 1073741789),\n                 Rational(3, 1073741789) / Rational(3, 2))\n    assert_equal(Rational(6, 1073741789),\n                 Rational(3, 1073741789) + Rational(3, 1073741789))\n    assert_equal(Rational(0, 1),\n                 Rational(3, 1073741789) - Rational(3, 1073741789))\n    assert_equal(Rational(9, 1152921429444920521),\n                 Rational(3, 1073741789) * Rational(3, 1073741789))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 1073741789) / Rational(3, 1073741789))\n    assert_equal(Rational(1152921429444920530, 3221225367),\n                 Rational(3, 1073741789) + Rational(1073741789, 3))\n    assert_equal(Rational(-1152921429444920512, 3221225367),\n                 Rational(3, 1073741789) - Rational(1073741789, 3))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 1073741789) * Rational(1073741789, 3))\n    assert_equal(Rational(9, 1152921429444920521),\n                 Rational(3, 1073741789) / Rational(1073741789, 3))\n    assert_equal(Rational(6442450848, 1152921470247108503),\n                 Rational(3, 1073741789) + Rational(3, 1073741827))\n    assert_equal(Rational(114, 1152921470247108503),\n                 Rational(3, 1073741789) - Rational(3, 1073741827))\n    assert_equal(Rational(9, 1152921470247108503),\n                 Rational(3, 1073741789) * Rational(3, 1073741827))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(3, 1073741789) / Rational(3, 1073741827))\n    assert_equal(Rational(1152921470247108512, 3221225367),\n                 Rational(3, 1073741789) + Rational(1073741827, 3))\n    assert_equal(Rational(-1152921470247108494, 3221225367),\n                 Rational(3, 1073741789) - Rational(1073741827, 3))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(3, 1073741789) * Rational(1073741827, 3))\n    assert_equal(Rational(9, 1152921470247108503),\n                 Rational(3, 1073741789) / Rational(1073741827, 3))\n    assert_equal(Rational(1152921432666146002, 1152921470247108503),\n                 Rational(3, 1073741789) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(-1152921426223695040, 1152921470247108503),\n                 Rational(3, 1073741789) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(3, 1073741789) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225481, 1152921429444920521),\n                 Rational(3, 1073741789) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741830, 1073741789),\n                 Rational(3, 1073741789) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(-1073741824, 1073741789),\n                 Rational(3, 1073741789) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(3221225481, 1152921429444920521),\n                 Rational(3, 1073741789) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(3, 1073741789) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741789, 3), +Rational(1073741789, 3))\n    assert_equal(Rational(-1073741789, 3), -Rational(1073741789, 3))\n    assert_equal(Rational(1073741792, 3),\n                 Rational(1073741789, 3) + Rational(1, 1))\n    assert_equal(Rational(1073741786, 3),\n                 Rational(1073741789, 3) - Rational(1, 1))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741789, 3) * Rational(1, 1))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741789, 3) / Rational(1, 1))\n    assert_equal(Rational(1073741795, 3),\n                 Rational(1073741789, 3) + Rational(2, 1))\n    assert_equal(Rational(1073741783, 3),\n                 Rational(1073741789, 3) - Rational(2, 1))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(1073741789, 3) * Rational(2, 1))\n    assert_equal(Rational(1073741789, 6),\n                 Rational(1073741789, 3) / Rational(2, 1))\n    assert_equal(Rational(1073741798, 3),\n                 Rational(1073741789, 3) + Rational(3, 1))\n    assert_equal(Rational(1073741780, 3),\n                 Rational(1073741789, 3) - Rational(3, 1))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1073741789, 3) * Rational(3, 1))\n    assert_equal(Rational(1073741789, 9),\n                 Rational(1073741789, 3) / Rational(3, 1))\n    assert_equal(Rational(4294967156, 3),\n                 Rational(1073741789, 3) + Rational(1073741789, 1))\n    assert_equal(Rational(-2147483578, 3),\n                 Rational(1073741789, 3) - Rational(1073741789, 1))\n    assert_equal(Rational(1152921429444920521, 3),\n                 Rational(1073741789, 3) * Rational(1073741789, 1))\n    assert_equal(Rational(1, 3),\n                 Rational(1073741789, 3) / Rational(1073741789, 1))\n    assert_equal(Rational(4294967270, 3),\n                 Rational(1073741789, 3) + Rational(1073741827, 1))\n    assert_equal(Rational(-2147483692, 3),\n                 Rational(1073741789, 3) - Rational(1073741827, 1))\n    assert_equal(Rational(1152921470247108503, 3),\n                 Rational(1073741789, 3) * Rational(1073741827, 1))\n    assert_equal(Rational(1073741789, 3221225481),\n                 Rational(1073741789, 3) / Rational(1073741827, 1))\n    assert_equal(Rational(1073741791, 3),\n                 Rational(1073741789, 3) + Rational(2, 3))\n    assert_equal(Rational(357913929, 1),\n                 Rational(1073741789, 3) - Rational(2, 3))\n    assert_equal(Rational(2147483578, 9),\n                 Rational(1073741789, 3) * Rational(2, 3))\n    assert_equal(Rational(1073741789, 2),\n                 Rational(1073741789, 3) / Rational(2, 3))\n    assert_equal(Rational(2147483587, 6),\n                 Rational(1073741789, 3) + Rational(3, 2))\n    assert_equal(Rational(2147483569, 6),\n                 Rational(1073741789, 3) - Rational(3, 2))\n    assert_equal(Rational(1073741789, 2),\n                 Rational(1073741789, 3) * Rational(3, 2))\n    assert_equal(Rational(2147483578, 9),\n                 Rational(1073741789, 3) / Rational(3, 2))\n    assert_equal(Rational(1152921429444920530, 3221225367),\n                 Rational(1073741789, 3) + Rational(3, 1073741789))\n    assert_equal(Rational(1152921429444920512, 3221225367),\n                 Rational(1073741789, 3) - Rational(3, 1073741789))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741789, 3) * Rational(3, 1073741789))\n    assert_equal(Rational(1152921429444920521, 9),\n                 Rational(1073741789, 3) / Rational(3, 1073741789))\n    assert_equal(Rational(2147483578, 3),\n                 Rational(1073741789, 3) + Rational(1073741789, 3))\n    assert_equal(Rational(0, 1),\n                 Rational(1073741789, 3) - Rational(1073741789, 3))\n    assert_equal(Rational(1152921429444920521, 9),\n                 Rational(1073741789, 3) * Rational(1073741789, 3))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741789, 3) / Rational(1073741789, 3))\n    assert_equal(Rational(1152921470247108512, 3221225481),\n                 Rational(1073741789, 3) + Rational(3, 1073741827))\n    assert_equal(Rational(1152921470247108494, 3221225481),\n                 Rational(1073741789, 3) - Rational(3, 1073741827))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1073741789, 3) * Rational(3, 1073741827))\n    assert_equal(Rational(1152921470247108503, 9),\n                 Rational(1073741789, 3) / Rational(3, 1073741827))\n    assert_equal(Rational(715827872, 1),\n                 Rational(1073741789, 3) + Rational(1073741827, 3))\n    assert_equal(Rational(-38, 3),\n                 Rational(1073741789, 3) - Rational(1073741827, 3))\n    assert_equal(Rational(1152921470247108503, 9),\n                 Rational(1073741789, 3) * Rational(1073741827, 3))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1073741789, 3) / Rational(1073741827, 3))\n    assert_equal(Rational(1152921473468333870, 3221225481),\n                 Rational(1073741789, 3) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921467025883136, 3221225481),\n                 Rational(1073741789, 3) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921429444920521, 3221225481),\n                 Rational(1073741789, 3) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741789, 3) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921432666146002, 3221225367),\n                 Rational(1073741789, 3) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921426223695040, 3221225367),\n                 Rational(1073741789, 3) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741789, 3) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921429444920521, 3221225481),\n                 Rational(1073741789, 3) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(3, 1073741827), +Rational(3, 1073741827))\n    assert_equal(Rational(-3, 1073741827), -Rational(3, 1073741827))\n    assert_equal(Rational(1073741830, 1073741827),\n                 Rational(3, 1073741827) + Rational(1, 1))\n    assert_equal(Rational(-1073741824, 1073741827),\n                 Rational(3, 1073741827) - Rational(1, 1))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(3, 1073741827) * Rational(1, 1))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(3, 1073741827) / Rational(1, 1))\n    assert_equal(Rational(2147483657, 1073741827),\n                 Rational(3, 1073741827) + Rational(2, 1))\n    assert_equal(Rational(-2147483651, 1073741827),\n                 Rational(3, 1073741827) - Rational(2, 1))\n    assert_equal(Rational(6, 1073741827),\n                 Rational(3, 1073741827) * Rational(2, 1))\n    assert_equal(Rational(3, 2147483654),\n                 Rational(3, 1073741827) / Rational(2, 1))\n    assert_equal(Rational(3221225484, 1073741827),\n                 Rational(3, 1073741827) + Rational(3, 1))\n    assert_equal(Rational(-3221225478, 1073741827),\n                 Rational(3, 1073741827) - Rational(3, 1))\n    assert_equal(Rational(9, 1073741827),\n                 Rational(3, 1073741827) * Rational(3, 1))\n    assert_equal(Rational(1, 1073741827),\n                 Rational(3, 1073741827) / Rational(3, 1))\n    assert_equal(Rational(1152921470247108506, 1073741827),\n                 Rational(3, 1073741827) + Rational(1073741789, 1))\n    assert_equal(Rational(-1152921470247108500, 1073741827),\n                 Rational(3, 1073741827) - Rational(1073741789, 1))\n    assert_equal(Rational(3221225367, 1073741827),\n                 Rational(3, 1073741827) * Rational(1073741789, 1))\n    assert_equal(Rational(3, 1152921470247108503),\n                 Rational(3, 1073741827) / Rational(1073741789, 1))\n    assert_equal(Rational(1152921511049297932, 1073741827),\n                 Rational(3, 1073741827) + Rational(1073741827, 1))\n    assert_equal(Rational(-1152921511049297926, 1073741827),\n                 Rational(3, 1073741827) - Rational(1073741827, 1))\n    assert_equal(Rational(3, 1),\n                 Rational(3, 1073741827) * Rational(1073741827, 1))\n    assert_equal(Rational(3, 1152921511049297929),\n                 Rational(3, 1073741827) / Rational(1073741827, 1))\n    assert_equal(Rational(2147483663, 3221225481),\n                 Rational(3, 1073741827) + Rational(2, 3))\n    assert_equal(Rational(-2147483645, 3221225481),\n                 Rational(3, 1073741827) - Rational(2, 3))\n    assert_equal(Rational(2, 1073741827),\n                 Rational(3, 1073741827) * Rational(2, 3))\n    assert_equal(Rational(9, 2147483654),\n                 Rational(3, 1073741827) / Rational(2, 3))\n    assert_equal(Rational(3221225487, 2147483654),\n                 Rational(3, 1073741827) + Rational(3, 2))\n    assert_equal(Rational(-3221225475, 2147483654),\n                 Rational(3, 1073741827) - Rational(3, 2))\n    assert_equal(Rational(9, 2147483654),\n                 Rational(3, 1073741827) * Rational(3, 2))\n    assert_equal(Rational(2, 1073741827),\n                 Rational(3, 1073741827) / Rational(3, 2))\n    assert_equal(Rational(6442450848, 1152921470247108503),\n                 Rational(3, 1073741827) + Rational(3, 1073741789))\n    assert_equal(Rational(-114, 1152921470247108503),\n                 Rational(3, 1073741827) - Rational(3, 1073741789))\n    assert_equal(Rational(9, 1152921470247108503),\n                 Rational(3, 1073741827) * Rational(3, 1073741789))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(3, 1073741827) / Rational(3, 1073741789))\n    assert_equal(Rational(1152921470247108512, 3221225481),\n                 Rational(3, 1073741827) + Rational(1073741789, 3))\n    assert_equal(Rational(-1152921470247108494, 3221225481),\n                 Rational(3, 1073741827) - Rational(1073741789, 3))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(3, 1073741827) * Rational(1073741789, 3))\n    assert_equal(Rational(9, 1152921470247108503),\n                 Rational(3, 1073741827) / Rational(1073741789, 3))\n    assert_equal(Rational(6, 1073741827),\n                 Rational(3, 1073741827) + Rational(3, 1073741827))\n    assert_equal(Rational(0, 1),\n                 Rational(3, 1073741827) - Rational(3, 1073741827))\n    assert_equal(Rational(9, 1152921511049297929),\n                 Rational(3, 1073741827) * Rational(3, 1073741827))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 1073741827) / Rational(3, 1073741827))\n    assert_equal(Rational(1152921511049297938, 3221225481),\n                 Rational(3, 1073741827) + Rational(1073741827, 3))\n    assert_equal(Rational(-1152921511049297920, 3221225481),\n                 Rational(3, 1073741827) - Rational(1073741827, 3))\n    assert_equal(Rational(1, 1),\n                 Rational(3, 1073741827) * Rational(1073741827, 3))\n    assert_equal(Rational(9, 1152921511049297929),\n                 Rational(3, 1073741827) / Rational(1073741827, 3))\n    assert_equal(Rational(1073741792, 1073741827),\n                 Rational(3, 1073741827) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(-1073741786, 1073741827),\n                 Rational(3, 1073741827) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(3221225367, 1152921511049297929),\n                 Rational(3, 1073741827) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(3, 1073741827) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921514270523296, 1152921470247108503),\n                 Rational(3, 1073741827) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(-1152921507828072562, 1152921470247108503),\n                 Rational(3, 1073741827) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(3, 1073741827) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(3221225367, 1152921511049297929),\n                 Rational(3, 1073741827) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741827, 3), +Rational(1073741827, 3))\n    assert_equal(Rational(-1073741827, 3), -Rational(1073741827, 3))\n    assert_equal(Rational(1073741830, 3),\n                 Rational(1073741827, 3) + Rational(1, 1))\n    assert_equal(Rational(1073741824, 3),\n                 Rational(1073741827, 3) - Rational(1, 1))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741827, 3) * Rational(1, 1))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741827, 3) / Rational(1, 1))\n    assert_equal(Rational(1073741833, 3),\n                 Rational(1073741827, 3) + Rational(2, 1))\n    assert_equal(Rational(1073741821, 3),\n                 Rational(1073741827, 3) - Rational(2, 1))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(1073741827, 3) * Rational(2, 1))\n    assert_equal(Rational(1073741827, 6),\n                 Rational(1073741827, 3) / Rational(2, 1))\n    assert_equal(Rational(1073741836, 3),\n                 Rational(1073741827, 3) + Rational(3, 1))\n    assert_equal(Rational(1073741818, 3),\n                 Rational(1073741827, 3) - Rational(3, 1))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1073741827, 3) * Rational(3, 1))\n    assert_equal(Rational(1073741827, 9),\n                 Rational(1073741827, 3) / Rational(3, 1))\n    assert_equal(Rational(4294967194, 3),\n                 Rational(1073741827, 3) + Rational(1073741789, 1))\n    assert_equal(Rational(-2147483540, 3),\n                 Rational(1073741827, 3) - Rational(1073741789, 1))\n    assert_equal(Rational(1152921470247108503, 3),\n                 Rational(1073741827, 3) * Rational(1073741789, 1))\n    assert_equal(Rational(1073741827, 3221225367),\n                 Rational(1073741827, 3) / Rational(1073741789, 1))\n    assert_equal(Rational(4294967308, 3),\n                 Rational(1073741827, 3) + Rational(1073741827, 1))\n    assert_equal(Rational(-2147483654, 3),\n                 Rational(1073741827, 3) - Rational(1073741827, 1))\n    assert_equal(Rational(1152921511049297929, 3),\n                 Rational(1073741827, 3) * Rational(1073741827, 1))\n    assert_equal(Rational(1, 3),\n                 Rational(1073741827, 3) / Rational(1073741827, 1))\n    assert_equal(Rational(357913943, 1),\n                 Rational(1073741827, 3) + Rational(2, 3))\n    assert_equal(Rational(1073741825, 3),\n                 Rational(1073741827, 3) - Rational(2, 3))\n    assert_equal(Rational(2147483654, 9),\n                 Rational(1073741827, 3) * Rational(2, 3))\n    assert_equal(Rational(1073741827, 2),\n                 Rational(1073741827, 3) / Rational(2, 3))\n    assert_equal(Rational(2147483663, 6),\n                 Rational(1073741827, 3) + Rational(3, 2))\n    assert_equal(Rational(2147483645, 6),\n                 Rational(1073741827, 3) - Rational(3, 2))\n    assert_equal(Rational(1073741827, 2),\n                 Rational(1073741827, 3) * Rational(3, 2))\n    assert_equal(Rational(2147483654, 9),\n                 Rational(1073741827, 3) / Rational(3, 2))\n    assert_equal(Rational(1152921470247108512, 3221225367),\n                 Rational(1073741827, 3) + Rational(3, 1073741789))\n    assert_equal(Rational(1152921470247108494, 3221225367),\n                 Rational(1073741827, 3) - Rational(3, 1073741789))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1073741827, 3) * Rational(3, 1073741789))\n    assert_equal(Rational(1152921470247108503, 9),\n                 Rational(1073741827, 3) / Rational(3, 1073741789))\n    assert_equal(Rational(715827872, 1),\n                 Rational(1073741827, 3) + Rational(1073741789, 3))\n    assert_equal(Rational(38, 3),\n                 Rational(1073741827, 3) - Rational(1073741789, 3))\n    assert_equal(Rational(1152921470247108503, 9),\n                 Rational(1073741827, 3) * Rational(1073741789, 3))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1073741827, 3) / Rational(1073741789, 3))\n    assert_equal(Rational(1152921511049297938, 3221225481),\n                 Rational(1073741827, 3) + Rational(3, 1073741827))\n    assert_equal(Rational(1152921511049297920, 3221225481),\n                 Rational(1073741827, 3) - Rational(3, 1073741827))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741827, 3) * Rational(3, 1073741827))\n    assert_equal(Rational(1152921511049297929, 9),\n                 Rational(1073741827, 3) / Rational(3, 1073741827))\n    assert_equal(Rational(2147483654, 3),\n                 Rational(1073741827, 3) + Rational(1073741827, 3))\n    assert_equal(Rational(0, 1),\n                 Rational(1073741827, 3) - Rational(1073741827, 3))\n    assert_equal(Rational(1152921511049297929, 9),\n                 Rational(1073741827, 3) * Rational(1073741827, 3))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741827, 3) / Rational(1073741827, 3))\n    assert_equal(Rational(1152921514270523296, 3221225481),\n                 Rational(1073741827, 3) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921507828072562, 3221225481),\n                 Rational(1073741827, 3) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741827, 3) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921511049297929, 3221225367),\n                 Rational(1073741827, 3) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921473468333984, 3221225367),\n                 Rational(1073741827, 3) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921467025883022, 3221225367),\n                 Rational(1073741827, 3) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921511049297929, 3221225367),\n                 Rational(1073741827, 3) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741827, 3) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741789, 1073741827), +Rational(1073741789, 1073741827))\n    assert_equal(Rational(-1073741789, 1073741827), -Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483616, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(1, 1))\n    assert_equal(Rational(-38, 1073741827),\n                 Rational(1073741789, 1073741827) - Rational(1, 1))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1073741789, 1073741827) * Rational(1, 1))\n    assert_equal(Rational(1073741789, 1073741827),\n                 Rational(1073741789, 1073741827) / Rational(1, 1))\n    assert_equal(Rational(3221225443, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(2, 1))\n    assert_equal(Rational(-1073741865, 1073741827),\n                 Rational(1073741789, 1073741827) - Rational(2, 1))\n    assert_equal(Rational(2147483578, 1073741827),\n                 Rational(1073741789, 1073741827) * Rational(2, 1))\n    assert_equal(Rational(1073741789, 2147483654),\n                 Rational(1073741789, 1073741827) / Rational(2, 1))\n    assert_equal(Rational(4294967270, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(3, 1))\n    assert_equal(Rational(-2147483692, 1073741827),\n                 Rational(1073741789, 1073741827) - Rational(3, 1))\n    assert_equal(Rational(3221225367, 1073741827),\n                 Rational(1073741789, 1073741827) * Rational(3, 1))\n    assert_equal(Rational(1073741789, 3221225481),\n                 Rational(1073741789, 1073741827) / Rational(3, 1))\n    assert_equal(Rational(1152921471320850292, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(1073741789, 1))\n    assert_equal(Rational(-1152921469173366714, 1073741827),\n                 Rational(1073741789, 1073741827) - Rational(1073741789, 1))\n    assert_equal(Rational(1152921429444920521, 1073741827),\n                 Rational(1073741789, 1073741827) * Rational(1073741789, 1))\n    assert_equal(Rational(1, 1073741827),\n                 Rational(1073741789, 1073741827) / Rational(1073741789, 1))\n    assert_equal(Rational(1152921512123039718, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(1073741827, 1))\n    assert_equal(Rational(-1152921509975556140, 1073741827),\n                 Rational(1073741789, 1073741827) - Rational(1073741827, 1))\n    assert_equal(Rational(1073741789, 1),\n                 Rational(1073741789, 1073741827) * Rational(1073741827, 1))\n    assert_equal(Rational(1073741789, 1152921511049297929),\n                 Rational(1073741789, 1073741827) / Rational(1073741827, 1))\n    assert_equal(Rational(5368709021, 3221225481),\n                 Rational(1073741789, 1073741827) + Rational(2, 3))\n    assert_equal(Rational(1073741713, 3221225481),\n                 Rational(1073741789, 1073741827) - Rational(2, 3))\n    assert_equal(Rational(2147483578, 3221225481),\n                 Rational(1073741789, 1073741827) * Rational(2, 3))\n    assert_equal(Rational(3221225367, 2147483654),\n                 Rational(1073741789, 1073741827) / Rational(2, 3))\n    assert_equal(Rational(5368709059, 2147483654),\n                 Rational(1073741789, 1073741827) + Rational(3, 2))\n    assert_equal(Rational(-1073741903, 2147483654),\n                 Rational(1073741789, 1073741827) - Rational(3, 2))\n    assert_equal(Rational(3221225367, 2147483654),\n                 Rational(1073741789, 1073741827) * Rational(3, 2))\n    assert_equal(Rational(2147483578, 3221225481),\n                 Rational(1073741789, 1073741827) / Rational(3, 2))\n    assert_equal(Rational(1152921432666146002, 1152921470247108503),\n                 Rational(1073741789, 1073741827) + Rational(3, 1073741789))\n    assert_equal(Rational(1152921426223695040, 1152921470247108503),\n                 Rational(1073741789, 1073741827) - Rational(3, 1073741789))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(1073741789, 1073741827) * Rational(3, 1073741789))\n    assert_equal(Rational(1152921429444920521, 3221225481),\n                 Rational(1073741789, 1073741827) / Rational(3, 1073741789))\n    assert_equal(Rational(1152921473468333870, 3221225481),\n                 Rational(1073741789, 1073741827) + Rational(1073741789, 3))\n    assert_equal(Rational(-1152921467025883136, 3221225481),\n                 Rational(1073741789, 1073741827) - Rational(1073741789, 3))\n    assert_equal(Rational(1152921429444920521, 3221225481),\n                 Rational(1073741789, 1073741827) * Rational(1073741789, 3))\n    assert_equal(Rational(3, 1073741827),\n                 Rational(1073741789, 1073741827) / Rational(1073741789, 3))\n    assert_equal(Rational(1073741792, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(3, 1073741827))\n    assert_equal(Rational(1073741786, 1073741827),\n                 Rational(1073741789, 1073741827) - Rational(3, 1073741827))\n    assert_equal(Rational(3221225367, 1152921511049297929),\n                 Rational(1073741789, 1073741827) * Rational(3, 1073741827))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741789, 1073741827) / Rational(3, 1073741827))\n    assert_equal(Rational(1152921514270523296, 3221225481),\n                 Rational(1073741789, 1073741827) + Rational(1073741827, 3))\n    assert_equal(Rational(-1152921507828072562, 3221225481),\n                 Rational(1073741789, 1073741827) - Rational(1073741827, 3))\n    assert_equal(Rational(1073741789, 3),\n                 Rational(1073741789, 1073741827) * Rational(1073741827, 3))\n    assert_equal(Rational(3221225367, 1152921511049297929),\n                 Rational(1073741789, 1073741827) / Rational(1073741827, 3))\n    assert_equal(Rational(2147483578, 1073741827),\n                 Rational(1073741789, 1073741827) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(0, 1),\n                 Rational(1073741789, 1073741827) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921429444920521, 1152921511049297929),\n                 Rational(1073741789, 1073741827) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741789, 1073741827) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(2305842940494218450, 1152921470247108503),\n                 Rational(1073741789, 1073741827) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(-81604377408, 1152921470247108503),\n                 Rational(1073741789, 1073741827) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741789, 1073741827) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921429444920521, 1152921511049297929),\n                 Rational(1073741789, 1073741827) / Rational(1073741827, 1073741789))\n    assert_equal(Rational(1073741827, 1073741789), +Rational(1073741827, 1073741789))\n    assert_equal(Rational(-1073741827, 1073741789), -Rational(1073741827, 1073741789))\n    assert_equal(Rational(2147483616, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(1, 1))\n    assert_equal(Rational(38, 1073741789),\n                 Rational(1073741827, 1073741789) - Rational(1, 1))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1073741827, 1073741789) * Rational(1, 1))\n    assert_equal(Rational(1073741827, 1073741789),\n                 Rational(1073741827, 1073741789) / Rational(1, 1))\n    assert_equal(Rational(3221225405, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(2, 1))\n    assert_equal(Rational(-1073741751, 1073741789),\n                 Rational(1073741827, 1073741789) - Rational(2, 1))\n    assert_equal(Rational(2147483654, 1073741789),\n                 Rational(1073741827, 1073741789) * Rational(2, 1))\n    assert_equal(Rational(1073741827, 2147483578),\n                 Rational(1073741827, 1073741789) / Rational(2, 1))\n    assert_equal(Rational(4294967194, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(3, 1))\n    assert_equal(Rational(-2147483540, 1073741789),\n                 Rational(1073741827, 1073741789) - Rational(3, 1))\n    assert_equal(Rational(3221225481, 1073741789),\n                 Rational(1073741827, 1073741789) * Rational(3, 1))\n    assert_equal(Rational(1073741827, 3221225367),\n                 Rational(1073741827, 1073741789) / Rational(3, 1))\n    assert_equal(Rational(1152921430518662348, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(1073741789, 1))\n    assert_equal(Rational(-1152921428371178694, 1073741789),\n                 Rational(1073741827, 1073741789) - Rational(1073741789, 1))\n    assert_equal(Rational(1073741827, 1),\n                 Rational(1073741827, 1073741789) * Rational(1073741789, 1))\n    assert_equal(Rational(1073741827, 1152921429444920521),\n                 Rational(1073741827, 1073741789) / Rational(1073741789, 1))\n    assert_equal(Rational(1152921471320850330, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(1073741827, 1))\n    assert_equal(Rational(-1152921469173366676, 1073741789),\n                 Rational(1073741827, 1073741789) - Rational(1073741827, 1))\n    assert_equal(Rational(1152921511049297929, 1073741789),\n                 Rational(1073741827, 1073741789) * Rational(1073741827, 1))\n    assert_equal(Rational(1, 1073741789),\n                 Rational(1073741827, 1073741789) / Rational(1073741827, 1))\n    assert_equal(Rational(5368709059, 3221225367),\n                 Rational(1073741827, 1073741789) + Rational(2, 3))\n    assert_equal(Rational(1073741903, 3221225367),\n                 Rational(1073741827, 1073741789) - Rational(2, 3))\n    assert_equal(Rational(2147483654, 3221225367),\n                 Rational(1073741827, 1073741789) * Rational(2, 3))\n    assert_equal(Rational(3221225481, 2147483578),\n                 Rational(1073741827, 1073741789) / Rational(2, 3))\n    assert_equal(Rational(5368709021, 2147483578),\n                 Rational(1073741827, 1073741789) + Rational(3, 2))\n    assert_equal(Rational(-1073741713, 2147483578),\n                 Rational(1073741827, 1073741789) - Rational(3, 2))\n    assert_equal(Rational(3221225481, 2147483578),\n                 Rational(1073741827, 1073741789) * Rational(3, 2))\n    assert_equal(Rational(2147483654, 3221225367),\n                 Rational(1073741827, 1073741789) / Rational(3, 2))\n    assert_equal(Rational(1073741830, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(3, 1073741789))\n    assert_equal(Rational(1073741824, 1073741789),\n                 Rational(1073741827, 1073741789) - Rational(3, 1073741789))\n    assert_equal(Rational(3221225481, 1152921429444920521),\n                 Rational(1073741827, 1073741789) * Rational(3, 1073741789))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741827, 1073741789) / Rational(3, 1073741789))\n    assert_equal(Rational(1152921432666146002, 3221225367),\n                 Rational(1073741827, 1073741789) + Rational(1073741789, 3))\n    assert_equal(Rational(-1152921426223695040, 3221225367),\n                 Rational(1073741827, 1073741789) - Rational(1073741789, 3))\n    assert_equal(Rational(1073741827, 3),\n                 Rational(1073741827, 1073741789) * Rational(1073741789, 3))\n    assert_equal(Rational(3221225481, 1152921429444920521),\n                 Rational(1073741827, 1073741789) / Rational(1073741789, 3))\n    assert_equal(Rational(1152921514270523296, 1152921470247108503),\n                 Rational(1073741827, 1073741789) + Rational(3, 1073741827))\n    assert_equal(Rational(1152921507828072562, 1152921470247108503),\n                 Rational(1073741827, 1073741789) - Rational(3, 1073741827))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(1073741827, 1073741789) * Rational(3, 1073741827))\n    assert_equal(Rational(1152921511049297929, 3221225367),\n                 Rational(1073741827, 1073741789) / Rational(3, 1073741827))\n    assert_equal(Rational(1152921473468333984, 3221225367),\n                 Rational(1073741827, 1073741789) + Rational(1073741827, 3))\n    assert_equal(Rational(-1152921467025883022, 3221225367),\n                 Rational(1073741827, 1073741789) - Rational(1073741827, 3))\n    assert_equal(Rational(1152921511049297929, 3221225367),\n                 Rational(1073741827, 1073741789) * Rational(1073741827, 3))\n    assert_equal(Rational(3, 1073741789),\n                 Rational(1073741827, 1073741789) / Rational(1073741827, 3))\n    assert_equal(Rational(2305842940494218450, 1152921470247108503),\n                 Rational(1073741827, 1073741789) + Rational(1073741789, 1073741827))\n    assert_equal(Rational(81604377408, 1152921470247108503),\n                 Rational(1073741827, 1073741789) - Rational(1073741789, 1073741827))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741827, 1073741789) * Rational(1073741789, 1073741827))\n    assert_equal(Rational(1152921511049297929, 1152921429444920521),\n                 Rational(1073741827, 1073741789) / Rational(1073741789, 1073741827))\n    assert_equal(Rational(2147483654, 1073741789),\n                 Rational(1073741827, 1073741789) + Rational(1073741827, 1073741789))\n    assert_equal(Rational(0, 1),\n                 Rational(1073741827, 1073741789) - Rational(1073741827, 1073741789))\n    assert_equal(Rational(1152921511049297929, 1152921429444920521),\n                 Rational(1073741827, 1073741789) * Rational(1073741827, 1073741789))\n    assert_equal(Rational(1, 1),\n                 Rational(1073741827, 1073741789) / Rational(1073741827, 1073741789))\n  end\n\nend\n"
  },
  {
    "path": "test/rdoc/parsers/test_parse_c.rb",
    "content": "require 'stringio'\nrequire 'tempfile'\nrequire 'test/unit'\nrequire 'rdoc/parsers/parse_c'\n\nclass RDoc::C_Parser\n  attr_accessor :classes\n\n  public :do_classes, :do_constants\nend\n\nclass TestRdocC_Parser < Test::Unit::TestCase\n\n  def setup\n    @tempfile = Tempfile.new self.class.name\n    filename = @tempfile.path\n\n    @top_level = RDoc::TopLevel.new filename\n    @fn = filename\n    @options = Options.instance\n    @stats = RDoc::Stats.new\n\n    @progress = StringIO.new\n  end\n\n  def teardown\n    @tempfile.unlink\n  end\n\n  def test_do_classes_boot_class\n    content = <<-EOF\n/* Document-class: Foo\n * this is the Foo boot class\n */\nVALUE cFoo = boot_defclass(\"Foo\", 0);\n    EOF\n\n    klass = util_get_class content, 'cFoo'\n    assert_equal \"   this is the Foo boot class\\n   \", klass.comment\n  end\n\n  def test_do_classes_class\n    content = <<-EOF\n/* Document-class: Foo\n * this is the Foo class\n */\nVALUE cFoo = rb_define_class(\"Foo\", rb_cObject);\n    EOF\n\n    klass = util_get_class content, 'cFoo'\n    assert_equal \"   this is the Foo class\\n   \", klass.comment\n  end\n\n  def test_do_classes_class_under\n    content = <<-EOF\n/* Document-class: Kernel::Foo\n * this is the Foo class under Kernel\n */\nVALUE cFoo = rb_define_class_under(rb_mKernel, \"Foo\", rb_cObject);\n    EOF\n\n    klass = util_get_class content, 'cFoo'\n    assert_equal \"   this is the Foo class under Kernel\\n   \", klass.comment\n  end\n\n  def test_do_classes_module\n    content = <<-EOF\n/* Document-module: Foo\n * this is the Foo module\n */\nVALUE mFoo = rb_define_module(\"Foo\");\n    EOF\n\n    klass = util_get_class content, 'mFoo'\n    assert_equal \"   this is the Foo module\\n   \", klass.comment\n  end\n\n  def test_do_classes_module_under\n    content = <<-EOF\n/* Document-module: Kernel::Foo\n * this is the Foo module under Kernel\n */\nVALUE mFoo = rb_define_module_under(rb_mKernel, \"Foo\");\n    EOF\n\n    klass = util_get_class content, 'mFoo'\n    assert_equal \"   this is the Foo module under Kernel\\n   \", klass.comment\n  end\n\n  def test_do_constants\n    content = <<-EOF\n#include <ruby.h>\n\nvoid Init_foo(){\n   VALUE cFoo = rb_define_class(\"Foo\", rb_cObject);\n\n   /* 300: The highest possible score in bowling */\n   rb_define_const(cFoo, \"PERFECT\", INT2FIX(300));\n\n   /* Huzzah!: What you cheer when you roll a perfect game */\n   rb_define_const(cFoo, \"CHEER\", rb_str_new2(\"Huzzah!\"));\n\n   /* TEST\\:TEST: Checking to see if escaped semicolon works */\n   rb_define_const(cFoo, \"TEST\", rb_str_new2(\"TEST:TEST\"));\n\n   /* \\\\: The file separator on MS Windows */\n   rb_define_const(cFoo, \"MSEPARATOR\", rb_str_new2(\"\\\\\"));\n\n   /* /: The file separator on Unix */\n   rb_define_const(cFoo, \"SEPARATOR\", rb_str_new2(\"/\"));\n\n   /* C:\\\\Program Files\\\\Stuff: A directory on MS Windows */\n   rb_define_const(cFoo, \"STUFF\", rb_str_new2(\"C:\\\\Program Files\\\\Stuff\"));\n\n   /* Default definition */\n   rb_define_const(cFoo, \"NOSEMI\", INT2FIX(99));\n\n   rb_define_const(cFoo, \"NOCOMMENT\", rb_str_new2(\"No comment\"));\n\n   /*\n    * Multiline comment goes here because this comment spans multiple lines.\n    * Multiline comment goes here because this comment spans multiple lines.\n    */\n   rb_define_const(cFoo, \"MULTILINE\", INT2FIX(1));\n\n   /*\n    * 1: Multiline comment goes here because this comment spans multiple lines.\n    * Multiline comment goes here because this comment spans multiple lines.\n    */\n   rb_define_const(cFoo, \"MULTILINE_VALUE\", INT2FIX(1));\n\n   /* Multiline comment goes here because this comment spans multiple lines.\n    * Multiline comment goes here because this comment spans multiple lines.\n    */\n   rb_define_const(cFoo, \"MULTILINE_NOT_EMPTY\", INT2FIX(1));\n\n}\n    EOF\n\n    parser = util_parser content\n\n    parser.do_classes\n    parser.do_constants\n\n    klass = parser.classes['cFoo']\n    assert klass\n\n    constants = klass.constants\n    assert !klass.constants.empty?\n\n    constants = constants.map { |c| [c.name, c.value, c.comment] }\n\n    assert_equal ['PERFECT', '300',\n                  \"\\n      The highest possible score in bowling   \\n   \"],\n                 constants.shift\n    assert_equal ['CHEER', 'Huzzah!',\n                  \"\\n      What you cheer when you roll a perfect game   \\n   \"],\n                 constants.shift\n    assert_equal ['TEST', 'TEST:TEST',\n                  \"\\n      Checking to see if escaped semicolon works   \\n   \"],\n                 constants.shift\n    assert_equal ['MSEPARATOR', '\\\\',\n                  \"\\n      The file separator on MS Windows   \\n   \"],\n                 constants.shift\n    assert_equal ['SEPARATOR', '/',\n                  \"\\n      The file separator on Unix   \\n   \"],\n                 constants.shift\n    assert_equal ['STUFF', 'C:\\\\Program Files\\\\Stuff',\n                  \"\\n      A directory on MS Windows   \\n   \"],\n                 constants.shift\n    assert_equal ['NOSEMI', 'INT2FIX(99)',\n                  \"\\n      Default definition   \\n   \"],\n                 constants.shift\n    assert_equal ['NOCOMMENT', 'rb_str_new2(\"No comment\")', nil],\n                 constants.shift\n\n    comment = <<-EOF.chomp\n\n     \n      Multiline comment goes here because this comment spans multiple lines.\n      Multiline comment goes here because this comment spans multiple lines.\n      \n   \n    EOF\n    assert_equal ['MULTILINE', 'INT2FIX(1)', comment], constants.shift\n    assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift\n\n    comment = <<-EOF.chomp\n\n      Multiline comment goes here because this comment spans multiple lines.\n      Multiline comment goes here because this comment spans multiple lines.\n      \n   \n    EOF\n    assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift\n\n    assert constants.empty?, constants.inspect\n  end\n\n  def test_find_class_comment_init\n    content = <<-EOF\n/*\n * a comment for class Foo\n */\nvoid\nInit_Foo(void) {\n  VALUE foo = rb_define_class(\"Foo\", rb_cObject);\n}\n    EOF\n\n    klass = util_get_class content, 'foo'\n\n    assert_equal \"  \\n   a comment for class Foo\\n   \\n\", klass.comment\n  end\n\n  def test_find_class_comment_define_class\n    content = <<-EOF\n/*\n * a comment for class Foo\n */\nVALUE foo = rb_define_class(\"Foo\", rb_cObject);\n    EOF\n\n    klass = util_get_class content, 'foo'\n\n    assert_equal \"  \\n   a comment for class Foo\\n   \", klass.comment\n  end\n\n  def test_find_class_comment_define_class\n    content = <<-EOF\n/*\n * a comment for class Foo on Init\n */\nvoid\nInit_Foo(void) {\n    /*\n     * a comment for class Foo on rb_define_class\n     */\n    VALUE foo = rb_define_class(\"Foo\", rb_cObject);\n}\n    EOF\n\n    klass = util_get_class content, 'foo'\n\n    assert_equal \"  \\n   a comment for class Foo on Init\\n   \\n\", klass.comment\n  end\n\n  def util_get_class(content, name)\n    parser = util_parser content\n    parser.do_classes\n    parser.classes[name]\n  end\n\n  def util_parser(content)\n    parser = RDoc::C_Parser.new @top_level, @fn, content, @options, @stats\n    parser.progress = @progress\n    parser\n  end\n\nend\n\n"
  },
  {
    "path": "test/readline/test_readline.rb",
    "content": "begin\n  require \"readline\"\nrescue LoadError\nend\n\nif defined?(Readline) && !/EditLine/n.match(Readline::VERSION)\n\nrequire \"test/unit\"\nrequire \"tempfile\"\n\nclass TestReadline < Test::Unit::TestCase\n  def test_readline\n    stdin = Tempfile.new(\"test_readline_stdin\")\n    stdout = Tempfile.new(\"test_readline_stdout\")\n    begin\n      stdin.write(\"hello\\n\")\n      stdin.close\n      stdout.close\n      line = replace_stdio(stdin.path, stdout.path) {\n        Readline.readline(\"> \", true)\n      }\n      assert_equal(\"hello\", line)\n      assert_equal(true, line.tainted?)\n      stdout.open\n      assert_equal(\"> \", stdout.read(2))\n      assert_equal(1, Readline::HISTORY.length)\n      assert_equal(\"hello\", Readline::HISTORY[0])\n      assert_raises(SecurityError) do\n        Thread.start {\n          $SAFE = 1\n          replace_stdio(stdin.path, stdout.path) do\n            Readline.readline(\"> \".taint)\n          end\n        }.join\n      end\n      assert_raises(SecurityError) do\n        Thread.start {\n          $SAFE = 4\n          replace_stdio(stdin.path, stdout.path) { Readline.readline(\"> \") }\n        }.join\n      end\n    ensure\n      stdin.close(true)\n      stdout.close(true)\n    end\n  end\n\n  def test_completion_append_character\n    begin\n      Readline.completion_append_character = \"x\"\n      assert_equal(\"x\", Readline.completion_append_character)\n      Readline.completion_append_character = \"xyz\"\n      assert_equal(\"x\", Readline.completion_append_character)\n      Readline.completion_append_character = nil\n      assert_equal(nil, Readline.completion_append_character)\n      Readline.completion_append_character = \"\"\n      assert_equal(nil, Readline.completion_append_character)\n    rescue NotImplementedError\n    end\n  end\n\n  private\n\n  def replace_stdio(stdin_path, stdout_path)\n    open(stdin_path, \"r\"){|stdin|\n      open(stdout_path, \"w\"){|stdout|\n        orig_stdin = STDIN.dup\n        orig_stdout = STDOUT.dup\n        STDIN.reopen(stdin)\n        STDOUT.reopen(stdout)\n        begin\n          yield\n        ensure\n          STDIN.reopen(orig_stdin)\n          STDOUT.reopen(orig_stdout)\n          orig_stdin.close\n          orig_stdout.close\n        end\n      }\n    }\n  end\nend\n\nend\n"
  },
  {
    "path": "test/rexml/test_document.rb",
    "content": "require \"rexml/document\"\nrequire \"test/unit\"\n\nclass REXML::TestDocument < Test::Unit::TestCase\n  def test_new\n    doc = REXML::Document.new(<<EOF)\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<message>Hello world!</message>\nEOF\n    assert_equal(\"Hello world!\", doc.root.children.first.value)\n  end\n\n  XML_WITH_NESTED_ENTITY = <<EOF\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE member [\n  <!ENTITY a \"&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;\">\n  <!ENTITY b \"&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;\">\n  <!ENTITY c \"&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;\">\n  <!ENTITY d \"&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;\">\n  <!ENTITY e \"&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;\">\n  <!ENTITY f \"&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;\">\n  <!ENTITY g \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\">\n]>\n<member>\n&a;\n</member>\nEOF\n\n  XML_WITH_4_ENTITY_EXPANSION = <<EOF\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE member [\n  <!ENTITY a \"a\">\n  <!ENTITY a2 \"&a; &a;\">\n]>\n<member>\n&a;\n&a2;\n&lt;\n</member>\nEOF\n\n  def test_entity_expansion_limit\n    doc = REXML::Document.new(XML_WITH_NESTED_ENTITY)\n    assert_raise(RuntimeError) do\n      doc.root.children.first.value\n    end\n    REXML::Document.entity_expansion_limit = 100\n    assert_equal(100, REXML::Document.entity_expansion_limit)\n    doc = REXML::Document.new(XML_WITH_NESTED_ENTITY)\n    assert_raise(RuntimeError) do\n      doc.root.children.first.value\n    end\n    assert_equal(101, doc.entity_expansion_count)\n\n    REXML::Document.entity_expansion_limit = 4\n    doc = REXML::Document.new(XML_WITH_4_ENTITY_EXPANSION)\n    assert_equal(\"\\na\\na a\\n<\\n\", doc.root.children.first.value)\n    REXML::Document.entity_expansion_limit = 3\n    doc = REXML::Document.new(XML_WITH_4_ENTITY_EXPANSION)\n    assert_raise(RuntimeError) do\n      doc.root.children.first.value\n    end\n  ensure\n    REXML::Document.entity_expansion_limit = 10000\n  end\nend\n"
  },
  {
    "path": "test/rinda/test_rinda.rb",
    "content": "require 'test/unit'\n\nrequire 'drb/drb'\nrequire 'drb/eq'\nrequire 'rinda/tuplespace'\n\nrequire 'singleton'\n\nmodule Rinda\n\nclass MockClock\n  include Singleton\n\n  class MyTS < Rinda::TupleSpace\n    def keeper_thread\n      nil\n    end\n  end\n  \n  def initialize\n    @now = 2\n    @reso = 1\n    @ts = MyTS.new\n    @ts.write([2, :now])\n    @inf = 2**31 - 1\n  end\n\n  def now\n    @now.to_f\n  end\n\n  def at(n)\n    n\n  end\n    \n  def _forward(n=nil)\n    now ,= @ts.take([nil, :now])\n    @now = now + n\n    n = @reso if n.nil?\n    @ts.write([@now, :now])\n  end\n\n  def forward(n)\n    while n > 0\n      _forward(@reso)\n      n -= @reso\n      Thread.pass\n    end\n  end\n\n  def rewind\n    now ,= @ts.take([nil, :now])\n    @ts.write([@inf, :now])\n    @ts.take([nil, :now])\n    @now = 2\n    @ts.write([2, :now])\n  end\n\n  def sleep(n=nil)\n    now ,= @ts.read([nil, :now])\n    @ts.read([(now + n)..@inf, :now])\n    0\n  end\nend\n\nmodule Time\n  def sleep(n)\n    @m.sleep(n)\n  end\n  module_function :sleep\n\n  def at(n)\n    n\n  end\n  module_function :at\n\n  def now\n    @m ? @m.now : 2\n  end\n  module_function :now\n\n  def rewind\n    @m.rewind\n  end\n  module_function :rewind\n\n  def forward(n)\n    @m.forward(n)\n  end\n  module_function :forward\n\n  @m = MockClock.instance\nend\n\nclass TupleSpace\n  def sleep(n)\n    Time.sleep(n)\n  end\nend\n\nmodule TupleSpaceTestModule\n  def sleep(n)\n    if Thread.current == Thread.main\n      Time.forward(n)\n    else\n      Time.sleep(n)\n    end\n  end\n\n  def thread_join(th)\n    while th.alive?\n      Kernel.sleep(0.1)\n      sleep(1)\n    end\n    th.value\n  end\n  \n  def test_00_tuple\n    tuple = Rinda::TupleEntry.new([1,2,3])\n    assert(!tuple.canceled?)\n    assert(!tuple.expired?)\n    assert(tuple.alive?)\n  end\n\n  def test_00_template\n    tmpl = Rinda::Template.new([1,2,3])\n    assert_equal(3, tmpl.size)\n    assert_equal(3, tmpl[2])\n    assert(tmpl.match([1,2,3]))\n    assert(!tmpl.match([1,nil,3]))\n\n    tmpl = Rinda::Template.new([/^rinda/i, nil, :hello])\n    assert_equal(3, tmpl.size)\n    assert(tmpl.match(['Rinda', 2, :hello]))\n    assert(!tmpl.match(['Rinda', 2, Symbol]))\n    assert(!tmpl.match([1, 2, :hello]))\n    assert(tmpl.match([/^rinda/i, 2, :hello]))\n\n    tmpl = Rinda::Template.new([Symbol])\n    assert_equal(1, tmpl.size)\n    assert(tmpl.match([:hello]))\n    assert(tmpl.match([Symbol]))\n    assert(!tmpl.match(['Symbol']))\n\n    tmpl = Rinda::Template.new({\"message\"=>String, \"name\"=>String})\n    assert_equal(2, tmpl.size)\n    assert(tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\"}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\", \"1\"=>2}))\n    assert(!tmpl.match({\"message\"=>\"Hi\", \"name\"=>\"Foo\", \"age\"=>1}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"no_name\"=>\"Foo\"}))\n\n    assert_raises(Rinda::InvalidHashTupleKey) do\n      tmpl = Rinda::Template.new({:message=>String, \"name\"=>String})\n    end\n    tmpl = Rinda::Template.new({\"name\"=>String})\n    assert_equal(1, tmpl.size)\n    assert(tmpl.match({\"name\"=>\"Foo\"}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\"}))\n    assert(!tmpl.match({\"message\"=>:symbol, \"name\"=>\"Foo\", \"1\"=>2}))\n    assert(!tmpl.match({\"message\"=>\"Hi\", \"name\"=>\"Foo\", \"age\"=>1}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"no_name\"=>\"Foo\"}))\n\n    tmpl = Rinda::Template.new({\"message\"=>String, \"name\"=>String})\n    assert_equal(2, tmpl.size)\n    assert(tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\"}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\", \"1\"=>2}))\n    assert(!tmpl.match({\"message\"=>\"Hi\", \"name\"=>\"Foo\", \"age\"=>1}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"no_name\"=>\"Foo\"}))\n\n    tmpl = Rinda::Template.new({\"message\"=>String})\n    assert_equal(1, tmpl.size)\n    assert(tmpl.match({\"message\"=>\"Hello\"}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\"}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\", \"1\"=>2}))\n    assert(!tmpl.match({\"message\"=>\"Hi\", \"name\"=>\"Foo\", \"age\"=>1}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"no_name\"=>\"Foo\"}))\n\n    tmpl = Rinda::Template.new({\"message\"=>String, \"name\"=>nil})\n    assert_equal(2, tmpl.size)\n    assert(tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\"}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"name\"=>\"Foo\", \"1\"=>2}))\n    assert(!tmpl.match({\"message\"=>\"Hi\", \"name\"=>\"Foo\", \"age\"=>1}))\n    assert(!tmpl.match({\"message\"=>\"Hello\", \"no_name\"=>\"Foo\"}))\n\n    assert_raises(Rinda::InvalidHashTupleKey) do\n      @ts.write({:message=>String, \"name\"=>String})\n    end\n\n    @ts.write([1, 2, 3])\n    assert_equal([1, 2, 3], @ts.take([1, 2, 3]))\n\n    @ts.write({'1'=>1, '2'=>2, '3'=>3})\n    assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.take({'1'=>1, '2'=>2, '3'=>3}))\n\n    entry = @ts.write(['1'=>1, '2'=>2, '3'=>3])\n    assert_raises(Rinda::RequestExpiredError) do\n      assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.read({'1'=>1}, 0))\n    end\n    entry.cancel\n  end\n\n  def test_00_DRbObject\n    ro = DRbObject.new(nil, \"druby://host:1234\")\n    tmpl = Rinda::DRbObjectTemplate.new\n    assert(tmpl === ro)\n\n    tmpl = Rinda::DRbObjectTemplate.new(\"druby://host:1234\")\n    assert(tmpl === ro)\n\n    tmpl = Rinda::DRbObjectTemplate.new(\"druby://host:12345\")\n    assert(!(tmpl === ro))\n\n    tmpl = Rinda::DRbObjectTemplate.new(/^druby:\\/\\/host:/)\n    assert(tmpl === ro)\n\n    ro = DRbObject.new_with(12345, 1234)\n    assert(!(tmpl === ro))\n\n    ro = DRbObject.new_with(\"druby://foo:12345\", 1234)\n    assert(!(tmpl === ro))\n\n    tmpl = Rinda::DRbObjectTemplate.new(/^druby:\\/\\/(foo|bar):/)\n    assert(tmpl === ro)\n\n    ro = DRbObject.new_with(\"druby://bar:12345\", 1234)\n    assert(tmpl === ro)\n\n    ro = DRbObject.new_with(\"druby://baz:12345\", 1234)\n    assert(!(tmpl === ro))\n  end\n\n  def test_inp_rdp\n    assert_raises(Rinda::RequestExpiredError) do\n      @ts.take([:empty], 0)\n    end\n\n    assert_raises(Rinda::RequestExpiredError) do\n      @ts.read([:empty], 0)\n    end\n  end\n\n  def test_ruby_talk_264062\n    th = Thread.new { @ts.take([:empty], 1) }\n    sleep(10)\n    assert_raises(Rinda::RequestExpiredError) do\n      thread_join(th)\n    end\n\n    th = Thread.new { @ts.read([:empty], 1) }\n    sleep(10)\n    assert_raises(Rinda::RequestExpiredError) do\n      thread_join(th)\n    end\n  end\n\n  def test_symbol_tuple\n    @ts.write([:symbol, :symbol])\n    @ts.write(['string', :string])\n    assert_equal([[:symbol, :symbol]], @ts.read_all([:symbol, nil]))\n    assert_equal([[:symbol, :symbol]], @ts.read_all([Symbol, nil]))\n    assert_equal([], @ts.read_all([:nil, nil]))\n  end\n\n  def test_core_01\n    5.times do |n|\n      @ts.write([:req, 2])\n    end\n\n    assert_equal([[:req, 2], [:req, 2], [:req, 2], [:req, 2], [:req, 2]],\n\t\t @ts.read_all([nil, nil]))\n\n    taker = Thread.new do\n      s = 0\n      while true\n\tbegin\n\t  tuple = @ts.take([:req, Integer], 1)\n\t  assert_equal(2, tuple[1])\n\t  s += tuple[1]\n\trescue Rinda::RequestExpiredError\n\t  break\n\tend\n      end\n      @ts.write([:ans, s])\n      s\n    end\n    \n    assert_equal(10, thread_join(taker))\n    tuple = @ts.take([:ans, nil])\n    assert_equal(10, tuple[1])\n  end\n\n  def test_core_02\n    taker = Thread.new do\n      s = 0\n      while true\n\tbegin\n\t  tuple = @ts.take([:req, Integer], 1)\n\t  assert_equal(2, tuple[1])\n\t  s += tuple[1]\n\trescue Rinda::RequestExpiredError\n\t  break\n\tend\n      end\n      @ts.write([:ans, s])\n      s\n    end\n\n    5.times do |n|\n      @ts.write([:req, 2])\n    end\n\n    assert_equal(10, thread_join(taker))\n    tuple = @ts.take([:ans, nil])\n    assert_equal(10, tuple[1])\n    assert_equal([], @ts.read_all([nil, nil]))\n  end\n  \n  def test_core_03_notify\n    notify1 = @ts.notify(nil, [:req, Integer])\n    notify2 = @ts.notify(nil, [:ans, Integer], 8)\n    notify3 = @ts.notify(nil, {\"message\"=>String, \"name\"=>String}, 8)\n\n    @ts.write({\"message\"=>\"first\", \"name\"=>\"3\"}, 3)\n    @ts.write({\"message\"=>\"second\", \"name\"=>\"1\"}, 1)\n    @ts.write({\"message\"=>\"third\", \"name\"=>\"0\"})\n    @ts.take({\"message\"=>\"third\", \"name\"=>\"0\"})\n\n    listener1 = Thread.new do\n      lv = 0\n      n = 0\n      notify1.each  do |ev, tuple|\n\tn += 1\n\tif ev == 'write'\n\t  lv = lv + 1\n\telsif ev == 'take'\n\t  lv = lv - 1\n\telse\n\t  break\n\tend\n\tassert(lv >= 0)\n\tassert_equal([:req, 2], tuple)\n      end\n      [lv, n]\n    end\n\n    listener2 = Thread.new do\n      result = nil\n      lv = 0\n      n = 0\n      notify2.each do |ev, tuple|\n\tn += 1\n\tif ev == 'write'\n\t  lv = lv + 1\n\telsif ev == 'take'\n\t  lv = lv - 1\n\telsif ev == 'close'\n\t  result = [lv, n]\n\telse\n\t  break\n\tend\n\tassert(lv >= 0)\n\tassert_equal([:ans, 10], tuple)\n      end\n      result\n    end\n\n    taker = Thread.new do\n      s = 0\n      while true\n\tbegin\n\t  tuple = @ts.take([:req, Integer], 1)\n\t  s += tuple[1]\n\trescue Rinda::RequestExpiredError\n\t  break\n\tend\n      end\n      @ts.write([:ans, s])\n      s\n    end\n\n    5.times do |n|\n      @ts.write([:req, 2])\n    end\n\n    @ts.take({\"message\"=>\"first\", \"name\"=>\"3\"})\n\n    sleep(4)\n    assert_equal(10, thread_join(taker))\n    # notify2 must not expire until this @ts.take.\n    # sleep(4) might be short enough for the timeout of notify2 (8 secs)\n    tuple = @ts.take([:ans, nil])\n    assert_equal(10, tuple[1])\n    assert_equal([], @ts.read_all([nil, nil]))\n\n    notify1.cancel\n    sleep(7) # notify2 expired (sleep(4)+sleep(7) > 8)\n\n    assert_equal([0, 11], thread_join(listener1))\n    assert_equal([0, 3], thread_join(listener2))\n\n    ary = []\n    ary.push([\"write\", {\"message\"=>\"first\", \"name\"=>\"3\"}])\n    ary.push([\"write\", {\"message\"=>\"second\", \"name\"=>\"1\"}])\n    ary.push([\"write\", {\"message\"=>\"third\", \"name\"=>\"0\"}])\n    ary.push([\"take\", {\"message\"=>\"third\", \"name\"=>\"0\"}])\n    ary.push([\"take\", {\"message\"=>\"first\", \"name\"=>\"3\"}])\n    ary.push([\"delete\", {\"message\"=>\"second\", \"name\"=>\"1\"}])\n    ary.push([\"close\"])\n\n    notify3.each do |ev|\n      assert_equal(ary.shift, ev)\n    end\n    assert_equal([], ary)\n  end\n\n  def test_cancel_01\n    entry = @ts.write([:removeme, 1])\n    assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))\n    entry.cancel\n    assert_equal([], @ts.read_all([nil, nil]))\n    \n    template = nil\n    taker = Thread.new do\n      @ts.take([:take, nil], 10) do |template|\n\tThread.new do\n\t  template.cancel\n\tend\n      end\n    end\n    \n    sleep(2)\n\n    assert_raises(Rinda::RequestCanceledError) do\n      assert_nil(thread_join(taker))\n    end\n\n    assert(template.canceled?)\n    \n    @ts.write([:take, 1])\n\n    assert_equal([[:take, 1]], @ts.read_all([nil, nil]))\n  end\n\n  def test_cancel_02\n    entry = @ts.write([:removeme, 1])\n    assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))\n    entry.cancel\n    assert_equal([], @ts.read_all([nil, nil]))\n\n    template = nil\n    reader = Thread.new do\n      @ts.read([:take, nil], 10) do |template|\n\tThread.new do\n\t  template.cancel\n\tend\n      end\n    end\n\n    sleep(2)\n\n    assert_raises(Rinda::RequestCanceledError) do\n      assert_nil(thread_join(reader))\n    end\n\n    assert(template.canceled?)\n    \n    @ts.write([:take, 1])\n\n    assert_equal([[:take, 1]], @ts.read_all([nil, nil]))\n  end\n\n  class SimpleRenewer\n    def initialize(sec, n = 1)\n      @sec = sec\n      @n = n\n    end\n    \n    def renew\n      return -1 if @n <= 0\n      @n -= 1\n      return @sec\n    end\n  end\n\n  def test_00_renewer\n    tuple = Rinda::TupleEntry.new([1,2,3], true)\n    assert(!tuple.canceled?)\n    assert(tuple.expired?)\n    assert(!tuple.alive?)\n    \n    tuple = Rinda::TupleEntry.new([1,2,3], 1)\n    assert(!tuple.canceled?)\n    assert(!tuple.expired?)\n    assert(tuple.alive?)\n    sleep(2)\n    assert(tuple.expired?)\n    assert(!tuple.alive?)\n\n    @renewer = SimpleRenewer.new(1,2)\n    tuple = Rinda::TupleEntry.new([1,2,3], @renewer)\n    assert(!tuple.canceled?)\n    assert(!tuple.expired?)\n    assert(tuple.alive?)\n    sleep(1)\n    assert(!tuple.canceled?)\n    assert(!tuple.expired?)\n    assert(tuple.alive?)\n    sleep(2)\n    assert(tuple.expired?)\n    assert(!tuple.alive?)\n  end\nend\n\nclass TupleSpaceTest < Test::Unit::TestCase\n  include TupleSpaceTestModule\n\n  def setup\n    ThreadGroup.new.add(Thread.current)\n    @ts = Rinda::TupleSpace.new(1)\n  end\nend\n\nclass TupleSpaceProxyTest < Test::Unit::TestCase\n  include TupleSpaceTestModule\n\n  def setup\n    ThreadGroup.new.add(Thread.current)\n    @ts_base = Rinda::TupleSpace.new(1)\n    @ts = Rinda::TupleSpaceProxy.new(@ts_base)\n  end\n\n  def test_remote_array_and_hash\n    @ts.write(DRbObject.new([1, 2, 3]))\n    assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))\n    @ts.write(DRbObject.new({'head' => 1, 'tail' => 2}))\n    assert_equal({'head' => 1, 'tail' => 2},\n                 @ts.take({'head' => 1, 'tail' => 2}, 0))\n  end\n\n  @server = DRb.primary_server || DRb.start_service\nend\n\nend\n\n"
  },
  {
    "path": "test/rss/rss-assertions.rb",
    "content": "require 'erb'\n\nmodule RSS\n  module Assertions\n    def assert_parse(rss, assert_method, *args)\n      __send__(\"assert_#{assert_method}\", *args) do\n        ::RSS::Parser.parse(rss)\n      end\n      __send__(\"assert_#{assert_method}\", *args) do\n        ::RSS::Parser.parse(rss, false).validate\n      end\n    end\n    \n    def assert_ns(prefix, uri)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise NSError\")\n        rescue ::RSS::NSError => e\n          assert_equal(prefix, e.prefix)\n          assert_equal(uri, e.uri)\n        end\n      end\n    end\n    \n    def assert_missing_tag(tag, parent)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise MissingTagError\")\n        rescue ::RSS::MissingTagError => e\n          assert_equal(tag, e.tag)\n          assert_equal(parent, e.parent)\n        end\n      end\n    end\n    \n    def assert_too_much_tag(tag, parent)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise TooMuchTagError\")\n        rescue ::RSS::TooMuchTagError => e\n          assert_equal(tag, e.tag)\n          assert_equal(parent, e.parent)\n        end\n      end\n    end\n    \n    def assert_missing_attribute(tag, attrname)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise MissingAttributeError\")\n        rescue ::RSS::MissingAttributeError => e\n          assert_equal(tag, e.tag)\n          assert_equal(attrname, e.attribute)\n        end\n      end\n    end\n    \n    def assert_not_expected_tag(tag, uri, parent)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise NotExpectedTagError\")\n        rescue ::RSS::NotExpectedTagError => e\n          assert_equal(tag, e.tag)\n          assert_equal(uri, e.uri)\n          assert_equal(parent, e.parent)\n        end\n      end\n    end\n    \n    def assert_not_available_value(tag, value, attribute=nil)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise NotAvailableValueError\")\n        rescue ::RSS::NotAvailableValueError => e\n          assert_equal(tag, e.tag)\n          assert_equal(value, e.value)\n          assert_equal(attribute, e.attribute)\n        end\n      end\n    end\n\n    def assert_not_set_error(name, variables)\n      _wrap_assertion do\n        begin\n          yield\n          flunk(\"Not raise NotSetError\")\n        rescue ::RSS::NotSetError => e\n          assert_equal(name, e.name)\n          assert_kind_of(Array, variables)\n          assert_equal(variables.sort, e.variables.sort)\n        end\n      end\n    end\n    \n    def assert_xml_declaration(version, encoding, standalone, rss)\n      _wrap_assertion do\n        assert_equal(version, rss.version)\n        assert_equal(encoding, rss.encoding)\n        assert_equal(standalone, rss.standalone)\n      end\n    end\n    \n    def assert_xml_stylesheet_attrs(attrs, xsl)\n      _wrap_assertion do\n        n_attrs = normalized_attrs(attrs)\n        ::RSS::XMLStyleSheet::ATTRIBUTES.each do |name|\n          assert_equal(n_attrs[name], xsl.__send__(name))\n        end\n      end\n    end\n    \n    def assert_xml_stylesheet(target, attrs, xsl)\n      _wrap_assertion do\n        if attrs.has_key?(:href)\n          if !attrs.has_key?(:type) and attrs.has_key?(:guess_type)\n            attrs[:type] = attrs[:guess_type]\n          end\n          assert_equal(\"xml-stylesheet\", target)\n          assert_xml_stylesheet_attrs(attrs, xsl)\n        else\n          assert_nil(target)\n          assert_equal(\"\", xsl.to_s)\n        end\n      end\n    end\n    \n    def assert_xml_stylesheet_pis(attrs_ary, rss=nil)\n      _wrap_assertion do\n        if rss.nil?\n          rss = ::RSS::RDF.new\n          setup_rss10(rss)\n        end\n        xss_strs = []\n        attrs_ary.each do |attrs|\n          xss = ::RSS::XMLStyleSheet.new(attrs)\n          xss_strs.push(xss.to_s)\n          rss.xml_stylesheets.push(xss)\n        end\n        pi_str = rss.to_s.gsub(/<\\?xml .*\\n/, \"\").gsub(/\\s*<[^\\?].*\\z/m, \"\")\n        assert_equal(xss_strs.join(\"\\n\"), pi_str)\n      end\n    end\n\n    def assert_xml_stylesheets(attrs, xss)\n      _wrap_assertion do\n        xss.each_with_index do |xs, i|\n          assert_xml_stylesheet_attrs(attrs[i], xs)\n        end\n      end\n    end\n\n\n    def assert_atom_person(tag_name, generator)\n      _wrap_assertion do\n        name = \"Mark Pilgrim\"\n        uri = \"http://example.org/\"\n        email = \"f8dy@example.com\"\n\n        assert_parse(generator.call(<<-EOA), :missing_tag, \"name\", tag_name)\n  <#{tag_name}/>\nEOA\n\n        assert_parse(generator.call(<<-EOA), :missing_tag, \"name\", tag_name)\n  <#{tag_name}>\n    <uri>#{uri}</uri>\n    <email>#{email}</email>\n  </#{tag_name}>\nEOA\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <#{tag_name}>\n    <name>#{name}</name>\n  </#{tag_name}>\nEOA\n\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <#{tag_name}>\n    <name>#{name}</name>\n    <uri>#{uri}</uri>\n    <email>#{email}</email>\n  </#{tag_name}>\nEOA\n\n        person = yield(feed)\n        assert_not_nil(person)\n        assert_equal(name, person.name.content)\n        assert_equal(uri, person.uri.content)\n        assert_equal(email, person.email.content)\n      end\n    end\n\n    def assert_atom_category(generator)\n      _wrap_assertion do\n        term = \"Music\"\n        scheme = \"http://xmlns.com/wordnet/1.6/\"\n        label = \"music\"\n\n        missing_args = [:missing_attribute, \"category\", \"term\"]\n        assert_parse(generator.call(<<-EOA), *missing_args)\n  <category/>\nEOA\n\n        assert_parse(generator.call(<<-EOA), *missing_args)\n  <category scheme=\"#{scheme}\" label=\"#{label}\"/>\nEOA\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <category term=\"#{term}\"/>\nEOA\n\n      feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <category term=\"#{term}\" scheme=\"#{scheme}\" label=\"#{label}\"/>\nEOA\n\n        category = yield(feed)\n        assert_not_nil(category)\n        assert_equal(term, category.term)\n        assert_equal(scheme, category.scheme)\n        assert_equal(label, category.label)\n      end\n    end\n\n    def assert_atom_link(generator)\n      _wrap_assertion do\n        href = \"http://example.org/feed.atom\"\n        rel = \"self\"\n        type = \"application/atom+xml\"\n        hreflang = \"en\"\n        title = \"Atom\"\n        length = \"1024\"\n\n        assert_parse(generator.call(<<-EOA), :missing_attribute, \"link\", \"href\")\n  <link/>\nEOA\n\n        assert_parse(generator.call(<<-EOA), :missing_attribute, \"link\", \"href\")\n  <link rel=\"#{rel}\" type=\"#{type}\" hreflang=\"#{hreflang}\"\n        title=\"#{title}\" length=\"#{length}\"/>\nEOA\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <link href=\"#{href}\"/>\nEOA\n\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <link href=\"#{href}\" rel=\"#{rel}\" type=\"#{type}\" hreflang=\"#{hreflang}\"\n        title=\"#{title}\" length=\"#{length}\"/>\nEOA\n\n        link = yield(feed)\n        assert_not_nil(link)\n        assert_equal(href, link.href)\n        assert_equal(rel, link.rel)\n        assert_equal(type, link.type)\n        assert_equal(hreflang, link.hreflang)\n        assert_equal(title, link.title)\n        assert_equal(length, link.length)\n\n\n        href = \"http://example.org/index.html.ja\"\n        parent = link.parent.tag_name\n        return if parent == \"source\"\n\n        optional_attributes = %w(hreflang=\"ja\" type=\"text/html\")\n        0.upto(optional_attributes.size) do |i|\n          combination(optional_attributes, i).each do |attributes|\n            attrs = attributes.join(\" \")\n            assert_parse(generator.call(<<-EOA), :too_much_tag, \"link\", parent)\n  <link rel=\"alternate\" #{attrs} href=\"#{href}\"/>\n  <link rel=\"alternate\" #{attrs} href=\"#{href}\"/>\nEOA\n          end\n        end\n      end\n    end\n\n    def assert_atom_generator(generator)\n      _wrap_assertion do\n        uri = \"http://www.example.com/\"\n        version = \"1.0\"\n        content = \"Example Toolkit\"\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <generator/>\nEOA\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <generator uri=\"#{uri}\" version=\"#{version}\"/>\nEOA\n\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <generator uri=\"#{uri}\" version=\"#{version}\">#{content}</generator>\nEOA\n\n        gen = yield(feed)\n        assert_not_nil(gen)\n        assert_equal(uri, gen.uri)\n        assert_equal(version, gen.version)\n        assert_equal(content, gen.content)\n      end\n    end\n\n    def assert_atom_icon(generator)\n      _wrap_assertion do\n        content = \"http://www.example.com/example.png\"\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <icon/>\nEOA\n\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <icon>#{content}</icon>\nEOA\n\n        icon = yield(feed)\n        assert_not_nil(icon)\n        assert_equal(content, icon.content)\n      end\n    end\n\n    def assert_atom_text_construct(tag_name, generator)\n      _wrap_assertion do\n        [nil, \"text\", \"html\"].each do |type|\n          attr = \"\"\n          attr = \" type=\\\"#{type}\\\"\"if type\n          assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <#{tag_name}#{attr}/>\nEOA\n        end\n\n        assert_parse(generator.call(<<-EOA), :missing_tag, \"div\", tag_name)\n  <#{tag_name} type=\"xhtml\"/>\nEOA\n\n        args = [\"x\", Atom::URI, tag_name]\n        assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)\n  <#{tag_name} type=\"xhtml\"><x/></#{tag_name}>\nEOA\n\n        invalid_value = \"invalid\"\n        args = [\"type\", invalid_value]\n        assert_parse(generator.call(<<-EOA), :not_available_value, *args)\n  <#{tag_name} type=\"#{invalid_value}\"/>\nEOA\n\n        [\n         [nil, \"A lot of effort went into making this effortless\"],\n         [\"text\", \"A lot of effort went into making this effortless\"],\n         [\"html\", \"A <em>lot</em> of effort went into making this effortless\"],\n        ].each do |type, content|\n          attr = \"\"\n          attr = \" type=\\\"#{type}\\\"\" if type\n          feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <#{tag_name}#{attr}>#{h content}</#{tag_name}>\nEOA\n\n          element = yield(feed)\n          assert_not_nil(element)\n          assert_equal(type, element.type)\n          assert_equal(content, element.content)\n        end\n\n        [false, true].each do |with_space|\n          xhtml_uri = \"http://www.w3.org/1999/xhtml\"\n          xhtml_content = \"<div xmlns=\\\"#{xhtml_uri}\\\">abc</div>\"\n          xhtml_element = RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                                {\"xmlns\" => xhtml_uri},\n                                                [\"abc\"])\n          content = xhtml_content\n          content = \"  #{content}  \" if with_space\n          feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <#{tag_name} type=\"xhtml\">#{content}</#{tag_name}>\nEOA\n\n          element = yield(feed)\n          assert_not_nil(element)\n          assert_equal(\"xhtml\", element.type)\n          assert_equal(xhtml_content, element.content)\n          assert_equal(xhtml_element, element.xhtml)\n        end\n      end\n    end\n\n    def assert_atom_date_construct(tag_name, generator)\n      _wrap_assertion do\n        args = [tag_name, \"\"]\n        assert_parse(generator.call(<<-EOR), :not_available_value, *args)\n  <#{tag_name}/>\nEOR\n\n        [\n         [\"xxx\", false],\n         [\"2007\", false],\n         [\"2007/02/09\", true],\n        ].each do |invalid_value, can_parse|\n          assert_not_available_value(tag_name, invalid_value) do\n            RSS::Parser.parse(generator.call(<<-EOR))\n  <#{tag_name}>#{invalid_value}</#{tag_name}>\nEOR\n          end\n\n          feed = RSS::Parser.parse(generator.call(<<-EOR), false)\n  <#{tag_name}>#{invalid_value}</#{tag_name}>\nEOR\n          value = yield(feed).content\n          if can_parse\n            assert_equal(Time.parse(invalid_value), value)\n          else\n            assert_nil(value)\n          end\n        end\n\n        [\n         \"2003-12-13T18:30:02Z\",\n         \"2003-12-13T18:30:02.25Z\",\n         \"2003-12-13T18:30:02+01:00\",\n         \"2003-12-13T18:30:02.25+01:00\",\n        ].each do |valid_value|\n          assert_parse(generator.call(<<-EOR), :nothing_raised)\n  <#{tag_name}>#{valid_value}</#{tag_name}>\nEOR\n\n          feed = RSS::Parser.parse(generator.call(<<-EOR))\n  <#{tag_name}>#{valid_value}</#{tag_name}>\nEOR\n          assert_equal(Time.parse(valid_value), yield(feed).content)\n        end\n      end\n    end\n\n    def assert_atom_logo(generator)\n      _wrap_assertion do\n        content = \"http://www.example.com/example.png\"\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <logo/>\nEOA\n\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <logo>#{content}</logo>\nEOA\n\n        logo = yield(feed)\n        assert_not_nil(logo)\n        assert_equal(content, logo.content)\n      end\n    end\n\n    def assert_atom_content(generator, &getter)\n      _wrap_assertion do\n        assert_atom_content_inline_text(generator, &getter)\n        assert_atom_content_inline_xhtml(generator, &getter)\n        assert_atom_content_inline_other(generator, &getter)\n        assert_atom_content_out_of_line(generator, &getter)\n      end\n    end\n\n    def assert_atom_content_inline_text(generator)\n      _wrap_assertion do\n        [nil, \"text\", \"html\"].each do |type|\n          content = \"<content\"\n          content << \" type='#{type}'\" if type\n\n          suffix = \"/>\"\n          assert_parse(generator.call(content + suffix), :nothing_raised)\n          suffix = \">xxx</content>\"\n          assert_parse(generator.call(content + suffix), :nothing_raised)\n        end\n\n        [\n         [\"text\", \"sample content\"],\n         [\"text/plain\", \"sample content\"],\n         [\"html\", \"<em>sample</em> content\"]\n        ].each do |type, content_content|\n          feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <content type=\"#{type}\">#{h content_content}</content>\nEOA\n          content = yield(feed)\n          assert_equal(type, content.type)\n          if %w(text html).include?(type)\n            assert(content.inline_text?)\n          else\n            assert(!content.inline_text?)\n          end\n          if type == \"html\"\n            assert(content.inline_html?)\n          else\n            assert(!content.inline_html?)\n          end\n          assert(!content.inline_xhtml?)\n          if type == \"text/plain\"\n            assert(content.inline_other?)\n            assert(content.inline_other_text?)\n          else\n            assert(!content.inline_other?)\n            assert(!content.inline_other_text?)\n          end\n          assert(!content.inline_other_xml?)\n          assert(!content.inline_other_base64?)\n          assert(!content.out_of_line?)\n          assert(!content.have_xml_content?)\n          assert_equal(content_content, content.content)\n        end\n      end\n    end\n\n    def assert_atom_content_inline_xhtml(generator)\n      _wrap_assertion do\n        args = [\"div\", \"content\"]\n        assert_parse(generator.call(<<-EOA), :missing_tag, *args)\n  <content type=\"xhtml\"/>\nEOA\n\n        args = [\"x\", Atom::URI, \"content\"]\n        assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)\n  <content type=\"xhtml\"><x/></content>\nEOA\n\n        xhtml_uri = \"http://www.w3.org/1999/xhtml\"\n        xhtml_content = \"<div xmlns=\\\"#{xhtml_uri}\\\">abc</div>\"\n        xhtml_element = RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                              {\"xmlns\" => xhtml_uri},\n                                              [\"abc\"])\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <content type=\"xhtml\">#{xhtml_content}</content>\nEOA\n\n        content = yield(feed)\n        assert_not_nil(content)\n        assert_equal(\"xhtml\", content.type)\n        assert(!content.inline_text?)\n        assert(!content.inline_html?)\n        assert(content.inline_xhtml?)\n        assert(!content.inline_other?)\n        assert(!content.inline_other_text?)\n        assert(!content.inline_other_xml?)\n        assert(!content.inline_other_base64?)\n        assert(!content.out_of_line?)\n        assert(content.have_xml_content?)\n        assert_equal(xhtml_content, content.content)\n        assert_equal(xhtml_element, content.xhtml)\n      end\n    end\n\n    def assert_atom_content_inline_other(generator, &getter)\n      _wrap_assertion do\n        assert_atom_content_inline_other_text(generator, &getter)\n        assert_atom_content_inline_other_xml(generator, &getter)\n      end\n    end\n\n    def assert_atom_content_inline_other_text(generator)\n      _wrap_assertion do\n        type = \"image/png\"\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <content type=\"#{type}\"/>\nEOA\n\n        png_file = File.join(File.dirname(__FILE__), \"dot.png\")\n        png = File.open(png_file, \"rb\") {|file| file.read}\n        base64_content = [png].pack(\"m\")\n\n        [false, true].each do |with_space|\n          xml_content = base64_content\n          xml_content = \"  #{base64_content}\" if with_space\n          feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <content type=\"#{type}\">#{xml_content}</content>\nEOA\n\n          content = yield(feed)\n          assert_not_nil(content)\n          assert_equal(type, content.type)\n          assert(!content.inline_text?)\n          assert(!content.inline_html?)\n          assert(!content.inline_xhtml?)\n          assert(content.inline_other?)\n          assert(!content.inline_other_text?)\n          assert(!content.inline_other_xml?)\n          assert(content.inline_other_base64?)\n          assert(!content.out_of_line?)\n          assert(!content.have_xml_content?)\n          assert_equal(png, content.content)\n\n          xml = REXML::Document.new(content.to_s).root\n          assert_rexml_element([], {\"type\" => type}, base64_content, xml)\n        end\n      end\n    end\n\n    def assert_atom_content_inline_other_xml(generator)\n      _wrap_assertion do\n        type = \"image/svg+xml\"\n\n        assert_parse(generator.call(<<-EOA), :nothing_raised)\n  <content type=\"#{type}\"/>\nEOA\n\n        svg_uri = \"http://www.w3.org/2000/svg\"\n        svg_width = \"50pt\"\n        svg_height = \"20pt\"\n        svg_version = \"1.0\"\n        text_x = \"15\"\n        text_y = \"15\"\n        text = \"text\"\n        svg_content = <<-EOS\n<svg\n   xmlns=\"#{svg_uri}\"\n   width=\"#{svg_width}\"\n   height=\"#{svg_height}\"\n   version=\"#{svg_version}\"\n><text x=\"#{text_x}\" y=\"#{text_y}\">#{text}</text\n></svg>\nEOS\n\n        text_element = RSS::XML::Element.new(\"text\", nil, svg_uri,\n                                             {\n                                               \"x\" => text_x,\n                                               \"y\" => text_y,\n                                             },\n                                             [text])\n        svg_element = RSS::XML::Element.new(\"svg\", nil, svg_uri,\n                                            {\n                                              \"xmlns\" => svg_uri,\n                                              \"width\" => svg_width,\n                                              \"height\" => svg_height,\n                                              \"version\" => svg_version,\n                                            },\n                                            [text_element])\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <content type=\"#{type}\">#{svg_content}</content>\nEOA\n\n        content = yield(feed)\n        assert_not_nil(content)\n        assert_equal(type, content.type)\n        assert(!content.inline_text?)\n        assert(!content.inline_html?)\n        assert(!content.inline_xhtml?)\n        assert(content.inline_other?)\n        assert(!content.inline_other_text?)\n        assert(content.inline_other_xml?)\n        assert(!content.inline_other_base64?)\n        assert(!content.out_of_line?)\n        assert(content.have_xml_content?)\n        assert_equal(REXML::Document.new(svg_content).to_s.chomp,\n                     REXML::Document.new(content.content).to_s.chomp)\n        assert_equal(svg_element, content.xml)\n        assert_nil(content.xhtml)\n      end\n    end\n\n    def assert_atom_content_out_of_line(generator)\n      _wrap_assertion do\n        text_type = \"text/plain\"\n        text_src = \"http://example.com/README.txt\"\n\n        missing_args = [:missing_attribute, \"content\", \"type\"]\n        # RSS Parser raises error even if this is \"should\" not \"must\".\n        assert_parse(generator.call(<<-EOA), *missing_args)\n  <content src=\"#{text_src}\"/>\nEOA\n\n        content_content = \"xxx\"\n        not_available_value_args = [:not_available_value,\n                                    \"content\", content_content]\n        assert_parse(generator.call(<<-EOA), *not_available_value_args)\n  <content type=\"#{text_type}\" src=\"#{text_src}\">#{content_content}</content>\nEOA\n\n        feed = RSS::Parser.parse(generator.call(<<-EOA))\n  <content type=\"#{text_type}\" src=\"#{text_src}\"/>\nEOA\n        content = yield(feed)\n        assert_not_nil(content)\n        assert_equal(text_type, content.type)\n        assert_equal(text_src, content.src)\n        assert(!content.inline_text?)\n        assert(!content.inline_html?)\n        assert(!content.inline_xhtml?)\n        assert(!content.inline_other?)\n        assert(!content.inline_other_text?)\n        assert(!content.inline_other_xml?)\n        assert(!content.inline_other_base64?)\n        assert(content.out_of_line?)\n        assert(!content.have_xml_content?)\n        assert_nil(content.xml)\n        assert_nil(content.xhtml)\n        assert_equal(\"\", content.content)\n      end\n    end\n\n    def assert_atom_source(generator, &getter)\n      _wrap_assertion do\n        assert_atom_source_author(generator, &getter)\n        assert_atom_source_category(generator, &getter)\n        assert_atom_source_contributor(generator, &getter)\n        assert_atom_source_generator(generator, &getter)\n        assert_atom_source_icon(generator, &getter)\n        assert_atom_source_id(generator, &getter)\n        assert_atom_source_link(generator, &getter)\n        assert_atom_source_logo(generator, &getter)\n        assert_atom_source_rights(generator, &getter)\n        assert_atom_source_subtitle(generator, &getter)\n        assert_atom_source_title(generator, &getter)\n        assert_atom_source_updated(generator, &getter)\n      end\n    end\n\n    def assert_atom_source_author(generator)\n      assert_atom_person(\"author\", generator) do |feed|\n        source = yield(feed)\n        assert_equal(1, source.authors.size)\n        source.author\n      end\n    end\n\n    def assert_atom_source_category(generator)\n      assert_atom_category(generator) do |feed|\n        source = yield(feed)\n        assert_equal(1, source.categories.size)\n        source.category\n      end\n    end\n\n    def assert_atom_source_contributor(generator)\n      assert_atom_person(\"contributor\", generator) do |feed|\n        source = yield(feed)\n        assert_equal(1, source.contributors.size)\n        source.contributor\n      end\n    end\n\n    def assert_atom_source_generator(generator)\n      assert_atom_generator(generator) do |feed|\n        yield(feed).generator\n      end\n    end\n\n    def assert_atom_source_icon(generator)\n      assert_atom_icon(generator) do |feed|\n        yield(feed).icon\n      end\n    end\n\n    def assert_atom_source_id(generator)\n      id_content = \"urn:uuid:a2fb588b-5674-4898-b420-265a734fea69\"\n      id = \"<id>#{id_content}</id>\"\n      feed = RSS::Parser.parse(generator.call(id))\n      assert_equal(id_content, yield(feed).id.content)\n    end\n\n    def assert_atom_source_link(generator)\n      assert_atom_link(generator) do |feed|\n        source = yield(feed)\n        assert_equal(1, source.links.size)\n        source.link\n      end\n    end\n\n    def assert_atom_source_logo(generator)\n      assert_atom_logo(generator) do |feed|\n        yield(feed).logo\n      end\n    end\n\n    def assert_atom_source_rights(generator)\n      assert_atom_text_construct(\"rights\", generator) do |feed|\n        yield(feed).rights\n      end\n    end\n\n    def assert_atom_source_subtitle(generator)\n      assert_atom_text_construct(\"subtitle\", generator) do |feed|\n        yield(feed).subtitle\n      end\n    end\n\n    def assert_atom_source_title(generator)\n      assert_atom_text_construct(\"title\", generator) do |feed|\n        yield(feed).title\n      end\n    end\n\n    def assert_atom_source_updated(generator)\n      assert_atom_date_construct(\"updated\", generator) do |feed|\n        yield(feed).updated\n      end\n    end\n\n    def assert_dublin_core(elems, target)\n      _wrap_assertion do\n        elems.each do |name, value|\n          assert_equal(value, target.__send__(\"dc_#{name}\"))\n        end\n      end\n    end\n    \n    def assert_multiple_dublin_core(elems, target)\n      _wrap_assertion do\n        elems.each do |name, values, plural|\n          plural ||= \"#{name}s\"\n          actual = target.__send__(\"dc_#{plural}\").collect{|x| x.value}\n          assert_equal(values, actual)\n        end\n      end\n    end\n    \n    def assert_syndication(elems, target)\n      _wrap_assertion do\n        elems.each do |name, value|\n          meth = \"sy_#{name}\"\n          value = value.to_i if meth == \"sy_updateFrequency\"\n          assert_equal(value, target.__send__(meth ))\n        end\n      end\n    end\n    \n    def assert_content(elems, target)\n      _wrap_assertion do\n        elems.each do |name, value|\n          assert_equal(value, target.__send__(\"content_#{name}\"))\n        end\n      end\n    end\n    \n    def assert_trackback(attrs, target)\n      _wrap_assertion do\n        n_attrs = normalized_attrs(attrs)\n        if n_attrs[\"ping\"]\n          assert_equal(n_attrs[\"ping\"], target.trackback_ping)\n        end\n        if n_attrs[\"abouts\"]\n          n_attrs[\"abouts\"].each_with_index do |about, i|\n            assert_equal(about, target.trackback_abouts[i].value)\n          end\n        end\n      end\n    end\n\n    def assert_taxo_topic(topics, target)\n      _wrap_assertion do\n        topics.each_with_index do |topic, i|\n          taxo_topic = target.taxo_topics[i]\n          topic.each do |name, value|\n            case name\n            when :link\n              assert_equal(value, taxo_topic.about)\n              assert_equal(value, taxo_topic.taxo_link)\n            when :topics\n              assert_equal(value, taxo_topic.taxo_topics.resources)\n            else\n              assert_equal(value, taxo_topic.__send__(\"dc_#{name}\"))\n            end\n          end\n        end\n      end\n    end\n\n\n    def assert_attributes(attrs, names, target)\n      _wrap_assertion do\n        n_attrs = normalized_attrs(attrs)\n        names.each do |info|\n          if info.is_a?(String)\n            name = info\n            type = nil\n          else\n            name, type = info\n          end\n          value = n_attrs[name]\n          if value.is_a?(Time)\n            actual = target.__send__(name)\n            assert_instance_of(Time, actual)\n            assert_equal(value.to_i, actual.to_i)\n          elsif value\n            case type\n            when :integer\n              value = value.to_i\n            when :boolean\n              value = value == \"true\" if value.is_a?(String)\n            end\n            assert_equal(value, target.__send__(name))\n          end\n        end\n      end\n    end\n\n    def assert_rexml_element(children, attrs, text, element, text_type=nil)\n      _wrap_assertion do\n        if children\n          children_info = element.elements.collect {|e| [e.namespace, e.name]}\n          assert_equal(children.collect {|uri, name| [uri, name]}.sort,\n                       children_info.sort)\n        end\n        if attrs\n          assert_equal(attrs.collect {|k, v| [k, v]}.sort,\n                       element.attributes.collect {|k, v| [k, v]}.sort)\n        end\n        case text_type\n        when :time\n          assert_not_nil(element.text)\n          assert_equal(Time.parse(text).to_s, Time.parse(element.text).to_s)\n        else\n          assert_equal(text, element.text)\n        end\n      end\n    end\n\n    def _assert_maker_atom_persons(feed_type, maker_readers, feed_readers)\n      _wrap_assertion do\n        persons = []\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n          targets.each do |target|\n            person = {\n              :name => target.name,\n              :uri => target.uri,\n              :email => target.email,\n            }\n            persons << person if person[:name]\n          end\n        end\n\n        actual_persons = chain_reader(feed, feed_readers) || []\n        actual_persons = actual_persons.collect do |person|\n          {\n            :name => person.name ? person.name.content : nil,\n            :uri => person.uri ? person.uri.content : nil,\n            :email => person.email ? person.email.content : nil,\n          }\n        end\n        assert_equal(persons, actual_persons)\n      end\n    end\n\n    def assert_maker_atom_persons(feed_type, maker_readers, feed_readers,\n                                  not_set_error_name=nil,\n                                  parent_not_set_error_name=nil,\n                                  parent_not_set_variable=nil)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        args = [feed_type, maker_readers, feed_readers]\n        if parent_not_set_error_name or parent_not_set_variable\n          assert_not_set_error(parent_not_set_error_name,\n                               parent_not_set_variable) do\n            _assert_maker_atom_persons(*args) do |maker|\n              yield maker\n            end\n          end\n        else\n          _assert_maker_atom_persons(*args) do |maker|\n            yield maker\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(name)) do\n          _assert_maker_atom_persons(feed_type, maker_readers,\n                                     feed_readers) do |maker|\n            yield maker\n            targets = chain_reader(maker, maker_readers)\n            target = targets.new_child\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(name)) do\n          _assert_maker_atom_persons(feed_type, maker_readers,\n                                     feed_readers) do |maker|\n            yield maker\n            targets = chain_reader(maker, maker_readers)\n            target = targets.new_child\n            target.uri = \"http://example.com/~me/\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(name)) do\n          _assert_maker_atom_persons(feed_type, maker_readers,\n                                     feed_readers) do |maker|\n            yield maker\n            targets = chain_reader(maker, maker_readers)\n            target = targets.new_child\n            target.email = \"me@example.com\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(name)) do\n          _assert_maker_atom_persons(feed_type, maker_readers,\n                                     feed_readers) do |maker|\n            yield maker\n            targets = chain_reader(maker, maker_readers)\n            target = targets.new_child\n            target.uri = \"http://example.com/~me/\"\n            target.email = \"me@example.com\"\n          end\n        end\n\n        _assert_maker_atom_persons(feed_type, maker_readers,\n                                   feed_readers) do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n          target = targets.new_child\n          target.name = \"me\"\n        end\n\n        _assert_maker_atom_persons(feed_type, maker_readers,\n                                   feed_readers) do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n          target = targets.new_child\n          target.name = \"me\"\n          target.uri = \"http://example.com/~me/\"\n        end\n\n        _assert_maker_atom_persons(feed_type, maker_readers,\n                                   feed_readers) do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n          target = targets.new_child\n          target.name = \"me\"\n          target.email = \"me@example.com\"\n        end\n\n        _assert_maker_atom_persons(feed_type, maker_readers,\n                                   feed_readers) do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n          target = targets.new_child\n          target.name = \"me\"\n          target.uri = \"http://example.com/~me/\"\n          target.email = \"me@example.com\"\n        end\n\n        _assert_maker_atom_persons(feed_type, maker_readers,\n                                   feed_readers) do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n\n          target = targets.new_child\n          target.name = \"me\"\n          target.uri = \"http://example.com/~me/\"\n          target.email = \"me@example.com\"\n\n          target = targets.new_child\n          target.name = \"you\"\n          target.uri = \"http://example.com/~you/\"\n          target.email = \"you@example.com\"\n        end\n\n        assert_not_set_error(not_set_error_name, %w(name)) do\n          _assert_maker_atom_persons(feed_type, maker_readers,\n                                     feed_readers) do |maker|\n            yield maker\n            targets = chain_reader(maker, maker_readers)\n\n            target = targets.new_child\n            target.name = \"me\"\n            target.uri = \"http://example.com/~me/\"\n            target.email = \"me@example.com\"\n\n            target = targets.new_child\n          end\n        end\n      end\n    end\n\n    def _assert_maker_atom_text_construct(feed_type, maker_readers,\n                                          feed_readers, &block)\n      maker_extractor = Proc.new do |target|\n        text = {\n          :type => target.type,\n          :content => target.content,\n          :xml_content => target.xml_content,\n        }\n        if text[:type] == \"xhtml\"\n          if text[:xml_content]\n            xml_content = text[:xml_content]\n            xhtml_uri = \"http://www.w3.org/1999/xhtml\"\n            unless xml_content.is_a?(RSS::XML::Element) and\n                [\"div\", xhtml_uri] == [xml_content.name, xml_content.uri]\n              children = xml_content\n              children = [children] unless children.is_a?(Array)\n              xml_content = RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                                  {\"xmlns\" => xhtml_uri},\n                                                  children)\n              text[:xml_content] = xml_content\n            end\n            text\n          else\n            nil\n          end\n        else\n          text[:content] ? text : nil\n        end\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :type => target.type,\n          :content => target.content,\n          :xml_content => target.xhtml,\n        }\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n    end\n\n    def assert_maker_atom_text_construct(feed_type, maker_readers, feed_readers,\n                                         parent_not_set_error_name=nil,\n                                         parent_not_set_variable=nil,\n                                         not_set_error_name=nil)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        args = [feed_type, maker_readers, feed_readers]\n        if parent_not_set_error_name or parent_not_set_variable\n          assert_not_set_error(parent_not_set_error_name,\n                               parent_not_set_variable) do\n            _assert_maker_atom_text_construct(*args) do |maker|\n              yield maker\n            end\n          end\n        else\n          _assert_maker_atom_text_construct(*args) do |maker|\n            yield maker\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(content)) do\n          _assert_maker_atom_text_construct(*args) do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers) {|x| x}\n            target.type = \"text\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(content)) do\n          _assert_maker_atom_text_construct(*args) do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers) {|x| x}\n            target.type = \"html\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(xml_content)) do\n          _assert_maker_atom_text_construct(*args) do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers) {|x| x}\n            target.type = \"xhtml\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(xml_content)) do\n          _assert_maker_atom_text_construct(*args) do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers) {|x| x}\n            target.type = \"xhtml\"\n            target.content = \"Content\"\n          end\n        end\n\n        _assert_maker_atom_text_construct(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers) {|x| x}\n          target.type = \"text\"\n          target.content = \"Content\"\n        end\n\n        _assert_maker_atom_text_construct(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers) {|x| x}\n          target.type = \"html\"\n          target.content = \"<em>Content</em>\"\n        end\n\n        _assert_maker_atom_text_construct(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers) {|x| x}\n          target.type = \"xhtml\"\n          target.xml_content = \"text only\"\n        end\n\n        _assert_maker_atom_text_construct(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers) {|x| x}\n          target.type = \"xhtml\"\n          target.xml_content = RSS::XML::Element.new(\"unknown\")\n        end\n      end\n    end\n\n    def _assert_maker_atom_date_construct(feed_type, maker_readers,\n                                          feed_readers, &block)\n      maker_extractor = Proc.new do |target|\n        date = {\n          :content => target,\n        }\n        date[:content] ? date : nil\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :content => target.content,\n        }\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n    end\n\n    def assert_maker_atom_date_construct(feed_type, maker_readers, feed_readers,\n                                         parent_not_set_error_name=nil,\n                                         parent_not_set_variable=nil)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        if parent_not_set_error_name or parent_not_set_variable\n          assert_not_set_error(parent_not_set_error_name,\n                               parent_not_set_variable) do\n            _assert_maker_atom_date_construct(*args) do |maker|\n              yield maker\n            end\n          end\n        else\n          _assert_maker_atom_date_construct(*args) do |maker|\n            yield maker\n          end\n        end\n\n        maker_readers = maker_readers.dup\n        writer = \"#{maker_readers.pop}=\"\n        _assert_maker_atom_date_construct(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.__send__(writer, Time.now)\n        end\n      end\n    end\n\n    def _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                   maker_extractor, feed_extractor)\n      _wrap_assertion do\n        element = nil\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers) {|x| x}\n          element = maker_extractor.call(target)\n        end\n\n        target = chain_reader(feed, feed_readers)\n        if target\n          actual_element = feed_extractor.call(target)\n        else\n          actual_element = nil\n        end\n        assert_equal(element, actual_element)\n      end\n    end\n\n    def _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,\n                                    maker_extractor, feed_extractor,\n                                    invalid_feed_checker=nil)\n      _wrap_assertion do\n        elements = []\n        invalid_feed = false\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          targets = chain_reader(maker, maker_readers)\n          targets.each do |target|\n            element = maker_extractor.call(target)\n            elements << element if element\n          end\n          if invalid_feed_checker\n            invalid_feed = invalid_feed_checker.call(targets)\n          end\n        end\n\n        if invalid_feed\n          assert_nil(feed)\n        else\n          actual_elements = chain_reader(feed, feed_readers) || []\n          actual_elements = actual_elements.collect do |target|\n            feed_extractor.call(target)\n          end\n          assert_equal(elements, actual_elements)\n        end\n      end\n    end\n\n    def assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                  setup_target, optional_variables,\n                                  required_variable, assert_method_name,\n                                  not_set_error_name=nil,\n                                  *additional_args)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        0.upto(optional_variables.size) do |i|\n          combination(optional_variables, i).each do |names|\n            have = {}\n            names.each do |name|\n              have[name.intern] = true\n            end\n            have_required_variable_too =\n              have.merge({required_variable.intern => true})\n\n            assert_not_set_error(not_set_error_name, [required_variable]) do\n              __send__(assert_method_name, feed_type, maker_readers,\n                       feed_readers, *additional_args) do |maker|\n                yield maker\n                target = chain_reader(maker, maker_readers) {|x| x}\n                setup_target.call(target, have)\n              end\n            end\n\n            __send__(assert_method_name, feed_type, maker_readers, feed_readers,\n                     *additional_args) do |maker|\n              yield maker\n              target = chain_reader(maker, maker_readers) {|x| x}\n              setup_target.call(target, have_required_variable_too)\n            end\n          end\n        end\n      end\n    end\n\n    def assert_maker_atom_elements(feed_type, maker_readers, feed_readers,\n                                   setup_target, optional_variables,\n                                   required_variable, assert_method_name,\n                                   not_set_error_name=nil,\n                                   *additional_args)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        0.upto(optional_variables.size) do |i|\n          combination(optional_variables, i).each do |names|\n            have = {}\n            names.each do |name|\n              have[name.intern] = true\n            end\n            have_required_variable_too =\n              have.merge({required_variable.intern => true})\n\n            assert_not_set_error(not_set_error_name, [required_variable]) do\n              __send__(assert_method_name, feed_type, maker_readers,\n                       feed_readers, *additional_args) do |maker|\n                yield maker\n                targets = chain_reader(maker, maker_readers)\n                setup_target.call(targets, have)\n              end\n            end\n\n            __send__(assert_method_name, feed_type, maker_readers, feed_readers,\n                     *additional_args) do |maker|\n              yield maker\n              targets = chain_reader(maker, maker_readers)\n              setup_target.call(targets, have_required_variable_too)\n            end\n\n            __send__(assert_method_name, feed_type, maker_readers, feed_readers,\n                     *additional_args) do |maker|\n              yield maker\n              targets = chain_reader(maker, maker_readers)\n              setup_target.call(targets, have_required_variable_too)\n              setup_target.call(targets, have_required_variable_too)\n            end\n\n            assert_not_set_error(not_set_error_name, [required_variable]) do\n            __send__(assert_method_name, feed_type, maker_readers, feed_readers,\n                     *additional_args) do |maker|\n                yield maker\n                targets = chain_reader(maker, maker_readers)\n                setup_target.call(targets, have_required_variable_too)\n                setup_target.call(targets, have)\n              end\n            end\n          end\n        end\n      end\n    end\n\n    def _assert_maker_atom_categories(feed_type, maker_readers,\n                                      feed_readers, &block)\n      maker_extractor = Proc.new do |target|\n        category = {\n          :term => target.term,\n          :scheme => target.scheme,\n          :label => target.label,\n        }\n        category[:term] ? category : nil\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :term => target.term,\n          :scheme => target.scheme,\n          :label => target.label,\n        }\n      end\n      _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,\n                                  maker_extractor, feed_extractor, &block)\n    end\n\n    def assert_maker_atom_categories(feed_type, maker_readers, feed_readers,\n                                     not_set_error_name=nil, &block)\n      _wrap_assertion do\n        _assert_maker_atom_categories(feed_type, maker_readers,\n                                      feed_readers) do |maker|\n          yield maker\n        end\n\n        setup_target = Proc.new do |targets, have|\n          target = targets.new_child\n          target.term = \"music\" if have[:term]\n          target.scheme = \"http://example.com/category/music\" if have[:scheme]\n          target.label = \"Music\" if have[:label]\n        end\n\n        optional_variables = %w(scheme label)\n\n        assert_maker_atom_elements(feed_type, maker_readers, feed_readers,\n                                   setup_target, optional_variables,\n                                   \"term\", :_assert_maker_atom_categories,\n                                   not_set_error_name, &block)\n      end\n    end\n\n    def _assert_maker_atom_generator(feed_type, maker_readers,\n                                     feed_readers, &block)\n      maker_extractor = Proc.new do |target|\n        generator = {\n          :uri => target.uri,\n          :version => target.version,\n          :content => target.content,\n        }\n        generator[:content] ? generator : nil\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :uri => target.uri,\n          :version => target.version,\n          :content => target.content,\n        }\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n     end\n\n    def assert_maker_atom_generator(feed_type, maker_readers, feed_readers,\n                                    not_set_error_name=nil, &block)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        _assert_maker_atom_generator(feed_type, maker_readers,\n                                     feed_readers) do |maker|\n          yield maker\n        end\n\n        setup_target = Proc.new do |target, have|\n          target.content = \"RSS Maker\" if have[:content]\n          target.uri = \"http://example.com/rss/maker\" if have[:uri]\n          target.version = \"0.0.1\" if have[:version]\n        end\n\n        optional_variables = %w(uri version)\n\n        assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                  setup_target, optional_variables,\n                                  \"content\", :_assert_maker_atom_generator,\n                                  not_set_error_name, &block)\n      end\n    end\n\n    def _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,\n                                accessor_base, &block)\n      maker_extractor = Proc.new do |target|\n        icon = {\n          :content => target.__send__(accessor_base),\n        }\n        icon[:content] ? icon : nil\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :content => target.content,\n        }\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n    end\n\n    def assert_maker_atom_icon(feed_type, maker_readers, feed_readers,\n                               accessor_base=nil, not_set_error_name=nil)\n      _wrap_assertion do\n        accessor_base ||= \"url\"\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,\n                                accessor_base) do |maker|\n          yield maker\n        end\n\n        _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,\n                                accessor_base) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.__send__(\"#{accessor_base}=\", \"http://example.com/icon.png\")\n        end\n      end\n    end\n\n    def _assert_maker_atom_links(feed_type, maker_readers, feed_readers,\n                                 allow_duplication=false, &block)\n      maker_extractor = Proc.new do |target|\n        link = {\n          :href => target.href,\n          :rel => target.rel,\n          :type => target.type,\n          :hreflang => target.hreflang,\n          :title => target.title,\n          :length => target.length,\n        }\n        link[:href] ? link : nil\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :href => target.href,\n          :rel => target.rel,\n          :type => target.type,\n          :hreflang => target.hreflang,\n          :title => target.title,\n          :length => target.length,\n        }\n      end\n      invalid_feed_checker = Proc.new do |targets|\n        infos = {}\n        invalid = false\n        targets.each do |target|\n          key = [target.hreflang, target.type]\n          if infos.has_key?(key)\n            invalid = true\n            break\n          end\n          infos[key] = true if target.rel.nil? or target.rel == \"alternate\"\n        end\n        invalid\n      end\n      invalid_feed_checker = nil if allow_duplication\n      _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,\n                                  maker_extractor, feed_extractor,\n                                  invalid_feed_checker,\n                                  &block)\n    end\n\n    def assert_maker_atom_links(feed_type, maker_readers, feed_readers,\n                                not_set_error_name=nil, allow_duplication=false,\n                                &block)\n      _wrap_assertion do\n        _assert_maker_atom_links(feed_type, maker_readers,\n                                 feed_readers) do |maker|\n          yield maker\n        end\n\n        langs = %(ja en fr zh po)\n        setup_target = Proc.new do |targets, have|\n          target = targets.new_child\n          lang = langs[targets.size % langs.size]\n          target.href = \"http://example.com/index.html.#{lang}\" if have[:href]\n          target.rel = \"alternate\" if have[:rel]\n          target.type = \"text/xhtml\" if have[:type]\n          target.hreflang = lang if have[:hreflang]\n          target.title = \"FrontPage(#{lang})\" if have[:title]\n          target.length = 1024 if have[:length]\n        end\n\n        optional_variables = %w(rel type hreflang title length)\n\n        assert_maker_atom_elements(feed_type, maker_readers, feed_readers,\n                                   setup_target, optional_variables,\n                                   \"href\", :_assert_maker_atom_links,\n                                   not_set_error_name, allow_duplication,\n                                   &block)\n      end\n    end\n\n    def _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,\n                                accessor_base, &block)\n      maker_extractor = Proc.new do |target|\n        logo = {\n          :uri => target.__send__(accessor_base),\n        }\n        logo[:uri] ? logo : nil\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :uri => target.content,\n        }\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n    end\n\n    def assert_maker_atom_logo(feed_type, maker_readers, feed_readers,\n                               accessor_base=nil, not_set_error_name=nil)\n      _wrap_assertion do\n        accessor_base ||= \"uri\"\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,\n                                accessor_base) do |maker|\n          yield maker\n        end\n\n        _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,\n                                accessor_base) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.__send__(\"#{accessor_base}=\", \"http://example.com/logo.png\")\n        end\n      end\n    end\n\n    def _assert_maker_atom_id(feed_type, maker_readers, feed_readers, &block)\n      maker_extractor = Proc.new do |target|\n        id = {\n          :uri => target.id,\n        }\n        id[:uri] ? id : nil\n      end\n      feed_extractor = Proc.new do |target|\n        if target.id\n          {\n            :uri => target.id.content,\n          }\n        else\n          nil\n        end\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n    end\n\n    def assert_maker_atom_id(feed_type, maker_readers, feed_readers,\n                             not_set_error_name=nil)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n\n        args = [feed_type, maker_readers, feed_readers]\n        _assert_maker_atom_id(*args) do |maker|\n          yield maker\n        end\n\n        _assert_maker_atom_id(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.id = \"http://example.com/id/1\"\n        end\n      end\n    end\n\n    def _assert_maker_atom_content(feed_type, maker_readers,\n                                   feed_readers, &block)\n      maker_extractor = Proc.new do |target|\n        content = {\n          :type => target.type,\n          :src => target.src,\n          :content => target.content,\n          :xml => target.xml,\n          :inline_text => target.inline_text?,\n          :inline_html => target.inline_html?,\n          :inline_xhtml => target.inline_xhtml?,\n          :inline_other => target.inline_other?,\n          :inline_other_text => target.inline_other_text?,\n          :inline_other_xml => target.inline_other_xml?,\n          :inline_other_base64 => target.inline_other_base64?,\n          :out_of_line => target.out_of_line?,\n        }\n        content[:src] = nil if content[:src] and content[:content]\n        if content[:type] or content[:content]\n          content\n        else\n          nil\n        end\n      end\n      feed_extractor = Proc.new do |target|\n        {\n          :type => target.type,\n          :src => target.src,\n          :content => target.content,\n          :xml => target.xml,\n          :inline_text => target.inline_text?,\n          :inline_html => target.inline_html?,\n          :inline_xhtml => target.inline_xhtml?,\n          :inline_other => target.inline_other?,\n          :inline_other_text => target.inline_other_text?,\n          :inline_other_xml => target.inline_other_xml?,\n          :inline_other_base64 => target.inline_other_base64?,\n          :out_of_line => target.out_of_line?,\n        }\n      end\n      _assert_maker_atom_element(feed_type, maker_readers, feed_readers,\n                                 maker_extractor, feed_extractor,\n                                 &block)\n    end\n\n    def assert_maker_atom_content(feed_type, maker_readers, feed_readers,\n                                  not_set_error_name=nil, &block)\n      _wrap_assertion do\n        not_set_error_name ||= \"maker.#{maker_readers.join('.')}\"\n        args = [feed_type, maker_readers, feed_readers, not_set_error_name]\n        assert_maker_atom_content_inline_text(*args, &block)\n        assert_maker_atom_content_inline_xhtml(*args, &block)\n        assert_maker_atom_content_inline_other(*args, &block)\n        assert_maker_atom_content_out_of_line(*args, &block)\n      end\n    end\n\n    def assert_maker_atom_content_inline_text(feed_type, maker_readers,\n                                              feed_readers, not_set_error_name)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n        end\n\n        assert_not_set_error(not_set_error_name, %w(content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"text\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"html\"\n          end\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.content = \"\"\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"text\"\n          target.content = \"example content\"\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"html\"\n          target.content = \"<em>text</em>\"\n        end\n      end\n    end\n\n    def assert_maker_atom_content_inline_xhtml(feed_type, maker_readers,\n                                               feed_readers, not_set_error_name)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        assert_not_set_error(not_set_error_name, %w(xml_content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"xhtml\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(xml_content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"xhtml\"\n            target.content = \"dummy\"\n          end\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"xhtml\"\n          target.xml_content = \"text\"\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"xhtml\"\n          target.xml = \"text\"\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"xhtml\"\n          target.xml_content =\n            RSS::XML::Element.new(\"em\", nil, nil, {}, [\"text\"])\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"xhtml\"\n          target.xml = RSS::XML::Element.new(\"em\", nil, nil, {}, [\"text\"])\n        end\n\n\n        xhtml_uri = \"http://www.w3.org/1999/xhtml\"\n        em = RSS::XML::Element.new(\"em\", nil, nil, {}, [\"text\"])\n        em_with_xhtml_uri =\n          RSS::XML::Element.new(\"em\", nil, xhtml_uri, {}, [\"text\"])\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"xhtml\"\n          target.xml = em\n        end\n        assert_equal(RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                           {\"xmlns\" => xhtml_uri},\n                                           [em_with_xhtml_uri]),\n                     chain_reader(feed, feed_readers).xml)\n\n        div = RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                    {\"xmlns\" => xhtml_uri,\n                                     \"class\" => \"sample\"},\n                                    [\"text\"])\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"xhtml\"\n          target.xml = div\n        end\n        assert_equal(div, chain_reader(feed, feed_readers).xml)\n      end\n    end\n\n    def assert_maker_atom_content_inline_other(*args, &block)\n      _wrap_assertion do\n        assert_maker_atom_content_inline_other_xml(*args, &block)\n        assert_maker_atom_content_inline_other_text(*args, &block)\n        assert_maker_atom_content_inline_other_base64(*args, &block)\n      end\n    end\n\n    def assert_maker_atom_content_inline_other_xml(feed_type, maker_readers,\n                                                   feed_readers,\n                                                   not_set_error_name)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        assert_not_set_error(not_set_error_name, %w(xml_content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"application/xml\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(xml_content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"svg/image+xml\"\n          end\n        end\n\n        svg_uri = \"http://www.w3.org/2000/svg\"\n        rect = RSS::XML::Element.new(\"rect\", nil, svg_uri,\n                                     {\"x\" => \"0.5cm\",\n                                      \"y\" => \"0.5cm\",\n                                      \"width\" => \"2cm\",\n                                      \"height\" => \"1cm\"})\n        svg = RSS::XML::Element.new(\"svg\", nil, svg_uri,\n                                    {\"xmlns\" => svg_uri,\n                                     \"version\" => \"1.1\",\n                                     \"width\" => \"5cm\",\n                                     \"height\" => \"4cm\"},\n                                    [rect])\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/svg+xml\"\n          target.xml = svg\n        end\n\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/svg+xml\"\n          target.xml = svg\n        end\n        assert_equal(svg, chain_reader(feed, feed_readers).xml)\n      end\n    end\n\n    def assert_maker_atom_content_inline_other_text(feed_type, maker_readers,\n                                                    feed_readers,\n                                                    not_set_error_name)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        assert_not_set_error(not_set_error_name, %w(content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"text/plain\"\n          end\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"text/plain\"\n          target.content = \"text\"\n        end\n      end\n    end\n\n    def assert_maker_atom_content_inline_other_base64(feed_type, maker_readers,\n                                                      feed_readers,\n                                                      not_set_error_name)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        content = \"\\211PNG\\r\\n\\032\\n\"\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/png\"\n          target.content = content\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/png\"\n          target.src = \"http://example.com/logo.png\"\n          target.content = content\n        end\n\n        feed = RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/png\"\n          target.src = \"http://example.com/logo.png\"\n          target.content = content\n        end\n        target = chain_reader(feed, feed_readers)\n        assert_nil(target.src)\n        assert_equal(content, target.content)\n      end\n    end\n\n    def assert_maker_atom_content_out_of_line(feed_type, maker_readers,\n                                              feed_readers, not_set_error_name)\n      _wrap_assertion do\n        args = [feed_type, maker_readers, feed_readers]\n        assert_not_set_error(not_set_error_name, %w(content)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.type = \"image/png\"\n          end\n        end\n\n        assert_not_set_error(not_set_error_name, %w(type)) do\n          RSS::Maker.make(\"atom:#{feed_type}\") do |maker|\n            yield maker\n            target = chain_reader(maker, maker_readers)\n            target.src = \"http://example.com/logo.png\"\n          end\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/png\"\n          target.src = \"http://example.com/logo.png\"\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"image/png\"\n          target.content = \"\\211PNG\\r\\n\\032\\n\"\n        end\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"application/xml\"\n          target.src = \"http://example.com/sample.xml\"\n        end\n\n\n        _assert_maker_atom_content(*args) do |maker|\n          yield maker\n          target = chain_reader(maker, maker_readers)\n          target.type = \"text/plain\"\n          target.src = \"http://example.com/README.txt\"\n        end\n      end\n    end\n\n    def assert_slash_elements(expected, target)\n      assert_equal(expected,\n                   {\n                     \"section\" => target.slash_section,\n                     \"department\" => target.slash_department,\n                     \"comments\" => target.slash_comments,\n                     \"hit_parades\" => target.slash_hit_parades,\n                   })\n      assert_equal(expected[\"hit_parades\"].join(\",\"),\n                   target.slash_hit_parade)\n    end\n\n    def chain_reader(target, readers, &block)\n      readers.inject(target) do |result, reader|\n        return nil if result.nil?\n        result.__send__(reader, &block)\n      end\n    end\n\n    def normalized_attrs(attrs)\n      n_attrs = {}\n      attrs.each do |name, value|\n        n_attrs[name.to_s] = value\n      end\n      n_attrs\n    end\n\n    def combination(elements, n)\n      if n <= 0 or elements.size < n\n        []\n      elsif n == 1\n        elements.collect {|element| [element]}\n      else\n        first, *rest = elements\n        combination(rest, n - 1).collect do |sub_elements|\n          [first, *sub_elements]\n        end + combination(rest, n)\n      end\n    end\n\n    def tag(name, content=nil, attributes={})\n      attributes = attributes.collect do |key, value|\n        \"#{ERB::Util.h(key)}=\\\"#{ERB::Util.h(value)}\\\"\"\n      end.join(\" \")\n      begin_tag = \"<#{name}\"\n      begin_tag << \" #{attributes}\" unless attributes.empty?\n      if content\n        \"#{begin_tag}>#{content}</#{name}>\\n\"\n      else\n        \"#{begin_tag}/>\\n\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/rss-testcase.rb",
    "content": "require \"erb\"\n\nrequire \"test/unit\"\nrequire 'rss-assertions'\n\nrequire \"rss\"\n\nmodule RSS\n  class TestCase < Test::Unit::TestCase\n    include ERB::Util\n\n    include RSS\n    include Assertions\n\n    XMLDECL_VERSION = \"1.0\"\n    XMLDECL_ENCODING = \"UTF-8\"\n    XMLDECL_STANDALONE = \"no\"\n\n    RDF_ABOUT = \"http://www.xml.com/xml/news.rss\"\n    RDF_RESOURCE = \"http://xml.com/universal/images/xml_tiny.gif\"\n    TITLE_VALUE = \"XML.com\"\n    LINK_VALUE = \"http://xml.com/pub\"\n    URL_VALUE = \"http://xml.com/universal/images/xml_tiny.gif\"\n    NAME_VALUE = \"hogehoge\"\n    LANGUAGE_VALUE = \"ja\"\n    DESCRIPTION_VALUE = \"\n    XML.com features a rich mix of information and services\n    for the XML community.\n    \"\n    RESOURCES = [\n      \"http://xml.com/pub/2000/08/09/xslt/xslt.html\",\n      \"http://xml.com/pub/2000/08/09/rdfdb/index.html\",\n    ]\n\n    CLOUD_DOMAIN = \"data.ourfavoritesongs.com\"\n    CLOUD_PORT = \"80\"\n    CLOUD_PATH = \"/RPC2\"\n    CLOUD_REGISTER_PROCEDURE = \"ourFavoriteSongs.rssPleaseNotify\"\n    CLOUD_PROTOCOL = \"xml-rpc\"\n    \n    ENCLOSURE_URL = \"http://www.scripting.com/mp3s/weatherReportSuite.mp3\"\n    ENCLOSURE_LENGTH = \"12216320\"\n    ENCLOSURE_TYPE = \"audio/mpeg\"\n    \n    CATEGORY_DOMAIN = \"http://www.superopendirectory.com/\"\n\n    FEED_TITLE = \"dive into mark\"\n    FEED_UPDATED = \"2003-12-13T18:30:02Z\"\n    FEED_AUTHOR_NAME = \"John Doe\"\n    FEED_ID = \"urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6\"\n\n    ENTRY_TITLE = \"Atom-Powered Robots Run Amok\"\n    ENTRY_LINK = \"http://example.org/2003/12/13/atom03\"\n    ENTRY_ID = \"urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a\"\n    ENTRY_UPDATED = \"2003-12-13T18:30:02Z\"\n    ENTRY_SUMMARY = \"Some text.\"\n\n    t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n    class << t\n      alias_method(:to_s, :iso8601)\n    end\n\n    DC_ELEMENTS = {\n      :title => \"hoge\",\n      :description =>\n        \" XML is placing increasingly heavy loads on\n          the existing technical infrastructure of the Internet.\",\n      :creator => \"Rael Dornfest (mailto:rael@oreilly.com)\",\n      :subject => \"XML\",\n      :publisher => \"The O'Reilly Network\",\n      :contributor => \"hogehoge\",\n      :type => \"fugafuga\",\n      :format => \"hohoho\",\n      :identifier => \"fufufu\",\n      :source => \"barbar\",\n      :language => \"ja\",\n      :relation => \"cococo\",\n      :rights => \"Copyright (c) 2000 O'Reilly &amp; Associates, Inc.\",\n      :date => t,\n    }\n\n    DC_NODES = DC_ELEMENTS.collect do |name, value|\n      \"<#{DC_PREFIX}:#{name}>#{value}</#{DC_PREFIX}:#{name}>\"\n    end.join(\"\\n\")\n\n    def default_test\n      # This class isn't tested\n    end\n\n    private\n    def make_xmldecl(v=XMLDECL_VERSION, e=XMLDECL_ENCODING, s=XMLDECL_STANDALONE)\n      rv = \"<?xml version='#{v}'\"\n      rv << \" encoding='#{e}'\" if e\n      rv << \" standalone='#{s}'\" if s\n      rv << \"?>\"\n      rv\n    end\n\n    def make_RDF(content=nil, xmlns=[])\n      <<-EORSS\n#{make_xmldecl}\n<rdf:RDF xmlns=\"#{URI}\" xmlns:rdf=\"#{RDF::URI}\"\n#{xmlns.collect {|pre, uri| \"xmlns:#{pre}='#{uri}'\"}.join(' ')}>\n#{block_given? ? yield : content}\n</rdf:RDF>\nEORSS\n    end\n\n    def make_channel(content=nil)\n      <<-EOC\n<channel rdf:about=\"#{RDF_ABOUT}\">\n  <title>#{TITLE_VALUE}</title>\n  <link>#{LINK_VALUE}</link>\n  <description>#{DESCRIPTION_VALUE}</description>\n\n  <image rdf:resource=\"#{RDF_RESOURCE}\" />\n\n  <items>\n    <rdf:Seq>\n#{RESOURCES.collect do |res| '<rdf:li resource=\"' + res + '\" />' end.join(\"\\n\")}\n    </rdf:Seq>\n  </items>\n\n  <textinput rdf:resource=\"#{RDF_RESOURCE}\" />\n\n#{block_given? ? yield : content}\n</channel>\nEOC\n    end\n\n    def make_image(content=nil)\n      <<-EOI\n<image rdf:about=\"#{RDF_ABOUT}\">\n  <title>#{TITLE_VALUE}</title>\n  <url>#{URL_VALUE}</url>\n  <link>#{LINK_VALUE}</link>\n#{block_given? ? yield : content}\n</image>\nEOI\n    end\n\n    def make_item(content=nil)\n      <<-EOI\n<item rdf:about=\"#{RDF_ABOUT}\">\n  <title>#{TITLE_VALUE}</title>\n  <link>#{LINK_VALUE}</link>\n  <description>#{DESCRIPTION_VALUE}</description>\n#{block_given? ? yield : content}\n</item>\nEOI\n    end\n\n    def make_textinput(content=nil)\n      <<-EOT\n<textinput rdf:about=\"#{RDF_ABOUT}\">\n  <title>#{TITLE_VALUE}</title>\n  <description>#{DESCRIPTION_VALUE}</description>\n  <name>#{NAME_VALUE}</name>\n  <link>#{LINK_VALUE}</link>\n#{block_given? ? yield : content}\n</textinput>\nEOT\n    end\n\n    def make_sample_RDF\n      make_RDF(<<-EOR)\n#{make_channel}\n#{make_image}\n#{make_item}\n#{make_textinput}\nEOR\n    end\n\n    def make_rss20(content=nil, xmlns=[])\n      <<-EORSS\n#{make_xmldecl}\n<rss version=\"2.0\"\n#{xmlns.collect {|pre, uri| \"xmlns:#{pre}='#{uri}'\"}.join(' ')}>\n#{block_given? ? yield : content}\n</rss>\nEORSS\n    end\n\n    def make_sample_items20\n      RESOURCES.collect do |res|\n        elems = [\"<link>#{res}</link>\"]\n        elems << \"<title>title of #{res}</title>\"\n        elems = elems.join(\"\\n\")\n        item = \"<item>\\n#{elems}\\n</item>\"\n      end.join(\"\\n\")\n    end\n\n    def make_channel20(content=nil)\n      <<-EOC\n<channel>\n  <title>#{TITLE_VALUE}</title>\n  <link>#{LINK_VALUE}</link>\n  <description>#{DESCRIPTION_VALUE}</description>\n  <language>#{LANGUAGE_VALUE}</language>\n\n  <image>\n    <url>#{RDF_RESOURCE}</url>\n    <title>#{TITLE_VALUE}</title>\n    <link>#{LINK_VALUE}</link>\n  </image>\n\n#{make_sample_items20}\n\n  <textInput>\n    <title>#{TITLE_VALUE}</title>\n    <description>#{DESCRIPTION_VALUE}</description>\n    <name>#{NAME_VALUE}</name>\n    <link>#{RDF_RESOURCE}</link>\n  </textInput>\n\n#{block_given? ? yield : content}\n</channel>\nEOC\n    end\n\n    def make_item20(content=nil)\n      <<-EOI\n<item>\n  <title>#{TITLE_VALUE}</title>\n  <link>#{LINK_VALUE}</link>\n  <description>#{DESCRIPTION_VALUE}</description>\n#{block_given? ? yield : content}\n</item>\nEOI\n    end\n\n    def make_cloud20\n      <<-EOC\n<cloud\n  domain=\"#{CLOUD_DOMAIN}\"\n  port=\"#{CLOUD_PORT}\"\n  path=\"#{CLOUD_PATH}\"\n  registerProcedure=\"#{CLOUD_REGISTER_PROCEDURE}\"\n  protocol=\"#{CLOUD_PROTOCOL}\" />\nEOC\n    end\n\n    def make_sample_rss20\n      make_rss20(<<-EOR)\n#{make_channel20}\nEOR\n    end\n\n    def make_feed_without_entry(content=nil, xmlns=[])\n      <<-EOA\n<feed xmlns=\"#{Atom::URI}\"\n#{xmlns.collect {|pre, uri| \"xmlns:#{pre}='#{uri}'\"}.join(' ')}>\n  <id>#{FEED_ID}</id>\n  <title>#{FEED_TITLE}</title>\n  <updated>#{FEED_UPDATED}</updated>\n  <author>\n    <name>#{FEED_AUTHOR_NAME}</name>\n  </author>\n#{block_given? ? yield : content}\n</feed>\nEOA\n    end\n\n    def make_entry(content=nil)\n      <<-EOA\n  <entry>\n    <title>#{ENTRY_TITLE}</title>\n    <id>#{ENTRY_ID}</id>\n    <updated>#{ENTRY_UPDATED}</updated>\n#{block_given? ? yield : content}\n  </entry>\nEOA\n    end\n\n    def make_feed_with_open_entry(content=nil, xmlns=[], &block)\n      make_feed_without_entry(<<-EOA, xmlns)\n#{make_entry(content, &block)}\nEOA\n    end\n\n    def make_feed_with_open_entry_source(content=nil, xmlns=[])\n      make_feed_with_open_entry(<<-EOA, xmlns)\n  <source>\n#{block_given? ? yield : content}\n  </source>\nEOA\n    end\n\n    def make_feed(content=nil, xmlns=[])\n      make_feed_without_entry(<<-EOA, xmlns)\n  <entry>\n    <title>#{ENTRY_TITLE}</title>\n    <link href=\"#{ENTRY_LINK}\"/>\n    <id>#{ENTRY_ID}</id>\n    <updated>#{ENTRY_UPDATED}</updated>\n    <summary>#{ENTRY_SUMMARY}</summary>\n  </entry>\n#{block_given? ? yield : content}\nEOA\n    end\n\n    def make_entry_document(content=nil, xmlns=[])\n      <<-EOA\n<entry xmlns=\"#{Atom::URI}\"\n#{xmlns.collect {|pre, uri| \"xmlns:#{pre}='#{uri}'\"}.join(' ')}>\n  <id>#{ENTRY_ID}</id>\n  <title>#{ENTRY_TITLE}</title>\n  <updated>#{ENTRY_UPDATED}</updated>\n  <author>\n    <name>#{FEED_AUTHOR_NAME}</name>\n  </author>\n#{block_given? ? yield : content}\n</entry>\nEOA\n    end\n\n    def make_entry_document_with_open_source(content=nil, xmlns=[])\n      make_entry_document(<<-EOA, xmlns)\n  <source>\n#{block_given? ? yield : content}\n  </source>\nEOA\n    end\n\n    def make_element(elem_name, attrs, contents)\n      attrs_str = attrs.collect do |name, value|\n        \"#{h name}='#{h value}'\"\n      end.join(\" \")\n      attrs_str = \" #{attrs_str}\" unless attrs_str.empty?\n\n      if contents.is_a?(String)\n        contents_str = h(contents)\n      else\n        contents_str = contents.collect do |name, value|\n          \"#{Element::INDENT}<#{h name}>#{h value}</#{h name}>\"\n        end.join(\"\\n\")\n        contents_str = \"\\n#{contents_str}\\n\"\n      end\n\n      \"<#{h elem_name}#{attrs_str}>#{contents_str}</#{h elem_name}>\"\n    end\n\n    def xmlns_container(xmlns_decls, content)\n      attributes = xmlns_decls.collect do |prefix, uri|\n        \"xmlns:#{h prefix}=\\\"#{h uri}\\\"\"\n      end.join(\" \")\n      \"<dummy #{attributes}>#{content}</dummy>\"\n    end\n\n    private\n    def setup_rss10(rdf)\n      assert_equal(\"\", rdf.to_s)\n\n      channel = RDF::Channel.new\n      assert_equal(\"\", channel.to_s)\n      channel.about = \"http://example.com/index.rdf\"\n      channel.title = \"title\"\n      channel.link = \"http://example.com/\"\n      channel.description = \"description\"\n      assert_equal(\"\", channel.to_s)\n\n      item_title = \"item title\"\n      item_link = \"http://example.com/item\"\n      channel.items = RDF::Channel::Items.new\n      channel.items.Seq.lis << RDF::Channel::Items::Seq::Li.new(item_link)\n      assert_not_equal(\"\", channel.to_s)\n\n      rdf.channel = channel\n      assert_equal(\"\", rdf.to_s)\n\n      item = RDF::Item.new\n      item.title = item_title\n      item.link = item_link\n      item.about = item_link\n      rdf.items << item\n      assert_not_equal(\"\", rdf.to_s)\n    end\n    \n    def setup_rss20(rss)\n      assert_equal(\"\", rss.to_s)\n\n      channel = Rss::Channel.new\n      assert_equal(\"\", channel.to_s)\n      channel.title = \"title\"\n      channel.link = \"http://example.com/\"\n      channel.description = \"description\"\n      assert_not_equal(\"\", channel.to_s)\n\n      rss.channel = channel\n      assert_not_equal(\"\", rss.to_s)\n    end\n    \n    def setup_dummy_channel(maker)\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com/feed.xml\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n\n      maker.channel.about = about\n      maker.channel.title = title\n      maker.channel.link = link\n      maker.channel.description = description\n      maker.channel.language = language\n    end\n\n    def setup_dummy_channel_atom(maker)\n      updated = Time.now\n      author = \"Foo\"\n\n      setup_dummy_channel(maker)\n      maker.channel.links.first.rel = \"self\"\n      maker.channel.links.first.type = \"application/atom+xml\"\n      maker.channel.updated = updated\n      maker.channel.author = author\n    end\n\n    def setup_dummy_image(maker)\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n\n      maker.channel.link = link if maker.channel.link.nil?\n      \n      maker.image.title = title\n      maker.image.url = url\n    end\n\n    def setup_dummy_textinput(maker)\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com/search.cgi\"\n\n      maker.textinput.title = title\n      maker.textinput.description = description\n      maker.textinput.name = name\n      maker.textinput.link = link\n    end\n\n    def setup_dummy_item(maker)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n\n      item = maker.items.new_item\n      item.title = title\n      item.link = link\n    end\n\n    def setup_dummy_item_atom(maker)\n      setup_dummy_item(maker)\n\n      item = maker.items.first\n      item.id = \"http://example.net/xxx\"\n      item.updated = Time.now\n    end\n\n    def setup_taxo_topic(target, topics)\n      topics.each do |topic|\n        taxo_topic = target.taxo_topics.new_taxo_topic\n        topic.each do |name, value|\n          case name\n          when :link\n            taxo_topic.taxo_link = value\n          when :topics\n            value.each do |t|\n              taxo_topic.taxo_topics << t\n            end\n          else\n            dc_elems = taxo_topic.__send__(\"dc_#{name}s\")\n            dc_elem = dc_elems.__send__(\"new_#{name}\")\n            dc_elem.value = value\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_1.0.rb",
    "content": "require \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\n\nmodule RSS\n  class TestRSS10Core < TestCase\n    \n    def setup\n      @rdf_prefix = \"rdf\"\n      @rdf_uri = \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n      @uri = \"http://purl.org/rss/1.0/\"\n    end\n    \n    def test_RDF\n      version = \"1.0\"\n      encoding = \"UTF-8\"\n      standalone = false\n      \n      rdf = RDF.new(version, encoding, standalone)\n      setup_rss10(rdf)\n      doc = REXML::Document.new(rdf.to_s)\n      \n      xmldecl = doc.xml_decl\n      \n      %w(version encoding).each do |x|\n        assert_equal(instance_eval(x), xmldecl.__send__(x))\n      end\n      assert_equal(standalone, !xmldecl.standalone.nil?)\n      \n      assert_equal(@rdf_uri, doc.root.namespace)\n    end\n    \n    def test_not_displayed_xml_stylesheets\n      rdf = RDF.new()\n      plain_rdf = rdf.to_s\n      3.times do\n        rdf.xml_stylesheets.push(XMLStyleSheet.new)\n        assert_equal(plain_rdf, rdf.to_s)\n      end\n    end\n    \n    def test_xml_stylesheets\n      [\n        [{:href => \"a.xsl\", :type => \"text/xsl\"}],\n        [\n          {:href => \"a.xsl\", :type => \"text/xsl\"},\n          {:href => \"a.css\", :type => \"text/css\"},\n        ],\n      ].each do |attrs_ary|\n        assert_xml_stylesheet_pis(attrs_ary)\n      end\n    end\n    \n    def test_channel\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      resource = \"http://hoge.com/hoge.png\"\n\n      item_title = \"item title\"\n      item_link = \"http://hoge.com/item\"\n\n      image = RDF::Channel::Image.new(resource)\n      items = RDF::Channel::Items.new\n      items.Seq.lis << items.class::Seq::Li.new(item_link)\n      textinput = RDF::Channel::Textinput.new(resource)\n\n      rss_item = RDF::Item.new\n      rss_item.title = item_title\n      rss_item.link = item_link\n      rss_item.about = item_link\n\n      channel = RDF::Channel.new(about)\n      %w(title link description image items textinput).each do |x|\n        channel.__send__(\"#{x}=\", instance_eval(x))\n      end\n      \n      doc = REXML::Document.new(make_RDF(<<-EOR))\n#{channel}\n<items>\n#{rss_item}\n</items>\nEOR\n      c = doc.root.elements[1]\n      \n      assert_equal(about, c.attributes[\"about\"])\n      %w(title link description image textinput).each do |x|\n        elem = c.elements[x]\n        assert_equal(x, elem.name)\n        assert_equal(@uri, elem.namespace)\n        if x == \"image\" or x == \"textinput\"\n          excepted = resource\n          res = elem.attributes.get_attribute(\"resource\")\n          assert_equal(@rdf_uri, res.namespace)\n          value = res.value\n        else\n          excepted = instance_eval(x)\n          value = elem.text\n        end\n        assert_equal(excepted, value)\n      end\n      assert_equal(@uri, c.elements[\"items\"].namespace)\n      assert_equal(\"items\", c.elements[\"items\"].name)\n    end\n    \n    def test_channel_image\n      resource = \"http://hoge.com/hoge.png\"\n      image = RDF::Channel::Image.new(resource)\n      \n      doc = REXML::Document.new(make_RDF(image.to_s))\n      i = doc.root.elements[1]\n      \n      assert_equal(\"image\", i.name)\n      assert_equal(@uri, i.namespace)\n      \n      res = i.attributes.get_attribute(\"resource\")\n      \n      assert_equal(@rdf_uri, res.namespace)\n      assert_equal(resource, res.value)\n    end\n    \n    def test_channel_textinput\n      resource = \"http://hoge.com/hoge.png\"\n      textinput = RDF::Channel::Textinput.new(resource)\n      \n      doc = REXML::Document.new(make_RDF(textinput.to_s))\n      t = doc.root.elements[1]\n      \n      assert_equal(\"textinput\", t.name)\n      assert_equal(@uri, t.namespace)\n      \n      res = t.attributes.get_attribute(\"resource\")\n      \n      assert_equal(@rdf_uri, res.namespace)\n      assert_equal(resource, res.value)\n    end\n    \n    def test_channel_items\n      item_link = \"http://example.com/item\"\n\n      items = RDF::Channel::Items.new\n      li = items.Seq.class::Li.new(item_link)\n      items.Seq.lis << li\n      \n      doc = REXML::Document.new(make_RDF(items.to_s))\n      i = doc.root.elements[1]\n      \n      assert_equal(\"items\", i.name)\n      assert_equal(@uri, i.namespace)\n      \n      assert_equal(1, i.elements.size)\n      seq = i.elements[1]\n      assert_equal(\"Seq\", seq.name)\n      assert_equal(@rdf_uri, seq.namespace)\n\n      assert_equal(1, seq.elements.size)\n      l = seq.elements[1]\n      assert_equal(\"li\", l.name)\n      assert_equal(@rdf_uri, l.namespace)\n      assert_equal(item_link, l.attributes[\"resource\"])\n    end\n    \n    def test_seq\n      item_link = \"http://example.com/item\"\n      seq = RDF::Seq.new\n      li = seq.class::Li.new(item_link)\n      seq.lis << li\n      \n      doc = REXML::Document.new(make_RDF(seq.to_s))\n      s = doc.root.elements[1]\n      \n      assert_equal(\"Seq\", s.name)\n      assert_equal(@rdf_uri, s.namespace)\n\n      assert_equal(1, s.elements.size)\n      l = s.elements[1]\n      assert_equal(\"li\", l.name)\n      assert_equal(@rdf_uri, l.namespace)\n      assert_equal(item_link, l.attributes[\"resource\"])\n    end\n    \n    def test_li\n      resource = \"http://hoge.com/\"\n      li = RDF::Li.new(resource)\n      \n      doc = REXML::Document.new(make_RDF(li.to_s))\n      l = doc.root.elements[1]\n      \n      assert_equal(\"li\", l.name)\n      assert_equal(@rdf_uri, l.namespace(l.prefix))\n      \n      res = l.attributes.get_attribute(\"resource\")\n      \n      assert_equal('', res.instance_eval(\"@prefix\"))\n      assert_equal(resource, res.value)\n    end\n    \n    def test_image\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      url = \"http://hoge.com/hoge\"\n      link = \"http://hoge.com/fuga\"\n      \n      image = RDF::Image.new(about)\n      %w(title url link).each do |x|\n        image.__send__(\"#{x}=\", instance_eval(x))\n      end\n      \n      doc = REXML::Document.new(make_RDF(image.to_s))\n      i = doc.root.elements[1]\n      \n      assert_equal(about, i.attributes[\"about\"])\n      %w(title url link).each do |x|\n        elem = i.elements[x]\n        assert_equal(x, elem.name)\n        assert_equal(@uri, elem.namespace)\n        assert_equal(instance_eval(x), elem.text)\n      end\n    end\n    \n    def test_item\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com/fuga\"\n      description = \"hogehogehoge\"\n      \n      item = RDF::Item.new(about)\n      %w(title link description).each do |x|\n        item.__send__(\"#{x}=\", instance_eval(x))\n      end\n      \n      doc = REXML::Document.new(make_RDF(item.to_s))\n      i = doc.root.elements[1]\n      \n      assert_equal(about, i.attributes[\"about\"])\n      %w(title link description).each do |x|\n        elem = i.elements[x]\n        assert_equal(x, elem.name)\n        assert_equal(@uri, elem.namespace)\n        assert_equal(instance_eval(x), elem.text)\n      end\n    end\n    \n    def test_textinput\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com/fuga\"\n      name = \"foo\"\n      description = \"hogehogehoge\"\n      \n      textinput = RDF::Textinput.new(about)\n      %w(title link name description).each do |x|\n        textinput.__send__(\"#{x}=\", instance_eval(x))\n      end\n      \n      doc = REXML::Document.new(make_RDF(textinput.to_s))\n      t = doc.root.elements[1]\n      \n      assert_equal(about, t.attributes[\"about\"])\n      %w(title link name description).each do |x|\n        elem = t.elements[x]\n        assert_equal(x, elem.name)\n        assert_equal(@uri, elem.namespace)\n        assert_equal(instance_eval(x), elem.text)\n      end\n    end\n\n    def test_to_xml\n      rss = RSS::Parser.parse(make_sample_RDF)\n      assert_equal(rss.to_s, rss.to_xml)\n      assert_equal(rss.to_s, rss.to_xml(\"1.0\"))\n      rss09 = rss.to_xml(\"0.91\") do |maker|\n        maker.channel.language = \"en-us\"\n      end\n      rss09 = RSS::Parser.parse(rss09)\n      assert_equal(\"0.91\", rss09.rss_version)\n      assert_equal([\"rss\", \"0.91\", nil], rss09.feed_info)\n      rss20 = RSS::Parser.parse(rss.to_xml(\"2.0\"))\n      assert_equal(\"2.0\", rss20.rss_version)\n      assert_equal([\"rss\", \"2.0\", nil], rss20.feed_info)\n\n      atom_xml = rss.to_xml(\"atom\") do |maker|\n        maker.channel.author = \"Alice\"\n        maker.channel.updated ||= Time.now\n        maker.items.each do |item|\n          item.updated ||= Time.now\n        end\n      end\n      atom = RSS::Parser.parse(atom_xml)\n      assert_equal([\"atom\", \"1.0\", \"feed\"], atom.feed_info)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_2.0.rb",
    "content": "require \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nmodule RSS\n  class TestRSS20Core < TestCase\n\n    def setup\n      @rss_version = \"2.0\"\n    end\n    \n    def test_Rss\n      version = \"1.0\"\n      encoding = \"UTF-8\"\n      standalone = false\n      \n      rss = Rss.new(@rss_version, version, encoding, standalone)\n      setup_rss20(rss)\n      \n      doc = REXML::Document.new(rss.to_s(false))\n      \n      xmldecl = doc.xml_decl\n      \n      %w(version encoding).each do |x|\n        assert_equal(instance_eval(x), xmldecl.__send__(x))\n      end\n      assert_equal(standalone, !xmldecl.standalone.nil?)\n      \n      assert_equal(\"\", doc.root.namespace)\n      assert_equal(@rss_version, doc.root.attributes[\"version\"])\n    end\n    \n    def test_not_displayed_xml_stylesheets\n      rss = Rss.new(@rss_version)\n      plain_rss = rss.to_s\n      3.times do\n        rss.xml_stylesheets.push(XMLStyleSheet.new)\n        assert_equal(plain_rss, rss.to_s)\n      end\n    end\n    \n    def test_xml_stylesheets\n      [\n        [{:href => \"a.xsl\", :type => \"text/xsl\"}],\n        [\n          {:href => \"a.xsl\", :type => \"text/xsl\"},\n          {:href => \"a.css\", :type => \"text/css\"},\n        ],\n      ].each do |attrs_ary|\n        rss = Rss.new(@rss_version)\n        setup_rss20(rss)\n        assert_xml_stylesheet_pis(attrs_ary, rss)\n      end\n    end\n\n    def test_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      \n      language = \"en-us\"\n      copyright = \"Copyright 2002, Spartanburg Herald-Journal\"\n      managingEditor = \"geo@herald.com (George Matesky)\"\n      webMaster = \"betty@herald.com (Betty Guernsey)\"\n      pubDate = Time.parse(\"Sat, 07 Sep 2002 00:00:01 GMT\")\n      lastBuildDate = Time.parse(\"Sat, 07 Sep 2002 09:42:31 GMT\")\n      categories = [\n        {\n          :content => \"Newspapers\",\n        },\n        {\n          :domain => \"Syndic8\",\n          :content => \"1765\",\n        }\n      ]\n      generator = \"MightyInHouse Content System v2.3\"\n      docs = \"http://blogs.law.harvard.edu/tech/rss\"\n\n      ttl = \"60\"\n\n      rating = '(PICS-1.1 \"http://www.rsac.org/ratingsv01.html\" l gen true comment \"RSACi North America Server\" for \"http://www.rsac.org\" on \"1996.04.16T08:15-0500\" r (n 0 s 0 v 0 l 0))'\n\n      channel = Rss::Channel.new\n      \n      elems = %w(title link description language copyright\n                 managingEditor webMaster pubDate lastBuildDate\n                 generator docs ttl rating)\n      elems.each do |x|\n        value = instance_eval(x)\n        value = value.rfc822 if %w(pubDate lastBuildDate).include?(x)\n        channel.__send__(\"#{x}=\", value)\n      end\n      categories.each do |cat|\n        channel.categories << Rss::Channel::Category.new(cat[:domain],\n                                                         cat[:content])\n      end\n      \n      doc = REXML::Document.new(make_rss20(channel.to_s))\n      c = doc.root.elements[1]\n      \n      elems.each do |x|\n        elem = c.elements[x]\n        assert_equal(x, elem.name)\n        assert_equal(\"\", elem.namespace)\n        expected = instance_eval(x)\n        case x\n        when \"pubDate\", \"lastBuildDate\"\n          assert_equal(expected, Time.parse(elem.text))\n        when \"ttl\"\n          expected = channel.__send__(x)\n          assert_equal(expected, elem.text.to_i)\n        else\n          assert_equal(expected, elem.text)\n        end\n      end\n      categories.each_with_index do |cat, i|\n        cat = cat.dup\n        cat[:domain] ||= nil\n        category = c.elements[\"category[#{i+1}]\"]\n        actual = {\n          :domain => category.attributes[\"domain\"],\n          :content => category.text,\n        }\n        assert_equal(cat, actual)\n      end\n    end\n\n    def test_channel_cloud\n      cloud_params = {\n        :domain => \"rpc.sys.com\",\n        :port => \"80\",\n        :path => \"/RPC2\",\n        :registerProcedure => \"myCloud.rssPleaseNotify\",\n        :protocol => \"xml-rpc\",\n      }\n      cloud = Rss::Channel::Cloud.new(cloud_params[:domain],\n                                      cloud_params[:port],\n                                      cloud_params[:path],\n                                      cloud_params[:registerProcedure],\n                                      cloud_params[:protocol])\n      cloud_params[:port] = cloud.port\n      \n      doc = REXML::Document.new(cloud.to_s)\n      cloud_elem = doc.root\n      \n      actual = {}\n      cloud_elem.attributes.each do |name, value|\n        value = value.to_i if name == \"port\"\n        actual[name.intern] = value\n      end\n      assert_equal(cloud_params, actual)\n    end\n\n    def test_channel_image\n      image_params = {\n        :url => \"http://hoge.com/hoge.png\",\n        :title => \"fugafuga\",\n        :link => \"http://hoge.com\",\n        :width => \"144\",\n        :height => \"400\",\n        :description => \"an image\",\n      }\n      image = Rss::Channel::Image.new(image_params[:url],\n                                      image_params[:title],\n                                      image_params[:link],\n                                      image_params[:width],\n                                      image_params[:height],\n                                      image_params[:description])\n\n      doc = REXML::Document.new(image.to_s)\n      image_elem = doc.root\n      \n      image_params.each do |name, value|\n        value = image.__send__(name)\n        actual = image_elem.elements[name.to_s].text\n        actual = actual.to_i if [:width, :height].include?(name)\n        assert_equal(value, actual)\n      end\n    end\n    \n    def test_channel_textInput\n      textInput_params = {\n        :title => \"fugafuga\",\n        :description => \"text hoge fuga\",\n        :name => \"hoge\",\n        :link => \"http://hoge.com\",\n      }\n      textInput = Rss::Channel::TextInput.new(textInput_params[:title],\n                                              textInput_params[:description],\n                                              textInput_params[:name],\n                                              textInput_params[:link])\n\n      doc = REXML::Document.new(textInput.to_s)\n      input_elem = doc.root\n      \n      textInput_params.each do |name, value|\n        actual = input_elem.elements[name.to_s].text\n        assert_equal(value, actual)\n      end\n    end\n    \n    def test_channel_skip_days\n      skipDays_values = [\n        \"Sunday\",\n        \"Monday\",\n      ]\n      skipDays = Rss::Channel::SkipDays.new\n      skipDays_values.each do |value|\n        skipDays.days << Rss::Channel::SkipDays::Day.new(value)\n      end\n      \n      doc = REXML::Document.new(skipDays.to_s)\n      days_elem = doc.root\n      \n      skipDays_values.each_with_index do |value, i|\n        assert_equal(value, days_elem.elements[i + 1].text)\n      end\n    end\n    \n    def test_channel_skip_hours\n      skipHours_values = [\n        \"0\",\n        \"13\",\n      ]\n      skipHours = Rss::Channel::SkipHours.new\n      skipHours_values.each do |value|\n        skipHours.hours << Rss::Channel::SkipHours::Hour.new(value)\n      end\n\n      doc = REXML::Document.new(skipHours.to_s)\n      hours_elem = doc.root\n      \n      skipHours_values.each_with_index do |value, i|\n        expected = skipHours.hours[i].content\n        assert_equal(expected, hours_elem.elements[i + 1].text.to_i)\n      end\n    end\n\n    def test_item\n      title = \"fugafuga\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n      author = \"oprah@oxygen.net\"\n      categories = [\n        {\n          :content => \"Newspapers\",\n        },\n        {\n          :domain => \"Syndic8\",\n          :content => \"1765\",\n        }\n      ]\n      comments = \"http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290\"\n      pubDate = Time.parse(\"Sat, 07 Sep 2002 00:00:01 GMT\")\n\n      channel = Rss::Channel.new\n      channel.title = \"title\"\n      channel.link = \"http://example.com/\"\n      channel.description = \"description\"\n\n      item = Rss::Channel::Item.new\n      channel.items << item\n      \n      elems = %w(title link description author comments pubDate)\n      elems.each do |x|\n        value = instance_eval(x)\n        value = value.rfc822 if x == \"pubDate\"\n        item.__send__(\"#{x}=\", value)\n      end\n      categories.each do |cat|\n        item.categories << Rss::Channel::Category.new(cat[:domain],\n                                                      cat[:content])\n      end\n      \n      doc = REXML::Document.new(channel.to_s)\n      channel_elem = doc.root\n\n      item_elem = channel_elem.elements[\"item[1]\"]\n      elems.each do |x|\n        elem = item_elem.elements[x]\n        assert_equal(x, elem.name)\n        assert_equal(\"\", elem.namespace)\n        expected = instance_eval(x)\n        case x\n        when \"pubDate\"\n          assert_equal(expected, Time.parse(elem.text))\n        else\n          assert_equal(expected, elem.text)\n        end\n      end\n      categories.each_with_index do |cat, i|\n        cat = cat.dup\n        cat[:domain] ||= nil\n        category = item_elem.elements[\"category[#{i+1}]\"]\n        actual = {\n          :domain => category.attributes[\"domain\"],\n          :content => category.text,\n        }\n        assert_equal(cat, actual)\n      end\n    end\n\n    def test_item_enclosure\n      enclosure_params = {\n        :url => \"http://www.scripting.com/mp3s/weatherReportSuite.mp3\",\n        :length => \"12216320\",\n        :type => \"audio/mpeg\",\n      }\n\n      enclosure = Rss::Channel::Item::Enclosure.new(enclosure_params[:url],\n                                                    enclosure_params[:length],\n                                                    enclosure_params[:type])\n      enclosure_params[:length] = enclosure.length\n      \n      doc = REXML::Document.new(enclosure.to_s)\n      enclosure_elem = doc.root\n\n      actual = {}\n      enclosure_elem.attributes.each do |name, value|\n        value = value.to_i if name == \"length\"\n        actual[name.intern] = value\n      end\n      assert_equal(enclosure_params, actual)\n    end\n    \n    def test_item_guid\n      test_params = [\n        {\n          :content => \"http://some.server.com/weblogItem3207\",\n        },\n        {\n          :isPermaLink => \"true\",\n          :content => \"http://inessential.com/2002/09/01.php#a2\",\n        },\n      ]\n\n      test_params.each do |guid_params|\n        guid = Rss::Channel::Item::Guid.new(guid_params[:isPermaLink],\n                                            guid_params[:content])\n        if guid_params.has_key?(:isPermaLink)\n          guid_params[:isPermaLink] = guid.isPermaLink\n        end\n        if guid.isPermaLink.nil?\n          assert_equal(true, guid.PermaLink?)\n        else\n          assert_equal(guid.isPermaLink, guid.PermaLink?)\n        end\n        \n        doc = REXML::Document.new(guid.to_s)\n        guid_elem = doc.root\n      \n        actual = {}\n        actual[:content] = guid_elem.text if guid_elem.text\n        guid_elem.attributes.each do |name, value|\n          value = value == \"true\" if name == \"isPermaLink\"\n          actual[name.intern] = value\n        end\n        assert_equal(guid_params, actual)\n      end\n    end\n    \n    def test_item_source\n      source_params = {\n        :url => \"http://www.tomalak.org/links2.xml\",\n        :content => \"Tomalak's Realm\",\n      }\n\n      source = Rss::Channel::Item::Source.new(source_params[:url],\n                                              source_params[:content])\n\n      doc = REXML::Document.new(source.to_s)\n      source_elem = doc.root\n      \n      actual = {}\n      actual[:content] = source_elem.text\n      source_elem.attributes.each do |name, value|\n        actual[name.intern] = value\n      end\n      assert_equal(source_params, actual)\n    end\n\n    def test_to_xml\n      rss = RSS::Parser.parse(make_sample_rss20)\n      assert_equal(rss.to_s, rss.to_xml)\n      assert_equal(rss.to_s, rss.to_xml(\"2.0\"))\n      rss09_xml = rss.to_xml(\"0.91\") do |maker|\n        setup_dummy_image(maker)\n      end\n      rss09 = RSS::Parser.parse(rss09_xml)\n      assert_equal(\"0.91\", rss09.rss_version)\n      rss10 = rss.to_xml(\"1.0\") do |maker|\n        maker.channel.about = \"http://www.example.com/index.rdf\"\n      end\n      rss10 = RSS::Parser.parse(rss10)\n      assert_equal(\"1.0\", rss10.rss_version)\n\n      atom_xml = rss.to_xml(\"atom1.0\") do |maker|\n        maker.channel.id = \"http://www.example.com/atom.xml\"\n        maker.channel.author = \"Alice\"\n        maker.channel.updated = Time.now\n        maker.items.each do |item|\n          item.author = \"Bob\"\n          item.updated = Time.now\n        end\n      end\n      atom = RSS::Parser.parse(atom_xml)\n      assert_equal([\"atom\", \"1.0\", \"feed\"], atom.feed_info)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_accessor.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/2.0\"\nrequire \"rss/syndication\"\nrequire \"rss/image\"\n\nmodule RSS\n  class TestAccessor < TestCase\n    def test_date\n      channel = Rss::Channel.new\n      channel.pubDate = nil\n      assert_nil(channel.pubDate)\n      \n      time = Time.now\n      channel.pubDate = time\n      assert_equal(time, channel.pubDate)\n      \n      time = Time.parse(Time.now.rfc822)\n      channel.pubDate = time.rfc822\n      assert_equal(time, channel.pubDate)\n\n      time = Time.parse(Time.now.iso8601)\n      value = time.iso8601\n      assert_not_available_value(\"pubDate\", value) do\n        channel.pubDate = value\n      end\n      \n      channel.do_validate = false\n      time = Time.parse(Time.now.iso8601)\n      value = time.iso8601\n      channel.pubDate = value\n      assert_equal(time, channel.pubDate)\n      \n      channel.pubDate = nil\n      assert_nil(channel.pubDate)\n    end\n    \n    def test_integer\n      image_item = RDF::Item::ImageItem.new\n\n      image_item.width = nil\n      assert_nil(image_item.width)\n      \n      width = 10\n      image_item.width = width\n      assert_equal(width, image_item.width)\n      \n      width = 10.0\n      image_item.width = width\n      assert_equal(width, image_item.width)\n      \n      width = \"10\"\n      image_item.width = width\n      assert_equal(width.to_i, image_item.width)\n      \n      width = \"10.0\"\n      assert_not_available_value(\"image:width\", width) do\n        image_item.width = width\n      end\n\n      image_item.do_validate = false\n      width = \"10.0\"\n      image_item.width = width\n      assert_equal(width.to_i, image_item.width)\n      \n      image_item.width = nil\n      assert_nil(image_item.width)\n    end\n    \n    def test_positive_integer\n      channel = RDF::Channel.new\n\n      channel.sy_updateFrequency = nil\n      assert_nil(channel.sy_updateFrequency)\n      \n      freq = 10\n      channel.sy_updateFrequency = freq\n      assert_equal(freq, channel.sy_updateFrequency)\n      \n      freq = 10.0\n      channel.sy_updateFrequency = freq\n      assert_equal(freq, channel.sy_updateFrequency)\n      \n      freq = \"10\"\n      channel.sy_updateFrequency = freq\n      assert_equal(freq.to_i, channel.sy_updateFrequency)\n      \n      freq = \"10.0\"\n      assert_not_available_value(\"sy:updateFrequency\", freq) do\n        channel.sy_updateFrequency = freq\n      end\n\n      channel.do_validate = false\n      freq = \"10.0\"\n      channel.sy_updateFrequency = freq\n      assert_equal(freq.to_i, channel.sy_updateFrequency)\n      \n      channel.sy_updateFrequency = nil\n      assert_nil(channel.sy_updateFrequency)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_atom.rb",
    "content": "require \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/atom\"\n\nmodule RSS\n  class TestAtomCore < TestCase\n    def setup\n      @uri = \"http://www.w3.org/2005/Atom\"\n      @xhtml_uri = \"http://www.w3.org/1999/xhtml\"\n    end\n\n    def test_feed\n      version = \"1.0\"\n      encoding = \"UTF-8\"\n      standalone = false\n\n      feed = Atom::Feed.new(version, encoding, standalone)\n      assert_equal(\"\", feed.to_s)\n\n      author = feed.class::Author.new\n      name = feed.class::Author::Name.new\n      name.content = \"an author\"\n      author.name = name\n      assert_not_equal(\"\", author.to_s)\n      feed.authors << author\n      assert_equal(\"\", feed.to_s)\n\n      id = feed.class::Id.new\n      id.content = \"http://example.com/atom.xml\"\n      assert_not_equal(\"\", id.to_s)\n      feed.id = id\n      assert_equal(\"\", feed.to_s)\n\n      title = feed.class::Title.new\n      title.content = \"a title\"\n      assert_not_equal(\"\", title.to_s)\n      feed.title = title\n      assert_equal(\"\", feed.to_s)\n\n      updated = feed.class::Updated.new\n      updated.content = Time.now\n      assert_not_equal(\"\", updated.to_s)\n      feed.updated = updated\n      assert_not_equal(\"\", feed.to_s)\n\n\n      feed.authors.clear\n      assert_equal(\"\", feed.to_s)\n      entry = Atom::Feed::Entry.new\n      setup_entry(entry)\n      assert_not_equal(\"\", entry.to_s)\n\n      author = entry.authors.first\n      entry.authors.clear\n      assert_equal(\"\", entry.to_s)\n      entry.parent = feed\n      assert_equal(\"\", entry.to_s)\n      feed.authors << author\n      assert_not_equal(\"\", entry.to_s)\n      feed.authors.clear\n      feed.entries << entry\n      assert_equal(\"\", feed.to_s)\n      entry.authors << author\n      assert_not_equal(\"\", entry.to_s)\n      assert_not_equal(\"\", feed.to_s)\n\n      doc = REXML::Document.new(feed.to_s)\n      xmldecl = doc.xml_decl\n\n      %w(version encoding).each do |x|\n        assert_equal(instance_eval(x), xmldecl.__send__(x))\n      end\n      assert_equal(standalone, !xmldecl.standalone.nil?)\n\n      assert_equal(@uri, doc.root.namespace)\n    end\n\n    def test_entry\n      version = \"1.0\"\n      encoding = \"UTF-8\"\n      standalone = false\n\n      entry = Atom::Entry.new(version, encoding, standalone)\n      setup_entry(entry)\n\n      author = entry.authors.first\n      entry.authors.clear\n      assert_equal(\"\", entry.to_s)\n      source = Atom::Entry::Source.new\n      source.authors << author\n      entry.source = source\n      assert_not_equal(\"\", entry.to_s)\n\n      doc = REXML::Document.new(entry.to_s)\n      xmldecl = doc.xml_decl\n\n      %w(version encoding).each do |x|\n        assert_equal(instance_eval(x), xmldecl.__send__(x))\n      end\n      assert_equal(standalone, !xmldecl.standalone.nil?)\n\n      assert_equal(@uri, doc.root.namespace)\n    end\n\n    def test_not_displayed_xml_stylesheets\n      feed = Atom::Feed.new\n      plain_feed = feed.to_s\n      3.times do\n        feed.xml_stylesheets.push(XMLStyleSheet.new)\n        assert_equal(plain_feed, feed.to_s)\n      end\n    end\n\n    def test_atom_author\n      assert_atom_person_to_s(Atom::Feed::Author)\n      assert_atom_person_to_s(Atom::Feed::Entry::Author)\n      assert_atom_person_to_s(Atom::Entry::Author)\n      assert_atom_person_to_s(Atom::Feed::Entry::Source::Author)\n      assert_atom_person_to_s(Atom::Entry::Source::Author)\n    end\n\n    def test_atom_category\n      assert_atom_category_to_s(Atom::Feed::Category)\n      assert_atom_category_to_s(Atom::Feed::Entry::Category)\n      assert_atom_category_to_s(Atom::Entry::Category)\n      assert_atom_category_to_s(Atom::Feed::Entry::Source::Category)\n      assert_atom_category_to_s(Atom::Entry::Source::Category)\n    end\n\n    def test_atom_contributor\n      assert_atom_person_to_s(Atom::Feed::Contributor)\n      assert_atom_person_to_s(Atom::Feed::Entry::Contributor)\n      assert_atom_person_to_s(Atom::Entry::Contributor)\n      assert_atom_person_to_s(Atom::Feed::Entry::Source::Contributor)\n      assert_atom_person_to_s(Atom::Entry::Source::Contributor)\n    end\n\n    def test_atom_generator\n      assert_atom_generator_to_s(Atom::Feed::Generator)\n      assert_atom_generator_to_s(Atom::Feed::Entry::Source::Generator)\n      assert_atom_generator_to_s(Atom::Entry::Source::Generator)\n    end\n\n    def test_atom_icon\n      assert_atom_icon_to_s(Atom::Feed::Icon)\n      assert_atom_icon_to_s(Atom::Feed::Entry::Source::Icon)\n      assert_atom_icon_to_s(Atom::Entry::Source::Icon)\n    end\n\n    def test_atom_id\n      assert_atom_id_to_s(Atom::Feed::Id)\n      assert_atom_id_to_s(Atom::Feed::Entry::Id)\n      assert_atom_id_to_s(Atom::Entry::Id)\n      assert_atom_id_to_s(Atom::Feed::Entry::Source::Id)\n      assert_atom_id_to_s(Atom::Entry::Source::Id)\n    end\n\n    def test_atom_link\n      assert_atom_link_to_s(Atom::Feed::Link)\n      assert_atom_link_to_s(Atom::Feed::Entry::Link)\n      assert_atom_link_to_s(Atom::Entry::Link)\n      assert_atom_link_to_s(Atom::Feed::Entry::Source::Link)\n      assert_atom_link_to_s(Atom::Entry::Source::Link)\n    end\n\n    def test_atom_logo\n      assert_atom_logo_to_s(Atom::Feed::Logo)\n      assert_atom_logo_to_s(Atom::Feed::Entry::Source::Logo)\n      assert_atom_logo_to_s(Atom::Entry::Source::Logo)\n    end\n\n    def test_atom_rights\n      assert_atom_text_construct_to_s(Atom::Feed::Rights)\n      assert_atom_text_construct_to_s(Atom::Feed::Entry::Rights)\n      assert_atom_text_construct_to_s(Atom::Entry::Rights)\n      assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Rights)\n      assert_atom_text_construct_to_s(Atom::Entry::Source::Rights)\n    end\n\n    def test_atom_subtitle\n      assert_atom_text_construct_to_s(Atom::Feed::Subtitle)\n      assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Subtitle)\n      assert_atom_text_construct_to_s(Atom::Entry::Source::Subtitle)\n    end\n\n    def test_atom_title\n      assert_atom_text_construct_to_s(Atom::Feed::Title)\n      assert_atom_text_construct_to_s(Atom::Feed::Entry::Title)\n      assert_atom_text_construct_to_s(Atom::Entry::Title)\n      assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Title)\n      assert_atom_text_construct_to_s(Atom::Entry::Source::Title)\n    end\n\n    def test_atom_updated\n      assert_atom_date_construct_to_s(Atom::Feed::Updated)\n      assert_atom_date_construct_to_s(Atom::Feed::Entry::Updated)\n      assert_atom_date_construct_to_s(Atom::Entry::Updated)\n      assert_atom_date_construct_to_s(Atom::Feed::Entry::Source::Updated)\n      assert_atom_date_construct_to_s(Atom::Entry::Source::Updated)\n    end\n\n    def test_atom_content\n      assert_atom_content_to_s(Atom::Feed::Entry::Content)\n      assert_atom_content_to_s(Atom::Entry::Content)\n    end\n\n    def test_atom_published\n      assert_atom_date_construct_to_s(Atom::Feed::Entry::Published)\n      assert_atom_date_construct_to_s(Atom::Entry::Published)\n    end\n\n    def test_atom_summary\n      assert_atom_text_construct_to_s(Atom::Feed::Entry::Summary)\n      assert_atom_text_construct_to_s(Atom::Entry::Summary)\n    end\n\n\n    def test_to_xml(with_convenience_way=true)\n      atom = RSS::Parser.parse(make_feed)\n      assert_equal(atom.to_s, atom.to_xml)\n      assert_equal(atom.to_s, atom.to_xml(\"atom\"))\n      assert_equal(atom.to_s, atom.to_xml(\"atom1.0\"))\n      assert_equal(atom.to_s, atom.to_xml(\"atom1.0:feed\"))\n      assert_equal(atom.to_s, atom.to_xml(\"atom:feed\"))\n\n      rss09_xml = atom.to_xml(\"0.91\") do |maker|\n        maker.channel.language = \"en-us\"\n        maker.channel.link = \"http://example.com/\"\n        if with_convenience_way\n          maker.channel.description = atom.title.content\n        else\n          maker.channel.description {|d| d.content = atom.title.content}\n        end\n\n        maker.image.url = \"http://example.com/logo.png\"\n        maker.image.title = \"Logo\"\n      end\n      rss09 = RSS::Parser.parse(rss09_xml)\n      assert_equal([\"rss\", \"0.91\", nil], rss09.feed_info)\n\n      rss20_xml = atom.to_xml(\"2.0\") do |maker|\n        maker.channel.link = \"http://example.com/\"\n        if with_convenience_way\n          maker.channel.description = atom.title.content\n        else\n          maker.channel.description {|d| d.content = atom.title.content}\n        end\n      end\n      rss20 = RSS::Parser.parse(rss20_xml)\n      assert_equal(\"2.0\", rss20.rss_version)\n      assert_equal([\"rss\", \"2.0\", nil], rss20.feed_info)\n    end\n\n    def test_to_xml_with_new_api_since_018\n      test_to_xml(false)\n    end\n\n    private\n    def setup_entry(entry)\n      _wrap_assertion do\n        assert_equal(\"\", entry.to_s)\n\n        author = entry.class::Author.new\n        name = entry.class::Author::Name.new\n        name.content = \"an author\"\n        author.name = name\n        assert_not_equal(\"\", author.to_s)\n        entry.authors << author\n        assert_equal(\"\", entry.to_s)\n\n        id = entry.class::Id.new\n        id.content = \"http://example.com/atom.xml\"\n        assert_not_equal(\"\", id.to_s)\n        entry.id = id\n        assert_equal(\"\", entry.to_s)\n\n        title = entry.class::Title.new\n        title.content = \"a title\"\n        assert_not_equal(\"\", title.to_s)\n        entry.title = title\n        assert_equal(\"\", entry.to_s)\n\n        updated = entry.class::Updated.new\n        updated.content = Time.now\n        assert_not_equal(\"\", updated.to_s)\n        entry.updated = updated\n        assert_not_equal(\"\", entry.to_s)\n      end\n    end\n\n\n    def assert_atom_person_to_s(target_class)\n      _wrap_assertion do\n        name = \"A person\"\n        uri = \"http://example.com/person/\"\n        email = \"person@example.com\"\n\n        target = target_class.new\n        assert_equal(\"\", target.to_s)\n\n        target = target_class.new\n        person_name = target_class::Name.new\n        person_name.content = name\n        target.name = person_name\n        xml_target = REXML::Document.new(target.to_s).root\n        assert_equal([\"name\"], xml_target.elements.collect {|e| e.name})\n        assert_equal([name], xml_target.elements.collect {|e| e.text})\n\n        person_uri = target_class::Uri.new\n        person_uri.content = uri\n        target.uri = person_uri\n        xml_target = REXML::Document.new(target.to_s).root\n        assert_equal([\"name\", \"uri\"], xml_target.elements.collect {|e| e.name})\n        assert_equal([name, uri], xml_target.elements.collect {|e| e.text})\n\n        person_email = target_class::Email.new\n        person_email.content = email\n        target.email = person_email\n        xml_target = REXML::Document.new(target.to_s).root\n        assert_equal([\"name\", \"uri\", \"email\"],\n                     xml_target.elements.collect {|e| e.name})\n        assert_equal([name, uri, email],\n                     xml_target.elements.collect {|e| e.text})\n      end\n    end\n\n    def assert_atom_category_to_s(target_class)\n      _wrap_assertion do\n        term = \"music\"\n        scheme = \"http://example.com/music\"\n        label = \"Music\"\n\n        category = target_class.new\n        assert_equal(\"\", category.to_s)\n\n        category = target_class.new\n        category.scheme = scheme\n        assert_equal(\"\", category.to_s)\n\n        category = target_class.new\n        category.label = label\n        assert_equal(\"\", category.to_s)\n\n        category = target_class.new\n        category.scheme = scheme\n        category.label = label\n        assert_equal(\"\", category.to_s)\n\n        category = target_class.new\n        category.term = term\n        xml = REXML::Document.new(category.to_s).root\n        assert_rexml_element([], {\"term\" => term}, nil, xml)\n\n        category = target_class.new\n        category.term = term\n        category.scheme = scheme\n        xml = REXML::Document.new(category.to_s).root\n        assert_rexml_element([], {\"term\" => term, \"scheme\" => scheme}, nil, xml)\n\n        category = target_class.new\n        category.term = term\n        category.label = label\n        xml = REXML::Document.new(category.to_s).root\n        assert_rexml_element([], {\"term\" => term, \"label\" => label}, nil, xml)\n\n        category = target_class.new\n        category.term = term\n        category.scheme = scheme\n        category.label = label\n        xml = REXML::Document.new(category.to_s).root\n        attrs = {\"term\" => term, \"scheme\" => scheme, \"label\" => label}\n        assert_rexml_element([], attrs, nil, xml)\n      end\n    end\n\n    def assert_atom_generator_to_s(target_class)\n      _wrap_assertion do\n        content = \"Feed generator\"\n        uri = \"http://example.com/generator\"\n        version = \"0.0.1\"\n\n        generator = target_class.new\n        assert_equal(\"\", generator.to_s)\n\n        generator = target_class.new\n        generator.uri = uri\n        assert_equal(\"\", generator.to_s)\n\n        generator = target_class.new\n        generator.version = version\n        assert_equal(\"\", generator.to_s)\n\n        generator = target_class.new\n        generator.uri = uri\n        generator.version = version\n        assert_equal(\"\", generator.to_s)\n\n        generator = target_class.new\n        generator.content = content\n        xml = REXML::Document.new(generator.to_s).root\n        assert_rexml_element([], {}, content, xml)\n\n        generator = target_class.new\n        generator.content = content\n        generator.uri = uri\n        xml = REXML::Document.new(generator.to_s).root\n        assert_rexml_element([], {\"uri\" => uri}, content, xml)\n\n        generator = target_class.new\n        generator.content = content\n        generator.version = version\n        xml = REXML::Document.new(generator.to_s).root\n        assert_rexml_element([], {\"version\" => version}, content, xml)\n\n        generator = target_class.new\n        generator.content = content\n        generator.uri = uri\n        generator.version = version\n        xml = REXML::Document.new(generator.to_s).root\n        assert_rexml_element([], {\"uri\" => uri, \"version\" => version},\n                             content, xml)\n      end\n    end\n\n    def assert_atom_icon_to_s(target_class)\n      _wrap_assertion do\n        content = \"http://example.com/icon.png\"\n\n        icon = target_class.new\n        assert_equal(\"\", icon.to_s)\n\n        icon = target_class.new\n        icon.content = content\n        xml = REXML::Document.new(icon.to_s).root\n        assert_rexml_element([], {}, content, xml)\n      end\n    end\n\n    def assert_atom_id_to_s(target_class)\n      _wrap_assertion do\n        content = \"http://example.com/1\"\n\n        id = target_class.new\n        assert_equal(\"\", id.to_s)\n\n        id = target_class.new\n        id.content = content\n        xml = REXML::Document.new(id.to_s).root\n        assert_rexml_element([], {}, content, xml)\n      end\n    end\n\n    def assert_atom_link_to_s(target_class)\n      _wrap_assertion do\n        href = \"http://example.com/atom.xml\"\n        rel = \"self\"\n        type = \"application/atom+xml\"\n        hreflang = \"ja\"\n        title = \"Atom Feed\"\n        length = \"801\"\n\n        link = target_class.new\n        assert_equal(\"\", link.to_s)\n\n        link = target_class.new\n        link.href = href\n        xml = REXML::Document.new(link.to_s).root\n        assert_rexml_element([], {\"href\" => href}, nil, xml)\n\n        optional_arguments = %w(rel type hreflang title length)\n        optional_arguments.each do |name|\n          rest = optional_arguments.reject {|x| x == name}\n\n          link = target_class.new\n          link.__send__(\"#{name}=\", eval(name))\n          assert_equal(\"\", link.to_s)\n\n          rest.each do |n|\n            link.__send__(\"#{n}=\", eval(n))\n            assert_equal(\"\", link.to_s)\n          end\n\n          link = target_class.new\n          link.href = href\n          link.__send__(\"#{name}=\", eval(name))\n          attrs = [[\"href\", href], [name, eval(name)]]\n          xml = REXML::Document.new(link.to_s).root\n          assert_rexml_element([], attrs, nil, xml)\n\n          rest.each do |n|\n            link.__send__(\"#{n}=\", eval(n))\n            attrs << [n, eval(n)]\n            xml = REXML::Document.new(link.to_s).root\n            assert_rexml_element([], attrs, nil, xml)\n          end\n        end\n      end\n    end\n\n    def assert_atom_logo_to_s(target_class)\n      _wrap_assertion do\n        content = \"http://example.com/logo.png\"\n\n        logo = target_class.new\n        assert_equal(\"\", logo.to_s)\n\n        logo = target_class.new\n        logo.content = content\n        xml = REXML::Document.new(logo.to_s).root\n        assert_rexml_element([], {}, content, xml)\n      end\n    end\n\n    def assert_atom_text_construct_to_s(target_class)\n      _wrap_assertion do\n        text_content = \"plain text\"\n        html_content = \"<em>#{text_content}</em>\"\n        xhtml_uri = \"http://www.w3.org/1999/xhtml\"\n        xhtml_em = RSS::XML::Element.new(\"em\", nil, xhtml_uri, {}, text_content)\n        xhtml_content = RSS::XML::Element.new(\"div\", nil, xhtml_uri,\n                                              {\"xmlns\" => xhtml_uri},\n                                              [xhtml_em])\n\n        text = target_class.new\n        assert_equal(\"\", text.to_s)\n\n        text = target_class.new\n        text.type = \"text\"\n        assert_equal(\"\", text.to_s)\n\n        text = target_class.new\n        text.content = text_content\n        xml = REXML::Document.new(text.to_s).root\n        assert_rexml_element([], {}, text_content, xml)\n\n        text = target_class.new\n        text.type = \"text\"\n        text.content = text_content\n        xml = REXML::Document.new(text.to_s).root\n        assert_rexml_element([], {\"type\" => \"text\"}, text_content, xml)\n\n        text = target_class.new\n        text.type = \"html\"\n        text.content = html_content\n        xml = REXML::Document.new(text.to_s).root\n        assert_rexml_element([], {\"type\" => \"html\"}, html_content, xml)\n\n        text = target_class.new\n        text.type = \"xhtml\"\n        text.content = xhtml_content\n        assert_equal(\"\", text.to_s)\n\n        text = target_class.new\n        text.type = \"xhtml\"\n        text.__send__(target_class.xml_setter, xhtml_content)\n        xml = REXML::Document.new(text.to_s).root\n        assert_rexml_element([[xhtml_uri, \"div\"]], {\"type\" => \"xhtml\"},\n                             nil, xml)\n        assert_rexml_element([[xhtml_uri, \"em\"]], nil, nil, xml.elements[1])\n        assert_rexml_element([], {}, text_content, xml.elements[1].elements[1])\n\n        text = target_class.new\n        text.type = \"xhtml\"\n        text.__send__(target_class.xml_setter, xhtml_em)\n        xml = REXML::Document.new(text.to_s).root\n        assert_rexml_element([[xhtml_uri, \"div\"]], {\"type\" => \"xhtml\"},\n                             nil, xml)\n        assert_rexml_element([[xhtml_uri, \"em\"]], nil, nil, xml.elements[1])\n        assert_rexml_element([], {}, text_content, xml.elements[1].elements[1])\n      end\n    end\n\n    def assert_atom_date_construct_to_s(target_class)\n      _wrap_assertion do\n        date = target_class.new\n        assert_equal(\"\", date.to_s)\n\n        [\n         \"2003-12-13T18:30:02Z\",\n         \"2003-12-13T18:30:02.25Z\",\n         \"2003-12-13T18:30:02+01:00\",\n         \"2003-12-13T18:30:02.25+01:00\",\n        ].each do |content|\n          date = target_class.new\n          date.content = content\n          xml = REXML::Document.new(date.to_s).root\n          assert_rexml_element([], {}, content, xml, :time)\n\n          date = target_class.new\n          date.content = Time.parse(content)\n          xml = REXML::Document.new(date.to_s).root\n          assert_rexml_element([], {}, content, xml, :time)\n        end\n      end\n    end\n\n    def assert_atom_content_to_s(target_class)\n      _wrap_assertion do\n        assert_atom_text_construct_to_s(target_class)\n        assert_atom_content_inline_other_xml_to_s(target_class)\n        assert_atom_content_inline_other_text_to_s(target_class)\n        assert_atom_content_inline_other_base64_to_s(target_class)\n        assert_atom_content_out_of_line_to_s(target_class)\n      end\n    end\n\n    def assert_atom_content_inline_other_xml_to_s(target_class)\n      _wrap_assertion do\n        content = target_class.new\n        content.type = \"text/xml\"\n        assert_equal(\"\", content.to_s)\n\n        content = target_class.new\n        content.type = \"text/xml\"\n        content.xml = RSS::XML::Element.new(\"em\")\n        xml = REXML::Document.new(content.to_s).root\n        assert_rexml_element([[\"\", \"em\"]], {\"type\" => \"text/xml\"}, nil, xml)\n      end\n    end\n\n    def assert_atom_content_inline_other_text_to_s(target_class)\n      _wrap_assertion do\n        content = target_class.new\n        content.type = \"text/plain\"\n        assert_equal(\"\", content.to_s)\n\n        content = target_class.new\n        content.type = \"text/plain\"\n        content.xml = RSS::XML::Element.new(\"em\")\n        assert_equal(\"\", content.to_s)\n\n        content = target_class.new\n        content.type = \"text/plain\"\n        content.content = \"content\"\n        xml = REXML::Document.new(content.to_s).root\n        assert_rexml_element([], {\"type\" => \"text/plain\"}, \"content\", xml)\n      end\n    end\n\n    def assert_atom_content_inline_other_base64_to_s(target_class)\n      _wrap_assertion do\n        type = \"image/png\"\n        png_file = File.join(File.dirname(__FILE__), \"dot.png\")\n        original_content = File.open(png_file, \"rb\") {|file| file.read}\n\n        content = target_class.new\n        content.type = type\n        content.content = original_content\n        xml = REXML::Document.new(content.to_s).root\n        assert_rexml_element([], {\"type\" => type},\n                             [original_content].pack(\"m\"),\n                             xml)\n      end\n    end\n\n    def assert_atom_content_out_of_line_to_s(target_class)\n      _wrap_assertion do\n        type = \"application/zip\"\n        src = \"http://example.com/xxx.zip\"\n\n        content = target_class.new\n        assert(!content.out_of_line?)\n        content.src = src\n        assert(content.out_of_line?)\n        xml = REXML::Document.new(content.to_s).root\n        assert_rexml_element([], {\"src\" => src}, nil, xml)\n\n        content = target_class.new\n        assert(!content.out_of_line?)\n        content.type = type\n        assert(!content.out_of_line?)\n        content.src = src\n        assert(content.out_of_line?)\n        xml = REXML::Document.new(content.to_s).root\n        assert_rexml_element([], {\"type\" => type, \"src\" => src}, nil, xml)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_content.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/content\"\n\nmodule RSS\n  class TestContent < TestCase\n    def setup\n      @prefix = \"content\"\n      @uri = \"http://purl.org/rss/1.0/modules/content/\"\n      \n      @elems = {\n        :encoded => \"<em>ATTENTION</em>\",\n      }\n      \n      @content_nodes = @elems.collect do |name, value|\n        \"<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>\"\n      end.join(\"\\n\")\n      \n      @rss10_source = make_RDF(<<-EOR, {@prefix => @uri})\n#{make_channel()}\n#{make_image()}\n#{make_item(@content_nodes)}\n#{make_textinput()}\nEOR\n\n      @rss10 = Parser.parse(@rss10_source)\n\n\n      @rss20_source = make_rss20(<<-EOR, {@prefix =>  @uri})\n#{make_channel20(make_item20(@content_nodes))}\nEOR\n\n      @rss20 = Parser.parse(@rss20_source)\n    end\n\n    def test_parser\n      assert_nothing_raised do\n        Parser.parse(@rss10_source)\n      end\n\n      assert_nothing_raised do\n        Parser.parse(@rss20_source)\n      end\n\n      @elems.each do |tag, value|\n        tag_name = \"#{@prefix}:#{tag}\"\n        content_encodes = make_element(tag_name, {}, value) * 2\n\n        assert_too_much_tag(tag.to_s, \"item\") do\n          Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))\n#{make_channel}\n#{make_item(content_encodes)}\nEOR\n        end\n\n        assert_too_much_tag(tag.to_s, \"item\") do\n          Parser.parse(make_rss20(<<-EOR, {@prefix => @uri}))\n#{make_channel20(make_item20(content_encodes))}\nEOR\n        end\n      end\n    end\n\n    def test_accessor\n      new_value = {\n        :encoded => \"<![CDATA[<it>hoge</it>]]>\",\n      }\n\n      @elems.each do |name, value|\n        [@rss10, @rss20].each do |rss|\n          meth = \"#{RSS::CONTENT_PREFIX}_#{name}\"\n          parent = rss.items.last\n          assert_equal(value, parent.__send__(meth))\n          parent.__send__(\"#{meth}=\", new_value[name].to_s)\n          assert_equal(new_value[name], parent.__send__(meth))\n        end\n      end\n    end\n    \n    def test_to_s\n      @elems.each do |name, value|\n        excepted = make_element(\"#{@prefix}:#{name}\", {}, value)\n        meth = \"#{RSS::CONTENT_PREFIX}_#{name}_element\"\n        [@rss10, @rss20].each do |rss|\n          assert_equal(excepted, rss.items.last.__send__(meth))\n        end\n      end\n\n      [@rss10_source, @rss20_source].each do |source|\n        REXML::Document.new(source).root.each_element do |parent|\n          next unless parent.name != \"item\"\n          parent.each_element do |elem|\n            if elem.namespace == @uri\n              assert_equal(elem.text, @elems[elem.name.intern].to_s)\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_dublincore.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n  class TestDublinCore < TestCase\n    def setup\n      @rss10_parents = [%w(channel), %w(image), %w(item), %w(textinput)]\n\n      @rss10_source = make_RDF(<<-EOR, {DC_PREFIX =>  DC_URI})\n#{make_channel(DC_NODES)}\n#{make_image(DC_NODES)}\n#{make_item(DC_NODES)}\n#{make_textinput(DC_NODES)}\nEOR\n\n      @rss20_parents = [%w(channel), %w(items last)]\n\n      @rss20_source = make_rss20(<<-EOR, {DC_PREFIX =>  DC_URI})\n#{make_channel20(DC_NODES + make_item20(DC_NODES))}\nEOR\n\n      @atom_feed_parents = [[], %w(entries last)]\n\n      @atom_feed_source = make_feed(<<-EOR, {DC_PREFIX =>  DC_URI})\n#{DC_NODES}\n#{make_entry(DC_NODES)}\nEOR\n\n      @atom_entry_parents = [[]]\n\n      @atom_entry_source = make_entry_document(<<-EOR, {DC_PREFIX =>  DC_URI})\n#{DC_NODES}\nEOR\n    end\n\n    def test_parser\n      rss10_maker = Proc.new do |content, xmlns|\n        make_RDF(<<-EOR, xmlns)\n#{make_channel(content)}\n#{make_image(content)}\n#{make_item(content)}\n#{make_textinput(content)}\nEOR\n      end\n      assert_dc_parse(@rss10_source, @rss10_parents, false, &rss10_maker)\n      assert_dc_parse(@rss10_source, @rss10_parents, true, &rss10_maker)\n\n      rss20_maker = Proc.new do |content, xmlns|\n        make_rss20(<<-EOR, xmlns)\n#{make_channel20(content + make_item20(content))}\nEOR\n      end\n      assert_dc_parse(@rss20_source, @rss20_parents, false, &rss20_maker)\n      assert_dc_parse(@rss20_source, @rss20_parents, true, &rss20_maker)\n\n      atom_feed_maker = Proc.new do |content, xmlns|\n        make_feed(<<-EOR, xmlns)\n#{content}\n#{make_entry(content)}\nEOR\n      end\n      assert_dc_parse(@atom_feed_source, @atom_feed_parents, false,\n                      &atom_feed_maker)\n      assert_dc_parse(@atom_feed_source, @atom_feed_parents, true,\n                      &atom_feed_maker)\n\n      atom_entry_maker = Proc.new do |content, xmlns|\n        make_entry_document(<<-EOR, xmlns)\n#{content}\nEOR\n      end\n      assert_dc_parse(@atom_entry_source, @atom_entry_parents, false,\n                      &atom_entry_maker)\n      assert_dc_parse(@atom_entry_source, @atom_entry_parents, true,\n                      &atom_entry_maker)\n    end\n\n    def test_singular_accessor\n      assert_dc_singular_accessor(@rss10_source, @rss10_parents)\n      assert_dc_singular_accessor(@rss20_source, @rss20_parents)\n      assert_dc_singular_accessor(@atom_feed_source, @atom_feed_parents)\n      assert_dc_singular_accessor(@atom_entry_source, @atom_entry_parents)\n    end\n\n    def test_plural_accessor\n      assert_dc_plural_accessor(@rss10_source, @rss10_parents, false)\n      assert_dc_plural_accessor(@rss10_source, @rss10_parents, true)\n\n      assert_dc_plural_accessor(@rss20_source, @rss20_parents, false)\n      assert_dc_plural_accessor(@rss20_source, @rss20_parents, true)\n\n      assert_dc_plural_accessor(@atom_feed_source, @atom_feed_parents, false)\n      assert_dc_plural_accessor(@atom_feed_source, @atom_feed_parents, true)\n\n      assert_dc_plural_accessor(@atom_entry_source, @atom_entry_parents, false)\n      assert_dc_plural_accessor(@atom_entry_source, @atom_entry_parents, true)\n    end\n\n    def test_to_s\n      assert_dc_to_s(@rss10_source, @rss10_parents, false)\n      assert_dc_to_s(@rss10_source, @rss10_parents, true)\n\n      targets = [\"channel\", \"channel/item[3]\"]\n      assert_dc_to_s(@rss20_source, @rss20_parents, false, targets)\n      assert_dc_to_s(@rss20_source, @rss20_parents, true, targets)\n\n      targets = [\".\", \"entry\"]\n      assert_dc_to_s(@atom_feed_source, @atom_feed_parents, false, targets)\n      assert_dc_to_s(@atom_feed_source, @atom_feed_parents, true, targets)\n\n      targets = [\".\"]\n      assert_dc_to_s(@atom_entry_source, @atom_entry_parents, false, targets)\n      assert_dc_to_s(@atom_entry_source, @atom_entry_parents, true, targets)\n    end\n\n    private\n    def dc_plural_suffix(name, check_backward_compatibility)\n      if name == :rights\n        if check_backward_compatibility\n          \"es\"\n        else\n          \"_list\"\n        end\n      else\n        \"s\"\n      end\n    end\n\n    def assert_dc_parse(source, parents, check_backward_compatibility, &maker)\n      assert_nothing_raised do\n        Parser.parse(source)\n      end\n\n      DC_ELEMENTS.each do |name, value|\n        parents.each do |parent_readers|\n          feed = nil\n          assert_nothing_raised do\n            tag = \"#{DC_PREFIX}:#{name}\"\n            dc_content = \"<#{tag}>#{value}</#{tag}>\\n\"\n            dc_content *= 2\n            feed = Parser.parse(maker.call(dc_content, {DC_PREFIX => DC_URI}))\n          end\n          parent = chain_reader(feed, parent_readers)\n\n          plural_suffix = dc_plural_suffix(name, check_backward_compatibility)\n          plural_reader = \"dc_#{name}#{plural_suffix}\"\n          values = parent.__send__(plural_reader).collect do |x|\n            val = x.value\n            if val.kind_of?(String)\n              CGI.escapeHTML(val)\n            else\n              val\n            end\n          end\n          assert_equal([value, value], values)\n        end\n      end\n    end\n\n    def assert_dc_singular_accessor(source, parents)\n      feed = Parser.parse(source)\n      new_value = \"hoge\"\n\n      parents.each do |parent_readers|\n        parent = chain_reader(feed, parent_readers)\n        DC_ELEMENTS.each do |name, value|\n          parsed_value = parent.__send__(\"dc_#{name}\")\n          if parsed_value.kind_of?(String)\n            parsed_value = CGI.escapeHTML(parsed_value)\n          end\n          assert_equal(value, parsed_value)\n          if name == :date\n            t = Time.iso8601(\"2003-01-01T02:30:23+09:00\")\n            class << t\n              alias_method(:to_s, :iso8601)\n            end\n            parent.__send__(\"dc_#{name}=\", t.iso8601)\n            assert_equal(t, parent.__send__(\"dc_#{name}\"))\n            if parent.class.method_defined?(:date_without_dc_date=)\n              assert_nil(parent.date)\n            else\n              assert_equal(t, parent.date)\n            end\n\n            parent.date = value\n            assert_equal(value, parent.date)\n            assert_equal(value, parent.__send__(\"dc_#{name}\"))\n          else\n            parent.__send__(\"dc_#{name}=\", new_value)\n            assert_equal(new_value, parent.__send__(\"dc_#{name}\"))\n          end\n        end\n      end\n    end\n\n    def assert_dc_plural_accessor(source, parents, check_backward_compatibility)\n      feed = Parser.parse(source)\n      new_value = \"hoge\"\n\n      DC_ELEMENTS.each do |name, value|\n        parents.each do |parent_readers|\n          parent = chain_reader(feed, parent_readers)\n          parsed_value = parent.__send__(\"dc_#{name}\")\n          if parsed_value.kind_of?(String)\n            parsed_value = CGI.escapeHTML(parsed_value)\n          end\n          assert_equal(value, parsed_value)\n\n          plural_suffix = dc_plural_suffix(name, check_backward_compatibility)\n          plural_reader = \"dc_#{name}#{plural_suffix}\"\n          klass_name = \"DublinCore#{Utils.to_class_name(name.to_s)}\"\n          klass = DublinCoreModel.const_get(klass_name)\n          if name == :date\n            t = Time.iso8601(\"2003-01-01T02:30:23+09:00\")\n            class << t\n              alias_method(:to_s, :iso8601)\n            end\n            elems = parent.__send__(plural_reader)\n            elems << klass.new(t.iso8601)\n            new_elems = parent.__send__(plural_reader)\n            values = new_elems.collect{|x| x.value}\n            assert_equal([parent.__send__(\"dc_#{name}\"), t], values)\n          else\n            elems = parent.__send__(plural_reader)\n            elems << klass.new(new_value)\n            new_elems = parent.__send__(plural_reader)\n            values = new_elems.collect{|x| x.value}\n            assert_equal([parent.__send__(\"dc_#{name}\"), new_value],\n                         values)\n          end\n        end\n      end\n    end\n\n    def assert_dc_to_s(source, parents, check_backward_compatibility,\n                       targets=nil)\n      feed = Parser.parse(source)\n\n      DC_ELEMENTS.each do |name, value|\n        excepted = \"<#{DC_PREFIX}:#{name}>#{value}</#{DC_PREFIX}:#{name}>\"\n        parents.each do |parent_readers|\n          parent = chain_reader(feed, parent_readers)\n          assert_equal(excepted, parent.__send__(\"dc_#{name}_elements\"))\n        end\n\n        plural_suffix = dc_plural_suffix(name, check_backward_compatibility)\n        reader = \"dc_#{name}#{plural_suffix}\"\n        excepted = Array.new(2, excepted).join(\"\\n\")\n        parents.each do |parent_readers|\n          parent = chain_reader(feed, parent_readers)\n          elems = parent.__send__(reader)\n          klass_name = \"DublinCore#{Utils.to_class_name(name.to_s)}\"\n          klass = DublinCoreModel.const_get(klass_name)\n          elems << klass.new(parent.__send__(\"dc_#{name}\"))\n          assert_equal(excepted, parent.__send__(\"dc_#{name}_elements\"))\n        end\n      end\n\n      targets ||= parents.collect do |parent_readers|\n        parent_readers.first\n      end\n      feed_root = REXML::Document.new(source).root\n      targets.each do |target_xpath|\n        parent = feed_root.elements[target_xpath]\n        parent.each_element do |elem|\n          if elem.namespace == DC_URI\n            assert_equal(CGI.escapeHTML(elem.text),\n                         DC_ELEMENTS[elem.name.intern].to_s)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_image.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/image\"\n\nmodule RSS\n  class TestImage < TestCase\n\n    def setup\n      @prefix = \"image\"\n      @uri = \"http://purl.org/rss/1.0/modules/image/\"\n\n      @favicon_attrs = {\n        \"rdf:about\" => \"http://www.kuro5hin.org/favicon.ico\",\n        \"#{@prefix}:size\" => \"small\",\n      }\n      @favicon_contents = {\"dc:title\" => \"Kuro5hin\",}\n      @items = [\n        [\n          {\n            \"rdf:about\" => \"http://www.example.org/item.png\",\n            \"rdf:resource\" => \"http://www.example.org/item\",\n          },\n          {\n            \"dc:title\" => \"Example Image\",\n            \"#{@prefix}:width\" => \"100\",\n            \"#{@prefix}:height\" => \"65\",\n          },\n        ],\n        [\n          {\n            \"rdf:about\" => \"http://www.kuro5hin.org/images/topics/culture.jpg\",\n          },\n          {\n            \"dc:title\" => \"Culture\",\n            \"#{@prefix}:width\" => \"80\",\n            \"#{@prefix}:height\" => \"50\",\n          },\n        ]\n      ]\n\n\n      @channel_nodes = make_element(\"#{@prefix}:favicon\",\n                                    @favicon_attrs,\n                                    @favicon_contents)\n      items = \"\"\n      @items.each do |attrs, contents|\n        image_item = make_element(\"#{@prefix}:item\", attrs, contents)\n        items << make_item(image_item)\n      end\n\n      @ns = {\n        @prefix => @uri,\n        DC_PREFIX => DC_URI,\n      }\n      @rss_source = make_RDF(<<-EOR, @ns)\n#{make_channel(@channel_nodes)}\n#{make_image}\n#{items}\n#{make_textinput}\nEOR\n\n      @rss = Parser.parse(@rss_source)\n    end\n\n    def test_parser\n      assert_nothing_raised do\n        Parser.parse(@rss_source)\n      end\n\n      assert_too_much_tag(\"favicon\", \"channel\") do\n        Parser.parse(make_RDF(<<-EOR, @ns))\n#{make_channel(@channel_nodes * 2)}\n#{make_item}\nEOR\n      end\n\n      attrs = {\"rdf:about\" => \"http://www.example.org/item.png\"}\n      contents = [[\"#{@prefix}:width\", \"80\"]] * 5\n      image_item = make_element(\"#{@prefix}:item\", attrs, contents)\n      assert_too_much_tag(\"width\", \"item\") do\n        Parser.parse(make_RDF(<<-EOR, @ns))\n#{make_channel}\n#{make_item(image_item)}\nEOR\n      end\n    end\n\n    def test_favicon_accessor\n      favicon = @rss.channel.image_favicon\n      [\n        %w(about rdf:about http://example.com/favicon.ico),\n        %w(size image:size large),\n        %w(image_size image:size medium),\n      ].each do |name, full_name, new_value|\n        assert_equal(@favicon_attrs[full_name], favicon.__send__(name))\n        favicon.__send__(\"#{name}=\", new_value)\n        assert_equal(new_value, favicon.__send__(name))\n        favicon.__send__(\"#{name}=\", @favicon_attrs[full_name])\n        assert_equal(@favicon_attrs[full_name], favicon.__send__(name))\n      end\n\n      %w(small medium large).each do |value|\n        assert_nothing_raised do\n          favicon.size = value\n          favicon.image_size = value\n        end\n      end\n\n      %w(aaa AAA SMALL MEDIUM LARGE).each do |value|\n        args = [\"#{@prefix}:favicon\", value, \"#{@prefix}:size\"]\n        assert_not_available_value(*args) do\n          favicon.size = value\n        end\n        assert_not_available_value(*args) do\n          favicon.image_size = value\n        end\n      end\n\n      [\n        %w(dc_title dc:title sample-favicon),\n      ].each do |name, full_name, new_value|\n        assert_equal(@favicon_contents[full_name], favicon.__send__(name))\n        favicon.__send__(\"#{name}=\", new_value)\n        assert_equal(new_value, favicon.__send__(name))\n        favicon.__send__(\"#{name}=\", @favicon_contents[full_name])\n        assert_equal(@favicon_contents[full_name], favicon.__send__(name))\n      end\n    end\n\n    def test_item_accessor\n      @rss.items.each_with_index do |item, i|\n        image_item = item.image_item\n        attrs, contents = @items[i]\n        [\n          %w(about rdf:about http://example.com/image.png),\n          %w(resource rdf:resource http://example.com/),\n        ].each do |name, full_name, new_value|\n          assert_equal(attrs[full_name], image_item.__send__(name))\n          image_item.__send__(\"#{name}=\", new_value)\n          assert_equal(new_value, image_item.__send__(name))\n          image_item.__send__(\"#{name}=\", attrs[full_name])\n          assert_equal(attrs[full_name], image_item.__send__(name))\n        end\n\n        [\n          [\"width\", \"image:width\", \"111\"],\n          [\"image_width\", \"image:width\", \"44\"],\n          [\"height\", \"image:height\", \"222\"],\n          [\"image_height\", \"image:height\", \"88\"],\n        ].each do |name, full_name, new_value|\n          assert_equal(contents[full_name].to_i, image_item.__send__(name))\n          image_item.__send__(\"#{name}=\", new_value)\n          assert_equal(new_value.to_i, image_item.__send__(name))\n          image_item.__send__(\"#{name}=\", contents[full_name])\n          assert_equal(contents[full_name].to_i, image_item.__send__(name))\n        end\n\n        [\n          [\"dc_title\", \"dc:title\", \"sample-image\"],\n        ].each do |name, full_name, new_value|\n          assert_equal(contents[full_name], image_item.__send__(name))\n          image_item.__send__(\"#{name}=\", new_value)\n          assert_equal(new_value, image_item.__send__(name))\n          image_item.__send__(\"#{name}=\", contents[full_name])\n          assert_equal(contents[full_name], image_item.__send__(name))\n        end\n      end\n    end\n\n    def test_favicon_to_s\n      favicon = @rss.channel.image_favicon\n      expected_xml = image_xmlns_container(make_element(\"#{@prefix}:favicon\",\n                                                        @favicon_attrs,\n                                                        @favicon_contents))\n      expected = REXML::Document.new(expected_xml)\n      actual_xml = image_xmlns_container(favicon.to_s(false, \"\"))\n      actual = REXML::Document.new(actual_xml)\n      assert_equal(expected.to_s, actual.to_s)\n    end\n\n    def test_item_to_s\n      @rss.items.each_with_index do |item, i|\n        attrs, contents = @items[i]\n        expected_xml = make_element(\"#{@prefix}:item\", attrs, contents)\n        expected_xml = image_xmlns_container(expected_xml)\n        expected = REXML::Document.new(expected_xml)\n        actual_xml = image_xmlns_container(item.image_item.to_s(false, \"\"))\n        actual = REXML::Document.new(actual_xml)\n\n        assert_equal(expected[0].attributes, actual[0].attributes)\n\n        %w(image:height image:width dc:title).each do |name|\n          actual_target = actual.elements[\"//#{name}\"]\n          expected_target = expected.elements[\"//#{name}\"]\n          assert_equal(expected_target.to_s, actual_target.to_s)\n        end\n      end\n    end\n\n    private\n    def image_xmlns_container(content)\n      xmlns_container({\n                        @prefix => @uri,\n                        \"dc\" => \"http://purl.org/dc/elements/1.1/\",\n                        \"rdf\" => \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n                      },\n                      content)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_inherit.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/1.0\"\n\nmodule RSS\n  class TestInherit < TestCase\n\n    class InheritedImage < RSS::RDF::Image\n      def self.indent_size; 1; end\n      def self.tag_name; 'image'; end\n    end\n\n    def setup\n      @rss = make_RDF(<<-EOR)\n#{make_channel}\n#{make_image}\n#{make_item}\n#{make_textinput}\nEOR\n    end\n\n    def test_inherit\n      rss = RSS::Parser.parse(@rss)\n      orig_image = rss.image\n      prefix = \"[INHERIT]\"\n      image = InheritedImage.new(\"#{prefix} #{orig_image.about}\")\n      image.title = \"#{prefix} #{orig_image.title}\"\n      image.url = \"#{prefix} #{orig_image.url}\"\n      image.link = \"#{prefix} #{orig_image.link}\"\n      rss.image = image\n\n      new_rss = RSS::Parser.parse(rss.to_s)\n      new_image = new_rss.image\n      assert_equal(\"#{prefix} #{orig_image.about}\", new_image.about)\n      assert_equal(\"#{prefix} #{orig_image.title}\", new_image.title)\n      assert_equal(\"#{prefix} #{orig_image.url}\", new_image.url)\n      assert_equal(\"#{prefix} #{orig_image.link}\", new_image.link)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_itunes.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/2.0\"\nrequire \"rss/itunes\"\n\nmodule RSS\n  class TestITunes < TestCase\n    def test_author\n      assert_itunes_author(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n\n      assert_itunes_author(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    def test_block\n      assert_itunes_block(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    def test_category\n      assert_itunes_category(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n    end\n\n    def test_image\n      assert_itunes_image(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n    end\n\n    def test_duration\n      assert_itunes_duration(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    def test_explicit\n      assert_itunes_explicit(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n\n      assert_itunes_explicit(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    def test_keywords\n      assert_itunes_keywords(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n\n      assert_itunes_keywords(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    def test_new_feed_url\n      assert_itunes_new_feed_url(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n    end\n\n    def test_owner\n      assert_itunes_owner(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n    end\n\n    def test_subtitle\n      assert_itunes_subtitle(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n\n      assert_itunes_subtitle(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    def test_summary\n      assert_itunes_summary(%w(channel)) do |content, xmlns|\n        make_rss20(make_channel20(content), xmlns)\n      end\n\n      assert_itunes_summary(%w(items last)) do |content, xmlns|\n        make_rss20(make_channel20(make_item20(content)), xmlns)\n      end\n    end\n\n    private\n    def itunes_rss20_parse(content, &maker)\n      xmlns = {\"itunes\" => \"http://www.itunes.com/dtds/podcast-1.0.dtd\"}\n      rss20_xml = maker.call(content, xmlns)\n      ::RSS::Parser.parse(rss20_xml)\n    end\n\n    def assert_itunes_author(readers, &rss20_maker)\n      _wrap_assertion do\n        author = \"John Lennon\"\n        rss20 = itunes_rss20_parse(tag(\"itunes:author\", author), &rss20_maker)\n        target = chain_reader(rss20, readers)\n        assert_equal(author, target.itunes_author)\n      end\n    end\n\n    def _assert_itunes_block(value, boolean_value, readers, &rss20_maker)\n      rss20 = itunes_rss20_parse(tag(\"itunes:block\", value), &rss20_maker)\n      target = chain_reader(rss20, readers)\n      assert_equal(value, target.itunes_block)\n      assert_equal(boolean_value, target.itunes_block?)\n    end\n\n    def assert_itunes_block(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_block(\"yes\", true, readers, &rss20_maker)\n        _assert_itunes_block(\"Yes\", true, readers, &rss20_maker)\n        _assert_itunes_block(\"no\", false, readers, &rss20_maker)\n        _assert_itunes_block(\"\", false, readers, &rss20_maker)\n      end\n    end\n\n    def _assert_itunes_category(categories, readers, &rss20_maker)\n      cats = categories.collect do |category|\n        if category.is_a?(Array)\n          category, sub_category = category\n          tag(\"itunes:category\",\n              tag(\"itunes:category\", nil, {\"text\" => sub_category}),\n              {\"text\" => category})\n        else\n          tag(\"itunes:category\", nil, {\"text\" => category})\n        end\n      end.join\n      rss20 = itunes_rss20_parse(cats, &rss20_maker)\n      target = chain_reader(rss20, readers)\n      actual_categories = target.itunes_categories.collect do |category|\n        cat = category.text\n        if category.itunes_categories.empty?\n          cat\n        else\n          [cat, *category.itunes_categories.collect {|c| c.text}]\n        end\n      end\n      assert_equal(categories, actual_categories)\n    end\n\n    def assert_itunes_category(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_category([\"Audio Blogs\"], readers, &rss20_maker)\n        _assert_itunes_category([[\"Arts & Entertainment\", \"Games\"]],\n                                readers, &rss20_maker)\n        _assert_itunes_category([[\"Arts & Entertainment\", \"Games\"],\n                                 [\"Technology\", \"Computers\"],\n                                 \"Audio Blogs\"],\n                                readers, &rss20_maker)\n      end\n    end\n\n    def assert_itunes_image(readers, &rss20_maker)\n      _wrap_assertion do\n        url = \"http://example.com/podcasts/everything/AllAboutEverything.jpg\"\n        content = tag(\"itunes:image\", nil, {\"href\" => url})\n        rss20 = itunes_rss20_parse(content, &rss20_maker)\n        target = chain_reader(rss20, readers)\n        assert_not_nil(target.itunes_image)\n        assert_equal(url, target.itunes_image.href)\n\n        assert_missing_attribute(\"image\", \"href\") do\n          content = tag(\"itunes:image\")\n          itunes_rss20_parse(content, &rss20_maker)\n        end\n      end\n    end\n\n    def _assert_itunes_duration(hour, minute, second, value,\n                                readers, &rss20_maker)\n      content = tag(\"itunes:duration\", value)\n      rss20 = itunes_rss20_parse(content, &rss20_maker)\n      duration = chain_reader(rss20, readers).itunes_duration\n      assert_equal(value, duration.content)\n      assert_equal(hour, duration.hour)\n      assert_equal(minute, duration.minute)\n      assert_equal(second, duration.second)\n    end\n\n    def _assert_itunes_duration_not_available_value(value, &rss20_maker)\n      assert_not_available_value(\"duration\", value) do\n        content = tag(\"itunes:duration\", value)\n        itunes_rss20_parse(content, &rss20_maker)\n      end\n    end\n\n    def assert_itunes_duration(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_duration(7, 14, 5, \"07:14:05\", readers, &rss20_maker)\n        _assert_itunes_duration(7, 14, 5, \"7:14:05\", readers, &rss20_maker)\n        _assert_itunes_duration(0, 4, 55, \"04:55\", readers, &rss20_maker)\n        _assert_itunes_duration(0, 4, 5, \"4:05\", readers, &rss20_maker)\n\n        _assert_itunes_duration_not_available_value(\"5\", &rss20_maker)\n        _assert_itunes_duration_not_available_value(\"09:07:14:05\", &rss20_maker)\n        _assert_itunes_duration_not_available_value(\"10:5\", &rss20_maker)\n        _assert_itunes_duration_not_available_value(\"10:03:5\", &rss20_maker)\n        _assert_itunes_duration_not_available_value(\"10:3:05\", &rss20_maker)\n\n        _assert_itunes_duration_not_available_value(\"xx:xx:xx\", &rss20_maker)\n      end\n    end\n\n    def _assert_itunes_explicit(explicit, value, readers, &rss20_maker)\n      content = tag(\"itunes:explicit\", value)\n      rss20 = itunes_rss20_parse(content, &rss20_maker)\n      target = chain_reader(rss20, readers)\n      assert_equal(value, target.itunes_explicit)\n      assert_equal(explicit, target.itunes_explicit?)\n    end\n\n    def assert_itunes_explicit(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_explicit(true, \"yes\", readers, &rss20_maker)\n        _assert_itunes_explicit(false, \"clean\", readers, &rss20_maker)\n        _assert_itunes_explicit(nil, \"no\", readers, &rss20_maker)\n      end\n    end\n\n    def _assert_itunes_keywords(keywords, value, readers, &rss20_maker)\n      content = tag(\"itunes:keywords\", value)\n      rss20 = itunes_rss20_parse(content, &rss20_maker)\n      target = chain_reader(rss20, readers)\n      assert_equal(keywords, target.itunes_keywords)\n    end\n\n    def assert_itunes_keywords(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_keywords([\"salt\"], \"salt\", readers, &rss20_maker)\n        _assert_itunes_keywords([\"salt\"], \" salt \", readers, &rss20_maker)\n        _assert_itunes_keywords([\"salt\", \"pepper\", \"shaker\", \"exciting\"],\n                                \"salt, pepper, shaker, exciting\",\n                                readers, &rss20_maker)\n        _assert_itunes_keywords([\"metric\", \"socket\", \"wrenches\", \"toolsalt\"],\n                                \"metric, socket, wrenches, toolsalt\",\n                                readers, &rss20_maker)\n        _assert_itunes_keywords([\"olitics\", \"red\", \"blue\", \"state\"],\n                                \"olitics, red, blue, state\",\n                                readers, &rss20_maker)\n      end\n    end\n\n    def assert_itunes_new_feed_url(readers, &rss20_maker)\n      _wrap_assertion do\n        url = \"http://newlocation.com/example.rss\"\n        content = tag(\"itunes:new-feed-url\", url)\n        rss20 = itunes_rss20_parse(content, &rss20_maker)\n        target = chain_reader(rss20, readers)\n        assert_equal(url, target.itunes_new_feed_url)\n      end\n    end\n\n    def _assert_itunes_owner(name, email, readers, &rss20_maker)\n      content = tag(\"itunes:owner\",\n                    tag(\"itunes:name\", name) + tag(\"itunes:email\", email))\n      rss20 = itunes_rss20_parse(content, &rss20_maker)\n      owner = chain_reader(rss20, readers).itunes_owner\n      assert_equal(name, owner.itunes_name)\n      assert_equal(email, owner.itunes_email)\n    end\n\n    def assert_itunes_owner(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_owner(\"John Doe\", \"john.doe@example.com\",\n                             readers, &rss20_maker)\n\n        assert_missing_tag(\"name\", \"owner\")  do\n          content = tag(\"itunes:owner\")\n          itunes_rss20_parse(content, &rss20_maker)\n        end\n\n        assert_missing_tag(\"name\", \"owner\")  do\n          content = tag(\"itunes:owner\",\n                        tag(\"itunes:email\", \"john.doe@example.com\"))\n          itunes_rss20_parse(content, &rss20_maker)\n        end\n\n        assert_missing_tag(\"email\", \"owner\")  do\n          content = tag(\"itunes:owner\", tag(\"itunes:name\", \"John Doe\"))\n          itunes_rss20_parse(content, &rss20_maker)\n        end\n      end\n    end\n\n    def _assert_itunes_subtitle(value, readers, &rss20_maker)\n      content = tag(\"itunes:subtitle\", value)\n      rss20 = itunes_rss20_parse(content, &rss20_maker)\n      target = chain_reader(rss20, readers)\n      assert_equal(value, target.itunes_subtitle)\n    end\n\n    def assert_itunes_subtitle(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_subtitle(\"A show about everything\", readers, &rss20_maker)\n        _assert_itunes_subtitle(\"A short primer on table spices\",\n                                readers, &rss20_maker)\n        _assert_itunes_subtitle(\"Comparing socket wrenches is fun!\",\n                                readers, &rss20_maker)\n        _assert_itunes_subtitle(\"Red + Blue != Purple\", readers, &rss20_maker)\n      end\n    end\n\n    def _assert_itunes_summary(value, readers, &rss20_maker)\n      content = tag(\"itunes:summary\", value)\n      rss20 = itunes_rss20_parse(content, &rss20_maker)\n      target = chain_reader(rss20, readers)\n      assert_equal(value, target.itunes_summary)\n    end\n\n    def assert_itunes_summary(readers, &rss20_maker)\n      _wrap_assertion do\n        _assert_itunes_summary(\"All About Everything is a show about \" +\n                               \"everything. Each week we dive into any \" +\n                               \"subject known to man and talk about it as \" +\n                               \"much as we can. Look for our Podcast in \" +\n                               \"the iTunes Music Store\",\n                               readers, &rss20_maker)\n        _assert_itunes_summary(\"This week we talk about salt and pepper \" +\n                               \"shakers, comparing and contrasting pour \" +\n                               \"rates, construction materials, and overall \" +\n                               \"aesthetics. Come and join the party!\",\n                               readers, &rss20_maker)\n        _assert_itunes_summary(\"This week we talk about metric vs. old \" +\n                               \"english socket wrenches. Which one is \" +\n                               \"better? Do you really need both? Get all \" +\n                               \"of your answers here.\",\n                               readers, &rss20_maker)\n        _assert_itunes_summary(\"This week we talk about surviving in a \" +\n                               \"Red state if you're a Blue person. Or \" +\n                               \"vice versa.\",\n                               readers, &rss20_maker)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_0.9.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMaker09 < TestCase\n\n    def test_rss\n      rss = RSS::Maker.make(\"0.91\")\n      assert_nil(rss)\n      \n      rss = RSS::Maker.make(\"0.9\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n      end\n      assert_equal(\"0.92\", rss.rss_version)\n      \n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n      end\n      assert_equal(\"0.91\", rss.rss_version)\n\n      \n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.encoding = \"EUC-JP\"\n      end\n      assert_equal(\"0.91\", rss.rss_version)\n      assert_equal(\"EUC-JP\", rss.encoding)\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.standalone = \"yes\"\n      end\n      assert_equal(\"0.91\", rss.rss_version)\n      assert_equal(\"yes\", rss.standalone)\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.encoding = \"EUC-JP\"\n        maker.standalone = \"yes\"\n      end\n      assert_equal(\"0.91\", rss.rss_version)\n      assert_equal(\"EUC-JP\", rss.encoding)\n      assert_equal(\"yes\", rss.standalone)\n    end\n\n    def test_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n      copyright = \"foo\"\n      managingEditor = \"bar\"\n      webMaster = \"web master\"\n      rating = '(PICS-1.1 \"http://www.rsac.org/ratingsv01.html\" l gen true comment \"RSACi North America Server\" for \"http://www.rsac.org\" on \"1996.04.16T08:15-0500\" r (n 0 s 0 v 0 l 0))'\n      docs = \"http://foo.com/doc\"\n      skipDays = [\n        \"Sunday\",\n        \"Monday\",\n      ]\n      skipHours = [\n        \"0\",\n        \"13\",\n      ]\n      pubDate = Time.now\n      lastBuildDate = Time.now\n\n      image_url = \"http://example.com/logo.png\"\n      image_title = \"Logo\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n        maker.channel.language = language\n        maker.channel.copyright = copyright\n        maker.channel.managingEditor = managingEditor\n        maker.channel.webMaster = webMaster\n        maker.channel.rating = rating\n        maker.channel.docs = docs\n        maker.channel.pubDate = pubDate\n        maker.channel.lastBuildDate = lastBuildDate\n\n        skipDays.each do |day|\n          maker.channel.skipDays.new_day do |new_day|\n            new_day.content = day\n          end\n        end\n        skipHours.each do |hour|\n          maker.channel.skipHours.new_hour do |new_hour|\n            new_hour.content = hour\n          end\n        end\n\n        maker.image.url = image_url\n        maker.image.title = image_title\n      end\n      channel = rss.channel\n      \n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(language, channel.language)\n      assert_equal(copyright, channel.copyright)\n      assert_equal(managingEditor, channel.managingEditor)\n      assert_equal(webMaster, channel.webMaster)\n      assert_equal(rating, channel.rating)\n      assert_equal(docs, channel.docs)\n      assert_equal(pubDate, channel.pubDate)\n      assert_equal(pubDate, channel.date)\n      assert_equal(lastBuildDate, channel.lastBuildDate)\n\n      skipDays.each_with_index do |day, i|\n        assert_equal(day, channel.skipDays.days[i].content)\n      end\n      skipHours.each_with_index do |hour, i|\n        assert_equal(hour.to_i, channel.skipHours.hours[i].content)\n      end\n      \n      assert(channel.items.empty?)\n\n      assert_equal(image_url, channel.image.url)\n      assert_equal(image_title, channel.image.title)\n      assert_equal(link, channel.image.link)\n\n      assert_nil(channel.textInput)\n    end\n\n    def test_not_valid_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n\n      assert_not_set_error(\"maker.channel\", %w(title)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          # maker.channel.title = title\n          maker.channel.link = link\n          maker.channel.description = description\n          maker.channel.language = language\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(link)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          maker.channel.title = title\n          # maker.channel.link = link\n          maker.channel.link = nil\n          maker.channel.description = description\n          maker.channel.language = language\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(description)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          maker.channel.title = title\n          maker.channel.link = link\n          # maker.channel.description = description\n          maker.channel.language = language\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(language)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          maker.channel.title = title\n          maker.channel.link = link\n          maker.channel.description = description\n          # maker.channel.language = language\n        end\n      end\n    end\n    \n    def test_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      width = \"144\"\n      height = \"400\"\n      description = \"an image\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        maker.image.url = url\n        maker.image.width = width\n        maker.image.height = height\n        maker.image.description = description\n      end\n      image = rss.image\n      assert_equal(title, image.title)\n      assert_equal(link, image.link)\n      assert_equal(url, image.url)\n      assert_equal(width.to_i, image.width)\n      assert_equal(height.to_i, image.height)\n      assert_equal(description, image.description)\n\n      assert_not_set_error(\"maker.channel\", %w(description title language)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          # setup_dummy_channel(maker)\n          maker.channel.link = link\n        \n          maker.image.title = title\n          maker.image.url = url\n          maker.image.width = width\n          maker.image.height = height\n          maker.image.description = description\n        end\n      end\n    end\n\n    def test_not_valid_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      width = \"144\"\n      height = \"400\"\n      description = \"an image\"\n\n      assert_not_set_error(\"maker.image\", %w(title)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          setup_dummy_channel(maker)\n          maker.channel.link = link\n\n          # maker.image.title = title\n          maker.image.url = url\n          maker.image.width = width\n          maker.image.height = height\n          maker.image.description = description\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(link)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          setup_dummy_channel(maker)\n          # maker.channel.link = link\n          maker.channel.link = nil\n        \n          maker.image.title = title\n          maker.image.url = url\n          maker.image.width = width\n          maker.image.height = height\n          maker.image.description = description\n        end\n      end\n\n      assert_not_set_error(\"maker.image\", %w(url)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          setup_dummy_channel(maker)\n          maker.channel.link = link\n\n          maker.image.title = title\n          # maker.image.url = url\n          maker.image.width = width\n          maker.image.height = height\n          maker.image.description = description\n        end\n      end\n    end\n    \n    def test_items(with_convenience_way=true)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n      end\n      assert(rss.channel.items.empty?)\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.items.new_item do |item|\n          item.title = title\n          item.link = link\n          # item.description = description\n        end\n\n        setup_dummy_image(maker)\n      end\n      assert_equal(1, rss.channel.items.size)\n      item = rss.channel.items.first\n      assert_equal(title, item.title)\n      assert_equal(link, item.link)\n      assert_nil(item.description)\n\n\n      item_size = 5\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |_item|\n            _item.title = \"#{title}#{i}\"\n            _item.link = \"#{link}#{i}\"\n            _item.description = \"#{description}#{i}\"\n          end\n        end\n        maker.items.do_sort = true\n\n        setup_dummy_image(maker)\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.channel.items.each_with_index do |_item, i|\n        assert_equal(\"#{title}#{i}\", _item.title)\n        assert_equal(\"#{link}#{i}\", _item.link)\n        assert_equal(\"#{description}#{i}\", _item.description)\n      end\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |_item|\n            _item.title = \"#{title}#{i}\"\n            _item.link = \"#{link}#{i}\"\n            _item.description = \"#{description}#{i}\"\n          end\n        end\n        maker.items.do_sort = Proc.new do |x, y|\n          if with_convenience_way\n            y.title[-1] <=> x.title[-1]\n          else\n            y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}\n          end\n        end\n\n        setup_dummy_image(maker)\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.channel.items.reverse.each_with_index do |_item, i|\n        assert_equal(\"#{title}#{i}\", _item.title)\n        assert_equal(\"#{link}#{i}\", _item.link)\n        assert_equal(\"#{description}#{i}\", _item.description)\n      end\n    end\n\n    def test_items_with_new_api_since_018\n      test_items(false)\n    end\n\n    def test_textInput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      textInput = rss.channel.textInput\n      assert_equal(title, textInput.title)\n      assert_equal(description, textInput.description)\n      assert_equal(name, textInput.name)\n      assert_equal(link, textInput.link)\n\n      assert_not_set_error(\"maker.channel\",\n                           %w(link language description title)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          # setup_dummy_channel(maker)\n\n          maker.textinput.title = title\n          maker.textinput.description = description\n          maker.textinput.name = name\n          maker.textinput.link = link\n        end\n      end\n    end\n    \n    def test_not_valid_textInput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        # maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.textinput.title = title\n        # maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.textinput.title = title\n        maker.textinput.description = description\n        # maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        # maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_1.0.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMaker10 < TestCase\n\n    def test_rdf\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n      end\n      assert_equal(\"1.0\", rss.rss_version)\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.encoding = \"EUC-JP\"\n\n        setup_dummy_item(maker)\n      end\n      assert_equal(\"1.0\", rss.rss_version)\n      assert_equal(\"EUC-JP\", rss.encoding)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.standalone = \"yes\"\n\n        setup_dummy_item(maker)\n      end\n      assert_equal(\"1.0\", rss.rss_version)\n      assert_equal(\"yes\", rss.standalone)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.encoding = \"EUC-JP\"\n        maker.standalone = \"yes\"\n\n        setup_dummy_item(maker)\n      end\n      assert_equal(\"1.0\", rss.rss_version)\n      assert_equal(\"EUC-JP\", rss.encoding)\n      assert_equal(\"yes\", rss.standalone)\n    end\n\n    def test_channel\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n\n      rss = RSS::Maker.make(\"1.0\")\n      assert_nil(rss)\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.channel.about = about\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n\n        setup_dummy_item(maker)\n      end\n      channel = rss.channel\n      assert_equal(about, channel.about)\n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(1, channel.items.Seq.lis.size)\n      assert_nil(channel.image)\n      assert_nil(channel.textinput)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.channel.about = about\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n\n        setup_dummy_image(maker)\n\n        setup_dummy_textinput(maker)\n\n        setup_dummy_item(maker)\n      end\n      channel = rss.channel\n      assert_equal(about, channel.about)\n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(1, channel.items.Seq.lis.size)\n      assert_equal(rss.image.about, channel.image.resource)\n      assert_equal(rss.textinput.about, channel.textinput.resource)\n    end\n\n    def test_not_valid_channel\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n\n      assert_not_set_error(\"maker.channel\", %w(about)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          # maker.channel.about = about\n          maker.channel.title = title\n          maker.channel.link = link\n          maker.channel.description = description\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(title)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          maker.channel.about = about\n          # maker.channel.title = title\n          maker.channel.link = link\n          maker.channel.description = description\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(link)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          maker.channel.about = about\n          maker.channel.title = title\n          # maker.channel.link = link\n          maker.channel.description = description\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(description)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          maker.channel.about = about\n          maker.channel.title = title\n          maker.channel.link = link\n          # maker.channel.description = description\n        end\n      end\n    end\n    \n    \n    def test_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        maker.image.url = url\n\n        setup_dummy_item(maker)\n      end\n      image = rss.image\n      assert_equal(url, image.about)\n      assert_equal(url, rss.channel.image.resource)\n      assert_equal(title, image.title)\n      assert_equal(link, image.link)\n      assert_equal(url, image.url)\n\n      assert_not_set_error(\"maker.channel\", %w(about title description)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          # setup_dummy_channel(maker)\n          maker.channel.link = link\n          \n          maker.image.title = title\n          maker.image.url = url\n        end\n      end\n    end\n\n    def test_not_valid_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        # maker.image.url = url\n        maker.image.title = title\n\n        setup_dummy_item(maker)\n      end\n      assert_nil(rss.channel.image)\n      assert_nil(rss.image)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.url = url\n        # maker.image.title = title\n\n        setup_dummy_item(maker)\n      end\n      assert_nil(rss.channel.image)\n      assert_nil(rss.image)\n\n      assert_not_set_error(\"maker.channel\", %w(link)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          setup_dummy_channel(maker)\n          # maker.channel.link = link\n          maker.channel.link = nil\n          \n          maker.image.url = url\n          maker.image.title = title\n\n          setup_dummy_item(maker)\n        end\n      end\n    end\n\n    def test_items(with_convenience_way=true)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n\n      assert_not_set_error(\"maker\", %w(items)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          setup_dummy_channel(maker)\n        end\n      end\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.items.new_item do |item|\n          item.title = title\n          item.link = link\n          # item.description = description\n        end\n      end\n      assert_equal(1, rss.items.size)\n      item = rss.items.first\n      assert_equal(link, item.about)\n      assert_equal(title, item.title)\n      assert_equal(link, item.link)\n      assert_nil(item.description)\n\n      \n      item_size = 5\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |_item|\n            _item.title = \"#{title}#{i}\"\n            _item.link = \"#{link}#{i}\"\n            _item.description = \"#{description}#{i}\"\n          end\n        end\n        maker.items.do_sort = true\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.items.each_with_index do |_item, i|\n        assert_equal(\"#{link}#{i}\", _item.about)\n        assert_equal(\"#{title}#{i}\", _item.title)\n        assert_equal(\"#{link}#{i}\", _item.link)\n        assert_equal(\"#{description}#{i}\", _item.description)\n      end\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |_item|\n            _item.title = \"#{title}#{i}\"\n            _item.link = \"#{link}#{i}\"\n            _item.description = \"#{description}#{i}\"\n          end\n        end\n        maker.items.do_sort = Proc.new do |x, y|\n          if with_convenience_way\n            y.title[-1] <=> x.title[-1]\n          else\n            y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}\n          end\n        end\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.items.reverse.each_with_index do |_item, i|\n        assert_equal(\"#{link}#{i}\", _item.about)\n        assert_equal(\"#{title}#{i}\", _item.title)\n        assert_equal(\"#{link}#{i}\", _item.link)\n        assert_equal(\"#{description}#{i}\", _item.description)\n      end\n\n      max_size = item_size / 2\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |_item|\n            _item.title = \"#{title}#{i}\"\n            _item.link = \"#{link}#{i}\"\n            _item.description = \"#{description}#{i}\"\n          end\n        end\n        maker.items.max_size = max_size\n      end\n      assert_equal(max_size, rss.items.size)\n      rss.items.each_with_index do |_item, i|\n        assert_equal(\"#{link}#{i}\", _item.about)\n        assert_equal(\"#{title}#{i}\", _item.title)\n        assert_equal(\"#{link}#{i}\", _item.link)\n        assert_equal(\"#{description}#{i}\", _item.description)\n      end\n\n      max_size = 0\n      assert_not_set_error(\"maker\", %w(items)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          setup_dummy_channel(maker)\n\n          item_size.times do |i|\n            maker.items.new_item do |_item|\n              _item.title = \"#{title}#{i}\"\n              _item.link = \"#{link}#{i}\"\n              _item.description = \"#{description}#{i}\"\n            end\n          end\n          maker.items.max_size = max_size\n        end\n      end\n\n      max_size = -2\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |_item|\n            _item.title = \"#{title}#{i}\"\n            _item.link = \"#{link}#{i}\"\n            _item.description = \"#{description}#{i}\"\n          end\n        end\n        maker.items.max_size = max_size\n      end\n      assert_equal(item_size + max_size + 1, rss.items.size)\n      rss.items.each_with_index do |_item, i|\n        assert_equal(\"#{link}#{i}\", _item.about)\n        assert_equal(\"#{title}#{i}\", _item.title)\n        assert_equal(\"#{link}#{i}\", _item.link)\n        assert_equal(\"#{description}#{i}\", _item.description)\n      end\n    end\n\n    def test_items_with_new_api_since_018\n      test_items(false)\n    end\n\n    def test_not_valid_items\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n\n      assert_not_set_error(\"maker.item\", %w(title)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          setup_dummy_channel(maker)\n\n          maker.items.new_item do |item|\n            # item.title = title\n            item.link = link\n          end\n        end\n      end\n\n      assert_not_set_error(\"maker.item\", %w(link)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          setup_dummy_channel(maker)\n\n          maker.items.new_item do |item|\n            item.title = title\n            # item.link = link\n          end\n        end\n      end\n\n      assert_not_set_error(\"maker.item\", %w(title link)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          setup_dummy_channel(maker)\n\n          maker.items.new_item do |item|\n            # item.title = title\n            # item.link = link\n          end\n        end\n      end\n    end\n\n    def test_textinput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.link = link\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n\n        setup_dummy_item(maker)\n      end\n      textinput = rss.textinput\n      assert_equal(link, textinput.about)\n      assert_equal(link, rss.channel.textinput.resource)\n      assert_equal(title, textinput.title)\n      assert_equal(name, textinput.name)\n      assert_equal(description, textinput.description)\n      assert_equal(link, textinput.link)\n\n      assert_not_set_error(\"maker.channel\", %w(about link description title)) do\n        RSS::Maker.make(\"1.0\") do |maker|\n          # setup_dummy_channel(maker)\n\n          maker.textinput.link = link\n          maker.textinput.title = title\n          maker.textinput.description = description\n          maker.textinput.name = name\n        end\n      end\n    end\n    \n    def test_not_valid_textinput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        # maker.textinput.link = link\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n\n        setup_dummy_item(maker)\n      end\n      assert_nil(rss.channel.textinput)\n      assert_nil(rss.textinput)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.link = link\n        # maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n\n        setup_dummy_item(maker)\n      end\n      assert_nil(rss.channel.textinput)\n      assert_nil(rss.textinput)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.link = link\n        maker.textinput.title = title\n        # maker.textinput.description = description\n        maker.textinput.name = name\n\n        setup_dummy_item(maker)\n      end\n      assert_nil(rss.channel.textinput)\n      assert_nil(rss.textinput)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.link = link\n        maker.textinput.title = title\n        maker.textinput.description = description\n        # maker.textinput.name = name\n\n        setup_dummy_item(maker)\n      end\n      assert_nil(rss.channel.textinput)\n      assert_nil(rss.textinput)\n    end\n\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_2.0.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMaker20 < TestCase\n\n    def test_rss\n      rss = RSS::Maker.make(\"2.0\")\n      assert_nil(rss)\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n      end\n      assert_equal(\"2.0\", rss.rss_version)\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.encoding = \"EUC-JP\"\n      end\n      assert_equal(\"2.0\", rss.rss_version)\n      assert_equal(\"EUC-JP\", rss.encoding)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.standalone = \"yes\"\n      end\n      assert_equal(\"2.0\", rss.rss_version)\n      assert_equal(\"yes\", rss.standalone)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.encoding = \"EUC-JP\"\n        maker.standalone = \"yes\"\n      end\n      assert_equal(\"2.0\", rss.rss_version)\n      assert_equal(\"EUC-JP\", rss.encoding)\n      assert_equal(\"yes\", rss.standalone)\n    end\n\n    def test_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n      copyright = \"foo\"\n      managingEditor = \"bar\"\n      webMaster = \"web master\"\n      rating = '(PICS-1.1 \"http://www.rsac.org/ratingsv01.html\" l gen true comment \"RSACi North America Server\" for \"http://www.rsac.org\" on \"1996.04.16T08:15-0500\" r (n 0 s 0 v 0 l 0))'\n      docs = \"http://foo.com/doc\"\n      skipDays = [\n        \"Sunday\",\n        \"Monday\",\n      ]\n      skipHours = [\n        \"0\",\n        \"13\",\n      ]\n      pubDate = Time.now\n      lastBuildDate = Time.now\n      categories = [\n        \"Nespapers\",\n        \"misc\",\n      ]\n      generator = \"RSS Maker\"\n      ttl = \"60\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n        maker.channel.language = language\n        maker.channel.copyright = copyright\n        maker.channel.managingEditor = managingEditor\n        maker.channel.webMaster = webMaster\n        maker.channel.rating = rating\n        maker.channel.docs = docs\n        maker.channel.pubDate = pubDate\n        maker.channel.lastBuildDate = lastBuildDate\n\n        skipDays.each do |day|\n          maker.channel.skipDays.new_day do |new_day|\n            new_day.content = day\n          end\n        end\n        skipHours.each do |hour|\n          maker.channel.skipHours.new_hour do |new_hour|\n            new_hour.content = hour\n          end\n        end\n        \n        categories.each do |category|\n          maker.channel.categories.new_category do |new_category|\n            new_category.content = category\n          end\n        end\n        \n        maker.channel.generator = generator\n        maker.channel.ttl = ttl\n      end\n      channel = rss.channel\n      \n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(language, channel.language)\n      assert_equal(copyright, channel.copyright)\n      assert_equal(managingEditor, channel.managingEditor)\n      assert_equal(webMaster, channel.webMaster)\n      assert_equal(rating, channel.rating)\n      assert_equal(docs, channel.docs)\n      assert_equal(pubDate, channel.pubDate)\n      assert_equal(pubDate, channel.date)\n      assert_equal(lastBuildDate, channel.lastBuildDate)\n\n      skipDays.each_with_index do |day, i|\n        assert_equal(day, channel.skipDays.days[i].content)\n      end\n      skipHours.each_with_index do |hour, i|\n        assert_equal(hour.to_i, channel.skipHours.hours[i].content)\n      end\n      \n      channel.categories.each_with_index do |category, i|\n        assert_equal(categories[i], category.content)\n      end\n      \n      assert_equal(generator, channel.generator)\n      assert_equal(ttl.to_i, channel.ttl)\n\n      assert(channel.items.empty?)\n      assert_nil(channel.image)\n      assert_nil(channel.textInput)\n    end\n\n    def test_not_valid_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n      \n      assert_not_set_error(\"maker.channel\", %w(title)) do\n        RSS::Maker.make(\"2.0\") do |maker|\n          # maker.channel.title = title\n          maker.channel.link = link\n          maker.channel.description = description\n          maker.channel.language = language\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(link)) do\n        RSS::Maker.make(\"2.0\") do |maker|\n          maker.channel.title = title\n          # maker.channel.link = link\n          maker.channel.description = description\n          maker.channel.language = language\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(description)) do\n        RSS::Maker.make(\"2.0\") do |maker|\n          maker.channel.title = title\n          maker.channel.link = link\n          # maker.channel.description = description\n          maker.channel.language = language\n        end\n      end\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n        # maker.channel.language = language\n      end\n      assert_not_nil(rss)\n    end\n\n    \n    def test_cloud\n      domain = \"rpc.sys.com\"\n      port = \"80\"\n      path = \"/RPC2\"\n      registerProcedure = \"myCloud.rssPleaseNotify\"\n      protocol = \"xml-rpc\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.channel.cloud.domain = domain\n        maker.channel.cloud.port = port\n        maker.channel.cloud.path = path\n        maker.channel.cloud.registerProcedure = registerProcedure\n        maker.channel.cloud.protocol = protocol\n      end\n      cloud = rss.channel.cloud\n      assert_equal(domain, cloud.domain)\n      assert_equal(port.to_i, cloud.port)\n      assert_equal(path, cloud.path)\n      assert_equal(registerProcedure, cloud.registerProcedure)\n      assert_equal(protocol, cloud.protocol)\n    end\n    \n    def test_not_valid_cloud\n      domain = \"rpc.sys.com\"\n      port = \"80\"\n      path = \"/RPC2\"\n      registerProcedure = \"myCloud.rssPleaseNotify\"\n      protocol = \"xml-rpc\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        # maker.channel.cloud.domain = domain\n        maker.channel.cloud.port = port\n        maker.channel.cloud.path = path\n        maker.channel.cloud.registerProcedure = registerProcedure\n        maker.channel.cloud.protocol = protocol\n      end\n      assert_nil(rss.channel.cloud)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.channel.cloud.domain = domain\n        # maker.channel.cloud.port = port\n        maker.channel.cloud.path = path\n        maker.channel.cloud.registerProcedure = registerProcedure\n        maker.channel.cloud.protocol = protocol\n      end\n      assert_nil(rss.channel.cloud)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.channel.cloud.domain = domain\n        maker.channel.cloud.port = port\n        # maker.channel.cloud.path = path\n        maker.channel.cloud.registerProcedure = registerProcedure\n        maker.channel.cloud.protocol = protocol\n      end\n      assert_nil(rss.channel.cloud)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.channel.cloud.domain = domain\n        maker.channel.cloud.port = port\n        maker.channel.cloud.path = path\n        # maker.channel.cloud.registerProcedure = registerProcedure\n        maker.channel.cloud.protocol = protocol\n      end\n      assert_nil(rss.channel.cloud)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.channel.cloud.domain = domain\n        maker.channel.cloud.port = port\n        maker.channel.cloud.path = path\n        maker.channel.cloud.registerProcedure = registerProcedure\n        # maker.channel.cloud.protocol = protocol\n      end\n      assert_nil(rss.channel.cloud)\n    end\n    \n\n    def test_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      width = \"144\"\n      height = \"400\"\n      description = \"an image\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        maker.image.url = url\n        maker.image.width = width\n        maker.image.height = height\n        maker.image.description = description\n      end\n      image = rss.image\n      assert_equal(title, image.title)\n      assert_equal(link, image.link)\n      assert_equal(url, image.url)\n      assert_equal(width.to_i, image.width)\n      assert_equal(height.to_i, image.height)\n      assert_equal(description, image.description)\n\n      assert_not_set_error(\"maker.channel\", %w(title description)) do\n        RSS::Maker.make(\"2.0\") do |maker|\n          # setup_dummy_channel(maker)\n          maker.channel.link = link\n        \n          maker.image.title = title\n          maker.image.url = url\n          maker.image.width = width\n          maker.image.height = height\n          maker.image.description = description\n        end\n      end\n    end\n\n    def test_not_valid_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      width = \"144\"\n      height = \"400\"\n      description = \"an image\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        # maker.image.title = title\n        maker.image.url = url\n        maker.image.width = width\n        maker.image.height = height\n        maker.image.description = description\n      end\n      assert_nil(rss.image)\n\n      assert_not_set_error(\"maker.channel\", %w(link)) do\n        RSS::Maker.make(\"2.0\") do |maker|\n          setup_dummy_channel(maker)\n          # maker.channel.link = link\n          maker.channel.link = nil\n        \n          maker.image.title = title\n          maker.image.url = url\n          maker.image.width = width\n          maker.image.height = height\n          maker.image.description = description\n        end\n      end\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        # maker.image.url = url\n        maker.image.width = width\n        maker.image.height = height\n        maker.image.description = description\n      end\n      assert_nil(rss.image)\n    end\n    \n    def test_items(with_convenience_way=true)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n      author = \"oprah@oxygen.net\"\n      comments = \"http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290\"\n      pubDate = Time.now\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n      end\n      assert(rss.channel.items.empty?)\n\n      item_size = 5\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n            item.author = \"#{author}#{i}\"\n            item.comments = \"#{comments}#{i}\"\n            item.date = pubDate\n          end\n        end\n        maker.items.do_sort = true\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.channel.items.each_with_index do |item, i|\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n        assert_equal(\"#{author}#{i}\", item.author)\n        assert_equal(\"#{comments}#{i}\", item.comments)\n        assert_equal(pubDate, item.pubDate)\n        assert_equal(pubDate, item.date)\n      end\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n            item.author = \"#{author}#{i}\"\n            item.comments = \"#{comments}#{i}\"\n            item.date = pubDate\n          end\n        end\n        maker.items.do_sort = Proc.new do |x, y|\n          if with_convenience_way\n            y.title[-1] <=> x.title[-1]\n          else\n            y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}\n          end\n        end\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.channel.items.reverse.each_with_index do |item, i|\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n        assert_equal(\"#{author}#{i}\", item.author)\n        assert_equal(\"#{comments}#{i}\", item.comments)\n        assert_equal(pubDate, item.pubDate)\n        assert_equal(pubDate, item.date)\n      end\n    end\n\n    def test_items_with_new_api_since_018\n      test_items(false)\n    end\n\n    def test_pubDate_without_description\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n      author = \"oprah@oxygen.net\"\n      pubDate = Time.now\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.items.new_item do |item|\n          item.title = title\n          item.link = link\n          # item.description = description\n          item.author = author\n          item.pubDate = pubDate\n        end\n      end\n      assert_equal(1, rss.items.size)\n      rss.channel.items.each_with_index do |item, i|\n        assert_equal(title, item.title)\n        assert_equal(link, item.link)\n        # assert_equal(description, item.description)\n        assert_equal(author, item.author)\n        assert_equal(pubDate, item.pubDate)\n        assert_equal(pubDate, item.date)\n      end\n    end\n\n    def test_guid\n      isPermaLink = \"true\"\n      content = \"http://inessential.com/2002/09/01.php#a2\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        guid = maker.items.last.guid\n        guid.isPermaLink = isPermaLink\n        guid.content = content\n      end\n      guid = rss.channel.items.last.guid\n      assert_equal(isPermaLink == \"true\", guid.isPermaLink)\n      assert_equal(content, guid.content)\n    end\n\n    def test_not_valid_guid\n      content = \"http://inessential.com/2002/09/01.php#a2\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        guid = maker.items.last.guid\n        # guid.content = content\n      end\n      assert_nil(rss.channel.items.last.guid)\n    end\n    \n    def test_enclosure\n      url = \"http://www.scripting.com/mp3s/weatherReportSuite.mp3\"\n      length = \"12216320\"\n      type = \"audio/mpeg\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        enclosure = maker.items.last.enclosure\n        enclosure.url = url\n        enclosure.length = length\n        enclosure.type = type\n      end\n      enclosure = rss.channel.items.last.enclosure\n      assert_equal(url, enclosure.url)\n      assert_equal(length.to_i, enclosure.length)\n      assert_equal(type, enclosure.type)\n    end\n\n    def test_not_valid_enclosure\n      url = \"http://www.scripting.com/mp3s/weatherReportSuite.mp3\"\n      length = \"12216320\"\n      type = \"audio/mpeg\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        enclosure = maker.items.last.enclosure\n        # enclosure.url = url\n        enclosure.length = length\n        enclosure.type = type\n      end\n      assert_nil(rss.channel.items.last.enclosure)\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        enclosure = maker.items.last.enclosure\n        enclosure.url = url\n        # enclosure.length = length\n        enclosure.type = type\n      end\n      assert_nil(rss.channel.items.last.enclosure)\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        enclosure = maker.items.last.enclosure\n        enclosure.url = url\n        enclosure.length = length\n        # enclosure.type = type\n      end\n      assert_nil(rss.channel.items.last.enclosure)\n    end\n\n\n    def test_source\n      url = \"http://static.userland.com/tomalak/links2.xml\"\n      content = \"Tomalak's Realm\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        source = maker.items.last.source\n        source.url = url\n        source.content = content\n      end\n      source = rss.channel.items.last.source\n      assert_equal(url, source.url)\n      assert_equal(content, source.content)\n    end\n\n    def test_not_valid_source\n      url = \"http://static.userland.com/tomalak/links2.xml\"\n      content = \"Tomalak's Realm\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        source = maker.items.last.source\n        # source.url = url\n        source.content = content\n      end\n      assert_nil(rss.channel.items.last.source)\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        source = maker.items.last.source\n        source.url = url\n        # source.content = content\n      end\n      assert_nil(rss.channel.items.last.source)\n    end\n    \n    def test_category\n      domain = \"http://www.fool.com/cusips\"\n      content = \"MSFT\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        maker.items.last.categories.new_category do |category|\n          category.domain = domain\n          category.content = content\n        end\n      end\n      category = rss.channel.items.last.categories.last\n      assert_equal(domain, category.domain)\n      assert_equal(content, category.content)\n    end\n\n    def test_not_valid_category\n      content = \"Grateful Dead\"\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        maker.items.last.categories.new_category do |category|\n          # category.content = content\n        end\n      end\n      assert(rss.channel.items.last.categories.empty?)\n    end\n    \n    def test_textInput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      textInput = rss.channel.textInput\n      assert_equal(title, textInput.title)\n      assert_equal(description, textInput.description)\n      assert_equal(name, textInput.name)\n      assert_equal(link, textInput.link)\n\n      assert_not_set_error(\"maker.channel\", %w(link description title)) do\n        RSS::Maker.make(\"2.0\") do |maker|\n          # setup_dummy_channel(maker)\n\n          maker.textinput.title = title\n          maker.textinput.description = description\n          maker.textinput.name = name\n          maker.textinput.link = link\n        end\n      end\n    end\n    \n    def test_not_valid_textInput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        # maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.title = title\n        # maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.title = title\n        maker.textinput.description = description\n        # maker.textinput.name = name\n        maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        # maker.textinput.link = link\n      end\n      assert_nil(rss.channel.textInput)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_atom_entry.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerAtomEntry < TestCase\n    def test_root_element\n      entry = Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n      assert_equal([\"atom\", \"1.0\", \"entry\"], entry.feed_info)\n\n      entry = Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.encoding = \"EUC-JP\"\n      end\n      assert_equal([\"atom\", \"1.0\", \"entry\"], entry.feed_info)\n      assert_equal(\"EUC-JP\", entry.encoding)\n\n      entry = Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.standalone = \"yes\"\n      end\n      assert_equal([\"atom\", \"1.0\", \"entry\"], entry.feed_info)\n      assert_equal(\"yes\", entry.standalone)\n\n      entry = Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.encoding = \"EUC-JP\"\n        maker.standalone = \"yes\"\n      end\n      assert_equal([\"atom\", \"1.0\", \"entry\"], entry.feed_info)\n      assert_equal(\"EUC-JP\", entry.encoding)\n      assert_equal(\"yes\", entry.standalone)\n    end\n\n    def test_invalid_feed\n      assert_not_set_error(\"maker.item\", %w(id title author updated)) do\n        Maker.make(\"atom:entry\") do |maker|\n        end\n      end\n\n      assert_not_set_error(\"maker.item\", %w(id title updated)) do\n        Maker.make(\"atom:entry\") do |maker|\n          maker.channel.author = \"foo\"\n        end\n      end\n\n      assert_not_set_error(\"maker.item\", %w(title updated)) do\n        Maker.make(\"atom:entry\") do |maker|\n          maker.channel.author = \"foo\"\n          maker.channel.id = \"http://example.com\"\n        end\n      end\n\n      assert_not_set_error(\"maker.item\", %w(updated)) do\n        Maker.make(\"atom:entry\") do |maker|\n          maker.channel.author = \"foo\"\n          maker.channel.id = \"http://example.com\"\n          maker.channel.title = \"Atom Feed\"\n        end\n      end\n\n      assert_not_set_error(\"maker.item\", %w(author)) do\n        Maker.make(\"atom:entry\") do |maker|\n          maker.channel.id = \"http://example.com\"\n          maker.channel.title = \"Atom Feed\"\n          maker.channel.updated = Time.now\n        end\n      end\n\n      entry = Maker.make(\"atom:entry\") do |maker|\n        maker.channel.author = \"Foo\"\n        maker.channel.id = \"http://example.com\"\n        maker.channel.title = \"Atom Feed\"\n        maker.channel.updated = Time.now\n      end\n      assert_not_nil(entry)\n    end\n\n    def test_author\n      assert_maker_atom_persons(\"entry\",\n                                [\"channel\", \"authors\"],\n                                [\"authors\"],\n                                \"maker.channel.author\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_persons(\"entry\",\n                                [\"items\", \"first\", \"authors\"],\n                                [\"authors\"],\n                                \"maker.item.author\",\n                                \"maker.item\", [\"author\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.authors.clear\n        maker.items.first.authors.clear\n      end\n\n      assert_maker_atom_persons(\"entry\",\n                                [\"items\", \"first\", \"source\", \"authors\"],\n                                [\"source\", \"authors\"],\n                                \"maker.item.source.author\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_category\n      assert_maker_atom_categories(\"entry\",\n                                   [\"channel\", \"categories\"],\n                                   [\"categories\"],\n                                   \"maker.channel.category\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_categories(\"entry\",\n                                   [\"items\", \"first\", \"categories\"],\n                                   [\"categories\"],\n                                   \"maker.item.category\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_categories(\"entry\",\n                                   [\"items\", \"first\", \"source\", \"categories\"],\n                                   [\"source\", \"categories\"],\n                                   \"maker.item.source.category\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_content\n      assert_maker_atom_content(\"entry\",\n                                [\"items\", \"first\", \"content\"],\n                                [\"content\"],\n                                \"maker.item.content\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_contributor\n      assert_maker_atom_persons(\"entry\",\n                                [\"channel\", \"contributors\"],\n                                [\"contributors\"],\n                                \"maker.channel.contributor\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_persons(\"entry\",\n                                [\"items\", \"first\", \"contributors\"],\n                                [\"contributors\"],\n                                \"maker.item.contributor\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_persons(\"entry\",\n                                [\"items\", \"first\", \"source\", \"contributors\"],\n                                [\"source\", \"contributors\"],\n                                \"maker.item.source.contributor\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_link\n      assert_maker_atom_links(\"entry\",\n                              [\"channel\", \"links\"],\n                              [\"links\"],\n                              \"maker.channel.link\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.links.clear\n        maker.items.first.links.clear\n      end\n\n      assert_maker_atom_links(\"entry\",\n                              [\"items\", \"first\", \"links\"],\n                              [\"links\"],\n                              \"maker.item.link\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.links.clear\n        maker.items.first.links.clear\n      end\n\n      assert_maker_atom_links(\"entry\",\n                              [\"items\", \"first\", \"source\", \"links\"],\n                              [\"source\", \"links\"],\n                              \"maker.item.source.link\", true) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_published\n      assert_maker_atom_date_construct(\"entry\",\n                                       [\"items\", \"first\", \"published\"],\n                                       [\"published\"]\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_rights\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"channel\", \"copyright\"],\n                                       [\"rights\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"items\", \"first\", \"rights\"],\n                                       [\"rights\"],\n                                       nil, nil, \"maker.item.rights\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"items\", \"first\", \"source\", \"rights\"],\n                                       [\"source\", \"rights\"],\n                                       nil, nil, \"maker.item.source.rights\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n\n    def test_source_generator\n      assert_maker_atom_generator(\"entry\",\n                                  [\"items\", \"first\", \"source\", \"generator\"],\n                                  [\"source\", \"generator\"],\n                                  \"maker.item.source.generator\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_source_icon\n      assert_maker_atom_icon(\"entry\",\n                             [\"items\", \"first\", \"source\", \"icon\"],\n                             [\"source\", \"icon\"],\n                             nil, \"maker.item.source.icon\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_source_id\n      assert_maker_atom_id(\"entry\",\n                           [\"items\", \"first\", \"source\"],\n                           [\"source\"],\n                           \"maker.item.source\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_source_logo\n      assert_maker_atom_logo(\"entry\",\n                             [\"items\", \"first\", \"source\", \"logo\"],\n                             [\"source\", \"logo\"],\n                             nil,\n                             \"maker.item.source.logo\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_source_subtitle\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"items\", \"first\", \"source\", \"subtitle\"],\n                                       [\"source\", \"subtitle\"],\n                                       nil, nil,\n                                       \"maker.item.source.subtitle\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_summary\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"items\", \"first\", \"description\"],\n                                       [\"summary\"],\n                                       nil, nil, \"maker.item.description\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_title\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"channel\", \"title\"], [\"title\"],\n                                       \"maker.item\", [\"title\"],\n                                       \"maker.channel.title\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.title = nil\n        maker.items.first.title = nil\n      end\n\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"items\", \"first\", \"title\"],\n                                       [\"title\"],\n                                       \"maker.item\", [\"title\"],\n                                       \"maker.item.title\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.title = nil\n        maker.items.first.title = nil\n      end\n\n      assert_maker_atom_text_construct(\"entry\",\n                                       [\"items\", \"first\", \"source\", \"title\"],\n                                       [\"source\", \"title\"],\n                                       nil, nil, \"maker.item.source.title\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_updated\n      assert_maker_atom_date_construct(\"entry\",\n                                       [\"channel\", \"updated\"], [\"updated\"],\n                                       \"maker.item\", [\"updated\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.updated = nil\n        maker.items.first.updated = nil\n      end\n\n      assert_maker_atom_date_construct(\"entry\",\n                                       [\"items\", \"first\", \"updated\"],\n                                       [\"updated\"],\n                                       \"maker.item\", [\"updated\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.channel.updated = nil\n        maker.items.first.updated = nil\n      end\n\n      assert_maker_atom_date_construct(\"entry\",\n                                       [\"items\", \"first\", \"source\", \"updated\"],\n                                       [\"source\", \"updated\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_atom_feed.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerAtomFeed < TestCase\n    def test_root_element\n      feed = Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n      assert_equal([\"atom\", \"1.0\", \"feed\"], feed.feed_info)\n\n      feed = Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.encoding = \"EUC-JP\"\n      end\n      assert_equal([\"atom\", \"1.0\", \"feed\"], feed.feed_info)\n      assert_equal(\"EUC-JP\", feed.encoding)\n\n      feed = Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.standalone = \"yes\"\n      end\n      assert_equal([\"atom\", \"1.0\", \"feed\"], feed.feed_info)\n      assert_equal(\"yes\", feed.standalone)\n\n      feed = Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.encoding = \"EUC-JP\"\n        maker.standalone = \"yes\"\n      end\n      assert_equal([\"atom\", \"1.0\", \"feed\"], feed.feed_info)\n      assert_equal(\"EUC-JP\", feed.encoding)\n      assert_equal(\"yes\", feed.standalone)\n    end\n\n    def test_invalid_feed\n      assert_not_set_error(\"maker.channel\", %w(id title author updated)) do\n        Maker.make(\"atom\") do |maker|\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(id title updated)) do\n        Maker.make(\"atom\") do |maker|\n          maker.channel.author = \"foo\"\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(title updated)) do\n        Maker.make(\"atom\") do |maker|\n          maker.channel.author = \"foo\"\n          maker.channel.id = \"http://example.com\"\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(updated)) do\n        Maker.make(\"atom\") do |maker|\n          maker.channel.author = \"foo\"\n          maker.channel.id = \"http://example.com\"\n          maker.channel.title = \"Atom Feed\"\n        end\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(author)) do\n        Maker.make(\"atom\") do |maker|\n          maker.channel.id = \"http://example.com\"\n          maker.channel.title = \"Atom Feed\"\n          maker.channel.updated = Time.now\n        end\n      end\n\n      feed = Maker.make(\"atom\") do |maker|\n        maker.channel.author = \"Foo\"\n        maker.channel.id = \"http://example.com\"\n        maker.channel.title = \"Atom Feed\"\n        maker.channel.updated = Time.now\n      end\n      assert_not_nil(feed)\n    end\n\n    def test_author\n      assert_maker_atom_persons(\"feed\",\n                                [\"channel\", \"authors\"],\n                                [\"authors\"],\n                                \"maker.channel.author\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_not_set_error(\"maker.channel\", %w(author)) do\n        RSS::Maker.make(\"atom\") do |maker|\n          setup_dummy_channel_atom(maker)\n          setup_dummy_item_atom(maker)\n          maker.channel.authors.clear\n        end\n      end\n\n      assert_maker_atom_persons(\"feed\",\n                                [\"items\", \"first\", \"authors\"],\n                                [\"entries\", \"first\", \"authors\"],\n                                \"maker.item.author\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_persons(\"feed\",\n                                [\"items\", \"first\", \"source\", \"authors\"],\n                                [\"entries\", \"first\", \"source\", \"authors\"],\n                                \"maker.item.source.author\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_category\n      assert_maker_atom_categories(\"feed\",\n                                   [\"channel\", \"categories\"],\n                                   [\"categories\"],\n                                   \"maker.channel.category\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_categories(\"feed\",\n                                   [\"items\", \"first\", \"categories\"],\n                                   [\"entries\", \"first\", \"categories\"],\n                                   \"maker.item.category\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_categories(\"feed\",\n                                   [\"items\", \"first\", \"source\", \"categories\"],\n                                   [\"entries\", \"first\", \"source\", \"categories\"],\n                                   \"maker.item.source.category\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_contributor\n      assert_maker_atom_persons(\"feed\",\n                                [\"channel\", \"contributors\"],\n                                [\"contributors\"],\n                                \"maker.channel.contributor\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_persons(\"feed\",\n                                [\"items\", \"first\", \"contributors\"],\n                                [\"entries\", \"first\", \"contributors\"],\n                                \"maker.item.contributor\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_persons(\"feed\",\n                                [\"items\", \"first\", \"source\", \"contributors\"],\n                                [\"entries\", \"first\", \"source\", \"contributors\"],\n                                \"maker.item.source.contributor\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_generator\n      assert_maker_atom_generator(\"feed\",\n                                  [\"channel\", \"generator\"],\n                                  [\"generator\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_generator(\"feed\",\n                                  [\"items\", \"first\", \"source\", \"generator\"],\n                                  [\"entries\", \"first\", \"source\", \"generator\"],\n                                  \"maker.item.source.generator\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_icon\n      assert_maker_atom_icon(\"feed\", [\"channel\"], [\"icon\"], \"icon\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_icon(\"feed\",\n                             [\"items\", \"first\", \"source\", \"icon\"],\n                             [\"entries\", \"first\", \"source\", \"icon\"],\n                             nil, \"maker.item.source.icon\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_link\n      assert_maker_atom_links(\"feed\",\n                              [\"channel\", \"links\"],\n                              [\"links\"],\n                              \"maker.channel.link\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_links(\"feed\",\n                              [\"items\", \"first\", \"links\"],\n                              [\"entries\", \"first\", \"links\"],\n                              \"maker.item.link\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_links(\"feed\",\n                              [\"items\", \"first\", \"source\", \"links\"],\n                              [\"entries\", \"first\", \"source\", \"links\"],\n                              \"maker.item.source.link\", true) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_logo\n      assert_maker_atom_logo(\"feed\", [\"channel\"], [\"logo\"], \"logo\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_logo(\"feed\", [\"image\"], [\"logo\"], \"url\") do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_logo(\"feed\",\n                             [\"items\", \"first\", \"source\", \"logo\"],\n                             [\"entries\", \"first\", \"source\", \"logo\"],\n                             nil, \"maker.item.source.logo\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_rights\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"channel\", \"copyright\"],\n                                       [\"rights\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n      end\n\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"items\", \"first\", \"rights\"],\n                                       [\"entries\", \"first\", \"rights\"],\n                                       nil, nil, \"maker.item.rights\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"items\", \"first\", \"source\", \"rights\"],\n                                       [\"entries\", \"first\", \"source\", \"rights\"],\n                                       nil, nil, \"maker.item.source.rights\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_subtitle\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"channel\", \"subtitle\"],\n                                       [\"subtitle\"],\n                                       nil, nil,\n                                       \"maker.channel.description\") do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.channel.description = nil\n      end\n\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"channel\", \"subtitle\"],\n                                       [\"subtitle\"],\n                                       nil, nil,\n                                       \"maker.channel.description\") do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.channel.description {|d| d.content = nil}\n      end\n\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"items\", \"first\", \"source\", \"subtitle\"],\n                                       [\"entries\", \"first\",\n                                        \"source\", \"subtitle\"],\n                                       nil, nil,\n                                       \"maker.item.source.subtitle\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_title\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"channel\", \"title\"], [\"title\"],\n                                       \"maker.channel\", [\"title\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.channel.title = nil\n      end\n\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"items\", \"first\", \"title\"],\n                                       [\"entries\", \"first\", \"title\"],\n                                       \"maker.item\", [\"title\"],\n                                       \"maker.item.title\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.items.first.title = nil\n      end\n\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"items\", \"first\", \"source\", \"title\"],\n                                       [\"entries\", \"first\", \"source\", \"title\"],\n                                       nil, nil, \"maker.item.source.title\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_updated\n      assert_maker_atom_date_construct(\"feed\",\n                                       [\"channel\", \"updated\"], [\"updated\"],\n                                       \"maker.channel\", [\"updated\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        maker.channel.updated = nil\n      end\n\n      assert_maker_atom_date_construct(\"feed\",\n                                       [\"items\", \"first\", \"updated\"],\n                                       [\"entries\", \"first\", \"updated\"],\n                                       \"maker.item\", [\"updated\"]) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n        maker.items.first.updated = nil\n      end\n\n      assert_maker_atom_date_construct(\"feed\",\n                                       [\"items\", \"first\", \"source\", \"updated\"],\n                                       [\"entries\", \"first\", \"source\", \"updated\"]\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_published\n      assert_maker_atom_date_construct(\"feed\",\n                                       [\"items\", \"first\", \"published\"],\n                                       [\"entries\", \"first\", \"published\"]\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_summary\n      assert_maker_atom_text_construct(\"feed\",\n                                       [\"items\", \"first\", \"description\"],\n                                       [\"entries\", \"first\", \"summary\"],\n                                       nil, nil, \"maker.item.description\"\n                                       ) do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_content\n      assert_maker_atom_content(\"feed\",\n                                [\"items\", \"first\", \"content\"],\n                                [\"entries\", \"first\", \"content\"],\n                                \"maker.item.content\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n\n    def test_id\n      assert_maker_atom_id(\"feed\",\n                           [\"items\", \"first\", \"source\"],\n                           [\"entries\", \"first\", \"source\"],\n                           \"maker.item.source\") do |maker|\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_content.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerContent < TestCase\n\n    def setup\n      @uri = \"http://purl.org/rss/1.0/modules/content/\"\n      \n      @elements = {\n        :encoded => \"<em>ATTENTION</em>\",\n      }\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        @elements.each do |name, value|\n          item.__send__(\"#{accessor_name(name)}=\", value)\n        end\n      end\n      assert_content(@elements, rss.items.last)\n    end\n\n    def test_rss20\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        @elements.each do |name, value|\n          item.__send__(\"#{accessor_name(name)}=\", value)\n        end\n      end\n      assert_content(@elements, rss.items.last)\n    end\n\n    private\n    def accessor_name(name)\n      \"content_#{name}\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_dc.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerDublinCore < TestCase\n\n    def setup\n      @uri = \"http://purl.org/dc/elements/1.1/\"\n      \n      t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n      \n      @elements = {\n        :title => \"hoge\",\n        :description =>\n          \" XML is placing increasingly heavy loads on\n          the existing technical infrastructure of the Internet.\",\n        :creator => \"Rael Dornfest (mailto:rael@oreilly.com)\",\n        :subject => \"XML\",\n        :publisher => \"The O'Reilly Network\",\n        :contributor => \"hogehoge\",\n        :type => \"fugafuga\",\n        :format => \"hohoho\",\n        :identifier => \"fufufu\",\n        :source => \"barbar\",\n        :language => \"ja\",\n        :relation => \"cococo\",\n        :rights => \"Copyright (c) 2000 O'Reilly &amp; Associates, Inc.\",\n        :date => t,\n      }\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        set_elements(maker.channel)\n\n        setup_dummy_image(maker)\n        set_elements(maker.image)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        @elements.each do |name, value|\n          item.__send__(\"#{accessor_name(name)}=\", value)\n        end\n\n        setup_dummy_textinput(maker)\n        set_elements(maker.textinput)\n      end\n      assert_dublin_core(@elements, rss.channel)\n      assert_dublin_core(@elements, rss.image)\n      assert_dublin_core(@elements, rss.items.last)\n      assert_dublin_core(@elements, rss.textinput)\n    end\n\n    def test_rss10_multiple\n      assert_multiple_dublin_core_rss10(\"_list\")\n      assert_multiple_dublin_core_rss10(\"es\")\n    end\n\n    def assert_multiple_dublin_core_rss10(multiple_rights_suffix)\n      elems = []\n      @elements.each do |name, value|\n        plural = name.to_s + (name == :rights ? multiple_rights_suffix : \"s\")\n        values = [value]\n        if name == :date\n          values << value + 60\n        else\n          values << value * 2\n        end\n        elems << [name, values, plural]\n      end\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        set_multiple_elements(maker.channel, elems)\n\n        setup_dummy_image(maker)\n        set_multiple_elements(maker.image, elems)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        elems.each do |name, values, plural|\n          dc_elems = item.__send__(\"dc_#{plural}\")\n          values.each do |value|\n            dc_elems.__send__(\"new_#{name}\") do |elem|\n              elem.value = value\n            end\n          end\n        end\n\n        setup_dummy_textinput(maker)\n        set_multiple_elements(maker.textinput, elems)\n      end\n      assert_multiple_dublin_core(elems, rss.channel)\n      assert_multiple_dublin_core(elems, rss.image)\n      assert_multiple_dublin_core(elems, rss.items.last)\n      assert_multiple_dublin_core(elems, rss.textinput)\n    end\n\n    def test_date\n      t1 = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      t2 = Time.iso8601(\"2005-01-01T12:00:05+00:00\")\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.date = t1\n        maker.channel.dc_dates.new_date do |date|\n          date.value = t2\n        end\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        item.date = t2\n        item.dc_dates.new_date do |date|\n          date.value = t1\n        end\n      end\n      assert_equal([t1, t2], rss.channel.dc_dates.collect{|x| x.value})\n      assert_equal([t2, t1], rss.items.last.dc_dates.collect{|x| x.value})\n    end\n    \n    private\n    def accessor_name(name)\n      \"dc_#{name}\"\n    end\n\n    def set_elements(target, elems=@elements)\n      elems.each do |name, value|\n        target.__send__(\"#{accessor_name(name)}=\", value)\n      end\n    end\n\n    def set_multiple_elements(target, elems)\n      elems.each do |name, values, plural|\n        plural ||= \"#{name}s\"\n        dc_elems = target.__send__(\"dc_#{plural}\")\n        values.each do |value|\n          dc_elems.__send__(\"new_#{name}\") do |new_dc_elem|\n            new_dc_elem.value = value\n          end\n        end\n      end\n    end\n\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_image.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerImage < TestCase\n\n    def setup\n      @uri = \"http://web.resource.org/rss/1.0/modules/image/\"\n\n      @favicon_infos = {\n        \"about\" => \"http://www.kuro5hin.org/favicon.ico\",\n        \"image_size\" => \"small\",\n        \"dc_title\" => \"example\",\n      }\n      @item_infos = {\n        \"about\" => \"http://www.example.org/item.png\",\n        \"resource\" => \"http://www.example.org/item\",\n        \"dc_title\" => \"Example Image\",\n        \"image_width\" => \"100\",\n        \"image_height\" => \"65\",\n      }\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        @favicon_infos.each do |name, value|\n          maker.channel.image_favicon.__send__(\"#{name}=\", value)\n        end\n\n        setup_dummy_image(maker)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        @item_infos.each do |name, value|\n          item.image_item.__send__(\"#{name}=\", value)\n        end\n\n        setup_dummy_textinput(maker)\n      end\n      \n      setup_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.setup_maker(maker)\n      end\n\n      [rss, setup_rss].each_with_index do |target, i|\n        favicon = target.channel.image_favicon\n        assert_equal(@favicon_infos[\"about\"], favicon.about)\n        assert_equal(@favicon_infos[\"image_size\"], favicon.image_size)\n        assert_equal(@favicon_infos[\"dc_title\"], favicon.dc_title)\n        \n        item = target.items.last.image_item\n        assert_equal(@item_infos[\"about\"], item.about)\n        assert_equal(@item_infos[\"resource\"], item.resource)\n        assert_equal(@item_infos[\"image_width\"].to_i, item.image_width)\n        assert_equal(@item_infos[\"image_height\"].to_i, item.image_height)\n        assert_equal(@item_infos[\"dc_title\"], item.dc_title)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_itunes.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerITunes < TestCase\n    def test_author\n      assert_maker_itunes_author(%w(channel))\n      assert_maker_itunes_author(%w(items last))\n    end\n\n    def test_block\n      assert_maker_itunes_block(%w(channel))\n      assert_maker_itunes_block(%w(items last))\n    end\n\n    def test_category\n      assert_maker_itunes_category(%w(channel))\n    end\n\n    def test_image\n      assert_maker_itunes_image(%w(channel))\n    end\n\n    def test_duration\n      assert_maker_itunes_duration(%w(items last))\n    end\n\n    def test_explicit\n      assert_maker_itunes_explicit(%w(channel))\n      assert_maker_itunes_explicit(%w(items last))\n    end\n\n    def test_keywords\n      assert_maker_itunes_keywords(%w(channel))\n      assert_maker_itunes_keywords(%w(items last))\n    end\n\n    def test_new_feed_url\n      assert_maker_itunes_new_feed_url(%w(channel))\n    end\n\n    def test_owner\n      assert_maker_itunes_owner(%w(channel))\n    end\n\n    def test_subtitle\n      assert_maker_itunes_subtitle(%w(channel))\n      assert_maker_itunes_subtitle(%w(items last))\n    end\n\n    def test_summary\n      assert_maker_itunes_summary(%w(channel))\n      assert_maker_itunes_summary(%w(items last))\n    end\n\n    private\n\n    def assert_maker_itunes_author(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        author = \"John Doe\"\n        rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n          setup_dummy_channel(maker)\n          setup_dummy_item(maker)\n\n          target = chain_reader(maker, maker_readers)\n          target.itunes_author = author\n        end\n        target = chain_reader(rss20, feed_readers)\n        assert_equal(author, target.itunes_author)\n      end\n    end\n\n    def _assert_maker_itunes_block(value, boolean_value, maker_readers,\n                                   feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        target.itunes_block = value\n        assert_equal(value, target.itunes_block)\n        assert_equal(boolean_value, target.itunes_block?)\n      end\n      target = chain_reader(rss20, feed_readers)\n      if [true, false].include?(value)\n        feed_expected_value = value = value ? \"yes\" : \"no\"\n      else\n        feed_expected_value = value\n      end\n      assert_equal(value, target.itunes_block)\n      assert_equal(boolean_value, target.itunes_block?)\n    end\n\n    def assert_maker_itunes_block(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_block(\"yes\", true, maker_readers, feed_readers)\n        _assert_maker_itunes_block(\"Yes\", true, maker_readers, feed_readers)\n        _assert_maker_itunes_block(\"no\", false, maker_readers, feed_readers)\n        _assert_maker_itunes_block(\"\", false, maker_readers, feed_readers)\n        _assert_maker_itunes_block(true, true, maker_readers, feed_readers)\n        _assert_maker_itunes_block(false, false, maker_readers, feed_readers)\n        _assert_maker_itunes_block(nil, false, maker_readers, feed_readers)\n      end\n    end\n\n    def _assert_maker_itunes_category(categories, maker_readers, feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        categories.each do |category|\n          sub_target = target.itunes_categories\n          if category.is_a?(Array)\n            category.each do |sub_category|\n              sub_target = sub_target.new_category\n              sub_target.text = sub_category\n            end\n          else\n            sub_target.new_category.text = category\n          end\n        end\n      end\n\n      target = chain_reader(rss20, feed_readers)\n      actual_categories = target.itunes_categories.collect do |category|\n        cat = category.text\n        if category.itunes_categories.empty?\n          cat\n        else\n          [cat, *category.itunes_categories.collect {|c| c.text}]\n        end\n      end\n      assert_equal(categories, actual_categories)\n    end\n\n    def assert_maker_itunes_category(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_category([\"Audio Blogs\"],\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_category([[\"Arts & Entertainment\", \"Games\"]],\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_category([[\"Arts & Entertainment\", \"Games\"],\n                                       [\"Technology\", \"Computers\"],\n                                       \"Audio Blogs\"],\n                                      maker_readers, feed_readers)\n      end\n    end\n\n    def assert_maker_itunes_image(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        url = \"http://example.com/podcasts/everything/AllAboutEverything.jpg\"\n\n        rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n          setup_dummy_channel(maker)\n          setup_dummy_item(maker)\n\n          target = chain_reader(maker, maker_readers)\n          target.itunes_image = url\n        end\n\n        target = chain_reader(rss20, feed_readers)\n        assert_not_nil(target.itunes_image)\n        assert_equal(url, target.itunes_image.href)\n      end\n    end\n\n    def _assert_maker_itunes_duration(hour, minute, second, value,\n                                      maker_readers, feed_readers)\n      _assert_maker_itunes_duration_by_value(hour, minute, second, value,\n                                             maker_readers, feed_readers)\n      _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,\n                                                          value,\n                                                          maker_readers,\n                                                          feed_readers)\n    end\n\n    def _assert_maker_itunes_duration_by(hour, minute, second, value,\n                                         maker_readers, feed_readers)\n      expected_value = nil\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        expected_value = yield(target)\n        assert_equal(expected_value, target.itunes_duration)\n        target.itunes_duration do |duration|\n          assert_equal([hour, minute, second, expected_value],\n                       [duration.hour, duration.minute,\n                        duration.second, duration.content])\n        end\n      end\n      target = chain_reader(rss20, feed_readers)\n      duration = target.itunes_duration\n      assert_not_nil(duration)\n      assert_equal([hour, minute, second, expected_value],\n                   [duration.hour, duration.minute,\n                    duration.second, duration.content])\n    end\n\n    def _assert_maker_itunes_duration_by_value(hour, minute, second, value,\n                                               maker_readers, feed_readers)\n      _assert_maker_itunes_duration_by(hour, minute, second, value,\n                                       maker_readers, feed_readers) do |target|\n        target.itunes_duration = value\n        value\n      end\n    end\n\n    def _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,\n                                                            value,\n                                                            maker_readers,\n                                                            feed_readers)\n      _assert_maker_itunes_duration_by(hour, minute, second, value,\n                                       maker_readers, feed_readers) do |target|\n        target.itunes_duration do |duration|\n          duration.hour = hour\n          duration.minute = minute\n          duration.second = second\n        end\n        value.split(\":\").collect {|v| \"%02d\" % v.to_i}.join(\":\")\n      end\n    end\n\n    def _assert_maker_itunes_duration_invalid_value(value, maker_readers)\n      assert_raise(ArgumentError) do\n        ::RSS::Maker.make(\"rss2.0\") do |maker|\n          setup_dummy_channel(maker)\n          setup_dummy_item(maker)\n\n          target = chain_reader(maker, maker_readers)\n          target.itunes_duration = value\n        end\n      end\n    end\n\n    def assert_maker_itunes_duration(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_duration(7, 14, 5, \"07:14:05\", maker_readers,\n                                      feed_readers)\n        _assert_maker_itunes_duration(7, 14, 5, \"7:14:05\", maker_readers,\n                                      feed_readers)\n        _assert_maker_itunes_duration(0, 4, 55, \"04:55\", maker_readers,\n                                      feed_readers)\n        _assert_maker_itunes_duration(0, 4, 5, \"4:05\", maker_readers,\n                                      feed_readers)\n\n        _assert_maker_itunes_duration_invalid_value(\"5\", maker_readers)\n        _assert_maker_itunes_duration_invalid_value(\"09:07:14:05\", maker_readers)\n        _assert_maker_itunes_duration_invalid_value(\"10:5\", maker_readers)\n        _assert_maker_itunes_duration_invalid_value(\"10:03:5\", maker_readers)\n        _assert_maker_itunes_duration_invalid_value(\"10:3:05\", maker_readers)\n\n        _assert_maker_itunes_duration_invalid_value(\"xx:xx:xx\", maker_readers)\n      end\n    end\n\n    def _assert_maker_itunes_explicit(explicit, value,\n                                      maker_readers, feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        target.itunes_explicit = value\n        assert_equal(explicit, target.itunes_explicit?)\n      end\n      target = chain_reader(rss20, feed_readers)\n      assert_equal(value, target.itunes_explicit)\n      assert_equal(explicit, target.itunes_explicit?)\n    end\n\n    def assert_maker_itunes_explicit(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_explicit(true, \"yes\", maker_readers, feed_readers)\n        _assert_maker_itunes_explicit(false, \"clean\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_explicit(nil, \"no\", maker_readers, feed_readers)\n      end\n    end\n\n    def _assert_maker_itunes_keywords(keywords, value,\n                                      maker_readers, feed_readers)\n      _assert_maker_itunes_keywords_by_value(keywords, value,\n                                             maker_readers, feed_readers)\n      _assert_maker_itunes_keywords_by_keywords(keywords, maker_readers,\n                                                feed_readers)\n    end\n\n    def _assert_maker_itunes_keywords_by(keywords, maker_readers, feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        yield(target)\n      end\n      assert_nothing_raised do\n        rss20 = ::RSS::Parser.parse(rss20.to_s)\n      end\n      target = chain_reader(rss20, feed_readers)\n      assert_equal(keywords, target.itunes_keywords)\n    end\n\n    def _assert_maker_itunes_keywords_by_value(keywords, value,\n                                               maker_readers, feed_readers)\n      _assert_maker_itunes_keywords_by(keywords, maker_readers,\n                                       feed_readers) do |target|\n        target.itunes_keywords = value\n      end\n    end\n\n    def _assert_maker_itunes_keywords_by_keywords(keywords,\n                                                  maker_readers, feed_readers)\n      _assert_maker_itunes_keywords_by(keywords, maker_readers,\n                                       feed_readers) do |target|\n        target.itunes_keywords = keywords\n      end\n    end\n\n    def assert_maker_itunes_keywords(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_keywords([\"salt\"], \"salt\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_keywords([\"salt\"], \" salt \",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_keywords([\"salt\", \"pepper\", \"shaker\", \"exciting\"],\n                                      \"salt, pepper, shaker, exciting\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_keywords([\"metric\", \"socket\", \"wrenches\",\n                                       \"toolsalt\"],\n                                      \"metric, socket, wrenches, toolsalt\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_keywords([\"olitics\", \"red\", \"blue\", \"state\"],\n                                      \"olitics, red, blue, state\",\n                                      maker_readers, feed_readers)\n      end\n    end\n\n    def assert_maker_itunes_new_feed_url(maker_readers, feed_readers=nil)\n      feed_readers ||= maker_readers\n      url = \"http://newlocation.com/example.rss\"\n\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        target.itunes_new_feed_url = url\n      end\n      target = chain_reader(rss20, feed_readers)\n      assert_equal(url, target.itunes_new_feed_url)\n    end\n\n    def _assert_maker_itunes_owner(name, email, maker_readers, feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        owner = target.itunes_owner\n        owner.itunes_name = name\n        owner.itunes_email = email\n      end\n      owner = chain_reader(rss20, feed_readers).itunes_owner\n      if name.nil? and email.nil?\n        assert_nil(owner)\n      else\n        assert_not_nil(owner)\n        assert_equal(name, owner.itunes_name)\n        assert_equal(email, owner.itunes_email)\n      end\n    end\n\n    def assert_maker_itunes_owner(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_owner(\"John Doe\", \"john.doe@example.com\",\n                                   maker_readers, feed_readers)\n\n        not_set_name = ([\"maker\"] + maker_readers + [\"itunes_owner\"]).join(\".\")\n        assert_not_set_error(not_set_name, [\"itunes_name\"]) do\n          _assert_maker_itunes_owner(nil, \"john.doe@example.com\",\n                                     maker_readers, feed_readers)\n        end\n        assert_not_set_error(not_set_name, [\"itunes_email\"]) do\n          _assert_maker_itunes_owner(\"John Doe\", nil,\n                                     maker_readers, feed_readers)\n        end\n\n        _assert_maker_itunes_owner(nil, nil, maker_readers, feed_readers)\n      end\n    end\n\n    def _assert_maker_itunes_subtitle(subtitle, maker_readers, feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        target.itunes_subtitle = subtitle\n      end\n\n      target = chain_reader(rss20, feed_readers)\n      assert_equal(subtitle, target.itunes_subtitle)\n    end\n\n    def assert_maker_itunes_subtitle(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_subtitle(\"A show about everything\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_subtitle(\"A short primer on table spices\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_subtitle(\"Comparing socket wrenches is fun!\",\n                                      maker_readers, feed_readers)\n        _assert_maker_itunes_subtitle(\"Red + Blue != Purple\",\n                                      maker_readers, feed_readers)\n      end\n    end\n\n    def _assert_maker_itunes_summary(summary, maker_readers, feed_readers)\n      rss20 = ::RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        target = chain_reader(maker, maker_readers)\n        target.itunes_summary = summary\n      end\n\n      target = chain_reader(rss20, feed_readers)\n      assert_equal(summary, target.itunes_summary)\n    end\n\n    def assert_maker_itunes_summary(maker_readers, feed_readers=nil)\n      _wrap_assertion do\n        feed_readers ||= maker_readers\n        _assert_maker_itunes_summary(\"All About Everything is a show about \" +\n                                     \"everything. Each week we dive into any \" +\n                                     \"subject known to man and talk about it \" +\n                                     \"as much as we can. Look for our Podcast \" +\n                                     \"in the iTunes Music Store\",\n                                     maker_readers, feed_readers)\n        _assert_maker_itunes_summary(\"This week we talk about salt and pepper \" +\n                                     \"shakers, comparing and contrasting pour \" +\n                                     \"rates, construction materials, and \" +\n                                     \"overall aesthetics. Come and join the \" +\n                                     \"party!\",\n                                     maker_readers, feed_readers)\n        _assert_maker_itunes_summary(\"This week we talk about metric vs. old \" +\n                                     \"english socket wrenches. Which one is \" +\n                                     \"better? Do you really need both? Get \" +\n                                     \"all of your answers here.\",\n                                     maker_readers, feed_readers)\n        _assert_maker_itunes_summary(\"This week we talk about surviving in a \" +\n                                     \"Red state if you’re a Blue person. Or \" +\n                                     \"vice versa.\",\n                                     maker_readers, feed_readers)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_slash.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerSlash < TestCase\n    def setup\n      @elements = {\n        \"section\" => \"articles\",\n        \"department\" => \"not-an-ocean-unless-there-are-lobsters\",\n        \"comments\" => 177,\n        \"hit_parades\" => [177, 155, 105, 33, 6, 3, 0],\n      }\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        @elements.each do |name, value|\n          item.send(\"slash_#{name}=\", value)\n        end\n      end\n\n      item = rss.items.last\n      assert_not_nil(item)\n      assert_slash_elements(item)\n    end\n\n    private\n    def assert_slash_elements(target)\n      super(@elements, target)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_sy.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerSyndication < TestCase\n\n    def setup\n      @uri = \"http://purl.org/rss/1.0/modules/syndication/\"\n      \n      t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n      \n      @elements = {\n        :updatePeriod => \"hourly\",\n        :updateFrequency => \"2\",\n        :updateBase => t,\n      }\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        set_elements(maker.channel)\n        setup_dummy_item(maker)\n      end\n      assert_syndication(@elements, rss.channel)\n    end\n\n    private\n    def accessor_name(name)\n      \"sy_#{name}\"\n    end\n\n    def set_elements(target)\n      @elements.each do |name, value|\n        target.__send__(\"#{accessor_name(name)}=\", value)\n      end\n    end\n\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_taxo.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerTaxonomy < TestCase\n\n    def setup\n      @uri = \"http://purl.org/rss/1.0/modules/taxonomy/\"\n      \n      @resources = [\n        \"http://meerkat.oreillynet.com/?c=cat23\",\n        \"http://meerkat.oreillynet.com/?c=47\",\n        \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/\",\n      ]\n\n      @topics = [\n        {\n          :link => \"http://meerkat.oreillynet.com/?c=cat23\",\n          :title => \"Data: XML\",\n          :description => \"A Meerkat channel\",\n         },\n        {\n          :link => \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/\",\n          :title => \"XML\",\n          :subject => \"XML\",\n          :description => \"DMOZ category\",\n          :topics => [\n            \"http://meerkat.oreillynet.com/?c=cat23\",\n            \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/\",\n            \"http://dmoz.org/Computers/Programming/Internet/\",\n          ]\n         },\n       ]\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        set_topics(maker.channel)\n\n        setup_dummy_item(maker)\n        set_topics(maker.items.last)\n\n        setup_taxo_topic(maker, @topics)\n      end\n      assert_equal(@resources, rss.channel.taxo_topics.resources)\n      assert_equal(@resources, rss.items.last.taxo_topics.resources)\n      assert_taxo_topic(@topics, rss)\n    end\n\n    def _test_date\n      t1 = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      t2 = Time.iso8601(\"2005-01-01T12:00:05+00:00\")\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.date = t1\n        maker.channel.dc_dates.new_date do |date|\n          date.value = t2\n        end\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        item.date = t2\n        item.dc_dates.new_date do |date|\n          date.value = t1\n        end\n      end\n      assert_equal([t1, t2], rss.channel.dc_dates.collect{|x| x.value})\n      assert_equal([t2, t1], rss.items.last.dc_dates.collect{|x| x.value})\n    end\n    \n    private\n    def set_topics(target, resources=@resources)\n      resources.each do |value|\n        target.taxo_topics << value\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_trackback.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerTrackBack < TestCase\n\n    def setup\n      @uri = \"http://madskills.com/public/xml/rss/module/trackback/\"\n      \n      @elements = {\n        :ping => \"http://bar.com/tb.cgi?tb_id=rssplustrackback\",\n        :abouts => [\n          \"http://foo.com/trackback/tb.cgi?tb_id=20020923\",\n          \"http://bar.com/trackback/tb.cgi?tb_id=20041114\",\n        ],\n      }\n    end\n\n    def test_rss10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        setup_dummy_item(maker)\n        item = maker.items.last\n        item.trackback_ping = @elements[:ping]\n        @elements[:abouts].each do |about|\n          item.trackback_abouts.new_about do |new_about|\n            new_about.value = about\n          end\n        end\n      end\n      assert_trackback(@elements, rss.items.last)\n    end\n\n    private\n    def accessor_name(name)\n      \"trackback_#{name}\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_maker_xml-stylesheet.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestMakerXMLStyleSheet < TestCase\n\n    def test_xml_stylesheet\n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n      end\n\n      xss = rss.xml_stylesheets.first\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n\n      \n      href = 'http://example.com/index.xsl'\n      type = 'text/xsl'\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.xml_stylesheets.new_xml_stylesheet do |_xss|\n          _xss.href = href\n        end\n\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n      end\n\n      xss = rss.xml_stylesheets.first\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n    end\n\n    def test_not_valid_xml_stylesheet\n      href = 'xss.XXX'\n      type = \"text/xsl\"\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          # xss.href = href\n          xss.type = type\n        end\n\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n      end\n      assert(rss.xml_stylesheets.empty?)\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          # xss.type = type\n        end\n\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n      end\n      assert(rss.xml_stylesheets.empty?)\n    end\n    \n  end\nend\n"
  },
  {
    "path": "test/rss/test_parser.rb",
    "content": "require \"fileutils\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n  class TestParser < TestCase\n    def setup\n      @_default_parser = Parser.default_parser\n      @rss10 = make_RDF(<<-EOR)\n#{make_channel}\n#{make_item}\n#{make_textinput}\n#{make_image}\nEOR\n      @rss_file = \"rss10.rdf\"\n      File.open(@rss_file, \"w\") {|f| f.print(@rss10)}\n    end\n\n    def teardown\n      Parser.default_parser = @_default_parser\n      FileUtils.rm_f(@rss_file)\n    end\n\n    def test_default_parser\n      assert_nothing_raised do\n        Parser.default_parser = RSS::AVAILABLE_PARSERS.first\n      end\n\n      assert_raise(RSS::NotValidXMLParser) do\n        Parser.default_parser = RSS::Parser\n      end\n    end\n\n    def test_parse\n      assert_not_nil(RSS::Parser.parse(@rss_file))\n\n      garbage_rss_file = @rss_file + \"-garbage\"\n      if RSS::Parser.default_parser.name == \"RSS::XMLParserParser\"\n        assert_raise(RSS::NotWellFormedError) do\n          RSS::Parser.parse(garbage_rss_file)\n        end\n      else\n        assert_nil(RSS::Parser.parse(garbage_rss_file))\n      end\n    end\n\n    def test_parse_tag_includes_hyphen\n      assert_nothing_raised do\n        RSS::Parser.parse(make_RDF(<<-EOR))\n<xCal:x-calconnect-venue xmlns:xCal=\"urn:ietf:params:xml:ns:xcal\" />\n#{make_channel}\n#{make_item}\n#{make_textinput}\n#{make_image}\nEOR\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_parser_1.0.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/dublincore\"\n\nmodule RSS\n  class TestParser10 < TestCase\n    def test_RDF\n      assert_ns(\"\", RDF::URI) do\n        Parser.parse(<<-EOR)\n#{make_xmldecl}\n<RDF/>\nEOR\n      end\n\n      assert_ns(\"\", RDF::URI) do\n        Parser.parse(<<-EOR)\n#{make_xmldecl}\n<RDF xmlns=\"hoge\"/>\nEOR\n      end\n\n      assert_ns(\"rdf\", RDF::URI) do\n        Parser.parse(<<-EOR)\n#{make_xmldecl}\n<rdf:RDF xmlns:rdf=\"hoge\"/>\nEOR\n      end\n\n      assert_parse(<<-EOR, :missing_tag, \"channel\", \"RDF\")\n#{make_xmldecl}\n<rdf:RDF xmlns:rdf=\"#{RSS::RDF::URI}\"/>\nEOR\n\n      assert_parse(<<-EOR, :missing_tag, \"channel\", \"RDF\")\n#{make_xmldecl}\n<RDF xmlns=\"#{RSS::RDF::URI}\"/>\nEOR\n\n      assert_parse(<<-EOR, :missing_tag, \"channel\", \"RDF\")\n#{make_xmldecl}\n<RDF xmlns=\"#{RSS::RDF::URI}\"/>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"item\", \"RDF\")\n#{make_channel}\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"item\", \"RDF\")\n#{make_channel}\n#{make_image}\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"item\", \"RDF\")\n#{make_channel}\n#{make_textinput}\nEOR\n\n      assert_too_much_tag(\"image\", \"RDF\") do\n        Parser.parse(make_RDF(<<-EOR))\n#{make_channel}\n#{make_image}\n#{make_image}\n#{make_item}\n#{make_textinput}\nEOR\n      end\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_item}\n#{make_image}\n#{make_textinput}\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_item}\n#{make_textinput}\n#{make_image}\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_image}\n#{make_item}\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_image}\n#{make_item}\n#{make_textinput}\nEOR\n\n      1.step(15, 3) do |i|\n        rss = make_RDF() do\n          res = make_channel\n          i.times { res << make_item }\n          res\n        end\n        assert_parse(rss, :nothing_raised)\n      end\n    end\n\n    def test_undefined_entity\n      return unless RSS::Parser.default_parser.raise_for_undefined_entity?\n      assert_parse(make_RDF(<<-EOR), :raises, RSS::NotWellFormedError)\n#{make_channel}\n#{make_image}\n<item rdf:about=\"#{RDF_ABOUT}\">\n  <title>#{TITLE_VALUE} &UNKNOWN_ENTITY;</title>\n  <link>#{LINK_VALUE}</link>\n  <description>#{DESCRIPTION_VALUE}</description>\n</item>\n#{make_textinput}\nEOR\n    end\n\n    def test_channel\n      assert_parse(make_RDF(<<-EOR), :missing_attribute, \"channel\", \"rdf:about\")\n<channel />\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"title\", \"channel\")\n<channel rdf:about=\"http://example.com/\"/>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"link\", \"channel\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n</channel>\nEOR\n\n      assert_parse(make_RDF(<<EOR), :missing_tag, \"description\", \"channel\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n</channel>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"items\", \"channel\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n</channel>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_attribute, \"image\", \"rdf:resource\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image/>\n</channel>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"items\", \"channel\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image rdf:resource=\"http://example.com/hoge.png\" />\n</channel>\nEOR\n\n      rss = make_RDF(<<-EOR)\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image rdf:resource=\"http://example.com/hoge.png\" />\n  <items/>\n</channel>\nEOR\n\n      assert_missing_tag(\"Seq\", \"items\") do\n        Parser.parse(rss)\n      end\n\n      assert_missing_tag(\"item\", \"RDF\") do\n        Parser.parse(rss, false).validate\n      end\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"item\", \"RDF\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image rdf:resource=\"http://example.com/hoge.png\" />\n  <items>\n    <rdf:Seq>\n    </rdf:Seq>\n  </items>\n</channel>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_attribute, \"textinput\", \"rdf:resource\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image rdf:resource=\"http://example.com/hoge.png\" />\n  <items>\n    <rdf:Seq>\n    </rdf:Seq>\n  </items>\n  <textinput/>\n</channel>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"item\", \"RDF\")\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image rdf:resource=\"http://example.com/hoge.png\" />\n  <items>\n    <rdf:Seq>\n    </rdf:Seq>\n  </items>\n  <textinput rdf:resource=\"http://example.com/search\" />\n</channel>\nEOR\n    end\n\n    def test_rdf_li\n      rss = make_RDF(<<-EOR)\n<channel rdf:about=\"http://example.com/\">\n  <title>hoge</title>\n  <link>http://example.com/</link>\n  <description>hogehoge</description>\n  <image rdf:resource=\"http://example.com/hoge.png\" />\n  <items>\n    <rdf:Seq>\n      <rdf:li \\#{rdf_li_attr}/>\n    </rdf:Seq>\n  </items>\n  <textinput rdf:resource=\"http://example.com/search\" />\n</channel>\n#{make_item}\nEOR\n\n      source = Proc.new do |rdf_li_attr|\n        eval(%Q[%Q[#{rss}]], binding)\n      end\n\n      attr = %q[resource=\"http://example.com/hoge\"]\n      assert_parse(source.call(attr), :nothing_raised)\n\n      attr = %q[rdf:resource=\"http://example.com/hoge\"]\n      assert_parse(source.call(attr), :nothing_raised)\n\n      assert_parse(source.call(\"\"), :missing_attribute, \"li\", \"resource\")\n    end\n\n    def test_image\n      assert_parse(make_RDF(<<-EOR), :missing_attribute, \"image\", \"rdf:about\")\n#{make_channel}\n<image>\n</image>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"title\", \"image\")\n#{make_channel}\n<image rdf:about=\"http://example.com/hoge.png\">\n</image>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"url\", \"image\")\n#{make_channel}\n<image rdf:about=\"http://example.com/hoge.png\">\n  <title>hoge</title>\n</image>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"link\", \"image\")\n#{make_channel}\n<image rdf:about=\"http://example.com/hoge.png\">\n  <title>hoge</title>\n  <url>http://example.com/hoge.png</url>\n</image>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"item\", \"RDF\")\n#{make_channel}\n<image rdf:about=\"http://example.com/hoge.png\">\n  <title>hoge</title>\n  <url>http://example.com/hoge.png</url>\n  <link>http://example.com/</link>\n</image>\nEOR\n\n      rss = make_RDF(<<-EOR)\n#{make_channel}\n<image rdf:about=\"http://example.com/hoge.png\">\n  <link>http://example.com/</link>\n  <url>http://example.com/hoge.png</url>\n  <title>hoge</title>\n</image>\nEOR\n\n      assert_missing_tag(\"item\", \"RDF\") do\n        Parser.parse(rss)\n      end\n\n      assert_missing_tag(\"item\", \"RDF\") do\n        Parser.parse(rss, false).validate\n      end\n    end\n\n    def test_item\n      assert_parse(make_RDF(<<-EOR), :missing_attribute, \"item\", \"rdf:about\")\n#{make_channel}\n#{make_image}\n<item>\n</item>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"title\", \"item\")\n#{make_channel}\n#{make_image}\n<item rdf:about=\"http://example.com/hoge.html\">\n</item>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"link\", \"item\")\n#{make_channel}\n#{make_image}\n<item rdf:about=\"http://example.com/hoge.html\">\n  <title>hoge</title>\n</item>\nEOR\n\n      assert_too_much_tag(\"title\", \"item\") do\n        Parser.parse(make_RDF(<<-EOR))\n#{make_channel}\n#{make_image}\n<item rdf:about=\"http://example.com/hoge.html\">\n  <title>hoge</title>\n  <title>hoge</title>\n  <link>http://example.com/hoge.html</link>\n</item>\nEOR\n      end\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_image}\n<item rdf:about=\"http://example.com/hoge.html\">\n  <title>hoge</title>\n  <link>http://example.com/hoge.html</link>\n</item>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_image}\n<item rdf:about=\"http://example.com/hoge.html\">\n  <title>hoge</title>\n  <link>http://example.com/hoge.html</link>\n  <description>hogehoge</description>\n</item>\nEOR\n    end\n\n    def test_textinput\n      assert_parse(make_RDF(<<-EOR), :missing_attribute, \"textinput\", \"rdf:about\")\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput>\n</textinput>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"title\", \"textinput\")\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput rdf:about=\"http://example.com/search.html\">\n</textinput>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"description\", \"textinput\")\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput rdf:about=\"http://example.com/search.html\">\n  <title>hoge</title>\n</textinput>\nEOR\n\n      assert_too_much_tag(\"title\", \"textinput\") do\n        Parser.parse(make_RDF(<<-EOR))\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput rdf:about=\"http://example.com/search.html\">\n  <title>hoge</title>\n  <title>hoge</title>\n  <description>hogehoge</description>\n</textinput>\nEOR\n      end\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"name\", \"textinput\")\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput rdf:about=\"http://example.com/search.html\">\n  <title>hoge</title>\n  <description>hogehoge</description>\n</textinput>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :missing_tag, \"link\", \"textinput\")\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput rdf:about=\"http://example.com/search.html\">\n  <title>hoge</title>\n  <description>hogehoge</description>\n  <name>key</name>\n</textinput>\nEOR\n\n      assert_parse(make_RDF(<<-EOR), :nothing_raised)\n#{make_channel}\n#{make_image}\n#{make_item}\n<textinput rdf:about=\"http://example.com/search.html\">\n  <title>hoge</title>\n  <description>hogehoge</description>\n  <name>key</name>\n  <link>http://example.com/search.html</link>\n</textinput>\nEOR\n    end\n\n    def test_ignore\n      name = \"a\"\n      rss = make_RDF(<<-EOR)\n#{make_channel}\n#{make_item}\n<#{name}/>\nEOR\n      assert_not_expected_tag(name, ::RSS::URI, \"RDF\") do\n        Parser.parse(rss, true, false)\n      end\n\n      uri = \"\"\n      name = \"a\"\n      rss = make_RDF(<<-EOR)\n#{make_channel}\n#{make_item}\n<#{name} xmlns=\"\"/>\nEOR\n      assert_parse(rss, :nothing_raised)\n      assert_not_expected_tag(name, uri, \"RDF\") do\n        Parser.parse(rss, true, false)\n      end\n\n      uri = \"http://example.com/\"\n      name = \"a\"\n      rss = make_RDF(<<-EOR)\n#{make_channel}\n#{make_item}\n<x:#{name} xmlns:x=\"#{uri}\"/>\nEOR\n      assert_parse(rss, :nothing_raised)\n      assert_not_expected_tag(name, uri, \"RDF\") do\n        Parser.parse(rss, true, false)\n      end\n\n      uri = ::RSS::URI\n      name = \"a\"\n      rss = make_RDF(<<-EOR)\n#{make_channel}\n#{make_item}\n#{make_image(\"<#{name}/>\")}\nEOR\n      assert_parse(rss, :nothing_raised)\n      assert_not_expected_tag(name, uri, \"image\") do\n        Parser.parse(rss, true, false)\n      end\n      \n      uri = CONTENT_URI\n      name = \"encoded\"\n      elem = \"<#{name} xmlns='#{uri}'/>\"\n      rss = make_RDF(<<-EOR)\n#{make_channel}\n#{make_item}\n#{make_image(elem)}\nEOR\n      assert_parse(rss, :nothing_raised)\n      assert_not_expected_tag(name, uri, \"image\") do\n        Parser.parse(rss, true, false)\n      end\n    end\n\n    def test_unknown_duplicated_element\n      xmlns = {\"test\" => \"http://localhost/test\"}\n      assert_parse(make_RDF(<<-EOR, xmlns), :nothing_raised)\n        #{make_channel(\"<test:string/>\")}\n        #{make_item}\n        #{make_image}\n      EOR\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_parser_2.0.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/2.0\"\n\nmodule RSS\n  class TestParser20 < TestCase\n    def test_rss20\n      assert_parse(make_rss20(<<-EOR), :missing_tag, \"channel\", \"rss\")\nEOR\n\n      assert_parse(make_rss20(<<-EOR), :nothing_raised)\n#{make_channel20(\"\")}\nEOR\n    end\n\n    def test_cloud20\n      attrs = [\n        [\"domain\", CLOUD_DOMAIN],\n        [\"port\", CLOUD_PORT],\n        [\"path\", CLOUD_PATH],\n        [\"registerProcedure\", CLOUD_REGISTER_PROCEDURE],\n        [\"protocol\", CLOUD_PROTOCOL],\n      ]\n\n      (attrs.size + 1).times do |i|\n        missing_attr = attrs[i]\n        if missing_attr\n          meth = :missing_attribute\n          args = [\"cloud\", missing_attr[0]]\n        else\n          meth = :nothing_raised\n          args = []\n        end\n\n        cloud_attrs = []\n        attrs.each_with_index do |attr, j|\n          unless i == j\n            cloud_attrs << %Q[#{attr[0]}=\"#{attr[1]}\"]\n          end\n        end\n\n        assert_parse(make_rss20(<<-EOR), meth, *args)\n#{make_channel20(%Q[<cloud #{cloud_attrs.join(\"\\n\")}/>])}\nEOR\n      end\n    end\n\n    def test_source20\n        assert_parse(make_rss20(<<-EOR), :missing_attribute, \"source\", \"url\")\n#{make_channel20(make_item20(%Q[<source>Example</source>]))}\nEOR\n\n        assert_parse(make_rss20(<<-EOR), :nothing_raised)\n#{make_channel20(make_item20(%Q[<source url=\"http://example.com/\" />]))}\nEOR\n\n        assert_parse(make_rss20(<<-EOR), :nothing_raised)\n#{make_channel20(make_item20(%Q[<source url=\"http://example.com/\">Example</source>]))}\nEOR\n    end\n\n    def test_enclosure20\n      attrs = [\n        [\"url\", ENCLOSURE_URL],\n        [\"length\", ENCLOSURE_LENGTH],\n        [\"type\", ENCLOSURE_TYPE],\n      ]\n\n      (attrs.size + 1).times do |i|\n        missing_attr = attrs[i]\n        if missing_attr\n          meth = :missing_attribute\n          args = [\"enclosure\", missing_attr[0]]\n        else\n          meth = :nothing_raised\n          args = []\n        end\n\n        enclosure_attrs = []\n        attrs.each_with_index do |attr, j|\n          unless i == j\n            enclosure_attrs << %Q[#{attr[0]}=\"#{attr[1]}\"]\n          end\n        end\n\n        assert_parse(make_rss20(<<-EOR), meth, *args)\n#{make_channel20(%Q[\n#{make_item20(%Q[\n<enclosure\n  #{enclosure_attrs.join(\"\\n\")} />\n    ])}\n  ])}\nEOR\n      end\n    end\n\n    def test_category20\n      values = [nil, CATEGORY_DOMAIN]\n      values.each do |value|\n        domain = \"\"\n        domain << %Q[domain=\"#{value}\"] if value\n\n        [\"\", \"Example Text\"].each do |text|\n          rss_src = make_rss20(<<-EOR)\n#{make_channel20(%Q[\n#{make_item20(%Q[\n<category #{domain}>#{text}</category>\n    ])}\n  ])}\nEOR\n          assert_parse(rss_src, :nothing_raised)\n\n          rss = RSS::Parser.parse(rss_src)\n          category = rss.items.last.categories.first\n          assert_equal(value, category.domain)\n          assert_equal(text, category.content)\n        end\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "test/rss/test_parser_atom_entry.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/atom\"\n\nmodule RSS\n  class TestParserAtom < TestCase\n    def test_entry_validation\n      assert_ns(\"\", Atom::URI) do\n        Parser.parse(<<-EOA)\n<entry/>\nEOA\n      end\n\n      assert_ns(\"\", Atom::URI) do\n        Parser.parse(<<-EOA)\n<entry xmlns=\"hoge\"/>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"id\", \"entry\") do\n<entry xmlns=\"#{Atom::URI}\"/>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"title\", \"entry\") do\n<entry xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>\n</entry>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"updated\", \"entry\") do\n<entry xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>\n  <title>Example Entry</title>\n</entry>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"author\", \"entry\") do\n<entry xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>\n  <title>Example Entry</title>\n  <updated>2003-10-10T18:30:02Z</updated>\n</entry>\nEOA\n      end\n\n      assert_parse(<<-EOA, :nothing_raised) do\n<entry xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>\n  <title>Example Entry</title>\n  <updated>2003-10-10T18:30:02Z</updated>\n  <author>\n    <name>A person</name>\n  </author>\n</entry>\nEOA\n      end\n    end\n\n    def test_entry\n      entry = RSS::Parser.parse(<<-EOA)\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<entry xmlns=\"http://www.w3.org/2005/Atom\">\n  <author>\n    <name>A person</name>\n  </author>\n  <title>Atom-Powered Robots Run Amok</title>\n  <link href=\"http://example.org/2003/12/13/atom03\"/>\n  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>\n  <updated>2003-12-13T18:30:02Z</updated>\n  <summary>Some text.</summary>\n</entry>\nEOA\n      assert_not_nil(entry)\n      assert_equal(\"Atom-Powered Robots Run Amok\", entry.title.content)\n      assert_equal(\"http://example.org/2003/12/13/atom03\", entry.link.href)\n      assert_equal(\"urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a\",\n                   entry.id.content)\n      assert_equal(Time.parse(\"2003-12-13T18:30:02Z\"), entry.updated.content)\n      assert_equal(\"Some text.\", entry.summary.content)\n    end\n\n    def test_entry_author\n      assert_atom_person(\"author\", method(:make_entry_document)) do |entry|\n        assert_equal(2, entry.authors.size)\n        entry.authors.last\n      end\n    end\n\n    def test_entry_category\n      assert_atom_category(method(:make_entry_document)) do |entry|\n        assert_equal(1, entry.categories.size)\n        entry.category\n      end\n    end\n\n    def test_entry_content_text\n      assert_atom_content(method(:make_entry_document)) do |entry|\n        entry.content\n      end\n    end\n\n    def test_entry_contributor\n      assert_atom_person(\"contributor\", method(:make_entry_document)) do |entry|\n        assert_equal(1, entry.contributors.size)\n        entry.contributor\n      end\n    end\n\n    def test_entry_id\n      entry = RSS::Parser.parse(make_entry_document)\n      assert_equal(ENTRY_ID, entry.id.content)\n    end\n\n    def test_entry_link\n      assert_atom_link(method(:make_entry_document)) do |entry|\n        assert_equal(1, entry.links.size)\n        entry.link\n      end\n    end\n\n    def test_published\n      generator = method(:make_entry_document)\n      assert_atom_date_construct(\"published\", generator) do |entry|\n        entry.published\n      end\n    end\n\n    def test_entry_rights\n      generator = method(:make_entry_document)\n      assert_atom_text_construct(\"rights\", generator) do |entry|\n        entry.rights\n      end\n    end\n\n    def test_entry_source\n      generator = method(:make_entry_document_with_open_source)\n      assert_atom_source(generator) do |entry|\n        assert_not_nil(entry.source)\n        entry.source\n      end\n    end\n\n    def test_entry_summary\n      generator = method(:make_entry_document)\n      assert_atom_text_construct(\"summary\", generator) do |entry|\n        entry.summary\n      end\n    end\n\n    def test_entry_title\n      entry = RSS::Parser.parse(make_entry_document)\n      assert_equal(ENTRY_TITLE, entry.title.content)\n    end\n\n    def test_entry_updated\n      entry = RSS::Parser.parse(make_entry_document)\n      assert_equal(Time.parse(ENTRY_UPDATED), entry.updated.content)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_parser_atom_feed.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/atom\"\n\nmodule RSS\n  class TestParserAtomFeed < TestCase\n    def test_feed_validation\n      assert_ns(\"\", Atom::URI) do\n        Parser.parse(<<-EOA)\n<feed/>\nEOA\n      end\n\n      assert_ns(\"\", Atom::URI) do\n        Parser.parse(<<-EOA)\n<feed xmlns=\"hoge\"/>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"id\", \"feed\") do\n<feed xmlns=\"#{Atom::URI}\"/>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"title\", \"feed\") do\n<feed xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n</feed>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"updated\", \"feed\") do\n<feed xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n  <title>Example Feed</title>\n</feed>\nEOA\n      end\n\n      assert_parse(<<-EOA, :missing_tag, \"author\", \"feed\") do\n<feed xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n  <title>Example Feed</title>\n  <updated>2003-12-13T18:30:02Z</updated>\n</feed>\nEOA\n      end\n\n      assert_parse(<<-EOA, :nothing_raised) do\n<feed xmlns=\"#{Atom::URI}\">\n  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n  <title>Example Feed</title>\n  <updated>2003-12-13T18:30:02Z</updated>\n  <author>\n    <name>A person</name>\n  </author>\n</feed>\nEOA\n      end\n    end\n\n    def test_lang\n      feed = RSS::Parser.parse(<<-EOA)\n<feed xmlns=\"#{Atom::URI}\" xml:lang=\"ja\">\n  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n  <title xml:lang=\"en\">Example Feed</title>\n  <updated>2003-12-13T18:30:02Z</updated>\n  <author xml:lang=\"en\">\n    <name>A person</name>\n  </author>\n</feed>\nEOA\n\n      assert_equal(\"ja\", feed.lang)\n      assert_equal(\"ja\", feed.id.lang)\n      assert_equal(\"en\", feed.title.lang)\n      assert_equal(\"ja\", feed.updated.lang)\n      assert_equal(\"en\", feed.author.lang)\n      assert_equal(\"en\", feed.author.name.lang)\n    end\n\n    def test_base\n      feed = RSS::Parser.parse(<<-EOA)\n<feed xmlns=\"#{Atom::URI}\" xml:base=\"http://example.com/\">\n  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>\n  <title xml:lang=\"en\">Example Feed</title>\n  <updated>2003-12-13T18:30:02Z</updated>\n  <generator uri=\"generator\">Generator</generator>\n  <link hreflang=\"ja\" href=\"http://example.org/link1\"/>\n  <link hreflang=\"en\" href=\"link2\"/>\n  <link hreflang=\"fr\" xml:base=\"http://example.net/\" href=\"link3\"/>\n  <author>\n    <name>A person</name>\n    <uri>person</uri>\n  </author>\n</feed>\nEOA\n\n      assert_equal(\"http://example.com/\", feed.base)\n      assert_equal(\"http://example.com/\", feed.id.base)\n      assert_equal(\"http://example.com/\", feed.title.base)\n      assert_equal(\"http://example.com/\", feed.updated.base)\n      assert_equal(\"http://example.com/\", feed.generator.base)\n      assert_equal(\"http://example.com/generator\", feed.generator.uri)\n\n      assert_equal(\"http://example.com/\", feed.links[0].base)\n      assert_equal(\"http://example.org/link1\", feed.links[0].href)\n      assert_equal(\"http://example.com/\", feed.links[1].base)\n      assert_equal(\"http://example.com/link2\", feed.links[1].href)\n      assert_equal(\"http://example.net/\", feed.links[2].base)\n      assert_equal(\"http://example.net/link3\", feed.links[2].href)\n      assert_equal(\"http://example.com/person\", feed.author.uri.content)\n    end\n\n    def test_feed_author\n      assert_atom_person(\"author\", method(:make_feed)) do |feed|\n        assert_equal(2, feed.authors.size)\n        feed.authors[1]\n      end\n    end\n\n    def test_entry_author\n      generator = method(:make_feed_with_open_entry)\n      assert_atom_person(\"author\", generator) do |feed|\n        assert_equal(1, feed.entries.size)\n        assert_equal(1, feed.entry.authors.size)\n        feed.entry.author\n      end\n    end\n\n    def test_feed_category\n      assert_atom_category(method(:make_feed)) do |feed|\n        assert_equal(1, feed.categories.size)\n        feed.category\n      end\n    end\n\n    def test_entry_category\n      assert_atom_category(method(:make_feed_with_open_entry)) do |feed|\n        assert_equal(1, feed.entries.size)\n        assert_equal(1, feed.entry.categories.size)\n        feed.entry.category\n      end\n    end\n\n    def test_entry_content\n      assert_atom_content(method(:make_feed_with_open_entry)) do |feed|\n        assert_equal(1, feed.entries.size)\n        feed.entry.content\n      end\n    end\n\n    def test_feed_contributor\n      assert_atom_person(\"contributor\", method(:make_feed)) do |feed|\n        assert_equal(1, feed.contributors.size)\n        feed.contributor\n      end\n    end\n\n    def test_entry_contributor\n      generator = method(:make_feed_with_open_entry)\n      assert_atom_person(\"contributor\", generator) do |feed|\n        assert_equal(1, feed.entries.size)\n        assert_equal(1, feed.entry.contributors.size)\n        feed.entry.contributor\n      end\n    end\n\n    def test_feed_generator\n      assert_atom_generator(method(:make_feed)) do |feed|\n        feed.generator\n      end\n    end\n\n    def test_feed_icon\n      assert_atom_icon(method(:make_feed)) do |feed|\n        feed.icon\n      end\n    end\n\n    def test_feed_id\n      feed = RSS::Parser.parse(make_feed(''))\n      assert_equal(FEED_ID, feed.id.content)\n    end\n\n    def test_entry_id\n      feed = RSS::Parser.parse(make_feed(''))\n      assert_equal(ENTRY_ID, feed.entry.id.content)\n    end\n\n    def test_feed_link\n      assert_atom_link(method(:make_feed)) do |feed|\n        assert_equal(1, feed.links.size)\n        feed.link\n      end\n    end\n\n    def test_entry_link\n      assert_atom_link(method(:make_feed_with_open_entry)) do |feed|\n        assert_equal(1, feed.entries.size)\n        assert_equal(1, feed.entry.links.size)\n        feed.entry.link\n      end\n    end\n\n    def test_feed_logo\n      assert_atom_logo(method(:make_feed)) do |feed|\n        feed.logo\n      end\n    end\n\n    def test_feed_rights\n      assert_atom_text_construct(\"rights\", method(:make_feed)) do |feed|\n        feed.rights\n      end\n    end\n\n    def test_entry_rights\n      generator = method(:make_feed_with_open_entry)\n      assert_atom_text_construct(\"rights\", generator) do |feed|\n        assert_equal(1, feed.entries.size)\n        feed.entry.rights\n      end\n    end\n\n    def test_entry_source\n      assert_atom_source(method(:make_feed_with_open_entry_source)) do |feed|\n        assert_equal(1, feed.entries.size)\n        assert_not_nil(feed.entry.source)\n        feed.entry.source\n      end\n    end\n\n    def test_feed_subtitle\n      assert_atom_text_construct(\"subtitle\", method(:make_feed)) do |feed|\n        feed.subtitle\n      end\n    end\n\n    def test_feed_title\n      feed = RSS::Parser.parse(make_feed(''))\n      assert_equal(FEED_TITLE, feed.title.content)\n    end\n\n    def test_entry_title\n      feed = RSS::Parser.parse(make_feed(''))\n      assert_equal(ENTRY_TITLE, feed.entry.title.content)\n    end\n\n    def test_feed_updated\n      feed = RSS::Parser.parse(make_feed(''))\n      assert_equal(Time.parse(FEED_UPDATED), feed.updated.content)\n    end\n\n    def test_entry_updated\n      feed = RSS::Parser.parse(make_feed(''))\n      assert_equal(Time.parse(ENTRY_UPDATED), feed.entry.updated.content)\n    end\n\n    def test_entry_published\n      generator = method(:make_feed_with_open_entry)\n      assert_atom_date_construct(\"published\", generator) do |feed|\n        assert_equal(1, feed.entries.size)\n        feed.entry.published\n      end\n    end\n\n    def test_entry_summary\n      generator = method(:make_feed_with_open_entry)\n      assert_atom_text_construct(\"summary\", generator) do |feed|\n        assert_equal(1, feed.entries.size)\n        feed.entry.summary\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_0.9.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMaker09 < TestCase\n\n    def test_setup_maker_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n      copyright = \"foo\"\n      managingEditor = \"bar\"\n      webMaster = \"web master\"\n      rating = '(PICS-1.1 \"http://www.rsac.org/ratingsv01.html\" l gen true comment \"RSACi North America Server\" for \"http://www.rsac.org\" on \"1996.04.16T08:15-0500\" r (n 0 s 0 v 0 l 0))'\n      docs = \"http://foo.com/doc\"\n      skipDays = [\n        \"Sunday\",\n        \"Monday\",\n      ]\n      skipHours = [\n        \"0\",\n        \"13\",\n      ]\n      pubDate = Time.now\n      lastBuildDate = Time.now\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n        maker.channel.language = language\n        maker.channel.copyright = copyright\n        maker.channel.managingEditor = managingEditor\n        maker.channel.webMaster = webMaster\n        maker.channel.rating = rating\n        maker.channel.docs = docs\n        maker.channel.pubDate = pubDate\n        maker.channel.lastBuildDate = lastBuildDate\n\n        skipDays.each do |day|\n          maker.channel.skipDays.new_day do |new_day|\n            new_day.content = day\n          end\n        end\n        skipHours.each do |hour|\n          maker.channel.skipHours.new_hour do |new_hour|\n            new_hour.content = hour\n          end\n        end\n\n        setup_dummy_image(maker)\n      end\n\n      assert_not_set_error(\"maker.image\", %w(title url)) do\n        RSS::Maker.make(\"0.91\") do |maker|\n          rss.channel.setup_maker(maker)\n        end\n      end\n\n      new_rss = RSS::Maker.make(\"0.91\") do |maker|\n        rss.channel.setup_maker(maker)\n        setup_dummy_image(maker)\n      end\n      channel = new_rss.channel\n      \n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(language, channel.language)\n      assert_equal(copyright, channel.copyright)\n      assert_equal(managingEditor, channel.managingEditor)\n      assert_equal(webMaster, channel.webMaster)\n      assert_equal(rating, channel.rating)\n      assert_equal(docs, channel.docs)\n      assert_equal(pubDate, channel.pubDate)\n      assert_equal(lastBuildDate, channel.lastBuildDate)\n\n      skipDays.each_with_index do |day, i|\n        assert_equal(day, channel.skipDays.days[i].content)\n      end\n      skipHours.each_with_index do |hour, i|\n        assert_equal(hour.to_i, channel.skipHours.hours[i].content)\n      end\n\n      assert(channel.items.empty?)\n      assert_nil(channel.textInput)\n    end\n\n    def test_setup_maker_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      width = \"144\"\n      height = \"400\"\n      description = \"an image\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        maker.image.url = url\n        maker.image.width = width\n        maker.image.height = height\n        maker.image.description = description\n      end\n      \n      new_rss = RSS::Maker.make(\"0.91\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.image.setup_maker(maker)\n      end\n      \n      image = new_rss.image\n      assert_equal(title, image.title)\n      assert_equal(link, image.link)\n      assert_equal(url, image.url)\n      assert_equal(width.to_i, image.width)\n      assert_equal(height.to_i, image.height)\n      assert_equal(description, image.description)\n    end\n    \n    def test_setup_maker_textinput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n\n      new_rss = RSS::Maker.make(\"0.91\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.image.setup_maker(maker)\n        rss.textinput.setup_maker(maker)\n      end\n      \n      textInput = new_rss.channel.textInput\n      assert_equal(title, textInput.title)\n      assert_equal(description, textInput.description)\n      assert_equal(name, textInput.name)\n      assert_equal(link, textInput.link)\n    end\n\n    def test_setup_maker_items(for_backward_compatibility=false)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n\n      item_size = 5\n      \n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n          end\n        end\n\n        setup_dummy_image(maker)\n      end\n      \n      new_rss = RSS::Maker.make(\"0.91\") do |maker|\n        rss.channel.setup_maker(maker)\n\n        rss.items.each do |item|\n          if for_backward_compatibility\n            item.setup_maker(maker)\n          else\n            item.setup_maker(maker.items)\n          end\n        end\n\n        rss.image.setup_maker(maker)\n      end\n\n      assert_equal(item_size, new_rss.items.size)\n      new_rss.items.each_with_index do |item, i|\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n      end\n    end\n\n    def test_setup_maker_items_backward_compatibility\n      test_setup_maker_items(true)\n    end\n    \n    def test_setup_maker\n      encoding = \"EUC-JP\"\n      standalone = true\n      \n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        setup_dummy_channel(maker)\n        setup_dummy_image(maker)\n      end\n\n      new_rss = RSS::Maker.make(\"0.91\") do |maker|\n        rss.setup_maker(maker)\n      end\n      \n      assert_equal(\"0.91\", new_rss.rss_version)\n      assert_equal(encoding, new_rss.encoding)\n      assert_equal(standalone, new_rss.standalone)\n\n      xss = rss.xml_stylesheets.first\n      assert_equal(1, rss.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_1.0.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMaker10 < TestCase\n\n    def setup\n      t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n      \n      @dc_elems = {\n        :title => \"hoge\",\n        :description =>\n          \" XML is placing increasingly heavy loads on\n          the existing technical infrastructure of the Internet.\",\n        :creator => \"Rael Dornfest (mailto:rael@oreilly.com)\",\n        :subject => \"XML\",\n        :publisher => \"The O'Reilly Network\",\n        :contributor => \"hogehoge\",\n        :type => \"fugafuga\",\n        :format => \"hohoho\",\n        :identifier => \"fufufu\",\n        :source => \"barbar\",\n        :language => \"ja\",\n        :relation => \"cococo\",\n        :rights => \"Copyright (c) 2000 O'Reilly &amp; Associates, Inc.\",\n        :date => t,\n      }\n\n      @sy_elems = {\n        :updatePeriod => \"hourly\",\n        :updateFrequency => \"2\",\n        :updateBase => t,\n      }\n\n      @content_elems = {\n        :encoded => \"<em>ATTENTION</em>\",\n      }\n      \n      @trackback_elems = {\n        :ping => \"http://bar.com/tb.cgi?tb_id=rssplustrackback\",\n        :about => [\n          \"http://foo.com/trackback/tb.cgi?tb_id=20020923\",\n          \"http://foo.com/trackback/tb.cgi?tb_id=20021010\",\n        ],\n      }\n\n      @taxo_topic_elems = [\n        {\n          :link => \"http://meerkat.oreillynet.com/?c=cat23\",\n          :title => \"Data: XML\",\n          :description => \"A Meerkat channel\",\n        },\n        {\n          :link => \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/\",\n          :title => \"XML\",\n          :subject => \"XML\",\n          :description => \"DMOZ category\",\n          :topics => [\n            \"http://meerkat.oreillynet.com/?c=cat23\",\n            \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/\",\n            \"http://dmoz.org/Computers/Programming/Internet/\",\n          ]\n        },\n      ]\n    end\n    \n    def test_setup_maker_channel\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.channel.about = about\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n        \n        @dc_elems.each do |var, value|\n          maker.channel.__send__(\"dc_#{var}=\", value)\n        end\n\n        @sy_elems.each do |var, value|\n          maker.channel.__send__(\"sy_#{var}=\", value)\n        end\n\n        setup_dummy_item(maker)\n      end\n\n      new_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.items.each do |item|\n          item.setup_maker(maker)\n        end\n      end\n      channel = new_rss.channel\n      \n      assert_equal(about, channel.about)\n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(1, channel.items.Seq.lis.size)\n      assert_nil(channel.image)\n      assert_nil(channel.textinput)\n\n      @dc_elems.each do |var, value|\n        assert_equal(value, channel.__send__(\"dc_#{var}\"))\n      end\n      \n      @sy_elems.each do |var, value|\n        value = value.to_i if var == :updateFrequency\n        assert_equal(value, channel.__send__(\"sy_#{var}\"))\n      end\n      \n    end\n\n    def test_setup_maker_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        maker.image.url = url\n\n        @dc_elems.each do |var, value|\n          maker.image.__send__(\"dc_#{var}=\", value)\n        end\n\n        setup_dummy_item(maker)\n      end\n      \n      new_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.image.setup_maker(maker)\n        rss.items.each do |item|\n          item.setup_maker(maker)\n        end\n      end\n      \n      image = new_rss.image\n      assert_equal(url, image.about)\n      assert_equal(url, new_rss.channel.image.resource)\n      assert_equal(title, image.title)\n      assert_equal(link, image.link)\n      assert_equal(url, image.url)\n\n      @dc_elems.each do |var, value|\n        assert_equal(image.__send__(\"dc_#{var}\"), value)\n      end\n    end\n    \n    def test_setup_maker_textinput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        maker.textinput.link = link\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n\n        @dc_elems.each do |var, value|\n          maker.textinput.__send__(\"dc_#{var}=\", value)\n        end\n\n        setup_dummy_item(maker)\n      end\n      \n      new_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.textinput.setup_maker(maker)\n        rss.items.each do |item|\n          item.setup_maker(maker)\n        end\n      end\n      \n      textinput = new_rss.textinput\n      assert_equal(link, textinput.about)\n      assert_equal(link, new_rss.channel.textinput.resource)\n      assert_equal(title, textinput.title)\n      assert_equal(name, textinput.name)\n      assert_equal(description, textinput.description)\n      assert_equal(link, textinput.link)\n\n      @dc_elems.each do |var, value|\n        assert_equal(textinput.__send__(\"dc_#{var}\"), value)\n      end\n    end\n\n    def test_setup_maker_items(for_backward_compatibility=false)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n\n      item_size = 5\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n\n            @dc_elems.each do |var, value|\n              item.__send__(\"dc_#{var}=\", value)\n            end\n\n            @content_elems.each do |var, value|\n              item.__send__(\"content_#{var}=\", value)\n            end\n\n            item.trackback_ping = @trackback_elems[:ping]\n            @trackback_elems[:about].each do |value|\n              item.trackback_abouts.new_about do |new_about|\n                new_about.value = value\n              end\n            end\n          end\n        end\n      end\n      \n      new_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.channel.setup_maker(maker)\n\n        rss.items.each do |item|\n          if for_backward_compatibility\n            item.setup_maker(maker)\n          else\n            item.setup_maker(maker.items)\n          end\n        end\n      end\n      \n      assert_equal(item_size, new_rss.items.size)\n      new_rss.items.each_with_index do |item, i|\n        assert_equal(\"#{link}#{i}\", item.about)\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n\n        @dc_elems.each do |var, value|\n          assert_equal(item.__send__(\"dc_#{var}\"), value)\n        end\n      \n        @content_elems.each do |var, value|\n          assert_equal(item.__send__(\"content_#{var}\"), value)\n        end\n      \n        assert_equal(@trackback_elems[:ping], item.trackback_ping)\n        assert_equal(@trackback_elems[:about].size, item.trackback_abouts.size)\n        item.trackback_abouts.each_with_index do |about, j|\n          assert_equal(@trackback_elems[:about][j], about.value)\n        end\n      end\n    end\n\n    def test_setup_maker_items_sort\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n\n      item_size = 5\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          item = RSS::RDF::Item.new(\"#{link}#{i}\")\n          item.title = \"#{title}#{i}\"\n          item.link = \"#{link}#{i}\"\n          item.description = \"#{description}#{i}\"\n          item.dc_date = Time.now + i * 60\n          item.setup_maker(maker.items)\n        end\n        maker.items.do_sort = false\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.items.each_with_index do |item, i|\n        assert_equal(\"#{link}#{i}\", item.about)\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n      end\n\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          item = RSS::RDF::Item.new(\"#{link}#{i}\")\n          item.title = \"#{title}#{i}\"\n          item.link = \"#{link}#{i}\"\n          item.description = \"#{description}#{i}\"\n          item.dc_date = Time.now + i * 60\n          item.setup_maker(maker.items)\n        end\n        maker.items.do_sort = true\n      end\n      assert_equal(item_size, rss.items.size)\n      rss.items.reverse.each_with_index do |item, i|\n        assert_equal(\"#{link}#{i}\", item.about)\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n      end\n    end\n\n    def test_setup_maker_items_backward_compatibility\n      test_setup_maker_items(true)\n    end\n    \n    def test_setup_maker\n      encoding = \"EUC-JP\"\n      standalone = true\n      \n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n      end\n      \n      new_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.setup_maker(maker)\n      end\n      \n      assert_equal(\"1.0\", new_rss.rss_version)\n      assert_equal(encoding, new_rss.encoding)\n      assert_equal(standalone, new_rss.standalone)\n\n      xss = new_rss.xml_stylesheets.first\n      assert_equal(1, new_rss.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n    end\n\n    def test_setup_maker_full\n      encoding = \"EUC-JP\"\n      standalone = true\n      \n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      channel_about = \"http://hoge.com\"\n      channel_title = \"fugafuga\"\n      channel_link = \"http://hoge.com\"\n      channel_description = \"fugafugafugafuga\"\n\n      image_title = \"fugafuga\"\n      image_url = \"http://hoge.com/hoge.png\"\n      \n      textinput_title = \"fugafuga\"\n      textinput_description = \"text hoge fuga\"\n      textinput_name = \"hoge\"\n      textinput_link = \"http://hoge.com\"\n      \n      item_title = \"TITLE\"\n      item_link = \"http://hoge.com/\"\n      item_description = \"text hoge fuga\"\n\n      item_size = 5\n      \n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        maker.channel.about = channel_about\n        maker.channel.title = channel_title\n        maker.channel.link = channel_link\n        maker.channel.description = channel_description\n        @dc_elems.each do |var, value|\n          maker.channel.__send__(\"dc_#{var}=\", value)\n        end\n        @sy_elems.each do |var, value|\n          maker.channel.__send__(\"sy_#{var}=\", value)\n        end\n        \n        maker.image.title = image_title\n        maker.image.url = image_url\n        @dc_elems.each do |var, value|\n          maker.image.__send__(\"dc_#{var}=\", value)\n        end\n        \n        maker.textinput.link = textinput_link\n        maker.textinput.title = textinput_title\n        maker.textinput.description = textinput_description\n        maker.textinput.name = textinput_name\n        @dc_elems.each do |var, value|\n          maker.textinput.__send__(\"dc_#{var}=\", value)\n        end\n        \n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{item_title}#{i}\"\n            item.link = \"#{item_link}#{i}\"\n            item.description = \"#{item_description}#{i}\"\n\n            @dc_elems.each do |var, value|\n              item.__send__(\"dc_#{var}=\", value)\n            end\n\n            @content_elems.each do |var, value|\n              item.__send__(\"content_#{var}=\", value)\n            end\n\n            item.trackback_ping = @trackback_elems[:ping]\n            @trackback_elems[:about].each do |value|\n              item.trackback_abouts.new_about do |new_about|\n                new_about.value = value\n              end\n            end\n          end\n        end\n\n        setup_taxo_topic(maker, @taxo_topic_elems)\n      end\n      \n      new_rss = RSS::Maker.make(\"1.0\") do |maker|\n        rss.setup_maker(maker)\n      end\n      \n      assert_equal(\"1.0\", new_rss.rss_version)\n      assert_equal(encoding, new_rss.encoding)\n      assert_equal(standalone, new_rss.standalone)\n\n      xss = new_rss.xml_stylesheets.first\n      assert_equal(1, new_rss.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n\n      channel = new_rss.channel\n      assert_equal(channel_about, channel.about)\n      assert_equal(channel_title, channel.title)\n      assert_equal(channel_link, channel.link)\n      assert_equal(channel_description, channel.description)\n      item_resources = []\n      item_size.times do |i|\n        item_resources << \"#{item_link}#{i}\"\n      end\n      assert_equal(item_resources, channel.items.resources)\n      assert_equal(image_url, channel.image.resource)\n      assert_equal(textinput_link, channel.textinput.resource)\n      @dc_elems.each do |var, value|\n        assert_equal(value, channel.__send__(\"dc_#{var}\"))\n      end\n      @sy_elems.each do |var, value|\n        value = value.to_i if var == :updateFrequency\n        assert_equal(value, channel.__send__(\"sy_#{var}\"))\n      end\n\n      image = new_rss.image\n      assert_equal(image_url, image.about)\n      assert_equal(image_url, new_rss.channel.image.resource)\n      assert_equal(image_title, image.title)\n      assert_equal(channel_link, image.link)\n      assert_equal(image_url, image.url)\n      @dc_elems.each do |var, value|\n        assert_equal(image.__send__(\"dc_#{var}\"), value)\n      end\n      \n      textinput = new_rss.textinput\n      assert_equal(textinput_link, textinput.about)\n      assert_equal(textinput_link, new_rss.channel.textinput.resource)\n      assert_equal(textinput_title, textinput.title)\n      assert_equal(textinput_name, textinput.name)\n      assert_equal(textinput_description, textinput.description)\n      assert_equal(textinput_link, textinput.link)\n      @dc_elems.each do |var, value|\n        assert_equal(textinput.__send__(\"dc_#{var}\"), value)\n      end\n\n      assert_equal(item_size, new_rss.items.size)\n      new_rss.items.each_with_index do |item, i|\n        assert_equal(\"#{item_link}#{i}\", item.about)\n        assert_equal(\"#{item_title}#{i}\", item.title)\n        assert_equal(\"#{item_link}#{i}\", item.link)\n        assert_equal(\"#{item_description}#{i}\", item.description)\n\n        @dc_elems.each do |var, value|\n          assert_equal(item.__send__(\"dc_#{var}\"), value)\n        end\n      \n        @content_elems.each do |var, value|\n          assert_equal(item.__send__(\"content_#{var}\"), value)\n        end\n      \n        assert_equal(@trackback_elems[:ping], item.trackback_ping)\n        assert_equal(@trackback_elems[:about].size, item.trackback_abouts.size)\n        item.trackback_abouts.each_with_index do |about, j|\n          assert_equal(@trackback_elems[:about][j], about.value)\n        end\n      end\n\n      assert_taxo_topic(@taxo_topic_elems, new_rss)\n    end\n    \n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_2.0.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMaker20 < TestCase\n\n    def test_setup_maker_channel\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      description = \"fugafugafugafuga\"\n      language = \"ja\"\n      copyright = \"foo\"\n      managingEditor = \"bar\"\n      webMaster = \"web master\"\n      rating = '(PICS-1.1 \"http://www.rsac.org/ratingsv01.html\" l gen true comment \"RSACi North America Server\" for \"http://www.rsac.org\" on \"1996.04.16T08:15-0500\" r (n 0 s 0 v 0 l 0))'\n      docs = \"http://foo.com/doc\"\n      skipDays = [\n        \"Sunday\",\n        \"Monday\",\n      ]\n      skipHours = [\n        \"0\",\n        \"13\",\n      ]\n      pubDate = Time.now\n      lastBuildDate = Time.now\n      categories = [\n        \"Nespapers\",\n        \"misc\",\n      ]\n      generator = \"RSS Maker\"\n      ttl = \"60\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        maker.channel.title = title\n        maker.channel.link = link\n        maker.channel.description = description\n        maker.channel.language = language\n        maker.channel.copyright = copyright\n        maker.channel.managingEditor = managingEditor\n        maker.channel.webMaster = webMaster\n        maker.channel.rating = rating\n        maker.channel.docs = docs\n        maker.channel.pubDate = pubDate\n        maker.channel.lastBuildDate = lastBuildDate\n\n        skipDays.each do |day|\n          maker.channel.skipDays.new_day do |new_day|\n            new_day.content = day\n          end\n        end\n        skipHours.each do |hour|\n          maker.channel.skipHours.new_hour do |new_hour|\n            new_hour.content = hour\n          end\n        end\n\n\n        categories.each do |category|\n          maker.channel.categories.new_category do |new_category|\n            new_category.content = category\n          end\n        end\n        \n        maker.channel.generator = generator\n        maker.channel.ttl = ttl\n      end\n\n      new_rss = RSS::Maker.make(\"2.0\") do |maker|\n        rss.channel.setup_maker(maker)\n      end\n      channel = new_rss.channel\n      \n      assert_equal(title, channel.title)\n      assert_equal(link, channel.link)\n      assert_equal(description, channel.description)\n      assert_equal(language, channel.language)\n      assert_equal(copyright, channel.copyright)\n      assert_equal(managingEditor, channel.managingEditor)\n      assert_equal(webMaster, channel.webMaster)\n      assert_equal(rating, channel.rating)\n      assert_equal(docs, channel.docs)\n      assert_equal(pubDate, channel.pubDate)\n      assert_equal(lastBuildDate, channel.lastBuildDate)\n\n      skipDays.each_with_index do |day, i|\n        assert_equal(day, channel.skipDays.days[i].content)\n      end\n      skipHours.each_with_index do |hour, i|\n        assert_equal(hour.to_i, channel.skipHours.hours[i].content)\n      end\n      \n\n      channel.categories.each_with_index do |category, i|\n        assert_equal(categories[i], category.content)\n      end\n      \n      assert_equal(generator, channel.generator)\n      assert_equal(ttl.to_i, channel.ttl)\n\n\n      assert(channel.items.empty?)\n      assert_nil(channel.image)\n      assert_nil(channel.textInput)\n    end\n\n    def test_setup_maker_image\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      url = \"http://hoge.com/hoge.png\"\n      width = \"144\"\n      height = \"400\"\n      description = \"an image\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        maker.channel.link = link\n        \n        maker.image.title = title\n        maker.image.url = url\n        maker.image.width = width\n        maker.image.height = height\n        maker.image.description = description\n      end\n      \n      new_rss = RSS::Maker.make(\"2.0\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.image.setup_maker(maker)\n      end\n      \n      image = new_rss.image\n      assert_equal(title, image.title)\n      assert_equal(link, image.link)\n      assert_equal(url, image.url)\n      assert_equal(width.to_i, image.width)\n      assert_equal(height.to_i, image.height)\n      assert_equal(description, image.description)\n    end\n    \n    def test_setup_maker_textinput\n      title = \"fugafuga\"\n      description = \"text hoge fuga\"\n      name = \"hoge\"\n      link = \"http://hoge.com\"\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n\n        maker.textinput.title = title\n        maker.textinput.description = description\n        maker.textinput.name = name\n        maker.textinput.link = link\n      end\n\n      new_rss = RSS::Maker.make(\"2.0\") do |maker|\n        rss.channel.setup_maker(maker)\n        rss.textinput.setup_maker(maker)\n      end\n      \n      textInput = new_rss.channel.textInput\n      assert_equal(title, textInput.title)\n      assert_equal(description, textInput.description)\n      assert_equal(name, textInput.name)\n      assert_equal(link, textInput.link)\n    end\n\n    def test_setup_maker_items(for_backward_compatibility=false)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n      author = \"oprah@oxygen.net\"\n      comments = \"http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290\"\n      pubDate = Time.now\n\n      guid_isPermaLink = \"true\"\n      guid_content = \"http://inessential.com/2002/09/01.php#a2\"\n      \n      enclosure_url = \"http://www.scripting.com/mp3s/weatherReportSuite.mp3\"\n      enclosure_length = \"12216320\"\n      enclosure_type = \"audio/mpeg\"\n\n      source_url = \"http://static.userland.com/tomalak/links2.xml\"\n      source_content = \"Tomalak's Realm\"\n      \n      category_domain = \"http://www.fool.com/cusips\"\n      category_content = \"MSFT\"\n      \n      item_size = 5\n      \n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_dummy_channel(maker)\n        \n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n            item.author = \"#{author}#{i}\"\n            item.comments = \"#{comments}#{i}\"\n            item.date = pubDate\n\n            item.guid.isPermaLink = guid_isPermaLink\n            item.guid.content = guid_content\n\n            item.enclosure.url = enclosure_url\n            item.enclosure.length = enclosure_length\n            item.enclosure.type = enclosure_type\n\n            item.source.url = source_url\n            item.source.content = source_content\n\n            category = item.categories.new_category\n            category.domain = category_domain\n            category.content = category_content\n          end\n        end\n      end\n      \n      new_rss = RSS::Maker.make(\"2.0\") do |maker|\n        rss.channel.setup_maker(maker)\n\n        rss.items.each do |item|\n          if for_backward_compatibility\n            item.setup_maker(maker)\n          else\n            item.setup_maker(maker.items)\n          end\n        end\n      end\n      \n      assert_equal(item_size, new_rss.items.size)\n      new_rss.items.each_with_index do |item, i|\n        assert_equal(\"#{title}#{i}\", item.title)\n        assert_equal(\"#{link}#{i}\", item.link)\n        assert_equal(\"#{description}#{i}\", item.description)\n        assert_equal(\"#{author}#{i}\", item.author)\n        assert_equal(\"#{comments}#{i}\", item.comments)\n        assert_equal(pubDate, item.pubDate)\n\n        assert_equal(guid_isPermaLink == \"true\", item.guid.isPermaLink)\n        assert_equal(guid_content, item.guid.content)\n\n        assert_equal(enclosure_url, item.enclosure.url)\n        assert_equal(enclosure_length.to_i, item.enclosure.length)\n        assert_equal(enclosure_type, item.enclosure.type)\n\n        assert_equal(source_url, item.source.url)\n        assert_equal(source_content, item.source.content)\n\n        assert_equal(1, item.categories.size)\n        assert_equal(category_domain, item.category.domain)\n        assert_equal(category_content, item.category.content)\n      end\n\n    end\n\n    def test_setup_maker_items_backward_compatibility\n      test_setup_maker_items(true)\n    end\n    \n    def test_setup_maker\n      encoding = \"EUC-JP\"\n      standalone = true\n      \n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        setup_dummy_channel(maker)\n      end\n      \n      new_rss = RSS::Maker.make(\"2.0\") do |maker|\n        rss.setup_maker(maker)\n      end\n      \n      assert_equal(\"2.0\", new_rss.rss_version)\n      assert_equal(encoding, new_rss.encoding)\n      assert_equal(standalone, new_rss.standalone)\n\n      xss = rss.xml_stylesheets.first\n      assert_equal(1, rss.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n    end\n    \n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_atom_entry.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMakerAtomEntry < TestCase\n    def setup\n      t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n\n      @dc_elems = {\n        :title => \"hoge\",\n        :description =>\n          \" XML is placing increasingly heavy loads on\n          the existing technical infrastructure of the Internet.\",\n        :creator => \"Rael Dornfest (mailto:rael@oreilly.com)\",\n        :subject => \"XML\",\n        :publisher => \"The O'Reilly Network\",\n        :contributor => \"hogehoge\",\n        :type => \"fugafuga\",\n        :format => \"hohoho\",\n        :identifier => \"fufufu\",\n        :source => \"barbar\",\n        :language => \"ja\",\n        :relation => \"cococo\",\n        :rights => \"Copyright (c) 2000 O'Reilly &amp; Associates, Inc.\",\n        :date => t,\n      }\n    end\n\n    def test_setup_maker_entry(with_dc=true)\n      authors = [\n                 {\n                   :name => \"Bob\",\n                   :uri => \"http://example.com/~bob/\",\n                   :email => \"bob@example.com\",\n                 },\n                 {\n                   :name => \"Alice\",\n                   :uri => \"http://example.com/~alice/\",\n                   :email => \"alice@example.com\",\n                 },\n                ]\n      categories = [\n                    {\n                      :term => \"music\",\n                      :label => \"Music\",\n                    },\n                    {\n                      :term => \"book\",\n                      :scheme => \"http://example.com/category/book/\",\n                      :label => \"Book\",\n                    },\n                   ]\n      contributors = [\n                      {\n                        :name => \"Chris\",\n                        :email => \"chris@example.com\",\n                      },\n                      {\n                        :name => \"Eva\",\n                        :uri => \"http://example.com/~eva/\",\n                      },\n                     ]\n      id = \"urn:uuid:8b105336-7e20-45fc-bb78-37fb3e1db25a\"\n      link = \"http://hoge.com\"\n      published = Time.now - 60 * 3600\n      rights = \"Copyrights (c) 2007 Alice and Bob\"\n      description = \"fugafugafugafuga\"\n      title = \"fugafuga\"\n      updated = Time.now\n\n      feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        maker.items.new_item do |item|\n          authors.each do |author_info|\n            item.authors.new_author do |author|\n              author_info.each do |key, value|\n                author.__send__(\"#{key}=\", value)\n              end\n            end\n          end\n\n          categories.each do |category_info|\n            item.categories.new_category do |category|\n              category_info.each do |key, value|\n                category.__send__(\"#{key}=\", value)\n              end\n            end\n          end\n\n          contributors.each do |contributor_info|\n            item.contributors.new_contributor do |contributor|\n              contributor_info.each do |key, value|\n                contributor.__send__(\"#{key}=\", value)\n              end\n            end\n          end\n\n          item.id = id\n          item.link = link\n          item.published = published\n          item.rights = rights\n          item.description = description\n          item.title = title\n          item.updated = updated\n\n          if with_dc\n            @dc_elems.each do |var, value|\n              if var == :date\n                item.new_dc_date(value)\n              else\n                item.__send__(\"dc_#{var}=\", value)\n              end\n            end\n          end\n        end\n      end\n      assert_not_nil(feed)\n\n      new_feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        feed.setup_maker(maker)\n      end\n      assert_not_nil(new_feed)\n\n      new_authors = new_feed.authors.collect do |author|\n        {\n          :name => author.name.content,\n          :uri => author.uri.content,\n          :email => author.email.content,\n        }\n      end\n      assert_equal(authors, new_authors)\n\n      new_categories = new_feed.categories.collect do |category|\n        {\n          :term => category.term,\n          :scheme => category.scheme,\n          :label => category.label,\n        }.reject {|key, value| value.nil?}\n      end\n      assert_equal(categories, new_categories)\n\n      new_contributors = new_feed.contributors.collect do |contributor|\n        info = {}\n        info[:name] = contributor.name.content\n        info[:uri] = contributor.uri.content if contributor.uri\n        info[:email] = contributor.email.content if contributor.email\n        info\n      end\n      assert_equal(contributors, new_contributors)\n\n      assert_equal(id, new_feed.id.content)\n      assert_equal(link, new_feed.link.href)\n      assert_equal(published, new_feed.published.content)\n      assert_equal(rights, new_feed.rights.content)\n      assert_equal(description, new_feed.summary.content)\n      assert_equal(title, new_feed.title.content)\n      assert_equal(updated, new_feed.updated.content)\n\n      if with_dc\n        @dc_elems.each do |var, value|\n          if var == :date\n            assert_equal([updated, value],\n                         new_feed.dc_dates.collect {|date| date.value})\n          else\n            assert_equal(value, new_feed.__send__(\"dc_#{var}\"))\n          end\n        end\n      end\n\n      assert_equal(1, new_feed.items.size)\n    end\n\n    def test_setup_maker_entry_without_dc\n      test_setup_maker_entry(false)\n    end\n\n    def test_setup_maker_items(for_backward_compatibility=false)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n      updated = Time.now\n\n      item_size = 5\n      feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n\n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n            item.updated = updated + i * 60\n          end\n        end\n      end\n\n      new_feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        feed.items.each do |item|\n          if for_backward_compatibility\n            item.setup_maker(maker)\n          else\n            item.setup_maker(maker.items)\n          end\n        end\n\n        feed.items.clear\n        feed.setup_maker(maker)\n      end\n\n      assert_equal(1, new_feed.items.size)\n      new_feed.items[0..1].each_with_index do |item, i|\n        assert_equal(\"#{title}#{i}\", item.title.content)\n        assert_equal(\"#{link}#{i}\", item.link.href)\n        assert_equal(\"#{description}#{i}\", item.summary.content)\n        assert_equal(updated + i * 60, item.updated.content)\n      end\n    end\n\n    def test_setup_maker_items_sort\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      summary = \"text hoge fuga\"\n      updated = Time.now\n\n      feed_size = 5\n      feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n\n        feed_size.times do |i|\n          entry_class = RSS::Atom::Entry\n          entry = entry_class.new\n          entry.title = entry_class::Title.new(:content => \"#{title}#{i}\")\n          entry.links << entry_class::Link.new(:href => \"#{link}#{i}\")\n          entry.summary = entry_class::Summary.new(:content => \"#{summary}#{i}\")\n          entry.updated = entry_class::Updated.new(:content => updated + i * 60)\n          entry.setup_maker(maker.items)\n        end\n        maker.items.do_sort = false\n      end\n      assert_equal(1, feed.items.size)\n\n      assert_equal(\"#{title}0\", feed.title.content)\n      assert_equal(\"#{link}0\", feed.link.href)\n      assert_equal(\"#{summary}0\", feed.summary.content)\n\n\n      feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        setup_dummy_channel_atom(maker)\n\n        feed_size.times do |i|\n          entry_class = RSS::Atom::Entry\n          entry = entry_class.new\n          entry.title = entry_class::Title.new(:content => \"#{title}#{i}\")\n          entry.links << entry_class::Link.new(:href => \"#{link}#{i}\")\n          entry.summary = entry_class::Summary.new(:content => \"#{summary}#{i}\")\n          entry.updated = entry_class::Updated.new(:content => updated + i * 60)\n          entry.setup_maker(maker.items)\n        end\n        maker.items.do_sort = true\n      end\n      assert_equal(1, feed.items.size)\n\n      assert_equal(\"#{title}#{feed_size - 1}\", feed.title.content)\n      assert_equal(\"#{link}#{feed_size - 1}\", feed.link.href)\n      assert_equal(\"#{summary}#{feed_size - 1}\", feed.summary.content)\n    end\n\n    def test_setup_maker_items_backward_compatibility\n      test_setup_maker_items(true)\n    end\n\n    def test_setup_maker\n      encoding = \"EUC-JP\"\n      standalone = true\n\n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n      assert_not_nil(feed)\n\n      new_feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        feed.setup_maker(maker)\n      end\n\n      assert_equal([\"atom\", \"1.0\", \"entry\"], new_feed.feed_info)\n      assert_equal(encoding, new_feed.encoding)\n      assert_equal(standalone, new_feed.standalone)\n\n      xss = new_feed.xml_stylesheets.first\n      assert_equal(1, new_feed.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n    end\n\n    def test_setup_maker_full\n      encoding = \"EUC-JP\"\n      standalone = true\n\n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      channel_about = \"http://hoge.com\"\n      channel_title = \"fugafuga\"\n      channel_link = \"http://hoge.com\"\n      channel_description = \"fugafugafugafuga\"\n      channel_author = \"Bob\"\n\n      image_url = \"http://hoge.com/hoge.png\"\n\n      item_title = \"TITLE\"\n      item_link = \"http://hoge.com/\"\n      item_description = \"text hoge fuga\"\n\n      entry_size = 5\n      feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        maker.channel.about = channel_about\n        maker.channel.title = channel_title\n        maker.channel.link = channel_link\n        maker.channel.description = channel_description\n        maker.channel.author = channel_author\n        @dc_elems.each do |var, value|\n          maker.channel.__send__(\"dc_#{var}=\", value)\n        end\n\n        maker.image.url = image_url\n\n        entry_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{item_title}#{i}\"\n            item.link = \"#{item_link}#{i}\"\n            item.description = \"#{item_description}#{i}\"\n\n            @dc_elems.each do |var, value|\n              item.__send__(\"dc_#{var}=\", value)\n            end\n          end\n        end\n      end\n\n      new_feed = RSS::Maker.make(\"atom:entry\") do |maker|\n        feed.setup_maker(maker)\n      end\n\n      assert_equal([\"atom\", \"1.0\", \"entry\"], new_feed.feed_info)\n      assert_equal(encoding, new_feed.encoding)\n      assert_equal(standalone, new_feed.standalone)\n\n      xss = new_feed.xml_stylesheets.first\n      assert_equal(1, new_feed.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n\n      assert_equal(\"#{item_title}0\", new_feed.title.content)\n      assert_equal(\"#{item_link}0\", new_feed.link.href)\n      assert_equal(\"#{item_description}0\", new_feed.summary.content)\n      @dc_elems.each do |var, value|\n        assert_equal(value, new_feed.__send__(\"dc_#{var}\"))\n      end\n      assert_equal(1, new_feed.items.size)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_atom_feed.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMakerAtomFeed < TestCase\n    def setup\n      t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n\n      @dc_elems = {\n        :title => \"hoge\",\n        :description =>\n          \" XML is placing increasingly heavy loads on\n          the existing technical infrastructure of the Internet.\",\n        :creator => \"Rael Dornfest (mailto:rael@oreilly.com)\",\n        :subject => \"XML\",\n        :publisher => \"The O'Reilly Network\",\n        :contributor => \"hogehoge\",\n        :type => \"fugafuga\",\n        :format => \"hohoho\",\n        :identifier => \"fufufu\",\n        :source => \"barbar\",\n        :language => \"ja\",\n        :relation => \"cococo\",\n        :rights => \"Copyright (c) 2000 O'Reilly &amp; Associates, Inc.\",\n        :date => t,\n      }\n    end\n\n    def test_setup_maker_feed(with_dc=true)\n      authors = [\n                 {\n                   :name => \"Bob\",\n                   :uri => \"http://example.com/~bob/\",\n                   :email => \"bob@example.com\",\n                 },\n                 {\n                   :name => \"Alice\",\n                   :uri => \"http://example.com/~alice/\",\n                   :email => \"alice@example.com\",\n                 },\n                ]\n      categories = [\n                    {\n                      :term => \"music\",\n                      :label => \"Music\",\n                    },\n                    {\n                      :term => \"book\",\n                      :scheme => \"http://example.com/category/book/\",\n                      :label => \"Book\",\n                    },\n                   ]\n      contributors = [\n                      {\n                        :name => \"Chris\",\n                        :email => \"chris@example.com\",\n                      },\n                      {\n                        :name => \"Eva\",\n                        :uri => \"http://example.com/~eva/\",\n                      },\n                     ]\n      generator = {\n        :uri => \"http://example.com/generator/\",\n        :version => \"0.0.1\",\n        :content => \"Feed Generator\",\n      }\n      icon = \"http://example.com/icon.png\"\n      about = \"http://hoge.com\"\n      title = \"fugafuga\"\n      link = \"http://hoge.com\"\n      logo = \"http://example.com/logo.png\"\n      rights = \"Copyrights (c) 2007 Alice and Bob\"\n      description = \"fugafugafugafuga\"\n      updated = Time.now\n\n      feed = RSS::Maker.make(\"atom\") do |maker|\n        authors.each do |author_info|\n          maker.channel.authors.new_author do |author|\n            author_info.each do |key, value|\n              author.__send__(\"#{key}=\", value)\n            end\n          end\n        end\n\n        categories.each do |category_info|\n          maker.channel.categories.new_category do |category|\n            category_info.each do |key, value|\n              category.__send__(\"#{key}=\", value)\n            end\n          end\n        end\n\n        contributors.each do |contributor_info|\n          maker.channel.contributors.new_contributor do |contributor|\n            contributor_info.each do |key, value|\n              contributor.__send__(\"#{key}=\", value)\n            end\n          end\n        end\n\n        generator.each do |key, value|\n          maker.channel.generator do |g|\n            g.__send__(\"#{key}=\", value)\n          end\n        end\n\n        maker.channel.icon = icon\n\n        maker.channel.about = about\n        maker.channel.link = link\n        maker.channel.logo = logo\n        maker.channel.rights = rights\n        maker.channel.title = title\n        maker.channel.description = description\n        maker.channel.updated = updated\n\n        if with_dc\n          @dc_elems.each do |var, value|\n            if var == :date\n              maker.channel.new_dc_date(value)\n            else\n              maker.channel.__send__(\"dc_#{var}=\", value)\n            end\n          end\n        end\n\n        setup_dummy_item_atom(maker)\n      end\n      assert_not_nil(feed)\n\n      new_feed = RSS::Maker.make(\"atom\") do |maker|\n        feed.setup_maker(maker)\n      end\n      assert_not_nil(new_feed)\n\n      new_authors = new_feed.authors.collect do |author|\n        {\n          :name => author.name.content,\n          :uri => author.uri.content,\n          :email => author.email.content,\n        }\n      end\n      assert_equal(authors, new_authors)\n\n      new_categories = new_feed.categories.collect do |category|\n        {\n          :term => category.term,\n          :scheme => category.scheme,\n          :label => category.label,\n        }.reject {|key, value| value.nil?}\n      end\n      assert_equal(categories, new_categories)\n\n      new_contributors = new_feed.contributors.collect do |contributor|\n        info = {}\n        info[:name] = contributor.name.content\n        info[:uri] = contributor.uri.content if contributor.uri\n        info[:email] = contributor.email.content if contributor.email\n        info\n      end\n      assert_equal(contributors, new_contributors)\n\n      new_generator = {\n        :uri => new_feed.generator.uri,\n        :version => new_feed.generator.version,\n        :content => new_feed.generator.content,\n      }\n      assert_equal(generator, new_generator)\n\n      assert_equal(icon, new_feed.icon.content)\n      assert_equal(about, new_feed.id.content)\n      assert_equal(link, new_feed.link.href)\n      assert_equal(logo, new_feed.logo.content)\n      assert_equal(rights, new_feed.rights.content)\n      assert_equal(description, new_feed.subtitle.content)\n      assert_equal(title, new_feed.title.content)\n      assert_equal(updated, new_feed.updated.content)\n\n      if with_dc\n        @dc_elems.each do |var, value|\n          if var == :date\n            assert_equal([updated, value],\n                         new_feed.dc_dates.collect {|date| date.value})\n          else\n            assert_equal(value, new_feed.__send__(\"dc_#{var}\"))\n          end\n        end\n      end\n\n      assert_equal(1, new_feed.items.size)\n    end\n\n    def test_setup_maker_feed_without_dc\n      test_setup_maker_feed(false)\n    end\n\n    def test_setup_maker_items(for_backward_compatibility=false)\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      description = \"text hoge fuga\"\n      updated = Time.now\n\n      item_size = 5\n      feed = RSS::Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n\n        item_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{title}#{i}\"\n            item.link = \"#{link}#{i}\"\n            item.description = \"#{description}#{i}\"\n            item.updated = updated + i * 60\n          end\n        end\n      end\n\n      new_feed = RSS::Maker.make(\"atom\") do |maker|\n        feed.items.each do |item|\n          if for_backward_compatibility\n            item.setup_maker(maker)\n          else\n            item.setup_maker(maker.items)\n          end\n        end\n\n        feed.items.clear\n        feed.setup_maker(maker)\n      end\n\n      assert_equal(item_size, new_feed.items.size)\n      new_feed.items.each_with_index do |item, i|\n        assert_equal(\"#{title}#{i}\", item.title.content)\n        assert_equal(\"#{link}#{i}\", item.link.href)\n        assert_equal(\"#{description}#{i}\", item.summary.content)\n        assert_equal(updated + i * 60, item.updated.content)\n      end\n    end\n\n    def test_setup_maker_items_sort\n      title = \"TITLE\"\n      link = \"http://hoge.com/\"\n      summary = \"text hoge fuga\"\n      updated = Time.now\n\n      feed_size = 5\n      feed = RSS::Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n\n        feed_size.times do |i|\n          entry_class = RSS::Atom::Feed::Entry\n          entry = entry_class.new\n          entry.title = entry_class::Title.new(:content => \"#{title}#{i}\")\n          entry.links << entry_class::Link.new(:href => \"#{link}#{i}\")\n          entry.summary = entry_class::Summary.new(:content => \"#{summary}#{i}\")\n          entry.updated = entry_class::Updated.new(:content => updated + i * 60)\n          entry.setup_maker(maker.items)\n        end\n        maker.items.do_sort = false\n      end\n      assert_equal(feed_size, feed.entries.size)\n      feed.entries.each_with_index do |entry, i|\n        assert_equal(\"#{title}#{i}\", entry.title.content)\n        assert_equal(\"#{link}#{i}\", entry.link.href)\n        assert_equal(\"#{summary}#{i}\", entry.summary.content)\n      end\n\n\n      feed = RSS::Maker.make(\"atom\") do |maker|\n        setup_dummy_channel_atom(maker)\n\n        feed_size.times do |i|\n          entry_class = RSS::Atom::Feed::Entry\n          entry = entry_class.new\n          entry.title = entry_class::Title.new(:content => \"#{title}#{i}\")\n          entry.links << entry_class::Link.new(:href => \"#{link}#{i}\")\n          entry.summary = entry_class::Summary.new(:content => \"#{summary}#{i}\")\n          entry.updated = entry_class::Updated.new(:content => updated + i * 60)\n          entry.setup_maker(maker.items)\n        end\n        maker.items.do_sort = true\n       end\n      assert_equal(feed_size, feed.entries.size)\n      feed.entries.reverse.each_with_index do |entry, i|\n        assert_equal(\"#{title}#{i}\", entry.title.content)\n        assert_equal(\"#{link}#{i}\", entry.link.href)\n        assert_equal(\"#{summary}#{i}\", entry.summary.content)\n      end\n    end\n\n    def test_setup_maker_items_backward_compatibility\n      test_setup_maker_items(true)\n    end\n\n    def test_setup_maker\n      encoding = \"EUC-JP\"\n      standalone = true\n      \n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      feed = RSS::Maker.make(\"atom\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        setup_dummy_channel_atom(maker)\n        setup_dummy_item_atom(maker)\n      end\n      assert_not_nil(feed)\n\n      new_feed = RSS::Maker.make(\"atom\") do |maker|\n        feed.setup_maker(maker)\n      end\n\n      assert_equal([\"atom\", \"1.0\", \"feed\"], new_feed.feed_info)\n      assert_equal(encoding, new_feed.encoding)\n      assert_equal(standalone, new_feed.standalone)\n\n      xss = new_feed.xml_stylesheets.first\n      assert_equal(1, new_feed.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n    end\n\n    def test_setup_maker_full\n      encoding = \"EUC-JP\"\n      standalone = true\n\n      href = 'a.xsl'\n      type = 'text/xsl'\n      title = 'sample'\n      media = 'printer'\n      charset = 'UTF-8'\n      alternate = 'yes'\n\n      channel_about = \"http://hoge.com\"\n      channel_title = \"fugafuga\"\n      channel_link = \"http://hoge.com\"\n      channel_description = \"fugafugafugafuga\"\n      channel_author = \"Bob\"\n\n      image_url = \"http://hoge.com/hoge.png\"\n\n      item_title = \"TITLE\"\n      item_link = \"http://hoge.com/\"\n      item_description = \"text hoge fuga\"\n\n      entry_size = 5\n      feed = RSS::Maker.make(\"atom\") do |maker|\n        maker.encoding = encoding\n        maker.standalone = standalone\n\n        maker.xml_stylesheets.new_xml_stylesheet do |xss|\n          xss.href = href\n          xss.type = type\n          xss.title = title\n          xss.media = media\n          xss.charset = charset\n          xss.alternate = alternate\n        end\n\n        maker.channel.about = channel_about\n        maker.channel.title = channel_title\n        maker.channel.link = channel_link\n        maker.channel.description = channel_description\n        maker.channel.author = channel_author\n        @dc_elems.each do |var, value|\n          maker.channel.__send__(\"dc_#{var}=\", value)\n        end\n\n        maker.image.url = image_url\n\n        entry_size.times do |i|\n          maker.items.new_item do |item|\n            item.title = \"#{item_title}#{i}\"\n            item.link = \"#{item_link}#{i}\"\n            item.description = \"#{item_description}#{i}\"\n\n            @dc_elems.each do |var, value|\n              item.__send__(\"dc_#{var}=\", value)\n            end\n          end\n        end\n      end\n\n      new_feed = RSS::Maker.make(\"atom\") do |maker|\n        feed.setup_maker(maker)\n      end\n\n      assert_equal([\"atom\", \"1.0\", \"feed\"], new_feed.feed_info)\n      assert_equal(encoding, new_feed.encoding)\n      assert_equal(standalone, new_feed.standalone)\n\n      xss = new_feed.xml_stylesheets.first\n      assert_equal(1, new_feed.xml_stylesheets.size)\n      assert_equal(href, xss.href)\n      assert_equal(type, xss.type)\n      assert_equal(title, xss.title)\n      assert_equal(media, xss.media)\n      assert_equal(charset, xss.charset)\n      assert_equal(alternate, xss.alternate)\n\n      assert_equal(channel_title, new_feed.title.content)\n      assert_equal(channel_link, new_feed.link.href)\n      assert_equal(channel_description, new_feed.subtitle.content)\n      assert_equal(channel_author, new_feed.author.name.content)\n      assert_equal(image_url, new_feed.logo.content)\n      @dc_elems.each do |var, value|\n        assert_equal(value, new_feed.__send__(\"dc_#{var}\"))\n      end\n\n      assert_equal(entry_size, new_feed.entries.size)\n      new_feed.entries.each_with_index do |entry, i|\n        assert_equal(\"#{item_title}#{i}\", entry.title.content)\n        assert_equal(\"#{item_link}#{i}\", entry.link.href)\n        assert_equal(\"#{item_description}#{i}\", entry.summary.content)\n\n        @dc_elems.each do |var, value|\n          assert_equal(value, entry.__send__(\"dc_#{var}\"))\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_itunes.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMakerITunes < TestCase\n    def test_setup_maker_simple\n      author = \"John Doe\"\n      block = true\n      categories = [\"Audio Blogs\"]\n      image = \"http://example.com/podcasts/everything/AllAboutEverything.jpg\"\n      duration = \"4:05\"\n      duration_components = [0, 4, 5]\n      explicit = true\n      keywords = [\"salt\", \"pepper\", \"shaker\", \"exciting\"]\n      new_feed_url = \"http://newlocation.com/example.rss\"\n      owner = {:name => \"John Doe\", :email => \"john.doe@example.com\"}\n      subtitle = \"A show about everything\"\n      summary = \"All About Everything is a show about \" +\n        \"everything. Each week we dive into any \" +\n        \"subject known to man and talk about it \" +\n        \"as much as we can. Look for our Podcast \" +\n        \"in the iTunes Music Store\"\n\n      feed = RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        channel = maker.channel\n        channel.itunes_author = author\n        channel.itunes_block = block\n        categories.each do |category|\n          channel.itunes_categories.new_category.text = category\n        end\n        channel.itunes_image = image\n        channel.itunes_explicit = explicit\n        channel.itunes_keywords = keywords\n        channel.itunes_owner.itunes_name = owner[:name]\n        channel.itunes_owner.itunes_email = owner[:email]\n        channel.itunes_subtitle = subtitle\n        channel.itunes_summary = summary\n\n        item = maker.items.last\n        item.itunes_author = author\n        item.itunes_block = block\n        item.itunes_duration = duration\n        item.itunes_explicit = explicit\n        item.itunes_keywords = keywords\n        item.itunes_subtitle = subtitle\n        item.itunes_summary = summary\n      end\n      assert_not_nil(feed)\n\n      new_feed = RSS::Maker.make(\"rss2.0\") do |maker|\n        feed.setup_maker(maker)\n      end\n      assert_not_nil(new_feed)\n\n      channel = new_feed.channel\n      item = new_feed.items.last\n\n      assert_equal(author, channel.itunes_author)\n      assert_equal(author, item.itunes_author)\n\n      assert_equal(block, channel.itunes_block?)\n      assert_equal(block, item.itunes_block?)\n\n      assert_equal(categories,\n                   collect_itunes_categories(channel.itunes_categories))\n\n      assert_equal(image, channel.itunes_image.href)\n\n      assert_equal(duration_components,\n                   [item.itunes_duration.hour,\n                    item.itunes_duration.minute,\n                    item.itunes_duration.second])\n\n      assert_equal(explicit, channel.itunes_explicit?)\n      assert_equal(explicit, item.itunes_explicit?)\n\n      assert_equal(keywords, channel.itunes_keywords)\n      assert_equal(keywords, item.itunes_keywords)\n\n      assert_equal(owner,\n                   {\n                     :name => channel.itunes_owner.itunes_name,\n                     :email => channel.itunes_owner.itunes_email\n                   })\n\n      assert_equal(subtitle, channel.itunes_subtitle)\n      assert_equal(subtitle, item.itunes_subtitle)\n\n      assert_equal(summary, channel.itunes_summary)\n      assert_equal(summary, item.itunes_summary)\n    end\n\n    def test_setup_maker_with_nested_categories\n      categories = [[\"Arts & Entertainment\", \"Games\"],\n                    [\"Technology\", \"Computers\"],\n                    \"Audio Blogs\"]\n\n      feed = RSS::Maker.make(\"rss2.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        channel = maker.channel\n        categories.each do |category|\n          target = channel.itunes_categories\n          if category.is_a?(Array)\n            category.each do |sub_category|\n              target = target.new_category\n              target.text = sub_category\n            end\n          else\n            target.new_category.text = category\n          end\n        end\n      end\n      assert_not_nil(feed)\n\n      new_feed = RSS::Maker.make(\"rss2.0\") do |maker|\n        feed.setup_maker(maker)\n      end\n      assert_not_nil(new_feed)\n\n      channel = new_feed.channel\n\n      assert_equal(categories,\n                   collect_itunes_categories(channel.itunes_categories))\n    end\n\n    private\n    def collect_itunes_categories(categories)\n      categories.collect do |c|\n        rest = collect_itunes_categories(c.itunes_categories)\n        if rest.empty?\n          c.text\n        else\n          [c.text, *rest]\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_setup_maker_slash.rb",
    "content": "require \"rss-testcase\"\n\nrequire \"rss/maker\"\n\nmodule RSS\n  class TestSetupMakerSlash < TestCase\n    def test_setup_maker\n      elements = {\n        \"section\" => \"articles\",\n        \"department\" => \"not-an-ocean-unless-there-are-lobsters\",\n        \"comments\" => 177,\n        \"hit_parades\" => [177, 155, 105, 33, 6, 3, 0],\n      }\n\n      rss = RSS::Maker.make(\"rss1.0\") do |maker|\n        setup_dummy_channel(maker)\n        setup_dummy_item(maker)\n\n        item = maker.items.last\n        item.slash_section = elements[\"section\"]\n        item.slash_department = elements[\"department\"]\n        item.slash_comments = elements[\"comments\"]\n        item.slash_hit_parade = elements[\"hit_parades\"].join(\",\")\n      end\n      assert_not_nil(rss)\n\n      new_rss = RSS::Maker.make(\"rss1.0\") do |maker|\n        rss.setup_maker(maker)\n      end\n      assert_not_nil(new_rss)\n\n      item = new_rss.items.last\n      assert_not_nil(item)\n\n      assert_slash_elements(elements, item)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_slash.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/slash\"\n\nmodule RSS\n  class TestSlash < TestCase\n    def setup\n      @elements = {\n        \"section\" => \"articles\",\n        \"department\" => \"not-an-ocean-unless-there-are-lobsters\",\n        \"comments\" => 177,\n        \"hit_parades\" => [177, 155, 105, 33, 6, 3, 0],\n      }\n\n      slash_nodes = @elements.collect do |name, value|\n        if name == \"hit_parades\"\n          name = \"hit_parade\"\n          value = value.join(\",\")\n        end\n        \"<slash:#{name}>#{value}</slash:#{name}>\"\n      end.join(\"\\n\")\n\n      slash_ns = {\"slash\" => \"http://purl.org/rss/1.0/modules/slash/\"}\n      @source = make_RDF(<<-EOR, slash_ns)\n#{make_channel}\n#{make_image}\n#{make_item(slash_nodes)}\n#{make_textinput}\nEOR\n    end\n\n    def test_parser\n      rss = RSS::Parser.parse(@source)\n\n      assert_not_nil(rss)\n\n      item = rss.items[0]\n      assert_not_nil(item)\n\n      assert_slash_elements(item)\n    end\n\n    def test_to_s\n      rss = RSS::Parser.parse(@source)\n      rss = RSS::Parser.parse(rss.to_s)\n\n      assert_not_nil(rss)\n\n      item = rss.items[0]\n      assert_not_nil(item)\n\n      assert_slash_elements(item)\n    end\n\n    private\n    def assert_slash_elements(target)\n      super(@elements, target)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_syndication.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/syndication\"\n\nmodule RSS\n  class TestSyndication < TestCase\n    \n    def setup\n      @prefix = \"sy\"\n      @uri = \"http://purl.org/rss/1.0/modules/syndication/\"\n      \n      @parents = %w(channel)\n      \n      t = Time.iso8601(\"2000-01-01T12:00:05+00:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n      \n      @elems = {\n        :updatePeriod => \"hourly\",\n        :updateFrequency => \"2\",\n        :updateBase => t,\n      }\n      \n      @sy_nodes = @elems.collect do |name, value|\n        \"<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>\"\n      end.join(\"\\n\")\n      \n      @rss_source = make_RDF(<<-EOR, {@prefix =>  @uri})\n#{make_channel(@sy_nodes)}\n#{make_image()}\n#{make_item()}\n#{make_textinput()}\nEOR\n\n      @rss = Parser.parse(@rss_source)\n    end\n  \n    def test_parser\n      \n      assert_nothing_raised do\n        Parser.parse(@rss_source)\n      end\n      \n      @elems.each do |tag, value|\n        assert_too_much_tag(tag.to_s, \"channel\") do\n          Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))\n#{make_channel((\"<\" + @prefix + \":\" + tag.to_s + \">\" +\n  CGI.escapeHTML(value.to_s) +\n  \"</\" + @prefix + \":\" + tag.to_s + \">\") * 2)}\n#{make_item}\nEOR\n        end\n      end\n\n    end\n  \n    def test_accessor\n      \n      t = Time.iso8601(\"2003-01-01T12:00:23+09:00\")\n      class << t\n        alias_method(:to_s, :iso8601)\n      end\n      \n      new_value = {\n        :updatePeriod => \"daily\",\n        :updateFrequency => \"11\",\n        :updateBase => t,\n      }\n      \n      @elems.each do |name, value|\n        value = value.to_i if name == :updateFrequency\n        @parents.each do |parent|\n          assert_equal(value, @rss.__send__(parent).__send__(\"sy_#{name}\"))\n          @rss.__send__(parent).__send__(\"sy_#{name}=\", new_value[name])\n          new_val = new_value[name]\n          new_val = new_val.to_i if name == :updateFrequency\n          assert_equal(new_val, @rss.__send__(parent).__send__(\"sy_#{name}\"))\n        end\n      end\n      \n      %w(hourly daily weekly monthly yearly).each do |x|\n        @parents.each do |parent|\n          assert_nothing_raised do\n            @rss.__send__(parent).sy_updatePeriod = x\n          end\n        end\n      end\n      \n      %w(-2 0.3 -0.4).each do |x|\n        @parents.each do |parent|\n          assert_not_available_value(\"sy:updateBase\", x) do\n            @rss.__send__(parent).sy_updateBase = x\n          end\n        end\n      end\n      \n    end\n\n    def test_to_s\n      \n      @elems.each do |name, value|\n        excepted = \"<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>\"\n        @parents.each do |parent|\n          assert_equal(excepted,\n                       @rss.__send__(parent).__send__(\"sy_#{name}_element\"))\n        end\n      end\n      \n      REXML::Document.new(@rss_source).root.each_element do |parent|\n        if @parents.include?(parent.name)\n          parent.each_element do |elem|\n            if elem.namespace == @uri\n              assert_equal(elem.text, @elems[elem.name.intern].to_s)\n            end\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_taxonomy.rb",
    "content": "require \"cgi\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/2.0\"\nrequire \"rss/taxonomy\"\n\nmodule RSS\n  class TestTaxonomy < TestCase\n    \n    def setup\n      @prefix = \"taxo\"\n      @uri = \"http://purl.org/rss/1.0/modules/taxonomy/\"\n      @dc_prefix = \"dc\"\n      @dc_uri = \"http://purl.org/dc/elements/1.1/\"\n\n      @ns = {\n        @prefix => @uri,\n        @dc_prefix => @dc_uri,\n      }\n      \n      @topics_parents = %w(channel item)\n      \n      @topics_lis = [\n        \"http://meerkat.oreillynet.com/?c=cat23\",\n        \"http://meerkat.oreillynet.com/?c=47\",\n        \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/\",\n      ]\n\n      @topics_node = \"<#{@prefix}:topics>\\n\"\n      @topics_node << \"  <rdf:Bag>\\n\"\n      @topics_lis.each do |value|\n        resource = CGI.escapeHTML(value)\n        @topics_node << \"    <rdf:li resource=\\\"#{resource}\\\"/>\\n\"\n      end\n      @topics_node << \"  </rdf:Bag>\\n\"\n      @topics_node << \"</#{@prefix}:topics>\"\n\n      @topic_topics_lis = \\\n      [\n       \"http://meerkat.oreillynet.com/?c=cat23\",\n       \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/\",\n       \"http://dmoz.org/Computers/Programming/Internet/\",\n      ]\n\n      @topic_contents = \\\n      [\n       {\n         :link => \"http://meerkat.oreillynet.com/?c=cat23\",\n         :title => \"Data: XML\",\n         :description => \"A Meerkat channel\",\n       },\n       {\n         :link => \"http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/\",\n         :title => \"XML\",\n         :subject => \"XML\",\n         :description => \"DMOZ category\",\n         :topics => @topic_topics_lis,\n       }\n      ]\n\n      @topic_nodes = @topic_contents.collect do |info|\n        link = info[:link]\n        rv = \"<#{@prefix}:topic rdf:about=\\\"#{link}\\\">\\n\"\n        info.each do |name, value|\n          case name\n          when :topics\n            rv << \"  <#{@prefix}:topics>\\n\"\n            rv << \"    <rdf:Bag>\\n\"\n            value.each do |li|\n              resource = CGI.escapeHTML(li)\n              rv << \"      <rdf:li resource=\\\"#{resource}\\\"/>\\n\"\n            end\n            rv << \"    </rdf:Bag>\\n\"\n            rv << \"  </#{@prefix}:topics>\\n\"\n          else\n            prefix = (name == :link ? @prefix : @dc_prefix)\n            rv << \"  <#{prefix}:#{name}>#{value}</#{prefix}:#{name}>\\n\"\n          end\n        end\n        rv << \"</#{@prefix}:topic>\"\n      end\n      \n      @rss_source = make_RDF(<<-EOR, @ns)\n#{make_channel(@topics_node)}\n#{make_image()}\n#{make_item(@topics_node)}\n#{make_textinput()}\n#{@topic_nodes.join(\"\\n\")}\nEOR\n\n      @rss = Parser.parse(@rss_source)\n    end\n\n    def test_parser\n      assert_nothing_raised do\n        Parser.parse(@rss_source)\n      end\n      \n      assert_too_much_tag(\"topics\", \"channel\") do\n        Parser.parse(make_RDF(<<-EOR, @ns))\n#{make_channel(@topics_node * 2)}\n#{make_item()}\nEOR\n      end\n\n      assert_too_much_tag(\"topics\", \"item\") do\n        Parser.parse(make_RDF(<<-EOR, @ns))\n#{make_channel()}\n#{make_item(@topics_node * 2)}\nEOR\n      end\n    end\n  \n    def test_accessor\n      topics = @rss.channel.taxo_topics\n      assert_equal(@topics_lis.sort,\n                   topics.Bag.lis.collect {|li| li.resource}.sort)\n      assert_equal(@topics_lis.sort, topics.resources.sort)\n\n      assert_equal(@rss.taxo_topics.first, @rss.taxo_topic)\n\n      @topic_contents.each_with_index do |info, i|\n        topic = @rss.taxo_topics[i]\n        info.each do |name, value|\n          case name\n          when :link\n            assert_equal(value, topic.about)\n            assert_equal(value, topic.taxo_link)\n          when :topics\n            assert_equal(value.sort, topic.taxo_topics.resources.sort)\n          else\n            assert_equal(value, topic.__send__(\"dc_#{name}\"))\n          end\n        end\n      end\n    end\n    \n    def test_to_s\n      @topics_parents.each do |parent|\n        meth = \"taxo_topics_element\"\n        assert_equal(@topics_node, @rss.__send__(parent).__send__(meth))\n      end\n\n      @topic_nodes.each_with_index do |node, i|\n        expected_xml = taxo_xmlns_container(node)\n        expected = REXML::Document.new(expected_xml).root.elements[1]\n        actual_xml = taxo_xmlns_container(@rss.taxo_topics[i].to_s(true, \"\"))\n        actual = REXML::Document.new(actual_xml).root.elements[1]\n        expected_elems = expected.reject {|x| x.is_a?(REXML::Text)}\n        actual_elems = actual.reject {|x| x.is_a?(REXML::Text)}\n        expected_elems.sort! {|x, y| x.name <=> y.name}\n        actual_elems.sort! {|x, y| x.name <=> y.name}\n        assert_equal(expected_elems.collect {|x| x.to_s},\n                     actual_elems.collect {|x| x.to_s})\n        assert_equal(expected.attributes.sort, actual.attributes.sort)\n      end\n    end\n\n    private\n    def taxo_xmlns_container(content)\n      xmlns_container({\n                        @prefix => @uri,\n                        \"dc\" => \"http://purl.org/dc/elements/1.1/\",\n                        \"rdf\" => \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n                      },\n                      content)\n    end\n  end\nend\n\n"
  },
  {
    "path": "test/rss/test_to_s.rb",
    "content": "require \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/maker\"\nrequire \"rss/1.0\"\nrequire \"rss/2.0\"\nrequire \"rss/content\"\nrequire \"rss/dublincore\"\nrequire \"rss/syndication\"\nrequire \"rss/trackback\"\n\nmodule RSS\n  class TestToS < TestCase\n    def setup\n      @image_url = \"http://example.com/foo.png\"\n      @textinput_link = \"http://example.com/search.cgi\"\n      @item_links = [\n        \"http://example.com/1\",\n        \"http://example.com/2\",\n      ]\n      \n      setup_xml_declaration_info\n      setup_xml_stylesheet_infos\n      setup_channel_info\n      setup_item_infos\n      setup_image_info\n      setup_textinput_info\n\n      setup_dublin_core_info\n      setup_syndication_info\n      setup_content_info\n      setup_trackback_info\n    end\n\n    def test_to_s_10\n      rss = RSS::Maker.make(\"1.0\") do |maker|\n        setup_full(maker)\n      end\n\n      assert_xml_declaration(@version, @encoding, @standalone, rss)\n      assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)\n      assert_channel10(@channel_info, rss.channel)\n      assert_items10(@item_infos, rss.items)\n      rss.items.each do |item|\n        assert_trackback(@trackback_info, item)\n      end\n      assert_image10(@image_info, rss.image)\n      assert_textinput10(@textinput_info, rss.textinput)\n\n      rss = RSS::Parser.parse(rss.to_s)\n\n      assert_xml_declaration(@version, @encoding, @standalone, rss)\n      assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)\n      assert_channel10(@channel_info, rss.channel)\n      assert_items10(@item_infos, rss.items)\n      assert_image10(@image_info, rss.image)\n      assert_textinput10(@textinput_info, rss.textinput)\n    end\n    \n    def test_to_s_09\n      rss = RSS::Maker.make(\"0.91\") do |maker|\n        setup_full(maker)\n      end\n\n      assert_xml_declaration(@version, @encoding, @standalone, rss)\n      assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)\n      assert_channel09(@channel_info, rss.channel)\n      assert_items09(@item_infos, rss.items)\n      assert_image09(@image_info, rss.image)\n      assert_textinput09(@textinput_info, rss.textinput)\n\n      rss = RSS::Parser.parse(rss.to_s)\n\n      assert_xml_declaration(@version, @encoding, @standalone, rss)\n      assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)\n      assert_channel09(@channel_info, rss.channel)\n      assert_items09(@item_infos, rss.items)\n      assert_image09(@image_info, rss.image)\n      assert_textinput09(@textinput_info, rss.textinput)\n    end\n    \n    def test_to_s_20\n      rss = RSS::Maker.make(\"2.0\") do |maker|\n        setup_full(maker)\n      end\n\n      assert_xml_declaration(@version, @encoding, @standalone, rss)\n      assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)\n      assert_channel20(@channel_info, rss.channel)\n      assert_items20(@item_infos, rss.items)\n      assert_image20(@image_info, rss.image)\n      assert_textinput20(@textinput_info, rss.textinput)\n\n      rss = RSS::Parser.parse(rss.to_s)\n\n      assert_xml_declaration(@version, @encoding, @standalone, rss)\n      assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)\n      assert_channel20(@channel_info, rss.channel)\n      assert_items20(@item_infos, rss.items)\n      assert_image20(@image_info, rss.image)\n      assert_textinput20(@textinput_info, rss.textinput)\n    end\n    \n    private\n    def setup_xml_declaration_info\n      @version = \"1.0\"\n      @encoding = \"UTF-8\"\n      @standalone = false\n    end\n\n    def setup_xml_stylesheet_infos\n      @xs_infos = [\n        {\n          \"href\" => \"XXX.xsl\",\n          \"type\" => \"text/xsl\",\n          \"title\" => \"XXX\",\n          \"media\" => \"print\",\n          \"alternate\" => \"no\",\n        },\n        {\n          \"href\" => \"YYY.css\",\n          \"type\" => \"text/css\",\n          \"title\" => \"YYY\",\n          \"media\" => \"all\",\n          \"alternate\" => \"no\",\n        },\n      ]\n    end\n\n    def setup_channel_info\n      @channel_info = {\n        \"about\" => \"http://example.com/index.rdf\",\n        \"title\" => \"Sample RSS\",\n        \"link\" => \"http://example.com/\",\n        \"description\" => \"Sample\\n\\n\\n\\n\\nSite\",\n        \"language\" => \"en\",\n        \"copyright\" => \"FDL\",\n        \"managingEditor\" => \"foo@example.com\",\n        \"webMaster\" => \"webmaster@example.com\",\n        \"rating\" => '(PICS-1.1 \"http://www.rsac.org/ratingsv01.html\" l gen true comment \"RSACi North America Server\" for \"http://www.rsac.org\" on \"1996.04.16T08:15-0500\" r (n 0 s 0 v 0 l 0))',\n        \"docs\" => \"http://backend.userland.com/rss091\",\n        \"skipDays\" => [\n          \"Monday\",\n          \"Friday\",\n        ],\n        \"skipHours\" => [\n          \"12\",\n          \"23\",\n        ],\n        \"date\" => Time.now,\n        \"lastBuildDate\" => Time.now - 3600,\n        \"generator\" => \"RSS Maker\",\n        \"ttl\" => \"60\",\n        \"cloud\" => {\n          \"domain\" => \"rpc.sys.com\",\n          \"port\" => \"80\",\n          \"path\" => \"/RPC2\",\n          \"registerProcedure\" => \"myCloud.rssPleaseNotify\",\n          \"protocol\" => \"xml-rpc\",\n        },\n        \"category\" => {\n          \"domain\" => \"http://example.com/misc/\",\n          \"content\" => \"misc\",\n        },\n\n        \"image\" => {\n          \"resource\" => @image_url,\n        },\n\n        \"textinput\" => {\n          \"resource\" => @textinput_link,\n        },\n\n        \"items\" => @item_links.collect{|link| {\"resource\" => link}},\n      }\n    end\n\n    def setup_item_infos\n      @item_infos = [\n        {\n          \"title\" => \"Sample item1\",\n          \"link\" => @item_links[0],\n          \"description\" => \"Sample description1\",\n          \"date\" => Time.now - 3600,\n          \"author\" => \"foo@example.com\",\n          \"comments\" => \"http://example.com/1/comments\",\n          \"guid\" => {\n            \"isPermaLink\" => \"true\",\n            \"content\" => \"http://example.com/1\",\n          },\n          \"enclosure\" => {\n            \"url\" => \"http://example.com/1.mp3\",\n            \"length\" => \"100\",\n            \"type\" => \"audio/mpeg\",\n          },\n          \"source\" => {\n            \"url\" => \"http:/example.com/\",\n            \"content\" => \"Sample site\",\n          },\n          \"category\" => {\n            \"domain\" => \"http://example.com/misc/\",\n            \"content\" => \"misc\",\n          },\n        },\n\n        {\n          \"title\" => \"Sample item2\",\n          \"link\" => @item_links[1],\n          \"description\" => \"Sample description2\",\n          \"date\" => Time.now - 7200,\n          \"author\" => \"foo@example.com\",\n          \"comments\" => \"http://example.com/2/comments\",\n          \"guid\" => {\n            \"isPermaLink\" => \"false\",\n            \"content\" => \"http://example.com/2\",\n          },\n          \"enclosure\" => {\n            \"url\" => \"http://example.com/2.mp3\",\n            \"length\" => \"200\",\n            \"type\" => \"audio/mpeg\",\n          },\n          \"source\" => {\n            \"url\" => \"http:/example.com/\",\n            \"content\" => \"Sample site\",\n          },\n          \"category\" => {\n            \"domain\" => \"http://example.com/misc/\",\n            \"content\" => \"misc\",\n          },\n        },\n      ]\n    end\n\n    def setup_image_info\n      @image_info = {\n        \"title\" => \"Sample image\",\n        \"url\" => @image_url,\n        \"width\" => \"88\",\n        \"height\" => \"31\",\n        \"description\" => \"Sample\",\n      }\n    end\n\n    def setup_textinput_info\n      @textinput_info = {\n        \"title\" => \"Sample textinput\",\n        \"description\" => \"Search\",\n        \"name\" => \"key\",\n        \"link\" => @textinput_link,\n      }\n    end\n\n    def setup_dublin_core_info\n      @dc_info = {\n        \"title\" => \"DC title\",\n        \"description\" => \"DC desc\",\n        \"creator\" => \"DC creator\",\n        \"subject\" => \"DC subject\",\n        \"publisher\" => \"DC publisher\",\n        \"contributor\" => \"DC contributor\",\n        \"type\" => \"DC type\",\n        \"format\" => \"DC format\",\n        \"identifier\" => \"DC identifier\",\n        \"source\" => \"DC source\",\n        \"language\" => \"ja\",\n        \"relation\" => \"DC relation\",\n        \"coverage\" => \"DC coverage\",\n        \"rights\" => \"DC rights\",\n        \"date\" => Time.now - 60,\n      }\n    end\n\n    def setup_syndication_info\n      @sy_info = {\n        \"updatePeriod\" => \"hourly\",\n        \"updateFrequency\" => \"2\",\n        \"updateBase\" => Time.now - 3600,\n      }\n    end\n    \n    def setup_content_info\n      @content_info = {\n        \"encoded\" => \"<p>p</p>\",\n      }\n    end\n    \n    def setup_trackback_info\n      @trackback_info = {\n        \"ping\" => \"http://example.com/tb.cgi?tb_id=XXX\",\n        \"abouts\" => [\n          \"http://example.net/tb.cgi?tb_id=YYY\",\n          \"http://example.org/tb.cgi?tb_id=ZZZ\",\n        ]\n      }\n    end\n\n\n    def setup_full(maker)\n      setup_xml_declaration(maker)\n      setup_xml_stylesheets(maker)\n      setup_channel(maker)\n      setup_image(maker)\n      setup_items(maker)\n      setup_textinput(maker)\n    end\n\n    def setup_xml_declaration(maker)\n      %w(version encoding standalone).each do |name|\n        maker.__send__(\"#{name}=\", instance_eval(\"@#{name}\"))\n      end\n    end\n\n    def setup_xml_stylesheets(maker)\n      @xs_infos.each do |info|\n        xs = maker.xml_stylesheets.new_xml_stylesheet\n        info.each do |name, value|\n          xs.__send__(\"#{name}=\", value)\n        end\n      end\n    end\n\n    def setup_channel(maker)\n      channel = maker.channel\n      info = @channel_info\n      \n      %w(about title link description language copyright\n         managingEditor webMaster rating docs date\n         lastBuildDate generator ttl).each do |name|\n        channel.__send__(\"#{name}=\", info[name])\n      end\n\n      skipDays = channel.skipDays\n      info[\"skipDays\"].each do |day|\n        new_day = skipDays.new_day\n        new_day.content = day\n      end\n\n      skipHours = channel.skipHours\n      info[\"skipHours\"].each do |hour|\n        new_hour = skipHours.new_hour\n        new_hour.content = hour\n      end\n      \n      cloud = channel.cloud\n      %w(domain port path registerProcedure protocol).each do |name|\n        cloud.__send__(\"#{name}=\", info[\"cloud\"][name])\n      end\n\n      category = channel.categories.new_category\n      %w(domain content).each do |name|\n        category.__send__(\"#{name}=\", info[\"category\"][name])\n      end\n    end\n    \n    def setup_image(maker)\n      image = maker.image\n      info = @image_info\n\n      %w(title url width height description).each do |name|\n        image.__send__(\"#{name}=\", info[name])\n      end\n    end\n    \n    def setup_items(maker)\n      items = maker.items\n\n      @item_infos.each do |info|\n        item = items.new_item\n        %w(title link description date author comments).each do |name|\n          item.__send__(\"#{name}=\", info[name])\n        end\n        \n        guid = item.guid\n        %w(isPermaLink content).each do |name|\n          guid.__send__(\"#{name}=\", info[\"guid\"][name])\n        end\n\n        enclosure = item.enclosure\n        %w(url length type).each do |name|\n          enclosure.__send__(\"#{name}=\", info[\"enclosure\"][name])\n        end\n\n        source = item.source\n        %w(url content).each do |name|\n          source.__send__(\"#{name}=\", info[\"source\"][name])\n        end\n\n        category = item.categories.new_category\n        %w(domain content).each do |name|\n          category.__send__(\"#{name}=\", info[\"category\"][name])\n        end\n\n        setup_trackback(item)\n      end\n    end\n\n    def setup_textinput(maker)\n      textinput = maker.textinput\n      info = @textinput_info\n\n      %w(title description name link).each do |name|\n        textinput.__send__(\"#{name}=\", info[name])\n      end\n    end\n\n    def setup_content(target)\n      prefix = \"content\"\n      %w(encoded).each do |name|\n        target.__send__(\"#{prefix}_#{name}=\", @content_info[name])\n      end\n    end\n    \n    def setup_dublin_core(target)\n      prefix = \"dc\"\n      %w(title description creator subject publisher\n        contributor type format identifier source language\n        relation coverage rights).each do |name|\n        target.__send__(\"#{prefix}_#{name}=\", @dc_info[name])\n      end\n    end\n    \n    def setup_syndicate(target)\n      prefix = \"sy\"\n      %w(updatePeriod updateFrequency updateBase).each do |name|\n        target.__send__(\"#{prefix}_#{name}=\", @sy_info[name])\n      end\n    end\n    \n    def setup_trackback(target)\n      target.trackback_ping = @trackback_info[\"ping\"]\n      @trackback_info[\"abouts\"].each do |about|\n        new_about = target.trackback_abouts.new_about\n        new_about.value = about\n      end\n    end\n\n\n    def assert_channel10(attrs, channel)\n      _wrap_assertion do\n        n_attrs = normalized_attrs(attrs)\n        \n        names = %w(about title link description)\n        assert_attributes(attrs, names, channel)\n\n        %w(image items textinput).each do |name|\n          value = n_attrs[name]\n          if value\n            target = channel.__send__(name)\n            __send__(\"assert_channel10_#{name}\", value, target)\n          end\n        end\n      end\n    end\n\n    def assert_channel10_image(attrs, image)\n      _wrap_assertion do\n        assert_attributes(attrs, %w(resource), image)\n      end\n    end\n    \n    def assert_channel10_textinput(attrs, textinput)\n      _wrap_assertion do\n        assert_attributes(attrs, %w(resource), textinput)\n      end\n    end\n\n    def assert_channel10_items(attrs, items)\n      _wrap_assertion do\n        assert_equal(items.resources, items.Seq.lis.collect {|x| x.resource})\n        items.Seq.lis.each_with_index do |li, i|\n          assert_attributes(attrs[i], %w(resource), li)\n        end\n      end\n    end\n\n    def assert_image10(attrs, image)\n      _wrap_assertion do\n        names = %w(about title url link)\n        assert_attributes(attrs, names, image)\n      end\n    end\n\n    def assert_items10(attrs, items)\n      _wrap_assertion do\n        names = %w(about title link description)\n        items.each_with_index do |item, i|\n          assert_attributes(attrs[i], names, item)\n        end\n      end\n    end\n\n    def assert_textinput10(attrs, textinput)\n      _wrap_assertion do\n        names = %w(about title description name link)\n        assert_attributes(attrs, names, textinput)\n      end\n    end\n\n\n    def assert_channel09(attrs, channel)\n      _wrap_assertion do\n        n_attrs = normalized_attrs(attrs)\n\n        names = %w(title description link language rating\n                   copyright pubDate lastBuildDate docs\n                   managingEditor webMaster)\n        assert_attributes(attrs, names, channel)\n        \n        %w(skipHours skipDays).each do |name|\n          value = n_attrs[name]\n          if value\n            target = channel.__send__(name)\n            __send__(\"assert_channel09_#{name}\", value, target)\n          end\n        end\n      end\n    end\n\n    def assert_channel09_skipDays(contents, skipDays)\n      _wrap_assertion do\n        days = skipDays.days\n        contents.each_with_index do |content, i|\n          assert_equal(content, days[i].content)\n        end\n      end\n    end\n    \n    def assert_channel09_skipHours(contents, skipHours)\n      _wrap_assertion do\n        hours = skipHours.hours\n        contents.each_with_index do |content, i|\n          assert_equal(content.to_i, hours[i].content)\n        end\n      end\n    end\n    \n    def assert_image09(attrs, image)\n      _wrap_assertion do\n        names = %w(url link title description)\n        names << [\"width\", :integer]\n        names << [\"height\", :integer]\n        assert_attributes(attrs, names, image)\n      end\n    end\n\n    def assert_items09(attrs, items)\n      _wrap_assertion do\n        names = %w(title link description)\n        items.each_with_index do |item, i|\n          assert_attributes(attrs[i], names, item)\n        end\n      end\n    end\n    \n    def assert_textinput09(attrs, textinput)\n      _wrap_assertion do\n        names = %w(title description name link)\n        assert_attributes(attrs, names, textinput)\n      end\n    end\n\n\n    def assert_channel20(attrs, channel)\n      _wrap_assertion do\n        n_attrs = normalized_attrs(attrs)\n        \n        names = %w(title link description language copyright\n                   managingEditor webMaster pubDate\n                   lastBuildDate generator docs rating)\n        names << [\"ttl\", :integer]\n        assert_attributes(attrs, names, channel)\n\n        %w(cloud categories skipHours skipDays).each do |name|\n          value = n_attrs[name]\n          if value\n            target = channel.__send__(name)\n            __send__(\"assert_channel20_#{name}\", value, target)\n          end\n        end\n      end\n    end\n\n    def assert_channel20_skipDays(contents, skipDays)\n      assert_channel09_skipDays(contents, skipDays)\n    end\n    \n    def assert_channel20_skipHours(contents, skipHours)\n      assert_channel09_skipHours(contents, skipHours)\n    end\n    \n    def assert_channel20_cloud(attrs, cloud)\n      _wrap_assertion do\n        names = %w(domain path registerProcedure protocol)\n        names << [\"port\", :integer]\n        assert_attributes(attrs, names, cloud)\n      end\n    end\n    \n    def assert_channel20_categories(attrs, categories)\n      _wrap_assertion do\n        names = %w(domain content)\n        categories.each_with_index do |category, i|\n          assert_attributes(attrs[i], names, category)\n        end\n      end\n    end\n    \n    def assert_image20(attrs, image)\n      _wrap_assertion do\n        names = %w(url link title description)\n        names << [\"width\", :integer]\n        names << [\"height\", :integer]\n        assert_attributes(attrs, names, image)\n      end\n    end\n\n    def assert_items20(attrs, items)\n      _wrap_assertion do\n        names = %w(about title link description)\n        items.each_with_index do |item, i|\n          assert_attributes(attrs[i], names, item)\n\n          n_attrs = normalized_attrs(attrs[i])\n\n          %w(source enclosure categories guid).each do |name|\n            value = n_attrs[name]\n            if value\n              target = item.__send__(name)\n              __send__(\"assert_items20_#{name}\", value, target)\n            end\n          end\n        end\n      end\n    end\n\n    def assert_items20_source(attrs, source)\n      _wrap_assertion do\n        assert_attributes(attrs, %w(url content), source)\n      end\n    end\n    \n    def assert_items20_enclosure(attrs, enclosure)\n      _wrap_assertion do\n        names = [\"url\", [\"length\", :integer], \"type\"]\n        assert_attributes(attrs, names, enclosure)\n      end\n    end\n    \n    def assert_items20_categories(attrs, categories)\n      _wrap_assertion do\n        assert_channel20_categories(attrs, categories)\n      end\n    end\n    \n    def assert_items20_guid(attrs, guid)\n      _wrap_assertion do\n        names = [[\"isPermaLink\", :boolean], [\"content\"]]\n        assert_attributes(attrs, names, guid)\n      end\n    end\n\n    def assert_textinput20(attrs, textinput)\n      _wrap_assertion do\n        names = %w(title description name link)\n        assert_attributes(attrs, names, textinput)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_trackback.rb",
    "content": "require \"cgi\"\nrequire \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/2.0\"\nrequire \"rss/trackback\"\n\nmodule RSS\n  class TestTrackBack < TestCase\n    \n    def setup\n      @prefix = \"trackback\"\n      @uri = \"http://madskills.com/public/xml/rss/module/trackback/\"\n      \n      @parents = %w(item)\n      \n      @elems = {\n        :ping => \"http://bar.com/tb.cgi?tb_id=rssplustrackback\",\n        :about => \"http://foo.com/trackback/tb.cgi?tb_id=20020923\",\n      }\n      \n      @content_nodes = @elems.collect do |name, value|\n        \"<#{@prefix}:#{name} rdf:resource=\\\"#{CGI.escapeHTML(value.to_s)}\\\"/>\"\n      end.join(\"\\n\")\n      \n      @content_nodes2 = @elems.collect do |name, value|\n        \"<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>\"\n      end.join(\"\\n\")\n      \n      @rss_source = make_RDF(<<-EOR, {@prefix =>  @uri})\n#{make_channel()}\n#{make_image()}\n#{make_item(@content_nodes)}\n#{make_textinput()}\nEOR\n\n      @rss = Parser.parse(@rss_source)\n\n      @rss20_source = make_rss20(nil, {@prefix =>  @uri}) do\n        make_channel20(nil) do\n          make_item20(@content_nodes2)\n        end\n      end\n\n      @rss20 = Parser.parse(@rss20_source, false)\n    end\n\n    def test_parser\n\n      assert_nothing_raised do\n        Parser.parse(@rss_source)\n      end\n\n      @elems.find_all{|k, v| k == :ping}.each do |tag, value|\n        assert_too_much_tag(tag.to_s, \"item\") do\n          Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))\n#{make_channel()}\n#{make_item((\"<\" + @prefix + \":\" + tag.to_s + \" rdf:resource=\\\"\" +\n  CGI.escapeHTML(value.to_s) +\n  \"\\\"/>\") * 2)}\nEOR\n        end\n      end\n\n      @elems.find_all{|k, v| k == :about}.each do |tag, value|\n        assert_missing_tag(\"trackback:ping\", \"item\") do\n          Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))\n#{make_channel()}\n#{make_item((\"<\" + @prefix + \":\" + tag.to_s + \" rdf:resource=\\\"\" +\n  CGI.escapeHTML(value.to_s) +\n  \"\\\"/>\") * 2)}\nEOR\n        end\n\n      end\n\n    end\n  \n    def test_accessor\n      \n      new_value = {\n        :ping => \"http://baz.com/trackback/tb.cgi?tb_id=20030808\",\n        :about => \"http://hoge.com/trackback/tb.cgi?tb_id=90030808\",\n      }\n      \n      @elems.each do |name, value|\n        @parents.each do |parent|\n          accessor = \"#{RSS::TRACKBACK_PREFIX}_#{name}\"\n          target = @rss.__send__(parent)\n          target20 = @rss20.channel.__send__(parent, -1)\n          assert_equal(value, target.__send__(accessor))\n          assert_equal(value, target20.__send__(accessor))\n          if name == :about\n            # abount is zero or more\n            target.__send__(\"#{accessor}=\", 0, new_value[name].to_s)\n            target20.__send__(\"#{accessor}=\", 0, new_value[name].to_s)\n          else\n            target.__send__(\"#{accessor}=\", new_value[name].to_s)\n            target20.__send__(\"#{accessor}=\", new_value[name].to_s)\n          end\n          assert_equal(new_value[name], target.__send__(accessor))\n          assert_equal(new_value[name], target20.__send__(accessor))\n        end\n      end\n      \n    end\n\n    def test_to_s\n      \n      @elems.each do |name, value|\n        excepted = %Q!<#{@prefix}:#{name} rdf:resource=\"#{CGI.escapeHTML(value)}\"/>!\n        @parents.each do |parent|\n          meth = \"#{RSS::TRACKBACK_PREFIX}_#{name}_element\"\n          meth << \"s\" if name == :about\n          assert_equal(excepted, @rss.__send__(parent).__send__(meth))\n        end\n      end\n      \n      REXML::Document.new(@rss_source).root.each_element do |parent|\n        if @parents.include?(parent.name)\n          parent.each_element do |elem|\n            if elem.namespace == @uri\n              assert_equal(elem.attributes[\"resource\"], @elems[elem.name.intern])\n            end\n          end\n        end\n      end\n      \n    end\n    \n  end\nend\n\n"
  },
  {
    "path": "test/rss/test_version.rb",
    "content": "require \"rss-testcase\"\n\nmodule RSS\n  class TestVersion < TestCase\n    def test_version\n      assert_equal(\"0.2.4\", ::RSS::VERSION)\n    end\n  end\nend\n"
  },
  {
    "path": "test/rss/test_xml-stylesheet.rb",
    "content": "require \"rexml/document\"\n\nrequire \"rss-testcase\"\n\nrequire \"rss/1.0\"\nrequire \"rss/xml-stylesheet\"\n\nmodule RSS\n  class TestXMLStyleSheet < TestCase\n    \n    def test_accessor\n      [\n        {:href => \"a.xsl\", :type => \"text/xsl\"},\n        {:media => \"print\", :title => \"FOO\"},\n        {:charset => \"UTF-8\", :alternate => \"yes\"},\n      ].each do |attrs|\n        assert_xml_stylesheet_attrs(attrs, XMLStyleSheet.new(attrs))\n      end\n    end\n    \n    def test_to_s\n      [\n        {:href => \"a.xsl\", :type => \"text/xsl\"},\n        {:type => \"text/xsl\"},\n        {:href => \"a.xsl\", :guess_type => \"text/xsl\"},\n        {:href => \"a.css\", :type => \"text/css\"},\n        {:href => \"a.css\", :type => \"text/xsl\",\n         :guess_type => \"text/css\"},\n        {:href => \"a.xsl\", :type => \"text/xsl\",\n         :title => \"sample\", :media => \"printer\",\n         :charset => \"UTF-8\", :alternate => \"yes\"},\n        {:href => \"a.css\", :guess_type => \"text/css\",\n         :alternate => \"no\"},\n        {:type => \"text/xsl\", :title => \"sample\",\n         :media => \"printer\", :charset => \"UTF-8\",\n         :alternate => \"yes\"},\n      ].each do |attrs|\n        target, contents = parse_pi(XMLStyleSheet.new(attrs).to_s)\n        assert_xml_stylesheet(target, attrs, XMLStyleSheet.new(contents))\n      end\n    end\n    \n    def test_bad_alternate\n      %w(a ___ ??? BAD_ALTERNATE).each do |value|\n        xss = XMLStyleSheet.new\n        assert_raise(NotAvailableValueError) do\n          xss.alternate = value\n        end\n        xss.do_validate = false\n        assert_nothing_raised do\n          xss.alternate = value\n        end\n        assert_nil(xss.alternate)\n      end\n    end\n    \n    def test_parse\n      [\n        [{:href => \"a.xsl\", :type => \"text/xsl\"},],\n        [{:media => \"print\", :title => \"FOO\"},],\n        [{:charset => \"UTF-8\", :alternate => \"yes\"},],\n        [{:href => \"a.xsl\", :type => \"text/xsl\"},\n         {:type => \"text/xsl\"},\n         {:href => \"a.xsl\", :guess_type => \"text/xsl\"},\n         {:href => \"a.css\", :type => \"text/css\"},\n         {:href => \"a.css\", :type => \"text/xsl\",\n          :guess_type => \"text/css\"},\n         {:href => \"a.xsl\", :type => \"text/xsl\",\n          :title => \"sample\", :media => \"printer\",\n          :charset => \"UTF-8\", :alternate => \"yes\"},\n         {:href => \"a.css\", :guess_type => \"text/css\",\n          :alternate => \"no\"},\n         {:type => \"text/xsl\", :title => \"sample\",\n          :media => \"printer\", :charset => \"UTF-8\",\n          :alternate => \"yes\"},],\n      ].each do |xsss|\n        doc = REXML::Document.new(make_sample_RDF)\n        root = doc.root\n        xsss.each do |xss|\n          content = xss.collect do |key, name|\n            %Q[#{key}=\"#{name}\"]\n          end.join(\" \")\n          pi = REXML::Instruction.new(\"xml-stylesheet\", content)\n          root.previous_sibling = pi\n        end\n        rss = Parser.parse(doc.to_s)\n        have_href_xsss = xsss.find_all {|xss| xss.has_key?(:href)}\n        assert_equal(have_href_xsss.size, rss.xml_stylesheets.size)\n        rss.xml_stylesheets.each_with_index do |stylesheet, i|\n          target, = parse_pi(stylesheet.to_s)\n          assert_xml_stylesheet(target, have_href_xsss[i], stylesheet)\n        end\n      end\n    end\n    \n    def parse_pi(pi)\n      /\\A\\s*<\\?(\\S+)([^(?:\\?>)]+)\\?>\\s*\\z/ =~ pi\n      target = $1\n      dummy = REXML::Document.new(\"<dummy #{$2}/>\").root\n      contents = {}\n      dummy.attributes.each do |name, value|\n        contents[name] = value\n      end\n      [target, contents]\n    end\n    \n  end\nend\n"
  },
  {
    "path": "test/ruby/beginmainend.rb",
    "content": "errout = ARGV.shift\n\nBEGIN {\n  puts \"b1\"\n  local_begin1 = \"local_begin1\"\n  $global_begin1 = \"global_begin1\"\n  ConstBegin1 = \"ConstBegin1\"\n}\n\nBEGIN {\n  puts \"b2\"\n\n  BEGIN {\n    puts \"b2-1\"\n  }\n}\n\n# for scope check\nraise if defined?(local_begin1)\nraise unless defined?($global_begin1)\nraise unless defined?(::ConstBegin1)\nlocal_for_end2 = \"e2\"\n$global_for_end1 = \"e1\"\n\nputs \"main\"\n\nEND {\n  puts local_for_end2\t# e2\n}\n\neval <<EOE\n  BEGIN {\n    puts \"b3\"\n\n    BEGIN {\n      puts \"b3-1\"\n    }\n  }\n\n  BEGIN {\n    puts \"b4\"\n  }\n\n  END {\n    puts \"e3\"\n  }\n\n  END {\n    puts \"e4\"\n\n    END {\n      puts \"e4-1\"\n\n      END {\n\tputs \"e4-1-1\"\n      }\n    }\n\n    END {\n      puts \"e4-2\"\n    }\n  }\nEOE\n\nEND {\n  exit\n  puts \"should not be dumped\"\n\n  END {\n    puts \"not reached\"\n  }\n}\n\nEND {\n  puts $global_for_end1\t# e1\n\n  END {\n    puts \"e1-1\"\n  }\n}\n"
  },
  {
    "path": "test/ruby/endblockwarn.rb",
    "content": "def end1\n  END {}\nend\n\nend1\n\neval <<EOE\n  def end2\n    END {}\n  end\nEOE\n\n"
  },
  {
    "path": "test/ruby/envutil.rb",
    "content": "module EnvUtil\n  def rubybin\n    if ruby = ENV[\"RUBY\"]\n      return ruby\n    end\n    ruby = \"ruby\"\n    rubyexe = ruby+\".exe\"\n    3.times do\n      if File.exist? ruby and File.executable? ruby and !File.directory? ruby\n        return File.expand_path(ruby)\n      end\n      if File.exist? rubyexe and File.executable? rubyexe\n        return File.expand_path(ruby)\n      end\n      ruby = File.join(\"..\", ruby)\n    end\n    begin\n      require \"rbconfig\"\n      File.join(\n        Config::CONFIG[\"bindir\"],\n\tConfig::CONFIG[\"ruby_install_name\"] + Config::CONFIG[\"EXEEXT\"]\n      )\n    rescue LoadError\n      \"ruby\"\n    end\n  end\n  module_function :rubybin\nend\n"
  },
  {
    "path": "test/ruby/marshaltestlib.rb",
    "content": "module MarshalTestLib\n  # include this module to a Test::Unit::TestCase and definde encode(o) and\n  # decode(s) methods.  e.g.\n  #\n  # def encode(o)\n  #   SOAPMarshal.dump(o)\n  # end\n  #\n  # def decode(s)\n  #   SOAPMarshal.load(s)\n  # end\n\n  NegativeZero = (-1.0 / (1.0 / 0.0))\n\n  module Mod1; end\n  module Mod2; end\n\n  def marshaltest(o1)\n    str = encode(o1)\n    print str, \"\\n\" if $DEBUG\n    o2 = decode(str)\n    o2\n  end\n\n  def marshal_equal(o1, msg = nil)\n    msg = msg ? msg + \"(#{ caller[0] })\" : caller[0]\n    o2 = marshaltest(o1)\n    assert_equal(o1.class, o2.class, msg)\n    iv1 = o1.instance_variables.sort\n    iv2 = o2.instance_variables.sort\n    assert_equal(iv1, iv2)\n    val1 = iv1.map {|var| o1.instance_eval {eval var}}\n    val2 = iv1.map {|var| o2.instance_eval {eval var}}\n    assert_equal(val1, val2, msg)\n    if block_given?\n      assert_equal(yield(o1), yield(o2), msg)\n    else\n      assert_equal(o1, o2, msg)\n    end\n  end\n\n  class MyObject; def initialize(v) @v = v end; attr_reader :v; end\n  def test_object\n    o1 = Object.new\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_object_subclass\n    marshal_equal(MyObject.new(2)) {|o| o.v}\n  end\n\n  def test_object_extend\n    o1 = Object.new\n    o1.extend(Mod1)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n    o1.extend(Mod2)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n  end\n\n  def test_object_subclass_extend\n    o1 = MyObject.new(2)\n    o1.extend(Mod1)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n    o1.extend(Mod2)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n  end\n\n  class MyArray < Array\n    def initialize(v, *args)\n      super(args)\n      @v = v\n    end\n  end\n  def test_array\n    marshal_equal(5)\n    marshal_equal([1,2,3])\n  end\n\n  def test_array_subclass\n    marshal_equal(MyArray.new(0, 1, 2, 3))\n  end\n\n  def test_array_ivar\n    o1 = Array.new\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  class MyException < Exception; def initialize(v, *args) super(*args); @v = v; end; attr_reader :v; end\n  def test_exception\n    marshal_equal(Exception.new('foo')) {|o| o.message}\n    marshal_equal(assert_raise(NoMethodError) {no_such_method()}) {|o| o.message}\n  end\n\n  def test_exception_subclass\n    marshal_equal(MyException.new(20, \"bar\")) {|o| [o.message, o.v]}\n  end\n\n  def test_false\n    marshal_equal(false)\n  end\n\n  class MyHash < Hash; def initialize(v, *args) super(*args); @v = v; end end\n  def test_hash\n    marshal_equal({1=>2, 3=>4})\n  end\n\n  def test_hash_default\n    h = Hash.new(:default)\n    h[5] = 6\n    marshal_equal(h)\n  end\n\n  def test_hash_subclass\n    h = MyHash.new(7, 8)\n    h[4] = 5\n    marshal_equal(h)\n  end\n\n  def test_hash_default_proc\n    h = Hash.new {}\n    assert_raises(TypeError) { marshaltest(h) }\n  end\n\n  def test_hash_ivar\n    o1 = Hash.new\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_hash_extend\n    o1 = Hash.new\n    o1.extend(Mod1)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n    o1.extend(Mod2)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n  end\n\n  def test_hash_subclass_extend\n    o1 = MyHash.new(2)\n    o1.extend(Mod1)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n    o1.extend(Mod2)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n  end\n\n  def test_bignum\n    marshal_equal(-0x4000_0000_0000_0001)\n    marshal_equal(-0x4000_0001)\n    marshal_equal(0x4000_0000)\n    marshal_equal(0x4000_0000_0000_0000)\n  end\n\n  def test_fixnum\n    marshal_equal(-0x4000_0000)\n    marshal_equal(-0x3fff_ffff)\n    marshal_equal(-1)\n    marshal_equal(0)\n    marshal_equal(1)\n    marshal_equal(0x3fff_ffff)\n  end\n\n  def test_fixnum_ivar\n    o1 = 1\n    o1.instance_eval { @iv = 2 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  ensure\n    1.instance_eval { remove_instance_variable(\"@iv\") }\n  end\n\n  def test_fixnum_ivar_self\n    o1 = 1\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  ensure\n    1.instance_eval { remove_instance_variable(\"@iv\") }\n  end\n\n  def test_fixnum_64bit\n    obj = [1220278665, 1220278662, 1220278661, 1220278661, 1220278656]\n\n    marshal_equal(obj)\n  end\n\n  def test_float\n    marshal_equal(-1.0)\n    marshal_equal(0.0)\n    marshal_equal(1.0)\n  end\n\n  def test_float_inf_nan\n    marshal_equal(1.0/0.0)\n    marshal_equal(-1.0/0.0)\n    marshal_equal(0.0/0.0) {|o| o.nan?}\n    marshal_equal(NegativeZero) {|o| 1.0/o}\n  end\n\n  def test_float_ivar\n    o1 = 1.23\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_float_ivar_self\n    o1 = 5.5\n    o1.instance_eval { @iv = o1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_float_extend\n    o1 = 0.0/0.0\n    o1.extend(Mod1)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n    o1.extend(Mod2)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n  end\n\n  class MyRange < Range; def initialize(v, *args) super(*args); @v = v; end end\n  def test_range\n    marshal_equal(1..2)\n    marshal_equal(1...3)\n  end\n\n  def test_range_subclass\n    marshal_equal(MyRange.new(4,5,8, false))\n  end\n\n  class MyRegexp < Regexp; def initialize(v, *args) super(*args); @v = v; end end\n  def test_regexp\n    marshal_equal(/a/)\n    marshal_equal(/A/i)\n    marshal_equal(/A/mx)\n  end\n\n  def test_regexp_subclass\n    marshal_equal(MyRegexp.new(10, \"a\"))\n  end\n\n  class MyString < String; def initialize(v, *args) super(*args); @v = v; end end\n  def test_string\n    marshal_equal(\"abc\")\n  end\n\n  def test_string_ivar\n    o1 = \"\"\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_string_subclass\n    marshal_equal(MyString.new(10, \"a\"))\n  end\n\n  def test_string_subclass_cycle\n    str = MyString.new(10, \"b\")\n    str.instance_eval { @v = str }\n    marshal_equal(str) { |o|\n      assert_equal(o.__id__, o.instance_eval { @v }.__id__)\n      o.instance_eval { @v }\n    }\n  end\n\n  def test_string_subclass_extend\n    o = \"abc\"\n    o.extend(Mod1)\n    str = MyString.new(o, \"c\")\n    marshal_equal(str) { |o|\n      assert(o.instance_eval { @v }).kind_of?(Mod1)\n    }\n  end\n\n  MyStruct = Struct.new(\"MyStruct\", :a, :b)\n  if RUBY_VERSION < \"1.8.0\"\n    # Struct#== is not defined in ruby/1.6\n    class MyStruct\n      def ==(rhs)\n\treturn true if __id__ == rhs.__id__\n\treturn false unless rhs.is_a?(::Struct) \n\treturn false if self.class != rhs.class\n\tmembers.each do |member|\n\t  return false if self.__send__(member) != rhs.__send__(member)\n\tend\n\treturn true\n      end\n    end\n  end\n  class MySubStruct < MyStruct; def initialize(v, *args) super(*args); @v = v; end end\n  def test_struct\n    marshal_equal(MyStruct.new(1,2))\n  end\n\n  def test_struct_subclass\n    if RUBY_VERSION < \"1.8.0\"\n      # Substruct instance cannot be dumped in ruby/1.6\n      # ::Marshal.dump(MySubStruct.new(10, 1, 2)) #=> uninitialized struct\n      return false\n    end\n    marshal_equal(MySubStruct.new(10,1,2))\n  end\n\n  def test_struct_ivar\n    o1 = MyStruct.new\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_struct_subclass_extend\n    o1 = MyStruct.new\n    o1.extend(Mod1)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n    o1.extend(Mod2)\n    marshal_equal(o1) { |o|\n      (class << self; self; end).ancestors\n    }\n  end\n\n  def test_symbol\n    marshal_equal(:a)\n    marshal_equal(:a?)\n    marshal_equal(:a!)\n    marshal_equal(:a=)\n    marshal_equal(:|)\n    marshal_equal(:^)\n    marshal_equal(:&)\n    marshal_equal(:<=>)\n    marshal_equal(:==)\n    marshal_equal(:===)\n    marshal_equal(:=~)\n    marshal_equal(:>)\n    marshal_equal(:>=)\n    marshal_equal(:<)\n    marshal_equal(:<=)\n    marshal_equal(:<<)\n    marshal_equal(:>>)\n    marshal_equal(:+)\n    marshal_equal(:-)\n    marshal_equal(:*)\n    marshal_equal(:/)\n    marshal_equal(:%)\n    marshal_equal(:**)\n    marshal_equal(:~)\n    marshal_equal(:+@)\n    marshal_equal(:-@)\n    marshal_equal(:[])\n    marshal_equal(:[]=)\n    marshal_equal(:`)   #`\n    marshal_equal(\"a b\".intern)\n  end\n\n  class MyTime < Time; def initialize(v, *args) super(*args); @v = v; end end\n  def test_time\n    # once there was a bug caused by usec overflow.  try a little harder.\n    10.times do\n      t = Time.now\n      marshal_equal(t, t.usec.to_s)\n    end\n  end\n\n  def test_time_subclass\n    marshal_equal(MyTime.new(10))\n  end\n\n  def test_time_ivar\n    o1 = Time.now\n    o1.instance_eval { @iv = 1 }\n    marshal_equal(o1) {|o| o.instance_eval { @iv }}\n  end\n\n  def test_true\n    marshal_equal(true)\n  end\n\n  def test_nil\n    marshal_equal(nil)\n  end\n\n  def test_share\n    o = [:share]\n    o1 = [o, o]\n    o2 = marshaltest(o1)\n    assert_same(o2.first, o2.last)\n  end\n\n  class CyclicRange < Range\n    def <=>(other); true; end\n  end\n  def test_range_cyclic\n    return unless CyclicRange.respond_to?(:allocate) # test for 1.8\n    o1 = CyclicRange.allocate\n    o1.instance_eval { initialize(o1, o1) }\n    o2 = marshaltest(o1)\n    assert_same(o2, o2.begin)\n    assert_same(o2, o2.end)\n  end\n\n  def test_singleton\n    o = Object.new\n    def o.m() end\n    assert_raises(TypeError) { marshaltest(o) }\n    o = Object.new\n    c = class << o\n      @v = 1\n      class C; self; end\n    end\n    assert_raises(TypeError) { marshaltest(o) }\n    assert_raises(TypeError) { marshaltest(c) }\n    assert_raises(TypeError) { marshaltest(ARGF) }\n    assert_raises(TypeError) { marshaltest(ENV) }\n  end\n\n  def test_extend\n    o = Object.new\n    o.extend Mod1\n    marshal_equal(o) { |obj| obj.kind_of? Mod1 }\n    o = Object.new\n    o.extend Mod1\n    o.extend Mod2\n    marshal_equal(o) {|obj| class << obj; ancestors end}\n    o = Object.new\n    o.extend Module.new\n    assert_raises(TypeError) { marshaltest(o) }\n  end\n\n  def test_extend_string\n    o = \"\"\n    o.extend Mod1\n    marshal_equal(o) { |obj| obj.kind_of? Mod1 }\n    o = \"\"\n    o.extend Mod1\n    o.extend Mod2\n    marshal_equal(o) {|obj| class << obj; ancestors end}\n    o = \"\"\n    o.extend Module.new\n    assert_raises(TypeError) { marshaltest(o) }\n  end\n\n  def test_anonymous\n    c = Class.new\n    assert_raises(TypeError) { marshaltest(c) }\n    o = c.new\n    assert_raises(TypeError) { marshaltest(o) }\n    m = Module.new\n    assert_raises(TypeError) { marshaltest(m) }\n  end\n\n  def test_string_empty\n    marshal_equal(\"\")\n  end\n\n  def test_string_crlf\n    marshal_equal(\"\\r\\n\")\n  end\n\n  def test_string_escape\n    marshal_equal(\"\\0<;;>\\1;;\")\n  end\n\n  MyStruct2 = Struct.new(:a, :b)\n  if RUBY_VERSION < \"1.8.0\"\n    # Struct#== is not defined in ruby/1.6\n    class MyStruct2\n      def ==(rhs)\n\treturn true if __id__ == rhs.__id__\n\treturn false unless rhs.is_a?(::Struct) \n\treturn false if self.class != rhs.class\n\tmembers.each do |member|\n\t  return false if self.__send__(member) != rhs.__send__(member)\n\tend\n\treturn true\n      end\n    end\n  end\n  def test_struct_toplevel\n    o = MyStruct2.new(1,2)\n    marshal_equal(o)\n  end\nend\n"
  },
  {
    "path": "test/ruby/suicide.rb",
    "content": "STDERR.reopen(STDOUT)\nat_exit{Process.kill(:INT, $$); sleep 0}\n# brent@mbari.org says\n#  sleep 0 avoids race between process termination and signal reception\n"
  },
  {
    "path": "test/ruby/test_alias.rb",
    "content": "require 'test/unit'\n\nclass TestAlias < Test::Unit::TestCase\n  class Alias0\n    def foo; \"foo\" end\n  end\n  class Alias1<Alias0\n    alias bar foo\n    def foo; \"foo+\" + super end\n  end\n  class Alias2<Alias1\n    alias baz foo\n    undef foo\n  end\n  class Alias3<Alias2\n    def foo\n      defined? super\n    end\n    def bar\n      defined? super\n    end\n    def quux\n      defined? super\n    end\n  end\n\n  def test_alias\n    x = Alias2.new\n    assert_equal(\"foo\", x.bar)\n    assert_equal(\"foo+foo\", x.baz)\n\n    # test_check for cache\n    assert_equal(\"foo+foo\", x.baz)\n\n    x = Alias3.new\n    assert(!x.foo)\n    assert(x.bar)\n    assert(!x.quux)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_array.rb",
    "content": "require 'test/unit'\n\nclass TestArray < Test::Unit::TestCase\n  def test_0_literal\n    assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])\n    assert_equal([1, 2, 1, 2], [1, 2] * 2)\n    assert_equal(\"1:2\", [1, 2] * \":\")\n\n    assert_equal([1, 2].hash, [1, 2].hash)\n\n    assert_equal([2,3], [1,2,3] & [2,3,4])\n    assert_equal([1,2,3,4], [1,2,3] | [2,3,4])\n    assert_equal([1,2,3] - [2,3], [1])\n\n    x = [0, 1, 2, 3, 4, 5]\n    assert_equal(2, x[2])\n    assert_equal([1, 2, 3], x[1..3])\n    assert_equal([1, 2, 3], x[1,3])\n\n    x[0, 2] = 10\n    assert(x[0] == 10 && x[1] == 2)\n\n    x[0, 0] = -1\n    assert(x[0] == -1 && x[1] == 10)\n\n    x[-1, 1] = 20\n    assert(x[-1] == 20 && x.pop == 20)\n  end\n\n  def test_array_andor_0\n    assert_equal([2], ([1,2,3]&[2,4,6]))\n    assert_equal([1,2,3,4,6], ([1,2,3]|[2,4,6]))\n  end\n\n  def test_compact_0\n    a = [nil, 1, nil, nil, 5, nil, nil]\n    assert_equal [1, 5], a.compact\n    assert_equal [nil, 1, nil, nil, 5, nil, nil], a\n    a.compact!\n    assert_equal [1, 5], a\n  end\n\n  def test_uniq_0\n    x = [1, 1, 4, 2, 5, 4, 5, 1, 2]\n    x.uniq!\n    assert_equal([1, 4, 2, 5], x)\n  end\n\n  def test_empty_0\n    assert_equal true, [].empty?\n    assert_equal false, [1].empty?\n    assert_equal false, [1, 1, 4, 2, 5, 4, 5, 1, 2].empty?\n  end\n\n  def test_sort_0\n    x = [\"it\", \"came\", \"to\", \"pass\", \"that\", \"...\"]\n    x = x.sort.join(\" \")\n    assert_equal(\"... came it pass that to\", x)\n    x = [2,5,3,1,7]\n    x.sort!{|a,b| a<=>b}\t\t# sort with condition\n    assert_equal([1,2,3,5,7], x)\n    x.sort!{|a,b| b-a}\t\t# reverse sort\n    assert_equal([7,5,3,2,1], x)\n  end\n\n  def test_split_0\n    x = \"The Boassert of Mormon\"\n    assert_equal(x.reverse, x.split(//).reverse!.join)\n    assert_equal(x.reverse, x.reverse!)\n    assert_equal(\"g:n:i:r:t:s: :e:t:y:b: :1\", \"1 byte string\".split(//).reverse.join(\":\"))\n    x = \"a b c  d\"\n    assert_equal(['a', 'b', 'c', 'd'], x.split)\n    assert_equal(['a', 'b', 'c', 'd'], x.split(' '))\n  end\n\n  def test_misc_0\n    assert(defined? \"a\".chomp)\n    assert_equal([\"a\", \"b\", \"c\"], \"abc\".scan(/./))\n    assert_equal([[\"1a\"], [\"2b\"], [\"3c\"]], \"1a2b3c\".scan(/(\\d.)/))\n    # non-greedy match\n    assert_equal([[\"a\", \"12\"], [\"b\", \"22\"]], \"a=12;b=22\".scan(/(.*?)=(\\d*);?/))\n\n    x = [1]\n    assert_equal('1:1:1:1:1', (x * 5).join(\":\"))\n    assert_equal('1', (x * 1).join(\":\"))\n    assert_equal('', (x * 0).join(\":\"))\n\n    *x = *(1..7).to_a\n    assert_equal(7, x.size)\n    assert_equal([1, 2, 3, 4, 5, 6, 7], x)\n\n    x = [1,2,3]\n    x[1,0] = x\n    assert_equal([1,1,2,3,2,3], x)\n\n    x = [1,2,3]\n    x[-1,0] = x\n    assert_equal([1,2,1,2,3,3], x)\n\n    x = [1,2,3]\n    x.concat(x)\n    assert_equal([1,2,3,1,2,3], x)\n\n    x = [1,2,3]\n    x.clear\n    assert_equal([], x)\n\n    x = [1,2,3]\n    y = x.dup\n    x << 4\n    y << 5\n    assert_equal([1,2,3,4], x)\n    assert_equal([1,2,3,5], y)\n  end\n\n  def test_beg_end_0\n    x = [1, 2, 3, 4, 5]\n    \n    assert_equal(1, x.first)\n    assert_equal([1], x.first(1))\n    assert_equal([1, 2, 3], x.first(3))\n    \n    assert_equal(5, x.last)\n    assert_equal([5], x.last(1))\n    assert_equal([3, 4, 5], x.last(3))\n    \n    assert_equal(1, x.shift)\n    assert_equal([2, 3, 4], x.shift(3))\n    assert_equal([5], x)\n    \n    assert_equal([2, 3, 4, 5], x.unshift(2, 3, 4))\n    assert_equal([1, 2, 3, 4, 5], x.unshift(1))\n    assert_equal([1, 2, 3, 4, 5], x)\n    \n    assert_equal(5, x.pop)\n    assert_equal([3, 4], x.pop(2))\n    assert_equal([1, 2], x)\n    \n    assert_equal([1, 2, 3, 4], x.push(3, 4))\n    assert_equal([1, 2, 3, 4, 5], x.push(5))\n    assert_equal([1, 2, 3, 4, 5], x)\n  end\n\n  def test_find_all_0\n    assert_respond_to([], :find_all)\n    assert_respond_to([], :select)       # Alias\n    assert_equal([], [].find_all{ |obj| obj == \"foo\"})\n\n    x = [\"foo\", \"bar\", \"baz\", \"baz\", 1, 2, 3, 3, 4]\n    assert_equal([\"baz\",\"baz\"], x.find_all{ |obj| obj == \"baz\" })\n    assert_equal([3,3], x.find_all{ |obj| obj == 3 })\n  end\n\n  def test_fill_0\n    assert_equal([-1, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1))\n    assert_equal([0, 1, 2, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 3))\n    assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3, 2))\n    assert_equal([0, 1, 2, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 3, 5))\n    assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2, 2))\n    assert_equal([0, 1, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 2, 5))\n    assert_equal([0, 1, 2, 3, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, -2, 1))\n    assert_equal([0, 1, 2, 3, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, -2, 3))\n    assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3..4))\n    assert_equal([0, 1, 2, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3...4))\n    assert_equal([0, 1, -1, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2..-2))\n    assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2...-2))\n    assert_equal([10, 11, 12, 13, 14, 15], [0, 1, 2, 3, 4, 5].fill{|i| i+10})\n    assert_equal([0, 1, 2, 13, 14, 15], [0, 1, 2, 3, 4, 5].fill(3){|i| i+10})\n    assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3, 2){|i| i+10})\n    assert_equal([0, 1, 2, 13, 14, 15, 16, 17], [0, 1, 2, 3, 4, 5].fill(3, 5){|i| i+10})\n    assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3..4){|i| i+10})\n    assert_equal([0, 1, 2, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(3...4){|i| i+10})\n    assert_equal([0, 1, 12, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(2..-2){|i| i+10})\n    assert_equal([0, 1, 12, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(2...-2){|i| i+10})\n  end\n\n  # From rubicon\n\n  def setup\n    @cls = Array\n  end\n\n  def test_00_new\n    a = @cls.new()\n    assert_instance_of(@cls, a)\n    assert_equal(0, a.length)\n    assert_nil(a[0])\n  end\n\n  def test_01_square_brackets\n    a = @cls[ 5, 4, 3, 2, 1 ]\n    assert_instance_of(@cls, a)\n    assert_equal(5, a.length)\n    5.times { |i| assert_equal(5-i, a[i]) }\n    assert_nil(a[6])\n  end\n\n  def test_AND # '&'\n    assert_equal(@cls[1, 3], @cls[ 1, 1, 3, 5 ] & @cls[ 1, 2, 3 ])\n    assert_equal(@cls[],     @cls[ 1, 1, 3, 5 ] & @cls[ ])\n    assert_equal(@cls[],     @cls[  ]           & @cls[ 1, 2, 3 ])\n    assert_equal(@cls[],     @cls[ 1, 2, 3 ]    & @cls[ 4, 5, 6 ])\n  end\n\n  def test_MUL # '*'\n    assert_equal(@cls[], @cls[]*3)\n    assert_equal(@cls[1, 1, 1], @cls[1]*3)\n    assert_equal(@cls[1, 2, 1, 2, 1, 2], @cls[1, 2]*3)\n    assert_equal(@cls[], @cls[1, 2, 3] * 0)\n    assert_raise(ArgumentError) { @cls[1, 2]*(-3) }\n\n    assert_equal('1-2-3-4-5', @cls[1, 2, 3, 4, 5] * '-')\n    assert_equal('12345',     @cls[1, 2, 3, 4, 5] * '')\n\n  end\n\n  def test_PLUS # '+'\n    assert_equal(@cls[],     @cls[]  + @cls[])\n    assert_equal(@cls[1],    @cls[1] + @cls[])\n    assert_equal(@cls[1],    @cls[]  + @cls[1])\n    assert_equal(@cls[1, 1], @cls[1] + @cls[1])\n    assert_equal(@cls['cat', 'dog', 1, 2, 3], %w(cat dog) + (1..3).to_a)\n  end\n\n  def test_MINUS # '-'\n    assert_equal(@cls[],  @cls[1] - @cls[1])\n    assert_equal(@cls[1], @cls[1, 2, 3, 4, 5] - @cls[2, 3, 4, 5])\n    # Ruby 1.8 feature change\n    #assert_equal(@cls[1], @cls[1, 2, 1, 3, 1, 4, 1, 5] - @cls[2, 3, 4, 5])\n    assert_equal(@cls[1, 1, 1, 1], @cls[1, 2, 1, 3, 1, 4, 1, 5] - @cls[2, 3, 4, 5])\n    a = @cls[]\n    1000.times { a << 1 }\n    assert_equal(1000, a.length)\n    #assert_equal(@cls[1], a - @cls[2])\n    assert_equal(@cls[1] * 1000, a - @cls[2])\n    #assert_equal(@cls[1],  @cls[1, 2, 1] - @cls[2])\n    assert_equal(@cls[1, 1],  @cls[1, 2, 1] - @cls[2])\n    assert_equal(@cls[1, 2, 3], @cls[1, 2, 3] - @cls[4, 5, 6])\n  end\n\n  def test_LSHIFT # '<<'\n    a = @cls[]\n    a << 1\n    assert_equal(@cls[1], a)\n    a << 2 << 3\n    assert_equal(@cls[1, 2, 3], a)\n    a << nil << 'cat'\n    assert_equal(@cls[1, 2, 3, nil, 'cat'], a)\n    a << a\n    assert_equal(@cls[1, 2, 3, nil, 'cat', a], a)\n  end\n\n  def test_CMP # '<=>'\n    assert_equal(0,  @cls[] <=> @cls[])\n    assert_equal(0,  @cls[1] <=> @cls[1])\n    assert_equal(0,  @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3, 'cat'])\n    assert_equal(-1, @cls[] <=> @cls[1])\n    assert_equal(1,  @cls[1] <=> @cls[])\n    assert_equal(-1, @cls[1, 2, 3] <=> @cls[1, 2, 3, 'cat'])\n    assert_equal(1,  @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3])\n    assert_equal(-1, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3, 'dog'])\n    assert_equal(1,  @cls[1, 2, 3, 'dog'] <=> @cls[1, 2, 3, 'cat'])\n  end\n\n  def test_EQUAL # '=='\n    assert(@cls[] == @cls[])\n    assert(@cls[1] == @cls[1])\n    assert(@cls[1, 1, 2, 2] == @cls[1, 1, 2, 2])\n    assert(@cls[1.0, 1.0, 2.0, 2.0] == @cls[1, 1, 2, 2])\n  end\n\n  def test_VERY_EQUAL # '==='\n    assert(@cls[] === @cls[])\n    assert(@cls[1] === @cls[1])\n    assert(@cls[1, 1, 2, 2] === @cls[1, 1, 2, 2])\n    assert(@cls[1.0, 1.0, 2.0, 2.0] === @cls[1, 1, 2, 2])\n  end\n\n  def test_AREF # '[]'\n    a = @cls[*(1..100).to_a]\n\n    assert_equal(1, a[0])\n    assert_equal(100, a[99])\n    assert_nil(a[100])\n    assert_equal(100, a[-1])\n    assert_equal(99,  a[-2])\n    assert_equal(1,   a[-100])\n    assert_nil(a[-101])\n    assert_nil(a[-101,0])\n    assert_nil(a[-101,1])\n    assert_nil(a[-101,-1])\n    assert_nil(a[10,-1])\n\n    assert_equal(@cls[1],   a[0,1])\n    assert_equal(@cls[100], a[99,1])\n    assert_equal(@cls[],    a[100,1])\n    assert_equal(@cls[100], a[99,100])\n    assert_equal(@cls[100], a[-1,1])\n    assert_equal(@cls[99],  a[-2,1])\n    assert_equal(@cls[],    a[-100,0])\n    assert_equal(@cls[1],   a[-100,1])\n\n    assert_equal(@cls[10, 11, 12], a[9, 3])\n    assert_equal(@cls[10, 11, 12], a[-91, 3])\n\n    assert_equal(@cls[1],   a[0..0])\n    assert_equal(@cls[100], a[99..99])\n    assert_equal(@cls[],    a[100..100])\n    assert_equal(@cls[100], a[99..200])\n    assert_equal(@cls[100], a[-1..-1])\n    assert_equal(@cls[99],  a[-2..-2])\n\n    assert_equal(@cls[10, 11, 12], a[9..11])\n    assert_equal(@cls[10, 11, 12], a[-91..-89])\n    \n    assert_nil(a[10, -3])\n    # Ruby 1.8 feature change:\n    # Array#[size..x] returns [] instead of nil.\n    #assert_nil(a[10..7])\n    assert_equal [], a[10..7]\n\n    assert_raise(TypeError) {a['cat']}\n  end\n\n  def test_ASET # '[]='\n    a = @cls[*(0..99).to_a]\n    assert_equal(0, a[0] = 0)\n    assert_equal(@cls[0] + @cls[*(1..99).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(0, a[10,10] = 0)\n    assert_equal(@cls[*(0..9).to_a] + @cls[0] + @cls[*(20..99).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(0, a[-1] = 0)\n    assert_equal(@cls[*(0..98).to_a] + @cls[0], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(0, a[-10, 10] = 0)\n    assert_equal(@cls[*(0..89).to_a] + @cls[0], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(0, a[0,1000] = 0)\n    assert_equal(@cls[0] , a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(0, a[10..19] = 0)\n    assert_equal(@cls[*(0..9).to_a] + @cls[0] + @cls[*(20..99).to_a], a)\n\n    b = @cls[*%w( a b c )]\n    a = @cls[*(0..99).to_a]\n    assert_equal(b, a[0,1] = b)\n    assert_equal(b + @cls[*(1..99).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(b, a[10,10] = b)\n    assert_equal(@cls[*(0..9).to_a] + b + @cls[*(20..99).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(b, a[-1, 1] = b)\n    assert_equal(@cls[*(0..98).to_a] + b, a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(b, a[-10, 10] = b)\n    assert_equal(@cls[*(0..89).to_a] + b, a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(b, a[0,1000] = b)\n    assert_equal(b , a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(b, a[10..19] = b)\n    assert_equal(@cls[*(0..9).to_a] + b + @cls[*(20..99).to_a], a)\n\n    # Ruby 1.8 feature change:\n    # assigning nil does not remove elements.\n=begin\n    a = @cls[*(0..99).to_a]\n    assert_equal(nil, a[0,1] = nil)\n    assert_equal(@cls[*(1..99).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(nil, a[10,10] = nil)\n    assert_equal(@cls[*(0..9).to_a] + @cls[*(20..99).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(nil, a[-1, 1] = nil)\n    assert_equal(@cls[*(0..98).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(nil, a[-10, 10] = nil)\n    assert_equal(@cls[*(0..89).to_a], a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(nil, a[0,1000] = nil)\n    assert_equal(@cls[] , a)\n\n    a = @cls[*(0..99).to_a]\n    assert_equal(nil, a[10..19] = nil)\n    assert_equal(@cls[*(0..9).to_a] + @cls[*(20..99).to_a], a)\n=end\n\n    a = @cls[1, 2, 3]\n    a[1, 0] = a\n    assert_equal([1, 1, 2, 3, 2, 3], a)\n\n    a = @cls[1, 2, 3]\n    a[-1, 0] = a\n    assert_equal([1, 2, 1, 2, 3, 3], a)\n  end\n\n  def test_assoc\n    a1 = @cls[*%w( cat feline )]\n    a2 = @cls[*%w( dog canine )]\n    a3 = @cls[*%w( mule asinine )]\n\n    a = @cls[ a1, a2, a3 ]\n\n    assert_equal(a1, a.assoc('cat'))\n    assert_equal(a3, a.assoc('mule'))\n    assert_equal(nil, a.assoc('asinine'))\n    assert_equal(nil, a.assoc('wombat'))\n    assert_equal(nil, a.assoc(1..2))\n  end\n\n  def test_at\n    a = @cls[*(0..99).to_a]\n    assert_equal(0,   a.at(0))\n    assert_equal(10,  a.at(10))\n    assert_equal(99,  a.at(99))\n    assert_equal(nil, a.at(100))\n    assert_equal(99,  a.at(-1))\n    assert_equal(0,  a.at(-100))\n    assert_equal(nil, a.at(-101))\n    assert_raise(TypeError) { a.at('cat') }\n  end\n\n  def test_clear\n    a = @cls[1, 2, 3]\n    b = a.clear\n    assert_equal(@cls[], a)\n    assert_equal(@cls[], b)\n    assert_equal(a.__id__, b.__id__)\n  end\n\n  def test_clone\n    for taint in [ false, true ]\n      for frozen in [ false, true ]\n        a = @cls[*(0..99).to_a]\n        a.taint  if taint\n        a.freeze if frozen\n        b = a.clone\n\n        assert_equal(a, b)\n        assert(a.__id__ != b.__id__)\n        assert_equal(a.frozen?, b.frozen?)\n        assert_equal(a.tainted?, b.tainted?)\n      end\n    end\n  end\n\n  def test_collect\n    a = @cls[ 1, 'cat', 1..1 ]\n    assert_equal([ Fixnum, String, Range], a.collect {|e| e.class} )\n    assert_equal([ 99, 99, 99], a.collect { 99 } )\n\n    assert_equal([], @cls[].collect { 99 })\n\n    assert_equal([1, 2, 3], @cls[1, 2, 3].collect)\n  end\n\n  # also update map!\n  def test_collect!\n    a = @cls[ 1, 'cat', 1..1 ]\n    assert_equal([ Fixnum, String, Range], a.collect! {|e| e.class} )\n    assert_equal([ Fixnum, String, Range], a)\n   \n    a = @cls[ 1, 'cat', 1..1 ]\n    assert_equal([ 99, 99, 99], a.collect! { 99 } )\n    assert_equal([ 99, 99, 99], a)\n\n    a = @cls[ ]\n    assert_equal([], a.collect! { 99 })\n    assert_equal([], a)\n  end\n\n  def test_compact\n    a = @cls[ 1, nil, nil, 2, 3, nil, 4 ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact)\n\n    a = @cls[ nil, 1, nil, 2, 3, nil, 4 ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact)\n\n    a = @cls[ 1, nil, nil, 2, 3, nil, 4, nil ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact)\n\n    a = @cls[ 1, 2, 3, 4 ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact)\n  end\n\n  def test_compact!\n    a = @cls[ 1, nil, nil, 2, 3, nil, 4 ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact!)\n    assert_equal(@cls[1, 2, 3, 4], a)\n\n    a = @cls[ nil, 1, nil, 2, 3, nil, 4 ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact!)\n    assert_equal(@cls[1, 2, 3, 4], a)\n\n    a = @cls[ 1, nil, nil, 2, 3, nil, 4, nil ]\n    assert_equal(@cls[1, 2, 3, 4], a.compact!)\n    assert_equal(@cls[1, 2, 3, 4], a)\n\n    a = @cls[ 1, 2, 3, 4 ]\n    assert_equal(nil, a.compact!)\n    assert_equal(@cls[1, 2, 3, 4], a)\n  end\n\n  def test_concat\n    assert_equal(@cls[1, 2, 3, 4],     @cls[1, 2].concat(@cls[3, 4]))\n    assert_equal(@cls[1, 2, 3, 4],     @cls[].concat(@cls[1, 2, 3, 4]))\n    assert_equal(@cls[1, 2, 3, 4],     @cls[1, 2, 3, 4].concat(@cls[]))\n    assert_equal(@cls[],               @cls[].concat(@cls[]))\n    assert_equal(@cls[@cls[1, 2], @cls[3, 4]], @cls[@cls[1, 2]].concat(@cls[@cls[3, 4]]))\n    \n    a = @cls[1, 2, 3]\n    a.concat(a)\n    assert_equal([1, 2, 3, 1, 2, 3], a)\n  end\n\n  def test_count\n    a = @cls[1, 2, 3, 1, 2]\n    assert_equal(5, a.count)\n    assert_equal(2, a.count(1))\n    assert_equal(3, a.count {|x| x % 2 == 1 })\n    assert_equal(2, a.count(1) {|x| x % 2 == 1 })\n    assert_raise(ArgumentError) { a.count(0, 1) }\n  end\n\n  def test_delete\n    a = @cls[*('cab'..'cat').to_a]\n    assert_equal('cap', a.delete('cap'))\n    assert_equal(@cls[*('cab'..'cao').to_a] + @cls[*('caq'..'cat').to_a], a)\n\n    a = @cls[*('cab'..'cat').to_a]\n    assert_equal('cab', a.delete('cab'))\n    assert_equal(@cls[*('cac'..'cat').to_a], a)\n\n    a = @cls[*('cab'..'cat').to_a]\n    assert_equal('cat', a.delete('cat'))\n    assert_equal(@cls[*('cab'..'cas').to_a], a)\n\n    a = @cls[*('cab'..'cat').to_a]\n    assert_equal(nil, a.delete('cup'))\n    assert_equal(@cls[*('cab'..'cat').to_a], a)\n\n    a = @cls[*('cab'..'cat').to_a]\n    assert_equal(99, a.delete('cup') { 99 } )\n    assert_equal(@cls[*('cab'..'cat').to_a], a)\n  end\n\n  def test_delete_at\n    a = @cls[*(1..5).to_a]\n    assert_equal(3, a.delete_at(2))\n    assert_equal(@cls[1, 2, 4, 5], a)\n\n    a = @cls[*(1..5).to_a]\n    assert_equal(4, a.delete_at(-2))\n    assert_equal(@cls[1, 2, 3, 5], a)\n\n    a = @cls[*(1..5).to_a]\n    assert_equal(nil, a.delete_at(5))\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n\n    a = @cls[*(1..5).to_a]\n    assert_equal(nil, a.delete_at(-6))\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n  end\n\n  # also reject!\n  def test_delete_if\n    a = @cls[ 1, 2, 3, 4, 5 ]\n    assert_equal(a, a.delete_if { false })\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n\n    a = @cls[ 1, 2, 3, 4, 5 ]\n    assert_equal(a, a.delete_if { true })\n    assert_equal(@cls[], a)\n\n    a = @cls[ 1, 2, 3, 4, 5 ]\n    assert_equal(a, a.delete_if { |i| i > 3 })\n    assert_equal(@cls[1, 2, 3], a)\n  end\n\n  def test_dup\n    for taint in [ false, true ]\n      for frozen in [ false, true ]\n        a = @cls[*(0..99).to_a]\n        a.taint  if taint\n        a.freeze if frozen\n        b = a.dup\n\n        assert_equal(a, b)\n        assert(a.__id__ != b.__id__)\n        assert_equal(false, b.frozen?)\n        assert_equal(a.tainted?, b.tainted?)\n      end\n    end\n  end\n\n  def test_each\n    a = @cls[*%w( ant bat cat dog )]\n    i = 0\n    a.each { |e|\n      assert_equal(a[i], e)\n      i += 1\n    }\n    assert_equal(4, i)\n\n    a = @cls[]\n    i = 0\n    a.each { |e|\n      assert_equal(a[i], e)\n      i += 1\n    }\n    assert_equal(0, i)\n\n    assert_equal(a, a.each {})\n  end\n\n  def test_each_index\n    a = @cls[*%w( ant bat cat dog )]\n    i = 0\n    a.each_index { |ind|\n      assert_equal(i, ind)\n      i += 1\n    }\n    assert_equal(4, i)\n\n    a = @cls[]\n    i = 0\n    a.each_index { |ind|\n      assert_equal(i, ind)\n      i += 1\n    }\n    assert_equal(0, i)\n\n    assert_equal(a, a.each_index {})\n  end\n\n  def test_empty?\n    assert(@cls[].empty?)\n    assert(!@cls[1].empty?)\n  end\n\n  def test_eql?\n    assert(@cls[].eql?(@cls[]))\n    assert(@cls[1].eql?(@cls[1]))\n    assert(@cls[1, 1, 2, 2].eql?(@cls[1, 1, 2, 2]))\n    assert(!@cls[1.0, 1.0, 2.0, 2.0].eql?(@cls[1, 1, 2, 2]))\n  end\n\n  def test_fill\n    assert_equal(@cls[],   @cls[].fill(99))\n    assert_equal(@cls[],   @cls[].fill(99, 0))\n    assert_equal(@cls[99], @cls[].fill(99, 0, 1))\n    assert_equal(@cls[99], @cls[].fill(99, 0..0))\n\n    assert_equal(@cls[99],   @cls[1].fill(99))\n    assert_equal(@cls[99],   @cls[1].fill(99, 0))\n    assert_equal(@cls[99],   @cls[1].fill(99, 0, 1))\n    assert_equal(@cls[99],   @cls[1].fill(99, 0..0))\n\n    assert_equal(@cls[99, 99], @cls[1, 2].fill(99))\n    assert_equal(@cls[99, 99], @cls[1, 2].fill(99, 0))\n    assert_equal(@cls[99, 99], @cls[1, 2].fill(99, nil))\n    assert_equal(@cls[1,  99], @cls[1, 2].fill(99, 1, nil))\n    assert_equal(@cls[99,  2], @cls[1, 2].fill(99, 0, 1))\n    assert_equal(@cls[99,  2], @cls[1, 2].fill(99, 0..0))\n  end\n\n  def test_first\n    assert_equal(3,   @cls[3, 4, 5].first)\n    assert_equal(nil, @cls[].first)\n  end\n\n  def test_flatten\n    a1 = @cls[ 1, 2, 3]\n    a2 = @cls[ 5, 6 ]\n    a3 = @cls[ 4, a2 ]\n    a4 = @cls[ a1, a3 ]\n    assert_equal(@cls[1, 2, 3, 4, 5, 6], a4.flatten)\n    assert_equal(@cls[ a1, a3], a4)\n\n    a5 = @cls[ a1, @cls[], a3 ]\n    assert_equal(@cls[1, 2, 3, 4, 5, 6], a5.flatten)\n    assert_equal(@cls[], @cls[].flatten)\n    assert_equal(@cls[], \n                 @cls[@cls[@cls[@cls[],@cls[]],@cls[@cls[]],@cls[]],@cls[@cls[@cls[]]]].flatten)\n\n    assert_raise(TypeError, \"[ruby-dev:31197]\") { [[]].flatten(\"\") }\n  end\n\n  def test_flatten!\n    a1 = @cls[ 1, 2, 3]\n    a2 = @cls[ 5, 6 ]\n    a3 = @cls[ 4, a2 ]\n    a4 = @cls[ a1, a3 ]\n    assert_equal(@cls[1, 2, 3, 4, 5, 6], a4.flatten!)\n    assert_equal(@cls[1, 2, 3, 4, 5, 6], a4)\n\n    a5 = @cls[ a1, @cls[], a3 ]\n    assert_equal(@cls[1, 2, 3, 4, 5, 6], a5.flatten!)\n    assert_equal(@cls[1, 2, 3, 4, 5, 6], a5)\n\n    assert_equal(@cls[], @cls[].flatten)\n    assert_equal(@cls[], \n                 @cls[@cls[@cls[@cls[],@cls[]],@cls[@cls[]],@cls[]],@cls[@cls[@cls[]]]].flatten)\n  end\n\n  def test_flatten_with_callcc\n    respond_to?(:callcc, true) or require 'continuation'\n    o = Object.new\n    def o.to_ary() callcc {|k| @cont = k; [1,2,3]} end\n    begin\n      assert_equal([10, 20, 1, 2, 3, 30, 1, 2, 3, 40], [10, 20, o, 30, o, 40].flatten)\n    rescue => e\n    else\n      o.instance_eval {@cont}.call\n    end\n    assert_instance_of(RuntimeError, e, '[ruby-dev:34798]')\n    assert_match(/reentered/, e.message, '[ruby-dev:34798]')\n  end\n\n  def test_hash\n    a1 = @cls[ 'cat', 'dog' ]\n    a2 = @cls[ 'cat', 'dog' ]\n    a3 = @cls[ 'dog', 'cat' ]\n    assert(a1.hash == a2.hash)\n    assert(a1.hash != a3.hash)\n  end\n\n  def test_include?\n    a = @cls[ 'cat', 99, /a/, @cls[ 1, 2, 3] ]\n    assert(a.include?('cat'))\n    assert(a.include?(99))\n    assert(a.include?(/a/))\n    assert(a.include?([1,2,3]))\n    assert(!a.include?('ca'))\n    assert(!a.include?([1,2]))\n  end\n\n  def test_index\n    a = @cls[ 'cat', 99, /a/, 99, @cls[ 1, 2, 3] ]\n    assert_equal(0, a.index('cat'))\n    assert_equal(1, a.index(99))\n    assert_equal(4, a.index([1,2,3]))\n    assert_nil(a.index('ca'))\n    assert_nil(a.index([1,2]))\n  end\n\n  def test_values_at\n    a = @cls[*('a'..'j').to_a]\n    assert_equal(@cls['a', 'c', 'e'], a.values_at(0, 2, 4))\n    assert_equal(@cls['j', 'h', 'f'], a.values_at(-1, -3, -5))\n    assert_equal(@cls['h', nil, 'a'], a.values_at(-3, 99, 0))\n  end\n\n  def test_join\n    $, = \"\"\n    a = @cls[]\n    assert_equal(\"\", a.join)\n    assert_equal(\"\", a.join(','))\n\n    $, = \"\"\n    a = @cls[1, 2]\n    assert_equal(\"12\", a.join)\n    assert_equal(\"1,2\", a.join(','))\n\n    $, = \"\"\n    a = @cls[1, 2, 3]\n    assert_equal(\"123\", a.join)\n    assert_equal(\"1,2,3\", a.join(','))\n\n    $, = \":\"\n    a = @cls[1, 2, 3]\n    assert_equal(\"1:2:3\", a.join)\n    assert_equal(\"1,2,3\", a.join(','))\n\n    $, = \"\"\n  end\n\n  def test_last\n    assert_equal(nil, @cls[].last)\n    assert_equal(1, @cls[1].last)\n    assert_equal(99, @cls[*(3..99).to_a].last)\n  end\n\n  def test_length\n    assert_equal(0, @cls[].length)\n    assert_equal(1, @cls[1].length)\n    assert_equal(2, @cls[1, nil].length)\n    assert_equal(2, @cls[nil, 1].length)\n    assert_equal(234, @cls[*(0..233).to_a].length)\n  end\n\n  # also update collect!\n  def test_map!\n    a = @cls[ 1, 'cat', 1..1 ]\n    assert_equal(@cls[ Fixnum, String, Range], a.map! {|e| e.class} )\n    assert_equal(@cls[ Fixnum, String, Range], a)\n   \n    a = @cls[ 1, 'cat', 1..1 ]\n    assert_equal(@cls[ 99, 99, 99], a.map! { 99 } )\n    assert_equal(@cls[ 99, 99, 99], a)\n\n    a = @cls[ ]\n    assert_equal(@cls[], a.map! { 99 })\n    assert_equal(@cls[], a)\n  end\n\n  def test_nitems\n    assert_equal(0, @cls[].nitems)\n    assert_equal(1, @cls[1].nitems)\n    assert_equal(1, @cls[1, nil].nitems)\n    assert_equal(1, @cls[nil, 1].nitems)\n    assert_equal(3, @cls[1, nil, nil, 2, nil, 3, nil].nitems)\n  end\n\n  def test_pack\n    a = @cls[*%w( cat wombat x yy)]\n    assert_equal(\"catwomx  yy \", a.pack(\"A3A3A3A3\"))\n    assert_equal(\"cat\", a.pack(\"A*\"))\n    assert_equal(\"cwx  yy \", a.pack(\"A3@1A3@2A3A3\"))\n    assert_equal(\"catwomx\\000\\000yy\\000\", a.pack(\"a3a3a3a3\"))\n    assert_equal(\"cat\", a.pack(\"a*\"))\n    assert_equal(\"ca\", a.pack(\"a2\"))\n    assert_equal(\"cat\\000\\000\", a.pack(\"a5\"))\n\n    assert_equal(\"\\x61\",     @cls[\"01100001\"].pack(\"B8\"))\n    assert_equal(\"\\x61\",     @cls[\"01100001\"].pack(\"B*\"))\n    assert_equal(\"\\x61\",     @cls[\"0110000100110111\"].pack(\"B8\"))\n    assert_equal(\"\\x61\\x37\", @cls[\"0110000100110111\"].pack(\"B16\"))\n    assert_equal(\"\\x61\\x37\", @cls[\"01100001\", \"00110111\"].pack(\"B8B8\"))\n    assert_equal(\"\\x60\",     @cls[\"01100001\"].pack(\"B4\"))\n    assert_equal(\"\\x40\",     @cls[\"01100001\"].pack(\"B2\"))\n\n    assert_equal(\"\\x86\",     @cls[\"01100001\"].pack(\"b8\"))\n    assert_equal(\"\\x86\",     @cls[\"01100001\"].pack(\"b*\"))\n    assert_equal(\"\\x86\",     @cls[\"0110000100110111\"].pack(\"b8\"))\n    assert_equal(\"\\x86\\xec\", @cls[\"0110000100110111\"].pack(\"b16\"))\n    assert_equal(\"\\x86\\xec\", @cls[\"01100001\", \"00110111\"].pack(\"b8b8\"))\n    assert_equal(\"\\x06\",     @cls[\"01100001\"].pack(\"b4\"))\n    assert_equal(\"\\x02\",     @cls[\"01100001\"].pack(\"b2\"))\n\n    assert_equal(\"ABC\",      @cls[ 65, 66, 67 ].pack(\"C3\"))\n    assert_equal(\"\\377BC\",   @cls[ -1, 66, 67 ].pack(\"C*\"))\n    assert_equal(\"ABC\",      @cls[ 65, 66, 67 ].pack(\"c3\"))\n    assert_equal(\"\\377BC\",   @cls[ -1, 66, 67 ].pack(\"c*\"))\n\n    \n    assert_equal(\"AB\\n\\x10\",  @cls[\"4142\", \"0a\", \"12\"].pack(\"H4H2H1\"))\n    assert_equal(\"AB\\n\\x02\",  @cls[\"1424\", \"a0\", \"21\"].pack(\"h4h2h1\"))\n\n    assert_equal(\"abc=02def=\\ncat=\\n=01=\\n\", \n                 @cls[\"abc\\002def\", \"cat\", \"\\001\"].pack(\"M9M3M4\"))\n\n    assert_equal(\"aGVsbG8K\\n\",  @cls[\"hello\\n\"].pack(\"m\"))\n    assert_equal(\",:&5L;&\\\\*:&5L;&\\\\*\\n\",  @cls[\"hello\\nhello\\n\"].pack(\"u\"))\n\n    assert_equal(\"\\xc2\\xa9B\\xe2\\x89\\xa0\", @cls[0xa9, 0x42, 0x2260].pack(\"U*\"))\n\n\n    format = \"c2x5CCxsdils_l_a6\";\n    # Need the expression in here to force ary[5] to be numeric.  This avoids\n    # test2 failing because ary2 goes str->numeric->str and ary does not.\n    ary = [1, -100, 127, 128, 32767, 987.654321098/100.0,\n      12345, 123456, -32767, -123456, \"abcdef\"]\n    x    = ary.pack(format)\n    ary2 = x.unpack(format)\n\n    assert_equal(ary.length, ary2.length)\n    assert_equal(ary.join(':'), ary2.join(':'))\n    assert_not_nil(x =~ /def/)\n\n=begin\n    skipping \"Not tested:\n        D,d & double-precision float, native format\\\\\n        E & double-precision float, little-endian byte order\\\\\n        e & single-precision float, little-endian byte order\\\\\n        F,f & single-precision float, native format\\\\\n        G & double-precision float, network (big-endian) byte order\\\\\n        g & single-precision float, network (big-endian) byte order\\\\\n        I & unsigned integer\\\\\n        i & integer\\\\\n        L & unsigned long\\\\\n        l & long\\\\\n\n        N & long, network (big-endian) byte order\\\\\n        n & short, network (big-endian) byte-order\\\\\n        P & pointer to a structure (fixed-length string)\\\\\n        p & pointer to a null-terminated string\\\\\n        S & unsigned short\\\\\n        s & short\\\\\n        V & long, little-endian byte order\\\\\n        v & short, little-endian byte order\\\\\n        X & back up a byte\\\\\n        x & null byte\\\\\n        Z & ASCII string (null padded, count is width)\\\\\n\"\n=end\n  end\n\n  def test_pop\n    a = @cls[ 'cat', 'dog' ]\n    assert_equal('dog', a.pop)\n    assert_equal(@cls['cat'], a)\n    assert_equal('cat', a.pop)\n    assert_equal(@cls[], a)\n    assert_nil(a.pop)\n    assert_equal(@cls[], a)\n  end\n\n  def test_push\n    a = @cls[1, 2, 3]\n    assert_equal(@cls[1, 2, 3, 4, 5], a.push(4, 5))\n    assert_equal(@cls[1, 2, 3, 4, 5, nil], a.push(nil))\n    # Ruby 1.8 feature:\n    # Array#push accepts any number of arguments.\n    #assert_raise(ArgumentError, \"a.push()\") { a.push() }\n    a.push\n    assert_equal @cls[1, 2, 3, 4, 5, nil], a\n    a.push 6, 7\n    assert_equal @cls[1, 2, 3, 4, 5, nil, 6, 7], a\n  end\n\n  def test_rassoc\n    a1 = @cls[*%w( cat  feline )]\n    a2 = @cls[*%w( dog  canine )]\n    a3 = @cls[*%w( mule asinine )]\n    a  = @cls[ a1, a2, a3 ]\n\n    assert_equal(a1,  a.rassoc('feline'))\n    assert_equal(a3,  a.rassoc('asinine'))\n    assert_equal(nil, a.rassoc('dog'))\n    assert_equal(nil, a.rassoc('mule'))\n    assert_equal(nil, a.rassoc(1..2))\n  end\n\n  # also delete_if\n  def test_reject!\n    a = @cls[ 1, 2, 3, 4, 5 ]\n    assert_equal(nil, a.reject! { false })\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n\n    a = @cls[ 1, 2, 3, 4, 5 ]\n    assert_equal(a, a.reject! { true })\n    assert_equal(@cls[], a)\n\n    a = @cls[ 1, 2, 3, 4, 5 ]\n    assert_equal(a, a.reject! { |i| i > 3 })\n    assert_equal(@cls[1, 2, 3], a)\n  end\n\n  def test_replace\n    a = @cls[ 1, 2, 3]\n    a_id = a.__id__\n    assert_equal(@cls[4, 5, 6], a.replace(@cls[4, 5, 6]))\n    assert_equal(@cls[4, 5, 6], a)\n    assert_equal(a_id, a.__id__)\n    assert_equal(@cls[], a.replace(@cls[]))\n  end\n\n  def test_reverse\n    a = @cls[*%w( dog cat bee ant )]\n    assert_equal(@cls[*%w(ant bee cat dog)], a.reverse)\n    assert_equal(@cls[*%w(dog cat bee ant)], a)\n    assert_equal(@cls[], @cls[].reverse)\n  end\n\n  def test_reverse!\n    a = @cls[*%w( dog cat bee ant )]\n    assert_equal(@cls[*%w(ant bee cat dog)], a.reverse!)\n    assert_equal(@cls[*%w(ant bee cat dog)], a)\n    # Ruby 1.8 feature change:\n    # Array#reverse always returns self.\n    #assert_nil(@cls[].reverse!)\n    assert_equal @cls[], @cls[].reverse!\n  end\n\n  def test_reverse_each\n    a = @cls[*%w( dog cat bee ant )]\n    i = a.length\n    a.reverse_each { |e|\n      i -= 1\n      assert_equal(a[i], e)\n    }\n    assert_equal(0, i)\n\n    a = @cls[]\n    i = 0\n    a.reverse_each { |e|\n      assert(false, \"Never get here\")\n    }\n    assert_equal(0, i)\n  end\n\n  def test_rindex\n    a = @cls[ 'cat', 99, /a/, 99, [ 1, 2, 3] ]\n    assert_equal(0, a.rindex('cat'))\n    assert_equal(3, a.rindex(99))\n    assert_equal(4, a.rindex([1,2,3]))\n    assert_nil(a.rindex('ca'))\n    assert_nil(a.rindex([1,2]))\n  end\n\n  def test_shift\n    a = @cls[ 'cat', 'dog' ]\n    assert_equal('cat', a.shift)\n    assert_equal(@cls['dog'], a)\n    assert_equal('dog', a.shift)\n    assert_equal(@cls[], a)\n    assert_nil(a.shift)\n    assert_equal(@cls[], a)\n  end\n\n  def test_size\n    assert_equal(0,   @cls[].size)\n    assert_equal(1,   @cls[1].size)\n    assert_equal(100, @cls[*(0..99).to_a].size)\n  end\n\n  def test_slice\n    a = @cls[*(1..100).to_a]\n\n    assert_equal(1, a.slice(0))\n    assert_equal(100, a.slice(99))\n    assert_nil(a.slice(100))\n    assert_equal(100, a.slice(-1))\n    assert_equal(99,  a.slice(-2))\n    assert_equal(1,   a.slice(-100))\n    assert_nil(a.slice(-101))\n\n    assert_equal(@cls[1],   a.slice(0,1))\n    assert_equal(@cls[100], a.slice(99,1))\n    assert_equal(@cls[],    a.slice(100,1))\n    assert_equal(@cls[100], a.slice(99,100))\n    assert_equal(@cls[100], a.slice(-1,1))\n    assert_equal(@cls[99],  a.slice(-2,1))\n\n    assert_equal(@cls[10, 11, 12], a.slice(9, 3))\n    assert_equal(@cls[10, 11, 12], a.slice(-91, 3))\n\n    assert_nil(a.slice(-101, 2))\n\n    assert_equal(@cls[1],   a.slice(0..0))\n    assert_equal(@cls[100], a.slice(99..99))\n    assert_equal(@cls[],    a.slice(100..100))\n    assert_equal(@cls[100], a.slice(99..200))\n    assert_equal(@cls[100], a.slice(-1..-1))\n    assert_equal(@cls[99],  a.slice(-2..-2))\n\n    assert_equal(@cls[10, 11, 12], a.slice(9..11))\n    assert_equal(@cls[10, 11, 12], a.slice(-91..-89))\n    \n    assert_nil(a.slice(-101..-1))\n\n    assert_nil(a.slice(10, -3))\n    # Ruby 1.8 feature change:\n    # Array#slice[size..x] always returns [].\n    #assert_nil(a.slice(10..7))\n    assert_equal @cls[], a.slice(10..7)\n  end\n\n  def test_slice!\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(3, a.slice!(2))\n    assert_equal(@cls[1, 2, 4, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(4, a.slice!(-2))\n    assert_equal(@cls[1, 2, 3, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(@cls[3,4], a.slice!(2,2))\n    assert_equal(@cls[1, 2, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(@cls[4,5], a.slice!(-2,2))\n    assert_equal(@cls[1, 2, 3], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(@cls[3,4], a.slice!(2..3))\n    assert_equal(@cls[1, 2, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(nil, a.slice!(20))\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(nil, a.slice!(-6))\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(nil, a.slice!(-6..4))\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n\n    a = @cls[1, 2, 3, 4, 5]\n    assert_equal(nil, a.slice!(-6,2))\n    assert_equal(@cls[1, 2, 3, 4, 5], a)\n  end\n\n  def test_sort\n    a = @cls[ 4, 1, 2, 3 ]\n    assert_equal(@cls[1, 2, 3, 4], a.sort)\n    assert_equal(@cls[4, 1, 2, 3], a)\n\n    assert_equal(@cls[4, 3, 2, 1], a.sort { |x, y| y <=> x} )\n    assert_equal(@cls[4, 1, 2, 3], a)\n\n    a.fill(1)\n    assert_equal(@cls[1, 1, 1, 1], a.sort)\n    \n    assert_equal(@cls[], @cls[].sort)\n  end\n\n  def test_sort!\n    a = @cls[ 4, 1, 2, 3 ]\n    assert_equal(@cls[1, 2, 3, 4], a.sort!)\n    assert_equal(@cls[1, 2, 3, 4], a)\n\n    assert_equal(@cls[4, 3, 2, 1], a.sort! { |x, y| y <=> x} )\n    assert_equal(@cls[4, 3, 2, 1], a)\n\n    a.fill(1)\n    assert_equal(@cls[1, 1, 1, 1], a.sort!)\n\n    assert_equal(@cls[1], @cls[1].sort!)\n    assert_equal(@cls[], @cls[].sort!)\n  end\n\n  def test_to_a\n    a = @cls[ 1, 2, 3 ]\n    a_id = a.__id__\n    assert_equal(a, a.to_a)\n    assert_equal(a_id, a.to_a.__id__)\n  end\n\n  def test_to_ary\n    a = [ 1, 2, 3 ]\n    b = @cls[*a]\n\n    a_id = a.__id__\n    assert_equal(a, b.to_ary)\n    if (@cls == Array)\n      assert_equal(a_id, a.to_ary.__id__)\n    end\n  end\n\n  def test_to_s\n    $, = \"\"\n    a = @cls[]\n    assert_equal(\"\", a.to_s)\n\n    $, = \"\"\n    a = @cls[1, 2]\n    assert_equal(\"12\", a.to_s)\n\n    $, = \"\"\n    a = @cls[1, 2, 3]\n    assert_equal(\"123\", a.to_s)\n\n    $, = \":\"\n    a = @cls[1, 2, 3]\n    assert_equal(\"1:2:3\", a.to_s)\n\n    $, = \"\"\n  end\n\n  def test_uniq\n    a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ]\n    b = a.dup\n    assert_equal(@cls[1, 2, 3, 4, nil], a.uniq)\n    assert_equal(b, a)\n\n    assert_equal(@cls[1, 2, 3], @cls[1, 2, 3].uniq)\n  end\n\n  def test_uniq!\n    a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ]\n    assert_equal(@cls[1, 2, 3, 4, nil], a.uniq!)\n    assert_equal(@cls[1, 2, 3, 4, nil], a)\n\n    assert_nil(@cls[1, 2, 3].uniq!)\n  end\n\n  def test_unshift\n    a = @cls[]\n    assert_equal(@cls['cat'], a.unshift('cat'))\n    assert_equal(@cls['dog', 'cat'], a.unshift('dog'))\n    assert_equal(@cls[nil, 'dog', 'cat'], a.unshift(nil))\n    assert_equal(@cls[@cls[1,2], nil, 'dog', 'cat'], a.unshift(@cls[1, 2]))\n  end\n\n  def test_OR # '|'\n    assert_equal(@cls[],  @cls[]  | @cls[])\n    assert_equal(@cls[1], @cls[1] | @cls[])\n    assert_equal(@cls[1], @cls[]  | @cls[1])\n    assert_equal(@cls[1], @cls[1] | @cls[1])\n\n    assert_equal(@cls[1,2], @cls[1] | @cls[2])\n    assert_equal(@cls[1,2], @cls[1, 1] | @cls[2, 2])\n    assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2])\n  end\n\n def test_combination\n    assert_equal(@cls[[]], @cls[1,2,3,4].combination(0).to_a)\n    assert_equal(@cls[[1],[2],[3],[4]], @cls[1,2,3,4].combination(1).to_a)\n    assert_equal(@cls[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], @cls[1,2,3,4].combination(2).to_a)\n    assert_equal(@cls[[1,2,3],[1,2,4],[1,3,4],[2,3,4]], @cls[1,2,3,4].combination(3).to_a)\n    assert_equal(@cls[[1,2,3,4]], @cls[1,2,3,4].combination(4).to_a)\n    assert_equal(@cls[], @cls[1,2,3,4].combination(5).to_a)\n  end\n\n  def test_product\n    assert_equal(@cls[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]],\n                 @cls[1,2,3].product([4,5]))\n    assert_equal(@cls[[1,1],[1,2],[2,1],[2,2]], @cls[1,2].product([1,2]))\n\n    assert_equal(@cls[[1,3,5],[1,3,6],[1,4,5],[1,4,6],\n                   [2,3,5],[2,3,6],[2,4,5],[2,4,6]], \n                 @cls[1,2].product([3,4],[5,6]))\n    assert_equal(@cls[[1],[2]], @cls[1,2].product)\n    assert_equal(@cls[], @cls[1,2].product([]))\n  end\n\n  def test_permutation\n    a = @cls[1,2,3]\n    assert_equal(@cls[[]], a.permutation(0).to_a)\n    assert_equal(@cls[[1],[2],[3]], a.permutation(1).to_a.sort)\n    assert_equal(@cls[[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]],\n                 a.permutation(2).to_a.sort)\n    assert_equal(@cls[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]],\n                 a.permutation(3).sort.to_a)\n    assert_equal(@cls[], a.permutation(4).to_a)\n    assert_equal(@cls[], a.permutation(-1).to_a)\n    assert_equal(\"abcde\".each_char.to_a.permutation(5).sort,\n                 \"edcba\".each_char.to_a.permutation(5).sort)\n    assert_equal(@cls[].permutation(0).to_a, @cls[[]])\n\n  end\n\n  def test_take\n    assert_equal([1,2,3], [1,2,3,4,5,0].take(3))\n    assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].take(-1) }\n    assert_equal([1,2], [1,2].take(1000000000), '[ruby-dev:34123]')\n  end\n\n  def test_take_while\n    assert_equal([1,2], [1,2,3,4,5,0].take_while {|i| i < 3 })\n  end\n\n  def test_drop\n    assert_equal([4,5,0], [1,2,3,4,5,0].drop(3))\n    assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].drop(-1) }\n    assert_equal([], [1,2].drop(1000000000), '[ruby-dev:34123]')\n  end\n\n  def test_drop_while\n    assert_equal([3,4,5,0], [1,2,3,4,5,0].drop_while {|i| i < 3 })\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_assignment.rb",
    "content": "require 'test/unit'\n\nclass TestAssignment < Test::Unit::TestCase\n  def test_assign\n    a=[]; a[0] ||= \"bar\";\n    assert_equal(\"bar\", a[0])\n    h={}; h[\"foo\"] ||= \"bar\";\n    assert_equal(\"bar\", h[\"foo\"])\n\n    aa = 5\n    aa ||= 25\n    assert_equal(5, aa)\n    bb ||= 25\n    assert_equal(25, bb)\n    cc &&=33\n    assert_nil(cc)\n    cc = 5\n    cc &&=44\n    assert_equal(44, cc)\n\n    a = nil; assert_nil(a)\n    a = 1; assert_equal(1, a)\n    a = []; assert_equal([], a)\n    a = [1]; assert_equal([1], a)\n    a = [nil]; assert_equal([nil], a)\n    a = [[]]; assert_equal([[]], a)\n    a = [1,2]; assert_equal([1,2], a)\n    a = [*[]]; assert_equal([], a)\n    a = [*[1]]; assert_equal([1], a)\n    a = [*[1,2]]; assert_equal([1,2], a)\n\n    a = *nil; assert_nil(a)\n    a = *1; assert_equal(1, a)\n    a = *[]; assert_nil(a)\n    a = *[1]; assert_equal(1, a)\n    a = *[nil]; assert_nil(a)\n    a = *[[]]; assert_equal([], a)\n    a = *[1,2]; assert_equal([1,2], a)\n    a = *[*[]]; assert_nil(a)\n    a = *[*[1]]; assert_equal(1, a)\n    a = *[*[1,2]]; assert_equal([1,2], a)\n\n    *a = nil; assert_equal([nil], a)\n    *a = 1; assert_equal([1], a)\n    *a = []; assert_equal([[]], a)\n    *a = [1]; assert_equal([[1]], a)\n    *a = [nil]; assert_equal([[nil]], a)\n    *a = [[]]; assert_equal([[[]]], a)\n    *a = [1,2]; assert_equal([[1,2]], a)\n    *a = [*[]]; assert_equal([[]], a)\n    *a = [*[1]]; assert_equal([[1]], a)\n    *a = [*[1,2]]; assert_equal([[1,2]], a)\n\n    *a = *nil; assert_equal([nil], a)\n    *a = *1; assert_equal([1], a)\n    *a = *[]; assert_equal([], a)\n    *a = *[1]; assert_equal([1], a)\n    *a = *[nil]; assert_equal([nil], a)\n    *a = *[[]]; assert_equal([[]], a)\n    *a = *[1,2]; assert_equal([1,2], a)\n    *a = *[*[]]; assert_equal([], a)\n    *a = *[*[1]]; assert_equal([1], a)\n    *a = *[*[1,2]]; assert_equal([1,2], a)\n\n    a,b,*c = nil; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = 1; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = []; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = [1]; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = [nil]; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = [[]]; assert_equal([[],nil,[]], [a,b,c])\n    a,b,*c = [1,2]; assert_equal([1,2,[]], [a,b,c])\n    a,b,*c = [*[]]; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = [*[1]]; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = [*[1,2]]; assert_equal([1,2,[]], [a,b,c])\n\n    a,b,*c = *nil; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = *1; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = *[]; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = *[1]; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = *[nil]; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = *[[]]; assert_equal([[],nil,[]], [a,b,c])\n    a,b,*c = *[1,2]; assert_equal([1,2,[]], [a,b,c])\n    a,b,*c = *[*[]]; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = *[*[1]]; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c])\n  end\n\n  def test_yield\n    def f; yield nil; end; f {|a| assert_nil(a)}\n    def f; yield 1; end; f {|a| assert_equal(1, a)}\n    def f; yield []; end; f {|a| assert_equal([], a)}\n    def f; yield [1]; end; f {|a| assert_equal([1], a)}\n    def f; yield [nil]; end; f {|a| assert_equal([nil], a)}\n    def f; yield [[]]; end; f {|a| assert_equal([[]], a)}\n    def f; yield [*[]]; end; f {|a| assert_equal([], a)}\n    def f; yield [*[1]]; end; f {|a| assert_equal([1], a)}\n    def f; yield [*[1,2]]; end; f {|a| assert_equal([1,2], a)}\n\n    def f; yield *nil; end; f {|a| assert_nil(a)}\n    def f; yield *1; end; f {|a| assert_equal(1, a)}\n    def f; yield *[1]; end; f {|a| assert_equal(1, a)}\n    def f; yield *[nil]; end; f {|a| assert_nil(a)}\n    def f; yield *[[]]; end; f {|a| assert_equal([], a)}\n    def f; yield *[*[1]]; end; f {|a| assert_equal(1, a)}\n\n    def f; yield; end; f {|*a| assert_equal([], a)}\n    def f; yield nil; end; f {|*a| assert_equal([nil], a)}\n    def f; yield 1; end; f {|*a| assert_equal([1], a)}\n    def f; yield []; end; f {|*a| assert_equal([[]], a)}\n    def f; yield [1]; end; f {|*a| assert_equal([[1]], a)}\n    def f; yield [nil]; end; f {|*a| assert_equal([[nil]], a)}\n    def f; yield [[]]; end; f {|*a| assert_equal([[[]]], a)}\n    def f; yield [1,2]; end; f {|*a| assert_equal([[1,2]], a)}\n    def f; yield [*[]]; end; f {|*a| assert_equal([[]], a)}\n    def f; yield [*[1]]; end; f {|*a| assert_equal([[1]], a)}\n    def f; yield [*[1,2]]; end; f {|*a| assert_equal([[1,2]], a)}\n\n    def f; yield *nil; end; f {|*a| assert_equal([nil], a)}\n    def f; yield *1; end; f {|*a| assert_equal([1], a)}\n    def f; yield *[]; end; f {|*a| assert_equal([], a)}\n    def f; yield *[1]; end; f {|*a| assert_equal([1], a)}\n    def f; yield *[nil]; end; f {|*a| assert_equal([nil], a)}\n    def f; yield *[[]]; end; f {|*a| assert_equal([[]], a)}\n    def f; yield *[*[]]; end; f {|*a| assert_equal([], a)}\n    def f; yield *[*[1]]; end; f {|*a| assert_equal([1], a)}\n    def f; yield *[*[1,2]]; end; f {|*a| assert_equal([1,2], a)}\n\n    def f; yield; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield nil; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield 1; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}\n    def f; yield []; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield [1]; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}\n    def f; yield [nil]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield [[]]; end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}\n    def f; yield [*[]]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield [*[1]]; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}\n    def f; yield [*[1,2]]; end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}\n\n    def f; yield *nil; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield *1; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}\n    def f; yield *[]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield *[1]; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}\n    def f; yield *[nil]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield *[[]]; end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}\n    def f; yield *[*[]]; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}\n    def f; yield *[*[1]]; end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}\n    def f; yield *[*[1,2]]; end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}\n  end\n\n  def test_return\n    def r; return; end; a = r(); assert_nil(a)\n    def r; return nil; end; a = r(); assert_nil(a)\n    def r; return 1; end; a = r(); assert_equal(1, a)\n    def r; return []; end; a = r(); assert_equal([], a)\n    def r; return [1]; end; a = r(); assert_equal([1], a)\n    def r; return [nil]; end; a = r(); assert_equal([nil], a)\n    def r; return [[]]; end; a = r(); assert_equal([[]], a)\n    def r; return [*[]]; end; a = r(); assert_equal([], a)\n    def r; return [*[1]]; end; a = r(); assert_equal([1], a)\n    def r; return [*[1,2]]; end; a = r(); assert_equal([1,2], a)\n\n    def r; return *nil; end; a = r(); assert_nil(a)\n    def r; return *1; end; a = r(); assert_equal(1, a)\n    def r; return *[]; end; a = r(); assert_nil(a)\n    def r; return *[1]; end; a = r(); assert_equal(1, a)\n    def r; return *[nil]; end; a = r(); assert_nil(a)\n    def r; return *[[]]; end; a = r(); assert_equal([], a)\n    def r; return *[*[]]; end; a = r(); assert_nil(a)\n    def r; return *[*[1]]; end; a = r(); assert_equal(1, a)\n    def r; return *[*[1,2]]; end; a = r(); assert_equal([1,2], a)\n\n    def r; return *nil; end; a = *r(); assert_nil(a)\n    def r; return *1; end; a = *r(); assert_equal(1, a)\n    def r; return *[]; end; a = *r(); assert_nil(a)\n    def r; return *[1]; end; a = *r(); assert_equal(1, a)\n    def r; return *[nil]; end; a = *r(); assert_nil(a)\n    def r; return *[[]]; end; a = *r(); assert_nil(a)\n    def r; return *[*[]]; end; a = *r(); assert_nil(a)\n    def r; return *[*[1]]; end; a = *r(); assert_equal(1, a)\n    def r; return *[*[1,2]]; end; a = *r(); assert_equal([1,2], a)\n\n    def r; return; end; *a = r(); assert_equal([nil], a)\n    def r; return nil; end; *a = r(); assert_equal([nil], a)\n    def r; return 1; end; *a = r(); assert_equal([1], a)\n    def r; return []; end; *a = r(); assert_equal([[]], a)\n    def r; return [1]; end; *a = r(); assert_equal([[1]], a)\n    def r; return [nil]; end; *a = r(); assert_equal([[nil]], a)\n    def r; return [[]]; end; *a = r(); assert_equal([[[]]], a)\n    def r; return [1,2]; end; *a = r(); assert_equal([[1,2]], a)\n    def r; return [*[]]; end; *a = r(); assert_equal([[]], a)\n    def r; return [*[1]]; end; *a = r(); assert_equal([[1]], a)\n    def r; return [*[1,2]]; end; *a = r(); assert_equal([[1,2]], a)\n\n    def r; return *nil; end; *a = r(); assert_equal([nil], a)\n    def r; return *1; end; *a = r(); assert_equal([1], a)\n    def r; return *[]; end; *a = r(); assert_equal([nil], a)\n    def r; return *[1]; end; *a = r(); assert_equal([1], a)\n    def r; return *[nil]; end; *a = r(); assert_equal([nil], a)\n    def r; return *[[]]; end; *a = r(); assert_equal([[]], a)\n    def r; return *[1,2]; end; *a = r(); assert_equal([[1,2]], a)\n    def r; return *[*[]]; end; *a = r(); assert_equal([nil], a)\n    def r; return *[*[1]]; end; *a = r(); assert_equal([1], a)\n    def r; return *[*[1,2]]; end; *a = r(); assert_equal([[1,2]], a)\n\n    def r; return *nil; end; *a = *r(); assert_equal([nil], a)\n    def r; return *1; end; *a = *r(); assert_equal([1], a)\n    def r; return *[]; end; *a = *r(); assert_equal([nil], a)\n    def r; return *[1]; end; *a = *r(); assert_equal([1], a)\n    def r; return *[nil]; end; *a = *r(); assert_equal([nil], a)\n    def r; return *[[]]; end; *a = *r(); assert_equal([], a)\n    def r; return *[1,2]; end; *a = *r(); assert_equal([1,2], a)\n    def r; return *[*[]]; end; *a = *r(); assert_equal([nil], a)\n    def r; return *[*[1]]; end; *a = *r(); assert_equal([1], a)\n    def r; return *[*[1,2]]; end; *a = *r(); assert_equal([1,2], a)\n\n    def r; return; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return nil; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return 1; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c])\n    def r; return []; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return [1]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c])\n    def r; return [nil]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return [[]]; end; a,b,*c = r(); assert_equal([[],nil,[]], [a,b,c])\n    def r; return [1,2]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c])\n    def r; return [*[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return [*[1]]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c])\n    def r; return [*[1,2]]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c])\n\n    def r; return *nil; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return *1; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c])\n    def r; return *[]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return *[1]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c])\n    def r; return *[nil]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return *[[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return *[1,2]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c])\n    def r; return *[*[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c])\n    def r; return *[*[1]]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c])\n    def r; return *[*[1,2]]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c])\n  end\n\n  def test_lambda\n    f = lambda {|r,| assert_equal([], r)}\n    f.call([], *[])\n\n    f = lambda {|r,*l| assert_equal([], r); assert_equal([1], l)}\n    f.call([], *[1])\n\n    f = lambda{|x| x}\n    assert_equal(42, f.call(42))\n    assert_equal([42], f.call([42]))\n    assert_equal([[42]], f.call([[42]]))\n    assert_equal([42,55], f.call([42,55]))\n\n    f = lambda{|x,| x}\n    assert_equal(42, f.call(42))\n    assert_equal([42], f.call([42]))\n    assert_equal([[42]], f.call([[42]]))\n    assert_equal([42,55], f.call([42,55]))\n\n    f = lambda{|*x| x}\n    assert_equal([42], f.call(42))\n    assert_equal([[42]], f.call([42]))\n    assert_equal([[[42]]], f.call([[42]]))\n    assert_equal([[42,55]], f.call([42,55]))\n    assert_equal([42,55], f.call(42,55))\n  end\n\n  def test_multi\n    a,=*[1]\n    assert_equal(1, a)\n    a,=*[[1]]\n    assert_equal([1], a)\n    a,=*[[[1]]]\n    assert_equal([[1]], a)\n\n    x, (y, z) = 1, 2, 3\n    assert_equal([1,2,nil], [x,y,z])\n    x, (y, z) = 1, [2,3]\n    assert_equal([1,2,3], [x,y,z])\n    x, (y, z) = 1, [2]\n    assert_equal([1,2,nil], [x,y,z])\n  end\n\n  def test_break\n    a = loop do break; end; assert_nil(a)\n    a = loop do break nil; end; assert_nil(a)\n    a = loop do break 1; end; assert_equal(1, a)\n    a = loop do break []; end; assert_equal([], a)\n    a = loop do break [1]; end; assert_equal([1], a)\n    a = loop do break [nil]; end; assert_equal([nil], a)\n    a = loop do break [[]]; end; assert_equal([[]], a)\n    a = loop do break [*[]]; end; assert_equal([], a)\n    a = loop do break [*[1]]; end; assert_equal([1], a)\n    a = loop do break [*[1,2]]; end; assert_equal([1,2], a)\n\n    a = loop do break *nil; end; assert_nil(a)\n    a = loop do break *1; end; assert_equal(1, a)\n    a = loop do break *[]; end; assert_nil(a)\n    a = loop do break *[1]; end; assert_equal(1, a)\n    a = loop do break *[nil]; end; assert_nil(a)\n    a = loop do break *[[]]; end; assert_equal([], a)\n    a = loop do break *[*[]]; end; assert_nil(a)\n    a = loop do break *[*[1]]; end; assert_equal(1, a)\n    a = loop do break *[*[1,2]]; end; assert_equal([1,2], a)\n\n    *a = loop do break; end; assert_equal([nil], a)\n    *a = loop do break nil; end; assert_equal([nil], a)\n    *a = loop do break 1; end; assert_equal([1], a)\n    *a = loop do break []; end; assert_equal([[]], a)\n    *a = loop do break [1]; end; assert_equal([[1]], a)\n    *a = loop do break [nil]; end; assert_equal([[nil]], a)\n    *a = loop do break [[]]; end; assert_equal([[[]]], a)\n    *a = loop do break [1,2]; end; assert_equal([[1,2]], a)\n    *a = loop do break [*[]]; end; assert_equal([[]], a)\n    *a = loop do break [*[1]]; end; assert_equal([[1]], a)\n    *a = loop do break [*[1,2]]; end; assert_equal([[1,2]], a)\n\n    *a = loop do break *nil; end; assert_equal([nil], a)\n    *a = loop do break *1; end; assert_equal([1], a)\n    *a = loop do break *[]; end; assert_equal([nil], a)\n    *a = loop do break *[1]; end; assert_equal([1], a)\n    *a = loop do break *[nil]; end; assert_equal([nil], a)\n    *a = loop do break *[[]]; end; assert_equal([[]], a)\n    *a = loop do break *[1,2]; end; assert_equal([[1,2]], a)\n    *a = loop do break *[*[]]; end; assert_equal([nil], a)\n    *a = loop do break *[*[1]]; end; assert_equal([1], a)\n    *a = loop do break *[*[1,2]]; end; assert_equal([[1,2]], a)\n\n    *a = *loop do break *nil; end; assert_equal([nil], a)\n    *a = *loop do break *1; end; assert_equal([1], a)\n    *a = *loop do break *[]; end; assert_equal([nil], a)\n    *a = *loop do break *[1]; end; assert_equal([1], a)\n    *a = *loop do break *[nil]; end; assert_equal([nil], a)\n    *a = *loop do break *[[]]; end; assert_equal([], a)\n    *a = *loop do break *[1,2]; end; assert_equal([1,2], a)\n    *a = *loop do break *[*[]]; end; assert_equal([nil], a)\n    *a = *loop do break *[*[1]]; end; assert_equal([1], a)\n    *a = *loop do break *[*[1,2]]; end; assert_equal([1,2], a)\n\n    a,b,*c = loop do break; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break nil; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break 1; end; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = loop do break []; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break [1]; end; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = loop do break [nil]; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break [[]]; end; assert_equal([[],nil,[]], [a,b,c])\n    a,b,*c = loop do break [1,2]; end; assert_equal([1,2,[]], [a,b,c])\n    a,b,*c = loop do break [*[]]; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break [*[1]]; end; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = loop do break [*[1,2]]; end; assert_equal([1,2,[]], [a,b,c])\n\n    a,b,*c = loop do break *nil; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break *1; end; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[]; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[1]; end; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[nil]; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[[]]; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[1,2]; end; assert_equal([1,2,[]], [a,b,c])\n    a,b,*c = loop do break *[*[]]; end; assert_equal([nil,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[*[1]]; end; assert_equal([1,nil,[]], [a,b,c])\n    a,b,*c = loop do break *[*[1,2]]; end; assert_equal([1,2,[]], [a,b,c])\n  end\n\n  def test_next\n    def r(val); a = yield(); assert_equal(val, a); end\n    r(nil){next}\n    r(nil){next nil}\n    r(1){next 1}\n    r([]){next []}\n    r([1]){next [1]}\n    r([nil]){next [nil]}\n    r([[]]){next [[]]}\n    r([]){next [*[]]}\n    r([1]){next [*[1]]}\n    r([1,2]){next [*[1,2]]}\n\n    r(nil){next *nil}\n    r(1){next *1}\n    r(nil){next *[]}\n    r(1){next *[1]}\n    r(nil){next *[nil]}\n    r([]){next *[[]]}\n    r(nil){next *[*[]]}\n    r(1){next *[*[1]]}\n    r([1,2]){next *[*[1,2]]}\n\n    def r(val); *a = yield(); assert_equal(val, a); end\n    r([nil]){next}\n    r([nil]){next nil}\n    r([1]){next 1}\n    r([[]]){next []}\n    r([[1]]){next [1]}\n    r([[nil]]){next [nil]}\n    r([[[]]]){next [[]]}\n    r([[1,2]]){next [1,2]}\n    r([[]]){next [*[]]}\n    r([[1]]){next [*[1]]}\n    r([[1,2]]){next [*[1,2]]}\n\n    def r(val); *a = *yield(); assert_equal(val, a); end\n    r([nil]){next *nil}\n    r([1]){next *1}\n    r([nil]){next *[]}\n    r([1]){next *[1]}\n    r([nil]){next *[nil]}\n    r([]){next *[[]]}\n    r([1,2]){next *[1,2]}\n    r([nil]){next *[*[]]}\n    r([1]){next *[*[1]]}\n    r([1,2]){next *[*[1,2]]}\n\n    def r(val); a,b,*c = yield(); assert_equal(val, [a,b,c]); end\n    r([nil,nil,[]]){next}\n    r([nil,nil,[]]){next nil}\n    r([1,nil,[]]){next 1}\n    r([nil,nil,[]]){next []}\n    r([1,nil,[]]){next [1]}\n    r([nil,nil,[]]){next [nil]}\n    r([[],nil,[]]){next [[]]}\n    r([1,2,[]]){next [1,2]}\n    r([nil,nil,[]]){next [*[]]}\n    r([1,nil,[]]){next [*[1]]}\n    r([1,2,[]]){next [*[1,2]]}\n\n    def r(val); a,b,*c = *yield(); assert_equal(val, [a,b,c]); end\n    r([nil,nil,[]]){next *nil}\n    r([1,nil,[]]){next *1}\n    r([nil,nil,[]]){next *[]}\n    r([1,nil,[]]){next *[1]}\n    r([nil,nil,[]]){next *[nil]}\n    r([nil,nil,[]]){next *[[]]}\n    r([1,2,[]]){next *[1,2]}\n    r([nil,nil,[]]){next *[*[]]}\n    r([1,nil,[]]){next *[*[1]]}\n    r([1,2,[]]){next *[*[1,2]]}\n  end\n\n  def test_assign2\n    a = nil\n    assert(defined?(a))\n    assert_nil(a)\n\n    # multiple asignment\n    a, b = 1, 2\n    assert(a == 1 && b == 2)\n\n    a, b = b, a\n    assert(a == 2 && b == 1)\n\n    a, = 1,2\n    assert_equal(1, a)\n\n    a, *b = 1, 2, 3\n    assert(a == 1 && b == [2, 3])\n\n    a, (b, c), d = 1, [2, 3], 4\n    assert(a == 1 && b == 2 && c == 3 && d == 4)\n\n    *a = 1, 2, 3\n    assert_equal([1, 2, 3], a)\n\n    *a = 4\n    assert_equal([4], a)\n\n    *a = nil\n    assert_equal([nil], a)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_beginendblock.rb",
    "content": "require 'test/unit'\nrequire 'tempfile'\n$:.replace([File.dirname(File.expand_path(__FILE__))] | $:)\nrequire 'envutil'\n\nclass TestBeginEndBlock < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  def q(content)\n    \"\\\"#{content}\\\"\"\n  end\n\n  def test_beginendblock\n    ruby = EnvUtil.rubybin\n    target = File.join(DIR, 'beginmainend.rb')\n    result = IO.popen(\"#{q(ruby)} #{q(target)}\"){|io|io.read}\n    assert_equal(%w(b1 b2-1 b2 main b3-1 b3 b4 e1 e4 e3 e2 e4-2 e4-1 e1-1 e4-1-1), result.split)\n  end\n\n  def test_begininmethod\n    assert_raises(SyntaxError) do\n      eval(\"def foo; BEGIN {}; end\")\n    end\n\n    assert_raises(SyntaxError) do\n      eval('eval(\"def foo; BEGIN {}; end\")')\n    end\n  end\n\n  def test_endblockwarn\n    ruby = EnvUtil.rubybin\n    # Use Tempfile to create temporary file path.\n    launcher = Tempfile.new(self.class.name)\n    errout = Tempfile.new(self.class.name)\n\n    launcher << <<EOF\nerrout = ARGV.shift\nSTDERR.reopen(File.open(errout, \"w\"))\nSTDERR.sync = true\nDir.chdir(#{q(DIR)})\ncmd = \"\\\\\"#{ruby}\\\\\" \\\\\"endblockwarn.rb\\\\\"\"\nsystem(cmd)\nEOF\n    launcher.close\n    launcherpath = launcher.path\n    errout.close\n    erroutpath = errout.path\n    system(\"#{q(ruby)} #{q(launcherpath)} #{q(erroutpath)}\")\n    expected = <<EOW\nendblockwarn.rb:2: warning: END in method; use at_exit\n(eval):2: warning: END in method; use at_exit\nEOW\n    assert_equal(expected, File.read(erroutpath))\n    # expecting Tempfile to unlink launcher and errout file.\n  end\n\n  def test_raise_in_at_exit\n    # [ruby-core:09675]\n    ruby = EnvUtil.rubybin\n    out = IO.popen(\"#{q(ruby)} -e 'STDERR.reopen(STDOUT);\" \\\n\t\t   \"at_exit{raise %[SomethingBad]};\" \\\n\t\t   \"raise %[SomethingElse]'\") {|f|\n      f.read\n    }\n    assert_match /SomethingBad/, out\n    assert_match /SomethingElse/, out\n  end\n\n  def test_should_propagate_exit_code\n    ruby = EnvUtil.rubybin\n    assert_equal false, system(ruby, '-e', 'at_exit{exit 2}')\n    assert_equal 2, $?.exitstatus\n    assert_nil $?.termsig\n  end\n\n  def test_should_propagate_signaled\n    ruby = EnvUtil.rubybin\n    out = IO.popen(\"#{ruby} #{File.dirname(__FILE__)}/suicide.rb\"){|f|\n      f.read\n    }\n    assert_match /Interrupt$/, out\n    Process.kill(0, 0) rescue return # check if signal works\n    assert_nil $?.exitstatus\n    assert_equal Signal.list[\"INT\"], $?.termsig\n  end\n\n  def test_begin_and_eval\n    $test_begin_and_eval = :ok\n    begin\n      eval(\"BEGIN{$test_begin_and_eval = :ng}\\n_/a:a\")\n    rescue SyntaxError\n      x1 = x2 = $test_begin_and_eval\n      eval(\"x2 = $test_begin_and_eval\")\n    end\n    assert_equal(:ok, x1)\n    assert_equal(:ok, x2)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_bignum.rb",
    "content": "require 'test/unit'\n\nclass TestBignum < Test::Unit::TestCase\n  def fact(n)\n    return 1 if n == 0\n    f = 1\n    while n>0\n      f *= n\n      n -= 1\n    end\n    return f\n  end\n\n  def test_bignum\n    $x = fact(40)\n    assert_equal($x, $x)\n    assert_equal($x, fact(40))\n    assert($x < $x+2)\n    assert($x > $x-2)\n    assert_equal(815915283247897734345611269596115894272000000000, $x)\n    assert_not_equal(815915283247897734345611269596115894272000000001, $x)\n    assert_equal(815915283247897734345611269596115894272000000001, $x+1)\n    assert_equal(335367096786357081410764800000, $x/fact(20))\n    $x = -$x\n    assert_equal(-815915283247897734345611269596115894272000000000, $x)\n    assert_equal(2-(2**32), -(2**32-2))\n    assert_equal(2**32 - 5, (2**32-3)-2)\n\n    for i in 1000..1014\n      assert_equal(2 ** i, 1 << i)\n    end\n\n    n1 = 1 << 1000\n    for i in 1000..1014\n      assert_equal(n1, 1 << i)\n      n1 *= 2\n    end\n\n    n2=n1\n    for i in 1..10\n      n1 = n1 / 2\n      n2 = n2 >> 1\n      assert_equal(n1, n2)\n    end\n\n    for i in 4000..4096\n      n1 = 1 << i;\n      assert_equal(n1-1, (n1**2-1) / (n1+1))\n    end\n  end\n\n  def test_calc\n    b = 10**80\n    a = b * 9 + 7\n    assert_equal(7, a.modulo(b))\n    assert_equal(-b + 7, a.modulo(-b))\n    assert_equal(b + -7, (-a).modulo(b))\n    assert_equal(-7, (-a).modulo(-b))\n    assert_equal(7, a.remainder(b))\n    assert_equal(7, a.remainder(-b))\n    assert_equal(-7, (-a).remainder(b))\n    assert_equal(-7, (-a).remainder(-b))\n\n    assert_equal(10000000000000000000100000000000000000000, 10**40+10**20)\n    assert_equal(100000000000000000000, 10**40/10**20)\n\n    a = 677330545177305025495135714080\n    b = 14269972710765292560\n    assert_equal(0, a % b)\n    assert_equal(0, -a % b)\n  end\n\n  def shift_test(a)\n    b = a / (2 ** 32)\n    c = a >> 32\n    assert_equal(b, c)\n\n    b = a * (2 ** 32)\n    c = a << 32\n    assert_equal(b, c)\n  end\n\n  def test_shift\n    shift_test(-4518325415524767873)\n    shift_test(-0xfffffffffffffffff)\n  end\n\n  def test_to_s  # [ruby-core:10686]\n    assert_equal(\"fvvvvvvvvvvvv\" ,18446744073709551615.to_s(32))\n    assert_equal(\"g000000000000\" ,18446744073709551616.to_s(32))\n    assert_equal(\"3w5e11264sgsf\" ,18446744073709551615.to_s(36))\n    assert_equal(\"3w5e11264sgsg\" ,18446744073709551616.to_s(36))\n    assert_equal(\"nd075ib45k86f\" ,18446744073709551615.to_s(31))\n    assert_equal(\"nd075ib45k86g\" ,18446744073709551616.to_s(31))\n    assert_equal(\"1777777777777777777777\" ,18446744073709551615.to_s(8))\n    assert_equal(\"-1777777777777777777777\" ,-18446744073709551615.to_s(8))\n  end\n\n  def test_too_big_to_s\n    if (big = 2**31-1).is_a?(Fixnum)\n      return\n    end\n    e = assert_raise(RangeError) {(1 << big).to_s}\n    assert_match(/too big to convert/, e.message)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_call.rb",
    "content": "require 'test/unit'\n\nclass TestCall < Test::Unit::TestCase\n  def aaa(a, b=100, *rest)\n    res = [a, b]\n    res += rest if rest\n    return res\n  end\n\n  def test_call\n    assert_raises(ArgumentError) {aaa()}\n    assert_raises(ArgumentError) {aaa}\n\n    assert_equal([1, 100], aaa(1))\n    assert_equal([1, 2], aaa(1, 2))\n    assert_equal([1, 2, 3, 4], aaa(1, 2, 3, 4))\n    assert_equal([1, 2, 3, 4], aaa(1, *[2, 3, 4]))\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_case.rb",
    "content": "require 'test/unit'\n\nclass TestCase < Test::Unit::TestCase\n  def test_case\n    case 5\n    when 1, 2, 3, 4, 6, 7, 8\n      assert(false)\n    when 5\n      assert(true)\n    end\n\n    case 5\n    when 5\n      assert(true)\n    when 1..10\n      assert(false)\n    end\n\n    case 5\n    when 1..10\n      assert(true)\n    else\n      assert(false)\n    end\n\n    case 5\n    when 5\n      assert(true)\n    else\n      assert(false)\n    end\n\n    case \"foobar\"\n    when /^f.*r$/\n      assert(true)\n    else\n      assert(false)\n    end\n\n    case\n    when true\n      assert(true)\n    when false, nil\n      assert(false)\n    else\n      assert(false)\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_clone.rb",
    "content": "require 'test/unit'\n\nclass TestClone < Test::Unit::TestCase\n  module M001; end\n  module M002; end\n  module M003; include M002; end\n  module M002; include M001; end\n  module M003; include M002; end\n\n  def test_clone\n    foo = Object.new\n    def foo.test\n      \"test\"\n    end\n    bar = foo.clone\n    def bar.test2\n      \"test2\"\n    end\n\n    assert_equal(\"test2\", bar.test2)\n    assert_equal(\"test\", bar.test)\n    assert_equal(\"test\", foo.test)\n\n    assert_raises(NoMethodError) {foo.test2}\n\n    assert_equal([M003, M002, M001], M003.ancestors)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_condition.rb",
    "content": "require 'test/unit'\n\nclass TestCondition < Test::Unit::TestCase\n\n  # [should] first test to see if we can run the tests.\n\n  def test_condition\n    $x = '0';\n\n    $x == $x && assert(true)\n    $x != $x && assert(false)\n    $x == $x || assert(false)\n    $x != $x || assert(true)\n\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_const.rb",
    "content": "require 'test/unit'\n\nclass TestConst < Test::Unit::TestCase\n  TEST1 = 1\n  TEST2 = 2\n\n  module Const\n    TEST3 = 3\n    TEST4 = 4\n  end\n\n  module Const2\n    TEST3 = 6\n    TEST4 = 8\n  end\n\n  def test_const\n    self.class.class_eval {\n      include Const\n    }\n    assert_equal([1,2,3,4], [TEST1,TEST2,TEST3,TEST4])\n\n    self.class.class_eval {\n      include Const2\n    }\n    STDERR.print \"intentionally redefines TEST3, TEST4\\n\" if $VERBOSE\n    assert_equal([1,2,6,8], [TEST1,TEST2,TEST3,TEST4])\n\n    assert_equal(-1, (String <=> Object))\n    assert_equal(1, (Object <=> String))\n    assert_equal(nil, (Array <=> String))\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_defined.rb",
    "content": "require 'test/unit'\n\nclass TestDefined < Test::Unit::TestCase\n  class Foo\n    def foo\n      p :foo\n    end\n    protected :foo\n    def bar(f)\n      yield(defined?(self.foo))\n      yield(defined?(f.foo))\n    end\n  end\n\n  def defined_test\n    return !defined?(yield)\n  end\n\n  def test_defined\n    $x = nil\n\n    assert(defined?($x))\t\t# global variable\n    assert_equal('global-variable', defined?($x))# returns description\n\n    assert_nil(defined?(foo))\t\t# undefined\n    foo=5\n    assert(defined?(foo))\t\t# local variable\n\n    assert(defined?(Array))\t\t# constant\n    assert(defined?(::Array))\t\t# toplevel constant\n    assert(defined?(File::Constants))\t# nested constant\n    assert(defined?(Object.new))\t# method\n    assert(!defined?(Object.print))\t# private method\n    assert(defined?(1 == 2))\t\t# operator expression\n\n    f = Foo.new\n    assert_nil(defined?(f.foo))\n    f.bar(f) { |v| assert(v) }\n\n    assert(defined_test)\t\t# not iterator\n    assert(!defined_test{})\t# called as iterator\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_dir.rb",
    "content": "require 'test/unit'\n\nrequire 'tmpdir'\nrequire 'fileutils'\n\nclass TestDir < Test::Unit::TestCase\n\n  ROOT = File.join(Dir.tmpdir, \"__test_dir__#{$$}\")\n\n  def setup\n    Dir.mkdir(ROOT)\n    for i in ?a..?z\n      if i % 2 == 0\n        FileUtils.touch(File.join(ROOT, i.chr))\n      else\n        FileUtils.mkdir(File.join(ROOT, i.chr))\n      end\n    end\n  end\n\n  def teardown\n    FileUtils.rm_rf ROOT if File.directory?(ROOT)\n  end\n\n  def test_seek\n    dir = Dir.open(ROOT)\n    begin\n      cache = []\n      loop do\n        pos = dir.tell\n        break unless name = dir.read\n        cache << [pos, name]\n      end\n      for x in cache.sort_by {|x| x[0] % 3 } # shuffle\n        dir.seek(x[0])\n        assert_equal(x[1], dir.read)\n      end\n    ensure\n      dir.close\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_enum.rb",
    "content": "require 'test/unit'\n\nclass TestEnumerable < Test::Unit::TestCase\n  def setup\n    @obj = Object.new\n    class << @obj\n      include Enumerable\n      def each\n        yield 1\n        yield 2\n        yield 3\n        yield 1\n        yield 2\n      end\n    end\n    @verbose = $VERBOSE\n    $VERBOSE = nil\n  end\n\n  def teardown\n    $VERBOSE = @verbose\n  end\n\n  def test_grep\n    assert_equal([1, 2, 1, 2], @obj.grep(1..2))\n    a = []\n    @obj.grep(2) {|x| a << x }\n    assert_equal([2, 2], a)\n  end\n\n  def test_count\n    assert_equal(5, @obj.count)\n    assert_equal(2, @obj.count(1))\n    assert_equal(3, @obj.count {|x| x % 2 == 1 })\n    assert_equal(2, @obj.count(1) {|x| x % 2 == 1 })\n    assert_raise(ArgumentError) { @obj.count(0, 1) }\n  end\n\n  def test_find\n    assert_equal(2, @obj.find {|x| x % 2 == 0 })\n    assert_equal(nil, @obj.find {|x| false })\n    assert_equal(:foo, @obj.find(proc { :foo }) {|x| false })\n  end\n\n  def test_find_index\n    assert_equal(1, @obj.find_index(2))\n    assert_equal(1, @obj.find_index {|x| x % 2 == 0 })\n    assert_equal(nil, @obj.find_index {|x| false })\n    assert_raise(ArgumentError) { @obj.find_index(0, 1) }\n  end\n\n  def test_find_all\n    assert_equal([1, 3, 1], @obj.find_all {|x| x % 2 == 1 })\n  end\n\n  def test_reject\n    assert_equal([2, 3, 2], @obj.reject {|x| x < 2 })\n  end\n\n  def test_to_a\n    assert_equal([1, 2, 3, 1, 2], @obj.to_a)\n  end\n\n  def test_inject\n    assert_equal(12, @obj.inject {|z, x| z * x })\n    assert_equal(48, @obj.inject {|z, x| z * 2 + x })\n    assert_equal(12, @obj.inject(:*))\n    assert_equal(24, @obj.inject(2) {|z, x| z * x })\n    assert_equal(24, @obj.inject(2, :*) {|z, x| z * x })\n  end\n\n  def test_partition\n    assert_equal([[1, 3, 1], [2, 2]], @obj.partition {|x| x % 2 == 1 })\n  end\n\n  def test_group_by\n    h = { 1 => [1, 1], 2 => [2, 2], 3 => [3] }\n    assert_equal(h, @obj.group_by {|x| x })\n  end\n\n  def test_first\n    assert_equal(1, @obj.first)\n    assert_equal([1, 2, 3], @obj.first(3))\n  end\n\n  def test_sort\n    assert_equal([1, 1, 2, 2, 3], @obj.sort)\n  end\n\n  def test_sort_by\n    assert_equal([3, 2, 2, 1, 1], @obj.sort_by {|x| -x })\n  end\n\n  def test_all\n    assert_equal(true, @obj.all? {|x| x <= 3 })\n    assert_equal(false, @obj.all? {|x| x < 3 })\n    assert_equal(true, @obj.all?)\n    assert_equal(false, [true, true, false].all?)\n  end\n\n  def test_any\n    assert_equal(true, @obj.any? {|x| x >= 3 })\n    assert_equal(false, @obj.any? {|x| x > 3 })\n    assert_equal(true, @obj.any?)\n    assert_equal(false, [false, false, false].any?)\n  end\n\n  def test_one\n    assert(@obj.one? {|x| x == 3 })\n    assert(!(@obj.one? {|x| x == 1 }))\n    assert(!(@obj.one? {|x| x == 4 }))\n    assert(%w{ant bear cat}.one? {|word| word.length == 4})\n    assert(!(%w{ant bear cat}.one? {|word| word.length > 4}))\n    assert(!(%w{ant bear cat}.one? {|word| word.length < 4}))\n    assert(!([ nil, true, 99 ].one?))\n    assert([ nil, true, false ].one?)\n  end\n\n  def test_none\n    assert(@obj.none? {|x| x == 4 })\n    assert(!(@obj.none? {|x| x == 1 }))\n    assert(!(@obj.none? {|x| x == 3 }))\n    assert(%w{ant bear cat}.none? {|word| word.length == 5})\n    assert(!(%w{ant bear cat}.none? {|word| word.length >= 4}))\n    assert([].none?)\n    assert([nil].none?)\n    assert([nil,false].none?)\n  end\n\n  def test_min\n    assert_equal(1, @obj.min)\n    assert_equal(3, @obj.min {|a,b| b <=> a })\n    a = %w(albatross dog horse)\n    assert_equal(\"albatross\", a.min)\n    assert_equal(\"dog\", a.min {|a,b| a.length <=> b.length })\n    assert_equal(1, [3,2,1].min)\n  end\n\n  def test_max\n    assert_equal(3, @obj.max)\n    assert_equal(1, @obj.max {|a,b| b <=> a })\n    a = %w(albatross dog horse)\n    assert_equal(\"horse\", a.max)\n    assert_equal(\"albatross\", a.max {|a,b| a.length <=> b.length })\n    assert_equal(1, [3,2,1].max{|a,b| b <=> a })\n  end\n\n  def test_minmax\n    assert_equal([1, 3], @obj.minmax)\n    assert_equal([3, 1], @obj.minmax {|a,b| b <=> a })\n    a = %w(albatross dog horse)\n    assert_equal([\"albatross\", \"horse\"], a.minmax)\n    assert_equal([\"dog\", \"albatross\"], a.minmax {|a,b| a.length <=> b.length })\n    assert_equal([1, 3], [2,3,1].minmax)\n    assert_equal([3, 1], [2,3,1].minmax {|a,b| b <=> a })\n  end\n\n  def test_min_by\n    assert_equal(3, @obj.min_by {|x| -x })\n    a = %w(albatross dog horse)\n    assert_equal(\"dog\", a.min_by {|x| x.length })\n    assert_equal(3, [2,3,1].min_by {|x| -x })\n  end\n\n  def test_max_by\n    assert_equal(1, @obj.max_by {|x| -x })\n    a = %w(albatross dog horse)\n    assert_equal(\"albatross\", a.max_by {|x| x.length })\n    assert_equal(1, [2,3,1].max_by {|x| -x })\n  end\n\n  def test_minmax_by\n    assert_equal([3, 1], @obj.minmax_by {|x| -x })\n    a = %w(albatross dog horse)\n    assert_equal([\"dog\", \"albatross\"], a.minmax_by {|x| x.length })\n    assert_equal([3, 1], [2,3,1].minmax_by {|x| -x })\n  end\n\n  def test_member\n    assert(@obj.member?(1))\n    assert(!(@obj.member?(4)))\n    assert([1,2,3].member?(1))\n    assert(!([1,2,3].member?(4)))\n  end\n\n  def test_each_with_index\n    a = []\n    @obj.each_with_index {|x, i| a << [x, i] }\n    assert_equal([[1,0],[2,1],[3,2],[1,3],[2,4]], a)\n\n    hash = Hash.new\n    %w(cat dog wombat).each_with_index do |item, index|\n      hash[item] = index\n    end\n    assert_equal({\"cat\"=>0, \"wombat\"=>2, \"dog\"=>1}, hash)\n  end\n\n  def test_zip\n    assert_equal([[1,1],[2,2],[3,3],[1,1],[2,2]], @obj.zip(@obj))\n    a = []\n    @obj.zip([:a, :b, :c]) {|x,y| a << [x, y] }\n    assert_equal([[1,:a],[2,:b],[3,:c],[1,nil],[2,nil]], a)\n  end\n\n  def test_take\n    assert_equal([1,2,3], @obj.take(3))\n  end\n\n  def test_take_while\n    assert_equal([1,2], @obj.take_while {|x| x <= 2})\n  end\n\n  def test_drop\n    assert_equal([3,1,2], @obj.drop(2))\n  end\n\n  def test_drop_while\n    assert_equal([3,1,2], @obj.drop_while {|x| x <= 2})\n  end\n\n  def test_cycle\n    assert_equal([1,2,3,1,2,1,2,3,1,2], @obj.cycle.take(10))\n  end\n\n  def test_callcc\n    assert_raise(RuntimeError) do\n      c = nil\n      @obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }\n      c.call\n    end\n\n    assert_raise(RuntimeError) do\n      c = nil\n      o = Object.new\n      class << o; self; end.class_eval do\n        define_method(:<=>) do |x|\n          callcc {|c2| c ||= c2 }\n          0\n        end\n      end\n      [o, o].sort_by {|x| x }\n      c.call\n    end\n\n    assert_raise(RuntimeError) do\n      c = nil\n      o = Object.new\n      class << o; self; end.class_eval do\n        define_method(:<=>) do |x|\n          callcc {|c2| c ||= c2 }\n          0\n        end\n      end\n      [o, o, o].sort_by {|x| x }\n      c.call\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_enumerator.rb",
    "content": "require 'test/unit'\n\nclass TestEnumerator < Test::Unit::TestCase\n  def setup\n    @obj = Object.new\n    class << @obj\n      include Enumerable\n      def foo(*a)\n        a.each {|x| yield x }\n      end\n    end\n  end\n\n  def enum_test obj\n    i = 0\n    obj.map{|e|\n      e\n    }.sort\n  end\n\n  def test_iterators\n    assert_equal [0, 1, 2], enum_test(3.times)\n    assert_equal [\"x\", \"y\", \"z\"], enum_test([\"z\", \"y\", \"x\"].each)\n    assert_equal [[\"x\", 1], [\"y\", 2]], enum_test({\"y\"=>2, \"x\"=>1})\n  end\n\n  ## Enumerator as Iterator\n\n  def test_next\n    e = 3.times\n    3.times{|i|\n      assert_equal i, e.next\n    }\n    assert_raise(StopIteration){e.next}\n  end\n\n  def test_loop\n    e = 3.times\n    i = 0\n    loop{\n      assert_equal(i, e.next)\n      i += 1\n    }\n  end\n\n  def test_nested_itaration\n    def (o = Object.new).each\n      yield :ok1\n      yield [:ok2, :x].each.next\n    end\n    e = o.to_enum\n    assert_equal :ok1, e.next\n    assert_equal :ok2, e.next\n    assert_raise(StopIteration){e.next}\n  end\n\n\n  def test_initialize\n    assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).to_a)\n    assert_equal([1, 2, 3], Enumerable::Enumerator.new(@obj, :foo, 1, 2, 3).to_a)\n    assert_raise(ArgumentError) { Enumerable::Enumerator.new }\n  end\n\n  def test_initialize_copy\n    assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a)\n    e = @obj.to_enum(:foo, 1, 2, 3)\n    assert_nothing_raised { assert_equal(1, e.next) }\n    #assert_raise(TypeError) { e.dup }\n  end\n\n  def test_gc\n    assert_nothing_raised do\n      1.times do\n        foo = [1,2,3].to_enum\n        GC.start\n      end\n      GC.start\n    end\n  end\n\n  def test_slice\n    assert_equal([[1,2,3],[4,5,6],[7,8,9],[10]], (1..10).each_slice(3).to_a)\n  end\n\n  def test_cons\n    a = [[1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,7], [6,7,8], [7,8,9], [8,9,10]]\n    assert_equal(a, (1..10).each_cons(3).to_a)\n  end\n\n  def test_with_index\n    assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a)\n  end\n\n  def test_next_rewind\n    e = @obj.to_enum(:foo, 1, 2, 3)\n    assert_equal(1, e.next)\n    assert_equal(2, e.next)\n    e.rewind\n    assert_equal(1, e.next)\n    assert_equal(2, e.next)\n    assert_equal(3, e.next)\n    assert_raise(StopIteration) { e.next }\n  end\nend\n\n"
  },
  {
    "path": "test/ruby/test_env.rb",
    "content": "require 'test/unit'\n\nclass TestEnv < Test::Unit::TestCase\n  IGNORE_CASE = /djgpp|bccwin|mswin|mingw/ =~ RUBY_PLATFORM\n\n  def setup\n    @backup = ENV.delete('test')\n    @BACKUP = ENV.delete('TEST')\n  end\n\n  def teardown\n    ENV['test'] = @backup if @backup\n    ENV['TEST'] = @BACKUP if @BACKUP\n  end\n\n  def test_bracket\n    assert_nil(ENV['test'])\n    assert_nil(ENV['TEST'])\n    ENV['test'] = 'foo'\n    assert_equal('foo', ENV['test'])\n    if IGNORE_CASE\n      assert_equal('foo', ENV['TEST'])\n    else\n      assert_nil(ENV['TEST'])\n    end\n    ENV['TEST'] = 'bar'\n    assert_equal('bar', ENV['TEST'])\n    if IGNORE_CASE\n      assert_equal('bar', ENV['test'])\n    else\n      assert_equal('foo', ENV['test'])\n    end\n\n    assert_raises(TypeError) {\n      tmp = ENV[1]\n    }\n    assert_raises(TypeError) {\n      ENV[1] = 'foo'\n    }\n    assert_raises(TypeError) {\n      ENV['test'] = 0\n    }\n  end\n\n  def test_has_value\n    val = 'a'\n    val.succ! while ENV.has_value?(val) && ENV.has_value?(val.upcase)\n    ENV['test'] = val[0...-1]\n\n    assert_equal(false, ENV.has_value?(val))\n    assert_equal(false, ENV.has_value?(val.upcase))\n    ENV['test'] = val\n    assert_equal(true, ENV.has_value?(val))\n    assert_equal(false, ENV.has_value?(val.upcase))\n    ENV['test'] = val.upcase\n    assert_equal(false, ENV.has_value?(val))\n    assert_equal(true, ENV.has_value?(val.upcase))\n  end\n\n  def test_index\n    val = 'a'\n    val.succ! while ENV.has_value?(val) && ENV.has_value?(val.upcase)\n    ENV['test'] = val[0...-1]\n\n    assert_nil(ENV.index(val))\n    assert_nil(ENV.index(val.upcase))\n    ENV['test'] = val\n    if IGNORE_CASE\n      assert_equal('TEST', ENV.index(val).upcase)\n    else\n      assert_equal('test', ENV.index(val))\n    end\n    assert_nil(ENV.index(val.upcase))\n    ENV['test'] = val.upcase\n    assert_nil(ENV.index(val))\n    if IGNORE_CASE\n      assert_equal('TEST', ENV.index(val.upcase).upcase)\n    else\n      assert_equal('test', ENV.index(val.upcase))\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_eval.rb",
    "content": "require 'test/unit'\n\nclass TestEval < Test::Unit::TestCase\n  # eval with binding\n  def test_ev\n    local1 = \"local1\"\n    lambda {\n      local2 = \"local2\"\n      return binding\n    }.call\n  end\n\n  def test_eval\n    assert_nil(eval(\"\"))\n    $bad=false\n    eval 'while false; $bad = true; print \"foo\\n\" end'\n    assert(!$bad)\n\n    assert(eval('TRUE'))\n    assert(eval('true'))\n    assert(!eval('NIL'))\n    assert(!eval('nil'))\n    assert(!eval('FALSE'))\n    assert(!eval('false'))\n\n    $foo = 'assert(true)'\n    begin\n      eval $foo\n    rescue\n      assert(false)\n    end\n\n    assert_equal('assert(true)', eval(\"$foo\"))\n    assert_equal(true, eval(\"true\"))\n    i = 5\n    assert(eval(\"i == 5\"))\n    assert_equal(5, eval(\"i\"))\n    assert(eval(\"defined? i\"))\n\n    $x = test_ev\n    assert_equal(\"local1\", eval(\"local1\", $x)) # normal local var\n    assert_equal(\"local2\", eval(\"local2\", $x)) # nested local var\n    $bad = true\n    begin\n      p eval(\"local1\")\n    rescue NameError\t\t# must raise error\n      $bad = false\n    end\n    assert(!$bad)\n\n    # !! use class_eval to avoid nested definition\n    self.class.class_eval %q(\n      module EvTest\n\tEVTEST1 = 25\n\tevtest2 = 125\n\t$x = binding\n      end\n    )\n    assert_equal(25, eval(\"EVTEST1\", $x))\t# constant in module\n    assert_equal(125, eval(\"evtest2\", $x))\t# local var in module\n    $bad = true\n    begin\n      eval(\"EVTEST1\")\n    rescue NameError\t\t# must raise error\n      $bad = false\n    end\n    assert(!$bad)\n\n    x = proc{}\n    eval \"i4 = 1\", x\n    assert_equal(1, eval(\"i4\", x))\n    x = proc{proc{}}.call\n    eval \"i4 = 22\", x\n    assert_equal(22, eval(\"i4\", x))\n    $x = []\n    x = proc{proc{}}.call\n    eval \"(0..9).each{|i5| $x[i5] = proc{i5*2}}\", x\n    assert_equal(8, $x[4].call)\n\n    x = binding\n    eval \"i = 1\", x\n    assert_equal(1, eval(\"i\", x))\n    x = proc{binding}.call\n    eval \"i = 22\", x\n    assert_equal(22, eval(\"i\", x))\n    $x = []\n    x = proc{binding}.call\n    eval \"(0..9).each{|i5| $x[i5] = proc{i5*2}}\", x\n    assert_equal(8, $x[4].call)\n    x = proc{binding}.call\n    eval \"for i6 in 1..1; j6=i6; end\", x\n    assert(eval(\"defined? i6\", x))\n    assert(eval(\"defined? j6\", x))\n\n    proc {\n      p = binding\n      eval \"foo11 = 1\", p\n      foo22 = 5\n      proc{foo11=22}.call\n      proc{foo22=55}.call\n      assert_equal(eval(\"foo11\"), eval(\"foo11\", p))\n      assert_equal(1, eval(\"foo11\"))\n      assert_equal(eval(\"foo22\"), eval(\"foo22\", p))\n      assert_equal(55, eval(\"foo22\"))\n    }.call\n\n    p1 = proc{i7 = 0; proc{i7}}.call\n    assert_equal(0, p1.call)\n    eval \"i7=5\", p1\n    assert_equal(5, p1.call)\n    assert(!defined?(i7))\n\n    p1 = proc{i7 = 0; proc{i7}}.call\n    i7 = nil\n    assert_equal(0, p1.call)\n    eval \"i7=1\", p1\n    assert_equal(1, p1.call)\n    eval \"i7=5\", p1\n    assert_equal(5, p1.call)\n    assert_nil(i7)\n  end\n\n  def test_nil_instance_eval_cvar # [ruby-dev:24103]\n    def nil.test_binding\n      binding\n    end\n    bb = eval(\"nil.instance_eval \\\"binding\\\"\", nil.test_binding)\n    assert_raise(NameError) { eval(\"@@a\", bb) }\n    class << nil\n      remove_method :test_binding\n    end\n  end\n\n  def test_fixnum_instance_eval_cvar # [ruby-dev:24213]\n    assert_raise(NameError) { 1.instance_eval \"@@a\" }\n  end\n\n  def test_cvar_scope_with_instance_eval # [ruby-dev:24223]\n    Fixnum.class_eval \"@@test_cvar_scope_with_instance_eval = 1\" # depends on [ruby-dev:24229]\n    @@test_cvar_scope_with_instance_eval = 4\n    assert_equal(4, 1.instance_eval(\"@@test_cvar_scope_with_instance_eval\"))\n    Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval)\n  end\n\n  def test_eval_and_define_method # [ruby-dev:24228]\n    assert_nothing_raised {\n      def temporally_method_for_test_eval_and_define_method(&block)\n        lambda {\n          class << Object.new; self end.__send__(:define_method, :zzz, &block)\n        }\n      end\n      v = eval(\"temporally_method_for_test_eval_and_define_method {}\")\n      {}[0] = {}\n      v.call\n    }\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_exception.rb",
    "content": "require 'test/unit'\n\nclass TestException < Test::Unit::TestCase\n  def test_exception\n    begin\n      raise \"this must be handled\"\n      assert(false)\n    rescue\n      assert(true)\n    end\n\n    $bad = true\n    begin\n      raise \"this must be handled no.2\"\n    rescue\n      if $bad\n        $bad = false\n        retry\n        assert(false)\n      end\n    end\n    assert(true)\n\n    # exception in rescue clause\n    $string = \"this must be handled no.3\"\n    e = assert_raises(RuntimeError) do\n      begin\n        raise \"exception in rescue clause\"\n      rescue\n        raise $string\n      end\n      assert(false)\n    end\n    assert_equal($string, e.message)\n\n    # exception in ensure clause\n    $string = \"exception in ensure clause\"\n    e = assert_raises(RuntimeError) do\n      begin\n        raise \"this must be handled no.4\"\n      ensure\n        assert_instance_of(RuntimeError, $!)\n        assert_equal(\"this must be handled no.4\", $!.message)\n        raise \"exception in ensure clause\"\n      end\n      assert(false)\n    end\n    assert_equal($string, e.message)\n\n    $bad = true\n    begin\n      begin\n        raise \"this must be handled no.5\"\n      ensure\n        $bad = false\n      end\n    rescue\n    end\n    assert(!$bad)\n\n    $bad = true\n    begin\n      begin\n        raise \"this must be handled no.6\"\n      ensure\n        $bad = false\n      end\n    rescue\n    end\n    assert(!$bad)\n\n    $bad = true\n    while true\n      begin\n        break\n      ensure\n        $bad = false\n      end\n    end\n    assert(!$bad)\n\n    assert(catch(:foo) {\n         loop do\n           loop do\n    \t throw :foo, true\n    \t break\n           end\n           break\n           assert(false)\t\t\t# should no reach here\n         end\n         false\n       })\n\n  end\n\n  def test_else\n    begin\n      assert(true)\n    rescue\n      assert(false)\n    else\n      assert(true)\n    end\n\n    begin\n      assert(true)\n      raise\n      assert(false)\n    rescue\n      assert(true)\n    else\n      assert(false)\n    end\n\n    begin\n      assert(true)\n      begin\n\tassert(true)\n      rescue\n\tassert(false)\n      else\n\tassert(true)\n      end\n      assert(true)\n    rescue\n      assert(false)\n    else\n      assert(true)\n    end\n\n    begin\n      assert(true)\n      begin\n\tassert(true)\n\traise\n\tassert(false)\n      rescue\n\tassert(true)\n      else\n\tassert(false)\n      end\n      assert(true)\n    rescue\n      assert(false)\n    else\n      assert(true)\n    end\n\n    begin\n      assert(true)\n      begin\n\tassert(true)\n      rescue\n\tassert(false)\n      else\n\tassert(true)\n      end\n      assert(true)\n      raise\n      assert(false)\n    rescue\n      assert(true)\n    else\n      assert(false)\n    end\n\n    begin\n      assert(true)\n      begin\n\tassert(true)\n\traise\n\tassert(false)\n      rescue\n\tassert(true)\n      else\n\tassert(false)\n      end\n      assert(true)\n      raise\n      assert(false)\n    rescue\n      assert(true)\n    else\n      assert(false)\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_file.rb",
    "content": "require 'test/unit'\nrequire 'tempfile'\n$:.replace([File.dirname(File.expand_path(__FILE__))] | $:)\nrequire 'ut_eof'\n\nclass TestFile < Test::Unit::TestCase\n\n  # I don't know Ruby's spec about \"unlink-before-close\" exactly.\n  # This test asserts current behaviour.\n  def test_unlink_before_close\n    filename = File.basename(__FILE__) + \".#{$$}\"\n    w = File.open(filename, \"w\")\n    w << \"foo\"\n    w.close\n    r = File.open(filename, \"r\")\n    begin\n      if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM\n\tbegin\n\t  File.unlink(filename)\n\t  assert(false)\n\trescue Errno::EACCES\n\t  assert(true)\n\tend\n      else\n\tFile.unlink(filename)\n\tassert(true)\n      end\n    ensure\n      r.close\n      File.unlink(filename) if File.exist?(filename)\n    end\n  end\n\n  include TestEOF\n  def open_file(content)\n    f = Tempfile.new(\"test-eof\")\n    f << content\n    f.rewind\n    yield f\n  end\n  alias open_file_rw open_file\n\n  include TestEOF::Seek\n\n  def test_fnmatch\n    # from [ruby-dev:22815] and [ruby-dev:22819]\n    assert(true, File.fnmatch('\\[1\\]' , '[1]'))\n    assert(true, File.fnmatch('*?', 'a'))\n  end\n\n  def test_truncate_wbuf # [ruby-dev:24191]\n    f = Tempfile.new(\"test-truncate\")\n    f.print \"abc\"\n    f.truncate(0)\n    f.print \"def\"\n    f.close\n    assert_equal(\"\\0\\0\\0def\", File.read(f.path))\n  end\n\n  def test_truncate_rbuf # [ruby-dev:24197]\n    f = Tempfile.new(\"test-truncate\")\n    f.puts \"abc\"\n    f.puts \"def\"\n    f.close\n    f.open\n    assert_equal(\"abc\\n\", f.gets)\n    f.truncate(3)\n    assert_equal(nil, f.gets)\n  end\n\n  def test_read_all_extended_file\n    f = Tempfile.new(\"test-extended-file\")\n    assert_nil(f.getc)\n    open(f.path, \"w\") {|g| g.print \"a\" }\n    assert_equal(\"a\", f.read)\n  end\n\n  def test_gets_extended_file\n    f = Tempfile.new(\"test-extended-file\")\n    assert_nil(f.getc)\n    open(f.path, \"w\") {|g| g.print \"a\" }\n    assert_equal(\"a\", f.gets(\"a\"))\n  end\n\n  def test_gets_para_extended_file\n    f = Tempfile.new(\"test-extended-file\")\n    assert_nil(f.getc)\n    open(f.path, \"w\") {|g| g.print \"\\na\" }\n    assert_equal(\"a\", f.gets(\"\"))\n  end\n\n  def test_each_byte_extended_file\n    f = Tempfile.new(\"test-extended-file\")\n    assert_nil(f.getc)\n    open(f.path, \"w\") {|g| g.print \"a\" }\n    result = []\n    f.each_byte {|b| result << b }\n    assert_equal([?a], result)\n  end\n\n  def test_getc_extended_file\n    f = Tempfile.new(\"test-extended-file\")\n    assert_nil(f.getc)\n    open(f.path, \"w\") {|g| g.print \"a\" }\n    assert_equal(?a, f.getc)\n  end\n\nend\n"
  },
  {
    "path": "test/ruby/test_file_exhaustive.rb",
    "content": "require \"test/unit\"\nrequire \"fileutils\"\nrequire \"tmpdir\"\n\nclass TestFileExhaustive < Test::Unit::TestCase\n  def setup\n    @dir = Dir.mktmpdir(\"rubytest-file\")\n    File.chown(-1, Process.gid, @dir)\n    @file = make_tmp_filename(\"file\")\n    @zerofile = make_tmp_filename(\"zerofile\")\n    @nofile = make_tmp_filename(\"nofile\")\n    @symlinkfile = make_tmp_filename(\"symlinkfile\")\n    @hardlinkfile = make_tmp_filename(\"hardlinkfile\")\n    make_file(\"foo\", @file)\n    make_file(\"\", @zerofile)\n    @time = Time.now\n    begin\n      File.symlink(@file, @symlinkfile)\n    rescue NotImplementedError\n      @symlinkfile = nil\n    end\n    begin\n      File.link(@file, @hardlinkfile)\n    rescue NotImplementedError, Errno::EINVAL\t# EINVAL for Windows Vista\n      @hardlinkfile = nil\n    end\n  end\n\n  def teardown\n    GC.start\n    FileUtils.remove_entry_secure @dir\n  end\n\n  def make_file(content, file = @file)\n    open(file, \"w\") {|fh| fh << content }\n  end\n  \n  def make_tmp_filename(prefix)\n    @hardlinkfile = @dir + \"/\" + prefix + File.basename(__FILE__) + \".#{$$}.test\"\n  end\n\n  def test_path\n    file = @file\n\n    assert_equal(file, File.open(file) {|f| f.path})\n  end\n\n  def assert_integer(n)\n    assert(n.is_a?(Integer), n.inspect + \" is not Fixnum.\")\n  end\n\n  def assert_integer_or_nil(n)\n    assert(n.is_a?(Integer) || n.equal?(nil), n.inspect + \" is neither Fixnum nor nil.\")\n  end\n\n  def test_stat\n    sleep(@time - Time.now + 1.1)\n    make_file(\"foo\", @file + \"2\")\n    fs1, fs2 = File.stat(@file), File.stat(@file + \"2\")\n    assert_nothing_raised do\n      assert_equal(0, fs1 <=> fs1)\n      assert_equal(-1, fs1 <=> fs2)\n      assert_equal(1, fs2 <=> fs1)\n      assert_nil(fs1 <=> nil)\n      assert_integer(fs1.dev)\n      assert_integer_or_nil(fs1.rdev)\n      assert_integer_or_nil(fs1.dev_major)\n      assert_integer_or_nil(fs1.dev_minor)\n      assert_integer_or_nil(fs1.rdev_major)\n      assert_integer_or_nil(fs1.rdev_minor)\n      assert_integer(fs1.ino)\n      assert_integer(fs1.mode)\n      unless /emx/ =~ RUBY_PLATFORM\n        assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink)\n      end\n      assert_integer(fs1.uid)\n      assert_integer(fs1.gid)\n      assert_equal(3, fs1.size)\n      assert_integer_or_nil(fs1.blksize)\n      assert_integer_or_nil(fs1.blocks)\n      assert_kind_of(Time, fs1.atime)\n      assert_kind_of(Time, fs1.mtime)\n      assert_kind_of(Time, fs1.ctime)\n      assert_kind_of(String, fs1.inspect)\n    end\n    assert_raise(Errno::ENOENT) { File.stat(@nofile) }\n    assert_kind_of(File::Stat, File.open(@file) {|f| f.stat})\n    assert_raise(Errno::ENOENT) { File.lstat(@nofile) }\n    assert_kind_of(File::Stat, File.open(@file) {|f| f.lstat})\n  end\n\n  def test_directory_p\n    assert(File.directory?(@dir))\n    assert(!(File.directory?(@dir+\"/...\")))\n    assert(!(File.directory?(@file)))\n    assert(!(File.directory?(@nofile)))\n  end\n\n  def test_pipe_p ## xxx\n    assert(!(File.pipe?(@dir)))\n    assert(!(File.pipe?(@file)))\n    assert(!(File.pipe?(@nofile)))\n  end\n\n  def test_symlink_p\n    assert(!(File.symlink?(@dir)))\n    assert(!(File.symlink?(@file)))\n    assert(File.symlink?(@symlinkfile)) if @symlinkfile\n    assert(!(File.symlink?(@hardlinkfile))) if @hardlinkfile\n    assert(!(File.symlink?(@nofile)))\n  end\n\n  def test_socket_p ## xxx\n    assert(!(File.socket?(@dir)))\n    assert(!(File.socket?(@file)))\n    assert(!(File.socket?(@nofile)))\n  end\n\n  def test_blockdev_p ## xxx\n    assert(!(File.blockdev?(@dir)))\n    assert(!(File.blockdev?(@file)))\n    assert(!(File.blockdev?(@nofile)))\n  end\n\n  def test_chardev_p ## xxx\n    assert(!(File.chardev?(@dir)))\n    assert(!(File.chardev?(@file)))\n    assert(!(File.chardev?(@nofile)))\n  end\n\n  def test_exist_p\n    assert(File.exist?(@dir))\n    assert(File.exist?(@file))\n    assert(!(File.exist?(@nofile)))\n  end\n\n  def test_readable_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0200, @file)\n    assert(!(File.readable?(@file)))\n    File.chmod(0600, @file)\n    assert(File.readable?(@file))\n    assert(!(File.readable?(@nofile)))\n  end\n\n  def test_readable_real_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0200, @file)\n    assert(!(File.readable_real?(@file)))\n    File.chmod(0600, @file)\n    assert(File.readable_real?(@file))\n    assert(!(File.readable_real?(@nofile)))\n  end\n\n  def test_writable_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0400, @file)\n    assert(!(File.writable?(@file)))\n    File.chmod(0600, @file)\n    assert(File.writable?(@file))\n    assert(!(File.writable?(@nofile)))\n  end\n\n  def test_writable_real_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0400, @file)\n    assert(!(File.writable_real?(@file)))\n    File.chmod(0600, @file)\n    assert(File.writable_real?(@file))\n    assert(!(File.writable_real?(@nofile)))\n  end\n\n  def test_executable_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0100, @file)\n    assert(File.executable?(@file))\n    File.chmod(0600, @file)\n    assert(!(File.executable?(@file)))\n    assert(!(File.executable?(@nofile)))\n  end\n\n  def test_executable_real_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0100, @file)\n    assert(File.executable_real?(@file))\n    File.chmod(0600, @file)\n    assert(!(File.executable_real?(@file)))\n    assert(!(File.executable_real?(@nofile)))\n  end\n\n  def test_file_p\n    assert(!(File.file?(@dir)))\n    assert(File.file?(@file))\n    assert(!(File.file?(@nofile)))\n  end\n\n  def test_zero_p\n    assert_nothing_raised { File.zero?(@dir) }\n    assert(!(File.zero?(@file)))\n    assert(File.zero?(@zerofile))\n    assert(!(File.zero?(@nofile)))\n  end\n\n  def test_size_p\n    assert_nothing_raised { File.size?(@dir) }\n    assert_equal(3, File.size?(@file))\n    assert(!(File.size?(@zerofile)))\n    assert(!(File.size?(@nofile)))\n  end\n\n  def test_owned_p ## xxx\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    assert(File.owned?(@file))\n    assert(File.grpowned?(@file))\n  end\n\n  def test_suid_sgid_sticky ## xxx\n    assert(!(File.setuid?(@file)))\n    assert(!(File.setgid?(@file)))\n    assert(!(File.sticky?(@file)))\n  end\n\n  def test_identical_p\n    assert(File.identical?(@file, @file))\n    assert(!(File.identical?(@file, @zerofile)))\n    assert(!(File.identical?(@file, @nofile)))\n    assert(!(File.identical?(@nofile, @file)))\n  end\n\n  def test_size\n    assert_integer(File.size(@dir))\n    assert_equal(3, File.size(@file))\n    assert_equal(0, File.size(@zerofile))\n    assert_raise(Errno::ENOENT) { File.size(@nofile) }\n  end\n\n  def test_ftype\n    assert_equal(\"directory\", File.ftype(@dir))\n    assert_equal(\"file\", File.ftype(@file))\n    assert_equal(\"link\", File.ftype(@symlinkfile)) if @symlinkfile\n    assert_equal(\"file\", File.ftype(@hardlinkfile)) if @hardlinkfile\n    assert_raise(Errno::ENOENT) { File.ftype(@nofile) }\n  end\n\n  def test_atime\n    t1 = File.atime(@file)\n    t2 = File.open(@file) {|f| f.atime}\n    assert_kind_of(Time, t1)\n    assert_kind_of(Time, t2)\n    assert_equal(t1, t2)\n    assert_raise(Errno::ENOENT) { File.atime(@nofile) }\n  end\n\n  def test_mtime\n    t1 = File.mtime(@file)\n    t2 = File.open(@file) {|f| f.mtime}\n    assert_kind_of(Time, t1)\n    assert_kind_of(Time, t2)\n    assert_equal(t1, t2)\n    assert_raise(Errno::ENOENT) { File.mtime(@nofile) }\n  end\n\n  def test_ctime\n    t1 = File.ctime(@file)\n    t2 = File.open(@file) {|f| f.ctime}\n    assert_kind_of(Time, t1)\n    assert_kind_of(Time, t2)\n    assert_equal(t1, t2)\n    assert_raise(Errno::ENOENT) { File.ctime(@nofile) }\n  end\n\n  def test_chmod\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    assert_equal(1, File.chmod(0444, @file))\n    assert_equal(0444, File.stat(@file).mode % 01000)\n    assert_equal(0, File.open(@file) {|f| f.chmod(0222)})\n    assert_equal(0222, File.stat(@file).mode % 01000)\n    File.chmod(0600, @file)\n    assert_raise(Errno::ENOENT) { File.chmod(0600, @nofile) }\n  end\n\n  def test_lchmod\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    assert_equal(1, File.lchmod(0444, @file))\n    assert_equal(0444, File.stat(@file).mode % 01000)\n    File.lchmod(0600, @file)\n    assert_raise(Errno::ENOENT) { File.lchmod(0600, @nofile) }\n  rescue NotImplementedError\n  end\n\n  def test_chown ## xxx\n  end\n\n  def test_lchown ## xxx\n  end\n\n  def test_symlink\n    return unless @symlinkfile\n    assert_equal(\"link\", File.ftype(@symlinkfile))\n    assert_raise(Errno::EEXIST) { File.symlink(@file, @file) }\n  end\n\n  def test_utime\n    t = Time.local(2000)\n    File.utime(t + 1, t + 2, @zerofile)\n    assert_equal(t + 1, File.atime(@zerofile))\n    assert_equal(t + 2, File.mtime(@zerofile))\n  end\n\n  def test_hardlink\n    return unless @hardlinkfile\n    assert_equal(\"file\", File.ftype(@hardlinkfile))\n    assert_raise(Errno::EEXIST) { File.link(@file, @file) }\n  end\n\n  def test_symlink2\n    return unless @symlinkfile\n    assert_equal(@file, File.readlink(@symlinkfile))\n    assert_raise(Errno::EINVAL) { File.readlink(@file) }\n    assert_raise(Errno::ENOENT) { File.readlink(@nofile) }\n  rescue NotImplementedError\n  end\n\n  def test_unlink\n    assert_equal(1, File.unlink(@file))\n    make_file(\"foo\", @file)\n    assert_raise(Errno::ENOENT) { File.unlink(@nofile) }\n  end\n\n  def test_rename\n    assert_equal(0, File.rename(@file, @nofile))\n    assert(!(File.exist?(@file)))\n    assert(File.exist?(@nofile))\n    assert_equal(0, File.rename(@nofile, @file))\n    assert_raise(Errno::ENOENT) { File.rename(@nofile, @file) }\n  end\n\n  def test_umask\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    prev = File.umask(0777)\n    assert_equal(0777, File.umask)\n    open(@nofile, \"w\") { }\n    assert_equal(0, File.stat(@nofile).mode % 01000)\n    File.unlink(@nofile)\n    assert_equal(0777, File.umask(prev))\n    assert_raise(ArgumentError) { File.umask(0, 1, 2) }\n  end\n\n  def test_expand_path\n    assert_equal(@file, File.expand_path(File.basename(@file), File.dirname(@file)))\n    if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM\n      assert_equal(@file, File.expand_path(@file + \" \"))\n      assert_equal(@file, File.expand_path(@file + \".\"))\n      assert_equal(@file, File.expand_path(@file + \"::$DATA\"))\n    end\n  end\n\n  def test_basename\n    assert_equal(File.basename(@file).sub(/\\.test$/, \"\"), File.basename(@file, \".test\"))\n    assert_equal(\"\", File.basename(\"\"))\n    assert_equal(\"foo\", File.basename(\"foo\"))\n    assert_equal(\"foo\", File.basename(\"foo\", \".ext\"))\n    assert_equal(\"foo\", File.basename(\"foo.ext\", \".ext\"))\n    assert_equal(\"foo\", File.basename(\"foo.ext\", \".*\"))\n    if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM\n      basename = File.basename(@file)\n      assert_equal(basename, File.basename(@file + \" \"))\n      assert_equal(basename, File.basename(@file + \".\"))\n      assert_equal(basename, File.basename(@file + \"::$DATA\"))\n      basename.chomp!(\".test\")\n      assert_equal(basename, File.basename(@file + \" \", \".test\"))\n      assert_equal(basename, File.basename(@file + \".\", \".test\"))\n      assert_equal(basename, File.basename(@file + \"::$DATA\", \".test\"))\n      assert_equal(basename, File.basename(@file + \" \", \".*\"))\n      assert_equal(basename, File.basename(@file + \".\", \".*\"))\n      assert_equal(basename, File.basename(@file + \"::$DATA\", \".*\"))\n    end\n  end\n\n  def test_dirname\n    assert(@file.start_with?(File.dirname(@file)))\n    assert_equal(\".\", File.dirname(\"\"))\n  end\n\n  def test_extname\n    assert(\".test\", File.extname(@file))\n    prefixes = [\"\", \"/\", \".\", \"/.\", \"bar/.\", \"/bar/.\"]\n    infixes = [\"\", \" \", \".\"]\n    infixes2 = infixes + [\".ext \"]\n    appendixes = [\"\"]\n    if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM\n      appendixes << \" \" << \".\" << \"::$DATA\" << \"::$DATA.bar\"\n    end\n    prefixes.each do |prefix|\n      appendixes.each do |appendix|\n        infixes.each do |infix|\n          path = \"#{prefix}foo#{infix}#{appendix}\"\n          assert_equal(\"\", File.extname(path), \"File.extname(#{path.inspect})\")\n        end\n        infixes2.each do |infix|\n          path = \"#{prefix}foo#{infix}.ext#{appendix}\"\n          assert_equal(\".ext\", File.extname(path), \"File.extname(#{path.inspect})\")\n        end\n      end\n    end\n  end\n\n  def test_split\n    d, b = File.split(@file)\n    assert_equal(File.dirname(@file), d)\n    assert_equal(File.basename(@file), b)\n  end\n\n  def test_join\n    s = \"foo\" + File::SEPARATOR + \"bar\" + File::SEPARATOR + \"baz\"\n    assert_equal(s, File.join(\"foo\", \"bar\", \"baz\"))\n    assert_equal(s, File.join([\"foo\", \"bar\", \"baz\"]))\n    assert_equal(s, File.join(\"foo\" + File::SEPARATOR, \"bar\", File::SEPARATOR + \"baz\"))\n  end\n\n  def test_truncate\n    assert_equal(0, File.truncate(@file, 1))\n    assert(File.exist?(@file))\n    assert_equal(1, File.size(@file))\n    assert_equal(0, File.truncate(@file, 0))\n    assert(File.exist?(@file))\n    assert(File.zero?(@file))\n    make_file(\"foo\", @file)\n    assert_raise(Errno::ENOENT) { File.truncate(@nofile, 0) }\n\n    f = File.new(@file, \"w\")\n    assert_equal(0, f.truncate(2))\n    assert(File.exist?(@file))\n    assert_equal(2, File.size(@file))\n    assert_equal(0, f.truncate(0))\n    assert(File.exist?(@file))\n    assert(File.zero?(@file))\n    f.close\n    make_file(\"foo\", @file)\n\n    assert_raise(IOError) { File.open(@file) {|f| f.truncate(0)} }\n  rescue NotImplementedError\n  end\n\n  def test_flock ## xxx\n    f = File.new(@file, \"r+\")\n    f.flock(File::LOCK_EX)\n    f.flock(File::LOCK_SH)\n    f.flock(File::LOCK_UN)\n    f.close\n  rescue NotImplementedError\n  end\n\n  def test_test\n    sleep(@time - Time.now + 1.1)\n    make_file(\"foo\", @file + \"2\")\n    [@dir, @file, @zerofile, @symlinkfile, @hardlinkfile].compact.each do |f|\n      assert_equal(File.atime(f), test(?A, f))\n      assert_equal(File.ctime(f), test(?C, f))\n      assert_equal(File.mtime(f), test(?M, f))\n      assert_equal(File.blockdev?(f), test(?b, f))\n      assert_equal(File.chardev?(f), test(?c, f))\n      assert_equal(File.directory?(f), test(?d, f))\n      assert_equal(File.exist?(f), test(?e, f))\n      assert_equal(File.file?(f), test(?f, f))\n      assert_equal(File.setgid?(f), test(?g, f))\n      assert_equal(File.grpowned?(f), test(?G, f))\n      assert_equal(File.sticky?(f), test(?k, f))\n      assert_equal(File.symlink?(f), test(?l, f))\n      assert_equal(File.owned?(f), test(?o, f))\n      assert_nothing_raised { test(?O, f) }\n      assert_equal(File.pipe?(f), test(?p, f))\n      assert_equal(File.readable?(f), test(?r, f))\n      assert_equal(File.readable_real?(f), test(?R, f))\n      assert_equal(File.size?(f), test(?s, f))\n      assert_equal(File.socket?(f), test(?S, f))\n      assert_equal(File.setuid?(f), test(?u, f))\n      assert_equal(File.writable?(f), test(?w, f))\n      assert_equal(File.executable?(f), test(?x, f))\n      assert_equal(File.executable_real?(f), test(?X, f))\n      assert_equal(File.zero?(f), test(?z, f))\n    end\n    assert_equal(false, test(?-, @dir, @file))\n    assert_equal(true, test(?-, @file, @file))\n    assert_equal(true, test(?=, @file, @file))\n    assert_equal(false, test(?>, @file, @file))\n    assert_equal(false, test(?<, @file, @file))\n    unless /cygwin/ =~ RUBY_PLATFORM\n      assert_equal(false, test(?=, @file, @file + \"2\"))\n      assert_equal(false, test(?>, @file, @file + \"2\"))\n      assert_equal(true, test(?>, @file + \"2\", @file))\n      assert_equal(true, test(?<, @file, @file + \"2\"))\n      assert_equal(false, test(?<, @file + \"2\", @file))\n    end\n    assert_raise(ArgumentError) { test }\n    assert_raise(Errno::ENOENT) { test(?A, @nofile) }\n    assert_raise(ArgumentError) { test(?a) }\n  end\n\n  def test_stat_init\n    sleep(@time - Time.now + 1.1)\n    make_file(\"foo\", @file + \"2\")\n    fs1, fs2 = File::Stat.new(@file), File::Stat.new(@file + \"2\")\n    assert_nothing_raised do\n      assert_equal(0, fs1 <=> fs1)\n      assert_equal(-1, fs1 <=> fs2)\n      assert_equal(1, fs2 <=> fs1)\n      assert_nil(fs1 <=> nil)\n      assert_integer(fs1.dev)\n      assert_integer_or_nil(fs1.rdev)\n      assert_integer_or_nil(fs1.dev_major)\n      assert_integer_or_nil(fs1.dev_minor)\n      assert_integer_or_nil(fs1.rdev_major)\n      assert_integer_or_nil(fs1.rdev_minor)\n      assert_integer(fs1.ino)\n      assert_integer(fs1.mode)\n      unless /emx/ =~ RUBY_PLATFORM\n        assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink)\n      end\n      assert_integer(fs1.uid)\n      assert_integer(fs1.gid)\n      assert_equal(3, fs1.size)\n      assert_integer_or_nil(fs1.blksize)\n      assert_integer_or_nil(fs1.blocks)\n      assert_kind_of(Time, fs1.atime)\n      assert_kind_of(Time, fs1.mtime)\n      assert_kind_of(Time, fs1.ctime)\n      assert_kind_of(String, fs1.inspect)\n    end\n    assert_raise(Errno::ENOENT) { File::Stat.new(@nofile) }\n    assert_kind_of(File::Stat, File::Stat.new(@file).dup)\n    assert_raise(TypeError) do\n      File::Stat.new(@file).instance_eval { initialize_copy(0) }\n    end\n  end\n\n  def test_stat_ftype\n    assert_equal(\"directory\", File::Stat.new(@dir).ftype)\n    assert_equal(\"file\", File::Stat.new(@file).ftype)\n    # File::Stat uses stat\n    assert_equal(\"file\", File::Stat.new(@symlinkfile).ftype) if @symlinkfile\n    assert_equal(\"file\", File::Stat.new(@hardlinkfile).ftype) if @hardlinkfile\n  end\n\n  def test_stat_directory_p\n    assert(File::Stat.new(@dir).directory?)\n    assert(!(File::Stat.new(@file).directory?))\n  end\n\n  def test_stat_pipe_p ## xxx\n    assert(!(File::Stat.new(@dir).pipe?))\n    assert(!(File::Stat.new(@file).pipe?))\n  end\n\n  def test_stat_symlink_p\n    assert(!(File::Stat.new(@dir).symlink?))\n    assert(!(File::Stat.new(@file).symlink?))\n    # File::Stat uses stat\n    assert(!(File::Stat.new(@symlinkfile).symlink?)) if @symlinkfile\n    assert(!(File::Stat.new(@hardlinkfile).symlink?)) if @hardlinkfile\n  end\n\n  def test_stat_socket_p ## xxx\n    assert(!(File::Stat.new(@dir).socket?))\n    assert(!(File::Stat.new(@file).socket?))\n  end\n\n  def test_stat_blockdev_p ## xxx\n    assert(!(File::Stat.new(@dir).blockdev?))\n    assert(!(File::Stat.new(@file).blockdev?))\n  end\n\n  def test_stat_chardev_p ## xxx\n    assert(!(File::Stat.new(@dir).chardev?))\n    assert(!(File::Stat.new(@file).chardev?))\n  end\n\n  def test_stat_readable_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0200, @file)\n    assert(!(File::Stat.new(@file).readable?))\n    File.chmod(0600, @file)\n    assert(File::Stat.new(@file).readable?)\n  end\n\n  def test_stat_readable_real_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0200, @file)\n    assert(!(File::Stat.new(@file).readable_real?))\n    File.chmod(0600, @file)\n    assert(File::Stat.new(@file).readable_real?)\n  end\n\n  def test_stat_writable_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0400, @file)\n    assert(!(File::Stat.new(@file).writable?))\n    File.chmod(0600, @file)\n    assert(File::Stat.new(@file).writable?)\n  end\n\n  def test_stat_writable_real_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0400, @file)\n    assert(!(File::Stat.new(@file).writable_real?))\n    File.chmod(0600, @file)\n    assert(File::Stat.new(@file).writable_real?)\n  end\n\n  def test_stat_executable_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0100, @file)\n    assert(File::Stat.new(@file).executable?)\n    File.chmod(0600, @file)\n    assert(!(File::Stat.new(@file).executable?))\n  end\n\n  def test_stat_executable_real_p\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    File.chmod(0100, @file)\n    assert(File::Stat.new(@file).executable_real?)\n    File.chmod(0600, @file)\n    assert(!(File::Stat.new(@file).executable_real?))\n  end\n\n  def test_stat_file_p\n    assert(!(File::Stat.new(@dir).file?))\n    assert(File::Stat.new(@file).file?)\n  end\n\n  def test_stat_zero_p\n    assert_nothing_raised { File::Stat.new(@dir).zero? }\n    assert(!(File::Stat.new(@file).zero?))\n    assert(File::Stat.new(@zerofile).zero?)\n  end\n\n  def test_stat_size_p\n    assert_nothing_raised { File::Stat.new(@dir).size? }\n    assert_equal(3, File::Stat.new(@file).size?)\n    assert(!(File::Stat.new(@zerofile).size?))\n  end\n\n  def test_stat_owned_p ## xxx\n    return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM\n    assert(File::Stat.new(@file).owned?)\n    assert(File::Stat.new(@file).grpowned?)\n  end\n\n  def test_stat_suid_sgid_sticky ## xxx\n    assert(!(File::Stat.new(@file).setuid?))\n    assert(!(File::Stat.new(@file).setgid?))\n    assert(!(File::Stat.new(@file).sticky?))\n  end\n\n  def test_stat_size\n    assert_integer(File::Stat.new(@dir).size)\n    assert_equal(3, File::Stat.new(@file).size)\n    assert_equal(0, File::Stat.new(@zerofile).size)\n  end\n\n  def test_path_check\n    assert_nothing_raised { ENV[\"PATH\"] }\n  end\n\n  def test_find_file\n    assert_raise(SecurityError) do\n      Thread.new do\n        $SAFE = 4\n        load(@file)\n      end.join\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_fixnum.rb",
    "content": "require 'test/unit'\n\nclass TestFixnum < Test::Unit::TestCase\n  def setup\n    @verbose = $VERBOSE\n    $VERBOSE = nil\n  end\n\n  def teardown\n    $VERBOSE = @verbose\n  end\n\n  def test_pow\n    [1, 2, 2**64, 2**63*3, 2**64*3].each do |y|\n      [-1, 0, 1].each do |x|\n        z1 = x**y\n        z2 = (-x)**y\n        if y % 2 == 1\n          assert_equal(z2, -z1)\n        else\n          assert_equal(z2, z1)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_float.rb",
    "content": "require 'test/unit'\n\nclass TestFloat < Test::Unit::TestCase\n  def test_float\n    assert_equal(2, 2.6.floor)\n    assert_equal(-3, (-2.6).floor)\n    assert_equal(3, 2.6.ceil)\n    assert_equal(-2, (-2.6).ceil)\n    assert_equal(2, 2.6.truncate)\n    assert_equal(-2, (-2.6).truncate)\n    assert_equal(3, 2.6.round)\n    assert_equal(-2, (-2.4).truncate)\n    assert((13.4 % 1 - 0.4).abs < 0.0001)\n  end\n\n  def nan_test(x,y)\n    extend Test::Unit::Assertions\n    assert(x != y)\n    assert_equal(false, (x < y))\n    assert_equal(false, (x > y))\n    assert_equal(false, (x <= y))\n    assert_equal(false, (x >= y))\n  end\n  def test_nan\n    nan = 0.0/0\n    nan_test(nan, nan)\n    nan_test(nan, 0)\n    nan_test(nan, 1)\n    nan_test(nan, -1)\n    nan_test(nan, 1000)\n    nan_test(nan, -1000)\n    nan_test(nan, 1_000_000_000_000)\n    nan_test(nan, -1_000_000_000_000)\n    nan_test(nan, 100.0);\n    nan_test(nan, -100.0);\n    nan_test(nan, 0.001);\n    nan_test(nan, -0.001);\n    nan_test(nan, 1.0/0);\n    nan_test(nan, -1.0/0);\n  end\n\n  def test_precision\n    u = 3.7517675036461267e+17\n    v = sprintf(\"%.16e\", u).to_f\n    assert_in_delta(u, v, u.abs * Float::EPSILON)\n    assert_in_delta(u, v, v.abs * Float::EPSILON)\n  end\n\n  def test_symmetry_bignum # [ruby-bugs-ja:118]\n    a = 100000000000000000000000\n    b = 100000000000000000000000.0\n    assert_equal(a == b, b == a)\n  end\n\n  def test_strtod\n    a = Float(\"0\")\n    assert(a.abs < Float::EPSILON)\n    a = Float(\"0.0\")\n    assert(a.abs < Float::EPSILON)\n    a = Float(\"+0.0\")\n    assert(a.abs < Float::EPSILON)\n    a = Float(\"-0.0\")\n    assert(a.abs < Float::EPSILON)\n    a = Float(\"0.0000000000000000001\")\n    assert(a != 0.0)\n    a = Float(\"+0.0000000000000000001\")\n    assert(a != 0.0)\n    a = Float(\"-0.0000000000000000001\")\n    assert(a != 0.0)\n    a = Float(\".0\")\n    assert(a.abs < Float::EPSILON)\n    a = Float(\"+.0\")\n    assert(a.abs < Float::EPSILON)\n    a = Float(\"-.0\")\n    assert(a.abs < Float::EPSILON)\n    assert(a.abs < Float::EPSILON)\n    assert_raise(ArgumentError){Float(\".\")}\n    assert_raise(ArgumentError){Float(\"+\")}\n    assert_raise(ArgumentError){Float(\"+.\")}\n    assert_raise(ArgumentError){Float(\"-\")}\n    assert_raise(ArgumentError){Float(\"-.\")}\n    assert_raise(ArgumentError){Float(\"1e\")}\n    # add expected behaviour here.\n  end\n\n  def test_divmod\n    assert_equal([2, 3.5], 11.5.divmod(4))\n    assert_equal([-3, -0.5], 11.5.divmod(-4))\n    assert_equal([-3, 0.5], (-11.5).divmod(4))\n    assert_equal([2, -3.5], (-11.5).divmod(-4))\n  end\n\n  def test_div\n    assert_equal(2, 11.5.div(4))\n    assert_equal(-3, 11.5.div(-4))\n    assert_equal(-3, (-11.5).div(4))\n    assert_equal(2, (-11.5).div(-4))\n  end\n\n  def test_modulo\n    assert_equal(3.5, 11.5.modulo(4))\n    assert_equal(-0.5, 11.5.modulo(-4))\n    assert_equal(0.5, (-11.5).modulo(4))\n    assert_equal(-3.5, (-11.5).modulo(-4))\n  end\n\n  def test_remainder\n    assert_equal(3.5, 11.5.remainder(4))\n    assert_equal(3.5, 11.5.remainder(-4))\n    assert_equal(-3.5, (-11.5).remainder(4))\n    assert_equal(-3.5, (-11.5).remainder(-4))\n  end\n\n  def test_to_i\n    assert_operator(4611686018427387905.0.to_i, :>, 0)\n    assert_operator(4611686018427387904.0.to_i, :>, 0)\n    assert_operator(4611686018427387903.8.to_i, :>, 0)\n    assert_operator(4611686018427387903.5.to_i, :>, 0)\n    assert_operator(4611686018427387903.2.to_i, :>, 0)\n    assert_operator(4611686018427387903.0.to_i, :>, 0)\n    assert_operator(4611686018427387902.0.to_i, :>, 0)\n\n    assert_operator(1073741825.0.to_i, :>, 0)\n    assert_operator(1073741824.0.to_i, :>, 0)\n    assert_operator(1073741823.8.to_i, :>, 0)\n    assert_operator(1073741823.5.to_i, :>, 0)\n    assert_operator(1073741823.2.to_i, :>, 0)\n    assert_operator(1073741823.0.to_i, :>, 0)\n    assert_operator(1073741822.0.to_i, :>, 0)\n\n    assert_operator((-1073741823.0).to_i, :<, 0)\n    assert_operator((-1073741824.0).to_i, :<, 0)\n    assert_operator((-1073741824.2).to_i, :<, 0)\n    assert_operator((-1073741824.5).to_i, :<, 0)\n    assert_operator((-1073741824.8).to_i, :<, 0)\n    assert_operator((-1073741825.0).to_i, :<, 0)\n    assert_operator((-1073741826.0).to_i, :<, 0)\n\n    assert_operator((-4611686018427387903.0).to_i, :<, 0)\n    assert_operator((-4611686018427387904.0).to_i, :<, 0)\n    assert_operator((-4611686018427387904.2).to_i, :<, 0)\n    assert_operator((-4611686018427387904.5).to_i, :<, 0)\n    assert_operator((-4611686018427387904.8).to_i, :<, 0)\n    assert_operator((-4611686018427387905.0).to_i, :<, 0)\n    assert_operator((-4611686018427387906.0).to_i, :<, 0)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_gc.rb",
    "content": "require 'test/unit'\n\nclass TestGc < Test::Unit::TestCase\n  class S\n    def initialize(a)\n      @a = a\n    end\n  end\n\n  def test_gc\n    assert_nothing_raised do\n      1.upto(10000) {\n        tmp = [0,1,2,3,4,5,6,7,8,9]\n      }\n      tmp = nil\n    end\n    l=nil\n    100000.times {\n      l = S.new(l)\n    }\n    GC.start\n    assert true   # reach here or dumps core\n    l = []\n    100000.times {\n      l.push([l])\n    }\n    GC.start\n    assert true   # reach here or dumps core\n    100000.times {\n      Time.now\n    }\n    assert true, '[ruby-dev:39201]'   # reach here or dumps core\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_hash.rb",
    "content": "require 'test/unit'\n\nclass TestHash < Test::Unit::TestCase\n\n  def test_hash\n    x = {1=>2, 2=>4, 3=>6}\n    y = {1, 2, 2, 4, 3, 6}\n\n    assert_equal(2, x[1])\n\n    assert(begin\n         for k,v in y\n           raise if k*2 != v\n         end\n         true\n       rescue\n         false\n       end)\n\n    assert_equal(3, x.length)\n    assert(x.has_key?(1))\n    assert(x.has_value?(4))\n    assert_equal([4,6], x.values_at(2,3))\n    assert_equal({1=>2, 2=>4, 3=>6}, x)\n\n    z = y.keys.join(\":\")\n    assert_equal(\"1:2:3\", z)\n\n    z = y.values.join(\":\")\n    assert_equal(\"2:4:6\", z)\n    assert_equal(x, y)\n\n    y.shift\n    assert_equal(2, y.length)\n\n    z = [1,2]\n    y[z] = 256\n    assert_equal(256, y[z])\n\n    x = Hash.new(0)\n    x[1] = 1\n    assert_equal(1, x[1])\n    assert_equal(0, x[2])\n\n    x = Hash.new([])\n    assert_equal([], x[22])\n    assert_same(x[22], x[22])\n\n    x = Hash.new{[]}\n    assert_equal([], x[22])\n    assert_not_same(x[22], x[22])\n\n    x = Hash.new{|h,k| z = k; h[k] = k*2}\n    z = 0\n    assert_equal(44, x[22])\n    assert_equal(22, z)\n    z = 0\n    assert_equal(44, x[22])\n    assert_equal(0, z)\n    x.default = 5\n    assert_equal(5, x[23])\n\n    x = Hash.new\n    def x.default(k)\n      $z = k\n      self[k] = k*2\n    end\n    $z = 0\n    assert_equal(44, x[22])\n    assert_equal(22, $z)\n    $z = 0\n    assert_equal(44, x[22])\n    assert_equal(0, $z)\n  end\n\n  # From rubicon\n\n  def setup\n    @cls = Hash\n    @h = @cls[\n      1 => 'one', 2 => 'two', 3 => 'three',\n      self => 'self', true => 'true', nil => 'nil',\n      'nil' => nil\n    ]\n  end\n\n  def test_s_AREF\n    h = @cls[\"a\" => 100, \"b\" => 200]\n    assert_equal(100, h['a'])\n    assert_equal(200, h['b'])\n    assert_nil(h['c'])\n\n    h = @cls.[](\"a\" => 100, \"b\" => 200)\n    assert_equal(100, h['a'])\n    assert_equal(200, h['b'])\n    assert_nil(h['c'])\n  end\n\n  def test_s_new\n    h = @cls.new\n    assert_instance_of(@cls, h)\n    assert_nil(h.default)\n    assert_nil(h['spurious'])\n\n    h = @cls.new('default')\n    assert_instance_of(@cls, h)\n    assert_equal('default', h.default)\n    assert_equal('default', h['spurious'])\n    \n  end\n\n  def test_AREF # '[]'\n    t = Time.now\n    h = @cls[\n      1 => 'one', 2 => 'two', 3 => 'three',\n      self => 'self', t => 'time', nil => 'nil',\n      'nil' => nil\n    ]\n\n    assert_equal('one',   h[1])\n    assert_equal('two',   h[2])\n    assert_equal('three', h[3])\n    assert_equal('self',  h[self])\n    assert_equal('time',  h[t])\n    assert_equal('nil',   h[nil])\n    assert_equal(nil,     h['nil'])\n    assert_equal(nil,     h['koala'])\n\n    h1 = h.dup\n    h1.default = :default\n\n    assert_equal('one',    h1[1])\n    assert_equal('two',    h1[2])\n    assert_equal('three',  h1[3])\n    assert_equal('self',   h1[self])\n    assert_equal('time',   h1[t])\n    assert_equal('nil',    h1[nil])\n    assert_equal(nil,      h1['nil'])\n    assert_equal(:default, h1['koala'])\n\n\n  end\n\n  def test_ASET # '[]='\n    t = Time.now\n    h = @cls.new\n    h[1]     = 'one'\n    h[2]     = 'two'\n    h[3]     = 'three'\n    h[self]  = 'self'\n    h[t]     = 'time'\n    h[nil]   = 'nil'\n    h['nil'] = nil\n    assert_equal('one',   h[1])\n    assert_equal('two',   h[2])\n    assert_equal('three', h[3])\n    assert_equal('self',  h[self])\n    assert_equal('time',  h[t])\n    assert_equal('nil',   h[nil])\n    assert_equal(nil,     h['nil'])\n    assert_equal(nil,     h['koala'])\n\n    h[1] = 1\n    h[nil] = 99\n    h['nil'] = nil\n    z = [1,2]\n    h[z] = 256\n    assert_equal(1,       h[1])\n    assert_equal('two',   h[2])\n    assert_equal('three', h[3])\n    assert_equal('self',  h[self])\n    assert_equal('time',  h[t])\n    assert_equal(99,      h[nil])\n    assert_equal(nil,     h['nil'])\n    assert_equal(nil,     h['koala'])\n    assert_equal(256,     h[z])\n  end\n\n  def test_EQUAL # '=='\n    h1 = @cls[ \"a\" => 1, \"c\" => 2 ]\n    h2 = @cls[ \"a\" => 1, \"c\" => 2, 7 => 35 ]\n    h3 = @cls[ \"a\" => 1, \"c\" => 2, 7 => 35 ]\n    h4 = @cls[ ]\n    assert(h1 == h1)\n    assert(h2 == h2)\n    assert(h3 == h3)\n    assert(h4 == h4)\n    assert(!(h1 == h2))\n    assert(h2 == h3)\n    assert(!(h3 == h4))\n  end\n\n  def test_clear\n    assert(@h.size > 0)\n    @h.clear\n    assert_equal(0, @h.size)\n    assert_nil(@h[1])\n  end\n\n  def test_clone\n    for taint in [ false, true ]\n      for frozen in [ false, true ]\n        a = @h.clone\n        a.taint  if taint\n        a.freeze if frozen\n        b = a.clone\n\n        assert_equal(a, b)\n        assert(a.__id__ != b.__id__)\n        assert_equal(a.frozen?, b.frozen?)\n        assert_equal(a.tainted?, b.tainted?)\n      end\n    end\n  end\n\n  def test_default\n    assert_nil(@h.default)\n    h = @cls.new(:xyzzy)\n    assert_equal(:xyzzy, h.default)\n  end\n\n  def test_default=\n    assert_nil(@h.default)\n    @h.default = :xyzzy\n    assert_equal(:xyzzy, @h.default)\n  end\n\n  def test_delete\n    h1 = @cls[ 1 => 'one', 2 => 'two', true => 'true' ]\n    h2 = @cls[ 1 => 'one', 2 => 'two' ]\n    h3 = @cls[ 2 => 'two' ]\n\n    assert_equal('true', h1.delete(true))\n    assert_equal(h2, h1)\n\n    assert_equal('one', h1.delete(1))\n    assert_equal(h3, h1)\n\n    assert_equal('two', h1.delete(2))\n    assert_equal(@cls[], h1)\n\n    assert_nil(h1.delete(99))\n    assert_equal(@cls[], h1)\n\n    assert_equal('default 99', h1.delete(99) {|i| \"default #{i}\" })\n  end\n\n  def test_delete_if\n    base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]\n    h1   = @cls[ 1 => 'one', 2 => false, true => 'true' ]\n    h2   = @cls[ 2 => false, 'cat' => 99 ]\n    h3   = @cls[ 2 => false ]\n\n    h = base.dup\n    assert_equal(h, h.delete_if { false })\n    assert_equal(@cls[], h.delete_if { true })\n\n    h = base.dup\n    assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) })\n    assert_equal(h1, h)\n\n    h = base.dup\n    assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) })\n    assert_equal(h2, h)\n\n    h = base.dup\n    assert_equal(h3, h.delete_if {|k,v| v })\n    assert_equal(h3, h)\n\n    h = base.dup\n    n = 0\n    h.delete_if {|*a|\n      n += 1\n      assert_equal(2, a.size)\n      assert_equal(base[a[0]], a[1])\n      h.shift\n      true\n    }\n    assert_equal(base.size, n)\n  end\n\n  def test_dup\n    for taint in [ false, true ]\n      for frozen in [ false, true ]\n        a = @h.dup\n        a.taint  if taint\n        a.freeze if frozen\n        b = a.dup\n\n        assert_equal(a, b)\n        assert(a.__id__ != b.__id__)\n        assert_equal(false, b.frozen?)\n        assert_equal(a.tainted?, b.tainted?)\n      end\n    end\n  end\n\n  def test_each\n    count = 0\n    @cls[].each { |k, v| count + 1 }\n    assert_equal(0, count)\n\n    h = @h\n    h.each do |k, v|\n      assert_equal(v, h.delete(k))\n    end\n    assert_equal(@cls[], h)\n  end\n\n  def test_each_key\n    count = 0\n    @cls[].each_key { |k| count + 1 }\n    assert_equal(0, count)\n\n    h = @h\n    h.each_key do |k|\n      h.delete(k)\n    end\n    assert_equal(@cls[], h)\n  end\n\n  def test_each_pair\n    count = 0\n    @cls[].each_pair { |k, v| count + 1 }\n    assert_equal(0, count)\n\n    h = @h\n    h.each_pair do |k, v|\n      assert_equal(v, h.delete(k))\n    end\n    assert_equal(@cls[], h)\n  end\n\n  def test_each_value\n    res = []\n    @cls[].each_value { |v| res << v }\n    assert_equal(0, [].length)\n\n    @h.each_value { |v| res << v }\n    assert_equal(0, [].length)\n\n    expected = []\n    @h.each { |k, v| expected << v }\n\n    assert_equal([], expected - res)\n    assert_equal([], res - expected)\n  end\n\n  def test_empty?\n    assert(@cls[].empty?)\n    assert(!@h.empty?)\n  end\n\n  def test_fetch\n    assert_raise(IndexError) { @cls[].fetch(1) }\n    assert_raise(IndexError) { @h.fetch('gumby') }\n    assert_equal('gumbygumby', @h.fetch('gumby') {|k| k * 2 })\n    assert_equal('pokey', @h.fetch('gumby', 'pokey'))\n\n    assert_equal('one', @h.fetch(1))\n    assert_equal(nil, @h.fetch('nil'))\n    assert_equal('nil', @h.fetch(nil))\n  end\n\n  def test_key?\n    assert(!@cls[].key?(1))\n    assert(!@cls[].key?(nil))\n    assert(@h.key?(nil))\n    assert(@h.key?(1))\n    assert(!@h.key?('gumby'))\n  end\n\n  def test_value?\n    assert(!@cls[].value?(1))\n    assert(!@cls[].value?(nil))\n    assert(@h.value?('one'))\n    assert(@h.value?(nil))\n    assert(!@h.value?('gumby'))\n  end\n\n  def test_include?\n    assert(!@cls[].include?(1))\n    assert(!@cls[].include?(nil))\n    assert(@h.include?(nil))\n    assert(@h.include?(1))\n    assert(!@h.include?('gumby'))\n  end\n\n  def test_values_at\n    res = @h.values_at('dog', 'cat', 'horse')\n    assert(res.length == 3)\n    assert_equal([nil, nil, nil], res)\n\n    res = @h.values_at\n    assert(res.length == 0)\n\n    res = @h.values_at(3, 2, 1, nil)\n    assert_equal 4, res.length\n    assert_equal %w( three two one nil ), res\n\n    res = @h.values_at(3, 99, 1, nil)\n    assert_equal 4, res.length\n    assert_equal ['three', nil, 'one', 'nil'], res\n  end\n\n\n  def test_invert\n    h = @h.invert\n    assert_equal(1, h['one'])\n    assert_equal(true, h['true'])\n    assert_equal(nil,  h['nil'])\n\n    h.each do |k, v|\n      assert(@h.key?(v))    # not true in general, but works here\n    end\n\n    h = @cls[ 'a' => 1, 'b' => 2, 'c' => 1].invert\n    assert_equal(2, h.length)\n    assert(h[1] == 'a' || h[1] == 'c')\n    assert_equal('b', h[2])\n  end\n\n  def test_key?\n    assert(!@cls[].key?(1))\n    assert(!@cls[].key?(nil))\n    assert(@h.key?(nil))\n    assert(@h.key?(1))\n    assert(!@h.key?('gumby'))\n  end\n\n  def test_keys\n    assert_equal([], @cls[].keys)\n\n    keys = @h.keys\n    expected = []\n    @h.each { |k, v| expected << k }\n    assert_equal([], keys - expected)\n    assert_equal([], expected - keys)\n  end\n\n  def test_length\n    assert_equal(0, @cls[].length)\n    assert_equal(7, @h.length)\n  end\n\n  def test_member?\n    assert(!@cls[].member?(1))\n    assert(!@cls[].member?(nil))\n    assert(@h.member?(nil))\n    assert(@h.member?(1))\n    assert(!@h.member?('gumby'))\n  end\n\n  def test_rehash\n    a = [ \"a\", \"b\" ]\n    c = [ \"c\", \"d\" ]\n    h = @cls[ a => 100, c => 300 ]\n    assert_equal(100, h[a])\n    a[0] = \"z\"\n    assert_nil(h[a])\n    h.rehash\n    assert_equal(100, h[a])\n  end\n\n  def test_reject\n    base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]\n    h1   = @cls[ 1 => 'one', 2 => false, true => 'true' ]\n    h2   = @cls[ 2 => false, 'cat' => 99 ]\n    h3   = @cls[ 2 => false ]\n\n    h = base.dup\n    assert_equal(h, h.reject { false })\n    assert_equal(@cls[], h.reject { true })\n\n    h = base.dup\n    assert_equal(h1, h.reject {|k,v| k.instance_of?(String) })\n\n    assert_equal(h2, h.reject {|k,v| v.instance_of?(String) })\n\n    assert_equal(h3, h.reject {|k,v| v })\n    assert_equal(base, h)\n  end\n\n  def test_reject!\n    base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]\n    h1   = @cls[ 1 => 'one', 2 => false, true => 'true' ]\n    h2   = @cls[ 2 => false, 'cat' => 99 ]\n    h3   = @cls[ 2 => false ]\n\n    h = base.dup\n    assert_equal(nil, h.reject! { false })\n    assert_equal(@cls[],  h.reject! { true })\n\n    h = base.dup\n    assert_equal(h1, h.reject! {|k,v| k.instance_of?(String) })\n    assert_equal(h1, h)\n\n    h = base.dup\n    assert_equal(h2, h.reject! {|k,v| v.instance_of?(String) })\n    assert_equal(h2, h)\n\n    h = base.dup\n    assert_equal(h3, h.reject! {|k,v| v })\n    assert_equal(h3, h)\n  end\n\n  def test_replace\n    h = @cls[ 1 => 2, 3 => 4 ]\n    h1 = h.replace(@cls[ 9 => 8, 7 => 6 ])\n    assert_equal(h, h1)\n    assert_equal(8, h[9])\n    assert_equal(6, h[7])\n    assert_nil(h[1])\n    assert_nil(h[2])\n  end\n\n  def test_shift\n    h = @h.dup\n    \n    @h.length.times {\n      k, v = h.shift\n      assert(@h.key?(k))\n      assert_equal(@h[k], v)\n    }\n\n    assert_equal(0, h.length)\n  end\n\n  def test_size\n    assert_equal(0, @cls[].length)\n    assert_equal(7, @h.length)\n  end\n\n  def test_sort\n    h = @cls[].sort\n    assert_equal([], h)\n\n    h = @cls[ 1 => 1, 2 => 1 ].sort\n    assert_equal([[1,1], [2,1]], h)\n\n    h = @cls[ 'cat' => 'feline', 'ass' => 'asinine', 'bee' => 'beeline' ]\n    h1 = h.sort\n    assert_equal([ %w(ass asinine), %w(bee beeline), %w(cat feline)], h1)\n  end\n\n  def test_store\n    t = Time.now\n    h = @cls.new\n    h.store(1, 'one')\n    h.store(2, 'two')\n    h.store(3, 'three')\n    h.store(self, 'self')\n    h.store(t,  'time')\n    h.store(nil, 'nil')\n    h.store('nil', nil)\n    assert_equal('one',   h[1])\n    assert_equal('two',   h[2])\n    assert_equal('three', h[3])\n    assert_equal('self',  h[self])\n    assert_equal('time',  h[t])\n    assert_equal('nil',   h[nil])\n    assert_equal(nil,     h['nil'])\n    assert_equal(nil,     h['koala'])\n\n    h.store(1, 1)\n    h.store(nil,  99)\n    h.store('nil', nil)\n    assert_equal(1,       h[1])\n    assert_equal('two',   h[2])\n    assert_equal('three', h[3])\n    assert_equal('self',  h[self])\n    assert_equal('time',  h[t])\n    assert_equal(99,      h[nil])\n    assert_equal(nil,     h['nil'])\n    assert_equal(nil,     h['koala'])\n  end\n\n  def test_to_a\n    assert_equal([], @cls[].to_a)\n    assert_equal([[1,2]], @cls[ 1=>2 ].to_a)\n    a = @cls[ 1=>2, 3=>4, 5=>6 ].to_a\n    assert_equal([1,2], a.delete([1,2]))\n    assert_equal([3,4], a.delete([3,4]))\n    assert_equal([5,6], a.delete([5,6]))\n    assert_equal(0, a.length)\n  end\n\n  def test_to_hash\n    h = @h.to_hash\n    assert_equal(@h, h)\n  end\n\n  def test_to_s\n    h = @cls[ 1 => 2, \"cat\" => \"dog\", 1.5 => :fred ]\n    assert_equal(h.to_a.join, h.to_s)\n    $, = \":\"\n    assert_equal(h.to_a.join, h.to_s)\n    h = @cls[]\n    assert_equal(h.to_a.join, h.to_s)\n    $, = nil\n  end\n\n  def test_update\n    h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]\n    h2 = @cls[ 2 => 'two', 4 => 'four' ]\n\n    ha = @cls[ 1 => 2, 2 => 'two', 3 => 4, 4 => 'four' ]\n    hb = @cls[ 1 => 2, 2 => 3, 3 => 4, 4 => 'four' ]\n\n    assert_equal(ha, h1.update(h2))\n    assert_equal(ha, h1)\n\n    h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]\n    h2 = @cls[ 2 => 'two', 4 => 'four' ]\n\n    assert_equal(hb, h2.update(h1))\n    assert_equal(hb, h2)\n  end\n\n  def test_value?\n    assert(!@cls[].value?(1))\n    assert(!@cls[].value?(nil))\n    assert(@h.value?(nil))\n    assert(@h.value?('one'))\n    assert(!@h.value?('gumby'))\n  end\n\n  def test_values\n    assert_equal([], @cls[].values)\n\n    vals = @h.values\n    expected = []\n    @h.each { |k, v| expected << v }\n    assert_equal([], vals - expected)\n    assert_equal([], expected - vals)\n  end\n\n  def test_hash_hash\n    assert_equal({0=>2,11=>1}.hash, {11=>1,0=>2}.hash)\n  end\n\n  def test_hash_bignum_hash\n    x = 2<<(32-3)-1\n    assert_equal({x=>1}.hash, {x=>1}.hash)\n    x = 2<<(64-3)-1\n    assert_equal({x=>1}.hash, {x=>1}.hash)\n\n    o = Object.new\n    def o.hash; 2<<100; end\n    assert_equal({x=>1}.hash, {x=>1}.hash)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_ifunless.rb",
    "content": "require 'test/unit'\n\nclass TestIfunless < Test::Unit::TestCase\n  def test_if_unless\n    $x = 'test';\n    assert(if $x == $x then true else false end)\n    $bad = false\n    unless $x == $x\n      $bad = true\n    end\n    assert(!$bad)\n    assert(unless $x != $x then true else false end)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_integer.rb",
    "content": "require 'test/unit'\n\nclass TestInteger < Test::Unit::TestCase\n  VS = [\n    -0x1000000000000000000000000000000000000000000000002,\n    -0x1000000000000000000000000000000000000000000000001,\n    -0x1000000000000000000000000000000000000000000000000,\n    -0xffffffffffffffffffffffffffffffffffffffffffffffff,\n    -0x1000000000000000000000002,\n    -0x1000000000000000000000001,\n    -0x1000000000000000000000000,\n    -0xffffffffffffffffffffffff,\n    -0x10000000000000002,\n    -0x10000000000000001,\n    -0x10000000000000000,\n    -0xffffffffffffffff,\n    -0x4000000000000002,\n    -0x4000000000000001,\n    -0x4000000000000000,\n    -0x3fffffffffffffff,\n    -0x100000002,\n    -0x100000001,\n    -0x100000000,\n    -0xffffffff,\n    -0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001\n    -0x80000002,\n    -0x80000001,\n    -0x80000000,\n    -0x7fffffff,\n    -0x524b2245,\n    -0x40000002,\n    -0x40000001,\n    -0x40000000,\n    -0x3fffffff,\n    -0x10002,\n    -0x10001,\n    -0x10000,\n    -0xffff,\n    -0x8101, # 0x8101 * 0x7f01 = 0x40000001\n    -0x8002,\n    -0x8001,\n    -0x8000,\n    -0x7fff,\n    -0x7f01,\n    -65,\n    -64,\n    -63,\n    -62,\n    -33,\n    -32,\n    -31,\n    -30,\n    -3,\n    -2,\n    -1,\n    0,\n    1,\n    2,\n    3,\n    30,\n    31,\n    32,\n    33,\n    62,\n    63,\n    64,\n    65,\n    0x7f01,\n    0x7ffe,\n    0x7fff,\n    0x8000,\n    0x8001,\n    0x8101,\n    0xfffe,\n    0xffff,\n    0x10000,\n    0x10001,\n    0x3ffffffe,\n    0x3fffffff,\n    0x40000000,\n    0x40000001,\n    0x524b2245,\n    0x7ffffffe,\n    0x7fffffff,\n    0x80000000,\n    0x80000001,\n    0xc717a08d,\n    0xfffffffe,\n    0xffffffff,\n    0x100000000,\n    0x100000001,\n    0x3ffffffffffffffe,\n    0x3fffffffffffffff,\n    0x4000000000000000,\n    0x4000000000000001,\n    0xfffffffffffffffe,\n    0xffffffffffffffff,\n    0x10000000000000000,\n    0x10000000000000001,\n    0xffffffffffffffffffffffff,\n    0x1000000000000000000000000,\n    0x1000000000000000000000001,\n    0xffffffffffffffffffffffffffffffffffffffffffffffff,\n    0x1000000000000000000000000000000000000000000000000,\n    0x1000000000000000000000000000000000000000000000001\n  ]\n\n  #VS.map! {|v| 0x4000000000000000.coerce(v)[0] }\n\n  BDSIZE = 0x4000000000000000.coerce(0)[0].size\n  def self.bdsize(x)\n    ((x + 1) / 8 + BDSIZE) / BDSIZE * BDSIZE\n  end\n  def bdsize(x)\n    self.class.bdsize(x)\n  end\n\n  min = -1\n  min *= 2 while min.class == Fixnum\n  FIXNUM_MIN = min/2\n  max = 1\n  max *= 2 while (max-1).class == Fixnum\n  FIXNUM_MAX = max/2-1\n\n  def test_fixnum_range\n    assert_instance_of(Bignum, FIXNUM_MIN-1)\n    assert_instance_of(Fixnum, FIXNUM_MIN)\n    assert_instance_of(Fixnum, FIXNUM_MAX)\n    assert_instance_of(Bignum, FIXNUM_MAX+1)\n  end\n\n  def check_class(n)\n    if FIXNUM_MIN <= n && n <= FIXNUM_MAX\n      assert_instance_of(Fixnum, n)\n    else\n      assert_instance_of(Bignum, n)\n    end\n  end\n\n  def test_aref\n    VS.each {|a|\n      100.times {|i|\n        assert_equal((a >> i).odd? ? 1 : 0, a[i], \"(#{a})[#{i}]\")\n      }\n    }\n    VS.each {|a|\n      VS.each {|b|\n        c = nil\n        assert_nothing_raised(\"(#{a})[#{b}]\") { c = a[b] }\n        check_class(c)\n        if b < 0\n          assert_equal(0, c, \"(#{a})[#{b}]\")\n        else\n          assert_equal((a >> b).odd? ? 1 : 0, c, \"(#{a})[#{b}]\")\n        end\n      }\n    }\n\n    # assert_equal(1, (1 << 0x40000000)[0x40000000], \"[ruby-dev:31271]\")\n    # assert_equal(0, (-1 << 0x40000001)[0x40000000], \"[ruby-dev:31271]\")\n    big_zero = 0x40000000.coerce(0)[0]\n    assert_equal(0, (-0x40000002)[big_zero], \"[ruby-dev:31271]\")\n    assert_equal(1, 0x400000001[big_zero], \"[ruby-dev:31271]\")\n  end\n\n  def test_plus\n    VS.each {|a|\n      VS.each {|b|\n        c = a + b\n        check_class(c)\n        assert_equal(b + a, c, \"#{a} + #{b}\")\n        assert_equal(a, c - b, \"(#{a} + #{b}) - #{b}\")\n        assert_equal(a-~b-1, c, \"#{a} + #{b}\") # Hacker's Delight\n        assert_equal((a^b)+2*(a&b), c, \"#{a} + #{b}\") # Hacker's Delight\n        assert_equal((a|b)+(a&b), c, \"#{a} + #{b}\") # Hacker's Delight\n        assert_equal(2*(a|b)-(a^b), c, \"#{a} + #{b}\") # Hacker's Delight\n      }\n    }\n  end\n\n  def test_minus\n    VS.each {|a|\n      VS.each {|b|\n        c = a - b\n        check_class(c)\n        assert_equal(a, c + b, \"(#{a} - #{b}) + #{b}\")\n        assert_equal(-b, c - a, \"(#{a} - #{b}) - #{a}\")\n        assert_equal(a+~b+1, c, \"#{a} - #{b}\") # Hacker's Delight\n        assert_equal((a^b)-2*(b&~a), c, \"#{a} - #{b}\") # Hacker's Delight\n        assert_equal((a&~b)-(b&~a), c, \"#{a} - #{b}\") # Hacker's Delight\n        assert_equal(2*(a&~b)-(a^b), c, \"#{a} - #{b}\") # Hacker's Delight\n      }\n    }\n  end\n\n  def test_mult\n    VS.each {|a|\n      VS.each {|b|\n        c = a * b\n        check_class(c)\n        assert_equal(b * a, c, \"#{a} * #{b}\")\n        assert_equal(b, c / a, \"(#{a} * #{b}) / #{a}\") if a != 0\n        assert_equal(a.abs * b.abs, (a * b).abs, \"(#{a} * #{b}).abs\")\n        assert_equal((a-100)*(b-100)+(a-100)*100+(b-100)*100+10000, c, \"#{a} * #{b}\")\n        assert_equal((a+100)*(b+100)-(a+100)*100-(b+100)*100+10000, c, \"#{a} * #{b}\")\n      }\n    }\n  end\n\n  def test_divmod\n    VS.each {|a|\n      VS.each {|b|\n        if b == 0\n          assert_raise(ZeroDivisionError) { a.divmod(b) }\n        else\n          q, r = a.divmod(b)\n          check_class(q)\n          check_class(r)\n          assert_equal(a, b*q+r)\n          assert(r.abs < b.abs)\n          assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))\n          assert_equal(q, a/b)\n          assert_equal(q, a.div(b))\n          assert_equal(r, a%b)\n          assert_equal(r, a.modulo(b))\n        end\n      }\n    }\n  end\n\n  def test_pow\n    small_values = VS.find_all {|v| 0 <= v && v < 1000 }\n    VS.each {|a|\n      small_values.each {|b|\n        c = a ** b\n        check_class(c)\n        d = 1\n        b.times { d *= a }\n        assert_equal(d, c, \"(#{a}) ** #{b}\")\n        if a != 0\n          d = c\n          b.times { d /= a }\n          assert_equal(1, d, \"((#{a}) ** #{b}) / #{a} / ...(#{b} times)...\")\n        end\n      }\n    }\n\n    assert_equal(0**-1 == 0, false)\n  end\n\n  def test_not\n    VS.each {|a|\n      b = ~a\n      check_class(b)\n      assert_equal(-1 ^ a, b, \"~#{a}\")\n      assert_equal(-a-1, b, \"~#{a}\") # Hacker's Delight\n      assert_equal(0, a & b, \"#{a} & ~#{a}\")\n      assert_equal(-1, a | b, \"#{a} | ~#{a}\")\n    }\n  end\n\n  def test_or\n    VS.each {|a|\n      VS.each {|b|\n        c = a | b\n        check_class(c)\n        assert_equal(b | a, c, \"#{a} | #{b}\")\n        assert_equal(a + b - (a&b), c, \"#{a} | #{b}\")\n        assert_equal((a & ~b) + b, c, \"#{a} | #{b}\") # Hacker's Delight\n        assert_equal(-1, c | ~a, \"(#{a} | #{b}) | ~#{a})\")\n      }\n    }\n  end\n\n  def test_and\n    VS.each {|a|\n      VS.each {|b|\n        c = a & b\n        check_class(c)\n        assert_equal(b & a, c, \"#{a} & #{b}\")\n        assert_equal(a + b - (a|b), c, \"#{a} & #{b}\")\n        assert_equal((~a | b) - ~a, c, \"#{a} & #{b}\") # Hacker's Delight\n        assert_equal(0, c & ~a, \"(#{a} & #{b}) & ~#{a}\")\n      }\n    }\n  end\n\n  def test_xor\n    VS.each {|a|\n      VS.each {|b|\n        c = a ^ b\n        check_class(c)\n        assert_equal(b ^ a, c, \"#{a} ^ #{b}\")\n        assert_equal((a|b)-(a&b), c, \"#{a} ^ #{b}\") # Hacker's Delight\n        assert_equal(b, c ^ a, \"(#{a} ^ #{b}) ^ #{a}\")\n      }\n    }\n  end\n\n  def test_lshift\n    small_values = VS.find_all {|v| v < 8000 }\n    VS.each {|a|\n      small_values.each {|b|\n        c = a << b\n        check_class(c)\n        if 0 <= b\n          assert_equal(a, c >> b, \"(#{a} << #{b}) >> #{b}\")\n          assert_equal(a * 2**b, c, \"#{a} << #{b}\")\n        end\n        0.upto(c.size*8+10) {|nth|\n          assert_equal(a[nth-b], c[nth], \"(#{a} << #{b})[#{nth}]\")\n        }\n      }\n    }\n    assert_equal(0, 1 << -0x40000000)\n    assert_equal(0, 1 << -0x40000001)\n    assert_equal(0, 1 << -0x80000000)\n    assert_equal(0, 1 << -0x80000001)\n    # assert_equal(bdsize(0x80000000), (1 << 0x80000000).size)\n  end\n\n  def test_rshift\n    small_values = VS.find_all {|v| -8000 < v }\n    VS.each {|a|\n      small_values.each {|b|\n        c = a >> b\n        check_class(c)\n        if b <= 0\n          assert_equal(a, c << b, \"(#{a} >> #{b}) << #{b}\")\n          assert_equal(a * 2**(-b), c, \"#{a} >> #{b}\")\n        end\n        0.upto(c.size*8+10) {|nth|\n          assert_equal(a[nth+b], c[nth], \"(#{a} >> #{b})[#{nth}]\")\n        }\n      }\n    }\n    # assert_equal(bdsize(0x40000001), (1 >> -0x40000001).size)\n    assert((1 >> 0x80000000).zero?)\n    assert((1 >> 0xffffffff).zero?)\n    assert((1 >> 0x100000000).zero?)\n    # assert_equal((1 << 0x40000000), (1 >> -0x40000000))\n    # assert_equal((1 << 0x40000001), (1 >> -0x40000001))\n  end\n\n  def test_succ\n    VS.each {|a|\n      b = a.succ\n      check_class(b)\n      assert_equal(a+1, b, \"(#{a}).succ\")\n      assert_equal(a, b.pred, \"(#{a}).succ.pred\")\n      assert_equal(a, b-1, \"(#{a}).succ - 1\")\n    }\n  end\n\n  def test_pred\n    VS.each {|a|\n      b = a.pred\n      check_class(b)\n      assert_equal(a-1, b, \"(#{a}).pred\")\n      assert_equal(a, b.succ, \"(#{a}).pred.succ\")\n      assert_equal(a, b + 1, \"(#{a}).pred + 1\")\n    }\n  end\n\n  def test_unary_plus\n    VS.each {|a|\n      b = +a\n      check_class(b)\n      assert_equal(a, b, \"+(#{a})\")\n    }\n  end\n\n  def test_unary_minus\n    VS.each {|a|\n      b = -a\n      check_class(b)\n      assert_equal(0-a, b, \"-(#{a})\")\n      assert_equal(~a+1, b, \"-(#{a})\")\n      assert_equal(0, a+b, \"#{a}+(-(#{a}))\")\n    }\n  end\n\n  def test_cmp\n    VS.each_with_index {|a, i|\n      VS.each_with_index {|b, j|\n        assert_equal(i <=> j, a <=> b, \"#{a} <=> #{b}\")\n        assert_equal(i < j, a < b, \"#{a} < #{b}\")\n        assert_equal(i <= j, a <= b, \"#{a} <= #{b}\")\n        assert_equal(i > j, a > b, \"#{a} > #{b}\")\n        assert_equal(i >= j, a >= b, \"#{a} >= #{b}\")\n      }\n    }\n  end\n\n  def test_eq\n    VS.each_with_index {|a, i|\n      VS.each_with_index {|b, j|\n        c = a == b\n        assert_equal(b == a, c, \"#{a} == #{b}\")\n        assert_equal(i == j, c, \"#{a} == #{b}\")\n      }\n    }\n  end\n\n  def test_abs\n    VS.each {|a|\n      b = a.abs\n      check_class(b)\n      if a < 0\n        assert_equal(-a, b, \"(#{a}).abs\")\n      else\n        assert_equal(a, b, \"(#{a}).abs\")\n      end\n    }\n  end\n\n  def test_ceil\n    VS.each {|a|\n      b = a.ceil\n      check_class(b)\n      assert_equal(a, b, \"(#{a}).ceil\")\n    }\n  end\n\n  def test_floor\n    VS.each {|a|\n      b = a.floor\n      check_class(b)\n      assert_equal(a, b, \"(#{a}).floor\")\n    }\n  end\n\n  def test_round\n    VS.each {|a|\n      b = a.round\n      check_class(b)\n      assert_equal(a, b, \"(#{a}).round\")\n    }\n  end\n\n  def test_truncate\n    VS.each {|a|\n      b = a.truncate\n      check_class(b)\n      assert_equal(a, b, \"(#{a}).truncate\")\n    }\n  end\n\n  def test_remainder\n    VS.each {|a|\n      VS.each {|b|\n        if b == 0\n          assert_raise(ZeroDivisionError) { a.divmod(b) }\n        else\n          r = a.remainder(b)\n          check_class(r)\n          if a < 0\n            assert_operator(-b.abs, :<, r, \"#{a}.remainder(#{b})\")\n            assert_operator(0, :>=, r, \"#{a}.remainder(#{b})\")\n          elsif 0 < a\n            assert_operator(0, :<=, r, \"#{a}.remainder(#{b})\")\n            assert_operator(b.abs, :>, r, \"#{a}.remainder(#{b})\")\n          else\n            assert_equal(0, r, \"#{a}.remainder(#{b})\")\n          end\n        end\n      }\n    }\n  end\n\n  def test_zero_nonzero\n    VS.each {|a|\n      z = a.zero?\n      n = a.nonzero?\n      if a == 0\n        assert_equal(true, z, \"(#{a}).zero?\")\n        assert_equal(nil, n, \"(#{a}).nonzero?\")\n      else\n        assert_equal(false, z, \"(#{a}).zero?\")\n        assert_equal(a, n, \"(#{a}).nonzero?\")\n        check_class(n)\n      end\n      assert(z ^ n, \"(#{a}).zero? ^ (#{a}).nonzero?\")\n    }\n  end\n\n  def test_even_odd\n    VS.each {|a|\n      e = a.even?\n      o = a.odd?\n      assert_equal((a % 2) == 0, e, \"(#{a}).even?\")\n      assert_equal((a % 2) == 1, o, \"(#{a}).odd\")\n      assert_equal((a & 1) == 0, e, \"(#{a}).even?\")\n      assert_equal((a & 1) == 1, o, \"(#{a}).odd\")\n      assert(e ^ o, \"(#{a}).even? ^ (#{a}).odd?\")\n    }\n  end\n\n  def test_to_s\n    2.upto(36) {|radix|\n      VS.each {|a|\n        s = a.to_s(radix)\n        b = s.to_i(radix)\n        assert_equal(a, b, \"(#{a}).to_s(#{radix}).to_i(#{radix})\")\n      }\n    }\n  end\n\n  def test_printf_x\n    VS.reverse_each {|a|\n      s = sprintf(\"%x\", a)\n      if /\\A\\.\\./ =~ s\n        b = -($'.tr('0123456789abcdef', 'fedcba9876543210').to_i(16) + 1)\n      else\n        b = s.to_i(16)\n      end\n      assert_equal(a, b, \"sprintf('%x', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_printf_x_sign\n    VS.reverse_each {|a|\n      s = sprintf(\"%+x\", a)\n      b = s.to_i(16)\n      assert_equal(a, b, \"sprintf('%+x', #{a}) = #{s.inspect}\")\n      s = sprintf(\"% x\", a)\n      b = s.to_i(16)\n      assert_equal(a, b, \"sprintf('% x', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_printf_o\n    VS.reverse_each {|a|\n      s = sprintf(\"%o\", a)\n      if /\\A\\.\\./ =~ s\n        b = -($'.tr('01234567', '76543210').to_i(8) + 1)\n      else\n        b = s.to_i(8)\n      end\n      assert_equal(a, b, \"sprintf('%o', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_printf_o_sign\n    VS.reverse_each {|a|\n      s = sprintf(\"%+o\", a)\n      b = s.to_i(8)\n      assert_equal(a, b, \"sprintf('%+o', #{a}) = #{s.inspect}\")\n      s = sprintf(\"% o\", a)\n      b = s.to_i(8)\n      assert_equal(a, b, \"sprintf('% o', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_printf_b\n    VS.reverse_each {|a|\n      s = sprintf(\"%b\", a)\n      if /\\A\\.\\./ =~ s\n        b = -($'.tr('01', '10').to_i(2) + 1)\n      else\n        b = s.to_i(2)\n      end\n      assert_equal(a, b, \"sprintf('%b', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_printf_b_sign\n    VS.reverse_each {|a|\n      s = sprintf(\"%+b\", a)\n      b = s.to_i(2)\n      assert_equal(a, b, \"sprintf('%+b', #{a}) = #{s.inspect}\")\n      s = sprintf(\"% b\", a)\n      b = s.to_i(2)\n      assert_equal(a, b, \"sprintf('% b', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_printf_di\n    VS.reverse_each {|a|\n      s = sprintf(\"%d\", a)\n      b = s.to_i\n      assert_equal(a, b, \"sprintf('%d', #{a}) = #{s.inspect}\")\n      s = sprintf(\"%i\", a)\n      b = s.to_i\n      assert_equal(a, b, \"sprintf('%i', #{a}) = #{s.inspect}\")\n    }\n  end\n\n  def test_marshal\n    VS.reverse_each {|a|\n      s = Marshal.dump(a)\n      b = Marshal.load(s)\n      assert_equal(a, b, \"Marshal.load(Marshal.dump(#{a}))\")\n    }\n  end\n\n  def test_pack_ber\n    template = \"w\"\n    VS.reverse_each {|a|\n      if a < 0\n        assert_raise(ArgumentError) { [a].pack(template) }\n      else\n        s = [a].pack(template)\n        b = s.unpack(template)[0]\n        assert_equal(a, b, \"[#{a}].pack(#{template.dump}).unpack(#{template.dump})\")\n      end\n    }\n  end\n\n  def test_pack_utf8\n    template = \"U\"\n    VS.reverse_each {|a|\n      if a < 0 || 0x7fffffff < a\n        assert_raise(RangeError) { [a].pack(template) }\n      else\n        s = [a].pack(template)\n        b = s.unpack(template)[0]\n        assert_equal(a, b, \"[#{a}].pack(#{template.dump}).unpack(#{template.dump})\")\n      end\n    }\n  end\n\n  def test_Integer\n    assert_raise(ArgumentError) {Integer(\"0x-1\")}\n    assert_raise(ArgumentError) {Integer(\"-0x-1\")}\n    assert_raise(ArgumentError) {Integer(\"0x     123\")}\n    assert_raise(ArgumentError) {Integer(\"0x      123\")}\n    assert_raise(ArgumentError) {Integer(\"0x0x5\")}\n    assert_raise(ArgumentError) {Integer(\"0x0x000000005\")}\n    assert_nothing_raised(ArgumentError) {\n      assert_equal(1540841, \"0x0x5\".to_i(36))\n    }\n    assert_raise(ArgumentError) { Integer(\"--0\") }\n    assert_raise(ArgumentError) { Integer(\"-+0\") }\n    assert_raise(ArgumentError) { Integer(\"++1\") }\n    assert_raise(ArgumentError) { Integer(\"\") }\n    assert_raise(ArgumentError) { Integer(\"10  x\") }\n    assert_raise(ArgumentError) { Integer(\"1__2\") }\n    assert_raise(ArgumentError) { Integer(\"1z\") }\n    assert_raise(ArgumentError) { Integer(\"46116860184273__87904\") }\n    assert_raise(ArgumentError) { Integer(\"4611686018427387904_\") }\n    assert_raise(ArgumentError) { Integer(\"4611686018427387904  :\") }\n    assert_equal(0x4000000000000000, Integer(\"46_11_686_0184273_87904\"))\n    assert_raise(ArgumentError) { Integer(\"\\0\") }\n    assert_nothing_raised(ArgumentError, \"[ruby-core:13873]\") {\n      assert_equal(0, Integer(\"0 \"))\n    }\n    assert_nothing_raised(ArgumentError, \"[ruby-core:14139]\") {\n      assert_equal(0377, Integer(\"0_3_7_7\"))\n    }\n    assert_raise(ArgumentError, \"[ruby-core:14139]\") {Integer(\"0__3_7_7\")}\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_io.rb",
    "content": "require 'test/unit'\nrequire 'tmpdir'\nrequire 'tempfile'\n\nclass TestIO < Test::Unit::TestCase\n  def mkcdtmpdir\n    Dir.mktmpdir {|d|\n      Dir.chdir(d) {\n        yield\n      }\n    }\n  end\n\n  def test_gets_rs\n    r, w = IO.pipe\n    w.print \"\\377xyz\"\n    w.close\n    assert_equal(\"\\377\", r.gets(\"\\377\"), \"[ruby-dev:24460]\")\n    r.close\n  end\n\n  def test_readpartial_pos\n    mkcdtmpdir {\n      open(\"foo\", \"w\") {|f| f << \"abc\" }\n      open(\"foo\") {|f|\n        f.seek(0)\n        assert_equal(\"ab\", f.readpartial(2))\n        assert_equal(2, f.pos)\n      }\n    }\n  end\n\n  def make_tempfile\n    t = Tempfile.new(\"foo\")\n    t.binmode\n    t.puts \"foo\"\n    t.puts \"bar\"\n    t.puts \"baz\"\n    t.close\n    t\n  end\n\n  def test_binmode_after_closed\n    t = make_tempfile\n    t.close\n    assert_raise(IOError) {t.binmode}\n  end\n\n  def test_pos\n    t = make_tempfile\n\n    open(t.path, IO::RDWR|IO::CREAT|IO::TRUNC, 0600) do |f|\n      f.write \"Hello\"\n      assert_equal(5, f.pos)\n    end\n    open(t.path, IO::RDWR|IO::CREAT|IO::TRUNC, 0600) do |f|\n      f.sync = true\n      f.read\n      f.write \"Hello\"\n      assert_equal(5, f.pos)\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_iterator.rb",
    "content": "require 'test/unit'\n\nclass Array\n  def iter_test1\n    collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}\n  end\n  def iter_test2\n    a = collect{|e| [e, yield(e)]}\n    a.sort{|a,b|a[1]<=>b[1]}\n  end\nend\n\nclass TestIterator < Test::Unit::TestCase\n  def ttt\n    assert(iterator?)\n  end\n\n  def test_iterator\n    assert(!iterator?)\n\n    ttt{}\n\n    # yield at top level\t!! here's not toplevel\n    assert(!defined?(yield))\n  end\n\n  def test_array\n    $x = [1, 2, 3, 4]\n    $y = []\n\n    # iterator over array\n    for i in $x\n      $y.push i\n    end\n    assert_equal($x, $y)\n  end\n\n  def tt\n    1.upto(10) {|i|\n      yield i\n    }\n  end\n\n  def tt2(dummy)\n    yield 1\n  end\n\n  def tt3(&block)\n    tt2(raise(ArgumentError,\"\"),&block)\n  end\n\n  def test_nested_iterator\n    i = 0\n    tt{|i| break if i == 5}\n    assert_equal(5, i)\n\n    assert_raises(ArgumentError) do\n      tt3{}\n    end\n  end\n\n  def tt4 &block\n    tt2(raise(ArgumentError,\"\"),&block)\n  end\n\n  def test_block_argument_without_paren\n    assert_raises(ArgumentError) do\n      tt4{}\n    end\n  end\n\n  # iterator break/redo/next/retry\n  def test_break\n    done = true\n    loop{\n      break\n      done = false\t\t\t# should not reach here\n    }\n    assert(done)\n\n    done = false\n    $bad = false\n    loop {\n      break if done\n      done = true\n      next\n      $bad = true\t\t\t# should not reach here\n    }\n    assert(!$bad)\n\n    done = false\n    $bad = false\n    loop {\n      break if done\n      done = true\n      redo\n      $bad = true\t\t\t# should not reach here\n    }\n    assert(!$bad)\n\n    $x = []\n    for i in 1 .. 7\n      $x.push i\n    end\n    assert_equal(7, $x.size)\n    assert_equal([1, 2, 3, 4, 5, 6, 7], $x)\n\n    $done = false\n    $x = []\n    for i in 1 .. 7\t\t\t# see how retry works in iterator loop\n      if i == 4 and not $done\n\t$done = true\n\tretry\n      end\n      $x.push(i)\n    end\n    assert_equal(10, $x.size)\n    assert_equal([1, 2, 3, 1, 2, 3, 4, 5, 6, 7], $x)\n  end\n\n  def test_append_method_to_built_in_class\n    $x = [[1,2],[3,4],[5,6]]\n    assert_equal($x.iter_test1{|x|x}, $x.iter_test2{|x|x})\n  end\n\n  class IterTest\n    def initialize(e); @body = e; end\n\n    def each0(&block); @body.each(&block); end\n    def each1(&block); @body.each {|*x| block.call(*x) } end\n    def each2(&block); @body.each {|*x| block.call(x) } end\n    def each3(&block); @body.each {|x| block.call(*x) } end\n    def each4(&block); @body.each {|x| block.call(x) } end\n    def each5; @body.each {|*x| yield(*x) } end\n    def each6; @body.each {|*x| yield(x) } end\n    def each7; @body.each {|x| yield(*x) } end\n    def each8; @body.each {|x| yield(x) } end\n\n    def f(a)\n      a\n    end\n  end\n\n  def test_itertest\n    assert_equal([1], IterTest.new(nil).method(:f).to_proc.call([1]))\n    m = /\\w+/.match(\"abc\")\n    assert_equal([m], IterTest.new(nil).method(:f).to_proc.call([m]))\n\n    IterTest.new([0]).each0 {|x| assert_equal(0, x)}\n    IterTest.new([1]).each1 {|x| assert_equal(1, x)}\n    IterTest.new([2]).each2 {|x| assert_equal([2], x)}\n    IterTest.new([3]).each3 {|x| assert_equal(3, x)}\n    IterTest.new([4]).each4 {|x| assert_equal(4, x)}\n    IterTest.new([5]).each5 {|x| assert_equal(5, x)}\n    IterTest.new([6]).each6 {|x| assert_equal([6], x)}\n    IterTest.new([7]).each7 {|x| assert_equal(7, x)}\n    IterTest.new([8]).each8 {|x| assert_equal(8, x)}\n\n    IterTest.new([[0]]).each0 {|x| assert_equal([0], x)}\n    IterTest.new([[1]]).each1 {|x| assert_equal([1], x)}\n    IterTest.new([[2]]).each2 {|x| assert_equal([[2]], x)}\n    IterTest.new([[3]]).each3 {|x| assert_equal(3, x)}\n    IterTest.new([[4]]).each4 {|x| assert_equal([4], x)}\n    IterTest.new([[5]]).each5 {|x| assert_equal([5], x)}\n    IterTest.new([[6]]).each6 {|x| assert_equal([[6]], x)}\n    IterTest.new([[7]]).each7 {|x| assert_equal(7, x)}\n    IterTest.new([[8]]).each8 {|x| assert_equal([8], x)}\n\n    IterTest.new([[0,0]]).each0 {|x| assert_equal([0,0], x)}\n    IterTest.new([[8,8]]).each8 {|x| assert_equal([8,8], x)}\n  end\n\n  def m(var)\n    var\n  end\n\n  def m1\n    m(block_given?)\n  end\n\n  def m2\n    m(block_given?,&proc{})\n  end\n\n  def test_block_given\n    assert(m1{p 'test'})\n    assert(m2{p 'test'})\n    assert(!m1())\n    assert(!m2())\n  end\n\n  def m3(var, &block)\n    m(yield(var), &block)\n  end\n\n  def m4(&block)\n    m(m1(), &block)\n  end\n\n  def test_block_passing\n    assert(!m4())\n    assert(!m4 {})\n    assert_equal(100, m3(10) {|x|x*x})\n  end\n\n  class C\n    include Enumerable\n    def initialize\n      @a = [1,2,3]\n    end\n    def each(&block)\n      @a.each(&block)\n    end\n  end\n\n  def test_collect\n    assert_equal([1,2,3], C.new.collect{|n| n})\n  end\n\n  def test_proc\n    assert_instance_of(Proc, lambda{})\n    assert_instance_of(Proc, Proc.new{})\n    lambda{|a|assert_equal(a, 1)}.call(1)\n  end\n\n  def test_block\n    assert_instance_of(NilClass, get_block)\n    assert_instance_of(Proc, get_block{})\n  end\n\n  def test_argument\n    assert_nothing_raised {lambda{||}.call}\n    assert_raises(ArgumentError) {lambda{||}.call(1)}\n    assert_nothing_raised {lambda{|a,|}.call(1)}\n    assert_raises(ArgumentError) {lambda{|a,|}.call()}\n    assert_raises(ArgumentError) {lambda{|a,|}.call(1,2)}\n  end\n\n  def get_block(&block)\n    block\n  end\n\n  def test_get_block\n    assert_instance_of(Proc, get_block{})\n    assert_nothing_raised {get_block{||}.call()}\n    assert_nothing_raised {get_block{||}.call(1)}\n    assert_nothing_raised {get_block{|a,|}.call(1)}\n    assert_nothing_raised {get_block{|a,|}.call()}\n    assert_nothing_raised {get_block{|a,|}.call(1,2)}\n\n    assert_nothing_raised {get_block(&lambda{||}).call()}\n    assert_raises(ArgumentError) {get_block(&lambda{||}).call(1)}\n    assert_nothing_raised {get_block(&lambda{|a,|}).call(1)}\n    assert_raises(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)}\n\n    block = get_block{11}\n    assert_instance_of(Proc, block)\n    assert_instance_of(Proc, block.to_proc)\n    assert_equal(block.clone.call, 11)\n    assert_instance_of(Proc, get_block(&block))\n\n    lambda = lambda{44}\n    assert_instance_of(Proc, lambda)\n    assert_instance_of(Proc, lambda.to_proc)\n    assert_equal(lambda.clone.call, 44)\n    assert_instance_of(Proc, get_block(&lambda))\n\n    assert_equal(1, Proc.new{|a,| a}.call(1,2,3))\n    assert_nothing_raised {Proc.new{|a,|}.call(1,2)}\n  end\n\n  def return1_test\n    Proc.new {\n      return 55\n    }.call + 5\n  end\n\n  def test_return1\n    assert_equal(55, return1_test())\n  end\n\n  def return2_test\n    lambda {\n      return 55\n    }.call + 5\n  end\n\n  def test_return2\n    assert_equal(60, return2_test())\n  end\n\n  def proc_call(&b)\n    b.call\n  end\n  def proc_yield()\n    yield\n  end\n  def proc_return1\n    proc_call{return 42}+1\n  end\n\n  def test_proc_return1\n    assert_equal(42, proc_return1())\n  end\n\n  def proc_return2\n    proc_yield{return 42}+1\n  end\n\n  def test_proc_return2\n    assert_equal(42, proc_return2())\n  end\n\n  def test_ljump\n    block = get_block{11}\n    lambda = lambda{44}\n    assert_raises(LocalJumpError) {get_block{break}.call}\n    assert_nothing_raised {lambda{break}.call}\n    assert_instance_of(LocalJumpError, (get_block{break}.call rescue $!))\n\n    assert_equal(-1, block.arity)\n    assert_equal(-1, lambda.arity)\n    assert_equal(0, lambda{||}.arity)\n    assert_equal(1, lambda{|a|}.arity)\n    assert_equal(1, lambda{|a,|}.arity)\n    assert_equal(2, lambda{|a,b|}.arity)\n  end\n\n  def marity_test(m)\n    method = method(m)\n    assert_equal(method.arity, method.to_proc.arity)\n  end\n\n  def test_marity\n    marity_test(:assert)\n    marity_test(:marity_test)\n    marity_test(:p)\n\n    lambda(&method(:assert)).call(true)\n    lambda(&get_block{|a,n| assert(a,n)}).call(true, \"marity\")\n  end\n\n  def foo\n    yield([:key, :value])\n  end\n  def bar(&blk)\n    blk.call([:key, :value])\n  end\n\n  def test_yield_vs_call\n    foo{|k,v| assert_equal([:key, :value], [k,v])}\n    bar{|k,v| assert_equal([:key, :value], [k,v])}\n  end\n\n  class H\n    def each\n      yield [:key, :value]\n    end\n  end\n\n  def test_assoc_yield\n    [{:key=>:value}, H.new].each {|h|\n      h.each{|a| assert_equal([:key, :value], a)}\n      h.each{|*a| assert_equal([[:key, :value]], a)}\n      h.each{|k,v| assert_equal([:key, :value], [k,v])}\n    }\n  end\n\n  class ITER_TEST1\n    def a\n      block_given?\n    end\n  end\n\n  class ITER_TEST2 < ITER_TEST1\n    include Test::Unit::Assertions\n    def a\n      assert(super)\n      super\n    end\n  end\n\n  def test_iter_test2\n    assert(ITER_TEST2.new.a {})\n  end\n\n  class ITER_TEST3\n    def foo x\n      return yield if block_given?\n      x\n    end\n  end\n\n  class ITER_TEST4 < ITER_TEST3\n    include Test::Unit::Assertions\n    def foo x\n      assert_equal(super, yield)\n      assert_equal(x, super(x, &nil))\n    end\n  end\n\n  def test_iter4\n    ITER_TEST4.new.foo(44){55}\n  end\n\n  def test_break__nested_loop1\n    _test_break__nested_loop1 do\n      break\n    end\n  end\n\n  def _test_break__nested_loop1\n    while true\n      yield\n    end\n    assert(false, \"must not reach here\")\n  end\n\n  def test_break__nested_loop2\n    _test_break__nested_loop2 do\n      break\n    end\n  end\n\n  def _test_break__nested_loop2\n    until false\n      yield\n    end\n    assert(false, \"must not reach here\")\n  end\n\n  def test_break__nested_loop3\n    _test_break__nested_loop3 do\n      break\n    end\n  end\n\n  def _test_break__nested_loop3\n    loop do\n      yield\n    end\n    assert(false, \"must not reach here\")\n  end\n\n  def test_break_from_enum\n    result = [\"a\"].inject(\"ng\") {|x,y| break \"ok\"}\n    assert_equal(\"ok\", result)\n  end\n\n  def _test_return_trace_func(x)\n    set_trace_func(proc {})\n    [].fetch(2) {return x}\n  ensure\n    set_trace_func(nil)\n  end\n\n  def test_return_trace_func\n    ok = \"returned gracefully\"\n    result = \"skipped\"\n    result = _test_return_trace_func(ok)\n  ensure\n    assert_equal(ok, result)\n    return\n  end\n\n  class IterString < ::String\n    def ===(other)\n      super if !block_given?\n    end\n  end\n\n  # Check that the block passed to an iterator\n  # does not get propagated inappropriately\n  def test_block_given_within_iterator\n    assert_equal([\"b\"], [\"a\", \"b\", \"c\"].grep(IterString.new(\"b\")) {|s| s})\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_marshal.rb",
    "content": "require 'test/unit'\ndir = File.dirname(File.expand_path(__FILE__))\norgpath = $:.dup\nbegin\n  $:.push(dir)\n  require 'marshaltestlib'\nensure\n  $:.replace(orgpath)\nend\n\nclass TestMarshal < Test::Unit::TestCase\n  include MarshalTestLib\n\n  def encode(o)\n    stress, GC.stress = GC.stress, true\n    Marshal.dump(o)\n  ensure\n    GC.stress = stress\n  end\n\n  def decode(s)\n    stress, GC.stress = GC.stress, true\n    Marshal.load(s)\n  ensure\n    GC.stress = stress\n  end\n\n  def fact(n)\n    return 1 if n == 0\n    f = 1\n    while n>0\n      f *= n\n      n -= 1\n    end\n    return f\n  end\n\n  StrClone=String.clone;\n\n  def test_marshal\n    $x = [1,2,3,[4,5,\"foo\"],{1=>\"bar\"},2.5,fact(30)]\n    $y = Marshal.dump($x)\n    assert_equal($x, Marshal.load($y))\n\n    assert_instance_of(StrClone, Marshal.load(Marshal.dump(StrClone.new(\"abc\"))))\n\n    [[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|\n      a = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))\n      ma = Marshal.dump(a)\n      b = Marshal.load(ma)\n      assert_equal(a, b)\n    }\n  end\n\n  class C\n    def initialize(str)\n      @str = str\n    end\n    def _dump(limit)\n      @str\n    end\n    def self._load(s)\n      new(s)\n    end\n  end\n\n  def test_too_long_string\n    (data = Marshal.dump(C.new(\"a\")))[-2, 1] = \"\\003\\377\\377\\377\"\n    e = assert_raise(ArgumentError, \"[ruby-dev:32054]\") {\n      Marshal.load(data)\n    }\n    assert_equal(\"marshal data too short\", e.message)\n  end\n\n  class DumpTest\n    def marshal_dump\n      loop { Thread.pass }\n    end\n  end\n\n  class LoadTest\n    def marshal_dump\n      nil\n    end\n    def marshal_load(obj)\n      loop { Thread.pass }\n    end\n  end\n\n  def test_context_switch\n    o = DumpTest.new\n    Thread.new { Marshal.dump(o) }\n    GC.start\n    assert(true, '[ruby-dev:39425]')\n\n    o = LoadTest.new\n    m = Marshal.dump(o)\n    Thread.new { Marshal.load(m) }\n    GC.start\n    assert(true, '[ruby-dev:39425]')\n  end\n\n  def test_taint\n    x = Object.new\n    x.taint\n    s = Marshal.dump(x)\n    assert_equal(true, s.tainted?)\n    y = Marshal.load(s)\n    assert_equal(true, y.tainted?)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_math.rb",
    "content": "require 'test/unit'\n\nclass TestMath < Test::Unit::TestCase\n  def test_math\n    assert_equal(2, Math.sqrt(4))\n\n    self.class.class_eval {\n      include Math\n    }\n    assert_equal(2, sqrt(4))\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_method.rb",
    "content": "require 'test/unit'\n\nclass TestMethod < Test::Unit::TestCase\n  def m0() end\n  def m1(a) end\n  def m2(a, b) end\n  def mo1(a = nil, &b) end\n  def mo2(a, b = nil) end\n  def mo3(*a) end\n  def mo4(a, *b, &c) end\n\n  class Base\n    def foo() :base end\n  end\n  class Derived < Base\n    def foo() :derived end\n  end\n\n  def test_arity\n    assert_equal(0, method(:m0).arity)\n    assert_equal(1, method(:m1).arity)\n    assert_equal(2, method(:m2).arity)\n    assert_equal(-1, method(:mo1).arity)\n    assert_equal(-2, method(:mo2).arity)\n    assert_equal(-1, method(:mo3).arity)\n    assert_equal(-2, method(:mo4).arity)\n  end\n\n  def test_unbind\n    assert_equal(:derived, Derived.new.foo)\n    um = Derived.new.method(:foo).unbind\n    assert_instance_of(UnboundMethod, um)\n    Derived.class_eval do\n      def foo() :changed end\n    end\n    assert_equal(:changed, Derived.new.foo)\n    assert_equal(:derived, um.bind(Derived.new).call)\n    assert_raise(TypeError) do\n      um.bind(Base.new)\n    end\n  end\n\n  def test_receiver_name_owner\n    o = Object.new\n    def o.foo; end\n    m = o.method(:foo)\n    assert_equal(o, m.receiver)\n    assert_equal(\"foo\", m.name)\n    assert_equal(class << o; self; end, m.owner)\n    assert_equal(\"foo\", m.unbind.name)\n    assert_equal(class << o; self; end, m.unbind.owner)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_objectspace.rb",
    "content": "require 'test/unit'\n\nclass TestObjectSpace < Test::Unit::TestCase\n  def self.deftest_id2ref(obj)\n    /:(\\d+)/ =~ caller[0]\n    file = $`\n    line = $1.to_i\n    code = <<\"End\"\n    define_method(\"test_id2ref_#{line}\") {\\\n      o = ObjectSpace._id2ref(obj.object_id);\\\n      assert_same(obj, o, \"didn't round trip: \\#{obj.inspect}\");\\\n    }\nEnd\n    eval code, binding, file, line\n  end\n\n  deftest_id2ref(-0x4000000000000001)\n  deftest_id2ref(-0x4000000000000000)\n  deftest_id2ref(-0x40000001)\n  deftest_id2ref(-0x40000000)\n  deftest_id2ref(-1)\n  deftest_id2ref(0)\n  deftest_id2ref(1)\n  deftest_id2ref(0x3fffffff)\n  deftest_id2ref(0x40000000)\n  deftest_id2ref(0x3fffffffffffffff)\n  deftest_id2ref(0x4000000000000000)\n  deftest_id2ref(:a)\n  deftest_id2ref(:abcdefghijilkjl)\n  deftest_id2ref(:==)\n  deftest_id2ref(Object.new)\n  deftest_id2ref(self)\n  deftest_id2ref(true)\n  deftest_id2ref(false)\n  deftest_id2ref(nil)\nend\n"
  },
  {
    "path": "test/ruby/test_pack.rb",
    "content": "require 'test/unit'\n\nclass TestPack < Test::Unit::TestCase\n  def test_pack\n    $format = \"c2x5CCxsdils_l_a6\";\n    # Need the expression in here to force ary[5] to be numeric.  This avoids\n    # test2 failing because ary2 goes str->numeric->str and ary does not.\n    ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,\"abcdef\"]\n    $x = ary.pack($format)\n    ary2 = $x.unpack($format)\n\n    assert_equal(ary.length, ary2.length)\n    assert_equal(ary.join(':'), ary2.join(':'))\n    assert_match(/def/, $x)\n\n    $x = [-1073741825]\n    assert_equal($x, $x.pack(\"q\").unpack(\"q\"))\n\n    $x = [-1]\n    assert_equal($x, $x.pack(\"l\").unpack(\"l\"))\n  end\n\n  def test_pack_N\n    assert_equal \"\\000\\000\\000\\000\", [0].pack('N')\n    assert_equal \"\\000\\000\\000\\001\", [1].pack('N')\n    assert_equal \"\\000\\000\\000\\002\", [2].pack('N')\n    assert_equal \"\\000\\000\\000\\003\", [3].pack('N')\n    assert_equal \"\\377\\377\\377\\376\", [4294967294].pack('N')\n    assert_equal \"\\377\\377\\377\\377\", [4294967295].pack('N')\n\n    assert_equal \"\\200\\000\\000\\000\", [2**31].pack('N')\n    assert_equal \"\\177\\377\\377\\377\", [-2**31-1].pack('N')\n    assert_equal \"\\377\\377\\377\\377\", [-1].pack('N')\n\n    assert_equal \"\\000\\000\\000\\001\\000\\000\\000\\001\", [1,1].pack('N*')\n    assert_equal \"\\000\\000\\000\\001\\000\\000\\000\\001\\000\\000\\000\\001\", [1,1,1].pack('N*')\n  end\n\n  def test_unpack_N\n    assert_equal 1, \"\\000\\000\\000\\001\".unpack('N')[0]\n    assert_equal 2, \"\\000\\000\\000\\002\".unpack('N')[0]\n    assert_equal 3, \"\\000\\000\\000\\003\".unpack('N')[0]\n    assert_equal 3, \"\\000\\000\\000\\003\".unpack('N')[0]\n    assert_equal 4294967295, \"\\377\\377\\377\\377\".unpack('N')[0]\n    assert_equal [1,1], \"\\000\\000\\000\\001\\000\\000\\000\\001\".unpack('N*')\n    assert_equal [1,1,1], \"\\000\\000\\000\\001\\000\\000\\000\\001\\000\\000\\000\\001\".unpack('N*')\n  end\n\n  def test_pack_U\n    assert_raises(RangeError) { [-0x40000001].pack(\"U\") }\n    assert_raises(RangeError) { [-0x40000000].pack(\"U\") }\n    assert_raises(RangeError) { [-1].pack(\"U\") }\n    assert_equal \"\\000\", [0].pack(\"U\")\n    assert_equal \"\\374\\277\\277\\277\\277\\277\", [0x3fffffff].pack(\"U\")\n    assert_equal \"\\375\\200\\200\\200\\200\\200\", [0x40000000].pack(\"U\")\n    assert_equal \"\\375\\277\\277\\277\\277\\277\", [0x7fffffff].pack(\"U\")\n    assert_raises(RangeError) { [0x80000000].pack(\"U\") }\n    assert_raises(RangeError) { [0x100000000].pack(\"U\") }\n  end\n\n  def test_pack_unpack_hH\n    assert_equal(\"\\x01\\xfe\", [\"10ef\"].pack(\"h*\"))\n    assert_equal(\"\", [\"10ef\"].pack(\"h0\"))\n    assert_equal(\"\\x01\\x0e\", [\"10ef\"].pack(\"h3\"))\n    assert_equal(\"\\x01\\xfe\\x0\", [\"10ef\"].pack(\"h5\"))\n    assert_equal(\"\\xff\\x0f\", [\"fff\"].pack(\"h3\"))\n    assert_equal(\"\\xff\\x0f\", [\"fff\"].pack(\"h4\"))\n    assert_equal(\"\\xff\\x0f\\0\", [\"fff\"].pack(\"h5\"))\n    assert_equal(\"\\xff\\x0f\\0\", [\"fff\"].pack(\"h6\"))\n    assert_equal(\"\\xff\\x0f\\0\\0\", [\"fff\"].pack(\"h7\"))\n    assert_equal(\"\\xff\\x0f\\0\\0\", [\"fff\"].pack(\"h8\"))\n\n    assert_equal(\"\\x10\\xef\", [\"10ef\"].pack(\"H*\"))\n    assert_equal(\"\", [\"10ef\"].pack(\"H0\"))\n    assert_equal(\"\\x10\\xe0\", [\"10ef\"].pack(\"H3\"))\n    assert_equal(\"\\x10\\xef\\x0\", [\"10ef\"].pack(\"H5\"))\n    assert_equal(\"\\xff\\xf0\", [\"fff\"].pack(\"H3\"))\n    assert_equal(\"\\xff\\xf0\", [\"fff\"].pack(\"H4\"))\n    assert_equal(\"\\xff\\xf0\\0\", [\"fff\"].pack(\"H5\"))\n    assert_equal(\"\\xff\\xf0\\0\", [\"fff\"].pack(\"H6\"))\n    assert_equal(\"\\xff\\xf0\\0\\0\", [\"fff\"].pack(\"H7\"))\n    assert_equal(\"\\xff\\xf0\\0\\0\", [\"fff\"].pack(\"H8\"))\n\n    assert_equal([\"10ef\"], \"\\x01\\xfe\".unpack(\"h*\"))\n    assert_equal([\"\"], \"\\x01\\xfe\".unpack(\"h0\"))\n    assert_equal([\"1\"], \"\\x01\\xfe\".unpack(\"h1\"))\n    assert_equal([\"10\"], \"\\x01\\xfe\".unpack(\"h2\"))\n    assert_equal([\"10e\"], \"\\x01\\xfe\".unpack(\"h3\"))\n    assert_equal([\"10ef\"], \"\\x01\\xfe\".unpack(\"h4\"))\n    assert_equal([\"10ef\"], \"\\x01\\xfe\".unpack(\"h5\"))\n\n    assert_equal([\"10ef\"], \"\\x10\\xef\".unpack(\"H*\"))\n    assert_equal([\"\"], \"\\x10\\xef\".unpack(\"H0\"))\n    assert_equal([\"1\"], \"\\x10\\xef\".unpack(\"H1\"))\n    assert_equal([\"10\"], \"\\x10\\xef\".unpack(\"H2\"))\n    assert_equal([\"10e\"], \"\\x10\\xef\".unpack(\"H3\"))\n    assert_equal([\"10ef\"], \"\\x10\\xef\".unpack(\"H4\"))\n    assert_equal([\"10ef\"], \"\\x10\\xef\".unpack(\"H5\"))\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_path.rb",
    "content": "require 'test/unit'\n\nclass TestPath < Test::Unit::TestCase\n  def test_path\n    assert_equal(\"a\", File.basename(\"a\"))\n    assert_equal(\"b\", File.basename(\"a/b\"))\n    assert_equal(\"b\", File.basename(\"a/b/\"))\n    assert_equal(\"/\", File.basename(\"/\"))\n    assert_equal(\"/\", File.basename(\"//\"))\n    assert_equal(\"/\", File.basename(\"///\"))\n    assert_equal(\"b\", File.basename(\"a/b////\"))\n    assert_equal(\"a\", File.basename(\"a.rb\", \".rb\"))\n    assert_equal(\"a\", File.basename(\"a.rb///\", \".rb\"))\n    assert_equal(\"a\", File.basename(\"a.rb///\", \".*\"))\n    assert_equal(\"a.rb\", File.basename(\"a.rb///\", \".c\"))\n    assert_equal(\".\", File.dirname(\"a\"))\n    assert_equal(\"/\", File.dirname(\"/\"))\n    assert_equal(\"/\", File.dirname(\"/a\"))\n    assert_equal(\"a\", File.dirname(\"a/b\"))\n    assert_equal(\"a/b\", File.dirname(\"a/b/c\"))\n    assert_equal(\"/a/b\", File.dirname(\"/a/b/c\"))\n    assert_equal(\"/a\", File.dirname(\"/a/b/\"))\n    assert_equal(\"/a\", File.dirname(\"/a/b///\"))\n    case Dir.pwd\n    when %r'\\A\\w:'\n      assert_match(/\\A\\w:\\/\\z/, File.expand_path(\".\", \"/\"))\n      assert_match(/\\A\\w:\\/a\\z/, File.expand_path(\"a\", \"/\"))\n      dosish = true\n    when %r'\\A//'\n      assert_match(%r'\\A//[^/]+/[^/]+\\z', File.expand_path(\".\", \"/\"))\n      assert_match(%r'\\A//[^/]+/[^/]+/a\\z', File.expand_path(\".\", \"/\"))\n      dosish = true\n    else\n      assert_equal(\"/\", File.expand_path(\".\", \"/\"))\n      assert_equal(\"/sub\", File.expand_path(\"sub\", \"/\"))\n    end\n    if dosish\n      assert_equal(\"//machine/share\", File.expand_path(\"/\", \"//machine/share/sub\"))\n      assert_equal(\"//machine/share/dir\", File.expand_path(\"/dir\", \"//machine/share/sub\"))\n      assert_equal(\"z:/\", File.expand_path(\"/\", \"z:/sub\"))\n      assert_equal(\"z:/dir\", File.expand_path(\"/dir\", \"z:/sub\"))\n    end\n    assert_equal(\"//\", File.expand_path(\".\", \"//\"))\n    assert_equal(\"//sub\", File.expand_path(\"sub\", \"//\"))\n  end\n\n  def test_dirname # [ruby-dev:27738]\n    if /(bcc|ms)win\\d|mingw|cygwin|djgpp|human|emx/ =~ RUBY_PLATFORM\n      # DOSISH_DRIVE_LETTER\n      assert_equal('C:.', File.dirname('C:'))\n      assert_equal('C:.', File.dirname('C:a'))\n      assert_equal('C:.', File.dirname('C:a/'))\n      assert_equal('C:a', File.dirname('C:a/b'))\n\n      assert_equal('C:/', File.dirname('C:/'))\n      assert_equal('C:/', File.dirname('C:/a'))\n      assert_equal('C:/', File.dirname('C:/a/'))\n      assert_equal('C:/a', File.dirname('C:/a/b'))\n\n      assert_equal('C:/', File.dirname('C://'))\n      assert_equal('C:/', File.dirname('C://a'))\n      assert_equal('C:/', File.dirname('C://a/'))\n      assert_equal('C:/a', File.dirname('C://a/b'))\n\n      assert_equal('C:/', File.dirname('C:///'))\n      assert_equal('C:/', File.dirname('C:///a'))\n      assert_equal('C:/', File.dirname('C:///a/'))\n      assert_equal('C:/a', File.dirname('C:///a/b'))\n    else\n      # others\n      assert_equal('.', File.dirname('C:'))\n      assert_equal('.', File.dirname('C:a'))\n      assert_equal('.', File.dirname('C:a/'))\n      assert_equal('C:a', File.dirname('C:a/b'))\n\n      assert_equal('.', File.dirname('C:/'))\n      assert_equal('C:', File.dirname('C:/a'))\n      assert_equal('C:', File.dirname('C:/a/'))\n      assert_equal('C:/a', File.dirname('C:/a/b'))\n\n      assert_equal('.', File.dirname('C://'))\n      assert_equal('C:', File.dirname('C://a'))\n      assert_equal('C:', File.dirname('C://a/'))\n      # not spec.\n      #assert_equal('C://a', File.dirname('C://a/b'))\n\n      assert_equal('.', File.dirname('C:///'))\n      assert_equal('C:', File.dirname('C:///a'))\n      assert_equal('C:', File.dirname('C:///a/'))\n      # not spec.\n      #assert_equal('C:///a', File.dirname('C:///a/b'))\n    end\n\n    assert_equal('.', File.dirname(''))\n    assert_equal('.', File.dirname('a'))\n    assert_equal('.', File.dirname('a/'))\n    assert_equal('a', File.dirname('a/b'))\n\n    assert_equal('/', File.dirname('/'))\n    assert_equal('/', File.dirname('/a'))\n    assert_equal('/', File.dirname('/a/'))\n    assert_equal('/a', File.dirname('/a/b'))\n\n    if /(bcc|ms|cyg)win|mingw|djgpp|human|emx/ =~ RUBY_PLATFORM\n      # DOSISH_UNC\n      assert_equal('//', File.dirname('//'))\n      assert_equal('//a', File.dirname('//a'))\n      assert_equal('//a', File.dirname('//a/'))\n      assert_equal('//a/b', File.dirname('//a/b'))\n      assert_equal('//a/b', File.dirname('//a/b/'))\n      assert_equal('//a/b', File.dirname('//a/b/c'))\n\n      assert_equal('//', File.dirname('///'))\n      assert_equal('//a', File.dirname('///a'))\n      assert_equal('//a', File.dirname('///a/'))\n      assert_equal('//a/b', File.dirname('///a/b'))\n      assert_equal('//a/b', File.dirname('///a/b/'))\n      assert_equal('//a/b', File.dirname('///a/b/c'))\n    else\n      # others\n      assert_equal('/', File.dirname('//'))\n      assert_equal('/', File.dirname('//a'))\n      assert_equal('/', File.dirname('//a/'))\n      assert_equal('/a', File.dirname('//a/b'))\n      assert_equal('/a', File.dirname('//a/b/'))\n      assert_equal('/a/b', File.dirname('//a/b/c'))\n\n      assert_equal('/', File.dirname('///'))\n      assert_equal('/', File.dirname('///a'))\n      assert_equal('/', File.dirname('///a/'))\n      assert_equal('/a', File.dirname('///a/b'))\n      assert_equal('/a', File.dirname('///a/b/'))\n      assert_equal('/a/b', File.dirname('///a/b/c'))\n    end\n  end\n\n  def test_basename # [ruby-dev:27766]\n    if /(bcc|ms)win\\d|mingw|cygwin|djgpp|human|emx/ =~ RUBY_PLATFORM\n      # DOSISH_DRIVE_LETTER\n      assert_equal('', File.basename('C:'))\n      assert_equal('a', File.basename('C:a'))\n      assert_equal('a', File.basename('C:a/'))\n      assert_equal('b', File.basename('C:a/b'))\n\n      assert_equal('/', File.basename('C:/'))\n      assert_equal('a', File.basename('C:/a'))\n      assert_equal('a', File.basename('C:/a/'))\n      assert_equal('b', File.basename('C:/a/b'))\n\n      assert_equal('/', File.basename('C://'))\n      assert_equal('a', File.basename('C://a'))\n      assert_equal('a', File.basename('C://a/'))\n      assert_equal('b', File.basename('C://a/b'))\n\n      assert_equal('/', File.basename('C:///'))\n      assert_equal('a', File.basename('C:///a'))\n      assert_equal('a', File.basename('C:///a/'))\n      assert_equal('b', File.basename('C:///a/b'))\n    else\n      # others\n      assert_equal('C:', File.basename('C:'))\n      assert_equal('C:a', File.basename('C:a'))\n      assert_equal('C:a', File.basename('C:a/'))\n      assert_equal('b', File.basename('C:a/b'))\n\n      assert_equal('C:', File.basename('C:/'))\n      assert_equal('a', File.basename('C:/a'))\n      assert_equal('a', File.basename('C:/a/'))\n      assert_equal('b', File.basename('C:/a/b'))\n\n      assert_equal('C:', File.basename('C://'))\n      assert_equal('a', File.basename('C://a'))\n      assert_equal('a', File.basename('C://a/'))\n      assert_equal('b', File.basename('C://a/b'))\n\n      assert_equal('C:', File.basename('C:///'))\n      assert_equal('a', File.basename('C:///a'))\n      assert_equal('a', File.basename('C:///a/'))\n      assert_equal('b', File.basename('C:///a/b'))\n    end\n\n    assert_equal('', File.basename(''))\n    assert_equal('a', File.basename('a'))\n    assert_equal('a', File.basename('a/'))\n    assert_equal('b', File.basename('a/b'))\n\n    assert_equal('/', File.basename('/'))\n    assert_equal('a', File.basename('/a'))\n    assert_equal('a', File.basename('/a/'))\n    assert_equal('b', File.basename('/a/b'))\n\n    if /(bcc|ms|cyg)win|mingw|djgpp|human|emx/ =~ RUBY_PLATFORM\n      # DOSISH_UNC\n      assert_equal('/', File.basename('//'))\n      assert_equal('/', File.basename('//a'))\n      assert_equal('/', File.basename('//a/'))\n      assert_equal('/', File.basename('//a/b'))\n      assert_equal('/', File.basename('//a/b/'))\n      assert_equal('c', File.basename('//a/b/c'))\n\n      assert_equal('/', File.basename('///'))\n      assert_equal('/', File.basename('///a'))\n      assert_equal('/', File.basename('///a/'))\n      assert_equal('/', File.basename('///a/b'))\n      assert_equal('/', File.basename('///a/b/'))\n      assert_equal('c', File.basename('///a/b/c'))\n    else\n      # others\n      assert_equal('/', File.basename('//'))\n      assert_equal('a', File.basename('//a'))\n      assert_equal('a', File.basename('//a/'))\n      assert_equal('b', File.basename('//a/b'))\n      assert_equal('b', File.basename('//a/b/'))\n      assert_equal('c', File.basename('//a/b/c'))\n\n      assert_equal('/', File.basename('///'))\n      assert_equal('a', File.basename('///a'))\n      assert_equal('a', File.basename('///a/'))\n      assert_equal('b', File.basename('///a/b'))\n      assert_equal('b', File.basename('///a/b/'))\n      assert_equal('c', File.basename('///a/b/c'))\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_pipe.rb",
    "content": "require 'test/unit'\n$:.replace([File.dirname(File.expand_path(__FILE__))] | $:)\nrequire 'ut_eof'\nrequire 'envutil'\n\nclass TestPipe < Test::Unit::TestCase\n  include TestEOF\n  def open_file(content)\n    r, w = IO.pipe\n    w << content\n    w.close\n    begin\n      yield r\n    ensure\n      r.close\n    end\n  end\n\n  def test_write\n    bug2559 = '[ruby-core:27425]'\n    a, b = IO.pipe\n    begin\n      a.close\n      assert_raises(Errno::EPIPE, bug2559) do\n        b.write(\"hi\")\n      end\n    ensure\n      a.close if !a.closed?\n      b.close if !b.closed?\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_proc.rb",
    "content": "require 'test/unit'\n\nclass TestProc < Test::Unit::TestCase\n  def test_proc\n    p1 = proc{|i| i}\n    assert_equal(2, p1.call(2))\n    assert_equal(3, p1.call(3))\n\n    p1 = proc{|i| i*2}\n    assert_equal(4, p1.call(2))\n    assert_equal(6, p1.call(3))\n\n    p2 = nil\n    x=0\n\n    proc{\n      iii=5\t\t\t\t# nested local variable\n      p1 = proc{|i|\n        iii = i\n      }\n      p2 = proc {\n        x = iii                 \t# nested variables shared by procs\n      }\n      # scope of nested variables\n      assert(defined?(iii))\n    }.call\n    assert(!defined?(iii))\t\t# out of scope\n\n    loop{iii=5; assert(eval(\"defined? iii\")); break}\n    loop {\n      iii = 10\n      def self.dyna_var_check\n        loop {\n          assert(!defined?(iii))\n          break\n        }\n      end\n      dyna_var_check\n      break\n    }\n    p1.call(5)\n    p2.call\n    assert_equal(5, x)\n  end\n\n  def assert_arity(n)\n    meta = class << self; self; end\n    meta.class_eval {define_method(:foo, Proc.new)}\n    assert_equal(n, method(:foo).arity)\n  end\n\n  def test_arity\n    assert_equal(-1, proc{}.arity)\n    assert_equal(0, proc{||}.arity)\n    assert_equal(1, proc{|x|}.arity)\n    assert_equal(2, proc{|x, y|}.arity)\n    assert_equal(-2, proc{|x, *y|}.arity)\n    assert_equal(-1, proc{|*x|}.arity)\n    assert_equal(-1, proc{|*|}.arity)\n\n    assert_arity(-1) {}\n    assert_arity(0) {||}\n    assert_arity(1) {|x|}\n    assert_arity(2) {|x, y|}\n    assert_arity(-2) {|x, *y|}\n    assert_arity(-1) {|*x|}\n    assert_arity(-1) {|*|}\n  end\n\n  # [ruby-dev:22592]\n  def m(x)\n    lambda { x }\n  end\n  def test_eq\n    # [ruby-dev:22592]\n    a = m(1)\n    b = m(2)\n    assert_not_equal(a, b)\n    assert_not_equal(a.call, b.call)\n\n    # [ruby-dev:22599]\n    assert_not_equal(proc {||}, proc {|x,y|})\n\n    # [ruby-dev:22601]\n    a = lambda {|x| lambda {} }.call(1)\n    b = lambda {}\n    assert_not_equal(a, b)\n  end\n\n  def test_block_par\n    assert_equal(10, Proc.new{|&b| b.call(10)}.call {|x| x})\n    assert_equal(12, Proc.new{|a,&b| b.call(a)}.call(12) {|x| x})\n  end\n\n  def test_define_method_scope\n    a = 1\n    c = Class.new\n    c.send(:define_method, :x) do |*|\n      lambda {a = 2}.call\n    end\n    c.new.x(nil)\n    assert_equal(2, a, '[ruby-core:23050]')\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_process.rb",
    "content": "require 'test/unit'\n\nclass TestProcess < Test::Unit::TestCase\n  def test_rlimit_availability\n    begin\n      Process.getrlimit(nil)\n    rescue NotImplementedError\n      assert_raise(NotImplementedError) { Process.setrlimit }\n    rescue TypeError\n      assert_raise(ArgumentError) { Process.setrlimit }\n    end\n  end\n\n  def rlimit_exist?\n    Process.getrlimit(nil)\n  rescue NotImplementedError\n    return false\n  rescue TypeError\n    return true\n  end\n\n  def test_rlimit_nofile\n    return unless rlimit_exist?\n    pid = fork {\n      cur_nofile, max_nofile = Process.getrlimit(Process::RLIMIT_NOFILE)\n      begin\n        Process.setrlimit(Process::RLIMIT_NOFILE, 0, max_nofile)\n      rescue Errno::EINVAL\n        exit 0\n      end\n      begin\n        IO.pipe\n      rescue Errno::EMFILE\n        exit 0\n      end\n      exit 1\n    }\n    Process.wait pid\n    assert_equal(0, $?.to_i)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_rand.rb",
    "content": "require 'test/unit'\n\nclass TestRand < Test::Unit::TestCase\n  def test_mt\n    srand(0x00000456_00000345_00000234_00000123)\n    %w(1067595299  955945823  477289528 4107218783 4228976476).each {|w|\n      assert_equal(w.to_i, rand(0x100000000))\n    }\n  end\n\n  def test_0x3fffffff\n    srand(0)\n    %w(209652396 398764591 924231285 404868288 441365315).each {|w|\n      assert_equal(w.to_i, rand(0x3fffffff))\n    }\n  end\n\n  def test_0x40000000\n    srand(0)\n    %w(209652396 398764591 924231285 404868288 441365315).each {|w|\n      assert_equal(w.to_i, rand(0x40000000))\n    }\n  end\n\n  def test_0x40000001\n    srand(0)\n    %w(209652396 398764591 924231285 441365315 192771779).each {|w|\n      assert_equal(w.to_i, rand(0x40000001))\n    }\n  end\n\n  def test_0xffffffff\n    srand(0)\n    %w(2357136044 2546248239 3071714933 3626093760 2588848963).each {|w|\n      assert_equal(w.to_i, rand(0xffffffff))\n    }\n  end\n\n  def test_0x100000000\n    srand(0)\n    %w(2357136044 2546248239 3071714933 3626093760 2588848963).each {|w|\n      assert_equal(w.to_i, rand(0x100000000))\n    }\n  end\n\n  def test_0x100000001\n    srand(0)\n    %w(2546248239 1277901399 243580376 1171049868 2051556033).each {|w|\n      assert_equal(w.to_i, rand(0x100000001))\n    }\n  end\n\n  def test_rand_0x100000000\n    srand(311702798)\n    %w(4119812344 3870378946 80324654 4294967296 410016213).each {|w|\n      assert_equal(w.to_i, rand(0x100000001))\n    }\n  end\n\n  def test_0x1000000000000\n    srand(0)\n    %w(11736396900911\n       183025067478208\n       197104029029115\n       130583529618791\n       180361239846611).each {|w|\n      assert_equal(w.to_i, rand(0x1000000000000))\n    }\n  end\n\n  def test_0x1000000000001\n    srand(0)\n    %w(187121911899765\n       197104029029115\n       180361239846611\n       236336749852452\n       208739549485656).each {|w|\n      assert_equal(w.to_i, rand(0x1000000000001))\n    }\n  end\n\n  def test_0x3fffffffffffffff\n    srand(0)\n    %w(900450186894289455\n       3969543146641149120\n       1895649597198586619\n       827948490035658087\n       3203365596207111891).each {|w|\n      assert_equal(w.to_i, rand(0x3fffffffffffffff))\n    }\n  end\n\n  def test_0x4000000000000000\n    srand(0)\n    %w(900450186894289455\n       3969543146641149120\n       1895649597198586619\n       827948490035658087\n       3203365596207111891).each {|w|\n      assert_equal(w.to_i, rand(0x4000000000000000))\n    }\n  end\n\n  def test_0x4000000000000001\n    srand(0)\n    %w(900450186894289455\n       3969543146641149120\n       1895649597198586619\n       827948490035658087\n       2279347887019741461).each {|w|\n      assert_equal(w.to_i, rand(0x4000000000000001))\n    }\n  end\n\n  def test_neg_0x10000000000\n    ws = %w(455570294424 1073054410371 790795084744 2445173525 1088503892627)\n    srand(3)\n    ws.each {|w| assert_equal(w.to_i, rand(0x10000000000)) }\n    srand(3)\n    ws.each {|w| assert_equal(w.to_i, rand(-0x10000000000)) }\n  end\n\n  def test_neg_0x10000\n    ws = %w(2732 43567 42613 52416 45891)\n    srand(0)\n    ws.each {|w| assert_equal(w.to_i, rand(0x10000)) }\n    srand(0)\n    ws.each {|w| assert_equal(w.to_i, rand(-0x10000)) }\n  end\n\nend\n"
  },
  {
    "path": "test/ruby/test_range.rb",
    "content": "require 'test/unit'\n\nclass TestRange < Test::Unit::TestCase\n  def test_range_string\n    # XXX: Is this really the test of Range?\n    assert_equal([], (\"a\" ... \"a\").to_a)\n    assert_equal([\"a\"], (\"a\" .. \"a\").to_a)\n    assert_equal([\"a\"], (\"a\" ... \"b\").to_a)\n    assert_equal([\"a\", \"b\"], (\"a\" .. \"b\").to_a)\n  end\n\n  def test_evaluation_order\n    arr = [1,2]\n    r = (arr.shift)..(arr.shift)\n    assert_equal(1..2, r, \"[ruby-dev:26383]\")\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_readpartial.rb",
    "content": "require 'test/unit'\nrequire 'timeout'\nrequire 'fcntl'\n\nclass TestReadPartial < Test::Unit::TestCase\n  def make_pipe\n    r, w = IO.pipe\n    begin\n      yield r, w\n    ensure\n      r.close unless r.closed?\n      w.close unless w.closed?\n    end\n  end\n\n  def pipe\n    make_pipe {|r, w|\n      yield r, w\n    }\n    return unless defined?(Fcntl::F_SETFL)\n    return unless defined?(Fcntl::F_GETFL)\n    return unless defined?(Fcntl::O_NONBLOCK)\n    make_pipe {|r, w|\n      r.fcntl(Fcntl::F_SETFL, r.fcntl(Fcntl::F_GETFL) | Fcntl::O_NONBLOCK)\n      yield r, w\n    }\n  end\n\n  def test_length_zero\n    pipe {|r, w|\n      assert_equal('', r.readpartial(0))\n    }\n  end\n\n  def test_closed_pipe\n    pipe {|r, w|\n      w << 'abc'\n      w.close\n      assert_equal('ab', r.readpartial(2))\n      assert_equal('c', r.readpartial(2))\n      assert_raises(EOFError) { r.readpartial(2) }\n      assert_raises(EOFError) { r.readpartial(2) }\n    }\n  end\n\n  if !File::ALT_SEPARATOR # read on pipe cannot timeout on Windows.\n  def test_open_pipe\n    pipe {|r, w|\n      w << 'abc'\n      assert_equal('ab', r.readpartial(2))\n      assert_equal('c', r.readpartial(2))\n      assert_raises(TimeoutError) {\n        timeout(0.1) { r.readpartial(2) }\n      }\n    }\n  end\n\n  def test_with_stdio\n    pipe {|r, w|\n      w << \"abc\\ndef\\n\"\n      assert_equal(\"abc\\n\", r.gets)\n      w << \"ghi\\n\"\n      assert_equal(\"de\", r.readpartial(2))\n      assert_equal(\"f\\n\", r.readpartial(4096))\n      assert_equal(\"ghi\\n\", r.readpartial(4096))\n      assert_raises(TimeoutError) {\n        timeout(0.1) { r.readpartial(2) }\n      }\n    }\n  end\n  end\n\nend\n\n"
  },
  {
    "path": "test/ruby/test_settracefunc.rb",
    "content": "require 'test/unit'\n\nclass TestSetTraceFunc < Test::Unit::TestCase\n  def foo; end;\n\n  def bar\n    events = []\n    set_trace_func(Proc.new { |event, file, lineno, mid, bidning, klass|\n      events << [event, lineno, mid, klass]\n    })\n    return events\n  end\n\n  def test_event\n    events = []\n    set_trace_func(Proc.new { |event, file, lineno, mid, bidning, klass|\n      events << [event, lineno, mid, klass]\n    })\n    a = 1\n    foo\n    a\n    b = 1 + 2\n    if b == 3\n      case b\n      when 2\n        c = \"b == 2\"\n      when 3\n        c = \"b == 3\"\n      end\n    end\n    begin\n      raise \"error\"\n    rescue\n    end\n    eval(\"class Foo; end\")\n    set_trace_func nil\n\n    assert_equal([\"line\", 19, :test_event, TestSetTraceFunc],\n                 events.shift)     # a = 1\n    assert_equal([\"line\", 20, :test_event, TestSetTraceFunc],\n                 events.shift)     # foo\n    assert_equal([\"call\", 4, :foo, TestSetTraceFunc],\n                 events.shift)     # foo\n    assert_equal([\"return\", 4, :foo, TestSetTraceFunc],\n                 events.shift)     # foo\n    assert_equal([\"line\", 21, :test_event, TestSetTraceFunc],\n                 events.shift)     # a\n    assert_equal([\"line\", 22, :test_event, TestSetTraceFunc],\n                 events.shift)     # b = 1 + 2\n    assert_equal([\"c-call\", 22, :+, Fixnum],\n                 events.shift)     # 1 + 2\n    assert_equal([\"c-return\", 22, :+, Fixnum],\n                 events.shift)     # 1 + 2\n    assert_equal([\"line\", 23, :test_event, TestSetTraceFunc],\n                 events.shift)     # if b == 3\n    assert_equal([\"c-call\", 23, :==, Fixnum],\n                 events.shift)     # b == 3\n    assert_equal([\"c-return\", 23, :==, Fixnum],\n                 events.shift)     # b == 3\n    assert_equal([\"line\", 23, :test_event, TestSetTraceFunc],\n                 events.shift)     # if b == 3\n    assert_equal([\"line\", 24, :test_event, TestSetTraceFunc],\n                 events.shift)     # case b\n    assert_equal([\"line\", 25, :test_event, TestSetTraceFunc],\n                 events.shift)     # when 2\n    assert_equal([\"c-call\", 25, :===, Kernel],\n                 events.shift)     # when 2\n    assert_equal([\"c-call\", 25, :==, Fixnum],\n                 events.shift)     # when 2\n    assert_equal([\"c-return\", 25, :==, Fixnum],\n                 events.shift)     # when 2\n    assert_equal([\"c-return\", 25, :===, Kernel],\n                 events.shift)     # when 2\n    assert_equal([\"line\", 27, :test_event, TestSetTraceFunc],\n                 events.shift)     # when 3\n    assert_equal([\"c-call\", 27, :===, Kernel],\n                 events.shift)     # when 3\n    assert_equal([\"c-return\", 27, :===, Kernel],\n                 events.shift)     # when 3\n    assert_equal([\"line\", 28, :test_event, TestSetTraceFunc],\n                 events.shift)     # c = \"b == 3\"\n    assert_equal([\"line\", 31, :test_event, TestSetTraceFunc],\n                 events.shift)     # begin\n    assert_equal([\"line\", 32, :test_event, TestSetTraceFunc],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-call\", 32, :raise, Kernel],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-call\", 32, :new, Class],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-call\", 32, :initialize, Exception],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-return\", 32, :initialize, Exception],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-return\", 32, :new, Class],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-call\", 32, :backtrace, Exception],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-return\", 32, :backtrace, Exception],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-call\", 32, :set_backtrace, Exception],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-return\", 32, :set_backtrace, Exception],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"raise\", 32, :test_event, TestSetTraceFunc],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"c-return\", 32, :raise, Kernel],\n                 events.shift)     # raise \"error\"\n    assert_equal([\"line\", 35, :test_event, TestSetTraceFunc],\n                 events.shift)     # eval(<<EOF)\n    assert_equal([\"c-call\", 35, :eval, Kernel],\n                 events.shift)     # eval(<<EOF)\n    assert_equal([\"line\", 1, :test_event, TestSetTraceFunc],\n                 events.shift)     # class Foo\n    assert_equal([\"c-call\", 1, :inherited, Class],\n                 events.shift)     # class Foo\n    assert_equal([\"c-return\", 1, :inherited, Class],\n                 events.shift)     # class Foo\n    assert_equal([\"class\", 1, :test_event, TestSetTraceFunc],\n                 events.shift)     # class Foo\n    assert_equal([\"end\", 1, :test_event, TestSetTraceFunc],\n                 events.shift)     # class Foo\n    assert_equal([\"c-return\", 35, :eval, Kernel],\n                 events.shift)     # eval(<<EOF)\n    assert_equal([\"line\", 36, :test_event, TestSetTraceFunc],\n                 events.shift)     # set_trace_func nil\n    assert_equal([\"c-call\", 36, :set_trace_func, Kernel],\n                 events.shift)     # set_trace_func nil\n    assert_equal([], events)\n\n    events = bar\n    set_trace_func(nil)\n    assert_equal([\"line\", 11, :bar, TestSetTraceFunc], events.shift)\n    assert_equal([\"return\", 11, :bar, TestSetTraceFunc], events.shift)\n    assert_equal([\"line\", 131, :test_event, TestSetTraceFunc], events.shift)\n    assert_equal([\"c-call\", 131, :set_trace_func, Kernel], events.shift)\n    assert_equal([], events)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_signal.rb",
    "content": "require 'test/unit'\nrequire 'timeout'\n\nclass TestSignal < Test::Unit::TestCase\n  def have_fork?\n    begin\n      fork{}\n      true\n    rescue NotImplementedError\n      false\n    end\n  end\n\n  def test_signal\n    defined?(Process.kill) or return\n    begin\n      $x = 0\n      oldtrap = trap \"SIGINT\", proc{|sig| $x = 2}\n      Process.kill \"SIGINT\", $$\n      sleep 0.1\n      assert_equal(2, $x)\n\n      trap \"SIGINT\", proc{raise \"Interrupt\"}\n\n      x = assert_raises(RuntimeError) do\n        Process.kill \"SIGINT\", $$\n        sleep 0.1\n      end\n      assert(x)\n      assert_match(/Interrupt/, x.message)\n    ensure\n      trap \"SIGINT\", oldtrap\n    end\n  end\n\n  def test_exit_action\n    return unless have_fork?\t# snip this test\n    begin\n      r, w = IO.pipe\n      r0, w0 = IO.pipe\n      pid = fork {\n        trap(:USR1, \"EXIT\")\n        w0.close\n        w.syswrite(\"a\")\n        Thread.start { Thread.pass }\n        r0.sysread(4096)\n      }\n      r.sysread(1)\n      sleep 0.1\n      assert_nothing_raised(\"[ruby-dev:26128]\") {\n        Process.kill(:USR1, pid)\n        begin\n          Timeout.timeout(10) {\n            Process.waitpid pid\n          }\n        rescue Timeout::Error\n          Process.kill(:TERM, pid)\n          raise\n        end\n      }\n    ensure\n      r.close\n      w.close\n      r0.close\n      w0.close\n    end\n  end\n\n  def test_child_vtalrm\n    return unless have_fork?\t# snip this test\n    pid = fork {100_000.times{ 1+1 }}\n    pid, status = Process.wait2(pid)\n    assert_equal(false, status.signaled?, '[ruby-core:25606]')\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_sleep.rb",
    "content": "require 'test/unit'\n\nclass TestSleep < Test::Unit::TestCase\n  def test_sleep_5sec\n    start = Time.now\n    sleep 5\n    slept = Time.now-start\n    assert_in_delta(5.0, slept, 0.1, \"[ruby-core:18015]: longer than expected\")\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_string.rb",
    "content": "require 'test/unit'\n\nclass TestString < Test::Unit::TestCase\n  def check_sum(str, bits=16)\n    sum = 0\n    str.each_byte {|c| sum += c}\n    sum = sum & ((1 << bits) - 1) if bits != 0\n    assert_equal(sum, str.sum(bits))\n  end\n  def test_sum\n    assert_equal(0, \"\".sum)\n    assert_equal(294, \"abc\".sum)\n    check_sum(\"abc\")\n    check_sum(\"\\x80\")\n    0.upto(70) {|bits|\n      check_sum(\"xyz\", bits)\n    }\n  end\n\n  def test_inspect\n    original_kcode = $KCODE\n\n    $KCODE = 'n'\n    assert_equal('\"\\343\\201\\202\"', \"\\xe3\\x81\\x82\".inspect)\n\n    $KCODE = 'u'\n    assert_equal('\"\\\\343\\\\201\\\\202\"', \"\\xe3\\x81\\x82\".inspect)\n    assert_no_match(/\\0/, \"\\xe3\\x81\".inspect, '[ruby-dev:39550]')\n  ensure\n    $KCODE = original_kcode\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_stringchar.rb",
    "content": "require 'test/unit'\n\nclass TestStringchar < Test::Unit::TestCase\n  def test_string\n    assert_equal(\"abcd\", \"abcd\")\n    assert_match(/abcd/, \"abcd\")\n    assert(\"abcd\" === \"abcd\")\n    # compile time string concatenation\n    assert_equal(\"abcd\", \"ab\" \"cd\")\n    assert_equal(\"22aacd44\", \"#{22}aa\" \"cd#{44}\")\n    assert_equal(\"22aacd445566\", \"#{22}aa\" \"cd#{44}\" \"55\" \"#{66}\")\n    assert(\"abc\" !~ /^$/)\n    assert(\"abc\\n\" !~ /^$/)\n    assert(\"abc\" !~ /^d*$/)\n    assert_equal(3, (\"abc\" =~ /d*$/))\n    assert(\"\" =~ /^$/)\n    assert(\"\\n\" =~ /^$/)\n    assert(\"a\\n\\n\" =~ /^$/)\n    assert(\"abcabc\" =~ /.*a/); assert_equal(\"abca\", $&)\n    assert(\"abcabc\" =~ /.*c/); assert_equal(\"abcabc\", $&)\n    assert(\"abcabc\" =~ /.*?a/); assert_equal(\"a\", $&)\n    assert(\"abcabc\" =~ /.*?c/); assert_equal(\"abc\", $&)\n    assert(/(.|\\n)*?\\n(b|\\n)/ =~ \"a\\nb\\n\\n\"); assert_equal(\"a\\nb\", $&)\n\n    assert(/^(ab+)+b/ =~ \"ababb\"); assert_equal(\"ababb\", $&)\n    assert(/^(?:ab+)+b/ =~ \"ababb\"); assert_equal(\"ababb\", $&)\n    assert(/^(ab+)+/ =~ \"ababb\"); assert_equal(\"ababb\", $&)\n    assert(/^(?:ab+)+/ =~ \"ababb\"); assert_equal(\"ababb\", $&)\n\n    assert(/(\\s+\\d+){2}/ =~ \" 1 2\"); assert_equal(\" 1 2\", $&)\n    assert(/(?:\\s+\\d+){2}/ =~ \" 1 2\"); assert_equal(\" 1 2\", $&)\n\n    $x = <<END;\nABCD\nABCD\nEND\n    $x.gsub!(/((.|\\n)*?)B((.|\\n)*?)D/){$1+$3}\n    assert_equal(\"AC\\nAC\\n\", $x)\n\n    assert(\"foobar\" =~ /foo(?=(bar)|(baz))/)\n    assert(\"foobaz\" =~ /foo(?=(bar)|(baz))/)\n\n    $foo = \"abc\"\n    assert_equal(\"abc = abc\", \"#$foo = abc\")\n    assert_equal(\"abc = abc\", \"#{$foo} = abc\")\n\n    foo = \"abc\"\n    assert_equal(\"abc = abc\", \"#{foo} = abc\")\n\n    assert_equal('-----', '-' * 5)\n    assert_equal('-', '-' * 1)\n    assert_equal('', '-' * 0)\n\n    foo = '-'\n    assert_equal('-----', foo * 5)\n    assert_equal('-', foo * 1)\n    assert_equal('', foo * 0)\n\n    $x = \"a.gif\"\n    assert_equal(\"gif\", $x.sub(/.*\\.([^\\.]+)$/, '\\1'))\n    assert_equal(\"b.gif\", $x.sub(/.*\\.([^\\.]+)$/, 'b.\\1'))\n    assert_equal(\"\", $x.sub(/.*\\.([^\\.]+)$/, '\\2'))\n    assert_equal(\"ab\", $x.sub(/.*\\.([^\\.]+)$/, 'a\\2b'))\n    assert_equal(\"<a.gif>\", $x.sub(/.*\\.([^\\.]+)$/, '<\\&>'))\n  end\n\n  def test_char\n    # character constants(assumes ASCII)\n    assert_equal(?a, \"a\"[0])\n    assert_equal(?a, ?a)\n    assert_equal(1, ?\\C-a)\n    assert_equal(225, ?\\M-a)\n    assert_equal(129, ?\\M-\\C-a)\n    assert_equal(?A, \"a\".upcase![0])\n    assert_equal(?a, \"A\".downcase![0])\n    assert_equal(\"ABC\", \"abc\".tr!(\"a-z\", \"A-Z\"))\n    assert_equal(\"ABC\", \"aabbcccc\".tr_s!(\"a-z\", \"A-Z\"))\n    assert_equal(\"abc\", \"abcc\".squeeze!(\"a-z\"))\n    assert_equal(\"ad\", \"abcd\".delete!(\"bc\"))\n\n    $x = \"abcdef\"\n    $y = [ ?a, ?b, ?c, ?d, ?e, ?f ]\n    $bad = false\n    $x.each_byte {|i|\n      if i != $y.shift\n        $bad = true\n        break\n      end\n    }\n    assert(!$bad)\n\n    s = \"a string\"\n    s[0..s.size]=\"another string\"\n    assert_equal(\"another string\", s)\n\n    s = <<EOS\n#{\n[1,2,3].join(\",\")\n}\nEOS\n    assert_equal(\"1,2,3\\n\", s)\n    assert_equal(926381, \"Just\".to_i(36))\n    assert_equal(-23200231779, \"-another\".to_i(36))\n    assert_equal(\"ruby\", 1299022.to_s(36))\n    assert_equal(\"-hacker\", -1045307475.to_s(36))\n    assert_equal(265419172580680477752431643787347, \"Just_another_Ruby_hacker\".to_i(36))\n    assert_equal(\"-justanotherrubyhacker\", -265419172580680477752431643787347.to_s(36))\n\n    a = []\n    (0..255).each {|n|\n      ch = [n].pack(\"C\")\n      a.push ch if /a#{Regexp.quote ch}b/x =~ \"ab\"\n    }\n    assert_equal(0, a.size)\n  end\n\n  def test_bang\n    s = \"aBc\"\n    s.upcase\n    assert_equal(\"aBc\", s)\n    s.upcase!\n    assert_equal(\"ABC\", s)\n\n    s = \"aBc\"\n    s.downcase\n    assert_equal(\"aBc\", s)\n    s.downcase!\n    assert_equal(\"abc\", s)\n\n    s = \"aBc\"\n    s.swapcase\n    assert_equal(\"aBc\", s)\n    s.swapcase!\n    assert_equal(\"AbC\", s)\n\n    s = \"aBc\"\n    s.capitalize\n    assert_equal(\"aBc\", s)\n    s.capitalize!\n    assert_equal(\"Abc\", s)\n\n    s = \"aBc\"\n    s.tr(\"a-z\", \"A-Z\")\n    assert_equal(\"aBc\", s)\n    s.tr!(\"a-z\", \"A-Z\")\n    assert_equal(\"ABC\", s)\n\n    s = \"aaBBcc\"\n    s.tr_s(\"a-z\", \"A-Z\")\n    assert_equal(\"aaBBcc\", s)\n    s.tr_s!(\"a-z\", \"A-Z\")\n    assert_equal(\"ABBC\", s)\n\n    s = \"aaBBcc\"\n    s.squeeze(\"a-z\")\n    assert_equal(\"aaBBcc\", s)\n    s.squeeze!(\"a-z\")\n    assert_equal(\"aBBc\", s)\n\n    s = \"aaBBcc\"\n    s.delete(\"a-z\")\n    assert_equal(\"aaBBcc\", s)\n    s.delete!(\"a-z\")\n    assert_equal(\"BB\", s)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_struct.rb",
    "content": "require 'test/unit'\n\nclass TestStruct < Test::Unit::TestCase\n  def test_struct\n    struct_test = Struct.new(\"Test\", :foo, :bar)\n    assert_equal(Struct::Test, struct_test)\n\n    test = struct_test.new(1, 2)\n    assert_equal(1, test.foo)\n    assert_equal(2, test.bar)\n    assert_equal(1, test[0])\n    assert_equal(2, test[1])\n\n    a, b = test.to_a\n    assert_equal(1, a)\n    assert_equal(2, b)\n\n    test[0] = 22\n    assert_equal(22, test.foo)\n\n    test.bar = 47\n    assert_equal(47, test.bar)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_super.rb",
    "content": "require 'test/unit'\n\nclass TestSuper < Test::Unit::TestCase\n  class Base\n    def single(a) a end\n    def double(a, b) [a,b] end\n    def array(*a) a end\n    def optional(a = 0) a end\n  end\n  class Single1 < Base\n    def single(*) super end\n  end\n  class Single2 < Base\n    def single(a,*) super end\n  end\n  class Double1 < Base\n    def double(*) super end\n  end\n  class Double2 < Base\n    def double(a,*) super end\n  end\n  class Double3 < Base\n    def double(a,b,*) super end\n  end\n  class Array1 < Base\n    def array(*) super end\n  end\n  class Array2 < Base\n    def array(a,*) super end\n  end\n  class Array3 < Base\n    def array(a,b,*) super end\n  end\n  class Array4 < Base\n    def array(a,b,c,*) super end\n  end\n  class Optional1 < Base\n    def optional(a = 1) super end\n  end\n  class Optional2 < Base\n    def optional(a, b = 1) super end\n  end\n  class Optional3 < Base\n    def single(a = 1) super end\n  end\n  class Optional4 < Base\n    def array(a = 1, *) super end\n  end\n  class Optional5 < Base\n    def array(a = 1, b = 2, *) super end\n  end\n\n  def test_single1\n    assert_equal(1, Single1.new.single(1))\n  end\n  def test_single2\n    assert_equal(1, Single2.new.single(1))\n  end\n  def test_double1\n    assert_equal([1, 2], Double1.new.double(1, 2))\n  end\n  def test_double2\n    assert_equal([1, 2], Double2.new.double(1, 2))\n  end\n  def test_double3\n    assert_equal([1, 2], Double3.new.double(1, 2))\n  end\n  def test_array1\n    assert_equal([], Array1.new.array())\n    assert_equal([1], Array1.new.array(1))\n  end\n  def test_array2\n    assert_equal([1], Array2.new.array(1))\n    assert_equal([1,2], Array2.new.array(1, 2))\n  end\n  def test_array3\n    assert_equal([1,2], Array3.new.array(1, 2))\n    assert_equal([1,2,3], Array3.new.array(1, 2, 3))\n  end\n  def test_array4\n    assert_equal([1,2,3], Array4.new.array(1, 2, 3))\n    assert_equal([1,2,3,4], Array4.new.array(1, 2, 3, 4))\n  end\n  def test_optional1\n    assert_equal(9, Optional1.new.optional(9))\n    assert_equal(1, Optional1.new.optional)\n  end\n  def test_optional2\n    assert_raise(ArgumentError) do\n      # call Base#optional with 2 arguments; the 2nd arg is supplied\n      assert_equal(9, Optional2.new.optional(9))\n    end\n    assert_raise(ArgumentError) do\n      # call Base#optional with 2 arguments\n      assert_equal(9, Optional2.new.optional(9, 2))\n    end\n  end\n  def test_optional3\n    assert_equal(9, Optional3.new.single(9))\n    # call Base#single with 1 argument; the arg is supplied\n    assert_equal(1, Optional3.new.single)\n  end\n  def test_optional4\n    assert_equal([1], Optional4.new.array)\n    assert_equal([9], Optional4.new.array(9))\n    assert_equal([9, 8], Optional4.new.array(9, 8))\n  end\n  def test_optional5\n    assert_equal([1, 2], Optional5.new.array)\n    assert_equal([9, 2], Optional5.new.array(9))\n    assert_equal([9, 8], Optional5.new.array(9, 8))\n    assert_equal([9, 8, 7], Optional5.new.array(9, 8, 7))\n  end\n\n  class A\n    def tt(aa)\n      \"A#tt\"\n    end\n\n    def uu(a)\n      class << self\n        define_method(:tt) do |sym|\n          super\n        end\n      end\n    end\n  end\n\n  class B\n    def m\n      [self, \"#{self.class.to_s}::m\"]\n    end\n  end\n\n  class C < B\n    def self.t\n      define_method(:m) {super}\n    end\n  end\n\n  def test_define_method\n    a = A.new\n    a.uu(12)\n    assert_equal(\"A#tt\", a.tt(12), '[ruby-core:03856]')\n\n    bug2419 = '[ruby-core:26984]'\n    q = C.t\n    assert_raise(NoMethodError, bug2419) {q.call}\n    c = C.new\n    assert_equal([c, \"#{C.to_s}::m\"], c.m, bug2419)\n  end\n\n  module Bug2537\n    class Parent\n      def run(a)\n        a\n      end\n    end\n\n    class Child < Parent\n      def run(*a)\n        proc {super(*a)}.call\n      end\n    end\n  end\n\n  def test_super_in_block_call\n    bug2537 = '[ruby-dev:39931]'\n    assert_nothing_raised(bug2537) do\n      assert_equal(bug2537, Bug2537::Child.new.run(bug2537), bug2537)\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_symbol.rb",
    "content": "require 'test/unit'\n\nclass TestSymbol < Test::Unit::TestCase\n  # [ruby-core:3573]\n\n  def assert_eval_inspected(sym)\n    n = sym.inspect\n    assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(n))}\n  end\n\n  def test_inspect_invalid\n    # 2) Symbol#inspect sometimes returns invalid symbol representations:\n    assert_eval_inspected(:\"!\")\n    assert_eval_inspected(:\"=\")\n    assert_eval_inspected(:\"0\")\n    assert_eval_inspected(:\"$1\")\n    assert_eval_inspected(:\"@1\")\n    assert_eval_inspected(:\"@@1\")\n    assert_eval_inspected(:\"@\")\n    assert_eval_inspected(:\"@@\")\n  end\n\n  def assert_inspect_evaled(n)\n    assert_nothing_raised(SyntaxError) {assert_equal(n, eval(n).inspect)}\n  end\n\n  def test_inspect_suboptimal\n    # 3) Symbol#inspect sometimes returns suboptimal symbol representations:\n    assert_inspect_evaled(':foo')\n    assert_inspect_evaled(':foo!')\n    assert_inspect_evaled(':bar?')\n    assert_inspect_evaled(':<<')\n    assert_inspect_evaled(':>>')\n    assert_inspect_evaled(':<=')\n    assert_inspect_evaled(':>=')\n    assert_inspect_evaled(':=~')\n    assert_inspect_evaled(':==')\n    assert_inspect_evaled(':===')\n    assert_raise(SyntaxError) {eval ':='}\n    assert_inspect_evaled(':*')\n    assert_inspect_evaled(':**')\n    assert_raise(SyntaxError) {eval ':***'}\n    assert_inspect_evaled(':+')\n    assert_inspect_evaled(':-')\n    assert_inspect_evaled(':+@')\n    assert_inspect_evaled(':-@')\n    assert_inspect_evaled(':|')\n    assert_inspect_evaled(':^')\n    assert_inspect_evaled(':&')\n    assert_inspect_evaled(':/')\n    assert_inspect_evaled(':%')\n    assert_inspect_evaled(':~')\n    assert_inspect_evaled(':`')\n    assert_inspect_evaled(':[]')\n    assert_inspect_evaled(':[]=')\n    assert_raise(SyntaxError) {eval ':||'}\n    assert_raise(SyntaxError) {eval ':&&'}\n    assert_raise(SyntaxError) {eval ':['}\n  end\n\n  def test_inspect_dollar\n    # 4) :$- always treats next character literally:\n    sym = \"$-\".intern\n    assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(':$-'))}\n    assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(\":$-\\n\"))}\n    assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(\":$- \"))}\n    assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(\":$-#\"))}\n    assert_raise(SyntaxError) {eval ':$-('}\n  end\n\n  def test_inspect_number\n    # 5) Inconsistency between :$0 and :$1? The first one is valid, but the \n    # latter isn't.\n    assert_inspect_evaled(':$0')\n    assert_inspect_evaled(':$1')\n  end\n\n  def test_to_proc\n    assert_equal %w(1 2 3), (1..3).map(&:to_s)\n    [\n      [],\n      [1],\n      [1, 2],\n      [1, [2, 3]],\n    ].each do |ary|\n      ary_id = ary.object_id\n      assert_equal ary_id, :object_id.to_proc.call(ary)\n      ary_ids = ary.collect{|x| x.object_id }\n      assert_equal ary_ids, ary.collect(&:object_id)\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_system.rb",
    "content": "require 'test/unit'\n$:.replace([File.dirname(File.expand_path(__FILE__))] | $:)\nrequire 'envutil'\n\nclass TestSystem < Test::Unit::TestCase\n  def valid_syntax?(code, fname)\n    code = code.sub(/\\A(?:\\s*\\#.*$)*(\\n)?/n) {\n      \"#$&#{\"\\n\" if $1 && !$2}BEGIN{return true}\\n\"\n    }\n    eval(code, nil, fname, 0)\n  end\n\n  def test_system\n    ruby = EnvUtil.rubybin\n    assert_equal(\"foobar\\n\", `echo foobar`)\n    assert_equal('foobar', `#{ruby} -e 'print \"foobar\"'`)\n\n    tmp = open(\"script_tmp\", \"w\")\n    tmp.print \"print $zzz\\n\";\n    tmp.close\n\n    assert_equal('true', `#{ruby} -s script_tmp -zzz`)\n    assert_equal('555', `#{ruby} -s script_tmp -zzz=555`)\n\n    tmp = open(\"script_tmp\", \"w\")\n    tmp.print \"#! /usr/local/bin/ruby -s\\n\";\n    tmp.print \"print $zzz\\n\";\n    tmp.close\n\n    assert_equal('678', `#{ruby} script_tmp -zzz=678`)\n\n    tmp = open(\"script_tmp\", \"w\")\n    tmp.print \"this is a leading junk\\n\";\n    tmp.print \"#! /usr/local/bin/ruby -s\\n\";\n    tmp.print \"print $zzz\\n\";\n    tmp.print \"__END__\\n\";\n    tmp.print \"this is a trailing junk\\n\";\n    tmp.close\n\n    assert_equal('nil', `#{ruby} -x script_tmp`)\n    assert_equal('555', `#{ruby} -x script_tmp -zzz=555`)\n\n    tmp = open(\"script_tmp\", \"w\")\n    for i in 1..5\n      tmp.print i, \"\\n\"\n    end\n    tmp.close\n\n    `#{ruby} -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp`\n    tmp = open(\"script_tmp\", \"r\")\n    while tmp.gets\n      assert_equal(0, $_.to_i % 5)\n    end\n    tmp.close\n\n    File.unlink \"script_tmp\" or `/bin/rm -f \"script_tmp\"`\n    File.unlink \"script_tmp.bak\" or `/bin/rm -f \"script_tmp.bak\"`\n  end\n\n  def test_syntax\n    assert_nothing_raised(Exception) do\n      for script in Dir[File.expand_path(\"../../../{lib,sample,ext}/**/*.rb\", __FILE__)]\n        valid_syntax? IO::read(script), script\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_time.rb",
    "content": "require 'test/unit'\n\nclass TestTime < Test::Unit::TestCase\n  def test_time_add()\n    assert_equal(Time.utc(2000, 3, 21, 3, 30) + 3 * 3600,\n                 Time.utc(2000, 3, 21, 6, 30))\n    assert_equal(Time.utc(2000, 3, 21, 3, 30) + (-3 * 3600),\n                 Time.utc(2000, 3, 21, 0, 30))\n    assert_equal(0, (Time.at(1.1) + 0.9).usec)\n  end\n\n  def test_time_subt()\n    assert_equal(Time.utc(2000, 3, 21, 3, 30) - 3 * 3600,\n                 Time.utc(2000, 3, 21, 0, 30))\n    assert_equal(Time.utc(2000, 3, 21, 3, 30) - (-3 * 3600),\n                 Time.utc(2000, 3, 21, 6, 30))\n    assert_equal(900000, (Time.at(1.1) - 0.2).usec)\n  end\n\n  def test_time_time()\n    assert_equal(Time.utc(2000, 3, 21, 3, 30)  \\\n                -Time.utc(2000, 3, 21, 0, 30), 3*3600)\n    assert_equal(Time.utc(2000, 3, 21, 0, 30)  \\\n                -Time.utc(2000, 3, 21, 3, 30), -3*3600)\n  end\n\n  def negative_time_t?\n    begin\n      Time.at(-1)\n      true\n    rescue ArgumentError\n      false\n    end\n  end\n\n  def test_timegm\n    if negative_time_t?\n      assert_equal(-0x80000000, Time.utc(1901, 12, 13, 20, 45, 52).tv_sec)\n      assert_equal(-2, Time.utc(1969, 12, 31, 23, 59, 58).tv_sec)\n      assert_equal(-1, Time.utc(1969, 12, 31, 23, 59, 59).tv_sec)\n    end\n\n    assert_equal(0, Time.utc(1970, 1, 1, 0, 0, 0).tv_sec) # the Epoch\n    assert_equal(1, Time.utc(1970, 1, 1, 0, 0, 1).tv_sec)\n    assert_equal(31535999, Time.utc(1970, 12, 31, 23, 59, 59).tv_sec)\n    assert_equal(31536000, Time.utc(1971, 1, 1, 0, 0, 0).tv_sec)\n    assert_equal(78796799, Time.utc(1972, 6, 30, 23, 59, 59).tv_sec)\n\n    # 1972-06-30T23:59:60Z is the first leap second.\n    if Time.utc(1972, 7, 1, 0, 0, 0) - Time.utc(1972, 6, 30, 23, 59, 59) == 1\n      # no leap second.\n      assert_equal(78796800, Time.utc(1972, 7, 1, 0, 0, 0).tv_sec)\n      assert_equal(78796801, Time.utc(1972, 7, 1, 0, 0, 1).tv_sec)\n      assert_equal(946684800, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)\n      assert_equal(0x7fffffff, Time.utc(2038, 1, 19, 3, 14, 7).tv_sec)\n    else\n      # leap seconds supported.\n      assert_equal(2, Time.utc(1972, 7, 1, 0, 0, 0) - Time.utc(1972, 6, 30, 23, 59, 59))\n      assert_equal(78796800, Time.utc(1972, 6, 30, 23, 59, 60).tv_sec)\n      assert_equal(78796801, Time.utc(1972, 7, 1, 0, 0, 0).tv_sec)\n      assert_equal(78796802, Time.utc(1972, 7, 1, 0, 0, 1).tv_sec)\n      assert_equal(946684822, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)\n    end\n  end\n\n  def test_huge_difference # [ruby-dev:22619]\n    if negative_time_t?\n      assert_equal(Time.at(-0x80000000), Time.at(0x7fffffff) - 0xffffffff)\n      assert_equal(Time.at(-0x80000000), Time.at(0x7fffffff) + (-0xffffffff))\n      assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) + 0xffffffff)\n      assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) - (-0xffffffff))\n    end\n  end\n\n  def test_at\n    assert_equal(100000, Time.at(0.1).usec)\n    assert_equal(10000, Time.at(0.01).usec)\n    assert_equal(1000, Time.at(0.001).usec)\n    assert_equal(100, Time.at(0.0001).usec)\n    assert_equal(10, Time.at(0.00001).usec)\n    assert_equal(1, Time.at(0.000001).usec)\n    assert_equal(0, Time.at(1e-7).usec)\n    assert_equal(0, Time.at(4e-7).usec)\n    assert_equal(1, Time.at(6e-7).usec)\n    assert_equal(1, Time.at(14e-7).usec)\n    assert_equal(2, Time.at(16e-7).usec)\n    if negative_time_t?\n      assert_equal(0, Time.at(-1e-7).usec)\n      assert_equal(0, Time.at(-4e-7).usec)\n      assert_equal(999999, Time.at(-6e-7).usec)\n      assert_equal(999999, Time.at(-14e-7).usec)\n      assert_equal(999998, Time.at(-16e-7).usec)\n    end\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_trace.rb",
    "content": "require 'test/unit'\n\nclass TestTrace < Test::Unit::TestCase\n  def test_trace\n    $x = 1234\n    $y = 0\n    trace_var :$x, proc{$y = $x}\n    $x = 40414\n    assert_equal($x, $y)\n    \n    untrace_var :$x\n    $x = 19660208\n    assert_not_equal($x, $y)\n    \n    trace_var :$x, proc{$x *= 2}\n    $x = 5\n    assert_equal(10, $x)\n    \n    untrace_var :$x\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_variable.rb",
    "content": "require 'test/unit'\n\nclass TestVariable < Test::Unit::TestCase\n  class Gods\n    @@rule = \"Uranus\"\n    def ruler0\n      @@rule\n    end\n\n    def self.ruler1\t\t# <= per method definition style\n      @@rule\n    end\n    class << self\t\t\t# <= multiple method definition style\n      def ruler2\n\t@@rule\n      end\n    end\n  end\n\n  module Olympians\n    @@rule =\"Zeus\"\n    def ruler3\n      @@rule\n    end\n  end\n\n  class Titans < Gods\n    @@rule = \"Cronus\"\n    include Olympians           \t# OK to cause warning (intentional)\n  end\n\n  def test_variable\n    assert_instance_of(Fixnum, $$)\n    \n    # read-only variable\n    assert_raises(NameError) do\n      $$ = 5\n    end\n\n    foobar = \"foobar\"\n    $_ = foobar\n    assert_equal(foobar, $_)\n\n    assert_equal(\"Cronus\", Gods.new.ruler0)\n    assert_equal(\"Cronus\", Gods.ruler1)\n    assert_equal(\"Cronus\", Gods.ruler2)\n    assert_equal(\"Cronus\", Titans.ruler1)\n    assert_equal(\"Cronus\", Titans.ruler2)\n    atlas = Titans.new\n    assert_equal(\"Cronus\", atlas.ruler0)\n    assert_equal(\"Zeus\", atlas.ruler3)\n  end\nend\n"
  },
  {
    "path": "test/ruby/test_whileuntil.rb",
    "content": "require 'test/unit'\n\nclass TestWhileuntil < Test::Unit::TestCase\n  def test_while\n    tmp = open(\"while_tmp\", \"w\")\n    tmp.print \"tvi925\\n\";\n    tmp.print \"tvi920\\n\";\n    tmp.print \"vt100\\n\";\n    tmp.print \"Amiga\\n\";\n    tmp.print \"paper\\n\";\n    tmp.close\n\n    tmp = open(\"while_tmp\", \"r\")\n    assert_instance_of(File, tmp)\n    \n    while line = tmp.gets()\n      break if /vt100/ =~ line\n    end\n\n    assert(!tmp.eof?)\n    assert_match(/vt100/, line)\n    tmp.close\n\n    tmp = open(\"while_tmp\", \"r\")\n    while line = tmp.gets()\n      next if /vt100/ =~ line\n      assert_no_match(/vt100/, line)\n    end\n    assert(tmp.eof?)\n    assert_no_match(/vt100/, line)\n    tmp.close\n\n    tmp = open(\"while_tmp\", \"r\")\n    while tmp.gets()\n      line = $_\n      gsub(/vt100/, 'VT100')\n      if $_ != line\n        $_.gsub!('VT100', 'Vt100')\n        redo\n      end\n      assert_no_match(/vt100/, $_)\n      assert_no_match(/VT100/, $_)\n    end\n    assert(tmp.eof?)\n    tmp.close\n\n    sum=0\n    for i in 1..10\n      sum += i\n      i -= 1\n      if i > 0\n        redo\n      end\n    end\n    assert_equal(220, sum)\n\n    tmp = open(\"while_tmp\", \"r\")\n    while line = tmp.gets()\n      break if 3\n      assert_no_match(/vt100/, line)\n      assert_no_match(/Amiga/, line)\n      assert_no_match(/paper/, line)\n    end\n    tmp.close\n\n    File.unlink \"while_tmp\" or `/bin/rm -f \"while_tmp\"`\n    assert(!File.exist?(\"while_tmp\"))\n  end\n\n  def test_until\n    i = 0\n    until i>4\n      i+=1\n    end\n    assert(i>4)\n  end\nend\n"
  },
  {
    "path": "test/ruby/ut_eof.rb",
    "content": "require 'test/unit'\n\nmodule TestEOF\n  def test_eof_0\n    open_file(\"\") {|f|\n      assert_equal(\"\", f.read(0))\n      assert_equal(\"\", f.read(0))\n      assert_equal(\"\", f.read)\n      assert_nil(f.read(0))\n      assert_nil(f.read(0))\n    }\n    open_file(\"\") {|f|\n      assert_nil(f.read(1))\n      assert_equal(\"\", f.read)\n      assert_nil(f.read(1))\n    }\n    open_file(\"\") {|f|\n      s = \"x\"\n      assert_equal(\"\", f.read(nil, s))\n      assert_equal(\"\", s)\n    }\n    open_file(\"\") {|f|\n      s = \"x\"\n      assert_nil(f.read(10, s))\n      assert_equal(\"\", s)\n    }\n  end\n\n  def test_eof_0_rw\n    return unless respond_to? :open_file_rw\n    open_file_rw(\"\") {|f|\n      assert_equal(\"\", f.read)\n      assert_equal(\"\", f.read)\n      assert_equal(0, f.syswrite(\"\"))\n      assert_equal(\"\", f.read)\n    }\n  end\n\n  def test_eof_1\n    open_file(\"a\") {|f|\n      assert_equal(\"\", f.read(0))\n      assert_equal(\"a\", f.read(1))\n      assert_equal(\"\" , f.read(0))\n      assert_equal(\"\" , f.read(0))\n      assert_equal(\"\", f.read)\n      assert_nil(f.read(0))\n      assert_nil(f.read(0))\n    }\n    open_file(\"a\") {|f|\n      assert_equal(\"a\", f.read(1))\n      assert_nil(f.read(1))\n    }\n    open_file(\"a\") {|f|\n      assert_equal(\"a\", f.read(2))\n      assert_nil(f.read(1))\n      assert_equal(\"\", f.read)\n      assert_nil(f.read(1))\n    }\n    open_file(\"a\") {|f|\n      assert_equal(\"a\", f.read)\n      assert_nil(f.read(1))\n      assert_equal(\"\", f.read)\n      assert_nil(f.read(1))\n    }\n    open_file(\"a\") {|f|\n      assert_equal(\"a\", f.read(2))\n      assert_equal(\"\", f.read)\n      assert_equal(\"\", f.read)\n    }\n    open_file(\"a\") {|f|\n      assert_equal(\"a\", f.read)\n      assert_nil(f.read(0))\n    }\n    open_file(\"a\") {|f|\n      s = \"x\"\n      assert_equal(\"a\", f.read(nil, s))\n      assert_equal(\"a\", s)\n    }\n    open_file(\"a\") {|f|\n      s = \"x\"\n      assert_equal(\"a\", f.read(10, s))\n      assert_equal(\"a\", s)\n    }\n  end\n\n  def test_eof_2\n    open_file(\"\") {|f|\n      assert_equal(\"\", f.read)\n      assert(f.eof?)\n    }\n  end\n\n  def test_eof_3\n    open_file(\"\") {|f|\n      assert(f.eof?)\n    }\n  end\n\n  module Seek\n    def open_file_seek(content, pos)\n      open_file(content) do |f|\n        f.seek(pos)\n        yield f\n      end\n    end\n\n    def test_eof_0_seek\n      open_file_seek(\"\", 10) {|f|\n        assert_equal(10, f.pos)\n        assert_equal(\"\", f.read(0))\n        assert_equal(\"\", f.read)\n        assert_nil(f.read(0))\n        assert_equal(\"\", f.read)\n      }\n    end\n\n    def test_eof_1_seek\n      open_file_seek(\"a\", 10) {|f|\n        assert_equal(\"\", f.read)\n        assert_equal(\"\", f.read)\n      }\n      open_file_seek(\"a\", 1) {|f|\n        assert_equal(\"\", f.read)\n        assert_equal(\"\", f.read)\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "test/runner.rb",
    "content": "require 'test/unit'\n\nrcsid = %w$Id$\nVersion = rcsid[2].scan(/\\d+/).collect!(&method(:Integer)).freeze rescue nil\nRelease = rcsid[3].freeze rescue nil\n\nexit Test::Unit::AutoRunner.run(true, File.dirname($0))\n"
  },
  {
    "path": "test/sdbm/test_sdbm.rb",
    "content": "require 'test/unit'\n\nbegin\n  require 'sdbm'\nrescue LoadError\nend\n\nclass TestSDBM < Test::Unit::TestCase\n  def setup\n    @path = \"tmptest_sdbm_\"\n    assert_instance_of(SDBM, @sdbm = SDBM.new(@path))\n  end\n  def teardown\n    assert_nil(@sdbm.close)\n    ObjectSpace.each_object(SDBM) do |obj|\n      obj.close unless obj.closed?\n    end\n    File.delete *Dir.glob(\"tmptest_sdbm*\").to_a\n    p Dir.glob(\"tmptest_sdbm*\") if $DEBUG\n  end\n\n  def check_size(expect, sdbm=@sdbm)\n    assert_equal(expect, sdbm.size)\n    n = 0\n    sdbm.each { n+=1 }\n    assert_equal(expect, n)\n    if expect == 0\n      assert_equal(true, sdbm.empty?)\n    else\n      assert_equal(false, sdbm.empty?)\n    end\n  end\n\n  def have_fork?\n    begin\n      fork{}\n      true\n    rescue NotImplementedError\n      false\n    end\n  end\n\n  def test_version\n    assert(! SDBM.const_defined?(:VERSION))\n  end\n\n  def test_s_new_has_no_block\n    # SDBM.new ignore the block\n    foo = true\n    assert_instance_of(SDBM, sdbm = SDBM.new(\"tmptest_sdbm\") { foo = false })\n    assert_equal(foo, true)\n    assert_nil(sdbm.close)\n  end\n  def test_s_open_no_create\n    assert_nil(sdbm = SDBM.open(\"tmptest_sdbm\", nil))\n  ensure\n    sdbm.close if sdbm\n  end\n  def test_s_open_with_block\n    assert_equal(SDBM.open(\"tmptest_sdbm\") { :foo }, :foo)\n  end\n=begin\n  # Is it guaranteed on many OS?\n  def test_s_open_lock_one_process\n    # locking on one process\n    assert_instance_of(SDBM, sdbm  = SDBM.open(\"tmptest_sdbm\", 0644))\n    assert_raise(Errno::EWOULDBLOCK) {\n      begin\n\tSDBM.open(\"tmptest_sdbm\", 0644)\n      rescue Errno::EAGAIN\n\traise Errno::EWOULDBLOCK\n      end\n    }\n  end\n=end\n\n  def test_s_open_nolock\n    # sdbm 1.8.0 specific\n    if not defined? SDBM::NOLOCK\n      return\n    end\n    return unless have_fork?\t# snip this test\n\n    fork() {\n      assert_instance_of(SDBM, sdbm  = SDBM.open(\"tmptest_sdbm\", 0644,\n\t\t\t\t\t\tSDBM::NOLOCK))\n      sleep 2\n    }\n    sleep 1\n    begin\n      sdbm2 = nil\n      assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {\n\tassert_instance_of(SDBM, sdbm2 = SDBM.open(\"tmptest_sdbm\", 0644))\n      }\n    ensure\n      Process.wait\n      sdbm2.close if sdbm2\n    end\n\n    p Dir.glob(\"tmptest_sdbm*\") if $DEBUG\n\n    fork() {\n      assert_instance_of(SDBM, sdbm  = SDBM.open(\"tmptest_sdbm\", 0644))\n      sleep 2\n    }\n    begin\n      sleep 1\n      sdbm2 = nil\n      assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {\n\t# this test is failed on Cygwin98 (???)\n\tassert_instance_of(SDBM, sdbm2 = SDBM.open(\"tmptest_sdbm\", 0644,\n\t\t\t\t\t\t   SDBM::NOLOCK))\n      }\n    ensure\n      Process.wait\n      sdbm2.close if sdbm2\n    end\n  end\n\n  def test_s_open_error\n    return if /(ms|bcc)win|mingw|djgpp/ =~ RUBY_PLATFORM\n    assert_instance_of(SDBM, sdbm = SDBM.open(\"tmptest_sdbm\", 0))\n    assert_raise(Errno::EACCES) {\n      SDBM.open(\"tmptest_sdbm\", 0)\n    }\n    sdbm.close\n  end\n\n  def test_close\n    assert_instance_of(SDBM, sdbm = SDBM.open(\"tmptest_sdbm\"))\n    assert_nil(sdbm.close)\n\n    # closed SDBM file\n    assert_raise(SDBMError) { sdbm.close }\n  end\n\n  def test_aref\n    assert_equal('bar', @sdbm['foo'] = 'bar')\n    assert_equal('bar', @sdbm['foo'])\n\n    assert_nil(@sdbm['bar'])\n  end\n\n  def test_fetch\n    assert_equal('bar', @sdbm['foo']='bar')\n    assert_equal('bar', @sdbm.fetch('foo'))\n\n    # key not found\n    assert_raise(IndexError) {\n      @sdbm.fetch('bar')\n    }\n\n    # test for `ifnone' arg\n    assert_equal('baz', @sdbm.fetch('bar', 'baz'))\n\n    # test for `ifnone' block\n    assert_equal('foobar', @sdbm.fetch('bar') {|key| 'foo' + key })\n  end\n\n  def test_aset\n    num = 0\n    2.times {|i|\n      assert_equal('foo', @sdbm['foo'] = 'foo')\n      assert_equal('foo', @sdbm['foo'])\n      assert_equal('bar', @sdbm['foo'] = 'bar')\n      assert_equal('bar', @sdbm['foo'])\n\n      num += 1 if i == 0\n      assert_equal(num, @sdbm.size)\n\n      # assign nil\n      assert_equal('', @sdbm['bar'] = '')\n      assert_equal('', @sdbm['bar'])\n\n      num += 1 if i == 0\n      assert_equal(num, @sdbm.size)\n\n      # empty string\n      assert_equal('', @sdbm[''] = '')\n      assert_equal('', @sdbm[''])\n\n      num += 1 if i == 0\n      assert_equal(num, @sdbm.size)\n\n      # Fixnum\n      assert_equal('200', @sdbm['100'] = '200')\n      assert_equal('200', @sdbm['100'])\n\n      num += 1 if i == 0\n      assert_equal(num, @sdbm.size)\n\n      # Big key and value\n      assert_equal('y' * 100, @sdbm['x' * 100] = 'y' * 100)\n      assert_equal('y' * 100, @sdbm['x' * 100])\n\n      num += 1 if i == 0\n      assert_equal(num, @sdbm.size)\n    }\n  end\n\n  def test_index\n    assert_equal('bar', @sdbm['foo'] = 'bar')\n    assert_equal('foo', @sdbm.index('bar'))\n    assert_nil(@sdbm['bar'])\n  end\n\n  def test_indexes\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n    assert_equal(values.reverse, @sdbm.indexes(*keys.reverse))\n  end\n\n  def test_values_at\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n    assert_equal(values.reverse, @sdbm.values_at(*keys.reverse))\n  end\n\n  def test_select_with_block\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n    ret = @sdbm.select {|k,v|\n      assert_equal(k.upcase, v)\n      k != \"bar\"\n    }\n    assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],\n\t\t  ret.sort)\n  end\n\n  def test_length\n    num = 10\n    assert_equal(0, @sdbm.size)\n    num.times {|i|\n      i = i.to_s\n      @sdbm[i] = i\n    }\n    assert_equal(num, @sdbm.size)\n\n    @sdbm.shift\n\n    assert_equal(num - 1, @sdbm.size)\n  end\n\n  def test_empty?\n    assert_equal(true, @sdbm.empty?)\n    @sdbm['foo'] = 'FOO'\n    assert_equal(false, @sdbm.empty?)\n  end\n\n  def test_each_pair\n    n = 0\n    @sdbm.each_pair { n += 1 }\n    assert_equal(0, n)\n\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n\n    n = 0\n    ret = @sdbm.each_pair {|key, val|\n      assert_not_nil(i = keys.index(key))\n      assert_equal(val, values[i])\n\n      n += 1\n    }\n    assert_equal(keys.size, n)\n    assert_equal(@sdbm, ret)\n  end\n\n  def test_each_value\n    n = 0\n    @sdbm.each_value { n += 1 }\n    assert_equal(0, n)\n\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n\n    n = 0\n    ret = @sdbm.each_value {|val|\n      assert_not_nil(key = @sdbm.index(val))\n      assert_not_nil(i = keys.index(key))\n      assert_equal(val, values[i])\n\n      n += 1\n    }\n    assert_equal(keys.size, n)\n    assert_equal(@sdbm, ret)\n  end\n\n  def test_each_key\n    n = 0\n    @sdbm.each_key { n += 1 }\n    assert_equal(0, n)\n\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n\n    n = 0\n    ret = @sdbm.each_key {|key|\n      assert_not_nil(i = keys.index(key))\n      assert_equal(@sdbm[key], values[i])\n\n      n += 1\n    }\n    assert_equal(keys.size, n)\n    assert_equal(@sdbm, ret)\n  end\n\n  def test_keys\n    assert_equal([], @sdbm.keys)\n\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n\n    assert_equal(keys.sort, @sdbm.keys.sort)\n    assert_equal(values.sort, @sdbm.values.sort)\n  end\n\n  def test_values\n    test_keys\n  end\n\n  def test_shift\n    assert_nil(@sdbm.shift)\n    assert_equal(0, @sdbm.size)\n\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n\n    ret_keys = []\n    ret_values = []\n    while ret = @sdbm.shift\n      ret_keys.push ret[0]\n      ret_values.push ret[1]\n\n      assert_equal(keys.size - ret_keys.size, @sdbm.size)\n    end\n\n    assert_equal(keys.sort, ret_keys.sort)\n    assert_equal(values.sort, ret_values.sort)\n  end\n\n  def test_delete\n    keys = %w(foo bar baz)\n    values = %w(FOO BAR BAZ)\n    key = keys[1]\n\n    assert_nil(@sdbm.delete(key))\n    assert_equal(0, @sdbm.size)\n\n    @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values\n\n    assert_equal('BAR', @sdbm.delete(key))\n    assert_nil(@sdbm[key])\n    assert_equal(2, @sdbm.size)\n\n    assert_nil(@sdbm.delete(key))\n  end\n  def test_delete_with_block\n    key = 'no called block'\n    @sdbm[key] = 'foo'\n    assert_equal('foo', @sdbm.delete(key) {|k| k.replace 'called block'})\n    assert_equal('no called block', key)\n    assert_equal(0, @sdbm.size)\n\n    key = 'no called block'\n    assert_equal(:blockval,\n\t\t  @sdbm.delete(key) {|k| k.replace 'called block'; :blockval})\n    assert_equal('called block', key)\n    assert_equal(0, @sdbm.size)\n  end\n\n  def test_delete_if\n    v = \"0\"\n    100.times {@sdbm[v] = v; v = v.next}\n\n    ret = @sdbm.delete_if {|key, val| key.to_i < 50}\n    assert_equal(@sdbm, ret)\n    check_size(50, @sdbm)\n\n    ret = @sdbm.delete_if {|key, val| key.to_i >= 50}\n    assert_equal(@sdbm, ret)\n    check_size(0, @sdbm)\n\n    # break\n    v = \"0\"\n    100.times {@sdbm[v] = v; v = v.next}\n    check_size(100, @sdbm)\n    n = 0;\n    @sdbm.delete_if {|key, val|\n      break if n > 50\n      n+=1\n      true\n    }\n    assert_equal(51, n)\n    check_size(49, @sdbm)\n\n    @sdbm.clear\n\n    # raise\n    v = \"0\"\n    100.times {@sdbm[v] = v; v = v.next}\n    check_size(100, @sdbm)\n    n = 0;\n    begin\n      @sdbm.delete_if {|key, val|\n\traise \"runtime error\" if n > 50\n\tn+=1\n\ttrue\n      }\n    rescue\n    end\n    assert_equal(51, n)\n    check_size(49, @sdbm)\n  end\n\n  def test_reject\n    v = \"0\"\n    100.times {@sdbm[v] = v; v = v.next}\n\n    hash = @sdbm.reject {|key, val| key.to_i < 50}\n    assert_instance_of(Hash, hash)\n    assert_equal(100, @sdbm.size)\n\n    assert_equal(50, hash.size)\n    hash.each_pair {|key,val|\n      assert_equal(false, key.to_i < 50)\n      assert_equal(key, val)\n    }\n\n    hash = @sdbm.reject {|key, val| key.to_i < 100}\n    assert_instance_of(Hash, hash)\n    assert_equal(true, hash.empty?)\n  end\n\n  def test_clear\n    v = \"1\"\n    100.times {v = v.next; @sdbm[v] = v}\n\n    assert_equal(@sdbm, @sdbm.clear)\n\n    # validate SDBM#size\n    i = 0\n    @sdbm.each { i += 1 }\n    assert_equal(@sdbm.size, i)\n    assert_equal(0, i)\n  end\n\n  def test_invert\n    v = \"0\"\n    100.times {@sdbm[v] = v; v = v.next}\n\n    hash = @sdbm.invert\n    assert_instance_of(Hash, hash)\n    assert_equal(100, hash.size)\n    hash.each_pair {|key, val|\n      assert_equal(key.to_i, val.to_i)\n    }\n  end\n\n  def test_update\n    hash = {}\n    v = \"0\"\n    100.times {v = v.next; hash[v] = v}\n\n    @sdbm[\"101\"] = \"101\"\n    @sdbm.update hash\n    assert_equal(101, @sdbm.size)\n    @sdbm.each_pair {|key, val|\n      assert_equal(key.to_i, val.to_i)\n    }\n  end\n\n  def test_replace\n    hash = {}\n    v = \"0\"\n    100.times {v = v.next; hash[v] = v}\n\n    @sdbm[\"101\"] = \"101\"\n    @sdbm.replace hash\n    assert_equal(100, @sdbm.size)\n    @sdbm.each_pair {|key, val|\n      assert_equal(key.to_i, val.to_i)\n    }\n  end\n\n  def test_haskey?\n    assert_equal('bar', @sdbm['foo']='bar')\n    assert_equal(true,  @sdbm.has_key?('foo'))\n    assert_equal(false, @sdbm.has_key?('bar'))\n  end\n\n  def test_has_value?\n    assert_equal('bar', @sdbm['foo']='bar')\n    assert_equal(true,  @sdbm.has_value?('bar'))\n    assert_equal(false, @sdbm.has_value?('foo'))\n  end\n\n  def test_to_a\n    v = \"0\"\n    100.times {v = v.next; @sdbm[v] = v}\n\n    ary = @sdbm.to_a\n    assert_instance_of(Array, ary)\n    assert_equal(100, ary.size)\n    ary.each {|key,val|\n      assert_equal(key.to_i, val.to_i)\n    }\n  end\n\n  def test_to_hash\n    v = \"0\"\n    100.times {v = v.next; @sdbm[v] = v}\n\n    hash = @sdbm.to_hash\n    assert_instance_of(Hash, hash)\n    assert_equal(100, hash.size)\n    hash.each {|key,val|\n      assert_equal(key.to_i, val.to_i)\n    }\n  end\nend\n"
  },
  {
    "path": "test/soap/asp.net/hello.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<wsdl:definitions xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\"\nxmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\nxmlns:s=\"http://www.w3.org/2001/XMLSchema\"\nxmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\nxmlns:tns=\"http://localhost/WebService/\"\nxmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\"\nxmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\"\ntargetNamespace=\"http://localhost/WebService/\"\nxmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\">\n  <wsdl:types>\n    <s:schema elementFormDefault=\"qualified\"\ntargetNamespace=\"http://localhost/WebService/\">\n      <s:element name=\"HelloWorld\">\n        <s:complexType />\n      </s:element>\n      <s:element name=\"HelloWorldResponse\">\n        <s:complexType>\n          <s:sequence>\n            <s:element minOccurs=\"0\" maxOccurs=\"1\"\nname=\"HelloWorldResult\" type=\"s:string\" />\n          </s:sequence>\n        </s:complexType>\n      </s:element>\n      <s:element name=\"SayHello\">\n        <s:complexType>\n          <s:sequence>\n            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"name\"\ntype=\"s:string\" />\n          </s:sequence>\n        </s:complexType>\n      </s:element>\n      <s:element name=\"SayHelloResponse\">\n        <s:complexType>\n          <s:sequence>\n            <s:element minOccurs=\"0\" maxOccurs=\"1\"\nname=\"SayHelloResult\" type=\"s:string\" />\n          </s:sequence>\n        </s:complexType>\n      </s:element>\n    </s:schema>\n  </wsdl:types>\n  <wsdl:message name=\"HelloWorldSoapIn\">\n    <wsdl:part name=\"parameters\" element=\"tns:HelloWorld\" />\n  </wsdl:message>\n  <wsdl:message name=\"HelloWorldSoapOut\">\n    <wsdl:part name=\"parameters\" element=\"tns:HelloWorldResponse\" />\n  </wsdl:message>\n  <wsdl:message name=\"SayHelloSoapIn\">\n    <wsdl:part name=\"parameters\" element=\"tns:SayHello\" />\n  </wsdl:message>\n  <wsdl:message name=\"SayHelloSoapOut\">\n    <wsdl:part name=\"parameters\" element=\"tns:SayHelloResponse\" />\n  </wsdl:message>\n  <wsdl:portType name=\"Service1Soap\">\n    <wsdl:operation name=\"HelloWorld\">\n      <wsdl:input message=\"tns:HelloWorldSoapIn\" />\n      <wsdl:output message=\"tns:HelloWorldSoapOut\" />\n    </wsdl:operation>\n    <wsdl:operation name=\"SayHello\">\n      <wsdl:input message=\"tns:SayHelloSoapIn\" />\n      <wsdl:output message=\"tns:SayHelloSoapOut\" />\n    </wsdl:operation>\n  </wsdl:portType>\n  <wsdl:binding name=\"Service1Soap\" type=\"tns:Service1Soap\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\"\nstyle=\"document\" />\n    <wsdl:operation name=\"HelloWorld\">\n      <soap:operation\nsoapAction=\"http://localhost/WebService/HelloWorld\" style=\"document\" />\n      <wsdl:input>\n        <soap:body use=\"literal\" />\n      </wsdl:input>\n      <wsdl:output>\n        <soap:body use=\"literal\" />\n      </wsdl:output>\n    </wsdl:operation>\n    <wsdl:operation name=\"SayHello\">\n      <soap:operation soapAction=\"http://localhost/WebService/SayHello\"\nstyle=\"document\" />\n      <wsdl:input>\n        <soap:body use=\"literal\" />\n      </wsdl:input>\n      <wsdl:output>\n        <soap:body use=\"literal\" />\n      </wsdl:output>\n    </wsdl:operation>\n  </wsdl:binding>\n  <wsdl:service name=\"Service1\">\n    <documentation xmlns=\"http://schemas.xmlsoap.org/wsdl/\" />\n    <wsdl:port name=\"Service1Soap\" binding=\"tns:Service1Soap\">\n      <soap:address\nlocation=\"http://localhost/WebService/Service1.asmx\" />\n    </wsdl:port>\n  </wsdl:service>\n</wsdl:definitions>\n"
  },
  {
    "path": "test/soap/asp.net/test_aspdotnet.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/rpc/driver'\n\n\nmodule SOAP; module ASPDotNet\n\n\nclass TestASPDotNet < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = \"http://localhost/WebService/\"\n\n    def on_init\n      add_document_method(\n        self,\n        Namespace + 'SayHello',\n        'sayHello',\n        XSD::QName.new(Namespace, 'SayHello'),\n        XSD::QName.new(Namespace, 'SayHelloResponse')\n      )\n    end\n  \n    def sayHello(arg)\n      name = arg['name']\n      \"Hello #{name}\"\n    end\n  end\n\n  Port = 17171\n  Endpoint = \"http://localhost:#{Port}/\"\n\n  def setup\n    setup_server\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', Server::Namespace, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_document_method\n    @client = SOAP::RPC::Driver.new(Endpoint, Server::Namespace)\n    @client.wiredump_dev = STDOUT if $DEBUG\n    @client.add_document_method('sayHello', Server::Namespace + 'SayHello',\n      XSD::QName.new(Server::Namespace, 'SayHello'),\n      XSD::QName.new(Server::Namespace, 'SayHelloResponse'))\n    assert_equal(\"Hello Mike\", @client.sayHello(:name => \"Mike\"))\n  end\n\n  def test_aspdotnethandler\n    @client = SOAP::RPC::Driver.new(Endpoint, Server::Namespace)\n    @client.wiredump_dev = STDOUT if $DEBUG\n    @client.add_method_with_soapaction('sayHello', Server::Namespace + 'SayHello', 'name')\n    @client.default_encodingstyle = SOAP::EncodingStyle::ASPDotNetHandler::Namespace\n    assert_equal(\"Hello Mike\", @client.sayHello(\"Mike\"))\n  end\n\n  if defined?(HTTPAccess2)\n\n    # qualified!\n    REQUEST_ASPDOTNETHANDLER =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:sayHello xmlns:n1=\"http://localhost/WebService/\">\n      <n1:name>Mike</n1:name>\n    </n1:sayHello>\n  </env:Body>\n</env:Envelope>]\n\n    def test_aspdotnethandler_envelope\n      @client = SOAP::RPC::Driver.new(Endpoint, Server::Namespace)\n      @client.wiredump_dev = str = ''\n      @client.add_method_with_soapaction('sayHello', Server::Namespace + 'SayHello', 'name')\n      @client.default_encodingstyle = SOAP::EncodingStyle::ASPDotNetHandler::Namespace\n      assert_equal(\"Hello Mike\", @client.sayHello(\"Mike\"))\n      assert_equal(REQUEST_ASPDOTNETHANDLER, parse_requestxml(str))\n    end\n\n    def parse_requestxml(str)\n      str.split(/\\r?\\n\\r?\\n/)[3]\n    end\n\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/soap/calc/calc.rb",
    "content": "module CalcService\n  def self.add(lhs, rhs)\n    lhs + rhs\n  end\n\n  def self.sub(lhs, rhs)\n    lhs - rhs\n  end\n\n  def self.multi(lhs, rhs)\n    lhs * rhs\n  end\n\n  def self.div(lhs, rhs)\n    lhs / rhs\n  end\nend\n"
  },
  {
    "path": "test/soap/calc/calc2.rb",
    "content": "class CalcService2\n  def initialize(value = 0)\n    @value = value\n  end\n\n  def set_value(value)\n    @value = value\n  end\n\n  def get_value\n    @value\n  end\n\n  def +(rhs)\n    @value + rhs\n  end\n\n  def -(rhs)\n    @value - rhs\n  end\n\n  def *(rhs)\n    @value * rhs\n  end\n\n  def /(rhs)\n    @value / rhs\n  end\nend\n"
  },
  {
    "path": "test/soap/calc/server.cgi",
    "content": "require 'soap/rpc/cgistub'\n\nclass CalcServer < SOAP::RPC::CGIStub\n  def initialize(*arg)\n    super\n\n    require 'calc'\n    servant = CalcService\n    add_servant(servant, 'http://tempuri.org/calcService')\n  end\nend\n\nstatus = CalcServer.new('CalcServer', nil).start\n"
  },
  {
    "path": "test/soap/calc/server.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'soap/rpc/standaloneServer'\nrequire 'calc'\n\nclass CalcServer < SOAP::RPC::StandaloneServer\n  def initialize(*arg)\n    super\n\n    servant = CalcService\n    add_servant(servant, 'http://tempuri.org/calcService')\n  end\nend\n\nif $0 == __FILE__\n  status = CalcServer.new('CalcServer', nil, '0.0.0.0', 17171).start\nend\n"
  },
  {
    "path": "test/soap/calc/server2.rb",
    "content": "#!/usr/bin/env ruby\n\nrequire 'soap/rpc/standaloneServer'\nrequire 'calc2'\n\nclass CalcServer2 < SOAP::RPC::StandaloneServer\n  def on_init\n    servant = CalcService2.new\n    add_method(servant, 'set_value', 'newValue')\n    add_method(servant, 'get_value')\n    add_method_as(servant, '+', 'add', 'lhs')\n    add_method_as(servant, '-', 'sub', 'lhs')\n    add_method_as(servant, '*', 'multi', 'lhs')\n    add_method_as(servant, '/', 'div', 'lhs')\n  end\nend\n\nif $0 == __FILE__\n  status = CalcServer2.new('CalcServer', 'http://tempuri.org/calcService', '0.0.0.0', 17171).start\nend\n"
  },
  {
    "path": "test/soap/calc/test_calc.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'server.rb'\n\n\nmodule SOAP\nmodule Calc\n\n\nclass TestCalc < Test::Unit::TestCase\n  Port = 17171\n\n  def setup\n    @server = CalcServer.new(self.class.name, nil, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/\"\n    @calc = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService')\n    @calc.add_method('add', 'lhs', 'rhs')\n    @calc.add_method('sub', 'lhs', 'rhs')\n    @calc.add_method('multi', 'lhs', 'rhs')\n    @calc.add_method('div', 'lhs', 'rhs')\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @calc.reset_stream\n  end\n\n  def test_calc\n    assert_equal(3, @calc.add(1, 2))\n    assert_equal(-1.1, @calc.sub(1.1, 2.2))\n    assert_equal(2.42, @calc.multi(1.1, 2.2))\n    assert_equal(2, @calc.div(5, 2))\n    assert_equal(2.5, @calc.div(5.0, 2))\n    assert_equal(1.0/0.0, @calc.div(1.1, 0))\n    assert_raises(ZeroDivisionError) do\n      @calc.div(1, 0)\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/calc/test_calc2.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'server2.rb'\n\n\nmodule SOAP\nmodule Calc\n\n\nclass TestCalc2 < Test::Unit::TestCase\n  Port = 17171\n\n  def setup\n    @server = CalcServer2.new('CalcServer', 'http://tempuri.org/calcService', '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/\"\n    @var = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService')\n    @var.wiredump_dev = STDERR if $DEBUG\n    @var.add_method('set_value', 'newValue')\n    @var.add_method('get_value')\n    @var.add_method_as('+', 'add', 'rhs')\n    @var.add_method_as('-', 'sub', 'rhs')\n    @var.add_method_as('*', 'multi', 'rhs')\n    @var.add_method_as('/', 'div', 'rhs')\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @var.reset_stream\n  end\n\n  def test_calc2\n    assert_equal(1, @var.set_value(1))\n    assert_equal(3, @var + 2)\n    assert_equal(-1.2, @var - 2.2)\n    assert_equal(2.2, @var * 2.2)\n    assert_equal(0, @var / 2)\n    assert_equal(0.5, @var / 2.0)\n    assert_raises(ZeroDivisionError) do\n      @var / 0\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/calc/test_calc_cgi.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'logger'\nrequire 'webrick'\nrequire 'rbconfig'\n\n\nmodule SOAP\nmodule Calc\n\n\nclass TestCalcCGI < Test::Unit::TestCase\n  # This test shuld be run after installing ruby.\n  RUBYBIN = File.join(\n    Config::CONFIG[\"bindir\"],\n    Config::CONFIG[\"ruby_install_name\"] + Config::CONFIG[\"EXEEXT\"]\n  )\n  RUBYBIN << \" -d\" if $DEBUG\n\n  Port = 17171\n\n  def setup\n    logger = Logger.new(STDERR)\n    logger.level = Logger::Severity::ERROR\n    @server = WEBrick::HTTPServer.new(\n      :BindAddress => \"0.0.0.0\",\n      :Logger => logger,\n      :Port => Port,\n      :AccessLog => [],\n      :DocumentRoot => File.dirname(File.expand_path(__FILE__)),\n      :CGIPathEnv => ENV['PATH'],\n      :CGIInterpreter => RUBYBIN\n    )\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/server.cgi\"\n    @calc = SOAP::RPC::Driver.new(@endpoint, 'http://tempuri.org/calcService')\n    @calc.wiredump_dev = STDERR if $DEBUG\n    @calc.add_method('add', 'lhs', 'rhs')\n    @calc.add_method('sub', 'lhs', 'rhs')\n    @calc.add_method('multi', 'lhs', 'rhs')\n    @calc.add_method('div', 'lhs', 'rhs')\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @calc.reset_stream\n  end\n\n  def test_calc_cgi\n    assert_equal(3, @calc.add(1, 2))\n    assert_equal(-1.1, @calc.sub(1.1, 2.2))\n    assert_equal(2.42, @calc.multi(1.1, 2.2))\n    assert_equal(2, @calc.div(5, 2))\n    assert_equal(2.5, @calc.div(5.0, 2))\n    assert_equal(1.0/0.0, @calc.div(1.1, 0))\n    assert_raises(ZeroDivisionError) do\n      @calc.div(1, 0)\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/fault/test_customfault.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'soap/rpc/standaloneServer'\n\n\nmodule SOAP\nmodule Fault\n\n\nclass TestCustomFault < Test::Unit::TestCase\n  Port = 17171\n\n  class CustomFaultServer < SOAP::RPC::StandaloneServer\n    def on_init\n      add_method(self, 'fault', 'msg')\n    end\n\n    def fault(msg)\n      SOAPFault.new(SOAPString.new(\"mycustom\"),\n        SOAPString.new(\"error: #{msg}\"),\n        SOAPString.new(self.class.name))\n    end\n  end\n\n  def setup\n    @server = CustomFaultServer.new('customfault', 'urn:customfault', '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/\"\n    @client = SOAP::RPC::Driver.new(@endpoint, 'urn:customfault')\n    @client.wiredump_dev = STDERR if $DEBUG\n    @client.add_method(\"fault\", \"msg\")\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @client.reset_stream\n  end\n\n  def test_custom_fault\n    begin\n      @client.fault(\"message\")\n      assert(false, 'exception not raised')\n    rescue SOAP::FaultError => e\n      assert(true, 'exception raised')\n      assert_equal('error: message', e.message)\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/header/server.cgi",
    "content": "require 'pstore'\nrequire 'soap/rpc/cgistub'\nrequire 'soap/header/simplehandler'\n\n\nclass AuthHeaderPortServer < SOAP::RPC::CGIStub\n  PortName = 'http://tempuri.org/authHeaderPort'\n  SupportPortName = 'http://tempuri.org/authHeaderSupportPort'\n  MyHeaderName = XSD::QName.new(\"http://tempuri.org/authHeader\", \"auth\")\n  SessionDB = File.join(File.expand_path(File.dirname(__FILE__)), 'session.pstoredb')\n\n  class AuthHeaderService\n    def self.create\n      new\n    end\n\n    def deposit(amt)\n      \"deposit #{amt} OK\"\n    end\n\n    def withdrawal(amt)\n      \"withdrawal #{amt} OK\"\n    end\n  end\n\n  class AuthHeaderSupportService\n    def delete_sessiondb\n      File.unlink(SessionDB) if File.file?(SessionDB)\n      backup = SessionDB + \"~\"\n      File.unlink(backup) if File.file?(backup)\n    end\n  end\n\n  def initialize(*arg)\n    super\n    add_rpc_servant(AuthHeaderService.new, PortName)\n    add_rpc_servant(AuthHeaderSupportService.new, SupportPortName)\n    add_rpc_headerhandler(ServerAuthHeaderHandler.new)\n  end\n\n  class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler\n    Users = {\n      'NaHi' => 'passwd',\n      'HiNa' => 'wspass'\n    }\n\n    def initialize\n      super(MyHeaderName)\n      @db = PStore.new(SessionDB)\n      @db.transaction do\n\t@db[\"root\"] = {} unless @db.root?(\"root\")\n      end\n      @userid = @sessionid = nil\n    end\n\n    def login(userid, passwd)\n      userid and passwd and Users[userid] == passwd\n    end\n\n    def auth(sessionid)\n      in_sessiondb do |root|\n\troot[sessionid][0]\n      end\n    end\n\n    def create_session(userid)\n      in_sessiondb do |root|\n\twhile true\n  \t  key = create_sessionkey\n  \t  break unless root[key]\n   \tend\n    \troot[key] = [userid]\n     \tkey\n      end\n    end\n\n    def destroy_session(sessionkey)\n      in_sessiondb do |root|\n\troot.delete(sessionkey)\n      end\n    end\n\n    def on_simple_outbound\n      { \"sessionid\" => @sessionid }\n    end\n\n    def on_simple_inbound(my_header, mu)\n      succeeded = false\n      userid = my_header[\"userid\"]\n      passwd = my_header[\"passwd\"]\n      if login(userid, passwd)\n\tsucceeded = true\n      elsif sessionid = my_header[\"sessionid\"]\n\tif userid = auth(sessionid)\n\t  destroy_session(sessionid)\n\t  succeeded = true\n\tend\n      end\n      raise RuntimeError.new(\"authentication failed\") unless succeeded\n      @userid = userid\n      @sessionid = create_session(userid)\n    end\n\n  private\n\n    def create_sessionkey\n      Time.now.usec.to_s\n    end\n\n    def in_sessiondb\n      @db.transaction do\n\tyield(@db[\"root\"])\n      end\n    end\n  end\nend\n\n\nstatus = AuthHeaderPortServer.new('AuthHeaderPortServer', nil).start\n"
  },
  {
    "path": "test/soap/header/test_authheader.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/header/simplehandler'\n\n\nmodule SOAP\nmodule Header\n\n\nclass TestAuthHeader < Test::Unit::TestCase\n  Port = 17171\n  PortName = 'http://tempuri.org/authHeaderPort'\n  MyHeaderName = XSD::QName.new(\"http://tempuri.org/authHeader\", \"auth\")\n  DummyHeaderName = XSD::QName.new(\"http://tempuri.org/authHeader\", \"dummy\")\n\n  class AuthHeaderPortServer < SOAP::RPC::StandaloneServer\n    class AuthHeaderService\n      def self.create\n\tnew\n      end\n\n      def deposit(amt)\n\t\"deposit #{amt} OK\"\n      end\n\n      def withdrawal(amt)\n\t\"withdrawal #{amt} OK\"\n      end\n    end\n\n    def initialize(*arg)\n      super\n      add_rpc_servant(AuthHeaderService.new, PortName)\n      ServerAuthHeaderHandler.init\n      add_request_headerhandler(ServerAuthHeaderHandler)\n    end\n\n    class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler\n      class << self\n\tdef create\n\t  new\n\tend\n\n\tdef init\n\t  @users = {\n\t    'NaHi' => 'passwd',\n\t    'HiNa' => 'wspass'\n\t  }\n\t  @sessions = {}\n\tend\n\n\tdef login(userid, passwd)\n\t  userid and passwd and @users[userid] == passwd\n\tend\n\n\tdef auth(sessionid)\n\t  @sessions[sessionid][0]\n\tend\n\n\tdef create_session(userid)\n\t  while true\n\t    key = create_sessionkey\n\t    break unless @sessions[key]\n\t  end\n\t  @sessions[key] = [userid]\n\t  key\n\tend\n\n\tdef destroy_session(sessionkey)\n\t  @sessions.delete(sessionkey)\n\tend\n\n\tdef sessions\n\t  @sessions\n\tend\n\n      private\n\n\tdef create_sessionkey\n\t  Time.now.usec.to_s\n\tend\n      end\n\n      def initialize\n\tsuper(MyHeaderName)\n\t@userid = @sessionid = nil\n      end\n\n      def on_simple_outbound\n\t{ \"sessionid\" => @sessionid }\n      end\n\n      def on_simple_inbound(my_header, mu)\n\tauth = false\n\tuserid = my_header[\"userid\"]\n\tpasswd = my_header[\"passwd\"]\n\tif self.class.login(userid, passwd)\n\t  auth = true\n\telsif sessionid = my_header[\"sessionid\"]\n\t  if userid = self.class.auth(sessionid)\n\t    self.class.destroy_session(sessionid)\n\t    auth = true\n\t  end\n\tend\n\traise RuntimeError.new(\"authentication failed\") unless auth\n\t@userid = userid\n\t@sessionid = self.class.create_session(userid)\n      end\n    end\n  end\n\n  class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler\n    def initialize(userid, passwd, mustunderstand)\n      super(MyHeaderName)\n      @sessionid = nil\n      @userid = userid\n      @passwd = passwd\n      @mustunderstand = mustunderstand\n    end\n\n    def on_simple_outbound\n      if @sessionid\n\t{ \"sessionid\" => @sessionid }\n      else\n\t{ \"userid\" => @userid, \"passwd\" => @passwd }\n      end\n    end\n\n    def on_simple_inbound(my_header, mustunderstand)\n      @sessionid = my_header[\"sessionid\"]\n    end\n\n    def sessionid\n      @sessionid\n    end\n  end\n\n  class DummyHeaderHandler < SOAP::Header::SimpleHandler\n    def initialize(mustunderstand)\n      super(DummyHeaderName)\n      @mustunderstand = mustunderstand\n    end\n\n    def on_simple_outbound\n      { XSD::QName.new(\"foo\", \"bar\") => nil }\n    end\n\n    def on_simple_inbound(my_header, mustunderstand)\n    end\n  end\n\n  def setup\n    @endpoint = \"http://localhost:#{Port}/\"\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = AuthHeaderPortServer.new(self.class.name, nil, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      @server.start\n    }\n  end\n\n  def setup_client\n    @client = SOAP::RPC::Driver.new(@endpoint, PortName)\n    @client.wiredump_dev = STDERR if $DEBUG\n    @client.add_method('deposit', 'amt')\n    @client.add_method('withdrawal', 'amt')\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def test_success_no_mu\n    h = ClientAuthHeaderHandler.new('NaHi', 'passwd', false)\n    @client.headerhandler << h\n    do_transaction_check(h)\n  end\n\n  def test_success_mu\n    h = ClientAuthHeaderHandler.new('NaHi', 'passwd', true)\n    @client.headerhandler << h\n    do_transaction_check(h)\n  end\n\n  def test_no_mu\n    h = ClientAuthHeaderHandler.new('NaHi', 'passwd', true)\n    @client.headerhandler << h\n    @client.headerhandler << DummyHeaderHandler.new(false)\n    do_transaction_check(h)\n  end\n\n  def test_mu\n    h = ClientAuthHeaderHandler.new('NaHi', 'passwd', true)\n    @client.headerhandler << h\n    @client.headerhandler << (h2 = DummyHeaderHandler.new(true))\n    assert_raise(SOAP::UnhandledMustUnderstandHeaderError) do\n      assert_equal(\"deposit 150 OK\", @client.deposit(150))\n    end\n    @client.headerhandler.delete(h2)\n    @client.headerhandler << (h2 = DummyHeaderHandler.new(false))\n    do_transaction_check(h)\n  end\n\n  def do_transaction_check(h)\n    assert_equal(\"deposit 150 OK\", @client.deposit(150))\n    serversess = AuthHeaderPortServer::ServerAuthHeaderHandler.sessions[h.sessionid]\n    assert_equal(\"NaHi\", serversess[0])\n    assert_equal(\"withdrawal 120 OK\", @client.withdrawal(120))\n    serversess = AuthHeaderPortServer::ServerAuthHeaderHandler.sessions[h.sessionid]\n    assert_equal(\"NaHi\", serversess[0])\n  end\n\n  def test_authfailure\n    h = ClientAuthHeaderHandler.new('NaHi', 'pa', false)\n    @client.headerhandler << h\n    assert_raises(RuntimeError) do\n      @client.deposit(150)\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/header/test_authheader_cgi.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/header/simplehandler'\nrequire 'logger'\nrequire 'webrick'\nrequire 'rbconfig'\n\n\nmodule SOAP\nmodule Header\n\n\nclass TestAuthHeaderCGI < Test::Unit::TestCase\n  # This test shuld be run after installing ruby.\n  RUBYBIN = File.join(\n    Config::CONFIG[\"bindir\"],\n    Config::CONFIG[\"ruby_install_name\"] + Config::CONFIG[\"EXEEXT\"]\n  )\n  RUBYBIN << \" -d\" if $DEBUG\n  \n  Port = 17171\n  PortName = 'http://tempuri.org/authHeaderPort'\n  SupportPortName = 'http://tempuri.org/authHeaderSupportPort'\n  MyHeaderName = XSD::QName.new(\"http://tempuri.org/authHeader\", \"auth\")\n\n  class ClientAuthHeaderHandler < SOAP::Header::SimpleHandler\n    def initialize(userid, passwd)\n      super(MyHeaderName)\n      @sessionid = nil\n      @userid = userid\n      @passwd = passwd\n    end\n\n    def on_simple_outbound\n      if @sessionid\n\t{ \"sessionid\" => @sessionid }\n      else\n\t{ \"userid\" => @userid, \"passwd\" => @passwd }\n      end\n    end\n\n    def on_simple_inbound(my_header, mustunderstand)\n      @sessionid = my_header[\"sessionid\"]\n    end\n\n    def sessionid\n      @sessionid\n    end\n  end\n\n  def setup\n    @endpoint = \"http://localhost:#{Port}/\"\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @endpoint = \"http://localhost:#{Port}/server.cgi\"\n    logger = Logger.new(STDERR)\n    logger.level = Logger::Severity::ERROR\n    @server = WEBrick::HTTPServer.new(\n      :BindAddress => \"0.0.0.0\",\n      :Logger => logger,\n      :Port => Port,\n      :AccessLog => [],\n      :DocumentRoot => File.dirname(File.expand_path(__FILE__)),\n      :CGIPathEnv => ENV['PATH'],\n      :CGIInterpreter => RUBYBIN\n    )\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n  end\n\n  def setup_client\n    @client = SOAP::RPC::Driver.new(@endpoint, PortName)\n    @client.wiredump_dev = STDERR if $DEBUG\n    @client.add_method('deposit', 'amt')\n    @client.add_method('withdrawal', 'amt')\n    @supportclient = SOAP::RPC::Driver.new(@endpoint, SupportPortName)\n    @supportclient.add_method('delete_sessiondb')\n  end\n\n  def teardown\n    @supportclient.delete_sessiondb\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n    @supportclient.reset_stream\n  end\n\n  def test_success\n    h = ClientAuthHeaderHandler.new('NaHi', 'passwd')\n    @client.headerhandler << h\n    assert_equal(\"deposit 150 OK\", @client.deposit(150))\n    assert_equal(\"withdrawal 120 OK\", @client.withdrawal(120))\n  end\n\n  def test_authfailure\n    h = ClientAuthHeaderHandler.new('NaHi', 'pa')\n    @client.headerhandler << h\n    assert_raises(RuntimeError) do\n      @client.deposit(150)\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/header/test_simplehandler.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/header/simplehandler'\n\n\nmodule SOAP\nmodule Header\n\n\nclass TestSimpleHandler < Test::Unit::TestCase\n  Port = 17171\n  PortName = 'http://tempuri.org/authHeaderPort'\n\n  class PingPortServer < SOAP::RPC::StandaloneServer\n    class PingService\n      def self.create\n\tnew\n      end\n\n      def ping\n        Thread.current[:pingheader]\n      end\n    end\n\n    def initialize(*arg)\n      super\n      add_rpc_servant(PingService.new, PortName)\n      add_request_headerhandler(PingServerHeaderHandler)\n    end\n\n    class PingServerHeaderHandler < SOAP::Header::SimpleHandler\n      MyHeaderName = XSD::QName.new(\"http://xmlsoap.org/Ping\", \"PingHeader\")\n  \n      def self.create\n        new\n      end\n\n      def initialize()\n        super(MyHeaderName)\n      end\n\n      def on_simple_outbound\n        \"dummy\"\n      end\n\n      def on_simple_inbound(my_header, mu)\n        Thread.current[:pingheader] = my_header\n      end\n    end\n  end\n\n  class PingClientHeaderHandler < SOAP::Header::SimpleHandler\n    MyHeaderName = XSD::QName.new(\"http://xmlsoap.org/Ping\", \"PingHeader\")\n\n    def initialize(pingHeader)\n      super(MyHeaderName)\n      @pingHeader = pingHeader\n      @mustunderstand = false\n    end\n\n    def on_simple_outbound\n      @pingHeader # --- note, not a Hash\n    end\n\n    def on_simple_inbound(my_header, mustunderstand)\n      Thread.current[:pingheader] = my_header\n    end\n  end\n\n  def setup\n    @endpoint = \"http://localhost:#{Port}/\"\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = PingPortServer.new(self.class.name, nil, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      @server.start\n    }\n  end\n\n  def setup_client\n    @client = SOAP::RPC::Driver.new(@endpoint, PortName)\n    @client.wiredump_dev = STDERR if $DEBUG\n    @client.add_method('ping')\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def test_string\n    h = PingClientHeaderHandler.new('pingheader')\n    @client.headerhandler << h\n    assert_equal(\"pingheader\", @client.ping)\n    assert_equal(\"dummy\", Thread.current[:pingheader])\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/helloworld/hw_s.rb",
    "content": "require 'soap/rpc/standaloneServer'\n\nclass HelloWorldServer < SOAP::RPC::StandaloneServer\n  def on_init\n    add_method(self, 'hello_world', 'from')\n  end\n\n  def hello_world(from)\n    \"Hello World, from #{ from }\"\n  end\nend\n\nif $0 == __FILE__\n  server = HelloWorldServer.new('hws', 'urn:hws', '0.0.0.0', 17171)\n  server.start\nend\n"
  },
  {
    "path": "test/soap/helloworld/test_helloworld.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'hw_s.rb'\n\n\nmodule SOAP\nmodule HelloWorld\n\n\nclass TestHelloWorld < Test::Unit::TestCase\n  Port = 17171\n\n  def setup\n    @server = HelloWorldServer.new('hws', 'urn:hws', '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/\"\n    @client = SOAP::RPC::Driver.new(@endpoint, 'urn:hws')\n    @client.add_method(\"hello_world\", \"from\")\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @client.reset_stream\n  end\n\n  def test_hello_world\n    assert_equal(\"Hello World, from NaHi\", @client.hello_world(\"NaHi\"))\n    assert_equal(\"Hello World, from <&>\", @client.hello_world(\"<&>\"))\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/marshal/test_digraph.rb",
    "content": "require 'test/unit'\nrequire 'soap/marshal'\n\n\nmodule SOAP\nmodule Marshal\n\n\nclass Node; include SOAP::Marshallable\n  attr_reader :first, :second, :str\n\n  def initialize(*init_next)\n    @first = init_next[0]\n    @second = init_next[1]\n  end\nend\n\nclass TestDigraph < Test::Unit::TestCase\n  def setup\n    @n9 = Node.new\n    @n81 = Node.new(@n9)\n    @n82 = Node.new(@n9)\n    @n7 = Node.new(@n81, @n82)\n    @n61 = Node.new(@n7)\n    @n62 = Node.new(@n7)\n    @n5 = Node.new(@n61, @n62)\n    @n41 = Node.new(@n5)\n    @n42 = Node.new(@n5)\n    @n3 = Node.new(@n41, @n42)\n    @n21 = Node.new(@n3)\n    @n22 = Node.new(@n3)\n    @n1 = Node.new(@n21, @n22)\n  end\n\n  def test_marshal\n    f = File.open(\"digraph_marshalled_string.soap\", \"wb\")\n    SOAP::Marshal.dump(@n1, f)\n    f.close\n    f = File.open(\"digraph_marshalled_string.soap\")\n    str = f.read\n    f.close\n    newnode = SOAP::Marshal.unmarshal(str)\n    assert_equal(newnode.first.first.__id__, newnode.second.first.__id__)\n    assert_equal(newnode.first.first.first.first.__id__, newnode.second.first.second.first.__id__)\n  end\n\n  def teardown\n    if File.exist?(\"digraph_marshalled_string.soap\")\n      File.unlink(\"digraph_marshalled_string.soap\")\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/marshal/test_marshal.rb",
    "content": "require 'test/unit'\nrequire 'soap/marshal'\ndir = File.join(File.dirname(File.expand_path(__FILE__)), '../../ruby')\norgpath = $:.dup\nbegin\n  $:.push(dir)\n  require 'marshaltestlib'\nensure\n  $:.replace(orgpath)\nend\n\nmodule SOAP\nmodule Marshal\nclass TestMarshal < Test::Unit::TestCase\n  include MarshalTestLib\n\n  def encode(o)\n    SOAPMarshal.dump(o)\n  end\n\n  def decode(s)\n    SOAPMarshal.load(s)\n  end\nend\nend\nend\n"
  },
  {
    "path": "test/soap/marshal/test_struct.rb",
    "content": "require 'test/unit'\nrequire 'soap/marshal'\n\n\nmodule SOAP\nmodule Marshal\n\n\nFoo1 = ::Struct.new(\"Foo1\", :m)\nFoo2 = ::Struct.new(:m)\nclass Foo3\n  attr_accessor :m\nend\n\nclass TestStruct < Test::Unit::TestCase\n  def test_foo1\n    org = Foo1.new\n    org.m = org\n    obj = convert(org)\n    assert_equal(Foo1, obj.class)\n    assert_equal(obj.m, obj)\n  end\n\n  def test_foo2\n    org = Foo2.new\n    org.m = org\n    obj = convert(org)\n    assert_equal(Foo2, obj.class)\n    assert_equal(obj.m, obj)\n  end\n\n  def test_foo3\n    org = Foo3.new\n    org.m = org\n    obj = convert(org)\n    assert_equal(Foo3, obj.class)\n    assert_equal(obj.m, obj)\n  end\n\n  def convert(obj)\n    SOAP::Marshal.unmarshal(SOAP::Marshal.marshal(obj))\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/ssl/README",
    "content": "* certificates and keys in this directory is copied from http-access2 test.\n"
  },
  {
    "path": "test/soap/ssl/ca.cert",
    "content": "-----BEGIN CERTIFICATE-----\nMIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES\nMBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X\nDTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ\nBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR\nwjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d\nL5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY\nbS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi\nJI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm\ndEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA\nAaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w\nZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f\nUSKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe\n31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu\nSlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD\nggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+\nr/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY\nMJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj\nPvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U\nPbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a\nd/xgcK06UVQRL/HbEYGiQL056mc=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "test/soap/ssl/client.cert",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDKDCCAhCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES\nMBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X\nDTA0MDEzMTAzMTQ1OFoXDTM1MDEyMzAzMTQ1OFowZTELMAkGA1UEBgwCSlAxEjAQ\nBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRAwDgYDVQQDDAdleGFtcGxl\nMSIwIAYJKoZIhvcNAQkBDBNleGFtcGxlQGV4YW1wbGUub3JnMIGfMA0GCSqGSIb3\nDQEBAQUAA4GNADCBiQKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLW\njTkvsgOwbYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQ\ngNS6ew7/Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2Xf\newIDAQABo4GPMIGMMAwGA1UdEwEB/wQCMAAwMQYJYIZIAYb4QgENBCQWIlJ1Ynkv\nT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOFvay0H7lr2\nxUx6waYEV2bVDYQhMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYI\nKwYBBQUHAwQwDQYJKoZIhvcNAQEFBQADggEBABd2dYWqbDIWf5sWFvslezxJv8gI\nw64KCJBuyJAiDuf+oazr3016kMzAlt97KecLZDusGNagPrq02UX7YMoQFsWJBans\ncDtHrkM0al5r6/WGexNMgtYbNTYzt/IwodISGBgZ6dsOuhznwms+IBsTNDAvWeLP\nlt2tOqD8kEmjwMgn0GDRuKjs4EoboA3kMULb1p9akDV9ZESU3eOtpS5/G5J5msLI\n9WXbYBjcjvkLuJH9VsJhb+R58Vl0ViemvAHhPilSl1SPWVunGhv6FcIkdBEi1k9F\ne8BNMmsEjFiANiIRvpdLRbiGBt0KrKTndVfsmoKCvY48oCOvnzxtahFxfs8=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "test/soap/ssl/client.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLWjTkvsgOw\nbYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQgNS6ew7/\nLuq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2XfewIDAQAB\nAoGAZcz8llWErtsV3QB9gNb3S/PNADGjqBFjReva8n3jG2k4sZSibpwWTwUaTNtT\nZQgjSRKRvH1hk9XwffNAvXAQZNNkuj/16gO2oO45nyLj4dO365ujLptWnVIWDHOE\nuN0GeiZO+VzcCisT0WCq4tvtLeH8svrxzA8cbXIEyOK7NiECQQDwo2zPFyKAZ/Cu\nlDJ6zKT+RjfWwW7DgWzirAlTrt4ViMaW+IaDH29TmQpb4V4NuR3Xi+2Xl4oicu6S\n36TW9+/FAkEA3rgfOQJuLlWSnw1RTGwvnC816a/W7iYYY7B+0U4cDbfWl7IoXT4y\nM8nV/HESooviZLqBwzAYSoj3fFKYBKpGPwJAUO8GN5iWWA2dW3ooiDiv/X1sZmRk\ndojfMFWgRW747tEzya8Ivq0h6kH8w+5GjeMG8Gn1nRiwsulo6Ckj7dEx6QJACyui\n7UIQ8qP6GZ4aYMHgVW4Mvy7Bkeo5OO7GPYs0Xv/EdJFL8vlGnVBXOjUVoS9w6Gpu\nTbLg1QQvnX2rADjmEwJANxZO2GUkaWGsEif8aGW0x5g/IdaMGG27pTWk5zqix7P3\n1UDrdo/JOXhptovhRi06EppIxAxYmbh9vd9VN8Itlw==\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/soap/ssl/server.cert",
    "content": "-----BEGIN CERTIFICATE-----\nMIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES\nMBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB\nMB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx\nEjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh\nbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku\np+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S\nvtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/\nvHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg\nhkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd\nBgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud\nJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP\nCFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo\nzIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ\nRC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60\nDR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0\njQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM\nrRlQ\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "test/soap/ssl/server.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2\ncUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv\nMkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB\nAoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O\nrk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W\nIPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ\nOynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK\ngQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma\nqm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU\n9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm\nsyhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L\nmGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH\nLjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/soap/ssl/sslsvr.rb",
    "content": "require 'webrick/https'\nrequire 'logger'\nrequire 'rbconfig'\n\nrequire 'soap/rpc/httpserver'\n\nclass HelloWorldServer < SOAP::RPC::HTTPServer\nprivate\n\n  def on_init\n    self.level = Logger::Severity::FATAL\n    @default_namespace = 'urn:ssltst'\n    add_method(self, 'hello_world', 'from')\n  end\n\n  def hello_world(from)\n    \"Hello World, from #{ from }\"\n  end\nend\n\n\nif $0 == __FILE__\n  PORT = 17171\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  def cert(filename)\n    OpenSSL::X509::Certificate.new(File.open(File.join(DIR, filename)) { |f|\n      f.read\n    })\n  end\n\n  def key(filename)\n    OpenSSL::PKey::RSA.new(File.open(File.join(DIR, filename)) { |f|\n      f.read\n    })\n  end\n\n  $server = HelloWorldServer.new(\n    :BindAddress => \"0.0.0.0\",\n    :Port => PORT,\n    :AccessLog => [],\n    :SSLEnable => true,\n    :SSLCACertificateFile => File.join(DIR, 'ca.cert'),\n    :SSLCertificate => cert('server.cert'),\n    :SSLPrivateKey => key('server.key'),\n    :SSLVerifyClient => nil, #OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT|OpenSSL::SSL::VERIFY_PEER,\n    :SSLClientCA => cert('ca.cert'),\n    :SSLCertName => nil\n  )\n  t = Thread.new {\n    Thread.current.abort_on_exception = true\n    $server.start\n  }\n  STDOUT.sync = true\n  puts $$\n  t.join\nend\n"
  },
  {
    "path": "test/soap/ssl/subca.cert",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES\nMBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X\nDTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ\nBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe\nANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1\nd/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC\nkGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm\n3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x\n4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC\nAwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P\ncGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH\nLzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN\nrT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4\nc4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha\nLKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H\nySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X\nSF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ\nuY/bPeOBYiVsOYVe\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "test/soap/ssl/test_ssl.rb",
    "content": "require 'test/unit'\nbegin\n  require 'http-access2'\nrescue LoadError\nend\nrequire 'soap/rpc/driver'\n\nif defined?(HTTPAccess2) and defined?(OpenSSL)\n\nmodule SOAP; module SSL\n\n\nclass TestSSL < Test::Unit::TestCase\n  PORT = 17171\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n  require 'rbconfig'\n  RUBY = File.join(\n    Config::CONFIG[\"bindir\"],\n    Config::CONFIG[\"ruby_install_name\"] + Config::CONFIG[\"EXEEXT\"]\n  )\n\n  def setup\n    @url = \"https://localhost:#{PORT}/hello\"\n    @serverpid = @client = nil\n    @verify_callback_called = false\n    setup_server\n    setup_client\n  end\n\n  def teardown\n    teardown_client\n    teardown_server\n  end\n\n  def test_options\n    cfg = @client.streamhandler.client.ssl_config\n    assert_nil(cfg.client_cert)\n    assert_nil(cfg.client_key)\n    assert_nil(cfg.client_ca)\n    assert_equal(OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, cfg.verify_mode)\n    assert_nil(cfg.verify_callback)\n    assert_nil(cfg.timeout)\n    assert_equal(OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2, cfg.options)\n    assert_equal(\"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH\", cfg.ciphers)\n    assert_instance_of(OpenSSL::X509::Store, cfg.cert_store)\n    # dummy call to ensure sslsvr initialization finished.\n    assert_raise(OpenSSL::SSL::SSLError) do\n      @client.hello_world(\"ssl client\")\n    end\n  end\n\n  def test_verification\n    cfg = @client.options\n    cfg[\"protocol.http.ssl_config.verify_callback\"] = method(:verify_callback).to_proc\n    @verify_callback_called = false\n    ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n    assert_equal(\"certificate verify failed\", ssle.message)\n    assert(@verify_callback_called)\n    #\n    cfg[\"protocol.http.ssl_config.client_cert\"] = File.join(DIR, \"client.cert\")\n    cfg[\"protocol.http.ssl_config.client_key\"] = File.join(DIR, \"client.key\")\n    @verify_callback_called = false\n    ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n    assert_equal(\"certificate verify failed\", ssle.message)\n    assert(@verify_callback_called)\n    #\n    cfg[\"protocol.http.ssl_config.ca_file\"] = File.join(DIR, \"ca.cert\")\n    @verify_callback_called = false\n    ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n    assert_equal(\"certificate verify failed\", ssle.message)\n    assert(@verify_callback_called)\n    #\n    cfg[\"protocol.http.ssl_config.ca_file\"] = File.join(DIR, \"subca.cert\")\n    @verify_callback_called = false\n    assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n    assert(@verify_callback_called)\n    #\n    cfg[\"protocol.http.ssl_config.verify_depth\"] = \"1\"\n    @verify_callback_called = false\n    ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n    assert_equal(\"certificate verify failed\", ssle.message)\n    assert(@verify_callback_called)\n    #\n    cfg[\"protocol.http.ssl_config.verify_depth\"] = \"\"\n    cfg[\"protocol.http.ssl_config.cert_store\"] = OpenSSL::X509::Store.new\n    cfg[\"protocol.http.ssl_config.verify_mode\"] = OpenSSL::SSL::VERIFY_PEER.to_s\n    ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n    assert_equal(\"certificate verify failed\", ssle.message)\n    #\n    cfg[\"protocol.http.ssl_config.verify_mode\"] = \"\"\n    assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n  end\n\n  def test_property\n    testpropertyname = File.join(DIR, 'soapclient.properties')\n    File.open(testpropertyname, \"w\") do |f|\n      f <<<<__EOP__\nprotocol.http.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER\n# depth: 1 causes an error (intentional)\nprotocol.http.ssl_config.verify_depth = 1\nprotocol.http.ssl_config.client_cert = #{File.join(DIR, 'client.cert')}\nprotocol.http.ssl_config.client_key = #{File.join(DIR, 'client.key')}\nprotocol.http.ssl_config.ca_file = #{File.join(DIR, 'ca.cert')}\nprotocol.http.ssl_config.ca_file = #{File.join(DIR, 'subca.cert')}\nprotocol.http.ssl_config.ciphers = ALL\n__EOP__\n    end\n    begin\n      @client.loadproperty(testpropertyname)\n      @client.options[\"protocol.http.ssl_config.verify_callback\"] = method(:verify_callback).to_proc\n      @verify_callback_called = false\n      # NG with String\n      ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n      assert_equal(\"certificate verify failed\", ssle.message)\n      assert(@verify_callback_called)\n      # NG with Integer\n      @client.options[\"protocol.http.ssl_config.verify_depth\"] = 0\n      ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n      assert_equal(\"certificate verify failed\", ssle.message)\n      assert(@verify_callback_called)\n      # OK with empty\n      @client.options[\"protocol.http.ssl_config.verify_depth\"] = \"\"\n      @verify_callback_called = false\n      assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n      assert(@verify_callback_called)\n      # OK with nil\n      @client.options[\"protocol.http.ssl_config.verify_depth\"] = nil\n      @verify_callback_called = false\n      assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n      assert(@verify_callback_called)\n      # OK with String\n      @client.options[\"protocol.http.ssl_config.verify_depth\"] = \"3\"\n      @verify_callback_called = false\n      assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n      assert(@verify_callback_called)\n      # OK with Integer\n      @client.options[\"protocol.http.ssl_config.verify_depth\"] = 3\n      @verify_callback_called = false\n      assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n      assert(@verify_callback_called)\n    ensure\n      File.unlink(testpropertyname)\n    end\n  end\n\n  def test_ciphers\n    cfg = @client.options\n    cfg[\"protocol.http.ssl_config.client_cert\"] = File.join(DIR, 'client.cert')\n    cfg[\"protocol.http.ssl_config.client_key\"] = File.join(DIR, 'client.key')\n    cfg[\"protocol.http.ssl_config.ca_file\"] = File.join(DIR, \"ca.cert\")\n    cfg[\"protocol.http.ssl_config.ca_file\"] = File.join(DIR, \"subca.cert\")\n    #cfg.timeout = 123\n    cfg[\"protocol.http.ssl_config.ciphers\"] = \"!ALL\"\n    #\n    ssle = assert_raise(OpenSSL::SSL::SSLError) {@client.hello_world(\"ssl client\")}\n    # depends on OpenSSL version. (?:0.9.8|0.9.7)\n    assert_match(/\\A(?:SSL_CTX_set_cipher_list:: no cipher match|no ciphers available)\\z/, ssle.message)\n    #\n    cfg[\"protocol.http.ssl_config.ciphers\"] = \"ALL\"\n    assert_equal(\"Hello World, from ssl client\", @client.hello_world(\"ssl client\"))\n  end\n\nprivate\n\n  def q(str)\n    %Q[\"#{str}\"]\n  end\n\n  def setup_server\n    svrcmd = \"#{q(RUBY)} \"\n    #svrcmd << \"-d \" if $DEBUG\n    svrcmd << File.join(DIR, \"sslsvr.rb\")\n    svrout = IO.popen(svrcmd)\n    @serverpid = Integer(svrout.gets.chomp)\n  end\n\n  def setup_client\n    @client = SOAP::RPC::Driver.new(@url, 'urn:ssltst')\n    @client.add_method(\"hello_world\", \"from\")\n  end\n\n  def teardown_server\n    if @serverpid\n      Process.kill('KILL', @serverpid)\n      Process.waitpid(@serverpid)\n    end\n  end\n\n  def teardown_client\n    @client.reset_stream if @client\n  end\n\n  def verify_callback(ok, cert)\n    @verify_callback_called = true\n    p [\"client\", ok, cert] if $DEBUG\n    ok\n  end\nend\n\n\nend; end\n\nend\n"
  },
  {
    "path": "test/soap/struct/test_struct.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/httpserver'\nrequire 'soap/rpc/driver'\n\n\nmodule SOAP; module Struct\n\n\nclass TestStruct < Test::Unit::TestCase\n  Namespace = \"urn:example.com:simpletype-rpc\"\n  class Server < ::SOAP::RPC::HTTPServer\n    @@test_struct = ::Struct.new(:one, :two)\n\n    def on_init\n      add_method(self, 'a_method')\n    end\n  \n    def a_method\n      @@test_struct.new(\"string\", 1)\n    end\n  end\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new(\n      :Port => Port,\n      :BindAddress => \"0.0.0.0\",\n      :AccessLog => [],\n      :SOAPDefaultNamespace => Namespace\n    )\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    @client = ::SOAP::RPC::Driver.new(\"http://localhost:#{Port}/\", Namespace)\n    @client.wiredump_dev = STDERR if $DEBUG\n    @client.add_method('a_method')\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_struct\n    assert_equal(\"string\", @client.a_method.one)\n    assert_equal(1, @client.a_method.two)\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/soap/swa/test_file.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/attachment'\n\n\nmodule SOAP\nmodule SWA\n\n\nclass TestFile < Test::Unit::TestCase\n  Port = 17171\n  THIS_FILE = File.expand_path(__FILE__)\n\n  class SwAService\n    def get_file\n      return {\n     \t'name' => $0,\n\t'file' => SOAP::Attachment.new(File.open(THIS_FILE)) # closed when GCed.\n      }\n    end\n  \n    def put_file(name, file)\n      \"File '#{name}' was received ok.\"\n    end\n  end\n\n  def setup\n    @server = SOAP::RPC::StandaloneServer.new('SwAServer',\n      'http://www.acmetron.com/soap', '0.0.0.0', Port)\n    @server.add_servant(SwAService.new)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/\"\n    @client = SOAP::RPC::Driver.new(@endpoint, 'http://www.acmetron.com/soap')\n    @client.add_method('get_file')\n    @client.add_method('put_file', 'name', 'file')\n    @client.wiredump_dev = STDERR if $DEBUG\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @client.reset_stream\n  end\n\n  def test_get_file\n    assert_equal(\n      File.open(THIS_FILE) { |f| f.read },\n      @client.get_file['file'].content\n    )\n  end\n\n  def test_put_file\n    assert_equal(\n      \"File 'foo' was received ok.\",\n      @client.put_file('foo',\n\tSOAP::Attachment.new(File.open(THIS_FILE)))\n    )\n    assert_equal(\n      \"File 'bar' was received ok.\",\n      @client.put_file('bar',\n\tSOAP::Attachment.new(File.open(THIS_FILE) { |f| f.read }))\n    )\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/soap/test_basetype.rb",
    "content": "require 'test/unit'\nrequire 'soap/baseData'\n\n\nmodule SOAP\n\n\nclass TestSOAP < Test::Unit::TestCase\n  NegativeZero = (-1.0 / (1.0 / 0.0))\n\n  def setup\n    # Nothing to do.\n  end\n\n  def teardown\n    # Nothing to do.\n  end\n\n  def assert_parsed_result(klass, str)\n    o = klass.new(str)\n    assert_equal(str, o.to_s)\n  end\n\n  def test_SOAPNil\n    o = SOAP::SOAPNil.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::NilLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    o = SOAP::SOAPNil.new(nil)\n    assert_equal(true, o.is_nil)\n    assert_equal(nil, o.data)\n    assert_equal(\"\", o.to_s)\n    o = SOAP::SOAPNil.new('var')\n    assert_equal(false, o.is_nil)\n    assert_equal('var', o.data)\n    assert_equal('var', o.to_s)\n  end\n\n  def test_SOAPString\n    o = SOAP::SOAPString.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::StringLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    str = \"abc\"\n    assert_equal(str, SOAP::SOAPString.new(str).data)\n    assert_equal(str, SOAP::SOAPString.new(str).to_s)\n    assert_raises(XSD::ValueSpaceError) do\n      SOAP::SOAPString.new(\"\\0\")\n    end\n    assert_raises(XSD::ValueSpaceError) do\n      p SOAP::SOAPString.new(\"\\xC0\\xC0\").to_s\n    end\n  end\n\n  def test_SOAPBoolean\n    o = SOAP::SOAPBoolean.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::BooleanLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      [\"true\", true],\n      [\"1\", true],\n      [\"false\", false],\n      [\"0\", false],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPBoolean.new(data).data)\n      assert_equal(expected.to_s, SOAP::SOAPBoolean.new(data).to_s)\n    end\n\n    assert_raises(XSD::ValueSpaceError) do\n      SOAP::SOAPBoolean.new(\"nil\").to_s\n    end\n  end\n\n  def test_SOAPDecimal\n    o = SOAP::SOAPDecimal.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DecimalLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      -9999999999,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789,\n    ]\n    targets.each do |dec|\n      assert_equal(dec.to_s, SOAP::SOAPDecimal.new(dec).data)\n    end\n\n    targets = [\n      \"0\",\n      \"0.00000001\",\n      \"1000000000\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n      \"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123.45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",\n    ]\n    targets.each do |str|\n      assert_equal(str, SOAP::SOAPDecimal.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"0.0\", \"0\"],\n      [\"-0.0\", \"0\"],\n      [\"+0.0\", \"0\"],\n      [\"0.\", \"0\"],\n      [\".0\", \"0\"],\n      [\n\t\"+0.12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"0.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\"\n      ],\n      [\n\t\".0000012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"0.000001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\"\n      ],\n      [\n\t\"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\",\n\t\"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n      ],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPDecimal.new(data).to_s)\n    end\n\n    targets = [\n      \"0.000000000000a\",\n      \"00a.0000000000001\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tSOAP::SOAPDecimal.new(d)\n      end\n    end\n  end\n\n  def test_SOAPFloat\n    o = SOAP::SOAPFloat.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::FloatLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      3.14159265358979,\n      12.34e36,\n      1.402e-45,\n      -1.402e-45,\n    ]\n    targets.each do |f|\n      assert_equal(f, SOAP::SOAPFloat.new(f).data)\n    end\n\n    targets = [\n      \"+3.141592654\",\n      \"+1.234e+37\",\n      \"+1.402e-45\",\n      \"-1.402e-45\",\n    ]\n    targets.each do |f|\n      assert_equal(f, SOAP::SOAPFloat.new(f).to_s)\n    end\n\n    targets = [\n      [3, \"+3\"], \t# should be 3.0?\n      [-2, \"-2\"],\t# ditto\n      [3.14159265358979, \"+3.141592654\"],\n      [12.34e36, \"+1.234e+37\"],\n      [1.402e-45, \"+1.402e-45\"],\n      [-1.402e-45, \"-1.402e-45\"],\n      [\"1.402e\", \"+1.402\"],\n      [\"12.34E36\", \"+1.234e+37\"],\n      [\"1.402E-45\", \"+1.402e-45\"],\n      [\"-1.402E-45\", \"-1.402e-45\"],\n      [\"1.402E\", \"+1.402\"],\n    ]\n    targets.each do |f, str|\n      assert_equal(str, SOAP::SOAPFloat.new(f).to_s)\n    end\n\n    assert_equal(\"+0\", SOAP::SOAPFloat.new(+0.0).to_s)\n    assert_equal(\"-0\", SOAP::SOAPFloat.new(NegativeZero).to_s)\n    assert(SOAP::SOAPFloat.new(0.0/0.0).data.nan?)\n    assert_equal(\"INF\", SOAP::SOAPFloat.new(1.0/0.0).to_s)\n    assert_equal(1, SOAP::SOAPFloat.new(1.0/0.0).data.infinite?)\n    assert_equal(\"-INF\", SOAP::SOAPFloat.new(-1.0/0.0).to_s)\n    assert_equal(-1, SOAP::SOAPFloat.new(-1.0/0.0).data.infinite?)\n\n    targets = [\n      \"0.000000000000a\",\n      \"00a.0000000000001\",\n      \"+-5\",\n      \"5_0\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tSOAP::SOAPFloat.new(d)\n      end\n    end\n  end\n\n  def test_SOAPDouble\n    o = SOAP::SOAPDouble.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DoubleLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      3.14159265358979,\n      12.34e36,\n      1.402e-45,\n      -1.402e-45,\n    ]\n    targets.each do |f|\n      assert_equal(f, SOAP::SOAPDouble.new(f).data)\n    end\n\n    targets = [\n      \"+3.14159265358979\",\n      \"+1.234e+37\",\n      \"+1.402e-45\",\n      \"-1.402e-45\",\n    ]\n    targets.each do |f|\n      assert_equal(f, SOAP::SOAPDouble.new(f).to_s)\n    end\n\n    targets = [\n      [3, \"+3\"],\t# should be 3.0?\n      [-2, \"-2\"],\t# ditto.\n      [3.14159265358979, \"+3.14159265358979\"],\n      [12.34e36, \"+1.234e+37\"],\n      [1.402e-45, \"+1.402e-45\"],\n      [-1.402e-45, \"-1.402e-45\"],\n      [\"1.402e\", \"+1.402\"],\n      [\"12.34E36\", \"+1.234e+37\"],\n      [\"1.402E-45\", \"+1.402e-45\"],\n      [\"-1.402E-45\", \"-1.402e-45\"],\n      [\"1.402E\", \"+1.402\"],\n    ]\n    targets.each do |f, str|\n      assert_equal(str, SOAP::SOAPDouble.new(f).to_s)\n    end\n\n    assert_equal(\"+0\", SOAP::SOAPFloat.new(+0.0).to_s)\n    assert_equal(\"-0\", SOAP::SOAPFloat.new(NegativeZero).to_s)\n    assert_equal(\"NaN\", SOAP::SOAPDouble.new(0.0/0.0).to_s)\n    assert(SOAP::SOAPDouble.new(0.0/0.0).data.nan?)\n    assert_equal(\"INF\", SOAP::SOAPDouble.new(1.0/0.0).to_s)\n    assert_equal(1, SOAP::SOAPDouble.new(1.0/0.0).data.infinite?)\n    assert_equal(\"-INF\", SOAP::SOAPDouble.new(-1.0/0.0).to_s)\n    assert_equal(-1, SOAP::SOAPDouble.new(-1.0/0.0).data.infinite?)\n\n    targets = [\n      \"0.000000000000a\",\n      \"00a.0000000000001\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tSOAP::SOAPDouble.new(d)\n      end\n    end\n  end\n\n  def test_SOAPDuration\n    o = SOAP::SOAPDuration.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DurationLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"P1Y2M3DT4H5M6S\",\n      \"P1234Y5678M9012DT3456H7890M1234.5678S\",\n      \"P0DT3456H7890M1234.5678S\",\n      \"P1234Y5678M9012D\",\n      \"-P1234Y5678M9012DT3456H7890M1234.5678S\",\n      \"P5678M9012DT3456H7890M1234.5678S\",\n      \"-P1234Y9012DT3456H7890M1234.5678S\",\n      \"+P1234Y5678MT3456H7890M1234.5678S\",\n      \"P1234Y5678M9012DT7890M1234.5678S\",\n      \"-P1234Y5678M9012DT3456H1234.5678S\",\n      \"+P1234Y5678M9012DT3456H7890M\",\n      \"P123400000000000Y\",\n      \"-P567800000000000M\",\n      \"+P901200000000000D\",\n      \"P0DT345600000000000H\",\n      \"-P0DT789000000000000M\",\n      \"+P0DT123400000000000.000000000005678S\",\n      \"P1234YT1234.5678S\",\n      \"-P5678MT7890M\",\n      \"+P9012DT3456H\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPDuration, str)\n    end\n\n    targets = [\n      [\"P0Y0M0DT0H0M0S\",\n        \"P0D\"],\n      [\"-P0DT0S\",\n        \"-P0D\"],\n      [\"P01234Y5678M9012DT3456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y005678M9012DT3456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M0009012DT3456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M9012DT00003456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M9012DT3456H000007890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M9012DT3456H7890M0000001234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPDuration.new(data).to_s)\n    end\n  end\n\n  def test_SOAPDateTime\n    o = SOAP::SOAPDateTime.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DateTimeLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002-05-18T16:52:20Z\",\n      \"0001-01-01T00:00:00Z\",\n      \"9999-12-31T23:59:59Z\",\n      \"19999-12-31T23:59:59Z\",\n      \"2002-12-31T23:59:59.999Z\",\n      \"2002-12-31T23:59:59.001Z\",\n      \"2002-12-31T23:59:59.99999999999999999999Z\",\n      \"2002-12-31T23:59:59.00000000000000000001Z\",\n      \"2002-12-31T23:59:59+09:00\",\n      \"2002-12-31T23:59:59+00:01\",\n      \"2002-12-31T23:59:59-00:01\",\n      \"2002-12-31T23:59:59-23:59\",\n      \"2002-12-31T23:59:59.00000000000000000001+13:30\",\n      \"2002-12-31T23:59:59.51375Z\",\n      \"2002-12-31T23:59:59.51345+12:34\",\n      \"-2002-05-18T16:52:20Z\",\n      \"-4711-12-31T23:59:59Z\",\n      \"-4713-01-01T12:00:00Z\",\n      \"-19999-12-31T23:59:59Z\",\n      \"-2002-12-31T23:59:59+00:01\",\n      \"-0001-12-31T23:59:59.00000000000000000001+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPDateTime, str)\n    end\n\n    targets = [\n      [\"2002-12-31T23:59:59.00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"2002-12-31T23:59:59+00:00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"2002-12-31T23:59:59-00:00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59.00\",\n\t\"-2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59+00:00\",\n\t\"-2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59-00:00\",\n\t\"-2002-12-31T23:59:59Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPDateTime.new(data).to_s)\n      d = DateTime.parse(data)\n      d >>= 12 if d.year < 0    # XSDDateTime.year(-1) == DateTime.year(0)\n      assert_equal(expected, SOAP::SOAPDateTime.new(d).to_s)\n    end\n\n    targets = [\n      \"1-05-18T16:52:20Z\",\n      \"05-18T16:52:20Z\",\n      \"2002-05T16:52:20Z\",\n      \"2002-05-18T16:52Z\",\n      \"\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError, d.to_s) do\n\tSOAP::SOAPDateTime.new(d)\n      end\n    end\n  end\n\n  def test_SOAPTime\n    o = SOAP::SOAPTime.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::TimeLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"16:52:20Z\",\n      \"00:00:00Z\",\n      \"23:59:59Z\",\n      \"23:59:59.999Z\",\n      \"23:59:59.001Z\",\n      \"23:59:59.99999999999999999999Z\",\n      \"23:59:59.00000000000000000001Z\",\n      \"23:59:59+09:00\",\n      \"23:59:59+00:01\",\n      \"23:59:59-00:01\",\n      \"23:59:59-23:59\",\n      \"23:59:59.00000000000000000001+13:30\",\n      \"23:59:59.51375Z\",\n      \"23:59:59.51375+12:34\",\n      \"23:59:59+00:01\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPTime, str)\n    end\n\n    targets = [\n      [\"23:59:59.00\",\n\t\"23:59:59Z\"],\n      [\"23:59:59+00:00\",\n\t\"23:59:59Z\"],\n      [\"23:59:59-00:00\",\n\t\"23:59:59Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPTime.new(data).to_s)\n    end\n  end\n\n  def test_SOAPDate\n    o = SOAP::SOAPDate.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DateLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002-05-18Z\",\n      \"0001-01-01Z\",\n      \"9999-12-31Z\",\n      \"19999-12-31Z\",\n      \"2002-12-31+09:00\",\n      \"2002-12-31+00:01\",\n      \"2002-12-31-00:01\",\n      \"2002-12-31-23:59\",\n      \"2002-12-31+13:30\",\n      \"-2002-05-18Z\",\n      \"-19999-12-31Z\",\n      \"-2002-12-31+00:01\",\n      \"-0001-12-31+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPDate, str)\n    end\n\n    targets = [\n      [\"2002-12-31\",\n\t\"2002-12-31Z\"],\n      [\"2002-12-31+00:00\",\n\t\"2002-12-31Z\"],\n      [\"2002-12-31-00:00\",\n\t\"2002-12-31Z\"],\n      [\"-2002-12-31\",\n\t\"-2002-12-31Z\"],\n      [\"-2002-12-31+00:00\",\n\t\"-2002-12-31Z\"],\n      [\"-2002-12-31-00:00\",\n\t\"-2002-12-31Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPDate.new(data).to_s)\n      d = Date.parse(data)\n      d >>= 12 if d.year < 0    # XSDDate.year(-1) == Date.year(0)\n      assert_equal(expected, SOAP::SOAPDate.new(d).to_s)\n    end\n  end\n\n  def test_SOAPGYearMonth\n    o = SOAP::SOAPGYearMonth.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GYearMonthLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002-05Z\",\n      \"0001-01Z\",\n      \"9999-12Z\",\n      \"19999-12Z\",\n      \"2002-12+09:00\",\n      \"2002-12+00:01\",\n      \"2002-12-00:01\",\n      \"2002-12-23:59\",\n      \"2002-12+13:30\",\n      \"-2002-05Z\",\n      \"-19999-12Z\",\n      \"-2002-12+00:01\",\n      \"-0001-12+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPGYearMonth, str)\n    end\n\n    targets = [\n      [\"2002-12\",\n\t\"2002-12Z\"],\n      [\"2002-12+00:00\",\n\t\"2002-12Z\"],\n      [\"2002-12-00:00\",\n\t\"2002-12Z\"],\n      [\"-2002-12\",\n\t\"-2002-12Z\"],\n      [\"-2002-12+00:00\",\n\t\"-2002-12Z\"],\n      [\"-2002-12-00:00\",\n\t\"-2002-12Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPGYearMonth.new(data).to_s)\n    end\n  end\n\n  def test_SOAPGYear\n    o = SOAP::SOAPGYear.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GYearLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002Z\",\n      \"0001Z\",\n      \"9999Z\",\n      \"19999Z\",\n      \"2002+09:00\",\n      \"2002+00:01\",\n      \"2002-00:01\",\n      \"2002-23:59\",\n      \"2002+13:30\",\n      \"-2002Z\",\n      \"-19999Z\",\n      \"-2002+00:01\",\n      \"-0001+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPGYear, str)\n    end\n\n    targets = [\n      [\"2002\",\n\t\"2002Z\"],\n      [\"2002+00:00\",\n\t\"2002Z\"],\n      [\"2002-00:00\",\n\t\"2002Z\"],\n      [\"-2002\",\n\t\"-2002Z\"],\n      [\"-2002+00:00\",\n\t\"-2002Z\"],\n      [\"-2002-00:00\",\n\t\"-2002Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPGYear.new(data).to_s)\n    end\n  end\n\n  def test_SOAPGMonthDay\n    o = SOAP::SOAPGMonthDay.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GMonthDayLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"05-18Z\",\n      \"01-01Z\",\n      \"12-31Z\",\n      \"12-31+09:00\",\n      \"12-31+00:01\",\n      \"12-31-00:01\",\n      \"12-31-23:59\",\n      \"12-31+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPGMonthDay, str)\n    end\n\n    targets = [\n      [\"12-31\",\n\t\"12-31Z\"],\n      [\"12-31+00:00\",\n\t\"12-31Z\"],\n      [\"12-31-00:00\",\n\t\"12-31Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPGMonthDay.new(data).to_s)\n    end\n  end\n\n  def test_SOAPGDay\n    o = SOAP::SOAPGDay.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GDayLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"18Z\",\n      \"01Z\",\n      \"31Z\",\n      \"31+09:00\",\n      \"31+00:01\",\n      \"31-00:01\",\n      \"31-23:59\",\n      \"31+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPGDay, str)\n    end\n\n    targets = [\n      [\"31\",\n\t\"31Z\"],\n      [\"31+00:00\",\n\t\"31Z\"],\n      [\"31-00:00\",\n\t\"31Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPGDay.new(data).to_s)\n    end\n  end\n\n  def test_SOAPGMonth\n    o = SOAP::SOAPGMonth.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GMonthLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"05Z\",\n      \"01Z\",\n      \"12Z\",\n      \"12+09:00\",\n      \"12+00:01\",\n      \"12-00:01\",\n      \"12-23:59\",\n      \"12+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPGMonth, str)\n    end\n\n    targets = [\n      [\"12\",\n\t\"12Z\"],\n      [\"12+00:00\",\n\t\"12Z\"],\n      [\"12-00:00\",\n\t\"12Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPGMonth.new(data).to_s)\n    end\n  end\n\n  def test_SOAPHexBinary\n    o = SOAP::SOAPHexBinary.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::HexBinaryLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"abcdef\",\n      \"\\xe3\\x81\\xaa\\xe3\\x81\\xb2\",\n      \"\\0\",\n      \"\",\n    ]\n    targets.each do |str|\n      assert_equal(str, SOAP::SOAPHexBinary.new(str).string)\n      assert_equal(str.unpack(\"H*\")[0].tr('a-f', 'A-F'),\n\tSOAP::SOAPHexBinary.new(str).data)\n      o = SOAP::SOAPHexBinary.new\n      o.set_encoded(str.unpack(\"H*\")[0].tr('a-f', 'A-F'))\n      assert_equal(str, o.string)\n      o.set_encoded(str.unpack(\"H*\")[0].tr('A-F', 'a-f'))\n      assert_equal(str, o.string)\n    end\n\n    targets = [\n      \"0FG7\",\n      \"0fg7\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError, d.to_s) do\n\to = SOAP::SOAPHexBinary.new\n\to.set_encoded(d)\n\tp o.string\n      end\n    end\n  end\n\n  def test_SOAPBase64Binary\n    o = SOAP::SOAPBase64.new\n    assert_equal(SOAP::EncodingNamespace, o.type.namespace)\n    assert_equal(SOAP::Base64Literal, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"abcdef\",\n      \"\\xe3\\x81\\xaa\\xe3\\x81\\xb2\",\n      \"\\0\",\n      \"\",\n    ]\n    targets.each do |str|\n      assert_equal(str, SOAP::SOAPBase64.new(str).string)\n      assert_equal([str].pack(\"m\").chomp, SOAP::SOAPBase64.new(str).data)\n      o = SOAP::SOAPBase64.new\n      o.set_encoded([str].pack(\"m\").chomp)\n      assert_equal(str, o.string)\n    end\n\n    targets = [\n      \"-\",\n      \"*\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError, d.to_s) do\n\to = SOAP::SOAPBase64.new\n\to.set_encoded(d)\n\tp o.string\n      end\n    end\n  end\n\n  def test_SOAPAnyURI\n    o = SOAP::SOAPAnyURI.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::AnyURILiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    # Too few tests here I know.  Believe uri module. :)\n    targets = [\n      \"foo\",\n      \"http://foo\",\n      \"http://foo/bar/baz\",\n      \"http://foo/bar#baz\",\n      \"http://foo/bar%20%20?a+b\",\n      \"HTTP://FOO/BAR%20%20?A+B\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPAnyURI, str)\n    end\n  end\n\n  def test_SOAPQName\n    o = SOAP::SOAPQName.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::QNameLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    # More strict test is needed but current implementation allows all non-':'\n    # chars like ' ', C0 or C1...\n    targets = [\n      \"foo\",\n      \"foo:bar\",\n      \"a:b\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(SOAP::SOAPQName, str)\n    end\n  end\n\n\n  ###\n  ## Derived types\n  #\n\n  def test_SOAPInteger\n    o = SOAP::SOAPInteger.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::IntegerLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      -9999999999,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789,\n    ]\n    targets.each do |int|\n      assert_equal(int, SOAP::SOAPInteger.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"1000000000\",\n      \"-9999999999\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n      \"-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",\n    ]\n    targets.each do |str|\n      assert_equal(str, SOAP::SOAPInteger.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n      [\n\t\"+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n      ],\n   ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPInteger.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tSOAP::SOAPInteger.new(d)\n      end\n    end\n  end\n\n  def test_SOAPLong\n    o = SOAP::SOAPLong.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::LongLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      123,\n      -123,\n      9223372036854775807,\n      -9223372036854775808,\n    ]\n    targets.each do |lng|\n      assert_equal(lng, SOAP::SOAPLong.new(lng).data)\n    end\n\n    targets = [\n      \"0\",\n      \"123\",\n      \"-123\",\n      \"9223372036854775807\",\n      \"-9223372036854775808\",\n    ]\n    targets.each do |str|\n      assert_equal(str, SOAP::SOAPLong.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPLong.new(data).to_s)\n    end\n\n    targets = [\n      9223372036854775808,\n      -9223372036854775809,\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tSOAP::SOAPLong.new(d)\n      end\n    end\n  end\n\n  def test_SOAPInt\n    o = SOAP::SOAPInt.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::IntLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      123,\n      -123,\n      2147483647,\n      -2147483648,\n    ]\n    targets.each do |lng|\n      assert_equal(lng, SOAP::SOAPInt.new(lng).data)\n    end\n\n    targets = [\n      \"0\",\n      \"123\",\n      \"-123\",\n      \"2147483647\",\n      \"-2147483648\",\n    ]\n    targets.each do |str|\n      assert_equal(str, SOAP::SOAPInt.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, SOAP::SOAPInt.new(data).to_s)\n    end\n\n    targets = [\n      2147483648,\n      -2147483649,\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tSOAP::SOAPInt.new(d)\n      end\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/test_envelopenamespace.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'webrick'\nrequire 'logger'\n\n\nmodule SOAP\n\n\nclass TestEnvelopeNamespace < Test::Unit::TestCase\n  Port = 17171\n  TemporaryNamespace = 'urn:foo'\n\n  def setup\n    @logger = Logger.new(STDERR)\n    @logger.level = Logger::Severity::ERROR\n    @url = \"http://localhost:#{Port}/\"\n    @server = @client = nil\n    @server_thread = nil\n    setup_server\n    setup_client\n  end\n\n  def teardown\n    teardown_client\n    teardown_server\n  end\n\n  def setup_server\n    @server = WEBrick::HTTPServer.new(\n      :BindAddress => \"0.0.0.0\",\n      :Logger => @logger,\n      :Port => Port,\n      :AccessLog => [],\n      :DocumentRoot => File.dirname(File.expand_path(__FILE__))\n    )\n    @server.mount(\n      '/',\n      WEBrick::HTTPServlet::ProcHandler.new(method(:do_server_proc).to_proc)\n    )\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    @client = SOAP::RPC::Driver.new(@url, '')\n    @client.add_method(\"do_server_proc\")\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def do_server_proc(req, res)\n    res['content-type'] = 'text/xml'\n    res.body = <<__EOX__\n<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:env=\"#{TemporaryNamespace}\">\n  <env:Body>\n    <n1:do_server_proc xmlns:n1=\"urn:foo\" env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <return>hello world</return>\n    </n1:do_server_proc>\n  </env:Body>\n</env:Envelope>\n__EOX__\n  end\n\n  def test_normal\n    assert_raise(SOAP::ResponseFormatError) do\n      @client.do_server_proc\n    end\n    @client.options[\"soap.envelope.requestnamespace\"] = TemporaryNamespace\n    @client.options[\"soap.envelope.responsenamespace\"] = TemporaryNamespace\n    assert_equal('hello world', @client.do_server_proc)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/test_httpconfigloader.rb",
    "content": "require 'test/unit'\nrequire 'soap/httpconfigloader'\nrequire 'soap/rpc/driver'\n\nif defined?(HTTPAccess2)\n\nmodule SOAP\n\n\nclass TestHTTPConfigLoader < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  def setup\n    @client = SOAP::RPC::Driver.new(nil, nil)\n  end\n\n  def test_property\n    testpropertyname = File.join(DIR, 'soapclient.properties')\n    File.open(testpropertyname, \"w\") do |f|\n      f <<<<__EOP__\nprotocol.http.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER\n# depth: 1 causes an error (intentional)\nprotocol.http.ssl_config.verify_depth = 1\nprotocol.http.ssl_config.ciphers = ALL\n__EOP__\n    end\n    begin\n      @client.loadproperty(testpropertyname)\n      assert_equal('ALL', @client.options['protocol.http.ssl_config.ciphers'])\n    ensure\n      File.unlink(testpropertyname)\n    end\n  end\nend\n\n\nend\n\nend\n"
  },
  {
    "path": "test/soap/test_mapping.rb",
    "content": "require 'test/unit'\nrequire 'soap/mapping'\n\n\nmodule SOAP\n\n\nclass TestMapping < Test::Unit::TestCase\n  def test_date\n    targets = [\n      [\"2002-12-31\",\n\t\"2002-12-31Z\"],\n      [\"2002-12-31+00:00\",\n\t\"2002-12-31Z\"],\n      [\"2002-12-31-00:00\",\n\t\"2002-12-31Z\"],\n      [\"-2002-12-31\",\n\t\"-2002-12-31Z\"],\n      [\"-2002-12-31+00:00\",\n\t\"-2002-12-31Z\"],\n      [\"-2002-12-31-00:00\",\n\t\"-2002-12-31Z\"],\n    ]\n    targets.each do |str, expectec|\n      d = Date.parse(str)\n      assert_equal(d.class, convert(d).class)\n      assert_equal(d, convert(d))\n    end\n  end\n\n  def test_datetime\n    targets = [\n      [\"2002-12-31T23:59:59.00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"2002-12-31T23:59:59+00:00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"2002-12-31T23:59:59-00:00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59.00\",\n\t\"-2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59+00:00\",\n\t\"-2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59-00:00\",\n\t\"-2002-12-31T23:59:59Z\"],\n    ]\n    targets.each do |str, expectec|\n      d = DateTime.parse(str)\n      assert_equal(d.class, convert(d).class)\n      assert_equal(d, convert(d))\n    end\n  end\n\n  def convert(obj)\n    SOAP::Mapping.soap2obj(SOAP::Mapping.obj2soap(obj))\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/test_no_indent.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/rpc/driver'\n\nif defined?(HTTPAccess2)\n\nmodule SOAP\n\n\nclass TestNoIndent < Test::Unit::TestCase\n  Port = 17171\n\n  class NopServer < SOAP::RPC::StandaloneServer\n    def initialize(*arg)\n      super\n      add_rpc_method(self, 'nop')\n    end\n\n    def nop\n      SOAP::RPC::SOAPVoid.new\n    end\n  end\n\n  def setup\n    @server = NopServer.new(self.class.name, nil, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      @server.start\n    }\n    @endpoint = \"http://localhost:#{Port}/\"\n    @client = SOAP::RPC::Driver.new(@endpoint)\n    @client.add_rpc_method('nop')\n  end\n\n  def teardown\n    @server.shutdown\n    @t.kill\n    @t.join\n    @client.reset_stream\n  end\n\n  INDENT_XML =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <nop env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n    </nop>\n  </env:Body>\n</env:Envelope>]\n\n  NO_INDENT_XML =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\nxmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\nxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<env:Body>\n<nop env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n</nop>\n</env:Body>\n</env:Envelope>]\n\n  def test_indent\n    @client.wiredump_dev = str = ''\n    @client.options[\"soap.envelope.no_indent\"] = false\n    @client.nop\n    assert_equal(INDENT_XML, parse_requestxml(str))\n  end\n\n  def test_no_indent\n    @client.wiredump_dev = str = ''\n    @client.options[\"soap.envelope.no_indent\"] = true\n    @client.nop\n    assert_equal(NO_INDENT_XML, parse_requestxml(str))\n  end\n\n  def parse_requestxml(str)\n    str.split(/\\r?\\n\\r?\\n/)[3]\n  end\nend\n\n\nend\n\nend\n"
  },
  {
    "path": "test/soap/test_property.rb",
    "content": "require 'test/unit'\nrequire 'soap/property'\n\n\nmodule SOAP\n\n\nclass TestProperty < Test::Unit::TestCase\n  FrozenError = (RUBY_VERSION >= \"1.9.0\") ? RuntimeError : TypeError\n\n  def setup\n    @prop = ::SOAP::Property.new\n  end\n\n  def teardown\n    # Nothing to do.\n  end\n\n  def test_s_load\n    propstr = <<__EOP__\n\n# comment1\n\n# comment2\\r\n# comment2\n\n\\r\na.b.0 = 1\na.b.1 = 2\na.b.2 = 3\nclient.protocol.http.proxy=http://myproxy:8080   \\r\nclient.protocol.http.no_proxy:  intranet.example.com,local.example.com\\r\nclient.protocol.http.protocol_version = 1.0\nfoo\\\\:bar\\\\=baz = qux\nfoo\\\\\\\\.bar.baz=\\tq\\\\\\\\ux\\ttab\n  a\\\\ b                            =                          1   \n[ppp.qqq.rrr]\nsss = 3\nttt.uuu = 4\n\n[ sss.ttt.uuu  ]\nvvv.www = 5\n[  ]\nxxx.yyy.zzz = 6\n__EOP__\n    prop = Property.load(propstr)\n    assert_equal([\"1\", \"2\", \"3\"], prop[\"a.b\"].values.sort)\n    assert_equal(\"intranet.example.com,local.example.com\",\n      prop[\"client.protocol.http.no_proxy\"])\n    assert_equal(\"http://myproxy:8080\", prop[\"client.protocol.http.proxy\"])\n    assert_equal(\"1.0\", prop[\"client.protocol.http.protocol_version\"])\n    assert_equal(\"q\\\\ux\\ttab\", prop['foo\\.bar.baz'])\n    assert_equal(\"1\", prop['a b'])\n    assert_equal(\"3\", prop['ppp.qqq.rrr.sss'])\n    assert_equal(\"4\", prop['ppp.qqq.rrr.ttt.uuu'])\n    assert_equal(\"5\", prop['sss.ttt.uuu.vvv.www'])\n    assert_equal(\"6\", prop['xxx.yyy.zzz'])\n  end\n\n  def test_load\n    prop = Property.new\n    hooked = false\n    prop.add_hook(\"foo.bar.baz\") do |name, value|\n      assert_equal([\"foo\", \"bar\", \"baz\"], name)\n      assert_equal(\"123\", value)\n      hooked = true\n    end\n    prop.lock\n    prop[\"foo.bar\"].lock\n    prop.load(\"foo.bar.baz = 123\")\n    assert(hooked)\n    assert_raises(FrozenError) do\n      prop.load(\"foo.bar.qux = 123\")\n    end\n    prop.load(\"foo.baz = 456\")\n    assert_equal(\"456\", prop[\"foo.baz\"])\n  end\n\n  def test_initialize\n    prop = ::SOAP::Property.new\n    # store is empty\n    assert_nil(prop[\"a\"])\n    # does hook work?\n    assert_equal(1, prop[\"a\"] = 1)\n  end\n\n  def test_aref\n    # name_to_a\n    assert_nil(@prop[:foo])\n    assert_nil(@prop[\"foo\"])\n    assert_nil(@prop[[:foo]])\n    assert_nil(@prop[[\"foo\"]])\n    assert_raises(ArgumentError) do\n      @prop[1]\n    end\n    @prop[:foo] = :foo\n    assert_equal(:foo, @prop[:foo])\n    assert_equal(:foo, @prop[\"foo\"])\n    assert_equal(:foo, @prop[[:foo]])\n    assert_equal(:foo, @prop[[\"foo\"]])\n  end\n\n  def test_referent\n    # referent(1)\n    assert_nil(@prop[\"foo.foo\"])\n    assert_nil(@prop[[\"foo\", \"foo\"]])\n    assert_nil(@prop[[\"foo\", :foo]])\n    @prop[\"foo.foo\"] = :foo\n    assert_equal(:foo, @prop[\"foo.foo\"])\n    assert_equal(:foo, @prop[[\"foo\", \"foo\"]])\n    assert_equal(:foo, @prop[[:foo, \"foo\"]])\n    # referent(2)\n    @prop[\"bar.bar.bar\"] = :bar\n    assert_equal(:bar, @prop[\"bar.bar.bar\"])\n    assert_equal(:bar, @prop[[\"bar\", \"bar\", \"bar\"]])\n    assert_equal(:bar, @prop[[:bar, \"bar\", :bar]])\n  end\n\n  def test_to_key_and_deref\n    @prop[\"foo.foo\"] = :foo\n    assert_equal(:foo, @prop[\"fOo.FoO\"])\n    assert_equal(:foo, @prop[[:fOO, :FOO]])\n    assert_equal(:foo, @prop[[\"FoO\", :Foo]])\n    # deref_key negative test\n    assert_raises(ArgumentError) do\n      @prop[\"baz\"] = 1\n      @prop[\"baz.qux\"] = 2\n    end\n  end\n\n  def test_hook_name\n    tag = Object.new\n    tested = false\n    @prop.add_hook(\"foo.bar\") do |key, value|\n      assert_raise(FrozenError) do\n\tkey << \"baz\"\n      end\n      tested = true\n    end\n    @prop[\"foo.bar\"] = tag\n    assert(tested)\n  end\n\n  def test_value_hook\n    tag = Object.new\n    tested = false\n    @prop.add_hook(\"FOO.BAR.BAZ\") do |key, value|\n      assert_equal([\"Foo\", \"baR\", \"baZ\"], key)\n      assert_equal(tag, value)\n      tested = true\n    end\n    @prop[\"Foo.baR.baZ\"] = tag\n    assert_equal(tag, @prop[\"foo.bar.baz\"])\n    assert(tested)\n    @prop[\"foo.bar\"] = 1\t# unhook the above block\n    assert_equal(1, @prop[\"foo.bar\"])\n  end\n\n  def test_key_hook_no_cascade\n    tag = Object.new\n    tested = 0\n    @prop.add_hook do |key, value|\n      assert(false)\n    end\n    @prop.add_hook(false) do |key, value|\n      assert(false)\n    end\n    @prop.add_hook(\"foo\") do |key, value|\n      assert(false)\n    end\n    @prop.add_hook(\"foo.bar\", false) do |key, value|\n      assert(false)\n    end\n    @prop.add_hook(\"foo.bar.baz\") do |key, value|\n      assert(false)\n    end\n    @prop.add_hook(\"foo.bar.baz.qux\", false) do |key, value|\n      assert_equal([\"foo\", \"bar\", \"baz\", \"qux\"], key)\n      assert_equal(tag, value)\n      tested += 1\n    end\n    @prop[\"foo.bar.baz.qux\"] = tag\n    assert_equal(tag, @prop[\"foo.bar.baz.qux\"])\n    assert_equal(1, tested)\n  end\n\n  def test_key_hook_cascade\n    tag = Object.new\n    tested = 0\n    @prop.add_hook(true) do |key, value|\n      assert_equal([\"foo\", \"bar\", \"baz\", \"qux\"], key)\n      assert_equal(tag, value)\n      tested += 1\n    end\n    @prop.add_hook(\"foo\", true) do |key, value|\n      assert_equal([\"foo\", \"bar\", \"baz\", \"qux\"], key)\n      assert_equal(tag, value)\n      tested += 1\n    end\n    @prop.add_hook(\"foo.bar\", true) do |key, value|\n      assert_equal([\"foo\", \"bar\", \"baz\", \"qux\"], key)\n      assert_equal(tag, value)\n      tested += 1\n    end\n    @prop.add_hook(\"foo.bar.baz\", true) do |key, value|\n      assert_equal([\"foo\", \"bar\", \"baz\", \"qux\"], key)\n      assert_equal(tag, value)\n      tested += 1\n    end\n    @prop.add_hook(\"foo.bar.baz.qux\", true) do |key, value|\n      assert_equal([\"foo\", \"bar\", \"baz\", \"qux\"], key)\n      assert_equal(tag, value)\n      tested += 1\n    end\n    @prop[\"foo.bar.baz.qux\"] = tag\n    assert_equal(tag, @prop[\"foo.bar.baz.qux\"])\n    assert_equal(5, tested)\n  end\n\n  def test_keys\n    assert(@prop.keys.empty?)\n    @prop[\"foo\"] = 1\n    @prop[\"bar\"]\n    @prop[\"BAz\"] = 2\n    assert_equal(2, @prop.keys.size)\n    assert(@prop.keys.member?(\"foo\"))\n    assert(@prop.keys.member?(\"baz\"))\n    #\n    assert_nil(@prop[\"a\"])\n    @prop[\"a.a\"] = 1\n    assert_instance_of(::SOAP::Property, @prop[\"a\"])\n    @prop[\"a.b\"] = 1\n    @prop[\"a.c\"] = 1\n    assert_equal(3, @prop[\"a\"].keys.size)\n    assert(@prop[\"a\"].keys.member?(\"a\"))\n    assert(@prop[\"a\"].keys.member?(\"b\"))\n    assert(@prop[\"a\"].keys.member?(\"c\"))\n  end\n\n  def test_lshift\n    assert(@prop.empty?)\n    @prop << 1\n    assert_equal([1], @prop.values)\n    assert_equal(1, @prop[\"0\"])\n    @prop << 1\n    assert_equal([1, 1], @prop.values)\n    assert_equal(1, @prop[\"1\"])\n    @prop << 1\n    assert_equal([1, 1, 1], @prop.values)\n    assert_equal(1, @prop[\"2\"])\n    #\n    @prop[\"abc.def\"] = o = SOAP::Property.new\n    tested = 0\n    o.add_hook do |k, v|\n      tested += 1\n    end\n    @prop[\"abc.def\"] << 1\n    @prop[\"abc.def\"] << 2\n    @prop[\"abc.def\"] << 3\n    @prop[\"abc.def\"] << 4\n    assert_equal(4, tested)\n  end\n\n  def test_lock_each\n    @prop[\"a.b.c.d.e\"] = 1\n    @prop[\"a.b.d\"] = branch = ::SOAP::Property.new\n    @prop[\"a.b.d.e.f\"] = 2\n    @prop.lock\n    assert(@prop.locked?)\n    assert_instance_of(::SOAP::Property, @prop[\"a\"])\n    assert_raises(FrozenError) do\n      @prop[\"b\"]\n    end\n    #\n    @prop[\"a\"].lock\n    assert_raises(FrozenError) do\n      @prop[\"a\"]\n    end\n    assert_instance_of(::SOAP::Property, @prop[\"a.b\"])\n    #\n    @prop[\"a.b\"].lock\n    assert_raises(FrozenError) do\n      @prop[\"a.b\"]\n    end\n    assert_raises(FrozenError) do\n      @prop[\"a\"]\n    end\n    #\n    @prop[\"a.b.c.d\"].lock\n    assert_instance_of(::SOAP::Property, @prop[\"a.b.c\"])\n    assert_raises(FrozenError) do\n      @prop[\"a.b.c.d\"]\n    end\n    assert_instance_of(::SOAP::Property, @prop[\"a.b.d\"])\n    #\n    branch[\"e\"].lock\n    assert_instance_of(::SOAP::Property, @prop[\"a.b.d\"])\n    assert_raises(FrozenError) do\n      @prop[\"a.b.d.e\"]\n    end\n    assert_raises(FrozenError) do\n      branch[\"e\"]\n    end\n  end\n\n  def test_lock_cascade\n    @prop[\"a.a\"] = nil\n    @prop[\"a.b.c\"] = 1\n    @prop[\"b\"] = false\n    @prop.lock(true)\n    assert(@prop.locked?)\n    assert_equal(nil, @prop[\"a.a\"])\n    assert_equal(1, @prop[\"a.b.c\"])\n    assert_equal(false, @prop[\"b\"])\n    assert_raises(FrozenError) do\n      @prop[\"c\"]\n    end\n    assert_raises(FrozenError) do\n      @prop[\"c\"] = 2\n    end\n    assert_raises(FrozenError) do\n      @prop[\"a.b.R\"]\n    end\n    assert_raises(FrozenError) do\n      @prop.add_hook do\n\tassert(false)\n      end\n    end\n    assert_raises(FrozenError) do\n      @prop.add_hook(\"c\") do\n\tassert(false)\n      end\n    end\n    assert_raises(FrozenError) do\n      @prop.add_hook(\"a.c\") do\n\tassert(false)\n      end\n    end\n    assert_nil(@prop[\"a.a\"])\n    @prop[\"a.a\"] = 2\n    assert_equal(2, @prop[\"a.a\"])\n    #\n    @prop.unlock(true)\n    assert_nil(@prop[\"c\"])\n    @prop[\"c\"] = 2\n    assert_equal(2, @prop[\"c\"])\n    @prop[\"a.d.a.a\"] = :foo\n    assert_equal(:foo, @prop[\"a.d.a.a\"])\n    tested = false\n    @prop.add_hook(\"a.c\") do |name, value|\n      assert(true)\n      tested = true\n    end\n    @prop[\"a.c\"] = 3\n    assert(tested)\n  end\n\n  def test_hook_then_lock\n    tested = false\n    @prop.add_hook(\"a.b.c\") do |name, value|\n      assert_equal([\"a\", \"b\", \"c\"], name)\n      tested = true\n    end\n    @prop[\"a.b\"].lock\n    assert(!tested)\n    @prop[\"a.b.c\"] = 5\n    assert(tested)\n    assert_equal(5, @prop[\"a.b.c\"])\n    assert_raises(FrozenError) do\n      @prop[\"a.b.d\"] = 5\n    end\n  end\n\n  def test_lock_unlock_return\n    assert_equal(@prop, @prop.lock)\n    assert_equal(@prop, @prop.unlock)\n  end\n\n  def test_lock_split\n    @prop[\"a.b.c\"] = 1\n    assert_instance_of(::SOAP::Property, @prop[\"a.b\"])\n    @prop[\"a.b.d\"] = branch = ::SOAP::Property.new\n    @prop[\"a.b.d.e\"] = 2\n    assert_equal(branch, @prop[\"a.b.d\"])\n    assert_equal(branch, @prop[:a][:b][:d])\n    @prop.lock(true)\n    # split error 1\n    assert_raises(FrozenError) do\n      @prop[\"a.b\"]\n    end\n    # split error 2\n    assert_raises(FrozenError) do\n      @prop[\"a\"]\n    end\n    @prop[\"a.b.c\"] = 2\n    assert_equal(2, @prop[\"a.b.c\"])\n    # replace error\n    assert_raises(FrozenError) do\n      @prop[\"a.b.c\"] = ::SOAP::Property.new\n    end\n    # override error\n    assert_raises(FrozenError) do\n      @prop[\"a.b\"] = 1\n    end\n    #\n    assert_raises(FrozenError) do\n      @prop[\"a.b.d\"] << 1\n    end\n    assert_raises(FrozenError) do\n      branch << 1\n    end\n    branch.unlock(true)\n    branch << 1\n    branch << 2\n    branch << 3\n    assert_equal(2, @prop[\"a.b.d.e\"])\n    assert_equal(1, @prop[\"a.b.d.1\"])\n    assert_equal(2, @prop[\"a.b.d.2\"])\n    assert_equal(3, @prop[\"a.b.d.3\"])\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/test_soapelement.rb",
    "content": "require 'test/unit'\nrequire 'soap/baseData'\nrequire 'soap/mapping'\n\n\nmodule SOAP\n\n\nclass TestSOAPElement < Test::Unit::TestCase\n  include SOAP\n\n  def setup\n    # Nothing to do.\n  end\n\n  def teardown\n    # Nothing to do.\n  end\n\n  def d(elename = nil, text = nil)\n    elename ||= n(nil, nil)\n    if text\n      SOAPElement.new(elename, text)\n    else\n      SOAPElement.new(elename)\t# do not merge.\n    end\n  end\n\n  def n(namespace, name)\n    XSD::QName.new(namespace, name)\n  end\n\n  def test_initialize\n    elename = n(nil, nil)\n    obj = d(elename)\n    assert_equal(elename, obj.elename)\n    assert_equal(LiteralNamespace, obj.encodingstyle)\n    assert_equal({}, obj.extraattr)\n    assert_equal([], obj.precedents)\n    assert_equal(nil, obj.qualified)\n    assert_equal(nil, obj.text)\n    assert(obj.members.empty?)\n\n    obj = d(\"foo\", \"text\")\n    assert_equal(n(nil, \"foo\"), obj.elename)\n    assert_equal(\"text\", obj.text)\n  end\n\n  def test_add\n    obj = d()\n    child = d(\"abc\")\n    obj.add(child)\n    assert(obj.key?(\"abc\"))\n    assert_same(child, obj[\"abc\"])\n    assert_same(child, obj.abc)\n    def obj.foo; 1; end\n    child = d(\"foo\")\n    obj.add(child)\n    assert_equal(1, obj.foo)\n    assert_equal(child, obj.var_foo)\n    child = d(\"_?a?b_\")\n    obj.add(child)\n    assert_equal(child, obj.__send__('_?a?b_'))\n  end\n\n  def test_member\n    obj = d()\n    c1 = d(\"c1\")\n    obj.add(c1)\n    c2 = d(\"c2\")\n    obj.add(c2)\n    assert(obj.key?(\"c1\"))\n    assert(obj.key?(\"c2\"))\n    assert_equal(c1, obj[\"c1\"])\n    assert_equal(c2, obj[\"c2\"])\n    c22 = d(\"c22\")\n    obj[\"c2\"] = c22\n    assert(obj.key?(\"c2\"))\n    assert_equal(c22, obj[\"c2\"])\n    assert_equal([\"c1\", \"c2\"], obj.members.sort)\n    #\n    k_expect = [\"c1\", \"c2\"]\n    v_expect = [c1, c22]\n    obj.each do |k, v|\n      assert(k_expect.include?(k))\n      assert(v_expect.include?(v))\n      k_expect.delete(k)\n      v_expect.delete(v)\n    end\n    assert(k_expect.empty?)\n    assert(v_expect.empty?)\n  end\n\n  def test_to_obj\n    obj = d(\"root\")\n    ct1 = d(\"ct1\", \"t1\")\n    obj.add(ct1)\n    c2 = d(\"c2\")\n    ct2 = d(\"ct2\", \"t2\")\n    c2.add(ct2)\n    obj.add(c2)\n    assert_equal({ \"ct1\" => \"t1\", \"c2\" => { \"ct2\" => \"t2\" }}, obj.to_obj) \n    #\n    assert_equal(nil, d().to_obj)\n    assert_equal(\"abc\", d(nil, \"abc\").to_obj)\n    assert_equal(nil, d(\"abc\", nil).to_obj)\n  end\n\n  def test_from_obj\n    source = { \"ct1\" => \"t1\", \"c2\" => { \"ct2\" => \"t2\" }}\n    assert_equal(source, SOAPElement.from_obj(source).to_obj)\n    source = { \"1\" => nil }\n    assert_equal(source, SOAPElement.from_obj(source).to_obj)\n    source = {}\n    assert_equal(nil, SOAPElement.from_obj(source).to_obj)\t# not {}\n    source = nil\n    assert_equal(nil, SOAPElement.from_obj(source).to_obj)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/test_streamhandler.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/driver'\nrequire 'webrick'\nrequire 'webrick/httpproxy'\nrequire 'logger'\n\n\nmodule SOAP\n\n\nclass TestStreamHandler < Test::Unit::TestCase\n  Port = 17171\n  ProxyPort = 17172\n\n  def setup\n    @logger = Logger.new(STDERR)\n    @logger.level = Logger::Severity::ERROR\n    @url = \"http://localhost:#{Port}/\"\n    @proxyurl = \"http://localhost:#{ProxyPort}/\"\n    @server = @proxyserver = @client = nil\n    @server_thread = @proxyserver_thread = nil\n    setup_server\n    setup_client\n  end\n\n  def teardown\n    teardown_client\n    teardown_proxyserver if @proxyserver\n    teardown_server\n  end\n\n  def setup_server\n    @server = WEBrick::HTTPServer.new(\n      :BindAddress => \"0.0.0.0\",\n      :Logger => @logger,\n      :Port => Port,\n      :AccessLog => [],\n      :DocumentRoot => File.dirname(File.expand_path(__FILE__))\n    )\n    @server.mount(\n      '/',\n      WEBrick::HTTPServlet::ProcHandler.new(method(:do_server_proc).to_proc)\n    )\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_proxyserver\n    @proxyserver = WEBrick::HTTPProxyServer.new(\n      :BindAddress => \"0.0.0.0\",\n      :Logger => @logger,\n      :Port => ProxyPort,\n      :AccessLog => []\n    )\n    @proxyserver_thread = start_server_thread(@proxyserver)\n  end\n\n  def setup_client\n    @client = SOAP::RPC::Driver.new(@url, '')\n    @client.add_method(\"do_server_proc\")\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_proxyserver\n    @proxyserver.shutdown\n    @proxyserver_thread.kill\n    @proxyserver_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def do_server_proc(req, res)\n    res['content-type'] = 'text/xml'\n    res.body = <<__EOX__\n<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:do_server_proc xmlns:n1=\"urn:foo\" env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <return xsi:nil=\"true\"/>\n    </n1:do_server_proc>\n  </env:Body>\n</env:Envelope>\n__EOX__\n  end\n\n  def parse_req_header(str)\n    if ::SOAP::HTTPStreamHandler::Client.to_s == 'SOAP::NetHttpClient'\n      str = eval(str.split(/\\r?\\n/)[4][3..-1])\n    end\n    parse_req_header_http_access2(str)\n  end\n\n  def parse_req_header_http_access2(str)\n    headerp = false\n    headers = {}\n    req = nil\n    str.split(/(?:\\r?\\n)/).each do |line|\n      if headerp and /^$/ =~line\n\theaderp = false\n\tbreak\n      end\n      if headerp\n\tk, v = line.scan(/^([^:]+):\\s*(.*)$/)[0]\n\theaders[k.downcase] = v\n      end\n      if /^POST/ =~ line\n\treq = line\n\theaderp = true\n      end\n    end\n    return req, headers\n  end\n\n  def test_normal\n    str = \"\"\n    @client.wiredump_dev = str\n    assert_nil(@client.do_server_proc)\n    r, h = parse_req_header(str)\n    assert_match(%r\"POST / HTTP/1.\", r)\n    assert(/^text\\/xml;/ =~ h[\"content-type\"])\n  end\n\n  def test_uri\n    # initialize client with URI object\n    @client = SOAP::RPC::Driver.new(URI.parse(@url), '')\n    @client.add_method(\"do_server_proc\")\n    # same as test_normal\n    str = \"\"\n    @client.wiredump_dev = str\n    assert_nil(@client.do_server_proc)\n    r, h = parse_req_header(str)\n    assert_match(%r\"POST / HTTP/1.\", r)\n    assert(/^text\\/xml;/ =~ h[\"content-type\"])\n  end\n\n  def test_basic_auth\n    unless Object.const_defined?('HTTPAccess2')\n      # soap4r + net/http + basic_auth is not supported.\n      # use http-access2 instead.\n      assert(true)\n      return\n    end\n    str = \"\"\n    @client.wiredump_dev = str\n    @client.options[\"protocol.http.basic_auth\"] << [@url, \"foo\", \"bar\"]\n    assert_nil(@client.do_server_proc)\n    r, h = parse_req_header(str)\n    assert_equal(\"Basic Zm9vOmJhcg==\", h[\"authorization\"])\n  end\n\n  def test_proxy\n    if Object.const_defined?('HTTPAccess2')\n      backup = HTTPAccess2::Client::NO_PROXY_HOSTS.dup\n      HTTPAccess2::Client::NO_PROXY_HOSTS.clear\n    else\n      backup = SOAP::NetHttpClient::NO_PROXY_HOSTS.dup\n      SOAP::NetHttpClient::NO_PROXY_HOSTS.clear\n    end\n    setup_proxyserver\n    str = \"\"\n    @client.wiredump_dev = str\n    @client.options[\"protocol.http.proxy\"] = @proxyurl\n    assert_nil(@client.do_server_proc)\n    r, h = parse_req_header(str)\n    assert_match(%r\"POST http://localhost:17171/ HTTP/1.\", r)\n    # illegal proxy uri\n    assert_raise(ArgumentError) do\n      @client.options[\"protocol.http.proxy\"] = 'ftp://foo:8080'\n    end\n  ensure\n    if Object.const_defined?('HTTPAccess2')\n      HTTPAccess2::Client::NO_PROXY_HOSTS.replace(backup)\n    else\n      SOAP::NetHttpClient::NO_PROXY_HOSTS.replace(backup)\n    end\n  end\n\n  def test_charset\n    str = \"\"\n    @client.wiredump_dev = str\n    @client.options[\"protocol.http.charset\"] = \"iso-8859-8\"\n    assert_nil(@client.do_server_proc)\n    r, h = parse_req_header(str)\n    assert_equal(\"text/xml; charset=iso-8859-8\", h[\"content-type\"])\n    #\n    str.replace(\"\")\n    @client.options[\"protocol.http.charset\"] = \"iso-8859-3\"\n    assert_nil(@client.do_server_proc)\n    r, h = parse_req_header(str)\n    assert_equal(\"text/xml; charset=iso-8859-3\", h[\"content-type\"])\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/test_styleuse.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/httpserver'\nrequire 'soap/rpc/driver'\n\n\nmodule SOAP\n\n\nclass TestStyleUse < Test::Unit::TestCase\n  # rpc driver: obj in(Hash allowed for literal), obj out\n  # \n  #   style: not visible from user\n  #     rpc: wrapped element\n  #     document: unwrappted element\n  #\n  #   use:\n  #     encoding: a graph (SOAP Data Model)\n  #     literal: not a graph (SOAPElement)\n  #\n  # rpc stub: obj in, obj out(Hash is allowed for literal)\n  #\n  #   style: not visible from user\n  #     rpc: wrapped element\n  #     document: unwrappted element\n  #\n  #   use:\n  #     encoding: a graph (SOAP Data Model)\n  #     literal: not a graph (SOAPElement)\n  #\n  # document driver: SOAPElement in, SOAPElement out? [not implemented]\n  #\n  #   style: ditto\n  #   use: ditto\n  #\n  #\n  # document stub: SOAPElement in, SOAPElement out? [not implemented]\n  #\n  #   style: ditto\n  #   use: ditto\n  #\n  class GenericServant\n    # method name style: requeststyle_requestuse_responsestyle_responseuse\n\n    # 2 params -> array\n    def rpc_enc_rpc_enc(obj1, obj2)\n      [obj1, [obj1, obj2]]\n    end\n\n    # 2 objs -> array\n    def rpc_lit_rpc_enc(obj1, obj2)\n      [obj2, obj1]\n    end\n\n    # 2 params -> 2 params\n    def rpc_enc_rpc_lit(obj1, obj2)\n      klass = [obj1.class.name, obj2.class.name]\n      [obj2, obj1]\n    end\n\n    # 2 objs -> 2 objs\n    def rpc_lit_rpc_lit(obj1, obj2)\n      [obj1, obj2]\n    end\n\n    # 2 params -> array\n    def doc_enc_doc_enc(obj1, obj2)\n      [obj1, [obj1, obj2]]\n    end\n\n    # 2 objs -> array\n    def doc_lit_doc_enc(obj1, obj2)\n      [obj2, obj1]\n    end\n\n    # 2 params -> 2 hashes\n    def doc_enc_doc_lit(obj1, obj2)\n      klass = [obj1.class.name, obj2.class.name]\n      return {'obj1' => {'klass' => klass}, 'misc' => 'hash does not have an order'},\n        {'obj2' => {'klass' => klass}}\n    end\n\n    # 2 objs -> 2 objs\n    def doc_lit_doc_lit(obj1, obj2)\n      return obj1, obj2\n    end\n  end\n\n  Namespace = \"urn:styleuse\"\n\n  module Op\n    def self.opt(request_style, request_use, response_style, response_use)\n      {\n        :request_style => request_style,\n        :request_use => request_use,\n        :response_style => response_style,\n        :response_use => response_use\n      }\n    end\n\n    Op_rpc_enc_rpc_enc = [\n      XSD::QName.new(Namespace, 'rpc_enc_rpc_enc'),\n      nil,\n      'rpc_enc_rpc_enc', [\n        ['in', 'obj1', nil],\n        ['in', 'obj2', nil],\n        ['retval', 'return', nil]],\n      opt(:rpc, :encoded, :rpc, :encoded)\n    ]\n\n    Op_rpc_lit_rpc_enc = [\n      XSD::QName.new(Namespace, 'rpc_lit_rpc_enc'),\n      nil,\n      'rpc_lit_rpc_enc', [\n        ['in', 'obj1', nil],\n        ['in', 'obj2', nil],\n        ['retval', 'return', nil]],\n      opt(:rpc, :literal, :rpc, :encoded)\n    ]\n\n    Op_rpc_enc_rpc_lit = [\n      XSD::QName.new(Namespace, 'rpc_enc_rpc_lit'),\n      nil,\n      'rpc_enc_rpc_lit', [\n        ['in', 'obj1', nil],\n        ['in', 'obj2', nil],\n        ['retval', 'ret1', nil],\n        ['out', 'ret2', nil]],\n      opt(:rpc, :encoded, :rpc, :literal)\n    ]\n\n    Op_rpc_lit_rpc_lit = [\n      XSD::QName.new(Namespace, 'rpc_lit_rpc_lit'),\n      nil,\n      'rpc_lit_rpc_lit', [\n        ['in', 'obj1', nil],\n        ['in', 'obj2', nil],\n        ['retval', 'ret1', nil],\n        ['out', 'ret2', nil]],\n      opt(:rpc, :literal, :rpc, :literal)\n    ]\n\n    Op_doc_enc_doc_enc = [\n      Namespace + 'doc_enc_doc_enc',\n      'doc_enc_doc_enc', [\n        ['in', 'obj1', [nil, Namespace, 'obj1']],\n        ['in', 'obj2', [nil, Namespace, 'obj2']],\n        ['out', 'ret1', [nil, Namespace, 'ret1']],\n        ['out', 'ret2', [nil, Namespace, 'ret2']]],\n      opt(:document, :encoded, :document, :encoded)\n    ]\n\n    Op_doc_lit_doc_enc = [\n      Namespace + 'doc_lit_doc_enc',\n      'doc_lit_doc_enc', [\n        ['in', 'obj1', [nil, Namespace, 'obj1']],\n        ['in', 'obj2', [nil, Namespace, 'obj2']],\n        ['out', 'ret1', [nil, Namespace, 'ret1']],\n        ['out', 'ret2', [nil, Namespace, 'ret2']]],\n      opt(:document, :literal, :document, :encoded)\n    ]\n\n    Op_doc_enc_doc_lit = [\n      Namespace + 'doc_enc_doc_lit',\n      'doc_enc_doc_lit', [\n        ['in', 'obj1', [nil, Namespace, 'obj1']],\n        ['in', 'obj2', [nil, Namespace, 'obj2']],\n        ['out', 'ret1', [nil, Namespace, 'ret1']],\n        ['out', 'ret2', [nil, Namespace, 'ret2']]],\n      opt(:document, :encoded, :document, :literal)\n    ]\n\n    Op_doc_lit_doc_lit = [\n      Namespace + 'doc_lit_doc_lit',\n      'doc_lit_doc_lit', [\n        ['in', 'obj1', [nil, Namespace, 'obj1']],\n        ['in', 'obj2', [nil, Namespace, 'obj2']],\n        ['out', 'ret1', [nil, Namespace, 'ret1']],\n        ['out', 'ret2', [nil, Namespace, 'ret2']]],\n      opt(:document, :literal, :document, :literal)\n    ]\n  end\n\n  include Op\n\n  class Server < ::SOAP::RPC::HTTPServer\n    include Op\n\n    def on_init\n      @servant = GenericServant.new\n      add_rpc_operation(@servant, *Op_rpc_enc_rpc_enc)\n      add_rpc_operation(@servant, *Op_rpc_lit_rpc_enc)\n      add_rpc_operation(@servant, *Op_rpc_enc_rpc_lit)\n      add_rpc_operation(@servant, *Op_rpc_lit_rpc_lit)\n      add_document_operation(@servant, *Op_doc_enc_doc_enc)\n      add_document_operation(@servant, *Op_doc_lit_doc_enc)\n      add_document_operation(@servant, *Op_doc_enc_doc_lit)\n      add_document_operation(@servant, *Op_doc_lit_doc_lit)\n    end\n  end\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new(\n      :BindAddress => \"0.0.0.0\",\n      :Port => Port,\n      :AccessLog => [],\n      :SOAPDefaultNamespace => Namespace\n    )\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    @client = ::SOAP::RPC::Driver.new(\"http://localhost:#{Port}/\", Namespace)\n    @client.wiredump_dev = STDERR if $DEBUG\n    @client.add_rpc_operation(*Op_rpc_enc_rpc_enc)\n    @client.add_rpc_operation(*Op_rpc_lit_rpc_enc)\n    @client.add_rpc_operation(*Op_rpc_enc_rpc_lit)\n    @client.add_rpc_operation(*Op_rpc_lit_rpc_lit)\n    @client.add_document_operation(*Op_doc_enc_doc_enc)\n    @client.add_document_operation(*Op_doc_lit_doc_enc)\n    @client.add_document_operation(*Op_doc_enc_doc_lit)\n    @client.add_document_operation(*Op_doc_lit_doc_lit)\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_rpc_enc_rpc_enc\n    o = \"hello\"\n    obj1 = o\n    obj2 = [1]\n    ret = @client.rpc_enc_rpc_enc(obj1, obj2)\n    # server returns [obj1, [obj1, obj2]]\n    assert_equal([obj1, [obj1, obj2]], ret)\n    assert_same(ret[0], ret[1][0])\n  end\n\n  S1 = ::Struct.new(:a)\n  S2 = ::Struct.new(:c)\n  def test_rpc_lit_rpc_enc\n    ret1, ret2 = @client.rpc_lit_rpc_enc(S1.new('b'), S2.new('d'))\n    assert_equal('d', ret1.c)\n    assert_equal('b', ret2.a)\n    # Hash is allowed for literal\n    ret1, ret2 = @client.rpc_lit_rpc_enc({'a' => 'b'}, {'c' => 'd'})\n    assert_equal('d', ret1.c)\n    assert_equal('b', ret2.a)\n    # simple value\n    assert_equal(\n      ['1', 'a'],\n      @client.rpc_lit_rpc_enc('a', 1)\n    )\n  end\n\n  def test_rpc_enc_rpc_lit\n    assert_equal(\n      ['1', 'a'],\n      @client.rpc_enc_rpc_lit('a', '1')\n    )\n  end\n\n  def test_rpc_lit_rpc_lit\n    ret1, ret2 = @client.rpc_lit_rpc_lit({'a' => 'b'}, {'c' => 'd'})\n    assert_equal('b', ret1[\"a\"])\n    assert_equal('d', ret2[\"c\"])\n  end\n\n  def test_doc_enc_doc_enc\n    o = \"hello\"\n    obj1 = o\n    obj2 = [1]\n    ret = @client.rpc_enc_rpc_enc(obj1, obj2)\n    # server returns [obj1, [obj1, obj2]]\n    assert_equal([obj1, [obj1, obj2]], ret)\n    assert_same(ret[0], ret[1][0])\n  end\n\n  def test_doc_lit_doc_enc\n    ret1, ret2 = @client.doc_lit_doc_enc({'a' => 'b'}, {'c' => 'd'})\n    assert_equal('d', ret1.c)\n    assert_equal('b', ret2.a)\n    assert_equal(\n      ['a', '1'],\n      @client.doc_lit_doc_enc(1, 'a')\n    )\n  end\n\n  def test_doc_enc_doc_lit\n    ret1, ret2 = @client.doc_enc_doc_lit('a', 1)\n    # literal Array\n    assert_equal(['String', 'Fixnum'], ret1['obj1']['klass'])\n    # same value\n    assert_equal(ret1['obj1']['klass'], ret2['obj2']['klass'])\n    # not the same object (not encoded)\n    assert_not_same(ret1['obj1']['klass'], ret2['obj2']['klass'])\n  end\n\n  def test_doc_lit_doc_lit\n    ret1, ret2 = @client.doc_lit_doc_lit({'a' => 'b'}, {'c' => 'd'})\n    assert_equal('b', ret1[\"a\"])\n    assert_equal('d', ret2[\"c\"])\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/wsdlDriver/README.txt",
    "content": "echo_version.rb is generated by wsdl2ruby.rb;\n% wsdl2ruby.rb --wsdl simpletype.wsdl --classdef --force\n"
  },
  {
    "path": "test/soap/wsdlDriver/calc.wsdl",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<!--generated by GLUE Standard 4.0.1 on Wed Mar 09 10:20:07 GMT-08:00\n2005-->\n<wsdl:definitions name='Calculator'\ntargetNamespace='http://www.themindelectric.com/wsdl/Calculator/'\n    xmlns:tns='http://www.themindelectric.com/wsdl/Calculator/'\n    xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'\n    xmlns:http='http://schemas.xmlsoap.org/wsdl/http/'\n    xmlns:mime='http://schemas.xmlsoap.org/wsdl/mime/'\n    xmlns:xsd='http://www.w3.org/2001/XMLSchema'\n    xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'\n    xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'\n    xmlns:tme='http://www.themindelectric.com/'>\n    <wsdl:message name='add0In'>\n        <wsdl:part name='x' type='xsd:float'/>\n        <wsdl:part name='y' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='add0Out'>\n        <wsdl:part name='Result' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='divide1In'>\n        <wsdl:part name='numerator' type='xsd:float'/>\n        <wsdl:part name='denominator' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='divide1Out'>\n        <wsdl:part name='Result' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='multiply2In'>\n        <wsdl:part name='x' type='xsd:float'/>\n        <wsdl:part name='y' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='multiply2Out'>\n        <wsdl:part name='Result' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='subtract3In'>\n        <wsdl:part name='x' type='xsd:float'/>\n        <wsdl:part name='y' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:message name='subtract3Out'>\n        <wsdl:part name='Result' type='xsd:float'/>\n    </wsdl:message>\n    <wsdl:portType name='ICalculator'>\n        <wsdl:operation name='add' parameterOrder='x y'>\n            <wsdl:input name='add0In' message='tns:add0In'/>\n            <wsdl:output name='add0Out' message='tns:add0Out'/>\n        </wsdl:operation>\n        <wsdl:operation name='divide' parameterOrder='numerator\ndenominator'>\n            <wsdl:input name='divide1In' message='tns:divide1In'/>\n            <wsdl:output name='divide1Out' message='tns:divide1Out'/>\n        </wsdl:operation>\n        <wsdl:operation name='multiply' parameterOrder='x y'>\n            <wsdl:input name='multiply2In' message='tns:multiply2In'/>\n            <wsdl:output name='multiply2Out'\nmessage='tns:multiply2Out'/>\n        </wsdl:operation>\n        <wsdl:operation name='subtract' parameterOrder='x y'>\n            <wsdl:input name='subtract3In' message='tns:subtract3In'/>\n            <wsdl:output name='subtract3Out'\nmessage='tns:subtract3Out'/>\n        </wsdl:operation>\n    </wsdl:portType>\n    <wsdl:binding name='ICalculator' type='tns:ICalculator'>\n        <soap:binding style='rpc'\ntransport='http://schemas.xmlsoap.org/soap/http'/>\n        <wsdl:operation name='add'>\n            <soap:operation soapAction='add' style='rpc'/>\n            <wsdl:input name='add0In'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:input>\n            <wsdl:output name='add0Out'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:output>\n        </wsdl:operation>\n        <wsdl:operation name='divide'>\n            <soap:operation soapAction='divide' style='rpc'/>\n            <wsdl:input name='divide1In'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:input>\n            <wsdl:output name='divide1Out'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:output>\n        </wsdl:operation>\n        <wsdl:operation name='multiply'>\n            <soap:operation soapAction='multiply' style='rpc'/>\n            <wsdl:input name='multiply2In'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:input>\n            <wsdl:output name='multiply2Out'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:output>\n        </wsdl:operation>\n        <wsdl:operation name='subtract'>\n            <soap:operation soapAction='subtract' style='rpc'/>\n            <wsdl:input name='subtract3In'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:input>\n            <wsdl:output name='subtract3Out'>\n                <soap:body use='encoded'\nnamespace='http://www.fred.com'\nencodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>\n            </wsdl:output>\n        </wsdl:operation>\n    </wsdl:binding>\n    <wsdl:service name='Calculator'>\n        <wsdl:documentation>calculator service</wsdl:documentation>\n        <wsdl:port name='ICalculator' binding='tns:ICalculator'>\n            <soap:address\nlocation='http://ukulele:8080/calcapp/services/calculator'/>\n        </wsdl:port>\n    </wsdl:service>\n</wsdl:definitions>\n"
  },
  {
    "path": "test/soap/wsdlDriver/document.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name=\"submit_service\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:example.com:document\"\n    targetNamespace=\"urn:example.com:document\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema targetNamespace=\"urn:example.com:document\">\n      <xsd:element name=\"ruby\">\n        <xsd:complexType>\n          <xsd:sequence>\n            <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"myversion\" type=\"tns:myversion\"/>\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"date\" type=\"xsd:dateTime\"/>\n          </xsd:sequence>\n        </xsd:complexType>\n      </xsd:element>\n\n      <xsd:simpleType name=\"myversion\">\n        <xsd:restriction base=\"xsd:string\">\n          <xsd:enumeration value=\"1.6\"/>\n          <xsd:enumeration value=\"1.8\"/>\n          <xsd:enumeration value=\"1.9\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:schema>\n  </types>\n\n  <message name=\"submit_msg\">\n    <part name=\"parameters\" element=\"tns:ruby\"/>\n  </message>\n\n  <portType name=\"submit_port_type\">\n    <operation name=\"submit\">\n      <input message=\"tns:submit_msg\"/>\n      <output message=\"tns:submit_msg\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"submit_binding\" type=\"tns:submit_port_type\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\"/>\n    <operation name=\"submit\">\n      <soap:operation soapAction=\"urn:example.com:document#submit\" style=\"document\"/>\n      <input><soap:body use=\"literal\"/></input>\n      <output><soap:body use=\"literal\"/></output>\n    </operation>\n  </binding>\n\n  <service name=\"submit_service\">\n    <port name=\"submit_port\" binding=\"tns:submit_binding\">\n      <soap:address location=\"http://localhost:10080\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/soap/wsdlDriver/echo_version.rb",
    "content": "# urn:example.com:simpletype-rpc-type\nclass Version_struct\n  @@schema_type = \"version_struct\"\n  @@schema_ns = \"urn:example.com:simpletype-rpc-type\"\n\n  attr_accessor :version\n  attr_accessor :msg\n\n  def initialize(version = nil, msg = nil)\n    @version = version\n    @msg = msg\n  end\nend\n\n# urn:example.com:simpletype-rpc-type\nmodule Versions\n  C_16 = \"1.6\"\n  C_18 = \"1.8\"\n  C_19 = \"1.9\"\nend\n"
  },
  {
    "path": "test/soap/wsdlDriver/simpletype.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name=\"echo_version\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:example.com:simpletype-rpc\"\n    xmlns:txd=\"urn:example.com:simpletype-rpc-type\"\n    targetNamespace=\"urn:example.com:simpletype-rpc\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema targetNamespace=\"urn:example.com:simpletype-rpc-type\">\n      <xsd:complexType name=\"version_struct\">\n\t<xsd:all>\n\t  <xsd:element name=\"myversion\" type=\"txd:myversions\" />\n\t  <xsd:element name=\"msg\" type=\"xsd:string\" />\n\t</xsd:all>\n      </xsd:complexType>\n\n      <xsd:simpleType name=\"myversions\">\n        <xsd:restriction base=\"xsd:string\">\n          <xsd:enumeration value=\"1.6\"/>\n          <xsd:enumeration value=\"1.8\"/>\n          <xsd:enumeration value=\"1.9\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:schema>\n  </types>\n\n  <message name=\"msg_version\">\n    <part name=\"myversion\" type=\"txd:myversions\"/>\n  </message>\n\n  <message name=\"msg_version_struct\">\n    <part name=\"return\" type=\"txd:version_struct\"/>\n  </message>\n\n  <portType name=\"echo_version_port_type\">\n    <operation name=\"echo_version\">\n      <input message=\"tns:msg_version\"/>\n      <output message=\"tns:msg_version_struct\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"echo_version_binding\" type=\"tns:echo_version_port_type\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"rpc\"/>\n    <operation name=\"echo_version\">\n      <soap:operation soapAction=\"urn:example.com:simpletype-rpc\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:simpletype-rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:simpletype-rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"echo_version_service\">\n    <port name=\"echo_version_port\" binding=\"tns:echo_version_binding\">\n      <soap:address location=\"http://localhost:10080\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/soap/wsdlDriver/test_calc.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/httpserver'\nrequire 'soap/wsdlDriver'\n\n\nmodule SOAP\n\n\nclass TestCalc < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::HTTPServer\n    def on_init\n      add_method(self, 'add', 'x', 'y')\n    end\n  \n    def add(x, y)\n      x.to_f + y.to_f\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new(\n      :BindAddress => \"0.0.0.0\",\n      :Port => Port,\n      :AccessLog => [],\n      :SOAPDefaultNamespace => 'http://www.fred.com'\n    )\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    @wsdl = File.join(DIR, 'calc.wsdl')\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream if @client\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_rpc_driver\n    @client = ::SOAP::WSDLDriverFactory.new(@wsdl).create_rpc_driver\n    @client.wiredump_dev = STDOUT if $DEBUG\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.generate_explicit_type = true\n    assert_equal(0.3, @client.add(0.1, 0.2))\n    @client.generate_explicit_type = false\n    assert_equal(0.3, @client.add(0.1, 0.2))\n  end\n\n  def test_old_driver\n    silent do\n      @client = ::SOAP::WSDLDriverFactory.new(@wsdl).create_driver\n    end\n    @client.wiredump_dev = STDOUT if $DEBUG\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.generate_explicit_type = true\n    assert_equal(0.3, @client.add(0.1, 0.2))\n    @client.generate_explicit_type = false\n    assert_equal(0.3, @client.add(0.1, 0.2))\n  end\n\n  def silent\n    back = $VERBOSE\n    $VERBOSE = nil\n    begin\n      yield\n    ensure\n      $VERBOSE = back\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/wsdlDriver/test_document.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\n\nmodule SOAP\n\n\nclass TestDocument < Test::Unit::TestCase\n  Namespace = 'urn:example.com:document'\n\n  class Server < ::SOAP::RPC::StandaloneServer\n    def on_init\n      add_document_method(self, 'urn:example.com:document#submit', 'submit', XSD::QName.new(Namespace, 'ruby'), XSD::QName.new(Namespace, 'ruby'))\n    end\n  \n    def submit(ruby)\n      ruby\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new('Test', Namespace, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'document.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDOUT if $DEBUG\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_document\n    msg = {'myversion' => \"1.9\", 'date' => \"2004-01-01T00:00:00Z\"}\n    reply_msg = @client.submit(msg)\n    assert_equal('1.9', reply_msg.myversion)\n    assert_equal('1.9', reply_msg['myversion'])\n    assert_equal('2004-01-01T00:00:00Z', reply_msg.date)\n    assert_equal('2004-01-01T00:00:00Z', reply_msg['date'])\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/soap/wsdlDriver/test_simpletype.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/httpserver'\nrequire 'soap/wsdlDriver'\n\n\nmodule SOAP\n\n\nclass TestSimpleType < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::HTTPServer\n    def on_init\n      add_method(self, 'echo_version', 'version')\n    end\n  \n    def echo_version(version)\n      # \"2.0\" is out of range.\n      Version_struct.new(version || \"2.0\", 'checked')\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n  require File.join(DIR, 'echo_version')\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new(\n      :BindAddress => \"0.0.0.0\",\n      :Port => Port,\n      :AccessLog => [],\n      :SOAPDefaultNamespace => \"urn:example.com:simpletype-rpc\"\n    )\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'simpletype.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.wiredump_dev = STDOUT if $DEBUG\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.generate_explicit_type = false\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_ping\n    result = @client.echo_version(\"1.9\")\n    assert_equal(\"1.9\", result.version)\n    assert_equal(\"checked\", result.msg)\n    assert_raise(XSD::ValueSpaceError) do\n      @client.echo_version(\"2.0\")\n    end\n    assert_raise(XSD::ValueSpaceError) do\n      @client.echo_version(nil) # nil => \"2.0\" => out of range\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/socket/test_nonblock.rb",
    "content": "begin\n  require \"socket\"\nrescue LoadError\nend\n\nrequire \"test/unit\"\nrequire \"tempfile\"\nrequire \"timeout\"\n\nclass TestNonblockSocket < Test::Unit::TestCase\n  def test_accept_nonblock\n    serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)\n    serv.bind(Socket.sockaddr_in(0, \"127.0.0.1\"))\n    serv.listen(5)\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { serv.accept_nonblock }\n    c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)\n    c.connect(serv.getsockname)\n    s, sockaddr = serv.accept_nonblock\n    assert_equal(Socket.unpack_sockaddr_in(c.getsockname), Socket.unpack_sockaddr_in(sockaddr))\n  ensure\n    serv.close if serv\n    c.close if c\n    s.close if s\n  end\n\n  def test_connect_nonblock\n    serv = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)\n    serv.bind(Socket.sockaddr_in(0, \"127.0.0.1\"))\n    serv.listen(5)\n    c = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)\n    servaddr = serv.getsockname\n    begin\n      c.connect_nonblock(servaddr)\n    rescue Errno::EINPROGRESS\n      IO.select nil, [c]\n      assert_nothing_raised {\n        begin\n          c.connect_nonblock(servaddr)\n        rescue Errno::EISCONN\n        end\n      }\n    end\n    s, sockaddr = serv.accept\n    assert_equal(Socket.unpack_sockaddr_in(c.getsockname), Socket.unpack_sockaddr_in(sockaddr))\n  ensure\n    serv.close if serv\n    c.close if c\n    s.close if s\n  end\n\n  def test_udp_recvfrom_nonblock\n    u1 = UDPSocket.new\n    u2 = UDPSocket.new\n    u1.bind(\"127.0.0.1\", 0)\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { u1.recvfrom_nonblock(100) }\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINVAL) { u2.recvfrom_nonblock(100) }\n    u2.send(\"aaa\", 0, u1.getsockname)\n    IO.select [u1]\n    mesg, inet_addr = u1.recvfrom_nonblock(100)\n    assert_equal(4, inet_addr.length)\n    assert_equal(\"aaa\", mesg)\n    af, port, host, addr = inet_addr\n    u2_port, u2_addr = Socket.unpack_sockaddr_in(u2.getsockname)\n    assert_equal(u2_port, port)\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { u1.recvfrom_nonblock(100) }\n    u2.send(\"\", 0, u1.getsockname)\n    assert_nothing_raised(\"cygwin 1.5.19 has a problem to send an empty UDP packet. [ruby-dev:28915]\") {\n      timeout(1) { IO.select [u1] }\n    }\n    mesg, inet_addr = u1.recvfrom_nonblock(100)\n    assert_equal(\"\", mesg)\n  ensure\n    u1.close if u1\n    u2.close if u2\n  end\n\n  def test_udp_recv_nonblock\n    u1 = UDPSocket.new\n    u2 = UDPSocket.new\n    u1.bind(\"127.0.0.1\", 0)\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { u1.recv_nonblock(100) }\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINVAL) { u2.recv_nonblock(100) }\n    u2.send(\"aaa\", 0, u1.getsockname)\n    IO.select [u1]\n    mesg = u1.recv_nonblock(100)\n    assert_equal(\"aaa\", mesg)\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { u1.recv_nonblock(100) }\n    u2.send(\"\", 0, u1.getsockname)\n    assert_nothing_raised(\"cygwin 1.5.19 has a problem to send an empty UDP packet. [ruby-dev:28915]\") {\n      timeout(1) { IO.select [u1] }\n    }\n    mesg = u1.recv_nonblock(100)\n    assert_equal(\"\", mesg)\n  ensure\n    u1.close if u1\n    u2.close if u2\n  end\n\n  def test_socket_recvfrom_nonblock\n    s1 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)\n    s1.bind(Socket.sockaddr_in(0, \"127.0.0.1\"))\n    s2 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { s1.recvfrom_nonblock(100) }\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINVAL) { s2.recvfrom_nonblock(100) }\n    s2.send(\"aaa\", 0, s1.getsockname)\n    IO.select [s1]\n    mesg, sockaddr = s1.recvfrom_nonblock(100) \n    assert_equal(\"aaa\", mesg)\n    port, addr = Socket.unpack_sockaddr_in(sockaddr)\n    s2_port, s2_addr = Socket.unpack_sockaddr_in(s2.getsockname)\n    assert_equal(s2_port, port)\n  ensure\n    s1.close if s1\n    s2.close if s2\n  end\n\n  def tcp_pair\n    serv = TCPServer.new(\"127.0.0.1\", 0)\n    af, port, host, addr = serv.addr\n    c = TCPSocket.new(addr, port)\n    s = serv.accept\n    return c, s\n  ensure\n    serv.close if serv\n  end\n\n  def test_tcp_recv_nonblock\n    c, s = tcp_pair\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { c.recv_nonblock(100) }\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { s.recv_nonblock(100) }\n    c.write(\"abc\")\n    IO.select [s]\n    assert_equal(\"a\", s.recv_nonblock(1))\n    assert_equal(\"bc\", s.recv_nonblock(100))\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { s.recv_nonblock(100) }\n  ensure\n    c.close if c\n    s.close if s\n  end\n\n  def test_read_nonblock\n    c, s = tcp_pair\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { c.read_nonblock(100) }\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { s.read_nonblock(100) }\n    c.write(\"abc\")\n    IO.select [s]\n    assert_equal(\"a\", s.read_nonblock(1))\n    assert_equal(\"bc\", s.read_nonblock(100))\n    assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) { s.read_nonblock(100) }\n  ensure\n    c.close if c\n    s.close if s\n  end\n\n=begin\n  def test_write_nonblock\n    c, s = tcp_pair\n    str = \"a\" * 10000\n    _, ws, _ = IO.select(nil, [c], nil)\n    assert_equal([c], ws)\n    ret = c.write_nonblock(str)\n    assert_operator(ret, :>, 0)\n    loop {\n      assert_raise(Errno::EAGAIN, Errno::EWOULDBLOCK) {\n        loop {\n          ret = c.write_nonblock(str)\n          assert_operator(ret, :>, 0)\n        }\n      }\n      _, ws, _ = IO.select(nil, [c], nil, 0)\n      break if !ws\n    }\n  ensure\n    c.close if c\n    s.close if s\n  end\n=end\n\nend if defined?(Socket)\n"
  },
  {
    "path": "test/socket/test_socket.rb",
    "content": "begin\n  require \"socket\"\n  require \"test/unit\"\nrescue LoadError\nend\n\nclass TestBasicSocket < Test::Unit::TestCase\n  def inet_stream\n    sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)\n    yield sock\n  ensure\n    assert_raise(IOError) {sock.close}\n  end\n\n  def test_getsockopt\n    inet_stream do |s|\n      n = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE)\n      assert_equal([Socket::SOCK_STREAM].pack(\"i\"), n)\n      n = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR)\n      assert_equal([0].pack(\"i\"), n)\n      val = Object.new\n      class << val; self end.__send__(:define_method, :to_int) {\n        s.close\n        Socket::SO_TYPE\n      }\n      assert_raise(IOError) {\n        n = s.getsockopt(Socket::SOL_SOCKET, val)\n      }\n    end\n  end\n\n  def test_setsockopt # [ruby-dev:25039]\n    s = nil\n    linger = [0, 0].pack(\"ii\")\n\n    val = Object.new\n    class << val; self end.__send__(:define_method, :to_str) {\n      s.close\n      linger\n    }\n    inet_stream do |s|\n      assert_equal(0, s.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, linger))\n\n      assert_raise(IOError) {\n        s.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, val)\n      }\n    end\n\n    val = Object.new\n    class << val; self end.__send__(:define_method, :to_int) {\n      s.close\n      Socket::SO_LINGER\n    }\n    inet_stream do |s|\n      assert_raise(IOError) {\n        s.setsockopt(Socket::SOL_SOCKET, val, linger)\n      }\n    end\n  end\n\n  def test_listen\n    s = nil\n    log = Object.new\n    class << log; self end.__send__(:define_method, :to_int) {\n      s.close\n      2\n    }\n    inet_stream do |s|\n      assert_raise(IOError) {\n        s.listen(log)\n      }\n    end\n  end\nend if defined?(Socket)\n\nclass TestSocket < Test::Unit::TestCase\n  def test_unpack_sockaddr\n    sockaddr_in = Socket.sockaddr_in(80, \"\")\n    assert_raise(ArgumentError) { Socket.unpack_sockaddr_un(sockaddr_in) }\n    sockaddr_un = Socket.sockaddr_un(\"/tmp/s\")\n    assert_raise(ArgumentError) { Socket.unpack_sockaddr_in(sockaddr_un) }\n  end\nend if defined?(Socket) && Socket.respond_to?(:sockaddr_un)\n"
  },
  {
    "path": "test/socket/test_unix.rb",
    "content": "begin\n  require \"socket\"\nrescue LoadError\nend\n\nrequire \"test/unit\"\nrequire \"tempfile\"\n\nclass TestUNIXSocket < Test::Unit::TestCase\n  def test_fd_passing\n    r1, w = IO.pipe\n    s1, s2 = UNIXSocket.pair\n    begin\n      s1.send_io(nil)\n    rescue NotImplementedError\n      assert_raise(NotImplementedError) { s2.recv_io }\n    rescue TypeError\n      s1.send_io(r1)\n      r2 = s2.recv_io\n      assert_equal(r1.stat.ino, r2.stat.ino)\n      assert_not_equal(r1.fileno, r2.fileno)\n      w.syswrite \"a\"\n      assert_equal(\"a\", r2.sysread(10))\n    ensure\n      s1.close\n      s2.close\n      w.close\n      r1.close\n      r2.close if r2 && !r2.closed?\n    end\n  end\n\n  def bound_unix_socket(klass)\n    tmpfile = Tempfile.new(\"testrubysock\")\n    path = tmpfile.path\n    tmpfile.close(true)\n    yield klass.new(path), path\n  ensure\n    File.unlink path if path && File.socket?(path)\n  end\n\n  def test_addr\n    bound_unix_socket(UNIXServer) {|serv, path|\n      c = UNIXSocket.new(path)\n      s = serv.accept\n      assert_equal([\"AF_UNIX\", path], c.peeraddr)\n      assert_equal([\"AF_UNIX\", \"\"], c.addr)\n      assert_equal([\"AF_UNIX\", \"\"], s.peeraddr)\n      assert_equal([\"AF_UNIX\", path], s.addr)\n      assert_equal(path, s.path)\n      assert_equal(\"\", c.path)\n    }\n  end\n\n  def test_noname_path\n    s1, s2 = UNIXSocket.pair\n    assert_equal(\"\", s1.path)\n    assert_equal(\"\", s2.path)\n  ensure\n    s1.close\n    s2.close\n  end\n\n  def test_noname_addr\n    s1, s2 = UNIXSocket.pair\n    assert_equal([\"AF_UNIX\", \"\"], s1.addr)\n    assert_equal([\"AF_UNIX\", \"\"], s2.addr)\n  ensure\n    s1.close\n    s2.close\n  end\n\n  def test_noname_peeraddr\n    s1, s2 = UNIXSocket.pair\n    assert_equal([\"AF_UNIX\", \"\"], s1.peeraddr)\n    assert_equal([\"AF_UNIX\", \"\"], s2.peeraddr)\n  ensure\n    s1.close\n    s2.close\n  end\n\n  def test_noname_unpack_sockaddr_un\n    s1, s2 = UNIXSocket.pair\n    n = nil\n    assert_equal(\"\", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != \"\"\n    assert_equal(\"\", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != \"\"\n    assert_equal(\"\", Socket.unpack_sockaddr_un(n)) if (n = s2.getsockname) != \"\"\n    assert_equal(\"\", Socket.unpack_sockaddr_un(n)) if (n = s1.getpeername) != \"\"\n    assert_equal(\"\", Socket.unpack_sockaddr_un(n)) if (n = s2.getpeername) != \"\"\n  ensure\n    s1.close\n    s2.close\n  end\n\n  def test_noname_recvfrom\n    s1, s2 = UNIXSocket.pair\n    s2.write(\"a\")\n    assert_equal([\"a\", [\"AF_UNIX\", \"\"]], s1.recvfrom(10))\n  ensure\n    s1.close\n    s2.close\n  end\n\n  def test_noname_recv_nonblock\n    s1, s2 = UNIXSocket.pair\n    s2.write(\"a\")\n    IO.select [s1]\n    assert_equal(\"a\", s1.recv_nonblock(10))\n  ensure\n    s1.close\n    s2.close\n  end\n\n  def test_too_long_path\n    assert_raise(ArgumentError) { Socket.sockaddr_un(\"a\" * 300) }\n    assert_raise(ArgumentError) { UNIXServer.new(\"a\" * 300) }\n  end\n\n  def test_nul\n    assert_raise(ArgumentError) { Socket.sockaddr_un(\"a\\0b\") }\n    assert_raise(ArgumentError) { UNIXServer.new(\"a\\0b\") }\n  end\n\n  def test_dgram_pair\n    s1, s2 = UNIXSocket.pair(Socket::SOCK_DGRAM)\n    assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }\n    s2.send(\"\", 0)\n    s2.send(\"haha\", 0)\n    s2.send(\"\", 0)\n    s2.send(\"\", 0)\n    assert_equal(\"\", s1.recv(10))\n    assert_equal(\"haha\", s1.recv(10))\n    assert_equal(\"\", s1.recv(10))\n    assert_equal(\"\", s1.recv(10))\n    assert_raise(Errno::EAGAIN) { s1.recv_nonblock(10) }\n  ensure\n    s1.close if s1\n    s2.close if s2\n  end\n\nend if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM\n"
  },
  {
    "path": "test/stringio/test_stringio.rb",
    "content": "require 'test/unit'\nrequire 'stringio'\ndir = File.expand_path(__FILE__)\n2.times {dir = File.dirname(dir)}\n$:.replace([File.join(dir, \"ruby\")] | $:)\nrequire 'ut_eof'\n\nclass TestStringIO < Test::Unit::TestCase\n  include TestEOF\n  def open_file(content)\n    f = StringIO.new(content)\n    yield f\n  end\n  alias open_file_rw open_file\n\n  include TestEOF::Seek\n\n  def test_truncate # [ruby-dev:24190]\n    io = StringIO.new(\"\")\n    io.puts \"abc\"\n    io.truncate(0)\n    io.puts \"def\"\n    assert_equal(\"\\0\\0\\0\\0def\\n\", io.string)\n  end\n\n  def test_seek_beyond_eof # [ruby-dev:24194]\n    io = StringIO.new\n    n = 100\n    io.seek(n)\n    io.print \"last\"\n    assert_equal(\"\\0\" * n + \"last\", io.string)\n  end\n\n  def test_overwrite # [ruby-core:03836]\n    stringio = StringIO.new\n    responses = ['', 'just another ruby', 'hacker']\n    responses.each do |resp|\n      stringio.puts(resp)\n      stringio.rewind\n    end\n    assert_equal(\"hacker\\nother ruby\\n\", stringio.string)\n  end\n  \n  def test_reopen\n    f = StringIO.new(\"foo\\nbar\\nbaz\\n\")\n    assert_equal(\"foo\\n\", f.gets)\n    f.reopen(\"qux\\nquux\\nquuux\\n\")\n    assert_equal(\"qux\\n\", f.gets)\n\n    f2 = StringIO.new(\"\")\n    f2.reopen(f)\n    assert_equal(\"quux\\n\", f2.gets)\n  ensure\n    f.close unless f.closed?\n  end\nend\n"
  },
  {
    "path": "test/strscan/test_stringscanner.rb",
    "content": "#\n# test/strscan/test_stringscanner.rb\n#\n\nrequire 'strscan'\nrequire 'test/unit'\n\nclass TestStringScanner < Test::Unit::TestCase\n  def test_s_new\n    s = StringScanner.new('test string')\n    assert_instance_of StringScanner, s\n    assert_equal false, s.eos?\n    assert_equal false, s.tainted?\n\n    str = 'test string'\n    str.taint\n    s = StringScanner.new(str, false)\n    assert_instance_of StringScanner, s\n    assert_equal false, s.eos?\n    assert_same str, s.string\n    assert_equal true, s.string.tainted?\n\n    str = 'test string'\n    str.taint\n    s = StringScanner.new(str)\n    assert_equal true, s.string.tainted?\n  end\n\n  UNINIT_ERROR = ArgumentError\n\n  def test_s_allocate\n    s = StringScanner.allocate\n    assert_equal '#<StringScanner (uninitialized)>', s.inspect.sub(/StringScanner_C/, 'StringScanner')\n    assert_raises(UNINIT_ERROR) { s.eos? }\n    assert_raises(UNINIT_ERROR) { s.scan(/a/) }\n    s.string = 'test'\n    assert_equal '#<StringScanner 0/4 @ \"test\">', s.inspect.sub(/StringScanner_C/, 'StringScanner')\n    assert_nothing_raised(UNINIT_ERROR) { s.eos? }\n    assert_equal false, s.eos?\n  end\n\n  def test_s_mustc\n    assert_nothing_raised(NotImplementedError) {\n        StringScanner.must_C_version\n    }\n  end\n\n  def test_dup\n    s = StringScanner.new('test string')\n    d = s.dup\n    assert_equal s.inspect, d.inspect\n    assert_equal s.string, d.string\n    assert_equal s.pos, d.pos\n    assert_equal s.matched?, d.matched?\n    assert_equal s.eos?, d.eos?\n\n    s = StringScanner.new('test string')\n    s.scan(/test/)\n    d = s.dup\n    assert_equal s.inspect, d.inspect\n    assert_equal s.string, d.string\n    assert_equal s.pos, d.pos\n    assert_equal s.matched?, d.matched?\n    assert_equal s.eos?, d.eos?\n\n    s = StringScanner.new('test string')\n    s.scan(/test/)\n    s.scan(/NOT MATCH/)\n    d = s.dup\n    assert_equal s.inspect, d.inspect\n    assert_equal s.string, d.string\n    assert_equal s.pos, d.pos\n    assert_equal s.matched?, d.matched?\n    assert_equal s.eos?, d.eos?\n\n    s = StringScanner.new('test string')\n    s.terminate\n    d = s.dup\n    assert_equal s.inspect, d.inspect\n    assert_equal s.string, d.string\n    assert_equal s.pos, d.pos\n    assert_equal s.matched?, d.matched?\n    assert_equal s.eos?, d.eos?\n  end\n\n  def test_const_Version\n    assert_instance_of String, StringScanner::Version\n    assert_equal true, StringScanner::Version.frozen?\n  end\n\n  def test_const_Id\n    assert_instance_of String, StringScanner::Id\n    assert_equal true, StringScanner::Id.frozen?\n  end\n\n  def test_inspect\n    str = 'test string'\n    str.taint\n    s = StringScanner.new(str, false)\n    assert_instance_of String, s.inspect\n    assert_equal s.inspect, s.inspect\n    assert_equal '#<StringScanner 0/11 @ \"test ...\">', s.inspect.sub(/StringScanner_C/, 'StringScanner')\n    s.get_byte\n    assert_equal '#<StringScanner 1/11 \"t\" @ \"est s...\">', s.inspect.sub(/StringScanner_C/, 'StringScanner')\n    assert_equal true, s.inspect.tainted?\n\n    s = StringScanner.new(\"\\n\")\n    assert_equal '#<StringScanner 0/1 @ \"\\n\">', s.inspect\n  end\n\n  def test_eos?\n    s = StringScanner.new('test string')\n    assert_equal false, s.eos?\n    assert_equal false, s.eos?\n    s.scan(/\\w+/)\n    assert_equal false, s.eos?\n    assert_equal false, s.eos?\n    s.scan(/\\s+/)\n    s.scan(/\\w+/)\n    assert_equal true, s.eos?\n    assert_equal true, s.eos?\n    s.scan(/\\w+/)\n    assert_equal true, s.eos?\n\n    s = StringScanner.new('test')\n    s.scan(/te/)\n    s.string.replace ''\n    assert_equal true, s.eos?\n  end\n\n  def test_bol?\n    s = StringScanner.new(\"a\\nbbb\\n\\ncccc\\nddd\\r\\neee\")\n    assert_equal true, s.bol?\n    assert_equal true, s.bol?\n    s.scan(/a/)\n    assert_equal false, s.bol?\n    assert_equal false, s.bol?\n    s.scan(/\\n/)\n    assert_equal true, s.bol?\n    s.scan(/b/)\n    assert_equal false, s.bol?\n    s.scan(/b/)\n    assert_equal false, s.bol?\n    s.scan(/b/)\n    assert_equal false, s.bol?\n    s.scan(/\\n/)\n    assert_equal true, s.bol?\n    s.unscan\n    assert_equal false, s.bol?\n    s.scan(/\\n/)\n    s.scan(/\\n/)\n    assert_equal true, s.bol?\n    s.scan(/c+\\n/)\n    assert_equal true, s.bol?\n    s.scan(/d+\\r\\n/)\n    assert_equal true, s.bol?\n    s.scan(/e+/)\n    assert_equal false, s.bol?\n  end\n\n  def test_string\n    s = StringScanner.new('test')\n    assert_equal 'test', s.string\n    s.string = 'a'\n    assert_equal 'a', s.string\n    s.scan(/a/)\n    s.string = 'b'\n    assert_equal 0, s.pos\n  end\n\n  def test_pos\n    s = StringScanner.new('test string')\n    assert_equal 0, s.pos\n    s.get_byte\n    assert_equal 1, s.pos\n    s.get_byte\n    assert_equal 2, s.pos\n    s.terminate\n    assert_equal 11, s.pos\n  end\n\n  def test_concat\n    s = StringScanner.new('a')\n    s.scan(/a/)\n    s.concat 'b'\n    assert_equal false, s.eos?\n    assert_equal 'b', s.scan(/b/)\n    assert_equal true, s.eos?\n    s.concat 'c'\n    assert_equal false, s.eos?\n    assert_equal 'c', s.scan(/c/)\n    assert_equal true, s.eos?\n  end\n\n  def test_scan\n    s = StringScanner.new('stra strb strc', true)\n    tmp = s.scan(/\\w+/)\n    assert_equal 'stra', tmp\n    assert_equal false, tmp.tainted?\n\n    tmp = s.scan(/\\s+/)\n    assert_equal ' ', tmp\n    assert_equal false, tmp.tainted?\n\n    assert_equal 'strb', s.scan(/\\w+/)\n    assert_equal ' ',    s.scan(/\\s+/)\n\n    tmp = s.scan(/\\w+/)\n    assert_equal 'strc', tmp\n    assert_equal false, tmp.tainted?\n\n    assert_nil           s.scan(/\\w+/)\n    assert_nil           s.scan(/\\w+/)\n\n\n    str = 'stra strb strc'\n    str.taint\n    s = StringScanner.new(str, false)\n    tmp = s.scan(/\\w+/)\n    assert_equal 'stra', tmp\n    assert_equal true, tmp.tainted?\n\n    tmp = s.scan(/\\s+/)\n    assert_equal ' ', tmp\n    assert_equal true, tmp.tainted?\n\n    assert_equal 'strb', s.scan(/\\w+/)\n    assert_equal ' ',    s.scan(/\\s+/)\n\n    tmp = s.scan(/\\w+/)\n    assert_equal 'strc', tmp\n    assert_equal true, tmp.tainted?\n\n    assert_nil           s.scan(/\\w+/)\n    assert_nil           s.scan(/\\w+/)\n\n    s = StringScanner.new('test')\n    s.scan(/te/)\n    # This assumes #string does not duplicate string,\n    # but it is implementation specific issue.\n    # DO NOT RELY ON THIS FEATURE.\n    s.string.replace ''\n    # unspecified: assert_equal 2, s.pos\n    assert_equal nil, s.scan(/test/)\n\n    # [ruby-bugs:4361]\n    s = StringScanner.new(\"\")\n    assert_equal \"\", s.scan(//)\n    assert_equal \"\", s.scan(//)\n\n    # [ruby-dev:29914]\n    %w( NONE EUC SJIS UTF8 ).each do |kcode|\n      begin\n        $KCODE = kcode\n        assert_equal \"a\", StringScanner.new(\"a:b\").scan(/[^\\x01\\:]+/n)\n        assert_equal \"a\", StringScanner.new(\"a:b\").scan(/[^\\x01\\:]+/e)\n        assert_equal \"a\", StringScanner.new(\"a:b\").scan(/[^\\x01\\:]+/s)\n        assert_equal \"a\", StringScanner.new(\"a:b\").scan(/[^\\x01\\:]+/u)\n      ensure\n        $KCODE = 'NONE'\n      end\n    end\n  end\n\n  def test_skip\n    s = StringScanner.new('stra strb strc', true)\n    assert_equal 4, s.skip(/\\w+/)\n    assert_equal 1, s.skip(/\\s+/)\n    assert_equal 4, s.skip(/\\w+/)\n    assert_equal 1, s.skip(/\\s+/)\n    assert_equal 4, s.skip(/\\w+/)\n    assert_nil      s.skip(/\\w+/)\n    assert_nil      s.skip(/\\s+/)\n    assert_equal true, s.eos?\n\n    s = StringScanner.new('test')\n    s.scan(/te/)\n    s.string.replace ''\n    assert_equal nil, s.skip(/./)\n\n    # [ruby-bugs:4361]\n    s = StringScanner.new(\"\")\n    assert_equal 0, s.skip(//)\n    assert_equal 0, s.skip(//)\n  end\n\n  def test_getch\n    s = StringScanner.new('abcde')\n    assert_equal 'a', s.getch\n    assert_equal 'b', s.getch\n    assert_equal 'c', s.getch\n    assert_equal 'd', s.getch\n    assert_equal 'e', s.getch\n    assert_nil        s.getch\n\n    str = 'abc'\n    str.taint\n    s = StringScanner.new(str)\n    assert_equal true, s.getch.tainted?\n    assert_equal true, s.getch.tainted?\n    assert_equal true, s.getch.tainted?\n    assert_nil s.getch\n\n    kc_backup = $KCODE\n    begin\n      $KCODE = 'EUC'\n      s = StringScanner.new(\"\\244\\242\")\n      assert_equal \"\\244\\242\", s.getch\n      assert_nil s.getch\n    ensure\n      $KCODE = kc_backup\n    end\n\n    s = StringScanner.new('test')\n    s.scan(/te/)\n    s.string.replace ''\n    assert_equal nil, s.getch\n  end\n\n  def test_get_byte\n    s = StringScanner.new('abcde')\n    assert_equal 'a', s.get_byte\n    assert_equal 'b', s.get_byte\n    assert_equal 'c', s.get_byte\n    assert_equal 'd', s.get_byte\n    assert_equal 'e', s.get_byte\n    assert_nil        s.get_byte\n    assert_nil        s.get_byte\n\n    str = 'abc'\n    str.taint\n    s = StringScanner.new(str)\n    assert_equal true, s.get_byte.tainted?\n    assert_equal true, s.get_byte.tainted?\n    assert_equal true, s.get_byte.tainted?\n    assert_nil s.get_byte\n\n    kc_backup = $KCODE\n    begin\n      $KCODE = 'EUC'\n      s = StringScanner.new(\"\\244\\242\")\n      assert_equal \"\\244\", s.get_byte\n      assert_equal \"\\242\", s.get_byte\n      assert_nil s.get_byte\n    ensure\n      $KCODE = kc_backup\n    end\n\n    s = StringScanner.new('test')\n    s.scan(/te/)\n    s.string.replace ''\n    assert_equal nil, s.get_byte\n  end\n\n  def test_matched\n    s = StringScanner.new('stra strb strc')\n    s.scan(/\\w+/)\n    assert_equal 'stra', s.matched\n    assert_equal false, s.matched.tainted?\n    s.scan(/\\s+/)\n    assert_equal ' ', s.matched\n    s.scan(/\\w+/)\n    assert_equal 'strb', s.matched\n    s.scan(/\\s+/)\n    assert_equal ' ', s.matched\n    s.scan(/\\w+/)\n    assert_equal 'strc', s.matched\n    s.scan(/\\w+/)\n    assert_nil s.matched\n    s.getch\n    assert_nil s.matched\n\n    s = StringScanner.new('stra strb strc')\n    s.getch\n    assert_equal 's', s.matched\n    assert_equal false, s.matched.tainted?\n    s.get_byte\n    assert_equal 't', s.matched\n    assert_equal 't', s.matched\n    assert_equal false, s.matched.tainted?\n\n    str = 'test'\n    str.taint\n    s = StringScanner.new(str)\n    s.scan(/\\w+/)\n    assert_equal true, s.matched.tainted?\n    assert_equal true, s.matched.tainted?\n  end\n\n  def test_AREF\n    s = StringScanner.new('stra strb strc')\n\n    s.scan(/\\w+/)\n    assert_nil           s[-2]\n    assert_equal 'stra', s[-1]\n    assert_equal 'stra', s[0]\n    assert_nil           s[1]\n\n    assert_equal false,  s[-1].tainted?\n    assert_equal false,  s[0].tainted?\n\n    s.skip(/\\s+/)\n    assert_nil           s[-2]\n    assert_equal ' ',    s[-1]\n    assert_equal ' ',    s[0]\n    assert_nil           s[1]\n\n    s.scan(/(s)t(r)b/)\n    assert_nil           s[-100]\n    assert_nil           s[-4]\n    assert_equal 'strb', s[-3]\n    assert_equal 's',    s[-2]\n    assert_equal 'r',    s[-1]\n    assert_equal 'strb', s[0]\n    assert_equal 's',    s[1]\n    assert_equal 'r',    s[2]\n    assert_nil           s[3]\n    assert_nil           s[100]\n\n    s.scan(/\\s+/)\n\n    s.getch\n    assert_nil           s[-2]\n    assert_equal 's',    s[-1]\n    assert_equal 's',    s[0]\n    assert_nil           s[1]\n\n    s.get_byte\n    assert_nil           s[-2]\n    assert_equal 't',    s[-1]\n    assert_equal 't',    s[0]\n    assert_nil           s[1]\n\n    s.scan(/.*/)\n    s.scan(/./)\n    assert_nil           s[0]\n    assert_nil           s[0]\n\n\n    kc_backup = $KCODE\n    begin\n      $KCODE = 'EUC'\n      s = StringScanner.new(\"\\244\\242\")\n      s.getch\n      assert_equal \"\\244\\242\", s[0]\n    ensure\n      $KCODE = kc_backup\n    end\n\n\n    str = 'test'\n    str.taint\n    s = StringScanner.new(str)\n    s.scan(/(t)(e)(s)(t)/)\n    assert_equal true, s[0].tainted?\n    assert_equal true, s[1].tainted?\n    assert_equal true, s[2].tainted?\n    assert_equal true, s[3].tainted?\n    assert_equal true, s[4].tainted?\n  end\n\n  def test_pre_match\n    s = StringScanner.new('a b c d e')\n    s.scan(/\\w/)\n    assert_equal '', s.pre_match\n    assert_equal false, s.pre_match.tainted?\n    s.skip(/\\s/)\n    assert_equal 'a', s.pre_match\n    assert_equal false, s.pre_match.tainted?\n    s.scan(/\\w/)\n    assert_equal 'a ', s.pre_match\n    s.scan_until(/c/)\n    assert_equal 'a b ', s.pre_match\n    s.getch\n    assert_equal 'a b c', s.pre_match\n    s.get_byte\n    assert_equal 'a b c ', s.pre_match\n    s.get_byte\n    assert_equal 'a b c d', s.pre_match\n    s.scan(/never match/)\n    assert_nil s.pre_match\n\n    str = 'test string'\n    str.taint\n    s = StringScanner.new(str)\n    s.scan(/\\w+/)\n    assert_equal true, s.pre_match.tainted?\n    s.scan(/\\s+/)\n    assert_equal true, s.pre_match.tainted?\n    s.scan(/\\w+/)\n    assert_equal true, s.pre_match.tainted?\n  end\n\n  def test_post_match\n    s = StringScanner.new('a b c d e')\n    s.scan(/\\w/)\n    assert_equal ' b c d e', s.post_match\n    s.skip(/\\s/)\n    assert_equal 'b c d e', s.post_match\n    s.scan(/\\w/)\n    assert_equal ' c d e', s.post_match\n    s.scan_until(/c/)\n    assert_equal ' d e', s.post_match\n    s.getch\n    assert_equal 'd e', s.post_match\n    s.get_byte\n    assert_equal ' e', s.post_match\n    s.get_byte\n    assert_equal 'e', s.post_match\n    s.scan(/never match/)\n    assert_nil s.post_match\n    s.scan(/./)\n    assert_equal '', s.post_match\n    s.scan(/./)\n    assert_nil s.post_match\n\n    str = 'test string'\n    str.taint\n    s = StringScanner.new(str)\n    s.scan(/\\w+/)\n    assert_equal true, s.post_match.tainted?\n    s.scan(/\\s+/)\n    assert_equal true, s.post_match.tainted?\n    s.scan(/\\w+/)\n    assert_equal true, s.post_match.tainted?\n  end\n\n  def test_terminate\n    s = StringScanner.new('ssss')\n    s.getch\n    s.terminate\n    assert_equal true, s.eos?\n    s.terminate\n    assert_equal true, s.eos?\n  end\n\n  def test_reset\n    s = StringScanner.new('ssss')\n    s.getch\n    s.reset\n    assert_equal 0, s.pos\n    s.scan(/\\w+/)\n    s.reset\n    assert_equal 0, s.pos\n    s.reset\n    assert_equal 0, s.pos\n  end\n\n  def test_matched_size\n    s = StringScanner.new('test string')\n    assert_nil s.matched_size\n    s.scan(/test/)\n    assert_equal 4, s.matched_size\n    assert_equal 4, s.matched_size\n    s.scan(//)\n    assert_equal 0, s.matched_size\n    s.scan(/x/)\n    assert_nil s.matched_size\n    assert_nil s.matched_size\n    s.terminate\n    assert_nil s.matched_size\n\n    # obsolete\n    s = StringScanner.new('test string')\n    assert_nil s.matchedsize\n    s.scan(/test/)\n    assert_equal 4, s.matched_size\n    s.terminate\n    assert_nil s.matched_size\n  end\nend\n"
  },
  {
    "path": "test/testunit/collector/test_dir.rb",
    "content": "require 'test/unit'\nrequire 'test/unit/collector/dir'\nrequire 'pp'\n\nmodule Test\n  module Unit\n    module Collector\n      class TestDir < TestCase\n        class FileSystem\n          class Directory\n            def initialize(name, fs, parent=self, &block)\n              @name = name\n              @fs = fs\n              @parent = parent\n              @contents = {'.' => self, '..' => parent}\n              instance_eval(&block) if(block)\n            end\n            \n            def file(name, contents)\n              @contents[name] = contents\n            end\n\n            def dir(name, &block)\n              @contents[name] = self.class.new(name, @fs, self, &block)\n            end\n\n            def entries\n              @contents.keys\n            end\n\n            def directory?(name)\n              return true if(name.nil? || name.empty?)\n              return false unless(@contents.include?(name))\n              @contents[name].kind_of?(self.class)\n            end\n\n            def file?(name)\n              return false unless(@contents.include?(name))\n              !directory?(name)\n            end\n\n            def exist?(name)\n              @contents.include?(name)\n            end\n\n            def [](name)\n              raise Errno::ENOENT, name unless(@contents.include?(name))\n              @contents[name]\n            end\n\n            def path_to(name=nil)\n              if(!name)\n                @parent.path_to(@name)\n              elsif(@parent == self)\n                @fs.join('/', name)\n              else\n                @fs.join(@parent.path_to(@name), name)\n              end\n            end\n          end\n\n          class ObjectSpace\n            def initialize\n              @objects = []\n            end\n\n            def each_object(klass, &block)\n              @objects.find_all{|o| o.kind_of?(klass)}.each(&block)\n            end\n\n            def <<(object)\n              @objects << object\n            end\n          end\n\n          attr_reader :object_space\n          \n          def initialize(&block)\n            @root = Directory.new('/', self, &block)\n            @pwd = @root\n            @object_space = ObjectSpace.new\n            @required = []\n          end\n\n          def entries(dir)\n            e = find(dir)\n            require_directory(dir)\n            e.entries\n          end\n\n          def directory?(name)\n            return true if (base = basename(name)) == '/'\n            e = find(dirname(name))\n            return false unless(e)\n            e.directory?(base)\n          end\n\n          def find(path)\n            if(/\\A\\// =~ path)\n              thing = @root\n            else\n              thing = @pwd\n            end\n            path.scan(/[^\\/]+/) do |e|\n              break thing = false unless(thing.kind_of?(Directory))\n              thing = thing[e]\n            end\n            thing\n          end\n\n          def dirname(name)\n            if (name = name.tr_s('/', '/')) == '/'\n              name\n            else\n              name[%r\"\\A.+(?=/[^/]+/?\\z)|\\A/\"] || \".\"\n            end\n          end\n\n          def basename(name)\n            name[%r\"(\\A/|[^/]+)/*\\z\", 1]\n          end\n\n          def split(name)\n            [dirname(name), basename(name)]\n          end\n\n          def join(*parts)\n            parts.join('/').gsub(%r{/+}, '/')\n          end\n\n          def file?(name)\n            e = find(dirname(name))\n            return false unless(e)\n            e.file?(basename(name))\n          end\n\n          def pwd\n            @pwd.path_to\n          end\n\n          def chdir(to)\n            e = find(to)\n            require_directory(to)\n            @pwd = e\n          end\n\n          def expand_path(path, base = nil)\n            until /\\A\\// =~ path\n              base ||= pwd\n              path = join(base, path)\n              base = nil\n            end\n            path.gsub!(%r\"(?:/\\.)+(?=/)\", '')\n            nil while path.sub!(%r\"/(?!\\.\\./)[^/]+/\\.\\.(?=/)\", '')\n            path.sub!(%r\"\\A(?:/\\.\\.)+(?=/)\", '')\n            path.sub!(%r\"(?:\\A(/)|/)\\.\\.?\\z\", '\\1')\n            path\n          end\n\n          def require_directory(path)\n            raise Errno::ENOTDIR, path unless(directory?(path))\n          end\n\n          def require(file)\n            return false if(@required.include?(file))\n            begin\n              e = find(file)\n            rescue Errno::ENOENT => e\n              if(/\\.rb\\Z/ =~ file)\n                raise LoadError, file\n              end\n              e = find(file + '.rb')\n            end\n            @required << file\n            @object_space << e\n            true\n          rescue Errno::ENOENT\n            raise LoadError, file\n          end\n        end\n\n        def test_dir\n          inner_dir = nil\n          dirs = FileSystem::Directory.new('/', nil) do\n            file 'a', nil\n            inner_dir = dir 'b'\n          end\n          assert_equal(inner_dir, dirs['b'])\n        end\n\n        def test_fs\n          fs = FileSystem.new do\n            file 'a', nil\n            dir 'b'\n          end\n          assert_equal(['.', '..', 'a', 'b'].sort, fs.entries('/').sort)\n          assert(fs.directory?('/'))\n          assert(!fs.directory?('/a'))\n          assert(!fs.directory?('/bogus'))\n          assert(fs.file?('/a'))\n          assert(!fs.file?('/'))\n          assert(!fs.file?('/bogus'))\n          assert(fs.directory?('/b'))\n          assert(fs.file?('a'))\n          assert(fs.directory?('b'))\n        end\n\n        def test_fs_sub\n          fs = FileSystem.new do\n            dir 'a' do\n              file 'b', nil\n              dir 'c' do\n                file 'd', nil\n              end\n            end\n          end\n          assert(fs.file?('/a/b'))\n          assert(!fs.file?('/a/b/c/d'))\n          assert(fs.file?('/a/c/d'))\n        end\n\n        def test_fs_pwd\n          fs = FileSystem.new do\n            file 'a', nil\n            dir 'b' do\n              file 'c', nil\n              dir 'd' do\n                file 'e', nil\n              end\n            end\n          end\n          assert_equal('/', fs.pwd)\n          assert_raises(Errno::ENOENT) do\n            fs.chdir('bogus')\n          end\n          assert_raises(Errno::ENOTDIR) do\n            fs.chdir('a')\n          end\n          fs.chdir('b')\n          assert_equal('/b', fs.pwd)\n          fs.chdir('d')\n          assert_equal('/b/d', fs.pwd)\n          fs.chdir('..')\n          assert_equal('/b', fs.pwd)\n          fs.chdir('..')\n          assert_equal('/', fs.pwd)\n        end\n\n        def test_fs_entries\n          fs = FileSystem.new do\n            file 'a', nil\n            dir 'b' do\n              file 'c', nil\n              file 'd', nil\n            end\n            file 'e', nil\n            dir 'f' do\n              file 'g', nil\n              dir 'h' do\n                file 'i', nil\n              end\n            end\n          end\n          assert_equal(['.', '..', 'a', 'b', 'e', 'f'], fs.entries('/').sort)\n          assert_equal(['.', '..', 'a', 'b', 'e', 'f'], fs.entries('.').sort)\n          assert_equal(['.', '..', 'a', 'b', 'e', 'f'], fs.entries('b/..').sort)\n          assert_equal(['.', '..', 'c', 'd'], fs.entries('b').sort)\n          assert_raises(Errno::ENOENT) do\n            fs.entries('z')\n          end\n          assert_raises(Errno::ENOTDIR) do\n            fs.entries('a')\n          end\n          fs.chdir('f')\n          assert_equal(['.', '..', 'i'], fs.entries('h').sort)\n        end\n\n        class TestClass1\n        end\n        class TestClass2\n        end\n        def test_fs_require\n          fs = FileSystem.new do\n            file 'test_class1.rb', TestClass1\n            dir 'dir' do\n              file 'test_class2.rb', TestClass2\n            end\n          end\n          c = []\n          fs.object_space.each_object(Class) do |o|\n            c << o\n          end\n          assert_equal([], c)\n\n          assert_raises(LoadError) do\n            fs.require('bogus')\n          end\n          \n          assert(fs.require('test_class1.rb'))\n          assert(!fs.require('test_class1.rb'))\n          c = []\n          fs.object_space.each_object(Class) do |o|\n            c << o\n          end\n          assert_equal([TestClass1], c)\n\n          fs.require('dir/test_class2')\n          c = []\n          fs.object_space.each_object(Class) do |o|\n            c << o\n          end\n          assert_equal([TestClass1, TestClass2], c)\n\n          c = []\n          fs.object_space.each_object(Time) do |o|\n            c << o\n          end\n          assert_equal([], c)\n        end\n\n        def setup\n          @t1 = t1 = create_test(1)\n          @t2 = t2 = create_test(2)\n          @t3 = t3 = create_test(3)\n          @t4 = t4 = create_test(4)\n          @t5 = t5 = create_test(5)\n          @t6 = t6 = create_test(6)\n          fs = FileSystem.new do\n            file 'test_1.rb', t1\n            file 'test_2.rb', t2\n            dir 'd1' do\n              file 'test_3.rb', t3\n            end\n            file 't4.rb', t4\n            dir 'd2' do\n              file 'test_5', t5\n              file 'test_6.rb', Time\n            end\n            file 't6.rb', t6\n          end\n          fs.require('t6')\n          @c = Dir.new(fs, fs, fs.object_space, fs)\n        end\n\n        def create_test(name)\n          t = Class.new(TestCase)\n          t.class_eval <<-EOC\n            def self.name\n              \"T\\#{#{name}}\"\n            end\n            def test_#{name}a\n            end\n            def test_#{name}b\n            end\n          EOC\n          t\n        end\n\n        def test_simple_collect\n          expected = TestSuite.new('d1')\n          expected << (@t3.suite)\n          assert_equal(expected, @c.collect('d1'))\n        end\n\n        def test_multilevel_collect\n          expected = TestSuite.new('.')\n          expected << @t1.suite << @t2.suite\n          expected << (TestSuite.new('d1') << @t3.suite)\n          assert_equal(expected, @c.collect)\n        end\n\n        def test_collect_file\n          expected = TestSuite.new('test_1.rb')\n          expected << @t1.suite\n          assert_equal(expected, @c.collect('test_1.rb'))\n          \n          expected = TestSuite.new('t4.rb')\n          expected << @t4.suite\n          assert_equal(expected, @c.collect('t4.rb'))\n        end\n\n        def test_nil_pattern\n          expected = TestSuite.new('d2')\n          expected << @t5.suite\n          @c.pattern.clear\n          assert_equal(expected, @c.collect('d2'))\n        end\n\n        def test_filtering\n          expected = TestSuite.new('.')\n          expected << @t1.suite\n          @c.filter = proc{|t| t.method_name == 'test_1a' || t.method_name == 'test_1b'}\n          assert_equal(expected, @c.collect)\n        end\n\n        def test_collect_multi\n          expected = TestSuite.new('[d1, d2]')\n          expected << (TestSuite.new('d1') << @t3.suite)\n          expected << (TestSuite.new('d2') << @t5.suite)\n          @c.pattern.replace([/\\btest_/])\n          assert_equal(expected, @c.collect('d1', 'd2'))\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/collector/test_objectspace.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'test/unit/collector/objectspace'\n\nmodule Test\n  module Unit\n    module Collector\n      class TC_ObjectSpace < TestCase\n        def setup\n          @tc1 = Class.new(TestCase) do\n            def self.name\n              \"tc_1\"\n            end\n            def test_1\n            end\n            def test_2\n            end\n          end\n\n          @tc2 = Class.new(TestCase) do\n            def self.name\n              \"tc_2\"\n            end\n            def test_0\n            end\n          end\n\n          @no_tc = Class.new do\n            def test_4\n            end\n          end\n \n          @object_space = {Class => [@tc1, @tc2, @no_tc], String => ['']}\n          def @object_space.each_object(type)\n            self[type].each{|item| yield(item) }\n          end\n\n          @c = ObjectSpace.new(@object_space)\n        end\n\n        def full_suite(name=ObjectSpace::NAME)\n          expected = TestSuite.new(name)\n          expected << (TestSuite.new(@tc1.name) << @tc1.new('test_1') << @tc1.new('test_2'))\n          expected << (TestSuite.new(@tc2.name) << @tc2.new('test_0'))\n        end\n\n        def empty_suite\n          TestSuite.new(ObjectSpace::NAME)\n        end\n        \n        def test_basic_collection\n          assert_equal(full_suite(\"name\"), @c.collect(\"name\"))\n\n          @c.filter = []\n          assert_equal(full_suite(\"name\"), @c.collect(\"name\"))\n        end\n        \n        def test_filtered_collection\n          @c.filter = proc{false}\n          assert_equal(empty_suite, @c.collect)\n\n          @c.filter = proc{true}\n          assert_equal(full_suite, @c.collect)\n\n          @c.filter = proc{nil}\n          assert_equal(full_suite, @c.collect)\n\n          @c.filter = [proc{false}, proc{true}]\n          assert_equal(empty_suite, @c.collect)\n\n          @c.filter = [proc{true}, proc{false}]\n          assert_equal(full_suite, @c.collect)\n\n          @c.filter = [proc{nil}, proc{false}]\n          assert_equal(empty_suite, @c.collect)\n          \n          @c.filter = [proc{nil}, proc{true}]\n          assert_equal(full_suite, @c.collect)\n          \n          expected = TestSuite.new(ObjectSpace::NAME)\n          expected << (TestSuite.new(@tc1.name) << @tc1.new('test_1'))\n          expected << (TestSuite.new(@tc2.name) << @tc2.new('test_0'))\n          @c.filter = proc{|test| ['test_1', 'test_0'].include?(test.method_name)}\n          assert_equal(expected, @c.collect)\n\n          expected = TestSuite.new(ObjectSpace::NAME)\n          expected << (TestSuite.new(@tc1.name) << @tc1.new('test_1'))\n          expected << (TestSuite.new(@tc2.name) << @tc2.new('test_0'))\n          @c.filter = [proc{|t| t.method_name == 'test_1' ? true : nil}, proc{|t| t.method_name == 'test_0' ? true : nil}, proc{false}]\n          assert_equal(expected, @c.collect)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/runit/test_assert.rb",
    "content": "# Author:: Masaki Suketa.\n# Adapted by:: Nathaniel Talbott.\n# Copyright:: Copyright (c) Masaki Suketa. All rights reserved.\n# Copyright:: Copyright (c) 2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'rubyunit'\n\nmodule RUNIT\n  class TargetAssert\n    include RUNIT::Assert\n  end\n\n  class TestAssert < RUNIT::TestCase\n    def setup\n      @assert = TargetAssert.new\n      @e = nil\n    end\n\n    def test_assert\n      sub_test_assert_pass(true)\n      sub_test_assert_pass(TRUE)\n      sub_test_assert_failure(false)\n      sub_test_assert_failure(FALSE)\n      sub_test_assert_failure(nil)\n      sub_test_assert_pass(\"\")\n      sub_test_assert_pass(\"ok\")\n      sub_test_assert_pass(0)\n      sub_test_assert_pass(1)\n    end\n\n    def test_assert_with_2_argument\n      assert_no_exception {\n        assert(true, \"3\")\n      }\n      assert_no_exception {\n        assert(true)\n      }\n    end\n\n    def test_assert_equal_float_0_1\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(1.4, 1.35, 0.1)\n      }\n      sub_assert_pass(assert_proc)\n    end\n\n    def test_assert_equal_float_0_5\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(1.4, 1.34, 0.5)\n      }\n      sub_assert_pass(assert_proc)\n    end\n\n    def test_assert_equal_float_0\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(1.4, 1.4, 0)\n      }\n      sub_assert_pass(assert_proc)\n    end\n\n    def test_assert_equal_float_0_raise\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(1.4, 1.34, 0)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_equal_float_0_01\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(1.4, 1.35, 0.01)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_equal_float_0_001\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(Math.sqrt(2), 1.414, 0.001)\n      }\n      sub_assert_pass(assert_proc)\n    end\n\n    def test_assert_equal_float_minus_1_0\n      assert_proc = Proc.new {\n        @assert.assert_equal_float(1.4, 1.35, -1.0)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_fail\n      except = nil\n      begin\n        @assert.assert_fail(\"failure\")\n      rescue Exception\n        except = $!\n      end\n      assert_not_nil(except)\n    end\n\n    def sub_test_assert_pass(obj)\n      assert_proc = Proc.new {\n        @assert.assert(obj)\n      }\n      sub_assert_pass(assert_proc)\n    end\n\n    def sub_test_assert_failure(obj)\n      assert_proc = Proc.new {\n        @assert.assert(obj)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_equal\n      assert_proc = Proc.new {\n        @assert.assert_equal(2, 2)\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_equal(2, 3)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_nil\n      obj = nil\n      assert_proc = Proc.new {\n        @assert.assert_nil(obj)\n      }\n      sub_assert_pass(assert_proc)\n      obj = 'string'\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_not_nil\n      obj = 'string'\n      assert_proc = Proc.new {\n        @assert.assert_not_nil(obj)\n      }\n      sub_assert_pass(assert_proc)\n\n      obj = nil\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_operator\n      assert_proc = Proc.new {\n        @assert.assert_operator(2, :<, 3)\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_operator(2, :>, 3)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_respond_to\n      sub_test_assert_respond_to('string', 'sub', 'foo')\n      sub_test_assert_respond_to('string', :sub, :foo)\n    end\n\n    def sub_test_assert_respond_to(obj, msg, dummy_msg)\n      assert_proc = Proc.new {\n        @assert.assert_respond_to(msg, obj)\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_respond_to(dummy_msg, obj)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_send\n      assert_proc = Proc.new {\n        ary = []\n        @assert.assert_send ary, :empty?\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        ary = [2,3]\n        @assert.assert_send ary, :empty?\n      }\n      sub_assert_raise_fail(assert_proc)\n      assert_proc = Proc.new {\n        str = \"abc\"\n        @assert.assert_send str, :sub!, \"z\", \"y\"\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_kind_of\n      assert_proc = Proc.new {\n        @assert.assert_kind_of(String, \"string\")\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_kind_of(Regexp, \"string\")\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_instance_of\n      assert_proc = Proc.new {\n        @assert.assert_instance_of(String, \"string\")\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_instance_of(Object, \"string\")\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_match\n      assert_proc = Proc.new{\n        @assert.assert_match('foostring', /foo/)\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_match('barstring', /foo/)\n      }\n      sub_assert_raise_fail(assert_proc)\n      match = @assert.assert_match('foostring', /foo/)\n      assert_instance_of(MatchData, match)\n      assert_equal('foo', match[0])\n    end\n\n    def test_assert_matches\n      assert_proc = Proc.new{\n        @assert.assert_matches('foostring', /foo/)\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_matches('barstring', /foo/)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_not_match\n      assert_proc = Proc.new{\n        @assert.assert_not_match('barstring', /foo/)\n      }\n      sub_assert_pass(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_not_match('foostring', /foo/)\n      }\n      sub_assert_raise_fail(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_not_match('foobarbaz', /ba.+/)\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_same\n      flag = false\n      e = \"foo\"\n      a = e\n      assert_proc = Proc.new {@assert.assert_same(e, a)}\n      sub_assert_pass(assert_proc)\n\n      a = \"foo\"\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def test_assert_exception\n      assert_proc = Proc.new{\n        @assert.assert_exception(IOError) {\n    raise IOError\n        }\n      }\n      sub_assert_pass(assert_proc)\n\n      assert_proc = Proc.new{\n        @assert.assert_exception(StandardError) {\n    raise IOError\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n\n      assert_proc = Proc.new{\n        @assert.assert_exception(IOError, \"Exception\") {\n    raise StandardError\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n\n      assert_proc = Proc.new {\n        @assert.assert_exception(StandardError) {\n    \"No Exception raised in this block\"\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n\n      assert_proc = Proc.new {\n        @assert.assert_exception(StandardError) {\n    exit(33)\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n\n      t = @assert.assert_exception(IOError) {\n        raise IOError\n      }\n      assert_instance_of(IOError, t)\n      t = @assert.assert_exception(NameError) {\n        non_existent_method\n      }\n      assert_instance_of(NameError, t)\n      t = @assert.assert_exception(SystemExit) {\n        exit(33)\n      }\n      assert_instance_of(SystemExit, t)\n    end\n\n    def test_assert_no_exception\n      assert_proc = Proc.new{\n        @assert.assert_no_exception(IOError, ArgumentError) {\n    \"No Exception raised in this block\"\n        }\n      }\n      sub_assert_pass(assert_proc)\n\n      assert_proc = Proc.new{\n        @assert.assert_no_exception(IOError, ArgumentError) {\n    raise StandardError, \"Standard Error raised\"\n        }\n      }\n      sub_assert_raise_error(assert_proc)\n\n      assert_proc = Proc.new{\n        @assert.assert_no_exception(IOError, ArgumentError) {\n    raise ArgumentError, \"Bad Argument\"\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n\n      assert_proc = Proc.new{\n        @assert.assert_no_exception {\n          raise ArgumentError, \"Bad Argument\"\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n\n      assert_proc = Proc.new{\n        @assert.assert_no_exception {\n          raise NameError, \"Bad Name\"\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n      assert_proc = Proc.new {\n        @assert.assert_no_exception {\n    raise NoMemoryError\n        }\n      }\n      sub_assert_raise_fail(assert_proc)\n    end\n\n    def sub_assert_pass(p)\n      flag = false\n      err = nil\n      begin\n        p.call\n        flag = true\n      rescue\n        err = $!\n        flag = false\n      end\n      assert(flag, err.to_s)\n    end\n\n    def sub_assert_raise_fail(p)\n      flag = false\n      err = nil\n      begin\n        p.call\n        flag = false\n      rescue RUNIT::AssertionFailedError\n        flag = true\n        err = $!\n      rescue Exception\n        flag = false\n        err = $!\n      end\n      assert(flag, err.to_s)\n    end\n      \n    def sub_assert_raise_error(p)\n      flag = false\n      err = nil\n      begin\n        p.call\n        flag = false\n      rescue RUNIT::AssertionFailedError\n        flag = false\n        err = $!\n      rescue Exception\n        flag = true\n        err = $!\n      end\n      assert(flag, err.to_s)\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/runit/test_testcase.rb",
    "content": "# Author:: Masaki Suketa.\n# Adapted by:: Nathaniel Talbott.\n# Copyright:: Copyright (c) Masaki Suketa. All rights reserved.\n# Copyright:: Copyright (c) 2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'rubyunit'\n\nmodule RUNIT\n  class DummyError < StandardError\n  end\n\n  class TestTestCase < RUNIT::TestCase\n    def setup\n      @dummy_testcase = Class.new(RUNIT::TestCase) do\n        def self.name\n          \"DummyTestCase\"\n        end\n        \n        attr_reader :status, :dummy_called, :dummy2_called\n\n        def initialize(*arg)\n          super(*arg)\n          @status = 0\n          @dummy_called = false\n          @dummy2_called = false\n        end\n\n        def setup\n          @status = 1 if @status == 0\n        end\n\n        def test_dummy\n          @status = 2 if @status == 1\n          @dummy_called = true\n        end\n\n        def test_dummy2\n          @status = 2 if @status == 1\n          @dummy2_called = true\n          raise DummyError\n        end\n\n        def teardown\n          @status = 3 if @status == 2\n        end\n      end\n\n      @test1 = @dummy_testcase.new('test_dummy')\n      @test2 = @dummy_testcase.new('test_dummy2', 'TestCase')\n    end\n\n    def test_name\n      assert_equal('DummyTestCase#test_dummy', @test1.name) # The second parameter to #initialize is ignored in emulation\n      assert_equal('DummyTestCase#test_dummy2', @test2.name)\n    end\n\n    def test_run\n      result = RUNIT::TestResult.new\n      @test1.run(result)\n      assert_equal(1, result.run_count)\n    end\n\n    def test_s_suite\n      suite = @dummy_testcase.suite\n      assert_instance_of(RUNIT::TestSuite, suite)\n      assert_equal(2, suite.count_test_cases)\n    end\n\n    def test_teardown_err\n      suite = Class.new(RUNIT::TestCase) do\n        def test_foo\n          assert(false)\n        end\n        \n        def test_bar\n          assert(true)\n        end\n        \n        def teardown\n          raise StandardError\n        end\n      end.suite\n\n      result = RUNIT::TestResult.new\n      suite.run(result)\n      assert_equal(2, result.error_size)\n      assert_equal(1, result.failure_size)\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/runit/test_testresult.rb",
    "content": "# Author:: Masaki Suketa.\n# Adapted by:: Nathaniel Talbott.\n# Copyright:: Copyright (c) Masaki Suketa. All rights reserved.\n# Copyright:: Copyright (c) 2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'rubyunit'\n\nmodule RUNIT\n  class TestTestResult < RUNIT::TestCase\n    def setup\n      @result = RUNIT::TestResult.new\n      \n      @normal_suite = Class::new(RUNIT::TestCase) do\n        def test_1\n          assert(true)\n          assert(true)\n        end\n      end.suite\n      \n      @failure_suite = Class::new(RUNIT::TestCase) do\n        def test_1\n          assert(true)\n          assert(false)\n        end\n      end.suite\n      \n      @error_suite = Class::new(RUNIT::TestCase) do\n        def setup\n          raise ScriptError\n        end\n        def test_1\n          assert(true)\n        end\n      end.suite\n      \n      @multi_failure_suite = Class::new(RUNIT::TestCase) do\n        def test1\n          assert(false)\n        end\n        def test2\n          assert(false)\n        end\n        def test3\n          assert(false)\n        end\n      end.suite\n      \n      @with_error_suite = Class::new(RUNIT::TestCase) do\n        def test1\n          raise StandardError\n        end\n      end.suite\n      \n      @multi_error_suite = Class::new(RUNIT::TestCase) do\n        def test1\n          raise StandardError\n        end\n        def test2\n          raise StandardError\n        end\n        def test3\n          raise StandardError\n        end\n      end.suite\n      \n      @multi_suite = Class::new(RUNIT::TestCase) do\n        def test_1\n          assert(true)\n          assert(true)\n        end\n        def test_2\n          assert(true)\n        end\n        def test_3\n          assert(true)\n          assert(false)\n          assert(true)\n        end\n      end.suite\n    end\n\n    def test_error_size\n      @normal_suite.run(@result)\n      assert_equal(0, @result.error_size)\n      @with_error_suite.run(@result)\n      assert_equal(1, @result.error_size)\n      @multi_error_suite.run(@result)\n      assert_equal(4, @result.error_size)\n    end\n\n    def test_errors\n      @normal_suite.run(@result)\n      assert_equal(0, @result.errors.size)\n    end\n\n    def test_failure_size\n      @normal_suite.run(@result)\n      assert_equal(0, @result.failure_size)\n      @failure_suite.run(@result)\n      assert_equal(1, @result.failure_size)\n      @multi_failure_suite.run(@result)\n      assert_equal(4, @result.failure_size)\n    end\n\n    def test_failures\n      @normal_suite.run(@result)\n      assert_equal(0, @result.failures.size)\n      @failure_suite.run(@result)\n      assert_equal(1, @result.failures.size)\n      @multi_failure_suite.run(@result)\n      assert_equal(4, @result.failures.size)\n    end\n\n    def test_run_no_exception\n      assert_no_exception {\n        @error_suite.run(@result)\n      }\n    end\n\n    def test_run_asserts\n      @normal_suite.run(@result)\n      assert_equal(2, @result.run_asserts)\n    end\n\n    def test_run_asserts2\n      @failure_suite.run(@result)\n      assert_equal(2, @result.run_asserts)\n    end\n\n    def test_run_tests\n      assert_equal(0, @result.run_tests)\n      @normal_suite.run(@result)\n      assert_equal(1, @result.run_tests)\n      @multi_suite.run(@result) \n      assert_equal(4, @result.run_tests)\n    end\n\n    def test_succeed?\n      @normal_suite.run(@result)\n      assert(@result.succeed?)\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/runit/test_testsuite.rb",
    "content": "# Author:: Masaki Suketa.\n# Adapted by:: Nathaniel Talbott.\n# Copyright:: Copyright (c) Masaki Suketa. All rights reserved.\n# Copyright:: Copyright (c) 2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'rubyunit'\n\nmodule RUNIT\n  class TestTestSuite < RUNIT::TestCase\n    def setup\n      @testsuite = RUNIT::TestSuite.new\n      @dummy_test = Class.new(RUNIT::TestCase) do\n        def test_foo\n        end\n        def test_bar\n        end\n      end\n      @dummy_empty_test = Class.new(RUNIT::TestCase){}\n    end\n\n    def test_count_test_cases\n      assert_equal(0, @testsuite.count_test_cases)\n\n      @testsuite.add(@dummy_empty_test.suite)\n      assert_equal(0, @testsuite.count_test_cases)\n\n      @testsuite.add(@dummy_test.suite)\n      assert_equal(2, @testsuite.count_test_cases)\n\n      @testsuite.add(@dummy_test.suite)\n      assert_equal(4, @testsuite.count_test_cases)\n\n      dummytest_foo = @dummy_test.new('test_foo')\n      @testsuite.add(dummytest_foo)\n      assert_equal(5, @testsuite.count_test_cases)\n    end\n\n    def test_add\n      @testsuite.add(@dummy_empty_test.suite)\n      assert_equal(0, @testsuite.size)\n      assert_equal(0, @testsuite.count_test_cases)\n\n      @testsuite.add(@dummy_test.suite)\n      assert_equal(2, @testsuite.size)\n      assert_equal(2, @testsuite.count_test_cases)\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/test_assertions.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\n\nmodule Test\n  module Unit\n    class TC_Assertions < TestCase\n      def check(value, message=\"\")\n        add_assertion\n        if (!value)\n          raise AssertionFailedError.new(message)\n        end\n      end\n\n      def check_assertions(expect_fail, expected_message=\"\", return_value_expected=false)\n        @actual_assertion_count = 0\n        failed = true\n        actual_message = nil\n        @catch_assertions = true\n        return_value = nil\n        begin\n          return_value = yield\n          failed = false\n        rescue AssertionFailedError => error\n          actual_message = error.message\n        end\n        @catch_assertions = false\n        check(expect_fail == failed, (expect_fail ? \"Should have failed, but didn't\" : \"Should not have failed, but did with message\\n<#{actual_message}>\"))\n        check(1 == @actual_assertion_count, \"Should have made one assertion but made <#{@actual_assertion_count}>\")\n        if (expect_fail)\n          case expected_message\n            when String\n              check(actual_message == expected_message, \"Should have the correct message.\\n<#{expected_message.inspect}> expected but was\\n<#{actual_message.inspect}>\")\n            when Regexp\n              check(actual_message =~ expected_message, \"The message should match correctly.\\n</#{expected_message.source}/> expected to match\\n<#{actual_message.inspect}>\")\n            else\n              check(false, \"Incorrect expected message type in assert_nothing_failed\")\n          end\n        else\n          if (!return_value_expected)\n            check(return_value.nil?, \"Should not return a value but returned <#{return_value}>\")\n          else\n            check(!return_value.nil?, \"Should return a value\")\n          end\n        end\n        return return_value\n      end\n      \n      def check_nothing_fails(return_value_expected=false, &proc)\n        check_assertions(false, \"\", return_value_expected, &proc)\n      end\n      \n      def check_fails(expected_message=\"\", &proc)\n        check_assertions(true, expected_message, &proc)\n      end\n      \n      def test_assert_block\n        check_nothing_fails {\n          assert_block {true}\n        }\n        check_nothing_fails {\n          assert_block(\"successful assert_block\") {true}\n        }\n        check_nothing_fails {\n          assert_block(\"successful assert_block\") {true}\n        }\n        check_fails(\"assert_block failed.\") {\n          assert_block {false}\n        }\n        check_fails(\"failed assert_block\") {\n          assert_block(\"failed assert_block\") {false}\n        }\n      end\n      \n      def test_assert\n        check_nothing_fails{assert(\"a\")}\n        check_nothing_fails{assert(true)}\n        check_nothing_fails{assert(true, \"successful assert\")}\n        check_fails(\"<nil> is not true.\"){assert(nil)}\n        check_fails(\"<false> is not true.\"){assert(false)}\n        check_fails(\"failed assert.\\n<false> is not true.\"){assert(false, \"failed assert\")}\n      end\n      \n      def test_assert_equal\n        check_nothing_fails {\n          assert_equal(\"string1\", \"string1\")\n        }\n        check_nothing_fails {\n          assert_equal( \"string1\", \"string1\", \"successful assert_equal\")\n        }\n        check_nothing_fails {\n          assert_equal(\"string1\", \"string1\", \"successful assert_equal\")\n        }\n        check_fails(%Q{<\"string1\"> expected but was\\n<\"string2\">.}) {\n          assert_equal(\"string1\", \"string2\")\n        }\n        check_fails(%Q{failed assert_equal.\\n<\"string1\"> expected but was\\n<\"string2\">.}) {\n          assert_equal(\"string1\", \"string2\", \"failed assert_equal\")\n        }\n        check_fails(%Q{<\"1\"> expected but was\\n<1>.}) do\n          assert_equal(\"1\", 1)\n        end\n      end\n      \n      def test_assert_raise\n        return_value = nil\n        check_nothing_fails(true) {\n          return_value = assert_raise(RuntimeError) {\n            raise \"Error\"\n          }\n        }\n        check(return_value.kind_of?(Exception), \"Should have returned the exception from a successful assert_raise\")\n        check(return_value.message == \"Error\", \"Should have returned the correct exception from a successful assert_raise\")\n        check_nothing_fails(true) {\n          assert_raise(ArgumentError, \"successful assert_raise\") {\n            raise ArgumentError.new(\"Error\")\n          }\n        }\n        check_nothing_fails(true) {\n          assert_raise(RuntimeError) {\n            raise \"Error\"\n          }\n        }\n        check_nothing_fails(true) {\n          assert_raise(RuntimeError, \"successful assert_raise\") {\n            raise \"Error\"\n          }\n        }\n        check_fails(\"<RuntimeError> exception expected but none was thrown.\") {\n          assert_raise(RuntimeError) {\n            1 + 1\n          }\n        }\n        check_fails(%r{\\Afailed assert_raise.\\n<ArgumentError> exception expected but was\\nClass: <RuntimeError>\\nMessage: <\"Error\">\\n---Backtrace---\\n.+\\n---------------\\Z}m) {\n          assert_raise(ArgumentError, \"failed assert_raise\") {\n            raise \"Error\"\n          }\n        }\n        check_fails(\"Should expect a class of exception, Object.\\n<false> is not true.\") {\n          assert_nothing_raised(Object) {\n            1 + 1\n          }\n        }\n\n        exceptions = [ArgumentError, TypeError]\n        modules = [Math, Comparable]\n        rescues = exceptions + modules\n        exceptions.each do |exc|\n          check_nothing_fails(true) {\n            return_value = assert_raise(*rescues) {\n              raise exc, \"Error\"\n            }\n          }\n          check(return_value.instance_of?(exc), \"Should have returned #{exc} but was #{return_value.class}\")\n          check(return_value.message == \"Error\", \"Should have returned the correct exception from a successful assert_raise\")\n        end\n        modules.each do |mod|\n          check_nothing_fails(true) {\n            return_value = assert_raise(*rescues) {\n              raise Exception.new(\"Error\").extend(mod)\n            }\n          }\n          check(mod === return_value, \"Should have returned #{mod}\")\n          check(return_value.message == \"Error\", \"Should have returned the correct exception from a successful assert_raise\")\n        end\n        check_fails(\"<[ArgumentError, TypeError, Math, Comparable]> exception expected but none was thrown.\") {\n          assert_raise(*rescues) {\n            1 + 1\n          }\n        }\n        check_fails(%r{\\Afailed assert_raise.\n<\\[ArgumentError, TypeError\\]> exception expected but was\nClass: <RuntimeError>\nMessage: <\"Error\">\n---Backtrace---\n.+\n---------------\\Z}m) {\n          assert_raise(ArgumentError, TypeError, \"failed assert_raise\") {\n            raise \"Error\"\n          }\n        }\n      end\n      \n      def test_assert_instance_of\n        check_nothing_fails {\n          assert_instance_of(String, \"string\")\n        }\n        check_nothing_fails {\n          assert_instance_of(String, \"string\", \"successful assert_instance_of\")\n        }\n        check_nothing_fails {\n          assert_instance_of(String, \"string\", \"successful assert_instance_of\")\n        }\n        check_fails(%Q{<\"string\"> expected to be an instance of\\n<Hash> but was\\n<String>.}) {\n          assert_instance_of(Hash, \"string\")\n        }\n        check_fails(%Q{failed assert_instance_of.\\n<\"string\"> expected to be an instance of\\n<Hash> but was\\n<String>.}) {\n          assert_instance_of(Hash, \"string\", \"failed assert_instance_of\")\n        }\n      end\n      \n      def test_assert_nil\n        check_nothing_fails {\n          assert_nil(nil)\n        }\n        check_nothing_fails {\n          assert_nil(nil, \"successful assert_nil\")\n        }\n        check_nothing_fails {\n          assert_nil(nil, \"successful assert_nil\")\n        }\n        check_fails(%Q{<nil> expected but was\\n<\"string\">.}) {\n          assert_nil(\"string\")\n        }\n        check_fails(%Q{failed assert_nil.\\n<nil> expected but was\\n<\"string\">.}) {\n          assert_nil(\"string\", \"failed assert_nil\")\n        }\n      end\n      \n      def test_assert_not_nil\n        check_nothing_fails{assert_not_nil(false)}\n        check_nothing_fails{assert_not_nil(false, \"message\")}\n        check_fails(\"<nil> expected to not be nil.\"){assert_not_nil(nil)}\n        check_fails(\"message.\\n<nil> expected to not be nil.\") {assert_not_nil(nil, \"message\")}\n      end\n        \n      def test_assert_kind_of\n        check_nothing_fails {\n          assert_kind_of(Module, Array)\n        }\n        check_nothing_fails {\n          assert_kind_of(Object, \"string\", \"successful assert_kind_of\")\n        }\n        check_nothing_fails {\n          assert_kind_of(Object, \"string\", \"successful assert_kind_of\")\n        }\n        check_nothing_fails {\n          assert_kind_of(Comparable, 1)\n        }\n        check_fails(%Q{<\"string\">\\nexpected to be kind_of?\\n<Class> but was\\n<String>.}) {\n          assert_kind_of(Class, \"string\")\n        }\n        check_fails(%Q{failed assert_kind_of.\\n<\"string\">\\nexpected to be kind_of?\\n<Class> but was\\n<String>.}) {\n          assert_kind_of(Class, \"string\", \"failed assert_kind_of\")\n        }\n      end\n      \n      def test_assert_match\n        check_nothing_fails {\n          assert_match(/strin./, \"string\")\n        }\n        check_nothing_fails {\n          assert_match(\"strin\", \"string\")\n        }\n        check_nothing_fails {\n          assert_match(/strin./, \"string\", \"successful assert_match\")\n        }\n        check_nothing_fails {\n          assert_match(/strin./, \"string\", \"successful assert_match\")\n        }\n        check_fails(%Q{<\"string\"> expected to be =~\\n</slin./>.}) {\n          assert_match(/slin./, \"string\")\n        }\n        check_fails(%Q{<\"string\"> expected to be =~\\n</strin\\\\./>.}) {\n          assert_match(\"strin.\", \"string\")\n        }\n        check_fails(%Q{failed assert_match.\\n<\"string\"> expected to be =~\\n</slin./>.}) {\n          assert_match(/slin./, \"string\", \"failed assert_match\")\n        }\n      end\n      \n      def test_assert_same\n        thing = \"thing\"\n        check_nothing_fails {\n          assert_same(thing, thing)\n        }\n        check_nothing_fails {\n          assert_same(thing, thing, \"successful assert_same\")\n        }\n        check_nothing_fails {\n          assert_same(thing, thing, \"successful assert_same\")\n        }\n        thing2 = \"thing\"\n        check_fails(%Q{<\"thing\">\\nwith id <#{thing.__id__}> expected to be equal? to\\n<\"thing\">\\nwith id <#{thing2.__id__}>.}) {\n          assert_same(thing, thing2)\n        }\n        check_fails(%Q{failed assert_same.\\n<\"thing\">\\nwith id <#{thing.__id__}> expected to be equal? to\\n<\"thing\">\\nwith id <#{thing2.__id__}>.}) {\n          assert_same(thing, thing2, \"failed assert_same\")\n        }\n      end\n      \n      def test_assert_nothing_raised\n        check_nothing_fails {\n          assert_nothing_raised {\n            1 + 1\n          }\n        }\n        check_nothing_fails {\n          assert_nothing_raised(\"successful assert_nothing_raised\") {\n            1 + 1\n          }\n        }\n        check_nothing_fails {\n          assert_nothing_raised(\"successful assert_nothing_raised\") {\n            1 + 1\n          }\n        }\n        check_nothing_fails {\n          begin\n            assert_nothing_raised(RuntimeError, StandardError, Comparable, \"successful assert_nothing_raised\") {\n              raise ZeroDivisionError.new(\"ArgumentError\")\n            }\n          rescue ZeroDivisionError\n          end\n        }\n        check_fails(\"Should expect a class of exception, Object.\\n<false> is not true.\") {\n          assert_nothing_raised(Object) {\n            1 + 1\n          }\n        }\n        check_fails(%r{\\AException raised:\\nClass: <RuntimeError>\\nMessage: <\"Error\">\\n---Backtrace---\\n.+\\n---------------\\Z}m) {\n          assert_nothing_raised {\n            raise \"Error\"\n          }\n        }\n        check_fails(%r{\\Afailed assert_nothing_raised\\.\\nException raised:\\nClass: <RuntimeError>\\nMessage: <\"Error\">\\n---Backtrace---\\n.+\\n---------------\\Z}m) {\n          assert_nothing_raised(\"failed assert_nothing_raised\") {\n            raise \"Error\"\n          }\n        }\n        check_fails(%r{\\AException raised:\\nClass: <RuntimeError>\\nMessage: <\"Error\">\\n---Backtrace---\\n.+\\n---------------\\Z}m) {\n          assert_nothing_raised(StandardError, RuntimeError) {\n            raise \"Error\"\n          }\n        }\n        check_fails(\"Failure.\") do\n          assert_nothing_raised do\n            flunk(\"Failure\")\n          end\n        end\n      end\n      \n      def test_flunk\n        check_fails(\"Flunked.\") {\n          flunk\n        }\n        check_fails(\"flunk message.\") {\n          flunk(\"flunk message\")\n        }\n      end\n      \n      def test_assert_not_same\n        thing = \"thing\"\n        thing2 = \"thing\"\n        check_nothing_fails {\n          assert_not_same(thing, thing2)\n        }\n        check_nothing_fails {\n          assert_not_same(thing, thing2, \"message\")\n        }\n        check_fails(%Q{<\"thing\">\\nwith id <#{thing.__id__}> expected to not be equal? to\\n<\"thing\">\\nwith id <#{thing.__id__}>.}) {\n          assert_not_same(thing, thing)\n        }\n        check_fails(%Q{message.\\n<\"thing\">\\nwith id <#{thing.__id__}> expected to not be equal? to\\n<\"thing\">\\nwith id <#{thing.__id__}>.}) {\n          assert_not_same(thing, thing, \"message\")\n        }\n      end\n      \n      def test_assert_not_equal\n        check_nothing_fails {\n          assert_not_equal(\"string1\", \"string2\")\n        }\n        check_nothing_fails {\n          assert_not_equal(\"string1\", \"string2\", \"message\")\n        }\n        check_fails(%Q{<\"string\"> expected to be != to\\n<\"string\">.}) {\n          assert_not_equal(\"string\", \"string\")\n        }\n        check_fails(%Q{message.\\n<\"string\"> expected to be != to\\n<\"string\">.}) {\n          assert_not_equal(\"string\", \"string\", \"message\")\n        }\n      end\n      \n      def test_assert_no_match\n        check_nothing_fails{assert_no_match(/sling/, \"string\")}\n        check_nothing_fails{assert_no_match(/sling/, \"string\", \"message\")}\n        check_fails(%Q{The first argument to assert_no_match should be a Regexp.\\n<\"asdf\"> expected to be an instance of\\n<Regexp> but was\\n<String>.}) do\n          assert_no_match(\"asdf\", \"asdf\")\n        end\n        check_fails(%Q{</string/> expected to not match\\n<\"string\">.}) do\n          assert_no_match(/string/, \"string\")\n        end\n        check_fails(%Q{message.\\n</string/> expected to not match\\n<\"string\">.}) do\n          assert_no_match(/string/, \"string\", \"message\")\n        end\n      end\n      \n      def test_assert_throws\n        check_nothing_fails {\n          assert_throws(:thing, \"message\") {\n            throw :thing\n          }\n        }\n        check_fails(\"message.\\n<:thing> expected to be thrown but\\n<:thing2> was thrown.\") {\n          assert_throws(:thing, \"message\") {\n            throw :thing2\n          }\n        }\n        check_fails(\"message.\\n<:thing> should have been thrown.\") {\n          assert_throws(:thing, \"message\") {\n            1 + 1\n          }\n        }\n      end\n      \n      def test_assert_nothing_thrown\n        check_nothing_fails {\n          assert_nothing_thrown(\"message\") {\n            1 + 1\n          }\n        }\n        check_fails(\"message.\\n<:thing> was thrown when nothing was expected.\") {\n          assert_nothing_thrown(\"message\") {\n            throw :thing\n          }\n        }\n      end\n      \n      def test_assert_operator\n        check_nothing_fails {\n          assert_operator(\"thing\", :==, \"thing\", \"message\")\n        }\n        check_fails(%Q{<0.15>\\ngiven as the operator for #assert_operator must be a Symbol or #respond_to?(:to_str).}) do\n          assert_operator(\"thing\", 0.15, \"thing\")\n        end\n        check_fails(%Q{message.\\n<\"thing1\"> expected to be\\n==\\n<\"thing2\">.}) {\n          assert_operator(\"thing1\", :==, \"thing2\", \"message\")\n        }\n      end\n      \n      def test_assert_respond_to\n        check_nothing_fails {\n          assert_respond_to(\"thing\", :to_s, \"message\")\n        }\n        check_nothing_fails {\n          assert_respond_to(\"thing\", \"to_s\", \"message\")\n        }\n        check_fails(\"<0.15>\\ngiven as the method name argument to #assert_respond_to must be a Symbol or #respond_to?(:to_str).\") {\n          assert_respond_to(\"thing\", 0.15)\n        }\n        check_fails(\"message.\\n<:symbol>\\nof type <Symbol>\\nexpected to respond_to?<:non_existent>.\") {\n          assert_respond_to(:symbol, :non_existent, \"message\")\n        }\n      end\n      \n      def test_assert_in_delta\n        check_nothing_fails {\n          assert_in_delta(1.4, 1.4, 0)\n        }\n        check_nothing_fails {\n          assert_in_delta(0.5, 0.4, 0.1, \"message\")\n        }\n        check_nothing_fails {\n          float_thing = Object.new\n          def float_thing.to_f\n            0.2\n          end\n          assert_in_delta(0.1, float_thing, 0.1)\n        }\n        check_fails(\"message.\\n<0.5> and\\n<0.4> expected to be within\\n<0.05> of each other.\") {\n          assert_in_delta(0.5, 0.4, 0.05, \"message\")\n        }\n        check_fails(%r{The arguments must respond to to_f; the first float did not\\.\\n<.+>\\nof type <Object>\\nexpected to respond_to\\?<:to_f>.}) {\n          assert_in_delta(Object.new, 0.4, 0.1)\n        }\n        check_fails(\"The delta should not be negative.\\n<-0.1> expected to be\\n>=\\n<0.0>.\") {\n          assert_in_delta(0.5, 0.4, -0.1, \"message\")\n        }\n      end\n      \n      def test_assert_send\n        object = Object.new\n        class << object\n          private\n          def return_argument(argument, bogus)\n            return argument\n          end\n        end\n        check_nothing_fails {\n          assert_send([object, :return_argument, true, \"bogus\"], \"message\")\n        }\n        check_fails(%r{\\Amessage\\.\\n<.+> expected to respond to\\n<return_argument\\(\\[false, \"bogus\"\\]\\)> with a true value.\\Z}) {\n          assert_send([object, :return_argument, false, \"bogus\"], \"message\")\n        }\n      end\n      \n      def test_condition_invariant\n        object = Object.new\n        def object.inspect\n          @changed = true\n        end\n        def object.==(other)\n          @changed ||= false\n          return (!@changed)\n        end\n        check_nothing_fails {\n          assert_equal(object, object, \"message\")\n        }\n      end\n  \n      def add_failure(message, location=caller)\n        if (!@catch_assertions)\n          super\n        end\n      end\n      \n      def add_assertion\n        if (!@catch_assertions)\n          super\n        else\n          @actual_assertion_count += 1\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/test_error.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\n\nmodule Test\n  module Unit\n    class TC_Error < TestCase\n      TF_Exception = Struct.new('TF_Exception', :message, :backtrace)\n      def test_display\n        ex = TF_Exception.new(\"message1\\nmessage2\", ['line1', 'line2'])\n        e = Error.new(\"name\", ex)\n        assert_equal(\"name: #{TF_Exception.name}: message1\", e.short_display)\n        assert_equal(<<EOM.strip, e.long_display)\nError:\nname:\nStruct::TF_Exception: message1\nmessage2\n    line1\n    line2\nEOM\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/test_failure.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'test/unit/failure'\n\nmodule Test::Unit\n  class TestFailure < TestCase\n    def test_display\n      f = Failure.new(\"name\", [%q{location:1 in 'l'}], \"message1\\nmessage2\")\n      assert_equal(\"name: message1\", f.short_display)\n      assert_equal(<<EOM.strip, f.long_display)\nFailure:\nname [location:1]:\nmessage1\nmessage2\nEOM\n\n      f = Failure.new(\"name\", [%q{location1:2 in 'l1'}, 'location2:1', %q{location3:3 in 'l3'}], \"message1\\nmessage2\")\n      assert_equal(\"name: message1\", f.short_display)\n      assert_equal(<<EOM.strip, f.long_display)\nFailure:\nname\n    [location1:2 in 'l1'\n     location2:1\n     location3:3 in 'l3']:\nmessage1\nmessage2\nEOM\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/test_testcase.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\n\nmodule Test\n  module Unit\n    class TC_TestCase < TestCase\n      def test_creation\n        tc = Class.new(TestCase) do\n          def test_with_arguments(arg1, arg2)\n          end\n        end\n      \n        caught = true\n        catch(:invalid_test) do\n          tc.new(:test_with_arguments)\n          caught = false\n        end\n        check(\"Should have caught an invalid test when there are arguments\", caught)\n        \n        caught = true\n        catch(:invalid_test) do\n          tc.new(:non_existent_test)\n          caught = false\n        end\n        check(\"Should have caught an invalid test when the method does not exist\", caught)\n      end\n      \n      def setup\n        @tc_failure_error = Class.new(TestCase) do\n          def test_failure\n            assert_block(\"failure\") { false }\n          end\n          def test_error\n            1 / 0\n          end\n          def test_nested_failure\n            nested\n          end\n          def nested\n            assert_block(\"nested\"){false}\n          end\n          def return_passed?\n            return passed?\n          end\n        end\n\n        def @tc_failure_error.name\n          \"TC_FailureError\"\n        end\n      end\n \n      def test_add_failed_assertion\n        test_case = @tc_failure_error.new(:test_failure)\n        check(\"passed? should start out true\", test_case.return_passed?)\n        result = TestResult.new\n        called = false\n        result.add_listener(TestResult::FAULT) {\n          | fault |\n          check(\"Should have a Failure\", fault.instance_of?(Failure))\n          check(\"The Failure should have the correct message\", \"failure\" == fault.message)\n          check(\"The Failure should have the correct test_name (was <#{fault.test_name}>)\", fault.test_name == \"test_failure(TC_FailureError)\")\n          r = /\\A.*#{Regexp.escape(File.basename(__FILE__))}:\\d+:in `test_failure'\\Z/\n\n          location = fault.location\n          check(\"The location should be an array\", location.kind_of?(Array))\n          check(\"The location should have two lines (was: <#{location.inspect}>)\", location.size == 2)\n          check(\"The Failure should have the correct location (was <#{location[0].inspect}>, expected <#{r.inspect}>)\", r =~ location[0])\n          called = true\n        }\n        progress = []\n        test_case.run(result) { |*arguments| progress << arguments }\n        check(\"The failure should have triggered the listener\", called)\n        check(\"The failure should have set passed?\", !test_case.return_passed?)\n        check(\"The progress block should have been updated correctly\", [[TestCase::STARTED, test_case.name], [TestCase::FINISHED, test_case.name]] == progress)\n      end\n\n      def test_add_failure_nested\n        test_case = @tc_failure_error.new(:test_nested_failure)\n        check(\"passed? should start out true\", test_case.return_passed?)\n\n        result = TestResult.new\n        called = false\n        result.add_listener(TestResult::FAULT) {\n          | fault |\n          check(\"Should have a Failure\", fault.instance_of?(Failure))\n          check(\"The Failure should have the correct message\", \"nested\" == fault.message)\n          check(\"The Failure should have the correct test_name (was <#{fault.test_name}>)\", fault.test_name == \"test_nested_failure(TC_FailureError)\")\n          r = \n\n          location = fault.location\n          check(\"The location should be an array\", location.kind_of?(Array))\n          check(\"The location should have the correct number of lines (was: <#{location.inspect}>)\", location.size == 3)\n          check(\"The Failure should have the correct location (was <#{location[0].inspect}>)\", /\\A.*#{Regexp.escape(File.basename(__FILE__))}:\\d+:in `nested'\\Z/ =~ location[0])\n          check(\"The Failure should have the correct location (was <#{location[1].inspect}>)\", /\\A.*#{Regexp.escape(File.basename(__FILE__))}:\\d+:in `test_nested_failure'\\Z/ =~ location[1])\n          called = true\n        }\n        test_case.run(result){}\n        check(\"The failure should have triggered the listener\", called)\n      end\n      \n      def test_add_error\n        test_case = @tc_failure_error.new(:test_error)\n        check(\"passed? should start out true\", test_case.return_passed?)\n        result = TestResult.new\n        called = false\n        result.add_listener(TestResult::FAULT) {\n          | fault |\n          check(\"Should have a TestError\", fault.instance_of?(Error))\n          check(\"The Error should have the correct message\", \"ZeroDivisionError: divided by 0\" == fault.message)\n          check(\"The Error should have the correct test_name\", \"test_error(TC_FailureError)\" == fault.test_name)\n          check(\"The Error should have the correct exception\", fault.exception.instance_of?(ZeroDivisionError))\n          called = true\n        }\n        test_case.run(result) {}\n        check(\"The error should have triggered the listener\", called)\n        check(\"The error should have set passed?\", !test_case.return_passed?)\n      end\n\n      def test_no_tests      \n        suite = TestCase.suite\n        check(\"Should have a test suite\", suite.instance_of?(TestSuite))\n        check(\"Should have one test\", suite.size == 1)\n        check(\"Should have the default test\", suite.tests.first.name == \"default_test(Test::Unit::TestCase)\")\n        \n        result = TestResult.new\n        suite.run(result) {}\n        check(\"Should have had one test run\", result.run_count == 1)\n        check(\"Should have had one test failure\", result.failure_count == 1)\n        check(\"Should have had no errors\", result.error_count == 0)\n      end\n\n      def test_suite\n        tc = Class.new(TestCase) do\n          def test_succeed\n            assert_block {true}\n          end\n          def test_fail\n            assert_block {false}\n          end\n          def test_error\n            1/0\n          end\n          def dont_run\n            assert_block {true}\n          end\n          def test_dont_run(argument)\n            assert_block {true}\n          end\n          def test\n            assert_block {true}\n          end\n        end\n      \n        suite = tc.suite\n        check(\"Should have a test suite\", suite.instance_of?(TestSuite))\n        check(\"Should have three tests\", suite.size == 3)\n  \n        result = TestResult.new\n        suite.run(result) {}\n        check(\"Should have had three test runs\", result.run_count == 3)\n        check(\"Should have had one test failure\", result.failure_count == 1)\n        check(\"Should have had one test error\", result.error_count == 1)\n      end\n      \n     \n      def test_setup_teardown\n        tc = Class.new(TestCase) do\n          attr_reader(:setup_called, :teardown_called)\n          def initialize(test)\n            super(test)\n            @setup_called = false\n            @teardown_called = false\n          end\n          def setup\n            @setup_called = true\n          end\n          def teardown\n            @teardown_called = true\n          end\n          def test_succeed\n            assert_block {true}\n          end\n          def test_fail\n            assert_block {false}\n          end\n          def test_error\n            raise \"Error!\"\n          end\n        end\n        result = TestResult.new\n  \n        test = tc.new(:test_succeed)\n        test.run(result) {}\n        check(\"Should have called setup the correct number of times\", test.setup_called)\n        check(\"Should have called teardown the correct number of times\", test.teardown_called)\n  \n        test = tc.new(:test_fail)\n        test.run(result) {}\n        check(\"Should have called setup the correct number of times\", test.setup_called)\n        check(\"Should have called teardown the correct number of times\", test.teardown_called)\n  \n        test = tc.new(:test_error)\n        test.run(result) {}\n        check(\"Should have called setup the correct number of times\", test.setup_called)\n        check(\"Should have called teardown the correct number of times\", test.teardown_called)\n  \n        check(\"Should have had two test runs\", result.run_count == 3)\n        check(\"Should have had a test failure\", result.failure_count == 1)\n        check(\"Should have had a test error\", result.error_count == 1)\n      end\n      \n      def test_assertion_failed_not_called\n        tc = Class.new(TestCase) do\n          def test_thing\n            raise AssertionFailedError.new\n          end\n        end\n        \n        suite = tc.suite\n        check(\"Should have one test\", suite.size == 1)\n        result = TestResult.new\n        suite.run(result) {}\n        check(\"Should have had one test run\", result.run_count == 1)\n        check(\"Should have had one assertion failure\", result.failure_count == 1)\n        check(\"Should not have any assertion errors but had #{result.error_count}\", result.error_count == 0)\n      end\n      \n      def test_equality\n        tc1 = Class.new(TestCase) do\n          def test_1\n          end\n          def test_2\n          end\n        end\n        \n        tc2 = Class.new(TestCase) do\n          def test_1\n          end\n        end\n      \n        test1 = tc1.new('test_1')\n        test2 = tc1.new('test_1')\n        check(\"Should be equal\", test1 == test2)\n        check(\"Should be equal\", test2 == test1)\n        \n        test1 = tc1.new('test_2')\n        check(\"Should not be equal\", test1 != test2)\n        check(\"Should not be equal\", test2 != test1)\n        \n        test2 = tc1.new('test_2')\n        check(\"Should be equal\", test1 == test2)\n        check(\"Should be equal\", test2 == test1)\n        \n        test1 = tc1.new('test_1')\n        test2 = tc2.new('test_1')\n        check(\"Should not be equal\", test1 != test2)\n        check(\"Should not be equal\", test2 != test1)\n\n        \n        check(\"Should not be equal\", test1 != Object.new)\n        check(\"Should not be equal\", Object.new != test1)\n      end\n      \n      def check(message, passed)\n        @_result.add_assertion\n        if ! passed\n          raise AssertionFailedError.new(message)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/test_testresult.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/testcase'\nrequire 'test/unit/testresult'\n\nmodule Test\n  module Unit\n    class TC_TestResult < TestCase\n      def setup\n        @my_result = TestResult.new\n        @my_result.add_assertion()\n        @my_result.add_failure(\"\")\n        @my_result.add_error(\"\")\n      end\n      def test_result_changed_notification\n        called1 = false\n        @my_result.add_listener( TestResult::CHANGED) {\n          |result|\n          assert_block(\"The result should be correct\") { result == @my_result }\n          called1 = true\n        }\n        @my_result.add_assertion\n        assert_block(\"Should have been notified when the assertion happened\") { called1 }\n        \n        called1, called2 = false, false\n        @my_result.add_listener( TestResult::CHANGED) {\n          |result|\n          assert_block(\"The result should be correct\") { result == @my_result }\n          called2 = true\n        }\n        @my_result.add_assertion\n        assert_block(\"Both listeners should have been notified for a success\") { called1 && called2 }\n  \n        called1, called2 = false, false\n        @my_result.add_failure(\"\")\n        assert_block(\"Both listeners should have been notified for a failure\") { called1 && called2 }\n  \n        called1, called2 = false, false    \n        @my_result.add_error(\"\")\n        assert_block(\"Both listeners should have been notified for an error\") { called1 && called2 }\n  \n        called1, called2 = false, false    \n        @my_result.add_run\n        assert_block(\"Both listeners should have been notified for a run\") { called1 && called2 }\n      end\n      def test_fault_notification\n        called1 = false\n        fault = \"fault\"\n        @my_result.add_listener(TestResult::FAULT) {\n          | passed_fault |\n          assert_block(\"The fault should be correct\") { passed_fault == fault }\n          called1 = true\n        }\n  \n        @my_result.add_assertion\n        assert_block(\"Should not have been notified when the assertion happened\") { !called1 }\n        \n        @my_result.add_failure(fault)\n        assert_block(\"Should have been notified when the failure happened\") { called1 }\n        \n        called1, called2 = false, false\n        @my_result.add_listener(TestResult::FAULT) {\n          | passed_fault |\n          assert_block(\"The fault should be correct\") { passed_fault == fault }\n          called2 = true\n        }\n  \n        @my_result.add_assertion\n        assert_block(\"Neither listener should have been notified for a success\") { !(called1 || called2) }\n  \n        called1, called2 = false, false\n        @my_result.add_failure(fault)\n        assert_block(\"Both listeners should have been notified for a failure\") { called1 && called2 }\n  \n        called1, called2 = false, false    \n        @my_result.add_error(fault)\n        assert_block(\"Both listeners should have been notified for an error\") { called1 && called2 }\n  \n        called1, called2 = false, false\n        @my_result.add_run\n        assert_block(\"Neither listener should have been notified for a run\") { !(called1 || called2) }\n      end\n      def test_passed?\n        result = TestResult.new\n        assert(result.passed?, \"An empty result should have passed\")\n  \n        result.add_assertion\n        assert(result.passed?, \"Adding an assertion should not cause the result to not pass\")\n  \n        result.add_run\n        assert(result.passed?, \"Adding a run should not cause the result to not pass\")\n  \n        result.add_failure(\"\")\n        assert(!result.passed?, \"Adding a failed assertion should cause the result to not pass\")\n  \n        result = TestResult.new\n        result.add_error(\"\")\n        assert(!result.passed?, \"Adding an error should cause the result to not pass\")\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/test_testsuite.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\n\nmodule Test\n  module Unit\n    class TC_TestSuite < TestCase\n      def setup\n        @testcase1 = Class.new(TestCase) do\n          def test_succeed1\n            assert_block { true }\n          end\n          def test_fail\n            assert_block { false }\n          end\n        end\n\n        @testcase2 = Class.new(TestCase) do\n          def test_succeed2\n            assert_block { true }\n          end\n          def test_error\n            raise\n          end\n        end\n      end\n\n      def test_add\n        s = TestSuite.new\n        assert_equal(s, s << self.class.new(\"test_add\"))\n      end\n\n      def test_delete\n        s = TestSuite.new\n        t1 = self.class.new(\"test_delete\")\n        s << t1\n        t2 = self.class.new(\"test_add\")\n        s << t2\n        assert_equal(t1, s.delete(t1))\n        assert_nil(s.delete(t1))\n        assert_equal(TestSuite.new << t2, s)\n      end\n\n      def test_size\n        suite = TestSuite.new\n        suite2 = TestSuite.new\n        suite2 << self.class.new(\"test_size\")\n        suite << suite2\n        suite << self.class.new(\"test_size\")\n        assert_equal(2, suite.size, \"The count should be correct\")\n      end\n      \n      def test_run\n        progress = []\n        suite = @testcase1.suite\n        result = TestResult.new\n        suite.run(result) { |*values| progress << values }\n  \n        assert_equal(2, result.run_count, \"Should have had four test runs\")\n        assert_equal(1, result.failure_count, \"Should have had one test failure\")\n        assert_equal(0, result.error_count, \"Should have had one test error\")\n        assert_equal([[TestSuite::STARTED, suite.name],\n                [TestCase::STARTED, \"test_fail(#{suite.name})\"],\n                [TestCase::FINISHED, \"test_fail(#{suite.name})\"],\n                [TestCase::STARTED, \"test_succeed1(#{suite.name})\"],\n                [TestCase::FINISHED, \"test_succeed1(#{suite.name})\"],\n                [TestSuite::FINISHED, suite.name]],\n                progress, \"Should have had the correct progress\")\n        \n        suite = TestSuite.new\n        suite << @testcase1.suite\n        suite << @testcase2.suite\n        result = TestResult.new\n        progress = []\n        suite.run(result) { |*values| progress << values }\n  \n        assert_equal(4, result.run_count, \"Should have had four test runs\")\n        assert_equal(1, result.failure_count, \"Should have had one test failure\")\n        assert_equal(1, result.error_count, \"Should have had one test error\")\n        assert_equal(14, progress.size, \"Should have had the correct number of progress calls\")\n      end\n      \n      def test_empty?\n        assert(TestSuite.new.empty?, \"A new test suite should be empty?\")\n        assert(!@testcase2.suite.empty?, \"A test suite with tests should not be empty\")\n      end\n      \n      def test_equality\n        suite1 = TestSuite.new\n        suite2 = TestSuite.new\n        assert_equal(suite1, suite2)\n        assert_equal(suite2, suite1)\n        \n        suite1 = TestSuite.new('name')\n        assert_not_equal(suite1, suite2)\n        assert_not_equal(suite2, suite1)\n        \n        suite2 = TestSuite.new('name')\n        assert_equal(suite1, suite2)\n        assert_equal(suite2, suite1)\n        \n        suite1 << 'test'\n        assert_not_equal(suite1, suite2)\n        assert_not_equal(suite2, suite1)\n        \n        suite2 << 'test'\n        assert_equal(suite1, suite2)\n        assert_equal(suite2, suite1)\n        \n        suite2 = Object.new\n        class << suite2\n          def name\n            'name'\n          end\n          def tests\n            ['test']\n          end\n        end\n        assert_not_equal(suite1, suite2)\n        assert_not_equal(suite2, suite1)\n\n        assert_not_equal(suite1, Object.new)\n        assert_not_equal(Object.new, suite1)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/util/test_backtracefilter.rb",
    "content": "require 'test/unit'\n\nrequire 'test/unit/util/backtracefilter'\n\nmodule Test::Unit::Util\n  class TestBacktraceFilter < Test::Unit::TestCase\n    include BacktraceFilter\n    \n    def test_filter_backtrace\n      backtrace = [%q{C:\\some\\old\\path/test/unit/assertions.rb:44:in 'assert'},\n        %q{tc_thing.rb:4:in 'a'},\n        %q{tc_thing.rb:4:in 'test_stuff'},\n        %q{C:\\some\\old\\path/test/unit/testcase.rb:44:in 'send'},\n        %q{C:\\some\\old\\path\\test\\unit\\testcase.rb:44:in 'run'},\n        %q{C:\\some\\old\\path\\test\\unit.rb:44:in 'run'},\n        %q{tc_thing.rb:3}]\n      assert_equal(backtrace[1..2], filter_backtrace(backtrace, %q{C:\\some\\old\\path\\test\\unit}), \"Should filter out all TestUnit-specific lines\")\n\nbacktrace = [%q{tc_thing.rb:4:in 'a'},\n        %q{tc_thing.rb:4:in 'test_stuff'},\n        %q{tc_thing.rb:3}]\n      assert_equal(backtrace, filter_backtrace(backtrace, %q{C:\\some\\old\\path\\test\\unit}), \"Shouldn't filter too much\")\n\n      backtrace = [%q{C:\\some\\old\\path/test/unit/assertions.rb:44:in 'assert'},\n        %q{tc_thing.rb:4:in 'a'},\n        %q{tc_thing.rb:4:in 'test_stuff'},\n        %q{tc_thing.rb:3}]\n      assert_equal(backtrace[1..3], filter_backtrace(backtrace, %q{C:\\some\\old\\path\\test\\unit}), \"Should filter out all TestUnit-specific lines\")\n      \n      backtrace = [%q{C:\\some\\old\\path/test/unit/assertions.rb:44:in 'assert'},\n        %q{C:\\some\\old\\path/test/unit/testcase.rb:44:in 'send'},\n        %q{C:\\some\\old\\path\\test\\unit\\testcase.rb:44:in 'run'},\n        %q{C:\\some\\old\\path\\test\\unit.rb:44:in 'run'}]\n      assert_equal(backtrace, filter_backtrace(backtrace, %q{C:\\some\\old\\path\\test\\unit}), \"Should filter out all TestUnit-specific lines\")\n    end\n\n    def test_nil_backtrace\n      assert_equal([\"No backtrace\"], filter_backtrace(nil))\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/util/test_observable.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit/util/observable'\n\nmodule Test\n  module Unit\n    module Util\n      class TC_Observable < TestCase\n      \n        class TF_Observable\n          include Observable\n        end\n        \n        def setup\n          @observable = TF_Observable.new\n        end\n        \n        def test_simple_observation\n          assert_raises(ArgumentError, \"add_listener should throw an exception if no callback is supplied\") do\n            @observable.add_listener(:property, \"a\")\n          end\n      \n          heard = false\n          callback = proc { heard = true }\n          assert_equal(\"a\", @observable.add_listener(:property, \"a\", &callback), \"add_listener should return the listener that was added\")\n      \n          count = 0\n          @observable.instance_eval do\n            count = notify_listeners(:property)\n          end\n          assert_equal(1, count, \"notify_listeners should have returned the number of listeners that were notified\")\n          assert(heard, \"Should have heard the property changed\")\n      \n          heard = false\n          assert_equal(callback, @observable.remove_listener(:property, \"a\"), \"remove_listener should return the callback\")\n          \n          count = 1\n          @observable.instance_eval do\n            count = notify_listeners(:property)\n          end\n          assert_equal(0, count, \"notify_listeners should have returned the number of listeners that were notified\")\n          assert(!heard, \"Should not have heard the property change\")\n        end\n        \n        def test_value_observation\n          value = nil\n          @observable.add_listener(:property, \"a\") do |passed_value|\n            value = passed_value\n          end\n          count = 0\n          @observable.instance_eval do\n            count = notify_listeners(:property, \"stuff\")\n          end\n          assert_equal(1, count, \"Should have update the correct number of listeners\")\n          assert_equal(\"stuff\", value, \"Should have received the value as an argument to the listener\")\n        end\n        \n        def test_multiple_value_observation\n          values = []\n          @observable.add_listener(:property, \"a\") do |first_value, second_value|\n            values = [first_value, second_value]\n          end\n          count = 0\n          @observable.instance_eval do\n            count = notify_listeners(:property, \"stuff\", \"more stuff\")\n          end\n          assert_equal(1, count, \"Should have update the correct number of listeners\")\n          assert_equal([\"stuff\", \"more stuff\"], values, \"Should have received the value as an argument to the listener\")\n        end\n        \n        def test_add_remove_with_default_listener\n          assert_raises(ArgumentError, \"add_listener should throw an exception if no callback is supplied\") do\n            @observable.add_listener(:property)\n          end\n      \n          heard = false\n          callback = proc { heard = true }\n          assert_equal(callback, @observable.add_listener(:property, &callback), \"add_listener should return the listener that was added\")\n      \n          count = 0\n          @observable.instance_eval do\n            count = notify_listeners(:property)\n          end\n          assert_equal(1, count, \"notify_listeners should have returned the number of listeners that were notified\")\n          assert(heard, \"Should have heard the property changed\")\n      \n          heard = false\n          assert_equal(callback, @observable.remove_listener(:property, callback), \"remove_listener should return the callback\")\n      \n          count = 1\n          @observable.instance_eval do\n            count = notify_listeners(:property)\n          end\n          assert_equal(0, count, \"notify_listeners should have returned the number of listeners that were notified\")\n          assert(!heard, \"Should not have heard the property change\")\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/testunit/util/test_procwrapper.rb",
    "content": "# Author:: Nathaniel Talbott.\n# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.\n# License:: Ruby license.\n\nrequire 'test/unit'\nrequire 'test/unit/util/procwrapper'\n\nmodule Test\n  module Unit\n    module Util\n      class TC_ProcWrapper < TestCase\n        def munge_proc(&a_proc)\n          return a_proc\n        end\n        def setup\n          @original = proc {}\n          @munged = munge_proc(&@original)\n          @wrapped_original = ProcWrapper.new(@original)\n          @wrapped_munged = ProcWrapper.new(@munged)\n        end\n        def test_wrapping\n          assert_same(@original, @wrapped_original.to_proc, \"The wrapper should return what was wrapped\")\n        end\n        def test_hashing\n      \n          assert_equal(@wrapped_original.hash, @wrapped_munged.hash, \"The original and munged should have the same hash when wrapped\")\n          assert_equal(@wrapped_original, @wrapped_munged, \"The wrappers should be equivalent\")\n          \n          a_hash = {@wrapped_original => @original}\n          assert(a_hash[@wrapped_original], \"Should be able to access the wrapper in the hash\")\n          assert_equal(a_hash[@wrapped_original], @original, \"Should be able to access the wrapper in the hash\")\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/thread/lbtest.rb",
    "content": "#! /usr/bin/ruby\nrequire 'thread'\n\nclass LocalBarrier\n  def initialize(n)\n    @wait = Queue.new\n    @done = Queue.new\n    @keeper = begin_keeper(n)\n  end\n\n  def sync\n    @done.push(true)\n    @wait.pop\n  end\n\n  def join\n    @keeper.join\n  end\n\n  private\n  def begin_keeper(n)\n    Thread.start do\n      n.times do\n        @done.pop\n      end\n      n.times do\n        @wait.push(true)\n      end\n    end\n  end\nend\n\nn = 10\n\nlb = LocalBarrier.new(n)\n\n(n - 1).times do |i|\n  Thread.start do\n    sleep((rand(n) + 1) / 10.0)\n    puts \"#{i}: done\"\n    lb.sync\n    puts \"#{i}: cont\"\n  end\nend\n\nlb.sync\nputs \"#{n-1}: done\"\n\n# lb.join # leaving waiting threads.\n\nputs \"exit.\"\n"
  },
  {
    "path": "test/thread/test_thread.rb",
    "content": "# -*- ruby-indent-level: 4 -*-\nrequire 'thread'\nrequire 'test/unit'\n\nclass TC_Thread < Test::Unit::TestCase\n    def setup\n\tThread.abort_on_exception = true\n    end\n    def teardown\n\tThread.abort_on_exception = false\n    end\n    def test_condvar\n\tmutex = Mutex.new\n\tcondvar = ConditionVariable.new\n\tresult = []\n\tmutex.synchronize do\n\t    t = Thread.new do\n\t\tmutex.synchronize do\n\t\t    result << 1\n\t\t    condvar.signal\n\t\tend\n\t    end\n\t\n\t    result << 0\n\t    condvar.wait(mutex)\n\t    result << 2\n\t    t.join\n\tend\n\tassert_equal([0, 1, 2], result)\n    end\n\n    def test_condvar_wait_not_owner\n\tmutex = Mutex.new\n\tcondvar = ConditionVariable.new\n\n\tassert_raises(ThreadError) { condvar.wait(mutex) }\n    end\n\n    def test_condvar_wait_exception_handling\n\t# Calling wait in the only thread running should raise a ThreadError of\n\t# 'stopping only thread'\n\tmutex = Mutex.new\n\tcondvar = ConditionVariable.new\n\n\tThread.abort_on_exception = false\n\n\tlocked = false\n\tthread = Thread.new do\n\t    mutex.synchronize do\n\t\tbegin\n\t\t    condvar.wait(mutex)\n\t\trescue Exception\n\t\t    locked = mutex.locked?\n\t\t    raise\n\t\tend\n\t    end\n\tend\n\n\twhile !thread.stop?\n\t    sleep(0.1)\n\tend\n\n\tthread.raise Interrupt, \"interrupt a dead condition variable\"\n\tassert_raises(Interrupt) { thread.value }\n\tassert(locked)\n    end\n\n    def test_local_barrier\n        dir = File.dirname(__FILE__)\n        lbtest = File.join(dir, \"lbtest.rb\")\n        $:.unshift File.join(File.dirname(dir), 'ruby')\n        require 'envutil'\n        $:.shift\n        10.times {\n            result = `#{EnvUtil.rubybin} #{lbtest}`\n            assert(!$?.coredump?, '[ruby-dev:30653]')\n            assert_equal(\"exit.\", result[/.*\\Z/], '[ruby-dev:30653]')\n        }\n    end\n\n    def test_queue_rescue\n        require \"timeout\"\n        queue = Queue.new\n        assert_raises(Timeout::Error) {Timeout.timeout(0.001) {queue.pop}}\n        queue.push(1)\n        assert_nothing_raised(\"[ruby-dev:37545]\") {assert_equal(1, queue.pop)}\n        assert(queue.empty?)\n    end\nend\n\n"
  },
  {
    "path": "test/uri/test_common.rb",
    "content": "require 'test/unit'\nrequire 'uri'\n\nmodule URI\n\n\nclass TestCommon < Test::Unit::TestCase\n  def setup\n  end\n\n  def teardown\n  end\n\n  def test_extract\n    assert_equal(['http://example.com'], \n\t\t URI.extract('http://example.com'))\n    assert_equal(['http://example.com'], \n\t\t URI.extract('(http://example.com)'))\n    assert_equal(['http://example.com/foo)'], \n\t\t URI.extract('(http://example.com/foo)'))\n    assert_equal(['http://example.jphttp://example.jp'], \n\t\t URI.extract('http://example.jphttp://example.jp'), \"[ruby-list:36086]\")\n    assert_equal(['http://example.jphttp://example.jp'], \n\t\t URI.extract('http://example.jphttp://example.jp', ['http']), \"[ruby-list:36086]\")\n    assert_equal(['http://', 'mailto:'].sort, \n\t\t URI.extract('ftp:// http:// mailto: https://', ['http', 'mailto']).sort)\n    # reported by Doug Kearns <djkea2@mugca.its.monash.edu.au>\n    assert_equal(['From:', 'mailto:xxx@xxx.xxx.xxx]'].sort, \n\t\t URI.extract('From: XXX [mailto:xxx@xxx.xxx.xxx]').sort)\n  end\n\n  def test_regexp\n    assert_instance_of Regexp, URI.regexp\n    assert_instance_of Regexp, URI.regexp(['http'])\n    assert_equal URI.regexp, URI.regexp\n    assert_equal 'http://', 'x http:// x'.slice(URI.regexp)\n    assert_equal 'http://', 'x http:// x'.slice(URI.regexp(['http']))\n    assert_equal 'http://', 'x http:// x ftp://'.slice(URI.regexp(['http']))\n    assert_equal nil, 'http://'.slice(URI.regexp([]))\n    assert_equal nil, ''.slice(URI.regexp)\n    assert_equal nil, 'xxxx'.slice(URI.regexp)\n    assert_equal nil, ':'.slice(URI.regexp)\n    assert_equal 'From:', 'From:'.slice(URI.regexp)\n  end\n\n  def test_kernel_uri\n    expected = URI.parse(\"http://www.ruby-lang.org/\")\n    assert_equal(expected, URI(\"http://www.ruby-lang.org/\"))\n    assert_equal(expected, Kernel::URI(\"http://www.ruby-lang.org/\"))\n    assert_raise(NoMethodError) { Object.new.URI(\"http://www.ruby-lang.org/\") }\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/uri/test_ftp.rb",
    "content": "require 'test/unit'\nrequire 'uri/ftp'\n\nmodule URI\n\n\nclass TestFTP < Test::Unit::TestCase\n  def setup\n  end\n\n  def test_parse\n    url = URI.parse('ftp://user:pass@host.com/abc/def')\n    assert_kind_of(URI::FTP, url)\n\n    exp = [\n      'ftp',\n      'user:pass', 'host.com', URI::FTP.default_port, \n      'abc/def', nil,\n    ]\n    ary = [\n      url.scheme, url.userinfo, url.host, url.port,\n      url.path, url.opaque\n    ]\n    assert_equal(exp, ary)\n\n    assert_equal('user', url.user)\n    assert_equal('pass', url.password)\n  end\n\n  def test_paths\n    # If you think what's below is wrong, please read RubyForge bug 2055, \n    # RFC 1738 section 3.2.2, and RFC 2396.\n    u = URI.parse('ftp://ftp.example.com/foo/bar/file.ext')\n    assert_equal(u.path, 'foo/bar/file.ext')\n    u = URI.parse('ftp://ftp.example.com//foo/bar/file.ext')\n    assert_equal(u.path, '/foo/bar/file.ext')\n    u = URI.parse('ftp://ftp.example.com/%2Ffoo/bar/file.ext')\n    assert_equal(u.path, '/foo/bar/file.ext')\n  end\n\n  def test_assemble\n    # uri/ftp is conservative and uses the older RFC 1738 rules, rather than\n    # assuming everyone else has implemented RFC 2396.\n    uri = URI::FTP.build(['user:password', 'ftp.example.com', nil, \n                         '/path/file.zip', 'i'])\n    assert_equal(uri.to_s,\n           'ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=i')\n  end\n\n  def test_select\n    assert_equal(['ftp', 'a.b.c', 21], URI.parse('ftp://a.b.c/').select(:scheme, :host, :port))\n    u = URI.parse('ftp://a.b.c/')\n    ary = u.component.collect {|c| u.send(c)}\n    assert_equal(ary, u.select(*u.component))\n    assert_raises(ArgumentError) do\n      u.select(:scheme, :host, :not_exist, :port)\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/uri/test_generic.rb",
    "content": "require 'test/unit'\nrequire 'uri'\n\nmodule URI\n\n\nclass TestGeneric < Test::Unit::TestCase\n  def setup\n    @url = 'http://a/b/c/d;p?q'\n    @base_url = URI.parse(@url)\n  end\n\n  def teardown\n  end\n\n  def uri_to_ary(uri)\n    uri.class.component.collect {|c| uri.send(c)}\n  end\n\n  def test_parse\n    # 0\n    assert_kind_of(URI::HTTP, @base_url)\n\n    exp = [\n      'http', \n      nil, 'a', URI::HTTP.default_port, \n      '/b/c/d;p', \n      'q',\n      nil\n    ]\n    ary = uri_to_ary(@base_url)\n    assert_equal(exp, ary)\n\n    # 1\n    url = URI.parse('ftp://ftp.is.co.za/rfc/rfc1808.txt')\n    assert_kind_of(URI::FTP, url)\n\n    exp = [\n      'ftp', \n      nil, 'ftp.is.co.za', URI::FTP.default_port, \n      'rfc/rfc1808.txt', nil,\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n    # 1'\n    url = URI.parse('ftp://ftp.is.co.za/%2Frfc/rfc1808.txt')\n    assert_kind_of(URI::FTP, url)\n\n    exp = [\n      'ftp', \n      nil, 'ftp.is.co.za', URI::FTP.default_port, \n      '/rfc/rfc1808.txt', nil,\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n\n    # 2\n    url = URI.parse('gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles')\n    assert_kind_of(URI::Generic, url)\n\n    exp = [\n      'gopher', \n      nil, 'spinaltap.micro.umn.edu', nil, nil,\n      '/00/Weather/California/Los%20Angeles', nil,\n      nil,\n      nil\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n\n    # 3\n    url = URI.parse('http://www.math.uio.no/faq/compression-faq/part1.html')\n    assert_kind_of(URI::HTTP, url)\n\n    exp = [\n      'http', \n      nil, 'www.math.uio.no', URI::HTTP.default_port, \n      '/faq/compression-faq/part1.html', \n      nil,\n      nil\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n\n    # 4\n    url = URI.parse('mailto:mduerst@ifi.unizh.ch')\n    assert_kind_of(URI::Generic, url)\n\n    exp = [\n      'mailto', \n      'mduerst@ifi.unizh.ch',\n      []\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n\n    # 5\n    url = URI.parse('news:comp.infosystems.www.servers.unix')\n    assert_kind_of(URI::Generic, url)\n\n    exp = [\n      'news', \n      nil, nil, nil, nil, \n      nil, 'comp.infosystems.www.servers.unix',\n      nil,\n      nil\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n\n    # 6\n    url = URI.parse('telnet://melvyl.ucop.edu/')\n    assert_kind_of(URI::Generic, url)\n\n    exp = [\n      'telnet', \n      nil, 'melvyl.ucop.edu', nil, nil, \n      '/', nil,\n      nil,\n      nil\n    ]\n    ary = uri_to_ary(url)\n    assert_equal(exp, ary)\n\n    # 7\n    # reported by Mr. Kubota <em6t-kbt@asahi-net.or.jp>\n    assert_raises(URI::InvalidURIError) { URI.parse('http://a_b:80/') }\n    assert_raises(URI::InvalidURIError) { URI.parse('http://a_b/') }\n\n    # 8\n    # reported by m_seki\n    uri = URI.parse('file:///foo/bar.txt')\n    assert_kind_of(URI::Generic, url)\n    uri = URI.parse('file:/foo/bar.txt')\n    assert_kind_of(URI::Generic, url)\n\n    # 9\n    url = URI.parse('ftp://:pass@localhost/')\n    assert_equal('', url.user, \"[ruby-dev:25667]\")\n    assert_equal('pass', url.password)\n    assert_equal(':pass', url.userinfo, \"[ruby-dev:25667]\")\n    url = URI.parse('ftp://user@localhost/')\n    assert_equal('user', url.user)\n    assert_equal(nil, url.password)\n    assert_equal('user', url.userinfo)\n    url = URI.parse('ftp://localhost/')\n    assert_equal(nil, url.user)\n    assert_equal(nil, url.password)\n    assert_equal(nil, url.userinfo)\n  end\n\n  def test_merge\n    u1 = URI.parse('http://foo')\n    u2 = URI.parse('http://foo/')\n    u3 = URI.parse('http://foo/bar')\n    u4 = URI.parse('http://foo/bar/')\n\n    assert_equal(URI.parse('http://foo/baz'), u1 + 'baz')\n    assert_equal(URI.parse('http://foo/baz'), u2 + 'baz')\n    assert_equal(URI.parse('http://foo/baz'), u3 + 'baz')\n    assert_equal(URI.parse('http://foo/bar/baz'), u4 + 'baz')\n\n    assert_equal(URI.parse('http://foo/baz'), u1 + '/baz')\n    assert_equal(URI.parse('http://foo/baz'), u2 + '/baz')\n    assert_equal(URI.parse('http://foo/baz'), u3 + '/baz')\n    assert_equal(URI.parse('http://foo/baz'), u4 + '/baz')\n\n    url = URI.parse('http://hoge/a.html') + 'b.html'\n    assert_equal('http://hoge/b.html', url.to_s, \"[ruby-dev:11508]\")\n\n    # reported by Mr. Kubota <em6t-kbt@asahi-net.or.jp>\n    url = URI.parse('http://a/b') + 'http://x/y'\n    assert_equal('http://x/y', url.to_s)\n    assert_equal(url, URI.parse('')                     + 'http://x/y')\n    assert_equal(url, URI.parse('').normalize           + 'http://x/y')\n    assert_equal(url, URI.parse('http://a/b').normalize + 'http://x/y')\n\n    u = URI.parse('http://foo/bar/baz')\n    assert_equal(nil, u.merge!(\"\"))\n    assert_equal(nil, u.merge!(u))\n    assert(nil != u.merge!(\".\"))\n    assert_equal('http://foo/bar/', u.to_s)\n    assert(nil != u.merge!(\"../baz\"))\n    assert_equal('http://foo/baz', u.to_s)\n\n    u0 = URI.parse('mailto:foo@example.com')\n    u1 = URI.parse('mailto:foo@example.com#bar')\n    assert_equal(uri_to_ary(u0 + '#bar'), uri_to_ary(u1), \"[ruby-dev:23628]\")\n\n    u0 = URI.parse('http://www.example.com/')\n    u1 = URI.parse('http://www.example.com/foo/..') + './'\n    assert_equal(u0, u1, \"[ruby-list:39838]\")\n    u0 = URI.parse('http://www.example.com/foo/')\n    u1 = URI.parse('http://www.example.com/foo/bar/..') + './'\n    assert_equal(u0, u1)\n    u0 = URI.parse('http://www.example.com/foo/bar/')\n    u1 = URI.parse('http://www.example.com/foo/bar/baz/..') + './'\n    assert_equal(u0, u1)\n    u0 = URI.parse('http://www.example.com/')\n    u1 = URI.parse('http://www.example.com/foo/bar/../..') + './'\n    assert_equal(u0, u1)\n    u0 = URI.parse('http://www.example.com/foo/')\n    u1 = URI.parse('http://www.example.com/foo/bar/baz/../..') + './'\n    assert_equal(u0, u1)\n\n    u = URI.parse('http://www.example.com/')\n    u0 = u + './foo/'\n    u1 = u + './foo/bar/..'\n    assert_equal(u0, u1, \"[ruby-list:39844]\")\n    u = URI.parse('http://www.example.com/')\n    u0 = u + './'\n    u1 = u + './foo/bar/../..'\n    assert_equal(u0, u1)\n  end\n\n  def test_route\n    url = URI.parse('http://hoge/a.html').route_to('http://hoge/b.html')\n    assert_equal('b.html', url.to_s)\n\n    url = URI.parse('http://hoge/a/').route_to('http://hoge/b/')\n    assert_equal('../b/', url.to_s)\n    url = URI.parse('http://hoge/a/b').route_to('http://hoge/b/')\n    assert_equal('../b/', url.to_s)\n\n    url = URI.parse('http://hoge/a/b/').route_to('http://hoge/b/')\n    assert_equal('../../b/', url.to_s)\n\n    url = URI.parse('http://hoge/a/b/').route_to('http://HOGE/b/')\n    assert_equal('../../b/', url.to_s)\n\n    url = URI.parse('http://hoge/a/b/').route_to('http://MOGE/b/')\n    assert_equal('//MOGE/b/', url.to_s)\n\n    url = URI.parse('file:///a/b/').route_to('file:///a/b/')\n    assert_equal('', url.to_s)\n\n    url = URI.parse('mailto:foo@example.com').route_to('mailto:foo@example.com#bar')\n    assert_equal('#bar', url.to_s)\n\n    url = URI.parse('mailto:foo@example.com#bar').route_to('mailto:foo@example.com')\n    assert_equal('', url.to_s)\n\n    url = URI.parse('mailto:foo@example.com').route_to('mailto:foo@example.com')\n    assert_equal('', url.to_s)\n  end\n\n  def test_rfc3986_examples\n#  http://a/b/c/d;p?q\n#        g:h           =  g:h\n    url = @base_url.merge('g:h')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g:h', url.to_s)\n    url = @base_url.route_to('g:h')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g:h', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g             =  http://a/b/c/g\n    url = @base_url.merge('g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ./g           =  http://a/b/c/g\n    url = @base_url.merge('./g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g')\n    assert_kind_of(URI::Generic, url)\n    assert('./g' != url.to_s) # ok\n    assert_equal('g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g/            =  http://a/b/c/g/\n    url = @base_url.merge('g/')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g/', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g/')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g/', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        /g            =  http://a/g\n    url = @base_url.merge('/g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/g', url.to_s)\n    url = @base_url.route_to('http://a/g')\n    assert_kind_of(URI::Generic, url)\n    assert('/g' != url.to_s) # ok\n    assert_equal('../../g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        //g           =  http://g\n    url = @base_url.merge('//g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://g', url.to_s)\n    url = @base_url.route_to('http://g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('//g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ?y            =  http://a/b/c/d;p?y\n    url = @base_url.merge('?y')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/d;p?y', url.to_s)\n    url = @base_url.route_to('http://a/b/c/d;p?y')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('?y', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g?y           =  http://a/b/c/g?y\n    url = @base_url.merge('g?y')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g?y', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g?y')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g?y', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        #s            =  http://a/b/c/d;p?q#s\n    url = @base_url.merge('#s')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/d;p?q#s', url.to_s)\n    url = @base_url.route_to('http://a/b/c/d;p?q#s')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('#s', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g#s           =  http://a/b/c/g#s\n    url = @base_url.merge('g#s')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g#s', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g#s')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g#s', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g?y#s         =  http://a/b/c/g?y#s\n    url = @base_url.merge('g?y#s')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g?y#s', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g?y#s')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g?y#s', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ;x            =  http://a/b/c/;x\n    url = @base_url.merge(';x')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/;x', url.to_s)\n    url = @base_url.route_to('http://a/b/c/;x')\n    assert_kind_of(URI::Generic, url)\n    assert_equal(';x', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g;x           =  http://a/b/c/g;x\n    url = @base_url.merge('g;x')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g;x', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g;x')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g;x', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g;x?y#s       =  http://a/b/c/g;x?y#s\n    url = @base_url.merge('g;x?y#s')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g;x?y#s', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g;x?y#s')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g;x?y#s', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        .             =  http://a/b/c/\n    url = @base_url.merge('.')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/', url.to_s)\n    url = @base_url.route_to('http://a/b/c/')\n    assert_kind_of(URI::Generic, url)\n    assert('.' != url.to_s) # ok\n    assert_equal('./', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ./            =  http://a/b/c/\n    url = @base_url.merge('./')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/', url.to_s)\n    url = @base_url.route_to('http://a/b/c/')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('./', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ..            =  http://a/b/\n    url = @base_url.merge('..')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/', url.to_s)\n    url = @base_url.route_to('http://a/b/')\n    assert_kind_of(URI::Generic, url)\n    assert('..' != url.to_s) # ok\n    assert_equal('../', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ../           =  http://a/b/\n    url = @base_url.merge('../')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/', url.to_s)\n    url = @base_url.route_to('http://a/b/')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('../', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ../g          =  http://a/b/g\n    url = @base_url.merge('../g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/g', url.to_s)\n    url = @base_url.route_to('http://a/b/g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('../g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ../..         =  http://a/\n    url = @base_url.merge('../..')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/', url.to_s)\n    url = @base_url.route_to('http://a/')\n    assert_kind_of(URI::Generic, url)\n    assert('../..' != url.to_s) # ok\n    assert_equal('../../', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ../../        =  http://a/\n    url = @base_url.merge('../../')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/', url.to_s)\n    url = @base_url.route_to('http://a/')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('../../', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ../../g       =  http://a/g\n    url = @base_url.merge('../../g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/g', url.to_s)\n    url = @base_url.route_to('http://a/g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('../../g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        <>            =  (current document)\n    url = @base_url.merge('')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/d;p?q', url.to_s)\n    url = @base_url.route_to('http://a/b/c/d;p?q')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        /./g          =  http://a/g\n    url = @base_url.merge('/./g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/g', url.to_s)\n#    url = @base_url.route_to('http://a/./g')\n#    assert_kind_of(URI::Generic, url)\n#    assert_equal('/./g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        /../g         =  http://a/g\n    url = @base_url.merge('/../g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/g', url.to_s)\n#    url = @base_url.route_to('http://a/../g')\n#    assert_kind_of(URI::Generic, url)\n#    assert_equal('/../g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g.            =  http://a/b/c/g.\n    url = @base_url.merge('g.')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g.', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g.')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g.', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        .g            =  http://a/b/c/.g\n    url = @base_url.merge('.g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/.g', url.to_s)\n    url = @base_url.route_to('http://a/b/c/.g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('.g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g..           =  http://a/b/c/g..\n    url = @base_url.merge('g..')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g..', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g..')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g..', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ..g           =  http://a/b/c/..g\n    url = @base_url.merge('..g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/..g', url.to_s)\n    url = @base_url.route_to('http://a/b/c/..g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('..g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ../../../g    =  http://a/g\n    url = @base_url.merge('../../../g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/g', url.to_s)\n    url = @base_url.route_to('http://a/g')\n    assert_kind_of(URI::Generic, url)\n    assert('../../../g' != url.to_s)  # ok? yes, it confuses you\n    assert_equal('../../g', url.to_s) # and it is clearly\n\n#  http://a/b/c/d;p?q\n#        ../../../../g =  http://a/g\n    url = @base_url.merge('../../../../g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/g', url.to_s)\n    url = @base_url.route_to('http://a/g')\n    assert_kind_of(URI::Generic, url)\n    assert('../../../../g' != url.to_s) # ok? yes, it confuses you\n    assert_equal('../../g', url.to_s)   # and it is clearly\n\n#  http://a/b/c/d;p?q\n#        ./../g        =  http://a/b/g\n    url = @base_url.merge('./../g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/g', url.to_s)\n    url = @base_url.route_to('http://a/b/g')\n    assert_kind_of(URI::Generic, url)\n    assert('./../g' != url.to_s) # ok\n    assert_equal('../g', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        ./g/.         =  http://a/b/c/g/\n    url = @base_url.merge('./g/.')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g/', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g/')\n    assert_kind_of(URI::Generic, url)\n    assert('./g/.' != url.to_s) # ok\n    assert_equal('g/', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g/./h         =  http://a/b/c/g/h\n    url = @base_url.merge('g/./h')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g/h', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g/h')\n    assert_kind_of(URI::Generic, url)\n    assert('g/./h' != url.to_s) # ok\n    assert_equal('g/h', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g/../h        =  http://a/b/c/h\n    url = @base_url.merge('g/../h')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/h', url.to_s)\n    url = @base_url.route_to('http://a/b/c/h')\n    assert_kind_of(URI::Generic, url)\n    assert('g/../h' != url.to_s) # ok\n    assert_equal('h', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g;x=1/./y     =  http://a/b/c/g;x=1/y\n    url = @base_url.merge('g;x=1/./y')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g;x=1/y', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g;x=1/y')\n    assert_kind_of(URI::Generic, url)\n    assert('g;x=1/./y' != url.to_s) # ok\n    assert_equal('g;x=1/y', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g;x=1/../y    =  http://a/b/c/y\n    url = @base_url.merge('g;x=1/../y')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/y', url.to_s)\n    url = @base_url.route_to('http://a/b/c/y')\n    assert_kind_of(URI::Generic, url)\n    assert('g;x=1/../y' != url.to_s) # ok\n    assert_equal('y', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g?y/./x       =  http://a/b/c/g?y/./x\n    url = @base_url.merge('g?y/./x')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g?y/./x', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g?y/./x')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g?y/./x', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g?y/../x      =  http://a/b/c/g?y/../x\n    url = @base_url.merge('g?y/../x')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g?y/../x', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g?y/../x')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g?y/../x', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g#s/./x       =  http://a/b/c/g#s/./x\n    url = @base_url.merge('g#s/./x')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g#s/./x', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g#s/./x')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g#s/./x', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        g#s/../x      =  http://a/b/c/g#s/../x\n    url = @base_url.merge('g#s/../x')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http://a/b/c/g#s/../x', url.to_s)\n    url = @base_url.route_to('http://a/b/c/g#s/../x')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('g#s/../x', url.to_s)\n\n#  http://a/b/c/d;p?q\n#        http:g        =  http:g           ; for validating parsers\n#                      |  http://a/b/c/g   ; for backwards compatibility\n    url = @base_url.merge('http:g')\n    assert_kind_of(URI::HTTP, url)\n    assert_equal('http:g', url.to_s)\n    url = @base_url.route_to('http:g')\n    assert_kind_of(URI::Generic, url)\n    assert_equal('http:g', url.to_s)\n  end\n\n  def test_join\n    assert_equal(URI.parse('http://foo/bar'), URI.join('http://foo/bar'))\n    assert_equal(URI.parse('http://foo/bar'), URI.join('http://foo', 'bar'))\n    assert_equal(URI.parse('http://foo/bar/'), URI.join('http://foo', 'bar/'))\n\n    assert_equal(URI.parse('http://foo/baz'), URI.join('http://foo', 'bar', 'baz'))\n    assert_equal(URI.parse('http://foo/baz'), URI.join('http://foo', 'bar', '/baz'))\n    assert_equal(URI.parse('http://foo/baz/'), URI.join('http://foo', 'bar', '/baz/'))\n    assert_equal(URI.parse('http://foo/bar/baz'), URI.join('http://foo', 'bar/', 'baz'))\n    assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar', 'baz', 'hoge'))\n\n    assert_equal(URI.parse('http://foo/bar/baz'), URI.join('http://foo', 'bar/baz'))\n    assert_equal(URI.parse('http://foo/bar/hoge'), URI.join('http://foo', 'bar/baz', 'hoge'))\n    assert_equal(URI.parse('http://foo/bar/baz/hoge'), URI.join('http://foo', 'bar/baz/', 'hoge'))\n    assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar/baz', '/hoge'))\n    assert_equal(URI.parse('http://foo/bar/hoge'), URI.join('http://foo', 'bar/baz', 'hoge'))\n    assert_equal(URI.parse('http://foo/bar/baz/hoge'), URI.join('http://foo', 'bar/baz/', 'hoge'))\n    assert_equal(URI.parse('http://foo/hoge'), URI.join('http://foo', 'bar/baz', '/hoge'))\n  end\n\n  # ruby-dev:16728\n  def test_set_component\n    uri = URI.parse('http://foo:bar@baz')\n    assert_equal('oof', uri.user = 'oof')\n    assert_equal('http://oof:bar@baz', uri.to_s)\n    assert_equal('rab', uri.password = 'rab')\n    assert_equal('http://oof:rab@baz', uri.to_s)\n    assert_equal('foo', uri.userinfo = 'foo')\n    assert_equal('http://foo:rab@baz', uri.to_s)\n    assert_equal(['foo', 'bar'], uri.userinfo = ['foo', 'bar'])\n    assert_equal('http://foo:bar@baz', uri.to_s)\n    assert_equal(['foo'], uri.userinfo = ['foo'])\n    assert_equal('http://foo:bar@baz', uri.to_s)\n    assert_equal('zab', uri.host = 'zab')\n    assert_equal('http://foo:bar@zab', uri.to_s)\n    assert_equal(8080, uri.port = 8080)\n    assert_equal('http://foo:bar@zab:8080', uri.to_s)\n    assert_equal('/', uri.path = '/')\n    assert_equal('http://foo:bar@zab:8080/', uri.to_s)\n    assert_equal('a=1', uri.query = 'a=1')\n    assert_equal('http://foo:bar@zab:8080/?a=1', uri.to_s)\n    assert_equal('b123', uri.fragment = 'b123')\n    assert_equal('http://foo:bar@zab:8080/?a=1#b123', uri.to_s)\n\n    uri = URI.parse('http://example.com')\n    assert_raises(URI::InvalidURIError) { uri.password = 'bar' }\n    uri.userinfo = 'foo:bar'\n    assert_equal('http://foo:bar@example.com', uri.to_s)\n    assert_raises(URI::InvalidURIError) { uri.registry = 'bar' }\n    assert_raises(URI::InvalidURIError) { uri.opaque = 'bar' }\n\n    uri = URI.parse('mailto:foo@example.com')\n    assert_raises(URI::InvalidURIError) { uri.user = 'bar' }\n    assert_raises(URI::InvalidURIError) { uri.password = 'bar' }\n    assert_raises(URI::InvalidURIError) { uri.userinfo = ['bar', 'baz'] }\n    assert_raises(URI::InvalidURIError) { uri.host = 'bar' }\n    assert_raises(URI::InvalidURIError) { uri.port = 'bar' }\n    assert_raises(URI::InvalidURIError) { uri.path = 'bar' }\n    assert_raises(URI::InvalidURIError) { uri.query = 'bar' }\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/uri/test_http.rb",
    "content": "require 'test/unit'\nrequire 'uri/http'\n\nmodule URI\n\n\nclass TestHTTP < Test::Unit::TestCase\n  def setup\n  end\n\n  def teardown\n  end\n\n  def uri_to_ary(uri)\n    uri.class.component.collect {|c| uri.send(c)}\n  end\n\n  def test_parse\n    u = URI.parse('http://a')\n    assert_kind_of(URI::HTTP, u)\n    assert_equal(['http', \n\t\t   nil, 'a', URI::HTTP.default_port,\n\t\t   '', nil, nil], uri_to_ary(u))\n  end\n\n  def test_normalize\n    host = 'aBcD'\n    u1 = URI.parse('http://' + host          + '/eFg?HiJ')\n    u2 = URI.parse('http://' + host.downcase + '/eFg?HiJ')\n    assert(u1.normalize.host == 'abcd')\n    assert(u1.normalize.path == u1.path)\n    assert(u1.normalize == u2.normalize)\n    assert(!u1.normalize.host.equal?(u1.host))\n    assert( u2.normalize.host.equal?(u2.host))\n\n    assert_equal('http://abc/', URI.parse('http://abc').normalize.to_s)\n  end\n\n  def test_equal\n    assert(URI.parse('http://abc') == URI.parse('http://ABC'))\n    assert(URI.parse('http://abc/def') == URI.parse('http://ABC/def'))\n    assert(URI.parse('http://abc/def') != URI.parse('http://ABC/DEF'))\n  end\n\n  def test_request_uri\n    assert_equal('/',         URI.parse('http://a.b.c/').request_uri)\n    assert_equal('/?abc=def', URI.parse('http://a.b.c/?abc=def').request_uri)\n    assert_equal('/',         URI.parse('http://a.b.c').request_uri)\n    assert_equal('/?abc=def', URI.parse('http://a.b.c?abc=def').request_uri)\n  end\n\n  def test_select\n    assert_equal(['http', 'a.b.c', 80], URI.parse('http://a.b.c/').select(:scheme, :host, :port))\n    u = URI.parse('http://a.b.c/')\n    assert_equal(uri_to_ary(u), u.select(*u.component))\n    assert_raises(ArgumentError) do\n      u.select(:scheme, :host, :not_exist, :port)\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/uri/test_ldap.rb",
    "content": "require 'test/unit'\nrequire 'uri/ldap'\n\nmodule URI\n\n\nclass TestLDAP < Test::Unit::TestCase\n  def setup\n  end\n\n  def teardown\n  end\n\n  def uri_to_ary(uri)\n    uri.class.component.collect {|c| uri.send(c)}\n  end\n\n  def test_parse\n    url = 'ldap://ldap.jaist.ac.jp/o=JAIST,c=JP?sn?base?(sn=ttate*)'\n    u = URI.parse(url)\n    assert_kind_of(URI::LDAP, u)\n    assert_equal(url, u.to_s)\n    assert_equal('o=JAIST,c=JP', u.dn)\n    assert_equal('sn', u.attributes)\n    assert_equal('base', u.scope)\n    assert_equal('(sn=ttate*)', u.filter)\n    assert_equal(nil, u.extensions)\n\n    u.scope = URI::LDAP::SCOPE_SUB\n    u.attributes = 'sn,cn,mail'\n    assert_equal('ldap://ldap.jaist.ac.jp/o=JAIST,c=JP?sn,cn,mail?sub?(sn=ttate*)', u.to_s)\n    assert_equal('o=JAIST,c=JP', u.dn)\n    assert_equal('sn,cn,mail', u.attributes)\n    assert_equal('sub', u.scope)\n    assert_equal('(sn=ttate*)', u.filter)\n    assert_equal(nil, u.extensions)\n\n    # from RFC2255, section 6.\n    urls = {\n      'ldap:///o=University%20of%20Michigan,c=US' =>\n      ['ldap', nil, URI::LDAP::DEFAULT_PORT, \n\t'o=University%20of%20Michigan,c=US', \n\tnil, nil, nil, nil],\n\n      'ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US' =>\n      ['ldap', 'ldap.itd.umich.edu', URI::LDAP::DEFAULT_PORT, \n\t'o=University%20of%20Michigan,c=US', \n\tnil, nil, nil, nil],\n\n      'ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US?postalAddress' =>\n      ['ldap', 'ldap.itd.umich.edu', URI::LDAP::DEFAULT_PORT, \n\t'o=University%20of%20Michigan,c=US',\n\t'postalAddress', nil, nil, nil],\n\n      'ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)' =>\n      ['ldap', 'host.com', 6666, \n\t'o=University%20of%20Michigan,c=US',\n\tnil, 'sub', '(cn=Babs%20Jensen)', nil],\n\n      'ldap://ldap.itd.umich.edu/c=GB?objectClass?one' =>\n      ['ldap', 'ldap.itd.umich.edu', URI::LDAP::DEFAULT_PORT, \n\t'c=GB', \n\t'objectClass', 'one', nil, nil],\n\n      'ldap://ldap.question.com/o=Question%3f,c=US?mail' =>\n      ['ldap', 'ldap.question.com', URI::LDAP::DEFAULT_PORT, \n\t'o=Question%3f,c=US',\n\t'mail', nil, nil, nil],\n\n      'ldap://ldap.netscape.com/o=Babsco,c=US??(int=%5c00%5c00%5c00%5c04)' =>\n      ['ldap', 'ldap.netscape.com', URI::LDAP::DEFAULT_PORT, \n\t'o=Babsco,c=US',\n\tnil, '(int=%5c00%5c00%5c00%5c04)', nil, nil],\n\n      'ldap:///??sub??bindname=cn=Manager%2co=Foo' =>\n      ['ldap', nil, URI::LDAP::DEFAULT_PORT, \n\t'',\n\tnil, 'sub', nil, 'bindname=cn=Manager%2co=Foo'],\n\n      'ldap:///??sub??!bindname=cn=Manager%2co=Foo' =>\n      ['ldap', nil, URI::LDAP::DEFAULT_PORT, \n\t'',\n\tnil, 'sub', nil, '!bindname=cn=Manager%2co=Foo'],\n    }.each do |url, ary|\n      u = URI.parse(url)\n      assert_equal(ary, uri_to_ary(u))\n    end\n  end\n\n  def test_select\n    u = URI.parse('ldap:///??sub??!bindname=cn=Manager%2co=Foo')\n    assert_equal(uri_to_ary(u), u.select(*u.component))\n    assert_raises(ArgumentError) do\n      u.select(:scheme, :host, :not_exist, :port)\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/uri/test_mailto.rb",
    "content": "require 'test/unit'\nrequire 'uri/mailto'\n\nmodule URI\n\n\nclass TestMailTo < Test::Unit::TestCase\n  def setup\n    @u = URI::MailTo\n  end\n\n  def teardown\n  end\n\n  def uri_to_ary(uri)\n    uri.class.component.collect {|c| uri.send(c)}\n  end\n\n  def test_build\n    ok = []\n    bad = []\n\n    # RFC2368, 6. Examples\n    # mailto:chris@example.com\n    ok << [\"mailto:chris@example.com\"]\n    ok[-1] << [\"chris@example.com\", nil]\n    ok[-1] << {:to => \"chris@example.com\"}\n\n    # mailto:infobot@example.com?subject=current-issue\n    ok << [\"mailto:infobot@example.com?subject=current-issue\"]\n    ok[-1] << [\"infobot@example.com\", [\"subject=current-issue\"]]\n    ok[-1] << {:to => \"infobot@example.com\", \n      :headers => [\"subject=current-issue\"]}\n\n    # mailto:infobot@example.com?body=send%20current-issue\n    ok << [\"mailto:infobot@example.com?body=send%20current-issue\"]\n    ok[-1] << [\"infobot@example.com\", [\"body=send%20current-issue\"]]\n    ok[-1] << {:to => \"infobot@example.com\", \n      :headers => [\"body=send%20current-issue\"]}\n\n    # mailto:infobot@example.com?body=send%20current-issue%0D%0Asend%20index\n    ok << [\"mailto:infobot@example.com?body=send%20current-issue%0D%0Asend%20index\"]\n    ok[-1] << [\"infobot@example.com\", \n      [\"body=send%20current-issue%0D%0Asend%20index\"]]\n    ok[-1] << {:to => \"infobot@example.com\", \n      :headers => [\"body=send%20current-issue%0D%0Asend%20index\"]}\n\n    # mailto:foobar@example.com?In-Reply-To=%3c3469A91.D10AF4C@example.com\n    ok << [\"mailto:foobar@example.com?In-Reply-To=%3c3469A91.D10AF4C@example.com\"]\n    ok[-1] << [\"foobar@example.com\", \n      [\"In-Reply-To=%3c3469A91.D10AF4C@example.com\"]]\n    ok[-1] << {:to => \"foobar@example.com\", \n      :headers => [\"In-Reply-To=%3c3469A91.D10AF4C@example.com\"]}\n\n    # mailto:majordomo@example.com?body=subscribe%20bamboo-l\n    ok << [\"mailto:majordomo@example.com?body=subscribe%20bamboo-l\"]\n    ok[-1] << [\"majordomo@example.com\", [\"body=subscribe%20bamboo-l\"]]\n    ok[-1] << {:to => \"majordomo@example.com\", \n      :headers => [\"body=subscribe%20bamboo-l\"]}\n\n    # mailto:joe@example.com?cc=bob@example.com&body=hello\n    ok << [\"mailto:joe@example.com?cc=bob@example.com&body=hello\"]\n    ok[-1] << [\"joe@example.com\", [\"cc=bob@example.com\", \"body=hello\"]]\n    ok[-1] << {:to => \"joe@example.com\", \n      :headers => [\"cc=bob@example.com\", \"body=hello\"]}\n\n    # mailto:?to=joe@example.com&cc=bob@example.com&body=hello\n    ok << [\"mailto:?to=joe@example.com&cc=bob@example.com&body=hello\"]\n    ok[-1] << [nil, \n      [\"to=joe@example.com\", \"cc=bob@example.com\", \"body=hello\"]]\n    ok[-1] << {:headers => [\"to=joe@example.com\", \n\t\"cc=bob@example.com\", \"body=hello\"]}\n\n    # mailto:gorby%25kremvax@example.com\n    ok << [\"mailto:gorby%25kremvax@example.com\"]\n    ok[-1] << [\"gorby%25kremvax@example.com\", nil]\n    ok[-1] << {:to => \"gorby%25kremvax@example.com\"}\n\n    # mailto:unlikely%3Faddress@example.com?blat=foop\n    ok << [\"mailto:unlikely%3Faddress@example.com?blat=foop\"]\n    ok[-1] << [\"unlikely%3Faddress@example.com\", [\"blat=foop\"]]\n    ok[-1] << {:to => \"unlikely%3Faddress@example.com\", \n      :headers => [\"blat=foop\"]}\n\n    ok_all = ok.flatten.join(\"\\0\")\n\n    # mailto:joe@example.com?cc=bob@example.com?body=hello   ; WRONG!\n    bad << [\"joe@example.com\", [\"cc=bob@example.com?body=hello\"]]\n\n    # mailto:javascript:alert()\n    bad << [\"javascript:alert()\", []]\n\n    # '=' which is in hname or hvalue is wrong.\n    bad << [\"foo@example.jp?subject=1+1=2\", []]\n\n    ok.each do |x|\n      assert_equal(x[0],\n\t\t   @u.build(x[1]).to_s)\n      assert_equal(x[0],\n\t\t   @u.build(x[2]).to_s)\n    end\n\n    bad.each do |x|\n      assert_raises(URI::InvalidComponentError) {\n\t@u.build(x)\n      }\n    end\n\n    assert_equal(ok_all, ok.flatten.join(\"\\0\"))\n  end\n\n  def test_select\n    u = URI.parse('mailto:joe@example.com?cc=bob@example.com&body=hello')\n    assert_equal(uri_to_ary(u), u.select(*u.component))\n    assert_raises(ArgumentError) do\n      u.select(:scheme, :host, :not_exist, :port)\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/webrick/.htaccess",
    "content": "this file should not be published.\n"
  },
  {
    "path": "test/webrick/test_cgi.rb",
    "content": "require \"webrick\"\nrequire File.join(File.dirname(__FILE__), \"utils.rb\")\nrequire \"test/unit\"\n\nclass TestWEBrickCGI < Test::Unit::TestCase\n  def test_cgi\n    accepted = started = stopped = 0\n    requested0 = requested1 = 0\n    config = {\n      :CGIInterpreter => TestWEBrick::RubyBin,\n      :DocumentRoot => File.dirname(__FILE__),\n      :DirectoryIndex => [\"webrick.cgi\"],\n    }\n    if RUBY_PLATFORM =~ /mswin32|mingw|cygwin|bccwin32/\n      config[:CGIPathEnv] = ENV['PATH'] # runtime dll may not be in system dir.\n    end\n    TestWEBrick.start_httpserver(config){|server, addr, port|\n      http = Net::HTTP.new(addr, port)\n      req = Net::HTTP::Get.new(\"/webrick.cgi\")\n      http.request(req){|res| assert_equal(\"/webrick.cgi\", res.body)}\n      req = Net::HTTP::Get.new(\"/webrick.cgi/path/info\")\n      http.request(req){|res| assert_equal(\"/path/info\", res.body)}\n      req = Net::HTTP::Get.new(\"/webrick.cgi/%3F%3F%3F?foo=bar\")\n      http.request(req){|res| assert_equal(\"/???\", res.body)}\n      req = Net::HTTP::Get.new(\"/webrick.cgi/%A4%DB%A4%B2/%A4%DB%A4%B2\")\n      http.request(req){|res|\n        assert_equal(\"/\\xA4\\xDB\\xA4\\xB2/\\xA4\\xDB\\xA4\\xB2\", res.body)}\n      req = Net::HTTP::Get.new(\"/webrick.cgi?a=1;a=2;b=x\")\n      http.request(req){|res| assert_equal(\"a=1, a=2, b=x\", res.body)}\n      req = Net::HTTP::Get.new(\"/webrick.cgi?a=1&a=2&b=x\")\n      http.request(req){|res| assert_equal(\"a=1, a=2, b=x\", res.body)}\n\n      req = Net::HTTP::Post.new(\"/webrick.cgi?a=x;a=y;b=1\")\n      req[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n      http.request(req, \"a=1;a=2;b=x\"){|res|\n        assert_equal(\"a=1, a=2, b=x\", res.body)}\n      req = Net::HTTP::Post.new(\"/webrick.cgi?a=x&a=y&b=1\")\n      req[\"Content-Type\"] = \"application/x-www-form-urlencoded\"\n      http.request(req, \"a=1&a=2&b=x\"){|res|\n        assert_equal(\"a=1, a=2, b=x\", res.body)}\n      req = Net::HTTP::Get.new(\"/\")\n      http.request(req){|res|\n        ary = res.body.to_a\n        assert_match(%r{/$}, ary[0])\n        assert_match(%r{/webrick.cgi$}, ary[1])\n      }\n\n      req = Net::HTTP::Get.new(\"/webrick.cgi\")\n      req[\"Cookie\"] = \"CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001\"\n      http.request(req){|res|\n        assert_equal(\n          \"CUSTOMER=WILE_E_COYOTE\\nPART_NUMBER=ROCKET_LAUNCHER_0001\\n\",\n          res.body)\n      }\n\n      req = Net::HTTP::Get.new(\"/webrick.cgi\")\n      cookie =  %{$Version=\"1\"; }\n      cookie << %{Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; }\n      cookie << %{Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"; }\n      cookie << %{Shipping=\"FedEx\"; $Path=\"/acme\"}\n      req[\"Cookie\"] = cookie\n      http.request(req){|res|\n        assert_equal(\"Customer=WILE_E_COYOTE, Shipping=FedEx\",\n                     res[\"Set-Cookie\"])\n        assert_equal(\"Customer=WILE_E_COYOTE\\n\" +\n                     \"Part_Number=Rocket_Launcher_0001\\n\" +\n                     \"Shipping=FedEx\\n\", res.body)\n      }\n    }\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_cookie.rb",
    "content": "require \"test/unit\"\nrequire \"webrick/cookie\"\n\nclass TestWEBrickCookie < Test::Unit::TestCase\n  def test_new\n    cookie = WEBrick::Cookie.new(\"foo\",\"bar\")\n    assert_equal(\"foo\", cookie.name)\n    assert_equal(\"bar\", cookie.value)\n    assert_equal(\"foo=bar\", cookie.to_s)\n  end\n\n  def test_time\n    cookie = WEBrick::Cookie.new(\"foo\",\"bar\")\n    t = 1000000000\n    cookie.max_age = t\n    assert_match(t.to_s, cookie.to_s)\n\n    cookie = WEBrick::Cookie.new(\"foo\",\"bar\")\n    t = Time.at(1000000000)\n    cookie.expires = t\n    assert_equal(Time, cookie.expires.class)\n    assert_equal(t, cookie.expires)\n    ts = t.httpdate\n    cookie.expires = ts\n    assert_equal(Time, cookie.expires.class)\n    assert_equal(t, cookie.expires)\n    assert_match(ts, cookie.to_s)\n  end\n\n  def test_parse\n    data = \"\"\n    data << '$Version=\"1\"; '\n    data << 'Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"; '\n    data << 'Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\"; '\n    data << 'Shipping=\"FedEx\"; $Path=\"/acme\"'\n    cookies = WEBrick::Cookie.parse(data)\n    assert_equal(1, cookies[0].version)\n    assert_equal(\"Customer\", cookies[0].name)\n    assert_equal(\"WILE_E_COYOTE\", cookies[0].value)\n    assert_equal(\"/acme\", cookies[0].path)\n    assert_equal(1, cookies[1].version)\n    assert_equal(\"Part_Number\", cookies[1].name)\n    assert_equal(\"Rocket_Launcher_0001\", cookies[1].value)\n    assert_equal(1, cookies[2].version)\n    assert_equal(\"Shipping\", cookies[2].name)\n    assert_equal(\"FedEx\", cookies[2].value)\n\n    data = \"hoge=moge; __div__session=9865ecfd514be7f7\"\n    cookies = WEBrick::Cookie.parse(data)\n    assert_equal(0, cookies[0].version)\n    assert_equal(\"hoge\", cookies[0].name)\n    assert_equal(\"moge\", cookies[0].value)\n    assert_equal(\"__div__session\", cookies[1].name)\n    assert_equal(\"9865ecfd514be7f7\", cookies[1].value)\n  end\n\n  def test_parse_set_cookie\n    data = %(Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\")\n    cookie = WEBrick::Cookie.parse_set_cookie(data)\n    assert_equal(\"Customer\", cookie.name)\n    assert_equal(\"WILE_E_COYOTE\", cookie.value)\n    assert_equal(1, cookie.version)\n    assert_equal(\"/acme\", cookie.path)\n\n    data = %(Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"; Secure)\n    cookie = WEBrick::Cookie.parse_set_cookie(data)\n    assert_equal(\"Shipping\", cookie.name)\n    assert_equal(\"FedEx\", cookie.value)\n    assert_equal(1, cookie.version)\n    assert_equal(\"/acme\", cookie.path)\n    assert_equal(true, cookie.secure)\n  end\n\n  def test_parse_set_cookies\n    data = %(Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"; Secure)\n    data << %(, CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT; path=/; Secure)\n    data << %(, name=\"Aaron\"; Version=\"1\"; path=\"/acme\")\n    cookies = WEBrick::Cookie.parse_set_cookies(data)\n    assert_equal(3, cookies.length)\n\n    fed_ex = cookies.find { |c| c.name == 'Shipping' }\n    assert_not_nil(fed_ex)\n    assert_equal(\"Shipping\", fed_ex.name)\n    assert_equal(\"FedEx\", fed_ex.value)\n    assert_equal(1, fed_ex.version)\n    assert_equal(\"/acme\", fed_ex.path)\n    assert_equal(true, fed_ex.secure)\n\n    name = cookies.find { |c| c.name == 'name' }\n    assert_not_nil(name)\n    assert_equal(\"name\", name.name)\n    assert_equal(\"Aaron\", name.value)\n    assert_equal(1, name.version)\n    assert_equal(\"/acme\", name.path)\n\n    customer = cookies.find { |c| c.name == 'CUSTOMER' }\n    assert_not_nil(customer)\n    assert_equal(\"CUSTOMER\", customer.name)\n    assert_equal(\"WILE_E_COYOTE\", customer.value)\n    assert_equal(0, customer.version)\n    assert_equal(\"/\", customer.path)\n    assert_equal(Time.utc(1999, 11, 9, 23, 12, 40), customer.expires)\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_filehandler.rb",
    "content": "require \"test/unit\"\nrequire \"webrick\"\nrequire \"stringio\"\nrequire File.join(File.dirname(__FILE__), \"utils.rb\")\n\nclass WEBrick::TestFileHandler < Test::Unit::TestCase\n  def default_file_handler(filename)\n    klass = WEBrick::HTTPServlet::DefaultFileHandler\n    klass.new(WEBrick::Config::HTTP, filename)\n  end\n\n  def windows?\n    File.directory?(\"\\\\\")\n  end\n\n  def get_res_body(res)\n    return res.body.read rescue res.body\n  end\n\n  def make_range_request(range_spec)\n    msg = <<-_end_of_request_\n      GET / HTTP/1.0\n      Range: #{range_spec}\n\n    _end_of_request_\n    return StringIO.new(msg.gsub(/^ {6}/, \"\"))\n  end\n\n  def make_range_response(file, range_spec)\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(make_range_request(range_spec))\n    res = WEBrick::HTTPResponse.new(WEBrick::Config::HTTP)\n    size = File.size(file)\n    handler = default_file_handler(file)\n    handler.make_partial_content(req, res, file, size)\n    return res\n  end\n\n  def test_make_partial_content\n    filename = __FILE__\n    filesize = File.size(filename)\n\n    res = make_range_response(filename, \"bytes=#{filesize-100}-\")\n    assert_match(%r{^text/plain}, res[\"content-type\"])\n    assert_equal(get_res_body(res).size, 100)\n\n    res = make_range_response(filename, \"bytes=-100\")\n    assert_match(%r{^text/plain}, res[\"content-type\"])\n    assert_equal(get_res_body(res).size, 100)\n\n    res = make_range_response(filename, \"bytes=0-99\")\n    assert_match(%r{^text/plain}, res[\"content-type\"])\n    assert_equal(get_res_body(res).size, 100)\n\n    res = make_range_response(filename, \"bytes=100-199\")\n    assert_match(%r{^text/plain}, res[\"content-type\"])\n    assert_equal(get_res_body(res).size, 100)\n\n    res = make_range_response(filename, \"bytes=0-0\")\n    assert_match(%r{^text/plain}, res[\"content-type\"])\n    assert_equal(get_res_body(res).size, 1)\n\n    res = make_range_response(filename, \"bytes=-1\")\n    assert_match(%r{^text/plain}, res[\"content-type\"])\n    assert_equal(get_res_body(res).size, 1)\n\n    res = make_range_response(filename, \"bytes=0-0, -2\")\n    assert_match(%r{^multipart/byteranges}, res[\"content-type\"])\n  end\n\n  def test_filehandler\n    config = { :DocumentRoot => File.dirname(__FILE__), }\n    this_file = File.basename(__FILE__)\n    TestWEBrick.start_httpserver(config) do |server, addr, port|\n      http = Net::HTTP.new(addr, port)\n      req = Net::HTTP::Get.new(\"/\")\n      http.request(req){|res|\n        assert_equal(\"200\", res.code)\n        assert_equal(\"text/html\", res.content_type)\n        assert_match(/HREF=\"#{this_file}\"/, res.body)\n      }\n      req = Net::HTTP::Get.new(\"/#{this_file}\")\n      http.request(req){|res|\n        assert_equal(\"200\", res.code)\n        assert_equal(\"text/plain\", res.content_type)\n        assert_equal(File.read(__FILE__), res.body)\n      }\n    end\n  end\n\n  def test_non_disclosure_name\n    config = { :DocumentRoot => File.dirname(__FILE__), }\n    this_file = File.basename(__FILE__)\n    TestWEBrick.start_httpserver(config) do |server, addr, port|\n      http = Net::HTTP.new(addr, port)\n      doc_root_opts = server[:DocumentRootOptions]\n      doc_root_opts[:NondisclosureName] = %w(.ht* *~ test_*)\n      req = Net::HTTP::Get.new(\"/\")\n      http.request(req){|res|\n        assert_equal(\"200\", res.code)\n        assert_equal(\"text/html\", res.content_type)\n        assert_no_match(/HREF=\"#{File.basename(__FILE__)}\"/, res.body)\n      }\n      req = Net::HTTP::Get.new(\"/#{this_file}\")\n      http.request(req){|res|\n        assert_equal(\"404\", res.code)\n      }\n      doc_root_opts[:NondisclosureName] = %w(.ht* *~ TEST_*)\n      http.request(req){|res|\n        assert_equal(\"404\", res.code)\n      }\n    end\n  end\n\n  def test_directory_traversal\n    config = { :DocumentRoot => File.dirname(__FILE__), }\n    this_file = File.basename(__FILE__)\n    TestWEBrick.start_httpserver(config) do |server, addr, port|\n      http = Net::HTTP.new(addr, port)\n      req = Net::HTTP::Get.new(\"/../../\")\n      http.request(req){|res| assert_equal(\"400\", res.code) }\n      req = Net::HTTP::Get.new(\"/..%5c../#{File.basename(__FILE__)}\")\n      http.request(req){|res| assert_equal(windows? ? \"200\" : \"404\", res.code) }\n      req = Net::HTTP::Get.new(\"/..%5c..%5cruby.c\")\n      http.request(req){|res| assert_equal(\"404\", res.code) }\n    end\n  end\n\n  def test_unwise_in_path\n    if windows?\n      config = { :DocumentRoot => File.dirname(__FILE__), }\n      this_file = File.basename(__FILE__)\n      TestWEBrick.start_httpserver(config) do |server, addr, port|\n        http = Net::HTTP.new(addr, port)\n        req = Net::HTTP::Get.new(\"/..%5c..\")\n        http.request(req){|res| assert_equal(\"301\", res.code) }\n      end\n    end\n  end\n\n  def test_short_filename\n    config = {\n      :CGIInterpreter => TestWEBrick::RubyBin,\n      :DocumentRoot => File.dirname(__FILE__),\n      :CGIPathEnv => ENV['PATH'],\n    }\n    TestWEBrick.start_httpserver(config) do |server, addr, port|\n      http = Net::HTTP.new(addr, port)\n\n      req = Net::HTTP::Get.new(\"/webric~1.cgi/test\")\n      http.request(req) do |res|\n        if windows?\n          assert_equal(\"200\", res.code)\n          assert_equal(\"/test\", res.body)\n        else\n          assert_equal(\"404\", res.code)\n        end\n      end\n\n      req = Net::HTTP::Get.new(\"/.htaccess\")\n      http.request(req) {|res| assert_equal(\"404\", res.code) }\n      req = Net::HTTP::Get.new(\"/htacce~1\")\n      http.request(req) {|res| assert_equal(\"404\", res.code) }\n      req = Net::HTTP::Get.new(\"/HTACCE~1\")\n      http.request(req) {|res| assert_equal(\"404\", res.code) }\n    end\n  end\n\n  def test_script_disclosure\n    config = {\n      :CGIInterpreter => TestWEBrick::RubyBin,\n      :DocumentRoot => File.dirname(__FILE__),\n      :CGIPathEnv => ENV['PATH'],\n    }\n    TestWEBrick.start_httpserver(config) do |server, addr, port|\n      http = Net::HTTP.new(addr, port)\n\n      req = Net::HTTP::Get.new(\"/webrick.cgi/test\")\n      http.request(req) do |res|\n        assert_equal(\"200\", res.code)\n        assert_equal(\"/test\", res.body)\n      end\n\n      response_assertion = Proc.new do |res|\n        if windows?\n          assert_equal(\"200\", res.code)\n          assert_equal(\"/test\", res.body)\n        else\n          assert_equal(\"404\", res.code)\n        end\n      end\n      req = Net::HTTP::Get.new(\"/webrick.cgi%20/test\")\n      http.request(req, &response_assertion)\n      req = Net::HTTP::Get.new(\"/webrick.cgi./test\")\n      http.request(req, &response_assertion)\n      req = Net::HTTP::Get.new(\"/webrick.cgi::$DATA/test\")\n      http.request(req, &response_assertion)\n    end\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_httpauth.rb",
    "content": "require \"test/unit\"\nrequire \"net/http\"\nrequire \"tempfile\"\nrequire \"webrick\"\nrequire \"webrick/httpauth/basicauth\"\nrequire File.join(File.dirname(__FILE__), \"utils.rb\")\n\nclass TestWEBrickHTTPAuth < Test::Unit::TestCase\n  def test_basic_auth\n    TestWEBrick.start_httpserver{|server, addr, port|\n      realm = \"WEBrick's realm\"\n      path = \"/basic_auth\"\n\n      server.mount_proc(path){|req, res|\n        WEBrick::HTTPAuth.basic_auth(req, res, realm){|user, pass|\n          user == \"webrick\" && pass == \"supersecretpassword\"\n        }     \n        res.body = \"hoge\"\n      }\n      http = Net::HTTP.new(addr, port)\n      g = Net::HTTP::Get.new(path)\n      g.basic_auth(\"webrick\", \"supersecretpassword\")\n      http.request(g){|res| assert_equal(\"hoge\", res.body)}  \n      g.basic_auth(\"webrick\", \"not super\")\n      http.request(g){|res| assert_not_equal(\"hoge\", res.body)}\n    }\n  end\n\n  def test_basic_auth2\n    TestWEBrick.start_httpserver{|server, addr, port|\n      realm = \"WEBrick's realm\"\n      path = \"/basic_auth2\"\n\n      tmpfile = Tempfile.new(\"test_webrick_auth\")\n      tmpfile.close\n      tmp_pass = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)\n      tmp_pass.set_passwd(realm, \"webrick\", \"supersecretpassword\")\n      tmp_pass.set_passwd(realm, \"foo\", \"supersecretpassword\")\n      tmp_pass.flush\n\n      htpasswd = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)\n      users = []\n      htpasswd.each{|user, pass| users << user }\n      assert_equal(2, users.size)\n      assert(users.member?(\"webrick\"))\n      assert(users.member?(\"foo\"))\n\n      server.mount_proc(path){|req, res|\n        auth = WEBrick::HTTPAuth::BasicAuth.new(\n          :Realm => realm, :UserDB => htpasswd,\n          :Logger => server.logger\n        )\n        auth.authenticate(req, res)\n        res.body = \"hoge\"\n      }\n      http = Net::HTTP.new(addr, port)\n      g = Net::HTTP::Get.new(path)\n      g.basic_auth(\"webrick\", \"supersecretpassword\")\n      http.request(g){|res| assert_equal(\"hoge\", res.body)}  \n      g.basic_auth(\"webrick\", \"not super\")\n      http.request(g){|res| assert_not_equal(\"hoge\", res.body)}\n    }\n  end\n\n  def test_basic_auth3\n    tmpfile = Tempfile.new(\"test_webrick_auth\")\n    tmpfile.puts(\"webrick:{SHA}GJYFRpBbdchp595jlh3Bhfmgp8k=\")\n    tmpfile.flush\n    assert_raises(NotImplementedError){\n      WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)\n    }\n    tmpfile.close(true)\n\n    tmpfile = Tempfile.new(\"test_webrick_auth\")\n    tmpfile.puts(\"webrick:$apr1$IOVMD/..$rmnOSPXr0.wwrLPZHBQZy0\")\n    tmpfile.flush\n    assert_raises(NotImplementedError){\n      WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)\n    }\n    tmpfile.close(true)\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_httprequest.rb",
    "content": "require \"webrick\"\nrequire \"stringio\"\nrequire \"test/unit\"\n\nclass TestWEBrickHTTPRequest < Test::Unit::TestCase\n  def test_parse_09\n    msg = <<-_end_of_message_\n      GET /\n      foobar    # HTTP/0.9 request don't have header nor entity body.\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(\"GET\", req.request_method)\n    assert_equal(\"/\", req.unparsed_uri)\n    assert_equal(WEBrick::HTTPVersion.new(\"0.9\"), req.http_version)\n    assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)\n    assert_equal(80, req.port)\n    assert_equal(false, req.keep_alive?)\n    assert_equal(nil, req.body)\n    assert(req.query.empty?)\n  end\n\n  def test_parse_10\n    msg = <<-_end_of_message_\n      GET / HTTP/1.0\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(\"GET\", req.request_method)\n    assert_equal(\"/\", req.unparsed_uri)\n    assert_equal(WEBrick::HTTPVersion.new(\"1.0\"), req.http_version)\n    assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)\n    assert_equal(80, req.port)\n    assert_equal(false, req.keep_alive?)\n    assert_equal(nil, req.body)\n    assert(req.query.empty?)\n  end\n\n  def test_parse_11\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(\"GET\", req.request_method)\n    assert_equal(\"/path\", req.unparsed_uri)\n    assert_equal(\"\", req.script_name)\n    assert_equal(\"/path\", req.path_info)\n    assert_equal(WEBrick::HTTPVersion.new(\"1.1\"), req.http_version)\n    assert_equal(WEBrick::Config::HTTP[:ServerName], req.host)\n    assert_equal(80, req.port)\n    assert_equal(true, req.keep_alive?)\n    assert_equal(nil, req.body)\n    assert(req.query.empty?)\n  end\n\n  def test_parse_headers\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n      Host: test.ruby-lang.org:8080\n      Connection: close\n      Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,\n              text/html;level=2;q=0.4, */*;q=0.5\n      Accept-Encoding: compress;q=0.5\n      Accept-Encoding: gzip;q=1.0, identity; q=0.4, *;q=0\n      Accept-Language: en;q=0.5, *; q=0\n      Accept-Language: ja\n      Content-Type: text/plain\n      Content-Length: 7\n\n      foobar\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(\n      URI.parse(\"http://test.ruby-lang.org:8080/path\"), req.request_uri)\n    assert_equal(\"test.ruby-lang.org\", req.host)\n    assert_equal(8080, req.port)\n    assert_equal(false, req.keep_alive?)\n    assert_equal(\n      %w(text/html;level=1 text/html */* text/html;level=2 text/*),\n      req.accept)\n    assert_equal(%w(gzip compress identity *), req.accept_encoding)\n    assert_equal(%w(ja en *), req.accept_language)\n    assert_equal(7, req.content_length)\n    assert_equal(\"text/plain\", req.content_type)\n    assert_equal(\"foobar\\n\", req.body)\n    assert(req.query.empty?)\n  end\n\n  def test_parse_header2()\n    msg = <<-_end_of_message_\n      POST /foo/bar/../baz?q=a HTTP/1.0\n      Content-Length: 9\n      User-Agent:\n        FOO   BAR\n        BAZ\n\n      hogehoge\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(\"POST\", req.request_method)\n    assert_equal(\"/foo/baz\", req.path)\n    assert_equal(\"\", req.script_name)\n    assert_equal(\"/foo/baz\", req.path_info)\n    assert_equal(\"9\", req['content-length'])\n    assert_equal(\"FOO BAR BAZ\", req['user-agent'])\n    assert_equal(\"hogehoge\\n\", req.body)\n  end\n\n  def test_parse_headers3\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n      Host: test.ruby-lang.org\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(URI.parse(\"http://test.ruby-lang.org/path\"), req.request_uri)\n    assert_equal(\"test.ruby-lang.org\", req.host)\n    assert_equal(80, req.port)\n\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n      Host: 192.168.1.1\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(URI.parse(\"http://192.168.1.1/path\"), req.request_uri)\n    assert_equal(\"192.168.1.1\", req.host)\n    assert_equal(80, req.port)\n\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n      Host: [fe80::208:dff:feef:98c7]\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(URI.parse(\"http://[fe80::208:dff:feef:98c7]/path\"),\n                 req.request_uri)\n    assert_equal(\"[fe80::208:dff:feef:98c7]\", req.host)\n    assert_equal(80, req.port)\n\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n      Host: 192.168.1.1:8080\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(URI.parse(\"http://192.168.1.1:8080/path\"), req.request_uri)\n    assert_equal(\"192.168.1.1\", req.host)\n    assert_equal(8080, req.port)\n\n    msg = <<-_end_of_message_\n      GET /path HTTP/1.1\n      Host: [fe80::208:dff:feef:98c7]:8080\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    assert_equal(URI.parse(\"http://[fe80::208:dff:feef:98c7]:8080/path\"),\n                 req.request_uri)\n    assert_equal(\"[fe80::208:dff:feef:98c7]\", req.host)\n    assert_equal(8080, req.port)\n  end\n\n  def test_parse_get_params\n    param = \"foo=1;foo=2;foo=3;bar=x\"\n    msg = <<-_end_of_message_\n      GET /path?#{param} HTTP/1.1\n      Host: test.ruby-lang.org:8080\n\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    query = req.query\n    assert_equal(\"1\", query[\"foo\"])\n    assert_equal([\"1\", \"2\", \"3\"], query[\"foo\"].to_ary)\n    assert_equal([\"1\", \"2\", \"3\"], query[\"foo\"].list)\n    assert_equal(\"x\", query[\"bar\"])\n    assert_equal([\"x\"], query[\"bar\"].list)\n  end\n\n  def test_parse_post_params\n    param = \"foo=1;foo=2;foo=3;bar=x\"\n    msg = <<-_end_of_message_\n      POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1\n      Host: test.ruby-lang.org:8080\n      Content-Length: #{param.size}\n      Content-Type: application/x-www-form-urlencoded\n\n      #{param}\n    _end_of_message_\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n    query = req.query\n    assert_equal(\"1\", query[\"foo\"])\n    assert_equal([\"1\", \"2\", \"3\"], query[\"foo\"].to_ary)\n    assert_equal([\"1\", \"2\", \"3\"], query[\"foo\"].list)\n    assert_equal(\"x\", query[\"bar\"])\n    assert_equal([\"x\"], query[\"bar\"].list)\n  end\n\n  def test_chunked\n    crlf = \"\\x0d\\x0a\"\n    msg = <<-_end_of_message_\n      POST /path HTTP/1.1\n      Host: test.ruby-lang.org:8080\n      Transfer-Encoding: chunked\n\n    _end_of_message_\n    msg.gsub!(/^ {6}/, \"\")\n    open(__FILE__){|io|\n      while chunk = io.read(100)\n        msg << chunk.size.to_s(16) << crlf\n        msg << chunk << crlf\n      end\n    }\n    msg << \"0\" << crlf\n    req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n    req.parse(StringIO.new(msg))\n    assert_equal(File.read(__FILE__), req.body)\n  end\n\n  def test_bad_messages\n    param = \"foo=1;foo=2;foo=3;bar=x\"\n    msg = <<-_end_of_message_\n      POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1\n      Host: test.ruby-lang.org:8080\n      Content-Type: application/x-www-form-urlencoded\n\n      #{param}\n    _end_of_message_\n    assert_raises(WEBrick::HTTPStatus::LengthRequired){\n      req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n      req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n      req.body\n    }\n\n    msg = <<-_end_of_message_\n      POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1\n      Host: test.ruby-lang.org:8080\n      Content-Length: 100000\n\n      body is too short.\n    _end_of_message_\n    assert_raises(WEBrick::HTTPStatus::BadRequest){\n      req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n      req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n      req.body\n    }\n\n    msg = <<-_end_of_message_\n      POST /path?foo=x;foo=y;foo=z;bar=1 HTTP/1.1\n      Host: test.ruby-lang.org:8080\n      Transfer-Encoding: foobar\n\n      body is too short.\n    _end_of_message_\n    assert_raises(WEBrick::HTTPStatus::NotImplemented){\n      req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)\n      req.parse(StringIO.new(msg.gsub(/^ {6}/, \"\")))\n      req.body\n    }\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_httpserver.rb",
    "content": "require \"test/unit\"\nrequire \"net/http\"\nrequire \"webrick\"\nrequire File.join(File.dirname(__FILE__), \"utils.rb\")\n\nclass TestWEBrickHTTPServer < Test::Unit::TestCase\n  def test_mount\n    httpd = WEBrick::HTTPServer.new(\n      :Logger => WEBrick::Log.new(TestWEBrick::NullWriter),\n      :DoNotListen=>true\n    )\n    httpd.mount(\"/\", :Root)\n    httpd.mount(\"/foo\", :Foo)\n    httpd.mount(\"/foo/bar\", :Bar, :bar1)\n    httpd.mount(\"/foo/bar/baz\", :Baz, :baz1, :baz2)\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/\")\n    assert_equal(:Root, serv)\n    assert_equal([], opts)\n    assert_equal(script_name, \"\")\n    assert_equal(path_info, \"/\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/sub\")\n    assert_equal(:Root, serv)\n    assert_equal([], opts)\n    assert_equal(script_name, \"\")\n    assert_equal(path_info, \"/sub\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/sub/\")\n    assert_equal(:Root, serv)\n    assert_equal([], opts)\n    assert_equal(script_name, \"\")\n    assert_equal(path_info, \"/sub/\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/foo\")\n    assert_equal(:Foo, serv)\n    assert_equal([], opts)\n    assert_equal(script_name, \"/foo\")\n    assert_equal(path_info, \"\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/foo/\")\n    assert_equal(:Foo, serv)\n    assert_equal([], opts)\n    assert_equal(script_name, \"/foo\")\n    assert_equal(path_info, \"/\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/foo/sub\")\n    assert_equal(:Foo, serv)\n    assert_equal([], opts)\n    assert_equal(script_name, \"/foo\")\n    assert_equal(path_info, \"/sub\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/foo/bar\")\n    assert_equal(:Bar, serv)\n    assert_equal([:bar1], opts)\n    assert_equal(script_name, \"/foo/bar\")\n    assert_equal(path_info, \"\")\n\n    serv, opts, script_name, path_info = httpd.search_servlet(\"/foo/bar/baz\")\n    assert_equal(:Baz, serv)\n    assert_equal([:baz1, :baz2], opts)\n    assert_equal(script_name, \"/foo/bar/baz\")\n    assert_equal(path_info, \"\")\n  end\n\n  class Req\n    attr_reader :port, :host\n    def initialize(addr, port, host)\n      @addr, @port, @host = addr, port, host\n    end\n    def addr\n      [0,0,0,@addr]\n    end\n  end\n\n  def httpd(addr, port, host, ali)\n    config ={\n      :Logger      => WEBrick::Log.new(TestWEBrick::NullWriter),\n      :DoNotListen => true,\n      :BindAddress => addr,\n      :Port        => port,\n      :ServerName  => host,\n      :ServerAlias => ali,\n    }\n    return WEBrick::HTTPServer.new(config)\n  end\n\n  def assert_eql?(v1, v2)\n    assert_equal(v1.object_id, v2.object_id)\n  end\n\n  def test_lookup_server\n    addr1  = \"192.168.100.1\"\n    addr2  = \"192.168.100.2\"\n    addrz  = \"192.168.100.254\"\n    local  = \"127.0.0.1\"\n    port1  = 80\n    port2  = 8080\n    port3  = 10080\n    portz  = 32767\n    name1  = \"www.example.com\"\n    name2  = \"www2.example.com\"\n    name3  = \"www3.example.com\"\n    namea  = \"www.example.co.jp\"\n    nameb  = \"www.example.jp\"\n    namec  = \"www2.example.co.jp\"\n    named  = \"www2.example.jp\"\n    namez  = \"foobar.example.com\"\n    alias1 = [namea, nameb]\n    alias2 = [namec, named]\n\n    host1 = httpd(nil, port1, name1, nil)\n    hosts = [\n      host2  = httpd(addr1, port1, name1, nil),\n      host3  = httpd(addr1, port1, name2, alias1),\n      host4  = httpd(addr1, port2, name1, nil),\n      host5  = httpd(addr1, port2, name2, alias1),\n      host6  = httpd(addr1, port2, name3, alias2),\n      host7  = httpd(addr2, nil,   name1, nil),\n      host8  = httpd(addr2, nil,   name2, alias1),\n      host9  = httpd(addr2, nil,   name3, alias2),\n      host10 = httpd(local, nil,   nil,   nil),\n      host11 = httpd(nil,   port3, nil,   nil),\n    ].sort_by{ rand }\n    hosts.each{|h| host1.virtual_host(h) }\n\n    # connect to addr1\n    assert_eql?(host2,   host1.lookup_server(Req.new(addr1, port1, name1)))\n    assert_eql?(host3,   host1.lookup_server(Req.new(addr1, port1, name2)))\n    assert_eql?(host3,   host1.lookup_server(Req.new(addr1, port1, namea)))\n    assert_eql?(host3,   host1.lookup_server(Req.new(addr1, port1, nameb)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, port1, namez)))\n    assert_eql?(host4,   host1.lookup_server(Req.new(addr1, port2, name1)))\n    assert_eql?(host5,   host1.lookup_server(Req.new(addr1, port2, name2)))\n    assert_eql?(host5,   host1.lookup_server(Req.new(addr1, port2, namea)))\n    assert_eql?(host5,   host1.lookup_server(Req.new(addr1, port2, nameb)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, port2, namez)))\n    assert_eql?(host11,  host1.lookup_server(Req.new(addr1, port3, name1)))\n    assert_eql?(host11,  host1.lookup_server(Req.new(addr1, port3, name2)))\n    assert_eql?(host11,  host1.lookup_server(Req.new(addr1, port3, namea)))\n    assert_eql?(host11,  host1.lookup_server(Req.new(addr1, port3, nameb)))\n    assert_eql?(host11,  host1.lookup_server(Req.new(addr1, port3, namez)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, portz, name1)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, portz, name2)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, portz, namea)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, portz, nameb)))\n    assert_eql?(nil,     host1.lookup_server(Req.new(addr1, portz, namez)))\n\n    # connect to addr2\n    assert_eql?(host7,  host1.lookup_server(Req.new(addr2, port1, name1)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port1, name2)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port1, namea)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port1, nameb)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addr2, port1, namez)))\n    assert_eql?(host7,  host1.lookup_server(Req.new(addr2, port2, name1)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port2, name2)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port2, namea)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port2, nameb)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addr2, port2, namez)))\n    assert_eql?(host7,  host1.lookup_server(Req.new(addr2, port3, name1)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port3, name2)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port3, namea)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, port3, nameb)))\n    assert_eql?(host11, host1.lookup_server(Req.new(addr2, port3, namez)))\n    assert_eql?(host7,  host1.lookup_server(Req.new(addr2, portz, name1)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, portz, name2)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, portz, namea)))\n    assert_eql?(host8,  host1.lookup_server(Req.new(addr2, portz, nameb)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addr2, portz, namez)))\n\n    # connect to addrz\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port1, name1)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port1, name2)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port1, namea)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port1, nameb)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port1, namez)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port2, name1)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port2, name2)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port2, namea)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port2, nameb)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, port2, namez)))\n    assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name1)))\n    assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name2)))\n    assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namea)))\n    assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, nameb)))\n    assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namez)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, portz, name1)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, portz, name2)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, portz, namea)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, portz, nameb)))\n    assert_eql?(nil,    host1.lookup_server(Req.new(addrz, portz, namez)))\n\n    # connect to localhost\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name1)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name2)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namea)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port1, nameb)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namez)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name1)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name2)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namea)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port2, nameb)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namez)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name1)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name2)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namea)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port3, nameb)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namez)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name1)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name2)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namea)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, portz, nameb)))\n    assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namez)))\n  end\n\n  def test_callbacks\n    accepted = started = stopped = 0\n    requested0 = requested1 = 0\n    config = {\n      :ServerName => \"localhost\",\n      :AcceptCallback => Proc.new{ accepted += 1 },\n      :StartCallback => Proc.new{ started += 1 },\n      :StopCallback => Proc.new{ stopped += 1 },\n      :RequestCallback => Proc.new{|req, res| requested0 += 1 },\n    }\n    TestWEBrick.start_httpserver(config){|server, addr, port|\n      vhost_config = {\n        :ServerName => \"myhostname\",\n        :BindAddress => addr,\n        :Port => port,\n        :DoNotListen => true,\n        :Logger => WEBrick::Log.new(TestWEBrick::NullWriter),\n        :AccessLog => [],\n        :RequestCallback => Proc.new{|req, res| requested1 += 1 },\n      }\n      server.virtual_host(WEBrick::HTTPServer.new(vhost_config))\n\n      true while server.status != :Running\n      assert_equal(started, 1)\n      assert_equal(stopped, 0)\n      assert_equal(accepted, 0)\n\n      http = Net::HTTP.new(addr, port)\n      req = Net::HTTP::Get.new(\"/\")\n      req[\"Host\"] = \"myhostname:#{port}\"\n      http.request(req){|res| assert_equal(\"404\", res.code)}\n      http.request(req){|res| assert_equal(\"404\", res.code)}\n      http.request(req){|res| assert_equal(\"404\", res.code)}\n      req[\"Host\"] = \"localhost:#{port}\"\n      http.request(req){|res| assert_equal(\"404\", res.code)}\n      http.request(req){|res| assert_equal(\"404\", res.code)}\n      http.request(req){|res| assert_equal(\"404\", res.code)}\n      assert_equal(6, accepted)\n      assert_equal(3, requested0)\n      assert_equal(3, requested1)\n    }\n    assert_equal(started, 1)\n    assert_equal(stopped, 1)\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_httputils.rb",
    "content": "require \"test/unit\"\nrequire \"webrick/httputils\"\n\nclass TestWEBrickHTTPUtils < Test::Unit::TestCase\n  include WEBrick::HTTPUtils\n\n  def test_normilize_path\n    assert_equal(\"/foo\",       normalize_path(\"/foo\"))\n    assert_equal(\"/foo/bar/\",  normalize_path(\"/foo/bar/\"))\n\n    assert_equal(\"/\",          normalize_path(\"/foo/../\"))\n    assert_equal(\"/\",          normalize_path(\"/foo/..\"))\n    assert_equal(\"/\",          normalize_path(\"/foo/bar/../../\"))\n    assert_equal(\"/\",          normalize_path(\"/foo/bar/../..\"))\n    assert_equal(\"/\",          normalize_path(\"/foo/bar/../..\"))\n    assert_equal(\"/baz\",       normalize_path(\"/foo/bar/../../baz\"))\n    assert_equal(\"/baz\",       normalize_path(\"/foo/../bar/../baz\"))\n    assert_equal(\"/baz/\",      normalize_path(\"/foo/../bar/../baz/\"))\n    assert_equal(\"/...\",       normalize_path(\"/bar/../...\"))\n    assert_equal(\"/.../\",      normalize_path(\"/bar/../.../\"))\n\n    assert_equal(\"/foo/\",      normalize_path(\"/foo/./\"))\n    assert_equal(\"/foo/\",      normalize_path(\"/foo/.\"))\n    assert_equal(\"/foo/\",      normalize_path(\"/foo/././\"))\n    assert_equal(\"/foo/\",      normalize_path(\"/foo/./.\"))\n    assert_equal(\"/foo/bar\",   normalize_path(\"/foo/./bar\"))\n    assert_equal(\"/foo/bar/\",  normalize_path(\"/foo/./bar/.\"))\n    assert_equal(\"/foo/bar/\",  normalize_path(\"/./././foo/./bar/.\"))\n\n    assert_equal(\"/foo/bar/\",  normalize_path(\"//foo///.//bar/.///.//\"))\n    assert_equal(\"/\",          normalize_path(\"//foo///..///bar/.///..//.//\"))\n\n    assert_raises(RuntimeError){ normalize_path(\"foo/bar\") }\n    assert_raises(RuntimeError){ normalize_path(\"..\") }\n    assert_raises(RuntimeError){ normalize_path(\"/..\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./..\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./../..\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./../../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/../..\") }\n    assert_raises(RuntimeError){ normalize_path(\"/../../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/../../..\") }\n    assert_raises(RuntimeError){ normalize_path(\"/../../../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/../foo/../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/../foo/../../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/foo/bar/../../../../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/foo/../bar/../../\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./../bar/\") }\n    assert_raises(RuntimeError){ normalize_path(\"/./../\") }\n  end\n\n  def test_split_header_value\n    assert_equal(['foo', 'bar'], split_header_value('foo, bar'))\n    assert_equal(['\"foo\"', 'bar'], split_header_value('\"foo\", bar'))\n    assert_equal(['foo', '\"bar\"'], split_header_value('foo, \"bar\"'))\n    assert_equal(['*'], split_header_value('*'))\n    assert_equal(['W/\"xyzzy\"', 'W/\"r2d2xxxx\"', 'W/\"c3piozzzz\"'],\n                 split_header_value('W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\"'))\n  end\n\n  def test_escape\n    assert_equal(\"/foo/bar\", escape(\"/foo/bar\"))\n    assert_equal(\"/~foo/bar\", escape(\"/~foo/bar\"))\n    assert_equal(\"/~foo%20bar\", escape(\"/~foo bar\"))\n    assert_equal(\"/~foo%20bar\", escape(\"/~foo bar\"))\n    assert_equal(\"/~foo%09bar\", escape(\"/~foo\\tbar\"))\n    assert_equal(\"/~foo+bar\", escape(\"/~foo+bar\"))\n  end\n\n  def test_escape_form\n    assert_equal(\"%2Ffoo%2Fbar\", escape_form(\"/foo/bar\"))\n    assert_equal(\"%2F~foo%2Fbar\", escape_form(\"/~foo/bar\"))\n    assert_equal(\"%2F~foo+bar\", escape_form(\"/~foo bar\"))\n    assert_equal(\"%2F~foo+%2B+bar\", escape_form(\"/~foo + bar\"))\n  end\n\n  def test_unescape\n    assert_equal(\"/foo/bar\", unescape(\"%2ffoo%2fbar\"))\n    assert_equal(\"/~foo/bar\", unescape(\"/%7efoo/bar\"))\n    assert_equal(\"/~foo/bar\", unescape(\"%2f%7efoo%2fbar\"))\n    assert_equal(\"/~foo+bar\", unescape(\"/%7efoo+bar\"))\n  end\n\n  def test_unescape_form\n    assert_equal(\"//foo/bar\", unescape_form(\"/%2Ffoo/bar\"))\n    assert_equal(\"//foo/bar baz\", unescape_form(\"/%2Ffoo/bar+baz\"))\n    assert_equal(\"/~foo/bar baz\", unescape_form(\"/%7Efoo/bar+baz\"))\n  end\n\n  def test_escape_path\n    assert_equal(\"/foo/bar\", escape_path(\"/foo/bar\"))\n    assert_equal(\"/foo/bar/\", escape_path(\"/foo/bar/\"))\n    assert_equal(\"/%25foo/bar/\", escape_path(\"/%foo/bar/\"))\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_httpversion.rb",
    "content": "require \"test/unit\"\nrequire \"webrick/httpversion\"\n\nclass TestWEBrickHTTPVersion < Test::Unit::TestCase\n  def setup\n    @v09 = WEBrick::HTTPVersion.new(\"0.9\")\n    @v10 = WEBrick::HTTPVersion.new(\"1.0\")\n    @v11 = WEBrick::HTTPVersion.new(\"1.001\")\n  end\n\n  def test_to_s()\n    assert_equal(\"0.9\", @v09.to_s)\n    assert_equal(\"1.0\", @v10.to_s)\n    assert_equal(\"1.1\", @v11.to_s)\n  end\n\n  def test_major()\n    assert_equal(0, @v09.major)\n    assert_equal(1, @v10.major)\n    assert_equal(1, @v11.major)\n  end\n\n  def test_minor()\n    assert_equal(9, @v09.minor)\n    assert_equal(0, @v10.minor)\n    assert_equal(1, @v11.minor)\n  end\n\n  def test_compar()\n    assert_equal(0, @v09 <=> \"0.9\")\n    assert_equal(0, @v09 <=> \"0.09\")\n\n    assert_equal(-1, @v09 <=> @v10)\n    assert_equal(-1, @v09 <=> \"1.00\")\n\n    assert_equal(1, @v11 <=> @v09)\n    assert_equal(1, @v11 <=> \"1.0\")\n    assert_equal(1, @v11 <=> \"0.9\")\n  end\nend\n"
  },
  {
    "path": "test/webrick/test_server.rb",
    "content": "require \"test/unit\"\nrequire \"tempfile\"\nrequire \"webrick\"\nrequire File.join(File.dirname(__FILE__), \"utils.rb\")\n\nclass TestWEBrickServer < Test::Unit::TestCase\n  class Echo < WEBrick::GenericServer\n    def run(sock)\n      while line = sock.gets\n        sock << line\n      end\n    end\n  end\n\n  def test_server\n    TestWEBrick.start_server(Echo){|server, addr, port|\n      TCPSocket.open(addr, port){|sock|\n        sock.puts(\"foo\"); assert_equal(\"foo\\n\", sock.gets)\n        sock.puts(\"bar\"); assert_equal(\"bar\\n\", sock.gets)\n        sock.puts(\"baz\"); assert_equal(\"baz\\n\", sock.gets)\n        sock.puts(\"qux\"); assert_equal(\"qux\\n\", sock.gets)\n      }\n    }\n  end\n\n  def test_callbacks\n    accepted = started = stopped = 0\n    config = {\n      :AcceptCallback => Proc.new{ accepted += 1 },\n      :StartCallback => Proc.new{ started += 1 },\n      :StopCallback => Proc.new{ stopped += 1 },\n    }\n    TestWEBrick.start_server(Echo, config){|server, addr, port|\n      true while server.status != :Running\n      assert_equal(started, 1)\n      assert_equal(stopped, 0)\n      assert_equal(accepted, 0)\n      TCPSocket.open(addr, port){|sock| (sock << \"foo\\n\").gets }\n      TCPSocket.open(addr, port){|sock| (sock << \"foo\\n\").gets }\n      TCPSocket.open(addr, port){|sock| (sock << \"foo\\n\").gets }\n      assert_equal(accepted, 3)\n    }\n    assert_equal(started, 1)\n    assert_equal(stopped, 1)\n  end\n\n  def test_daemon\n    begin\n      r, w = IO.pipe\n      Process.fork{\n        r.close\n        WEBrick::Daemon.start\n        w.puts(Process.pid)\n        sleep\n      }\n      assert(Process.kill(:KILL, r.gets.to_i))\n    rescue NotImplementedError\n      # snip this test\n    ensure\n      r.close\n      w.close\n    end\n  end\nend\n"
  },
  {
    "path": "test/webrick/utils.rb",
    "content": "begin\n  loadpath = $:.dup\n  $:.replace($: | [File.expand_path(\"../ruby\", File.dirname(__FILE__))])\n  require 'envutil'\nensure\n  $:.replace(loadpath)\nend\nrequire \"webrick\"\nbegin\n  require \"webrick/https\"\nrescue LoadError\nend\nrequire \"webrick/httpproxy\"\n\nmodule TestWEBrick\n  NullWriter = Object.new\n  def NullWriter.<<(msg)\n    puts msg if $DEBUG\n    return self\n  end\n\n  RubyBin = \"\\\"#{EnvUtil.rubybin}\\\"\"\n  RubyBin << \" \\\"-I#{File.expand_path(\"../..\", File.dirname(__FILE__))}/lib\\\"\"\n  RubyBin << \" \\\"-I#{File.dirname(EnvUtil.rubybin)}/.ext/common\\\"\"\n  RubyBin << \" \\\"-I#{File.dirname(EnvUtil.rubybin)}/.ext/#{RUBY_PLATFORM}\\\"\"\n\n  module_function\n\n  def start_server(klass, config={}, &block)\n    server = klass.new({\n      :BindAddress => \"127.0.0.1\", :Port => 0,\n      :Logger => WEBrick::Log.new(NullWriter),\n      :AccessLog => [[NullWriter, \"\"]]\n    }.update(config))\n    begin\n      thread = Thread.start{ server.start }\n      addr = server.listeners[0].addr\n      block.call([server, addr[3], addr[1]])\n    ensure\n      server.stop\n      thread.join\n    end\n  end\n\n  def start_httpserver(config={}, &block)\n    start_server(WEBrick::HTTPServer, config, &block)\n  end\n\n  def start_httpproxy(config={}, &block)\n    start_server(WEBrick::HTTPProxyServer, config, &block)\n  end\nend\n"
  },
  {
    "path": "test/webrick/webrick.cgi",
    "content": "#!ruby -d\nrequire \"webrick/cgi\"\n\nclass TestApp < WEBrick::CGI\n  def do_GET(req, res)\n    res[\"content-type\"] = \"text/plain\"\n    if (p = req.path_info) && p.length > 0\n      res.body = p\n    elsif (q = req.query).size > 0\n      res.body = q.keys.sort.collect{|key|\n        q[key].list.sort.collect{|v|\n          \"#{key}=#{v}\"\n        }.join(\", \")\n      }.join(\", \")\n    elsif %r{/$} =~ req.request_uri.to_s\n      res.body = \"\"\n      res.body << req.request_uri.to_s  << \"\\n\"\n      res.body << req.script_name\n    elsif !req.cookies.empty?\n      res.body = req.cookies.inject(\"\"){|result, cookie|\n        result << \"%s=%s\\n\" % [cookie.name, cookie.value]\n      }\n      res.cookies << WEBrick::Cookie.new(\"Customer\", \"WILE_E_COYOTE\")\n      res.cookies << WEBrick::Cookie.new(\"Shipping\", \"FedEx\")\n    else\n      res.body = req.script_name\n    end\n  end\n\n  def do_POST(req, res)\n    do_GET(req, res)\n  end\nend\n\ncgi = TestApp.new\ncgi.start\n"
  },
  {
    "path": "test/webrick/webrick_long_filename.cgi",
    "content": "#!ruby -d\nrequire \"webrick/cgi\"\n\nclass TestApp < WEBrick::CGI\n  def do_GET(req, res)\n    res[\"content-type\"] = \"text/plain\"\n    if (p = req.path_info) && p.length > 0\n      res.body = p\n    elsif (q = req.query).size > 0\n      res.body = q.keys.sort.collect{|key|\n        q[key].list.sort.collect{|v|\n          \"#{key}=#{v}\"\n        }.join(\", \")\n      }.join(\", \")\n    elsif %r{/$} =~ req.request_uri.to_s\n      res.body = \"\"\n      res.body << req.request_uri.to_s  << \"\\n\"\n      res.body << req.script_name\n    elsif !req.cookies.empty?\n      res.body = req.cookies.inject(\"\"){|result, cookie|\n        result << \"%s=%s\\n\" % [cookie.name, cookie.value]\n      }\n      res.cookies << WEBrick::Cookie.new(\"Customer\", \"WILE_E_COYOTE\")\n      res.cookies << WEBrick::Cookie.new(\"Shipping\", \"FedEx\")\n    else\n      res.body = req.script_name\n    end\n  end\n\n  def do_POST(req, res)\n    do_GET(req, res)\n  end\nend\n\ncgi = TestApp.new\ncgi.start\n"
  },
  {
    "path": "test/wsdl/any/any.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name=\"echo\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:example.com:echo\"\n    xmlns:txd=\"urn:example.com:echo-type\"\n    targetNamespace=\"urn:example.com:echo\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema targetNamespace=\"urn:example.com:echo-type\">\n      <xsd:complexType name=\"foo.bar\">\n        <xsd:sequence>\n          <xsd:any />\n        </xsd:sequence>\n      </xsd:complexType>\n    </xsd:schema>\n  </types>\n\n  <message name=\"msg_echoitem\">\n    <part name=\"echoitem\" type=\"txd:foo.bar\"/>\n  </message>\n\n  <portType name=\"echo_port_type\">\n    <operation name=\"echo\">\n      <input message=\"tns:msg_echoitem\"/>\n      <output message=\"tns:msg_echoitem\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"echo_binding\" type=\"tns:echo_port_type\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"rpc\"/>\n    <operation name=\"echo\">\n      <soap:operation soapAction=\"urn:example.com:echo\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:echo\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:echo\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"echo_service\">\n    <port name=\"echo_port\" binding=\"tns:echo_binding\">\n      <soap:address location=\"http://localhost:10080\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/any/expectedDriver.rb",
    "content": "require 'echo.rb'\n\nrequire 'soap/rpc/driver'\n\nclass Echo_port_type < ::SOAP::RPC::Driver\n  DefaultEndpointUrl = \"http://localhost:10080\"\n  MappingRegistry = ::SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    FooBar,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"urn:example.com:echo-type\", \"foo.bar\") }\n  )\n\n  Methods = [\n    [ XSD::QName.new(\"urn:example.com:echo\", \"echo\"),\n      \"urn:example.com:echo\",\n      \"echo\",\n      [ [\"in\", \"echoitem\", [\"FooBar\", \"urn:example.com:echo-type\", \"foo.bar\"]],\n        [\"retval\", \"echoitem\", [\"FooBar\", \"urn:example.com:echo-type\", \"foo.bar\"]] ],\n      { :request_style =>  :rpc, :request_use =>  :encoded,\n        :response_style => :rpc, :response_use => :encoded }\n    ]\n  ]\n\n  def initialize(endpoint_url = nil)\n    endpoint_url ||= DefaultEndpointUrl\n    super(endpoint_url, nil)\n    self.mapping_registry = MappingRegistry\n    init_methods\n  end\n\nprivate\n\n  def init_methods\n    Methods.each do |definitions|\n      opt = definitions.last\n      if opt[:request_style] == :document\n        add_document_operation(*definitions)\n      else\n        add_rpc_operation(*definitions)\n        qname = definitions[0]\n        name = definitions[2]\n        if qname.name != name and qname.name.capitalize == name.capitalize\n          ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|\n            __send__(name, *arg)\n          end\n        end\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "test/wsdl/any/expectedEcho.rb",
    "content": "require 'xsd/qname'\n\n# {urn:example.com:echo-type}foo.bar\nclass FooBar\n  @@schema_type = \"foo.bar\"\n  @@schema_ns = \"urn:example.com:echo-type\"\n  @@schema_element = [[\"any\", [nil, XSD::QName.new(nil, \"any\")]]]\n\n  attr_accessor :any\n\n  def initialize(any = nil)\n    @any = any\n  end\nend\n"
  },
  {
    "path": "test/wsdl/any/expectedService.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'echoServant.rb'\n\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/mapping/registry'\n\nclass Echo_port_type\n  MappingRegistry = ::SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    FooBar,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"urn:example.com:echo-type\", \"foo.bar\") }\n  )\n\n  Methods = [\n    [ XSD::QName.new(\"urn:example.com:echo\", \"echo\"),\n      \"urn:example.com:echo\",\n      \"echo\",\n      [ [\"in\", \"echoitem\", [\"FooBar\", \"urn:example.com:echo-type\", \"foo.bar\"]],\n        [\"retval\", \"echoitem\", [\"FooBar\", \"urn:example.com:echo-type\", \"foo.bar\"]] ],\n      { :request_style =>  :rpc, :request_use =>  :encoded,\n        :response_style => :rpc, :response_use => :encoded }\n    ]\n  ]\nend\n\nclass Echo_port_typeApp < ::SOAP::RPC::StandaloneServer\n  def initialize(*arg)\n    super(*arg)\n    servant = Echo_port_type.new\n    Echo_port_type::Methods.each do |definitions|\n      opt = definitions.last\n      if opt[:request_style] == :document\n        @router.add_document_operation(servant, *definitions)\n      else\n        @router.add_rpc_operation(servant, *definitions)\n      end\n    end\n    self.mapping_registry = Echo_port_type::MappingRegistry\n  end\nend\n\nif $0 == __FILE__\n  # Change listen port.\n  server = Echo_port_typeApp.new('app', nil, '0.0.0.0', 10080)\n  trap(:INT) do\n    server.shutdown\n  end\n  server.start\nend\n"
  },
  {
    "path": "test/wsdl/any/test_any.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/wsdl2ruby'\nmodule WSDL; module Any\n\n\nclass TestAny < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def test_any\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"any.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['driver'] = nil\n    gen.opt['client_skelton'] = nil\n    gen.opt['servant_skelton'] = nil\n    gen.opt['standalone_server_stub'] = nil\n    gen.opt['force'] = true\n    suppress_warning do\n      gen.run\n    end\n    compare(\"expectedDriver.rb\", \"echoDriver.rb\")\n    compare(\"expectedEcho.rb\", \"echo.rb\")\n    compare(\"expectedService.rb\", \"echo_service.rb\")\n\n    File.unlink(pathname(\"echo_service.rb\"))\n    File.unlink(pathname(\"echo.rb\"))\n    File.unlink(pathname(\"echo_serviceClient.rb\"))\n    File.unlink(pathname(\"echoDriver.rb\"))\n    File.unlink(pathname(\"echoServant.rb\"))\n  end\n\n  def compare(expected, actual)\n    assert_equal(loadfile(expected), loadfile(actual), actual)\n  end\n\n  def loadfile(file)\n    File.open(pathname(file)) { |f| f.read }\n  end\n\n  def suppress_warning\n    back = $VERBOSE\n    $VERBOSE = nil\n    begin\n      yield\n    ensure\n      $VERBOSE = back\n    end\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/wsdl/axisArray/axisArray.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<wsdl:definitions name = \"itemList\"\n    targetNamespace=\"urn:jp.gr.jin.rrr.example.itemList\"\n    xmlns:tns=\"urn:jp.gr.jin.rrr.example.itemList\"\n    xmlns:typens=\"urn:jp.gr.jin.rrr.example.itemListType\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n  <wsdl:types>\n    <schema targetNamespace=\"urn:jp.gr.jin.rrr.example.itemListType\"\n\txmlns=\"http://www.w3.org/2001/XMLSchema\">\n      <import namespace=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      <complexType name=\"Item\">\n        <sequence>\n          <element name=\"name\" type=\"xsd:string\"/>\n        </sequence>\n      </complexType>\n      <complexType name=\"ItemList\">\n        <sequence>\n          <element maxOccurs=\"unbounded\" minOccurs=\"0\" name=\"Item\" type=\"typens:Item\"/>\n        </sequence>\n      </complexType>\n    </schema>\n  </wsdl:types>\n\n  <wsdl:message name=\"listItemRequest\"/>\n\n  <wsdl:message name=\"listItemResponse\">\n    <wsdl:part name=\"list\" type=\"typens:ItemList\"/>\n  </wsdl:message>\n\n  <wsdl:portType name=\"ItemListPortType\">\n    <wsdl:operation name=\"listItem\">\n      <wsdl:input message=\"tns:listItemRequest\" name=\"listItemRequest\"/>\n      <wsdl:output message=\"tns:listItemResponse\" name=\"listItemResponse\"/>\n    </wsdl:operation>\n  </wsdl:portType>\n\n  <wsdl:binding name=\"ItemListBinding\" type=\"tns:ItemListPortType\">\n    <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n    <wsdl:operation name=\"listItem\">\n      <soap:operation soapAction=\"\"/>\n      <wsdl:input name=\"listItemRequest\">\n\t<soap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:jp.gr.jin.rrr.example.itemList\" use=\"encoded\"/>\n      </wsdl:input>\n      <wsdl:output name=\"listItemResponse\">\n\t<soap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:jp.gr.jin.rrr.example.itemList\" use=\"encoded\"/>\n      </wsdl:output>\n    </wsdl:operation>\n  </wsdl:binding>\n\n  <wsdl:service name=\"ItemListService\">\n    <wsdl:port binding=\"tns:ItemListBinding\" name=\"ItemListPort\">\n      <soap:address location=\"http://localhost:10080/\"/>\n    </wsdl:port>\n  </wsdl:service>\n</wsdl:definitions>\n"
  },
  {
    "path": "test/wsdl/axisArray/itemList.rb",
    "content": "# Generated by wsdl2ruby.rb with axisArray.wsdl.\n\n# urn:jp.gr.jin.rrr.example.itemListType\nclass Item\n  @@schema_type = \"Item\"\n  @@schema_ns = \"urn:jp.gr.jin.rrr.example.itemListType\"\n\n  def name\n    @name\n  end\n\n  def name=(value)\n    @name = value\n  end\n\n  def initialize(name = nil)\n    @name = name\n  end\nend\n\n# urn:jp.gr.jin.rrr.example.itemListType\nclass ItemList < Array\n  # Contents type should be dumped here...\n  @@schema_type = \"ItemList\"\n  @@schema_ns = \"urn:jp.gr.jin.rrr.example.itemListType\"\nend\n\n"
  },
  {
    "path": "test/wsdl/axisArray/test_axisarray.rb",
    "content": "require 'test/unit'\nrequire 'soap/processor'\nrequire 'soap/mapping'\nrequire 'soap/rpc/element'\nrequire 'wsdl/importer'\nrequire 'itemList.rb'\n\n\nmodule WSDL\n\n\nclass TestAxisArray < Test::Unit::TestCase\n  def setup\n    @xml =<<__EOX__\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <soapenv:Body>\n    <ns1:listItemResponse soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"urn:jp.gr.jin.rrr.example.itemList\">\n      <list href=\"#id0\"/>\n    </ns1:listItemResponse>\n    <multiRef id=\"id0\" soapenc:root=\"0\" soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xsi:type=\"ns2:ItemList\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns2=\"urn:jp.gr.jin.rrr.example.itemListType\">\n      <Item href=\"#id1\"/>\n      <Item href=\"#id2\"/>\n      <Item href=\"#id3\"/>\n    </multiRef>\n    <multiRef id=\"id3\" soapenc:root=\"0\" soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xsi:type=\"ns3:Item\" xmlns:ns3=\"urn:jp.gr.jin.rrr.example.itemListType\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <name xsi:type=\"xsd:string\">name3</name>\n    </multiRef>\n    <multiRef id=\"id1\" soapenc:root=\"0\" soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xsi:type=\"ns4:Item\" xmlns:ns4=\"urn:jp.gr.jin.rrr.example.itemListType\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <name xsi:type=\"xsd:string\">name1</name>\n    </multiRef>\n    <multiRef id=\"id2\" soapenc:root=\"0\" soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xsi:type=\"ns5:Item\" xmlns:ns5=\"urn:jp.gr.jin.rrr.example.itemListType\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <name xsi:type=\"xsd:string\">name2</name>\n    </multiRef>\n  </soapenv:Body>\n</soapenv:Envelope>\n__EOX__\n  end\n\n  def test_by_stub\n    header, body = ::SOAP::Processor.unmarshal(@xml)\n    ary = ::SOAP::Mapping.soap2obj(body.response)\n    assert_equal(3, ary.size)\n    assert_equal(\"name1\", ary[0].name)\n    assert_equal(\"name2\", ary[1].name)\n    assert_equal(\"name3\", ary[2].name)\n  end\n\n  def test_by_wsdl\n    wsdlfile = File.join(File.dirname(File.expand_path(__FILE__)), 'axisArray.wsdl')\n    wsdl = WSDL::Importer.import(wsdlfile)\n    service = wsdl.services[0]\n    port = service.ports[0]\n    wsdl_types = wsdl.collect_complextypes\n    rpc_decode_typemap = wsdl_types + wsdl.soap_rpc_complextypes(port.find_binding)\n    opt = {}\n    opt[:default_encodingstyle] = ::SOAP::EncodingNamespace\n    opt[:decode_typemap] = rpc_decode_typemap\n    header, body = ::SOAP::Processor.unmarshal(@xml, opt)\n    ary = ::SOAP::Mapping.soap2obj(body.response)\n    assert_equal(3, ary.size)\n    assert_equal(\"name1\", ary[0].name)\n    assert_equal(\"name2\", ary[1].name)\n    assert_equal(\"name3\", ary[2].name)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/wsdl/datetime/DatetimeService.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'datetimeServant.rb'\n\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/mapping/registry'\n\nclass DatetimePortType\n  MappingRegistry = ::SOAP::Mapping::Registry.new\n\n  Methods = [\n    [\"now\", \"now\",\n      [\n        [\"in\", \"now\", [::SOAP::SOAPDateTime]],\n        [\"retval\", \"now\", [::SOAP::SOAPDateTime]]\n      ],\n      \"\", \"urn:jp.gr.jin.rrr.example.datetime\", :rpc\n    ]\n  ]\nend\n\nclass DatetimePortTypeApp < ::SOAP::RPC::StandaloneServer\n  def initialize(*arg)\n    super(*arg)\n    servant = DatetimePortType.new\n    DatetimePortType::Methods.each do |name_as, name, param_def, soapaction, namespace, style|\n      if style == :document\n        @router.add_document_operation(servant, soapaction, name, param_def)\n      else\n        qname = XSD::QName.new(namespace, name_as)\n        @router.add_rpc_operation(servant, qname, soapaction, name, param_def)\n      end\n    end\n    self.mapping_registry = DatetimePortType::MappingRegistry\n  end\nend\n\nif $0 == __FILE__\n  # Change listen port.\n  server = DatetimePortTypeApp.new('app', nil, '0.0.0.0', 10080)\n  trap(:INT) do\n    server.shutdown\n  end\n  server.start\nend\n"
  },
  {
    "path": "test/wsdl/datetime/datetime.rb",
    "content": ""
  },
  {
    "path": "test/wsdl/datetime/datetime.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<wsdl:definitions name = \"datetime\"\n    targetNamespace=\"urn:jp.gr.jin.rrr.example.datetime\"\n    xmlns:tns=\"urn:jp.gr.jin.rrr.example.datetime\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n  <wsdl:message name=\"nowRequest\">\n    <wsdl:part name=\"now\" type=\"xsd:dateTime\"/>\n  </wsdl:message>\n\n  <wsdl:message name=\"nowResponse\">\n    <wsdl:part name=\"now\" type=\"xsd:dateTime\"/>\n  </wsdl:message>\n\n  <wsdl:portType name=\"DatetimePortType\">\n    <wsdl:operation name=\"now\">\n      <wsdl:input message=\"tns:nowRequest\" name=\"nowRequest\"/>\n      <wsdl:output message=\"tns:nowResponse\" name=\"nowResponse\"/>\n    </wsdl:operation>\n  </wsdl:portType>\n\n  <wsdl:binding name=\"DatetimeBinding\" type=\"tns:DatetimePortType\">\n    <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n    <wsdl:operation name=\"now\">\n      <soap:operation soapAction=\"\"/>\n      <wsdl:input name=\"nowRequest\">\n\t<soap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:jp.gr.jin.rrr.example.datetime\" use=\"encoded\"/>\n      </wsdl:input>\n      <wsdl:output name=\"nowResponse\">\n\t<soap:body encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:jp.gr.jin.rrr.example.datetime\" use=\"encoded\"/>\n      </wsdl:output>\n    </wsdl:operation>\n  </wsdl:binding>\n\n  <wsdl:service name=\"DatetimeService\">\n    <wsdl:port binding=\"tns:DatetimeBinding\" name=\"DatetimePort\">\n      <soap:address location=\"http://localhost:10080/\"/>\n    </wsdl:port>\n  </wsdl:service>\n</wsdl:definitions>\n"
  },
  {
    "path": "test/wsdl/datetime/datetimeServant.rb",
    "content": "require 'datetime.rb'\n\nclass DatetimePortType\n  # SYNOPSIS\n  #   now(now)\n  #\n  # ARGS\n  #   now\t\t - {http://www.w3.org/2001/XMLSchema}dateTime\n  #\n  # RETURNS\n  #   now\t\t - {http://www.w3.org/2001/XMLSchema}dateTime\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def now(now)\n    #raise NotImplementedError.new\n    now + 1\n  end\nend\n\n"
  },
  {
    "path": "test/wsdl/datetime/test_datetime.rb",
    "content": "require 'test/unit'\nrequire 'soap/wsdlDriver'\nrequire 'DatetimeService.rb'\n\n\nmodule WSDL\nmodule Datetime\n\n\nclass TestDatetime < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = DatetimePortTypeApp.new('Datetime server', nil, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'datetime.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.generate_explicit_type = true\n    @client.wiredump_dev = STDOUT if $DEBUG\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def test_datetime\n    d = DateTime.now\n    d1 = d + 1\n    d2 = @client.now(d)\n    assert_equal(d1.year, d2.year)\n    assert_equal(d1.month, d2.month)\n    assert_equal(d1.day, d2.day)\n    assert_equal(d1.hour, d2.hour)\n    assert_equal(d1.min, d2.min)\n    assert_equal(d1.sec, d2.sec)\n    assert_equal(d1.sec, d2.sec)\n  end\n\n  def test_time\n    d = DateTime.now\n    t = Time.gm(d.year, d.month, d.day, d.hour, d.min, d.sec)\n    d1 = d + 1\n    d2 = @client.now(t)\n    assert_equal(d1.year, d2.year)\n    assert_equal(d1.month, d2.month)\n    assert_equal(d1.day, d2.day)\n    assert_equal(d1.hour, d2.hour)\n    assert_equal(d1.min, d2.min)\n    assert_equal(d1.sec, d2.sec)\n    assert_equal(d1.sec, d2.sec)\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/wsdl/document/document.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions\n    name=\"echo\"\n    targetNamespace=\"urn:docrpc\"\n    xmlns:tns=\"urn:docrpc\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema elementFormDefault=\"unqualified\" targetNamespace=\"urn:docrpc\">\n      <xsd:complexType name=\"echo_struct\">\n        <xsd:sequence>\n          <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"m_string\" type=\"xsd:string\" />\n          <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"m_datetime\" type=\"xsd:dateTime\" />\n        </xsd:sequence>\n        <xsd:attribute name=\"m_attr\" type=\"xsd:string\" />\n      </xsd:complexType>\n\n      <xsd:element name=\"echoele\">\n        <xsd:complexType>\n          <xsd:sequence>\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"struct1\" type=\"tns:echo_struct\" />\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"struct-2\" type=\"tns:echo_struct\" />\n          </xsd:sequence>\n          <xsd:attribute name=\"attr_string\" type=\"xsd:string\" />\n          <xsd:attribute name=\"attr-int\" type=\"xsd:int\" />\n        </xsd:complexType>\n      </xsd:element>\n      <xsd:element name=\"echo_response\">\n        <xsd:complexType>\n          <xsd:sequence>\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"struct1\" type=\"tns:echo_struct\" />\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"struct-2\" type=\"tns:echo_struct\" />\n          </xsd:sequence>\n          <xsd:attribute name=\"attr_string\" type=\"xsd:string\" />\n          <xsd:attribute name=\"attr-int\" type=\"xsd:int\" />\n        </xsd:complexType>\n      </xsd:element>\n    </xsd:schema>\n  </types>\n\n  <message name=\"echo_in\">\n    <part name=\"parameters\" element=\"tns:echoele\" />\n  </message>\n  <message name=\"echo_out\">\n    <part name=\"parameters\" element=\"tns:echo_response\" />\n  </message>\n\n  <portType name=\"docrpc_porttype\">\n    <operation name=\"echo\">\n      <input message=\"tns:echo_in\" />\n      <output message=\"tns:echo_out\" />\n    </operation>\n  </portType>\n\n  <binding name=\"docrpc_binding\" type=\"tns:docrpc_porttype\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\" />\n    <operation name=\"echo\">\n      <soap:operation soapAction=\"urn:docrpc:echo\" style=\"document\" />\n      <input>\n        <soap:body use=\"literal\" />\n      </input>\n      <output>\n        <soap:body use=\"literal\" />\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"docrpc_service\">\n    <port name=\"docprc_service_port\" binding=\"tns:docrpc_binding\">\n      <soap:address location=\"http://localhost:17171/\" />\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/document/echo.rb",
    "content": "require 'xsd/qname'\n\n# {urn:docrpc}echoele\nclass Echoele\n  @@schema_type = \"echoele\"\n  @@schema_ns = \"urn:docrpc\"\n  @@schema_attribute = {XSD::QName.new(nil, \"attr_string\") => \"SOAP::SOAPString\", XSD::QName.new(nil, \"attr-int\") => \"SOAP::SOAPInt\"}\n  @@schema_element = [[\"struct1\", [\"Echo_struct\", XSD::QName.new(nil, \"struct1\")]], [\"struct_2\", [\"Echo_struct\", XSD::QName.new(nil, \"struct-2\")]]]\n\n  attr_accessor :struct1\n  attr_accessor :struct_2\n\n  def xmlattr_attr_string\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr_string\")]\n  end\n\n  def xmlattr_attr_string=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr_string\")] = value\n  end\n\n  def xmlattr_attr_int\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr-int\")]\n  end\n\n  def xmlattr_attr_int=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr-int\")] = value\n  end\n\n  def initialize(struct1 = nil, struct_2 = nil)\n    @struct1 = struct1\n    @struct_2 = struct_2\n    @__xmlattr = {}\n  end\nend\n\n# {urn:docrpc}echo_response\nclass Echo_response\n  @@schema_type = \"echo_response\"\n  @@schema_ns = \"urn:docrpc\"\n  @@schema_attribute = {XSD::QName.new(nil, \"attr_string\") => \"SOAP::SOAPString\", XSD::QName.new(nil, \"attr-int\") => \"SOAP::SOAPInt\"}\n  @@schema_element = [[\"struct1\", [\"Echo_struct\", XSD::QName.new(nil, \"struct1\")]], [\"struct_2\", [\"Echo_struct\", XSD::QName.new(nil, \"struct-2\")]]]\n\n  attr_accessor :struct1\n  attr_accessor :struct_2\n\n  def xmlattr_attr_string\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr_string\")]\n  end\n\n  def xmlattr_attr_string=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr_string\")] = value\n  end\n\n  def xmlattr_attr_int\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr-int\")]\n  end\n\n  def xmlattr_attr_int=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"attr-int\")] = value\n  end\n\n  def initialize(struct1 = nil, struct_2 = nil)\n    @struct1 = struct1\n    @struct_2 = struct_2\n    @__xmlattr = {}\n  end\nend\n\n# {urn:docrpc}echo_struct\nclass Echo_struct\n  @@schema_type = \"echo_struct\"\n  @@schema_ns = \"urn:docrpc\"\n  @@schema_attribute = {XSD::QName.new(nil, \"m_attr\") => \"SOAP::SOAPString\"}\n  @@schema_element = [[\"m_string\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"m_string\")]], [\"m_datetime\", [\"SOAP::SOAPDateTime\", XSD::QName.new(nil, \"m_datetime\")]]]\n\n  attr_accessor :m_string\n  attr_accessor :m_datetime\n\n  def xmlattr_m_attr\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"m_attr\")]\n  end\n\n  def xmlattr_m_attr=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(nil, \"m_attr\")] = value\n  end\n\n  def initialize(m_string = nil, m_datetime = nil)\n    @m_string = m_string\n    @m_datetime = m_datetime\n    @__xmlattr = {}\n  end\nend\n"
  },
  {
    "path": "test/wsdl/document/number.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions\n    name=\"foo\"\n    targetNamespace=\"urn:foo\"\n    xmlns:tns=\"urn:foo\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema elementFormDefault=\"unqualified\" targetNamespace=\"urn:foo\">\n      <xsd:element name=\"get_foo\">\n        <xsd:complexType>\n          <xsd:sequence>\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"number\" type=\"xsd:string\" />\n          </xsd:sequence>\n        </xsd:complexType>\n      </xsd:element>\n    </xsd:schema>\n  </types>\n\n  <message name=\"get_foo_in\">\n    <part name=\"parameters\" element=\"tns:get_foo\" />\n  </message>\n  <message name=\"get_foo_out\">\n    <part name=\"parameters\" type=\"xsd:string\" />\n  </message>\n\n  <portType name=\"foo_porttype\">\n    <operation name=\"get_foo\">\n      <input message=\"tns:get_foo_in\" />\n      <output message=\"tns:get_foo_out\" />\n    </operation>\n  </portType>\n\n  <binding name=\"foo_binding\" type=\"tns:foo_porttype\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\"\n        style=\"document\" />\n    <operation name=\"get_foo\">\n      <soap:operation soapAction=\"urn:foo:get_foo\" style=\"document\" />\n      <input>\n        <soap:body use=\"literal\" />\n      </input>\n      <output>\n        <soap:body use=\"literal\" />\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"foo_service\">\n    <port name=\"foo_service_port\" binding=\"tns:foo_binding\">\n      <soap:address location=\"http://localhost:17171/\" />\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/document/ping_nosoapaction.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions xmlns:tns=\"http://xmlsoap.org/Ping\"\nxmlns=\"http://schemas.xmlsoap.org/wsdl/\"\nxmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\nxmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\ntargetNamespace=\"http://xmlsoap.org/Ping\" name=\"Ping\">\n    <types>\n        <schema targetNamespace=\"http://xmlsoap.org/Ping\"\n        xmlns=\"http://www.w3.org/2001/XMLSchema\"\n        elementFormDefault=\"qualified\">\n            <complexType name=\"ping\">\n                <sequence>\n                    <element name=\"scenario\" type=\"xsd:string\"\n                    nillable=\"true\"/>\n                    <element name=\"origin\" type=\"xsd:string\"\n                    nillable=\"true\"/>\n                    <element name=\"text\" type=\"xsd:string\"\n                    nillable=\"true\"/>\n                </sequence>\n            </complexType>\n            <complexType name=\"pingResponse\">\n                <sequence>\n                    <element name=\"scenario\" type=\"xsd:string\"\n                    nillable=\"true\"/>\n                    <element name=\"origin\" type=\"xsd:string\"\n                    nillable=\"true\"/>\n                    <element name=\"text\" type=\"xsd:string\"\n                    nillable=\"true\"/>\n                </sequence>\n            </complexType>\n            <element name=\"Ping\" type=\"tns:ping\"/>\n            <element name=\"PingResponse\" type=\"tns:pingResponse\"/>\n        </schema>\n    </types>\n    <message name=\"PingRequest\">\n        <part name=\"ping\" element=\"tns:Ping\"/>\n    </message>\n    <message name=\"PingResponse\">\n        <part name=\"pingResponse\" element=\"tns:PingResponse\"/>\n    </message>\n    <portType name=\"PingPort\">\n        <operation name=\"Ping\">\n            <input message=\"tns:PingRequest\"/>\n            <output message=\"tns:PingResponse\"/>\n        </operation>\n    </portType>\n    <binding name=\"PingBinding\" type=\"tns:PingPort\">\n        <soap:binding style=\"document\"\n        transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n        <operation name=\"Ping\">\n            <soap:operation/>\n            <input>\n                <soap:body use=\"literal\"/>\n            </input>\n            <output>\n                <soap:body use=\"literal\"/>\n            </output>\n        </operation>\n    </binding>\n    <service name=\"PingService\">\n        <port name=\"PingPort\" binding=\"tns:PingBinding\">\n            <soap:address\n            location=\"http://127.0.0.1:8080/axis/services/PingPort\"/>\n        </port>\n    </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/document/test_nosoapaction.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\nrequire 'soap/rpc/driver'\n\n\nmodule WSDL; module Document\n\n\nclass TestNoSOAPAction < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = 'http://xmlsoap.org/Ping'\n\n    def on_init\n      add_document_method(\n        self,\n        Namespace + '/ping',\n        'ping_with_soapaction',\n        XSD::QName.new(Namespace, 'Ping'),\n        XSD::QName.new(Namespace, 'PingResponse')\n      )\n\n      add_document_method(\n        self,\n        nil,\n        'ping',\n        XSD::QName.new(Namespace, 'Ping'),\n        XSD::QName.new(Namespace, 'PingResponse')\n      )\n\n      # When no SOAPAction given, latter method(ping) is called.\n    end\n  \n    def ping(arg)\n      arg.text = 'ping'\n      arg\n    end\n  \n    def ping_with_soapaction(arg)\n      arg.text = 'ping_with_soapaction'\n      arg\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', Server::Namespace, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_with_soapaction\n    wsdl = File.join(DIR, 'ping_nosoapaction.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDOUT if $DEBUG\n    rv = @client.ping(:scenario => 'scenario', :origin => 'origin',\n      :text => 'text')\n    assert_equal('scenario', rv.scenario)\n    assert_equal('origin', rv.origin)\n    assert_equal('ping', rv.text)\n  end\n\n  def test_without_soapaction\n    @client = ::SOAP::RPC::Driver.new(\"http://localhost:#{Port}/\",\n      Server::Namespace)\n    @client.add_document_method('ping', Server::Namespace + '/ping',\n      XSD::QName.new(Server::Namespace, 'Ping'),\n      XSD::QName.new(Server::Namespace, 'PingResponse'))\n    @client.wiredump_dev = STDOUT if $DEBUG\n    rv = @client.ping(:scenario => 'scenario', :origin => 'origin',\n      :text => 'text')\n    assert_equal('scenario', rv.scenario)\n    assert_equal('origin', rv.origin)\n    assert_equal('ping_with_soapaction', rv.text)\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/wsdl/document/test_number.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\n\nmodule WSDL; module Document\n\n\nclass TestNumber < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = 'urn:foo'\n\n    def on_init\n      add_document_method(\n        self,\n        Namespace + ':get_foo',\n        'get_foo',\n        XSD::QName.new(Namespace, 'get_foo'),\n        XSD::QName.new(Namespace, 'get_foo_response')\n      )\n    end\n  \n    def get_foo(arg)\n      arg.number\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_classdef\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    File.unlink(pathname('foo.rb'))\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:rpc\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_classdef\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"number.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['force'] = true\n    gen.run\n    require pathname('foo')\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def test_wsdl\n    wsdl = File.join(DIR, 'number.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDOUT if $DEBUG\n\n    # with the Struct defined in foo.rb, which is generated from WSDL\n    assert_equal(\"12345\", @client.get_foo(Get_foo.new(\"12345\")))\n\n    # with Hash\n    assert_equal(\"12345\", @client.get_foo({:number => \"12345\"}))\n\n    # with Original struct\n    get_foo_struct = Struct.new(:number)\n    assert_equal(\"12345\", @client.get_foo(get_foo_struct.new(\"12345\")))\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/wsdl/document/test_rpc.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\n\nmodule WSDL; module Document\n\n\nclass TestRPC < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = 'urn:docrpc'\n\n    def on_init\n      add_document_method(\n        self,\n        Namespace + ':echo',\n        'echo',\n        XSD::QName.new(Namespace, 'echo'),\n        XSD::QName.new(Namespace, 'echo_response')\n      )\n    end\n  \n    def echo(arg)\n      if arg.is_a?(Echoele)\n        # swap args\n        tmp = arg.struct1\n        arg.struct1 = arg.struct_2\n        arg.struct_2 = tmp\n        arg\n      else\n        # swap args\n        tmp = arg[\"struct1\"]\n        arg[\"struct1\"] = arg[\"struct-2\"]\n        arg[\"struct-2\"] = tmp\n        arg\n      end\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_classdef\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    #File.unlink(pathname('echo.rb'))\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:rpc\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_classdef\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"document.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['force'] = true\n    gen.run\n    require pathname('echo')\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def test_wsdl\n    wsdl = File.join(DIR, 'document.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDOUT if $DEBUG\n\n    struct1 = Echo_struct.new(\"mystring1\", now1 = Time.now)\n    struct1.xmlattr_m_attr = 'myattr1'\n    struct2 = Echo_struct.new(\"mystring2\", now2 = Time.now)\n    struct2.xmlattr_m_attr = 'myattr2'\n    echo = Echoele.new(struct1, struct2)\n    echo.xmlattr_attr_string = 'attr_string'\n    echo.xmlattr_attr_int = 5\n    ret = @client.echo(echo)\n\n    # struct#m_datetime in a response is a DateTime even though\n    # struct#m_datetime in a request is a Time.\n    timeformat = \"%Y-%m-%dT%H:%M:%S\"\n    assert_equal(\"mystring2\", ret.struct1.m_string)\n    assert_equal(now2.strftime(timeformat),\n      date2time(ret.struct1.m_datetime).strftime(timeformat))\n    assert_equal(\"mystring1\", ret.struct_2.m_string)\n    assert_equal(now1.strftime(timeformat),\n      date2time(ret.struct_2.m_datetime).strftime(timeformat))\n    assert_equal(\"attr_string\", ret.xmlattr_attr_string)\n    assert_equal(5, ret.xmlattr_attr_int)\n  end\n\n  def date2time(date)\n    if date.respond_to?(:to_time)\n      date.to_time\n    else\n      d = date.new_offset(0)\n      d.instance_eval {\n        Time.utc(year, mon, mday, hour, min, sec,\n          (sec_fraction * 86400000000).to_i)\n      }.getlocal\n    end\n  end\n\n  include ::SOAP\n  def test_naive\n    @client = ::SOAP::RPC::Driver.new(\"http://localhost:#{Port}/\")\n    @client.add_document_method('echo', 'urn:docrpc:echo',\n      XSD::QName.new('urn:docrpc', 'echoele'),\n      XSD::QName.new('urn:docrpc', 'echo_response'))\n    @client.wiredump_dev = STDOUT if $DEBUG\n\n    echo = SOAPElement.new('foo')\n    echo.extraattr['attr_string'] = 'attr_string'\n    echo.extraattr['attr-int'] = 5\n    echo.add(struct1 = SOAPElement.new('struct1'))\n    struct1.add(SOAPElement.new('m_string', 'mystring1'))\n    struct1.add(SOAPElement.new('m_datetime', '2005-03-17T19:47:31+01:00'))\n    struct1.extraattr['m_attr'] = 'myattr1'\n    echo.add(struct2 = SOAPElement.new('struct-2'))\n    struct2.add(SOAPElement.new('m_string', 'mystring2'))\n    struct2.add(SOAPElement.new('m_datetime', '2005-03-17T19:47:32+02:00'))\n    struct2.extraattr['m_attr'] = 'myattr2'\n    ret = @client.echo(echo)\n    timeformat = \"%Y-%m-%dT%H:%M:%S\"\n    assert_equal('mystring2', ret.struct1.m_string)\n    assert_equal('2005-03-17T19:47:32',\n      ret.struct1.m_datetime.strftime(timeformat))\n    assert_equal(\"mystring1\", ret.struct_2.m_string)\n    assert_equal('2005-03-17T19:47:31',\n      ret.struct_2.m_datetime.strftime(timeformat))\n    assert_equal('attr_string', ret.xmlattr_attr_string)\n    assert_equal(5, ret.xmlattr_attr_int)\n\n    echo = {'struct1' => {'m_string' => 'mystring1', 'm_datetime' => '2005-03-17T19:47:31+01:00'}, \n          'struct-2' => {'m_string' => 'mystring2', 'm_datetime' => '2005-03-17T19:47:32+02:00'}}\n    ret = @client.echo(echo)\n    timeformat = \"%Y-%m-%dT%H:%M:%S\"\n    assert_equal('mystring2', ret.struct1.m_string)\n    assert_equal('2005-03-17T19:47:32',\n      ret.struct1.m_datetime.strftime(timeformat))\n    assert_equal(\"mystring1\", ret.struct_2.m_string)\n    assert_equal('2005-03-17T19:47:31',\n      ret.struct_2.m_datetime.strftime(timeformat))\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/wsdl/emptycomplextype.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name = \"emptycomplextype\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    targetNamespace=\"urn:jp.gr.jin.rrr.example.emptycomplextype\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n\n  <types>\n    <xsd:schema elementFormDefault=\"qualified\"\n\ttargetNamespace=\"urn:jp.gr.jin.rrr.example.emptycomplextype\">\n      <xsd:element name=\"typeIn\">\n        <xsd:complexType />\n      </xsd:element>\n\n      <xsd:element name=\"typeOut\">\n        <xsd:complexType>\n          <xsd:sequence>\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"str1\" type=\"xsd:string\" />\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"str2\" type=\"xsd:string\" />\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"seq\">\n              <xsd:complexType>\n                <xsd:sequence>\n                  <xsd:any />\n                </xsd:sequence>\n              </xsd:complexType>\n            </xsd:element>\n          </xsd:sequence>\n        </xsd:complexType>\n      </xsd:element>\n    </xsd:schema>\n  </types>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/map/map.wsdl",
    "content": "<?xml version=\"1.0\"?>\n<definitions\n    name=\"map\"\n    targetNamespace=\"urn:map\"\n    xmlns:tns=\"urn:map\"\n    xmlns:txd=\"urn:map\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:apachesoap=\"http://xml.apache.org/xml-soap\">\n\n  <types>\n    <schema\n\txmlns=\"http://www.w3.org/2001/XMLSchema\"\n\ttargetNamespace=\"http://xml.apache.org/xml-soap\">\n      <complexType name=\"Map\">\n\t<sequence>\n\t  <element name=\"item\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t    <complexType>\n\t      <sequence>\n\t\t<element name=\"key\" type=\"xsd:anyType\" />\n\t\t<element name=\"value\" type=\"xsd:anyType\" />\n\t      </sequence>\n\t    </complexType>\n\t  </element>\n\t</sequence>\n      </complexType>\n    </schema>\n  </types>\n\n  <message name=\"mapRequest\"/>\n  <message name=\"mapResponse\">\n    <part name=\"return\" type=\"apachesoap:Map\"/>\n  </message>\n\n  <message name=\"map2Request\">\n    <part name=\"arg\" type=\"apachesoap:Map\"/>\n  </message>\n  <message name=\"map2Response\">\n    <part name=\"return\" type=\"apachesoap:Map\"/>\n  </message>\n\n  <portType name=\"MapServicePortType\">\n    <operation name=\"map\" parameterOrder=\"\">\n      <input message=\"tns:mapRequest\"/>\n      <output message=\"tns:mapResponse\"/>\n    </operation>\n\n    <operation name=\"map2\" parameterOrder=\"\">\n      <input message=\"tns:map2Request\"/>\n      <output message=\"tns:map2Response\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"MapServicePortBinding\" type=\"tns:MapServicePortType\">\n    <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n    <operation name=\"map\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:map\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:map\"/>\n      </output>\n    </operation>\n\n    <operation name=\"map2\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:map\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:map\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"MapService\">\n    <port name=\"MapServicePort\" binding=\"tns:MapServicePortBinding\">\n      <soap:address location=\"http://raa.ruby-lang.org/soap/1.0.2/\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/map/map.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n2:mapResponse xmlns:n1=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:n2=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\" env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <return xmlns:n3=\"http://xml.apache.org/xml-soap\" xsi:type=\"n3:Map\">\n\t<item>\n\t  <key xsi:type=\"xsd:string\">a</key>\n\t  <value xsi:type=\"n3:Map\">\n\t    <item>\n\t      <key xsi:type=\"xsd:string\">a1</key>\n\t      <value xsi:type=\"n1:Array\" n1:arrayType=\"xsd:anyType[1]\">\n\t\t<item xsi:type=\"xsd:string\">a1</item>\n\t      </value>\n\t    </item>\n\t    <item>\n\t      <key xsi:type=\"xsd:string\">a2</key>\n\t      <value xsi:type=\"n1:Array\" n1:arrayType=\"xsd:anyType[1]\">\n\t\t<item xsi:type=\"xsd:string\">a2</item>\n\t      </value>\n\t    </item>\n\t  </value>\n\t</item>\n\t<item>\n\t  <key xsi:type=\"xsd:string\">b</key>\n\t  <value xsi:type=\"n3:Map\">\n\t    <item>\n\t      <key xsi:type=\"xsd:string\">b1</key>\n\t      <value xsi:type=\"n1:Array\" n1:arrayType=\"xsd:anyType[1]\">\n\t\t<item xsi:type=\"xsd:string\">b1</item>\n\t      </value>\n\t    </item>\n\t    <item>\n\t      <key xsi:type=\"xsd:string\">b2</key>\n\t      <value xsi:type=\"n1:Array\" n1:arrayType=\"xsd:anyType[1]\">\n\t\t<item xsi:type=\"xsd:string\">b2</item>\n\t      </value>\n\t    </item>\n\t  </value>\n\t</item>\n      </return>\n    </n2:mapResponse>\n  </env:Body>\n</env:Envelope>\n"
  },
  {
    "path": "test/wsdl/map/test_map.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/httpserver'\nrequire 'soap/wsdlDriver'\n\n\nmodule WSDL\n\n\nclass TestMap < Test::Unit::TestCase\n  Port = 17171\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  class Server < ::SOAP::RPC::HTTPServer\n    def on_init\n      add_method(self, 'map')\n      add_method(self, 'map2', 'arg')\n    end\n\n    def map\n      {1 => \"a\", 2 => \"b\"}\n    end\n\n    def map2(arg)\n      arg\n    end\n  end\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new(\n      :BindAddress => \"0.0.0.0\",\n      :Port => Port,\n      :AccessLog => [],\n      :SOAPDefaultNamespace => \"urn:map\"\n    )\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'map.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.generate_explicit_type = true\n    @client.wiredump_dev = STDOUT if $DEBUG\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def test_by_wsdl\n    dir = File.dirname(File.expand_path(__FILE__))\n    wsdlfile = File.join(dir, 'map.wsdl')\n    xml = File.open(File.join(dir, 'map.xml')) { |f| f.read }\n    wsdl = WSDL::Importer.import(wsdlfile)\n    service = wsdl.services[0]\n    port = service.ports[0]\n    wsdl_types = wsdl.collect_complextypes\n    rpc_decode_typemap = wsdl_types + wsdl.soap_rpc_complextypes(port.find_binding)\n    opt = {}\n    opt[:default_encodingstyle] = ::SOAP::EncodingNamespace\n    opt[:decode_typemap] = rpc_decode_typemap\n    header, body = ::SOAP::Processor.unmarshal(xml, opt)\n    map = ::SOAP::Mapping.soap2obj(body.response)\n    assert_equal([\"a1\"], map[\"a\"][\"a1\"])\n    assert_equal([\"a2\"], map[\"a\"][\"a2\"])\n    assert_equal([\"b1\"], map[\"b\"][\"b1\"])\n    assert_equal([\"b2\"], map[\"b\"][\"b2\"])\n  end\n\n  def test_wsdldriver\n    assert_equal({1 => \"a\", 2 => \"b\"}, @client.map)\n    assert_equal({1 => 2}, @client.map2({1 => 2}))\n    assert_equal({1 => {2 => 3}}, @client.map2({1 => {2 => 3}}))\n    assert_equal({[\"a\", 2] => {2 => 3}}, @client.map2({[\"a\", 2] => {2 => 3}}))\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/wsdl/marshal/person.wsdl",
    "content": "<?xml version=\"1.0\"?>\n<definitions name=\"Person\"\n    targetNamespace=\"http://www.jin.gr.jp/~nahi/xmlns/sample/Person\"\n    xmlns:tns=\"http://www.jin.gr.jp/~nahi/xmlns/sample/Person\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema xmlns=\"http://www.w3.org/2001/XMLSchema\" \n        targetNamespace=\"http://www.jin.gr.jp/~nahi/xmlns/sample/Person\">\n      <complexType name=\"Person\">\n        <all>\n          <element name=\"familyname\" type=\"xsd:string\"/>\n          <element name=\"givenname\" type=\"xsd:string\"/>\n          <element name=\"var1\" type=\"xsd:int\"/>\n          <element name=\"var2\" type=\"xsd:double\"/>\n          <element name=\"var3\" type=\"xsd:string\"/>\n        </all>\n      </complexType>\n    </xsd:schema>\n  </types>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/marshal/person_org.rb",
    "content": "require 'xsd/qname'\n\n# {http://www.jin.gr.jp/~nahi/xmlns/sample/Person}Person\nclass Person\n  @@schema_type = \"Person\"\n  @@schema_ns = \"http://www.jin.gr.jp/~nahi/xmlns/sample/Person\"\n  @@schema_element = [[\"familyname\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"familyname\")]], [\"givenname\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"givenname\")]], [\"var1\", [\"SOAP::SOAPInt\", XSD::QName.new(nil, \"var1\")]], [\"var2\", [\"SOAP::SOAPDouble\", XSD::QName.new(nil, \"var2\")]], [\"var3\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"var3\")]]]\n\n  attr_accessor :familyname\n  attr_accessor :givenname\n  attr_accessor :var1\n  attr_accessor :var2\n  attr_accessor :var3\n\n  def initialize(familyname = nil, givenname = nil, var1 = nil, var2 = nil, var3 = nil)\n    @familyname = familyname\n    @givenname = givenname\n    @var1 = var1\n    @var2 = var2\n    @var3 = var3\n  end\nend\n"
  },
  {
    "path": "test/wsdl/marshal/test_wsdlmarshal.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'soap/mapping/wsdlencodedregistry'\nrequire 'soap/marshal'\nrequire 'wsdl/soap/wsdl2ruby'\n\nclass WSDLMarshaller\n  include SOAP\n\n  def initialize(wsdlfile)\n    wsdl = WSDL::Parser.new.parse(File.open(wsdlfile) { |f| f.read })\n    types = wsdl.collect_complextypes\n    @opt = {\n      :decode_typemap => types,\n      :generate_explicit_type => false,\n      :pretty => true\n    }\n    @mapping_registry = Mapping::WSDLEncodedRegistry.new(types)\n  end\n\n  def dump(obj, io = nil)\n    type = Mapping.class2element(obj.class)\n    ele =  Mapping.obj2soap(obj, @mapping_registry, type)\n    ele.elename = ele.type\n    Processor.marshal(SOAPEnvelope.new(nil, SOAPBody.new(ele)), @opt, io)\n  end\n\n  def load(io)\n    header, body = Processor.unmarshal(io, @opt)\n    Mapping.soap2obj(body.root_node)\n  end\nend\n\n\nrequire File.join(File.dirname(__FILE__), 'person_org')\n\nclass Person\n  def ==(rhs)\n    @familyname == rhs.familyname and @givenname == rhs.givenname and\n      @var1 == rhs.var1 and @var2 == rhs.var2 and @var3 == rhs.var3\n  end\nend\n\n\nclass TestWSDLMarshal < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  def test_marshal\n    marshaller = WSDLMarshaller.new(pathname('person.wsdl'))\n    obj = Person.new(\"NAKAMURA\", \"Hiroshi\", 1, 1.0,  \"1\")\n    str = marshaller.dump(obj)\n    obj2 = marshaller.load(str)\n    assert_equal(obj, obj2)\n    assert_equal(str, marshaller.dump(obj2))\n  end\n\n  def test_classdef\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"person.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['force'] = true\n    gen.run\n    compare(\"person_org.rb\", \"Person.rb\")\n    File.unlink(pathname('Person.rb'))\n  end\n\n  def compare(expected, actual)\n    assert_equal(loadfile(expected), loadfile(actual), actual)\n  end\n\n  def loadfile(file)\n    File.open(pathname(file)) { |f| f.read }\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\nend\n"
  },
  {
    "path": "test/wsdl/multiplefault.wsdl",
    "content": "<?xml version=\"1.0\"?>\n<definitions name=\"MultipleFaultTest\"\n    targetNamespace=\"urn:jp.gr.jin.rrr.example.ele\"\n    xmlns:tns=\"urn:jp.gr.jin.rrr.example.ele\"\n    xmlns:typens=\"urn:jp.gr.jin.rrr.example.datatypes\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n    xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n\n  <types>\n    <xsd:schema xmlns=\"http://www.w3.org/2001/XMLSchema\"\n\ttargetNamespace=\"urn:jp.gr.jin.rrr.example.datatypes\">\n      <xsd:complexType name=\"AuthenticationError\">\n\t<all>\n\t  <element name=\"message\" type=\"xsd:string\" />\n\t  <element name=\"backtrace\" type=\"xoapenc:Array\" />\n\t</all>\n      </xsd:complexType>\n      <xsd:complexType name=\"AuthorizationError\">\n\t<all>\n\t  <element name=\"message\" type=\"xsd:string\" />\n\t  <element name=\"backtrace\" type=\"xoapenc:Array\" />\n\t</all>\n      </xsd:complexType>\n    </xsd:schema>\n  </types> \n\n  <message name=\"inputmsg\"/>\n  <message name=\"outputmsg\"/>\n  <message name=\"faultmsg1\" >\n    <part name=\"exception\" type=\"typens:AuthenticationError\" />\n  </message>\n  <message name=\"faultmsg2\" >\n    <part name=\"exception\" type=\"typens:AuthorizationError\" />\n  </message>\n\n  <portType name=\"MultipleFaultPortType\">\n    <operation name=\"myoperation\">\n      <input message=\"tns:inputmsg\"/>\n      <output message=\"tns:outputmsg\"/>\n      <fault message=\"tns:faultmsg1\"/>\n      <fault message=\"tns:faultmsg2\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"MultipleFaultBinding\" type=\"tns:MultipleFaultPortType\">\n    <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n    <operation name=\"myoperation\">\n      <soap:operation soapAction=\"urn:jp.gr.jin.rrr.example.ele\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:jp.gr.jin.rrr.example.ele\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:jp.gr.jin.rrr.example.ele\"\n   \t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"MultipleFaultService\">\n    <port name=\"MultipleFaultPortType\" binding=\"tns:MultipleFaultBinding\">\n      <soap:address location=\"http://localhost:17171/\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/qualified/lp.rb",
    "content": ""
  },
  {
    "path": "test/wsdl/qualified/lp.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions\n    name=\"lp\"\n    targetNamespace=\"urn:lp\"\n    xmlns:tns=\"urn:lp\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <schema xmlns=\"http://www.w3.org/2001/XMLSchema\">\n      <import namespace=\"urn:lp\" schemaLocation=\"lp.xsd\"/>\n    </schema>\n  </types>\n\n  <message name=\"login_in\">\n    <part name=\"parameters\" element=\"tns:login\" />\n  </message>\n  <message name=\"login_out\">\n    <part name=\"parameters\" element=\"tns:loginResponse\" />\n  </message>\n\n  <portType name=\"lp_porttype\">\n    <operation name=\"login\">\n      <input message=\"tns:login_in\" />\n      <output message=\"tns:login_out\" />\n    </operation>\n  </portType>\n\n  <binding name=\"lp_binding\" type=\"tns:lp_porttype\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\" />\n    <operation name=\"login\">\n      <soap:operation soapAction=\"urn:lp:login\" style=\"document\" />\n      <input>\n        <soap:body use=\"literal\" />\n      </input>\n      <output>\n        <soap:body use=\"literal\" />\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"lp_service\">\n    <port name=\"lp_service_port\" binding=\"tns:lp_binding\">\n      <soap:address location=\"http://localhost:17171/\" />\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/qualified/lp.xsd",
    "content": "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:lp=\"urn:lp\" targetNamespace=\"urn:lp\" elementFormDefault=\"unqualified\">\n\n  <xs:complexType name=\"login\">\n    <xs:sequence>\n      <xs:element name=\"username\" type=\"xs:string\"/>\n      <xs:element name=\"password\" type=\"xs:string\"/>\n      <xs:element name=\"timezone\" type=\"xs:string\" minOccurs=\"0\" maxOccurs=\"1\"/>\n    </xs:sequence>\n  </xs:complexType>\n\n  <xs:element name=\"login\" type=\"lp:login\"/>\n\n  <xs:complexType name=\"loginResponse\">\n    <xs:sequence>\n      <xs:element name=\"loginResult\">\n        <xs:complexType>\n          <xs:sequence>\n            <xs:element name=\"sessionID\" type=\"xs:string\"/>\n          </xs:sequence>\n        </xs:complexType>\n      </xs:element>\n    </xs:sequence>\n  </xs:complexType>\n\n  <xs:element name=\"loginResponse\" type=\"lp:loginResponse\"/>\n</xs:schema>\n"
  },
  {
    "path": "test/wsdl/qualified/np.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<wsdl:definitions xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:s=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://www50.brinkster.com/vbfacileinpt/np\" xmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" targetNamespace=\"http://www50.brinkster.com/vbfacileinpt/np\" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\">\n  <wsdl:types>\n    <s:schema elementFormDefault=\"qualified\" targetNamespace=\"http://www50.brinkster.com/vbfacileinpt/np\">\n      <s:element name=\"GetPrimeNumbers\">\n        <s:complexType>\n          <s:sequence>\n            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"Max\" type=\"s:string\" />\n          </s:sequence>\n        </s:complexType>\n      </s:element>\n      <s:element name=\"GetPrimeNumbersResponse\">\n        <s:complexType>\n          <s:sequence>\n            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"GetPrimeNumbersResult\" type=\"s:string\" />\n          </s:sequence>\n        </s:complexType>\n      </s:element>\n    </s:schema>\n  </wsdl:types>\n  <wsdl:message name=\"GetPrimeNumbersSoapIn\">\n    <wsdl:part name=\"parameters\" element=\"tns:GetPrimeNumbers\" />\n  </wsdl:message>\n  <wsdl:message name=\"GetPrimeNumbersSoapOut\">\n    <wsdl:part name=\"parameters\" element=\"tns:GetPrimeNumbersResponse\" />\n  </wsdl:message>\n  <wsdl:portType name=\"pnumSoap\">\n    <wsdl:operation name=\"GetPrimeNumbers\">\n      <wsdl:input message=\"tns:GetPrimeNumbersSoapIn\" />\n      <wsdl:output message=\"tns:GetPrimeNumbersSoapOut\" />\n    </wsdl:operation>\n  </wsdl:portType>\n  <wsdl:binding name=\"pnumSoap\" type=\"tns:pnumSoap\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\" />\n    <wsdl:operation name=\"GetPrimeNumbers\">\n      <soap:operation soapAction=\"http://www50.brinkster.com/vbfacileinpt/np/GetPrimeNumbers\" style=\"document\" />\n      <wsdl:input>\n        <soap:body use=\"literal\" />\n      </wsdl:input>\n      <wsdl:output>\n        <soap:body use=\"literal\" />\n      </wsdl:output>\n    </wsdl:operation>\n  </wsdl:binding>\n  <wsdl:service name=\"pnum\">\n    <wsdl:port name=\"pnumSoap\" binding=\"tns:pnumSoap\">\n      <soap:address location=\"http://www50.brinkster.com/vbfacileinpt/np.asmx\" />\n    </wsdl:port>\n  </wsdl:service>\n</wsdl:definitions>"
  },
  {
    "path": "test/wsdl/qualified/test_qualified.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\nif defined?(HTTPAccess2)\n\nmodule WSDL\n\n\nclass TestQualified < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = 'http://www50.brinkster.com/vbfacileinpt/np'\n\n    def on_init\n      add_document_method(\n        self,\n        Namespace + '/GetPrimeNumbers',\n        'GetPrimeNumbers',\n        XSD::QName.new(Namespace, 'GetPrimeNumbers'),\n        XSD::QName.new(Namespace, 'GetPrimeNumbersResponse')\n      )\n    end\n  \n    def GetPrimeNumbers(arg)\n      nil\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_clientdef\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    unless $DEBUG\n      File.unlink(pathname('default.rb'))\n      File.unlink(pathname('defaultDriver.rb'))\n    end\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:lp\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_clientdef\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      gen = WSDL::SOAP::WSDL2Ruby.new\n      gen.location = pathname(\"np.wsdl\")\n      gen.basedir = DIR\n      gen.logger.level = Logger::FATAL\n      gen.opt['classdef'] = nil\n      gen.opt['driver'] = nil\n      gen.opt['force'] = true\n      gen.run\n      require pathname('default.rb')\n    ensure\n      Dir.chdir(backupdir)\n    end\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  LOGIN_REQUEST_QUALIFIED_NS =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:GetPrimeNumbers xmlns:n1=\"http://www50.brinkster.com/vbfacileinpt/np\">\n      <n1:Max>10</n1:Max>\n    </n1:GetPrimeNumbers>\n  </env:Body>\n</env:Envelope>]\n\n  LOGIN_REQUEST_QUALIFIED =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <GetPrimeNumbers xmlns=\"http://www50.brinkster.com/vbfacileinpt/np\">\n      <Max>10</Max>\n    </GetPrimeNumbers>\n  </env:Body>\n</env:Envelope>]\n\n  def test_wsdl\n    wsdl = File.join(DIR, 'np.wsdl')\n    @client = nil\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    ensure\n      Dir.chdir(backupdir)\n    end\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = str = ''\n    @client.GetPrimeNumbers(:Max => 10)\n    assert_equal(LOGIN_REQUEST_QUALIFIED_NS, parse_requestxml(str))\n  end\n\n  include ::SOAP\n  def test_naive\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      require pathname('defaultDriver')\n    ensure\n      Dir.chdir(backupdir)\n    end\n    @client = PnumSoap.new(\"http://localhost:#{Port}/\")\n\n    @client.wiredump_dev = str = ''\n    @client.getPrimeNumbers(GetPrimeNumbers.new(10))\n    assert_equal(LOGIN_REQUEST_QUALIFIED, parse_requestxml(str))\n  end\n\n  def parse_requestxml(str)\n    str.split(/\\r?\\n\\r?\\n/)[3]\n  end\nend\n\n\nend\n\nend\n"
  },
  {
    "path": "test/wsdl/qualified/test_unqualified.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\nif defined?(HTTPAccess2)\n\nmodule WSDL\n\n\nclass TestUnqualified < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = 'urn:lp'\n\n    def on_init\n      add_document_method(\n        self,\n        Namespace + ':login',\n        'login',\n        XSD::QName.new(Namespace, 'login'),\n        XSD::QName.new(Namespace, 'loginResponse')\n      )\n    end\n  \n    def login(arg)\n      nil\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_clientdef\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    File.unlink(pathname('lp.rb'))\n    File.unlink(pathname('lpDriver.rb'))\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:lp\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_clientdef\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      gen = WSDL::SOAP::WSDL2Ruby.new\n      gen.location = pathname(\"lp.wsdl\")\n      gen.basedir = DIR\n      gen.logger.level = Logger::FATAL\n      gen.opt['classdef'] = nil\n      gen.opt['driver'] = nil\n      gen.opt['force'] = true\n      gen.run\n      require pathname('lp')\n    ensure\n      Dir.chdir(backupdir)\n    end\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  LOGIN_REQUEST_QUALIFIED =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:login xmlns:n1=\"urn:lp\">\n      <username>NaHi</username>\n      <password>passwd</password>\n      <timezone>JST</timezone>\n    </n1:login>\n  </env:Body>\n</env:Envelope>]\n\n  def test_wsdl\n    wsdl = File.join(DIR, 'lp.wsdl')\n    @client = nil\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    ensure\n      Dir.chdir(backupdir)\n    end\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = str = ''\n    @client.login(:timezone => 'JST', :password => 'passwd',\n      :username => 'NaHi')\n    assert_equal(LOGIN_REQUEST_QUALIFIED, parse_requestxml(str))\n  end\n\n  include ::SOAP\n  def test_naive\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      require pathname('lpDriver')\n    ensure\n      Dir.chdir(backupdir)\n    end\n    @client = Lp_porttype.new(\"http://localhost:#{Port}/\")\n\n    @client.wiredump_dev = str = ''\n    @client.login(Login.new('NaHi', 'passwd', 'JST'))\n    assert_equal(LOGIN_REQUEST_QUALIFIED, parse_requestxml(str))\n  end\n\n  def parse_requestxml(str)\n    str.split(/\\r?\\n\\r?\\n/)[3]\n  end\nend\n\n\nend\n\nend\n"
  },
  {
    "path": "test/wsdl/raa/RAA.rb",
    "content": "# http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\nclass Category\n  @@schema_type = \"Category\"\n  @@schema_ns = \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n\n  def major\n    @major\n  end\n\n  def major=(value)\n    @major = value\n  end\n\n  def minor\n    @minor\n  end\n\n  def minor=(value)\n    @minor = value\n  end\n\n  def initialize(major = nil,\n      minor = nil)\n    @major = major\n    @minor = minor\n  end\nend\n\n# http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\nclass Product\n  @@schema_type = \"Product\"\n  @@schema_ns = \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n\n  def id\n    @id\n  end\n\n  def id=(value)\n    @id = value\n  end\n\n  def name\n    @name\n  end\n\n  def name=(value)\n    @name = value\n  end\n\n  def short_description\n    @short_description\n  end\n\n  def short_description=(value)\n    @short_description = value\n  end\n\n  def version\n    @version\n  end\n\n  def version=(value)\n    @version = value\n  end\n\n  def status\n    @status\n  end\n\n  def status=(value)\n    @status = value\n  end\n\n  def homepage\n    @homepage\n  end\n\n  def homepage=(value)\n    @homepage = value\n  end\n\n  def download\n    @download\n  end\n\n  def download=(value)\n    @download = value\n  end\n\n  def license\n    @license\n  end\n\n  def license=(value)\n    @license = value\n  end\n\n  def description\n    @description\n  end\n\n  def description=(value)\n    @description = value\n  end\n\n  def initialize(id = nil,\n      name = nil,\n      short_description = nil,\n      version = nil,\n      status = nil,\n      homepage = nil,\n      download = nil,\n      license = nil,\n      description = nil)\n    @id = id\n    @name = name\n    @short_description = short_description\n    @version = version\n    @status = status\n    @homepage = homepage\n    @download = download\n    @license = license\n    @description = description\n  end\nend\n\n# http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\nclass Owner\n  @@schema_type = \"Owner\"\n  @@schema_ns = \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n\n  def id\n    @id\n  end\n\n  def id=(value)\n    @id = value\n  end\n\n  def email\n    @email\n  end\n\n  def email=(value)\n    @email = value\n  end\n\n  def name\n    @name\n  end\n\n  def name=(value)\n    @name = value\n  end\n\n  def initialize(id = nil,\n      email = nil,\n      name = nil)\n    @id = id\n    @email = email\n    @name = name\n  end\nend\n\n# http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\nclass Info\n  @@schema_type = \"Info\"\n  @@schema_ns = \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n\n  def category\n    @category\n  end\n\n  def category=(value)\n    @category = value\n  end\n\n  def product\n    @product\n  end\n\n  def product=(value)\n    @product = value\n  end\n\n  def owner\n    @owner\n  end\n\n  def owner=(value)\n    @owner = value\n  end\n\n  def created\n    @created\n  end\n\n  def created=(value)\n    @created = value\n  end\n\n  def updated\n    @updated\n  end\n\n  def updated=(value)\n    @updated = value\n  end\n\n  def initialize(category = nil,\n      product = nil,\n      owner = nil,\n      created = nil,\n      updated = nil)\n    @category = category\n    @product = product\n    @owner = owner\n    @created = created\n    @updated = updated\n  end\nend\n\n# http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\nclass InfoArray < Array\n  # Contents type should be dumped here...\n  @@schema_type = \"InfoArray\"\n  @@schema_ns = \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\nend\n\n# http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\nclass StringArray < Array\n  # Contents type should be dumped here...\n  @@schema_type = \"StringArray\"\n  @@schema_ns = \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\nend\n\n# http://xml.apache.org/xml-soap\nclass Map < Array\n  # Contents type should be dumped here...\n  @@schema_type = \"Map\"\n  @@schema_ns = \"http://xml.apache.org/xml-soap\"\nend\n\n"
  },
  {
    "path": "test/wsdl/raa/RAAServant.rb",
    "content": "class RAABaseServicePortType\n  # SYNOPSIS\n  #   getAllListings\n  #\n  # ARGS\n  #   N/A\n  #\n  # RETURNS\n  #   return\t\tStringArray - {http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/}StringArray\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def getAllListings\n    #raise NotImplementedError.new\n    [\"ruby\", \"soap4r\"]\n  end\n  \n  # SYNOPSIS\n  #   getProductTree\n  #\n  # ARGS\n  #   N/A\n  #\n  # RETURNS\n  #   return\t\tMap - {http://xml.apache.org/xml-soap}Map\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def getProductTree\n    raise NotImplementedError.new\n  end\n  \n  # SYNOPSIS\n  #   getInfoFromCategory(category)\n  #\n  # ARGS\n  #   category\t\tCategory - {http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/}Category\n  #\n  # RETURNS\n  #   return\t\tInfoArray - {http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/}InfoArray\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def getInfoFromCategory(category)\n    raise NotImplementedError.new\n  end\n  \n  # SYNOPSIS\n  #   getModifiedInfoSince(timeInstant)\n  #\n  # ARGS\n  #   timeInstant\t\t - {http://www.w3.org/2001/XMLSchema}dateTime\n  #\n  # RETURNS\n  #   return\t\tInfoArray - {http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/}InfoArray\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def getModifiedInfoSince(timeInstant)\n    raise NotImplementedError.new\n  end\n  \n  # SYNOPSIS\n  #   getInfoFromName(productName)\n  #\n  # ARGS\n  #   productName\t\t - {http://www.w3.org/2001/XMLSchema}string\n  #\n  # RETURNS\n  #   return\t\tInfo - {http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/}Info\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def getInfoFromName(productName)\n    raise NotImplementedError.new\n  end\n  \n  # SYNOPSIS\n  #   getInfoFromOwnerId(ownerId)\n  #\n  # ARGS\n  #   ownerId\t\t - {http://www.w3.org/2001/XMLSchema}int\n  #\n  # RETURNS\n  #   return\t\tInfoArray - {http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/}InfoArray\n  #\n  # RAISES\n  #   (undefined)\n  #\n  def getInfoFromOwnerId(ownerId)\n    raise NotImplementedError.new\n  end\nend\n\n"
  },
  {
    "path": "test/wsdl/raa/RAAService.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'RAAServant.rb'\n\nrequire 'soap/rpc/standaloneServer'\n\nclass RAABaseServicePortType\n  MappingRegistry = SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    StringArray,\n    ::SOAP::SOAPArray,\n    ::SOAP::Mapping::Registry::TypedArrayFactory,\n    { :type => XSD::QName.new(\"http://www.w3.org/2001/XMLSchema\", \"string\") }\n  )\n  MappingRegistry.set(\n    Map,\n    ::SOAP::SOAPArray,\n    ::SOAP::Mapping::Registry::TypedArrayFactory,\n    { :type => XSD::QName.new(\"http://www.w3.org/2001/XMLSchema\", \"anyType\") }\n  )\n  MappingRegistry.set(\n    Category,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Category\") }\n  )\n  MappingRegistry.set(\n    InfoArray,\n    ::SOAP::SOAPArray,\n    ::SOAP::Mapping::Registry::TypedArrayFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\") }\n  )\n  MappingRegistry.set(\n    Info,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\") }\n  )\n  MappingRegistry.set(\n    Product,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Product\") }\n  )\n  MappingRegistry.set(\n    Owner,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Owner\") }\n  )\n\n\n  Methods = [\n    [\"getAllListings\", \"getAllListings\", [\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.w3.org/2001/XMLSchema\", \"string\"]]], \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getProductTree\", \"getProductTree\", [\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.w3.org/2001/XMLSchema\", \"anyType\"]]], \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getInfoFromCategory\", \"getInfoFromCategory\", [\n      [\"in\", \"category\",\n       [::SOAP::SOAPStruct, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Category\"]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]], \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getModifiedInfoSince\", \"getModifiedInfoSince\", [\n      [\"in\", \"timeInstant\",\n       [SOAP::SOAPDateTime]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]], \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getInfoFromName\", \"getInfoFromName\", [\n      [\"in\", \"productName\",\n       [SOAP::SOAPString]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPStruct, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]], \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getInfoFromOwnerId\", \"getInfoFromOwnerId\", [\n      [\"in\", \"ownerId\",\n       [SOAP::SOAPInt]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]], \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"]\n  ]\nend\n\nclass App < SOAP::RPC::StandaloneServer\n  def initialize(*arg)\n    super\n\n    servant = RAABaseServicePortType.new\n    RAABaseServicePortType::Methods.each do |name_as, name, params, soapaction, namespace|\n      qname = XSD::QName.new(namespace, name_as)\n      @router.add_method(servant, qname, soapaction, name, params)\n    end\n\n    self.mapping_registry = RAABaseServicePortType::MappingRegistry\n  end\nend\n\n# Change listen port.\nif $0 == __FILE__\n  App.new('app', nil, '0.0.0.0', 10080).start\nend\n"
  },
  {
    "path": "test/wsdl/raa/README.txt",
    "content": "RAAServant.rb: based on the file which is generated with the following command;\n  bin/wsdl2ruby.rb --wsdl raa.wsdl --servant_skelton --force\n\nRAAService.rb: generated with the following command;\n  bin/wsdl2ruby.rb --wsdl raa.wsdl --standalone_server_stub --force\n\nRAA.rb: generated with the following command;\n  bin/wsdl2ruby.rb --wsdl raa.wsdl --classdef --force\n"
  },
  {
    "path": "test/wsdl/raa/raa.wsdl",
    "content": "<?xml version=\"1.0\"?>\n<definitions\n    name=\"RAA\"\n    targetNamespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n    xmlns:tns=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n    xmlns:txd=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n    xmlns:apachesoap=\"http://xml.apache.org/xml-soap\">\n\n  <types>\n    <schema\n\txmlns=\"http://www.w3.org/2001/XMLSchema\"\n\ttargetNamespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\">\n\n      <complexType name=\"Category\">\n  \t<all>\n    \t  <element name=\"major\" type=\"string\"/>\n\t  <element name=\"minor\" type=\"string\"/>\n  \t</all>\n      </complexType>\n\n      <complexType name=\"Product\">\n  \t<all>\n    \t  <element name=\"id\" type=\"int\"/>\n    \t  <element name=\"name\" type=\"string\"/>\n    \t  <element name=\"short_description\" type=\"string\"/>\n\t  <element name=\"version\" type=\"string\"/>\n\t  <element name=\"status\" type=\"string\"/>\n\t  <element name=\"homepage\" type=\"anyURI\"/>\n\t  <element name=\"download\" type=\"anyURI\"/>\n\t  <element name=\"license\" type=\"string\"/>\n\t  <element name=\"description\" type=\"string\"/>\n  \t</all>\n      </complexType>\n\n      <complexType name=\"Owner\">\n  \t<all>\n    \t  <element name=\"id\" type=\"int\"/>\n\t  <element name=\"email\" type=\"anyURI\"/>\n\t  <element name=\"name\" type=\"string\"/>\n  \t</all>\n      </complexType>\n\n      <complexType name=\"Info\">\n  \t<all>\n    \t  <element name=\"category\" type=\"txd:Category\"/>\n    \t  <element name=\"product\" type=\"txd:Product\"/>\n\t  <element name=\"owner\" type=\"txd:Owner\"/>\n\t  <element name=\"created\" type=\"xsd:dateTime\"/>\n\t  <element name=\"updated\" type=\"xsd:dateTime\"/>\n  \t</all>\n      </complexType>\n\n      <import namespace=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      <complexType name=\"InfoArray\">\n\t<complexContent>\n  \t  <restriction base=\"soapenc:Array\">\n  \t    <attribute ref=\"soapenc:arrayType\" wsdl:arrayType=\"txd:Info[]\"/>\n  \t  </restriction>\n\t</complexContent>\n      </complexType>\n\n      <complexType name=\"StringArray\">\n\t<complexContent>\n  \t  <restriction base=\"soapenc:Array\">\n  \t    <attribute ref=\"soapenc:arrayType\" wsdl:arrayType=\"xsd:string[]\"/>\n  \t  </restriction>\n\t</complexContent>\n      </complexType>\n    </schema>\n\n    <!-- type definition for ApacheSOAP's Map -->\n    <schema\n\txmlns=\"http://www.w3.org/2001/XMLSchema\"\n\ttargetNamespace=\"http://xml.apache.org/xml-soap\">\n      <complexType name=\"Map\">\n\t<sequence>\n\t  <element name=\"item\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n\t    <complexType>\n\t      <sequence>\n\t\t<element name=\"key\" type=\"anyType\" />\n\t\t<element name=\"value\" type=\"anyType\" />\n\t      </sequence>\n\t    </complexType>\n\t  </element>\n\t</sequence>\n      </complexType>\n    </schema>\n  </types>\n\n  <message name=\"getAllListingsRequest\"/>\n  <message name=\"getAllListingsResponse\">\n    <part name=\"return\" type=\"txd:StringArray\"/>\n  </message>\n\n  <message name=\"getProductTreeRequest\"/>\n  <message name=\"getProductTreeResponse\">\n    <part name=\"return\" type=\"apachesoap:Map\"/>\n  </message>\n\n  <message name=\"getInfoFromCategoryRequest\">\n    <part name=\"category\" type=\"txd:Category\"/>\n  </message>\n  <message name=\"getInfoFromCategoryResponse\">\n    <part name=\"return\" type=\"txd:InfoArray\"/>\n  </message>\n\n  <message name=\"getModifiedInfoSinceRequest\">\n    <part name=\"timeInstant\" type=\"xsd:dateTime\"/>\n  </message>\n  <message name=\"getModifiedInfoSinceResponse\">\n    <part name=\"return\" type=\"txd:InfoArray\"/>\n  </message>\n\n  <message name=\"getInfoFromNameRequest\">\n    <part name=\"productName\" type=\"xsd:string\"/>\n  </message>\n  <message name=\"getInfoFromNameResponse\">\n    <part name=\"return\" type=\"txd:Info\"/>\n  </message>\n\n  <message name=\"getInfoFromOwnerIdRequest\">\n    <part name=\"ownerId\" type=\"xsd:int\"/>\n  </message>\n  <message name=\"getInfoFromOwnerIdResponse\">\n    <part name=\"return\" type=\"txd:InfoArray\"/>\n  </message>\n\n  <portType name=\"RAABaseServicePortType\">\n    <operation name=\"getAllListings\"\n\tparameterOrder=\"\">\n      <input message=\"tns:getAllListingsRequest\"/>\n      <output message=\"tns:getAllListingsResponse\"/>\n    </operation>\n\n    <operation name=\"getProductTree\"\n\tparameterOrder=\"\">\n      <input message=\"tns:getProductTreeRequest\"/>\n      <output message=\"tns:getProductTreeResponse\"/>\n    </operation>\n\n    <operation name=\"getInfoFromCategory\"\n\tparameterOrder=\"category\">\n      <input message=\"tns:getInfoFromCategoryRequest\"/>\n      <output message=\"tns:getInfoFromCategoryResponse\"/>\n    </operation>\n\n    <operation name=\"getModifiedInfoSince\"\n\tparameterOrder=\"timeInstant\">\n      <input message=\"tns:getModifiedInfoSinceRequest\"/>\n      <output message=\"tns:getModifiedInfoSinceResponse\"/>\n    </operation>\n\n    <operation name=\"getInfoFromName\"\n\tparameterOrder=\"productName\">\n      <input message=\"tns:getInfoFromNameRequest\"/>\n      <output message=\"tns:getInfoFromNameResponse\"/>\n    </operation>\n\n    <operation name=\"getInfoFromOwnerId\"\n\tparameterOrder=\"ownerId\">\n      <input message=\"tns:getInfoFromOwnerIdRequest\"/>\n      <output message=\"tns:getInfoFromOwnerIdResponse\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"RAABaseServicePortBinding\" type=\"tns:RAABaseServicePortType\">\n    <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n\n    <operation name=\"getAllListings\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"getProductTree\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"getInfoFromCategory\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"getModifiedInfoSince\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"getInfoFromName\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"getInfoFromOwnerId\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"RAAService\">\n    <port name=\"RAABaseServicePort\" binding=\"tns:RAABaseServicePortBinding\">\n      <soap:address location=\"http://raa.ruby-lang.org/soap/1.0.2/\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/raa/server.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'soap/rpc/standaloneServer'\nrequire 'RAA.rb'\n\nclass RAABaseServicePortType\n  MappingRegistry = SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    StringArray,\n    ::SOAP::SOAPArray,\n    ::SOAP::Mapping::Registry::TypedArrayFactory,\n    { :type => XSD::QName.new(\"http://www.w3.org/2001/XMLSchema\", \"string\") }\n  )\n  MappingRegistry.set(\n    Map,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://xml.apache.org/xml-soap\", \"Map\") }\n  )\n  MappingRegistry.set(\n    Category,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Category\") }\n  )\n  MappingRegistry.set(\n    InfoArray,\n    ::SOAP::SOAPArray,\n    ::SOAP::Mapping::Registry::TypedArrayFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\") }\n  )\n  MappingRegistry.set(\n    Info,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\") }\n  )\n  MappingRegistry.set(\n    Product,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Product\") }\n  )\n  MappingRegistry.set(\n    Owner,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Owner\") }\n  )\n  \n  Methods = [\n    [\"getAllListings\", \"getAllListings\", [\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.w3.org/2001/XMLSchema\", \"string\"]]],\n     \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getProductTree\", \"getProductTree\", [\n      [\"retval\", \"return\",\n       [::SOAP::SOAPStruct, \"http://xml.apache.org/xml-soap\", \"Map\"]]],\n     \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getInfoFromCategory\", \"getInfoFromCategory\", [\n      [\"in\", \"category\",\n       [::SOAP::SOAPStruct, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Category\"]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]],\n     \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getModifiedInfoSince\", \"getModifiedInfoSince\", [\n      [\"in\", \"timeInstant\",\n       [SOAP::SOAPDateTime]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]],\n     \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getInfoFromName\", \"getInfoFromName\", [\n      [\"in\", \"productName\",\n       [SOAP::SOAPString]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPStruct, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]],\n     \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"],\n    [\"getInfoFromOwnerId\", \"getInfoFromOwnerId\", [\n      [\"in\", \"ownerId\",\n       [SOAP::SOAPInt]],\n      [\"retval\", \"return\",\n       [::SOAP::SOAPArray, \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\", \"Info\"]]],\n     \"\", \"http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.2/\"]\n  ]\n\n  def getAllListings\n    [\"ruby\", \"soap4r\"]\n  end\nend\n\nclass RAABaseServiceServer < SOAP::RPC::StandaloneServer\n  def initialize(*arg)\n    super\n\n    servant = RAABaseServicePortType.new\n    RAABaseServicePortType::Methods.each do |name_as, name, params, soapaction, namespace|\n      qname = XSD::QName.new(namespace, name_as)\n      @router.add_method(servant, qname, soapaction, name, params)\n    end\n\n    self.mapping_registry = RAABaseServicePortType::MappingRegistry\n  end\nend\n"
  },
  {
    "path": "test/wsdl/raa/test_raa.rb",
    "content": "require 'test/unit'\nrequire 'soap/wsdlDriver'\nrequire 'RAA.rb'\nrequire 'RAAServant.rb'\nrequire 'RAAService.rb'\n\n\nmodule WSDL\nmodule RAA\n\n\nclass TestRAA < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = App.new('RAA server', nil, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'raa.wsdl')\n    @raa = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @raa.endpoint_url = \"http://localhost:#{Port}/\"\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @raa.reset_stream\n  end\n\n  def test_raa\n    assert_equal([\"ruby\", \"soap4r\"], @raa.getAllListings)\n  end\n\n  def foo\n    p @raa.getProductTree()\n    p @raa.getInfoFromCategory(Category.new(\"Library\", \"XML\"))\n    t = Time.at(Time.now.to_i - 24 * 3600)\n    p @raa.getModifiedInfoSince(t)\n    p @raa.getModifiedInfoSince(DateTime.new(t.year, t.mon, t.mday, t.hour, t.min, t.sec))\n    o = @raa.getInfoFromName(\"SOAP4R\")\n    p o.type\n    p o.owner.name\n    p o\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/wsdl/ref/expectedProduct.rb",
    "content": "require 'xsd/qname'\n\n# {urn:product}Rating\nmodule Rating\n  C_0 = \"0\"\n  C_1 = \"+1\"\n  C_1_2 = \"-1\"\nend\n\n# {urn:product}Product-Bag\nclass ProductBag\n  @@schema_type = \"Product-Bag\"\n  @@schema_ns = \"urn:product\"\n  @@schema_attribute = {XSD::QName.new(\"urn:product\", \"version\") => \"SOAP::SOAPString\", XSD::QName.new(\"urn:product\", \"yesno\") => \"SOAP::SOAPString\"}\n  @@schema_element = [[\"bag\", [\"Product[]\", XSD::QName.new(nil, \"bag\")]], [\"rating\", [\"SOAP::SOAPString[]\", XSD::QName.new(\"urn:product\", \"Rating\")]], [\"product_Bag\", [nil, XSD::QName.new(\"urn:product\", \"Product-Bag\")]], [\"comment_1\", [nil, XSD::QName.new(nil, \"comment_1\")]], [\"comment_2\", [\"Comment[]\", XSD::QName.new(nil, \"comment-2\")]]]\n\n  attr_accessor :bag\n  attr_accessor :product_Bag\n  attr_accessor :comment_1\n  attr_accessor :comment_2\n\n  def Rating\n    @rating\n  end\n\n  def Rating=(value)\n    @rating = value\n  end\n\n  def xmlattr_version\n    (@__xmlattr ||= {})[XSD::QName.new(\"urn:product\", \"version\")]\n  end\n\n  def xmlattr_version=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(\"urn:product\", \"version\")] = value\n  end\n\n  def xmlattr_yesno\n    (@__xmlattr ||= {})[XSD::QName.new(\"urn:product\", \"yesno\")]\n  end\n\n  def xmlattr_yesno=(value)\n    (@__xmlattr ||= {})[XSD::QName.new(\"urn:product\", \"yesno\")] = value\n  end\n\n  def initialize(bag = [], rating = [], product_Bag = nil, comment_1 = [], comment_2 = [])\n    @bag = bag\n    @rating = rating\n    @product_Bag = product_Bag\n    @comment_1 = comment_1\n    @comment_2 = comment_2\n    @__xmlattr = {}\n  end\nend\n\n# {urn:product}Creator\nclass Creator\n  @@schema_type = \"Creator\"\n  @@schema_ns = \"urn:product\"\n  @@schema_element = []\n\n  def initialize\n  end\nend\n\n# {urn:product}Product\nclass Product\n  @@schema_type = \"Product\"\n  @@schema_ns = \"urn:product\"\n  @@schema_element = [[\"name\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"name\")]], [\"rating\", [\"SOAP::SOAPString\", XSD::QName.new(\"urn:product\", \"Rating\")]]]\n\n  attr_accessor :name\n\n  def Rating\n    @rating\n  end\n\n  def Rating=(value)\n    @rating = value\n  end\n\n  def initialize(name = nil, rating = nil)\n    @name = name\n    @rating = rating\n  end\nend\n\n# {urn:product}Comment\nclass Comment < String\nend\n"
  },
  {
    "path": "test/wsdl/ref/product.wsdl",
    "content": "<?xml version=\"1.0\"?>\n<definitions name=\"product\"\n    targetNamespace=\"urn:product\"\n    xmlns:tns=\"urn:product\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema xmlns=\"http://www.w3.org/2001/XMLSchema\"\n        targetNamespace=\"urn:product\">\n      <simpleType name=\"non-empty-string\">\n        <restriction base=\"xsd:string\">\n          <minLength value=\"1\"/>\n        </restriction>\n      </simpleType>\n\n      <complexType name=\"Product\">\n        <all>\n          <element name=\"name\" type=\"xsd:string\"/>\n          <element ref=\"tns:Rating\"/>\n        </all>\n      </complexType>\n\n      <complexType name=\"Comment\">\n        <simpleContent>\n          <extension base=\"xsd:string\">\n            <attribute name=\"msgid\" type=\"xsd:string\" use=\"required\"/>\n          </extension>\n        </simpleContent>\n      </complexType>\n\n      <attribute name=\"version\" type=\"tns:non-empty-string\"/>\n\n      <attribute default=\"Y\" name=\"yesno\">\n        <simpleType>\n          <restriction base=\"xsd:string\">\n            <enumeration value=\"Y\"/>\n            <enumeration value=\"N\"/>\n          </restriction>\n        </simpleType>\n      </attribute>\n\n      <element name=\"Rating\">\n        <simpleType>\n          <restriction base=\"xsd:string\">\n            <enumeration value=\"+1\"/>\n            <enumeration value=\"0\"/>\n            <enumeration value=\"-1\"/>\n          </restriction>\n        </simpleType>\n      </element>\n\n      <element name=\"Product-Bag\">\n        <complexType>\n          <sequence>\n            <element name=\"bag\" type=\"tns:Product\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n            <element ref=\"tns:Rating\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n            <element ref=\"tns:Product-Bag\"/>\n            <element name=\"comment_1\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n              <complexType>\n                <simpleContent>\n                  <extension base=\"xsd:string\">\n                    <attribute name=\"msgid\" type=\"xsd:string\" use=\"required\"/>\n                  </extension>\n                </simpleContent>\n              </complexType>\n            </element>\n            <element name=\"comment-2\" type=\"tns:Comment\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n          </sequence>\n          <attribute ref=\"tns:version\"/>\n          <attribute ref=\"tns:yesno\"/>\n        </complexType>\n      </element>\n\n      <element name=\"Creator\" minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <complexType>\n          <simpleContent>\n            <extension base=\"xsd:string\">\n              <attribute name=\"Role\" type=\"xs:string\" use=\"required\"/>\n            </extension>\n          </simpleContent>\n        </complexType>\n      </element>\n    </xsd:schema>\n  </types>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/ref/test_ref.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\nrequire 'wsdl/soap/wsdl2ruby'\n\n\nmodule WSDL\nmodule Ref\n\n\nclass TestRef < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n  Port = 17171\n\n  def test_classdef\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"product.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['force'] = true\n    suppress_warning do\n      gen.run\n    end\n    compare(\"expectedProduct.rb\", \"product.rb\")\n    File.unlink(pathname('product.rb'))\n  end\n\n  def compare(expected, actual)\n    assert_equal(loadfile(expected), loadfile(actual), actual)\n  end\n\n  def loadfile(file)\n    File.open(pathname(file)) { |f| f.read }\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def suppress_warning\n    back = $VERBOSE\n    $VERBOSE = nil\n    begin\n      yield\n    ensure\n      $VERBOSE = back\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/wsdl/rpc/echoDriver.rb",
    "content": "require 'echo.rb'\n\nrequire 'soap/rpc/driver'\n\nclass Echo_port_type < ::SOAP::RPC::Driver\n  DefaultEndpointUrl = \"http://localhost:10080\"\n  MappingRegistry = ::SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    Person,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"urn:rpc-type\", \"person\") }\n  )\n\n  Methods = [\n    [\"echo\", \"echo\",\n      [\n        [\"in\", \"arg1\", [::SOAP::SOAPStruct, \"urn:rpc-type\", \"person\"]],\n        [\"in\", \"arg2\", [::SOAP::SOAPStruct, \"urn:rpc-type\", \"person\"]],\n        [\"retval\", \"return\", [::SOAP::SOAPStruct, \"urn:rpc-type\", \"person\"]]\n      ],\n      \"\", \"urn:rpc\", :rpc\n    ]\n  ]\n\n  def initialize(endpoint_url = nil)\n    endpoint_url ||= DefaultEndpointUrl\n    super(endpoint_url, nil)\n    self.mapping_registry = MappingRegistry\n    init_methods\n  end\n\nprivate\n\n  def init_methods\n    Methods.each do |name_as, name, params, soapaction, namespace, style|\n      qname = XSD::QName.new(namespace, name_as)\n      if style == :document\n        @proxy.add_document_method(soapaction, name, params)\n        add_document_method_interface(name, params)\n      else\n        @proxy.add_rpc_method(qname, soapaction, name, params)\n        add_rpc_method_interface(name, params)\n      end\n      if name_as != name and name_as.capitalize == name.capitalize\n        sclass = class << self; self; end\n        sclass.__send__(:define_method, name_as, proc { |*arg|\n          __send__(name, *arg)\n        })\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "test/wsdl/rpc/echo_serviceClient.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'echoDriver.rb'\n\nendpoint_url = ARGV.shift\nobj = Echo_port_type.new(endpoint_url)\n\n# Uncomment the below line to see SOAP wiredumps.\n# obj.wiredump_dev = STDERR\n\n# SYNOPSIS\n#   echo(arg1, arg2)\n#\n# ARGS\n#   arg1            Person - {urn:rpc-type}person\n#   arg2            Person - {urn:rpc-type}person\n#\n# RETURNS\n#   v_return        Person - {urn:rpc-type}person\n#\narg1 = arg2 = nil\nputs obj.echo(arg1, arg2)\n\n\n"
  },
  {
    "path": "test/wsdl/rpc/rpc.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name=\"echo\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:rpc\"\n    xmlns:txd=\"urn:rpc-type\"\n    targetNamespace=\"urn:rpc\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema targetNamespace=\"urn:rpc-type\">\n      <xsd:complexType name=\"person\">\n\t<xsd:all>\n\t  <xsd:element name=\"family-name\" type=\"xsd:string\" />\n\t  <xsd:element name=\"given_name\" type=\"xsd:string\" />\n\t  <xsd:element name=\"age\" type=\"xsd:int\" />\n\t  <xsd:element name=\"link\" type=\"txd:person\" />\n\t</xsd:all>\n      </xsd:complexType>\n    </xsd:schema>\n  </types>\n\n  <message name=\"echo_in\">\n    <part name=\"arg1\" type=\"txd:person\"/>\n    <part name=\"arg2\" type=\"txd:person\"/>\n  </message>\n\n  <message name=\"echo_out\">\n    <part name=\"return\" type=\"txd:person\"/>\n  </message>\n\n  <portType name=\"echo_port_type\">\n    <operation name=\"echo\">\n      <input message=\"tns:echo_in\"/>\n      <output message=\"tns:echo_out\"/>\n    </operation>\n\n    <operation name=\"echo_err\">\n      <input message=\"tns:echo_in\"/>\n      <output message=\"tns:echo_out\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"echo_binding\" type=\"tns:echo_port_type\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"rpc\"/>\n    <operation name=\"echo\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"echo_err\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"echo_service\">\n    <port name=\"echo_port\" binding=\"tns:echo_binding\">\n      <soap:address location=\"http://localhost:10080\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/rpc/test-rpc-lit.wsdl",
    "content": "<?xml version=\"1.0\"?>\n\n<definitions name=\"RPC-Literal-TestDefinitions\"\n  targetNamespace=\"http://whitemesa.net/wsdl/rpc-lit-test\"\n  xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n  xmlns:soap11=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n  xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns:tns=\"http://whitemesa.net/wsdl/rpc-lit-test\"\n  xmlns:types=\"http://soapbuilders.org/rpc-lit-test/types\"\n  xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <schema xmlns=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://soapbuilders.org/rpc-lit-test/types\">\n\n      <element name=\"stringItem\" type=\"xsd:string\" />\n      <complexType name=\"ArrayOfstring\">\n        <sequence>\n          <element ref=\"types:stringItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </sequence>\n      </complexType>\n\n      <complexType name=\"ArrayOfstringInline\">\n        <sequence>\n          <element name=\"stringItem\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </sequence>\n      </complexType>\n\n      <complexType name=\"ArrayOfint\">\n        <sequence>\n          <element name=\"integer\" type=\"xsd:int\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </sequence>\n      </complexType>\n\n      <element name=\"structItem\" type=\"types:SOAPStruct\" />\n      <complexType name=\"SOAPStruct\">\n        <all>\n          <element name=\"varString\" type=\"xsd:string\"/>\n          <element name=\"varInt\" type=\"xsd:int\"/>\n          <element name=\"varFloat\" type=\"xsd:float\"/>\n        </all>\n      </complexType>\n\n      <complexType name=\"ArrayOfSOAPStruct\">\n        <sequence>\n          <element ref=\"types:structItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n        </sequence>\n      </complexType>\n\n      <complexType name=\"SOAPStructStruct\">\n        <all>\n          <element name=\"varString\" type=\"xsd:string\"/>\n          <element name=\"varInt\" type=\"xsd:int\"/>\n          <element name=\"varFloat\" type=\"xsd:float\"/>\n          <element ref=\"types:structItem\" />\n        </all>\n      </complexType>\n\n      <complexType name=\"SOAPArrayStruct\">\n        <all>\n          <element name=\"varString\" type=\"xsd:string\"/>\n          <element name=\"varInt\" type=\"xsd:int\"/>\n          <element name=\"varFloat\" type=\"xsd:float\"/>\n          <element name=\"varArray\" type=\"types:ArrayOfstring\"/>\n        </all>\n      </complexType>\n\n    </schema>\n\n  </types>\n\n  <!-- echoStruct rpc operation -->\n  <message name=\"echoStructRequest\">\n    <part name=\"inputStruct\" type=\"types:SOAPStruct\"/>\n  </message>\n  <message name=\"echoStructResponse\">\n    <part name=\"return\" type=\"types:SOAPStruct\"/>\n  </message>\n\n  <!-- echoStructArray rpc operation -->\n  <message name=\"echoStructArrayRequest\">\n    <part name=\"inputStructArray\" type=\"types:ArrayOfSOAPStruct\"/>\n  </message>\n  <message name=\"echoStructArrayResponse\">\n    <part name=\"return\" type=\"types:ArrayOfSOAPStruct\"/>\n  </message>\n\n  <!-- echoStructAsSimpleTypes rpc operation -->\n  <message name=\"echoStructAsSimpleTypesRequest\">\n    <part name=\"inputStruct\" type=\"types:SOAPStruct\"/>\n  </message>\n  <message name=\"echoStructAsSimpleTypesResponse\">\n    <part name=\"outputString\" type=\"xsd:string\"/>\n    <part name=\"outputInteger\" type=\"xsd:int\"/>\n    <part name=\"outputFloat\" type=\"xsd:float\"/>\n  </message>\n\n  <!-- echoSimpleTypesAsStruct rpc operation -->\n  <message name=\"echoSimpleTypesAsStructRequest\">\n    <part name=\"inputString\" type=\"xsd:string\"/>\n    <part name=\"inputInteger\" type=\"xsd:int\"/>\n    <part name=\"inputFloat\" type=\"xsd:float\"/>\n  </message>\n  <message name=\"echoSimpleTypesAsStructResponse\">\n    <part name=\"return\" type=\"types:SOAPStruct\"/>\n  </message>\n\n  <!-- echoNestedStruct rpc operation -->\n  <message name=\"echoNestedStructRequest\">\n    <part name=\"inputStruct\" type=\"types:SOAPStructStruct\"/>\n  </message>\n  <message name=\"echoNestedStructResponse\">\n    <part name=\"return\" type=\"types:SOAPStructStruct\"/>\n  </message>\n\n  <!-- echoNestedArray rpc operation -->\n  <message name=\"echoNestedArrayRequest\">\n    <part name=\"inputStruct\" type=\"types:SOAPArrayStruct\"/>\n  </message>\n  <message name=\"echoNestedArrayResponse\">\n    <part name=\"return\" type=\"types:SOAPArrayStruct\"/>\n  </message>\n\n  <!-- echoStringArray rpc operation -->\n  <message name=\"echoStringArrayRequest\">\n    <part name=\"inputStringArray\" type=\"types:ArrayOfstring\"/>\n  </message>\n  <message name=\"echoStringArrayResponse\">\n    <part name=\"return\" type=\"types:ArrayOfstring\"/>\n  </message>\n\n  <message name=\"echoStringArrayInlineRequest\">\n    <part name=\"inputStringArray\" type=\"types:ArrayOfstringInline\"/>\n  </message>\n  <message name=\"echoStringArrayInlineResponse\">\n    <part name=\"return\" type=\"types:ArrayOfstringInline\"/>\n  </message>\n\n  <!-- echoIntegerArray rpc operation -->\n  <message name=\"echoIntegerArrayRequest\">\n    <part name=\"inputIntegerArray\" type=\"types:ArrayOfint\"/>\n  </message>\n  <message name=\"echoIntegerArrayResponse\">\n    <part name=\"return\" type=\"types:ArrayOfint\"/>\n  </message>\n\n  <!-- echoBoolean rpc operation -->\n  <message name=\"echoBooleanRequest\">\n    <part name=\"inputBoolean\" type=\"xsd:boolean\"/>\n  </message>\n  <message name=\"echoBooleanResponse\">\n    <part name=\"return\" type=\"xsd:boolean\"/>\n  </message>\n\n  <!-- echoString rpc operation -->\n  <message name=\"echoStringRequest\">\n    <part name=\"inputString\" type=\"xsd:string\"/>\n  </message>\n  <message name=\"echoStringResponse\">\n    <part name=\"return\" type=\"xsd:string\"/>\n  </message>\n\n\n  <portType name=\"SoapTestPortTypeRpc\">\n\n    <!-- echoStruct rpc operation -->\n    <operation name=\"echoStruct\" parameterOrder=\"inputStruct\">\n      <input message=\"tns:echoStructRequest\"/>\n      <output message=\"tns:echoStructResponse\"/>\n    </operation>\n\n    <!-- echoStructArray rpc operation -->\n    <operation name=\"echoStructArray\" parameterOrder=\"inputStructArray\">\n      <input message=\"tns:echoStructArrayRequest\"/>\n      <output message=\"tns:echoStructArrayResponse\"/>\n    </operation>\n\n    <!-- echoStructAsSimpleTypes rpc operation -->\n    <operation name=\"echoStructAsSimpleTypes\" parameterOrder=\"inputStruct outputString outputInteger outputFloat\">\n      <input message=\"tns:echoStructAsSimpleTypesRequest\"/>\n      <output message=\"tns:echoStructAsSimpleTypesResponse\"/>\n    </operation>\n\n    <!-- echoSimpleTypesAsStruct rpc operation -->\n    <operation name=\"echoSimpleTypesAsStruct\" parameterOrder=\"inputString inputInteger inputFloat\">\n      <input message=\"tns:echoSimpleTypesAsStructRequest\"/>\n      <output message=\"tns:echoSimpleTypesAsStructResponse\"/>\n    </operation>\n\n    <!-- echoNestedStruct rpc operation -->\n    <operation name=\"echoNestedStruct\" parameterOrder=\"inputStruct\">\n      <input message=\"tns:echoNestedStructRequest\"/>\n      <output message=\"tns:echoNestedStructResponse\"/>\n    </operation>\n\n    <!-- echoNestedArray rpc operation -->\n    <operation name=\"echoNestedArray\" parameterOrder=\"inputStruct\">\n      <input message=\"tns:echoNestedArrayRequest\"/>\n      <output message=\"tns:echoNestedArrayResponse\"/>\n    </operation>\n\n    <!-- echoStringArray rpc operation -->\n    <operation name=\"echoStringArray\" parameterOrder=\"inputStringArray\">\n      <input message=\"tns:echoStringArrayRequest\"/>\n      <output message=\"tns:echoStringArrayResponse\"/>\n    </operation>\n\n    <operation name=\"echoStringArrayInline\" parameterOrder=\"inputStringArray\">\n      <input message=\"tns:echoStringArrayInlineRequest\"/>\n      <output message=\"tns:echoStringArrayInlineResponse\"/>\n    </operation>\n\n    <!-- echoIntegerArray rpc operation -->\n    <operation name=\"echoIntegerArray\" parameterOrder=\"inputIntegerArray\">\n      <input message=\"tns:echoIntegerArrayRequest\"/>\n      <output message=\"tns:echoIntegerArrayResponse\"/>\n    </operation>\n\n    <!-- echoBoolean rpc operation -->\n    <operation name=\"echoBoolean\" parameterOrder=\"inputBoolean\">\n      <input message=\"tns:echoBooleanRequest\"/>\n      <output message=\"tns:echoBooleanResponse\"/>\n    </operation>\n\n    <!-- echoString rpc operation -->\n    <operation name=\"echoString\" parameterOrder=\"inputString\">\n      <input message=\"tns:echoStringRequest\"/>\n      <output message=\"tns:echoStringResponse\"/>\n    </operation>\n\n  </portType>\n\n  <binding name=\"Soap11TestRpcLitBinding\" type=\"tns:SoapTestPortTypeRpc\">\n    <soap11:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n\n    <!-- echoStruct rpc operation -->\n    <operation name=\"echoStruct\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!--  echoStructArray rpc operation -->\n    <operation name=\"echoStructArray\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoStructAsSimpleTypes rpc operation -->\n    <operation name=\"echoStructAsSimpleTypes\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoSimpleTypesAsStruct rpc operation -->\n    <operation name=\"echoSimpleTypesAsStruct\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoNestedStruct rpc operation -->\n    <operation name=\"echoNestedStruct\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoNestedArray rpc operation -->\n    <operation name=\"echoNestedArray\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoStringArray rpc operation -->\n    <operation name=\"echoStringArray\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <operation name=\"echoStringArrayInline\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoIntegerArray rpc operation -->\n    <operation name=\"echoIntegerArray\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoBoolean rpc operation -->\n    <operation name=\"echoBoolean\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n    <!-- echoString rpc operation -->\n    <operation name=\"echoString\">\n      <soap11:operation soapAction=\"http://soapinterop.org/\"/>\n      <input>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </input>\n      <output>\n        <soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n      </output>\n    </operation>\n\n  </binding>\n\n  <service name=\"WhiteMesaSoapRpcLitTestSvc\">\n\n    <port name=\"Soap11TestRpcLitPort\" binding=\"tns:Soap11TestRpcLitBinding\">\n      <soap11:address location=\"http://www.whitemesa.net/test-rpc-lit\"/>\n    </port>\n\n  </service>\n\n</definitions>\n"
  },
  {
    "path": "test/wsdl/rpc/test-rpc-lit12.wsdl",
    "content": "<?xml version=\"1.0\"?>\n\n<definitions name=\"RPC-Literal-TestDefinitions\"\n\ttargetNamespace=\"http://whitemesa.net/wsdl/rpc-lit-test\"\n\txmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n\txmlns:soap12=\"http://schemas.xmlsoap.org/wsdl/soap12/\"\n\txmlns:soap11=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n\txmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n\txmlns:tns=\"http://whitemesa.net/wsdl/rpc-lit-test\"\n\txmlns:types=\"http://soapbuilders.org/rpc-lit-test/types\"\n\txmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\">\n\t<types>\n\t\t<schema xmlns=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://soapbuilders.org/rpc-lit-test/types\">\n\n            <element name=\"stringItem\" type=\"xsd:string\" />\n\t\t\t<complexType name=\"ArrayOfstring\">\n\t\t\t\t<sequence>\n\t\t\t\t\t<element ref=\"types:stringItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n\t\t\t\t</sequence>\n\t\t\t</complexType>\n\n\t\t\t<complexType name=\"ArrayOfint\">\n\t\t\t\t<sequence>\n\t\t\t\t\t<element name=\"integer\" type=\"xsd:int\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n\t\t\t\t</sequence>\n\t\t\t</complexType>\n\n            <element name=\"structItem\" type=\"types:SOAPStruct\" />\n\t\t\t<complexType name=\"SOAPStruct\">\n\t\t\t\t<all>\n\t\t\t\t\t<element name=\"varString\" type=\"xsd:string\"/>\n\t\t\t\t\t<element name=\"varInt\" type=\"xsd:int\"/>\n\t\t\t\t\t<element name=\"varFloat\" type=\"xsd:float\"/>\n\t\t\t\t</all>\n\t\t\t</complexType>\n\t\t\t\n\t\t\t<complexType name=\"ArrayOfSOAPStruct\">\n\t\t\t\t<sequence>\n\t\t\t\t\t<element ref=\"types:structItem\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n\t\t\t\t</sequence>\n\t\t\t</complexType>\n\n\t\t\t<complexType name=\"SOAPStructStruct\">\n\t\t\t\t<all>\n\t\t\t\t\t<element name=\"varString\" type=\"xsd:string\"/>\n\t\t\t\t\t<element name=\"varInt\" type=\"xsd:int\"/>\n\t\t\t\t\t<element name=\"varFloat\" type=\"xsd:float\"/>\n\t\t\t\t\t<element ref=\"types:structItem\" />\n\t\t\t\t</all>\n\t\t\t</complexType>\n\n\t\t\t<complexType name=\"SOAPArrayStruct\">\n\t\t\t\t<all>\n\t\t\t\t\t<element name=\"varString\" type=\"xsd:string\"/>\n\t\t\t\t\t<element name=\"varInt\" type=\"xsd:int\"/>\n\t\t\t\t\t<element name=\"varFloat\" type=\"xsd:float\"/>\n\t\t\t\t\t<element name=\"varArray\" type=\"types:ArrayOfstring\"/>\n\t\t\t\t</all>\n\t\t\t</complexType>\n\n\t\t</schema>\n\n\t</types>\n\n\t<!-- echoStruct rpc operation -->\n\t<message name=\"echoStructRequest\">\n\t\t<part name=\"inputStruct\" type=\"types:SOAPStruct\"/>\n\t</message>\n\t<message name=\"echoStructResponse\">\n\t\t<part name=\"return\" type=\"types:SOAPStruct\"/>\n\t</message>\n\n\t<!-- echoStructArray rpc operation -->\n\t<message name=\"echoStructArrayRequest\">\n\t\t<part name=\"inputStructArray\" type=\"types:ArrayOfSOAPStruct\"/>\n\t</message>\n\t<message name=\"echoStructArrayResponse\">\n\t\t<part name=\"return\" type=\"types:ArrayOfSOAPStruct\"/>\n\t</message>\n\n\t<!-- echoStructAsSimpleTypes rpc operation -->\n\t<message name=\"echoStructAsSimpleTypesRequest\">\n\t\t<part name=\"inputStruct\" type=\"types:SOAPStruct\"/>\n\t</message>\n\t<message name=\"echoStructAsSimpleTypesResponse\">\n\t\t<part name=\"outputString\" type=\"xsd:string\"/>\n\t\t<part name=\"outputInteger\" type=\"xsd:int\"/>\n\t\t<part name=\"outputFloat\" type=\"xsd:float\"/>\n\t</message>\n\n\t<!-- echoSimpleTypesAsStruct rpc operation -->\n\t<message name=\"echoSimpleTypesAsStructRequest\">\n\t\t<part name=\"inputString\" type=\"xsd:string\"/>\n\t\t<part name=\"inputInteger\" type=\"xsd:int\"/>\n\t\t<part name=\"inputFloat\" type=\"xsd:float\"/>\n\t</message>\n\t<message name=\"echoSimpleTypesAsStructResponse\">\n\t\t<part name=\"return\" type=\"types:SOAPStruct\"/>\n\t</message>\n\n\t<!-- echoNestedStruct rpc operation -->\n\t<message name=\"echoNestedStructRequest\">\n\t\t<part name=\"inputStruct\" type=\"types:SOAPStructStruct\"/>\n\t</message>\n\t<message name=\"echoNestedStructResponse\">\n\t\t<part name=\"return\" type=\"types:SOAPStructStruct\"/>\n\t</message>\n\n\t<!-- echoNestedArray rpc operation -->\n\t<message name=\"echoNestedArrayRequest\">\n\t\t<part name=\"inputStruct\" type=\"types:SOAPArrayStruct\"/>\n\t</message>\n\t<message name=\"echoNestedArrayResponse\">\n\t\t<part name=\"return\" type=\"types:SOAPArrayStruct\"/>\n\t</message>\n\n\t<!-- echoStringArray rpc operation -->\n\t<message name=\"echoStringArrayRequest\">\n\t\t<part name=\"inputStringArray\" type=\"types:ArrayOfstring\"/>\n\t</message>\n\t<message name=\"echoStringArrayResponse\">\n\t\t<part name=\"return\" type=\"types:ArrayOfstring\"/>\n\t</message>\n\n\t<!-- echoIntegerArray rpc operation -->\n\t<message name=\"echoIntegerArrayRequest\">\n\t\t<part name=\"inputIntegerArray\" type=\"types:ArrayOfint\"/>\n\t</message>\n\t<message name=\"echoIntegerArrayResponse\">\n\t\t<part name=\"return\" type=\"types:ArrayOfint\"/>\n\t</message>\n\n\t<!-- echoBoolean rpc operation -->\n\t<message name=\"echoBooleanRequest\">\n\t\t<part name=\"inputBoolean\" type=\"xsd:boolean\"/>\n\t</message>\n\t<message name=\"echoBooleanResponse\">\n\t\t<part name=\"return\" type=\"xsd:boolean\"/>\n\t</message>\n\n\t<!-- echoString rpc operation -->\n\t<message name=\"echoStringRequest\">\n\t\t<part name=\"inputString\" type=\"xsd:string\"/>\n\t</message>\n\t<message name=\"echoStringResponse\">\n\t\t<part name=\"return\" type=\"xsd:string\"/>\n\t</message>\n\n\n\t<portType name=\"SoapTestPortTypeRpc\">\n\n\t\t<!-- echoStruct rpc operation -->\n\t\t<operation name=\"echoStruct\" parameterOrder=\"inputStruct\">\n\t\t\t<input message=\"tns:echoStructRequest\"/>\n\t\t\t<output message=\"tns:echoStructResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoStructArray rpc operation -->\n\t\t<operation name=\"echoStructArray\" parameterOrder=\"inputStructArray\">\n\t\t\t<input message=\"tns:echoStructArrayRequest\"/>\n\t\t\t<output message=\"tns:echoStructArrayResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoStructAsSimpleTypes rpc operation -->\n\t\t<operation name=\"echoStructAsSimpleTypes\" parameterOrder=\"inputStruct outputString outputInteger outputFloat\">\n\t\t\t<input message=\"tns:echoStructAsSimpleTypesRequest\"/>\n\t\t\t<output message=\"tns:echoStructAsSimpleTypesResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoSimpleTypesAsStruct rpc operation -->\n\t\t<operation name=\"echoSimpleTypesAsStruct\" parameterOrder=\"inputString inputInteger inputFloat\">\n\t\t\t<input message=\"tns:echoSimpleTypesAsStructRequest\"/>\n\t\t\t<output message=\"tns:echoSimpleTypesAsStructResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoNestedStruct rpc operation -->\n\t\t<operation name=\"echoNestedStruct\" parameterOrder=\"inputStruct\">\n\t\t\t<input message=\"tns:echoNestedStructRequest\"/>\n\t\t\t<output message=\"tns:echoNestedStructResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoNestedArray rpc operation -->\n\t\t<operation name=\"echoNestedArray\" parameterOrder=\"inputStruct\">\n\t\t\t<input message=\"tns:echoNestedArrayRequest\"/>\n\t\t\t<output message=\"tns:echoNestedArrayResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoStringArray rpc operation -->\n\t\t<operation name=\"echoStringArray\" parameterOrder=\"inputStringArray\">\n\t\t\t<input message=\"tns:echoStringArrayRequest\"/>\n\t\t\t<output message=\"tns:echoStringArrayResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoIntegerArray rpc operation -->\n\t\t<operation name=\"echoIntegerArray\" parameterOrder=\"inputIntegerArray\">\n\t\t\t<input message=\"tns:echoIntegerArrayRequest\"/>\n\t\t\t<output message=\"tns:echoIntegerArrayResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoBoolean rpc operation -->\n\t\t<operation name=\"echoBoolean\" parameterOrder=\"inputBoolean\">\n\t\t\t<input message=\"tns:echoBooleanRequest\"/>\n\t\t\t<output message=\"tns:echoBooleanResponse\"/>\n\t\t</operation>\n\n\t\t<!-- echoString rpc operation -->\n\t\t<operation name=\"echoString\" parameterOrder=\"inputString\">\n\t\t\t<input message=\"tns:echoStringRequest\"/>\n\t\t\t<output message=\"tns:echoStringResponse\"/>\n\t\t</operation>\n\n\t</portType>\n\n\t<binding name=\"Soap11TestRpcLitBinding\" type=\"tns:SoapTestPortTypeRpc\">\n\t\t<soap11:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n\n\t\t<!-- echoStruct rpc operation -->\n\t\t<operation name=\"echoStruct\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!--  echoStructArray rpc operation -->\n\t\t<operation name=\"echoStructArray\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoStructAsSimpleTypes rpc operation -->\n\t\t<operation name=\"echoStructAsSimpleTypes\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoSimpleTypesAsStruct rpc operation -->\n\t\t<operation name=\"echoSimpleTypesAsStruct\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoNestedStruct rpc operation -->\n\t\t<operation name=\"echoNestedStruct\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoNestedArray rpc operation -->\n\t\t<operation name=\"echoNestedArray\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoStringArray rpc operation -->\n\t\t<operation name=\"echoStringArray\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoIntegerArray rpc operation -->\n\t\t<operation name=\"echoIntegerArray\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoBoolean rpc operation -->\n\t\t<operation name=\"echoBoolean\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoString rpc operation -->\n\t\t<operation name=\"echoString\">\n\t\t\t<soap11:operation soapAction=\"http://soapinterop.org/\"/>\n\t\t\t<input>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap11:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t</binding>\n\n\t<binding name=\"Soap12TestRpcLitBinding\" type=\"tns:SoapTestPortTypeRpc\">\n\t\t<soap12:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n\n\t\t<!-- echoStruct rpc operation -->\n\t\t<operation name=\"echoStruct\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!--  echoStructArray rpc operation -->\n\t\t<operation name=\"echoStructArray\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoStructAsSimpleTypes rpc operation -->\n\t\t<operation name=\"echoStructAsSimpleTypes\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoSimpleTypesAsStruct rpc operation -->\n\t\t<operation name=\"echoSimpleTypesAsStruct\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoNestedStruct rpc operation -->\n\t\t<operation name=\"echoNestedStruct\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoNestedArray rpc operation -->\n\t\t<operation name=\"echoNestedArray\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoStringArray rpc operation -->\n\t\t<operation name=\"echoStringArray\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoIntegerArray rpc operation -->\n\t\t<operation name=\"echoIntegerArray\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoBoolean rpc operation -->\n\t\t<operation name=\"echoBoolean\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t\t<!-- echoString rpc operation -->\n\t\t<operation name=\"echoString\">\n\t\t\t<soap12:operation/>\n\t\t\t<input>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</input>\n\t\t\t<output>\n\t\t\t\t<soap12:body use=\"literal\" namespace=\"http://soapbuilders.org/rpc-lit-test\" />\n\t\t\t</output>\n\t\t</operation>\n\n\t</binding>\n\n\t<service name=\"WhiteMesaSoapRpcLitTestSvc\">\n\n  \t\t<port name=\"Soap12TestRpcLitPort\" binding=\"tns:Soap12TestRpcLitBinding\">\n    \t\t\t<soap12:address location=\"http://www.whitemesa.net/soap12/test-rpc-lit\"/>\n  \t\t</port>\n  \t\t<port name=\"Soap11TestRpcLitPort\" binding=\"tns:Soap11TestRpcLitBinding\">\n    \t\t\t<soap11:address location=\"http://www.whitemesa.net/test-rpc-lit\"/>\n  \t\t</port>\n\n\t</service>\n\n</definitions>\n"
  },
  {
    "path": "test/wsdl/rpc/test_rpc.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\n\nmodule WSDL; module RPC\n\n\nclass TestRPC < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    def on_init\n      self.generate_explicit_type = false\n      add_rpc_method(self, 'echo', 'arg1', 'arg2')\n      add_rpc_method(self, 'echo_err', 'arg1', 'arg2')\n    end\n  \n    DummyPerson = Struct.new(\"family-name\".intern, :given_name)\n    def echo(arg1, arg2)\n      case arg1.family_name\n      when 'normal'\n        arg1.family_name = arg2.family_name\n        arg1.given_name = arg2.given_name\n        arg1.age = arg2.age\n        arg1\n      when 'dummy'\n        DummyPerson.new(\"family-name\", \"given_name\")\n      else\n        raise\n      end\n    end\n  \n    ErrPerson = Struct.new(:given_name, :no_such_element)\n    def echo_err(arg1, arg2)\n      ErrPerson.new(58, Time.now)\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_classdef\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    File.unlink(pathname('echo.rb'))\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:rpc\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_classdef\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"rpc.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['force'] = true\n    gen.run\n    require pathname('echo')\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def test_wsdl\n    wsdl = File.join(DIR, 'rpc.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDOUT if $DEBUG\n\n    ret = @client.echo(Person.new(\"normal\", \"\", 12), Person.new(\"Hi\", \"Na\", 21))\n    assert_equal(Person, ret.class)\n    assert_equal(\"Hi\", ret.family_name)\n    assert_equal(\"Na\", ret.given_name)\n    assert_equal(21, ret.age)\n\n    ret = @client.echo(Person.new(\"dummy\", \"\", 12), Person.new(\"Hi\", \"Na\", 21))\n    assert_equal(Person, ret.class)\n    assert_equal(\"family-name\", ret.family_name)\n    assert_equal(\"given_name\", ret.given_name)\n    assert_equal(nil, ret.age)\n\n    ret = @client.echo_err(Person.new(\"Na\", \"Hi\"), Person.new(\"Hi\", \"Na\"))\n    assert_equal(Person, ret.class)\n    assert_equal(\"58\", ret.given_name)\n    assert_equal(nil, ret.family_name)\n    assert_equal(nil, ret.age)\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/wsdl/rpc/test_rpc_lit.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/soap/wsdl2ruby'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\nif defined?(HTTPAccess2) and defined?(OpenSSL)\n\nmodule WSDL; module RPC\n\n\nclass TestRPCLIT < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    Namespace = \"http://soapbuilders.org/rpc-lit-test\"\n\n    def on_init\n      self.generate_explicit_type = false\n      add_rpc_operation(self, \n        XSD::QName.new(Namespace, 'echoStringArray'),\n        nil,\n        'echoStringArray', [\n          ['in', 'inputStringArray', nil],\n          ['retval', 'return', nil]\n        ],\n        {\n          :request_style => :rpc,\n          :request_use => :literal,\n          :response_style => :rpc,\n          :response_use => :literal\n        }\n      )\n      add_rpc_operation(self, \n        XSD::QName.new(Namespace, 'echoStringArrayInline'),\n        nil,\n        'echoStringArrayInline', [\n          ['in', 'inputStringArray', nil],\n          ['retval', 'return', nil]\n        ],\n        {\n          :request_style => :rpc,\n          :request_use => :literal,\n          :response_style => :rpc,\n          :response_use => :literal\n        }\n      )\n      add_rpc_operation(self, \n        XSD::QName.new(Namespace, 'echoNestedStruct'),\n        nil,\n        'echoNestedStruct', [\n          ['in', 'inputNestedStruct', nil],\n          ['retval', 'return', nil]\n        ],\n        {\n          :request_style => :rpc,\n          :request_use => :literal,\n          :response_style => :rpc,\n          :response_use => :literal\n        }\n      )\n      add_rpc_operation(self, \n        XSD::QName.new(Namespace, 'echoStructArray'),\n        nil,\n        'echoStructArray', [\n          ['in', 'inputStructArray', nil],\n          ['retval', 'return', nil]\n        ],\n        {\n          :request_style => :rpc,\n          :request_use => :literal,\n          :response_style => :rpc,\n          :response_use => :literal\n        }\n      )\n    end\n  \n    def echoStringArray(strings)\n      # strings.stringItem => Array\n      ArrayOfstring[*strings.stringItem]\n    end\n\n    def echoStringArrayInline(strings)\n      ArrayOfstringInline[*strings.stringItem]\n    end\n\n    def echoNestedStruct(struct)\n      struct\n    end\n\n    def echoStructArray(ary)\n      ary\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_classdef\n    @client = nil\n  end\n\n  def teardown\n    teardown_server\n    unless $DEBUG\n      File.unlink(pathname('RPC-Literal-TestDefinitions.rb'))\n      File.unlink(pathname('RPC-Literal-TestDefinitionsDriver.rb'))\n    end\n    @client.reset_stream if @client\n  end\n\n  def setup_server\n    @server = Server.new('Test', Server::Namespace, '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_classdef\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"test-rpc-lit.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['driver'] = nil\n    gen.opt['force'] = true\n    gen.run\n    backupdir = Dir.pwd\n    begin\n      Dir.chdir(DIR)\n      require pathname('RPC-Literal-TestDefinitions.rb')\n      require pathname('RPC-Literal-TestDefinitionsDriver.rb')\n    ensure\n      Dir.chdir(backupdir)\n    end\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def test_wsdl_echoStringArray\n    wsdl = pathname('test-rpc-lit.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDOUT if $DEBUG\n    # response contains only 1 part.\n    result = @client.echoStringArray(ArrayOfstring[\"a\", \"b\", \"c\"])[0]\n    assert_equal([\"a\", \"b\", \"c\"], result.stringItem)\n  end\n\n  ECHO_STRING_ARRAY_REQUEST =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoStringArray xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <inputStringArray xmlns:n2=\"http://soapbuilders.org/rpc-lit-test/types\">\n        <n2:stringItem>a</n2:stringItem>\n        <n2:stringItem>b</n2:stringItem>\n        <n2:stringItem>c</n2:stringItem>\n      </inputStringArray>\n    </n1:echoStringArray>\n  </env:Body>\n</env:Envelope>]\n\n  ECHO_STRING_ARRAY_RESPONSE =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoStringArrayResponse xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <return xmlns:n2=\"http://soapbuilders.org/rpc-lit-test/types\">\n        <n2:stringItem>a</n2:stringItem>\n        <n2:stringItem>b</n2:stringItem>\n        <n2:stringItem>c</n2:stringItem>\n      </return>\n    </n1:echoStringArrayResponse>\n  </env:Body>\n</env:Envelope>]\n\n  def test_stub_echoStringArray\n    drv = SoapTestPortTypeRpc.new(\"http://localhost:#{Port}/\")\n    drv.wiredump_dev = str = ''\n    # response contains only 1 part.\n    result = drv.echoStringArray(ArrayOfstring[\"a\", \"b\", \"c\"])[0]\n    assert_equal([\"a\", \"b\", \"c\"], result.stringItem)\n    assert_equal(ECHO_STRING_ARRAY_REQUEST, parse_requestxml(str))\n    assert_equal(ECHO_STRING_ARRAY_RESPONSE, parse_responsexml(str))\n  end\n\n  ECHO_STRING_ARRAY_INLINE_REQUEST =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoStringArrayInline xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <inputStringArray>\n        <stringItem>a</stringItem>\n        <stringItem>b</stringItem>\n        <stringItem>c</stringItem>\n      </inputStringArray>\n    </n1:echoStringArrayInline>\n  </env:Body>\n</env:Envelope>]\n\n  ECHO_STRING_ARRAY_INLINE_RESPONSE =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoStringArrayInlineResponse xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <return>\n        <stringItem>a</stringItem>\n        <stringItem>b</stringItem>\n        <stringItem>c</stringItem>\n      </return>\n    </n1:echoStringArrayInlineResponse>\n  </env:Body>\n</env:Envelope>]\n\n  def test_stub_echoStringArrayInline\n    drv = SoapTestPortTypeRpc.new(\"http://localhost:#{Port}/\")\n    drv.wiredump_dev = str = ''\n    # response contains only 1 part.\n    result = drv.echoStringArrayInline(ArrayOfstringInline[\"a\", \"b\", \"c\"])[0]\n    assert_equal([\"a\", \"b\", \"c\"], result.stringItem)\n    assert_equal(ECHO_STRING_ARRAY_INLINE_REQUEST, parse_requestxml(str))\n    assert_equal(ECHO_STRING_ARRAY_INLINE_RESPONSE, parse_responsexml(str))\n  end\n\n  ECHO_NESTED_STRUCT_REQUEST =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoNestedStruct xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <inputStruct xmlns:n2=\"http://soapbuilders.org/rpc-lit-test/types\">\n        <varString>str</varString>\n        <varInt>1</varInt>\n        <varFloat>+1</varFloat>\n        <n2:structItem>\n          <varString>str</varString>\n          <varInt>1</varInt>\n          <varFloat>+1</varFloat>\n        </n2:structItem>\n      </inputStruct>\n    </n1:echoNestedStruct>\n  </env:Body>\n</env:Envelope>]\n\n  ECHO_NESTED_STRUCT_RESPONSE =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoNestedStructResponse xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <return xmlns:n2=\"http://soapbuilders.org/rpc-lit-test/types\">\n        <varString>str</varString>\n        <varInt>1</varInt>\n        <varFloat>+1</varFloat>\n        <n2:structItem>\n          <varString>str</varString>\n          <varInt>1</varInt>\n          <varFloat>+1</varFloat>\n        </n2:structItem>\n      </return>\n    </n1:echoNestedStructResponse>\n  </env:Body>\n</env:Envelope>]\n\n  def test_wsdl_echoNestedStruct\n    wsdl = pathname('test-rpc-lit.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = str = ''\n    # response contains only 1 part.\n    result = @client.echoNestedStruct(SOAPStructStruct.new(\"str\", 1, 1.0, SOAPStruct.new(\"str\", 1, 1.0)))[0]\n    assert_equal('str', result.varString)\n    assert_equal('1', result.varInt)\n    assert_equal('+1', result.varFloat)\n    assert_equal('str', result.structItem.varString)\n    assert_equal('1', result.structItem.varInt)\n    assert_equal('+1', result.structItem.varFloat)\n    assert_equal(ECHO_NESTED_STRUCT_REQUEST, parse_requestxml(str))\n    assert_equal(ECHO_NESTED_STRUCT_RESPONSE, parse_responsexml(str))\n  end\n\n  def test_stub_echoNestedStruct\n    drv = SoapTestPortTypeRpc.new(\"http://localhost:#{Port}/\")\n    drv.wiredump_dev = str = ''\n    # response contains only 1 part.\n    result = drv.echoNestedStruct(SOAPStructStruct.new(\"str\", 1, 1.0, SOAPStruct.new(\"str\", 1, 1.0)))[0]\n    assert_equal('str', result.varString)\n    assert_equal('1', result.varInt)\n    assert_equal('+1', result.varFloat)\n    assert_equal('str', result.structItem.varString)\n    assert_equal('1', result.structItem.varInt)\n    assert_equal('+1', result.structItem.varFloat)\n    assert_equal(ECHO_NESTED_STRUCT_REQUEST, parse_requestxml(str))\n    assert_equal(ECHO_NESTED_STRUCT_RESPONSE, parse_responsexml(str))\n  end\n\n  ECHO_STRUCT_ARRAY_REQUEST =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoStructArray xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <inputStructArray xmlns:n2=\"http://soapbuilders.org/rpc-lit-test/types\">\n        <n2:structItem>\n          <varString>str</varString>\n          <varInt>2</varInt>\n          <varFloat>+2.1</varFloat>\n        </n2:structItem>\n        <n2:structItem>\n          <varString>str</varString>\n          <varInt>2</varInt>\n          <varFloat>+2.1</varFloat>\n        </n2:structItem>\n      </inputStructArray>\n    </n1:echoStructArray>\n  </env:Body>\n</env:Envelope>]\n\n  ECHO_STRUCT_ARRAY_RESPONSE =\n%q[<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <n1:echoStructArrayResponse xmlns:n1=\"http://soapbuilders.org/rpc-lit-test\">\n      <return xmlns:n2=\"http://soapbuilders.org/rpc-lit-test/types\">\n        <n2:structItem>\n          <varString>str</varString>\n          <varInt>2</varInt>\n          <varFloat>+2.1</varFloat>\n        </n2:structItem>\n        <n2:structItem>\n          <varString>str</varString>\n          <varInt>2</varInt>\n          <varFloat>+2.1</varFloat>\n        </n2:structItem>\n      </return>\n    </n1:echoStructArrayResponse>\n  </env:Body>\n</env:Envelope>]\n\n  def test_wsdl_echoStructArray\n    wsdl = pathname('test-rpc-lit.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = str = ''\n    # response contains only 1 part.\n    e = SOAPStruct.new(\"str\", 2, 2.1)\n    result = @client.echoStructArray(ArrayOfSOAPStruct[e, e])\n    assert_equal(ECHO_STRUCT_ARRAY_REQUEST, parse_requestxml(str))\n    assert_equal(ECHO_STRUCT_ARRAY_RESPONSE, parse_responsexml(str))\n  end\n\n  def test_stub_echoStructArray\n    drv = SoapTestPortTypeRpc.new(\"http://localhost:#{Port}/\")\n    drv.wiredump_dev = str = ''\n    # response contains only 1 part.\n    e = SOAPStruct.new(\"str\", 2, 2.1)\n    result = drv.echoStructArray(ArrayOfSOAPStruct[e, e])\n    assert_equal(ECHO_STRUCT_ARRAY_REQUEST, parse_requestxml(str))\n    assert_equal(ECHO_STRUCT_ARRAY_RESPONSE, parse_responsexml(str))\n  end\n\n  def parse_requestxml(str)\n    str.split(/\\r?\\n\\r?\\n/)[3]\n  end\n\n  def parse_responsexml(str)\n    str.split(/\\r?\\n\\r?\\n/)[6]\n  end\nend\n\n\nend; end\n\nend\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/expectedClient.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'echo_versionDriver.rb'\n\nendpoint_url = ARGV.shift\nobj = Echo_version_port_type.new(endpoint_url)\n\n# run ruby with -d to see SOAP wiredumps.\nobj.wiredump_dev = STDERR if $DEBUG\n\n# SYNOPSIS\n#   echo_version(version)\n#\n# ARGS\n#   version         Version - {urn:example.com:simpletype-rpc-type}version\n#\n# RETURNS\n#   version_struct  Version_struct - {urn:example.com:simpletype-rpc-type}version_struct\n#\nversion = nil\nputs obj.echo_version(version)\n\n# SYNOPSIS\n#   echo_version_r(version_struct)\n#\n# ARGS\n#   version_struct  Version_struct - {urn:example.com:simpletype-rpc-type}version_struct\n#\n# RETURNS\n#   version         Version - {urn:example.com:simpletype-rpc-type}version\n#\nversion_struct = nil\nputs obj.echo_version_r(version_struct)\n\n\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/expectedDriver.rb",
    "content": "require 'echo_version.rb'\n\nrequire 'soap/rpc/driver'\n\nclass Echo_version_port_type < ::SOAP::RPC::Driver\n  DefaultEndpointUrl = \"http://localhost:10080\"\n  MappingRegistry = ::SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    Version_struct,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"urn:example.com:simpletype-rpc-type\", \"version_struct\") }\n  )\n\n  Methods = [\n    [ XSD::QName.new(\"urn:example.com:simpletype-rpc\", \"echo_version\"),\n      \"urn:example.com:simpletype-rpc\",\n      \"echo_version\",\n      [ [\"in\", \"version\", [\"::SOAP::SOAPString\"]],\n        [\"retval\", \"version_struct\", [\"Version_struct\", \"urn:example.com:simpletype-rpc-type\", \"version_struct\"]] ],\n      { :request_style =>  :rpc, :request_use =>  :encoded,\n        :response_style => :rpc, :response_use => :encoded }\n    ],\n    [ XSD::QName.new(\"urn:example.com:simpletype-rpc\", \"echo_version_r\"),\n      \"urn:example.com:simpletype-rpc\",\n      \"echo_version_r\",\n      [ [\"in\", \"version_struct\", [\"Version_struct\", \"urn:example.com:simpletype-rpc-type\", \"version_struct\"]],\n        [\"retval\", \"version\", [\"::SOAP::SOAPString\"]] ],\n      { :request_style =>  :rpc, :request_use =>  :encoded,\n        :response_style => :rpc, :response_use => :encoded }\n    ]\n  ]\n\n  def initialize(endpoint_url = nil)\n    endpoint_url ||= DefaultEndpointUrl\n    super(endpoint_url, nil)\n    self.mapping_registry = MappingRegistry\n    init_methods\n  end\n\nprivate\n\n  def init_methods\n    Methods.each do |definitions|\n      opt = definitions.last\n      if opt[:request_style] == :document\n        add_document_operation(*definitions)\n      else\n        add_rpc_operation(*definitions)\n        qname = definitions[0]\n        name = definitions[2]\n        if qname.name != name and qname.name.capitalize == name.capitalize\n          ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|\n            __send__(name, *arg)\n          end\n        end\n      end\n    end\n  end\nend\n\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/expectedEchoVersion.rb",
    "content": "require 'xsd/qname'\n\n# {urn:example.com:simpletype-rpc-type}version_struct\nclass Version_struct\n  @@schema_type = \"version_struct\"\n  @@schema_ns = \"urn:example.com:simpletype-rpc-type\"\n  @@schema_element = [[\"version\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"version\")]], [\"msg\", [\"SOAP::SOAPString\", XSD::QName.new(nil, \"msg\")]]]\n\n  attr_accessor :version\n  attr_accessor :msg\n\n  def initialize(version = nil, msg = nil)\n    @version = version\n    @msg = msg\n  end\nend\n\n# {urn:example.com:simpletype-rpc-type}version\nmodule Version\n  C_16 = \"1.6\"\n  C_18 = \"1.8\"\n  C_19 = \"1.9\"\nend\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/expectedServant.rb",
    "content": "require 'echo_version.rb'\n\nclass Echo_version_port_type\n  # SYNOPSIS\n  #   echo_version(version)\n  #\n  # ARGS\n  #   version         Version - {urn:example.com:simpletype-rpc-type}version\n  #\n  # RETURNS\n  #   version_struct  Version_struct - {urn:example.com:simpletype-rpc-type}version_struct\n  #\n  def echo_version(version)\n    p [version]\n    raise NotImplementedError.new\n  end\n\n  # SYNOPSIS\n  #   echo_version_r(version_struct)\n  #\n  # ARGS\n  #   version_struct  Version_struct - {urn:example.com:simpletype-rpc-type}version_struct\n  #\n  # RETURNS\n  #   version         Version - {urn:example.com:simpletype-rpc-type}version\n  #\n  def echo_version_r(version_struct)\n    p [version_struct]\n    raise NotImplementedError.new\n  end\nend\n\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/expectedService.rb",
    "content": "#!/usr/bin/env ruby\nrequire 'echo_versionServant.rb'\n\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/mapping/registry'\n\nclass Echo_version_port_type\n  MappingRegistry = ::SOAP::Mapping::Registry.new\n\n  MappingRegistry.set(\n    Version_struct,\n    ::SOAP::SOAPStruct,\n    ::SOAP::Mapping::Registry::TypedStructFactory,\n    { :type => XSD::QName.new(\"urn:example.com:simpletype-rpc-type\", \"version_struct\") }\n  )\n\n  Methods = [\n    [ XSD::QName.new(\"urn:example.com:simpletype-rpc\", \"echo_version\"),\n      \"urn:example.com:simpletype-rpc\",\n      \"echo_version\",\n      [ [\"in\", \"version\", [\"::SOAP::SOAPString\"]],\n        [\"retval\", \"version_struct\", [\"Version_struct\", \"urn:example.com:simpletype-rpc-type\", \"version_struct\"]] ],\n      { :request_style =>  :rpc, :request_use =>  :encoded,\n        :response_style => :rpc, :response_use => :encoded }\n    ],\n    [ XSD::QName.new(\"urn:example.com:simpletype-rpc\", \"echo_version_r\"),\n      \"urn:example.com:simpletype-rpc\",\n      \"echo_version_r\",\n      [ [\"in\", \"version_struct\", [\"Version_struct\", \"urn:example.com:simpletype-rpc-type\", \"version_struct\"]],\n        [\"retval\", \"version\", [\"::SOAP::SOAPString\"]] ],\n      { :request_style =>  :rpc, :request_use =>  :encoded,\n        :response_style => :rpc, :response_use => :encoded }\n    ]\n  ]\nend\n\nclass Echo_version_port_typeApp < ::SOAP::RPC::StandaloneServer\n  def initialize(*arg)\n    super(*arg)\n    servant = Echo_version_port_type.new\n    Echo_version_port_type::Methods.each do |definitions|\n      opt = definitions.last\n      if opt[:request_style] == :document\n        @router.add_document_operation(servant, *definitions)\n      else\n        @router.add_rpc_operation(servant, *definitions)\n      end\n    end\n    self.mapping_registry = Echo_version_port_type::MappingRegistry\n  end\nend\n\nif $0 == __FILE__\n  # Change listen port.\n  server = Echo_version_port_typeApp.new('app', nil, '0.0.0.0', 10080)\n  trap(:INT) do\n    server.shutdown\n  end\n  server.start\nend\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/rpc.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name=\"echo_version\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:example.com:simpletype-rpc\"\n    xmlns:txd=\"urn:example.com:simpletype-rpc-type\"\n    targetNamespace=\"urn:example.com:simpletype-rpc\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema targetNamespace=\"urn:example.com:simpletype-rpc-type\">\n      <xsd:complexType name=\"version_struct\">\n\t<xsd:all>\n\t  <xsd:element name=\"version\" type=\"txd:version\" />\n\t  <xsd:element name=\"msg\" type=\"xsd:string\" />\n\t</xsd:all>\n      </xsd:complexType>\n\n      <xsd:simpleType name=\"version\">\n        <xsd:restriction base=\"xsd:string\">\n          <xsd:enumeration value=\"1.6\"/>\n          <xsd:enumeration value=\"1.8\"/>\n          <xsd:enumeration value=\"1.9\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:schema>\n  </types>\n\n  <message name=\"msg_version\">\n    <part name=\"version\" type=\"txd:version\"/>\n  </message>\n\n  <message name=\"msg_version_struct\">\n    <part name=\"version_struct\" type=\"txd:version_struct\"/>\n  </message>\n\n  <portType name=\"echo_version_port_type\">\n    <operation name=\"echo_version\">\n      <input message=\"tns:msg_version\"/>\n      <output message=\"tns:msg_version_struct\"/>\n    </operation>\n\n    <operation name=\"echo_version_r\">\n      <input message=\"tns:msg_version_struct\"/>\n      <output message=\"tns:msg_version\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"echo_version_binding\" type=\"tns:echo_version_port_type\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"rpc\"/>\n    <operation name=\"echo_version\">\n      <soap:operation soapAction=\"urn:example.com:simpletype-rpc\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:simpletype-rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:simpletype-rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n\n    <operation name=\"echo_version_r\">\n      <soap:operation soapAction=\"urn:example.com:simpletype-rpc\"/>\n      <input>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:simpletype-rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </input>\n      <output>\n        <soap:body use=\"encoded\" namespace=\"urn:example.com:simpletype-rpc\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"echo_version_service\">\n    <port name=\"echo_version_port\" binding=\"tns:echo_version_binding\">\n      <soap:address location=\"http://localhost:10080\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/simpletype/rpc/test_rpc.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/wsdl2ruby'\n\n\nmodule WSDL; module SimpleType\n\n\nclass TestRPC < Test::Unit::TestCase\n  DIR = File.dirname(File.expand_path(__FILE__))\n  def pathname(filename)\n    File.join(DIR, filename)\n  end\n\n  def test_rpc\n    gen = WSDL::SOAP::WSDL2Ruby.new\n    gen.location = pathname(\"rpc.wsdl\")\n    gen.basedir = DIR\n    gen.logger.level = Logger::FATAL\n    gen.opt['classdef'] = nil\n    gen.opt['driver'] = nil\n    gen.opt['client_skelton'] = nil\n    gen.opt['servant_skelton'] = nil\n    gen.opt['standalone_server_stub'] = nil\n    gen.opt['force'] = true\n    suppress_warning do\n      gen.run\n    end\n    compare(\"expectedEchoVersion.rb\", \"echo_version.rb\")\n    compare(\"expectedDriver.rb\", \"echo_versionDriver.rb\")\n    compare(\"expectedService.rb\", \"echo_version_service.rb\")\n    compare(\"expectedClient.rb\", \"echo_version_serviceClient.rb\")\n    compare(\"expectedServant.rb\", \"echo_versionServant.rb\")\n\n    File.unlink(pathname(\"echo_version.rb\"))\n    File.unlink(pathname(\"echo_versionDriver.rb\"))\n    File.unlink(pathname(\"echo_version_service.rb\"))\n    File.unlink(pathname(\"echo_version_serviceClient.rb\"))\n    File.unlink(pathname(\"echo_versionServant.rb\"))\n  end\n\n  def compare(expected, actual)\n    assert_equal(loadfile(expected), loadfile(actual), actual)\n  end\n\n  def loadfile(file)\n    File.open(pathname(file)) { |f| f.read }\n  end\n\n  def suppress_warning\n    back = $VERBOSE\n    $VERBOSE = nil\n    begin\n      yield\n    ensure\n      $VERBOSE = back\n    end\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/wsdl/simpletype/simpletype.wsdl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<definitions name=\"ping_service\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:tns=\"urn:example.com:simpletype\"\n    targetNamespace=\"urn:example.com:simpletype\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\n  <types>\n    <xsd:schema targetNamespace=\"urn:example.com:simpletype\">\n      <xsd:element name=\"ruby\">\n        <xsd:complexType>\n          <xsd:sequence>\n            <xsd:element minOccurs=\"1\" maxOccurs=\"1\" name=\"myversion\" type=\"tns:myversion\"/>\n            <xsd:element minOccurs=\"0\" maxOccurs=\"1\" name=\"date\" type=\"xsd:dateTime\"/>\n          </xsd:sequence>\n        </xsd:complexType>\n      </xsd:element>\n\n      <xsd:simpleType name=\"myversion\">\n        <xsd:restriction base=\"xsd:string\">\n          <xsd:enumeration value=\"1.6\"/>\n          <xsd:enumeration value=\"1.8\"/>\n          <xsd:enumeration value=\"1.9\"/>\n        </xsd:restriction>\n      </xsd:simpleType>\n\n      <xsd:element name=\"myid\" type=\"tns:ID\"/>\n\n      <xsd:simpleType name=\"ID\">\n        <xsd:restriction base=\"xsd:string\">\n          <xsd:length value=\"18\"/>\n          <xsd:pattern value='[a-zA-Z0-9]{18}'/>\n        </xsd:restriction>\n      </xsd:simpleType>\n    </xsd:schema>\n  </types>\n\n  <message name=\"ping_in\">\n    <part name=\"parameters\" element=\"tns:ruby\"/>\n  </message>\n\n  <message name=\"ping_out\">\n    <part name=\"parameters\" type=\"xsd:string\"/>\n  </message>\n\n  <message name=\"ping_id_in\">\n    <part name=\"parameters\" element=\"tns:myid\"/>\n  </message>\n\n  <message name=\"ping_id_out\">\n    <part name=\"parameters\" element=\"tns:myid\"/>\n  </message>\n\n  <message name=\"versionmsg\">\n    <part name=\"myversion\" element=\"tns:myversion\"/>\n  </message>\n\n  <portType name=\"ping_port_type\">\n    <operation name=\"ping\">\n      <input message=\"tns:ping_in\"/>\n      <output message=\"tns:ping_out\"/>\n    </operation>\n\n    <operation name=\"ping_id\">\n      <input message=\"tns:ping_id_in\"/>\n      <output message=\"tns:ping_id_out\"/>\n    </operation>\n\n    <operation name=\"echo_version\">\n      <input message=\"tns:versionmsg\"/>\n      <output message=\"tns:versionmsg\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"ping_binding\" type=\"tns:ping_port_type\">\n    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\"/>\n    <operation name=\"ping\">\n      <soap:operation soapAction=\"urn:example.com:simpletype:ping\" style=\"document\"/>\n      <input><soap:body use=\"literal\"/></input>\n      <output><soap:body use=\"literal\"/></output>\n    </operation>\n\n    <operation name=\"ping_id\">\n      <soap:operation soapAction=\"urn:example.com:simpletype:ping_id\" style=\"document\"/>\n      <input><soap:body use=\"literal\"/></input>\n      <output><soap:body use=\"literal\"/></output>\n    </operation>\n  </binding>\n\n  <service name=\"ping_service\">\n    <port name=\"ping_port\" binding=\"tns:ping_binding\">\n      <soap:address location=\"http://localhost:10080\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/simpletype/test_simpletype.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\n\nmodule WSDL\nmodule SimpleType\n\n\nclass TestSimpleType < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    def on_init\n      add_document_method(self, 'urn:example.com:simpletype:ping', 'ping',\n        XSD::QName.new('urn:example.com:simpletype', 'ruby'),\n        XSD::QName.new('http://www.w3.org/2001/XMLSchema', 'string'))\n      add_document_method(self, 'urn:example.com:simpletype:ping_id', 'ping_id',\n        XSD::QName.new('urn:example.com:simpletype', 'myid'),\n        XSD::QName.new('urn:example.com:simpletype', 'myid'))\n    end\n  \n    def ping(ruby)\n      version = ruby[\"myversion\"]\n      date = ruby[\"date\"]\n      \"#{version} (#{date})\"\n    end\n\n    def ping_id(id)\n      id\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:example.com:simpletype\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @server_thread = start_server_thread(@server)\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'simpletype.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.generate_explicit_type = false\n    @client.wiredump_dev = STDOUT if $DEBUG\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @server_thread.kill\n    @server_thread.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def start_server_thread(server)\n    t = Thread.new {\n      Thread.current.abort_on_exception = true\n      server.start\n    }\n    t\n  end\n\n  def test_ping\n    ret = @client.ping({:myversion => \"1.9\", :date => \"2004-01-01T00:00:00Z\"})\n    assert_equal(\"1.9 (2004-01-01T00:00:00Z)\", ret)\n  end\n\n  def test_ping_id\n    ret = @client.ping_id(\"012345678901234567\")\n    assert_equal(\"012345678901234567\", ret)\n    # length\n    assert_raise(XSD::ValueSpaceError) do\n      @client.ping_id(\"0123456789012345678\")\n    end\n    # pattern\n    assert_raise(XSD::ValueSpaceError) do\n      @client.ping_id(\"01234567890123456;\")\n    end\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/wsdl/soap/soapbodyparts.wsdl",
    "content": "<?xml version=\"1.0\"?>\n<definitions\n    name=\"soapbodyparts\"\n    targetNamespace=\"urn:www.example.com:soapbodyparts:v1\"\n    xmlns:tns=\"urn:www.example.com:soapbodyparts:v1\"\n    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n    xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\">\n\n  <types>\n    <schema xmlns=\"http://www.w3.org/2001/XMLSchema\"\n\ttargetNamespace=\"urn:www.example.com:soapbodyparts:v1\">\n      <import namespace = \"http://schemas.xmlsoap.org/soap/encoding/\"/>\n      <complexType name=\"StringArray\">\n \t<complexContent>\n\t  <restriction base=\"soapenc:Array\">\n\t    <attribute ref=\"soapenc:arrayType\" wsdl:arrayType=\"string[]\"/>\n  \t  </restriction>\n  \t</complexContent>\n      </complexType>\n    </schema>\n  </types>\n\n  <message name=\"fooRequest\">\n    <part name=\"param1\" type=\"xsd:string\"/>\n    <part name=\"param2\" type=\"xsd:string\"/>\n    <part name=\"param3\" type=\"xsd:string\"/>\n  </message>\n\n  <message name=\"fooResponse\">\n    <part name=\"return\" type=\"tns:StringArray\"/>\n  </message>\n\n  <portType name=\"FooServicePortType\">\n    <operation name=\"foo\"\n\tparameterOrder=\"param3 param2 param1\">\n      <input message=\"tns:fooRequest\"/>\n      <output message=\"tns:fooResponse\"/>\n    </operation>\n    <operation name=\"bar\"\n\tparameterOrder=\"param1 param2 param3\">\n      <input message=\"tns:fooRequest\"/>\n      <output message=\"tns:fooResponse\"/>\n    </operation>\n    <operation name=\"baz\">\n      <input message=\"tns:fooRequest\"/>\n      <output message=\"tns:fooResponse\"/>\n    </operation>\n  </portType>\n\n  <binding name=\"FooServicePortBinding\" type=\"tns:FooServicePortType\">\n    <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n    <operation name=\"foo\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    parts=\"param1 param3\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:www.example.com:soapbodyparts:v1\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:www.example.com:soapbodyparts:v1\"/>\n      </output>\n    </operation>\n    <operation name=\"bar\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    parts=\"param3 param2\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:www.example.com:soapbodyparts:v1\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:www.example.com:soapbodyparts:v1\"/>\n      </output>\n    </operation>\n    <operation name=\"baz\">\n      <soap:operation soapAction=\"\"/>\n      <input>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:www.example.com:soapbodyparts:v1\"/>\n      </input>\n      <output>\n\t<soap:body use=\"encoded\"\n\t    encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\n\t    namespace=\"urn:www.example.com:soapbodyparts:v1\"/>\n      </output>\n    </operation>\n  </binding>\n\n  <service name=\"FooService\">\n    <port name=\"FooServicePort\" binding=\"tns:FooServicePortBinding\">\n      <soap:address location=\"http://raa.ruby-lang.org/soap/1.0.2/\"/>\n    </port>\n  </service>\n</definitions>\n"
  },
  {
    "path": "test/wsdl/soap/test_soapbodyparts.rb",
    "content": "require 'test/unit'\nrequire 'soap/rpc/standaloneServer'\nrequire 'soap/wsdlDriver'\n\n\nmodule WSDL\nmodule SOAP\n\n\nclass TestSOAPBodyParts < Test::Unit::TestCase\n  class Server < ::SOAP::RPC::StandaloneServer\n    def on_init\n      add_method(self, 'foo', 'p1', 'p2', 'p3')\n      add_method(self, 'bar', 'p1', 'p2', 'p3')\n      add_method(self, 'baz', 'p1', 'p2', 'p3')\n    end\n  \n    def foo(p1, p2, p3)\n      [p1, p2, p3]\n    end\n\n    alias bar foo\n\n    def baz(p1, p2, p3)\n      [p3, p2, p1]\n    end\n  end\n\n  DIR = File.dirname(File.expand_path(__FILE__))\n\n  Port = 17171\n\n  def setup\n    setup_server\n    setup_client\n  end\n\n  def setup_server\n    @server = Server.new('Test', \"urn:www.example.com:soapbodyparts:v1\", '0.0.0.0', Port)\n    @server.level = Logger::Severity::ERROR\n    @t = Thread.new {\n      Thread.current.abort_on_exception = true\n      @server.start\n    }\n  end\n\n  def setup_client\n    wsdl = File.join(DIR, 'soapbodyparts.wsdl')\n    @client = ::SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver\n    @client.endpoint_url = \"http://localhost:#{Port}/\"\n    @client.wiredump_dev = STDERR if $DEBUG\n  end\n\n  def teardown\n    teardown_server\n    teardown_client\n  end\n\n  def teardown_server\n    @server.shutdown\n    @t.kill\n    @t.join\n  end\n\n  def teardown_client\n    @client.reset_stream\n  end\n\n  def test_soapbodyparts\n    assert_equal([\"1\", \"2\", \"3\"], @client.foo(\"1\", \"2\", \"3\"))\n    assert_equal([\"3\", \"2\", \"1\"], @client.foo(\"3\", \"2\", \"1\"))\n    assert_equal([\"1\", \"2\", \"3\"], @client.bar(\"1\", \"2\", \"3\"))\n    assert_equal([\"3\", \"2\", \"1\"], @client.baz(\"1\", \"2\", \"3\"))\n  end\nend\n\n\nend\nend\n"
  },
  {
    "path": "test/wsdl/test_emptycomplextype.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\n\n\nmodule WSDL\n\n\nclass TestWSDL < Test::Unit::TestCase\n  def setup\n    @file = File.join(File.dirname(File.expand_path(__FILE__)), 'emptycomplextype.wsdl')\n  end\n\n  def test_wsdl\n    @wsdl = WSDL::Parser.new.parse(File.open(@file) { |f| f.read })\n    assert(/\\{urn:jp.gr.jin.rrr.example.emptycomplextype\\}emptycomplextype/ =~ @wsdl.inspect)\n  end\nend\n\n\n\nend\n"
  },
  {
    "path": "test/wsdl/test_fault.rb",
    "content": "require 'test/unit'\nrequire 'soap/processor'\nrequire 'soap/mapping'\nrequire 'soap/rpc/element'\nrequire 'wsdl/parser'\n\n\nmodule WSDL\n\n\nclass TestFault < Test::Unit::TestCase\n  def setup\n    @xml =<<__EOX__\n<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <env:Body>\n    <env:Fault xmlns:n1=\"http://schemas.xmlsoap.org/soap/encoding/\"\n        env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n      <faultcode xsi:type=\"xsd:string\">Server</faultcode>\n      <faultstring xsi:type=\"xsd:string\">faultstring</faultstring>\n      <faultactor xsi:type=\"xsd:string\">faultactor</faultactor>\n      <detail xmlns:n2=\"http://www.ruby-lang.org/xmlns/ruby/type/custom\"\n          xsi:type=\"n2:SOAPException\">\n\t<excn_type_name xsi:type=\"xsd:string\">type</excn_type_name>\n\t<cause href=\"#id123\"/>\n      </detail>\n    </env:Fault>\n    <cause id=\"id123\" xsi:type=\"xsd:int\">5</cause>\n  </env:Body>\n</env:Envelope>\n__EOX__\n  end\n\n  def test_by_wsdl\n    rpc_decode_typemap = WSDL::Definitions.soap_rpc_complextypes\n    opt = {}\n    opt[:default_encodingstyle] = ::SOAP::EncodingNamespace\n    opt[:decode_typemap] = rpc_decode_typemap\n    header, body = ::SOAP::Processor.unmarshal(@xml, opt)\n    fault = ::SOAP::Mapping.soap2obj(body.response)\n    assert_equal(\"Server\", fault.faultcode)\n    assert_equal(\"faultstring\", fault.faultstring)\n    assert_equal(URI.parse(\"faultactor\"), fault.faultactor)\n    assert_equal(5, fault.detail.cause)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/wsdl/test_multiplefault.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/parser'\nrequire 'wsdl/soap/classDefCreator'\n\n\nmodule WSDL\n\n\nclass TestMultipleFault < Test::Unit::TestCase\n  def self.setup(filename)\n    @@filename = filename\n  end\n\n  def test_multiplefault\n    @wsdl = WSDL::Parser.new.parse(File.open(@@filename) { |f| f.read })\n    classdefstr = WSDL::SOAP::ClassDefCreator.new(@wsdl).dump\n    yield_eval_binding(classdefstr) do |b|\n      assert_equal(\n\tWSDL::TestMultipleFault::AuthenticationError,\n\teval(\"AuthenticationError\", b)\n      )\n      assert_equal(\n\tWSDL::TestMultipleFault::AuthorizationError,\n\teval(\"AuthorizationError\", b)\n      )\n    end\n  end\n\n  def yield_eval_binding(evaled)\n    b = binding\n    eval(evaled, b)\n    yield(b)\n  end\nend\n\nTestMultipleFault.setup(File.join(File.dirname(__FILE__), 'multiplefault.wsdl'))\n\n\nend\n"
  },
  {
    "path": "test/xmlrpc/data/bug_bool.expected",
    "content": "--- \n- true\n- false"
  },
  {
    "path": "test/xmlrpc/data/bug_bool.xml",
    "content": "<?xml version=\"1.0\"?>\n<methodResponse>\n  <params>\n    <param>\n      <value><boolean>0</boolean></value>\n    </param>\n  </params>\n</methodResponse>\n"
  },
  {
    "path": "test/xmlrpc/data/bug_cdata.expected",
    "content": "--- \n- true\n- test"
  },
  {
    "path": "test/xmlrpc/data/bug_cdata.xml",
    "content": "<?xml version=\"1.0\"?>\n<methodResponse>\n  <params>\n    <param>\n      <value><string><![CDATA[test]]></string></value>\n    </param>\n  </params>\n</methodResponse>\n"
  },
  {
    "path": "test/xmlrpc/data/bug_covert.expected",
    "content": "--- \n- true\n- >\n  Site,SANs,Array\n\n  Configured Capacity,Array Reserved Capacity,Array Ava\n\n  ilable Capacity,Array % Reserved,Host Allocated,Host Used,Host Free,Host %\n\n  Used\n"
  },
  {
    "path": "test/xmlrpc/data/bug_covert.xml",
    "content": "<?xml version=\"1.0\"\nencoding=\"ISO-8859-1\"?><methodResponse><params><param><value>Site,SANs,Array\nConfigured Capacity,Array Reserved Capacity,Array Ava\nilable Capacity,Array % Reserved,Host Allocated,Host Used,Host Free,Host %\nUsed\n</value></param></params></methodResponse>\n"
  },
  {
    "path": "test/xmlrpc/data/datetime_iso8601.xml",
    "content": "<?xml version=\"1.0\"?>\n<methodResponse>\n  <params>\n    <param>\n      <value><dateTime.iso8601>20041105T01:15:23Z</dateTime.iso8601></value>\n    </param>\n  </params>\n</methodResponse>\n"
  },
  {
    "path": "test/xmlrpc/data/fault.xml",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<methodResponse>\n  <fault>\n    <value><struct>\n      <member>\n        <name>faultCode</name>\n        <value><int>4</int></value>\n      </member>\n      <member>\n        <name>faultString</name>\n        <value>an error message</value>\n      </member>\n    </struct></value>\n  </fault>\n</methodResponse>\n\n"
  },
  {
    "path": "test/xmlrpc/data/value.expected",
    "content": "--- \n- Test\n- \n  - Hallo Leute\n  - \"   Hallo   \"\n  - ''\n  - \"   \""
  },
  {
    "path": "test/xmlrpc/data/value.xml",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<methodCall>\n  <methodName>Test</methodName>\n  <params>\n    <param>\n      <value>Hallo Leute</value>\n    </param>\n    <param>\n      <value>   Hallo   </value>\n    </param>\n    <param>\n      <value></value>\n    </param>\n    <param>\n      <value>   </value>\n    </param>\n  </params>\n</methodCall>\n\n\n\n\n"
  },
  {
    "path": "test/xmlrpc/data/xml1.expected",
    "content": "--- \n- true\n- \n  - \n    subscriber: MegaCorp\n    lastName: Baker\n    telephone1: 1-508-791-1267\n    telephone2: 1-800-445-2588\n    password: p1111\n    OID: \"1\"\n    email: hbaker@yahoo.com\n    adminId: hbaker\n    objectName: AdministratorDO\n  - \n    subscriber: CornerStore\n    lastName: Dragon\n    telephone1: 1-781-789-9089\n    telephone2: 1-800-445-2588\n    password: p3333\n    OID: \"3\"\n    email: adragon@yahoo.com\n    adminId: adragon\n    objectName: AdministratorDO\n  - \n    subscriber: Cyberdyne\n    lastName: Rodman\n    telephone1: 1-617-789-1890\n    telephone2: 1-800-445-2588\n    password: p4444\n    OID: \"4\"\n    email: mrodman@yahoo.com\n    adminId: mrodman\n    objectName: AdministratorDO\n  - \n    subscriber: StarSports\n    lastName: Jordan\n    telephone1: 1-617-890-7897\n    telephone2: 1-800-445-2588\n    password: p5555\n    OID: \"5\"\n    email: mjordan@yahoo.com\n    adminId: mjordan\n    objectName: AdministratorDO\n  - \n    subscriber: GreatBooks\n    lastName: Pippen\n    telephone1: 1-781-789-9876\n    telephone2: 1-800-445-2588\n    password: p6666\n    OID: \"6\"\n    email: gpippen@yahoo.com\n    adminId: gpippen\n    objectName: AdministratorDO\n  - \n    subscriber: AxisChemicals\n    lastName: Andhrew\n    telephone1: 1-781-678-8970\n    telephone2: 1-800-445-2588\n    password: p7777\n    OID: \"7\"\n    email: aandrew@yahoo.com\n    adminId: aandrew\n    objectName: AdministratorDO\n  - \n    subscriber: MediaShop\n    lastName: Vincent\n    telephone1: 1-786-897-8908\n    telephone2: 1-800-445-2588\n    password: p8888\n    OID: \"8\"\n    email: tvincent@yahoo.com\n    adminId: tvincent\n    objectName: AdministratorDO\n  - \n    subscriber: SmartShop\n    lastName: Richard\n    telephone1: 1-508-789-6789\n    telephone2: 1-800-445-2588\n    password: p9999\n    OID: \"9\"\n    email: krichard@yahoo.com\n    adminId: krichard\n    objectName: AdministratorDO\n  - \n    subscriber: HomeNeeds\n    lastName: Cornell\n    telephone1: 1-617-789-8979\n    telephone2: 1-800-445-2588\n    password: paaaa\n    OID: \"10\"\n    email: gconell@yahoo.com\n    adminId: gcornell\n    objectName: AdministratorDO\n  - \n    subscriber: MegaCorp\n    lastName: HorstMann\n    telephone1: 1-508-791-1267\n    telephone2: 1-800-445-2588\n    password: p1111\n    OID: \"11\"\n    email: shorstmann@yahoo.com\n    adminId: shorstmann\n    objectName: AdministratorDO\n  - \n    subscriber: CornerStore\n    lastName: Bob\n    telephone1: 1-781-789-9089\n    telephone2: 1-800-445-2588\n    password: p3333\n    OID: \"13\"\n    email: rbob@yahoo.com\n    adminId: rbob\n    objectName: AdministratorDO\n  - \n    subscriber: Cyberdyne\n    lastName: Peter\n    telephone1: 1-617-789-1890\n    telephone2: 1-800-445-2588\n    password: p4444\n    OID: \"14\"\n    email: speter@yahoo.com\n    adminId: speter\n    objectName: AdministratorDO\n  - \n    subscriber: StarSports\n    lastName: Novak\n    telephone1: 1-617-890-7897\n    telephone2: 1-800-445-2588\n    password: p5555\n    OID: \"15\"\n    email: pnovak@yahoo.com\n    adminId: pnovak\n    objectName: AdministratorDO\n  - \n    subscriber: GreatBooks\n    lastName: Nancy\n    telephone1: 1-781-789-9876\n    telephone2: 1-800-445-2588\n    password: p6666\n    OID: \"16\"\n    email: pnancy@yahoo.com\n    adminId: pnancy\n    objectName: AdministratorDO\n  - \n    subscriber: AxisChemicals\n    lastName: Michel\n    telephone1: 1-781-678-8970\n    telephone2: 1-800-445-2588\n    password: p7777\n    OID: \"17\"\n    email: hmichel@yahoo.com\n    adminId: hmichel\n    objectName: AdministratorDO\n  - \n    subscriber: MediaShop\n    lastName: David\n    telephone1: 1-786-897-8908\n    telephone2: 1-800-445-2588\n    password: p8888\n    OID: \"18\"\n    email: kdavid@yahoo.com\n    adminId: kdavid\n    objectName: AdministratorDO\n  - \n    subscriber: SmartShop\n    lastName: Valnoor\n    telephone1: 1-508-789-6789\n    telephone2: 1-800-445-2588\n    password: p9999\n    OID: \"19\"\n    email: pvalnoor@yahoo.com\n    adminId: pvalnoor\n    objectName: AdministratorDO\n  - \n    subscriber: HomeNeeds\n    lastName: Smith\n    telephone1: 1-617-789-8979\n    telephone2: 1-800-445-2588\n    password: paaaa\n    OID: \"20\"\n    email: wsmith@yahoo.com\n    adminId: wsmith\n    objectName: AdministratorDO\n  - \n    subscriber: MegaCorp\n    lastName: Caral\n    telephone1: 1-781-789-9876\n    telephone2: 1-800-445-2588\n    password: p6666\n    OID: \"21\"\n    email: gcaral@yahoo.com\n    adminId: gcaral\n    objectName: AdministratorDO\n  - \n    subscriber: CornerStore\n    lastName: Hillary\n    telephone1: 1-786-897-8908\n    telephone2: 1-800-445-2588\n    password: p8888\n    OID: \"23\"\n    email: phillary@yahoo.com\n    adminId: phillary\n    objectName: AdministratorDO\n  - \n    subscriber: Cyberdyne\n    lastName: Philip\n    telephone1: 1-508-789-6789\n    telephone2: 1-800-445-2588\n    password: p9999\n    OID: \"24\"\n    email: bphilip@yahoo.com\n    adminId: bphilip\n    objectName: AdministratorDO\n  - \n    subscriber: StarSports\n    lastName: Andrea\n    telephone1: 1-617-789-8979\n    telephone2: 1-800-445-2588\n    password: paaaa\n    OID: \"25\"\n    email: sandrea@yahoo.com\n    adminId: sandrea\n    objectName: AdministratorDO\n  - \n    subscriber: s4\n    lastName: \"null\"\n    telephone1: \"null\"\n    telephone2: \"null\"\n    password: s4\n    OID: \"26\"\n    email: \"null\"\n    adminId: s4\n    objectName: AdministratorDO\n  - \n    subscriber: BigBank\n    lastName: administrator\n    telephone1: ''\n    telephone2: ''\n    password: admin\n    OID: \"82\"\n    email: ''\n    adminId: admin\n    objectName: AdministratorDO"
  },
  {
    "path": "test/xmlrpc/data/xml1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><methodResponse><params><param><value><array><data><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>hbaker</value></member><member><name>email</name><value>hbaker@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-791-1267</value></member><member><name>OID</name><value>1</value></member><member><name>password</name><value>p1111</value></member><member><name>lastName</name><value>Baker</value></member><member><name>subscriber</name><value>MegaCorp</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>adragon</value></member><member><name>email</name><value>adragon@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9089</value></member><member><name>OID</name><value>3</value></member><member><name>password</name><value>p3333</value></member><member><name>lastName</name><value>Dragon</value></member><member><name>subscriber</name><value>CornerStore</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>mrodman</value></member><member><name>email</name><value>mrodman@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-1890</value></member><member><name>OID</name><value>4</value></member><member><name>password</name><value>p4444</value></member><member><name>lastName</name><value>Rodman</value></member><member><name>subscriber</name><value>Cyberdyne</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>mjordan</value></member><member><name>email</name><value>mjordan@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-890-7897</value></member><member><name>OID</name><value>5</value></member><member><name>password</name><value>p5555</value></member><member><name>lastName</name><value>Jordan</value></member><member><name>subscriber</name><value>StarSports</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>gpippen</value></member><member><name>email</name><value>gpippen@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9876</value></member><member><name>OID</name><value>6</value></member><member><name>password</name><value>p6666</value></member><member><name>lastName</name><value>Pippen</value></member><member><name>subscriber</name><value>GreatBooks</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>aandrew</value></member><member><name>email</name><value>aandrew@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-678-8970</value></member><member><name>OID</name><value>7</value></member><member><name>password</name><value>p7777</value></member><member><name>lastName</name><value>Andhrew</value></member><member><name>subscriber</name><value>AxisChemicals</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>tvincent</value></member><member><name>email</name><value>tvincent@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-786-897-8908</value></member><member><name>OID</name><value>8</value></member><member><name>password</name><value>p8888</value></member><member><name>lastName</name><value>Vincent</value></member><member><name>subscriber</name><value>MediaShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>krichard</value></member><member><name>email</name><value>krichard@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-789-6789</value></member><member><name>OID</name><value>9</value></member><member><name>password</name><value>p9999</value></member><member><name>lastName</name><value>Richard</value></member><member><name>subscriber</name><value>SmartShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>gcornell</value></member><member><name>email</name><value>gconell@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-8979</value></member><member><name>OID</name><value>10</value></member><member><name>password</name><value>paaaa</value></member><member><name>lastName</name><value>Cornell</value></member><member><name>subscriber</name><value>HomeNeeds</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>shorstmann</value></member><member><name>email</name><value>shorstmann@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-791-1267</value></member><member><name>OID</name><value>11</value></member><member><name>password</name><value>p1111</value></member><member><name>lastName</name><value>HorstMann</value></member><member><name>subscriber</name><value>MegaCorp</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>rbob</value></member><member><name>email</name><value>rbob@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9089</value></member><member><name>OID</name><value>13</value></member><member><name>password</name><value>p3333</value></member><member><name>lastName</name><value>Bob</value></member><member><name>subscriber</name><value>CornerStore</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>speter</value></member><member><name>email</name><value>speter@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-1890</value></member><member><name>OID</name><value>14</value></member><member><name>password</name><value>p4444</value></member><member><name>lastName</name><value>Peter</value></member><member><name>subscriber</name><value>Cyberdyne</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>pnovak</value></member><member><name>email</name><value>pnovak@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-890-7897</value></member><member><name>OID</name><value>15</value></member><member><name>password</name><value>p5555</value></member><member><name>lastName</name><value>Novak</value></member><member><name>subscriber</name><value>StarSports</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>pnancy</value></member><member><name>email</name><value>pnancy@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9876</value></member><member><name>OID</name><value>16</value></member><member><name>password</name><value>p6666</value></member><member><name>lastName</name><value>Nancy</value></member><member><name>subscriber</name><value>GreatBooks</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>hmichel</value></member><member><name>email</name><value>hmichel@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-678-8970</value></member><member><name>OID</name><value>17</value></member><member><name>password</name><value>p7777</value></member><member><name>lastName</name><value>Michel</value></member><member><name>subscriber</name><value>AxisChemicals</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>kdavid</value></member><member><name>email</name><value>kdavid@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-786-897-8908</value></member><member><name>OID</name><value>18</value></member><member><name>password</name><value>p8888</value></member><member><name>lastName</name><value>David</value></member><member><name>subscriber</name><value>MediaShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>pvalnoor</value></member><member><name>email</name><value>pvalnoor@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-789-6789</value></member><member><name>OID</name><value>19</value></member><member><name>password</name><value>p9999</value></member><member><name>lastName</name><value>Valnoor</value></member><member><name>subscriber</name><value>SmartShop</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>wsmith</value></member><member><name>email</name><value>wsmith@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-8979</value></member><member><name>OID</name><value>20</value></member><member><name>password</name><value>paaaa</value></member><member><name>lastName</name><value>Smith</value></member><member><name>subscriber</name><value>HomeNeeds</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>gcaral</value></member><member><name>email</name><value>gcaral@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-781-789-9876</value></member><member><name>OID</name><value>21</value></member><member><name>password</name><value>p6666</value></member><member><name>lastName</name><value>Caral</value></member><member><name>subscriber</name><value>MegaCorp</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>phillary</value></member><member><name>email</name><value>phillary@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-786-897-8908</value></member><member><name>OID</name><value>23</value></member><member><name>password</name><value>p8888</value></member><member><name>lastName</name><value>Hillary</value></member><member><name>subscriber</name><value>CornerStore</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>bphilip</value></member><member><name>email</name><value>bphilip@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-508-789-6789</value></member><member><name>OID</name><value>24</value></member><member><name>password</name><value>p9999</value></member><member><name>lastName</name><value>Philip</value></member><member><name>subscriber</name><value>Cyberdyne</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>sandrea</value></member><member><name>email</name><value>sandrea@yahoo.com</value></member><member><name>telephone2</name><value>1-800-445-2588</value></member><member><name>telephone1</name><value>1-617-789-8979</value></member><member><name>OID</name><value>25</value></member><member><name>password</name><value>paaaa</value></member><member><name>lastName</name><value>Andrea</value></member><member><name>subscriber</name><value>StarSports</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>s4</value></member><member><name>email</name><value>null</value></member><member><name>telephone2</name><value>null</value></member><member><name>telephone1</name><value>null</value></member><member><name>OID</name><value>26</value></member><member><name>password</name><value>s4</value></member><member><name>lastName</name><value>null</value></member><member><name>subscriber</name><value>s4</value></member></struct></value><value><struct><member><name>objectName</name><value>AdministratorDO</value></member><member><name>adminId</name><value>admin</value></member><member><name>email</name><value></value></member><member><name>telephone2</name><value></value></member><member><name>telephone1</name><value></value></member><member><name>OID</name><value>82</value></member><member><name>password</name><value>admin</value></member><member><name>lastName</name><value>administrator</value></member><member><name>subscriber</name><value>BigBank</value></member></struct></value></data></array></value></param></params></methodResponse>\n"
  },
  {
    "path": "test/xmlrpc/test_cookie.rb",
    "content": "require 'test/unit'\nrequire 'time'\nrequire 'webrick'\nrequire File.join(File.dirname(__FILE__), 'webrick_testing')\nrequire \"xmlrpc/server\"\nrequire 'xmlrpc/client'\n\nclass TestCookie < Test::Unit::TestCase\n  include WEBrick_Testing\n\n  def create_servlet\n    s = XMLRPC::WEBrickServlet.new\n\n    def s.logged_in_users\n      @logged_in_users ||= {}\n    end\n    def s.request\n      @request\n    end\n    def s.response\n      @response\n    end\n    def s.service(request, response)\n      @request = request\n      @response = response\n      super\n    ensure\n      @request = nil\n      @response = nil\n    end\n\n    key = Time.now.to_i.to_s\n    valid_user = \"valid-user\"\n    s.add_handler(\"test.login\") do |user, password|\n      ok = (user == valid_user and password == \"secret\")\n      if ok\n        s.logged_in_users[key] = user\n        expires = (Time.now + 60 * 60).httpdate\n        cookies = s.response.cookies\n        cookies << \"key=\\\"#{key}\\\"; path=\\\"/RPC2\\\"; expires=#{expires}\"\n        cookies << \"user=\\\"#{user}\\\"; path=\\\"/RPC2\\\"\"\n      end\n      ok\n    end\n\n    s.add_handler(\"test.require_authenticate_echo\") do |string|\n      cookies = {}\n      s.request.cookies.each do |cookie|\n        cookies[cookie.name] = cookie.value\n      end\n      if cookies == {\"key\" => key, \"user\" => valid_user}\n        string\n      else\n        raise XMLRPC::FaultException.new(29, \"Authentication required\")\n      end\n    end\n\n    s.set_default_handler do |name, *args|\n      raise XMLRPC::FaultException.new(-99, \"Method #{name} missing\" +\n            \" or wrong number of parameters!\")\n    end\n\n    s.add_introspection\n\n    s\n  end\n\n  def setup_http_server(port)\n    option = {:Port => port}\n\n    start_server(option) {|w| w.mount('/RPC2', create_servlet) }\n\n    @s = XMLRPC::Client.new3(:port => port)\n  end\n\n  PORT = 8070\n  def test_cookie\n    begin\n      setup_http_server(PORT)\n      do_test\n    ensure\n      stop_server\n    end\n  end\n\n  def do_test\n    assert(!@s.call(\"test.login\", \"invalid-user\", \"invalid-password\"))\n    exception = assert_raise(XMLRPC::FaultException) do\n      @s.call(\"test.require_authenticate_echo\", \"Hello\")\n    end\n    assert_equal(29, exception.faultCode)\n\n    assert(@s.call(\"test.login\", \"valid-user\", \"secret\"))\n    assert_equal(\"Hello\", @s.call(\"test.require_authenticate_echo\", \"Hello\"))\n  end\nend\n"
  },
  {
    "path": "test/xmlrpc/test_datetime.rb",
    "content": "require 'test/unit'\nrequire \"xmlrpc/datetime\"\n\nclass Test_DateTime < Test::Unit::TestCase\n\n  def test_new\n    dt = createDateTime()\n\n    assert_instance_of(XMLRPC::DateTime, dt)\n  end\n\n  def test_new_exception\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(4.5, 13, 32, 25, 60, 60) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 32, 25, 60, 60) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 25, 60, 60) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 60, 60) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 59, 60) }\n    assert_nothing_raised(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 59, 59) }\n\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 0, 0, -1, -1, -1) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 0, -1, -1, -1) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, -1, -1, -1) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, -1, -1) }\n    assert_raises(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, 0, -1) }\n    assert_nothing_raised(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, 0, 0) }\n  end\n\n\n  def test_get_values\n    y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5\n    dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)\n\n    assert_equal(y, dt.year)\n    assert_equal(m, dt.month)\n    assert_equal(m, dt.mon)\n    assert_equal(d, dt.day)\n\n    assert_equal(h, dt.hour)\n    assert_equal(mi,dt.min)\n    assert_equal(s, dt.sec)\n  end\n\n  def test_set_values\n    dt = createDateTime()\n    y, m, d, h, mi, s = 1950, 12, 9, 8, 52, 30\n\n    dt.year  = y\n    dt.month = m\n    dt.day   = d\n    dt.hour  = h\n    dt.min   = mi\n    dt.sec   = s\n\n    assert_equal(y, dt.year)\n    assert_equal(m, dt.month)\n    assert_equal(m, dt.mon)\n    assert_equal(d, dt.day)\n\n    assert_equal(h, dt.hour)\n    assert_equal(mi,dt.min)\n    assert_equal(s, dt.sec)\n\n    dt.mon = 5\n    assert_equal(5, dt.month)\n    assert_equal(5, dt.mon)\n  end\n\n  def test_set_exception\n    dt = createDateTime()\n    \n    assert_raises(ArgumentError)    { dt.year = 4.5 }\n    assert_nothing_raised(ArgumentError) { dt.year = -2000 }\n \n    assert_raises(ArgumentError) { dt.month = 0 }\n    assert_raises(ArgumentError) { dt.month = 13 }\n    assert_nothing_raised(ArgumentError) { dt.month = 7 }\n\n    assert_raises(ArgumentError) { dt.mon = 0 }\n    assert_raises(ArgumentError) { dt.mon = 13 }\n    assert_nothing_raised(ArgumentError) { dt.mon = 7 }\n\n    assert_raises(ArgumentError) { dt.day = 0 }\n    assert_raises(ArgumentError) { dt.day = 32 }\n    assert_nothing_raised(ArgumentError) { dt.day = 16 }\n\n    assert_raises(ArgumentError) { dt.hour = -1 }\n    assert_raises(ArgumentError) { dt.hour = 25 }\n    assert_nothing_raised(ArgumentError) { dt.hour = 12 }\n\n    assert_raises(ArgumentError) { dt.min = -1 }\n    assert_raises(ArgumentError) { dt.min = 60 }\n    assert_nothing_raised(ArgumentError) { dt.min = 30 }\n\n    assert_raises(ArgumentError) { dt.sec = -1 }\n    assert_raises(ArgumentError) { dt.sec = 60 }\n    assert_nothing_raised(ArgumentError) { dt.sec = 30 }\n  end\n\n  def test_to_a\n    y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5\n    dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)\n    a = dt.to_a \n\n    assert_instance_of(Array, a)\n    assert_equal(6,  a.size, \"Returned array has wrong size\")\n\n    assert_equal(y,  a[0])\n    assert_equal(m,  a[1])\n    assert_equal(d,  a[2])\n    assert_equal(h,  a[3])\n    assert_equal(mi, a[4])\n    assert_equal(s,  a[5])\n  end\n\n  def test_to_time1\n    y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5\n    dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)\n    time = dt.to_time \n    \n    assert_not_nil(time)\n\n    assert_equal(y,  time.year)\n    assert_equal(m,  time.month)\n    assert_equal(d,  time.day)\n    assert_equal(h,  time.hour)\n    assert_equal(mi, time.min)\n    assert_equal(s,  time.sec)\n  end\n\n  def test_to_time2\n    dt = createDateTime()\n    dt.year = 1969\n    \n    assert_nil(dt.to_time)\n  end\n\n  def test_to_date1\n    y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5\n    dt = XMLRPC::DateTime.new(y, m, d, h, mi, s)\n    date = dt.to_date \n \n    assert_equal(y, date.year)\n    assert_equal(m, date.month)\n    assert_equal(d, date.day)\n  end\n\n  def test_to_date2\n    dt = createDateTime()\n    dt.year = 666\n    \n    assert_equal(666, dt.to_date.year)\n  end\n\n\n  def createDateTime\n    XMLRPC::DateTime.new(1970, 3, 24, 12, 0, 5)\n  end\n\nend\n"
  },
  {
    "path": "test/xmlrpc/test_features.rb",
    "content": "require 'test/unit'\nrequire \"xmlrpc/create\"\nrequire \"xmlrpc/parser\"\nrequire \"xmlrpc/config\"\n\nclass Test_Features < Test::Unit::TestCase\n\n  def setup\n    @params = [nil, {\"test\" => nil}, [nil, 1, nil]]\n  end\n\n  def test_nil_create\n    XMLRPC::XMLWriter.each_installed_writer do |writer|\n      c = XMLRPC::Create.new(writer)\n\n      XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)}\n      XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, false)\n      assert_raises(RuntimeError) { str = c.methodCall(\"test\", *@params) }\n\n      XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)}\n      XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, true)\n      assert_nothing_raised { str = c.methodCall(\"test\", *@params) }\n    end\n  end\n\n  def test_nil_parse\n    XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)}\n    XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, true)\n\n    XMLRPC::XMLWriter.each_installed_writer do |writer|\n      c = XMLRPC::Create.new(writer)\n      str = c.methodCall(\"test\", *@params) \n      XMLRPC::XMLParser.each_installed_parser do |parser|\n        para = nil\n\n        XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_PARSER)}\n        XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, false)\n        assert_raises(RuntimeError) { para = parser.parseMethodCall(str) }\n\n        XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_PARSER)}\n        XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, true)\n        assert_nothing_raised { para = parser.parseMethodCall(str) }\n        assert_equal(para[1], @params)\n      end\n    end\n  end\n\nend\n"
  },
  {
    "path": "test/xmlrpc/test_marshal.rb",
    "content": "require 'test/unit'\nrequire \"xmlrpc/marshal\"\n\nclass Test_Marshal < Test::Unit::TestCase\n  # for test_parser_values\n  class Person\n    include XMLRPC::Marshallable\n    attr_reader :name\n    def initialize(name)\n      @name = name\n    end\n  end\n\n\n  def test1_dump_response\n    assert_nothing_raised(NameError) {\n      XMLRPC::Marshal.dump_response('arg')\n    }\n  end\n\n  def test1_dump_call\n    assert_nothing_raised(NameError) {\n      XMLRPC::Marshal.dump_call('methodName', 'arg')\n    }\n  end\n\n  def test2_dump_load_response\n    value = [1, 2, 3, {\"test\" => true}, 3.4]\n    res   = XMLRPC::Marshal.dump_response(value)\n\n    assert_equal(value, XMLRPC::Marshal.load_response(res))\n  end\n\n  def test2_dump_load_call\n    methodName = \"testMethod\"\n    value      = [1, 2, 3, {\"test\" => true}, 3.4]\n    exp        = [methodName, [value, value]]\n\n    res   = XMLRPC::Marshal.dump_call(methodName, value, value)\n\n    assert_equal(exp, XMLRPC::Marshal.load_call(res))\n  end\n\n  def test_parser_values\n    v1 = [ \n      1, -7778,                        # integers\n      1.0, 0.0, -333.0, 2343434343.0,  # floats\n      false, true, true, false,        # booleans\n      \"Hallo\", \"with < and >\", \"\"      # strings\n    ]\n\n    v2 = [\n      [v1, v1, v1],\n      {\"a\" => v1}\n    ]\n\n    v3 = [\n      XMLRPC::Base64.new(\"\\001\"*1000), # base64\n      :aSymbol, :anotherSym            # symbols (-> string)\n    ]\n    v3_exp = [\n      \"\\001\"*1000,\n      \"aSymbol\", \"anotherSym\"\n    ]\n    person = Person.new(\"Michael\")\n\n    XMLRPC::XMLParser.each_installed_parser do |parser|\n      m = XMLRPC::Marshal.new(parser)\n\n      assert_equal( v1, m.load_response(m.dump_response(v1)) )\n      assert_equal( v2, m.load_response(m.dump_response(v2)) )\n      assert_equal( v3_exp, m.load_response(m.dump_response(v3)) )\n\n      pers = m.load_response(m.dump_response(person))\n      \n      assert( pers.is_a?(Person) )\n      assert( person.name == pers.name ) \n    end\n\n    # missing, Date, Time, DateTime\n    # Struct\n  end\n\n  def test_no_params_tag\n    # bug found by Idan Sofer\n\n    expect = %{<?xml version=\"1.0\" ?><methodCall><methodName>myMethod</methodName><params/></methodCall>\\n}\n\n    str = XMLRPC::Marshal.dump_call(\"myMethod\")\n    assert_equal(expect, str)\n  end\n\nend\n"
  },
  {
    "path": "test/xmlrpc/test_parser.rb",
    "content": "require 'test/unit'\nrequire 'xmlrpc/datetime'\nrequire \"xmlrpc/parser\"\nrequire 'yaml'\n\nmodule GenericParserTest\n  def datafile(base)\n    File.join(File.dirname(__FILE__), \"data\", base)\n  end\n \n  def load_data(name)\n    [File.read(datafile(name) + \".xml\"), YAML.load(File.read(datafile(name) + \".expected\"))]\n  end\n\n  def setup\n    @xml1, @expected1 = load_data('xml1')\n    @xml2, @expected2 = load_data('bug_covert') \n    @xml3, @expected3 = load_data('bug_bool') \n    @xml4, @expected4 = load_data('value') \n\n    @cdata_xml, @cdata_expected = load_data('bug_cdata')\n\n    @datetime_xml = File.read(datafile('datetime_iso8601.xml'))\n    @datetime_expected = XMLRPC::DateTime.new(2004, 11, 5, 1, 15, 23)\n\n    @fault_doc = File.read(datafile('fault.xml'))\n  end\n\n  # test parseMethodResponse --------------------------------------------------\n  \n  def test_parseMethodResponse1\n    assert_equal(@expected1, @p.parseMethodResponse(@xml1))\n  end\n\n  def test_parseMethodResponse2\n    assert_equal(@expected2, @p.parseMethodResponse(@xml2))\n  end\n\n  def test_parseMethodResponse3\n    assert_equal(@expected3, @p.parseMethodResponse(@xml3))\n  end\n\n  def test_cdata\n    assert_equal(@cdata_expected, @p.parseMethodResponse(@cdata_xml))\n  end\n\n  def test_dateTime\n    assert_equal(@datetime_expected, @p.parseMethodResponse(@datetime_xml)[1])\n  end\n\n  # test parseMethodCall ------------------------------------------------------\n\n  def test_parseMethodCall\n    assert_equal(@expected4, @p.parseMethodCall(@xml4))\n  end\n\n  # test fault ----------------------------------------------------------------\n\n  def test_fault\n    flag, fault = @p.parseMethodResponse(@fault_doc)\n     assert_equal(flag, false)\n     unless fault.is_a? XMLRPC::FaultException\n       assert(false, \"must be an instance of class XMLRPC::FaultException\")\n     end\n     assert_equal(fault.faultCode, 4)\n     assert_equal(fault.faultString, \"an error message\")\n  end\nend\n\n# create test class for each installed parser \nXMLRPC::XMLParser.each_installed_parser do |parser|\n  klass = parser.class\n  name = klass.to_s.split(\"::\").last\n\n  eval %{\n    class Test_#{name} < Test::Unit::TestCase\n      include GenericParserTest\n\n      def setup\n        super\n        @p = #{klass}.new\n      end\n    end\n  }\nend\n"
  },
  {
    "path": "test/xmlrpc/test_webrick_server.rb",
    "content": "require 'test/unit'\nrequire 'webrick'\nrequire File.join(File.dirname(__FILE__), 'webrick_testing')\nrequire \"xmlrpc/server\"\nrequire 'xmlrpc/client'\n\nclass Test_Webrick < Test::Unit::TestCase\n  include WEBrick_Testing\n\n  def create_servlet\n    s = XMLRPC::WEBrickServlet.new\n\n    s.add_handler(\"test.add\") do |a,b|\n      a + b\n    end\n\n    s.add_handler(\"test.div\") do |a,b|\n      if b == 0\n        raise XMLRPC::FaultException.new(1, \"division by zero\")\n      else\n        a / b \n      end\n    end \n\n    s.set_default_handler do |name, *args|\n      raise XMLRPC::FaultException.new(-99, \"Method #{name} missing\" +\n            \" or wrong number of parameters!\")\n    end\n\n    s.add_introspection\n\n    return s\n  end\n\n  def setup_http_server(port, use_ssl)\n    option = {\n      :Port => port, \n      :SSLEnable => use_ssl,\n    }\n    if use_ssl\n      require 'webrick/https'\n      option.update(\n        :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE, \n        :SSLCertName => []\n      )\n    end\n\n    start_server(option) {|w| w.mount('/RPC2', create_servlet) }\n\n    @s = XMLRPC::Client.new3(:port => port, :use_ssl => use_ssl)\n  end\n\n  PORT = 8070\n  def test_client_server\n    # NOTE: I don't enable SSL testing as this hangs\n    [false].each do |use_ssl|\n      begin\n        setup_http_server(PORT, use_ssl)\n        do_test\n      ensure\n        stop_server\n      end\n    end\n  end\n\n  def do_test\n    # simple call\n    assert_equal 9, @s.call('test.add', 4, 5)\n\n    # fault exception\n    assert_raises(XMLRPC::FaultException) { @s.call('test.div', 1, 0) }\n\n    # fault exception via call2\n    ok, param = @s.call2('test.div', 1, 0)\n    assert_equal false, ok\n    assert_instance_of XMLRPC::FaultException, param\n    assert_equal 1, param.faultCode\n    assert_equal 'division by zero', param.faultString\n\n    # call2 without fault exception\n    ok, param = @s.call2('test.div', 10, 5)\n    assert_equal true, ok\n    assert_equal param, 2\n\n    # introspection\n    assert_equal [\"test.add\", \"test.div\", \"system.listMethods\", \"system.methodSignature\", \"system.methodHelp\"], @s.call(\"system.listMethods\")\n\n    # default handler (missing handler)\n    ok, param = @s.call2('test.nonexisting')\n    assert_equal false, ok\n    assert_equal -99, param.faultCode\n\n    # default handler (wrong number of arguments)\n    ok, param = @s.call2('test.add', 1, 2, 3)\n    assert_equal false, ok\n    assert_equal -99, param.faultCode\n  end\nend\n"
  },
  {
    "path": "test/xmlrpc/webrick_testing.rb",
    "content": "require 'timeout'\n\nmodule WEBrick_Testing\n  class DummyLog < WEBrick::BasicLog\n    def initialize() super(self) end\n    def <<(*args) end\n  end\n  \n  def start_server(config={})\n    raise \"already started\" if @__server\n    @__started = false\n\n    Thread.new {\n      @__server = WEBrick::HTTPServer.new(\n        { \n          :Logger => DummyLog.new,\n          :AccessLog => [],\n          :StartCallback => proc { @__started = true }\n        }.update(config))\n      yield @__server \n      @__server.start\n      @__started = false\n    }\n\n    Timeout.timeout(5) {\n      nil until @__started # wait until the server is ready\n    }\n  end\n\n  def stop_server\n    Timeout.timeout(5) {\n      @__server.shutdown\n      nil while @__started # wait until the server is down\n    }\n    @__server = nil\n  end\nend\n"
  },
  {
    "path": "test/xsd/codegen/test_classdef.rb",
    "content": "require 'test/unit'\nrequire 'xsd/codegen/classdef'\n\n\nmodule XSD; module CodeGen\n\n\nclass TestClassDefCreator < Test::Unit::TestCase\n  include XSD::CodeGen\n  include GenSupport\n\n  def test_classdef_simple\n    c = ClassDef.new(\"Foo\")\n    assert_equal(format(<<-EOD), c.dump)\n      class Foo\n      end\n    EOD\n  end\n\n  def test_classdef_complex\n    c = ClassDef.new(\"Foo::Bar::Baz\", String)\n    assert_equal(format(<<-EOD), c.dump)\n      module Foo; module Bar\n\n      class Baz < String\n      end\n\n      end; end\n    EOD\n  end\n\n  def test_require\n    c = ClassDef.new(\"Foo\")\n    c.def_require(\"foo/bar\")\n    assert_equal(format(<<-EOD), c.dump)\n      require 'foo/bar'\n\n      class Foo\n      end\n    EOD\n  end\n\n  def test_comment\n    c = ClassDef.new(\"Foo\")\n    c.def_require(\"foo/bar\")\n    c.comment = <<-EOD\n      foo\n    EOD\n    assert_equal(format(<<-EOD), c.dump)\n      require 'foo/bar'\n\n      # foo\n      class Foo\n      end\n    EOD\n    c.comment = <<-EOD\n            foo\n\n              bar\n             baz\n\n    EOD\n    assert_equal(format(<<-EOD), c.dump)\n      require 'foo/bar'\n\n      # foo\n      # \n      #   bar\n      #  baz\n      # \n      class Foo\n      end\n    EOD\n  end\n\n  def test_emptymethod\n    c = ClassDef.new(\"Foo\")\n    c.def_method('foo') do\n    end\n    c.def_method('bar') do\n      ''\n    end\n    assert_equal(format(<<-EOD), c.dump)\n      class Foo\n        def foo\n        end\n\n        def bar\n        end\n      end\n    EOD\n  end\n\n  def test_full\n    c = ClassDef.new(\"Foo::Bar::HobbitName\", String)\n    c.def_require(\"foo/bar\")\n    c.comment = <<-EOD\n        foo\n      bar\n        baz\n    EOD\n    c.def_const(\"FOO\", 1)\n    c.def_classvar(\"@@foo\", \"var\".dump)\n    c.def_classvar(\"baz\", \"1\".dump)\n    c.def_attr(\"Foo\", true, \"foo\")\n    c.def_attr(\"bar\")\n    c.def_attr(\"baz\", true)\n    c.def_attr(\"Foo2\", true, \"foo2\")\n    c.def_attr(\"foo3\", false, \"foo3\")\n    c.def_method(\"foo\") do\n      <<-EOD\n        foo.bar = 1\n\\tbaz.each do |ele|\n\\t  ele\n        end\n      EOD\n    end\n    c.def_method(\"baz\", \"qux\") do\n      <<-EOD\n        [1, 2, 3].each do |i|\n          p i\n        end\n      EOD\n    end\n\n    m = MethodDef.new(\"qux\", \"quxx\", \"quxxx\") do\n      <<-EOD\n      p quxx + quxxx\n      EOD\n    end\n    m.comment = \"hello world\\n123\"\n    c.add_method(m)\n    c.def_code <<-EOD\n      Foo.new\n      Bar.z\n    EOD\n    c.def_code <<-EOD\n      Foo.new\n      Bar.z\n    EOD\n    c.def_privatemethod(\"foo\", \"baz\", \"*arg\", \"&block\")\n\n    assert_equal(format(<<-EOD), c.dump)\n    require 'foo/bar'\n\n    module Foo; module Bar\n\n    #   foo\n    # bar\n    #   baz\n    class HobbitName < String\n      @@foo = \"var\"\n      @@baz = \"1\"\n\n      FOO = 1\n\n      Foo.new\n      Bar.z\n\n      Foo.new\n      Bar.z\n\n      attr_accessor :bar\n      attr_accessor :baz\n      attr_reader :foo3\n\n      def Foo\n        @foo\n      end\n\n      def Foo=(value)\n        @foo = value\n      end\n\n      def Foo2\n        @foo2\n      end\n\n      def Foo2=(value)\n        @foo2 = value\n      end\n\n      def foo\n        foo.bar = 1\n        baz.each do |ele|\n          ele\n        end\n      end\n\n      def baz(qux)\n        [1, 2, 3].each do |i|\n          p i\n        end\n      end\n\n      # hello world\n      # 123\n      def qux(quxx, quxxx)\n        p quxx + quxxx\n      end\n\n    private\n\n      def foo(baz, *arg, &block)\n      end\n    end\n\n    end; end\n    EOD\n  end\nend\n\n\nend; end\n"
  },
  {
    "path": "test/xsd/noencoding.xml",
    "content": "<?xml version=\"1.0\" encoding=\"euc-jp\"?>\n<schema xmlns=\"http://www.w3.org/2001/XMLSchema\">\n  <!--  -->\n</schema>\n"
  },
  {
    "path": "test/xsd/test_noencoding.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/xmlSchema/parser'\n\n\nmodule XSD\n\n\nclass TestEmptyCharset < Test::Unit::TestCase\n  def setup\n    @file = File.join(File.dirname(File.expand_path(__FILE__)), 'noencoding.xml')\n  end\n\n  def test_wsdl\n    begin\n      xml = WSDL::XMLSchema::Parser.new.parse(File.open(@file) { |f| f.read })\n    rescue RuntimeError\n      if XSD::XMLParser.const_defined?(\"REXMLParser\")\n\tSTDERR.puts(\"rexml cannot handle euc-jp without iconv/uconv.\")\n\treturn\n      end\n      raise\n    rescue Errno::EINVAL\n      # unsupported encoding\n      return\n    end\n    assert_equal(WSDL::XMLSchema::Schema, xml.class)\n    assert_equal(0, xml.collect_elements.size)\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/xsd/test_xmlschemaparser.rb",
    "content": "require 'test/unit'\nrequire 'wsdl/xmlSchema/parser'\n\n\nmodule XSD\n\n\nclass TestXMLSchemaParser < Test::Unit::TestCase\n  def setup\n    @file = File.join(File.dirname(File.expand_path(__FILE__)), 'xmlschema.xml')\n  end\n\n  def test_wsdl\n    @wsdl = WSDL::XMLSchema::Parser.new.parse(File.open(@file) { |f| f.read })\n    assert_equal(WSDL::XMLSchema::Schema, @wsdl.class)\n    assert_equal(1, @wsdl.collect_elements.size)\n  end\nend\n\n\n\nend\n"
  },
  {
    "path": "test/xsd/test_xsd.rb",
    "content": "require 'test/unit'\nrequire 'xsd/datatypes'\n\n\nmodule XSD\n\n\nclass TestXSD < Test::Unit::TestCase\n  NegativeZero = (-1.0 / (1.0 / 0.0))\n\n  def setup\n  end\n\n  def teardown\n  end\n\n  def assert_parsed_result(klass, str)\n    o = klass.new(str)\n    assert_equal(str, o.to_s)\n  end\n\n  def test_NSDBase\n    o = XSD::NSDBase.new\n    assert_equal(nil, o.type)\n  end\n\n  def test_XSDBase\n    o = XSD::XSDAnySimpleType.new\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n    assert_equal('', o.to_s)\n  end\n\n  def test_XSDNil\n    o = XSD::XSDNil.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::NilLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    o = XSD::XSDNil.new(nil)\n    assert_equal(true, o.is_nil)\n    assert_equal(nil, o.data)\n    assert_equal(\"\", o.to_s)\n    o = XSD::XSDNil.new('var')\n    assert_equal(false, o.is_nil)\n    assert_equal('var', o.data)\n    assert_equal('var', o.to_s)\n  end\n\n  def test_XSDString_UTF8\n    o = XSD::XSDString.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::StringLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    str = \"abc\"\n    assert_equal(str, XSD::XSDString.new(str).data)\n    assert_equal(str, XSD::XSDString.new(str).to_s)\n    assert_raises(XSD::ValueSpaceError) do\n      XSD::XSDString.new(\"\\0\")\n    end\n    assert_raises(XSD::ValueSpaceError) do\n      p XSD::XSDString.new(\"\\xC0\\xC0\").to_s\n    end\n  end\n\n  def test_XSDString_NONE\n    XSD::Charset.module_eval { @encoding_backup = @encoding; @encoding = \"NONE\" }\n    begin\n      o = XSD::XSDString.new\n      assert_equal(XSD::Namespace, o.type.namespace)\n      assert_equal(XSD::StringLiteral, o.type.name)\n      assert_equal(nil, o.data)\n      assert_equal(true, o.is_nil)\n\n      str = \"abc\"\n      assert_equal(str, XSD::XSDString.new(str).data)\n      assert_equal(str, XSD::XSDString.new(str).to_s)\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDString.new(\"\\0\")\n      end\n      assert_raises(XSD::ValueSpaceError) do\n\tp XSD::XSDString.new(\"\\xC0\\xC0\").to_s\n      end\n    ensure\n      XSD::Charset.module_eval { @encoding = @encoding_backup }\n    end\n  end\n\n  def test_XSDBoolean\n    o = XSD::XSDBoolean.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::BooleanLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      [\"true\", true],\n      [\"1\", true],\n      [\"false\", false],\n      [\"0\", false],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDBoolean.new(data).data)\n      assert_equal(expected.to_s, XSD::XSDBoolean.new(data).to_s)\n    end\n\n    assert_raises(XSD::ValueSpaceError) do\n      XSD::XSDBoolean.new(\"nil\").to_s\n    end\n  end\n\n  def test_XSDDecimal\n    o = XSD::XSDDecimal.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DecimalLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      -9999999999,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789,\n    ]\n    targets.each do |dec|\n      assert_equal(dec.to_s, XSD::XSDDecimal.new(dec).data)\n    end\n\n    targets = [\n      \"0\",\n      \"0.00000001\",\n      \"1000000000\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n      \"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123.45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDDecimal.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"0.0\", \"0\"],\n      [\"-0.0\", \"0\"],\n      [\"+0.0\", \"0\"],\n      [\"0.\", \"0\"],\n      [\".0\", \"0\"],\n      [\n\t\"+0.12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"0.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\"\n     ],\n      [\n\t\".0000012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"0.000001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\"\n     ],\n      [\n\t\"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\",\n\t\"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n     ],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDDecimal.new(data).to_s)\n    end\n\n    targets = [\n      \"0.000000000000a\",\n      \"00a.0000000000001\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDDecimal.new(d)\n      end\n    end\n  end\n\n  def test_XSDFloat\n    o = XSD::XSDFloat.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::FloatLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      3.14159265358979,\n      12.34e36,\n      1.402e-45,\n      -1.402e-45,\n    ]\n    targets.each do |f|\n      assert_equal(f, XSD::XSDFloat.new(f).data)\n    end\n\n    targets = [\n      \"+3.141592654\",\n      \"+1.234e+37\",\n      \"+1.402e-45\",\n      \"-1.402e-45\",\n    ]\n    targets.each do |f|\n      assert_equal(f, XSD::XSDFloat.new(f).to_s)\n    end\n\n    targets = [\n      [3, \"+3\"], \t# should be 3.0?\n      [-2, \"-2\"],\t# ditto\n      [3.14159265358979, \"+3.141592654\"],\n      [12.34e36, \"+1.234e+37\"],\n      [1.402e-45, \"+1.402e-45\"],\n      [-1.402e-45, \"-1.402e-45\"],\n      [\"1.402e\", \"+1.402\"],\n      [\"12.34E36\", \"+1.234e+37\"],\n      [\"1.402E-45\", \"+1.402e-45\"],\n      [\"-1.402E-45\", \"-1.402e-45\"],\n      [\"1.402E\", \"+1.402\"],\n    ]\n    targets.each do |f, str|\n      assert_equal(str, XSD::XSDFloat.new(f).to_s)\n    end\n\n    assert_equal(\"+0\", XSD::XSDFloat.new(+0.0).to_s)\n    assert_equal(\"-0\", XSD::XSDFloat.new(NegativeZero).to_s)\n    assert(XSD::XSDFloat.new(0.0/0.0).data.nan?)\n    assert_equal(\"INF\", XSD::XSDFloat.new(1.0/0.0).to_s)\n    assert_equal(1, XSD::XSDFloat.new(1.0/0.0).data.infinite?)\n    assert_equal(\"-INF\", XSD::XSDFloat.new(-1.0/0.0).to_s)\n    assert_equal(-1, XSD::XSDFloat.new(-1.0/0.0).data.infinite?)\n\n    targets = [\n      \"0.000000000000a\",\n      \"00a.0000000000001\",\n      \"+-5\",\n      \"5_0\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDFloat.new(d)\n      end\n    end\n  end\n\n  def test_XSDDouble\n    o = XSD::XSDDouble.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DoubleLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      3.14159265358979,\n      12.34e36,\n      1.402e-45,\n      -1.402e-45,\n    ]\n    targets.each do |f|\n      assert_equal(f, XSD::XSDDouble.new(f).data)\n    end\n\n    targets = [\n      \"+3.14159265358979\",\n      \"+1.234e+37\",\n      \"+1.402e-45\",\n      \"-1.402e-45\",\n    ]\n    targets.each do |f|\n      assert_equal(f, XSD::XSDDouble.new(f).to_s)\n    end\n\n    targets = [\n      [3, \"+3\"],\t# should be 3.0?\n      [-2, \"-2\"],\t# ditto.\n      [3.14159265358979, \"+3.14159265358979\"],\n      [12.34e36, \"+1.234e+37\"],\n      [1.402e-45, \"+1.402e-45\"],\n      [-1.402e-45, \"-1.402e-45\"],\n      [\"1.402e\", \"+1.402\"],\n      [\"12.34E36\", \"+1.234e+37\"],\n      [\"1.402E-45\", \"+1.402e-45\"],\n      [\"-1.402E-45\", \"-1.402e-45\"],\n      [\"1.402E\", \"+1.402\"],\n    ]\n    targets.each do |f, str|\n      assert_equal(str, XSD::XSDDouble.new(f).to_s)\n    end\n\n    assert_equal(\"+0\", XSD::XSDFloat.new(+0.0).to_s)\n    assert_equal(\"-0\", XSD::XSDFloat.new(NegativeZero).to_s)\n    assert_equal(\"NaN\", XSD::XSDDouble.new(0.0/0.0).to_s)\n    assert(XSD::XSDDouble.new(0.0/0.0).data.nan?)\n    assert_equal(\"INF\", XSD::XSDDouble.new(1.0/0.0).to_s)\n    assert_equal(1, XSD::XSDDouble.new(1.0/0.0).data.infinite?)\n    assert_equal(\"-INF\", XSD::XSDDouble.new(-1.0/0.0).to_s)\n    assert_equal(-1, XSD::XSDDouble.new(-1.0/0.0).data.infinite?)\n\n    targets = [\n      \"0.000000000000a\",\n      \"00a.0000000000001\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDDouble.new(d)\n      end\n    end\n  end\n\n  def test_XSDDuration\n    o = XSD::XSDDuration.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DurationLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"P1Y2M3DT4H5M6S\",\n      \"P1234Y5678M9012DT3456H7890M1234.5678S\",\n      \"P0DT3456H7890M1234.5678S\",\n      \"P1234Y5678M9012D\",\n      \"-P1234Y5678M9012DT3456H7890M1234.5678S\",\n      \"P5678M9012DT3456H7890M1234.5678S\",\n      \"-P1234Y9012DT3456H7890M1234.5678S\",\n      \"+P1234Y5678MT3456H7890M1234.5678S\",\n      \"P1234Y5678M9012DT7890M1234.5678S\",\n      \"-P1234Y5678M9012DT3456H1234.5678S\",\n      \"+P1234Y5678M9012DT3456H7890M\",\n      \"P123400000000000Y\",\n      \"-P567800000000000M\",\n      \"+P901200000000000D\",\n      \"P0DT345600000000000H\",\n      \"-P0DT789000000000000M\",\n      \"+P0DT123400000000000.000000000005678S\",\n      \"P1234YT1234.5678S\",\n      \"-P5678MT7890M\",\n      \"+P9012DT3456H\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDDuration, str)\n    end\n\n    targets = [\n      [\"P0Y0M0DT0H0M0S\",\n        \"P0D\"],\n      [\"-P0DT0S\",\n        \"-P0D\"],\n      [\"P01234Y5678M9012DT3456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y005678M9012DT3456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M0009012DT3456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M9012DT00003456H7890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M9012DT3456H000007890M1234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n      [\"P1234Y5678M9012DT3456H7890M0000001234.5678S\",\n        \"P1234Y5678M9012DT3456H7890M1234.5678S\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDDuration.new(data).to_s)\n    end\n  end\n\n  def test_XSDDateTime\n    o = XSD::XSDDateTime.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DateTimeLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002-05-18T16:52:20Z\",\n      \"0001-01-01T00:00:00Z\",\n      \"9999-12-31T23:59:59Z\",\n      \"19999-12-31T23:59:59Z\",\n      \"2002-12-31T23:59:59.999Z\",\n      \"2002-12-31T23:59:59.001Z\",\n      \"2002-12-31T23:59:59.99999999999999999999Z\",\n      \"2002-12-31T23:59:59.00000000000000000001Z\",\n      \"2002-12-31T23:59:59+09:00\",\n      \"2002-12-31T23:59:59+00:01\",\n      \"2002-12-31T23:59:59-00:01\",\n      \"2002-12-31T23:59:59-23:59\",\n      \"2002-12-31T23:59:59.00000000000000000001+13:30\",\n      \"2002-12-31T23:59:59.5137Z\",\n      \"2002-12-31T23:59:59.51375Z\",\t# 411/800\n      \"2002-12-31T23:59:59.51375+12:34\",\n      \"-2002-05-18T16:52:20Z\",\n      \"-4713-01-01T12:00:00Z\",\n      \"-2002-12-31T23:59:59+00:01\",\n      \"-0001-12-31T23:59:59.00000000000000000001+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDDateTime, str)\n    end\n\n    targets = [\n      [\"2002-12-31T23:59:59.00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"2002-12-31T23:59:59+00:00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"2002-12-31T23:59:59-00:00\",\n\t\"2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59.00\",\n\t\"-2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59+00:00\",\n\t\"-2002-12-31T23:59:59Z\"],\n      [\"-2002-12-31T23:59:59-00:00\",\n\t\"-2002-12-31T23:59:59Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDDateTime.new(data).to_s)\n      d = DateTime.parse(data)\n      d >>= 12 if d.year < 0    # XSDDateTime.year(-1) == DateTime.year(0)\n      assert_equal(expected, XSD::XSDDateTime.new(d).to_s)\n    end\n\n    targets = [\n      \"0000-05-18T16:52:20Z\",\n      \"05-18T16:52:20Z\",\n      \"2002-05T16:52:20Z\",\n      \"2002-05-18T16:52Z\",\n      \"\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError, d.to_s) do\n\tXSD::XSDDateTime.new(d)\n      end\n    end\n  end\n\n  def test_XSDTime\n    o = XSD::XSDTime.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::TimeLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"16:52:20Z\",\n      \"00:00:00Z\",\n      \"23:59:59Z\",\n      \"23:59:59.999Z\",\n      \"23:59:59.001Z\",\n      \"23:59:59.99999999999999999999Z\",\n      \"23:59:59.00000000000000000001Z\",\n      \"23:59:59+09:00\",\n      \"23:59:59+00:01\",\n      \"23:59:59-00:01\",\n      \"23:59:59-23:59\",\n      \"23:59:59.00000000000000000001+13:30\",\n      \"23:59:59.51345Z\",\n      \"23:59:59.51345+12:34\",\n      \"23:59:59+00:01\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDTime, str)\n    end\n\n    targets = [\n      [\"23:59:59.00\",\n\t\"23:59:59Z\"],\n      [\"23:59:59+00:00\",\n\t\"23:59:59Z\"],\n      [\"23:59:59-00:00\",\n\t\"23:59:59Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDTime.new(data).to_s)\n    end\n  end\n\n  def test_XSDDate\n    o = XSD::XSDDate.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::DateLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002-05-18Z\",\n      \"0001-01-01Z\",\n      \"9999-12-31Z\",\n      \"19999-12-31Z\",\n      \"2002-12-31+09:00\",\n      \"2002-12-31+00:01\",\n      \"2002-12-31-00:01\",\n      \"2002-12-31-23:59\",\n      \"2002-12-31+13:30\",\n      \"-2002-05-18Z\",\n      \"-19999-12-31Z\",\n      \"-2002-12-31+00:01\",\n      \"-0001-12-31+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDDate, str)\n    end\n\n    targets = [\n      [\"2002-12-31\",\n\t\"2002-12-31Z\"],\n      [\"2002-12-31+00:00\",\n\t\"2002-12-31Z\"],\n      [\"2002-12-31-00:00\",\n\t\"2002-12-31Z\"],\n      [\"-2002-12-31\",\n\t\"-2002-12-31Z\"],\n      [\"-2002-12-31+00:00\",\n\t\"-2002-12-31Z\"],\n      [\"-2002-12-31-00:00\",\n\t\"-2002-12-31Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDDate.new(data).to_s)\n      d = Date.parse(data)\n      d >>= 12 if d.year < 0    # XSDDate.year(-1) == Date.year(0)\n      assert_equal(expected, XSD::XSDDate.new(d).to_s)\n    end\n  end\nend\n\nclass TestXSD2 < Test::Unit::TestCase\n  def setup\n    # Nothing to do.\n  end\n\n  def teardown\n    # Nothing to do.\n  end\n\n  def assert_parsed_result(klass, str)\n    o = klass.new(str)\n    assert_equal(str, o.to_s)\n  end\n\n  def test_XSDGYearMonth\n    o = XSD::XSDGYearMonth.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GYearMonthLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002-05Z\",\n      \"0001-01Z\",\n      \"9999-12Z\",\n      \"19999-12Z\",\n      \"2002-12+09:00\",\n      \"2002-12+00:01\",\n      \"2002-12-00:01\",\n      \"2002-12-23:59\",\n      \"2002-12+13:30\",\n      \"-2002-05Z\",\n      \"-19999-12Z\",\n      \"-2002-12+00:01\",\n      \"-0001-12+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDGYearMonth, str)\n    end\n\n    targets = [\n      [\"2002-12\",\n\t\"2002-12Z\"],\n      [\"2002-12+00:00\",\n\t\"2002-12Z\"],\n      [\"2002-12-00:00\",\n\t\"2002-12Z\"],\n      [\"-2002-12\",\n\t\"-2002-12Z\"],\n      [\"-2002-12+00:00\",\n\t\"-2002-12Z\"],\n      [\"-2002-12-00:00\",\n\t\"-2002-12Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDGYearMonth.new(data).to_s)\n    end\n  end\n\n  def test_XSDGYear\n    o = XSD::XSDGYear.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GYearLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"2002Z\",\n      \"0001Z\",\n      \"9999Z\",\n      \"19999Z\",\n      \"2002+09:00\",\n      \"2002+00:01\",\n      \"2002-00:01\",\n      \"2002-23:59\",\n      \"2002+13:30\",\n      \"-2002Z\",\n      \"-19999Z\",\n      \"-2002+00:01\",\n      \"-0001+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDGYear, str)\n    end\n\n    targets = [\n      [\"2002\",\n\t\"2002Z\"],\n      [\"2002+00:00\",\n\t\"2002Z\"],\n      [\"2002-00:00\",\n\t\"2002Z\"],\n      [\"-2002\",\n\t\"-2002Z\"],\n      [\"-2002+00:00\",\n\t\"-2002Z\"],\n      [\"-2002-00:00\",\n\t\"-2002Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDGYear.new(data).to_s)\n    end\n  end\n\n  def test_XSDGMonthDay\n    o = XSD::XSDGMonthDay.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GMonthDayLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"05-18Z\",\n      \"01-01Z\",\n      \"12-31Z\",\n      \"12-31+09:00\",\n      \"12-31+00:01\",\n      \"12-31-00:01\",\n      \"12-31-23:59\",\n      \"12-31+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDGMonthDay, str)\n    end\n\n    targets = [\n      [\"12-31\",\n\t\"12-31Z\"],\n      [\"12-31+00:00\",\n\t\"12-31Z\"],\n      [\"12-31-00:00\",\n\t\"12-31Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDGMonthDay.new(data).to_s)\n    end\n  end\n\n  def test_XSDGDay\n    o = XSD::XSDGDay.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GDayLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"18Z\",\n      \"01Z\",\n      \"31Z\",\n      \"31+09:00\",\n      \"31+00:01\",\n      \"31-00:01\",\n      \"31-23:59\",\n      \"31+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDGDay, str)\n    end\n\n    targets = [\n      [\"31\",\n\t\"31Z\"],\n      [\"31+00:00\",\n\t\"31Z\"],\n      [\"31-00:00\",\n\t\"31Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDGDay.new(data).to_s)\n    end\n  end\n\n  def test_XSDGMonth\n    o = XSD::XSDGMonth.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::GMonthLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"05Z\",\n      \"01Z\",\n      \"12Z\",\n      \"12+09:00\",\n      \"12+00:01\",\n      \"12-00:01\",\n      \"12-23:59\",\n      \"12+13:30\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDGMonth, str)\n    end\n\n    targets = [\n      [\"12\",\n\t\"12Z\"],\n      [\"12+00:00\",\n\t\"12Z\"],\n      [\"12-00:00\",\n\t\"12Z\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDGMonth.new(data).to_s)\n    end\n  end\n\n  def test_XSDHexBinary\n    o = XSD::XSDHexBinary.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::HexBinaryLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"abcdef\",\n      \"\\xe3\\x81\\xaa\\xe3\\x81\\xb2\",\n      %Q(\\0),\n      \"\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDHexBinary.new(str).string)\n      assert_equal(str.unpack(\"H*\")[0 ].tr('a-f', 'A-F'),\n\tXSD::XSDHexBinary.new(str).data)\n      o = XSD::XSDHexBinary.new\n      o.set_encoded(str.unpack(\"H*\")[0 ].tr('a-f', 'A-F'))\n      assert_equal(str, o.string)\n      o.set_encoded(str.unpack(\"H*\")[0 ].tr('A-F', 'a-f'))\n      assert_equal(str, o.string)\n    end\n\n    targets = [\n      \"0FG7\",\n      \"0fg7\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError, d.to_s) do\n\to = XSD::XSDHexBinary.new\n\to.set_encoded(d)\n\tp o.string\n      end\n    end\n  end\n\n  def test_XSDBase64Binary\n    o = XSD::XSDBase64Binary.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::Base64BinaryLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      \"abcdef\",\n      \"\\xe3\\x81\\xaa\\xe3\\x81\\xb2\",\n      %Q(\\0),\n      \"\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDBase64Binary.new(str).string)\n      assert_equal([str ].pack(\"m\").chomp, XSD::XSDBase64Binary.new(str).data)\n      o = XSD::XSDBase64Binary.new\n      o.set_encoded([str ].pack(\"m\").chomp)\n      assert_equal(str, o.string)\n    end\n\n    targets = [\n      \"-\",\n      \"*\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError, d.to_s) do\n\to = XSD::XSDBase64Binary.new\n\to.set_encoded(d)\n\tp o.string\n      end\n    end\n  end\n\n  def test_XSDAnyURI\n    o = XSD::XSDAnyURI.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::AnyURILiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    # Too few tests here I know.  Believe uri module. :)\n    targets = [\n      \"foo\",\n      \"http://foo\",\n      \"http://foo/bar/baz\",\n      \"http://foo/bar#baz\",\n      \"http://foo/bar%20%20?a+b\",\n      \"HTTP://FOO/BAR%20%20?A+B\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDAnyURI, str)\n    end\n  end\n\n  def test_XSDQName\n    o = XSD::XSDQName.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::QNameLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    # More strict test is needed but current implementation allows all non-':'\n    # chars like ' ', C0 or C1...\n    targets = [\n      \"foo\",\n      \"foo:bar\",\n      \"a:b\",\n    ]\n    targets.each do |str|\n      assert_parsed_result(XSD::XSDQName, str)\n    end\n  end\n\n\n  ###\n  ## Derived types\n  #\n\n  def test_XSDInteger\n    o = XSD::XSDInteger.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::IntegerLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      -9999999999,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n      -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDInteger.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"1000000000\",\n      \"-9999999999\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n      \"-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDInteger.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n      [\n\t\"+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n     ],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDInteger.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDInteger.new(d)\n      end\n    end\n  end\n\n  def test_XSDNonPositiveInteger\n    o = XSD::XSDNonPositiveInteger.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::NonPositiveIntegerLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      -9999999999,\n      -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDNonPositiveInteger.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"-9999999999\",\n      \"-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDNonPositiveInteger.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDNonPositiveInteger.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDNonPositiveInteger.new(d)\n      end\n    end\n  end\n\n  def test_XSDNegativeInteger\n    o = XSD::XSDNegativeInteger.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::NegativeIntegerLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      -1,\n      -9999999999,\n      -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDNegativeInteger.new(int).data)\n    end\n\n    targets = [\n      \"-1\",\n      \"-9999999999\",\n      \"-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDNegativeInteger.new(str).to_s)\n    end\n\n    targets = [\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDNegativeInteger.new(data).to_s)\n    end\n\n    targets = [\n      \"-0.0\",\n      \"-5.2\",\n      \"-0.000000000000a\",\n      \"+-5\",\n      \"-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDNegativeInteger.new(d)\n      end\n    end\n  end\n\n  def test_XSDLong\n    o = XSD::XSDLong.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::LongLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      123,\n      -123,\n      9223372036854775807,\n      -9223372036854775808,\n    ]\n    targets.each do |lng|\n      assert_equal(lng, XSD::XSDLong.new(lng).data)\n    end\n\n    targets = [\n      \"0\",\n      \"123\",\n      \"-123\",\n      \"9223372036854775807\",\n      \"-9223372036854775808\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDLong.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDLong.new(data).to_s)\n    end\n\n    targets = [\n      9223372036854775808,\n      -9223372036854775809,\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDLong.new(d)\n      end\n    end\n  end\n\n  def test_XSDInt\n    o = XSD::XSDInt.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::IntLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      123,\n      -123,\n      2147483647,\n      -2147483648,\n    ]\n    targets.each do |lng|\n      assert_equal(lng, XSD::XSDInt.new(lng).data)\n    end\n\n    targets = [\n      \"0\",\n      \"123\",\n      \"-123\",\n      \"2147483647\",\n      \"-2147483648\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDInt.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDInt.new(data).to_s)\n    end\n\n    targets = [\n      2147483648,\n      -2147483649,\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDInt.new(d)\n      end\n    end\n  end\n\n  def test_XSDShort\n    o = XSD::XSDShort.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::ShortLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      123,\n      -123,\n      32767,\n      -32768,\n    ]\n    targets.each do |lng|\n      assert_equal(lng, XSD::XSDShort.new(lng).data)\n    end\n\n    targets = [\n      \"0\",\n      \"123\",\n      \"-123\",\n      \"32767\",\n      \"-32768\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDShort.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDShort.new(data).to_s)\n    end\n\n    targets = [\n      32768,\n      -32769,\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDShort.new(d)\n      end\n    end\n  end\n\n  def test_XSDByte\n    o = XSD::XSDByte.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::ByteLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      123,\n      -123,\n      127,\n      -128,\n    ]\n    targets.each do |lng|\n      assert_equal(lng, XSD::XSDByte.new(lng).data)\n    end\n\n    targets = [\n      \"0\",\n      \"123\",\n      \"-123\",\n      \"127\",\n      \"-128\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDByte.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"-000123\", \"-123\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDByte.new(data).to_s)\n    end\n\n    targets = [\n      128,\n      -129,\n      \"0.0\",\n      \"-5.2\",\n      \"0.000000000000a\",\n      \"+-5\",\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDByte.new(d)\n      end\n    end\n  end\n\n  def test_XSDNonNegativeInteger\n    o = XSD::XSDNonNegativeInteger.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::NonNegativeIntegerLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDNonNegativeInteger.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"1000000000\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDNonNegativeInteger.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\n\t\"+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n     ],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDNonNegativeInteger.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDNonNegativeInteger.new(d)\n      end\n    end\n  end\n\n  def test_XSDUnsignedLong\n    o = XSD::XSDUnsignedLong.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::UnsignedLongLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      18446744073709551615,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDUnsignedLong.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"1000000000\",\n      \"18446744073709551615\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDUnsignedLong.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"+18446744073709551615\", \"18446744073709551615\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDUnsignedLong.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"18446744073709551615.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDUnsignedLong.new(d)\n      end\n    end\n  end\n\n  def test_XSDUnsignedInt\n    o = XSD::XSDUnsignedInt.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::UnsignedIntLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      1000000000,\n      4294967295,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDUnsignedInt.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"1000000000\",\n      \"4294967295\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDUnsignedInt.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"+4294967295\", \"4294967295\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDUnsignedInt.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"4294967295.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDUnsignedInt.new(d)\n      end\n    end\n  end\n\n  def test_XSDUnsignedShort\n    o = XSD::XSDUnsignedShort.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::UnsignedShortLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      10000,\n      65535,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDUnsignedShort.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"1000\",\n      \"65535\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDUnsignedShort.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"+65535\", \"65535\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDUnsignedShort.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"65535.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDUnsignedShort.new(d)\n      end\n    end\n  end\n\n  def test_XSDUnsignedByte\n    o = XSD::XSDUnsignedByte.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::UnsignedByteLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      0,\n      10,\n      255,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDUnsignedByte.new(int).data)\n    end\n\n    targets = [\n      \"0\",\n      \"10\",\n      \"255\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDUnsignedByte.new(str).to_s)\n    end\n\n    targets = [\n      [\"-0\", \"0\"],\n      [\"+0\", \"0\"],\n      [\"000123\", \"123\"],\n      [\"+255\", \"255\"],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDUnsignedByte.new(data).to_s)\n    end\n\n    targets = [\n      \"0.0\",\n      \"0.000000000000a\",\n      \"+-5\",\n      \"255.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDUnsignedByte.new(d)\n      end\n    end\n  end\n\n  def test_XSDPositiveInteger\n    o = XSD::XSDPositiveInteger.new\n    assert_equal(XSD::Namespace, o.type.namespace)\n    assert_equal(XSD::PositiveIntegerLiteral, o.type.name)\n    assert_equal(nil, o.data)\n    assert_equal(true, o.is_nil)\n\n    targets = [\n      1,\n      1000000000,\n      12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890,\n    ]\n    targets.each do |int|\n      assert_equal(int, XSD::XSDPositiveInteger.new(int).data)\n    end\n\n    targets = [\n      \"1\",\n      \"1000000000\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n    ]\n    targets.each do |str|\n      assert_equal(str, XSD::XSDPositiveInteger.new(str).to_s)\n    end\n\n    targets = [\n      [\"+1\", \"1\"],\n      [\"000123\", \"123\"],\n      [\n\t\"+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\",\n\t\"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\"\n     ],\n    ]\n    targets.each do |data, expected|\n      assert_equal(expected, XSD::XSDPositiveInteger.new(data).to_s)\n    end\n\n    targets = [\n      \"1.0\",\n      \"1.000000000000a\",\n      \"+-5\",\n      \"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890.\"\n    ]\n    targets.each do |d|\n      assert_raises(XSD::ValueSpaceError) do\n\tXSD::XSDPositiveInteger.new(d)\n      end\n    end\n  end\nend\n\n\nend\n"
  },
  {
    "path": "test/xsd/xmlschema.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<xs:schema\n    attributeFormDefault=\"qualified\"\n    elementFormDefault=\"qualified\"\n    targetNamespace=\"urn:jp.gr.jin.rrr.example.fakeschema\"\n    xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n  <xs:element name=\"MessageDataSet\">\n    <xs:complexType>\n      <xs:choice maxOccurs=\"unbounded\" />\n    </xs:complexType>\n  </xs:element>\n</xs:schema>\n"
  },
  {
    "path": "test/yaml/test_yaml.rb",
    "content": "# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*-\n#\t\t\t\t\t\t\t\t\t\t\t\tvim:sw=4:ts=4\n# $Id$\n#\nrequire 'test/unit'\nrequire 'yaml'\n\n# [ruby-core:01946]\nmodule YAML_Tests\n    StructTest = Struct::new( :c )\nend\n\nclass YAML_Unit_Tests < Test::Unit::TestCase\n\t#\n\t# Convert between YAML and the object to verify correct parsing and\n\t# emitting\n\t#\n\tdef assert_to_yaml( obj, yaml )\n\t\tassert_equal( obj, YAML::load( yaml ) )\n\t\tassert_equal( obj, YAML::parse( yaml ).transform )\n        assert_equal( obj, YAML::load( obj.to_yaml ) )\n\t\tassert_equal( obj, YAML::parse( obj.to_yaml ).transform )\n        assert_equal( obj, YAML::load(\n\t\t\tobj.to_yaml( :UseVersion => true, :UseHeader => true, :SortKeys => true ) \n\t\t) )\n\tend\n\n\t#\n\t# Test parser only\n\t#\n\tdef assert_parse_only( obj, yaml )\n\t\tassert_equal( obj, YAML::load( yaml ) )\n\t\tassert_equal( obj, YAML::parse( yaml ).transform )\n\tend\n\n    def assert_cycle( obj )\n        assert_equal( obj, YAML::load( obj.to_yaml ) )\n    end\n\n    def assert_path_segments( path, segments )\n        YAML::YPath.each_path( path ) { |choice|\n            assert_equal( choice.segments, segments.shift )\n        }\n        assert_equal( segments.length, 0, \"Some segments leftover: #{ segments.inspect }\" )\n    end\n\n\t#\n\t# Make a time with the time zone\n\t#\n\tdef mktime( year, mon, day, hour, min, sec, usec, zone = \"Z\" )\n        usec = usec.to_s.to_f * 1000000\n\t\tval = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )\n\t\tif zone != \"Z\"\n\t\t\thour = zone[0,3].to_i * 3600\n\t\t\tmin = zone[3,2].to_i * 60\n\t\t\tofs = (hour + min)\n\t\t\tval = Time.at( val.to_f - ofs )\n\t\tend\n\t\treturn val\n\tend\n\n\t#\n\t# Tests modified from 00basic.t in YAML.pm\n\t#\n\tdef test_basic_map\n\t\t# Simple map\n\t\tassert_parse_only(\n\t\t\t{ 'one' => 'foo', 'three' => 'baz', 'two' => 'bar' }, <<EOY\none: foo\ntwo: bar\nthree: baz\nEOY\n\t\t)\n\tend\n\n\tdef test_basic_strings\n\t\t# Common string types\n\t\tassert_cycle(\"x\")\n\t\tassert_cycle(\":x\")\n\t\tassert_cycle(\":\")\n\t\tassert_parse_only(\n\t\t\t{ 1 => 'simple string', 2 => 42, 3 => '1 Single Quoted String',\n\t\t\t  4 => 'YAML\\'s Double \"Quoted\" String', 5 => \"A block\\n  with several\\n    lines.\\n\",\n\t\t\t  6 => \"A \\\"chomped\\\" block\", 7 => \"A folded\\n string\\n\", 8 => \": started string\" },\n\t\t\t  <<EOY\n1: simple string\n2: 42\n3: '1 Single Quoted String'\n4: \"YAML's Double \\\\\\\"Quoted\\\\\\\" String\"\n5: |\n  A block\n    with several\n      lines.\n6: |-\n  A \"chomped\" block\n7: >\n  A\n  folded\n   string\n8: \": started string\"\nEOY\n\t\t)\n\tend\n\n\t#\n\t# Test the specification examples\n\t# - Many examples have been changes because of whitespace problems that\n\t#   caused the two to be inequivalent, or keys to be sorted wrong\n\t#\n\n\tdef test_spec_simple_implicit_sequence\n\t  \t# Simple implicit sequence\n\t\tassert_to_yaml(\n\t\t\t[ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ], <<EOY\n- Mark McGwire\n- Sammy Sosa\n- Ken Griffey\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_simple_implicit_map\n\t\t# Simple implicit map\n\t\tassert_to_yaml(\n\t\t\t{ 'hr' => 65, 'avg' => 0.278, 'rbi' => 147 }, <<EOY\navg: 0.278\nhr: 65\nrbi: 147\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_simple_map_with_nested_sequences\n\t\t# Simple mapping with nested sequences\n\t\tassert_to_yaml(\n\t\t\t{ 'american' => \n\t\t\t  [ 'Boston Red Sox', 'Detroit Tigers', 'New York Yankees' ],\n\t\t\t  'national' =>\n\t\t\t  [ 'New York Mets', 'Chicago Cubs', 'Atlanta Braves' ] }, <<EOY\namerican:\n  - Boston Red Sox\n  - Detroit Tigers\n  - New York Yankees\nnational:\n  - New York Mets\n  - Chicago Cubs\n  - Atlanta Braves\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_simple_sequence_with_nested_map\n\t\t# Simple sequence with nested map\n\t\tassert_to_yaml(\n\t\t  [\n\t\t    {'name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278},\n\t\t\t{'name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288}\n\t\t  ], <<EOY\n-\n  avg: 0.278\n  hr: 65\n  name: Mark McGwire\n-\n  avg: 0.288\n  hr: 63\n  name: Sammy Sosa\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_sequence_of_sequences\n\t\t# Simple sequence with inline sequences\n\t\tassert_parse_only(\n\t\t  [ \n\t\t  \t[ 'name', 'hr', 'avg' ],\n\t\t\t[ 'Mark McGwire', 65, 0.278 ],\n\t\t\t[ 'Sammy Sosa', 63, 0.288 ]\n\t\t  ], <<EOY\n- [ name         , hr , avg   ]\n- [ Mark McGwire , 65 , 0.278 ]\n- [ Sammy Sosa   , 63 , 0.288 ]\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_mapping_of_mappings\n\t\t# Simple map with inline maps\n\t\tassert_parse_only(\n\t\t  { 'Mark McGwire' =>\n\t\t    { 'hr' => 65, 'avg' => 0.278 },\n\t\t\t'Sammy Sosa' =>\n\t\t    { 'hr' => 63, 'avg' => 0.288 }\n\t\t  }, <<EOY\nMark McGwire: {hr: 65, avg: 0.278}\nSammy Sosa:   {hr: 63,\n               avg: 0.288}\nEOY\n\t\t)\n\tend\n\n    def test_ambiguous_comments\n        # [ruby-talk:88012]\n        assert_to_yaml( \"Call the method #dave\", <<EOY )\n--- \"Call the method #dave\"\nEOY\n    end\n\n\tdef test_spec_nested_comments\n\t\t# Map and sequences with comments\n\t\tassert_parse_only(\n\t\t  { 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ],\n\t\t    'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY\nhr: # 1998 hr ranking\n  - Mark McGwire\n  - Sammy Sosa\nrbi:\n  # 1998 rbi ranking\n  - Sammy Sosa\n  - Ken Griffey\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_anchors_and_aliases\n\t\t# Anchors and aliases\n\t\tassert_parse_only(\n\t\t\t{ 'hr' =>\n\t\t\t  [ 'Mark McGwire', 'Sammy Sosa' ],\n\t\t\t  'rbi' =>\n\t\t\t  [ 'Sammy Sosa', 'Ken Griffey' ] }, <<EOY\nhr:\n   - Mark McGwire\n   # Name \"Sammy Sosa\" scalar SS\n   - &SS Sammy Sosa\nrbi:\n   # So it can be referenced later.\n   - *SS\n   - Ken Griffey\nEOY\n\t \t)\n\n        assert_to_yaml(\n            [{\"arrival\"=>\"EDI\", \"departure\"=>\"LAX\", \"fareref\"=>\"DOGMA\", \"currency\"=>\"GBP\"}, {\"arrival\"=>\"MEL\", \"departure\"=>\"SYD\", \"fareref\"=>\"MADF\", \"currency\"=>\"AUD\"}, {\"arrival\"=>\"MCO\", \"departure\"=>\"JFK\", \"fareref\"=>\"DFSF\", \"currency\"=>\"USD\"}], <<EOY\n  -   \n    &F fareref: DOGMA\n    &C currency: GBP\n    &D departure: LAX\n    &A arrival: EDI \n  - { *F: MADF, *C: AUD, *D: SYD, *A: MEL }\n  - { *F: DFSF, *C: USD, *D: JFK, *A: MCO }\nEOY\n        )\n\n        assert_to_yaml(\n            {\"ALIASES\"=>[\"fareref\", \"currency\", \"departure\", \"arrival\"], \"FARES\"=>[{\"arrival\"=>\"EDI\", \"departure\"=>\"LAX\", \"fareref\"=>\"DOGMA\", \"currency\"=>\"GBP\"}, {\"arrival\"=>\"MEL\", \"departure\"=>\"SYD\", \"fareref\"=>\"MADF\", \"currency\"=>\"AUD\"}, {\"arrival\"=>\"MCO\", \"departure\"=>\"JFK\", \"fareref\"=>\"DFSF\", \"currency\"=>\"USD\"}]}, <<EOY\n---\nALIASES: [&f fareref, &c currency, &d departure, &a arrival]\nFARES:\n- *f: DOGMA\n  *c: GBP\n  *d: LAX\n  *a: EDI\n\n- *f: MADF\n  *c: AUD\n  *d: SYD\n  *a: MEL\n\n- *f: DFSF\n  *c: USD\n  *d: JFK\n  *a: MCO\n\nEOY\n        )\n\n\tend\n\n\tdef test_spec_mapping_between_sequences\n\t\t# Complex key #1\n\t\tdj = Date.new( 2001, 7, 23 )\n\t\tassert_parse_only(\n\t\t\t{ [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],\n\t\t\t  [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] }, <<EOY\n? # PLAY SCHEDULE\n  - Detroit Tigers\n  - Chicago Cubs\n:  \n  - 2001-07-23\n\n? [ New York Yankees,\n    Atlanta Braves ]\n: [ 2001-07-02, 2001-08-12, \n    2001-08-14 ]\nEOY\n\t\t)\n\n\t\t# Complex key #2\n\t\tassert_parse_only(\n\t\t  { [ 'New York Yankees', 'Atlanta Braves' ] =>\n\t\t    [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ),\n\t\t\t  Date.new( 2001, 8, 14 ) ],\n\t\t\t[ 'Detroit Tigers', 'Chicago Cubs' ] =>\n\t\t\t[ Date.new( 2001, 7, 23 ) ]\n\t\t  }, <<EOY\n?\n    - New York Yankees\n    - Atlanta Braves\n:\n  - 2001-07-02\n  - 2001-08-12\n  - 2001-08-14\n?\n    - Detroit Tigers\n    - Chicago Cubs\n:\n  - 2001-07-23\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_sequence_key_shortcut\n\t\t# Shortcut sequence map\n\t\tassert_parse_only(\n\t\t  { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),\n\t\t    'bill-to' => 'Chris Dumars', 'product' =>\n\t\t\t[ { 'item' => 'Super Hoop', 'quantity' => 1 },\n\t\t\t  { 'item' => 'Basketball', 'quantity' => 4 },\n\t\t\t  { 'item' => 'Big Shoes', 'quantity' => 1 } ] }, <<EOY\ninvoice: 34843\ndate   : 2001-01-23\nbill-to: Chris Dumars\nproduct:\n  - item    : Super Hoop\n    quantity: 1\n  - item    : Basketball\n    quantity: 4\n  - item    : Big Shoes\n    quantity: 1\nEOY\n\t\t)\n\tend\n\n    def test_spec_sequence_in_sequence_shortcut\n        # Seq-in-seq\n        assert_parse_only( [ [ [ 'one', 'two', 'three' ] ] ], <<EOY )\n- - - one\n    - two\n    - three\nEOY\n    end\n\n    def test_spec_sequence_shortcuts\n        # Sequence shortcuts combined\n        assert_parse_only( \n[\n  [ \n    [ [ 'one' ] ],\n    [ 'two', 'three' ],\n    { 'four' => nil },\n    [ { 'five' => [ 'six' ] } ],\n    [ 'seven' ]\n  ],\n  [ 'eight', 'nine' ]\n], <<EOY )\n- - - - one\n  - - two\n    - three\n  - four:\n  - - five:\n      - six\n  - - seven\n- - eight\n  - nine\nEOY\n    end\n\n\tdef test_spec_single_literal\n\t\t# Literal scalar block\n\t\tassert_parse_only( [ \"\\\\/|\\\\/|\\n/ |  |_\\n\" ], <<EOY )\n- |\n    \\\\/|\\\\/|\n    / |  |_\nEOY\n\tend\n\n\tdef test_spec_single_folded\n\t\t# Folded scalar block\n\t\tassert_parse_only(\n\t\t\t[ \"Mark McGwire's year was crippled by a knee injury.\\n\" ], <<EOY\n- >\n    Mark McGwire\\'s\n    year was crippled\n    by a knee injury.\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_preserve_indent\n\t\t# Preserve indented spaces\n\t\tassert_parse_only(\n\t\t\t\"Sammy Sosa completed another fine season with great stats.\\n\\n  63 Home Runs\\n  0.288 Batting Average\\n\\nWhat a year!\\n\", <<EOY\n--- >\n Sammy Sosa completed another\n fine season with great stats.\n\n   63 Home Runs\n   0.288 Batting Average\n\n What a year!\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_indentation_determines_scope\n\t\tassert_parse_only(\n\t\t\t{ 'name' => 'Mark McGwire', 'accomplishment' => \"Mark set a major league home run record in 1998.\\n\",\n\t\t\t  'stats' => \"65 Home Runs\\n0.278 Batting Average\\n\" }, <<EOY\nname: Mark McGwire\naccomplishment: >\n   Mark set a major league\n   home run record in 1998.\nstats: |\n   65 Home Runs\n   0.278 Batting Average\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_multiline_scalars\n\t\t# Multiline flow scalars\n\t \tassert_parse_only(\n\t \t\t{ 'plain' => 'This unquoted scalar spans many lines.',\n\t \t\t  'quoted' => \"So does this quoted scalar.\\n\" }, <<EOY\nplain: This unquoted\n       scalar spans\n       many lines.\nquoted: \"\\\\\n  So does this quoted\n  scalar.\\\\n\"\nEOY\n\t\t)\n\tend\t\n\n\tdef test_spec_type_int\n\t\tassert_parse_only(\n\t\t\t{ 'canonical' => 12345, 'decimal' => 12345, 'octal' => '014'.oct, 'hexadecimal' => '0xC'.hex }, <<EOY\ncanonical: 12345\ndecimal: +12,345\noctal: 014\nhexadecimal: 0xC\nEOY\n\t\t)\n\t\tassert_parse_only(\n            { 'canonical' => 685230, 'decimal' => 685230, 'octal' => 02472256, 'hexadecimal' => 0x0A74AE, 'sexagesimal' => 685230 }, <<EOY)\ncanonical: 685230\ndecimal: +685,230\noctal: 02472256\nhexadecimal: 0x0A,74,AE\nsexagesimal: 190:20:30\nEOY\n\tend\n\n\tdef test_spec_type_float\n\t\tassert_parse_only(\n\t\t\t{ 'canonical' => 1230.15, 'exponential' => 1230.15, 'fixed' => 1230.15,\n\t\t\t  'negative infinity' => -1.0/0.0 }, <<EOY)\ncanonical: 1.23015e+3\nexponential: 12.3015e+02\nfixed: 1,230.15\nnegative infinity: -.inf\nEOY\n\t\tnan = YAML::load( <<EOY )\nnot a number: .NaN\nEOY\n\t\tassert( nan['not a number'].nan? )\n\tend\n\n\tdef test_spec_type_misc\n\t\tassert_parse_only(\n\t\t\t{ nil => nil, true => true, false => false, 'string' => '12345' }, <<EOY\nnull: ~\ntrue: yes\nfalse: no\nstring: '12345'\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_complex_invoice\n\t\t# Complex invoice type\n\t\tid001 = { 'given' => 'Chris', 'family' => 'Dumars', 'address' =>\n\t\t\t{ 'lines' => \"458 Walkman Dr.\\nSuite #292\\n\", 'city' => 'Royal Oak',\n\t\t\t  'state' => 'MI', 'postal' => 48046 } }\n\t\tassert_parse_only(\n\t\t\t{ 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ),\n\t\t\t  'bill-to' => id001, 'ship-to' => id001, 'product' =>\n\t\t\t  [ { 'sku' => 'BL394D', 'quantity' => 4,\n\t\t\t      'description' => 'Basketball', 'price' => 450.00 },\n\t\t\t\t{ 'sku' => 'BL4438H', 'quantity' => 1,\n\t\t\t\t  'description' => 'Super Hoop', 'price' => 2392.00 } ],\n\t\t\t  'tax' => 251.42, 'total' => 4443.52,\n\t\t\t  'comments' => \"Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\\n\" }, <<EOY\ninvoice: 34843\ndate   : 2001-01-23\nbill-to: &id001\n    given  : Chris\n    family : !str Dumars\n    address:\n        lines: |\n            458 Walkman Dr.\n            Suite #292\n        city    : Royal Oak\n        state   : MI\n        postal  : 48046\nship-to: *id001\nproduct:\n    - !map\n      sku         : BL394D\n      quantity    : 4\n      description : Basketball\n      price       : 450.00\n    - sku         : BL4438H\n      quantity    : 1\n      description : Super Hoop\n      price       : 2392.00\ntax  : 251.42\ntotal: 4443.52\ncomments: >\n    Late afternoon is best.\n    Backup contact is Nancy\n    Billsmer @ 338-4338.\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_log_file\n\t\tdoc_ct = 0\n\t\tYAML::load_documents( <<EOY\n---\nTime: 2001-11-23 15:01:42 -05:00\nUser: ed\nWarning: >\n  This is an error message\n  for the log file\n---\nTime: 2001-11-23 15:02:31 -05:00\nUser: ed\nWarning: >\n  A slightly different error\n  message.\n---\nDate: 2001-11-23 15:03:17 -05:00\nUser: ed\nFatal: >\n  Unknown variable \"bar\"\nStack:\n  - file: TopClass.py\n    line: 23\n    code: |\n      x = MoreObject(\"345\\\\n\")\n  - file: MoreClass.py\n    line: 58\n    code: |-\n      foo = bar\nEOY\n\t\t) { |doc|\n\t\t\tcase doc_ct\n\t\t\t\twhen 0\n\t\t\t\t\tassert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 01, 42, 00, \"-05:00\" ),\n\t\t\t\t\t\t'User' => 'ed', 'Warning' => \"This is an error message for the log file\\n\" } )\n\t\t\t\twhen 1\n\t\t\t\t\tassert_equal( doc, { 'Time' => mktime( 2001, 11, 23, 15, 02, 31, 00, \"-05:00\" ),\n\t\t\t\t\t\t'User' => 'ed', 'Warning' => \"A slightly different error message.\\n\" } )\n\t\t\t\twhen 2\n\t\t\t\t\tassert_equal( doc, { 'Date' => mktime( 2001, 11, 23, 15, 03, 17, 00, \"-05:00\" ),\n\t\t\t\t\t\t'User' => 'ed', 'Fatal' => \"Unknown variable \\\"bar\\\"\\n\",\n\t\t\t\t\t\t'Stack' => [\n\t\t\t\t\t\t\t{ 'file' => 'TopClass.py', 'line' => 23, 'code' => \"x = MoreObject(\\\"345\\\\n\\\")\\n\" },\n\t\t\t\t\t\t\t{ 'file' => 'MoreClass.py', 'line' => 58, 'code' => \"foo = bar\" } ] } )\n\t\t\tend\n\t\t\tdoc_ct += 1\n\t\t}\n\t\tassert_equal( doc_ct, 3 )\n\tend\n\n\tdef test_spec_root_fold\n\t\ty = YAML::load( <<EOY\n--- >\nThis YAML stream contains a single text value.\nThe next stream is a log file - a sequence of\nlog entries. Adding an entry to the log is a\nsimple matter of appending it at the end.\nEOY\n\t\t)\n\t\tassert_equal( y, \"This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\\n\" )\n\tend\n\n\tdef test_spec_root_mapping\n\t\ty = YAML::load( <<EOY\n# This stream is an example of a top-level mapping.\ninvoice : 34843\ndate    : 2001-01-23\ntotal   : 4443.52\nEOY\n\t\t)\n\t\tassert_equal( y, { 'invoice' => 34843, 'date' => Date.new( 2001, 1, 23 ), 'total' => 4443.52 } )\n\tend\n\n\tdef test_spec_oneline_docs\n\t\tdoc_ct = 0\n\t\tYAML::load_documents( <<EOY\n# The following is a sequence of three documents.\n# The first contains an empty mapping, the second\n# an empty sequence, and the last an empty string.\n--- {}\n--- [ ]\n--- ''\nEOY\n\t\t) { |doc|\n\t\t\tcase doc_ct\n\t\t\t\twhen 0\n\t\t\t\t\tassert_equal( doc, {} )\n\t\t\t\twhen 1\n\t\t\t\t\tassert_equal( doc, [] )\n\t\t\t\twhen 2\n\t\t\t\t\tassert_equal( doc, '' )\n\t\t\tend\n\t\t\tdoc_ct += 1\n\t\t}\n\t\tassert_equal( doc_ct, 3 )\n\tend\n\n\tdef test_spec_domain_prefix\n        customer_proc = proc { |type, val|\n            if Hash === val\n                scheme, domain, type = type.split( ':', 3 )\n                val['type'] = \"domain #{type}\"\n                val\n            else\n                raise ArgumentError, \"Not a Hash in domain.tld,2002/invoice: \" + val.inspect\n            end\n        }\n        YAML.add_domain_type( \"domain.tld,2002\", 'invoice', &customer_proc )\n        YAML.add_domain_type( \"domain.tld,2002\", 'customer', &customer_proc )\n\t\tassert_parse_only( { \"invoice\"=> { \"customers\"=> [ { \"given\"=>\"Chris\", \"type\"=>\"domain customer\", \"family\"=>\"Dumars\" } ], \"type\"=>\"domain invoice\" } }, <<EOY\n# 'http://domain.tld,2002/invoice' is some type family.\ninvoice: !domain.tld,2002/^invoice\n  # 'seq' is shorthand for 'http://yaml.org/seq'.\n  # This does not effect '^customer' below\n  # because it is does not specify a prefix.\n  customers: !seq\n    # '^customer' is shorthand for the full\n    # notation 'http://domain.tld,2002/customer'.\n    - !^customer\n      given : Chris\n      family : Dumars\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_throwaway\n\t\tassert_parse_only(\n\t\t\t{\"this\"=>\"contains three lines of text.\\nThe third one starts with a\\n# character. This isn't a comment.\\n\"}, <<EOY\n### These are four throwaway comment  ###\n\n### lines (the second line is empty). ###\nthis: |   # Comments may trail lines.\n    contains three lines of text.\n    The third one starts with a\n    # character. This isn't a comment.\n\n# These are three throwaway comment\n# lines (the first line is empty).\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_force_implicit\n\t\t# Force implicit\n\t\tassert_parse_only( \n\t\t\t{ 'integer' => 12, 'also int' => 12, 'string' => '12' }, <<EOY\ninteger: 12\nalso int: ! \"12\"\nstring: !str 12\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_private_types\n\t\tdoc_ct = 0\n\t\tYAML::parse_documents( <<EOY\n# Private types are per-document.\n---\npool: !!ball\n   number: 8\n   color: black\n---\nbearing: !!ball\n   material: steel\nEOY\n\t\t) { |doc|\n\t\t\tcase doc_ct\n\t\t\t\twhen 0\n\t\t\t\t\tassert_equal( doc['pool'].type_id, 'x-private:ball' )\n\t\t\t\t\tassert_equal( doc['pool'].transform.value, { 'number' => 8, 'color' => 'black' } )\n\t\t\t\twhen 1\n\t\t\t\t\tassert_equal( doc['bearing'].type_id, 'x-private:ball' ) \n\t\t\t\t\tassert_equal( doc['bearing'].transform.value, { 'material' => 'steel' } )\n\t\t\tend\n\t\t\tdoc_ct += 1\n\t\t}\n\t\tassert_equal( doc_ct, 2 )\n\tend\n\n\tdef test_spec_url_escaping\n\t\tYAML.add_domain_type( \"domain.tld,2002\", \"type0\" ) { |type, val|\n\t\t\t\"ONE: #{val}\"\n\t\t}\n\t\tYAML.add_domain_type( \"domain.tld,2002\", \"type%30\" ) { |type, val|\n\t\t\t\"TWO: #{val}\"\n\t\t}\n\t\tassert_parse_only(\n\t\t\t{ 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value' ] }, <<EOY\nsame:\n  - !domain.tld,2002/type\\\\x30 value\n  - !domain.tld,2002/type0 value\ndifferent: # As far as the YAML parser is concerned\n  - !domain.tld,2002/type%30 value\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_override_anchor\n\t\t# Override anchor\n\t\ta001 = \"The alias node below is a repeated use of this value.\\n\"\n\t\tassert_parse_only( \n\t\t\t{ 'anchor' => 'This scalar has an anchor.', 'override' => a001, 'alias' => a001 }, <<EOY\nanchor : &A001 This scalar has an anchor.\noverride : &A001 >\n The alias node below is a\n repeated use of this value.\nalias : *A001\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_explicit_families\n        YAML.add_domain_type( \"somewhere.com,2002\", 'type' ) { |type, val|\n            \"SOMEWHERE: #{val}\"\n        }\n\t\tassert_parse_only(\n\t\t\t{ 'not-date' => '2002-04-28', 'picture' => \"GIF89a\\f\\000\\f\\000\\204\\000\\000\\377\\377\\367\\365\\365\\356\\351\\351\\345fff\\000\\000\\000\\347\\347\\347^^^\\363\\363\\355\\216\\216\\216\\340\\340\\340\\237\\237\\237\\223\\223\\223\\247\\247\\247\\236\\236\\236i^\\020' \\202\\n\\001\\000;\", 'hmm' => \"SOMEWHERE: family above is short for\\nhttp://somewhere.com/type\\n\" }, <<EOY\nnot-date: !str 2002-04-28\npicture: !binary |\n R0lGODlhDAAMAIQAAP//9/X\n 17unp5WZmZgAAAOfn515eXv\n Pz7Y6OjuDg4J+fn5OTk6enp\n 56enmleECcgggoBADs=\n\nhmm: !somewhere.com,2002/type | \n family above is short for\n http://somewhere.com/type\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_application_family\n\t\t# Testing the clarkevans.com graphs\n\t\tYAML.add_domain_type( \"clarkevans.com,2002\", 'graph/shape' ) { |type, val|\n\t\t\tif Array === val\n\t\t\t\tval << \"Shape Container\"\n\t\t\t\tval\n\t\t\telse\n\t\t\t\traise ArgumentError, \"Invalid graph of type #{val.class}: \" + val.inspect\n\t\t\tend\n\t\t}\n\t\tone_shape_proc = Proc.new { |type, val|\n\t\t\tif Hash === val\n                type = type.split( /:/ )\n\t\t\t\tval['TYPE'] = \"Shape: #{type[2]}\"\n\t\t\t\tval\n\t\t\telse\n\t\t\t\traise ArgumentError, \"Invalid graph of type #{val.class}: \" + val.inspect\n\t\t\tend\n\t\t}\n\t\tYAML.add_domain_type( \"clarkevans.com,2002\", 'graph/circle', &one_shape_proc )\n\t\tYAML.add_domain_type( \"clarkevans.com,2002\", 'graph/line', &one_shape_proc )\n\t\tYAML.add_domain_type( \"clarkevans.com,2002\", 'graph/text', &one_shape_proc )\n\t\tassert_parse_only(\n\t\t\t[[{\"radius\"=>7, \"center\"=>{\"x\"=>73, \"y\"=>129}, \"TYPE\"=>\"Shape: graph/circle\"}, {\"finish\"=>{\"x\"=>89, \"y\"=>102}, \"TYPE\"=>\"Shape: graph/line\", \"start\"=>{\"x\"=>73, \"y\"=>129}}, {\"TYPE\"=>\"Shape: graph/text\", \"value\"=>\"Pretty vector drawing.\", \"start\"=>{\"x\"=>73, \"y\"=>129}, \"color\"=>16772795}, \"Shape Container\"]], <<EOY\n- !clarkevans.com,2002/graph/^shape\n  - !^circle\n    center: &ORIGIN {x: 73, y: 129}\n    radius: 7\n  - !^line # !clarkevans.com,2002/graph/line\n    start: *ORIGIN\n    finish: { x: 89, y: 102 }\n  - !^text\n    start: *ORIGIN\n    color: 0xFFEEBB\n    value: Pretty vector drawing.\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_float_explicit\n\t\tassert_parse_only(\n\t\t\t[ 10.0, 10.0, 10.0, 10.0 ], <<EOY\n# All entries in the sequence\n# have the same type and value.\n- 10.0\n- !float 10\n- !yaml.org,2002/^float '10'\n- !yaml.org,2002/float \"\\\\\n  1\\\\\n  0\"\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_builtin_seq\n\t\t# Assortment of sequences\n\t\tassert_parse_only(\n\t\t\t{ 'empty' => [], 'in-line' => [ 'one', 'two', 'three', 'four', 'five' ],\n\t\t\t  'nested' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],\n\t\t\t  \t\"A multi-line sequence entry\\n\", 'Sixth item in top sequence' ] }, <<EOY\nempty: []\nin-line: [ one, two, three # May span lines,\n         , four,           # indentation is\n           five ]          # mostly ignored.\nnested:\n - First item in top sequence\n -\n  - Subordinate sequence entry\n - >\n   A multi-line\n   sequence entry\n - Sixth item in top sequence\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_builtin_map\n\t\t# Assortment of mappings\n\t\tassert_parse_only( \n\t\t\t{ 'empty' => {}, 'in-line' => { 'one' => 1, 'two' => 2 },\n\t\t\t  'spanning' => { 'one' => 1, 'two' => 2 },\n\t\t\t  'nested' => { 'first' => 'First entry', 'second' =>\n\t\t\t  \t{ 'key' => 'Subordinate mapping' }, 'third' =>\n\t\t\t\t  [ 'Subordinate sequence', {}, 'Previous mapping is empty.',\n\t\t\t\t\t{ 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },\n\t\t\t\t\t'The previous entry is equal to the following one.',\n\t\t\t\t\t{ 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],\n\t\t\t\t  12.0 => 'This key is a float.', \"?\\n\" => 'This key had to be protected.',\n\t\t\t\t  \"\\a\" => 'This key had to be escaped.',\n\t\t\t\t  \"This is a multi-line folded key\\n\" => \"Whose value is also multi-line.\\n\",\n\t\t\t\t  [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }, <<EOY\n\nempty: {}\nin-line: { one: 1, two: 2 }\nspanning: { one: 1,\n   two: 2 }\nnested:\n first : First entry\n second:\n  key: Subordinate mapping\n third:\n  - Subordinate sequence\n  - { }\n  - Previous mapping is empty.\n  - A key: value pair in a sequence.\n    A second: key:value pair.\n  - The previous entry is equal to the following one.\n  -\n    A key: value pair in a sequence.\n    A second: key:value pair.\n !float 12 : This key is a float.\n ? >\n  ?\n : This key had to be protected.\n \"\\\\a\" : This key had to be escaped.\n ? >\n   This is a\n   multi-line\n   folded key\n : >\n   Whose value is\n   also multi-line.\n ?\n  - This key\n  - is a sequence\n :\n  - With a sequence value.\n# The following parses correctly,\n# but Ruby 1.6.* fails the comparison!\n# ?\n#  This: key\n#  is a: mapping\n# :\n#  with a: mapping value.\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_builtin_literal_blocks\n\t\t# Assortment of literal scalar blocks\n\t\tassert_parse_only(\n\t\t\t{\"both are equal to\"=>\"  This has no newline.\", \"is equal to\"=>\"The \\\\ ' \\\" characters may be\\nfreely used. Leading white\\n   space is significant.\\n\\nLine breaks are significant.\\nThus this value contains one\\nempty line and ends with a\\nsingle line break, but does\\nnot start with one.\\n\", \"also written as\"=>\"  This has no newline.\", \"indented and chomped\"=>\"  This has no newline.\", \"empty\"=>\"\", \"literal\"=>\"The \\\\ ' \\\" characters may be\\nfreely used. Leading white\\n   space is significant.\\n\\nLine breaks are significant.\\nThus this value contains one\\nempty line and ends with a\\nsingle line break, but does\\nnot start with one.\\n\"}, <<EOY\nempty: |\n\nliteral: |\n The \\\\ ' \" characters may be\n freely used. Leading white\n    space is significant.\n\n Line breaks are significant.\n Thus this value contains one\n empty line and ends with a\n single line break, but does\n not start with one.\n\nis equal to: \"The \\\\ ' \\\\\" characters may \\\\\n be\\\\nfreely used. Leading white\\\\n   space \\\\\n is significant.\\\\n\\\\nLine breaks are \\\\\n significant.\\\\nThus this value contains \\\\\n one\\\\nempty line and ends with a\\\\nsingle \\\\\n line break, but does\\\\nnot start with one.\\\\n\"\n\n# Comments may follow a nested\n# scalar value. They must be\n# less indented.\n\n# Modifiers may be combined in any order.\nindented and chomped: |2-\n    This has no newline.\n\nalso written as: |-2\n    This has no newline.\n\nboth are equal to: \"  This has no newline.\"\nEOY\n\t\t)\n\n\t\tstr1 = \"This has one newline.\\n\"\n\t\tstr2 = \"This has no newline.\"\n\t\tstr3 = \"This has two newlines.\\n\\n\"\n\t\tassert_parse_only( \n\t\t\t{ 'clipped' => str1, 'same as \"clipped\" above' => str1, \n\t\t\t  'stripped' => str2, 'same as \"stripped\" above' => str2, \n\t\t\t  'kept' => str3, 'same as \"kept\" above' => str3 }, <<EOY\nclipped: |\n    This has one newline.\n\nsame as \"clipped\" above: \"This has one newline.\\\\n\"\n\nstripped: |-\n    This has no newline.\n\nsame as \"stripped\" above: \"This has no newline.\"\n\nkept: |+\n    This has two newlines.\n\nsame as \"kept\" above: \"This has two newlines.\\\\n\\\\n\"\n\nEOY\n\t\t)\n\tend\n\t\n\tdef test_spec_span_single_quote\n\t\tassert_parse_only( {\"third\"=>\"a single quote ' must be escaped.\", \"second\"=>\"! : \\\\ etc. can be used freely.\", \"is same as\"=>\"this contains six spaces\\nand one line break\", \"empty\"=>\"\", \"span\"=>\"this contains six spaces\\nand one line break\"}, <<EOY\nempty: ''\nsecond: '! : \\\\ etc. can be used freely.'\nthird: 'a single quote '' must be escaped.'\nspan: 'this contains\n      six spaces\n      \n      and one\n      line break'\nis same as: \"this contains six spaces\\\\nand one line break\"\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_span_double_quote\n\t\tassert_parse_only( {\"is equal to\"=>\"this contains four  spaces\", \"third\"=>\"a \\\" or a \\\\ must be escaped.\", \"second\"=>\"! : etc. can be used freely.\", \"empty\"=>\"\", \"fourth\"=>\"this value ends with an LF.\\n\", \"span\"=>\"this contains four  spaces\"}, <<EOY\nempty: \"\"\nsecond: \"! : etc. can be used freely.\"\nthird: \"a \\\\\\\" or a \\\\\\\\ must be escaped.\"\nfourth: \"this value ends with an LF.\\\\n\"\nspan: \"this contains\n  four  \\\\\n      spaces\"\nis equal to: \"this contains four  spaces\"\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_builtin_time\n\t\t# Time\n\t\tassert_parse_only(\n\t\t\t{ \"space separated\" => mktime( 2001, 12, 14, 21, 59, 43, \".10\", \"-05:00\" ), \n\t\t\t  \"canonical\" => mktime( 2001, 12, 15, 2, 59, 43, \".10\" ), \n\t\t\t  \"date (noon UTC)\" => Date.new( 2002, 12, 14), \n\t\t\t  \"valid iso8601\" => mktime( 2001, 12, 14, 21, 59, 43, \".10\", \"-05:00\" ) }, <<EOY\ncanonical: 2001-12-15T02:59:43.1Z\nvalid iso8601: 2001-12-14t21:59:43.10-05:00\nspace separated: 2001-12-14 21:59:43.10 -05:00\ndate (noon UTC): 2002-12-14\nEOY\n\t\t)\n\tend\n\n\tdef test_spec_builtin_binary\n\t\tarrow_gif = \"GIF89a\\f\\000\\f\\000\\204\\000\\000\\377\\377\\367\\365\\365\\356\\351\\351\\345fff\\000\\000\\000\\347\\347\\347^^^\\363\\363\\355\\216\\216\\216\\340\\340\\340\\237\\237\\237\\223\\223\\223\\247\\247\\247\\236\\236\\236iiiccc\\243\\243\\243\\204\\204\\204\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371\\377\\376\\371!\\376\\016Made with GIMP\\000,\\000\\000\\000\\000\\f\\000\\f\\000\\000\\005,  \\216\\2010\\236\\343@\\024\\350i\\020\\304\\321\\212\\010\\034\\317\\200M$z\\357\\3770\\205p\\270\\2601f\\r\\e\\316\\001\\303\\001\\036\\020' \\202\\n\\001\\000;\"\n\t\tassert_parse_only(\n\t\t\t{ 'canonical' => arrow_gif, 'base64' => arrow_gif, \n\t\t\t  'description' => \"The binary value above is a tiny arrow encoded as a gif image.\\n\" }, <<EOY\ncanonical: !binary \"\\\\\n R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf\\\\\n n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW\\\\\n NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++\\\\\n f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg\\\\\n d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN\\\\\n AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww\\\\\n EeECcgggoBADs=\"\nbase64: !binary |\n R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOf\n n515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaW\n NjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++\n f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUg\n d2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuN\n AFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84Bww\n EeECcgggoBADs=\ndescription: >\n The binary value above is a tiny arrow\n encoded as a gif image.\nEOY\n\t\t)\n\tend\n\tdef test_ruby_regexp\n\t\t# Test Ruby regular expressions\n\t\tassert_to_yaml( \n\t\t\t{ 'simple' => /a.b/, 'complex' => %r'\\A\"((?:[^\"]|\\\")+)\"',\n\t\t\t  'case-insensitive' => /George McFly/i }, <<EOY\ncase-insensitive: !ruby/regexp \"/George McFly/i\"\ncomplex: !ruby/regexp \"/\\\\\\\\A\\\\\"((?:[^\\\\\"]|\\\\\\\\\\\\\")+)\\\\\"/\"\nsimple: !ruby/regexp \"/a.b/\"\nEOY\n\t\t)\n\tend\n\n    #\n    # Test of Ranges\n    #\n    def test_ranges\n\n        # Simple numeric\n        assert_to_yaml( 1..3, <<EOY )\n--- !ruby/range 1..3\nEOY\n\n        # Simple alphabetic\n        assert_to_yaml( 'a'..'z', <<EOY )\n--- !ruby/range a..z\nEOY\n\n        # Float\n        assert_to_yaml( 10.5...30.3, <<EOY )\n--- !ruby/range 10.5...30.3\nEOY\n\n    end\n\n\tdef test_ruby_struct\n\t\t# Ruby structures\n\t\tbook_struct = Struct::new( \"BookStruct\", :author, :title, :year, :isbn )\n\t\tassert_to_yaml(\n\t\t\t[ book_struct.new( \"Yukihiro Matsumoto\", \"Ruby in a Nutshell\", 2002, \"0-596-00214-9\" ),\n\t\t\t  book_struct.new( [ 'Dave Thomas', 'Andy Hunt' ], \"The Pickaxe\", 2002, \n\t\t\t\tbook_struct.new( \"This should be the ISBN\", \"but I have another struct here\", 2002, \"None\" ) \n\t\t\t  ) ], <<EOY\n- !ruby/struct:BookStruct\n  author: Yukihiro Matsumoto\n  title: Ruby in a Nutshell\n  year: 2002\n  isbn: 0-596-00214-9\n- !ruby/struct:BookStruct\n  author:\n    - Dave Thomas\n    - Andy Hunt\n  title: The Pickaxe\n  year: 2002\n  isbn: !ruby/struct:BookStruct\n    author: This should be the ISBN\n    title: but I have another struct here\n    year: 2002\n    isbn: None\nEOY\n\t\t)\n\n        assert_to_yaml( YAML_Tests::StructTest.new( 123 ), <<EOY )\n--- !ruby/struct:YAML_Tests::StructTest\nc: 123\nEOY\n\n\tend\n\n\tdef test_emitting_indicators\n\t\tassert_to_yaml( \"Hi, from Object 1. You passed: please, pretty please\", <<EOY\n--- \"Hi, from Object 1. You passed: please, pretty please\"\nEOY\n\t\t)\n\tend\n\n\t#\n\t# Test the YAML::Stream class -- INACTIVE at the moment\n\t#\n\tdef test_document\n\t\ty = YAML::Stream.new( :Indent => 2, :UseVersion => 0 )\n\t\ty.add( \n\t\t\t{ 'hi' => 'hello', 'map' =>\n\t\t\t\t{ 'good' => 'two' },\n\t\t\t  'time' => Time.now,\n\t\t\t  'try' => /^po(.*)$/,\n\t\t\t  'bye' => 'goodbye'\n\t\t\t}\n\t\t)\n\t\ty.add( { 'po' => 'nil', 'oper' => 90 } )\n\t\ty.add( { 'hi' => 'wow!', 'bye' => 'wow!' } )\n\t\ty.add( { [ 'Red Socks', 'Boston' ] => [ 'One', 'Two', 'Three' ] } )\n\t\ty.add( [ true, false, false ] )\n\tend\n\n    #\n    # Test YPath choices parsing\n    #\n    def test_ypath_parsing\n        assert_path_segments( \"/*/((one|three)/name|place)|//place\",\n          [ [\"*\", \"one\", \"name\"],\n            [\"*\", \"three\", \"name\"],\n            [\"*\", \"place\"],\n            [\"/\", \"place\"] ]\n        )\n    end\n\n    #\n    # Tests from Tanaka Akira on [ruby-core]\n    #\n    def test_akira\n\n        # Commas in plain scalars [ruby-core:1066]\n        assert_to_yaml(\n            {\"A\"=>\"A,\",\"B\"=>\"B\"}, <<EOY\nA: \"A,\"\nB: B\nEOY\n        )\n\n        # Double-quoted keys [ruby-core:1069]\n        assert_to_yaml(\n            {\"1\"=>2, \"2\"=>3}, <<EOY\n'1': 2\n\"2\": 3\nEOY\n        )\n\n        # Anchored mapping [ruby-core:1071]\n        assert_to_yaml(\n            [{\"a\"=>\"b\"}] * 2, <<EOY\n- &id001\n  a: b\n- *id001\nEOY\n        )\n\n        # Stress test [ruby-core:1071]\n        # a = []; 1000.times { a << {\"a\"=>\"b\", \"c\"=>\"d\"} }\n        # YAML::load( a.to_yaml )\n\n    end\n\n    #\n    # Test Time.now cycle\n    #\n    def test_time_now_cycle\n        #\n        # From Minero Aoki [ruby-core:2305]\n        #\n        require 'yaml'\n        t = Time.now\n        5.times do\n            assert_cycle(t)\n        end\n    end\n\n    #\n    # Test Range cycle\n    #\n    def test_range_cycle\n      #\n      # From Minero Aoki [ruby-core:02306]\n      #\n      assert_cycle(\"a\"..\"z\")\n\n      #\n      # From Nobu Nakada [ruby-core:02311]\n      #\n      assert_cycle(0..1)\n      assert_cycle(1.0e20 .. 2.0e20)\n      assert_cycle(\"0\"..\"1\")\n      assert_cycle(\"..\"...\"...\")\n      assert_cycle(\".rb\"..\".pl\")\n      assert_cycle(\".rb\"...\".pl\")\n      assert_cycle('\"'...\".\")\n      assert_cycle(\"'\"...\".\")\n    end\n\n    #\n    # Circular references\n    #\n    def test_circular_references\n        a = []; a[0] = a; a[1] = a\n        inspect_str = \"[[...], [...]]\"\n        assert_equal( inspect_str, YAML::load( a.to_yaml ).inspect )\n    end\n\n    #\n    # Test Symbol cycle\n    #\n    def test_symbol_cycle\n      #\n      # From Aaron Schrab [ruby-Bugs:2535]\n      #\n      assert_cycle(:\"^foo\")\n    end\n\n    #\n    # Test Numeric cycle\n    #\n    class NumericTest < Numeric\n      def initialize(value)\n        @value = value\n      end\n      def ==(other)\n        @value == other.instance_eval{ @value }\n      end\n    end\n    def test_numeric_cycle\n      assert_cycle(1) # Fixnum\n      assert_cycle(111111111111111111111111111111111) # Bignum\n      assert_cycle(NumericTest.new(3)) # Subclass of Numeric\n    end\n\n    #\n    # Test empty map/seq in map cycle\n    #\n    def test_empty_map_key\n      #\n      # empty seq as key\n      #\n      o = YAML.load({[]=>\"\"}.to_yaml)\n      assert_equal(Hash, o.class)\n      assert_equal([[]], o.keys)\n\n      #\n      # empty map as key\n      #\n      o = YAML.load({{}=>\"\"}.to_yaml)\n      assert_equal(Hash, o.class)\n      assert_equal([{}], o.keys)\n    end\n\n    #\n    # contributed by riley lynch [ruby-Bugs-8548]\n    #\n    def test_object_id_collision\n      omap = YAML::Omap.new\n      1000.times { |i| omap[\"key_#{i}\"] = { \"value\" => i } }\n      raise \"id collision in ordered map\" if omap.to_yaml =~ /id\\d+/\n    end\nend\n\nif $0 == __FILE__\n  suite = Test::Unit::TestSuite.new('YAML')\n  ObjectSpace.each_object(Class) do |klass|\n    suite << klass.suite if (Test::Unit::TestCase > klass)\n  end\n  require 'test/unit/ui/console/testrunner'\n  Test::Unit::UI::Console::TestRunner.run(suite).passed?\nend\n"
  },
  {
    "path": "test/yaml/test_yamlstore.rb",
    "content": "require 'test/unit'\nrequire 'yaml/store'\n\nclass YAMLStoreTest < Test::Unit::TestCase\n  def setup\n    @yamlstore_file = \"yamlstore.tmp.#{Process.pid}\"\n    @yamlstore = YAML::Store.new(@yamlstore_file)\n  end\n\n  def teardown\n    File.unlink(@yamlstore_file) rescue nil\n  end\n\n  def test_opening_new_file_in_readonly_mode_should_result_in_empty_values\n    @yamlstore.transaction(true) do\n      assert_nil @yamlstore[:foo]\n      assert_nil @yamlstore[:bar]\n    end\n  end\n  \n  def test_opening_new_file_in_readwrite_mode_should_result_in_empty_values\n    @yamlstore.transaction do\n      assert_nil @yamlstore[:foo]\n      assert_nil @yamlstore[:bar]\n    end\n  end\n  \n  def test_data_should_be_loaded_correctly_when_in_readonly_mode\n    @yamlstore.transaction do\n      @yamlstore[:foo] = \"bar\"\n    end\n    @yamlstore.transaction(true) do\n      assert_equal \"bar\", @yamlstore[:foo]\n    end\n  end\n  \n  def test_data_should_be_loaded_correctly_when_in_readwrite_mode\n    @yamlstore.transaction do\n      @yamlstore[:foo] = \"bar\"\n    end\n    @yamlstore.transaction do\n      assert_equal \"bar\", @yamlstore[:foo]\n    end\n  end\n  \n  def test_changes_after_commit_are_discarded\n    @yamlstore.transaction do\n      @yamlstore[:foo] = \"bar\"\n      @yamlstore.commit\n      @yamlstore[:foo] = \"baz\"\n    end\n    @yamlstore.transaction(true) do\n      assert_equal \"bar\", @yamlstore[:foo]\n    end\n  end\n  \n  def test_changes_are_not_written_on_abort\n    @yamlstore.transaction do\n      @yamlstore[:foo] = \"bar\"\n      @yamlstore.abort\n    end\n    @yamlstore.transaction(true) do\n      assert_nil @yamlstore[:foo]\n    end\n  end\n  \n  def test_writing_inside_readonly_transaction_raises_error\n    assert_raise(PStore::Error) do\n      @yamlstore.transaction(true) do\n        @yamlstore[:foo] = \"bar\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/zlib/test_zlib.rb",
    "content": "require 'test/unit/testsuite'\nrequire 'test/unit/testcase'\nrequire 'stringio'\n\nbegin\n  require 'zlib'\nrescue LoadError\nend\n\nif defined? Zlib\n  class TestZlibGzipReader < Test::Unit::TestCase\n    D0 = \"\\037\\213\\010\\000S`\\017A\\000\\003\\003\\000\\000\\000\\000\\000\\000\\000\\000\\000\"\n    def test_read0\n      assert_equal(\"\", Zlib::GzipReader.new(StringIO.new(D0)).read(0))\n    end\n\n    def test_ungetc # [ruby-dev:24060]\n      s = \"\"\n      w = Zlib::GzipWriter.new(StringIO.new(s))\n      w << (1...1000).to_a.inspect\n      w.close\n      r = Zlib::GzipReader.new(StringIO.new(s))\n      r.read(100)\n      r.ungetc ?a\n      assert_nothing_raised {\n        r.read(100)\n        r.read\n        r.close\n      }\n    end\n\n    def test_ungetc_paragraph # [ruby-dev:24065]\n      s = \"\"\n      w = Zlib::GzipWriter.new(StringIO.new(s))\n      w << \"abc\"\n      w.close\n      r = Zlib::GzipReader.new(StringIO.new(s))\n      r.ungetc ?\\n\n      assert_equal(\"abc\", r.gets(\"\"))\n      assert_nothing_raised {\n        r.read\n        r.close\n      }\n    end\n  end\n\n  class TestZlibGzipWriter < Test::Unit::TestCase\n    def test_invalid_new\n      # [ruby-dev:23228]\n      assert_raise(NoMethodError) { Zlib::GzipWriter.new(nil).close }\n      # [ruby-dev:23344]\n      assert_raise(NoMethodError) { Zlib::GzipWriter.new(true).close }\n      assert_raise(NoMethodError) { Zlib::GzipWriter.new(0).close }\n      assert_raise(NoMethodError) { Zlib::GzipWriter.new(:hoge).close }\n    end\n  end\nend\n"
  },
  {
    "path": "time.c",
    "content": "/**********************************************************************\n\n  time.c -\n\n  $Author$\n  $Date$\n  created at: Tue Dec 28 14:31:59 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include <sys/types.h>\n#include <time.h>\n#include <errno.h>\n\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n\n#include <math.h>\n\nVALUE rb_cTime;\n\nstruct time_object {\n    struct timeval tv;\n    struct tm tm;\n    int gmt;\n    int tm_got;\n};\n\n#define GetTimeval(obj, tobj) \\\n    Data_Get_Struct(obj, struct time_object, tobj)\n\nstatic void time_free _((void *));\nstatic VALUE time_utc_offset _((VALUE));\n\nstatic void\ntime_free(tobj)\n    void *tobj;\n{\n    if (tobj) free(tobj);\n}\n\nstatic VALUE time_s_alloc _((VALUE));\nstatic VALUE\ntime_s_alloc(klass)\n    VALUE klass;\n{\n    VALUE obj;\n    struct time_object *tobj;\n\n    obj = Data_Make_Struct(klass, struct time_object, 0, time_free, tobj);\n    tobj->tm_got=0;\n    tobj->tv.tv_sec = 0;\n    tobj->tv.tv_usec = 0;\n\n    return obj;\n}\n\nstatic void\ntime_modify(time)\n    VALUE time;\n{\n    rb_check_frozen(time);\n    if (!OBJ_TAINTED(time) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify Time\");\n}\n\n/*\n *  Document-method: now\n *\n *  Synonym for <code>Time.new</code>. Returns a +Time+ object\n *  initialized tot he current system time.\n *\n *  call-seq:\n *     Time.new -> time\n *  \n *  Returns a <code>Time</code> object initialized to the current system\n *  time. <b>Note:</b> The object created will be created using the\n *  resolution available on your system clock, and so may include\n *  fractional seconds.\n *     \n *     a = Time.new      #=> Wed Apr 09 08:56:03 CDT 2003\n *     b = Time.new      #=> Wed Apr 09 08:56:03 CDT 2003\n *     a == b            #=> false\n *     \"%.6f\" % a.to_f   #=> \"1049896563.230740\"\n *     \"%.6f\" % b.to_f   #=> \"1049896563.231466\"\n *     \n */\n\nstatic VALUE\ntime_init(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    time_modify(time);\n    GetTimeval(time, tobj);\n    tobj->tm_got=0;\n    tobj->tv.tv_sec = 0;\n    tobj->tv.tv_usec = 0;\n    if (gettimeofday(&tobj->tv, 0) < 0) {\n\trb_sys_fail(\"gettimeofday\");\n    }\n\n    return time;\n}\n\n#define NDIV(x,y) (-(-((x)+1)/(y))-1)\n#define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)\n\nstatic void\ntime_overflow_p(secp, usecp)\n    time_t *secp, *usecp;\n{\n    time_t tmp, sec = *secp, usec = *usecp;\n\n    if (usec >= 1000000) {\t/* usec positive overflow */\n\ttmp = sec + usec / 1000000;\n\tusec %= 1000000;\n\tif (sec > 0 && tmp < 0) {\n\t    rb_raise(rb_eRangeError, \"out of Time range\");\n\t}\n\tsec = tmp;\n    }\n    if (usec < 0) {\t\t/* usec negative overflow */\n\ttmp = sec + NDIV(usec,1000000); /* negative div */\n\tusec = NMOD(usec,1000000);      /* negative mod */\n\tif (sec < 0 && tmp > 0) {\n\t    rb_raise(rb_eRangeError, \"out of Time range\");\n\t}\n\tsec = tmp;\n    }\n#ifndef NEGATIVE_TIME_T\n    if (sec < 0 || (sec == 0 && usec < 0))\n\trb_raise(rb_eArgError, \"time must be positive\");\n#endif\n    *secp = sec;\n    *usecp = usec;\n}\n\nstatic VALUE time_new_internal _((VALUE, time_t, time_t));\nstatic VALUE\ntime_new_internal(klass, sec, usec)\n    VALUE klass;\n    time_t sec, usec;\n{\n    VALUE time = time_s_alloc(klass);\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    time_overflow_p(&sec, &usec);\n    tobj->tv.tv_sec = sec;\n    tobj->tv.tv_usec = usec;\n\n    return time;\n}\n\nVALUE\nrb_time_new(sec, usec)\n    time_t sec, usec;\n{\n    return time_new_internal(rb_cTime, sec, usec);\n}\n\nstatic struct timeval\ntime_timeval(time, interval)\n    VALUE time;\n    int interval;\n{\n    struct timeval t;\n    const char *tstr = interval ? \"time interval\" : \"time\";\n\n#ifndef NEGATIVE_TIME_T\n    interval = 1;\n#endif\n\n    switch (TYPE(time)) {\n      case T_FIXNUM:\n\tt.tv_sec = FIX2LONG(time);\n\tif (interval && t.tv_sec < 0)\n\t    rb_raise(rb_eArgError, \"%s must be positive\", tstr);\n\tt.tv_usec = 0;\n\tbreak;\n\n      case T_FLOAT:\n\tif (interval && RFLOAT(time)->value < 0.0)\n\t    rb_raise(rb_eArgError, \"%s must be positive\", tstr);\n\telse {\n\t    double f, d;\n\n\t    d = modf(RFLOAT(time)->value, &f);\n\t    if (d >= 0) {\n\t\tt.tv_usec = (int)(d*1e6+0.5);\n\t    }\n\t    else if ((t.tv_usec = (int)(-d*1e6+0.5)) > 0) {\n\t\tt.tv_usec = 1000000 - t.tv_usec;\n\t\tf -= 1;\n\t    }\n\t    t.tv_sec = (time_t)f;\n\t    if (f != t.tv_sec) {\n\t\trb_raise(rb_eRangeError, \"%f out of Time range\", RFLOAT(time)->value);\n\t    }\n\t}\n\tbreak;\n\n      case T_BIGNUM:\n\tt.tv_sec = NUM2LONG(time);\n\tif (interval && t.tv_sec < 0)\n\t    rb_raise(rb_eArgError, \"%s must be positive\", tstr);\n\tt.tv_usec = 0;\n\tbreak;\n\n      default:\n\trb_raise(rb_eTypeError, \"can't convert %s into %s\",\n\t\t rb_obj_classname(time), tstr);\n\tbreak;\n    }\n    return t;\n}\n\nstruct timeval\nrb_time_interval(time)\n    VALUE time;\n{\n    return time_timeval(time, Qtrue);\n}\n\nstruct timeval\nrb_time_timeval(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    struct timeval t;\n\n    if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {\n\tGetTimeval(time, tobj);\n\tt = tobj->tv;\n\treturn t;\n    }\n    return time_timeval(time, Qfalse);\n}\n\n/*\n *  call-seq:\n *     Time.at( aTime ) => time\n *     Time.at( seconds [, microseconds] ) => time\n *  \n *  Creates a new time object with the value given by <i>aTime</i>, or\n *  the given number of <i>seconds</i> (and optional\n *  <i>microseconds</i>) from epoch. A non-portable feature allows the\n *  offset to be negative on some systems.\n *     \n *     Time.at(0)            #=> Wed Dec 31 18:00:00 CST 1969\n *     Time.at(946702800)    #=> Fri Dec 31 23:00:00 CST 1999\n *     Time.at(-284061600)   #=> Sat Dec 31 00:00:00 CST 1960\n */\n\nstatic VALUE\ntime_s_at(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    struct timeval tv;\n    VALUE time, t;\n\n    if (rb_scan_args(argc, argv, \"11\", &time, &t) == 2) {\n\ttv.tv_sec = NUM2LONG(time);\n\ttv.tv_usec = NUM2LONG(t);\n    }\n    else {\n\ttv = rb_time_timeval(time);\n    }\n    t = time_new_internal(klass, tv.tv_sec, tv.tv_usec);\n    if (TYPE(time) == T_DATA && RDATA(time)->dfree == time_free) {\n\tstruct time_object *tobj, *tobj2;\n\n\tGetTimeval(time, tobj);\n\tGetTimeval(t, tobj2);\n\ttobj2->gmt = tobj->gmt;\n    }\n    return t;\n}\n\nstatic const char months[][4] = {\n    \"jan\", \"feb\", \"mar\", \"apr\", \"may\", \"jun\",\n    \"jul\", \"aug\", \"sep\", \"oct\", \"nov\", \"dec\",\n};\n\nstatic long\nobj2long(obj)\n    VALUE obj;\n{\n    if (TYPE(obj) == T_STRING) {\n\tobj = rb_str_to_inum(obj, 10, Qfalse);\n    }\n\n    return NUM2LONG(obj);\n}\n\nstatic void\ntime_arg(argc, argv, tm, usec)\n    int argc;\n    VALUE *argv;\n    struct tm *tm;\n    time_t *usec;\n{\n    VALUE v[8];\n    int i;\n    long year;\n\n    MEMZERO(tm, struct tm, 1);\n    *usec = 0;\n    if (argc == 10) {\n\tv[0] = argv[5];\n\tv[1] = argv[4];\n\tv[2] = argv[3];\n\tv[3] = argv[2];\n\tv[4] = argv[1];\n\tv[5] = argv[0];\n\tv[6] = Qnil;\n\ttm->tm_isdst = RTEST(argv[8]) ? 1 : 0;\n    }\n    else {\n\trb_scan_args(argc, argv, \"17\", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7]);\n\t/* v[6] may be usec or zone (parsedate) */\n\t/* v[7] is wday (parsedate; ignored) */\n\ttm->tm_wday = -1;\n\ttm->tm_isdst = -1;\n    }\n\n    year = obj2long(v[0]);\n\n    if (0 <= year && year < 39) {\n\tyear += 100;\n\trb_warning(\"2 digits year is used\");\n    }\n    else if (69 <= year && year < 139) {\n\trb_warning(\"2 or 3 digits year is used\");\n    }\n    else {\n\tyear -= 1900;\n    }\n\n    tm->tm_year = year;\n\n    if (NIL_P(v[1])) {\n\ttm->tm_mon = 0;\n    }\n    else {\n\tVALUE s = rb_check_string_type(v[1]);\n\tif (!NIL_P(s)) {\n\t    tm->tm_mon = -1;\n\t    for (i=0; i<12; i++) {\n\t\tif (RSTRING(s)->len == 3 &&\n\t\t    strcasecmp(months[i], RSTRING(s)->ptr) == 0) {\n\t\t    tm->tm_mon = i;\n\t\t    break;\n\t\t}\n\t    }\n\t    if (tm->tm_mon == -1) {\n\t\tchar c = RSTRING(s)->ptr[0];\n\n\t\tif ('0' <= c && c <= '9') {\n\t\t    tm->tm_mon = obj2long(s)-1;\n\t\t}\n\t    }\n\t}\n\telse {\n\t    tm->tm_mon = obj2long(v[1])-1;\n\t}\n    }\n    if (NIL_P(v[2])) {\n\ttm->tm_mday = 1;\n    }\n    else {\n\ttm->tm_mday = obj2long(v[2]);\n    }\n    tm->tm_hour = NIL_P(v[3])?0:obj2long(v[3]);\n    tm->tm_min  = NIL_P(v[4])?0:obj2long(v[4]);\n    tm->tm_sec  = NIL_P(v[5])?0:obj2long(v[5]);\n    if (!NIL_P(v[6])) {\n\tif (argc == 8) {\n\t    /* v[6] is timezone, but ignored */\n\t}\n\telse if (argc == 7) {\n\t    *usec = obj2long(v[6]);\n\t}\n    }\n\n    /* value validation */\n    if (\n           tm->tm_year != year ||\n#ifndef NEGATIVE_TIME_T\n           tm->tm_year < 69 ||\n#endif\n\t   tm->tm_mon  < 0 || tm->tm_mon  > 11\n\t|| tm->tm_mday < 1 || tm->tm_mday > 31\n\t|| tm->tm_hour < 0 || tm->tm_hour > 23\n\t|| tm->tm_min  < 0 || tm->tm_min  > 59\n\t|| tm->tm_sec  < 0 || tm->tm_sec  > 60)\n\trb_raise(rb_eArgError, \"argument out of range\");\n}\n\nstatic VALUE time_gmtime _((VALUE));\nstatic VALUE time_localtime _((VALUE));\nstatic VALUE time_get_tm _((VALUE, int));\n\nstatic int\nleap_year_p(y)\n    long y;\n{\n  return ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0);\n}\n\n#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))\n\nstatic time_t\ntimegm_noleapsecond(tm)\n    struct tm *tm;\n{\n    static int common_year_yday_offset[] = {\n        -1,\n        -1 + 31,\n        -1 + 31 + 28,\n        -1 + 31 + 28 + 31,\n        -1 + 31 + 28 + 31 + 30,\n        -1 + 31 + 28 + 31 + 30 + 31,\n        -1 + 31 + 28 + 31 + 30 + 31 + 30,\n        -1 + 31 + 28 + 31 + 30 + 31 + 30 + 31,\n        -1 + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,\n        -1 + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\n        -1 + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\n        -1 + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30\n          /* 1    2    3    4    5    6    7    8    9    10   11 */\n    };\n    static int leap_year_yday_offset[] = {\n        -1,\n        -1 + 31,\n        -1 + 31 + 29,\n        -1 + 31 + 29 + 31,\n        -1 + 31 + 29 + 31 + 30,\n        -1 + 31 + 29 + 31 + 30 + 31,\n        -1 + 31 + 29 + 31 + 30 + 31 + 30,\n        -1 + 31 + 29 + 31 + 30 + 31 + 30 + 31,\n        -1 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,\n        -1 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\n        -1 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\n        -1 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30\n          /* 1    2    3    4    5    6    7    8    9    10   11 */\n    };\n\n    long tm_year = tm->tm_year;\n    int tm_yday = tm->tm_mday;\n    if (leap_year_p(tm_year + 1900))\n        tm_yday += leap_year_yday_offset[tm->tm_mon];\n    else\n        tm_yday += common_year_yday_offset[tm->tm_mon];\n\n    /*\n     *  `Seconds Since the Epoch' in SUSv3:\n     *  tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +\n     *  (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -\n     *  ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400\n     */\n    return tm->tm_sec + tm->tm_min*60 + tm->tm_hour*3600 +\n           (time_t)(tm_yday +\n                    (tm_year-70)*365 +\n                    DIV(tm_year-69,4) -\n                    DIV(tm_year-1,100) +\n                    DIV(tm_year+299,400))*86400;\n}\n\nstatic int\ntmcmp(a, b)\n    struct tm *a;\n    struct tm *b;\n{\n    if (a->tm_year != b->tm_year)\n        return a->tm_year < b->tm_year ? -1 : 1;\n    else if (a->tm_mon != b->tm_mon)\n        return a->tm_mon < b->tm_mon ? -1 : 1;\n    else if (a->tm_mday != b->tm_mday)\n        return a->tm_mday < b->tm_mday ? -1 : 1;\n    else if (a->tm_hour != b->tm_hour)\n        return a->tm_hour < b->tm_hour ? -1 : 1;\n    else if (a->tm_min != b->tm_min)\n        return a->tm_min < b->tm_min ? -1 : 1;\n    else if (a->tm_sec != b->tm_sec)\n        return a->tm_sec < b->tm_sec ? -1 : 1;\n    else\n        return 0;\n}\n\n#if SIZEOF_TIME_T == SIZEOF_LONG\ntypedef unsigned long unsigned_time_t;\n#elif SIZEOF_TIME_T == SIZEOF_INT\ntypedef unsigned int unsigned_time_t;\n#elif SIZEOF_TIME_T == SIZEOF_LONG_LONG\ntypedef unsigned LONG_LONG unsigned_time_t;\n#else\n# error cannot find integer type which size is same as time_t.\n#endif\n\nstatic time_t\nsearch_time_t(tptr, utc_p)\n    struct tm *tptr;\n    int utc_p;\n{\n    time_t guess, guess_lo, guess_hi;\n    struct tm *tm, tm_lo, tm_hi;\n    int d, have_guess;\n    int find_dst;\n\n    find_dst = 0 < tptr->tm_isdst;\n\n#ifdef NEGATIVE_TIME_T\n    guess_lo = (time_t)~((unsigned_time_t)~(time_t)0 >> 1);\n#else\n    guess_lo = 0;\n#endif\n    guess_hi = ((time_t)-1) < ((time_t)0) ?\n\t       (time_t)((unsigned_time_t)~(time_t)0 >> 1) :\n\t       ~(time_t)0;\n\n    guess = timegm_noleapsecond(tptr);\n    tm = (utc_p ? gmtime : localtime)(&guess);\n    if (tm) {\n        d = tmcmp(tptr, tm);\n        if (d == 0) return guess;\n        if (d < 0) {\n            guess_hi = guess;\n            guess -= 24 * 60 * 60;\n        }\n        else {\n            guess_lo = guess;\n            guess += 24 * 60 * 60;\n        }\n        if (guess_lo < guess && guess < guess_hi &&\n            (tm = (utc_p ? gmtime : localtime)(&guess)) != NULL) {\n            d = tmcmp(tptr, tm);\n            if (d == 0) return guess;\n            if (d < 0)\n                guess_hi = guess;\n            else\n                guess_lo = guess;\n        }\n    }\n\n    tm = (utc_p ? gmtime : localtime)(&guess_lo);\n    if (!tm) goto error;\n    d = tmcmp(tptr, tm);\n    if (d < 0) goto out_of_range;\n    if (d == 0) return guess_lo;\n    tm_lo = *tm;\n\n    tm = (utc_p ? gmtime : localtime)(&guess_hi);\n    if (!tm) goto error;\n    d = tmcmp(tptr, tm);\n    if (d > 0) goto out_of_range;\n    if (d == 0) return guess_hi;\n    tm_hi = *tm;\n\n    have_guess = 0;\n\n    while (guess_lo + 1 < guess_hi) {\n      /* there is a gap between guess_lo and guess_hi. */\n      unsigned long range = 0;\n      if (!have_guess) {\n\tint a, b;\n\t/*\n\t  Try precious guess by a linear interpolation at first.\n\t  `a' and `b' is a coefficient of guess_lo and guess_hi as:\n\n\t    guess = (guess_lo * a + guess_hi * b) / (a + b)\n\n\t  However this causes overflow in most cases, following assignment\n\t  is used instead:\n\n\t    guess = guess_lo / d * a + (guess_lo % d) * a / d\n\t\t  + guess_hi / d * b + (guess_hi % d) * b / d\n\t      where d = a + b\n\n\t  To avoid overflow in this assignment, `d' is restricted to less than\n\t  sqrt(2**31).  By this restriction and other reasons, the guess is\n\t  not accurate and some error is expected.  `range' approximates \n\t  the maximum error.\n\n\t  When these parameters are not suitable, i.e. guess is not within\n\t  guess_lo and guess_hi, simple guess by binary search is used.\n\t*/\n\trange = 366 * 24 * 60 * 60;\n\ta = (tm_hi.tm_year - tptr->tm_year);\n\tb = (tptr->tm_year - tm_lo.tm_year);\n\t/* 46000 is selected as `some big number less than sqrt(2**31)'. */\n\tif (a + b <= 46000 / 12) {\n\t  range = 31 * 24 * 60 * 60;\n\t  a *= 12;\n\t  b *= 12;\n\t  a += tm_hi.tm_mon - tptr->tm_mon;\n\t  b += tptr->tm_mon - tm_lo.tm_mon;\n\t  if (a + b <= 46000 / 31) {\n\t    range = 24 * 60 * 60;\n\t    a *= 31;\n\t    b *= 31;\n\t    a += tm_hi.tm_mday - tptr->tm_mday;\n\t    b += tptr->tm_mday - tm_lo.tm_mday;\n\t    if (a + b <= 46000 / 24) {\n\t      range = 60 * 60;\n\t      a *= 24;\n\t      b *= 24;\n\t      a += tm_hi.tm_hour - tptr->tm_hour;\n\t      b += tptr->tm_hour - tm_lo.tm_hour;\n\t      if (a + b <= 46000 / 60) {\n\t\trange = 60;\n\t\ta *= 60;\n\t\tb *= 60;\n\t\ta += tm_hi.tm_min - tptr->tm_min;\n\t\tb += tptr->tm_min - tm_lo.tm_min;\n\t\tif (a + b <= 46000 / 60) {\n\t\t  range = 1;\n\t\t  a *= 60;\n\t\t  b *= 60;\n\t\t  a += tm_hi.tm_sec - tptr->tm_sec;\n\t\t  b += tptr->tm_sec - tm_lo.tm_sec;\n\t\t}\n\t      }\n\t    }\n\t  }\n\t}\n\tif (a <= 0) a = 1;\n\tif (b <= 0) b = 1;\n\td = a + b;\n\t/*\n\t  Although `/' and `%' may produce unexpected result with negative\n\t  argument, it doesn't cause serious problem because there is a\n\t  fail safe.\n\t*/\n\tguess = guess_lo / d * a + (guess_lo % d) * a / d\n\t      + guess_hi / d * b + (guess_hi % d) * b / d;\n\thave_guess = 1;\n      }\n\n      if (guess <= guess_lo || guess_hi <= guess) {\n\t/* Precious guess is invalid. try binary search. */ \n\tguess = guess_lo / 2 + guess_hi / 2;\n\tif (guess <= guess_lo)\n\t  guess = guess_lo + 1;\n\telse if (guess >= guess_hi)\n\t  guess = guess_hi - 1;\n\trange = 0;\n      }\n\n      tm = (utc_p ? gmtime : localtime)(&guess);\n      if (!tm) goto error;\n      have_guess = 0;\n\n      d = tmcmp(tptr, tm);\n      if (d < 0) {\n        guess_hi = guess;\n\ttm_hi = *tm;\n\tif (range) {\n\t  guess = guess - range;\n\t  range = 0;\n\t  if (guess_lo < guess && guess < guess_hi)\n\t    have_guess = 1;\n\t}\n      }\n      else if (d > 0) {\n        guess_lo = guess;\n\ttm_lo = *tm;\n\tif (range) {\n\t  guess = guess + range;\n\t  range = 0;\n\t  if (guess_lo < guess && guess < guess_hi)\n\t    have_guess = 1;\n\t}\n      }\n      else {\n\tif (!utc_p) {\n\t  /* If localtime is nonmonotonic, another result may exist. */\n\t  time_t guess2;\n\t  if (find_dst) {\n\t    guess2 = guess - 2 * 60 * 60;\n\t    tm = localtime(&guess2);\n\t    if (tm) {\n\t      if (tptr->tm_hour != (tm->tm_hour + 2) % 24 ||\n\t\t  tptr->tm_min != tm->tm_min ||\n\t\t  tptr->tm_sec != tm->tm_sec) {\n\t\tguess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +\n\t\t\t  (tm->tm_min - tptr->tm_min) * 60 +\n\t\t\t  (tm->tm_sec - tptr->tm_sec);\n\t\tif (tptr->tm_mday != tm->tm_mday)\n\t\t  guess2 += 24 * 60 * 60;\n\t\tif (guess != guess2) {\n\t\t  tm = localtime(&guess2);\n\t\t  if (tmcmp(tptr, tm) == 0) {\n\t\t    if (guess < guess2)\n\t\t      return guess;\n\t\t    else\n\t\t      return guess2;\n\t\t  }\n\t\t}\n\t      }\n\t    }\n\t  }\n\t  else {\n\t    guess2 = guess + 2 * 60 * 60;\n\t    tm = localtime(&guess2);\n\t    if (tm) {\n\t      if ((tptr->tm_hour + 2) % 24 != tm->tm_hour ||\n\t\t  tptr->tm_min != tm->tm_min ||\n\t\t  tptr->tm_sec != tm->tm_sec) {\n\t\tguess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +\n\t\t\t  (tm->tm_min - tptr->tm_min) * 60 +\n\t\t\t  (tm->tm_sec - tptr->tm_sec);\n\t\tif (tptr->tm_mday != tm->tm_mday)\n\t\t  guess2 -= 24 * 60 * 60;\n\t\tif (guess != guess2) {\n\t\t  tm = localtime(&guess2);\n\t\t  if (tmcmp(tptr, tm) == 0) {\n\t\t    if (guess < guess2)\n\t\t      return guess2;\n\t\t    else\n\t\t      return guess;\n\t\t  }\n\t\t}\n\t      }\n\t    }\n\t  }\n\t}\n\treturn guess;\n      }\n    }\n    /* Given argument has no corresponding time_t. Let's outerpolation. */\n    if (tm_lo.tm_year == tptr->tm_year && tm_lo.tm_mon == tptr->tm_mon) {\n      return guess_lo +\n        (tptr->tm_mday - tm_lo.tm_mday) * 24 * 60 * 60 +\n        (tptr->tm_hour - tm_lo.tm_hour) * 60 * 60 +\n        (tptr->tm_min - tm_lo.tm_min) * 60 +\n        (tptr->tm_sec - tm_lo.tm_sec);\n    }\n    else if (tm_hi.tm_year == tptr->tm_year && tm_hi.tm_mon == tptr->tm_mon) {\n      return guess_hi +\n        (tptr->tm_mday - tm_hi.tm_mday) * 24 * 60 * 60 +\n        (tptr->tm_hour - tm_hi.tm_hour) * 60 * 60 +\n        (tptr->tm_min - tm_hi.tm_min) * 60 +\n        (tptr->tm_sec - tm_hi.tm_sec);\n    }\n\n  out_of_range:\n    rb_raise(rb_eArgError, \"time out of range\");\n\n  error:\n    rb_raise(rb_eArgError, \"gmtime/localtime error\");\n    return 0;\t\t\t/* not reached */\n}\n\nstatic time_t\nmake_time_t(tptr, utc_p)\n    struct tm *tptr;\n    int utc_p;\n{\n    time_t t;\n#ifdef NEGATIVE_TIME_T\n    struct tm *tmp;\n#endif\n    struct tm buf;\n    buf = *tptr;\n    if (utc_p) {\n#if defined(HAVE_TIMEGM)\n\tif ((t = timegm(&buf)) != -1)\n            return t;\n#ifdef NEGATIVE_TIME_T\n        if ((tmp = gmtime(&t)) &&\n            tptr->tm_year == tmp->tm_year &&\n            tptr->tm_mon == tmp->tm_mon &&\n            tptr->tm_mday == tmp->tm_mday &&\n            tptr->tm_hour == tmp->tm_hour &&\n            tptr->tm_min == tmp->tm_min &&\n            tptr->tm_sec == tmp->tm_sec)\n            return t;\n#endif\n#endif\n\treturn search_time_t(&buf, utc_p);\n    }\n    else {\n#if defined(HAVE_MKTIME)\n\tif ((t = mktime(&buf)) != -1)\n            return t;\n#ifdef NEGATIVE_TIME_T\n        if ((tmp = localtime(&t)) &&\n            tptr->tm_year == tmp->tm_year &&\n            tptr->tm_mon == tmp->tm_mon &&\n            tptr->tm_mday == tmp->tm_mday &&\n            tptr->tm_hour == tmp->tm_hour &&\n            tptr->tm_min == tmp->tm_min &&\n            tptr->tm_sec == tmp->tm_sec)\n            return t;\n#endif\n#endif\n\treturn search_time_t(&buf, utc_p);\n    }\n}\n\nstatic VALUE\ntime_utc_or_local(argc, argv, utc_p, klass)\n    int argc;\n    VALUE *argv;\n    int utc_p;\n    VALUE klass;\n{\n    struct tm tm;\n    VALUE time;\n    time_t usec;\n\n    time_arg(argc, argv, &tm, &usec);\n    time = time_new_internal(klass, make_time_t(&tm, utc_p), usec);\n    if (utc_p) return time_gmtime(time);\n    return time_localtime(time);\n}\n\n/*\n *  call-seq:\n *     Time.utc( year [, month, day, hour, min, sec, usec] ) => time\n *     Time.utc( sec, min, hour, day, month, year, wday, yday, isdst, tz\n *     ) => time\n *     Time.gm( year [, month, day, hour, min, sec, usec] ) => time\n *     Time.gm( sec, min, hour, day, month, year, wday, yday, isdst, tz\n *     ) => time\n *     \n *  Creates a time based on given values, interpreted as UTC (GMT). The\n *  year must be specified. Other values default to the minimum value\n *  for that field (and may be <code>nil</code> or omitted). Months may\n *  be specified by numbers from 1 to 12, or by the three-letter English\n *  month names. Hours are specified on a 24-hour clock (0..23). Raises\n *  an <code>ArgumentError</code> if any values are out of range. Will\n *  also accept ten arguments in the order output by\n *  <code>Time#to_a</code>.\n *\n *     Time.utc(2000,\"jan\",1,20,15,1)  #=> Sat Jan 01 20:15:01 UTC 2000\n *     Time.gm(2000,\"jan\",1,20,15,1)   #=> Sat Jan 01 20:15:01 UTC 2000\n */\nstatic VALUE\ntime_s_mkutc(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    return time_utc_or_local(argc, argv, Qtrue, klass);\n}\n\n/*\n *  call-seq:\n *     Time.local( year [, month, day, hour, min, sec, usec] ) => time\n *     Time.local( sec, min, hour, day, month, year, wday, yday, isdst,\n *     tz ) => time\n *     Time.mktime( year, month, day, hour, min, sec, usec )   => time\n *  \n *  Same as <code>Time::gm</code>, but interprets the values in the\n *  local time zone.\n *     \n *     Time.local(2000,\"jan\",1,20,15,1)   #=> Sat Jan 01 20:15:01 CST 2000\n */\n\nstatic VALUE\ntime_s_mktime(argc, argv, klass)\n    int argc;\n    VALUE *argv;\n    VALUE klass;\n{\n    return time_utc_or_local(argc, argv, Qfalse, klass);\n}\n\n/*\n *  call-seq:\n *     time.to_i   => int\n *     time.tv_sec => int\n *  \n *  Returns the value of <i>time</i> as an integer number of seconds\n *  since epoch.\n *     \n *     t = Time.now\n *     \"%10.5f\" % t.to_f   #=> \"1049896564.17839\"\n *     t.to_i              #=> 1049896564\n */\n\nstatic VALUE\ntime_to_i(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    return LONG2NUM(tobj->tv.tv_sec);\n}\n\n/*\n *  call-seq:\n *     time.to_f => float\n *  \n *  Returns the value of <i>time</i> as a floating point number of\n *  seconds since epoch.\n *     \n *     t = Time.now\n *     \"%10.5f\" % t.to_f   #=> \"1049896564.13654\"\n *     t.to_i              #=> 1049896564\n */\n\nstatic VALUE\ntime_to_f(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    return rb_float_new((double)tobj->tv.tv_sec+(double)tobj->tv.tv_usec/1e6);\n}\n\n/*\n *  call-seq:\n *     time.usec    => int\n *     time.tv_usec => int\n *  \n *  Returns just the number of microseconds for <i>time</i>.\n *     \n *     t = Time.now        #=> Wed Apr 09 08:56:04 CDT 2003\n *     \"%10.6f\" % t.to_f   #=> \"1049896564.259970\"\n *     t.usec              #=> 259970\n */\n\nstatic VALUE\ntime_usec(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    return LONG2NUM(tobj->tv.tv_usec);\n}\n\n/*\n *  call-seq:\n *     time <=> other_time => -1, 0, +1 \n *     time <=> numeric    => -1, 0, +1\n *  \n *  Comparison---Compares <i>time</i> with <i>other_time</i> or with\n *  <i>numeric</i>, which is the number of seconds (possibly\n *  fractional) since epoch.\n *     \n *     t = Time.now       #=> Wed Apr 09 08:56:03 CDT 2003\n *     t2 = t + 2592000   #=> Fri May 09 08:56:03 CDT 2003\n *     t <=> t2           #=> -1\n *     t2 <=> t           #=> 1\n *     t <=> t            #=> 0\n */\n\nstatic VALUE\ntime_cmp(time1, time2)\n    VALUE time1, time2;\n{\n    struct time_object *tobj1, *tobj2;\n\n    GetTimeval(time1, tobj1);\n    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {\n\tGetTimeval(time2, tobj2);\n\tif (tobj1->tv.tv_sec == tobj2->tv.tv_sec) {\n\t    if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return INT2FIX(0);\n\t    if (tobj1->tv.tv_usec > tobj2->tv.tv_usec) return INT2FIX(1);\n\t    return INT2FIX(-1);\n\t}\n\tif (tobj1->tv.tv_sec > tobj2->tv.tv_sec) return INT2FIX(1);\n\treturn INT2FIX(-1);\n    }\n\n    return Qnil;\n}\n\n/*\n * call-seq:\n *  time.eql?(other_time)\n *\n * Return <code>true</code> if <i>time</i> and <i>other_time</i> are\n * both <code>Time</code> objects with the same seconds and fractional\n * seconds.\n */\n\nstatic VALUE\ntime_eql(time1, time2)\n    VALUE time1, time2;\n{\n    struct time_object *tobj1, *tobj2;\n\n    GetTimeval(time1, tobj1);\n    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {\n\tGetTimeval(time2, tobj2);\n\tif (tobj1->tv.tv_sec == tobj2->tv.tv_sec) {\n\t    if (tobj1->tv.tv_usec == tobj2->tv.tv_usec) return Qtrue;\n\t}\n    }\n    return Qfalse;\n}\n\n/*\n *  call-seq:\n *     time.utc? => true or false\n *     time.gmt? => true or false\n *  \n *  Returns <code>true</code> if <i>time</i> represents a time in UTC\n *  (GMT).\n *     \n *     t = Time.now                        #=> Wed Apr 09 08:56:04 CDT 2003\n *     t.utc?                              #=> false\n *     t = Time.gm(2000,\"jan\",1,20,15,1)   #=> Sat Jan 01 20:15:01 UTC 2000\n *     t.utc?                              #=> true\n *\n *     t = Time.now                        #=> Wed Apr 09 08:56:03 CDT 2003\n *     t.gmt?                              #=> false\n *     t = Time.gm(2000,1,1,20,15,1)       #=> Sat Jan 01 20:15:01 UTC 2000\n *     t.gmt?                              #=> true\n */\n\nstatic VALUE\ntime_utc_p(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->gmt) return Qtrue;\n    return Qfalse;\n}\n\n/*\n * call-seq:\n *   time.hash   => fixnum\n *\n * Return a hash code for this time object.\n */\n\nstatic VALUE\ntime_hash(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    long hash;\n\n    GetTimeval(time, tobj);\n    hash = tobj->tv.tv_sec ^ tobj->tv.tv_usec;\n    return LONG2FIX(hash);\n}\n\n/* :nodoc: */\nstatic VALUE\ntime_init_copy(copy, time)\n    VALUE copy, time;\n{\n    struct time_object *tobj, *tcopy;\n\n    if (copy == time) return copy;\n    time_modify(copy);\n    if (TYPE(time) != T_DATA || RDATA(time)->dfree != time_free) {\n\trb_raise(rb_eTypeError, \"wrong argument type\");\n    }\n    GetTimeval(time, tobj);\n    GetTimeval(copy, tcopy);\n    MEMCPY(tcopy, tobj, struct time_object, 1);\n\n    return copy;\n}\n\nstatic VALUE\ntime_dup(time)\n    VALUE time;\n{\n    VALUE dup = time_s_alloc(CLASS_OF(time));\n    time_init_copy(dup, time);\n    return dup;\n}\n\n/*\n *  call-seq:\n *     time.localtime => time\n *  \n *  Converts <i>time</i> to local time (using the local time zone in\n *  effect for this process) modifying the receiver.\n *     \n *     t = Time.gm(2000, \"jan\", 1, 20, 15, 1)\n *     t.gmt?        #=> true\n *     t.localtime   #=> Sat Jan 01 14:15:01 CST 2000\n *     t.gmt?        #=> false\n */\n\nstatic VALUE\ntime_localtime(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    struct tm *tm_tmp;\n    time_t t;\n\n    GetTimeval(time, tobj);\n    if (!tobj->gmt) {\n\tif (tobj->tm_got)\n\t    return time;\n    }\n    else {\n\ttime_modify(time);\n    }\n    t = tobj->tv.tv_sec;\n    tm_tmp = localtime(&t);\n    if (!tm_tmp)\n\trb_raise(rb_eArgError, \"localtime error\");\n    tobj->tm = *tm_tmp;\n    tobj->tm_got = 1;\n    tobj->gmt = 0;\n    return time;\n}\n\n/*\n *  call-seq:\n *     time.gmtime    => time\n *     time.utc       => time\n *  \n *  Converts <i>time</i> to UTC (GMT), modifying the receiver.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:03 CDT 2003\n *     t.gmt?         #=> false\n *     t.gmtime       #=> Wed Apr 09 13:56:03 UTC 2003\n *     t.gmt?         #=> true\n *\n *     t = Time.now   #=> Wed Apr 09 08:56:04 CDT 2003\n *     t.utc?         #=> false\n *     t.utc          #=> Wed Apr 09 13:56:04 UTC 2003\n *     t.utc?         #=> true\n */\n\nstatic VALUE\ntime_gmtime(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    struct tm *tm_tmp;\n    time_t t;\n\n    GetTimeval(time, tobj);\n    if (tobj->gmt) {\n\tif (tobj->tm_got)\n\t    return time;\n    }\n    else {\n\ttime_modify(time);\n    }\n    t = tobj->tv.tv_sec;\n    tm_tmp = gmtime(&t);\n    if (!tm_tmp)\n\trb_raise(rb_eArgError, \"gmtime error\");\n    tobj->tm = *tm_tmp;\n    tobj->tm_got = 1;\n    tobj->gmt = 1;\n    return time;\n}\n\n/*\n *  call-seq:\n *     time.getlocal => new_time\n *  \n *  Returns a new <code>new_time</code> object representing <i>time</i> in\n *  local time (using the local time zone in effect for this process).\n *     \n *     t = Time.gm(2000,1,1,20,15,1)   #=> Sat Jan 01 20:15:01 UTC 2000\n *     t.gmt?                          #=> true\n *     l = t.getlocal                  #=> Sat Jan 01 14:15:01 CST 2000\n *     l.gmt?                          #=> false\n *     t == l                          #=> true\n */\n\nstatic VALUE\ntime_getlocaltime(time)\n    VALUE time;\n{\n    return time_localtime(time_dup(time));\n}\n\n/*\n *  call-seq:\n *     time.getgm  => new_time\n *     time.getutc => new_time\n *  \n *  Returns a new <code>new_time</code> object representing <i>time</i> in\n *  UTC.\n *     \n *     t = Time.local(2000,1,1,20,15,1)   #=> Sat Jan 01 20:15:01 CST 2000\n *     t.gmt?                             #=> false\n *     y = t.getgm                        #=> Sun Jan 02 02:15:01 UTC 2000\n *     y.gmt?                             #=> true\n *     t == y                             #=> true\n */\n\nstatic VALUE\ntime_getgmtime(time)\n    VALUE time;\n{\n    return time_gmtime(time_dup(time));\n}\n\nstatic VALUE\ntime_get_tm(time, gmt)\n    VALUE time;\n    int gmt;\n{\n    if (gmt) return time_gmtime(time);\n    return time_localtime(time);\n}\n\n/*\n *  call-seq:\n *     time.asctime => string\n *     time.ctime   => string\n *  \n *  Returns a canonical string representation of <i>time</i>.\n *     \n *     Time.now.asctime   #=> \"Wed Apr  9 08:56:03 2003\"\n */\n\nstatic VALUE\ntime_asctime(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    char *s;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    s = asctime(&tobj->tm);\n    if (s[24] == '\\n') s[24] = '\\0';\n\n    return rb_str_new2(s);\n}\n\n/*\n *  call-seq:\n *     time.inspect => string\n *     time.to_s    => string\n *  \n *  Returns a string representing <i>time</i>. Equivalent to calling\n *  <code>Time#strftime</code> with a format string of ``<code>%a</code>\n *  <code>%b</code> <code>%d</code> <code>%H:%M:%S</code>\n *  <code>%Z</code> <code>%Y</code>''.\n *     \n *     Time.now.to_s   #=> \"Wed Apr 09 08:56:04 CDT 2003\"\n */\n\nstatic VALUE\ntime_to_s(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    char buf[128];\n    int len;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    if (tobj->gmt == 1) {\n\tlen = strftime(buf, 128, \"%a %b %d %H:%M:%S UTC %Y\", &tobj->tm);\n    }\n    else {\n\ttime_t off;\n\tchar buf2[32];\n\tchar sign = '+';\n#if defined(HAVE_STRUCT_TM_TM_GMTOFF)\n\toff = tobj->tm.tm_gmtoff;\n#else\n\tVALUE tmp = time_utc_offset(time);\n\toff = NUM2INT(tmp);\n#endif\n\tif (off < 0) {\n\t    sign = '-';\n\t    off = -off;\n\t}\n\tsprintf(buf2, \"%%a %%b %%d %%H:%%M:%%S %c%02d%02d %%Y\",\n\t\tsign, (int)(off/3600), (int)(off%3600/60));\n\tlen = strftime(buf, 128, buf2, &tobj->tm);\n    }\n    return rb_str_new(buf, len);\n}\n\nstatic VALUE\ntime_add(tobj, offset, sign)\n    struct time_object *tobj;\n    VALUE offset;\n    int sign;\n{\n    double v = NUM2DBL(offset);\n    double f, d;\n    unsigned_time_t sec_off;\n    time_t usec_off, sec, usec;\n    VALUE result;\n\n    if (v < 0) {\n        v = -v;\n        sign = -sign;\n    }\n    d = modf(v, &f);\n    sec_off = (unsigned_time_t)f;\n    if (f != (double)sec_off)\n        rb_raise(rb_eRangeError, \"time %s %f out of Time range\",\n            sign < 0 ? \"-\" : \"+\", v);\n    usec_off = (time_t)(d*1e6+0.5);\n\n    if (sign < 0) {\n        sec = tobj->tv.tv_sec - sec_off;\n        usec = tobj->tv.tv_usec - usec_off;\n        if (sec > tobj->tv.tv_sec)\n            rb_raise(rb_eRangeError, \"time - %f out of Time range\", v);\n    }\n    else {\n        sec = tobj->tv.tv_sec + sec_off;\n        usec = tobj->tv.tv_usec + usec_off;\n        if (sec < tobj->tv.tv_sec)\n            rb_raise(rb_eRangeError, \"time + %f out of Time range\", v);\n    }\n    result = rb_time_new(sec, usec);\n    if (tobj->gmt) {\n\tGetTimeval(result, tobj);\n\ttobj->gmt = 1;\n    }\n    return result;\n}\n\n/*\n *  call-seq:\n *     time + numeric => time\n *  \n *  Addition---Adds some number of seconds (possibly fractional) to\n *  <i>time</i> and returns that value as a new time.\n *     \n *     t = Time.now         #=> Wed Apr 09 08:56:03 CDT 2003\n *     t + (60 * 60 * 24)   #=> Thu Apr 10 08:56:03 CDT 2003\n */\n\nstatic VALUE\ntime_plus(time1, time2)\n    VALUE time1, time2;\n{\n    struct time_object *tobj;\n    GetTimeval(time1, tobj);\n\n    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {\n\trb_raise(rb_eTypeError, \"time + time?\");\n    }\n    return time_add(tobj, time2, 1);\n}\n\n/*\n *  call-seq:\n *     time - other_time => float\n *     time - numeric    => time\n *  \n *  Difference---Returns a new time that represents the difference\n *  between two times, or subtracts the given number of seconds in\n *  <i>numeric</i> from <i>time</i>.\n *     \n *     t = Time.now       #=> Wed Apr 09 08:56:03 CDT 2003\n *     t2 = t + 2592000   #=> Fri May 09 08:56:03 CDT 2003\n *     t2 - t             #=> 2592000.0\n *     t2 - 2592000       #=> Wed Apr 09 08:56:03 CDT 2003\n */\n\nstatic VALUE\ntime_minus(time1, time2)\n    VALUE time1, time2;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time1, tobj);\n    if (TYPE(time2) == T_DATA && RDATA(time2)->dfree == time_free) {\n\tstruct time_object *tobj2;\n        double f;\n\n\tGetTimeval(time2, tobj2);\n\tf = (double)tobj->tv.tv_sec - (double)tobj2->tv.tv_sec;\n\tf += ((double)tobj->tv.tv_usec - (double)tobj2->tv.tv_usec)*1e-6;\n\t/* XXX: should check float overflow on 64bit time_t platforms */\n\n\treturn rb_float_new(f);\n    }\n    return time_add(tobj, time2, -1);\n}\n\n/*\n * call-seq:\n *   time.succ   => new_time\n *\n * Return a new time object, one second later than <code>time</code>.\n */\n\nstatic VALUE\ntime_succ(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    int gmt;\n\n    GetTimeval(time, tobj);\n    gmt = tobj->gmt;\n    time = rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);\n    GetTimeval(time, tobj);\n    tobj->gmt = gmt;\n    return time;\n}\n\n/*\n *  call-seq:\n *     time.sec => fixnum\n *  \n *  Returns the second of the minute (0..60)<em>[Yes, seconds really can\n *  range from zero to 60. This allows the system to inject leap seconds\n *  every now and then to correct for the fact that years are not really\n *  a convenient number of hours long.]</em> for <i>time</i>.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:04 CDT 2003\n *     t.sec          #=> 4\n */\n\nstatic VALUE\ntime_sec(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_sec);\n}\n\n/*\n *  call-seq:\n *     time.min => fixnum\n *  \n *  Returns the minute of the hour (0..59) for <i>time</i>.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:03 CDT 2003\n *     t.min          #=> 56\n */\n\nstatic VALUE\ntime_min(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_min);\n}\n\n/*\n *  call-seq:\n *     time.hour => fixnum\n *  \n *  Returns the hour of the day (0..23) for <i>time</i>.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:03 CDT 2003\n *     t.hour         #=> 8\n */\n\nstatic VALUE\ntime_hour(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_hour);\n}\n\n/*\n *  call-seq:\n *     time.day  => fixnum\n *     time.mday => fixnum\n *  \n *  Returns the day of the month (1..n) for <i>time</i>.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:03 CDT 2003\n *     t.day          #=> 9\n *     t.mday         #=> 9\n */\n\nstatic VALUE\ntime_mday(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_mday);\n}\n\n/*\n *  call-seq:\n *     time.mon   => fixnum\n *     time.month => fixnum\n *  \n *  Returns the month of the year (1..12) for <i>time</i>.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:03 CDT 2003\n *     t.mon          #=> 4\n *     t.month        #=> 4\n */\n\nstatic VALUE\ntime_mon(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_mon+1);\n}\n\n/*\n *  call-seq:\n *     time.year => fixnum\n *  \n *  Returns the year for <i>time</i> (including the century).\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:04 CDT 2003\n *     t.year         #=> 2003\n */\n\nstatic VALUE\ntime_year(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return LONG2NUM((long)tobj->tm.tm_year+1900);\n}\n\n/*\n *  call-seq:\n *     time.wday => fixnum\n *  \n *  Returns an integer representing the day of the week, 0..6, with\n *  Sunday == 0.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:04 CDT 2003\n *     t.wday         #=> 3\n */\n\nstatic VALUE\ntime_wday(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_wday);\n}\n\n/*\n *  call-seq:\n *     time.yday => fixnum\n *  \n *  Returns an integer representing the day of the year, 1..366.\n *     \n *     t = Time.now   #=> Wed Apr 09 08:56:04 CDT 2003\n *     t.yday         #=> 99\n */\n\nstatic VALUE\ntime_yday(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return INT2FIX(tobj->tm.tm_yday+1);\n}\n\n/*\n *  call-seq:\n *     time.isdst => true or false\n *     time.dst?  => true or false\n *  \n *  Returns <code>true</code> if <i>time</i> occurs during Daylight\n *  Saving Time in its time zone.\n *     \n *     Time.local(2000, 7, 1).isdst   #=> true\n *     Time.local(2000, 1, 1).isdst   #=> false\n *     Time.local(2000, 7, 1).dst?    #=> true\n *     Time.local(2000, 1, 1).dst?    #=> false\n */\n\nstatic VALUE\ntime_isdst(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return tobj->tm.tm_isdst?Qtrue:Qfalse;\n}\n\n/*\n *  call-seq:\n *     time.zone => string\n *  \n *  Returns the name of the time zone used for <i>time</i>. As of Ruby\n *  1.8, returns ``UTC'' rather than ``GMT'' for UTC times.\n *     \n *     t = Time.gm(2000, \"jan\", 1, 20, 15, 1)\n *     t.zone   #=> \"UTC\"\n *     t = Time.local(2000, \"jan\", 1, 20, 15, 1)\n *     t.zone   #=> \"CST\"\n */\n\nstatic VALUE\ntime_zone(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n#if !defined(HAVE_TM_ZONE) && (!defined(HAVE_TZNAME) || !defined(HAVE_DAYLIGHT))\n    char buf[64];\n    int len;\n#endif\n    \n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n\n    if (tobj->gmt == 1) {\n\treturn rb_str_new2(\"UTC\");\n    }\n#if defined(HAVE_TM_ZONE)\n    return rb_str_new2(tobj->tm.tm_zone);\n#elif defined(HAVE_TZNAME) && defined(HAVE_DAYLIGHT)\n    return rb_str_new2(tzname[daylight && tobj->tm.tm_isdst]);\n#else\n    len = strftime(buf, 64, \"%Z\", &tobj->tm);\n    return rb_str_new(buf, len);\n#endif\n}\n\n/*\n *  call-seq:\n *     time.gmt_offset => fixnum\n *     time.gmtoff     => fixnum\n *     time.utc_offset => fixnum\n *  \n *  Returns the offset in seconds between the timezone of <i>time</i>\n *  and UTC.\n *     \n *     t = Time.gm(2000,1,1,20,15,1)   #=> Sat Jan 01 20:15:01 UTC 2000\n *     t.gmt_offset                    #=> 0\n *     l = t.getlocal                  #=> Sat Jan 01 14:15:01 CST 2000\n *     l.gmt_offset                    #=> -21600\n */\n\nstatic VALUE\ntime_utc_offset(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n\n    if (tobj->gmt == 1) {\n\treturn INT2FIX(0);\n    }\n    else {\n#if defined(HAVE_STRUCT_TM_TM_GMTOFF)\n\treturn INT2NUM(tobj->tm.tm_gmtoff);\n#else\n\tstruct tm *u, *l;\n\ttime_t t;\n\tlong off;\n\tl = &tobj->tm;\n\tt = tobj->tv.tv_sec;\n\tu = gmtime(&t);\n\tif (!u)\n\t    rb_raise(rb_eArgError, \"gmtime error\");\n\tif (l->tm_year != u->tm_year)\n\t    off = l->tm_year < u->tm_year ? -1 : 1;\n\telse if (l->tm_mon != u->tm_mon)\n\t    off = l->tm_mon < u->tm_mon ? -1 : 1;\n\telse if (l->tm_mday != u->tm_mday)\n\t    off = l->tm_mday < u->tm_mday ? -1 : 1;\n\telse\n\t    off = 0;\n\toff = off * 24 + l->tm_hour - u->tm_hour;\n\toff = off * 60 + l->tm_min - u->tm_min;\n\toff = off * 60 + l->tm_sec - u->tm_sec;\n\treturn LONG2FIX(off);\n#endif\n    }\n}\n\n/*\n *  call-seq:\n *     time.to_a => array\n *  \n *  Returns a ten-element <i>array</i> of values for <i>time</i>:\n *  {<code>[ sec, min, hour, day, month, year, wday, yday, isdst, zone\n *  ]</code>}. See the individual methods for an explanation of the\n *  valid ranges of each value. The ten elements can be passed directly\n *  to <code>Time::utc</code> or <code>Time::local</code> to create a\n *  new <code>Time</code>.\n *     \n *     now = Time.now   #=> Wed Apr 09 08:56:04 CDT 2003\n *     t = now.to_a     #=> [4, 56, 8, 9, 4, 2003, 3, 99, true, \"CDT\"]\n */\n\nstatic VALUE\ntime_to_a(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    return rb_ary_new3(10,\n\t\t    INT2FIX(tobj->tm.tm_sec),\n\t\t    INT2FIX(tobj->tm.tm_min),\n\t\t    INT2FIX(tobj->tm.tm_hour),\n\t\t    INT2FIX(tobj->tm.tm_mday),\n\t\t    INT2FIX(tobj->tm.tm_mon+1),\n\t\t    LONG2NUM((long)tobj->tm.tm_year+1900),\n\t\t    INT2FIX(tobj->tm.tm_wday),\n\t\t    INT2FIX(tobj->tm.tm_yday+1),\n\t\t    tobj->tm.tm_isdst?Qtrue:Qfalse,\n\t\t    time_zone(time));\n}\n\n#define SMALLBUF 100\nstatic int\nrb_strftime(buf, format, time)\n    char **buf;\n    const char *format;\n    struct tm *time;\n{\n    int size, len, flen;\n\n    (*buf)[0] = '\\0';\n    flen = strlen(format);\n    if (flen == 0) {\n\treturn 0;\n    }\n    errno = 0;\n    len = strftime(*buf, SMALLBUF, format, time);\n    if (len != 0 || (**buf == '\\0' && errno != ERANGE)) return len;\n    for (size=1024; ; size*=2) {\n\t*buf = xmalloc(size);\n\t(*buf)[0] = '\\0';\n\tlen = strftime(*buf, size, format, time);\n\t/*\n\t * buflen can be zero EITHER because there's not enough\n\t * room in the string, or because the control command\n\t * goes to the empty string. Make a reasonable guess that\n\t * if the buffer is 1024 times bigger than the length of the\n\t * format string, it's not failing for lack of room.\n\t */\n\tif (len > 0 || size >= 1024 * flen) return len;\n\tfree(*buf);\n    }\n    /* not reached */\n}\n\n/*\n *  call-seq:\n *     time.strftime( string ) => string\n *  \n *  Formats <i>time</i> according to the directives in the given format\n *  string. Any text not listed as a directive will be passed through\n *  to the output string.\n *\n *  Format meaning:\n *    %a - The abbreviated weekday name (``Sun'')\n *    %A - The  full  weekday  name (``Sunday'')\n *    %b - The abbreviated month name (``Jan'')\n *    %B - The  full  month  name (``January'')\n *    %c - The preferred local date and time representation\n *    %d - Day of the month (01..31)\n *    %H - Hour of the day, 24-hour clock (00..23)\n *    %I - Hour of the day, 12-hour clock (01..12)\n *    %j - Day of the year (001..366)\n *    %m - Month of the year (01..12)\n *    %M - Minute of the hour (00..59)\n *    %p - Meridian indicator (``AM''  or  ``PM'')\n *    %S - Second of the minute (00..60)\n *    %U - Week  number  of the current year,\n *            starting with the first Sunday as the first\n *            day of the first week (00..53)\n *    %W - Week  number  of the current year,\n *            starting with the first Monday as the first\n *            day of the first week (00..53)\n *    %w - Day of the week (Sunday is 0, 0..6)\n *    %x - Preferred representation for the date alone, no time\n *    %X - Preferred representation for the time alone, no date\n *    %y - Year without a century (00..99)\n *    %Y - Year with century\n *    %Z - Time zone name\n *    %% - Literal ``%'' character\n *     \n *     t = Time.now\n *     t.strftime(\"Printed on %m/%d/%Y\")   #=> \"Printed on 04/09/2003\"\n *     t.strftime(\"at %I:%M%p\")            #=> \"at 08:56AM\"\n */\n\nstatic VALUE\ntime_strftime(time, format)\n    VALUE time, format;\n{\n    struct time_object *tobj;\n    char buffer[SMALLBUF], *buf = buffer;\n    const char *fmt;\n    long len;\n    VALUE str;\n\n    GetTimeval(time, tobj);\n    if (tobj->tm_got == 0) {\n\ttime_get_tm(time, tobj->gmt);\n    }\n    StringValue(format);\n    format = rb_str_new4(format);\n    fmt = RSTRING(format)->ptr;\n    len = RSTRING(format)->len;\n    if (len == 0) {\n\trb_warning(\"strftime called with empty format string\");\n    }\n    else if (strlen(fmt) < len) {\n\t/* Ruby string may contain \\0's. */\n\tconst char *p = fmt, *pe = fmt + len;\n\n\tstr = rb_str_new(0, 0);\n\twhile (p < pe) {\n\t    len = rb_strftime(&buf, p, &tobj->tm);\n\t    rb_str_cat(str, buf, len);\n\t    p += strlen(p);\n\t    if (buf != buffer) {\n\t\tfree(buf);\n\t\tbuf = buffer;\n\t    }\n\t    for (fmt = p; p < pe && !*p; ++p);\n\t    if (p > fmt) rb_str_cat(str, fmt, p - fmt);\n\t}\n\treturn str;\n    }\n    else {\n\tlen = rb_strftime(&buf, RSTRING(format)->ptr, &tobj->tm);\n    }\n    str = rb_str_new(buf, len);\n    if (buf != buffer) free(buf);\n    return str;\n}\n\n/*\n *  call-seq:\n *     Time.times => struct_tms\n *  \n *  Deprecated in favor of <code>Process::times</code>\n */\n\nstatic VALUE\ntime_s_times(obj)\n    VALUE obj;\n{\n    rb_warn(\"obsolete method Time::times; use Process::times\");\n    return rb_proc_times(obj);\n}\n\n/*\n * undocumented\n */\n\nstatic VALUE\ntime_mdump(time)\n    VALUE time;\n{\n    struct time_object *tobj;\n    struct tm *tm;\n    unsigned long p, s;\n    char buf[8];\n    time_t t;\n    int i;\n\n    GetTimeval(time, tobj);\n\n    t = tobj->tv.tv_sec;\n    tm = gmtime(&t);\n\n    if ((tm->tm_year & 0xffff) != tm->tm_year)\n\trb_raise(rb_eArgError, \"year too big to marshal\");\n\n    p = 0x1UL        << 31 | /*  1 */\n\ttobj->gmt    << 30 | /*  1 */\n\ttm->tm_year  << 14 | /* 16 */\n\ttm->tm_mon   << 10 | /*  4 */\n\ttm->tm_mday  <<  5 | /*  5 */\n\ttm->tm_hour;         /*  5 */\n    s = tm->tm_min   << 26 | /*  6 */\n\ttm->tm_sec   << 20 | /*  6 */\n\ttobj->tv.tv_usec;    /* 20 */\n\n    for (i=0; i<4; i++) {\n\tbuf[i] = p & 0xff;\n\tp = RSHIFT(p, 8);\n    }\n    for (i=4; i<8; i++) {\n\tbuf[i] = s & 0xff;\n\ts = RSHIFT(s, 8);\n    }\n\n    return rb_str_new(buf, 8);\n}\n\n/*\n * call-seq:\n *   time._dump   => string\n *\n * Dump _time_ for marshaling.\n */\n\nstatic VALUE\ntime_dump(argc, argv, time)\n    int argc;\n    VALUE *argv;\n    VALUE time;\n{\n    VALUE str;\n\n    rb_scan_args(argc, argv, \"01\", 0);\n    str = time_mdump(time); \n    if (FL_TEST(time, FL_EXIVAR)) {\n\trb_copy_generic_ivar(str, time);\n\tFL_SET(str, FL_EXIVAR);\n    }\n\n    return str;\n}\n\n/*\n * undocumented\n */\n\nstatic VALUE\ntime_mload(time, str)\n    VALUE time, str;\n{\n    struct time_object *tobj;\n    unsigned long p, s;\n    time_t sec, usec;\n    unsigned char *buf;\n    struct tm tm;\n    int i, gmt;\n\n    time_modify(time);\n    StringValue(str);\n    buf = (unsigned char *)RSTRING(str)->ptr;\n    if (RSTRING(str)->len != 8) {\n\trb_raise(rb_eTypeError, \"marshaled time format differ\");\n    }\n\n    p = s = 0;\n    for (i=0; i<4; i++) {\n\tp |= buf[i]<<(8*i);\n    }\n    for (i=4; i<8; i++) {\n\ts |= buf[i]<<(8*(i-4));\n    }\n\n    if ((p & (1UL<<31)) == 0) {\n\tsec = p;\n\tusec = s;\n    }\n    else {\n\tp &= ~(1UL<<31);\n\tgmt        = (p >> 30) & 0x1;\n\ttm.tm_year = (p >> 14) & 0xffff;\n\ttm.tm_mon  = (p >> 10) & 0xf;\n\ttm.tm_mday = (p >>  5) & 0x1f;\n\ttm.tm_hour =  p        & 0x1f;\n\ttm.tm_min  = (s >> 26) & 0x3f;\n\ttm.tm_sec  = (s >> 20) & 0x3f;\n\ttm.tm_isdst = 0;\n\n\tsec = make_time_t(&tm, Qtrue);\n\tusec = (time_t)(s & 0xfffff);\n    }\n    time_overflow_p(&sec, &usec);\n\n    GetTimeval(time, tobj);\n    tobj->tm_got = 0;\n    tobj->gmt = gmt;\n    tobj->tv.tv_sec = sec;\n    tobj->tv.tv_usec = usec;\n    return time;\n}\n\n/*\n * call-seq:\n *   Time._load(string)   => time\n *\n * Unmarshal a dumped +Time+ object.\n */\n\nstatic VALUE\ntime_load(klass, str)\n    VALUE klass, str;\n{\n    VALUE time = time_s_alloc(klass);\n\n    if (FL_TEST(str, FL_EXIVAR)) {\n\trb_copy_generic_ivar(time, str);\n\tFL_SET(time, FL_EXIVAR);\n    }\n    time_mload(time, str);\n    return time;\n}\n\n/*\n *  <code>Time</code> is an abstraction of dates and times. Time is\n *  stored internally as the number of seconds and microseconds since\n *  the <em>epoch</em>, January 1, 1970 00:00 UTC. On some operating\n *  systems, this offset is allowed to be negative. Also see the\n *  library modules <code>Date</code> and <code>ParseDate</code>. The\n *  <code>Time</code> class treats GMT (Greenwich Mean Time) and UTC\n *  (Coordinated Universal Time)<em>[Yes, UTC really does stand for\n *  Coordinated Universal Time. There was a committee involved.]</em>\n *  as equivalent.  GMT is the older way of referring to these\n *  baseline times but persists in the names of calls on Posix\n *  systems.\n *     \n *  All times are stored with some number of microseconds. Be aware of\n *  this fact when comparing times with each other---times that are\n *  apparently equal when displayed may be different when compared.\n */\n\nvoid\nInit_Time()\n{\n    rb_cTime = rb_define_class(\"Time\", rb_cObject);\n    rb_include_module(rb_cTime, rb_mComparable);\n\n    rb_define_alloc_func(rb_cTime, time_s_alloc);\n    rb_define_singleton_method(rb_cTime, \"now\", rb_class_new_instance, -1);\n    rb_define_singleton_method(rb_cTime, \"at\", time_s_at, -1);\n    rb_define_singleton_method(rb_cTime, \"utc\", time_s_mkutc, -1);\n    rb_define_singleton_method(rb_cTime, \"gm\", time_s_mkutc, -1);\n    rb_define_singleton_method(rb_cTime, \"local\", time_s_mktime, -1);\n    rb_define_singleton_method(rb_cTime, \"mktime\", time_s_mktime, -1);\n\n    rb_define_singleton_method(rb_cTime, \"times\", time_s_times, 0);\n\n    rb_define_method(rb_cTime, \"to_i\", time_to_i, 0);\n    rb_define_method(rb_cTime, \"to_f\", time_to_f, 0);\n    rb_define_method(rb_cTime, \"<=>\", time_cmp, 1);\n    rb_define_method(rb_cTime, \"eql?\", time_eql, 1);\n    rb_define_method(rb_cTime, \"hash\", time_hash, 0);\n    rb_define_method(rb_cTime, \"initialize\", time_init, 0);\n    rb_define_method(rb_cTime, \"initialize_copy\", time_init_copy, 1);\n\n    rb_define_method(rb_cTime, \"localtime\", time_localtime, 0);\n    rb_define_method(rb_cTime, \"gmtime\", time_gmtime, 0);\n    rb_define_method(rb_cTime, \"utc\", time_gmtime, 0);\n    rb_define_method(rb_cTime, \"getlocal\", time_getlocaltime, 0);\n    rb_define_method(rb_cTime, \"getgm\", time_getgmtime, 0);\n    rb_define_method(rb_cTime, \"getutc\", time_getgmtime, 0);\n\n    rb_define_method(rb_cTime, \"ctime\", time_asctime, 0);\n    rb_define_method(rb_cTime, \"asctime\", time_asctime, 0);\n    rb_define_method(rb_cTime, \"to_s\", time_to_s, 0);\n    rb_define_method(rb_cTime, \"inspect\", time_to_s, 0);\n    rb_define_method(rb_cTime, \"to_a\", time_to_a, 0);\n\n    rb_define_method(rb_cTime, \"+\", time_plus, 1);\n    rb_define_method(rb_cTime, \"-\", time_minus, 1);\n\n    rb_define_method(rb_cTime, \"succ\", time_succ, 0);\n    rb_define_method(rb_cTime, \"sec\", time_sec, 0);\n    rb_define_method(rb_cTime, \"min\", time_min, 0);\n    rb_define_method(rb_cTime, \"hour\", time_hour, 0);\n    rb_define_method(rb_cTime, \"mday\", time_mday, 0);\n    rb_define_method(rb_cTime, \"day\", time_mday, 0);\n    rb_define_method(rb_cTime, \"mon\", time_mon, 0);\n    rb_define_method(rb_cTime, \"month\", time_mon, 0);\n    rb_define_method(rb_cTime, \"year\", time_year, 0);\n    rb_define_method(rb_cTime, \"wday\", time_wday, 0);\n    rb_define_method(rb_cTime, \"yday\", time_yday, 0);\n    rb_define_method(rb_cTime, \"isdst\", time_isdst, 0);\n    rb_define_method(rb_cTime, \"dst?\", time_isdst, 0);\n    rb_define_method(rb_cTime, \"zone\", time_zone, 0);\n    rb_define_method(rb_cTime, \"gmtoff\", time_utc_offset, 0);\n    rb_define_method(rb_cTime, \"gmt_offset\", time_utc_offset, 0);\n    rb_define_method(rb_cTime, \"utc_offset\", time_utc_offset, 0);\n\n    rb_define_method(rb_cTime, \"utc?\", time_utc_p, 0);\n    rb_define_method(rb_cTime, \"gmt?\", time_utc_p, 0);\n\n    rb_define_method(rb_cTime, \"tv_sec\", time_to_i, 0);\n    rb_define_method(rb_cTime, \"tv_usec\", time_usec, 0);\n    rb_define_method(rb_cTime, \"usec\", time_usec, 0);\n\n    rb_define_method(rb_cTime, \"strftime\", time_strftime, 1);\n\n    /* methods for marshaling */\n    rb_define_method(rb_cTime, \"_dump\", time_dump, -1);\n    rb_define_singleton_method(rb_cTime, \"_load\", time_load, 1);\n#if 0\n    /* Time will support marshal_dump and marshal_load in the future (1.9 maybe) */\n    rb_define_method(rb_cTime, \"marshal_dump\", time_mdump, 0);\n    rb_define_method(rb_cTime, \"marshal_load\", time_mload, 1);\n#endif\n}\n"
  },
  {
    "path": "util.c",
    "content": "/**********************************************************************\n\n  util.c -\n\n  $Author$\n  $Date$\n  created at: Fri Mar 10 17:22:34 JST 1995\n\n  Copyright (C) 1993-2008 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n\n#include <ctype.h>\n#include <stdio.h>\n#include <errno.h>\n#include <math.h>\n#include <float.h>\n\n#ifdef _WIN32\n#include \"missing/file.h\"\n#endif\n#if defined(__CYGWIN32__) || defined(_WIN32)\n#include <io.h>\n#endif\n\n#include \"util.h\"\n#ifndef HAVE_STRING_H\nchar *strchr _((char*,char));\n#endif\n\nunsigned long\nscan_oct(start, len, retlen)\n    const char *start;\n    int len;\n    int *retlen;\n{\n    register const char *s = start;\n    register unsigned long retval = 0;\n\n    while (len-- && *s >= '0' && *s <= '7') {\n\tretval <<= 3;\n\tretval |= *s++ - '0';\n    }\n    *retlen = s - start;\n    return retval;\n}\n\nunsigned long\nscan_hex(start, len, retlen)\n    const char *start;\n    int len;\n    int *retlen;\n{\n    static const char hexdigit[] = \"0123456789abcdef0123456789ABCDEF\";\n    register const char *s = start;\n    register unsigned long retval = 0;\n    char *tmp;\n\n    while (len-- && *s && (tmp = strchr(hexdigit, *s))) {\n\tretval <<= 4;\n\tretval |= (tmp - hexdigit) & 15;\n\ts++;\n    }\n    *retlen = s - start;\n    return retval;\n}\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#if defined(HAVE_FCNTL_H)\n#include <fcntl.h>\n#endif\n\n#ifndef S_ISDIR\n#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)\n#endif\n\n#if defined(MSDOS) || defined(__CYGWIN32__) || defined(_WIN32)\n/*\n *  Copyright (c) 1993, Intergraph Corporation\n *\n *  You may distribute under the terms of either the GNU General Public\n *  License or the Artistic License, as specified in the perl README file.\n *\n *  Various Unix compatibility functions and NT specific functions.\n *\n *  Some of this code was derived from the MSDOS port(s) and the OS/2 port.\n *\n */\n\n\n/*\n * Suffix appending for in-place editing under MS-DOS and OS/2 (and now NT!).\n *\n * Here are the rules:\n *\n * Style 0:  Append the suffix exactly as standard perl would do it.\n *           If the filesystem groks it, use it.  (HPFS will always\n *           grok it.  So will NTFS. FAT will rarely accept it.)\n *\n * Style 1:  The suffix begins with a '.'.  The extension is replaced.\n *           If the name matches the original name, use the fallback method.\n *\n * Style 2:  The suffix is a single character, not a '.'.  Try to add the\n *           suffix to the following places, using the first one that works.\n *               [1] Append to extension.\n *               [2] Append to filename,\n *               [3] Replace end of extension,\n *               [4] Replace end of filename.\n *           If the name matches the original name, use the fallback method.\n *\n * Style 3:  Any other case:  Ignore the suffix completely and use the\n *           fallback method.\n *\n * Fallback method:  Change the extension to \".$$$\".  If that matches the\n *           original name, then change the extension to \".~~~\".\n *\n * If filename is more than 1000 characters long, we die a horrible\n * death.  Sorry.\n *\n * The filename restriction is a cheat so that we can use buf[] to store\n * assorted temporary goo.\n *\n * Examples, assuming style 0 failed.\n *\n * suffix = \".bak\" (style 1)\n *                foo.bar => foo.bak\n *                foo.bak => foo.$$$\t(fallback)\n *                foo.$$$ => foo.~~~\t(fallback)\n *                makefile => makefile.bak\n *\n * suffix = \"~\" (style 2)\n *                foo.c => foo.c~\n *                foo.c~ => foo.c~~\n *                foo.c~~ => foo~.c~~\n *                foo~.c~~ => foo~~.c~~\n *                foo~~~~~.c~~ => foo~~~~~.$$$ (fallback)\n *\n *                foo.pas => foo~.pas\n *                makefile => makefile.~\n *                longname.fil => longname.fi~\n *                longname.fi~ => longnam~.fi~\n *                longnam~.fi~ => longnam~.$$$\n *\n */\n\n\nstatic int valid_filename(char *s);\n\nstatic const char suffix1[] = \".$$$\";\nstatic const char suffix2[] = \".~~~\";\n\n#define ext (&buf[1000])\n\n#define strEQ(s1,s2) (strcmp(s1,s2) == 0)\n\nvoid\nruby_add_suffix(str, suffix)\n    VALUE str;\n    char *suffix;\n{\n    int baselen;\n    int extlen = strlen(suffix);\n    char *s, *t, *p;\n    long slen;\n    char buf[1024];\n\n    if (RSTRING(str)->len > 1000)\n        rb_fatal(\"Cannot do inplace edit on long filename (%ld characters)\",\n\t\t RSTRING(str)->len);\n\n#if defined(DJGPP) || defined(__CYGWIN32__) || defined(_WIN32)\n    /* Style 0 */\n    slen = RSTRING(str)->len;\n    rb_str_cat(str, suffix, extlen);\n#if defined(DJGPP)\n    if (_USE_LFN) return;\n#else\n    if (valid_filename(RSTRING(str)->ptr)) return;\n#endif\n\n    /* Fooey, style 0 failed.  Fix str before continuing. */\n    RSTRING(str)->ptr[RSTRING(str)->len = slen] = '\\0';\n#endif\n\n    slen = extlen;\n    t = buf; baselen = 0; s = RSTRING(str)->ptr;\n    while ((*t = *s) && *s != '.') {\n\tbaselen++;\n\tif (*s == '\\\\' || *s == '/') baselen = 0;\n \ts++; t++;\n    }\n    p = t;\n\n    t = ext; extlen = 0;\n    while (*t++ = *s++) extlen++;\n    if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; }\n\n    if (*suffix == '.') {        /* Style 1 */\n        if (strEQ(ext, suffix)) goto fallback;\n\tstrcpy(p, suffix);\n    }\n    else if (suffix[1] == '\\0') {  /* Style 2 */\n        if (extlen < 4) {\n\t    ext[extlen] = *suffix;\n\t    ext[++extlen] = '\\0';\n        }\n\telse if (baselen < 8) {\n   \t    *p++ = *suffix;\n\t}\n\telse if (ext[3] != *suffix) {\n\t    ext[3] = *suffix;\n\t}\n\telse if (buf[7] != *suffix) {\n\t    buf[7] = *suffix;\n\t}\n\telse goto fallback;\n\tstrcpy(p, ext);\n    }\n    else { /* Style 3:  Panic */\nfallback:\n\t(void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5);\n    }\n    rb_str_resize(str, strlen(buf));\n    memcpy(RSTRING(str)->ptr, buf, RSTRING(str)->len);\n}\n\n#if defined(__CYGWIN32__) || defined(_WIN32)\n#if defined __CYGWIN32__ || defined __MINGW32__\nextern int _open(const char *, int, ...);\nextern int _close(int);\nextern int _unlink(const char *);\n#endif\n\nstatic int\nvalid_filename(char *s)\n{\n    int fd;\n\n    /*\n    // It doesn't exist, so see if we can open it.\n    */\n\n    if ((fd = _open(s, O_CREAT|O_EXCL, 0666)) >= 0) {\n\t_close(fd);\n\t_unlink(s);\t/* don't leave it laying around */\n\treturn 1;\n    }\n    else if (errno == EEXIST) {\n\t/* if the file exists, then it's a valid filename! */\n\treturn 1;\n    }\n    return 0;\n}\n#endif\n#endif\n\n#if defined __DJGPP__\n\n#include <dpmi.h>\n\nstatic char dbcs_table[256];\n\nint\nmake_dbcs_table()\n{\n    __dpmi_regs r;\n    struct {\n\tunsigned char start;\n\tunsigned char end;\n    } vec;\n    int offset;\n\n    memset(&r, 0, sizeof(r));\n    r.x.ax = 0x6300;\n    __dpmi_int(0x21, &r);\n    offset = r.x.ds * 16 + r.x.si;\n\n    for (;;) {\n\tint i;\n\tdosmemget(offset, sizeof vec, &vec);\n\tif (!vec.start && !vec.end)\n\t    break;\n\tfor (i = vec.start; i <= vec.end; i++)\n\t    dbcs_table[i] = 1;\n\toffset += 2;\n    }\n}\n\nint\nmblen(const char *s, size_t n)\n{\n    static int need_init = 1;\n    if (need_init) {\n\tmake_dbcs_table();\n\tneed_init = 0;\n    }\n    if (s) {\n\tif (n == 0 || *s == 0)\n\t    return 0;\n\telse if (!s[1])\n\t    return 1;\n\treturn dbcs_table[(unsigned char)*s] + 1;\n    }\n    else\n\treturn 1;\n}\n\nstruct PathList {\n    struct PathList *next;\n    char *path;\n};\n\nstruct PathInfo {\n    struct PathList *head;\n    int count;\n};\n\nstatic int\npush_element(const char *path, VALUE vinfo)\n{\n    struct PathList *p;\n    struct PathInfo *info = (struct PathInfo *)vinfo;\n\n    p = ALLOC(struct PathList);\n    MEMZERO(p, struct PathList, 1);\n    p->path = ruby_strdup(path);\n    p->next = info->head;\n    info->head = p;\n    info->count++;\n\n    return 0;\n}\n\n#include <dirent.h>\nint __opendir_flags = __OPENDIR_PRESERVE_CASE;\n\nchar **\n__crt0_glob_function(char *path)\n{\n    int len = strlen(path);\n    int i;\n    char **rv;\n    char path_buffer[PATH_MAX];\n    char *buf = path_buffer;\n    char *p;\n    struct PathInfo info;\n    struct PathList *plist;\n\n    if (PATH_MAX <= len)\n\tbuf = ruby_xmalloc(len + 1);\n\n    strncpy(buf, path, len);\n    buf[len] = '\\0';\n\n    for (p = buf; *p; p += mblen(p, MB_CUR_MAX))\n\tif (*p == '\\\\')\n\t    *p = '/';\n\n    info.count = 0;\n    info.head = 0;\n\n    ruby_glob(buf, 0, push_element, (VALUE)&info);\n\n    if (buf != path_buffer)\n\truby_xfree(buf);\n\n    if (info.count == 0)\n\treturn 0;\n\n    rv = ruby_xmalloc((info.count + 1) * sizeof (char *));\n\n    plist = info.head;\n    i = 0;\n    while (plist) {\n\tstruct PathList *cur;\n\trv[i] = plist->path;\n\tcur = plist;\n\tplist = plist->next;\n\truby_xfree(cur);\n\ti++;\n    }\n    rv[i] = 0;\n    return rv;\n}\n\n#endif\n\n/* mm.c */\n\n#define A ((int*)a)\n#define B ((int*)b)\n#define C ((int*)c)\n#define D ((int*)d)\n\n#define mmprepare(base, size) do {\\\n if (((long)base & (0x3)) == 0)\\\n   if (size >= 16) mmkind = 1;\\\n   else            mmkind = 0;\\\n else              mmkind = -1;\\\n high = (size & (~0xf));\\\n low  = (size &  0x0c);\\\n} while (0)\\\n\n#define mmarg mmkind, size, high, low\n\nstatic void mmswap_(a, b, mmarg)\n    register char *a, *b;\n    int mmarg;\n{\n register int s;\n if (a == b) return;\n if (mmkind >= 0) {\n   if (mmkind > 0) {\n     register char *t = a + high;\n     do {\n       s = A[0]; A[0] = B[0]; B[0] = s;\n       s = A[1]; A[1] = B[1]; B[1] = s;\n       s = A[2]; A[2] = B[2]; B[2] = s;\n       s = A[3]; A[3] = B[3]; B[3] = s;  a += 16; b += 16;\n     } while (a < t);\n   }\n   if (low != 0) { s = A[0]; A[0] = B[0]; B[0] = s;\n     if (low >= 8) { s = A[1]; A[1] = B[1]; B[1] = s;\n       if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = s;}}}\n }\n else {\n   register char *t = a + size;\n   do {s = *a; *a++ = *b; *b++ = s;} while (a < t);\n }\n}\n#define mmswap(a,b) mmswap_((a),(b),mmarg)\n\nstatic void mmrot3_(a, b, c, mmarg)\n    register char *a, *b, *c;\n    int mmarg;\n{\n register int s;\n if (mmkind >= 0) {\n   if (mmkind > 0) {\n     register char *t = a + high;\n     do {\n       s = A[0]; A[0] = B[0]; B[0] = C[0]; C[0] = s;\n       s = A[1]; A[1] = B[1]; B[1] = C[1]; C[1] = s;\n       s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;\n       s = A[3]; A[3] = B[3]; B[3] = C[3]; C[3] = s; a += 16; b += 16; c += 16;\n     } while (a < t);\n   }\n   if (low != 0) { s = A[0]; A[0] = B[0]; B[0] = C[0]; C[0] = s;\n     if (low >= 8) { s = A[1]; A[1] = B[1]; B[1] = C[1]; C[1] = s;\n       if (low == 12) {s = A[2]; A[2] = B[2]; B[2] = C[2]; C[2] = s;}}}\n }\n else {\n   register char *t = a + size;\n   do {s = *a; *a++ = *b; *b++ = *c; *c++ = s;} while (a < t);\n }\n}\n#define mmrot3(a,b,c) mmrot3_((a),(b),(c),mmarg)\n\n/* qs6.c */\n/*****************************************************/\n/*                                                   */\n/*          qs6   (Quick sort function)              */\n/*                                                   */\n/* by  Tomoyuki Kawamura              1995.4.21      */\n/* kawamura@tokuyama.ac.jp                           */\n/*****************************************************/\n\ntypedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */\n#define PUSH(ll,rr) do { top->LL = (ll); top->RR = (rr); ++top; } while (0)  /* Push L,l,R,r */\n#define POP(ll,rr)  do { --top; ll = top->LL; rr = top->RR; } while (0)      /* Pop L,l,R,r */\n\n#define med3(a,b,c) ((*cmp)(a,b,d)<0 ?                                   \\\n                       ((*cmp)(b,c,d)<0 ? b : ((*cmp)(a,c,d)<0 ? c : a)) : \\\n                       ((*cmp)(b,c,d)>0 ? b : ((*cmp)(a,c,d)<0 ? a : c)))\n\nvoid ruby_qsort (base, nel, size, cmp, d)\n     void* base;\n     const int nel;\n     const int size;\n     int (*cmp)();\n     void *d;\n{\n  register char *l, *r, *m;          \t/* l,r:left,right group   m:median point */\n  register int  t, eq_l, eq_r;       \t/* eq_l: all items in left group are equal to S */\n  char *L = base;                    \t/* left end of curren region */\n  char *R = (char*)base + size*(nel-1); /* right end of current region */\n  int  chklim = 63;                     /* threshold of ordering element check */\n  stack_node stack[32], *top = stack;   /* 32 is enough for 32bit CPU */\n  int mmkind, high, low;\n\n  if (nel <= 1) return;        /* need not to sort */\n  mmprepare(base, size);\n  goto start;\n\n  nxt:\n  if (stack == top) return;    /* return if stack is empty */\n  POP(L,R);\n\n  for (;;) {\n    start:\n    if (L + size == R) {       /* 2 elements */\n      if ((*cmp)(L,R,d) > 0) mmswap(L,R); goto nxt;\n    }\n\n    l = L; r = R;\n    t = (r - l + size) / size;  /* number of elements */\n    m = l + size * (t >> 1);    /* calculate median value */\n\n    if (t >= 60) {\n      register char *m1;\n      register char *m3;\n      if (t >= 200) {\n\tt = size*(t>>3); /* number of bytes in splitting 8 */\n\t{\n\t  register char *p1 = l  + t;\n\t  register char *p2 = p1 + t;\n\t  register char *p3 = p2 + t;\n\t  m1 = med3(p1, p2, p3);\n\t  p1 = m  + t;\n\t  p2 = p1 + t;\n\t  p3 = p2 + t;\n\t  m3 = med3(p1, p2, p3);\n\t}\n      }\n      else {\n\tt = size*(t>>2); /* number of bytes in splitting 4 */\n\tm1 = l + t;\n\tm3 = m + t;\n      }\n      m = med3(m1, m, m3);\n    }\n\n    if ((t = (*cmp)(l,m,d)) < 0) {                           /*3-5-?*/\n      if ((t = (*cmp)(m,r,d)) < 0) {                         /*3-5-7*/\n\tif (chklim && nel >= chklim) {   /* check if already ascending order */\n\t  char *p;\n\t  chklim = 0;\n\t  for (p=l; p<r; p+=size) if ((*cmp)(p,p+size,d) > 0) goto fail;\n\t  goto nxt;\n\t}\n\tfail: goto loopA;                                    /*3-5-7*/\n      }\n      if (t > 0) {\n\tif ((*cmp)(l,r,d) <= 0) {mmswap(m,r); goto loopA;}     /*3-5-4*/\n\tmmrot3(r,m,l); goto loopA;                           /*3-5-2*/\n      }\n      goto loopB;                                            /*3-5-5*/\n    }\n\n    if (t > 0) {                                             /*7-5-?*/\n      if ((t = (*cmp)(m,r,d)) > 0) {                         /*7-5-3*/\n\tif (chklim && nel >= chklim) {   /* check if already ascending order */\n\t  char *p;\n\t  chklim = 0;\n\t  for (p=l; p<r; p+=size) if ((*cmp)(p,p+size,d) < 0) goto fail2;\n\t  while (l<r) {mmswap(l,r); l+=size; r-=size;}  /* reverse region */\n\t  goto nxt;\n\t}\n\tfail2: mmswap(l,r); goto loopA;                      /*7-5-3*/\n      }\n      if (t < 0) {\n\tif ((*cmp)(l,r,d) <= 0) {mmswap(l,m); goto loopB;}   /*7-5-8*/\n\tmmrot3(l,m,r); goto loopA;                           /*7-5-6*/\n      }\n      mmswap(l,r); goto loopA;                               /*7-5-5*/\n    }\n\n    if ((t = (*cmp)(m,r,d)) < 0)  {goto loopA;}              /*5-5-7*/\n    if (t > 0) {mmswap(l,r); goto loopB;}                    /*5-5-3*/\n\n    /* determining splitting type in case 5-5-5 */           /*5-5-5*/\n    for (;;) {\n      if ((l += size) == r)      goto nxt;                   /*5-5-5*/\n      if (l == m) continue;\n      if ((t = (*cmp)(l,m,d)) > 0) {mmswap(l,r); l = L; goto loopA;}/*575-5*/\n      if (t < 0)                 {mmswap(L,l); l = L; goto loopB;}  /*535-5*/\n    }\n\n    loopA: eq_l = 1; eq_r = 1;  /* splitting type A */ /* left <= median < right */\n    for (;;) {\n      for (;;) {\n\tif ((l += size) == r)\n\t  {l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}\n\tif (l == m) continue;\n\tif ((t = (*cmp)(l,m,d)) > 0) {eq_r = 0; break;}\n\tif (t < 0) eq_l = 0;\n      }\n      for (;;) {\n\tif (l == (r -= size))\n\t  {l -= size; if (l != m) mmswap(m,l); l -= size; goto fin;}\n\tif (r == m) {m = l; break;}\n\tif ((t = (*cmp)(r,m,d)) < 0) {eq_l = 0; break;}\n\tif (t == 0) break;\n      }\n      mmswap(l,r);    /* swap left and right */\n    }\n\n    loopB: eq_l = 1; eq_r = 1;  /* splitting type B */ /* left < median <= right */\n    for (;;) {\n      for (;;) {\n\tif (l == (r -= size))\n\t  {r += size; if (r != m) mmswap(r,m); r += size; goto fin;}\n\tif (r == m) continue;\n\tif ((t = (*cmp)(r,m,d)) < 0) {eq_l = 0; break;}\n\tif (t > 0) eq_r = 0;\n      }\n      for (;;) {\n\tif ((l += size) == r)\n\t  {r += size; if (r != m) mmswap(r,m); r += size; goto fin;}\n\tif (l == m) {m = r; break;}\n\tif ((t = (*cmp)(l,m,d)) > 0) {eq_r = 0; break;}\n\tif (t == 0) break;\n      }\n      mmswap(l,r);    /* swap left and right */\n    }\n\n    fin:\n    if (eq_l == 0)                         /* need to sort left side */\n      if (eq_r == 0)                       /* need to sort right side */\n\tif (l-L < R-r) {PUSH(r,R); R = l;} /* sort left side first */\n\telse           {PUSH(L,l); L = r;} /* sort right side first */\n      else R = l;                          /* need to sort left side only */\n    else if (eq_r == 0) L = r;             /* need to sort right side only */\n    else goto nxt;                         /* need not to sort both sides */\n  }\n}\n\nchar *\nruby_strdup(str)\n    const char *str;\n{\n    char *tmp;\n    int len = strlen(str) + 1;\n\n    tmp = xmalloc(len);\n    memcpy(tmp, str, len);\n\n    return tmp;\n}\n\n/* Mask system strdup to fix tcmalloc issue on OS X*/\n#define strdup(s) strdup(s)\nchar *\nstrdup(str)\n    const char *str;\n{\n    return ruby_strdup(str);\n}\n#define strdup(s) ruby_strdup(s)\n\nchar *\nruby_getcwd()\n{\n#ifdef HAVE_GETCWD\n    int size = 200;\n    char *buf = xmalloc(size);\n\n    while (!getcwd(buf, size)) {\n\tif (errno != ERANGE) {\n\t    free(buf);\n\t    rb_sys_fail(\"getcwd\");\n\t}\n\tsize *= 2;\n\tbuf = xrealloc(buf, size);\n    }\n#else\n# ifndef PATH_MAX\n#  define PATH_MAX 8192\n# endif\n    char *buf = xmalloc(PATH_MAX+1);\n\n    if (!getwd(buf)) {\n\tfree(buf);\n\trb_sys_fail(\"getwd\");\n    }\n#endif\n    return buf;\n}\n\n\n/****************************************************************\n *\n * The author of this software is David M. Gay.\n *\n * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose without fee is hereby granted, provided that this entire notice\n * is included in all copies of any software which is or includes a copy\n * or modification of this software and in all copies of the supporting\n * documentation for such software.\n *\n * THIS SOFTWARE IS BEING PROVIDED \"AS IS\", WITHOUT ANY EXPRESS OR IMPLIED\n * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY\n * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY\n * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.\n *\n ***************************************************************/\n\n/* Please send bug reports to David M. Gay (dmg at acm dot org,\n * with \" at \" changed at \"@\" and \" dot \" changed to \".\").\t*/\n\n/* On a machine with IEEE extended-precision registers, it is\n * necessary to specify double-precision (53-bit) rounding precision\n * before invoking strtod or dtoa.  If the machine uses (the equivalent\n * of) Intel 80x87 arithmetic, the call\n *\t_control87(PC_53, MCW_PC);\n * does this with many compilers.  Whether this or another call is\n * appropriate depends on the compiler; for this to work, it may be\n * necessary to #include \"float.h\" or another system-dependent header\n * file.\n */\n\n/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.\n *\n * This strtod returns a nearest machine number to the input decimal\n * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are\n * broken by the IEEE round-even rule.  Otherwise ties are broken by\n * biased rounding (add half and chop).\n *\n * Inspired loosely by William D. Clinger's paper \"How to Read Floating\n * Point Numbers Accurately\" [Proc. ACM SIGPLAN '90, pp. 92-101].\n *\n * Modifications:\n *\n *\t1. We only require IEEE, IBM, or VAX double-precision\n *\t\tarithmetic (not IEEE double-extended).\n *\t2. We get by with floating-point arithmetic in a case that\n *\t\tClinger missed -- when we're computing d * 10^n\n *\t\tfor a small integer d and the integer n is not too\n *\t\tmuch larger than 22 (the maximum integer k for which\n *\t\twe can represent 10^k exactly), we may be able to\n *\t\tcompute (d*10^k) * 10^(e-k) with just one roundoff.\n *\t3. Rather than a bit-at-a-time adjustment of the binary\n *\t\tresult in the hard case, we use floating-point\n *\t\tarithmetic to determine the adjustment to within\n *\t\tone bit; only in really hard cases do we need to\n *\t\tcompute a second residual.\n *\t4. Because of 3., we don't need a large table of powers of 10\n *\t\tfor ten-to-e (just some small tables, e.g. of 10^k\n *\t\tfor 0 <= k <= 22).\n */\n\n/*\n * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least\n *\tsignificant byte has the lowest address.\n * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most\n *\tsignificant byte has the lowest address.\n * #define Long int on machines with 32-bit ints and 64-bit longs.\n * #define IBM for IBM mainframe-style floating-point arithmetic.\n * #define VAX for VAX-style floating-point arithmetic (D_floating).\n * #define No_leftright to omit left-right logic in fast floating-point\n *\tcomputation of dtoa.\n * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3\n *\tand strtod and dtoa should round accordingly.\n * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3\n *\tand Honor_FLT_ROUNDS is not #defined.\n * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines\n *\tthat use extended-precision instructions to compute rounded\n *\tproducts and quotients) with IBM.\n * #define ROUND_BIASED for IEEE-format with biased rounding.\n * #define Inaccurate_Divide for IEEE-format with correctly rounded\n *\tproducts but inaccurate quotients, e.g., for Intel i860.\n * #define NO_LONG_LONG on machines that do not have a \"long long\"\n *\tinteger type (of >= 64 bits).  On such machines, you can\n *\t#define Just_16 to store 16 bits per 32-bit Long when doing\n *\thigh-precision integer arithmetic.  Whether this speeds things\n *\tup or slows things down depends on the machine and the number\n *\tbeing converted.  If long long is available and the name is\n *\tsomething other than \"long long\", #define Llong to be the name,\n *\tand if \"unsigned Llong\" does not work as an unsigned version of\n *\tLlong, #define #ULLong to be the corresponding unsigned type.\n * #define KR_headers for old-style C function headers.\n * #define Bad_float_h if your system lacks a float.h or if it does not\n *\tdefine some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,\n *\tFLT_RADIX, FLT_ROUNDS, and DBL_MAX.\n * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)\n *\tif memory is available and otherwise does something you deem\n *\tappropriate.  If MALLOC is undefined, malloc will be invoked\n *\tdirectly -- and assumed always to succeed.\n * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making\n *\tmemory allocations from a private pool of memory when possible.\n *\tWhen used, the private pool is PRIVATE_MEM bytes long:  2304 bytes,\n *\tunless #defined to be a different length.  This default length\n *\tsuffices to get rid of MALLOC calls except for unusual cases,\n *\tsuch as decimal-to-binary conversion of a very long string of\n *\tdigits.  The longest string dtoa can return is about 751 bytes\n *\tlong.  For conversions by strtod of strings of 800 digits and\n *\tall dtoa conversions in single-threaded executions with 8-byte\n *\tpointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte\n *\tpointers, PRIVATE_MEM >= 7112 appears adequate.\n * #define INFNAN_CHECK on IEEE systems to cause strtod to check for\n *\tInfinity and NaN (case insensitively).  On some systems (e.g.,\n *\tsome HP systems), it may be necessary to #define NAN_WORD0\n *\tappropriately -- to the most significant word of a quiet NaN.\n *\t(On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)\n *\tWhen INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,\n *\tstrtod also accepts (case insensitively) strings of the form\n *\tNaN(x), where x is a string of hexadecimal digits and spaces;\n *\tif there is only one string of hexadecimal digits, it is taken\n *\tfor the 52 fraction bits of the resulting NaN; if there are two\n *\tor more strings of hex digits, the first is for the high 20 bits,\n *\tthe second and subsequent for the low 32 bits, with intervening\n *\twhite space ignored; but if this results in none of the 52\n *\tfraction bits being on (an IEEE Infinity symbol), then NAN_WORD0\n *\tand NAN_WORD1 are used instead.\n * #define MULTIPLE_THREADS if the system offers preemptively scheduled\n *\tmultiple threads.  In this case, you must provide (or suitably\n *\t#define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed\n *\tby FREE_DTOA_LOCK(n) for n = 0 or 1.  (The second lock, accessed\n *\tin pow5mult, ensures lazy evaluation of only one copy of high\n *\tpowers of 5; omitting this lock would introduce a small\n *\tprobability of wasting memory, but would otherwise be harmless.)\n *\tYou must also invoke freedtoa(s) to free the value s returned by\n *\tdtoa.  You may do so whether or not MULTIPLE_THREADS is #defined.\n * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that\n *\tavoids underflows on inputs whose result does not underflow.\n *\tIf you #define NO_IEEE_Scale on a machine that uses IEEE-format\n *\tfloating-point numbers and flushes underflows to zero rather\n *\tthan implementing gradual underflow, then you must also #define\n *\tSudden_Underflow.\n * #define YES_ALIAS to permit aliasing certain double values with\n *\tarrays of ULongs.  This leads to slightly better code with\n *\tsome compilers and was always used prior to 19990916, but it\n *\tis not strictly legal and can cause trouble with aggressively\n *\toptimizing compilers (e.g., gcc 2.95.1 under -O2).\n * #define USE_LOCALE to use the current locale's decimal_point value.\n * #define SET_INEXACT if IEEE arithmetic is being used and extra\n *\tcomputation should be done to set the inexact flag when the\n *\tresult is inexact and avoid setting inexact when the result\n *\tis exact.  In this case, dtoa.c must be compiled in\n *\tan environment, perhaps provided by #include \"dtoa.c\" in a\n *\tsuitable wrapper, that defines two functions,\n *\t\tint get_inexact(void);\n *\t\tvoid clear_inexact(void);\n *\tsuch that get_inexact() returns a nonzero value if the\n *\tinexact bit is already set, and clear_inexact() sets the\n *\tinexact bit to 0.  When SET_INEXACT is #defined, strtod\n *\talso does extra computations to set the underflow and overflow\n *\tflags when appropriate (i.e., when the result is tiny and\n *\tinexact or when it is a numeric value rounded to +-infinity).\n * #define NO_ERRNO if strtod should not assign errno = ERANGE when\n *\tthe result overflows to +-Infinity or underflows to 0.\n */\n\n#ifdef WORDS_BIGENDIAN\n#define IEEE_BIG_ENDIAN\n#else\n#define IEEE_LITTLE_ENDIAN\n#endif\n\n#ifdef __vax__\n#define VAX\n#undef IEEE_BIG_ENDIAN\n#undef IEEE_LITTLE_ENDIAN\n#endif\n\n#if defined(__arm__) && !defined(__VFP_FP__)\n#define IEEE_BIG_ENDIAN\n#undef IEEE_LITTLE_ENDIAN\n#endif\n\n#undef Long\n#undef ULong\n\n#if SIZEOF_INT == 4\n#define Long int\n#define ULong unsigned int\n#elif SIZEOF_LONG == 4\n#define Long long int\n#define ULong unsigned long int\n#endif\n\n#if HAVE_LONG_LONG\n#define Llong LONG_LONG\n#endif\n\n#ifdef DEBUG\n#include \"stdio.h\"\n#define Bug(x) {fprintf(stderr, \"%s\\n\", x); exit(1);}\n#endif\n\n#include \"stdlib.h\"\n#include \"string.h\"\n\n#ifdef USE_LOCALE\n#include \"locale.h\"\n#endif\n\n#ifdef MALLOC\nextern void *MALLOC(size_t);\n#else\n#define MALLOC malloc\n#endif\n\n#ifndef Omit_Private_Memory\n#ifndef PRIVATE_MEM\n#define PRIVATE_MEM 2304\n#endif\n#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))\nstatic double private_mem[PRIVATE_mem], *pmem_next = private_mem;\n#endif\n\n#undef IEEE_Arith\n#undef Avoid_Underflow\n#ifdef IEEE_BIG_ENDIAN\n#define IEEE_Arith\n#endif\n#ifdef IEEE_LITTLE_ENDIAN\n#define IEEE_Arith\n#endif\n\n#include \"errno.h\"\n\n#ifdef Bad_float_h\n\n#ifdef IEEE_Arith\n#define DBL_DIG 15\n#define DBL_MAX_10_EXP 308\n#define DBL_MAX_EXP 1024\n#define FLT_RADIX 2\n#endif /*IEEE_Arith*/\n\n#ifdef IBM\n#define DBL_DIG 16\n#define DBL_MAX_10_EXP 75\n#define DBL_MAX_EXP 63\n#define FLT_RADIX 16\n#define DBL_MAX 7.2370055773322621e+75\n#endif\n\n#ifdef VAX\n#define DBL_DIG 16\n#define DBL_MAX_10_EXP 38\n#define DBL_MAX_EXP 127\n#define FLT_RADIX 2\n#define DBL_MAX 1.7014118346046923e+38\n#endif\n\n#ifndef LONG_MAX\n#define LONG_MAX 2147483647\n#endif\n\n#else /* ifndef Bad_float_h */\n#include \"float.h\"\n#endif /* Bad_float_h */\n\n#ifndef __MATH_H__\n#include \"math.h\"\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1\nExactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined.\n#endif\n\ntypedef union { double d; ULong L[2]; } U;\n\n#ifdef YES_ALIAS\ntypedef double double_u;\n#  define dval(x) x\n#  ifdef IEEE_LITTLE_ENDIAN\n#    define word0(x) (((ULong *)&x)[1])\n#    define word1(x) (((ULong *)&x)[0])\n#  else\n#    define word0(x) (((ULong *)&x)[0])\n#    define word1(x) (((ULong *)&x)[1])\n#  endif\n#else\ntypedef U double_u;\n#  ifdef IEEE_LITTLE_ENDIAN\n#    define word0(x) (x.L[1])\n#    define word1(x) (x.L[0])\n#  else\n#    define word0(x) (x.L[0])\n#    define word1(x) (x.L[1])\n#  endif\n#  define dval(x) (x.d)\n#endif\n\n/* The following definition of Storeinc is appropriate for MIPS processors.\n * An alternative that might be better on some machines is\n * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)\n */\n#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)\n#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \\\n((unsigned short *)a)[0] = (unsigned short)c, a++)\n#else\n#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \\\n((unsigned short *)a)[1] = (unsigned short)c, a++)\n#endif\n\n/* #define P DBL_MANT_DIG */\n/* Ten_pmax = floor(P*log(2)/log(5)) */\n/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */\n/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */\n/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */\n\n#ifdef IEEE_Arith\n#define Exp_shift  20\n#define Exp_shift1 20\n#define Exp_msk1    0x100000\n#define Exp_msk11   0x100000\n#define Exp_mask  0x7ff00000\n#define P 53\n#define Bias 1023\n#define Emin (-1022)\n#define Exp_1  0x3ff00000\n#define Exp_11 0x3ff00000\n#define Ebits 11\n#define Frac_mask  0xfffff\n#define Frac_mask1 0xfffff\n#define Ten_pmax 22\n#define Bletch 0x10\n#define Bndry_mask  0xfffff\n#define Bndry_mask1 0xfffff\n#define LSB 1\n#define Sign_bit 0x80000000\n#define Log2P 1\n#define Tiny0 0\n#define Tiny1 1\n#define Quick_max 14\n#define Int_max 14\n#ifndef NO_IEEE_Scale\n#define Avoid_Underflow\n#ifdef Flush_Denorm\t/* debugging option */\n#undef Sudden_Underflow\n#endif\n#endif\n\n#ifndef Flt_Rounds\n#ifdef FLT_ROUNDS\n#define Flt_Rounds FLT_ROUNDS\n#else\n#define Flt_Rounds 1\n#endif\n#endif /*Flt_Rounds*/\n\n#ifdef Honor_FLT_ROUNDS\n#define Rounding rounding\n#undef Check_FLT_ROUNDS\n#define Check_FLT_ROUNDS\n#else\n#define Rounding Flt_Rounds\n#endif\n\n#else /* ifndef IEEE_Arith */\n#undef Check_FLT_ROUNDS\n#undef Honor_FLT_ROUNDS\n#undef SET_INEXACT\n#undef  Sudden_Underflow\n#define Sudden_Underflow\n#ifdef IBM\n#undef Flt_Rounds\n#define Flt_Rounds 0\n#define Exp_shift  24\n#define Exp_shift1 24\n#define Exp_msk1   0x1000000\n#define Exp_msk11  0x1000000\n#define Exp_mask  0x7f000000\n#define P 14\n#define Bias 65\n#define Exp_1  0x41000000\n#define Exp_11 0x41000000\n#define Ebits 8\t/* exponent has 7 bits, but 8 is the right value in b2d */\n#define Frac_mask  0xffffff\n#define Frac_mask1 0xffffff\n#define Bletch 4\n#define Ten_pmax 22\n#define Bndry_mask  0xefffff\n#define Bndry_mask1 0xffffff\n#define LSB 1\n#define Sign_bit 0x80000000\n#define Log2P 4\n#define Tiny0 0x100000\n#define Tiny1 0\n#define Quick_max 14\n#define Int_max 15\n#else /* VAX */\n#undef Flt_Rounds\n#define Flt_Rounds 1\n#define Exp_shift  23\n#define Exp_shift1 7\n#define Exp_msk1    0x80\n#define Exp_msk11   0x800000\n#define Exp_mask  0x7f80\n#define P 56\n#define Bias 129\n#define Exp_1  0x40800000\n#define Exp_11 0x4080\n#define Ebits 8\n#define Frac_mask  0x7fffff\n#define Frac_mask1 0xffff007f\n#define Ten_pmax 24\n#define Bletch 2\n#define Bndry_mask  0xffff007f\n#define Bndry_mask1 0xffff007f\n#define LSB 0x10000\n#define Sign_bit 0x8000\n#define Log2P 1\n#define Tiny0 0x80\n#define Tiny1 0\n#define Quick_max 15\n#define Int_max 15\n#endif /* IBM, VAX */\n#endif /* IEEE_Arith */\n\n#ifndef IEEE_Arith\n#define ROUND_BIASED\n#endif\n\n#ifdef RND_PRODQUOT\n#define rounded_product(a,b) a = rnd_prod(a, b)\n#define rounded_quotient(a,b) a = rnd_quot(a, b)\nextern double rnd_prod(double, double), rnd_quot(double, double);\n#else\n#define rounded_product(a,b) a *= b\n#define rounded_quotient(a,b) a /= b\n#endif\n\n#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))\n#define Big1 0xffffffff\n\n#ifndef Pack_32\n#define Pack_32\n#endif\n\n#define FFFFFFFF 0xffffffffUL\n\n#ifdef NO_LONG_LONG\n#undef ULLong\n#ifdef Just_16\n#undef Pack_32\n/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.\n * This makes some inner loops simpler and sometimes saves work\n * during multiplications, but it often seems to make things slightly\n * slower.  Hence the default is now to store 32 bits per Long.\n */\n#endif\n#else\t/* long long available */\n#ifndef Llong\n#define Llong long long\n#endif\n#ifndef ULLong\n#define ULLong unsigned Llong\n#endif\n#endif /* NO_LONG_LONG */\n\n#ifndef MULTIPLE_THREADS\n#define ACQUIRE_DTOA_LOCK(n)\t/*nothing*/\n#define FREE_DTOA_LOCK(n)\t/*nothing*/\n#endif\n\n#define Kmax 15\n\nstruct Bigint {\n    struct Bigint *next;\n    int k, maxwds, sign, wds;\n    ULong x[1];\n};\n\ntypedef struct Bigint Bigint;\n\nstatic Bigint *freelist[Kmax+1];\n\nstatic Bigint *\nBalloc(int k)\n{\n    int x;\n    Bigint *rv;\n#ifndef Omit_Private_Memory\n    unsigned int len;\n#endif\n\n    ACQUIRE_DTOA_LOCK(0);\n    if ((rv = freelist[k]) != 0) {\n        freelist[k] = rv->next;\n    }\n    else {\n        x = 1 << k;\n#ifdef Omit_Private_Memory\n        rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));\n#else\n        len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)\n                /sizeof(double);\n        if (pmem_next - private_mem + len <= PRIVATE_mem) {\n            rv = (Bigint*)pmem_next;\n            pmem_next += len;\n        }\n        else\n            rv = (Bigint*)MALLOC(len*sizeof(double));\n#endif\n        rv->k = k;\n        rv->maxwds = x;\n    }\n    FREE_DTOA_LOCK(0);\n    rv->sign = rv->wds = 0;\n    return rv;\n}\n\nstatic void\nBfree(Bigint *v)\n{\n    if (v) {\n        ACQUIRE_DTOA_LOCK(0);\n        v->next = freelist[v->k];\n        freelist[v->k] = v;\n        FREE_DTOA_LOCK(0);\n    }\n}\n\n#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \\\ny->wds*sizeof(Long) + 2*sizeof(int))\n\nstatic Bigint *\nmultadd(Bigint *b, int m, int a)   /* multiply by m and add a */\n{\n    int i, wds;\n#ifdef ULLong\n    ULong *x;\n    ULLong carry, y;\n#else\n    ULong carry, *x, y;\n#ifdef Pack_32\n    ULong xi, z;\n#endif\n#endif\n    Bigint *b1;\n\n    wds = b->wds;\n    x = b->x;\n    i = 0;\n    carry = a;\n    do {\n#ifdef ULLong\n        y = *x * (ULLong)m + carry;\n        carry = y >> 32;\n        *x++ = y & FFFFFFFF;\n#else\n#ifdef Pack_32\n        xi = *x;\n        y = (xi & 0xffff) * m + carry;\n        z = (xi >> 16) * m + (y >> 16);\n        carry = z >> 16;\n        *x++ = (z << 16) + (y & 0xffff);\n#else\n        y = *x * m + carry;\n        carry = y >> 16;\n        *x++ = y & 0xffff;\n#endif\n#endif\n    } while (++i < wds);\n    if (carry) {\n        if (wds >= b->maxwds) {\n            b1 = Balloc(b->k+1);\n            Bcopy(b1, b);\n            Bfree(b);\n            b = b1;\n        }\n        b->x[wds++] = carry;\n        b->wds = wds;\n    }\n    return b;\n}\n\nstatic Bigint *\ns2b(const char *s, int nd0, int nd, ULong y9)\n{\n    Bigint *b;\n    int i, k;\n    Long x, y;\n\n    x = (nd + 8) / 9;\n    for (k = 0, y = 1; x > y; y <<= 1, k++) ;\n#ifdef Pack_32\n    b = Balloc(k);\n    b->x[0] = y9;\n    b->wds = 1;\n#else\n    b = Balloc(k+1);\n    b->x[0] = y9 & 0xffff;\n    b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;\n#endif\n\n    i = 9;\n    if (9 < nd0) {\n        s += 9;\n        do {\n            b = multadd(b, 10, *s++ - '0');\n        } while (++i < nd0);\n        s++;\n    }\n    else\n        s += 10;\n    for (; i < nd; i++)\n        b = multadd(b, 10, *s++ - '0');\n    return b;\n}\n\nstatic int\nhi0bits(register ULong x)\n{\n    register int k = 0;\n\n    if (!(x & 0xffff0000)) {\n        k = 16;\n        x <<= 16;\n    }\n    if (!(x & 0xff000000)) {\n        k += 8;\n        x <<= 8;\n    }\n    if (!(x & 0xf0000000)) {\n        k += 4;\n        x <<= 4;\n    }\n    if (!(x & 0xc0000000)) {\n        k += 2;\n        x <<= 2;\n    }\n    if (!(x & 0x80000000)) {\n        k++;\n        if (!(x & 0x40000000))\n            return 32;\n    }\n    return k;\n}\n\nstatic int\nlo0bits(ULong *y)\n{\n    register int k;\n    register ULong x = *y;\n\n    if (x & 7) {\n        if (x & 1)\n            return 0;\n        if (x & 2) {\n            *y = x >> 1;\n            return 1;\n        }\n        *y = x >> 2;\n        return 2;\n    }\n    k = 0;\n    if (!(x & 0xffff)) {\n        k = 16;\n        x >>= 16;\n    }\n    if (!(x & 0xff)) {\n        k += 8;\n        x >>= 8;\n    }\n    if (!(x & 0xf)) {\n        k += 4;\n        x >>= 4;\n    }\n    if (!(x & 0x3)) {\n        k += 2;\n        x >>= 2;\n    }\n    if (!(x & 1)) {\n        k++;\n        x >>= 1;\n        if (!x)\n            return 32;\n    }\n    *y = x;\n    return k;\n}\n\nstatic Bigint *\ni2b(int i)\n{\n    Bigint *b;\n\n    b = Balloc(1);\n    b->x[0] = i;\n    b->wds = 1;\n    return b;\n}\n\nstatic Bigint *\nmult(Bigint *a, Bigint *b)\n{\n    Bigint *c;\n    int k, wa, wb, wc;\n    ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;\n    ULong y;\n#ifdef ULLong\n    ULLong carry, z;\n#else\n    ULong carry, z;\n#ifdef Pack_32\n    ULong z2;\n#endif\n#endif\n\n    if (a->wds < b->wds) {\n        c = a;\n        a = b;\n        b = c;\n    }\n    k = a->k;\n    wa = a->wds;\n    wb = b->wds;\n    wc = wa + wb;\n    if (wc > a->maxwds)\n        k++;\n    c = Balloc(k);\n    for (x = c->x, xa = x + wc; x < xa; x++)\n        *x = 0;\n    xa = a->x;\n    xae = xa + wa;\n    xb = b->x;\n    xbe = xb + wb;\n    xc0 = c->x;\n#ifdef ULLong\n    for (; xb < xbe; xc0++) {\n        if ((y = *xb++) != 0) {\n            x = xa;\n            xc = xc0;\n            carry = 0;\n            do {\n                z = *x++ * (ULLong)y + *xc + carry;\n                carry = z >> 32;\n                *xc++ = z & FFFFFFFF;\n            } while (x < xae);\n            *xc = carry;\n        }\n    }\n#else\n#ifdef Pack_32\n    for (; xb < xbe; xb++, xc0++) {\n        if (y = *xb & 0xffff) {\n            x = xa;\n            xc = xc0;\n            carry = 0;\n            do {\n                z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;\n                carry = z >> 16;\n                z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;\n                carry = z2 >> 16;\n                Storeinc(xc, z2, z);\n            } while (x < xae);\n            *xc = carry;\n        }\n        if (y = *xb >> 16) {\n            x = xa;\n            xc = xc0;\n            carry = 0;\n            z2 = *xc;\n            do {\n                z = (*x & 0xffff) * y + (*xc >> 16) + carry;\n                carry = z >> 16;\n                Storeinc(xc, z, z2);\n                z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;\n                carry = z2 >> 16;\n            } while (x < xae);\n            *xc = z2;\n        }\n    }\n#else\n    for (; xb < xbe; xc0++) {\n        if (y = *xb++) {\n            x = xa;\n            xc = xc0;\n            carry = 0;\n            do {\n                z = *x++ * y + *xc + carry;\n                carry = z >> 16;\n                *xc++ = z & 0xffff;\n            } while (x < xae);\n            *xc = carry;\n        }\n    }\n#endif\n#endif\n    for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;\n    c->wds = wc;\n    return c;\n}\n\nstatic Bigint *p5s;\n\nstatic Bigint *\npow5mult(Bigint *b, int k)\n{\n    Bigint *b1, *p5, *p51;\n    int i;\n    static int p05[3] = { 5, 25, 125 };\n\n    if ((i = k & 3) != 0)\n        b = multadd(b, p05[i-1], 0);\n\n    if (!(k >>= 2))\n        return b;\n    if (!(p5 = p5s)) {\n        /* first time */\n#ifdef MULTIPLE_THREADS\n        ACQUIRE_DTOA_LOCK(1);\n        if (!(p5 = p5s)) {\n            p5 = p5s = i2b(625);\n            p5->next = 0;\n        }\n        FREE_DTOA_LOCK(1);\n#else\n        p5 = p5s = i2b(625);\n        p5->next = 0;\n#endif\n    }\n    for (;;) {\n        if (k & 1) {\n            b1 = mult(b, p5);\n            Bfree(b);\n            b = b1;\n        }\n        if (!(k >>= 1))\n            break;\n        if (!(p51 = p5->next)) {\n#ifdef MULTIPLE_THREADS\n            ACQUIRE_DTOA_LOCK(1);\n            if (!(p51 = p5->next)) {\n                p51 = p5->next = mult(p5,p5);\n                p51->next = 0;\n            }\n            FREE_DTOA_LOCK(1);\n#else\n            p51 = p5->next = mult(p5,p5);\n            p51->next = 0;\n#endif\n        }\n        p5 = p51;\n    }\n    return b;\n}\n\nstatic Bigint *\nlshift(Bigint *b, int k)\n{\n    int i, k1, n, n1;\n    Bigint *b1;\n    ULong *x, *x1, *xe, z;\n\n#ifdef Pack_32\n    n = k >> 5;\n#else\n    n = k >> 4;\n#endif\n    k1 = b->k;\n    n1 = n + b->wds + 1;\n    for (i = b->maxwds; n1 > i; i <<= 1)\n        k1++;\n    b1 = Balloc(k1);\n    x1 = b1->x;\n    for (i = 0; i < n; i++)\n        *x1++ = 0;\n    x = b->x;\n    xe = x + b->wds;\n#ifdef Pack_32\n    if (k &= 0x1f) {\n        k1 = 32 - k;\n        z = 0;\n        do {\n            *x1++ = *x << k | z;\n            z = *x++ >> k1;\n        } while (x < xe);\n        if ((*x1 = z) != 0)\n            ++n1;\n    }\n#else\n    if (k &= 0xf) {\n        k1 = 16 - k;\n        z = 0;\n        do {\n            *x1++ = *x << k  & 0xffff | z;\n            z = *x++ >> k1;\n        } while (x < xe);\n        if (*x1 = z)\n            ++n1;\n    }\n#endif\n    else\n        do {\n            *x1++ = *x++;\n        } while (x < xe);\n    b1->wds = n1 - 1;\n    Bfree(b);\n    return b1;\n}\n\nstatic int\ncmp(Bigint *a, Bigint *b)\n{\n    ULong *xa, *xa0, *xb, *xb0;\n    int i, j;\n\n    i = a->wds;\n    j = b->wds;\n#ifdef DEBUG\n    if (i > 1 && !a->x[i-1])\n        Bug(\"cmp called with a->x[a->wds-1] == 0\");\n    if (j > 1 && !b->x[j-1])\n        Bug(\"cmp called with b->x[b->wds-1] == 0\");\n#endif\n    if (i -= j)\n        return i;\n    xa0 = a->x;\n    xa = xa0 + j;\n    xb0 = b->x;\n    xb = xb0 + j;\n    for (;;) {\n        if (*--xa != *--xb)\n            return *xa < *xb ? -1 : 1;\n        if (xa <= xa0)\n            break;\n    }\n    return 0;\n}\n\nstatic Bigint *\ndiff(Bigint *a, Bigint *b)\n{\n    Bigint *c;\n    int i, wa, wb;\n    ULong *xa, *xae, *xb, *xbe, *xc;\n#ifdef ULLong\n    ULLong borrow, y;\n#else\n    ULong borrow, y;\n#ifdef Pack_32\n    ULong z;\n#endif\n#endif\n\n    i = cmp(a,b);\n    if (!i) {\n        c = Balloc(0);\n        c->wds = 1;\n        c->x[0] = 0;\n        return c;\n    }\n    if (i < 0) {\n        c = a;\n        a = b;\n        b = c;\n        i = 1;\n    }\n    else\n        i = 0;\n    c = Balloc(a->k);\n    c->sign = i;\n    wa = a->wds;\n    xa = a->x;\n    xae = xa + wa;\n    wb = b->wds;\n    xb = b->x;\n    xbe = xb + wb;\n    xc = c->x;\n    borrow = 0;\n#ifdef ULLong\n    do {\n        y = (ULLong)*xa++ - *xb++ - borrow;\n        borrow = y >> 32 & (ULong)1;\n        *xc++ = y & FFFFFFFF;\n    } while (xb < xbe);\n    while (xa < xae) {\n        y = *xa++ - borrow;\n        borrow = y >> 32 & (ULong)1;\n        *xc++ = y & FFFFFFFF;\n    }\n#else\n#ifdef Pack_32\n    do {\n        y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;\n        borrow = (y & 0x10000) >> 16;\n        z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;\n        borrow = (z & 0x10000) >> 16;\n        Storeinc(xc, z, y);\n    } while (xb < xbe);\n    while (xa < xae) {\n        y = (*xa & 0xffff) - borrow;\n        borrow = (y & 0x10000) >> 16;\n        z = (*xa++ >> 16) - borrow;\n        borrow = (z & 0x10000) >> 16;\n        Storeinc(xc, z, y);\n    }\n#else\n    do {\n        y = *xa++ - *xb++ - borrow;\n        borrow = (y & 0x10000) >> 16;\n        *xc++ = y & 0xffff;\n    } while (xb < xbe);\n    while (xa < xae) {\n        y = *xa++ - borrow;\n        borrow = (y & 0x10000) >> 16;\n        *xc++ = y & 0xffff;\n    }\n#endif\n#endif\n    while (!*--xc)\n        wa--;\n    c->wds = wa;\n    return c;\n}\n\nstatic double\nulp(double x_)\n{\n    register Long L;\n    double_u x, a;\n    dval(x) = x_;\n\n    L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;\n#ifndef Avoid_Underflow\n#ifndef Sudden_Underflow\n    if (L > 0) {\n#endif\n#endif\n#ifdef IBM\n        L |= Exp_msk1 >> 4;\n#endif\n        word0(a) = L;\n        word1(a) = 0;\n#ifndef Avoid_Underflow\n#ifndef Sudden_Underflow\n    }\n    else {\n        L = -L >> Exp_shift;\n        if (L < Exp_shift) {\n            word0(a) = 0x80000 >> L;\n            word1(a) = 0;\n        }\n        else {\n            word0(a) = 0;\n            L -= Exp_shift;\n            word1(a) = L >= 31 ? 1 : 1 << 31 - L;\n        }\n    }\n#endif\n#endif\n    return dval(a);\n}\n\nstatic double\nb2d(Bigint *a, int *e)\n{\n    ULong *xa, *xa0, w, y, z;\n    int k;\n    double_u d;\n#ifdef VAX\n    ULong d0, d1;\n#else\n#define d0 word0(d)\n#define d1 word1(d)\n#endif\n\n    xa0 = a->x;\n    xa = xa0 + a->wds;\n    y = *--xa;\n#ifdef DEBUG\n    if (!y) Bug(\"zero y in b2d\");\n#endif\n    k = hi0bits(y);\n    *e = 32 - k;\n#ifdef Pack_32\n    if (k < Ebits) {\n        d0 = Exp_1 | y >> (Ebits - k);\n        w = xa > xa0 ? *--xa : 0;\n        d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);\n        goto ret_d;\n    }\n    z = xa > xa0 ? *--xa : 0;\n    if (k -= Ebits) {\n        d0 = Exp_1 | y << k | z >> (32 - k);\n        y = xa > xa0 ? *--xa : 0;\n        d1 = z << k | y >> (32 - k);\n    }\n    else {\n        d0 = Exp_1 | y;\n        d1 = z;\n    }\n#else\n    if (k < Ebits + 16) {\n        z = xa > xa0 ? *--xa : 0;\n        d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;\n        w = xa > xa0 ? *--xa : 0;\n        y = xa > xa0 ? *--xa : 0;\n        d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;\n        goto ret_d;\n    }\n    z = xa > xa0 ? *--xa : 0;\n    w = xa > xa0 ? *--xa : 0;\n    k -= Ebits + 16;\n    d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;\n    y = xa > xa0 ? *--xa : 0;\n    d1 = w << k + 16 | y << k;\n#endif\nret_d:\n#ifdef VAX\n    word0(d) = d0 >> 16 | d0 << 16;\n    word1(d) = d1 >> 16 | d1 << 16;\n#else\n#undef d0\n#undef d1\n#endif\n    return dval(d);\n}\n\nstatic Bigint *\nd2b(double d_, int *e, int *bits)\n{\n    double_u d;\n    Bigint *b;\n    int de, k;\n    ULong *x, y, z;\n#ifndef Sudden_Underflow\n    int i;\n#endif\n#ifdef VAX\n    ULong d0, d1;\n#endif\n    dval(d) = d_;\n#ifdef VAX\n    d0 = word0(d) >> 16 | word0(d) << 16;\n    d1 = word1(d) >> 16 | word1(d) << 16;\n#else\n#define d0 word0(d)\n#define d1 word1(d)\n#endif\n\n#ifdef Pack_32\n    b = Balloc(1);\n#else\n    b = Balloc(2);\n#endif\n    x = b->x;\n\n    z = d0 & Frac_mask;\n    d0 &= 0x7fffffff;   /* clear sign bit, which we ignore */\n#ifdef Sudden_Underflow\n    de = (int)(d0 >> Exp_shift);\n#ifndef IBM\n    z |= Exp_msk11;\n#endif\n#else\n    if ((de = (int)(d0 >> Exp_shift)) != 0)\n        z |= Exp_msk1;\n#endif\n#ifdef Pack_32\n    if ((y = d1) != 0) {\n        if ((k = lo0bits(&y)) != 0) {\n            x[0] = y | z << (32 - k);\n            z >>= k;\n        }\n        else\n            x[0] = y;\n#ifndef Sudden_Underflow\n        i =\n#endif\n        b->wds = (x[1] = z) ? 2 : 1;\n    }\n    else {\n#ifdef DEBUG\n        if (!z)\n            Bug(\"Zero passed to d2b\");\n#endif\n        k = lo0bits(&z);\n        x[0] = z;\n#ifndef Sudden_Underflow\n        i =\n#endif\n        b->wds = 1;\n        k += 32;\n    }\n#else\n    if (y = d1) {\n        if (k = lo0bits(&y))\n            if (k >= 16) {\n                x[0] = y | z << 32 - k & 0xffff;\n                x[1] = z >> k - 16 & 0xffff;\n                x[2] = z >> k;\n                i = 2;\n            }\n            else {\n                x[0] = y & 0xffff;\n                x[1] = y >> 16 | z << 16 - k & 0xffff;\n                x[2] = z >> k & 0xffff;\n                x[3] = z >> k+16;\n                i = 3;\n            }\n        else {\n            x[0] = y & 0xffff;\n            x[1] = y >> 16;\n            x[2] = z & 0xffff;\n            x[3] = z >> 16;\n            i = 3;\n        }\n    }\n    else {\n#ifdef DEBUG\n        if (!z)\n            Bug(\"Zero passed to d2b\");\n#endif\n        k = lo0bits(&z);\n        if (k >= 16) {\n            x[0] = z;\n            i = 0;\n        }\n        else {\n            x[0] = z & 0xffff;\n            x[1] = z >> 16;\n            i = 1;\n        }\n        k += 32;\n    }\n    while (!x[i])\n        --i;\n    b->wds = i + 1;\n#endif\n#ifndef Sudden_Underflow\n    if (de) {\n#endif\n#ifdef IBM\n        *e = (de - Bias - (P-1) << 2) + k;\n        *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);\n#else\n        *e = de - Bias - (P-1) + k;\n        *bits = P - k;\n#endif\n#ifndef Sudden_Underflow\n    }\n    else {\n        *e = de - Bias - (P-1) + 1 + k;\n#ifdef Pack_32\n        *bits = 32*i - hi0bits(x[i-1]);\n#else\n        *bits = (i+2)*16 - hi0bits(x[i]);\n#endif\n    }\n#endif\n    return b;\n}\n#undef d0\n#undef d1\n\nstatic double\nratio(Bigint *a, Bigint *b)\n{\n    double_u da, db;\n    int k, ka, kb;\n\n    dval(da) = b2d(a, &ka);\n    dval(db) = b2d(b, &kb);\n#ifdef Pack_32\n    k = ka - kb + 32*(a->wds - b->wds);\n#else\n    k = ka - kb + 16*(a->wds - b->wds);\n#endif\n#ifdef IBM\n    if (k > 0) {\n        word0(da) += (k >> 2)*Exp_msk1;\n        if (k &= 3)\n            dval(da) *= 1 << k;\n    }\n    else {\n        k = -k;\n        word0(db) += (k >> 2)*Exp_msk1;\n        if (k &= 3)\n            dval(db) *= 1 << k;\n    }\n#else\n    if (k > 0)\n        word0(da) += k*Exp_msk1;\n    else {\n        k = -k;\n        word0(db) += k*Exp_msk1;\n    }\n#endif\n    return dval(da) / dval(db);\n}\n\nstatic const double\ntens[] = {\n    1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,\n    1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,\n    1e20, 1e21, 1e22\n#ifdef VAX\n    , 1e23, 1e24\n#endif\n};\n\nstatic const double\n#ifdef IEEE_Arith\nbigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };\nstatic const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,\n#ifdef Avoid_Underflow\n    9007199254740992.*9007199254740992.e-256\n    /* = 2^106 * 1e-53 */\n#else\n    1e-256\n#endif\n};\n/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */\n/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */\n#define Scale_Bit 0x10\n#define n_bigtens 5\n#else\n#ifdef IBM\nbigtens[] = { 1e16, 1e32, 1e64 };\nstatic const double tinytens[] = { 1e-16, 1e-32, 1e-64 };\n#define n_bigtens 3\n#else\nbigtens[] = { 1e16, 1e32 };\nstatic const double tinytens[] = { 1e-16, 1e-32 };\n#define n_bigtens 2\n#endif\n#endif\n\n#ifndef IEEE_Arith\n#undef INFNAN_CHECK\n#endif\n\n#ifdef INFNAN_CHECK\n\n#ifndef NAN_WORD0\n#define NAN_WORD0 0x7ff80000\n#endif\n\n#ifndef NAN_WORD1\n#define NAN_WORD1 0\n#endif\n\nstatic int\nmatch(const char **sp, char *t)\n{\n    int c, d;\n    const char *s = *sp;\n\n    while (d = *t++) {\n        if ((c = *++s) >= 'A' && c <= 'Z')\n            c += 'a' - 'A';\n        if (c != d)\n            return 0;\n    }\n    *sp = s + 1;\n    return 1;\n}\n\n#ifndef No_Hex_NaN\nstatic void\nhexnan(double *rvp, const char **sp)\n{\n    ULong c, x[2];\n    const char *s;\n    int havedig, udx0, xshift;\n\n    x[0] = x[1] = 0;\n    havedig = xshift = 0;\n    udx0 = 1;\n    s = *sp;\n    while (c = *(const unsigned char*)++s) {\n        if (c >= '0' && c <= '9')\n            c -= '0';\n        else if (c >= 'a' && c <= 'f')\n            c += 10 - 'a';\n        else if (c >= 'A' && c <= 'F')\n            c += 10 - 'A';\n        else if (c <= ' ') {\n            if (udx0 && havedig) {\n                udx0 = 0;\n                xshift = 1;\n            }\n            continue;\n        }\n        else if (/*(*/ c == ')' && havedig) {\n            *sp = s + 1;\n            break;\n        }\n        else\n            return; /* invalid form: don't change *sp */\n        havedig = 1;\n        if (xshift) {\n            xshift = 0;\n            x[0] = x[1];\n            x[1] = 0;\n        }\n        if (udx0)\n            x[0] = (x[0] << 4) | (x[1] >> 28);\n        x[1] = (x[1] << 4) | c;\n    }\n    if ((x[0] &= 0xfffff) || x[1]) {\n        word0(*rvp) = Exp_mask | x[0];\n        word1(*rvp) = x[1];\n    }\n}\n#endif /*No_Hex_NaN*/\n#endif /* INFNAN_CHECK */\n\ndouble\nruby_strtod(const char *s00, char **se)\n{\n#ifdef Avoid_Underflow\n    int scale;\n#endif\n    int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,\n         e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;\n    const char *s, *s0, *s1;\n    double aadj, adj;\n    double_u aadj1, rv, rv0;\n    Long L;\n    ULong y, z;\n    Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;\n#ifdef SET_INEXACT\n    int inexact, oldinexact;\n#endif\n#ifdef Honor_FLT_ROUNDS\n    int rounding;\n#endif\n#ifdef USE_LOCALE\n    const char *s2;\n#endif\n\n    errno = 0;\n    sign = nz0 = nz = 0;\n    dval(rv) = 0.;\n    for (s = s00;;s++)\n        switch (*s) {\n          case '-':\n            sign = 1;\n            /* no break */\n          case '+':\n            if (*++s)\n                goto break2;\n            /* no break */\n          case 0:\n            goto ret0;\n          case '\\t':\n          case '\\n':\n          case '\\v':\n          case '\\f':\n          case '\\r':\n          case ' ':\n            continue;\n          default:\n            goto break2;\n        }\nbreak2:\n    if (*s == '0') {\n        nz0 = 1;\n        while (*++s == '0') ;\n        if (!*s)\n            goto ret;\n    }\n    s0 = s;\n    y = z = 0;\n    for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)\n        if (nd < 9)\n            y = 10*y + c - '0';\n        else if (nd < 16)\n            z = 10*z + c - '0';\n    nd0 = nd;\n#ifdef USE_LOCALE\n    s1 = localeconv()->decimal_point;\n    if (c == *s1) {\n        c = '.';\n        if (*++s1) {\n            s2 = s;\n            for (;;) {\n                if (*++s2 != *s1) {\n                    c = 0;\n                    break;\n                }\n                if (!*++s1) {\n                    s = s2;\n                    break;\n                }\n            }\n        }\n    }\n#endif\n    if (c == '.') {\n        if (!ISDIGIT(s[1]))\n            goto dig_done;\n        c = *++s;\n        if (!nd) {\n            for (; c == '0'; c = *++s)\n                nz++;\n            if (c > '0' && c <= '9') {\n                s0 = s;\n                nf += nz;\n                nz = 0;\n                goto have_dig;\n            }\n            goto dig_done;\n        }\n        for (; c >= '0' && c <= '9'; c = *++s) {\nhave_dig:\n            nz++;\n            if (c -= '0') {\n                nf += nz;\n                for (i = 1; i < nz; i++)\n                    if (nd++ < 9)\n                        y *= 10;\n                    else if (nd <= DBL_DIG + 1)\n                        z *= 10;\n                if (nd++ < 9)\n                    y = 10*y + c;\n                else if (nd <= DBL_DIG + 1)\n                    z = 10*z + c;\n                nz = 0;\n            }\n        }\n    }\ndig_done:\n    e = 0;\n    if (c == 'e' || c == 'E') {\n        if (!nd && !nz && !nz0) {\n            goto ret0;\n        }\n        s00 = s;\n        esign = 0;\n        switch (c = *++s) {\n          case '-':\n            esign = 1;\n          case '+':\n            c = *++s;\n        }\n        if (c >= '0' && c <= '9') {\n            while (c == '0')\n                c = *++s;\n            if (c > '0' && c <= '9') {\n                L = c - '0';\n                s1 = s;\n                while ((c = *++s) >= '0' && c <= '9')\n                    L = 10*L + c - '0';\n                if (s - s1 > 8 || L > 19999)\n                    /* Avoid confusion from exponents\n                     * so large that e might overflow.\n                     */\n                    e = 19999; /* safe for 16 bit ints */\n                else\n                    e = (int)L;\n                if (esign)\n                    e = -e;\n            }\n            else\n                e = 0;\n        }\n        else\n            s = s00;\n    }\n    if (!nd) {\n        if (!nz && !nz0) {\n#ifdef INFNAN_CHECK\n            /* Check for Nan and Infinity */\n            switch (c) {\n              case 'i':\n              case 'I':\n                if (match(&s,\"nf\")) {\n                    --s;\n                    if (!match(&s,\"inity\"))\n                        ++s;\n                    word0(rv) = 0x7ff00000;\n                    word1(rv) = 0;\n                    goto ret;\n                }\n                break;\n              case 'n':\n              case 'N':\n                if (match(&s, \"an\")) {\n                    word0(rv) = NAN_WORD0;\n                    word1(rv) = NAN_WORD1;\n#ifndef No_Hex_NaN\n                    if (*s == '(') /*)*/\n                        hexnan(&rv, &s);\n#endif\n                    goto ret;\n                }\n            }\n#endif /* INFNAN_CHECK */\nret0:\n            s = s00;\n            sign = 0;\n        }\n        goto ret;\n    }\n    e1 = e -= nf;\n\n    /* Now we have nd0 digits, starting at s0, followed by a\n     * decimal point, followed by nd-nd0 digits.  The number we're\n     * after is the integer represented by those digits times\n     * 10**e */\n\n    if (!nd0)\n        nd0 = nd;\n    k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;\n    dval(rv) = y;\n    if (k > 9) {\n#ifdef SET_INEXACT\n        if (k > DBL_DIG)\n            oldinexact = get_inexact();\n#endif\n        dval(rv) = tens[k - 9] * dval(rv) + z;\n    }\n    bd0 = bb = bd = bs = delta = 0;\n    if (nd <= DBL_DIG\n#ifndef RND_PRODQUOT\n#ifndef Honor_FLT_ROUNDS\n        && Flt_Rounds == 1\n#endif\n#endif\n    ) {\n        if (!e)\n            goto ret;\n        if (e > 0) {\n            if (e <= Ten_pmax) {\n#ifdef VAX\n                goto vax_ovfl_check;\n#else\n#ifdef Honor_FLT_ROUNDS\n                /* round correctly FLT_ROUNDS = 2 or 3 */\n                if (sign) {\n                    rv = -rv;\n                    sign = 0;\n                }\n#endif\n                /* rv = */ rounded_product(dval(rv), tens[e]);\n                goto ret;\n#endif\n            }\n            i = DBL_DIG - nd;\n            if (e <= Ten_pmax + i) {\n                /* A fancier test would sometimes let us do\n                 * this for larger i values.\n                 */\n#ifdef Honor_FLT_ROUNDS\n                /* round correctly FLT_ROUNDS = 2 or 3 */\n                if (sign) {\n                    rv = -rv;\n                    sign = 0;\n                }\n#endif\n                e -= i;\n                dval(rv) *= tens[i];\n#ifdef VAX\n                /* VAX exponent range is so narrow we must\n                 * worry about overflow here...\n                 */\nvax_ovfl_check:\n                word0(rv) -= P*Exp_msk1;\n                /* rv = */ rounded_product(dval(rv), tens[e]);\n                if ((word0(rv) & Exp_mask)\n                        > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))\n                    goto ovfl;\n                word0(rv) += P*Exp_msk1;\n#else\n                /* rv = */ rounded_product(dval(rv), tens[e]);\n#endif\n                goto ret;\n            }\n        }\n#ifndef Inaccurate_Divide\n        else if (e >= -Ten_pmax) {\n#ifdef Honor_FLT_ROUNDS\n            /* round correctly FLT_ROUNDS = 2 or 3 */\n            if (sign) {\n                rv = -rv;\n                sign = 0;\n            }\n#endif\n            /* rv = */ rounded_quotient(dval(rv), tens[-e]);\n            goto ret;\n        }\n#endif\n    }\n    e1 += nd - k;\n\n#ifdef IEEE_Arith\n#ifdef SET_INEXACT\n    inexact = 1;\n    if (k <= DBL_DIG)\n        oldinexact = get_inexact();\n#endif\n#ifdef Avoid_Underflow\n    scale = 0;\n#endif\n#ifdef Honor_FLT_ROUNDS\n    if ((rounding = Flt_Rounds) >= 2) {\n        if (sign)\n            rounding = rounding == 2 ? 0 : 2;\n        else\n            if (rounding != 2)\n                rounding = 0;\n    }\n#endif\n#endif /*IEEE_Arith*/\n\n    /* Get starting approximation = rv * 10**e1 */\n\n    if (e1 > 0) {\n        if ((i = e1 & 15) != 0)\n            dval(rv) *= tens[i];\n        if (e1 &= ~15) {\n            if (e1 > DBL_MAX_10_EXP) {\novfl:\n#ifndef NO_ERRNO\n                errno = ERANGE;\n#endif\n                /* Can't trust HUGE_VAL */\n#ifdef IEEE_Arith\n#ifdef Honor_FLT_ROUNDS\n                switch (rounding) {\n                  case 0: /* toward 0 */\n                  case 3: /* toward -infinity */\n                    word0(rv) = Big0;\n                    word1(rv) = Big1;\n                    break;\n                  default:\n                    word0(rv) = Exp_mask;\n                    word1(rv) = 0;\n                }\n#else /*Honor_FLT_ROUNDS*/\n                word0(rv) = Exp_mask;\n                word1(rv) = 0;\n#endif /*Honor_FLT_ROUNDS*/\n#ifdef SET_INEXACT\n                /* set overflow bit */\n                dval(rv0) = 1e300;\n                dval(rv0) *= dval(rv0);\n#endif\n#else /*IEEE_Arith*/\n                word0(rv) = Big0;\n                word1(rv) = Big1;\n#endif /*IEEE_Arith*/\n                if (bd0)\n                    goto retfree;\n                goto ret;\n            }\n            e1 >>= 4;\n            for (j = 0; e1 > 1; j++, e1 >>= 1)\n                if (e1 & 1)\n                    dval(rv) *= bigtens[j];\n            /* The last multiplication could overflow. */\n            word0(rv) -= P*Exp_msk1;\n            dval(rv) *= bigtens[j];\n            if ((z = word0(rv) & Exp_mask)\n                    > Exp_msk1*(DBL_MAX_EXP+Bias-P))\n                goto ovfl;\n            if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {\n                /* set to largest number */\n                /* (Can't trust DBL_MAX) */\n                word0(rv) = Big0;\n                word1(rv) = Big1;\n            }\n            else\n                word0(rv) += P*Exp_msk1;\n        }\n    }\n    else if (e1 < 0) {\n        e1 = -e1;\n        if ((i = e1 & 15) != 0)\n            dval(rv) /= tens[i];\n        if (e1 >>= 4) {\n            if (e1 >= 1 << n_bigtens)\n                goto undfl;\n#ifdef Avoid_Underflow\n            if (e1 & Scale_Bit)\n                scale = 2*P;\n            for (j = 0; e1 > 0; j++, e1 >>= 1)\n                if (e1 & 1)\n                    dval(rv) *= tinytens[j];\n            if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)\n                    >> Exp_shift)) > 0) {\n                /* scaled rv is denormal; zap j low bits */\n                if (j >= 32) {\n                    word1(rv) = 0;\n                    if (j >= 53)\n                        word0(rv) = (P+2)*Exp_msk1;\n                    else\n                        word0(rv) &= 0xffffffff << (j-32);\n                }\n                else\n                    word1(rv) &= 0xffffffff << j;\n            }\n#else\n            for (j = 0; e1 > 1; j++, e1 >>= 1)\n                if (e1 & 1)\n                    dval(rv) *= tinytens[j];\n            /* The last multiplication could underflow. */\n            dval(rv0) = dval(rv);\n            dval(rv) *= tinytens[j];\n            if (!dval(rv)) {\n                dval(rv) = 2.*dval(rv0);\n                dval(rv) *= tinytens[j];\n#endif\n                if (!dval(rv)) {\nundfl:\n                    dval(rv) = 0.;\n#ifndef NO_ERRNO\n                    errno = ERANGE;\n#endif\n                    if (bd0)\n                        goto retfree;\n                    goto ret;\n                }\n#ifndef Avoid_Underflow\n                word0(rv) = Tiny0;\n                word1(rv) = Tiny1;\n                /* The refinement below will clean\n                 * this approximation up.\n                 */\n            }\n#endif\n        }\n    }\n\n    /* Now the hard part -- adjusting rv to the correct value.*/\n\n    /* Put digits into bd: true value = bd * 10^e */\n\n    bd0 = s2b(s0, nd0, nd, y);\n\n    for (;;) {\n        bd = Balloc(bd0->k);\n        Bcopy(bd, bd0);\n        bb = d2b(dval(rv), &bbe, &bbbits);  /* rv = bb * 2^bbe */\n        bs = i2b(1);\n\n        if (e >= 0) {\n            bb2 = bb5 = 0;\n            bd2 = bd5 = e;\n        }\n        else {\n            bb2 = bb5 = -e;\n            bd2 = bd5 = 0;\n        }\n        if (bbe >= 0)\n            bb2 += bbe;\n        else\n            bd2 -= bbe;\n        bs2 = bb2;\n#ifdef Honor_FLT_ROUNDS\n        if (rounding != 1)\n            bs2++;\n#endif\n#ifdef Avoid_Underflow\n        j = bbe - scale;\n        i = j + bbbits - 1; /* logb(rv) */\n        if (i < Emin)   /* denormal */\n            j += P - Emin;\n        else\n            j = P + 1 - bbbits;\n#else /*Avoid_Underflow*/\n#ifdef Sudden_Underflow\n#ifdef IBM\n        j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);\n#else\n        j = P + 1 - bbbits;\n#endif\n#else /*Sudden_Underflow*/\n        j = bbe;\n        i = j + bbbits - 1; /* logb(rv) */\n        if (i < Emin)   /* denormal */\n            j += P - Emin;\n        else\n            j = P + 1 - bbbits;\n#endif /*Sudden_Underflow*/\n#endif /*Avoid_Underflow*/\n        bb2 += j;\n        bd2 += j;\n#ifdef Avoid_Underflow\n        bd2 += scale;\n#endif\n        i = bb2 < bd2 ? bb2 : bd2;\n        if (i > bs2)\n            i = bs2;\n        if (i > 0) {\n            bb2 -= i;\n            bd2 -= i;\n            bs2 -= i;\n        }\n        if (bb5 > 0) {\n            bs = pow5mult(bs, bb5);\n            bb1 = mult(bs, bb);\n            Bfree(bb);\n            bb = bb1;\n        }\n        if (bb2 > 0)\n            bb = lshift(bb, bb2);\n        if (bd5 > 0)\n            bd = pow5mult(bd, bd5);\n        if (bd2 > 0)\n            bd = lshift(bd, bd2);\n        if (bs2 > 0)\n            bs = lshift(bs, bs2);\n        delta = diff(bb, bd);\n        dsign = delta->sign;\n        delta->sign = 0;\n        i = cmp(delta, bs);\n#ifdef Honor_FLT_ROUNDS\n        if (rounding != 1) {\n            if (i < 0) {\n                /* Error is less than an ulp */\n                if (!delta->x[0] && delta->wds <= 1) {\n                    /* exact */\n#ifdef SET_INEXACT\n                    inexact = 0;\n#endif\n                    break;\n                }\n                if (rounding) {\n                    if (dsign) {\n                        adj = 1.;\n                        goto apply_adj;\n                    }\n                }\n                else if (!dsign) {\n                    adj = -1.;\n                    if (!word1(rv)\n                     && !(word0(rv) & Frac_mask)) {\n                        y = word0(rv) & Exp_mask;\n#ifdef Avoid_Underflow\n                        if (!scale || y > 2*P*Exp_msk1)\n#else\n                        if (y)\n#endif\n                        {\n                            delta = lshift(delta,Log2P);\n                            if (cmp(delta, bs) <= 0)\n                                adj = -0.5;\n                        }\n                    }\napply_adj:\n#ifdef Avoid_Underflow\n                    if (scale && (y = word0(rv) & Exp_mask)\n                            <= 2*P*Exp_msk1)\n                        word0(adj) += (2*P+1)*Exp_msk1 - y;\n#else\n#ifdef Sudden_Underflow\n                    if ((word0(rv) & Exp_mask) <=\n                            P*Exp_msk1) {\n                        word0(rv) += P*Exp_msk1;\n                        dval(rv) += adj*ulp(dval(rv));\n                        word0(rv) -= P*Exp_msk1;\n                    }\n                    else\n#endif /*Sudden_Underflow*/\n#endif /*Avoid_Underflow*/\n                    dval(rv) += adj*ulp(dval(rv));\n                }\n                break;\n            }\n            adj = ratio(delta, bs);\n            if (adj < 1.)\n                adj = 1.;\n            if (adj <= 0x7ffffffe) {\n                /* adj = rounding ? ceil(adj) : floor(adj); */\n                y = adj;\n                if (y != adj) {\n                    if (!((rounding>>1) ^ dsign))\n                        y++;\n                    adj = y;\n                }\n            }\n#ifdef Avoid_Underflow\n            if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)\n                word0(adj) += (2*P+1)*Exp_msk1 - y;\n#else\n#ifdef Sudden_Underflow\n            if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {\n                word0(rv) += P*Exp_msk1;\n                adj *= ulp(dval(rv));\n                if (dsign)\n                    dval(rv) += adj;\n                else\n                    dval(rv) -= adj;\n                word0(rv) -= P*Exp_msk1;\n                goto cont;\n            }\n#endif /*Sudden_Underflow*/\n#endif /*Avoid_Underflow*/\n            adj *= ulp(dval(rv));\n            if (dsign)\n                dval(rv) += adj;\n            else\n                dval(rv) -= adj;\n            goto cont;\n        }\n#endif /*Honor_FLT_ROUNDS*/\n\n        if (i < 0) {\n            /* Error is less than half an ulp -- check for\n             * special case of mantissa a power of two.\n             */\n            if (dsign || word1(rv) || word0(rv) & Bndry_mask\n#ifdef IEEE_Arith\n#ifdef Avoid_Underflow\n                || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1\n#else\n                || (word0(rv) & Exp_mask) <= Exp_msk1\n#endif\n#endif\n            ) {\n#ifdef SET_INEXACT\n                if (!delta->x[0] && delta->wds <= 1)\n                    inexact = 0;\n#endif\n                break;\n            }\n            if (!delta->x[0] && delta->wds <= 1) {\n                /* exact result */\n#ifdef SET_INEXACT\n                inexact = 0;\n#endif\n                break;\n            }\n            delta = lshift(delta,Log2P);\n            if (cmp(delta, bs) > 0)\n                goto drop_down;\n            break;\n        }\n        if (i == 0) {\n            /* exactly half-way between */\n            if (dsign) {\n                if ((word0(rv) & Bndry_mask1) == Bndry_mask1\n                        &&  word1(rv) == (\n#ifdef Avoid_Underflow\n                        (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)\n                        ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :\n#endif\n                        0xffffffff)) {\n                    /*boundary case -- increment exponent*/\n                    word0(rv) = (word0(rv) & Exp_mask)\n                                + Exp_msk1\n#ifdef IBM\n                                | Exp_msk1 >> 4\n#endif\n                    ;\n                    word1(rv) = 0;\n#ifdef Avoid_Underflow\n                    dsign = 0;\n#endif\n                    break;\n                }\n            }\n            else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {\ndrop_down:\n                /* boundary case -- decrement exponent */\n#ifdef Sudden_Underflow /*{{*/\n                L = word0(rv) & Exp_mask;\n#ifdef IBM\n                if (L <  Exp_msk1)\n#else\n#ifdef Avoid_Underflow\n                if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))\n#else\n                if (L <= Exp_msk1)\n#endif /*Avoid_Underflow*/\n#endif /*IBM*/\n                    goto undfl;\n                L -= Exp_msk1;\n#else /*Sudden_Underflow}{*/\n#ifdef Avoid_Underflow\n                if (scale) {\n                    L = word0(rv) & Exp_mask;\n                    if (L <= (2*P+1)*Exp_msk1) {\n                        if (L > (P+2)*Exp_msk1)\n                            /* round even ==> */\n                            /* accept rv */\n                            break;\n                        /* rv = smallest denormal */\n                        goto undfl;\n                    }\n                }\n#endif /*Avoid_Underflow*/\n                L = (word0(rv) & Exp_mask) - Exp_msk1;\n#endif /*Sudden_Underflow}}*/\n                word0(rv) = L | Bndry_mask1;\n                word1(rv) = 0xffffffff;\n#ifdef IBM\n                goto cont;\n#else\n                break;\n#endif\n            }\n#ifndef ROUND_BIASED\n            if (!(word1(rv) & LSB))\n                break;\n#endif\n            if (dsign)\n                dval(rv) += ulp(dval(rv));\n#ifndef ROUND_BIASED\n            else {\n                dval(rv) -= ulp(dval(rv));\n#ifndef Sudden_Underflow\n                if (!dval(rv))\n                    goto undfl;\n#endif\n            }\n#ifdef Avoid_Underflow\n            dsign = 1 - dsign;\n#endif\n#endif\n            break;\n        }\n        if ((aadj = ratio(delta, bs)) <= 2.) {\n            if (dsign)\n                aadj = dval(aadj1) = 1.;\n            else if (word1(rv) || word0(rv) & Bndry_mask) {\n#ifndef Sudden_Underflow\n                if (word1(rv) == Tiny1 && !word0(rv))\n                    goto undfl;\n#endif\n                aadj = 1.;\n                dval(aadj1) = -1.;\n            }\n            else {\n                /* special case -- power of FLT_RADIX to be */\n                /* rounded down... */\n\n                if (aadj < 2./FLT_RADIX)\n                    aadj = 1./FLT_RADIX;\n                else\n                    aadj *= 0.5;\n                dval(aadj1) = -aadj;\n            }\n        }\n        else {\n            aadj *= 0.5;\n            dval(aadj1) = dsign ? aadj : -aadj;\n#ifdef Check_FLT_ROUNDS\n            switch (Rounding) {\n              case 2: /* towards +infinity */\n                aadj1 -= 0.5;\n                break;\n              case 0: /* towards 0 */\n              case 3: /* towards -infinity */\n                aadj1 += 0.5;\n            }\n#else\n            if (Flt_Rounds == 0)\n                dval(aadj1) += 0.5;\n#endif /*Check_FLT_ROUNDS*/\n        }\n        y = word0(rv) & Exp_mask;\n\n        /* Check for overflow */\n\n        if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {\n            dval(rv0) = dval(rv);\n            word0(rv) -= P*Exp_msk1;\n            adj = dval(aadj1) * ulp(dval(rv));\n            dval(rv) += adj;\n            if ((word0(rv) & Exp_mask) >=\n                    Exp_msk1*(DBL_MAX_EXP+Bias-P)) {\n                if (word0(rv0) == Big0 && word1(rv0) == Big1)\n                    goto ovfl;\n                word0(rv) = Big0;\n                word1(rv) = Big1;\n                goto cont;\n            }\n            else\n                word0(rv) += P*Exp_msk1;\n        }\n        else {\n#ifdef Avoid_Underflow\n            if (scale && y <= 2*P*Exp_msk1) {\n                if (aadj <= 0x7fffffff) {\n                    if ((z = aadj) <= 0)\n                        z = 1;\n                    aadj = z;\n                    dval(aadj1) = dsign ? aadj : -aadj;\n                }\n                word0(aadj1) += (2*P+1)*Exp_msk1 - y;\n            }\n            adj = dval(aadj1) * ulp(dval(rv));\n            dval(rv) += adj;\n#else\n#ifdef Sudden_Underflow\n            if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {\n                dval(rv0) = dval(rv);\n                word0(rv) += P*Exp_msk1;\n                adj = aadj1 * ulp(dval(rv));\n                dval(rv) += adj;\n#ifdef IBM\n                if ((word0(rv) & Exp_mask) <  P*Exp_msk1)\n#else\n                if ((word0(rv) & Exp_mask) <= P*Exp_msk1)\n#endif\n                {\n                    if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1)\n                        goto undfl;\n                    word0(rv) = Tiny0;\n                    word1(rv) = Tiny1;\n                    goto cont;\n                }\n                else\n                    word0(rv) -= P*Exp_msk1;\n            }\n            else {\n                adj = aadj1 * ulp(dval(rv));\n                dval(rv) += adj;\n            }\n#else /*Sudden_Underflow*/\n            /* Compute adj so that the IEEE rounding rules will\n             * correctly round rv + adj in some half-way cases.\n             * If rv * ulp(rv) is denormalized (i.e.,\n             * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid\n             * trouble from bits lost to denormalization;\n             * example: 1.2e-307 .\n             */\n            if (y <= (P-1)*Exp_msk1 && aadj > 1.) {\n                aadj1 = (double)(int)(aadj + 0.5);\n                if (!dsign)\n                    aadj1 = -aadj1;\n            }\n            adj = aadj1 * ulp(dval(rv));\n            dval(rv) += adj;\n#endif /*Sudden_Underflow*/\n#endif /*Avoid_Underflow*/\n        }\n        z = word0(rv) & Exp_mask;\n#ifndef SET_INEXACT\n#ifdef Avoid_Underflow\n        if (!scale)\n#endif\n        if (y == z) {\n            /* Can we stop now? */\n            L = (Long)aadj;\n            aadj -= L;\n            /* The tolerances below are conservative. */\n            if (dsign || word1(rv) || word0(rv) & Bndry_mask) {\n                if (aadj < .4999999 || aadj > .5000001)\n                    break;\n            }\n            else if (aadj < .4999999/FLT_RADIX)\n                break;\n        }\n#endif\ncont:\n        Bfree(bb);\n        Bfree(bd);\n        Bfree(bs);\n        Bfree(delta);\n    }\n#ifdef SET_INEXACT\n    if (inexact) {\n        if (!oldinexact) {\n            word0(rv0) = Exp_1 + (70 << Exp_shift);\n            word1(rv0) = 0;\n            dval(rv0) += 1.;\n        }\n    }\n    else if (!oldinexact)\n        clear_inexact();\n#endif\n#ifdef Avoid_Underflow\n    if (scale) {\n        word0(rv0) = Exp_1 - 2*P*Exp_msk1;\n        word1(rv0) = 0;\n        dval(rv) *= dval(rv0);\n#ifndef NO_ERRNO\n        /* try to avoid the bug of testing an 8087 register value */\n        if (word0(rv) == 0 && word1(rv) == 0)\n            errno = ERANGE;\n#endif\n    }\n#endif /* Avoid_Underflow */\n#ifdef SET_INEXACT\n    if (inexact && !(word0(rv) & Exp_mask)) {\n        /* set underflow bit */\n        dval(rv0) = 1e-300;\n        dval(rv0) *= dval(rv0);\n    }\n#endif\nretfree:\n    Bfree(bb);\n    Bfree(bd);\n    Bfree(bs);\n    Bfree(bd0);\n    Bfree(delta);\nret:\n    if (se)\n        *se = (char *)s;\n    return sign ? -dval(rv) : dval(rv);\n}\n\nstatic int\nquorem(Bigint *b, Bigint *S)\n{\n    int n;\n    ULong *bx, *bxe, q, *sx, *sxe;\n#ifdef ULLong\n    ULLong borrow, carry, y, ys;\n#else\n    ULong borrow, carry, y, ys;\n#ifdef Pack_32\n    ULong si, z, zs;\n#endif\n#endif\n\n    n = S->wds;\n#ifdef DEBUG\n    /*debug*/ if (b->wds > n)\n    /*debug*/   Bug(\"oversize b in quorem\");\n#endif\n    if (b->wds < n)\n        return 0;\n    sx = S->x;\n    sxe = sx + --n;\n    bx = b->x;\n    bxe = bx + n;\n    q = *bxe / (*sxe + 1);  /* ensure q <= true quotient */\n#ifdef DEBUG\n    /*debug*/ if (q > 9)\n    /*debug*/   Bug(\"oversized quotient in quorem\");\n#endif\n    if (q) {\n        borrow = 0;\n        carry = 0;\n        do {\n#ifdef ULLong\n            ys = *sx++ * (ULLong)q + carry;\n            carry = ys >> 32;\n            y = *bx - (ys & FFFFFFFF) - borrow;\n            borrow = y >> 32 & (ULong)1;\n            *bx++ = y & FFFFFFFF;\n#else\n#ifdef Pack_32\n            si = *sx++;\n            ys = (si & 0xffff) * q + carry;\n            zs = (si >> 16) * q + (ys >> 16);\n            carry = zs >> 16;\n            y = (*bx & 0xffff) - (ys & 0xffff) - borrow;\n            borrow = (y & 0x10000) >> 16;\n            z = (*bx >> 16) - (zs & 0xffff) - borrow;\n            borrow = (z & 0x10000) >> 16;\n            Storeinc(bx, z, y);\n#else\n            ys = *sx++ * q + carry;\n            carry = ys >> 16;\n            y = *bx - (ys & 0xffff) - borrow;\n            borrow = (y & 0x10000) >> 16;\n            *bx++ = y & 0xffff;\n#endif\n#endif\n        } while (sx <= sxe);\n        if (!*bxe) {\n            bx = b->x;\n            while (--bxe > bx && !*bxe)\n                --n;\n            b->wds = n;\n        }\n    }\n    if (cmp(b, S) >= 0) {\n        q++;\n        borrow = 0;\n        carry = 0;\n        bx = b->x;\n        sx = S->x;\n        do {\n#ifdef ULLong\n            ys = *sx++ + carry;\n            carry = ys >> 32;\n            y = *bx - (ys & FFFFFFFF) - borrow;\n            borrow = y >> 32 & (ULong)1;\n            *bx++ = y & FFFFFFFF;\n#else\n#ifdef Pack_32\n            si = *sx++;\n            ys = (si & 0xffff) + carry;\n            zs = (si >> 16) + (ys >> 16);\n            carry = zs >> 16;\n            y = (*bx & 0xffff) - (ys & 0xffff) - borrow;\n            borrow = (y & 0x10000) >> 16;\n            z = (*bx >> 16) - (zs & 0xffff) - borrow;\n            borrow = (z & 0x10000) >> 16;\n            Storeinc(bx, z, y);\n#else\n            ys = *sx++ + carry;\n            carry = ys >> 16;\n            y = *bx - (ys & 0xffff) - borrow;\n            borrow = (y & 0x10000) >> 16;\n            *bx++ = y & 0xffff;\n#endif\n#endif\n        } while (sx <= sxe);\n        bx = b->x;\n        bxe = bx + n;\n        if (!*bxe) {\n            while (--bxe > bx && !*bxe)\n                --n;\n            b->wds = n;\n        }\n    }\n    return q;\n}\n\n#ifndef MULTIPLE_THREADS\nstatic char *dtoa_result;\n#endif\n\nstatic char *\nrv_alloc(int i)\n{\n    int j, k, *r;\n\n    j = sizeof(ULong);\n    for (k = 0;\n            sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;\n            j <<= 1)\n        k++;\n    r = (int*)Balloc(k);\n    *r = k;\n    return\n#ifndef MULTIPLE_THREADS\n        dtoa_result =\n#endif\n        (char *)(r+1);\n}\n\nstatic char *\nnrv_alloc(const char *s, char **rve, int n)\n{\n    char *rv, *t;\n\n    t = rv = rv_alloc(n+1);\n    while ((*t = *s++) != 0) t++;\n    if (rve)\n        *rve = t;\n    return rv;\n}\n\n#define rv_strdup(s, rve) nrv_alloc(s, rve, strlen(s)+1)\n\n/* freedtoa(s) must be used to free values s returned by dtoa\n * when MULTIPLE_THREADS is #defined.  It should be used in all cases,\n * but for consistency with earlier versions of dtoa, it is optional\n * when MULTIPLE_THREADS is not defined.\n */\n\nvoid\nfreedtoa(char *s)\n{\n    Bigint *b = (Bigint *)((int *)s - 1);\n    b->maxwds = 1 << (b->k = *(int*)b);\n    Bfree(b);\n#ifndef MULTIPLE_THREADS\n    if (s == dtoa_result)\n        dtoa_result = 0;\n#endif\n}\n\n/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.\n *\n * Inspired by \"How to Print Floating-Point Numbers Accurately\" by\n * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].\n *\n * Modifications:\n *  1. Rather than iterating, we use a simple numeric overestimate\n *     to determine k = floor(log10(d)).  We scale relevant\n *     quantities using O(log2(k)) rather than O(k) multiplications.\n *  2. For some modes > 2 (corresponding to ecvt and fcvt), we don't\n *     try to generate digits strictly left to right.  Instead, we\n *     compute with fewer bits and propagate the carry if necessary\n *     when rounding the final digit up.  This is often faster.\n *  3. Under the assumption that input will be rounded nearest,\n *     mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.\n *     That is, we allow equality in stopping tests when the\n *     round-nearest rule will give the same floating-point value\n *     as would satisfaction of the stopping test with strict\n *     inequality.\n *  4. We remove common factors of powers of 2 from relevant\n *     quantities.\n *  5. When converting floating-point integers less than 1e16,\n *     we use floating-point arithmetic rather than resorting\n *     to multiple-precision integers.\n *  6. When asked to produce fewer than 15 digits, we first try\n *     to get by with floating-point arithmetic; we resort to\n *     multiple-precision integer arithmetic only if we cannot\n *     guarantee that the floating-point calculation has given\n *     the correctly rounded result.  For k requested digits and\n *     \"uniformly\" distributed input, the probability is\n *     something like 10^(k-15) that we must resort to the Long\n *     calculation.\n */\n\nchar *\ndtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)\n{\n /* Arguments ndigits, decpt, sign are similar to those\n    of ecvt and fcvt; trailing zeros are suppressed from\n    the returned string.  If not null, *rve is set to point\n    to the end of the return value.  If d is +-Infinity or NaN,\n    then *decpt is set to 9999.\n\n    mode:\n        0 ==> shortest string that yields d when read in\n            and rounded to nearest.\n        1 ==> like 0, but with Steele & White stopping rule;\n            e.g. with IEEE P754 arithmetic , mode 0 gives\n            1e23 whereas mode 1 gives 9.999999999999999e22.\n        2 ==> max(1,ndigits) significant digits.  This gives a\n            return value similar to that of ecvt, except\n            that trailing zeros are suppressed.\n        3 ==> through ndigits past the decimal point.  This\n            gives a return value similar to that from fcvt,\n            except that trailing zeros are suppressed, and\n            ndigits can be negative.\n        4,5 ==> similar to 2 and 3, respectively, but (in\n            round-nearest mode) with the tests of mode 0 to\n            possibly return a shorter string that rounds to d.\n            With IEEE arithmetic and compilation with\n            -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same\n            as modes 2 and 3 when FLT_ROUNDS != 1.\n        6-9 ==> Debugging modes similar to mode - 4:  don't try\n            fast floating-point estimate (if applicable).\n\n        Values of mode other than 0-9 are treated as mode 0.\n\n        Sufficient space is allocated to the return value\n        to hold the suppressed trailing zeros.\n    */\n\n    int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,\n        j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,\n        spec_case, try_quick;\n    Long L;\n#ifndef Sudden_Underflow\n    int denorm;\n    ULong x;\n#endif\n    Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;\n    double ds;\n    double_u d, d2, eps;\n    char *s, *s0;\n#ifdef Honor_FLT_ROUNDS\n    int rounding;\n#endif\n#ifdef SET_INEXACT\n    int inexact, oldinexact;\n#endif\n\n    dval(d) = d_;\n\n#ifndef MULTIPLE_THREADS\n    if (dtoa_result) {\n        freedtoa(dtoa_result);\n        dtoa_result = 0;\n    }\n#endif\n\n    if (word0(d) & Sign_bit) {\n        /* set sign for everything, including 0's and NaNs */\n        *sign = 1;\n        word0(d) &= ~Sign_bit;  /* clear sign bit */\n    }\n    else\n        *sign = 0;\n\n#if defined(IEEE_Arith) + defined(VAX)\n#ifdef IEEE_Arith\n    if ((word0(d) & Exp_mask) == Exp_mask)\n#else\n    if (word0(d)  == 0x8000)\n#endif\n    {\n        /* Infinity or NaN */\n        *decpt = 9999;\n#ifdef IEEE_Arith\n        if (!word1(d) && !(word0(d) & 0xfffff))\n            return rv_strdup(\"Infinity\", rve);\n#endif\n        return rv_strdup(\"NaN\", rve);\n    }\n#endif\n#ifdef IBM\n    dval(d) += 0; /* normalize */\n#endif\n    if (!dval(d)) {\n        *decpt = 1;\n        return rv_strdup(\"0\", rve);\n    }\n\n#ifdef SET_INEXACT\n    try_quick = oldinexact = get_inexact();\n    inexact = 1;\n#endif\n#ifdef Honor_FLT_ROUNDS\n    if ((rounding = Flt_Rounds) >= 2) {\n        if (*sign)\n            rounding = rounding == 2 ? 0 : 2;\n        else\n            if (rounding != 2)\n                rounding = 0;\n    }\n#endif\n\n    b = d2b(dval(d), &be, &bbits);\n#ifdef Sudden_Underflow\n    i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));\n#else\n    if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {\n#endif\n        dval(d2) = dval(d);\n        word0(d2) &= Frac_mask1;\n        word0(d2) |= Exp_11;\n#ifdef IBM\n        if (j = 11 - hi0bits(word0(d2) & Frac_mask))\n            dval(d2) /= 1 << j;\n#endif\n\n        /* log(x)   ~=~ log(1.5) + (x-1.5)/1.5\n         * log10(x)  =  log(x) / log(10)\n         *      ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))\n         * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)\n         *\n         * This suggests computing an approximation k to log10(d) by\n         *\n         * k = (i - Bias)*0.301029995663981\n         *  + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );\n         *\n         * We want k to be too large rather than too small.\n         * The error in the first-order Taylor series approximation\n         * is in our favor, so we just round up the constant enough\n         * to compensate for any error in the multiplication of\n         * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,\n         * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,\n         * adding 1e-13 to the constant term more than suffices.\n         * Hence we adjust the constant term to 0.1760912590558.\n         * (We could get a more accurate k by invoking log10,\n         *  but this is probably not worthwhile.)\n         */\n\n        i -= Bias;\n#ifdef IBM\n        i <<= 2;\n        i += j;\n#endif\n#ifndef Sudden_Underflow\n        denorm = 0;\n    }\n    else {\n        /* d is denormalized */\n\n        i = bbits + be + (Bias + (P-1) - 1);\n        x = i > 32  ? word0(d) << (64 - i) | word1(d) >> (i - 32)\n\t    : word1(d) << (32 - i);\n        dval(d2) = x;\n        word0(d2) -= 31*Exp_msk1; /* adjust exponent */\n        i -= (Bias + (P-1) - 1) + 1;\n        denorm = 1;\n    }\n#endif\n    ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;\n    k = (int)ds;\n    if (ds < 0. && ds != k)\n        k--;    /* want k = floor(ds) */\n    k_check = 1;\n    if (k >= 0 && k <= Ten_pmax) {\n        if (dval(d) < tens[k])\n            k--;\n        k_check = 0;\n    }\n    j = bbits - i - 1;\n    if (j >= 0) {\n        b2 = 0;\n        s2 = j;\n    }\n    else {\n        b2 = -j;\n        s2 = 0;\n    }\n    if (k >= 0) {\n        b5 = 0;\n        s5 = k;\n        s2 += k;\n    }\n    else {\n        b2 -= k;\n        b5 = -k;\n        s5 = 0;\n    }\n    if (mode < 0 || mode > 9)\n        mode = 0;\n\n#ifndef SET_INEXACT\n#ifdef Check_FLT_ROUNDS\n    try_quick = Rounding == 1;\n#else\n    try_quick = 1;\n#endif\n#endif /*SET_INEXACT*/\n\n    if (mode > 5) {\n        mode -= 4;\n        try_quick = 0;\n    }\n    leftright = 1;\n    ilim = ilim1 = -1;\n    switch (mode) {\n      case 0:\n      case 1:\n        i = 18;\n        ndigits = 0;\n        break;\n      case 2:\n        leftright = 0;\n        /* no break */\n      case 4:\n        if (ndigits <= 0)\n            ndigits = 1;\n        ilim = ilim1 = i = ndigits;\n        break;\n      case 3:\n        leftright = 0;\n        /* no break */\n      case 5:\n        i = ndigits + k + 1;\n        ilim = i;\n        ilim1 = i - 1;\n        if (i <= 0)\n            i = 1;\n    }\n    s = s0 = rv_alloc(i+1);\n\n#ifdef Honor_FLT_ROUNDS\n    if (mode > 1 && rounding != 1)\n        leftright = 0;\n#endif\n\n    if (ilim >= 0 && ilim <= Quick_max && try_quick) {\n\n        /* Try to get by with floating-point arithmetic. */\n\n        i = 0;\n        dval(d2) = dval(d);\n        k0 = k;\n        ilim0 = ilim;\n        ieps = 2; /* conservative */\n        if (k > 0) {\n            ds = tens[k&0xf];\n            j = k >> 4;\n            if (j & Bletch) {\n                /* prevent overflows */\n                j &= Bletch - 1;\n                dval(d) /= bigtens[n_bigtens-1];\n                ieps++;\n            }\n            for (; j; j >>= 1, i++)\n                if (j & 1) {\n                    ieps++;\n                    ds *= bigtens[i];\n                }\n            dval(d) /= ds;\n        }\n        else if ((j1 = -k) != 0) {\n            dval(d) *= tens[j1 & 0xf];\n            for (j = j1 >> 4; j; j >>= 1, i++)\n                if (j & 1) {\n                    ieps++;\n                    dval(d) *= bigtens[i];\n                }\n        }\n        if (k_check && dval(d) < 1. && ilim > 0) {\n            if (ilim1 <= 0)\n                goto fast_failed;\n            ilim = ilim1;\n            k--;\n            dval(d) *= 10.;\n            ieps++;\n        }\n        dval(eps) = ieps*dval(d) + 7.;\n        word0(eps) -= (P-1)*Exp_msk1;\n        if (ilim == 0) {\n            S = mhi = 0;\n            dval(d) -= 5.;\n            if (dval(d) > dval(eps))\n                goto one_digit;\n            if (dval(d) < -dval(eps))\n                goto no_digits;\n            goto fast_failed;\n        }\n#ifndef No_leftright\n        if (leftright) {\n            /* Use Steele & White method of only\n             * generating digits needed.\n             */\n            dval(eps) = 0.5/tens[ilim-1] - dval(eps);\n            for (i = 0;;) {\n                L = dval(d);\n                dval(d) -= L;\n                *s++ = '0' + (int)L;\n                if (dval(d) < dval(eps))\n                    goto ret1;\n                if (1. - dval(d) < dval(eps))\n                    goto bump_up;\n                if (++i >= ilim)\n                    break;\n                dval(eps) *= 10.;\n                dval(d) *= 10.;\n            }\n        }\n        else {\n#endif\n            /* Generate ilim digits, then fix them up. */\n            dval(eps) *= tens[ilim-1];\n            for (i = 1;; i++, dval(d) *= 10.) {\n                L = (Long)(dval(d));\n                if (!(dval(d) -= L))\n                    ilim = i;\n                *s++ = '0' + (int)L;\n                if (i == ilim) {\n                    if (dval(d) > 0.5 + dval(eps))\n                        goto bump_up;\n                    else if (dval(d) < 0.5 - dval(eps)) {\n                        while (*--s == '0') ;\n                        s++;\n                        goto ret1;\n                    }\n                    break;\n                }\n            }\n#ifndef No_leftright\n        }\n#endif\nfast_failed:\n        s = s0;\n        dval(d) = dval(d2);\n        k = k0;\n        ilim = ilim0;\n    }\n\n    /* Do we have a \"small\" integer? */\n\n    if (be >= 0 && k <= Int_max) {\n        /* Yes. */\n        ds = tens[k];\n        if (ndigits < 0 && ilim <= 0) {\n            S = mhi = 0;\n            if (ilim < 0 || dval(d) <= 5*ds)\n                goto no_digits;\n            goto one_digit;\n        }\n        for (i = 1;; i++, dval(d) *= 10.) {\n            L = (Long)(dval(d) / ds);\n            dval(d) -= L*ds;\n#ifdef Check_FLT_ROUNDS\n            /* If FLT_ROUNDS == 2, L will usually be high by 1 */\n            if (dval(d) < 0) {\n                L--;\n                dval(d) += ds;\n            }\n#endif\n            *s++ = '0' + (int)L;\n            if (!dval(d)) {\n#ifdef SET_INEXACT\n                inexact = 0;\n#endif\n                break;\n            }\n            if (i == ilim) {\n#ifdef Honor_FLT_ROUNDS\n                if (mode > 1)\n                switch (rounding) {\n                  case 0: goto ret1;\n                  case 2: goto bump_up;\n                }\n#endif\n                dval(d) += dval(d);\n                if (dval(d) > ds || (dval(d) == ds && (L & 1))) {\nbump_up:\n                    while (*--s == '9')\n                        if (s == s0) {\n                            k++;\n                            *s = '0';\n                            break;\n                        }\n                    ++*s++;\n                }\n                break;\n            }\n        }\n        goto ret1;\n    }\n\n    m2 = b2;\n    m5 = b5;\n    if (leftright) {\n        i =\n#ifndef Sudden_Underflow\n            denorm ? be + (Bias + (P-1) - 1 + 1) :\n#endif\n#ifdef IBM\n            1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);\n#else\n            1 + P - bbits;\n#endif\n        b2 += i;\n        s2 += i;\n        mhi = i2b(1);\n    }\n    if (m2 > 0 && s2 > 0) {\n        i = m2 < s2 ? m2 : s2;\n        b2 -= i;\n        m2 -= i;\n        s2 -= i;\n    }\n    if (b5 > 0) {\n        if (leftright) {\n            if (m5 > 0) {\n                mhi = pow5mult(mhi, m5);\n                b1 = mult(mhi, b);\n                Bfree(b);\n                b = b1;\n            }\n            if ((j = b5 - m5) != 0)\n                b = pow5mult(b, j);\n        }\n        else\n            b = pow5mult(b, b5);\n    }\n    S = i2b(1);\n    if (s5 > 0)\n        S = pow5mult(S, s5);\n\n    /* Check for special case that d is a normalized power of 2. */\n\n    spec_case = 0;\n    if ((mode < 2 || leftright)\n#ifdef Honor_FLT_ROUNDS\n            && rounding == 1\n#endif\n    ) {\n        if (!word1(d) && !(word0(d) & Bndry_mask)\n#ifndef Sudden_Underflow\n            && word0(d) & (Exp_mask & ~Exp_msk1)\n#endif\n        ) {\n            /* The special case */\n            b2 += Log2P;\n            s2 += Log2P;\n            spec_case = 1;\n        }\n    }\n\n    /* Arrange for convenient computation of quotients:\n     * shift left if necessary so divisor has 4 leading 0 bits.\n     *\n     * Perhaps we should just compute leading 28 bits of S once\n     * and for all and pass them and a shift to quorem, so it\n     * can do shifts and ors to compute the numerator for q.\n     */\n#ifdef Pack_32\n    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)\n        i = 32 - i;\n#else\n    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0)\n        i = 16 - i;\n#endif\n    if (i > 4) {\n        i -= 4;\n        b2 += i;\n        m2 += i;\n        s2 += i;\n    }\n    else if (i < 4) {\n        i += 28;\n        b2 += i;\n        m2 += i;\n        s2 += i;\n    }\n    if (b2 > 0)\n        b = lshift(b, b2);\n    if (s2 > 0)\n        S = lshift(S, s2);\n    if (k_check) {\n        if (cmp(b,S) < 0) {\n            k--;\n            b = multadd(b, 10, 0);  /* we botched the k estimate */\n            if (leftright)\n                mhi = multadd(mhi, 10, 0);\n            ilim = ilim1;\n        }\n    }\n    if (ilim <= 0 && (mode == 3 || mode == 5)) {\n        if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {\n            /* no digits, fcvt style */\nno_digits:\n            k = -1 - ndigits;\n            goto ret;\n        }\none_digit:\n        *s++ = '1';\n        k++;\n        goto ret;\n    }\n    if (leftright) {\n        if (m2 > 0)\n            mhi = lshift(mhi, m2);\n\n        /* Compute mlo -- check for special case\n         * that d is a normalized power of 2.\n         */\n\n        mlo = mhi;\n        if (spec_case) {\n            mhi = Balloc(mhi->k);\n            Bcopy(mhi, mlo);\n            mhi = lshift(mhi, Log2P);\n        }\n\n        for (i = 1;;i++) {\n            dig = quorem(b,S) + '0';\n            /* Do we yet have the shortest decimal string\n             * that will round to d?\n             */\n            j = cmp(b, mlo);\n            delta = diff(S, mhi);\n            j1 = delta->sign ? 1 : cmp(b, delta);\n            Bfree(delta);\n#ifndef ROUND_BIASED\n            if (j1 == 0 && mode != 1 && !(word1(d) & 1)\n#ifdef Honor_FLT_ROUNDS\n                && rounding >= 1\n#endif\n            ) {\n                if (dig == '9')\n                    goto round_9_up;\n                if (j > 0)\n                    dig++;\n#ifdef SET_INEXACT\n                else if (!b->x[0] && b->wds <= 1)\n                    inexact = 0;\n#endif\n                *s++ = dig;\n                goto ret;\n            }\n#endif\n            if (j < 0 || (j == 0 && mode != 1\n#ifndef ROUND_BIASED\n                && !(word1(d) & 1)\n#endif\n            )) {\n                if (!b->x[0] && b->wds <= 1) {\n#ifdef SET_INEXACT\n                    inexact = 0;\n#endif\n                    goto accept_dig;\n                }\n#ifdef Honor_FLT_ROUNDS\n                if (mode > 1)\n                    switch (rounding) {\n                      case 0: goto accept_dig;\n                      case 2: goto keep_dig;\n                    }\n#endif /*Honor_FLT_ROUNDS*/\n                if (j1 > 0) {\n                    b = lshift(b, 1);\n                    j1 = cmp(b, S);\n                    if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9')\n                        goto round_9_up;\n                }\naccept_dig:\n                *s++ = dig;\n                goto ret;\n            }\n            if (j1 > 0) {\n#ifdef Honor_FLT_ROUNDS\n                if (!rounding)\n                    goto accept_dig;\n#endif\n                if (dig == '9') { /* possible if i == 1 */\nround_9_up:\n                    *s++ = '9';\n                    goto roundoff;\n                }\n                *s++ = dig + 1;\n                goto ret;\n            }\n#ifdef Honor_FLT_ROUNDS\nkeep_dig:\n#endif\n            *s++ = dig;\n            if (i == ilim)\n                break;\n            b = multadd(b, 10, 0);\n            if (mlo == mhi)\n                mlo = mhi = multadd(mhi, 10, 0);\n            else {\n                mlo = multadd(mlo, 10, 0);\n                mhi = multadd(mhi, 10, 0);\n            }\n        }\n    }\n    else\n        for (i = 1;; i++) {\n            *s++ = dig = quorem(b,S) + '0';\n            if (!b->x[0] && b->wds <= 1) {\n#ifdef SET_INEXACT\n                inexact = 0;\n#endif\n                goto ret;\n            }\n            if (i >= ilim)\n                break;\n            b = multadd(b, 10, 0);\n        }\n\n    /* Round off last digit */\n\n#ifdef Honor_FLT_ROUNDS\n    switch (rounding) {\n      case 0: goto trimzeros;\n      case 2: goto roundoff;\n    }\n#endif\n    b = lshift(b, 1);\n    j = cmp(b, S);\n    if (j > 0 || (j == 0 && (dig & 1))) {\n roundoff:\n        while (*--s == '9')\n            if (s == s0) {\n                k++;\n                *s++ = '1';\n                goto ret;\n            }\n        ++*s++;\n    }\n    else {\n        while (*--s == '0') ;\n        s++;\n    }\nret:\n    Bfree(S);\n    if (mhi) {\n        if (mlo && mlo != mhi)\n            Bfree(mlo);\n        Bfree(mhi);\n    }\nret1:\n#ifdef SET_INEXACT\n    if (inexact) {\n        if (!oldinexact) {\n            word0(d) = Exp_1 + (70 << Exp_shift);\n            word1(d) = 0;\n            dval(d) += 1.;\n        }\n    }\n    else if (!oldinexact)\n        clear_inexact();\n#endif\n    Bfree(b);\n    *s = 0;\n    *decpt = k + 1;\n    if (rve)\n        *rve = s;\n    return s0;\n}\n\nvoid\nruby_each_words(const char *str, void (*func)(const char*, int, void*), void *arg)\n{\n    const char *end;\n    int len;\n\n    if (!str) return;\n    for (; *str; str = end) {\n\twhile (ISSPACE(*str) || *str == ',') str++;\n\tif (!*str) break;\n\tend = str;\n\twhile (*end && !ISSPACE(*end) && *end != ',') end++;\n\tlen = end - str;\n\t(*func)(str, len, arg);\n    }\n}\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "util.h",
    "content": "/**********************************************************************\n\n  util.h -\n\n  $Author$\n  $Date$\n  created at: Thu Mar  9 11:55:53 JST 1995\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#ifndef UTIL_H\n#define UTIL_H\n\n#ifndef _\n#ifdef __cplusplus\n# ifndef  HAVE_PROTOTYPES\n#  define HAVE_PROTOTYPES 1\n# endif\n# ifndef  HAVE_STDARG_PROTOTYPES\n#  define HAVE_STDARG_PROTOTYPES 1\n# endif\n#endif\n#ifdef HAVE_PROTOTYPES\n# define _(args) args\n#else\n# define _(args) ()\n#endif\n#ifdef HAVE_STDARG_PROTOTYPES\n# define __(args) args\n#else\n# define __(args) ()\n#endif\n#endif\n\n#define scan_oct ruby_scan_oct\nunsigned long scan_oct _((const char*, int, int*));\n#define scan_hex ruby_scan_hex\nunsigned long scan_hex _((const char*, int, int*));\n\n#if defined(MSDOS) || defined(__CYGWIN32__) || defined(_WIN32)\nvoid ruby_add_suffix();\n#endif\n\nvoid ruby_qsort _((void*, const int, const int, int (*)(), void*));\n#define qsort(b,n,s,c,d) ruby_qsort(b,n,s,c,d)\n\nvoid ruby_setenv _((const char*, const char*));\nvoid ruby_unsetenv _((const char*));\n#undef setenv\n#undef unsetenv\n#define setenv(name,val) ruby_setenv(name,val)\n#define unsetenv(name,val) ruby_unsetenv(name);\n\nchar *ruby_strdup _((const char*));\nchar *strdup _((const char*));\n#undef strdup\n#define strdup(s) ruby_strdup(s)\n\nchar *ruby_getcwd _((void));\n#define my_getcwd() ruby_getcwd()\n\ndouble ruby_strtod _((const char*, char **));\n#undef strtod\n#define strtod(s,e) ruby_strtod(s,e)\n\n#endif /* UTIL_H */\n"
  },
  {
    "path": "variable.c",
    "content": "/**********************************************************************\n\n  variable.c -\n\n  $Author$\n  $Date$\n  created at: Tue Apr 19 23:55:15 JST 1994\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n  Copyright (C) 2000  Network Applied Communication Laboratory, Inc.\n  Copyright (C) 2000  Information-technology Promotion Agency, Japan\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"env.h\"\n#include \"node.h\"\n#include \"st.h\"\n#include \"util.h\"\n\nst_table *rb_global_tbl;\nst_table *rb_class_tbl;\nstatic ID autoload, classpath, tmp_classpath;\n\nvoid\nInit_var_tables()\n{\n    rb_global_tbl = st_init_numtable();\n    rb_class_tbl = st_init_numtable();\n    autoload = rb_intern(\"__autoload__\");\n    classpath = rb_intern(\"__classpath__\");\n    tmp_classpath = rb_intern(\"__tmp_classpath__\");\n}\n\nstruct fc_result {\n    ID name;\n    VALUE klass;\n    VALUE path;\n    VALUE track;\n    struct fc_result *prev;\n};\n\nstatic VALUE\nfc_path(fc, name)\n    struct fc_result *fc;\n    ID name;\n{\n    VALUE path, tmp;\n\n    path = rb_str_new2(rb_id2name(name));\n    while (fc) {\n\tif (fc->track == rb_cObject) break;\n\tif (ROBJECT(fc->track)->iv_tbl &&\n\t    st_lookup(ROBJECT(fc->track)->iv_tbl, classpath, &tmp)) {\n\t    tmp = rb_str_dup(tmp);\n\t    rb_str_cat2(tmp, \"::\");\n\t    rb_str_append(tmp, path);\n\n\t    return tmp;\n\t}\n\ttmp = rb_str_new2(rb_id2name(fc->name));\n\trb_str_cat2(tmp, \"::\");\n\trb_str_append(tmp, path);\n\tpath = tmp;\n\tfc = fc->prev;\n    }\n    return path;\n}\n\nstatic int\nfc_i(key, value, res)\n    ID key;\n    VALUE value;\n    struct fc_result *res;\n{\n    if (!rb_is_const_id(key)) return ST_CONTINUE;\n\n    if (value == res->klass) {\n\tres->path = fc_path(res, key);\n\treturn ST_STOP;\n    }\n    switch (TYPE(value)) {\n      case T_MODULE:\n      case T_CLASS:\n\tif (!RCLASS(value)->iv_tbl) return ST_CONTINUE;\n\telse {\n\t    struct fc_result arg;\n\t    struct fc_result *list;\n\n\t    list = res;\n\t    while (list) {\n\t\tif (list->track == value) return ST_CONTINUE;\n\t\tlist = list->prev;\n\t    }\n\n\t    arg.name = key;\n\t    arg.path = 0;\n\t    arg.klass = res->klass;\n\t    arg.track = value;\n\t    arg.prev = res;\n\t    st_foreach_safe(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);\n\t    if (arg.path) {\n\t\tres->path = arg.path;\n\t\treturn ST_STOP;\n\t    }\n\t}\n\tbreak;\n\n      default:\n\tbreak;\n    }\n    return ST_CONTINUE;\n}\n\nstatic VALUE\nfind_class_path(klass)\n    VALUE klass;\n{\n    struct fc_result arg;\n\n    arg.name = 0;\n    arg.path = 0;\n    arg.klass = klass;\n    arg.track = rb_cObject;\n    arg.prev = 0;\n    if (RCLASS(rb_cObject)->iv_tbl) {\n\tst_foreach_safe(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);\n    }\n    if (arg.path == 0) {\n\tst_foreach(rb_class_tbl, fc_i, (st_data_t)&arg);\n    }\n    if (arg.path) {\n\tif (!ROBJECT(klass)->iv_tbl) {\n\t    ROBJECT(klass)->iv_tbl = st_init_numtable();\n\t}\n\tst_insert(ROBJECT(klass)->iv_tbl, classpath, arg.path);\n\tst_delete(RCLASS(klass)->iv_tbl, &tmp_classpath, 0);\n\treturn arg.path;\n    }\n    return Qnil;\n}\n\nstatic VALUE\nclassname(klass)\n    VALUE klass;\n{\n    VALUE path = Qnil;\n\n    if (!klass) klass = rb_cObject;\n    if (ROBJECT(klass)->iv_tbl) {\n\tif (!st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) {\n\t    ID classid = rb_intern(\"__classid__\");\n\n\t    if (!st_lookup(ROBJECT(klass)->iv_tbl, classid, &path)) {\n\t\treturn find_class_path(klass);\n\t    }\n\t    path = rb_str_new2(rb_id2name(SYM2ID(path)));\n\t    st_insert(ROBJECT(klass)->iv_tbl, classpath, path);\n\t    st_delete(RCLASS(klass)->iv_tbl, (st_data_t*)&classid, 0);\n\t}\n\tif (TYPE(path) != T_STRING) {\n\t    rb_bug(\"class path is not set properly\");\n\t}\n\treturn path;\n    }\n    return find_class_path(klass);\n}\n\n/*\n *  call-seq:\n *     mod.name    => string\n *  \n *  Returns the name of the module <i>mod</i>.\n */\n\nVALUE\nrb_mod_name(mod)\n    VALUE mod;\n{\n    VALUE path = classname(mod);\n\n    if (!NIL_P(path)) return rb_str_dup(path);\n    return rb_str_new(0,0);\n}\n\nVALUE\nrb_class_path(klass)\n    VALUE klass;\n{\n    VALUE path = classname(klass);\n\n    if (!NIL_P(path)) return path;\n    if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,\n\t\t\t\t\t   tmp_classpath, &path)) {\n\treturn path;\n    }\n    else {\n\tconst char *s = \"Class\";\n\tsize_t len;\n\n\tif (TYPE(klass) == T_MODULE) {\n\t    if (rb_obj_class(klass) == rb_cModule) {\n\t\ts = \"Module\";\n\t    }\n\t    else {\n\t\ts = rb_class2name(RBASIC(klass)->klass);\n\t    }\n\t}\n\tlen = 2 + strlen(s) + 3 + 2 * SIZEOF_LONG + 1;\n\tpath = rb_str_new(0, len);\n\tsnprintf(RSTRING(path)->ptr, len+1, \"#<%s:0x%lx>\", s, klass);\n\tRSTRING(path)->len = strlen(RSTRING(path)->ptr);\n\trb_ivar_set(klass, tmp_classpath, path);\n\n\treturn path;\n    }\n}\n\nvoid\nrb_set_class_path(klass, under, name)\n    VALUE klass, under;\n    const char *name;\n{\n    VALUE str;\n\n    if (under == rb_cObject) {\n\tstr = rb_str_new2(name);\n    }\n    else {\n\tstr = rb_str_dup(rb_class_path(under));\n\trb_str_cat2(str, \"::\");\n\trb_str_cat2(str, name);\n    }\n    rb_ivar_set(klass, classpath, str);\n}\n\nVALUE\nrb_path2class(path)\n    const char *path;\n{\n    const char *pbeg, *p;\n    ID id;\n    VALUE c = rb_cObject;\n    VALUE str = 0;\n\n    if (path[0] == '#') {\n\trb_raise(rb_eArgError, \"can't retrieve anonymous class %s\", path);\n    }\n    pbeg = p = path;\n    while (*p) {\n\twhile (*p && *p != ':') p++;\n\tif (str) {\n\t    RSTRING(str)->len = 0;\n\t    rb_str_cat(str, pbeg, p-pbeg);\n\t}\n\telse {\n\t    str = rb_str_new(pbeg, p-pbeg);\n\t}\n\tid = rb_intern(RSTRING(str)->ptr);\n\tif (p[0] == ':') {\n\t    if (p[1] != ':') goto undefined_class;\n\t    p += 2;\n\t    pbeg = p;\n\t}\n\tif (!rb_const_defined(c, id)) {\n\t  undefined_class:\n\t    rb_raise(rb_eArgError, \"undefined class/module %.*s\", p-path, path);\n\t}\n\tc = rb_const_get_at(c, id);\n\tswitch (TYPE(c)) {\n\t  case T_MODULE:\n\t  case T_CLASS:\n\t    break;\n\t  default:\n\t    rb_raise(rb_eTypeError, \"%s does not refer class/module\", path);\n\t}\n    }\n\n    return c;\n}\n\nvoid\nrb_name_class(klass, id)\n    VALUE klass;\n    ID id;\n{\n    rb_iv_set(klass, \"__classid__\", ID2SYM(id));\n}\n\nVALUE\nrb_class_name(klass)\n    VALUE klass;\n{\n    return rb_class_path(rb_class_real(klass));\n}\n\nconst char *\nrb_class2name(klass)\n    VALUE klass;\n{\n    return RSTRING(rb_class_name(klass))->ptr;\n}\n\nconst char *\nrb_obj_classname(obj)\n    VALUE obj;\n{\n    return rb_class2name(CLASS_OF(obj));\n}\n\nstruct trace_var {\n    int removed;\n    void (*func)();\n    VALUE data;\n    struct trace_var *next;\n};\n\nstruct global_variable {\n    int   counter;\n    void *data;\n    VALUE (*getter)();\n    void  (*setter)();\n    void  (*marker)();\n    int block_trace;\n    struct trace_var *trace;\n};\n\nstruct global_entry {\n    struct global_variable *var;\n    ID id;\n};\n\nstatic VALUE undef_getter();\nstatic void  undef_setter();\nstatic void  undef_marker();\n\nstatic VALUE val_getter();\nstatic void  val_setter();\nstatic void  val_marker();\n\nstatic VALUE var_getter();\nstatic void  var_setter();\nstatic void  var_marker();\n\nstruct global_entry*\nrb_global_entry(id)\n    ID id;\n{\n    struct global_entry *entry;\n    st_data_t data;\n\n    if (!st_lookup(rb_global_tbl, id, &data)) {\n\tstruct global_variable *var;\n\tentry = ALLOC(struct global_entry);\n\tvar = ALLOC(struct global_variable);\n\tentry->id = id;\n\tentry->var = var;\n\tvar->counter = 1;\n\tvar->data = 0;\n\tvar->getter = undef_getter;\n\tvar->setter = undef_setter;\n\tvar->marker = undef_marker;\n\n\tvar->block_trace = 0;\n\tvar->trace = 0;\n\tst_add_direct(rb_global_tbl, id, (st_data_t)entry);\n    }\n    else {\n\tentry = (struct global_entry *)data;\n    }\n    return entry;\n}\n\nstatic VALUE\nundef_getter(id)\n    ID id;\n{\n    rb_warning(\"global variable `%s' not initialized\", rb_id2name(id));\n\n    return Qnil;\n}\n\nstatic void\nundef_setter(val, id, data, var)\n    VALUE val;\n    ID id;\n    void *data;\n    struct global_variable *var;\n{\n    var->getter = val_getter;\n    var->setter = val_setter;\n    var->marker = val_marker;\n\n    var->data = (void*)val;\n}\n\nstatic void\nundef_marker()\n{\n}\n\nstatic VALUE\nval_getter(id, val)\n    ID id;\n    VALUE val;\n{\n    return val;\n}\n\nstatic void\nval_setter(val, id, data, var)\n    VALUE val;\n    ID id;\n    void *data;\n    struct global_variable *var;\n{\n    var->data = (void*)val;\n}\n\nstatic void\nval_marker(data)\n    VALUE data;\n{\n    if (data) rb_gc_mark_maybe(data);\n}\n\nstatic VALUE\nvar_getter(id, var)\n    ID id;\n    VALUE *var;\n{\n    if (!var) return Qnil;\n    return *var;\n}\n\nstatic void\nvar_setter(val, id, var)\n    VALUE val;\n    ID id;\n    VALUE *var;\n{\n    *var = val;\n}\n\nstatic void\nvar_marker(var)\n    VALUE *var;\n{\n    if (var) rb_gc_mark_maybe(*var);\n}\n\nstatic void\nreadonly_setter(val, id, var)\n    VALUE val;\n    ID id;\n    void *var;\n{\n    rb_name_error(id, \"%s is a read-only variable\", rb_id2name(id));\n}\n\nstatic int\nmark_global_entry(key, entry)\n    ID key;\n    struct global_entry *entry;\n{\n    struct trace_var *trace;\n    struct global_variable *var = entry->var;\n\n    (*var->marker)(var->data);\n    trace = var->trace;\n    while (trace) {\n\tif (trace->data) rb_gc_mark_maybe(trace->data);\n\ttrace = trace->next;\n    }\n    return ST_CONTINUE;\n}\n\nvoid\nrb_gc_mark_global_tbl()\n{\n    if (rb_global_tbl) {\n\tst_foreach(rb_global_tbl, mark_global_entry, 0);\n    }\n}\n\nstatic ID\nglobal_id(name)\n    const char *name;\n{\n    ID id;\n\n    if (name[0] == '$') id = rb_intern(name);\n    else {\n\tchar *buf = ALLOCA_N(char, strlen(name)+2);\n\tbuf[0] = '$';\n\tstrcpy(buf+1, name);\n\tid = rb_intern(buf);\n    }\n    return id;\n}\n\nvoid\nrb_define_hooked_variable(name, var, getter, setter)\n    const char  *name;\n    VALUE *var;\n    VALUE (*getter)();\n    void  (*setter)();\n{\n    struct global_variable *gvar;\n    ID id = global_id(name);\n\n    gvar = rb_global_entry(id)->var;\n    gvar->data = (void*)var;\n    gvar->getter = getter?getter:var_getter;\n    gvar->setter = setter?setter:var_setter;\n    gvar->marker = var_marker;\n}\n\nvoid\nrb_define_variable(name, var)\n    const char  *name;\n    VALUE *var;\n{\n    rb_define_hooked_variable(name, var, 0, 0);\n}\n\nvoid\nrb_define_readonly_variable(name, var)\n    const char  *name;\n    VALUE *var;\n{\n    rb_define_hooked_variable(name, var, 0, readonly_setter);\n}\n\nvoid\nrb_define_virtual_variable(name, getter, setter)\n    const char  *name;\n    VALUE (*getter)();\n    void  (*setter)();\n{\n    if (!getter) getter = val_getter;\n    if (!setter) setter = readonly_setter;\n    rb_define_hooked_variable(name, 0, getter, setter);\n}\n\nstatic void\nrb_trace_eval(cmd, val)\n    VALUE cmd, val;\n{\n    rb_eval_cmd(cmd, rb_ary_new3(1, val), 0);\n}\n\n/*\n *  call-seq:\n *     trace_var(symbol, cmd )             => nil\n *     trace_var(symbol) {|val| block }    => nil\n *  \n *  Controls tracing of assignments to global variables. The parameter\n *  +symbol_ identifies the variable (as either a string name or a\n *  symbol identifier). _cmd_ (which may be a string or a\n *  +Proc+ object) or block is executed whenever the variable\n *  is assigned. The block or +Proc+ object receives the\n *  variable's new value as a parameter. Also see\n *  <code>Kernel::untrace_var</code>.\n *     \n *     trace_var :$_, proc {|v| puts \"$_ is now '#{v}'\" }\n *     $_ = \"hello\"\n *     $_ = ' there'\n *     \n *  <em>produces:</em>\n *     \n *     $_ is now 'hello'\n *     $_ is now ' there'\n */\n\nVALUE\nrb_f_trace_var(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE var, cmd;\n    struct global_entry *entry;\n    struct trace_var *trace;\n\n    rb_secure(4);\n    if (rb_scan_args(argc, argv, \"11\", &var, &cmd) == 1) {\n\tcmd = rb_block_proc();\n    }\n    if (NIL_P(cmd)) {\n\treturn rb_f_untrace_var(argc, argv);\n    }\n    entry = rb_global_entry(rb_to_id(var));\n    if (OBJ_TAINTED(cmd)) {\n\trb_raise(rb_eSecurityError, \"Insecure: tainted variable trace\");\n    }\n    trace = ALLOC(struct trace_var);\n    trace->next = entry->var->trace;\n    trace->func = rb_trace_eval;\n    trace->data = cmd;\n    trace->removed = 0;\n    entry->var->trace = trace;\n\n    return Qnil;\n}\n\nstatic void\nremove_trace(var)\n    struct global_variable *var;\n{\n    struct trace_var *trace = var->trace;\n    struct trace_var t;\n    struct trace_var *next;\n\n    t.next = trace;\n    trace = &t;\n    while (trace->next) {\n\tnext = trace->next;\n\tif (next->removed) {\n\t    trace->next = next->next;\n\t    free(next);\n\t}\n\telse {\n\t    trace = next;\n\t}\n    }\n    var->trace = t.next;\n}\n\n/*\n *  call-seq:\n *     untrace_var(symbol [, cmd] )   => array or nil\n *  \n *  Removes tracing for the specified command on the given global\n *  variable and returns +nil+. If no command is specified,\n *  removes all tracing for that variable and returns an array\n *  containing the commands actually removed.\n */\n\nVALUE\nrb_f_untrace_var(argc, argv)\n    int argc;\n    VALUE *argv;\n{\n    VALUE var, cmd;\n    ID id;\n    struct global_entry *entry;\n    struct trace_var *trace;\n    st_data_t data;\n\n    rb_secure(4);\n    rb_scan_args(argc, argv, \"11\", &var, &cmd);\n    id = rb_to_id(var);\n    if (!st_lookup(rb_global_tbl, id, &data)) {\n\trb_name_error(id, \"undefined global variable %s\", rb_id2name(id));\n    }\n\n    trace = (entry = (struct global_entry *)data)->var->trace;\n    if (NIL_P(cmd)) {\n\tVALUE ary = rb_ary_new();\n\n\twhile (trace) {\n\t    struct trace_var *next = trace->next;\n\t    rb_ary_push(ary, (VALUE)trace->data);\n\t    trace->removed = 1;\n\t    trace = next;\n\t}\n\n\tif (!entry->var->block_trace) remove_trace(entry->var);\n\treturn ary;\n    }\n    else {\n\twhile (trace) {\n\t    if (trace->data == cmd) {\n\t\ttrace->removed = 1;\n\t\tif (!entry->var->block_trace) remove_trace(entry->var);\n\t\treturn rb_ary_new3(1, cmd);\n\t    }\n\t    trace = trace->next;\n\t}\n    }\n    return Qnil;\n}\n\nVALUE\nrb_gvar_get(entry)\n    struct global_entry *entry;\n{\n    struct global_variable *var = entry->var;\n    return (*var->getter)(entry->id, var->data, var);\n}\n\nstruct trace_data {\n    struct trace_var *trace;\n    VALUE val;\n};\n\nstatic VALUE\ntrace_ev(data)\n    struct trace_data *data;\n{\n    struct trace_var *trace = data->trace;\n\n    while (trace) {\n\t(*trace->func)(trace->data, data->val);\n\ttrace = trace->next;\n    }\n    return Qnil;\t\t/* not reached */\n}\n\nstatic VALUE\ntrace_en(var)\n    struct global_variable *var;\n{\n    var->block_trace = 0;\n    remove_trace(var);\n    return Qnil;\t\t/* not reached */\n}\n\nVALUE\nrb_gvar_set(entry, val)\n    struct global_entry *entry;\n    VALUE val;\n{\n    struct trace_data trace;\n    struct global_variable *var = entry->var;\n\n    if (rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't change global variable value\");\n    (*var->setter)(val, entry->id, var->data, var);\n\n    if (var->trace && !var->block_trace) {\n\tvar->block_trace = 1;\n\ttrace.trace = var->trace;\n\ttrace.val = val;\n\trb_ensure(trace_ev, (VALUE)&trace, trace_en, (VALUE)var);\n    }\n    return val;\n}\n\nVALUE\nrb_gv_set(name, val)\n    const char *name;\n    VALUE val;\n{\n    struct global_entry *entry;\n\n    entry = rb_global_entry(global_id(name));\n    return rb_gvar_set(entry, val);\n}\n\nVALUE\nrb_gv_get(name)\n    const char *name;\n{\n    struct global_entry *entry;\n\n    entry = rb_global_entry(global_id(name));\n    return rb_gvar_get(entry);\n}\n\nVALUE\nrb_gvar_defined(entry)\n    struct global_entry *entry;\n{\n    if (entry->var->getter == undef_getter) return Qfalse;\n    return Qtrue;\n}\n\nstatic int\ngvar_i(key, entry, ary)\n    ID key;\n    struct global_entry *entry;\n    VALUE ary;\n{\n    rb_ary_push(ary, rb_str_new2(rb_id2name(key)));\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     global_variables    => array\n *  \n *  Returns an array of the names of global variables.\n *     \n *     global_variables.grep /std/   #=> [\"$stderr\", \"$stdout\", \"$stdin\"]\n */\n\nVALUE\nrb_f_global_variables()\n{\n    VALUE ary = rb_ary_new();\n    char buf[4];\n    const char *s = \"&`'+123456789\";\n\n    st_foreach(rb_global_tbl, gvar_i, ary);\n    if (!NIL_P(rb_backref_get())) {\n\twhile (*s) {\n\t    sprintf(buf, \"$%c\", *s++);\n\t    rb_ary_push(ary, rb_str_new2(buf));\n\t}\n    }\n    return ary;\n}\n\nvoid\nrb_alias_variable(name1, name2)\n    ID name1;\n    ID name2;\n{\n    struct global_entry *entry1, *entry2;\n    st_data_t data1;\n\n    if (rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't alias global variable\");\n\n    entry2 = rb_global_entry(name2);\n    if (!st_lookup(rb_global_tbl, name1, &data1)) {\n\tentry1 = ALLOC(struct global_entry);\n\tentry1->id = name1;\n\tst_add_direct(rb_global_tbl, name1, (st_data_t)entry1);\n    }\n    else if ((entry1 = (struct global_entry *)data1)->var != entry2->var) {\n\tstruct global_variable *var = entry1->var;\n\tif (var->block_trace) {\n\t    rb_raise(rb_eRuntimeError, \"can't alias in tracer\");\n\t}\n\tvar->counter--;\n\tif (var->counter == 0) {\n\t    struct trace_var *trace = var->trace;\n\t    while (trace) {\n\t\tstruct trace_var *next = trace->next;\n\t\tfree(trace);\n\t\ttrace = next;\n\t    }\n\t    free(var);\n\t}\n    }\n    else {\n\treturn;\n    }\n    entry2->var->counter++;\n    entry1->var = entry2->var;\n}\n\nstatic int special_generic_ivar = 0;\nstatic st_table *generic_iv_tbl;\n\nst_table*\nrb_generic_ivar_table(obj)\n    VALUE obj;\n{\n    st_data_t tbl;\n\n    if (!FL_TEST(obj, FL_EXIVAR)) return 0;\n    if (!generic_iv_tbl) return 0;\n    if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0;\n    return (st_table *)tbl;\n}\n\nstatic VALUE\ngeneric_ivar_get(obj, id, warn)\n    VALUE obj;\n    ID id;\n    int warn;\n{\n    st_data_t tbl;\n    VALUE val;\n\n    if (generic_iv_tbl) {\n\tif (st_lookup(generic_iv_tbl, obj, &tbl)) {\n\t    if (st_lookup((st_table *)tbl, id, &val)) {\n\t\treturn val;\n\t    }\n\t}\n    }\n    if (warn) {\n\trb_warning(\"instance variable %s not initialized\", rb_id2name(id));\n    }\n    return Qnil;\n}\n\nstatic void\ngeneric_ivar_set(obj, id, val)\n    VALUE obj;\n    ID id;\n    VALUE val;\n{\n    st_table *tbl;\n    st_data_t data;\n\n    if (rb_special_const_p(obj)) {\n\tspecial_generic_ivar = 1;\n    }\n    if (!generic_iv_tbl) {\n\tgeneric_iv_tbl = st_init_numtable();\n    }\n\n    if (!st_lookup(generic_iv_tbl, obj, &data)) {\n\tFL_SET(obj, FL_EXIVAR);\n\ttbl = st_init_numtable();\n\tst_add_direct(generic_iv_tbl, obj, (st_data_t)tbl);\n\tst_add_direct(tbl, id, val);\n\treturn;\n    }\n    st_insert((st_table *)data, id, val);\n}\n\nstatic VALUE\ngeneric_ivar_defined(obj, id)\n    VALUE obj;\n    ID id;\n{\n    st_table *tbl;\n    st_data_t data;\n    VALUE val;\n\n    if (!generic_iv_tbl) return Qfalse;\n    if (!st_lookup(generic_iv_tbl, obj, &data)) return Qfalse;\n    tbl = (st_table *)data;\n    if (st_lookup(tbl, id, &val)) {\n\treturn Qtrue;\n    }\n    return Qfalse;\n}\n\nstatic int\ngeneric_ivar_remove(obj, id, valp)\n    VALUE obj;\n    ID id;\n    VALUE *valp;\n{\n    st_table *tbl;\n    st_data_t data;\n    int status;\n\n    if (!generic_iv_tbl) return 0;\n    if (!st_lookup(generic_iv_tbl, obj, &data)) return 0;\n    tbl = (st_table *)data;\n    status = st_delete(tbl, &id, valp);\n    if (tbl->num_entries == 0) {\n\tst_delete(generic_iv_tbl, &obj, &data);\n\tst_free_table((st_table *)data);\n    }\n    return status;\n}\n\nvoid\nrb_mark_generic_ivar(obj)\n    VALUE obj;\n{\n    st_data_t tbl;\n\n    if (!generic_iv_tbl) return;\n    if (st_lookup(generic_iv_tbl, obj, &tbl)) {\n\trb_mark_tbl((st_table *)tbl);\n    }\n}\n\nvoid\nadd_generic_ivar_to_remembered_set(obj)\n    VALUE obj;\n{\n    st_data_t tbl;\n\n    if (!generic_iv_tbl) return;\n    if (st_lookup(generic_iv_tbl, obj, &tbl)) {\n\tadd_table_to_remembered_set((st_table *)tbl);\n    }\n}\n\nstatic int\ngivar_mark_i(key, value)\n    ID key;\n    VALUE value;\n{\n    rb_gc_mark(value);\n    return ST_CONTINUE;\n}\n\nstatic int\ngivar_i(obj, tbl)\n    VALUE obj;\n    st_table *tbl;\n{\n    if (rb_special_const_p(obj)) {\n\tst_foreach(tbl, givar_mark_i, 0);\n    }\n    return ST_CONTINUE;\n}\n\nvoid\nrb_mark_generic_ivar_tbl()\n{\n    if (!generic_iv_tbl) return;\n    if (special_generic_ivar == 0) return;\n    st_foreach_safe(generic_iv_tbl, givar_i, 0);\n}\n\nvoid\nrb_free_generic_ivar(obj)\n    VALUE obj;\n{\n    st_data_t tbl;\n\n    if (!generic_iv_tbl) return;\n    if (st_delete(generic_iv_tbl, &obj, &tbl))\n\tst_free_table((st_table *)tbl);\n}\n\nvoid\nrb_copy_generic_ivar(clone, obj)\n    VALUE clone, obj;\n{\n    st_data_t data;\n\n    if (!generic_iv_tbl) return;\n    if (!FL_TEST(obj, FL_EXIVAR)) return;\n    if (st_lookup(generic_iv_tbl, obj, &data)) {\n\tst_table *tbl = (st_table *)data;\n\n\tif (st_lookup(generic_iv_tbl, clone, &data)) {\n\t    st_free_table((st_table *)data);\n\t    st_insert(generic_iv_tbl, clone, (st_data_t)st_copy(tbl));\n\t}\n\telse {\n\t    st_add_direct(generic_iv_tbl, clone, (st_data_t)st_copy(tbl));\n\t}\n    }\n}\n\nstatic VALUE\nivar_get(obj, id, warn)\n    VALUE obj;\n    ID id;\n    int warn;\n{\n    VALUE val;\n\n    switch (TYPE(obj)) {\n      case T_OBJECT:\n      case T_CLASS:\n      case T_MODULE:\n\tif (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))\n\t    return val;\n\tbreak;\n      default:\n\tif (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))\n\t    return generic_ivar_get(obj, id, warn);\n\tbreak;\n    }\n    if (warn) {\n\trb_warning(\"instance variable %s not initialized\", rb_id2name(id));\n    }\n    return Qnil;\n}\n\nVALUE\nrb_ivar_get(obj, id)\n    VALUE obj;\n    ID id;\n{\n    return ivar_get(obj, id, Qtrue);\n}\n\nVALUE\nrb_attr_get(obj, id)\n    VALUE obj;\n    ID id;\n{\n    return ivar_get(obj, id, Qfalse);\n}\n\nVALUE\nrb_ivar_set(obj, id, val)\n    VALUE obj;\n    ID id;\n    VALUE val;\n{\n    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify instance variable\");\n    if (OBJ_FROZEN(obj)) rb_error_frozen(\"object\");\n    switch (TYPE(obj)) {\n      case T_OBJECT:\n      case T_CLASS:\n      case T_MODULE:\n\tif (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();\n\tst_insert(ROBJECT(obj)->iv_tbl, id, val);\n\tbreak;\n      default:\n\tgeneric_ivar_set(obj, id, val);\n\tbreak;\n    }\n    return val;\n}\n\nVALUE\nrb_ivar_defined(obj, id)\n    VALUE obj;\n    ID id;\n{\n    switch (TYPE(obj)) {\n      case T_OBJECT:\n      case T_CLASS:\n      case T_MODULE:\n\tif (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0))\n\t    return Qtrue;\n\tbreak;\n      default:\n\tif (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))\n\t    return generic_ivar_defined(obj, id);\n\tbreak;\n    }\n    return Qfalse;\n}\n\nstatic int\nivar_i(key, entry, ary)\n    ID key;\n    struct global_entry *entry;\n    VALUE ary;\n{\n    if (rb_is_instance_id(key)) {\n\trb_ary_push(ary, rb_str_new2(rb_id2name(key)));\n    }\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     obj.instance_variables    => array\n *  \n *  Returns an array of instance variable names for the receiver. Note\n *  that simply defining an accessor does not create the corresponding\n *  instance variable.\n *     \n *     class Fred\n *       attr_accessor :a1\n *       def initialize\n *         @iv = 3\n *       end\n *     end\n *     Fred.new.instance_variables   #=> [\"@iv\"]\n */\n\nVALUE\nrb_obj_instance_variables(obj)\n    VALUE obj;\n{\n    VALUE ary;\n\n    ary = rb_ary_new();\n    switch (TYPE(obj)) {\n      case T_OBJECT:\n      case T_CLASS:\n      case T_MODULE:\n\tif (ROBJECT(obj)->iv_tbl) {\n\t    st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary);\n\t}\n\tbreak;\n      default:\n\tif (!generic_iv_tbl) break;\n\tif (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {\n\t    st_data_t tbl;\n\n\t    if (st_lookup(generic_iv_tbl, obj, &tbl)) {\n\t\tst_foreach_safe((st_table *)tbl, ivar_i, ary);\n\t    }\n\t}\n\tbreak;\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     obj.remove_instance_variable(symbol)    => obj\n *  \n *  Removes the named instance variable from <i>obj</i>, returning that\n *  variable's value.\n *     \n *     class Dummy\n *       attr_reader :var\n *       def initialize\n *         @var = 99\n *       end\n *       def remove\n *         remove_instance_variable(:@var)\n *       end\n *     end\n *     d = Dummy.new\n *     d.var      #=> 99\n *     d.remove   #=> 99\n *     d.var      #=> nil\n */\n\nVALUE\nrb_obj_remove_instance_variable(obj, name)\n    VALUE obj, name;\n{\n    VALUE val = Qnil;\n    ID id = rb_to_id(name);\n\n    if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't modify instance variable\");\n    if (OBJ_FROZEN(obj)) rb_error_frozen(\"object\");\n    if (!rb_is_instance_id(id)) {\n\trb_name_error(id, \"`%s' is not allowed as an instance variable name\", rb_id2name(id));\n    }\n\n    switch (TYPE(obj)) {\n      case T_OBJECT:\n      case T_CLASS:\n      case T_MODULE:\n\tif (ROBJECT(obj)->iv_tbl && st_delete(ROBJECT(obj)->iv_tbl, (st_data_t*)&id, &val)) {\n\t    return val;\n\t}\n\tbreak;\n      default:\n\tif (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {\n\t    if (generic_ivar_remove(obj, id, &val)) {\n\t\treturn val;\n\t    }\n\t}\n\tbreak;\n    }\n    rb_name_error(id, \"instance variable %s not defined\", rb_id2name(id));\n    return Qnil;\t\t/* not reached */\n}\n\nNORETURN(static void uninitialized_constant _((VALUE, ID)));\nstatic void\nuninitialized_constant(klass, id)\n    VALUE klass;\n    ID id;\n{\n    if (klass && klass != rb_cObject)\n\trb_name_error(id, \"uninitialized constant %s::%s\",\n\t\t      rb_class2name(klass),\n\t\t      rb_id2name(id));\n    else {\n\trb_name_error(id, \"uninitialized constant %s\", rb_id2name(id));\n    }\n}\n\nstatic VALUE\nconst_missing(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_funcall(klass, rb_intern(\"const_missing\"), 1, ID2SYM(id));\n}\n\n\n/*\n * call-seq:\n *    mod.const_missing(sym)    => obj\n *\n *  Invoked when a reference is made to an undefined constant in\n *  <i>mod</i>. It is passed a symbol for the undefined constant, and\n *  returns a value to be used for that constant. The\n *  following code is a (very bad) example: if reference is made to\n *  an undefined constant, it attempts to load a file whose name is\n *  the lowercase version of the constant (thus class <code>Fred</code> is\n *  assumed to be in file <code>fred.rb</code>). If found, it returns the\n *  value of the loaded class. It therefore implements a perverse\n *  kind of autoload facility.\n *  \n *    def Object.const_missing(name)\n *      @looked_for ||= {}\n *      str_name = name.to_s\n *      raise \"Class not found: #{name}\" if @looked_for[str_name]\n *      @looked_for[str_name] = 1\n *      file = str_name.downcase\n *      require file\n *      klass = const_get(name)\n *      return klass if klass\n *      raise \"Class not found: #{name}\"\n *    end\n *  \n */\n\nVALUE\nrb_mod_const_missing(klass, name)\n    VALUE klass, name;\n{\n    ruby_frame = ruby_frame->prev; /* pop frame for \"const_missing\" */\n    uninitialized_constant(klass, rb_to_id(name));\n    return Qnil;\t\t/* not reached */\n}\n\nstatic struct st_table *\ncheck_autoload_table(av)\n    VALUE av;\n{\n    Check_Type(av, T_DATA);\n    if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||\n\tRDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) {\n\trb_raise(rb_eTypeError, \"wrong autoload table: %s\", RSTRING(rb_inspect(av))->ptr);\n    }\n    return (struct st_table *)DATA_PTR(av);\n}\n\nvoid\nrb_autoload(mod, id, file)\n    VALUE mod;\n    ID id;\n    const char *file;\n{\n    VALUE av, fn;\n    struct st_table *tbl;\n\n    if (!rb_is_const_id(id)) {\n\trb_raise(rb_eNameError, \"autoload must be constant name\", rb_id2name(id));\n    }\n    if (!file || !*file) {\n\trb_raise(rb_eArgError, \"empty file name\");\n    }\n\n    if ((tbl = RCLASS(mod)->iv_tbl) && st_lookup(tbl, id, &av) && av != Qundef)\n\treturn;\n\n    rb_const_set(mod, id, Qundef);\n    tbl = RCLASS(mod)->iv_tbl;\n    if (st_lookup(tbl, autoload, &av)) {\n\ttbl = check_autoload_table(av);\n    }\n    else {\n\tav = Data_Wrap_Struct(0 , rb_mark_tbl, st_free_table, 0);\n\tst_add_direct(tbl, autoload, av);\n\tDATA_PTR(av) = tbl = st_init_numtable();\n    }\n    fn = rb_str_new2(file);\n    FL_UNSET(fn, FL_TAINT);\n    OBJ_FREEZE(fn);\n    st_insert(tbl, id, (st_data_t)NEW_NODE_EDEN(NODE_MEMO, fn, ruby_safe_level, 0));\n}\n\nstatic NODE*\nautoload_delete(mod, id)\n    VALUE mod;\n    ID id;\n{\n    VALUE val;\n    st_data_t load = 0;\n\n    st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, 0);\n    if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {\n\tstruct st_table *tbl = check_autoload_table(val);\n\n\tst_delete(tbl, (st_data_t*)&id, &load);\n\n\tif (tbl->num_entries == 0) {\n\t    id = autoload;\n\t    st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, &val);\n\t}\n    }\n\n    return (NODE *)load;\n}\n\nVALUE\nrb_autoload_load(klass, id)\n    VALUE klass;\n    ID id;\n{\n    VALUE file;\n    NODE *load = autoload_delete(klass, id);\n\n    if (!load || !(file = load->nd_lit) || rb_provided(RSTRING(file)->ptr)) {\n\treturn Qfalse;\n    }\n    return rb_require_safe(file, load->nd_nth);\n}\n\nstatic VALUE\nautoload_file(mod, id)\n    VALUE mod;\n    ID id;\n{\n    VALUE val, file;\n    struct st_table *tbl;\n    st_data_t load;\n\n    if (!st_lookup(RCLASS(mod)->iv_tbl, autoload, &val) ||\n\t!(tbl = check_autoload_table(val)) || !st_lookup(tbl, id, &load)) {\n\treturn Qnil;\n    }\n    file = ((NODE *)load)->nd_lit;\n    Check_Type(file, T_STRING);\n    if (!RSTRING(file)->ptr || !*RSTRING(file)->ptr) {\n\trb_raise(rb_eArgError, \"empty file name\");\n    }\n    if (!rb_provided(RSTRING(file)->ptr)) {\n\treturn file;\n    }\n\n    /* already loaded but not defined */\n    st_delete(tbl, (st_data_t*)&id, 0);\n    if (!tbl->num_entries) {\n\tid = autoload;\n\tst_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, &val);\n    }\n    return Qnil;\n}\n\nVALUE\nrb_autoload_p(mod, id)\n    VALUE mod;\n    ID id;\n{\n    struct st_table *tbl = RCLASS(mod)->iv_tbl;\n    VALUE val;\n\n    if (!tbl || !st_lookup(tbl, id, &val) || val != Qundef) {\n\treturn Qnil;\n    }\n    return autoload_file(mod, id);\n}\n\nstatic VALUE\nrb_const_get_0(klass, id, exclude, recurse)\n    VALUE klass;\n    ID id;\n    int exclude, recurse;\n{\n    VALUE value, tmp;\n    int mod_retry = 0;\n\n    tmp = klass;\n  retry:\n    while (tmp) {\n\twhile (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {\n\t    if (value == Qundef) {\n\t\tif (!RTEST(rb_autoload_load(tmp, id))) break;\n\t\tcontinue;\n\t    }\n\t    if (exclude && tmp == rb_cObject && klass != rb_cObject) {\n\t\trb_warn(\"toplevel constant %s referenced by %s::%s\",\n\t\t\trb_id2name(id), rb_class2name(klass), rb_id2name(id));\n\t    }\n\t    return value;\n\t}\n\tif (!recurse && klass != rb_cObject) break;\n\ttmp = RCLASS(tmp)->super;\n    }\n    if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {\n\tmod_retry = 1;\n\ttmp = rb_cObject;\n\tgoto retry;\n    }\n\n    return const_missing(klass, id);\n}\n\nVALUE\nrb_const_get_from(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_const_get_0(klass, id, Qtrue, Qtrue);\n}\n\nVALUE\nrb_const_get(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_const_get_0(klass, id, Qfalse, Qtrue);\n}\n\nVALUE\nrb_const_get_at(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_const_get_0(klass, id, Qtrue, Qfalse);\n}\n\n/*\n *  call-seq:\n *     remove_const(sym)   => obj\n *  \n *  Removes the definition of the given constant, returning that\n *  constant's value. Predefined classes and singleton objects (such as\n *  <i>true</i>) cannot be removed.\n */\n\nVALUE\nrb_mod_remove_const(mod, name)\n    VALUE mod, name;\n{\n    ID id = rb_to_id(name);\n    VALUE val;\n\n    if (!rb_is_const_id(id)) {\n\trb_name_error(id, \"`%s' is not allowed as a constant name\", rb_id2name(id));\n    }\n    if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't remove constant\");\n    if (OBJ_FROZEN(mod)) rb_error_frozen(\"class/module\");\n\n    if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, (st_data_t*)&id, &val)) {\n\tif (val == Qundef) {\n\t    autoload_delete(mod, id);\n\t    val = Qnil;\n\t}\n\treturn val;\n    }\n    if (rb_const_defined_at(mod, id)) {\n\trb_name_error(id, \"cannot remove %s::%s\",\n\t\t rb_class2name(mod), rb_id2name(id));\n    }\n    rb_name_error(id, \"constant %s::%s not defined\",\n\t\t  rb_class2name(mod), rb_id2name(id));\n    return Qnil;\t\t/* not reached */\n}\n\nstatic int\nsv_i(key, value, tbl)\n    ID key;\n    VALUE value;\n    st_table *tbl;\n{\n    if (rb_is_const_id(key)) {\n\tif (!st_lookup(tbl, key, 0)) {\n\t    st_insert(tbl, key, key);\n\t}\n    }\n    return ST_CONTINUE;\n}\n\nvoid*\nrb_mod_const_at(mod, data)\n    VALUE mod;\n    void *data;\n{\n    st_table *tbl = data;\n    if (!tbl) {\n\ttbl = st_init_numtable();\n    }\n    if (RCLASS(mod)->iv_tbl) {\n\tst_foreach_safe(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);\n    }\n    return tbl;\n}\n\nvoid*\nrb_mod_const_of(mod, data)\n    VALUE mod;\n    void *data;\n{\n    VALUE tmp = mod;\n    for (;;) {\n\tdata = rb_mod_const_at(tmp, data);\n\ttmp = RCLASS(tmp)->super;\n\tif (!tmp) break;\n\tif (tmp == rb_cObject && mod != rb_cObject) break;\n    }\n    return data;\n}\n\nstatic int\nlist_i(key, value, ary)\n    ID key, value;\n    VALUE ary;\n{\n    rb_ary_push(ary, rb_str_new2(rb_id2name(key)));\n    return ST_CONTINUE;\n}\n\nVALUE\nrb_const_list(data)\n    void *data;\n{\n    st_table *tbl = data;\n    VALUE ary;\n\n    if (!tbl) return rb_ary_new2(0);\n    ary = rb_ary_new2(tbl->num_entries);\n    st_foreach(tbl, list_i, ary);\n    st_free_table(tbl);\n\n    return ary;\n}\n\n/*\n *  call-seq:\n *     mod.constants    => array\n *  \n *  Returns an array of the names of the constants accessible in\n *  <i>mod</i>. This includes the names of constants in any included\n *  modules (example at start of section).\n */\n\nVALUE\nrb_mod_constants(mod)\n    VALUE mod;\n{\n    return rb_const_list(rb_mod_const_of(mod, 0));\n}\n\nstatic int\nrb_const_defined_0(klass, id, exclude, recurse)\n    VALUE klass;\n    ID id;\n    int exclude, recurse;\n{\n    VALUE value, tmp;\n    int mod_retry = 0;\n\n    tmp = klass;\n  retry:\n    while (tmp) {\n\tif (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl, id, &value)) {\n\t    if (value == Qundef && NIL_P(autoload_file(klass, id)))\n\t\treturn Qfalse;\n\t    return Qtrue;\n\t}\n\tif (!recurse && klass != rb_cObject) break;\n\ttmp = RCLASS(tmp)->super;\n    }\n    if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {\n\tmod_retry = 1;\n\ttmp = rb_cObject;\n\tgoto retry;\n    }\n    return Qfalse;\n}\n\nint\nrb_const_defined_from(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_const_defined_0(klass, id, Qtrue, Qtrue);\n}\n\nint\nrb_const_defined(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_const_defined_0(klass, id, Qfalse, Qtrue);\n}\n\nint\nrb_const_defined_at(klass, id)\n    VALUE klass;\n    ID id;\n{\n    return rb_const_defined_0(klass, id, Qtrue, Qfalse);\n}\n\nstatic void\nmod_av_set(klass, id, val, isconst)\n    VALUE klass;\n    ID id;\n    VALUE val;\n    int isconst;\n{\n    const char *dest = isconst ? \"constant\" : \"class variable\";\n\n    if (!OBJ_TAINTED(klass) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't set %s\", dest);\n    if (OBJ_FROZEN(klass)) {\n\tif (BUILTIN_TYPE(klass) == T_MODULE) {\n\t    rb_error_frozen(\"module\");\n\t}\n\telse {\n\t    rb_error_frozen(\"class\");\n\t}\n    }\n    if (!RCLASS(klass)->iv_tbl) {\n\tRCLASS(klass)->iv_tbl = st_init_numtable();\n    }\n    else if (isconst) {\n\tVALUE value = Qfalse;\n\n\tif (st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {\n\t    if (value == Qundef)\n\t\tautoload_delete(klass, id);\n\t    else\n\t\trb_warn(\"already initialized %s %s\", dest, rb_id2name(id));\n\t}\n    }\n\n    st_insert(RCLASS(klass)->iv_tbl, id, val);\n}\n\nvoid\nrb_const_set(klass, id, val)\n    VALUE klass;\n    ID id;\n    VALUE val;\n{\n    if (NIL_P(klass)) {\n\trb_raise(rb_eTypeError, \"no class/module to define constant %s\",\n\t\t rb_id2name(id));\n    }\n    mod_av_set(klass, id, val, Qtrue);\n}\n\nvoid\nrb_define_const(klass, name, val)\n    VALUE klass;\n    const char *name;\n    VALUE val;\n{\n    ID id = rb_intern(name);\n\n    if (!rb_is_const_id(id)) {\n\trb_warn(\"rb_define_const: invalid name `%s' for constant\", name);\n    }\n    if (klass == rb_cObject) {\n\trb_secure(4);\n    }\n    rb_const_set(klass, id, val);\n}\n\nvoid\nrb_define_global_const(name, val)\n    const char *name;\n    VALUE val;\n{\n    rb_define_const(rb_cObject, name, val);\n}\n\nstatic VALUE\noriginal_module(c)\n    VALUE c;\n{\n    if (TYPE(c) == T_ICLASS)\n\treturn RBASIC(c)->klass;\n    return c;\n}\n\nstatic void\ncvar_override_check(id, a)\n    ID id;\n    VALUE a;\n{\n    VALUE base = original_module(a);\n\n    a = RCLASS(a)->super;\n    while (a) {\n\tif (RCLASS(a)->iv_tbl) {\n\t    if (st_lookup(RCLASS(a)->iv_tbl,id,0)) {\n\t\trb_warning(\"class variable %s of %s is overridden by %s\",\n\t\t\t   rb_id2name(id), rb_class2name(original_module(a)),\n\t\t\t   rb_class2name(base));\n\t    }\n\t}\n\ta = RCLASS(a)->super;\n    }\n}\n\nvoid\nrb_cvar_set(klass, id, val, warn)\n    VALUE klass;\n    ID id;\n    VALUE val;\n    int warn;\n{\n    VALUE tmp;\n\n    tmp = klass;\n    while (tmp) {\n\tif (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) {\n\t    if (OBJ_FROZEN(tmp)) rb_error_frozen(\"class/module\");\n\t    if (!OBJ_TAINTED(tmp) && rb_safe_level() >= 4)\n\t\trb_raise(rb_eSecurityError, \"Insecure: can't modify class variable\");\n\t    if (warn && RTEST(ruby_verbose) && klass != tmp) {\n\t\trb_warning(\"already initialized class variable %s\", rb_id2name(id));\n\t    }\n\t    st_insert(RCLASS(tmp)->iv_tbl,id,val);\n\t    if (RTEST(ruby_verbose)) {\n\t\tcvar_override_check(id, tmp);\n\t    }\n\t    return;\n\t}\n\ttmp = RCLASS(tmp)->super;\n    }\n\n    mod_av_set(klass, id, val, Qfalse);\n}\n\nVALUE\nrb_cvar_get(klass, id)\n    VALUE klass;\n    ID id;\n{\n    VALUE value;\n    VALUE tmp;\n\n    tmp = klass;\n    while (tmp) {\n\tif (RCLASS(tmp)->iv_tbl) {\n\t    if (st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {\n\t\tif (RTEST(ruby_verbose)) {\n\t\t    cvar_override_check(id, tmp);\n\t\t}\n\t\treturn value;\n\t    }\n\t}\n\ttmp = RCLASS(tmp)->super;\n    }\n\n    rb_name_error(id,\"uninitialized class variable %s in %s\",\n\t\t  rb_id2name(id), rb_class2name(klass));\n    return Qnil;\t\t/* not reached */\n}\n\nVALUE\nrb_cvar_defined(klass, id)\n    VALUE klass;\n    ID id;\n{\n    VALUE tmp;\n\n    tmp = klass;\n    while (tmp) {\n\tif (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) {\n\t    return Qtrue;\n\t}\n\ttmp = RCLASS(tmp)->super;\n    }\n\n    return Qfalse;\n}\n\nvoid\nrb_cv_set(klass, name, val)\n    VALUE klass;\n    const char *name;\n    VALUE val;\n{\n    ID id = rb_intern(name);\n    if (!rb_is_class_id(id)) {\n\trb_name_error(id, \"wrong class variable name %s\", name);\n    }\n    rb_cvar_set(klass, id, val, Qfalse);\n}\n\nVALUE\nrb_cv_get(klass, name)\n    VALUE klass;\n    const char *name;\n{\n    ID id = rb_intern(name);\n    if (!rb_is_class_id(id)) {\n\trb_name_error(id, \"wrong class variable name %s\", name);\n    }\n    return rb_cvar_get(klass, id);\n}\n\nvoid\nrb_define_class_variable(klass, name, val)\n    VALUE klass;\n    const char *name;\n    VALUE val;\n{\n    ID id = rb_intern(name);\n\n    if (!rb_is_class_id(id)) {\n\trb_name_error(id, \"wrong class variable name %s\", name);\n    }\n    rb_cvar_set(klass, id, val, Qtrue);\n}\n\nstatic int\ncv_i(key, value, ary)\n    ID key;\n    VALUE value;\n    VALUE ary;\n{\n    if (rb_is_class_id(key)) {\n\tVALUE kval = rb_str_new2(rb_id2name(key));\n\tif (!rb_ary_includes(ary, kval)) {\n\t    rb_ary_push(ary, kval);\n\t}\n    }\n    return ST_CONTINUE;\n}\n\n/*\n *  call-seq:\n *     mod.class_variables   => array\n *  \n *  Returns an array of the names of class variables in <i>mod</i> and\n *  the ancestors of <i>mod</i>.\n *     \n *     class One\n *       @@var1 = 1\n *     end\n *     class Two < One\n *       @@var2 = 2\n *     end\n *     One.class_variables   #=> [\"@@var1\"]\n *     Two.class_variables   #=> [\"@@var2\", \"@@var1\"]\n */\n\nVALUE\nrb_mod_class_variables(obj)\n    VALUE obj;\n{\n    VALUE ary = rb_ary_new();\n\n    for (;;) {\n\tif (RCLASS(obj)->iv_tbl) {\n\t    st_foreach_safe(RCLASS(obj)->iv_tbl, cv_i, ary);\n\t}\n\tobj = RCLASS(obj)->super;\n\tif (!obj) break;\n    }\n    return ary;\n}\n\n/*\n *  call-seq:\n *     remove_class_variable(sym)    => obj\n *  \n *  Removes the definition of the <i>sym</i>, returning that\n *  constant's value.\n *     \n *     class Dummy\n *       @@var = 99\n *       puts @@var\n *       remove_class_variable(:@@var)\n *       puts(defined? @@var)\n *     end\n *     \n *  <em>produces:</em>\n *     \n *     99\n *     nil\n */\n\nVALUE\nrb_mod_remove_cvar(mod, name)\n    VALUE mod, name;\n{\n    ID id = rb_to_id(name);\n    VALUE val;\n\n    if (!rb_is_class_id(id)) {\n\trb_name_error(id, \"wrong class variable name %s\", rb_id2name(id));\n    }\n    if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)\n\trb_raise(rb_eSecurityError, \"Insecure: can't remove class variable\");\n    if (OBJ_FROZEN(mod)) rb_error_frozen(\"class/module\");\n\n    if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, (st_data_t*)&id, &val)) {\n\treturn val;\n    }\n    if (rb_cvar_defined(mod, id)) {\n\trb_name_error(id, \"cannot remove %s for %s\",\n\t\t rb_id2name(id), rb_class2name(mod));\n    }\n    rb_name_error(id, \"class variable %s not defined for %s\",\n\t\t  rb_id2name(id), rb_class2name(mod));\n    return Qnil;\t\t/* not reached */\n}\n\nVALUE\nrb_iv_get(obj, name)\n    VALUE obj;\n    const char *name;\n{\n    ID id = rb_intern(name);\n\n    return rb_ivar_get(obj, id);\n}\n\nVALUE\nrb_iv_set(obj, name, val)\n    VALUE obj;\n    const char *name;\n    VALUE val;\n{\n    ID id = rb_intern(name);\n\n    return rb_ivar_set(obj, id, val);\n}\n"
  },
  {
    "path": "version.c",
    "content": "/**********************************************************************\n\n  version.c -\n\n  $Author$\n  $Date$\n  created at: Thu Sep 30 20:08:01 JST 1993\n\n  Copyright (C) 1993-2003 Yukihiro Matsumoto\n\n**********************************************************************/\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n#include \"version.h\"\n#include <stdio.h>\n\n#define PRINT(type) puts(ruby_##type)\n#define MKSTR(type) rb_obj_freeze(rb_str_new(ruby_##type, sizeof(ruby_##type)-1))\n\nconst char ruby_engine[] = RUBY_ENGINE;\nconst char ruby_version[] = RUBY_VERSION;\nconst char ruby_release_date[] = RUBY_RELEASE_DATE;\nconst char ruby_platform[] = RUBY_PLATFORM;\nconst int ruby_patchlevel = RUBY_PATCHLEVEL;\nconst char *ruby_description;\nconst char *ruby_copyright;\n\n#define REE_VERSION \"2010.02\"\n\n#define KIJI_VERSION \"0.11\"\nconst char ruby_kiji_version[] = KIJI_VERSION;\n\nvoid\nInit_version()\n{\n    static char description[128];\n    static char copyright[128];\n    VALUE e = MKSTR(engine);\n    VALUE v = MKSTR(version);\n    VALUE d = MKSTR(release_date);\n    VALUE p = MKSTR(platform);\n    VALUE k = MKSTR(kiji_version);\n    VALUE tmp;\n\n    rb_define_global_const(\"RUBY_ENGINE\", e);\n    rb_define_global_const(\"RUBY_VERSION\", v);\n    rb_define_global_const(\"RUBY_RELEASE_DATE\", d);\n    rb_define_global_const(\"RUBY_PLATFORM\", p);\n    rb_define_global_const(\"RUBY_PATCHLEVEL\", INT2FIX(RUBY_PATCHLEVEL));\n    rb_define_global_const(\"KIJI_VERSION\", k);\n\n    snprintf(description, sizeof(description),\n             \"ruby %s (%s %s %d) [%s], MBARI 0x%x, \"\n             \"Ruby Enterprise Edition %s, Kiji %s\",\n             RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_RELEASE_STR,\n             RUBY_RELEASE_NUM, RUBY_PLATFORM,\n             STACK_WIPE_SITES, REE_VERSION, KIJI_VERSION);\n    ruby_description = description;\n    tmp = rb_obj_freeze(rb_str_new2(description));\n    rb_define_global_const(\"RUBY_DESCRIPTION\", tmp);\n\n    snprintf(copyright, sizeof(copyright), \"ruby - Copyright (C) %d-%d %s\",\n             RUBY_BIRTH_YEAR, RUBY_RELEASE_YEAR, RUBY_AUTHOR);\n    ruby_copyright = copyright;\n    tmp = rb_obj_freeze(rb_str_new2(copyright));\n    rb_define_global_const(\"RUBY_COPYRIGHT\", tmp);\n\n    /* obsolete constants */\n    rb_define_global_const(\"VERSION\", v);\n    rb_define_global_const(\"RELEASE_DATE\", d);\n    rb_define_global_const(\"PLATFORM\", p);\n}\n\nvoid\nruby_show_version()\n{\n    PRINT(description);\n    fflush(stdout);\n}\n\nvoid\nruby_show_copyright()\n{\n    PRINT(copyright);\n    exit(0);\n}\n"
  },
  {
    "path": "version.h",
    "content": "#define RUBY_ENGINE \"ruby\"\n#define RUBY_VERSION \"1.8.7\"\n#define RUBY_RELEASE_DATE \"2010-04-19\"\n#define RUBY_VERSION_CODE 187\n#define RUBY_RELEASE_CODE 20100419\n#define RUBY_PATCHLEVEL 253\n\n#define RUBY_VERSION_MAJOR 1\n#define RUBY_VERSION_MINOR 8\n#define RUBY_VERSION_TEENY 7\n#define RUBY_RELEASE_YEAR 2010\n#define RUBY_RELEASE_MONTH 4\n#define RUBY_RELEASE_DAY 19\n\n#ifdef RUBY_EXTERN\nRUBY_EXTERN const char ruby_version[];\nRUBY_EXTERN const char ruby_release_date[];\nRUBY_EXTERN const char ruby_platform[];\nRUBY_EXTERN const int ruby_patchlevel;\nRUBY_EXTERN const char *ruby_description;\nRUBY_EXTERN const char *ruby_copyright;\n#endif\n\n#define RUBY_AUTHOR \"Yukihiro Matsumoto\"\n#define RUBY_BIRTH_YEAR 1993\n#define RUBY_BIRTH_MONTH 2\n#define RUBY_BIRTH_DAY 24\n\n#define RUBY_RELEASE_STR \"patchlevel\"\n#define RUBY_RELEASE_NUM RUBY_PATCHLEVEL\n"
  },
  {
    "path": "vms/vms.h",
    "content": "#ifndef VMSRUBY_VMS_H_INCLUDED\n#define VMSRUBY_VMS_H_INCLUDED\n\nextern int isinf(double);\nextern int isnan(double);\nextern int flock(int fd, int oper);\n\nextern int vsnprintf();\n\n#endif\n"
  },
  {
    "path": "vms/vmsruby_private.c",
    "content": "#include \"vmsruby_private.h\"\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid _vmsruby_init(void)\n{\n    _vmsruby_set_switch(\"DECC$WLS\", \"TRUE\");\n}\n\n\n#include <starlet.h>\n#include <string.h>\n#include <descrip.h>\n#include <lnmdef.h>\n\nstruct item_list_3 {\n    short buflen;\n    short itmcod;\n    void *bufadr;\n    void *retlen;\n};\n\nlong _vmsruby_set_switch(char *name, char *value)\n{\n    long status;\n    struct item_list_3 itemlist[20];\n    int i;\n\n    i = 0;\n    itemlist[i].itmcod = LNM$_STRING;\n    itemlist[i].buflen = strlen(value);\n    itemlist[i].bufadr = value;\n    itemlist[i].retlen = NULL;\n    i++;\n    itemlist[i].itmcod = 0;\n    itemlist[i].buflen = 0;\n\n    $DESCRIPTOR(TABLE_d, \"LNM$PROCESS\");\n    $DESCRIPTOR(lognam_d, \"\");\n\n    lognam_d.dsc$a_pointer = name;\n    lognam_d.dsc$w_length  = strlen(name);\n\n    status = sys$crelnm (\n             \t 0, \n             \t &TABLE_d, \n             \t &lognam_d, \n             \t 0,  /* usermode */\n             \t itemlist);\n\n    return status;\n}\n"
  },
  {
    "path": "vms/vmsruby_private.h",
    "content": "#ifndef VMSRUBY_H_INCLUDED\n#define VMSRUBY_H_INCLUDED\n\nvoid _vmsruby_init(void);\nlong _vmsruby_set_switch(char *, char *);\n\n#endif /* VMSRUBY_H_INCLUDED */\n"
  },
  {
    "path": "win32/Makefile.sub",
    "content": "# -*- makefile -*-\n\nSHELL = $(COMSPEC)\nMKFILES = Makefile\nNULL = nul\n\n!ifndef MFLAGS\nMFLAGS=-l\n!endif\n\n!ifndef CROSS_COMPILING\nCROSS_COMPILING = 0\n!endif\n!ifndef LARGEFILE_SUPPORT\nLARGEFILE_SUPPORT = 1\n!endif\n!ifndef win_srcdir\nwin_srcdir = $(srcdir)/win32\n!endif\n\n#### Start of system configuration section. ####\n\n## variables may be overridden by $(compile_dir)/Makefile\n!ifndef srcdir\nsrcdir = ..\n!endif\n!ifndef RUBY_INSTALL_NAME\nRUBY_INSTALL_NAME = ruby$(RUBY_SUFFIX)\n!endif\n!if !defined(RUBYW_INSTALL_NAME) || \"$(RUBYW_INSTALL_NAME)\" == \"$(RUBY_INSTALL_NAME)\"\nRUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME:ruby=rubyw)\n!endif\n!if \"$(RUBYW_INSTALL_NAME)\" == \"$(RUBY_INSTALL_NAME)\"\nRUBYW_INSTALL_NAME = $(RUBY_INSTALL_NAME)w\n!endif\n!if !defined(icondirs) && defined(ICONDIRS)\nicondirs=$(ICONDIRS)\n!endif\n!if defined(icondirs)\nicondirs=$(icondirs:\\=/)\niconinc=-I$(icondirs: = -I)\n!endif\n###############\n\nVPATH = $(srcdir);$(srcdir)/missing;$(srcdir)/win32\n.SUFFIXES: .y .def .lib\n\n!if !defined(CC)\nCC = cl\n!endif\n!if !defined(CPP) || \"$(CPP)\" == \"cl\"\nCPP = $(CC) -E\n!endif\n!if !defined(YACC)\nYACC = byacc\n!endif\nAR = lib -nologo\nPURIFY =\nAUTOCONF = autoconf\nRM = $(COMSPEC) /C $(srcdir:/=\\)\\win32\\rm.bat\n\n!if !defined(PROCESSOR_ARCHITECTURE)\nPROCESSOR_ARCHITECTURE = x86\n!endif\nMACHINE = $(PROCESSOR_ARCHITECTURE)\n!if \"$(PROCESSOR_ARCHITECTURE)\" == \"x86\"\n!if !defined(PROCESSOR_LEVEL)\nPROCESSOR_LEVEL = 5\n!endif\n!if 6 < $(PROCESSOR_LEVEL)\nPROCESSOR_LEVEL = 6\n!endif\n!if $(MSC_VER) < 1400\nPROCESSOR_FLAG = -G$(PROCESSOR_LEVEL)\n!endif\nCPU = i$(PROCESSOR_LEVEL)86\nARCH = i386\n!else\nCPU = $(PROCESSOR_ARCHITECTURE)\nARCH = $(PROCESSOR_ARCHITECTURE)\n!endif\n!if !defined(DEBUGFLAGS) && $(MSC_VER) < 1400\nDEBUGFLAGS = -Zi\n!endif\n!if !defined(OPTFLAGS)\n!if $(MSC_VER) < 1400\nOPTFLAGS = -O2b2xg-\n!else\nOPTFLAGS = -O2b2xty-\n!endif\n!endif\n!if !defined(OS)\nOS = mswin32\n!endif\n!if !defined(RT)\n!error RT not defined.  Retry from configure pass.\n!endif\n\narch = $(ARCH)-$(OS)\n\n!ifndef RUBY_SO_NAME\nRUBY_SO_NAME = $(RT)-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR)\n!endif\n!ifndef RUBY_PLATFORM\nRUBY_PLATFORM = $(arch)\n!endif\n\n!if !defined(prefix)\nprefix = /usr\n!endif\n!if !defined(exec_prefix)\nexec_prefix = $(prefix)\n!endif\n!if !defined(libdir)\nlibdir = $(exec_prefix)/lib\n!endif\n!if !defined(datadir)\ndatadir = /share\n!endif\n!ifndef EXTOUT\nEXTOUT = .ext\n!endif\n!ifndef RIDATADIR\nRIDATADIR = $(DESTDIR)$(datadir)/ri/$(MAJOR).$(MINOR)/system\n!endif\n!ifndef TESTUI\nTESTUI = console\n!endif\n!ifndef TESTS\nTESTS =\n!endif\n!ifndef RDOCTARGET\nRDOCTARGET = install-nodoc\n!endif\n\nOUTFLAG       = -Fe\n!if !defined(RUNTIMEFLAG)\nRUNTIMEFLAG   = -MD\n!endif\n!if !defined(CFLAGS)\nCFLAGS = $(RUNTIMEFLAG) $(DEBUGFLAGS) $(WARNFLAGS) $(OPTFLAGS) $(PROCESSOR_FLAG)\n!endif\n!if !defined(LDFLAGS)\nLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf\n!endif\n!if !defined(XLDFLAGS)\nXLDFLAGS = -stack:$(STACK)\n!endif\n!if !defined(RFLAGS)\nRFLAGS = -r\n!endif\n!if !defined(EXTLIBS)\nEXTLIBS =\n!endif\n!if !defined(LIBS)\nLIBS = oldnames.lib user32.lib advapi32.lib shell32.lib\n!if !defined(USE_WINSOCK2)\nLIBS = $(LIBS) wsock32.lib\n!else\nLIBS = $(LIBS) ws2_32.lib\n!endif\nLIBS = $(LIBS) $(EXTLIBS)\n!endif\n!if !defined(MISSING)\nMISSING = acosh.obj crypt.obj erf.obj win32.obj\n!endif\n\nARFLAGS = -machine:$(MACHINE) -out:\nCC = $(CC) -nologo\nLD = $(CC)\nLDSHARED = $(LD) -LD\nXCFLAGS = -DRUBY_EXPORT -I. -I$(srcdir) -I$(srcdir)/missing $(XCFLAGS)\n!if $(MSC_VER) >= 1400\n# Prevents VC++ 2005 (cl ver 14) warnings\nCRTDEFFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE\nMANIFESTTOOL = mt -nologo\nLDSHARED_1 = @if exist $(@).manifest $(MANIFESTTOOL) -manifest $(@).manifest -outputresource:$(@);2\nLDSHARED_2 = @if exist $(@).manifest $(RM) $(@:/=\\).manifest\n!endif\nCPPFLAGS = $(CRTDEFFLAGS) $(DEFS) $(ARCHDEFS) $(CPPFLAGS)\n\nDLDFLAGS = $(LDFLAGS) -dll\nSOLIBS = \n\nLIBRUBY_LDSHARED = $(LDSHARED)\nLIBRUBY_DLDFLAGS = $(EXTLDFLAGS) -def:$(RUBYDEF)\n\nEXEEXT = .exe\n!if !defined(PROGRAM)\nPROGRAM=$(RUBY_INSTALL_NAME)$(EXEEXT)\n!endif\n!if !defined(WPROGRAM) && defined(RUBYW_INSTALL_NAME)\nWPROGRAM=$(RUBYW_INSTALL_NAME)$(EXEEXT)\n!endif\nRUBYDEF = $(RUBY_SO_NAME).def\n!if $(CROSS_COMPILING)\nMINIRUBY = $(RUBY) -I$(MAKEDIR) -rfake\nRUNRUBY = $(MINIRUBY)\n!else\nMINIRUBY = .\\miniruby$(EXEEXT) -I$(srcdir)/lib\nRUNRUBY = .\\$(PROGRAM)\n!endif\nMINIRUBY = $(MINIRUBY) $(MINIRUBYOPT)\nRUNRUBY = $(RUNRUBY) \"$(srcdir)/runruby.rb\" --extout=\"$(EXTOUT)\" --\n\n!if !defined(STACK)\nSTACK = 0x2000000\n!if defined(STACK_COMMIT)\nSTACK = $(STACK),$(STACK_COMMIT)\n!endif\n!endif\nORGLIBPATH = $(LIB)\n\n#### End of system configuration section. ####\n\nLIBRUBY_A     = $(RUBY_SO_NAME)-static.lib\nLIBRUBY_SO    = $(RUBY_SO_NAME).dll\nLIBRUBY       = $(RUBY_SO_NAME).lib\nLIBRUBYARG    = $(LIBRUBY)\n\n!if $(CROSS_COMPILING)\nPREP          = fake.rb\n!else\nPREP          = miniruby$(EXEEXT)\n!endif\n\n!if !defined(EXTSTATIC)\nEXTSTATIC     = \n!endif\n\nOBJEXT = obj\nASMEXT = asm\n\nINSTALLED_LIST= .installed.list\n\n!if !defined(WINMAINOBJ)\nWINMAINOBJ    = winmain.$(OBJEXT)\n!endif\nMINIOBJS      = dmydln.$(OBJEXT)\nLIBOBJS       = acosh.obj crypt.obj erf.obj strlcpy.obj strlcat.obj win32.obj $(LIBOBJS)\n\n!ifndef COMMON_LIBS\nCOMMON_LIBS  = m\n!endif\n!ifndef COMMON_MACROS\nCOMMON_MACROS = WIN32_LEAN_AND_MEAN WIN32\n!endif\n!ifndef COMMON_HEADERS\n!if !defined(USE_WINSOCK2)\nCOMMON_HEADERS = winsock.h\n!else\nCOMMON_HEADERS = winsock2.h ws2tcpip.h\n!endif\nCOMMON_HEADERS = $(COMMON_HEADERS) windows.h\n!endif\n\nall: $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub $(srcdir)/common.mk\n\nruby: $(PROGRAM)\nrubyw: $(WPROGRAM)\n\n!include $(srcdir)/common.mk\n\n$(MKFILES): $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub $(win_srcdir)/configure.bat $(win_srcdir)/setup.mak\n\t$(COMSPEC) /C $(win_srcdir:/=\\)\\configure.bat $(configure_args)\n\t@echo $(MKFILES) should be updated, re-run $(MAKE).\n\t@exit 1\n\nCONFIG_H = ./.config.h.time\n\nconfig: config.status\n\nconfig.status: $(CONFIG_H)\n\nBANG = !\n\n!if exist(config.h)\n!include config.h\n!endif\n\n$(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub\n\t@echo Creating config.h\n\t@$(COMSPEC) /C $(srcdir:/=\\)\\win32\\ifchange.bat config.h <<\n#if _MSC_VER != $(MSC_VER)\n#error MSC version unmatch: _MSC_VER: $(MSC_VER) is expected.\n#endif\n!if defined(USE_WINSOCK2)\n#define USE_WINSOCK2 $(USE_WINSOCK2)\n!endif\n#define STDC_HEADERS 1\n#define HAVE_SYS_TYPES_H 1\n#define HAVE_SYS_STAT_H 1\n#define HAVE_STDLIB_H 1\n#define HAVE_STRING_H 1\n#define HAVE_MEMORY_H 1\n!if $(MSC_VER) >= 1400\n#define HAVE_LONG_LONG 1\n!endif\n#define HAVE_OFF_T 1\n#define SIZEOF_INT 4\n#define SIZEOF_SHORT 2\n#define SIZEOF_LONG 4\n!if $(MSC_VER) >= 1400\n#define SIZEOF_LONG_LONG 8\n!else\n#define SIZEOF_LONG_LONG 0\n!endif\n#define SIZEOF___INT64 8\n#define SIZEOF_OFF_T 4\n#define SIZEOF_VOIDP 4\n#define SIZEOF_FLOAT 4\n#define SIZEOF_DOUBLE 8\n!if $(MSC_VER) >= 1400\n#define SIZEOF_TIME_T 8\n!else\n#define SIZEOF_TIME_T 4\n!endif\n#define HAVE_PROTOTYPES 1\n#define TOKEN_PASTE(x,y) x##y\n#define HAVE_STDARG_PROTOTYPES 1\n!if $(MSC_VER) > 1100\n#define NORETURN(x) __declspec(noreturn) x\n!endif\n!if $(MSC_VER) >= 1300\n#define DEPRECATED(x) __declspec(deprecated) x\n#define NOINLINE(x) __declspec(noinline) x\n!endif\n#define RUBY_EXTERN extern __declspec(dllimport)\n#define HAVE_DECL_SYS_NERR 1\n!if !defined(WIN32_WCE)\n#define HAVE_LIMITS_H 1\n!endif\n#define HAVE_FCNTL_H 1\n#define HAVE_SYS_UTIME_H 1\n#define HAVE_FLOAT_H 1\n#define rb_pid_t int\n#define rb_gid_t int\n#define rb_uid_t int\n#define HAVE_STRUCT_STAT_ST_RDEV 1\n#define HAVE_ST_RDEV 1\n#define GETGROUPS_T int\n#define RETSIGTYPE void\n!if !defined(WIN32_WCE)\n#define HAVE_ALLOCA 1\n!endif\n#define HAVE_DUP2 1\n#define HAVE_MEMCMP 1\n#define HAVE_MEMMOVE 1\n#define HAVE_MKDIR 1\n#define HAVE_STRCASECMP 1\n#define HAVE_STRNCASECMP 1\n#define HAVE_STRERROR 1\n#define HAVE_STRFTIME 1\n#define HAVE_STRCHR 1\n#define HAVE_STRSTR 1\n#define HAVE_STRTOD 1\n#define HAVE_STRTOL 1\n#define HAVE_STRTOUL 1\n#define HAVE_FLOCK 1\n#define HAVE_VSNPRINTF 1\n#define HAVE_ISNAN 1\n#define HAVE_FINITE 1\n#define HAVE_HYPOT 1\n#define HAVE_FMOD 1\n#define HAVE_FREXP 1\n#define HAVE_MODF 1\n#define HAVE_WAITPID 1\n#define HAVE_FSYNC 1\n#define HAVE_GETCWD 1\n#define HAVE_CHSIZE 1\n#define HAVE_TIMES 1\n#define HAVE_FCNTL 1\n#define HAVE_LINK 1\n!if !defined(WIN32_WCE)\n#define HAVE__SETJMP 1\n!endif\n#define HAVE_TELLDIR 1\n#define HAVE_SEEKDIR 1\n#define HAVE_MKTIME 1\n#define HAVE_COSH 1\n#define HAVE_SINH 1\n#define HAVE_TANH 1\n#define HAVE_TZNAME 1\n#define HAVE_DAYLIGHT 1\n#define SETPGRP_VOID 1\n#define RSHIFT(x,y) ((x)>>(int)y)\n#define FILE_COUNT _cnt\n#define FILE_READPTR _ptr\n#define RUBY_SETJMP(env) _setjmp(env)\n#define RUBY_LONGJMP(env,val) longjmp(env,val)\n#define RUBY_JMP_BUF jmp_buf\n#define inline __inline\n#define NEED_IO_SEEK_BETWEEN_RW 1\n!if \"$(PROCESSOR_ARCHITECTURE)\" == \"x86\" || \"$(ARCH)\" == \"x64\" || \"$(ARCH)\" == \"ia64\"\n#define STACK_GROW_DIRECTION -1\n!endif\n#define DEFAULT_KCODE KCODE_NONE\n#define DLEXT \".so\"\n#define DLEXT2 \".dll\"\n#define RUBY_LIB \"/lib/ruby/$(MAJOR).$(MINOR)\"\n#define RUBY_SITE_LIB \"/lib/ruby/site_ruby\"\n#define RUBY_SITE_LIB2 \"/lib/ruby/site_ruby/$(MAJOR).$(MINOR)\"\n#define RUBY_VENDOR_LIB \"/lib/ruby/vendor_ruby\"\n#define RUBY_VENDOR_LIB2 \"/lib/ruby/vendor_ruby/$(MAJOR).$(MINOR)\"\n#define RUBY_PLATFORM \"$(arch)\"\n#define RUBY_ARCHLIB \"/lib/ruby/$(MAJOR).$(MINOR)/$(ARCH)-$(OS)\"\n#define RUBY_SITE_ARCHLIB \"/lib/ruby/site_ruby/$(MAJOR).$(MINOR)/$(ARCH)-$(RT)\"\n#define RUBY_VENDOR_ARCHLIB \"/lib/ruby/vendor_ruby/$(MAJOR).$(MINOR)/$(ARCH)-$(RT)\"\n#define LIBRUBY_SO \"$(LIBRUBY_SO)\"\n#if 0\n$(BANG)if \"$(RUBY_SO_NAME)\"!=\"$$(RUBY_SO_NAME)\" || \"$(ARCH)-$(OS)\"!=\"$$(ARCH)-$$(OS)\"\nconfig.h: nul\n$(BANG)endif\n#endif\n!if defined(WIN32_WCE)\n#define GC_MALLOC_LIMIT 4000000\n#define stricmp _stricmp\n#define fopen   wce_fopen\n#define open\t   _open\n#define read\t   _read\n#define write\t   _write\n#define lseek      _lseek\n\n#if _WIN32_WCE < 300\n  #define isascii(c) ( (c>=0x00&&c<=0x7f)?1:0 )\n  #define isspace(c) ( ((c>=0x09&&c<=0x0d)||c==0x20)?1:0 )\n  #define isdigit(c) ( (c>=0x30&&c<=0x39)?1:0 )\n  #define isupper(c) ( (c>='A'&&c<='Z')?1:0 )\n  #define isalpha(c) ( ((c>='A'&&c<='Z')||(c>='a'&&c<='z'))?1:0 )\n  #define isprint(c) ( (c>=0x20&&c<=0x7e)?1:0 )\n  #define isalnum(c) ( (isalpha(c)||isdigit(c))?1:0 )\n  #define iscntrl(c) ( ((c>=0x00&&c<=0x1f)||c==0x7f)?1:0 )\n  #define islower(c) ( (c>='a'&&c<='z')?1:0 )\n  #define ispunct(c) ( !(isalnum(c)||isspace(c))?1:0 )\n  #define isxdigit(c) ( ((c>=0&&c<=9)||(c>='A'&&c<='F')||(c>='a'&&c<='f'))?1:0 )\n#endif\n!endif\n<<\n\t@exit > $(@:/=\\)\n\nconfig.status: $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub $(srcdir)/common.mk\n\t@echo Creating $@\n\t@exit <<$@\n# Generated automatically by Makefile.sub.\ns,@SHELL@,$$(COMSPEC),;t t\ns,@BUILD_FILE_SEPARATOR@,\\,;t t\ns,@PATH_SEPARATOR@,;,;t t\ns,@CFLAGS@,$(CFLAGS),;t t\ns,@CPPFLAGS@,$(CPPFLAGS),;t t\ns,@CXXFLAGS@,$(CXXFLAGS),;t t\ns,@FFLAGS@,$(FFLAGS),;t t\ns,@LDFLAGS@,,;t t\ns,@LIBS@,$(LIBS),;t t\ns,@exec_prefix@,$${prefix},;t t\ns,@prefix@,,;t t\ns,@program_transform_name@,s,$$,$(RUBY_SUFFIX),,;t t\ns,@bindir@,$${exec_prefix}/bin,;t t\ns,@sbindir@,$${exec_prefix}/sbin,;t t\ns,@libexecdir@,$${exec_prefix}/libexec,;t t\ns,@datadir@,$${prefix}/share,;t t\ns,@sysconfdir@,$${prefix}/etc,;t t\ns,@sharedstatedir@,/etc,;t t\ns,@localstatedir@,/var,;t t\ns,@libdir@,$${exec_prefix}/lib,;t t\ns,@includedir@,$${prefix}/include,;t t\ns,@oldincludedir@,/usr/include,;t t\ns,@infodir@,$${prefix}/info,;t t\ns,@mandir@,$${prefix}/man,;t t\ns,@build@,$(CPU)-pc-$(OS),;t t\ns,@build_alias@,$(CPU)-$(OS),;t t\ns,@build_cpu@,$(CPU),;t t\ns,@build_vendor@,pc,;t t\ns,@build_os@,$(OS),;t t\ns,@host@,$(CPU)-pc-$(OS),;t t\ns,@host_alias@,$(CPU)-$(OS),;t t\ns,@host_cpu@,$(CPU),;t t\ns,@host_vendor@,pc,;t t\ns,@host_os@,$(OS),;t t\ns,@target@,$(ARCH)-pc-$(OS),;t t\ns,@target_alias@,$(ARCH)-$(OS),;t t\ns,@target_cpu@,$(ARCH),;t t\ns,@target_vendor@,pc,;t t\ns,@target_os@,$(OS),;t t\ns,@CC@,$(CC),;t t\ns,@CPP@,$(CPP),;t t\ns,@YACC@,$(YACC),;t t\ns,@RANLIB@,,;t t\ns,@AR@,$(AR),;t t\ns,@ARFLAGS@,$(ARFLAGS),;t t\ns,@LN_S@,$(LN_S),;t t\ns,@SET_MAKE@,MFLAGS = -$$(MAKEFLAGS),;t t\ns,@CP@,copy > nul,;t t\ns,@LIBOBJS@,$(LIBOBJS),;t t\ns,@ALLOCA@,$(ALLOCA),;t t\ns,@DEFAULT_KCODE@,$(DEFAULT_KCODE),;t t\ns,@EXEEXT@,.exe,;t t\ns,@OBJEXT@,$(OBJEXT),;t t\ns,@XCFLAGS@,$(XCFLAGS),;t t\ns,@XLDFLAGS@,$(XLDFLAGS),;t t\ns,@DLDFLAGS@,$(DLDFLAGS) $$(LIBPATH),;t t\ns,@ARCH_FLAG@,$(ARCH_FLAG),;t t\ns,@STATIC@,$(STATIC),;t t\ns,@CCDLFLAGS@,,;t t\ns,@LDSHARED@,$(LDSHARED),;t t\ns,@DLEXT@,so,;t t\ns,@DLEXT2@,dll,;t t\ns,@LIBEXT@,lib,;t t\ns,@STRIP@,$(STRIP),;t t\ns,@EXTSTATIC@,$(EXTSTATIC),;t t\ns,@setup@,Setup,;t t\ns,@MINIRUBY@,$(MINIRUBY),;t t\ns,@PREP@,miniruby$(EXEEXT),;t t\ns,@RUNRUBY@,$(RUNRUBY),;t t\ns,@EXTOUT@,$(EXTOUT),;t t\ns,@ARCHFILE@,,;t t\ns,@RDOCTARGET@,$(RDOCTARGET),;t t\ns,@LIBRUBY_LDSHARED@,$(LIBRUBY_LDSHARED),;t t\ns,@LIBRUBY_DLDFLAGS@,$(LIBRUBY_DLDFLAGS),;t t\ns,@RUBY_INSTALL_NAME@,$(RUBY_INSTALL_NAME),;t t\ns,@rubyw_install_name@,$(RUBYW_INSTALL_NAME),;t t\ns,@RUBYW_INSTALL_NAME@,$(RUBYW_INSTALL_NAME),;t t\ns,@RUBY_SO_NAME@,$(RUBY_SO_NAME),;t t\ns,@LIBRUBY_A@,$$(RUBY_SO_NAME)-static.lib,;t t\ns,@LIBRUBY_SO@,$$(RUBY_SO_NAME).dll,;t t\ns,@LIBRUBY_ALIASES@,$(LIBRUBY_ALIASES),;t t\ns,@LIBRUBY@,$$(RUBY_SO_NAME).lib,;t t\ns,@LIBRUBYARG@,$$(LIBRUBYARG_SHARED),;t t\ns,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A),;t t\ns,@LIBRUBYARG_SHARED@,$$(LIBRUBY),;t t\ns,@SOLIBS@,$(SOLIBS),;t t\ns,@DLDLIBS@,$(DLDLIBS),;t t\ns,@ENABLE_SHARED@,yes,;t t\ns,@OUTFLAG@,$(OUTFLAG),;t t\ns,@CPPOUTFILE@,-P,;t t\ns,@LIBPATHFLAG@, -libpath:\"%s\",;t t\ns,@RPATHFLAG@,,;t t\ns,@LIBARG@,%s.lib,;t t\ns,@LINK_SO@,$$(LDSHARED) -Fe$$(@) $$(OBJS) $$(LIBS) $$(LOCAL_LIBS) $$(DLDFLAGS) -implib:$$(*F:.so=)-$$(arch).lib -pdb:$$(*F:.so=)-$$(arch).pdb -def:$$(DEFFILE),;t t\n!if $(MSC_VER) >= 1400\ns,@LINK_SO@,$(MANIFESTTOOL) -manifest $$(@).manifest -outputresource:$$(@);2,;t t\ns,@LINK_SO@,@$$(RM) $$(@:/=\\).manifest,;t t\n!endif\ns,@COMPILE_C@,$$(CC) $$(INCFLAGS) $$(CFLAGS) $$(CPPFLAGS) -c -Tc$$(<:\\=/),;t t\ns,@COMPILE_CXX@,$$(CXX) $$(INCFLAGS) $$(CXXFLAGS) $$(CPPFLAGS) -c -Tp$$(<:\\=/),;t t\ns,@COMPILE_RULES@,{$$(hdrdir)}.%s{}.%s: {$$(topdir)}.%s{}.%s: {$$(srcdir)}.%s{}.%s: .%s.%s:,;t t\ns,@RULE_SUBST@,{.;$$(VPATH)}%s,;t t\ns,@TRY_LINK@,$$(CC) -Feconftest $$(INCFLAGS) -I$$(hdrdir) $$(CPPFLAGS) $$(CFLAGS) $$(src) $$(LOCAL_LIBS) $$(LIBS) -link $$(LDFLAGS) $$(LIBPATH) $$(XLDFLAGS),;t t\ns,@COMMON_LIBS@,$(COMMON_LIBS),;t t\ns,@COMMON_MACROS@,$(COMMON_MACROS),;t t\ns,@COMMON_HEADERS@,$(COMMON_HEADERS),;t t\ns,@DISTCLEANFILES@,vc*.pdb,;t t\ns,@EXPORT_PREFIX@, ,;t t\ns,@arch@,$(ARCH)-$(OS),;t t\ns,@sitearch@,$(ARCH)-$(RT),;t t\ns,@sitedir@,$${prefix}/lib/ruby/site_ruby,;t t\ns,@vendordir@,$${prefix}/lib/ruby/vendor_ruby,;t t\ns,@configure_args@,--with-make-prog=nmake --enable-shared $(configure_args),;t t\ns,@configure_input@,$$configure_input,;t t\ns,@srcdir@,$(srcdir),;t t\ns,@top_srcdir@,$(srcdir),;t t\n<<KEEP\n\nminiruby$(EXEEXT):\n\t\t@echo. $(LIBS)\n\t\t@$(RM) $@\n\t\t$(PURIFY) $(CC) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(LIBS) -Fe$@ $(LDFLAGS)\n\t\t$(LDSHARED_1)\n\t\t$(LDSHARED_2)\n\n!if \"$(PROGRAM)\" != \"\"\n$(PROGRAM):\t$(RUBY_INSTALL_NAME).res\n\t\t$(PURIFY) $(CC) $(MAINOBJ) $(RUBY_INSTALL_NAME).res \\\n\t\t\t$(OUTFLAG)$@ $(LIBRUBYARG) $(LDFLAGS) $(XLDFLAGS)\n\t\t$(LDSHARED_1)\n\t\t$(LDSHARED_2)\n!endif\n\n!if \"$(WPROGRAM)\" != \"\"\n$(WPROGRAM):\t$(MAINOBJ) $(WINMAINOBJ) $(LIBRUBY_SO) $(RUBYW_INSTALL_NAME).res\n\t\t$(PURIFY) $(CC) $(MAINOBJ) $(WINMAINOBJ) \\\n\t\t\t$(RUBYW_INSTALL_NAME).res $(OUTFLAG)$@ $(LIBRUBYARG) \\\n\t\t\t$(LDFLAGS) $(XLDFLAGS) -subsystem:Windows\n\t\t$(LDSHARED_1)\n\t\t$(LDSHARED_2)\n!endif\n\n$(LIBRUBY_A):\t$(OBJS) $(DMYEXT)\n\t\t$(AR) $(ARFLAGS)$@ $(OBJS) $(DMYEXT)\n\n$(LIBRUBY):\t$(RUBYDEF)\n\t\t$(AR) $(ARFLAGS)$@ -def:$(RUBYDEF)\n\n$(LIBRUBY_SO):\t$(LIBRUBY_A) $(DLDOBJS) $(RUBYDEF) $(RUBY_SO_NAME).res\n\t\t@echo. $(DLDOBJS)\n\t\t@-$(PRE_LIBRUBY_UPDATE)\n\t\t$(LDSHARED) $(MAINOBJ) $(DLDOBJS) $(LIBRUBY_A) \\\n\t\t\t$(RUBY_SO_NAME).res $(LIBS) -Fe$@ $(LDFLAGS) \\\n\t\t\t$(LIBRUBY_DLDFLAGS)\n\t\t$(LDSHARED_1)\n\t\t$(LDSHARED_2)\n\n$(RUBYDEF):\t$(LIBRUBY_A) $(PREP)\n\t\t$(MINIRUBY) $(srcdir)/win32/mkexports.rb -output=$@ $(LIBRUBY_A)\n\n{$(win_srcdir)}.def.lib:\n\t\t$(AR) $(ARFLAGS)$@ -def:$<\n\nclean-local::\n\t\t@$(RM) $(WINMAINOBJ) ext\\extinit.c ext\\extinit.$(OBJEXT) ext\\vc*.pdb miniruby.lib\n\t\t@$(RM) $(RUBY_INSTALL_NAME).res $(RUBYW_INSTALL_NAME).res $(RUBY_SO_NAME).res\n\t\t@$(RM) *.map *.pdb *.ilk *.exp $(RUBYDEF)\n\ndistclean-local::\n\t\t@$(RM) ext\\config.cache $(RBCONFIG:/=\\) $(CONFIG_H:/=\\)\n\t\t@$(RM) $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc\n\n$(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc: $(RBCONFIG)\n\t\t@$(MINIRUBY) $(srcdir)/win32/resource.rb \\\n\t\t\t-ruby_name=$(RUBY_INSTALL_NAME) \\\n\t\t\t-rubyw_name=$(RUBYW_INSTALL_NAME) \\\n\t\t\t-so_name=$(RUBY_SO_NAME) \\\n!if defined(WIN32_WCE)\n\t\t\t-wce_ver=$(SUBSYSVERSION) \\\n!endif\n\t\t\t. $(icondirs) $(win_srcdir)\n\nfake.rb: $(MKFILES)\n\t@echo Creating <<$@\nclass Object\n  CROSS_COMPILING = RUBY_PLATFORM\n  remove_const :RUBY_PLATFORM\n  remove_const :RUBY_VERSION\n  RUBY_PLATFORM = \"$(ARCH)\"\n  RUBY_VERSION = \"$(MAJOR).$(MINOR).$(TEENY)\"\nend\nclass File\n  remove_const :ALT_SEPARATOR\n  ALT_SEPARATOR = \"\\\\\"\nend\n<<KEEP\n\nupdate-rubyspec:\n!if exist($(srcdir:/=\\)\\rubyspec)\n\tcd $(srcdir:/=\\)\\rubyspec\\mspec\n\tgit pull\n\tcd ..\\spec\\rubyspec\n\tgit pull\n!else\n\tgit clone $(MSPEC_GIT_URL) $(srcdir)/rubyspec/mspec\n\tgit clone $(RUBYSPEC_GIT_URL) $(srcdir)/rubyspec/spec/rubyspec\n!endif\n\ntest-rubyspec:\n!if exist($(srcdir:/=\\)\\rubyspec)\n\t$(RUNRUBY) $(srcdir)/rubyspec/mspec/bin/mspec -r$(srcdir)/ext/purelib.rb $(srcdir)/rubyspec/spec/rubyspec/$(MAJOR).$(MINOR)\n!else\n\t@echo No rubyspec here.  put rubyspec to srcdir first.\n\t@cd $(srcdir:/=\\)\\rubyspec\n!endif\n\n{$(srcdir)/missing}.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)\n{$(srcdir)/win32}.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)\n{$(win_srcdir)}.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)\n{$(win_srcdir)/sys}.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)\n{$(srcdir)}.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)\n.c.obj:\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\\=/)\n\n.rc.res:\n\t$(RC) -I. -I$(<D) $(iconinc) -I$(srcdir)/win32 $(RFLAGS) -fo$@ $(<:\\=/)\n\n{$(srcdir)}.y.c:\n\t$(YACC) $(YFLAGS) $(<:\\=/)\n\tsed -e \"s!^ *extern char \\*getenv();!/* & */!;s/^\\(#.*\\)y\\.tab/\\1parse/\" y.tab.c > $@\n\t@del y.tab.c\n\n$(OBJS): {$(srcdir)}win32/win32.h\n\ndir.$(OBJEXT) win32.$(OBJEXT): {$(srcdir)}win32/dir.h\n\next/extinit.obj: ext/extinit.c $(SETUP)\n\t$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -Fo$@ -c ext/extinit.c\n"
  },
  {
    "path": "win32/README.win32",
    "content": "=begin\n\n= How to build ruby using Visual C++\n\n== Requirement\n\n(1) Visual C++ 5.0 or later.\n\n(2) If you want to run `((%nmake clean%))' or `((%nmake distclean%))'\n    properly, you must install UNIX compatible `((%rm%))' command on\n    your ((|PATH|)) if you want to clean after compile.\n\n(3) Please set environment variable (({INCLUDE})), (({LIB})), (({PATH}))\n    to run required commands properly from the command line.\n\n    Note: building ruby requires following commands.\n     * nmake\n     * cl\n     * lib\n     * dumpbin\n\n== How to compile and install\n\n(1) Execute win32\\configure.bat on your build directory.\n    You can specify the target platform as an argument.\n    For example, run `((%configure i686-mswin32%))'\n\n(2) Change ((|RUBY_INSTALL_NAME|)) and ((|RUBY_SO_NAME|)) in (({Makefile}))\n    if you want to change the name of the executable files. \n    And add ((|RUBYW_INSTALL_NAME|)) to change the name of the\n    executable without console window if also you want.\n\n(3) Run `((%nmake%))'\n\n(4) If you want to make rubyw.exe, run `((%nmake rubyw.exe%))'\n\n(5) Run `((%nmake test%))'\n\n(6) Run `((%nmake DESTDIR=<install_directory> install%))'\n\n    This command will create following directories and install files onto them.\n      * <install_directory>\\bin\n      * <install_directory>\\lib\n      * <install_directory>\\lib\\ruby\n      * <install_directory>\\lib\\ruby\\<MAJOR>.<MINOR>\n      * <install_directory>\\lib\\ruby\\<MAJOR>.<MINOR>\\<PLATFORM>\n      * <install_directory>\\lib\\ruby\\site_ruby\n      * <install_directory>\\lib\\ruby\\site_ruby\\<MAJOR>.<MINOR>\n      * <install_directory>\\lib\\ruby\\site_ruby\\<MAJOR>.<MINOR>\\<PLATFORM>\n      * <install_directory>\\man\\man1\n    If Ruby's version is `x.y.z', the ((|<MAJOR>|)) is `x' and the ((|<MINOR>|)) is `y'.\n    The default ((|<PLATFORM>|)) is `(({i386-mswin32}))'.\n\n== Icons\n\nAny icon files(*.ico) in the build directory, directories specified with\n((|icondirs|)) make variable and (({win32})) directory under the ruby\nsource directory will be included in DLL or executable files, according\nto their base names.\n    $(RUBY_INSTALL_NAME).ico or ruby.ico   --> $(RUBY_INSTALL_NAME).exe\n    $(RUBYW_INSTALL_NAME).ico or rubyw.ico --> $(RUBYW_INSTALL_NAME).exe\n    the others                             --> $(RUBY_SO_NAME).dll\n\nAlthough no icons are distributed with the ruby source or in the official \nsite, you can use anything you like. For example, followings are written \nin Japanese, but you can download at least.\n\n* ((<URL:http://member.nifty.ne.jp/ueivu/rubyico.html>)) or\n  ((<zipped icons|URL:http://member.nifty.ne.jp/ueivu/Ruby_ico.zip>))\n* ((<URL:http://homepage1.nifty.com/a_nakata/ruby/>)) or\n  ((<icon itself|URL:http://homepage1.nifty.com/a_nakata/ruby/RubyIcon.ico>))\n\n== Build examples\n\n* Build on the ruby source directory.\n\n  ex.)\n    ruby source directory:  C:\\ruby\n    build directory:        C:\\ruby\n    install directory:      C:\\usr\\local\n\n    C:\n    cd \\ruby\n    win32\\configure\n    nmake\n    nmake test\n    nmake DESTDIR=/usr/local install\n\n* Build on the relative directory from the ruby source directory.\n\n  ex.)\n    ruby source directory:  C:\\ruby\n    build directory:        C:\\ruby\\mswin32\n    install directory:      C:\\usr\\local\n\n    C:\n    cd \\ruby\n    mkdir mswin32\n    cd mswin32\n    ..\\win32\\configure\n    nmake\n    nmake test\n    nmake DESTDIR=/usr/local install\n\n* Build on the different drive.\n\n  ex.)\n    ruby source directory:  C:\\src\\ruby\n    build directory:        D:\\build\\ruby\n    install directory:      C:\\usr\\local\n\n    D:\n    cd D:\\build\\ruby\n    C:\\src\\ruby\\win32\\configure\n    nmake\n    nmake test\n    nmake DESTDIR=C:/usr/local install\n\n== Bugs\n\nYou can ((*NOT*)) use a path name contains any white space characters as\nthe ruby source directory, this restriction comes from the behavior of\n(({!INCLUDE})) directives of (({NMAKE})).\n((- you may call it a bug. -))\n\n=end\n"
  },
  {
    "path": "win32/configure.bat",
    "content": "@echo off\r\n::: Don't set environment variable in batch file other than autoexec.bat\r\n::: to avoid \"Out of environment space\" problem on Windows 95/98.\r\n::: set TMPMAKE=~tmp~.mak\r\n\r\necho> ~tmp~.mak ####\r\necho>> ~tmp~.mak conf = %0\r\necho>> ~tmp~.mak $(conf:\\=/): nul\r\necho>> ~tmp~.mak \t@del ~tmp~.mak\r\necho>> ~tmp~.mak \t@-$(MAKE) -l$(MAKEFLAGS) -f $(@D)/setup.mak \\\r\n:loop\r\nif \"%1\" == \"\" goto :end\r\nif \"%1\" == \"--prefix\" goto :prefix\r\nif \"%1\" == \"--srcdir\" goto :srcdir\r\nif \"%1\" == \"srcdir\" goto :srcdir\r\nif \"%1\" == \"--target\" goto :target\r\nif \"%1\" == \"target\" goto :target\r\nif \"%1\" == \"--with-static-linked-ext\" goto :extstatic\r\nif \"%1\" == \"--with-winsock2\" goto :winsock2\r\nif \"%1\" == \"--program-suffix\" goto :suffix\r\nif \"%1\" == \"--program-name\" goto :installname\r\nif \"%1\" == \"--install-name\" goto :installname\r\nif \"%1\" == \"--so-name\" goto :soname\r\nif \"%1\" == \"--enable-install-doc\" goto :enable-rdoc\r\nif \"%1\" == \"--disable-install-doc\" goto :disable-rdoc\r\nif \"%1\" == \"--extout\" goto :extout\r\nif \"%1\" == \"-h\" goto :help\r\nif \"%1\" == \"--help\" goto :help\r\n  echo>> ~tmp~.mak \t\"%1\" \\\r\n  shift\r\ngoto :loop\r\n:srcdir\r\n  echo>> ~tmp~.mak \t\"srcdir=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:prefix\r\n  echo>> ~tmp~.mak \t\"prefix=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:suffix\r\n  echo>> ~tmp~.mak \t\"RUBY_SUFFIX=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:installname\r\n  echo>> ~tmp~.mak \t\"RUBY_INSTALL_NAME=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:soname\r\n  echo>> ~tmp~.mak \t\"RUBY_SO_NAME=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:target\r\n  echo>> ~tmp~.mak \t\"%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:extstatic\r\n  echo>> ~tmp~.mak \t\"EXTSTATIC=static\" \\\r\n  shift\r\ngoto :loop\r\n:winsock2\r\n  echo>> ~tmp~.mak \t\"USE_WINSOCK2=1\" \\\r\n  shift\r\ngoto :loop\r\n:enable-rdoc\r\n  echo>> ~tmp~.mak \t\"RDOCTARGET=install-doc\" \\\r\n  shift\r\ngoto :loop\r\n:disable-rdoc\r\n  echo>> ~tmp~.mak \t\"RDOCTARGET=install-nodoc\" \\\r\n  shift\r\ngoto :loop\r\n:extout\r\n  echo>> ~tmp~.mak \t\"EXTOUT=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:help\r\n  echo Configuration:\r\n  echo   --help                  display this help\r\n  echo   --srcdir=DIR            find the sources in DIR [configure dir or `..']\r\n  echo Installation directories:\r\n  echo   --prefix=PREFIX         install files in PREFIX (ignored currently)\r\n  echo System types:\r\n  echo   --target=TARGET         configure for TARGET [i386-mswin32]\r\n  echo Optional Package:\r\n  echo   --with-winsock2         link winsock2\r\n  echo   --with-static-linked-ext link external modules statically\r\n  echo   --enable-install-doc    install rdoc indexes during install\r\n  del ~tmp~.mak\r\ngoto :exit\r\n:end\r\necho>> ~tmp~.mak \tWIN32DIR=$(@D)\r\nnmake -alf ~tmp~.mak\r\n:exit\r\n"
  },
  {
    "path": "win32/dir.h",
    "content": "#ifdef __BORLANDC__\n#  ifndef WIN32_DIR_H_\n#    define WIN32_DIR_H_\n#    include <sys/types.h>\n#  endif\n#endif\n\nstruct direct\n{\n    long d_namlen;\n    ino_t d_ino;\n    char d_name[256];\n    char d_isdir; /* directory */\n    char d_isrep; /* reparse point */\n};\ntypedef struct {\n    char *start;\n    char *curr;\n    long size;\n    long nfiles;\n    long loc;  /* [0, nfiles) */\n    struct direct dirstr;\n    char *bits;  /* used for d_isdir and d_isrep */\n} DIR;\n\n\nDIR*           rb_w32_opendir(const char*);\nstruct direct* rb_w32_readdir(DIR *);\nlong           rb_w32_telldir(DIR *);\nvoid           rb_w32_seekdir(DIR *, long);\nvoid           rb_w32_rewinddir(DIR *);\nvoid           rb_w32_closedir(DIR *);\n\n#define opendir   rb_w32_opendir\n#define readdir   rb_w32_readdir\n#define telldir   rb_w32_telldir\n#define seekdir   rb_w32_seekdir\n#define rewinddir rb_w32_rewinddir\n#define closedir  rb_w32_closedir\n"
  },
  {
    "path": "win32/ifchange.bat",
    "content": "@echo off\r\n:: usage: ifchange target temporary\r\n\r\n:: check if fc.exe works.\r\necho foo > conftest1.tmp\r\necho bar > conftest2.tmp\r\nfc.exe conftest1.tmp conftest2.tmp > nul\r\nif not errorlevel 1 goto :brokenfc\r\ndel conftest1.tmp > nul\r\ndel conftest2.tmp > nul\r\n\r\n:: target does not exist or new file differs from it.\r\nif not exist %1 goto :update\r\nfc.exe %1 %2 > nul\r\nif errorlevel 1 goto :update\r\n\r\n:unchange\r\necho %1 unchanged.\r\ndel %2\r\ngoto :end\r\n\r\n:brokenfc\r\ndel conftest1.tmp > nul\r\ndel conftest2.tmp > nul\r\necho FC.EXE does not work properly.\r\necho assuming %1 should be changed.\r\n\r\n:update\r\necho %1 updated.\r\nif exist %1 del %1\r\ncopy %2 %1 > nul\r\n:end\r\n"
  },
  {
    "path": "win32/mkexports.rb",
    "content": "#!./miniruby -s\n\n$name = $library = $description = nil\n\nSYM = {}\n\nobjs = ARGV.collect {|s| s.tr('/', '\\\\')}\nIO.foreach(\"|dumpbin -symbols \" + objs.join(' ')) do |l|\n  next if /^[0-9A-F]+ 0+ UNDEF / =~ l\n  next unless l.sub!(/.*?\\s(\\(\\)\\s+)?External\\s+\\|\\s+/, \"\")\n  is_data = !$1\n  if /^[@_](?!\\w+@\\d+$)/ =~ l\n    next if /(?!^)@.*@/ =~ l || /@[0-9a-f]{16}$/ =~ l\n    l.sub!(/^[@_]/, '')\n  elsif !l.sub!(/^(\\S+) \\([^@?\\`\\']*\\)$/, '\\1')\n    next\n  end\n  SYM[l.strip] = is_data\nend\n\nexports = []\nif $name\n  exports << \"Name \" + $name\nelsif $library\n  exports << \"Library \" + $library\nend\nexports << \"Description \" + $description.dump if $description\nexports << \"EXPORTS\"\nSYM.sort.each do |sym, is_data|\n  exports << (is_data ? \"#{sym} DATA\" : sym)\nend\n\nif $output\n  open($output, 'w') {|f| f.puts exports.join(\"\\n\")}\nelse\n  puts exports.join(\"\\n\")\nend\n"
  },
  {
    "path": "win32/resource.rb",
    "content": "#!./miniruby -sI.\n\nrequire 'rbconfig'\n\nCONFIG = Config::MAKEFILE_CONFIG\n\nversion = %w'MAJOR MINOR TEENY PATCHLEVEL'.map {|v| CONFIG[v] || '0'}\nfversion = version.join(',')\nrversion = version.join('.')\n\n$ruby_name ||= CONFIG[\"RUBY_INSTALL_NAME\"]\n$rubyw_name ||= CONFIG[\"RUBYW_INSTALL_NAME\"] || $ruby_name.sub(/ruby/, '\\&w')\n$so_name ||= CONFIG[\"RUBY_SO_NAME\"]\n\nicons = {}\ndef icons.find(path)\n  if File.directory?(path)\n    Dir.open(File.expand_path(path)) do |d|\n      d.grep(/\\.ico$/i) {|i| self[$`] = i}\n    end\n  else\n    self[File.basename(path, '.ico')] = path\n  end\n  self\nend\n\nif ARGV.empty?\n  icons.find('.')\nelse\n  ARGV.each {|i| icons.find(i)}\nend\n\nruby_icon = rubyw_icon = nil\n[$ruby_name, 'ruby'].find do |i|\n  if i = icons[i]\n    ruby_icon = \"1 ICON DISCARDABLE \"+i.dump+\"\\n\"\n  end\nend\n[$rubyw_name, 'rubyw'].find do |i|\n  if i = icons[i]\n    rubyw_icon = \"1 ICON DISCARDABLE \"+i.dump+\"\\n\"\n  end\nend\ndll_icons = []\nicons.keys.sort.each do |i|\n  dll_icons << \"#{dll_icons.size + 1} ICON DISCARDABLE \"+icons[i].dump+\"\\n\"\nend\n\n[ # base name    extension         file type  desc, icons\n  [$ruby_name,   CONFIG[\"EXEEXT\"], 'VFT_APP', 'CUI', ruby_icon],\n  [$rubyw_name,  CONFIG[\"EXEEXT\"], 'VFT_APP', 'GUI', rubyw_icon || ruby_icon],\n  [$so_name,     '.dll',           'VFT_DLL', 'DLL', dll_icons.join],\n].each do |base, ext, type, desc, icons|\n  open(base + '.rc', \"w\") { |f|\n    f.binmode if /mingw/ =~ RUBY_PLATFORM\n\n    f.print <<EOF\n#ifndef __BORLANDC__\n#include <windows.h>\n#include <winver.h>\n#endif\n\n#{icons || ''}\nVS_VERSION_INFO VERSIONINFO\n FILEVERSION    #{fversion}\n PRODUCTVERSION #{fversion}\n FILEFLAGSMASK  0x3fL\n FILEFLAGS      0x0L\n FILEOS         VOS__WINDOWS32\n FILETYPE       #{type}\n FILESUBTYPE    VFT2_UNKNOWN\nBEGIN\n BLOCK \"StringFileInfo\"\n BEGIN\n  BLOCK \"000004b0\"\n  BEGIN\n   VALUE \"FileDescription\",  \"Ruby interpreter (#{desc}) #{rversion} [#{RUBY_PLATFORM}]\\\\0\"\n   VALUE \"FileVersion\",      \"#{fversion}\\\\0\"\n   VALUE \"Home Page\",        \"http://www.ruby-lang.org/\\\\0\"\n   VALUE \"InternalName\",     \"#{base + ext}\\\\0\"\n   VALUE \"LegalCopyright\",   \"Copyright (C) 1993-#{RUBY_RELEASE_DATE[/\\d+/]} Yukihiro Matsumoto\\\\0\"\n   VALUE \"OriginalFilename\", \"#{base + ext}\\\\0\"\n   VALUE \"Platform\",         \"#{RUBY_PLATFORM}\\\\0\"\n   VALUE \"ProductVersion\",   \"#{fversion}\\\\0\"\n   VALUE \"Release Date\",     \"#{RUBY_RELEASE_DATE}\\\\0\"\n   VALUE \"Version\",          \"#{rversion}\\\\0\"\n  END\n END\n BLOCK \"VarFileInfo\"\n BEGIN\n  VALUE \"Translation\", 0x0, 0x4b0\n END\nEND\nEOF\n  }\nend\n\n"
  },
  {
    "path": "win32/rm.bat",
    "content": "@echo off\r\nif \"%1\" == \"-f\" shift\r\n:begin\r\nif \"%1\" == \"\" goto :end\r\nif exist \"%1\" del \"%1\"\r\nshift\r\ngoto :begin\r\n:end\r\n"
  },
  {
    "path": "win32/setup.mak",
    "content": "# -*- makefile -*-\n\n!if \"$(srcdir)\" != \"\"\nWIN32DIR = $(srcdir)/win32\n!elseif \"$(WIN32DIR)\" == \"win32\"\nsrcdir = .\n!elseif \"$(WIN32DIR)\" == \"$(WIN32DIR:/win32=)/win32\"\nsrcdir = $(WIN32DIR:/win32=)\n!else\nsrcdir = $(WIN32DIR)/..\n!endif\n!ifndef prefix\nprefix = /usr\n!endif\nOS = mswin32\nBANG = !\nAPPEND = echo.>>$(MAKEFILE)\n!ifdef MAKEFILE\nMAKE = $(MAKE) -f $(MAKEFILE)\n!else\nMAKEFILE = Makefile\n!endif\nARCH = PROCESSOR_ARCHITECTURE\nCPU = PROCESSOR_LEVEL\nCC = cl -nologo\nCPP = $(CC) -EP\n\nall: -prologue- -generic- -epilogue-\ni386-$(OS): -prologue- -i386- -epilogue-\ni486-$(OS): -prologue- -i486- -epilogue-\ni586-$(OS): -prologue- -i586- -epilogue-\ni686-$(OS): -prologue- -i686- -epilogue-\nalpha-$(OS): -prologue- -alpha- -epilogue-\n\n-prologue-: -basic-vars- -system-vars- -version- -program-name-\n\n-basic-vars-: nul\n\t@type << > $(MAKEFILE)\n### Makefile for ruby $(OS) ###\nMAKE = nmake\nsrcdir = $(srcdir:\\=/)\nprefix = $(prefix:\\=/)\nEXTSTATIC = $(EXTSTATIC)\n!if defined(USE_WINSOCK2)\nUSE_WINSOCK2 = $(USE_WINSOCK2)\n!endif\n!if defined(RDOCTARGET)\nRDOCTARGET = $(RDOCTARGET)\n!endif\n!if defined(EXTOUT)\nEXTOUT = $(EXTOUT)\n!endif\n<<\n\n-system-vars-: -osname- -runtime-\n\n-osname-: nul\n\t@echo OS = mswin32 >>$(MAKEFILE)\n\n-runtime-: nul\n\t@$(CC) -MD <<rtname.c user32.lib > nul\n#include <windows.h>\n#include <memory.h>\n#include <string.h>\n#include <stddef.h>\n#include <stdio.h>\n#ifndef MAXPATHLEN\n# define MAXPATHLEN 1024\n#endif\n\nint\nruntime_name()\n{\n    char libpath[MAXPATHLEN+1];\n    char *p, *base = NULL, *ver = NULL;\n    HMODULE msvcrt = NULL;\n    MEMORY_BASIC_INFORMATION m;\n\n    memset(&m, 0, sizeof(m));\n    if (VirtualQuery(stdin, &m, sizeof(m)) && m.State == MEM_COMMIT)\n\tmsvcrt = (HMODULE)m.AllocationBase;\n    GetModuleFileName(msvcrt, libpath, sizeof libpath);\n\n    libpath[sizeof(libpath) - 1] = '\\0';\n    for (p = libpath; *p; p = CharNext(p)) {\n\tif (*p == '\\\\') {\n\t    base = ++p;\n\t}\n    }\n    if (!base) return 0;\n    if (p = strchr(base, '.')) *p = '\\0';\n    for (p = base; *p; p = CharNext(p)) {\n\tif (!isascii(*p)) continue;\n\tif (isupper(*p)) {\n\t    *p = tolower(*p);\n\t}\n\tif (!isdigit(*p)) {\n\t    ver = NULL;\n\t} else if (!ver) {\n\t    ver = p;\n\t}\n    }\n    if (ver) printf(\"OS = $$(OS)_%s\\n\", ver);\n    printf(\"RT = %s\\n\", base);\n    return 1;\n}\n\nint main(int argc, char **argv)\n{\n    if (!runtime_name()) return EXIT_FAILURE;\n    return EXIT_SUCCESS;\n}\n<<\n\t@.\\rtname >>$(MAKEFILE)\n\t@del rtname.*\n\n-version-: nul\n\t@$(APPEND)\n\t@$(CPP) -I$(srcdir) <<\"Creating $(MAKEFILE)\" | find \"=\" >>$(MAKEFILE)\n#include \"version.h\"\nMAJOR = RUBY_VERSION_MAJOR\nMINOR = RUBY_VERSION_MINOR\nTEENY = RUBY_VERSION_TEENY\nMSC_VER = _MSC_VER\n<<\n\n-program-name-:\n\t@type << >>$(MAKEFILE)\n!ifdef RUBY_SUFFIX\nRUBY_SUFFIX = $(RUBY_SUFFIX)\n!endif\n!ifdef RUBY_INSTALL_NAME\nRUBY_INSTALL_NAME = $(RUBY_INSTALL_NAME)\n!endif\n!ifdef RUBY_SO_NAME\nRUBY_SO_NAME = $(RUBY_SO_NAME)\n!endif\n<<\n\n-generic-: nul\n!if defined($(ARCH)) || defined($(CPU))\n\t@type << >>$(MAKEFILE)\n!if defined($(ARCH))\n$(ARCH) = $(PROCESSOR_ARCHITECTURE)\n!endif\n!if defined($(CPU))\n$(CPU) = $(PROCESSOR_LEVEL)\n!endif\n\n<<\n!endif\n\n-alpha-: nul\n\t@echo $(ARCH) = alpha>>$(MAKEFILE)\n-ix86-: nul\n\t@echo $(ARCH) = x86>>$(MAKEFILE)\n\n-i386-: -ix86-\n\t@echo $(CPU) = 3>>$(MAKEFILE)\n-i486-: -ix86-\n\t@echo $(CPU) = 4>>$(MAKEFILE)\n-i586-: -ix86-\n\t@echo $(CPU) = 5>>$(MAKEFILE)\n-i686-: -ix86-\n\t@echo $(CPU) = 6>>$(MAKEFILE)\n\n-epilogue-: nul\n\t@type << >>$(MAKEFILE)\n# OS = $(OS)\n# RUBY_INSTALL_NAME = ruby\n# RUBY_SO_NAME = $$(RT)-$$(RUBY_INSTALL_NAME)$$(MAJOR)$$(MINOR)\n# CFLAGS = -nologo -MD $$(DEBUGFLAGS) $$(OPTFLAGS) $$(PROCESSOR_FLAG)\n# CPPFLAGS = -I. -I$$(srcdir) -I$$(srcdir)/missing -DLIBRUBY_SO=\\\"$$(LIBRUBY_SO)\\\"\n# STACK = 0x2000000\n# LDFLAGS = $$(CFLAGS) -Fm\n# XLDFLAGS = \n# RFLAGS = -r\n# EXTLIBS =\n\n$(BANG)include $$(srcdir)/win32/Makefile.sub\n<<\n\t@$(COMSPEC) /C $(srcdir:/=\\)\\win32\\rm.bat config.h config.status\n\t@echo type `$(MAKE)' to make ruby for $(OS).\n"
  },
  {
    "path": "win32/win32.c",
    "content": "/*\n *  Copyright (c) 1993, Intergraph Corporation\n *\n *  You may distribute under the terms of either the GNU General Public\n *  License or the Artistic License, as specified in the perl README file.\n *\n *  Various Unix compatibility functions and NT specific functions.\n *\n *  Some of this code was derived from the MSDOS port(s) and the OS/2 port.\n *\n */\n\n#include \"ruby.h\"\n#include \"rubysig.h\"\n#include \"dln.h\"\n#include <fcntl.h>\n#include <process.h>\n#include <sys/stat.h>\n/* #include <sys/wait.h> */\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <assert.h>\n#include <ctype.h>\n\n#include <windows.h>\n#include <winbase.h>\n#include <wincon.h>\n#include <shlobj.h>\n#if _MSC_VER >= 1400\n#include <crtdbg.h>\n#endif\n#ifdef __MINGW32__\n#include <mswsock.h>\n#include <mbstring.h>\n#endif\n#include \"win32.h\"\n#include \"win32/dir.h\"\n#ifdef _WIN32_WCE\n#include \"wince.h\"\n#endif\n#ifndef index\n#define index(x, y) strchr((x), (y))\n#endif\n#define isdirsep(x) ((x) == '/' || (x) == '\\\\')\n\n#undef stat\n#undef fclose\n#undef close\n#undef setsockopt\n\n#ifndef bool\n#define bool int\n#endif\n\n#if defined __BORLANDC__ || defined _WIN32_WCE\n#  define _filbuf _fgetc\n#  define _flsbuf _fputc\n#  define enough_to_get(n) (--(n) >= 0)\n#  define enough_to_put(n) (++(n) < 0)\n#else\n#  define enough_to_get(n) (--(n) >= 0)\n#  define enough_to_put(n) (--(n) >= 0)\n#endif\n\n#if HAVE_WSAWAITFORMULTIPLEEVENTS\n# define USE_INTERRUPT_WINSOCK\n#endif\n\n#if USE_INTERRUPT_WINSOCK\n# define WaitForMultipleEvents WSAWaitForMultipleEvents\n# define CreateSignal() (HANDLE)WSACreateEvent()\n# define SetSignal(ev) WSASetEvent(ev)\n# define ResetSignal(ev) WSAResetEvent(ev)\n#else  /* USE_INTERRUPT_WINSOCK */\n# define WaitForMultipleEvents WaitForMultipleObjectsEx\n# define CreateSignal() CreateEvent(NULL, FALSE, FALSE, NULL);\n# define SetSignal(ev) SetEvent(ev)\n# define ResetSignal(ev) (void)0\n#endif /* USE_INTERRUPT_WINSOCK */\n\n#ifdef WIN32_DEBUG\n#define Debug(something) something\n#else\n#define Debug(something) /* nothing */\n#endif\n\n#define TO_SOCKET(x)\t_get_osfhandle(x)\n\nstatic struct ChildRecord *CreateChild(const char *, const char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);\nstatic bool has_redirection(const char *);\nstatic void StartSockets ();\nstatic DWORD wait_events(HANDLE event, DWORD timeout);\n#if !defined(_WIN32_WCE)\nstatic int rb_w32_open_osfhandle(long osfhandle, int flags);\n#else\n#define rb_w32_open_osfhandle(osfhandle, flags) _open_osfhandle(osfhandle, flags)\n#endif\n\n/* errno mapping */\nstatic struct {\n    DWORD winerr;\n    int err;\n} errmap[] = {\n    {\tERROR_INVALID_FUNCTION,\t\tEINVAL\t\t},\n    {\tERROR_FILE_NOT_FOUND,\t\tENOENT\t\t},\n    {\tERROR_PATH_NOT_FOUND,\t\tENOENT\t\t},\n    {\tERROR_TOO_MANY_OPEN_FILES,\tEMFILE\t\t},\n    {\tERROR_ACCESS_DENIED,\t\tEACCES\t\t},\n    {\tERROR_INVALID_HANDLE,\t\tEBADF\t\t},\n    {\tERROR_ARENA_TRASHED,\t\tENOMEM\t\t},\n    {\tERROR_NOT_ENOUGH_MEMORY,\tENOMEM\t\t},\n    {\tERROR_INVALID_BLOCK,\t\tENOMEM\t\t},\n    {\tERROR_BAD_ENVIRONMENT,\t\tE2BIG\t\t},\n    {\tERROR_BAD_FORMAT,\t\tENOEXEC\t\t},\n    {\tERROR_INVALID_ACCESS,\t\tEINVAL\t\t},\n    {\tERROR_INVALID_DATA,\t\tEINVAL\t\t},\n    {\tERROR_INVALID_DRIVE,\t\tENOENT\t\t},\n    {\tERROR_CURRENT_DIRECTORY,\tEACCES\t\t},\n    {\tERROR_NOT_SAME_DEVICE,\t\tEXDEV\t\t},\n    {\tERROR_NO_MORE_FILES,\t\tENOENT\t\t},\n    {\tERROR_WRITE_PROTECT,\t\tEROFS\t\t},\n    {\tERROR_BAD_UNIT,\t\t\tENODEV\t\t},\n    {\tERROR_NOT_READY,\t\tENXIO\t\t},\n    {\tERROR_BAD_COMMAND,\t\tEACCES\t\t},\n    {\tERROR_CRC,\t\t\tEACCES\t\t},\n    {\tERROR_BAD_LENGTH,\t\tEACCES\t\t},\n    {\tERROR_SEEK,\t\t\tEIO\t\t},\n    {\tERROR_NOT_DOS_DISK,\t\tEACCES\t\t},\n    {\tERROR_SECTOR_NOT_FOUND,\t\tEACCES\t\t},\n    {\tERROR_OUT_OF_PAPER,\t\tEACCES\t\t},\n    {\tERROR_WRITE_FAULT,\t\tEIO\t\t},\n    {\tERROR_READ_FAULT,\t\tEIO\t\t},\n    {\tERROR_GEN_FAILURE,\t\tEACCES\t\t},\n    {\tERROR_LOCK_VIOLATION,\t\tEACCES\t\t},\n    {\tERROR_SHARING_VIOLATION,\tEACCES\t\t},\n    {\tERROR_WRONG_DISK,\t\tEACCES\t\t},\n    {\tERROR_SHARING_BUFFER_EXCEEDED,\tEACCES\t\t},\n    {\tERROR_BAD_NETPATH,\t\tENOENT\t\t},\n    {\tERROR_NETWORK_ACCESS_DENIED,\tEACCES\t\t},\n    {\tERROR_BAD_NET_NAME,\t\tENOENT\t\t},\n    {\tERROR_FILE_EXISTS,\t\tEEXIST\t\t},\n    {\tERROR_CANNOT_MAKE,\t\tEACCES\t\t},\n    {\tERROR_FAIL_I24,\t\t\tEACCES\t\t},\n    {\tERROR_INVALID_PARAMETER,\tEINVAL\t\t},\n    {\tERROR_NO_PROC_SLOTS,\t\tEAGAIN\t\t},\n    {\tERROR_DRIVE_LOCKED,\t\tEACCES\t\t},\n    {\tERROR_BROKEN_PIPE,\t\tEPIPE\t\t},\n    {\tERROR_DISK_FULL,\t\tENOSPC\t\t},\n    {\tERROR_INVALID_TARGET_HANDLE,\tEBADF\t\t},\n    {\tERROR_INVALID_HANDLE,\t\tEINVAL\t\t},\n    {\tERROR_WAIT_NO_CHILDREN,\t\tECHILD\t\t},\n    {\tERROR_CHILD_NOT_COMPLETE,\tECHILD\t\t},\n    {\tERROR_DIRECT_ACCESS_HANDLE,\tEBADF\t\t},\n    {\tERROR_NEGATIVE_SEEK,\t\tEINVAL\t\t},\n    {\tERROR_SEEK_ON_DEVICE,\t\tEACCES\t\t},\n    {\tERROR_DIR_NOT_EMPTY,\t\tENOTEMPTY\t},\n    {\tERROR_DIRECTORY,\t\tENOTDIR\t\t},\n    {\tERROR_NOT_LOCKED,\t\tEACCES\t\t},\n    {\tERROR_BAD_PATHNAME,\t\tENOENT\t\t},\n    {\tERROR_MAX_THRDS_REACHED,\tEAGAIN\t\t},\n    {\tERROR_LOCK_FAILED,\t\tEACCES\t\t},\n    {\tERROR_ALREADY_EXISTS,\t\tEEXIST\t\t},\n    {\tERROR_INVALID_STARTING_CODESEG,\tENOEXEC\t\t},\n    {\tERROR_INVALID_STACKSEG,\t\tENOEXEC\t\t},\n    {\tERROR_INVALID_MODULETYPE,\tENOEXEC\t\t},\n    {\tERROR_INVALID_EXE_SIGNATURE,\tENOEXEC\t\t},\n    {\tERROR_EXE_MARKED_INVALID,\tENOEXEC\t\t},\n    {\tERROR_BAD_EXE_FORMAT,\t\tENOEXEC\t\t},\n    {\tERROR_ITERATED_DATA_EXCEEDS_64k,ENOEXEC\t\t},\n    {\tERROR_INVALID_MINALLOCSIZE,\tENOEXEC\t\t},\n    {\tERROR_DYNLINK_FROM_INVALID_RING,ENOEXEC\t\t},\n    {\tERROR_IOPL_NOT_ENABLED,\t\tENOEXEC\t\t},\n    {\tERROR_INVALID_SEGDPL,\t\tENOEXEC\t\t},\n    {\tERROR_AUTODATASEG_EXCEEDS_64k,\tENOEXEC\t\t},\n    {\tERROR_RING2SEG_MUST_BE_MOVABLE,\tENOEXEC\t\t},\n    {\tERROR_RELOC_CHAIN_XEEDS_SEGLIM,\tENOEXEC\t\t},\n    {\tERROR_INFLOOP_IN_RELOC_CHAIN,\tENOEXEC\t\t},\n    {\tERROR_FILENAME_EXCED_RANGE,\tENOENT\t\t},\n    {\tERROR_NESTING_NOT_ALLOWED,\tEAGAIN\t\t},\n    {\tERROR_NOT_ENOUGH_QUOTA,\t\tENOMEM\t\t},\n    {\tWSAENAMETOOLONG,\t\tENAMETOOLONG\t},\n    {\tWSAENOTEMPTY,\t\t\tENOTEMPTY\t},\n    {\tWSAEINTR,\t\t\tEINTR\t\t},\n    {\tWSAEBADF,\t\t\tEBADF\t\t},\n    {\tWSAEACCES,\t\t\tEACCES\t\t},\n    {\tWSAEFAULT,\t\t\tEFAULT\t\t},\n    {\tWSAEINVAL,\t\t\tEINVAL\t\t},\n    {\tWSAEMFILE,\t\t\tEMFILE\t\t},\n};\n\nint\nrb_w32_map_errno(DWORD winerr)\n{\n    int i;\n\n    if (winerr == 0) {\n\treturn 0;\n    }\n\n    for (i = 0; i < sizeof(errmap) / sizeof(*errmap); i++) {\n\tif (errmap[i].winerr == winerr) {\n\t    return errmap[i].err;\n\t}\n    }\n\n    if (winerr >= WSABASEERR) {\n\treturn winerr;\n    }\n    return EINVAL;\n}\n\n#define map_errno rb_w32_map_errno\n\nstatic const char *NTLoginName;\n\n#ifdef WIN95\nstatic DWORD Win32System = (DWORD)-1;\n\nDWORD\nrb_w32_osid(void)\n{\n    static OSVERSIONINFO osver;\n\n    if (osver.dwPlatformId != Win32System) {\n\tmemset(&osver, 0, sizeof(OSVERSIONINFO));\n\tosver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\n\tGetVersionEx(&osver);\n\tWin32System = osver.dwPlatformId;\n    }\n    return (Win32System);\n}\n#endif\n\n#define IsWinNT() rb_w32_iswinnt()\n#define IsWin95() rb_w32_iswin95()\n\n/* main thread constants */\nstatic struct {\n    HANDLE handle;\n    DWORD id;\n} main_thread;\n\n/* interrupt stuff */\nstatic HANDLE interrupted_event;\n\nHANDLE\nGetCurrentThreadHandle(void)\n{\n    static HANDLE current_process_handle = NULL;\n    HANDLE h;\n\n    if (!current_process_handle)\n\tcurrent_process_handle = GetCurrentProcess();\n    if (!DuplicateHandle(current_process_handle, GetCurrentThread(),\n\t\t\t current_process_handle, &h,\n\t\t\t 0, FALSE, DUPLICATE_SAME_ACCESS))\n\treturn NULL;\n    return h;\n}\n\n/* simulate flock by locking a range on the file */\n\n\n#define LK_ERR(f,i) \\\n    do {\t\t\t\t\t\t\t\t\\\n\tif (f)\t\t\t\t\t\t\t\t\\\n\t    i = 0;\t\t\t\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t    DWORD err = GetLastError();\t\t\t\t\t\\\n\t    if (err == ERROR_LOCK_VIOLATION)\t\t\t\t\\\n\t\terrno = EWOULDBLOCK;\t\t\t\t\t\\\n\t    else if (err == ERROR_NOT_LOCKED)\t\t\t\t\\\n\t\ti = 0;\t\t\t\t\t\t\t\\\n\t    else\t\t\t\t\t\t\t\\\n\t\terrno = map_errno(err);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n    } while (0)\n#define LK_LEN      ULONG_MAX\n\nstatic VALUE\nflock_winnt(VALUE self, int argc, VALUE* argv)\n{\n    OVERLAPPED o;\n    int i = -1;\n    const HANDLE fh = (HANDLE)self;\n    const int oper = argc;\n\n    memset(&o, 0, sizeof(o));\n\n    switch(oper) {\n      case LOCK_SH:\t\t/* shared lock */\n\tLK_ERR(LockFileEx(fh, 0, 0, LK_LEN, LK_LEN, &o), i);\n\tbreak;\n      case LOCK_EX:\t\t/* exclusive lock */\n\tLK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, LK_LEN, &o), i);\n\tbreak;\n      case LOCK_SH|LOCK_NB:\t/* non-blocking shared lock */\n\tLK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, LK_LEN, &o), i);\n\tbreak;\n      case LOCK_EX|LOCK_NB:\t/* non-blocking exclusive lock */\n\tLK_ERR(LockFileEx(fh,\n\t\t\t  LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,\n\t\t\t  0, LK_LEN, LK_LEN, &o), i);\n\tbreak;\n      case LOCK_UN:\t\t/* unlock lock */\n      case LOCK_UN|LOCK_NB:\t/* unlock is always non-blocking, I hope */\n\tLK_ERR(UnlockFileEx(fh, 0, LK_LEN, LK_LEN, &o), i);\n\tbreak;\n      default:            /* unknown */\n\terrno = EINVAL;\n\tbreak;\n    }\n    return i;\n}\n\n#ifdef WIN95\nstatic VALUE\nflock_win95(VALUE self, int argc, VALUE* argv)\n{\n    int i = -1;\n    const HANDLE fh = (HANDLE)self;\n    const int oper = argc;\n\n    switch(oper) {\n      case LOCK_EX:\n\tdo {\n\t    LK_ERR(LockFile(fh, 0, 0, LK_LEN, LK_LEN), i);\n\t} while (i && errno == EWOULDBLOCK);\n\tbreak;\n      case LOCK_EX|LOCK_NB:\n\tLK_ERR(LockFile(fh, 0, 0, LK_LEN, LK_LEN), i);\n\tbreak;\n      case LOCK_UN:\n      case LOCK_UN|LOCK_NB:\n\tLK_ERR(UnlockFile(fh, 0, 0, LK_LEN, LK_LEN), i);\n\tbreak;\n      default:\n\terrno = EINVAL;\n\tbreak;\n    }\n    return i;\n}\n#endif\n\n#undef LK_ERR\n\nint\nflock(int fd, int oper)\n{\n#ifdef WIN95\n    static asynchronous_func_t locker = NULL;\n\n    if (!locker) {\n\tif (IsWinNT())\n\t    locker = flock_winnt;\n\telse\n\t    locker = flock_win95;\n    }\n#else\n    const asynchronous_func_t locker = flock_winnt;\n#endif\n\n    return rb_w32_asynchronize(locker,\n\t\t\t      (VALUE)_get_osfhandle(fd), oper, NULL,\n\t\t\t      (DWORD)-1);\n}\n\nstatic void init_stdhandle(void);\n\n#if _MSC_VER >= 1400\nstatic void\ninvalid_parameter(const wchar_t *expr, const wchar_t *func, const wchar_t *file, unsigned int line, uintptr_t dummy)\n{\n    // nothing to do\n}\n\nstatic int __cdecl\nrtc_error_handler(int e, const char *src, int line, const char *exe, const char *fmt, ...)\n{\n    return 0;\n}\n#endif\n\nstatic CRITICAL_SECTION select_mutex;\nstatic BOOL fWinsock;\nstatic char *envarea;\nstatic void\nexit_handler(void)\n{\n    if (fWinsock) {\n\tWSACleanup();\n\tfWinsock = FALSE;\n    }\n    if (envarea) {\n\tFreeEnvironmentStrings(envarea);\n\tenvarea = NULL;\n    }\n    DeleteCriticalSection(&select_mutex);\n}\n\nstatic void\ninit_env(void)\n{\n    char env[_MAX_PATH];\n    DWORD len;\n    BOOL f;\n    LPITEMIDLIST pidl;\n\n    if (!GetEnvironmentVariable(\"HOME\", env, sizeof(env))) {\n\tf = FALSE;\n\tif (GetEnvironmentVariable(\"HOMEDRIVE\", env, sizeof(env)))\n\t    len = strlen(env);\n\telse\n\t    len = 0;\n\tif (GetEnvironmentVariable(\"HOMEPATH\", env + len, sizeof(env) - len) || len) {\n\t    f = TRUE;\n\t}\n\telse if (GetEnvironmentVariable(\"USERPROFILE\", env, sizeof(env))) {\n\t    f = TRUE;\n\t}\n\telse if (SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl) == 0) {\n\t    LPMALLOC alloc;\n\t    f = SHGetPathFromIDList(pidl, env);\n\t    SHGetMalloc(&alloc);\n\t    alloc->lpVtbl->Free(alloc, pidl);\n\t    alloc->lpVtbl->Release(alloc);\n\t}\n\tif (f) {\n\t    char *p = env;\n\t    while (*p) {\n\t\tif (*p == '\\\\') *p = '/';\n\t\tp = CharNext(p);\n\t    }\n\t    if (p - env == 2 && env[1] == ':') {\n\t\t*p++ = '/';\n\t\t*p = 0;\n\t    }\n\t    SetEnvironmentVariable(\"HOME\", env);\n\t}\n    }\n\n    if (!GetEnvironmentVariable(\"USER\", env, sizeof env)) {\n\tif (GetEnvironmentVariable(\"USERNAME\", env, sizeof env) ||\n\t    GetUserName(env, (len = sizeof env, &len))) {\n\t    SetEnvironmentVariable(\"USER\", env);\n\t}\n\telse {\n\t    NTLoginName = \"<Unknown>\";\n\t    return;\n\t}\n    }\n    NTLoginName = strdup(env);\n}\n\n//\n// Initialization stuff\n//\nvoid\nNtInitialize(int *argc, char ***argv)\n{\n#if _MSC_VER >= 1400\n    static void set_pioinfo_extra(void);\n\n    _CrtSetReportMode(_CRT_ASSERT, 0);\n    _set_invalid_parameter_handler(invalid_parameter);\n    _RTC_SetErrorFunc(rtc_error_handler);\n    set_pioinfo_extra();\n#endif\n\n    //\n    // subvert cmd.exe's feeble attempt at command line parsing\n    //\n    *argc = rb_w32_cmdvector(GetCommandLine(), argv);\n\n    //\n    // Now set up the correct time stuff\n    //\n\n    tzset();\n\n    init_env();\n\n    init_stdhandle();\n\n    InitializeCriticalSection(&select_mutex);\n\n    atexit(exit_handler);\n\n    // Initialize Winsock\n    StartSockets();\n\n#ifdef _WIN32_WCE\n    // free commandline buffer\n    wce_FreeCommandLine();\n#endif\n}\n\nchar *\ngetlogin()\n{\n    return (char *)NTLoginName;\n}\n\n#define MAXCHILDNUM 256\t/* max num of child processes */\n\nstatic struct ChildRecord {\n    HANDLE hProcess;\t/* process handle */\n    rb_pid_t pid;\t/* process id */\n} ChildRecord[MAXCHILDNUM];\n\n#define FOREACH_CHILD(v) do { \\\n    struct ChildRecord* v; \\\n    for (v = ChildRecord; v < ChildRecord + sizeof(ChildRecord) / sizeof(ChildRecord[0]); ++v)\n#define END_FOREACH_CHILD } while (0)\n\nstatic struct ChildRecord *\nFindChildSlot(rb_pid_t pid)\n{\n\n    FOREACH_CHILD(child) {\n\tif (child->pid == pid) {\n\t    return child;\n\t}\n    } END_FOREACH_CHILD;\n    return NULL;\n}\n\nstatic struct ChildRecord *\nFindChildSlotByHandle(HANDLE h)\n{\n\n    FOREACH_CHILD(child) {\n\tif (child->hProcess == h) {\n\t    return child;\n\t}\n    } END_FOREACH_CHILD;\n    return NULL;\n}\n\nstatic void\nCloseChildHandle(struct ChildRecord *child)\n{\n    HANDLE h = child->hProcess;\n    child->hProcess = NULL;\n    child->pid = 0;\n    CloseHandle(h);\n}\n\nstatic struct ChildRecord *\nFindFreeChildSlot(void)\n{\n    FOREACH_CHILD(child) {\n\tif (!child->pid) {\n\t    child->pid = -1;\t/* lock the slot */\n\t    child->hProcess = NULL;\n\t    return child;\n\t}\n    } END_FOREACH_CHILD;\n    return NULL;\n}\n\n\n/*\n  ruby -lne 'BEGIN{$cmds = Hash.new(0); $mask = 1}'\n   -e '$cmds[$_.downcase] |= $mask' -e '$mask <<= 1 if ARGF.eof'\n   -e 'END{$cmds.sort.each{|n,f|puts \"    \\\"\\\\#{f.to_s(8)}\\\" #{n.dump} + 1,\"}}'\n   98cmd ntcmd\n */\nstatic const char *const szInternalCmds[] = {\n    \"\\2\" \"assoc\" + 1,\n    \"\\3\" \"break\" + 1,\n    \"\\3\" \"call\" + 1,\n    \"\\3\" \"cd\" + 1,\n    \"\\1\" \"chcp\" + 1,\n    \"\\3\" \"chdir\" + 1,\n    \"\\3\" \"cls\" + 1,\n    \"\\2\" \"color\" + 1,\n    \"\\3\" \"copy\" + 1,\n    \"\\1\" \"ctty\" + 1,\n    \"\\3\" \"date\" + 1,\n    \"\\3\" \"del\" + 1,\n    \"\\3\" \"dir\" + 1,\n    \"\\3\" \"echo\" + 1,\n    \"\\2\" \"endlocal\" + 1,\n    \"\\3\" \"erase\" + 1,\n    \"\\3\" \"exit\" + 1,\n    \"\\3\" \"for\" + 1,\n    \"\\2\" \"ftype\" + 1,\n    \"\\3\" \"goto\" + 1,\n    \"\\3\" \"if\" + 1,\n    \"\\1\" \"lfnfor\" + 1,\n    \"\\1\" \"lh\" + 1,\n    \"\\1\" \"lock\" + 1,\n    \"\\3\" \"md\" + 1,\n    \"\\3\" \"mkdir\" + 1,\n    \"\\2\" \"move\" + 1,\n    \"\\3\" \"path\" + 1,\n    \"\\3\" \"pause\" + 1,\n    \"\\2\" \"popd\" + 1,\n    \"\\3\" \"prompt\" + 1,\n    \"\\2\" \"pushd\" + 1,\n    \"\\3\" \"rd\" + 1,\n    \"\\3\" \"rem\" + 1,\n    \"\\3\" \"ren\" + 1,\n    \"\\3\" \"rename\" + 1,\n    \"\\3\" \"rmdir\" + 1,\n    \"\\3\" \"set\" + 1,\n    \"\\2\" \"setlocal\" + 1,\n    \"\\3\" \"shift\" + 1,\n    \"\\2\" \"start\" + 1,\n    \"\\3\" \"time\" + 1,\n    \"\\2\" \"title\" + 1,\n    \"\\1\" \"truename\" + 1,\n    \"\\3\" \"type\" + 1,\n    \"\\1\" \"unlock\" + 1,\n    \"\\3\" \"ver\" + 1,\n    \"\\3\" \"verify\" + 1,\n    \"\\3\" \"vol\" + 1,\n};\n\nstatic int\ninternal_match(const void *key, const void *elem)\n{\n    return strcmp(key, *(const char *const *)elem);\n}\n\nstatic int\nis_command_com(const char *interp)\n{\n    int i = strlen(interp) - 11;\n\n    if ((i == 0 || i > 0 && isdirsep(interp[i-1])) &&\n\tstrcasecmp(interp+i, \"command.com\") == 0) {\n\treturn 1;\n    }\n    return 0;\n}\n\nstatic int\nis_internal_cmd(const char *cmd, int nt)\n{\n    char cmdname[9], *b = cmdname, c, **nm;\n\n    do {\n\tif (!(c = *cmd++)) return 0;\n    } while (isspace(c));\n    while (isalpha(c)) {\n\t*b++ = tolower(c);\n\tif (b == cmdname + sizeof(cmdname)) return 0;\n\tc = *cmd++;\n    }\n    if (c == '.') c = *cmd;\n    switch (c) {\n      case '<': case '>': case '|':\n\treturn 1;\n      case '\\0': case ' ': case '\\t': case '\\n':\n\tbreak;\n      default:\n\treturn 0;\n    }\n    *b = 0;\n    nm = bsearch(cmdname, szInternalCmds,\n\t\t sizeof(szInternalCmds) / sizeof(*szInternalCmds),\n\t\t sizeof(*szInternalCmds),\n\t\t internal_match);\n    if (!nm || !(nm[0][-1] & (nt ? 2 : 1)))\n\treturn 0;\n    return 1;\n}\n\n\nSOCKET\nrb_w32_get_osfhandle(int fh)\n{\n    return _get_osfhandle(fh);\n}\n\nrb_pid_t\npipe_exec(const char *cmd, int mode, FILE **fpr, FILE **fpw)\n{\n    struct ChildRecord* child;\n    HANDLE hReadIn, hReadOut;\n    HANDLE hWriteIn, hWriteOut;\n    HANDLE hDupInFile, hDupOutFile;\n    HANDLE hCurProc;\n    SECURITY_ATTRIBUTES sa;\n    BOOL fRet;\n    BOOL reading, writing;\n    int fd;\n    int pipemode;\n    char modes[3];\n    int ret;\n\n    /* Figure out what we're doing... */\n    writing = (mode & (O_WRONLY | O_RDWR)) ? TRUE : FALSE;\n    reading = ((mode & O_RDWR) || !writing) ? TRUE : FALSE;\n    if (mode & O_BINARY) {\n\tpipemode = O_BINARY;\n\tmodes[1] = 'b';\n\tmodes[2] = '\\0';\n    }\n    else {\n\tpipemode = O_TEXT;\n\tmodes[1] = '\\0';\n    }\n\n    sa.nLength              = sizeof (SECURITY_ATTRIBUTES);\n    sa.lpSecurityDescriptor = NULL;\n    sa.bInheritHandle       = TRUE;\n    ret = -1;\n    hWriteIn = hReadOut = NULL;\n\n    RUBY_CRITICAL(do {\n\t/* create pipe */\n\thCurProc = GetCurrentProcess();\n\tif (reading) {\n\t    fRet = CreatePipe(&hReadIn, &hReadOut, &sa, 2048L);\n\t    if (!fRet) {\n\t\terrno = map_errno(GetLastError());\n\t\tbreak;\n\t    }\n\t    if (!DuplicateHandle(hCurProc, hReadIn, hCurProc, &hDupInFile, 0,\n\t\t\t\t FALSE, DUPLICATE_SAME_ACCESS)) {\n\t\terrno = map_errno(GetLastError());\n\t\tCloseHandle(hReadIn);\n\t\tCloseHandle(hReadOut);\n\t\tCloseHandle(hCurProc);\n\t\tbreak;\n\t    }\n\t    CloseHandle(hReadIn);\n\t}\n\tif (writing) {\n\t    fRet = CreatePipe(&hWriteIn, &hWriteOut, &sa, 2048L);\n\t    if (!fRet) {\n\t\terrno = map_errno(GetLastError());\n\t      write_pipe_failed:\n\t\tif (reading) {\n\t\t    CloseHandle(hDupInFile);\n\t\t    CloseHandle(hReadOut);\n\t\t}\n\t\tbreak;\n\t    }\n\t    if (!DuplicateHandle(hCurProc, hWriteOut, hCurProc, &hDupOutFile, 0,\n\t\t\t\t FALSE, DUPLICATE_SAME_ACCESS)) {\n\t\terrno = map_errno(GetLastError());\n\t\tCloseHandle(hWriteIn);\n\t\tCloseHandle(hWriteOut);\n\t\tCloseHandle(hCurProc);\n\t\tgoto write_pipe_failed;\n\t    }\n\t    CloseHandle(hWriteOut);\n\t}\n\tCloseHandle(hCurProc);\n\n\t/* create child process */\n\tchild = CreateChild(cmd, NULL, &sa, hWriteIn, hReadOut, NULL);\n\tif (!child) {\n\t    if (reading) {\n\t\tCloseHandle(hReadOut);\n\t\tCloseHandle(hDupInFile);\n\t    }\n\t    if (writing) {\n\t\tCloseHandle(hWriteIn);\n\t\tCloseHandle(hDupOutFile);\n\t    }\n\t    break;\n\t}\n\n\t/* associate handle to fp */\n\tif (reading) {\n\t    fd = rb_w32_open_osfhandle((long)hDupInFile,\n\t\t\t\t       (_O_RDONLY | pipemode));\n\t    CloseHandle(hReadOut);\n\t    if (fd == -1) {\n\t\tCloseHandle(hDupInFile);\n\t      read_open_failed:\n\t\tif (writing) {\n\t\t    CloseHandle(hWriteIn);\n\t\t    CloseHandle(hDupOutFile);\n\t\t}\n\t\tCloseChildHandle(child);\n\t\tbreak;\n\t    }\n\t    modes[0] = 'r';\n\t    if ((*fpr = (FILE *)fdopen(fd, modes)) == NULL) {\n\t\t_close(fd);\n\t\tgoto read_open_failed;\n\t    }\n\t}\n\tif (writing) {\n\t    fd = rb_w32_open_osfhandle((long)hDupOutFile,\n\t\t\t\t       (_O_WRONLY | pipemode));\n\t    CloseHandle(hWriteIn);\n\t    if (fd == -1) {\n\t\tCloseHandle(hDupOutFile);\n\t      write_open_failed:\n\t\tif (reading) {\n\t\t    fclose(*fpr);\n\t\t}\n\t\tCloseChildHandle(child);\n\t\tbreak;\n\t    }\n\t    modes[0] = 'w';\n\t    if ((*fpw = (FILE *)fdopen(fd, modes)) == NULL) {\n\t\t_close(fd);\n\t\tgoto write_open_failed;\n\t    }\n\t}\n\tret = child->pid;\n    } while (0));\n\n    return ret;\n}\n\nextern VALUE rb_last_status;\n\nint\ndo_spawn(int mode, const char *cmd)\n{\n    struct ChildRecord *child;\n    DWORD exitcode;\n\n    switch (mode) {\n      case P_WAIT:\n      case P_NOWAIT:\n      case P_OVERLAY:\n\tbreak;\n      default:\n\terrno = EINVAL;\n\treturn -1;\n    }\n\n    child = CreateChild(cmd, NULL, NULL, NULL, NULL, NULL);\n    if (!child) {\n\treturn -1;\n    }\n\n    switch (mode) {\n      case P_WAIT:\n\trb_syswait(child->pid);\n\treturn NUM2INT(rb_last_status);\n      case P_NOWAIT:\n\treturn child->pid;\n      case P_OVERLAY:\n\tWaitForSingleObject(child->hProcess, INFINITE);\n\tGetExitCodeProcess(child->hProcess, &exitcode);\n\tCloseChildHandle(child);\n\t_exit(exitcode);\n      default:\n\treturn -1;\t/* not reached */\n    }\n}\n\nint\ndo_aspawn(int mode, const char *prog, char **argv)\n{\n    char *cmd, *p, *q, *s, **t;\n    int len, n, bs, quote;\n    struct ChildRecord *child;\n    DWORD exitcode;\n\n    switch (mode) {\n      case P_WAIT:\n      case P_NOWAIT:\n      case P_OVERLAY:\n\tbreak;\n      default:\n\terrno = EINVAL;\n\treturn -1;\n    }\n\n    for (t = argv, len = 0; *t; t++) {\n\tfor (p = *t, n = quote = bs = 0; *p; ++p) {\n\t    switch (*p) {\n\t      case '\\\\':\n\t\t++bs;\n\t\tbreak;\n\t      case '\"':\n\t\tn += bs + 1; bs = 0;\n\t\tquote = 1;\n\t\tbreak;\n\t      case ' ': case '\\t':\n\t\tquote = 1;\n\t      default:\n\t\tbs = 0;\n\t\tp = CharNext(p) - 1;\n\t\tbreak;\n\t    }\n\t}\n\tlen += p - *t + n + 1;\n\tif (quote) len += 2;\n    }\n    cmd = ALLOCA_N(char, len);\n    for (t = argv, q = cmd; p = *t; t++) {\n\tquote = 0;\n\ts = p;\n\tif (!*p || strpbrk(p, \" \\t\\\"\")) {\n\t    quote = 1;\n\t    *q++ = '\"';\n\t}\n\tfor (bs = 0; *p; ++p) {\n\t    switch (*p) {\n\t      case '\\\\':\n\t\t++bs;\n\t\tbreak;\n\t      case '\"':\n\t\tmemcpy(q, s, n = p - s); q += n; s = p;\n\t\tmemset(q, '\\\\', ++bs); q += bs; bs = 0;\n\t\tbreak;\n\t      default:\n\t\tbs = 0;\n\t\tp = CharNext(p) - 1;\n\t\tbreak;\n\t    }\n\t}\n\tmemcpy(q, s, n = p - s);\n\tq += n;\n\tif (quote) *q++ = '\"';\n\t*q++ = ' ';\n    }\n    if (q > cmd) --q;\n    *q = '\\0';\n\n    child = CreateChild(cmd, prog, NULL, NULL, NULL, NULL);\n    if (!child) {\n\treturn -1;\n    }\n\n    switch (mode) {\n      case P_WAIT:\n\trb_syswait(child->pid);\n\treturn NUM2INT(rb_last_status);\n      case P_NOWAIT:\n\treturn child->pid;\n      case P_OVERLAY:\n\tWaitForSingleObject(child->hProcess, INFINITE);\n\tGetExitCodeProcess(child->hProcess, &exitcode);\n\tCloseChildHandle(child);\n\t_exit(exitcode);\n      default:\n\treturn -1;\t/* not reached */\n    }\n}\n\nstatic struct ChildRecord *\nCreateChild(const char *cmd, const char *prog, SECURITY_ATTRIBUTES *psa,\n\t    HANDLE hInput, HANDLE hOutput, HANDLE hError)\n{\n    BOOL fRet;\n    DWORD  dwCreationFlags;\n    STARTUPINFO aStartupInfo;\n    PROCESS_INFORMATION aProcessInformation;\n    SECURITY_ATTRIBUTES sa;\n    const char *shell;\n    struct ChildRecord *child;\n    char *p = NULL;\n\n    if (!cmd && !prog) {\n\terrno = EFAULT;\n\treturn NULL;\n    }\n\n    child = FindFreeChildSlot();\n    if (!child) {\n\terrno = EAGAIN;\n\treturn NULL;\n    }\n\n    if (!psa) {\n\tsa.nLength              = sizeof (SECURITY_ATTRIBUTES);\n\tsa.lpSecurityDescriptor = NULL;\n\tsa.bInheritHandle       = TRUE;\n\tpsa = &sa;\n    }\n\n    memset(&aStartupInfo, 0, sizeof (STARTUPINFO));\n    memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION));\n    aStartupInfo.cb = sizeof (STARTUPINFO);\n    if (hInput || hOutput || hError) {\n\taStartupInfo.dwFlags = STARTF_USESTDHANDLES;\n\tif (hInput) {\n\t    aStartupInfo.hStdInput  = hInput;\n\t}\n\telse {\n\t    aStartupInfo.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);\n\t}\n\tif (hOutput) {\n\t    aStartupInfo.hStdOutput = hOutput;\n\t}\n\telse {\n\t    aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);\n\t}\n\tif (hError) {\n\t    aStartupInfo.hStdError = hError;\n\t}\n\telse {\n\t    aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);\n\t}\n    }\n\n    dwCreationFlags = (NORMAL_PRIORITY_CLASS);\n\n    if (prog) {\n\tif (!(p = dln_find_exe(prog, NULL))) {\n\t    shell = prog;\n\t}\n    }\n    else {\n\tint redir = -1;\n\tint len = 0;\n\tint nt;\n\twhile (ISSPACE(*cmd)) cmd++;\n\tfor (prog = cmd; *prog; prog = CharNext(prog)) {\n\t    if (ISSPACE(*prog)) {\n\t\tlen = prog - cmd;\n\t\tdo ++prog; while (ISSPACE(*prog));\n\t\tif (!*prog--) break;\n\t    }\n\t    else {\n\t\tlen = 0;\n\t    }\n\t}\n\tif (!len) len = strlen(cmd);\n\tif ((shell = getenv(\"RUBYSHELL\")) && (redir = has_redirection(cmd))) {\n\t    char *tmp = ALLOCA_N(char, strlen(shell) + len + sizeof(\" -c \") + 2);\n\t    sprintf(tmp, \"%s -c \\\"%.*s\\\"\", shell, len, cmd);\n\t    cmd = tmp;\n\t}\n\telse if ((shell = getenv(\"COMSPEC\")) &&\n\t\t (nt = !is_command_com(shell),\n\t\t  (redir < 0 ? has_redirection(cmd) : redir) ||\n\t\t  is_internal_cmd(cmd, nt))) {\n\t    char *tmp = ALLOCA_N(char, strlen(shell) + len + sizeof(\" /c \")\n\t\t\t\t + (nt ? 2 : 0));\n\t    sprintf(tmp, nt ? \"%s /c \\\"%.*s\\\"\" : \"%s /c %.*s\", shell, len, cmd);\n\t    cmd = tmp;\n\t}\n\telse {\n\t    shell = NULL;\n\t    prog = cmd;\n\t    for (;;) {\n\t\tif (!*prog) {\n\t\t    p = dln_find_exe(cmd, NULL);\n\t\t    break;\n\t\t}\n\t\tif (strchr(\".:*?\\\"/\\\\\", *prog)) {\n\t\t    if (cmd[len]) {\n\t\t\tchar *tmp = ALLOCA_N(char, len + 1);\n\t\t\tmemcpy(tmp, cmd, len);\n\t\t\ttmp[len] = 0;\n\t\t\tcmd = tmp;\n\t\t    }\n\t\t    break;\n\t\t}\n\t\tif (ISSPACE(*prog) || strchr(\"<>|\", *prog)) {\n\t\t    len = prog - cmd;\n\t\t    p = ALLOCA_N(char, len + 1);\n\t\t    memcpy(p, cmd, len);\n\t\t    p[len] = 0;\n\t\t    p = dln_find_exe(p, NULL);\n\t\t    break;\n\t\t}\n\t\tprog++;\n\t    }\n\t}\n    }\n    if (p) {\n\tchar *tmp = ALLOCA_N(char, strlen(p) + 1);\n\tstrcpy(tmp, p);\n\tshell = tmp;\n\twhile (*tmp) {\n\t    if ((unsigned char)*tmp == '/')\n\t\t*tmp = '\\\\';\n\t    tmp = CharNext(tmp);\n\t}\n    }\n\n    RUBY_CRITICAL({\n\tfRet = CreateProcess(shell, (char *)cmd, psa, psa,\n\t\t\t     psa->bInheritHandle, dwCreationFlags, NULL, NULL,\n\t\t\t     &aStartupInfo, &aProcessInformation);\n\terrno = map_errno(GetLastError());\n    });\n\n    if (!fRet) {\n\tchild->pid = 0;\t\t/* release the slot */\n\treturn NULL;\n    }\n\n    CloseHandle(aProcessInformation.hThread);\n\n    child->hProcess = aProcessInformation.hProcess;\n    child->pid = (rb_pid_t)aProcessInformation.dwProcessId;\n\n    if (!IsWinNT()) {\n\t/* On Win9x, make pid positive similarly to cygwin and perl */\n\tchild->pid = -child->pid;\n    }\n\n    return child;\n}\n\ntypedef struct _NtCmdLineElement {\n    struct _NtCmdLineElement *next;\n    char *str;\n    int len;\n    int flags;\n} NtCmdLineElement;\n\n//\n// Possible values for flags\n//\n\n#define NTGLOB   0x1\t// element contains a wildcard\n#define NTMALLOC 0x2\t// string in element was malloc'ed\n#define NTSTRING 0x4\t// element contains a quoted string\n\nstatic int\ninsert(const char *path, VALUE vinfo)\n{\n    NtCmdLineElement *tmpcurr;\n    NtCmdLineElement ***tail = (NtCmdLineElement ***)vinfo;\n\n    tmpcurr = (NtCmdLineElement *)malloc(sizeof(NtCmdLineElement));\n    if (!tmpcurr) return -1;\n    MEMZERO(tmpcurr, NtCmdLineElement, 1);\n    tmpcurr->len = strlen(path);\n    tmpcurr->str = strdup(path);\n    if (!tmpcurr->str) return -1;\n    tmpcurr->flags |= NTMALLOC;\n    **tail = tmpcurr;\n    *tail = &tmpcurr->next;\n\n    return 0;\n}\n\n#ifdef HAVE_SYS_PARAM_H\n# include <sys/param.h>\n#else\n# define MAXPATHLEN 512\n#endif\n\n\nstatic NtCmdLineElement **\ncmdglob(NtCmdLineElement *patt, NtCmdLineElement **tail)\n{\n    char buffer[MAXPATHLEN], *buf = buffer;\n    char *p;\n    NtCmdLineElement **last = tail;\n    int status;\n\n    if (patt->len >= MAXPATHLEN)\n\tif (!(buf = malloc(patt->len + 1))) return 0;\n\n    strncpy (buf, patt->str, patt->len);\n    buf[patt->len] = '\\0';\n    for (p = buf; *p; p = CharNext(p))\n\tif (*p == '\\\\')\n\t    *p = '/';\n    status = ruby_glob(buf, 0, insert, (VALUE)&tail);\n    if (buf != buffer)\n\tfree(buf);\n\n    if (status || last == tail) return 0;\n    if (patt->flags & NTMALLOC)\n\tfree(patt->str);\n    free(patt);\n    return tail;\n}\n\n// \n// Check a command string to determine if it has I/O redirection\n// characters that require it to be executed by a command interpreter\n//\n\nstatic bool\nhas_redirection(const char *cmd)\n{\n    char quote = '\\0';\n    const char *ptr;\n\n    //\n    // Scan the string, looking for redirection (< or >) or pipe \n    // characters (|) that are not in a quoted string\n    //\n\n    for (ptr = cmd; *ptr;) {\n\tswitch (*ptr) {\n\t  case '\\'':\n\t  case '\\\"':\n\t    if (!quote)\n\t\tquote = *ptr;\n\t    else if (quote == *ptr)\n\t\tquote = '\\0';\n\t    ptr++;\n\t    break;\n\n\t  case '>':\n\t  case '<':\n\t  case '|':\n\t    if (!quote)\n\t\treturn TRUE;\n\t    ptr++;\n\t    break;\n\n\t  case '\\\\':\n\t    ptr++;\n\t  default:\n\t    ptr = CharNext(ptr);\n\t    break;\n\t}\n    }\n    return FALSE;\n}\n\nstatic inline char *\nskipspace(char *ptr)\n{\n    while (ISSPACE(*ptr))\n\tptr++;\n    return ptr;\n}\n\nint \nrb_w32_cmdvector(const char *cmd, char ***vec)\n{\n    int globbing, len;\n    int elements, strsz, done;\n    int slashes, escape;\n    char *ptr, *base, *buffer, *cmdline;\n    char **vptr;\n    char quote;\n    NtCmdLineElement *curr, **tail;\n    NtCmdLineElement *cmdhead = NULL, **cmdtail = &cmdhead;\n\n    //\n    // just return if we don't have a command line\n    //\n\n    while (ISSPACE(*cmd))\n\tcmd++;\n    if (!*cmd) {\n\t*vec = NULL;\n\treturn 0;\n    }\n\n    ptr = cmdline = strdup(cmd);\n\n    //\n    // Ok, parse the command line, building a list of CmdLineElements.\n    // When we've finished, and it's an input command (meaning that it's\n    // the processes argv), we'll do globing and then build the argument \n    // vector.\n    // The outer loop does one interation for each element seen. \n    // The inner loop does one interation for each character in the element.\n    //\n\n    while (*(ptr = skipspace(ptr))) {\n\tbase = ptr;\n\tquote = slashes = globbing = escape = 0;\n\tfor (done = 0; !done && *ptr; ) {\n\t    //\n\t    // Switch on the current character. We only care about the\n\t    // white-space characters, the  wild-card characters, and the\n\t    // quote characters.\n\t    //\n\n\t    switch (*ptr) {\n\t      case '\\\\':\n\t\tif (quote != '\\'') slashes++;\n\t        break;\n\n\t      case ' ':\n\t      case '\\t':\n\t      case '\\n':\n\t\t//\n\t\t// if we're not in a string, then we're finished with this\n\t\t// element\n\t\t//\n\n\t\tif (!quote) {\n\t\t    *ptr = 0;\n\t\t    done = 1;\n\t\t}\n\t\tbreak;\n\n\t      case '*':\n\t      case '?':\n\t      case '[':\n\t      case '{':\n\t\t// \n\t\t// record the fact that this element has a wildcard character\n\t\t// N.B. Don't glob if inside a single quoted string\n\t\t//\n\n\t\tif (quote != '\\'')\n\t\t    globbing++;\n\t\tslashes = 0;\n\t\tbreak;\n\n\t      case '\\'':\n\t      case '\\\"':\n\t\t//\n\t\t// if we're already in a string, see if this is the\n\t\t// terminating close-quote. If it is, we're finished with \n\t\t// the string, but not neccessarily with the element.\n\t\t// If we're not already in a string, start one.\n\t\t//\n\n\t\tif (!(slashes & 1)) {\n\t\t    if (!quote)\n\t\t\tquote = *ptr;\n\t\t    else if (quote == *ptr) {\n\t\t\tif (quote == '\"' && quote == ptr[1])\n\t\t\t    ptr++;\n\t\t\tquote = '\\0';\n\t\t    }\n\t\t}\n\t\tescape++;\n\t\tslashes = 0;\n\t\tbreak;\n\n\t      default:\n\t\tptr = CharNext(ptr);\n\t\tslashes = 0;\n\t\tcontinue;\n\t    }\n\t    ptr++;\n\t}\n\n\t//\n\t// when we get here, we've got a pair of pointers to the element,\n\t// base and ptr. Base points to the start of the element while ptr\n\t// points to the character following the element.\n\t//\n\n\tlen = ptr - base;\n\tif (done) --len;\n\n\t//\n\t// if it's an input vector element and it's enclosed by quotes, \n\t// we can remove them.\n\t//\n\n\tif (escape) {\n\t    char *p = base, c;\n\t    slashes = quote = 0;\n\t    while (p < base + len) {\n\t\tswitch (c = *p) {\n\t\t  case '\\\\':\n\t\t    p++;\n\t\t    if (quote != '\\'') slashes++;\n\t\t    break;\n\n\t\t  case '\\'':\n\t\t  case '\"':\n\t\t    if (!(slashes & 1) && quote && quote != c) {\n\t\t\tp++;\n\t\t\tslashes = 0;\n\t\t\tbreak;\n\t\t    }\n\t\t    memcpy(p - ((slashes + 1) >> 1), p + (~slashes & 1),\n\t\t\t   base + len - p);\n\t\t    len -= ((slashes + 1) >> 1) + (~slashes & 1);\n\t\t    p -= (slashes + 1) >> 1;\n\t\t    if (!(slashes & 1)) {\n\t\t\tif (quote) {\n\t\t\t    if (quote == '\"' && quote == *p)\n\t\t\t\tp++;\n\t\t\t    quote = '\\0';\n\t\t\t}\n\t\t\telse\n\t\t\t    quote = c;\n\t\t    }\n\t\t    else\n\t\t\tp++;\n\t\t    slashes = 0;\n\t\t    break;\n\n\t\t  default:\n\t\t    p = CharNext(p);\n\t\t    slashes = 0;\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\n\tcurr = (NtCmdLineElement *)calloc(sizeof(NtCmdLineElement), 1);\n\tif (!curr) goto do_nothing;\n\tcurr->str = base;\n\tcurr->len = len;\n\n\tif (globbing && (tail = cmdglob(curr, cmdtail))) {\n\t    cmdtail = tail;\n\t}\n\telse {\n\t    *cmdtail = curr;\n\t    cmdtail = &curr->next;\n\t}\n    }\n\n    //\n    // Almost done! \n    // Count up the elements, then allocate space for a vector of pointers\n    // (argv) and a string table for the elements.\n    // \n\n    for (elements = 0, strsz = 0, curr = cmdhead; curr; curr = curr->next) {\n\telements++;\n\tstrsz += (curr->len + 1);\n    }\n\n    len = (elements+1)*sizeof(char *) + strsz;\n    buffer = (char *)malloc(len);\n    if (!buffer) {\n      do_nothing:\n\twhile (curr = cmdhead) {\n\t    cmdhead = curr->next;\n\t    if (curr->flags & NTMALLOC) free(curr->str);\n\t    free(curr);\n\t}\n\tfree(cmdline);\n\tfor (vptr = *vec; *vptr; ++vptr);\n\treturn vptr - *vec;\n    }\n    \n    //\n    // make vptr point to the start of the buffer\n    // and ptr point to the area we'll consider the string table.\n    //\n    //   buffer (*vec)\n    //   |\n    //   V       ^---------------------V\n    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+\n    //   |   |       | ....  | NULL  |   | ..... |\\0 |   | ..... |\\0 |...\n    //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+\n    //   |-  elements+1             -| ^ 1st element   ^ 2nd element\n\n    vptr = (char **) buffer;\n\n    ptr = buffer + (elements+1) * sizeof(char *);\n\n    while (curr = cmdhead) {\n\tmemcpy(ptr, curr->str, curr->len);\n\t*vptr++ = ptr;\n\tptr += curr->len;\n\t*ptr++ = '\\0';\n\tcmdhead = curr->next;\n\tif (curr->flags & NTMALLOC) free(curr->str);\n\tfree(curr);\n    }\n    *vptr = 0;\n\n    *vec = (char **) buffer;\n    free(cmdline);\n    return elements;\n}\n\n//\n// UNIX compatible directory access functions for NT\n//\n\n#define PATHLEN 1024\n\n//\n// The idea here is to read all the directory names into a string table\n// (separated by nulls) and when one of the other dir functions is called\n// return the pointer to the current file name. \n//\n\n#define GetBit(bits, i) ((bits)[(i) / CHAR_BIT] &  (1 << (i) % CHAR_BIT))\n#define SetBit(bits, i) ((bits)[(i) / CHAR_BIT] |= (1 << (i) % CHAR_BIT))\n\n#define BitOfIsDir(n) ((n) * 2)\n#define BitOfIsRep(n) ((n) * 2 + 1)\n#define DIRENT_PER_CHAR (CHAR_BIT / 2)\n\nstatic HANDLE\nopen_dir_handle(const char *filename, WIN32_FIND_DATA *fd)\n{\n    HANDLE fh;\n    static const char wildcard[] = \"/*\";\n    long len = strlen(filename);\n    char *scanname = malloc(len + sizeof(wildcard));\n\n    //\n    // Create the search pattern\n    //\n    if (!scanname) {\n\treturn INVALID_HANDLE_VALUE;\n    }\n    memcpy(scanname, filename, len + 1);\n\n    if (index(\"/\\\\:\", *CharPrev(scanname, scanname + len)) == NULL)\n\tmemcpy(scanname + len, wildcard, sizeof(wildcard));\n    else\n\tmemcpy(scanname + len, wildcard + 1, sizeof(wildcard) - 1);\n\n    //\n    // do the FindFirstFile call\n    //\n    fh = FindFirstFile(scanname, fd);\n    free(scanname);\n    if (fh == INVALID_HANDLE_VALUE) {\n\terrno = map_errno(GetLastError());\n    }\n    return fh;\n}\n\nDIR *\nrb_w32_opendir(const char *filename)\n{\n    DIR               *p;\n    long               len;\n    long               idx;\n    struct stat\t       sbuf;\n    WIN32_FIND_DATA fd;\n    HANDLE          fh;\n\n    //\n    // check to see if we've got a directory\n    //\n\n    if (rb_w32_stat(filename, &sbuf) < 0)\n\treturn NULL;\n    if (!(sbuf.st_mode & S_IFDIR) &&\n\t(!ISALPHA(filename[0]) || filename[1] != ':' || filename[2] != '\\0' ||\n\t((1 << (filename[0] & 0x5f) - 'A') & GetLogicalDrives()) == 0)) {\n\terrno = ENOTDIR;\n\treturn NULL;\n    }\n\n    fh = open_dir_handle(filename, &fd);\n    if (fh == INVALID_HANDLE_VALUE) {\n\treturn NULL;\n    }\n\n    //\n    // Get us a DIR structure\n    //\n    p = calloc(sizeof(DIR), 1);\n    if (p == NULL)\n\treturn NULL;\n\n    //\n    // now allocate the first part of the string table for the\n    // filenames that we find.\n    //\n\n    idx = strlen(fd.cFileName)+1;\n    if (!(p->start = (char *)malloc(idx)) || !(p->bits = (char *)malloc(1))) {\n      error:\n\trb_w32_closedir(p);\n\tFindClose(fh);\n\terrno = ENOMEM;\n\treturn NULL;\n    }\n    strcpy(p->start, fd.cFileName);\n    p->bits[0] = 0;\n    if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n\tSetBit(p->bits, BitOfIsDir(0));\n    if (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)\n\tSetBit(p->bits, BitOfIsRep(0));\n    p->nfiles++;\n\n    //\n    // loop finding all the files that match the wildcard\n    // (which should be all of them in this directory!).\n    // the variable idx should point one past the null terminator\n    // of the previous string found.\n    //\n    while (FindNextFile(fh, &fd)) {\n\tchar *newpath;\n\n\tlen = strlen(fd.cFileName) + 1;\n\n\t//\n\t// bump the string table size by enough for the\n\t// new name and it's null terminator \n\t//\n\n\tnewpath = (char *)realloc(p->start, idx + len);\n\tif (newpath == NULL) {\n\t    goto error;\n\t}\n\tp->start = newpath;\n\tstrcpy(&p->start[idx], fd.cFileName);\n\n\tif (p->nfiles % DIRENT_PER_CHAR == 0) {\n\t    char *tmp = realloc(p->bits, p->nfiles / DIRENT_PER_CHAR + 1);\n\t    if (!tmp)\n\t\tgoto error;\n\t    p->bits = tmp;\n\t    p->bits[p->nfiles / DIRENT_PER_CHAR] = 0;\n\t}\n\tif (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\n\t    SetBit(p->bits, BitOfIsDir(p->nfiles));\n\tif (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)\n\t    SetBit(p->bits, BitOfIsRep(p->nfiles));\n\n\tp->nfiles++;\n\tidx += len;\n    }\n    FindClose(fh);\n    p->size = idx;\n    p->curr = p->start;\n    return p;\n}\n\n//\n// Move to next entry\n//\n\nstatic void\nmove_to_next_entry(DIR *dirp)\n{\n    if (dirp->curr) {\n\tdirp->loc++;\n\tdirp->curr += strlen(dirp->curr) + 1;\n\tif (dirp->curr >= (dirp->start + dirp->size)) {\n\t    dirp->curr = NULL;\n\t}\n    }\n}\n\n//\n// Readdir just returns the current string pointer and bumps the\n// string pointer to the next entry.\n//\n\nstruct direct  *\nrb_w32_readdir(DIR *dirp)\n{\n    static int  dummy = 0;\n\n    if (dirp->curr) {\n\n\t//\n\t// first set up the structure to return\n\t//\n\n\tstrcpy(dirp->dirstr.d_name, dirp->curr);\n\tdirp->dirstr.d_namlen = strlen(dirp->curr);\n\n\t//\n\t// Fake inode\n\t//\n\tdirp->dirstr.d_ino = dummy++;\n\n\t//\n\t// Attributes\n\t//\n\tdirp->dirstr.d_isdir = GetBit(dirp->bits, BitOfIsDir(dirp->loc));\n\tdirp->dirstr.d_isrep = GetBit(dirp->bits, BitOfIsRep(dirp->loc));\n\n\t//\n\t// Now set up for the next call to readdir\n\t//\n\n\tmove_to_next_entry(dirp);\n\n\treturn &(dirp->dirstr);\n\n    } else\n\treturn NULL;\n}\n\n//\n// Telldir returns the current string pointer position\n//\n\nlong\nrb_w32_telldir(DIR *dirp)\n{\n    return dirp->loc;\n}\n\n//\n// Seekdir moves the string pointer to a previously saved position\n// (Saved by telldir).\n\nvoid\nrb_w32_seekdir(DIR *dirp, long loc)\n{\n    rb_w32_rewinddir(dirp);\n\n    while (dirp->curr && loc-- > 0) {\n\tmove_to_next_entry(dirp);\n    }\n}\n\n//\n// Rewinddir resets the string pointer to the start\n//\n\nvoid\nrb_w32_rewinddir(DIR *dirp)\n{\n    dirp->curr = dirp->start;\n    dirp->loc = 0;\n}\n\n//\n// This just free's the memory allocated by opendir\n//\n\nvoid\nrb_w32_closedir(DIR *dirp)\n{\n    free(dirp->start);\n    free(dirp->bits);\n    free(dirp);\n}\n\nEXTERN_C void __cdecl _lock_fhandle(int);\nEXTERN_C void __cdecl _unlock_fhandle(int);\nEXTERN_C void __cdecl _unlock(int);\n\n#if (defined _MT || defined __MSVCRT__) && !defined __BORLANDC__\n#define MSVCRT_THREADS\n#endif\n#ifdef MSVCRT_THREADS\n# define MTHREAD_ONLY(x) x\n# define STHREAD_ONLY(x)\n#elif defined(__BORLANDC__)\n# define MTHREAD_ONLY(x)\n# define STHREAD_ONLY(x)\n#else\n# define MTHREAD_ONLY(x)\n# define STHREAD_ONLY(x) x\n#endif\n\ntypedef struct\t{\n    long osfhnd;    /* underlying OS file HANDLE */\n    char osfile;    /* attributes of file (e.g., open in text mode?) */\n    char pipech;    /* one char buffer for handles opened on pipes */\n#ifdef MSVCRT_THREADS\n    int lockinitflag;\n    CRITICAL_SECTION lock;\n#if _MSC_VER >= 1400\n    char textmode;\n    char pipech2[2];\n#endif\n#endif\n}\tioinfo;\n\n#if !defined _CRTIMP || defined __MINGW32__\n#undef _CRTIMP\n#define _CRTIMP __declspec(dllimport)\n#endif\n\n#if !defined(__BORLANDC__) && !defined(_WIN32_WCE)\nEXTERN_C _CRTIMP ioinfo * __pioinfo[];\n\n#define IOINFO_L2E\t\t\t5\n#define IOINFO_ARRAY_ELTS\t(1 << IOINFO_L2E)\n#define _pioinfo(i)\t((ioinfo*)((char*)(__pioinfo[i >> IOINFO_L2E]) + (i & (IOINFO_ARRAY_ELTS - 1)) * (sizeof(ioinfo) + pioinfo_extra)))\n#define _osfhnd(i)  (_pioinfo(i)->osfhnd)\n#define _osfile(i)  (_pioinfo(i)->osfile)\n#define _pipech(i)  (_pioinfo(i)->pipech)\n\n#if _MSC_VER >= 1400\nstatic size_t pioinfo_extra = 0;\t/* workaround for VC++8 SP1 */\n\nstatic void\nset_pioinfo_extra(void)\n{\n    int fd;\n\n    fd = open(\"NUL\", O_RDONLY);\n    for (pioinfo_extra = 0; pioinfo_extra <= 64; pioinfo_extra += sizeof(void *)) {\n\tif (_osfhnd(fd) == _get_osfhandle(fd)) {\n\t    break;\n\t}\n    }\n    close(fd);\n\n    if (pioinfo_extra > 64) {\n\t/* not found, maybe something wrong... */\n\tpioinfo_extra = 0;\n    }\n}\n#else\n#define pioinfo_extra 0\n#endif\n\n#define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = osfh)\n#define _set_osflags(fh, flags) (_osfile(fh) = (flags))\n\n#define FOPEN\t\t\t0x01\t/* file handle open */\n#define FNOINHERIT\t\t0x10\t/* file handle opened O_NOINHERIT */\n#define FAPPEND\t\t\t0x20\t/* file handle opened O_APPEND */\n#define FDEV\t\t\t0x40\t/* file handle refers to device */\n#define FTEXT\t\t\t0x80\t/* file handle is in text mode */\n\nstatic int\nrb_w32_open_osfhandle(long osfhandle, int flags)\n{\n    int fh;\n    char fileflags;\t\t/* _osfile flags */\n    HANDLE hF;\n\n    /* copy relevant flags from second parameter */\n    fileflags = FDEV;\n\n    if (flags & O_APPEND)\n\tfileflags |= FAPPEND;\n\n    if (flags & O_TEXT)\n\tfileflags |= FTEXT;\n\n    if (flags & O_NOINHERIT)\n\tfileflags |= FNOINHERIT;\n\n    /* attempt to allocate a C Runtime file handle */\n    hF = CreateFile(\"NUL\", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);\n    fh = _open_osfhandle((long)hF, 0);\n    CloseHandle(hF);\n    if (fh == -1) {\n\terrno = EMFILE;\t\t/* too many open files */\n\t_doserrno = 0L;\t\t/* not an OS error */\n    }\n    else {\n\n\tMTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fh)->lock)));\n\t/* the file is open. now, set the info in _osfhnd array */\n\t_set_osfhnd(fh, osfhandle);\n\n\tfileflags |= FOPEN;\t\t/* mark as open */\n\n\t_set_osflags(fh, fileflags); /* set osfile entry */\n\tMTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fh)->lock));\n    }\n    return fh;\t\t\t/* return handle */\n}\n\nstatic void\ninit_stdhandle(void)\n{\n    if (fileno(stdin) < 0) {\n\tstdin->_file = 0;\n    }\n    if (fileno(stdout) < 0) {\n\tstdout->_file = 1;\n    }\n    if (fileno(stderr) < 0) {\n\tstderr->_file = 2;\n    }\n    setvbuf(stderr, NULL, _IONBF, 0);\n}\n#else\n\n#define _set_osfhnd(fh, osfh) (void)((fh), (osfh))\n#define _set_osflags(fh, flags) (void)((fh), (flags))\n\nstatic void\ninit_stdhandle(void)\n{\n}\n#endif\n\n#ifdef __BORLANDC__\nstatic int\nrb_w32_open_osfhandle(long osfhandle, int flags)\n{\n    int fd = _open_osfhandle(osfhandle, flags);\n    if (fd == -1) {\n\terrno = EMFILE;\t\t/* too many open files */\n\t_doserrno = 0L;\t\t/* not an OS error */\n    }\n    return fd;\n}\n#endif\n\n#undef getsockopt\n\nstatic int\nis_socket(SOCKET fd)\n{\n    char sockbuf[80];\n    int optlen;\n    int retval;\n    int result = TRUE;\n\n    optlen = sizeof(sockbuf);\n    RUBY_CRITICAL({\n\tretval = getsockopt(fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);\n\tif (retval == SOCKET_ERROR) {\n\t    int iRet;\n\t    iRet = WSAGetLastError();\n\t    if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED)\n\t\tresult = FALSE;\n\t}\n    });\n\n    //\n    // If we get here, then fd is actually a socket.\n    //\n\n    return result;\n}\n\n//\n// Since the errors returned by the socket error function \n// WSAGetLastError() are not known by the library routine strerror\n// we have to roll our own.\n//\n\n#undef strerror\n\nchar *\nrb_w32_strerror(int e)\n{\n    static char buffer[512];\n#if !defined __MINGW32__\n    extern int sys_nerr;\n#endif\n    DWORD source = 0;\n    char *p;\n\n#if defined __BORLANDC__ && defined ENOTEMPTY // _sys_errlist is broken\n    switch (e) {\n      case ENAMETOOLONG:\n\treturn \"Filename too long\";\n      case ENOTEMPTY:\n\treturn \"Directory not empty\";\n    }\n#endif\n\n    if (e < 0 || e > sys_nerr) {\n\tif (e < 0)\n\t    e = GetLastError();\n\tif (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |\n\t\t\t  FORMAT_MESSAGE_IGNORE_INSERTS, &source, e, 0,\n\t\t\t  buffer, sizeof(buffer), NULL) == 0) {\n\t    strcpy(buffer, \"Unknown Error\");\n\t}\n    }\n    else {\n\tstrncpy(buffer, strerror(e), sizeof(buffer));\n\tbuffer[sizeof(buffer) - 1] = 0;\n    }\n\n    p = buffer;\n    while ((p = strpbrk(p, \"\\r\\n\")) != NULL) {\n\tmemmove(p, p + 1, strlen(p));\n    }\n    return buffer;\n}\n\n//\n// various stubs\n//\n\n\n// Ownership\n//\n// Just pretend that everyone is a superuser. NT will let us know if\n// we don't really have permission to do something.\n//\n\n#define ROOT_UID\t0\n#define ROOT_GID\t0\n\nrb_uid_t\ngetuid(void)\n{\n\treturn ROOT_UID;\n}\n\nrb_uid_t\ngeteuid(void)\n{\n\treturn ROOT_UID;\n}\n\nrb_gid_t\ngetgid(void)\n{\n\treturn ROOT_GID;\n}\n\nrb_gid_t\ngetegid(void)\n{\n    return ROOT_GID;\n}\n\nint\nsetuid(rb_uid_t uid)\n{ \n    return (uid == ROOT_UID ? 0 : -1);\n}\n\nint\nsetgid(rb_gid_t gid)\n{\n    return (gid == ROOT_GID ? 0 : -1);\n}\n\n//\n// File system stuff\n//\n\nint\n/* ioctl(int i, unsigned int u, char *data) */\n#ifdef __BORLANDC__\n  ioctl(int i, int u, ...)\n#else\n  ioctl(int i, unsigned int u, long data)\n#endif\n{\n    errno = EINVAL;\n    return -1;\n}\n\n#undef FD_SET\n\nvoid\nrb_w32_fdset(int fd, fd_set *set)\n{\n    unsigned int i;\n    SOCKET s = TO_SOCKET(fd);\n\n    for (i = 0; i < set->fd_count; i++) {\n        if (set->fd_array[i] == s) {\n            return;\n        }\n    }\n    if (i == set->fd_count) {\n        if (set->fd_count < FD_SETSIZE) {\n            set->fd_array[i] = s;\n            set->fd_count++;\n        }\n    }\n}\n\n#undef FD_CLR\n\nvoid\nrb_w32_fdclr(int fd, fd_set *set)\n{\n    unsigned int i;\n    SOCKET s = TO_SOCKET(fd);\n\n    for (i = 0; i < set->fd_count; i++) {\n        if (set->fd_array[i] == s) {\n            while (i < set->fd_count - 1) {\n                set->fd_array[i] = set->fd_array[i + 1];\n                i++;\n            }\n            set->fd_count--;\n            break;\n        }\n    }\n}\n\n#undef FD_ISSET\n\nint\nrb_w32_fdisset(int fd, fd_set *set)\n{\n    int ret;\n    SOCKET s = TO_SOCKET(fd);\n    if (s == (SOCKET)INVALID_HANDLE_VALUE)\n        return 0;\n    RUBY_CRITICAL(ret = __WSAFDIsSet(s, set));\n    return ret;\n}\n\n//\n// Networking trampolines\n// These are used to avoid socket startup/shutdown overhead in case \n// the socket routines aren't used.\n//\n\n#undef select\n\nstatic int NtSocketsInitialized = 0;\n\nstatic int\nextract_fd(fd_set *dst, fd_set *src, int (*func)(SOCKET))\n{\n    int s = 0;\n    if (!src || !dst) return 0;\n\n    while (s < src->fd_count) {\n        SOCKET fd = src->fd_array[s];\n\n\tif (!func || (*func)(fd)) { /* move it to dst */\n\t    int d;\n\n\t    for (d = 0; d < dst->fd_count; d++) {\n\t\tif (dst->fd_array[d] == fd) break;\n\t    }\n\t    if (d == dst->fd_count && dst->fd_count < FD_SETSIZE) {\n\t\tdst->fd_array[dst->fd_count++] = fd;\n\t    }\n\t    memmove(\n\t\t&src->fd_array[s],\n\t\t&src->fd_array[s+1], \n\t\tsizeof(src->fd_array[0]) * (--src->fd_count - s));\n\t}\n\telse s++;\n    }\n\n    return dst->fd_count;\n}\n\nstatic int\nis_not_socket(SOCKET sock)\n{\n    return !is_socket(sock);\n}\n\nstatic int\nis_pipe(SOCKET sock) /* DONT call this for SOCKET! it clains it is PIPE. */\n{\n    int ret;\n\n    RUBY_CRITICAL(\n\tret = (GetFileType((HANDLE)sock) == FILE_TYPE_PIPE)\n    );\n\n    return ret;\n}\n\nstatic int\nis_readable_pipe(SOCKET sock) /* call this for pipe only */\n{\n    int ret;\n    DWORD n = 0;\n\n    RUBY_CRITICAL(\n\tif (PeekNamedPipe((HANDLE)sock, NULL, 0, NULL, &n, NULL)) {\n\t    ret = (n > 0);\n\t}\n\telse {\n\t    ret = (GetLastError() == ERROR_BROKEN_PIPE); /* pipe was closed */\n\t}\n    );\n\n    return ret;\n}\n\nstatic int\nis_console(SOCKET sock) /* DONT call this for SOCKET! */\n{\n    int ret;\n    DWORD n = 0;\n    INPUT_RECORD ir;\n\n    RUBY_CRITICAL(\n\tret = (PeekConsoleInput((HANDLE)sock, &ir, 1, &n))\n    );\n\n    return ret;\n}\n\nstatic int\nis_readable_console(SOCKET sock) /* call this for console only */\n{\n    int ret = 0;\n    DWORD n = 0;\n    INPUT_RECORD ir;\n\n    RUBY_CRITICAL(\n\tif (PeekConsoleInput((HANDLE)sock, &ir, 1, &n) && n > 0) {\n\t    if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown &&\n\t\tir.Event.KeyEvent.uChar.AsciiChar) {\n\t\tret = 1;\n\t    }\n\t    else {\n\t\tReadConsoleInput((HANDLE)sock, &ir, 1, &n);\n\t    }\n\t}\n    );\n\n    return ret;\n}\n\nstatic int\ndo_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,\n            struct timeval *timeout)\n{\n    int r = 0;\n\n    if (nfds == 0) {\n\tif (timeout)\n\t    rb_w32_sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);\n\telse\n\t    rb_w32_sleep(INFINITE);\n    }\n    else {\n\tRUBY_CRITICAL(\n\t    EnterCriticalSection(&select_mutex);\n\t    r = select(nfds, rd, wr, ex, timeout);\n\t    LeaveCriticalSection(&select_mutex);\n\t    if (r == SOCKET_ERROR) {\n\t\terrno = map_errno(WSAGetLastError());\n\t\tr = -1;\n\t    }\n\t);\n    }\n\n    return r;\n}\n\nstatic inline int\nsubtract(struct timeval *rest, const struct timeval *wait)\n{\n    if (rest->tv_sec < wait->tv_sec) {\n\treturn 0;\n    }\n    while (rest->tv_usec <= wait->tv_usec) {\n\tif (rest->tv_sec <= wait->tv_sec) {\n\t    return 0;\n\t}\n\trest->tv_sec -= 1;\n\trest->tv_usec += 1000 * 1000;\n    }\n    rest->tv_sec -= wait->tv_sec;\n    rest->tv_usec -= wait->tv_usec;\n    return 1;\n}\n\nstatic inline int\ncompare(const struct timeval *t1, const struct timeval *t2)\n{\n    if (t1->tv_sec < t2->tv_sec)\n\treturn -1;\n    if (t1->tv_sec > t2->tv_sec)\n\treturn 1;\n    if (t1->tv_usec < t2->tv_usec)\n\treturn -1;\n    if (t1->tv_usec > t2->tv_usec)\n\treturn 1;\n    return 0;\n}\n\n#undef Sleep\nlong \nrb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,\n\t      struct timeval *timeout)\n{\n    long r;\n    fd_set pipe_rd;\n    fd_set cons_rd;\n    fd_set else_rd;\n    fd_set else_wr;\n    int nonsock = 0;\n    struct timeval limit;\n\n    if (nfds < 0 || (timeout && (timeout->tv_sec < 0 || timeout->tv_usec < 0))) {\n\terrno = EINVAL;\n\treturn -1;\n    }\n\n    if (timeout) {\n\tif (timeout->tv_sec < 0 ||\n\t    timeout->tv_usec < 0 ||\n\t    timeout->tv_usec >= 1000000) {\n\t    errno = EINVAL;\n\t    return -1;\n\t}\n\tgettimeofday(&limit, NULL);\n\tlimit.tv_sec += timeout->tv_sec;\n\tlimit.tv_usec += timeout->tv_usec;\n\tif (limit.tv_usec >= 1000000) {\n\t    limit.tv_usec -= 1000000;\n\t    limit.tv_sec++;\n\t}\n    }\n\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n\n    // assume else_{rd,wr} (other than socket, pipe reader, console reader)\n    // are always readable/writable. but this implementation still has\n    // problem. if pipe's buffer is full, writing to pipe will block\n    // until some data is read from pipe. but ruby is single threaded system,\n    // so whole system will be blocked forever.\n\n    else_rd.fd_count = 0;\n    nonsock += extract_fd(&else_rd, rd, is_not_socket);\n\n    pipe_rd.fd_count = 0;\n    extract_fd(&pipe_rd, &else_rd, is_pipe); // should not call is_pipe for socket\n\n    cons_rd.fd_count = 0;\n    extract_fd(&cons_rd, &else_rd, is_console); // ditto\n\n    else_wr.fd_count = 0;\n    nonsock += extract_fd(&else_wr, wr, is_not_socket);\n\n    r = 0;\n    if (rd && rd->fd_count > r) r = rd->fd_count;\n    if (wr && wr->fd_count > r) r = wr->fd_count;\n    if (ex && ex->fd_count > r) r = ex->fd_count;\n    if (nfds > r) nfds = r;\n\n    {\n\tstruct timeval rest;\n\tstruct timeval wait;\n\tstruct timeval zero;\n\twait.tv_sec = 0; wait.tv_usec = 10 * 1000; // 10ms\n\tzero.tv_sec = 0; zero.tv_usec = 0;         //  0ms\n\tif (timeout) rest = *timeout;\n\tfor (;;) {\n\t    if (nonsock) {\n\t\t// modifying {else,pipe,cons}_rd is safe because\n\t\t// if they are modified, function returns immediately.\n\t\textract_fd(&else_rd, &pipe_rd, is_readable_pipe);\n\t\textract_fd(&else_rd, &cons_rd, is_readable_console);\n\t    }\n\n\t    if (else_rd.fd_count || else_wr.fd_count) {\n\t\tr = do_select(nfds, rd, wr, ex, &zero); // polling\n\t\tif (r < 0) break; // XXX: should I ignore error and return signaled handles?\n\t\tr += extract_fd(rd, &else_rd, NULL); // move all\n\t\tr += extract_fd(wr, &else_wr, NULL); // move all\n\t\tbreak;\n\t    }\n\t    else {\n\t\tfd_set orig_rd;\n\t\tfd_set orig_wr;\n\t\tfd_set orig_ex;\n\t\tstruct timeval *dowait = &wait;\n\t\tif (timeout && compare(&rest, &wait) < 0) dowait = &rest;\n\n\t\tif (rd) orig_rd = *rd;\n\t\tif (wr) orig_wr = *wr;\n\t\tif (ex) orig_ex = *ex;\n\t\tr = do_select(nfds, rd, wr, ex, dowait);\n\t\tif (r != 0) break; // signaled or error\n\t\tif (rd) *rd = orig_rd;\n\t\tif (wr) *wr = orig_wr;\n\t\tif (ex) *ex = orig_ex;\n\n\t\tif (timeout) {\n\t\t    struct timeval now;\n\t\t    gettimeofday(&now, NULL);\n\t\t    rest = limit;\n\t\t    if (!subtract(&rest, &now)) break;\n\t\t}\n\t    }\n\t}\n    }\n\n    return r;\n}\n\nstatic void\nStartSockets ()\n{\n    WORD version;\n    WSADATA retdata;\n    int ret;\n#ifndef USE_WINSOCK2\n    int iSockOpt;\n#endif\n\n    //\n    // initalize the winsock interface and insure that it's\n    // cleaned up at exit.\n    //\n#ifdef USE_WINSOCK2\n    version = MAKEWORD(2, 0);\n    if (WSAStartup(version, &retdata))\n\trb_fatal (\"Unable to locate winsock library!\\n\");\n    if (LOBYTE(retdata.wVersion) != 2)\n\trb_fatal(\"could not find version 2 of winsock dll\\n\");\n#else\n    version = MAKEWORD(1, 1);\n    if (ret = WSAStartup(version, &retdata))\n\trb_fatal (\"Unable to locate winsock library!\\n\");\n    if (LOBYTE(retdata.wVersion) != 1)\n\trb_fatal(\"could not find version 1 of winsock dll\\n\");\n\n    if (HIBYTE(retdata.wVersion) != 1)\n\trb_fatal(\"could not find version 1 of winsock dll\\n\");\n#endif\t/* USE_WINSOCK2 */\n\n    fWinsock = TRUE;\n\n#ifndef USE_WINSOCK2\n# ifndef SO_SYNCHRONOUS_NONALERT\n#  define SO_SYNCHRONOUS_NONALERT 0x20\n# endif\n\n    iSockOpt = SO_SYNCHRONOUS_NONALERT;\n    /*\n     * Enable the use of sockets as filehandles\n     */\n# ifndef SO_OPENTYPE\n#  define SO_OPENTYPE     0x7008\n# endif\n\n    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,\n\t       (char *)&iSockOpt, sizeof(iSockOpt));\n#endif\t/* USE_WINSOCK2 */\n\n    main_thread.handle = GetCurrentThreadHandle();\n    main_thread.id = GetCurrentThreadId();\n\n    interrupted_event = CreateSignal();\n    if (!interrupted_event)\n\trb_fatal(\"Unable to create interrupt event!\\n\");\n    NtSocketsInitialized = 1;\n}\n\n#undef accept\n\nint\nrb_w32_accept(int s, struct sockaddr *addr, int *addrlen)\n{\n    SOCKET r;\n    int fd;\n\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tHANDLE h = CreateFile(\"NUL\", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);\n\tfd = rb_w32_open_osfhandle((long)h, O_RDWR|O_BINARY|O_NOINHERIT);\n\tif (fd != -1) {\n\t    r = accept(TO_SOCKET(s), addr, addrlen);\n\t    if (r != INVALID_SOCKET) {\n\t\tMTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fd)->lock)));\n\t\t_set_osfhnd(fd, r);\n\t\tMTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));\n\t\tCloseHandle(h);\n\t    }\n\t    else {\n\t\terrno = map_errno(WSAGetLastError());\n\t\tclose(fd);\n\t\tfd = -1;\n\t    }\n\t}\n\telse\n\t    CloseHandle(h);\n    });\n    return fd;\n}\n\n#undef bind\n\nint \nrb_w32_bind(int s, struct sockaddr *addr, int addrlen)\n{\n    int r;\n\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = bind(TO_SOCKET(s), addr, addrlen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef connect\n\nint \nrb_w32_connect(int s, struct sockaddr *addr, int addrlen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = connect(TO_SOCKET(s), addr, addrlen);\n\tif (r == SOCKET_ERROR) {\n\t    int err = WSAGetLastError();\n\t    if (err != WSAEWOULDBLOCK)\n\t\terrno = map_errno(err);\n\t    else\n\t\terrno = EINPROGRESS;\n\t}\n    });\n    return r;\n}\n\n\n#undef getpeername\n\nint \nrb_w32_getpeername(int s, struct sockaddr *addr, int *addrlen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getpeername(TO_SOCKET(s), addr, addrlen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef getsockname\n\nint \nrb_w32_getsockname(int s, struct sockaddr *addr, int *addrlen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getsockname(TO_SOCKET(s), addr, addrlen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\nint \nrb_w32_getsockopt(int s, int level, int optname, char *optval, int *optlen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getsockopt(TO_SOCKET(s), level, optname, optval, optlen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef ioctlsocket\n\nint \nrb_w32_ioctlsocket(int s, long cmd, u_long *argp)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = ioctlsocket(TO_SOCKET(s), cmd, argp);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef listen\n\nint \nrb_w32_listen(int s, int backlog)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = listen(TO_SOCKET(s), backlog);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef recv\n\nint \nrb_w32_recv(int s, char *buf, int len, int flags)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = recv(TO_SOCKET(s), buf, len, flags);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef recvfrom\n\nint \nrb_w32_recvfrom(int s, char *buf, int len, int flags, \n\t\tstruct sockaddr *from, int *fromlen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = recvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef send\n\nint \nrb_w32_send(int s, const char *buf, int len, int flags)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = send(TO_SOCKET(s), buf, len, flags);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef sendto\n\nint \nrb_w32_sendto(int s, const char *buf, int len, int flags, \n\t      struct sockaddr *to, int tolen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = sendto(TO_SOCKET(s), buf, len, flags, to, tolen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef setsockopt\n\nint \nrb_w32_setsockopt(int s, int level, int optname, char *optval, int optlen)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = setsockopt(TO_SOCKET(s), level, optname, optval, optlen);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n    \n#undef shutdown\n\nint \nrb_w32_shutdown(int s, int how)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = shutdown(TO_SOCKET(s), how);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#ifdef USE_WINSOCK2\nstatic SOCKET\nopen_ifs_socket(int af, int type, int protocol)\n{\n    unsigned long proto_buffers_len = 0;\n    int error_code;\n    SOCKET out = INVALID_SOCKET;\n\n    if (WSAEnumProtocols(NULL, NULL, &proto_buffers_len) == SOCKET_ERROR) {\n\terror_code = WSAGetLastError();\n\tif (error_code == WSAENOBUFS) {\n\t    WSAPROTOCOL_INFO *proto_buffers;\n\t    int protocols_available = 0;\n\n\t    proto_buffers = (WSAPROTOCOL_INFO *)malloc(proto_buffers_len);\n\t    if (!proto_buffers) {\n\t\tWSASetLastError(WSA_NOT_ENOUGH_MEMORY);\n\t\treturn INVALID_SOCKET;\n\t    }\n\n\t    protocols_available =\n\t\tWSAEnumProtocols(NULL, proto_buffers, &proto_buffers_len);\n\t    if (protocols_available != SOCKET_ERROR) {\n\t\tint i;\n\t\tfor (i = 0; i < protocols_available; i++) {\n\t\t    if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily) ||\n\t\t\t(type != proto_buffers[i].iSocketType) ||\n\t\t\t(protocol != 0 && protocol != proto_buffers[i].iProtocol))\n\t\t\tcontinue;\n\n\t\t    if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)\n\t\t\tcontinue;\n\n\t\t    out = WSASocket(af, type, protocol, &(proto_buffers[i]), 0, 0);\n\t\t    break;\n\t\t}\n\t\tif (out == INVALID_SOCKET)\n\t\t    out = WSASocket(af, type, protocol, NULL, 0, 0);\n\t    }\n\n\t    free(proto_buffers);\n\t}\n    }\n\n    return out;\n}\n#endif\t/* USE_WINSOCK2 */\n\n#undef socket\n#ifdef USE_WINSOCK2\n#define open_socket(a, t, p)\topen_ifs_socket(a, t, p)\n#else\n#define open_socket(a, t, p)\tsocket(a, t, p)\n#endif\n\nint \nrb_w32_socket(int af, int type, int protocol)\n{\n    SOCKET s;\n    int fd;\n\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\ts = open_socket(af, type, protocol);\n\tif (s == INVALID_SOCKET) {\n\t    errno = map_errno(WSAGetLastError());\n\t    fd = -1;\n\t}\n\telse {\n\t    fd = rb_w32_open_osfhandle(s, O_RDWR|O_BINARY);\n\t}\n    });\n    return fd;\n}\n\n#undef gethostbyaddr\n\nstruct hostent *\nrb_w32_gethostbyaddr (char *addr, int len, int type)\n{\n    struct hostent *r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = gethostbyaddr(addr, len, type);\n\tif (r == NULL)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef gethostbyname\n\nstruct hostent *\nrb_w32_gethostbyname (char *name)\n{\n    struct hostent *r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = gethostbyname(name);\n\tif (r == NULL)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef gethostname\n\nint\nrb_w32_gethostname (char *name, int len)\n{\n    int r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = gethostname(name, len);\n\tif (r == SOCKET_ERROR)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef getprotobyname\n\nstruct protoent *\nrb_w32_getprotobyname (char *name)\n{\n    struct protoent *r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getprotobyname(name);\n\tif (r == NULL)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef getprotobynumber\n\nstruct protoent *\nrb_w32_getprotobynumber (int num)\n{\n    struct protoent *r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getprotobynumber(num);\n\tif (r == NULL)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef getservbyname\n\nstruct servent *\nrb_w32_getservbyname (char *name, char *proto)\n{\n    struct servent *r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getservbyname(name, proto);\n\tif (r == NULL)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n#undef getservbyport\n\nstruct servent *\nrb_w32_getservbyport (int port, char *proto)\n{\n    struct servent *r;\n    if (!NtSocketsInitialized) {\n\tStartSockets();\n    }\n    RUBY_CRITICAL({\n\tr = getservbyport(port, proto);\n\tif (r == NULL)\n\t    errno = map_errno(WSAGetLastError());\n    });\n    return r;\n}\n\n//\n// Networking stubs\n//\n\nvoid endhostent() {}\nvoid endnetent() {}\nvoid endprotoent() {}\nvoid endservent() {}\n\nstruct netent *getnetent (void) {return (struct netent *) NULL;}\n\nstruct netent *getnetbyaddr(long net, int type) {return (struct netent *)NULL;}\n\nstruct netent *getnetbyname(char *name) {return (struct netent *)NULL;}\n\nstruct protoent *getprotoent (void) {return (struct protoent *) NULL;}\n\nstruct servent *getservent (void) {return (struct servent *) NULL;}\n\nvoid sethostent (int stayopen) {}\n\nvoid setnetent (int stayopen) {}\n\nvoid setprotoent (int stayopen) {}\n\nvoid setservent (int stayopen) {}\n\nint\nfcntl(int fd, int cmd, ...)\n{\n    SOCKET sock = TO_SOCKET(fd);\n    va_list va;\n    int arg;\n    int ret;\n    u_long ioctlArg;\n\n    if (!is_socket(sock)) {\n\terrno = EBADF;\n\treturn -1;\n    }\n    if (cmd != F_SETFL) {\n\terrno = EINVAL;\n\treturn -1;\n    }\n\n    va_start(va, cmd);\n    arg = va_arg(va, int);\n    va_end(va);\n    if (arg & O_NONBLOCK) {\n\tioctlArg = 1;\n    }\n    else {\n\tioctlArg = 0;\n    }\n    RUBY_CRITICAL({\n\tret = ioctlsocket(sock, FIONBIO, &ioctlArg);\n\tif (ret == -1) {\n\t    errno = map_errno(WSAGetLastError());\n\t}\n    });\n\n    return ret;\n}\n\n#ifndef WNOHANG\n#define WNOHANG -1\n#endif\n\nstatic rb_pid_t\npoll_child_status(struct ChildRecord *child, int *stat_loc)\n{\n    DWORD exitcode;\n    DWORD err;\n\n    if (!GetExitCodeProcess(child->hProcess, &exitcode)) {\n\t/* If an error occured, return immediatly. */\n\terr = GetLastError();\n\tif (err == ERROR_INVALID_PARAMETER)\n\t    errno = ECHILD;\n\telse\n\t    errno = map_errno(GetLastError());\n\tCloseChildHandle(child);\n\treturn -1;\n    }\n    if (exitcode != STILL_ACTIVE) {\n\t/* If already died, return immediatly. */\n\trb_pid_t pid = child->pid;\n\tCloseChildHandle(child);\n\tif (stat_loc) *stat_loc = exitcode << 8;\n\treturn pid;\n    }\n    return 0;\n}\n\nrb_pid_t\nwaitpid(rb_pid_t pid, int *stat_loc, int options)\n{\n    DWORD timeout;\n\n    if (options == WNOHANG) {\n\ttimeout = 0;\n    } else {\n\ttimeout = INFINITE;\n    }\n\n    if (pid == -1) {\n\tint count = 0;\n\tDWORD ret;\n\tHANDLE events[MAXCHILDNUM + 1];\n\n\tFOREACH_CHILD(child) {\n\t    if (!child->pid || child->pid < 0) continue;\n\t    if ((pid = poll_child_status(child, stat_loc))) return pid;\n\t    events[count++] = child->hProcess;\n\t} END_FOREACH_CHILD;\n\tif (!count) {\n\t    errno = ECHILD;\n\t    return -1;\n\t}\n\tevents[count] = interrupted_event;\n\n\tret = WaitForMultipleEvents(count + 1, events, FALSE, timeout, TRUE);\n\tif (ret == WAIT_TIMEOUT) return 0;\n\tif ((ret -= WAIT_OBJECT_0) == count) {\n\t    ResetSignal(interrupted_event);\n\t    errno = EINTR;\n\t    return -1;\n\t}\n\tif (ret > count) {\n\t    errno = map_errno(GetLastError());\n\t    return -1;\n\t}\n\n\treturn poll_child_status(FindChildSlotByHandle(events[ret]), stat_loc);\n    }\n    else {\n\tstruct ChildRecord* child = FindChildSlot(pid);\n\tif (!child) {\n\t    errno = ECHILD;\n\t    return -1;\n\t}\n\n\twhile (!(pid = poll_child_status(child, stat_loc))) {\n\t    /* wait... */\n\t    if (wait_events(child->hProcess, timeout) != WAIT_OBJECT_0) {\n\t\t/* still active */\n\t\tpid = 0;\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    return pid;\n}\n\n#include <sys/timeb.h>\n\nstatic int\nfiletime_to_timeval(const FILETIME* ft, struct timeval *tv)\n{\n    ULARGE_INTEGER tmp;\n    unsigned LONG_LONG lt;\n\n    tmp.LowPart = ft->dwLowDateTime;\n    tmp.HighPart = ft->dwHighDateTime;\n    lt = tmp.QuadPart;\n\n    /* lt is now 100-nanosec intervals since 1601/01/01 00:00:00 UTC,\n       convert it into UNIX time (since 1970/01/01 00:00:00 UTC).\n       the first leap second is at 1972/06/30, so we doesn't need to think\n       about it. */\n    lt /= 10;\t/* to usec */\n    lt -= (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60 * 1000 * 1000;\n\n    tv->tv_sec = lt / (1000 * 1000);\n    tv->tv_usec = lt % (1000 * 1000);\n\n    return tv->tv_sec > 0 ? 0 : -1;\n}\n\nint _cdecl\ngettimeofday(struct timeval *tv, struct timezone *tz)\n{\n    FILETIME ft;\n\n    GetSystemTimeAsFileTime(&ft);\n    filetime_to_timeval(&ft, tv);\n\n    return 0;\n}\n\nchar *\nrb_w32_getcwd(char *buffer, int size)\n{\n    char *p = buffer;\n    char *bp;\n    int len;\n\n    len = GetCurrentDirectory(0, NULL);\n    if (!len) {\n\terrno = map_errno(GetLastError());\n\treturn NULL;\n    }\n\n    if (p) {\n\tif (size < len) {\n\t    errno = ERANGE;\n\t    return NULL;\n\t}\n    }\n    else {\n\tp = malloc(len);\n\tsize = len;\n\tif (!p) {\n\t    errno = ENOMEM;\n\t    return NULL;\n\t}\n    }\n\n    if (!GetCurrentDirectory(size, p)) {\n\terrno = map_errno(GetLastError());\n\tif (!buffer)\n\t    free(p);\n\treturn NULL;\n    }\n\n    for (bp = p; *bp != '\\0'; bp = CharNext(bp)) {\n\tif (*bp == '\\\\') {\n\t    *bp = '/';\n\t}\n    }\n\n    return p;\n}\n\nint\nchown(const char *path, int owner, int group)\n{\n\treturn 0;\n}\n\nint\nkill(int pid, int sig)\n{\n    int ret = 0;\n    DWORD err;\n\n    if (pid <= 0) {\n\terrno = EINVAL;\n\treturn -1;\n    }\n\n    if (IsWin95()) pid = -pid;\n    if ((unsigned int)pid == GetCurrentProcessId() &&\n\t(sig != 0 && sig != SIGKILL)) {\n\tif ((ret = raise(sig)) != 0) {\n\t    /* MSVCRT doesn't set errno... */\n\t    errno = EINVAL;\n\t}\n\treturn ret;\n    }\n\n    switch (sig) {\n      case 0:\n\tRUBY_CRITICAL({\n\t    HANDLE hProc =\n\t\tOpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pid);\n\t    if (hProc == NULL || hProc == INVALID_HANDLE_VALUE) {\n\t\tif (GetLastError() == ERROR_INVALID_PARAMETER) {\n\t\t    errno = ESRCH;\n\t\t}\n\t\telse {\n\t\t    errno = EPERM;\n\t\t}\n\t\tret = -1;\n\t    }\n\t    else {\n\t\tCloseHandle(hProc);\n\t    }\n\t});\n\tbreak;\n\n      case SIGINT:\n\tRUBY_CRITICAL({\n\t    if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid)) {\n\t\tif ((err = GetLastError()) == 0)\n\t\t    errno = EPERM;\n\t\telse\n\t\t    errno = map_errno(GetLastError());\n\t\tret = -1;\n\t    }\n\t});\n\tbreak;\n\n      case SIGKILL:\n\tRUBY_CRITICAL({\n\t    HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, (DWORD)pid);\n\t    if (hProc == NULL || hProc == INVALID_HANDLE_VALUE) {\n\t\tif (GetLastError() == ERROR_INVALID_PARAMETER) {\n\t\t    errno = ESRCH;\n\t\t}\n\t\telse {\n\t\t    errno = EPERM;\n\t\t}\n\t\tret = -1;\n\t    }\n\t    else {\n\t\tif (!TerminateProcess(hProc, 0)) {\n\t\t    errno = EPERM;\n\t\t    ret = -1;\n\t\t}\n\t\tCloseHandle(hProc);\n\t    }\n\t});\n\tbreak;\n\n      default:\n\terrno = EINVAL;\n\tret = -1;\n\tbreak;\n    }\n\n    return ret;\n}\n\nint\nlink(char *from, char *to)\n{\n    static BOOL (WINAPI *pCreateHardLink)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES) = NULL;\n    static int myerrno = 0;\n\n    if (!pCreateHardLink && !myerrno) {\n\tHANDLE hKernel;\n\n\thKernel = GetModuleHandle(\"kernel32.dll\");\n\tif (hKernel) {\n\t    pCreateHardLink = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES))GetProcAddress(hKernel, \"CreateHardLinkA\");\n\t    if (!pCreateHardLink) {\n\t\tmyerrno = map_errno(GetLastError());\n\t    }\n\t    CloseHandle(hKernel);\n\t}\n\telse {\n\t    myerrno = map_errno(GetLastError());\n\t}\n    }\n    if (!pCreateHardLink) {\n\terrno = myerrno;\n\treturn -1;\n    }\n\n    if (!pCreateHardLink(to, from, NULL)) {\n\terrno = map_errno(GetLastError());\n\treturn -1;\n    }\n\n    return 0;\n}\n\nint\nwait()\n{\n\treturn 0;\n}\n\nchar *\nrb_w32_getenv(const char *name)\n{\n    int len = strlen(name);\n    char *env;\n\n    if (envarea)\n\tFreeEnvironmentStrings(envarea);\n    envarea = GetEnvironmentStrings();\n    if (!envarea) {\n\tmap_errno(GetLastError());\n\treturn NULL;\n    }\n\n    for (env = envarea; *env; env += strlen(env) + 1)\n\tif (strncasecmp(env, name, len) == 0 && *(env + len) == '=')\n\t    return env + len + 1;\n\n    return NULL;\n}\n\nint\nrb_w32_rename(const char *oldpath, const char *newpath)\n{\n    int res = 0;\n    int oldatts;\n    int newatts;\n\n    oldatts = GetFileAttributes(oldpath);\n    newatts = GetFileAttributes(newpath);\n\n    if (oldatts == -1) {\n\terrno = map_errno(GetLastError());\n\treturn -1;\n    }\n\n    RUBY_CRITICAL({\n\tif (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)\n\t    SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);\n\n\tif (!MoveFile(oldpath, newpath))\n\t    res = -1;\n\n\tif (res) {\n\t    switch (GetLastError()) {\n\t      case ERROR_ALREADY_EXISTS:\n\t      case ERROR_FILE_EXISTS:\n\t\tif (IsWinNT()) {\n\t\t    if (MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))\n\t\t\tres = 0;\n\t\t} else {\n\t\t    for (;;) {\n\t\t\tif (!DeleteFile(newpath) && GetLastError() != ERROR_FILE_NOT_FOUND)\n\t\t\t    break;\n\t\t\telse if (MoveFile(oldpath, newpath)) {\n\t\t\t    res = 0;\n\t\t\t    break;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\tif (res)\n\t    errno = map_errno(GetLastError());\n\telse\n\t    SetFileAttributes(newpath, oldatts);\n    });\n\n    return res;\n}\n\nstatic int\nisUNCRoot(const char *path)\n{\n    if (path[0] == '\\\\' && path[1] == '\\\\') {\n\tconst char *p;\n\tfor (p = path + 2; *p; p = CharNext(p)) {\n\t    if (*p == '\\\\')\n\t\tbreak;\n\t}\n\tif (p[0] && p[1]) {\n\t    for (p++; *p; p = CharNext(p)) {\n\t\tif (*p == '\\\\')\n\t\t    break;\n\t    }\n\t    if (!p[0] || !p[1] || (p[1] == '.' && !p[2]))\n\t\treturn 1;\n\t}\n    }\n    return 0;\n}\n\nstatic time_t\nfiletime_to_unixtime(const FILETIME *ft)\n{\n    struct timeval tv;\n\n    if (filetime_to_timeval(ft, &tv) == (time_t)-1)\n\treturn 0;\n    else\n\treturn tv.tv_sec;\n}\n\nstatic unsigned\nfileattr_to_unixmode(DWORD attr, const char *path)\n{\n    unsigned mode = 0;\n\n    if (attr & FILE_ATTRIBUTE_READONLY) {\n\tmode |= S_IREAD;\n    }\n    else {\n\tmode |= S_IREAD | S_IWRITE | S_IWUSR;\n    }\n\n    if (attr & FILE_ATTRIBUTE_DIRECTORY) {\n\tmode |= S_IFDIR | S_IEXEC;\n    }\n    else {\n\tmode |= S_IFREG;\n    }\n\n    if (path && (mode & S_IFREG)) {\n\tconst char *end = path + strlen(path);\n\twhile (path < end) {\n\t    end = CharPrev(path, end);\n\t    if (*end == '.') {\n\t\tif ((strcmpi(end, \".bat\") == 0) ||\n\t\t    (strcmpi(end, \".cmd\") == 0) ||\n\t\t    (strcmpi(end, \".com\") == 0) ||\n\t\t    (strcmpi(end, \".exe\") == 0)) {\n\t\t    mode |= S_IEXEC;\n\t\t}\n\t\tbreak;\n\t    }\n\t}\n    }\n\n    mode |= (mode & 0700) >> 3;\n    mode |= (mode & 0700) >> 6;\n\n    return mode;\n}\n\nstatic int\ncheck_valid_dir(const char *path)\n{\n    WIN32_FIND_DATA fd;\n    HANDLE fh = open_dir_handle(path, &fd);\n    if (fh == INVALID_HANDLE_VALUE)\n\treturn -1;\n    FindClose(fh);\n    return 0;\n}\n\nstatic int\nwinnt_stat(const char *path, struct stat *st)\n{\n    HANDLE h;\n    WIN32_FIND_DATA wfd;\n\n    memset(st, 0, sizeof(struct stat));\n    st->st_nlink = 1;\n\n    if (_mbspbrk(path, \"?*\")) {\n\terrno = ENOENT;\n\treturn -1;\n    }\n    h = FindFirstFile(path, &wfd);\n    if (h != INVALID_HANDLE_VALUE) {\n\tFindClose(h);\n\tst->st_mode  = fileattr_to_unixmode(wfd.dwFileAttributes, path);\n\tst->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime);\n\tst->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime);\n\tst->st_ctime = filetime_to_unixtime(&wfd.ftCreationTime);\n\tst->st_size  = wfd.nFileSizeLow; /* TODO: 64bit support */\n    }\n    else {\n\t// If runtime stat(2) is called for network shares, it fails on WinNT.\n\t// Because GetDriveType returns 1 for network shares. (Win98 returns 4)\n\tDWORD attr = GetFileAttributes(path);\n\tif (attr == -1) {\n\t    errno = map_errno(GetLastError());\n\t    return -1;\n\t}\n\tif (attr & FILE_ATTRIBUTE_DIRECTORY) {\n\t    if (check_valid_dir(path)) return -1;\n\t}\n\tst->st_mode  = fileattr_to_unixmode(attr, path);\n    }\n\n    st->st_dev = st->st_rdev = (isalpha(path[0]) && path[1] == ':') ?\n\ttoupper(path[0]) - 'A' : _getdrive() - 1;\n\n    return 0;\n}\n\n#ifdef WIN95\nstatic int\nwin95_stat(const char *path, struct stat *st)\n{\n    int ret = stat(path, st);\n    if (ret) return ret;\n    if (st->st_mode & S_IFDIR) {\n\treturn check_valid_dir(path);\n    }\n    return 0;\n}\n#else\n#define win95_stat(path, st) -1\n#endif\n\nint\nrb_w32_stat(const char *path, struct stat *st)\n{\n    const char *p;\n    char *buf1, *s, *end;\n    int len;\n    int ret;\n\n    if (!path || !st) {\n\terrno = EFAULT;\n\treturn -1;\n    }\n    buf1 = ALLOCA_N(char, strlen(path) + 2);\n    for (p = path, s = buf1; *p; p++, s++) {\n\tif (*p == '/')\n\t    *s = '\\\\';\n\telse\n\t    *s = *p;\n    }\n    *s = '\\0';\n    len = s - buf1;\n    if (!len || '\\\"' == *(--s)) {\n\terrno = ENOENT;\n\treturn -1;\n    }\n    end = CharPrev(buf1, buf1 + len);\n\n    if (isUNCRoot(buf1)) {\n\tif (*end == '.')\n\t    *end = '\\0';\n\telse if (*end != '\\\\')\n\t    strcat(buf1, \"\\\\\");\n    } else if (*end == '\\\\' || (buf1 + 1 == end && *end == ':'))\n\tstrcat(buf1, \".\");\n\n    ret = IsWinNT() ? winnt_stat(buf1, st) : win95_stat(buf1, st);\n    if (ret == 0) {\n\tst->st_mode &= ~(S_IWGRP | S_IWOTH);\n    }\n    return ret;\n}\n\nstatic long\nfiletime_to_clock(FILETIME *ft)\n{\n    __int64 qw = ft->dwHighDateTime;\n    qw <<= 32;\n    qw |= ft->dwLowDateTime;\n    qw /= 10000;  /* File time ticks at 0.1uS, clock at 1mS */\n    return (long) qw;\n}\n\nint\nrb_w32_times(struct tms *tmbuf)\n{\n    FILETIME create, exit, kernel, user;\n\n    if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {\n\ttmbuf->tms_utime = filetime_to_clock(&user);\n\ttmbuf->tms_stime = filetime_to_clock(&kernel);\n\ttmbuf->tms_cutime = 0;\n\ttmbuf->tms_cstime = 0;\n    }\n    else {\n\ttmbuf->tms_utime = clock();\n\ttmbuf->tms_stime = 0;\n\ttmbuf->tms_cutime = 0;\n\ttmbuf->tms_cstime = 0;\n    }\n    return 0;\n}\n\n#define yield_once() Sleep(0)\n#define yield_until(condition) do yield_once(); while (!(condition))\n\nstatic DWORD\nwait_events(HANDLE event, DWORD timeout)\n{\n    HANDLE events[2];\n    int count = 0;\n    DWORD ret;\n\n    if (event) {\n\tevents[count++] = event;\n    }\n    events[count++] = interrupted_event;\n\n    ret = WaitForMultipleEvents(count, events, FALSE, timeout, TRUE);\n\n    if (ret == WAIT_OBJECT_0 + count - 1) {\n\tResetSignal(interrupted_event);\n\terrno = EINTR;\n    }\n\n    return ret;\n}\n\nstatic CRITICAL_SECTION *\nsystem_state(void)\n{\n    static int initialized = 0;\n    static CRITICAL_SECTION syssect;\n\n    if (!initialized) {\n\tInitializeCriticalSection(&syssect);\n\tinitialized = 1;\n    }\n    return &syssect;\n}\n\nstatic LONG flag_interrupt = -1;\nstatic volatile DWORD tlsi_interrupt = TLS_OUT_OF_INDEXES;\n\nvoid\nrb_w32_enter_critical(void)\n{\n    if (IsWinNT()) {\n\tEnterCriticalSection(system_state());\n\treturn;\n    }\n\n    if (tlsi_interrupt == TLS_OUT_OF_INDEXES) {\n\ttlsi_interrupt = TlsAlloc();\n    }\n\n    {\n\tDWORD ti = (DWORD)TlsGetValue(tlsi_interrupt);\n\twhile (InterlockedIncrement(&flag_interrupt) > 0 && !ti) {\n\t    InterlockedDecrement(&flag_interrupt);\n\t    Sleep(1);\n\t}\n\tTlsSetValue(tlsi_interrupt, (PVOID)++ti);\n    }\n}\n\nvoid\nrb_w32_leave_critical(void)\n{\n    if (IsWinNT()) {\n\tLeaveCriticalSection(system_state());\n\treturn;\n    }\n\n    InterlockedDecrement(&flag_interrupt);\n    TlsSetValue(tlsi_interrupt, (PVOID)((DWORD)TlsGetValue(tlsi_interrupt) - 1));\n}\n\nstruct handler_arg_t {\n    void (*handler)(int);\n    int arg;\n    int status;\n    int finished;\n    HANDLE handshake;\n};\n\nstatic void\nrb_w32_call_handler(struct handler_arg_t* h)\n{\n    int status;\n    RUBY_CRITICAL(rb_protect((VALUE (*)(VALUE))h->handler, (VALUE)h->arg, &h->status);\n\t\t  status = h->status;\n\t\t  SetEvent(h->handshake));\n    if (status) {\n\trb_jump_tag(status);\n    }\n    h->finished = 1;\n    yield_until(0);\n}\n\nstatic struct handler_arg_t *\nsetup_handler(struct handler_arg_t *harg, int arg, void (*handler)(int),\n\t      HANDLE handshake)\n{\n    harg->handler = handler;\n    harg->arg = arg;\n    harg->status = 0;\n    harg->finished = 0;\n    harg->handshake = handshake;\n    return harg;\n}\n\nstatic void\nsetup_call(CONTEXT* ctx, struct handler_arg_t *harg)\n{\n#ifdef _M_IX86\n    DWORD *esp = (DWORD *)ctx->Esp;\n    *--esp = (DWORD)harg;\n    *--esp = ctx->Eip;\n    ctx->Esp = (DWORD)esp;\n    ctx->Eip = (DWORD)rb_w32_call_handler;\n#else\n#ifndef _WIN32_WCE\n#error unsupported processor\n#endif\n#endif\n}\n\nvoid\nrb_w32_interrupted(void)\n{\n    SetSignal(interrupted_event);\n}\n\nint\nrb_w32_main_context(int arg, void (*handler)(int))\n{\n    static HANDLE interrupt_done = NULL;\n    struct handler_arg_t harg;\n    CONTEXT ctx_orig;\n    HANDLE current_thread = GetCurrentThread();\n    int old_priority = GetThreadPriority(current_thread);\n\n    if (GetCurrentThreadId() == main_thread.id) return FALSE;\n\n    rb_w32_interrupted();\n\n    RUBY_CRITICAL({\t\t/* the main thread must be in user state */\n\tCONTEXT ctx;\n\n\tSuspendThread(main_thread.handle);\n\tSetThreadPriority(current_thread, GetThreadPriority(main_thread.handle));\n\n\tZeroMemory(&ctx, sizeof(CONTEXT));\n\tctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;\n\tGetThreadContext(main_thread.handle, &ctx);\n\tctx_orig = ctx;\n\n\t/* handler context setup */\n\tif (!interrupt_done) {\n\t    interrupt_done = CreateEvent(NULL, FALSE, FALSE, NULL);\n\t    /* anonymous one-shot event */\n\t}\n\telse {\n\t    ResetEvent(interrupt_done);\n\t}\n\tsetup_call(&ctx, setup_handler(&harg, arg, handler, interrupt_done));\n\n\tctx.ContextFlags = CONTEXT_CONTROL;\n\tSetThreadContext(main_thread.handle, &ctx);\n\tResumeThread(main_thread.handle);\n    });\n\n    /* give a chance to the main thread */\n    yield_once();\n    WaitForSingleObject(interrupt_done, INFINITE); /* handshaking */\n\n    if (!harg.status) {\n\t/* no exceptions raised, restore old context. */\n\tRUBY_CRITICAL({\n\t    /* ensure the main thread is in user state. */\n\t    yield_until(harg.finished);\n\n\t    SuspendThread(main_thread.handle);\n\t    ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;\n\t    SetThreadContext(main_thread.handle, &ctx_orig);\n\t    ResumeThread(main_thread.handle);\n\t});\n    }\n    /* otherwise leave the main thread raised */\n\n    SetThreadPriority(current_thread, old_priority);\n\n    return TRUE;\n}\n\nint\nrb_w32_sleep(unsigned long msec)\n{\n    DWORD ret;\n    RUBY_CRITICAL(ret = wait_events(NULL, msec));\n    yield_once();\n    CHECK_INTS;\n    return ret != WAIT_TIMEOUT;\n}\n\nstatic void\ncatch_interrupt(void)\n{\n    yield_once();\n    RUBY_CRITICAL(wait_events(NULL, 0));\n    CHECK_INTS;\n}\n\n#undef fgetc\nint\nrb_w32_getc(FILE* stream)\n{\n    int c, trap_immediate = rb_trap_immediate;\n#ifndef _WIN32_WCE\n    if (enough_to_get(stream->FILE_COUNT)) {\n\tc = (unsigned char)*stream->FILE_READPTR++;\n\trb_trap_immediate = trap_immediate;\n    }\n    else \n#endif\n    {\n\tc = _filbuf(stream);\n#if defined __BORLANDC__ || defined _WIN32_WCE\n        if ((c == EOF) && (errno == EPIPE)) {\n\t    clearerr(stream);\n        }\n#endif\n\trb_trap_immediate = trap_immediate;\n\tcatch_interrupt();\n    }\n    return c;\n}\n\n#undef fputc\nint\nrb_w32_putc(int c, FILE* stream)\n{\n    int trap_immediate = rb_trap_immediate;\n#ifndef _WIN32_WCE\n    if (enough_to_put(stream->FILE_COUNT)) {\n\tc = (unsigned char)(*stream->FILE_READPTR++ = (char)c);\n\trb_trap_immediate = trap_immediate;\n    }\n    else \n#endif\n    {\n\tc = _flsbuf(c, stream);\n\trb_trap_immediate = trap_immediate;\n\tcatch_interrupt();\n    }\n    return c;\n}\n\nstruct asynchronous_arg_t {\n    /* output field */\n    void* stackaddr;\n    int errnum;\n\n    /* input field */\n    VALUE (*func)(VALUE self, int argc, VALUE* argv);\n    VALUE self;\n    int argc;\n    VALUE* argv;\n};\n\nstatic DWORD WINAPI\ncall_asynchronous(PVOID argp)\n{\n    DWORD ret;\n    struct asynchronous_arg_t *arg = argp;\n    arg->stackaddr = &argp;\n    ret = (DWORD)arg->func(arg->self, arg->argc, arg->argv);\n    arg->errnum = errno;\n    return ret;\n}\n\nVALUE\nrb_w32_asynchronize(asynchronous_func_t func, VALUE self,\n\t\t    int argc, VALUE* argv, VALUE intrval)\n{\n    DWORD val;\n    BOOL interrupted = FALSE;\n    HANDLE thr;\n\n    RUBY_CRITICAL({\n\tstruct asynchronous_arg_t arg;\n\n\targ.stackaddr = NULL;\n\targ.errnum = 0;\n\targ.func = func;\n\targ.self = self;\n\targ.argc = argc;\n\targ.argv = argv;\n\n\tthr = CreateThread(NULL, 0, call_asynchronous, &arg, 0, &val);\n\n\tif (thr) {\n\t    yield_until(arg.stackaddr);\n\n\t    if (wait_events(thr, INFINITE) != WAIT_OBJECT_0) {\n\t\tinterrupted = TRUE;\n\n\t\tif (TerminateThread(thr, intrval)) {\n\t\t    yield_once();\n\t\t}\n\t    }\n\n\t    GetExitCodeThread(thr, &val);\n\t    CloseHandle(thr);\n\n\t    if (interrupted) {\n\t\t/* must release stack of killed thread, why doesn't Windows? */\n\t\tMEMORY_BASIC_INFORMATION m;\n\n\t\tmemset(&m, 0, sizeof(m));\n\t\tif (!VirtualQuery(arg.stackaddr, &m, sizeof(m))) {\n\t\t    Debug(fprintf(stderr, \"couldn't get stack base:%p:%d\\n\",\n\t\t\t\t  arg.stackaddr, GetLastError()));\n\t\t}\n\t\telse if (!VirtualFree(m.AllocationBase, 0, MEM_RELEASE)) {\n\t\t    Debug(fprintf(stderr, \"couldn't release stack:%p:%d\\n\",\n\t\t\t\t  m.AllocationBase, GetLastError()));\n\t\t}\n\t\terrno = EINTR;\n\t    }\n\t    else {\n\t\terrno = arg.errnum;\n\t    }\n\t}\n    });\n\n    if (!thr) {\n\trb_fatal(\"failed to launch waiter thread:%d\", GetLastError());\n    }\n\n    if (interrupted) {\n\tCHECK_INTS;\n    }\n\n    return val;\n}\n\nchar **\nrb_w32_get_environ(void)\n{\n    char *envtop, *env;\n    char **myenvtop, **myenv;\n    int num;\n\n    /*\n     * We avoid values started with `='. If you want to deal those values,\n     * change this function, and some functions in hash.c which recognize\n     * `=' as delimiter or rb_w32_getenv() and ruby_setenv().\n     * CygWin deals these values by changing first `=' to '!'. But we don't\n     * use such trick and follow cmd.exe's way that just doesn't show these\n     * values.\n     * (U.N. 2001-11-15)\n     */\n    envtop = GetEnvironmentStrings();\n    for (env = envtop, num = 0; *env; env += strlen(env) + 1)\n\tif (*env != '=') num++;\n\n    myenvtop = (char **)malloc(sizeof(char *) * (num + 1));\n    for (env = envtop, myenv = myenvtop; *env; env += strlen(env) + 1) {\n\tif (*env != '=') {\n\t    if (!(*myenv = (char *)malloc(strlen(env) + 1))) {\n\t\tbreak;\n\t    }\n\t    strcpy(*myenv, env);\n\t    myenv++;\n\t}\n    }\n    *myenv = NULL;\n    FreeEnvironmentStrings(envtop);\n\n    return myenvtop;\n}\n\nvoid\nrb_w32_free_environ(char **env)\n{\n    char **t = env;\n\n    while (*t) free(*t++);\n    free(env);\n}\n\n#undef getpid\nrb_pid_t\nrb_w32_getpid(void)\n{\n    rb_pid_t pid;\n\n    pid = getpid();\n\n    if (IsWin95()) pid = -pid;\n\n    return pid;\n}\n\nint\nrb_w32_fclose(FILE *fp)\n{\n    int fd = fileno(fp);\n    SOCKET sock = TO_SOCKET(fd);\n    int save_errno = errno;\n\n    if (fflush(fp)) return -1;\n    if (!is_socket(sock)) {\n\tUnlockFile((HANDLE)sock, 0, 0, LK_LEN, LK_LEN);\n\treturn fclose(fp);\n    }\n    _set_osfhnd(fd, (SOCKET)INVALID_HANDLE_VALUE);\n    fclose(fp);\n    errno = save_errno;\n    if (closesocket(sock) == SOCKET_ERROR) {\n\terrno = map_errno(WSAGetLastError());\n\treturn -1;\n    }\n    return 0;\n}\n\nint\nrb_w32_close(int fd)\n{\n    SOCKET sock = TO_SOCKET(fd);\n    int save_errno = errno;\n\n    if (!is_socket(sock)) {\n\tUnlockFile((HANDLE)sock, 0, 0, LK_LEN, LK_LEN);\n\treturn _close(fd);\n    }\n    _set_osfhnd(fd, (SOCKET)INVALID_HANDLE_VALUE);\n    _close(fd);\n    errno = save_errno;\n    if (closesocket(sock) == SOCKET_ERROR) {\n\terrno = map_errno(WSAGetLastError());\n\treturn -1;\n    }\n    return 0;\n}\n\n#undef read\nsize_t\nrb_w32_read(int fd, void *buf, size_t size)\n{\n    SOCKET sock = TO_SOCKET(fd);\n\n    if (!is_socket(sock))\n\treturn read(fd, buf, size);\n    else\n\treturn rb_w32_recv(fd, buf, size, 0);\n}\n\n#undef write\nsize_t\nrb_w32_write(int fd, const void *buf, size_t size)\n{\n    SOCKET sock = TO_SOCKET(fd);\n\n    if (!is_socket(sock))\n\treturn write(fd, buf, size);\n    else\n\treturn rb_w32_send(fd, buf, size, 0);\n}\n\nstatic int\nunixtime_to_filetime(time_t time, FILETIME *ft)\n{\n    struct tm *tm;\n    SYSTEMTIME st;\n    FILETIME lt;\n\n    tm = localtime(&time);\n    st.wYear = tm->tm_year + 1900;\n    st.wMonth = tm->tm_mon + 1;\n    st.wDayOfWeek = tm->tm_wday;\n    st.wDay = tm->tm_mday;\n    st.wHour = tm->tm_hour;\n    st.wMinute = tm->tm_min;\n    st.wSecond = tm->tm_sec;\n    st.wMilliseconds = 0;\n    if (!SystemTimeToFileTime(&st, &lt) ||\n\t!LocalFileTimeToFileTime(&lt, ft)) {\n\terrno = map_errno(GetLastError());\n\treturn -1;\n    }\n    return 0;\n}\n\nint\nrb_w32_utime(const char *path, struct utimbuf *times)\n{\n    HANDLE hFile;\n    FILETIME atime, mtime;\n    struct stat stat;\n    int ret = 0;\n\n    if (rb_w32_stat(path, &stat)) {\n\treturn -1;\n    }\n\n    if (times) {\n\tif (unixtime_to_filetime(times->actime, &atime)) {\n\t    return -1;\n\t}\n\tif (unixtime_to_filetime(times->modtime, &mtime)) {\n\t    return -1;\n\t}\n    }\n    else {\n\tGetSystemTimeAsFileTime(&atime);\n\tmtime = atime;\n    }\n\n    RUBY_CRITICAL({\n\tconst DWORD attr = GetFileAttributes(path);\n\tif (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY))\n\t    SetFileAttributes(path, attr & ~FILE_ATTRIBUTE_READONLY);\n\thFile = CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING,\n\t\t\t   IsWin95() ? 0 : FILE_FLAG_BACKUP_SEMANTICS, 0);\n\tif (hFile == INVALID_HANDLE_VALUE) {\n\t    errno = map_errno(GetLastError());\n\t    ret = -1;\n\t}\n\telse {\n\t    if (!SetFileTime(hFile, NULL, &atime, &mtime)) {\n\t\terrno = map_errno(GetLastError());\n\t\tret = -1;\n\t    }\n\t    CloseHandle(hFile);\n\t}\n\tif (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY))\n\t    SetFileAttributes(path, attr);\n    });\n\n    return ret;\n}\n\nint\nrb_w32_vsnprintf(char *buf, size_t size, const char *format, va_list va)\n{\n    int ret = _vsnprintf(buf, size, format, va);\n    if (size > 0) buf[size - 1] = 0;\n    return ret;\n}\n\nint\nrb_w32_snprintf(char *buf, size_t size, const char *format, ...)\n{\n    int ret;\n    va_list va;\n\n    va_start(va, format);\n    ret = vsnprintf(buf, size, format, va);\n    va_end(va);\n    return ret;\n}\n\nint\nrb_w32_mkdir(const char *path, int mode)\n{\n    int ret = -1;\n    RUBY_CRITICAL(do {\n\tif (CreateDirectory(path, NULL) == FALSE) {\n\t    errno = map_errno(GetLastError());\n\t    break;\n\t}\n\tif (chmod(path, mode) == -1) {\n\t    RemoveDirectory(path);\n\t    break;\n\t}\n\tret = 0;\n    } while (0));\n    return ret;\n}\n\nint\nrb_w32_rmdir(const char *path)\n{\n    int ret = 0;\n    RUBY_CRITICAL({\n\tconst DWORD attr = GetFileAttributes(path);\n\tif (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {\n\t    SetFileAttributes(path, attr & ~FILE_ATTRIBUTE_READONLY);\n\t}\n\tif (RemoveDirectory(path) == FALSE) {\n\t    errno = map_errno(GetLastError());\n\t    ret = -1;\n\t    if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {\n\t\tSetFileAttributes(path, attr);\n\t    }\n\t}\n    });\n    return ret;\n}\n\nint\nrb_w32_unlink(const char *path)\n{\n    int ret = 0;\n    RUBY_CRITICAL({\n\tconst DWORD attr = GetFileAttributes(path);\n\tif (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {\n\t    SetFileAttributes(path, attr & ~FILE_ATTRIBUTE_READONLY);\n\t}\n\tif (DeleteFile(path) == FALSE) {\n\t    errno = map_errno(GetLastError());\n\t    ret = -1;\n\t    if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {\n\t\tSetFileAttributes(path, attr);\n\t    }\n\t}\n    });\n    return ret;\n}\n\n#if !defined(__BORLANDC__) && !defined(_WIN32_WCE)\nint\nrb_w32_isatty(int fd)\n{\n    // validate fd by using _get_osfhandle() because we cannot access _nhandle\n    if (_get_osfhandle(fd) == -1) {\n\treturn 0;\n    }\n    if (!(_osfile(fd) & FOPEN)) {\n\terrno = EBADF;\n\treturn 0;\n    }\n    if (!(_osfile(fd) & FDEV)) {\n\terrno = ENOTTY;\n\treturn 0;\n    }\n    return 1;\n}\n#endif\n\n//\n// Fix bcc32's stdio bug\n//\n\n#ifdef __BORLANDC__\nstatic int\ntoo_many_files()\n{\n    FILE *f;\n    for (f = _streams; f < _streams + _nfile; f++) {\n\tif (f->fd < 0) return 0;\n    }\n    return 1;\n}\n\n#undef fopen\nFILE *\nrb_w32_fopen(const char *path, const char *mode)\n{\n    FILE *f = (errno = 0, fopen(path, mode));\n    if (f == NULL && errno == 0) {\n\tif (too_many_files())\n\t    errno = EMFILE;\n    }\n    return f;\n}\n\nFILE *\nrb_w32_fdopen(int handle, const char *type)\n{\n    FILE *f = (errno = 0, _fdopen(handle, (char *)type));\n    if (f == NULL && errno == 0) {\n\tif (handle < 0)\n\t    errno = EBADF;\n\telse if (too_many_files())\n\t    errno = EMFILE;\n    }\n    return f;\n}\n\nFILE *\nrb_w32_fsopen(const char *path, const char *mode, int shflags)\n{\n    FILE *f = (errno = 0, _fsopen(path, mode, shflags));\n    if (f == NULL && errno == 0) {\n\tif (too_many_files())\n\t    errno = EMFILE;\n    }\n    return f;\n}\n#endif\n\nRUBY_EXTERN int __cdecl _CrtDbgReportW() {return 0;}\n"
  },
  {
    "path": "win32/win32.h",
    "content": "#ifndef RUBY_WIN32_H\n#define RUBY_WIN32_H\n\n/*\n *  Copyright (c) 1993, Intergraph Corporation\n *\n *  You may distribute under the terms of either the GNU General Public\n *  License or the Artistic License, as specified in the perl README file.\n *\n */\n\n//\n// Definitions for NT port of Perl\n//\n\n\n//\n// Ok now we can include the normal include files.\n//\n\n// #include <stdarg.h> conflict with varargs.h?\n#if !defined(IN) && !defined(FLOAT)\n#ifdef __BORLANDC__\n#define USE_WINSOCK2\n#endif\n#ifdef USE_WINSOCK2\n#include <winsock2.h>\n#include <ws2tcpip.h>\n#include <windows.h>\n#else\n#include <windows.h>\n#include <winsock.h>\n#endif\n#endif\n\n#define NT 1\t\t\t/* deprecated */\n\n#ifdef _WIN32_WCE\n#undef CharNext\n#define CharNext CharNextA\n#endif\n\n//\n// We're not using Microsoft's \"extensions\" to C for\n// Structured Exception Handling (SEH) so we can nuke these\n//\n#undef try\n#undef except\n#undef finally\n#undef leave\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <direct.h>\n#include <process.h>\n#include <time.h>\n#if defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER == 1200\nextern \"C++\" {\t\t\t/* template without extern \"C++\" */\n#endif\n#include <math.h>\n#if defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER == 1200\n}\n#endif\n#include <signal.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#if !defined(__BORLANDC__)\n# include <sys/utime.h>\n#else\n# include <utime.h>\n#endif\n#include <io.h>\n#include <malloc.h>\n\n#ifdef _M_IX86\n# define WIN95 1\n#else\n# undef  WIN95\n#endif\n\n#ifdef WIN95\nextern DWORD rb_w32_osid(void);\n#define rb_w32_iswinnt()  (rb_w32_osid() == VER_PLATFORM_WIN32_NT)\n#define rb_w32_iswin95()  (rb_w32_osid() == VER_PLATFORM_WIN32_WINDOWS)\n#else\n#define rb_w32_iswinnt()  TRUE\n#define rb_w32_iswin95()  FALSE\n#endif\n\n#define WNOHANG -1\n\n#undef getc\n#undef putc\n#undef fgetc\n#undef fputc\n#undef getchar\n#undef putchar\n#undef fgetchar\n#undef fputchar\n#undef utime\n#define getc(_stream)\t\trb_w32_getc(_stream)\n#define putc(_c, _stream)\trb_w32_putc(_c, _stream)\n#define fgetc(_stream)\t\tgetc(_stream)\n#define fputc(_c, _stream)\tputc(_c, _stream)\n#define getchar()\t\trb_w32_getc(stdin)\n#define putchar(_c)\t\trb_w32_putc(_c, stdout)\n#define fgetchar()\t\tgetchar()\n#define fputchar(_c)\t\tputchar(_c)\n#define utime(_p, _t)\t\trb_w32_utime(_p, _t)\n\n#define strcasecmp(s1, s2)\tstricmp(s1, s2)\n#define strncasecmp(s1, s2, n)\tstrnicmp(s1, s2, n)\n\n#define close(h)\t\trb_w32_close(h)\n#define fclose(f)\t\trb_w32_fclose(f)\n#define read(f, b, s)\t\trb_w32_read(f, b, s)\n#define write(f, b, s)\t\trb_w32_write(f, b, s)\n#define getpid()\t\trb_w32_getpid()\n#define sleep(x)\t\trb_w32_sleep((x)*1000)\n#ifdef __BORLANDC__\n#define creat(p, m)\t\t_creat(p, m)\n#define eof()\t\t\t_eof()\n#define filelength(h)\t\t_filelength(h)\n#define mktemp(t)\t\t_mktemp(t)\n#define tell(h)\t\t\t_tell(h)\n#define unlink(p)\t\t_unlink(p)\n#define _open\t\t\t_sopen\n#define sopen\t\t\t_sopen\n#undef fopen\n#define fopen(p, m)\t\trb_w32_fopen(p, m)\n#undef fdopen\n#define fdopen(h, m)\t\trb_w32_fdopen(h, m)\n#undef fsopen\n#define fsopen(p, m, sh)\trb_w32_fsopen(p, m, sh)\n#endif\n#define fsync(h)\t\t_commit(h)\n#undef stat\n#define stat(path,st)\t\trb_w32_stat(path,st)\n#undef execv\n#define execv(path,argv)\tdo_aspawn(P_OVERLAY,path,argv)\n#if !defined(__BORLANDC__) && !defined(_WIN32_WCE)\n#undef isatty\n#define isatty(h)\t\trb_w32_isatty(h)\n#endif\n#undef mkdir\n#define mkdir(p, m)\t\trb_w32_mkdir(p, m)\n#undef rmdir\n#define rmdir(p)\t\trb_w32_rmdir(p)\n#undef unlink\n#define unlink(p)\t\trb_w32_unlink(p)\n\n#ifdef __MINGW32__\nstruct timezone {\n  int tz_minuteswest;\n  int tz_dsttime;\n};\n#undef isascii\n#define isascii __isascii\n#endif\nextern void   NtInitialize(int *, char ***);\nextern int    rb_w32_cmdvector(const char *, char ***);\nextern rb_pid_t pipe_exec(const char *, int, FILE **, FILE **);\nextern int    flock(int fd, int oper);\nextern int    rb_w32_accept(int, struct sockaddr *, int *);\nextern int    rb_w32_bind(int, struct sockaddr *, int);\nextern int    rb_w32_connect(int, struct sockaddr *, int);\nextern void   rb_w32_fdset(int, fd_set*);\nextern void   rb_w32_fdclr(int, fd_set*);\nextern int    rb_w32_fdisset(int, fd_set*);\nextern long   rb_w32_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);\nextern int    rb_w32_getpeername(int, struct sockaddr *, int *);\nextern int    rb_w32_getsockname(int, struct sockaddr *, int *);\nextern int    rb_w32_getsockopt(int, int, int, char *, int *);\nextern int    rb_w32_ioctlsocket(int, long, u_long *);\nextern int    rb_w32_listen(int, int);\nextern int    rb_w32_recv(int, char *, int, int);\nextern int    rb_w32_recvfrom(int, char *, int, int, struct sockaddr *, int *);\nextern int    rb_w32_send(int, const char *, int, int);\nextern int    rb_w32_sendto(int, const char *, int, int, struct sockaddr *, int);\nextern int    rb_w32_setsockopt(int, int, int, char *, int);\nextern int    rb_w32_shutdown(int, int);\nextern int    rb_w32_socket(int, int, int);\nextern SOCKET rb_w32_get_osfhandle(int);\nextern struct hostent * rb_w32_gethostbyaddr(char *, int, int);\nextern struct hostent * rb_w32_gethostbyname(char *);\nextern int    rb_w32_gethostname(char *, int);\nextern struct protoent * rb_w32_getprotobyname(char *);\nextern struct protoent * rb_w32_getprotobynumber(int);\nextern struct servent  * rb_w32_getservbyname(char *, char *);\nextern struct servent  * rb_w32_getservbyport(int, char *);\nextern char * rb_w32_getcwd(char *, int);\nextern char * rb_w32_getenv(const char *);\nextern int    rb_w32_rename(const char *, const char *);\nextern int    rb_w32_stat(const char *, struct stat *);\nextern char **rb_w32_get_environ(void);\nextern void   rb_w32_free_environ(char **);\nextern int    rb_w32_map_errno(DWORD);\n\n#define vsnprintf(s,n,f,l) rb_w32_vsnprintf(s,n,f,l)\n#define snprintf   rb_w32_snprintf\nextern int rb_w32_vsnprintf(char *, size_t, const char *, va_list);\nextern int rb_w32_snprintf(char *, size_t, const char *, ...);\n\nextern int chown(const char *, int, int);\nextern int link(char *, char *);\nextern int gettimeofday(struct timeval *, struct timezone *);\nextern rb_pid_t waitpid (rb_pid_t, int *, int);\nextern int do_spawn(int, const char *);\nextern int do_aspawn(int, const char *, char **);\nextern int kill(int, int);\nextern int fcntl(int, int, ...);\nextern rb_pid_t rb_w32_getpid(void);\n\n#if !defined(__BORLANDC__) && !defined(_WIN32_WCE)\nextern int rb_w32_isatty(int);\n#endif\nextern int rb_w32_mkdir(const char *, int);\nextern int rb_w32_rmdir(const char *);\nextern int rb_w32_unlink(const char*);\n\n#ifdef __BORLANDC__\nextern FILE *rb_w32_fopen(const char *, const char *);\nextern FILE *rb_w32_fdopen(int, const char *);\nextern FILE *rb_w32_fsopen(const char *, const char *, int);\n#endif\n\n#include <float.h>\n#if !defined __MINGW32__ || defined __NO_ISOCEXT\n#ifndef isnan\n#define isnan(x) _isnan(x)\n#endif\n#ifndef finite\n#define finite(x) _finite(x)\n#endif\n#ifndef copysign\n#define copysign(a, b) _copysign(a, b)\n#endif\n#ifndef scalb\n#define scalb(a, b) _scalb(a, b)\n#endif\n#endif\n\n#if !defined S_IFIFO && defined _S_IFIFO\n#define S_IFIFO _S_IFIFO\n#endif\n\n#ifdef __BORLANDC__\n#undef S_ISDIR\n#undef S_ISFIFO\n#undef S_ISBLK\n#undef S_ISCHR\n#undef S_ISREG\n#define S_ISDIR(m)  (((unsigned short)(m) & S_IFMT) == S_IFDIR)\n#define S_ISFIFO(m) (((unsigned short)(m) & S_IFMT) == S_IFIFO)\n#define S_ISBLK(m)  (((unsigned short)(m) & S_IFMT) == S_IFBLK)\n#define S_ISCHR(m)  (((unsigned short)(m) & S_IFMT) == S_IFCHR)\n#define S_ISREG(m)  (((unsigned short)(m) & S_IFMT) == S_IFREG)\n#endif\n\n#if !defined S_IRUSR && !defined __MINGW32__\n#define S_IRUSR 0400\n#endif\n#ifndef S_IRGRP\n#define S_IRGRP 0040\n#endif\n#ifndef S_IROTH\n#define S_IROTH 0004\n#endif\n\n#if !defined S_IWUSR && !defined __MINGW32__\n#define S_IWUSR 0200\n#endif\n#ifndef S_IWGRP\n#define S_IWGRP 0020\n#endif\n#ifndef S_IWOTH\n#define S_IWOTH 0002\n#endif\n\n#if !defined S_IXUSR && !defined __MINGW32__\n#define S_IXUSR 0100\n#endif\n#ifndef S_IXGRP\n#define S_IXGRP 0010\n#endif\n#ifndef S_IXOTH\n#define S_IXOTH 0001\n#endif\n\n//\n// define this so we can do inplace editing\n//\n\n#define SUFFIX\n\n//\n// stubs\n//\n#if !defined(__BORLANDC__)\nextern int       ioctl (int, unsigned int, long);\n#endif\nextern rb_uid_t  getuid (void);\nextern rb_uid_t  geteuid (void);\nextern rb_gid_t  getgid (void);\nextern rb_gid_t  getegid (void);\nextern int       setuid (rb_uid_t);\nextern int       setgid (rb_gid_t);\n\nextern char *rb_w32_strerror(int);\n\n#define strerror(e) rb_w32_strerror(e)\n\n#define PIPE_BUF 1024\n\n#define LOCK_SH 1\n#define LOCK_EX 2\n#define LOCK_NB 4\n#define LOCK_UN 8\n\n\n#ifndef SIGINT\n#define SIGINT 2\n#endif\n#ifndef SIGKILL\n#define SIGKILL\t9\n#endif\n\n\n/* #undef va_start */\n/* #undef va_end */\n\n/* winsock error map */\n#define EWOULDBLOCK\tWSAEWOULDBLOCK\n#define EINPROGRESS\tWSAEINPROGRESS\n#define EALREADY\tWSAEALREADY\n#define ENOTSOCK\tWSAENOTSOCK\n#define EDESTADDRREQ\tWSAEDESTADDRREQ\n#define EMSGSIZE\tWSAEMSGSIZE\n#define EPROTOTYPE\tWSAEPROTOTYPE\n#define ENOPROTOOPT\tWSAENOPROTOOPT\n#define EPROTONOSUPPORT\tWSAEPROTONOSUPPORT\n#define ESOCKTNOSUPPORT\tWSAESOCKTNOSUPPORT\n#define EOPNOTSUPP\tWSAEOPNOTSUPP\n#define EPFNOSUPPORT\tWSAEPFNOSUPPORT\n#define EAFNOSUPPORT\tWSAEAFNOSUPPORT\n#define EADDRINUSE\tWSAEADDRINUSE\n#define EADDRNOTAVAIL\tWSAEADDRNOTAVAIL\n#define ENETDOWN\tWSAENETDOWN\n#define ENETUNREACH\tWSAENETUNREACH\n#define ENETRESET\tWSAENETRESET\n#define ECONNABORTED\tWSAECONNABORTED\n#define ECONNRESET\tWSAECONNRESET\n#define ENOBUFS\t\tWSAENOBUFS\n#define EISCONN\t\tWSAEISCONN\n#define ENOTCONN\tWSAENOTCONN\n#define ESHUTDOWN\tWSAESHUTDOWN\n#define ETOOMANYREFS\tWSAETOOMANYREFS\n#define ETIMEDOUT\tWSAETIMEDOUT\n#define ECONNREFUSED\tWSAECONNREFUSED\n#define ELOOP\t\tWSAELOOP\n/*#define ENAMETOOLONG\tWSAENAMETOOLONG*/\n#define EHOSTDOWN\tWSAEHOSTDOWN\n#define EHOSTUNREACH\tWSAEHOSTUNREACH\n/*#define ENOTEMPTY\tWSAENOTEMPTY*/\n#define EPROCLIM\tWSAEPROCLIM\n#define EUSERS\t\tWSAEUSERS\n#define EDQUOT\t\tWSAEDQUOT\n#define ESTALE\t\tWSAESTALE\n#define EREMOTE\t\tWSAEREMOTE\n\n#define F_SETFL 1\n#define O_NONBLOCK 1\n\n#ifdef accept\n#undef accept\n#endif\n#define accept(s, a, l)\t\trb_w32_accept(s, a, l)\n\n#ifdef bind\n#undef bind\n#endif\n#define bind(s, a, l)\t\trb_w32_bind(s, a, l)\n\n#ifdef connect\n#undef connect\n#endif\n#define connect(s, a, l)\trb_w32_connect(s, a, l)\n\n#undef FD_SET\n#define FD_SET(f, s)\t\trb_w32_fdset(f, s)\n\n#undef FD_CLR\n#define FD_CLR(f, s)\t\trb_w32_fdclr(f, s)\n\n#undef FD_ISSET\n#define FD_ISSET(f, s)\t\trb_w32_fdisset(f, s)\n\n#undef select\n#define select(n, r, w, e, t)\trb_w32_select(n, r, w, e, t)\n\n#ifdef getpeername\n#undef getpeername\n#endif\n#define getpeername(s, a, l)\trb_w32_getpeername(s, a, l)\n\n#ifdef getsockname\n#undef getsockname\n#endif\n#define getsockname(s, a, l)\trb_w32_getsockname(s, a, l)\n\n#ifdef getsockopt\n#undef getsockopt\n#endif\n#define getsockopt(s, v, n, o, l) rb_w32_getsockopt(s, v, n, o, l)\n\n#ifdef ioctlsocket\n#undef ioctlsocket\n#endif\n#define ioctlsocket(s, c, a)\trb_w32_ioctlsocket(s, c, a)\n\n#ifdef listen\n#undef listen\n#endif\n#define listen(s, b)\t\trb_w32_listen(s, b)\n\n#ifdef recv\n#undef recv\n#endif\n#define recv(s, b, l, f)\trb_w32_recv(s, b, l, f)\n\n#ifdef recvfrom\n#undef recvfrom\n#endif\n#define recvfrom(s, b, l, f, fr, frl) rb_w32_recvfrom(s, b, l, f, fr, frl)\n\n#ifdef send\n#undef send\n#endif\n#define send(s, b, l, f)\trb_w32_send(s, b, l, f)\n\n#ifdef sendto\n#undef sendto\n#endif\n#define sendto(s, b, l, f, t, tl) rb_w32_sendto(s, b, l, f, t, tl)\n\n#ifdef setsockopt\n#undef setsockopt\n#endif\n#define setsockopt(s, v, n, o, l) rb_w32_setsockopt(s, v, n, o, l)\n\n#ifdef shutdown\n#undef shutdown\n#endif\n#define shutdown(s, h)\t\trb_w32_shutdown(s, h)\n\n#ifdef socket\n#undef socket\n#endif\n#define socket(s, t, p)\t\trb_w32_socket(s, t, p)\n\n#ifdef gethostbyaddr\n#undef gethostbyaddr\n#endif\n#define gethostbyaddr(a, l, t)\trb_w32_gethostbyaddr(a, l, t)\n\n#ifdef gethostbyname\n#undef gethostbyname\n#endif\n#define gethostbyname(n)\trb_w32_gethostbyname(n)\n\n#ifdef gethostname\n#undef gethostname\n#endif\n#define gethostname(n, l)\trb_w32_gethostname(n, l)\n\n#ifdef getprotobyname\n#undef getprotobyname\n#endif\n#define getprotobyname(n)\trb_w32_getprotobyname(n)\n\n#ifdef getprotobynumber\n#undef getprotobynumber\n#endif\n#define getprotobynumber(n)\trb_w32_getprotobynumber(n)\n\n#ifdef getservbyname\n#undef getservbyname\n#endif\n#define getservbyname(n, p)\trb_w32_getservbyname(n, p)\n\n#ifdef getservbyport\n#undef getservbyport\n#endif\n#define getservbyport(p, pr)\trb_w32_getservbyport(p, pr)\n\n#ifdef get_osfhandle\n#undef get_osfhandle\n#endif\n#define get_osfhandle(h)\trb_w32_get_osfhandle(h)\n\n#ifdef getcwd\n#undef getcwd\n#endif\n#define getcwd(b, s)\t\trb_w32_getcwd(b, s)\n\n#ifdef getenv\n#undef getenv\n#endif\n#define getenv(n)\t\trb_w32_getenv(n)\n\n#ifdef rename\n#undef rename\n#endif\n#define rename(o, n)\t\trb_w32_rename(o, n)\n\nstruct tms {\n\tlong\ttms_utime;\n\tlong\ttms_stime;\n\tlong\ttms_cutime;\n\tlong\ttms_cstime;\n};\n\n#ifdef times\n#undef times\n#endif\n#define times(t) rb_w32_times(t)\nint rb_w32_times(struct tms *);\n\n/* thread stuff */\nHANDLE GetCurrentThreadHandle(void);\nvoid rb_w32_interrupted(void);\nint  rb_w32_main_context(int arg, void (*handler)(int));\nint  rb_w32_sleep(unsigned long msec);\nvoid rb_w32_enter_critical(void);\nvoid rb_w32_leave_critical(void);\nint  rb_w32_putc(int, FILE*);\nint  rb_w32_getc(FILE*);\nint  rb_w32_close(int);\nint  rb_w32_fclose(FILE*);\nsize_t rb_w32_read(int, void *, size_t);\nsize_t rb_w32_write(int, const void *, size_t);\nint  rb_w32_utime(const char *, struct utimbuf *);\n#define Sleep(msec) (void)rb_w32_sleep(msec)\n\n/*\n== ***CAUTION***\nSince this function is very dangerous, ((*NEVER*))\n* lock any HANDLEs(i.e. Mutex, Semaphore, CriticalSection and so on) or,\n* use anything like TRAP_BEG...TRAP_END block structure,\nin asynchronous_func_t.\n*/\ntypedef DWORD (*asynchronous_func_t)(DWORD self, int argc, DWORD* argv);\nDWORD rb_w32_asynchronize(asynchronous_func_t func, DWORD self, int argc, DWORD* argv, DWORD intrval);\n\n#endif\n"
  },
  {
    "path": "win32/winmain.c",
    "content": "#include <windows.h>\n#include <stdio.h>\n\nextern int main(int, char**, char**);\n\nint WINAPI\nWinMain(HINSTANCE current, HINSTANCE prev, LPSTR cmdline, int showcmd)\n{\n    return main(0, NULL, NULL);\n}\n"
  },
  {
    "path": "wince/Makefile.sub",
    "content": "# -*- makefile -*-\n\nCROSS_COMPILING = 1\nLARGEFILE_SUPPORT = 0\n\n!ifndef win_srcdir\nwin_srcdir = $(srcdir)/wince\n!endif\n\n!if !defined(OS) || !defined(RT)\nOS = mswince\nRT = $(OS)\n!endif\n\n!if !defined(WARNFLAGS)\nWARNFLAGS = -w\n!endif\nARCHDEFS  = $(CECPUDEF) -DUNDER_CE -D_WIN32_WCE=$(SUBSYSVERSION:.=) \\\n           -DFILENAME_MAX=MAX_PATH -DTLS_OUT_OF_INDEXES=0xFFFFFFFF \\\n           -DBUFSIZ=512 -D_UNICODE -DUNICODE\n!if !defined(LDFLAGS)\nLDFLAGS = -link -incremental:yes -pdb:none -machine:$(MACHINE) -subsystem:$(SUBSYSTEM)\n!endif\n!if !defined(XLDFLAGS)\nXLDFLAGS = -stack:$(STACK) -subsystem:$(SUBSYSTEM)\n!endif\nLIBS = coredll.lib ceshell.lib winsock.lib  $(EXTLIBS)\nMISSING = acosh.obj crypt.obj dup2.obj erf.obj hypot.obj \\\n          isinf.obj isnan.obj strftime.obj win32.obj \\\n          assert.obj direct.obj errno.obj io_wce.obj process_wce.obj \\\n          signal_wce.obj stdio.obj stdlib.obj string_wce.obj \\\n          time_wce.obj wince.obj winsock2.obj \\\n          stat.obj timeb.obj utime.obj\nLIBOBJS      = isinf.obj isnan.obj\nCOMMON_LIBS  = coredll winsock\nCOMMON_MACROS = WIN32_LEAN_AND_MEAN\nCOMMON_HEADERS = winsock.h windows.h\n\nXCFLAGS = -I$(srcdir)/wince\n\n!if !defined(STACK_COMMIT)\nSTACK_COMMIT = 0x10000\n!endif\nWINMAINOBJ    = wincemain.$(OBJEXT)\n\n!include $(srcdir)/win32/Makefile.sub\n"
  },
  {
    "path": "wince/README.wince",
    "content": "=begin\n\n= How to build ruby using eMbedded Visual C++\n\n== Requirement\n\n(1) eMbedded Visual C++ 3.0 or later.\n\n(2) If you want to run `((%nmake clean%))' or `((%nmake distclean%))'\n    properly, you must install UNIX compatible `((%rm%))' command on\n    your ((|PATH|)) if you want to clean after compile.\n\n(3) Please set environment variable (({INCLUDE})), (({LIB})), (({PATH})),\n    (({CE_TOOLS_DIR})), (({EMBEDDED_TOOLS_DIR})) to run required commands\n    properly from the command line.\n\n    Note: building ruby requires following commands.\n     * nmake\n     * clarm or clmips or shcl\n     * lib\n     * dumpbin\n\n== How to compile and install\n\n(1) Execute wince\\configure.bat on your build directory.\n    You can specify the target platform as an argument.\n    For example, run `((%configure arm-hpc2k-wince%))'\n\n(2) Change ((|RUBY_INSTALL_NAME|)) and ((|RUBY_SO_NAME|)) in (({Makefile}))\n    if you want to change the name of the executable files. \n\n(3) Run `((%nmake%))'\n\n(4) Run `((%nmake DESTDIR=<install_directory> install%))'\n\n    This command will create following directories and copy (not install :-P)\n    files onto them.\n      * <install_directory>\\bin\n      * <install_directory>\\lib\n      * <install_directory>\\lib\\ruby\n      * <install_directory>\\lib\\ruby\\<MAJOR>.<MINOR>\n      * <install_directory>\\lib\\ruby\\<MAJOR>.<MINOR>\\<PLATFORM>\n      * <install_directory>\\lib\\ruby\\site_ruby\n      * <install_directory>\\lib\\ruby\\site_ruby\\<MAJOR>.<MINOR>\n      * <install_directory>\\lib\\ruby\\site_ruby\\<MAJOR>.<MINOR>\\<PLATFORM>\n      * <install_directory>\\man\\man1\n    If Ruby's version is `x.y.z', the ((|<MAJOR>|)) is `x' and the ((|<MINOR>|)) is `y'.\n    In case of `mips-hpc2k-wince', The ((|<PLATFORM>|)) is `(({mips-mswince}))'.\n\n(5) Copy <install_directory> to your WindowsCE machine.\n\n== Icons\n\nAny icon files(*.ico) in the build directory, directories specified with\n((|icondirs|)) make variable and (({win32})) directory under the ruby\nsource directory will be included in DLL or executable files, according\nto their base names.\n    $(RUBY_INSTALL_NAME).ico or ruby.ico   --> $(RUBY_INSTALL_NAME).exe\n    $(RUBYW_INSTALL_NAME).ico or rubyw.ico --> $(RUBYW_INSTALL_NAME).exe\n    the others                             --> $(RUBY_SO_NAME).dll\n\nAlthough no icons are distributed with the ruby source or in the official \nsite, you can use anything you like. For example, followings are written \nin Japanese, but you can download at least.\n\n* ((<URL:http://member.nifty.ne.jp/ueivu/rubyico.html>)) or\n  ((<zipped icons|URL:http://member.nifty.ne.jp/ueivu/Ruby_ico.zip>))\n* ((<URL:http://homepage1.nifty.com/a_nakata/ruby/>)) or\n  ((<icon itself|URL:http://homepage1.nifty.com/a_nakata/ruby/RubyIcon.ico>))\n\n== Build examples\n\n* Build on the ruby source directory.\n\n  ex.)\n    ruby source directory:  C:\\ruby\n    build directory:        C:\\ruby\n    install directory:      C:\\usr\\local\n\n    C:\n    cd \\ruby\n    win32\\configure\n    nmake\n    nmake DESTDIR=/usr/local install\n\n* Build on the relative directory from the ruby source directory.\n\n  ex.)\n    ruby source directory:  C:\\ruby\n    build directory:        C:\\ruby\\mswin32\n    install directory:      C:\\usr\\local\n\n    C:\n    cd \\ruby\n    mkdir mswin32\n    cd mswin32\n    ..\\win32\\configure\n    nmake\n    nmake DESTDIR=/usr/local install\n\n* Build on the different drive.\n\n  ex.)\n    ruby source directory:  C:\\src\\ruby\n    build directory:        D:\\build\\ruby\n    install directory:      C:\\usr\\local\n\n    D:\n    cd D:\\build\\ruby\n    C:\\src\\ruby\\win32\\configure\n    nmake\n    nmake DESTDIR=C:/usr/local install\n\n== Bugs\n\nYou can ((*NOT*)) use a path name contains any white space characters as\nthe ruby source directory, this restriction comes from the behavior of\n(({!INCLUDE})) directives of (({NMAKE})).\n((- you may call it a bug. -))\n\n=end\n"
  },
  {
    "path": "wince/assert.c",
    "content": "#include <windows.h>\n#include <tchar.h>\n#include \"assert.h\"\n\n\nvoid assert( int expression )\n{\n\tif( expression==0 )\n\t\texit(2);\n}\n\n"
  },
  {
    "path": "wince/assert.h",
    "content": "#ifndef _ASSERT_H_\n#define _ASSERT_H_\n\nvoid assert( int expression );\n\n#endif\n"
  },
  {
    "path": "wince/configure.bat",
    "content": "@echo off\r\n::: Don't set environment variable in batch file other than autoexec.bat\r\n::: to avoid \"Out of environment space\" problem on Windows 95/98.\r\n::: set TMPMAKE=~tmp~.mak\r\n\r\necho> ~tmp~.mak ####\r\necho>> ~tmp~.mak conf = %0\r\necho>> ~tmp~.mak $(conf:\\=/): nul\r\necho>> ~tmp~.mak \t@del ~tmp~.mak\r\necho>> ~tmp~.mak \t@-$(MAKE) -l$(MAKEFLAGS) -f $(@D)/setup.mak \\\r\n:loop\r\nif \"%1\" == \"\" goto :end\r\nif \"%1\" == \"--prefix\" goto :prefix\r\nif \"%1\" == \"--srcdir\" goto :srcdir\r\nif \"%1\" == \"srcdir\" goto :srcdir\r\nif \"%1\" == \"--target\" goto :target\r\nif \"%1\" == \"target\" goto :target\r\nif \"%1\" == \"--with-static-linked-ext\" goto :extstatic\r\nif \"%1\" == \"--program-suffix\" goto :suffix\r\nif \"%1\" == \"--program-name\" goto :progname\r\nif \"%1\" == \"--enable-install-doc\" goto :enable-rdoc\r\nif \"%1\" == \"--disable-install-doc\" goto :disable-rdoc\r\nif \"%1\" == \"--extout\" goto :extout\r\nif \"%1\" == \"-h\" goto :help\r\nif \"%1\" == \"--help\" goto :help\r\nif \"%1\" == \"CC\" goto :define\r\nif \"%1\" == \"EMBEDDED_TOOLS_DIR\" goto :define\r\nif \"%1\" == \"CE_TOOLS_DIR\" goto :define\r\nif \"%1\" == \"EMBEDDED_TOOLS4_DIR\" goto :define\r\nif \"%1\" == \"CE_TOOLS4_DIR\" goto :define\r\n  echo>> ~tmp~.mak \t\"%1\" \\\r\n  shift\r\ngoto :loop\r\n:srcdir\r\n  echo>> ~tmp~.mak \t\"srcdir=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:prefix\r\n  echo>> ~tmp~.mak \t\"prefix=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:suffix\r\n  echo>> ~tmp~.mak \t\"RUBY_SUFFIX=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:installname\r\n  echo>> ~tmp~.mak \t\"RUBY_INSTALL_NAME=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:soname\r\n  echo>> ~tmp~.mak \t\"RUBY_SO_NAME=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:define\r\n  echo>> ~tmp~.mak \t\"%1=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:target\r\n  echo>> ~tmp~.mak \t\"%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:extstatic\r\n  echo>> ~tmp~.mak \t\"EXTSTATIC=static\" \\\r\n  shift\r\ngoto :loop\r\n:enable-rdoc\r\n  echo>> ~tmp~.mak \t\"RDOCTARGET=install-doc\" \\\r\n  shift\r\ngoto :loop\r\n:disable-rdoc\r\n  echo>> ~tmp~.mak \t\"RDOCTARGET=install-nodoc\" \\\r\n  shift\r\ngoto :loop\r\n:extout\r\n  echo>> ~tmp~.mak \t\"EXTOUT=%2\" \\\r\n  shift\r\n  shift\r\ngoto :loop\r\n:help\r\n  echo Configuration:\r\n  echo   --help                  display this help\r\n  echo   --srcdir=DIR            find the sources in DIR [configure dir or `..']\r\n  echo Installation directories:\r\n  echo   --prefix=PREFIX         install files in PREFIX (ignored currently)\r\n  echo System types:\r\n  echo   --target=TARGET         configure for TARGET [i386-mswin32]\r\n  echo Optional Package:\r\n  echo   --with-static-linked-ext link external modules statically\r\n  echo   --enable-install-doc    install rdoc indexes during install\r\n  del ~tmp~.mak\r\ngoto :exit\r\n:end\r\necho>> ~tmp~.mak \tWIN32DIR=$(@D)\r\nnmake -alf ~tmp~.mak\r\n:exit\r\n"
  },
  {
    "path": "wince/direct.c",
    "content": "/***************************************************************\n  direct.c\n***************************************************************/\n\n#include <windows.h>\n#include <tchar.h>\n#include <direct.h>\n#include \"wince.h\" /* for wce_mbtowc */\n\n/* global for chdir, getcwd */\nchar _currentdir[MAX_PATH+1];\n\n\nchar *getcwd(char* buffer, int maxlen)\n{\n\tstrcpy( buffer, _currentdir );\n\treturn buffer;\n}\n\nint _chdir(const char * dirname)\n{\n\tif( MAX_PATH < strlen(dirname) )\n\t\treturn -1;\n\n\tstrcpy( _currentdir, dirname );\n\treturn 0;\n}\n\nint _rmdir(const char * dir)\n{\n\twchar_t *wdir;\n\tBOOL rc;\n\n\t/* replace with RemoveDirectory. */\n\twdir = wce_mbtowc(dir);\n\trc = RemoveDirectoryW(wdir);\n\tfree(wdir);\n\n\treturn rc==TRUE ? 0 : -1;\n}\n\nint _mkdir(const char * dir)\n{\n\twchar_t* wdir;\n\tBOOL rc;\n\n\t/* replace with CreateDirectory. */\n\twdir = wce_mbtowc(dir);\n\trc = CreateDirectoryW(wdir, NULL);\n\tfree(wdir);\n\n\treturn rc==TRUE ? 0 : -1;\n}\n\n"
  },
  {
    "path": "wince/direct.h",
    "content": "#ifndef DIRECT_H\n#define DIRECT_H 1\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nchar *getcwd(char* buffer, int maxlen);\nint _chdir(const char * dirname);\nint _rmdir(const char * dir);\nint _mkdir(const char * dir);\n\n#ifdef __cplusplus\n};\n#endif\n\n#define chdir      _chdir\n#define rmdir      _rmdir\n#define mkdir      _mkdir\n\n#endif\n"
  },
  {
    "path": "wince/errno.c",
    "content": "/***************************************************************\n  errno.c\n***************************************************************/\n\n#include <errno.h>\n\n\nint errno;\nint _doserrno;\nint _sys_nerr;\n\n"
  },
  {
    "path": "wince/errno.h",
    "content": "#ifndef ERRNO_H\n#define ERRNO_H 1\n\n\n#define EPERM           1\n#define ENOENT          2\n#define ESRCH           3\n#define EINTR           4\n#define EIO             5\n#define ENXIO           6\n#define E2BIG           7\n#define ENOEXEC         8\n#define EBADF           9\n#define ECHILD          10\n#define EAGAIN          11\n#define ENOMEM          12\n#define EACCES          13\n#define EFAULT          14\n#define EOSERR          15 // rk\n#define EBUSY           16\n#define EEXIST          17\n#define EXDEV           18\n#define ENODEV          19\n#define ENOTDIR         20\n#define EISDIR          21\n#define EINVAL          22\n#define ENFILE          23\n#define EMFILE          24\n#define ENOTTY          25\n#define EFBIG           27\n#define ENOSPC          28\n#define ESPIPE          29\n#define EROFS           30\n#define EMLINK          31\n#define EPIPE           32\n#define EDOM            33\n#define ERANGE          34\n#define EDEADLK         36\n#define ENOSYS          37\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nextern int errno;\nextern int _doserrno;\nextern int _sys_nerr;\n\n#define sys_nerr _sys_nerr\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "wince/fcntl.h",
    "content": "\n#ifndef FCNTL_H\n#define FCNTL_H 1\n\n\n#define F_SETFL         1\n#define F_SETFD         2\n#define F_GETFL         3\n\n#define _O_RDONLY       0x0000  /* open for reading only */\n#define _O_WRONLY       0x0001  /* open for writing only */\n#define _O_RDWR         0x0002  /* open for reading and writing */\n\n#define _O_NONBLOCK     0x0004\n\n#define _O_APPEND       0x0008  /* writes done at eof */\n#define _O_CREAT        0x0100  /* create and open file */\n#define _O_TRUNC        0x0200  /* open and truncate */\n#define _O_EXCL         0x0400  /* open only if file doesn't already exist */\n#define _O_TEXT         0x4000  /* file mode is text (translated) */\n#define _O_BINARY       0x8000  /* file mode is binary (untranslated) */\n#define _O_ACCMODE      0x10000\n\n#define _O_NOINHERIT    0\n#define O_NOINHERIT     _O_NOINHERIT\n\n#define O_RDONLY        _O_RDONLY\n#define O_WRONLY        _O_WRONLY\n#define O_RDWR          _O_RDWR\n\n#define O_NONBLOCK      _O_NONBLOCK\n\n#define O_APPEND        _O_APPEND\n#define O_CREAT         _O_CREAT\n#define O_TRUNC         _O_TRUNC\n#define O_EXCL          _O_EXCL\n#define O_TEXT          _O_TEXT\n#define O_BINARY        _O_BINARY\n#define O_ACCMODE       _O_ACCMODE\n\n\n#endif\n"
  },
  {
    "path": "wince/io.h",
    "content": "\n#ifndef _IO_WINCE_H_\n#define _IO_WINCE_H_\n\n#ifndef _TIME_T_DEFINED\ntypedef unsigned long time_t;\n#define _TIME_T_DEFINED\n#endif\n\n#ifndef _FSIZE_T_DEFINED\ntypedef unsigned long _fsize_t; /* Could be 64 bits for Win32 */\n#define _FSIZE_T_DEFINED\n#endif\n\n#ifndef _FINDDATA_T_DEFINED\nstruct _finddata_t {\n        unsigned    attrib;\n        time_t      time_create;    /* -1 for FAT file systems */\n        time_t      time_access;    /* -1 for FAT file systems */\n        time_t      time_write;\n        _fsize_t    size;\n        char        name[260];\n};\n#define _FINDDATA_T_DEFINED\n#endif\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint _chsize(int handle, long size);\nint _rename (const char *oldname, const char *newname);\nint _unlink(const char *file);\nint _umask(int cmask);\nint _chmod(const char *path, int mode);\nint dup( int handle );\n//int dup2( int handle1, int handle2 );\nint _isatty(int fd);\nint _pipe(int *phandles, unsigned int psize, int textmode);\nint _access(const char *filename, int flags);\nint _open_osfhandle ( long osfhandle, int flags);\nlong _get_osfhandle( int filehandle );\nint _open(const char *file, int mode,...);\nint close(int fd);\nint _read(int fd, void *buffer, int length);\nint _write(int fd, const void *buffer, unsigned count);\nlong _lseek(int handle, long offset, int origin);\nlong _findfirst( char *filespec, struct _finddata_t *fileinfo );\nint _findnext( long handle, struct _finddata_t *fileinfo );\nint _findclose( long handle );\n\n#ifdef __cplusplus\n};\n#endif\n\n#define chmod      _chmod\n#define chsize     _chsize\n#define rename     _rename\n#define unlink\t   _unlink\n#define open\t   _open\n//#define close\t   _close\n#define read\t   _read\n#define write\t   _write\n#define umask\t   _umask\n//#define dup        _dup\n#define isatty\t   _isatty\n#define access\t   _access\n#define pipe       _pipe\n#define setmode    _setmode\n#define lseek      _lseek\n\n#define _close\t   close\n\n#endif\n\n"
  },
  {
    "path": "wince/io_wce.c",
    "content": "/***************************************************************\n  io.c\n\n  author : uema2\n  date   : Nov 30, 2002\n\n  You can freely use, copy, modify, and redistribute\n  the whole contents.\n***************************************************************/\n\n#include <windows.h>\n#include <stdlib.h>\n#include <io.h>\n#include <fcntl.h>\n#include <time.h>\n#include <errno.h>\n#include \"wince.h\" /* for wce_mbtowc */\n\nextern int _errno;\n\n\nint _rename(const char *oldname, const char *newname)\n{\n\twchar_t *wold, *wnew;\n\tBOOL rc;\n\n\twold = wce_mbtowc(oldname);\n\twnew = wce_mbtowc(newname);\n\n\t/* replace with MoveFile. */\n\trc = MoveFileW(wold, wnew);\n\n\tfree(wold);\n\tfree(wnew);\n\n\treturn rc==TRUE ? 0 : -1;\n}\n\nint _unlink(const char *file)\n{\n\twchar_t *wfile;\n\tBOOL rc;\n\n\t/* replace with DeleteFile. */\n\twfile = wce_mbtowc(file);\n\trc = DeleteFileW(wfile);\n\tfree(wfile);\n\n\treturn rc==TRUE ? 0 : -1;\n}\n\n/* replace \"open\" with \"CreateFile\", etc. */\nint _open(const char *file, int mode, va_list arg)\n{\n\twchar_t *wfile;\n\tDWORD access=0, share=0, create=0;\n\tHANDLE h;\n\n\tif( (mode&_O_RDWR) != 0 )\n\t\taccess = GENERIC_READ|GENERIC_WRITE;\n\telse if( (mode&_O_RDONLY) != 0 )\n\t\taccess = GENERIC_READ;\n\telse if( (mode&_O_WRONLY) != 0 )\n\t\taccess = GENERIC_WRITE;\n\n\tif( (mode&_O_CREAT) != 0 )\n\t\tcreate = CREATE_ALWAYS;\n\telse\n\t\tcreate = OPEN_ALWAYS;\n\n\twfile = wce_mbtowc(file);\n\n\th = CreateFileW(wfile, access, share, NULL,\n\t\t\tcreate, 0, NULL );\n\n\tfree(wfile);\n\treturn (int)h;\n}\n\nint close(int fd)\n{\n\tCloseHandle( (HANDLE)fd );\n\treturn 0;\n}\n\nint _read(int fd, void *buffer, int length)\n{\n\tDWORD dw;\n\tReadFile( (HANDLE)fd, buffer, length, &dw, NULL );\n\treturn (int)dw;\n}\n\nint _write(int fd, const void *buffer, unsigned count)\n{\n\tDWORD dw;\n\tWriteFile( (HANDLE)fd, buffer, count, &dw, NULL );\n\treturn (int)dw;\n}\n\nlong _lseek(int handle, long offset, int origin)\n{\n\tDWORD flag, ret;\n\n\tswitch(origin)\n\t{\n\tcase SEEK_SET: flag = FILE_BEGIN;   break;\n\tcase SEEK_CUR: flag = FILE_CURRENT; break;\n\tcase SEEK_END: flag = FILE_END;     break;\n\tdefault:       flag = FILE_CURRENT; break;\n\t}\n\n\tret = SetFilePointer( (HANDLE)handle, offset, NULL, flag );\n\treturn ret==0xFFFFFFFF ? -1 : 0;\n}\n\n/* _findfirst, _findnext, _findclose. */\n/* replace them with FindFirstFile, etc. */\nlong _findfirst( char *file, struct _finddata_t *fi )\n{\n\tHANDLE h;\n\tWIN32_FIND_DATAA fda;\n\n\th = FindFirstFileA( file, &fda );\n\tif( h==NULL )\n\t{\n\t\terrno = EINVAL; return -1;\n\t}\n\n\tfi->attrib      = fda.dwFileAttributes;\n\tfi->time_create = wce_FILETIME2time_t( &fda.ftCreationTime );\n\tfi->time_access = wce_FILETIME2time_t( &fda.ftLastAccessTime );\n\tfi->time_write  = wce_FILETIME2time_t( &fda.ftLastWriteTime );\n\tfi->size        = fda.nFileSizeLow + (fda.nFileSizeHigh<<32);\n\tstrcpy( fi->name, fda.cFileName );\n\n\treturn (long)h;\n}\n\nint _findnext( long handle, struct _finddata_t *fi )\n{\n\tWIN32_FIND_DATAA fda;\n\tBOOL b;\n\n\tb = FindNextFileA( (HANDLE)handle, &fda );\n\n\tif( b==FALSE )\n\t{\n\t\terrno = ENOENT; return -1;\n\t}\n\n\tfi->attrib      = fda.dwFileAttributes;\n\tfi->time_create = wce_FILETIME2time_t( &fda.ftCreationTime );\n\tfi->time_access = wce_FILETIME2time_t( &fda.ftLastAccessTime );\n\tfi->time_write  = wce_FILETIME2time_t( &fda.ftLastWriteTime );\n\tfi->size        = fda.nFileSizeLow + (fda.nFileSizeHigh<<32);\n\tstrcpy( fi->name, fda.cFileName );\n\n\treturn 0;\n}\n\nint _findclose( long handle )\n{\n\tBOOL b;\n\tb = FindClose( (HANDLE)handle );\n\treturn b==FALSE ? -1 : 0;\n}\n\n/* below functions unsupported... */\n/* I have no idea how to replace... */\nint _chsize(int handle, long size)\n{\n\terrno = EACCES;\n\treturn -1;\n}\n\nint _umask(int cmask)\n{\n\treturn 0;\n}\n\nint _chmod(const char *path, int mode)\n{\n\treturn 0;\n}\n\n/* WinCE doesn't have dup and dup2.  */\n/* so, we cannot use missing/dup2.c. */\nint dup( int handle )\n{\n\terrno = EBADF;\n\treturn -1;\n}\n/*\nint dup2( int handle1, int handle2 )\n{\n\terrno = EBADF;\n\treturn -1;\n}\n*/\nint _isatty(int fd)\n{\n\tif( fd==(int)_fileno(stdin) || \n\t\tfd==(int)_fileno(stdout)||\n\t\tfd==(int)_fileno(stderr) )\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint _pipe(int *phandles, unsigned int psize, int textmode)\n{\n\treturn -1;\n}\n\nint _access(const char *filename, int flags)\n{\n\treturn 0;\n}\n\nint _open_osfhandle( long osfhandle, int flags)\n{\n/*\treturn 0; */\n\treturn (int)osfhandle;\n}\n\nlong _get_osfhandle( int filehandle )\n{\n/*\treturn 0; */\n\treturn (long)filehandle;\n}\n"
  },
  {
    "path": "wince/process.h",
    "content": "#ifndef PROCESS_H\n#define PROCESS_H 1\n\n\n#define _P_WAIT         0\n#define _P_NOWAIT       1\n#define _P_OVERLAY      2\n#define _P_DETACH       4\n\n#define P_WAIT          _P_WAIT\n#define P_NOWAIT        _P_NOWAIT\n#define P_DETACH        _P_DETACH\n#define P_OVERLAY       _P_OVERLAY\n\n#ifndef _INTPTR_T_DEFINED\ntypedef int            intptr_t;\n#define _INTPTR_T_DEFINED\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint _getpid(void);\n\nint _cwait(int *, int, int);\nvoid abort(void);\n\nint _execl(const char *, const char *, ...);\n//int _execv(const char *, const char * const *);\nint execv(const char *path, char *const argv[]);\n\nintptr_t _spawnle(int, const char *, const char *, ...);\nintptr_t _spawnvpe(int, const char *, const char * const *,\n\t      const char * const *);\n\n#ifdef __cplusplus\n};\n#endif\n\n//#define getpid\t   _getpid\n#define execl\t   _execl\n#define execv\t   _execv\n\n\n#endif\n"
  },
  {
    "path": "wince/process_wce.c",
    "content": "/***************************************************************\n  process.c\n***************************************************************/\n\n#include <windows.h>\n#include \"process.h\"\n\nint _getpid(void)\n{\n\treturn (int)GetCurrentProcessId();\n}\n\n/* I wonder _exec and _swawn should be replaced with CreateProcess... */\nint _execl(const char *cmdname, const char *arg0, \n\t\t   va_list va_args)\n{\n\treturn 0;\n}\n\nint execv(const char *path, char *const argv[])\n{\n\treturn 0;\n}\n\nvoid abort(void)\n{\n}\n\nint _cwait( int *termstat, int procHandle, int action )\n{\n\treturn 0;\n}\n\nintptr_t _spawnle(int mode, \n\tconst char *cmdname, const char *arg0,\n\tva_list va_argn)\n{\n\treturn 0;\n}\n\nintptr_t _spawnvpe(int mode,\n\tconst char *cmdname, const char *const *argv,\n\tconst char *const *envp)\n{\n\treturn 0;\n}\n\n"
  },
  {
    "path": "wince/setup.mak",
    "content": "# -*- makefile -*-\n\n!if \"$(srcdir)\" != \"\"\nWIN32DIR = $(srcdir)/win32\n!elseif \"$(WIN32DIR)\" == \"win32\"\nsrcdir = .\n!elseif \"$(WIN32DIR)\" == \"$(WIN32DIR:/win32=)/win32\"\nsrcdir = $(WIN32DIR:/win32=)\n!else\nsrcdir = $(WIN32DIR)/..\n!endif\n!ifndef prefix\nprefix = /usr\n!endif\nOS = mswince\nRT = msvcrt\nINCLUDE = !include\nAPPEND = echo>>$(MAKEFILE)\n!ifdef MAKEFILE\nMAKE = $(MAKE) -f $(MAKEFILE)\n!else\nMAKEFILE = Makefile\n!endif\nARCH = PROCESSOR_ARCHITECTURE\nCPU = PROCESSOR_LEVEL\nCPP = cl -nologo -EP\n\nall: -prologue- -generic- -epilogue-\ni386-$(OS): -prologue- -i386- -epilogue-\ni486-$(OS): -prologue- -i486- -epilogue-\ni586-$(OS): -prologue- -i586- -epilogue-\ni686-$(OS): -prologue- -i686- -epilogue-\nalpha-$(OS): -prologue- -alpha- -epilogue-\n\n# CE\nmips-hpc2k-wince: -prologue- -mips- -hpc2k- -epilogue-\nmips-ppc-wince: -prologue- -mips- -ppc- -epilogue-\nmips-hpcpro-wince: -prologue- -mips- -hpcpro- -epilogue-\narm-hpc2k-wince: -prologue- -arm- -hpc2k- -epilogue-\narm-ppc-wince: -prologue- -arm- -ppc- -epilogue-\narm-hpcpro-wince: -prologue- -arm- -hpcpro- -epilogue-\nsh3-ppc-wince: -prologue- -sh3- -ppc- -epilogue-\nsh3-hpcpro-wince: -prologue- -sh3- -hpcpro- -epilogue-\nsh4-hpcpro-wince: -prologue- -sh4- -hpcpro- -epilogue-\narmv4-.net41-wince: -prologue- -armv4- -.net41- -epilogue-\narmv4t-.net41-wince: -prologue- -armv4t- -.net41- -epilogue-\narmv4i-sig3-wince: -prologue- -armv4i- -sig3- -epilogue-\n\n-prologue-: nul\n\t@type << > $(MAKEFILE)\n### Makefile for ruby $(OS) ###\nsrcdir = $(srcdir:\\=/)\nprefix = $(prefix:\\=/)\nEXTSTATIC = $(EXTSTATIC)\n!if defined(RDOCTARGET)\nRDOCTARGET = $(RDOCTARGET)\n!endif\n!if defined(EXTOUT)\nEXTOUT = $(EXTOUT)\n!endif\n<<\n\t@$(CPP) -I$(srcdir) <<\"Creating $(MAKEFILE)\" >> $(MAKEFILE)\n#include \"version.h\"\nMAJOR = RUBY_VERSION_MAJOR\nMINOR = RUBY_VERSION_MINOR\nTEENY = RUBY_VERSION_TEENY\nMSC_VER = _MSC_VER\n<<\n\n-generic-: nul\n!if defined($(ARCH)) || defined($(CPU))\n\t@type << >>$(MAKEFILE)\n!if defined($(ARCH))\n$(ARCH) = $(PROCESSOR_ARCHITECTURE)\n!endif\n!if defined($(CPU))\n$(CPU) = $(PROCESSOR_LEVEL)\n!endif\n\n<<\n!endif\n\n-alpha-: nul\n\t@$(APPEND) $(ARCH) = alpha\n-ix86-: nul\n\t@$(APPEND) $(ARCH) = x86\n\n-i386-: -ix86-\n\t@$(APPEND) $(CPU) = 3\n-i486-: -ix86-\n\t@$(APPEND) $(CPU) = 4\n-i586-: -ix86-\n\t@$(APPEND) $(CPU) = 5\n-i686-: -ix86-\n\t@$(APPEND) $(CPU) = 6\n\n# CE\n-mips- -arm- -sh3- -sh4-::\n\t@$(APPEND) $(ARCH) = $(@:-=)\n-mips- -arm-::\n\t@$(APPEND) CC = cl$(@:-=)\n-sh3- -sh4-::\n\t@$(APPEND) CC = shcl\n-armv4- -armv4i-::\n\t@$(APPEND) CC = clarm\n\t@$(APPEND) ARCHFOLDER = $(@:-=)\n-armv4t-::\n\t@$(APPEND) CC = clthumb\n\t@$(APPEND) ARCHFOLDER = $(@:-=)\n\n-arm-::\n\t@$(APPEND) CECPUDEF = -DARM -D_ARM_\n-mips-::\n\t@$(APPEND) CECPUDEF = -DMIPS -D_MIPS_\n-sh3-::\n\t@$(APPEND) CECPUDEF = -DSHx -DSH3 -D_SH3_\n-sh4-::\n\t@$(APPEND) CECPUDEF = -DSHx -DSH4 -D_SH4_\n\t@$(APPEND) QSH4  = -Qsh4\n-armv4-::\n\t@$(APPEND) CECPUDEF = -DARM -D_ARM_ -DARMV4\n\t@$(APPEND) $(ARCH) = ARM\n-armv4t- -armv4i-::\n\t@$(APPEND) CECPUDEF = -DARM -D_ARM_ -DARMV4T -DTHUMB -D_THUMB_\n\t@$(APPEND) $(ARCH) = THUMB\n\n\n-hpc2k-: -hpc2000-\n-ppc-: \"-MS Pocket PC-\"\n-hpcpro2-: \"-MS HPC Pro-\"\n-hpcpro-: \"-MS HPC Pro--\"\n\n-mswin32-:\n\t@type << >>$(MAKEFILE)\nOS = mswin32\nRT = msvcrt\n<<\n\n-mswince-:\n\t@type << >>$(MAKEFILE)\n!ifdef CE_TOOLS_DIR\nCE_TOOLS_DIR = $(CE_TOOLS_DIR)\n!endif\n!ifdef EMBEDDED_TOOLS_DIR\nEMBEDDED_TOOLS_DIR = $(EMBEDDED_TOOLS_DIR)\n!endif\n\nOS = mswince\nRT = $$(OS)\n<<\n\n-mswince4-:\n\t@type << >>$(MAKEFILE)\n!ifdef CE_TOOLS4_DIR\nCE_TOOLS4_DIR = $(CE_TOOLS4_DIR)\n!endif\n!ifdef EMBEDDED_TOOLS4_DIR\nEMBEDDED_TOOLS4_DIR = $(EMBEDDED_TOOLS4_DIR)\n!endif\n\nOS = mswince\nRT = $$(OS)\n<<\n\n\n-mswince-3.00 -mswince-2.11: -mswince-\n\t@type << >>$(MAKEFILE)\nSUBSYSVERSION = $(@:-mswince-=)\nPATH = $$(EMBEDDED_TOOLS_DIR)/common/evc/bin;$$(EMBEDDED_TOOLS_DIR)/EVC/WCE$$(SUBSYSVERSION:.=)/bin\n<<\n\n-mswince-4.10: -mswince4-\n\t@type << >>$(MAKEFILE)\nSUBSYSVERSION = $(@:-mswince-=)\nEXTLIBS = ws2.lib\nPATH = $$(EMBEDDED_TOOLS4_DIR)/common/evc/bin;$$(EMBEDDED_TOOLS4_DIR)/EVC/WCE$$(SUBSYSVERSION:.=)/bin\n<<\n\n-hpc2000- \"-MS Pocket PC-\": -mswince-3.00\n\"-MS HPC Pro-\" \"-MS HPC Pro--\": -mswince-2.11\n-.net41- -sig3-: -mswince-4.10\n\n-hpc2000-:\n\t@type << >>$(MAKEFILE)\nSUBSYSTEM = windowsce,3.0\nINCLUDE = $$(CE_TOOLS_DIR)/wce$$(SUBSYSVERSION:.=)/$(@:-=)/include\nLIB = $$(CE_TOOLS_DIR)/wce$$(SUBSYSVERSION:.=)/$(@:-=)/lib/$$(PROCESSOR_ARCHITECTURE)\n<<\n\n\"-MS Pocket PC-\":\n\t@type << >>$(MAKEFILE)\nSUBSYSTEM = windowsce,3.0\nINCLUDE = $$(CE_TOOLS_DIR)/wce$$(SUBSYSVERSION:.=)/MS Pocket PC/include\nLIB = $$(CE_TOOLS_DIR)/wce$$(SUBSYSVERSION:.=)/MS Pocket PC/lib/$$(PROCESSOR_ARCHITECTURE)\n<<\n\n\n\"-MS HPC Pro--\":\n\t@type << >>$(MAKEFILE)\nSUBSYSTEM = windowsce,2.11\nINCLUDE = $$(CE_TOOLS_DIR)/wce$$(SUBSYSVERSION:.=)/MS HPC Pro/include\nLIB = $$(CE_TOOLS_DIR)/wce$$(SUBSYSVERSION:.=)/MS HPC Pro/lib/$$(PROCESSOR_ARCHITECTURE)\n<<\n\n-.net41-:\n\t@type << >>$(MAKEFILE)\nSUBSYSTEM = windowsce,4.1\nINCLUDE = $$(CE_TOOLS4_DIR)/wce400/STANDARDSDK/include/$$(ARCHFOLDER)\nLIB = $$(CE_TOOLS4_DIR)/wce400/STANDARDSDK/lib/$$(ARCHFOLDER)\n<<\n\n-sig3-:\n\t@type << >>$(MAKEFILE)\nSUBSYSTEM = windowsce,4.1\nINCLUDE = $$(CE_TOOLS4_DIR)/wce410/sigmarionIII SDK/include/$$(ARCHFOLDER)\nLIB = $$(CE_TOOLS4_DIR)/wce410/sigmarionIII SDK/lib/$$(ARCHFOLDER)\n<<\n\n-epilogue-: nul\n\t@type << >>$(MAKEFILE)\n!ifdef RUBY_INSTALL_NAME\nRUBY_INSTALL_NAME = $(RUBY_INSTALL_NAME)\n!else ifdef RUBY_SUFFIX\nRUBY_INSTALL_NAME = ruby$(RUBY_SUFFIX)\n!endif\n!ifdef RUBY_SO_NAME\nRUBY_SO_NAME = $(RUBY_SO_NAME)\n!else\n# RUBY_SO_NAME = $$(RT)-$$(RUBY_INSTALL_NAME)$$(MAJOR)$$(MINOR)\n!endif\n# CFLAGS = -nologo $$(DEBUGFLAGS) $$(OPTFLAGS) $$(PROCESSOR_FLAG)\nCPPFLAGS = -I. -I$$(srcdir) -I$$(srcdir)/missing -I$$(srcdir)/wince \\\n           $$(CECPUDEF) -DUNDER_CE -D_WIN32_WCE=$$(SUBSYSVERSION:.=) \\\n           -DFILENAME_MAX=MAX_PATH -DTLS_OUT_OF_INDEXES=0xFFFFFFFF \\\n           -DBUFSIZ=512 -D_UNICODE -DUNICODE $$(QSH4)\n# STACK = 0x10000,0x1000\n# LDFLAGS = $$(CFLAGS) -Fm\n# XLDFLAGS = \n# RFLAGS = -r\n# EXTLIBS =\n\n$(INCLUDE) $$(srcdir)/wince/Makefile.sub\n<<\n\t@$(srcdir:/=\\)\\win32\\rm.bat config.h config.status\n\t@echo type `$(MAKE)' to make ruby for $(OS).\n"
  },
  {
    "path": "wince/signal.h",
    "content": "#ifndef SIGNAL_H\n#define SIGNAL_H 1\n\n#include <sys/types.h>\n\n#define SIGHUP\t\t1\n#define SIGINT      2\n#define SIGQUIT\t\t3\n#define SIGILL      4\n#define SIGPIPE     5\n#define SIGFPE      8\n#define SIGUSR1\t\t10\n#define SIGSEGV     11\n#define SIGUSR2\t\t12\n#define SIGTERM     15\n#define SIGCHLD\t\t17\n#define SIGTSTP\t\t20\n#define SIGBREAK    21\n#define SIGABRT     22\n#define NSIG        22\n\n#define SA_NOCLDSTOP\t1\n#define SA_SHIRQ\t0x04000000\n#define SA_STACK\t0x08000000\n#define SA_RESTART\t0x10000000\n#define SA_INTERRUPT\t0x20000000\n#define SA_NOMASK\t0x40000000\n#define SA_ONESHOT\t0x80000000\n\n/* signal action codes */\n\n#define SIG_DFL (void (*)(int))0           /* default signal action */\n#define SIG_IGN (void (*)(int))1           /* ignore signal */\n#define SIG_SGE (void (*)(int))3           /* signal gets error */\n#define SIG_ACK (void (*)(int))4           /* acknowledge */\n#define SIG_ERR (void (*)(int))-1          /* signal error value */\n\n#define SIG_BLOCK          0\t/* for blocking signals */\n#define SIG_UNBLOCK        1\t/* for unblocking signals */\n#define SIG_SETMASK        2\t/* for setting the signal mask */\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef void (* SIGHANDLER)(int);\ntypedef void (* sighandler_t)(int);\n\ntypedef int sig_atomic_t;\ntypedef unsigned int sigset_t;\n\nstruct sigaction{\n\tsighandler_t sa_handler;\n\tsigset_t sa_mask;\n\tunsigned long sa_flags;\n\tvoid (*sa_restorer)(void);\n};\n\nint raise(int sig);\n//#ifndef _WIN32_WCE_EMULATION\n  void (* signal(int sig, void (__cdecl *func)(int)))(int);\n//#else\n//  void (* signal(int sig, void (*func)));\n//#endif\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "wince/signal_wce.c",
    "content": "/***************************************************************\n  signal.c\n***************************************************************/\n\n#include <windows.h>\n#include \"signal.h\"\n\n/* lazy replacement... (^^; */\nint raise(int sig)\n{\n\treturn 0;\n}\n\n//#ifdef _WIN32_WCE\n//#ifdef _WIN32_WCE_EMULATION\n//void (* signal(int sig, void (*func)))\n//{\n//\treturn sig;\n//}\n//#else\nvoid (* signal(int sig, void (__cdecl *func)(int)))(int)\n{\n\treturn sig;\n}\n//#endif\n//#endif\n"
  },
  {
    "path": "wince/stddef.h",
    "content": "\n#ifndef _STDDEF_H_\n#define _STDDEF_H_\n\n#endif\n"
  },
  {
    "path": "wince/stdio.c",
    "content": "/***************************************************************\n  stdio.c\n***************************************************************/\n\n#include <windows.h>\n#include \"wince.h\" /* for wce_mbtowc */\n\n\nFILE *freopen(const char *filename, const char *mode, FILE *file)\n{\n\twchar_t *wfilename, *wmode;\n\tFILE *fp;\n\n\twfilename = wce_mbtowc(filename);\n\twmode     = wce_mbtowc(mode);\n\n\tfp = _wfreopen(wfilename, wmode, file);\n\n\tfree(wfilename);\n\tfree(wmode);\n\n\treturn fp;\n}\n\nFILE *fdopen( int handle, const char *mode )\n{\n\twchar_t *wmode;\n\tFILE* fp;\n\n\twmode = wce_mbtowc(mode);\n\tfp = _wfdopen( (void*)handle, wmode );\n\n\tfree(wmode);\n\treturn fp;\n}\n\n"
  },
  {
    "path": "wince/stdlib.c",
    "content": "/***************************************************************\n  stdlib.c\n***************************************************************/\n\n#include <windows.h>\n\nchar **environ;\nextern char * rb_w32_getenv(const char *);\n\n/* getenv should replace with rb_w32_getenv. */\nchar *getenv(const char *env)\n{\n\treturn rb_w32_getenv(env);\n}\n\nchar *_fullpath(char *absPath, const char *relPath, \n\t\t\t\tsize_t maxLength)\n{\n\tstrcpy( absPath, relPath );\n\treturn absPath;\n}\n\nint mblen(const char *mbstr, size_t count)\n{\n\tconst char *p = mbstr;\n\tsize_t i;\n\tint    n=0;\n\n\tfor( i=0; i<count; i++ )\n\t{\n\t\tif( *p=='\\0' ) break;\n\t\tif( IsDBCSLeadByteEx( CP_ACP, *p ) )\n\t\t\tn+=2, p+=2;\n\t\telse\n\t\t\tn+=1, p+=1;\n\t}\n\n\treturn n;\n}\n\nvoid *bsearch( const void *key, const void *base,\n\t\t\t   size_t num, size_t width,\n\t\t\t   int ( __cdecl *compare )(const void *, const void *))\n{\n\tsize_t i;\n\tconst void* p = base;\n\tconst char* px;\n\n\tfor( i=0; i<num; i++ )\n\t{\n\t\tif( 0==compare( key, p ) )\n\t\t\treturn (void*)p;\n\t\tpx = (const char*)p; px+=width; p=(const void*)px;\n\t}\n\treturn NULL;\n}\n\n"
  },
  {
    "path": "wince/string_wce.c",
    "content": "/***************************************************************\n  string.c\n***************************************************************/\n\n#include <windows.h>\n#include \"wince.h\" /* for wce_mbtowc */\n\n/* _strdup already exists in stdlib.h? */\nchar *strdup(const char * str)\n{\n\tchar *p;\n\n\tp = malloc( strlen(str)+1 );\n\tstrcpy( p, str );\n\treturn p;\n}\n\nchar* strerror(int errno)\n{\n\tstatic char buf[32]=\"wince::strerror called.\";\n\treturn buf;\n}\n\n/* strnicmp already exists in stdlib.h? */\nint strnicmp( const char *s1, const char *s2, size_t count )\n{\n\twchar_t *w1, *w2;\n\tint n;\n\n\tw1 = wce_mbtowc(s1);\n\tw2 = wce_mbtowc(s2);\n\n\tn = wcsnicmp(w1, w2, count);\n\n\tfree(w1);\n\tfree(w2);\n\n\treturn n;\n}\n\n#if _WIN32_WCE < 300\n#include \"..\\missing\\strtoul.c\"\n\nchar *strrchr( const char *p, int c )\n{\n\tchar *pp;\n\tfor( pp=(char*)p+strlen(p); pp!=p; pp-- )\n\t{\n\t\tif( *pp==c ) break;\n\t}\n\treturn pp==p ? NULL : pp;\n}\n\nint stricmp( const char *s1, const char *s2 )\n{\n\twchar_t *w1, *w2;\n\tint n;\n\n\tw1 = wce_mbtowc(s1);\n\tw2 = wce_mbtowc(s2);\n\n\tn = wcsicmp(w1, w2);\n\n\tfree(w1);\n\tfree(w2);\n\n\treturn n;\n}\n\nchar *strpbrk(const char *str, const char *cs)\n{\n\twchar_t *wstr, *wcs, *w;\n\tchar *s = NULL;\n\n\twstr = wce_mbtowc(str);\n\twcs  = wce_mbtowc(cs);\n\n\tw = wcspbrk(wstr, wcs);\n\n\tif( w!=NULL )\n\t\ts = str + (wcs-wstr)/sizeof(wchar_t);\n\n\tfree(wstr);\n\tfree(wcs);\n\n\treturn s;\n}\n\n#endif\n"
  },
  {
    "path": "wince/sys/stat.c",
    "content": "/***************************************************************\n  stat.c\n\n  author : uema2\n  date   : Nov 30, 2002\n\n  You can freely use, copy, modify, and redistribute\n  the whole contents.\n***************************************************************/\n\n#include <windows.h>\n#include <sys/stat.h>\n#include <time.h>\n#include \"..\\wince.h\" /* for wce_mbtowc */\n\n\nint _stat(const char *filename, struct _stat *st)\n{\n\tDWORD dwAttribute;\n\tHANDLE h;\n\tDWORD dwSizeLow=0, dwSizeHigh=0, dwError=0;\n\tWIN32_FIND_DATAW fd;\n\twchar_t *wfilename;\n\n//\twfilename = wce_mbtowc(filename);\n\twfilename = wce_replaceRelativeDir(filename);\n\n\tdwAttribute = GetFileAttributesW(wfilename);\n\tif(dwAttribute==0xFFFFFFFF)\n\t{\n\t\tfree(wfilename);\n\t\treturn -1;\n\t}\n\n\tst->st_mode = 0;\n\tif((dwAttribute & FILE_ATTRIBUTE_DIRECTORY) != 0)\n\t\tst->st_mode += S_IFDIR;\n\telse\n\t\tst->st_mode += S_IFREG;\n\n\t/* initialize */\n\tst->st_atime = 0;\n    st->st_mtime = 0;\n    st->st_ctime = 0;\n\tst->st_size  = 0;\n\tst->st_dev   = 0;\n\n\th = FindFirstFileW(wfilename, &fd);\n\tif(h == INVALID_HANDLE_VALUE)\n\t{\n\t\tif(wfilename[wcslen(wfilename)-1]\t== L'\\\\')\n\t\t{\n\t\t\twfilename[wcslen(wfilename)-1] = L'\\0';\n\t\t\th = FindFirstFileW(wfilename, &fd);\n\t\t\tif(h == INVALID_HANDLE_VALUE)\n\t\t\t{\n\t\t\t\tfree(wfilename);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfree(wfilename);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* FILETIME -> time_t */\n\tst->st_atime = wce_FILETIME2time_t(&fd.ftLastAccessTime);\n    st->st_mtime = wce_FILETIME2time_t(&fd.ftLastWriteTime);\n    st->st_ctime = wce_FILETIME2time_t(&fd.ftCreationTime);\n\tst->st_size  = fd.nFileSizeLow;\n\n\tFindClose( h );\n\tfree(wfilename);\n\treturn 0;\n}\n\nint fstat(int file, struct stat *sbuf)\n{\n\t/* GetFileSize & GetFileTime */\n\tDWORD dwSize;\n\tFILETIME ctime, atime, mtime;\n\n\tdwSize = GetFileSize( (HANDLE)file, NULL );\n\tif( dwSize == 0xFFFFFFFF )\n\t\treturn -1;\n\n\tsbuf->st_size = dwSize;\n\tsbuf->st_dev  = 0;\n\tsbuf->st_rdev = 0;\n\tsbuf->st_mode = _S_IFREG;\n\tsbuf->st_nlink= 1;\n\n\tGetFileTime( (HANDLE)file, &ctime, &atime, &mtime );\n\tsbuf->st_ctime = wce_FILETIME2time_t(&ctime);\n\tsbuf->st_atime = wce_FILETIME2time_t(&atime);\n\tsbuf->st_mtime = wce_FILETIME2time_t(&mtime);\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "wince/sys/stat.h",
    "content": "#ifndef SYS_STAT_H\n#define SYS_STAT_H 1\n\n#include <sys/types.h>\n\n#define _S_IFMT         0170000         /* file type mask */\n#define _S_IFDIR        0040000         /* directory */\n#define _S_IFCHR        0020000         /* character special */\n#define _S_IFIFO        0010000         /* pipe */\n#define _S_IFREG        0100000         /* regular */\n#define _S_IREAD        0000400         /* read permission, owner */\n#define _S_IWRITE       0000200         /* write permission, owner */\n#define _S_IEXEC        0000100         /* execute/search permission, owner */\n\n#define S_IFMT   _S_IFMT\n#define S_IFREG  _S_IFREG\n#define S_IFCHR  _S_IFCHR\n#define S_IFDIR  _S_IFDIR\n#define S_IREAD  _S_IREAD\n#define S_IWRITE _S_IWRITE\n#define S_IEXEC  _S_IEXEC\n\n#ifndef S_ISDIR\n#define S_ISDIR(X) (((X) & S_IFMT) == S_IFDIR)\n#endif\n#ifndef S_ISREG\n#define S_ISREG(X) (((X) & S_IFMT) == S_IFREG)\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// in sys/types.h\n//typedef unsigned int _dev_t;\n//typedef long _off_t;\n//typedef unsigned short _ino_t;\n\n#ifndef _STAT_DEFINED\nstruct stat \n{\n  dev_t st_dev;\n  ino_t st_ino;\n  unsigned short st_mode;\n  short st_nlink;\n  short st_uid;\n  short st_gid;\n  dev_t st_rdev;\n  off_t st_size;\n  time_t st_atime;\n  time_t st_mtime;\n  time_t st_ctime;\n};\n#define _STAT_DEFINED\n#endif /* _STAT_DEFINED */\n\n#define _stat stat\n\nint _stat(const char *filename, struct _stat *stat);\nint fstat(int file, struct stat *sbuf);\n\n\n#ifdef __cplusplus\n};\n#endif\n\n\n#endif\n"
  },
  {
    "path": "wince/sys/timeb.c",
    "content": "/***************************************************************\n  timeb.c\n***************************************************************/\n\n#include <windows.h>\n#include <time.h>\n#include <sys/timeb.h>\n\n\nint ftime(struct timeb *tp)\n{\n\tSYSTEMTIME s;\n\tFILETIME   f;\n\n\tGetLocalTime(&s);\n\tSystemTimeToFileTime( &s, &f );\n\n\ttp->dstflag  = 0;\n\ttp->timezone = _timezone/60;\n\ttp->time     = wce_FILETIME2time_t(&f);\n\ttp->millitm  = s.wMilliseconds;\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "wince/sys/timeb.h",
    "content": "#ifndef SYS_TIMEB_H\n#define SYS_TIMEB_H 1\n\n#include <sys/types.h>\n\nstruct _timeb {\n\ttime_t time;\n\tunsigned short millitm;\n\tshort timezone;\n\tshort dstflag;\n};\n\n#define timeb _timeb\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint ftime(struct timeb *tp);\n\n#ifdef __cplusplus\n};\n#endif\n\n\n#endif\n"
  },
  {
    "path": "wince/sys/types.h",
    "content": "#ifndef SYS_TYPES_H\n#define SYS_TYPES_H 1\n\n#define BIG_ENDIAN    1234\n#define LITTLE_ENDIAN 4321\n\n#ifdef MIPS\n#define BYTE_ORDER LITTLE_ENDIAN\n#endif\n\n//#if UNDER_CE > 201\n//  typedef unsigned long time_t;\n//  #define _TIME_T_DEFINED_\n//#endif\ntypedef unsigned long dev_t;\ntypedef unsigned long ino_t;\n#ifndef _MODE_T_DEFINED_\n  typedef unsigned long mode_t;\n  #define _MODE_T_DEFINED_\n#endif\n\ntypedef long clock_t;\n\n#ifndef _PTRDIFF_T_DEFINED\ntypedef long ptrdiff_t;\n#define _PTRDIFF_T_DEFINED\n#endif\n\ntypedef long off_t;\n\n//typedef unsigned char u_char;\n//typedef unsigned short u_short;\n\n#ifndef _CADDR_T_DEFINED_\ntypedef unsigned char * caddr_t;\n#define _CADDR_T_DEFINED_\n#endif\n\n#ifndef _SIZE_T_DEFINED_\ntypedef unsigned int size_t;\n#define _SIZE_T_DEFINED_\n#endif\n\n//typedef unsigned char u_int8_t;\n\n//typedef short int16_t;\n//typedef unsigned short u_int16_t;\n\n//typedef int int32_t;\n//typedef unsigned int u_int32_t;\n\n//typedef unsigned long u_long;\n//typedef unsigned int u_int;\n\n//#ifndef _TIME_T_DEFINED_\n//typedef unsigned long time_t;\n//#define _TIME_T_DEFINED_\n//#endif\n\n#endif\n"
  },
  {
    "path": "wince/sys/utime.c",
    "content": "/***************************************************************\n  utime.c\n***************************************************************/\n\n#include <windows.h>\n#include <sys/utime.h>\n#include \"..\\wince.h\" /* for wce_mbtowc */\n\n\n#ifdef _WIN32_WCE\n  #if _WIN32_WCE < 300\n    #define Int32x32To64(a, b) ((LONGLONG)((LONG)(a)) * (LONGLONG)((LONG)(b)))\n/*    #define Int32x32To64(a, b) ((__int64)((LONG)(a)) * (__int64)((LONG)(b))) */\n  #endif\n#endif\n\nint utime(const char *f, struct utimbuf *t)\n{\n\tHANDLE h;\n\tFILETIME atime={0}, mtime={0};\n\t__int64 time64;\n\tBOOL rc;\n\twchar_t *w;\n\n\tw = wce_mbtowc(f);\n\th = CreateFileW(w, GENERIC_WRITE, \n\t\t\tFILE_SHARE_READ|FILE_SHARE_WRITE,\n\t\t\tNULL, OPEN_EXISTING, 0, 0);\n\tfree(w);\n\n\tif( h==INVALID_HANDLE_VALUE )\n\t\treturn -1;\n\n\ttime64 = Int32x32To64(t->actime, 10000000) + 116444736000000000;\n\tatime.dwLowDateTime  = (DWORD)time64;\n\tatime.dwHighDateTime = (DWORD)(time64 >> 32);\n\ttime64 = Int32x32To64(t->modtime, 10000000) + 116444736000000000;\n\tmtime.dwLowDateTime  = (DWORD)time64;\n\tmtime.dwHighDateTime = (DWORD)(time64 >> 32);\n\n\trc = SetFileTime(h, NULL, &atime, &mtime);\n\treturn rc==TRUE ? 0 : -1;\n}\n\n"
  },
  {
    "path": "wince/sys/utime.h",
    "content": "#ifndef SYS_UTIME_H\n#define SYS_UTIME_H 1\n\n#include <time.h>\n\nstruct utimbuf \n{\n  time_t actime;\n  time_t modtime;\n};\n\n#define _utimbuf utimbuf\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint utime(const char *f, struct utimbuf *t);\n\n#ifdef __cplusplus\n};\n#endif\n\n//#define utime _utime\n\n#endif\n"
  },
  {
    "path": "wince/time.h",
    "content": "#ifndef _TIME_WINCE_H\n#define _TIME_WINCE_H 1\n\n#include <winbase.h>\n#include <sys/types.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nextern int daylight;\nextern int _timezone, timezone;\nextern char *tzname[2];\n\n#if 0\n#define _DAY_SEC           (24L * 60L * 60L)    /* secs in a day */\n#define _YEAR_SEC          (365L * _DAY_SEC)    /* secs in a year */\n#define _FOUR_YEAR_SEC     (1461L * _DAY_SEC)   /* secs in a 4 year interval */\n#define _DEC_SEC           315532800L           /* secs in 1970-1979 */\n#define _BASE_YEAR         70L                  /* 1970 is the base year */\n#define _BASE_DOW          4                    /* 01-01-70 was a Thursday */\n#define _LEAP_YEAR_ADJUST  17L                  /* Leap years 1900 - 1970 */\n#define _MAX_YEAR          138L                 /* 2038 is the max year */\n#endif\n\n#ifndef _TM_DEFINED\nstruct tm {\n  int tm_sec;     /* seconds after the minute - [0,59] */\n  int tm_min;     /* minutes after the hour - [0,59] */\n  int tm_hour;    /* hours since midnight - [0,23] */\n  int tm_mday;    /* day of the month - [1,31] */\n  int tm_mon;     /* months since January - [0,11] */\n  int tm_year;    /* years since 1900 */\n  int tm_wday;    /* days since Sunday - [0,6] */\n  int tm_yday;    /* days since January 1 - [0,365] */\n  int tm_isdst;   /* daylight savings time flag */\n};\n#define _TM_DEFINED\n#endif\n\n\ntypedef struct {\n\t\tint  yr;        // year of interest\n\t\tint  yd;        // day of year \n\t\tlong ms;        // milli-seconds in the day \n} transitionTime;\n\ntime_t mktime(struct tm* pt);\ntime_t time( time_t *timer );\nstruct tm *localtime(const time_t *ptime);\nstruct tm *gmtime(const time_t *tod);\nchar* ctime( const time_t *t );\nchar* asctime(const struct tm *tptr);\nvoid tzset();\nint clock(void);\ntime_t wce_FILETIME2time_t(const FILETIME* pf);\n\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "wince/time_wce.c",
    "content": "/***************************************************************\n  time.c\n\n  author : uema2\n  date   : Nov 30, 2002\n\n  You can freely use, copy, modify, and redistribute\n  the whole contents.\n***************************************************************/\n\n/*#define __SCRATCH_TIMEC_DEBUG__ */\n\n#include <windows.h>\n#include <tchar.h>\n#include <time.h>\n\n/* globals */\nconst __int64 _onesec_in100ns = (__int64)10000000;\nint   timezone, _timezone, altzone;\nint   daylight;\nchar *tzname[2];\n\n\n/* __int64 <--> FILETIME */\nstatic __int64 wce_FILETIME2int64(FILETIME f)\n{\n\t__int64 t;\n\n\tt = f.dwHighDateTime;\n\tt <<= 32;\n\tt |= f.dwLowDateTime;\n\treturn t;\n}\n\nstatic FILETIME wce_int642FILETIME(__int64 t)\n{\n\tFILETIME f;\n\n\tf.dwHighDateTime = (DWORD)((t >> 32) & 0x00000000FFFFFFFF);\n\tf.dwLowDateTime  = (DWORD)( t        & 0x00000000FFFFFFFF);\n\treturn f;\n}\n\n/* FILETIME utility */\nstatic FILETIME wce_getFILETIMEFromYear(WORD year)\n{\n\tSYSTEMTIME s={0};\n\tFILETIME f;\n\n\ts.wYear      = year;\n\ts.wMonth     = 1;\n\ts.wDayOfWeek = 1;\n\ts.wDay       = 1;\n\n\tSystemTimeToFileTime( &s, &f );\n\treturn f;\n}\n\nstatic time_t wce_getYdayFromSYSTEMTIME(const SYSTEMTIME* s)\n{\n\t__int64 t;\n\tFILETIME f1, f2;\n\n\tf1 = wce_getFILETIMEFromYear( s->wYear );\n\tSystemTimeToFileTime( s, &f2 );\n\n\tt = wce_FILETIME2int64(f2)-wce_FILETIME2int64(f1);\n\n\treturn (time_t)((t/_onesec_in100ns)/(60*60*24));\n}\n\n/* tm <--> SYSTEMTIME */\nstatic SYSTEMTIME wce_tm2SYSTEMTIME(struct tm *t)\n{\n\tSYSTEMTIME s;\n\n\ts.wYear      = t->tm_year + 1900;\n\ts.wMonth     = t->tm_mon  + 1;\n\ts.wDayOfWeek = t->tm_wday;\n\ts.wDay       = t->tm_mday;\n\ts.wHour      = t->tm_hour;\n\ts.wMinute    = t->tm_min;\n\ts.wSecond    = t->tm_sec;\n\ts.wMilliseconds = 0;\n\n\treturn s;\n}\n\nstatic struct tm wce_SYSTEMTIME2tm(SYSTEMTIME *s)\n{\n\tstruct tm t;\n\n\tt.tm_year  = s->wYear - 1900;\n\tt.tm_mon   = s->wMonth- 1;\n\tt.tm_wday  = s->wDayOfWeek;\n\tt.tm_mday  = s->wDay;\n\tt.tm_yday  = wce_getYdayFromSYSTEMTIME(s);\n\tt.tm_hour  = s->wHour;\n\tt.tm_min   = s->wMinute;\n\tt.tm_sec   = s->wSecond;\n\tt.tm_isdst = 0;\n\n\treturn t;\n}\n\n/* FILETIME <--> time_t */\ntime_t wce_FILETIME2time_t(const FILETIME* f)\n{\n\tFILETIME f1601, f1970;\n\t__int64 t, offset;\n\n\tf1601 = wce_getFILETIMEFromYear(1601);\n\tf1970 = wce_getFILETIMEFromYear(1970);\n\n\toffset = wce_FILETIME2int64(f1970) - wce_FILETIME2int64(f1601);\n\n\tt = wce_FILETIME2int64(*f);\n\n\tt -= offset;\n\treturn (time_t)(t / _onesec_in100ns);\n}\n\nFILETIME wce_time_t2FILETIME(const time_t t)\n{\n\tFILETIME f, f1970;\n\t__int64 time;\n\n\tf1970 = wce_getFILETIMEFromYear(1970);\n\n\ttime = t;\n\ttime *= _onesec_in100ns;\n\ttime += wce_FILETIME2int64(f1970);\n\n\tf = wce_int642FILETIME(time);\n\n\treturn f;\n}\n\n/* time.h difinition */\ntime_t time( time_t *timer )\n{\n\tSYSTEMTIME s;\n\tFILETIME   f;\n\n\tif( timer==NULL ) return 0;\n\n\tGetSystemTime( &s );\n\n\tSystemTimeToFileTime( &s, &f );\n\n\t*timer = wce_FILETIME2time_t(&f);\n\treturn *timer;\n}\n\nstruct tm *localtime( const time_t *timer )\n{\n\tSYSTEMTIME ss, ls, s;\n\tFILETIME   sf, lf, f;\n\t__int64 t, diff;\n\tstatic struct tm tms;\n\n\tGetSystemTime(&ss);\n\tGetLocalTime(&ls);\n\n\tSystemTimeToFileTime( &ss, &sf );\n\tSystemTimeToFileTime( &ls, &lf );\n\n\tdiff = wce_FILETIME2int64(sf) - wce_FILETIME2int64(lf);\n\n\tf = wce_time_t2FILETIME(*timer);\n\tt = wce_FILETIME2int64(f) - diff;\n\tf = wce_int642FILETIME(t);\n\n\tFileTimeToSystemTime( &f, &s );\n\n\ttms = wce_SYSTEMTIME2tm(&s);\n\n\treturn &tms;\n}\n\ntime_t mktime(struct tm* pt)\n{\n\tSYSTEMTIME ss, ls, s;\n\tFILETIME   sf, lf, f;\n\t__int64 diff;\n\n\tGetSystemTime(&ss);\n\tGetLocalTime(&ls);\n\tSystemTimeToFileTime( &ss, &sf );\n\tSystemTimeToFileTime( &ls, &lf );\n\n\tdiff = (wce_FILETIME2int64(lf)-wce_FILETIME2int64(sf))/_onesec_in100ns;\n\n\ts = wce_tm2SYSTEMTIME(pt);\n\tSystemTimeToFileTime( &s, &f );\n\treturn wce_FILETIME2time_t(&f) - (time_t)diff;\n}\n\nstruct tm *gmtime(const time_t *t)\n{\n\tFILETIME f;\n\tSYSTEMTIME s;\n\tstatic struct tm tms;\n\t\n\tf = wce_time_t2FILETIME(*t);\n\tFileTimeToSystemTime(&f, &s);\n\ttms = wce_SYSTEMTIME2tm(&s);\n\treturn &tms;\n}\n\nchar* ctime( const time_t *t )\n{\n\t// Wed Jan 02 02:03:55 1980\\n\\0\n\tstatic char buf[30]={0};\n\tchar week[] = \"Sun Mon Tue Wed Thr Fri Sat \";\n\tchar month[]= \"Jan Feb Mar Apl May Jun Jul Aug Sep Oct Nov Dec \";\n\tstruct tm tms;\n\n\ttms = *localtime(t);\n\n\tstrncpy( buf,    week+tms.tm_wday*4, 4 );\n\tstrncpy( buf+4,  month+tms.tm_mon*4, 4 );\n\tsprintf( buf+8,  \"%02d \", tms.tm_mday );\n\tsprintf( buf+11, \"%02d:%02d:%02d %d\\n\", \n\t\ttms.tm_hour, tms.tm_min, tms.tm_sec, tms.tm_year+1900 );\n\treturn buf;\n}\n\nchar *asctime(const struct tm *pt)\n{\n\tstatic char buf[30]={0};\n\tchar week[] = \"Sun Mon Tue Wed Thr Fri Sat \";\n\tchar month[]= \"Jan Feb Mar Apl May Jun Jul Aug Sep Oct Nov Dec \";\n\n\tstrncpy( buf,    week+pt->tm_wday*4, 4 );\n\tstrncpy( buf+4,  month+pt->tm_mon*4, 4 );\n\tsprintf( buf+8,  \"%02d \", pt->tm_mday );\n\tsprintf( buf+11, \"%02d:%02d:%02d %d\\n\", \n\t\tpt->tm_hour, pt->tm_min, pt->tm_sec, pt->tm_year+1900 );\n\treturn buf;\n}\n\nvoid tzset()\n{\n\tdaylight = 1;\n\t_timezone = 28800;\n\ttimezone = 28800;\n}\n\nint clock(void)\n{\n\treturn 1;\n}\n\n//---------------------------------------------------------------\n#ifdef __SCRATCH_TIMEC_DEBUG__\n\nint main()\n{\n\ttime_t t1, t2;\n\tstruct tm tm1, tm2;\n\n\ttime( &t1 );\n\ttm1 = *localtime(&t1);\n\tt1 = mktime(&tm1);\n\ttm1 = *gmtime(&t1);\n\n\t_time( &t2 );\n\ttm2 = *_localtime(&t2);\n\tt2 = _mktime(&tm2);\n\ttm2 = *_gmtime(&t2);\n\n\t// time, mktime\n\tif( t1==t2 )\n\t\tOutputDebugString( \"ok\\n\" );\n\telse\n\t{\n\t\tstatic char buf[128];\n\t\twsprintf( buf, \"ng : %d, %d\\n\", t1, t2 );\n\t\tOutputDebugString( buf );\n\t}\n\n\t// localtime, gmtime\n\tif( 0==memcmp( &tm1, &tm2, sizeof(struct tm) ) )\n\t\tOutputDebugString( \"ok\\n\" );\n\telse\n\t\tOutputDebugString( \"ng\\n\" );\n\n\t// ctime\n\tOutputDebugString( ctime(&t1) );\n\tOutputDebugString( _ctime(&t2) );\n\n\t// asctime\n\tOutputDebugString( asctime(&tm1) );\n\tOutputDebugString( _asctime(&tm2) );\n\n\treturn 0;\n}\n\n#endif\n\n"
  },
  {
    "path": "wince/varargs.h",
    "content": "\n#ifndef VARARGS_H\n#define VARARGS_H 1\n\n#ifdef  __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _VA_LIST_DEFINED\ntypedef char *va_list;\n#define _VA_LIST_DEFINED\n#endif\n\n//#ifdef MIPS\n#define va_alist __va_alist, __va_alist2, __va_alist3, __va_alist4\n#define va_dcl int __va_alist, __va_alist2, __va_alist3, __va_alist4;\n#define va_start(list) list = (char *) &__va_alist\n#define va_end(list)\n#define va_arg(list, mode) ((mode *)(list =\\\n (char *) ((((int)list + (__builtin_alignof(mode)<=4?3:7)) &\\\n (__builtin_alignof(mode)<=4?-4:-8))+sizeof(mode))))[-1]\n#else\n#define _INTSIZEOF(n)    ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )\n#define va_dcl va_list va_alist;\n#define va_start(ap) ap = (va_list)&va_alist\n#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )\n#define va_end(ap) ap = (va_list)0\n//#endif\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "wince/wince.c",
    "content": "/***************************************************************\n  wince.c\n\n  author : uema2\n  date   : Nov 30, 2002\n\n  You can freely use, copy, modify, and redistribute\n  the whole contents.\n***************************************************************/\n\n#include <windows.h>\n#include <tchar.h>\n#include \"wince.h\"\n\n/* global for GetCommandLineA */\nchar *_commandLine;\n\nextern char _currentdir[];\n\n/* make up Win32API except wce_* functions.  */\n\nDWORD GetModuleFileNameA( \n\tHMODULE hModule, LPSTR lpFileName,\n\tDWORD size )\n{\n\tLPWSTR lpFileNameW;\n\tLPSTR  mb;\n\tsize_t ret;\n\n\tif( size==0 ) return 0;\n\n\tlpFileNameW = (LPWSTR)malloc( size*sizeof(wchar_t) );\n\tret = GetModuleFileNameW( hModule, lpFileNameW, size );\n\tmb = wce_wctomb(lpFileNameW);\n\tstrcpy(lpFileName, mb);\n\tfree(mb);\n\tfree(lpFileNameW);\n\n\treturn ret;\n}\n\n#if _WIN32_WCE < 300\nFARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName)\n{\n\tFARPROC p;\n\tLPWSTR  lpwProcName;\n\n\tlpwProcName = wce_mbtowc( lpProcName );\n\tp = GetProcAddressW( hModule, lpwProcName );\n\tfree( lpwProcName );\n\treturn p;\n}\n#endif \n\nchar * GetCommandLineA(void)\n{\n\treturn _commandLine;\n}\n\n/* this is not Win32API. GetCommandLineA helper. */\nvoid wce_SetCommandLine(LPCWSTR wcmd)\n{\n\tchar* acmd;\n\n\tacmd = wce_wctomb( wcmd );\n\t_commandLine = (char*)malloc( strlen(acmd)+5 );\n\tsprintf( _commandLine, \"ruby %s\", acmd );\n\tfree(acmd);\n}\n\n/* this is not Win32API. GetCommandLineA helper. */\nvoid wce_FreeCommandLine(void)\n{\n\tfree(_commandLine);\n\t_commandLine = NULL;\n}\n\n/* I have no idea how to replace this. */\nBOOL GetProcessTimes(HANDLE hprocess,\n\tLPFILETIME lpCreationTime, LPFILETIME lpExitTime,\n\tLPFILETIME lpKernelTime, LPFILETIME lpUserTime) \n{\n\treturn 0;\n}\n\n/* --------------  file attributes functions. ------------------- */\nDWORD GetFileAttributesA(LPCSTR lpFileName)\n{\n\tLPWSTR lpwFileName;\n\tDWORD dw;\n\n\tlpwFileName = wce_mbtowc(lpFileName);\n\tdw = GetFileAttributesW(lpwFileName);\n\tfree(lpwFileName);\n\treturn dw;\n}\n\nBOOL SetFileAttributesA(\n\tLPCSTR lpFileName, DWORD attributes) \n{\n\tLPWSTR lpwFileName;\n\tBOOL b;\n\n\tlpwFileName = wce_mbtowc(lpFileName);\n\tb = SetFileAttributesW(lpwFileName, attributes);\n\tfree(lpwFileName);\n\treturn b;\n}\n\n/* ---------------  move and remove functions. ------------------- */\nBOOL MoveFileA(LPCSTR fn1, LPCSTR fn2)\n{\n\tLPWSTR wfn1, wfn2;\n\tBOOL b;\n\n\twfn1 = wce_mbtowc(fn1);\n\twfn2 = wce_mbtowc(fn2);\n\tb = MoveFileW(wfn1, wfn2);\n\tfree(wfn1);\n\tfree(wfn2);\n\treturn 0;\n}\n\nBOOL MoveFileEx(LPCSTR oldname, LPCSTR newname, DWORD dwFlags)\n{\n\tLPWSTR woldname, wnewname;\n\tBOOL b;\n\n\twoldname = wce_mbtowc(oldname);\n\twnewname = wce_mbtowc(newname);\n\n\tif( (dwFlags&MOVEFILE_REPLACE_EXISTING)!=0 )\n\t\tDeleteFileW( wnewname );\n\n\tb = MoveFileW( woldname, wnewname );\n\n\tfree(woldname);\n\tfree(wnewname);\n\n\treturn b;\n}\n\nBOOL DeleteFileA(LPCSTR path)\n{ \n\tLPWSTR wpath;\n\tBOOL b;\n\n\twpath = wce_mbtowc(path);\n\tb = DeleteFileW(wpath);\n\tfree(wpath);\n\treturn 0;\n}\n\n/* --------------- EnvironmentVariable functions. ----------------- */\nDWORD GetEnvironmentVariable(\n\tLPCSTR name, LPSTR value, DWORD size)\n{\n\t/* use registry instead of \"environment valuable\". */\n\tHKEY\thk;\n\tLONG\tlret;\n\tLPBYTE\tlpData;\n\tDWORD\tdwType=REG_SZ, cbData;\n\tTCHAR   buf[MAX_PATH]={0};\n\tLPWSTR  wname;\n\tLPSTR   avalue;\n\n\tlret = RegOpenKeyEx( HKEY_LOCAL_MACHINE,\n\t\t\t\t_T(\"Software\\\\ruby_mswince\"),\n\t\t\t\t0, KEY_QUERY_VALUE, &hk );\n\n\tif ( lret != ERROR_SUCCESS )\n\t{\n\t\tstrcpy( value, \"\" );\n\t\treturn 0;\n\t}\n\n\tlpData = (LPBYTE)buf;\n\tcbData = MAX_PATH*sizeof(*buf);\n\twname  = wce_mbtowc( name );\n\n\tlret = RegQueryValueEx( hk, wname,\n\t\tNULL, &dwType, lpData, &cbData );\n\tRegCloseKey( hk );\n\n\tif ( lret != ERROR_SUCCESS )\n\t{\n\t\tstrcpy( value, \"\" );\n\t\tfree( wname );\n\t\treturn 0;\n\t}\n\n\tavalue = wce_wctomb( (LPCTSTR)lpData );\n\tstrcpy( value, avalue );\n\tfree( avalue );\n\tfree( wname );\n\n\treturn strlen(value);\n}\n\nBOOL SetEnvironmentVariable(LPCSTR name, LPCSTR value)\n{\n\t/* use registry instead of \"environment valuable\". */\n\tHKEY\thk;\n\tLONG\tlret;\n\tLPBYTE\tlpData;\n\tDWORD\tret, dwType=REG_SZ, cbData;\n\tLPWSTR  wname, wvalue;\n\n\tlret = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\n\t\t\t_T(\"Software\\\\ruby_mswince\"),\n\t\t\t0, _T(\"\"), 0,\n\t\t\t0, NULL, &hk, &ret );\n\tif( lret != ERROR_SUCCESS )\n\t\treturn FALSE;\n\n\twname  = wce_mbtowc(name);\n\twvalue = wce_mbtowc(value);\n\n\tlpData = (LPBYTE)wvalue;\n\tcbData = (wcslen(wvalue) + 1) * sizeof(*wvalue);\n\tlret = RegSetValueEx( hk, wname,\n\t\t0, dwType, lpData, cbData );\n\tRegCloseKey( hk );\n\tfree(wname);\n\tfree(wvalue);\n\treturn lret == ERROR_SUCCESS;\n}\n\nLPVOID GetEnvironmentStrings(VOID)\n{\n\treturn NULL;\n}\n\nBOOL FreeEnvironmentStrings(LPSTR lpszEnvironmentBlock)\n{\n\treturn FALSE;\n}\n\n/* DuplicateHandle, LockFile, etc... */\n/* I have no idea...  */\nBOOL GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,\n\t\tDWORD dwProcessGroupID)\n{\n\treturn 0;\n}\n\nBOOL DuplicateHandle(\n\tHANDLE source_process, HANDLE source,\n\tHANDLE dest_process, HANDLE *dest,\n\tDWORD access, BOOL inherit, DWORD options)\n{\n\treturn 0;\n}\n\nBOOL LockFile(HANDLE hFile,\n\tDWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,\n\tDWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)\n{\n\treturn FALSE;\n}\n\nBOOL LockFileEx(HANDLE hFile,\n\tDWORD dwFlags, DWORD dwReserved,\n\tDWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,\n\tLPOVERLAPPED lpOverlapped)\n{\n\treturn FALSE;\n}\n\nBOOL UnlockFile( HFILE hFile,\n\tDWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,\n\tDWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)\n{\n\treturn FALSE;\n}\n\nBOOL UnlockFileEx(HANDLE hFile,\n\tDWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,\n\tDWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)\n{\n\treturn FALSE;\n}\n\n/* --------------------- etc, etc, etc... ----------------------- */\nBOOL GetVersionExA(OSVERSIONINFOA *v)\n{\n\tOSVERSIONINFOW wv;\n\tBOOL b;\n\tLPSTR mb;\n\n\tb = GetVersionExW(&wv);\n\tmb = wce_wctomb(wv.szCSDVersion);\n\n\tstrcpy( v->szCSDVersion, mb );\n\tfree(mb);\n\treturn b;\n}\n\nDWORD WaitForMultipleObjectsEx(DWORD count,\n\tconst HANDLE *handles, BOOL wait_all,\n\tDWORD timeout, BOOL alertable)\n{\n\treturn WaitForMultipleObjects(\n\t\tcount, handles, wait_all,\n\t\ttimeout );\n}\n\nBOOL CreateProcessA(LPCSTR appname, LPCSTR commandline,\n\tLPSECURITY_ATTRIBUTES att, LPSECURITY_ATTRIBUTES threadatt,\n\tBOOL bOpt, DWORD dwFlag, LPVOID lpEnv, LPSTR dir,\n\tLPSTARTUPINFO lpsi, LPPROCESS_INFORMATION lppi)\n{\n\tLPWSTR wappname, wcommandline, wdir;\n\tBOOL b;\n\n\twappname     = wce_mbtowc(appname);\n\twcommandline = wce_mbtowc(commandline);\n\twdir         = wce_mbtowc(dir);\n\n\tb = CreateProcessW(wappname, wcommandline,\n\t\t\tatt, threadatt, bOpt, dwFlag, lpEnv,\n\t\t\twdir, lpsi, lppi);\n\n\tfree(wappname);\n\tfree(wcommandline);\n\tfree(wdir);\n\n\treturn b;\n}\n\nHANDLE CreateEventA(SECURITY_ATTRIBUTES *sa, \n\tBOOL manual_reset, BOOL initial_state, LPCSTR name)\n{\n\tHANDLE h;\n\tLPWSTR wname;\n\n\twname = wce_mbtowc(name);\n\th = CreateEventW(sa, manual_reset,\n\t\tinitial_state, wname);\n\tfree(wname);\n\n\treturn h;\n}\n\nDWORD FormatMessageA(DWORD dwFlags, LPCVOID lpSource, \n\tDWORD dwMessageId, DWORD dwLanguageId, LPSTR lpBuffer, \n\tDWORD nSize, va_list* args)\n{\n\tDWORD dw;\n\tLPWSTR lpWBuffer;\n\n\tlpWBuffer = wce_mbtowc(lpBuffer);\n\tdw = FormatMessageW( dwFlags, lpSource,\n\t\t\tdwMessageId, dwLanguageId,\n\t\t\tlpWBuffer, nSize, (va_list*)args );\n\tfree(lpWBuffer);\n\treturn dw;\n}\n\n/*---------------- FindFirstFile, FindNextFile ------------------ */\nHANDLE FindFirstFileA(LPCSTR path,\n\t\t\tWIN32_FIND_DATAA *data)\n{\n\tLPWSTR wpath;\n\tLPSTR  mb;\n\tHANDLE h;\n\tWIN32_FIND_DATAW wdata;\n\n\twpath = wce_mbtowc(path);\n\th = FindFirstFileW( wpath, &wdata );\n\tfree(wpath);\n\t\n\tmb = wce_wctomb( wdata.cFileName );\n\tstrcpy( data->cFileName, mb );\n\tfree(mb);\n\n\treturn h;\n}\n\nBOOL FindNextFileA(HANDLE handle,\n\tWIN32_FIND_DATAA *data)\n{\n\tBOOL b;\n\tWIN32_FIND_DATAW wdata;\n\tLPSTR mb1;\n\n\tb = FindNextFileW(handle, &wdata);\n\n\tmb1 = wce_wctomb( wdata.cFileName );\n\tstrcpy( data->cFileName, mb1 );\n\tfree(mb1);\n\n\treturn b;\n}\n\n/* CreateFile doesn't support SECURITY_ATTRIBUTES in WinCE. */\n/* it must be NULL. */\nHANDLE CreateFileA(LPCSTR filename, DWORD access,\n\tDWORD sharing, LPSECURITY_ATTRIBUTES sa,\n\tDWORD creation, DWORD attributes, HANDLE template)\n{\n\tLPWSTR wfilename;\n\tHANDLE h;\n\n\twfilename = wce_mbtowc(filename);\n\th = CreateFileW(wfilename, access, sharing,\n\t\t\tNULL, creation, 0, NULL);\n\tfree(wfilename);\n\n\treturn 0;\n}\n\n/* ---------------- CharNext, CharPrev. ---------------------*/\nLPSTR CharNextA(LPCSTR a)\n{\n\tchar *p=(char *)a;\n\tif( TRUE==IsDBCSLeadByteEx(CP_ACP, (BYTE)*a) )\n\t\tp+=2;\n\telse\n\t\tp++;\n\n\treturn p;\n}\n\nLPSTR CharPrevA(LPCSTR start, LPCSTR ptr)\n{\n\tif( start==ptr ) return (LPSTR)start;\n\telse if( start+1==ptr ) return (LPSTR)start;\n\telse if( TRUE==IsDBCSLeadByteEx(CP_ACP, (BYTE)*(ptr-2)) )\n\t\treturn (LPSTR)(ptr-2);\n\telse\n\t\treturn (LPSTR)(ptr-1);\n}\n\n/* WinCE doesn't have \"drives\". */\nDWORD GetLogicalDrives(VOID)\n{\n\treturn 0;\n}\n\n/* WinCE doesn't have \"user name\". */\nBOOL GetUserName(LPSTR lpBuffer, LPDWORD nSize)\n{\n\treturn 0;\n}\n\n/*------------------- LoadLibrary -----------------------*/\nHINSTANCE LoadLibraryA(LPCSTR libname)\n{\n\tHINSTANCE h;\n\tLPWSTR wlibname;\n\n\t// if starts \".\\\", replace current directory.\n//\twlibname = wce_replaceRelativeDir(libname);\n\n\twlibname = wce_mbtowc(libname);\n\th = LoadLibraryW(wlibname);\n\tfree(wlibname);\n\treturn h;\n}\n\nHINSTANCE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile,\n\t\t\tDWORD dwFlags)\n{\n\tHINSTANCE h;\n\tLPWSTR wlibname;\n\n\twlibname = wce_mbtowc(lpLibFileName);\n//\twlibname = wce_replaceRelativeDir(lpLibFileName);\n\n#if _WIN32_WCE < 300\n\th = LoadLibraryW(wlibname);\n#else\n\th = LoadLibraryExW(wlibname, hFile, dwFlags);\n#endif\n\tfree(wlibname);\n\treturn h;\n}\n\n/* WinCE doesn't have \"CreatePipe\". */\nBOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe,\n\tLPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)\n{\n\treturn FALSE;\n}\n\n/* WinCE doesn't have \"Standard Devices\". */\nHANDLE GetStdHandle(DWORD nStdHandle)\n{\n\treturn NULL;\n}\n\nBOOL SetStdHandle(DWORD nStdHandle, HANDLE h)\n{\n\treturn FALSE;\n}\n\n#if _WIN32_WCE < 300\nVOID ZeroMemory(PVOID p, DWORD length)\n{\n\tmemset(p,0,length);\n}\n#endif\n\n\n/* need in ruby/io.c. */\nint ReadDataPending()\n{\n\treturn 0;\n}\n\n/*---------------- helper functions. ---------------------------- */\nFILE *wce_fopen( const char *fname, const char *mode )\n{\n\tTCHAR* tfname = wce_replaceRelativeDir(fname);\n\tTCHAR* tmode = wce_mbtowc(mode);\n\tFILE* fp = _tfopen(tfname, tmode);\n\tfree(tfname); free(tmode);\n\treturn fp;\n}\n\nvoid wce_SetCurrentDir()\n{\n\tWCHAR tbuf[MAX_PATH+1]={0};\n\tWCHAR *tp;\n\tchar *buf;\n\n\tGetModuleFileNameW( NULL, tbuf, MAX_PATH );\n\ttp = _tcsrchr( tbuf, '\\\\' );\n\tif( tp!=NULL ) *tp=_T('\\0');\n\tbuf = wce_wctomb(tbuf);\n\tstrcpy( _currentdir, buf );\n\tfree(buf);\n}\n\nTCHAR *wce_replaceRelativeDir(const char* str)\n{\n\tTCHAR *tbuf;\n\n\tif( 2<=strlen(str) && str[0]=='.' &&\n\t\t(str[1]=='/' || str[1]=='\\\\') )\n\t{\n\t\tchar *buf;\n\t\tint len = strlen(str) + strlen(_currentdir);\n\t\tbuf = malloc( len+1 );\n\t\tsprintf(buf, \"%s%s\", _currentdir, &str[1]);\n\t\ttbuf = wce_mbtowc(buf);\n\t\tfree(buf);\n\t}\n\telse\n\t\ttbuf = wce_mbtowc(str);\n\treturn tbuf;\n}\n\n/* char -> wchar_t */\nwchar_t* wce_mbtowc(const char* a)\n{\n\tint length;\n\twchar_t *wbuf;\n\n\tlength = MultiByteToWideChar(CP_ACP, 0, \n\t\ta, -1, NULL, 0);\n\twbuf = (wchar_t*)malloc( (length+1)*sizeof(wchar_t) );\n\tMultiByteToWideChar(CP_ACP, 0,\n\t\ta, -1, wbuf, length);\n\n\treturn wbuf;\n}\n\n/* wchar_t -> char */\nchar* wce_wctomb(const wchar_t* w)\n{\n\tDWORD charlength;\n\tchar* pChar;\n\n\tcharlength = WideCharToMultiByte(CP_ACP, 0, w,\n\t\t\t\t\t-1, NULL, 0, NULL, NULL);\n\tpChar = (char*)malloc(charlength+1);\n\tWideCharToMultiByte(CP_ACP, 0, w,\n\t\t-1, pChar, charlength, NULL, NULL);\n\n\treturn pChar;\n}\n"
  },
  {
    "path": "wince/wince.h",
    "content": "\n#ifndef _EXT_CE_\n#define _EXT_CE_\n\n/* unique difinition in wince platform. */\n\n#ifndef _MIPS_\n  #define CONTEXT_FLOATING_POINT  0x00000002L\n#endif\n\n/* LockFile difinition. */\n#define LOCKFILE_FAIL_IMMEDIATELY   0x00000001\n#define LOCKFILE_EXCLUSIVE_LOCK     0x00000002\n\n/* Dual Mode difinition. */\n#define STARTF_USESHOWWINDOW    0x00000001\n#define STARTF_USESIZE          0x00000002\n#define STARTF_USEPOSITION      0x00000004\n#define STARTF_USECOUNTCHARS    0x00000008\n#define STARTF_USEFILLATTRIBUTE 0x00000010\n#define STARTF_RUNFULLSCREEN    0x00000020\n#define STARTF_FORCEONFEEDBACK  0x00000040\n#define STARTF_FORCEOFFFEEDBACK 0x00000080\n#define STARTF_USESTDHANDLES    0x00000100\n/* #define STARTF_USEHOTKEY        0x00000200 */\n\n#define STD_INPUT_HANDLE    (DWORD)-10\n#define STD_OUTPUT_HANDLE   (DWORD)-11\n#define STD_ERROR_HANDLE    (DWORD)-12\n\n#define NORMAL_PRIORITY_CLASS       0x00000020\n#define IDLE_PRIORITY_CLASS         0x00000040\n#define HIGH_PRIORITY_CLASS         0x00000080\n#define REALTIME_PRIORITY_CLASS     0x00000100\n\n\n/* WINSOCK.H? */\n#define SO_SYNCHRONOUS_NONALERT 0x20\n\n/* MoveFileEx definition. */\n#define MOVEFILE_REPLACE_EXISTING       0x00000001\n/*\n#define MOVEFILE_COPY_ALLOWED           0x00000002\n#define MOVEFILE_DELAY_UNTIL_REBOOT     0x00000004\n#define MOVEFILE_WRITE_THROUGH          0x00000008\n#define MOVEFILE_CREATE_HARDLINK        0x00000010\n#define MOVEFILE_FAIL_IF_NOT_TRACKABLE  0x00000020\n*/\n\n#define _fgetc fgetc\n#define _fputc fputc\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Win32 API redifinition. */\n\n#undef GetCommandLine\n#define GetCommandLine GetCommandLineA\n\n#undef SetFileAttributes\n#define SetFileAttributes SetFileAttributesA\n\n#undef GetFileAttributes\n#define GetFileAttributes GetFileAttributesA\n\n#undef FormatMessage\n#define FormatMessage FormatMessageA\n\n#undef GetModuleFileName\n#define GetModuleFileName GetModuleFileNameA\n\n#undef CreateFile\n#define CreateFile CreateFileA\n\n#undef MoveFile\n#define MoveFile MoveFileA\n\n#undef DeleteFile\n#define DeleteFile DeleteFileA\n\n#undef CreateProcess\n#define CreateProcess CreateProcessA\n\n#undef CharNext\n#define CharNext CharNextA\n\n#undef CharPrev\n#define CharPrev CharPrevA\n\n#undef WIN32_FIND_DATA\n#define WIN32_FIND_DATA WIN32_FIND_DATAA\n\n#undef FindFirstFile\n#define FindFirstFile FindFirstFileA\n\n#undef FindNextFile\n#define FindNextFile FindNextFileA\n\n/* stdio.c */\nFILE *freopen(const char *filename, const char *mode, FILE *file);\nFILE *fdopen( int handle, const char *mode );\n\n//#define fdopen _fdopen\n\n/* stdlib.c */\nchar *getenv(const char *charstuff);\nchar *_fullpath(char *absPath, const char *relPath, size_t maxLength);\n\n/* string.c */\nchar *strdup(const char * str);\n/* char *strerror(int errno); */\nint strnicmp( const char *s1, const char *s2, size_t count );\n\n//#define strnicmp _strnicmp\n#define stricmp _stricmp\n\n/* for win32.c */\nFARPROC GetProcAddressX(HMODULE hModule, LPCSTR lpProcName);\n\nBOOL MoveFileEx(LPCSTR oldname, LPCSTR newname, DWORD dwFlags);\nBOOL DuplicateHandle(\n\tHANDLE source_process, HANDLE source,\n\tHANDLE dest_process, HANDLE *dest,\n\tDWORD access, BOOL inherit, DWORD options);\nBOOL LockFile(HANDLE hFile,\n\tDWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,\n\tDWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh);\nBOOL LockFileEx(HANDLE hFile,\n\tDWORD dwFlags, DWORD dwReserved,\n\tDWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,\n\tLPOVERLAPPED lpOverlapped);\nBOOL UnlockFile( HFILE hFile,\n\tDWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,\n\tDWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh);\nBOOL UnlockFileEx(HANDLE hFile,\n\tDWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,\n\tDWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped);\nBOOL GetUserName(LPSTR lpBuffer, LPDWORD nSize);\nBOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe,\n\tLPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize);\nHANDLE GetStdHandle(DWORD nStdHandle);\nBOOL SetStdHandle(DWORD nStdHandle, HANDLE h);\nDWORD GetLogicalDrives(VOID);\nDWORD WaitForMultipleObjectsEx(DWORD count,\n\tconst HANDLE *handles, BOOL wait_all,\n\tDWORD timeout, BOOL alertable);\nDWORD GetEnvironmentVariable(LPCSTR name, LPSTR value, DWORD size);\nLPVOID GetEnvironmentStrings(VOID);\nBOOL FreeEnvironmentStrings(LPSTR lpszEnvironmentBlock);\nBOOL GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,\n\t\tDWORD dwProcessGroupID);\nBOOL GetProcessTimes(HANDLE hprocess,\n\tLPFILETIME lpCreationTime, LPFILETIME lpExitTime,\n\tLPFILETIME lpKernelTime, LPFILETIME lpUserTime);\n\n/* char -> wchar_t, wchar_t -> char */\nwchar_t* wce_mbtowc(const char* a);\nchar*    wce_wctomb(const wchar_t* w);\n/* other helpers. */\nvoid wce_SetCommandLine(LPCWSTR wcmd);\nvoid wce_FreeCommandLine(void);\nTCHAR *wce_replaceRelativeDir(const char* str);\nvoid wce_SetCurrentDir();\n\n#if _WIN32_WCE < 300\n  /* for Handheld PC Pro. */\n  char *strrchr( const char *p, int c );\n  int stricmp( const char *p1, const char *p2 );\n  VOID ZeroMemory(PVOID p, DWORD length);\n\n  #define isascii(c) ( (c>=0x00&&c<=0x7f)?1:0 )\n  #define isspace(c) ( ((c>=0x09&&c<=0x0d)||c==0x20)?1:0 )\n  #define isdigit(c) ( (c>=0x00&&c<=0x09)?1:0 )\n  #define isupper(c) ( (c>='A'&&c<='Z')?1:0 )\n  #define isalpha(c) ( ((c>='A'&&c<='Z')||(c>='a'&&c<='z'))?1:0 )\n  #define isprint(c) ( (c>=0x20&&c<=0x7e)?1:0 )\n  #define isalnum(c) ( (isalpha(c)||isdigit(c))?1:0 )\n  #define iscntrl(c) ( ((c>=0x00&&c<=0x1f)||c==0x7f)?1:0 )\n  #define islower(c) ( (c>='a'&&c<='z')?1:0 )\n  #define ispunct(c) ( !(isalnum(c)||isspace(c))?1:0 )\n  #define isxdigit(c) ( ((c>=0&&c<=9)||(c>='A'&&c<='F')||(c>='a'&&c<='f'))?1:0 )\n#endif\n\n#ifdef __cplusplus\n};\n#endif\n\n\n#endif /* _EXT_CE_ */\n"
  },
  {
    "path": "wince/wincemain.c",
    "content": "#include <windows.h>\n#include <stdio.h>\n#include \"wince.h\"\n\nextern int main(int, char**, char**);\n\n\nint WINAPI\nWinMain(HINSTANCE current, HINSTANCE prev, LPWSTR wcmd, int showcmd)\n{\n\t/* wchar_t -> char */\n\twce_SetCommandLine(wcmd);\n\n\twce_SetCurrentDir();\n\n\t/* main. */\n    return main(0, NULL, NULL);\n}\n\n"
  },
  {
    "path": "wince/wincon.h",
    "content": "\n#ifndef _WINCON_H_\n#define _WINCON_H_\n\n#define CTRL_C_EVENT        0\n\n#endif\n"
  },
  {
    "path": "wince/winsock2.c",
    "content": "/***************************************************************\n  winsock2.c\n***************************************************************/\n\n//#define _WINSOCK2_C_DEBUG_MAIN_\n\n#include <windows.h>\n#include \"wince.h\"\n#ifdef _WINSOCK2_C_DEBUG_MAIN_\n  #include <winsock.h>\n#endif\n\n#ifndef _WINSOCK2_C_DEBUG_MAIN_\nstruct  servent{\n\tchar*  s_name;     /* official service name */\n\tchar** s_aliases;  /* alias list */\n\tshort  s_port;     /* port # */\n\tchar*  s_proto;    /* protocol to use */\n};\nstruct  protoent{\n\tchar*  p_name;     /* official protocol name */\n\tchar** p_aliases;  /* alias list */\n\tshort  p_proto;    /* protocol # */\n};\n#endif\n\nstruct sproto{\n\tshort num;\n\tchar name[10];\n};\nstruct sserv{\n\tshort num;\n\tchar protoname[10];\n\tchar servname[20];\n};\n\nstatic struct sproto _proto_table[11]={\n\t0,  \"ip\",\n\t1,  \"icmp\",\n\t3,  \"ggp\",\n\t6,  \"tcp\",\n\t8,  \"egp\",\n\t12, \"pup\",\n\t17, \"udp\",\n\t20, \"hmp\",\n\t22, \"xns-idp\",\n\t27, \"rdp\",\n\t66, \"rvd\",\n};\n\nstatic struct sserv _serv_table[142]={\n\t7, \"tcp\", \"echo\",\n\t7, \"udp\", \"echo\",\n\t9, \"tcp\", \"discard\",\n\t9, \"udp\", \"discard\",\n\t11, \"tcp\", \"systat\",\n\t11, \"udp\", \"systat\",\n\t13, \"tcp\", \"daytime\",\n\t13, \"udp\", \"daytime\",\n\t15, \"tcp\", \"netstat\",\n\t17, \"tcp\", \"qotd\",\n\t17, \"udp\", \"qotd\",\n\t19, \"tcp\", \"chargen\",\n\t19, \"udp\", \"chargen\",\n\t20, \"tcp\", \"ftp-data\",\n\t21, \"tcp\", \"ftp\",\n\t23, \"tcp\", \"telnet\",\n\t25, \"tcp\", \"smtp\",\n\t37, \"tcp\", \"time\",\n\t37, \"udp\", \"time\",\n\t39, \"udp\", \"rlp\",\n\t42, \"tcp\", \"name\",\n\t42, \"udp\", \"name\",\n\t43, \"tcp\", \"whois\",\n\t53, \"tcp\", \"domain\",\n\t53, \"udp\", \"domain\",\n\t53, \"tcp\", \"nameserver\",\n\t53, \"udp\", \"nameserver\",\n\t57, \"tcp\", \"mtp\",\n\t67, \"udp\", \"bootp\",\n\t69, \"udp\", \"tftp\",\n\t77, \"tcp\", \"rje\",\n\t79, \"tcp\", \"finger\",\n\t87, \"tcp\", \"link\",\n\t95, \"tcp\", \"supdup\",\n\t101, \"tcp\", \"hostnames\",\n\t102, \"tcp\", \"iso-tsap\",\n\t103, \"tcp\", \"dictionary\",\n\t103, \"tcp\", \"x400\",\n\t104, \"tcp\", \"x400-snd\",\n\t105, \"tcp\", \"csnet-ns\",\n\t109, \"tcp\", \"pop\",\n\t109, \"tcp\", \"pop2\",\n\t110, \"tcp\", \"pop3\",\n\t111, \"tcp\", \"portmap\",\n\t111, \"udp\", \"portmap\",\n\t111, \"tcp\", \"sunrpc\",\n\t111, \"udp\", \"sunrpc\",\n\t113, \"tcp\", \"auth\",\n\t115, \"tcp\", \"sftp\",\n\t117, \"tcp\", \"path\",\n\t117, \"tcp\", \"uucp-path\",\n\t119, \"tcp\", \"nntp\",\n\t123, \"udp\", \"ntp\",\n\t137, \"udp\", \"nbname\",\n\t138, \"udp\", \"nbdatagram\",\n\t139, \"tcp\", \"nbsession\",\n\t144, \"tcp\", \"NeWS\",\n\t153, \"tcp\", \"sgmp\",\n\t158, \"tcp\", \"tcprepo\",\n\t161, \"tcp\", \"snmp\",\n\t162, \"tcp\", \"snmp-trap\",\n\t170, \"tcp\", \"print-srv\",\n\t175, \"tcp\", \"vmnet\",\n\t315, \"udp\", \"load\",\n\t400, \"tcp\", \"vmnet0\",\n\t500, \"udp\", \"sytek\",\n\t512, \"udp\", \"biff\",\n\t512, \"tcp\", \"exec\",\n\t513, \"tcp\", \"login\",\n\t513, \"udp\", \"who\",\n\t514, \"tcp\", \"shell\",\n\t514, \"udp\", \"syslog\",\n\t515, \"tcp\", \"printer\",\n\t517, \"udp\", \"talk\",\n\t518, \"udp\", \"ntalk\",\n\t520, \"tcp\", \"efs\",\n\t520, \"udp\", \"route\",\n\t525, \"udp\", \"timed\",\n\t526, \"tcp\", \"tempo\",\n\t530, \"tcp\", \"courier\",\n\t531, \"tcp\", \"conference\",\n\t531, \"udp\", \"rvd-control\",\n\t532, \"tcp\", \"netnews\",\n\t533, \"udp\", \"netwall\",\n\t540, \"tcp\", \"uucp\",\n\t543, \"tcp\", \"klogin\",\n\t544, \"tcp\", \"kshell\",\n\t550, \"udp\", \"new-rwho\",\n\t556, \"tcp\", \"remotefs\",\n\t560, \"udp\", \"rmonitor\",\n\t561, \"udp\", \"monitor\",\n\t600, \"tcp\", \"garcon\",\n\t601, \"tcp\", \"maitrd\",\n\t602, \"tcp\", \"busboy\",\n\t700, \"udp\", \"acctmaster\",\n\t701, \"udp\", \"acctslave\",\n\t702, \"udp\", \"acct\",\n\t703, \"udp\", \"acctlogin\",\n\t704, \"udp\", \"acctprinter\",\n\t704, \"udp\", \"elcsd\",\n\t705, \"udp\", \"acctinfo\",\n\t706, \"udp\", \"acctslave2\",\n\t707, \"udp\", \"acctdisk\",\n\t750, \"tcp\", \"kerberos\",\n\t750, \"udp\", \"kerberos\",\n\t751, \"tcp\", \"kerberos_master\",\n\t751, \"udp\", \"kerberos_master\",\n\t752, \"udp\", \"passwd_server\",\n\t753, \"udp\", \"userreg_server\",\n\t754, \"tcp\", \"krb_prop\",\n\t888, \"tcp\", \"erlogin\",\n\t1109, \"tcp\", \"kpop\",\n\t1167, \"udp\", \"phone\",\n\t1524, \"tcp\", \"ingreslock\",\n\t1666, \"udp\", \"maze\",\n\t2049, \"udp\", \"nfs\",\n\t2053, \"tcp\", \"knetd\",\n\t2105, \"tcp\", \"eklogin\",\n\t5555, \"tcp\", \"rmt\",\n\t5556, \"tcp\", \"mtb\",\n\t9535, \"tcp\", \"man\",\n\t9536, \"tcp\", \"w\",\n\t9537, \"tcp\", \"mantst\",\n\t10000, \"tcp\", \"bnews\",\n\t10000, \"udp\", \"rscs0\",\n\t10001, \"tcp\", \"queue\",\n\t10001, \"udp\", \"rscs1\",\n\t10002, \"tcp\", \"poker\",\n\t10002, \"udp\", \"rscs2\",\n\t10003, \"tcp\", \"gateway\",\n\t10003, \"udp\", \"rscs3\",\n\t10004, \"tcp\", \"remp\",\n\t10004, \"udp\", \"rscs4\",\n\t10005, \"udp\", \"rscs5\",\n\t10006, \"udp\", \"rscs6\",\n\t10007, \"udp\", \"rscs7\",\n\t10008, \"udp\", \"rscs8\",\n\t10009, \"udp\", \"rscs9\",\n\t10010, \"udp\", \"rscsa\",\n\t10011, \"udp\", \"rscsb\",\n\t10012, \"tcp\", \"qmaster\",\n\t10012, \"udp\", \"qmaster\",\n};\n\n/* WinCE doesn't have /etc/protocols. */\nstruct protoent* getprotobyname(const char* name)\n{\n\tstatic struct protoent pe;\n\tint i;\n\tint len = strlen(name);\n\n\tmemset( &pe, 0, sizeof(struct protoent) );\n\n\tfor(i=0; i<9; i++)\n\t{\n\t\tif( 0==strnicmp(_proto_table[i].name, name, len) )\n\t\t{\n\t\t\tpe.p_name = _proto_table[i].name;\n\t\t\tpe.p_proto= _proto_table[i].num;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn &pe;\n}\n\nstruct protoent* getprotobynumber(int proto)\n{\n\tstatic struct protoent pe={0};\n\tint i;\n\n\tmemset( &pe, 0, sizeof(struct protoent) );\n\n\tfor(i=0; i<9; i++)\n\t{\n\t\tif( proto == _proto_table[i].num )\n\t\t{\n\t\t\tpe.p_name = _proto_table[i].name;\n\t\t\tpe.p_proto= _proto_table[i].num;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn &pe;\n}\n\n/* WinCE doesn't have /etc/services. */\nstruct servent* getservbyname(const char* name,\n                              const char* proto)\n{\n\tstatic struct servent se;\n\tint i;\n\tint slen = strlen(name), plen = strlen(proto);\n\n\tmemset( &se, 0, sizeof(struct servent) );\n\n\tif( proto==NULL ) return NULL;\n\tif( 0!=strnicmp( proto, \"tcp\", 3 ) &&\n\t\t0!=strnicmp( proto, \"udp\", 3 ) )\n\t\treturn NULL;\n\n\tfor( i=0; i<142; i++ )\n\t{\n\t\tif( 0==strnicmp( name, _serv_table[i].servname, slen ) &&\n\t\t\t0==strnicmp( proto, _serv_table[i].protoname, plen ) )\n\t\t{\n\t\t\tchar hc, lc;\n\t\t\tse.s_name = _serv_table[i].servname;\n\t\t\tse.s_proto= _serv_table[i].protoname;\n\t\t\thc = (_serv_table[i].num&0xFF00)>>8;\n\t\t\tlc = _serv_table[i].num&0xFF;\n\t\t\tse.s_port = (lc<<8) + hc;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn &se;\n}\n\nstruct servent* getservbyport(int port, const char* proto)\n{\n\tstatic struct servent se;\n\tint i;\n\tint plen = strlen(proto);\n\tshort sport;\n\tchar  lc, hc;\n\n\thc = (port&0xFF00)>>8;\n\tlc = port&0xFF;\n\n\tsport = (lc<<8) + hc;\n\n\tmemset( &se, 0, sizeof(struct servent) );\n\n\tif( proto==NULL ) return NULL;\n\tif( 0!=strnicmp( proto, \"tcp\", 3 ) &&\n\t\t0!=strnicmp( proto, \"udp\", 3 ) )\n\t\treturn NULL;\n\n\tfor( i=0; i<142; i++ )\n\t{\n\t\tif( sport == _serv_table[i].num &&\n\t\t\t0==strnicmp( proto, _serv_table[i].protoname, plen ) )\n\t\t{\n\t\t\tse.s_name = _serv_table[i].servname;\n\t\t\tse.s_proto= _serv_table[i].protoname;\n\t\t\tse.s_port = port;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn &se;\n}\n\n\n#ifdef _WINSOCK2_C_DEBUG_MAIN_\n\nint main()\n{\n\tWORD wVersionRequested = MAKEWORD(1,1);\n\tWSADATA wsaData;\n\tint nErrorStatus;\n\tstruct protoent pe1, pe2;\n\tstruct servent se1, se2;\n\n\tnErrorStatus = WSAStartup(wVersionRequested, &wsaData);\n\tif(nErrorStatus != 0)\n\t\treturn -1;\n\n\tpe1 = *getprotobyname(\"UDP\");\n\tpe2 = *_getprotobyname(\"UDP\");\n\n//\tpe1 = *getprotobynumber(17);\n//\tpe2 = *_getprotobynumber(17);\n\n//\tse1 = *getservbyname(\"gateway\", \"tcp\");\n//\tse2 = *_getservbyname(\"gateway\", \"tcp\");\n\n\tse1 = *getservbyport(0x1327, \"tcp\");\n\tse2 = *_getservbyport(0x1327, \"tcp\");\n\n\tWSACleanup();\n\n\treturn 0;\n}\n\n#endif\n"
  },
  {
    "path": "x68/_dtos18.c",
    "content": "/*\n * PROJECT C Library, X68000 PROGRAMMING INTERFACE DEFINITION\n * --------------------------------------------------------------------\n * This file is written by the Project C Library Group,  and completely\n * in public domain. You can freely use, copy, modify, and redistribute\n * the whole contents, without this notice.\n * --------------------------------------------------------------------\n * $Id$\n */\n\n/* System headers */\n#include <stdlib.h>\n#include <sys/xstdlib.h>\n\n/*\n** ܴؿưѴƤʸˤ뤿ᡢŪˤ\n** ˳ǼǤޤǤȤǤʤäƺǹ\n** 18Ǥ롣\n*/\n\n/* File scope variables */\nstatic double _pos1[32] = {\n    1.0e+17,\t\t\t\t\t/* + 0 */\n    1.0e+18,\t\t\t\t\t/* + 1 */\n    1.0e+19,\t\t\t\t\t/* + 2 */\n    1.0e+20,\t\t\t\t\t/* + 3 */\n    1.0e+21,\t\t\t\t\t/* + 4 */\n    1.0e+22,\t\t\t\t\t/* + 5 */\n    1.0e+23,\t\t\t\t\t/* + 6 */\n    1.0e+24,\t\t\t\t\t/* + 7 */\n    1.0e+25,\t\t\t\t\t/* + 8 */\n    1.0e+26,\t\t\t\t\t/* + 9 */\n    1.0e+27,\t\t\t\t\t/* +10 */\n    1.0e+28,\t\t\t\t\t/* +11 */\n    1.0e+29,\t\t\t\t\t/* +12 */\n    1.0e+30,\t\t\t\t\t/* +13 */\n    1.0e+31,\t\t\t\t\t/* +14 */\n    1.0e+32,\t\t\t\t\t/* +15 */\n    1.0e+33,\t\t\t\t\t/* +16 */\n    1.0e+34,\t\t\t\t\t/* +17 */\n    1.0e+35,\t\t\t\t\t/* +18 */\n    1.0e+36,\t\t\t\t\t/* +19 */\n    1.0e+37,\t\t\t\t\t/* +20 */\n    1.0e+38,\t\t\t\t\t/* +21 */\n    1.0e+39,\t\t\t\t\t/* +22 */\n    1.0e+40,\t\t\t\t\t/* +23 */\n    1.0e+41,\t\t\t\t\t/* +24 */\n    1.0e+42,\t\t\t\t\t/* +25 */\n    1.0e+43,\t\t\t\t\t/* +26 */\n    1.0e+44,\t\t\t\t\t/* +27 */\n    1.0e+45,\t\t\t\t\t/* +28 */\n    1.0e+46,\t\t\t\t\t/* +29 */\n    1.0e+47,\t\t\t\t\t/* +30 */\n    1.0e+48,\t\t\t\t\t/* +31 */\n};\n\n/* File scope variables */\nstatic double _neg1[32] = {\n    1.0e+17,\t\t\t\t\t/* - 0 */\n    1.0e+16,\t\t\t\t\t/* - 1 */\n    1.0e+15,\t\t\t\t\t/* - 2 */\n    1.0e+14,\t\t\t\t\t/* - 3 */\n    1.0e+13,\t\t\t\t\t/* - 4 */\n    1.0e+12,\t\t\t\t\t/* - 5 */\n    1.0e+11,\t\t\t\t\t/* - 6 */\n    1.0e+10,\t\t\t\t\t/* - 7 */\n    1.0e+9,\t\t\t\t\t/* - 8 */\n    1.0e+8,\t\t\t\t\t/* - 9 */\n    1.0e+7,\t\t\t\t\t/* -10 */\n    1.0e+6,\t\t\t\t\t/* -11 */\n    1.0e+5,\t\t\t\t\t/* -12 */\n    1.0e+4,\t\t\t\t\t/* -13 */\n    1.0e+3,\t\t\t\t\t/* -14 */\n    1.0e+2,\t\t\t\t\t/* -15 */\n    1.0e+1,\t\t\t\t\t/* -16 */\n    1.0e+0,\t\t\t\t\t/* -17 */\n    1.0e-1,\t\t\t\t\t/* -18 */\n    1.0e-2,\t\t\t\t\t/* -19 */\n    1.0e-3,\t\t\t\t\t/* -20 */\n    1.0e-4,\t\t\t\t\t/* -21 */\n    1.0e-5,\t\t\t\t\t/* -22 */\n    1.0e-6,\t\t\t\t\t/* -23 */\n    1.0e-7,\t\t\t\t\t/* -24 */\n    1.0e-8,\t\t\t\t\t/* -25 */\n    1.0e-9,\t\t\t\t\t/* -26 */\n    1.0e-10,\t\t\t\t\t/* -27 */\n    1.0e-11,\t\t\t\t\t/* -28 */\n    1.0e-12,\t\t\t\t\t/* -29 */\n    1.0e-13,\t\t\t\t\t/* -30 */\n    1.0e-14,\t\t\t\t\t/* -31 */\n};\n\n/* File scope variables */\nstatic double _pos2[10] = {\n    1.0e+0,\t\t\t\t\t/* 000 */\n    1.0e+32,\t\t\t\t\t/* 001 */\n    1.0e+64,\t\t\t\t\t/* 010 */\n    1.0e+96,\t\t\t\t\t/* 011 */\n    1.0e+128,\t\t\t\t\t/* 100 */\n    1.0e+160,\t\t\t\t\t/* 101 */\n    1.0e+192,\t\t\t\t\t/* 110 */\n    1.0e+224,\t\t\t\t\t/* 111 */\n    1.0e+256,\t\t\t\t\t/* 1000 */\n    1.0e+288,\t\t\t\t\t/* 1001 */\n};\n\n/* File scope variables */\nstatic double _neg2[10] = {\n    1.0e-0,\t\t\t\t\t/* 000 */\n    1.0e-32,\t\t\t\t\t/* 001 */\n    1.0e-64,\t\t\t\t\t/* 010 */\n    1.0e-96,\t\t\t\t\t/* 011 */\n    1.0e-128,\t\t\t\t\t/* 100 */\n    1.0e-160,\t\t\t\t\t/* 101 */\n    1.0e-192,\t\t\t\t\t/* 110 */\n    1.0e-224,\t\t\t\t\t/* 111 */\n    1.0e-256,\t\t\t\t\t/* 1000 */\n    1.0e-288,\t\t\t\t\t/* 1001 */\n};\n\n/* File scope functions */\nstatic int _cmpd (double x, double y)\n{\n    unsigned long vx, vy, rc;\n    unsigned long *x_ptr = (unsigned long *) &x;\n    unsigned long *y_ptr = (unsigned long *) &y;\n\n    /* xλؿӥåȤФ */\n    vx = x_ptr[0] & 0x7FF00000;\n\n    /* yλؿӥåȤФ */\n    vy = y_ptr[0] & 0x7FF00000;\n\n    /* ؿӥåȤȽǤ */\n    if ((rc = vy - vx) != 0)\n\treturn rc;\n\n    /* xͭξ̥ӥåȤФ */\n    vx = x_ptr[0] & 0x000FFFFF;\n\n    /* yͭξ̥ӥåȤФ */\n    vy = y_ptr[0] & 0x000FFFFF;\n\n    /* ̥ӥåȤȽǤ */\n    if ((rc = vy - vx) != 0)\n\treturn rc;\n\n    /* xͭβ̥ӥåȤФ */\n    vx = x_ptr[1];\n\n    /* yͭβ̥ӥåȤФ */\n    vy = y_ptr[1];\n\n    /* ǽȽ */\n    return vy - vx;\n}\n\n/* Functions */\nvoid _dtos18 (double x, int *decpt, int *sign, char *buffer)\n{\n    short e2;\n    int e, n;\n\n    /* 2λؿ(Хʤξ) */\n    e2 = (((unsigned short *) &x)[0] & 0x7FF0U) >> 4;\n\n    /* ؿ0ξϡ0.0å */\n    if (e2 == 0) {\n\n\tunsigned long hi = ((unsigned long *) &x)[0] & 0xFFFFF;\n\tunsigned long lo = ((unsigned long *) &x)[1];\n\n\t/* ͭ0ɤ */\n\tif (hi == 0 && lo == 0) {\n\n\t    /* ʸ */\n\t    buffer[0] = '0';\n\n\t    /* NUL */\n\t    buffer[1] = '\\0';\n\n\t    /* ֤׻ */\n\t    *decpt = 1;\n\n\t    /* ׻ */\n\t    /* *sign = hi & 0x80000000UL; */\n\t    *sign = 0;\n\n\t    /*  */\n\t    return;\n\n\t}\n\n    }\n\n    /* 2λؿ˥Х򤫤Ƥ10λؿ򳵻 (approx. log10(2)) */\n    e = ((int) ((e2 - 1023) * 77)) >> 8;\n\n    /* ؿξ */\n    if (e >= 0) {\n\n\t/* ؿ32꾮ϥơ֥1 */\n\tif (e < 32)\n\t    x *= _neg1[e];\n\n\t/* ؿ32礭ϥơ֥1,2 */\n\telse\n\t    x *= _neg1[e & 31] * _neg2[e >> 5];\n\n    }\n\n    /* ؿξ */\n    else {\n\n\t/* ͤ׻ */\n\tn = -e;\n\n\t/* ͤ32꾮ϥơ֥1 */\n\tif (n < 32)\n\t    x *= _pos1[n];\n\n\t/* ͤ32礭ϥơ֥1,2 */\n\telse {\n\t    x *= _pos1[n & 31];\n\t    x *= _pos2[n >> 5];\n\t}\n\n    }\n\n    /* 󥰤᤹ */\n    if (_cmpd (1.0e+18, x) >= 0) {\n\te++;\n\tx *= 1.0e-1;\n    }\n\n    /* 󥰤­ʤɲ */\n    else if (_cmpd (1.0e+17, x) < 0) {\n\te--;\n\tx *= 1.0e+1;\n    }\n\n    /* ֤׻ */\n    *decpt = e + 1;\n\n    /* ׻ */\n    *sign = ((unsigned char *) &x)[0] & 0x80U;\n\n    /* ʸѴ */\n    _ulltoa ((unsigned long long) x, buffer);\n}\n"
  },
  {
    "path": "x68/_round.c",
    "content": "/*\n * PROJECT C Library, X68000 PROGRAMMING INTERFACE DEFINITION\n * --------------------------------------------------------------------\n * This file is written by the Project C Library Group,  and completely\n * in public domain. You can freely use, copy, modify, and redistribute\n * the whole contents, without this notice.\n * --------------------------------------------------------------------\n * $Id$\n */\n/* changed 1997.2.2 by K.Okabe */\n\n/* System headers */\n#include <stdlib.h>\n#include <sys/xstdlib.h>\n\n/* Functions */\nint _round (char *top, char *cur, int undig)\n{\n    char *ptr;\n\n    /* Ǹ夬5̤ʤݤɬפʤ */\n    if (undig < '5')\n\treturn 0;\n\n    /* ݥ */\n    ptr = cur - 1;\n\n    /* Ƭޤʤݤ */\n    while (ptr >= top) {\n\n\t/* 夬ʤФǽ */\n\tif (++(*ptr) <= '9')\n\t    return 0;\n\n\t/* η0᤹ */\n\t*ptr-- = '0';\n\n    }\n\n    /* Ƭ1ˤ */\n    *++ptr = '1';\n\n    /* 夬򤷤餻 */\n    return 1;\n}\n"
  },
  {
    "path": "x68/fconvert.c",
    "content": "/*\n * PROJECT C Library, X68000 PROGRAMMING INTERFACE DEFINITION\n * --------------------------------------------------------------------\n * This file is written by the Project C Library Group,  and completely\n * in public domain. You can freely use, copy, modify, and redistribute\n * the whole contents, without this notice.\n * --------------------------------------------------------------------\n * $Id$\n */\n/* changed 1997.2.3 by K.Okabe */\n\n/* System headers */\n#include <stdlib.h>\n#include <sys/xstdlib.h>\n\n/* Functions */\nchar *fconvert (double x, int ndigit, int *decpt, int *sign, char *buffer)\n{\n    int pos, n;\n    char *src, *dst;\n    char string[24];\n    int figup;\n\n    /* 18ʸѴ */\n    _dtos18 (x, decpt, sign, string);\n\n    /* ԡɥ쥹 */\n    src = string;\n\n    /* ԡ襢ɥ쥹 */\n    dst = buffer;\n\n    /* ֤ */\n    pos = *decpt;\n\n    /* ֤ʤ */\n    if (pos < 0) {\n\n\t/* ׻ */\n\tn = min (-pos, ndigit);\n\n\t/* Ƭ0 */\n\twhile (n-- > 0)\n\t    *dst++ = '0';\n\n\t/* ֤0ˤʤ */\n\t*decpt = 0;\n\n    }\n\n    /* ĤΥԡ */\n    n = ndigit + pos;\n\n    /* Ǽ˥ԡ */\n    while (n-- > 0) {\n\n\t/* ­ʤʬ0 */\n\tif (*src == '\\0') {\n\t    while (n-- >= 0)\n\t\t*dst++ = '0';\n\t    break;\n\t}\n\n\t/* Ѵʸ󤫤饳ԡ */\n\t*dst++ = *src++;\n\n    }\n\n    /* ݤ */\n    *decpt += (figup = _round (buffer, dst, *src));\n\n    /* 夬꤬0ɲä */\n    if (figup)\n\t*dst++ = '0';\n\n    /* ü NUL Ǥ */\n    *dst = '\\0';\n\n    /* ɥ쥹֤ */\n    return buffer;\n}\n"
  },
  {
    "path": "x68/select.c",
    "content": "/*\n * PROJECT C Library, X68000 PROGRAMMING INTERFACE DEFINITION\n * --------------------------------------------------------------------\n * This file is written by the Project C Library Group,  and completely\n * in public domain. You can freely use, copy, modify, and redistribute\n * the whole contents, without this notice.\n * --------------------------------------------------------------------\n * $Id$\n */\n\n#ifndef __IOCS_INLINE__\n#define __IOCS_INLINE__\n#define __DOS_INLINE__\n#define __DOS_DOSCALL__\n#endif\n\n/* System headers */\n#include <errno.h>\n#include <fcntl.h>\n#include <string.h>\n#include <sys/dos.h>\n#include <sys/iocs.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#if 0\n#include <sys/select.h>\n#include <sys/xsocket.h>\n#endif\n#include <sys/xunistd.h>\n\n/* Macros */\n#define XFD_ISSET(fd,fds) ((fds) && FD_ISSET ((fd), (fds)))\n#define isreadable(mode)  ((mode) == O_RDONLY || (mode) == O_RDWR)\n#define iswritable(mode)  ((mode) == O_WRONLY || (mode) == O_RDWR)\n#ifndef _POSIX_FD_SETSIZE\n#define _POSIX_FD_SETSIZE OPEN_MAX\n#endif\n\n/* Functions */\nint\nselect (int fds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)\n{\n  fd_set oread, owrite, oexcept;\n  int ticks, start;\n  int nfds;\n\n  if (fds > _POSIX_FD_SETSIZE)\n    {\n      errno = EINVAL;\n      return -1;\n    }\n\n  FD_ZERO (&oread);\n  FD_ZERO (&owrite);\n  FD_ZERO (&oexcept);\n\n  nfds = 0;\n  ticks = -1;\n\n  if (timeout)\n    {\n      ticks = timeout->tv_sec * 100 + timeout->tv_usec / 10000;\n      if (ticks < 0)\n\t{\n\t  errno = EINVAL;\n\t  return -1;\n\t}\n    }\n\n  start = _iocs_ontime ();\n  for (;;)\n    {\n      {\n\tint fd;\n\t\n\tfor (fd = 0; fd < fds; fd++)\n\t  {\n\t    int accmode;\n\t    \n\t    if (_fddb[fd].inuse == _FD_NOTUSED)\n\t      continue;\n\t    \n\t    accmode = _fddb[fd].oflag & O_ACCMODE;\n\t    \n\t    if (isatty (fd))\n\t      {\n\t\tif (XFD_ISSET (fd, rfds) && isreadable (accmode) && _dos_k_keysns ())\n\t\t  {\n\t\t    FD_SET (fd, &oread);\n\t\t    nfds++;\n\t\t  }\n\t\t\n\t\tif (XFD_ISSET (fd, wfds) && iswritable (accmode))\n\t\t  {\n\t\t    FD_SET (fd, &owrite);\n\t\t    nfds++;\n\t\t  }\n\t      }\n#if 0\n\t    else if (_fddb[fd].sockno >= 0)\n\t      {\n\t\tif (XFD_ISSET (fd, rfds) && _socklen (_fddb[fd].sockno, 0))\n\t\t  {\n\t\t    FD_SET (fd, &oread);\n\t\t    nfds++;\n\t\t  }\n\n\t\tif (XFD_ISSET (fd, wfds) /* && _socklen (_fddb[fd].sockno, 1) == 0 */)\n\t\t  {\n\t\t    FD_SET (fd, &owrite);\n\t\t    nfds++;\n\t\t  }\n\t      }\n#endif\n\t    else\n\t      {\n\t\tif (XFD_ISSET (fd, rfds) && isreadable (accmode) && _dos_ioctrlis (fd))\n\t\t  {\n\t\t    FD_SET (fd, &oread);\n\t\t    nfds++;\n\t\t  }\n\t\t\n\t\tif (XFD_ISSET (fd, wfds) && iswritable (accmode) && _dos_ioctrlos (fd))\n\t\t  {\n\t\t    FD_SET (fd, &owrite);\n\t\t    nfds++;\n\t\t  }\n\t      }\n\t  }\n      }\n\n      {\n\tint rest;\n\t\n\tif ((rest = (_iocs_ontime () - start) % 8640000) < 0)\n\t  rest += 8640000;\n\t\n\tif (nfds != 0)\n\t  {\n\t    if (ticks >= 0)\n\t      {\n\t\tint left;\n\t\t\n\t\tif ((left = ticks - rest) < 0)\n\t\t  left = 0;\n\t\t\n\t\ttimeout->tv_sec = left / 100;\n\t\ttimeout->tv_usec = (left % 100) * 10000;\n\t      }\n\t    \n\t    if (rfds)\n\t      *rfds = oread;\n\t    if (wfds)\n\t      *wfds = owrite;\n\t    if (efds)\n\t      *efds = oexcept;\n\t    \n\t    return nfds;\n\t  }\n\t\n\tif (ticks >= 0 && rest > ticks)\n\t  return 0;\n      }\n\n      _dos_change_pr ();\n    }\n}\n"
  }
]